/* =========================================================
   Echo v17.2 — Motion Layer (additive, namespaced, reversible)
   Calibration: intimate · reflective · present · unmistakable
   ---------------------------------------------------------
   DELTA v17.1 → v17.2
   - NEW: Scroll progress bar (3 px forest gradient, fixed top)
   - NEW: Frosted nav shadow after scrollY > 40 px
   - NEW: Section-level fade + slide-up on viewport enter
     (every .panel now rises 48 px with blur handoff)
   - NEW: Card scale-up-from-invisible (opacity 0 → 1, scale
     .82 → 1). Replaces v17.1's .55/.965 pre-state with a
     stronger cinematic lift.
   - NEW: Hero staged sequence — longer range (40 px), longer
     cascade (up to 1.15 s tail), cubic hold.
   - NEW: Text word-split reveal on h2.display (each word
     arrives staggered as the heading enters view).
   - NEW: 3-D micro-tilt on .demo-card / .insight (desktop
     pointer:fine — 6° max, rAF-throttled).
   - NEW: Magnetic CTA pull (.btn-primary follows pointer
     within 40 px radius — 6 px max deflection).
   - NEW: Insight numeric count-up on reveal (handled by JS).
   - NEW: Sticky reveal momentum — sections overshoot then
     settle (0.25 s hold then .985 → 1.0 scale settle).

   SAFETY CONTRACT (unchanged)
   - All effects gated behind `body.mx-ready`.
   - Respects `prefers-reduced-motion: reduce` (blanket off).
   - Respects `<html data-no-motion="1">` escape hatch.
   - No layout-affecting properties on ancestors of sticky/fixed.
   - Does not rename or require any new DOM contracts.
   ========================================================= */

/* =========================================================
   SCROLL PROGRESS BAR — 3 px, forest gradient, fixed top
   ========================================================= */
body.mx-ready .mx-progress{
  position: fixed;
  top: 0; left: 0; right: 0;
  height: 3px;
  z-index: 9999;
  pointer-events: none;
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--forest-glow) 90%, transparent) 0%,
    var(--forest) 50%,
    var(--forest-deep) 100%);
  transform: scaleX(var(--mx-progress, 0));
  transform-origin: left center;
  will-change: transform;
  transition: opacity .25s var(--ease);
  opacity: .92;
  box-shadow: 0 1px 3px color-mix(in srgb, var(--forest-deep) 45%, transparent);
}
/* Fade the bar back out when the user is at the very top */
body.mx-ready .mx-progress[data-at-top="1"]{ opacity: 0 }

/* =========================================================
   FROSTED NAV — activates once scrolled past 40 px
   (nav already has its own base styling in theme.css — we only
    layer a shadow + stronger backdrop blur; we never touch
    its layout, height, or positioning)
   ========================================================= */
body.mx-ready .nav{
  transition:
    background-color .4s var(--ease),
    box-shadow .4s var(--ease),
    backdrop-filter .4s var(--ease),
    border-color .4s var(--ease);
}
body.mx-ready .nav.mx-scrolled{
  background-color: color-mix(in srgb, var(--paper) 82%, transparent);
  -webkit-backdrop-filter: saturate(1.2) blur(14px);
          backdrop-filter: saturate(1.2) blur(14px);
  box-shadow:
    0 1px 0 color-mix(in srgb, var(--rule) 70%, transparent),
    0 12px 32px -18px color-mix(in srgb, var(--forest-deep) 30%, transparent);
}

/* =========================================================
   REVEAL — extended blur handoff on existing .reveal
   ========================================================= */
body.mx-ready .reveal{
  filter: blur(7px);
  transition:
    opacity 1s var(--ease),
    transform 1s var(--ease),
    filter 1.1s var(--ease);
}
body.mx-ready .reveal.in{ filter: blur(0) }

/* =========================================================
   SECTION-LEVEL FADE + SLIDE-UP — NEW in v17.2
   Every major .panel rises from 48 px below, with a gentle
   blur, when it enters viewport. Subtle overshoot then settle.
   ========================================================= */
