/* === Animations & Transitions for 书游小筑 === */

/* ---- Keyframes ---- */

@keyframes pageIn {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes pageOut {
  from { opacity: 1; transform: translateY(0); }
  to   { opacity: 0; transform: translateY(-10px); }
}

@keyframes contentIn {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes cardIn {
  from { opacity: 0; transform: translateY(24px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes fadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes fadeOut {
  from { opacity: 1; }
  to   { opacity: 0; }
}

@keyframes modalIn {
  from { opacity: 0; transform: scale(0.92) translateY(12px); }
  to   { opacity: 1; transform: scale(1) translateY(0); }
}

@keyframes slideUp {
  from { transform: translateY(100%); }
  to   { transform: translateY(0); }
}

/* ---- Page Transitions ---- */

.page.animate-in {
  animation: pageIn 0.3s cubic-bezier(0.16, 1, 0.3, 1) both;
}

.page.animate-out {
  animation: pageOut 0.2s cubic-bezier(0.4, 0, 0.6, 1) both;
}

/* ---- Content Entrance ---- */

.content-enter {
  animation: contentIn 0.35s cubic-bezier(0.16, 1, 0.3, 1) both;
}

/* Fade-only entrance: safe for scroll containers and sticky parents.
   Using transform on a scroll container (overflow:auto/scroll) creates
   a new containing block that breaks sticky positioning and can interfere
   with scroll-to-top behavior. */
.fade-enter {
  animation: fadeIn 0.3s ease both;
}

/* Fade exit for chapter/page transitions — paired with .fade-enter */
.fade-exit {
  animation: fadeOut 0.2s ease both;
}

/* Initial hidden state before fade-enter animation — prevents flash of visible content */
.fade-enter-ready {
  opacity: 0;
}

/* Cross-fade transition stack: overlays old and new content via CSS Grid so they
   cross-fade simultaneously instead of sequentially. */
.reader-transition-stack {
  display: grid;
  max-width: var(--reader-max-w);
  margin: 0 auto;
}

.reader-transition-stack > * {
  grid-area: 1 / 1;
  /* keep vertical padding on the stack items so the stack height matches content */
  padding: var(--space-xl) 0;
}

/* ---- Card Staggered Entrance ---- */

.card-stagger {
  opacity: 0;
  animation: cardIn 0.45s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}

/* ---- Modal Animations ---- */

.modal-overlay {
  animation: fadeIn 0.2s ease both;
}

.modal {
  animation: modalIn 0.28s cubic-bezier(0.16, 1, 0.3, 1) both;
}

/* ---- Bottom Sheet ---- */

.bottom-sheet-overlay {
  animation: fadeIn 0.25s ease both;
}

.bottom-sheet {
  animation: slideUp 0.35s cubic-bezier(0.16, 1, 0.3, 1) both;
}

/* ---- Nav Sliding Indicator ---- */

.nav-links {
  position: relative;
}

.nav-indicator {
  position: absolute;
  bottom: -1px;
  left: 0;
  height: 3px;
  background: var(--accent);
  border-radius: 3px 3px 0 0;
  transition: left 0.35s cubic-bezier(0.16, 1, 0.3, 1),
              width 0.35s cubic-bezier(0.16, 1, 0.3, 1);
}

/* ---- Button Press Feedback ---- */

.btn,
.btn-icon,
.nav-link {
  transition: transform 0.12s ease,
              background-color var(--transition-hover),
              color var(--transition-hover);
}

.btn:active,
.btn-icon:active {
  transform: scale(0.94);
}

.nav-link:active {
  transform: scale(0.96);
}

/* ---- Game Back Bar & Area ---- */

.game-back-bar,
.game-area {
  animation: contentIn 0.3s cubic-bezier(0.16, 1, 0.3, 1) both;
}

/* ---- Theme Transition Enhancement ---- */

html {
  transition: background-color 0.35s ease;
}

body {
  transition: background-color 0.35s ease, color 0.35s ease;
}

/* ---- Reduce Motion ---- */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
