/* hidden 屬性要贏過下面的 display:flex（.chips、.pick），不然藏不起來 */
[hidden] { display: none !important; }
:root {
  color-scheme: light dark;
  --fg: #1a1a1a; --bg: #ffffff; --muted: #767676; --line: #e3e3e3; --accent: #c0392b;
  /* 1.0：讀音依聲調上色。1.0.12：顏色就是 Pleco 的國語聲調色，照「用國語唸出來的形狀」對 —— 高＝紅（一聲：高高的）、
     升＝綠（二聲：往上揚）、低＝藍（三聲的半上：低低的）、降＝紫（四聲）、中平＝灰（Pleco 輕聲的灰）。Irene 熟 Pleco 的顏色，
     看顏色就照國語的形狀唸，讀音可以跳過；à 長得像 ˋ 的陷阱也由顏色解決（藍＝低）。1.0～1.0.11 照教科書的對照（升≈完整的三聲
     214 → 藍、高≈二聲 → 綠、低另給琥珀）—— 可是 Pleco 用熟的人心裡的藍（三聲）就是「低」，藍色的升調會被唸成低調。
     1.0.11：五個顏色（連同中平的灰 --tone-mid）亮度一樣 —— Irene：「黑白模式要把聲調拿掉練」。黑白（灰階）螢幕常見的三種換算
     （CSS grayscale／Rec.709 luma、WCAG 亮度 Y、OKLab L）都在 1.5% 以內；Rec.601 luma（舊式電子紙）在 7.5% 以內 —— 四種全等的話
     彩度只剩一半、跟灰色分不太出來，彩色模式（平常用的）就不好用了。紅要跟灰一樣亮，只能是偏沉的紅。對白底 4.6–4.9:1 。
     （這裡的「1.5%」是 0–1 的絕對差：Rec.709、Y、OKLab L 都差 0.015 以內，Rec.601 0.075 以內 —— tools/test-colors.mjs 會檢查。）
     1.2.5（Irene：「一聲（高）改成更接近紅，至少粉紅 —— 現在的橘色每次都讓我怪怪的；黑白模式的亮度一樣要完全一樣」）：
     高調從 OKLCH 色相 28–32（偏橘的鮭魚色）轉到 10–12（玫瑰紅、偏粉）。亮度鎖住時紅的彩度只到 0.09–0.10（再高三種灰階換算就分家），
     所以只能動色相：G 比 B 高 → 橘，B 追上 G → 紅、再多一點 → 粉。線上記號、淡色線也一起轉到 12 */
  --tone-low: #4a6cd3; --tone-falling: #885db2; --tone-high: #a25d66; --tone-rising: #3a850b; --tone-mid: #707070;
  /* 線上記號的墨色：同色相、很深（OKLCH L 0.32），灰階下跟淡色條差很多（4–5:1） */
  --rail-ink-low: oklch(0.32 0.089 268); --rail-ink-falling: oklch(0.32 0.089 312); --rail-ink-high: oklch(0.32 0.09 12); --rail-ink-rising: oklch(0.32 0.089 145);
  /* 1.0.6：AI 例句左邊那條線：四個聲調的淡色，亮度一樣（OKLCH L 0.78）。1.0.12：沒有聲調的線（中平、多音節）改成同亮度的灰 ——
     原本那條是淡紅（主色 45%），跟高調的淡紅撞在一起；灰也剛好是 Pleco 的輕聲色 */
  --ai-line-default: oklch(0.78 0 0);
  --pastel-low: oklch(0.78 0.075 268); --pastel-falling: oklch(0.78 0.075 312); --pastel-high: oklch(0.78 0.075 12); --pastel-rising: oklch(0.78 0.075 145);
  /* 1.0.10～1.0.12：AI 例句那條線（單音節的詞）上一排聲調記號 —— 黑白（灰階）螢幕上那條線是唯一的聲調提示。記號跟顏色同一個
     國語聲調（Pleco／注音）：高 ˉ（一聲）、升 ˊ（二聲）、低 ˇ（三聲）、降 ˋ（四聲）；中平不標。只當遮罩用（10×12 一格，
     跟著線寬放大），顏色另外給。1.0.10 每個上了色的字底下也有一個 —— Irene 沒要，1.0.11 拿掉 */
  --rail-high: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 12'%3E%3Cpath d='M1.8 5.7 8.2 5.7' fill='none' stroke='%23000' stroke-linecap='round' stroke-linejoin='round' stroke-width='2.3'/%3E%3C/svg%3E");
  --rail-rising: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 12'%3E%3Cpath d='M2.2 9.4 7.8 2' fill='none' stroke='%23000' stroke-linecap='round' stroke-linejoin='round' stroke-width='2.2'/%3E%3C/svg%3E");
  --rail-low: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 12'%3E%3Cpath d='M1.6 2.6 5 9 8.4 2.6' fill='none' stroke='%23000' stroke-linecap='round' stroke-linejoin='round' stroke-width='2.1'/%3E%3C/svg%3E");
  --rail-falling: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 12'%3E%3Cpath d='M2.2 2 7.8 9.4' fill='none' stroke='%23000' stroke-linecap='round' stroke-linejoin='round' stroke-width='2.2'/%3E%3C/svg%3E");
}
@media (prefers-color-scheme: dark) {
  :root { --fg: #ececec; --bg: #111111; --muted: #9a9a9a; --line: #2a2a2a; --accent: #ff6b5e;
    --tone-low: #6d98ff; --tone-falling: #b088e2; --tone-high: #d4858e; --tone-rising: #72ac59; --tone-mid: #9a9a9a;
    --rail-ink-low: oklch(0.88 0.057 268); --rail-ink-falling: oklch(0.88 0.06 312); --rail-ink-high: oklch(0.88 0.06 12); --rail-ink-rising: oklch(0.88 0.06 145);
    --ai-line-default: oklch(0.43 0 0);
    --pastel-low: oklch(0.43 0.09 268); --pastel-falling: oklch(0.43 0.09 312); --pastel-high: oklch(0.43 0.09 12); --pastel-rising: oklch(0.43 0.09 145); }
}
/* 1.0.3：OLED 純黑（設定頁「顯示」的開關）：不管系統設定一律黑底；分隔線、框線再暗一點，整片才是真的黑 */
:root[data-theme="oled"] {
  color-scheme: dark;
  --fg: #e6e6e6; --bg: #000000; --muted: #8c8c8c; --line: #1c1c1c; --accent: #ff6b5e;
  --tone-low: #5f89fa; --tone-falling: #a478d7; --tone-high: #c47783; --tone-rising: #659e4a; --tone-mid: #8c8c8c;
  --rail-ink-low: oklch(0.86 0.06 268); --rail-ink-falling: oklch(0.86 0.06 312); --rail-ink-high: oklch(0.86 0.06 12); --rail-ink-rising: oklch(0.86 0.06 145);
  --ai-line-default: oklch(0.40 0 0);
  --pastel-low: oklch(0.40 0.09 268); --pastel-falling: oklch(0.40 0.09 312); --pastel-high: oklch(0.40 0.09 12); --pastel-rising: oklch(0.40 0.09 145);
}
/* 下拉、輸入框：瀏覽器暗色預設是灰底塊（新分頁底下的兩個下拉最明顯），純黑模式改成黑底細框 */
:root[data-theme="oled"] :is(select, input[type="text"], input[type="password"], textarea) { background: #000; color: var(--fg); border: 1px solid #333; border-radius: 4px; }
html, body {
  margin: 0; background: var(--bg); color: var(--fg);
  font: 16px/1.5 -apple-system, "Segoe UI", "Noto Sans Thai", "Leelawadee UI", Thonburi, Loma, sans-serif;
}
body:not(.page) { min-height: 100vh; display: grid; place-items: center; }
/* 1.0.11：新分頁兩邊先留好捲軸的位置 —— 一般滑鼠的桌機上，卡片變長、捲軸跑出來時整張卡會往左跳 7.5px（實測） */
html:not(:has(body.page)) { scrollbar-gutter: stable both-edges; }
/* 2.0.4（審查 review-2.0.1）：isolation —— 卡片自己一層：裡面的 z-index（兩塊時的 #dict、.main-rest、🔊）只在卡片裡排，
   不會蓋到底下固定的那一排（矮的寬螢幕上，左欄的例句蓋住「學校課本 · 全部」、點不到） */
#card { text-align: center; padding: 2rem 1.25rem 5rem; max-width: 46rem; width: 100%; box-sizing: border-box; -webkit-tap-highlight-color: transparent; isolation: isolate; }
#word { font-size: clamp(3rem, 14vw, 9rem); font-weight: 400; line-height: 1.3; margin: .15em 0 .1em; }
/* 1.0.15：放不下時分左右兩塊（Irene 放大很多倍時，AI 例句和按鈕掉到底下那一排後面）。newtab.js 的 fitTiles 量過才加
   .tiles，只在夠寬的畫面。左：字、讀音、聲調怎麼來、意思、分類、例句、難記；右：AI 例句、按鈕、跳過／復原、提示。
   平常兩個包裝不佔版面（display: contents）—— 放得下的卡跟以前一模一樣 */
.tile-main, .tile-side, .tile-rest { display: contents; }
/* 1.0.19（審查）：單欄時 #ai 跟 #answer 是相鄰的 block，例句框下面多留的空（--ai-hold）會跟 .answer 的 margin-top 1.8rem 疊成一個（取大的），
   換成比較短的句子時按鈕還是往上跳 —— 按鈕那一塊包成自己的區塊（flow-root：裡面的 margin 不往外疊）。沒有多留時版面一模一樣 */
#card:not(.tiles) #ai:not([hidden]) + .side-rest { display: flow-root; }
/* 1.0.17（Irene：「重量不平均，泰文字和例句要在同一條水平線上置中；元素之間的距離要一樣」）：兩塊共用三排 ——
   第一排左邊是詞表那一行；第二排左邊大字、右邊 AI 例句，兩個都對這一排的中線置中；第三排左邊讀音以下、右邊按鈕、提示、
   跳過，從同一個高度開始排。每一排、每個東西之間都是同一個間距（--tile-gap），各自原本的上下邊距不算 */
#card.tiles { --tile-gap: 1.1rem; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: clamp(1.5rem, 3vw, 3.5rem); row-gap: var(--tile-gap); align-items: start; max-width: 80rem; }
#card.tiles #dict { grid-area: 1 / 1; margin: 0; position: relative; z-index: 1; }   /* 1.1（審查）：大字的框切到墨水後，它的行高往上蓋到這一行 —— 定位讓這一行畫在上面、點得到（點一下＝記住了，不是按住偷看）。
   2.0.1（審查）：1.2.4 起大字自己也定位了（🔊 掛在裡面）—— 兩個都定位就照順序疊，大字又蓋回來；z-index 讓這一行一定在上面 */
#card.tiles #word { grid-area: 2 / 1; align-self: center; margin: 0; }
#card.tiles #ai { grid-area: 2 / 2; align-self: center; margin-top: 0; }
#card.tiles:not(.loose) #ai { margin-block: calc(var(--ai-hold, 0px) / 2); top: var(--ai-shift, 0px); }   /* top：對著字本體的中線（newtab.js alignAi） */   /* 1.0.19（審查）：多留的空上下各一半 —— 例句一直對著大字的中線 */
#card.tiles .main-rest { grid-area: 3 / 1; position: relative; z-index: 1; }   /* 2.0.1（審查）：大字的框往下也切到墨水，蓋到讀音那一行的上半 —— 讀音那一排畫在上面、點得到 */
#card.tiles .side-rest { grid-area: 3 / 2; }
#card.tiles .tile-rest { display: flex; flex-direction: column; align-items: center; gap: var(--tile-gap); min-width: 0; }
#card.tiles .tile-rest > * { margin: 0; }
#card.tiles .tile-rest > :empty { display: none; }   /* 空的（沒有分類、沒有例句）不佔一個間距 */
/* 很小的視窗：例句比字高、左欄又長，「字和例句同一列」會把左欄往下推到底下那一排後面 —— 這時改回左右各排各的（1.0.16 的排法），先求放得下 */
#card.tiles.loose .tile-main, #card.tiles.loose .tile-side { display: flex; flex-direction: column; align-items: center; gap: var(--tile-gap); min-width: 0; }
#card.tiles.loose .tile-main { grid-area: 1 / 1 / 4 / 2; }
#card.tiles.loose .tile-side { grid-area: 1 / 2 / 4 / 3; }
#card.tiles.loose :is(#word, #ai, .tile-rest) { align-self: stretch; }
.reading { font-size: 1.25rem; color: var(--muted); margin: 0; }
.meaning { font-size: 1.6rem; margin: .4em 0 .8em; }
.examples p { margin: .35em 0; }
.ex { display: block; font-size: 1.3rem; }
.exm { display: block; font-size: 1rem; color: var(--muted); }
.rate { display: flex; gap: .6rem; justify-content: center; flex-wrap: wrap; }
/* 1.0.11：按鈕那一排 ——「翻開」、新詞的兩顆、評分鈕疊在同一格（grid 同一個位置，格子跟最大的一樣大），↻ 固定在格子右邊。
   到期卡兩種都排版：題目上評分鈕看不見、翻開後「翻開」看不見 —— 翻開時這一排一動也不動 */
.answer { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: .6rem; width: fit-content; max-width: 100%; margin: 1.8rem auto 0; }   /* 1.0.12：放不下時 ↻ 換到下一行（兩種狀態都一樣，不會跳） */
/* 1.0.18（審查）：四顆評分鈕在手機上排成固定的 2×2 —— 換行時是照那一塊「整排放得下多寬」算的：四顆排一排（510px）放不下 ↻
   就自己佔一行（1.0.12 起 400–600px 的手機整塊高了 71px）；2×2 只要約 266px，旁邊放得下 ↻ 就放旁邊（414px 以上），放不下照舊換行 */
/* 1.0.19（審查）：只在旁邊真的有 ↻ 時才排 2×2（AI 關著、或 600px 以上四顆本來就排得成一排 —— 硬排 2×2 反而高 71px）；
   用 px（媒體查詢的 rem 跟著瀏覽器的字級設定，不是這一頁的 16px）；只管 #rate（「記住了／我早就會」照舊）。
   ↻ 靠上：題目上跟一排高的「翻開」對齊，翻開後在 2×2 的第一排旁邊（兩種狀態同一個位置，翻開時不動） */
@media (max-width: 600px) {
  #card:not(.btn2) .answer:has(> #aiAgain:not([hidden])) #rate { display: grid; grid-template-columns: repeat(2, auto); justify-content: center; }
  #card:not(.btn2) #aiAgain { align-self: flex-start; }
}
.answer-slot { display: grid; min-width: 0; }
.answer-slot > * { grid-area: 1 / 1; }
#card.test:not(.revealed) #rate { visibility: hidden; }
#card.revealed #revealBox { visibility: hidden; }
.rate button {
  font: inherit; color: inherit; background: transparent; border: 1px solid currentColor; border-radius: 999px;
  padding: .5em 1.2em; min-width: 6.5rem; cursor: pointer; opacity: .8;
  display: flex; flex-direction: column; align-items: center; gap: .1em;
}
.rate button small { font-size: .75rem; color: var(--muted); min-height: 1.5em; }   /* 1.0.11：間隔還沒算好（空的）時也佔一行 */
.rate button:hover, .rate button:focus-visible { opacity: 1; }
.rate button.again { color: var(--accent); }
.muted { color: var(--muted); }
.small { font-size: .85rem; }
.tools .off { visibility: hidden; }   /* 1.0.11：「復原」還不能用時看不見、但佔位 */
/* 2.1.0（Irene）：「跳過／↶ 復原」只有手機、平板看得到（沒有鍵盤快捷鍵）；電腦用 N、⌘Z —— 寫在底下那一排的提示裡 */
html:not(.touch) .tools { display: none; }
footer { position: fixed; right: 1rem; bottom: 1rem; display: flex; gap: .9rem; align-items: center; }
footer a { text-decoration: none; }
#empty { text-align: center; padding: 1rem; }
/* v0.7.1：設定頁與學習頁整體放大兩倍（根字級 16→32px，rem 全跟著變）；新分頁不受影響 */
html:has(body.page) { font-size: 19.2px; }   /* 2.0（Irene）：設定頁的字小 40%（32 → 19.2px）；2.3.0（Irene）：學習頁也一樣（字母、遊戲的字跟著等比例縮） */
body.page { font-size: 1rem; }  /* body 原本寫死 16px，內文要跟著根字級走 */
.page select, .page input, .page button, .page textarea { font: inherit; }  /* 下拉、按鈕也要跟著變大 */
.page { max-width: 42rem; margin: 0 auto; padding: 1.2rem 1rem 3rem; }
.page input[type="checkbox"], .page input[type="radio"] { width: 1em; height: 1em; vertical-align: -.1em; }
.page h1 { margin-top: 0; }
/* 2.3.0（Irene）：設定、學習頁頂端 —— 「← 首頁」一行＋標題前的 App 圖示 ท（點了也回首頁）。
   圖示是 icons/tho.svg 當遮罩、塗 App 中平調的顏色（跟工具列的圖示同一個 ท、同一個灰；深色主題自動換成深色的中平調） */
.crumbs { margin: 0 0 .4rem; font-size: .85rem; color: var(--muted); }
.crumbs a { color: inherit; text-decoration: none; border-radius: 4px; }
.crumbs a:hover, .crumbs a:focus-visible { color: var(--fg); text-decoration: underline; }
.page-head { display: flex; align-items: center; gap: .5rem; margin: 0 0 .6rem; }
.page-head h1 { margin: 0; }
.home-icon { flex: none; width: 2.3rem; height: 2.3rem; -webkit-mask: url(icons/tho.svg) center / contain no-repeat; mask: url(icons/tho.svg) center / contain no-repeat; background: var(--tone-mid); transition: background-color .15s; }
.home-icon:hover { background: var(--fg); }
.home-icon:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
.box { border: 1px solid var(--line); border-radius: 10px; padding: 1rem 1.25rem; margin: 1rem 0; }
.box h2 { font-size: 1.05rem; margin: 0 0 .6rem; }
.box label { margin-right: 1rem; }
.disabled { opacity: .5; }
table { width: 100%; border-collapse: collapse; }
th, td { text-align: left; padding: .4rem .3rem; border-bottom: 1px solid var(--line); }
td button { font: inherit; font-size: .85rem; margin-right: .4rem; }
code { font-family: ui-monospace, Menlo, monospace; font-size: .9em; }
/* 1.2.1：泰文字型（設定頁「顯示」）：Itim（Cadson Demak、Pablo Impallari；SIL Open Font License 1.1，見 fonts/OFL.txt）。
   unicode-range 只有泰文字母：泰文字換成 Itim，讀音（Itim 沒有 ɛ ɔ ʉ）、國語、介面照舊用系統字。字型是本機檔，先擋著不畫（block）再畫，不會先閃系統字 */
@font-face { font-family: "Thai Tab Itim"; src: url("fonts/Itim-Regular.otf") format("opentype"); font-weight: 400; font-style: normal; font-display: block; unicode-range: U+0E00-0E7F; }
html[data-thai-font="itim"] body { font-family: "Thai Tab Itim", -apple-system, "Segoe UI", "Noto Sans Thai", "Leelawadee UI", Thonburi, Loma, sans-serif; }
/* 1.2.2（審查）：母音、聲調記號寫在「-」或空白上（-ิ、เ-ีย、ไม้เอก ่）時，上面那個 face 不管 - 和空白 → 整組（字＋記號）掉回系統字、
   跟旁邊的 Itim 不搭。學習頁的表、「聲調怎麼來」、內文裡單獨寫的記號用另一個 face：空白、( )、- 也用 Itim（Itim 沒有 ◌、全形括號） */
@font-face { font-family: "Thai Tab Itim Notation"; src: url("fonts/Itim-Regular.otf") format("opentype"); font-weight: 400; font-style: normal; font-display: block; unicode-range: U+0020, U+0028-0029, U+002D, U+0E00-0E7F; }
html[data-thai-font="itim"] :is(.tone-list, .rule-table, .tone-note, .th-notation, .game-fb) { font-family: "Thai Tab Itim Notation", -apple-system, "Segoe UI", "Noto Sans Thai", "Leelawadee UI", Thonburi, Loma, sans-serif; }
.font-sample { font-size: 1.4em; margin-left: .4em; }
/* 2.0：只有擴充功能才能用的那一格（照微糖設定頁的 ADD-ON ONLY）—— 網頁版看得到、不能勾 */
.ext-badge { display: inline-block; margin-left: .5em; padding: .1em .6em; border: 1px solid currentColor; border-radius: 999px; font-size: .62em; font-weight: 600; letter-spacing: .06em; vertical-align: .18em; opacity: .7; }
#hoverBox.no-ext label { opacity: .55; }
#status.bad { color: var(--accent); }
input[type="text"] { font: inherit; padding: .25em .5em; min-width: 14rem; }
button { font: inherit; }

/* v0.2：分類標籤、底部兩個下拉、今天額度用完 */
.chips { display: flex; flex-wrap: wrap; gap: .35rem; justify-content: center; margin: -.2em 0 .6em; }
.chip { font-size: .72rem; letter-spacing: .02em; padding: .12em .6em; border-radius: 999px; border: 1px solid var(--line); color: var(--muted); }
.chip.cat { border-color: transparent; background: color-mix(in srgb, var(--accent) 12%, transparent); color: var(--fg); }
.chip.rank { font-variant-numeric: tabular-nums; }
footer { left: 1rem; right: 1rem; justify-content: flex-end; flex-wrap: wrap; row-gap: .4rem; }
/* 1.0.12（審查）：題目上的版面跟翻開後一樣高，小手機上「翻開」會落到固定在底部的這一排底下（點了反而打開詞表下拉）——
   卡片底下照它實際的高度留空（newtab.js 量 --footer-h），它自己有底色 */
body:not(.page) footer { background: var(--bg); padding: .35rem 0; }
#card { padding-bottom: calc(var(--footer-h, 3.5rem) + 1.5rem); }
/* 1.0.18（審查）：用 Tab 移到「跳過／翻開／評分鈕」時，捲到底下那一排的上面（不躲在它後面） */
html:not(:has(body.page)) { scroll-padding-bottom: calc(var(--footer-h, 3.5rem) + 1.25rem); }
/* 0.9.2：詞表、分類兩個下拉並排靠左，統計以後靠右。
   1.2.4（Irene：「只要一排字，像右邊那樣：學校課本 · 全部，照現在一樣是下拉、滑過去游標變」）：看得到的是選中的名字（不帶詞數），
   真的 select 蓋在字上面、透明 —— 點下去就是原本的下拉（選項照舊帶詞數）。鍵盤 Tab 到它時整個字框起來 */
.picks { display: inline-flex; align-items: center; gap: .45rem; font-size: .85rem; color: var(--muted); }
.pick { position: relative; display: inline-flex; align-items: center; cursor: pointer; border-radius: 4px; }
.pick select { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; font: inherit; font-size: .85rem; margin: 0; }
.pick:hover .pick-text { color: var(--fg); }
.pick:has(select:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
.pick:has(select:focus-visible) .pick-text { color: var(--fg); }
.pick-sep:has(+ #catLabel[hidden]) { display: none; }   /* 只有一個分類（不出分類下拉）：沒有「·」 */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
/* 2.1.0（Irene）：提示搬到底下那一排、按鈕的左邊 —— 佔掉中間剩下的空（不撐開、不換行）、靠右、一行，太長就「…」（滑過去看整句）：
   翻開時換一句，這一排不會變高、按鈕不會動。手機、平板（只寫短的那一句）和很窄的視窗：自己一行、在按鈕那一排的上面；
   空的時候也佔那一行（翻開前後一樣高） */
footer .hint { flex: 1 1 0; min-width: 0; margin: 0; text-align: right; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: .8rem; line-height: 1.5; color: var(--muted); }
/* 空的時候剛好一行字高（1.5em ＝ 行高）—— 1.25em 比一行字矮 3.2px，手機上翻開後提示變空，卡片往下移 1.5px（jump-audit p13／p14 抓到） */
html.touch footer .hint { order: -1; flex: 1 0 100%; min-height: 1.5em; }
@media (max-width: 40rem) { footer .hint { order: -1; flex: 1 0 100%; min-height: 1.5em; } }
.stats-wrap { display: inline-flex; margin-left: auto; }   /* 提示自己一行時：詞表留在左邊，鈕靠右 */
#done { text-align: center; padding: 1rem; max-width: 30rem; }
#done .actions { display: flex; gap: .6rem; justify-content: center; flex-wrap: wrap; }

/* v0.3：英文開關（設定頁；關著就不畫英文意思與例句翻譯；按住字偷看） */
html.no-en:not(.peek) #meaning:not(.fallback), html.no-en:not(.peek) .exm-en { display: none; }
/* v0.5：國語意思是主線；兩個語言都開著時英文退成副線 */
html.no-zh:not(.peek) #meaningZh:not(.fallback), html.no-zh:not(.peek) .exm-zh { display: none; }
.meaning-zh { font-size: 1.7rem; margin: .35em 0 .15em; }
html:not(.no-zh) #meaningZh:not([hidden]) + #meaning { font-size: 1.15rem; color: var(--muted); margin-top: 0; }
.exm-zh { color: var(--fg); font-size: 1.05rem; }
/* v0.4／1.0：到期的詞先只露出勾的部分（預設只有泰文字），空白鍵、點一下或倒數到了才翻開 */
/* 1.0.11：題目上沒露的部分照樣排版、只是看不見（visibility: hidden 佔好位置，不是 display: none）——
   Irene：「翻開時內容直接出現，已經畫好的東西留在原位」。翻開只是讓它們看得見，整張卡的高度不變、置中的位置也不變 */
#card.test:not(.revealed) :is(#chips, #examples, #toneNote, #leech, #speakBtn) { visibility: hidden; }
/* 1.1.3：「題目上唸這個詞」開著 → 題目上的聲音是提示，🔊 題目上就看得見（再聽一次；P 也可以） */
#card.test.say-q:not(.revealed) #speakBtn { visibility: visible; }
#card.test:not(.revealed):not(.first-word) #word { visibility: hidden; }
#card.test:not(.revealed):not(.first-reading) #reading { visibility: hidden; }
#card.test:not(.revealed):not(.first-meaning) #meaning { visibility: hidden; }
#card.test:not(.revealed):not(.first-mandarin) #meaningZh { visibility: hidden; }
kbd { font: inherit; font-size: .85em; border: 1px solid var(--line); border-radius: 4px; padding: 0 .3em; }
.parts { display: flex; flex-wrap: wrap; gap: .3rem 1rem; align-items: center; }
/* 1.1.3：設定頁的子選項（跟著上一個開關；上一個關掉就不能勾） */
.sub-opt { margin: -.25rem 0 .6rem 1.6rem; }
.sub-opt label:has(input:disabled) { opacity: .5; }
#word { user-select: none; -webkit-user-select: none; }
html.no-en #word { cursor: help; }
#done button { font: inherit; padding: .5em 1.2em; border-radius: 999px; border: 1px solid currentColor; background: transparent; color: inherit; cursor: pointer; }

/* v0.7：AI 例句區塊（在例句下面；右鍵或 ↻ 重新生成） */
/* 1.0.6：整塊置中（寬度跟著內容、最寬 34rem），字照樣靠左、左邊照樣一條線 */
.ai { position: relative; margin: .8rem auto 0; padding: 0 1.1rem; width: fit-content; max-width: 34rem; box-sizing: border-box; border-left: var(--ai-line-w, 3px) solid var(--ai-line); text-align: left; }
#ai { --ai-line: var(--ai-line-default); --ai-line-w: 18px; margin-bottom: var(--ai-hold, 0px); }   /* 1.0.11：邊距用 rem —— 等 AI 時字比較小（.9rem），用 em 的話字來了框會往下挪 1.3px */
#ai[data-tone="low"] { --ai-line: var(--pastel-low); --ai-ink: var(--rail-ink-low); --ai-rail: var(--rail-low); }
#ai[data-tone="falling"] { --ai-line: var(--pastel-falling); --ai-ink: var(--rail-ink-falling); --ai-rail: var(--rail-falling); }
#ai[data-tone="high"] { --ai-line: var(--pastel-high); --ai-ink: var(--rail-ink-high); --ai-rail: var(--rail-high); }
#ai[data-tone="rising"] { --ai-line: var(--pastel-rising); --ai-ink: var(--rail-ink-rising); --ai-rail: var(--rail-rising); }
/* 1.0.11：線寬 18px（Irene：「至少粗三倍、裡面的圖案也放大」），有聲調的線上一排半透明的聲調記號；原本的顏色（中平、多音節）沒有記號 */
#ai:is([data-tone="low"], [data-tone="falling"], [data-tone="high"], [data-tone="rising"])::after {
  content: ""; position: absolute; top: 0; bottom: 0; left: calc(-1 * var(--ai-line-w)); width: var(--ai-line-w); pointer-events: none;
  background: color-mix(in srgb, var(--ai-ink) 85%, transparent);   /* 1.0.11：深墨、85%（黑白螢幕上一眼看得到） */
  /* 一整顆一整顆平均排（space）：線的底端不會切到半個記號 */
  -webkit-mask-image: var(--ai-rail); mask-image: var(--ai-rail); -webkit-mask-size: 100% auto; mask-size: 100% auto;
  -webkit-mask-repeat: no-repeat space; mask-repeat: no-repeat space; -webkit-mask-position: 0 0; mask-position: 0 0; }
/* 1.0.9：題目上泰文字沒露（例：只露國語）時，線照樣依聲調上色（Irene：聲調是詞的一部分、是回想的提示，不是要藏的答案；
   缺字題沒有聲調常常有兩個答案；奶油色本來是「中平／多音節」的意思，題目上用它等於給錯的資訊）。
   翻卡設定「題目上也露聲調色」關掉才回到原本的顏色 */
#card.test.no-tone-hint:not(.revealed):not(.first-word) #ai { --ai-line: var(--ai-line-default); }
#card.test.no-tone-hint:not(.revealed):not(.first-word) #ai::after { content: none; }
.ai p { margin: .2em 0; font-size: 1.05rem; }
/* 1.0.17（Irene：「左邊那條線不要比右邊的字高，剛好切齊」）：框上下不留白（以前 .6rem），第一行上、最後一行下的邊距也不算進框裡 ——
   線就是字的高度。要多佔的空間（不縮回原本的高度）改放在框外（newtab.js drawAi 的 margin-bottom），不再把線撐長 */
.ai p:first-child { margin-top: 0; }
.ai p:last-child { margin-bottom: 0; }
.ai p[lang="th"] { font-size: clamp(1.75rem, 7vw, 2.3rem); }   /* 1.2.3（Irene：AI 例句的泰文大 1.7 倍）：1.35 → 2.3rem；手機窄（7vw 不到 2.3rem）時最少 1.75rem，句子才不會折成好幾行 */
.ai.loading, .ai.bad { color: var(--muted); font-size: .9rem; }
#ai.waiting { min-height: 7.27rem; }   /* 泰文句＋讀音＋翻譯的高度（1.2.3 泰文 2.3rem：116.3px；讀音藏起來時少一行 87.8px。1.0.17 是 90.4／61.9；1.0.11 是 118.4／89.6）
   —— 第一張卡還沒量過時用；之後照上一句實際的高度預留（newtab.js aiReserve） */
#card.hide-reading #ai.waiting { min-height: 5.49rem; }
/* 等 AI 時線先不畫：框跟著「AI 想一下…」那一行，字來了才知道多寬 —— 線直接出現在最後的位置，不會橫著滑過去 */
#ai.waiting { border-left-color: transparent; }
#ai.waiting::after { content: none; }
#ai.busy > * { opacity: .4; }   /* 重新生成：舊的例句變淡留在原地 */
/* 1.0.13：泰文句子右上的 🔊（唸那一整行）。一直排版、只切 visibility —— 這台裝置沒有泰文語音（html.no-voice）、
   到期卡還沒翻開（聲音就是一半的答案；翻卡先露讀音時例外，跟 P 一樣）就看不見；翻開、語音晚到都不會動 */
.ai p .ai-say { float: right; margin: .12em 0 0 .45rem; }
/* 1.0.18（審查）：🔊 很小（約 24×30px），新詞上差一點點到旁邊就變成「記住了」—— 點得到的範圍往外加大，畫面不動
   （::after 跟著按鈕 visibility: hidden，看不見時這一塊也點不到；例句的 🔊 和字的 🔊 都是） */
.ai p .ai-say { position: relative; }
.ai p .ai-say::after, #speakBtn::after { content: ""; position: absolute; inset: -10px -14px -8px -10px; }
:is(html.no-voice, #card.test:not(.revealed):not(.first-reading)) .ai-say { visibility: hidden; }
.ai.bad { color: var(--accent); }
/* 1.0.6：AI 重新生成 —— 跟「翻開」同一款（細框、透明底、0.8 → 1），但是圓的；放在那一排按鈕最右邊。圖示：箭頭圍著 AI，單色 */
/* 尺寸直接算成跟旁邊的鈕一樣高（翻開：一行字 1.5em＋上下 .5em＋框；評分鈕：兩行 1.5em＋1.125em＋.1em 間距＋上下 .5em＋框），
   寬度一樣 → 正圓。（aspect-ratio 搭 stretch 在 Chromium 會被擠成橢圓） */
.ai-again { --size: calc(2.5em + 2px); width: var(--size); height: var(--size); flex: 0 0 var(--size); align-self: center; box-sizing: border-box;
  font: inherit; color: inherit; background: transparent; border: 1px solid currentColor; border-radius: 50%; padding: 0; display: grid; place-items: center; cursor: pointer; opacity: .8; }
.answer .ai-again { --size: calc(3.725em + 2px); }   /* 1.0.11：一直是評分鈕（兩行）的高度，題目上、翻開後一樣大 */
.ai-again:hover, .ai-again:focus-visible { opacity: 1; }
.ai-again svg { width: 1.75em; height: 1.75em; }
.answer .ai-again svg { width: 2.2em; height: 2.2em; }
#card.test:not(.revealed):not(.first-ai) #aiAgain { visibility: hidden; }
#aiSettings textarea { width: 100%; max-width: 40rem; font: inherit; font-size: .9rem; box-sizing: border-box; }
.keyRow { margin: .4rem 0; display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; }
.keyRow input[type="password"] { font: inherit; padding: .25em .5em; min-width: 18rem; }
.vars code { margin-right: .4em; }

/* v0.8.1：iPhone Safari 分頁裡的「先加入主畫面」提示（只有網頁版會出現） */
.install-hint { position: fixed; left: .75rem; right: .75rem; top: .75rem; z-index: 10; display: flex; gap: .6rem; align-items: flex-start; padding: .7rem .9rem; border-radius: 10px; border: 1px solid var(--line); background: var(--bg); color: var(--fg); font-size: .9rem; line-height: 1.45; box-shadow: 0 2px 12px color-mix(in srgb, var(--fg) 12%, transparent); }
.install-hint span { flex: 1; }
.install-hint button { font: inherit; border: 0; background: transparent; color: var(--muted); cursor: pointer; padding: 0 .2rem; }
/* 0.9.2：開不起來時，「還沒有詞」底下的技術原因（截圖用） */
.boot-error { color: var(--muted); font-size: .8rem; white-space: pre-wrap; overflow-wrap: anywhere; }

/* v0.6：學習頁（文章＋小遊戲） */
.learn { max-width: 56rem; }
.toc { display: flex; flex-wrap: wrap; gap: .5rem; margin: 0 0 1rem; }
.toc a { text-decoration: none; border: 1px solid var(--line); border-radius: 999px; padding: .25em .9em; color: var(--fg); font-size: .9rem; }
.toc a.active { border-color: currentColor; }
.art-title { font-size: 1.6rem; margin: .5rem 0; }
.prose h2 { font-size: 1.1rem; margin: 1.2rem 0 .4rem; }
.prose p, .prose li { max-width: 46rem; }
.learn-links { margin: .2rem 0 .6rem; padding-left: 1.2rem; }
.learn-links li { margin: .2em 0; }
/* 學習頁的表格：不撐滿、欄位靠緊、字母格不吃寬度 */
.learn table { width: auto; }
.cls-table { margin: .6rem 0 1rem; }
.cls-table th, .cls-table td { padding: .15rem .7rem; vertical-align: middle; }
.cls-table th:first-child { font-size: 1rem; white-space: nowrap; }
.th-letter { font-size: 2.4rem; line-height: 1; white-space: nowrap; }  /* 根字級已加倍 → 等於原本的三倍。不要設 width:1%：在不撐滿的表格裡它會反過來把整張表撐到滿版 */
.learn .prose td[lang="th"], .learn .tone-list td:nth-child(2) { font-size: 1.15em; }
.tone-list td, .tone-list th { padding: .3rem .5rem; }
.toggles { display: flex; flex-wrap: wrap; gap: .4rem 1.2rem; }
.toggle-line { font-size: .9rem; }
.game { outline: none; }
.game:focus-visible { box-shadow: 0 0 0 2px var(--accent); }
.game-q { margin: 0 0 .6rem; color: var(--muted); font-size: .9rem; }
.game-stage { text-align: center; min-height: 7rem; }
.game-stage .big { font-size: clamp(4.5rem, 14vw, 8rem); line-height: 1.25; }
.opts { display: flex; flex-wrap: wrap; gap: .5rem; justify-content: center; margin: .6rem 0; }
.opts button { font: inherit; color: inherit; background: transparent; border: 1px solid currentColor; border-radius: 999px; padding: .5em 1.1em; min-width: 5.5rem; cursor: pointer; display: flex; flex-direction: column; align-items: center; gap: .1em; }
.opts button small { font-size: .7rem; color: var(--muted); }
.opts button.ok { background: color-mix(in srgb, #2e7d32 18%, transparent); border-color: #2e7d32; }
.opts button.bad { background: color-mix(in srgb, var(--accent) 18%, transparent); border-color: var(--accent); }
.opts button:disabled { cursor: default; }
/* 1.1：猜字母 —— 題目是名稱的讀音（大字）；選項是字母（要夠大才分得出 ฎ ฏ、ด ต、ถ ภ）；答完每個選項底下標名稱 */
.game-stage .big-read { font-size: clamp(1.2rem, 7vw, 2.8rem); line-height: 1.4; }
.game-stage .name-ans { min-height: 2.6rem; margin: .2rem 0 0; display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 0 .4em; }
.game-stage .ans-letter { font-size: 2rem; line-height: 1.2; }
.opts .opt-letter { font-size: 2.1rem; line-height: 1.25; }
.opts .opt-note { font-size: .8rem; line-height: 1.35; text-align: center; }   /* 2.3.0：根字級變小 → 名稱（泰文）從 .7 加到 .8rem，聲調記號才看得清楚 */
.opts:not(.answered) .opt-note { visibility: hidden; }
#game-names .opts { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); max-width: 36rem; margin-inline: auto; }
#game-names .opts button { min-width: 0; border-radius: 1.4rem; padding: .4em .5em; }
/* 藏著的名稱有長有短（ฑ มณโฑ 換四行）：每一列一樣高、號碼釘在底下 —— 答題前看不出哪一顆的名稱比較長（不然等於提示） */
#game-names .opts { grid-auto-rows: 1fr; }
#game-names .opts button small { margin-top: auto; }
@media (max-width: 700px) { #game-names .opts { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.game-fb { min-height: 1.6em; text-align: center; margin: .4rem 0; }
.game-fb.ok strong { color: #2e7d32; }
.game-fb.bad strong { color: var(--accent); }
.game-next { display: block; margin: .3rem auto; font: inherit; padding: .4em 1.1em; border-radius: 999px; border: 1px solid currentColor; background: transparent; color: inherit; cursor: pointer; }
.game-score { text-align: center; margin: .4rem 0 0; }
.tone-layout { display: grid; grid-template-columns: minmax(0, 1fr) 24rem; gap: 1.2rem; align-items: start; }
.rule-side { position: sticky; top: 1rem; margin: 2.6rem 0 0; }
.rule-table { font-size: .85rem; }
.rule-table th, .rule-table td { padding: .3rem .25rem; text-align: center; }
.rule-table th small { font-weight: 400; color: var(--muted); }
.rule-table tbody th { text-align: left; white-space: nowrap; }
.rule-table td.hit { outline: 2px solid var(--accent); background: color-mix(in srgb, var(--accent) 14%, transparent); font-weight: 600; }
@media (max-width: 60rem) { .tone-layout { grid-template-columns: 1fr; } .rule-side { position: static; margin: 0; } }

/* 1.0：學習循環 —— 新詞先學（記住了／我早就會）、到期的先想再翻開；讀音上色、熟了收起；沒存到要說 */
.reading-line { margin: 0; display: flex; align-items: center; justify-content: center; gap: .35rem; min-height: 1.9rem; }
.reading-wrap { position: relative; display: inline-flex; align-items: center; }
/* 1.2.4（Irene：「例句的喇叭跑到角落，像 bug 但我喜歡；大字的也一樣 —— 右上角、一樣的距離、一樣大」）：
   字的 🔊 在大字裡面、絕對定位，掛在第一行字的右上角（newtab.js placeSay：左邊＝那一行字的右緣＋.45rem，跟例句 🔊 的 margin 一樣；
   下緣＝子音本體的頂 —— 例句的 🔊 量起來也是坐在子音頂上）。不佔版面：字照樣置中、翻開不會動，讀音那一行也不再有 🔊。
   2.0.1（審查）：單欄不再在字的左右留空（字窄了會折行、手機上畫面變寬）—— 第一行排滿時 🔊 往左縮進來（placeSay 夾住）。
   兩塊時照舊左右各留 2.6rem（fitWord 照扣掉的寬度縮字）：🔊 不會壓到右邊那一欄。
   z-index 2：兩塊時上面那一行（#dict）、下面讀音那一排疊在大字上面（z-index 1），🔊 還是要在最上面、點得到 */
#word { position: relative; }
#card.tiles #word { padding-inline: 2.6rem; }
#speakBtn { position: absolute; left: 0; top: 0; z-index: 2; }
.icon-btn { font: inherit; font-size: 1.15rem; line-height: 1; background: none; border: 0; cursor: pointer; padding: .15em .25em; opacity: .65; }
/* 1.2.4（Irene：「喇叭按鈕的樣子可以換：⾳ 🎵 🩷」，設定頁「唸出來」底下）：字的 🔊、例句的 🔊 都是 CSS 畫的圖示 ——
   按鈕本身沒有字（大字的 textContent 還是那個詞；複製例句也不會帶到 🔊） */
:root { --say-icon: "🔊"; }
:root[data-say-icon="yin"] { --say-icon: "⾳"; }
:root[data-say-icon="note"] { --say-icon: "🎵"; }
:root[data-say-icon="heart"] { --say-icon: "🩷"; }
:is(#speakBtn, .ai-say, .say-icon)::before { content: var(--say-icon); }   /* .say-icon：學習頁的 🔊（2.0.1） */
.icon-btn:hover, .icon-btn:focus-visible { opacity: 1; }
/* 上色的範圍：讀音（.reading.tones）、讀音藏起來時的泰文字（#word.tones、難記詞的對照） */
.tones .tone-low { color: var(--tone-low); }
.tones .tone-falling { color: var(--tone-falling); }
.tones .tone-high { color: var(--tone-high); }
.tones .tone-rising { color: var(--tone-rising); }
.tones .tone-mid, .ai p.tones, #word.tones { color: var(--tone-mid); }   /* 1.0.11：中平也是同亮度的灰（不然黑白模式下「這個是中平」照樣看得出來）；1.0.12：沒切成音節的字（標點、跨兩個聲調的片段）也是 */
.reading.faded { filter: blur(.3em); cursor: help; transition: filter .15s; }
.reading.faded:hover, html.peek .reading.faded { filter: none; }
/* 1.0.4「藏起讀音」（新詞也藏）：讀音、AI 例句的讀音都不畫；按住字（html.peek）才看得到。泰文字改成依聲調上色 */
html:not(.peek) #card.hide-reading :is(#reading, .ai-reading) { display: none; }
#card.hide-reading #word { cursor: help; }
#card.test:not(.revealed) #word { cursor: default; }   /* 1.0.12：題目上按住字不偷看（蓋掉上面的 help）；1.2.4（審查）：1.2.2 起左鍵點題目不翻開 → 不要手的游標 */
/* 1.0.5：AI 例句 —— 泰文句子（讀音藏起來時）或讀音那一行（沒藏時）依聲調上色；正在學的詞畫底線。
   到期卡還沒翻開、翻卡設定勾了「AI 例句」（預設）：例句也先露，題目上要猜的那幾樣挖空 ——
   泰文字、讀音、國語、英文各自跟著翻卡設定（例：只露泰文字 → 翻譯裡那個詞的意思挖掉） */
#card.test:not(.revealed):not(.first-ai) #ai { visibility: hidden; }
#ai .cloze-th { text-decoration-line: underline; text-decoration-thickness: max(2px, .07em); text-decoration-color: var(--ai-line); text-underline-offset: .32em; }   /* 1.0.12：分開寫 —— iOS 18 的 Safari 不認簡寫裡的粗細和顏色，整條底線會不見 */
:is(#card.test:not(.revealed):not(.first-word) #ai .cloze-th, #card.test:not(.revealed):not(.first-reading) #ai .cloze-reading,
    #card.test:not(.revealed):not(.first-mandarin) #ai .cloze-zh, #card.test:not(.revealed):not(.first-meaning) #ai .cloze-en) {
  background: color-mix(in srgb, var(--muted) 24%, transparent); border-radius: 4px; user-select: none; }
:is(#card.test:not(.revealed):not(.first-word) #ai .cloze-th, #card.test:not(.revealed):not(.first-reading) #ai .cloze-reading,
    #card.test:not(.revealed):not(.first-mandarin) #ai .cloze-zh, #card.test:not(.revealed):not(.first-meaning) #ai .cloze-en),
:is(#card.test:not(.revealed):not(.first-word) #ai .cloze-th, #card.test:not(.revealed):not(.first-reading) #ai .cloze-reading) * { color: transparent !important; }
/* 只露讀音當題目（聽力回想）時，熟了也不模糊：那是題目本身 */
#card.test:not(.revealed).first-reading .reading.faded { filter: none; }
.tone-note { font-size: .85rem; color: var(--muted); margin: .3em auto 0; max-width: 34rem; }
.tone-note .tone-line { display: block; }   /* 1.0.6：一個音節一行 */
.badge { font-size: .5em; font-weight: 400; letter-spacing: .05em; vertical-align: .4em; padding: .05em .5em; border: 1px solid var(--line); border-radius: 999px; color: var(--muted); }
.chip.meta { border-style: dashed; }
.chip.leech-chip { border-color: var(--accent); color: var(--accent); }
.leech { font-size: .9rem; color: var(--accent); margin: .7em auto 0; max-width: 34rem; }
.reveal-box { display: flex; align-items: flex-start; }   /* 1.0.11：撐滿那一格的寬；1.0.12：高度只到一排評分鈕（4 顆在窄螢幕換成兩排時，不會變成一大塊） */
#revealBtn { font: inherit; color: inherit; background: transparent; border: 1px solid currentColor; border-radius: 999px; padding: .5em 1.8em; cursor: pointer; opacity: .8;
  flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .45em; min-height: calc(3.725em + 2px); }
#revealBtn:hover, #revealBtn:focus-visible { opacity: 1; }
.reveal-bar { display: block; width: min(7rem, 100%); height: 3px; border-radius: 2px; overflow: hidden; background: var(--line); }   /* 1.0.11：倒數條在「翻開」鈕裡（像評分鈕底下那一行小字） */
.reveal-bar i { display: block; height: 100%; background: var(--muted); transform-origin: left center; animation: reveal-countdown var(--dur, 5s) linear forwards; }
.reveal-bar.paused i { animation-play-state: paused; }
@keyframes reveal-countdown { from { transform: scaleX(1); } to { transform: scaleX(0); } }
#card.btn2 .btn4 { display: none; }
.rate button.good { font-weight: 600; }
.tools { display: flex; gap: 1.2rem; justify-content: center; margin: 1rem 0 0; }
.link-btn { font: inherit; font-size: .85rem; background: none; border: 0; padding: .2em .3em; color: var(--muted); cursor: pointer; text-decoration: underline; text-underline-offset: .2em; }
.link-btn:hover, .link-btn:focus-visible { color: var(--fg); }
.banners { position: fixed; top: .75rem; left: 50%; transform: translateX(-50%); z-index: 20; width: min(40rem, calc(100% - 2rem)); display: flex; flex-direction: column; gap: .4rem; pointer-events: none; }
.banner { pointer-events: auto; margin: 0; padding: .55rem .9rem; border-radius: 10px; border: 1px solid var(--line); background: var(--bg); color: var(--fg); font-size: .9rem; line-height: 1.45; box-shadow: 0 2px 12px color-mix(in srgb, var(--fg) 12%, transparent); }
.banner.bad { border-color: var(--accent); color: var(--accent); }
.banner button { font: inherit; margin-left: .4rem; padding: .1em .8em; border-radius: 999px; border: 1px solid currentColor; background: transparent; color: inherit; cursor: pointer; }
#doneText { margin-bottom: .4rem; }
.done-more { display: inline-block; text-align: left; margin: 0 auto 1rem; padding-left: 1.2rem; font-size: .92rem; }
.done-more li { margin: .25em 0; }
.backup-nudge { color: var(--fg); }
/* 1.2.4（Irene）：「📚 學習」合成一顆鈕（學習頁）、「🛠️ 改裝」（設定）—— 細框圓角，跟卡片上的鈕同一個調子 */
footer .foot-btn { display: inline-flex; align-items: center; gap: .35em; font: inherit; font-size: .85rem; line-height: 1.2; color: var(--muted); background: transparent; border: 1px solid var(--line); border-radius: 999px; padding: .2em .75em .2em .55em; cursor: pointer; }
footer .foot-btn .emo { font-size: 1.25rem; line-height: 1; }
footer .foot-btn:hover, footer .foot-btn:focus-visible, footer .stats-btn[aria-expanded="true"] { color: var(--fg); border-color: color-mix(in srgb, var(--fg) 40%, transparent); }
/* 2.1.0（Irene：「像 Claude 的用量圈圈」）：統計鈕 —— 圓圈＝這個詞表學過幾成，旁邊一個數字＝到期的；點開的小框才寫全部 */
.stats-btn, .stats-panel { --progress: color-mix(in srgb, var(--fg) 55%, var(--bg)); }
.stats-btn .ring { width: 1.25rem; height: 1.25rem; transform: rotate(-90deg); flex: none; }
.stats-btn .ring circle { fill: none; stroke-width: 4.5; }
.stats-btn .ring-track { stroke: var(--line); }
.stats-btn .ring-fill { stroke: var(--progress); }
.stats-btn:hover .ring-fill, .stats-btn[aria-expanded="true"] .ring-fill { stroke: var(--fg); }
.stats-num { font-weight: 600; font-variant-numeric: tabular-nums; min-width: 1ch; text-align: center; }
.stats-panel { position: absolute; right: 0; bottom: calc(100% + .5rem); z-index: 30; width: min(19rem, calc(100vw - 2rem)); box-sizing: border-box;
  display: flex; flex-direction: column; gap: .8rem; padding: .9rem 1rem 1rem; text-align: left; font-size: .85rem; line-height: 1.4;
  background: var(--bg); color: var(--fg); border: 1px solid var(--line); border-radius: 14px; box-shadow: 0 10px 30px color-mix(in srgb, var(--fg) 14%, transparent); }
.stats-panel p { margin: 0; }
.sp-head { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; font-weight: 600; }
.sp-engine { font-weight: 400; font-size: .8rem; color: var(--muted); }
.sp-item { display: flex; flex-direction: column; gap: .4rem; }
.sp-row { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; }
.sp-val { color: var(--muted); font-variant-numeric: tabular-nums; }
.sp-bar { height: 6px; border-radius: 3px; background: var(--line); overflow: hidden; }
.sp-bar i { display: block; height: 100%; width: 0; background: var(--progress); border-radius: inherit; }
.sp-note { font-size: .8rem; color: var(--muted); }
.sp-key { font-size: .75rem; color: var(--muted); border-top: 1px solid var(--line); padding-top: .65rem; }
@media (prefers-reduced-motion: reduce) { .reading.faded { transition: none; } .reveal-bar i { animation: none; } }
/* 讀音依聲調上色（學習頁整頁、設定頁的對照）—— 只管顏色，不動版面 */
.legend .tone-low { color: var(--tone-low); } .legend .tone-falling { color: var(--tone-falling); }
.legend .tone-high { color: var(--tone-high); } .legend .tone-rising { color: var(--tone-rising); }
.legend .tone-mid { color: var(--tone-mid); }
