/**
 * 動態系統（Motion System）— 全站共用的節奏、曲線與轉場
 *
 * 載入位置：兩個路由都緊接在 base.css 之後（見 src/lib/assets.ts），之後的
 * 每一支樣式表都能引用這裡的 token。JS 端的對應模組是 js/utils/motion.js，
 * 它在執行期從這裡讀曲線（getComputedStyle），兩邊不必各寫一份數值。
 *
 * 三條原則，改動畫前先對照：
 *
 * 1. 只動合成層屬性：transform／translate／scale／opacity（必要時 clip-path）。
 *    width、height、left、top、box-shadow、background-position 的動畫每一幀都要
 *    重排或重繪；在上百列的表格頁上，一條無限循環的 box-shadow 就足以讓捲動掉幀。
 * 2. 進場慢、退場快：進場用 ease-out（快速起步、柔軟落地），退場用 ease-in 且
 *    時長約為進場的六成。使用者要的是「它不見了」，不是看它慢慢離開。
 * 3. 狀態切換用 transition，裝飾性循環才用 animation：transition 能在半途被打斷
 *    並從當下位置反向，快速連點不會跳格；animation 被打斷時會從頭播。
 *
 * 通用進場動畫請用獨立的 translate／scale 屬性而不是 transform：
 * 大量既有元件把 transform 拿去做定位（例如 translateY(-50%) 置中），
 * 進場動畫若寫 transform 會在播放期間蓋掉它，結束時再跳回原位。
 */

:root {
    /* ── 時長 ───────────────────────────────────────── */
    --motion-instant: 90ms;   /* 按下回饋 */
    --motion-fast: 160ms;     /* hover、顏色、小元件退場 */
    --motion-base: 240ms;     /* 一般狀態切換 */
    --motion-medium: 320ms;   /* 下拉選單、手風琴、面板 */
    --motion-slow: 420ms;     /* 彈窗進場、頁面區塊進場 */
    --motion-slower: 600ms;   /* 主題切換、大範圍編排 */
    /* 彈簧曲線前段就走完九成、後段是細微的回彈與收斂，時長要給足，
       否則尾巴被截掉會像是突然煞停 */
    --motion-spring: 560ms;

    /* ── 曲線 ───────────────────────────────────────── */
    /* 一般用途（Material 3 emphasized 的近似）：起步明確、收尾很長 */
    --ease-standard: cubic-bezier(0.2, 0, 0, 1);
    /* 進場 */
    --ease-out-quart: cubic-bezier(0.25, 1, 0.5, 1);
    --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
    /* 退場 */
    --ease-in-quart: cubic-bezier(0.5, 0, 0.75, 0);
    /* 兩端都在畫面內的位移（例如主題切換的圓形展開） */
    --ease-in-out-quart: cubic-bezier(0.76, 0, 0.24, 1);

    /* 阻尼彈簧（由阻尼比取樣產生，收斂門檻 0.2%）：
       spring        ζ=0.72，回彈約 3.8%——彈窗、下拉、Toast
       spring-soft   ζ=0.90，回彈約 0.15%——面板、指示條，只要物理感不要彈
       spring-bouncy ζ=0.50，回彈約 16%——徽章、勾選、小圖示的「啵」一下 */
    --ease-spring: linear(0, 0.0195, 0.0704, 0.1427, 0.2281, 0.3201, 0.4136, 0.5047, 0.5907, 0.6697, 0.7405, 0.8026, 0.856, 0.901, 0.938, 0.9677, 0.991, 1.0086, 1.0213, 1.0299, 1.0352, 1.0378, 1.0384, 1.0373, 1.0352, 1.0323, 1.0289, 1.0254, 1.0218, 1.0183, 1.0151, 1.0121, 1.0095, 1.0071, 1.0052, 1.0035, 1.0021, 1.001, 1.0002, 0.9996, 0.9991, 0.9988, 0.9986, 0.9985, 1);
    --ease-spring-soft: linear(0, 0.0208, 0.073, 0.1444, 0.226, 0.3114, 0.3959, 0.4766, 0.5516, 0.6197, 0.6806, 0.7343, 0.7809, 0.8209, 0.855, 0.8837, 0.9076, 0.9274, 0.9436, 0.9567, 0.9673, 0.9757, 0.9824, 0.9876, 0.9915, 0.9946, 0.9968, 0.9985, 0.9996, 1.0005, 1.001, 1.0013, 1.0015, 1.0015, 1.0015, 1.0014, 1);
    --ease-spring-bouncy: linear(0, 0.0238, 0.0877, 0.1804, 0.292, 0.4134, 0.5372, 0.657, 0.7682, 0.8675, 0.9527, 1.0228, 1.0776, 1.1177, 1.1442, 1.1587, 1.163, 1.159, 1.1484, 1.1332, 1.1149, 1.0951, 1.0749, 1.0554, 1.0373, 1.0212, 1.0074, 0.996, 0.9872, 0.9807, 0.9764, 0.9741, 0.9734, 0.9741, 0.9759, 0.9784, 0.9813, 0.9846, 0.9879, 0.991, 0.994, 0.9966, 0.9988, 1.0007, 1.0021, 1.0032, 1.0039, 1.0042, 1.0043, 1.0042, 1.0039, 1.0035, 1.003, 1.0025, 1.002, 1.0014, 1);

    /* 依序進場時每個元素的間隔 */
    --stagger-step: 30ms;

    /* base.css 既有的三個 token 改用新曲線（auth.css 與連結色仍在引用） */
    --transition-fast: var(--motion-fast) var(--ease-out-quart);
    --transition-normal: var(--motion-base) var(--ease-out-quart);
    --transition-slow: var(--motion-slower) var(--ease-out-quart);
}

