/* ============================================================
   PAGE TRANSITIONS - Quasi Interactive
   ============================================================
   Two journeys, two different feelings, because the two places do not
   feel the same.

   INTO blank.   The tape crossing. Colour drains out of the picture, the
                 grain comes up, and the dark closes over it - which is the
                 move the GAME makes between its chapters, where tape
                 colour, grain, grey and light all ride one eased number
                 while he walks the corridor. Anyone who has played it will
                 half-recognise this without being able to say why.

   BACK to the   The channel change. A burst of static, the tracking bar
   studio.       rolling through it, and the studio snapping back on a CRT
                 power-on line. Built from the static and the VHS bar the
                 site already runs, so it reads as part of the same signal.

   It sits above .static-overlay (9999), never takes a click, and is
   invisible until asked for. Nothing here runs at all if the visitor has
   asked for reduced motion - see transition.js.
   ============================================================ */

.tx {
  position: fixed;
  inset: 0;
  z-index: 10000;
  pointer-events: none;
  visibility: hidden;
  overflow: hidden;
}

.tx.is-on { visibility: visible; }

.tx > * {
  position: absolute;
  inset: 0;
  opacity: 0;
}

/* the same noise the rest of the site is grained with */
.tx-grain {
  inset: -60px;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)' opacity='1'/%3E%3C/svg%3E");
  background-size: 256px 256px;
  will-change: opacity, transform;
}

/* GREY, BLENDED AS SATURATION: a flat grey blended this way keeps the
   backdrop's hue and brightness and takes its colour away, so the page
   drains rather than being washed over. */
.tx-desat {
  background: #808080;
  mix-blend-mode: saturation;
}

.tx-dark { background: #000; }

/* the tracking bar, on its way through */
.tx-scan {
  inset: auto 0 auto 0;
  height: 16vh;
  top: -18vh;
  background: linear-gradient(to bottom,
              rgba(255,255,255,0) 0%,
              rgba(255,255,255,0.10) 35%,
              rgba(255,255,255,0.85) 50%,
              rgba(255,255,255,0.10) 65%,
              rgba(255,255,255,0) 100%);
}

/* the CRT line: a full-height sheet squashed to a hairline, then let go */
.tx-line {
  background: #fff;
  transform: scaleY(0.004);
  transform-origin: 50% 50%;
  will-change: transform, opacity;
}

/* ---------- 1. LEAVING FOR blank. : the tape crossing ---------- */
.tx--blank-out .tx-grain {
  animation: txTo 520ms linear both, txJitter 0.25s steps(3) infinite;
  --to: 0.42;
}
.tx--blank-out .tx-desat { animation: txTo 360ms ease-out both; --to: 1; }
.tx--blank-out .tx-dark  { animation: txTo 420ms cubic-bezier(.55,0,.85,.35) 150ms both; --to: 1; }

/* ---------- 2. ARRIVING AT blank. : up out of the dark ---------- */
.tx--blank-in .tx-dark  { animation: txFrom 620ms ease-out 60ms both; --from: 1; }
.tx--blank-in .tx-desat { animation: txFrom 700ms ease-out both; --from: 1; }
.tx--blank-in .tx-grain {
  animation: txFrom 720ms linear both, txJitter 0.25s steps(3) infinite;
  --from: 0.42;
}

/* ---------- 3. LEAVING FOR THE STUDIO : the channel change ---------- */
.tx--studio-out .tx-grain {
  animation: txTo 200ms linear both, txJitter 0.08s steps(4) infinite;
  --to: 0.8;
}
.tx--studio-out .tx-scan { animation: txScanDown 400ms cubic-bezier(.4,0,.6,1) both; }
.tx--studio-out .tx-dark { animation: txTo 160ms linear 300ms both; --to: 1; }

/* ---------- 4. ARRIVING AT THE STUDIO : the set comes on ---------- */
.tx--studio-in .tx-dark  { animation: txFrom 480ms ease-out 140ms both; --from: 1; }
.tx--studio-in .tx-line  { animation: txCrt 440ms cubic-bezier(.2,.8,.3,1) both; }
.tx--studio-in .tx-grain {
  animation: txFrom 560ms linear both, txJitter 0.1s steps(4) infinite;
  --from: 0.55;
}

/* ---------- the four movements ---------- */
@keyframes txTo   { from { opacity: 0; }         to { opacity: var(--to, 1); } }
@keyframes txFrom { from { opacity: var(--from, 1); } to { opacity: 0; } }

@keyframes txScanDown {
  0%   { opacity: 0;   top: -18vh; }
  12%  { opacity: 1; }
  88%  { opacity: 1; }
  100% { opacity: 0;   top: 100vh; }
}

@keyframes txCrt {
  0%   { opacity: 0;    transform: scaleY(0.004); }
  14%  { opacity: 1;    transform: scaleY(0.004); }
  55%  { opacity: 0.9;  transform: scaleY(1); }
  100% { opacity: 0;    transform: scaleY(1); }
}

@keyframes txJitter {
  0%   { transform: translate(0, 0); }
  25%  { transform: translate(-3px, 2px); }
  50%  { transform: translate(2px, -3px); }
  75%  { transform: translate(-2px, -1px); }
  100% { transform: translate(0, 0); }
}

/* Nobody who has asked for stillness gets any of this. transition.js also
   refuses to intercept the click, so the link simply works. */
@media (prefers-reduced-motion: reduce) {
  .tx, .tx * { animation: none !important; visibility: hidden !important; opacity: 0 !important; }
}
