html {
  scroll-behavior: smooth;
}

/* Dark-theme scrollbars instead of default OS chrome */
* {
  scrollbar-width: auto;
  scrollbar-color: #27272a transparent;
}
*::-webkit-scrollbar {
  width: 14px;
  height: 14px;
}
*::-webkit-scrollbar-track {
  background: transparent;
}
*::-webkit-scrollbar-thumb {
  background-color: #27272a;
  border-radius: 9999px;
  border: 3px solid transparent;
  background-clip: padding-box;
}
*::-webkit-scrollbar-thumb:hover {
  background-color: #10b981;
}

/* Animated grid background pan (replaces the Framer Motion backgroundPosition
   loop on the original <GridBackground>). */
@keyframes gridPan {
  from {
    background-position: 0 0;
  }
  to {
    background-position: 56px 56px;
  }
}
.animate-grid-pan {
  animation: gridPan 10s linear infinite;
}

/* Ambient rising pixels (replaces the per-pixel Framer Motion top animation).
   Each pixel sets its own --dur / --delay inline. */
@keyframes pixelRise {
  from {
    top: 105%;
  }
  to {
    top: -5%;
  }
}
.pixel {
  animation-name: pixelRise;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
  animation-duration: var(--dur, 18s);
  animation-delay: var(--delay, 0s);
}

/* Blinking terminal cursor on the retro card stack. */
@keyframes cursorBlink {
  0%,
  49% {
    opacity: 1;
  }
  50%,
  100% {
    opacity: 0;
  }
}
.animate-cursor-blink {
  animation: cursorBlink 1s step-end infinite;
}

/* Gentle whole-page fade-in on load, so arriving/returning to the site (a
   full navigation, e.g. the player's Back link) eases in instead of snapping.
   (`.reveal` is now a no-op class left in the markup; scroll-triggered
   reveals were removed as unnecessary.) */
@keyframes pageFadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
#app {
  animation: pageFadeIn 0.35s ease both;
}

/* Above-the-fold entrance (replaces Framer Motion initial/animate on the
   nav and hero). */
@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
.fade-in-up {
  opacity: 0;
  animation: fadeInUp 0.5s ease forwards;
}

/* View swap (Home <-> Library) entrance, replacing AnimatePresence. */
@keyframes viewEnter {
  from {
    opacity: 0;
    transform: translateY(12px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
.view-enter {
  animation: viewEnter 0.3s ease forwards;
}

/* Retro card stack: two stacked cards, JS toggles [data-top] to swap which
   sits on top. Transitions handle the spring-ish motion Framer used. */
.if-cardstack {
  position: relative;
  width: 100%;
  max-width: 410px;
  height: 512px;
  margin: 0 auto;
}
/* Three-card deck. A card with no data-pos sits at the back position but
   fully transparent, so cards fade in/out in place as the deck rotates
   rather than flying across. Only the front card (pos 0) is interactive. */
.if-card {
  position: absolute;
  inset: 0;
  transition:
    transform 0.6s cubic-bezier(0.22, 1, 0.36, 1),
    opacity 0.6s ease;
  transform: translate(30px, -22px) scale(0.88) rotate(4.5deg);
  opacity: 0;
  z-index: 0;
  pointer-events: none;
}
.if-card[data-pos='2'] {
  transform: translate(30px, -22px) scale(0.88) rotate(4.5deg);
  opacity: 0.3;
  z-index: 10;
}
.if-card[data-pos='1'] {
  transform: translate(16px, -12px) scale(0.94) rotate(2.5deg);
  opacity: 0.6;
  z-index: 20;
}
.if-card[data-pos='0'] {
  transform: translate(0, 0) scale(1) rotate(-2deg);
  opacity: 1;
  z-index: 30;
  pointer-events: auto;
}
