/* ============================================================
   transition.css — Shared page-transition + fade-up system.

   Loaded by every live page. Contains:
     1. Page-leave/arrive overlay (body::before).
     2. View-transition contract (navbar pinned, root crossfade killed).
     3. Fade-up base (opacity-only) + initial-load stagger window.
     4. Reduced-motion overrides.

   Page-specific bits that LIVE INLINE in each page:
     • view-transition-name:navbar on the page's #navbar rule.
     • body.is-revealing IMAGE-ELEMENT overrides — selectors vary by page.
     • Hero / page-title keyframe animations (timing constants below).

   Timing constants (sync new keyframes to these):
     • Leave overlay:   100ms ease-in
     • Page reveal:     800ms ease-out
     • Text fade-up:    400ms cubic-bezier(.4,0,.2,1) + 300ms initial delay
     • Image fade-up:   700ms cubic-bezier(.4,0,.2,1) + 600ms initial delay
     • IO rootMargin:   -6%
     • is-revealing window: 1600ms (set by transition.js)
   ============================================================ */

/* 0. Navbar logo click-area control ------------------------------ */

/* Click area should match the visible logo, not the wider wrapper. The logo
   wrapper is an <a> wrapping an <img> — fit-content + line-height:0 makes
   the anchor's bounds tightly match the painted image. Applies on every
   viewport, so blank navbar space (between logo and links) is no longer
   clickable. The full "Landmark PM" wordmark stays on every viewport. */
.nav-logo{display:inline-block;width:fit-content;line-height:0}

/* 0b. Stable scrollbar -------------------------------------------- */

/* Force the vertical scrollbar to always be present so the viewport width
   doesn't oscillate during initial page load. Otherwise the browser may
   render the new page briefly without a scrollbar (assumed no overflow),
   then bring it back once content lays out — that ~15–17px width swing
   shows up as the navbar links (anchored to the grid's auto column on the
   right) flying right and back for a frame. The logo (anchored to the 1fr
   column on the left) doesn't move, which is the diagnostic signature. */
html{overflow-y:scroll}

/* 1. Leave / arrive overlay -------------------------------------- */

/* Sits at z-50, BELOW the navbar (z-100). On click, JS adds .is-leaving →
   overlay snaps to opacity 1 covering content. After one paint frame JS
   navigates. New page paints with overlay still at 1 (page-reveal animation
   plays 1 → 0 over 50ms). Persistent black through the unload → paint gap.
   Navbar stays visible on top; transparent navbar areas resolve to this dark
   overlay (matched between pages → invisible view-transition morph). */
/* Transition on opacity = the LEAVE animation: when .is-leaving is added,
   animation:none cancels the arrive animation and the transition smoothly
   ramps opacity 0 → 1 over 100ms (visible fade-to-black before navigating).
   The arrive animation (page-reveal) overrides the transition on first paint. */
body::before{content:'';position:fixed;inset:0;z-index:100;background:var(--inv-bg);pointer-events:none;opacity:var(--overlay-opacity, 0);animation:page-reveal 800ms ease-out both}
body.is-leaving::before{animation:page-leave 800ms ease-out both}
@keyframes page-reveal{0%{opacity:1}50%{opacity:1}100%{opacity:0}}
@keyframes page-leave{0%{opacity:0}50%{opacity:1}100%{opacity:1}}

/* 2. View-transition contract ------------------------------------ */

/* @view-transition is intentionally DISABLED.

   Even with animation:none on every pseudo-element (root + navbar group +
   image-pair), Chrome's view-transition compositor introduced subtle morph
   artifacts — most notably a 5–10px horizontal shift of nav-link text for
   one frame on cross-page navigation, plus a residual height "glitch" when
   the leaving and arriving navbars were in different scroll states. The
   live (pre-VT) site doesn't show any of this.

   Persistence is now handled WITHOUT view-transitions:
     • Native paint-hold keeps the OLD page's pixels visible while the new
       page parses and paints — the gap is bridged by the browser, no JS.
     • body::before overlay above paints a dark sheet over the body content
       during leave + arrive, so the visual is "navbar over black" on both
       pages — identical regardless of which page you're on.
     • The click-handler workaround in transition.js sets the leaving
       navbar's .scrolled state to match the destination's first-paint
       state (full or scrolled) before navigating, so paint-hold shows the
       leaving page in a state that matches the new page's initial paint.

   To re-enable VT (only if a future feature genuinely needs cross-document
   element morphing — e.g. shared image hero), uncomment the rules below
   AND restore `view-transition-name: navbar` on each page's #navbar.
   ----
   @view-transition{navigation:auto}
   ::view-transition{background:var(--inv-bg)}
   ::view-transition-old(root),::view-transition-new(root){animation:none;mix-blend-mode:normal;background:var(--inv-bg)}
   ::view-transition-group(navbar){animation:none}
   ::view-transition-old(navbar),::view-transition-new(navbar){animation:none}
   ---- */

/* 3. Fade-up + initial-load stagger ------------------------------ */

/* Base: 900ms opacity + 16px translateY rise. The transition is on .is-visible
   only (NOT on bare .fade-up) so the initial opacity:0 / translateY(16px)
   land instantly when JS adds the class — otherwise the transition fires
   backwards first, causing a brief flash. */
.fade-up{opacity:0;transform:translateY(16px)}
.fade-up.is-visible{opacity:1;transform:translateY(0);transition:opacity .9s var(--ease),transform .9s var(--ease)}

/* During the initial-load reveal window (transition.js adds body.is-revealing
   on script run, removes it at 1600ms) text fade-ups get a 300ms delay so
   they trail the page-reveal overlay clearing. After 1600ms the class is
   gone and scroll-triggered fades use no delay. Pages with a hero image
   override hero-text fade-ups to 600ms so the image leads the title. */
body.is-revealing .fade-up.is-visible{transition-delay:300ms}

/* Image elements: each page declares its own image-element selector list
   inline (.pe-card, .leader-portrait, etc.). The pattern they apply:

     body.is-revealing .image-elem.fade-up.is-visible{
       transition-duration:700ms;transition-delay:600ms
     }

   Kept inline because the selector list varies by page. */

/* 4. Reduced-motion ---------------------------------------------- */

@media (prefers-reduced-motion:reduce){
  body::before{animation:none;display:none}
  .fade-up{opacity:1}
  .fade-up.is-visible{transition:none}
}