/* 不支援 linear() 的瀏覽器：退回外觀相近的 cubic-bezier。
   不能讓變數留著 linear()——整條 transition 宣告會在計算值階段失效，動畫整個消失 */
@supports not (transition-timing-function: linear(0, 1)) {
    :root {
        --ease-spring: cubic-bezier(0.34, 1.3, 0.64, 1);
        --ease-spring-soft: cubic-bezier(0.22, 1, 0.36, 1);
        --ease-spring-bouncy: cubic-bezier(0.34, 1.56, 0.64, 1);
    }
}

/* ══════════════════════════════════════════════════════════════════════
   通用關鍵影格（各元件共用；名稱一律 motion- 前綴，避免與既有同名影格互蓋——
   站內已經有三份不同內容的 @keyframes fadeIn，後載入的那份會默默覆蓋前面的）
   ══════════════════════════════════════════════════════════════════════ */

@keyframes motion-fade-in {
    from { opacity: 0; }
}

@keyframes motion-fade-out {
    to { opacity: 0; }
}

/* 由下方浮入；距離可由 --motion-enter-distance 覆寫 */
@keyframes motion-enter-up {
    from {
        opacity: 0;
        translate: 0 var(--motion-enter-distance, 0.75rem);
    }
}

/* 縮放進場（彈窗、浮層） */
@keyframes motion-scale-in {
    from {
        opacity: 0;
        scale: var(--motion-enter-scale, 0.96);
    }
}

/* 小元件的「啵」一下（搭配 --ease-spring-bouncy） */
@keyframes motion-pop-in {
    from {
        opacity: 0;
        scale: 0.4;
    }
}

/* 骨架屏掃光：只移動偽元素，不動 background-position（後者每一幀都要重繪） */
@keyframes motion-shimmer {
    from { translate: -100% 0; }
    to { translate: 100% 0; }
}

/* ══════════════════════════════════════════════════════════════════════
   View Transitions
   ══════════════════════════════════════════════════════════════════════

   只用在兩個地方：跨文件的「登入頁 ⇄ 後台」淡化，以及主題切換的圓形展開
   （由 js/utils/motion.js 的 withViewTransition() 觸發，轉場期間在 <html> 掛上
   vt-theme）。

   切頁與側欄收合刻意不用：實測擷取主內容區快照的成本，在 CPU 降速兩倍時每次
   都會在動作起點多掉一到三幀，比單純的逐區進場與寬度過渡更不順。主題切換一年
   按不了幾次、而且本來就要整頁重算樣式，快照成本相對可以忽略。 */

