/* ============================================================
   烛心 · 动画层 v3（丝滑统合版）
   ------------------------------------------------------------
   目标：
   1. 全站所有可动画元素统一缓动体系，手感一致
   2. 卡片/列表/标签等交错入场「自动适配任意数量」
      —— 用 CSS 变量 --i（由 JS 写入序号）驱动延迟，
         新增卡片无需改任何 CSS
   3. 兜底：没有 JS 写入序号时，用 nth-child 前 12 个兜底
   4. 全程只动 transform / opacity（GPU 合成，不重排）
   5. 尊重 prefers-reduced-motion 与 html.no-anim
   ============================================================ */

/* ---------- 缓动与时长体系（全站唯一来源） ---------- */
:root {
  --ease-out:      cubic-bezier(.22, 1, .36, 1);
  --ease-soft:     cubic-bezier(.4, 0, .2, 1);
  --ease-spring:   cubic-bezier(.34, 1.56, .64, 1);
  --ease-spring-2: cubic-bezier(.2, 1.1, .35, 1);
  --ease-in-out:   cubic-bezier(.65, 0, .35, 1);
  --ease-expo:     cubic-bezier(.16, 1, .3, 1);

  --dur-instant: .12s;
  --dur-fast:    .2s;
  --dur:         .38s;
  --dur-slow:    .6s;
  --dur-slower:  .9s;

  --stagger: 55ms;

  /* 交错入场：优先用 JS 写的序号，缺失时回退 0 */
  --i: 0;
  --stagger-delay: calc(var(--i) * var(--stagger));
}

/* ============================================================
   1. 交错延迟：自动适配任意数量卡片
   ------------------------------------------------------------
   原理：JS 给容器内每个子元素写 style="--i:N"。
   这里统一用 --stagger-delay 作为动画/过渡延迟。
   新增卡片时 JS 自动重算序号，CSS 一行都不用改。
   ============================================================ */
.stagger > * {
  animation-delay: var(--stagger-delay, 0ms);
}
/* 兜底：没有 JS 时用 nth-child 覆盖前 12 个 */
.stagger > *:nth-child(1)  { --i: 0; }
.stagger > *:nth-child(2)  { --i: 1; }
.stagger > *:nth-child(3)  { --i: 2; }
.stagger > *:nth-child(4)  { --i: 3; }
.stagger > *:nth-child(5)  { --i: 4; }
.stagger > *:nth-child(6)  { --i: 5; }
.stagger > *:nth-child(7)  { --i: 6; }
.stagger > *:nth-child(8)  { --i: 7; }
.stagger > *:nth-child(9)  { --i: 8; }
.stagger > *:nth-child(10) { --i: 9; }
.stagger > *:nth-child(11) { --i: 10; }
.stagger > *:nth-child(12) { --i: 11; }

/* ============================================================
   2. 通用入场关键帧
   ============================================================ */
