/* ==========================================================================
   OEAC Digital Library — advanced interaction layer
   Loaded AFTER assets/css/app.css. This file only adds motion and appearance;
   it changes no layout of the existing components.

   Every colour is taken from the design-system tokens declared in app.css, so
   both themes ([data-theme="light"]) keep working without extra rules.
   ========================================================================== */

/* --------------------------------------------------------------------------
   COUNT-UP state — carried while a number is animating (JS adds/removes it)
   -------------------------------------------------------------------------- */
.count-up {
  color: var(--orange);
  text-shadow: 0 0 20px var(--orange-glow);
}

/* --------------------------------------------------------------------------
   SKELETON shimmer — placeholder while content is still loading
   -------------------------------------------------------------------------- */
.skeleton {
  position: relative;
  overflow: hidden;
  background: var(--surface-2);
  border-radius: 10px;
  color: transparent;
}
.skeleton::after {
  content: '';
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, var(--gray-line), transparent);
  animation: oeacShimmer 1.4s ease-in-out infinite;
}
@keyframes oeacShimmer { to { transform: translateX(100%); } }

/* --------------------------------------------------------------------------
   BLUR-UP images — JS swaps .img-loading -> .img-loaded once decoded
   -------------------------------------------------------------------------- */
.img-loading {
  opacity: 0;
  filter: blur(14px);
  transform: scale(1.05);
}
.img-loaded {
  opacity: 1;
  filter: blur(0);
  transform: scale(1);
  transition: opacity .6s ease, filter .6s ease, transform .6s ease;
}

/* --------------------------------------------------------------------------
   SCROLL PROGRESS bar — thin line pinned to the very top of the viewport
   -------------------------------------------------------------------------- */
.oeac-scrollbar-top {
  position: fixed;
  top: 0;
  left: 0;
  height: 3px;
  width: 0;
  z-index: 1200;
  pointer-events: none;
  background: linear-gradient(90deg, var(--orange), var(--orange-bright));
  box-shadow: 0 0 12px var(--orange-glow);
  transition: width .08s linear;
}
/* The reader page owns the whole viewport — no page progress bar there. */
body.reader-body .oeac-scrollbar-top { display: none; }

/* --------------------------------------------------------------------------
   3D TILT helper — JS adds .tilt-wrap to .book-card / .showcase-card
   -------------------------------------------------------------------------- */
.tilt-wrap {
  perspective: 1000px;
  transform-style: preserve-3d;
  will-change: transform;
}

/* --------------------------------------------------------------------------
   MASKED LINE REVEAL — clip-path wipe used by [data-reveal-mask]
   -------------------------------------------------------------------------- */
.reveal-mask {
  clip-path: inset(0 100% 0 0);
  opacity: 0;
  transition: clip-path .9s cubic-bezier(.2, .9, .3, 1), opacity .5s ease;
}
body[dir="rtl"] .reveal-mask { clip-path: inset(0 0 0 100%); }
.reveal-mask.in { clip-path: inset(0 0 0 0); opacity: 1; }

/* --------------------------------------------------------------------------
   RIPPLE — click feedback injected by JS into buttons/links
   -------------------------------------------------------------------------- */
.has-ripple { position: relative; overflow: hidden; }
.ripple {
  position: absolute;
  border-radius: 50%;
  pointer-events: none;
  opacity: .8;
  transform: scale(0);
  background: radial-gradient(circle, var(--orange-glow) 0%, transparent 70%);
  animation: oeacRipple .6s ease-out forwards;
}
@keyframes oeacRipple { to { transform: scale(2.6); opacity: 0; } }

/* --------------------------------------------------------------------------
   BACK-TO-TOP — floating button, shown by JS past 600px of scroll
   -------------------------------------------------------------------------- */
.back-to-top {
  position: fixed;
  right: 1.4rem;
  bottom: 1.4rem;
  width: 46px;
  height: 46px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  border: 1px solid var(--orange);
  background: var(--surface);
  color: var(--orange);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
  z-index: 1400;
  opacity: 0;
  visibility: hidden;
  transform: translateY(14px);
  backdrop-filter: blur(10px);
  transition: opacity .3s ease, transform .3s ease, visibility .3s ease,
              background .3s ease, box-shadow .3s ease;
}
.back-to-top.show { opacity: 1; visibility: visible; transform: translateY(0); }
.back-to-top:hover {
  background: var(--orange-glow);
  box-shadow: 0 12px 30px -10px var(--orange-glow);
}
@media (max-width: 640px) {
  .back-to-top { right: 1rem; bottom: 1rem; width: 40px; height: 40px; }
}

