:root {
    --ink: #15313b;
    --ink-soft: #4c6870;
    --paper: #eef6f8;
    --line: #d7e6ea;
    --brand: #0f7ea3;
    --brand-dark: #0a6480;
    --danger: #c8262a;
    --danger-dark: #a31e21;
    --topbar-bg: #15313b;
    --card-bg: #fff;
    --input-bg: #fff;
    --input-border: #d4d2ce;
    --table-border: #e5e5e5;
    --text-muted: #777;
    --shadow: rgba(28,28,30,0.04);
}

html[data-theme="dark"] {
    --ink: #e7eef0;
    --ink-soft: #a9bcc2;
    --paper: #0f1a1d;
    --line: #2a3d43;
    --brand: #22a6d9;
    --brand-dark: #4fc1ec;
    --danger: #e2585c;
    --danger-dark: #f0797c;
    --card-bg: #172427;
    --input-bg: #1c2c30;
    --input-border: #35494f;
    --table-border: #2a3d43;
    --text-muted: #93a7ac;
    --shadow: rgba(0,0,0,0.3);
}

* { box-sizing: border-box; }
body {
    margin: 0;
    font-family: "Microsoft JhengHei", "PingFang TC", -apple-system, BlinkMacSystemFont, sans-serif;
    background: var(--paper);
    color: var(--ink);
}
a { color: var(--brand-dark); }

