/* ==========================================================================
   Harsh Sales Agency — FX layer
   Premium interaction effects, written natively (no React/Tailwind runtime):
   page curtain, split-text reveals, nav spotlight, magnetic buttons,
   3D tilt + pointer glow, clip-path image wipes, sticky stacked steps,
   cursor image trail, horizontal category rail.
   Every effect is gated behind prefers-reduced-motion and pointer capability.
   ========================================================================== */

/* --- 1. Page curtain ------------------------------------------------------ */
.curtain {
  position:fixed; inset:0; z-index:120; background:var(--ink);
  display:grid; place-items:center; pointer-events:none;
  clip-path:inset(0 0 0 0);
  transition:clip-path 1s cubic-bezier(.76,0,.24,1);
}
.curtain img { width:64px; height:auto; opacity:0; transform:translateY(10px) scale(.94) }
.curtain.is-in img { animation:curtainMark .9s var(--ease-out) forwards }
@keyframes curtainMark {
  0%   { opacity:0; transform:translateY(10px) scale(.94) }
  45%  { opacity:1; transform:translateY(0) scale(1) }
  100% { opacity:0; transform:translateY(-8px) scale(1.04) }
}
.curtain.is-out { clip-path:inset(0 0 100% 0) }
.curtain.is-cover { clip-path:inset(0 0 0 0) !important; transition-duration:.55s }
body.is-leaving { cursor:progress }

/* --- 2. Split-text reveal ------------------------------------------------- */
.split-t { display:inline-block; overflow:hidden; vertical-align:bottom }
/* Resting state is VISIBLE. The hidden state is armed by JS (.split-arm) and
   is always disarmed on a timer, so a heading can never be left invisible
   because an animation or observer failed to run. */
.split-t > i { display:inline-block; font-style:inherit; transform:none; opacity:1 }
.split-arm .split-t > i { transform:translateY(105%); opacity:0 }
.split-ready .split-t > i { transition:transform .82s var(--ease-out), opacity .6s var(--ease-out) }
.split-in .split-t > i { transform:none; opacity:1 }

/* --- 3. Nav spotlight ----------------------------------------------------- */
/* Desktop only: on mobile `.nav__links` must stay `position:fixed` for the
   slide-down panel, and this rule (later in the cascade) was overriding it. */
@media (min-width:961px) { .nav__links { position:relative } }
.nav__spot {
  position:absolute; z-index:-1; border-radius:var(--r-full);
  background:var(--cream-2); opacity:0;
  transition:transform .42s var(--ease-out), width .42s var(--ease-out),
             height .42s var(--ease-out), opacity .3s;
  pointer-events:none; left:0; top:0;
}
.nav__links.spot-on .nav__spot { opacity:1 }
@media (max-width:960px) { .nav__spot { display:none } }

/* --- 4. Magnetic buttons -------------------------------------------------- */
.mag { will-change:transform }
.mag__in { display:inline-flex; align-items:center; gap:10px; will-change:transform }

/* --- 5. Tilt + pointer glow ---------------------------------------------- */
.tilt { transform-style:preserve-3d; will-change:transform }
.tilt > * { transform:translateZ(0) }
.card.tilt::before, .cat.tilt::before {
  content:""; position:absolute; inset:0; z-index:3; pointer-events:none;
  border-radius:inherit; opacity:0; transition:opacity .35s;
  background:radial-gradient(320px circle at var(--mx,50%) var(--my,50%),
    rgba(246,156,49,.20), transparent 62%);
}
.card.tilt:hover::before, .cat.tilt:hover::before { opacity:1 }
.card.tilt { position:relative }

/* --- 6. Clip-path image wipe --------------------------------------------- */
/* Same fail-visible pattern as split text: unclipped is the resting state. */
.wipe { clip-path:inset(0 0 0 0); transition:clip-path 1.05s cubic-bezier(.76,0,.24,1) }
.wipe.wipe-arm { clip-path:inset(0 0 100% 0) }
.wipe.is-in { clip-path:inset(0 0 0 0) }
.wipe img { transition:transform 1.3s var(--ease-out) }
.wipe.wipe-arm img { transform:scale(1.14) }
.wipe.is-in img { transform:none }

/* --- 7. Sticky stacked steps (desktop) ----------------------------------- */
@media (min-width:1024px) and (prefers-reduced-motion:no-preference) {
  .steps--stack { display:block; position:relative }
  .steps--stack .step {
    position:sticky; top:calc(var(--nav-h) + 24px);
    margin-bottom:18px; display:grid; grid-template-columns:64px 1fr;
    gap:22px; align-items:start; padding:30px 32px;
    background:var(--white);
    transition:transform .5s var(--ease-out), box-shadow .5s var(--ease-out),
               opacity .5s var(--ease-out);
  }
  .steps--stack .step:nth-child(1) { top:calc(var(--nav-h) + 24px) }
  .steps--stack .step:nth-child(2) { top:calc(var(--nav-h) + 40px) }
  .steps--stack .step:nth-child(3) { top:calc(var(--nav-h) + 56px) }
  .steps--stack .step:nth-child(4) { top:calc(var(--nav-h) + 72px) }
  .steps--stack .step::before {
    grid-row:1/3; margin:0; font-size:1.6rem; font-family:var(--f-display);
    color:var(--amber); line-height:1;
  }
  .steps--stack .step h3 { grid-column:2 }
  .steps--stack .step p  { grid-column:2; max-width:62ch }
  .steps--stack .step.is-under { transform:scale(.975); opacity:.55 }
}

/* --- 8. Cursor image trail (fine pointers only) -------------------------- */
.trail { position:fixed; inset:0; z-index:1; pointer-events:none; overflow:hidden }
.trail img {
  position:absolute; width:132px; height:132px; object-fit:cover;
  border-radius:14px; opacity:0; transform:translate(-50%,-50%) scale(.6) rotate(0deg);
  box-shadow:0 18px 40px rgba(0,0,0,.35);
  animation:trailPop 1.15s var(--ease-out) forwards;
}
@keyframes trailPop {
  0%   { opacity:0; transform:translate(-50%,-50%) scale(.55) rotate(var(--r,0deg)) }
  18%  { opacity:1; transform:translate(-50%,-50%) scale(1) rotate(var(--r,0deg)) }
  100% { opacity:0; transform:translate(-50%,calc(-50% + 46px)) scale(.9) rotate(var(--r,0deg)) }
}

/* --- 9. Horizontal category rail ----------------------------------------- */
@media (min-width:900px) {
  .rail { overflow:hidden }
  .rail__track { display:flex; gap:18px; will-change:transform }
  .rail__track .cat { flex:0 0 clamp(230px,20vw,290px) }
}

/* --- 10. Marquee pause on hover ------------------------------------------ */
.marquee:hover .marquee__track { animation-play-state:paused }

/* --- 11. Gradient text sweep on section headings ------------------------- */
.shead h2 .split-t > i { will-change:transform }

/* --- 12. Scroll-linked hero parallax ------------------------------------- */
.hero__frames { will-change:transform }

/* --- 13. Reduced motion / touch fallbacks -------------------------------- */
@media (prefers-reduced-motion:reduce) {
  .curtain { display:none }
  .split-t > i { transform:none !important; opacity:1 !important; transition:none }
  .wipe { clip-path:none !important; transition:none }
  .wipe img { transform:none !important }
  .trail { display:none }
  .tilt { transform:none !important }
}
@media (hover:none), (pointer:coarse) {
  .trail { display:none }
  .card.tilt::before, .cat.tilt::before { display:none }
}
