/* es6-fx.css — 覺知全人測評 互動與動態層（2026-08-23）
 *
 * 鐵則：只做視覺與動態，不新增、不修改任何一個字。
 *       只動 transform / opacity / box-shadow / background，不動會觸發重排的屬性。
 *       所有效果都可被 prefers-reduced-motion 關掉。
 */

:root {
  --fx-ease: cubic-bezier(.32, .72, 0, 1);   /* 有質量、收得住的曲線，不用 ease-in-out */
  --fx-pop: cubic-bezier(.34, 1.4, .64, 1);  /* 輕微回彈，用在小圓點 */
  --fx-fast: .26s;
  --fx-mid: .5s;
  --fx-slow: .85s;
}

/* ── 可點擊元素：按下去要有回應 ─────────────────────────────── */
.tap,
.jnav,
a[href] {
  transition: transform var(--fx-fast) var(--fx-ease),
              box-shadow var(--fx-fast) var(--fx-ease),
              background-color var(--fx-fast) var(--fx-ease),
              color var(--fx-fast) var(--fx-ease);
}
.tap:hover,
.jnav:hover { transform: translateY(-2px); }
.tap:active,
.jnav:active { transform: translateY(0) scale(.98); }

/* ── 大卡片：浮起來、影子變深 ───────────────────────────────── */
.fx-card {
  transition: transform var(--fx-mid) var(--fx-ease),
              box-shadow var(--fx-mid) var(--fx-ease);
  will-change: transform;
}
.fx-card:hover {
  transform: translateY(-5px);
  box-shadow: 0 18px 40px rgba(65, 51, 42, .15);
}

/* ── 插圖：滑過會輕輕轉一下、浮起來 ─────────────────────────── */
.fx-doodle {
  transition: transform var(--fx-slow) var(--fx-ease);
  will-change: transform;
}
.fx-doodle:hover { transform: translateY(-7px) rotate(-3deg) scale(1.05); }

/* 插圖進場：從下方浮起並轉正 */
.fx-doodle.fx-in { opacity: 0; transform: translateY(24px) rotate(-7deg) scale(.92); }
.fx-doodle.fx-in.fx-on {
  opacity: 1;
  transform: none;
  transition: opacity var(--fx-slow) var(--fx-ease), transform var(--fx-slow) var(--fx-ease);
}

/* ── 構面長條：從 0 長出來 ──────────────────────────────────── */
.fx-bar { transition: width 1.15s var(--fx-ease); }

/* ── 標記點：彈進來，滑過放大 ───────────────────────────────── */
.fx-dot { transition: transform .55s var(--fx-pop), opacity .35s ease; }
.fx-dot.fx-in { opacity: 0; transform: scale(.35); }
.fx-dot.fx-in.fx-on { opacity: 1; transform: none; }
.fx-dot:hover { transform: scale(1.22); z-index: 3; }

/* ── 狀態詞／構面關鍵字：滑過浮出同色淡底 ───────────────────── */
.fx-key {
  border-radius: 5px;
  padding: 1px 3px;
  margin: 0 -3px;
  transition: background-color var(--fx-fast) var(--fx-ease);
}
.fx-key:hover { background-color: var(--fx-key-soft, rgba(0, 0, 0, .05)); }

/* ── 三方建議：滑過往前推一點，圖示跟著動 ───────────────────── */
.fx-chip { transition: transform var(--fx-fast) var(--fx-ease); }
.fx-chip:hover { transform: translateX(3px); }
.fx-chip:hover .jz-adv-ic { transform: translateX(2px) scale(1.12); }
.jz-adv-ic { transition: transform var(--fx-fast) var(--fx-ease); }

/* ── 頂部列：捲動後浮起 ─────────────────────────────────────── */
.fx-topbar {
  transition: box-shadow var(--fx-mid) var(--fx-ease),
              background-color var(--fx-mid) var(--fx-ease);
}
.fx-topbar.fx-stuck { box-shadow: 0 6px 24px rgba(65, 51, 42, .11); }

