/* 客戶後台 —— 視覺跟公司網（company-site/public/app.css）。
 *
 * ⚠️ 顏色一個都唔係新諗嘅：藍 #2472BC、炭黑、灰階、深色嗰套，
 *    全部由公司網抄過嚟。上次盲試咗 8 張全部唔合格，所以呢度唔創作，
 *    淨係把一套已經批准咗嘅語言用喺一個 app 介面度。
 *
 *    公司網冇而 app 一定要有嘅（ok／bad／warn、surface、shadow）
 *    先至係新加，而且盡量由現有色推出嚟。
 *
 * ⚠️ radius 由公司網嘅 18px 收窄到 12px。18 係 marketing 卡片嘅圓角，
 *    落喺一個密密麻麻嘅資料介面度會好似一堆藥丸。
 */

:root{
  --bg:#f7f8fa;
  --surface:#ffffff;
  --card:#ffffff;
  --ink:#222222;
  --muted:#5b6169;
  --faint:#8b929b;
  --line:#e3e6ea;
  --line-2:#eef0f3;
  --accent:#2472BC;
  --accent-ink:#ffffff;
  --accent-soft:rgba(36,114,188,.10);
  --ok:#1f8f4e;
  --ok-soft:rgba(31,143,78,.12);
  --warn:#b8720a;
  --warn-soft:rgba(184,114,10,.12);
  --bad:#c0392b;
  --bad-soft:rgba(192,57,43,.12);
  --shadow:0 1px 2px rgba(34,38,43,.05);
  --radius:12px;
  --radius-s:8px;
  --side:236px;
  /* ⚠️ logo 要分深淺兩個檔 —— 個 wordmark 啲字係炭黑色，落喺深色底
     就會消失。唔用 CSS filter 反色：反埋個藍色標誌一齊變，變咗第二隻色。
     ⚠️ 條 url() 係**相對 app.css 本身**，唔係相對版面 —— 所以
        production（/app.css）同 tools/preview.html（/public/app.css）
        兩邊都指得返啱嗰個檔，唔使寫死一條絕對路徑。 */
  --logo:url(logo.png);
}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    --bg:#15181c; --surface:#1d2127; --card:#1d2127;
    --ink:#f2f4f7; --muted:#aab2bd; --faint:#7c8591;
    --line:#2b3038; --line-2:#252a31;
    --accent:#4a8fd6; --accent-soft:rgba(74,143,214,.16);
    --ok:#4cc27a; --ok-soft:rgba(76,194,122,.14);
    --warn:#e0a34e; --warn-soft:rgba(224,163,78,.14);
    --bad:#f0655a; --bad-soft:rgba(240,101,90,.14);
    --shadow:0 1px 2px rgba(0,0,0,.35);
    --logo:url(logo-dark.png);
  }
}
:root[data-theme="dark"]{
  --bg:#15181c; --surface:#1d2127; --card:#1d2127;
  --ink:#f2f4f7; --muted:#aab2bd; --faint:#7c8591;
  --line:#2b3038; --line-2:#252a31;
  --accent:#4a8fd6; --accent-soft:rgba(74,143,214,.16);
  --ok:#4cc27a; --ok-soft:rgba(76,194,122,.14);
  --warn:#e0a34e; --warn-soft:rgba(224,163,78,.14);
  --bad:#f0655a; --bad-soft:rgba(240,101,90,.14);
  --shadow:0 1px 2px rgba(0,0,0,.35);
  --logo:url(logo-dark.png);
}

*{box-sizing:border-box;margin:0;padding:0}
html{height:100%}
body{
  min-height:100%;background:var(--bg);color:var(--ink);
  font-family:"Noto Sans TC",-apple-system,"PingFang TC","Microsoft JhengHei",sans-serif;
  font-size:14px;line-height:1.65;
  -webkit-font-smoothing:antialiased;
}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
[hidden]{display:none!important}
.num{font-variant-numeric:tabular-nums}

/* ── 骨架：左邊欄 ＋ 主區 ────────────────────────── */
.app{display:grid;grid-template-columns:var(--side) 1fr;min-height:100vh}
.side{
  background:var(--surface);border-right:1px solid var(--line);
  padding:20px 14px;display:flex;flex-direction:column;gap:22px;
  position:sticky;top:0;height:100vh;
  /* ⚠️ 一定要 overflow-y:auto。sticky ＋ 寫死 100vh，入面長過個 mon 嘅話
     多出嚟嗰截永遠捲唔到 —— 2026-09-10 量到 720px 高嘅 mon 本身已經
     長 35px（登出掣去咗 755px），加埋 Rare 支援提示框去到 895px。
     病徵係「搵唔到登出」，唔會有人聯想到係 CSS。 */
  overflow-y:auto;
}
.brand{display:flex;flex-direction:column;align-items:flex-start;gap:7px;padding:2px 8px}
/* ⚠️ 用 background 唔用 <img>：深淺兩版靠 --logo 換，`<img src>` 換唔到。
   高度靠 aspect-ratio 由闊度計返，唔好寫死 —— 寫死就等於再手動度多次
   個圖嘅比例，換張新 logo 就會扁咗或者拉長。 */
.brand-logo{
  width:150px;aspect-ratio:480/182;
  background:var(--logo) left center/contain no-repeat;
}
.login .brand-logo{width:186px}
.brand-name{font-weight:700;font-size:14px;line-height:1.2}
.brand-sub{font-size:11.5px;color:var(--faint);line-height:1.2;margin-top:2px}

.nav{display:flex;flex-direction:column;gap:2px}
.nav a{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:9px 10px;border-radius:var(--radius-s);color:var(--muted);font-weight:500;
  transition:background .15s,color .15s;
}
.nav a:hover{background:var(--line-2);color:var(--ink)}
.nav a.on{background:var(--accent-soft);color:var(--accent);font-weight:600}
.nav .cnt{
  font-size:11.5px;font-weight:700;min-width:20px;height:20px;padding:0 6px;
  border-radius:10px;display:grid;place-items:center;
  background:var(--bad);color:#fff;
}
.nav a.on .cnt{background:var(--accent);color:var(--accent-ink)}
/* 「等待落單」嗰粒 —— 同「答唔到」嗰粒**一定要唔同色**。
   ⚠️ 兩粒紅色排埋一齊，客戶淨係見到「兩個數」，唔會知一個係
      「有人問咗嘢冇人覆」、一個係「有生意等緊接」。
   ⚠️ 用 `--ok`（綠）唔用另一隻紅：呢粒唔係壞事，係生意。 */
