/* ============================================================
   loading.css — 高级加载动效（formating.pages.dev）
   独立文件，不修改 style.css。

   设计规范落地：
   · 只动画 transform / opacity（进度条统一 scaleX + origin:left）
   · 缓动仅用三种：--ease-out 进入退出 / --ease-in-out 屏内移动 / ease 150ms 悬停颜色
   · 时长：微交互 120ms · 标准 UI 200ms · 整页 280ms 进 / 220ms 出（退出快 20%）
   · 入场初始态 scale(0.95)
   · 成对元素同 easing 同 duration
   · prefers-reduced-motion：去 transform，保留 opacity，循环动画停在好看的帧
   · hover 一律包在 @media (hover:hover) and (pointer:fine)
   ============================================================ */

:root {
  /* 缓动令牌（规范只允许这三种） */
  --lp-ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --lp-ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  /* 时长令牌 */
  --lp-t-micro: 120ms;   /* 微交互 */
  --lp-t-ui: 200ms;      /* 标准 UI */
  --lp-t-page-in: 280ms; /* 整页进入 */
  --lp-t-page-out: 220ms;/* 整页退出（比进入快约 20%） */
}

/* 启动页显示期间锁定滚动（由 loading.js 添加 .lp-booting） */
html.lp-booting, html.lp-booting body { overflow: hidden !important; }

/* ---------- 顶部进度条 ---------- */
.lp-top {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: 3px;
  z-index: 99990;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--lp-t-ui) var(--lp-ease-out);
}
.lp-top.is-active { opacity: 1; }

