.hero-upload {
  aspect-ratio: 3 / 2;
  container-type: inline-size;
}

.hero-upload__scene {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
}

.hero-upload__stage {
  position: absolute;
  z-index: 1;
  top: 0;
  inset-inline: 0;
  text-align: center;
  font-size: clamp(14px, 4.6cqw, 22px);
  line-height: 1.2;
  letter-spacing: -.025em;
}

.hero-upload__stage > span { grid-area: 1 / 1; }
.hero-upload__phase { opacity: 0; }

/* The unanimated scene is the completed delivery, including the open box and files. */
.hero-upload__world,
.hero-upload__destination-key { transform: translateX(-960px); }
.hero-upload__computer { transform: translate(9.6px, 9px) scale(.96); }
.hero-upload__box-scale { transform: translate(0, .92px) scale(.72); transform-origin: 240px 154px; }
/* The lid stands open on its back hinge: real 3D rotation, projected with the box's oblique camera. */
.hero-upload__lid-plate { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, -0.4, 0.35, 1, 0, 0, 0, 0, 1) translate3d(0, 0, -40px) rotateX(94deg) translate3d(0, 0, 40px) rotateX(-90deg); transform-origin: 0 0; }
.hero-upload__lid-flap { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, -0.4, 0.35, 1, 0, 0, 0, 0, 1) translate3d(0, 0, -40px) rotateX(94deg) translate3d(0, 0, 40px) translate3d(0, 0, 0.8px); transform-origin: 0 0; }
.hero-upload__incoming .hero-upload__layer-front,
.hero-upload__lid-front,
.hero-upload__lid-outer,
.hero-upload__layer-back,
.hero-upload__network,
.hero-upload__trails,
.hero-upload__sheen,
.hero-upload__key-edge,
.hero-upload__key,
.hero-upload__pulse { opacity: 0; }
.hero-upload__outgoing { transform: translate(126px, -4px) scale(1); }
.hero-upload__key,
.hero-upload__key-turn { transform-origin: 0 0; }
.hero-upload__receipt { transform-origin: 359px 187.5px; }
.hero-upload__box-sway { transform-origin: 240px 229px; }
.hero-upload__pulse { transform-origin: 240px 172px; }

