/* ==========================================================================
   uiverse.css — 基于 uiverse.io 开源组件（MIT License）适配的 UI 增强层
   --------------------------------------------------------------------------
   组件来源（MIT，版权与许可声明随注释保留）：
   1. 打字机加载动画   uiverse.io/Nawsome/kind-mole-87      Copyright (c) Nawsome
   2. 心形点赞庆祝动画  uiverse.io/catraco/plastic-moth-91   Copyright (c) catraco
   3. 书签涟漪收藏动画  uiverse.io/Galahhad/mighty-warthog-42 Copyright (c) Galahhad
   4. 按钮按压反馈      uiverse.io/vinodjangid07/heavy-badger-29 Copyright (c) Vinod Jangid
   5. 输入框平滑过渡    uiverse.io/alexruix/jolly-emu-80    Copyright (c) alexruix
   --------------------------------------------------------------------------
   适配原则（对齐 DESIGN.md）：
   - 所有颜色走 styles.css 的语义变量（--primary / --primary-soft / --line …），
     自动跟随紫荆 / 绯红 / 蔚蓝三主题切换；
   - 平面优先：动画只做状态反馈，不新增大面积阴影；
   - 全部动画尊重 prefers-reduced-motion，减少动态偏好时立即停用；
   - 语义色（点赞 rose / 收藏 gold）跨主题保持不变，与现有 .sq-like / .sq-fav 一致。
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. 打字机加载动画（AI 解答 / 生成等待态）
      源组件：uiverse.io/Nawsome/kind-mole-87 · MIT
      用法：<div class="uv-typewriter" aria-hidden="true">
              <div class="slide"><i></i></div>
              <div class="paper"></div>
              <div class="keyboard"></div>
            </div>
   -------------------------------------------------------------------------- */
.uv-typewriter {
  --uvt-blue: var(--primary);
  --uvt-blue-dark: var(--primary-dark);
  --uvt-key: #fff;
  --uvt-paper: var(--primary-soft);
  --uvt-text: var(--line);
  --uvt-tool: var(--primary-dark);
  --uvt-duration: 3s;
  position: relative;
  width: 120px;
  height: 78px;
  flex: none;
  animation: uv-bounce var(--uvt-duration) linear infinite;
}

.uv-typewriter .slide {
  width: 92px;
  height: 20px;
  border-radius: 3px;
  margin-left: 14px;
  transform: translateX(14px);
  background: linear-gradient(var(--uvt-blue), var(--uvt-blue-dark));
  animation: uv-slide var(--uvt-duration) ease infinite;
}

.uv-typewriter .slide:before,
.uv-typewriter .slide:after,
.uv-typewriter .slide i:before {
  content: "";
  position: absolute;
  background: var(--uvt-tool);
}

.uv-typewriter .slide:before {
  width: 2px;
  height: 8px;
  top: 6px;
  left: 100%;
}

.uv-typewriter .slide:after {
  left: 94px;
  top: 3px;
  height: 14px;
  width: 6px;
  border-radius: 3px;
}

.uv-typewriter .slide i {
  display: block;
  position: absolute;
  right: 100%;
  width: 6px;
  height: 4px;
  top: 4px;
  background: var(--uvt-tool);
}

.uv-typewriter .slide i:before {
  right: 100%;
  top: -2px;
  width: 4px;
  border-radius: 2px;
  height: 14px;
}

.uv-typewriter .paper {
  position: absolute;
  left: 24px;
  top: -26px;
  width: 40px;
  height: 46px;
  border-radius: 5px;
  background: var(--uvt-paper);
  transform: translateY(46px);
  animation: uv-paper var(--uvt-duration) linear infinite;
}

.uv-typewriter .paper:before {
  content: "";
  position: absolute;
  left: 6px;
  right: 6px;
  top: 7px;
  border-radius: 2px;
  height: 4px;
  transform: scaleY(0.8);
  background: var(--uvt-text);
  box-shadow: 0 12px 0 var(--uvt-text), 0 24px 0 var(--uvt-text), 0 36px 0 var(--uvt-text);
}

.uv-typewriter .keyboard {
  width: 120px;
  height: 56px;
  margin-top: -10px;
  z-index: 1;
  position: relative;
}

.uv-typewriter .keyboard:before,
.uv-typewriter .keyboard:after {
  content: "";
  position: absolute;
}

