/* ==========================================================================
   SELF-HOSTED SIGNATURE FONTS — hero "by Starla" only
   Angellica Signature = capital S | Calipatrya = by + tarla
   ========================================================================== */
@font-face {
  font-family: "Angellica Signature";
  /* woff2 first (~57 KB -> 24 KB subset), .ttf kept as a fallback for the
     ~2% of browsers without woff2 support. font-display:swap guarantees the
     byline paints in a fallback face instead of staying invisible. */
  src: url("../fonts/AngellicaSignature.woff2") format("woff2"),
       url("../fonts/AngellicaSignature.ttf") format("truetype");
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Calipatrya";
  src: url("../fonts/Calipatrya.woff2") format("woff2"),
       url("../fonts/Calipatrya.ttf") format("truetype");
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}

/* ========================================================================
   828 Mega Mums by Starla — homepage.css
   Homepage-only styles split from shared main.css.

   Intent:
   - Keep homepage hero/sliding-card/carousel/category-card edits isolated.
   - Load only on the WordPress front page.
   - Do not touch WooCommerce, RedNao, product wizard, or cart selectors.
   ======================================================================== */

/* ==========================================================================
   SECTION 1: SEASON ANNOUNCEMENT --- MOVED
   The announcement bar is now sitewide. Its markup lives in
   includes/announcement-bar.php and its styles in assets/css/announcement-bar.css.
   Nothing for it should be added back to this homepage-only file.
   ========================================================================== */

/* ==========================================================================
   SECTION 2: HERO GRID CONVERGENCE
   ========================================================================== */
.hero-section { position: relative; width: 100vw; background-color: var(--color-bg-neutral); }
.hero-sticky { position: relative; height: calc(100vh - var(--mm-header-pin-offset, 96px)); height: calc(100dvh - var(--mm-header-pin-offset, 96px)); width: 100vw; overflow: hidden; display: flex; align-items: center; justify-content: center; }
.hero-grid { position: relative; display: flex; height: 100%; width: 100%; align-items: stretch; justify-content: center; gap: 0px; padding: 0px; }
.col-side { display: flex; flex-direction: column; width: 0%; opacity: 0; gap: 0px; will-change: transform, width, opacity; }
.col-center { position: relative; flex: 0 0 auto; width: 100%; height: 100%; border-radius: 0px; overflow: hidden; display: flex; align-items: center; justify-content: center; will-change: width, height, border-radius; }
/* ADDED 2026-08-19 — the center-photo overlay is now ACF-controlled.
   The gradient below is only a fallback for when no ACF value is present, and
   it matches the previous hardcoded behavior exactly. front-page.php sets
   --mm-hero-center-overlay on .col-center; custom properties inherit into
   ::after, so nothing else here needs to change. Stays at z-index 5, which
   keeps it under the .knockout-overlay lettering at z-index 10. */
.col-center::after { content: ''; position: absolute; inset: 0; background: var(--mm-hero-center-overlay, linear-gradient(to top, rgba(0, 0, 0, 0.4) 0%, rgba(0, 0, 0, 0) 60%)); z-index: 5; pointer-events: none; }
.img-wrap { position: relative; flex: 1; overflow: hidden; border-radius: 0px; will-change: border-radius; }
/* --------------------------------------------------------------------------
   SCOPED 2026-08-02 - Phase 2 of the global `img` bug fix.
   This line used to read `img { ... }`, which targeted EVERY image on the
   homepage - including the header logo, footer logo, icons and any image
   inserted through the WordPress editor. It is now limited to the hero grid.
   The other three groups that silently relied on the old global rule are given
   explicit rules below so none of them lose their sizing.
   homepage.css is only enqueued when is_front_page() is true, so scoping to
   component classes is sufficient here.
   -------------------------------------------------------------------------- */

/* 1 + 2. Hero side tiles and hero center image */
.hero-grid img { width: 100%; height: 100%; object-fit: cover; display: block; }
.hero-grid .img-wrap img { width: 100%; height: 100%; object-fit: cover; display: block; }
.hero-grid .col-center .main-img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* 3. Opposite sliding showcase cards */
.showcase-card img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* 4. Featured designs 3D carousel - the <a> needs the box before the img can fill it */
.mum-carousel .mum-card > a { display: block; width: 100%; height: 100%; }
.mum-carousel .mum-card img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* ==========================================================================
   ★ EASY TWEAKS — HERO BRAND + "by Starla"
   Search this file for: EASY TWEAKS  or  by Starla
   Change ONLY the --mm-* values in the first block when possible.
   ========================================================================== */
.mm-homepage {
  /* Desktop: higher % = higher on the image | 5% = near bottom */
  --mm-hero-brand-bottom: 5%;

  /* Optional whole-brand horizontal shift from center (negative = left) */
  --mm-hero-brand-shift-x: 0px;

  /* Desktop signature sizes */
  --mm-byline-calipatrya-size: 17vw;   /* by + tarla */
  --mm-byline-angellica-size: 15vw;    /* capital S only */

  /* Soft pink from your logo export */
  --mm-byline-color: #F391BC;

  /* How tightly "by Starla" tucks under MUMS (more negative = closer) */
  --mm-byline-nudge-up: -0.28em;

  /* Desktop-only: by Starla left shift (uses left:, NOT transform — GSAP owns transform) */
  --mm-byline-shift-x: -3em;
}

@media (max-width: 768px) {
  .mm-homepage {
    --mm-hero-brand-bottom: 5%;
    --mm-hero-brand-shift-x: 0px;
    --mm-byline-calipatrya-size: 30vw;
    --mm-byline-angellica-size: 21vw;
    --mm-byline-nudge-up: -0.16em;
    /* Mobile: no left shift — stay tucked under stacked MUMS */
    --mm-byline-shift-x: 0px;
  }
}

.knockout-overlay {
  position: absolute;
  inset: 0;
  z-index: 10;
  pointer-events: none;
  overflow: hidden; /* clip brand to middle hero image */
}

/* Clip title + by Starla inside the middle image */
.mm-homepage .col-center {
  overflow: hidden;
}

.knockout-brand {
  position: absolute;
  bottom: var(--mm-hero-brand-bottom);
  left: 50%;
  /* Centering is CSS-only on purpose. It used to live in a gsap.set() that ran
     on window "load", so the lockup painted half its own width to the RIGHT
     until every hero image finished downloading -- and stayed there forever if
     GSAP failed to load. GSAP never animates this element (it animates the
     children .knockout-text and .mm-hero-byline), so it has no reason to own
     this transform. --mm-hero-brand-shift-x still works exactly as before. */
  transform: translateX(calc(-50% + var(--mm-hero-brand-shift-x, 0px)));
  transform-origin: 50% 100%;
  z-index: 10;
  display: flex;
  flex-direction: column;
  align-items: center;
  width: max-content;
  max-width: none;
  pointer-events: none;
  will-change: transform;
  overflow: visible; /* parents clip; brand can size freely */
}

.knockout-text {
  position: relative;
  bottom: auto;
  left: auto;
  transform: none;
  font-family: var(--font-hero-knockout);
  font-weight: 900;
  font-size: clamp(3rem, 11vw, 12rem);
  line-height: 0.85;
  text-align: center;
  text-transform: uppercase;
  display: flex;
  flex-direction: row;
  justify-content: center;
  gap: 0.3em;
  color: transparent;
  -webkit-text-stroke: 2px var(--color-pink-soft);
  transform-origin: bottom center;
  will-change: transform;
  margin: 0;
}

.mm-hero-byline {
  margin: 0;
  margin-top: var(--mm-byline-nudge-up);
  margin-right: 0;
  padding: 0;
  align-self: flex-end;
  line-height: 0.8;
  white-space: nowrap;
  color: var(--mm-byline-color);
  position: relative;
  /* Horizontal placement ONLY via left (desktop -3em, mobile 0).
     Do not use transform here — GSAP uses transform for pin stretch. */
  left: var(--mm-byline-shift-x);
  transform-origin: right bottom;
}

/* Belt-and-suspenders: force no mobile side shift even if a var is wrong */
@media (max-width: 768px) {
  .mm-homepage .mm-hero-byline {
    left: 0 !important;
  }
}

.mm-hero-byline__by,
.mm-hero-byline__rest {
  font-family: "Calipatrya", cursive;
  font-weight: normal;
  font-style: normal;
  font-size: var(--mm-byline-calipatrya-size);
  letter-spacing: 0.01em;
}

.mm-hero-byline__s {
  font-family: "Angellica Signature", cursive;
  font-weight: normal;
  font-style: normal;
  font-size: var(--mm-byline-angellica-size);
  display: inline-block;
  margin-left: -0.1em;
  margin-right: -0.05em;
  transform: translateY(0.12em);
}

.mm-hero-byline__by {
  margin-right: 0.02em;
}

@media (max-width: 768px) {
  .knockout-text {
    -webkit-text-stroke: 1px var(--color-pink-soft);
    flex-direction: column;
    gap: 0;
    font-size: clamp(4rem, 18vw, 8rem);
    bottom: auto;
  }
}
/* ===== end EASY TWEAKS — hero by Starla ===== */