/* --------------------------------------------------------------------------
   CONFETTI — full-screen, click-through canvas overlay (created on demand)
   -------------------------------------------------------------------------- */
.confetti-canvas {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 4000;
}

/* --------------------------------------------------------------------------
   RECENTLY VIEWED rail — small horizontal cards rendered by OEACUX.recent
   -------------------------------------------------------------------------- */
.oeac-recent { margin: 0 0 1.4rem; }
.oeac-recent-rail {
  display: flex;
  gap: .8rem;
  overflow-x: auto;
  padding: .3rem .1rem .9rem;
  scroll-snap-type: x proximity;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.oeac-recent-rail::-webkit-scrollbar { display: none; }
.oeac-recent-item {
  flex: 0 0 118px;
  display: flex;
  flex-direction: column;
  gap: .45rem;
  padding: .55rem;
  border-radius: 12px;
  border: 1px solid var(--gray-line);
  background: var(--surface-2);
  color: var(--txt-dim);
  text-decoration: none;
  scroll-snap-align: start;
  transition: transform .3s ease, border-color .3s ease, color .3s ease;
}
.oeac-recent-item:hover {
  transform: translateY(-4px);
  border-color: var(--orange);
  color: var(--txt);
}
.oeac-recent-thumb {
  width: 100%;
  aspect-ratio: 3 / 4;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  border-radius: 8px;
  background: var(--black-card);
}
.oeac-recent-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.oeac-recent-thumb .ph { font-size: 1.7rem; color: var(--txt-dimmer); }
.oeac-recent-t {
  font-size: .74rem;
  font-weight: 600;
  line-height: 1.25;
  color: var(--txt);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.oeac-recent-a {
  font-size: .63rem;
  color: var(--txt-dimmer);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* --------------------------------------------------------------------------
   KEYBOARD HINT overlay — toggled with "?"
   -------------------------------------------------------------------------- */
.kbd-hint {
  position: fixed;
  inset: 0;
  z-index: 2600;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 2rem;
  background: var(--surface);
  backdrop-filter: blur(8px);
}
.kbd-hint.open { display: flex; animation: oeacHintFade .25s ease; }
@keyframes oeacHintFade { from { opacity: 0; } to { opacity: 1; } }
.kbd-hint-card {
  width: 100%;
  max-width: 430px;
  padding: 1.4rem 1.5rem;
  border-radius: 18px;
  border: 1px solid var(--orange);
  background: var(--black-card);
  color: var(--txt);
  box-shadow: var(--shadow-card);
}
.kbd-hint-card h4 {
  font-size: 1rem;
  font-weight: 800;
  letter-spacing: -.3px;
  margin-bottom: .9rem;
}
.kbd-hint-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: .42rem 0;
  font-size: .84rem;
  color: var(--txt-dim);
  border-bottom: 1px solid var(--gray-line);
}
.kbd-hint-row:last-of-type { border-bottom: none; }
.kbd-hint-row kbd {
  display: inline-block;
  min-width: 1.5rem;
  text-align: center;
  margin-inline-start: .2rem;
  padding: .1rem .4rem;
  border-radius: 5px;
  border: 1px solid var(--gray-line);
  background: var(--surface-2);
  color: var(--txt);
  font-size: .7rem;
  font-family: inherit;
}
.kbd-hint-close {
  margin-top: 1rem;
  width: 100%;
  padding: .6rem 1rem;
  border-radius: 60px;
  border: 1px solid var(--orange);
  background: transparent;
  color: var(--orange);
  font-family: inherit;
  font-size: .82rem;
  font-weight: 700;
  cursor: pointer;
  transition: background .3s ease, color .3s ease;
}
.kbd-hint-close:hover { background: var(--orange-glow); }

/* --------------------------------------------------------------------------
   REDUCED MOTION — nothing moves; effects snap straight to their end state.
   (app.css already neutralises animations globally; this guarantees the
   states this layer relies on, e.g. the mask, resolve to visible.)
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .reveal-mask,
  .reveal-mask.in { clip-path: inset(0 0 0 0); opacity: 1; transition: none; }
  .img-loading,
  .img-loaded { opacity: 1; filter: none; transform: none; transition: none; }
  .skeleton::after { display: none; }
  .ripple { display: none; }
  .back-to-top { transition: none; }
  .oeac-scrollbar-top { transition: none; }
  .oeac-recent-item:hover { transform: none; }
}
