/* ============================================================
   animations.css · 动效库（依赖 tokens.css）
   分三类：① 常驻氛围（flow / pulse / scan）
          ② 数据变化（dataIn / countUp / blink）
          ③ 入场（fadeInUp / slideInRight / stagger）
   原则：常驻动效只用 transform / opacity，避免重排掉帧
   ============================================================ */

/* ==================== ① 常驻氛围 ==================== */

/* 光带横向流动 —— 卡片顶边 / 板块分隔 */
@keyframes flow {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(100%); }
}

/* 心跳脉冲 —— AI 在线指示点 */
@keyframes pulse {
  0%, 100% { opacity: 1;   transform: scale(1); }
  50%      { opacity: 0.6; transform: scale(1.05); }
}

/* 光晕扩散 —— 浮动按钮 / 关键告警（双层错峰） */
@keyframes pulseRing {
  0%   { transform: scale(0.85); opacity: 0.55; }
  70%  { transform: scale(1.6);  opacity: 0; }
  100% { transform: scale(1.6);  opacity: 0; }
}

/* 骨架微光 —— 加载占位 */
@keyframes shimmer {
  0%   { background-position: -200% 0; }
  100% { background-position: 200% 0; }
}

/* 扫描线下移 —— mini-map / 雷达图 */
@keyframes scanline {
  0%   { transform: translateY(-100%); opacity: 0; }
  10%  { opacity: 1; }
  90%  { opacity: 1; }
  100% { transform: translateY(100%); opacity: 0; }
}

/* 旋转 —— 采集中 / 同步中 */
@keyframes spin {
  to { transform: rotate(360deg); }
}

/* 呼吸边框 —— 活跃板块 */
@keyframes borderBreath {
  0%, 100% { border-color: var(--border-glass); }
  50%      { border-color: var(--border-brand); }
}

/* 全息网格纵向漂移 —— 背景 */
@keyframes gridDrift {
  0%   { background-position: 0 0, 0 0; }
  100% { background-position: 0 32px, 32px 0; }
}

/* ==================== ② 数据变化 ==================== */

/* 数据流入 —— 新数值从下方顶入（数字滚动的核心） */
@keyframes dataIn {
  0%   { transform: translateY(60%); opacity: 0; filter: blur(2px); }
  60%  { opacity: 1; filter: blur(0); }
  100% { transform: translateY(0);   opacity: 1; }
}

/* 数据流出 —— 旧数值向上退出（与 dataIn 配对做滚轮） */
@keyframes dataOut {
  0%   { transform: translateY(0);    opacity: 1; }
  100% { transform: translateY(-60%); opacity: 0; }
}

/* 数值高亮闪一下 —— 值变更提示 */
@keyframes valueFlash {
  0%   { color: var(--brand-500); text-shadow: var(--glow-brand); }
  100% { color: var(--text-primary); text-shadow: none; }
}

/* 光标闪烁 —— 流式输出 */
@keyframes blink {
  50% { opacity: 0; }
}

/* 滴答 —— 时钟秒位轻微跳动 */
@keyframes tick {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-1px); }
}

/* sparkline 描边生长 —— 微图入场 */
@keyframes drawLine {
  from { stroke-dashoffset: 240; }
  to   { stroke-dashoffset: 0; }
}

/* 柱状生长 —— 全息柱图 */
@keyframes barGrow {
  from { transform: scaleY(0); }
  to   { transform: scaleY(1); }
}

/* ==================== ③ 入场 ==================== */

