/* =============================================================================
   booster-3d.css - 3D booster stage of the opening view.

   Reference: `.docs/steps/4.md` point 1. The viewport hosts the Three.js canvas; the
   `is-fallback` modifier is applied when WebGL or the Three.js module is unavailable,
   in which case the 2D booster image is displayed instead.
   ============================================================================= */

.booster-3d {
  position: relative;
  display: grid;
  /* A single column pinned to the width of the box: without it the column is sized by the WebGL
     canvas, and a canvas left over from a wider window would inflate the stage instead of
     shrinking with it. */
  grid-template-columns: minmax(0, 1fr);
  place-items: center;
  /* 10 % narrower than its container, and slightly taller: the booster keeps free room on both
     sides, which is what lets the two extension arrows of the preview stick to the sides of the
     booster on a phone instead of sitting above and below it. */
  width: 90%;
  margin-inline: auto;
  min-height: 50vh;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background-image: radial-gradient(circle at 50% 38%, var(--color-surface-alt), var(--color-bg));
  overflow: hidden;
  /* The booster is dragged/swiped: the browser must not scroll instead. */
  touch-action: none;
  user-select: none;
  transition: opacity var(--duration-base) var(--easing-standard),
    transform var(--duration-base) var(--easing-standard);
}

.booster-3d__viewport {
  width: 100%;
  height: 50vh;
}

.booster-3d__viewport canvas {
  display: block;
  width: 100%;
  height: 100%;
}

.booster-3d__fallback {
  /* The 2D booster is zoomed out like the 3D one (10 % smaller). */
  max-height: 36vh;
  width: auto;
  /* Tapping the 2D image replaces the 3D open gesture. */
  cursor: pointer;
  filter: drop-shadow(var(--shadow-md));
  /* THE BOOSTER ARTWORKS ARE STORED UPSIDE DOWN.

     The UV map of `assets/boostermodel.glb` reads `assets/boosters/<setId>.png` with its V axis
     flipped, so the pack only stands right side up on the 3D model. Every place that shows that
     same PNG flat turns it back here: this fallback, the streaming overlay
     (`css/overlay.css`), the Mine Pick board (`css/views/minepick.css`) and the new-set popup
     (`css/components/modal.css`). Redrawing the source files is what would be wrong: the model
     would then show them mirrored.

     `rotate` instead of `transform`: the opening animations animate `transform`, and the two
     properties compose, so the pack stays upright through the whole tear. */
  rotate: 180deg;
}

.booster-3d__loading,
.booster-3d__hint {
  position: absolute;
  left: var(--space-3);
  right: var(--space-3);
  text-align: center;
  font-size: var(--font-size-xs);
  color: var(--color-text-muted);
  pointer-events: none;
}

.booster-3d__loading {
  top: 50%;
  transform: translateY(-50%);
  font-size: var(--font-size-sm);
}

.booster-3d__hint {
  bottom: var(--space-3);
}

/* --- States -------------------------------------------------------------- */

.booster-3d.is-fallback .booster-3d__viewport,
.booster-3d.is-fallback .booster-3d__hint {
  display: none;
}

.booster-3d.is-tearing .booster-3d__viewport,
.booster-3d.is-tearing .booster-3d__fallback {
  animation: booster-3d-tear var(--duration-base) var(--easing-standard) forwards;
}

.booster-3d.is-tearing .booster-3d__hint,
.booster-3d.is-tearing .booster-3d__loading {
  opacity: 0;
  transition: opacity var(--duration-fast) var(--easing-standard);
}

.booster-3d.is-dismissed {
  display: none;
}

@keyframes booster-3d-tear {
  from {
    opacity: 1;
    transform: translateY(0) scale(1) rotate(0deg);
  }
  to {
    opacity: 0;
    transform: translateY(-18%) scale(1.08) rotate(-3deg);
  }
}

@media (min-width: 768px) {
  .booster-3d,
  .booster-3d__viewport {
    min-height: 55vh;
    height: 55vh;
  }
}