/* SECTION 3 — Identity statement + product-discovery bridge */
.identity-bridge {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding: clamp(5rem, 8vw, 7rem) clamp(1.5rem, 5vw, 3rem);
  text-align: center;
  color: var(--color-text-dark);
}
.identity-bridge::before {
  content: "";
  position: absolute;
  z-index: -1;
  width: min(58rem, 112vw);
  height: min(34rem, 72vw);
  left: 50%;
  top: 47%;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  pointer-events: none;
}
/* A: existing homepage background with a broad blush glow. */
.identity-bridge--option-a { background: transparent !important; }
.identity-bridge--option-a::before { background: radial-gradient(ellipse, rgba(220,100,150,.18) 0%, rgba(255,182,193,.10) 43%, rgba(255,245,246,0) 73%); filter: blur(18px); }
/* B: a clear cream/blush pause between the hero and product discovery. */
.identity-bridge--option-b { background: linear-gradient(135deg, #fffaf7 0%, #fff1f3 52%, #fff8f2 100%) !important; }
.identity-bridge--option-b::before { background: radial-gradient(ellipse, rgba(220,100,150,.10) 0%, rgba(255,245,246,0) 68%); filter: blur(24px); }
/* Combined review: page background still reads through a soft cream/blush wash,
   with Option A's diffused H1 glow. Change only the modifier class later. */
.identity-bridge--combined { background: linear-gradient(135deg, rgba(255,250,247,.58) 0%, rgba(255,241,243,.46) 52%, rgba(255,248,242,.58) 100%) !important; }
.identity-bridge--combined::before { background: radial-gradient(ellipse, rgba(220,100,150,.10) 0%, rgba(255,182,193,.05) 43%, rgba(255,245,246,0) 73%); filter: blur(18px); }
.identity-bridge__inner { position: relative; z-index: 1; width: min(100%, 58rem); margin: 0 auto; }
.identity-bridge__eyebrow { margin: 0 0 1.1rem; font-size: clamp(.72rem, 1vw, .84rem); font-weight: 700; line-height: 1.4; letter-spacing: .19em; }
.identity-bridge__heading { max-width: 56rem; margin: 0 auto; font-weight: 700; line-height: 1.06; letter-spacing: -.035em; text-wrap: balance; }
.identity-bridge__supporting { max-width: 47.5rem; margin: 1.65rem auto 0; line-height: 1.75; text-wrap: pretty; }
.identity-bridge__finished { max-width: 43rem; margin: 1rem auto 0; font-size: clamp(.95rem, 1.2vw, 1.08rem); font-weight: 600; line-height: 1.65; }
.identity-bridge__brand { margin: 2rem auto 0; font-weight: 700; line-height: 1.3; letter-spacing: .025em; }
/* The load-fired mmIdentityRise animation that used to live here has been
   removed. It ran on page load, and this section sits below a 100vh hero, so
   it had always played and finished before the visitor scrolled down to it -
   which is why this section looked like it had no animation at all. The same
   rise is now fired on scroll by the motion engine in homepage.js, which tags
   these elements with data-mmh-reveal="up" and the same 80ms cadence.
   The @keyframes below is kept only so any other rule referencing it is safe. */

/* Hero CTA row. Two real buttons + one text link, each a separate <a>. */
.identity-bridge__actions { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: .75rem 1rem; margin: 2.25rem auto 0; }
.identity-bridge__btn { display: inline-flex; align-items: center; justify-content: center; min-height: 48px; padding: .8rem 1.6rem; border: 1.5px solid transparent; border-radius: 9px; font-size: clamp(.92rem, 1.1vw, 1rem); font-weight: 600; line-height: 1.2; text-decoration: none; transition: transform .14s ease, box-shadow .14s ease, background .2s ease, border-color .2s ease; }
.identity-bridge__btn--primary { background: #2C1A1D; color: #fff !important; box-shadow: 0 1px 0 rgba(124,42,74,.14), 0 3px 4px rgba(124,42,74,.24), 0 7px 9px -5px rgba(124,42,74,.32); }
.identity-bridge__btn--primary:hover { background: #4b2a30; }
.identity-bridge__btn--secondary { background: rgba(255,255,255,.72); border-color: rgba(220,100,150,.42); color: #2C1A1D !important; box-shadow: 0 1px 0 rgba(124,42,74,.10), 0 2px 3px rgba(124,42,74,.16); }
.identity-bridge__btn--secondary:hover { background: #fff; border-color: #DC6496; }
.identity-bridge__btn--primary:hover, .identity-bridge__btn--secondary:hover { transform: translateY(3px); box-shadow: 0 1px 0 rgba(124,42,74,.16), 0 1px 2px rgba(124,42,74,.28); }
.identity-bridge__btn--text { min-height: 0; padding: .35rem .25rem; color: #A13F64 !important; font-weight: 600; text-decoration: underline; text-underline-offset: 4px; text-decoration-thickness: 1.5px; }
.identity-bridge__btn--text:hover { color: #DC6496 !important; }
.identity-bridge__btn:focus-visible { outline: 3px solid #DC6496; outline-offset: 3px; }
@media (max-width: 600px) {
  .identity-bridge__actions { flex-direction: column; align-items: stretch; margin-top: 1.85rem; }
  .identity-bridge__btn--primary, .identity-bridge__btn--secondary, .identity-bridge__btn--tertiary { width: 100%; }
}
@keyframes mmIdentityRise { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } }
@media (max-width: 768px) {
  .identity-bridge { padding: clamp(3rem, 12vw, 4rem) clamp(1.375rem, 6vw, 1.625rem); }
  .identity-bridge::before { width: 125vw; height: 28rem; top: 40%; }
  .identity-bridge__eyebrow { margin-bottom: .9rem; letter-spacing: .14em; }
  .identity-bridge__heading { font-size: clamp(2rem, 10.5vw, 3.15rem); line-height: 1.08; }
  .identity-bridge__supporting { margin-top: 1.35rem; line-height: 1.65; }
  .identity-bridge__finished { margin-top: .9rem; }
  .identity-bridge__brand { margin-top: 1.65rem; }
}
@media (prefers-reduced-motion: reduce) {
  .identity-bridge__eyebrow, .identity-bridge__heading, .identity-bridge__supporting, .identity-bridge__finished, .identity-bridge__brand, .identity-bridge__actions { opacity: 1; animation: none; transform: none; }
  .identity-bridge__btn { transition: none; }
  .identity-bridge__btn:hover { transform: none; }
}

/* ==========================================================================
   SECTION 2: OPPOSITE DIRECTION SLIDING CARDS
   ========================================================================== */
.showcase-overflow-wrapper { overflow: clip; background-color: var(--color-bg-neutral); }
.mum-showcase { height: 100vh; position: relative; display: flex; align-items: center; justify-content: center; background-color: var(--color-bg-neutral); }
/* ADDED 2026-08-19 — reclaim the sticky-header strip INSIDE the pinned area.
   .mum-showcase stays at height: 100vh and the ScrollTrigger still uses
   start: "top top" / end: "+=150%", so the section lands in exactly the same
   place on the page as before. The padding simply moves the cards out from
   under the sticky header so the full image is visible. .showcase-title-wrapper
   is position: absolute with inset: 0, so it resolves against the padding box
   and the headline stays centered where it is today. */
.showcase-pinned-area { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; position: relative; padding-top: var(--mm-header-pin-offset, 108px); box-sizing: border-box; }
.showcase-title-wrapper { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; z-index: 0; pointer-events: none; }
.showcase-title { font-family: var(--font-heading); font-size: clamp(3.5rem, 12vw, 10rem); font-weight: 500; line-height: 0.9; letter-spacing: -0.02em; text-align: center; margin: 0; padding: 0 1.5rem; color: var(--color-text-dark); }
.showcase-title em { font-style: italic; color: var(--color-pink-hot); }

.showcase-grid { position: relative; z-index: 10; display: grid; grid-template-columns: 1fr; gap: 2rem; width: 100%; max-width: 1200px; padding: 0 1.5rem; }
@media (min-width: 768px) { .showcase-grid { grid-template-columns: 1fr 1fr; gap: 4rem; padding: 0 3rem; } }

/* CHANGED 2026-08-19 — cards are now sized from HEIGHT, not width.
   Driving from height is what guarantees the whole image clears the sticky
   header at every viewport: the height is capped first, then the aspect ratio
   derives the width. max-width: 100% clamps the width back to the grid column
   if a squarer ratio would otherwise overflow it (a 640px-tall square wants
   640px of width in a 520px column). --mm-card-ratio is set from ACF.
   The GSAP slide-in uses xPercent: -120 / +120, which is relative to each
   card's own width, so narrower cards still start fully offscreen. */
.showcase-card { position: relative; aspect-ratio: var(--mm-card-ratio, 4/5); height: min(64vh, 640px); width: auto; max-width: 100%; justify-self: center; border-radius: 1rem; overflow: hidden; background: var(--color-cream); border: var(--border-rose-soft); box-shadow: var(--shadow-premium); will-change: transform; transform: translateZ(0); cursor: pointer; transition: box-shadow .35s ease, border-color .35s ease; }
.showcase-image { width: 100%; height: 100%; object-fit: cover; display: block; }
.card-badge { position: absolute; bottom: 1.5rem; left: 1.5rem; right: 1.5rem; z-index: 2; display: flex; flex-direction: column; align-items: flex-start; gap: .6rem; }
.badge-text { display: inline-block; padding: 0.6rem 1.25rem; font-family: var(--font-body); font-size: 0.875rem; font-weight: 600; border-radius: 999px; background-color: rgba(255, 240, 245, 0.9); backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px); color: var(--color-text-dark); border: var(--border-rose-soft); }

/* ADDED 2026-08-19 — clickability affordances for the two sliding cards.
   The whole card is a real <a class="showcase-card__link"> now.

   !! IMPORTANT !! Every hover and press effect below animates an INNER element
   (the image, the scrim, the button). Never put a transform on .showcase-card
   itself: GSAP owns that element's transform for the slide-in (xPercent -120 /
   +120), and a competing CSS transform makes the cards jump mid-tween. */
.showcase-card__link { position: absolute; inset: 0; display: block; z-index: 3; text-decoration: none; color: inherit; -webkit-tap-highlight-color: transparent; }
.showcase-card__link:focus-visible { outline: 3px solid var(--color-pink-hot); outline-offset: -4px; border-radius: 1rem; }

/* The card shell lifts on hover so the whole tile reads as one control. */
.showcase-card:hover { border-color: var(--color-pink-hot); box-shadow: 0 22px 48px rgba(124, 42, 74, .28); }

/* Photo zoom is the affordance that survives at any aspect ratio. */
.showcase-image { position: relative; z-index: 0; transition: transform .55s cubic-bezier(.25, 1, .5, 1); }
.showcase-card:hover .showcase-image { transform: scale(1.05); }
.showcase-card:active .showcase-image { transform: scale(1.02); }

/* Bottom fade so the name, price and button stay legible over a busy photo and
   the button reads as a control instead of part of the picture.
   Strength is the Card bottom shading field; 0 switches it off. */
.showcase-card__scrim { position: absolute; left: 0; right: 0; bottom: 0; height: 58%; z-index: 1; pointer-events: none; opacity: var(--mm-card-scrim, 1); background: linear-gradient(to top, rgba(44, 26, 29, .55) 0%, rgba(44, 26, 29, 0) 100%); }

/* Price + button sit in a wrapping row under the name pill, so a long button
   label drops to its own line instead of overflowing a narrow 4:5 card. */
.card-badge__row { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }
.card-price { display: inline-block; padding: .5rem 1rem; border-radius: 999px; font-family: var(--font-body); font-size: .9rem; font-weight: 700; color: var(--color-text-dark); background-color: rgba(255, 255, 255, .94); border: var(--border-rose-soft); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); }

/* ALWAYS-VISIBLE solid button. A hover-only CTA is invisible on every touch
   device, which is exactly where these cards were being scrolled past. Solid
   fill (not the frosted translucent pill) is what separates a control from a
   caption at a glance. */
.card-cta { display: inline-flex; align-items: center; gap: .4rem; padding: .6rem 1.15rem; border-radius: 999px; font-family: var(--font-body); font-size: .875rem; font-weight: 700; letter-spacing: .01em; background: var(--mm-cta-bg, #A13F64); color: var(--mm-cta-text, #FFFFFF); box-shadow: 0 4px 14px rgba(44, 26, 29, .28); transition: transform .25s ease, filter .25s ease, box-shadow .25s ease; }
.showcase-card:hover .card-cta { filter: brightness(1.07); transform: translateY(-1px); box-shadow: 0 9px 22px rgba(44, 26, 29, .34); }
.showcase-card:active .card-cta { transform: translateY(1px) scale(.98); box-shadow: 0 3px 10px rgba(44, 26, 29, .30); }
.card-cta__arrow { transition: transform .25s ease; }
.showcase-card:hover .card-cta__arrow { transform: translateX(3px); }

@media (prefers-reduced-motion: reduce) {
  .showcase-image, .card-cta, .card-cta__arrow { transition: none; }
  .showcase-card:hover .showcase-image, .showcase-card:active .showcase-image { transform: none; }
  .showcase-card:hover .card-cta, .showcase-card:active .card-cta { transform: none; }
  .showcase-card:hover .card-cta__arrow { transform: none; }
}

/* ADDED 2026-08-19 — mobile sizing for the taller sliding cards.
   Both cards stack into a single column here, so the binding constraint is
   (2 x card height) + gap fitting inside 100vh minus the ~88px mobile header.
   The gap drops from 2rem to 1rem to buy back height for the images. */
@media (max-width: 767px) {
  .showcase-grid { gap: 1rem; }
  /* CHANGED 2026-08-19 — mobile cards are near full-bleed instead of being
     sized from height. min(36vh, 360px) at a 4:5 ratio left each card only
     ~288px wide with wide empty margins either side, which read as a
     decorative divider image rather than a product tile. Width drives the
     size now, and max-height keeps two stacked cards plus the gap inside the
     pinned 100vh minus the sticky header, so a taller ratio crops the photo
     (object-fit: cover) instead of overflowing the section. dvh repeats the
     value for browsers that support it, matching .hero-sticky above. */
  .showcase-card {
    width: min(90vw, 420px);
    height: auto;
    max-height: calc((100vh - var(--mm-header-pin-offset, 88px) - 2.5rem) / 2);
    max-height: calc((100dvh - var(--mm-header-pin-offset, 88px) - 2.5rem) / 2);
  }
  .card-badge { bottom: 1rem; left: 1rem; right: 1rem; gap: .5rem; }
  .card-price, .card-cta { padding: .5rem .9rem; }
}

/* Featured Designs / BEST SELLERS introduction.
   ACF continues to control wording, selected fonts, colors, and size percentages.
   Approved permanent spacing promoted Jul 18, 2026. */

/* ==========================================================================
   BEST SELLERS + CAROUSEL — EASY SPACING TWEAKS
   Change only these custom-property values for future spacing adjustments.
   ========================================================================== */
.mm-homepage {
    /* Desktop: BEST SELLERS heading area. */
    --mm-best-sellers-top-desktop: 3.25rem;
    --mm-best-sellers-copy-gap-desktop: 0.9rem;
    --mm-best-sellers-bottom-desktop: 1.5rem;
    --mm-carousel-top-space-desktop: 1rem;
    --mm-carousel-pull-up-desktop: -0.5rem;

    /* Desktop: active slide title and description below the carousel. */
    --mm-carousel-info-pull-up-desktop: 2rem;
    --mm-slide-copy-gap-desktop: 0.5rem;

    /* Mobile: BEST SELLERS heading area. */
    --mm-best-sellers-top-mobile: 2.5rem;
    --mm-best-sellers-copy-gap-mobile: 0.35rem;
    --mm-best-sellers-bottom-mobile: 0rem;
    --mm-carousel-top-space-mobile: 0rem;
    --mm-carousel-pull-up-mobile: -2.25rem;

    /* Mobile: active slide title and description below the carousel. */
    --mm-carousel-info-pull-up-mobile: -0.25rem;
    --mm-slide-copy-gap-mobile: 0.15rem;
}

.mm-homepage .showcase-description {
    padding: var(--mm-best-sellers-top-desktop) 1.5rem var(--mm-best-sellers-bottom-desktop);
    display: flex;
    justify-content: center;
}
.mm-homepage .showcase-description .description-content {
    width: 100%;
    max-width: 900px;
    margin-inline: auto;
    text-align: center;
}
.mm-homepage .showcase-description .description-eyebrow {
    margin: 0 auto;
    padding: 0;
    font-family: var(--font-heading);
    font-weight: 700;
    line-height: 1;
    letter-spacing: 0.055em;
    text-transform: uppercase;
    color: var(--color-brand-rose);
    text-wrap: balance;
}
.mm-homepage .showcase-description .description-body {
    max-width: 700px;
    margin: var(--mm-best-sellers-copy-gap-desktop) auto 0;
    padding: 0;
    font-family: var(--font-body);
    font-weight: 400;
    line-height: 1.55;
    color: var(--color-text-muted);
    letter-spacing: normal;
    text-wrap: balance;
}

/* Keep the introduction visually attached to its carousel. */
.mm-homepage .showcase-overflow-wrapper + .mum-carousel-container {
    padding-top: var(--mm-carousel-top-space-desktop);
    margin-top: var(--mm-carousel-pull-up-desktop);
}

/* Keep each active slide title and description close to the carousel. */
.mm-homepage .mum-info-section {
    margin-top: var(--mm-carousel-info-pull-up-desktop);
}
.mm-homepage .mum-info-section .mum-title {
    margin-bottom: var(--mm-slide-copy-gap-desktop);
}
.mm-homepage .mum-info-section .mum-desc {
    margin-top: 0;
}

@media (max-width: 768px) {
    .mm-homepage .showcase-description {
        padding: var(--mm-best-sellers-top-mobile) 1.5rem var(--mm-best-sellers-bottom-mobile);
    }
    .mm-homepage .showcase-description .description-eyebrow {
        line-height: 1.02;
        letter-spacing: 0.04em;
    }
    .mm-homepage .showcase-description .description-body {
        max-width: 32rem;
        margin-top: var(--mm-best-sellers-copy-gap-mobile);
        line-height: 1.5;
    }
    .mm-homepage .showcase-overflow-wrapper + .mum-carousel-container {
        padding-top: var(--mm-carousel-top-space-mobile);
        margin-top: var(--mm-carousel-pull-up-mobile);
    }
    .mm-homepage .mum-info-section {
        margin-top: var(--mm-carousel-info-pull-up-mobile);
    }
    .mm-homepage .mum-info-section .mum-title {
        margin-bottom: var(--mm-slide-copy-gap-mobile);
    }
}

/* ==========================================================================
   SECTION 3: 3D REFLECTING CAROUSEL
   Restored Jul 11, 2026 from the original approved visual version.
   Original 8px reflection gap, fade mask, side-card dimming, transforms,
   opacity, spacing, and mobile Balance B composition are preserved.
   ========================================================================== */
.mum-carousel-container { width: 100%; padding: 80px 0; background: var(--color-bg-neutral); color: var(--color-text-dark); display: flex; flex-direction: column; align-items: center; overflow: hidden; }
.mum-carousel { width: 100%; max-width: 1200px; height: 440px; position: relative; perspective: 1200px; }
.mum-track { width: 100%; height: 100%; position: relative; transform-style: preserve-3d; display: flex; justify-content: center; align-items: center; }
.mum-card { position: absolute; top: 50%; left: 50%; width: 300px; aspect-ratio: 4 / 5; border-radius: 12px; background: transparent; transition: transform 0.6s cubic-bezier(0.25, 1, 0.5, 1), opacity 0.6s cubic-bezier(0.25, 1, 0.5, 1), filter 0.6s cubic-bezier(0.25, 1, 0.5, 1); cursor: pointer; will-change: transform, opacity; backface-visibility: hidden; -webkit-backface-visibility: hidden;  }
.mum-card a { display: block; width: 100%; height: 100%; }
.mum-card img { width: 100%; height: 100%; object-fit: cover; border-radius: 12px; box-shadow: 0 15px 35px rgba(180, 120, 140, 0.15); border: var(--border-rose-soft); }

/* Standards-based replacement for -webkit-box-reflect.
   The wrapper stays below the card; only its inner image is mirrored. */
.mum-card-reflection {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  width: 100%;
  height: 50%;
  overflow: hidden;
  border-radius: 12px;
  opacity: 0.30;
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, rgba(0,0,0,0.58) 48%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 0%, rgba(0,0,0,0.58) 48%, transparent 100%);
  contain: strict;
  isolation: isolate;
  pointer-events: none;
  user-select: none;
}

.mum-card-reflection .mum-card-reflection-image {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 200%;
  object-fit: cover;
  border-radius: 12px;
  transform: scaleY(-1);
  transform-origin: center center;
  box-shadow: 0 15px 35px rgba(180, 120, 140, 0.15);
  border: var(--border-rose-soft);
  pointer-events: none;
}


.mum-card.center { transform: translate(-50%, -50%) translateZ(0) rotateY(0deg) scale(1); z-index: 10; opacity: 1; filter: grayscale(0%) brightness(100%); }
.mum-card.left-1 { transform: translate(-140%, -50%) translateZ(-150px) rotateY(30deg) scale(0.85); z-index: 5; opacity: 0.65; filter: grayscale(20%) brightness(85%); }
.mum-card.right-1 { transform: translate(40%, -50%) translateZ(-150px) rotateY(-30deg) scale(0.85); z-index: 5; opacity: 0.65; filter: grayscale(20%) brightness(85%); }
.mum-card.left-2 { transform: translate(-220%, -50%) translateZ(-300px) rotateY(45deg) scale(0.7); z-index: 3; opacity: 0.35; filter: grayscale(40%) brightness(75%); }
.mum-card.right-2 { transform: translate(120%, -50%) translateZ(-300px) rotateY(-45deg) scale(0.7); z-index: 3; opacity: 0.35; filter: grayscale(40%) brightness(75%); }
.mum-card.hidden { transform: translate(-50%, -50%) translateZ(-500px) scale(0.5); z-index: 1; opacity: 0; pointer-events: none; }

.mum-arrow { position: absolute; top: 50%; transform: translateY(-50%); background: rgba(255, 240, 245, 0.85); color: var(--color-pink-hot); width: 45px; height: 45px; border-radius: 50%; border: var(--border-rose-soft); font-size: 1.8rem; line-height: 1; cursor: pointer; z-index: 20; transition: all 0.3s ease; backdrop-filter: blur(5px); display: flex; align-items: center; justify-content: center; }
.mum-arrow:hover { background: var(--color-pink-hot); color: var(--color-cream); transform: translateY(-50%) scale(1.1); border-color: var(--color-pink-hot); }
.mum-left { left: 5%; }
.mum-right { right: 5%; }

.mum-info-section { text-align: center; margin-top: 40px; max-width: 600px; padding: 0 20px; transition: opacity 0.3s ease; }
.mum-title { font-family: var(--font-heading); font-size: 2.2rem; font-weight: 600; margin-bottom: 10px; color: var(--color-brand-rose); text-shadow: 0 1px 2px rgba(180, 120, 140, 0.1); }
.mum-desc { font-family: var(--font-body); font-size: 1.1rem; color: var(--color-text-muted); line-height: 1.5; }
.mum-dots { display: flex; justify-content: center; gap: 12px; margin-top: 25px; }
.mum-dot { width: 10px; height: 10px; border-radius: 50%; background: rgba(220, 100, 150, 0.2); cursor: pointer; transition: all 0.3s ease; }
.mum-dot.active { background: var(--color-pink-hot); transform: scale(1.3); }

@media (max-width: 768px) {
  /* Balance B mobile: tighter frame + spacing, bigger fluid center card,
     bigger and harder-angled side cards that peek more. */
  .mum-carousel-container { padding: 40px 0; }
  .mum-carousel { height: clamp(360px, 112vw, 470px); }
  .mum-card { width: min(66vw, 300px); }
  /* Only three cards are visible on mobile; do not paint hidden reflections. */
  .mum-card.left-2 .mum-card-reflection,
  .mum-card.right-2 .mum-card-reflection,
  .mum-card.hidden .mum-card-reflection { display: none; }
  .mum-card.left-1 { transform: translate(-88%, -50%) translateZ(-120px) rotateY(45deg) scale(0.82); opacity: 0.82; filter: grayscale(10%) brightness(92%); }
  .mum-card.right-1 { transform: translate(-12%, -50%) translateZ(-120px) rotateY(-45deg) scale(0.82); opacity: 0.82; filter: grayscale(10%) brightness(92%); }
  .mum-card.left-2, .mum-card.right-2 { opacity: 0; pointer-events: none; }
  .mum-arrow { width: 38px; height: 38px; font-size: 1.5rem; background: rgba(255, 240, 245, 0.6); }
  .mum-left { left: 1%; }
  .mum-right { right: 1%; }
  .mum-title { font-size: 1.7rem; }
  .mum-desc { font-size: 0.95rem; }
}

@media (max-width: 480px) {
  /* Narrower phones: pull the side cards in slightly so they don't run too far off-screen. */
  .mum-card.left-1 { transform: translate(-84%, -50%) translateZ(-90px) rotateY(42deg) scale(0.8); }
  .mum-card.right-1 { transform: translate(-16%, -50%) translateZ(-90px) rotateY(-42deg) scale(0.8); }
}


@media (prefers-reduced-motion: reduce) {
  .mum-card,
  .mum-card-reflection,
  .mum-info-section,
  .mum-title,
  .mum-desc,
  .mum-dot {
    transition: none !important;
    animation: none !important;
  }
}

/* ==========================================================================
   SECTION 4: 3D FANNING / FLIP CARDS
   ========================================================================== */
.mum-categories-section { position: relative; width: 100%; padding: 100px 24px; background-color: var(--color-bg-neutral); color: var(--color-text-dark); display: block; }
.categories-header { text-align: center; margin-bottom: 5rem; }
.categories-title { font-family: var(--font-heading); font-size: clamp(2.5rem, 5vw, 4.5rem); font-weight: 500; color: var(--color-text-dark); margin-bottom: 1.2rem; }
.categories-subtitle { font-family: var(--font-body); font-size: clamp(1rem, 1.5vw, 1.25rem); color: var(--color-text-muted); }

.card-row { position: relative; width: 100%; max-width: 1100px; margin: 0 auto 2rem auto; perspective: 1200px; display: block; }
@media (min-width: 768px) { .card-row { display: flex; flex-direction: row; justify-content: center; gap: 2rem; margin-bottom: 2rem; } }

.card-pin-wrapper { position: relative; width: 100%; max-width: 320px; margin: 0 auto 2rem auto; z-index: 1; }
@media (min-width: 768px) { .card-pin-wrapper { width: calc(33.333% - 1.35rem); max-width: none; margin: 0; } }

.mum-card-category { position: relative; display: block; width: 100%; aspect-ratio: 3 / 4; text-decoration: none; border-radius: 16px; will-change: transform; background: transparent; transform-style: preserve-3d; }
.mum-card-inner { position: relative; width: 100%; height: 100%; transform-style: preserve-3d; will-change: transform; border-radius: 16px; box-shadow: var(--shadow-premium); transition: box-shadow 0.4s ease; }
.mum-card-category:hover .mum-card-inner { box-shadow: var(--shadow-hover); }

.mum-card-front, .mum-card-back { position: absolute; inset: 0; backface-visibility: hidden; border-radius: 16px; overflow: hidden; background-color: var(--color-cream); border: var(--border-rose-soft); }
.mum-card-front img { width: 100%; height: 100%; object-fit: cover; display: block; }
.mum-card-front::after { content: ''; position: absolute; inset: 0; background: linear-gradient(to bottom, rgba(255,255,255,0), rgba(255,240,245,0.15)); }

.mum-card-back { transform: rotateY(180deg); display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 2rem; text-align: center; }
.back-bg-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: 1; }
.back-overlay { position: absolute; inset: 0; background: linear-gradient(to bottom, rgba(255, 240, 245, 0.9), rgba(255, 230, 240, 0.98)); z-index: 2; }
.card-content-wrapper { position: relative; z-index: 3; display: flex; flex-direction: column; align-items: center; }
.category-title { color: var(--color-text-dark); font-family: var(--font-heading); font-size: clamp(1.5rem, 2vw, 2.2rem); font-weight: 500; line-height: 1.1; margin-bottom: 2rem; text-wrap: balance; }
.fade-up { opacity: 0; transform: translateY(20px); }

.magnetic-glow-btn { position: relative; display: inline-flex; align-items: center; justify-content: center; padding: 14px 32px; border: 1px solid rgba(255, 105, 180, 0.3); border-radius: 999px; background: var(--color-pink-hot); color: var(--color-cream); font-family: var(--font-body); font-size: 14px; letter-spacing: 0.05em; text-transform: uppercase; font-weight: 600; overflow: hidden; transform: translateZ(0); transition: transform 250ms cubic-bezier(0.25, 1, 0.5, 1), border-color 250ms ease, box-shadow 250ms ease; z-index: 0; }
.mum-card-category:hover .magnetic-glow-btn { transform: translateY(-2px); border-color: var(--color-pink-soft); box-shadow: 0 8px 24px rgba(255, 105, 180, 0.3); }
.magnetic-glow-btn::before { content: ""; position: absolute; inset: -60px; background: radial-gradient( circle at var(--x, 50%) var(--y, 50%), rgba(255, 240, 245, 0.95) 0%, rgba(255, 182, 193, 0.55) 25%, transparent 60% ); filter: blur(12px); opacity: var(--glow, 0); transition: opacity 180ms ease; pointer-events: none; z-index: -1; }

/* Fixed Background Logic */
.global-fixed-bg {
    position: fixed;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
    z-index: -1; 
    pointer-events: none; 
}
.global-fixed-bg img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.bg-overlay {
    position: absolute;
    inset: 0;
    background: rgba(255, 245, 246, 0.85); /* Semi-transparent frost so text is readable */
}

/* Make homepage sections transparent so the background shows through */
body, main, .hero-section, .showcase-overflow-wrapper, .mum-showcase, .showcase-description, .mum-carousel-container, .mum-categories-section {
    background-color: transparent !important;
}

/* ==========================================================================
   HOMEPAGE CATEGORY CARDS — Mobile Flip Fix (reliable 2D version)
   Updated Jun 26, 2026
   Desktop keeps the 3D flip. Mobile uses a squash + crossfade so cards
   never disappear inside ScrollTrigger pins.
   ========================================================================== */

/* Keep the pinned mobile card above the next card while it animates. */
.card-pin-wrapper.is-mobile-flipping {
  z-index: 20;
}

@media (max-width: 767px) {
  .card-pin-wrapper {
    isolation: isolate;
  }

  /* On mobile, turn OFF the 3D flip entirely — JS handles the flip in 2D. */
  .mum-card-category,
  .mum-card-inner {
    transform-style: flat !important;
    -webkit-transform-style: flat !important;
  }

  .mum-card-front,
  .mum-card-back {
    backface-visibility: visible !important;
    -webkit-backface-visibility: visible !important;
    transform: none !important;   /* remove the rotateY/translateZ on mobile */
  }
}

/* ==========================================================================
   SECTION 6 — MOBILE CATEGORY ROW FLIP OVERRIDE
   Mobile pins each row and uses a flat 2D squash/crossfade instead of rotateY.
   ========================================================================== */
@media (max-width: 767px) {
  .card-row {
    perspective: none !important;
    transform-style: flat !important;
  }

  .card-row.is-mobile-row-pinned {
    z-index: 20;
  }

  .card-pin-wrapper {
    z-index: 1;
  }

  .card-pin-wrapper.mm-mobile-row-card {
    position: relative;
  }

  .mum-card-category,
  .mum-card-inner {
    transform-style: flat !important;
  }

  .mum-card-front,
  .mum-card-back {
    -webkit-backface-visibility: visible !important;
    backface-visibility: visible !important;
  }

  .mum-card-back {
    transform: none !important;
  }
}


/* ==========================================================================
   LOWER HOMEPAGE — WHY CHOOSE: RESPONSIVE TWO-COLUMN STICKY REPAIR

   Keep the introduction pinned in the left grid track on tablets and larger.
   Phones stack normally and explicitly opt out of sticky positioning.
   The higher-specificity homepage scope protects this structural layout from
   broad theme/plugin rules without changing the section's visual styling.
   ========================================================================== */
.mm-homepage .mm-lower-homepage-test .mm-why-choose,
.mm-homepage .mm-lower-homepage-test .mm-why-choose > .mm-wrap {
  overflow: visible;
}

.mm-homepage .mm-lower-homepage-test .mm-why-shell {
  display: grid;
  grid-template-columns: minmax(0, 3fr) minmax(0, 5fr);
  gap: clamp(2rem, 5vw, 5rem);
  align-items: start;
  width: 100%;
  min-width: 0;
}

.mm-homepage .mm-lower-homepage-test .mm-why-intro,
.mm-homepage .mm-lower-homepage-test .mm-reasons {
  min-width: 0;
  max-width: 100%;
  box-sizing: border-box;
}

.mm-homepage .mm-lower-homepage-test .mm-why-intro {
  position: -webkit-sticky;
  position: sticky;
  top: calc(var(--mm-header-pin-offset, 96px) + 1.5rem);
  align-self: start;
  justify-self: stretch;
  width: auto;
  height: max-content;
  left: auto;
  right: auto;
}

/* A standard 768px tablet remains two-column; only phone widths stack. */
@media (max-width: 767px) {
  .mm-homepage .mm-lower-homepage-test .mm-why-shell {
    grid-template-columns: minmax(0, 1fr);
    gap: 2rem;
  }

  .mm-homepage .mm-lower-homepage-test .mm-why-intro {
    position: static;
    top: auto;
    width: 100%;
    height: auto;
  }
}


/* ==========================================================================
   ADDED 2026-07-28
   1. "Starting at" price pill on the collection cards
   2. Short card rows (1 or 2 cards) so hiding a card never leaves a gap
   3. Real Google map embed in the Pickup & delivery section
   4. Meet Starla band with no portrait
   Everything here is scoped so it cannot reach product pages or the wizard.
   ========================================================================== */

/* 1. Price + short description panel --------------------------------------
   The price is no longer a pill. It is large plain text sitting with the
   short description inside one soft panel near the bottom of the card back,
   underneath the button. Colors, fonts and sizes come from the ACF
   "Our Collections" tab, which prints them after this file loads. */
.mum-card-back .card-content-wrapper .mm-card-meta {
  width: 100%;
  margin-top: 1rem;
  padding: 0.85rem 1rem;
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.7);
  box-shadow: 0 2px 12px rgba(50, 27, 36, 0.1);
  text-align: center;
}
.mum-card-back .card-content-wrapper .mm-card-price {
  display: block;
  margin: 0;
  padding: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
  white-space: normal;
  color: #8f1f4f;
  font-size: clamp(1.1rem, 2.2vw, 1.6rem);
  font-weight: 700;
  line-height: 1.15;
}
.mum-card-back .card-content-wrapper .mm-card-desc {
  margin: 0.4rem 0 0;
  color: #4e3b41;
  font-size: clamp(0.8rem, 1.35vw, 0.95rem);
  line-height: 1.45;
}

/* 2. Short rows ---------------------------------------------------------- */
/* The grid is three across on desktop. When a row holds only one or two
   cards, center it instead of leaving dead space on the right. Card width is
   unchanged, so the pinned-card animation still measures what it expects. */
@media (min-width: 768px) {
  .categories-grid-container .card-row--1,
  .categories-grid-container .card-row--2 {
    justify-content: center;
  }
}

/* 3. Map embed ----------------------------------------------------------- */
.mm-homepage .mm-lower-homepage-test .mm-map {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  min-height: 0;
  background: var(--mm-blush, #fff7fa);
}

.mm-homepage .mm-lower-homepage-test .mm-map iframe {
  display: block;
  width: 100%;
  height: 280px;
  border: 0;
  filter: saturate(0.92);
}

.mm-homepage .mm-lower-homepage-test .mm-map-details {
  display: grid;
  gap: 4px;
  padding: 16px 18px;
  border-top: 1px solid var(--mm-line, #ead9de);
  font-size: 0.92rem;
  line-height: 1.45;
}

.mm-homepage .mm-lower-homepage-test .mm-map-details strong {
  color: var(--mm-plum, #321b24);
  font-size: 1rem;
}

.mm-homepage .mm-lower-homepage-test .mm-map-details span {
  color: var(--mm-muted, #746368);
}

.mm-homepage .mm-lower-homepage-test .mm-map-details a {
  color: var(--mm-rose-deep, #a13f64);
  font-weight: 600;
  text-decoration: none;
}

.mm-homepage .mm-lower-homepage-test .mm-map-details a:hover,
.mm-homepage .mm-lower-homepage-test .mm-map-details a:focus-visible {
  text-decoration: underline;
}

/* 4. Meet Starla with no portrait ---------------------------------------- */
/* Used until a real photo of Starla exists. The instruction placeholder that
   was rendering to customers is gone; add the portrait back by removing the
   --solo modifier and putting an <img> in .mm-portrait. */
.mm-homepage .mm-lower-homepage-test .mm-maker-band--solo {
  grid-template-columns: minmax(0, 1fr);
}

.mm-homepage .mm-lower-homepage-test .mm-maker-band--solo .mm-maker-copy {
  max-width: 72ch;
}

.mm-homepage .mm-lower-homepage-test .mm-portrait img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: inherit;
}


/* ==========================================================================
   SECTION 12 - COLLECTION CARD BACK: THREE ZONES

   The back of each flip card is a column with three parts: the title near the
   top, a flexible middle that centers the button, and the price + short
   description panel resting near the bottom edge. The exact top and bottom
   spacing is printed by front-page.php from the "Our Collections" tab, so the
   two can be tuned separately without touching this file.
   ========================================================================== */
.mum-card-back .card-content-wrapper {
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  justify-content: flex-start;
}
.mum-card-back .card-content-wrapper .mm-card-mid {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 0;
}
.mum-card-back .card-content-wrapper .mm-card-meta {
  flex: 0 0 auto;
}

/* ==========================================================================
   SHARED MOTION SYSTEM  (v6)

   One easing curve and one rhythm for the whole homepage, so the GSAP
   sections up top and the reveal sections below feel like one page.

   --mm-ease is the CSS twin of GSAP's power2.out (easeOutCubic), which is
   what the showcase, carousel and category cards already use. Changing it
   here changes it everywhere, including the identity bridge above.
   ========================================================================== */
:root{
  --mm-ease:cubic-bezier(.215,.61,.355,1); /* == GSAP power2.out */
  --mm-ease-spring:cubic-bezier(.34,1.56,.64,1);
  --mm-dur:.64s;          /* section reveal */
  --mm-dur-fast:.35s;     /* micro-interaction */
  --mm-dur-slow:.82s;     /* wipes / large media */
  --mm-stagger:90ms;
  --mm-shift:28px;
}

/* --------------------------------------------------------------------------
   HERO ENTRANCE

   Scale only, at full opacity. The hero image is the LCP element, so it must
   never start transparent - an opacity:0 start would push LCP back by the
   length of the fade. A transform paints real pixels on the very first frame
   and runs on the compositor, so this costs nothing on first paint and
   cannot cause layout shift.

   It targets .main-img (not .col-center or .hero-grid) because the GSAP hero
   timeline already writes width/height/gap/padding to those, and .col-left /
   .col-right / .knockout-text already carry GSAP transforms. .main-img is the
   one element in the hero that GSAP never touches, so there is no conflict.
   -------------------------------------------------------------------------- */
@keyframes mmHeroSettle{ from{ transform:scale(1.04); } to{ transform:scale(1); } }
.mm-homepage .col-center .main-img{
  animation:mmHeroSettle 1200ms var(--mm-ease) both;
  will-change:transform;
}

/* --------------------------------------------------------------------------
   SCROLL REVEAL ENGINE

   Fail-open: everything is visible by default. homepage.js adds .mmh-js to
   <html> only after it has confirmed it can reveal things again, so if the JS
   is blocked or errors out, nothing is ever left hidden.

   Drives the four Custom HTML blocks, Reviews and FAQ. Any future element
   joins in just by adding data-mmh-reveal="up|left|right|zoom|rise|wipe".
   -------------------------------------------------------------------------- */
[data-mmh-reveal]{opacity:1;transform:none;}

html.mmh-js [data-mmh-reveal]{
  opacity:0;
  transform:var(--mmh-from,translate3d(0,var(--mm-shift),0));
  clip-path:var(--mmh-clip,none);
  will-change:opacity,transform;
}
html.mmh-js [data-mmh-reveal="up"]{--mmh-from:translate3d(0,var(--mm-shift),0);}
html.mmh-js [data-mmh-reveal="down"]{--mmh-from:translate3d(0,calc(var(--mm-shift) * -.85),0);}
html.mmh-js [data-mmh-reveal="left"]{--mmh-from:translate3d(-42px,0,0);}
html.mmh-js [data-mmh-reveal="right"]{--mmh-from:translate3d(42px,0,0);}
html.mmh-js [data-mmh-reveal="zoom"]{--mmh-from:scale(.94);}
html.mmh-js [data-mmh-reveal="rise"]{--mmh-from:translate3d(0,34px,0) scale(.97);}
html.mmh-js [data-mmh-reveal="wipe"]{opacity:1;--mmh-from:none;--mmh-clip:inset(0 0 100% 0);}
html.mmh-js [data-mmh-reveal="wipe-left"]{opacity:1;--mmh-from:none;--mmh-clip:inset(0 100% 0 0);}

/* opacity-only: for sticky elements, which must never receive a transform */
html.mmh-js [data-mmh-reveal="fade"]{--mmh-from:none;}

html.mmh-js [data-mmh-reveal].is-in{
  opacity:1;
  transform:none;
  clip-path:inset(0 0 0 0);
  transition:opacity var(--mm-dur) var(--mm-ease),
             transform var(--mm-dur) var(--mm-ease),
             clip-path var(--mm-dur-slow) var(--mm-ease);
  /* --mmh-hold is 0ms everywhere except while the page is scrolling UP, on
     the elements tagged for it. See the ROUND 4 block at the end of this
     file. */
  transition-delay:calc(var(--d,0ms) + var(--mmh-hold,0ms));
}
html.mmh-js [data-mmh-reveal].is-out{
  opacity:0;
  transform:var(--mmh-from,translate3d(0,var(--mm-shift),0));
  clip-path:var(--mmh-clip,none);
  transition:opacity .26s ease,transform .26s ease,clip-path .26s ease;
  transition-delay:0ms;
}
/* HOTFIX 2026-08-17 — clip-path deadlock.
   clip-path shrinks the box IntersectionObserver measures, opacity does not.
   So a wipe element that went out of view had zero visible area, its
   intersectionRatio could never pass the 0.01 threshold, .is-in was never
   added, and the clip was never released. It hid itself permanently.
   The .is-out state must therefore never re-apply the clip. The first wipe
   still plays, because that comes from the class-less base state above. */
html.mmh-js [data-mmh-reveal^="wipe"].is-out{opacity:1;clip-path:inset(0 0 0 0);}

/* number chips / badges: spring in just behind their card */
html.mmh-js .mmh-pop{opacity:0;transform:scale(.55) rotate(-10deg);
  transition:transform .56s var(--mm-ease-spring),opacity .32s ease;}
html.mmh-js [data-mmh-reveal].is-in .mmh-pop{opacity:1;transform:none;
  transition-delay:calc(var(--d,0ms) + 160ms);}
html.mmh-js [data-mmh-reveal].is-out .mmh-pop{opacity:0;transform:scale(.55) rotate(-10deg);transition-delay:0ms;}

/* slow settle on photography (on entry, not a loop) */
html.mmh-js .mmh-kenburns img{transform:scale(1.09);transition:transform 1.8s var(--mm-ease);}
html.mmh-js .mmh-kenburns.is-in img{transform:scale(1);}

@media (hover:hover) and (pointer:fine){
  .mmh-lift{transition:transform .26s var(--mm-ease),box-shadow .26s var(--mm-ease);}
  .mmh-lift:hover{transform:translateY(-4px)!important;
    box-shadow:0 4px 6px rgba(50,27,36,.14),0 16px 26px -8px rgba(50,27,36,.26)!important;}
}

/* --------------------------------------------------------------------------
   REVIEWS  (.mmh-proof)
   The SMS reviews animate like an actual conversation: the incoming bubble
   arrives from the left, the reply answers from the right a beat later.
   -------------------------------------------------------------------------- */
html.mmh-js .mmh-proof .mmh-sms__bubble{opacity:0;transform:translate3d(-18px,10px,0) scale(.96);
  transition:opacity .42s var(--mm-ease),transform .52s var(--mm-ease-spring);}
html.mmh-js .mmh-proof .mmh-sms__reply{transform:translate3d(18px,10px,0) scale(.96);}
html.mmh-js .mmh-proof [data-mmh-reveal].is-in .mmh-sms__bubble{opacity:1;transform:none;
  transition-delay:calc(var(--d,0ms) + 220ms);}
html.mmh-js .mmh-proof [data-mmh-reveal].is-in .mmh-sms__reply{
  transition-delay:calc(var(--d,0ms) + 560ms);}
html.mmh-js .mmh-proof [data-mmh-reveal].is-in .mmh-sms__time{transition-delay:calc(var(--d,0ms) + 780ms);}
html.mmh-js .mmh-proof .mmh-sms__time{opacity:0;transition:opacity .4s var(--mm-ease);}
html.mmh-js .mmh-proof [data-mmh-reveal].is-in .mmh-sms__time{opacity:1;}

/* stars wipe in left-to-right instead of just appearing */
.mmh-proof .mmh-stars{display:inline-block;}
html.mmh-js .mmh-proof .mmh-stars{clip-path:inset(0 100% 0 0);
  transition:clip-path .62s var(--mm-ease);}
html.mmh-js .mmh-proof [data-mmh-reveal].is-in .mmh-stars{clip-path:inset(0 0 0 0);
  transition-delay:calc(var(--d,0ms) + 200ms);}

/* review photos/screenshots settle like the Meet Starla portrait */
html.mmh-js .mmh-proof .mmh-review__photo img,
html.mmh-js .mmh-proof .mmh-review__shot img{transform:scale(1.06);transition:transform 1.2s var(--mm-ease);}
html.mmh-js .mmh-proof [data-mmh-reveal].is-in .mmh-review__photo img,
html.mmh-js .mmh-proof [data-mmh-reveal].is-in .mmh-review__shot img{transform:scale(1);}
.mmh-proof .mmh-review__photo,.mmh-proof .mmh-review__shot{overflow:hidden;}

/* --------------------------------------------------------------------------
   FAQ  (.mmh-faq)
   NOTE: .mmh-cta-card is sticky, so it is revealed with opacity ONLY.
   A transform on a sticky element silently breaks the stickiness.
   -------------------------------------------------------------------------- */
html.mmh-js .mmh-faq .mmf-item{--mmh-from:translate3d(-24px,0,0);}
.mmh-faq .mmf-icon{transition:transform .42s var(--mm-ease-spring);}
html.mmh-js .mmh-faq [data-mmh-reveal] .mmf-icon{transform:rotate(-90deg);}
html.mmh-js .mmh-faq [data-mmh-reveal].is-in .mmf-icon{transform:none;
  transition-delay:calc(var(--d,0ms) + 180ms);}

@media (prefers-reduced-motion:reduce){
  .mm-homepage .col-center .main-img{animation:none!important;}
  html.mmh-js [data-mmh-reveal],
  html.mmh-js [data-mmh-reveal].is-in,
  html.mmh-js [data-mmh-reveal].is-out,
  html.mmh-js .mmh-pop,
  html.mmh-js .mmh-proof .mmh-sms__bubble,
  html.mmh-js .mmh-proof .mmh-sms__time,
  html.mmh-js .mmh-proof .mmh-stars,
  html.mmh-js .mmh-faq .mmf-icon{
    opacity:1!important;transform:none!important;clip-path:none!important;transition:none!important;}
  html.mmh-js .mmh-kenburns img,
  html.mmh-js .mmh-proof .mmh-review__photo img,
  html.mmh-js .mmh-proof .mmh-review__shot img{transform:none!important;transition:none!important;}
}
/* ===================== END SHARED MOTION SYSTEM ===================== */


/* ==========================================================================
   HOMEPAGE MOTION - ROUND 2

   Extends the shared motion system above to the sections that sit ABOVE the
   Custom HTML blocks. Everything here is driven by the same --mm-ease curve
   and the same reveal engine, so the top of the page now reads as part of the
   same document as the bottom.

   Nothing in this block writes to an element that GSAP also writes to. That
   rule is what keeps the pinned hero, the pinned showcase and the pinned
   category rows from fighting a second animation system.
   ========================================================================== */

/* --------------------------------------------------------------------------
   "The Texas" / "Tradition."

   Opposing entrances that close toward the centre. 56px rather than a long
   sweep, for three reasons: type this large needs very little movement to
   read as motion; the parent is already fading and scaling out on a scrubbed
   pin, so a long travel would still be moving while the parent dissolves; and
   a wide translate risks horizontal overflow on a section whose ancestors
   must NOT be given an overflow value - overflow:hidden on an ancestor of a
   pinned element breaks ScrollTrigger pinning outright.
   -------------------------------------------------------------------------- */
html.mmh-js .showcase-title-line-1{--mmh-from:translate3d(-72px,0,0);}
html.mmh-js .showcase-title-line-2{--mmh-from:translate3d(72px,0,0);}

/* ROUND 4: these two lines are now the slowest reveal on the page.

   --mm-dur is the shared duration token used by the .is-in transition, so
   overriding it HERE, on the element, slows only these two spans and leaves
   every other reveal on the page at .64s. 1.05s on 72px of travel is a long,
   deliberate close - and because the spans are now fired from the pinned
   showcase timeline (see homepage.js) rather than from the viewport edge,
   the whole movement happens while the headline is on screen instead of
   finishing before the pin engages.

   The travel is trimmed on phones: the type is clamp()-scaled and 72px is a
   much larger proportion of a 390px viewport than of a 1440px one. */
html.mmh-js .showcase-title-line{--mm-dur:1.05s;}
@media (max-width:767px){
  html.mmh-js .showcase-title-line-1{--mmh-from:translate3d(-48px,0,0);}
  html.mmh-js .showcase-title-line-2{--mmh-from:translate3d(48px,0,0);}
  html.mmh-js .showcase-title-line{--mm-dur:.92s;}
}

/* The two lines are inline spans; a transform needs a block-level box. */
.showcase-title-line{display:block;}

/* --------------------------------------------------------------------------
   Identity bridge
   Slightly shorter travel than the default section reveal - this is a run of
   single lines of text, not a card, and 28px on a line of type reads as a
   lurch. 12px matches the original mmIdentityRise exactly.
   -------------------------------------------------------------------------- */
/* ROUND 4: superseded. The identity bridge is no longer six independently
   observed elements - it is one observed section that cascades its children.
   All of it now lives in the ROUND 4 block at the bottom of this file. */

/* --------------------------------------------------------------------------
   Carousel caption wrapper
   Reveals as a unit on scroll. The title and description inside it are still
   animated independently by GSAP on every card change - that is untouched.
   -------------------------------------------------------------------------- */
html.mmh-js [data-mmh-reveal].mum-info-section{--mmh-from:translate3d(0,18px,0);}

/* --------------------------------------------------------------------------
   FIX: hover lift on the category card buttons

   .magnetic-glow-btn carries the .fade-up class, so GSAP animates y on it and
   leaves an inline transform behind when the tween finishes. An inline style
   outranks a stylesheet rule, which silently killed this hover lift:

       .mum-card-category:hover .magnetic-glow-btn { transform: translateY(-2px); }

   !important is used here rather than clearProps on the tween itself. The
   desktop card timeline is SCRUBBED, and clearProps fires every time the
   playhead reaches the end of a scrubbed tween - including on the way back
   up - which produces a visible flicker as GSAP strips and re-applies the
   transform. A CSS-only fix cannot destabilise the timeline at all.
   -------------------------------------------------------------------------- */
@media (hover:hover) and (pointer:fine){
  .mum-card-category:hover .magnetic-glow-btn{transform:translateY(-2px)!important;}
}

/* --------------------------------------------------------------------------
   Reduced motion

   The GSAP timelines are now gated in homepage.js with
   (prefers-reduced-motion: no-preference), so the pinned hero, the pinned
   showcase and the pinned category rows do not build at all for these
   visitors. Scroll-jacked pinning is the single worst offender for anyone
   with vestibular sensitivity, and it was previously running regardless of
   the setting. Because each gsap.set() lives INSIDE its matchMedia callback,
   skipping the timeline also skips the offscreen starting positions, so the
   page simply renders as static, correctly laid out markup.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion:reduce){
  .showcase-title,
  .showcase-title-line-1,
  .showcase-title-line-2,
  .showcase-description .description-eyebrow,
  .showcase-description .description-body,
  .mum-info-section,
  .identity-bridge__eyebrow,
  .identity-bridge__heading,
  .identity-bridge__supporting,
  .identity-bridge__finished,
  .identity-bridge__brand,
  .identity-bridge__actions,
  .identity-bridge__actions > a{
    opacity:1!important;transform:none!important;animation:none!important;transition:none!important;
  }
  /* card backs are revealed by homepage.js for these visitors, so the parked
     .fade-up state must not hold them invisible */
  .fade-up{opacity:1!important;transform:none!important;}
}
/* ================== END HOMEPAGE MOTION - ROUND 2 ================== */

/* ==================================================================
   HOMEPAGE MOTION - ROUND 3
   ================================================================== */

/* ROUND 4: the round-3 payoff-line settle and eyebrow tracking rules were
   keyed to [data-mmh-reveal] on the elements themselves. Those attributes are
   gone now that the section is a group, so the rules are re-stated - with the
   same values - inside the ROUND 4 block at the bottom of this file. */

/* "Featured Categories" header - previously had no animation at all. */
html.mmh-js [data-mmh-reveal].categories-title{--mmh-from:translate3d(0,26px,0);}
html.mmh-js [data-mmh-reveal].categories-subtitle{--mmh-from:translate3d(0,20px,0);}

/* Carousel controls. */
html.mmh-js [data-mmh-reveal].mum-arrow{--mmh-from:scale(.86);}
html.mmh-js [data-mmh-reveal].mum-dots{--mmh-from:translate3d(0,14px,0);}

/* Round 3 additions to the reduced-motion parked state. */
@media (prefers-reduced-motion:reduce){
  .categories-title,
  .categories-subtitle,
  .mum-arrow,
  .mum-dots{
    opacity:1 !important;
    transform:none !important;
    animation:none !important;
  }
  .identity-bridge__eyebrow{transition:none !important;}
}
/* ================== END HOMEPAGE MOTION - ROUND 3 ================== */


/* ==================================================================
   HOMEPAGE MOTION - ROUND 4

   Three things live here:
     1. the scroll-up hold
     2. the identity bridge, rebuilt as a section-driven cascade
     3. a permanent guard against the stale keyframe that broke it
   ================================================================== */

/* ------------------------------------------------------------------
   1. SCROLL-UP HOLD

   Scrolling down, an element enters from the bottom of the viewport -
   empty space, nothing in the way. Scrolling up, the same element
   enters from the TOP, sliding out from behind the sticky header, so a
   reveal that starts the moment it technically intersects is already
   half over by the time it is visible. The -140px header allowance
   added in round 3 bought back the header's height but not the reading
   time, which is why the top of the page still felt "already done" on
   the way back up while the bottom of the page felt right.

   html.mmh-up is toggled by the reveal engine on every scroll. Only the
   elements tagged data-mmh-uphold react to it - the lower sections were
   reported as behaving correctly and are deliberately untouched.

   Because it is applied through calc(var(--d) + var(--mmh-hold)), the
   hold ADDS to each element's own delay and the whole cascade keeps its
   internal rhythm; it just starts later.
   ------------------------------------------------------------------ */
html.mmh-up [data-mmh-uphold]{--mmh-hold:220ms;}

/* ------------------------------------------------------------------
   2. IDENTITY BRIDGE - one section, one clock

   Previously each line was its own observed element, so each line's
   delay only began when THAT line crossed the threshold. The buttons
   sit at the bottom of the section, so their 590ms wait did not even
   start until they were already well up the screen - which is exactly
   the "the buttons take way too long to come into view" report.

   Now .identity-bridge__inner is the observed element (JS gives it
   data-mmh-group="identity") and every child animates off that single
   .is-in, so the ladder below is the real, literal running order from
   the moment the section enters:

     0ms    HANDMADE IN SAN ANGELO, TEXAS   rise + tracking .30em > .19em
     90ms   H1 heading                      rise
     190ms  "Every mum and garter..."       rise
     300ms  "Traditional mums from $150..." rise, isolated beat
     400ms  "Custom-made. Extravagant..."   scale settle, not a rise
     500ms  buttons                         staggered rise, 80ms apart

   The group element itself is never given an opacity or a transform,
   so it cannot affect layout, stacking context or stickiness.
   ------------------------------------------------------------------ */

/* parked state */
html.mmh-js [data-mmh-group="identity"] .identity-bridge__eyebrow,
html.mmh-js [data-mmh-group="identity"] .identity-bridge__heading,
html.mmh-js [data-mmh-group="identity"] .identity-bridge__supporting,
html.mmh-js [data-mmh-group="identity"] .identity-bridge__finished,
html.mmh-js [data-mmh-group="identity"] .identity-bridge__brand,
html.mmh-js [data-mmh-group="identity"] .identity-bridge__actions > a{
  opacity:0;
  transform:translate3d(0,24px,0);
  will-change:opacity,transform;
}

/* the payoff line lands as a scale settle, not one more rise */
html.mmh-js [data-mmh-group="identity"] .identity-bridge__brand{
  transform:translate3d(0,10px,0) scale(.965);
}

/* the eyebrow's tracking closes as it settles */
html.mmh-js [data-mmh-group="identity"] .identity-bridge__eyebrow{
  letter-spacing:.30em;
}

/* the delay ladder */
html.mmh-js [data-mmh-group="identity"] .identity-bridge__eyebrow{--d:0ms;}
html.mmh-js [data-mmh-group="identity"] .identity-bridge__heading{--d:90ms;}
html.mmh-js [data-mmh-group="identity"] .identity-bridge__supporting{--d:190ms;}
html.mmh-js [data-mmh-group="identity"] .identity-bridge__finished{--d:300ms;}
html.mmh-js [data-mmh-group="identity"] .identity-bridge__brand{--d:400ms;}
html.mmh-js [data-mmh-group="identity"] .identity-bridge__actions > a:nth-child(1){--d:500ms;}
html.mmh-js [data-mmh-group="identity"] .identity-bridge__actions > a:nth-child(2){--d:580ms;}
html.mmh-js [data-mmh-group="identity"] .identity-bridge__actions > a:nth-child(3){--d:660ms;}
html.mmh-js [data-mmh-group="identity"] .identity-bridge__actions > a:nth-child(n+4){--d:740ms;}

/* revealed state */
html.mmh-js [data-mmh-group="identity"].is-in .identity-bridge__eyebrow,
html.mmh-js [data-mmh-group="identity"].is-in .identity-bridge__heading,
html.mmh-js [data-mmh-group="identity"].is-in .identity-bridge__supporting,
html.mmh-js [data-mmh-group="identity"].is-in .identity-bridge__finished,
html.mmh-js [data-mmh-group="identity"].is-in .identity-bridge__brand,
html.mmh-js [data-mmh-group="identity"].is-in .identity-bridge__actions > a{
  opacity:1;
  transform:none;
  transition:opacity var(--mm-dur) var(--mm-ease),
             transform var(--mm-dur) var(--mm-ease),
             letter-spacing var(--mm-dur) var(--mm-ease);
  transition-delay:calc(var(--d,0ms) + var(--mmh-hold,0ms));
}
html.mmh-js [data-mmh-group="identity"].is-in .identity-bridge__eyebrow{
  letter-spacing:.19em;
}

/* reset on the way out - fast, and with no delay, so a section that is
   scrolled past and returned to always starts from the parked state */
html.mmh-js [data-mmh-group="identity"].is-out .identity-bridge__eyebrow,
html.mmh-js [data-mmh-group="identity"].is-out .identity-bridge__heading,
html.mmh-js [data-mmh-group="identity"].is-out .identity-bridge__supporting,
html.mmh-js [data-mmh-group="identity"].is-out .identity-bridge__finished,
html.mmh-js [data-mmh-group="identity"].is-out .identity-bridge__brand,
html.mmh-js [data-mmh-group="identity"].is-out .identity-bridge__actions > a{
  transition:opacity .26s ease,transform .26s ease,letter-spacing .26s ease;
  transition-delay:0ms;
}

@media (max-width:600px){
  html.mmh-js [data-mmh-group="identity"] .identity-bridge__eyebrow{letter-spacing:.24em;}
  html.mmh-js [data-mmh-group="identity"].is-in .identity-bridge__eyebrow{letter-spacing:.14em;}
}

/* ------------------------------------------------------------------
   3. THE GUARD

   A stale duplicate of the old load-fired keyframe was still living in
   footer.css and had been silently overriding this entire section since
   round 2 - a running @keyframes animation outranks any transition, in
   any stylesheet, at any specificity. That copy has been deleted, and
   this rule makes sure a resurrected one can never do it again.

   It is scoped to html.mmh-js, so it only applies once the reveal
   engine has confirmed it is alive and driving these elements. If the
   JS never runs, this rule never applies and any inherited animation
   still plays - the fail-open behaviour is preserved.
   ------------------------------------------------------------------ */
html.mmh-js .identity-bridge__eyebrow,
html.mmh-js .identity-bridge__heading,
html.mmh-js .identity-bridge__supporting,
html.mmh-js .identity-bridge__finished,
html.mmh-js .identity-bridge__brand,
html.mmh-js .identity-bridge__actions,
html.mmh-js .identity-bridge__actions > a{
  animation:none !important;
}

/* Reduced motion: the engine never adds .mmh-js for these visitors, so
   nothing above can apply. This is belt and braces for the case where a
   duplicate keyframe reappears in another stylesheet. */
@media (prefers-reduced-motion:reduce){
  .identity-bridge__eyebrow,
  .identity-bridge__heading,
  .identity-bridge__supporting,
  .identity-bridge__finished,
  .identity-bridge__brand,
  .identity-bridge__actions,
  .identity-bridge__actions > a,
  .showcase-title-line,
  .showcase-title-line-1,
  .showcase-title-line-2{
    opacity:1 !important;
    transform:none !important;
    animation:none !important;
    transition:none !important;
  }
}
/* ================== END HOMEPAGE MOTION - ROUND 4 ================== */


/* ==========================================================================
   HOMEPAGE MOTION - ROUND 6

   Two mobile bug fixes ONLY. No timing, easing, direction, delay, stagger
   value, GSAP timeline, ScrollTrigger or pin is changed by anything below.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. THE PAGE COULD BE DRAGGED SIDEWAYS ON MOBILE

   The reveal engine's "right" variant starts an element at
   translate3d(42px,0,0). Transforms contribute to RIGHT-hand scrollable
   overflow - left-hand overflow is discarded in LTR, which is exactly why
   the "left" reveals never caused this and the FAQ list never did either.

   On mobile the Why shell collapses to one column with 14px of .mmh-wrap
   padding plus 14px of shell padding, leaving only ~29px of slack. A 42px
   start position therefore pushed the document wider than the viewport and
   the whole page became draggable. Measured in a 375px/390px viewport:

     .mmh-reason  resting right edge 346px, viewport 375px -> 13px over
     .mmh-map     resting right edge 353px, viewport 390px ->  5px over

   The FAQ list already solved this for its own items, further up this file:

     html.mmh-js .mmh-faq .mmf-item{--mmh-from:translate3d(-24px,0,0);}

   24px instead of the engine default of 42px. The rules below are that same
   override, mirrored to the right, so the Why cards and the pickup map keep
   their direction and character and simply travel the distance the FAQ items
   already travel. 24px fits inside the padding at every breakpoint, down to
   a 320px iPhone SE, so the overflow is removed at the source.

   No overflow-x, no clipping, and nothing is applied to html, body, or any
   ancestor of a pinned or sticky element.

   Scoped per section on purpose. The global "right" variant is NOT changed,
   because .showcase-title-line-2 also uses it and that element is driven
   from the pinned showcase timeline.

   Easing and duration are unchanged, and already match the FAQ items - both
   inherit --mm-ease and --mm-dur from the :root block above.
   -------------------------------------------------------------------------- */
html.mmh-js .mmh-why .mmh-reason{--mmh-from:translate3d(24px,0,0);}
html.mmh-js .mmh-pickup .mmh-map{--mmh-from:translate3d(24px,0,0);}

/* --------------------------------------------------------------------------
   2. SCROLL JITTER WHILE THE WHY SECTION WAS IN VIEW  ***THE GUARD***

   .mmh-why was the only section on the page with NESTED backdrop-filter:

     .mmh-why            blur(2px)   <- section
       .mmh-why__shell   blur(8px)   <- inside it
         .mmh-why__intro blur(10px)  <- inside that, and position:sticky
         .mmh-reason x7  blur(10px)  <- inside that

   Ten blurred backdrops stacked three deep. Every nested backdrop-filter has
   to read back the composited output of everything painted beneath it, and
   while the section is scrolling that result is invalid on every frame, so
   the whole stack re-rasterises at 60fps. That is why the stutter began as
   the section entered the viewport and stopped the moment it left.

   The reference implementation is the FAQ section in
   template-parts/homepage/faq.php - structurally the same thing (two column
   shell, sticky dark card, MORE animated children than Why) and smooth:

     .mmh-faq          background:transparent, no backdrop-filter
     .mmh-faq__shell   blur(8px)                 <- exactly one, flat
     .mmh-cta-card     opaque, no backdrop-filter <- and it is the sticky one
     .mmf-item x10     no backdrop-filter

   THE REAL FIX IS IN THE BLOCK, NOT HERE. The three offending declarations
   have been deleted from the Custom HTML block itself (Pages > Home,
   "Why order from Starla"), which is where they actually live. See
   homepage-html-blocks-v8-animated.txt.

   This rule is a tripwire, in the same spirit as THE GUARD in round 4
   above: if an older copy of that block is ever re-pasted, it must not be
   able to quietly bring the jitter back. It is scoped with .mm-homepage so
   it outranks the <style> that ships inside the block, which comes later in
   document order.

   Only backdrop-filter is neutralised. Every background colour and alpha in
   the block is left exactly as authored, so there is no colour shift - the
   backdrops behind these elements are near-uniform, which is why the blur
   was costing a great deal and showing almost nothing.

   NOTE: .mmh-why__shell is deliberately absent from this list. It KEEPS its
   blur(8px) - it is identical to .mmh-faq__shell, which is proven smooth on
   this page. If you ever genuinely want a backdrop blur back on one of the
   elements below, delete it from this list rather than fighting it.
   -------------------------------------------------------------------------- */
.mm-homepage .mmh-why,
.mm-homepage .mmh-why .mmh-why__intro,
.mm-homepage .mmh-why .mmh-reason{
  -webkit-backdrop-filter:none !important;
  backdrop-filter:none !important;
}
/* ================== END HOMEPAGE MOTION - ROUND 6 ================== */