.nav .cnt.book{background:var(--ok);color:#fff}
.nav a.on .cnt.book{background:var(--ok);color:#fff}
/* ── 側邊欄額度 ─────────────────────────────────────
   ⚠️ `margin-top:auto` 由呢舊嘢攞去，跟住要即刻幫 .side-foot 取消返 ——
   兩個都 auto 嘅話，flex 會把剩餘空間**平均分**俾兩個，於是額度飄咗喺
   半空、下面吊住個戶口。冇額度（無上限／攞唔到）嗰陣呢舊唔會 render，
   .side-foot 就攞返自己嗰個 auto，位置同以前一樣。 */
.quota{
  margin-top:auto;display:block;padding:10px;border-radius:var(--radius-s);
  background:var(--line-2);transition:background .15s;
}
.quota:hover{background:var(--line)}
.quota-h{display:flex;align-items:baseline;justify-content:space-between;gap:8px;font-size:12.5px;color:var(--muted)}
.quota-h b{color:var(--ink);font-weight:600}
.quota-h span{font-size:15px;font-weight:700;color:var(--ok)}
.quota.warn .quota-h span{color:var(--warn)}
.quota.bad .quota-h span{color:var(--bad)}
.quota-bar{height:5px;border-radius:3px;background:var(--line);overflow:hidden;margin:7px 0 6px}
.quota-bar i{display:block;height:100%;background:var(--ok);border-radius:3px;transition:width .4s}
.quota.warn .quota-bar i{background:var(--warn)}
.quota.bad .quota-bar i{background:var(--bad)}
.quota-f{font-size:11.5px;color:var(--faint);line-height:1.5}
.quota-f em{display:block;font-style:normal;color:var(--accent);font-weight:600;margin-top:2px}
.quota + .side-foot{margin-top:0}

.side-foot{margin-top:auto;padding:8px 10px;border-top:1px solid var(--line-2);font-size:12.5px;color:var(--muted)}
/* 語言掣。細細粒擺喺戶口上面 —— 唔入 nav，因為佢唔係一版嘢。 */
.lang{display:flex;gap:4px;margin-bottom:8px}
.lang button{
  padding:3px 9px;border-radius:99px;border:1px solid var(--line);
  font-size:11.5px;color:var(--faint);transition:all .15s;
}
.lang button:hover{color:var(--ink);border-color:var(--muted)}
.lang button.on{background:var(--accent-soft);border-color:var(--accent);color:var(--accent);font-weight:600}
.side-foot b{display:block;color:var(--ink);font-weight:600}
.side-foot button{color:var(--faint);margin-top:6px;font-size:12px}
.side-foot button:hover{color:var(--accent)}

.main{min-width:0;padding:28px 32px 48px}
.top{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;margin-bottom:22px}
h1{font-size:22px;font-weight:700;letter-spacing:-.01em;line-height:1.3}
.top p{color:var(--muted);margin-top:3px}

/* ── 狀態燈：條線 ＋ 個腦 ───────────────────────── */
.lights{display:flex;gap:8px;flex-wrap:wrap}
.light{
  display:inline-flex;align-items:center;gap:7px;padding:6px 11px;
  border:1px solid var(--line);border-radius:999px;background:var(--card);
  font-size:12.5px;font-weight:600;color:var(--muted);box-shadow:var(--shadow);
}
.light i{width:8px;height:8px;border-radius:50%;background:var(--faint)}
.light.ok i{background:var(--ok);box-shadow:0 0 0 3px var(--ok-soft)}
.light.bad i{background:var(--bad);box-shadow:0 0 0 3px var(--bad-soft)}
.light.warn i{background:var(--warn);box-shadow:0 0 0 3px var(--warn-soft)}
.light small{font-weight:500;color:var(--faint)}

/* ── 卡 ─────────────────────────────────────────── */
.card{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);box-shadow:var(--shadow)}
/* ⚠️ 卡嘅距離一直靠 `.stats`／`.grid-2` 個 gap 撐 —— 一張跟一張、
   冇 grid 包嗰啲（團隊管理、設定、數據分析下半版）就會貼死。
   限死 `.main >`：grid 入面嗰啲卡係 grid 嘅仔，唔會中招撞歪行。 */
.main > .card + .card{margin-top:18px}
.card-h{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:14px 18px;border-bottom:1px solid var(--line-2);
}
.card-h h2{font-size:14.5px;font-weight:700}
.card-h .more{font-size:12.5px;color:var(--accent);font-weight:600}
.card-b{padding:6px 0}

/* 數字格 */
.stats{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin-bottom:18px}
.stat{padding:16px 18px}
.stat .k{font-size:12.5px;color:var(--muted);font-weight:500}
.stat .v{font-size:30px;font-weight:700;letter-spacing:-.02em;line-height:1.15;margin-top:4px}
.stat .d{font-size:12px;color:var(--faint);margin-top:4px}
.stat.hot .v{color:var(--bad)}
.stat.good .v{color:var(--ok)}

.grid-2{display:grid;grid-template-columns:1.4fr 1fr;gap:18px}

/* ── 清單行 ─────────────────────────────────────── */
.row{
  display:grid;grid-template-columns:1fr auto;gap:4px 16px;align-items:center;
  padding:12px 18px;border-bottom:1px solid var(--line-2);
  transition:background .12s;cursor:pointer;
}
.row:last-child{border-bottom:0}
.row:hover{background:var(--line-2)}
.row.on{background:var(--accent-soft)}
/* ⚠️ 每格都要寫明 column。有定 row 冇定 column 嘅元素（.when）會喺
   auto-placement 度**先擺**，霸咗 (1,1)，跟住 .t 就被推去第二欄 ——
   出嚟係時間喺左、標題喺右。第一次 render 就係咁樣。 */
.row .t{grid-column:1;grid-row:1;font-weight:600;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.row .s{grid-column:1;grid-row:2;font-size:12.5px;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.row .when{grid-column:2;grid-row:1/3;font-size:12px;color:var(--faint);text-align:right;white-space:nowrap}
.row .when b{display:block;color:var(--warn);font-weight:700}
/* 分類標籤。⚠️ 照上面嗰段：一定要寫明 grid-column，唔寫就會被
   auto-placement 擺去第二欄，同 .when 迫埋一齊。 */
.row .tg{grid-column:1;grid-row:3;display:flex;flex-wrap:wrap;gap:5px;margin-top:2px}

/* 標籤 */
.tag{
  display:inline-block;font-size:11.5px;font-weight:700;padding:1px 8px;border-radius:6px;
  vertical-align:middle;margin-right:6px;
}
.tag.auto{background:var(--ok-soft);color:var(--ok)}
.tag.draft{background:var(--bad-soft);color:var(--bad)}
.tag.sent{background:var(--accent-soft);color:var(--accent)}
.tag.dismissed{background:var(--line-2);color:var(--faint)}

.empty{padding:36px 18px;text-align:center;color:var(--faint)}
.empty b{display:block;color:var(--muted);font-weight:600;margin-bottom:2px}

/* ── 對話：左清單、右詳情 ──────────────────────── */
.chat-wrap{display:grid;grid-template-columns:340px 1fr;gap:18px;min-height:560px}
.chat-list{overflow:auto;max-height:calc(100vh - 140px)}
.chat-head{padding:14px 20px;border-bottom:1px solid var(--line-2);display:flex;align-items:center;justify-content:space-between}
.chat-head b{font-size:15px}
.chat-head span{font-size:12.5px;color:var(--muted);margin-left:8px}
.thread{padding:18px 20px;display:flex;flex-direction:column;gap:10px;max-height:calc(100vh - 220px);overflow:auto}
.msg{max-width:74%;padding:9px 13px;border-radius:14px;line-height:1.55;position:relative;white-space:pre-wrap;word-break:break-word}
.msg.in{align-self:flex-start;background:var(--line-2);border-bottom-left-radius:4px}
.msg.out{align-self:flex-end;background:var(--accent);color:var(--accent-ink);border-bottom-right-radius:4px}
.msg.out.human{background:var(--ok)}
.msg .meta{display:block;font-size:11px;opacity:.7;margin-top:4px}
.msg .meta.human{font-weight:600}
.pending{
  align-self:stretch;margin:2px 0;padding:10px 13px;border-radius:10px;
  background:var(--bad-soft);border:1px dashed var(--bad);color:var(--bad);font-size:12.5px;
}
.pending b{font-weight:700}
.pending span{color:var(--muted);display:block;margin-top:2px}

/* ── 等緊人手 ───────────────────────────────────── */
.wait{padding:14px 18px;border-bottom:1px solid var(--line-2);display:grid;grid-template-columns:1fr auto;gap:6px 16px}
.wait:last-child{border-bottom:0}
.wait .q{grid-column:1;grid-row:1;font-weight:600;font-size:14.5px}
.wait .why{grid-column:1;grid-row:2;font-size:12.5px;color:var(--muted)}
.wait .why i{font-style:normal;color:var(--bad);font-weight:600}
.wait .who{grid-column:1;grid-row:3;font-size:12px;color:var(--faint)}
.wait .age{grid-column:2;grid-row:1/4;text-align:right;font-size:12px;color:var(--faint);white-space:nowrap}
.wait .age b{display:block;font-size:20px;font-weight:700;color:var(--bad);letter-spacing:-.01em}
.wait .age b.calm{color:var(--warn)}
.wait .age b.fresh{color:var(--muted)}
/* ⚠️ 成行本來係一個 <a>。加咗掣就唔可以（<button> 唔准放喺 <a> 入面），
   所以改成 <div>，條問題自己做返條 link —— 即係話**最平嗰個 plan
   照樣撳得入去睇對話**，跟 plan 走嘅淨係「立即對話」粒掣。
   （點解要咁分，見 `app.js` 個 `waitRow()`。） */
.wait .q{color:inherit;text-decoration:none}
.wait .q:hover{text-decoration:underline}
/* 掣擺喺第 4 行，唔可以塞落 `.age` 嗰一格（右上角）—— 嗰格入面係
   「等咗幾耐」，成版最緊要嗰個數。擺埋一齊就會有人撳落個數度。 */
.wait-act{grid-column:1/3;grid-row:4;display:flex;align-items:center;gap:8px;margin-top:6px}
.wait-act .btn.sm{padding:5px 12px;font-size:12.5px}
.wait-act button{font-size:12.5px;font-weight:600;color:var(--muted);padding:5px 10px;border-radius:6px}
.wait-act button:hover{background:var(--line-2);color:var(--ink)}
.wait-act button[disabled]{opacity:.5}
.wait-act .err{margin:0}

/* ── 登入 ───────────────────────────────────────── */
.login{min-height:100vh;display:grid;place-items:center;padding:24px}
.login .card{width:100%;max-width:380px;padding:30px 30px 26px}
/* 個 wordmark 本身底下已經有一行細字（RARE AI MARKETING），
   所以下面嗰句副標題要行開啲，唔係兩行細灰字會黐埋一齊。 */
.login .brand{padding:0;margin-bottom:22px;gap:11px}
.login h1{font-size:19px;margin-bottom:4px}
.login p{color:var(--muted);margin-bottom:20px}
.field{margin-bottom:14px}
.field label{display:block;font-size:12.5px;font-weight:600;color:var(--muted);margin-bottom:5px}
/* ⚠️ 唔可以淨係 `.field input` —— 設定版啲輸入框唔喺 `.field` 入面，
   收窄咗個 selector 就會跌返做瀏覽器預設（2px inset、白底）。
   淺色模式勉強睇得出，**深色模式就係一格白**，而冇人會為咗一個
   輸入框去開深色模式試。所以呢度一次過寫齊。 */
.field input,.field select,.set input,.set select,.set textarea,.ind select{
  width:100%;padding:10px 12px;border:1px solid var(--line);border-radius:var(--radius-s);
  background:var(--bg);color:var(--ink);font:inherit;outline:0;transition:border-color .15s,box-shadow .15s;
}
.field input:focus,.field select:focus,.set input:focus,.set select:focus,.set textarea:focus,.ind select:focus,.kv-r select:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  padding:10px 16px;border-radius:var(--radius-s);font-weight:600;
  background:var(--accent);color:var(--accent-ink);width:100%;transition:filter .15s;
}
.btn:hover{filter:brightness(1.06)}
.btn[disabled]{opacity:.6;cursor:default}
.err{color:var(--bad);font-size:12.5px;margin-top:10px;min-height:1.4em}

/* ── 資料庫（期 3）──────────────────────────────── */
/* ⚠️ overflow-y 一定要 hidden：入面啲 a 用 margin-bottom:-1px 疊住條底線，
   淨係 overflow-x:auto 嘅話呢 1px 會令佢生一條直向 scrollbar 出嚟。 */
.tabs{display:flex;gap:2px;border-bottom:1px solid var(--line);margin-bottom:18px;overflow-x:auto;overflow-y:hidden;scrollbar-width:none}
.tabs a{
  padding:9px 14px;color:var(--muted);font-weight:500;white-space:nowrap;
  border-bottom:2px solid transparent;margin-bottom:-1px;transition:color .15s,border-color .15s;
}
.tabs a:hover{color:var(--ink)}
.tabs a.on{color:var(--accent);border-bottom-color:var(--accent);font-weight:600}
.tabs a small{margin-left:5px;font-size:11px;color:var(--faint);font-weight:600}

.kb-hint{
  padding:10px 14px;border-radius:var(--radius-s);background:var(--accent-soft);
  color:var(--ink);font-size:13px;margin-bottom:14px;line-height:1.6;
}
.kb-hint.bad{background:var(--bad-soft)}
.kb-hint.ok{background:var(--ok-soft);color:var(--ok);font-weight:600}
.kb-hint code{background:var(--card);border:1px solid var(--line);border-radius:4px;padding:0 6px;font-weight:700;margin-right:2px}
.kb-hint small{color:var(--muted);margin-right:8px}
.faint{color:var(--faint)}

.tbl{width:100%;border-collapse:collapse;font-size:13.5px}
.tbl th{text-align:left;font-size:12px;color:var(--muted);font-weight:600;padding:11px 16px;border-bottom:1px solid var(--line-2);white-space:nowrap}
.tbl td{padding:12px 16px;border-bottom:1px solid var(--line-2);vertical-align:top}
.tbl tr:last-child td{border-bottom:0}
.tbl tr.off td{color:var(--faint)}
.tbl td.act,.faq .act{text-align:right;white-space:nowrap}
.tbl button,.faq .act button,.hist button{
  font-size:12.5px;font-weight:600;color:var(--accent);padding:4px 9px;border-radius:6px;
}
.tbl button:hover,.faq .act button:hover,.hist button:hover{background:var(--accent-soft)}
button.ghost{color:var(--muted)}
.card-foot{padding:12px 18px;border-top:1px solid var(--line-2);display:flex;align-items:center}
.btn.sm{width:auto;padding:7px 14px;font-size:13px}
/* ⚠️ 上面個 `button.ghost` 綁死咗 button 標籤 —— <a class="btn ghost">
   食唔到，兩粒掣會一樣咁實色。呢條係俾 <a> 用嘅。 */
.btn.ghost{background:var(--line-2);color:var(--ink)}
.btn.ghost:hover{background:var(--line)}

.frm{margin-top:14px}
.frm-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px 16px;padding:16px 18px 4px}
.frm-grid.one{grid-template-columns:1fr}

/* 建議回答（FAQ 預填表）。⚠️ 全部新 class 用 `sug-` 開頭 ——
   app.css 入面好多兩三個字嘅短名，撞咗個 DOM 一樣啱但畫面會爛。 */
.sug{margin:12px 18px 0;border:1px solid var(--line);border-radius:var(--radius-s);overflow:hidden}
.sug-h{padding:10px 14px 8px;font-size:13px;font-weight:600;background:var(--line-2)}
.sug-h small{display:block;font-weight:400;color:var(--muted);font-size:12px;margin-top:3px;line-height:1.55}
/* ⚠️ `pre-wrap` 唔可以少 —— 嗰啲原文本身係 WhatsApp 訊息，分行同空行
   就係佢嘅排版。擠成一嚿，客戶會以為個客服真係咁樣覆人。
   ⚠️ 一定要封高度：2026-09-09 量到最抵用嗰條建議係成張海報連課程全文，
   唔封就把下面「官方答法」個輸入框推到成版之外。 */
.sug-b{padding:12px 14px;font-size:13px;line-height:1.65;white-space:pre-wrap;
  max-height:210px;overflow-y:auto;background:var(--card)}
.sug-f{display:flex;align-items:center;gap:10px;padding:10px 14px;border-top:1px solid var(--line-2)}
.sug-f span{font-size:12px;color:var(--muted);line-height:1.5}
.frm .field{margin:0}
.frm .field span{display:block;font-size:12.5px;font-weight:600;color:var(--muted);margin-bottom:5px}
.frm .field small{display:block;font-size:11.5px;color:var(--faint);margin-top:4px;line-height:1.4}
.frm .err{padding:0 18px}
textarea{
  width:100%;padding:10px 12px;border:1px solid var(--line);border-radius:var(--radius-s);
  background:var(--bg);color:var(--ink);font:inherit;line-height:1.6;resize:vertical;outline:0;
  transition:border-color .15s,box-shadow .15s;
}
textarea:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
textarea[readonly]{opacity:.8}
.soft{margin-bottom:14px}

.faq{padding:14px 18px;border-bottom:1px solid var(--line-2);display:grid;grid-template-columns:1fr auto;gap:4px 16px}
.faq:last-child{border-bottom:0}
.faq .q{grid-column:1;font-weight:600}
.faq .a{grid-column:1;color:var(--muted);font-size:13px;white-space:pre-wrap}
.faq .act{grid-column:2;grid-row:1/3}
.faq.off .q,.faq.off .a{color:var(--faint)}

.hist{padding:13px 18px;border-bottom:1px solid var(--line-2);display:flex;justify-content:space-between;gap:16px;align-items:flex-start}
.hist:last-child{border-bottom:0}
.diff{display:flex;flex-wrap:wrap;gap:4px 14px;margin-top:6px;font-size:12.5px}
.diff span{color:var(--muted)}
.diff i{font-style:normal;color:var(--faint);margin-right:4px}

/* ── 設定 ───────────────────────────────────────── */
/* ⚠️ `.card-b` 特登係 `padding: 6px 0` —— 左右零。現有嘅 `.faq` `.hist`
   各自帶住 `padding: … 18px`，所以新加嘅行都要自己補返，唔係啲輸入框
   就會爆到貼住張卡個邊（第一版就係咁，量到 input 269–1392 對住
   card 268–1393，即係成個貼晒邊）。 */
.sets .set,.card-b > .kv,.card-b > .pw,.card-b .acct,.card-b > .invf{padding-left:18px;padding-right:18px}
.sets .set{padding-top:14px;padding-bottom:14px;border-bottom:1px solid var(--line-2)}
.sets .set:first-child{padding-top:6px}
.sets .set:last-child{border-bottom:0;padding-bottom:6px}
.set b{font-weight:600}
.set p{color:var(--muted);font-size:13px;line-height:1.6;margin-top:4px}
.set.off b{color:var(--muted)}
.set.col{display:flex;flex-direction:column;gap:8px}
.set.col p{margin:0}
.set .tag{margin-left:8px;vertical-align:2px}

/* 開關掣。⚠️ 用 <label> 包住個 checkbox，唔用 JS 砌 —— 咁樣鍵盤同
   螢幕閱讀器都用得，而且撳字都 toggle 到。 */
.sw{display:inline-block;vertical-align:-6px;margin-right:9px;cursor:pointer}
.sw input{position:absolute;opacity:0;width:0;height:0}
.sw i{
  display:block;width:38px;height:22px;border-radius:11px;background:var(--line);
  position:relative;transition:background .18s;
}
.sw i::after{
  content:"";position:absolute;top:3px;left:3px;width:16px;height:16px;border-radius:50%;
  background:#fff;box-shadow:0 1px 2px rgba(0,0,0,.25);transition:transform .18s;
}
.sw input:checked + i{background:var(--accent)}
.sw input:checked + i::after{transform:translateX(16px)}
.sw input:focus-visible + i{box-shadow:0 0 0 3px var(--accent-soft)}
.sw input:disabled + i{opacity:.45;cursor:not-allowed}

.kv{display:grid;gap:12px}
.kv > div{display:grid;grid-template-columns:150px 1fr;gap:4px 12px;align-items:baseline}
.kv span{color:var(--muted);font-size:13px}
.kv small{grid-column:2;color:var(--faint);font-size:12px;line-height:1.5}
/* 行業揀選。⚠️ 上面 `.kv small` 寫死咗 grid-column:2，但呢個 <small> 係
   喺 form 入面，form 唔係 grid —— 所以要喺呢度取消返，唔係就會有一格
   莫名其妙嘅空位。 */
.ind{display:grid;grid-template-columns:1fr auto;gap:8px 10px;align-items:center}
.ind select{width:100%}
.ind .btn{width:auto;padding:9px 16px}
.ind .err,.ind small{grid-column:1/3}
.kv .ind small{grid-column:1/3}

.pw{margin-top:18px;padding-top:18px;border-top:1px solid var(--line-2);display:flex;flex-direction:column;gap:8px}
.pw p{color:var(--muted);font-size:13px}
.pw .frm-grid{padding:6px 0 0}

@media (max-width:600px){
  .kv > div{grid-template-columns:1fr}
  .kv small{grid-column:1}
}

/* ── 額度 ───────────────────────────────────────── */
.use{padding:16px 18px;margin-bottom:18px;display:flex;flex-direction:column;gap:9px}
.use-h{display:flex;justify-content:space-between;align-items:baseline;gap:12px;flex-wrap:wrap}
.use-n{display:flex;align-items:baseline;gap:8px}
.use-n b{font-size:26px;line-height:1}
.use-bar{height:7px;border-radius:4px;background:var(--line);overflow:hidden}
.use-bar i{display:block;height:100%;background:var(--ok);border-radius:4px;transition:width .4s}
.use.warn .use-bar i{background:var(--warn)}
.use.bad .use-bar i{background:var(--bad)}
.use.bad{border-color:var(--bad)}
/* ── 額度版 ─────────────────────────────────────── */
.kv-r{display:flex;align-items:baseline;gap:10px;padding:11px 20px;border-bottom:1px solid var(--line-2)}
.kv-r:last-child{border-bottom:0}
.kv-r b{min-width:120px}
.kv-r span{color:var(--muted);font-size:13px;flex:1}
.kv-r em{font-style:normal;font-size:12px;font-weight:600;color:var(--accent);
  background:var(--accent-soft);padding:3px 9px;border-radius:99px}
.kv-r.on{background:var(--accent-soft)}
.topup .card-b{padding:16px 20px 18px}
.topup p{line-height:1.7;margin-bottom:8px}
.topup-a{display:flex;gap:10px;flex-wrap:wrap;margin-top:14px}
.topup-a .btn{width:auto;padding:10px 18px}

.use-msg{font-size:13px;line-height:1.65;color:var(--ink);background:var(--accent-soft);
  padding:9px 12px;border-radius:var(--radius-s);margin-top:2px}
.use.bad .use-msg{background:var(--bad-soft)}
.use.warn .use-msg{background:var(--warn-soft)}

/* ── 答唔到啲乜 ─────────────────────────────────── */
.unans{display:grid;grid-template-columns:26px 1fr auto;gap:4px 12px;align-items:center;
  padding:12px 18px;border-bottom:1px solid var(--line-2)}
.unans:last-child{border-bottom:0}
.unans .rank{width:24px;height:24px;border-radius:50%;background:var(--accent-soft);
  color:var(--accent);font-size:12px;font-weight:700;display:grid;place-items:center}
.unans b{font-weight:600}
.unans .btn{white-space:nowrap}
.kws{display:flex;flex-wrap:wrap;gap:7px}
.kw{display:inline-flex;align-items:center;gap:6px;padding:5px 10px;border-radius:99px;
  background:var(--surface);border:1px solid var(--line);font-size:13px}
.kw i{font-style:normal;color:var(--muted);font-size:11.5px;font-weight:700}
.hours{display:flex;align-items:flex-end;gap:3px;height:92px}
.hr{flex:1;display:flex;flex-direction:column;justify-content:flex-end;height:100%;gap:4px}
.hr i{display:block;background:var(--accent);border-radius:2px;min-height:2px;opacity:.85}
.hr span{font-size:9.5px;color:var(--faint);text-align:center;height:12px}

/* ── 客人 ───────────────────────────────────────── */
.per{display:grid;grid-template-columns:1fr auto auto;gap:6px 14px;align-items:center;
  padding:12px 18px;border-bottom:1px solid var(--line-2)}
.per:last-child{border-bottom:0}
.per-note{font-size:12.5px;color:var(--muted);margin-top:4px;
  padding-left:9px;border-left:2px solid var(--line)}
.per-t{display:flex;flex-wrap:wrap;gap:5px;justify-content:flex-end;max-width:260px}
.per-a{display:flex;gap:6px;align-items:center;white-space:nowrap}
.kw.sm{padding:3px 8px;font-size:11.5px}
.kw.on{border-color:var(--accent);background:var(--accent-soft);color:var(--accent);font-weight:600}
.kw.t-ok{border-color:var(--ok);color:var(--ok)}
.kw.t-warn{border-color:var(--warn);color:var(--warn)}
.kw.t-bad{border-color:var(--bad);color:var(--bad)}
.kw.t-accent{border-color:var(--accent);color:var(--accent)}
#pq input{width:220px;padding:7px 11px;font-size:13px}
@media (max-width:760px){
  .per{grid-template-columns:1fr}
  .per-t{justify-content:flex-start;max-width:none}
  .per-a{justify-content:flex-start}
  #pq input{width:100%}
}

/* 設定入面「揀一個」嗰種（預約由邊個處理）——
   揀完當面講一句嗰個模式係做咩，唔使客戶自己估。 */
.pickhint{font-size:12.5px;color:var(--muted);line-height:1.6;margin-top:8px;
  background:var(--accent-soft);padding:9px 12px;border-radius:var(--radius-s)}
/* ⚠️ 「等待落單」要同「等待人手」分得出 —— 佢係「有生意等緊接」，
   唔係「有人問咗嘢冇人覆」。同一堆入面就會沉底。 */
.wait-hd{display:flex;align-items:baseline;gap:9px;padding:14px 20px 6px;
  font-size:12.5px;font-weight:600;color:var(--muted)}
.wait-hd.book{color:var(--accent)}
.wait-hd small{font-weight:400;color:var(--faint)}

/* ── 同事 ＋ 邀請碼（期 4）──────────────── */
/* ⚠️ 全部新 class 都用 `inv-` 開頭，除了 `.invf`／`.joinbox`／`.rolenote`。
   點解：app.css 入面好多短名（`.code`／`.used`／`.open` 嗰種兩三個字），
   撞咗個 DOM 一樣啱，但畫面會爛 —— 而你會去查 JS，查極都查唔到。 */
.invf{max-width:456px}
.invf .btn{width:auto;padding:10px 18px}
.rolenote{font-size:12.5px;color:var(--muted);line-height:1.6;margin:-4px 0 14px;
  background:var(--accent-soft);padding:9px 12px;border-radius:var(--radius-s)}

.inv-box{margin-top:18px;padding:16px 18px;border:1px solid var(--accent);
  border-radius:var(--radius-s);background:var(--accent-soft)}
.inv-box p{margin-bottom:8px;font-size:13px}
.inv-box .btn{width:auto;padding:8px 16px}
/* ⚠️ 條碼係俾人攞住部手機抄嘅 —— 大字、等寬、字距鬆。
   等寬字體唔可以慳：非等寬字體嘅 rn 同 m 望落一樣，
   而客戶抄錯一隻字嘅結果係「邀請碼不正確」，兩邊都查唔到點解。 */
.inv-code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  font-size:22px;font-weight:700;letter-spacing:.08em;padding:10px 0 14px;
  color:var(--ink);word-break:break-all}
