/* ==========================================================================
   答案之书 · 动画层
   anim.css —— 翻页、墨迹浮现、界面微动效
   ========================================================================== */

/* --------------------------------------------------------------------------
   翻页
   0 → -180deg 绕中缝旋转，末尾 14% 做一次 -181.5deg 的微回弹，
   模拟纸张落到对面时的惯性。
   duration 由 JS 通过 --dur 注入（快速连翻时极短，落页时较长）。
   -------------------------------------------------------------------------- */

@keyframes leafFlip {
  0%   { transform: rotateY(0deg); }
  86%  { transform: rotateY(-181.5deg); }
  100% { transform: rotateY(-180deg); }
}

.leaf.is-flipping {
  animation-name: leafFlip;
  animation-duration: var(--dur, 420ms);
  animation-timing-function: cubic-bezier(.42, 0, .25, 1);
  animation-fill-mode: forwards;
}

/* 翻页时纸面受光的细微明暗变化 */
@keyframes faceShade {
  0%   { opacity: 0; }
  46%  { opacity: .16; }
  100% { opacity: 0; }
}

.leaf.is-flipping .leaf-face::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 3;
  background: #1a1408;
  pointer-events: none;
  animation: faceShade var(--dur, 420ms) ease-in-out both;
}

/* --------------------------------------------------------------------------
   答案墨迹浮现
   从墨雾中显形：模糊消散 + 轻微上浮。

   ⚠️ 这里只允许动画 opacity / filter / transform 这三个「不参与布局」的属性。
   曾经用过 letter-spacing 做「字距聚拢」的效果，但那会让文字宽度在动画期间
   变化（.3em → .04em，收缩约 26%）。当某条答案的宽度刚好贴近容器宽度时，
   动画途中会跨过换行阈值，行数在 1↔2 之间反复翻转；
   再叠加 .page-face 的 flex 垂直居中，视觉上就是文字上下抖动。
   抖动区间随视口宽度漂移，实测长度 6–8 字与 19–24 字都会命中。
   改任何属性前先问一句：它会不会改变文字宽度？
   -------------------------------------------------------------------------- */

@keyframes inkReveal {
  0% {
    opacity: 0;
    filter: blur(7px);
    transform: translateY(8px);
  }
  55% {
    opacity: 1;
  }
  100% {
    opacity: 1;
    filter: blur(0);
    transform: translateY(0);
  }
}

.answer-text.is-revealing {
  animation: inkReveal 820ms cubic-bezier(.2, .8, .3, 1) both;
}

/* 墨圈扩散 */
@keyframes inkBloom {
  0%   { opacity: .62; transform: translate(-50%, -50%) scale(.22); }
  100% { opacity: 0;   transform: translate(-50%, -50%) scale(1.45); }
}

.ink-bloom {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 66%;
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  background: radial-gradient(circle,
    rgba(88, 70, 44, .17), rgba(88, 70, 44, .06) 46%, transparent 70%);
  pointer-events: none;
  z-index: 1;
  opacity: 0;
}
.ink-bloom.is-on {
  animation: inkBloom 900ms ease-out both;
}

/* --------------------------------------------------------------------------
   界面微动效
   -------------------------------------------------------------------------- */

@keyframes hintPulse {
  0%, 100% { opacity: .4; }
  50%      { opacity: .95; }
}

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

.btn.is-entering {
  animation: btnIn 340ms cubic-bezier(.2, .8, .3, 1) both;
}

/* 抽取中：主按钮做一次极轻的呼吸，暗示"正在翻" */
@keyframes btnBusy {
  0%, 100% { opacity: .55; }
  50%      { opacity: .82; }
}
.btn.is-busy {
  animation: btnBusy 1.1s ease-in-out infinite;
}

/* --------------------------------------------------------------------------
   工具类
   -------------------------------------------------------------------------- */

.is-hidden {
  display: none !important;
}

/* --------------------------------------------------------------------------
   尊重系统的"减少动态效果"设置
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .leaf.is-flipping {
    animation-duration: 160ms !important;
  }
  .answer-text.is-revealing {
    animation-duration: 220ms !important;
    animation-name: inkRevealSimple;
  }
  .cover-hint {
    animation: none;
    opacity: .72;
  }
  .ink-bloom.is-on {
    animation: none;
  }

  /*
   * 缩短开合时长时，必须改 --dur-book 这个变量本身，
   * 不能只写 .cover { transition-duration } —— 那会让封面变快、而左半页的
   * leftPageIn/leftPageOut 关键帧仍按 1100ms 播放，两者错位、幽灵页回归。
   */
  :root {
    --dur-book: 260ms;
  }
}

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