/* ══════════════════════════════════════════════════════════════════════════
   團購招商後台 —— 設計系統
   ─────────────────────────────────────────────────────────────────────────
   分三層，順序不可顛倒：
     ① 品牌色盤      原本就有的 11 個色值，**一個都沒有改**
     ② 尺度 token    間距／圓角／字級／層級
     ③ 語意別名      --bg／--surface／--text／--border… 元件規則只准用這一層

   為什麼要有第 ③ 層：深色模式若靠「為每條元件規則再寫一條覆寫」，會變成
   兩份互相追趕的樣式表，改一邊忘一邊。改成元件規則一律引用語意別名之後，
   深色模式**只需重新定義 :root 的別名**，元件規則一行都不用動。
   ══════════════════════════════════════════════════════════════════════════ */

:root{
  /* ① 品牌色盤（原封不動；深色模式沿用同一組品牌色） */
  --ink:#15333D; --blue:#3C6E8C; --gold:#A98B5B; --cream:#F1ECE2;
  --sky:#DCE7EF; --paper:#FCFCFA; --grey:#5F6E74; --line:#E7E3DA;
  --ok:#2E7D5B; --warn:#B4703A; --bad:#B3403A;

  /* ② 尺度 token */
  --sp-1:4px; --sp-2:6px; --sp-3:8px; --sp-4:12px; --sp-5:16px; --sp-6:20px;
  --r-xs:4px; --r-sm:8px; --r-md:12px; --r-lg:14px; --r-pill:20px;
  --fs-2xs:10px; --fs-xs:11px; --fs-sm:12px; --fs-base:13px; --fs-md:14px;
  --fs-lg:15px; --fs-xl:17px; --fs-2xl:22px; --fs-3xl:24px;
  --z-toast:60; --z-modal:70;

  /* ③ 語意別名 —— 深色模式只覆寫這一段 */
  --bg:var(--sky);
  --surface:var(--paper);
  --surface-2:var(--cream);
  --surface-3:#FAF8F4;                 /* 表格斑馬紋 */
  --field-bg:#fff;
  --text:#152128;
  --text-dim:var(--grey);
  --text-inv:#fff;
  --heading:var(--ink);
  --border:var(--line);
  --accent:var(--blue);
  --accent-2:var(--gold);
  --side-bg:var(--ink);
  --side-fg:#DCE7EF;
  --side-fg-dim:#9DBFD9;
  --side-hover:rgba(255,255,255,.06);
  --side-active:rgba(255,255,255,.12);
  --th-bg:var(--ink);
  --th-fg:#fff;
  --shadow-sm:0 2px 10px rgba(21,51,61,.06);
  --shadow-lg:0 12px 40px rgba(21,51,61,.16);
  --shadow-modal:0 20px 60px rgba(21,51,61,.3);
  --shadow-toast:0 8px 24px rgba(21,51,61,.24);
  --log-bg:#0f1c21; --log-fg:#cfe3ea;
  --tag-bg:var(--cream); --tag-fg:#6b5637;
  --tag-ok-bg:#E3F1E9; --tag-ok-fg:var(--ok);
  --tag-bad-bg:#F8E7E6; --tag-bad-fg:var(--bad);
  --tag-warn-bg:#FBF0E2; --tag-warn-fg:var(--warn);
  --warn-bg:#FBF3E8; --warn-fg:#6b4a24;
  --err-bg:#F8E7E6; --err-fg:#7a2f2a;
  --load-bg:#F2F6F9;
  --empty-bg:#F7F6F2;
  --modal-back:rgba(21,51,61,.45);
  --preview-bg:#fff;                   /* 信件預覽底色 */
}

