/* Stowe Holdings: motion layer for the Enterprise Balanced page.
   Loaded after enterprise.css. Behaviour lives in ../../js/pages/enterprise-motion.js.

   How it works
   - An inline script in <head> adds html.motion (only when reduced motion is off).
   - enterprise-motion.js tags elements with .m (fade + rise), .m-r (fade + slide from the right),
     .m-img (picture wipes open), .m-bar (accent rule draws in), and adds .in when they scroll into view.
   - Once an element has finished its entrance the classes come off again, so the original
     hover transitions in enterprise.css take back over.
   - Individual transform properties (translate / scale / rotate) are used throughout so they
     stack with the existing `transform` hover effects instead of replacing them.
   - With prefers-reduced-motion, html.motion is never set: everything is simply shown. */

:root {
  --eo: cubic-bezier(0.16, 1, 0.3, 1);      /* ease-out: entrances */
  --eio: cubic-bezier(0.7, 0, 0.2, 1);      /* ease-in-out: wipes and rules */
}

/* =========================================================
   Hero: headline split into lines (markup is always present, motion is optional)
   ========================================================= */
.hero h1 .ln { display: block; overflow: hidden; padding-bottom: 0.12em; margin-bottom: -0.12em; }
.hero h1 .ln, .hero h1 .ln-i { background: none; color: #fff; -webkit-text-fill-color: currentColor; }
.hero h1 .ln-i { display: block; }

/* ---- Hero intro on load ---- */
.motion .hero .eyebrow,
.motion .hero .lead,
.motion .hero-cta,
.motion .ledger > div,
.motion .trust p,
.motion .trust li {
  opacity: 0; translate: 0 24px;
  transition: opacity 0.9s var(--eo) var(--d, 0s), translate 1s var(--eo) var(--d, 0s);
}
.motion .hero h1 .ln-i { translate: 0 110%; transition: translate 1.1s var(--eo) var(--d, 0s); }
.motion .show { opacity: 0; translate: 56px 0; transition: opacity 1.1s var(--eo) 0.3s, translate 1.3s var(--eo) 0.3s; }
.motion .hero-photo { opacity: 0; scale: 1.1; transition: opacity 1.8s ease 0.1s, scale 2.6s var(--eo) 0.1s; }

.motion .hero .eyebrow { --d: 0.05s; }
.motion .hero h1 .ln:nth-child(1) .ln-i { --d: 0.12s; }
.motion .hero h1 .ln:nth-child(2) .ln-i { --d: 0.22s; }
.motion .hero h1 .ln:nth-child(3) .ln-i { --d: 0.32s; }
.motion .hero .lead { --d: 0.5s; }
.motion .hero-cta { --d: 0.62s; }
.motion .trust p { --d: 1.15s; }

.motion .hero.h-in .eyebrow,
.motion .hero.h-in .lead,
.motion .hero.h-in .hero-cta,
.motion .hero.h-in .ledger > div,
.motion .hero.h-in .trust p,
.motion .hero.h-in .trust li,
.motion .hero.h-in .show { opacity: 1; translate: 0 0; }
.motion .hero.h-in h1 .ln-i { translate: 0 0; }
.motion .hero.h-in .hero-photo { opacity: var(--photo-o, 1); scale: 1; }

/* the photo layer is taller than the hero so it can drift with the scroll */
.motion .hero-photo { top: -14%; }

/* pointer-led light behind the console */
.motion .hero::after {
  background:
    radial-gradient(36% 50% at var(--gx, 78%) var(--gy, 42%), var(--glow-a), transparent 70%),
    radial-gradient(34% 46% at 0% 100%, var(--glow-b), transparent 70%);
}

/* a gold scan runs along the facts ledger once the intro lands */
.ledger { position: relative; }
@media (prefers-reduced-motion: no-preference) {
  .motion .ledger::before {
    content: ""; position: absolute; left: 0; top: -1px; width: 100%; height: 1px;
    background: var(--grad); transform-origin: left; scale: 0 1; opacity: 0; pointer-events: none;
  }
  .motion .hero.h-in .ledger::before { animation: ledger-scan 2.2s var(--eio) 0.85s both; }
}
@keyframes ledger-scan {
  0% { scale: 0 1; opacity: 1; }
  60% { scale: 1 1; opacity: 1; }
  100% { scale: 1 1; opacity: 0; }
}

/* =========================================================
   Scroll reveals
   ========================================================= */
.motion .m {
  opacity: 0; translate: 0 32px;
  transition:
    opacity 0.9s var(--eo) var(--d, 0s),
    translate 1s var(--eo) var(--d, 0s),
    background-color 0.2s, color 0.2s, border-color 0.2s;
}
.motion .m.m-r { translate: 48px 0; }
.motion .m.in { opacity: 1; translate: 0 0; }

/* pictures wipe open top to bottom while the photo settles from a slight zoom.
   The clip sits on the <img>, not the observed <figure>: Chromium's IntersectionObserver
   counts a target's own clip-path, so a fully clipped figure never "enters" and stays hidden. */
.motion .m-img img {
  clip-path: inset(0 0 100% 0); scale: 1.16;
  transition: clip-path 1.25s var(--eio) var(--d, 0s), scale 1.8s var(--eo) var(--d, 0s), transform 0.6s;
}
.motion .m-img.in img { clip-path: inset(0 0 0 0); scale: 1; }

/* coloured top rules draw in from the left */
.motion .serve-c.m-bar::before,
.motion .cell.m-bar::before,
.motion .reg > li.m-bar::after {
  transform-origin: left; scale: 0 1;
  transition: scale 1.1s var(--eio) var(--d, 0s);
}
.motion .serve-c.m-bar.in::before,
.motion .cell.m-bar.in::before,
.motion .reg > li.m-bar.in::after { scale: 1 1; }
.motion .her-figs.m-bar, .motion .comp.m-bar { background-size: 0 2px; transition: background-size 1.5s var(--eio) 0.1s; }
.motion .her-figs.m-bar.in, .motion .comp.m-bar.in { background-size: 100% 2px; }

/* compliance check marks fill in after their card lands */
.motion .comp li.m .st::before { background-size: 0 0; transition: background-size 0.5s cubic-bezier(0.3, 1.6, 0.5, 1) calc(var(--d, 0s) + 0.5s); }
.motion .comp li.m.in .st::before { background-size: 6px 6px; }

/* =========================================================
   Heritage timeline: a gold rule fills as you scroll, squares pop in
   ========================================================= */
.motion .tl::after {
  content: ""; position: absolute; left: 0; right: 0; top: 6px; height: 2px;
  background: var(--grad-deep); transform-origin: left; scale: var(--tl-p, 0) 1; pointer-events: none;
}
@media (max-width: 1100px) {
  .motion .tl::after { left: 6px; right: auto; top: 0; bottom: 0; width: 2px; height: auto; transform-origin: top; scale: 1 var(--tl-p, 0); }
}
.motion .tl li.m::before {
  scale: 0; rotate: 45deg;
  transition: scale 0.6s cubic-bezier(0.3, 1.6, 0.5, 1) calc(var(--d, 0s) + 0.15s), rotate 0.8s var(--eo) calc(var(--d, 0s) + 0.15s);
}
.motion .tl li.m.in::before { scale: 1; rotate: 0deg; }

/* parallax pictures: taller than their frame so they can drift */
.motion .lead-band figure, .motion .fp-img { overflow: hidden; }
.motion [data-px] { top: -8%; bottom: auto; height: 116%; translate: 0 var(--py, 0px); }

/* integrations glow drifts against the scroll */
.motion .ix::before { translate: 0 var(--ix-y, 0px); }

/* the Stowe hub breathes while the section is on screen (paused with the section's Pause button) */
@media (prefers-reduced-motion: no-preference) {
  .motion .ix.is-live .reg .hub::before {
    content: ""; position: absolute; inset: 0; pointer-events: none;
    animation: hub-ping 2.8s ease-out infinite;
  }
  .ix:has(#ixPause[aria-pressed="true"]) .reg .hub::before { animation-play-state: paused; }
}
@keyframes hub-ping {
  0% { box-shadow: inset 0 0 0 0 rgba(216, 185, 121, 0.55); }
  100% { box-shadow: inset 0 0 0 36px rgba(216, 185, 121, 0); }
}
/* a partner tile that lights up eases in rather than snapping */
.reg > li.on b { animation: tile-on 0.45s var(--eo); }
@keyframes tile-on { from { translate: 0 6px; opacity: 0.4; } }

/* =========================================================
   Pointer spotlight on cards (fine pointers only; JS adds .sp)
   ========================================================= */
.news-c, .vid { position: relative; }
.sp::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 2;
  background: radial-gradient(380px circle at var(--mx, 50%) var(--my, 50%), var(--sp-c, rgba(31, 91, 255, 0.08)), transparent 65%);
  opacity: 0; transition: opacity 0.35s;
}
.sp:hover::after { opacity: 1; }
.cell-dark.sp { --sp-c: rgba(143, 176, 255, 0.14); }
/* the partner tiles already use ::after for their rule, so their light goes on ::before (.sp-b) */
.sp-b::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(260px circle at var(--mx, 50%) var(--my, 50%), rgba(143, 176, 255, 0.16), transparent 65%);
  opacity: 0; transition: opacity 0.35s;
}
.sp-b.on::before { background: radial-gradient(260px circle at var(--mx, 50%) var(--my, 50%), rgba(255, 255, 255, 0.18), transparent 65%); }
.sp-b:hover::before { opacity: 1; }

