
/* ===== 全局动画 tokens(全站唯一来源,一切动画统一引用)===== */
:root{--anim-duration:.6s;--anim-easing:cubic-bezier(.22,.61,.36,1);--anim-stagger:100ms}

/* 初始隐藏态只在 html.anim-ready(JS 已接管)且用户不排斥动效时生效:
   无 JS / 爬虫 / prefers-reduced-motion:reduce → 永远直接是最终状态,内容不丢。 */
@media (prefers-reduced-motion: no-preference){

/* ===== section 入场(IntersectionObserver 加 .anim-in;CSS 驱动;只动 transform/opacity)===== */
html.anim-ready [data-anim]{opacity:0;
  transition:opacity var(--anim-duration) var(--anim-easing),transform var(--anim-duration) var(--anim-easing)}
html.anim-ready [data-anim="fade-up"]{transform:translateY(24px)}
html.anim-ready [data-anim="scale-in"]{transform:scale(.96)}
html.anim-ready [data-anim].anim-in{opacity:1;transform:none}
/* 卡片行子元素错峰入场(JS 标 .anim-item 并给 --anim-i;入场完 .anim-done 清延迟,免得拖慢 hover) */
html.anim-ready [data-anim] .anim-item{opacity:0;transform:translateY(18px);
  transition:opacity var(--anim-duration) var(--anim-easing),transform var(--anim-duration) var(--anim-easing);
  transition-delay:calc(var(--anim-i,0)*var(--anim-stagger))}
html.anim-ready [data-anim].anim-in .anim-item{opacity:1;transform:none}
html.anim-ready [data-anim].anim-done .anim-item{transition-delay:0ms}

/* ===== section 内部微动效(全局旋钮,挂 body[data-anim-inner~=…])===== */
/* 卡片 hover 微抬升 */
body[data-anim-inner~="hover-lift"] :is(article,figure,.card,[class*="card"]){
  transition:transform calc(var(--anim-duration)*.5) var(--anim-easing)}
body[data-anim-inner~="hover-lift"] :is(article,figure,.card,[class*="card"]):hover{transform:translateY(-5px)}

/* CTA 呼吸微光(只在 CTA 段;发光壳是 ::after 静态 box-shadow,动画只呼吸 opacity) */
body[data-anim-inner~="cta-glow"] [data-anim-cta] :is(a[class*="btn"],a[class*="button"],a[href^="tel:"],button){position:relative}
body[data-anim-inner~="cta-glow"] [data-anim-cta] :is(a[class*="btn"],a[class*="button"],a[href^="tel:"],button)::after{
  content:"";position:absolute;inset:-5px;border-radius:inherit;pointer-events:none;
  box-shadow:0 0 24px 4px color-mix(in srgb, var(--color-primary,#3b82f6) 55%, transparent);
  opacity:.25;animation:anim-cta-breathe calc(var(--anim-duration)*5) var(--anim-easing) infinite}
@keyframes anim-cta-breathe{0%,100%{opacity:.2}50%{opacity:.8}}

}