/* 深色模式：只重新定義語意別名，下方所有元件規則一行未動。 */
@media(prefers-color-scheme:dark){
  :root{
    --bg:#0E1A1F;
    --surface:#152329;
    --surface-2:#1C2C33;
    --surface-3:#18272D;
    --field-bg:#0F1C22;
    --text:#E4EDF1;
    --text-dim:#9AAAB2;
    --text-inv:#fff;
    --heading:#CFE0E8;
    --border:#2A3C44;
    --accent:#6FA3C0;
    --accent-2:#C6A971;
    --side-bg:#0B1519;
    --side-fg:#C8DAE5;
    --side-fg-dim:#89A6B8;
    --th-bg:#1E323A;
    --th-fg:#DCE7EF;
    --shadow-sm:0 2px 10px rgba(0,0,0,.40);
    --shadow-lg:0 12px 40px rgba(0,0,0,.55);
    --shadow-modal:0 20px 60px rgba(0,0,0,.60);
    --shadow-toast:0 8px 24px rgba(0,0,0,.50);
    --log-bg:#0A1317; --log-fg:#BFD6DE;
    --tag-bg:#233238; --tag-fg:#D9C9A6;
    --tag-ok-bg:#16342A; --tag-ok-fg:#7FD3AA;
    --tag-bad-bg:#3A1E1D; --tag-bad-fg:#F0918B;
    --tag-warn-bg:#382A1B; --tag-warn-fg:#E0AE76;
    --warn-bg:#332618; --warn-fg:#E8C79B;
    --err-bg:#3A1E1D; --err-fg:#F0A9A3;
    --load-bg:#16242B;
    --empty-bg:#17242A;
    --modal-back:rgba(0,0,0,.60);
    /* ⚠ 信件預覽刻意維持淺底：招商信 HTML 是為白底設計的，
       跟著轉深色會讓深色文字配深色底而完全看不見。 */
    --preview-bg:#F5F5F2;
  }
}

*{box-sizing:border-box;margin:0;padding:0}
/* [hidden] 必須勝過下方的 display:flex/grid 規則，否則隱藏層仍會蓋住畫面 */
[hidden]{display:none !important}
body{font-family:'Microsoft JhengHei','PingFang TC','Noto Sans TC',system-ui,sans-serif;
  background:var(--bg);color:var(--text);font-size:var(--fs-md);line-height:1.6}
button{font:inherit;cursor:pointer;border:0;border-radius:var(--r-sm);padding:var(--sp-3) 14px;
  background:var(--accent);color:var(--text-inv);transition:.15s}
button:hover{filter:brightness(1.08)}
button.ghost{background:var(--surface);color:var(--heading);border:1px solid var(--border)}
button.primary{background:var(--ink)}
button.danger{background:var(--bad)}
button:disabled{opacity:.45;cursor:not-allowed}
input,select,textarea{font:inherit;padding:var(--sp-3) 10px;border:1px solid var(--border);
  border-radius:var(--r-sm);background:var(--field-bg);color:var(--text);max-width:100%}
input:focus,select:focus,textarea:focus{outline:2px solid var(--accent);outline-offset:-1px}
a{color:var(--accent)}

/* a11y：鍵盤操作必須看得見焦點。用 :focus-visible 才不會在滑鼠點擊時也畫框。 */
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:var(--r-xs)}
nav a:focus-visible{outline-color:var(--accent-2);outline-offset:-2px}
.skip-link{position:absolute;left:-9999px;top:0;z-index:calc(var(--z-modal) + 1);
  background:var(--surface);color:var(--heading);padding:var(--sp-3) var(--sp-5);
  border-radius:var(--r-sm);box-shadow:var(--shadow-lg)}
.skip-link:focus{left:var(--sp-3);top:var(--sp-3)}

/* 登入 */
.login-wrap{min-height:100vh;display:flex;align-items:center;justify-content:center;padding:24px}
.login-card{background:var(--surface);padding:36px 32px;border-radius:16px;width:100%;max-width:380px;
  box-shadow:var(--shadow-lg);display:flex;flex-direction:column;gap:14px}
.logo{font-size:var(--fs-2xl);font-weight:700;color:var(--heading);letter-spacing:2px}
.logo-sub{font-size:var(--fs-sm);color:var(--accent-2);letter-spacing:4px;margin-bottom:var(--sp-3)}
.login-card label{display:flex;flex-direction:column;gap:var(--sp-2);font-size:var(--fs-base);color:var(--text-dim)}
.err{color:var(--bad);font-size:var(--fs-base);min-height:18px}
.hint{color:var(--text-dim);font-size:var(--fs-sm);line-height:1.7}