/* ── 章節跳點：目前所在的那一顆放大 ─────────────────────────── */
.jnav { transition: transform var(--fx-fast) var(--fx-ease), box-shadow var(--fx-fast) var(--fx-ease); }
.jnav.fx-active {
  transform: scale(1.3);
  box-shadow: 0 4px 16px rgba(65, 51, 42, .34);
}
.jnav.fx-active:hover { transform: scale(1.34) translateY(-2px); }

/* ── 分數數字：跑動時用等寬數字，避免寬度跳動 ───────────────── */
.fx-num { font-variant-numeric: tabular-nums; }

/* ── 不喜歡動態的人，全部關掉 ───────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: .01ms !important;
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
  }
  .fx-card:hover,
  .fx-doodle:hover,
  .tap:hover,
  .jnav:hover,
  .fx-chip:hover { transform: none; }
  .fx-doodle.fx-in,
  .fx-dot.fx-in { opacity: 1; transform: none; }
}

/* ── 背景裝飾（KWJ 2026-08-23「太空了，但不要用太多插圖，可以有裝飾」）──
   只用三種材料：兩團極淡的品牌色光暈、一個細線圓、一層點陣。
   不加插圖、不加文字，永遠在內容底下且不吃點擊。
   --jz-a 由各章的主色帶入；沒帶就用品牌褐。 */
.jz-deco { position: relative; }
.jz-deco > * { position: relative; z-index: 1; }

