/* ==========================================================================
   火蜘蛛 CRM — 动效层
   ---------------------------------------------------------------------------
   参数对齐对标站 crm.broctagon.com 的实测动效：
     · 入场曲线   cubic-bezier(.16,1,.3,1)  时长 380ms   （其 nebula 体系）
     · 移出曲线   220ms ease-in
     · 通用过渡   cubic-bezier(.215,.61,.355,1)  时长 300ms
     · 按钮阴影   cubic-bezier(.25,.8,.5,1)  时长 300ms
     · 按钮高度阴影挂 ::before（便于与元素自身阴影解耦），按压时抬到更高一层
     · 列表入场   位移 16px → 0；页面入场 位移 10px → 0

   本文件只负责「动」，不含配色与排版（那些在 tokens.css / ui.css）。
   全部动效都尊重 prefers-reduced-motion。
   ========================================================================== */

/* ==========================================================================
   1. 关键帧
   ========================================================================== */

/* 页面入场：淡入 + 轻微上浮（对标站 nebula-page-in 的位移量） */
@keyframes hz-page-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}
/* 页面离场：向上淡出（对标站 nebula-page-out） */
@keyframes hz-page-out {
  from { opacity: 1; transform: translateY(0); }
  to   { opacity: 0; transform: translateY(-6px); }
}
/* 列表项入场：位移更大，营造"逐条落下" */
@keyframes hz-rise {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: translateY(0); }
}
/* 纯淡入 */
@keyframes hz-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}
/* 弹层入场：从略小放大 + 淡入 */
@keyframes hz-pop {
  from { opacity: 0; transform: translateY(8px) scale(.97); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
/* 通知从右侧滑入 */
@keyframes hz-toast-in {
  from { opacity: 0; transform: translateX(24px) scale(.98); }
  to   { opacity: 1; transform: translateX(0) scale(1); }
}
/* 悬浮微抬（用于强调卡片，缓慢往返） */
@keyframes hz-float {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-3px); }
}
/* 呼吸光环：用于"进行中"的状态点（对标站 nebula-pulse-ring） */
@keyframes hz-pulse-ring {
  0%   { box-shadow: 0 0 0 0 rgba(var(--cta-rgb), .45); }
  70%  { box-shadow: 0 0 0 7px rgba(var(--cta-rgb), 0); }
  100% { box-shadow: 0 0 0 0 rgba(var(--cta-rgb), 0); }
}
/* 骨架屏流光 */
@keyframes hz-shimmer {
  from { background-position: 200% 0; }
  to   { background-position: -200% 0; }
}
/* 涟漪：从点击点扩散后淡出 */
@keyframes hz-ripple {
  from { transform: scale(0); opacity: .28; }
  to   { transform: scale(1); opacity: 0; }
}
/* 旋转（加载态） */
@keyframes hz-spin { to { transform: rotate(360deg); } }
/* 数字滚动/强调：轻微脉冲（用于刷新后的数值变化提示） */
@keyframes hz-bump {
  0%   { transform: scale(1); }
  40%  { transform: scale(1.06); }
  100% { transform: scale(1); }
}
/* 跑马灯（长文本横幅） */
@keyframes hz-ticker {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
/* 下划线从中心展开（页签/导航激活态） */
@keyframes hz-underline-in {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

/* ==========================================================================
   2. 入场工具类
   ========================================================================== */

.anim-page { animation: hz-page-in var(--motion-dur-out) var(--motion-ease-out) both; }
.anim-rise { animation: hz-rise var(--motion-dur-out) var(--motion-ease-out) both; }
.anim-fade { animation: hz-fade var(--motion-dur) var(--motion-ease) both; }
.anim-pop  { animation: hz-pop var(--motion-dur) var(--motion-ease-out) both; }

/* 交错入场：容器加 .stagger，子元素依次落下。
   纯 CSS 实现（nth-child 阶梯），无需 JS 标注索引 —— 页面代码零改动。
   上限 12 层，之后不再增加延迟，避免长列表整体"越来越慢"。 */
.stagger > * { animation: hz-rise var(--motion-dur-out) var(--motion-ease-out) both; }
.stagger > *:nth-child(1)  { animation-delay: 0ms; }
.stagger > *:nth-child(2)  { animation-delay: 24ms; }
.stagger > *:nth-child(3)  { animation-delay: 48ms; }
.stagger > *:nth-child(4)  { animation-delay: 72ms; }
.stagger > *:nth-child(5)  { animation-delay: 96ms; }
.stagger > *:nth-child(6)  { animation-delay: 120ms; }
.stagger > *:nth-child(7)  { animation-delay: 144ms; }
.stagger > *:nth-child(8)  { animation-delay: 168ms; }
.stagger > *:nth-child(9)  { animation-delay: 192ms; }
.stagger > *:nth-child(10) { animation-delay: 216ms; }
.stagger > *:nth-child(11) { animation-delay: 240ms; }
.stagger > *:nth-child(n+12) { animation-delay: 264ms; }

/* 表格只整体淡入一次：逐个 <tr> 做 transform 会在长表上掉帧 */
.table-wrap.rise, .card.rise, .stat.rise { animation: hz-rise var(--motion-dur-out) var(--motion-ease-out) both; }

/* ==========================================================================
   3. 按钮动态（重点）
   ---------------------------------------------------------------------------
   四层反馈叠加，互不干扰：
     ① 覆盖层  ::after  —— Material 状态层（悬浮变深 / 按压更深），不改底色
     ② 高度阴影 ::before —— 独立元素承载阴影，可单独过渡（对标站同款做法）
     ③ 位移    元素自身   —— 按压时下沉 1px，配合阴影回收，形成"按下去"的实体感
     ④ 涟漪    .hz-ripple —— 从指针落点扩散的圆形水波（运行时注入，见 ui.js）
   ========================================================================== */

.btn {
  position: relative;
  isolation: isolate;                 /* 让 ::before 的 z-index:-1 不穿透到祖先 */
  overflow: hidden;                   /* 裁掉溢出按钮的涟漪 */
  -webkit-tap-highlight-color: transparent;
  transition:
    background-color var(--motion-dur) var(--motion-ease),
    border-color var(--motion-dur) var(--motion-ease),
    color var(--motion-dur) var(--motion-ease),
    box-shadow var(--motion-dur) var(--motion-ease-standard),
    transform var(--motion-dur) var(--motion-ease-standard);
  will-change: transform;
}

/* ② 高度阴影层：默认抬起一档，悬浮再抬一档，按压收回 */
.btn::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: var(--e1);
  z-index: -1;
  pointer-events: none;
  transition: box-shadow var(--motion-dur) var(--motion-ease-standard);
}
.btn:hover:not(:disabled)::before   { box-shadow: var(--e2); }
.btn:focus-visible:not(:disabled)::before { box-shadow: var(--e2); }
.btn:active:not(:disabled)::before  { box-shadow: none; }

/* ① 状态覆盖层：用 currentColor，深底按钮自然变亮、浅底按钮自然变深 */
.btn::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: currentColor;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--motion-dur) var(--motion-ease);
}
.btn:hover:not(:disabled)::after  { opacity: .07; }
.btn:active:not(:disabled)::after { opacity: .14; }