/* 版面 */
#app{display:flex;min-height:100vh}
aside{width:210px;background:var(--side-bg);color:var(--side-fg);display:flex;flex-direction:column;
  padding:var(--sp-6) 0;flex-shrink:0}
.brandmark{padding:0 var(--sp-6) var(--sp-6);font-size:var(--fs-xl);font-weight:700;
  color:var(--text-inv);letter-spacing:1px}
.brandmark span{display:block;font-size:var(--fs-2xs);letter-spacing:5px;color:var(--accent-2);margin-top:var(--sp-1)}
nav{display:flex;flex-direction:column;flex:1}
nav a{padding:11px var(--sp-6);cursor:pointer;color:var(--side-fg-dim);text-decoration:none;
  border-left:3px solid transparent}
nav a:hover{background:var(--side-hover);color:var(--text-inv)}
nav a.on,nav a[aria-current="page"]{background:var(--side-active);color:var(--text-inv);
  border-left-color:var(--accent-2)}
/* D3-1 導覽分組標題：純呈現層，data-view 值完全未動 */
.nav-group{padding:14px var(--sp-6) var(--sp-1);font-size:var(--fs-2xs);letter-spacing:2px;
  color:var(--side-fg-dim);opacity:.75;text-transform:none}
.who{padding:var(--sp-5) var(--sp-6) 0;border-top:1px solid var(--side-active);
  font-size:var(--fs-sm);color:var(--side-fg-dim)}
.who button{margin-top:var(--sp-3);width:100%;background:var(--side-active)}
main{flex:1;padding:22px 26px 60px;overflow-x:auto}
header{display:flex;justify-content:space-between;align-items:flex-start;gap:var(--sp-5);margin-bottom:18px}
h1{font-size:var(--fs-2xl);color:var(--heading)}
.sub{color:var(--text-dim);font-size:var(--fs-base)}
.active-brand{background:var(--surface);border:1px solid var(--border);border-radius:10px;
  padding:var(--sp-3) 14px;font-size:var(--fs-base);white-space:nowrap}
.active-brand b{color:var(--heading)}

/* 側欄開合鈕：只在窄螢幕出現（見檔尾 D4-3） */
.nav-toggle{display:none;background:var(--surface);color:var(--heading);
  border:1px solid var(--border);border-radius:var(--r-sm)}

.panel{background:var(--surface);border-radius:var(--r-lg);padding:18px var(--sp-6);
  margin-bottom:var(--sp-5);box-shadow:var(--shadow-sm)}
.panel h3{font-size:var(--fs-lg);color:var(--heading);margin-bottom:var(--sp-4)}
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-5)}
@media(max-width:1000px){.grid2{grid-template-columns:1fr}}
.toolbar{display:flex;gap:10px;flex-wrap:wrap;margin-bottom:14px;align-items:center}
.toolbar input{min-width:190px}
.muted{color:var(--text-dim)}
.warn{background:var(--warn-bg);border-left:4px solid var(--warn);padding:10px 14px;
  border-radius:var(--r-sm);margin-bottom:14px;font-size:var(--fs-base);color:var(--warn-fg)}

/* 卡片 */
.cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:var(--sp-4);
  margin-bottom:var(--sp-5)}
.card{background:var(--surface);border-radius:var(--r-md);padding:14px var(--sp-5);box-shadow:var(--shadow-sm)}
.card .v{font-size:var(--fs-3xl);font-weight:700;color:var(--heading);line-height:1.2}
.card .l{font-size:var(--fs-sm);color:var(--text-dim);margin-top:var(--sp-1)}

/* 表格 */
table{width:100%;border-collapse:collapse;font-size:var(--fs-base)}
th{background:var(--th-bg);color:var(--th-fg);text-align:left;padding:var(--sp-3) 10px;
  font-weight:600;white-space:nowrap}
