/* =========================================================================
   XONWARE — Motion Layer CSS (Foundation Pass)
   ----------------------------------------------------------------------
   Supporting styles for /assets/js/motion.js. Strictly additive.
   ========================================================================= */

/* ---- Lenis smooth-scroll hooks --------------------------------------- */
/* Lenis sets `class="lenis"` on <html> when initialised. */
html.lenis {
  height: auto;
}
html.lenis.lenis-smooth {
  scroll-behavior: auto !important;
}
html.lenis.lenis-smooth [data-lenis-prevent] {
  overscroll-behavior: contain;
}
html.lenis.lenis-stopped {
  overflow: hidden;
}
html.lenis.lenis-scrolling iframe {
  pointer-events: none;
}

/* ---- Word-stagger reveal --------------------------------------------- */
/* While JS is still loading, words are inline-flow — no FOUC. */
[data-motion-words-init] .motion-word {
  display: inline-block;
  opacity: 0;
  transform: translateY(0.5em);
  transition:
    opacity .7s cubic-bezier(.22, .7, .2, 1),
    transform .8s cubic-bezier(.22, .7, .2, 1);
  will-change: opacity, transform;
}
[data-motion-words-init].is-in .motion-word {
  opacity: 1;
  transform: translateY(0);
}

/* Headlines often contain <em> with serif italic — preserve descent. */
[data-motion-words-init] em .motion-word,
[data-motion-words-init] strong .motion-word,
[data-motion-words-init] span .motion-word {
  /* inherit transition + delay from parent .motion-word rule */
}

/* ---- Tilt prep ------------------------------------------------------- */
/* The motion.js handler sets transform-style / will-change / perspective
   on each [data-tilt] target inline. The parent should be position:
   relative so the bounding-rect math is stable; this is enforced where
   needed via existing site CSS (e.g. .xa-bob is already relative). */
[data-tilt] {
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}

/* When tilted, the inner shot deserves a soft drop shadow that intensifies
   slightly to suggest depth. Only applies to the XIMS dashboard frame. */
.xa-frame[data-tilt] {
  box-shadow:
    0 30px 60px -20px rgba(15, 20, 50, .25),
    0 18px 36px -18px rgba(15, 20, 50, .18);
  transition:
    transform .35s cubic-bezier(.22, .7, .2, 1),
    box-shadow .4s ease;
}
.xa-bob:hover > .xa-frame[data-tilt] {
  box-shadow:
    0 50px 80px -22px rgba(15, 20, 50, .32),
    0 24px 48px -20px rgba(15, 20, 50, .22),
    0 0 0 1px rgba(26, 35, 126, .06);
}