@keyframes riseIn {
  from { opacity: 0; transform: translate3d(0, 22px, 0) scale(.98); }
  to   { opacity: 1; transform: translate3d(0, 0, 0) scale(1); }
}
@keyframes fadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes popIn {
  0%   { opacity: 0; transform: scale(.86); }
  60%  { opacity: 1; transform: scale(1.04); }
  100% { opacity: 1; transform: scale(1); }
}
@keyframes slideInLeft {
  from { opacity: 0; transform: translate3d(-18px, 0, 0); }
  to   { opacity: 1; transform: translate3d(0, 0, 0); }
}
@keyframes slideInRight {
  from { opacity: 0; transform: translate3d(18px, 0, 0); }
  to   { opacity: 1; transform: translate3d(0, 0, 0); }
}
/* ★ 文字从下往上淡入（本次重点补做） */
@keyframes textRise {
  from {
    opacity: 0;
    transform: translate3d(0, 30px, 0);
    filter: blur(6px);
  }
  to {
    opacity: 1;
    transform: translate3d(0, 0, 0);
    filter: blur(0);
  }
}
/* ★ 逐字/逐行上浮（更细腻的段落入场） */
@keyframes lineRise {
  from { opacity: 0; transform: translate3d(0, 18px, 0) scale(.985); }
  to   { opacity: 1; transform: translate3d(0, 0, 0) scale(1); }
}
@keyframes barGrow {
  from { opacity: 0; transform: scaleY(.15); }
  to   { opacity: 1; transform: scaleY(1); }
}
@keyframes barFillX {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}
@keyframes iconPop {
  0%   { transform: scale(1) rotate(0deg); }
  40%  { transform: scale(1.3) rotate(-8deg); }
  70%  { transform: scale(.94) rotate(4deg); }
  100% { transform: scale(1) rotate(0deg); }
}
@keyframes pulseGlow {
  0%, 100% { opacity: 1; }
  50%      { opacity: .45; }
}
@keyframes floatY {
  0%, 100% { transform: translate3d(0, 0, 0); }
  50%      { transform: translate3d(0, -7px, 0); }
}
@keyframes sheen {
  0%   { transform: translateX(-130%); }
  52%  { transform: translateX(130%); }
  100% { transform: translateX(130%); }
}
@keyframes shakeX {
  0%, 100% { transform: translateX(0); }
  20%      { transform: translateX(-6px); }
  40%      { transform: translateX(6px); }
  60%      { transform: translateX(-4px); }
  80%      { transform: translateX(4px); }
}
@keyframes spinSlow {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* ============================================================
   2.1 ★ 页面级入场：每次切换标签页都会重新播放
   ------------------------------------------------------------
   原理：renderPage() 重建 #blocks 的 DOM，
   新元素插入时 keyframes 动画自动从头播放。
   因此这里用 animation 而不是 transition —— transition 在
   元素一出现就带 .in 类时会被「瞬间完成」，看不到效果。
   ============================================================ */

/* 区块容器：整体上浮淡入 */
#blocks > .block,
#blocks > .login-banner {
  animation: riseIn .62s var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * 70ms);
}

/* ★ 文字段落：从下往上淡入（带轻微模糊，更有质感）
   ------------------------------------------------------------
   注意 .block-text 是容器、.block-text p 是真正的段落。
   两者都做，但延迟错开：容器先动，文字随后逐段浮现。 */
.block-text,
.block p,
.block-text .txt {
  animation: textRise .8s var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * 70ms + 110ms);
  will-change: opacity, transform;
}
.block-text p {
  animation: textRise .72s var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * 90ms + 210ms);
}

/* 区块内标题稍晚一点，形成层次 */
.block-title,
.block > h3,
.block > h2 {
  animation: slideInLeft .6s var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * 70ms + 60ms);
}
.block-title::before,
.block > h3::before {
  transform-origin: top;
  animation: barGrow .6s var(--ease-spring-2) both;
  animation-delay: calc(var(--i, 0) * 70ms + 160ms);
}

/* 页面大标题：略微慢一点，突出层次 */
.page-head h1 {
  animation: textRise .7s var(--ease-out) both;
}
.page-head > p,
.page-head .sub {
  animation: textRise .7s var(--ease-out) both;
  animation-delay: .09s;
}

/* 统计卡片 */
.stat, .stat-item {
  animation: riseIn .66s var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * 55ms + 120ms);
}

/* 时间线：每条从下往上，逐条出现 */
.tl-item {
  animation: lineRise .7s var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * 80ms + 140ms);
}

/* 卡片列表 */
.acard, .li, .litem, .gitem, .scard {
  animation: riseIn .66s var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * 60ms);
}

/* 技能条 */
.bar-item, .bars .bar {
  animation: lineRise .66s var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * 70ms + 80ms);
}

/* 标签 */
.tag, .chip, .tl-tag {
  animation: popIn .5s var(--ease-spring-2) both;
  animation-delay: calc(var(--i, 0) * 35ms + 100ms);
}