body.mx-ready .panel:not(.mx-in-view){
  opacity: 0;
  transform: translateY(48px);
  filter: blur(4px);
}
body.mx-ready .panel{
  transition:
    opacity 1.1s var(--ease),
    transform 1.1s var(--ease),
    filter 1s var(--ease),
    box-shadow 1s var(--ease),
    border-color .8s var(--ease);
  will-change: transform, opacity;
}
body.mx-ready .mx-in-view.panel{
  opacity: 1;
  transform: translateY(0);
  filter: blur(0);
  box-shadow: 0 22px 58px -28px color-mix(in srgb, var(--forest-deep) 52%, transparent);
}

/* Hero section is NOT hidden on load — hero has its own staged reveal */
body.mx-ready .hero{ opacity: 1; transform: none; filter: none }

/* Subscribe band — gentler variant */
body.mx-ready .subscribe-band:not(.mx-in-view){
  opacity: 0;
  transform: translateY(28px);
}
body.mx-ready .subscribe-band{
  transition: opacity 1s var(--ease), transform 1s var(--ease);
}
body.mx-ready .mx-in-view.subscribe-band{
  opacity: 1;
  transform: translateY(0);
}

/* =========================================================
   HERO STAGED SEQUENCE — stronger cadence in v17.2
   ========================================================= */
body.mx-ready .mx-hero .hero-kicker,
body.mx-ready .mx-hero .hero-title,
body.mx-ready .mx-hero .hero-sub,
body.mx-ready .mx-hero .hero-meta,
body.mx-ready .mx-hero .hero-ctas,
body.mx-ready .mx-hero .hero-phone-col{
  opacity: 0;
  transform: translateY(40px);
  animation: mxHeroIn 1.25s cubic-bezier(.2,.7,.2,1) forwards;
}
body.mx-ready .mx-hero .hero-kicker                     { animation-delay: .10s }
body.mx-ready .mx-hero .hero-title                      { animation-delay: .28s }
body.mx-ready .mx-hero .hero-sub:nth-of-type(1)         { animation-delay: .50s }
body.mx-ready .mx-hero .hero-sub:nth-of-type(2)         { animation-delay: .68s }
body.mx-ready .mx-hero .hero-meta                       { animation-delay: .86s }
body.mx-ready .mx-hero .hero-ctas                       { animation-delay: 1.02s }
body.mx-ready .mx-hero .hero-phone-col                  {
  animation-delay: .38s;
  transform: translateY(52px) scale(.96);
}

@keyframes mxHeroIn{
  to{ opacity: 1; transform: translateY(0) scale(1) }
}

/* =========================================================
   HERO TITLE GLINT — italic signature loops every 16 s
   ========================================================= */
body.mx-ready .mx-hero .hero-title em{
  background-image: linear-gradient(120deg,
    var(--forest-deep) 0%,
    var(--forest-deep) 34%,
    color-mix(in srgb, var(--forest-glow) 82%, var(--forest-deep)) 50%,
    var(--forest-deep) 66%,
    var(--forest-deep) 100%);
  background-size: 260% 100%;
  background-position: 100% 0;
  -webkit-background-clip: text;
          background-clip: text;
  animation: mxGlint 16s var(--ease) 1.4s infinite;
}
@supports not ((-webkit-background-clip: text) or (background-clip: text)){
  body.mx-ready .mx-hero .hero-title em{ background: none; color: var(--forest-deep) }
}
@keyframes mxGlint{
  0%   { background-position: 100% 0 }
  18%  { background-position: 0% 0 }
  28%  { background-position: -30% 0 }
  100% { background-position: -30% 0 }
}

/* =========================================================
   HERO-KICKER DOT — ambient signature pulse
   ========================================================= */
body.mx-ready .mx-hero .hero-kicker{ position: relative }
body.mx-ready .mx-hero .hero-kicker::before{
  animation: mxDotPulse 3.2s ease-in-out infinite;
}
@keyframes mxDotPulse{
  0%, 100% { opacity: 1 }
  50%      { opacity: .45 }
}