/* =========================================================
   Small interactions
   ========================================================= */
/* primary buttons: a light sweep on hover */
.btn-primary { position: relative; overflow: hidden; isolation: isolate; }
.btn-primary::after {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: linear-gradient(110deg, transparent 30%, rgba(255, 255, 255, 0.28) 50%, transparent 70%);
  translate: -120% 0; transition: translate 0.75s var(--eo);
}
.btn-primary:hover::after { translate: 120% 0; }
.btn:active { scale: 0.98; }

/* inline links: arrow nudges on hover */
.link > [aria-hidden] { display: inline-block; transition: translate 0.25s var(--eo); }
.link:hover > [aria-hidden] { translate: 4px 0; }

/* header: lifts off the page once you scroll, with a thin progress rule on narrow screens */
.hdr { transition: box-shadow 0.3s, background-color 0.3s; }
.hdr.scrolled {
  background: rgba(255, 255, 255, 0.88);
  -webkit-backdrop-filter: saturate(1.4) blur(12px); backdrop-filter: saturate(1.4) blur(12px);
  box-shadow: 0 14px 32px -22px rgba(11, 22, 38, 0.4);
}
.hdr::after {
  content: ""; position: absolute; left: 0; bottom: -1px; width: 100%; height: 2px; pointer-events: none;
  background: var(--grad); transform-origin: left; scale: var(--pg, 0) 1;
}
@media (min-width: 1200px) { .hdr::after { content: none; } } /* the side rail shows progress there */