/* ---- Reduced-motion: instant, static, accessible ---------------------- */
@media (prefers-reduced-motion: reduce) {
  [data-motion-words-init] .motion-word {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  [data-tilt] {
    transform: none !important;
    transition: none !important;
  }
  html.lenis {
    /* Fall back to native scrolling. motion.js won't init Lenis under reduce
       anyway, but if a third party did, suppress the smooth-scroll override. */
    scroll-behavior: auto !important;
  }
}

/* =========================================================================
   PHASE 2 — Per-section choreography
   ========================================================================= */

/* ---- Sticky-pinned section (used on home scale band) ----------------- */
/* Pattern: an outer .xa-pin-host that's taller than the viewport, with an
   inner .xa-pin-stage that sticks to the top of the viewport while the
   user scrolls through the host's extra height. Creates a "section
   lingers in place" effect — Stripe's most-used scroll move. */
.xa-pin-host {
  position: relative;
  /* Host is 1.2x viewport-height — that's 0.2vh of extra scroll for the pin.
     Content stays naturally sized inside the stage; pin duration ~ host minus
     stage height = brief but deliberate "lingering" effect. */
  min-height: 120vh;
}
.xa-pin-stage {
  position: sticky;
  top: 0;
  /* Top-align the content so it's immediately visible when the user enters
     the section. No more 100vh forced height with flex centering — that
     created empty space above the heading because content was centred
     vertically before the stage actually pinned. */
  display: block;
  padding-block: clamp(60px, 6vw, 100px);
}
/* Mobile: drop the pin so the user can scroll naturally — pins frustrate
   on small screens with vertical stats lists. */
@media (max-width: 920px) {
  .xa-pin-host {
    min-height: 0;
  }
  .xa-pin-stage {
    position: static;
    min-height: 0;
    display: block;
  }
}
/* Don't double-apply the section's own vertical padding inside the
   stage — the stage's flex centring handles spacing. */
.xa-pin-host > .xa-pin-stage > .xa-wide {
  padding-block: clamp(40px, 5vw, 80px);
}

/* ---- Upgraded KPI tile choreography ---------------------------------- */
/* Replace the existing fade-up on .xa-kpi (inside the pin host) with a
   more cinematic per-tile entrance: subtle scale + clipped reveal +
   stagger driven by nth-child. */
.xa-pin-host .xa-kpi {
  opacity: 0;
  transform: translateY(28px) scale(.96);
  transition:
    opacity .85s cubic-bezier(.22, .7, .2, 1),
    transform .85s cubic-bezier(.22, .7, .2, 1);
  will-change: opacity, transform;
}
.xa-pin-host .xa-kpis.is-in .xa-kpi,
.xa-pin-host [data-anim].is-in .xa-kpi {
  opacity: 1;
  transform: translateY(0) scale(1);
}
.xa-pin-host .xa-kpis.is-in .xa-kpi:nth-child(1),
.xa-pin-host [data-anim].is-in .xa-kpi:nth-child(1) { transition-delay: .00s; }
.xa-pin-host .xa-kpis.is-in .xa-kpi:nth-child(2),
.xa-pin-host [data-anim].is-in .xa-kpi:nth-child(2) { transition-delay: .07s; }
.xa-pin-host .xa-kpis.is-in .xa-kpi:nth-child(3),
.xa-pin-host [data-anim].is-in .xa-kpi:nth-child(3) { transition-delay: .14s; }
.xa-pin-host .xa-kpis.is-in .xa-kpi:nth-child(4),
.xa-pin-host [data-anim].is-in .xa-kpi:nth-child(4) { transition-delay: .21s; }
.xa-pin-host .xa-kpis.is-in .xa-kpi:nth-child(5),
.xa-pin-host [data-anim].is-in .xa-kpi:nth-child(5) { transition-delay: .28s; }
.xa-pin-host .xa-kpis.is-in .xa-kpi:nth-child(6),
.xa-pin-host [data-anim].is-in .xa-kpi:nth-child(6) { transition-delay: .35s; }

/* ---- "Live data" pulse on counters once they finish ticking up ------- */
/* motion.js adds .is-live to each [data-counter] once its animation
   completes. The pulse is a brief glow that suggests the number is
   live-updating, a Stripe touch. */
[data-counter].is-live {
  animation: xa-live-pulse 1.8s ease-in-out 1;
}
@keyframes xa-live-pulse {
  0%   { text-shadow: 0 0 0 rgba(139, 197, 63, 0); }
  35%  { text-shadow: 0 0 24px rgba(139, 197, 63, .55), 0 0 4px rgba(139, 197, 63, .35); }
  100% { text-shadow: 0 0 0 rgba(139, 197, 63, 0); }
}

/* ---- Illustration-frame tilt — give it a presence boost on hover ----- */
.xa-illust-frame[data-tilt] {
  transition:
    transform .35s cubic-bezier(.22, .7, .2, 1),
    box-shadow .4s ease;
  transform-style: preserve-3d;
  will-change: transform;
}
.xa-illust-band:hover .xa-illust-frame[data-tilt] {
  /* The cursor parent is .xa-illust-band; intensify shadow on hover. */
  box-shadow:
    0 40px 80px -22px rgba(15, 20, 50, .22),
    0 20px 40px -20px rgba(15, 20, 50, .15);
}

/* Reduced-motion: kill all Phase 2 motion too */
@media (prefers-reduced-motion: reduce) {
  .xa-pin-host { min-height: 0 !important; }
  .xa-pin-stage {
    position: static !important;
    min-height: 0 !important;
    display: block !important;
  }
  .xa-pin-host .xa-kpi {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  [data-counter].is-live { animation: none !important; }
}

/* =========================================================================
   PHASE 3 — Cinematic scroll choreography
   ========================================================================= */

/* ---- Architecture tier focus — dim non-focused tiers, brighten focus ---- */
/* Base: tiers fully visible. When .xa-arch has a tier-focus-N class,
   all tiers except N dim to 25% opacity, drawing attention sequentially. */
.xa-arch svg [data-tier] {
  transition: opacity .85s cubic-bezier(.22, .7, .2, 1);
}
.xa-arch.tier-focus-1 svg [data-tier]:not([data-tier="1"]),
.xa-arch.tier-focus-2 svg [data-tier]:not([data-tier="2"]),
.xa-arch.tier-focus-3 svg [data-tier]:not([data-tier="3"]) {
  opacity: 0.22;
}
/* The focused tier gets a slight scale-up + glow via a subtle drop-shadow */
.xa-arch.tier-focus-1 svg [data-tier="1"],
.xa-arch.tier-focus-2 svg [data-tier="2"],
.xa-arch.tier-focus-3 svg [data-tier="3"] {
  filter: drop-shadow(0 6px 24px rgba(139, 197, 63, .25));
}

/* ---- Section threading — vertical line + pulsing dot ------------------ */
.xa-thread {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 18px 0;
  pointer-events: none;
  position: relative;
}
.xa-thread svg {
  height: 96px;
  width: 6px;
  overflow: visible;
}
.xa-thread__line {
  stroke: url(#xa-thread-grad);
  /* Fallback solid colour when gradient defs aren't available */
  stroke: rgba(26, 35, 126, .18);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-dasharray: 96;
  stroke-dashoffset: 96;
  transition: stroke-dashoffset 1.3s cubic-bezier(.22, .7, .2, 1);
}
.xa-thread.is-in .xa-thread__line {
  stroke-dashoffset: 0;
}
.xa-thread__dot {
  fill: rgba(139, 197, 63, 0);
  transition: fill .5s ease 1.0s;
  transform-box: fill-box;
  transform-origin: center;
}
.xa-thread.is-in .xa-thread__dot {
  fill: rgba(139, 197, 63, .95);
  animation: xa-thread-pulse 2.2s ease-in-out infinite 1.2s;
}
@keyframes xa-thread-pulse {
  0%, 100% { transform: scale(1); filter: drop-shadow(0 0 0 rgba(139, 197, 63, 0)); }
  50%      { transform: scale(1.5); filter: drop-shadow(0 0 8px rgba(139, 197, 63, .8)); }
}

/* ---- Floating accent UI chips (home slide 2, around dashboard) -------- */
.xa-chip {
  position: absolute;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 16px;
  background: rgba(255, 255, 255, .96);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: 1px solid rgba(139, 197, 63, .22);
  border-radius: 999px;
  box-shadow:
    0 1px 0 rgba(255, 255, 255, .9) inset,
    0 4px 8px rgba(15, 20, 50, .05),
    0 24px 48px -20px rgba(15, 20, 50, .18);
  font-family: 'Geist Mono', ui-monospace, monospace;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-700);
  z-index: 10;
  pointer-events: none;
  will-change: transform;
  animation: xa-chip-bob 5s ease-in-out infinite;
}
.xa-chip__dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--leaf-500);
  box-shadow: 0 0 0 0 rgba(139, 197, 63, .55);
  animation: xa-chip-dot-pulse 2s ease-in-out infinite;
  flex-shrink: 0;
}
.xa-chip__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--leaf-700);
  flex-shrink: 0;
}
.xa-chip__txt {
  display: inline-block;
  color: var(--ink-700);
  line-height: 1;
  white-space: nowrap;
}
@keyframes xa-chip-dot-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(139, 197, 63, .55); }
  50%      { box-shadow: 0 0 0 7px rgba(139, 197, 63, 0); }
}
@keyframes xa-chip-bob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-9px); }
}

