/* ══════════════════════════════════════════════════════════════════════
   基底元件 — 全站共用，只用 tokens.css 的變數
   命名：.btn / .pill / .card / .stat / .sec / .tbl / .kv / .chip / .hint …
   舊的 cpm-* 名稱在頁面層保留少數，元件一律用這裡的。
   ══════════════════════════════════════════════════════════════════════ */
*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{
  background:var(--ground);color:var(--ink);font-family:var(--font);
  font-size:var(--fs-lg);line-height:1.6;-webkit-font-smoothing:antialiased;
}
button,input,select,textarea{font-family:inherit;font-size:inherit;color:inherit}
button{cursor:pointer}
a{color:var(--accent)}
[hidden]{display:none !important}

/* 數字：比例字體＋等寬數字。等寬字型只給案號、日期、ID */
.num{font-variant-numeric:tabular-nums;font-feature-settings:"tnum"}
.mono{font-family:var(--mono);font-variant-numeric:tabular-nums;font-size:.94em}
.muted{color:var(--ink-3)}
.r{text-align:right}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}

/* 鍵盤焦點：全站統一 */
:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
input:focus-visible,select:focus-visible,textarea:focus-visible{outline-offset:-1px}

/* ── 按鈕：三級 ─────────────────────────────────────────────────────
   primary  藍實心  一個區塊只有一顆
   (default) 灰框   次要動作
   .text    無框    列內操作、取消、刪除
   .danger  只給 .text 用：紅字，不給實心 */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:6px;
  background:var(--panel);color:var(--ink-2);border:1px solid var(--line);
  padding:6px 14px;font-size:15px;font-weight:600;line-height:1.35;white-space:nowrap;
  border-radius:var(--radius);
}
.btn:hover{background:var(--panel-2);color:var(--ink);border-color:var(--ink-3)}
.btn:disabled{opacity:.5;cursor:default}
.btn.primary{background:var(--accent);border-color:var(--accent);color:var(--on-accent)}
.btn.primary:hover{opacity:.9;color:var(--on-accent)}
.btn.dark{background:var(--ink);border-color:var(--ink);color:var(--panel)}
.btn.dark:hover{opacity:.88;color:var(--panel)}
.btn.text{background:none;border-color:transparent;color:var(--accent);padding:4px 8px;font-weight:500}
.btn.text:hover{background:var(--accent-soft);border-color:transparent;color:var(--accent)}
.btn.text.danger{color:var(--crit)}
.btn.text.danger:hover{background:var(--crit-soft)}
.btn.sm{padding:4px 10px;font-size:14px}
.btn.xs{padding:2px 8px;font-size:13px}
.btn.icon{padding:5px 9px;font-size:16px;line-height:1}
.btn.block{width:100%}
label.btn input[type=file]{display:none}

/* ── 徽章 ─────────────────────────────────────────────────────────── */
.pill{
  display:inline-block;font-size:13px;font-weight:600;padding:1px 8px;line-height:1.55;
  border:1px solid var(--line);background:var(--panel-2);color:var(--ink-2);white-space:nowrap;
  border-radius:var(--radius);vertical-align:middle;
}
.pill.crit{color:var(--crit);border-color:var(--crit);background:var(--crit-soft)}
.pill.warn{color:var(--warn);border-color:var(--warn);background:var(--warn-soft)}
.pill.ok{color:var(--ok);border-color:var(--ok);background:var(--ok-soft)}
.pill.info{color:var(--info);border-color:var(--info);background:var(--info-soft)}
.pill.acc{color:var(--accent);border-color:var(--accent);background:var(--accent-soft)}
.pill.acc2{color:var(--accent-2);border-color:var(--accent-2);background:var(--accent-2-soft)}
.pill.muted{color:var(--ink-3);border-color:var(--line);background:var(--panel-2)}
.pill.dark{color:var(--panel);background:var(--ink);border-color:var(--ink)}
/* 流程色相：--h 由 stageHue() 帶進來 */
.pill.hue{
  color:hsl(var(--h) var(--hue-fg-s) var(--hue-fg-l));
  background:hsl(var(--h) var(--hue-bg-s) var(--hue-bg-l));
  border-color:hsl(var(--h) var(--hue-bd-s) var(--hue-bd-l));
}
.pill.xs{font-size:12px;padding:0 6px}
.pill.mono{font-family:var(--mono);font-weight:600}

/* 等級 A/B/C/未定 同一套 */
.grade{font-family:var(--mono);font-size:13px;font-weight:600;padding:0 7px;border:1px solid var(--line);color:var(--ink-3);background:var(--panel-2);display:inline-block;line-height:1.6}
.grade.g-A{color:var(--crit);border-color:var(--crit);background:var(--crit-soft)}
.grade.g-B{color:var(--warn);border-color:var(--warn);background:var(--warn-soft)}
.grade.g-C{color:var(--info);border-color:var(--info);background:var(--info-soft)}

/* 停滯天數：三級一套（30／90），全站同一個門檻 */
.stale{font-variant-numeric:tabular-nums;font-weight:600;white-space:nowrap}
.stale.w1{color:var(--warn)}
.stale.w2{color:var(--crit)}
.stale.approx::after{content:"≈";font-weight:400;color:var(--ink-3);margin-left:2px}

/* ── 卡片與區塊 ────────────────────────────────────────────────────── */
.card{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius)}
.card.raised{box-shadow:var(--shadow)}
.sec{background:var(--panel);border:1px solid var(--line);margin-bottom:var(--sp-4)}
.sec-h{
  padding:9px 14px;background:var(--panel-2);border-bottom:1px solid var(--line);
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
}
.sec-h b{font-size:15px;font-weight:700}
.sec-h .c{font-size:13px;color:var(--ink-3)}
.sec-h .act{margin-left:auto;display:flex;gap:6px;align-items:center}
.sec-b{padding:14px}
.sec-b.flush{padding:0}
.sec.danger{border-color:var(--crit)}
.sec.danger .sec-h{background:var(--crit-soft);border-bottom-color:var(--crit)}

