/* --------------------------------------------------------------------------
   噪点溶解（dither）背景：技法逐项对齐 CodePen "Dithered CSS Gradients"
   案例——纯色基底 + 径向渐变背景层，mask = 噪点贴图
   （/textures/dither-noise.png，65×65 平铺，黑色像素 + 随机 Alpha）
   与同形状径向渐变按案例默认 add 合成：渐变过渡区只有噪点 Alpha 足够的
   像素显影，形成颗粒感消隐，杜绝平滑色带；
   image-rendering: pixelated 保持颗粒锐利。
   溶解圆心在顶部中央（案例的 circle at 50% 0）：基底圆盘藏在封面窗后，
   致密颗粒带从窗底缘开始铺满全卡。

   与案例唯一的有意差异：mask 渐变的封顶不透明度。
   案例封顶 #000（alpha 1），渐变饱和区 mask=1 → 颗粒消失、落回纯色
   （案例元素仅 130px，饱和区很小，无伤大雅）；竖版卡片要求顶部到底部
   全程保持颗粒，故封顶降为 alpha 0.8：饱和区 = 80%~94% 图层色 +
   噪点提供的 ±14% 细腻颗粒起伏——与案例过渡带同款的柔和颗粒质感，
   铺满全卡且不伤文字可读性。
   -------------------------------------------------------------------------- */

