/* ============================================================
   motion.css — 全站的動畫

   整站的動態效果只在這一支。不喜歡就把 index.html 裡這一行 <link>
   刪掉，其他什麼都不用改，畫面會回到完全靜態但功能一模一樣。

   ── 三條原則 ──

   1. 動畫只做「進場」跟「狀態變化」，不做裝飾。
      每一個動作都要在回答一個問題：東西從哪來的？剛剛什麼變了？

   2. 不碰版面。這支只寫 opacity / transform / animation-delay 這類
      不影響排版計算的屬性。特別是電腦版有兩張卡片是 position: sticky，
      在它們身上加 transform 會讓固定定位算錯，所以卡片一律不動。

   3. 快。進場 220–380ms，狀態變化 120ms。
      使用者是來調色的，不是來看動畫的。

   ── 一列一列跑出來是怎麼做的 ──
   JS 在每個元素上寫一個序號 --i（第幾組配方）跟 --j（第幾行顏料），
   CSS 用它算 animation-delay。時間全部在 CSS 這裡調，JS 不管時間。
   ============================================================ */


/* ---------- 時間與曲線 ---------- */

:root {
  --t-fast: 120ms;    /* 狀態變化：hover、按下、顏色換掉 */
  --t-base: 220ms;    /* 一般進場 */
  --t-slow: 380ms;    /* 主角進場 */

  /* 尾巴慢下來的曲線，收尾比較穩，不會有煞車感 */
  --ease: cubic-bezier(.22, .61, .36, 1);

  /* 一列跟下一列差幾毫秒 */
  --stagger-res: 90ms;   /* 配方與配方之間 */
  --stagger-row: 50ms;   /* 同一組配方裡，顏料行與行之間 */
}


/* ---------- 共用的 keyframes ---------- */

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

@keyframes rise-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

@keyframes slide-in {
  from { opacity: 0; transform: translateX(-8px); }
  to   { opacity: 1; transform: none; }
}


/* ============================================================
   1. 換分頁
   ============================================================ */

/* 只淡入，不位移。
   .page 底下有 sticky 的卡片，在祖先身上放 transform 會讓 sticky
   的定位基準跑掉，所以這一層碰都不要碰。 */
.page.on {
  animation: fade-in var(--t-base) var(--ease) both;
}

.tabs > button,
.modes button {
  transition: background-color var(--t-base) var(--ease),
              color var(--t-base) var(--ease);
}


/* ============================================================
   2. 按鈕與輸入元件
   ============================================================ */

.btn {
  transition: background-color var(--t-fast) var(--ease),
              border-color var(--t-fast) var(--ease),
              color var(--t-fast) var(--ease),
              transform var(--t-fast) var(--ease);
}

/* 按下去要有回饋，不然不知道到底有沒有按到 */
.btn:active {
  transform: translateY(1px);
}

.btn.primary[disabled]:active {
  transform: none;
}

/* 「計算中…」會卡住幾百毫秒，讓它呼吸一下，才不會像當掉 */
.btn.primary[disabled] {
  animation: calculating 1.1s ease-in-out infinite;
}

@keyframes calculating {
  0%, 100% { opacity: .35; }
  50%      { opacity: .62; }
}

.x,
.drop,
input[type=range]::-webkit-slider-thumb,
.pl {
  transition: background-color var(--t-fast) var(--ease),
              border-color var(--t-fast) var(--ease),
              color var(--t-fast) var(--ease);
}


/* ============================================================
   3. 顏色換掉的時候平滑過去

   拉滑桿時顏色是一格一格跳的，補 120ms 會順很多。
   不要再長了 —— 再長就會跟不上手指，變成「顏色慢半拍」。
   ============================================================ */

.result,
.target,
.sw,
.dot,
.bdot,
.compare-swatches b,
.bar i {
  transition: background-color var(--t-fast) linear;
}


