/* ==========================================================================
   animations.css — CSS 层动画（回退层）与档位降级规则
   适用范围：全站
   加载顺序：最后加载（在 base/layout/components 之后）
   档位说明（有效档位由 js/core/animation.js 写入 <html data-motion="...">）：
     full    丰富：位移 + 缩放 + 透明度，脉冲 / 骨架闪光 / 抖动 / 淡入
     reduced 简化：仅透明度与轻微缩放；关闭大位移与抖动
     opacity 仅透明度：URL anim=off 时使用；除透明度外全部关闭
     off     无动画：全部关闭，只保留即时的状态变化
   动画原则：只使用 transform 与 opacity，避免触发布局重排；
     脉冲 = ::after 的透明度变化；骨架闪光 = ::after 的 transform 平移。
   HTML 初始 data-motion="off"（避免脚本执行前误播动画），
   JS 启动后立即切换为设备评分结果。
   旋转指示器（.btn__spinner）属于功能反馈，在所有档位保留。
   ========================================================================== */

/* --------------------------------------------------------------------------
   骨架屏高亮色（供闪光渐变使用，跟随明暗主题）
   -------------------------------------------------------------------------- */
:root {
  --color-skeleton-hi: #e3e9f1;
}
@media (prefers-color-scheme: dark) {
  :root {
    --color-skeleton-hi: #242b35;
  }
}

/* --------------------------------------------------------------------------
   关键帧定义
   -------------------------------------------------------------------------- */