/* =========================================================
   PHONE MOCK IDLE BREATHE
   ========================================================= */
body.mx-ready .mx-hero .demo-phone{
  transform-origin: 50% 60%;
  animation: mxPhoneBreathe 6.5s ease-in-out 0s infinite alternate;
}
@keyframes mxPhoneBreathe{
  from{ transform: translateY(0)     scale(.996) }
  to  { transform: translateY(-10px) scale(1)    }
}

/* =========================================================
   CARD SCALE-UP FROM INVISIBLE — NEW in v17.2
   Opacity 0, scale .82, translate 60 px → 1/1/0. Visibly
   cinematic. .qcard and .step stay excluded.
   ========================================================= */
body.mx-ready .demo-card:not(.mx-in-view),
body.mx-ready .aud-card:not(.mx-in-view),
body.mx-ready .insight:not(.mx-in-view),
body.mx-ready .phase:not(.mx-in-view){
  opacity: 0;
  transform: translateY(60px) scale(.82);
  filter: blur(3px);
}
body.mx-ready .demo-card,
body.mx-ready .aud-card,
body.mx-ready .insight,
body.mx-ready .phase{
  transition:
    transform 1.1s cubic-bezier(.2,.7,.2,1),
    opacity 1s var(--ease),
    filter .9s var(--ease),
    box-shadow .45s var(--ease),
    border-color .5s var(--ease);
}
body.mx-ready .mx-in-view.demo-card,
body.mx-ready .mx-in-view.aud-card,
body.mx-ready .mx-in-view.insight,
body.mx-ready .mx-in-view.phase{
  opacity: 1;
  transform: translateY(0) scale(1);
  filter: blur(0);
}

/* =========================================================
   CARD HOVER — lift + tilt combines with JS `--mx-tx/--mx-ty`
   ========================================================= */
body.mx-ready .demo-card{ position: relative; transform-style: preserve-3d }
body.mx-ready .demo-card:hover{
  transform: translateY(-6px)
             rotateX(calc(var(--mx-ty, 0) * -1deg))
             rotateY(calc(var(--mx-tx, 0) * 1deg));
  box-shadow: 0 30px 60px -24px color-mix(in srgb, var(--forest-deep) 52%, transparent);
  border-color: color-mix(in srgb, var(--forest) 55%, var(--rule));
}
body.mx-ready .aud-card{
  position: relative;
  transition:
    transform .4s var(--ease),
    box-shadow .4s var(--ease),
    border-color .5s var(--ease);
}
body.mx-ready .aud-card:hover{
  transform: translateY(-5px);
  box-shadow: 0 22px 44px -20px color-mix(in srgb, var(--ink) 32%, transparent);
  border-color: color-mix(in srgb, var(--forest) 40%, var(--rule));
}
body.mx-ready .insight{
  position: relative;
  transform-style: preserve-3d;
  transition:
    transform .4s var(--ease),
    box-shadow .4s var(--ease),
    border-color .5s var(--ease);
}
body.mx-ready .insight:hover{
  transform: translateY(-5px)
             rotateX(calc(var(--mx-ty, 0) * -0.8deg))
             rotateY(calc(var(--mx-tx, 0) * 0.8deg));
  box-shadow: 0 26px 50px -22px color-mix(in srgb, var(--forest-deep) 45%, transparent);
  border-color: color-mix(in srgb, var(--forest) 55%, var(--rule));
}

/* .qcard hover lift only — no entry pre-state (quotes rotate every 7 s) */
body.mx-ready .qcard{
  transition:
    transform .4s var(--ease),
    box-shadow .4s var(--ease),
    border-color .4s var(--ease);
}
body.mx-ready .qcard:hover{
  transform: translateY(-3px);
  box-shadow: 0 16px 38px -18px color-mix(in srgb, var(--forest-deep) 38%, transparent);
}

/* =========================================================
   CURSOR SPOTLIGHT (opt-in via .mx-spot from JS; pointer:fine)
   ========================================================= */
