/* ==========================================================================
   FinanceTracker 全站动效层
   --------------------------------------------------------------------------
   背景：此前全站 17 个 CSS 文件里只有 login.css 与 review-weather.css 含
   @keyframes，其余页面（仪表盘、统计、预算、交易列表、编辑/删除表单页等）
   完全没有入场动画。本文件由 base.html 统一引入，提供一条共享动效基线。

   两条必须遵守的约束：
   1) 不使用 forwards/both 填充。动画结束后 computed transform 回到 none，
      否则 transform 会长期存在，为 position:fixed 后代（Bootstrap modal 是
      position:fixed）制造包含块，导致弹窗定位错乱。
   2) 含 modal/dialog 的容器只用纯 opacity 动画（见下方安全护栏）。opacity
      不产生包含块，无论动画是否结束都绝对安全。
   ========================================================================== */

:root {
    --motion-rise: 14px;
    --motion-duration: 0.44s;
    --motion-duration-fast: 0.3s;
    --motion-duration-slow: 0.62s;
    --motion-ease: cubic-bezier(0.22, 0.61, 0.36, 1);
    --motion-stagger-step: 0.05s;
}

@keyframes fttRiseIn {
    from { opacity: 0; transform: translateY(var(--motion-rise)); }
    to   { opacity: 1; transform: translateY(0); }
}

@keyframes fttFadeIn {
    from { opacity: 0; }
    to   { opacity: 1; }
}

@keyframes fttScaleIn {
    from { opacity: 0; transform: scale(0.965); }
    to   { opacity: 1; transform: scale(1); }
}

@keyframes fttGrowX {
    from { transform: scaleX(0); }
    to   { transform: scaleX(1); }
}

@keyframes fttSlideInStart {
    from { opacity: 0; transform: translateX(-12px); }
    to   { opacity: 1; transform: translateX(0); }
}

/* --------------------------------------------------------------------------
   1. 卡片入场：全站自动生效
   绝大多数页面（含 12 个编辑/删除表单页、统计 33 张卡、预算、动态、
   成就、导入流程）都使用 .card 作为内容容器，因此这一条即可覆盖全站。
   -------------------------------------------------------------------------- */
.card {
    animation: fttRiseIn var(--motion-duration) var(--motion-ease) backwards;
}

/* base.html 既有的 .fade-in-up 是显式工具类，优先级应高于上面的自动入场。
   加一个类提升特异性到 (0,2,0)，避免被 .card 覆盖而失效。 */
.card.fade-in-up {
    animation: fadeInUp var(--motion-duration-slow) var(--motion-ease) backwards;
}

/* --------------------------------------------------------------------------
   2. 网格错峰入场
   仅使用已核实的真实容器类（.summary-tile 之类只存在于 CSS、并未出现在
   模板标记中，不能作为选择器）。
   -------------------------------------------------------------------------- */
:is(
    .figures,
    .quick-grid,
    .statistics-totals,
    .achievement-grid,
    .briefing-metrics-grid,
    .chart-summary-grid,
    .budget-category-grid,
    .statistics-insights
) > * {
    animation: fttRiseIn var(--motion-duration) var(--motion-ease) backwards;
}

