/* ==========================================================================
   animations.css — motion system
   Extracted from the existing home/about pages so every page shares the
   exact same easing, timing and reveal behaviour.
   ========================================================================== */

/* ---------- Keyframes ---------- */
@keyframes spin      { to { transform: rotate(360deg); } }
@keyframes fadeDown  { from { opacity:0; transform:translateY(-14px); } to { opacity:1; transform:none; } }
@keyframes fadeUp    { from { opacity:0; transform:translateY(16px); }  to { opacity:1; transform:none; } }
@keyframes charIn    { from { opacity:0; transform:translateY(.4em); filter:blur(6px); }
                       to   { opacity:1; transform:translateY(0);    filter:blur(0); } }
@keyframes marquee   { to { transform: translateX(-50%); } }
@keyframes float     { 0%,100% { transform:translateY(0); } 50% { transform:translateY(-12px); } }

/* ---------- Preloader ---------- */
.preloader{position:fixed;inset:0;z-index:100;display:grid;place-items:center;background:var(--coral);transition:opacity .6s var(--ease),visibility .6s var(--ease)}
.preloader.hide{opacity:0;visibility:hidden}
.spinner{width:52px;height:52px;border-radius:50%;border:3px solid rgba(255,255,255,.35);border-top-color:#fff;animation:spin .8s linear infinite}

/* ---------- Scroll reveal primitives ---------- */
.rise{opacity:0;transform:translateY(30px);transition:opacity .8s var(--ease),transform .8s var(--ease);transition-delay:var(--d,0s)}
.rise.in-view{opacity:1;transform:none}

.reveal-words .word,
.reveal-chars .char2{display:inline-block;white-space:pre;opacity:0}
.reveal-words.in-view .word {animation:charIn .7s var(--ease) both;animation-delay:calc(var(--i) * .06s)}
.reveal-chars.in-view .char2{animation:charIn .6s var(--ease) both;animation-delay:calc(var(--i) * .04s)}

/* Image wipe + zoom reveal (gated on image load by main.js) */
.img-reveal{overflow:hidden}
.img-reveal img{
  width:100%;height:100%;object-fit:cover;display:block;
  clip-path:inset(0 100% 0 0);transform:scale(1.3);
  transition:clip-path .55s var(--ease),transform .7s var(--ease);
  transition-delay:var(--d,0s);
}
.img-reveal.in-view img{clip-path:inset(0 0 0 0);transform:scale(1)}

/* Section separator dot */
.section-dot{position:absolute;top:0;left:50%;transform:translateX(-50%);width:14px;height:14px;border-radius:50%;background:var(--ink);z-index:3;opacity:0;transition:opacity .6s var(--ease)}
.section-dot.in-view{opacity:1}

/* Page-load entrance for hero content */
.page-enter{opacity:0;transform:translateY(24px)}
.is-loaded .page-enter{animation:fadeUp .9s var(--ease) var(--d,.45s) both}

/* Fallback background for remote images */
.media-fallback{background:linear-gradient(135deg,#f2937a,var(--coral) 60%,#d8543a);font-size:0}

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001s!important;animation-delay:0s!important;transition-duration:.001s!important}
  .rise,.section-dot,.word,.char2,.page-enter{opacity:1!important;transform:none!important;filter:none!important}
  .img-reveal img{clip-path:inset(0 0 0 0)!important;transform:none!important}
  html{scroll-behavior:auto!important}
}