body.mx-ready .mx-spot{ isolation: isolate }
body.mx-ready .mx-spot::after{
  content: "";
  position: absolute; inset: 0;
  border-radius: inherit;
  background: radial-gradient(240px circle at var(--mx-x, 50%) var(--mx-y, 50%),
    color-mix(in srgb, var(--forest-glow) 28%, transparent) 0%,
    transparent 62%);
  pointer-events: none;
  opacity: 0;
  transition: opacity .4s var(--ease);
  z-index: 0;
}
body.mx-ready .mx-spot > *{ position: relative; z-index: 1 }
body.mx-ready .mx-spot:hover::after{ opacity: 1 }

/* =========================================================
   MAGNETIC CTA — primary button pulls toward pointer
   (JS sets --mx-mag-x/--mx-mag-y within a 40 px radius)
   ========================================================= */
body.mx-ready .btn-primary{
  transition:
    transform .25s cubic-bezier(.2,.7,.2,1),
    box-shadow .35s var(--ease);
  transform: translate3d(var(--mx-mag-x, 0), var(--mx-mag-y, 0), 0);
}
body.mx-ready .btn-primary:hover{
  box-shadow: 0 22px 40px -14px color-mix(in srgb, var(--forest-deep) 62%, transparent);
}

/* =========================================================
   WORD-SPLIT REVEAL ON h2.display (each word staggers in
   once JS wraps the text in .mx-w spans and the parent
   heading crosses the viewport threshold)
   ========================================================= */
body.mx-ready h2.display .mx-w{
  display: inline-block;
  opacity: 0;
  transform: translateY(28px);
  filter: blur(3px);
  transition:
    opacity .7s var(--ease),
    transform .7s cubic-bezier(.2,.7,.2,1),
    filter .7s var(--ease);
  transition-delay: calc(var(--mx-wi, 0) * 70ms);
}
body.mx-ready h2.display.mx-words-in .mx-w{
  opacity: 1;
  transform: translateY(0);
  filter: blur(0);
}

/* =========================================================
   FOREST CTA PANEL — ambient gradient drift
   ========================================================= */
body.mx-ready .panel.forest{
  background-size: 220% 220%;
  background-position: 0% 0%;
}
body.mx-ready .mx-in-view.panel.forest{
  animation: mxForestDrift 13s ease-in-out infinite alternate;
}
@keyframes mxForestDrift{
  from{ background-position: 0% 0%     }
  to  { background-position: 100% 100% }
}

/* =========================================================
   NAV LINK UNDERLINE GROW ON HOVER
   ========================================================= */
body.mx-ready .nav-links a:not(.nav-cta){ position: relative }
body.mx-ready .nav-links a:not(.nav-cta)::after{
  content: "";
  position: absolute; left: 12px; right: 12px; bottom: 4px;
  height: 1.5px;
  background: var(--forest);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform .4s var(--ease);
  pointer-events: none;
}
body.mx-ready .nav-links a:not(.nav-cta):hover::after{ transform: scaleX(1) }

/* =========================================================
   BRAND TILE GLOW ON HOVER
   ========================================================= */
body.mx-ready .brand-tile{
  transition:
    box-shadow .35s var(--ease),
    transform .35s var(--ease);
}
body.mx-ready .brand-tile:hover{
  transform: translateY(-2px);
  box-shadow: 0 14px 32px -14px color-mix(in srgb, var(--forest-deep) 55%, transparent);
}

/* =========================================================
   INSIGHT NUMERIC EYEBROW — arrival tag pulse
   ========================================================= */
body.mx-ready .mx-in-view.insight .inum{
  animation: mxTag 1.6s var(--ease) .1s both;
}
@keyframes mxTag{
  from{ letter-spacing: .04em; opacity: .3 }
  to  { letter-spacing: .08em; opacity: 1  }
}

/* =========================================================
   SCORE BAR SHIMMER (flywheel fill)
   ========================================================= */
