/* effects.css — 动效层：毛玻璃 / 粒子 / 流光 / 入场
   原则：只用 transform + opacity 做动画；尊重系统「减少动态效果」；不干扰阅读。 */

/* ============ 0. 可访问性：一律可关 ============ */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  .fx-particles, .fx-aura { display: none !important; }
  .fx-reveal { opacity: 1 !important; transform: none !important; }
  .fx-char { opacity: 1 !important; transform: none !important; }
}

/* ============ 1. 毛玻璃 ============ */
.glass {
  background: linear-gradient(180deg, rgba(255,255,255,.055), rgba(255,255,255,.018));
  backdrop-filter: blur(22px) saturate(150%);
  -webkit-backdrop-filter: blur(22px) saturate(150%);
  border: 1px solid rgba(255,255,255,.085);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.09), 0 14px 44px rgba(0,0,0,.38);
}

/* 导航：玻璃 + 底部流光 */
.nav {
  background: linear-gradient(180deg, rgba(10,10,12,.74), rgba(10,10,12,.52)) !important;
  backdrop-filter: blur(24px) saturate(165%);
  -webkit-backdrop-filter: blur(24px) saturate(165%);
  border-bottom: 1px solid rgba(255,255,255,.06) !important;
}
.nav::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255,59,48,.65), rgba(56,189,248,.4), transparent);
  background-size: 220% 100%;
  animation: navFlow 9s linear infinite;
  opacity: .55; pointer-events: none;
}
@keyframes navFlow { from { background-position: 220% 0 } to { background-position: -120% 0 } }

/* 卡片：hover 时玻璃上浮 */
.wcard {
  transition: transform .25s cubic-bezier(.2,.8,.2,1), border-color .25s, background .25s, box-shadow .25s;
}
.wcard:hover {
  box-shadow: 0 18px 44px rgba(0,0,0,.45), inset 0 1px 0 rgba(255,255,255,.07);
  backdrop-filter: blur(8px);
}

/* 侧栏卡片、面板、抽屉统一玻璃质感 */
.side-card, .panel, .kpi, .hub-card, .ns-card {
  backdrop-filter: blur(14px) saturate(130%);
  -webkit-backdrop-filter: blur(14px) saturate(130%);
}
.sheet {
  background: linear-gradient(180deg, rgba(22,22,28,.92), rgba(15,15,19,.96)) !important;
  backdrop-filter: blur(30px) saturate(150%);
}

/* ============ 2. 流光 ============ */
/* 严重度条：光带扫过 */
.sevbar-fill { position: relative; overflow: hidden; }
.sevbar-fill::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(100deg, transparent 20%, rgba(255,255,255,.65) 50%, transparent 80%);
  transform: translateX(-110%);
  animation: barSheen 3.2s cubic-bezier(.4,0,.2,1) infinite;
}
@keyframes barSheen { 0% { transform: translateX(-110%) } 55%, 100% { transform: translateX(210%) } }

/* 主按钮：hover 扫光 */
.btn-primary { position: relative; overflow: hidden; }
.btn-primary::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(115deg, transparent 30%, rgba(255,255,255,.4) 50%, transparent 70%);
  transform: translateX(-130%);
  pointer-events: none;
}
.btn-primary:hover::after { animation: btnSheen .85s cubic-bezier(.3,0,.2,1); }
@keyframes btnSheen { to { transform: translateX(130%) } }

/* 卡片四条边：hover 时流光绕行 */
@property --fx-ang { syntax: '<angle>'; initial-value: 0deg; inherits: false; }
.wcard::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit; padding: 1px;
  background: conic-gradient(from var(--fx-ang),
    transparent 0deg, transparent 250deg, rgba(255,59,48,.9) 320deg, rgba(255,140,60,.9) 340deg, transparent 360deg);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  opacity: 0; transition: opacity .3s; pointer-events: none;
}
.wcard:hover::before { opacity: 1; animation: borderSpin 2.4s linear infinite; }
@keyframes borderSpin { to { --fx-ang: 360deg } }

