/* ============================================================
   PAGE TRANSITIONS
   Fade-to-black between pages, plus the "rise into darkness"
   variant used when leaving the surface for the space page.
   Timings here are mirrored in assets/transitions.js — keep
   the two in step if you change them.
   ============================================================ */

:root {
  --pt-clear: 560ms;   /* veil clearing on arrival */
  --pt-close: 420ms;   /* veil closing on exit */
  --pt-prep: 200ms;    /* fixed chrome clearing out before the rise */
  --pt-ascend: 1100ms; /* home -> space rise */
}

/* The veil itself. Painted on the root element so it exists
   before the body does — no flash on a slow first paint. */
html::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 9999;
  background: #000;
  opacity: 0;
  pointer-events: none;
}

/* Arrival: hold solid black, then clear. */
html.pt-arriving::after { opacity: 1; }

html.pt-arrived::after {
  opacity: 0;
  transition: opacity var(--pt-clear) ease-out;
}

/* Exit: close the veil before navigating. */
html.pt-leaving { overflow: hidden; }

html.pt-leaving::after {
  opacity: 1;
  pointer-events: auto;
  transition: opacity var(--pt-close) ease-in;
}

/* Travelling between the surface and the space layer.

   The move is a transform on <body>, and a transformed ancestor
   becomes the containing block for its position:fixed descendants
   — so the fixed chrome has to be off screen before the transform
   lands, or it snaps to a new anchor mid-shot. A page can lengthen
   this window with data-pt-prep on <html> when it has its own
   content to clear out first. */
html.pt-chrome-out .site-header,
html.pt-chrome-out .depth-meter,
html.pt-chrome-out .depth-gauge,
html.pt-chrome-out .scroll-hint,
html.pt-chrome-out .top-buffer-hint {
  opacity: 0;
  transition: opacity var(--pt-prep) ease-out;
}

html.pt-ascending .site-header,
html.pt-ascending .depth-meter,
html.pt-ascending .depth-gauge,
html.pt-ascending .scroll-hint,
html.pt-ascending .top-buffer-hint,
html.pt-descending .site-header,
html.pt-descending .depth-meter,
html.pt-descending .depth-gauge,
html.pt-descending .scroll-hint,
html.pt-descending .top-buffer-hint {
  visibility: hidden;
}

html.pt-ascending,
html.pt-descending {
  overflow: hidden;
  background: #000;
}

/* Going up: the page slides DOWN so the view appears to travel up
   past it, with the dark arriving from above. */
html.pt-ascending body {
  transform: translateY(16vh);
  transition: transform var(--pt-ascend) cubic-bezier(0.45, 0, 0.75, 0.15);
}

/* Coming back down: the same move, mirrored. */
html.pt-descending body {
  transform: translateY(-16vh);
  transition: transform var(--pt-ascend) cubic-bezier(0.45, 0, 0.75, 0.15);
}

html.pt-ascending::after,
html.pt-descending::after {
  opacity: 1;
  pointer-events: auto;
  transition: opacity var(--pt-ascend) cubic-bezier(0.6, 0, 0.85, 0.35);
}

@media (prefers-reduced-motion: reduce) {
  html.pt-ascending body,
  html.pt-descending body {
    transform: none;
    transition: none;
  }

  html.pt-arrived::after,
  html.pt-leaving::after,
  html.pt-ascending::after,
  html.pt-descending::after {
    transition-duration: 1ms;
  }
}