/* 列表项（动态活动、榜单等） */
#actList li, #rankList li, .rank li, .acts li {
  animation: slideInLeft .55s var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * 40ms);
}

/* 积分区块 */
.pts-sec {
  animation: riseIn .6s var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * 70ms);
}

/* .reveal 的入场也改用 animation，保证切页时重播。
   注意：只对「真正的文字元素」用 textRise；
   .stat / .tl-item / .acard 等有自己动画的元素不要被覆盖，
   否则会丢掉各自的交错延迟与上浮曲线。 */
.reveal {
  opacity: 0;
  transform: translate3d(0, 30px, 0);
}
.reveal.in {
  opacity: 1;
  transform: translate3d(0, 0, 0);
}
.reveal.in:not(.stat):not(.stat-item):not(.tl-item):not(.acard):not(.li):not(.litem):not(.gitem):not(.scard):not(.bar-item):not(.mon-card):not(.pts-sec) {
  animation: textRise .75s var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * 60ms + 80ms);
}

/* ============================================================
   3. 性能：GPU 合成提示
   ============================================================ */
.acard, .li, .stat, .litem, .gitem, .bar, .bar-item, .tl-item,
.tab, .brand-avatar, .adban, .gbtn, .pbtn, .atab, .chip,
.pcard-copy, .dnav-item, .btn, .mon-card, .mon-pill, .scard,
.mon-bar-fill, .pts-sec, .tag {
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}
/* 只给真正会动的元素加 will-change，避免显存浪费 */
.acard, .li, .litem, .gitem, .adban, .scard, .mon-card {
  will-change: transform;
}

/* ============================================================
   4. 卡片：悬停抬升 + 光泽 + 边框点亮
   ============================================================ */
.acard, .li, .litem, .gitem, .scard, .mon-card {
  transition:
    transform var(--dur) var(--ease-spring-2),
    border-color var(--dur-fast) var(--ease-soft),
    box-shadow var(--dur) var(--ease-out),
    background var(--dur-fast) var(--ease-soft);
}
.acard:hover, .li:hover, .litem:hover, .gitem:hover,
.scard:hover, .mon-card:hover {
  transform: translate3d(0, -5px, 0) scale(1.012);
  box-shadow:
    0 18px 40px -18px rgba(0, 0, 0, .62),
    0 0 0 1px color-mix(in srgb, var(--accent) 18%, transparent);
}
.acard:active, .li:active, .litem:active, .gitem:active,
.scard:active, .mon-card:active {
  transform: translate3d(0, -2px, 0) scale(.995);
  transition-duration: var(--dur-fast);
}

/* 卡片图标 */
.acard .ic, .litem .ic, .gitem .ic, .li .ic {
  display: inline-block;
  transition: transform var(--dur) var(--ease-spring);
}
.acard:hover .ic, .gitem:hover .ic { transform: translateY(-2px) scale(1.16) rotate(-4deg); }
.litem:hover .ic, .li:hover .ic    { transform: scale(1.18) rotate(7deg); }

/* ============================================================
   5. 按钮：统一按下回弹
   ------------------------------------------------------------
   注意：navsmooth.css 里 .refresh-btn / .gmodal-btn 等用了
   !important 定义自己的手感（如刷新按钮旋转），
   这里只统一「没有特殊定义」的通用按钮，避免相互打架。
   ============================================================ */
button, .btn, .tab, .dnav-item, a.acard, a.li, a.litem, a.gitem {
  -webkit-tap-highlight-color: transparent;
}
.btn, .gbtn, .pbtn, .atab, .pcard-copy, .chip,
.rm-btn, .adban-btn, .to-top, .pts-sign-btn, .lb-btn {
  transition:
    transform var(--dur) var(--ease-spring-2),
    background var(--dur-fast) var(--ease-soft),
    border-color var(--dur-fast) var(--ease-soft),
    color var(--dur-fast) var(--ease-soft),
    box-shadow var(--dur) var(--ease-out),
    filter var(--dur-fast) var(--ease-soft);
}
.btn:hover, .gbtn:hover, .atab:hover, .rm-btn:hover {
  transform: translate3d(0, -2px, 0);
}
.btn:not(:disabled):active,
.gbtn:active, .pbtn:active, .atab:active,
.pcard-copy:active, .chip:active,
.rm-btn:active, .adban-btn:active, .to-top:active {
  transform: scale(.955);
  transition-duration: var(--dur-instant);
}
button:disabled { cursor: not-allowed; }