.inv-warn{color:var(--bad);font-weight:600}

/* 用咗、過咗期嘅淡色 —— 一眼分得出「等緊人入」同「完咗事」。 */
.kv-r.inv-used,.kv-r.inv-gone{opacity:.55}

/* 同事嗰行嘅權限掣同「除名」。
 * ⚠️ 呢個 select **唔可以**塞落上面 `.field input,…` 嗰條 `width:100%`
 *    嘅規則度。塞咗嘅話佢會撐開成行，把個電郵同「上次登入」逼到
 *    一個字一行 —— 望落似響應式壞咗，但其實係一條共用規則。
 *    所以呢度自己寫齊（連深色模式嗰幾個 token），唔借人哋條規則。
 * ⚠️ 兩粒都要 `flex:none` ＋ `nowrap`：唔加嘅話 flex 會壓佢哋，
 *    「除名」兩個字會斷做兩行。 */
.kv-r select{
  flex:none;width:auto;min-width:112px;padding:6px 10px;font-size:13px;
  border:1px solid var(--line);border-radius:var(--radius-s);
  background:var(--bg);color:var(--ink);font-family:inherit;outline:0;
}
.kv-r .btn.sm{flex:none;white-space:nowrap}
/* 個電郵同時間唔應該迫到一個字一行 —— 佢係成行入面最有用嗰段字。 */
.kv-r span{min-width:0}