@keyframes fadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes fadeInUp {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes fadeInDown {
  from { opacity: 0; transform: translateY(-10px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes slideInRight {
  from { opacity: 0; transform: translateX(16px); }
  to   { opacity: 1; transform: translateX(0); }
}
/* 折叠展开 —— M4 情报列表 */
@keyframes expandDown {
  from { opacity: 0; max-height: 0; }
  to   { opacity: 1; max-height: 400px; }
}
/* 弹入 —— 浮动按钮 / Toast */
@keyframes popIn {
  0%   { opacity: 0; transform: scale(0.8); }
  100% { opacity: 1; transform: scale(1); }
}

/* ==================== 工具类 ==================== */

.anim-flow      { animation: flow var(--duration-flow) var(--easing-default) infinite; }
.anim-pulse     { animation: pulse var(--duration-pulse) var(--easing-default) infinite; }
.anim-pulse-ring{ animation: pulseRing 2200ms var(--easing-out) infinite; }
.anim-spin      { animation: spin 1200ms linear infinite; }
.anim-scan      { animation: scanline 3600ms var(--easing-default) infinite; }
.anim-breath    { animation: borderBreath 3000ms var(--easing-default) infinite; }
.anim-blink     { animation: blink 1000ms steps(2) infinite; }
.anim-tick      { animation: tick 1000ms steps(2) infinite; }

.anim-data-in   { animation: dataIn var(--duration-slow) var(--easing-out) both; }
.anim-flash     { animation: valueFlash 900ms var(--easing-default); }
.anim-draw      { stroke-dasharray: 240; animation: drawLine 1200ms var(--easing-out) both; }
.anim-bar-grow  { transform-origin: bottom; animation: barGrow var(--duration-slow) var(--easing-out) both; }

.anim-fade-in   { animation: fadeIn var(--duration-normal) var(--easing-default) both; }
.anim-fade-up   { animation: fadeInUp var(--duration-slow) var(--easing-out) both; }
.anim-fade-down { animation: fadeInDown var(--duration-slow) var(--easing-out) both; }
.anim-slide-r   { animation: slideInRight var(--duration-slow) var(--easing-out) both; }
.anim-expand    { overflow: hidden; animation: expandDown var(--duration-slow) var(--easing-out) both; }
.anim-pop       { animation: popIn var(--duration-normal) var(--easing-spring) both; }

/* 骨架屏 */
.skeleton {
  background: linear-gradient(90deg,
    var(--gray-800) 25%,
    var(--gray-700) 50%,
    var(--gray-800) 75%);
  background-size: 200% 100%;
  animation: shimmer 1600ms linear infinite;
  border-radius: var(--radius-sm);
  color: transparent !important;
}

/* 列表错峰入场：给 li / .rt-item 加 .stagger，父级按 nth-child 递延 */
.stagger > * { animation: fadeInUp var(--duration-slow) var(--easing-out) both; }
.stagger > *:nth-child(1) { animation-delay: 0ms; }
.stagger > *:nth-child(2) { animation-delay: 60ms; }
.stagger > *:nth-child(3) { animation-delay: 120ms; }
.stagger > *:nth-child(4) { animation-delay: 180ms; }
.stagger > *:nth-child(5) { animation-delay: 240ms; }
.stagger > *:nth-child(6) { animation-delay: 300ms; }
.stagger > *:nth-child(7) { animation-delay: 360ms; }
.stagger > *:nth-child(8) { animation-delay: 420ms; }

/* 数字滚轮容器：内部 .num-roll-item 用 dataIn / dataOut 交替 */
.num-roll {
  display: inline-block;
  overflow: hidden;
  vertical-align: bottom;
  line-height: 1.15;
}
.num-roll > .num-roll-item { display: block; animation: dataIn var(--duration-slow) var(--easing-out) both; }
.num-roll > .num-roll-item.is-out { animation: dataOut var(--duration-normal) var(--easing-default) both; }

/* 光带底衬：任意容器加 .flow-underline 得到一条流动分隔线 */
.flow-underline {
  position: relative;
  overflow: hidden;
}
.flow-underline::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 1px;
  background: var(--gradient-flow);
  background-size: 45% 100%;
  background-repeat: no-repeat;
  animation: flowBg var(--duration-flow) var(--easing-default) infinite;
}
@keyframes flowBg {
  0%   { background-position: -50% 0; }
  100% { background-position: 150% 0; }
}

/* 错峰第二环：.anim-pulse-ring.delay-1 做双环扩散 */
.delay-1 { animation-delay: 700ms; }
.delay-2 { animation-delay: 1400ms; }

/* 无障碍：系统请求减少动效时全部停掉（保留最终态） */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
  }
}