/* 統計卡：顏色只走語意層 */
.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:1px;background:var(--line);border:1.5px solid var(--ink);margin-bottom:var(--sp-5)}
.stat{background:var(--panel);padding:14px 16px;text-align:left;border:0;display:block;width:100%;cursor:default;position:relative}
/* 可點的卡：hover 整張反黑，右上角浮出箭頭——不然沒人知道統計卡可以點 */
.stat.click{cursor:pointer;transition:background .12s}
.stat.click::after{content:"→";position:absolute;right:12px;top:11px;font-size:15px;opacity:0;transition:opacity .12s}
.stats .stat.click:hover,.stats .stat.click:focus-visible{background:var(--ink)}
.stats .stat.click:hover .n,.stats .stat.click:hover .l,.stats .stat.click:hover .s,
.stats .stat.click:focus-visible .n,.stats .stat.click:focus-visible .l,.stats .stat.click:focus-visible .s{color:var(--panel)}
.stat.click:hover::after,.stat.click:focus-visible::after{opacity:.75;color:var(--panel)}
@media (prefers-reduced-motion:reduce){.stat.click,.stat.click::after{transition:none}}
@media (hover:none){.stat.click::after{opacity:.45}}
.stat .n{font-size:var(--fs-2xl);font-weight:700;line-height:1.1;font-variant-numeric:tabular-nums;display:block;letter-spacing:-.01em}
.stat .l{font-size:14px;color:var(--ink);margin-top:5px;line-height:1.4;font-weight:500;display:block}
.stat .s{font-size:12.5px;color:var(--ink-3);display:block;margin-top:1px;line-height:1.4}
.stat .n.crit{color:var(--crit)} .stat .n.warn{color:var(--warn)}
.stat .n.ok{color:var(--ok)} .stat .n.info{color:var(--info)} .stat .n.muted{color:var(--ink-3)}
/* 只改外框顏色。不要再寫 .stats.attention .stat{background} ——
   它跟 .stat.click:hover 同特異性又寫在後面，會把 hover 反黑蓋掉變成白底白字。 */
.stats.attention{border-color:var(--crit)}

/* 提示、註記 */
.hint{margin-top:12px;padding:9px 13px;font-size:14.5px;background:var(--panel-2);border:1px solid var(--line);color:var(--ink-2);line-height:1.6}
.hint b{color:var(--ink)}
.hint.warn{background:var(--warn-soft);border-color:var(--warn);color:var(--ink)}
.hint.ok{background:var(--ok-soft);border-color:var(--ok);color:var(--ink)}
.hint.crit{background:var(--crit-soft);border-color:var(--crit);color:var(--ink)}
.note{font-size:13px;color:var(--ink-3);line-height:1.6;margin-top:10px}
.empty{padding:36px 20px;text-align:center;color:var(--ink-3);font-size:15px;line-height:1.7}
.empty b{color:var(--ink-2)}

/* ── 篩選列 ───────────────────────────────────────────────────────── */
.filters{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin-bottom:12px}
.filters select,.filters input[type=text],.filters input[type=search]{
  background:var(--panel);border:1px solid var(--line);padding:6px 10px;font-size:15px;
}
.chip{background:var(--panel);border:1px solid var(--line);padding:5px 11px;font-size:14.5px;color:var(--ink-2);white-space:nowrap}
.chip:hover{color:var(--ink);border-color:var(--ink-3)}
.chip.on{background:var(--ink);color:var(--panel);border-color:var(--ink);font-weight:600}
.chip .n{font-variant-numeric:tabular-nums;opacity:.75;margin-left:4px;font-size:13px}
.chips{display:flex;gap:6px;flex-wrap:wrap}
.chips.scroll{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;padding-bottom:2px}
.chips.scroll::-webkit-scrollbar{display:none}
.linkbtn{background:none;border:0;color:var(--accent);font-size:14.5px;text-decoration:underline;padding:2px 4px}
.sp{flex:1 1 auto}

/* 摘要列：表格上方固定一行 */
.summary{
  display:flex;gap:18px;flex-wrap:wrap;align-items:center;
  padding:8px 12px;background:var(--panel-2);border:1px solid var(--line);border-bottom:0;
  font-size:13.5px;color:var(--ink-2);
}
.summary b{color:var(--ink);font-variant-numeric:tabular-nums}
.summary .crit b{color:var(--crit)}
.summary .legend{margin-left:auto;display:flex;gap:10px;align-items:center;font-size:12.5px;color:var(--ink-3)}
.summary .legend i{display:inline-block;width:9px;height:9px;margin-right:4px;vertical-align:-1px}
.summary .legend .w0 i{background:var(--ink-3)} .summary .legend .w1 i{background:var(--warn)} .summary .legend .w2 i{background:var(--crit)}

/* ── 表格 ─────────────────────────────────────────────────────────── */
.tblwrap{
  overflow:auto;max-height:calc(100vh / var(--z,1) - 262px);min-height:200px;
  border:1px solid var(--line);background:var(--panel);box-shadow:var(--shadow);
}
.tblwrap.flat{max-height:none;min-height:0;border:0;box-shadow:none}
.tblwrap.auto{max-height:none;min-height:0}
.tbl{border-collapse:separate;border-spacing:0;width:100%;font-size:15px}
.tbl th{
  background:var(--panel-2);font-weight:700;font-size:13px;letter-spacing:.03em;color:var(--ink-2);
  padding:9px 11px;text-align:left;white-space:nowrap;
  box-shadow:inset 0 -1.5px 0 var(--line);position:sticky;top:0;z-index:10;user-select:none;
}
.tbl th.sort{cursor:pointer}
.tbl th.sort:hover{background:var(--panel-3);color:var(--ink)}
.tbl th .ar{color:var(--accent);font-size:11px;margin-left:3px}
.tbl th.r,.tbl td.r{text-align:right}
.tbl td{padding:8px 11px;border-bottom:1px solid var(--line-2);vertical-align:top;background:var(--panel)}
.tbl tbody tr:hover td{background:var(--panel-2)}
.tbl tbody tr:last-child td{border-bottom:0}
.tbl tbody tr.row{cursor:pointer}
.tbl tbody tr.row:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
.tbl td.num{font-variant-numeric:tabular-nums;text-align:right;white-space:nowrap}
.tbl td.dt{font-family:var(--mono);font-size:13.5px;white-space:nowrap;color:var(--ink-2)}
.tbl .nm{font-weight:600;max-width:300px}
.tbl .nm .sub{display:block;font-weight:400;font-size:13px;color:var(--ink-3);margin-top:1px}
.tbl td .sub{display:block;font-size:12.5px;color:var(--ink-3);margin-top:2px}
.tbl.compact td{padding:6px 10px}
.tbl tfoot td{background:var(--panel-2);font-weight:700;border-top:1.5px solid var(--line);position:sticky;bottom:0}
.tbl .more{padding:10px;text-align:center}