.topbar {
    background: var(--topbar-bg);
    color: #fff;
    padding: 14px 18px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
}
.topbar-title { font-size: 18px; font-weight: bold; letter-spacing: 0.02em; display: flex; align-items: center; gap: 8px; }
.topbar-title-link { color: inherit; text-decoration: none; }
.topbar-title-link:hover { opacity: 0.85; }
.topbar-logo { height: 28px; width: auto; display: block; }
.topbar-right { display: flex; align-items: center; gap: 14px; }
.topbar-nav { font-size: 14px; }
.topbar-nav a { color: #bfe4f0; margin-left: 12px; text-decoration: none; }
.topbar-nav a:hover { color: #fff; }
.topbar-user { color: #cfcfd4; }

.theme-toggle-btn {
    width: 34px;
    height: 34px;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(255,255,255,0.12);
    border: 1px solid rgba(255,255,255,0.25);
    border-radius: 999px;
    color: #fff;
    font-size: 16px;
    cursor: pointer;
}
.theme-toggle-btn:hover { background: rgba(255,255,255,0.22); }

.container {
    max-width: 720px;
    margin: 0 auto;
    padding: 16px;
}
/* 報表類頁面（發票紀錄／歷史訂單查詢／財務對帳報表／師傅績效）欄位比較多，桌機螢幕明明還有很大空間，
   卻因為套用跟其他單欄表單頁面一樣的 720px 窄版面，逼著表格提前橫向捲動——放寬到 1200px，
   手機上因為螢幕本來就沒那麼寬，實際顯示效果跟原本差不多，不用另外處理。 */
.container-wide { max-width: 1200px; }

.card {
    background: var(--card-bg);
    border: 1px solid var(--line);
    border-radius: 10px;
    padding: 18px;
    margin-bottom: 16px;
    box-shadow: 0 1px 2px var(--shadow);
}

h1, h2, h3 { margin-top: 0; }

table { width: 100%; border-collapse: collapse; }
table th, table td { padding: 8px; border-bottom: 1px solid var(--table-border); text-align: left; font-size: 14px; }
/* .table-scroll 這個 class 被好幾個報表頁面（發票紀錄、歷史訂單、對帳報表、師傅績效）用來包住寬表格，
   但這個樣式本身之前漏掉沒有定義——欄位一多，瀏覽器會硬把每欄擠窄，中文字被迫一個字一行換行，很難看。
   改成表格本身可以撐開到內容需要的寬度，超出畫面的部分交給這個容器自己橫向捲動，不會影響頁面其他部分版面。
   nowrap 只套用在這個 class 底下的表格（欄位大多是姓名/狀態/日期這種短內容才適合），操作紀錄那種有長篇
   說明文字的表格沒有用這個 class，維持原本自然換行，不受影響。 */
.table-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    /* 左右邊緣淡出陰影：捲得到內容的那一側才會出現陰影，捲到底那一側自動消失，讓使用者一眼看出
       「這裡還能往右滑」而不是誤以為內容被切斷了；手機沒有滑鼠、通常也看不到捲軸，這個提示更重要。
       用的是常見的 CSS 雙層漸層背景技巧，background-attachment: local 讓陰影跟著內容捲動位置變化。 */
    background:
        linear-gradient(to right, var(--card-bg) 30%, rgba(255,255,255,0)),
        linear-gradient(to right, rgba(255,255,255,0), var(--card-bg) 70%) 100% 0,
        radial-gradient(farthest-side at 0 50%, rgba(0,0,0,.18), rgba(0,0,0,0)),
        radial-gradient(farthest-side at 100% 50%, rgba(0,0,0,.18), rgba(0,0,0,0)) 100% 0;
    background-repeat: no-repeat;
    background-color: var(--card-bg);
    background-size: 32px 100%, 32px 100%, 12px 100%, 12px 100%;
    background-position: 0 0, 100% 0, 0 0, 100% 0;
    background-attachment: local, local, scroll, scroll;
    /* 桌機瀏覽器（Chrome/Edge/Safari／Firefox）額外把捲軸調成一直看得到的細長樣式，避免作業系統
       預設「隱藏捲軸、要滑到才出現」讓人看不出這裡可以左右滑。 */
    scrollbar-width: thin;
    scrollbar-color: var(--brand) var(--card-bg);
}
.table-scroll::-webkit-scrollbar { height: 8px; }
.table-scroll::-webkit-scrollbar-track { background: var(--card-bg); }
.table-scroll::-webkit-scrollbar-thumb { background: var(--brand); border-radius: 4px; }
.table-scroll table { width: auto; min-width: 100%; }
.table-scroll table th, .table-scroll table td { white-space: nowrap; }
/* 個別儲存格想跳出 nowrap、維持自然換行時用（例如客戶姓名下面接第二行 Email 這種刻意換行的內容） */
.table-scroll table td.wrap-cell { white-space: normal; }
/* 備註欄：內容是自由輸入的文字（客戶用來記錄一起施工的技師），長度不固定。
   限制最大寬度，讓它自己折行，不會把整個表格撐寬到要一直橫向捲動。 */
.table-scroll table td.note-cell { max-width: 220px; }
.table-scroll table td.note-cell .note-manual { font-size: 13px; }

/* 師傅「我的收款紀錄」：備註自成一列、橫跨整個表格。
   刻意不放進訂單編號那一格——長長的技師名單會把那一欄撐寬，連帶把時間與付款方式擠到折行。
   有備註的訂單列加 .has-note 去掉下緣框線，讓備註視覺上貼著它所屬的那一筆，不像另一筆訂單。
   （用 PHP 加 class 而不是 CSS :has()，因為舊手機瀏覽器不一定支援 :has()。）
   這張表沒有包在 .table-scroll 裡，所以不受 nowrap 影響，長備註可以自然折行。 */
.has-note td { border-bottom: 0; }
.history-note-row td { padding-top: 0; font-size: 13px; color: var(--text-muted);
                       white-space: normal; word-break: break-word; }

/* 角色與權限設定：權限矩陣（權限=列、角色=欄，交叉點打勾）。角色一多只會往右多一欄、交給 .table-scroll
   橫向捲動，不會像「每個角色一大塊checklist」那樣往下無限疊長。第一欄（權限名稱）用 sticky 固定在左側，
   橫向捲動時仍看得到每一列是什麼權限。 */
.perm-matrix { width: auto; }
.perm-matrix th, .perm-matrix td { text-align: center; }
.perm-matrix .perm-matrix-label {
    position: sticky;
    left: 0;
    z-index: 2;
    background: var(--card-bg);
    text-align: left;
    white-space: nowrap;
}
.perm-matrix th.perm-matrix-role { white-space: nowrap; padding-left: 16px; padding-right: 16px; }
.perm-matrix .perm-matrix-cell { padding-left: 16px; padding-right: 16px; }
.perm-matrix input[type=checkbox] { width: 18px; height: 18px; }

/* 服務項目清單的欄寬（桌機用；手機版卡片模式下會在 media query 裡解除，
   避免固定寬度在窄螢幕把卡片撐開） */
.table-scroll table .col-name { min-width: 220px; }
.table-scroll table .col-price { width: 100px; }
.table-scroll table .col-sort { width: 76px; }

/* ------------------------------------------------------------------
   人員編輯頁（admin/staff_edit.php）
   原本編輯表單塞在人員清單表格的最後一欄用 <details> 展開，因為 .table-scroll 有
   white-space: nowrap，展開後表單無法換行而互相重疊。改成獨立頁面：左邊基本資料，
   右邊把「停用帳號」「重設密碼」分成各自的區塊，較不容易誤按。
   ------------------------------------------------------------------ */
.back-link { display: inline-flex; align-items: center; gap: 6px; font-size: 14px; text-decoration: none; }
.back-link svg { width: 16px; height: 16px; }

.person-header { display: flex; align-items: center; gap: 14px; margin-bottom: 18px; }
.person-avatar {
    width: 46px; height: 46px; flex: 0 0 46px;
    border-radius: 50%;
    background: rgba(15,126,163,0.12);
    border: 1px solid var(--brand);
    color: var(--brand-dark);
    display: flex; align-items: center; justify-content: center;
    font-size: 18px; font-weight: bold;
}
.person-name { font-size: 22px; font-weight: bold; line-height: 1.25; }
.person-meta { font-size: 13px; color: var(--text-muted); margin-top: 2px; }

.edit-layout { display: grid; grid-template-columns: 1.75fr 1fr; gap: 18px; align-items: start; }
.edit-side { display: flex; flex-direction: column; gap: 0; }
@media (max-width: 800px) {
    .edit-layout { grid-template-columns: 1fr; }
}

/* 表單欄位兩欄並排（畫面窄時自動變單欄） */
.field-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 20px; }
@media (max-width: 640px) {
    .field-grid { grid-template-columns: 1fr; }
}

/* 不可編輯的欄位（例如帳號）：用虛線邊框表示唯讀，跟可輸入的欄位一眼區分 */
.readonly-field {
    padding: 10px 12px;
    font-size: 16px;
    border: 1px dashed var(--input-border);
    border-radius: 8px;
    background: rgba(127,127,127,0.06);
    color: var(--text-muted);
}

.form-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 20px; }

