/* =============================================================================
   effects.css —— 人生模拟器 · 夜色氛围动效资产（可复用轻量动画）
   -----------------------------------------------------------------------------
   原理 / 定位：
     把过场动效的关键帧 + 可复用 class 集中在一处，供前端给任意 DOM 或内联 SVG
     元素挂载。配套的独立 .svg（loading-stars / year-transition / comet /
     pulse-node / ember-rise）已自带 SMIL 动画，可直接 <img> 使用；本文件用于
     在页面里给"已有元素"加同款氛围动效，避免重复造轮子。

   性能铁律（务必遵守）：
     - 只动 transform 和 opacity —— 二者不触发 layout/paint，由合成线程处理，最省电。
     - 不要给 width/height/top/left/margin/box-shadow/filter 做动画（会重排重绘、掉帧）。
     - 需要发光感时用"半透明渐变图层 + opacity 动画"模拟，别动 filter/box-shadow。
     - 高频动画元素可加 `will-change: transform, opacity;`（仅对确实在动的元素，别滥用）。

   无障碍降级：
     文件末尾统一 `@media (prefers-reduced-motion: reduce)`：关闭/弱化所有动画，
     把元素落到一个安静的静止态（可见但不动），照顾前庭敏感用户。

   通用用法：
     给元素加对应 class 即可，例如：
       <div class="anim-breathe">…</div>
       <img class="anim-float" src="/static/art/cosmos/nebula.svg">
     可用 CSS 变量微调时长/幅度（见各 class 注释），如：
       style="--breathe-dur: 3s; --breathe-scale: 1.06"
   ========================================================================== */


/* -----------------------------------------------------------------------------
   1) @keyframes 关键帧定义（全部仅用 transform / opacity）
   -------------------------------------------------------------------------- */

/* 呼吸：缩放 + 透明度同步起伏（loading / 在世节点 / 高亮强调） */
@keyframes anim-breathe {
  0%, 100% { transform: scale(var(--breathe-min, 0.9));  opacity: var(--breathe-opacity-min, 0.6); }
  50%      { transform: scale(var(--breathe-max, 1.08)); opacity: 1; }
}

/* 漂浮：上下轻微浮动（星云/卡片/装饰元素的"悬浮感"） */
@keyframes anim-float {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(var(--float-dist, -8px)); }
}

/* 微光扫过：一束高光从左滑到右（配合渐变背景做"翻年/扫光"质感） */
@keyframes anim-shimmer {
  0%   { transform: translateX(-120%); }
  100% { transform: translateX(120%); }
}

/* 淡入上浮：进入视图时由下方淡入（条目/卡片入场） */
@keyframes anim-fade-up {
  0%   { transform: translateY(var(--fade-up-dist, 16px)); opacity: 0; }
  100% { transform: translateY(0); opacity: 1; }
}

/* 脉冲扩散：从中心向外放大并淡出（星图"在世"信号涟漪） */
@keyframes anim-pulse {
  0%   { transform: scale(0.4); opacity: 0.7; }
  100% { transform: scale(1);   opacity: 0; }
}

/* 流星划过：斜向位移并在中段显形（星空点睛） */
@keyframes anim-comet {
  0%        { transform: translate(0, 0);        opacity: 0; }
  10%       { opacity: 1; }
  70%       { opacity: 1; }
  100%      { transform: translate(var(--comet-x, 320px), var(--comet-y, 160px)); opacity: 0; }
}

/* 余烬上升：自下而上飘散并淡出（燃尽/落幕） */
@keyframes anim-ember {
  0%   { transform: translateY(0)   translateX(0);                      opacity: 0; }
  15%  { opacity: 0.9; }
  70%  { opacity: 0.9; }
  100% { transform: translateY(var(--ember-rise, -300px)) translateX(var(--ember-drift, 8px)); opacity: 0; }
}