td{padding:7px 10px;border-bottom:1px solid var(--border);vertical-align:top}
tr:nth-child(even) td{background:var(--surface-3)}
.tag{display:inline-block;padding:1px var(--sp-3);border-radius:var(--r-pill);font-size:var(--fs-xs);
  background:var(--tag-bg);color:var(--tag-fg)}
.tag.ok{background:var(--tag-ok-bg);color:var(--tag-ok-fg)}
.tag.bad{background:var(--tag-bad-bg);color:var(--tag-bad-fg)}
.tag.warn{background:var(--tag-warn-bg);color:var(--tag-warn-fg)}

/* 品牌 */
.brand-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:var(--sp-4);
  margin-bottom:var(--sp-5)}
.brand-card{background:var(--surface);border-radius:var(--r-md);padding:var(--sp-5);cursor:pointer;
  border:2px solid transparent;box-shadow:var(--shadow-sm)}
.brand-card:hover{border-color:var(--accent)}
.brand-card.active{border-color:var(--accent-2)}
.brand-card .n{font-weight:700;color:var(--heading)}
.brand-card .s{font-size:var(--fs-sm);color:var(--text-dim);margin-top:var(--sp-1)}
.editor-head{display:flex;justify-content:space-between;align-items:center;gap:var(--sp-4);
  flex-wrap:wrap;margin-bottom:14px}
.editor-head>div{display:flex;gap:var(--sp-3)}
.sec{border:1px solid var(--border);border-radius:10px;margin-bottom:var(--sp-4);overflow:hidden}
.sec>summary{padding:10px 14px;background:var(--surface-2);cursor:pointer;font-weight:600;color:var(--heading)}
.sec .body{padding:var(--sp-4) 14px;display:grid;grid-template-columns:1fr;gap:10px}
.fld{display:grid;grid-template-columns:210px 1fr;gap:var(--sp-4);align-items:start}
@media(max-width:820px){.fld{grid-template-columns:1fr}}
.fld .k{font-size:var(--fs-base);color:var(--heading);padding-top:var(--sp-3)}
.fld .k .req{color:var(--bad);margin-left:var(--sp-1)}
.fld .k .d{display:block;font-size:var(--fs-xs);color:var(--text-dim);font-weight:400}
.fld input,.fld textarea{width:100%}
.fld textarea{min-height:64px;resize:vertical;font-family:inherit}

/* 日誌 */
pre#job-log{background:var(--log-bg);color:var(--log-fg);padding:14px;border-radius:10px;
  max-height:440px;overflow:auto;font-size:var(--fs-sm);line-height:1.55;
  white-space:pre-wrap;word-break:break-all}
.joblist-item{padding:var(--sp-3) 10px;border-bottom:1px solid var(--border);cursor:pointer;
  display:flex;justify-content:space-between;gap:var(--sp-3);font-size:var(--fs-base)}
.joblist-item:hover{background:var(--surface-2)}
.joblist-item.on{background:var(--bg)}

/* 寄信預覽 */
.preview-frame{width:100%;height:520px;border:1px solid var(--border);border-radius:10px;
  background:var(--preview-bg)}
.confirm-row{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-top:14px;
  padding-top:14px;border-top:1px solid var(--border)}
.rcpt{max-height:220px;overflow:auto;border:1px solid var(--border);border-radius:var(--r-sm)}
.bar{height:var(--sp-3);background:var(--bg);border-radius:var(--r-sm);overflow:hidden;margin-top:var(--sp-1)}
.bar>i{display:block;height:100%;background:var(--accent)}

/* ── 四工具聯邦整合：服務燈號與外連 ────────────────────────────────────── */
.svc-row{display:flex;flex-direction:column;gap:var(--sp-2);font-size:var(--fs-base)}
.svc-row b{margin-right:var(--sp-3)}
.svc-row .muted{margin-left:2px}
/* 每個服務一列（原本靠 <br>，改走元件層後改用 .svc-item 容器）*/
.svc-item{display:flex;align-items:center;flex-wrap:wrap;gap:2px}
.dot{display:inline-block;width:9px;height:9px;border-radius:50%;margin-right:var(--sp-3);
  vertical-align:middle;box-shadow:0 0 0 3px rgba(0,0,0,.04)}