/* Positioning around the .xa-bob (which wraps the dashboard frame) */
.xa-bob {
  position: relative;
}
.xa-chip--tl { top: -16px;   left: -28px;  animation-delay:  0s;  }
.xa-chip--tr { top: 32px;    right: -36px; animation-delay: -1.5s; }
.xa-chip--br { bottom: -16px; right: 24px;  animation-delay: -3s;  }

/* Hide chips on tablet/mobile where they'd overlap content */
@media (max-width: 1100px) {
  .xa-chip { display: none; }
}

/* Reduced-motion variants */
@media (prefers-reduced-motion: reduce) {
  .xa-thread__line {
    stroke-dashoffset: 0 !important;
    transition: none !important;
  }
  .xa-thread__dot {
    animation: none !important;
    fill: rgba(139, 197, 63, .85) !important;
  }
  .xa-chip {
    animation: none !important;
  }
  .xa-chip__dot {
    animation: none !important;
  }
  .xa-arch svg [data-tier] {
    opacity: 1 !important;
    transition: none !important;
    filter: none !important;
  }
}

/* =========================================================================
   PHASE 3.5 — Architecture diagram visual amplification
   Network elements need to be visible at viewport scale, not just on
   close inspection. Packets get bigger + brighter + dual-stage glow;
   wires get a continuous "flow" effect so the network reads alive even
   between packet pulses.
   ========================================================================= */