/* 可編輯明細表 */
.tbl.edit{font-size:14.5px}
.tbl.edit th{font-size:12.5px;color:var(--ink-3);padding:8px 6px;position:static}
.tbl.edit th:first-child,.tbl.edit td:first-child{padding-left:12px}
.tbl.edit td{padding:3px 4px}
.tbl.edit input,.tbl.edit select{
  width:100%;background:transparent;border:1px solid transparent;padding:5px 7px;font-size:14.5px;min-width:0;
}
.tbl.edit input:hover{border-color:var(--line-2);background:var(--panel-2)}
.tbl.edit input:focus,.tbl.edit select:focus{outline:none;border-color:var(--accent);background:var(--panel);box-shadow:0 0 0 2px var(--accent-soft)}
.tbl.edit input.r{text-align:right;font-variant-numeric:tabular-nums}
.tbl.edit input.strong{font-weight:600}
.tbl.edit input.c{text-align:center}
.tbl.edit input[type=date]{font-family:var(--mono);font-size:13.5px}
/* 日期輸入的清除鈕。
   iOS 的 <input type="date"> 是原生轉輪選擇器、沒有清除鍵，填錯了只能改成別的日期，
   沒辦法變回空白（桌機 Chrome 自帶小叉叉，所以只有手機會遇到）。
   ✕ 用絕對定位疊在輸入框右緣，不佔表格欄寬；有值時才顯示，並幫它留出 padding
   免得蓋到日期文字。 */
.datewrap{position:relative;display:inline-flex;align-items:center;width:100%;min-width:0}
.datewrap > input{flex:1;min-width:0}
.datewrap .dateclr{display:none;position:absolute;right:1px;top:50%;transform:translateY(-50%);
  width:22px;height:22px;padding:0;border:0;background:none;color:var(--ink-3);
  font-size:13px;line-height:1;cursor:pointer;z-index:1}   /* z-index：iOS 原生日期控制項會搶點擊 */
.datewrap.has .dateclr{display:block}
.datewrap.has > input{padding-right:24px}
.datewrap .dateclr:hover{color:var(--crit)}
.datewrap .dateclr:focus-visible{outline:2px solid var(--accent);outline-offset:1px}

.tbl.edit input::placeholder{color:var(--ink-3);opacity:.7;font-style:italic}
.tbl.edit tfoot td{padding:9px 6px;font-size:14.5px;position:static}
.tbl.edit tfoot td.lb{text-align:right;color:var(--ink-2);padding-right:12px}
.tbl.edit tfoot td.num{text-align:right;font-variant-numeric:tabular-nums}
.itemcell{display:flex;gap:4px;align-items:center}
.itemcell input{flex:1 1 auto}

/* 列操作：平常藏起來，hover 或列內有焦點才出現；觸控裝置永遠顯示 */
.rowact{display:flex;gap:2px;justify-content:flex-end;opacity:0;transition:opacity .12s}
tr:hover .rowact,tr:focus-within .rowact,.tl-i:hover .rowact,.tl-i:focus-within .rowact,.att:hover .rowact,.att:focus-within .rowact{opacity:1}
@media (hover:none){.rowact{opacity:1}}
@media (prefers-reduced-motion:reduce){.rowact{transition:none}}
.xbtn{background:none;border:1px solid transparent;color:var(--ink-3);padding:3px 7px;font-size:14px;line-height:1}
.xbtn:hover{color:var(--crit);border-color:var(--crit);background:var(--crit-soft)}

/* ── 表單：分組摺疊＋雙列對齊 ───────────────────────────────────── */
.groups{padding:14px;display:flex;flex-direction:column;gap:12px;background:var(--panel-2)}
.fg{border:1px solid var(--line);background:var(--panel)}
.fg[open]{box-shadow:var(--shadow)}
.fg > summary{
  list-style:none;cursor:pointer;padding:11px 16px;display:flex;align-items:center;gap:10px;
  font-size:15px;font-weight:700;user-select:none;
}
.fg > summary::-webkit-details-marker{display:none}
.fg > summary:hover{background:var(--panel-2)}
.fg > summary .ct{font-size:12.5px;font-weight:600;padding:0 7px;border:1px solid var(--line);color:var(--ink-3);background:var(--panel-2);font-variant-numeric:tabular-nums}
.fg > summary .ct.full{color:var(--ok);border-color:var(--ok);background:var(--ok-soft)}
.fg > summary .ar{margin-left:auto;color:var(--ink-3);font-size:12px;transition:transform .15s}
.fg[open] > summary .ar{transform:rotate(180deg)}
.fg[open] > summary{background:var(--panel-2);border-bottom:1px solid var(--line)}
.fg > .kv{padding:16px}
@media (prefers-reduced-motion:reduce){.fg > summary .ar{transition:none}}

