/* Minimal styling */
* { box-sizing: border-box; }
body { margin: 0; font-family: system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif; background:#0b0c10; color:#e6edf3; }
a { color:#79c0ff; }
.container { max-width: 960px; margin: 40px auto; padding: 0 16px; }
.menu { line-height: 1.8; }
.hint { opacity: 0.7; }

/* Packs page */
.shelf { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 12px; margin: 16px 0 24px; }
.pack-icon { height: 160px; background-size: cover; background-position: center; border: 2px solid #222; border-radius: 12px; cursor: pointer; box-shadow: 0 2px 8px rgba(0,0,0,0.4); }
.pack-icon:disabled { opacity: 0.35; cursor:not-allowed; }
.inventory { margin-top: 12px; opacity: 0.85; }

.stack { display:flex; flex-wrap: wrap; gap: 12px; min-height: 220px; margin: 12px 0; }
.card { width: 160px; height: 224px; background-size: cover; background-position: center; border-radius: 12px; border: 2px solid #161b22; box-shadow: 0 2px 10px rgba(0,0,0,0.6); }
.card.reveal { animation: flip 300ms ease-in; }
@keyframes flip { from { transform: rotateY(90deg); opacity:0; } to { transform: rotateY(0deg); opacity:1; } }

.glow { box-shadow: 0 0 16px rgba(130, 200, 255, 0.6), 0 0 28px rgba(130, 200, 255, 0.35); }
.shake { animation: shake 250ms ease-in; }
@keyframes shake {
  /* Reduce shaking amplitude for a subtler effect */
  10%, 90% { transform: translate3d(-0.5px, 0, 0); }
  20%, 80% { transform: translate3d(1px, 0, 0); }
  30%, 50%, 70% { transform: translate3d(-1.5px, 0, 0); }
  40%, 60% { transform: translate3d(1.5px, 0, 0); }
}

/* Hold‑to‑open effects for pack icons */
/* A subtle glowing outline while holding down */
.hold-glow {
  box-shadow: 0 0 16px rgba(255, 215, 0, 0.8), 0 0 32px rgba(255, 215, 0, 0.4);
}
/* Continuous shake while holding down */
.hold-shake {
  animation: shake 300ms ease-in-out infinite;
}
/* Explosion animation used when a booster is opened directly from the
   inventory.  Scales up the angled pack and fades it out. */
.pack-diag.explode {
  animation: packExplode 600ms ease-out forwards;
}
@keyframes packExplode {
  from {
    transform: rotateX(28deg) rotateZ(-14deg) scale(1);
    opacity: 1;
  }
  to {
    transform: rotateX(28deg) rotateZ(-14deg) scale(1.6);
    opacity: 0;
  }
}

button { background:#21262d; border:1px solid #30363d; color:#e6edf3; padding:8px 12px; border-radius:8px; }
button:hover { border-color:#8b949e; }

/* Collection page */
.collection-grid { display:grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 12px; margin: 16px 0; }
.sleeve { width: 160px; height: 224px; border-radius: 12px; border: 2px solid #222; background:#111; background-size: cover; background-position:center; position: relative; box-shadow: inset 0 0 20px rgba(255,255,255,0.06); }
.sleeve.owned { outline: 2px solid rgba(166, 116, 255, 0.7); }
.sleeve.missing { filter: grayscale(1) brightness(0.5); }

.sleeve .label { position:absolute; bottom:6px; left:6px; right:6px; background: rgba(0,0,0,0.5); padding:4px 6px; border-radius:6px; text-overflow:ellipsis; overflow:hidden; white-space:nowrap; font-size: 12px; }

.pagination { display:flex; align-items:center; gap: 12px; margin: 8px 0 16px; }

.modal { position:fixed; inset:0; display:flex; align-items:center; justify-content:center; background: rgba(0,0,0,0.6); }
.modal.hidden { display:none; }

/* Generic hidden class used to hide elements like the info bubble */
.hidden { display: none !important; }
.card-sheet { display:grid; grid-template-columns: 1fr 1fr; gap:16px; width: min(900px, 92vw); background:#0e1116; border:1px solid #30363d; border-radius:12px; padding:16px; }
.card-sheet .art { height: 420px; background-size: cover; background-position: center; border-radius:12px; border:1px solid #222; }
.card-sheet .meta h3 { margin: 0 0 8px 0; }
.card-sheet .meta p { margin: 6px 0; }

/* --- FX & badges --- */
.badge-new {
  position: absolute;
  top: 8px; right: 8px;
  background: #10b981;
  color: #071a14;
  font-weight: 700;
  font-size: 12px;
  padding: 4px 6px;
  border-radius: 6px;
  box-shadow: 0 0 10px rgba(16,185,129,0.5);
  transform: rotate(-6deg) scale(0.9);
  animation: badgePop 350ms ease-out;
}
@keyframes badgePop {
  0% { transform: rotate(-6deg) scale(0.5); opacity: 0; }
  100% { transform: rotate(-6deg) scale(0.9); opacity: 1; }
}

.fx-rays {
  position: absolute;
  inset: -20px;
  background: conic-gradient(from 0deg, rgba(255,255,255,0.1), rgba(255,255,0,0.2), rgba(255,255,255,0.1));
  filter: blur(8px);
  border-radius: 14px;
  animation: spinRays 2200ms linear infinite;
  pointer-events: none;
}
@keyframes spinRays { to { transform: rotate(360deg); } }

.fx-burst {
  position:absolute;
  inset:-10px;
  background: radial-gradient(circle at center, rgba(255,255,255,0.35), rgba(255,255,255,0.0) 60%);
  filter: blur(6px);
  border-radius: 14px;
  animation: pulseBurst 900ms ease-out;
  pointer-events: none;
}
@keyframes pulseBurst {
  0% { transform: scale(0.6); opacity: 0.0; }
  50% { transform: scale(1.1); opacity: 1; }
  100% { transform: scale(1.4); opacity: 0; }
}

/* Rarity intensities */
.card.rarity-rare { box-shadow: 0 0 18px rgba(94, 129, 255, 0.5); }
.card.rarity-epic { box-shadow: 0 0 24px rgba(192, 132, 252, 0.65); position: relative; }
.card.rarity-legendary { box-shadow: 0 0 28px rgba(253, 224, 71, 0.75); position: relative; }
.card.rarity-mythical { box-shadow: 0 0 36px rgba(16, 185, 129, 0.8), 0 0 56px rgba(99, 102, 241, 0.6); position: relative; }

/* Album fixed button */
.album-fab {
  position: fixed;
  right: 20px; bottom: 20px;
  width: 56px; height: 56px; border-radius: 50%;
  border: 1px solid #30363d; background:#0e1116;
  display:flex; align-items:center; justify-content:center;
  box-shadow: 0 4px 16px rgba(0,0,0,0.4);
  text-decoration:none; color:#e6edf3; font-weight:700;
  z-index: 500;
}

/* Home page layout */
.home-wrap { min-height: 100dvh; display:flex; flex-direction:column; }
.home-main { flex:1; display:flex; align-items:center; justify-content:center; }
.booster-center { display:flex; gap:16px; flex-wrap:wrap; justify-content:center; }
.home-bottom { position:fixed; left:0; right:0; bottom:0; padding:12px 16px; display:flex; justify-content:space-between; }
.btn-nav { background:#0e1116; border:1px solid #30363d; border-radius:12px; padding:10px 14px; text-decoration:none; color:#e6edf3; }
.home-inventory {
  position: fixed; top: 20px; right: 20px; min-width: 240px;
  background:#0e1116; border:1px solid #30363d; border-radius: 12px; padding: 10px 12px;
}
.home-inventory .row { display:flex; justify-content:space-between; margin:4px 0; font-size: 14px; }
.home-inventory .stats-btn { margin-top:8px; display:block; }

/* Modal base */
.modal { position:fixed; inset:0; display:flex; align-items:center; justify-content:center; background: rgba(0,0,0,0.6); }
.modal.hidden { display:none; }
.modal .panel { background:#0e1116; border:1px solid #30363d; border-radius: 12px; padding: 16px; min-width: 320px; }

/* Opening sequence */
.booster-stage { display:flex; align-items:center; justify-content:center; min-height: 260px; margin: 12px 0; position:relative; }
.booster-pack {
  width: 220px; height: 300px; background-size:cover; background-position:center;
  border:2px solid #222; border-radius: 12px; box-shadow: 0 6px 18px rgba(0,0,0,0.6);
  transform: translateY(40px) scale(0.9);
  opacity: 0.0;
  animation: boosterEnter 600ms ease-out forwards;
}
@keyframes boosterEnter {
  to { transform: translateY(0) scale(1); opacity: 1; }
}
.booster-tear { position:absolute; top:0; left:50%; transform: translateX(-50%); width: 220px; height: 8px;
  background: linear-gradient(90deg, rgba(255,255,255,0.35), rgba(255,255,255,0.0));
  border-radius: 8px;
  opacity:0;
}
.booster-pack.opened + .booster-tear { opacity:1; animation: tearFlash 450ms ease-out; }
@keyframes tearFlash {
  0% { transform: translateX(-50%) translateY(-10px); opacity:0; }
  40% { transform: translateX(-50%) translateY(-2px); opacity:1; }
  100% { transform: translateX(-50%) translateY(-20px); opacity:0; }
}
.face-down { width: 160px; height: 224px; border-radius:12px; border:2px solid #161b22; background-size:cover; background-position:center; }

/* Flight animation */
.fly-clone {
  position: fixed;
  width: 160px; height: 224px; border-radius: 12px; border: 2px solid #161b22;
  background-size: cover; background-position:center;
  z-index: 1000; pointer-events:none;
  animation: flyArc 900ms ease-in forwards;
}
@keyframes flyArc {
  0% { transform: translate(0,0) rotate(0deg); opacity:1; }
  60% { transform: translate(40px, -120px) rotate(-10deg); }
  100% { transform: translate(var(--dx), var(--dy)) rotate(12deg); opacity: 0.1; }
}

/* Angled shelf */
.shelf-angled {
  display: grid;
  /* Force exactly three boosters per row on the home page.  Each column
     occupies an equal fraction of the available width. */
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  perspective: 900px;
  transform-style: preserve-3d;
}
.pack-diag {
  width: 140px; height: 180px;
  border-radius: 10px;
  border: 2px solid #222;
  background-size: cover; background-position: center;
  box-shadow: 0 8px 18px rgba(0,0,0,0.45);
  transform: rotateX(28deg) rotateZ(-14deg) translateZ(0);
  cursor: pointer;
  transition: transform 180ms ease, box-shadow 180ms ease;
}
.pack-diag:hover {
  transform: rotateX(18deg) rotateZ(-10deg) translateZ(12px) scale(1.04);
  box-shadow: 0 14px 28px rgba(0,0,0,0.6);
}

/* Opening overlay stage overrides */
.open-overlay {
  position: fixed; inset: 0; background: rgba(0,0,0,0.65);
  display:flex; align-items:center; justify-content:center;
  z-index: 600;
}
/* Neon cyberpunk backdrop for booster opening.  Applies a vibrant radial
   gradient and faint diagonal lines to convey a futuristic arcade feel. */
.open-overlay.neon-bg {
  background:
    radial-gradient(circle at 30% 30%, rgba(50, 0, 80, 0.6), rgba(10, 0, 30, 0.9) 60%, rgba(0, 0, 20, 0.95) 100%),
    repeating-linear-gradient(45deg, rgba(130, 0, 255, 0.08) 0 8px, rgba(0,0,0,0) 8px 16px),
    repeating-linear-gradient(-45deg, rgba(0, 200, 255, 0.08) 0 8px, rgba(0,0,0,0) 8px 16px);
}

/* Tooltip style for the information bubble on the home page. */
.info-bubble {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 1000;
  background: rgba(5, 8, 20, 0.97);
  border: 1px solid #335;
  border-radius: 12px;
  padding: 20px 24px;
  width: min(450px, 90vw);
  color: #dfe;
  line-height: 1.4;
  box-shadow: 0 0 30px rgba(0, 255, 255, 0.2);
  backdrop-filter: blur(4px);
}
.info-bubble h2 {
  margin-top: 0;
  font-size: 20px;
  color: #79c0ff;
}
.info-bubble ul {
  padding-left: 20px;
  margin-top: 6px;
}
.info-bubble button {
  margin-top: 12px;
}
.open-panel {
  width: min(900px, 92vw);
  background:#0b0f14; border:1px solid #30363d; border-radius: 14px; padding: 16px;
}
.open-topbar { display:flex; justify-content:space-between; align-items:center; margin-bottom:8px; }

.booster-stand {
  display:flex; align-items:center; justify-content:center;
  min-height: 320px; position: relative;
}
.booster-3d {
  width: 240px; height: 320px;
  background-size: cover; background-position: center;
  border: 2px solid #222; border-radius: 12px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.6);
  transform: rotateX(6deg);
  position: relative;
}
/*
 * The tear handle (drag grip) is kept invisible so that the booster can be
 * dragged open without a visible square interfering with the artwork.  We
 * retain its size and position to preserve the drag hit area but remove
 * any visible styling.  The cursor remains a grab so users know the pack
 * is draggable.
 */
.tear-handle {
  position: absolute;
  top: -6px;
  right: -6px;
  width: 42px;
  height: 42px;
  border-radius: 10px;
  /* Make the handle invisible */
  background: transparent;
  border: none;
  box-shadow: none;
  opacity: 0;
  cursor: grab;
  user-select: none;
}
/* Tear line base: anchored on the right edge and grows to the left as the
   player drags the handle.  A subtle linear gradient gives the illusion of
   paper being peeled away. */
.rip-line {
  position: absolute;
  top: 0;
  /* Anchor the tear line on the left edge so that it grows to the right
     following the user’s drag direction. */
  left: 0;
  height: 8px;
  width: 0px;
  /* Gradient runs from left (transparent) to right (opaque) to simulate
     paper being peeled open. */
  background: linear-gradient(90deg, rgba(255,255,255,0.0), rgba(255,255,255,0.35));
  /* Rounded corner on the right end of the tear line */
  border-bottom-right-radius: 6px;
  pointer-events: none;
}
/* When the booster has been opened, extend the rip line downwards to simulate
   the torn paper flap. */
.booster-3d.opened .rip-line {
  height: 90px;
  transition: height 300ms ease;
}

.pack-mouth {
  position:absolute; top: 88px; left: 50%; transform: translateX(-50%);
  width: 220px; height: 0px; overflow: visible; pointer-events: none;
}
.deck-top {
  position:absolute; top: 0; left: 50%; transform: translate(-50%, -30px);
  width: 160px; height: 224px; border-radius:12px; border:2px solid #161b22;
  background-size:cover; background-position:center;
  box-shadow: 0 8px 18px rgba(0,0,0,0.55);
  pointer-events: auto;
  cursor: pointer;
}

/* Pull animation */
.pull-card {
  position:absolute; left: 50%; transform: translate(-50%, 20px) scale(0.9);
  width: 160px; height: 224px; border-radius: 12px; border:2px solid #161b22;
  background-size: cover; background-position:center;
  opacity: 0;
  animation: pullUp 380ms ease-out forwards;
}
@keyframes pullUp {
  to { transform: translate(-50%, -160px) scale(1); opacity: 1; }
}

/* The tear-handle appearance is defined above.  Remove duplicate
   definitions from legacy code to avoid reintroducing a visible handle. */

/* Circle reveal stage */
.circle-stage {
  position: relative;
  height: 520px;
  display:flex; align-items:center; justify-content:center;
}
.circle-anchor {
  position: absolute; left: 50%; top: 50%;
  width: 0; height: 0;
}
.fd-circle {
  position:absolute; width: 140px; height: 200px;
  border-radius: 12px; border:2px solid #161b22;
  background-size:cover; background-position:center;
  cursor: pointer;
  transform-origin: center center;
  transition: transform 180ms ease;
}
.fd-circle:hover { transform: scale(1.04); }
.fd-circle.revealed { cursor: default; }

.reveal-pop {
  animation: revealPop 260ms ease-out;
}
@keyframes revealPop {
  0% { transform: scale(0.8); opacity: 0; }
  100% { transform: scale(1); opacity: 1; }
}

/* ----- Aligned row layout with 3D perspective ----- */
.row-stage {
  position: relative;
  min-height: 420px;
  display:flex; align-items:center; justify-content:center;
  perspective: 1200px;
}
.fd-row {
  display:flex; gap: 14px; flex-wrap: wrap; justify-content:center;
  transform-style: preserve-3d;
}

/* ----- Flip card base ----- */
.flip-card {
  width: 160px; height: 224px; border-radius: 12px;
  position: relative;
  cursor: pointer;
  perspective: 1000px; /* extra perspective per card -> stronger 3D feel */
}
.flip-inner {
  position:absolute; inset:0;
  transform-style: preserve-3d;
  transition: transform 500ms ease;
  border-radius: 12px;
}
.flip-card.flipped .flip-inner { transform: rotateY(180deg); }

.flip-face {
  position:absolute; inset:0;
  /* Show the entire artwork rather than cropping.  Use contain so the
     complete image is visible regardless of aspect ratio, and set a dark
     background to fill empty space. */
  border-radius: 12px; border:2px solid #161b22;
  background-size: contain; background-position: center;
  background-color: #0a1018;
  backface-visibility: hidden;
  box-shadow: 0 8px 18px rgba(0,0,0,0.45);
}
.flip-front {
  transform: rotateY(180deg); /* so that after rotateY(180) it faces viewer */
}
.flip-back { /* face-down visible initially */ }

/* Slight pop on flip end */
.flip-card.flipped { animation: flipPop 180ms ease-out 420ms 1 both; }
@keyframes flipPop { from { transform: scale(0.98); } to { transform: scale(1); } }

/* ----- Flip row: tilt + stagger ----- */
.flip-card {
  width: 160px; height: 224px; border-radius: 12px; position: relative; cursor: pointer;
  perspective: 1000px;
  opacity: 1;
  transform: perspective(1000px) rotateX(var(--tiltX, 0deg)) rotateY(var(--tiltY, 0deg));
  transition: transform 120ms ease, opacity 240ms ease;
}
.flip-card.pre {
  opacity: 0;
  transform: perspective(1000px) translateY(16px) scale(0.96);
}
.flip-inner {
  position:absolute; inset:0; transform-style: preserve-3d; transition: transform 500ms ease; border-radius: 12px;
}
.flip-card.flipped .flip-inner { transform: rotateY(180deg); }

/* Paper shake (GSAP-like timeline end step) */
@keyframes paperShakeX {
  /* Further reduce shaking amplitude and rotation for a gentler effect */
  0% { transform: translateX(0) rotate(0deg); }
  20% { transform: translateX(-0.5px) rotate(-0.1deg); }
  40% { transform: translateX(0.5px) rotate(0.1deg); }
  60% { transform: translateX(-0.3px) rotate(-0.07deg); }
  80% { transform: translateX(0.3px) rotate(0.07deg); }
  100% { transform: translateX(0) rotate(0deg); }
}
.booster-shake { animation: paperShakeX 380ms ease-out both; }

/* Tweak topbar (no white button) */
.open-topbar { justify-content:center; }

/* =========================================================================
   Neon line background
   The home page optionally includes a cyberpunk backdrop of vertical neon
   rays drifting downwards.  These elements live in a container with the
   class `.neon-lines` that is inserted via JavaScript.  Each `.ray`
   element animates downward indefinitely to give the impression of
   streaming lines.  The z-index is negative so that the effect sits
   behind all interactive content.  pointer-events are disabled so it
   doesn’t intercept clicks.  Adjust the gradient colours and speeds to
   taste.
   ======================================================================== */
.neon-lines {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  z-index: -1;
  pointer-events: none;
}
.neon-lines .ray {
  position: absolute;
  top: -200vh;
  width: 2px;
  height: 200vh;
  background: linear-gradient(to bottom,
    rgba(96,0,160,0),
    rgba(160,0,220,0.6) 50%,
    rgba(96,0,160,0));
  border-radius: 1px;
  animation: rayMove 14s linear infinite;
}
@keyframes rayMove {
  from { transform: translateY(0); }
  to { transform: translateY(200vh); }
}