@media (prefers-reduced-motion: no-preference) {
  .hero-upload[data-animated] [data-loop] {
    animation-duration: 13.5s;
    animation-iteration-count: infinite;
    animation-timing-function: ease-in-out;
    animation-fill-mode: both;
    animation-play-state: paused;
  }

  .hero-upload[data-animated][data-running] [data-loop] { animation-play-state: running; }
  .hero-upload[data-animated] .hero-upload__static { opacity: 0; }
  .hero-upload[data-animated] .hero-upload__file-1,
  .hero-upload[data-animated] .hero-upload__file-1 > [data-loop] { animation-delay: .1s; }
  .hero-upload[data-animated] .hero-upload__file-2,
  .hero-upload[data-animated] .hero-upload__file-2 > [data-loop] { animation-delay: .2s; }
  .hero-upload[data-animated] .hero-upload__pulse-echo { animation-delay: .18s; }
  .hero-upload[data-animated] .hero-upload__pulse { animation-timing-function: cubic-bezier(.22, 1, .36, 1); }
  .hero-upload[data-animated] .hero-upload__phase { animation-timing-function: cubic-bezier(.22, 1, .36, 1); }

  .hero-upload[data-animated] [data-loop="visibility"] { animation-name: hero-safe-visibility; }
  .hero-upload[data-animated] [data-loop="network"] { animation-name: hero-safe-network; }
  .hero-upload[data-animated] [data-loop="trails"] { animation-name: hero-safe-trails; }
  .hero-upload[data-animated] [data-loop="fiber"] { animation-name: hero-safe-fiber; }
  .hero-upload[data-animated] [data-loop="sheen"] { animation-name: hero-safe-sheen; }
  .hero-upload[data-animated] [data-loop="world"] { animation-name: hero-safe-world; }
  .hero-upload[data-animated] [data-loop="computer"] { animation-name: hero-safe-computer; }
  .hero-upload[data-animated] [data-loop="box-scale"] { animation-name: hero-safe-box-scale; }
  .hero-upload[data-animated] [data-loop="box-sway"] { animation-name: hero-safe-box-sway; }
  .hero-upload[data-animated] [data-loop="lid-plate"] { animation-name: hero-safe-lid-plate; }
  .hero-upload[data-animated] [data-loop="lid-flap"] { animation-name: hero-safe-lid-flap; }
  .hero-upload[data-animated] [data-loop="lid-front"] { animation-name: hero-safe-lid-front; }
  .hero-upload[data-animated] [data-loop="lid-back"] { animation-name: hero-safe-lid-back; }
  .hero-upload[data-animated] [data-loop="lid-outer"] { animation-name: hero-safe-lid-outer; }
  .hero-upload[data-animated] [data-loop="lid-lining"] { animation-name: hero-safe-lid-lining; }
  .hero-upload[data-animated] [data-loop="wheel"] { animation-name: hero-safe-wheel; }
  .hero-upload[data-animated] [data-loop="pulse-lock"] { animation-name: hero-safe-pulse-lock; }
  .hero-upload[data-animated] [data-loop="pulse-unlock"] { animation-name: hero-safe-pulse-unlock; }
  .hero-upload[data-animated] [data-loop="no-key"] { animation-name: hero-safe-no-key; }
  .hero-upload[data-animated] [data-loop="incoming"] { animation-name: hero-safe-incoming; }
  .hero-upload[data-animated] [data-loop="incoming-front"] { animation-name: hero-safe-incoming-front; }
  .hero-upload[data-animated] [data-loop="incoming-back"] { animation-name: hero-safe-incoming-back; }
  .hero-upload[data-animated] [data-loop="outgoing"] { animation-name: hero-safe-outgoing; }
  .hero-upload[data-animated] [data-loop="outgoing-front"] { animation-name: hero-safe-outgoing-front; }
  .hero-upload[data-animated] [data-loop="outgoing-back"] { animation-name: hero-safe-outgoing-back; }
  .hero-upload[data-animated] [data-loop="key"] { animation-name: hero-safe-key; }
  .hero-upload[data-animated] [data-loop="key-insert"] { animation-name: hero-safe-key-insert; }
  .hero-upload[data-animated] [data-loop="key-turn"] { animation-name: hero-safe-key-turn; }
  .hero-upload[data-animated] [data-loop="key-edge"] { animation-name: hero-safe-key-edge; }
  .hero-upload[data-animated] [data-loop="receipt"] { animation-name: hero-safe-receipt; }
  .hero-upload[data-animated] [data-loop="scene-client"] { animation-name: hero-safe-scene-client; }
  .hero-upload[data-animated] [data-loop="scene-server"] { animation-name: hero-safe-scene-server; }
  .hero-upload[data-animated] [data-loop="scene-key"] { animation-name: hero-safe-scene-key; }

  .hero-upload[data-animated] [data-loop="fiber-pulses"] {
    animation-name: hero-safe-fiber-pulses;
    animation-duration: .24s;
    animation-timing-function: linear;
  }

  .hero-upload[data-animated] [data-loop="server-ciphertext"] {
    animation-name: hero-safe-server-ciphertext;
    animation-duration: 2.4s;
    animation-timing-function: linear;
  }

  .hero-upload[data-animated] [data-loop="led"] {
    animation-name: hero-safe-led;
    animation-duration: 1.4s;
  }

  .hero-upload[data-animated] .hero-upload__led-1 { animation-delay: -.5s; }
  .hero-upload[data-animated] .hero-upload__led-2 { animation-delay: -.9s; }

  .hero-upload[data-animated] [data-loop="trails-near"],
  .hero-upload[data-animated] [data-loop="trails-far"] {
    animation-name: hero-safe-trail-drift;
    animation-duration: .75s;
    animation-timing-function: linear;
  }

  .hero-upload[data-animated] [data-loop="trails-far"] {
    animation-duration: 1.1s;
  }
}

/* Ten and a half seconds for the handoff, then three seconds with no title.
   The completed delivery stays still throughout the pause. */
