/* ============================================================
   Eddys Development — MOTION LAYER
   Cinematic scroll + micro-interactions for the landing page.
   Pairs with js/motion.js (GSAP + ScrollTrigger + Lenis).

   PROGRESSIVE ENHANCEMENT CONTRACT
   --------------------------------
   • <html> only gets the `.motion` class when the motion engine is
     actually going to run (libs loaded + motion allowed). Every
     "hide it so GSAP can reveal it" rule below is therefore scoped
     to `html.motion`.
   • If a CDN fails, reduced-motion is on, or JS is off, `.motion`
     is never present (or gets removed) → the page renders fully
     visible with landing.css's own IntersectionObserver reveal.
   • We never use `!important` on transform/opacity so GSAP's inline
     styles always win.
   ============================================================ */

/* ------------------------------------------------------------
   0. PAGE TRANSITION — exit curtain (pairs with js/nav-transition.js)
   ------------------------------------------------------------
   A violet curtain (same palette as the loader) fades IN as you leave
   a page; the destination's loader fades it back out on arrival, so a
   navigation reads as one continuous motion. Reliable in every browser
   and fully controllable (no View Transitions API dependency). */
.page-exit {
  position: fixed;
  inset: 0;
  z-index: 9998;                 /* just under #loader (9999) */
  pointer-events: none;
  opacity: 0;
  background:
    radial-gradient(60% 60% at 50% 42%, rgba(226, 85, 43, .18), transparent 70%),
    var(--bg-0);
  transition: opacity .4s var(--ease-soft);
  will-change: opacity;
}
.page-exit.is-active { opacity: 1; pointer-events: auto; }
@media (prefers-reduced-motion: reduce) { .page-exit { display: none; } }

/* ------------------------------------------------------------
   1. LENIS — recommended base styles (smooth momentum scroll)
   ------------------------------------------------------------ */
html.lenis,
html.lenis body { height: auto; }

.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-smooth [data-lenis-prevent] { overscroll-behavior: contain; }
.lenis.lenis-stopped { overflow: hidden; }        /* used while the loader is up */
.lenis.lenis-smooth iframe { pointer-events: none; }

/* ------------------------------------------------------------
   2. PAGE LOADER — sleek "boot" overlay that dissolves on load
   ------------------------------------------------------------ */
#loader {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: grid;
  place-items: center;
  gap: 22px;
  background:
    radial-gradient(60% 60% at 50% 42%, rgba(226, 85, 43, .18), transparent 70%),
    var(--bg-0);
  /* GPU-friendly fade target */
  will-change: opacity, transform;
}
/* Hidden whenever the motion engine isn't driving the page. */
html:not(.motion) #loader { display: none; }

.loader-core {
  display: grid;
  justify-items: center;
  gap: 18px;
  transform: translate3d(0, 0, 0);
}

/* Brand mark with a sweeping conic ring around it */
.loader-mark {
  position: relative;
  width: 64px;
  height: 64px;
  display: grid;
  place-items: center;
  border-radius: 18px;
  color: #fff;
  background: linear-gradient(135deg, var(--violet-600), var(--magenta));
  box-shadow: 0 10px 30px rgba(245, 165, 36, .5), inset 0 1px 0 rgba(255, 255, 255, .45);
}
.loader-mark svg { width: 30px; height: 30px; }
.loader-mark::before {
  content: "";
  position: absolute;
  inset: -8px;
  border-radius: 24px;
  background: conic-gradient(from 0deg, transparent 0 70%, var(--violet-bright) 88%, transparent 100%);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 3px));
          mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 3px));
  animation: loaderSpin 1.1s linear infinite;
}
@keyframes loaderSpin { to { transform: rotate(360deg); } }

/* Thin progress rail filled by motion.js */
.loader-rail {
  position: relative;
  width: 180px;
  height: 3px;
  border-radius: 999px;
  background: rgba(245, 165, 36, .16);
  overflow: hidden;
}
.loader-bar {
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 100%;
  transform-origin: left center;
  transform: scaleX(0);        /* fill driven by JS (scaleX 0 → 1) */
  border-radius: inherit;
  background: linear-gradient(90deg, var(--violet), var(--magenta));
  box-shadow: 0 0 14px rgba(245, 165, 36, .6);
  will-change: transform;
}
.loader-text {
  font: 500 12.5px var(--font-mono);
  letter-spacing: .04em;
  color: var(--faint);
}
.loader-text b { color: var(--violet-bright); font-weight: 600; }

/* Safety net: if JS never dissolves it, fade away on its own. */
@keyframes loaderFailsafe { to { opacity: 0; visibility: hidden; } }
html.motion #loader { animation: loaderFailsafe .6s ease 5s forwards; }

