:root{
  --bg:#f7f7f5; --card:#fff; --ink:#1d1d1b; --muted:#6b6b66; --line:#e0e0da;
  --spoken:#e8f1fc; --spoken-b:#8fb6e8;
  --shown:#e7f5ec; --shown-b:#87c79f;
  --analysis:#fdf3dc; --analysis-b:#e0be6a;
  --background:#eeeeec; --background-b:#b9b9b3;
  --insufficient:#fbe9e7; --insufficient-b:#e09b90;
  --warn:#a8631a; --err:#b3261e;
}
*{box-sizing:border-box}
body{margin:0;background:var(--bg);color:var(--ink);
  font:15px/1.65 "Noto Sans TC","PingFang TC","Microsoft JhengHei",system-ui,sans-serif}
main{max-width:1600px;margin:0 auto;padding:0 20px 80px}
a{color:#1a5fb4}
h1{font-size:24px;margin:24px 0 4px}
h2{font-size:17px;margin:0 0 10px}
code{background:#ececea;padding:1px 5px;border-radius:3px;font-size:.9em}
.top{display:flex;gap:14px;align-items:baseline;padding:12px 20px;
  border-bottom:1px solid var(--line);background:#fff;position:sticky;top:0;z-index:30}
.brand{font-weight:600;text-decoration:none;color:var(--ink)}
.top-right{margin-left:auto;font-size:14px}
.muted{color:var(--muted)}
.small{font-size:12px}
.path{color:var(--muted);font-size:13px;word-break:break-all;margin:2px 0 16px}
.card{background:var(--card);border:1px solid var(--line);border-radius:8px;
  padding:16px;margin:16px 0}
.row{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin:8px 0}
button{font:inherit;padding:5px 11px;border:1px solid var(--line);border-radius:5px;
  background:#fff;cursor:pointer}
button:hover{background:#f0f0ee}
button:disabled{opacity:.5;cursor:default}
.btn-link{margin-left:10px}
input,select,textarea{font:inherit;padding:5px 8px;border:1px solid var(--line);
  border-radius:5px;background:#fff;max-width:100%}
textarea{width:100%;resize:vertical}
label{display:block;margin:8px 0}
label.chk,label.chk input{display:inline-block;margin:0 4px 0 0;width:auto}
form{margin:0}
.grid{border-collapse:collapse;width:100%;font-size:14px}
.grid th{text-align:left;color:var(--muted);font-weight:500;font-size:12px;
  border-bottom:1px solid var(--line);padding:4px 8px}
.grid td{border-bottom:1px solid var(--line);padding:6px 8px;vertical-align:top}
.num{text-align:right;font-variant-numeric:tabular-nums}
.tag{display:inline-block;font-size:11px;background:#e3ecfa;color:#1a5fb4;
  padding:0 6px;border-radius:9px;margin-left:4px}
.warn{color:var(--warn)}
.err,.err-inline{color:var(--err)}
.err{background:#fbe9e7;border:1px solid var(--insufficient-b);padding:8px 10px;border-radius:6px}
.log{background:#1d1d1b;color:#e6e6e3;padding:10px 12px;border-radius:6px;
  font-size:12.5px;max-height:280px;overflow:auto;white-space:pre-wrap;margin:0}
.stage-failed td{background:#fdf0ef}

/* 播放器。切片頁還是上下排（波形要整個寬度），Talk 頁是左右兩欄。 */
.player-wrap{display:flex;gap:16px;align-items:flex-start;position:sticky;top:49px;
  z-index:20;background:var(--bg);padding:12px 0;border-bottom:1px solid var(--line)}
video{width:520px;max-width:60vw;background:#000;border-radius:6px}
.player-side{flex:1;min-width:0}
.clock{font-size:26px;font-variant-numeric:tabular-nums;margin-bottom:6px}

/* Talk 頁的兩欄。影片和控制項固定在左邊，讀的東西全部在右邊。
   左欄要黏住，align-self 一定要寫：flex 的預設是 stretch，被拉滿高度的
   元素 sticky 沒有作用（它已經跟容器一樣高了，沒有可以滑動的餘裕）。 */
.talk-split{display:flex;gap:24px;align-items:flex-start}
.talk-left{flex:0 0 460px;position:sticky;top:61px;align-self:flex-start;
  padding-top:12px}
.talk-right{flex:1;min-width:0;padding-top:12px}
.talk-left video{width:100%;max-width:none;display:block}
.clock-row{display:flex;gap:6px;align-items:center;flex-wrap:wrap;margin:8px 0 6px}
.clock-row .clock{font-size:22px;margin:0;flex:1}
.now-cue{font-size:13px;line-height:1.5;min-height:3.2em;background:#fbfbf9;
  border:1px solid var(--line);border-radius:6px;padding:6px 9px}
.view-opts{margin-top:8px;font-size:13px}
.view-opts summary{cursor:pointer;color:var(--muted)}
.view-opts label.chk{display:block;margin:6px 0}

/* 窄畫面回到單欄，影片回到最上面並黏在那裡。
   這時候影片和控制項改成左右排，不是讓影片佔滿整個寬度：黏住的那一塊
   一旦高過螢幕的一半，底下要讀的東西就沒地方了。 */
@media (max-width:1100px){
  .talk-split{display:block}
  .talk-left{position:sticky;top:49px;z-index:20;background:var(--bg);
    padding:10px 0;border-bottom:1px solid var(--line);margin-bottom:12px;
    display:flex;gap:14px;align-items:flex-start}
  .talk-left video{flex:0 0 auto;width:420px;max-width:52vw;max-height:34vh;
    object-fit:contain}
  .talk-controls{flex:1;min-width:0}
  .clock-row{margin-top:0}
  .talk-right{padding-top:0}
  .now-cue{min-height:0}
}

/* 手機。影片再讓一點高度出來，控制項回到影片底下。 */
@media (max-width:640px){
  .talk-left{display:block}
  .talk-left video{width:100%;max-width:none;max-height:30vh}
  .clock-row{margin-top:6px}
}

/* 波形 */
canvas{width:100%;display:block;background:#fbfbf9;border:1px solid var(--line);
  border-radius:6px;cursor:crosshair}
/* 高度要用 CSS 寫死。只給 width:100% 的話 canvas 會照 300×H 的比例把自己拉高 */
#wave{height:150px}
#wave-zoom{height:80px;margin-bottom:8px}

/* 分頁 */
.tabs{display:flex;gap:4px;margin:18px 0 0;border-bottom:1px solid var(--line)}
.tabs a{padding:7px 14px;text-decoration:none;color:var(--muted);
  border:1px solid transparent;border-bottom:none;border-radius:6px 6px 0 0}
.tabs a.on{background:#fff;border-color:var(--line);color:var(--ink)}

/* 逐字稿 */
.transcript td{padding:5px 8px}
.transcript .tc{width:78px;white-space:nowrap}
.transcript .voice{width:110px;font-size:12px;color:var(--muted)}
.transcript .rev{width:88px;text-align:right;white-space:nowrap}
.transcript tr.presenter .voice{color:#1a5fb4}
.transcript tr.playing{background:#fff6d8}
.layer{display:flex;gap:8px;align-items:baseline}
.layer .lbl{flex:0 0 78px;font-size:11px;color:var(--muted);text-transform:lowercase}
.layer .txt{flex:1}
.active-corrected .lbl{color:#1a7f37;font-weight:600}
.hide-alt .alt{display:none}
/* 逐字稿搜尋：篩掉的列用 hidden 屬性藏起來，命中的字用 <mark> 標出來 */
.transcript tr[hidden]{display:none}
.transcript mark{background:#ffe680;padding:0 1px;border-radius:2px}
#cue-find{max-width:20em}
.hist{margin-top:6px;font-size:13px}

/* 問答 */
.conv{padding:4px 10px;border:1px solid var(--line);border-radius:14px;
  text-decoration:none;color:var(--muted);background:#fff}
.conv.on{background:#e3ecfa;color:#1a5fb4;border-color:#b9cff0}
.msg{border-top:1px solid var(--line);padding:14px 0}
.msg .q{display:flex;gap:10px;align-items:baseline;margin-bottom:8px}
.msg .qtext{font-weight:600;flex:1}
/* 版本切換（ADR 0014）。只有一版的時候整個不出現，那是雜訊 */
.msg .versions{display:inline-flex;align-items:center;gap:4px;font-size:12px;
  color:var(--muted);white-space:nowrap}
.msg .versions button{padding:0 6px;line-height:1.6;font-size:13px}
.msg .versions .off{padding:0 6px;opacity:.3}
.msg .edit-q{display:flex;gap:8px;align-items:flex-start;margin:0 0 10px}
.msg .edit-q textarea{flex:1;font:inherit;padding:6px}
/* 這一版回答的是別的問題（3-3）。跟 stale-note 同一個家族：都是在講
   「你現在看到的東西，對的不是你以為的那個東西」 */
.msg .asked-note{background:#fdf3e3;border-left:3px solid #d79b3e;
  padding:6px 10px;margin-bottom:8px;font-size:13px}
.del{color:var(--err);border-color:#f0d5d2}
.running{color:var(--muted)}
.running button{margin-top:6px}
.cancelled{color:var(--muted);background:#f3f1ee;border:1px solid var(--line);
  padding:8px 10px;border-radius:6px}
.bar{height:3px;background:#e6e6e3;border-radius:2px;overflow:hidden;margin-top:6px}
.bar i{display:block;height:100%;width:35%;background:#8fb6e8;
  animation:slide 1.4s ease-in-out infinite}
@keyframes slide{0%{margin-left:-35%}100%{margin-left:100%}}
.verdict{font-size:13px;padding:6px 10px;border-radius:6px;margin-bottom:10px;
  background:#eef7f0;border:1px solid #c6e2cf}
.verdict.downgraded{background:#fdf3dc;border-color:var(--analysis-b);color:#7a5410}
.verdict.flagged{background:#f4f2fb;border-color:#c3bbe4;color:#4d4276}
.trace{margin-top:6px}
.trace summary{cursor:pointer}
.trace .attempt{margin:6px 0}
.trace ul{margin:2px 0 0;padding-left:20px}
.trace .ok{color:#1a7f37}
.block{border-left:4px solid var(--line);background:#fff;padding:8px 12px;
  margin:8px 0;border-radius:0 6px 6px 0}
.block .kind{font-size:11px;color:var(--muted);margin-bottom:2px}
.block .raw-kind{margin-left:6px;opacity:.6}
.block .voice{margin-left:6px;padding:0 5px;border:1px solid currentColor;border-radius:3px;font-size:.9em}
.kind-spoken{background:var(--spoken);border-left-color:var(--spoken-b)}
.kind-shown{background:var(--shown);border-left-color:var(--shown-b)}
.kind-analysis{background:var(--analysis);border-left-color:var(--analysis-b)}
.kind-background{background:var(--background);border-left-color:var(--background-b)}
.kind-insufficient{background:var(--insufficient);border-left-color:var(--insufficient-b)}
.cites{margin-top:6px;display:flex;gap:6px;flex-wrap:wrap}
.cite{font-size:12px;padding:2px 8px;background:#fff;border-radius:12px}
.cite.stale{background:#f3f1ee;color:var(--muted);border-style:dashed;
  text-decoration:line-through;cursor:not-allowed}
.stale-note{font-size:13px;padding:6px 10px;border-radius:6px;margin-bottom:10px;
  background:#fdf3dc;border:1px solid var(--analysis-b);color:#7a5410}
.cite.revised{border-style:dashed}
.revised-note{font-size:13px;padding:6px 10px;border-radius:6px;margin-bottom:10px;
  background:#f3f1ee;border:1px solid var(--line);color:var(--muted)}
.ask{display:flex;gap:8px;align-items:flex-end;margin-top:14px}
.ask textarea{flex:1}

/* 常用問法與 AI 出的題目 */
.prompts{gap:6px}
.preset{display:inline-flex;align-items:stretch}
.preset button{border-radius:14px 0 0 14px;font-size:13px;max-width:26em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.preset .x{border-radius:0 14px 14px 0;border-left:none;color:var(--muted);
  padding:5px 8px}
.suggest{margin-top:10px;padding:10px 12px;border:1px solid var(--analysis-b);
  border-radius:6px;background:var(--analysis)}
.suggest h3{font-size:14px;margin:0 0 6px}
.suggest ul{margin:0;padding:0;list-style:none}
.suggest li{margin:4px 0}
.suggest li button{text-align:left;width:100%;background:#fff}

/* 投影片彈窗 */
.modal{position:fixed;inset:0;background:rgba(0,0,0,.6);z-index:50;
  display:flex;align-items:center;justify-content:center}
.modal[hidden]{display:none}
.modal-inner{background:#fff;border-radius:8px;padding:10px;max-width:92vw;max-height:92vh;
  display:flex;flex-direction:column;gap:8px}
.modal-bar{display:flex;justify-content:space-between;gap:20px;align-items:center}
.modal img{max-width:88vw;max-height:80vh;object-fit:contain}

/* 字幕。不同 Voice 不同顏色，看得出來換人講話了 */
video::cue{background:rgba(0,0,0,.72);font-size:.9em;line-height:1.5}
video::cue(.voice0){color:#a8d0ff}
video::cue(.voice1){color:#a9e8bf}
video::cue(.voice2){color:#f5d98a}
video::cue(.voice3){color:#f0b3a8}
video::cue(.voice4){color:#d8b8f0}
video::cue(.voice5){color:#e6e6e3}

/* Voice 的顏色點，跟字幕顏色對得起來 */
.vdot{display:inline-block;width:8px;height:8px;border-radius:50%;margin-right:5px;
  background:#b9b9b3;vertical-align:baseline}
.vdot.v0{background:#4a86d8}
.vdot.v1{background:#3fa06a}
.vdot.v2{background:#d3a02a}
.vdot.v3{background:#d1705f}
.vdot.v4{background:#9a6fc4}
.vdot.v5{background:#8a8a84}

/* 多輪問答 */
.tag.mode{background:#efeade;color:#7a5410}
.conv-bar{border-bottom:1px solid var(--line);padding-bottom:10px}
.rewritten-q{font-size:13px;color:var(--muted);margin-bottom:6px}
.mode-note{margin-bottom:4px}

/* 校對建議 */
.fixes .pick{width:26px}
.fix-filter button.on{background:#e3ecfa;border-color:#b9cff0;color:#1a5fb4}
.fix-batch{border-top:1px dashed var(--line);padding-top:8px}
/* 篩選只動 class。thead 不帶 lv- 的 class，所以選擇器只掃 tbody */
.fixes.only-ok tbody tr:not(.lv-ok),
.fixes.only-ok tbody tr.fix-off{display:none}
.fixes.only-warn tbody tr.lv-ok,
.fixes.only-warn tbody tr.fix-off{display:none}
.fixes.only-off tbody tr:not(.fix-off){display:none}
tr.fix-off td{opacity:.45}
tr.fix-off .fixline{text-decoration:line-through}
.fixes td{vertical-align:top}
.fixes .lvl{width:190px;font-size:12px}
.fixes .acts{width:110px;white-space:nowrap}
/* 一格裡的兩三個動作要並排。每一個動作各自是一個 form（htmx 的 post 帶
   自己的 hidden 欄位），而 form 預設是 block，不寫這一條就會上下堆疊。 */
.acts form{display:inline-block;margin-right:4px}
.fixline{line-height:1.9}
.fixline .del{background:#fbe1de;text-decoration:line-through;padding:1px 2px;border-radius:3px}
.fixline .ins{background:#d9f0e1;padding:1px 2px;border-radius:3px;font-weight:600}
tr.lv-near td,tr.lv-unseen td{background:#fdf6e6}
tr.lv-translated td{background:#fbe9e7}
.zh-flag{margin-top:3px;font-size:11px;color:var(--err);background:#fbe9e7;
  border:1px solid var(--insufficient-b);border-radius:3px;padding:1px 4px;
  display:inline-block;cursor:help}
tr.lv-wide td{background:#faf6ef}
.learned{margin-top:14px;padding:10px 12px;border:1px solid var(--shown-b);
  border-radius:6px;background:var(--shown)}
.learned h3{font-size:14px;margin:0 0 6px}
.learned .acts{white-space:nowrap;width:130px}
.learned .del{background:#fbe1de;padding:1px 4px;border-radius:3px;color:var(--ink);
  border:none}
.gloss{margin-top:14px}
.gloss-table .pick{width:26px}
.gloss-table tr.gone td{color:var(--muted);text-decoration:line-through}
.gloss-table tr.gone .acts,.gloss-table tr.gone .tag{text-decoration:none}
.gloss-table td{padding:3px 8px}
.term-note{margin-top:2px}
.gloss summary{cursor:pointer}

/* 自動分段審核表 */
.table-scroll{overflow-x:auto}
table.seg td{vertical-align:top}
table.seg input:not([type=checkbox]),table.seg select{width:auto;max-width:14em}
tr.seg-row{cursor:pointer}
tr.seg-row.flagged{background:#fdf6ec}
tr.seg-row.bad{background:var(--insufficient)}
tr.seg-row.seg-viewing{outline:2px solid rgba(26,127,55,.55)}
.seg-hint{font-size:12.5px;line-height:1.5;min-width:16em}
.seg-hint .ok{color:#1a7f37}

/* 登入頁和登出按鈕 */
.login{max-width:340px;margin:8vh auto}
.login label{display:block;margin:8px 0}
.login input{width:100%;box-sizing:border-box}
form.inline{display:inline}
.linkish{background:none;border:none;color:inherit;text-decoration:underline;
         cursor:pointer;padding:0;font:inherit}
