/* 有為全屋定制 · 門店報價系統 V1 */
:root{
  /* ★ 設計系統 v2（2026-10-29 全站美工改造）
     中性色全部帶一點綠，跟品牌深綠同色系 —— 畫面才不會「灰歸灰、綠歸綠」兩套。
     對比也一併拉高：--text 更深、--text-3 更深，小字在門店強光環境下才讀得到。 */
  --bg:#f1f4f2;
  --panel:#ffffff;
  --line:#e3e9e5;
  --line-2:#edf1ee;
  --text:#16211c;
  --text-2:#51655c;
  --text-3:#7c8e85;
  --brand:#1f5f4d;
  --brand-2:#2c7f66;
  --brand-soft:#e8f3ef;
  --warn:#b7791f;
  --warn-soft:#fdf3e2;
  --danger:#c0392b;
  --danger-soft:#fdeceb;
  --ok:#1f7a4d;
  --radius:12px;
  --shadow:0 1px 2px rgba(16,32,26,.05),0 3px 10px rgba(16,32,26,.06);
  /* 字級階梯：一次調這裡，全站跟著走（各模組沒有寫死字號的都會繼承） */
  --fs-body:15px;      /* 正文／表格／輸入 */
  --fs-sm:13px;        /* 表頭、標籤、次要 */
  --fs-xs:12.5px;      /* 角標、註解 */
}
*{box-sizing:border-box}
/* ---------- 關掉瀏覽器「滑過頭就上一頁」的手勢 ----------
   症狀：在橫向可捲動的寬表格（報價明細、圖紙開單預覽、產品清單…）裡按住往左拖
   （多選、或只是想滑去看後面欄位），捲到容器邊界還繼續拖，瀏覽器就把剩下的手勢
   當成「上一頁／下一頁」吃掉 → 整頁後退（SPA 是 hash 路由，看起來就是跳回上一頁）。
   程式裡沒有任何 history.back()／popstate，這是瀏覽器行為，只能靠 CSS 關掉：
     - html/body 用 overscroll-behavior-x:none　→ 關掉根層的橫向 overscroll 導航
     - 捲動容器用 contain　　　　　　　　　　　→ 自己照樣能捲，捲到底不要把剩餘手勢往外丟給整頁
   只鎖 x 軸：向下拉重整、直向捲動都不受影響。 */
html,body{overscroll-behavior-x:none}
.tbw,.modal-mask,.modal-b,.pk-tree,.pk-pop,.lines,.chg-list,.pm-tree,.pm-main,.perm-wrap,.lb-b,.content{overscroll-behavior:contain}
html,body{margin:0;padding:0}
body{
  background:var(--bg);color:var(--text);
  font-family:"PingFang TC","Microsoft JhengHei","Noto Sans TC","Microsoft YaHei",system-ui,-apple-system,"Segoe UI",sans-serif;
  font-size:14px;line-height:1.55;
}
.boot{padding:60px;text-align:center;color:var(--text-3)}
a{color:var(--brand-2);text-decoration:none}
button{font-family:inherit;font-size:13px}