@keyframes rq-spin {
  to {
    transform: rotate(360deg);
  }
}
@keyframes rq-pulse {
  0%,
  100% {
    opacity: 0;
  }
  50% {
    opacity: 1;
  }
}
@keyframes rq-shimmer {
  from {
    transform: translateX(-100%);
  }
  to {
    transform: translateX(100%);
  }
}
@keyframes rq-shake {
  10%,
  90% {
    transform: translateX(-2px);
  }
  20%,
  80% {
    transform: translateX(3px);
  }
  30%,
  50%,
  70% {
    transform: translateX(-5px);
  }
  40%,
  60% {
    transform: translateX(5px);
  }
}
@keyframes rq-fade-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
@keyframes rq-rise-in {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
@keyframes rq-menu-in {
  from {
    opacity: 0;
    transform: translateY(-4px) scale(0.98);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
@keyframes rq-toast-in {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
@keyframes rq-check-pop {
  from {
    opacity: 0;
    transform: rotate(-45deg) scale(0.6) translateY(-1px);
  }
  to {
    opacity: 1;
    transform: rotate(-45deg) scale(1) translateY(-1px);
  }
}

/* --------------------------------------------------------------------------
   旋转指示器：功能反馈，所有档位保留（无动画环境下静态圆环仍可辨识）
   -------------------------------------------------------------------------- */
.btn__spinner {
  animation: rq-spin 0.8s linear infinite;
}

/* ==========================================================================
   丰富档（full）
   ========================================================================== */
html[data-motion="full"] {
  scroll-behavior: smooth;
}
html[data-motion="full"] .anim-pulse::after {
  animation: rq-pulse 2.4s ease-in-out infinite;
}
html[data-motion="full"] .anim-shake {
  animation: rq-shake 360ms cubic-bezier(0.36, 0.07, 0.19, 0.97) 1;
}
html[data-motion="full"] .anim-fade-in {
  animation: rq-fade-in 320ms ease both;
}
html[data-motion="full"] .anim-rise-in {
  animation: rq-rise-in 320ms cubic-bezier(0.2, 0, 0, 1) both;
}
html[data-motion="full"] .anim-shimmer .skeleton__bar::after {
  opacity: 1;
  animation: rq-shimmer 1.6s linear infinite;
}
html[data-motion="full"] .copy-btn.is-copied .copy-btn__check {
  animation: rq-check-pop 180ms cubic-bezier(0.2, 0, 0, 1) both;
}
html[data-motion="full"] .btn:not([aria-disabled="true"]):active {
  transform: translateY(1px);
}
/* 悬停微抬升与柔和阴影（仅丰富档；原生与 aria 禁用态均不生效） */
html[data-motion="full"] .btn:not(:disabled):not([aria-disabled="true"]):hover {
  transform: translateY(-1px);
  box-shadow: 0 2px 6px rgba(15, 23, 42, 0.1);
  box-shadow: var(--shadow-hover);
}
html[data-motion="full"] .menu.is-open {
  animation: rq-menu-in 180ms cubic-bezier(0.2, 0, 0, 1) both;
}
html[data-motion="full"] .toast {
  animation: rq-toast-in 220ms cubic-bezier(0.2, 0, 0, 1) both;
}
html[data-motion="full"] .gate__progress-fill {
  will-change: transform;
}

/* ==========================================================================
   简化档（reduced）：只保留透明度与轻微缩放
   ========================================================================== */
html[data-motion="reduced"] .anim-pulse::after {
  animation: rq-pulse 3.2s ease-in-out infinite;
}
html[data-motion="reduced"] .anim-shake {
  animation: none;
}
html[data-motion="reduced"] .anim-fade-in {
  animation: rq-fade-in 240ms ease both;
}
html[data-motion="reduced"] .anim-rise-in {
  animation: rq-fade-in 240ms ease both; /* 位移降级为纯淡入 */
}
html[data-motion="reduced"] .anim-shimmer .skeleton__bar::after {
  animation: none;
}
html[data-motion="reduced"] .copy-btn.is-copied .copy-btn__check {
  animation: rq-fade-in 160ms ease both;
}
html[data-motion="reduced"] .btn:active {
  transform: scale(0.99); /* 轻微缩放，不产生位移 */
}
html[data-motion="reduced"] .menu.is-open {
  animation: rq-fade-in 160ms ease both;
}
html[data-motion="reduced"] .toast {
  animation: rq-fade-in 180ms ease both;
}

/* ==========================================================================
   仅透明度档（opacity，URL anim=off）
   ========================================================================== */
html[data-motion="opacity"] .anim-pulse::after,
html[data-motion="opacity"] .anim-shake,
html[data-motion="opacity"] .anim-shimmer .skeleton__bar::after {
  animation: none;
}
html[data-motion="opacity"] .anim-fade-in,
html[data-motion="opacity"] .anim-rise-in,
html[data-motion="opacity"] .copy-btn.is-copied .copy-btn__check,
html[data-motion="opacity"] .menu.is-open,
html[data-motion="opacity"] .toast {
  animation: rq-fade-in 200ms ease both;
}

/* ==========================================================================
   无动画档（off）
   ========================================================================== */
html[data-motion="off"] .anim-pulse::after,
html[data-motion="off"] .anim-shake,
html[data-motion="off"] .anim-shimmer .skeleton__bar::after,
html[data-motion="off"] .anim-fade-in,
html[data-motion="off"] .anim-rise-in,
html[data-motion="off"] .copy-btn.is-copied .copy-btn__check,
html[data-motion="off"] .menu.is-open,
html[data-motion="off"] .toast {
  animation: none;
}

/* --------------------------------------------------------------------------
   组件转场降级：无动画档取消全部过渡；仅透明度档去掉位移类过渡
   -------------------------------------------------------------------------- */
html[data-motion="off"] body,
html[data-motion="off"] a,
html[data-motion="off"] .btn,
html[data-motion="off"] .input,
html[data-motion="off"] .copy-btn,
html[data-motion="off"] .backup-item__toggle::after,
html[data-motion="off"] .backup-item__body-wrap,
html[data-motion="off"] .back-to-top,
html[data-motion="off"] .skip-link,
html[data-motion="off"] .toast,
html[data-motion="off"] .menu,
html[data-motion="off"] .gate__scroll,
html[data-motion="off"] .gate__progress-fill {
  transition: none;
}
html[data-motion="opacity"] a,
html[data-motion="opacity"] .btn,
html[data-motion="opacity"] .input,
html[data-motion="opacity"] .copy-btn,
html[data-motion="opacity"] .back-to-top,
html[data-motion="opacity"] .gate__progress-fill {
  transition-property: opacity, background-color, border-color, color,
    box-shadow;
}
html[data-motion="opacity"] .backup-item__toggle::after {
  transition: none;
}
html[data-motion="opacity"] .backup-item__body-wrap {
  transition: none;
}
html[data-motion="opacity"] .btn:active,
html[data-motion="off"] .btn:active {
  transform: none;
}

/* --------------------------------------------------------------------------
   门禁解锁的边框亮起过渡（full/reduced 保留颜色过渡）
   -------------------------------------------------------------------------- */
.gate__scroll {
  transition: border-color 280ms ease;
}