/* 图标按钮按下时图标缩一下 */
.gbtn .gb-ic { display: inline-block; transition: transform var(--dur) var(--ease-spring); }
.gbtn:hover .gb-ic { transform: scale(1.18) rotate(-6deg); }

/* ============================================================
   6. 列表 / 时间线 / 标签：交错入场
   ============================================================ */
.tl-item {
  animation: lineRise var(--dur-slow) var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * 80ms + 140ms);
}
.tl-item::before {
  transition: transform var(--dur) var(--ease-spring), box-shadow var(--dur);
}
.tl-item:hover::before {
  transform: scale(1.38);
  box-shadow: 0 0 0 5px color-mix(in srgb, var(--accent) 24%, transparent),
              0 0 16px var(--accent);
}
.tl-item h4 { transition: color var(--dur-fast) var(--ease-soft); }
.tl-item:hover h4 { color: var(--accent); }

/* 时间线竖线生长 */
.timeline::before {
  transform-origin: top;
  animation: barGrow var(--dur-slower) var(--ease-out) both;
  animation-delay: .1s;
}

/* 列表项左侧指示条 */
.li, .litem { position: relative; overflow: hidden; }
.li::before, .litem::before {
  content: '';
  position: absolute;
  left: 0; top: 50%;
  width: 2px; height: 0;
  background: var(--accent);
  border-radius: 0 2px 2px 0;
  transform: translateY(-50%);
  transition: height var(--dur) var(--ease-spring-2);
}
.li:hover::before, .litem:hover::before { height: 62%; }

/* 标签 */
.tag, .chip, .tl-tag {
  transition:
    transform var(--dur) var(--ease-spring),
    background var(--dur-fast) var(--ease-soft),
    border-color var(--dur-fast) var(--ease-soft),
    color var(--dur-fast) var(--ease-soft);
}
.tag:hover, .chip:hover, .tl-tag:hover {
  transform: translate3d(0, -3px, 0) scale(1.06);
}

/* ============================================================
   7. 技能条 / 统计
   ============================================================ */
.bar-item, .bars .bar {
  animation: lineRise var(--dur-slow) var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * 70ms + 80ms);
}
.bar i, .bar-fill {
  transform-origin: left;
  transition: width 1.15s var(--ease-expo);
}
/* 进度条流光 */
.bar-fill::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.45), transparent);
  transform: translateX(-100%);
  animation: sheen 2.4s var(--ease-soft) infinite;
}
.bar-fill { position: relative; overflow: hidden; }

.stat, .stat-item {
  animation: riseIn var(--dur-slow) var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * 55ms + 120ms);
  transition: transform var(--dur) var(--ease-spring-2),
              border-color var(--dur) var(--ease-soft);
}
.stat:hover, .stat-item:hover {
  transform: translate3d(0, -3px, 0);
  border-color: color-mix(in srgb, var(--accent) 42%, transparent);
}
.stat b, .stat-item b {
  display: inline-block;
  transition: transform var(--dur) var(--ease-spring), color var(--dur) var(--ease-soft);
}
.stat:hover b, .stat-item:hover b {
  transform: scale(1.1);
  color: var(--accent);
}

/* ============================================================
   8. 区块标题：金条生长 + 文字上浮
   ------------------------------------------------------------
   注意：这里与第 2.1 节保持一致的 delay 计算，
   否则后面的声明会覆盖前面的，交错效果会丢失。
   ============================================================ */