.dot.up{background:var(--ok)}
.dot.down{background:var(--bad)}
a.ext{margin-left:10px;font-size:var(--fs-sm);text-decoration:none;border-bottom:1px dotted var(--accent)}
a.ext:hover{border-bottom-style:solid}
pre{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-sm);padding:var(--sp-4);
  overflow-x:auto;font-size:var(--fs-sm);line-height:1.5;max-height:420px}
code{background:var(--surface-2);padding:1px 5px;border-radius:var(--r-xs);font-size:var(--fs-sm)}
h4{font-size:var(--fs-base);color:var(--heading);margin:var(--sp-4) 0 var(--sp-2)}

/* ── 元件層（D2）：四態、表格容器、panel 骨架、toast、modal ──────────────── */

/* 四態一致化。四種狀態共用同一個外框，只換左側色條與圖示 ——
   使用者一眼就能分辨「載入中／沒資料／遠端壞了／讀取失敗」。 */
.state{display:flex;gap:10px;align-items:flex-start;padding:var(--sp-4) 14px;border-radius:var(--r-sm);
  font-size:var(--fs-base);background:var(--surface-2);color:var(--tag-fg);
  border-left:4px solid var(--border)}
.state-i{line-height:1.5}
.state-m{font-weight:600}
.state-x{margin-top:var(--sp-1);font-size:var(--fs-sm);opacity:.85;word-break:break-word}
.state-loading{background:var(--load-bg);color:var(--text-dim);border-left-color:var(--accent)}
/* idle：等使用者按按鈕才會去取值。刻意比 loading 更淡、色條為虛線，
   避免和「正在載入」混為一談（那會讓人盯著不會變的畫面等）。 */
.state-idle{background:var(--surface-2);color:var(--text-dim);
  border-left-style:dashed;border-left-color:var(--border)}
.state-empty{background:var(--empty-bg);color:var(--text-dim);border-left-color:var(--border)}
.state-degraded{background:var(--warn-bg);color:var(--warn-fg);border-left-color:var(--warn)}
.state-error{background:var(--err-bg);color:var(--err-fg);border-left-color:var(--bad)}

/* ── 今日待辦（D3-2）────────────────────────────────────────────────────
   三種視覺狀態刻意不同：有待辦（強調）／零（安靜）／讀取失敗（虛線＋「—」）。
   「0」和「讀不到」長得一樣是最容易誤導操作者的設計，這裡分開。 */
.todo-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(168px,1fr));
  gap:var(--sp-3);margin-bottom:var(--sp-3)}
.todo{background:var(--surface-2);border:1px solid var(--border);border-radius:var(--r-md);
  padding:var(--sp-4);cursor:pointer;transition:box-shadow .15s,transform .15s,border-color .15s}
.todo:hover{box-shadow:var(--shadow-sm);transform:translateY(-1px);border-color:var(--accent)}
.todo-v{font-size:var(--fs-2xl);font-weight:700;line-height:1.2;color:var(--heading)}
.todo-l{font-size:var(--fs-sm);font-weight:600;margin-top:2px}
.todo-d{font-size:var(--fs-2xs);color:var(--text-dim);margin-top:var(--sp-1);line-height:1.5}
.todo-due{border-left:4px solid var(--accent-2);background:var(--warn-bg)}
.todo-due .todo-v{color:var(--accent-2)}
.todo-zero{opacity:.72}
.todo-dead{border-style:dashed}
.todo-dead .todo-v{color:var(--text-dim)}

/* 漏斗列可導覽（D3-3）：整列可點／可鍵盤啟用 */
.funnel-row{cursor:pointer}
.funnel-row:hover td{background:var(--side-hover)}
.funnel-row.is-zero{opacity:.6}

/* 螢幕閱讀器專用：視覺隱藏但保留在無障礙樹中（不能用 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}

/* 表格容器：讓寬表格自己橫向捲動，而不是把整個頁面撐寬 */
.tbl-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch}
.tbl-cap{margin-bottom:var(--sp-3);font-size:var(--fs-sm)}