/* 跨文件轉場（登入頁 ⇄ 後台）：兩邊都載入本檔，同源導向時交叉淡化 */
@view-transition {
    navigation: auto;
}

::view-transition-old(root) {
    animation: motion-fade-out var(--motion-fast) var(--ease-in-quart) both;
}

::view-transition-new(root) {
    animation: motion-fade-in var(--motion-base) var(--ease-out-quart) both;
}

/* 登入成功離開時，登入卡片被擷取成獨立的一層（auth.css 的 .auth-leaving），在後台
   淡入的同時往上收合。轉場動畫由「新頁面」的樣式決定，而後台不載入 auth.css，
   所以這段必須放在兩個路由共用的本檔 */
::view-transition-old(auth-card) {
    animation: motion-vt-auth-card-out var(--motion-fast) var(--ease-in-quart) both;
}

@keyframes motion-vt-auth-card-out {
    to {
        opacity: 0;
        translate: 0 -0.75rem;
        scale: 0.96;
    }
}

/* 轉場期間讓指標穿透到底下的真實頁面，不會吃掉轉場中的點擊 */
::view-transition {
    pointer-events: none;
}

/* ── vt-theme ────────────────────────────────────── */
/* 新主題以圓形從切換鈕展開；圓心與半徑由 theme.js 寫在 <html> 的
   --vt-theme-x／--vt-theme-y／--vt-theme-r 上（偽元素繼承自 <html>） */
html.vt-theme::view-transition-old(root),
html.vt-theme::view-transition-new(root) {
    animation: none;
    /* 預設的 plus-lighter 會讓重疊區顏色相加變亮，兩張都是不透明的整頁快照，
       必須改回一般合成 */
    mix-blend-mode: normal;
}

html.vt-theme::view-transition-new(root) {
    animation: motion-vt-theme-reveal var(--motion-slower) var(--ease-in-out-quart) both;
}

@keyframes motion-vt-theme-reveal {
    from {
        clip-path: circle(0 at var(--vt-theme-x, 50%) var(--vt-theme-y, 0%));
    }
    to {
        clip-path: circle(var(--vt-theme-r, 150%) at var(--vt-theme-x, 50%) var(--vt-theme-y, 0%));
    }
}

/* 轉場期間關閉所有 transition：新主題的快照是即時畫面，若元件各自以
   0.2～0.3 秒補間顏色，圓形展開的區域內會看到一片正在變色的半成品。
   移除這條規則時不會補播（transition 只在屬性值變化的當下觸發）。 */
html.vt-theme *,
html.vt-theme *::before,
html.vt-theme *::after,
html.theme-switching *,
html.theme-switching *::before,
html.theme-switching *::after {
    transition: none !important;
}

/* ══════════════════════════════════════════════════════════════════════
   減少動態偏好
   ══════════════════════════════════════════════════════════════════════

   作業系統開啟「減少動態效果」時，位移與縮放一律取消。時長設 1ms 而不是 0：
   0 秒的 transition 不會觸發 transitionend，依賴該事件收尾的程式會卡住。

   載入指示（轉圈）例外保留：它傳達的是「系統正在工作」，停住的轉圈圖示
   看起來像當機。 */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 1ms !important;
        animation-delay: 0ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 1ms !important;
        transition-delay: 0ms !important;
        scroll-behavior: auto !important;
    }

    html {
        scroll-behavior: auto !important;
    }

    .fa-spin,
    .fa-spinner,
    .refresh-overlay i,
    .spinner-ring,
    .btn.refreshing i,
    .deploy-refresh-btn.spinning i,
    .task-status-icon.building {
        animation-duration: 1.2s !important;
        animation-iteration-count: infinite !important;
    }

    ::view-transition-group(*),
    ::view-transition-old(*),
    ::view-transition-new(*) {
        animation: none !important;
    }
}
