/* ============================================================================
   北极星 V3 · 动效层（入场编排 / 按压 / 骨架 / 极光漂移 / 降级）
   ----------------------------------------------------------------------------
   原则（硬约束）：
     1) 只动 transform / opacity（合成器线程）；不动 width/height/top/left/filter；
     2) 页面切换不做滑屏（保手感）：只是淡入 + 8px 上浮；
     3) 列表错峰 40ms、最多 6 项（总时长 ≤ 520ms）；
     4) 所有动画都必须有 prefers-reduced-motion 兜底（tokens.css 已做全局归零，
        这里再对「循环类」动画显式关闭）；
     5) 不循环的装饰（光扫/图表绘制/数字滚动）只播一次。
   ========================================================================== */

/* 页面入场 */
.view { animation: view-in var(--dur-3) var(--ease-out) both; }
@keyframes view-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* 列表错峰：元素加 .stagger + style="--i:0..5" */
.stagger { animation: rise-in var(--dur-4) var(--ease-out) both; animation-delay: calc(var(--i, 0) * var(--stagger)); }
@keyframes rise-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* 首屏 hero 的「入场上浮 + 轻微缩放」：只有一处，且只播一次 */
.hero-in { animation: hero-in var(--dur-5) var(--ease-out) both; }
@keyframes hero-in {
  from { opacity: 0; transform: translateY(14px) scale(.985); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* 展开/折叠（高度动画禁用；用 clip 的 opacity+translate 代替） */
.collapsible { animation: collapse-in var(--dur-3) var(--ease-out) both; }
@keyframes collapse-in {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* 按压反馈（触摸设备最重要的一条） */
.press { transition: transform var(--dur-1) var(--ease-out), box-shadow var(--dur-1) var(--ease-out); }
.press:active { transform: scale(.975); }
@media (hover: hover) { .press:hover { transform: translateY(-1px); } }

/* 极光漂移 */
@keyframes orb-a {
  0%   { transform: translate3d(0, 0, 0) scale(1); }
  50%  { transform: translate3d(7vmax, 5vmax, 0) scale(1.08); }
  100% { transform: translate3d(-3vmax, 9vmax, 0) scale(1.02); }
}
@keyframes orb-b {
  0%   { transform: translate3d(0, 0, 0) scale(1.05); }
  50%  { transform: translate3d(-6vmax, 8vmax, 0) scale(1); }
  100% { transform: translate3d(4vmax, 3vmax, 0) scale(1.1); }
}
@keyframes orb-c {
  0%   { transform: translate3d(0, 0, 0) scale(1); opacity: .9; }
  100% { transform: translate3d(9vmax, -6vmax, 0) scale(1.12); opacity: .55; }
}
@keyframes core-breathe { from { opacity: .68; } to { opacity: 1; } }

/* 状态点脉冲（只在状态变化时播一次，不要无限） */
@keyframes pulse-dot {
  0%   { transform: scale(1); opacity: 1; }
  40%  { transform: scale(2.2); opacity: .35; }
  100% { transform: scale(1); opacity: 1; }
}

/* 骨架 shimmer（位移渐变，不动 background-position） */
@keyframes sk-shimmer { to { transform: translateX(100%); } }

/* 图表绘制：路径长度由 SVG pathLength=1 + stroke-dasharray 控制 */
@keyframes chart-draw {
  from { stroke-dashoffset: 1; }
  to   { stroke-dashoffset: 0; }
}

/* 数字滚动：由 JS 逐帧写 textContent，这里只给一个轻微「落定」动作 */
.num-pop { animation: num-pop var(--dur-3) var(--ease-out) both; }
@keyframes num-pop {
  from { opacity: .4; transform: translateY(3px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* 光扫（一次性；tokens 里 .sweep 引用） */
@keyframes sweep-in {
  from { transform: translateX(0) skewX(-18deg); }
  to   { transform: translateX(380%) skewX(-18deg); }
}

/* 底部弹层 / Toast / 淡入 */
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes sheet-up {
  from { opacity: .6; transform: translateY(26px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes toast-in {
  from { opacity: 0; transform: translateY(10px) scale(.97); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes toast-out {
  from { opacity: 1; transform: translateY(0); }
  to   { opacity: 0; transform: translateY(6px); }
}
@keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }

/* 阅读进度条：报告页滚动百分比（JS 写 style.transform: scaleX()） */
.scroll-progress {
  position: fixed;
  top: 0;
  left: 0;
  z-index: calc(var(--z-sticky) + 1);
  width: 100%;
  height: 2px;
  transform-origin: 0 50%;
  transform: scaleX(0);
  background: linear-gradient(90deg, var(--aurora-teal), var(--brand), var(--aurora-violet));
  box-shadow: 0 0 8px var(--aurora-teal-soft);
  pointer-events: none;
}

/* ------------------------------ 降级 ------------------------------ */
@media (prefers-reduced-motion: reduce) {
  .view, .stagger, .hero-in, .collapsible, .num-pop,
  .sheet-mask, .sheet-wrap, .toast, .sweep::after { animation: none !important; }
  .aurora__orb, .aurora__core, .dot--pulse { animation: none !important; }
  .sk::after { display: none; }
  .press:active { transform: none; opacity: .85; }
  .chart-draw { animation: none; }
  .scroll-progress { transition: none; }
}
html[data-perf="lite"] .view,
html[data-perf="lite"] .stagger,
html[data-perf="lite"] .hero-in { animation-duration: .001ms !important; }