/* ---- Data packets — bigger, brighter, layered glow ------------------- */
.xa-arch svg .xa-packet {
  r: 9;
  fill: var(--cyan-400);
  filter:
    drop-shadow(0 0 4px var(--cyan-400))
    drop-shadow(0 0 16px rgba(34, 211, 238, .8));
}
.xa-arch svg .xa-packet--green {
  fill: var(--leaf-500);
  filter:
    drop-shadow(0 0 4px var(--leaf-500))
    drop-shadow(0 0 18px rgba(139, 197, 63, .85));
}
.xa-arch svg .xa-packet--navy {
  fill: var(--ink-700);
  filter: drop-shadow(0 0 12px rgba(26, 35, 126, .7));
}

/* ---- Wire connectors — continuous "flowing dash" effect -------------- */
/* Once .xa-arch has .is-in (added by IO), the wires switch from the
   one-shot draw-in animation to a continuously-flowing dash that visually
   suggests data movement at all times — not just when a packet passes. */
.xa-arch.is-in svg .xa-arch-wire--anim {
  stroke: var(--leaf-500);
  stroke-width: 2;
  stroke-dasharray: 6 8;
  stroke-dashoffset: 0;
  animation: xa-wire-flow 1.6s linear infinite;
  /* Override the transition-to-static defined upstream */
  transition: none;
}
@keyframes xa-wire-flow {
  from { stroke-dashoffset: 0; }
  to   { stroke-dashoffset: -28; }
}

/* ---- Layer box pulse — subtle but constant motion -------------------- */
.xa-arch.is-in svg .xa-arch-box--navy {
  /* The navy core block gets a soft inner glow that pulses continuously */
  filter: drop-shadow(0 12px 30px rgba(26, 35, 126, .35));
  animation: xa-core-breathe 3.4s ease-in-out infinite;
}
@keyframes xa-core-breathe {
  0%, 100% { filter: drop-shadow(0 12px 30px rgba(26, 35, 126, .35)); }
  50%      { filter: drop-shadow(0 14px 42px rgba(26, 35, 126, .55)); }
}

/* When a tier is in focus, give its boxes a leaf-green halo */
.xa-arch.tier-focus-1 svg [data-tier="1"] .xa-arch-box,
.xa-arch.tier-focus-3 svg [data-tier="3"] .xa-arch-box--green {
  filter: drop-shadow(0 0 16px rgba(139, 197, 63, .45));
  transition: filter .8s cubic-bezier(.22, .7, .2, 1);
}

/* ---- Reduced-motion: kill all the continuous animations -------------- */
@media (prefers-reduced-motion: reduce) {
  .xa-arch.is-in svg .xa-arch-wire--anim {
    animation: none !important;
    stroke-dasharray: 0 !important;
  }
  .xa-arch.is-in svg .xa-arch-box--navy {
    animation: none !important;
  }
}
