/* =====================================================================
   effects.css — 动画关键帧 / 涟漪 / stagger / 跑马灯 / 进度环 / 金币粒子 / 成功勾选
   prefers-reduced-motion 全部关闭
   ===================================================================== */
@keyframes pageIn { from { opacity: 0; transform: translateX(18px); } to { opacity: 1; transform: none; } }
@keyframes pageInLeft { from { opacity: 0; transform: translateX(-18px); } to { opacity: 1; transform: none; } }
@keyframes pageInPop { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes fadeOut { from { opacity: 1; } to { opacity: 0; } }
@keyframes sheetUp { from { transform: translateY(100%); } to { transform: none; } }
@keyframes sheetDown { from { transform: none; } to { transform: translateY(100%); } }
@keyframes zoomIn { from { opacity: 0; transform: scale(.82); } to { opacity: 1; transform: none; } }
@keyframes zoomOut { from { opacity: 1; transform: none; } to { opacity: 0; transform: scale(.9); } }
@keyframes toastIn { from { opacity: 0; transform: translateY(-20px) scale(.95); } to { opacity: 1; transform: none; } }
@keyframes toastOut { to { opacity: 0; transform: translateY(-10px); } }
@keyframes toastBar { from { width: 100%; } to { width: 0; } }
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes skim { from { transform: translateX(-100%); } to { transform: translateX(100%); } }
@keyframes shine { 0% { left: -80%; } 60% { left: 130%; } 100% { left: 130%; } }
@keyframes pulse { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: .4; transform: scale(.7); } }
@keyframes shake { 0%, 100% { transform: none; } 25% { transform: translateX(-5px); } 75% { transform: translateX(5px); } }
@keyframes tabBounce { 0% { transform: scale(1); } 40% { transform: scale(1.3) translateY(-3px); } 100% { transform: scale(1); } }
@keyframes riseIn { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
@keyframes ripple { to { transform: scale(2.4); opacity: 0; } }
@keyframes marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@keyframes float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-6px); } }
@keyframes glowPulse { 0%, 100% { box-shadow: var(--glow); } 50% { box-shadow: 0 8px 28px rgba(255, 61, 113, .5); } }
@keyframes coinFall { 0% { transform: translate(0, 0) rotate(0) scale(1); opacity: 1; } 100% { transform: translate(var(--dx), var(--dy)) rotate(540deg) scale(.6); opacity: 0; } }
@keyframes drawCheck { to { stroke-dashoffset: 0; } }
@keyframes popCircle { 0% { transform: scale(0); } 70% { transform: scale(1.12); } 100% { transform: scale(1); } }
@keyframes ringGlow { 0%, 100% { filter: drop-shadow(0 0 2px rgba(255, 107, 53, .4)); } 50% { filter: drop-shadow(0 0 7px rgba(255, 61, 113, .7)); } }
@keyframes bgMove { from { background-position: 0 0; } to { background-position: 40px 0; } }

/* ---------- 涟漪 ---------- */
.ripple-host { position: relative; overflow: hidden; }
.ripple { position: absolute; border-radius: 50%; background: rgba(255, 255, 255, .45); transform: scale(0); animation: ripple .65s ease-out forwards; pointer-events: none; }
.btn:not(.btn-primary):not(.btn-accent):not(.btn-gold):not(.btn-ok):not(.btn-danger) .ripple, .list-row .ripple, .entry .ripple, .tab .ripple, .chip:not(.on) .ripple, .amount-grid button .ripple, .seg button .ripple, .cap-img .ripple, .av .ripple { background: rgba(255, 107, 53, .18); }