/* burger turns into a close mark */
.burger span, .burger span::before, .burger span::after { transition: background-color 0.2s, top 0.25s var(--eo), rotate 0.3s var(--eo); }
.burger[aria-expanded="true"] span { background: transparent; }
.burger[aria-expanded="true"] span::before { top: 0; rotate: 45deg; }
.burger[aria-expanded="true"] span::after { top: 0; rotate: -45deg; }

/* mega menu feature picture */
.mega-feat img { transition: scale 0.9s var(--eo), opacity 0.4s; }
.mega-feat:hover img { scale: 1.06; opacity: 0.45; }

@media (prefers-reduced-motion: no-preference) {
  /* mega menus and the mobile sheet slide down, their links follow in sequence */
  .mega.open { animation: drop-in 0.34s var(--eo) both; }
  .mega.open .mega-col > *, .mega.open .mega-feat { animation: rise-in 0.5s var(--eo) both; }
  .mega.open .mega-col:nth-child(1) > * { animation-delay: 0.04s; }
  .mega.open .mega-col:nth-child(2) > * { animation-delay: 0.09s; }
  .mega.open .mega-col:nth-child(3) > * { animation-delay: 0.14s; }
  .mega.open .mega-feat { animation-delay: 0.19s; }
  .sheet.open { animation: drop-in 0.34s var(--eo) both; }
  .sheet.open > * { animation: rise-in 0.45s var(--eo) both; animation-delay: calc(var(--i, 0) * 18ms + 40ms); }

  /* call-to-action band: a single sweep of light when it arrives */
  .cta-band { position: relative; overflow: hidden; isolation: isolate; }
  .motion .cta-band::before {
    content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
    background: linear-gradient(105deg, transparent 35%, rgba(255, 255, 255, 0.16) 50%, transparent 65%);
    translate: -100% 0;
  }
  .motion .cta-band.in::before { animation: sweep 1.8s var(--eio) 0.2s both; }

  /* live dots breathe a few times on arrival (kept under 5s of movement, WCAG 2.2.2) */
  .dot { animation: dot-pulse 1.6s ease-in-out 1s 3; }
}
@keyframes drop-in { from { opacity: 0; translate: 0 -10px; } }
@keyframes rise-in { from { opacity: 0; translate: 0 10px; } }
@keyframes sweep { from { translate: -100% 0; } to { translate: 100% 0; } }
@keyframes dot-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(24, 160, 88, 0.5); }
  50% { box-shadow: 0 0 0 5px rgba(24, 160, 88, 0); }
}