.uv-typewriter .keyboard:before {
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  border-radius: 7px;
  background: linear-gradient(135deg, var(--uvt-blue), var(--uvt-blue-dark));
  transform: perspective(10px) rotateX(2deg);
  transform-origin: 50% 100%;
}

.uv-typewriter .keyboard:after {
  left: 2px;
  top: 25px;
  width: 11px;
  height: 4px;
  border-radius: 2px;
  background: var(--uvt-key);
  box-shadow:
    15px 0 0 var(--uvt-key), 30px 0 0 var(--uvt-key), 45px 0 0 var(--uvt-key),
    60px 0 0 var(--uvt-key), 75px 0 0 var(--uvt-key), 90px 0 0 var(--uvt-key),
    22px 10px 0 var(--uvt-key), 37px 10px 0 var(--uvt-key), 52px 10px 0 var(--uvt-key),
    60px 10px 0 var(--uvt-key), 68px 10px 0 var(--uvt-key), 83px 10px 0 var(--uvt-key);
  animation: uv-keyboard var(--uvt-duration) linear infinite;
}

@keyframes uv-bounce {
  85%, 92%, 100% { transform: translateY(0); }
  89% { transform: translateY(-4px); }
  95% { transform: translateY(2px); }
}

@keyframes uv-slide {
  5% { transform: translateX(14px); }
  15%, 30% { transform: translateX(6px); }
  40%, 55% { transform: translateX(0); }
  65%, 70% { transform: translateX(-4px); }
  80%, 89% { transform: translateX(-12px); }
  100% { transform: translateX(14px); }
}

@keyframes uv-paper {
  5% { transform: translateY(46px); }
  20%, 30% { transform: translateY(34px); }
  40%, 55% { transform: translateY(22px); }
  65%, 70% { transform: translateY(10px); }
  80%, 85% { transform: translateY(0); }
  92%, 100% { transform: translateY(46px); }
}