.joinbox{border:1px solid var(--line);border-radius:var(--radius-s);margin-bottom:18px}
.joinbox .kv-r{padding:9px 14px;font-size:13px}
.joinbox .kv-r b{min-width:96px}

/* ── 細屏 ───────────────────────────────────────── */
@media (max-width:980px){
  .stats{grid-template-columns:repeat(2,1fr)}
  .grid-2,.chat-wrap{grid-template-columns:1fr}
}
@media (max-width:760px){
  .app{grid-template-columns:1fr}
  .side{position:static;height:auto;flex-direction:row;align-items:center;gap:12px;padding:12px 14px;border-right:0;border-bottom:1px solid var(--line)}
  .nav{flex-direction:row;flex:1;overflow:auto}
  .nav a{white-space:nowrap;padding:7px 10px}
  .side-foot{display:none}
  .main{padding:18px 16px 40px}
  .top{flex-direction:column}
  .msg{max-width:88%}
  /* 同事嗰行：窄屏排唔落一行。
     ⚠️ 唔可以靠 `.kv-r span{min-width:0}` 頂硬上 —— 個電郵會壓到剩返
        「a…」，而個電郵先係成行最有用嗰段字（分辨兩個同名同事就靠佢）。
        所以名同電郵各自佔一行，權限掣同「除名」留喺下面同一行。
     ⚠️ 只 scope 落 `.staff-r`，唔好落成個 `.kv-r` —— 額度版同 join 版
        都用緊 `.kv-r`，佢哋兩欄，wrap 咗會變成兩行標籤一行值。 */
  .staff-r{flex-wrap:wrap}
  .staff-r b{flex-basis:100%;min-width:0}
  .staff-r span{flex-basis:100%;flex-grow:0}
}