.block-title, .block > h3, .block > h2 {
  animation: slideInLeft var(--dur-slow) var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * 70ms + 60ms);
}
.block-title::before,
.block > h3::before {
  transform-origin: top;
  animation: barGrow var(--dur-slow) var(--ease-spring-2) both;
  animation-delay: calc(var(--i, 0) * 70ms + 160ms);
}

/* ============================================================
   9. 顶部栏 / 滚动进度
   ============================================================ */
.topbar {
  transition:
    box-shadow var(--dur) var(--ease-out),
    background var(--dur) var(--ease-soft),
    height var(--dur) var(--ease-expo);
}
html.scrolled .topbar {
  box-shadow: 0 10px 30px -20px rgba(0, 0, 0, .82);
  background: color-mix(in srgb, var(--bg) 92%, transparent);
}
.scroll-progress {
  will-change: width;
  transition: width .1s linear;
}

/* 标签下划线 */
.tab-underline {
  transition:
    transform var(--dur) var(--ease-expo),
    width var(--dur) var(--ease-expo),
    opacity var(--dur-fast) var(--ease-soft);
}
.tab { transition: color var(--dur-fast) var(--ease-soft); }
.tab .ti { display: inline-block; transition: transform var(--dur) var(--ease-spring); }
.tab:hover .ti { transform: translateY(-2px) scale(1.15); }
.tab.active .ti { animation: iconPop .5s var(--ease-spring); }

/* ============================================================
   10. 抽屉菜单
   ============================================================ */
.drawer { transition: transform .42s var(--ease-expo); }
.drawer-mask {
  transition: opacity var(--dur-slow) var(--ease-soft),
              visibility var(--dur-slow);
}
.dnav-item {
  animation: slideInLeft var(--dur) var(--ease-out) both;
  animation-delay: var(--stagger-delay, 0ms);
}

/* ============================================================
   11. 弹窗
   ============================================================ */
.gmodal-box { animation: popIn .4s var(--ease-spring-2) both; }
.gmodal-mask, .rm-mask {
  transition: opacity var(--dur) var(--ease-soft), visibility var(--dur);
}

/* ============================================================
   12. 监控面板 / 表格
   ============================================================ */
.mon-bar-fill {
  position: relative;
  overflow: hidden;
  transition: width .8s var(--ease-out), background .5s;
}
.mon-bar-fill::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.4), transparent);
  transform: translateX(-100%);
  animation: sheen 2.6s var(--ease-soft) infinite;
}
.mon-pill { transition: transform var(--dur-fast) var(--ease-spring); }
.mon-pill:hover { transform: translateY(-2px); }
.mon-live .dot { animation: pulseGlow 2s var(--ease-soft) infinite; }

.pts-sec { animation: riseIn var(--dur-slow) var(--ease-out) both; }
.pts-table tbody tr {
  transition: background var(--dur-fast) var(--ease-soft);
}
.pts-table tbody tr:hover {
  background: color-mix(in srgb, var(--accent) 7%, transparent);
}

/* ============================================================
   13. 加载骨架
   ============================================================ */
.skel, .skeleton { animation: pulseGlow 1.6s var(--ease-in-out) infinite; }

/* ============================================================
   14. 回到顶部
   ============================================================ */
.to-top {
  transition:
    opacity var(--dur) var(--ease-out),
    transform var(--dur) var(--ease-spring),
    border-color var(--dur-fast), color var(--dur-fast),
    box-shadow var(--dur-fast);
}
.to-top:hover {
  border-color: var(--accent);
  color: var(--accent);
  box-shadow: 0 8px 26px -8px color-mix(in srgb, var(--accent) 55%, transparent);
}

/* ============================================================
   15. 点击涟漪 / 按压反馈（JS 配合）
   ============================================================ */