/* ============ 3. 粒子与光晕 ============ */
.fx-particles {
  position: fixed; inset: 0; z-index: 0; pointer-events: none;
  /* canvas 是替换元素，光有 inset:0 不会拉伸，必须显式给宽高 */
  width: 100%; height: 100%;
  opacity: .6; transition: opacity .6s;
}
body.fx-on .wrap, body.fx-on .foot { position: relative; z-index: 1; }

/* 首页 hero 的极光 */
/* 极光层：保留原来的外扩观感（留出溢到屏幕边缘的光），
   横向溢出由 base.css 的 html{overflow-x:clip} 兜住，不会再让整页左右滑 */
.fx-aura { position: absolute; inset: -20% -10% auto -10%; height: 620px; pointer-events: none; z-index: 0; overflow: hidden; }
.fx-aura i {
  position: absolute; border-radius: 50%; filter: blur(70px); opacity: .5;
  will-change: transform;
}
.fx-aura i:nth-child(1) {
  width: 460px; height: 460px; left: 4%; top: -8%;
  background: radial-gradient(circle, rgba(255,59,48,.55), transparent 70%);
  animation: auraDrift 22s ease-in-out infinite alternate;
}
.fx-aura i:nth-child(2) {
  width: 380px; height: 380px; right: 8%; top: 6%;
  background: radial-gradient(circle, rgba(56,189,248,.32), transparent 70%);
  animation: auraDrift 28s ease-in-out infinite alternate-reverse;
}
.fx-aura i:nth-child(3) {
  width: 300px; height: 300px; left: 38%; top: 28%;
  background: radial-gradient(circle, rgba(212,25,75,.4), transparent 70%);
  animation: auraDrift 19s ease-in-out infinite alternate;
  animation-delay: -6s;
}
@keyframes auraDrift {
  0%   { transform: translate3d(0,0,0) scale(1) }
  50%  { transform: translate3d(40px,-24px,0) scale(1.12) }
  100% { transform: translate3d(-30px,18px,0) scale(.95) }
}

/* ============ 4. 入场与滚动渐显 ============ */
.fx-char {
  display: inline-block; opacity: 0;
  transform: translateY(20px) rotateX(-35deg);
  animation: charIn .68s cubic-bezier(.2,.8,.2,1) forwards;
  transform-origin: 50% 100%;
}
@keyframes charIn { to { opacity: 1; transform: none } }

.fx-reveal { opacity: 0; transform: translateY(26px); transition: opacity .72s cubic-bezier(.2,.8,.2,1), transform .72s cubic-bezier(.2,.8,.2,1); }
.fx-reveal.fx-in { opacity: 1; transform: none; }

/* 词条大字入场 */
.word-hanzi { animation: hanziIn .9s cubic-bezier(.2,.8,.2,1) both; }
@keyframes hanziIn {
  from { opacity: 0; transform: translateY(16px) scale(.97); filter: blur(6px) }
  to   { opacity: 1; transform: none; filter: none }
}

/* ============ 5. 细节反馈 ============ */
/* 词条卡汉字 hover 微发光 */
.wcard:hover .wc-hanzi { text-shadow: 0 0 26px rgba(255,255,255,.22); }

/* 严重度徽章脉冲（4/5 级才闪，提示危险） */
.wcard[data-sev="5"] .wc-sev { animation: sevPulse 2.6s ease-in-out infinite; }
@keyframes sevPulse {
  0%,100% { box-shadow: 0 0 0 0 rgba(212,25,75,.45) }
  50%     { box-shadow: 0 0 0 6px rgba(212,25,75,0) }
}