.jz-deco::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  opacity: .07;
  background-image:
    radial-gradient(circle at 10% 16%, var(--jz-a, #b3855f) 0, transparent 46%),
    radial-gradient(circle at 90% 78%, var(--jz-a, #b3855f) 0, transparent 40%),
    radial-gradient(var(--jz-a, #b3855f) 1px, transparent 1.1px);
  background-size: auto, auto, 26px 26px;
  background-repeat: no-repeat, no-repeat, repeat;
}

/* 細線圓：只在桌機出現，手機版面已經夠滿 */
.jz-deco::after {
  content: "";
  position: absolute;
  pointer-events: none;
  z-index: 0;
  width: min(42vw, 460px);
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  border: 1.5px solid var(--jz-a, #b3855f);
  opacity: .09;
  left: -14%;
  bottom: -26%;
}
@media (max-width: 767px) {
  .jz-deco::after { display: none; }
  .jz-deco::before { opacity: .05; }
}

/* 構面卡的專屬插圖：靠右下、壓在文字之後，不搶內容 */
.jz-dimdoodle {
  position: absolute;
  right: 30px;
  bottom: 12px;
  width: clamp(190px, 21vw, 300px);
  max-height: 88%;
  height: auto;
  object-fit: contain;
  opacity: .82;
  pointer-events: none;
  z-index: 0;
  filter: drop-shadow(0 1px 0 #fff) drop-shadow(0 -1px 0 #fff);
  transition: transform .8s var(--fx-ease), opacity .4s ease;
}
[data-jz-card="read"]:hover .jz-dimdoodle { transform: translateY(-6px) rotate(-2.5deg) scale(1.03); opacity: .88; }
/* 手機：文字是滿版的，插圖要留出落腳處，卡片底部多留一點空間 */
@media (max-width: 767px) {
  .jz-dimdoodle { width: clamp(132px, 34vw, 168px); right: 12px; bottom: 10px; opacity: .68; max-height: 56%; }
  [data-jz-card="read"] { padding-bottom: 104px !important; }
}

/* ── 桌機：構面解讀／親子交叉／一週行動改成滿版（KWJ 2026-08-23「不要有左側或右側空白處」）
   原本是「190px 標籤欄 ＋ 704px 內容」的兩欄，右邊留一大塊空白。
   改成標籤在上、內容滿版，與 01–13 節、結果輪廓一致。 */
@media (min-width: 768px) {
  [data-jz-region="read"],
  [data-jz-region="cross"],
  [data-jz-region="act"] {
    flex-direction: column !important;
    gap: 14px !important;
  }
  [data-jz-region="read"] > *,
  [data-jz-region="cross"] > *,
  [data-jz-region="act"] > * {
    width: 100% !important;
    max-width: none !important;
    flex: 0 0 auto !important;
  }
  [data-jz-region="read"] > *:last-child,
  [data-jz-region="cross"] > *:last-child,
  [data-jz-region="act"] > *:last-child {
    flex: 1 1 auto !important;
  }
}

/* ── 區塊標題收緊（KWJ 2026-08-23「不喜歡這麼空」）──
   版型原本在 190px 窄欄裡放一張區塊級裝飾圖；改成滿版後那張圖孤零零地
   撐出一大片空白。每個構面卡現在都有自己的插圖，而且插圖不可重複，
   所以區塊級那張收掉，標題壓成一行。 */
/* 區塊大圖：不是關掉，是換位置。移到區塊標題那一行的右端並放大。
   （先前用 display:none 一次關掉 39 張圖——含 18 張區塊大圖與 21 張長文節內插圖，是錯的。） */
[data-jz-region] > div:has(> .rvT[style*="doodles/"]) {
  display: flex !important;
  align-items: center;
  gap: clamp(16px, 2.4vw, 34px);
  width: 100% !important;
  flex-wrap: wrap;
}
[data-jz-region] > div > .rvT[style*="doodles/"] {
  margin-left: auto !important;
  margin-top: 0 !important;
  width: clamp(200px, 21vw, 300px) !important;
  height: auto !important;
  aspect-ratio: 184 / 150;
  opacity: .92;
  flex: none;
}
/* 長文 01–13 節內插圖：桌機救回，手機維持隱藏（375px 塞進去會把標題擠成孤行） */
[data-jz-region="secs"] div[style*="doodles/"] {
  width: clamp(120px, 13vw, 168px) !important;
  height: auto !important;
  aspect-ratio: 122 / 90;
  opacity: .75;
}
@media (max-width: 767px) {
  [data-jz-region="secs"] div[style*="doodles/"] { display: none !important; }
  [data-jz-region] > div > .rvT[style*="doodles/"] {
    width: clamp(140px, 38vw, 190px) !important;
    margin-left: auto !important;
  }
  [data-jz-region] > div:has(> .rvT[style*="doodles/"]) { gap: 10px; }
}
@media (min-width: 768px) {
  [data-jz-region="read"] > div:not([data-jz-card]):not([style*="absolute"]):first-of-type,
  [data-jz-region="cross"] > div:not([data-jz-card]):not([style*="absolute"]),
  [data-jz-region="act"] > div:not([data-jz-card]):not([style*="absolute"]) {
    /* 眉標與大標同一行，去掉為了窄欄留的上緣空間 */
  }
  [data-jz-region] > div > div[class="rvW"],
  [data-jz-region] > div > div.rvW { margin-top: 4px !important; }
}

/* ══════════════════════════════════════════════════════════════════════
   閱讀節奏：讓 51,000px 的長報告有「快—慢—停」，不是一路都在動。
   每一區塊的性格靠「種類」區分，不靠時長參數（620ms 和 680ms 沒有人分得出來）。
   設計會議定版 2026-08-23。
   ══════════════════════════════════════════════════════════════════════ */

/* ── 結果輪廓：全篇唯一「不淡入」的區塊 ──
   一眼就知道這裡是看數據，不是讀散文。 */
[data-jz-region="profile"] .rv,
[data-jz-region="profile"] .rvL,
[data-jz-region="profile"] .rvW {
  opacity: 1 !important;
  transform: none !important;
}

/* ── 構面卡：全篇唯一「圖比字晚到」──
   卡片先安靜就位，插圖晚 220ms 才浮進來，成為每張卡的收尾動作。 */
@media (prefers-reduced-motion: no-preference) {
  [data-jz-card="read"] .jz-dimdoodle {
    opacity: 0;
    transform: translate3d(18px, 10px, 0) scale(.92);
  }
  [data-jz-card="read"].on .jz-dimdoodle,
  [data-jz-card="read"][data-armed] .jz-dimdoodle {
    opacity: .82;
    transform: none;
    transition: opacity .5s var(--fx-ease) .22s,
                transform .62s cubic-bezier(.24, .9, .3, 1.06) .22s;
  }
}

/* ── 一週行動：全篇唯一「由上往下掉」的方向 ──
   方向一反轉，不用讀標題就知道換段了。全報告只用這一次。 */
@media (prefers-reduced-motion: no-preference) {
  [data-jz-region="act"] .rv,
  [data-jz-region="act"] .rvp,
  [data-jz-region="act"] .rvB {
    transform: translate3d(0, -22px, 0);
    transition-duration: .42s !important;
  }
  [data-jz-region="act"] .rv.on,
  [data-jz-region="act"] .rvp.on,
  [data-jz-region="act"] .rvB.on { transform: none; }
}

/* ── 親子交叉：全篇唯一「向內收攏」──
   孩子欄從左、家長欄從右同時滑向中線。動作本身就是語意。 */
@media (prefers-reduced-motion: no-preference) {
  [data-jz-region="cross"] .rvL { transform: translate3d(-26px, 0, 0); }
  [data-jz-region="cross"] .rvR { transform: translate3d(26px, 0, 0); }
  [data-jz-region="cross"] .rvL.on,
  [data-jz-region="cross"] .rvR.on { transform: none; }
}

/* ── 長文 01–13：全篇唯一「幾乎不動」的靜音段 ──
   最違反直覺、但最關鍵的一拍。沒有它，前面幾種性格會被稀釋成「一路都在動」。
   正文一進視窗就是完成態，可以立刻讀，不必等動畫跑完。 */
[data-jz-region="secs"] .rvB,
[data-jz-region="secs"] .rvp,
[data-jz-region="secs"] .rvW,
[data-jz-region="secs"] .rvT,
[data-jz-region="secs"] .rv {
  opacity: 1 !important;
  transform: none !important;
  transition: none !important;
  clip-path: none !important;
}

/* ── 本章進度：全篇唯一「一直在」的元素 ──
   只顯示「這一章還剩多少」，不顯示全頁進度（那是製造焦慮不是解焦慮）。 */
.fx-topbar { position: relative; }
.fx-chapbar {
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 2.5px;
  background: var(--jz-a, #ff5a1a);
  transform-origin: left center;
  transform: scaleX(var(--p, 0));
  opacity: .9;
  pointer-events: none;
  transition: transform .18s linear, background-color .5s var(--fx-ease);
}

/* ── reduced-motion 的缺口：delay 也要歸零 ──
   只關 duration 不關 delay，會變成「沒有動作卻逐個延遲跳出來」，比原本更難受。 */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-delay: 0s !important;
    animation-delay: 0s !important;
  }
  .jz-dimdoodle { opacity: .82 !important; transform: none !important; }
  .fx-chapbar { transition: none !important; }
}

/* ── 列印：全頁幾百個元素初始 opacity:0，不處理就是印出一片空白 ── */
@media print {
  *, *::before, *::after {
    opacity: 1 !important;
    transform: none !important;
    animation: none !important;
    transition: none !important;
    clip-path: none !important;
  }
  .fx-chapbar, .jz-deco::before, .jz-deco::after { display: none !important; }
}

/* ── 掃入標題改用 transform（原本是 clip-path，不在 transform/opacity 白名單，
   而且卡住時整行字看不見）。內容看得到永遠優先於動畫。 */
.rvW {
  clip-path: none !important;
  opacity: 0;
  transform: translate3d(0, 10px, 0);
  transition: opacity .5s var(--fx-ease), transform .5s var(--fx-ease);
}
.rvW.on { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) { .rvW { opacity: 1; transform: none; } }

/* ── 章首換氣：全篇唯一「與捲動耦合」的段落 ──
   其他效果都是觸發一次就播完；只有這裡的進度由捲動位置決定——
   手指停住畫面就停住，往回捲會倒著播。全報告只出現六次，就是六個換氣點。
   用原生 scroll-driven，不寫任何 scroll listener。 */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .jz-chaphero {
      animation: jzChapHero linear both;
      animation-timeline: view();
      animation-range: entry 0% cover 42%;
    }
    @keyframes jzChapHero { from { transform: scale(1.06); } to { transform: none; } }

    .jz-chapno {
      animation: jzChapNo linear both;
      animation-timeline: view();
      animation-range: entry 10% entry 86%;
    }
    @keyframes jzChapNo {
      from { transform: scale(.72) rotate(-10deg); opacity: .35; }
      to   { transform: none; opacity: 1; }
    }
    @media (max-width: 767px) {
      /* 小螢幕上 6% 的推進會讀成晃動 */
      @keyframes jzChapHero { from { transform: scale(1.035); } to { transform: none; } }
    }
  }
}
/* iOS：非矩形圓角 ＋ overflow:hidden ＋ 內部 transform 會露出方角，強制自成合成層 */
.jz-blobfix { transform: translateZ(0); isolation: isolate; }

/* ── 入場層次：同一組元素依序到位，不是一起蹦出來 ──
   --i 由 es6-fx.js 依元素在容器內的序位寫入，最多到第 8 個就封頂，
   避免長清單的最後一項等太久。 */
[style*="--i"] { }
[data-jz-region="profile"] .fx-bar {
  transition-delay: calc(var(--i, 0) * 70ms + var(--who, 0) * 90ms);
}
[data-jz-region="profile"] .fx-dot {
  transition-delay: calc(var(--i, 0) * 70ms + var(--who, 0) * 90ms + 60ms);
}
[data-jz-region="cross"] .rvL,
[data-jz-region="cross"] .rvR {
  transition-delay: calc(var(--i, 0) * 70ms);
}
.jz-stag { transition-delay: calc(var(--i, 0) * 80ms) !important; }

/* 三方建議膠囊：卡片就位後才依序進場，讓「可以做的事」有先後感 */
@media (prefers-reduced-motion: no-preference) {
  .fx-chip {
    opacity: 0;
    transform: translate3d(0, 8px, 0);
    transition: opacity .38s var(--fx-ease) calc(var(--i, 0) * 90ms + .18s),
                transform .44s var(--fx-ease) calc(var(--i, 0) * 90ms + .18s);
  }
  .fx-chip.fx-on { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .fx-chip { opacity: 1 !important; transform: none !important; }
  .jz-chaphero, .jz-chapno { animation: none !important; transform: none !important; opacity: 1 !important; }
}

/* ── 可點的元素要看得出來可以點（不新增任何文字）────────────────── */
[data-jz-jump] {
  cursor: pointer;
  border-radius: 10px;
  transition: background-color var(--fx-fast) var(--fx-ease),
              transform var(--fx-fast) var(--fx-ease);
}
[data-jz-jump]:hover { background-color: rgba(255, 255, 255, .55); transform: translateX(3px); }
[data-jz-jump]:active { transform: translateX(1px) scale(.995); }
[data-jz-jump]:focus-visible,
.jnav:focus-visible,
.tap:focus-visible,
a:focus-visible {
  outline: 2.5px solid var(--jz-a, #ff5a1a);
  outline-offset: 3px;
  border-radius: 8px;
}

/* 跳過去之後，目標卡輕輕亮一下，讓人知道「就是這一張」 */
.jz-flash { animation: jzFlash 1.4s var(--fx-ease) 1; }
@keyframes jzFlash {
  0%   { box-shadow: 0 0 0 0 rgba(255, 90, 26, .55), 0 3px 14px rgba(65, 51, 42, .08); }
  40%  { box-shadow: 0 0 0 6px rgba(255, 90, 26, .16), 0 12px 30px rgba(65, 51, 42, .16); }
  100% { box-shadow: 0 0 0 0 rgba(255, 90, 26, 0), 0 3px 14px rgba(65, 51, 42, .08); }
}

/* 觸控回饋：手機沒有 hover，按下去要有反應 */
@media (hover: none) {
  [data-jz-card]:active,
  .fx-card:active { transform: scale(.988); }
  [data-jz-jump]:active { background-color: rgba(255, 255, 255, .7); }
}

@media (prefers-reduced-motion: reduce) {
  .jz-flash { animation: none !important; }
  [data-jz-jump]:hover { transform: none; }
}

/* ── 跳轉靜音：長距離跳章時，沿途的進場一律不播 ── */
.jz-quiet .rv, .jz-quiet .rvp, .jz-quiet .rvL, .jz-quiet .rvR,
.jz-quiet .rvS, .jz-quiet .rvB, .jz-quiet .rvW, .jz-quiet .rvT,
.jz-quiet .rvStag, .jz-quiet .fx-doodle, .jz-quiet .jz-dimdoodle {
  transition: none !important;
  animation: none !important;
}

/* ── 回到頂端：捲過一屏才出現 ── */
.jz-topbtn {
  opacity: 0;
  transform: scale(.7);
  pointer-events: none;
  transition: opacity .32s var(--fx-ease), transform .32s var(--fx-ease);
}
.jz-topbtn.jz-show { opacity: 1; transform: none; pointer-events: auto; }

/* ── 全人成長導航：全篇唯一的齊列網格，依序展開 ── */
@media (prefers-reduced-motion: no-preference) {
  .jz-insight {
    opacity: 0;
    transform: translate3d(0, 14px, 0) scale(.985);
    transition: opacity .46s var(--fx-ease) calc(var(--i, 0) * 85ms),
                transform .52s cubic-bezier(.22, .72, .3, 1) calc(var(--i, 0) * 85ms);
  }
  .jz-insight.on { opacity: 1; transform: none; }
}

/* ── 可及性：鍵盤與觸控都要有回饋 ── */
.fx-chip:active { transform: translateX(1px) scale(.99); }
.jnav:active { transform: scale(1.05); }

@media (prefers-reduced-motion: reduce) {
  .jz-insight { opacity: 1 !important; transform: none !important; }
  .jz-topbtn { opacity: 1; transform: none; pointer-events: auto; }
}

/* ══════════════════════════════════════════════════════════════════
   會動的背景裝飾（KWJ 2026-08-23）
   只動 transform／opacity；每個區塊最多一顆會動的東西；
   章底色是不透明的，所以裝飾必須放在區塊「裡面」才看得見。
   ══════════════════════════════════════════════════════════════════ */

/* ① 細線圓：極慢地轉，給畫面一點呼吸，不會讓人分心 */
@media (prefers-reduced-motion: no-preference) {
  .jz-deco-live::after {
    animation: jzRing 90s linear infinite;
  }
  @keyframes jzRing {
    from { transform: rotate(0deg) scale(1); }
    50%  { transform: rotate(180deg) scale(1.04); }
    to   { transform: rotate(360deg) scale(1); }
  }
}

/* ② 跟著游標走的光球：只在章首帶出現，一章一顆。
   用 transform 位移（合成層處理），不重繪漸層。 */
.jz-orb {
  position: absolute;
  left: 0; top: 0;
  width: clamp(260px, 30vw, 460px);
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  background: radial-gradient(circle, var(--jz-a, #ff5a1a) 0%, transparent 62%);
  opacity: .16;
  pointer-events: none;
  z-index: 0;
  margin: -15% 0 0 -15%;
  transform: translate3d(var(--ox, 30%), var(--oy, 20%), 0);
  transition: transform 1.1s cubic-bezier(.22, .61, .36, 1), opacity .6s ease;
}
/* 漂浮改用 transform：原本動 margin-top，每一幀都會觸發版面重算，長頁上必卡。
   外層負責跟游標、內層負責漂浮，兩層都只動 transform。 */
.jz-orb-in {
  width: 100%; height: 100%; border-radius: 50%;
  background: inherit;
}
@media (prefers-reduced-motion: no-preference) {
  .jz-orb-in { animation: jzFloat 16s ease-in-out infinite alternate; }
  @keyframes jzFloat {
    from { transform: translate3d(0, 0, 0); }
    to   { transform: translate3d(0, 6%, 0); }
  }
}
@media (hover: none) {
  /* 手機沒有游標，光球就純漂浮，位置固定在偏右上 */
  .jz-orb { --ox: 58%; --oy: 8%; opacity: .13; }
}

/* ③ 點陣層極緩慢地平移，讓底不是死的 */
@media (prefers-reduced-motion: no-preference) {
  .jz-deco-live::before { animation: jzDrift 34s ease-in-out infinite alternate; }
  @keyframes jzDrift {
    from { transform: translate3d(0, 0, 0); }
    to   { transform: translate3d(-14px, -10px, 0); }
  }
}

@media (prefers-reduced-motion: reduce) {
  .jz-deco::after, .jz-deco::before, .jz-orb { animation: none !important; }
  .jz-orb { transition: none !important; }
}

/* ── 圖例當篩選器：點「孩子自評」只看孩子軌，點「家長觀察」只看家長軌 ── */
[data-jz-trk] {
  cursor: pointer;
  border-radius: 8px;
  padding: 2px 7px;
  margin: 0 -3px;
  transition: background-color var(--fx-fast) var(--fx-ease),
              transform var(--fx-fast) var(--fx-ease),
              opacity var(--fx-fast) var(--fx-ease);
}
[data-jz-trk]:hover { background: rgba(255, 255, 255, .7); transform: translateY(-1px); }
[data-jz-trk][aria-pressed="true"] { background: rgba(255, 255, 255, .95); box-shadow: 0 2px 8px rgba(65, 51, 42, .12); }

.jz-only-c .jz-trk-p,
.jz-only-p .jz-trk-c {
  opacity: 0;
  transform: scaleX(0);
  transform-origin: left center;
}
.jz-only-c .fx-bar.jz-trk-p,
.jz-only-p .fx-bar.jz-trk-c { transition: opacity .3s ease, transform .5s var(--fx-ease); }
.jz-only-c span.jz-trk-p,
.jz-only-p span.jz-trk-c { transform: none; }

/* ── 卡片跟著游標輕微傾斜（桌機） ── */
.jz-tilted {
  transform: perspective(900px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) translateY(-5px);
  transition: transform .18s var(--fx-ease), box-shadow var(--fx-mid) var(--fx-ease);
}

/* ── 插圖點一下會彈 ── */
.jz-bounce { animation: jzBounce .52s cubic-bezier(.34, 1.5, .64, 1) 1; }
@keyframes jzBounce {
  0%   { transform: scale(1) rotate(0deg); }
  35%  { transform: scale(1.14) rotate(-4deg); }
  70%  { transform: scale(.97) rotate(2deg); }
  100% { transform: scale(1) rotate(0deg); }
}

@media (prefers-reduced-motion: reduce) {
  .jz-tilted { transform: none !important; }
  .jz-bounce { animation: none !important; }
  .jz-only-c .jz-trk-p, .jz-only-p .jz-trk-c { transition: none !important; }
}

/* ── 注音：源泉注音圓體（ㄅ字嗨・BpmfGenSenRounded，ButTaiwan，Apache 2.0）──
   這個字型的字形本身就帶注音，不需要 ruby 標記；
   開啟時只要換字型，字旁自動出現注音。行高要放大，注音才不會被裁到。 */
@font-face {
  font-family: 'BpmfGenSen';
  src: url('fonts/BpmfGenSenRounded-subset.woff2') format('woff2');
  font-display: swap;
  font-weight: 400 900;
}
/* 開注音時，孩子會讀到的字全部換成注音字型——不只題目與選項，
   側欄量表名、提示、按鈕、頂欄卷別都要，不然會出現「有的字有注音有的沒有」。
   子集會過期：8/12 版只含當時低年級題目用字，8/27 題庫改版後 4–6 年級 141 題缺注音（KWJ 2026-09-08 回報）。
   2026-09-08 起子集＝全部 es6_items（含停用）＋構面名＋指導語＋兩支作答頁介面字，
   題庫或介面文字一改就重跑 _建置腳本/make-zhuyin-subset.py（可先 --check）。 */
.jz-zy,
.jz-zy div,
.jz-zy span,
.jz-zy a,
.jz-zy button {
  font-family: 'BpmfGenSen', 'Zen Maru Gothic', 'Huninn', 'Microsoft JhengHei', sans-serif !important;
}
/* 數字與英文維持原本的字型，換過去會變醜也沒有注音可標 */
.jz-zy [data-jz-qnum],
.jz-zy [data-jz-count],
.jz-zy [data-jz-progfill] {
  font-family: 'Figtree', sans-serif !important;
}
.jz-zy [data-jz-qtext] {
  line-height: 2.15 !important;
  letter-spacing: .02em;
}
.jz-zy [data-jz-olabel] { line-height: 2 !important; }
/* 注音要有地方站，行高一律放大 */
.jz-zy div, .jz-zy span { line-height: 1.95; }

/* ── 作答換題：舊題退出、新題進來，只動題卡不重畫整頁 ── */
[data-jz-qcard] { transition: opacity .15s ease, transform .15s cubic-bezier(.4, 0, 1, 1); }
[data-jz-qcard].jz-qout-l { opacity: 0; transform: translate3d(-26px, 0, 0); }
[data-jz-qcard].jz-qout-r { opacity: 0; transform: translate3d(26px, 0, 0); }
[data-jz-qcard].jz-qin-l,
[data-jz-qcard].jz-qin-r {
  animation: jzQIn .32s cubic-bezier(.22, .72, .28, 1) both;
}
[data-jz-qcard].jz-qin-r { --from: 30px; }
[data-jz-qcard].jz-qin-l { --from: -30px; }
@keyframes jzQIn {
  from { opacity: 0; transform: translate3d(var(--from, 30px), 0, 0); }
  to   { opacity: 1; transform: none; }
}

/* 選項按下的回饋（觸控也有） */
[data-jz-opt] { transition: background-color .18s var(--fx-ease), border-color .18s var(--fx-ease), box-shadow .24s var(--fx-ease), transform .12s var(--fx-ease); }
[data-jz-opt]:hover { transform: translateX(2px); }
[data-jz-opt]:active { transform: scale(.99); }

/* 進度條長度變化要看得到 */
[data-jz-progfill] { transition: width .45s cubic-bezier(.22, .72, .28, 1); }

@media (prefers-reduced-motion: reduce) {
  [data-jz-qcard], [data-jz-qcard].jz-qin-l, [data-jz-qcard].jz-qin-r {
    animation: none !important; transition: none !important; opacity: 1 !important; transform: none !important;
  }
}

/* ── 章間波浪緩慢漂移（Liquid Wave）── */
@media (prefers-reduced-motion: no-preference) {
  .jz-wavepath {
    animation: jzWave var(--wd, 15s) ease-in-out infinite alternate;
    transform-origin: center;
    transform-box: fill-box;
  }
  @keyframes jzWave {
    from { transform: translateX(-2.2%) scaleX(1.05); }
    to   { transform: translateX(2.2%) scaleX(1.05); }
  }
}

/* ── 章節跳點的環形進度（Circular Progress）── */
.jz-ring {
  position: absolute;
  inset: -4px;
  width: calc(100% + 8px);
  height: calc(100% + 8px);
  pointer-events: none;
  transform: rotate(-90deg);
}
.jz-ring-bg, .jz-ring-fg {
  fill: none;
  stroke-width: 2.5;
  stroke-linecap: round;
}
.jz-ring-bg { stroke: rgba(255, 255, 255, .45); }
.jz-ring-fg {
  stroke: #fff;
  stroke-dasharray: 113;
  stroke-dashoffset: 113;
  transition: stroke-dashoffset .2s linear;
  filter: drop-shadow(0 1px 2px rgba(65, 51, 42, .25));
}

/* ── 儀表歸位：長條到位時輕微過衝再收回（Gauge Meter 的手感）── */
.fx-bar { transition-timing-function: cubic-bezier(.2, .9, .25, 1.06) !important; }

@media (prefers-reduced-motion: reduce) {
  .jz-wavepath { animation: none !important; }
  .jz-ring-fg { transition: none !important; }
}