.ripple {
  position: absolute;
  border-radius: 50%;
  pointer-events: none;
  background: radial-gradient(circle,
    color-mix(in srgb, var(--accent) 50%, transparent) 0%,
    color-mix(in srgb, var(--accent) 22%, transparent) 42%,
    transparent 70%);
  transform: translate(-50%, -50%) scale(0);
  opacity: .85;
  will-change: transform, opacity;
  animation: rippleOut .48s var(--ease-out) forwards;
}
@keyframes rippleOut {
  0%   { transform: translate(-50%, -50%) scale(.25); opacity: .8; }
  100% { transform: translate(-50%, -50%) scale(1);   opacity: 0; }
}
.tap-press {
  transform: scale(.985) !important;
  transition: transform .09s var(--ease-soft) !important;
}
.tap-release {
  transition: transform .34s var(--ease-spring) !important;
}

/* 数字脉冲 */
.num-bump { animation: numBump .5s var(--ease-spring) both; }
@keyframes numBump {
  0%   { transform: scale(1); }
  45%  { transform: scale(1.14); }
  100% { transform: scale(1); }
}

/* 小游戏 */
.gslot {
  transition: transform var(--dur) var(--ease-spring),
              border-color var(--dur-fast) var(--ease-soft),
              color var(--dur-fast) var(--ease-soft);
}
.gslot.win { animation: slotWin .62s var(--ease-spring) both; }
@keyframes slotWin {
  0%   { transform: scale(1); }
  40%  { transform: scale(1.18) rotate(-3deg); }
  70%  { transform: scale(.96) rotate(2deg); }
  100% { transform: scale(1); }
}
.dice-box.roll { animation: rollA .7s var(--ease-spring) both; }
@keyframes rollA {
  0%   { transform: rotate(0deg) scale(1); }
  50%  { transform: rotate(200deg) scale(1.12); }
  100% { transform: rotate(360deg) scale(1); }
}

/* ============================================================
   16. 外部页面（player / muyu / ai）通用增强
   ============================================================ */
.card, .box, .kv {
  transition:
    transform var(--dur) var(--ease-spring-2),
    border-color var(--dur-fast) var(--ease-soft),
    box-shadow var(--dur) var(--ease-out);
}
.card:hover, .box:hover, .kv:hover {
  border-color: color-mix(in srgb, var(--accent) 34%, transparent);
}
.mine .box:hover, .kv:hover { transform: translate3d(0, -3px, 0); }

/* 榜单行 */
.rank li, #actList li, #rankList li {
  transition: background var(--dur-fast) var(--ease-soft),
              transform var(--dur-fast) var(--ease-out);
}
.rank li:hover, #actList li:hover, #rankList li:hover {
  background: color-mix(in srgb, var(--accent) 8%, transparent);
  transform: translateX(3px);
}

/* 玩法按钮 */
.pcat, .pbtn {
  transition:
    transform var(--dur) var(--ease-spring-2),
    background var(--dur-fast) var(--ease-soft),
    border-color var(--dur-fast) var(--ease-soft),
    color var(--dur-fast) var(--ease-soft);
}
.pcat:hover, .pbtn:hover { transform: translate3d(0, -2px, 0); }
.pcat:active, .pbtn:active { transform: scale(.955); }

/* 输入框聚焦 */
input, textarea, select {
  transition: border-color var(--dur-fast) var(--ease-soft),
              box-shadow var(--dur) var(--ease-out),
              background var(--dur-fast) var(--ease-soft);
}
input:focus, textarea:focus, select:focus {
  border-color: color-mix(in srgb, var(--accent) 60%, transparent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 15%, transparent);
}

/* 木鱼 / 通用可点元素 */
[data-press] { transition: transform var(--dur-fast) var(--ease-spring); }
[data-press]:active { transform: scale(.94); }

/* ============================================================
   17. 无障碍 / 全局关闭
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
  .reveal, .reveal.in {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
}
html.no-anim *, html.no-anim *::before, html.no-anim *::after {
  animation: none !important;
  transition: none !important;
  opacity: 1 !important;
  transform: none !important;
}
