/* ============================================================
   PAGE TRANSITION
   Clicking through to another page: white screen, the pink dot
   pops in, flicks through round objects, comes back, then grows
   until the screen is pink. The next page opens pink and the
   pink shrinks back into the dot to reveal it.
   Frames: assets/transition/*.webp (made in ChatGPT, see
   transition-frames/ for the full-size originals).
   Logic: page-transition.js, loaded in <head> on every page.
   ============================================================ */

/* Before page-transition.js has built the overlay on an arriving
   page, keep the screen pink so the new page never flashes. */
html.pt-entering::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 2147483000;
  background: #ff0099;
}

/* Plain ending: the new page opens on the white screen with the dot,
   sized and placed exactly like .pt-stage .pt-dot. */
html.pt-enter-plain::before {
  background: #ffffff;
}

html.pt-enter-plain::after {
  content: "";
  position: fixed;
  top: 50%;
  top: 50dvh;
  left: 50%;
  z-index: 2147483001;
  width: calc(min(62vmin, 520px) * 0.4);
  height: calc(min(62vmin, 520px) * 0.4);
  border-radius: 50%;
  background: #ff0099;
  transform: translate(-50%, -50%);
}

.pt-overlay {
  position: fixed;
  inset: 0;
  /* Dynamic viewport height where supported: the visible area on a phone. */
  height: 100vh;
  height: 100dvh;
  z-index: 2147483001;
  background: #ffffff;
  opacity: 0;
  pointer-events: none;
  transition: opacity 180ms ease;
}

.pt-overlay.is-on {
  opacity: 1;
  pointer-events: auto;
}

/* Arriving: no white sheet, the shrinking dot reveals the page. */
.pt-overlay.is-entering {
  background: transparent;
  opacity: 1;
  transition: none;
}

/* The stage is centred on the screen itself (not by the overlay's layout),
   so on a phone it stays in the middle of what is actually visible, whatever
   the browser toolbars are doing. */
.pt-stage {
  position: absolute;
  top: 50%;
  left: 50%;
  width: min(62vmin, 520px);
  aspect-ratio: 1 / 1;
  transform: translate(-50%, -50%);
}

.pt-frame {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  visibility: hidden;
}

.pt-frame.is-shown {
  visibility: visible;
}

/* The dot is 40% of the stage, the size every frame was drawn
   around, so objects read as the dot turning into something. */
.pt-dot {
  position: absolute;
  top: 30%;
  left: 30%;
  width: 40%;
  height: 40%;
  border-radius: 50%;
  background: #ff0099;
  transform: scale(0);
  will-change: transform;
}

.pt-dot.is-shown {
  transform: scale(1);
  transition: transform 220ms cubic-bezier(0.34, 1.56, 0.64, 1);
}

.pt-dot.is-hidden {
  visibility: hidden;
}

.pt-dot.is-growing {
  transform: scale(var(--pt-cover, 12));
  transition: transform 420ms cubic-bezier(0.7, 0, 0.84, 0);
}

/* Arriving: starts covering the screen, shrinks to nothing. */
.pt-dot.is-cover {
  transform: scale(var(--pt-cover, 12));
  transition: none;
}

.pt-dot.is-shrinking {
  transform: scale(0);
  transition: transform 560ms cubic-bezier(0.16, 1, 0.3, 1);
}

@media (prefers-reduced-motion: reduce) {
  html.pt-entering::before,
  html.pt-enter-plain::after,
  .pt-overlay {
    display: none;
  }
}