@keyframes uv-keyboard {
  5%, 12%, 21%, 30%, 39%, 48%, 57%, 66%, 75%, 84% {
    box-shadow:
      15px 0 0 var(--uvt-key), 30px 0 0 var(--uvt-key), 45px 0 0 var(--uvt-key),
      60px 0 0 var(--uvt-key), 75px 0 0 var(--uvt-key), 90px 0 0 var(--uvt-key),
      22px 10px 0 var(--uvt-key), 37px 10px 0 var(--uvt-key), 52px 10px 0 var(--uvt-key),
      60px 10px 0 var(--uvt-key), 68px 10px 0 var(--uvt-key), 83px 10px 0 var(--uvt-key);
  }
  9% {
    box-shadow:
      15px 2px 0 var(--uvt-key), 30px 0 0 var(--uvt-key), 45px 0 0 var(--uvt-key),
      60px 0 0 var(--uvt-key), 75px 0 0 var(--uvt-key), 90px 0 0 var(--uvt-key),
      22px 10px 0 var(--uvt-key), 37px 10px 0 var(--uvt-key), 52px 10px 0 var(--uvt-key),
      60px 10px 0 var(--uvt-key), 68px 10px 0 var(--uvt-key), 83px 10px 0 var(--uvt-key);
  }
  18% {
    box-shadow:
      15px 0 0 var(--uvt-key), 30px 0 0 var(--uvt-key), 45px 0 0 var(--uvt-key),
      60px 2px 0 var(--uvt-key), 75px 0 0 var(--uvt-key), 90px 0 0 var(--uvt-key),
      22px 10px 0 var(--uvt-key), 37px 10px 0 var(--uvt-key), 52px 10px 0 var(--uvt-key),
      60px 10px 0 var(--uvt-key), 68px 10px 0 var(--uvt-key), 83px 10px 0 var(--uvt-key);
  }
  27% {
    box-shadow:
      15px 0 0 var(--uvt-key), 30px 0 0 var(--uvt-key), 45px 0 0 var(--uvt-key),
      60px 0 0 var(--uvt-key), 75px 0 0 var(--uvt-key), 90px 0 0 var(--uvt-key),
      22px 12px 0 var(--uvt-key), 37px 10px 0 var(--uvt-key), 52px 10px 0 var(--uvt-key),
      60px 10px 0 var(--uvt-key), 68px 10px 0 var(--uvt-key), 83px 10px 0 var(--uvt-key);
  }
  36% {
    box-shadow:
      15px 0 0 var(--uvt-key), 30px 0 0 var(--uvt-key), 45px 0 0 var(--uvt-key),
      60px 0 0 var(--uvt-key), 75px 0 0 var(--uvt-key), 90px 0 0 var(--uvt-key),
      22px 10px 0 var(--uvt-key), 37px 10px 0 var(--uvt-key), 52px 12px 0 var(--uvt-key),
      60px 12px 0 var(--uvt-key), 68px 12px 0 var(--uvt-key), 83px 10px 0 var(--uvt-key);
  }
  45% {
    box-shadow:
      15px 0 0 var(--uvt-key), 30px 0 0 var(--uvt-key), 45px 0 0 var(--uvt-key),
      60px 0 0 var(--uvt-key), 75px 0 0 var(--uvt-key), 90px 2px 0 var(--uvt-key),
      22px 10px 0 var(--uvt-key), 37px 10px 0 var(--uvt-key), 52px 10px 0 var(--uvt-key),
      60px 10px 0 var(--uvt-key), 68px 10px 0 var(--uvt-key), 83px 10px 0 var(--uvt-key);
  }
  54% {
    box-shadow:
      15px 0 0 var(--uvt-key), 30px 2px 0 var(--uvt-key), 45px 0 0 var(--uvt-key),
      60px 0 0 var(--uvt-key), 75px 0 0 var(--uvt-key), 90px 0 0 var(--uvt-key),
      22px 10px 0 var(--uvt-key), 37px 10px 0 var(--uvt-key), 52px 10px 0 var(--uvt-key),
      60px 10px 0 var(--uvt-key), 68px 10px 0 var(--uvt-key), 83px 10px 0 var(--uvt-key);
  }
  63% {
    box-shadow:
      15px 0 0 var(--uvt-key), 30px 0 0 var(--uvt-key), 45px 0 0 var(--uvt-key),
      60px 0 0 var(--uvt-key), 75px 0 0 var(--uvt-key), 90px 0 0 var(--uvt-key),
      22px 10px 0 var(--uvt-key), 37px 10px 0 var(--uvt-key), 52px 10px 0 var(--uvt-key),
      60px 10px 0 var(--uvt-key), 68px 10px 0 var(--uvt-key), 83px 12px 0 var(--uvt-key);
  }
  72% {
    box-shadow:
      15px 0 0 var(--uvt-key), 30px 0 0 var(--uvt-key), 45px 2px 0 var(--uvt-key),
      60px 0 0 var(--uvt-key), 75px 0 0 var(--uvt-key), 90px 0 0 var(--uvt-key),
      22px 10px 0 var(--uvt-key), 37px 10px 0 var(--uvt-key), 52px 10px 0 var(--uvt-key),
      60px 10px 0 var(--uvt-key), 68px 10px 0 var(--uvt-key), 83px 10px 0 var(--uvt-key);
  }
  81% {
    box-shadow:
      15px 0 0 var(--uvt-key), 30px 0 0 var(--uvt-key), 45px 0 0 var(--uvt-key),
      60px 0 0 var(--uvt-key), 75px 0 0 var(--uvt-key), 90px 0 0 var(--uvt-key),
      22px 10px 0 var(--uvt-key), 37px 12px 0 var(--uvt-key), 52px 10px 0 var(--uvt-key),
      60px 10px 0 var(--uvt-key), 68px 10px 0 var(--uvt-key), 83px 10px 0 var(--uvt-key);
  }
}

/* 打字机等待态容器：loader + 说明文字横排，用于 .doc-search-answer 内 */
.uv-ai-waiting {
  display: flex;
  align-items: center;
  gap: 22px;
  margin-top: 14px;
  padding: 6px 2px 2px;
}
.uv-ai-waiting .uv-typewriter { transform: scale(.88); transform-origin: left center; }
.uv-ai-waiting .uv-ai-waiting-text {
  margin: 0;
  color: var(--muted-2);
  font-size: 13px;
  line-height: 1.7;
}
.uv-ai-waiting[hidden] { display: none; }

/* --------------------------------------------------------------------------
   2. 心形点赞庆祝动画（广场 .sq-like 增强）
      源组件：uiverse.io/catraco/plastic-moth-91 · MIT
      触发方式：JS 在点赞瞬间给按钮加 .uv-just-liked 类（约 650ms 后移除），
      初始渲染不播放，避免整页已赞内容集体跳动。
   -------------------------------------------------------------------------- */