/* ── 數據分析（2026-09-09）────────────────────────────
 *
 * ⚠️ 全部名用 `an-` 開頭。app.css 入面好多兩三個字母嘅短名
 *    （`.k` `.v` `.d` `.hr` `.tg`），加新名之前 grep 過先 ——
 *    撞咗名個 DOM 會啱但畫面會爛，而且爛得好難查。
 *
 * ⚠️ 六格 KPI 用 `auto-fit` 唔用 `repeat(6,1fr)`：英文 label 闊過中文
 *    成 1.5 倍，寫死六欄嘅話英文版會迫到啲數字換行。
 */
/* ⚠️ 唔用 `auto-fit minmax()`：六格喺 1280 闊度下面啱啱好排到五格，
   於是第六格「新客人」自己一個吊喺第二行，望落似排版爛咗
   （2026-09-09 preview 截圖見到）。用寫死嘅欄數，而 2／3／6 三個
   都整除到 6 —— 邊個闊度都唔會有孤兒格。 */
.an-kpi{display:grid;grid-template-columns:repeat(2,1fr);gap:14px;margin-bottom:18px}
@media (min-width:760px){.an-kpi{grid-template-columns:repeat(3,1fr)}}
@media (min-width:1180px){.an-kpi{grid-template-columns:repeat(6,1fr)}}
.an-k{padding:14px 16px}
.an-k .k{font-size:12.5px;color:var(--muted);font-weight:500}
.an-k .v{font-size:26px;font-weight:700;letter-spacing:-.02em;line-height:1.2;margin-top:2px}
.an-k .d{font-size:11.5px;color:var(--faint);margin-top:3px}
.an-k .d b{font-weight:600}
.an-k .d b.up{color:var(--ok)}
.an-k .d b.down{color:var(--bad)}
.an-k.t-ok .v{color:var(--ok)}
.an-k.t-bad .v{color:var(--bad)}
.an-k.t-accent .v{color:var(--accent)}