@keyframes hero-safe-visibility {
  0% { opacity: 0; }
  1.111%, 76.667% { opacity: 1; }
  77.778%, 100% { opacity: 0; }
}

/* Travel into the cloud, dock on the server for three seconds, then travel on to the recipient. */
@keyframes hero-safe-world {
  0%, 14.074% { transform: translateX(0); animation-timing-function: cubic-bezier(.45, 0, .2, 1); }
  25.926%, 46.667% { transform: translateX(-480px); animation-timing-function: cubic-bezier(.5, 0, .25, 1); }
  60%, 100% { transform: translateX(-960px); }
}

@keyframes hero-safe-computer {
  0%, 14.074% { transform: translate(9.6px, 9px) scale(.96); }
  18.148%, 51.852% { transform: translate(115.2px, 60px) scale(.52); }
  60%, 100% { transform: translate(9.6px, 9px) scale(.96); }
}

@keyframes hero-safe-box-scale {
  0%, 14.074% { transform: translate(0, 0.92px) scale(.72); }
  19.63%, 50.37% { transform: translate(0, 2.08px) scale(.72); }
  60%, 100% { transform: translate(0, 0.92px) scale(.72); }
}

/* Settle as the lid slaps shut, lag on departure, lean into each stop. */
@keyframes hero-safe-box-sway {
  0%, 9.615% { transform: rotate(0) translateY(0) scale(1); }
  10.104% { transform: rotate(0) translateY(0) scale(1.02, .975); }
  11.081%, 14.341% { transform: rotate(0) translateY(0) scale(1); }
  16.704% { transform: rotate(-3.5deg) translateY(0) scale(1); }
  19.556% { transform: rotate(1.2deg) translateY(-1px) scale(1); }
  21.852% { transform: rotate(-.3deg) translateY(0) scale(1); }
  24.444% { transform: rotate(2.5deg) translateY(0) scale(1); }
  26.815% { transform: rotate(-1deg) translateY(0) scale(1); }
  28.519%, 46.667% { transform: rotate(0) translateY(0) scale(1); }
  48.889% { transform: rotate(-3deg) translateY(0) scale(1); }
  51.481% { transform: rotate(1deg) translateY(-1px) scale(1); }
  54.074% { transform: rotate(-.3deg) translateY(0) scale(1); }
  57.407% { transform: rotate(3deg) translateY(0) scale(1); }
  60.37% { transform: rotate(-1.2deg) translateY(0) scale(1); }
  62.37%, 100% { transform: rotate(0) translateY(0) scale(1); }
}

@keyframes hero-safe-network {
  0%, 13.704% { opacity: 0; }
  17.037%, 55.926% { opacity: 1; }
  60%, 100% { opacity: 0; }
}

/* Speed lines and data pulses stop while the box rests on the server. */
@keyframes hero-safe-trails {
  0%, 17.407% { opacity: 0; }
  19.63%, 21.852% { opacity: 1; }
  24.444%, 47.778% { opacity: 0; }
  50%, 53.704% { opacity: 1; }
  56.296%, 100% { opacity: 0; }
}

@keyframes hero-safe-fiber {
  0%, 23.333% { opacity: 1; }
  25.926%, 46.296% { opacity: 0; }
  48.889%, 100% { opacity: 1; }
}

@keyframes hero-safe-fiber-pulses {
  from { transform: translateX(0); }
  to { transform: translateX(180px); }
}

@keyframes hero-safe-trail-drift {
  0% { opacity: 0; transform: translateX(36px); }
  20% { opacity: .8; }
  75% { opacity: .5; }
  100% { opacity: 0; transform: translateX(-54px); }
}

@keyframes hero-safe-server-ciphertext {
  from { transform: translateX(0); }
  to { transform: translateX(-120px); }
}

@keyframes hero-safe-led {
  0%, 100% { opacity: 1; }
  50% { opacity: .35; }
}

@keyframes hero-safe-sheen {
  0%, 11.704% { opacity: 0; transform: translateX(0); }
  12% { opacity: 1; transform: translateX(0); }
  15.556% { opacity: 0; transform: translateX(230px); }
  33.333% { opacity: 0; transform: translateX(0); }
  33.704% { opacity: 1; transform: translateX(0); }
  37.407%, 100% { opacity: 0; transform: translateX(230px); }
}