:is(
    .figures,
    .quick-grid,
    .statistics-totals,
    .achievement-grid,
    .briefing-metrics-grid,
    .chart-summary-grid,
    .budget-category-grid,
    .statistics-insights
) > *:nth-child(1) { animation-delay: calc(var(--motion-stagger-step) * 1); }
:is(
    .figures,
    .quick-grid,
    .statistics-totals,
    .achievement-grid,
    .briefing-metrics-grid,
    .chart-summary-grid,
    .budget-category-grid,
    .statistics-insights
) > *:nth-child(2) { animation-delay: calc(var(--motion-stagger-step) * 2); }
:is(
    .figures,
    .quick-grid,
    .statistics-totals,
    .achievement-grid,
    .briefing-metrics-grid,
    .chart-summary-grid,
    .budget-category-grid,
    .statistics-insights
) > *:nth-child(3) { animation-delay: calc(var(--motion-stagger-step) * 3); }
:is(
    .figures,
    .quick-grid,
    .statistics-totals,
    .achievement-grid,
    .briefing-metrics-grid,
    .chart-summary-grid,
    .budget-category-grid,
    .statistics-insights
) > *:nth-child(4) { animation-delay: calc(var(--motion-stagger-step) * 4); }
:is(
    .figures,
    .quick-grid,
    .statistics-totals,
    .achievement-grid,
    .briefing-metrics-grid,
    .chart-summary-grid,
    .budget-category-grid,
    .statistics-insights
) > *:nth-child(5) { animation-delay: calc(var(--motion-stagger-step) * 5); }
:is(
    .figures,
    .quick-grid,
    .statistics-totals,
    .achievement-grid,
    .briefing-metrics-grid,
    .chart-summary-grid,
    .budget-category-grid,
    .statistics-insights
) > *:nth-child(6) { animation-delay: calc(var(--motion-stagger-step) * 6); }
/* 第 7 个起统一延迟，避免长列表末尾等待过久 */
:is(
    .figures,
    .quick-grid,
    .statistics-totals,
    .achievement-grid,
    .briefing-metrics-grid,
    .chart-summary-grid,
    .budget-category-grid,
    .statistics-insights
) > *:nth-child(n + 7) { animation-delay: calc(var(--motion-stagger-step) * 6); }

/* --------------------------------------------------------------------------
   3. 进度条填充：从 0 横向展开到内联 width 指定的最终宽度
   （width 由模板内联样式给出，无法在 CSS 中得知，故用 scaleX 实现）
   -------------------------------------------------------------------------- */
.achievement-progress-fill,
.progress-bar {
    transform-origin: left center;
    animation: fttGrowX 0.7s var(--motion-ease) backwards;
}

/* cyberpunk 主题下 .progress-bar 原本带流动动画，特异性更高会覆盖上面的填充；
   这里显式合并两条动画，保持主题效果同时保留填充入场。 */
html[data-theme="cyberpunk"] .progress-bar {
    animation:
        cyberProgressFlow 2.8s ease-in-out infinite,
        fttGrowX 0.7s var(--motion-ease) backwards;
}

/* --------------------------------------------------------------------------
   4. 安全护栏
   容器一旦包含 modal/dialog，就把位移动画降级为纯透明度动画。
   （当前全站 modal 均为 .card 的兄弟节点，此规则是面向后续改动的保险。）
   -------------------------------------------------------------------------- */
:is(.card, .compact-panel, .dashboard-main, .dashboard-side):has(.modal),
:is(.card, .compact-panel, .dashboard-main, .dashboard-side):has(dialog) {
    animation-name: fttFadeIn;
}

/* 需要完全关闭某个元素的自动入场时显式声明 */
.motion-none {
    animation: none !important;
}

/* --------------------------------------------------------------------------
   5. 显式工具类（供模板按需使用）
   -------------------------------------------------------------------------- */
.motion-rise  { animation: fttRiseIn var(--motion-duration) var(--motion-ease) backwards; }
.motion-fade  { animation: fttFadeIn var(--motion-duration) var(--motion-ease) backwards; }
.motion-scale { animation: fttScaleIn var(--motion-duration) var(--motion-ease) backwards; }
.motion-slide { animation: fttSlideInStart var(--motion-duration) var(--motion-ease) backwards; }

/* --------------------------------------------------------------------------
   6. 减弱动效
   base.html 此前完全没有 prefers-reduced-motion 保护，而全站最广泛使用的
   过渡（.card/.btn/.form-control）正来自 base.html。此处补齐全局守卫。
   用极短时长而非 animation:none，以便依赖 animationend 的脚本仍能触发。
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-delay: 0ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}