.status-line { display: flex; align-items: center; gap: 9px; font-size: 15px; margin-bottom: 12px; }
.status-dot { width: 9px; height: 9px; border-radius: 50%; display: inline-block; }
.status-dot.is-on { background: var(--brand); }
.status-dot.is-off { background: var(--text-muted); }


/* ------------------------------------------------------------------
   「＋ 新增」收合面板（服務項目管理／人員管理／角色與權限設定共用）
   原本這些頁面都把「新增」表單放在最上面、清單放下面，資料一多就要一直往下捲才看得到清單。
   改成「清單優先、新增收合」：預設只顯示一條細長的新增列，點開才展開表單。
   ------------------------------------------------------------------ */
.add-panel {
    border: 1px solid var(--line);
    border-radius: 10px;
    margin-bottom: 16px;
    background: rgba(127,127,127,0.03);
}
.add-panel > summary {
    list-style: none;
    cursor: pointer;
    padding: 11px 15px;
    font-size: 15px;
    font-weight: bold;
    color: var(--brand-dark);
    display: flex;
    align-items: center;
    gap: 8px;
    user-select: none;
    border-radius: 10px;
}
.add-panel > summary::-webkit-details-marker { display: none; }
.add-panel > summary:hover { background: rgba(127,127,127,0.05); }
.add-panel > summary .add-plus {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: var(--brand);
    color: #fff;
    font-size: 15px;
    line-height: 1;
    flex: 0 0 20px;
}
.add-panel[open] > summary {
    border-bottom: 1px solid var(--line);
    border-radius: 10px 10px 0 0;
}
.add-panel[open] > summary .add-plus { transform: rotate(45deg); }
.add-panel .add-body { padding: 2px 15px 16px; }

/* ------------------------------------------------------------------
   手機版：把管理清單的表格改成一列一張卡片
   桌機上表格很好用，但手機螢幕窄，欄位多的表格只能橫向捲動，操作按鈕會被推到看不見的地方。
   加上 .stack-mobile 的表格在 640px 以下改成「一列一張卡」，每格前面用 data-label 顯示欄位名稱。
   只套用在欄位數適中的管理清單（人員／服務項目）；欄位很多的報表頁維持橫向捲動，
   因為攤開成卡片反而更難一次看完整列資料。
   ------------------------------------------------------------------ */
@media (max-width: 640px) {
    .table-scroll table.stack-mobile,
    .table-scroll table.stack-mobile tbody,
    .table-scroll table.stack-mobile tr,
    .table-scroll table.stack-mobile td {
        display: block;
        width: auto;
        min-width: 0;
    }
    /* 這些表格的標題列就是第一個 <tr>（沒有 thead），卡片模式下不需要 */
    .table-scroll table.stack-mobile tr:first-child { display: none; }
    .table-scroll table.stack-mobile tr {
        border: 1px solid var(--line);
        border-radius: 10px;
        padding: 10px 12px;
        margin-bottom: 10px;
        background: var(--card-bg);
    }
    .table-scroll table.stack-mobile td {
        white-space: normal;
        border-bottom: none;
        padding: 5px 0;
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 12px;
        font-size: 15px;
    }
    .table-scroll table.stack-mobile td::before {
        content: attr(data-label);
        flex: 0 0 auto;
        font-size: 13px;
        font-weight: bold;
        color: var(--ink-soft);
    }
    /* 沒有欄位名稱的儲存格（例如只放操作按鈕的那一格）不留標籤空位 */
    .table-scroll table.stack-mobile td[data-label=""]::before { content: none; }
    .table-scroll table.stack-mobile td > input,
    .table-scroll table.stack-mobile td > select {
        flex: 1 1 auto;
        width: auto;
        min-width: 0;
        max-width: 60%;
    }
    /* 桌機用的固定欄寬在卡片模式下解除，否則窄螢幕會被撐開 */
    .table-scroll table.stack-mobile .col-name,
    .table-scroll table.stack-mobile .col-price,
    .table-scroll table.stack-mobile .col-sort { min-width: 0; width: auto; }
    .table-scroll table.stack-mobile td.cell-actions {
        justify-content: flex-start;
        padding-top: 10px;
        margin-top: 4px;
        border-top: 1px solid var(--line);
    }
    .table-scroll table.stack-mobile td.cell-actions > div,
    .table-scroll table.stack-mobile td.cell-actions > a {
        flex: 1 1 auto;
    }
    .table-scroll table.stack-mobile td.cell-actions .btn { width: 100%; }
    /* 卡片模式下不需要橫向捲動的陰影提示 */
    .table-scroll:has(table.stack-mobile) { background-image: none; }
}