/* 只用 transform: scaleX 推进，避免动画 width 触发 layout */
.lp-top-fill {
  height: 100%;
  width: 100%;
  border-radius: 0 3px 3px 0;
  transform: scaleX(0);
  transform-origin: left center;
  will-change: transform;
  background: linear-gradient(90deg, var(--primary, #3b82f6), var(--accent, #06b6d4));
  box-shadow: 0 0 12px rgba(59, 130, 246, 0.7);
  transition: transform var(--lp-t-ui) var(--lp-ease-out),
              background 150ms ease;
}
/* 不确定态（等待真实回调）：整段扫光，位移走 translateX */
.lp-top.is-indeterminate .lp-top-fill {
  transform: scaleX(0.32);
  transition: none;
  animation: lp-sweep-x 1100ms var(--lp-ease-in-out) infinite;
}
.lp-top.is-done .lp-top-fill { background: linear-gradient(90deg, #34d399, #10b981); }
.lp-top.is-error .lp-top-fill { background: linear-gradient(90deg, #f87171, #ef4444); }

@keyframes lp-sweep-x {
  0%   { transform: scaleX(0.32) translateX(-100%); }
  100% { transform: scaleX(0.32) translateX(100%); }
}

/* 顶部进度条文字标签（与进度条同 easing / duration，成对一致） */
.lp-top-label {
  position: fixed;
  top: 9px; right: 14px;
  z-index: 99991;
  padding: 4px 11px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.2px;
  color: #fff;
  background: rgba(15, 23, 42, 0.82);
  border: 1px solid rgba(255, 255, 255, 0.16);
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.28);
  backdrop-filter: blur(10px);
  opacity: 0;
  transform: translateY(-6px);
  will-change: transform, opacity;
  pointer-events: none;
  transition: opacity var(--lp-t-ui) var(--lp-ease-out),
              transform var(--lp-t-ui) var(--lp-ease-out);
  font-variant-numeric: tabular-nums;
}
.lp-top-label.is-active { opacity: 1; transform: translateY(0); }
.lp-top-label.is-error { background: rgba(190, 30, 30, 0.9); }

/* ---------- 启动页 Splash ---------- */
.lp-splash {
  position: fixed;
  inset: 0;
  z-index: 99995;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 22px;
  background: linear-gradient(140deg, #0f0c29 0%, #302b63 45%, #1b2340 100%);
  opacity: 1;
  transition: opacity var(--lp-t-page-out) var(--lp-ease-out),
              transform var(--lp-t-page-out) var(--lp-ease-out),
              visibility var(--lp-t-page-out);
}
.lp-splash.is-leaving {
  opacity: 0;
  transform: scale(0.95);
  visibility: hidden;
  pointer-events: none;
}

.lp-splash-logo {
  width: 74px; height: 74px;
  border-radius: 22px;
  display: grid;
  place-items: center;
  background: linear-gradient(135deg, var(--primary, #3b82f6), var(--accent, #06b6d4));
  box-shadow: 0 14px 40px rgba(59, 130, 246, 0.42);
  will-change: transform;
  animation: lp-float 2.4s var(--lp-ease-in-out) infinite;
}
.lp-splash-logo svg { width: 38px; height: 38px; stroke: #fff; }

@keyframes lp-float {
  0%, 100% { transform: translateY(0) rotate(0deg); }
  50%      { transform: translateY(-9px) rotate(-4deg); }
}

.lp-splash-title {
  font-size: 19px;
  font-weight: 700;
  color: #fff;
  letter-spacing: 0.4px;
}
.lp-splash-sub {
  font-size: 12.5px;
  color: rgba(255, 255, 255, 0.62);
  margin-top: -14px;
  min-height: 16px;
  transition: opacity var(--lp-t-micro) ease;
}

/* 启动页环形进度：stroke-dashoffset 是 SVG 绘制属性，不触发 layout，
   且是表达"弧长百分比"唯一无副作用的方案（scaleX 会把圆环压扁） */
.lp-ring {
  width: 132px; height: 132px;
  position: relative;
  display: grid;
  place-items: center;
}
.lp-ring svg { position: absolute; inset: 0; transform: rotate(-90deg); }
.lp-ring-track { fill: none; stroke: rgba(255, 255, 255, 0.14); stroke-width: 5; }
.lp-ring-fill {
  fill: none;
  stroke: url(#lpRingGrad);
  stroke-width: 5;
  stroke-linecap: round;
  stroke-dasharray: 339.3; /* 2πr, r=54 */
  stroke-dashoffset: 339.3;
  filter: drop-shadow(0 0 6px rgba(6, 182, 212, 0.65));
  transition: stroke-dashoffset var(--lp-t-ui) var(--lp-ease-out);
}
.lp-ring-pct {
  font-size: 26px;
  font-weight: 800;
  color: #fff;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.lp-ring-pct small { font-size: 12px; font-weight: 600; opacity: 0.6; }

/* 启动页阶段刻度条：与环形同 easing / duration（成对一致），用 scaleX */
.lp-steps { display: flex; gap: 7px; }
.lp-step {
  width: 46px; height: 3px;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.16);
  overflow: hidden;
  position: relative;
}
.lp-step::after {
  content: "";
  position: absolute;
  inset: 0;
  width: 100%;
  transform: scaleX(0);
  transform-origin: left center;
  background: linear-gradient(90deg, #60a5fa, #22d3ee);
  transition: transform var(--lp-t-ui) var(--lp-ease-out);
}
.lp-step.is-done::after { transform: scaleX(1); }

/* ---------- 转换阶段进度浮层（读取真实 progress-item 状态） ---------- */
.lp-stage {
  position: fixed;
  right: 20px; bottom: 20px;
  z-index: 99989;
  width: 268px;
  padding: 14px 16px;
  border-radius: 18px;
  background: rgba(15, 23, 42, 0.86);
  border: 1px solid rgba(255, 255, 255, 0.14);
  box-shadow: 0 18px 46px rgba(0, 0, 0, 0.42);
  backdrop-filter: blur(14px);
  color: #f1f5f9;
  opacity: 0;
  transform: translateY(14px) scale(0.95);
  will-change: transform, opacity;
  pointer-events: none;
  transition: opacity var(--lp-t-ui) var(--lp-ease-out),
              transform var(--lp-t-ui) var(--lp-ease-out);
}
.lp-stage.is-active { opacity: 1; transform: translateY(0) scale(1); }

.lp-stage-head {
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: 13px;
  font-weight: 700;
  margin-bottom: 9px;
}
.lp-stage-spin {
  width: 13px; height: 13px;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.25);
  border-top-color: #fff;
  flex: none;
  will-change: transform;
  animation: lp-spin 800ms linear infinite;
}
@keyframes lp-spin { to { transform: rotate(360deg); } }

.lp-stage-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 600;
  font-size: 12px;
  color: rgba(241, 245, 249, 0.78);
}
.lp-stage-pct {
  font-size: 12px;
  font-weight: 800;
  color: #7dd3fc;
  font-variant-numeric: tabular-nums;
  flex: none;
}
.lp-stage-track {
  height: 4px;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.13);
  overflow: hidden;
}
.lp-stage-fill {
  height: 100%;
  width: 100%;
  border-radius: 2px;
  transform: scaleX(0);
  transform-origin: left center;
  will-change: transform;
  background: linear-gradient(90deg, #60a5fa, #22d3ee);
  transition: transform var(--lp-t-ui) var(--lp-ease-out);
}
.lp-stage-hint {
  margin-top: 8px;
  font-size: 11px;
  color: rgba(241, 245, 249, 0.55);
}

/* ---------- 拖拽文件读取进度（真实计数：已入列的文件数） ---------- */
.lp-drop {
  position: fixed;
  top: 84px; left: 50%;
  transform: translateX(-50%) translateY(-12px) scale(0.95);
  z-index: 99988;
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 10px 18px;
  border-radius: 999px;
  background: rgba(15, 23, 42, 0.9);
  border: 1px solid rgba(56, 189, 248, 0.42);
  box-shadow: 0 12px 34px rgba(0, 0, 0, 0.4);
  color: #e0f2fe;
  font-size: 13px;
  font-weight: 600;
  opacity: 0;
  will-change: transform, opacity;
  pointer-events: none;
  transition: opacity var(--lp-t-ui) var(--lp-ease-out),
              transform var(--lp-t-ui) var(--lp-ease-out);
}
.lp-drop.is-active {
  opacity: 1;
  transform: translateX(-50%) translateY(0) scale(1);
}
.lp-drop-count {
  min-width: 22px;
  padding: 1px 7px;
  border-radius: 999px;
  background: #0ea5e9;
  color: #fff;
  font-size: 12px;
  font-weight: 800;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

/* ---------- 乐观 UI：按钮即时反馈 ---------- */
.lp-busy { position: relative; overflow: hidden !important; }
.lp-busy::after {
  content: "";
  position: absolute;
  top: 0; bottom: 0;
  left: 0;
  width: 46%;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.32), transparent);
  will-change: transform;
  animation: lp-sweep-h 1050ms var(--lp-ease-in-out) infinite;
  pointer-events: none;
}
@keyframes lp-sweep-h {
  0%   { transform: translateX(-130%); }
  100% { transform: translateX(280%); }
}

/* 成功确认：轻微 pop，用规范允许的 ease-out */
.lp-ok {
  animation: lp-pop var(--lp-t-ui) var(--lp-ease-out) !important;
  border-color: #34d399 !important;
  box-shadow: 0 0 0 3px rgba(52, 211, 153, 0.28) !important;
}
@keyframes lp-pop {
  0%   { transform: scale(1); }
  45%  { transform: scale(1.05); }
  100% { transform: scale(1); }
}
/* 失败回滚：抖动用 will-change 抗掉帧 */
.lp-fail {
  will-change: transform;
  animation: lp-shake-x var(--lp-t-ui) var(--lp-ease-in-out) !important;
  border-color: #f87171 !important;
}
@keyframes lp-shake-x {
  0%, 100% { transform: translateX(0); }
  20%      { transform: translateX(-7px); }
  40%      { transform: translateX(7px); }
  60%      { transform: translateX(-4px); }
  80%      { transform: translateX(4px); }
}

/* ---------- 悬停（仅精确指针设备，避免触屏粘滞态） ---------- */
@media (hover: hover) and (pointer: fine) {
  .lp-top-label:hover { color: rgba(255, 255, 255, 0.92); }
  .lp-drop:hover { border-color: rgba(56, 189, 248, 0.75); }
}

/* ---------- 无障碍：减少动画 ----------
   规范：去 transform / 位移 / 缩放，保留 opacity 淡入淡出；
   循环动画用负 animation-delay 停在好看的帧。 */
@media (prefers-reduced-motion: reduce) {
  /* 保留 opacity 过渡，移除 transform 过渡 */
  .lp-top,
  .lp-top-label,
  .lp-splash,
  .lp-stage,
  .lp-drop,
  .lp-splash-sub,
  .lp-ring-fill,
  .lp-step::after,
  .lp-stage-fill,
  .lp-top-fill {
    transition: opacity 150ms ease !important;
    transform: none !important;
  }
  .lp-splash.is-leaving { transform: none !important; }
  .lp-top-label,
  .lp-stage,
  .lp-drop { transform: none !important; }
  .lp-drop.is-active { transform: none !important; }
  .lp-top-label.is-active { transform: none !important; }
  .lp-stage.is-active { transform: none !important; }

  /* 进度必须仍然可见：scaleX 归零会让进度"消失"，改为直接给满格 */
  .lp-top-fill { transform: scaleX(1) !important; }
  .lp-ring-fill { stroke-dashoffset: 0 !important; }
  .lp-step::after { transform: scaleX(1) !important; }
  .lp-stage-fill { transform: scaleX(1) !important; }

  /* 循环动画：负延迟停在好看的帧，而不是粗暴 none */
  .lp-splash-logo { animation: none !important; transform: none !important; }
  .lp-stage-spin,
  .lp-busy::after,
  .lp-top.is-indeterminate .lp-top-fill {
    animation: none !important;
  }
  /* 不确定态在 reduced-motion 下改为静态 100%，语义仍是"进行中" */
  .lp-top.is-indeterminate .lp-top-fill { transform: scaleX(1) !important; }
  /* busy 扫光停在中段，保留"正在处理"的视觉暗示但不动 */
  .lp-busy::after { transform: translateX(90%) !important; }

  .lp-ok, .lp-fail { animation: none !important; transform: none !important; }
}