/* ③ 按压下沉 */
.btn:hover:not(:disabled) { transform: translateY(-1px); }
.btn:active:not(:disabled) { transform: translateY(1px); }

/* 无阴影的轻量变体：保留覆盖层与位移，不抬升 */
.btn-ghost::before, .btn-outline::before { box-shadow: none; }
.btn-ghost:hover:not(:disabled)::before,
.btn-outline:hover:not(:disabled)::before { box-shadow: none; }
.btn-ghost:hover:not(:disabled), .btn-outline:hover:not(:disabled),
.btn-ghost:active:not(:disabled), .btn-outline:active:not(:disabled) { transform: none; }

/* 主按钮：同色辉光（对标站主按钮实测 0 4px 20px rgba(215,13,36,.42)） */
.btn-primary::before { box-shadow: var(--cta-glow); }
.btn-primary:hover:not(:disabled)::before { box-shadow: var(--cta-glow-strong); }
.btn-primary:active:not(:disabled)::before { box-shadow: var(--e1); }

/* 危险/成功按钮给同色辉光，保持"实心按钮会发光"的一致语言 */
.btn-danger::before  { box-shadow: 0 4px 18px rgba(206, 31, 32, .34); }
.btn-success::before { box-shadow: 0 4px 18px rgba(66, 181, 73, .34); }
.btn-danger:active:not(:disabled)::before,
.btn-success:active:not(:disabled)::before { box-shadow: var(--e1); }

/* 焦点环：键盘可见，鼠标点击不出现（:focus-visible） */
.btn:focus-visible { outline: none; box-shadow: var(--shadow-focus); }

/* 禁用：去掉一切动效反馈 */
.btn:disabled::before, .btn:disabled::after { box-shadow: none; opacity: 0; }
.btn:disabled:hover, .btn:disabled:active { transform: none; }

/* 加载态：内容淡出，宽度不跳 */
.btn.is-loading { pointer-events: none; }
.btn.is-loading .btn-label { opacity: .55; }

/* 涟漪（由 ui.js 注入的 <span class="hz-ripple">） */
.hz-ripple {
  position: absolute;
  border-radius: 50%;
  background: currentColor;
  pointer-events: none;
  transform: scale(0);
  animation: hz-ripple var(--motion-dur-ripple) var(--motion-ease-out) forwards;
}