.sq-like { position: relative; }
.sq-like .uv-burst {
  position: absolute;
  left: 20px; top: 50%;
  width: 4px; height: 4px;
  margin: -2px 0 0 -2px;
  border-radius: 50%;
  opacity: 0;
  pointer-events: none;
}
.sq-reply .sq-like .uv-burst { left: 16px; }

.sq-like.uv-just-liked svg { animation: uv-heart-pop .5s cubic-bezier(.25,.01,.25,1); }
.sq-like.uv-just-liked .sq-like-num { animation: uv-num-bump .4s ease-out; }
.sq-like.uv-just-liked .uv-burst { animation: uv-burst .6s ease-out; }

@keyframes uv-heart-pop {
  0% { transform: scale(.3); }
  45% { transform: scale(1.38); }
  70% { transform: scale(.92); }
  100% { transform: scale(1); }
}

@keyframes uv-num-bump {
  0% { transform: none; }
  40% { transform: translateY(-3px) scale(1.16); }
  100% { transform: none; }
}

@keyframes uv-burst {
  0% {
    opacity: 1;
    box-shadow:
      0 -7px 0 -1px #e11d48, 5px -5px 0 -1px #f43f5e, 7px 0 0 -1px #e11d48,
      5px 5px 0 -1px #f43f5e, 0 7px 0 -1px #e11d48, -5px 5px 0 -1px #f43f5e,
      -7px 0 0 -1px #e11d48, -5px -5px 0 -1px #f43f5e;
  }
  100% {
    opacity: 0;
    box-shadow:
      0 -17px 0 -1px #e11d48, 12px -12px 0 -1px #f43f5e, 17px 0 0 -1px #e11d48,
      12px 12px 0 -1px #f43f5e, 0 17px 0 -1px #e11d48, -12px 12px 0 -1px #f43f5e,
      -17px 0 0 -1px #e11d48, -12px -12px 0 -1px #f43f5e;
  }
}

/* --------------------------------------------------------------------------
   3. 书签收藏涟漪动画（广场 .sq-fav 增强）
      源组件：uiverse.io/Galahhad/mighty-warthog-42 · MIT
   -------------------------------------------------------------------------- */
.sq-fav { position: relative; }

.sq-fav.uv-just-saved svg { animation: uv-book-pop .5s cubic-bezier(.25,.01,.25,1); }
.sq-fav.uv-just-saved .sq-like-num { animation: uv-num-bump .4s ease-out; }
.sq-fav.uv-just-saved::after {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: 999px;
  border: 2px solid #f59e0b;
  opacity: 0;
  pointer-events: none;
  animation: uv-ripple .55s ease-out;
}

@keyframes uv-book-pop {
  0% { transform: scale(.4) rotate(-14deg); }
  55% { transform: scale(1.28) rotate(6deg); }
  100% { transform: scale(1) rotate(0deg); }
}

@keyframes uv-ripple {
  0% { transform: scale(.72); opacity: .85; }
  100% { transform: scale(1.28); opacity: 0; }
}

/* --------------------------------------------------------------------------
   4. 主按钮按压反馈（全局 .btn 增强）
      源组件：uiverse.io/vinodjangid07/heavy-badger-29 的 active 缩放思想 · MIT
   -------------------------------------------------------------------------- */
.btn:active { transform: translateY(0) scale(.98); }
.btn-primary:active { transform: translateY(0) scale(.972); }

/* --------------------------------------------------------------------------
   5. 输入框平滑过渡（.doc-search-field 增强）
      源组件：uiverse.io/alexruix/jolly-emu-80 的 cubic-bezier(.25,.01,.25,1) · MIT
   -------------------------------------------------------------------------- */
.doc-search-field {
  transition:
    border-color .3s cubic-bezier(.25,.01,.25,1),
    box-shadow .3s cubic-bezier(.25,.01,.25,1),
    background-color .25s cubic-bezier(.25,.01,.25,1);
}

/* --------------------------------------------------------------------------
   可访问性：减少动态偏好下，停用本文件全部装饰动画
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .uv-typewriter,
  .uv-typewriter .slide,
  .uv-typewriter .paper,
  .uv-typewriter .keyboard:after { animation: none; }
  .uv-typewriter .paper { transform: translateY(22px); }
  .sq-like.uv-just-liked svg,
  .sq-like.uv-just-liked .sq-like-num,
  .sq-like.uv-just-liked .uv-burst,
  .sq-fav.uv-just-saved svg,
  .sq-fav.uv-just-saved .sq-like-num,
  .sq-fav.uv-just-saved::after { animation: none; }
}