/* panel 骨架（D3-4 全面套用）*/
.panel-h{display:flex;justify-content:space-between;align-items:center;gap:var(--sp-4);
  flex-wrap:wrap;margin-bottom:var(--sp-4)}
.panel-h h3{margin-bottom:0}
.panel-a{display:flex;gap:var(--sp-3);flex-wrap:wrap}

/* toast：取代 alert()。經 aria-live 播報，不阻斷操作 */
#toasts{position:fixed;right:var(--sp-5);bottom:var(--sp-5);display:flex;flex-direction:column;
  gap:var(--sp-3);z-index:var(--z-toast);max-width:min(380px,calc(100vw - 32px))}
.toast{padding:11px 14px;border-radius:10px;font-size:var(--fs-base);color:var(--text-inv);
  background:var(--ink);box-shadow:var(--shadow-toast);animation:toast-in .18s ease-out;
  word-break:break-word}
.toast-ok{background:var(--ok)}
.toast-warn{background:var(--warn)}
.toast-bad{background:var(--bad)}
.toast.out{opacity:0;transform:translateY(6px);transition:.24s}
@keyframes toast-in{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}

/* modal：取代 confirm()。Esc 與點背景皆可取消 */
.modal-back{position:fixed;inset:0;background:var(--modal-back);display:flex;
  align-items:center;justify-content:center;padding:var(--sp-6);z-index:var(--z-modal)}
.modal{background:var(--surface);border-radius:var(--r-lg);padding:var(--sp-6) 22px;width:100%;
  max-width:440px;box-shadow:var(--shadow-modal)}
.modal h3{font-size:16px;color:var(--heading);margin-bottom:10px}
.modal-b{font-size:var(--fs-base);color:var(--text);display:flex;flex-direction:column;gap:var(--sp-2)}
.modal-a{display:flex;justify-content:flex-end;gap:var(--sp-3);margin-top:18px}

/* ── D4-3 窄螢幕（<820px）────────────────────────────────────────────────
   原本 210px 側欄固定佔位、main 用 overflow-x:auto，等於「只能桌機」。
   這裡把側欄改成抽屜（由 body.nav-open 控制），表格改逐列卡片。 */
@media(max-width:820px){
  #app{flex-direction:column}
  .nav-toggle{display:inline-flex;align-items:center;gap:var(--sp-2)}
  aside{position:fixed;inset:0 auto 0 0;width:250px;z-index:var(--z-modal);
    transform:translateX(-100%);transition:transform .2s ease-out;
    box-shadow:var(--shadow-modal);overflow-y:auto}
  body.nav-open aside{transform:none}
  /* 抽屜開啟時的遮罩：點它就關 */
  body.nav-open::after{content:'';position:fixed;inset:0;background:var(--modal-back);
    z-index:calc(var(--z-modal) - 1)}
  main{padding:var(--sp-5) var(--sp-5) 48px}
  header{flex-direction:column;align-items:stretch;gap:var(--sp-3)}
  .active-brand{white-space:normal}

  /* 表格 → 逐列卡片。依賴元件層 table() 為每個 td 寫入的 data-label。 */
  .tbl-wrap table,.tbl-wrap tbody{display:block}
  .tbl-wrap tr{display:block;background:var(--surface);border:1px solid var(--border);
    border-radius:var(--r-md);padding:10px var(--sp-4);margin-bottom:10px}
  .tbl-wrap tr:first-child{display:none}          /* 表頭列改由每格的 data-label 呈現 */
  .tbl-wrap td{display:flex;justify-content:space-between;gap:var(--sp-4);border-bottom:0;
    padding:3px 0;text-align:left !important}
  .tbl-wrap tr:nth-child(even) td{background:transparent}
  .tbl-wrap td::before{content:attr(data-label);flex:0 0 40%;color:var(--text-dim);
    font-size:var(--fs-sm);font-weight:600}
  .tbl-wrap td[data-label=""]::before{content:''}
}

/* 使用者要求減少動態效果時，關掉所有轉場與動畫 */
@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms !important;animation-iteration-count:1 !important;
    transition-duration:.001ms !important}
}