/* 图标按钮、小块按钮同样走这套反馈（宽度小，位移收窄） */
.btn-icon:hover:not(:disabled) { transform: translateY(-1px); }
.pg, .tab, .topnav-item, .nav-item, .dropdown-item, .topnav-link { transition: background-color var(--motion-dur-fast) var(--motion-ease), color var(--motion-dur-fast) var(--motion-ease), border-color var(--motion-dur-fast) var(--motion-ease); }

/* ==========================================================================
   4. 组件动效
   ========================================================================== */

/* 卡片：悬浮轻微抬升（只对可点卡片生效，避免整页都在动） */
.card-lift { transition: box-shadow var(--motion-dur) var(--motion-ease-standard), transform var(--motion-dur) var(--motion-ease-standard); }
.card-lift:hover { transform: translateY(-2px); box-shadow: var(--e2); }

/* 统计卡：进场 + 悬浮微亮 */
.stat { transition: box-shadow var(--motion-dur) var(--motion-ease-standard), transform var(--motion-dur) var(--motion-ease-standard), border-color var(--motion-dur) var(--motion-ease); }
.stat:hover { box-shadow: var(--e2); border-color: var(--border-strong); }
/* 数值刷新后的强调脉冲 */
.stat-value.bump { animation: hz-bump .42s var(--motion-ease-spring); }

/* 表格行：悬浮底色渐变而非瞬变 */
.table tbody tr { transition: background-color var(--motion-dur-fast) var(--motion-ease); }
.table tbody tr.row-click { cursor: pointer; }
.table tbody tr.row-click:hover { background: var(--bg-subtle); }

/* 弹层 */
.modal-backdrop { animation: hz-fade var(--motion-dur-in) var(--motion-ease-out) both; }
.modal { animation: hz-pop var(--motion-dur) var(--motion-ease-out) both; }

/* 通知 */
.toast { animation: hz-toast-in var(--motion-dur) var(--motion-ease-out) both; }
.toast.leaving { animation: hz-page-out var(--motion-dur-in) var(--motion-ease-in) both; }

/* 下拉面板 */
.dropdown, .topnav-panel { animation: hz-pop var(--motion-dur-in) var(--motion-ease-out) both; transform-origin: top right; }

/* 侧边抽屉（移动端） */
.drawer { transition: transform var(--motion-dur) var(--motion-ease-out); }

/* 输入框聚焦：描边 + 光环平滑过渡 */
.input, .select, .textarea {
  transition: border-color var(--motion-dur-fast) var(--motion-ease),
              box-shadow var(--motion-dur-fast) var(--motion-ease),
              background-color var(--motion-dur-fast) var(--motion-ease);
}

/* 页签下划线：切换时从中间展开 */
.tab { position: relative; }
.tab::after {
  content: ''; position: absolute; left: 12px; right: 12px; bottom: -1px; height: 2px;
  background: currentColor; border-radius: 2px;
  transform: scaleX(0); transform-origin: center;
  transition: transform var(--motion-dur) var(--motion-ease-out);
}
.tab.active::after { transform: scaleX(1); }

/* 进度条填充：数值变化平滑推进 */
.progress > i { transition: width var(--motion-dur-out) var(--motion-ease-out); }
.barlist .bar > i { transition: width var(--motion-dur-out) var(--motion-ease-out); }

/* 骨架屏：流光扫描（对标站 q-skeleton--wave 的语气） */
.skeleton {
  background: linear-gradient(90deg,
    var(--bg-subtle) 0%,
    rgba(145, 158, 171, .18) 20%,
    var(--bg-subtle) 40%,
    var(--bg-subtle) 100%);
  background-size: 200% 100%;
  animation: hz-shimmer 1.5s linear infinite;
  border-radius: 8px;
}

/* 加载指示器 */
.spinner { animation: hz-spin .7s linear infinite; }

/* 状态点：进行中呼吸 */
.dot.live { animation: hz-pulse-ring 2.2s var(--motion-ease) infinite; }

/* 长文本跑马灯（可选，加 .ticker 到容器） */
.ticker { overflow: hidden; white-space: nowrap; }
.ticker > span { display: inline-block; animation: hz-ticker 24s linear infinite; }
.ticker:hover > span { animation-play-state: paused; }

/* 顶栏滚动后加深阴影（由布局层在滚动时加 .scrolled） */
.topbar { transition: box-shadow var(--motion-dur) var(--motion-ease), background-color var(--motion-dur) var(--motion-ease); }
.topbar.scrolled { box-shadow: var(--e1); }

/* ==========================================================================
   5. 无障碍：用户要求减少动效时，全部降级为"直接呈现"
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  .stagger > * { animation-delay: 0ms !important; }
  .btn:hover:not(:disabled),
  .btn:active:not(:disabled),
  .card-lift:hover,
  .stat:hover { transform: none !important; }
  .hz-ripple { display: none !important; }
  .skeleton { animation: none !important; background: var(--bg-subtle) !important; }
}