.an-svg{width:100%;height:auto;display:block}
.an-donut{width:140px;height:140px;flex:0 0 140px}

/* 圈同旁邊嘅數。⚠️ 窄嘅時候要疊落去，唔可以硬並排 —— 一並排，
   個圈就會縮到睇唔到啲色。 */
.an-split{display:flex;align-items:center;gap:18px;flex-wrap:wrap;padding:14px 18px}
.an-legend{flex:1 1 180px;min-width:180px}
.an-legend div{display:grid;grid-template-columns:10px 1fr auto auto;gap:8px;
  align-items:center;padding:5px 0;font-size:12.5px}
.an-legend b{width:9px;height:9px;border-radius:3px;display:block}
.an-legend i{font-style:normal;font-weight:600}
.an-legend em{font-style:normal;color:var(--faint);font-size:11.5px;min-width:34px;text-align:right}

.an-leg{font-size:11.5px;color:var(--muted);display:flex;align-items:center;gap:5px}
.an-leg b{width:8px;height:8px;border-radius:2px;display:inline-block;margin-left:8px}
.an-leg b:first-child{margin-left:0}

.an-legend b.t-ok,.an-leg b.t-ok{background:var(--ok)}
.an-legend b.t-accent,.an-leg b.t-accent{background:var(--accent)}
.an-legend b.t-bad,.an-leg b.t-bad{background:var(--bad)}
.an-legend b.t-faint,.an-leg b.t-faint{background:var(--line)}