/* 篩選工具列（共用）：關鍵字＋各種下拉條件＋日期區間收在同一列，選了之後下方出現可各自取消的篩選標籤。
   原本只寫在「歷史訂單查詢」頁面自己的 <style> 裡，其他報表頁面（發票紀錄等）沒有共用到，樣式長得不一致；
   搬來這裡讓所有報表頁面共用同一套，以後新增篩選頁面也不用重寫一次。 */
.filter-toolbar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.search-field {
    display: flex; align-items: center; gap: 8px;
    border: 1px solid var(--input-border); border-radius: 8px; padding: 9px 12px;
    flex: 1 1 220px; min-width: 180px; background: var(--input-bg);
}
.search-field svg { width: 16px; height: 16px; color: var(--text-muted); flex: 0 0 auto; }
.search-field input { border: none; outline: none; font-size: 14px; width: 100%; background: transparent; color: var(--ink); }
.pill-select {
    border: 1px solid var(--input-border); border-radius: 8px; padding: 9px 10px;
    font-size: 13.5px; color: var(--ink); background: var(--input-bg); flex: 0 0 auto;
}
.date-group { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; }
.date-group input { border: 1px solid var(--input-border); border-radius: 8px; padding: 8px; font-size: 13px; color: var(--ink); background: var(--input-bg); width: 138px; }
.date-sep { color: var(--text-muted); font-size: 13px; }
.filter-toolbar .search-btn { flex: 0 0 auto; width: auto; margin-top: 0; padding: 10px 22px; }

.active-chips { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 12px; }
.chip { display: flex; align-items: center; gap: 6px; background: rgba(15,126,163,0.09); color: var(--brand-dark); border-radius: 14px; padding: 5px 8px 5px 12px; font-size: 12.5px; font-weight: 600; text-decoration: none; }
.chip svg { width: 12px; height: 12px; }
.chip:hover { background: rgba(15,126,163,0.16); }

