/* ============================================================
   D2C user-landing-specific styles. Shared header/footer/buttons/
   FAQ/marquee come from styles.css.

   Scope: every rule prefixed with .d2c- (or scoped under body.d2c)
   so nothing here can affect the B2B lander (for-brands.html).
   ============================================================ */

body.d2c{ background: var(--cream); }

/* ============================================================
   UNIVERSAL D2C OVERRIDES — colors + button sizing
   - All buttons same size: 382 × 80 at 1920 viewport (per Figma)
   - Cream is always #EEE7DF (the canonical --cream token)
   - Red is always #F82623 (flat, no gradient endpoints)
   ============================================================ */
/* D2C buttons now inherit fully from the shared B2B .btn styles —
   gradients, hover lift, transitions, shadows, color palette. No D2C
   overrides on size, fill, or hover. */
/* Canonical cream wherever we've previously used near-creams */
body.d2c .d2c-cta-foot strong{ color: #EEE7DF; }
body.d2c .d2c-cta-inner h2,
body.d2c .d2c-cta-h{ color: #EEE7DF; }

/* QR code image inside the popup */
.d2c-popup-qr img{
  width: 100%;
  height: 100%;
  display: block;
  object-fit: contain;
}

/* Active section nav highlight (D2C scope only) */
body.d2c .nav-links a.is-active{
  color: var(--red);
}
body.d2c .nav-links a.is-active::after{
  transform: scaleX(1);
}

/* Local palette additions */
body.d2c{
  --peach:        #FCE4D6;    /* salmon/peach bg behind sheets */
  --peach-deep:   #F4D6C2;
  --skin-1:       #FFE57A;    /* yellow */
  --skin-2:       #FFC744;    /* deep yellow */
  --skin-3:       #6AD89A;    /* mint green */
  --skin-4:       #FFB06A;    /* orange */
  --skin-5:       #C9A6F0;    /* purple */
  --skin-win:     #F82623;    /* hero red card */
  --d2c-radius:   34px;
}

/* ============ SPLASH SCREEN — orchestrated logo handoff ============
   The splash overlay sits on the hero's red surface. A single logo
   instance is positioned by JS at the EXACT pixel coordinates of the
   persistent hero logo (.d2c-hero-mark). It runs three phases:
     (1) scale-in   — grows from .55 → 1.08
     (2) blur-sharp — filter drops from blur(14px) → 0
     (3) settle     — elastic overshoot resolves to scale 1
   When the logo settles, the overlay fades, the real hero logo crossfades
   in at the same position (no flicker), and the rest of the hero blooms
   outward in a staggered cascade. */
body.d2c.is-loading{
  overflow: hidden;
  /* Belt-and-suspenders against touch scroll on iOS */
  touch-action: none;
}
.d2c-splash{
  position: fixed;
  inset: 0;
  z-index: 9999;
  background: var(--red);
  pointer-events: auto;
  transition:
    opacity .55s cubic-bezier(.4, 0, .2, 1),
    visibility 0s linear .55s;
}
.d2c-splash.is-hidden{
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}
.d2c-splash-logo{
  position: absolute;
  /* Start CENTERED on the viewport. Width is sized to MATCH the hero
     logo image's clamp (hero img height clamp 22→28px × ~2.91 aspect),
     so at scale 1.0 the splash logo lands at the EXACT pixel size of
     the static hero logo. JS later animates it to the hero's position
     via the `.is-traveling` class — no size change needed. */
  left: 50%;
  top: 50%;
  width: clamp(64px, 5.24vw, 82px);
  height: auto;
  opacity: .5;
  filter: brightness(0) invert(1);
  transform: translate(-50%, -50%) scale(.5);
  animation: d2c-splash-logo-enter 1.05s cubic-bezier(.2, .7, .2, 1) both;
  /* The travel phase is handled by a CSS transition that kicks in once
     .is-traveling lands AND the inline style for transform changes. */
  transition:
    transform .95s cubic-bezier(.55, .05, .2, 1),
    width    .95s cubic-bezier(.55, .05, .2, 1),
    left     .95s cubic-bezier(.55, .05, .2, 1),
    top      .95s cubic-bezier(.55, .05, .2, 1);
}
.d2c-splash-logo.is-traveling{
  /* When traveling we let the CSS transition (defined above) drive the
     motion. `animation: none` would otherwise let the BASE rule's
     opacity:0 + blur + scale(.55) bleed back through — so we explicitly
     pin the END-of-enter visual state here. */
  animation: none;
  opacity: 1;
  filter: brightness(0) invert(1) blur(0);
}
@keyframes d2c-splash-logo-enter{
  /* Smooth, monotonic enlargement: starts smaller (scale .5) at 50%
     opacity, gradually grows to scale 1.0 (= hero logo size) at 100%
     opacity. No overshoot, no elastic — clean gradient growth. */
  0%   { opacity: .5; filter: brightness(0) invert(1); transform: translate(-50%, -50%) scale(.5); }
  100% { opacity: 1; filter: brightness(0) invert(1); transform: translate(-50%, -50%) scale(1); }
}
/* While the splash is up, gate every hero/header reveal animation. The
   existing keyframes (d2c-fade-up + the chip/card entries) all use
   animation-fill-mode: both and a small delay — pausing here keeps each
   element invisible at frame 0 until the splash hands off. */
/* TIER B: `.d2c-hero-title` is INTENTIONALLY EXCLUDED from this
   list. The hero title is the LCP element — gating it behind
   opacity:0 + paused animation until JS dismisses the splash was
   pushing LCP to ~3-4s real (and 100+s in Lighthouse Lantern
   simulation). It now uses its own transform-only entry animation
   (see `d2c-title-slide` keyframe + .d2c-hero-title rule below)
   that paints at opacity:1 from t=0. The splash overlay still
   covers it visually during the splash sequence, so the user-facing
   visual is preserved. */
body.is-loading .d2c-hero-mark,
body.is-loading .d2c-hero-tag,
body.is-loading .d2c-hero-ctas,
body.is-loading .d2c-hero-foot,
body.is-loading .d2c-chip-float,
body.is-loading .d2c-hcard,
body.is-loading .site-header .nav-links,
body.is-loading .site-header .header-right{
  animation-play-state: paused !important;
  opacity: 0;
  /* Override the paused keyframe's translateY so the hero mark sits at
     its FINAL layout position. JS measures the hero mark's location to
     anchor the splash logo's travel target — if the mark were offset
     by the keyframe's translateY(16px), the splash logo would land
     16px below the mark's resting position and the handoff would jump. */
  transform: none !important;
}
/* Body class added by JS the moment the splash logo settles. Triggers
   cascading staggered reveals — each element entering FROM the hero
   logo direction (slide-up + fade) to feel like the page blooms out of
   the logo. */
/* Distinct animation names for the cascade — the browser restarts an
   animation when its name changes, so giving the reveal phase its own
   keyframe (d2c-bloom-up) guarantees a fresh play even though the visual
   effect mirrors d2c-fade-up. */
body.d2c.is-revealed .d2c-hero-mark{
  /* Fade-only (no translateY) so the position the splash logo lands at
     during travel matches the hero mark's FINAL position — otherwise the
     mark would shift up 18px after the cascade and the handoff would
     snap visibly. */
  animation: d2c-bloom-fade .45s 0ms cubic-bezier(.2,.7,.2,1) both;
}
@keyframes d2c-bloom-fade{
  0%   { opacity: 0; }
  100% { opacity: 1; }
}
body.d2c.is-revealed .d2c-hero-tag{
  animation: d2c-bloom-up .65s 120ms cubic-bezier(.2,.7,.2,1) both;
}
/* TIER B: `.d2c-hero-title` bloom override REMOVED. The title now
   uses a transform-only `d2c-title-slide` animation defined on its
   base rule that starts at opacity:1 immediately. Re-triggering
   `d2c-bloom-up` (opacity 0→1) here would cause a brief fade-out/
   fade-in flicker after splash dismiss. Other hero elements still
   bloom in via the is-revealed cascade — title just opts out. */
body.d2c.is-revealed .d2c-hero-ctas{
  animation: d2c-bloom-up .8s 380ms cubic-bezier(.2,.7,.2,1) both;
}
body.d2c.is-revealed .d2c-hero-foot{
  animation: d2c-bloom-up .8s 520ms cubic-bezier(.2,.7,.2,1) both;
}
body.d2c.is-revealed .d2c-chip-float{
  animation: d2c-bloom-up .7s 460ms cubic-bezier(.2,.7,.2,1) both;
}
body.d2c.is-revealed .d2c-chip-right{ animation-delay: 540ms; }
body.d2c.is-revealed .d2c-chip-right-2{ animation-delay: 620ms; }
body.d2c.is-revealed .d2c-hcard{
  /* fill-mode: BACKWARDS only (not `both`) so after the bloom animation
     ends, the transform reverts to the underlying `.d2c-hcard` rule's
     `translate(var(--px), var(--py))` — letting the cursor-parallax JS
     keep updating those vars and the cards keep drifting.
     With `both` the transform was locked at `translate(0, 0) scale(1)`
     at animation end and parallax never took visible effect. */
  animation: d2c-card-bloom .85s 350ms cubic-bezier(.18, 1.1, .32, 1) backwards;
}
body.d2c.is-revealed .d2c-hcard--2{ animation-delay: 420ms; }
body.d2c.is-revealed .d2c-hcard--3{ animation-delay: 490ms; }
body.d2c.is-revealed .d2c-hcard--4{ animation-delay: 560ms; }
body.d2c.is-revealed .d2c-hcard--5{ animation-delay: 630ms; }
body.d2c.is-revealed .site-header .nav-links,
body.d2c.is-revealed .site-header .header-right{
  animation: d2c-bloom-up .7s 250ms cubic-bezier(.2,.7,.2,1) both;
}
@keyframes d2c-bloom-up{
  0%   { opacity: 0; transform: translateY(18px); }
  100% { opacity: 1; transform: translateY(0); }
}
/* Cards drift OUTWARD from the center logo direction — start slightly
   smaller, settle to full size. */
@keyframes d2c-card-bloom{
  0%   { opacity: 0; transform: translate(0, 30px) scale(.86); }
  100% { opacity: 1; transform: translate(0, 0) scale(1); }
}
@media (prefers-reduced-motion: reduce){
  .d2c-splash-logo{ animation: none; opacity: 1; filter: brightness(0) invert(1); transform: translate(-50%, -50%) scale(1); }
  body.is-loading .d2c-hero-mark,
  body.is-loading .d2c-hero-tag,
  body.is-loading .d2c-hero-title,
  body.is-loading .d2c-hero-ctas,
  body.is-loading .d2c-hero-foot,
  body.is-loading .d2c-chip-float,
  body.is-loading .d2c-hcard,
  body.is-loading .site-header .nav-links,
  body.is-loading .site-header .header-right{ animation: none; opacity: 1; }
  body.d2c.is-revealed .d2c-hero-mark,
  body.d2c.is-revealed .d2c-hero-tag,
  body.d2c.is-revealed .d2c-hero-title,
  body.d2c.is-revealed .d2c-hero-ctas,
  body.d2c.is-revealed .d2c-hero-foot,
  body.d2c.is-revealed .d2c-chip-float,
  body.d2c.is-revealed .d2c-hcard,
  body.d2c.is-revealed .site-header .nav-links,
  body.d2c.is-revealed .site-header .header-right{ animation: none; opacity: 1; transform: none; }
}

/* ============ HERO — "Your Sweepstake Advantage" (red) ============ */
/* Pin stage: gives the sticky hero a scroll runway long enough for
   section-two to sheet up over it. */
.d2c-pin-stage{
  position: relative;
  height: 200vh;   /* 100vh pinned hero + 100vh of scroll for the sheet */
  /* Establish a stacking context so .d2c-pin-stage::after's z-index is
     scoped to this container (pseudo ABOVE hero) instead of competing
     in the body's stacking context where it would be overridden by
     .d2c-section-two. Pin-stage itself remains z:1 in body stacking,
     which is BELOW .d2c-section-two (z:2), so section-two still paints
     over pin-stage as a whole. */
  z-index: 1;
}
/* Cream "shoulder" underlay — covers the bottom 80vh of the pin-stage
   with cream + z-index ABOVE the hero (within pin-stage's context).
   The hero (sticky at viewport top) overlaps this cream zone at its
   bottom edge as the user scrolls — the cream progressively masks the
   hero's bottom, so by the time section-two slides up with its rounded
   top corners, those rounded carves reveal CREAM beneath, not red.
   Result: no visible "rounded red bottom corners" on the hero, and
   section-two's rounded top sits flush against a solid cream backdrop
   at every scroll position during the band animation. */
.d2c-pin-stage::after{
  content: "";
  position: absolute;
  left: 0; right: 0;
  bottom: 0;
  height: 80vh;
  background: var(--cream);
  z-index: 2;  /* above .d2c-hero (z:1) inside pin-stage's context */
  pointer-events: none;
}

.d2c-hero{
  background: var(--red);
  color: var(--cream);
  position: sticky;     /* pins to top while .d2c-pin-stage scrolls past */
  top: 0;
  height: 100vh;
  width: 100%;
  overflow: hidden;
  /* Flex column so the foot reliably sits at the bottom in every browser
     (Safari can be quirky about sticky-as-containing-block for absolute
     descendants — flex flow side-steps that entirely). */
  display: flex;
  flex-direction: column;
  /* padding-top = exactly the fixed header height (112px) so the stage's
     top sits flush with the header's bottom; .d2c-hero-inner then adds
     120px to land its text block "about 120 px below header bottom". */
  padding: 112px clamp(20px, 4vw, 64px) 0;
  border-radius: 0;
  isolation: isolate;
  z-index: 1;
}
/* Confetti / gems / stars Figma backdrop image — sits behind everything in the hero */
.d2c-hero-bg{
  /* Hidden per request to preview the hero without the confetti backdrop.
     Remove `display: none` to bring it back. */
  display: none;
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: center;
  z-index: 0;
  pointer-events: none;
  user-select: none;
  /* Subtle ambient drift */
  animation: d2c-hero-bg-drift 22s ease-in-out infinite;
}
@keyframes d2c-hero-bg-drift{
  0%, 100% { transform: scale(1.02) translate(0, 0); }
  50%      { transform: scale(1.05) translate(-12px, -8px); }
}
@media (prefers-reduced-motion: reduce){
  .d2c-hero-bg{ animation: none; }
}
/* Ensure the stage content stays above the backdrop */
.d2c-hero > .d2c-hero-stage{ position: relative; z-index: 2; }
/* Soften the underlying ::before/::after radial layers when the image is present */
.d2c-hero::before,
.d2c-hero::after{ z-index: 1; }
/* Soft radial inside red — adds atmospheric depth */
.d2c-hero::before{
  content: "";
  position: absolute; inset: 0;
  background:
    radial-gradient(ellipse 80% 60% at 50% 30%, rgba(255,255,255,.08), transparent 60%),
    radial-gradient(ellipse 60% 50% at 10% 90%, rgba(0,0,0,.10), transparent 60%);
  pointer-events: none;
  border-radius: inherit;
}
/* Faint dotted texture */
.d2c-hero::after{
  content: "";
  position: absolute; inset: 0;
  background-image:
    radial-gradient(rgba(255,255,255,.06) 1px, transparent 1.5px);
  background-size: 28px 28px;
  pointer-events: none;
  opacity: .35;
  border-radius: inherit;
}

.d2c-hero-stage{
  max-width: var(--hero-maxw);
  margin: 0 auto;
  position: relative;
  /* Take up all remaining space in the hero flex column so the foot
     (next flex child) reliably anchors to the hero's actual bottom.
     min-height is intentionally lower so the foot's bottom margin
     fully controls vertical placement without being clamped. */
  flex: 1 1 auto;
  width: 100%;
  min-height: clamp(440px, 50vh, 680px);
}
.d2c-hero-inner{
  position: relative;
  z-index: 4;
  text-align: center;
  /* 60 px below the header's bottom edge (raised another 30 — total 60 raised
     from the original 120). */
  padding-top: 60px;
  /* Pass pointer events THROUGH the headline block so the floating
     hero cards underneath are still hoverable. The block sits at
     z-index 4 (above cards at z 2) — without this, cursor over the
     centered headline area would hit the headline first and the
     cards' mouseenter would never fire. The interactive children
     (.btn, .d2c-hero-mark anchor, etc.) opt back IN below. */
  pointer-events: none;
}
/* Re-enable pointer events on any actually-interactive child of
   .d2c-hero-inner so links + CTAs still work. */
.d2c-hero-inner a,
.d2c-hero-inner button,
.d2c-hero-inner .btn{
  pointer-events: auto;
}
/* Persistent hero logo (splash mark animates into this position) */
.d2c-hero-mark{
  display: inline-flex;
  margin: 0 auto 18px;
  align-items: center;
  justify-content: center;
  opacity: 0;
  animation: d2c-fade-up .8s .05s cubic-bezier(.2,.7,.2,1) both;
  transition: transform .3s cubic-bezier(.2,.7,.2,1);
}
.d2c-hero-mark:hover{ transform: rotate(-4deg) scale(1.06); }
.d2c-hero-mark img{
  height: clamp(22px, 1.8vw, 28px);
  width: auto;
  display: block;
  /* Tint the SVG to pure white for the hero (clean white, not cream) */
  filter: brightness(0) invert(1);
}

.d2c-hero-tag{
  margin: 0 0 18px;
  font-family: var(--display-font);
  font-weight: 700;
  font-size: clamp(12px, 1vw, 14px);
  letter-spacing: .18em;
  text-transform: uppercase;
  color: #fff;
  opacity: 0;
  animation: d2c-fade-up .8s .15s cubic-bezier(.2,.7,.2,1) both;
}
.d2c-hero-title{
  margin: 0 0 28px;
  font-family: var(--headline-font);
  font-weight: 700;
  /* Scaled down 25% from prior clamp(60px, 8.4vw, 168px) */
  font-size: clamp(45px, 6.3vw, 126px);
  line-height: .9;
  letter-spacing: -.025em;
  color: #fff;
  text-shadow: 0 4px 0 rgba(0,0,0,.08);
  /* TIER B — opacity:1 from t=0 so this (the LCP element) is
     paintable on first frame regardless of JS-driven splash classes.
     The entry animation now uses a transform-only keyframe
     (`d2c-title-slide`) — the title still slides into place but
     never goes through opacity:0, so LCP fires immediately. */
  opacity: 1;
  animation: d2c-title-slide .9s .28s cubic-bezier(.2,.7,.2,1) both;
}
.d2c-hero-ctas{
  margin: 0 0 22px;
  display: inline-flex;
  opacity: 0;
  animation: d2c-fade-up .9s .42s cubic-bezier(.2,.7,.2,1) both;
}
/* Hero btn-light inherits all visuals (size, gradient, hover, shadow)
   from the shared B2B .btn-light + .btn:hover. */
/* Hero foot — pinned near the bottom of the hero with mascot inline:
   BROWSE, ENTER, TRACK [bird] WIN BIG — bird butts up against both text blocks. */
.d2c-hero-foot{
  /* Last child of the hero flex column — naturally sits at the bottom.
     Total raise from baseline: +30 px (down 40 more from +70 — foot was
     still reading as overlapping the button, this gives a clear 70+ px gap). */
  position: relative;
  z-index: 5;
  align-self: center;
  margin: auto 0 calc(clamp(20px, 3vw, 56px) + 30px);
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  font-family: var(--display-font);
  font-weight: 700;
  font-size: clamp(13px, 1.15vw, 17px);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: #fff;
  opacity: 0;
  animation: d2c-fade-up .9s .56s cubic-bezier(.2,.7,.2,1) both;
}
.d2c-hero-foot strong{ color: #fff; font-weight: 700; }
.d2c-hero-foot-text{ white-space: nowrap; }
.d2c-hero-foot-mascot{
  display: inline-grid; place-items: center;
  width: clamp(72px, 7vw, 110px);
  height: clamp(72px, 7vw, 110px);
  /* No margin — bird's bounding box should butt right up against
     "TRACK" on the left and "WIN BIG" on the right. */
  margin: 0;
  /* Drop-shadow removed — the PNG has its own shadow baked in, so a
     CSS drop-shadow on top traced the alpha edges and produced a halo. */
}
.d2c-hero-foot-mascot img{
  width: 100%; height: 100%;
  display: block;
  object-fit: contain;
}

@keyframes d2c-fade-up{
  from{ opacity: 0; transform: translateY(16px); }
  to  { opacity: 1; transform: translateY(0); }
}
/* TIER B — transform-only variant used by .d2c-hero-title (the LCP
   element). Identical motion to d2c-fade-up (16px slide) but DOES
   NOT touch opacity, so the title stays at its base opacity:1 from
   the very first frame and LCP fires immediately. */
@keyframes d2c-title-slide{
  from{ transform: translateY(16px); }
  to  { transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce){
  .d2c-hero-tag, .d2c-hero-title, .d2c-hero-ctas, .d2c-hero-foot{ animation: none; opacity: 1; }
}

/* Floating chips at sides */
.d2c-chip-float{
  position: absolute;
  display: inline-flex; align-items: center; gap: 8px;
  padding: 10px 18px;
  border-radius: 999px;
  font-family: var(--display-font);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: .04em;
  color: var(--cream);
  background: rgba(255,255,255,.14);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  box-shadow:
    0 6px 18px rgba(0,0,0,.14),
    inset 0 1px 0 rgba(255,255,255,.18);
  z-index: 3;
  white-space: nowrap;
  opacity: 0;
  /* Chip-in fades the chip in; NO perpetual float-bob — chips sit still when idle. */
  animation: d2c-chip-in 1s 1s cubic-bezier(.2,.7,.2,1) both;
}
.d2c-chip-float .dot,
.d2c-chip-float .d2c-chip-emoji{
  /* Inline emoji — no circle container, sits on the same baseline as the
     pill's text. */
  display: inline-block;
  margin-right: 4px;
  font-size: 14px;
  line-height: 1;
  vertical-align: -1px;
  background: transparent;
  width: auto; height: auto;
  border-radius: 0;
}
/* Cursor parallax via transform (additive with the bob animation that uses
   the separate `translate` CSS property). 0deg slant per spec.
   `overflow: visible` lets emoji confetti particles fly out on hover. */
.d2c-chip-float{
  --cx: 0px; --cy: 0px;
  transform: translate(var(--cx), var(--cy));
  overflow: visible;
}
.d2c-chip-left    { top: calc(46% + 20px); left: 15%;  animation-delay: 1s, 2s; }
.d2c-chip-right   { top: 38%; right: 14%; animation-delay: 1.1s, 2.4s; }
/* Third pill shifted down + further right per QA */
.d2c-chip-right-2 { top: calc(72% + 60px); right: calc(4% + 55px);  animation-delay: 1.2s, 2.6s; }
@keyframes d2c-chip-in{
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes d2c-float-bob{
  0%, 100% { translate: 0 0; }
  50%      { translate: 0 -6px; }
}

/* Floating sweepstake cards around the headline */
.d2c-hero-cards{
  position: absolute; inset: 0;
  pointer-events: none;
  z-index: 2;
}
.d2c-hcard{
  position: absolute;
  height: auto;
  display: block;
  user-select: none;
  filter:
    drop-shadow(0 24px 36px rgba(0,0,0,.32))
    drop-shadow(0 4px 8px rgba(0,0,0,.18));
  /* Parallax translate vars set by JS (only updates on cursor move) */
  --px: 0px;
  --py: 0px;
  /* 0deg slant per Figma; transform reserved for cursor parallax only. */
  transform: translate(var(--px), var(--py));
  /* Initial rise-in only; NO perpetual bob — cards sit still when idle.
     fill-mode: BACKWARDS so the from-state applies during delay, but
     after the animation ends the transform reverts to the rule's
     `translate(var(--px), var(--py))` — which lets the cursor-parallax
     JS keep updating those vars and the cards keep drifting. With
     `both` the transform was locked at animation end and parallax
     never took effect. */
  animation: d2c-card-rise 1s cubic-bezier(.2,.7,.2,1) backwards;
  /* CSS transition removed — the parallax JS already lerps at 8% per
     rAF frame which provides the smooth drift. The extra .8s CSS
     transition layered on top caused a visible "catch-up" lag at
     page load (cards trailed behind the cursor even though the JS
     lerp had snapped current to target). */
  will-change: transform;
  /* Hero cards need pointer-events: auto so the emoji burst hover
     handler fires. The parent .d2c-hero-cards keeps pointer-events:
     none so the empty space between cards doesn't block clicks on
     the headline / CTA underneath. */
  pointer-events: auto;
  cursor: pointer;
}
.d2c-hcard-eyebrow{
  font-size: 9px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase;
  opacity: .72;
}
.d2c-hcard-title{
  font-family: var(--headline-font);
  font-weight: 700;
  font-size: clamp(22px, 2vw, 30px);
  line-height: .92;
  letter-spacing: -.015em;
  margin-top: 6px;
}
.d2c-hcard-prize{
  display: inline-block;
  margin-top: 4px;
  padding: 4px 8px;
  border-radius: 999px;
  background: var(--red);
  color: #fff;
  font-size: 11px;
  letter-spacing: .04em;
}
.d2c-hcard-foot{
  font-size: 10px;
  letter-spacing: .06em;
  text-transform: uppercase;
  opacity: .58;
}
/* Card positions — Figma proportions. Top cards lowered to overlap headline,
   with manual nudges on hero_card_2 (-50px) and hero_card_1 (-100px) per latest QA.
   HTML mapping:
     hcard--1 ← hero_card_5.png  (WIN $10K)
     hcard--2 ← hero_card_2.png  (MLS Is Back)        — raised 50 px
     hcard--3 ← hero_card_4.png  (Free Cones)
     hcard--4 ← hero_card_3.png  (Jarritos)
     hcard--5 ← hero_card_1.png  (Bar S Hope My Meal) — raised 100 px
*/
.d2c-hcard--1 { left: 10%; top: 19%;                       width: clamp(140px, 11.8vw, 200px); animation-delay: 0s; }
.d2c-hcard--2 { left: 69%; top: calc(18% - 50px);          width: clamp(132px, 10.5vw, 178px); animation-delay: .12s; }
.d2c-hcard--3 { left: 22%; top: calc(53% + 40px);          width: clamp(130px, 10.3vw, 174px); animation-delay: .24s; }
.d2c-hcard--4 { left: 80%; top: calc(42% + 30px);          width: clamp(138px, 11.3vw, 190px); animation-delay: .36s; }
.d2c-hcard--5 { left: 25%; top: calc(18% - 100px);         width: clamp(120px, 9.6vw, 162px); animation-delay: .48s; }
@keyframes d2c-card-rise{
  from { opacity: 0; transform: translateY(14px) scale(.96) rotate(0); filter: blur(2px); }
  to   { opacity: 1; filter: blur(0); }
}
/* MOBILE LCP fix — transform-only variant of d2c-card-rise used by
   .d2c-hcard inside the mobile @media block at the top of this file.
   Drops the opacity 0→1 segment so hcards are paintable from t=0,
   but preserves the translateY + scale + blur rise so the entry
   motion is visually identical to desktop. The `to` frame omits
   transform/filter so post-animation the rule's base
   `transform: translate(var(--px), var(--py))` is restored
   (lets cursor parallax keep updating those vars on devices with
   a hover pointer — no-op on touch). */
@keyframes d2c-hcard-rise-mobile{
  from { transform: translateY(14px) scale(.96); filter: blur(2px); }
  to   { filter: blur(0); }
}
@keyframes d2c-card-bob{
  0%, 100% { translate: 0 0; }
  50%      { translate: 0 -8px; }
}
@media (prefers-reduced-motion: reduce){
  .d2c-hcard, .d2c-chip-float{ animation: none; opacity: 1; }
}

/* Mascot bird at bottom-center on red */
/* (Standalone .d2c-mascot removed — mascot is now inline inside .d2c-hero-foot.) */
@keyframes d2c-mascot-bounce{
  0%, 100% { transform: translateX(-50%) translateY(0); }
  50%      { transform: translateX(-50%) translateY(-6px); }
}
@media (prefers-reduced-motion: reduce){
  .d2c-mascot{ animation: none; }
}

/* ============ SECTION 2 — sheets up over the pinned hero ============
   Mirrors the B2B .solution mechanic: starts 80vh below its natural
   position and slides to 0 as the user scrolls through the pin-stage. */
.d2c-section-two{
  position: relative;
  z-index: 5;
  background: var(--cream);
  /* Rounded top corners — clipped via clip-path NOT overflow:hidden,
     because overflow:hidden on this ancestor breaks position:sticky on
     descendants (sticky picks it up as the "scrolling ancestor" and
     never engages against the page scroll). */
  border-radius: 64px 64px 0 0;
  clip-path: inset(0 round 64px 64px 0 0);
  /* Pull section-two up into the bottom 80vh of the pin-stage so the
     sheet can begin its rise from there. */
  margin-top: -80vh;
  --sheet-y: 80vh;
  transform: translate3d(0, var(--sheet-y), 0);
  will-change: transform;
  box-shadow:
    0 -24px 60px rgba(0,0,0,.22),
    0 -2px 0 rgba(255,255,255,.02);
}

/* ============ SUBTAG — "Stop digging" body text under the mini phone ============
   No container/card. Plain centered text directly on the cream Section 2 bg.
   Padding: top reduced by 100 px to raise the text, bottom increased by
   the same 100 px so Section 3 stays at the same Y on the page. */
.d2c-subtag{
  background: transparent;
  padding: clamp(0px, 2vw, 32px) clamp(20px, 4vw, 64px) clamp(24px, 3vw, 48px);
  text-align: center;
}
/* CARD VARIANT — used inside Section 3 to wrap the pitch in a cream
   rounded container that contrasts against the brown box. */
.d2c-subtag.d2c-subtag--card{
  background: var(--cream);
  border-radius: clamp(20px, 2.4vw, 36px);
  max-width: 880px;
  margin: clamp(24px, 3vw, 44px) auto 0;
  padding: clamp(28px, 4vw, 52px) clamp(32px, 5vw, 72px);
  box-shadow:
    0 2px 4px rgba(0, 0, 0, .04),
    0 18px 40px rgba(0, 0, 0, .12),
    inset 0 1px 0 rgba(255, 255, 255, .55);
}
.d2c-subtag-text{
  margin: 0 auto;
  max-width: 70ch;
  font-family: var(--display-font);
  /* Default body weight (500). The first line uses <strong> for bold. */
  font-weight: 500;
  font-size: clamp(18px, 1.8vw, 28px);
  line-height: 1.4;
  letter-spacing: -.01em;
  /* Sits on the brown Section 3 wrapper. Regular text = subtitle palette
     (warm cream-grey); <strong> = heading palette (light cream). */
  color: #C1B099;
}
.d2c-subtag-text strong{
  color: #EEE7DF;
  font-weight: 800;
}
/* When the subtag is in the cream-card variant, flip text colors so
   they read on the lighter background. */
.d2c-subtag.d2c-subtag--card .d2c-subtag-text{
  color: #6B5953;            /* warm grey on cream */
}
.d2c-subtag.d2c-subtag--card .d2c-subtag-text strong{
  color: var(--ink-2);       /* unified brown for the bold line */
}
/* Each "word" wrapper anchors an emoji that pops above it. The emoji
   starts hidden + small + below; JS adds .is-popped at the right
   reading-pace beat and the emoji springs up into place. */
.d2c-subtag-word{
  position: relative;
  display: inline-block;
}
.d2c-subtag-emoji{
  position: absolute;
  left: 50%;
  bottom: 100%;
  margin-bottom: 6px;
  font-size: clamp(22px, 2.4vw, 38px);
  line-height: 1;
  pointer-events: none;
  user-select: none;
  opacity: 0;
  transform: translate(-50%, 14px) scale(.4) rotate(-12deg);
  transition:
    transform .65s cubic-bezier(.18, 1.4, .32, 1),
    opacity .35s ease;
  white-space: nowrap;
}
.d2c-subtag-emoji.is-popped{
  opacity: 1;
  transform: translate(-50%, 0) scale(1) rotate(0deg);
}
/* Right-side emojis: check + hand sit to the RIGHT of their word
   (instead of above), springing in from below-right with the same
   elastic ease. */
.d2c-subtag-emoji[data-tag="check"],
.d2c-subtag-emoji[data-tag="hand"]{
  bottom: auto;
  top: 50%;
  left: 100%;
  margin-bottom: 0;
  margin-left: 8px;
  transform: translate(8px, -50%) scale(.4) rotate(-12deg);
}
.d2c-subtag-emoji[data-tag="check"].is-popped,
.d2c-subtag-emoji[data-tag="hand"].is-popped{
  transform: translate(0, -50%) scale(1) rotate(0deg);
}
/* Hand emoji — once popped, keep it waving for personality. */
.d2c-subtag-emoji[data-tag="hand"].is-popped{
  animation: d2c-hand-wave-right 2.6s ease-in-out .7s infinite;
  transform-origin: 30% 100%;
}
@keyframes d2c-hand-wave-right{
  0%, 70%, 100% { transform: translate(0, -50%) scale(1) rotate(0deg); }
  10%           { transform: translate(0, -50%) scale(1) rotate(22deg); }
  20%           { transform: translate(0, -50%) scale(1) rotate(-14deg); }
  30%           { transform: translate(0, -50%) scale(1) rotate(18deg); }
  40%           { transform: translate(0, -50%) scale(1) rotate(-8deg); }
  50%           { transform: translate(0, -50%) scale(1) rotate(12deg); }
  60%           { transform: translate(0, -50%) scale(1) rotate(0deg); }
}
@media (prefers-reduced-motion: reduce){
  .d2c-subtag-emoji{ opacity: 1; transform: translate(-50%, 0) scale(1); transition: none; }
  .d2c-subtag-emoji[data-tag="check"],
  .d2c-subtag-emoji[data-tag="hand"]{ transform: translate(0, -50%) scale(1); }
  .d2c-subtag-emoji[data-tag="hand"].is-popped{ animation: none; }
}

/* ============ GIVEAWAY BAND — TRUE PINNED SCROLL SECTION ============
   Structure (per QA spec):
     .d2c-band-pin-stage  → wrapper, height: 250vh — gives 150vh of pinned
                            scroll budget after the sticky engages
     .d2c-band            → sticky, top: 0, height: 100vh — fills the
                            viewport and STAYS THERE while the user scrolls
                            through the 150vh budget. The page does NOT
                            move vertically during this window; scroll only
                            advances the JS-driven swipe progress.
   The pin engages the instant pin-stage.top hits the viewport top, and
   releases when pin-stage.bottom hits the viewport bottom (last 100vh
   of the wrapper). */
.d2c-band-pin-stage{
  position: relative;
  /* Reduced from 250vh → 160vh so there's less empty scroll between the
     pinned animation and the "Stop digging" text. Auto-sequence is
     timer-driven and locks scroll anyway, so we don't need 150vh of
     pin budget — just enough buffer (60vh) for sticky to release
     naturally after the sequence ends. */
  height: 160vh;
}
.d2c-band{
  background: var(--cream);
  position: sticky;
  top: 0;
  height: 100vh;
  width: 100%;
  padding: 0 clamp(20px, 4vw, 64px);
  text-align: center;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  isolation: isolate;
}
/* ============ Cinematic background shapes ============
   Three soft blurred blobs drift slowly behind the phone, plus a warm
   halo directly behind the phone. All decorative, pointer-events:none,
   and behind the stage via z-index. Performance: transform/opacity only,
   will-change set, paused under prefers-reduced-motion. */
.d2c-band::before,
.d2c-band::after,
.d2c-band-stage::before{
  content: "";
  position: absolute;
  pointer-events: none;
  z-index: -1;
  will-change: transform, opacity;
  border-radius: 50%;
  filter: blur(40px);
  opacity: .55;
}
.d2c-band::before{
  width: clamp(280px, 36vw, 520px);
  aspect-ratio: 1;
  left: -8%;
  top: 12%;
  background: radial-gradient(circle at 35% 35%, rgba(248, 38, 35, .35), rgba(248, 38, 35, 0) 65%);
  animation: d2c-blob-drift-a 14s ease-in-out infinite alternate;
}
.d2c-band::after{
  width: clamp(320px, 40vw, 580px);
  aspect-ratio: 1;
  right: -10%;
  bottom: 8%;
  background: radial-gradient(circle at 60% 50%, rgba(255, 196, 120, .42), rgba(255, 196, 120, 0) 65%);
  animation: d2c-blob-drift-b 18s ease-in-out infinite alternate;
}
.d2c-band-stage{ position: relative; }
.d2c-band-stage::before{
  /* Halo directly behind the phone — soft warm glow that pulses gently
     and brightens dramatically when the swipe completes. */
  width: clamp(380px, 44vw, 640px);
  aspect-ratio: 1;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  background: radial-gradient(circle, rgba(248, 38, 35, .28), rgba(248, 38, 35, 0) 60%);
  filter: blur(28px);
  opacity: .35;
  animation: d2c-halo-breath 6s ease-in-out infinite;
  transition: opacity .9s ease, filter .9s ease;
}
.d2c-band.is-celebrating .d2c-band-stage::before{
  opacity: .9;
  filter: blur(18px);
  background: radial-gradient(circle, rgba(248, 38, 35, .55), rgba(255, 196, 120, .25) 35%, rgba(255, 196, 120, 0) 62%);
}
@keyframes d2c-blob-drift-a{
  0%   { transform: translate(0, 0) scale(1); }
  100% { transform: translate(40px, -28px) scale(1.06); }
}
@keyframes d2c-blob-drift-b{
  0%   { transform: translate(0, 0) scale(1); }
  100% { transform: translate(-36px, 24px) scale(1.08); }
}
@keyframes d2c-halo-breath{
  0%, 100% { opacity: .30; transform: translate(-50%, -50%) scale(.98); }
  50%      { opacity: .42; transform: translate(-50%, -50%) scale(1.04); }
}
@media (prefers-reduced-motion: reduce){
  .d2c-band::before, .d2c-band::after, .d2c-band-stage::before{
    animation: none;
  }
}
.d2c-band-stage{
  position: relative;
  margin: 0 auto;
  max-width: 1100px;
  width: 100%;
  display: grid;
  place-items: center;
}

/* ===== Slam text — "SWIPE TO ENTER 🎉" =====
   Single full-sentence headline placed BELOW the phone (was previously
   split into a left "Swipe..." + right "To enter 🎉" pair flanking the
   phone). The typewriter writes the full sentence into `.d2c-slam-text`
   one character at a time; when the swipe completes, `.d2c-slam-emoji`
   bounces in. SF Pro Rounded Bold, centered, sits in the white-space
   under the swipe modal. */
.d2c-slam{
  position: relative;
  /* Margin + font-size smoothly capped by BOTH vw AND vh — at any
     viewport the slam shrinks/grows to fit. min() picks the smaller
     so the slam never overflows on short laptop heights. */
  margin: min(clamp(20px, 2.4vw, 36px), 4vh) auto 0;
  display: block;
  text-align: center;
  font-family: var(--display-font);  /* SF Pro Rounded */
  font-weight: 700;                  /* Bold */
  font-size: min(clamp(22px, 2.6vw, 42px), 5vh);
  line-height: 1.1;
  letter-spacing: -.01em;
  /* Brown on cream — matches the unified site brown (#2E2220 via --ink-2)
     instead of the near-black --ink that was reading too cold on the
     cream Section 2 background. */
  color: var(--ink-2);
  text-transform: none;
  white-space: normal;
  pointer-events: none;
}
.d2c-slam--full{
  /* Reserve a stable vertical slot so the text doesn't shift the phone
     above when the typewriter populates it. min-height matches the
     line-height at the largest font-size to prevent reflow. */
  min-height: 1.2em;
  padding: 0 16px;
}
.d2c-slam-text{
  display: inline;
}
/* Caret that blinks while the typewriter is writing — fades out once
   the sentence is complete. */
.d2c-slam-text::after{
  content: '';
  display: inline-block;
  width: .08em;
  height: .9em;
  margin-left: .08em;
  vertical-align: -.08em;
  background: currentColor;
  opacity: 0;
  animation: d2c-slam-caret 800ms steps(2, end) infinite;
}
.d2c-slam.is-typing .d2c-slam-text::after{
  opacity: 1;
}
@keyframes d2c-slam-caret{
  0%, 50%   { opacity: 1; }
  50.01%, 100% { opacity: 0; }
}
.d2c-slam-dots{
  /* Match the main slam text — brown on cream. */
  color: var(--ink-2);
  display: inline-block;
  margin-left: 2px;
  letter-spacing: .02em;
}
.d2c-slam-emoji{
  margin-left: .35em;
  display: inline-block;
  /* Hidden until the swipe completes — JS sets `is-celebrated` on the
     parent and we pop the emoji in. */
  opacity: 0;
  transform: scale(.4) rotate(-12deg);
  transform-origin: center;
}
.d2c-slam.is-celebrated .d2c-slam-emoji{
  animation: d2c-slam-emoji-pop .7s cubic-bezier(.2, 1.5, .3, 1) both;
}
@keyframes d2c-slam-emoji-pop{
  0%   { opacity: 0; transform: scale(.4) rotate(-12deg); }
  55%  { opacity: 1; transform: scale(1.18) rotate(6deg); }
  78%  { transform: scale(.96) rotate(-3deg); }
  100% { opacity: 1; transform: scale(1) rotate(0); }
}
/* Subtle red pulse on the text when the swipe completes — sells the
   "you did it!" beat without overshadowing the emoji. */
.d2c-slam.is-celebrated .d2c-slam-text{
  animation: d2c-slam-text-pulse .9s ease-out both;
}
@keyframes d2c-slam-text-pulse{
  0%   { color: var(--ink-2); }
  35%  { color: var(--red, #F82623); }
  100% { color: var(--ink-2); }
}
@media (prefers-reduced-motion: reduce){
  .d2c-slam.is-celebrated .d2c-slam-emoji,
  .d2c-slam.is-celebrated .d2c-slam-text{ animation: none; opacity: 1; transform: none; color: var(--ink-2); }
}

/* ============ MINI PHONE — modular layered composition ============
   See HTML for full layering documentation. Each layer is positioned
   absolutely inside .d2c-mp (whose aspect-ratio matches the phone
   asset). Coordinates are percentages so the whole composition scales
   cleanly with viewport. Prefix `.d2c-mp` is used (not `.d2c-phone`)
   to avoid clashing with the legacy Track-sheet phone classes. */
.d2c-mp{
  position: relative;
  /* RESPONSIVE WIDTH: two-axis constraint so the phone always fits.
       1. Horizontal cap: clamp(300px, 32vw, 460px) — desktop comfort
       2. Vertical cap:   (100vh - 140px) × aspect (0.603) — guarantees
          phone height + slam reservation (~140px) ≤ viewport height
     min() picks the smaller — at tall viewports the vw clamp wins
     (phone at desktop comfort size); at shorter viewports (laptops,
     etc.) the vh cap kicks in and shrinks the phone smoothly so the
     slam beneath it always fits. */
  width: min(
    clamp(300px, 32vw, 460px),
    calc((100vh - 140px) * 0.603)
  );
  aspect-ratio: 2583 / 4286;   /* matches Phone_hardware_only.png */
  margin: 0 auto;
  perspective: 1400px;
  /* container-type lets ALL phone children size relative to the
     PHONE's width (cqi units), not the viewport. So when the phone
     shrinks, the title text, Rules button text, and swipe-prompt
     text all shrink proportionally — no overflow. */
  container-type: inline-size;
  /* Cinematic entry — phone enters with a gentle scale-up + lift when the
     band first comes into view, then breathes with a slow Y-bob. The
     `.is-revealed` class is added by the band's IntersectionObserver. */
  opacity: 0;
  transform: scale(.94) translateY(22px);
  will-change: transform, opacity;
}
.d2c-band.is-revealed .d2c-mp{
  animation:
    d2c-mp-entry 1.1s cubic-bezier(.2,.7,.2,1) both,
    d2c-mp-bob 7s ease-in-out 1.3s infinite alternate;
}
@keyframes d2c-mp-entry{
  0%   { opacity: 0; transform: scale(.94) translateY(22px); }
  60%  { opacity: 1; }
  100% { opacity: 1; transform: scale(1) translateY(0); }
}
@keyframes d2c-mp-bob{
  0%   { transform: translateY(0); }
  100% { transform: translateY(-8px); }
}
@media (prefers-reduced-motion: reduce){
  .d2c-mp{ opacity: 1; transform: none; }
  .d2c-band.is-revealed .d2c-mp{ animation: none; }
}

/* 1. Unified conveyor track — all 5 cards share this stage and move as
   one connected system. Each card has its own CSS vars (--x, --scale,
   --opacity, --blur, --rotY, --z) which JS sets every animation frame
   based on its distance from the float centerIdx. */
.d2c-mp-track{
  position: absolute;
  inset: 0;
  /* NO z-index AND NO transform-style: preserve-3d. Both create
     stacking-context-like behaviour that traps the card z-indexes
     inside the track and keeps the whole carousel BELOW the phone
     shell (which sits at z:3 as a sibling). Without these, each card's
     individual z-index competes directly with the shell in the
     parent's stacking context, so the active card (z:50) can finally
     render ABOVE the shell as the foreground element.
     We lose true 3D perspective depth on the rotateY transforms — the
     side cards now read as 2D-tilted rather than 3D-rotated — but
     that's an acceptable trade for actually seeing the active card. */
  pointer-events: none;
  /* Don't clip — side cards extend past the phone bounds. */
}
.d2c-mp-card{
  position: absolute;
  /* Original sizing — height matches the cutout (56.4% of phone), width
     follows the native 745:873 aspect ratio. */
  top: 33.8%;
  left: 50%;
  width: auto;
  height: 56.4%;
  aspect-ratio: 745 / 873;
  user-select: none;
  /* NO border-radius, NO box-shadow — the card renders as the raw PNG
     asset exactly as it was authored, with no extra layering. */
  transform:
    translate(-50%, -50%)
    translate3d(var(--x, 0px), var(--y, 0px), var(--z, 0px))
    rotateY(var(--rotY, 0deg))
    scale(var(--scale, 1));
  transform-origin: center center;
  opacity: var(--opacity, 1);
  filter: blur(var(--blur, 0px));
  will-change: transform, opacity, filter;
}

/* 2. Phone hardware shell — sits ABOVE the carousel track with its
   screen interior MASKED OUT, so the centered card shows through the
   cutout. Cards in side slots (outside the phone bezels) remain visible
   because the shell only covers the phone footprint. */
.d2c-mp-shell{
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 3;
  display: block;
  pointer-events: none;
  user-select: none;
  /* Cut a rectangle out of the shell at the screen interior coordinates
     (top 5.6%, height 56.4%, left 8.6%, width 82.8% — matching the
     gradient sky area in Phone_hardware_only.png). White = visible,
     black = hidden. FULLY percent-encoded (spaces → %20, '<' → %3C,
     '>' → %3E, etc.) because the previous form with raw spaces was
     parsed inconsistently across browsers — some left the shell fully
     opaque, hiding the active carousel card. */
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20100%20100'%20preserveAspectRatio='none'%3E%3Crect%20width='100'%20height='100'%20fill='white'/%3E%3Crect%20x='8.6'%20y='5.6'%20width='82.8'%20height='56.4'%20rx='2.6'%20ry='1.8'%20fill='black'/%3E%3C/svg%3E");
  -webkit-mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;
          mask-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20100%20100'%20preserveAspectRatio='none'%3E%3Crect%20width='100'%20height='100'%20fill='white'/%3E%3Crect%20x='8.6'%20y='5.6'%20width='82.8'%20height='56.4'%20rx='2.6'%20ry='1.8'%20fill='black'/%3E%3C/svg%3E");
          mask-size: 100% 100%;
          mask-repeat: no-repeat;
}

/* 3. Title — Futura LT, all caps, in the white-space band below the
   grey decorative bars and above starter_bottom.
   Size = 1/2 of slam text. Two lines allowed, LEFT-justified, lowered
   slightly so the text reads naturally just above starter_bottom. */
.d2c-mp-title{
  position: absolute;
  /* All offsets are PHONE-RELATIVE percentages so the title's position
     scales correctly when the phone shrinks at narrower viewports.
     Previous fixed-px shifts:
       transform: translate(35px, -40px) at phone-width 460 / phone-height 763
       → 35/460 = 7.6%  horizontal nudge
       → 40/763 = 5.2%  vertical raise
     are folded directly into the `left` / `top` values. */
  top: 60.8%;                 /* was 66% with a −40 px Y translate */
  left: 16.6%;                /* was 9% with a +35 px X translate */
  right: 9%;
  height: 16%;
  margin: 0;
  z-index: 5;
  display: flex;
  align-items: flex-end;
  justify-content: flex-start;
  text-align: left;
  font-family: var(--headline-font);
  font-weight: 700;
  /* PHONE-RELATIVE: cqi = % of container (phone) width.
     At phone width 460 → 9cqi = 41.4 (clamps 41), at 300 → 9cqi = 27,
     at 240 → 9cqi = 21.6 → clamp min 18px. */
  font-size: clamp(18px, 9cqi, 48px);
  line-height: 1.05;
  letter-spacing: .01em;
  text-transform: uppercase;
  /* Brown on cream — matches the unified site brown (#2E2220). */
  color: var(--ink-2);
  white-space: normal;
  overflow: hidden;
  word-wrap: break-word;
  /* `will-change` scoped to the swap-out moment only. Title is static
     for the ~5s of carousel hold; only the 0.42s crossfade benefits
     from a pre-promoted compositor layer. */
  transition:
    opacity .42s cubic-bezier(.22, 1, .36, 1),
    filter  .42s ease;
}
.d2c-mp-title.is-swap-out{
  opacity: 0;
  filter: blur(4px);
  will-change: opacity, filter;
}

/* ============ BOTTOM INTERACTION LAYER — provided assets only ============
   Asset dimensions (verified):
     Phone_hardware_only.png  2583 × 4286   aspect 0.603
     starter_bottom.png       2174 × 446    aspect 4.874
     swipe_track.png          1152 × 321    aspect 3.589
     draggable_circle.png      253 × 253    aspect 1.000
     static_rules.png          596 × 359    aspect 1.660

   Positioning uses NATURAL asset proportions relative to the phone shell,
   so the bottom UI looks identical to the supplied design composition.

   starter_bottom is 2174/2583 = 84.2% of phone width.
   static_rules is 596/2174 = 27.4% of starter width = 23.1% of phone width.
   swipe_track is 1152/2174 = 53.0% of starter width = 44.6% of phone width.
   draggable_circle is 253/1152 = 22.0% of swipe-track width,
     and 253/321 = 78.8% of swipe-track height.
*/

/* 4. Native Rules button — compact white pill sitting to the LEFT of the
   swipe modal. Same height as the swipe wrapper (44.6% × 321/1152 = 12.4%
   of phone width ≈ 7.47% of phone height). Soft shadow, tight icon-to-
   text gap, comfortable horizontal padding.

   Left edge is anchored to the title text's left edge:
     title.left = 9% (CSS left) + 35 px (transform offset) of the phone.
   The swipe wrapper is then anchored 7 px to the right of Rules (see below),
   so the whole CTA cluster sits flush with the giveaway title.
*/
.d2c-mp-rules-btn{
  position: absolute;
  bottom: 14.6%;                       /* same baseline as .d2c-mp-swipe */
  /* PHONE-RELATIVE — matches .d2c-mp-title's left:16.6% so the Rules pill
     and the giveaway title share their left edge at ANY viewport size. */
  left: 16.6%;
  z-index: 7;
  height: 7.47%;                       /* matches swipe wrapper height */
  display: inline-flex;
  align-items: center;
  gap: 0.4em;                          /* icon→text gap relative to font */
  padding: 0 3.5%;                     /* horizontal padding as % of phone */
  margin: 0;
  background: #FFFFFF;
  border: none;
  border-radius: 999px;                /* full pill */
  font-family: var(--display-font);    /* SF Pro Rounded */
  font-weight: 600;                    /* medium-bold */
  /* Container-relative — scales with phone width via cqi unit. */
  font-size: clamp(8px, 3cqi, 14px);
  color: #000;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
  /* Subtle elevation so the pill reads as a secondary button */
  box-shadow:
    0 2px 6px rgba(0, 0, 0, 0.12),
    0 1px 2px rgba(0, 0, 0, 0.06);
}
.d2c-mp-rules-btn-icon{
  /* Scaled down to ~61% of its previous rendered size (60% → 36.6%). */
  height: 36.6%;
  width: auto;
  display: block;
  pointer-events: none;
  user-select: none;
}
.d2c-mp-rules-btn-label{
  display: inline-block;
  letter-spacing: 0;
}

/* 5–6. swipe_track.png + draggable_circle.png — the swipe interaction.
   .d2c-mp-swipe is just an empty wrapper sized to the swipe_track asset's
   exact aspect ratio, so the knob's max translateX is naturally equal to
   wrapper.width − knob.width (computed by JS using getBoundingClientRect).
   No custom backgrounds / fills / overlays. Raised alongside starter. */
.d2c-mp-swipe{
  position: absolute;
  /* right:16% positions Swipe such that there's exactly a 7 px gap
     between Rules' right edge and Swipe's left edge at phone-width 460. */
  right: 16%;
  bottom: 14.6%;
  width: 44.6%;
  aspect-ratio: 1152 / 321;          /* swipe_track natural aspect */
  z-index: 7;
  pointer-events: none;
}
.d2c-mp-swipe-track{
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  /* Track is visible from the start — knob sits at left, prompt to its right. */
  opacity: 1;
}

/* "Swipe to enter." prompt — illuminating gradient text inside the track,
   to the right of where the knob initially rests. Gradient per spec:
   linear 15% #808080 → 50% #FCFCFC → 85% #808080, animated to feel like a
   light sweep across the text.

   WIPE: a CSS mask with a hard cut at --prompt-wipe (driven by JS from the
   knob's actual rendered right-edge position). Text to the LEFT of the
   wipe line is erased; text to the right remains visible. Back-scrolling
   recomputes the same value each frame, so the text reappears as the knob
   reverses. */
.d2c-mp-swipe-prompt{
  --prompt-wipe: 0%;
  position: absolute;
  top: 50%;
  /* Left edge starts a touch past the knob's natural width (≈22% of track) */
  left: 24%;
  right: 6%;
  transform: translateY(-50%);
  z-index: 1;                          /* between track (0) and knob (z:2) */
  font-family: var(--body-font);
  font-weight: 700;
  /* RESPONSIVE: size based on PHONE width (cqi = % of container inline
     size). .d2c-mp has container-type: inline-size. At phone width 460
     → 3.3cqi ≈ 15px (clamps to 16); at 300 → 3.3cqi = 9.9 → 10 min.
     Previously this was vw-based and the text overflowed the swipe
     pill when the phone shrunk on shorter viewports. */
  font-size: clamp(9px, 3.3cqi, 16px);
  letter-spacing: .01em;
  line-height: 1;
  text-align: center;
  white-space: nowrap;
  pointer-events: none;
  user-select: none;
  /* Gradient text — colors at 15 / 50 / 85% per spec. Background-size 200%
     lets us animate the gradient horizontally for the "illuminating" feel. */
  background-image: linear-gradient(
    90deg,
    #808080 15%,
    #FCFCFC 50%,
    #808080 85%
  );
  background-size: 200% 100%;
  background-repeat: no-repeat;
  -webkit-background-clip: text;
          background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
  animation: d2c-mp-prompt-shimmer 2.8s linear infinite;
  /* Wipe mask — hard cut at --prompt-wipe; LEFT side transparent (hidden),
     RIGHT side black (visible). */
  -webkit-mask-image: linear-gradient(
    90deg,
    transparent 0%,
    transparent var(--prompt-wipe),
    black       var(--prompt-wipe),
    black       100%
  );
          mask-image: linear-gradient(
    90deg,
    transparent 0%,
    transparent var(--prompt-wipe),
    black       var(--prompt-wipe),
    black       100%
  );
  -webkit-mask-size: 100% 100%;
          mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
}
@keyframes d2c-mp-prompt-shimmer{
  from { background-position: 100% 50%; }
  to   { background-position: -100% 50%; }
}
@media (prefers-reduced-motion: reduce){
  .d2c-mp-swipe-prompt{ animation: none; background-position: 50% 50%; }
}
/* Fall animation removed — the swipe pill stays in place after the slam. */

/* (Step-based height media queries removed — the smooth min() / cqi
   responsive system on .d2c-mp + interior text now handles all
   viewport heights without step jumps.) */

.d2c-mp-swipe-handle{
  position: absolute;
  top: 50%;
  /* Resting position: left edge sits 3.4% inside the track's left edge
     (≈7 px at wrapper-width 205). PHONE-RELATIVE so it stays inset at
     all viewport sizes. JS clamps max translateX symmetrically (3.4%
     inset on the right too). */
  left: 3.4%;
  height: 78.8%;
  width: auto;
  aspect-ratio: 1 / 1;
  transform: translate(var(--swipe-x, 0px), -50%);
  display: block;
  z-index: 2;                          /* on top of the prompt as it slides over */
  will-change: transform;
}

/* Row of phone-style giveaway cards */
.d2c-band-cards{
  position: relative;
  display: flex;
  align-items: center; justify-content: center;
  gap: clamp(8px, 1vw, 22px);
  margin: 0 auto clamp(56px, 6vw, 96px);
  min-height: clamp(360px, 40vh, 520px);
  perspective: 1800px;
  max-width: 1200px;
}
.d2c-pcard{
  position: relative;
  background: #fff;
  border-radius: 28px;
  width: clamp(132px, 13vw, 220px);
  aspect-ratio: 9 / 16;
  display: flex; flex-direction: column; justify-content: space-between;
  padding: 18px 16px 22px;
  text-align: left;
  font-family: var(--display-font);
  font-weight: 800;
  color: var(--ink);
  box-shadow:
    0 28px 56px rgba(0,0,0,.18),
    0 4px 12px rgba(0,0,0,.10),
    inset 0 1px 0 rgba(255,255,255,.8);
  transition: transform .5s cubic-bezier(.2,.7,.2,1), box-shadow .5s ease;
}
.d2c-pcard-eyebrow{
  font-size: 10px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase;
  opacity: .72;
}
.d2c-pcard-title{
  font-family: var(--headline-font);
  font-weight: 700;
  font-size: clamp(20px, 2vw, 32px);
  line-height: .9;
  letter-spacing: -.018em;
  margin-top: 6px;
}
.d2c-pcard-prize{
  font-size: 10px;
  letter-spacing: .12em;
  text-transform: uppercase;
  opacity: .8;
}
.d2c-pcard-foot{
  font-size: 10px;
  letter-spacing: .06em;
  text-transform: uppercase;
  opacity: .58;
}
.d2c-skin-1{ background: var(--skin-1); }
.d2c-skin-2{ background: var(--skin-2); }
.d2c-skin-3{ background: var(--skin-3); color: #14322a; }
.d2c-skin-4{ background: var(--skin-4); color: #3a1d10; }
.d2c-skin-5{ background: var(--skin-5); color: #2a164b; }
.d2c-skin-win{ background: var(--red); color: #fff; }
.d2c-skin-win .d2c-pcard-eyebrow{ opacity: .85; }
.d2c-skin-win .d2c-pcard-prize{ opacity: .85; }
.d2c-skin-win .d2c-pcard-foot{ opacity: .7; }

.d2c-pcard--n2  { transform: rotate(-11deg) translateY(28px); z-index: 1; }
.d2c-pcard--n1  { transform: rotate(-5deg)  translateY(6px);  z-index: 2; }
.d2c-pcard--center{
  transform: rotate(0deg) translateY(-12px) scale(1.08);
  z-index: 3;
  box-shadow:
    0 38px 72px rgba(240,46,24,.32),
    0 8px 18px rgba(0,0,0,.16),
    inset 0 1px 0 rgba(255,255,255,.4);
}
/* When the center card uses a Figma export, drop the padding so the asset
   fills the card edge-to-edge. */
.d2c-pcard--asset{
  padding: 0;
  background: #fff;
  overflow: hidden;
}
.d2c-pcard-img{
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}
.d2c-pcard--p1  { transform: rotate(5deg)   translateY(6px);  z-index: 2; }
.d2c-pcard--p2  { transform: rotate(11deg)  translateY(28px); z-index: 1; }

/* Hover lift */
.d2c-pcard:not(.d2c-pcard--center):hover{
  transform: rotate(0deg) translateY(-6px) scale(1.04);
  box-shadow:
    0 36px 64px rgba(0,0,0,.22),
    0 6px 14px rgba(0,0,0,.12),
    inset 0 1px 0 rgba(255,255,255,.85);
}
.d2c-pcard--center:hover{
  transform: rotate(0deg) translateY(-18px) scale(1.10);
}

/* Floating arrows decorating the center card */
.d2c-band-cards::before,
.d2c-band-cards::after{
  content: "";
  position: absolute;
  top: -8%;
  width: 80px; height: 80px;
  background:
    radial-gradient(circle, rgba(240,46,24,.18) 0%, transparent 60%);
  border-radius: 50%;
  pointer-events: none;
  filter: blur(20px);
}
.d2c-band-cards::before{ left: 12%; }
.d2c-band-cards::after { right: 12%; }

/* Floating "← swipe →" indicator that animates on idle */
.d2c-band-hint{
  position: absolute;
  bottom: -34px; left: 50%;
  transform: translateX(-50%);
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 16px;
  border-radius: 999px;
  background: rgba(0,0,0,.06);
  font-family: var(--display-font);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink);
  pointer-events: none;
  opacity: .68;
  z-index: 4;
  animation: d2c-band-hint-bob 2.6s ease-in-out infinite;
}
.d2c-band-hint svg{
  width: 14px; height: 14px;
  animation: d2c-band-hint-arrow 1.8s ease-in-out infinite;
}
@keyframes d2c-band-hint-bob{
  0%, 100% { transform: translateX(-50%) translateY(0); }
  50%      { transform: translateX(-50%) translateY(-3px); }
}
@keyframes d2c-band-hint-arrow{
  0%, 100% { transform: translateX(0); }
  50%      { transform: translateX(4px); }
}
@media (prefers-reduced-motion: reduce){
  .d2c-band-hint, .d2c-band-hint svg{ animation: none; }
}

/* Headline below cards */
.d2c-band-text{
  max-width: 1100px;
  margin: 0 auto;
}
.d2c-band-title{
  margin: 0;
  font-family: var(--headline-font);
  font-weight: 700;
  font-size: clamp(56px, 7.5vw, 132px);
  line-height: .92;
  letter-spacing: -.025em;
  color: var(--ink);
  display: inline-flex; align-items: baseline; gap: clamp(8px, 1vw, 18px);
  flex-wrap: wrap; justify-content: center;
}
.d2c-band-arrows{
  display: inline-flex; align-items: center; gap: 2px;
  color: var(--red);
  transform: translateY(-4px);
}
.d2c-band-arrows svg{
  width: clamp(40px, 5vw, 64px);
  height: clamp(40px, 5vw, 64px);
}
.d2c-band-arrows svg:last-child{ margin-left: -22px; }
.d2c-toenter{
  position: relative;
}
.d2c-swipe-word{
  position: relative;
  display: inline-block;
}
.d2c-swipe-dots{
  letter-spacing: .04em;
  color: var(--red);
}

/* ============================================================
   SECTION SHEETS — proportional heights + rounded-top overlap
   ------------------------------------------------------------
   Figma canvas: 1920w × 10935h. Each section has a min-height
   equal to its Figma height divided by 1920, expressed in vw,
   so heights scale proportionally with viewport width.
   Heights:
     S1 Hero        1071 / 1920 ≈ 55.78vw
     S2 Swipe       1629 / 1920 ≈ 84.84vw
     S3 Stats+Track 1968 / 1920 ≈ 102.50vw
     S4 Prizes+Comm 1896 / 1920 ≈  98.75vw
     S5 FAQ         1196 / 1920 ≈  62.29vw
     S6 CTA+Footer  2243 / 1920 ≈ 116.82vw

   Sheet overlap pattern: each section gets rounded-top corners
   and a negative margin-top so it visually "sheets up" over the
   previous section's flat bottom. z-index increments so later
   sections always cover earlier ones.
   ============================================================ */
:root{
  --sheet-radius: clamp(28px, 4.5vw, 86px);
  --sheet-overlap: clamp(28px, 4vw, 80px);
}

/* Section 1 — Hero Red
   NOTE: .d2c-hero already sets position:sticky, height:100vh, z-index:1
   inside .d2c-pin-stage (which has height:200vh). Section 2 sheets up over
   it via --sheet-y JS scrubbing. Do NOT override position/height/min-height
   here — that would break the pin-stage mechanic. */

/* Section 2 — Cream (Swipe-to-enter + Stop digging) — already has overlap via JS sheet-y */
.d2c-section-two{
  position: relative;
  z-index: 2;
  min-height: 84.84vw;
  border-top-left-radius: var(--sheet-radius);
  border-top-right-radius: var(--sheet-radius);
}

/* Section 3 — Dark brown (Subtag + Stats only)
   Self-contained, fully rounded, viewport-height rectangle that AUTO
   sheets up over the swipe band after the swipe-to-enter completes.
   The sheet-up motion is a CSS transition on `transform`, triggered by
   the `.is-revealed` class added by d2c.js when the swipe finishes.

   Layout math:
   - margin-top: -100vh overlaps the bottom 100vh of the swipe band's
     pin-stage so the brown box can rise into the viewport WITHOUT the
     user needing to scroll past the band first.
   - --sheet-y: 100vh initial — visually parks Section 3 at the END of
     the band-pin-stage (below viewport when user is in the pin).
   - .is-revealed flips --sheet-y to 0 → Section 3 slides UP 100vh in
     ~700ms ease-out, landing centered in viewport. */
.d2c-section-three{
  position: relative;
  z-index: 3;
  background: #2E2220;
  color: #fff;
  /* Slightly taller than the viewport so the brown card has more
     presence and a comfortable margin around title + subtag + stats. */
  min-height: 112vh;
  height: 112vh;
  /* Overlap the bottom 100vh of the swipe-band pin stage so the sheet-up
     happens entirely OVER the band, no user scroll required. */
  margin-top: -100vh;
  /* Sheet-up transform — driven by d2c.js scroll handler so the motion
     is REVERSIBLE: scroll forward = brown slides up over the swipe band;
     scroll back = brown slides back down, exposing the band again. */
  --sheet-y: 112vh;
  transform: translate3d(0, var(--sheet-y), 0);
  will-change: transform;
  /* ALL FOUR corners rounded — section sits as a card within the viewport. */
  border-radius: var(--sheet-radius);
  /* Center subtag + title + stats vertically + horizontally. */
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.d2c-section-three-inner{
  /* Explicit flex sizing — some Safari versions mis-compute the auto
     basis of a single flex child with `width:100%` + `max-width`. */
  flex: 0 1 auto;
  width: 100%;
  max-width: var(--maxw);
  margin: 0;
  /* Padding minimised so the cluster (subtag → title → stats → CTA)
     centers tightly within the brown box — guarantees the new "Start
     winning now" CTA sits ABOVE the viewport bottom rather than being
     clipped by the brown box overflowing past viewport. */
  padding: clamp(8px, 1vw, 16px) clamp(20px, 4vw, 64px);
  box-sizing: border-box;
}
/* CTA wrapper inside the brown Section 3 — use FLEX centering instead
   of text-align so Safari reliably centers the inline-flex .btn even
   when its width is intrinsic. Adds breathing room above the button. */
.d2c-section-three-cta{
  display: flex;
  justify-content: center;
  align-items: center;
  margin-top: clamp(20px, 2.4vw, 40px);
  /* Belt-and-braces: text-align fallback for non-flex contexts. */
  text-align: center;
}

/* Section 4 — Cream (Prizes + Community) */
.d2c-section-four{
  position: relative;
  z-index: 4;
  background: var(--cream);
  min-height: 98.75vw;
  margin-top: calc(var(--sheet-overlap) * -1);
  border-radius: var(--sheet-radius) var(--sheet-radius) var(--sheet-radius) var(--sheet-radius);
}
.d2c-section-four-inner{
  max-width: var(--maxw);
  margin: 0 auto;
}

/* Section 5 — White (FAQ) */
.d2c-section-five{
  position: relative;
  z-index: 5;
  background: #fff;
  min-height: 62.29vw;
  margin-top: calc(var(--sheet-overlap) * -1);
  border-top-left-radius: var(--sheet-radius);
  border-top-right-radius: var(--sheet-radius);
}

/* Section 6 — Red CTA + cream footer */
.d2c-section-six{
  position: relative;
  z-index: 6;
  background: var(--red);
  min-height: 116.82vw;
  margin-top: calc(var(--sheet-overlap) * -1);
  border-top-left-radius: var(--sheet-radius);
  border-top-right-radius: var(--sheet-radius);
  overflow: hidden;
}
.d2c-section-six-inner{
  /* Inner stacks the red CTA above the cream footer */
}

/* ============ STATS row — inside Section 3 (dark brown) ============
   The stats now sit directly on the section bg with no inner card.
   Numbers use Futura LT Pro Bold Condensed, labels SF Pro Rounded Bold. */
/* Section 3 intro — sits ABOVE the stats. */
.d2c-section-three-intro{
  max-width: var(--maxw);
  margin: 0 auto;
  padding: clamp(80px, 10vw, 160px) clamp(24px, 4vw, 64px) 0;
  text-align: center;
  color: #fff;
}
/* "Inside the app" eyebrow that sits between the subtag and the stats.
   Small label-style text, pushed DOWN even further with a bigger top
   margin so it almost touches the stats numbers below it. The bottom
   margin is collapsed to near-zero so the title visually anchors to
   the stats — they read as one cluster. */
/* "Whats inside" — section-opening eyebrow in Futura LT Pro (the
   --headline-font). Sits ABOVE the stats as the section's lead, so
   the order reads: TITLE → numbers → cream-card pitch → CTA. */
.d2c-section-three-title{
  /* Top margin bumped +50px per QA so the title sits LOWER inside the
     brown Section 3, giving more breathing room above it. */
  margin: 50px auto clamp(24px, 3vw, 44px);
  font-family: var(--headline-font);  /* Futura LT Pro */
  font-weight: 700;
  font-size: clamp(16px, 1.5vw, 22px);
  line-height: 1.1;
  letter-spacing: .22em;
  color: #EEE7DF;
  text-align: center;
  max-width: 30ch;
  text-transform: uppercase;
}
.d2c-section-three-sub{
  margin: clamp(20px, 2vw, 32px) auto 0;
  max-width: 58ch;
  font-family: var(--body-font);
  font-weight: 500;
  font-size: clamp(16px, 1.3vw, 22px);
  line-height: 1.55;
  color: rgba(255,255,255,.85);
}

.d2c-stats{
  position: relative;
  /* Top padding trimmed by ~50px to tighten the intro→stats gap;
     bottom padding trimmed by ~50px to tighten stats→sheets gap. */
  padding: clamp(0px, 1vw, 30px) 0 clamp(0px, 1vw, 30px);
}
.d2c-stats-card{
  max-width: var(--maxw);
  margin: 0 auto;
  color: #fff;
  padding: clamp(48px, 6vw, 100px) clamp(24px, 3vw, 60px);
}
.d2c-stats-grid{
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(40px, 5vw, 96px);
  align-items: end;
  text-align: center;
}
.d2c-stat{
  display: flex; flex-direction: column;
  align-items: center;
  gap: clamp(8px, .8vw, 16px);
  position: relative;
  padding: 12px 0;
}
/* Vertical dashed divider between adjacent stats — mirrors B2B `.stat + .stat::before`.
   Lighter dash color so it reads on the dark brown Section 3 bg. */
.d2c-stat + .d2c-stat::before{
  content: "";
  position: absolute;
  left: calc(clamp(40px, 5vw, 96px) / -2);
  top: 15%;
  bottom: 15%;
  width: 3px;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='3' height='36' viewBox='0 0 3 36'><line x1='1.5' y1='1.5' x2='1.5' y2='18.5' stroke='%23C1B099' stroke-opacity='0.55' stroke-width='3' stroke-linecap='round'/></svg>");
  background-size: 3px 36px;
  background-repeat: repeat-y;
}
/* num-roll on D2C stats: roll-up uses tabular-nums to prevent width jitter,
   then a brief scale-pulse on finish (matches B2B). */
.d2c-stat .num-roll{
  display: inline-block;
  transform-origin: center;
  font-feature-settings: "tnum" 1, "lnum" 1;
}
.d2c-stat .num-roll--finished{
  animation: d2c-num-finish .6s cubic-bezier(.2,.7,.2,1);
}
@keyframes d2c-num-finish{
  0%   { transform: scale(1); }
  40%  { transform: scale(1.08); }
  100% { transform: scale(1); }
}
@media (prefers-reduced-motion: reduce){
  .d2c-stat .num-roll--finished{ animation: none; }
}
.d2c-stat-num{
  font-family: var(--headline-font);   /* Futura LT */
  font-weight: 700;
  /* Trimmed clamp + nowrap: prevents "$345k" from wrapping to two lines
     when the cell width can't fit the wide $/digits/k glyphs. */
  font-size: clamp(52px, 7vw, 110px);
  line-height: .96;
  letter-spacing: -.03em;
  /* Heading palette on brown — light cream. */
  color: #EEE7DF;
  white-space: nowrap;
}
.d2c-stat-label{
  font-family: var(--body-font);
  font-weight: 700;
  font-size: clamp(14px, 1.3vw, 22px);
  line-height: 1.2;
  /* Subtitle palette on brown — warm cream-grey. */
  color: #C1B099;
}

/* ============ TRACK BAND — Single blue rounded container ============
   Figma node 2717:5611. Blue #4DA2FF with red border, ~53px rounded.
   Black "Start entering" CTA. Phone mock on right (My Entries).
   Sits inside Section 3 (dark brown), no own padding wrapper. */
.d2c-track-band{
  position: relative;
  padding: 0 0 clamp(40px, 5vw, 80px);
}
.d2c-track-card{
  max-width: var(--maxw);
  margin: 0 auto;
  background: #4DA2FF;
  border: 1px solid #FF3E32;
  border-radius: clamp(28px, 3.5vw, 53px);
  padding: clamp(40px, 5vw, 80px) clamp(28px, 4vw, 72px);
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr);
  align-items: center;
  gap: clamp(24px, 3vw, 56px);
  position: relative;
  overflow: hidden;
  box-shadow: 0 -5px 6px rgba(0,0,0,.25), 0 30px 60px rgba(0,0,0,.12);
}
.d2c-track-text{
  position: relative;
  z-index: 2;
  color: #fff;
}
.d2c-track-tag{
  display: inline-block;
  font-family: var(--headline-font);
  font-weight: 700;
  font-size: clamp(32px, 4vw, 64px);
  line-height: 1;
  letter-spacing: -.02em;
  color: #fff;
  text-transform: uppercase;
  margin-bottom: clamp(16px, 2vw, 28px);
}
.d2c-track-title{
  margin: 0 0 clamp(12px, 1.4vw, 22px);
  font-family: var(--body-font);
  font-weight: 700;
  font-size: clamp(22px, 2.2vw, 36px);
  line-height: 1.2;
  color: #fff;
}
.d2c-track-sub{
  margin: 0 0 clamp(20px, 2.4vw, 36px);
  font-family: var(--body-font);
  font-weight: 600;
  font-size: clamp(14px, 1.2vw, 20px);
  line-height: 1.5;
  color: rgba(255,255,255,.85);
}
body.d2c .d2c-track-cta{
  background: #2E2220;
  color: #fff;
  border: none;
  font-size: clamp(15px, 1.05vw, 18px);
}
body.d2c .d2c-track-cta:hover{
  background: #fff;
  color: var(--ink);
}
.d2c-track-visual{
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* ============ SHEETED CARDS — Browse / Enter / Track ============ */
/* Three sheets that stack on scroll. The cream surface now breaks out
   of the section-three-inner max-width and reaches the full viewport
   width so the colored cards sit against cream ONLY — no brown peeking
   through on the sides. */
.d2c-sheets{
  position: relative;
  background: var(--cream);
  padding: 0;
  /* Full-bleed escape from the section-three-inner clamp. */
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  width: 100vw;
  /* Rounded top edge where cream meets brown above. */
  border-top-left-radius: clamp(28px, 3vw, 56px);
  border-top-right-radius: clamp(28px, 3vw, 56px);
}
.d2c-sheets-stage{
  position: relative;
  /* Stage tall enough to scroll through all three sheets AND give each
     card its own hold zone so users actually SEE the third (TRACK)
     card before the red features section comes in. Budget per JS
     (after sensitivity tuning — wider HOLD/TRANS windows):
       hold sheet 1 (80vh) + transition 1→2 (120vh)
       hold sheet 2 (80vh) + transition 2→3 (120vh)
       hold sheet 3 (100vh) = 500vh of pinned scroll + 100vh pin engage.
     Increased from 500vh → 600vh so small scroll movements produce
     less animation progress per tick. */
  height: 600vh;
}
.d2c-sheets-pin{
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex; align-items: center; justify-content: center;
  padding: 0 clamp(20px, 4vw, 64px);
}
.d2c-sheet{
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  /* Figma card: 1686 × 831 on a 1920 page → 87.8% of viewport width */
  width: min(1686px, 87.8vw);
  /* Tall enough to nearly fill the viewport, capped so it never overflows */
  height: min(831px, 85vh);
  background: var(--peach);
  border-radius: clamp(32px, 3.4vw, 56px);
  /* Higher top padding pushes text to the top of the card per Figma */
  padding: clamp(56px, 6vw, 96px) clamp(40px, 4vw, 80px) clamp(40px, 4vw, 64px);
  display: grid;
  /* Wider visual column so each browse column can grow large enough to
     show exactly 2 giveaway cards stacked (card aspect ≈ 0.8, so each card
     needs height ≈ column_width × 1.25). */
  grid-template-columns: minmax(200px, 1fr) minmax(0, 2.4fr);
  /* minmax(0, 1fr) on the row stops the grid from expanding to the visual's
     unconstrained content height — column tracks (incl. the infinite-scroll
     image strips) can otherwise blow past the sheet's height cap. */
  grid-template-rows: minmax(0, 1fr);
  gap: clamp(20px, 2.4vw, 56px);
  /* Text aligns to the TOP of the card, not center */
  align-items: start;
  box-shadow:
    0 30px 80px rgba(0,0,0,.18),
    0 4px 12px rgba(0,0,0,.10),
    inset 0 1px 0 rgba(255,255,255,.5);
  /* will-change scoped to transform/opacity only (filter is no longer
     written on mobile, so promoting a filter layer is wasted memory).
     Sheets are continuously transformed by the JS scrubber while the
     stage is in view, so leaving will-change on is acceptable here —
     the cost is bounded to 3 elements. */
  will-change: transform, opacity;
  overflow: hidden;
}
/* Per-sheet brand colors per spec:
   - BROWSE: blue   #4DA2FF
   - ENTER:  purple #D7A2FF
   - TRACK:  green  #56DB9C */
.d2c-sheet--browse{ background: #4DA2FF; }
.d2c-sheet--enter{  background: #D7A2FF; }
.d2c-sheet--track{  background: #56DB9C; }
/* All text inside each sheet card renders in the cream color (#EEE7DF)
   for consistent legibility on the blue/purple/green card surfaces. */
.d2c-sheet--browse, .d2c-sheet--browse .d2c-sheet-title,
.d2c-sheet--browse .d2c-sheet-copy, .d2c-sheet--browse .d2c-sheet-sub,
.d2c-sheet--browse .d2c-sheet-copy strong,
.d2c-sheet--enter, .d2c-sheet--enter .d2c-sheet-title,
.d2c-sheet--enter .d2c-sheet-copy, .d2c-sheet--enter .d2c-sheet-sub,
.d2c-sheet--enter .d2c-sheet-copy strong,
.d2c-sheet--track, .d2c-sheet--track .d2c-sheet-title,
.d2c-sheet--track .d2c-sheet-copy, .d2c-sheet--track .d2c-sheet-sub,
.d2c-sheet--track .d2c-sheet-copy strong{
  color: #EEE7DF;
}

/* Text column sits at top of card, stacks tightly per Figma */
.d2c-sheet-text{
  display: flex;
  flex-direction: column;
  align-self: start;
}
/* Visual side stretches to the full sheet row height (constrained by
   the sheet's minmax(0, 1fr) row) so its children — including the
   3-column infinite-scroll image strips — fill vertically without
   spilling past the sheet height cap. */
.d2c-sheet-visual{
  align-self: stretch;
  height: 100%;
  min-height: 0;
  min-width: 0;
  overflow: hidden;
}
.d2c-sheet-title{
  margin: 0 0 14px;
  font-family: var(--headline-font);
  font-weight: 700;
  /* Slightly smaller than before so the headline + sub fit cleanly at top */
  font-size: clamp(56px, 5.6vw, 96px);
  line-height: .92;
  letter-spacing: -.025em;
  color: var(--ink);
}
.d2c-sheet-copy{
  margin: 0 0 6px;
  font-family: var(--display-font);
  font-weight: 800;
  font-size: clamp(18px, 1.7vw, 26px);
  line-height: 1.2;
  letter-spacing: -.012em;
  color: var(--ink);
  max-width: 22ch;
}
.d2c-sheet-copy strong{ font-weight: 800; }
.d2c-sheet-sub{
  margin: 0 0 24px;
  font-family: var(--display-font);
  font-weight: 600;
  font-size: clamp(14px, 1.05vw, 17px);
  line-height: 1.5;
  color: #4a3835;
  max-width: 32ch;
}
.d2c-sheet-cta{ margin-top: 8px; align-self: flex-start; }

/* BROWSE — 3 vertically-looping columns of giveaway cards.
   Figma reference:
     • Container: 1785 × 880.11
     • Per card:  324.56 × 405.52  (aspect 0.8)
     • Per column visible: 2 full cards stacked
     • Gap between columns: 41 px
     • Last column ends 139 px from the container right edge
   Translated to relative units so it scales with the sheet visual area. */
.d2c-browse-columns{
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  /* Minimal gap so column width can grow to show exactly 2 cards */
  gap: clamp(8px, 1vw, 18px);
  /* Right padding removed — using "more of the right-side spacing" per spec */
  padding-right: 0;
  width: 100%;
  height: 100%;
  align-items: center;
  perspective: 1200px;
}
.d2c-browse-col{
  position: relative;
  overflow: hidden;
  width: 100%;
  /* Column fills the full height of the sheet visual area (per latest QA) */
  height: 100%;
  border-radius: clamp(18px, 2vw, 32px);
  /* Soft fade at the top/bottom so cards melt into the loop boundary */
  -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 7%, #000 93%, transparent 100%);
          mask-image: linear-gradient(180deg, transparent 0%, #000 7%, #000 93%, transparent 100%);
}
.d2c-browse-col-track{
  display: flex;
  flex-direction: column;
  width: 100%;
  will-change: transform;
  /* Wrap-gap calculated per Figma ratio: 18 / 2926 ≈ 0.615 % of the
     rendered image height. At 1440 viewport the strip renders ~2640 px
     tall, so the gap is ~16 px; at 1920 it's ~22 px. clamp() keeps it
     scaling proportionally with viewport width (which drives column width
     which drives strip rendered height). */
  --strip-gap: clamp(10px, 1.13vw, 22px);
  gap: var(--strip-gap);
}
.d2c-browse-col-track img{
  display: block;
  width: 100%;
  height: auto;
  flex-shrink: 0;
  user-select: none;
  pointer-events: none;
}
/* <picture> wrapping each <img> for responsive source switching.
   display:contents removes the picture from layout so the column
   flex container still sees the inner <img> as its direct child
   (preserves the flex-direction:column stacking + flex-shrink:0
   semantics). */
.d2c-browse-col-track picture{
  display: contents;
}
/* Continuous loop — each strip is duplicated twice in the DOM, so a -50 %
   vertical translate puts the second copy exactly where the first started,
   making the wrap point invisible. Durations intentionally slow (90s / 100s)
   so each card lingers long enough to read. */
.d2c-browse-col-track--up{
  animation: d2c-browse-up 90s linear infinite;
}
.d2c-browse-col-track--down{
  animation: d2c-browse-down 100s linear infinite;
}
/* Wrap math: track is `2H + gap`. To put the second strip exactly where
   the first started, translate by -(H + gap). In percent of track that's
   `-(H + gap) / (2H + gap)` ≈ -50% - half_gap. Using a CSS variable so
   the math stays correct as --strip-gap scales with viewport. */
@keyframes d2c-browse-up{
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(0, calc(-50% - var(--strip-gap) / 2), 0); }
}
@keyframes d2c-browse-down{
  from { transform: translate3d(0, calc(-50% - var(--strip-gap) / 2), 0); }
  to   { transform: translate3d(0, 0, 0); }
}
@media (prefers-reduced-motion: reduce){
  .d2c-browse-col-track--up,
  .d2c-browse-col-track--down{ animation: none; }
}
.d2c-gtile{
  border-radius: 14px;
  aspect-ratio: 3 / 4;
  display: flex; align-items: flex-end;
  padding: 12px;
  color: var(--ink);
  font-family: var(--display-font);
  font-weight: 800;
  font-size: 12px;
  line-height: 1.05;
  letter-spacing: -.005em;
  box-shadow:
    0 12px 24px rgba(0,0,0,.12),
    inset 0 1px 0 rgba(255,255,255,.5);
  position: relative; overflow: hidden;
  transition: transform .5s cubic-bezier(.2,.7,.2,1), box-shadow .5s ease;
}
.d2c-gtile::after{
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(180deg, transparent 50%, rgba(0,0,0,.12) 100%);
  pointer-events: none;
}
.d2c-gtile span{ position: relative; z-index: 2; }
.d2c-gtile:hover{
  transform: translateY(-4px) scale(1.02);
  box-shadow:
    0 18px 36px rgba(0,0,0,.16),
    inset 0 1px 0 rgba(255,255,255,.6);
}
.d2c-gtile--a{
  background:
    radial-gradient(circle at 75% 25%, rgba(255,255,255,.42) 0%, transparent 36%),
    linear-gradient(160deg, #FFEDB8 0%, #FFCF52 100%);
  color: #3a2510;
}
.d2c-gtile--b{
  background:
    radial-gradient(circle at 25% 25%, rgba(255,255,255,.32) 0%, transparent 36%),
    linear-gradient(160deg, #A6E64A 0%, #4FA02A 100%);
  color: #14290a;
}
.d2c-gtile--c{
  background:
    radial-gradient(ellipse at 30% 10%, rgba(255,200,120,.36) 0%, transparent 50%),
    linear-gradient(160deg, #5A3F32 0%, #2B1F19 100%);
  color: #fff;
}
.d2c-gtile--d{
  background:
    radial-gradient(circle at 70% 70%, rgba(180,200,120,.22) 0%, transparent 45%),
    linear-gradient(160deg, #2A5236 0%, #173322 100%);
  color: #fff;
}
.d2c-gtile--e{
  background:
    radial-gradient(ellipse at 50% 30%, rgba(255,255,255,.3) 0%, transparent 45%),
    linear-gradient(160deg, #F58E2F 0%, #DB6314 100%);
  color: #fff;
}
.d2c-gtile--f{
  background:
    radial-gradient(circle at 20% 80%, rgba(255,255,255,.24) 0%, transparent 40%),
    linear-gradient(160deg, #D2C394 0%, #B0A06F 100%);
  color: #2c220e;
}
/* Decorative chip badge in each tile's top corner (eyebrow) */
.d2c-gtile::before{
  content: attr(data-tag);
  position: absolute;
  top: 8px; left: 8px;
  font-family: var(--display-font);
  font-weight: 800;
  font-size: 8px;
  letter-spacing: .08em;
  text-transform: uppercase;
  background: rgba(0,0,0,.16);
  color: rgba(255,255,255,.92);
  padding: 3px 7px;
  border-radius: 999px;
  z-index: 2;
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}
/* Color-corrected chips for light tiles */
.d2c-gtile--a::before,
.d2c-gtile--b::before,
.d2c-gtile--f::before{
  background: rgba(0,0,0,.10);
  color: rgba(0,0,0,.7);
}
/* Tiny stat row at the bottom-right (like Figma giveaway cards) */
.d2c-gtile::after{
  background:
    linear-gradient(180deg, transparent 50%, rgba(0,0,0,.16) 100%);
}

/* ENTER — toggle widget */
.d2c-enter-visual{
  position: relative;
  display: grid; place-items: center;
  height: 100%;
  width: 100%;
  /* Products can spill past the visual frame — they get clipped by the
     cream sheet's own overflow:hidden + rounded border instead. */
  overflow: visible;
}
/* The shared .d2c-sheet-visual rule sets overflow:hidden which would
   re-clip our products. Override JUST for the ENTER sheet so the visual
   column doesn't clip — the cream sheet stays the only clip boundary. */
.d2c-sheet--enter .d2c-sheet-visual{ overflow: visible; }
.d2c-enter-stage{
  position: relative;
  width: 100%;
  /* Height matches the visual container so % positions resolve against
     the SAME box the products visually live in (visual has overflow:
     hidden — anything past these bounds gets clipped). */
  height: 100%;
  min-height: clamp(280px, 26vw, 360px);
  display: grid; place-items: center;
  isolation: isolate;
}
/* Five product images arranged around the swipe button. Each card has a
   gentle idle float, and an animated burst-out keyed off .is-bursting on
   the visual. The burst vector + rotation are passed via CSS vars per card
   (set inline in HTML). */
.d2c-enter-prod{
  position: absolute;
  display: grid; place-items: center;
  /* --mx / --my are driven by the mouse-parallax JS — every product
     translates by its own depth × cursor delta. The compose order is
     translate → rotate → scale so the rest pose stays intact. */
  transform:
    translate(var(--mx, 0px), var(--my, 0px))
    rotate(var(--rest-rot, 0deg))
    scale(var(--rest-scale, 1));
  transition:
    transform .65s cubic-bezier(.2,.7,.2,1),
    opacity .6s ease,
    filter .6s ease;
  will-change: transform, opacity;
  z-index: 1;
}
.d2c-enter-prod img{
  width: 100%; height: 100%;
  object-fit: contain;
  user-select: none;
  -webkit-user-drag: none;
  /* No drop-shadow — most prize PNGs already ship with baked-in shadows
     and a CSS shadow on top reads as a grey halo around the silhouette. */
}
/* Per-prize positioning. Each object gets:
   - explicit width (height auto via grid + img object-fit: contain)
   - top/left/right anchor (sometimes negative to crop past stage edge)
   - --rest-rot for resting tilt
   - --rest-scale baseline scale (compounded with hover/bob if any)
   - --shadow drop-shadow tuned for the asset's silhouette
   - z-index for stacking
   - animation-delay so the gentle bob is desynchronised */
/* Layout calibrated to the Figma reference screenshot. Positions are
   percentages of the stage so the composition scales cleanly with the
   sheet. Tahoe + perfume crop intentionally past the right edge for the
   cinematic feel called for. Football + Luke + giftcard layer behind the
   swipe CTA at the bottom. */
/* Layered composition — products overlap slightly. z-index controls
   stacking; --depth is read by the mouse-parallax JS (larger = moves
   more, reads as closer/foreground). Auto-float removed; only cursor
   parallax drives motion now. */
/* Layered composition — sizing/positioning matches the Figma reference.
   Stacking: tahoe & headphones sit at the back; YETI in front of head-
   phones; swipe CTA mid; perfume + football tuck BEHIND the CTA on the
   right; gift card sits IN FRONT of the CTA on the left; Luke Combs on
   top. --depth feeds the cursor-parallax JS. */
.d2c-enter-prod--head{
  width: clamp(150px, 19vw, 260px);
  top: -12%;
  left: 8%;
  --rest-rot: -4deg;
  --rest-scale: 1;
  --shadow: 0 26px 36px rgba(0,0,0,.22);
  --depth: 10;
  z-index: 3;
}
.d2c-enter-prod--bag{
  width: clamp(130px, 16vw, 220px);
  top: -4%;
  left: 36%;
  --rest-rot: -4deg;
  --rest-scale: 1;
  --shadow: 0 30px 40px rgba(0,0,0,.24);
  --depth: 14;
  z-index: 4;
}
.d2c-enter-prod--tahoe{
  width: clamp(170px, 21vw, 290px);
  top: 4%;
  right: -6%;
  --rest-rot: 4deg;
  --rest-scale: 1;
  --shadow: 0 24px 32px rgba(0,0,0,.22);
  --depth: 8;
  z-index: 3;
}
.d2c-enter-prod--products{
  width: clamp(100px, 12vw, 170px);
  top: 22%;
  right: -8%;
  --rest-rot: 55deg;
  --rest-scale: 1;
  --shadow: 0 22px 30px rgba(0,0,0,.28);
  --depth: 16;
  z-index: 4;
}
.d2c-enter-prod--beer{
  width: clamp(72px, 9vw, 120px);
  top: 24%;
  left: 2%;
  --rest-rot: -10deg;
  --rest-scale: 1;
  --shadow: 0 18px 26px rgba(0,0,0,.28);
  --depth: 12;
  z-index: 5;
}
.d2c-enter-prod--giftcard{
  width: clamp(140px, 17vw, 230px);
  top: 56%;
  left: 4%;
  --rest-rot: -18deg;
  --rest-scale: 1;
  --shadow: 0 22px 32px rgba(0,0,0,.22);
  --depth: 18;
  z-index: 8;
}
.d2c-enter-prod--luke{
  width: clamp(96px, 12vw, 160px);
  top: 78%;
  left: 32%;
  --rest-rot: -2deg;
  --rest-scale: 1;
  --shadow: 0 16px 24px rgba(0,0,0,.28);
  --depth: 22;
  z-index: 9;
}
.d2c-enter-prod--football{
  width: clamp(140px, 17vw, 230px);
  top: 56%;
  right: 2%;
  --rest-rot: 12deg;
  --rest-scale: 1;
  --shadow: 0 24px 32px rgba(0,0,0,.26);
  --depth: 14;
  z-index: 4;
}
/* ===== Extra prizes — added for visual density / overlap ===== */
.d2c-enter-prod--cooler{
  width: clamp(120px, 15vw, 200px);
  top: 38%;
  /* Moved LEFT (was 22% → 6%) per QA — the cooler should sit out on
     the LEFT side of the visual area and only barely overlap with the
     centered swipe pill, not crowd it. */
  left: 6%;
  --rest-rot: -6deg;
  --rest-scale: 1;
  --depth: 16;
  z-index: 7;     /* overlaps in front of headphones + tahoe */
}
.d2c-enter-prod--perfume{
  width: clamp(80px, 10vw, 140px);
  top: 14%;
  left: 22%;
  --rest-rot: 8deg;
  --rest-scale: 1;
  --depth: 12;
  z-index: 5;
}
.d2c-enter-prod--sneaker{
  width: clamp(130px, 16vw, 210px);
  top: 38%;
  right: 18%;
  --rest-rot: 14deg;
  --rest-scale: 1;
  --depth: 14;
  z-index: 6;     /* overlaps slightly over the swipe CTA */
}
.d2c-enter-prod--wallet{
  width: clamp(110px, 14vw, 180px);
  top: 70%;
  left: 22%;
  --rest-rot: -8deg;
  --rest-scale: 1;
  --depth: 16;
  z-index: 7;
}
.d2c-enter-prod--headphones{
  width: clamp(140px, 18vw, 240px);
  top: -10%;
  right: 28%;
  --rest-rot: -2deg;
  --rest-scale: 1;
  --depth: 10;
  z-index: 2;
}
@keyframes d2c-enter-bob{
  0%, 100% { transform: translateY(0) rotate(var(--rest-rot, 0deg)) scale(var(--rest-scale, 1)); }
  50%      { transform: translateY(-8px) rotate(calc(var(--rest-rot, 0deg) + 3deg)) scale(var(--rest-scale, 1)); }
}

/* ============ CINEMATIC INTRO — staggered prop drop-in ============
   When the ENTER sheet first appears (.is-cinematic-intro is briefly
   added by JS), each prop starts hidden + scaled down + rotated off
   axis, then transitions into its rest pose with a staggered delay
   driven by inline `--i` per prop. The existing transition on
   .d2c-enter-prod (transform/opacity/filter ~0.65s ease) is overridden
   here so we can use a longer, more elastic curve + per-prop delay. */
.d2c-enter-visual.is-cinematic-intro .d2c-enter-prod{
  opacity: 0;
  transform:
    translate(var(--mx, 0px), calc(var(--my, 0px) + 60px))
    rotate(calc(var(--rest-rot, 0deg) - 10deg))
    scale(0.45);
  transition: none;
}
.d2c-enter-visual .d2c-enter-prod{
  /* Add a per-prop delay AND a slower/elastic curve so when the
     .is-cinematic-intro class is REMOVED, each prop transitions back
     to its rest pose with a staggered, bouncy entrance. The delay falls
     to 0 on subsequent state changes because we reset it in JS once the
     intro has played. */
  transition:
    transform 0.95s cubic-bezier(.18, 1.25, .28, 1) calc(var(--i, 0) * 0.07s),
    opacity 0.55s ease calc(var(--i, 0) * 0.07s),
    filter 0.6s ease;
}

/* ============ AMBIENT DRIFT — subtle "camera handheld" feel ============
   The stage pans by tiny amounts in a long, slow loop so the composition
   never feels fully static even when no swipe is firing. Pauses on
   prefers-reduced-motion. */
.d2c-enter-stage{
  animation: d2c-enter-stage-drift 14s ease-in-out infinite alternate;
}
@keyframes d2c-enter-stage-drift{
  0%   { transform: translate(0, 0); }
  50%  { transform: translate(8px, -6px); }
  100% { transform: translate(-6px, 4px); }
}
@media (prefers-reduced-motion: reduce){
  .d2c-enter-stage{ animation: none; }
}

/* ============ TELEGRAPH PULSE — primes the eye before the swipe ============
   A soft red halo pulses around the swipe handle for ~1s right before
   the auto-swipe animation fires, telegraphing the upcoming motion. */
.d2c-enter-swipe-handle.is-telegraphing{
  animation: d2c-enter-handle-pulse 1.0s ease-out 2;
}
@keyframes d2c-enter-handle-pulse{
  0%   { box-shadow:
           0 3px 8px rgba(0, 0, 0, .18),
           inset 0 1px 0 rgba(255,255,255,.14),
           0 0 0 0 rgba(248, 38, 35, .55); }
  60%  { box-shadow:
           0 3px 8px rgba(0, 0, 0, .18),
           inset 0 1px 0 rgba(255,255,255,.14),
           0 0 0 22px rgba(248, 38, 35, 0); }
  100% { box-shadow:
           0 3px 8px rgba(0, 0, 0, .18),
           inset 0 1px 0 rgba(255,255,255,.14),
           0 0 0 0 rgba(248, 38, 35, 0); }
}
@media (prefers-reduced-motion: reduce){
  .d2c-enter-swipe-handle.is-telegraphing{ animation: none; }
}

/* ============ BURST FLASH — radial bloom when the swipe completes ============
   A bright radial gradient fades in centered on the swipe pill, then
   washes out — like camera flash for the prize reveal. Sits behind the
   products via z-index so they remain readable on top of the glow. */
.d2c-enter-visual::after{
  content: "";
  position: absolute;
  inset: -10%;
  background: radial-gradient(circle at 50% 55%,
    rgba(255, 230, 200, .55) 0%,
    rgba(255, 220, 180, .25) 22%,
    rgba(255, 220, 180, 0) 55%);
  opacity: 0;
  pointer-events: none;
  z-index: 7;            /* below the swipe pill (z=6 but inside its own context) */
  mix-blend-mode: screen;
}
.d2c-enter-visual.is-bursting::after{
  animation: d2c-enter-burst-flash 1.6s cubic-bezier(.18, 1, .3, 1) both;
}
@keyframes d2c-enter-burst-flash{
  0%   { opacity: 0; transform: scale(.6); }
  18%  { opacity: 1; transform: scale(1.05); }
  100% { opacity: 0; transform: scale(1.25); }
}
@media (prefers-reduced-motion: reduce){
  .d2c-enter-visual.is-bursting::after{ animation: none; opacity: 0; }
}
/* BURST — on .is-bursting, each prize gives a brief reactive bounce that
   composes with its resting rotation/scale. The big visual is the SHOWER
   of mini product particles that JS spawns simultaneously. */
.d2c-enter-visual.is-bursting .d2c-enter-prod{
  animation: d2c-enter-burst 1.0s cubic-bezier(.16, 1.1, .3, 1) both;
}
@keyframes d2c-enter-burst{
  0%   { transform: translate(0, 0) rotate(var(--rest-rot, 0deg)) scale(var(--rest-scale, 1)); }
  40%  { transform: translate(0, -10px) rotate(calc(var(--rest-rot, 0deg) + var(--br, 0deg))) scale(calc(var(--rest-scale, 1) * 1.1)); }
  100% { transform: translate(0, 0) rotate(var(--rest-rot, 0deg)) scale(var(--rest-scale, 1)); }
}

/* Mini product particles — JS spawns these inside the stage. Each gets
   inline CSS vars (--mx, --my, --mr, --ms, --md) for its end position,
   rotation, scale, and animation duration. Linger at full opacity through
   most of the flight so the shower reads clearly. */
.d2c-enter-mini{
  position: absolute;
  top: 50%; left: 50%;
  width: clamp(36px, 4.5vw, 64px);
  aspect-ratio: 1;
  pointer-events: none;
  opacity: 0;
  transform: translate(-50%, -50%) scale(.3) rotate(0);
  animation: d2c-enter-mini-fly var(--md, 1.6s) cubic-bezier(.22, .9, .35, 1) both;
  z-index: 8;
}
.d2c-enter-mini img{
  width: 100%; height: 100%;
  object-fit: contain;
  filter: drop-shadow(0 10px 18px rgba(0,0,0,.28));
  user-select: none;
  -webkit-user-drag: none;
}
@keyframes d2c-enter-mini-fly{
  0%   { opacity: 0;   transform: translate(-50%, -50%) scale(.3) rotate(0); }
  10%  { opacity: 1;   transform: translate(calc(-50% + (var(--mx) * .15)), calc(-50% + (var(--my) * .15))) scale(var(--ms, 1)) rotate(calc(var(--mr) * .15)); }
  70%  { opacity: 1;   transform: translate(calc(-50% + (var(--mx) * .85)), calc(-50% + (var(--my) * .85))) scale(var(--ms, 1)) rotate(calc(var(--mr) * .85)); }
  100% { opacity: 0;   transform: translate(calc(-50% + var(--mx)), calc(-50% + var(--my))) scale(calc(var(--ms, 1) * .9)) rotate(var(--mr)); }
}
@media (prefers-reduced-motion: reduce){
  .d2c-enter-prod{ animation: none; }
  .d2c-enter-visual.is-bursting .d2c-enter-prod{ animation: none; }
  .d2c-enter-mini{ display: none; }
}

/* Swipe CTA — light cream pill, red Robin-logo circle on the left that
   slides L→R on auto-play, big "Swipe to enter" prompt centered, chevron
   on the right. Matches the Figma reference for the ENTER sheet. */
.d2c-enter-swipe{
  position: relative;
  z-index: 6;
  /* Condensed length, taller height for a chunkier, more dimensional pill. */
  width: clamp(260px, 26vw, 360px);
  height: clamp(80px, 7vw, 100px);
  background: #FFFFFF;
  border-radius: 999px;
  display: flex;
  align-items: center;
  justify-content: center;
  isolation: isolate;
  /* Slight slant so the CTA sits with a touch of personality, like the
     other prize objects around it. */
  transform: rotate(-3deg);
  /* Layered shadow stack — close + mid + far blooms create real depth
     and lift the pill off the cream surface. */
  box-shadow:
    0 2px 4px rgba(0,0,0,.08),
    0 10px 22px rgba(0,0,0,.14),
    0 30px 60px rgba(0,0,0,.20),
    inset 0 1px 0 rgba(255,255,255,.9);
}
.d2c-enter-swipe-prompt{
  font-family: var(--display-font);
  font-weight: 500;
  font-size: clamp(22px, 2.2vw, 29px);
  letter-spacing: -.01em;
  pointer-events: none;
  z-index: 1;
  white-space: nowrap;
  /* Optical center — pad left so the text reads centered AROUND the handle
     (which sits at the very left of the pill). */
  padding-left: clamp(40px, 4vw, 60px);
  /* Light-shine shimmer effect (same technique as Section 2's swipe
     prompt) — gradient sweeps through the text via background-clip. */
  color: transparent;
  background: linear-gradient(90deg, #2E2220 30%, #6B6B70 50%, #2E2220 70%);
  background-size: 220% 100%;
  background-position: 100% 50%;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: d2c-enter-shine 2.8s linear infinite;
  transition: opacity .35s ease;
}
.d2c-enter-swipe-prompt strong{
  font-weight: 800;
}
@keyframes d2c-enter-shine{
  0%   { background-position: 100% 50%; }
  100% { background-position: -120% 50%; }
}
@media (prefers-reduced-motion: reduce){
  .d2c-enter-swipe-prompt{ animation: none; background-position: 50% 50%; }
}
.d2c-enter-swipe-arrow{
  position: absolute;
  right: clamp(20px, 2vw, 28px);
  top: 50%;
  transform: translateY(-50%);
  width: clamp(22px, 1.8vw, 28px);
  height: clamp(22px, 1.8vw, 28px);
  color: #2E2220;
  display: grid;
  place-items: center;
  pointer-events: none;
  z-index: 1;
}
.d2c-enter-swipe-arrow svg{ width: 100%; height: 100%; }
.d2c-enter-swipe-handle{
  position: absolute;
  top: 50%;
  /* Static inset placed via `left` so the handle clearly starts INSIDE
     the white pill. `transform` only carries the animated swipe offset
     + vertical centering. */
  left: clamp(9px, .85vw, 13px);
  --swipe-x: 0px;
  width: clamp(62px, 5.4vw, 78px);
  height: clamp(62px, 5.4vw, 78px);
  border-radius: 50%;
  background: var(--red);
  display: grid;
  place-items: center;
  transform: translate(var(--swipe-x), -50%);
  z-index: 3;
  box-shadow:
    0 3px 8px rgba(0, 0, 0, .18),
    inset 0 1px 0 rgba(255,255,255,.14);
  transition: transform .05s linear;
  will-change: transform;
}
.d2c-enter-swipe-handle img{
  width: 58%;
  height: 58%;
  object-fit: contain;
  pointer-events: none;
}
.d2c-enter-swipe-handle-icon{
  width: 58%;
  height: 58%;
  display: block;
  pointer-events: none;
}
/* The legacy PNG track is no longer used — it's removed from the DOM
   in the new markup. This rule is a defensive no-op in case anything
   else references the class. */
.d2c-enter-swipe-track{ display: none; }
.d2c-enter-swipe.is-complete .d2c-enter-swipe-prompt,
.d2c-enter-swipe.is-complete .d2c-enter-swipe-arrow{ opacity: 0; }

/* Mobile compaction — the enter sheet visual is short on small screens,
   so the stage shrinks, products downsize, the swipe button narrows, and
   burst distances reduce so cards stay visible inside the visual. */
@media (max-width: 900px){
  .d2c-enter-visual{ overflow: visible; }
  .d2c-enter-stage{ height: clamp(280px, 90vw, 400px); width: min(100%, 440px); }
  /* Mobile placements — pulled in tighter, smaller, but keeping the same
     overall composition rhythm as desktop. */
  .d2c-enter-prod--tahoe   { width: clamp(140px, 42vw, 200px); top: 22%; left: -8%; }
  .d2c-enter-prod--bag     { width: clamp(56px,  16vw, 84px);  top: 0%;  left: 24%; }
  .d2c-enter-prod--luke    { width: clamp(54px,  14vw, 80px);  top: 2%;  right: 4%; }
  .d2c-enter-prod--products{ width: clamp(58px,  16vw, 90px);  top: 30%; left: 4%; }
  .d2c-enter-prod--head    { width: clamp(74px,  20vw, 110px); top: 22%; right: -2%; }
  .d2c-enter-prod--beer    { width: clamp(54px,  14vw, 80px);  top: 60%; right: 6%; }
  .d2c-enter-prod--giftcard{ width: clamp(64px,  18vw, 100px); top: 58%; left: 14%; }
  .d2c-enter-prod--football{ width: clamp(50px,  14vw, 78px);  top: 6%;  left: 50%; }
  .d2c-enter-swipe{ width: min(86%, 320px); }
  /* Tighter burst vectors on mobile. */
  .d2c-enter-visual.is-bursting .d2c-enter-prod--tahoe   { --bx: -130px; --by: -60px; }
  .d2c-enter-visual.is-bursting .d2c-enter-prod--bag     { --bx: -90px;  --by: -110px; }
  .d2c-enter-visual.is-bursting .d2c-enter-prod--luke    { --bx:  110px; --by: -120px; }
  .d2c-enter-visual.is-bursting .d2c-enter-prod--products{ --bx: -140px; --by:  50px; }
  .d2c-enter-visual.is-bursting .d2c-enter-prod--head    { --bx:  120px; --by: -50px; }
  .d2c-enter-visual.is-bursting .d2c-enter-prod--beer    { --bx:  140px; --by:  70px; }
  .d2c-enter-visual.is-bursting .d2c-enter-prod--giftcard{ --bx: -110px; --by:  90px; }
  .d2c-enter-visual.is-bursting .d2c-enter-prod--football{ --bx:  30px;  --by: -130px; }
}

.d2c-enter-win{ display: none; }

/* TRACK — phone mock */
.d2c-phone{
  position: relative;
  margin: 0 auto;
  width: clamp(260px, 26vw, 360px);
  aspect-ratio: 9 / 19;
  background: #1a1110;
  border-radius: 42px;
  padding: 10px;
  box-shadow:
    0 36px 70px rgba(0,0,0,.25),
    inset 0 0 0 4px #2a1f1d;
}

/* TRACK card — two static "phone screenshot" images replace the prior
   video. They live INSIDE .d2c-sheet-visual (the visual grid cell),
   so neither image can ever overlap the text/CTA cell on any viewport.
   The cell has overflow:hidden + a soft top fade-out, so any image
   overflow crops cleanly at the card boundary in every layout. */
.d2c-sheet--track .d2c-sheet-visual{
  position: relative;
  overflow: hidden;
  /* Soft top fade — same mask technique as .d2c-browse-col uses to
     melt the giveaway cards into the loop boundary. Eases the top
     of the screenshot stack into the green TRACK card background
     instead of having a hard rectangular edge. */
  -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 10%, #000 100%);
          mask-image: linear-gradient(180deg, transparent 0%, #000 10%, #000 100%);
}
/* Track-card phone screenshots — DIRECT CHILDREN of .d2c-sheet--track
   (the green card), positioned absolutely with % of CARD width/height
   to exactly match the Figma design (node 2932-10005 desktop).

   Figma proportions (card 1686 × 831):
     LEFT  phone "My Entries": x=490 (29%), y=53 (6.4%), w=516 (30.6%)
                               extends past card bottom (bottom 30% crops)
     RIGHT phone "Giveaway":   x=1074 (63.7%), y=-421 (extends ABOVE),
                               w=528 (31.3%), bottom at y=725 (87% from top)

   .d2c-sheet--track has overflow:hidden + rounded corners, so any
   image overflow crops cleanly at the green card boundary. */
.d2c-track-shot{
  position: absolute;
  display: block;
  height: auto;
  pointer-events: none;
  user-select: none;
  will-change: transform;
}
/* LEFT phone — "My Entries" — anchored top-left to match Figma's
   29% from left / 6.4% from top placement. Bottom of phone extends
   past the card and crops via sheet overflow. */
.d2c-track-shot--entries{
  top: 6.4%;
  left: 29%;
  z-index: 1;
  animation: d2c-track-bob-up 6s ease-in-out infinite;
}
/* RIGHT phone — "Giveaway" — anchored from card top with NEGATIVE
   offset so the top of the phone extends above the card edge
   (matches Figma's "Re-enter swipe at bottom, top cropped"). */
.d2c-track-shot--giveaway{
  top: -50.7%;
  left: 63.7%;
  z-index: 2;
  animation: d2c-track-bob-down 7s ease-in-out -2s infinite;
}
@keyframes d2c-track-bob-up{
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-6px); }
}
@keyframes d2c-track-bob-down{
  /* opposite phase so the two cards drift independently */
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(6px); }
}
@media (prefers-reduced-motion: reduce){
  .d2c-track-shot{ animation: none !important; }
}
.d2c-phone-notch{
  position: absolute;
  top: 14px; left: 50%;
  transform: translateX(-50%);
  width: 80px; height: 22px;
  background: #0a0808;
  border-radius: 0 0 14px 14px;
  z-index: 2;
}
.d2c-phone-screen{
  position: relative;
  width: 100%; height: 100%;
  background: var(--cream);
  border-radius: 32px;
  overflow: hidden;
  padding: 32px 14px 14px;
  display: flex; flex-direction: column;
  gap: 10px;
}
.d2c-phone-status{
  display: flex; align-items: center; justify-content: space-between;
  font-family: var(--display-font);
  font-size: 10px;
  font-weight: 700;
  color: var(--ink);
  padding: 0 4px;
}
.d2c-phone-brand{
  background: var(--red);
  color: #fff;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 9px;
  letter-spacing: .08em;
}
.d2c-phone-h{
  margin: 0;
  font-family: var(--headline-font);
  font-weight: 700;
  font-size: clamp(20px, 2vw, 28px);
  letter-spacing: -.02em;
  color: var(--ink);
  padding: 0 4px;
}
.d2c-phone-chips{
  display: flex; gap: 5px; flex-wrap: nowrap;
  padding: 0 4px;
  overflow: hidden;
}
.d2c-phone-chip{
  background: #fff;
  border-radius: 999px;
  padding: 5px 10px;
  font-family: var(--display-font);
  font-weight: 700;
  font-size: 9.5px;
  color: var(--ink);
  white-space: nowrap;
  box-shadow: 0 1px 0 rgba(0,0,0,.06);
  display: inline-flex; align-items: center; gap: 4px;
}
.d2c-phone-chip em{
  display: inline-grid; place-items: center;
  width: 14px; height: 14px;
  border-radius: 50%;
  background: var(--red);
  color: #fff;
  font-style: normal;
  font-size: 8px;
}
.d2c-phone-chip.is-active{ background: #FFE57A; }
.d2c-phone-grid{
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
  flex: 1;
  padding: 0 4px;
}
.d2c-phone-card{
  border-radius: 12px;
  aspect-ratio: 3 / 4;
  display: flex; align-items: flex-end; justify-content: space-between;
  padding: 8px;
  font-family: var(--display-font);
  font-weight: 800;
  font-size: 10px;
  color: #fff;
  line-height: 1.05;
  text-shadow: 0 1px 2px rgba(0,0,0,.4);
  position: relative; overflow: hidden;
  box-shadow: inset 0 -10px 20px rgba(0,0,0,.18);
}
.d2c-phone-card span:not(.d2c-phone-card-chip){
  position: relative; z-index: 2;
  flex: 1;
}
.d2c-phone-card-chip{
  position: absolute;
  top: 6px; left: 6px;
  padding: 2px 6px;
  font-size: 7.5px;
  font-weight: 800;
  letter-spacing: .04em;
  background: rgba(255,255,255,.92);
  color: var(--ink);
  border-radius: 999px;
  text-shadow: none;
  z-index: 3;
}
.d2c-phone-card--1{ background: linear-gradient(160deg, #b9e84d 0%, #6cb13a 100%); color: #14290a; text-shadow: none; }
.d2c-phone-card--2{ background: linear-gradient(160deg, #f58e2f 0%, #c44d12 100%); }
.d2c-phone-card--3{ background: linear-gradient(160deg, #f82623 0%, #a8170a 100%); }
.d2c-phone-card--4{ background: linear-gradient(160deg, #5BA4F4 0%, #2876c8 100%); }

/* ============ PRIZES — Brand carousel ============ */
.d2c-prizes{
  /* Background inherited from Section 4 cream wrapper. */
  padding: clamp(96px, 10vw, 180px) 0 clamp(64px, 7vw, 120px);
  text-align: center;
  overflow: hidden;
}
/* Title matches B2B's "One campaign. / One vendor." sizing (display-xxl) */
.d2c-prizes-title{
  margin: 0 auto;
  font-family: var(--headline-font);
  font-weight: 700;
  font-size: clamp(40px, 6.2vw, 92px);   /* same as B2B display-xxl */
  line-height: .94;
  letter-spacing: -.03em;
  color: #2E2220;
}
/* Subtext — SF Pro Rounded SemiBold (var(--body-font) = SF Pro Rounded,
   weight 600). Spacing mirrors B2B's `.solution-inner .lead-light`: 28px
   above the subtext. */
.d2c-prizes-lead{
  margin: 28px auto clamp(48px, 5vw, 80px);
  max-width: 56ch;
  color: #2E2220;
}
/* All prize tile labels → #2E2220 */
body.d2c .d2c-btile,
body.d2c .d2c-btile-name,
body.d2c .d2c-btile-label{
  color: #2E2220;
}
/* D2C FAQ text reverted — inherits all typography (font-family, weight,
   size, alignment, color) from the shared B2B `.faq-*` rules so the
   section matches the brand side. */

/* ===== Seamless Figma-export brand strip =====
   Two copies of _brand_carousel.png laid side-by-side. The track translates
   by exactly -50% so the second copy's leading edge slides into the first
   copy's leading edge with zero visual discontinuity. */
.d2c-brand-strip{
  position: relative;
  overflow: hidden;
  width: 100%;
  padding: 8px 0;
  /* Edge fade so the loop edges blur softly rather than pop */
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 6%, #000 94%, transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 6%, #000 94%, transparent 100%);
}
.d2c-brand-strip-track{
  display: flex;
  /* Wrap-gap matches the Figma proportion 18 / 2926 ≈ 0.615 % of image
     rendered width. The brand image renders ~4378 px wide at 1440 viewport
     and ~5836 px at 1920, so the proportional gap is ~27 px → ~36 px
     respectively. clamp() tracks it. The keyframe subtracts half this gap
     so the second copy lands where the first started, keeping the loop
     seamless with the spec'd breathing space at the wrap point. */
  --strip-gap: clamp(16px, 1.87vw, 40px);
  gap: var(--strip-gap);
  width: max-content;
  animation: d2c-brand-strip-roll 55s linear infinite;
  will-change: transform;
}
.d2c-brand-strip-img{
  display: block;
  /* Sized so ~5.85 Figma containers fit across the viewport at any width.
     Figma reference: each container = 292.99 px on a 1920 page → 18 tiles
     per image copy (21524 / 1196 native per tile). Per-tile rendered width
     should equal `viewport_width / 5.85`. With image aspect ~7.601:1 and
     N=18, the required image height is `(N / (5.85 × 7.601)) × viewport_width
     ≈ 40 vw`. */
  height: clamp(300px, 40vw, 780px);
  width: auto;
  /* Reserve layout width from the native aspect ratio BEFORE the PNG
     decodes. Without this, `width: auto` resolves to 0 on a still-
     undecoded <img>, the flex track collapses to 0 wide, and the
     keyframe translate has nothing to scroll — the carousel renders
     blank and motionless. With aspect-ratio the browser computes
     width = height × (21524/2832) immediately at layout time. */
  aspect-ratio: 21524 / 2832;
  flex-shrink: 0;
  user-select: none;
  pointer-events: none;
}
@keyframes d2c-brand-strip-roll{
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(calc(-50% - var(--strip-gap) / 2), 0, 0); }
}
@media (prefers-reduced-motion: reduce){
  .d2c-brand-strip-track{ animation: none; }
}

/* (Legacy text-tile marquee below — kept for back-compat but unused.) */
.d2c-brand-marquee{
  position: relative;
  overflow: hidden;
  padding: 8px 0;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 8%, #000 92%, transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 8%, #000 92%, transparent 100%);
}
.d2c-brand-marquee + .d2c-brand-marquee{
  margin-top: 14px;
}
.d2c-brand-track{
  display: flex;
  width: max-content;
  gap: 0;
  animation: d2c-marquee 60s linear infinite;
}
.d2c-brand-marquee--reverse .d2c-brand-track{
  animation-direction: reverse;
  animation-duration: 75s;
}
.d2c-brand-row{
  display: flex;
  gap: 14px;
  padding-right: 14px;
  flex-shrink: 0;
}
@keyframes d2c-marquee{
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }
}
.d2c-brand-marquee:hover .d2c-brand-track{ animation-play-state: paused; }

.d2c-btile{
  flex: 0 0 auto;
  width: clamp(96px, 9vw, 132px);
  aspect-ratio: 1.05 / 1;
  background: #fff;
  border-radius: 18px;
  display: grid; place-items: center;
  font-family: var(--display-font);
  font-weight: 700;
  font-size: clamp(11px, 1vw, 14px);
  color: var(--ink);
  letter-spacing: -.005em;
  padding: 8px;
  text-align: center;
  box-shadow:
    0 4px 12px rgba(0,0,0,.06),
    inset 0 0 0 1px rgba(0,0,0,.04);
  transition: transform .35s cubic-bezier(.2,.7,.2,1), box-shadow .35s ease;
}
.d2c-btile:hover{
  transform: translateY(-3px) scale(1.03);
  box-shadow:
    0 14px 28px rgba(0,0,0,.12),
    inset 0 0 0 1px rgba(0,0,0,.06);
}

/* ============ COMMUNITY (cream container; red CTA ribbon inside) ============ */
.d2c-community{
  /* Sits inside Section 4 cream wrapper. */
  color: var(--ink);
  padding: clamp(64px, 7vw, 120px) clamp(20px, 4vw, 64px) clamp(96px, 12vw, 180px);
  text-align: center;
  position: relative;
  overflow: hidden;
  isolation: isolate;
}
.d2c-community-inner{
  max-width: var(--maxw);
  margin: 0 auto;
  position: relative;
}
/* Hero text matches B2B's "One campaign. / One vendor." — display-xxl.
   text-transform: none so the heading renders EXACTLY as written in
   HTML ("Community built on winning.") — not forced uppercase. */
.d2c-community-title{
  margin: 0 auto;
  font-family: var(--headline-font);
  font-weight: 700;
  font-size: clamp(40px, 6.2vw, 92px);
  line-height: .94;
  letter-spacing: -.03em;
  color: var(--ink);
  text-transform: none;
}
/* Subtext — SF Pro Rounded SemiBold, 28 px above per B2B spacing */
.d2c-community-lead{
  margin: 28px auto clamp(64px, 6vw, 100px);
  max-width: 60ch;
  font-family: var(--body-font);
  font-weight: 600;
  font-size: clamp(16px, 1.3vw, 22px);
  line-height: 1.55;
  color: #3a2e2b;
}

/* Two phones */
.d2c-community-phones{
  display: flex; justify-content: center;
  gap: clamp(20px, 3vw, 64px);
  margin-bottom: clamp(64px, 7vw, 120px);
  flex-wrap: wrap;
  perspective: 1600px;
}
.d2c-cphone{
  position: relative;
  width: clamp(240px, 24vw, 340px);
  aspect-ratio: 9 / 19;
  background: #1a1110;
  border-radius: 42px;
  padding: 10px;
  box-shadow: 0 32px 64px rgba(0,0,0,.25);
}
/* Phone variant that uses a full UI screenshot (Figma export of Robin's app screen) */
.d2c-cphone--asset{
  padding: 8px;
  overflow: hidden;
}
.d2c-cphone-screenshot{
  width: 100%; height: 100%;
  display: block;
  border-radius: 34px;
  object-fit: cover;
  object-position: top center;
}
.d2c-cphone .d2c-phone-notch{
  top: 14px;
  background: #0a0808;
}
.d2c-cphone-screen{
  position: relative;
  width: 100%; height: 100%;
  background: #fff;
  border-radius: 32px;
  padding: 36px 14px 18px;
  display: flex; flex-direction: column;
  gap: 8px;
  overflow: hidden;
}
.d2c-cphone-screen--red{ background: var(--red); color: #fff; }

/* Profile phone */
.d2c-cphone-statusbar{
  display: flex; justify-content: space-between; align-items: center;
  padding: 0 6px;
  font-family: var(--display-font);
  font-weight: 700;
  font-size: 10px;
  color: var(--ink);
}
.d2c-cphone-statusbar--light{ color: #fff; }
.d2c-cphone-icons{ display: inline-flex; align-items: center; gap: 4px; }
.d2c-cphone-toprow{
  display: flex; justify-content: flex-end;
  padding: 0 6px;
}
.d2c-cphone-iconbtn{
  display: inline-grid; place-items: center;
  width: 22px; height: 22px;
  border-radius: 50%;
  color: var(--muted);
}
.d2c-cphone-avatar{
  position: relative;
  margin: 0 auto 6px;
  width: 64px; height: 64px;
  border-radius: 50%;
  border: 3px solid #fff;
  overflow: hidden;
  background: #f4ead7;
  display: grid; place-items: center;
  z-index: 2;
  box-shadow: 0 4px 12px rgba(0,0,0,.08);
}
.d2c-cphone-avatar svg{ width: 100%; height: 100%; }
.d2c-cphone-check{
  display: inline-grid; place-items: center;
  width: 12px; height: 12px;
  border-radius: 50%;
  background: var(--blue);
  color: #fff;
  font-size: 8px;
  font-weight: 800;
  margin-left: 4px;
  vertical-align: 1px;
}
.d2c-cphone-badge{
  display: inline-flex; align-items: center; gap: 4px;
  margin: 8px auto;
  padding: 4px 10px;
  font-family: var(--display-font);
  font-weight: 800;
  font-size: 9.5px;
  background: #f4ead7;
  color: var(--ink);
  border-radius: 999px;
}
.d2c-cphone-crown{ font-size: 9px; }
.d2c-cphone-meta{
  margin: 4px 0 8px;
  text-align: center;
  font-family: var(--display-font);
  font-weight: 700;
  font-size: 9px;
  letter-spacing: -.002em;
  color: var(--muted);
}
.d2c-cphone-pillrow{
  display: flex; gap: 4px;
  padding: 0 6px;
  overflow: hidden;
  margin-bottom: 6px;
}
.d2c-cphone-pill{
  flex: 1; text-align: center;
  padding: 4px 6px;
  border-radius: 999px;
  background: #f4ead7;
  font-family: var(--display-font);
  font-weight: 800;
  font-size: 8.5px;
  color: var(--ink);
  white-space: nowrap;
}
.d2c-cphone-pill.is-active{ background: var(--red); color: #fff; }

.d2c-cphone-tile{
  display: flex; align-items: flex-end;
  padding: 8px;
  color: #fff;
  font-family: var(--display-font);
  font-weight: 800;
  font-size: 9px;
  line-height: 1.05;
  text-shadow: 0 1px 2px rgba(0,0,0,.4);
}
.d2c-cphone-tile--blue{
  background: linear-gradient(160deg, #5BA4F4 0%, #2876c8 100%);
  text-shadow: none;
  color: #fff;
}
.d2c-cphone-tile--red{
  background: linear-gradient(160deg, #F82623 0%, #8a1d0d 100%);
}
.d2c-cphone-name{
  margin: 0;
  text-align: center;
  font-family: var(--display-font);
  font-weight: 800;
  font-size: 13px;
  color: var(--ink);
}
.d2c-cphone-sub{
  margin: 0;
  text-align: center;
  font-size: 11px;
  color: var(--muted);
}
.d2c-cphone-stats{
  display: flex; gap: 10px; justify-content: center;
  margin: 10px 0;
  font-family: var(--display-font);
  font-size: 9.5px;
  color: var(--ink);
}
.d2c-cphone-stats strong{ display: block; font-size: 12px; font-weight: 800; }
.d2c-cphone-btn{
  align-self: center;
  background: #efe7da;
  color: var(--ink);
  border: 0;
  border-radius: 999px;
  padding: 6px 14px;
  font-family: var(--display-font);
  font-weight: 700;
  font-size: 10px;
  cursor: pointer;
}
.d2c-cphone-tabs{
  display: flex; gap: 6px;
  margin: 10px 0 6px;
  padding: 0 4px;
}
.d2c-cphone-tabs span{
  flex: 1; text-align: center;
  font-family: var(--display-font);
  font-weight: 700;
  font-size: 9px;
  color: var(--muted);
  padding: 5px 0;
  border-radius: 6px;
}
.d2c-cphone-tabs .is-active{
  background: #f4ead7;
  color: var(--ink);
}
.d2c-cphone-grid{
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 5px;
  flex: 1;
  padding: 0 4px;
}
.d2c-cphone-tile{
  border-radius: 10px;
  background: var(--skin-1);
  box-shadow: inset 0 -8px 16px rgba(0,0,0,.12);
}
.d2c-cphone-tile.d2c-skin-2{ background: var(--skin-2); }
.d2c-cphone-tile.d2c-skin-3{ background: var(--skin-3); }

/* Streak phone */
.d2c-cphone-streakrow{
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px;
  padding: 6px 12px 4px;
}
.d2c-cphone-eyebrow{
  margin: 0;
  text-align: center;
  font-family: var(--display-font);
  font-weight: 700;
  font-size: 10px;
  letter-spacing: .14em;
  text-transform: uppercase;
  opacity: .78;
}
.d2c-cphone-day{
  margin: 0;
  font-family: var(--headline-font);
  font-weight: 700;
  font-size: 52px;
  line-height: .88;
  letter-spacing: -.025em;
}
.d2c-cphone-daysub{
  margin: 4px 0 0;
  font-family: var(--display-font);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .04em;
  opacity: .92;
}
.d2c-cphone-gem{
  display: inline-grid; place-items: center;
  width: 60px; height: 60px;
  flex-shrink: 0;
}
.d2c-cphone-tabs--dark{ padding: 0 12px; margin-top: 6px; }
.d2c-cphone-tabs--dark span{
  flex: 1; text-align: center;
  font-size: 8.5px; font-weight: 800;
  padding: 4px 0;
  border-radius: 4px;
  color: rgba(255,255,255,.6);
}
.d2c-cphone-tabs--dark .is-active{
  color: #fff;
  border-bottom: 2px solid #fff;
  border-radius: 0;
}
.d2c-cphone-tabs--pill{ padding: 0 12px; margin: 6px 0 4px; }
.d2c-cphone-tabs--pill span{
  flex: 1; text-align: center;
  padding: 4px 0;
  border-radius: 999px;
  font-size: 9px; font-weight: 800;
  color: rgba(255,255,255,.6);
  background: transparent;
}
.d2c-cphone-tabs--pill .is-active{
  background: rgba(255,255,255,.18);
  color: #fff;
}
.d2c-cphone-me{
  display: flex; align-items: center; gap: 8px;
  margin: 0 12px 6px;
  padding: 6px 12px;
  background: rgba(255,255,255,.18);
  border-radius: 999px;
  font-family: var(--display-font);
  font-size: 9.5px;
  font-weight: 800;
}
.d2c-cphone-rank{
  display: inline-grid; place-items: center;
  flex-shrink: 0;
  width: 18px; opacity: .92;
}
.d2c-cphone-avi{
  display: inline-block;
  flex-shrink: 0;
  width: 18px; height: 18px;
  border-radius: 50%;
  background: linear-gradient(160deg, #FFC744 0%, #F58E2F 100%);
  border: 1px solid rgba(255,255,255,.4);
}
.d2c-cphone-handle{ flex: 1; }
.d2c-cphone-days{
  font-size: 9px; font-weight: 700; opacity: .85;
  flex-shrink: 0;
}
.d2c-cphone-lead{
  margin: 0 12px 14px;
  text-align: center;
  font-size: 10.5px;
  font-weight: 600;
  line-height: 1.4;
  opacity: .92;
}
.d2c-cphone-list{
  list-style: none; margin: 0 12px; padding: 0;
  display: flex; flex-direction: column; gap: 4px;
  font-family: var(--display-font);
  font-size: 9.5px;
  font-weight: 800;
}
.d2c-cphone-list li{
  display: flex; align-items: center; gap: 8px;
  padding: 6px 10px;
  border-radius: 999px;
}
.d2c-cphone-list li > span:nth-child(3){ flex: 1; }
.d2c-cphone-list strong{ font-weight: 800; }
.d2c-cphone-list em{ font-style: normal; opacity: .8; font-size: 8.5px; font-weight: 700; }

/* Brown CTA ribbon — title + subtext at TOP, Win-Category + button
   at BOTTOM-LEFT, phone wires overhanging BOTTOM-RIGHT. */
.d2c-community-cta{
  position: relative;
  background: #2E2220;
  border-radius: clamp(28px, 3vw, 48px);
  padding: clamp(56px, 6vw, 110px) clamp(36px, 4vw, 72px) clamp(80px, 8vw, 160px);
  display: flex;
  flex-direction: column;
  gap: clamp(16px, 2vw, 32px);
  color: #fff;
  text-align: left;
  box-shadow: 0 30px 60px rgba(0,0,0,.16);
  overflow: visible;
}
/* TOP row: title + subtext, centered, white on brown */
.d2c-community-cta-top{
  text-align: center;
  max-width: 1000px;
  margin: 0 auto;
  width: 100%;
}
.d2c-community-cta-top .d2c-community-title{
  color: #ffffff;
}
.d2c-community-cta-top .d2c-community-lead{
  color: rgba(255,255,255,0.85);
  margin: 24px auto 0;
}
/* BOTTOM row: Win-Category text on the left; wireframes are absolutely
   positioned so they DON'T inflate the row height — that way the row is
   only as tall as the Win headline + button, and the gap between the
   header above and the next visible content stays tight. Wireframes
   overhang the bottom of the brown box via translateY (see mocks rules). */
.d2c-community-cta-body{
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  align-items: start;
  gap: clamp(24px, 3vw, 56px);
  min-height: clamp(320px, 33vw, 480px);
}
.d2c-community-cta-text{
  position: relative;
  z-index: 2;
  align-self: end;
}
.d2c-community-cta h3,
.d2c-typewriter-headline{
  margin: 0 0 clamp(22px, 2.4vw, 36px);
  font-family: var(--display-font);
  font-weight: 800;
  font-size: clamp(32px, 3.8vw, 60px);
  letter-spacing: -.025em;
  line-height: 1.02;
  color: #fff;
  text-transform: none;
}
/* Typewriter — period sits right after the last character regardless of
   word length. No min-width on .d2c-tw-word so it sizes to content. */
.d2c-tw-word{
  display: inline;
  text-align: left;
  white-space: nowrap;
}

/* Phone-frame wires — anchored to the BOTTOM of the brown community
   CTA, then nudged DOWN with translateY so they hang past the
   container's bottom edge. Sized smaller than the previous scaled-up
   version but bigger than the original. */
.d2c-community-mocks{
  position: absolute;
  top: 0;
  right: 0;
  display: flex;
  align-items: flex-start;
  justify-content: flex-end;
  gap: clamp(12px, 2vw, 32px);
  pointer-events: none;
}
/* Each mock <img> is now wrapped in a <picture> (for mobile source-
   switching). display:contents removes the wrapper from layout so
   the parent flex still treats the <img> as its direct child —
   preserves the existing gap/alignment/transform behavior exactly. */
.d2c-community-mocks picture{
  display: contents;
}
.d2c-community-mock{
  display: block;
  width: clamp(180px, 20vw, 300px);
  height: auto;
  filter: drop-shadow(0 24px 40px rgba(0,0,0,.22));
  user-select: none;
  pointer-events: none;
}
/* translateY pulls each mock DOWN past the container's bottom edge.
   Profile slightly higher than Discover for the staggered look.
   Both lowered by +50 px per QA so Discover (right) hangs further off. */
.d2c-community-mock--1{ transform: translateY(clamp(40px, 4vw, 70px)); }
.d2c-community-mock--2{ transform: translateY(clamp(60px, 6vw, 100px)); }

/* Community CTA button inherits all visuals from the shared B2B .btn. */

/* Typewriter — color rotates per-word via JS-set --tw-color */
.d2c-typewriter{
  display: inline;
  position: relative;
  color: var(--tw-color, #CBE3FF);
  transition: color .42s ease;
}
/* (the .d2c-tw-word inline + no-min-width is set above near the cta block) */
.d2c-tw-caret{
  display: inline-block;
  width: 4px;
  height: .82em;
  background: var(--tw-color, #CBE3FF);
  margin-left: 4px;
  vertical-align: -2px;
  animation: d2c-caret-blink .9s steps(2) infinite;
  transition: background .42s ease;
}
@keyframes d2c-caret-blink{
  0%, 49% { opacity: 1; }
  50%, 100% { opacity: 0; }
}
@media (prefers-reduced-motion: reduce){
  .d2c-tw-caret{ animation: none; opacity: .8; }
}

/* ============ FEATURES CAROUSEL — red 3D-style ============
   Bright red section, 5 phone-screenshot cards fanning out left/right
   around the active center card. Auto-rotates; arrows advance instantly.
   Cards use CSS transitions on transform/opacity; JS only sets
   data-offset on each card so layout lives in CSS. */
.d2c-features{
  background: #ff2020;
  color: #fff;
  padding: clamp(96px, 11vw, 180px) clamp(20px, 4vw, 64px) clamp(96px, 11vw, 180px);
  text-align: center;
  position: relative;
  overflow: hidden;
}
.d2c-features-inner{
  max-width: var(--maxw);
  margin: 0 auto;
}
.d2c-features-title{
  margin: 0;
  font-family: var(--headline-font);
  font-weight: 700;
  font-size: clamp(40px, 6.2vw, 92px);
  line-height: .94;
  letter-spacing: -.03em;
  color: #fff;
  /* text-transform: none so the heading renders EXACTLY as written in
     HTML ("Your giveaway control center.") — not forced uppercase. */
  text-transform: none;
}
.d2c-features-lead{
  margin: 20px auto clamp(8px, 1vw, 18px);
  max-width: 56ch;
  font-family: var(--body-font);
  font-weight: 600;
  font-size: clamp(16px, 1.3vw, 22px);
  line-height: 1.55;
  color: rgba(255,255,255,0.92);
}

.d2c-carousel{
  position: relative;
  width: 100%;
  /* Bumped back out so the arrows clear the rotated outer card by ~30px
     on desktop — close enough to feel connected, not overlapping. */
  max-width: 1160px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(20px, 3vw, 56px);
}
.d2c-carousel-stage{
  position: relative;
  flex: 1 1 auto;
  height: clamp(220px, 24vw, 320px);
  perspective: 1400px;
  overflow: visible;
}
.d2c-carousel-track{
  position: absolute;
  inset: 0;
  /* Preserve 3D so the cards' translateZ depth + rotateY produce true
     perspective depth rather than collapsing flat. */
  transform-style: preserve-3d;
}
.d2c-carousel-card{
  position: absolute;
  top: 50%;
  left: 50%;
  width: clamp(140px, 15vw, 220px);
  aspect-ratio: 7 / 8;
  transform: translate(-50%, -50%) scale(.4);
  transform-origin: 50% 50%;
  /* Preserve 3D so child rotateY actually feels like depth, not a flat
     skew. transform-style on the card itself isn't strictly needed but
     the stage already sets perspective; we lock backface for cleanliness. */
  backface-visibility: hidden;
  opacity: 0;
  z-index: 1;
  will-change: transform, opacity;
  /* Single duration + easing across all animatable properties so they
     finish in step — eliminates the "different parts arriving at
     different times" judder that read as glitchy. */
  transition:
    transform 1.4s cubic-bezier(.22, .6, .25, 1),
    opacity 1.4s cubic-bezier(.22, .6, .25, 1),
    filter 1.4s cubic-bezier(.22, .6, .25, 1);
  pointer-events: none;
}
.d2c-carousel-card img{
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  -webkit-user-drag: none;
  user-select: none;
  /* Drop-shadow removed — the PNGs already have their own designed
     drop-shadow baked in, so adding a CSS one on top traced the alpha
     edges and produced a weird halo around the card silhouette. */
}
/* Active center card — flat to camera, full scale. No bounce animation
   (the per-card transition + 3D rotateY of the neighbors gives the
   sense of motion; bouncing the center on every cycle made the swap
   feel jittery). */
.d2c-carousel-card[data-offset="0"]{
  transform: translate(-50%, -50%) scale(1) rotateY(0deg);
  opacity: 1;
  z-index: 50;
}
/* Neighbors and outer pair use rotateY so they appear to rotate away
   from the camera — combined with the stage's perspective:1400px this
   reads as true 3D depth, not a flat 2D rotation. translateZ pulls
   them back slightly so they sit behind the active card cleanly. */
.d2c-carousel-card[data-offset="1"]{
  transform: translate(calc(-50% + clamp(125px, 15vw, 220px)), -50%) translateZ(-80px) rotateY(-22deg) scale(.94);
  opacity: 1;
  z-index: 30;
}
.d2c-carousel-card[data-offset="-1"]{
  transform: translate(calc(-50% - clamp(125px, 15vw, 220px)), -50%) translateZ(-80px) rotateY(22deg) scale(.94);
  opacity: 1;
  z-index: 30;
}
.d2c-carousel-card[data-offset="2"]{
  transform: translate(calc(-50% + clamp(225px, 26vw, 390px)), -50%) translateZ(-180px) rotateY(-32deg) scale(.86);
  opacity: .85;
  z-index: 10;
}
.d2c-carousel-card[data-offset="-2"]{
  transform: translate(calc(-50% - clamp(225px, 26vw, 390px)), -50%) translateZ(-180px) rotateY(32deg) scale(.86);
  opacity: .85;
  z-index: 10;
}
/* Anything further out fades */
.d2c-carousel-card[data-offset="3"],
.d2c-carousel-card[data-offset="-3"],
.d2c-carousel-card[data-offset="4"],
.d2c-carousel-card[data-offset="-4"]{
  opacity: 0;
  z-index: 1;
}

/* Active card title + body — sits below the carousel, swaps as the
   active card changes. Min-height keeps the layout from jumping when
   the body text length varies between cards. */
.d2c-carousel-caption{
  margin: clamp(0px, .3vw, 6px) auto 0;
  max-width: 52ch;
  padding: 0 16px;
  text-align: center;
  color: #fff;
  min-height: clamp(120px, 12vw, 160px);
}
.d2c-carousel-caption-title{
  margin: 0 0 8px;
  font-family: var(--display-font);
  font-weight: 800;
  font-size: clamp(24px, 2.6vw, 40px);
  letter-spacing: -.01em;
  line-height: 1.05;
  color: #fff;
  transition: opacity .35s ease, transform .45s cubic-bezier(.2,.7,.2,1);
}
.d2c-carousel-caption-body{
  margin: 0 auto;
  /* Cap to a width that produces exactly 2 lines on every feature card.
     Combined with the line-clamp below this also guarantees the height
     stays consistent as captions swap. */
  max-width: 38ch;
  font-family: var(--body-font);
  font-weight: 500;
  font-size: clamp(15px, 1.25vw, 19px);
  line-height: 1.55;
  color: rgba(255,255,255,.92);
  transition: opacity .35s ease, transform .45s cubic-bezier(.2,.7,.2,1);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  min-height: calc(2 * 1.55em);
}
.d2c-carousel-caption.is-swap-out .d2c-carousel-caption-title,
.d2c-carousel-caption.is-swap-out .d2c-carousel-caption-body{
  opacity: 0;
  transform: translateY(8px);
}
@media (prefers-reduced-motion: reduce){
  .d2c-carousel-caption-title,
  .d2c-carousel-caption-body{ transition: none; }
}

/* Soft pink arrow buttons */
.d2c-carousel-arrow{
  flex: 0 0 auto;
  width: clamp(48px, 5vw, 64px);
  height: clamp(48px, 5vw, 64px);
  border-radius: 50%;
  background: #FFD1D1;
  border: 0;
  color: #0a0808;
  display: grid;
  place-items: center;
  cursor: pointer;
  z-index: 60;
  box-shadow: 0 10px 24px rgba(0,0,0,.18);
  transition: transform .25s ease, background .25s ease, box-shadow .25s ease;
}
.d2c-carousel-arrow svg{
  width: 42%;
  height: 42%;
}
.d2c-carousel-arrow:hover{
  background: #FFE3E3;
  transform: scale(1.08);
  box-shadow: 0 14px 28px rgba(0,0,0,.22);
}
.d2c-carousel-arrow:active{
  transform: scale(.94);
}
.d2c-carousel-arrow:focus-visible{
  outline: 3px solid #fff;
  outline-offset: 3px;
}

@media (max-width: 900px){
  .d2c-features{ padding: clamp(72px, 12vw, 120px) clamp(16px, 4vw, 32px); }
  .d2c-features-title{ font-size: clamp(36px, 9vw, 64px); }
  .d2c-carousel-stage{ height: clamp(320px, 60vw, 460px); }
  .d2c-carousel-card{ width: clamp(190px, 48vw, 280px); }
  .d2c-carousel-card[data-offset="1"]{
    transform: translate(calc(-50% + clamp(110px, 28vw, 200px)), -50%) scale(.74) rotate(7deg);
  }
  .d2c-carousel-card[data-offset="-1"]{
    transform: translate(calc(-50% - clamp(110px, 28vw, 200px)), -50%) scale(.74) rotate(-7deg);
  }
  .d2c-carousel-card[data-offset="2"]{
    transform: translate(calc(-50% + clamp(180px, 44vw, 320px)), -50%) scale(.54) rotate(11deg);
    opacity: .7;
  }
  .d2c-carousel-card[data-offset="-2"]{
    transform: translate(calc(-50% - clamp(180px, 44vw, 320px)), -50%) scale(.54) rotate(-11deg);
    opacity: .7;
  }
}
@media (max-width: 560px){
  .d2c-carousel{ gap: 8px; }
  .d2c-carousel-arrow{ width: 44px; height: 44px; }
}
@media (prefers-reduced-motion: reduce){
  .d2c-carousel-card{ transition: opacity .3s ease; }
}

/* ============ FAQ — sits inside Section 5 (white) ============ */
/* No bg override — Section 5 wrapper provides the #fff background. */

/* ============ FINAL CTA — Start your winning streak (inside Section 6 red) ============ */
/* ============ FINAL CTA — matches Figma reference ============
   Section 6 already provides the red bleed; the CTA card is transparent
   so the red flows continuously into the footer below. */
.d2c-cta{
  background: transparent;
  padding: clamp(64px, 8vw, 140px) clamp(20px, 3vw, 56px) clamp(48px, 5vw, 96px);
}
.d2c-cta-card{
  position: relative;
  max-width: var(--maxw);
  margin: 0 auto;
  /* Transparent — red parent shows through. */
  background: transparent;
  padding: clamp(48px, 6vw, 96px) clamp(20px, 3vw, 56px);
  color: #fff;
  text-align: center;
  isolation: isolate;
  overflow: visible;
}
/* Confetti / gems backdrop — full bleed inside the card, lower z so
   text and CTA sit above it. */
.d2c-cta-bg{
  position: absolute;
  inset: -20% -5%;
  width: 110%;
  height: 140%;
  object-fit: cover;
  object-position: center;
  z-index: 0;
  pointer-events: none;
  user-select: none;
  opacity: .9;
}
.d2c-cta-inner{
  position: relative;
  z-index: 3;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(28px, 3vw, 48px);
}
.d2c-cta-h{
  margin: 0;
  font-family: var(--headline-font);
  font-weight: 700;
  font-size: clamp(56px, 7.4vw, 132px);
  line-height: .9;
  letter-spacing: -.03em;
  color: #fff;
  text-transform: uppercase;
  text-shadow: 0 4px 0 rgba(0,0,0,.08);
}
/* CTA button now inherits everything (size, gradient, hover) from the
   universal .btn + .btn-light styles in styles.css. */
.d2c-cta-btn{ margin: 0; }

/* Foot line: BROWSE, ENTER, TRACK [mascot] AND WIN BIG */
.d2c-cta-foot{
  margin: clamp(12px, 1.5vw, 24px) 0 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: clamp(8px, 1vw, 16px);
  font-family: var(--display-font);
  font-weight: 800;
  font-size: clamp(13px, 1vw, 17px);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: #fff;
}
.d2c-cta-foot-text{ white-space: nowrap; }
.d2c-cta-foot-mascot{
  display: inline-flex; align-items: center; justify-content: center;
  width: clamp(48px, 5vw, 76px);
  height: auto;
}
.d2c-cta-foot-mascot img{
  width: 100%; height: auto; display: block;
  filter: drop-shadow(0 6px 12px rgba(0,0,0,.25));
}

/* 4 sweep cards — 2 left, 2 right. Each PAIR has one card fully visible
   and one that crops past the outer edge for the cinematic feel. */
.d2c-cta-cards{
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 1;
}
.d2c-cta-card-img{
  position: absolute;
  width: clamp(150px, 18vw, 280px);
  height: auto;
  border-radius: clamp(16px, 1.4vw, 22px);
  box-shadow: 0 28px 56px rgba(0,0,0,.28);
  user-select: none;
  -webkit-user-drag: none;
}
/* LEFT pair — outer (cropped) + inner (fully visible) */
.d2c-cta-card-img--l1{
  left: -8%;
  top: 18%;
  transform: rotate(-8deg);
  width: clamp(140px, 16vw, 240px);
  opacity: .92;
}
.d2c-cta-card-img--l2{
  left: 8%;
  top: 30%;
  transform: rotate(-4deg);
}
/* RIGHT pair — inner (fully visible) + outer (cropped) */
.d2c-cta-card-img--r1{
  right: 8%;
  top: 24%;
  transform: rotate(6deg);
}
.d2c-cta-card-img--r2{
  right: -8%;
  top: 14%;
  transform: rotate(10deg);
  width: clamp(140px, 16vw, 240px);
  opacity: .92;
}
@media (max-width: 900px){
  .d2c-cta-card-img--l1,
  .d2c-cta-card-img--r2{ display: none; }
  .d2c-cta-card-img--l2{ left: -2%; top: 6%; }
  .d2c-cta-card-img--r1{ right: -2%; top: 6%; }
  .d2c-cta-card-img{ width: clamp(110px, 22vw, 160px); }
}
@media (max-width: 560px){
  .d2c-cta-cards{ display: none; }
  .d2c-cta-bg{ opacity: .7; }
}

/* ============ APP-ACCESS POPUP ============ */
.d2c-popup{
  position: fixed;
  inset: 0;
  z-index: 200;
  display: grid; place-items: center;
  padding: 20px;
  pointer-events: none;
  opacity: 0;
  transition: opacity .35s cubic-bezier(.2,.7,.2,1);
}
.d2c-popup.is-open{
  opacity: 1;
  pointer-events: auto;
}
.d2c-popup-backdrop{
  position: absolute; inset: 0;
  background: rgba(20, 12, 10, .55);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}
.d2c-popup-card{
  position: relative;
  z-index: 2;
  width: min(440px, 100%);
  background: #fff;
  border-radius: 28px;
  padding: 36px 32px 28px;
  text-align: center;
  box-shadow:
    0 60px 120px rgba(0,0,0,.36),
    0 4px 12px rgba(0,0,0,.16);
  transform: translateY(20px) scale(.96);
  transition: transform .45s cubic-bezier(.2,.7,.2,1);
}
.d2c-popup.is-open .d2c-popup-card{
  transform: translateY(0) scale(1);
}
.d2c-popup-close{
  position: absolute;
  top: 14px; right: 14px;
  width: 36px; height: 36px;
  border-radius: 50%;
  background: rgba(0,0,0,.04);
  color: var(--ink);
  display: grid; place-items: center;
  cursor: pointer;
  transition: background .2s ease, transform .2s ease;
}
.d2c-popup-close:hover{
  background: rgba(0,0,0,.08);
  transform: rotate(90deg);
}
.d2c-popup-title{
  margin: 0 0 10px;
  font-family: var(--headline-font);
  font-weight: 700;
  /* Bumped from 26px → clamp(30px, 2.6vw, 38px) for stronger visual
     hierarchy in the popup. */
  font-size: clamp(30px, 2.6vw, 38px);
  line-height: 1.04;
  letter-spacing: -.015em;
  color: var(--ink);
}
.d2c-popup-sub{
  margin: 0 0 20px;
  font-family: var(--display-font);
  font-size: 14px;
  font-weight: 600;
  color: var(--muted);
}
.d2c-popup-qr{
  display: grid; place-items: center;
  margin: 0 auto 20px;
  padding: 12px;
  width: 224px; height: 224px;
  background: #fff;
  border-radius: 18px;
  box-shadow:
    0 8px 24px rgba(0,0,0,.10),
    inset 0 0 0 1px rgba(0,0,0,.06);
}
.d2c-popup-or{
  margin: 12px 0 14px;
  font-family: var(--display-font);
  font-size: 13px;
  font-weight: 600;
  color: var(--muted);
}
.d2c-popup-form{
  display: flex; align-items: center; gap: 0;
  background: #f5ead7;
  border-radius: 999px;
  padding: 6px 6px 6px 16px;
  margin-bottom: 14px;
  /* QA: guarantee the form never overflows its parent card under any
     viewport / font / placeholder length. width:100% pins the form to
     the card's content box; min-width:0 lets the form itself shrink
     inside flex/grid parents (Safari otherwise honors min-content). */
  width: 100%;
  max-width: 100%;
  min-width: 0;
  box-sizing: border-box;
}
.d2c-popup-prefix{
  font-family: var(--display-font);
  font-weight: 700;
  font-size: 14px;
  color: var(--ink);
  flex-shrink: 0;
}
.d2c-popup-input{
  /* `flex: 1 1 0` + `min-width: 0` lets the input shrink BELOW its
     intrinsic min-content size — without this, browsers honor the
     input's default min-width (~150–180px based on the `size` attr
     or placeholder length) and shove the submit button OUT of the
     rounded pill container. This is the canonical flexbox + form
     overflow fix. */
  flex: 1 1 0;
  min-width: 0;
  width: 100%;
  border: 0;
  background: transparent;
  font-family: var(--display-font);
  font-size: 14px;
  font-weight: 600;
  padding: 10px 12px;
  color: var(--ink);
  outline: none;
}
.d2c-popup-input::placeholder{ color: rgba(0,0,0,.42); }
.d2c-popup-submit{
  position: relative;
  /* flex-shrink:0 + explicit width keep the submit pill at a fixed
     38×38 — never compressed away by the input column. Combined with
     the input's `min-width: 0`, this guarantees a stable horizontal
     layout: prefix (fixed) + input (flexible/shrinkable) + submit
     (fixed) always fits inside the form's content box. */
  flex-shrink: 0;
  width: 38px; height: 38px;
  border-radius: 50%;
  background: linear-gradient(180deg, #F82623 0%, #DC1F0E 100%);
  color: #fff;
  border: 0;
  display: grid; place-items: center;
  cursor: pointer;
  box-shadow:
    0 4px 10px rgba(240,46,24,.35),
    inset 0 1px 0 rgba(255,255,255,.20);
  transition: transform .25s ease;
  /* overflow visible so confetti spawned inside can fountain past the
     button's small circular bounds */
  overflow: visible;
}
.d2c-popup-submit:hover{ transform: scale(1.05); }
.d2c-popup-fine{
  margin: 0;
  font-family: var(--display-font);
  font-size: 11px;
  line-height: 1.45;
  color: var(--muted);
}
.d2c-popup-fine a{ color: var(--ink); text-decoration: underline; }

body.is-popup-open{ overflow: hidden; }

/* ============ Scroll-reveal helpers ============ */
.d2c-reveal{
  opacity: 0;
  transform: translateY(28px);
  transition: opacity .9s cubic-bezier(.2,.7,.2,1), transform .9s cubic-bezier(.2,.7,.2,1);
  /* will-change intentionally OMITTED at base: there are dozens of
     .d2c-reveal elements site-wide; permanent promotion of every one
     wastes a GPU layer per element on idle (mobile memory pressure).
     The 900ms transition is light enough that browsers handle the
     reveal smoothly without an explicit hint. */
}
.d2c-reveal.is-in{ opacity: 1; transform: translateY(0); }
@media (prefers-reduced-motion: reduce){
  .d2c-reveal{ opacity: 1; transform: none; transition: none; }
}

/* ============ Responsive ============ */

@media (max-width: 1024px){
  /* Inner-sheet polish only — sticky-pin geometry + transforms are
     owned by the unified block at the END of this file so the JS
     scrubber (which sets inline transforms) isn't fought by !important
     declarations here. */
  .d2c-browse-grid{ max-height: 320px; }
  .d2c-sheet--browse .d2c-browse-col{ height: 100%; }
}
@media (max-width: 900px){
  .d2c-hero{ padding-top: clamp(120px, 14vw, 160px); border-radius: 0; }
  .d2c-hero-stage{ min-height: 580px; }
  .d2c-hero-title{ font-size: clamp(40px, 9vw, 72px); }

  .d2c-hcard{ width: clamp(86px, 18vw, 120px); font-size: 11px; padding: 10px; border-radius: 14px; }
  .d2c-hcard-title{ font-size: clamp(15px, 3vw, 20px); }
  .d2c-hcard-eyebrow, .d2c-hcard-foot{ font-size: 8px; }

  .d2c-hcard--3, .d2c-hcard--5{ display: none; }
  .d2c-chip-float{ font-size: 10.5px; padding: 7px 12px; }
  .d2c-chip-bottom{ display: none; }
  .d2c-chip-left{ top: auto; bottom: 25%; left: 4%; }
  .d2c-chip-right{ top: auto; bottom: 33%; right: 4%; }

  .d2c-band-cards{ min-height: 240px; gap: 4px; }
  .d2c-pcard{ width: clamp(76px, 16vw, 110px); padding: 10px; border-radius: 16px; }
  .d2c-pcard-title{ font-size: 14px; line-height: .92; }
  .d2c-pcard-eyebrow, .d2c-pcard-foot, .d2c-pcard-prize{ font-size: 7.5px; }
  .d2c-pcard--n2, .d2c-pcard--p2{ display: none; }

  .d2c-band-title{ font-size: clamp(36px, 9vw, 56px); gap: 6px; }
  .d2c-band-arrows svg{ width: 32px; height: 32px; }
  .d2c-band-arrows svg:last-child{ margin-left: -16px; }

  .d2c-subtag{ padding-top: clamp(40px, 6vw, 72px); }
  .d2c-subtag-text{ font-size: clamp(16px, 2.6vw, 22px); }

  /* (Sheet stage / pin / sheet layout owned by the unified END-OF-FILE
     block so the JS scrubber's inline transforms aren't overridden.
     Inner-card typography/visual polish only at this breakpoint.) */
  .d2c-sheet-title{ font-size: clamp(40px, 9vw, 64px); }
  .d2c-sheet--browse .d2c-browse-col{ height: 100%; }
  .d2c-sheet-copy{ font-size: clamp(17px, 3vw, 22px); }

  .d2c-phone{ width: clamp(220px, 50vw, 280px); }
  .d2c-prizes{ padding-top: clamp(80px, 12vw, 120px); }
  .d2c-prizes-title{ font-size: clamp(40px, 10vw, 64px); }
  .d2c-btile{ width: clamp(78px, 18vw, 100px); font-size: 11px; }

  .d2c-community{ border-radius: 36px 36px 0 0; padding-top: clamp(72px, 12vw, 120px); }
  .d2c-community h2{ font-size: clamp(36px, 9vw, 64px); }
  .d2c-cphone{ width: clamp(200px, 50vw, 280px); }
  .d2c-community-cta{ padding: clamp(40px, 8vw, 64px) clamp(20px, 4vw, 32px) clamp(60px, 10vw, 96px); gap: clamp(40px, 8vw, 72px); }
  .d2c-community-cta-body{ grid-template-columns: 1fr; text-align: center; min-height: clamp(340px, 60vw, 460px); }
  .d2c-community-cta-text{ align-self: start; }
  .d2c-community-cta h3,
  .d2c-typewriter-headline{ font-size: clamp(24px, 6vw, 38px); }
  /* Wireframes shrink on mobile so the pair fits inside the brown container
     and the slight bottom overhang is preserved. */
  .d2c-community-mocks{ left: 50%; right: auto; transform: translateX(-50%); gap: 8px; }
  .d2c-community-mock{ width: clamp(110px, 30vw, 150px); }
  .d2c-community-mock--1{ transform: translateY(clamp(30px, 5vw, 50px)); }
  .d2c-community-mock--2{ transform: translateY(clamp(48px, 7vw, 72px)); }

  .d2c-cta-card{ padding: clamp(56px, 10vw, 96px) clamp(20px, 4vw, 48px); }
  .d2c-cta-h{ font-size: clamp(44px, 12vw, 80px); }

  .d2c-popup-card{ padding: 32px 22px 22px; }
  .d2c-popup-title{ font-size: clamp(26px, 6.4vw, 32px); }
  .d2c-popup-qr{ width: 184px; height: 184px; }

  .nav-links{ display: none; }
  .header-inner{ grid-template-columns: auto 1fr auto; gap: 12px; padding: 16px clamp(16px, 4vw, 28px); }
}
@media (max-width: 560px){
  .d2c-hero-title{ font-size: clamp(40px, 11.5vw, 64px); }
  .d2c-hcard--4{ display: none; }
  .d2c-cta-float--3, .d2c-cta-float--4, .d2c-cta-float--5{ display: none; }
  .d2c-hcard{ width: clamp(78px, 22vw, 100px); }
  .d2c-hcard--1{ top: 4%; left: 2%; }
  .d2c-hcard--2{ top: 2%; right: 2%; }
  .d2c-pcard--n2, .d2c-pcard--p2, .d2c-pcard--n1{ display: none; }
  .d2c-pcard--p1{ display: flex; }
}

/* ============ D2C Footer — INVERTED B2B footer ============
   The B2B footer is white outer + red card with cream text. On the
   consumer side we invert: red outer (the section bg already provides
   this) + cream card with dark text. Same markup, only colors flip. */
body.d2c .footer{
  background: transparent;
}
body.d2c .footer-card{
  background: linear-gradient(180deg, #FFE9E1 0%, #F5DCD0 100%);
  color: #F82623;
  box-shadow:
    0 18px 44px rgba(0,0,0,.18),
    inset 0 1px 0 rgba(255,255,255,.7);
}
body.d2c .footer-card::before{
  background:
    radial-gradient(ellipse at 80% 0%, rgba(255,255,255,.4), transparent 50%),
    radial-gradient(ellipse at 20% 100%, rgba(60, 30, 24, .08), transparent 50%);
}
body.d2c .foot-label{ color: #F82623; }
body.d2c .app-pill{
  background: #F82623;
  color: #FFE9E1;
  box-shadow:
    0 8px 18px rgba(0,0,0,.22),
    inset 0 1px 0 rgba(255,255,255,.10);
}
body.d2c .app-pill .div{ color: #FFE9E1; opacity: .45; }
body.d2c .apple-mark,
body.d2c .play-mark{ background: #FFE9E1; }
body.d2c .foot-socials a{
  background: rgba(0,0,0,.08);
  color: #F82623;
}
body.d2c .foot-socials a:hover{
  background: rgba(0,0,0,.16);
  box-shadow: 0 8px 16px rgba(0,0,0,.14);
}
body.d2c .foot-nav,
body.d2c .foot-nav a{ color: #F82623; }
body.d2c .footer-mark{ color: #F82623; }

/* ============ Unified subtext typography ============
   All D2C subtexts use SF Pro Rounded SemiBold (var(--body-font), 600).
   `!important` so we beat the per-element font-weight declarations
   sprinkled through the file without having to retouch each one. */
body.d2c .d2c-hero-tag,
body.d2c .d2c-hero-foot,
body.d2c .d2c-features-lead,
body.d2c .d2c-prizes-lead,
body.d2c .d2c-community-lead,
body.d2c .d2c-section-three-sub,
body.d2c .d2c-sheet-sub,
body.d2c .d2c-sheet-copy,
body.d2c .d2c-subtag-text,
body.d2c .d2c-cta-foot,
body.d2c .d2c-carousel-caption-body{
  font-family: var(--body-font) !important;
  font-weight: 600 !important;
}
/* Bold inline (<strong>) inside subtexts steps up to 700 so it still
   stands out from the semi-bold baseline. */
body.d2c .d2c-subtag-text strong,
body.d2c .d2c-sheet-copy strong,
body.d2c .d2c-cta-foot strong{
  font-weight: 800 !important;
}

/* Universal scroll fade-up reveal — handled by the IO-based .d2c-reveal
   system (CSS earlier in this file, JS auto-tag list in d2c.js). That
   approach works in every browser and mirrors brand's .reveal-up. */

/* =================================================================
   ============   MOBILE OVERHAUL — single source of truth   ========
   =================================================================
   Applies <=768px. Recomposes the desktop sections that don't translate
   well to narrow viewports: kills heavy pin-stages, collapses absolute
   compositions into normal flow, single-column grids, larger tap
   targets, hides decorative clutter, and right-sizes typography. */
@media (max-width: 1024px){

  /* ============ MOBILE LCP/FCP FIX (revised — surgical) ============
     Tier B handled .d2c-hero-title (opacity:1 from t=0 + transform-
     only slide). This block extends the SAME pattern element-by-
     element to the rest of the above-fold hero so each is paintable
     from t=0 on mobile — WITHOUT flatly disabling animations.

     Per-element treatment:
       • Text/CTA (mark, tag, ctas, foot): switched to the existing
         `d2c-title-slide` keyframe (transform-only 16px slide).
         Original delays + durations preserved → identical motion.
       • hcards: switched to new `d2c-hcard-rise-mobile` keyframe
         (transform-only: translateY + scale + blur). Rise motion
         preserved — only the opacity gate is dropped.
       • chips: DISABLED. Documented below — only animation that
         had to be sacrificed, with explanation.

     For each element we also override the body.is-loading +
     body.is-revealed cascade so the JS class chain (which still
     fires after first paint while the splash plays) doesn't re-
     introduce opacity:0 or re-trigger the bloom keyframes that
     would briefly fade-out already-visible content.

     DESKTOP IS UNAFFECTED — all rules live inside the
     `@media (max-width: 1024px)` block. Desktop continues to use
     the unmedia'd cascade rules at d2c.css:127-201 (90/0.4s LCP). */

  /* TEXT + CTA — transform-only slide (motion preserved). */
  body.d2c .d2c-hero-mark{
    opacity: 1;
    animation: d2c-title-slide .8s .05s cubic-bezier(.2,.7,.2,1) both;
  }
  body.d2c .d2c-hero-tag{
    opacity: 1;
    animation: d2c-title-slide .8s .15s cubic-bezier(.2,.7,.2,1) both;
  }
  body.d2c .d2c-hero-ctas{
    opacity: 1;
    animation: d2c-title-slide .9s .42s cubic-bezier(.2,.7,.2,1) both;
  }
  body.d2c .d2c-hero-foot{
    opacity: 1;
    animation: d2c-title-slide .9s .56s cubic-bezier(.2,.7,.2,1) both;
  }

  /* HCARDS — rise motion preserved via transform-only variant.
     New keyframe `d2c-hcard-rise-mobile` (defined below this @media
     block) animates translateY + scale + blur exactly like the
     original d2c-card-rise, but drops the opacity 0→1 segment so
     cards are paintable from t=0. */
  body.d2c .d2c-hcard{
    opacity: 1;
    animation: d2c-hcard-rise-mobile 1s cubic-bezier(.2,.7,.2,1) backwards;
  }

  /* CHIPS — DISABLED animation. Reason: the original `d2c-chip-in`
     keyframe is opacity-only (no transform/scale/translate) — the
     animation IS the fade-in, there is no underlying motion to
     preserve. Forcing opacity:1 + animation:none lets the chips
     paint at t=0 with their final styling. Nothing else (no
     transform, no scale, no slide) is sacrificed. */
  body.d2c .d2c-chip-float{
    opacity: 1;
    animation: none;
  }

  /* Override body.is-loading so the JS-added class (which is set
     synchronously on first visit while splash plays) can't drive
     these elements back to opacity:0.
     ALSO unfreeze the animation timer. The desktop is-loading rule
     sets `animation-play-state: paused !important; transform: none
     !important` — that combination causes a JOLT on mobile when
     is-loading is removed at splash dismiss: the paused animation
     is at frame 0 (= `translateY(16px)` from-state), but the
     !important transform was masking that with `none`. The moment
     is-loading is lifted, the mask disappears and the element
     snaps down 16px before sliding back up.
     Fix: let the animation timer run during splash. The animation
     completes (~850ms) entirely under the red overlay, so by the
     time splash dismisses the element is already filled-forward
     to its final `translateY(0)` state — no visible jump. */
  body.d2c.is-loading .d2c-hero-mark,
  body.d2c.is-loading .d2c-hero-tag,
  body.d2c.is-loading .d2c-hero-ctas,
  body.d2c.is-loading .d2c-hero-foot,
  body.d2c.is-loading .d2c-chip-float,
  body.d2c.is-loading .d2c-hcard{
    opacity: 1 !important;
    animation-play-state: running !important;
  }

  /* Override body.is-revealed so the cascade-bloom rules at
     d2c.css:161-198 don't restart `d2c-bloom-up` / `d2c-card-bloom`
     animations (both go opacity 0→1 — would cause a visible flicker
     of already-painted content on mobile). Re-pin to the same
     transform-only animations we set above. */
  body.d2c.is-revealed .d2c-hero-mark{
    animation: d2c-title-slide .8s .05s cubic-bezier(.2,.7,.2,1) both;
  }
  body.d2c.is-revealed .d2c-hero-tag{
    animation: d2c-title-slide .8s .15s cubic-bezier(.2,.7,.2,1) both;
  }
  body.d2c.is-revealed .d2c-hero-ctas{
    animation: d2c-title-slide .9s .42s cubic-bezier(.2,.7,.2,1) both;
  }
  body.d2c.is-revealed .d2c-hero-foot{
    animation: d2c-title-slide .9s .56s cubic-bezier(.2,.7,.2,1) both;
  }
  body.d2c.is-revealed .d2c-chip-float{
    animation: none;
  }
  body.d2c.is-revealed .d2c-hcard{
    animation: d2c-hcard-rise-mobile 1s cubic-bezier(.2,.7,.2,1) backwards;
  }

  /* ---------- Global mobile guards ---------- */
  body.d2c{
    /* Prevent any rogue horizontal overflow — safer than relying on
       per-element rules to never exceed the viewport. */
    overflow-x: clip;
  }
  body.d2c img, body.d2c video, body.d2c svg{
    max-width: 100%;
  }

  /* ---------- Header ---------- */
  /* Header sizing now lives in styles.css under the same @media block
     so it stays consistent across consumer + brands pages. d2c.css only
     keeps the nav-links hide here as a double-belt against the desktop
     rule. */
  body.d2c .nav-links{ display: none; }

  /* ---------- HERO ---------- */
  /* RESTORED on mobile per user request — the persistent hero-mark
     logo above the "Every sweep, one feed" tag, so the splash logo
     has a real target to dive into (same UX as desktop). */
  body.d2c .d2c-hero-mark{
    display: inline-flex !important;
    margin: 0 auto 14px;
  }
  body.d2c .d2c-hero-mark img{
    /* Slightly larger than the desktop floor (22px) so the logo
       reads cleanly on phones, but reduced from the prior pass
       per user request — small/subtle, not dominant. */
    height: clamp(20px, 4.4vw, 24px);
  }

  /* CENTER the title + CTA cluster vertically. .d2c-hero-stage is the
     flex child that holds the inner block; flex-centering it produces
     a true vertical middle without depending on padding math. */
  body.d2c .d2c-hero-stage{
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 0;
    padding: 0;
  }
  body.d2c .d2c-hero-inner{
    padding-top: 0;
    position: relative;
    z-index: 4;
    /* Explicit centering at the inner level too so the entire
       logo + tag + title + CTA stack reads as one vertically-centered
       cluster on small viewports. */
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
  }
  body.d2c .d2c-hero-title{
    font-size: clamp(44px, 12vw, 64px);
    line-height: .92;
    letter-spacing: -.025em;
  }
  body.d2c .d2c-hero-tag{
    font-size: 13px;
    letter-spacing: .14em;
    margin-bottom: 12px;
    margin-top: 0;
  }
  body.d2c .d2c-hero-ctas{
    margin-top: 20px;
  }
  body.d2c .d2c-hero-ctas .btn{
    min-height: 48px;
    padding: 13px 26px;
    font-size: 16px;
  }
  /* Hero foot ("BROWSE, ENTER, TRACK [big mascot] WIN BIG") — mobile
     replicates the unlockt.me reference: a LARGE central mascot with the
     two text halves visually balanced on either side, sitting close to
     the mascot edges. Text is bumped up so it visually centers on the
     mascot's body rather than its feet.
     Bottom margin/padding TIGHTENED so the foot sits closer to the
     very bottom of the viewport per user request. The chip-left /
     chip-right-2 pills at bottom:8% sit ABOVE this foot — they don't
     collide horizontally because foot is centered and chips are
     edge-anchored. */
  body.d2c .d2c-hero-foot{
    font-size: clamp(11px, 3.2vw, 14px);
    letter-spacing: .14em;
    padding: 0 12px 6px;
    margin-bottom: 6px;
    gap: 8px;
    flex-wrap: nowrap;
    align-items: center;
    justify-content: center;
  }
  body.d2c .d2c-hero-foot-text{
    white-space: nowrap;
    flex: 0 0 auto;
  }
  body.d2c .d2c-hero-foot-mascot{
    width: clamp(64px, 19vw, 92px);
    height: clamp(64px, 19vw, 92px);
    flex: 0 0 auto;
    margin: 0 -2px;
  }

  /* RESTORED on mobile — scaled-down hero composition. The 3 floating
     chips and 5 floating sweepstake cards stay visible but smaller, so
     the hero keeps its full marketing energy on phones. */
  body.d2c .d2c-chip-float{
    font-size: 11px;
    padding: 6px 12px;
    gap: 5px;
  }
  body.d2c .d2c-chip-float .d2c-chip-emoji{
    font-size: 13px;
  }
  /* Pin chips to corners that DON'T overlap the centered title cluster.
     With cards at top (~14–32% of hero) and title cluster mid (35–60%),
     the safe zones are: top-right above cards, bottom-left + bottom-right
     in the band between CTA and foot. */
  /* MOBILE CHIP LAYOUT —
       chip-right     ("Track + optimize")   TOP-RIGHT  (top: 13%)
       chip-left      ("Swipe in seconds")   MID-LEFT   (bottom: 18%)
       chip-right-2   ("See what community") BOTTOM-RIGHT (bottom: 6%)
     chip-right is restored to its original top-right anchor per user
     request. chip-left stays where it is. chip-right-2 lowered so its
     vertical range no longer overlaps chip-left (chip-left bottom:18%,
     chip-right-2 bottom:6% gives a clear gap on opposite sides).
     Desktop chip positions are unchanged (unmedia'd rules at
     d2c.css:515-517 still own desktop). */
  /* "Swipe in seconds" pill — lowered slightly per user request to
     reduce headline-area crowding (was bottom: 18%). */
  body.d2c .d2c-chip-left{
    top: auto; bottom: 13%; left: 4%; right: auto;
  }
  /* "Track + optimize your wins" pill — top-right (unchanged). */
  body.d2c .d2c-chip-right{
    top: 13%; right: 4%; left: auto; bottom: auto;
  }
  /* "See what the community is entering" pill — REMOVED on mobile
     per user request to make the hero feel less overwhelming. The
     pill stays in HTML and still renders on desktop via the
     unmedia'd `.d2c-chip-right-2` rule. */
  body.d2c .d2c-chip-right-2{
    display: none !important;
  }
  /* Floating sweepstake cards — repositioned for mobile in a corner/
     edge-bleed layout (matches the unlockt.me reference). Cards live in
     the LEFT and RIGHT gutters of the viewport, at TOP / MIDDLE / BOTTOM,
     some bleeding past the viewport edge for cinematic crop. Title stays
     uncovered in the center. */
  body.d2c .d2c-hcard{
    transform: none;
    transform-origin: center;
    /* MOBILE — no shadow at all. The previous box-shadow painted a
       rectangular soft outline around the PNG bounding box (which
       includes transparent padding), so each card looked like it had
       a low-opacity frame floating behind it. Removed entirely on
       mobile per user request. Desktop keeps its filter:drop-shadow
       (shape-aware, no rectangular frame) in the unmedia'd .d2c-hcard
       rule at the top of the file.
       image-rendering hint kept for higher-quality resampling on
       Safari/iOS when the high-res source PNG is downscaled. */
    filter: none;
    box-shadow: none;
    image-rendering: -webkit-optimize-contrast;
  }
  /* Top-LEFT — small card, slight inset. Raised closer to the header
     per user request (was top:12%) so the red $10K giveaway card sits
     near the top of the hero viewport. */
  body.d2c .d2c-hcard--1{
    left: 4%; top: 5%; right: auto;
    width: clamp(96px, 28vw, 130px);
  }
  /* Top-RIGHT — slightly bigger, partial bleed off the right edge. */
  body.d2c .d2c-hcard--2{
    left: auto; right: -6%; top: 14%;
    width: clamp(104px, 32vw, 150px);
  }
  /* Middle-LEFT — large card bleeding off the LEFT edge. The earlier
     900px / 560px breakpoints hide cards 3/4/5; we explicitly re-show
     them here so the mobile unlockt.me layout has all 5.
     Moved further off-screen left + lowered per user request — the
     prior position (left:-10% top:42%) put too much visual weight in
     the headline area, making the hero feel crowded. The new position
     keeps just a sliver of the card visible at the screen edge as a
     hint of more content, well below the title cluster. */
  body.d2c .d2c-hcard--3{
    display: block;
    left: -22%; top: 55%; right: auto;
    width: clamp(110px, 34vw, 160px);
  }
  /* LOWER-RIGHT — large card bleeding off the RIGHT edge. Positioned
     at top:61% (midpoint between the original 40% mid-right spot and
     the 82% chip-aligned spot from the prior pass). Sits below the
     middle of the hero, above the .d2c-chip-right-2 community pill. */
  body.d2c .d2c-hcard--4{
    display: block;
    left: auto; right: -12%; top: 61%;
    width: clamp(112px, 36vw, 170px);
  }
  /* Bottom-LEFT — HIDDEN on mobile per user request. The yellow
     "Bar S Bonus Cash" card was overlapping the blue MLS card and
     the composition reads cleaner with only 4 cards. */
  body.d2c .d2c-hcard--5{
    display: none !important;
  }

  /* ---------- Hero pin-stage ---------- */
  /* RESTORED on mobile (per user request) — the hero pins for 100vh
     while Section 2 sheets up over it, exactly like desktop. Pin-stage
     is 200vh tall (100vh hero pin + 100vh sheet runway). */
  body.d2c .d2c-pin-stage{
    height: 200vh;
  }
  body.d2c .d2c-hero{
    position: sticky;
    top: 0;
    height: 100vh;
    height: 100svh;
    min-height: 100vh;
    min-height: 100svh;
    padding: 76px 16px 0;
  }
  /* (Earlier rule that zeroed margin-top + transform is now obsolete —
     the next block restores the desktop sheet-up choreography on
     mobile too. Kept here as a no-op so the override below has a
     clear single source of truth.) */
  body.d2c .d2c-section-two{
    margin-top: -80vh;
    --sheet-y: 80vh;
    transform: translate3d(0, var(--sheet-y), 0);
    min-height: 0;
  }

  /* ---------- SECTION 2 — Swipe band ---------- */
  /* The full desktop pin-stage sequence runs on mobile too: pin engages,
     typewriter writes "Swipe to enter" beneath the phone, knob auto-
     swipes, 🎉 pops in, then auto-routes to Section 3. The pin budget
     is reduced from 160vh → 140vh on mobile to keep the trapped-scroll
     window shorter on phones. */
  /* Section 2 keeps the desktop sheet-up margin/transform (set in the
     hero-pin-stage block above). Only override what's mobile-specific
     here. The --sheet-y default of 80vh stays; the JS scroll handler
     drives it down to 0 as the hero pin-stage scrolls past. */
  body.d2c .d2c-section-two{
    display: block;
    padding: 0;
  }
  body.d2c .d2c-band-pin-stage{
    height: 140vh;
    min-height: 0;
  }
  body.d2c .d2c-band{
    /* Stays sticky 100vh so isBandPinned()'s pin-engagement check
       (r.top<=0 && r.bottom>vh) fires correctly on mobile. */
    position: sticky;
    top: 0;
    height: 100vh;
    min-height: 0;
  }
  body.d2c .d2c-band-stage{
    height: auto;
    min-height: 0;
    padding: 0 16px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 100%;
  }
  /* Phone shrinks to fit a mobile screen comfortably — phone needs to
     leave vertical room for the slam beneath it within the 100vh sticky
     band. clamp keeps it readable on both small phones and tablets.

     MOBILE-ONLY VISIBILITY OVERRIDE — the desktop rules at d2c.css
     :1010-1023 hold .d2c-mp at opacity:0 + scale(.94) + translateY(22px)
     and only fade it in via a 1.1s `d2c-mp-entry` animation once JS
     adds `.d2c-band.is-revealed`. On mobile this combination (IO
     wait + 1.1s animation) is the dominant cause of the "blank
     section" the user sees on fast scrolls — the cards/phone art
     are present but the parent container is invisible. We force the
     phone visible from first paint here. Desktop keeps the cinematic
     reveal — these overrides only fire under the (max-width: 1024px)
     media gate. (Matches the prefers-reduced-motion branch at
     d2c.css:1028-1031 which already proves the layout works fine
     without the entry animation.) */
  body.d2c .d2c-mp{
    width: clamp(200px, 56vw, 280px);
    opacity: 1;
    transform: none;
    animation: none;
  }
  body.d2c .d2c-band.is-revealed .d2c-mp{
    /* Keep the slow ambient bob; drop the entry fade-in. */
    animation: d2c-mp-bob 7s ease-in-out 1.3s infinite alternate;
  }
  /* Full-sentence slam beneath the phone — mobile size + spacing. */
  body.d2c .d2c-slam--full{
    font-size: clamp(20px, 5.6vw, 28px);
    margin-top: clamp(16px, 4vw, 24px);
    padding: 0 18px;
  }

  /* ---------- SECTION 3 — Brown box ---------- */
  /* Disable the desktop sheet-up trick (margin-top:-100vh + transform).
     Brown sits in the normal document flow as a regular section. */
  body.d2c .d2c-section-three{
    margin-top: 0;
    height: auto;
    min-height: 0;
    --sheet-y: 0vh;
    transform: none;
    border-radius: clamp(28px, 6vw, 40px);
    padding: 56px 16px 64px;
    margin: 0 12px;
    width: auto;
    box-sizing: border-box;
  }
  body.d2c .d2c-section-three-inner{
    padding: 0;
    max-width: none;
  }
  body.d2c .d2c-subtag-text{
    font-size: 17px;
    line-height: 1.45;
  }
  /* Title at TOP of the brown box (Futura LT Pro eyebrow). */
  body.d2c .d2c-section-three-title{
    margin: 0 auto 20px;
    font-size: 13px;
    letter-spacing: .22em;
    color: #EEE7DF;
  }
  body.d2c .d2c-stats{
    padding: 0;
  }
  /* MOBILE: only 2 stats — Live Sweepstakes (#1) + Average Monthly
     Winners (#3). The middle "Combined Prize Value" is hidden. Grid
     drops to 2 columns so the remaining stats sit side-by-side. */
  body.d2c .d2c-stats-grid{
    grid-template-columns: 1fr 1fr;
    gap: clamp(20px, 5vw, 40px);
  }
  body.d2c .d2c-stat:nth-child(2){
    display: none;
  }
  /* MOBILE QA — the dashed divider between stats is the same SVG as
     desktop (3px stroke, 36px dash pattern), which reads too thick at
     phone widths. Replace with a finer SVG: 2px stroke, 24px pattern. */
  body.d2c .d2c-stat + .d2c-stat::before{
    width: 1.5px;
    left: calc(clamp(20px, 4vw, 40px) / -2);
    top: 18%;
    bottom: 18%;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='2' height='22' viewBox='0 0 2 22'><line x1='1' y1='1' x2='1' y2='11' stroke='%23C1B099' stroke-opacity='0.45' stroke-width='1.5' stroke-linecap='round'/></svg>");
    background-size: 2px 22px;
  }
  body.d2c .d2c-stat-num{
    font-size: clamp(42px, 12vw, 62px);
  }
  body.d2c .d2c-stat-label{
    font-size: 12px;
    line-height: 1.25;
  }
  /* Cream-card subtag — enlarged on mobile so the emoji pop animations
     stay INSIDE the container. The 🪏 (shovel) and ⌨️ (typewriter)
     emojis fly UP from below their words (out the top of the card),
     and ✅ (check) flies in from the right of "enter". Bumping padding
     (especially top) gives those emojis room to land inside. */
  body.d2c .d2c-subtag.d2c-subtag--card{
    margin: 26px auto 0;
    padding: 56px 28px 40px;
    border-radius: 26px;
    overflow: visible;
    box-shadow:
      0 2px 4px rgba(0, 0, 0, .04),
      0 14px 26px rgba(0, 0, 0, .10),
      inset 0 1px 0 rgba(255, 255, 255, .55);
  }
  body.d2c .d2c-subtag.d2c-subtag--card .d2c-subtag-text{
    font-size: 16px;
    line-height: 1.55;
  }
  /* Shrink the emoji pops slightly on mobile so they fit the extra
     padding without crashing into the text above. */
  body.d2c .d2c-subtag-emoji{
    font-size: 1.1em;
  }
  body.d2c .d2c-section-three-cta{
    margin-top: 22px;
  }
  body.d2c .d2c-section-three-cta .btn{
    min-height: 52px;
    padding: 14px 28px;
    font-size: 16px;
  }

  /* ---------- SHEETS — Browse / Enter / Track ---------- */
  /* RESTORED sheet-OVER behavior on mobile (per user request). Same
     desktop choreography — three cards pinned in a tall stage, each
     sliding up over the previous — but the stage shrinks from 500vh
     → 320vh on mobile so the trapped scroll window is more reasonable
     on a phone. Cards are forced to equal heights and a single-column
     vertical layout (title/copy on top, visual below). */
  body.d2c .d2c-sheets{
    margin: 0;
    width: 100%;
    border-radius: 0;
    padding: 0;
  }
  body.d2c .d2c-sheets-stage{
    /* Mobile pin budget bumped to match desktop after the sensitivity
       tuning — see the !important override later in this file that
       takes effect at runtime. Kept at 600vh for source-of-truth
       consistency. */
    height: 600vh;
  }
  body.d2c .d2c-sheets-pin{
    position: sticky;
    top: 0;
    height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 12px;
  }
  body.d2c .d2c-sheet{
    /* RE-INSTATE absolute positioning so the JS transform math sheets
       cards over each other instead of stacking them. */
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    /* Equal heights on every sheet — no auto-grow, no per-card variance. */
    width: min(94vw, 380px);
    height: min(78vh, 580px);
    max-width: none;
    margin: 0;
    padding: 26px 22px 22px;
    grid-template-columns: 1fr;
    /* Title block flexible; visual flexes to fill remainder. The 0fr
       on the visual row + overflow:hidden lets it crop gracefully if
       its natural content height exceeds the cell. */
    grid-template-rows: auto minmax(0, 1fr);
    gap: 14px;
    border-radius: clamp(24px, 5vw, 36px);
    box-shadow: 0 24px 50px rgba(0,0,0,.22), 0 4px 12px rgba(0,0,0,.12);
    overflow: hidden;
  }
  /* Visual area of each sheet (the column to the RIGHT on desktop)
     becomes the BOTTOM block on mobile. Force it to stay inside the
     bounds — any overflow is cropped per the user request that we can
     crop anything to fit. */
  body.d2c .d2c-sheet-visual{
    margin-top: 0;
    min-height: 0;
    height: 100%;
    overflow: hidden;
    position: relative;
  }
  body.d2c .d2c-sheet-title{
    font-size: clamp(40px, 11vw, 56px);
  }
  body.d2c .d2c-sheet-copy{
    font-size: 16px;
    line-height: 1.45;
    margin-top: 8px;
  }
  body.d2c .d2c-sheet-sub{
    font-size: 14px;
    margin-top: 4px;
    opacity: .85;
  }
  body.d2c .d2c-sheet-cta{
    min-height: 48px;
    padding: 13px 24px;
    font-size: 15px;
    margin-top: 18px;
  }
  body.d2c .d2c-sheet-visual{
    position: relative;
    height: auto;
    min-height: 280px;
  }
  /* ENTER card — the swipe pill (.d2c-enter-swipe) is the ONE element
     that absolutely cannot be cropped. Lock it to the dead-center of
     the visual area with a high z-index so the bursting product images
     never visually obscure it. The visual area gets a minimum height
     that comfortably contains the pill. */
  body.d2c .d2c-sheet--enter .d2c-sheet-visual{
    min-height: 300px;
    overflow: visible;        /* let products crop against the SHEET edge, not the visual edge */
    position: relative;
  }
  body.d2c .d2c-sheet--enter .d2c-enter-stage{
    width: 100%;
    height: 100%;
    min-height: 280px;
    position: relative;
    /* Keep the original `display: grid; place-items: center` from the
       desktop rule — flex centering misbehaves here because the stage
       has 13 absolutely-positioned product siblings whose layout the
       flex algorithm still indirectly considers. */
    display: grid;
    place-items: center;
    overflow: visible;
  }
  /* HARD-CENTER the pill using absolute positioning + translate, which
     bypasses any flex/grid centering quirks caused by sibling layout. */
  body.d2c .d2c-sheet--enter .d2c-enter-swipe{
    position: absolute;
    top: 50%;
    left: 50%;
    /* Combine center-translate with the existing -3° rotation. */
    transform: translate(-50%, -50%) rotate(-3deg);
    z-index: 20;              /* above every burst product (their z-index sits below 10) */
    /* Slightly tighter on mobile so there's safe-area margin to the
       card's left/right padding edges. */
    width: clamp(220px, 70vw, 280px);
    height: clamp(64px, 16vw, 80px);
    margin: 0;
  }
  body.d2c .d2c-sheet--enter .d2c-enter-swipe-prompt{
    font-size: clamp(16px, 4.6vw, 20px);
  }
  /* Recenter the handle's anchor — it's now inside an absolutely-
     positioned pill whose own transform includes translate(-50%,-50%).
     The handle stays at left:8px (its existing inset) but its vertical
     transform needs to keep using translate(...,-50%) for vertical
     centering since `top:50%` is from the pill, not the visual. */
  /* BROWSE — desktop uses a 3-column scrolling track of giveaway
     cards; at narrow widths the 3rd column bleeds off the right edge.
     Switch to a TIGHT 2-column track on mobile, contained inside the
     card with rounded edges. Cap height so it doesn't create a huge
     dead zone. */
  body.d2c .d2c-sheet--browse .d2c-sheet-visual{
    height: 320px;
    overflow: hidden;
    border-radius: 16px;
  }
  body.d2c .d2c-browse-columns{
    grid-template-columns: 1fr 1fr;
    height: 100%;
    gap: 10px;
  }
  body.d2c .d2c-browse-col:nth-child(3){
    /* Hide the 3rd column — visually crowded at narrow widths. */
    display: none;
  }
  body.d2c .d2c-browse-col-track img{
    border-radius: 12px;
  }
  /* ENTER — denser prize composition on mobile so the card visual
     fills the space below the title/body/CTA. The grid lets the
     visual cell stretch to fill the remaining sheet height, and we
     scatter ~10 prizes across that area in layered rings around the
     central swipe CTA. overflow:hidden contains anything that bleeds
     past the cell edges. */
  body.d2c .d2c-enter-visual{
    /* Let the grid track size the cell (auto-fill remainder of sheet);
       no fixed height so we always fill the available vertical space. */
    overflow: hidden;
    border-radius: 16px;
    position: relative;
  }
  body.d2c .d2c-enter-prod{
    /* Reset the desktop product transitions so we can position cleanly. */
    transition: none;
  }
  /* On mobile we now show MOST prizes (only the largest desktop-only
     items stay hidden to avoid crowding). Each item is tuned for
     this narrower viewport. */
  body.d2c .d2c-enter-prod--products,
  body.d2c .d2c-enter-prod--luke{ display: none; }

  /* Top row (above the swipe pill) — 4 hero prizes. */
  body.d2c .d2c-enter-prod--tahoe   { top: 2%;  right: -8%; left: auto; width: 46%; transform: rotate(2deg); }
  body.d2c .d2c-enter-prod--bag     { top: 0;   left: -6%;             width: 36%; transform: rotate(-6deg); }
  body.d2c .d2c-enter-prod--head    { top: 4%;  left: 38%; right: auto; width: 28%; transform: rotate(-2deg); }
  body.d2c .d2c-enter-prod--football{ top: 22%; left: 22%; right: auto; width: 18%; transform: rotate(8deg); }

  /* Middle row (just above + behind the swipe pill) — secondary fill. */
  body.d2c .d2c-enter-prod--headphones{ top: 30%; right: -4%; left: auto; width: 28%; transform: rotate(10deg); }
  body.d2c .d2c-enter-prod--perfume   { top: 36%; left: -4%;             width: 18%; transform: rotate(-12deg); }
  body.d2c .d2c-enter-prod--giftcard  { top: 42%; left: 42%; right: auto; width: 22%; transform: rotate(6deg); }

  /* Bottom row (below the swipe pill) — fills the empty zone near
     the bottom of the card. */
  body.d2c .d2c-enter-prod--sneaker{ top: 60%; left: -10%; right: auto; width: 38%; transform: rotate(8deg); }
  body.d2c .d2c-enter-prod--cooler { top: 64%; left: 38%; right: auto; width: 26%; transform: rotate(-6deg); }
  body.d2c .d2c-enter-prod--beer   { top: 62%; right: -6%; left: auto; width: 22%; transform: rotate(12deg); }
  body.d2c .d2c-enter-prod--wallet { top: 78%; left: 26%; right: auto; width: 24%; transform: rotate(-4deg); }
  body.d2c .d2c-enter-swipe{
    width: min(280px, 80%);
    height: 64px;
    /* Position swipe pill at the bottom-center of the stage. */
    position: absolute;
    bottom: 12%;
    left: 50%;
    top: auto;
    transform: translateX(-50%) rotate(-3deg);
  }
  body.d2c .d2c-enter-swipe-prompt{
    font-size: 18px;
  }
  body.d2c .d2c-enter-swipe-handle{
    width: 50px;
    height: 50px;
  }
  /* TRACK — video sits in the visual area at the bottom of the card.
     The video is a SIBLING of .d2c-sheet-visual (both inside the card),
     so we anchor it via `bottom: 0` + fixed height equal to the visual
     area's min-height, plus `transform: translateX(-50%)` to center. */
  body.d2c .d2c-sheet--track{
    /* Add a little inner padding-bottom so the visual area has room
       for the video without colliding with the card edge. */
    padding-bottom: 0;
    overflow: hidden;
  }
  body.d2c .d2c-sheet--track .d2c-sheet-visual{
    min-height: 360px;
    border-radius: 16px;
  }
  /* Track-card screenshots (.d2c-track-shot--entries / --giveaway)
     are sized per-breakpoint by the dedicated TRACK CARD SHOTS block
     at the END of this file. Both images live INSIDE .d2c-sheet-visual
     (overflow:hidden + top-fade mask) so they can never overlap the
     text/CTA cell on any width. */

  /* ---------- FEATURES carousel ---------- */
  body.d2c .d2c-features{
    padding: 72px 16px;
  }
  /* Match .d2c-prizes-title sizing exactly so the two section
     headlines ("Your Giveaway Control Center" + "Prizes from all
     these places") read at the same scale on mobile. */
  body.d2c .d2c-features-title{
    font-size: clamp(36px, 10vw, 56px);
  }
  body.d2c .d2c-features-lead{
    font-size: 15px;
  }
  /* MOBILE QA — hide the prev/next arrows entirely on mobile. The
     carousel auto-rotates every 4800ms via the d2c.js autoplay timer,
     so manual nav is redundant on phones. */
  body.d2c .d2c-carousel-arrow{
    display: none;
  }
  /* MOBILE QA — show exactly 3 cards in the viewport: the active
     (center) card + ONE on each side that's partially CUT off by the
     viewport edge. Cards at offset ±2 (and beyond) hide entirely. The
     ±1 cards are translated outward enough to bleed past the viewport
     edges with only ~40% of their width visible. */
  /* Tighter card spacing on mobile — side cards moved from ±50vw to
     ±36vw so they hug closer to the center card (less negative space
     between them). */
  body.d2c .d2c-carousel-card[data-offset="1"]{
    transform: translate(calc(-50% + 36vw), -50%) translateZ(-60px) rotateY(-18deg) scale(.84);
    opacity: .9;
  }
  body.d2c .d2c-carousel-card[data-offset="-1"]{
    transform: translate(calc(-50% - 36vw), -50%) translateZ(-60px) rotateY(18deg) scale(.84);
    opacity: .9;
  }
  /* Hide everything farther out — only the active card + immediate
     neighbors should ever be visible on mobile. */
  body.d2c .d2c-carousel-card[data-offset="2"],
  body.d2c .d2c-carousel-card[data-offset="-2"],
  body.d2c .d2c-carousel-card[data-offset="3"],
  body.d2c .d2c-carousel-card[data-offset="-3"],
  body.d2c .d2c-carousel-card[data-offset="4"],
  body.d2c .d2c-carousel-card[data-offset="-4"]{
    opacity: 0;
    pointer-events: none;
  }
  /* Center card scaled DOWN per mobile QA — smaller feature cards so
     more of the carousel composition is visible at narrow widths. */
  body.d2c .d2c-carousel-card{
    width: clamp(150px, 48vw, 210px);
  }
  /* Carousel stage no longer needs to make room for arrows. */
  body.d2c .d2c-carousel{
    padding-left: 0;
    padding-right: 0;
  }

  /* ---------- SECTION 4 — Prizes / Community ---------- */
  /* Prizes grid: keep cards inside the viewport instead of bleeding past
     either edge. Single-column or 2-up depending on width. */
  body.d2c .d2c-prizes-grid{
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 14px;
    padding: 0 16px;
  }
  body.d2c .d2c-prize-tile{
    aspect-ratio: 1;
  }
  body.d2c .d2c-prizes-title,
  body.d2c .d2c-community-title{
    font-size: clamp(36px, 10vw, 56px);
  }

  /* ---------- COMMUNITY — wireframes ABOVE the text/CTA ---------- */
  /* MOBILE QA: the desktop layout absolutely-positions the wireframes
     in the right column of a 2-col grid, which collapses on mobile and
     causes the text/CTA to cover them. On mobile we:
       1. Switch the body to flex column-reverse so the mocks (which
          are the SECOND child in the HTML) render ABOVE the text/CTA.
       2. Make the mocks block flow normally (position: relative).
       3. Center the wireframes horizontally inside the brown container. */
  body.d2c .d2c-community-cta-body{
    display: flex;
    flex-direction: column-reverse;
    align-items: center;
    grid-template-columns: none;
    min-height: 0;
    gap: clamp(28px, 6vw, 44px);
  }
  body.d2c .d2c-community-mocks{
    position: relative;
    top: auto; right: auto; left: auto;
    transform: none;
    display: flex;
    justify-content: center;
    align-items: flex-end;
    gap: 10px;
    width: 100%;
    /* Cap height so two large wireframes don't dominate the entire
       container — they sit nicely above the typewriter headline. */
    max-height: 360px;
  }
  body.d2c .d2c-community-mock{
    width: clamp(130px, 36vw, 170px);
  }
  /* Neutralize the desktop translateY drops so the wireframes sit
     fully inside the brown container instead of hanging past its
     bottom edge. */
  body.d2c .d2c-community-mock--1,
  body.d2c .d2c-community-mock--2{
    transform: none;
  }
  body.d2c .d2c-community-cta-text{
    width: 100%;
    text-align: center;
    align-self: center;
  }
  body.d2c .d2c-community-cta-text .d2c-community-btn{
    margin-top: clamp(20px, 5vw, 32px);
  }

  /* ---------- FAQ ---------- */
  body.d2c .d2c-faq{
    padding: 64px 16px 72px;
  }
  /* Stack the two-column FAQ layout (heading + CTA on top, accordion
     list below) so the sticky heading doesn't overlap the questions. */
  body.d2c .d2c-faq .faq-inner{
    grid-template-columns: 1fr;
    gap: 28px;
  }
  body.d2c .d2c-faq .faq-side{
    position: static;
    top: auto;
  }
  body.d2c .d2c-faq .faq-heading{
    font-size: clamp(40px, 11vw, 56px);
  }
  body.d2c .d2c-faq .faq-side .btn{
    margin-top: 18px;
    min-height: 48px;
  }
  body.d2c .d2c-faq .faq-list{ gap: 16px; }
  body.d2c .d2c-faq .faq-q{
    font-size: 16px;
    padding: 18px 18px;
  }

  /* ---------- SECTION 6 — Final CTA ---------- */
  body.d2c .d2c-section-six{
    padding-top: 60px;
  }
  body.d2c .d2c-cta-title,
  body.d2c .d2c-section-six h2{
    font-size: clamp(46px, 12vw, 72px);
    line-height: .94;
  }

  /* ---------- Footer ---------- */
  body.d2c .footer-card{
    padding: 32px 22px;
  }
  body.d2c .footer-top{
    flex-direction: column;
    align-items: flex-start;
    gap: 22px;
  }
  body.d2c .app-pill{ min-height: 48px; }
  body.d2c .foot-socials{ gap: 14px; }
  body.d2c .foot-socials a{
    width: 44px;
    height: 44px;
  }
  body.d2c .foot-nav{
    flex-wrap: wrap;
    gap: 14px 22px;
    justify-content: center;
  }
  body.d2c .footer-mark svg{ height: 56px; }

  /* ---------- Scroll-progress + return-to-top ---------- */
  body.d2c .scroll-progress{ height: 3px; }
}

/* Extra-tight tuning at very narrow widths (iPhone SE / Galaxy A series). */
@media (max-width: 380px){
  body.d2c .d2c-hero-title{ font-size: clamp(40px, 12vw, 52px); }
  body.d2c .d2c-section-three{ padding: 44px 14px 52px; }
  body.d2c .d2c-stat-num{ font-size: 38px; }
  body.d2c .d2c-stat-label{ font-size: 11px; }
  body.d2c .d2c-sheet{ padding: 24px 18px; }
  body.d2c .d2c-sheet-title{ font-size: 36px; }
  body.d2c .d2c-prizes-grid{ grid-template-columns: 1fr; }
  /* Hero foot — narrow phones keep the LARGE central mascot but trim
     the text + horizontal padding so the row stays on a single line. */
  body.d2c .d2c-hero-foot{ font-size: 10.5px; gap: 6px; padding: 0 8px 18px; letter-spacing: .12em; }
  body.d2c .d2c-hero-foot-mascot{ width: 68px; height: 68px; }
}

/* =================================================================
   POLISH PASS — additional mobile refinements                   ==
   ================================================================= */
@media (max-width: 1024px){

  /* (Blanket mobile reveal fallback REMOVED — it auto-revealed every
     .d2c-reveal element 1.2s after page load, regardless of scroll
     position. For elements far below the fold (community / FAQ /
     final CTA), they'd reveal off-screen before the user ever got
     there, so the on-scroll fade-up was never visible. The
     IntersectionObserver in d2c.js handles all reveals on scroll.) */

  /* (Sheets margin between cards REMOVED — sheets are now
     position:absolute and sheet OVER each other on mobile, so per-card
     bottom-margin no longer applies. The pin-stage's vh budget owns
     the spacing.) */

  /* Section 4 — top padding REMOVED so the BROWSE sheet's sticky pin
     engages immediately as the user enters Section 4, with no empty
     cream stripe between Section 3 (brown stats) and the first sheet.
     min-height auto so the section measures by content (sheets stage
     320vh + prizes + community), not the desktop 98.75vw cap. */
  body.d2c .d2c-section-four{
    padding: 0 0 64px;
    margin-top: 0;
    min-height: 0;
  }
  body.d2c .d2c-prizes-title,
  body.d2c .d2c-community-title{
    padding: 0 16px;
  }
  body.d2c .d2c-prizes-lead,
  body.d2c .d2c-community-lead{
    font-size: 15px;
    padding: 0 16px;
    margin-bottom: 28px;
  }

  /* Section 6 final CTA card — tighter padding, larger CTA target. */
  body.d2c .d2c-section-six{
    padding: 56px 0 0;
  }
  body.d2c .d2c-cta-card,
  body.d2c .d2c-section-six .cta-card{
    padding: 48px 24px;
    margin: 0 12px;
    border-radius: clamp(28px, 6vw, 40px);
  }
  body.d2c .d2c-cta-foot{
    font-size: 13px;
  }

  /* Footer card margin — same as Section 6 for visual continuity. */
  body.d2c .footer-card{
    margin: 0 12px;
    border-radius: clamp(28px, 6vw, 40px);
  }

  /* Features carousel — tighten card sizes and caption. */
  body.d2c .d2c-carousel-caption{
    padding: 0 24px;
  }
  body.d2c .d2c-carousel-caption-title{
    font-size: clamp(22px, 6vw, 32px);
  }
  body.d2c .d2c-carousel-caption-body{
    font-size: 14.5px;
    line-height: 1.5;
  }

  /* Scroll-progress bar — slightly thinner on mobile. */
  body.d2c .scroll-progress{
    height: 2px;
  }

  /* Return-to-top button — ensure 44px min tap target, position closer
     to safe area on mobile. */
  body.d2c .d2c-to-top,
  body.d2c #d2cToTop{
    width: 48px;
    height: 48px;
    bottom: 16px;
    right: 16px;
  }
}

/* =================================================================
   SHEETS STICKY-PIN — APPLY AT ALL WIDTHS ≤1024 (mobile + tablet).
   The JS-driven over-stacking choreography (see d2c.js comment
   "The same JS-driven transform math runs at all viewport sizes")
   expects sheets to be position:absolute inside a 100vh sticky pin
   regardless of viewport. Earlier @media (max-width:1024px) blocks
   in this file force position:relative + vertical flow, which kills
   the animation on mobile. This block at END of file overrides
   them and restores sticky-pin geometry. Inner-sheet layout is then
   refined by per-width blocks below (side-by-side for tablet,
   single-column for true mobile).
   ================================================================= */
@media (max-width: 1024px){
  /* Match the desktop stage height — 600vh after sensitivity tuning
     so mobile gets the same per-scroll-tick animation progress feel. */
  .d2c-sheets-stage{ height: 600vh !important; }
  .d2c-sheets-pin{
    position: sticky !important;
    top: 0 !important;
    height: 100vh !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    padding: 0 clamp(12px, 4vw, 64px) !important;
    flex-direction: row !important;
    gap: 0 !important;
  }
  .d2c-sheet{
    position: absolute !important;
    left: 50% !important;
    top: 50% !important;
    /* NOTE: transform intentionally NOT !important. JS scrubber sets
       an inline transform every scroll tick (translate(-50%, calc(-50% + Nvh))
       scale(...)); a CSS !important would defeat the inline style and
       break the over-stacking animation. The base `.d2c-sheet`
       declaration at the top of this file provides the centering
       transform until JS takes over. */
    transform: translate(-50%, -50%);
    min-height: 0 !important;
    margin: 0 !important;
    opacity: 1 !important;
    filter: none !important;
  }
  .d2c-sheet-visual{
    height: 100% !important;
    max-height: none !important;
    overflow: hidden;
  }
}

/* IN-BETWEEN TABLET ZONE (769–1024px) — side-by-side text + visual,
   desktop-style track video. */
@media (min-width: 769px) and (max-width: 1024px){
  .d2c-sheet{
    width: min(1686px, 87.8vw) !important;
    height: min(831px, 85vh) !important;
    grid-template-columns: minmax(200px, 1fr) minmax(0, 2.4fr) !important;
    grid-template-rows: minmax(0, 1fr) !important;
    padding: clamp(56px, 6vw, 96px) clamp(40px, 4vw, 80px) clamp(40px, 4vw, 64px) !important;
    gap: clamp(20px, 2.4vw, 56px) !important;
  }
  /* Track-card screenshot sizing for this breakpoint owned by the
     TRACK CARD SHOTS block at the END of this file. */
}

/* TRUE MOBILE (≤768px) — single-column inside sheet (text stacked
   over visual). Sheets still sticky-pin/over-stack as user scrolls;
   only the INNER layout collapses to one column so the text isn't
   crammed into ~140 px alongside the visual. */
@media (max-width: 768px){
  .d2c-sheet{
    width: min(560px, 92vw) !important;
    height: min(720px, 84vh) !important;
    grid-template-columns: 1fr !important;
    grid-template-rows: auto minmax(0, 1fr) !important;
    padding: clamp(24px, 6vw, 40px) !important;
    gap: clamp(14px, 3vw, 24px) !important;
  }
  .d2c-sheet-text{
    /* Text block sits above the visual; let it size to content. */
    align-self: start;
  }
  .d2c-sheet-visual{
    height: auto !important;
    min-height: 0 !important;
    flex: 1 1 auto;
    align-self: stretch;
    position: relative;
    overflow: hidden;
  }
  /* Track video on mobile inherits the unified inset:0 + object-fit:
     cover rule, so it fills the visual cell (which sits BELOW the
     text/CTA in this stacked layout) flush to the card's bottom
     boundary, cropping any excess from the bottom. */
}

/* =================================================================
   TRACK CARD SHOTS — per-viewport sizing for the side-by-side
   diptych. The pair fill the cell edge-to-edge (no inner "frame"
   around the screenshots); each card overlaps the other in the
   middle, and the corners are tucked tightly against the cell.
   Tall portrait aspect ratio (≈ 0.46 W/H) means a single card sized
   to >~50% of cell width will overflow vertically — that natural
   overflow IS the crop that exposes the desired half of each image.
   overflow:hidden on the visual cell handles cropping on all four
   edges; on mobile we allow modest left/right hang-off too.
   ================================================================= */

/* TRUE MOBILE (≤768px) — Figma mobile (node 2941-4171).
   Asymmetric staggered diptych: LEFT phone lowered (extends past
   card bottom, cropped); RIGHT phone raised higher in the card.
   text-cell has elevated z-index so the text/CTA always paint on
   top of any visual overlap with the phones. */
@media (max-width: 768px){
  .d2c-sheet--track .d2c-sheet-text{
    position: relative;
    z-index: 5;
  }
  .d2c-track-shot--entries{
    /* LEFT phone — LOWERED. Bottom extends 60px past the card
       bottom (cropped at sheet's overflow:hidden). */
    width: 48%;
    top: auto;
    bottom: calc(-2% - 60px);
    left: 3%;
    right: auto;
  }
  .d2c-track-shot--giveaway{
    /* RIGHT phone — LOWERED so it clears the subtext block above it.
       Previously sat at bottom:22% which crashed visually into the
       sheet's copy line on small phones. Now anchored close to the
       bottom (bottom:6%) so it stays well below all text. */
    width: 44%;
    top: auto;
    bottom: 6%;
    left: auto;
    right: 3%;
  }
}

/* TABLET (769–1024px) — phones at 30% card width (slightly scaled
   down from 34%), positioned with breathing room from the card's
   right edge (4% margin). Per-user 100px vertical stagger preserved
   (LEFT down, RIGHT up). */
@media (min-width: 769px) and (max-width: 1024px){
  .d2c-track-shot--entries{
    width: 30%;
    height: auto;
    top: calc(2.5% + 100px);
    left: 30%;
  }
  .d2c-track-shot--giveaway{
    width: 30%;
    height: auto;
    bottom: calc(2.5% + 100px);
    right: 4%;
    left: auto;
    top: auto;
  }
}

/* FULL-SIZE DESKTOP (≥1025px) — phones at 30% card width (slightly
   scaled down from 34%). RIGHT phone has 4% gap from the card's
   right edge; LEFT phone at left:33% (nudged in from 30%) so the
   pair sits closer together with a tighter ~3% center gap.
   Per-user 100px vertical stagger preserved. RIGHT phone bottom
   lowered so its top no longer overlaps the subtext. */
@media (min-width: 1025px){
  .d2c-track-shot--entries{
    width: 30%;
    height: auto;
    top: calc(2.5% + 100px);
    left: 33%;
  }
  .d2c-track-shot--giveaway{
    width: 30%;
    height: auto;
    bottom: calc(2.5% + 40px);
    right: 4%;
    left: auto;
    top: auto;
  }
}

/* =================================================================
   MOBILE PERFORMANCE PASS — strip the heaviest GPU/CPU effects on
   small viewports. Mobile devices have ~5–10× lower fill-rate than
   desktop, and `backdrop-filter`, large multi-stop `box-shadow`,
   and stacked filter chains are the biggest jank culprits.
   ================================================================= */
@media (max-width: 1024px){
  /* Popup backdrop — kill the 12 px backdrop-filter blur, just dim. */
  .d2c-popup-backdrop{
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
    background: rgba(0,0,0,.55);
  }
  /* Floating chips — drop the 10 px backdrop-filter blur. The chip
     stays solid-colored which actually reads better on mobile. */
  .d2c-chip-float{
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
  }
  /* Giveaway-tile inner chip blur — drop. */
  .d2c-gtile::before{
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
  }
  /* Sheets: trim the triple-stack box-shadow to a single subtle drop.
     The browser was repainting all three shadow layers every scroll
     frame as the sheet's transform changed. */
  .d2c-sheet{
    box-shadow: 0 12px 28px rgba(0,0,0,.18) !important;
  }
  /* Band-card halo blurs — these are decorative static blurs behind
     the mini-phone band; drop on mobile so the GPU isn't blurring a
     full-stage layer that's only subtly visible. */
  .d2c-band-cards::before,
  .d2c-band-cards::after{
    filter: none !important;
  }
  /* BROWSE column carousel — slow the animation 3× and drop the
     mask-image (gradient mask is expensive on mobile GPU). Mask is
     decorative top/bottom fade; without it the columns just hard-
     edge — visually fine inside the rounded card. */
  .d2c-browse-col{
    -webkit-mask-image: none !important;
            mask-image: none !important;
  }
  .d2c-browse-col-track--up{
    animation-duration: 240s !important;
  }
  .d2c-browse-col-track--down{
    animation-duration: 260s !important;
  }
  /* Pause browse animations when the parent sheet is the BACK card in
     the stack (covered by another sheet). JS-driven only adds class
     `.d2c-sheet--bg` to non-front sheets on mobile (see d2c.js). */
  .d2c-sheet--browse.d2c-sheet--bg .d2c-browse-col-track{
    animation-play-state: paused !important;
  }

  /* ========== 2026-05-20 mobile-smoothness pass ==========
     Targeted CSS-only kills for the remaining heavy paint operations
     that real devices feel during scroll. Each rule names exactly
     what's being dropped and why. Decorative gradients/visuals are
     preserved — only the blur/paint-heavy effect on top of them is
     removed. All scoped under @media (max-width: 1024px). */

  /* Section 2 band — decorative blurred color blobs behind the
     sticky stage. `filter: blur(40px)` over a 280-580px element
     forces the compositor to redo the blur on every scroll tick
     (sticky parent's position changes relative to viewport). The
     radial-gradient stays — it's a soft color wash; without the
     blur it just reads slightly sharper. Animation (transform-only
     d2c-blob-drift-a/b) stays — that's cheap. */
  .d2c-band::before,
  .d2c-band::after{
    filter: none !important;
  }
  /* Halo behind the mini-phone (28-40px blur + d2c-halo-breath
     animation infinite). The opacity+transform animation is cheap;
     it's the 28px blur on a 380-640px element that's expensive.
     Drop just the filter — animation continues for the breathing
     effect. */
  .d2c-band-stage::before,
  .d2c-band.is-celebrating .d2c-band-stage::before{
    filter: none !important;
  }
  /* Features section ambient red glow (`filter: blur(20px)`). Static
     decorative. Drop on mobile — radial gradient remains. */
  .d2c-features-bg{
    filter: none !important;
  }
  /* Mini-phone carousel — JS sets `--blur` 0-2.8px per frame on side
     cards as the orbit lerps. Each card has its own compositor layer
     (5 cards × per-frame paint). On mobile the side cards are
     positioned closer to center anyway (mqCardsMobile multiplier
     0.55 in d2c.js); the slight blur on side cards isn't noticeable
     but the per-frame paint cost is. Drop the filter entirely on
     mobile — rotation still reads via the scale/rotateY transforms
     that ARE cheap. */
  .d2c-mp-card{
    filter: none !important;
  }
  /* ENTER card swipe-handle pulse — `d2c-enter-handle-pulse` animates
     a 3-stop box-shadow that expands a 22px halo each cycle.
     box-shadow animations are paint-only (no compositor optimization)
     and the ripple expansion is one of the heaviest per-frame effects
     on the page during the auto-swipe sequence. Drop on mobile —
     the swipe handle is still visible + slides, just no halo pulse. */
  .d2c-enter-swipe-handle{
    animation: none !important;
  }
  /* ENTER prompt + mini-phone prompt — both animate
     `background-position` (a paint property — triggers repaint of
     the underlying gradient every frame, even on the compositor).
     Drop the shine/shimmer; prompt text remains fully readable. */
  .d2c-enter-swipe-prompt,
  .d2c-mp-swipe-prompt{
    animation: none !important;
    background-position: 50% 50% !important;
  }
}

/* prefers-reduced-motion catch-all for blurs/effects we couldn't kill
   per-element without breaking the desktop look. */
@media (prefers-reduced-motion: reduce){
  .d2c-popup-backdrop,
  .d2c-chip-float,
  .d2c-gtile::before{
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
  }
  .d2c-sheet{
    box-shadow: 0 8px 20px rgba(0,0,0,.15) !important;
  }
  /* Disable the always-on infinite browse-column scrolling animation —
     reduced-motion users get static columns. */
  .d2c-browse-col-track{
    animation: none !important;
  }
}