/* The lid swings on its back hinge: closing accelerates into the slam, opening eases out. */
@keyframes hero-safe-lid-plate {
  0%, 7.556% { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, -0.4, 0.35, 1, 0, 0, 0, 0, 1) translate3d(0, 0, -40px) rotateX(94deg) translate3d(0, 0, 40px) rotateX(-90deg); animation-timing-function: cubic-bezier(.333, 0, .667, .333); }
  9.778%, 67.407% { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, -0.4, 0.35, 1, 0, 0, 0, 0, 1) translate3d(0, 0, -40px) rotateX(0deg) translate3d(0, 0, 40px) rotateX(-90deg); animation-timing-function: cubic-bezier(.333, .667, .667, 1); }
  69.259%, 100% { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, -0.4, 0.35, 1, 0, 0, 0, 0, 1) translate3d(0, 0, -40px) rotateX(94deg) translate3d(0, 0, 40px) rotateX(-90deg); }
}

@keyframes hero-safe-lid-flap {
  0%, 7.556% { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, -0.4, 0.35, 1, 0, 0, 0, 0, 1) translate3d(0, 0, -40px) rotateX(94deg) translate3d(0, 0, 40px) translate3d(0, 0, 0.8px); animation-timing-function: cubic-bezier(.333, 0, .667, .333); }
  9.778%, 67.407% { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, -0.4, 0.35, 1, 0, 0, 0, 0, 1) translate3d(0, 0, -40px) rotateX(0deg) translate3d(0, 0, 40px) translate3d(0, 0, 0.8px); animation-timing-function: cubic-bezier(.333, .667, .667, 1); }
  69.259%, 100% { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, -0.4, 0.35, 1, 0, 0, 0, 0, 1) translate3d(0, 0, -40px) rotateX(94deg) translate3d(0, 0, 40px) translate3d(0, 0, 0.8px); }
}

/* Drawn in front of the box while the flap overlaps it, behind the files once it stands clear. */
@keyframes hero-safe-lid-front {
  0%, 8.674% { opacity: 0; }
  8.689%, 68.319% { opacity: 1; }
  68.333%, 100% { opacity: 0; }
}

@keyframes hero-safe-lid-back {
  0%, 8.674% { opacity: 1; }
  8.689%, 68.319% { opacity: 0; }
  68.333%, 100% { opacity: 1; }
}

/* The top shows its outside only while it faces the viewer; past edge-on we see its lining. */
@keyframes hero-safe-lid-outer {
  0%, 9.526% { opacity: 0; }
  9.541%, 67.6% { opacity: 1; }
  67.615%, 100% { opacity: 0; }
}

@keyframes hero-safe-lid-lining {
  0%, 9.526% { opacity: 1; }
  9.541%, 67.6% { opacity: 0; }
  67.615%, 100% { opacity: 1; }
}

/* Like a vault: the wheel turns a full revolution to throw the bolts after the lid shuts, and back once the key has turned. */
@keyframes hero-safe-wheel {
  0%, 9.778% { transform: rotate(0); }
  12.148% { transform: rotate(372deg); }
  12.889%, 65.926% { transform: rotate(360deg); }
  68%, 100% { transform: rotate(0); }
}

/* A ring of light marks the bolts going home, the lock holding on the server, and decryption. */
@keyframes hero-safe-pulse-lock {
  0%, 11.852% { opacity: 0; transform: scale(.9); }
  12.148% { opacity: .75; transform: scale(.95); }
  16.148%, 26.37% { opacity: 0; transform: scale(1.9); }
  26.667% { opacity: .6; transform: scale(.95); }
  30.741%, 100% { opacity: 0; transform: scale(1.9); }
}

@keyframes hero-safe-pulse-unlock {
  0%, 65.452% { opacity: 0; transform: scale(.9); }
  65.778% { opacity: .7; transform: scale(.95); }
  69.852%, 100% { opacity: 0; transform: scale(1.9); }
}

