/* ==========================================================================
   Arrival — the short magician's reveal on the first homepage visit of a tab.
   Three red card backs fan out, the centre card turns to the spade, the cards
   gather and the curtain dissolves into the hero, whose throw then plays.

   Lifecycle (see js/arrival.js and the inline script in index.html's <head>):
   - The head script adds html.arrival-on + html.arrival-hold before first
     paint, only when the arrival should play. Without JavaScript, on repeat
     visits and under reduced motion neither class is set and nothing shows.
   - arrival-on shows the overlay and holds the page still underneath it.
   - arrival-hold keeps the hero's entrance paused (the same set styles.css
     pauses until the hero frames decode). arrival.js removes it as the
     overlay starts to dissolve, so the throw is seen, once.
   The sequence itself is CSS so it starts on first paint, not when the
   deferred scripts run. Tune it with the custom properties below.
   ========================================================================== */

.arrival {
  /* Card size: the longest side stays well inside a small phone screen. */
  --arrival-card: min(150px, 30vw, 19vh);
  /* Length of the fan, turn and gather. The dissolve (js/arrival.js) follows. */
  --arrival-dur: 0.98s;
  /* How far the outer cards swing out. */
  --arrival-fan-angle: 14deg;
  --arrival-fan-shift: 36%;

  display: none;
  position: fixed;
  inset: 0;
  z-index: 1000;
  place-items: center;
  background: var(--bg, #050404);
  /* The page stays still beneath; input is caught on window by arrival.js. */
  touch-action: none;
  /* The hard maximum, kept even if arrival.js is slow to arrive: the curtain
     lifts itself 1.5s after it first shows. arrival.js normally lifts it sooner. */
  animation: arrival-out 0.3s ease-out 1.5s forwards;
}

@keyframes arrival-out {
  to {
    opacity: 0;
    visibility: hidden;
  }
}

.js.arrival-on .arrival {
  display: grid;
}

/* Hold the page while the overlay is up. The gutter keeps the width the same
   when the scrollbar comes back, so nothing shifts as the overlay clears. */
.js.arrival-on {
  overflow: hidden;
  scrollbar-gutter: stable;
}

/* Hidden links under the overlay never show a hand cursor or hover state.
   Pointer events land on <html>, where arrival.js turns them into a skip. */
.js.arrival-on body {
  pointer-events: none;
}

/* Hold the hero's entrance (photo fade, wind-up, throw, headline rise) until
   the overlay dissolves. */
.js.arrival-hold .hero :is(.hero__photos, .hero__windup, .card, .card__shadow),
.js.arrival-hold .hero__content > * {
  animation-play-state: paused;
}

/* ---- The cards ------------------------------------------------------------ */

.arrival__fan {
  position: relative;
  width: var(--arrival-card);
  aspect-ratio: 5 / 7;
  animation: arrival-in 0.24s cubic-bezier(0.2, 0.7, 0.2, 1) backwards;
}

.arrival__card {
  position: absolute;
  inset: 0;
  border-radius: 5.6% / 4%;
  /* Pivot below the pack, so the outer cards swing on an arc like a held fan. */
  transform-origin: 50% 118%;
  transform-style: preserve-3d;
  box-shadow:
    0 0 0 1px rgba(0, 0, 0, 0.5),
    0 22px 40px -18px rgba(0, 0, 0, 0.95);
  animation: var(--arrival-dur) linear both;
}

.arrival__card::before,
.arrival__card::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background-size: 100% 100%;
  backface-visibility: hidden;
}

/* Back: original coded artwork. Deep red, a fine red lattice, a warm-white
   frame, a gold hairline and a small gold spade in an oval. */
.arrival__card::before {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 250 350'%3E%3Cdefs%3E%3ClinearGradient id='g' x1='0' y1='0' x2='1' y2='1'%3E%3Cstop offset='0' stop-color='%23a0141f'/%3E%3Cstop offset='1' stop-color='%23790d15'/%3E%3C/linearGradient%3E%3Cpattern id='p' width='12' height='12' patternUnits='userSpaceOnUse' patternTransform='rotate(45 125 175)'%3E%3Cpath d='M0 6H12M6 0V12' stroke='%23b3121e' stroke-width='1.1'/%3E%3C/pattern%3E%3C/defs%3E%3Crect width='250' height='350' rx='14' fill='url(%23g)'/%3E%3Crect x='15' y='15' width='220' height='320' rx='6' fill='url(%23p)'/%3E%3Crect x='15' y='15' width='220' height='320' rx='6' fill='none' stroke='%23f5efe4' stroke-opacity='.72' stroke-width='2.2'/%3E%3Crect x='21' y='21' width='208' height='308' rx='3' fill='none' stroke='%23d6ad62' stroke-opacity='.6'/%3E%3Cellipse cx='125' cy='175' rx='33' ry='45' fill='%238e111a' stroke='%23d6ad62' stroke-opacity='.85' stroke-width='1.6'/%3E%3Cpath transform='translate(125 176) scale(1.45)' fill='%23d6ad62' d='M0,-13C3.6,-7.6 12,-3.4 12,3.2C12,8.8 5.6,10.6 1.4,6.4C1.8,9.8 3.4,12.4 5.6,13.6H-5.6C-3.4,12.4 -1.8,9.8 -1.4,6.4C-5.6,10.6 -12,8.8 -12,3.2C-12,-3.4 -3.6,-7.6 0,-13Z'/%3E%3C/svg%3E");
}