/* 卡片流：汉字呼吸光 */
.card-hanzi { animation: hanziBreath 6s ease-in-out infinite; }
@keyframes hanziBreath {
  0%,100% { text-shadow: 0 0 60px var(--glow, rgba(255,255,255,.14)) }
  50%     { text-shadow: 0 0 96px var(--glow, rgba(255,255,255,.2)) }
}

/* 底栏玻璃 */
.tabbar {
  background: linear-gradient(0deg, rgba(7,7,10,.97), rgba(7,7,10,.55)) !important;
  backdrop-filter: blur(22px) saturate(150%);
}

/* 抽屉进场弹性 */
.sheet { transition: transform .38s cubic-bezier(.16,1,.3,1) !important; }

/* 解码器命中词：脉冲框 */
.hit { animation: hitPulse 2.4s ease-in-out infinite; }
@keyframes hitPulse {
  0%,100% { box-shadow: 0 0 0 0 rgba(255,255,255,.25) }
  50%     { box-shadow: 0 0 0 3px rgba(255,255,255,.12) }
}

/* 收藏按钮被点亮时跳一下 */
.rail button.on .rb { animation: pop .42s cubic-bezier(.2,1.5,.4,1); }
@keyframes pop { 0% { transform: scale(1) } 42% { transform: scale(1.28) } 100% { transform: scale(1) } }

/* 后台：KPI 卡片 hover 抬升 */
.kpi { transition: transform .2s ease, border-color .2s; }
.kpi:hover { transform: translateY(-2px); border-color: var(--line); }

/* 尊重「减少动画」时的降级已在文件顶部统一处理 */

/* ============ 6. 卡片流专用 ============ */
/* 固定在背景的极光层（不随卡片滚动） */
.fx-aura--bg {
  position: fixed; inset: 0; height: 100%; z-index: 0; pointer-events: none;
  overflow: hidden;
}
.fx-aura--bg i {
  position: absolute; border-radius: 50%; filter: blur(90px);
  transition: background 1.1s ease, opacity 1.1s ease;
  will-change: transform;
}
.fx-aura--bg i:nth-child(1) {
  width: 620px; height: 620px; left: -14%; top: -10%;
  opacity: .32;
  animation: bgDriftA 26s ease-in-out infinite alternate;
}
.fx-aura--bg i:nth-child(2) {
  width: 520px; height: 520px; right: -16%; bottom: -12%;
  opacity: .18;
  animation: bgDriftB 32s ease-in-out infinite alternate;
}
@keyframes bgDriftA {
  0%   { transform: translate3d(0,0,0) scale(1) }
  100% { transform: translate3d(70px,50px,0) scale(1.15) }
}
@keyframes bgDriftB {
  0%   { transform: translate3d(0,0,0) scale(1.1) }
  100% { transform: translate3d(-60px,-40px,0) scale(.92) }
}

/* 卡片内容入场：每次滑到这张卡就重播一次 */
.card.is-active .card-inner { animation: feedCardIn .52s cubic-bezier(.2,.8,.2,1) both; }
@keyframes feedCardIn {
  from { opacity: 0; transform: translateY(18px) scale(.985); filter: blur(3px) }
  to   { opacity: 1; transform: none; filter: none }
}
/* 右侧操作栏稍晚一点出现 */
.card.is-active .rail { animation: railIn .5s cubic-bezier(.2,.8,.2,1) .12s both; }
@keyframes railIn {
  from { opacity: 0; transform: translateX(14px) }
  to   { opacity: 1; transform: none }
}

/* 高严重度卡片的标签加一层呼吸光 */
.card[data-sev="5"] .tag { animation: tagGlow 2.8s ease-in-out infinite; }
@keyframes tagGlow {
  0%,100% { box-shadow: 0 0 0 0 rgba(212,25,75,.5) }
  50%     { box-shadow: 0 0 16px 2px rgba(212,25,75,.35) }
}

/* 卡片流里粒子的层级：在卡片之下 */
body.feed-body .fx-particles { z-index: 0; }
body.feed-body .feed { position: relative; z-index: 1; }
