/* ─────────────────────────────────────────────────────────────────────────────
   Crossing between landing pages without the flash.

   The landing site is a handful of separate documents, deliberately: each is
   its own Vite entry so neither page carries the other's weight, /privacy and
   /terms are generated static HTML that must render with JavaScript disabled,
   and /404 is a standalone file Cloudflare Pages serves on a miss. The cost of
   that choice is a real navigation - the browser tears down one page and paints
   the next, and on a dark-panelled page the white gap between them is very
   visible. It read as a jolt rather than a move.

   Cross-document view transitions fix it at the browser level: no JS, no
   router, no delay before the navigation starts. The old page is captured, the
   new one fades up over it, and if the browser has never heard of any of this
   the navigation happens exactly as it does today. That is why this is a
   stylesheet rule and not a click handler - a click handler that animates
   BEFORE navigating makes the page slower to leave, which is the opposite of
   what is wanted.

   ── WHY THIS IS ITS OWN FILE IN public/, AND NOT A RULE IN index.css ───────

   Both documents must opt in: a transition needs the outgoing page to agree to
   be captured and the incoming page to agree to render into it. Opting in on
   one side only does nothing at all, silently. That makes WHERE this rule ends
   up a correctness question rather than a filing question, and index.css was
   the wrong answer twice over.

   It was the wrong answer for the two bundled pages because Vite decides which
   emitted stylesheet a rule lands in, and nobody chose it: the rule was
   compiling into `typeCycle-*.css`, the chunk named after the animated hero
   headline. Both entries happened to link that chunk, so both happened to opt
   in - an accident of chunk-sharing, not a decision. Stop importing one module
   from a page and the chunking changes shape, one document quietly stops opting
   in, and every navigation to it starts cutting instead. There is no error and
   no warning, because a half-opted-in transition is not a fault in the spec, it
   is simply no transition.

   It was the wrong answer for the generated pages because they never load
   index.css at all - /privacy, /terms and /404 are plain HTML with their own
   styles - so they carried a hand-copied duplicate of these rules instead. Two
   copies of a timing curve is how the two halves of one effect start
   disagreeing about what the effect is.

   One file, in public/ so it keeps a stable unhashed path, linked by every
   document the site serves. `scripts/check-view-transition.mjs` runs after the
   build and fails it if any document in dist/ stops opting in, because that is
   the failure this whole file exists to prevent and it is invisible by nature.
   ────────────────────────────────────────────────────────────────────────── */
@view-transition { navigation: auto; }

/* FADE THROUGH THE PAPER GROUND, rather than cross-fading the two pages.

   A plain cross-fade dissolves a blue hero into a dark ink panel, and for a
   moment you see both at once - which does not read as a transition, it reads
   as a rendering fault. Going out to a solid colour and back in from it is one
   move with a beat in the middle, and the beat is the thing that makes it feel
   deliberate instead of dropped.

   `::view-transition` is the root of the pseudo-element tree and paints behind
   both snapshots, so a background-color on it IS the colour you land on. The
   incoming animation starts AFTER the outgoing one finishes (140ms out, then
   in from 140ms) - the gap is when that colour is all there is. Overlap the
   two and the beat disappears and you are back to a cross-fade.

   Paper rather than navy or black: every page on the site now sits on the
   same #fbfaf7 ground, so the beat reads as the site rather than as the
   browser having lost the page. */
::view-transition { background-color: #fbfaf7; }

::view-transition-old(root) {
  animation: at-page-out 140ms cubic-bezier(0.4, 0, 1, 1) both;
}
::view-transition-new(root) {
  animation: at-page-in 220ms 140ms cubic-bezier(0, 0, 0.2, 1) both;
}

@keyframes at-page-out {
  from { opacity: 1; transform: scale(1); }
  to   { opacity: 0; transform: scale(0.994); }
}
@keyframes at-page-in {
  from { opacity: 0; transform: scale(1.006); }
  to   { opacity: 1; transform: scale(1); }
}

/* A cross-fade is motion, and a page that changes under someone who asked for
   less of it is the case this setting exists for. The navigation still happens;
   it just cuts. */
@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root),
  ::view-transition-new(root) { animation: none; }
}
