/* ============================================================
   animations.css — loader, keyframes, grain, reveal helpers
   ============================================================ */

/* ---------- Cinematic preloader (Phase 2) ---------- */
.loader {
  position: fixed; inset: 0; z-index: var(--z-loader);
  overflow: hidden;
  /* Failsafe: if JS never runs, fade the loader away so content is reachable. */
  animation: loaderFailsafe 0.6s ease 2s forwards;
}
.loader.is-done { animation: none; }
/* Loader plays once per visit; on later navigations it's skipped with no flash. */
html.no-loader .loader { display: none; }

.loader__panel {
  position: absolute; left: 0; right: 0; height: 50.5%;
  background: var(--color-navy);
  z-index: 1;
}
.loader__panel--top { top: 0; }
.loader__panel--bottom { bottom: 0; }

.loader__core {
  position: absolute; inset: 0; z-index: 2;
  display: grid; place-content: center; justify-items: center;
  gap: 1.4rem; text-align: center;
}
.loader__logo { width: clamp(140px, 26vw, 200px); height: auto; }

.loader__wordmark {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(2.2rem, 6vw, 4rem);
  color: var(--color-cream);
  display: flex; gap: 0.3em; align-items: baseline;
}
.loader__word { display: inline-block; overflow: hidden; }
.loader__word--script { font-style: italic; color: var(--color-accent); }

.loader__progress {
  width: clamp(180px, 26vw, 280px); height: 3px;
  background: rgba(255,255,255,0.18); border-radius: 2px; overflow: hidden;
}
.loader__progress-fill {
  display: block; height: 100%; width: 0%;
  background: linear-gradient(90deg, var(--color-accent), var(--color-foam));
}
.loader__count {
  font-family: var(--font-sans); font-size: 0.8rem; letter-spacing: 0.2em;
  color: var(--text-on-dark-soft);
}
.loader__count i { font-style: normal; opacity: 0.6; }

/* Surf texture pulse behind the logo */
.loader__core::before {
  content: ""; position: absolute; width: 60vmax; height: 60vmax;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(140,191,183,0.22), transparent 62%);
  animation: wavePulse 3.2s var(--ease-inout) infinite;
  z-index: -1;
}

@keyframes wavePulse {
  0%, 100% { transform: scale(0.85); opacity: 0.5; }
  50%      { transform: scale(1.12); opacity: 0.9; }
}
@keyframes loaderFailsafe {
  to { opacity: 0; visibility: hidden; pointer-events: none; }
}
@keyframes scrollCue {
  0%   { transform: scaleY(0); transform-origin: top; }
  45%  { transform: scaleY(1); transform-origin: top; }
  55%  { transform: scaleY(1); transform-origin: bottom; }
  100% { transform: scaleY(0); transform-origin: bottom; }
}
@keyframes menuItemIn {
  to { opacity: 1; transform: none; }
}

/* Stagger delays for mobile menu items */
.mobile-menu.is-open li:nth-child(1) .mobile-menu__link { animation-delay: 0.08s; }
.mobile-menu.is-open li:nth-child(2) .mobile-menu__link { animation-delay: 0.13s; }
.mobile-menu.is-open li:nth-child(3) .mobile-menu__link { animation-delay: 0.18s; }
.mobile-menu.is-open li:nth-child(4) .mobile-menu__link { animation-delay: 0.23s; }
.mobile-menu.is-open li:nth-child(5) .mobile-menu__link { animation-delay: 0.28s; }
.mobile-menu.is-open li:nth-child(6) .mobile-menu__link { animation-delay: 0.33s; }
.mobile-menu.is-open li:nth-child(7) .mobile-menu__link { animation-delay: 0.38s; }
.mobile-menu.is-open li:nth-child(8) .mobile-menu__link { animation-delay: 0.43s; }
.mobile-menu.is-open li:nth-child(9) .mobile-menu__link { animation-delay: 0.48s; }

/* ---------- Film grain overlay (Phase 4) ---------- */
.grain::after {
  content: ""; position: absolute; inset: 0; z-index: 1;
  pointer-events: none; opacity: 0.5; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.55'/%3E%3C/svg%3E");
}
.site-footer__grain {
  position: absolute; inset: 0; z-index: 1; pointer-events: none; opacity: 0.06;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---------- Reveal helpers ----------
   The resting (un-animated) state is VISIBLE: content must stay readable if
   GSAP never loads, never runs, or an animation never completes. The hidden
   pre-animation state is applied as inline styles by gsap-animations.js in the
   same JS tick that adds html.anim, so no CSS hiding rule is needed here — a
   CSS rule the JS forgets to undo leaves content invisible forever (this is
   exactly what kept .line-mask headings at opacity 0 on every machine). */
.reveal, .reveal-stagger > * { will-change: transform, opacity; }

@media (prefers-reduced-motion: reduce) {
  .loader__core::before,
  .scroll-cue i { animation: none; }
}