/* ============================================================
   4. 調色：配方列
   ============================================================ */

.mixrow {
  animation: slide-in var(--t-base) var(--ease) both;
  animation-delay: calc(var(--i, 0) * 40ms);
}


/* ============================================================
   5. 漆櫃：一罐一罐排進去
   ============================================================ */

.pl {
  animation: slide-in var(--t-base) var(--ease) both;
  animation-delay: calc(var(--i, 0) * 28ms);
}


/* ============================================================
   6. 反查結果：一組一組、一列一列跑出來

   時間軸（第 n 組配方，n 從 0 起算）：
     n×90ms         整組浮上來
     n×90ms + 60    兩塊比較色出現
     n×90ms + 160   比例條從左邊拉開
     n×90ms + 220   三個差異點從中線飛到定位
     n×90ms + 200   顏料行開始，每行再差 50ms
   ============================================================ */

/* 上面那行「數字是 Lab 色差單位…」 */
#out > .note {
  animation: fade-in var(--t-base) var(--ease) both;
}

.res {
  animation: rise-in var(--t-slow) var(--ease) both;
  animation-delay: calc(var(--i, 0) * var(--stagger-res));
}

.compare-swatches {
  animation: fade-in var(--t-slow) var(--ease) both;
  animation-delay: calc(var(--i, 0) * var(--stagger-res) + 60ms);
}

/* 比例條從左邊拉開，長度就是配方比例 */
.bar {
  transform-origin: left center;
  animation: bar-open var(--t-slow) var(--ease) both;
  animation-delay: calc(var(--i, 0) * var(--stagger-res) + 160ms);
}

@keyframes bar-open {
  from { transform: scaleX(0); opacity: .3; }
  to   { transform: none; opacity: 1; }
}

/* 差異點從中線（＝跟目標一樣）飛到它實際偏掉的位置。
   起點是「沒有差」，終點是「差這麼多」，這段位移本身就是在講差多少。
   位置由 JS 寫在 --pos 上，時間在這裡調。 */
.diff-mark {
  animation: diff-mark-out var(--t-slow) var(--ease) both;
  animation-delay: calc(var(--i, 0) * var(--stagger-res) + 220ms);
}

@keyframes diff-mark-out {
  from { left: 50%; opacity: .35; }
  to   { left: var(--pos, 50%); opacity: 1; }
}

.diff-name,
.diff-text {
  animation: fade-in var(--t-base) var(--ease) both;
  animation-delay: calc(var(--i, 0) * var(--stagger-res) + 220ms);
}

/* 顏料一行一行進來。--i 是第幾組配方（從 .res 繼承下來的），
   --j 是這組裡的第幾行。 */
.fl {
  animation: slide-in var(--t-base) var(--ease) both;
  animation-delay: calc(
    var(--i, 0) * var(--stagger-res) + 200ms + var(--j, 0) * var(--stagger-row)
  );
}


/* ============================================================
   7. 取色準心

   準心的 left / top 絕對不能加 transition —— 那是跟著手指走的，
   補間會讓它黏在手指後面。只有第一次出現時彈一下。
   ============================================================ */

.marker {
  animation: marker-pop var(--t-base) var(--ease) both;
}

@keyframes marker-pop {
  from { opacity: 0; transform: translate(-50%, -50%) scale(.55); }
  to   { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}

.pickhint {
  transition: color var(--t-base) var(--ease);
}


/* ============================================================
   8. 系統設定「減少動態效果」時全部關掉

   有些人會因為畫面移動頭暈。這是作業系統層級的設定，要尊重。

   用「時間縮到幾乎是 0」而不是 animation: none，是因為上面很多動畫
   靠 fill-mode 決定最終狀態（例如差異點的 left 位置）。
   直接 none 掉的話那些元素會跑到錯的地方。
   ============================================================ */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: .001ms !important;
    animation-delay: 0ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    transition-delay: 0ms !important;
  }
}