body.mx-ready .fly-scores .fill{
  position: relative;
  overflow: hidden;
}
body.mx-ready .fly-scores .fill::after{
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(90deg,
    transparent 0%,
    color-mix(in srgb, #fff 42%, transparent) 50%,
    transparent 100%);
  transform: translateX(-100%);
  animation: mxBarShimmer 3.6s ease-in-out 1s infinite;
  pointer-events: none;
}
@keyframes mxBarShimmer{
  0%   { transform: translateX(-100%) }
  55%  { transform: translateX(200%)  }
  100% { transform: translateX(200%)  }
}

/* =========================================================
   REDUCED MOTION — blanket override
   ========================================================= */
@media (prefers-reduced-motion: reduce){
  body.mx-ready .mx-progress{ display: none }
  body.mx-ready .nav.mx-scrolled{ backdrop-filter: none; -webkit-backdrop-filter: none }
  body.mx-ready .reveal{ filter: none; transition: none }
  body.mx-ready .panel:not(.mx-in-view){ opacity: 1; transform: none; filter: none }
  body.mx-ready .subscribe-band:not(.mx-in-view){ opacity: 1; transform: none }
  body.mx-ready .mx-hero .hero-kicker,
  body.mx-ready .mx-hero .hero-title,
  body.mx-ready .mx-hero .hero-sub,
  body.mx-ready .mx-hero .hero-meta,
  body.mx-ready .mx-hero .hero-ctas,
  body.mx-ready .mx-hero .hero-phone-col{
    opacity: 1; transform: none; animation: none;
  }
  body.mx-ready .mx-hero .hero-kicker::before{ animation: none }
  body.mx-ready .mx-hero .hero-title em{ background: none; color: var(--forest-deep); animation: none }
  body.mx-ready .mx-hero .demo-phone{ animation: none; transform: none }
  body.mx-ready .demo-card:not(.mx-in-view),
  body.mx-ready .aud-card:not(.mx-in-view),
  body.mx-ready .insight:not(.mx-in-view),
  body.mx-ready .phase:not(.mx-in-view){
    transform: none; opacity: 1; filter: none;
  }
  body.mx-ready .demo-card:hover,
  body.mx-ready .aud-card:hover,
  body.mx-ready .insight:hover,
  body.mx-ready .qcard:hover,
  body.mx-ready .brand-tile:hover{ transform: none }
  body.mx-ready .btn-primary{ transform: none }
  body.mx-ready .btn-primary:hover{ transform: none }
  body.mx-ready .mx-spot::after{ display: none }
  body.mx-ready .mx-in-view.panel{ box-shadow: none }
  body.mx-ready .mx-in-view.panel.forest{ animation: none }
  body.mx-ready .mx-in-view.insight .inum{ animation: none }
  body.mx-ready .fly-scores .fill::after{ animation: none; display: none }
  body.mx-ready .nav-links a:not(.nav-cta)::after{ display: none }
  body.mx-ready h2.display .mx-w{ opacity: 1; transform: none; filter: none; transition: none }
}

/* =========================================================
   HIGH CONTRAST / FORCED COLORS — suppress decoration
   ========================================================= */
@media (forced-colors: active){
  body.mx-ready .mx-progress{ display: none }
  body.mx-ready .mx-spot::after{ display: none }
  body.mx-ready .fly-scores .fill::after{ display: none }
  body.mx-ready .mx-in-view.panel{ box-shadow: none }
  body.mx-ready .mx-hero .hero-kicker::before{ animation: none }
  body.mx-ready .nav.mx-scrolled{ backdrop-filter: none; -webkit-backdrop-filter: none }
}

/* =========================================================
   PRINT — silence decoration
   ========================================================= */
@media print{
  body.mx-ready .mx-progress{ display: none !important }
  body.mx-ready .mx-spot::after,
  body.mx-ready .fly-scores .fill::after,
  body.mx-ready .nav-links a:not(.nav-cta)::after{ display: none !important }
  body.mx-ready .mx-in-view.panel{ box-shadow: none !important }
  body.mx-ready .mx-hero .hero-kicker::before{ animation: none !important }
  body.mx-ready .nav.mx-scrolled{ backdrop-filter: none !important; -webkit-backdrop-filter: none !important; box-shadow: none !important }
}
