/* ── Page transitions ────────────────────────────────────────────────────────
   Cross-document View Transitions. Moving between two pages of this site plays
   a curtain: the page you are leaving is covered from both edges inward, and
   the page you are arriving at opens back out from the middle.

   CSS only, on purpose. A JavaScript curtain has to hide the page before it can
   reveal it, so a script that fails to run leaves a blank page; this cannot.
   A browser without View Transitions simply navigates the way it always did.

   Every page of the site must carry this file, because a cross-document
   transition only runs when BOTH the outgoing and incoming pages opt in.

   HOW THE CURTAIN IS BUILT, since there are no curtain elements anywhere.
   There is nothing in the DOM to slide: during a transition the browser paints
   snapshots, not the real page. So the panels are the ABSENCE of a snapshot.
   ::view-transition carries the panel colour, and each snapshot is clipped with
   an inset that walks to and from the centre line. Where the snapshot has been
   clipped away, the panel colour is what shows, so two hard edges travel inward
   over the old page and back outward off the new one. One flat colour and two
   keyframes, no elements, nothing to keep in sync.

   FOUR THINGS HERE ARE DELIBERATE, and undoing any of them brings back the
   "one page written on top of the other" look this file was rewritten to fix.

   1. THE TWO HALVES DO NOT OVERLAP. The incoming page waits for the outgoing
      one to finish before it starts, so the screen is never showing parts of
      both. With the curtain that is also what makes it read as a curtain: for
      one frame in the middle, the panels are simply closed.

   2. mix-blend-mode IS FORCED TO normal. The browser default for these
      pseudo-elements is plus-lighter, which ADDS the two layers together. That
      is right for the UA's own paired opacity curves and wrong for any custom
      pair: overlapping content comes out brighter and visibly doubled.

   3. NOTHING IS A SHARED ELEMENT. Naming the header or the footer with a
      view-transition-name makes it one group morphing across the navigation,
      and this site positions its header three different ways (fixed on the docs
      pages, absolute on the homepage, static on the legal pages). Morphing
      between those geometries is what made the movement feel rigid and snapped.
      The whole page transitions as one layer instead.

   4. THE EASING IS THE POINT. cubic-bezier(.87, 0, .13, 1) is an exponential
      ease in and out: it barely moves, then crosses almost the whole screen,
      then settles. A linear or gently-eased wipe reads as a loading bar. This
      reads as something being drawn closed and pulled open.

   TO SLOW IT DOWN AND LOOK AT IT: raise the three durations HERE. A style
   injected from the outgoing page does nothing, because stylesheets do not
   cross documents and the transition spans both of them.
   ────────────────────────────────────────────────────────────────────────── */

@view-transition { navigation: auto; }

/* The curtain itself. This sits behind both snapshots for the whole
   transition, so it is what fills every pixel the clip-paths take away. */
::view-transition {
  background-color: #0b0b0d;
  background-image: linear-gradient(158deg, #1b1332 0%, #100c1c 46%, #0a0910 100%);
}

/* Leaving: the page is closed in on from both sides. */
::view-transition-old(root) {
  animation: ia-curtain-close 300ms cubic-bezier(.87, 0, .13, 1) both;
  mix-blend-mode: normal;
}

/* Arriving: the panels part again, and only this half moves. The 4px rise is
   small on purpose. Two layers travelling in opposite directions is itself the
   sliding-over-each-other look. */
::view-transition-new(root) {
  animation: ia-curtain-open 380ms cubic-bezier(.87, 0, .13, 1) 300ms both;
  mix-blend-mode: normal;
}

/* Both snapshots sit in the same stacking context by default, which is what
   lets them blend. Isolating the pair keeps each one composited on its own. */
::view-transition-image-pair(root) { isolation: isolate; }

/* The group must last as long as the two halves put together, or the incoming
   animation is cut off partway and lands with a jump. */
::view-transition-group(root) { animation-duration: 680ms; }

@keyframes ia-curtain-close {
  from { clip-path: inset(0 0 0 0); }
  to   { clip-path: inset(0 50% 0 50%); }
}
@keyframes ia-curtain-open {
  from { clip-path: inset(0 50% 0 50%); transform: translateY(4px); }
  to   { clip-path: inset(0 0 0 0);     transform: none; }
}

/* Anyone who has asked their system to reduce motion gets an instant swap. */
@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) {
    animation: none !important;
  }
}