/* ---------- stagger 进入 ---------- */
.stagger > * { animation: riseIn .45s var(--ease) both; }
.stagger > *:nth-child(1) { animation-delay: .03s; } .stagger > *:nth-child(2) { animation-delay: .08s; } .stagger > *:nth-child(3) { animation-delay: .13s; } .stagger > *:nth-child(4) { animation-delay: .18s; } .stagger > *:nth-child(5) { animation-delay: .23s; } .stagger > *:nth-child(6) { animation-delay: .28s; } .stagger > *:nth-child(7) { animation-delay: .33s; } .stagger > *:nth-child(8) { animation-delay: .38s; } .stagger > *:nth-child(n+9) { animation-delay: .42s; }
.float { animation: float 3s ease-in-out infinite; }
.glow-pulse { animation: glowPulse 2.2s ease-in-out infinite; }

/* ---------- 跑马灯 ---------- */
.marquee { display: flex; align-items: center; gap: 8px; height: 34px; padding: 0 12px; border-radius: 10px; background: var(--p-soft); color: #C2410C; font-size: 12px; overflow: hidden; margin-bottom: 12px; }
.marquee .mq-ic { width: 16px; height: 16px; flex: none; color: var(--p2); }
.marquee .mq-ic svg { width: 16px; height: 16px; }
.mq-track { flex: 1; overflow: hidden; min-width: 0; -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent); mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent); }
.mq-in { display: inline-flex; white-space: nowrap; animation: marquee var(--mq-dur, 20s) linear infinite; will-change: transform; }
.mq-in span { padding-right: 60px; }
.marquee.paused .mq-in { animation-play-state: paused; }

/* ---------- 进度环（SVG stroke-dashoffset） ---------- */
.ring { width: 56px; height: 56px; position: relative; flex: none; }
.ring svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.ring .bg { fill: none; stroke: #EEF0F5; stroke-width: 5; }
.ring .fg { fill: none; stroke: url(#ringGrad); stroke-width: 5; stroke-linecap: round; transition: stroke-dashoffset 1.1s var(--ease); animation: ringGlow 2.4s ease-in-out infinite; }
.ring.done .fg { stroke: var(--ok); animation: none; }
.ring .rt { position: absolute; inset: 0; display: grid; place-items: center; font-size: 12px; font-weight: 800; font-variant-numeric: tabular-nums; }
.ring.lg { width: 96px; height: 96px; } .ring.lg .rt { font-size: 18px; }

/* ---------- 进度条 ---------- */
.progress { height: 8px; border-radius: 4px; background: #EEF0F5; overflow: hidden; position: relative; }
.progress .bar { height: 100%; border-radius: 4px; background: var(--grad); background-size: 40px 40px; background-image: linear-gradient(135deg, rgba(255, 255, 255, .25) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .25) 50%, rgba(255, 255, 255, .25) 75%, transparent 75%), var(--grad); animation: bgMove 1s linear infinite; transition: width 1s var(--ease); }
.progress.full .bar { background: var(--ok); animation: none; }

/* ---------- 金币粒子 ---------- */
.fx-canvas { position: fixed; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 95; display: none; }
.fx-canvas.on { display: block; }
.coin-pop { position: fixed; left: var(--x); top: var(--y); width: 18px; height: 18px; border-radius: 50%; background: radial-gradient(circle at 35% 35%, #FFE58F, #F5A623 60%, #C97A00); box-shadow: 0 0 6px rgba(245, 166, 35, .7); pointer-events: none; z-index: 96; animation: coinFall .95s cubic-bezier(.25, .8, .5, 1) forwards; }

/* ---------- 成功勾选 ---------- */
.check-anim { width: 92px; height: 92px; margin: 0 auto 14px; }
.check-anim circle { fill: var(--ok); transform-origin: center; animation: popCircle .5s var(--ease-b) both; }
.check-anim path { fill: none; stroke: #fff; stroke-width: 5; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 60; stroke-dashoffset: 60; animation: drawCheck .45s .35s ease-out forwards; }
.check-anim.gold circle { fill: var(--gold); }

/* ---------- reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
  .btn-primary::after, .ripple, .coin-pop, .fx-canvas { display: none !important; }
  .mq-in { animation: none !important; }
  .check-anim path { stroke-dashoffset: 0; }
}