.an-grid3{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));
  gap:18px;margin:18px 0}

/* 熱力圖。一格 8px，24 格 ＋ 星期標籤 = 大約 230px，塞得落一個三欄格。 */
.an-heat-r{display:flex;align-items:center;gap:2px;margin-bottom:2px}
/* ⚠️ `width` 同 `flex-basis` 要一齊改。喺 flex row 入面計闊度嗰個係
   flex-basis，唔係 width —— 改咗 width 而留低 `flex:0 0 16px`，
   「週一」就會迫到兩行高，成個熱力圖散晒（2026-09-09 preview 見到）。 */
.an-heat-r span{font-size:11px;color:var(--faint);flex:0 0 26px;white-space:nowrap}
.an-heat-r i{flex:1 1 0;height:11px;border-radius:2px;background:var(--ok);min-width:3px}
.an-heat-x{display:flex;justify-content:space-between;margin-top:4px}
.an-heat-x span{width:26px;flex:0 0 26px}
.an-heat-x b{font-size:10px;color:var(--faint);font-weight:400}

.an-own{display:grid;grid-template-columns:1fr 90px 34px;gap:10px;align-items:center;
  font-size:12.5px;padding:5px 0}
.an-own em{font-style:normal;color:var(--warn)}
.an-own .num{text-align:right;font-weight:600}
.an-bar{height:7px;border-radius:4px;background:var(--line-2);overflow:hidden;display:block}
.an-bar i{display:block;height:100%;border-radius:4px}