label { display: block; margin: 12px 0 4px; font-weight: bold; font-size: 14px; color: var(--ink-soft); }
input[type=text], input[type=email], input[type=tel], input[type=password], input[type=number], select, textarea {
    width: 100%;
    padding: 10px 12px;
    font-size: 16px;
    border: 1px solid var(--input-border);
    border-radius: 8px;
    background: var(--input-bg);
    color: var(--ink);
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
input:focus, select:focus, textarea:focus {
    outline: none;
    border-color: var(--brand);
    box-shadow: 0 0 0 3px rgba(21,150,199,0.15);
}
textarea { resize: vertical; }
/* 表單驗證失敗時，具體標出是哪個欄位有問題（原本只在畫面最上方顯示一句籠統的錯誤訊息，
   使用者要自己猜是哪一欄，且欄位內容因為沒有回填一度看起來像被清空）。 */
input.input-error, select.input-error {
    border-color: var(--danger);
    box-shadow: 0 0 0 1px var(--danger);
}
/* 手機載具輸入：固定顯示不可編輯的「/」開頭，使用者只需要打後面7碼，不用自己記得加斜線。 */
.carrier-input-group {
    display: flex;
    align-items: stretch;
}
.carrier-input-group .carrier-prefix {
    display: flex;
    align-items: center;
    padding: 0 10px;
    border: 1px solid var(--input-border);
    border-right: none;
    border-radius: 8px 0 0 8px;
    background: var(--paper);
    color: var(--ink-soft);
    font-size: 16px;
}
.carrier-input-group input {
    border-radius: 0 8px 8px 0;
}
.carrier-input-group.input-error .carrier-prefix { border-color: var(--danger); }

.btn {
    display: inline-block;
    padding: 12px 20px;
    font-size: 16px;
    font-weight: bold;
    border: none;
    border-radius: 8px;
    background: var(--brand);
    color: #fff;
    cursor: pointer;
    text-decoration: none;
    text-align: center;
    transition: background 0.15s ease, transform 0.05s ease;
}
.btn:hover { background: var(--brand-dark); }
.btn:active { transform: translateY(1px); }
.btn-secondary { background: #e1eef1; color: var(--ink); }
.btn-secondary:hover { background: #cde0e4; }
html[data-theme="dark"] .btn-secondary { background: #223338; color: var(--ink); }
html[data-theme="dark"] .btn-secondary:hover { background: #2b4147; }
.btn-danger { background: var(--danger); }
.btn-danger:hover { background: var(--danger-dark); }
.btn-block { display: block; width: 100%; margin-top: 12px; }
.btn-sm { padding: 6px 12px; font-size: 13px; }

/* 次要按鈕：外框樣式，跟主要動作（實心）區分 */
.btn-ghost {
    background: transparent;
    border: 1px solid var(--input-border);
    color: var(--ink);
}
.btn-ghost:hover { background: rgba(127,127,127,0.08); }
.btn-outline-danger {
    background: transparent;
    border: 1px solid var(--danger);
    color: var(--danger);
}
.btn-outline-danger:hover { background: rgba(200,38,42,0.08); }

.item-row { display: flex; align-items: center; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid #eee; }

/* 拿掉瀏覽器原生的數字輸入框上下箭頭（手機上手指滑動經過很容易誤觸，數量會突然暴衝）。
   這個規則保留給其他地方還在用的 <input type=number>（例如手動輸入金額、單價設定）。 */
input[type=number]::-webkit-inner-spin-button,
input[type=number]::-webkit-outer-spin-button {
    -webkit-appearance: none;
    margin: 0;
}
input[type=number] { -moz-appearance: textfield; }

/* 選擇服務項目的數量改用下拉選單（0~9），不是數字輸入框：數字輸入框就算拿掉上下箭頭，
   滑鼠滾輪／觸控板在欄位有焦點時還是能改變數值（Sergey 實測滾輪可以調整，判斷手機觸控滑動也有同樣風險），
   下拉選單要先點開才能選，不會被滑過去的手勢意外觸發。 */
.qty-select {
    width: 76px;
    padding: 10px 8px;
    font-size: 16px;
    text-align: center;
    border: 1px solid var(--input-border);
    border-radius: 8px;
    background: var(--input-bg);
    color: var(--ink);
}

.chip-row { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.chip-btn {
    padding: 10px 14px;
    border: 1px solid var(--input-border);
    border-radius: 16px;
    background: var(--input-bg);
    color: var(--ink);
    font-size: 13px;
    cursor: pointer;
}
.chip-btn:active, .chip-btn.active { background: var(--brand); color: #fff; border-color: var(--brand); }

.total-box { font-size: 22px; font-weight: bold; text-align: right; margin-top: 8px; }
.subtotal-box { font-size: 14px; color: #666; text-align: right; }

.checklist label { display: flex; align-items: center; font-weight: normal; font-size: 15px; }
.checklist input[type=checkbox] { width: auto; margin-right: 8px; }

.checkbox-label { display: flex; align-items: center; font-weight: normal; font-size: 15px; }
.checkbox-label input[type=checkbox] { width: auto; margin-right: 8px; }

.password-field { position: relative; }
.password-field input { padding-right: 44px; }
.password-toggle-btn {
    position: absolute; right: 4px; top: 50%; transform: translateY(-50%);
    background: none; border: none; cursor: pointer; font-size: 18px; line-height: 1;
    padding: 8px; color: var(--ink-soft);
}


.status-badge { display: inline-block; padding: 4px 10px; border-radius: 12px; font-size: 13px; color: #fff; }
/* 訂單編號改成純數字格式（例如 #2026081614320552），tabular-nums 讓每個數字對齊等寬，比較好讀 */
.order-no { font-variant-numeric: tabular-nums; color: var(--ink-soft); }
.status-draft, .status-awaiting_cash_confirm, .status-awaiting_online_payment { background: #f0ad4e; }
.status-awaiting_invoice { background: #5bc0de; }
.status-paid { background: #28a745; }
.status-cancelled, .status-expired { background: #999; }
.status-pending_issue { background: #f0ad4e; }
.status-issued { background: #28a745; }
.status-failed { background: var(--danger); }

.flash-error { background: #fbeaea; color: var(--danger-dark); padding: 12px; border-radius: 8px; margin-bottom: 16px; border: 1px solid #f2cfd0; }
.flash-success { background: #e9f3ea; color: #256b32; padding: 12px; border-radius: 8px; margin-bottom: 16px; border: 1px solid #cde5cf; }
html[data-theme="dark"] .flash-error { background: #3a2226; color: #ff9fa2; border-color: #5a2e32; }
html[data-theme="dark"] .flash-success { background: #1f3626; color: #8fdb9f; border-color: #2d4d34; }

.qr-box { text-align: center; }
.qr-box img { max-width: 260px; width: 100%; height: auto; }

.nav-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.nav-grid a.card { display: block; text-align: center; text-decoration: none; color: var(--ink); font-weight: bold; }

/* 項目多的角色（管理者/財務）在每一頁最上方都有這條常駐導覽列（不是只有首頁才有）：常用項目做成頁籤橫排，
   次常用點「更多功能」展開下拉選單，設定類在下拉選單裡再點「系統設定」收合展開；
   項目少的角色（例如師傅）不套用，首頁維持 .nav-grid 平鋪版面。
   position: sticky 讓這條列固定跟著捲動、停在畫面最上方，不用滑回頁面最上面才能切換到別的功能。 */
.action-bar {
    display: flex;
    align-items: center;
    gap: 8px;
    background: var(--card-bg);
    border: 1px solid var(--line);
    border-radius: 12px;
    padding: 8px;
    box-shadow: 0 1px 2px var(--shadow);
    position: sticky;
    top: 8px;
    z-index: 15;
    margin-bottom: 16px;
    transition: box-shadow 0.25s ease, border-color 0.25s ease;
}
/* 真正貼齊畫面上緣捲動中時（JS 用 sentinel 偵測，見 render_nav_bar），陰影加深、邊框淡出，
   讓導覽列有「浮在內容上方」的層次感，不是全程都同一種扁平陰影。 */
.action-bar.is-stuck {
    box-shadow: 0 10px 24px rgba(21,49,59,0.14), 0 2px 6px rgba(21,49,59,0.08);
    border-color: transparent;
}
.nav-sentinel { height: 1px; }
/* 頁籤區塊自己滾動（左右滑動），「更多功能」按鈕固定在外面，
   避免手機上頁籤太多把「更多功能」擠出畫面、滑不到就點不到展開按鈕。 */
.tabs-scroll {
    display: flex;
    align-items: center;
    gap: 4px;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    flex: 1 1 auto;
    min-width: 0;
}
.tab {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 11px 16px;
    border-radius: 8px;
    color: var(--ink-soft);
    text-decoration: none;
    font-weight: 700;
    font-size: 14.5px;
    white-space: nowrap;
    transition: background 0.15s ease, color 0.15s ease;
}
.tab:hover { background: rgba(15,126,163,0.08); color: var(--ink); }
.tab:hover .tab-icon { transform: translateY(-1px); }
/* 目前所在的頁籤改用漸層底色＋陰影，比純色色塊多一點立體感 */
.tab.is-active { background: linear-gradient(135deg, var(--brand) 0%, var(--brand-dark) 100%); color: #fff; box-shadow: 0 2px 8px rgba(15,126,163,0.35); }
.tab .tab-icon { width: 18px; height: 18px; flex: 0 0 auto; transition: transform 0.2s cubic-bezier(.34,1.56,.64,1); }

.more-btn {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 7px;
    padding: 11px 14px;
    border-radius: 8px;
    border: 1px solid var(--line);
    background: #fff;
    color: var(--brand-dark);
    font-size: 14px;
    font-weight: 700;
    cursor: pointer;
    white-space: nowrap;
    transition: border-color 0.15s ease, background 0.15s ease;
}
html[data-theme="dark"] .more-btn { background: var(--card-bg); }
.more-btn:hover { border-color: var(--brand); background: rgba(15,126,163,0.06); }
.more-btn .more-chevron { width: 14px; height: 14px; transition: transform 0.22s cubic-bezier(.4,0,.2,1); }
.more-btn .more-chevron.is-open { transform: rotate(180deg); }

/* 展開/收合用 opacity + translateY + scale 一起做（不是 display:none/block 瞬間切換），
   有明顯的「浮現」動態感；平常 pointer-events:none 避免收合狀態擋住底下的點擊。 */
.dropdown {
    position: absolute;
    top: calc(100% + 10px);
    right: 8px;
    width: min(260px, calc(100vw - 48px));
    background: var(--card-bg);
    border: 1px solid var(--line);
    border-radius: 10px;
    box-shadow: 0 10px 28px rgba(21,49,59,0.16);
    padding: 8px;
    z-index: 20;
    opacity: 0;
    transform: translateY(-6px) scale(0.97);
    transform-origin: top right;
    pointer-events: none;
    transition: opacity 0.16s ease, transform 0.16s cubic-bezier(.2,.9,.3,1.3);
}
.dropdown.is-open { opacity: 1; transform: translateY(0) scale(1); pointer-events: auto; }
.drop-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 11px 10px;
    border-radius: 7px;
    color: var(--ink);
    text-decoration: none;
    font-size: 14px;
    font-weight: 500;
    transition: background 0.12s ease, padding-left 0.12s ease;
}
.drop-item:hover { background: rgba(15,126,163,0.08); color: var(--ink); padding-left: 13px; }
.drop-item.is-active { background: rgba(15,126,163,0.12); color: var(--brand-dark); font-weight: 700; }
.drop-item .tab-icon { width: 17px; height: 17px; color: var(--ink-soft); flex: 0 0 auto; }
.drop-divider { height: 1px; background: var(--line); margin: 6px 4px; }

.drop-group-toggle {
    width: 100%;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 11px 10px;
    border-radius: 7px;
    border: none;
    background: none;
    color: var(--text-muted);
    font-size: 12.5px;
    font-weight: 700;
    letter-spacing: 0.03em;
    cursor: pointer;
    text-align: left;
}
.drop-group-toggle:hover { background: rgba(15,126,163,0.08); color: var(--ink-soft); }
.drop-group-toggle .tab-icon { width: 15px; height: 15px; flex: 0 0 auto; }
.drop-group-chevron { margin-left: auto; width: 13px; height: 13px; transition: transform 0.15s ease; flex: 0 0 auto; }
.drop-group-chevron.is-open { transform: rotate(90deg); }
.drop-sub { overflow: hidden; max-height: 0; transition: max-height 0.16s ease; }
.drop-sub.is-open { max-height: 200px; }
.drop-sub .drop-item { padding-left: 26px; font-size: 13.5px; }

.text-muted { color: var(--text-muted); font-size: 13px; }
.right { text-align: right; }
.center { text-align: center; }

/* ---- 登入畫面 ---- */
.auth-shell {
    position: relative;
    overflow: hidden;
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px 16px;
    background:
        radial-gradient(circle at 15% 15%, rgba(15,126,163,0.14), transparent 40%),
        radial-gradient(circle at 85% 85%, rgba(21,49,59,0.06), transparent 45%),
        var(--paper);
}
.auth-waves {
    position: absolute;
    left: 0; right: 0; bottom: 0;
    height: 34vh;
    min-height: 180px;
    overflow: hidden;
    z-index: 0;
    pointer-events: none;
}
.auth-wave {
    position: absolute;
    left: 0; bottom: 0;
    width: 200%;
    height: 100%;
    background-repeat: repeat-x;
    background-position: 0 bottom;
}
.auth-wave--back {
    height: 100%;
    opacity: 0.35;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 600 100' preserveAspectRatio='none'%3E%3Cpath d='M0,55 C150,20 150,90 300,55 C450,20 450,90 600,55 L600,100 L0,100 Z' fill='%237fc2d8'/%3E%3C/svg%3E");
    background-size: 600px 100%;
    animation: auth-wave-scroll-back 16s linear infinite;
}
.auth-wave--front {
    height: 74%;
    opacity: 0.6;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 600 100' preserveAspectRatio='none'%3E%3Cpath d='M0,50 C150,85 150,15 300,50 C450,85 450,15 600,50 L600,100 L0,100 Z' fill='%230f7ea3'/%3E%3C/svg%3E");
    background-size: 600px 100%;
    animation: auth-wave-scroll-front 10s linear infinite reverse;
}
@keyframes auth-wave-scroll-back {
    from { background-position-x: 0; }
    to { background-position-x: -600px; }
}
@keyframes auth-wave-scroll-front {
    from { background-position-x: 0; }
    to { background-position-x: -600px; }
}
@media (prefers-reduced-motion: reduce) {
    .auth-wave { animation: none; }
}
.auth-box { position: relative; z-index: 1; width: 100%; max-width: 380px; }
.auth-logo {
    display: block;
    height: 96px;
    width: auto;
    margin: 0 auto 12px;
}
.auth-heading { text-align: center; margin-bottom: 28px; }
.auth-heading h1 { font-size: 20px; margin: 0 0 4px; letter-spacing: 0.02em; }
.auth-heading p { margin: 0; color: var(--ink-soft); font-size: 13px; }
.auth-card {
    background: var(--card-bg);
    border: 1px solid var(--line);
    border-radius: 14px;
    padding: 28px 24px;
    box-shadow: 0 12px 32px rgba(28,28,30,0.08);
}
html[data-theme="dark"] .auth-card { box-shadow: 0 12px 32px rgba(0,0,0,0.4); }
.auth-card label:first-of-type { margin-top: 0; }
.auth-footer { text-align: center; margin-top: 20px; color: #9a9a9a; font-size: 12px; }

.captcha-row { display: flex; gap: 8px; align-items: center; }
.captcha-row input { flex: 1; letter-spacing: 0.15em; text-transform: uppercase; }
.captcha-row img { height: 44px; border-radius: 8px; border: 1px solid var(--line); cursor: pointer; }

/* ==================================================================
   師傅收款：明細確認頁的「返回修改項目」
   這一頁原本沒有任何退路（見 CLAUDE.md 第八章第24項）。刻意放在頁面最上方，
   離底部的「確認並出示 QR Code」遠一點，避免手指誤觸。
   ================================================================== */
.back-form { margin-bottom: 12px; }
/* 用品牌色的外框按鈕，不用 .btn-ghost 的灰框——灰框在深色模式的卡片背景上幾乎看不見
   （2026-09-01 Sergey 驗收時反映）。--brand 在淺色／深色主題各有一組值，兩邊都夠明顯。 */
.btn-back {
    padding: 10px 16px;
    font-size: 15px;
    background: rgba(15,126,163,0.10);
    border: 1px solid var(--brand);
    color: var(--brand-dark);
}
.btn-back:hover { background: rgba(15,126,163,0.18); }
html[data-theme="dark"] .btn-back { background: rgba(34,166,217,0.18); }
html[data-theme="dark"] .btn-back:hover { background: rgba(34,166,217,0.28); }

/* 施工檢查／簽名沒完成時的紅字提醒。刻意做成頁面上的紅字而不是彈出視窗，
   也刻意不重新載入頁面——重載會把客戶剛簽好的簽名清掉。 */
.check-alert {
    color: var(--danger);
    font-weight: bold;
    font-size: 14px;
    margin: 0 0 10px;
    line-height: 1.5;
}
.checklist label.check-missing { color: var(--danger); }
.checklist label.check-missing input[type=checkbox] {
    outline: 2px solid var(--danger);
    outline-offset: 2px;
}

/* ==================================================================
   客戶簽名：全螢幕簽名板
   刻意全部寫死淺色（不吃深色主題的變數）——簽名是要印在收執聯上的文件影像，
   必須永遠是白底黑字，不能因為師傅手機開了深色模式就變成深色底。
   ================================================================== */
.sign-cta {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    width: 100%;
    padding: 22px 20px;
    font-size: 17px;
    font-weight: bold;
    border: 1px dashed #7fa8b4;
    border-radius: 10px;
    background: rgba(15,126,163,0.06);
    color: var(--brand-dark);
    cursor: pointer;
}
.sign-cta svg { width: 22px; height: 22px; stroke: currentColor; fill: none; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.sign-done { display: flex; align-items: center; gap: 12px; }
.sign-done img { width: 150px; border: 1px solid var(--line); border-radius: 6px; background: #fff; }
.sign-done-info { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }
.sign-ok { color: #1b7a35; font-weight: bold; font-size: 14px; }
html[data-theme="dark"] .sign-ok { color: #6ed08c; }

.sig-overlay {
    position: fixed;
    top: 0; right: 0; bottom: 0; left: 0;
    z-index: 200;
    display: none;
    background: #fff;
    touch-action: none;
    overscroll-behavior: contain;
}
.sig-overlay.is-open { display: block; }
/* 尺寸與 transform 由 signature-pad.js 依實際畫面算出來後設定 */
.sig-rot { position: absolute; top: 0; left: 0; display: flex; flex-direction: column; background: #fff; }
.sig-bar {
    position: relative;
    flex: 0 0 auto; height: 44px;
    display: flex; align-items: center; justify-content: center;
    background: #15313b; color: #fff;
    font-size: 16px; font-weight: bold; letter-spacing: 0.04em;
}
/* 全螢幕簽名板一定要有出口，否則客戶不簽名時會卡死出不去（2026-09-01 部署後發現）。
   放在標題列最左邊，手機轉正之後就是一般 App 的左上角返回位置。 */
.sig-back {
    position: absolute;
    left: 6px; top: 50%; transform: translateY(-50%);
    padding: 8px 14px;
    background: rgba(255,255,255,0.14);
    border: 1px solid rgba(255,255,255,0.3);
    border-radius: 8px;
    color: #fff;
    font-size: 15px; font-weight: bold;
    cursor: pointer;
}
.sig-back:hover { background: rgba(255,255,255,0.26); }
.sig-hint {
    flex: 0 0 auto; height: 28px;
    display: flex; align-items: center; justify-content: center;
    background: #f4f7f8; color: #5d757c;
    font-size: 13px; border-bottom: 1px solid #e2ebed;
}
.sig-body { flex: 1 1 auto; display: flex; gap: 10px; padding: 10px; min-height: 0; }
.sig-side { flex: 0 0 84px; display: flex; flex-direction: column; gap: 10px; }
.sig-btn {
    flex: 1 1 0;
    display: flex; align-items: center; justify-content: center;
    padding: 0;
    border-radius: 8px;
    font-size: 17px; font-weight: bold;
    writing-mode: vertical-rl;
    text-orientation: upright;
    letter-spacing: 5px;
    cursor: pointer;
}
.sig-clear { background: #fff; color: #c8262a; border: 1px solid #c8262a; }
.sig-ok { background: #0f7ea3; color: #fff; border: 1px solid #0f7ea3; }
.sig-pad {
    position: relative;
    flex: 1 1 auto;
    min-width: 0;
    border: 1px dashed #999;
    border-radius: 8px;
    background: #fff;
    overflow: hidden;
}
.sig-pad canvas { position: absolute; left: 0; top: 0; display: block; touch-action: none; }
.sig-wm {
    position: absolute; top: 0; right: 0; bottom: 0; left: 0;
    display: flex; align-items: center; justify-content: center;
    color: #d8d8d8; font-size: 30px; letter-spacing: 4px;
    pointer-events: none;
}

/* ==================================================================
   師傅收款流程手機版字體放大（.tech-lg）
   由 page_header() 的第四個參數加在 <main> 上，只掛在 tech/dashboard.php、
   confirm.php、qrcode.php 三頁。只在手機寬度生效，電腦版完全不受影響。
   客戶回饋：中年客戶在師傅手機上看不清楚（2026-08-28）。
   ================================================================== */
@media (max-width: 640px) {
    .tech-lg .card h2 { font-size: 21px; }
    .tech-lg .item-row { padding: 12px 0; }
    .tech-lg .item-row > div:first-child { flex: 1 1 auto; min-width: 0; }
    .tech-lg .item-name { font-size: 18px; }
    .tech-lg .text-muted { font-size: 15px; }
    .tech-lg .qty-select { font-size: 18px; width: 84px; padding: 12px 8px; }
    .tech-lg label { font-size: 16px; }
    .tech-lg input[type=text], .tech-lg input[type=number],
    .tech-lg select, .tech-lg textarea { font-size: 18px; }
    .tech-lg .chip-btn { font-size: 15px; padding: 11px 16px; }
    .tech-lg .subtotal-box { font-size: 16px; }
    .tech-lg .total-box { font-size: 26px; }
    /* 字放大後欄寬變緊，左右內距收窄一點，免得「數量」這種兩字標題被擠成兩行 */
    .tech-lg table th, .tech-lg table td { font-size: 16px; padding: 10px 4px; }
    .tech-lg table th:first-child, .tech-lg table td:first-child { padding-left: 0; }
    .tech-lg table th:last-child, .tech-lg table td:last-child { padding-right: 0; text-align: right; }
    .tech-lg .checklist label, .tech-lg .checkbox-label { font-size: 17px; }
    .tech-lg .checklist input[type=checkbox],
    .tech-lg .checkbox-label input[type=checkbox] { width: 20px; height: 20px; }
    .tech-lg .status-badge { font-size: 15px; }
    .tech-lg .btn { font-size: 18px; padding: 14px 20px; }
    .tech-lg .btn-sm { font-size: 15px; padding: 8px 14px; }
    .tech-lg .btn-back { font-size: 16px; padding: 11px 16px; }
    .tech-lg .sign-cta { font-size: 18px; }
    .tech-lg .check-alert { font-size: 16px; }
}