/* ---------- layout ---------- */
.shell{display:flex;min-height:100vh}
.sidebar{
  width:212px;flex:0 0 212px;background:#16281f;color:#cfe0d8;padding:14px 0;
  display:flex;flex-direction:column;position:sticky;top:0;height:100vh;overflow:auto;
}
.sidebar .brand{padding:6px 18px 14px;font-size:15px;font-weight:700;color:#fff;letter-spacing:.5px}
.sidebar .brand small{display:block;font-size:11px;color:#7fa595;font-weight:400;letter-spacing:0}
.nav-group{padding:10px 18px 4px;font-size:11px;color:#6f8c80;letter-spacing:1px}
.sidebar a.nav{
  display:flex;align-items:center;justify-content:space-between;gap:8px;
  padding:8px 18px;color:#cfe0d8;font-size:13.5px;border-left:3px solid transparent;cursor:pointer;
}
/* ★ 側欄徽標（2026-10-29）：選單右邊那顆數字＝「這一格有幾筆在等你」。
   用暖橙而不是品牌綠 —— 綠色在深綠側欄上根本看不出來，數字就白做了。
   min-width + 居中讓 1 位數跟 2 位數的膠囊一樣寬，不會左右跳。 */
.nav-badge{
  flex:none;min-width:18px;height:18px;padding:0 6px;border-radius:9px;
  background:#e08a4a;color:#231a12;font-size:11px;font-weight:700;line-height:18px;
  text-align:center;letter-spacing:0;
}
.sidebar a.nav.on .nav-badge{background:#f0a868}
.sidebar a.nav:hover{background:#1d3529}
.sidebar a.nav.on{background:#1d3529;border-left-color:var(--brand-2);color:#fff;font-weight:600}
.sidebar .foot{margin-top:auto;padding:12px 18px;font-size:11px;color:#6f8c80;border-top:1px solid #24382e}

.main{flex:1;min-width:0;display:flex;flex-direction:column}
.topbar{
  height:54px;background:var(--panel);border-bottom:1px solid var(--line);
  display:flex;align-items:center;gap:14px;padding:0 18px;position:sticky;top:0;z-index:30;
}
.topbar h1{font-size:16px;margin:0;font-weight:700}
.topbar .spacer{flex:1}
.topbar .who{font-size:12.5px;color:var(--text-2);text-align:right;line-height:1.3}
.topbar .who b{color:var(--text)}
.content{padding:18px;flex:1}
.page{max-width:1360px;margin:0 auto}
/* ★★ 大螢幕放寬（2026-10-10 客戶回報「全屏的頁面也太小了」）：
      原本不管螢幕多大都鎖在 1360px —— 1920 的螢幕上右邊整整空掉一塊，
      而排班表月曆（30 天）／報價明細／財務帳款這些**寬表格**只能擠在左邊，
      還得橫向捲動才看得完。
      管理系統是拿來看表格的，不是讀文章 —— 「一行字太長不好讀」那個顧慮在這裡不成立。
      ≥1500px 就吃滿可用寬度（留白交給 .content 的 padding）；
      2200px 以上再收一個上限，免得超寬螢幕上欄位被拉得太散。 */
@media(min-width:1500px){ .page{max-width:none} }
@media(min-width:2200px){ .page{max-width:2080px} }

/* ---------- generic ---------- */
.card{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);box-shadow:var(--shadow)}
.card + .card{margin-top:14px}
/* 可收合的卡片：<details class="card acc"><summary class="card-h">…
   用途：次要、平常不需要一直看的清單（例如員工管理的「離職庫」）。
   預設收合，才不會把每天要看的在職名單往下擠。 */
details.acc>summary{list-style:none;cursor:pointer;user-select:none}
details.acc>summary::-webkit-details-marker{display:none}
details.acc>summary.card-h{border-bottom:0;border-radius:var(--radius)}
details.acc[open]>summary.card-h{border-bottom:1px solid var(--line-2);border-radius:var(--radius) var(--radius) 0 0}
details.acc>summary::after{content:'▾';margin-left:8px;color:var(--text-3);font-size:12px}
details.acc[open]>summary::after{content:'▴'}
.card-h{padding:12px 16px;border-bottom:1px solid var(--line-2);display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.card-h h2{font-size:14.5px;margin:0;font-weight:700}
.card-h .spacer{flex:1}
.card-b{padding:14px 16px}
.card-b.tight{padding:0}
.muted{color:var(--text-2)}
.tiny{font-size:12px}
.row{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.grid{display:grid;gap:12px}
.g2{grid-template-columns:repeat(2,minmax(0,1fr))}
.g3{grid-template-columns:repeat(3,minmax(0,1fr))}
.g4{grid-template-columns:repeat(4,minmax(0,1fr))}
.g5{grid-template-columns:repeat(5,minmax(0,1fr))}
label.chk{display:flex;gap:6px;align-items:center;font-size:13px;cursor:pointer}
@media(max-width:1000px){.g3,.g4,.g5{grid-template-columns:repeat(2,minmax(0,1fr))}.g2{grid-template-columns:1fr}}
@media(max-width:640px){.g2,.g3,.g4,.g5{grid-template-columns:1fr}}

.btn{
  border:1px solid var(--line);background:#fff;color:var(--text);padding:6px 12px;border-radius:7px;cursor:pointer;
  font-size:13px;transition:.12s;
}
.btn:hover{border-color:#c7cfd6;background:#fafbfc}
.btn.primary{background:var(--brand);border-color:var(--brand);color:#fff}
.btn.primary:hover{background:var(--brand-2)}
.btn.ghost{background:transparent}
.btn.danger{color:var(--danger);border-color:#e9c9c5}
.btn.danger:hover{background:var(--danger-soft)}
.btn.warn{color:#8a5a12;border-color:#e6cf9e;background:#fdf6e6}
.btn.warn:hover{background:#faedd5;border-color:#dcc084}
.btn.sm{padding:3px 8px;font-size:12px;border-radius:6px}
.btn:disabled{opacity:.45;cursor:not-allowed}
.btn.tiny{padding:1px 6px;font-size:11.5px}

input,select,textarea{
  font-family:inherit;font-size:13px;padding:6px 9px;border:1px solid var(--line);border-radius:7px;background:#fff;color:var(--text);
  width:100%;
}
input:focus,select:focus,textarea:focus{outline:2px solid var(--brand-soft);border-color:var(--brand-2)}
label.fld{display:block;margin-bottom:10px}
label.fld > span{display:block;font-size:12px;color:var(--text-2);margin-bottom:3px}
/* 唯讀的「自動產生」欄位（例如系統設定裡的「報價單用」那兩欄）：
   灰底 + 不可選取游標，一眼看出「這格不是給你打的」，避免使用者以為改了會生效。 */
input.ro,input.ro:focus{background:#f2f4f7;color:var(--text-2);border-color:var(--line-2);cursor:not-allowed;outline:none}
.req::after{content:"＊";color:var(--danger);font-size:11px;margin-left:2px}

table{width:100%;border-collapse:collapse}
th,td{padding:8px 10px;text-align:left;border-bottom:1px solid var(--line-2);vertical-align:top}
th{font-size:12px;color:var(--text-2);font-weight:600;background:#fafbfc;white-space:nowrap}
td.num,th.num{text-align:right;font-variant-numeric:tabular-nums}
tbody tr:hover{background:#fbfcfd}
.empty{padding:26px;text-align:center;color:var(--text-3);font-size:13px}

/* ---------- 寬度工具（全域：彈窗與一般表格也要用；.lines 內的維持原樣） ---------- */
.w40{width:40px}.w60{width:60px}.w70{width:70px}.w80{width:80px}
.w100{width:100px}.w120{width:120px}.w130{width:130px}.w140{width:140px}
.w150{width:150px}.w160{width:160px}.w180{width:180px}.w200{width:200px}
.w40,.w60,.w70,.w80,.w100,.w120,.w130,.w140,.w150,.w160,.w180,.w200{max-width:100%;min-width:0}
input.w40,input.w60,input.w70,input.w80,input.w100,input.w120,input.w130,input.w140,
input.w150,input.w160,input.w180,input.w200{padding:5px 6px;font-size:12.5px}
.row.wrap{flex-wrap:wrap}
.c-danger{color:var(--danger);font-weight:600}
.c-ok{color:var(--ok);font-weight:600}

/* ---------- 圖紙開單 ---------- */
.tbw{overflow-x:auto;-webkit-overflow-scrolling:touch;max-width:100%;margin-bottom:2px}
/* ★ 固定操作列（2026-10-29）：補單表有 9 欄，窄一點的螢幕上最右邊那欄
   （刪除／作廢）會被推出畫面，聖輝就以為「這一頁不能刪」。
   把它釘在右邊，橫向捲動時也看得到。需要外層 .tbw 才有作用（u.wrapTables 會加）。 */
table.sticky-ops th:last-child,
table.sticky-ops td:last-child{
  position:sticky;right:0;background:var(--panel);
  box-shadow:-8px 0 10px -8px rgba(0,0,0,.35);
  white-space:nowrap;
}
table.sticky-ops thead th:last-child{z-index:3}
table.sticky-ops tbody td:last-child{z-index:2}
/* 圖紙開單預覽表：材料／產品欄的挑選器按鈕（原生 select 不能打字找，改用挑選器） */
.tbw .pk-wrap{display:flex}
.tbw .pk-wrap .pk-btn{max-width:190px;min-width:110px}
.tbw .pk-wrap .pk-btn .pk-tx{font-size:12px}
.hw-hint{display:block;margin-top:3px}
tr.off{opacity:.42}
tr.off input,tr.off select{background:#f4f6f8}
.dz.busy{border-color:var(--brand);background:var(--brand-soft);cursor:progress}
.dz.over{border-color:var(--brand);background:var(--brand-soft);border-style:solid}
.dz .tiny{margin-top:6px;line-height:1.6}
.dz b.c-danger{display:block;margin-bottom:2px}
/* 尺寸欄「下一個會被填入」的標記 */
input.pick{border-color:var(--brand);box-shadow:0 0 0 2px var(--brand-soft);background:#fbfffd}
input.autofill{background:#fffaf0;border-color:#e8cf9a}

.tag{display:inline-block;padding:1px 7px;border-radius:20px;font-size:11.5px;background:#eef1f4;color:var(--text-2);border:1px solid var(--line)}
.tag.ok{background:#e7f4ec;color:var(--ok);border-color:#cfe8d8}
.tag.warn{background:var(--warn-soft);color:var(--warn);border-color:#f0dcb8}
.tag.danger{background:var(--danger-soft);color:var(--danger);border-color:#f3cfcb}
.tag.brand{background:var(--brand-soft);color:var(--brand);border-color:#cfe5dc}
.tag.grey{background:#f1f3f5;color:var(--text-3)}

#toast-root{position:fixed;right:16px;bottom:16px;z-index:200;display:flex;flex-direction:column;gap:8px}
#modal-root{position:relative;z-index:150}
.toast{background:#1d2733;color:#fff;padding:9px 14px;border-radius:8px;font-size:13px;box-shadow:var(--shadow);max-width:360px;white-space:normal;line-height:1.6;cursor:pointer}
.toast.err{background:var(--danger)}
.toast.ok{background:var(--ok)}
.toast.warn{background:#8a5a00;color:#fff;white-space:normal;line-height:1.6}

.modal-mask{position:fixed;inset:0;background:rgba(18,26,34,.42);z-index:150;display:flex;align-items:flex-start;justify-content:center;padding:34px 14px;overflow:auto}
.modal{background:#fff;border-radius:12px;width:100%;max-width:640px;box-shadow:0 12px 40px rgba(15,25,35,.25)}
.modal.wide{max-width:960px}
.modal.narrow{max-width:440px}
.modal-h{padding:13px 18px;border-bottom:1px solid var(--line-2);display:flex;align-items:center}
.modal-h h3{margin:0;font-size:15px}
.modal-h .x{margin-left:auto;cursor:pointer;color:var(--text-3);font-size:18px;line-height:1}
.modal-b{padding:16px 18px;max-height:64vh;overflow:auto}
.modal-f{padding:12px 18px;border-top:1px solid var(--line-2);display:flex;gap:8px;justify-content:flex-end}

.seg{display:inline-flex;border:1px solid var(--line);border-radius:7px;overflow:hidden}
.seg button{border:0;background:#fff;padding:5px 11px;cursor:pointer;color:var(--text-2);font-size:12.5px}
.seg button + button{border-left:1px solid var(--line)}
.seg button.on{background:var(--brand);color:#fff;font-weight:600}
/* ★ 頁籤很多時要能換行（2026-10-12 財務頁收成 8 個頁籤）：
   原本 `.seg` 是 inline-flex 且 overflow:hidden，多的頁籤會直接消失在右邊邊界外
   —— 手機上尤其嚴重（看不到「帳單對帳」還以為功能不見了）。
   `.seg.wrap` 改成可以換行的膠囊列，每個頁籤自己一圈框。 */
.seg.wrap{display:flex;flex-wrap:wrap;gap:6px;border:0;border-radius:0;overflow:visible;padding:0}
.seg.wrap button{border:1px solid var(--line);border-radius:7px;background:#fff}
.seg.wrap button + button{border-left:1px solid var(--line)}
.seg.wrap button.on{background:var(--brand);color:#fff;border-color:var(--brand)}

/* ---------- login ---------- */
.login-wrap{min-height:100vh;display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,#16281f,#24503f 60%,#2c7f66);padding:20px}
.login-card{width:100%;max-width:400px;background:#fff;border-radius:14px;padding:28px;box-shadow:0 20px 50px rgba(0,0,0,.28)}
.login-card .logo{font-size:19px;font-weight:800;color:var(--brand);letter-spacing:1px}
.login-card .sub{font-size:12px;color:var(--text-2);margin:2px 0 20px}
.login-card h3{font-size:15px;margin:0 0 12px}
.hintbox{background:#f7f9fa;border:1px dashed var(--line);border-radius:8px;padding:10px 12px;font-size:12px;color:var(--text-2);margin-top:14px}

/* ---------- quote editor ---------- */
.qbar{
  position:sticky;top:54px;z-index:20;background:#fff;border:1px solid var(--line);border-radius:var(--radius);
  padding:10px 14px;display:flex;gap:12px;align-items:center;flex-wrap:wrap;box-shadow:var(--shadow);
}
.qbar .kv{font-size:12px;color:var(--text-2)}
.qbar .kv b{color:var(--text);font-size:13px}
/* 報價單客戶可以直接更換（開錯客戶時） */
.chg-list{margin-top:6px;border:1px solid var(--line-2);border-radius:8px;max-height:300px;overflow:auto}
.chg-item{display:flex;align-items:center;gap:8px;padding:7px 10px;cursor:pointer;font-size:13px;border-bottom:1px solid var(--line-2)}
.chg-item:last-child{border-bottom:0}
.chg-item:hover{background:var(--brand-soft)}
.chg-item.on{background:var(--brand-soft)}
.chg-item b{flex:none}
.chg-item .muted{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.chg-item .brand{flex:none;color:var(--brand)}
.qbar .sep{width:1px;height:26px;background:var(--line)}
.space-block{margin-top:14px}
.space-h{display:flex;align-items:center;gap:8px;padding:9px 14px;background:var(--brand-soft);border:1px solid #cfe5dc;border-radius:8px 8px 0 0;border-bottom:0}
.space-h .nm{font-weight:700;font-size:13.5px}
.lines{border:1px solid var(--line);border-top:0;border-radius:0 0 8px 8px;overflow:auto}
.lines table{min-width:1110px}   /* 含最左邊的拖曳握把欄；少了這 30px 操作欄會被擠到換行 */
.lines td{padding:5px 6px}
.lines th{padding:6px}
.lines input,.lines select{padding:4px 6px;font-size:12.5px}
.lines .w40{width:40px}.lines .w60{width:60px}.lines .w70{width:70px}.lines .w80{width:80px}
.lines .w100{width:100px}.lines .w130{width:130px}.lines .w150{width:150px}.lines .w180{width:180px}
.lines td.amt{font-weight:700;font-variant-numeric:tabular-nums}
.lines .miss{color:var(--danger);font-weight:600}

/* ---------- 手動排序：拖曳握把＋上移／下移 ----------
   ★ 只有握把（.drag-h）可拖，不要讓整列 draggable：
     整列可拖的話，在品名輸入框裡按住選字會被瀏覽器判成「拖曳這一列」。 */
.lines .w30{width:30px}
.dh-cell{text-align:center;padding:2px 0!important}
.drag-h{cursor:grab;user-select:none;-webkit-user-select:none;display:inline-flex;align-items:center;
  justify-content:center;width:26px;height:26px;border-radius:6px;color:var(--text-3);
  font-size:15px;line-height:1;touch-action:none}
.drag-h:hover{background:var(--line-2);color:var(--text)}
.drag-h:active{cursor:grabbing}
.space-h .drag-h{width:22px;height:22px;font-size:14px}
/* 拖起來的那一列／那一塊：半透明，看得出「正在搬的是這個」 */
tr.dragging,.space-block.dragging{opacity:.4}
/* 落下位置的指示線（插在目標前面／後面） */
.lines tr.dgt>td{border-top:2px solid var(--brand)}
.lines tr.dgb>td{border-bottom:2px solid var(--brand)}
.space-block.dgt{border-top:2px solid var(--brand)}
.space-block.dgb{border-bottom:2px solid var(--brand)}
/* 移動後短暫高亮，不然重繪完會不知道剛剛動到哪一列 */
@keyframes justmoved{from{background:#fff6d6}to{background:transparent}}
.just-moved{animation:justmoved .9s ease-out}
.btn.tiny.mv{min-width:30px;padding:3px 6px;font-weight:700}
.sub-note{font-size:11.5px;color:var(--text-3);padding:6px 10px;border-top:1px dashed var(--line-2)}
.totals{display:flex;justify-content:flex-end;padding:14px}
.totals table{width:320px}
.totals td{padding:5px 8px}
.totals tr.grand td{font-size:17px;font-weight:800;border-top:2px solid var(--text);padding-top:9px}
.warnbar{background:var(--warn-soft);border:1px solid #f0dcb8;color:#8a5a12;padding:8px 12px;border-radius:8px;font-size:12.5px;margin-top:12px}
/* 紅色的警示條：用在「這件事會留下對客戶的後果」的地方（例如改已發出報價單的單號）。
   刻意跟黃色的 warnbar 分開 —— 同一個顏色用在「提醒」和「會出事」上，人就兩個都不看了。 */
.warnbar.danger{background:#fdecea;border-color:#f3c9c3;color:#9b2c20}

/* ★ 來源標示（2026-10-12 防呆）：同一筆錢在兩個地方都碰得到時，
     在兩邊各標出「這筆是從哪裡來的／轉到哪裡去了」，並給互相跳轉的連結。
     例如：定金按「抵扣」→ 收款明細長出一筆 → 兩邊都看得到對方的單號。 */
.srctag{margin-top:3px;font-size:12px;line-height:1.45}
.srctag .tag{font-size:11px;padding:0 5px}
.srctag a{text-decoration:underline}
/* 從別頁跳過來時，被點的那一筆要看得見：底色標一下就好，不閃、不跳動 */
.focusrow{background:var(--warn-soft)!important;box-shadow:inset 3px 0 0 var(--brand)}
.errbar{background:var(--danger-soft);border:1px solid #f3cfcb;color:var(--danger);padding:8px 12px;border-radius:8px;font-size:12.5px;margin-top:12px}

/* ---------- 計量彙總（投影平方數／米數）----------
   面積與長度是兩種維度，視覺上也要分成兩列、各帶自己的單位，
   不給任何「加總成一個數字」的暗示。 */
.meas{width:320px;margin-top:14px;padding:10px 12px;border:1px solid var(--line);border-radius:8px;background:var(--bg)}
.meas-t{font-size:12.5px;font-weight:700;margin-bottom:6px}
.meas-row{display:flex;justify-content:space-between;align-items:baseline;padding:4px 0;font-size:13px}
.meas-row span{color:var(--text-3)}
.meas-row b{font-size:15px;font-variant-numeric:tabular-nums}
.meas-row+.meas-row{border-top:1px dashed var(--line-2)}
.meas-sp{font-size:11.5px;color:var(--text-3);border-top:1px dashed var(--line-2);margin-top:6px;padding-top:6px;line-height:1.7}
.meas-note{font-size:11px;color:var(--text-3);margin-top:5px}
.meas-empty{font-size:12px;color:var(--text-3);line-height:1.6}
.sp-meas{font-size:11.5px;color:var(--text-2);background:var(--bg);border:1px solid var(--line);border-radius:6px;padding:2px 7px;margin-left:6px;white-space:nowrap;font-variant-numeric:tabular-nums}

/* ---------- 自動轉匯（原幣 × 匯率 ＝ 訂單本幣）----------
   收款／退款／支出／發票四張表單共用同一塊 .fxblk；清單上的 .fxnote 是
   「這筆是怎麼換來的」的註記（一樣受金額遮罩管）。 */
.fxblk{border:1px dashed var(--line);border-radius:8px;padding:10px 12px;margin:10px 0;background:var(--bg)}
.fxblk .fld{margin-bottom:6px}
.fxblk #fxBtnWrap{display:flex;flex-direction:column;justify-content:flex-end}
/* ★ #fxBtnWrap 是 ID 選擇器，會蓋掉 [hidden] 的 display:none —— 一定要補這一條，
   否則「與訂單同幣別」時「抓今日匯率」按鈕不會藏起來。 */
.fxblk #fxBtnWrap[hidden]{display:none}
.fxblk #fxBtnWrap .btn{width:100%;min-height:34px}
.fxprev{margin-top:6px;font-size:12.5px}
.fxnote{font-size:11px;line-height:1.4;margin-top:1px}

/* ---------- 考勤打卡 ----------
   兩顆大按鈕是全頁的主角：手指頭要點得到（手機 ≥38px 是這套系統的底線，
   打卡鈕刻意做得更大），「已打卡」的狀態要一眼看出來，不用去讀文字。 */
.punch-row{display:flex;gap:12px;flex-wrap:wrap;margin-top:10px}
.punch-btn{flex:1 1 180px;min-width:160px;min-height:76px;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:3px;border-radius:12px;cursor:pointer;
  border:1px solid var(--line);background:var(--panel);transition:.15s}
.punch-btn b{font-size:17px}
.punch-btn span{font-size:11.5px;color:var(--text-3)}
.punch-btn.in{border-color:var(--brand);color:var(--brand);background:var(--brand-soft)}
.punch-btn.out{border-color:#5b7fa6;color:#2f5d84;background:#eef4fa}
.punch-btn:hover{filter:brightness(.97)}
.punch-btn.done{background:#f4f6f8;color:var(--text-3);border-style:dashed;cursor:default}
.punch-btn.done b{color:var(--text-2)}
.punch-btn[disabled]{opacity:.7;cursor:progress}
@media(max-width:640px){.punch-row{flex-direction:column}.punch-btn{width:100%}}
tr.dim td{color:var(--text-3)}

/* ---------- 存檔失敗的常駐警告條（#write-bar）----------
   為什麼不是 toast：toast 3 秒就消失。存檔失敗＝資料隨時會不見，使用者必須一直看得到。
   掛在 #app 之外（body 第一個子元素）並用 sticky，換頁整批重繪也洗不掉。
   z-index 900：蓋過彈窗（.modal-mask 150），但刻意低於挑選浮層（.pk-pop 4000）與
   圖片燈箱（.lb-mask 4600）—— 那兩個是全螢幕遮罩，被蓋住會擋到操作。 */
.write-bar{display:none}
.write-bar.on{display:block;position:sticky;top:0;z-index:900;background:var(--danger-soft);
  border-bottom:2px solid var(--danger);padding:10px 14px;font-size:13px;color:#7d2019}
.write-bar .wbb{display:flex;gap:12px;align-items:center;justify-content:center;flex-wrap:wrap;text-align:center}
.write-bar .wbt{line-height:1.6}
.write-bar .wba{display:flex;gap:8px;flex-wrap:wrap}
.write-bar .wbn{margin-top:6px;font-size:12px;color:#9a4038;line-height:1.6;text-align:center}

/* ---------- 連不上雲端時的常駐警告條（#sync-bar）----------
   為什麼要有：同步失敗原本只顯示在側欄底部那一行小字，員工錄了一整天的客戶與報價、
   以為已經存到雲端，其實整包都只在那台手機上 —— 老闆那台當然一筆都看不到，
   而且沒有任何一方知道出了什麼事（真實踩到：三位員工的資料一筆都沒上來）。
   規格與 #write-bar 一致：掛在 #app 之外、sticky、換頁洗不掉；但**兩者互斥**，
   因為「資料隨時會不見」比「還沒上傳」更急，兩條疊在一起會擠掉畫面。
   z-index 890（比 #write-bar 的 900 低，反正不會同時出現）。 */
.sync-bar{display:none}
.sync-bar.on{display:block;position:sticky;top:0;z-index:890;background:var(--warn-soft);
  border-bottom:2px solid #e0b070;padding:10px 14px;font-size:13px;color:#8a5a12}
.sync-bar .sbb{display:flex;gap:12px;align-items:center;justify-content:center;flex-wrap:wrap;text-align:center}
.sync-bar .sbt{line-height:1.6}
.sync-bar .sba{display:flex;gap:8px;flex-wrap:wrap}
.sync-bar .sbn{margin-top:6px;font-size:12px;color:#96631a;line-height:1.6;text-align:center}
.sync-bar code{background:#fff;border:1px solid #e6d3ae;border-radius:4px;padding:1px 5px;
  font-size:11.5px;word-break:break-all}

/* ---------- 系統設定：本機儲存用量 ---------- */
.storbar{font-size:12.5px;color:var(--text-2);background:var(--line-2);border:1px solid var(--line);
  border-radius:8px;padding:8px 12px;line-height:1.7}
.storbar.bad{background:var(--danger-soft);border-color:#f3cfcb;color:#7d2019}

/* ---------- 已鎖定版本：說明為什麼點不動 ＋ 一鍵產生新版本 ---------- */
.lockbar{display:flex;align-items:center;gap:12px;margin-top:12px;padding:12px 14px;border-radius:10px;
  background:#fff8e8;border:1px solid #f0dcb8;color:#8a5a12}
.lockbar .lb-ic{font-size:18px;line-height:1}
.lockbar .lb-tx b{display:block;font-size:13.5px;color:#7a4d0d;margin-bottom:2px}
.lockbar .lb-tx .tiny{color:#9a6a20;line-height:1.6;max-width:760px}
.lock-wrap{position:relative}
.lock-mask{position:absolute;inset:0;z-index:12;background:rgba(255,255,255,.6);border-radius:10px;display:flex;align-items:center;justify-content:center;cursor:not-allowed}
.lock-card{background:#fff;border:1px solid var(--line);box-shadow:var(--shadow);border-radius:10px;padding:16px 20px;max-width:520px;text-align:center;cursor:default}
.lock-card .lk-t{font-weight:700;font-size:14px;margin-bottom:4px}
.lock-card .tiny{color:var(--text-2);line-height:1.6}
#spaces [disabled],#totalsZone [disabled],#qNote[disabled],#qDisc[disabled]{cursor:not-allowed;background:#f3f5f7}
input[disabled],select[disabled],textarea[disabled]{cursor:not-allowed;color:var(--text-2);background:#f3f5f7}
.okbar{background:#e7f4ec;border:1px solid #cfe8d8;color:var(--ok);padding:8px 12px;border-radius:8px;font-size:12.5px;margin-top:12px}
code.pwd{font-family:ui-monospace,Consolas,Menlo,monospace;background:var(--bg-soft);border:1px solid var(--line);padding:3px 8px;border-radius:6px;font-size:13.5px;letter-spacing:.6px;white-space:nowrap}

.filters{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-bottom:12px}
.filters input,.filters select{width:auto;min-width:120px}

.kpi{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px}
@media(max-width:900px){.kpi{grid-template-columns:repeat(2,minmax(0,1fr))}}
.kpi .box{background:#fff;border:1px solid var(--line);border-radius:10px;padding:14px}
.kpi .box .n{font-size:24px;font-weight:800;letter-spacing:-.5px}
.kpi .box .t{font-size:12px;color:var(--text-2)}

.logline{font-size:12.5px;padding:6px 0;border-bottom:1px dashed var(--line-2)}
.logline .t{color:var(--text-3);margin-right:8px;font-variant-numeric:tabular-nums}

/* ---------- 產品圖片 ---------- */
.thumb{width:40px;height:40px;object-fit:cover;border-radius:6px;border:1px solid var(--line);cursor:pointer;vertical-align:middle;background:#fff}
.thumb.lg{width:88px;height:88px}
.thumb-none{display:inline-flex;width:40px;height:40px;align-items:center;justify-content:center;border:1px dashed var(--line);border-radius:6px;color:var(--text-3);font-size:11px}
.thumb-none.lg{width:88px;height:88px}

/* ---------- 產品庫：三層目錄樹 ---------- */
.pm{display:flex;align-items:flex-start;gap:0}
.pm-tree{width:236px;flex:0 0 236px;border-right:1px solid var(--line);padding:10px 8px 14px;max-height:74vh;overflow:auto}
.ct-head{display:flex;align-items:center;gap:6px;padding:0 6px 8px;font-size:13px;border-bottom:1px dashed var(--line);margin-bottom:6px}
.ct-row{display:flex;align-items:center;gap:5px;padding:5px 8px;border-radius:6px;cursor:pointer;font-size:13px;color:var(--text)}
.ct-row:hover{background:var(--line-2)}
.ct-row.on{background:var(--brand-soft);color:var(--brand);font-weight:600}
.ct-tw{width:13px;flex:0 0 13px;font-size:10px;color:var(--text-3);text-align:center}
.ct-nm{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ct-n{font-size:11px;color:var(--text-3);font-weight:400}
.ct-hint{padding:0 6px 6px;line-height:1.5}
.ct-act{display:none;align-items:center;gap:1px}
.ct-row:hover .ct-act{display:flex}
.ct-row:hover .ct-n{display:none}
.ct-b{border:1px solid var(--line);background:#fff;color:var(--text-2);border-radius:5px;font-size:11px;line-height:1;padding:3px 5px;cursor:pointer}
.ct-b:hover{background:var(--brand-soft);color:var(--brand);border-color:var(--brand)}
.ct-b.danger{color:var(--danger)}
.ct-b.danger:hover{background:var(--danger-soft);border-color:var(--danger)}
.cm-tb{width:100%}
.cm-tb td{border-bottom:1px solid var(--line-2);padding:5px 4px}
.ct-row.lv2{padding-left:24px}
.ct-row.lv3{padding-left:40px}
.pm-main{flex:1;min-width:0;padding:10px 14px 14px}
.pm-bar{display:flex;align-items:center;gap:8px;padding-bottom:8px;margin-bottom:8px;border-bottom:1px dashed var(--line)}
.pm-crumb{display:flex;align-items:baseline;gap:8px;min-width:0}
@media (max-width:960px){
  .pm{flex-direction:column}
  .pm-tree{width:auto;flex:none;border-right:0;border-bottom:1px solid var(--line);max-height:none}
}
/* ---------- 頂欄在手機上（2026-10-29 實測修） ----------
   390×844 實測：「回收站」被拆成「回收／站」兩行、「展示模式」也被折行，
   整個頂欄吃掉快 100px 高，看起來像沒做完的東西。
   作法：按鈕一律不換行、頂欄改成可以橫向捲動（比折行好讀也比較像手機 App），
   姓名／角色那一塊在窄螢幕收起來（側欄抽屜裡看得到）。 */
@media (max-width:720px){
  .topbar{height:auto;min-height:52px;gap:8px;padding:6px 10px;overflow-x:auto;overflow-y:hidden}
  .topbar > *{flex:0 0 auto}
  .topbar .spacer{flex:0 0 2px;width:2px}
  .topbar h1{font-size:15px;white-space:nowrap;max-width:34vw;overflow:hidden;text-overflow:ellipsis}
  .topbar .btn,.topbar .btn.sm{white-space:nowrap;padding:6px 10px;line-height:1.2}
  .topbar .who{display:none}
  .topbar .seg button{padding:4px 9px}
}

/* 觸控裝置沒有 hover，目錄的編輯按鈕一律顯示，否則永遠點不到 */
@media (hover:none),(pointer:coarse){
  .ct-act{display:flex}
  .ct-n{display:none}
}

/* ---------- 櫃體×櫃門對應矩陣 ---------- */
table.mx{border-collapse:collapse}
table.mx th{background:#f6f8f7;border:1px solid var(--line);padding:6px 8px;font-size:12px;white-space:normal;min-width:88px}
table.mx th:first-child{text-align:left;position:sticky;left:0;background:#f6f8f7;z-index:2}
table.mx td.mx-cell{border:1px solid var(--line);padding:0;text-align:center;min-width:88px}
.mx-price,.mx-new{display:block;width:100%;border:0;background:transparent;padding:8px 4px;cursor:pointer;font-size:12.5px;font-variant-numeric:tabular-nums}
.mx-price{color:var(--brand);font-weight:700}
.mx-price:hover{background:var(--brand-soft)}
.mx-new:hover{background:#f4f6f8}
.mx-split{color:#9aa5ad;font-size:11.5px;font-weight:400}
.row-dup{background:#fdf6e5}

/* ---------- 檔案匯入（拖檔／選檔） ---------- */
.dz{border:2px dashed #c3ced6;border-radius:12px;padding:18px 14px;text-align:center;cursor:pointer;
  background:#f7faf9;transition:border-color .15s,background .15s}
.dz:hover,.dz.on{border-color:var(--brand);background:var(--brand-soft)}
.dz-ic{font-size:26px;line-height:1;color:var(--brand)}
.dz-t{font-size:13.5px;margin-top:6px}
.dz-s{font-size:11.5px;color:var(--text-3);margin-top:4px}
.f-list{margin-top:10px;display:flex;flex-direction:column;gap:6px}
.f-row{display:flex;align-items:center;gap:8px;padding:6px 9px;border:1px solid var(--line);
  border-radius:8px;background:#fbfcfd;font-size:12.5px}
.f-row.err{border-color:#f3cfcb;background:var(--danger-soft)}
.f-nm{max-width:240px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dz-mask{position:fixed;inset:0;z-index:90;display:flex;align-items:center;justify-content:center;
  background:rgba(20,32,28,.42);pointer-events:none}
.dz-mask-in{background:#fff;border:2px dashed var(--brand);color:var(--brand);border-radius:14px;
  padding:22px 32px;font-size:15px;font-weight:700;box-shadow:var(--shadow)}

/* ---------- print / PDF（A4 最佳化） ---------- */
#print-area{display:none}
@media print{
  body{background:#fff}
  /* ★★★ 2026-10-19 修「列印到處跑版」：以前只藏 .shell/.topbar/.sidebar/#toast-root，
     漏了下面這四個 —— 每一個都足以讓整份單據跑掉：
       #write-bar／#sync-bar  存檔失敗與連不上雲端的常駐警告條，是 position:sticky top:0，
                              只要它開著，第一頁頂端就多一條彩色橫幅、整份內容往下推。
       #modal-root            從彈窗按「列印」時遮罩還在，而 .modal-mask 是 fixed inset:0
                              ⇒ 整張單被蓋住或只印到一角。
       #toast-root / .no-print 同前。
     另外 #print-area 要自己撐滿版面、不繼承任何寬度限制。 */
  .shell,.topbar,.sidebar,.no-print,
  #write-bar,#sync-bar,#modal-root,#toast-root{display:none !important}
  #print-area{display:block !important;width:auto;max-width:none;margin:0;padding:0}
  #print-area *{visibility:visible}
  #print-area img{max-width:100%;height:auto}
  /* ★ .pq 的 186mm 是給螢幕預覽的：A4 邊界 14mm ⇒ 可印寬只有 182mm，比它窄 4mm，
     右邊固定被切掉（或整份被縮小）。列印時一律交給可用寬度決定。 */
  .pq,.ct-wrap{max-width:none !important;width:auto !important}
  @page{size:A4;margin:16mm 14mm 18mm 14mm}
}
/* 報價單本體：螢幕預覽與列印共用；字級以 A4 閱讀為準（正文 ≈11.5pt、表格 ≈10.5pt） */
.pq{font-size:15px;color:#000;background:#fff;line-height:1.55;max-width:186mm}
.pq h1{font-size:25px;margin:0;letter-spacing:1px}
.pq .co{font-size:13.5px;color:#333;margin-top:5px}
.pq .doc-t{font-size:19px;font-weight:800;letter-spacing:6px;text-align:center;margin:10px 0 2px}
.pq .meta{text-align:right;font-size:13.5px;line-height:1.7}
.pq .hdr{display:flex;justify-content:space-between;gap:20px;border-bottom:2.5px solid #222;padding-bottom:10px;align-items:flex-end}
.pq table{width:100%;border-collapse:collapse;margin-top:12px}
.pq th,.pq td{border:1px solid #8a8a8a;padding:5px 7px;font-size:13.5px;vertical-align:middle}
.pq th{background:#efefef;font-size:13.5px}
.pq td.num{text-align:right;font-variant-numeric:tabular-nums}
.pq td.tiny,.pq .tiny{font-size:12px}
.pq .space-row{background:#f2f2f2;font-weight:700;font-size:14px}
/* 每個空間自己的小計：比明細重一點、比表尾的合計輕一點 */
.pq .space-sub{background:#fbfbfb;font-weight:600}
.pq .space-sub td{border-top:1px dashed #b9b9b9}
.pq tfoot td{font-size:13.5px}
.pq tfoot tr:last-child td{font-size:16px}
.pq .foot{margin-top:14px;font-size:12.5px;color:#333}
.pq .sign{margin-top:30px;display:flex;gap:46px;font-size:13.5px}
.pq .pimg{width:16mm;height:16mm;object-fit:cover;border:1px solid #bbb;border-radius:2mm;vertical-align:middle}
/* 列印分頁控制：表頭每頁重複、行不腰斬、空間標題與下一行同頁 */
@media print{
  .pq thead{display:table-header-group}
  /* ★★ 表尾（合計／稅金／應付總額）只能出現一次。
     預設是 table-footer-group，Chrome 列印時會「每頁重複」，
     於是每一頁的底部都印著整張單的總額 —— 客戶看到的第一頁只有兩個空間，
     底下卻寫 13 萬，當然會問「這兩個空間要 13 萬？」。改成一般列群組就只印在最後。 */
  .pq tfoot{display:table-row-group}
  .pq tr{break-inside:avoid;page-break-inside:avoid}
  .pq .space-row{break-after:avoid;page-break-after:avoid}
  .pq .space-sub{break-before:avoid;page-break-before:avoid}
  .pq .foot,.pq .sign{break-inside:avoid}
}
.pq .hdr{display:flex;justify-content:space-between;align-items:flex-start;border-bottom:2px solid #000;padding-bottom:8px}
.pq .meta{text-align:right;font-size:11.5px}

/* ===== 合約匯出：文件預覽與列印 ===== */
.ct-wrap{background:#fff;color:#111;font-size:14.5px;line-height:1.8;max-width:186mm;margin:0 auto;padding:4px 2px}
.ct-h1{font-size:22px;text-align:center;letter-spacing:3px;margin:16px 0 12px;font-weight:800}
.ct-h2{font-size:15.5px;margin:14px 0 6px;font-weight:800}
.ct-p{margin:3px 0;text-align:justify}
.ct-li{margin:2px 0 2px 22px;text-align:justify}
.ct-c{text-align:center;margin:4px 0}
.ct-small{font-size:11.5px;color:#666;margin-top:10px}
.ct-tb{width:100%;border-collapse:collapse;margin:8px 0;font-size:12.5px}
.ct-tb th,.ct-tb td{border:1px solid #9a9a9a;padding:4px 6px;vertical-align:top}
.ct-tb th{background:#eee}
.ct-tb td.num{text-align:right;font-variant-numeric:tabular-nums}
.ct-tb tr.sp td{background:#f5f5f5;font-weight:700}
.ct-tb tr.b td{font-weight:800}
.pb{height:0;break-after:page;page-break-after:always}
@media print{
  .ct-wrap{font-size:12pt;max-width:none}
  .ct-h1{font-size:18pt}
  .ct-h2{font-size:13pt}
  .ct-tb{font-size:10pt}
  .ct-tb thead{display:table-header-group}
  .ct-tb tr{break-inside:avoid;page-break-inside:avoid}
  .ct-h2{break-after:avoid;page-break-after:avoid}
}

/* 打包列印：合約本文 → 報價總表 → 圖紙，圖紙每頁都從新的一張紙開始 */
.pack-page{page-break-before:always;break-before:page}
.pack-t{font-size:12px;color:#5b6b7c;margin-bottom:6px}
.pack-page img{display:block;margin:0 auto;max-width:100%;height:auto}

/* ===== 線上簽署：客戶免登入簽署頁 ===== */
.sign-page{min-height:100vh;padding:26px 16px 70px;display:flex;justify-content:center}
.sign-box{width:100%;max-width:880px}
.sign-head{border-bottom:2px solid var(--brand);padding-bottom:12px;margin-bottom:16px}
.sign-brand{font-size:12px;letter-spacing:3px;color:var(--brand);font-weight:700}
.sign-head h1{margin:6px 0 10px;font-size:23px;line-height:1.3}
.sign-meta{display:flex;flex-wrap:wrap;gap:6px 20px;font-size:12.5px;color:var(--text-2)}
.sign-meta b{color:var(--text)}
.sign-doc{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:22px 24px;margin-bottom:14px;box-shadow:var(--shadow)}
.sign-hash{background:var(--brand-soft);border:1px solid #cfe4dd;border-radius:var(--radius);padding:10px 14px;font-size:12px;color:var(--text-2);margin-bottom:14px}
.sign-hash code{display:inline-block;margin-top:4px;font-size:12.5px;letter-spacing:.5px;color:var(--brand);word-break:break-all}
.sign-form,.sign-done{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:16px 18px;box-shadow:var(--shadow)}
.sign-done .ok{font-size:16px;font-weight:700;color:var(--ok)}
.sign-done .wait{font-size:16px;font-weight:700;color:var(--warn)}
.sign-preview{margin-top:10px;padding:8px;background:#fbfcfc;border:1px dashed var(--line);border-radius:8px}
.sign-preview img{max-width:260px;height:auto;display:block}
.sign-err{background:var(--danger-soft);border:1px solid #f3cfcb;color:var(--danger);padding:12px 14px;border-radius:var(--radius);font-size:13.5px}
.ct-sign{margin:6px 0 14px}
/* 一個段落裡可能同時有公司章與負責人章（左右並排），所以要 inline-block＋右邊距 */
.ct-sign img{max-width:100%;height:auto;display:inline-block;vertical-align:middle;margin-right:12px}

/* ===== 系統設定：電子印章 ===== */
.seal-head{font-size:13.5px;font-weight:700;margin:16px 0 0;padding-top:12px;border-top:1px dashed var(--line)}
.seal-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin:10px 0 8px}
.seal-card{border:1px solid var(--line);border-radius:var(--radius);padding:10px 12px;background:#fbfcfc;min-width:0}
.seal-card h4{margin:0 0 8px;font-size:13px}
/* 印章是透明背景＋紅印，用白底才看得清楚（深色底會看不出來） */
.seal-shot{height:104px;display:flex;align-items:center;justify-content:center;background:#fff;
  border:1px dashed var(--line);border-radius:8px;margin-bottom:8px;overflow:hidden}
.seal-shot img{max-height:92px;max-width:92%;object-fit:contain}
.seal-shot .none{font-size:12px;color:var(--text-2)}
.seal-meta{font-size:11.5px;color:var(--text-2);margin-top:6px}
.seal-card .row{gap:8px}
@media(max-width:640px){.seal-grid{grid-template-columns:1fr}}

/* ===== 合約附件（門市勾選區 + 客戶端預覽） ===== */
/* 門市：匯出合約彈窗裡的附件清單 */
.at-list{margin:2px 0 0}
.at-item{display:flex;align-items:center;gap:8px 10px;flex-wrap:wrap;
  padding:7px 10px;border:1px solid var(--line);border-radius:8px;background:var(--panel-2,#fafbfc);margin-bottom:6px}
.at-item label.chk{flex:1 1 auto;min-width:160px;margin:0}
.at-item .btn.sm{padding:3px 9px;font-size:12px}
.c-danger{color:var(--danger)}

/* ===== 工程變更確認單：逐筆變更項目 =====
   說明要能吃掉剩下的寬度（項目名稱常常很長），金額與方向固定寬度，
   手機上整列才不會被擠成兩行又對不齊。 */
.chg-it{display:flex;align-items:center;gap:6px 8px;flex-wrap:wrap;margin-bottom:6px}
.chg-it input[data-f="desc"]{flex:1 1 220px;min-width:0}
.chg-it select{flex:0 0 auto;width:88px}
.chg-it input[data-f="amount"]{flex:0 0 auto;width:120px;text-align:right}
.chg-it .btn.sm{padding:3px 9px;font-size:12px}
@media(max-width:640px){
  .chg-it input[data-f="desc"]{flex:1 1 100%}
  .chg-it select,.chg-it input[data-f="amount"]{flex:1 1 0;min-width:0}
}

/* ===== 工資核發：薪資項目一列一項（名稱＋比率／金額） =====
   跟變更項目同一個規矩：名稱吃掉剩下的寬度，金額固定寬度且靠右，
   手機上才不會被擠成兩行又對不齊。 */
.pr-it{display:flex;align-items:center;gap:6px 8px;flex-wrap:wrap;margin-bottom:6px}
.pr-it .pr-t{flex:1 1 130px;min-width:0;font-size:13px}
.pr-it input[type="number"]{width:120px;flex:none;text-align:right}
.pr-it input[readonly]{background:var(--panel-2,#fafbfc);color:var(--muted,#6b7a74)}
.pr-it .btn.sm{padding:3px 9px;font-size:12px}
.pr-it>input:not([type="number"]){flex:1 1 140px;min-width:0}
@media(max-width:640px){
  .pr-it .pr-t,.pr-it>input:not([type="number"]){flex:1 1 100%}
  .pr-it input[type="number"]{flex:1 1 0;min-width:0}
}

/* ===== 匯入報價單：建檔前的對照列（標籤左／值右） =====
   刻意做成通用的一行一欄，彈窗與卡片都能用；
   標籤固定最小寬度，兩張對照表疊在一起時數字才會對齊。 */
.kv-row{display:flex;align-items:baseline;gap:10px;padding:4px 0;
  font-size:13px;border-bottom:1px dashed var(--line-2)}
.kv-row:last-child{border-bottom:0}
.kv-row>span{color:var(--text-2);min-width:96px}
.kv-row>b{margin-left:auto;text-align:right;color:var(--text)}
.kv-row>em{color:var(--danger);font-style:normal;margin-left:auto;font-weight:600}

/* 客戶端：附件區（點開才抓那一頁的圖） */
.sign-att{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:14px 18px;margin-bottom:14px;box-shadow:var(--shadow)}
.sign-att h3{margin:0 0 4px;font-size:15px}
.att-grp{margin-top:10px}
.att-title{font-size:12.5px;font-weight:700;color:var(--brand);margin-bottom:6px;word-break:break-all}
.att-grid{display:flex;flex-wrap:wrap;gap:8px}
.att-card{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;
  width:104px;height:74px;border:1px solid var(--line);border-radius:8px;background:#fbfcfc;
  cursor:pointer;color:var(--text-2);padding:0}
.att-card:hover{border-color:var(--brand);background:var(--brand-soft);color:var(--brand)}
.att-pg{font-size:12.5px;font-weight:700}
.att-go{font-size:11px;color:var(--text-3)}
.att-card:hover .att-go{color:var(--brand)}
/* 附件燈箱 */
.att-lb{position:fixed;inset:0;z-index:120;background:rgba(12,18,24,.72);display:flex;align-items:center;justify-content:center;padding:14px}
.att-lb-in{background:var(--panel);border-radius:12px;max-width:min(1100px,96vw);width:100%;max-height:94dvh;display:flex;flex-direction:column;overflow:hidden}
.att-lb-bar{display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:9px 12px;border-bottom:1px solid var(--line);font-size:13px;color:var(--text-2)}
.att-lb-bar .btn.sm{padding:4px 10px;font-size:12.5px}
.att-lb-img{overflow:auto;padding:12px;text-align:center;background:#f7f9fa}
.att-lb-img img{max-width:100%;height:auto;display:block;margin:0 auto;border:1px solid var(--line);border-radius:6px}

/* 狀態徽章 */
.badge{display:inline-block;padding:2px 9px;border-radius:20px;font-size:11.5px;font-weight:700;white-space:nowrap}
.badge.waitA{background:var(--warn-soft);color:var(--warn);border:1px solid #f0dcb8}
.badge.waitB{background:#eef4fb;color:#2c5c96;border:1px solid #d3e0f0}
.badge.done{background:var(--brand-soft);color:var(--brand);border:1px solid #cfe4dd}
.badge.void{background:var(--line-2);color:var(--text-3);border:1px solid var(--line)}
td.ops{white-space:normal}
td.ops .btn{margin:0 4px 4px 0}

@media print{
  .sign-page{padding:0;min-height:0}
  .sign-form,.sign-hash,.sign-preview,.sign-att{display:none}
  .sign-doc{border:0;box-shadow:none;padding:0}
}

/* ===== 員工管理：逐人權限勾選 ===== */
.perm-wrap{margin-top:10px;border:1px solid var(--line);border-radius:var(--radius);background:var(--panel-2,#fafbfc);padding:10px 12px;max-height:340px;overflow:auto}
.perm-grp+.perm-grp{margin-top:12px;padding-top:10px;border-top:1px dashed var(--line)}
.perm-t{font-size:12.5px;font-weight:700;color:var(--brand);letter-spacing:.5px;margin-bottom:6px}
.perm-box{gap:6px 12px}
.perm-box label.chk{align-items:flex-start;padding:3px 4px;border-radius:6px;line-height:1.35}
.perm-box label.chk:hover{background:var(--line-2)}
.perm-box label.chk input{margin-top:2px}
.perm-box label.chk.ov{background:var(--brand-soft);border:1px solid #cfe4dd}
.ov-tag{font-size:10.5px;font-weight:700;color:var(--brand);margin-left:4px;padding:0 4px;border-radius:8px;background:var(--panel)}

/* ---------- 智能匯入：兩地價格同時輸入 ---------- */
.ai-fx{margin-top:10px;padding:9px 11px;border:1px solid var(--line);border-left:3px solid var(--brand);
  border-radius:8px;background:var(--brand-soft);font-size:12.5px;line-height:1.6}
.ai-fx input,.ai-fx select{padding:3px 6px;font-size:12.5px}
table.ai-tb{width:100%;border-collapse:collapse}
table.ai-tb th,table.ai-tb td{padding:4px 5px;border-bottom:1px solid var(--line-2);text-align:left;white-space:nowrap}
table.ai-tb th{font-size:11.5px;color:var(--text-3);font-weight:600;background:#fafbfc}
table.ai-tb input[type=number]{text-align:right;font-variant-numeric:tabular-nums}
table.ai-tb td.r,table.ai-tb th.r{text-align:right;font-variant-numeric:tabular-nums}

/* ---------- 系統設定：匯入資料庫（拖檔案） ---------- */
.drop-zone{margin-top:4px;padding:18px 14px;border:2px dashed var(--line);border-radius:10px;
  background:var(--panel-2,#fafbfc);text-align:center;line-height:2;transition:.15s}
.drop-zone:hover{border-color:var(--brand);background:var(--brand-soft)}
.drop-zone.over{border-color:var(--brand);background:var(--brand-soft);border-style:solid}
.drop-zone .btn{margin:0 0 0 8px}
.drop-zone .tiny{display:inline;margin:0 4px}
#impInfo:not(:empty){margin-top:10px;padding:9px 11px;border:1px solid var(--line);border-radius:8px;
  background:var(--panel-2,#fafbfc);line-height:1.7}
#impInfo table{margin-top:6px}

/* ---------- 合約範本：上傳自己的文本 ＋ 對照確認 ---------- */
/* 操作欄的按鈕不要被擠到換行（一列有 4 顆） */
.tpl-act{white-space:nowrap}
.tpl-act .btn{margin:0 4px 4px 0}
/* 套版後被填進去的欄位（{{員工姓名}}）—— 一眼看出「哪裡被系統動過」 */
.tpl-k{color:var(--brand);font-weight:700;background:var(--brand-soft);border-radius:3px;padding:0 2px}
/* 對照表：左邊原文灰、右邊結果深色，掃一眼就知道差在哪 */
table.tpl-map td{vertical-align:top}
.tpl-map .tpl-o{color:var(--text-3);font-size:12px;line-height:1.7;word-break:break-all}
.tpl-map .tpl-r{font-size:12.5px;line-height:1.7;word-break:break-all}
.tpl-map td .chk{margin-bottom:3px}

/* ---------- 產品挑選器：目錄可摺疊 + 關鍵字查找 ---------- */
.pk-wrap{display:inline-flex;align-items:center;gap:5px;vertical-align:middle;max-width:100%}
.pk-btn{display:inline-flex;align-items:center;gap:6px;max-width:150px;padding:5px 8px;
  border:1px solid var(--line);background:#fff;color:var(--text);border-radius:7px;cursor:pointer;text-align:left}
.pk-btn:hover{border-color:var(--brand-2);background:var(--brand-soft)}
.pk-btn:disabled,.pk-btn.dis{background:#f7f9fa;color:var(--text-3);cursor:not-allowed;border-color:var(--line)}
.pk-btn .pk-tx{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:12.5px}
.pk-btn .pk-tx.ph{color:var(--text-3)}
.pk-btn .pk-ar{color:var(--text-3);font-size:10px;flex:none}
.pk-wrap.narrow .pk-btn{max-width:96px;padding:5px 6px}
.pk-wrap.narrow .pk-btn .pk-tx{font-size:12px}
/* 配置包編輯器：一行一項材料，按鈕要夠寬才看得清品名（原本是原生 <select>） */
.pk-wrap.wide{flex:1;min-width:240px}
.pk-wrap.wide .pk-btn{max-width:100%;width:100%;min-width:240px}
.pkg-item{align-items:center}
.pk-thumb img{width:34px;height:34px;object-fit:contain;border:1px solid var(--line-2);
  border-radius:5px;background:#fff;cursor:zoom-in}
.pk-pop{position:fixed;z-index:4000;width:360px;max-width:calc(100vw - 16px);display:flex;flex-direction:column;
  background:var(--panel);border:1px solid var(--line);border-radius:10px;overflow:hidden;
  box-shadow:0 10px 30px rgba(20,30,40,.18)}
.pk-top{display:flex;gap:6px;padding:8px;border-bottom:1px solid var(--line-2)}
.pk-top .pk-q{flex:1;padding:6px 8px;font-size:13px;border:1px solid var(--line);border-radius:7px;background:#fff;color:var(--text)}
.pk-top .pk-foldall{padding:4px 8px;border:1px solid var(--line);background:#fff;border-radius:7px;cursor:pointer;color:var(--text-2)}
.pk-cnt{padding:4px 12px 2px;color:var(--text-3);font-size:11.5px}
.pk-tree{flex:1;overflow:auto;padding:2px 0 6px}
.pk-node{display:flex;align-items:center;gap:6px;padding:5px 10px;cursor:pointer;font-size:13px;font-weight:600;color:var(--text)}
.pk-node:hover{background:var(--brand-soft)}
.pk-node .pk-tw{width:12px;flex:none;color:var(--text-3);font-size:10px}
.pk-node .pk-nm{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pk-node .pk-n{font-size:11px;color:var(--text-3);font-weight:400}
.pk-item{display:flex;align-items:center;gap:7px;padding:4px 10px 4px 0;cursor:pointer;font-size:12.5px;line-height:1.35}
.pk-item:hover{background:var(--line-2)}
.pk-item.on{background:var(--brand-soft)}
.pk-item.cur{outline:2px solid var(--brand-2);outline-offset:-2px}
.pk-item .pk-th{width:28px;height:28px;flex:none;object-fit:contain;border:1px solid var(--line-2);border-radius:4px;background:#fff;cursor:zoom-in}
.pk-item .pk-th.none{visibility:hidden}
.pk-item .pk-inm{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pk-item .pk-ip{display:block;font-style:normal;font-size:11px;color:var(--text-3);font-weight:400}
.pk-empty{padding:24px 14px;text-align:center;color:var(--text-3)}
.pk-ft{padding:6px 8px;border-top:1px solid var(--line-2)}
.pk-new{width:100%;text-align:left;padding:6px 8px;border:1px dashed var(--line);background:#fff;
  border-radius:7px;color:var(--brand);cursor:pointer;font-size:12.5px}
.pk-new:hover{border-color:var(--brand);background:var(--brand-soft)}
.pk-clr{padding:6px 12px;border-top:1px solid var(--line-2);font-size:12px;color:var(--danger);cursor:pointer}
.pk-clr:hover{background:var(--danger-soft)}

/* ---------- 報價明細：有圖產品直接帶出縮圖 ---------- */
.row-thumb{margin-top:4px}
.row-thumb img{width:52px;height:52px;object-fit:contain;border:1px solid var(--line-2);border-radius:5px;
  background:#fff;cursor:zoom-in}
.row-thumb img:hover{border-color:var(--brand)}

/* ---------- 圖片燈箱 ----------
   z-index 必須高於挑選器浮層（.pk-pop 4000），否則從清單點縮圖放大時圖會被清單蓋住。 */
.lb-mask{position:fixed;inset:0;z-index:4600;background:rgba(12,18,24,.72);
  display:flex;align-items:center;justify-content:center;padding:22px}
.lb-box{background:#fff;border-radius:12px;max-width:min(880px,96vw);max-height:94vh;
  display:flex;flex-direction:column;overflow:hidden;box-shadow:0 24px 60px rgba(0,0,0,.45)}
.lb-h{display:flex;align-items:center;gap:10px;padding:11px 15px;border-bottom:1px solid var(--line-2);font-size:14px}
.lb-h b{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lb-h .lb-x{cursor:pointer;color:var(--text-3);font-size:16px;line-height:1;flex:none}
.lb-h .lb-x:hover{color:var(--text)}
.lb-b{padding:12px;background:#fbfcfc;overflow:auto;text-align:center}
.lb-b img{max-width:100%;max-height:62vh;border-radius:8px;display:block;margin:0 auto}
.lb-f{display:flex;gap:10px;align-items:baseline;flex-wrap:wrap;padding:9px 15px;
  border-top:1px solid var(--line-2);color:var(--text-2)}
.lb-f .lb-tip{margin-left:auto;color:var(--text-3);flex:none}

/* ---------- 批量換材料：勾選空間 ---------- */
.bc-scope{margin-bottom:10px;padding:9px 11px;border:1px solid var(--line);border-left:3px solid var(--brand);
  border-radius:8px;background:var(--brand-soft)}
.bc-spaces{display:flex;flex-wrap:wrap;gap:6px;margin:6px 0 2px}
.bc-sp{display:inline-flex;align-items:center;gap:5px;padding:3px 8px;background:#fff;
  border:1px solid var(--line);border-radius:20px;cursor:pointer;font-size:12.5px}
.bc-sp.on{border-color:var(--brand);background:#fff;color:var(--text);font-weight:600}
.bc-sp:not(.on){color:var(--text-3)}
.bc-sp input{margin:0}
.bc-sp .tiny{color:var(--text-3);font-weight:400}

/* ============================================================
   手機版（≤900px）：側欄改抽屜、表格可橫捲、觸控目標放大
   ============================================================ */
/* 漢堡鈕只有手機看得到 */
.nav-btn{display:none;align-items:center;justify-content:center;width:36px;height:36px;flex:none;
  padding:0;font-size:17px;line-height:1;border:1px solid var(--line);background:#fff;border-radius:8px;cursor:pointer;color:var(--text)}
.nav-scrim{display:none}

@media (max-width:900px){
  .shell{display:block}
  /* 側欄 → 抽屜 */
  .sidebar{
    position:fixed;top:0;left:0;bottom:0;width:78vw;max-width:300px;height:100dvh;z-index:120;
    transform:translateX(-104%);transition:transform .22s ease;box-shadow:2px 0 20px rgba(10,20,16,.28);
    padding-top:env(safe-area-inset-top,0px);
  }
  body.nav-open .sidebar{transform:none}
  .nav-scrim{position:fixed;inset:0;z-index:110;background:rgba(12,20,16,.45)}
  body.nav-open .nav-scrim{display:block}
  .sidebar a.nav{padding:11px 18px;font-size:14.5px}
  .nav-btn{display:inline-flex}

  /* 頂列：手機只留標題、語系、登出 */
  .topbar{height:auto;min-height:52px;padding:0 10px;gap:8px;padding-top:env(safe-area-inset-top,0px)}
  .topbar h1{font-size:15px;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .topbar .spacer{display:none}
  .topbar .who{display:none}
  .topbar .seg button{padding:6px 10px;font-size:13px}
  .content{padding:12px;overflow-x:auto}
  .card-b{padding:12px}
  .card-h{padding:10px 12px}
  .card-h h2{font-size:14px}

  /* 觸控目標放大；輸入字級 ≥16px 才不會被 iOS 自動放大畫面 */
  input,select,textarea{font-size:16px;padding:9px 10px}
  .lines input,.lines select,.ai-fx input,.ai-fx select,.pk-top .pk-q{font-size:16px;padding:6px 8px}
  .btn{padding:9px 14px;font-size:14px;min-height:38px}
  .btn.sm{padding:6px 10px;font-size:13px;min-height:32px}
  .btn.tiny{padding:3px 8px;font-size:12px;min-height:28px}
  .seg button{padding:6px 11px}
  .filters input,.filters select{width:100%;min-width:0}
  .filters{gap:6px}
  .filters .btn{width:100%}

  /* 表格：包一層可橫捲容器（u.wrapTables 自動加 .tbw） */
  .tbw{overflow-x:auto;-webkit-overflow-scrolling:touch;margin-bottom:2px;max-width:100%}
  .tbw table{min-width:max-content}
  th,td{padding:7px 8px}
  /* 關鍵：grid／flex 子項預設 min-width:auto，會被裡面的寬表格撐開，
     整個卡片跟著超過畫面寬度（實測 390 → 513），內容就被切掉。
     一律歸零，讓表格在自己那層橫捲，不外擴。 */
  .grid > *, .kpi > *, .row > *{min-width:0}
  .page, .content > *{min-width:0}
  /* 產品庫是 flex 版面（.pm 用 align-items:flex-start），直向排列時子項寬度會
     變成 max-content 而被寬表格撐到 3798px；改成 stretch 讓它跟容器同寬。 */
  .pm{align-items:stretch}
  .pm, .pm-main, .pm-tree, .pm-bar, .qbar, .space-h, .card-h{min-width:0}
  /* 表格可以橫捲時給右緣一點陰影，暗示「右邊還有」 */
  .tbw.more{box-shadow:inset -10px 0 10px -10px rgba(20,30,40,.28)}

  /* 彈窗 → 底部半版，拇指好按 */
  .modal-mask{padding:0;align-items:flex-end;justify-content:center}
  .modal{max-width:100%;border-radius:16px 16px 0 0;max-height:94dvh;
    animation:m-in .18s ease}
  .modal-b{padding:14px;max-height:calc(94dvh - 116px)}
  .modal-h{padding:12px 15px}
  .modal-f{padding:10px 14px;padding-bottom:calc(10px + env(safe-area-inset-bottom,0px))}
  .modal-f .btn{flex:1}
  @keyframes m-in{from{transform:translateY(14px);opacity:.6}to{transform:none;opacity:1}}

  /* 挑選器浮層 → 底部全寬 */
  .pk-pop{
    position:fixed !important;left:0 !important;right:0 !important;bottom:0 !important;top:auto !important;
    width:100% !important;max-width:100% !important;max-height:76dvh !important;border-radius:14px 14px 0 0;
    box-shadow:0 -10px 30px rgba(20,30,40,.22);
  }
  .pk-tree{max-height:56dvh}
  .pk-item{padding:8px 12px 8px 0}
  .pk-node{padding:8px 12px}
  .pk-wrap.wide{min-width:0}
  .pk-wrap.wide .pk-btn{min-width:0}

  /* 產品庫：目錄樹不要吃掉整屏 */
  .pm-tree{max-height:38vh;padding:8px 6px 10px}
  .pm-main{padding:8px 10px 12px}
  .pm-bar{flex-wrap:wrap;gap:6px}

  /* 報價編輯 */
  .qbar{top:52px;padding:8px 10px;gap:8px}
  .qbar .sep{display:none}
  .space-h{padding:8px 10px;flex-wrap:wrap}
  .lines table{min-width:970px}
  /* 手指頭要點得到：上移／下移與拖曳握把手機一律放大到 38px 觸控底線 */
  .btn.tiny.mv{min-width:38px;min-height:38px;font-size:15px}
  .drag-h,.space-h .drag-h{width:38px;height:38px;font-size:17px}
  .dh-cell{width:44px}
  .totals{justify-content:stretch;padding:12px}
  .totals table{width:100%}
  .meas{width:100%;margin-top:12px}
  .lockbar{flex-wrap:wrap}

  /* 提示條與燈箱 */
  #toast-root{left:10px;right:10px;bottom:calc(10px + env(safe-area-inset-bottom,0px))}
  .toast{max-width:none}
  .lb-mask{padding:10px}
  .lb-b img{max-height:56dvh}
  .lb-f{font-size:12.5px}

  .perm-wrap{max-height:none}
  .perm-box{grid-template-columns:1fr}
  .dz{padding:14px 10px}
  .login-card{padding:22px 18px}
  .kpi .box{padding:12px}
  .kpi .box .n{font-size:21px}
}

@media (max-width:420px){
  .topbar h1{font-size:14px}
  .content{padding:10px}
  .card-b{padding:10px}
  .kpi{gap:8px}
  .btn{padding:8px 12px;font-size:13.5px}
  .sidebar{width:86vw}
}

/* ---------- 雲端同步（core/cloudsync.js） ---------- */
#syncNow{display:inline-block}
#syncNow.sync-ok{color:#4f6b5e}
#syncNow.sync-warn{color:#b8860b;font-weight:600}
#syncNow.sync-bad{color:var(--danger,#c0392b);font-weight:600}
.syncbox{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.syncbox .st{font-size:13px}
.syncbox .st b{font-size:14px}
.syncbox .dot{width:8px;height:8px;border-radius:50%;background:#4f6b5e;flex:0 0 auto}
.syncbox .dot.warn{background:#b8860b}
.syncbox .dot.bad{background:var(--danger,#c0392b)}
.syncbox .meta{font-size:12px;color:var(--text-2,#6b7a72)}

/* ============================================================
   訂單管理與財務（v10 門店管理系統）
   ============================================================ */

/* 金額遮罩：沒有「看訂單金額」權限的人看到的是這個。
   刻意做成等寬的點點，讓一排數字對齊時看不出長度（長度也是資訊）。 */
.mmask{display:inline-block;letter-spacing:1px;color:var(--text-3);font-weight:600}
.mmask::after{content:'🔒';font-size:10px;margin-left:3px;opacity:.65}

/* 進度條：七個節點，走過的填色 */
.stgbar{height:6px;background:#e9edf1;border-radius:4px;overflow:hidden;margin:2px 0 7px}
.stgfill{height:100%;background:var(--brand);border-radius:4px;transition:width .25s}
.stgs{display:flex;flex-wrap:wrap;align-items:center;gap:3px;font-size:11.5px;color:var(--text-3)}
.stgs .stg{padding:1px 6px;border-radius:20px;background:#f1f3f5;border:1px solid transparent}
.stgs .stg.on{background:var(--brand-soft);color:var(--brand);border-color:#cfe5dc;font-weight:600}
.stgs .stgar{color:#c3ccd2}

/* 進度節點操作（一列按鈕，已完成的反白） */
.stgbtns{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}
.stgbtns .btn{min-width:auto}
.stgbtns .btn.on{background:var(--brand);color:#fff;border-color:var(--brand)}

/* 摘要數字卡（合約／已收／未收／毛利） */
.sum{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:10px}
.sum .box{border:1px solid var(--line);border-radius:9px;padding:10px 12px;background:#fbfcfc}
.sum .box .k{font-size:11.5px;color:var(--text-2)}
.sum .box .v{font-size:19px;font-weight:700;margin-top:2px;letter-spacing:-.2px}
.sum .box .v.ok{color:var(--ok)}
.sum .box .v.warn{color:var(--warn)}
.sum .box .v.danger{color:var(--danger)}
.sum .box .s{font-size:11.5px;color:var(--text-3);margin-top:1px}

/* 留言板 */
.note{border:1px solid var(--line);border-radius:9px;padding:9px 11px;background:#fff;margin-bottom:8px}
.note .nh{display:flex;align-items:center;gap:7px;flex-wrap:wrap;font-size:12px;color:var(--text-2)}
.note .nh b{color:var(--text);font-size:13px}
.note .nb{font-size:13.5px;line-height:1.7;white-space:pre-wrap;margin-top:4px;word-break:break-word}
.note .nb .at{color:var(--brand);font-weight:600}
.note .nf{display:flex;flex-wrap:wrap;gap:6px;margin-top:6px}
.note .nx{margin-left:auto;color:var(--text-3);font-size:12px;cursor:pointer}
.note .nx:hover{color:var(--danger)}

/* 檔案／照片區 */
.fgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(112px,1fr));gap:10px}
.fcard{border:1px solid var(--line);border-radius:9px;overflow:hidden;background:#fff;position:relative}
.fcard .fp{height:88px;background:#f6f8f9;display:flex;align-items:center;justify-content:center;
  cursor:zoom-in;overflow:hidden}
.fcard .fp img{width:100%;height:100%;object-fit:cover}
.fcard .fp .ext{font-size:22px;color:var(--text-3);font-weight:700}
.fcard .fn{font-size:11.5px;padding:5px 7px;line-height:1.35;word-break:break-all;color:var(--text-2)}
.fcard .fx{position:absolute;top:3px;right:3px;background:rgba(255,255,255,.9);border:1px solid var(--line-2);
  border-radius:50%;width:20px;height:20px;line-height:18px;text-align:center;cursor:pointer;font-size:12px;color:var(--text-3)}
.fcard .fx:hover{color:var(--danger);border-color:var(--danger)}
.fcard .loc{position:absolute;bottom:3px;left:3px;background:rgba(20,30,40,.66);color:#fff;
  border-radius:4px;font-size:10px;padding:1px 4px}

/* 付款截圖縮圖 */
.shots{display:flex;flex-wrap:wrap;gap:6px;margin-top:6px}
.shots img{width:64px;height:64px;object-fit:cover;border:1px solid var(--line-2);border-radius:6px;cursor:zoom-in}
.shots img:hover{border-color:var(--brand)}

/* 上傳區（拖曳／點選） */
.upbox{border:1.5px dashed var(--line);border-radius:9px;padding:14px;text-align:center;
  color:var(--text-2);font-size:13px;background:#fbfcfc;cursor:pointer}
.upbox:hover{border-color:var(--brand);background:var(--brand-soft)}
.upbox.busy{opacity:.6;cursor:wait}

@media (max-width:900px){
  .sum{grid-template-columns:repeat(2,1fr)}
  .fgrid{grid-template-columns:repeat(auto-fill,minmax(94px,1fr))}
}
@media (max-width:420px){
  .sum{grid-template-columns:1fr}
}

/* 產品庫分批顯示的「再載入」區塊 */
.pm-more{margin-top:10px;padding:10px 12px;border-top:1px dashed var(--line,#d8d8d8);text-align:center}

/* ===== 客戶快速錄入：一顆一顆點的選項（2026-10-09 新增） =====
   為什麼不用 <select>：接待是一邊問客戶一邊點，選項要「一眼看全部、一下就點到」，
   下拉還得多按一次、而且看不到其他選項。手機上圓鈕也比下拉好按。
   .opt 是 <button>，選中加 .on（跟 .seg button.on 同一個綠）。 */
.optblk{margin-bottom:10px}
.optblk > .olb{display:block;font-size:12.5px;color:var(--text-2);margin-bottom:5px}
.optblk > .olb .tiny{font-weight:400}
.opts{display:flex;flex-wrap:wrap;gap:6px}
.opt{border:1px solid var(--line);background:#fff;border-radius:15px;padding:5px 12px;
  font-size:12.5px;line-height:1.35;color:var(--text-2);cursor:pointer;font-family:inherit}
.opt:hover{border-color:var(--brand);color:var(--brand)}
.opt.on{background:var(--brand);border-color:var(--brand);color:#fff;font-weight:600}
.opt:active{transform:translateY(1px)}
.opts .opt-add{border-style:dashed;color:var(--text-3)}
.opts .opt-add:hover{color:var(--brand)}
/* 案件概況：一組一組的標籤 */
.pf-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:8px 14px}
.pf-row{font-size:13px;line-height:1.6}
.pf-row .k{display:block;font-size:11.5px;color:var(--text-3);letter-spacing:.02em}
.pf-row .v{color:var(--text)}
.pf-row .v.muted{color:var(--text-3)}
/* 客戶資料選項維護：每一組一張小卡 */
.copt{border:1px solid var(--line);border-radius:9px;padding:9px 11px;margin-bottom:8px;background:#fff}
.copt .ch{display:flex;align-items:center;gap:8px;font-size:13px;font-weight:600;margin-bottom:6px}
.copt .ch .tiny{font-weight:400}
.copt .ci{display:flex;align-items:center;gap:6px;padding:3px 0;border-top:1px dashed var(--line-2)}
.copt .ci:first-of-type{border-top:0}
.copt .ci input[type=text]{flex:1;min-width:0;padding:3px 7px;font-size:12.5px;border:1px solid var(--line);border-radius:6px}
.copt .ci .tn{width:88px;padding:2px 4px;font-size:12px;border:1px solid var(--line);border-radius:6px;background:#fff}
.copt .ci .mv{display:inline-flex;gap:2px}
.copt .ci .mv button{border:1px solid var(--line);background:#fff;border-radius:5px;
  width:22px;height:22px;line-height:1;cursor:pointer;color:var(--text-2);font-size:11px;padding:0}
.copt .ci .mv button:hover{border-color:var(--brand);color:var(--brand)}
.copt .ci .rm{border:0;background:none;color:var(--text-3);cursor:pointer;font-size:13px;padding:0 3px}
.copt .ci .rm:hover{color:var(--danger)}
@media (max-width:640px){
  .opt{padding:7px 13px;font-size:13.5px}          /* 手機上要更好按 */
  .pf-grid{grid-template-columns:1fr}
}

/* ---------- 人事證件／自訂 Word（2026-10-09 新增） ----------
   「證件」視窗裡一項一列：左邊是名稱與狀態，右邊是動作。
   手機上（≤640px）改成上下排，不然四顆按鈕會擠成一團。 */
.cert-list{border:1px solid var(--line);border-radius:9px;overflow:hidden;background:#fff}
.cert-row{display:flex;align-items:center;gap:10px;padding:8px 11px;border-top:1px solid var(--line-2);flex-wrap:wrap}
.cert-row:first-child{border-top:0}
.cert-row .ch{display:flex;align-items:center;gap:7px;flex:1;min-width:180px;font-size:13.5px}
.cert-row .cb{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.ce-sep{height:0;border-top:1px dashed var(--line);margin:12px 0}
/* 證件要求維護：每一項一列（比照客戶資料選項那張卡的 .copt .ci） */
.copt .ci .rq{display:inline-flex;align-items:center;gap:4px;font-size:12px;color:var(--text-2);white-space:nowrap}
@media (max-width:640px){
  .cert-row{align-items:flex-start;flex-direction:column;gap:6px}
  .cert-row .ch{min-width:0}
}

/* ---------- 員工簽署頁：上傳證件（2026-10-09 新增） ----------
   手機為主：一項一張卡、按鈕夠大好按（44px 上下），
   並沿用 .sign-att / .sign-doc 的紙張感，不要長得像另一個系統。 */
.sign-cert{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);
  padding:14px 18px;margin-bottom:14px;box-shadow:var(--shadow)}
.sign-cert h3{margin:0 0 4px;font-size:15px}
.sign-card{border:1px solid var(--line-2);border-radius:10px;padding:9px 11px;margin-top:9px;background:#fff}
.sign-card .sc-h{display:flex;align-items:center;gap:7px;flex-wrap:wrap;font-size:13.5px}
.sign-card .sc-h b{font-weight:600}
.sc-req,.sc-opt,.sc-ok,.sc-no{font-size:11px;padding:1px 6px;border-radius:20px;line-height:1.6;flex:none}
.sc-req{background:#fdecec;color:#b5342f}
.sc-opt{background:#f2f4f5;color:var(--text-3)}
.sc-ok{background:#e8f5ee;color:#1d7a4d}
.sc-no{background:#fff4e5;color:#a3611a}
.sign-word .btn.sm{padding:7px 13px}
@media (max-width:640px){
  .sign-cert{border:0;box-shadow:none;padding:0;margin-bottom:12px}
  .sign-card .btn.sm{padding:9px 14px;font-size:13.5px}
}

/* ---------- 客戶預約排版表（2026-10-13 聖輝指定） ----------
   按月一頁的月曆。三個設計重點都不在美觀，在判讀：

   ① **格子一定要一樣高**：不然「哪個禮拜比較滿」只能靠數格子上的卡片，
      眼睛其實讀不出來。用 min-height 讓每一格都留得住三張卡，
      空的日子也不會縮成一條線，翻頁時整張表不會上下跳。
   ② **撞車要看得見**：同一位負責人同一時段被排兩次 → 那一格紅框 + 上面的卡片紅字。
      這是這一頁存在的理由（LINE 群組裡口頭喬好的行程一定會撞），
      顏色要比其他任何狀態都顯眼。
   ③ **今天要一眼認出來**：開封面 Landing 到行事曆的人第一個要找的是「今天」，
      所以今天的日期數字加底色，不是加邊框（邊框會跟撞車的紅框打架）。 */
.ap-wrap{display:flex;flex-direction:column;gap:12px}
.ap-cal{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:1px;background:var(--line-2);
  border:1px solid var(--line);border-radius:var(--radius);overflow:hidden}
.ap-hd{background:var(--panel-2,#fafbfc);padding:6px 4px;text-align:center;font-size:12px;color:var(--text-2);
  font-weight:600;letter-spacing:.5px}
.ap-hd.wk{background:#f7f4ef;color:#8a5c1e}
.ap-cell{background:var(--panel);min-height:104px;padding:4px 4px 6px;position:relative;
  display:flex;flex-direction:column;gap:3px;cursor:pointer}
.ap-cell.out{background:#fafbfc}
.ap-cell.out .ap-dd{color:var(--text-3)}
.ap-cell.sel{box-shadow:inset 0 0 0 2px var(--brand-2)}
.ap-cell.clash{box-shadow:inset 0 0 0 2px var(--danger)}
.ap-dd{font-size:12.5px;font-weight:600;color:var(--text-2);line-height:1.4;padding:0 2px}
.ap-dd b{display:inline-block;min-width:20px;text-align:center;border-radius:20px;
  background:var(--brand);color:#fff;padding:0 5px;font-weight:700}
.ap-more{font-size:11px;color:var(--text-3);padding-left:3px}
.ap-ev{display:flex;align-items:flex-start;gap:4px;font-size:11.5px;line-height:1.35;
  border-radius:5px;padding:2px 4px;background:var(--line-2);color:var(--text);
  border-left:3px solid var(--text-3);overflow:hidden}
.ap-ev .t{font-variant-numeric:tabular-nums;flex:none;font-weight:600}
.ap-ev .n{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ap-ev.clash{border-left-color:var(--danger);background:var(--danger-soft)}
.ap-ev.done{opacity:.55}
.ap-ev.done .n{text-decoration:line-through}
.ap-ev.canceled{opacity:.45}
.ap-ev.canceled .n{text-decoration:line-through}
.ap-ev.drag{opacity:.4}
.ap-cell.over{background:var(--brand-soft)}

/* 當日時刻表：點月曆上任何一天，就在正下方攤開（★ 不跳頁、不開彈窗 ——
   開單開到一半跑去別頁，回來表單就白填了，這是踩過的坑） */
.ap-day{border:1px solid var(--line);border-radius:var(--radius);background:var(--panel)}
.ap-day-h{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:9px 12px;
  border-bottom:1px solid var(--line-2);background:var(--panel-2,#fafbfc)}
.ap-row{display:flex;align-items:flex-start;gap:10px;padding:9px 12px;border-bottom:1px solid var(--line-2)}
.ap-row:last-child{border-bottom:0}
.ap-row.clash{background:var(--danger-soft)}
.ap-when{width:92px;flex:none;font-variant-numeric:tabular-nums;font-weight:600;font-size:13.5px}
.ap-main{flex:1;min-width:0}
.ap-tags{display:flex;flex-wrap:wrap;gap:5px;margin-top:3px}
.ap-cust{font-size:13px}
.ap-meta{font-size:12px;color:var(--text-2);margin-top:2px;word-break:break-all}
.ap-act{display:flex;flex-direction:column;gap:4px;flex:none}

/* 類型圖例 */
.ap-lg{display:flex;flex-wrap:wrap;gap:6px}
.ap-lg span{font-size:11.5px;padding:2px 8px;border-radius:20px;color:#fff}

@media (max-width:900px){
  /* ★ 手機不能硬擠七欄：一格會窄到連「14:00」都放不下。
     每格只留日期數字與時間，客戶名先藏起來（留類型色條認人）；
     完整內容看下方攤開的當日時刻表（那裡才是真正讀跟操作的地方）。 */
  .ap-cell{min-height:74px;padding:3px 2px}
  .ap-ev{font-size:10.5px;padding:1px 3px}
  .ap-ev .n{display:none}
  .ap-row{flex-wrap:wrap}
  .ap-when{width:auto;min-width:74px}
  .ap-act{flex-direction:row;flex-wrap:wrap;width:100%}
}

/* ---------- 設計進度：表上直接改（2026-10-19 聖輝「這裏都沒有可以修改資料的地方」） ----------
   ★ 這幾格還沒碰之前是「透明無框」的，看起來像文字；滑過／聚焦才浮出邊框。
     目的是：一眼掃過去還是表格，但每一格都能直接改，不必先猜哪裡可以點。
   ★ 案名那一格留一條虛線底線：下拉選單本身有箭頭看得出來，純輸入框沒有，
     沒有底線就沒人知道「這一格可以打字」。 */
.ds-in{width:100%;min-width:0;padding:4px 6px;font-size:12.5px;border:1px solid transparent;
  background:transparent;border-radius:6px;color:inherit;font-family:inherit;
  text-overflow:ellipsis}
.ds-in:hover{border-color:var(--line);background:#fff}
.ds-in:focus{border-color:var(--brand-2);background:#fff;outline:2px solid var(--brand-soft)}
.ds-t{border-bottom:1px dashed #cfd6dd}
.ds-t:hover{border-bottom-color:transparent}
td.ds-c{vertical-align:middle}

/* 欄寬固定：不固定的話「五個階段的時間點」那條進度條會把其他欄全部吃掉，
   下拉被壓成兩三個字、天數折成兩行。 */
.ds-tb{table-layout:fixed;min-width:1290px}
.ds-tb td,.ds-tb th{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* 進度條那一格要放得下五格與折行的階段名，不能跟著 nowrap 被裁 */
.ds-tb td.ds-track{white-space:normal;overflow:visible;padding-left:8px;padding-right:8px}
/* 日期欄：Chrome 的 <input type=date> 內建寬度很大，不縮的話日曆圖示會被切掉 */
.ds-tb input[type="date"]{font-size:12px;padding-left:2px;padding-right:0}
.ds-tb input[type="date"]::-webkit-calendar-picker-indicator{margin:0;padding:0;opacity:.45}

/* 一排可點的數字（＝篩選）。點同一個就取消，不會被困在某一種篩選裡。 */
.ds-chips{display:flex;flex-wrap:wrap;gap:8px;margin:0 0 12px}
.ds-chip{display:inline-flex;align-items:center;gap:6px;padding:5px 12px;border-radius:20px;
  border:1px solid var(--line);background:var(--panel);font-size:12.5px;color:var(--text-2);
  cursor:pointer;user-select:none;transition:background .12s,border-color .12s}
.ds-chip:hover{background:#fafbfc;border-color:#c7cfd6}
.ds-chip b{font-variant-numeric:tabular-nums;color:var(--text);font-weight:600}
.ds-chip.on{border-color:var(--brand);background:var(--brand-soft);color:var(--brand);font-weight:600}
.ds-chip.on b{color:var(--brand)}
.ds-chip.danger.on{border-color:var(--danger);background:var(--danger-soft);color:var(--danger)}
.ds-chip.danger.on b{color:var(--danger)}
.ds-chip.warn.on{border-color:var(--warn);background:var(--warn-soft);color:var(--warn)}
.ds-chip.warn.on b{color:var(--warn)}
.ds-chip.ok.on{border-color:var(--ok);background:#e7f4ec;color:var(--ok)}
.ds-chip.ok.on b{color:var(--ok)}

/* ---------- 設計進度：三個頁籤（2026-10-31） ----------
   ★ 為什麼是頁籤而不是左側選單：三個頁籤看的是**同一批卡**，
     只是換角度（總表／為什麼卡住／誰做不完）。做成左側選單會被誤認成三種資料。
   ★ 樣式刻意跟 .ds-chip 同一家族（圓角、軟底），但少了「可點掉」的暗示 ——
     頁籤是按了會留在那一頁，不是篩選。 */
.ds-tabs{display:flex;gap:6px;margin:0 0 12px;border-bottom:1px solid var(--line);
  padding-bottom:0;flex-wrap:wrap}
.ds-tab{display:inline-flex;align-items:center;gap:6px;padding:8px 16px;font-size:13px;
  color:var(--text-2);cursor:pointer;user-select:none;border:1px solid transparent;
  border-bottom:2px solid transparent;border-radius:8px 8px 0 0;margin-bottom:-1px;
  transition:background .12s,color .12s}
.ds-tab:hover{background:#fafbfc;color:var(--text)}
.ds-tab b{font-variant-numeric:tabular-nums;font-weight:600;font-size:11.5px;
  background:#eef1f4;color:var(--text-2);border-radius:10px;padding:1px 7px}
.ds-tab.on{color:var(--brand);border-bottom-color:var(--brand);font-weight:600;background:#fff}
.ds-tab.on b{background:var(--brand-soft);color:var(--brand)}
.ds-tab.warn.on{color:var(--warn);border-bottom-color:var(--warn)}
.ds-tab.warn.on b{background:var(--warn-soft);color:var(--warn)}

/* 統計收在下面（<details>）：預設收起，點標題才展開 */
.ds-stats>summary{list-style:none;padding:12px 16px;display:flex;align-items:center;gap:8px}
.ds-stats>summary::-webkit-details-marker{display:none}
.ds-stats>summary:hover{background:#fafbfc}
.ds-stats .card-b.tight{border-radius:0 0 var(--radius) var(--radius)}

/* 窄螢幕：這張表欄位多，讓它自己橫捲（不要在手機上硬擠成一團字） */
@media (max-width:900px){
  .ds-tb{table-layout:auto;min-width:1290px}
  .ds-in{padding:6px 6px;font-size:13px}
}

/* ===== 驗收三態按鈕與列底色（2026-10-20 聖輝：點了要看得出點到哪） =====
   起因：程式本來就有 classList.toggle('on')，但全域並沒有 .btn.on 的樣式
   （只有 .stgbtns .btn.on，被限定在別的模組），所以點了畫面完全沒反應。 */
.acbtn.on{background:var(--ok);border-color:var(--ok);color:#fff;font-weight:600}
.acbtn.on:hover{background:var(--ok);border-color:var(--ok)}
.acbtn.on::before{content:"✓ "}
.acbtn.on.danger{background:var(--danger);border-color:var(--danger);color:#fff}
.acbtn.on.danger:hover{background:var(--danger);border-color:var(--danger)}
.acbtn.on.danger::before{content:"✕ "}
tr.acrow-ok>td{background:#f2faf5}
tr.acrow-ng>td{background:var(--danger-soft)}
tr.acrow-ok>td:first-child{box-shadow:inset 3px 0 0 var(--ok)}
tr.acrow-ng>td:first-child{box-shadow:inset 3px 0 0 var(--danger)}

/* 不適用（N/A）：灰底，讓「這項這一間沒有」一眼看得出來，且不計入進度 */
.acbtn.on.na{background:#8a94a0;border-color:#8a94a0;color:#fff;font-weight:600}
.acbtn.on.na:hover{background:#8a94a0;border-color:#8a94a0}
.acbtn.on.na::before{content:"— "}
tr.acrow-na>td{background:#f4f5f7}
tr.acrow-na>td:first-child{box-shadow:inset 3px 0 0 #8a94a0}

/* ============================================================================
   權限勾選（2026-10-29 SaaS 方案與權限）
   用在「開新戶」「公司詳細」「方案管理」三個彈窗。
   分組標題＋可自動換行的勾選項，窄螢幕會自己疊下來。
   ============================================================================ */
.featbox{border:1px solid var(--line-2);border-radius:8px;padding:10px 12px;background:#fafbfb}
.featg{margin-bottom:9px}
.featg:last-child{margin-bottom:0}
.featg-t{font-size:12px;color:var(--text-3);margin-bottom:5px;letter-spacing:.5px}
.featg-l{display:flex;flex-wrap:wrap;gap:7px 16px}
.fchk{display:inline-flex;align-items:center;gap:5px;font-size:13px;cursor:pointer;white-space:nowrap;user-select:none}
.fchk input{margin:0;cursor:pointer}
.fchk:hover span{color:var(--brand)}
@media(max-width:720px){
  .featg-l{gap:6px 12px}
  .fchk{font-size:13.5px}
}

/* ============================================================================
   設計系統 v2 · 全站美工改造（2026-10-29）
   ----------------------------------------------------------------------------
   為什麼整段加在檔案最後、而不是去改上面的規則：
     上面 1280 行裡有大量「踩過坑才寫出來」的功能性樣式（黏住的操作欄、A4 列印、
     拖曳握把、撞車紅框、金額遮罩…），直接改動風險高、也難回退。
     所以這裡只做「設計層」的覆蓋：字級階梯、間距、圓角、陰影、色階。
     ★ 位置必須在最後：同權重時「後面寫的」勝出，才蓋得掉舊值。
     ★ 桌面的字級／間距一律包在 @media(min-width:901px) 裡 —— 手機那段
       （≤900px：輸入 16px 防 iOS 自動縮放、按鈕 38px 觸控底線）在前面，
       不包起來會被這裡蓋掉，門市用手機操作就壞了。

   刻意「不動」的區域（動了會出事，改之前先問）：
     .pq / .ct-*   A4 報價單與合約本文，字級以紙本閱讀為準，不跟螢幕走
     .lines       報價明細，min-width:1110px 固定寬表，加寬只會更難用
     .ds-tb       設計進度，table-layout:fixed + nowrap，同理
     .ap-*        客戶預約月曆，格高與判讀規則是聖輝指定的
   ============================================================================ */

/* ---------- 1. 字級階梯（全域）----------
   只挑「手機那段沒有重設過」的選擇器，手機與桌面一起受惠。 */
body{font-size:var(--fs-body);line-height:1.6;
  -webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}
th{font-size:var(--fs-sm);font-weight:700;color:var(--text-2);letter-spacing:.02em}
.tiny{font-size:var(--fs-sm)}
.empty{font-size:14px}
.tag{font-size:var(--fs-xs);padding:2px 9px}
.badge{font-size:var(--fs-xs);padding:3px 10px}
.btn.sm{font-size:13.5px}
.btn.tiny{font-size:var(--fs-xs)}
.modal-h h3{font-size:17px}
.kpi .box .t{font-size:13.5px}
.sum .box .k{font-size:var(--fs-sm)}
.sum .box .s{font-size:var(--fs-xs)}
.optblk > .olb{font-size:13.5px}
.opt{font-size:13.5px}
.fchk{font-size:14px}
.ds-chip{font-size:13.5px}
.ct-row,.pk-node{font-size:14px}
.pk-item{font-size:13.5px}
.note .nh{font-size:13px}
.note .nh b{font-size:14px}
.note .nb{font-size:14.5px}
.logline{font-size:13.5px}
.att-title,.att-pg{font-size:13.5px}
.srctag{font-size:var(--fs-sm)}
.pack-t{font-size:var(--fs-sm)}
.qbar .kv{font-size:var(--fs-sm)}
.qbar .kv b{font-size:14px}
.stgs{font-size:var(--fs-xs)}

/* ---------- 2. 桌面：字級與間距（不進手機，保護觸控底線）---------- */
@media (min-width:901px){
  .sidebar{width:232px;flex:0 0 232px}
  .sidebar a.nav{font-size:14.5px;padding:9px 18px}
  .topbar{height:60px;padding:0 22px}
  .topbar h1{font-size:19px}
  .topbar .who{font-size:13.5px}
  .content{padding:22px}
  .card + .card{margin-top:16px}
  .card-h{padding:15px 20px}
  .card-b{padding:18px 20px}
  .card-h h2{font-size:17px}
  th,td{padding:11px 13px}
  .btn{font-size:var(--fs-body);padding:8px 15px;min-height:38px;border-radius:9px}
  .btn.sm{padding:5px 11px;min-height:32px}
  input,select,textarea{font-size:var(--fs-body);padding:8px 11px;border-radius:9px}
  .kpi .box{padding:18px 20px}
  .kpi .box .n{font-size:30px}
  .sum .box{padding:13px 15px}
  .sum .box .v{font-size:23px}
  .punch-btn b{font-size:19px}
  .punch-btn span{font-size:12.5px}
  .modal-h{padding:15px 20px}
  .modal-b{padding:18px 20px}
  .modal-f{padding:13px 20px}
  .seg button{padding:6px 13px;font-size:13.5px}
  /* ★ 報價單工具列黏在頂欄正下方：頂欄 54px → 60px，這裡一定要跟著改，
     不然兩條之間會露出一條 6px 的縫，往下捲時內容會從縫裡穿過去。 */
  .qbar{top:60px}
}

/* ---------- 3. 側欄：保留品牌深綠，做出層次 ---------- */
.sidebar{background:linear-gradient(180deg,#17291f,#13241c)}
.sidebar .brand{font-size:17px;padding:8px 18px 16px;letter-spacing:.8px}
.sidebar .brand small{font-size:12px;color:#85a797;margin-top:3px}
.nav-group{font-size:11.5px;color:#8fb3a3;letter-spacing:1.6px;padding:15px 18px 6px}
/* 右側圓角＋右留白：選中那一項看起來是一顆貼在左邊的膠囊，
   不再是一條貼滿整個側欄的色塊（選項多了才分得出哪一項被選到）。 */
.sidebar a.nav{border-radius:0 9px 9px 0;margin-right:10px}
.sidebar a.nav:hover{background:#1e3a2c;color:#e6f0ea}
.sidebar a.nav.on{background:#265441;color:#fff;font-weight:600}
.sidebar .foot{font-size:12px;color:#7f9b8d;padding:14px 18px;border-top:1px solid #22362c;line-height:1.7}

/* ---------- 4. 層級：卡片與表格 ---------- */
.card{border-color:var(--line);box-shadow:var(--shadow)}
.card-h{background:#fff;border-bottom:1px solid var(--line-2)}
/* 表頭改成實線分隔：原來跟資料行用同一條淡線，寬表往下捲時會分不出頭在哪 */
th{background:#f4f7f5;border-bottom:1px solid #dde5e0}
td{border-bottom:1px solid var(--line-2)}
tbody tr:hover{background:#f7faf8}
.topbar{box-shadow:0 1px 3px rgba(16,32,26,.06)}
.btn.primary{box-shadow:0 1px 2px rgba(31,95,77,.28)}

/* ---------- 5. 數字對齊（金額／統計，位數不同也要對得齊）---------- */
.kpi .box .n,.sum .box .v,.totals td,.ap-when{font-variant-numeric:tabular-nums}

/* ---------- 6. 鍵盤可見焦點（Tab 走得到哪裡要看得見）---------- */
.btn:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible,
.sidebar a.nav:focus-visible{outline:2px solid var(--brand-2);outline-offset:2px}

/* ---------- 7. 捲軸（只做精準指標裝置；觸控裝置本來就不顯示）---------- */
@media (pointer:fine){
  ::-webkit-scrollbar{width:10px;height:10px}
  ::-webkit-scrollbar-track{background:transparent}
  ::-webkit-scrollbar-thumb{background:#c6d2cb;border-radius:6px;
    border:2px solid transparent;background-clip:padding-box}
  ::-webkit-scrollbar-thumb:hover{background:#aab9b1}
}

/* ---------- 8. 手機同步放大（聖輝指示：桌面放大，手機也要跟上）----------
   上面的第 2 段刻意只做 ≥901px，就是為了不破壞手機原本的觸控底線；
   這裡再補一段把手機一起放大，等於「兩邊都放大、但各用各的安全值」。
   ★ 兩條絕對不能碰的線：
       · input/select/textarea 維持 16px —— 低於 16px，iOS 會在使用者點到輸入框時
         自動把整個畫面放大，表單就整個跑掉（這條在 863 行，這裡沒有重設它）。
       · .btn 的 min-height:38px／.btn.sm 32px／.btn.tiny 28px 維持 —— 手指頭的
         觸控底線，只放大字、不縮小按鈕。 */
@media (max-width:900px){
  .btn{font-size:15px}
  .btn.sm{font-size:14px}
  .btn.tiny{font-size:13px}
  th,td{padding:9px 10px}
  .card-b{padding:14px}
  .card-h{padding:12px 14px}
  .card-h h2{font-size:16px}
  .topbar h1{font-size:17px}
  .sidebar a.nav{font-size:15.5px;padding:12px 18px}
  .kpi .box .n{font-size:24px}
  .seg button{font-size:14px}
  .empty{font-size:14.5px}
  .punch-btn b{font-size:18px}
  .sum .box .v{font-size:21px}
}
/* 超窄螢幕（≤420px）再把字收回一點：同樣放大，但按鈕與卡片要用小一號的內距，
   不然 390px 寬的螢幕上一顆按鈕就吃掉半行、兩顆就換行。 */
@media (max-width:420px){
  .btn{font-size:14px}
  .btn.sm{font-size:13.5px}
  .card-b{padding:12px}
  .card-h{padding:11px 12px}
  .card-h h2{font-size:15.5px}
}

/* ---------- 9. 兩張固定寬表：只放大字，不動格寬 ----------
   .lines（報價明細）與 .ds-in（設計進度）是 min-width 1100px 以上的固定寬表，
   格子一放大整張表就更寬、手機橫向要捲更久。所以這裡只把「格子裡的字」放大
   1px（12.5→13.5），padding 一律不動 —— 文字變清楚了，寬度只增加一點點。
   ★ 桌面限定：手機那兩處維持 16px（輸入）與 13px（.ds-in），理由同第 8 段。 */
@media (min-width:901px){
  .lines input,.lines select{font-size:13.5px}
}
.ds-in{font-size:13.5px}
@media (max-width:900px){
  .ds-in{font-size:14px}
}

/* ---------- 預約頁：Google 地圖導航（2026-10-29 聖輝）----------
   「每次都要輸入客戶地址」→ 每一筆預約的地址後面直接給一個導航鈕，
   整天的行程再多一個「今日路線」。
   ★ .tag 原本是給 <span> 用的，套在 <a> 上會冒出底線與連結藍，
     所以在 a.ap-nav 上歸零；不動全站 .tag 的長相。 */
a.ap-nav{text-decoration:none;cursor:pointer}
a.ap-nav:hover{filter:brightness(.96)}
a.ap-nav:visited{color:inherit}
.ap-meta a.ap-nav{margin-left:2px;white-space:nowrap}
.ap-day-h a.ap-nav{white-space:nowrap}

/* ============================================================================
   戰略客戶（2026-10-31，views/vip.js）
   ----------------------------------------------------------------------------
   ★ 版面刻意做成「左清單 / 右工作台」而不是一張大表：
     合作方是少數（5～20 家），但每家底下的案源是幾十筆 ——
     一張表要把兩層壓平，結果就是同一家公司重複出現在 30 列上。
   ★ 手機（<=880px）改成上下堆疊：清單在上、工作台在下，兩邊都還是完整的。
   ============================================================================ */
.vp-wrap{display:grid;grid-template-columns:290px minmax(0,1fr);gap:14px;align-items:start}
.vp-side{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:10px;box-shadow:var(--shadow)}
.vp-main{min-width:0}
.vp-search{width:100%;box-sizing:border-box;padding:7px 10px;border:1px solid var(--line);border-radius:8px;
  font-size:var(--fs-sm);background:#fff;margin-bottom:8px}
.vp-item{padding:9px 10px;border-radius:9px;cursor:pointer;border:1px solid transparent;margin-bottom:4px}
.vp-item:hover{background:var(--bg)}
.vp-item.on{background:var(--brand-soft);border-color:#cfe4dc}
.vp-item-t{font-weight:600;font-size:13.5px;color:var(--text);display:flex;align-items:center;gap:6px}
.vp-item-s{font-size:12px;color:var(--text-2);margin-top:2px;line-height:1.5}
.vp-dot{margin-left:auto;background:var(--danger);color:#fff;font-size:11px;line-height:1;
  padding:3px 6px;border-radius:9px;font-weight:600}
.vp-nums{display:flex;flex-wrap:wrap;gap:18px;padding:4px 0 2px}
.vp-num b{display:block;font-size:19px;font-weight:700;letter-spacing:-.3px;color:var(--text)}
.vp-num span{display:block;font-size:11.5px;color:var(--text-3);margin-top:1px}
.vp-num.danger b{color:var(--danger)}
.vp-num.warn b{color:var(--warn)}
.vp-tabs{display:flex;gap:2px;border-bottom:1px solid var(--line);padding:0 12px;overflow-x:auto}
.vp-tab{background:none;border:0;border-bottom:2px solid transparent;padding:9px 12px;font-size:13px;
  color:var(--text-2);cursor:pointer;white-space:nowrap;font-family:inherit}
.vp-tab:hover{color:var(--text)}
.vp-tab.on{color:var(--brand);border-bottom-color:var(--brand);font-weight:600}
.vp-ops{white-space:nowrap}
.vp-wrap .tag{white-space:nowrap}
.vp-wrap td.nw{white-space:nowrap}
.vp-ops .btn{margin-left:4px}
.vp-note{border:1px solid var(--line);border-radius:10px;margin-bottom:9px;overflow:hidden}
.vp-note.hot{border-color:#f0c9c5;background:#fffdfd}
.vp-note.done{opacity:.62}
.vp-note-h{display:flex;gap:10px;align-items:flex-start;padding:10px 12px;cursor:pointer}
.vp-note-h:hover{background:var(--bg)}
.vp-note-t{font-weight:600;font-size:13.5px;display:flex;align-items:center;gap:6px}
.vp-note-s{font-size:12px;color:var(--text-2);margin-top:3px;line-height:1.6}
.vp-red{width:7px;height:7px;border-radius:50%;background:var(--danger);display:inline-block;flex:none}
.vp-note-b{padding:0 12px 12px;border-top:1px solid var(--line-2)}
.vp-body{background:var(--bg);border-radius:8px;padding:9px 11px;font-size:13px;line-height:1.75;
  white-space:normal;margin:10px 0;color:var(--text)}
.vp-thread{margin:10px 0 0}
.vp-msg{border-radius:9px;padding:8px 11px;margin-bottom:7px;max-width:92%;width:fit-content;min-width:170px}
.vp-msg.me{background:var(--brand-soft);margin-left:auto}
.vp-msg.them{background:#fdf3e2}
.vp-msg-h{font-size:11.5px;color:var(--text-3);display:flex;align-items:center;gap:6px;margin-bottom:3px}
.vp-msg-b{font-size:13px;line-height:1.7;white-space:normal;color:var(--text)}
.vp-msg-x{margin-left:auto;cursor:pointer;color:var(--text-3);font-size:15px;line-height:1;padding:0 2px}
.vp-msg-x:hover{color:var(--danger)}
.vp-reply{margin-top:10px}
.vp-reply textarea{width:100%;box-sizing:border-box;border:1px solid var(--line);border-radius:8px;
  padding:8px 10px;font-size:13px;font-family:inherit;line-height:1.6;resize:vertical}
.vp-att{margin-top:8px;font-size:12px;color:var(--text-2);display:flex;flex-wrap:wrap;gap:6px;align-items:center}
.vp-info{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px 18px}
.vp-kv{display:flex;gap:8px;font-size:13px;line-height:1.7;padding:3px 0;border-bottom:1px dashed var(--line-2)}
.vp-kv-k{color:var(--text-3);flex:none;min-width:76px}
.vp-kv-v{color:var(--text);min-width:0;word-break:break-word}
.form2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:0 14px}
.vp-ct{display:flex;gap:6px;align-items:center;margin-bottom:6px;flex-wrap:wrap}
.vp-ct input[type=text],.vp-ct input:not([type]){min-width:80px}
.vp-ctmain{display:flex;align-items:center;gap:4px;font-size:12px;color:var(--text-2);white-space:nowrap}
.vp-pick{display:block;padding:7px 4px;border-bottom:1px solid var(--line-2);font-size:13px;cursor:pointer}
@media(max-width:880px){
  .vp-wrap{grid-template-columns:1fr}
  .vp-info,.form2{grid-template-columns:1fr}
  .vp-side{max-height:38vh;overflow:auto}
}