/* Face (centre card only): warm white, a deep-red hairline frame, the spade. */
.arrival__card--c::after {
  transform: rotateY(180deg);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 250 350'%3E%3Cdefs%3E%3ClinearGradient id='g' x1='0' y1='0' x2='1' y2='1'%3E%3Cstop offset='0' stop-color='%23fbf6ec'/%3E%3Cstop offset='1' stop-color='%23ece4d4'/%3E%3C/linearGradient%3E%3Cpath id='s' d='M0,-13C3.6,-7.6 12,-3.4 12,3.2C12,8.8 5.6,10.6 1.4,6.4C1.8,9.8 3.4,12.4 5.6,13.6H-5.6C-3.4,12.4 -1.8,9.8 -1.4,6.4C-5.6,10.6 -12,8.8 -12,3.2C-12,-3.4 -3.6,-7.6 0,-13Z'/%3E%3C/defs%3E%3Crect width='250' height='350' rx='14' fill='url(%23g)'/%3E%3Crect x='13' y='13' width='224' height='324' rx='7' fill='none' stroke='%238e111a' stroke-opacity='.85' stroke-width='1.6'/%3E%3Cg fill='%23161413'%3E%3Cuse href='%23s' transform='translate(125 176) scale(3.3)'/%3E%3Cuse href='%23s' transform='translate(34 42) scale(.72)'/%3E%3Cuse href='%23s' transform='translate(216 308) rotate(180) scale(.72)'/%3E%3C/g%3E%3C/svg%3E");
}

/* The outer cards sit a touch further back. */
.arrival__card--l,
.arrival__card--r {
  filter: brightness(0.82);
}

.arrival__card--l {
  animation-name: arrival-fan-l;
}

.arrival__card--r {
  animation-name: arrival-fan-r;
}

.arrival__card--c {
  animation-name: arrival-turn;
}

@keyframes arrival-in {
  from {
    opacity: 0;
    transform: translateY(10px) scale(0.96);
  }
}

/* Squared pack, fan out, hold while the centre turns, gather. */
@keyframes arrival-fan-l {
  0%,
  20% {
    transform: translateX(0) rotate(0deg);
    animation-timing-function: cubic-bezier(0.2, 0.7, 0.2, 1);
  }
  50%,
  74% {
    transform: translateX(calc(var(--arrival-fan-shift) * -1)) rotate(calc(var(--arrival-fan-angle) * -1));
    animation-timing-function: cubic-bezier(0.55, 0, 0.25, 1);
  }
  94%,
  100% {
    transform: translateX(0) rotate(0deg);
  }
}

@keyframes arrival-fan-r {
  0%,
  20% {
    transform: translateX(0) rotate(0deg);
    animation-timing-function: cubic-bezier(0.2, 0.7, 0.2, 1);
  }
  50%,
  74% {
    transform: translateX(var(--arrival-fan-shift)) rotate(var(--arrival-fan-angle));
    animation-timing-function: cubic-bezier(0.55, 0, 0.25, 1);
  }
  94%,
  100% {
    transform: translateX(0) rotate(0deg);
  }
}

/* The centre card lifts slightly as it turns over, then settles on the spade. */
@keyframes arrival-turn {
  0%,
  44% {
    transform: perspective(800px) translateY(0) rotateY(0deg) scale(1);
    animation-timing-function: cubic-bezier(0.45, 0, 0.55, 1);
  }
  59% {
    transform: perspective(800px) translateY(-4%) rotateY(90deg) scale(1.05);
    animation-timing-function: cubic-bezier(0.45, 0, 0.25, 1);
  }
  74% {
    transform: perspective(800px) translateY(-2%) rotateY(180deg) scale(1.02);
    animation-timing-function: cubic-bezier(0.55, 0, 0.25, 1);
  }
  94%,
  100% {
    transform: perspective(800px) translateY(0) rotateY(180deg) scale(1);
  }
}

/* Belt and braces: the head script never starts the arrival under these. */
@media (prefers-reduced-motion: reduce) {
  .js.arrival-on .arrival {
    display: none;
  }

  .js.arrival-on {
    overflow: visible;
  }

  .js.arrival-on body {
    pointer-events: auto;
  }
}

@media print {
  .js.arrival-on .arrival {
    display: none;
  }
}