.dither-bg {
  position: absolute;
  inset: 0;
  overflow: hidden;
  image-rendering: pixelated;
  background-color: var(--dither-base, #ffecd2);
  /* mask 渐变封顶（见文件头注释）：案例为 #000，卡片降为 80% 以保留全卡颗粒 */
  --dither-mask-plateau: rgb(0 0 0 / 0.8);
}

.dither-bg__layer {
  position: absolute;
  inset: 0;
}

/* 沸腾变体：背景放大 110% 并回偏（案例原版补偿），
   feDisplacementMap 扭曲时边缘不会裁出缺口；
   外层卡体 overflow-hidden 负责收边 */
.dither-bg--boil {
  inset: -5%;
}

/* 径向溶解层：颜色从 --dither-pos 位置由透明颗粒化过渡到纯色。
   mask = 噪点贴图 + 径向渐变，按案例默认 add 合成，
   mask 渐变区间取案例公式 start-10 → stop+15%，封顶用 plateau（非 #000） */
.dither-bg__layer--radial {
  background-image: radial-gradient(
    circle at var(--dither-pos, 50% 0),
    transparent var(--dither-start, 25%),
    var(--dither-color) var(--dither-stop, 65%)
  );
  -webkit-mask-image:
    url("/textures/dither-noise.png"),
    radial-gradient(
      circle at var(--dither-pos, 50% 0),
      transparent var(--dither-mask-start, 5%),
      var(--dither-mask-plateau) var(--dither-mask-stop, 80%)
    );
  mask-image:
    url("/textures/dither-noise.png"),
    radial-gradient(
      circle at var(--dither-pos, 50% 0),
      transparent var(--dither-mask-start, 5%),
      var(--dither-mask-plateau) var(--dither-mask-stop, 80%)
    );
}

/* aura 变体专用：案例页面底纹同款的两层溶解（颜色由内联变量注入），
   mask 封顶同样用 plateau，理由见文件头注释 */
/* 中心径向溶解（案例 body::before） */
.dither-bg__layer--aura-radial {
  background-image: radial-gradient(
    circle at 50% 50%,
    transparent 30%,
    var(--dither-color) 60%
  );
  -webkit-mask-image:
    url("/textures/dither-noise.png"),
    radial-gradient(
      circle at 50% 50%,
      transparent 30%,
      var(--dither-mask-plateau) 70%
    );
  mask-image:
    url("/textures/dither-noise.png"),
    radial-gradient(
      circle at 50% 50%,
      transparent 30%,
      var(--dither-mask-plateau) 70%
    );
}

/* 对角线性溶解（案例 body::after）：两个对角各染一种颜色 */
.dither-bg__layer--aura-diagonal {
  background-image: linear-gradient(
    45deg,
    var(--dither-color-a) 10%,
    transparent 25%,
    transparent 75%,
    var(--dither-color-b) 90%
  );
  -webkit-mask-image:
    url("/textures/dither-noise.png"),
    linear-gradient(
      45deg,
      var(--dither-mask-plateau) 0%,
      transparent 25%,
      transparent 75%,
      var(--dither-mask-plateau) 100%
    );
  mask-image:
    url("/textures/dither-noise.png"),
    linear-gradient(
      45deg,
      var(--dither-mask-plateau) 0%,
      transparent 25%,
      transparent 75%,
      var(--dither-mask-plateau) 100%
    );
}
/* --------------------------------------------------------------------------
   沸腾火柴人场景动画（boil-scenes.tsx）
   序章 walker + 等级卡"忍者成长弧"（风格参考《忍者必须死3》）：
   疾影 → 三连斩 → 居合一闪 → 影分身 → 炎遁 → 天降 → 残心 → 万剑。
   骨骼系统：两节关节肢体（肘/膝独立弯曲）+ 髋部俯仰组——
   挥剑有鞭甩（肘先屈后弹）、跑跳有重心起伏，动作才丝滑。
   节奏原则：攻击快、收势慢（非对称），落地带回弹，跃起有滞空。
   沸腾抖动由 StickmanBoilDeco 壳内的 SVG filter 完成，本文件只负责场景动画。
   -------------------------------------------------------------------------- */

.boil-stage {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}

/* ======================= 共享：忍者三段围巾 ======================= */
.bsn-scarf__seg1,
.bsn-scarf__seg2,
.bsn-scarf__seg3 {
  transform-origin: 0 0;
  animation: bsn-scarf-wave1 0.5s ease-in-out infinite alternate;
}
.bsn-scarf__seg2 {
  animation-name: bsn-scarf-wave2;
  animation-delay: -0.12s;
}
.bsn-scarf__seg3 {
  animation-name: bsn-scarf-wave3;
  animation-delay: -0.24s;
}
@keyframes bsn-scarf-wave1 {
  from { transform: rotate(-10deg); }
  to { transform: rotate(8deg); }
}
@keyframes bsn-scarf-wave2 {
  from { transform: rotate(-14deg); }
  to { transform: rotate(12deg); }
}
@keyframes bsn-scarf-wave3 {
  from { transform: rotate(-18deg); }
  to { transform: rotate(16deg); }
}
/* 悬浮/下坠场景：围巾向上扬起 */
.bsn-scarf__seg1--up { animation-name: bsn-scarf-up1; }
.bsn-scarf__seg2--up { animation-name: bsn-scarf-up2; }
.bsn-scarf__seg3--up { animation-name: bsn-scarf-up3; }
@keyframes bsn-scarf-up1 {
  from { transform: rotate(-135deg); }
  to { transform: rotate(-115deg); }
}
@keyframes bsn-scarf-up2 {
  from { transform: rotate(-20deg); }
  to { transform: rotate(14deg); }
}
@keyframes bsn-scarf-up3 {
  from { transform: rotate(-24deg); }
  to { transform: rotate(20deg); }
}

/* ======================= 共享：疾跑躯体（疾影 / 炎遁） ======================= */
/* 大跨步飞驰：大腿 15°(前探) ↔ 118°(后蹬伸直)，膝盖独立勾弹 */
.bsn-sprint__bob {
  animation: bsn-sprint-bob 0.26s ease-in-out infinite alternate;
}
@keyframes bsn-sprint-bob {
  from { transform: translateY(0); }
  to { transform: translateY(-2.5px); }
}
.bsn-sprint__pitch {
  transform-origin: 0 0;
  animation: bsn-sprint-pitch 0.26s ease-in-out infinite alternate;
}
@keyframes bsn-sprint-pitch {
  from { transform: rotate(-2deg); }
  to { transform: rotate(4deg); }
}
.bsn-sprint__thigh-front,
.bsn-sprint__thigh-back {
  transform-origin: 0 0;
  animation: bsn-sprint-thigh 0.26s ease-in-out infinite alternate;
}
.bsn-sprint__thigh-back {
  animation-direction: alternate-reverse;
}
@keyframes bsn-sprint-thigh {
  from { transform: rotate(15deg); }
  to { transform: rotate(118deg); }
}
/* 膝盖：腿前抬时勾小腿（蓄势），下踏时弹直（发力） */
.bsn-sprint__knee-front,
.bsn-sprint__knee-back {
  transform-origin: 0 0;
  animation: bsn-sprint-knee 0.26s ease-in-out infinite alternate;
}
.bsn-sprint__knee-back {
  animation-direction: alternate-reverse;
}
@keyframes bsn-sprint-knee {
  from { transform: rotate(82deg); }
  to { transform: rotate(8deg); }
}
/* 负剑臂 / 后甩臂：全程保持后扬姿态，仅随步伐小幅晃动（反向相位） */
.bsn-sprint__arm-sword,
.bsn-sprint__arm-swing {
  transform-origin: 0 0;
  animation: bsn-sprint-sway 0.26s ease-in-out infinite alternate;
}
.bsn-sprint__arm-swing {
  animation-direction: alternate-reverse;
}
@keyframes bsn-sprint-sway {
  from { transform: rotate(-3deg); }
  to { transform: rotate(3deg); }
}

/* ======================= 序章 · walker（初入江湖） ======================= */

.bs-walker__walker {
  transform: translate(105px, 14px);
}
.bs-walker__figure {
  animation: bs-walker-bob 0.6s ease-in-out infinite alternate;
}
@keyframes bs-walker-bob {
  from { transform: translateY(0); }
  to { transform: translateY(-1.5px); }
}
/* 两节腿行走：大腿 68° ↔ 112°，膝盖在摆动中期弯曲 */
.bs-walker__leg-front,
.bs-walker__leg-back {
  transform-origin: 0 0;
  animation: bs-walker-thigh 0.6s ease-in-out infinite alternate;
}
.bs-walker__leg-back {
  animation-direction: alternate-reverse;
}
@keyframes bs-walker-thigh {
  from { transform: rotate(68deg); }
  to { transform: rotate(112deg); }
}
.bs-walker__knee-front,
.bs-walker__knee-back {
  transform-origin: 0 0;
  animation: bs-walker-knee 0.6s ease-in-out infinite alternate;
}
.bs-walker__knee-back {
  animation-direction: alternate-reverse;
}
@keyframes bs-walker-knee {
  from { transform: rotate(8deg); }
  to { transform: rotate(38deg); }
}
/* 两节臂自然摆动 */
.bs-walker__arm-front,
.bs-walker__arm-back {
  transform-origin: 0 0;
  animation: bs-walker-swing 0.6s ease-in-out infinite alternate;
}
.bs-walker__arm-back {
  animation-direction: alternate-reverse;
}
@keyframes bs-walker-swing {
  from { transform: rotate(76deg); }
  to { transform: rotate(104deg); }
}
.bs-walker__scarf {
  transform-origin: 0 0;
  animation: bs-walker-flutter 0.7s ease-in-out infinite alternate;
}
@keyframes bs-walker-flutter {
  from { transform: rotate(-7deg); }
  to { transform: rotate(7deg); }
}
.bs-walker__mountains {
  animation: bs-walker-drift-far 14s linear infinite;
}
@keyframes bs-walker-drift-far {
  from { transform: translateX(0); }
  to { transform: translateX(-240px); }
}
.bs-walker__grass {
  animation: bs-walker-drift-near 2.8s linear infinite;
}
@keyframes bs-walker-drift-near {
  from { transform: translateX(0); }
  to { transform: translateX(-240px); }
}
.bs-walker__mist {
  opacity: 0.1;
  animation: bs-walker-breathe 5s ease-in-out infinite alternate;
}
@keyframes bs-walker-breathe {
  from { opacity: 0.07; }
  to { opacity: 0.16; }
}
.bs-walker__star {
  transform-box: fill-box;
  transform-origin: center;
  opacity: 0.55;
  animation: bs-walker-twinkle 3s ease-in-out infinite;
}
@keyframes bs-walker-twinkle {
  0%, 100% { opacity: 0.4; transform: translate(214px, 20px) scale(0.85); }
  50% { opacity: 1; transform: translate(214px, 20px) scale(1.15); }
}

/* ======================= LV.10 · training（疾影） ======================= */

.bsn-dash__runner,
.bsn-dash__ghost {
  animation: bsn-dash-run 3.4s linear infinite;
}
.bsn-dash__ghost--near { animation-delay: 0.1s; }
.bsn-dash__ghost--far { animation-delay: 0.2s; }
@keyframes bsn-dash-run {
  from { transform: translate(-48px, 16px); }
  to { transform: translate(256px, 16px); }
}
.bsn-dash__streak {
  animation: bsn-dash-streak 0.45s linear infinite;
}
.bsn-dash__streak--2 { animation-delay: -0.15s; }
.bsn-dash__streak--3 { animation-delay: -0.3s; }
@keyframes bsn-dash-streak {
  from { transform: translateX(250px); opacity: 0; }
  25% { opacity: 0.55; }
  to { transform: translateX(-50px); opacity: 0; }
}

/* ======================= LV.25 · slash（三连斩） ======================= */
/* 三段连招 3s 循环：低身横扫(0-30%) → 拧身上撩(30-55%) → 跃起跳劈(55-80%) → 回稳
   节奏：攻击快、收势慢；腾空有滞空、落地有回弹 */

/* 重心：深蹲蓄力 → 起身 → 腾空 → 落地回弹 */
.bsn-combo__body {
  animation: bsn-combo-body 3s cubic-bezier(0.6, 0, 0.3, 1) infinite;
}
@keyframes bsn-combo-body {
  0%, 18% { transform: translateY(5px); }
  45% { transform: translateY(1px); }
  58% { transform: translateY(-4px); }
  66% { transform: translateY(-13px); }
  74% { transform: translateY(3px); }
  84%, 100% { transform: translateY(5px); }
}
/* 躯干：低身大幅前倾 → 拧身挺直 → 跃起后仰蓄力 → 劈落猛前倾 */
.bsn-combo__pitch {
  transform-origin: 0 0;
  animation: bsn-combo-pitch 3s cubic-bezier(0.6, 0, 0.3, 1) infinite;
}
@keyframes bsn-combo-pitch {
  0%, 10% { transform: rotate(42deg); }
  30% { transform: rotate(38deg); }
  45% { transform: rotate(8deg); }
  58% { transform: rotate(-16deg); }
  72% { transform: rotate(46deg); }
  82% { transform: rotate(38deg); }
  94%, 100% { transform: rotate(42deg); }
}
/* 双腿：深蹲屈 → 起身蹬直 → 腾空收腿团身 → 落地张开缓冲 */
.bsn-combo__thigh-f,
.bsn-combo__thigh-b,
.bsn-combo__knee-f,
.bsn-combo__knee-b {
  transform-origin: 0 0;
  animation: bsn-combo-limb 3s cubic-bezier(0.6, 0, 0.3, 1) infinite;
}
.bsn-combo__thigh-f { animation-name: bsn-combo-thigh-f; }
@keyframes bsn-combo-thigh-f {
  0%, 18% { transform: rotate(45deg); }
  45% { transform: rotate(70deg); }
  58% { transform: rotate(40deg); }
  66% { transform: rotate(32deg); }
  74% { transform: rotate(60deg); }
  100% { transform: rotate(45deg); }
}
.bsn-combo__knee-f { animation-name: bsn-combo-knee-f; }
@keyframes bsn-combo-knee-f {
  0%, 18% { transform: rotate(40deg); }
  45% { transform: rotate(15deg); }
  58% { transform: rotate(75deg); }
  66% { transform: rotate(90deg); }
  74% { transform: rotate(30deg); }
  100% { transform: rotate(40deg); }
}
.bsn-combo__thigh-b { animation-name: bsn-combo-thigh-b; }
@keyframes bsn-combo-thigh-b {
  0%, 18% { transform: rotate(130deg); }
  45% { transform: rotate(95deg); }
  58% { transform: rotate(55deg); }
  66% { transform: rotate(45deg); }
  74% { transform: rotate(110deg); }
  100% { transform: rotate(130deg); }
}
.bsn-combo__knee-b { animation-name: bsn-combo-knee-b; }
@keyframes bsn-combo-knee-b {
  0%, 18% { transform: rotate(12deg); }
  45% { transform: rotate(18deg); }
  58% { transform: rotate(70deg); }
  66% { transform: rotate(85deg); }
  74% { transform: rotate(20deg); }
  100% { transform: rotate(12deg); }
}
/* 平衡臂：低身撑地 → 拧身护于胸前 → 跃起向后上方甩开 → 劈落向后下方压 */
.bsn-combo__arm-free {
  transform-origin: 0 0;
  animation: bsn-combo-arm-free 3s cubic-bezier(0.6, 0, 0.3, 1) infinite;
}
@keyframes bsn-combo-arm-free {
  0%, 30% { transform: rotate(36deg); }
  45% { transform: rotate(-43deg); }
  58% { transform: rotate(-150deg); }
  72% { transform: rotate(94deg); }
  86% { transform: rotate(60deg); }
  100% { transform: rotate(36deg); }
}
/* 持剑臂肩扫：后引蓄势 → 低扫命中 → 回带 → 上撩 → 过顶 → 砸落 → 回收 */
.bsn-combo__arm-sword {
  transform-origin: 0 0;
  animation: bsn-combo-swing 3s cubic-bezier(0.6, 0, 0.3, 1) infinite;
}
@keyframes bsn-combo-swing {
  0%, 6% { transform: rotate(133deg); }
  16% { transform: rotate(48deg); }
  24% { transform: rotate(38deg); }
  45% { transform: rotate(-60deg); }
  58% { transform: rotate(-95deg); }
  72% { transform: rotate(30deg); }
  80% { transform: rotate(45deg); }
  94%, 100% { transform: rotate(133deg); }
}
/* 肘部鞭甩：蓄力时深屈、击中瞬间弹直 */
.bsn-combo__elbow {
  transform-origin: 0 0;
  animation: bsn-combo-elbow 3s cubic-bezier(0.6, 0, 0.3, 1) infinite;
}
@keyframes bsn-combo-elbow {
  0%, 6% { transform: rotate(-55deg); }
  16% { transform: rotate(-12deg); }
  24% { transform: rotate(-30deg); }
  45% { transform: rotate(-25deg); }
  58% { transform: rotate(-29deg); }
  72% { transform: rotate(-8deg); }
  80% { transform: rotate(-20deg); }
  94%, 100% { transform: rotate(-55deg); }
}
/* 腕部翻转（手之内）：横扫时翻腕压低剑刃贴身扫出，上撩/跳劈时立腕送剑 */
.bsn-combo__blade {
  transform-origin: 0 0;
  animation: bsn-combo-blade 3s cubic-bezier(0.6, 0, 0.3, 1) infinite;
}
@keyframes bsn-combo-blade {
  0%, 6% { transform: rotate(90deg); }
  16% { transform: rotate(-58deg); }
  24% { transform: rotate(-70deg); }
  45% { transform: rotate(17deg); }
  58% { transform: rotate(10deg); }
  72% { transform: rotate(-8deg); }
  80% { transform: rotate(-30deg); }
  88% { transform: rotate(20deg); }
  94%, 100% { transform: rotate(90deg); }
}
/* 三道刀光：与肩扫关键帧严格同相位，dash 沿剑刃行进方向揭示，
   长度按各弧实际弧长设置（横扫 85°≈62 / 上撩 98°≈72 / 跳劈 125°≈92） */
.bsn-combo__arc {
  stroke-dasharray: 62;
  stroke-dashoffset: 62;
  opacity: 0;
  animation: bsn-combo-arc 3s linear infinite;
}
.bsn-combo__arc--2 {
  stroke-dasharray: 72;
  stroke-dashoffset: 72;
  animation-name: bsn-combo-arc-2;
}
.bsn-combo__arc--3 {
  stroke-dasharray: 92;
  stroke-dashoffset: 92;
  animation-name: bsn-combo-arc-3;
}
@keyframes bsn-combo-arc {
  0%, 5% { opacity: 0; stroke-dashoffset: 62; }
  7% { opacity: 0.95; }
  15% { opacity: 0.95; stroke-dashoffset: 0; }
  24%, 100% { opacity: 0; stroke-dashoffset: 0; }
}
@keyframes bsn-combo-arc-2 {
  0%, 23% { opacity: 0; stroke-dashoffset: 72; }
  26% { opacity: 0.95; }
  44% { opacity: 0.95; stroke-dashoffset: 0; }
  54%, 100% { opacity: 0; stroke-dashoffset: 0; }
}
@keyframes bsn-combo-arc-3 {
  0%, 57% { opacity: 0; stroke-dashoffset: 92; }
  60% { opacity: 0.95; }
  71% { opacity: 0.95; stroke-dashoffset: 0; }
  82%, 100% { opacity: 0; stroke-dashoffset: 0; }
}
/* 火花：三次挥砍各自的剑尖落点，命中瞬间迸发 */
.bsn-combo__spark {
  opacity: 0;
  animation: bsn-combo-spark 3s linear infinite;
}
.bsn-combo__spark--2 { animation-name: bsn-combo-spark-2; }
.bsn-combo__spark--3 { animation-name: bsn-combo-spark-3; }
@keyframes bsn-combo-spark {
  0%, 13% { opacity: 0; }
  16% { opacity: 1; }
  26%, 100% { opacity: 0; }
}
@keyframes bsn-combo-spark-2 {
  0%, 43% { opacity: 0; }
  46% { opacity: 1; }
  56%, 100% { opacity: 0; }
}
@keyframes bsn-combo-spark-3 {
  0%, 70% { opacity: 0; }
  73% { opacity: 1; }
  84%, 100% { opacity: 0; }
}

/* ======================= LV.40 · charge（居合·一闪） ======================= */

/* 忍者：深蹲蓄力 → 瞬身（重心压低再弹起）→ 伫立收刀（3.2s 循环） */
.bsn-isshin__ninja {
  animation: bsn-isshin-dash 3.2s cubic-bezier(0.7, 0, 0.3, 1) infinite;
}
@keyframes bsn-isshin-dash {
  0%, 34% { transform: translate(52px, 20px); }
  40%, 100% { transform: translate(190px, 14px); }
}
/* 躯干：深蹲前倾 → 瞬身几乎放平 → 收刀挺直 */
.bsn-isshin__pitch {
  transform-origin: 0 0;
  animation: bsn-isshin-pitch 3.2s cubic-bezier(0.7, 0, 0.3, 1) infinite;
}
@keyframes bsn-isshin-pitch {
  0%, 34% { transform: rotate(28deg); }
  40% { transform: rotate(44deg); }
  54% { transform: rotate(5deg); }
  70%, 100% { transform: rotate(0); }
}
/* 双腿：深蹲屈 → 瞬身前后劈叉 → 收势并步 */
.bsn-isshin__thigh-front {
  transform-origin: 0 0;
  animation: bsn-isshin-thigh-f 3.2s cubic-bezier(0.7, 0, 0.3, 1) infinite;
}
@keyframes bsn-isshin-thigh-f {
  0%, 34% { transform: rotate(42deg); }
  40% { transform: rotate(28deg); }
  54% { transform: rotate(92deg); }
  70%, 100% { transform: rotate(88deg); }
}
.bsn-isshin__knee-front {
  transform-origin: 0 0;
  animation: bsn-isshin-knee-f 3.2s cubic-bezier(0.7, 0, 0.3, 1) infinite;
}
@keyframes bsn-isshin-knee-f {
  0%, 34% { transform: rotate(70deg); }
  40% { transform: rotate(8deg); }
  54% { transform: rotate(14deg); }
  70%, 100% { transform: rotate(12deg); }
}
.bsn-isshin__thigh-back {
  transform-origin: 0 0;
  animation: bsn-isshin-thigh-b 3.2s cubic-bezier(0.7, 0, 0.3, 1) infinite;
}
@keyframes bsn-isshin-thigh-b {
  0%, 34% { transform: rotate(115deg); }
  40% { transform: rotate(132deg); }
  54% { transform: rotate(96deg); }
  70%, 100% { transform: rotate(92deg); }
}
.bsn-isshin__knee-back {
  transform-origin: 0 0;
  animation: bsn-isshin-knee-b 3.2s cubic-bezier(0.7, 0, 0.3, 1) infinite;
}
@keyframes bsn-isshin-knee-b {
  0%, 34% { transform: rotate(65deg); }
  40% { transform: rotate(15deg); }
  54% { transform: rotate(14deg); }
  70%, 100% { transform: rotate(12deg); }
}
.bsn-isshin__arm-sword {
  transform-origin: 0 0;
  animation: bsn-isshin-arm 3.2s ease-in-out infinite;
}
@keyframes bsn-isshin-arm {
  0%, 34% { transform: rotate(-40deg); }
  48%, 100% { transform: rotate(0); }
}
/* 居合光痕 */
.bsn-isshin__beam {
  transform-box: fill-box;
  transform-origin: left center;
  opacity: 0;
  animation: bsn-isshin-beam 3.2s linear infinite;
}
@keyframes bsn-isshin-beam {
  0%, 36% { opacity: 0; transform: scaleX(0); }
  39% { opacity: 1; transform: scaleX(1); }
  52% { opacity: 0.9; }
  66%, 100% { opacity: 0; transform: scaleX(1); }
}
/* 竹靶上半截：切口滞后一拍滑落 */
.bsn-isshin__stalk-top {
  animation: bsn-isshin-stalk 3.2s cubic-bezier(0.5, 0, 0.8, 1) infinite;
}
@keyframes bsn-isshin-stalk {
  0%, 46% { transform: translate(0, 0) rotate(0); opacity: 1; }
  62% { transform: translate(16px, 8px) rotate(24deg); opacity: 1; }
  76%, 100% { transform: translate(26px, 34px) rotate(38deg); opacity: 0; }
}
/* 突进起点烟雾 */
.bsn-isshin__smoke {
  transform-box: fill-box;
  transform-origin: center;
  opacity: 0;
  animation: bsn-isshin-smoke 3.2s ease-out infinite;
}
@keyframes bsn-isshin-smoke {
  0%, 33% { opacity: 0; transform: scale(0.4); }
  38% { opacity: 0.8; }
  56%, 100% { opacity: 0; transform: scale(1.7); }
}

/* ======================= LV.55 · whirlwind（影舞·扇形三斩） ======================= */

/* 分身：烟起现身 → 同步斩 → 烟起散去（与烟雾两阵同相位） */
.bsn-bunshin__clone {
  opacity: 0;
  animation: bsn-bunshin-clone 2.6s ease-in-out infinite;
}
@keyframes bsn-bunshin-clone {
  0%, 10% { opacity: 0; }
  18%, 66% { opacity: 0.45; }
  78%, 100% { opacity: 0; }
}
/* 烟雾：每个循环两阵——分身现身（8%）与散去（68%）各一阵 */
.bsn-bunshin__smoke {
  transform-box: fill-box;
  transform-origin: center;
  opacity: 0;
  animation: bsn-bunshin-smoke 2.6s ease-out infinite;
}
@keyframes bsn-bunshin-smoke {
  0%, 6% { opacity: 0; transform: scale(0.4); }
  12% { opacity: 0.75; }
  22%, 62% { opacity: 0; transform: scale(1.8); }
  68% { opacity: 0.75; transform: scale(0.4); }
  82%, 100% { opacity: 0; transform: scale(1.8); }
}
/* 扇形三斩：分身对称上撩、本体当头直劈，蓄力同相位、同帧落刀 */
.bsn-bunshin__arm-up,
.bsn-bunshin__arm-chop {
  transform-origin: 0 0;
  animation: bsn-bunshin-arm-up 2.6s cubic-bezier(0.6, 0, 0.3, 1) infinite;
}
.bsn-bunshin__arm-chop {
  animation-name: bsn-bunshin-arm-chop;
}
@keyframes bsn-bunshin-arm-up {
  0%, 26% { transform: rotate(50deg); }
  42% { transform: rotate(-70deg); }
  56% { transform: rotate(-56deg); }
  80%, 100% { transform: rotate(50deg); }
}
@keyframes bsn-bunshin-arm-chop {
  0%, 26% { transform: rotate(-102deg); }
  42% { transform: rotate(30deg); }
  56% { transform: rotate(16deg); }
  80%, 100% { transform: rotate(-102deg); }
}
.bsn-bunshin__elbow {
  transform-origin: 0 0;
  animation: bsn-bunshin-elbow 2.6s cubic-bezier(0.6, 0, 0.3, 1) infinite;
}
@keyframes bsn-bunshin-elbow {
  0%, 26% { transform: rotate(-70deg); }
  42% { transform: rotate(-6deg); }
  56% { transform: rotate(-38deg); }
  80%, 100% { transform: rotate(-70deg); }
}
.bsn-bunshin__pitch {
  transform-origin: 0 0;
  animation: bsn-bunshin-pitch 2.6s cubic-bezier(0.6, 0, 0.3, 1) infinite;
}
@keyframes bsn-bunshin-pitch {
  0%, 26% { transform: rotate(-10deg); }
  42% { transform: rotate(13deg); }
  56% { transform: rotate(-2deg); }
  80%, 100% { transform: rotate(-10deg); }
}
/* 刀光：与肩扫同相位（26-42% 落刀），沿剑刃行进方向揭示，
   dash 长度按各弧实际弧长（上撩 110°≈77 / 直劈 135°≈94） */
.bsn-bunshin__arc {
  opacity: 0;
  stroke-dasharray: 77;
  stroke-dashoffset: 77;
  animation: bsn-bunshin-arc-up 2.6s linear infinite;
}
.bsn-bunshin__arc--chop {
  stroke-dasharray: 94;
  stroke-dashoffset: 94;
  animation-name: bsn-bunshin-arc-chop;
}
@keyframes bsn-bunshin-arc-up {
  0%, 29% { opacity: 0; stroke-dashoffset: 77; }
  32% { opacity: 0.95; }
  43% { opacity: 0.95; stroke-dashoffset: 0; }
  55%, 100% { opacity: 0; stroke-dashoffset: 0; }
}
@keyframes bsn-bunshin-arc-chop {
  0%, 29% { opacity: 0; stroke-dashoffset: 94; }
  32% { opacity: 0.95; }
  43% { opacity: 0.95; stroke-dashoffset: 0; }
  55%, 100% { opacity: 0; stroke-dashoffset: 0; }
}
/* 火花：三道斩击各自的剑尖落点，命中瞬间迸发 */
.bsn-bunshin__spark {
  opacity: 0;
  animation: bsn-bunshin-spark 2.6s linear infinite;
}
@keyframes bsn-bunshin-spark {
  0%, 40% { opacity: 0; }
  44% { opacity: 1; }
  56%, 100% { opacity: 0; }
}

/* ======================= LV.70 · flame（炎遁） ======================= */

/* 拖剑疾跑四肢沿用共享 bsn-sprint 系，此处只保留炎遁特效 */
.bsn-katon__streak {
  animation: bsn-katon-streak 0.5s linear infinite;
}
.bsn-katon__streak--2 { animation-delay: -0.25s; }
@keyframes bsn-katon-streak {
  from { transform: translateX(230px); opacity: 0; }
  25% { opacity: 0.8; }
  to { transform: translateX(-40px); opacity: 0; }
}
.bsn-katon__trail {
  animation: bsn-katon-trail 0.7s ease-out infinite;
}
@keyframes bsn-katon-trail {
  from { opacity: 1; transform: translate(0, 0) scale(1); }
  to { opacity: 0; transform: translate(-8px, -12px) scale(0.35); }
}
.bsn-katon__tongue {
  animation: bsn-katon-tongue 0.7s ease-out infinite;
}
@keyframes bsn-katon-tongue {
  from { opacity: 1; transform: translate(0, 0) scale(1); }
  to { opacity: 0; transform: translate(4px, -8px) scale(0.3); }
}

/* ======================= LV.85 · leap（天降） ======================= */

/* 坠劈：高空落下 → 砸地（回弹）→ 蹲伏 → 起身（2.6s 循环） */
.bsn-tenku__diver {
  animation: bsn-tenku-dive 2.6s cubic-bezier(0.55, 0, 0.8, 0.6) infinite;
}
@keyframes bsn-tenku-dive {
  0% { transform: translateY(-64px); }
  16% { transform: translateY(0); }
  22% { transform: translateY(4px); }
  34%, 100% { transform: translateY(0); }
}
/* 躯干：空中后仰 → 落地猛前倾 → 缓缓直起 */
.bsn-tenku__pitch {
  transform-origin: 0 0;
  animation: bsn-tenku-pitch 2.6s cubic-bezier(0.55, 0, 0.8, 0.6) infinite;
}
@keyframes bsn-tenku-pitch {
  0%, 13% { transform: rotate(-12deg); }
  20% { transform: rotate(32deg); }
  30% { transform: rotate(24deg); }
  62%, 100% { transform: rotate(4deg); }
}
/* 前腿：空中拖腿 → 落地单膝砸地 → 起身 */
.bsn-tenku__thigh-front {
  transform-origin: 0 0;
  animation: bsn-tenku-thigh-f 2.6s cubic-bezier(0.55, 0, 0.8, 0.6) infinite;
}
@keyframes bsn-tenku-thigh-f {
  0%, 13% { transform: rotate(65deg); }
  20% { transform: rotate(35deg); }
  30% { transform: rotate(40deg); }
  62%, 100% { transform: rotate(88deg); }
}
.bsn-tenku__knee-front {
  transform-origin: 0 0;
  animation: bsn-tenku-knee-f 2.6s cubic-bezier(0.55, 0, 0.8, 0.6) infinite;
}
@keyframes bsn-tenku-knee-f {
  0%, 13% { transform: rotate(55deg); }
  20% { transform: rotate(85deg); }
  30% { transform: rotate(75deg); }
  62%, 100% { transform: rotate(14deg); }
}
/* 后腿：空中后拖 → 落地深跪 */
.bsn-tenku__thigh-back {
  transform-origin: 0 0;
  animation: bsn-tenku-thigh-b 2.6s cubic-bezier(0.55, 0, 0.8, 0.6) infinite;
}
@keyframes bsn-tenku-thigh-b {
  0%, 13% { transform: rotate(118deg); }
  20% { transform: rotate(105deg); }
  30% { transform: rotate(108deg); }
  62%, 100% { transform: rotate(92deg); }
}
.bsn-tenku__knee-back {
  transform-origin: 0 0;
  animation: bsn-tenku-knee-b 2.6s cubic-bezier(0.55, 0, 0.8, 0.6) infinite;
}
@keyframes bsn-tenku-knee-b {
  0%, 13% { transform: rotate(60deg); }
  20% { transform: rotate(90deg); }
  30% { transform: rotate(80deg); }
  62%, 100% { transform: rotate(12deg); }
}
/* 持剑臂：举剑过顶 → 劈落 */
.bsn-tenku__arm-sword {
  transform-origin: 0 0;
  animation: bsn-tenku-sword 2.6s cubic-bezier(0.55, 0, 0.8, 0.6) infinite;
}
@keyframes bsn-tenku-sword {
  0%, 13% { transform: rotate(-155deg); }
  20% { transform: rotate(45deg); }
  30% { transform: rotate(38deg); }
  62%, 100% { transform: rotate(10deg); }
}
.bsn-tenku__elbow {
  transform-origin: 0 0;
  animation: bsn-tenku-elbow 2.6s cubic-bezier(0.55, 0, 0.8, 0.6) infinite;
}
@keyframes bsn-tenku-elbow {
  0%, 13% { transform: rotate(-30deg); }
  20% { transform: rotate(-5deg); }
  62%, 100% { transform: rotate(-20deg); }
}
/* 冲击波 / 墨迹 / 碎石 */
.bsn-tenku__shockwave {
  transform-box: fill-box;
  transform-origin: center;
  opacity: 0;
  animation: bsn-tenku-shockwave 2.6s ease-out infinite;
}
@keyframes bsn-tenku-shockwave {
  0%, 15% { opacity: 0; transform: scale(0.3); }
  18% { opacity: 0.9; }
  42%, 100% { opacity: 0; transform: scale(7.5); }
}
.bsn-tenku__ink {
  opacity: 0;
  animation: bsn-tenku-ink 2.6s ease-out infinite;
}
@keyframes bsn-tenku-ink {
  0%, 15% { opacity: 0; transform: scale(0.6); }
  19% { opacity: 0.95; }
  40%, 100% { opacity: 0; transform: scale(1.25); }
}
.bsn-tenku__rock {
  opacity: 0;
  animation: bsn-tenku-rock 2.6s cubic-bezier(0.3, 0, 0.7, 1) infinite;
}
.bsn-tenku__rock--2 { animation-delay: 0.03s; }
.bsn-tenku__rock--3 { animation-delay: 0.06s; }
.bsn-tenku__rock--4 { animation-delay: 0.09s; }
@keyframes bsn-tenku-rock {
  0%, 15% { opacity: 0; transform: translate(0, 0); }
  18% { opacity: 1; }
  46%, 100% { opacity: 0; transform: translate(-4px, -26px); }
}

/* ======================= LV.100 · master（残心·无形斩） ======================= */

/* 人静立不动，仅有呼吸般微起伏；斩痕在前方凭空绽开 */
.bsn-zanshin__breath {
  animation: bsn-zanshin-breath 3.2s ease-in-out infinite alternate;
}
@keyframes bsn-zanshin-breath {
  from { transform: translateY(0); }
  to { transform: translateY(-1.2px); }
}
/* 三道斩痕：\ → / → — 错峰绽开，第三刀停留更久（收势） */
.bsn-zanshin__flash {
  stroke-dasharray: 54;
  stroke-dashoffset: 54;
  opacity: 0;
  animation: bsn-zanshin-flash 3.2s linear infinite;
}
.bsn-zanshin__flash--2 { animation-name: bsn-zanshin-flash-2; }
.bsn-zanshin__flash--3 { animation-name: bsn-zanshin-flash-3; }
@keyframes bsn-zanshin-flash {
  0%, 8% { opacity: 0; stroke-dashoffset: 54; }
  10% { opacity: 1; }
  14% { opacity: 1; stroke-dashoffset: 0; }
  22%, 100% { opacity: 0; stroke-dashoffset: 0; }
}
@keyframes bsn-zanshin-flash-2 {
  0%, 24% { opacity: 0; stroke-dashoffset: 54; }
  26% { opacity: 1; }
  30% { opacity: 1; stroke-dashoffset: 0; }
  38%, 100% { opacity: 0; stroke-dashoffset: 0; }
}
@keyframes bsn-zanshin-flash-3 {
  0%, 40% { opacity: 0; stroke-dashoffset: 54; }
  42% { opacity: 1; }
  46% { opacity: 1; stroke-dashoffset: 0; }
  60%, 100% { opacity: 0; stroke-dashoffset: 0; }
}
/* 冲击波：第三刀落点荡开内外两环 */
.bsn-zanshin__shock {
  transform-box: fill-box;
  transform-origin: center;
  opacity: 0;
  animation: bsn-zanshin-shock 3.2s ease-out infinite;
}
.bsn-zanshin__shock--2 { animation-name: bsn-zanshin-shock-2; }
@keyframes bsn-zanshin-shock {
  0%, 46% { opacity: 0; transform: scale(0.3); }
  48% { opacity: 0.7; }
  66%, 100% { opacity: 0; transform: scale(2.6); }
}
@keyframes bsn-zanshin-shock-2 {
  0%, 52% { opacity: 0; transform: scale(0.3); }
  54% { opacity: 0.5; }
  72%, 100% { opacity: 0; transform: scale(2.2); }
}
/* 被斩断的落叶：第三刀落下后两半分离、旋落 */
.bsn-zanshin__leaf {
  opacity: 0;
  animation: bsn-zanshin-leaf 3.2s ease-in infinite;
}
.bsn-zanshin__leaf--2 { animation-name: bsn-zanshin-leaf-2; }
@keyframes bsn-zanshin-leaf {
  0%, 48% { opacity: 0; transform: translate(0, 0) rotate(0); }
  52% { opacity: 0.9; }
  88%, 100% { opacity: 0; transform: translate(-15px, 28px) rotate(-170deg); }
}
@keyframes bsn-zanshin-leaf-2 {
  0%, 48% { opacity: 0; transform: translate(0, 0) rotate(0); }
  52% { opacity: 0.9; }
  88%, 100% { opacity: 0; transform: translate(13px, 30px) rotate(150deg); }
}
/* 刀镡寒光：与三道斩痕同相位各闪一次，点明斩击出自大师 */
.bsn-zanshin__glint {
  opacity: 0;
  animation: bsn-zanshin-glint 3.2s linear infinite;
}
@keyframes bsn-zanshin-glint {
  0%, 7% { opacity: 0; }
  9% { opacity: 1; }
  11%, 23% { opacity: 0; }
  25% { opacity: 1; }
  27%, 39% { opacity: 0; }
  41% { opacity: 1; }
  45%, 100% { opacity: 0; }
}

/* ======================= LV.115 · ascend（万剑） ======================= */

.bsn-senbon__rays {
  transform-origin: 0 0;
  animation: bsn-senbon-rays 18s linear infinite;
}
@keyframes bsn-senbon-rays {
  from { transform: rotate(0); }
  to { transform: rotate(360deg); }
}
.bsn-senbon__orbit {
  transform-origin: 0 0;
  animation: bsn-senbon-orbit 7s linear infinite;
}
@keyframes bsn-senbon-orbit {
  from { transform: rotate(0); }
  to { transform: rotate(360deg); }
}
.bsn-senbon__levitator {
  animation: bsn-senbon-levitate 2.4s ease-in-out infinite alternate;
}
@keyframes bsn-senbon-levitate {
  from { transform: translateY(0); }
  to { transform: translateY(-5px); }
}
.bsn-senbon__mote {
  opacity: 0;
  animation: bsn-senbon-mote 3.5s ease-in infinite;
}
@keyframes bsn-senbon-mote {
  0% { opacity: 0; transform: translateY(0); }
  20% { opacity: 0.9; }
  100% { opacity: 0; transform: translateY(-58px); }
}
.bsn-senbon__star {
  transform-box: fill-box;
  transform-origin: center;
  opacity: 0.5;
  animation: bsn-senbon-twinkle 3s ease-in-out infinite;
}
.bsn-senbon__star--2 { animation-delay: -1.5s; }
@keyframes bsn-senbon-twinkle {
  0%, 100% { opacity: 0.35; transform: scale(0.85); }
  50% { opacity: 1; transform: scale(1.15); }
}

/* ======================= 时长卡"时光修行弧"（spark → mastery） =======================
   与忍者弧区分：素人玩家（无剑无围巾），道具全是"时间"。
   节奏弧光：前段手速雀跃 → 中段道具叙事 → 后段动作收束、气场递增。 */

/* ---- 共享：坐姿搓招肘部（三档手速，alt 反相 = 双手交替） ---- */
.bst-mash {
  transform-origin: 0 0;
  animation: bst-mash 0.55s ease-in-out infinite alternate;
}
.bst-mash--mid { animation-duration: 0.4s; }
.bst-mash--fast { animation-duration: 0.28s; }
.bst-mash--alt { animation-direction: alternate-reverse; }
@keyframes bst-mash {
  from { transform: rotate(-44deg); }
  to { transform: rotate(-12deg); }
}

/* ---- 共享：屏幕荧光脉动（fast 档 = 画面激烈） ---- */
.bst-glow {
  animation: bst-glow-pulse 2.2s ease-in-out infinite alternate;
}
.bst-glow--fast { animation-duration: 1.1s; }
@keyframes bst-glow-pulse {
  from { opacity: 0.12; }
  to { opacity: 0.34; }
}

/* ---- 共享：自屏幕升起的像素颗粒 ---- */
.bst-pixel {
  opacity: 0;
  animation: bst-pixel-rise 2.4s ease-in infinite;
}
.bst-pixel--2 { animation-delay: -0.7s; }
.bst-pixel--3 { animation-delay: -1.3s; }
.bst-pixel--4 { animation-delay: -1.9s; }
@keyframes bst-pixel-rise {
  0% { opacity: 0; transform: translateY(0); }
  15% { opacity: 0.9; }
  100% { opacity: 0; transform: translateY(-26px); }
}

/* ---- 3H · hooked：盘腿猛搓——身体绕髋前后摇晃 + 手速残影 ---- */
.bst-hooked__bob {
  transform-origin: 0 34px;
  animation: bst-hooked-bob 0.56s ease-in-out infinite alternate;
}
@keyframes bst-hooked-bob {
  from { transform: rotate(0deg); }
  to { transform: rotate(4deg); }
}
.bst-hooked__line {
  opacity: 0;
  animation: bst-hooked-line 0.28s linear infinite;
}
.bst-hooked__line--2 { animation-delay: -0.14s; }
@keyframes bst-hooked-line {
  0% { opacity: 0; transform: translateX(-6px); }
  40% { opacity: 0.55; }
  100% { opacity: 0; transform: translateX(5px); }
}

/* ---- 共享：星星闪烁（3 相位错峰） ---- */
.bst-twinkle {
  transform-box: fill-box;
  transform-origin: center;
  animation: bst-twinkle 3s ease-in-out infinite;
}
.bst-twinkle--2 { animation-delay: -1s; }
.bst-twinkle--3 { animation-delay: -2s; }
@keyframes bst-twinkle {
  0%, 100% { opacity: 0.3; transform: scale(0.8); }
  50% { opacity: 1; transform: scale(1.15); }
}

/* ---- 共享：呼吸起伏（后段场景各自放慢） ---- */
.bst-breath {
  animation: bst-breath 3.4s ease-in-out infinite alternate;
}
.bst-vigil__breath { animation: bst-breath 3.8s ease-in-out infinite alternate; }
.bst-century__breath { animation: bst-breath 4.6s ease-in-out infinite alternate; }
.bst-sage__breath { animation: bst-breath 5.4s ease-in-out infinite alternate; }
@keyframes bst-breath {
  from { transform: translateY(0); }
  to { transform: translateY(-1.4px); }
}

/* ---- 5H · focus：闹钟分针飞转 ---- */
.bst-clock__hand {
  transform-origin: 0 0;
  animation: bst-clock-hand 5s linear infinite;
}
@keyframes bst-clock-hand {
  from { transform: rotate(0); }
  to { transform: rotate(360deg); }
}

/* ---- 10H · daynight：日月同轨交替（月亮慢半圈） ---- */
.bst-daynight__sun,
.bst-daynight__moon {
  animation: bst-daynight-arc 12s linear infinite;
}
.bst-daynight__moon { animation-delay: -6s; }
@keyframes bst-daynight-arc {
  0% { transform: translate(-14px, 48px); opacity: 0; }
  8% { opacity: 0.9; }
  25% { transform: translate(56px, 14px); }
  50% { transform: translate(118px, 0px); opacity: 0.9; }
  75% { transform: translate(180px, 14px); }
  92% { opacity: 0.9; }
  100% { transform: translate(250px, 48px); opacity: 0; }
}

/* ---- 25H · streak：交替冲拳 + 汗珠 + 速度线 ---- */
.bst-streak__bob {
  animation: bst-streak-bob 0.3s ease-in-out infinite alternate;
}
@keyframes bst-streak-bob {
  from { transform: translateY(0); }
  to { transform: translateY(-2px); }
}
.bst-streak__punch {
  transform-origin: 0 0;
  animation: bst-streak-punch 0.3s ease-in-out infinite alternate;
}
.bst-streak__punch--alt { animation-direction: alternate-reverse; }
@keyframes bst-streak-punch {
  from { transform: rotate(-78deg); }
  to { transform: rotate(-8deg); }
}
.bst-streak__sweat {
  opacity: 0;
  animation: bst-streak-sweat 1.2s ease-out infinite;
}
@keyframes bst-streak-sweat {
  0%, 55% { opacity: 0; transform: translate(0, 0); }
  62% { opacity: 0.9; }
  100% { opacity: 0; transform: translate(10px, -14px); }
}
.bst-streak__line {
  animation: bst-streak-line 0.6s linear infinite;
}
.bst-streak__line--2 { animation-delay: -0.3s; }
@keyframes bst-streak-line {
  from { transform: translateX(16px); opacity: 0; }
  30% { opacity: 0.5; }
  to { transform: translateX(-14px); opacity: 0; }
}

/* ---- 50H · coffee：举杯小酌 + 杯口蒸汽 ---- */
.bst-coffee__sip {
  transform-origin: 0 0;
  animation: bst-coffee-sip 4.5s ease-in-out infinite;
}
@keyframes bst-coffee-sip {
  0%, 55% { transform: rotate(55deg); }
  68%, 80% { transform: rotate(14deg); }
  92%, 100% { transform: rotate(55deg); }
}
.bst-coffee__steam {
  opacity: 0;
  animation: bst-coffee-steam 2.2s ease-in infinite;
}
.bst-coffee__steam--2 { animation-delay: -1.1s; }
@keyframes bst-coffee-steam {
  0% { opacity: 0; transform: translateY(0); }
  25% { opacity: 0.75; }
  100% { opacity: 0; transform: translateY(-7px); }
}

/* ---- 100H · century：沙漏——流砂不断、上砂渐空、下砂渐积 ---- */
.bst-century__stream {
  stroke-dasharray: 3 3;
  animation: bst-century-stream 0.8s linear infinite;
}
@keyframes bst-century-stream {
  from { stroke-dashoffset: 6; }
  to { stroke-dashoffset: 0; }
}
.bst-century__top-sand {
  transform-box: fill-box;
  transform-origin: center;
  animation: bst-century-top 6s ease-in-out infinite;
}
@keyframes bst-century-top {
  0% { transform: scale(1.1); opacity: 0.65; }
  100% { transform: scale(0.55); opacity: 0.3; }
}
.bst-century__pile {
  transform-box: fill-box;
  transform-origin: center bottom;
  animation: bst-century-pile 6s ease-in-out infinite;
}
@keyframes bst-century-pile {
  0% { transform: scale(0.5); opacity: 0.4; }
  70% { transform: scale(1.1); opacity: 0.8; }
  100% { transform: scale(1.15); opacity: 0.85; }
}

/* ---- 200H · rhythm：指挥家挥棒打拍 + 节拍器恒摆（1.4s 同周期同步） ---- */
.bst-rhythm__sway {
  transform-origin: 0 0;
  animation: bst-rhythm-sway 1.4s ease-in-out infinite;
}
@keyframes bst-rhythm-sway {
  0%, 32%, 100% { transform: rotate(2deg); }
  44% { transform: rotate(-3deg); }
  62% { transform: rotate(0deg); }
}
/* 指挥臂：高举蓄势 → 下劈打拍 → 回弹 */
.bst-rhythm__arm {
  transform-origin: 0 0;
  animation: bst-rhythm-arm 1.4s ease-in-out infinite;
}
@keyframes bst-rhythm-arm {
  0%, 30%, 100% { transform: rotate(-46deg); }
  42% { transform: rotate(4deg); }
  56% { transform: rotate(-14deg); }
  72% { transform: rotate(-38deg); }
}
/* 自由臂：与指挥棒反相低扫 */
.bst-rhythm__arm-free {
  transform-origin: 0 0;
  animation: bst-rhythm-arm-free 1.4s ease-in-out infinite;
}
@keyframes bst-rhythm-arm-free {
  0%, 30%, 100% { transform: rotate(38deg); }
  42% { transform: rotate(18deg); }
  62% { transform: rotate(30deg); }
}
.bst-rhythm__pendulum {
  transform-origin: 0 0;
  animation: bst-rhythm-pendulum 0.7s ease-in-out infinite alternate;
}
@keyframes bst-rhythm-pendulum {
  from { transform: rotate(-27deg); }
  to { transform: rotate(27deg); }
}

/* ---- 300H · whetstone：验刃凝视 → 振刀下甩 → 回位（3s 循环） ---- */
.bst-whet__pitch {
  transform-origin: 0 0;
  animation: bst-whet-pitch 3s ease-in-out infinite;
}
@keyframes bst-whet-pitch {
  0%, 38%, 96%, 100% { transform: rotate(-4deg); }
  44% { transform: rotate(8deg); }
  52%, 82% { transform: rotate(3deg); }
}
/* 持刃臂：-30° 举刃于脸侧 ↔ 40° 振刀下甩 */
.bst-whet__arm-sword {
  transform-origin: 0 0;
  animation: bst-whet-arm 3s ease-in-out infinite;
}
@keyframes bst-whet-arm {
  0%, 38%, 96%, 100% { transform: rotate(-30deg); }
  44% { transform: rotate(46deg); }
  50% { transform: rotate(36deg); }
  82% { transform: rotate(40deg); }
}
.bst-whet__elbow {
  transform-origin: 0 0;
  animation: bst-whet-elbow 3s ease-in-out infinite;
}
@keyframes bst-whet-elbow {
  0%, 38%, 96%, 100% { transform: rotate(-50deg); }
  44% { transform: rotate(40deg); }
  50% { transform: rotate(30deg); }
  82% { transform: rotate(35deg); }
}
/* 扶刃臂：验刃时托住刀身，振刀前收回体侧 */
.bst-whet__arm-support {
  transform-origin: 0 0;
  animation: bst-whet-support 3s ease-in-out infinite;
}
@keyframes bst-whet-support {
  0%, 36%, 96%, 100% { transform: rotate(28deg); }
  42%, 88% { transform: rotate(72deg); }
}
/* 振刀寒光：下甩瞬间刃尖星芒闪现 */
.bst-whet__spark {
  opacity: 0;
  animation: bst-whet-spark 3s ease-out infinite;
}
.bst-whet__spark--2 { animation-delay: 0.04s; }
.bst-whet__spark--3 { animation-delay: 0.08s; }
@keyframes bst-whet-spark {
  0%, 42% { opacity: 0; transform: translate(0, 0); }
  46% { opacity: 1; }
  58%, 100% { opacity: 0; transform: translate(6px, 5px); }
}

/* ---- 500H · vigil：篝火双色火舌 + 余烬上升 ---- */
.bst-vigil__flame {
  transform-box: fill-box;
  transform-origin: center bottom;
  animation: bst-vigil-flame 0.5s ease-in-out infinite alternate;
}
.bst-vigil__flame--2 {
  animation-duration: 0.38s;
  animation-delay: -0.15s;
}
@keyframes bst-vigil-flame {
  from { transform: scaleY(0.82) scaleX(1.05); }
  to { transform: scaleY(1.12) scaleX(0.94); }
}
.bst-vigil__ember {
  opacity: 0;
  animation: bst-vigil-ember 2.6s ease-in infinite;
}
.bst-vigil__ember--2 { animation-delay: -0.9s; }
.bst-vigil__ember--3 { animation-delay: -1.7s; }
@keyframes bst-vigil-ember {
  0% { opacity: 0; transform: translate(0, 0); }
  18% { opacity: 0.9; }
  100% { opacity: 0; transform: translate(-3px, -22px); }
}

/* ---- 750H · echo：往昔残影错峰浮现 ---- */
.bst-echo__ghost {
  opacity: 0;
  animation: bst-echo-ghost 8s ease-in-out infinite;
}
.bst-echo__ghost--2 { animation-delay: -4s; }
@keyframes bst-echo-ghost {
  0%, 100% { opacity: 0; }
  35%, 65% { opacity: 0.3; }
}

/* ---- 1000H · vortex：时钟刻度环行 + 气场扩散 + 微粒升腾 ---- */
.bst-vortex__ring {
  transform-origin: 0 0;
  animation: bst-vortex-ring 16s linear infinite;
}
@keyframes bst-vortex-ring {
  from { transform: rotate(0); }
  to { transform: rotate(360deg); }
}
.bst-vortex__aura {
  transform-box: fill-box;
  transform-origin: center;
  opacity: 0;
  animation: bst-vortex-aura 3.6s ease-out infinite;
}
@keyframes bst-vortex-aura {
  0% { opacity: 0.35; transform: scale(0.5); }
  100% { opacity: 0; transform: scale(2.6); }
}
.bst-vortex__mote {
  opacity: 0;
  animation: bst-vortex-mote 4s ease-in infinite;
}
.bst-vortex__mote--2 { animation-delay: -1s; }
.bst-vortex__mote--3 { animation-delay: -2s; }
.bst-vortex__mote--4 { animation-delay: -3s; }
@keyframes bst-vortex-mote {
  0% { opacity: 0; transform: translate(0, 0); }
  20% { opacity: 0.85; }
  100% { opacity: 0; transform: translate(-10px, -56px); }
}

/* ---- 2000H · sage：双重气场环 + 落叶 ---- */
.bst-sage__aura {
  transform-box: fill-box;
  transform-origin: center;
  opacity: 0;
  animation: bst-sage-aura 4.5s ease-out infinite;
}
.bst-sage__aura--2 { animation-delay: -2.25s; }
@keyframes bst-sage-aura {
  0% { opacity: 0.4; transform: scale(0.55); }
  100% { opacity: 0; transform: scale(2.4); }
}
.bst-sage__leaf {
  opacity: 0;
  animation: bst-sage-leaf 7s ease-in-out infinite;
}
.bst-sage__leaf--2 { animation-delay: -3.5s; }
@keyframes bst-sage-leaf {
  0% { opacity: 0; transform: translate(0, 0) rotate(0); }
  18% { opacity: 0.8; }
  80% { opacity: 0.8; }
  100% { opacity: 0; transform: translate(-20px, 34px) rotate(-48deg); }
}

/* ---- 5000H · titan：神性光轮 + 环行三星 + 铭文呼吸 ---- */
.bst-titan__rays {
  transform-origin: 0 0;
  animation: bst-titan-rays 40s linear infinite;
}
@keyframes bst-titan-rays {
  from { transform: rotate(0); }
  to { transform: rotate(360deg); }
}
.bst-titan__orbit {
  transform-origin: 0 0;
  animation: bst-titan-orbit 16s linear infinite;
}
@keyframes bst-titan-orbit {
  from { transform: rotate(0); }
  to { transform: rotate(360deg); }
}
.bst-titan__engrave {
  stroke-dasharray: 4 3;
  animation: bst-titan-engrave 3s ease-in-out infinite alternate;
}
@keyframes bst-titan-engrave {
  from { opacity: 0.3; }
  to { opacity: 0.65; }
}

/* ---- 10000H · mastery：光轮 + 逆向时钟光环 + 五星环绕 + 星尘 + 悬浮 ---- */
.bst-mastery__rays {
  transform-origin: 0 0;
  animation: bst-mastery-rays 20s linear infinite;
}
@keyframes bst-mastery-rays {
  from { transform: rotate(0); }
  to { transform: rotate(360deg); }
}
.bst-mastery__halo {
  transform-origin: 0 0;
  animation: bst-mastery-halo 26s linear infinite;
}
@keyframes bst-mastery-halo {
  from { transform: rotate(360deg); }
  to { transform: rotate(0); }
}
.bst-mastery__orbit {
  transform-origin: 0 0;
  animation: bst-mastery-orbit 8s linear infinite;
}
@keyframes bst-mastery-orbit {
  from { transform: rotate(0); }
  to { transform: rotate(360deg); }
}
.bst-mastery__mote {
  opacity: 0;
  animation: bst-mastery-mote 3.5s ease-in infinite;
}
.bst-mastery__mote--2 { animation-delay: -1s; }
.bst-mastery__mote--3 { animation-delay: -2s; }
.bst-mastery__mote--4 { animation-delay: -2.6s; }
@keyframes bst-mastery-mote {
  0% { opacity: 0; transform: translateY(0); }
  20% { opacity: 0.9; }
  100% { opacity: 0; transform: translateY(-56px); }
}
.bst-mastery__levitate {
  animation: bst-mastery-levitate 2.4s ease-in-out infinite alternate;
}
@keyframes bst-mastery-levitate {
  from { transform: translateY(0); }
  to { transform: translateY(-5px); }
}

/* ======================= 局数卡"阅历老练弧" ======================= */
/* 道具是游戏元素（卡带/手柄/街机币），动作从"用力"走向"毫不费力"。
   循环无缝（0% = 100%），浮空道具反向自转保持正立。 */

/* ======================= 20 局 · loot（战利品） ======================= */

.bsn-loot__body {
  animation: bsn-loot-bob 1.6s ease-in-out infinite alternate;
}
@keyframes bsn-loot-bob {
  from { transform: translateY(0); }
  to { transform: translateY(-1.5px); }
}
/* 高举臂：小幅上举脉动（展示战利品） */
.bsn-loot__arm {
  transform-origin: 0 0;
  animation: bsn-loot-raise 1.6s ease-in-out infinite alternate;
}
@keyframes bsn-loot-raise {
  from { transform: rotate(-5deg); }
  to { transform: rotate(4deg); }
}
.bsn-loot__star {
  transform-box: fill-box;
  transform-origin: center;
  opacity: 0.5;
  animation: bsn-loot-twinkle 2.4s ease-in-out infinite;
}
.bsn-loot__star--2 { animation-delay: -1.2s; }
@keyframes bsn-loot-twinkle {
  0%, 100% { opacity: 0.35; transform: scale(0.8); }
  50% { opacity: 1; transform: scale(1.2); }
}

/* ======================= 50 局 · toss（抛接） ======================= */

/* 手柄：下沉蓄势 → 抛起翻转 360° → 落回掌心（90% 后落定一拍） */
.bsn-toss__prop {
  transform-box: fill-box;
  transform-origin: center;
  animation: bsn-toss-flip 1.6s cubic-bezier(0.45, 0, 0.55, 1) infinite;
}
@keyframes bsn-toss-flip {
  0% { transform: translateY(0) rotate(0); }
  10% { transform: translateY(2px) rotate(0); }
  50% { transform: translateY(-18px) rotate(-180deg); }
  90%, 100% { transform: translateY(0) rotate(-360deg); }
}
/* 抛接臂：随抛接小幅起落 */
.bsn-toss__arm {
  transform-origin: 0 0;
  animation: bsn-toss-arm 1.6s cubic-bezier(0.45, 0, 0.55, 1) infinite;
}
@keyframes bsn-toss-arm {
  0% { transform: rotate(0); }
  10% { transform: rotate(-8deg); }
  50% { transform: rotate(5deg); }
  90%, 100% { transform: rotate(0); }
}
.bsn-toss__body {
  animation: bsn-toss-bob 1.6s ease-in-out infinite;
}
@keyframes bsn-toss-bob {
  0%, 100% { transform: translateY(0); }
  10% { transform: translateY(1.5px); }
  50% { transform: translateY(-1px); }
  90% { transform: translateY(0); }
}

/* ======================= 80 局 · juggle（杂耍） ======================= */

/* 横向穿梭与纵向抛接同相合成：一趟两跳的杂耍弧线 */
.bsn-juggle__lane {
  animation: bsn-juggle-x 1.2s ease-in-out infinite alternate;
}
@keyframes bsn-juggle-x {
  from { transform: translateX(0); }
  to { transform: translateX(48px); }
}
.bsn-juggle__prop {
  transform-box: fill-box;
  transform-origin: center;
  animation: bsn-juggle-y 0.6s ease-in-out infinite alternate;
}
@keyframes bsn-juggle-y {
  from { transform: translateY(0) rotate(-10deg); }
  to { transform: translateY(-24px) rotate(10deg); }
}
/* 身体随手感轻微摇摆 */
.bsn-juggle__sway {
  transform-origin: 0 0;
  animation: bsn-juggle-sway 1.2s ease-in-out infinite alternate;
}
@keyframes bsn-juggle-sway {
  from { transform: rotate(-3deg); }
  to { transform: rotate(3deg); }
}

/* ======================= 110 局 · dummy（木人桩） ======================= */

/* 左右直冲拳：0.6s 一循环，右拳错半拍；收拳于腰、出拳即直 */
.bsn-dummy__arm-1,
.bsn-dummy__arm-2 {
  transform-origin: 0 0;
  animation: bsn-dummy-punch 0.6s cubic-bezier(0.6, 0, 0.3, 1) infinite;
}
.bsn-dummy__arm-2 { animation-delay: 0.3s; }
@keyframes bsn-dummy-punch {
  0% { transform: rotate(42deg); }
  15% { transform: rotate(-2deg); }
  30% { transform: rotate(-2deg); }
  55%, 100% { transform: rotate(42deg); }
}
.bsn-dummy__elbow-1,
.bsn-dummy__elbow-2 {
  transform-origin: 0 0;
  animation: bsn-dummy-elbow 0.6s cubic-bezier(0.6, 0, 0.3, 1) infinite;
}
.bsn-dummy__elbow-2 { animation-delay: 0.3s; }
@keyframes bsn-dummy-elbow {
  0% { transform: rotate(-108deg); }
  15% { transform: rotate(-6deg); }
  30% { transform: rotate(-6deg); }
  55%, 100% { transform: rotate(-108deg); }
}
/* 躯干随拳小幅拧转 */
.bsn-dummy__pitch {
  transform-origin: 0 0;
  animation: bsn-dummy-pitch 0.3s ease-in-out infinite alternate;
}
@keyframes bsn-dummy-pitch {
  from { transform: rotate(8deg); }
  to { transform: rotate(14deg); }
}
/* 触点拳劲：与两拳命中相位（15% / 65%）同步的两次闪现 */
.bsn-dummy__impact {
  transform-box: fill-box;
  transform-origin: center;
  opacity: 0;
  animation: bsn-dummy-impact 0.6s linear infinite;
}
@keyframes bsn-dummy-impact {
  0%, 13% { opacity: 0; transform: scale(0.7); }
  15% { opacity: 1; }
  22% { opacity: 0; transform: scale(1.15); }
  63% { opacity: 0; transform: scale(0.7); }
  65% { opacity: 1; }
  72%, 100% { opacity: 0; transform: scale(1.15); }
}
/* 木人桩：命中瞬间轻颤 */
.bsn-dummy__shake {
  animation: bsn-dummy-shake 0.6s linear infinite;
}
@keyframes bsn-dummy-shake {
  0%, 13% { transform: translateX(0); }
  16% { transform: translateX(1.5px); }
  22% { transform: translateX(0); }
  63% { transform: translateX(0); }
  66% { transform: translateX(1.5px); }
  72%, 100% { transform: translateX(0); }
}

/* ======================= 140 局 · coin（转币） ======================= */

/* 币在指尖飞转：侧视旋转 = 快速压扁回弹 + 微幅晃动 */
.bsn-coin__token {
  transform-box: fill-box;
  transform-origin: center;
  animation: bsn-coin-spin 0.36s ease-in-out infinite alternate;
}
@keyframes bsn-coin-spin {
  from { transform: translateY(0) rotate(-8deg) scaleX(1); }
  to { transform: translateY(-0.6px) rotate(8deg) scaleX(0.18); }
}
.bsn-coin__body {
  animation: bsn-coin-bob 2.2s ease-in-out infinite alternate;
}
@keyframes bsn-coin-bob {
  from { transform: translateY(0); }
  to { transform: translateY(-1.2px); }
}

/* ======================= 170 局 · brush（泼墨） ======================= */

/* 泼墨一笔：随挥笔自绘（dash）→ 驻足 → 墨干隐去 → 复位 */
.bsn-brush__ink {
  stroke-dasharray: 80;
  stroke-dashoffset: 80;
  animation: bsn-brush-ink 3s linear infinite;
}
@keyframes bsn-brush-ink {
  0%, 14% { stroke-dashoffset: 80; opacity: 1; }
  52% { stroke-dashoffset: 0; opacity: 1; }
  80% { stroke-dashoffset: 0; opacity: 1; }
  92% { stroke-dashoffset: 0; opacity: 0; }
  93% { stroke-dashoffset: 80; opacity: 0; }
  94%, 100% { stroke-dashoffset: 80; opacity: 1; }
}
/* 墨点：落笔瞬间飞溅 */
.bsn-brush__drop {
  transform-box: fill-box;
  transform-origin: center;
  opacity: 0;
  animation: bsn-brush-drop 3s ease-out infinite;
}
.bsn-brush__drop--2 { animation-delay: 0.05s; }
.bsn-brush__drop--3 { animation-delay: 0.1s; }
@keyframes bsn-brush-drop {
  0%, 50% { opacity: 0; transform: scale(0.4); }
  55% { opacity: 1; transform: scale(1.2); }
  80%, 100% { opacity: 0; transform: scale(0.7); }
}
/* 挥毫臂：大风车蓄力 → 一笔劈下 → 收笔回势（与墨迹同步） */
.bsn-brush__arm {
  transform-origin: 0 0;
  animation: bsn-brush-arm 3s cubic-bezier(0.6, 0, 0.3, 1) infinite;
}
@keyframes bsn-brush-arm {
  0%, 12% { transform: rotate(-75deg); }
  52% { transform: rotate(50deg); }
  64% { transform: rotate(50deg); }
  86%, 100% { transform: rotate(-75deg); }
}
.bsn-brush__elbow {
  transform-origin: 0 0;
  animation: bsn-brush-elbow 3s cubic-bezier(0.6, 0, 0.3, 1) infinite;
}
@keyframes bsn-brush-elbow {
  0%, 12% { transform: rotate(-50deg); }
  52% { transform: rotate(-5deg); }
  64% { transform: rotate(-5deg); }
  86%, 100% { transform: rotate(-50deg); }
}
/* 躯干：蓄力后仰 → 落笔前倾 */
.bsn-brush__pitch {
  transform-origin: 0 0;
  animation: bsn-brush-pitch 3s cubic-bezier(0.6, 0, 0.3, 1) infinite;
}
@keyframes bsn-brush-pitch {
  0%, 12% { transform: rotate(-10deg); }
  52% { transform: rotate(16deg); }
  64% { transform: rotate(16deg); }
  86%, 100% { transform: rotate(-10deg); }
}
/* 平衡臂：随挥笔向后甩开 */
.bsn-brush__arm-free {
  transform-origin: 0 0;
  animation: bsn-brush-arm-free 3s cubic-bezier(0.6, 0, 0.3, 1) infinite;
}
@keyframes bsn-brush-arm-free {
  0%, 12% { transform: rotate(30deg); }
  52% { transform: rotate(110deg); }
  64% { transform: rotate(110deg); }
  86%, 100% { transform: rotate(30deg); }
}

/* ======================= 200 局 · flow（云手） ======================= */

/* 道具环随手流转，道具反向自转保持正立 */
.bsn-flow__orbit {
  transform-origin: 0 0;
  animation: bsn-flow-orbit 6s linear infinite;
}
@keyframes bsn-flow-orbit {
  from { transform: rotate(0); }
  to { transform: rotate(360deg); }
}
.bsn-flow__prop {
  transform-origin: 0 0;
  animation: bsn-flow-prop 6s linear infinite;
}
@keyframes bsn-flow-prop {
  from { transform: rotate(0); }
  to { transform: rotate(-360deg); }
}
/* 云手：双臂缓慢交替 */
.bsn-flow__arm-1,
.bsn-flow__arm-2 {
  transform-origin: 0 0;
  animation: bsn-flow-arm 2.4s ease-in-out infinite alternate;
}
.bsn-flow__arm-2 { animation-direction: alternate-reverse; }
@keyframes bsn-flow-arm {
  from { transform: rotate(-42deg); }
  to { transform: rotate(18deg); }
}

/* ======================= 230 局 · orbit（环行） ======================= */

.bsn-orbit__ring {
  transform-origin: 0 0;
  animation: bsn-orbit-ring 9s linear infinite;
}
@keyframes bsn-orbit-ring {
  from { transform: rotate(0); }
  to { transform: rotate(360deg); }
}
.bsn-orbit__prop {
  transform-origin: 0 0;
  animation: bsn-orbit-prop 9s linear infinite;
}
@keyframes bsn-orbit-prop {
  from { transform: rotate(0); }
  to { transform: rotate(-360deg); }
}
.bsn-orbit__levitator {
  animation: bsn-orbit-levitate 2.6s ease-in-out infinite alternate;
}
@keyframes bsn-orbit-levitate {
  from { transform: translateY(0); }
  to { transform: translateY(-5px); }
}
.bsn-orbit__aura {
  transform-box: fill-box;
  transform-origin: center;
  opacity: 0;
  animation: bsn-orbit-aura 3.6s ease-out infinite;
}
@keyframes bsn-orbit-aura {
  0% { opacity: 0.45; transform: scale(0.6); }
  100% { opacity: 0; transform: scale(2.6); }
}

/* ======================= 260 局 · multi（千手） ======================= */

/* 残影臂：高速点按抖动（相位错开） */
.bsn-multi__ghost {
  transform-origin: 0 0;
  animation: bsn-multi-mash 0.22s ease-in-out infinite alternate;
}
@keyframes bsn-multi-mash {
  from { transform: rotate(-4deg); }
  to { transform: rotate(5deg); }
}
.bsn-multi__breath {
  animation: bsn-multi-breath 3s ease-in-out infinite alternate;
}
@keyframes bsn-multi-breath {
  from { transform: translateY(0); }
  to { transform: translateY(-1.2px); }
}

/* ======================= 300 局 · archive（典藏） ======================= */

/* 流光：缓慢扫过满墙卡带 */
.bsn-archive__shimmer {
  opacity: 0;
  animation: bsn-archive-shimmer 4.5s ease-in-out infinite;
}
@keyframes bsn-archive-shimmer {
  0% { opacity: 0; transform: translateX(30px); }
  15% { opacity: 0.3; }
  85% { opacity: 0.3; }
  100% { opacity: 0; transform: translateX(210px); }
}
/* 金色微尘 */
.bsn-archive__mote {
  opacity: 0;
  animation: bsn-archive-mote 3.5s ease-in infinite;
}
@keyframes bsn-archive-mote {
  0% { opacity: 0; transform: translateY(0); }
  20% { opacity: 0.9; }
  100% { opacity: 0; transform: translateY(-56px); }
}
.bsn-archive__breath {
  animation: bsn-archive-breath 3.2s ease-in-out infinite alternate;
}
@keyframes bsn-archive-breath {
  from { transform: translateY(0); }
  to { transform: translateY(-1.2px); }
}

/* ======================= 排行榜卡 · 登顶弧 ======================= */

/* 庆祝彩带：纸屑从顶端飘落，横向微摆，延迟由场景内联注入 */
.bsr-confetti {
  opacity: 0;
  animation: bsr-confetti-fall 2.6s linear infinite;
}
@keyframes bsr-confetti-fall {
  0% { transform: translate(0, -8px); opacity: 0; }
  12% { opacity: 0.9; }
  82% { opacity: 0.7; }
  100% { transform: translate(-4px, 82px); opacity: 0; }
}

/* ---------- Top 100 · ranked（上榜）：向上攀撑 ---------- */
.bsr-ranked__body {
  animation: bsr-ranked-push 0.9s ease-in-out infinite alternate;
}
@keyframes bsr-ranked-push {
  from { transform: translateY(1px); }
  to { transform: translateY(-2.5px); }
}
.bsr-ranked__pitch {
  transform-origin: 0 0;
  animation: bsr-ranked-pitch 0.9s ease-in-out infinite alternate;
}
@keyframes bsr-ranked-pitch {
  from { transform: rotate(0deg); }
  to { transform: rotate(-6deg); }
}

/* ---------- Top 50 · climber（上半区）：原地大跨步登阶 ---------- */
.bsr-climber__body {
  animation: bsr-climber-bob 0.7s ease-in-out infinite alternate;
}
@keyframes bsr-climber-bob {
  from { transform: translateY(0); }
  to { transform: translateY(-2px); }
}
.bsr-climber__pitch {
  transform-origin: 0 0;
  animation: bsr-climber-pitch 0.7s ease-in-out infinite alternate;
}
@keyframes bsr-climber-pitch {
  from { transform: rotate(0deg); }
  to { transform: rotate(5deg); }
}
/* 高抬腿登步：幅度比走路大，前后腿反相 */
.bsr-climber__thigh-front,
.bsr-climber__thigh-back {
  transform-origin: 0 0;
  animation: bsr-climber-thigh 0.7s ease-in-out infinite alternate;
}
.bsr-climber__thigh-back {
  animation-direction: alternate-reverse;
}
@keyframes bsr-climber-thigh {
  from { transform: rotate(58deg); }
  to { transform: rotate(118deg); }
}
.bsr-climber__knee-front,
.bsr-climber__knee-back {
  transform-origin: 0 0;
  animation: bsr-climber-knee 0.7s ease-in-out infinite alternate;
}
.bsr-climber__knee-back {
  animation-direction: alternate-reverse;
}
@keyframes bsr-climber-knee {
  from { transform: rotate(10deg); }
  to { transform: rotate(52deg); }
}
.bsr-climber__arm-front,
.bsr-climber__arm-back {
  transform-origin: 0 0;
  animation: bsr-climber-swing 0.7s ease-in-out infinite alternate;
}
.bsr-climber__arm-back {
  animation-direction: alternate-reverse;
}
@keyframes bsr-climber-swing {
  from { transform: rotate(72deg); }
  to { transform: rotate(108deg); }
}

/* ---------- Top 10 · elite（精英圈）：蓄力 → 腾空 → 落地 ---------- */
.bsr-elite__body {
  animation: bsr-elite-jump 1.8s ease-in-out infinite;
}
@keyframes bsr-elite-jump {
  0%, 100% { transform: translateY(0); }
  12% { transform: translateY(2.5px); }
  42%, 62% { transform: translateY(-9px); }
  78% { transform: translateY(0); }
  88% { transform: translateY(1.5px); }
}
.bsr-elite__pitch {
  transform-origin: 0 0;
  animation: bsr-elite-pitch 1.8s ease-in-out infinite;
}
@keyframes bsr-elite-pitch {
  0%, 100% { transform: rotate(0deg); }
  12% { transform: rotate(16deg); }
  42%, 62% { transform: rotate(-12deg); }
  78% { transform: rotate(8deg); }
}
.bsr-elite__thigh-front {
  transform-origin: 0 0;
  animation: bsr-elite-thigh-f 1.8s ease-in-out infinite;
}
@keyframes bsr-elite-thigh-f {
  0%, 100% { transform: rotate(88deg); }
  12% { transform: rotate(60deg); }
  42%, 62% { transform: rotate(52deg); }
  78% { transform: rotate(84deg); }
}
.bsr-elite__thigh-back {
  transform-origin: 0 0;
  animation: bsr-elite-thigh-b 1.8s ease-in-out infinite;
}
@keyframes bsr-elite-thigh-b {
  0%, 100% { transform: rotate(96deg); }
  12% { transform: rotate(118deg); }
  42%, 62% { transform: rotate(130deg); }
  78% { transform: rotate(100deg); }
}
.bsr-elite__knee-front {
  transform-origin: 0 0;
  animation: bsr-elite-knee-f 1.8s ease-in-out infinite;
}
@keyframes bsr-elite-knee-f {
  0%, 100% { transform: rotate(15deg); }
  12% { transform: rotate(70deg); }
  42%, 62% { transform: rotate(85deg); }
  78% { transform: rotate(20deg); }
}
.bsr-elite__knee-back {
  transform-origin: 0 0;
  animation: bsr-elite-knee-b 1.8s ease-in-out infinite;
}
@keyframes bsr-elite-knee-b {
  0%, 100% { transform: rotate(20deg); }
  12% { transform: rotate(60deg); }
  42%, 62% { transform: rotate(95deg); }
  78% { transform: rotate(28deg); }
}
/* 摆臂：蓄力后摆 → 腾空前挥 */
.bsr-elite__arm {
  transform-origin: 0 0;
  animation: bsr-elite-arm 1.8s ease-in-out infinite;
}
@keyframes bsr-elite-arm {
  0%, 100% { transform: rotate(70deg); }
  12% { transform: rotate(95deg); }
  42%, 62% { transform: rotate(-40deg); }
  78% { transform: rotate(60deg); }
}
/* 速度线只在腾空段显形 */
.bsr-elite__streak {
  opacity: 0;
  animation: bsr-elite-streak 1.8s ease-in-out infinite;
}
.bsr-elite__streak--2 {
  animation-delay: 0.06s;
}
@keyframes bsr-elite-streak {
  0%, 32%, 76%, 100% { opacity: 0; }
  44%, 62% { opacity: 0.8; }
}

/* ---------- Top 3 · podium（领奖台）：立正 → 深蹲蓄力 → 弹起秀肌肉 ---------- */
/* 循环 2.8s：0-22% 立正 → 30% 深蹲 → 42% 弹起定格 → 50-82% 展示脉冲 → 92% 收势 */
.bsr-podium__body {
  animation: bsr-podium-hop 2.8s ease-in-out infinite;
}
@keyframes bsr-podium-hop {
  0%, 22%, 48%, 66%, 82%, 100% { transform: translateY(0); }
  30% { transform: translateY(3px); }
  40% { transform: translateY(-3.5px); }
  58%, 74% { transform: translateY(-1.5px); }
}
.bsr-podium__pitch {
  transform-origin: 0 0;
  animation: bsr-podium-pitch 2.8s ease-in-out infinite;
}
@keyframes bsr-podium-pitch {
  0%, 22%, 92%, 100% { transform: rotate(0deg); }
  30% { transform: rotate(4deg); }
  42% { transform: rotate(-8deg); }
  48%, 66%, 82% { transform: rotate(-4deg); }
  58%, 74% { transform: rotate(-6deg); }
}
.bsr-podium__arm-right {
  transform-origin: 0 0;
  animation: bsr-podium-arm-r 2.8s ease-in-out infinite;
}
@keyframes bsr-podium-arm-r {
  0%, 22%, 92%, 100% { transform: rotate(78deg); }
  30% { transform: rotate(88deg); }
  42% { transform: rotate(-14deg); }
  48%, 66%, 82% { transform: rotate(-4deg); }
  58%, 74% { transform: rotate(-8deg); }
}
.bsr-podium__arm-left {
  transform-origin: 0 0;
  animation: bsr-podium-arm-l 2.8s ease-in-out infinite;
}
@keyframes bsr-podium-arm-l {
  0%, 22%, 92%, 100% { transform: rotate(102deg); }
  30% { transform: rotate(92deg); }
  42% { transform: rotate(194deg); }
  48%, 66%, 82% { transform: rotate(184deg); }
  58%, 74% { transform: rotate(188deg); }
}
.bsr-podium__elbow-right {
  transform-origin: 0 0;
  animation: bsr-podium-elbow-r 2.8s ease-in-out infinite;
}
@keyframes bsr-podium-elbow-r {
  0%, 22%, 92%, 100% { transform: rotate(-10deg); }
  30% { transform: rotate(-18deg); }
  42% { transform: rotate(-72deg); }
  48%, 66%, 82% { transform: rotate(-80deg); }
  58%, 74% { transform: rotate(-76deg); }
}
.bsr-podium__elbow-left {
  transform-origin: 0 0;
  animation: bsr-podium-elbow-l 2.8s ease-in-out infinite;
}
@keyframes bsr-podium-elbow-l {
  0%, 22%, 92%, 100% { transform: rotate(10deg); }
  30% { transform: rotate(18deg); }
  42% { transform: rotate(72deg); }
  48%, 66%, 82% { transform: rotate(80deg); }
  58%, 74% { transform: rotate(76deg); }
}
.bsr-podium__knee {
  transform-origin: 0 0;
  animation: bsr-podium-knee 2.8s ease-in-out infinite;
}
@keyframes bsr-podium-knee {
  0%, 22%, 48%, 100% { transform: rotate(6deg); }
  30% { transform: rotate(38deg); }
  40% { transform: rotate(2deg); }
}
/* 力量爆发线：定格展示期间在双拳旁闪烁 */
.bsr-podium__burst {
  opacity: 0;
  animation: bsr-podium-burst 2.8s ease-in-out infinite;
}
@keyframes bsr-podium-burst {
  0%, 40%, 86%, 100% { opacity: 0; }
  44% { opacity: 1; }
  54%, 66% { opacity: 0.3; }
  58%, 74% { opacity: 0.9; }
}

/* ---------- #1 · champion（冠军）：立正 → 拧身后仰指天定格 ---------- */
/* 循环 3.2s：0-25% 立正 → 32% 蓄力下沉 → 44% 过冲定格 → 54-85% 名场面保持 → 收势 */
.bsr-champion__body {
  animation: bsr-champion-breathe 3.2s ease-in-out infinite;
}
@keyframes bsr-champion-breathe {
  0%, 25%, 54%, 100% { transform: translateY(0); }
  32% { transform: translateY(2.5px); }
  44% { transform: translateY(-2.5px); }
}
.bsr-champion__pitch {
  transform-origin: 0 0;
  animation: bsr-champion-pitch 3.2s ease-in-out infinite;
}
@keyframes bsr-champion-pitch {
  0%, 25%, 100% { transform: rotate(0deg); }
  32% { transform: rotate(5deg); }
  44% { transform: rotate(-20deg); }
  54%, 85% { transform: rotate(-16deg); }
  70% { transform: rotate(-18deg); }
}
.bsr-champion__thigh-back {
  transform-origin: 0 0;
  animation: bsr-champion-thigh-b 3.2s ease-in-out infinite;
}
@keyframes bsr-champion-thigh-b {
  0%, 25%, 100% { transform: rotate(92deg); }
  32% { transform: rotate(96deg); }
  44% { transform: rotate(112deg); }
  54%, 85% { transform: rotate(108deg); }
  70% { transform: rotate(109deg); }
}
.bsr-champion__thigh-front {
  transform-origin: 0 0;
  animation: bsr-champion-thigh-f 3.2s ease-in-out infinite;
}
@keyframes bsr-champion-thigh-f {
  0%, 25%, 100% { transform: rotate(89deg); }
  32% { transform: rotate(94deg); }
  44% { transform: rotate(68deg); }
  54%, 85% { transform: rotate(72deg); }
  70% { transform: rotate(71deg); }
}
.bsr-champion__arm-chest {
  transform-origin: 0 0;
  animation: bsr-champion-arm-c 3.2s ease-in-out infinite;
}
@keyframes bsr-champion-arm-c {
  0%, 25%, 100% { transform: rotate(88deg); }
  32% { transform: rotate(96deg); }
  44% { transform: rotate(52deg); }
  54%, 85% { transform: rotate(58deg); }
  70% { transform: rotate(55deg); }
}
.bsr-champion__arm-point {
  transform-origin: 0 0;
  animation: bsr-champion-arm-p 3.2s ease-in-out infinite;
}
@keyframes bsr-champion-arm-p {
  0%, 25%, 100% { transform: rotate(92deg); }
  32% { transform: rotate(100deg); }
  44% { transform: rotate(-28deg); }
  54%, 85% { transform: rotate(-22deg); }
  70% { transform: rotate(-24deg); }
}
.bsr-champion__star {
  opacity: 0.4;
  animation: bsr-champion-twinkle 2.2s ease-in-out infinite;
}
.bsr-champion__star--2 {
  animation-delay: 1.1s;
}
@keyframes bsr-champion-twinkle {
  0%, 100% { opacity: 0.3; }
  50% { opacity: 1; }
}

/* ======================= 500 局 · universe（星域） ======================= */

/* 内环顺时针、外环逆时针，道具均反向自转保持正立 */
.bsn-universe__ring-in {
  transform-origin: 0 0;
  animation: bsn-universe-in 7s linear infinite;
}
@keyframes bsn-universe-in {
  from { transform: rotate(0); }
  to { transform: rotate(360deg); }
}
.bsn-universe__prop-in {
  transform-origin: 0 0;
  animation: bsn-universe-in-prop 7s linear infinite;
}
@keyframes bsn-universe-in-prop {
  from { transform: rotate(0); }
  to { transform: rotate(-360deg); }
}
.bsn-universe__ring-out {
  transform-origin: 0 0;
  animation: bsn-universe-out 13s linear infinite;
}
@keyframes bsn-universe-out {
  from { transform: rotate(0); }
  to { transform: rotate(-360deg); }
}
.bsn-universe__prop-out {
  transform-origin: 0 0;
  animation: bsn-universe-out-prop 13s linear infinite;
}
@keyframes bsn-universe-out-prop {
  from { transform: rotate(0); }
  to { transform: rotate(360deg); }
}
.bsn-universe__mote {
  opacity: 0;
  animation: bsn-universe-mote 3.5s ease-in infinite;
}
@keyframes bsn-universe-mote {
  0% { opacity: 0; transform: translateY(0); }
  20% { opacity: 0.8; }
  100% { opacity: 0; transform: translateY(-56px); }
}
.bsn-universe__breath {
  animation: bsn-universe-breath 3.2s ease-in-out infinite alternate;
}
@keyframes bsn-universe-breath {
  from { transform: translateY(0); }
  to { transform: translateY(-1.2px); }
}

/* 减少动态偏好：停掉 CSS 动画（SMIL 沸腾滤镜不在此列，属测试场景可接受） */
@media (prefers-reduced-motion: reduce) {
  .boil-stage * {
    animation: none !important;
  }
}
