/* ================================================================
   COMPONENT: CURTAIN — the page transition
   (class name kept for continuity; conceptually it is now a DISSOLVE)

   WHY THIS EXISTS INSTEAD OF A VIEW TRANSITION
   This site previously used a cross-document View Transition
   (`@view-transition { navigation: auto }` + `::view-transition-*`).
   It was removed. Measured, on real Chrome: the outgoing page reported
   a transition (`pageswap.hasVT = true`) while the incoming page got
   none (`pagereveal.hasVT = false`) — the browser abandoned the
   transition between documents, so the animation simply never ran, and
   there is no API to observe why. It also cannot be verified in a
   headless/background tab at all, because Chrome skips view transitions
   for hidden documents.

   The curtain owes nothing to the browser's capture machinery: it is a
   plain fixed element whose opacity is animated with CSS. The page swap
   happens underneath it, so a real document load still occurs (bfcache,
   no router, no module teardown, nothing to leak) and the motion is
   fully deterministic and testable.

   WHY IT IS PAPER, AND WHY IT FADES INSTEAD OF WIPING
   It used to be an opaque DEEP TEAL panel that WIPED up on a hard
   in-out curve. That was the wrong instinct twice over. The old note
   here argued a paper-coloured curtain "would be invisible against the
   paper pages" — true, and that is precisely the point. Both the
   homepage and every case page are the same warm paper, so a paper
   surface fading in and out is not read as a panel at all: it simply
   looks like the CONTENT leaving and arriving. There is no slab, no
   sweep, no colour event — the seam in the document swap just stops
   being visible.

   Wiping a saturated plane across the viewport on `cubic-bezier(0.76,
   0, 0.24, 1)` is a loud, mechanical gesture. Reference portfolios that
   read as premium (dousanmiao.com) move content 5–35px over 0.18–0.4s
   on near-linear-in curves and never cover anything. This is that,
   adapted to a real document navigation.

   THE MOTION — one quiet dissolve
     depart : opacity 0 -> 1  (--pt-leave,  0.2s)  content fades to blank paper
     arrive : opacity 1 at first paint, no flash
     reveal : opacity 1 -> 0  (--pt-reveal, 0.38s) content fades back in
   Reveal is longer than leave, so the arrival is the half you feel.
   The durations live in tokens.css and are mirrored by LEAVE_MS/REVEAL_MS in
   every page's head director — change all three together.
   ================================================================ */

.curtain {
  position: fixed;
  inset: 0;
  z-index: var(--z-curtain);
  /* Warm paper, not the hero teal — see the note above. */
  background-color: var(--surface-page);
  pointer-events: none;          /* never intercepts while parked */
  opacity: 0;
  will-change: opacity;
}

/* ── DEPART: dissolve to paper, then the browser navigates ──────── */
html.pt-leave .curtain {
  opacity: 1;
  transition: opacity var(--pt-leave, 0.2s) var(--ease-soft);
  pointer-events: auto;          /* swallow clicks once it's closing */
}

/* ── ARRIVE: already covering at first paint (no transition) ────── */
/* The head script adds this synchronously, before the new page paints, so
   there is never a flash of the un-transitioned page. */
html.pt-cover .curtain {
  opacity: 1;
}

/* ── REVEAL: dissolve away ──────────────────────────────────────── */
/* Declared AFTER `.pt-cover` so it wins when both are present — the
   script leaves `pt-cover` on and adds this, which avoids a race where
   removing one class in the same frame loses the transition's start value. */
html.pt-reveal .curtain {
  opacity: 0;
  transition: opacity var(--pt-reveal, 0.38s) var(--ease-soft);
}

@media (prefers-reduced-motion: reduce) {
  .curtain { display: none; }
}