/* 缓慢自转（可选：星图/光环极慢旋转，纯氛围） */
@keyframes anim-spin {
  0%   { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}


/* -----------------------------------------------------------------------------
   2) 可复用 class（挂到元素上即生效）
      每个 class 都说明：用途 + 怎么用 + 可调变量。
   -------------------------------------------------------------------------- */

/*
  .anim-breathe —— 呼吸
  用途：loading 占位、"在世"节点核心、需要轻柔强调的元素。
  用法：<span class="anim-breathe">●</span>
  可调：--breathe-dur(默认2.4s) / --breathe-min(0.9) / --breathe-max(1.08) / --breathe-opacity-min(0.6)
  注意：以元素中心缩放，建议给行内元素加 display:inline-block。
*/
.anim-breathe {
  animation: anim-breathe var(--breathe-dur, 2.4s) ease-in-out infinite;
  transform-origin: center;
  will-change: transform, opacity;
}

/*
  .anim-float —— 悬浮漂浮
  用途：星云背景、结局卡、装饰元素的"漂浮感"。
  用法：<img class="anim-float" src="…/cosmos/xxx.svg">
  可调：--float-dur(默认6s) / --float-dist(默认-8px，越大浮动越明显)
  注意：多个元素并排时用 animation-delay 错峰更自然。
*/
.anim-float {
  animation: anim-float var(--float-dur, 6s) ease-in-out infinite;
  will-change: transform;
}

/*
  .anim-shimmer —— 微光扫过（翻年/高光质感）
  用途：年份切换横幅、按钮/卡片的高光掠过。
  用法：把它放在一个 overflow:hidden 的相对定位容器内，作为一束高光条：
        <div class="shimmer-wrap"><span class="anim-shimmer"></span></div>
        .shimmer-wrap{position:relative;overflow:hidden}
        .anim-shimmer{position:absolute;inset:0;
          background:linear-gradient(100deg,transparent 40%,rgba(244,201,138,.7) 50%,transparent 60%)}
  可调：--shimmer-dur(默认2.6s)。需要"间歇"可改成 infinite + 较长 dur 或加 delay。
  注意：务必容器 overflow:hidden，否则高光会溢出。
*/
.anim-shimmer {
  animation: anim-shimmer var(--shimmer-dur, 2.6s) cubic-bezier(0.45, 0, 0.2, 1) infinite;
  will-change: transform;
}

/*
  .anim-fade-up —— 淡入上浮（入场）
  用途：列表项、信件、卡片进入视图时的入场动画。
  用法：<li class="anim-fade-up" style="animation-delay:.08s">…</li>
        多条目按序加 delay 形成"逐条浮现"。
  可调：--fade-up-dur(默认0.5s) / --fade-up-dist(默认16px)
  注意：这是"一次性"动画（forwards 保留末态）；若元素初始就在视口，直接生效。
*/
.anim-fade-up {
  animation: anim-fade-up var(--fade-up-dur, 0.5s) cubic-bezier(0.22, 1, 0.36, 1) both;
  will-change: transform, opacity;
}

/*
  .anim-pulse —— 脉冲涟漪
  用途：星图"在世"节点向外扩散的信号环；也可做"新消息/未读"提示。
  用法：在节点上叠一个绝对定位的圆环并加此类（通常放两个、错峰 delay）：
        <span class="anim-pulse"></span>  // 自身是个 border 圆
  可调：--pulse-dur(默认2.8s)
  注意：放多个时用 animation-delay 错峰（如 0s / 1.4s）；以中心缩放。
*/
.anim-pulse {
  animation: anim-pulse var(--pulse-dur, 2.8s) cubic-bezier(0.2, 0.6, 0.4, 1) infinite;
  transform-origin: center;
  will-change: transform, opacity;
}

/*
  .anim-comet —— 流星划过
  用途：星空背景里斜划而过的流星点缀。
  用法：<span class="anim-comet"></span>（自身可用渐变做出"头+尾"）。
  可调：--comet-dur(默认4.5s) / --comet-x(横向位移) / --comet-y(纵向位移)
  注意：建议放在 overflow:hidden 的星空容器内；多颗错峰 delay。
*/
.anim-comet {
  animation: anim-comet var(--comet-dur, 4.5s) cubic-bezier(0.3, 0, 0.5, 1) infinite;
  will-change: transform, opacity;
}

/*
  .anim-ember —— 余烬上升
  用途：燃尽/死亡/落幕场景里点点余烬自下而上飘散。
  用法：在场景底部放若干小圆点，逐个加此类 + 错峰 delay：
        <i class="anim-ember" style="animation-delay:1.1s"></i>
  可调：--ember-dur(默认7s) / --ember-rise(上升距离,默认-300px) / --ember-drift(横向飘移,默认8px)
  注意：哀伤场景，节奏要慢（dur 偏大）、数量克制；降级见文末。
*/
.anim-ember {
  animation: anim-ember var(--ember-dur, 7s) cubic-bezier(0.3, 0, 0.7, 1) infinite;
  will-change: transform, opacity;
}

/*
  .anim-spin-slow —— 极慢自转（可选氛围）
  用途：星图/光环/徽章外环的缓慢旋转，几乎察觉不到的呼吸式转动。
  用法：<g class="anim-spin-slow"> … </g>（内联 SVG 分组，注意设 transform-origin）
  可调：--spin-dur(默认60s)
  注意：内联 SVG 需 transform-box: fill-box; transform-origin: center; 才以自身为轴。
*/
.anim-spin-slow {
  animation: anim-spin var(--spin-dur, 60s) linear infinite;
  transform-box: fill-box;
  transform-origin: center;
  will-change: transform;
}


/* -----------------------------------------------------------------------------
   3) 辅助：动画延迟工具类（用于"逐条浮现"/错峰脉动，避免写内联 style）
   -------------------------------------------------------------------------- */
.anim-delay-1 { animation-delay: 0.1s; }
.anim-delay-2 { animation-delay: 0.2s; }
.anim-delay-3 { animation-delay: 0.3s; }
.anim-delay-4 { animation-delay: 0.4s; }
.anim-delay-5 { animation-delay: 0.5s; }


/* -----------------------------------------------------------------------------
   4) 无障碍降级：尊重系统"减少动态效果"偏好
      统一关闭循环动画、把一次性入场动画瞬时落到末态（可见但不动）。
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .anim-breathe,
  .anim-float,
  .anim-shimmer,
  .anim-pulse,
  .anim-comet,
  .anim-ember,
  .anim-spin-slow {
    animation: none !important;
  }

  /* 一次性入场动画：跳过过程，直接呈现最终可见态 */
  .anim-fade-up {
    animation: none !important;
    transform: none !important;
    opacity: 1 !important;
  }

  /* 把"显形类"动效落到安静的可见态，避免内容因 opacity:0 而消失 */
  .anim-comet,
  .anim-ember {
    opacity: 0 !important; /* 这两类是纯氛围点缀，静止时直接隐藏，最克制 */
  }
}