.kv{display:grid;grid-template-columns:repeat(auto-fit,minmax(224px,1fr));gap:16px 22px;grid-auto-rows:auto}
.kv > div{min-width:0;display:grid;grid-template-rows:subgrid;grid-row:span 2;gap:0}
@supports not (grid-template-rows:subgrid){.kv > div{display:block}.kv dt{min-height:2.45rem}}
.kv dt{font-size:13px;color:var(--ink-3);letter-spacing:.03em;margin-bottom:2px;display:flex;align-items:baseline;gap:6px;flex-wrap:wrap;cursor:help}
.kv dt .req{color:var(--crit);font-weight:700}
.kv dt .hint{display:block;flex:0 0 100%;font-size:12px;color:var(--ink-3);margin:0;padding:0;border:0;background:none;cursor:default}
.kv dt .same{margin-left:auto;font-size:12px;color:var(--accent);background:none;border:0;padding:0;cursor:pointer;text-decoration:underline}
.kv dd{margin:0;font-size:15.5px;word-break:break-word}
.kv dd.ro{padding:5px 8px;background:var(--panel-2);border:1px solid var(--line-2);color:var(--ink-2);font-variant-numeric:tabular-nums;min-height:2.1em}
.kv dd.ro.empty{color:var(--ink-3)}
.kv dd input,.kv dd select,.kv dd textarea{width:100%;background:var(--panel-2);border:1px solid var(--line);padding:5px 8px;font-size:15px}
.kv dd input.num{text-align:right;font-variant-numeric:tabular-nums}
.kv dd input.missing,.kv dd select.missing{border-color:var(--warn)}
.kv select.has-legacy{border-color:var(--warn);background:var(--warn-soft)}
.kv .qno{display:flex;gap:6px;align-items:stretch}
.kv .qno input{flex:1 1 auto;min-width:0}
.kv .qno .btn{flex:0 0 auto}
.kv .qno.linked input{border-color:var(--accent);background:var(--accent-soft);font-weight:600}

/* 通用輸入框（設定頁等散落處） */
.in{background:var(--panel-2);border:1px solid var(--line);padding:6px 10px;font-size:15px;min-width:0}
textarea.in{width:100%;resize:vertical;line-height:1.5}
.hrow{display:flex;gap:8px;flex-wrap:wrap;align-items:center}
/* 一排並列的控制項要有小標，不然只看到三個下拉不知道哪個是哪個 */
.hrow>.lb{font-size:13px;color:var(--ink-3);white-space:nowrap;margin-left:4px}
.hrow.mt{margin-top:12px}