/* ------------------------------------------------------------
   3. REVEAL STATES — hide animated content for GSAP to bring in.
      Only when the engine is live; scoped tightly to avoid FOUC.
   ------------------------------------------------------------ */
html.motion [data-reveal],
html.motion [data-anim] {
  opacity: 0;
  /* Override landing.css's default translateY(18px) so that AFTER GSAP
     clears its inline transform, cards rest at their natural position
     (and CSS :hover lifts keep working). */
  transform: none;
  /* Kill landing.css's own transition/blur so GSAP fully owns motion. */
  transition: none !important;
  filter: none !important;
}
/* Hero console boots in on load (handled by the intro timeline). */
html.motion .hero .console { opacity: 0; }

/* The grids stagger their own children, so the wrapper stays visible. */
html.motion .grid[data-anim],
html.motion .steps[data-anim],
html.motion .pricing-grid[data-anim] { opacity: 1; }

/* ------------------------------------------------------------
   4. MICRO-INTERACTIONS — magnetic + glowing interactive elements
   ------------------------------------------------------------ */

/* Elements motion.js wires for magnetic physics. translate3d keeps
   them on the compositor; GSAP writes the transform inline. */
html.motion .is-magnetic {
  will-change: transform;
  transform: translate3d(0, 0, 0);
}

/* Cursor-follow glow that lives just inside the button edge.
   --bx/--by are written by motion.js (px within the element). */
html.motion .btn.is-magnetic::before,
html.motion .nav-cta.is-magnetic::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: inherit;
  pointer-events: none;
  background: radial-gradient(
    120px 120px at var(--bx, 50%) var(--by, 50%),
    rgba(255, 255, 255, .35),
    rgba(232, 201, 138, .12) 45%,
    transparent 72%
  );
  opacity: 0;
  transition: opacity .25s var(--ease-soft);
}
html.motion .btn.is-magnetic:hover::before,
html.motion .nav-cta.is-magnetic:hover::before { opacity: 1; }
/* keep the existing light-sweep (::after) and the label above the glow */
html.motion .btn.is-magnetic > * { position: relative; z-index: 2; }

/* Animated glowing border — a soft pulsing halo on hover/focus.
   Pure box-shadow (no clipping issues with the .btn overflow:hidden). */
html.motion .btn.is-magnetic:not(.btn-ghost):not([aria-disabled="true"]):hover,
html.motion .nav-cta.is-magnetic:hover {
  animation: glowPulse 1.8s var(--ease-soft) infinite;
}
@keyframes glowPulse {
  0%, 100% { box-shadow: 0 10px 26px rgba(226, 85, 43, .42), 0 0 0 1px rgba(232, 201, 138, .18); }
  50%      { box-shadow: 0 14px 36px rgba(245, 165, 36, .62), 0 0 22px rgba(232, 201, 138, .45); }
}

/* Ghost + chip get a subtler border-glow (no heavy shadow). */
html.motion .btn-ghost.is-magnetic:hover,
html.motion .account-chip.is-magnetic:hover {
  box-shadow: 0 0 0 1px var(--border-hover), 0 0 18px rgba(245, 165, 36, .28);
}

/* ------------------------------------------------------------
   5. PARALLAX — background imagery + console drift.
      motion.js writes translate3d into these custom props so the
      browser only ever composites (no layout / paint thrash).
   ------------------------------------------------------------ */
html.motion .bg-aurora,
html.motion .bg-grid,
html.motion .bg-grain {
  will-change: transform;
  /* --px/--py are unitless numbers written by GSAP quickTo; * 1px gives
     them a length so translate3d stays GPU-composited. */
  transform: translate3d(calc(var(--px, 0) * 1px), calc(var(--py, 0) * 1px), 0);
}
/* The grain stays nearly still; aurora/grid drift more (depth). */

html.motion .hero .console { will-change: transform, opacity; }

/* The hero's decorative aura + the console's scrubbed drift can bleed a few
   px past the viewport once promoted to their own layers. Clip horizontally
   only (x), so the vertical scroll-fade of the console is unaffected and no
   stray horizontal scrollbar appears on mobile. */
html.motion .hero { overflow-x: clip; }

/* ------------------------------------------------------------
   6. REDUCED MOTION / SAFETY — never animate, never hide.
   ------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  #loader { display: none !important; }
  html.motion [data-reveal],
  html.motion [data-anim],
  html.motion .hero .console { opacity: 1 !important; transform: none !important; }
  html.motion .is-magnetic { transform: none !important; }
  html.motion .btn.is-magnetic:hover,
  html.motion .nav-cta.is-magnetic:hover { animation: none; }
  .loader-mark::before { animation: none; }
}
