/* ============================================================
   МОЙ — Page Transitions & Intro layer
   Self-contained: no edits to existing selectors, only additive.
   Drives: intro preloader · seamless hero handoff · curtain.
   All animation is GSAP-driven; these rules only set the
   *initial / resting* states so there is never a flash.
   ============================================================ */

/* ---------- LOADER — thin brand progress line ----------
   Injected by the inline pre-flight script in <body> on hard
   loads (no incoming curtain), so it paints before anything
   else. transitions.js drives the fill and dissolves it. */
.fx-loader {
  position: fixed; inset: 0; z-index: 1200;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 26px;
  background: linear-gradient(180deg,
    var(--beige) 0%,
    #F4EFE9 22%,
    var(--blue-2) 64%,
    var(--blue) 100%);
  will-change: opacity;
}
.fx-loader .fxl-logo { width: 46px; height: auto; }
.fx-loader .fxl-track {
  position: relative; width: min(300px, 58vw); height: 1px;
  background: var(--line); overflow: hidden;
}
.fx-loader .fxl-track i {
  position: absolute; left: 0; top: 0; height: 100%; width: 0%;
  background: var(--accent); transition: width 0.3s var(--ease);
}

/* ---------- Full-bleed transition image (intro hero / handoff) ----------
   Positioned + sized entirely from JS via getBoundingClientRect so an
   object-fit:cover photo re-crops cleanly between thumb ↔ fullscreen
   with NO non-uniform scale distortion. */
.fx-hero {
  position: fixed; left: 0; top: 0; z-index: 980;
  overflow: hidden; pointer-events: none;
  background: var(--blue-2);
  will-change: left, top, width, height;
}
.fx-hero img {
  width: 100%; height: 100%;
  object-fit: cover; display: block;
}

/* ---------- CURTAIN — seamless page fade ----------
   Reproduces the page's own .hero-gradient (beige→blue) so, because every
   destination lands at scroll 0 with that same gradient at its top, the
   curtain over the page is pixel-identical to the page underneath — raising
   it reveals the exact same pixels, so there is NO flash / colour blink.

   Contacts is the exception: style.css switches .hero-gradient off there, so
   a curtain heading for Contacts must not paint one either. It is painted at
   BUILD time, never later — the curtain is opaque for most of the transition,
   so a repaint after that point is a visible step rather than a hidden one. */
.fx-curtain {
  position: fixed; inset: 0; z-index: 1000;
  background-color: var(--blue);
  background-image: linear-gradient(180deg,
    var(--beige) 0%,
    #F4EFE9 22%,
    var(--blue-2) 64%,
    var(--blue) 100%);
  opacity: 0;
  pointer-events: none;
  will-change: opacity;
}
/* destination paints no gradient at all (Contacts) — flat ground only */
.fx-curtain.is-flat { background-image: none; }
/* no wordmark in fade mode */
.fx-curtain .fx-mark { display: none; }

@media (prefers-reduced-motion: reduce) {
  .fx-hero, .fx-curtain { display: none !important; }
}