/* ── 長條圖 ───────────────────────────────────────────────────────── */
.barlist{display:flex;flex-direction:column;gap:7px}
.barrow{display:grid;grid-template-columns:104px 1fr 56px;gap:10px;align-items:center;font-size:14.5px}
.barrow.pick{cursor:pointer;padding:2px 6px;margin:0 -6px;border:1px solid transparent}
.barrow.pick:hover{background:var(--panel-2);border-color:var(--line)}
.barrow.pick:hover .bl{color:var(--ink);font-weight:600}
.barrow .bl{color:var(--ink-2);text-align:right;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.barrow .bt{display:block;height:14px;background:var(--panel-3);position:relative;overflow:hidden}
.barrow .bf{display:block;height:100%;background:var(--accent);min-width:1px}
.barrow.hue .bf{background:hsl(var(--h) var(--hue-bar-s) var(--hue-bar-l))}
.barrow.muted .bf{background:var(--ink-3)}
.barrow .bv{font-variant-numeric:tabular-nums;font-size:13.5px;color:var(--ink-2);text-align:right}

/* 月份長條（時間維度） */
.mbars{display:grid;grid-auto-flow:column;grid-auto-columns:1fr;gap:6px;align-items:end;height:150px;padding:8px 4px 0}
.mbar{display:flex;flex-direction:column;align-items:center;gap:4px;height:100%;justify-content:flex-end;cursor:pointer;min-width:0}
.mbar .b{width:100%;background:var(--accent);min-height:2px;transition:height .2s}
.mbar.now .b{background:var(--info)}
.mbar .v{font-size:11px;color:var(--ink-3);font-variant-numeric:tabular-nums;white-space:nowrap}
.mbar .m{font-size:11.5px;color:var(--ink-3);white-space:nowrap}
.mbar:hover .b{opacity:.8}
@media (prefers-reduced-motion:reduce){.mbar .b{transition:none}}

/* 迷你進度條（標頭 KPI 用） */
.mini{display:block;height:4px;background:var(--panel-3);margin-top:5px;overflow:hidden}
.mini i{display:block;height:100%;background:var(--accent)}
.mini.ok i{background:var(--ok)} .mini.warn i{background:var(--warn)} .mini.crit i{background:var(--crit)}

/* ── 頁籤 ─────────────────────────────────────────────────────────── */
.tabs{display:flex;gap:2px;border-bottom:1.5px solid var(--ink);background:var(--panel)}
.tabs button{
  background:none;border:0;padding:10px 16px;font-size:16px;font-weight:500;color:var(--ink-2);
  border-bottom:2px solid transparent;margin-bottom:-1.5px;display:flex;align-items:center;gap:7px;white-space:nowrap;
}
.tabs button:hover{color:var(--ink);background:var(--panel-2)}
.tabs button.on{color:var(--ink);font-weight:700;border-bottom-color:var(--accent)}
.tabs button .n{font-size:12.5px;font-weight:600;color:var(--ink-3);background:var(--panel-2);border:1px solid var(--line);padding:0 6px;font-variant-numeric:tabular-nums}
.tabs button.on .n{color:var(--accent);border-color:var(--accent);background:var(--accent-soft)}
.pane{display:none}
.pane.on{display:block}

/* 大頁籤（設定頁） */
.bigtabs{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:1px;background:var(--line);border:1.5px solid var(--ink);margin-bottom:20px}
.bigtabs button{background:var(--panel);border:0;padding:12px 14px;text-align:left;font-size:15.5px;font-weight:600;color:var(--ink-2);line-height:1.3;border-bottom:3px solid transparent}
.bigtabs button .d{display:block;font-size:12.5px;font-weight:400;color:var(--ink-3);margin-top:3px}
.bigtabs button:hover{background:var(--panel-2)}
.bigtabs button.on{color:var(--ink);border-bottom-color:var(--accent);background:var(--panel-2)}
.bigtabs button.on .d{color:var(--ink-2)}

/* 錨點列（財務頁） */
.anchors{display:flex;gap:4px;flex-wrap:wrap;position:sticky;top:0;z-index:5;background:var(--ground);padding:0 0 10px;margin:-4px 0 6px}
.anchors button{background:var(--panel);border:1px solid var(--line);padding:4px 11px;font-size:13.5px;color:var(--ink-2)}
.anchors button:hover{color:var(--ink);border-color:var(--ink-3)}

/* ── 時間軸 ───────────────────────────────────────────────────────── */
.tl{position:relative;padding-left:20px}
.tl:before{content:"";position:absolute;left:5px;top:5px;bottom:5px;width:1px;background:var(--line)}
.tl-i{position:relative;padding:0 0 14px 4px;margin-left:-4px}
.tl-i:last-child{padding-bottom:0}
.tl-i:before{content:"";position:absolute;left:-15px;top:7px;width:9px;height:9px;background:var(--trk,var(--accent));border:2px solid var(--panel);border-radius:50%}
.tl-i .hd{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.tl-i .d{font-family:var(--mono);font-size:13.5px;color:var(--ink-3)}
.tl-i .tk{font-size:12px;font-weight:600;padding:0 6px;border:1px solid var(--trk,var(--accent));color:var(--trk,var(--accent));background:var(--trk-soft,var(--accent-soft));white-space:nowrap}
.tl-i .s{font-size:12.5px;font-weight:600;padding:0 6px;background:var(--panel-2);border:1px solid var(--line);color:var(--ink-2)}
.tl-i .c{font-size:15.5px;margin-top:3px;white-space:pre-wrap;word-break:break-word}
.tl-i .a{font-size:13px;color:var(--ink-3);margin-top:3px;display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.tl-i .a .rowact{margin-left:auto}
.tl-i .att-strip{display:flex;gap:6px;flex-wrap:wrap;margin-top:6px}
.tl-i .ed-mark,.wkrow .ed-mark{font-size:11.5px;color:var(--ink-3)}
/* 編輯中的那一筆：整塊反白，一眼看得出正在改哪一條 */
.tl-i.editing{background:var(--panel-2);border:1px solid var(--line);padding:9px 11px 11px;margin-left:-7px}
.tl-ed .row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.tl-ed .row.end{justify-content:flex-end;margin-top:9px}
.tl-ed .ed-date{background:var(--panel);border:1px solid var(--line);padding:5px 9px;font-size:14.5px;font-family:var(--mono)}
.tl-ed .ed-text{width:100%;margin-top:8px;background:var(--panel);border:1.5px solid var(--ink);
  padding:9px 11px;font-size:16px;resize:vertical;min-height:72px;font-family:inherit}

/* 軌道配色：依索引循環，設定頁加第 5 軌以後回到第 1 色 */
.tk0{--trk:var(--accent);--trk-soft:var(--accent-soft)}
.tk1{--trk:var(--accent-2);--trk-soft:var(--accent-2-soft)}
.tk2{--trk:var(--ok);--trk-soft:var(--ok-soft)}
.tk3{--trk:var(--warn);--trk-soft:var(--warn-soft)}
.tk4{--trk:var(--info);--trk-soft:var(--info-soft)}
.trk{border:1px solid var(--line);background:var(--panel-2);color:var(--ink-2);padding:5px 13px;font-size:14.5px;font-weight:600;white-space:nowrap}
.trk.on{background:var(--trk-soft,var(--accent-soft));color:var(--trk,var(--accent));border-color:var(--trk,var(--accent))}
.trkf{border:1px solid var(--line);background:var(--panel);color:var(--ink-3);padding:2px 9px;font-size:13px;font-weight:600;white-space:nowrap}
.trkf.on{background:var(--trk,var(--ink));border-color:var(--trk,var(--ink));color:var(--on-accent)}
.trkf.all.on{background:var(--ink);border-color:var(--ink);color:var(--panel)}

/* 狀態列（進度頁頂端） */
.statusbar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:8px 12px;margin-bottom:12px;border:1px solid var(--line);border-left-width:3px;background:var(--panel-2);font-size:14px}
.statusbar.hue{border-left-color:hsl(var(--h) var(--hue-bar-s) var(--hue-bar-l));background:hsl(var(--h) 55% 45% / var(--hue-tint))}
.statusbar label{font-weight:600;color:var(--ink-2);white-space:nowrap}
.statusbar select{background:var(--panel);border:1px solid var(--line);padding:5px 10px;font-size:15px;font-weight:600;min-width:130px}
.statusbar .since{color:var(--ink-3);font-size:13px}

/* 快速記錄 */
.quick{display:grid;grid-template-columns:132px 150px 1fr;gap:8px;margin-bottom:10px}
.quick input,.quick select{background:var(--panel-2);border:1px solid var(--line);padding:6px 9px;font-size:15px;min-width:0}
.quick textarea{grid-column:1/-1;background:var(--panel);border:1.5px solid var(--ink);padding:9px 11px;font-size:16px;resize:vertical;min-height:72px}
.quick textarea::placeholder{color:var(--ink-3)}

/* ── 抽屜 ─────────────────────────────────────────────────────────── */
.mask{position:fixed;inset:0;background:rgba(10,15,20,.45);z-index:80;display:none;backdrop-filter:blur(2px)}
.mask.on{display:block}
.drawer{
  position:fixed;top:0;right:0;bottom:0;width:min(var(--drawer-w),100%);background:var(--ground);
  z-index:90;transform:translateX(100%);transition:transform .22s ease;
  display:flex;flex-direction:column;
}
/* 陰影只在打開時才有：收起時抽屜只是推到畫面外，陰影會漏一條在螢幕最右邊（放大 2 倍時約 80px 寬） */
.drawer.on{transform:translateX(0);box-shadow:-8px 0 40px rgba(0,0,0,.2)}
@media (prefers-reduced-motion:reduce){.drawer{transition:none}}
.dh{background:var(--panel);border-bottom:1.5px solid var(--ink);padding:12px 20px 10px;display:flex;align-items:flex-start;gap:12px;flex:0 0 auto}
.dh .dmain{min-width:0;flex:1}
.dh h3{margin:0 0 4px;font-size:19px;font-weight:900;letter-spacing:-.01em;line-height:1.3;display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.dh .sub{font-size:13.5px;color:var(--ink-3);display:flex;gap:8px 12px;flex-wrap:wrap;align-items:center}
.dh .x{background:var(--panel-2);border:1px solid var(--line);padding:5px 11px;font-size:17px;line-height:1;margin-left:auto;flex:0 0 auto}
.dh .kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(130px,1fr));gap:14px;margin-top:10px;max-width:620px}
.dh .kpi i{display:block;font-style:normal;font-size:12px;color:var(--ink-3);letter-spacing:.04em}
.dh .kpi b{display:block;font-size:24px;font-weight:700;line-height:1.15;font-variant-numeric:tabular-nums;letter-spacing:-.01em}
.dh .kpi b .u{font-size:13px;font-weight:500;color:var(--ink-3);margin-left:3px}
.dh .kpi.empty b{color:var(--ink-3);font-weight:400;font-size:18px}
.db{flex:1 1 auto;overflow-y:auto;padding:16px 20px 60px}

/* ── 彈窗（材料表／報價單／確認） ─────────────────────────────────── */
.modalmask{position:fixed;inset:0;z-index:120;background:rgba(10,15,20,.5);display:flex;align-items:center;justify-content:center;padding:24px;backdrop-filter:blur(2px)}
.modal{background:var(--ground);border:1.5px solid var(--ink);width:min(960px,100%);max-height:min(78vh / var(--z,1),720px);display:flex;flex-direction:column;box-shadow:var(--shadow-lg)}
.modal.sm{width:min(440px,100%)}
.modal-h{display:flex;align-items:center;gap:12px;padding:12px 18px;background:var(--panel);border-bottom:1.5px solid var(--ink)}
.modal-h b{font-size:17px;font-weight:900}
.modal-h .c{font-size:13.5px;color:var(--ink-3)}
.modal-h .x{margin-left:auto;background:var(--panel-2);border:1px solid var(--line);padding:4px 10px;font-size:16px;line-height:1}
.modal-f{padding:12px 18px;background:var(--panel);border-bottom:1px solid var(--line);display:flex;flex-direction:column;gap:9px}
.modal-f input[type=text],.modal-f input[type=search]{background:var(--panel-2);border:1px solid var(--line);padding:8px 12px;font-size:16px;width:100%}
.modal-f .tabs{border:0;background:none;gap:5px;flex-wrap:wrap}
.modal-f .tabs button{border:1px solid var(--line);background:var(--panel-2);padding:4px 12px;font-size:14.5px;margin:0}
.modal-f .tabs button.on{background:var(--ink);color:var(--panel);border-color:var(--ink)}
.modal-b{flex:1 1 auto;overflow-y:auto;background:var(--panel)}
.modal-b .tbl th{position:sticky;top:0}
.modal-b tr.picked td{background:var(--accent-soft);font-weight:600}
.modal-b tr.row:hover td{background:var(--accent-soft)}
.modal-foot{display:flex;align-items:center;gap:16px;flex-wrap:wrap;padding:12px 16px;border-top:1px solid var(--line);background:var(--panel-2)}
.modal-foot .l{display:flex;flex-direction:column;gap:2px;font-size:14px;min-width:170px}
.modal-foot .l .warn{font-size:12.5px;color:var(--warn)}
.modal-foot .n{display:flex;gap:18px;margin-left:auto;font-size:14px;color:var(--ink-2);font-variant-numeric:tabular-nums}
.modal-foot .n b{color:var(--ink);font-size:15px}
.modal .body{padding:18px;font-size:15px;line-height:1.7;background:var(--panel);flex:1 1 auto;min-height:0;overflow-y:auto}   /* 內容比視窗高時在裡面捲，按鈕列固定在底下（2026-10-06 家充上行事曆視窗變長才發現） */
.modal .body input{width:100%;margin-top:10px}
.modal .actions{display:flex;gap:8px;justify-content:flex-end;padding:12px 18px;background:var(--panel-2);border-top:1px solid var(--line)}

/* 浮窗（欄位歷史、列選單） */
.pop{position:fixed;z-index:400;width:min(340px,92vw / var(--z,1));max-height:min(60vh / var(--z,1),420px);display:flex;flex-direction:column;border:1.5px solid var(--ink);background:var(--panel);box-shadow:var(--shadow-lg)}
.pop .hd{display:flex;align-items:center;gap:8px;padding:8px 12px;background:var(--panel-2);border-bottom:1px solid var(--line)}
.pop .hd b{font-size:14.5px;font-weight:800;flex:1;min-width:0}
.pop .hd .x{background:none;border:none;color:var(--ink-3);font-size:15px;line-height:1;padding:2px 4px}
.pop .bd{flex:1 1 auto;overflow-y:auto;padding:4px 0}
.pop .item{padding:8px 12px;border-bottom:1px solid var(--line-2);font-size:13.5px;line-height:1.6;display:block}
.pop .item:last-child{border-bottom:none}
.pop .who{font-weight:700;color:var(--ink)}
.pop .when{font-family:var(--mono);font-size:12.5px;color:var(--ink-3);margin-left:6px}
.pop .val{font-size:13px;color:var(--ink-2);margin-top:2px;word-break:break-all}
.pop .val b{color:var(--ink)}
.pop .none{padding:14px 12px;font-size:13.5px;color:var(--ink-3);line-height:1.7}
.menu{position:fixed;z-index:400;min-width:170px;background:var(--panel);border:1.5px solid var(--ink);box-shadow:var(--shadow-lg);padding:4px 0}
.menu button{display:block;width:100%;text-align:left;background:none;border:0;padding:8px 14px;font-size:14.5px;color:var(--ink)}
.menu button:hover{background:var(--panel-2)}
.menu button.danger{color:var(--crit)}
.menu hr{border:0;border-top:1px solid var(--line-2);margin:4px 0}

/* ── toast 與存檔狀態 ───────────────────────────────────────────── */
.toast{position:fixed;left:50%;bottom:28px;transform:translateX(-50%) translateY(20px);background:var(--ink);color:var(--panel);padding:10px 20px;font-size:15.5px;font-weight:500;z-index:200;opacity:0;transition:.2s;pointer-events:none;box-shadow:var(--shadow);max-width:min(560px,92vw / var(--z,1))}
.toast.on{opacity:1;transform:translateX(-50%) translateY(0)}
.toast.err{background:var(--crit);color:#fff}
.savestate{font-size:13px;color:var(--ink-3);white-space:nowrap;padding:5px 8px;border:1px solid transparent;font-variant-numeric:tabular-nums}
.savestate.busy{color:var(--accent)}
.savestate.off{color:var(--crit);border-color:var(--crit);background:var(--crit-soft)}
.savestate.ok{color:var(--ink-3)}

/* ── 附件 ─────────────────────────────────────────────────────────── */
.atts{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:10px}
.att{border:1px solid var(--line);background:var(--panel);display:flex;flex-direction:column;min-width:0}
.att .th{aspect-ratio:4/3;background:var(--panel-3);display:flex;align-items:center;justify-content:center;overflow:hidden;color:var(--ink-3);font-size:26px;cursor:pointer}
.att .th img{width:100%;height:100%;object-fit:cover;display:block}
.att .nm{font-size:12.5px;padding:6px 8px 2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.att .mt{font-size:11.5px;color:var(--ink-3);padding:0 8px 6px;display:flex;gap:6px;align-items:center}
.att .mt .rowact{margin-left:auto}
.att-mini{width:56px;height:56px;border:1px solid var(--line);background:var(--panel-3);object-fit:cover;display:block;cursor:pointer}
.att-mini.file{display:flex;align-items:center;justify-content:center;font-size:11px;color:var(--ink-2);text-align:center;padding:4px;overflow:hidden;line-height:1.2}
.rules{background:var(--panel-2);border:1px solid var(--line);padding:11px 14px;margin-bottom:10px;font-size:13.5px;line-height:1.75}
.rules b{display:block;font-size:14px;margin-bottom:3px}
.rules .y::before{content:"✔ ";color:var(--ok);font-weight:700}
.rules .n::before{content:"✕ ";color:var(--crit);font-weight:700}
.rules .i::before{content:"ⓘ ";color:var(--accent);font-weight:700}
.rules .f::before{content:"📁 "}
.rules .f{margin-top:4px;padding-top:5px;border-top:1px solid var(--line-2)}
.rules .mono{font-size:12.5px;color:var(--ink-2)}
/* 卡片檢視的排序控制項。表格靠點表頭排序，卡片沒有表頭，就靠這一組。 */
.sortbar{display:flex;align-items:center;gap:6px;margin-left:auto}
.sortbar .lb{font-size:13px;color:var(--ink-3);white-space:nowrap}
.sortbar select{min-width:104px}
.sortbar .btn{white-space:nowrap;font-variant-numeric:tabular-nums}

/* 加到主畫面的提示條。只在手機、且還沒裝的時候出現，按過「不用了」就不再來 */
.installbar{display:flex;align-items:center;gap:10px;padding:10px 12px;margin-bottom:12px;
  background:var(--ink);color:var(--panel);border:1.5px solid var(--ink)}
.installbar .t{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}
.installbar .t b{font-size:14.5px}
.installbar .t span{font-size:12.5px;opacity:.72}
.installbar .btn.primary{background:var(--panel);color:var(--ink);border-color:var(--panel)}
.installbar .btn.text{color:var(--panel);opacity:.7}

/* 財務頁裡的小標（標準成本／選配成本）。不用 .sec 是因為它們同屬「合約與金額」一段，
   多包一層框會讓那一頁看起來像三個不相干的區塊。 */
.subhd{display:flex;align-items:baseline;gap:8px;margin:16px 0 8px;padding-top:12px;border-top:1px solid var(--line-2)}
.subhd b{font-size:14px}
.subhd span{font-size:12.5px;color:var(--ink-3)}

/* 安裝步驟。編號是真的順序（一定要照著按），所以用有序清單不是條列 */
.steps{counter-reset:s;list-style:none;margin:0;padding:0;display:grid;gap:7px}
.steps li{counter-increment:s;display:flex;gap:10px;font-size:14.5px;line-height:1.6}
.steps li::before{content:counter(s);flex:0 0 22px;height:22px;margin-top:1px;
  display:grid;place-items:center;background:var(--ink);color:var(--panel);
  font-family:var(--mono);font-size:12px;font-weight:600}

.dropzone{border:1.5px dashed var(--line);padding:18px;text-align:center;color:var(--ink-3);font-size:14.5px;background:var(--panel-2)}
.dropzone.over{border-color:var(--accent);background:var(--accent-soft);color:var(--accent)}
.up-progress{font-size:13px;color:var(--accent);margin-top:8px}

/* 收款進度條 */
.recv{padding:12px 14px;border-bottom:1px solid var(--line)}
.recv .hd{font-size:14px;font-weight:600;margin-bottom:6px;display:flex;gap:8px;align-items:baseline}
.recv .hd span{font-weight:400;font-size:12.5px;color:var(--ink-3)}
.recv .hd .pct{margin-left:auto;font-weight:700;color:var(--ok);font-size:16px;font-variant-numeric:tabular-nums}
.recvbar{display:flex;height:14px;border-radius:7px;overflow:hidden;border:1px solid var(--ink);background:var(--panel)}
.recvbar span{display:block;height:100%}
.recvbar .paid{background:var(--ok)} .recvbar .inv{background:var(--line)} .recvbar .plan{background:var(--panel)}
.recvkey{display:flex;flex-wrap:wrap;gap:6px 16px;margin-top:8px;font-size:13px;color:var(--ink-2);font-variant-numeric:tabular-nums}
.recvkey .k{display:inline-flex;align-items:center;gap:6px}
.recvkey i{width:11px;height:11px;border-radius:3px;border:1px solid var(--ink);flex:none}
.recvkey .paid i{background:var(--ok);border-color:var(--ok)} .recvkey .inv i{background:var(--line)} .recvkey .plan i{background:var(--panel)}
tr.rc-paid td:first-child{box-shadow:inset 3px 0 0 var(--ok)}
tr.rc-inv td:first-child{box-shadow:inset 3px 0 0 var(--line)}
tr.rc-paid input[data-f="paidDate"]{color:var(--ok);font-weight:600}

/* 損益表 */
.plrow{display:flex;align-items:baseline;gap:14px;padding-bottom:10px;border-bottom:1.5px solid var(--line);margin-bottom:10px;flex-wrap:wrap}
.plrow .lb{font-size:15px;color:var(--ink-2);font-weight:500}
.plrow .v{margin-left:auto;font-size:24px;font-weight:700;font-variant-numeric:tabular-nums}
.plrow .v .sub{font-size:13px;font-weight:400;color:var(--ink-3);margin-left:8px}
.pltbl{width:100%;border-collapse:collapse;font-size:15.5px}
.pltbl th{font-size:13px;color:var(--ink-3);font-weight:600;letter-spacing:.04em;text-align:right;padding:0 0 6px;border-bottom:1px solid var(--line-2)}
.pltbl th:first-child{text-align:left}
.pltbl td{padding:7px 0;border-bottom:1px solid var(--line-2)}
.pltbl td.lb{color:var(--ink-2)}
.pltbl td.v{text-align:right;font-variant-numeric:tabular-nums;padding-left:14px;white-space:nowrap}
.pltbl tr.gp td{font-weight:700;font-size:17px}
.pltbl td.v.pos{color:var(--ok)} .pltbl td.v.neg{color:var(--crit)}
.pltbl td.v .sub{display:block;font-size:12.5px;font-weight:400;opacity:.85;margin-top:1px}
.pltbl tr:last-child td{border-bottom:0}
.plfoot{margin-top:12px;padding-top:10px;border-top:1px solid var(--line);display:flex;flex-direction:column;gap:5px}
.plfoot > div{display:flex;align-items:baseline;font-size:15.5px}
.plfoot .lb{color:var(--ink-2)}
.plfoot .v{margin-left:auto;font-variant-numeric:tabular-nums}
.plfoot .tot .lb{font-weight:700} .plfoot .tot .v{font-weight:700;font-size:18px}
.plfoot .v.pos{color:var(--ok)} .plfoot .v.neg{color:var(--crit)}

/* 成員 chip、對照表 */
.members{display:flex;flex-wrap:wrap;gap:8px}
.member{display:inline-flex;align-items:center;gap:7px;border:1px solid var(--line);background:var(--panel-2);padding:5px 10px;font-size:14px}
.member.adm{border-color:var(--accent);background:var(--accent-soft);color:var(--accent)}
.member em{font-style:normal;font-size:12px;color:var(--ink-3);font-family:var(--mono)}
.member select{font-size:12.5px;padding:1px 4px;background:var(--panel);border:1px solid var(--line)}
.member .x{background:none;border:none;color:var(--ink-3);font-size:14px;line-height:1;padding:0 2px}
.member .x:hover{color:var(--crit)}
.legacyval{font-size:13.5px;padding:2px 9px;background:var(--panel);border:1px solid var(--line);color:var(--ink-2);font-family:var(--mono);display:inline-flex;gap:6px;align-items:center}
.legacyval b{color:var(--crit);font-weight:600}
.fieldrow{display:flex;gap:8px;align-items:center;padding:7px 0;border-bottom:1px solid var(--line-2);flex-wrap:wrap}
.fieldrow:last-child{border-bottom:0}
.fieldrow .k{font-family:var(--mono);font-size:13px;color:var(--ink-3);flex:0 0 120px}
.fieldrow .nm{font-weight:600;font-size:15px;flex:1 1 140px}
.fieldrow .ty{font-size:13px;color:var(--ink-2)}
.fieldrow select,.fieldrow input{font-size:13.5px;padding:2px 6px;background:var(--panel-2);border:1px solid var(--line)}

/* 同步結果面板 */
.syncbox{border:1px solid var(--line);background:var(--panel);margin-top:12px}
.syncbox h5{margin:0;padding:10px 14px;font-size:14.5px;font-weight:800;background:var(--panel-2);border-bottom:1px solid var(--line)}
.syncbox ul{margin:0;padding:10px 14px 12px 30px;font-size:14px;line-height:1.75}
.syncbox li.warn{color:var(--warn)}
.syncbox .none{padding:12px 14px;color:var(--ink-3);font-size:14px}
.syncbox .chg{font-family:var(--mono);font-size:13px}
.syncbox .pad{padding:0 14px 14px}

/* 報價單狀態 */
.qst{display:inline-block;padding:0 8px;font-size:12.5px;font-weight:700;border:1px solid currentColor;white-space:nowrap;line-height:1.6}
.qst.won{color:var(--ok);background:var(--ok-soft)}
.qst.sent{color:var(--accent);background:var(--accent-soft)}
.qst.draft,.qst.lost{color:var(--ink-3);background:var(--panel-2)}

/* 健康檢查列 */
.health{display:flex;flex-direction:column;gap:6px}
.health .h{display:flex;align-items:center;gap:10px;padding:9px 12px;border:1px solid var(--line);background:var(--panel)}
.health .h .n{font-weight:700;font-variant-numeric:tabular-nums;min-width:44px;text-align:right;font-size:17px}
.health .h .n.ok{color:var(--ok)} .health .h .n.warn{color:var(--warn)} .health .h .n.crit{color:var(--crit)} .health .h .n.muted{color:var(--ink-3)}
.health .h .t{flex:1;font-size:14.5px}
.health .h .t small{display:block;color:var(--ink-3);font-size:12.5px}

/* 載入指示 */
.boot{position:fixed;inset:0;z-index:200;background:var(--ground);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:14px;font-size:15px;color:var(--ink-2)}
.boot .spin{width:28px;height:28px;border:2.5px solid var(--line);border-top-color:var(--accent);border-radius:50%;animation:spin .8s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
@media(prefers-reduced-motion:reduce){.boot .spin{animation-duration:2.4s}}
.skeleton{background:linear-gradient(90deg,var(--panel-2),var(--panel-3),var(--panel-2));background-size:200% 100%;animation:sk 1.2s linear infinite;height:14px;margin:8px 0}
@keyframes sk{to{background-position:-200% 0}}
