/* ==========================================================================
   effects.css —— 动效层（入场 / 交错 / 涟漪 / 关键帧 / 降级）
   所有动画集中在这一处，方便统一调节节奏或整体关闭。
   两个约定（写内容时只需要记住这两个属性）：
     data-reveal          该元素进入视口时淡入上浮（js/core.js 观察）
                          取值：默认上浮 / "left" / "right" / "zoom"
     data-stagger         标在容器上，由 js 给直接子元素写入 --i 序号，
                          子元素再配合 data-reveal 就能得到依次入场
   ========================================================================== */

/* ---------- 滚动揭示（--i 由 [data-stagger] 容器分配，形成交错） ---------- */
[data-reveal]{opacity:0;transform:translateY(16px);
  transition:opacity .5s var(--ease-out),transform .5s var(--ease-out);
  transition-delay:calc(var(--i,0) * 45ms)}
[data-reveal].in{opacity:1;transform:none}
[data-reveal="left"]{transform:translateX(-22px)}
[data-reveal="right"]{transform:translateX(22px)}
[data-reveal="zoom"]{transform:scale(.965)}

/* ---------- 面板切换入场（短而轻，避免整页大元素长时间占着合成层） ---------- */
.panel.is-active{animation:panel-in .3s var(--ease-out)}

/* ---------- 点击涟漪 ---------- */
.ripple{position:absolute;border-radius:50%;pointer-events:none;transform:translate(-50%,-50%) scale(0);
  background:rgba(255,255,255,.42);animation:ripple-out .5s var(--ease-out) forwards;z-index:-1;
  will-change:transform,opacity}
.nav-tab .ripple,.chip .ripple,.news-filter .ripple{background:var(--sage-tint)}
@keyframes ripple-out{to{transform:translate(-50%,-50%) scale(1);opacity:0}}

/* ---------- 关键帧 ---------- */
@keyframes panel-in{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
@keyframes rise-in{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}}
@keyframes kenburns{from{transform:scale(1.045)}to{transform:scale(1.115)}}
@keyframes dot-progress{from{transform:scaleX(0)}to{transform:scaleX(1)}}
@keyframes spin{to{transform:rotate(360deg)}}
@keyframes toast-in{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
@keyframes toast-out{to{opacity:0;transform:translateY(10px)}}
@keyframes shake{10%,90%{transform:translateX(-2px)}30%,70%{transform:translateX(3px)}50%{transform:translateX(-3px)}}
.shake{animation:shake .4s var(--ease)}

/* ---------- 移动端抽屉展开 ---------- */
.mobile-nav:not([hidden]){animation:drawer-in .28s var(--ease-out)}
@keyframes drawer-in{from{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:none}}

/* ---------- 统一降级：尊重系统的「减少动态效果」 ---------- */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation-duration:.01ms !important;animation-iteration-count:1 !important;
    transition-duration:.01ms !important;scroll-behavior:auto !important}
  [data-reveal]{opacity:1;transform:none}
  .slide-body>*,.carousel-slide.is-active .slide-body>*{opacity:1;transform:none}
}