/* The server has no key: the sign pops up while the box waits there. */
@keyframes hero-safe-no-key {
  0%, 28.519% { opacity: 0; transform: scale(.4); }
  30% { opacity: 1; transform: scale(1.15); }
  30.963%, 43.704% { opacity: 1; transform: scale(1); }
  45.556%, 100% { opacity: 0; transform: scale(.6); }
}

/* Arc over the box and drop in. */
@keyframes hero-safe-incoming {
  0%, 1.333% { transform: translate(126px, -4px) scale(1); }
  4.444% { transform: translate(0, -72px) scale(.5); }
  6.37%, 100% { transform: translate(0, -4px) scale(.5); }
}

/* Above the box while arcing over it, behind the front wall once dropping in. */
@keyframes hero-safe-incoming-front {
  0%, 4.444% { opacity: 1; }
  4.459%, 100% { opacity: 0; }
}

@keyframes hero-safe-incoming-back {
  0%, 4.444% { opacity: 0; }
  4.459%, 11.111% { opacity: 1; }
  12%, 100% { opacity: 0; }
}

/* Rise out of the box; the files swap into the identical sender position when the next cycle begins. */
@keyframes hero-safe-outgoing {
  0%, 69.037% { transform: translate(0, -4px) scale(.5); }
  70.815% { transform: translate(0, -74px) scale(.58); }
  73.333%, 100% { transform: translate(126px, -4px) scale(1); }
}

@keyframes hero-safe-outgoing-back {
  0%, 68.296% { opacity: 0; }
  69.037%, 70.815% { opacity: 1; }
  70.83%, 100% { opacity: 0; }
}

@keyframes hero-safe-outgoing-front {
  0%, 70.815% { opacity: 0; }
  70.83%, 100% { opacity: 1; }
}

/* Hover, align, insert into the wheel's hub, turn around the fixed shaft, then disappear before the wheel spins back. */
@keyframes hero-safe-key {
  0%, 49.63% { opacity: 0; transform: translate(84px, -24px) scale(1.25); }
  51.111% { opacity: 1; transform: translate(84px, -24px) scale(1.25); }
  54.074% { opacity: 1; transform: translate(84px, -27px) scale(1.25); }
  57.037% { opacity: 1; transform: translate(84px, -22px) scale(1.25); }
  60% { opacity: 1; transform: translate(84px, -24px) scale(1.25); }
  62.222%, 65.778% { opacity: 1; transform: translate(0, 0) scale(1); }
  66.296%, 100% { opacity: 0; transform: translate(0, 0) scale(1); }
}

@keyframes hero-safe-key-insert {
  0%, 62.222% { transform: translateX(14px); }
  63.704%, 100% { transform: translateX(-8px); }
}

@keyframes hero-safe-key-turn {
  0%, 63.704% { transform: rotateX(0); }
  65.63%, 100% { transform: rotateX(90deg); }
}

/* Preserve the bow's thickness when seen edge-on after the quarter turn. */
@keyframes hero-safe-key-edge {
  0%, 63.704% { opacity: 0; }
  65.63%, 100% { opacity: 1; }
}

@keyframes hero-safe-receipt {
  0%, 73.926% { opacity: 0; transform: scale(.7); }
  75.037% { opacity: 1; transform: scale(1.1); }
  75.926%, 100% { opacity: 1; transform: scale(1); }
}

/* Each title clears before the next appears; layout dimensions never change. */
@keyframes hero-safe-scene-client {
  0% { opacity: 0; transform: translateY(6px); }
  1.111%, 12.889% { opacity: 1; transform: translateY(0); }
  14.074%, 100% { opacity: 0; transform: translateY(-4px); }
}

@keyframes hero-safe-scene-server {
  0%, 25.556% { opacity: 0; transform: translateY(6px); }
  26.667%, 45.556% { opacity: 1; transform: translateY(0); }
  46.667%, 100% { opacity: 0; transform: translateY(-4px); }
}

/* No title while travelling; the team key closes the story once the box has arrived. */
@keyframes hero-safe-scene-key {
  0%, 60% { opacity: 0; transform: translateY(6px); }
  61.111%, 76.667% { opacity: 1; transform: translateY(0); }
  77.778%, 100% { opacity: 0; transform: translateY(-4px); }
}