/* ── Rare 支援（2026-09-10）─────────────────────────────
   ⚠️ 全部 `sup-` 開頭 —— 呢個檔好多短名（.grp .hd 都係 flex），撞咗會
      DOM 啱但畫面爛。加新 class 之前 grep 一次。
   ⚠️ 用 --warn 唔用 --accent：側欄成版都係藍，提示都藍就會溶埋落去，
      而佢存在嘅唯一理由就係「令你記得自己喺人哋間公司度」。 */
.sup-bar{display:flex;flex-direction:column;gap:4px;padding:10px 12px;border-radius:var(--radius-s);
  background:var(--warn-soft);border:1px solid var(--warn);font-size:12px;line-height:1.45;color:var(--ink)}
.sup-bar b{color:var(--warn);font-size:12.5px}
/* ⚠️ `:not(.btn)` 唔可以少 —— 返回掣都係 <a>，冇佢就會變咗藍底橙字（2026-09-10 量到）。 */
.sup-bar a:not(.btn){color:var(--warn);font-weight:600}
.sup-who{color:var(--warn);font-weight:600}
.sup-note{font-size:12.5px;line-height:1.5;margin-bottom:10px}
.sup-warn{color:var(--warn);font-weight:600}

.sup-page{max-width:1120px;margin:0 auto;padding:28px 32px 48px}
.sup-me{font-size:12.5px;color:var(--muted);text-align:right}
.sup-me b{display:block;color:var(--ink)}
.sup-me button{color:var(--faint);margin-top:4px;font-size:12px}
.sup-me button:hover{color:var(--accent)}
/* ⚠️ 除咗第一欄，其餘一律寫死闊度。每行係自己一個 grid，有一欄係
   `auto` 嘅話每行會各自計，兩行嘅數字就對唔齊（2026-09-10 preview 見到：
   「3」同「0」差咗 50px）。 */
.sup-row{display:grid;grid-template-columns:minmax(150px,1fr) 80px 120px 100px 310px 76px;
  gap:14px;align-items:center;padding:12px 0;border-bottom:1px solid var(--line-2)}
.sup-row:last-child{border-bottom:0}
.sup-name b{display:block}
.sup-name small,.sup-num small{display:block;font-size:11.5px;color:var(--faint);margin-top:2px}
.sup-num b{font-weight:600}
.sup-row.has-wait .sup-wait b{color:var(--warn)}
.sup-num.warn b{color:var(--warn)}
.sup-num.bad b{color:var(--bad)}
@media (max-width:980px){.sup-row{grid-template-columns:1fr 1fr}}
/* 自動回覆熄咗嗰條（2026-09-10）。用 --bad：佢唔係提示，係「而家冇人覆客」。 */
.pause-bar{display:flex;flex-direction:column;gap:4px;padding:10px 12px;border-radius:var(--radius-s);
  background:var(--bad-soft);border:1px solid var(--bad);font-size:12px;line-height:1.45;color:var(--ink)}
.pause-bar b{color:var(--bad);font-size:12.5px}
.pause-bar:hover{filter:brightness(.97)}
/* 忘記密碼寄咗之後嗰句（2026-09-10）。唔用 .err（紅）—— 呢句係「做咗」，唔係出錯。 */
.ok-note{padding:12px 14px;border-radius:var(--radius-s);background:var(--ok-soft);
  color:var(--ink);font-size:13px;line-height:1.6;margin-bottom:14px}
/* ── 後台直接覆客（2026-09-10）──────────────────────────
   ⚠️ 全部 `rp-` 開頭（呢個檔好多短名）。
   ⚠️ 未送到嗰啲用虛線框，同真正送咗嗰啲（.msg.out.human，實心綠）分得開 ——
      望落一樣嘅話，客戶會以為客人已經收到。 */
.rp-item{align-self:flex-end;max-width:74%;padding:9px 13px;border-radius:14px;border-bottom-right-radius:4px;
  border:1px dashed var(--ok);background:var(--ok-soft);white-space:pre-wrap;word-break:break-word;line-height:1.55}
.rp-item.rp-failed{border-color:var(--bad);background:var(--bad-soft)}
.rp-st{display:block;font-size:11.5px;color:var(--muted);margin-top:4px;white-space:normal}
.rp-bad{color:var(--bad)}
.rp-warn{color:var(--warn)}
.rp-form{border-top:1px solid var(--line);padding:14px 20px 16px}
.rp-form textarea{width:100%;min-height:74px;padding:9px 11px;border:1px solid var(--line);border-radius:var(--radius-s);
  background:var(--card);color:var(--ink);font:inherit;resize:vertical}
.rp-foot{display:flex;align-items:center;gap:10px;margin-top:8px}
.rp-foot small{flex:1;color:var(--faint);font-size:11.5px;line-height:1.45}
.rp-foot .btn{width:auto;white-space:nowrap}
.rp-note{border-top:1px solid var(--line);padding:12px 20px;font-size:12.5px;color:var(--faint)}
/* 返回「所有公司」嗰粒掣 —— 一定要睇落似掣（見 app.js 個 renderShell 註釋）。 */
.sup-bar .sup-back{display:block;text-align:center;color:var(--accent-ink);margin-bottom:6px;font-size:12.5px}
.sup-bar .sup-back:hover{color:var(--accent-ink)}