/* ============================================
   MOTION PACK — additive animation layer.
   Load AFTER all other CSS files.
   ============================================ */

/* ---- PAGE LOAD SHUTTER ---- */
.page-shutter{
  position:fixed;
  inset:0;
  background:var(--ink);
  z-index:9999;
  transform-origin:top;
  transform:scaleY(1);
  transition:transform .6s cubic-bezier(.2,.8,.2,1);
  pointer-events:none;
}
.page-shutter.is-open{
  transform:scaleY(0);
}
@media (prefers-reduced-motion: reduce){
  .page-shutter{display:none;}
}

/* ---- SITEWIDE "PUNCH" HOVER ----
   Extends the stamp/punch hover already used on
   .side-bottom a / .social-row a to more elements. */
.links-row a,
.tech-badge{
  transition:transform .15s ease, box-shadow .15s ease;
}
.links-row a:hover,
.tech-badge:hover{
  transform:translate(-2px,-2px);
  box-shadow:2px 2px 0 var(--red);
}

/* ---- MAGNETIC BUTTONS ----
   JS sets --mx/--my from pointer position; CSS applies
   it and snaps back hard on leave. */
.view-link,
.press-hint{
  transform:translate(var(--mx,0), var(--my,0));
  transition:transform .12s linear;
}
.view-link.snap-back,
.press-hint.snap-back{
  transition:transform .25s cubic-bezier(.2,.8,.2,1);
}

/* ---- HEADING GLITCH-FLICKER ON REVEAL ----
   A single hard flicker instead of a fade — opt-in via
   [data-reveal-glitch] on whichever headings you want. */
[data-reveal-glitch]{
  opacity:0;
}
[data-reveal-glitch].is-visible{
  animation:glitchIn .35s steps(3, end) forwards;
}
@keyframes glitchIn{
  0%{   opacity:0;   transform:translate(-4px,0); clip-path:inset(0 0 60% 0); }
  30%{  opacity:1;   transform:translate(3px,0);  clip-path:inset(40% 0 0 0); }
  60%{  opacity:.6;  transform:translate(-2px,0); clip-path:inset(0 0 20% 0); }
  100%{ opacity:1;   transform:translate(0,0);    clip-path:inset(0 0 0 0); }
}
@media (prefers-reduced-motion: reduce){
  [data-reveal-glitch]{opacity:1 !important; animation:none !important;}
}

/* ---- PAGE TRANSITIONS ----
   Driven by js/router.js, which swaps <main class="main">'s content
   via fetch() (instead of a full page reload) so state that lives
   outside .main -- like whatever's currently playing in the music
   player -- survives moving between pages. These classes just give
   that swap a directional slide instead of an instant cut, whether
   triggered by a sidebar nav click or a mobile swipe. */
.main.page-slide-out-left,
.main.page-slide-out-right{
  transition:transform .18s ease, opacity .18s ease;
  opacity:0;
}
.main.page-slide-out-left{transform:translateX(-24px);}
.main.page-slide-out-right{transform:translateX(24px);}

.main.page-slide-in-left,
.main.page-slide-in-right{
  opacity:0;
}
.main.page-slide-in-left{transform:translateX(-24px);}
.main.page-slide-in-right{transform:translateX(24px);}

.main.page-slide-run{
  transition:transform .32s cubic-bezier(.2,.8,.2,1), opacity .32s ease;
  transform:translateX(0);
  opacity:1;
}

@media (prefers-reduced-motion: reduce){
  .main.page-slide-out-left, .main.page-slide-out-right,
  .main.page-slide-in-left, .main.page-slide-in-right,
  .main.page-slide-run{
    transition:none !important;
    transform:none !important;
    opacity:1 !important;
  }
}