/*
 * 洗臉熊後台 — 共用設計系統（第一次鍍金）
 * 深色側欄 + 淺色內容區的精品後台風格：token 化配色/間距/圓角/陰影，
 * 並直接套用到既有的通用元素（table/button/form/...），
 * 讓所有既有頁面不用逐一改 HTML 就能繼承新外觀。
 */

:root {
  --color-brand: #c9a961;
  --color-brand-dark: #a8863f;
  --color-brand-light: #e4cd8f;
  --color-brand-soft: #f6efdd;

  --sidebar-bg-top: #202027;
  --sidebar-bg-bottom: #16161b;
  --sidebar-border: #2b2b34;
  --sidebar-text: #c4c2ce;
  --sidebar-text-active: #ffffff;
  --sidebar-group-title: #918fa0;

  --bg-page: #f5f4f1;
  --bg-card: #ffffff;
  --border-soft: #e8e6e0;
  --border-softer: #f0efea;

  --text-primary: #201f24;
  --text-secondary: #6f6d78;
  --text-muted: #9997a2;

  --status-yellow-bg: #fdf3dc; --status-yellow-text: #9a7716;
  --status-green-bg: #e2f4e7;  --status-green-text: #297a45;
  --status-blue-bg: #e5eefc;   --status-blue-text: #2f5fa8;
  --status-purple-bg: #ece8fb; --status-purple-text: #5b4aa8;
  --status-gray-bg: #edecef;   --status-gray-text: #6b6976;
  --status-red-bg: #fbe8e8;    --status-red-text: #b13d3d;

  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 20px;
  --radius-pill: 999px;

  --shadow-sm: 0 1px 2px rgba(24,20,10,0.05), 0 1px 1px rgba(24,20,10,0.04);
  --shadow-md: 0 10px 24px rgba(24,20,10,0.08), 0 2px 6px rgba(24,20,10,0.05);
  --shadow-lg: 0 20px 48px rgba(24,20,10,0.14), 0 6px 14px rgba(24,20,10,0.06);

  --space-1: 4px; --space-2: 8px; --space-3: 12px; --space-4: 16px;
  --space-5: 24px; --space-6: 32px; --space-7: 48px;

  --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", "Microsoft JhengHei",
               "Noto Sans TC", "PingFang TC", sans-serif;

  --ease-standard: cubic-bezier(.4, 0, .2, 1);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg-page);
  color: var(--text-primary);
  font-family: var(--font-sans);
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

/* 擋整頁邊界的 iOS 橡皮筋彈動：只給明確加上這個 class 的頁面（見 base.html 的
   body_class block，例如 app/templates/schedule.html），不是全站的 html,body
   規則。曾經全站下過這條（b16606a），結果場務表（/admin/board）出現橡皮筋、
   點任何按鈕都跳回頁首——場務表大量用 position:fixed 的「portal」技巧
   （appt_status_menu.js／day_view_fold_cell.js）逃開 .day-view-grid-wrap 的
   overflow 裁切，這類動態插入 fixed 元素的頁面，在觸控裝置上跟全站
   overscroll-behavior:none 互動會出現捲動位置被重置的已知瀏覽器行為。改回只給
   明確需要的頁面加這個 class，不要再動全站的 html,body。 */
.no-bounce-page {
  overscroll-behavior: none;
}

h1, h2, h3 { font-weight: 600; letter-spacing: -0.01em; color: var(--text-primary); }
h1 { font-size: 1.6rem; margin: 0 0 var(--space-5); }
h2 { font-size: 1.2rem; margin: var(--space-6) 0 var(--space-4); }
h3 { font-size: 1.02rem; margin: 0 0 var(--space-2); }
p { color: var(--text-secondary); }

a { color: var(--color-brand-dark); text-decoration: none; transition: color .15s var(--ease-standard); }
a:hover { color: var(--text-primary); }

/* ---------- 版型：深色側欄 + 淺色內容區 ---------- */

.app-shell { display: flex; min-height: 100vh; align-items: stretch; }

.sidebar {
  width: 248px;
  flex-shrink: 0;
  background: linear-gradient(180deg, var(--sidebar-bg-top), var(--sidebar-bg-bottom));
  color: var(--sidebar-text);
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  transition: width .25s var(--ease-standard);
  scrollbar-width: thin;
}
.sidebar.collapsed { width: 76px; }
.sidebar.collapsed .nav-label,
.sidebar.collapsed .nav-group-title,
.sidebar.collapsed .brand-text,
.sidebar.collapsed .sub-link { display: none; }
.sidebar.collapsed .brand { justify-content: center; padding: 22px 0; }
.sidebar.collapsed .nav-item, .sidebar.collapsed .nav-group a { justify-content: center; padding: 12px 0; }

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 22px 22px 20px;
  border-bottom: 1px solid var(--sidebar-border);
  color: #fff;
}
.brand-emoji { font-size: 1.6rem; line-height: 1; }
.brand-text { font-weight: 700; font-size: 1.15rem; letter-spacing: .02em; }
.brand-sub { display: block; font-size: .74rem; font-weight: 400; color: var(--color-brand-light); letter-spacing: .08em; margin-top: 3px; }

.sidebar nav { flex: 1; padding: var(--space-3) 0 var(--space-5); }

.nav-item, .nav-group a, .nav-group .nav-disabled {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 13px 22px;
  margin: 2px 10px;
  border-radius: var(--radius-sm);
  color: var(--sidebar-text);
  font-size: 1.04rem;
  line-height: 1.5;
  white-space: nowrap;
  overflow: hidden;
  transition: background .15s var(--ease-standard), color .15s var(--ease-standard), transform .15s var(--ease-standard);
}
.nav-item:hover, .nav-group a:hover {
  background: rgba(255,255,255,0.06);
  color: #fff;
  transform: translateX(2px);
}

/* 「AI 中心」裡還沒做出來的項目：反灰、不可點、不吃 hover 效果，標「建置中」 */
.nav-group .nav-disabled {
  opacity: .4;
  cursor: not-allowed;
  user-select: none;
}
.nav-building-tag {
  margin-left: auto;
  flex-shrink: 0;
  font-size: .66rem;
  font-weight: 600;
  padding: 1px 7px;
  border-radius: 999px;
  background: rgba(255,255,255,0.14);
  color: rgba(255,255,255,0.75);
}
.nav-item.active, .nav-group a.active {
  background: linear-gradient(90deg, rgba(201,169,97,.22), rgba(201,169,97,.08));
  color: #fff;
  font-weight: 600;
  box-shadow: inset 3px 0 0 var(--color-brand);
}
.nav-icon { width: 18px; text-align: center; flex-shrink: 0; opacity: .9; }

.nav-group-title {
  font-size: .92rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--sidebar-group-title);
  padding: 22px 22px 10px;
}
.nav-group .sub-link { font-size: .92rem; opacity: .82; }
.nav-group .nav-group-title {
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  -webkit-tap-highlight-color: transparent;
}
.nav-group .nav-group-title::after {
  content: '▾';
  font-size: .7rem;
  transition: transform .2s var(--ease-standard);
}
.nav-group.group-collapsed .nav-group-title::after { transform: rotate(-90deg); }
.sidebar .nav-group.group-collapsed > :not(.nav-group-title) { display: none; }

.sidebar-footer { padding: var(--space-3); border-top: 1px solid var(--sidebar-border); }
.sidebar-toggle {
  width: 100%;
  background: rgba(255,255,255,0.04);
  border: 1px solid var(--sidebar-border);
  color: var(--sidebar-text);
  border-radius: var(--radius-sm);
  padding: 8px;
  cursor: pointer;
  font-size: .85rem;
  transition: background .15s var(--ease-standard), color .15s var(--ease-standard);
}
.sidebar-toggle:hover { background: rgba(255,255,255,0.09); color: #fff; }

.sidebar-user {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-2); margin-bottom: var(--space-2);
}
.sidebar-user-name { font-size: .78rem; color: var(--sidebar-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sidebar-logout {
  background: transparent; border: 1px solid var(--sidebar-border); color: var(--sidebar-text);
  border-radius: var(--radius-sm); padding: 4px 10px; font-size: .78rem; cursor: pointer;
  transition: background .15s var(--ease-standard), color .15s var(--ease-standard);
}
.sidebar-logout:hover { background: rgba(255,255,255,0.09); color: #fff; }

.main-wrap { flex: 1; min-width: 0; display: flex; flex-direction: column; }

main {
  padding: var(--space-6) var(--space-4);
  max-width: none;
  width: 100%;
  margin: 0 auto;
  animation: page-in .38s var(--ease-standard);
}
@keyframes page-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ---------- 手機版側欄：漢堡抽屜（≤900px；桌面完全不受影響） ---------- */

.mobile-nav-toggle { display: none; }
.mobile-nav-overlay { display: none; }

@media (max-width: 900px) {
  main { padding: var(--space-5); }

  .mobile-nav-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    position: fixed;
    top: 14px;
    left: 14px;
    z-index: 30;
    width: 42px;
    height: 42px;
    border: 1px solid var(--sidebar-border);
    border-radius: var(--radius-sm);
    background: var(--sidebar-bg-top);
    color: #fff;
    font-size: 1.25rem;
    line-height: 1;
    cursor: pointer;
    box-shadow: var(--shadow-md);
  }

  /* 抽屜不擠壓內容——側欄改成 fixed + 位移到畫面外，開啟時疊在內容上面，
     不是把 main-wrap 往右推。 */
  .sidebar {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 26;
    width: 248px;
    transform: translateX(-100%);
    transition: transform .25s var(--ease-standard);
  }
  .sidebar.mobile-open { transform: translateX(0); }

  /* 桌面的「« 收合」是窄版摺疊，跟手機抽屜是兩件事——抽屜裡一律顯示完整
     文字/圖示，不跟著桌面版 localStorage 記住的收合狀態變窄。 */
  .sidebar-toggle { display: none; }
  .sidebar.collapsed { width: 248px; }
  .sidebar.collapsed .nav-label,
  .sidebar.collapsed .nav-group-title,
  .sidebar.collapsed .brand-text,
  .sidebar.collapsed .sub-link { display: initial; }
  .sidebar.collapsed .brand { justify-content: flex-start; padding: 22px 22px 20px; }
  .sidebar.collapsed .nav-item, .sidebar.collapsed .nav-group a { justify-content: flex-start; padding: 13px 22px; }

  .mobile-nav-overlay {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 25;
    background: rgba(16,16,20,0.45);
    opacity: 0;
    pointer-events: none;
    transition: opacity .25s var(--ease-standard);
  }
  .mobile-nav-overlay.visible { opacity: 1; pointer-events: auto; }

}

/* ---------- 卡片 ---------- */

.card {
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: var(--space-5);
  transition: box-shadow .2s var(--ease-standard), transform .2s var(--ease-standard);
}
.card:hover { box-shadow: var(--shadow-md); }

/* ---------- 表格 ---------- */

table {
  border-collapse: separate;
  border-spacing: 0;
  width: 100%;
  margin-bottom: var(--space-5);
  background: var(--bg-card);
  border-radius: var(--radius-md);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
  border: 1px solid var(--border-soft);
}
th, td {
  padding: 11px 14px;
  text-align: left;
  border-bottom: 1px solid var(--border-softer);
  font-size: .92rem;
}
th {
  background: #fbfaf7;
  color: var(--text-secondary);
  font-weight: 600;
  font-size: .78rem;
  text-transform: uppercase;
  letter-spacing: .04em;
}
tr:last-child td { border-bottom: none; }
tbody tr { transition: background .15s var(--ease-standard); }
tbody tr:hover { background: #faf8f4; }

/* ---------- 表單 ---------- */

form.inline { display: inline; }
fieldset {
  margin-top: var(--space-5);
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  padding: var(--space-4) var(--space-5);
}
legend { font-weight: 600; padding: 0 6px; color: var(--text-primary); }
label { display: block; margin: var(--space-3) 0 var(--space-1); font-size: .88rem; color: var(--text-secondary); font-weight: 500; }

input, select, textarea {
  padding: 9px 12px;
  width: 260px;
  max-width: 100%;
  font-family: inherit;
  font-size: .92rem;
  color: var(--text-primary);
  background: #fff;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-sm);
  transition: border-color .15s var(--ease-standard), box-shadow .15s var(--ease-standard);
}
/* 上面那條 width:260px 是為文字輸入框設計的，對 checkbox / radio 沒有任何意義，
   卻會把它們撐成 260px——表格裡的勾選框把整個第一欄撐到 279~401px（實測
   /tickets 401、/staff 360、/services 295、/customers 279，合理值約 48）。
   商品主檔頁 2026-08-04 已經為此單獨修過一次（.product-list-table 那兩條），
   全站還有 46 處同樣被撐寬；與其每張表各補一次（新增一張表就再犯一次），
   這裡直接把根因收掉。

   🔴 位置很重要：這條的具體度是 (0,1,1)，跟「class + 泛用 input」那類規則
   （例如 .staff-color-swatch-option input { width: 0 }，那是刻意把原生 radio
   藏起來換成色塊）完全相同，平手時靠原始碼順序決勝。所以它必須緊接在全域規則
   後面、排在所有 class 規則之前，那些刻意設定才不會被這條蓋掉。
   比它更具體的（.ticket-switch-row 22px、.tablet-calendar-filter 20px）本來就贏。 */
input[type="checkbox"], input[type="radio"] { width: auto; }
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--color-brand);
  box-shadow: 0 0 0 3px rgba(201,169,97,0.18);
}
textarea { width: 100%; min-height: 90px; }

/* ---------- 按鈕 ---------- */

button, .btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 9px 18px;
  margin-top: var(--space-3);
  cursor: pointer;
  font-family: inherit;
  font-size: .9rem;
  font-weight: 600;
  color: #fff;
  background: linear-gradient(180deg, #2a2a32, #1c1c22);
  border: none;
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-sm);
  transition: transform .12s var(--ease-standard), box-shadow .12s var(--ease-standard), background .12s var(--ease-standard);
}
button:hover, .btn:hover {
  transform: translateY(-1px);
  box-shadow: var(--shadow-md);
  color: #fff;
}
button:active, .btn:active { transform: translateY(0); }

.danger {
  background: linear-gradient(180deg, #d1544f, #b23d3d);
}

/* ---------- 橫向表單列（新增分類／新增服務項目） ---------- */

.row-form {
  display: flex;
  align-items: flex-end;
  gap: var(--space-4);
  flex-wrap: wrap;
}
.row-form label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 0;
  width: auto;
}
.row-form label.checkbox-label {
  flex-direction: row;
  align-items: center;
  gap: 6px;
}
.row-form input, .row-form select { width: auto; min-width: 130px; }
.row-form button { margin-top: 0; }

/* ---------- 進貨單品項列 ---------- */

.po-item-row {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  flex-wrap: wrap;
  padding: 6px 0;
}
.po-item-row select { min-width: 220px; }
.po-item-row input[type="number"] { width: auto; min-width: 90px; }

/* ---------- 分類主檔就地編輯（表格內的輸入框不用預設 260px 寬） ---------- */

.editable-row-table td input[type=text],
.editable-row-table td select { width: 100%; min-width: 90px; }

/* ---------- 圖片拖放上傳 ---------- */

.dropzone {
  width: 110px;
  min-height: 60px;
  padding: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  font-size: .78rem;
  color: var(--text-secondary);
  border: 1px dashed var(--border-soft);
  border-radius: var(--radius-sm);
  cursor: pointer;
  background: #fff;
}
.dropzone.dropzone-hover { border-color: var(--color-brand); background: rgba(201,169,97,0.08); }
.dropzone-thumb { max-width: 100%; max-height: 54px; object-fit: cover; border-radius: 4px; }

/* ---------- 訊息條 ---------- */

.msg {
  background: var(--status-green-bg);
  color: var(--status-green-text);
  padding: 12px 16px;
  margin-bottom: var(--space-4);
  border-radius: var(--radius-sm);
  border: 1px solid rgba(41,122,69,0.15);
}
/* 場務表結帳完成的輕量提示：沿用既有的 .msg 外觀，只加 flex 排版跟關閉鈕
   （見 app/order_ui.py 的 _board_redirect_after_signature、app/appointment_admin.py
   的 board()）——不是 position:fixed，一般文件流裡的區塊，不會跟場務表既有的
   position:fixed portal 元素（appt_status_menu.js／day_view_fold_cell.js）或
   捲動行為互相干擾。 */
.board-notice { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); }
.board-notice-close {
  background: none; border: none; cursor: pointer; font-size: 1.1rem; line-height: 1;
  color: inherit; padding: 0 4px; width: auto;
}
.error {
  background: var(--status-red-bg);
  color: var(--status-red-text);
  padding: 12px 16px;
  margin-bottom: var(--space-4);
  border-radius: var(--radius-sm);
  border: 1px solid rgba(177,61,61,0.15);
}
.hint {
  color: var(--text-muted);
  font-size: .82rem;
  margin: 4px 0 0;
}

/* ---------- 批次操作列 ---------- */

.batch-bar {
  background: var(--color-brand-soft);
  border: 1px solid rgba(201,169,97,0.35);
  border-radius: var(--radius-md);
  padding: 12px 16px;
  margin: -8px 0 20px;
}
.batch-bar form { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.batch-bar select, .batch-bar input[type=text] { width: auto; padding: 7px 10px; }
.batch-bar button { margin-top: 0; }

/* ---------- 狀態徽章（下拉本身統一走精品風格） ---------- */

select.status-switch-select {
  width: auto;
  padding: 6px 10px;
  border-radius: var(--radius-pill);
  font-size: .82rem;
  font-weight: 600;
  border: 1px solid var(--border-soft);
  background: #fff;
}

.badge {
  display: inline-block;
  padding: 3px 11px;
  border-radius: var(--radius-pill);
  font-size: .78rem;
  font-weight: 600;
}
.badge-yellow { background: var(--status-yellow-bg); color: var(--status-yellow-text); }
.badge-green  { background: var(--status-green-bg);  color: var(--status-green-text); }
.badge-blue   { background: var(--status-blue-bg);   color: var(--status-blue-text); }
.badge-purple { background: var(--status-purple-bg); color: var(--status-purple-text); }
.badge-gray   { background: var(--status-gray-bg);   color: var(--status-gray-text); }
.badge-red    { background: var(--status-red-bg);    color: var(--status-red-text); }

/* ---------- 預約卡片（場務表／總覽右側列表共用） ---------- */

.appt-card {
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-md);
  padding: 12px 14px;
  margin-bottom: 10px;
  background: #fff;
  box-shadow: var(--shadow-sm);
  transition: box-shadow .18s var(--ease-standard), transform .18s var(--ease-standard);
  animation: card-in .3s var(--ease-standard);
}
.appt-card:hover { box-shadow: var(--shadow-md); transform: translateY(-1px); }
@keyframes card-in {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.appt-card.status-system_accepted { border-left: 4px solid #e8c76b; }
.appt-card.status-confirmed       { border-left: 4px solid #4caf7d; }
.appt-card.status-arrived         { border-left: 4px solid #4a90d9; }
.appt-card.status-billed          { border-left: 4px solid #9b8ac4; background: #fbfaf8; }
.appt-card.status-cancelled,
.appt-card.status-no_show         { border-left: 4px solid #c9c7d1; opacity: .72; }

/* ---------- 儀表板：KPI 卡 + 圖表 placeholder ---------- */

.kpi-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--space-5);
  margin-bottom: var(--space-6);
}
.kpi-card {
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  box-shadow: var(--shadow-sm);
  position: relative;
  overflow: hidden;
  transition: box-shadow .2s var(--ease-standard), transform .2s var(--ease-standard);
}
.kpi-card:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
.kpi-card::before {
  content: "";
  position: absolute; top: 0; left: 0; right: 0; height: 3px;
  background: linear-gradient(90deg, var(--color-brand), var(--color-brand-light));
}
.kpi-label { font-size: .8rem; color: var(--text-muted); font-weight: 600; letter-spacing: .02em; }
.kpi-value { font-size: 2rem; font-weight: 700; margin-top: 6px; color: var(--text-primary); letter-spacing: -0.02em; }
.kpi-sub { font-size: .8rem; color: var(--text-muted); margin-top: 4px; }
.kpi-trend { font-size: .78rem; font-weight: 600; padding: 2px 8px; border-radius: var(--radius-pill); display: inline-block; margin-top: 8px; }
.kpi-trend.up   { background: var(--status-green-bg);  color: var(--status-green-text); }
.kpi-trend.down { background: var(--status-red-bg);    color: var(--status-red-text); }
.kpi-trend.flat { background: var(--status-gray-bg);   color: var(--status-gray-text); }

.dash-grid {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: var(--space-5);
}
@media (max-width: 900px) { .dash-grid { grid-template-columns: 1fr; } }

.mobile-ops-period {
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: var(--space-4) var(--space-5);
  margin-bottom: var(--space-4);
}
.mobile-ops-period h3 { margin: 0 0 var(--space-3); font-size: .95rem; }
.mobile-ops-row {
  display: flex; justify-content: space-between; align-items: baseline;
  padding: 8px 0; border-bottom: 1px solid var(--border-soft);
  color: inherit; text-decoration: none;
}
.mobile-ops-row:last-child { border-bottom: none; }
.mobile-ops-row .mobile-ops-label { font-size: .84rem; color: var(--text-muted); }
.mobile-ops-row .mobile-ops-value { font-weight: 700; color: var(--text-primary); }
.mobile-ops-counts {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-3);
  margin-bottom: var(--space-5);
}
.mobile-ops-counts a {
  display: block; text-align: center; text-decoration: none; color: inherit;
  background: var(--bg-card); border: 1px solid var(--border-soft); border-radius: var(--radius-lg);
  padding: var(--space-4); box-shadow: var(--shadow-sm);
}
.mobile-ops-counts .mobile-ops-count-value { font-size: 1.5rem; font-weight: 700; color: var(--text-primary); }
.mobile-ops-counts .mobile-ops-count-label { font-size: .78rem; color: var(--text-muted); margin-top: 2px; }

/* 儀表板即時狀態列 + 所選期間業績卡片：跟 .mobile-ops-summary 用一樣的視覺元件
   （.mobile-ops-counts/.mobile-ops-period/.mobile-ops-row 本身沒有 display:none，
   只有 .mobile-ops-summary 這個外層才有），但桌面版也要看得到，不能沿用會被
   隱藏的外層 class——這正是老闆之前看不到「上月」的根本原因。 */
.dashboard-live-summary { margin-bottom: var(--space-5); }
.dashboard-live-note { font-size: .8rem; color: var(--text-muted); margin: 0 0 var(--space-3); }
.dashboard-period-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--space-4);
  margin-bottom: var(--space-6);
}

.dashboard-period-picker {
  display: flex; flex-wrap: wrap; gap: var(--space-4);
  margin-bottom: var(--space-3);
}
.period-picker-form {
  display: flex; align-items: center; gap: var(--space-2);
  background: var(--bg-card); border: 1px solid var(--border-soft); border-radius: var(--radius-lg);
  padding: var(--space-3) var(--space-4); box-shadow: var(--shadow-sm);
}
.period-picker-form.active { border-color: var(--color-brand); }
.period-picker-form label { font-size: .8rem; color: var(--text-muted); white-space: nowrap; }
.dashboard-period-label { font-size: .85rem; color: var(--text-muted); margin-bottom: var(--space-5); }

.chart-card {
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  box-shadow: var(--shadow-sm);
  margin-bottom: var(--space-5);
}
.chart-card h3 { display: flex; align-items: center; justify-content: space-between; }
.chart-placeholder-note { font-size: .74rem; color: var(--text-muted); font-weight: 500; background: var(--status-gray-bg); padding: 2px 10px; border-radius: var(--radius-pill); }

.trend-bar-chart {
  height: 180px;
  display: flex;
  align-items: flex-end;
  gap: 6px;
  padding-top: 10px;
}
.trend-bar-chart .bar {
  flex: 1;
  background: linear-gradient(180deg, var(--color-brand-light), var(--color-brand));
  border-radius: 6px 6px 2px 2px;
  animation: bar-grow .6s var(--ease-standard) both;
  opacity: .85;
}
.trend-bar-chart .bar:hover { opacity: 1; }
@keyframes bar-grow {
  from { transform: scaleY(0); transform-origin: bottom; }
  to   { transform: scaleY(1); transform-origin: bottom; }
}

.rank-list { list-style: none; margin: 0; padding: 0; }
.rank-list li {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 0; border-bottom: 1px solid var(--border-softer);
  font-size: .9rem;
}
.rank-list li:last-child { border-bottom: none; }
.rank-list .rank-name { display: flex; align-items: center; gap: 10px; color: var(--text-primary); font-weight: 500; }
.rank-list .rank-num {
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--status-gray-bg); color: var(--text-secondary);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: .72rem; font-weight: 700;
}
.rank-list li:nth-child(1) .rank-num { background: var(--color-brand-soft); color: var(--color-brand-dark); }
.rank-list .rank-value { color: var(--text-secondary); font-weight: 600; }

/* ---------- 預約總覽：篩選列 ---------- */

.overview-filter-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin-bottom: var(--space-4);
}
.overview-filter-nav { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.overview-filter-controls { display: flex; align-items: center; gap: 20px; flex-wrap: wrap; }
.inline-label {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-size: .86rem;
  color: var(--text-secondary);
  font-weight: 500;
}
.inline-label select { width: auto; padding: 7px 12px; margin: 0; }
.checkbox-label input[type=checkbox] { width: auto; accent-color: var(--color-brand-dark); }

/* 「查看預約」複選下拉：標題文字固定不隨勾選變動，外觀比照既有的單選
   「工作人員」<select>（同樣的邊框/底色/字級），機制仍是 checkbox 複選面板，
   不共用同一個 <select>、也不改回單選。
   面板預設收合：用 :not([hidden]) 讓 CSS 的 display:flex 只在沒有 hidden
   屬性時生效，不然 author 規則的 display:flex 會蓋掉 [hidden] 的
   UA 預設 display:none，導致一進頁面面板就是展開的。 */
.staff-multiselect { position: relative; }
.staff-multiselect-toggle {
  padding: 9px 12px; border: 1px solid var(--border-soft); border-radius: var(--radius-sm);
  background: var(--bg-card); font-size: .92rem; font-weight: 500; color: var(--text-primary);
  cursor: pointer; display: inline-flex; align-items: center; gap: 8px; margin-top: 0;
}
/* 全站 button:hover 預設會把文字改成白色（配深色底），這顆按鈕底色是白的、
   不能沿用那套 hover 色，不然 hover 時字會看起來消失。 */
.staff-multiselect-toggle:hover { color: var(--text-primary); box-shadow: none; transform: none; }
.staff-multiselect-toggle.active { border-color: var(--color-brand-dark); color: var(--color-brand-dark); }
.staff-multiselect-toggle.active:hover { color: var(--color-brand-dark); }
.staff-multiselect-toggle-arrow {
  font-size: .7rem; color: var(--text-secondary); transition: transform .15s var(--ease-standard);
}
.staff-multiselect-toggle.active .staff-multiselect-toggle-arrow { transform: rotate(180deg); }
.staff-multiselect-panel:not([hidden]) {
  position: absolute; z-index: 20; top: calc(100% + 4px); left: 0; min-width: 160px;
  display: flex; flex-direction: column; gap: 4px; padding: 10px 12px;
  border: 1px solid var(--border-soft); border-radius: var(--radius-sm);
  background: var(--bg-card); box-shadow: var(--shadow-md);
}
.staff-multiselect-option { display: flex; align-items: center; gap: 6px; font-size: .84rem; font-weight: 500; white-space: nowrap; }
.staff-multiselect-option input[type=checkbox] { width: auto; accent-color: var(--color-brand-dark); }

/* ---------- 預約總覽：狀態統計摘要列 ---------- */

.status-summary {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 14px;
  margin: 0 0 var(--space-4);
}
.status-chip {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: .86rem;
  color: var(--text-secondary);
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  padding: 7px 15px;
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-sm);
  animation: chip-in .32s var(--ease-standard) both;
}
.status-chip strong { color: var(--text-primary); font-size: .96rem; }
.status-chip:nth-child(1) { animation-delay: .02s; }
.status-chip:nth-child(2) { animation-delay: .06s; }
.status-chip:nth-child(3) { animation-delay: .10s; }
.status-chip:nth-child(4) { animation-delay: .14s; }
.status-chip:nth-child(5) { animation-delay: .18s; }
.status-chip:nth-child(6) { animation-delay: .22s; }
@keyframes chip-in {
  from { opacity: 0; transform: translateY(5px); }
  to   { opacity: 1; transform: translateY(0); }
}

.status-dot { width: 9px; height: 9px; border-radius: 50%; display: inline-block; flex-shrink: 0; }
.status-dot.dot-system_accepted { background: #e8c76b; }
.status-dot.dot-confirmed       { background: #4caf7d; }
.status-dot.dot-arrived         { background: #4a90d9; }
.status-dot.dot-billed          { background: #9b8ac4; }
.status-dot.dot-no_show         { background: #b7b5c0; }
.status-dot.dot-cancelled       { background: #c9807f; }

/* ---------- 預約總覽：放大版月曆 ---------- */

/* table-layout:fixed 是真機裁切的根因修復：預設 table-layout:auto 只把
   td 的 width:14% 當初始建議值，內容（客人姓名、狀態行文字）需要更多空間時
   auto 排版照樣讓整張表撐寬超過容器——桌機因為容器夠寬、撐寬不明顯看不出來，
   平板全螢幕模式的 <main> 是 overflow-x:hidden（見本檔案 html.tablet-fullscreen
   main 那段），撐寬的部分直接被裁掉，週日整欄消失。改成 fixed 後 14% 是真的
   絕對比例，7 欄永遠等分容器寬度、不會撐寬，內容超出就在儲存格內裁斷/摺行
   （既有的 ellipsis/DAY_CELL_MAX_LINES 機制接住），不是讓整張表變寬。 */
.overview-calendar { table-layout: fixed; }
.overview-calendar th { padding: 14px; font-size: .82rem; text-align: center; }
.overview-calendar td {
  vertical-align: top;
  height: 108px;
  width: 14%;
  padding: 0;
  transition: background .15s var(--ease-standard);
}
.overview-calendar td:hover { background: var(--color-brand-soft); }
.overview-calendar td.calendar-cell-out { background: #fbfaf7; color: var(--text-muted); }
.overview-calendar td.calendar-cell-out:hover { background: #efece4; }
.overview-calendar td.calendar-cell-selected { box-shadow: inset 0 0 0 2px var(--color-brand); border-radius: var(--radius-sm); }
/* 今天那格：柔和的淡奶油金背景，跟白色區分但不刺眼；日期數字沿用既有的 .day-num-today 高亮，不動它。 */
.overview-calendar td.calendar-cell-today { background: rgba(201, 169, 97, 0.10); }
.overview-calendar td.calendar-cell-today:hover { background: var(--color-brand-soft); }
/* 日期獨立一行、置中放在格子最上方（沿用神美月曆的版型），底下內容區
   （狀態行 + 客人姓名）用整格寬度左右分配——不是日期跟狀態擠在左欄、
   客人姓名被壓到剩 45% 那種版面。桌機/平板同一套，不分斷點。 */
.overview-calendar .day-num { font-size: 1.12rem; font-weight: 500; text-align: center; }
.overview-calendar .day-num-today { font-weight: 700; color: var(--color-brand-dark); }
.overview-calendar a {
  display: flex; flex-direction: column; gap: 4px;
  height: 100%; padding: 14px; box-sizing: border-box; text-decoration: none; color: inherit;
}
.day-cell-content { display: flex; align-items: flex-start; justify-content: space-between; gap: 6px; width: 100%; min-width: 0; }
.day-cell-left { flex: 1; min-width: 0; }
/* 「查看預約」複選勾選後才會出現的右側客人姓名區，跟左側狀態徽章各自獨立摺疊
   （各自算各自的 DAY_CELL_MAX_LINES 上限），版面上是分開的兩欄，不是同一份清單。
   左右均分（flex:1 對 flex:1），不再固定卡在 45% 上限。 */
.day-cell-right { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; align-items: flex-end; text-align: right; }
/* 只顯示姓名（客戶等級徽章已移除，見 admin_overview.html）。維持單行不換行，
   月曆格高度才不會變得不可預期；DAY_CELL_MAX_LINES 摺疊算的是「幾個客人」
   不是「畫面幾行」，這裡只是同一行變寬，摺疊筆數不受影響。 */
.day-staff-customer-line {
  display: flex; align-items: center; justify-content: flex-end; gap: 3px;
  font-size: .66rem; font-weight: 600; max-width: 100%;
}
.day-staff-customer-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.day-staff-customer-line .staff-color-tag { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: inline-block; }

.day-status-lines { display: flex; flex-direction: column; gap: 2px; align-items: flex-start; }
.day-status-line {
  display: flex; align-items: center; gap: 4px; max-width: 100%;
  font-size: .66rem; font-weight: 600; color: var(--text-secondary);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.day-status-line .status-dot { flex-shrink: 0; }
.day-status-line-overflow { font-size: .66rem; color: var(--text-muted); margin-top: 1px; }

/* 手機預約總覽：390px 左右的畫面無法在 7 個約 55px 的欄位中同時顯示
   狀態與客人姓名。只在手機斷點把既有桌機月曆變成可橫向滑動的寬表格；
   桌機／平板仍沿用上面的 7 欄 table-layout:fixed，不改其尺寸與裁切規則。
   月曆內的資料、點日開啟單日檢視、工作人員篩選與查看預約複選都沿用
   原本 DOM/JS，這裡只給每一天足夠的可讀寬度。 */
@media (max-width: 600px) {
  .overview-filter-controls {
    width: 100%;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 10px;
  }
  .overview-filter-controls > .inline-label:first-child {
    min-width: 0;
  }
  .overview-filter-controls > .inline-label:first-child select {
    min-width: 0;
    max-width: 100%;
  }
  .overview-filter-controls .checkbox-label {
    grid-column: 1 / -1;
  }
  .staff-multiselect-panel:not([hidden]) {
    right: 0;
    left: auto;
    max-width: calc(100vw - 32px);
  }
  .calendar-wrap {
    overflow-x: auto;
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
    touch-action: pan-x pan-y;
  }
  .calendar-wrap::before {
    content: "↔ 左右滑動查看更多日期";
    display: block;
    width: max-content;
    margin: 0 0 8px;
    color: var(--text-muted);
    font-size: .72rem;
    font-weight: 600;
  }
  .overview-calendar {
    width: 980px;
    min-width: 980px;
  }
  .overview-calendar th {
    padding: 10px;
  }
  .overview-calendar td {
    width: 140px;
    height: 154px;
  }
  .overview-calendar a {
    padding: 10px;
  }
  .overview-calendar .day-num {
    font-size: 1rem;
  }
  .day-status-line,
  .day-staff-customer-line,
  .day-status-line-overflow {
    font-size: .72rem;
  }
}

/* ---------- #113 結帳工作台：整列可點，實際動作沿用場務表「開始結帳」同一顆
   連結/表單（見 checkout_board.js），這裡只做視覺呈現。 ---------- */
/* 每位美容師各自一張 <table>、內容多寡不同，table-layout:auto 會讓每張表各自算
   出不一樣的欄寬，導致「客人姓名」「電話」這些欄在不同技師的表格之間對不齊、
   整頁看起來是歪的。改成 table-layout:fixed + 每欄用 <colgroup> 給固定寬度百分比
   （見 checkout_board.html），所有分組表格套用同一組欄寬比例，欄位就能上下對齊——
   桌機的對齊需求不能為了平板拆掉。

   平板窄螢幕欄位撐不開的解法：不共用 .table-scroll-wrap（那個 class 另外還給
   .table-scroll-wrap table 訂了 min-width:max-content，是給別頁 auto 版面表格用的，
   混進來會跟這裡的 table-layout:fixed 打架），改用專屬的 .checkout-table-scroll
   容器——桌機寬度夠時 table 隨容器撐滿 100%；容器窄於 min-width(900px) 時，
   維持 900px 不縮、改成整張表橫向捲動，欄位比例/對齊完全不變，不是靠隱藏
   欄位或縮字解決。overflow-x:auto 選最一般的捲動方式，不用 position:fixed、
   也不鎖 overscroll-behavior——iPad Safari 的橡皮筋問題踩過，這裡不重踩。 */
.checkout-table-scroll { overflow-x: auto; max-width: 100%; -webkit-overflow-scrolling: touch; }
.checkout-table { table-layout: fixed; width: 100%; min-width: 900px; }
.checkout-table th,
.checkout-table td {
  padding: 8px 12px; overflow-wrap: break-word;
}
.checkout-table th { text-align: left; white-space: nowrap; }
.checkout-col-num { text-align: right; white-space: nowrap; }
.checkout-col-name { width: 14%; }
.checkout-col-phone { width: 12%; }
.checkout-col-balance { width: 9%; }
.checkout-col-voucher { width: 9%; }
.checkout-col-last-consumption { width: 18%; }
.checkout-col-today { width: 18%; }
.checkout-col-source { width: 8%; }
.checkout-col-op { width: 12%; }
.checkout-row { cursor: pointer; }
.checkout-row:hover { background: var(--bg-page); }
.checkout-action { cursor: default; }
.checkout-action-form { margin: 0; }
.checkout-action-link {
  display: inline-block; padding: 5px 14px; border-radius: var(--radius-sm);
  background: var(--color-brand); color: #fff; font-size: .82rem; font-weight: 600;
  border: none; cursor: pointer; text-decoration: none;
}

.status-dot.dot-staff-leave  { background: #a68a64; }
.status-dot.dot-store-closed { background: #b13d3d; }

/* ---------- 預約總覽：單日檢視（技師一欄一人，時間由上而下） ---------- */

.day-view-grid-wrap {
  display: flex; gap: 1px; background: var(--border-soft);
  overflow-x: auto; border: 1px solid var(--border-soft); border-radius: var(--radius-md);
}
.day-view-time-col {
  flex: 0 0 56px; display: flex; flex-direction: column; background: var(--bg-card);
  position: sticky; left: 0; z-index: 5;
}
.day-view-time-col .day-view-staff-name { visibility: hidden; }
.day-view-time-rows { display: grid; }
.day-view-time-label {
  display: flex; align-items: center; justify-content: center;
  font-size: .7rem; color: var(--text-muted); border-bottom: 1px solid var(--border-softer);
}
.day-view-staff-col { flex: 1 1 260px; min-width: 260px; background: var(--bg-card); display: flex; flex-direction: column; }
.day-view-staff-name {
  padding: 8px; font-weight: 600; font-size: .85rem; text-align: center;
  border-bottom: 1px solid var(--border-soft); background: #fbfaf7;
}
.day-view-staff-off .day-view-staff-name { background: #ece9e3; }
.day-view-off-fill { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; padding: 20px 8px; background: #f2f1ee; }
.day-view-leave-tag {
  font-size: .74rem; color: var(--text-secondary); background: var(--status-gray-bg);
  padding: 3px 10px; border-radius: var(--radius-pill);
}
.day-view-leave-note {
  font-size: .72rem; color: var(--text-secondary); max-width: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; cursor: help;
}
.day-view-leave-banner {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  font-size: .68rem; color: var(--status-yellow-text); background: var(--status-yellow-bg);
  padding: 4px 8px; border-bottom: 1px solid var(--border-softer);
}
.day-view-cells { display: grid; position: relative; }
.day-view-cell { grid-column: 1; border-bottom: 1px solid var(--border-softer); }
.day-view-cell-off { background: #f2f1ee; }
.day-view-cell-closed {
  display: flex; align-items: center; justify-content: center; text-align: center;
  color: var(--status-yellow-text); background: var(--status-yellow-bg);
  font-size: .7rem; font-weight: 600; padding: 2px 4px; box-sizing: border-box;
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
}
.day-view-cell-empty {
  display: flex; align-items: center; justify-content: center;
  color: var(--color-brand-dark); text-decoration: none; font-size: .78rem; font-weight: 600;
  background: var(--color-brand-soft); transition: background .12s var(--ease-standard);
  border: none; font-family: inherit; cursor: pointer; padding: 0; margin: 0; width: 100%;
}
.day-view-cell-empty:hover { background: var(--color-brand); color: #fff; }
.day-view-appt-card.appt-card {
  grid-column: 1; margin: 1px 3px; padding: 4px 6px;
  font-size: .7rem; overflow: hidden; z-index: 2;
  display: flex; flex-direction: row; justify-content: space-between; align-items: stretch; gap: 6px;
}
.day-view-appt-left { display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1; overflow: hidden; }
.day-view-appt-middle {
  display: flex; align-items: stretch; justify-content: center; flex: 0 0 25%; min-width: 0;
}
.day-view-appt-middle .appt-card-service-btn {
  flex: 1; display: flex; align-items: center; justify-content: center;
  margin: 0; white-space: normal; line-height: 1.15; text-align: center;
}
.day-view-appt-middle .appt-card-service-done { display: flex; align-items: center; justify-content: center; margin: 0; text-align: center; }
.day-view-appt-right {
  display: flex; flex-direction: column; align-items: stretch; gap: 3px; flex-shrink: 0; width: 92px;
  align-self: stretch; overflow-y: auto;
}
.day-view-appt-time { font-weight: 700; }
.day-view-appt-service, .day-view-appt-customer, .day-view-appt-source, .day-view-appt-member-info, .day-view-appt-note { color: var(--text-secondary); }

/* ---------- 預約卡四角（狀態/編輯/刪除/開單，跟開單頁四角是不同套：卡片窄，狀態下拉
   自己獨立一行維持可操作寬度，編輯/刪除/開單三顆並排在下面一行）---------- */

.appt-card-corners { margin-top: 2px; }
.appt-card-corner-status { font-size: .72rem; margin-bottom: 3px; }
.appt-card-corner-actions { display: flex; gap: 3px; }
.appt-card-corner-bill-form { margin: 0; flex: 1; min-width: 0; }
.appt-card-corner-delete, .appt-card-corner-edit, .appt-card-corner-bill {
  display: inline-block;
  flex: 1;
  min-width: 0;
  box-sizing: border-box;
  padding: 5px 4px;
  font-size: .7rem;
  font-weight: 700;
  border-radius: var(--radius-md);
  border: 1px solid var(--border-soft);
  background: var(--bg-page);
  color: var(--text-primary);
  text-decoration: none;
  text-align: center;
  box-shadow: none;
  margin: 0;
  width: 100%;
}
.appt-card-corner-delete { color: var(--status-red-text); border-color: var(--status-red-bg); }
.appt-card-corner-bill { color: var(--color-brand-dark); border-color: var(--color-brand-light); }
@media (max-width: 600px) {
  .appt-card-corner-delete, .appt-card-corner-edit, .appt-card-corner-bill { padding: 10px 4px; font-size: .8rem; }
}

/* ---------- 預約卡狀態選單（原生 select 換成選單：狀態可逆切換 + 分隔線 + 刪除/
   重置服務時間兩個危險動作，手機優先，選項要大好點）---------- */

.appt-status-menu { position: relative; }
.appt-status-menu-trigger {
  display: flex; align-items: center; justify-content: space-between; gap: 4px;
  width: 100%; box-sizing: border-box; padding: 4px 6px;
  font-size: .7rem; font-weight: 700; font-family: inherit;
  border: 1px solid var(--border-soft); border-radius: var(--radius-md);
  background: #fff; color: var(--text-primary); cursor: pointer; margin: 0;
}
.appt-status-menu-caret { font-size: .6rem; color: var(--text-muted); }
/* .appt-status-menu-list 展開時由 appt_status_menu.js 搬到 document.body、改成
   position:fixed 並用 JS 算好的 top/left 定位（見該檔說明）——卡片格子本身有
   overflow:auto 裁切（日檢視右欄、單日浮層都是），純 CSS 的 absolute/fixed 逃不掉，
   只有整個節點搬出卡片的 DOM 子樹才能真的浮在最上層、不被裁切、也不受格子寬度限制。
   這裡的 CSS 只負責關閉狀態(display:none)跟展開後的外觀，不負責定位。 */
.appt-status-menu-list {
  display: none; z-index: 1000; min-width: 190px;
  background: var(--bg-card); border: 1px solid var(--border-soft); border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg); padding: 4px;
}
.appt-status-menu-list.open { display: block; }
.appt-status-menu-item {
  display: block; width: 100%; box-sizing: border-box; text-align: left;
  padding: 11px 12px; margin: 0; font-size: .88rem; font-weight: 600; font-family: inherit;
  border: none; border-radius: var(--radius-md); background: none; color: var(--text-primary); cursor: pointer;
}
.appt-status-menu-item:hover { background: var(--color-brand-soft); }
.appt-status-menu-item-active { color: var(--color-brand-dark); }
.appt-status-menu-divider { height: 1px; background: var(--border-soft); margin: 4px 2px; }
.appt-status-menu-danger { color: var(--status-red-text); }
.appt-status-menu-danger:hover { background: var(--status-red-bg); }
.appt-status-menu-item:disabled {
  color: var(--text-muted); opacity: .55; cursor: not-allowed; background: none;
}
@media (max-width: 600px) {
  .appt-status-menu-trigger { padding: 10px 10px; font-size: .85rem; }
  .appt-status-menu-list { min-width: 220px; }
  .appt-status-menu-item { padding: 15px 14px; font-size: 1rem; }
}

/* ---------- 場務表：技師分欄版型（桌面依可用寬度自動多欄，平板/手機自然收成單欄）---------- */

.board-columns {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: var(--space-4);
}
@media (max-width: 700px) {
  .board-columns { grid-template-columns: 1fr; }
}

.board-staff-col {
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: var(--space-4);
}
.board-staff-name { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); }
.board-staff-add-link { font-size: .74rem; font-weight: 600; }

/* ---------- 場務表卡：資訊固定排序（時間／客人／服務／狀態標籤），編輯與開始結帳收成
   卡片右上角的次要小按鈕，開始服務／結束服務獨立留在卡片最下面當唯一主要按鈕
   （不跟其他資訊、次要按鈕搶視覺，約 40px 高、好點）---------- */

.board-appt-card { padding-bottom: 10px; }

.board-appt-time-row { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-2); }
.board-appt-time { font-weight: 700; font-size: .92rem; color: var(--text-primary); white-space: nowrap; }

.board-appt-mini-actions { display: flex; gap: 4px; flex-shrink: 0; }
.board-appt-mini-bill-form { margin: 0; }
.board-appt-mini-btn {
  display: inline-block;
  padding: 5px 10px;
  font-size: .72rem;
  font-weight: 700;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-soft);
  background: var(--bg-page);
  color: var(--text-primary);
  text-decoration: none;
  white-space: nowrap;
  margin: 0;
  box-shadow: none;
}
.board-appt-mini-btn:hover { color: var(--text-primary); border-color: var(--color-brand); transform: none; box-shadow: none; }
.board-appt-mini-btn-bill { color: var(--color-brand-dark); border-color: var(--color-brand-light); }

.board-appt-customer { margin-top: 6px; font-weight: 600; font-size: .92rem; color: var(--text-primary); }
.board-appt-customer em { color: var(--text-muted); font-weight: 400; font-style: normal; }
.board-appt-service { margin-top: 2px; font-size: .84rem; color: var(--text-secondary); }

.board-appt-status-tag { margin: 8px 0; }
.board-appt-status-tag .appt-status-menu-trigger {
  width: auto; padding: 3px 10px; font-size: .7rem; border-radius: var(--radius-pill);
}
.board-appt-status-tag:not(:has(.appt-status-menu)) {
  display: inline-block;
  font-size: .74rem;
  font-weight: 600;
  padding: 3px 11px;
  border-radius: var(--radius-pill);
  background: var(--status-purple-bg);
  color: var(--status-purple-text);
}

.board-appt-primary-btn {
  display: block;
  width: 100%;
  margin: 4px 0 0;
  padding: 11px 16px;
  line-height: 1.2;
  font-size: .92rem;
  font-weight: 700;
  border-radius: var(--radius-md);
  text-align: center;
  border: none;
  color: #fff;
}
.board-appt-primary-btn.appt-card-service-start { background: linear-gradient(180deg, var(--color-brand-light), var(--color-brand-dark)); }
.board-appt-primary-btn.appt-card-service-end { background: linear-gradient(180deg, #e08a5c, #c2673a); }

/* 重疊預約的被動延續卡（純顯示，不含互動控制）也沿用同一份資訊排序 */
.board-appt-passive .board-appt-time { font-weight: 700; font-size: .88rem; }
.board-appt-passive .board-appt-customer { margin-top: 4px; font-size: .88rem; }
.board-appt-passive .board-appt-service { font-size: .8rem; }

@media (max-width: 600px) {
  .board-appt-mini-btn { padding: 8px 12px; font-size: .8rem; }
  .board-appt-status-tag .appt-status-menu-trigger { padding: 7px 14px; font-size: .85rem; }
  .board-appt-primary-btn { padding: 14px; font-size: 1rem; }
}

/* 已取消/未到店：縮成單行薄卡，只佔自己這一格（其餘原本佔的格子在 _build_day_view
   就已經釋放成可點的「+」了），視覺上跟著灰掉、不強調。 */
.day-view-appt-card.day-view-appt-collapsed {
  flex-direction: row; align-items: center; align-self: start; height: auto;
  opacity: .68; background: var(--status-gray-bg);
}
.day-view-appt-collapsed .day-view-appt-left { flex-direction: row; gap: 8px; align-items: center; flex-wrap: wrap; }

/* 重疊預約（正常撞單防護不該出現，只有取消/歷史異常資料才會撞在一起）：預設起始最早
   那筆保留完整互動控制，其餘被涵蓋到的幾筆只留純顯示的灰色延續條，z-index 壓低，
   不會蓋住起始那筆的狀態選單/按鈕。中段/右側按鈕區塊一律渲染在 DOM 裡（不像
   #106 摺疊格那樣整段不存在），靠這裡的 display:none 隱藏——day_view_overlap_toggle.js
   點擊被蓋住的卡片時只是搬動 day-view-appt-passive 這個 class，不用另外處理按鈕
   顯示/隱藏，z-index 跟按鈕會一起自動換過去。 */
.day-view-appt-card.day-view-appt-passive {
  opacity: .55; background: var(--status-gray-bg); z-index: 1; cursor: pointer;
}
.day-view-appt-card.day-view-appt-passive .day-view-appt-middle,
.day-view-appt-card.day-view-appt-passive .day-view-appt-right {
  display: none;
}
.board-appt-passive { opacity: .6; background: var(--status-gray-bg); }

/* 已取消/未到店摺疊格：不進入時段佔位計算，只在起始格右上角疊一顆小 pill，
   justify-self/align-self 讓它只佔自己的大小，不會撐開或擠壓同格有效預約的寬度
   （有效預約卡片本身還是 grid-column:1 滿版）。點開清單沿用 appt_status_menu.js
   同一套 portal 定位手法（day_view_fold_cell.js），逃開 .day-view-grid-wrap 的
   overflow 裁切。 */
.day-view-fold-cell {
  grid-column: 1; justify-self: end; align-self: start;
  margin: 3px 4px 0 0; z-index: 3; position: relative;
}
.day-view-fold-trigger {
  display: flex; gap: 5px; align-items: center;
  font-size: .64rem; font-weight: 700; font-family: inherit;
  color: var(--text-secondary); background: var(--status-gray-bg);
  border: 1px solid var(--border-soft); border-radius: var(--radius-pill);
  padding: 2px 8px; margin: 0; cursor: pointer; box-shadow: var(--shadow-sm);
  white-space: nowrap;
}
.day-view-fold-trigger:hover { background: var(--border-soft); }
.day-view-fold-list {
  display: none; z-index: 1000; min-width: 220px; max-width: 280px; max-height: 280px;
  overflow-y: auto; background: var(--bg-card); border: 1px solid var(--border-soft);
  border-radius: var(--radius-md); box-shadow: var(--shadow-lg); padding: 4px;
}
.day-view-fold-list.open { display: block; }
.day-view-fold-list-item { padding: 6px; border-radius: var(--radius-sm); }
.day-view-fold-list-item + .day-view-fold-list-item { border-top: 1px solid var(--border-softer); }
.day-view-fold-list-name { font-size: .78rem; font-weight: 600; color: var(--text-primary); }
.day-view-fold-list-meta { font-size: .7rem; color: var(--text-secondary); margin-top: 2px; }

.day-view-appt-card.group-border-blue   { outline: 2px solid var(--status-blue-text); outline-offset: -2px; }
.day-view-appt-card.group-border-green  { outline: 2px solid var(--status-green-text); outline-offset: -2px; }
.day-view-appt-card.group-border-purple { outline: 2px solid var(--status-purple-text); outline-offset: -2px; }
.day-view-appt-card.group-border-yellow { outline: 2px solid var(--status-yellow-text); outline-offset: -2px; }

/* ---------- 預約總覽：單日並排檢視浮層（點月曆某天從右側滑出，月曆變暗但仍可見） ---------- */

.day-view-overlay-backdrop {
  position: fixed; inset: 0; background: rgba(20,18,10,.45);
  z-index: 60; opacity: 0; pointer-events: none;
  display: flex; justify-content: flex-end;
  transition: opacity .25s var(--ease-standard);
}
.day-view-overlay-backdrop.open { opacity: 1; pointer-events: auto; }
.day-view-overlay-panel {
  width: 78%; max-width: 1400px; height: 100vh; background: var(--bg-page);
  box-shadow: var(--shadow-lg); display: flex; flex-direction: column;
  transform: translateX(100%);
  transition: transform .3s var(--ease-standard);
}
.day-view-overlay-backdrop.open .day-view-overlay-panel { transform: translateX(0); }
.day-view-overlay-header {
  display: flex; align-items: center; justify-content: space-between; flex-shrink: 0;
  padding: var(--space-4) var(--space-5); border-bottom: 1px solid var(--border-soft);
  background: var(--bg-card);
}
.day-view-overlay-header strong { font-size: 1.1rem; }
#day-view-overlay-body { padding: var(--space-5); overflow-y: auto; flex: 1; }

/* ---------- 預約總覽：動效（月曆進場、右側詳情卡滑入、篩選淡出淡入） ---------- */

.calendar-wrap { animation: calendar-in .35s var(--ease-standard); }
@keyframes calendar-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}
.overview-calendar tbody tr {
  animation: calendar-row-in .32s var(--ease-standard) both;
}
.overview-calendar tbody tr:nth-child(1) { animation-delay: .02s; }
.overview-calendar tbody tr:nth-child(2) { animation-delay: .05s; }
.overview-calendar tbody tr:nth-child(3) { animation-delay: .08s; }
.overview-calendar tbody tr:nth-child(4) { animation-delay: .11s; }
.overview-calendar tbody tr:nth-child(5) { animation-delay: .14s; }
.overview-calendar tbody tr:nth-child(6) { animation-delay: .17s; }

.signature-history-card { margin-top: var(--space-5); padding: var(--space-5); }
.signature-history-heading,
.signature-history-row,
.signature-history-actions { display: flex; align-items: center; }
.signature-history-heading,
.signature-history-row { justify-content: space-between; gap: var(--space-4); }
.signature-history-heading h2,
.signature-history-heading .eyebrow { margin: 0; }
.signature-history-row { padding: var(--space-4) 0; border-top: 1px solid var(--border); }
.signature-history-row.is-voided { opacity: .62; }
.signature-history-actions { gap: var(--space-2); flex-wrap: wrap; justify-content: flex-end; }
.signature-void-label { color: var(--danger); font-weight: 700; }
@keyframes calendar-row-in {
  from { opacity: 0; transform: translateY(5px); }
  to   { opacity: 1; transform: translateY(0); }
}

.day-detail-panel { animation: panel-in .34s var(--ease-standard); }
@keyframes panel-in {
  from { opacity: 0; transform: translateX(16px); }
  to   { opacity: 1; transform: translateX(0); }
}

#overview-region { transition: opacity .14s ease; }
#overview-region.overview-fading { opacity: 0; }

/* ---------- 排班/關閉：月曆日期選取（純功能導向，不做進場動效） ---------- */

.sched-calendar { border-collapse: collapse; width: 100%; max-width: 460px; }
.sched-calendar th, .sched-calendar td {
  border: 1px solid var(--border-soft);
  text-align: center;
  padding: 0;
  width: 14.28%;
}
.sched-calendar th { padding: 8px; font-size: .8rem; color: var(--text-secondary); }
.sched-cal-cell { height: 46px; }
.sched-cal-cell.sched-cal-out { background: #fbfaf7; }
.sched-cal-cell.sched-cal-out .sched-cal-day { color: var(--text-muted); }
.sched-cal-cell.sched-cal-existing { background: var(--status-gray-bg); }
.sched-cal-day {
  display: flex; align-items: center; justify-content: center;
  height: 100%; margin: 0; cursor: pointer;
}
.sched-cal-cell.sched-cal-out .sched-cal-day { cursor: default; }
.sched-cal-day input { display: none; }
.sched-cal-day span {
  width: 28px; height: 28px; line-height: 28px;
  border-radius: 50%;
}
.sched-cal-cell.sched-cal-today .sched-cal-day span { font-weight: 700; color: var(--color-brand-dark); }
.sched-cal-day input:checked + span {
  background: var(--color-brand);
  color: #fff;
  font-weight: 600;
}
.sched-legend { display: flex; gap: var(--space-4); align-items: center; font-size: .82rem; color: var(--text-secondary); margin: var(--space-2) 0; }
.sched-legend-dot { display: inline-block; width: 14px; height: 14px; border-radius: 50%; margin-right: 5px; vertical-align: middle; }
.sched-legend-dot.existing { background: var(--status-gray-bg); border: 1px solid var(--border-soft); }
.sched-legend-dot.selected { background: var(--color-brand); }

.sched-cal-nav { display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-2); }

/* ---------- 技師代表色（staff.color，固定 12 色色票）----------
   /admin/overview 月曆「顯示休假」用來取代一律的 dot-staff-leave；
   /staff/{id}/edit 選色 UI 也重用同一套 class 當作色票預覽，兩處視覺一致。
   不開放自由輸入色碼，色碼只寫死在這裡這 12 組。 */
.staff-color-tag { display: inline-block; font-size: .68rem; font-weight: 600; padding: 2px 7px; border-radius: var(--radius-pill); }
.staff-color-tag.staff-color-blue   { background: #e5eefc; color: #2f5fa8; }
.staff-color-tag.staff-color-green  { background: #e2f4e7; color: #297a45; }
.staff-color-tag.staff-color-purple { background: #ece8fb; color: #5b4aa8; }
.staff-color-tag.staff-color-gold   { background: #fdf3dc; color: #9a7716; }
.staff-color-tag.staff-color-gray   { background: #edecef; color: #6b6976; }
.staff-color-tag.staff-color-pink   { background: #fce8f0; color: #b3467f; }
.staff-color-tag.staff-color-orange { background: #fde6d2; color: #b3591a; }
.staff-color-tag.staff-color-teal   { background: #dbf3ef; color: #1f7a63; }
.staff-color-tag.staff-color-indigo { background: #e2e4fb; color: #46469c; }
.staff-color-tag.staff-color-brown  { background: #ede1d3; color: #7a5230; }
.staff-color-tag.staff-color-olive  { background: #eef2cf; color: #6b7a1f; }
.staff-color-tag.staff-color-wine   { background: #f7dde3; color: #99315a; }

.staff-color-picker { display: flex; flex-wrap: wrap; gap: 8px; }
.staff-color-swatch-option { display: inline-flex; width: auto; margin: 0; cursor: pointer; }
.staff-color-swatch-option input { position: absolute; opacity: 0; width: 0; height: 0; }
.staff-color-swatch-preview { padding: 4px 10px; border-radius: var(--radius-pill); font-size: .78rem; font-weight: 600; border: 2px solid transparent; }
.staff-color-swatch-preview.staff-color-swatch-none { background: var(--status-gray-bg); color: var(--status-gray-text); }
.staff-color-swatch-option input:checked + .staff-color-swatch-preview { border-color: var(--color-brand-dark); }
.staff-color-swatch-option input:focus-visible + .staff-color-swatch-preview { outline: 2px solid var(--color-brand); outline-offset: 2px; }

/* ---------- 預約總覽：本頁彈窗新增預約（不跳頁） ---------- */

button.secondary, .secondary {
  background: var(--bg-page); color: var(--text-primary); border: 1px solid var(--border-soft);
  box-shadow: none;
}
button.secondary:hover, .secondary:hover { color: var(--text-primary); box-shadow: none; background: var(--border-softer); }

.modal-backdrop {
  position: fixed; inset: 0; background: rgba(20,18,10,.45);
  display: flex; align-items: center; justify-content: center; z-index: 100;
}
.modal-backdrop.hidden { display: none; }
.modal-box {
  background: var(--bg-card); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg);
  width: 480px; max-width: calc(100vw - 32px); max-height: calc(100vh - 64px);
  overflow-y: auto; padding: var(--space-5);
}
.modal-box.modal-box-wide { width: 680px; }
/* 儲值契約簽署（2／2）：全文要看得下去，放大到接近整頁，尺度跟設定頁預覽一致。
   🔴 外層 .modal-box 預設是 overflow-y:auto，跟 iframe 自己的捲軸疊成兩層——
   這裡改成 overflow:hidden 並用 flex 讓全文區吃滿剩餘高度，捲動只留在全文本身。 */
.modal-box.svc-sign-box {
  width: 92vw; max-width: 900px; height: 90vh; max-height: 90vh;
  display: flex; flex-direction: column; overflow: hidden;
}
.svc-sign-box > * { flex: 0 0 auto; }
.svc-sign-box .svc-contract-frame {
  flex: 1 1 auto; min-height: 160px; width: 100%;
  border: 1px solid var(--border-soft); border-radius: var(--radius-sm); background: #fff;
}
.svc-sign-pad { border: 2px dashed #9FBCB0; border-radius: 8px; background: #fff; }
.svc-sign-pad canvas { display: block; width: 100%; height: 140px; touch-action: none; }
.modal-header { display: flex; justify-content: space-between; align-items: center; }
.modal-header h3 { margin: 0; }
.modal-close {
  background: none; border: none; font-size: 1.4rem; line-height: 1; cursor: pointer;
  color: var(--text-secondary); width: auto; padding: 0; margin: 0; box-shadow: none;
}
.modal-close:hover { color: var(--text-primary); transform: none; box-shadow: none; }
.modal-footer { display: flex; justify-content: flex-end; gap: var(--space-3); margin-top: var(--space-4); }
.modal-footer button { margin-top: 0; }

.modal-search-results {
  border: 1px solid var(--border-soft); border-radius: var(--radius-sm); margin: -8px 0 12px;
  max-height: 160px; overflow-y: auto; background: var(--bg-card); box-shadow: var(--shadow-sm);
}
.modal-search-result-item { padding: 8px 12px; cursor: pointer; font-size: .88rem; }
.modal-search-result-item:hover { background: var(--bg-page); }

.slot-grid { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.slot-btn {
  width: auto; margin-top: 0; padding: 8px 14px;
  background: var(--bg-page); color: var(--text-primary); border: 1px solid var(--border-soft);
  box-shadow: none; font-weight: 500;
}
.slot-btn:hover { border-color: var(--color-brand); color: var(--text-primary); box-shadow: none; transform: none; }
.slot-btn.selected { background: var(--color-brand); color: #fff; border-color: var(--color-brand); }
.slot-btn.nearest-primary { border-color: var(--color-brand); font-weight: 700; }

/* ---------- 新增預約 modal：疊加項目多選（跟 /liff/book 同一套視覺語言） ---------- */

.addon-option {
  display: flex; align-items: center; gap: 10px;
  background: var(--bg-card); border: 1px solid var(--border-soft);
  border-radius: var(--radius-sm); padding: 8px 12px; margin-bottom: 6px;
  transition: background .15s var(--ease-standard), border-color .15s var(--ease-standard);
}
.addon-option:hover { border-color: var(--color-brand); }
.addon-option:has(.appt-modal-addon-checkbox:checked) {
  background: var(--color-brand-soft); border-color: var(--color-brand);
}

.addon-toggle {
  width: 100%; text-align: left; padding: 10px 14px;
  background: var(--bg-card); color: var(--text-primary);
  border: 1px dashed var(--border-soft); border-radius: var(--radius-sm);
  font-weight: 600; font-size: .9rem; cursor: pointer; margin: 0 0 8px;
  transition: border-color .15s var(--ease-standard), background .15s var(--ease-standard);
}
.addon-toggle:hover { border-color: var(--color-brand); }
.addon-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.addon-tag {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--color-brand-soft); color: var(--color-brand); border: 1px solid var(--color-brand);
  border-radius: 999px; padding: 4px 6px 4px 12px; font-size: .82rem; font-weight: 600;
}
.addon-tag-remove { cursor: pointer; font-weight: 700; padding: 0 6px; }
.addon-tag-remove:hover { color: var(--status-red-text); }

/* ---------- 共用分頁元件（會員/消費紀錄/儲值紀錄/服務項目列表共用） ---------- */

.pagination-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: var(--space-4); }
.pagination-bar .page-link {
  display: inline-block; padding: 6px 11px; border: 1px solid var(--border-soft); border-radius: var(--radius-sm);
  background: var(--bg-card); color: var(--text-primary); font-size: .85rem; text-decoration: none;
}
.pagination-bar .page-link:hover { border-color: var(--color-brand); }
.pagination-bar .page-link.active { background: var(--color-brand); color: #fff; border-color: var(--color-brand); font-weight: 700; }
.pagination-bar .page-link.disabled { color: var(--text-secondary); opacity: .45; pointer-events: none; }
.pagination-bar .page-ellipsis { padding: 0 4px; color: var(--text-secondary); }
.pagination-bar .page-jump { display: inline-flex; align-items: center; gap: 6px; margin-left: 8px; }
.pagination-bar .page-jump input[type="number"] { width: 68px; padding: 6px 8px; }
.pagination-bar .page-jump button { width: auto; margin-top: 0; padding: 6px 12px; }

/* ---------- 新增會員彈窗：兩欄式排版，分三區 ---------- */

.member-modal-fields { display: grid; grid-template-columns: 1fr 1fr; gap: 0 20px; }
.member-modal-fields .field input,
.member-modal-fields .field select { width: 100%; }
.member-modal-legend {
  grid-column: 1 / -1; font-weight: 600; margin-top: var(--space-4);
  padding-bottom: 4px; border-bottom: 1px solid var(--border-soft);
}
.member-modal-legend:first-child { margin-top: 0; }

/* ---------- 薪資頁明細視窗 ---------- */

.salary-section { margin-top: var(--space-5); }
.salary-section:first-child { margin-top: 0; }
.salary-section h4 { margin: 0 0 var(--space-2); }
.formula-box {
  background: var(--bg-page); border: 1px solid var(--border-soft); border-radius: var(--radius-sm);
  padding: 8px 12px; font-size: .88rem; margin-bottom: var(--space-3);
}
.salary-bill-group { border: 1px solid var(--border-soft); border-radius: var(--radius-sm); margin-bottom: 8px; padding: 4px 10px; }
.salary-bill-group summary { cursor: pointer; padding: 6px 0; font-weight: 500; }
.salary-placeholder-row { display: flex; justify-content: space-between; padding: 4px 0; color: var(--text-secondary); }

/* ---------- 排班頁規則列表：假別色標 + 日期小籤（取代逗號長字串） ---------- */

.leave-badge {
  display: inline-block; font-size: .72rem; font-weight: 600;
  padding: 2px 8px; border-radius: var(--radius-pill); margin-bottom: 4px;
}
.leave-badge.leave-blue   { background: var(--status-blue-bg);   color: var(--status-blue-text); }
.leave-badge.leave-purple { background: var(--status-purple-bg); color: var(--status-purple-text); }
.leave-badge.leave-green  { background: var(--status-green-bg);  color: var(--status-green-text); }
.leave-badge.leave-yellow { background: var(--status-yellow-bg); color: var(--status-yellow-text); }
.leave-badge.leave-red    { background: var(--status-red-bg);    color: var(--status-red-text); }
.leave-badge.leave-brand  { background: var(--color-brand-soft); color: var(--color-brand-dark); }
.leave-badge.leave-gray   { background: var(--status-gray-bg);   color: var(--status-gray-text); }

.date-pills { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; }
.date-pill {
  font-size: .74rem; background: var(--bg-page); border: 1px solid var(--border-soft);
  padding: 1px 8px; border-radius: var(--radius-pill); color: var(--text-secondary);
}

/* ---------- 消費/儲值紀錄：一排橫向精簡篩選列（取代原本直式一大欄）---------- */

.filter-bar-compact {
  display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap;
  margin-bottom: var(--space-4);
}
.filter-bar-compact input[type="date"] { width: auto; max-width: 160px; }
.filter-bar-compact input[type="text"] { width: auto; max-width: 240px; flex: 1 1 200px; }
.filter-bar-compact select { width: auto; max-width: 220px; }

/* ---------- 搜尋框顯式觸發：文字框 + 搜尋鈕 + 清除鈕包成一組 ---------- */

.search-box-group { display: inline-flex; align-items: center; gap: 4px; flex: 1 1 200px; max-width: 320px; }
.search-box-group input[type="text"] { flex: 1 1 auto; max-width: none; }
.search-box-group .search-btn, .search-box-group .search-clear-btn {
  width: auto; margin-top: 0; padding: 6px 10px; flex-shrink: 0;
  background: var(--bg-card); color: var(--text-primary); border: 1px solid var(--border-soft);
  border-radius: var(--radius-sm); font-size: .82rem; cursor: pointer; box-shadow: none;
}
.search-box-group .search-btn:hover, .search-box-group .search-clear-btn:hover {
  border-color: var(--color-brand); transform: none; box-shadow: none; background: var(--bg-card);
}
.search-box-group .search-clear-btn { padding: 6px 9px; font-weight: 700; color: var(--text-secondary); }

/* ---------- 手機欄位格式驗證：就地紅字提示 ---------- */

.phone-field-error { color: var(--status-red-text); font-size: .78rem; margin: 2px 0 8px; }

/* ---------- 會員詳情頁：會員資料區塊 ---------- */

.info-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px 24px; margin-bottom: 12px; }
.info-label { display: inline-block; min-width: 72px; color: var(--text-secondary); font-size: .85rem; }

/* ---------- 會員列表：神美同級欄位（顯示欄位下拉、姓名固定欄、色籤、截斷備註）---------- */

.hidden { display: none !important; }

/* ---------- 服務項目／商品／票券：編輯模式整頁批次編輯（app/static/catalog_bulk_edit.js）
   表格本身不套 form（每列刪除/上下架鈕各自是 form，包一個大 form 進去會變巢狀 form），
   純粹用 table 加一個狀態 class 切換每個欄位的唯讀/輸入兩種顯示。---------- */
.bulk-edit-bar { display: flex; justify-content: flex-end; align-items: center; gap: var(--space-2); margin: 4px 0 var(--space-3); clear: both; }
.bulk-edit-bar .msg, .bulk-edit-bar .error { margin: 0; padding: 6px 12px; font-size: .85rem; }
.js-bulk-input { display: none; width: 100%; box-sizing: border-box; }
table.is-edit-mode .js-bulk-view { display: none; }
table.is-edit-mode .js-bulk-input { display: inline-block; }

.table-scroll-wrap { overflow-x: auto; max-width: 100%; }
.table-scroll-wrap table { min-width: max-content; }

.col-name-phone { position: sticky; left: 0; background: var(--bg-card); z-index: 1; box-shadow: 2px 0 4px rgba(0,0,0,.04); }
.col-name-phone .phone-sub { display: block; font-size: .78rem; color: var(--text-secondary); }

.col-vis-dropdown { position: relative; display: inline-block; }
.col-vis-panel {
  position: absolute; right: 0; top: calc(100% + 4px); z-index: 20;
  background: var(--bg-card); border: 1px solid var(--border-soft); border-radius: var(--radius-md);
  box-shadow: var(--shadow-md); padding: var(--space-3); min-width: 200px;
}
.col-vis-panel label { display: block; font-size: .85rem; padding: 3px 0; }
.col-vis-panel input { width: auto; margin-right: 6px; }

.line-info-cell { display: flex; align-items: center; gap: 6px; }
.line-info-cell img { width: 24px; height: 24px; border-radius: 50%; object-fit: cover; }
.line-unbound { color: var(--text-muted); }

.level-badge { display: inline-block; font-size: .72rem; font-weight: 600; padding: 2px 8px; border-radius: var(--radius-pill); }
/* 2026-08-04：五個寫死的顏色 class（.level-purple/.level-black/.level-gold/
   .level-silver/.level-gray）已移除——等級顏色改成存在 customer_level_option 主檔的
   bg_color/text_color，畫徽章的地方直接套 inline style。留著這條 .level-badge 本體
   是因為形狀/字級/圓角這些跟顏色無關，各處仍共用。 */

.level-edit-btn {
  border: none; background: none; cursor: pointer; font-size: .8rem; color: var(--text-muted);
  padding: 0 2px; line-height: 1;
}
.level-edit-btn:hover { color: var(--text-secondary); }

.tag-pill {
  display: inline-block; font-size: .68rem; background: var(--bg-page); border: 1px solid var(--border-soft);
  padding: 1px 7px; border-radius: var(--radius-pill); color: var(--text-secondary); margin-left: 3px;
}

.truncate-cell { max-width: 140px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---------- 會員列表版面（只限這頁）：收緊 padding、勾選框貼左緣 ---------- */

.customer-table-compact th,
.customer-table-compact td {
  padding: 7px 10px;
}
.customer-table-compact th:first-child,
.customer-table-compact td:first-child {
  width: 28px;
  padding-left: 8px;
  padding-right: 4px;
}

/* ---------- 常駐開單鈕：併進頁面標題那一行右側 ----------
   原本是獨立一條橫幅（.topbar），在平板全螢幕模式下因為橫幅在 <main> 的
   捲動範圍外，視覺上永遠釘在最上方、吃掉一段可視高度。現在拿掉那條橫幅，
   按鈕改成 <main> 裡的第一個元素、float:right——每頁自己的 <h1> 完全沒有
   改動（61 個頁面共用同一顆按鈕，不用逐頁改樣板），文字會自然環繞在
   floated 按鈕左邊，視覺上跟標題同一行。路由/文字/底色漸層都沒變，只動
   位置。 */
.btn-brand {
  background: linear-gradient(180deg, var(--color-brand-light), var(--color-brand-dark));
  color: #fff;
  margin-top: 0;
}
.topbar-new-order { font-size: .95rem; float: right; margin-left: var(--space-4); }

/* ---------- 開單頁：左右分欄（左＝品項，右＝摘要／付款／操作） ---------- */

.order-layout {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: var(--space-5);
  align-items: start;
}
@media (max-width: 900px) { .order-layout { grid-template-columns: 1fr; } }

.order-summary-card h2 { margin-top: var(--space-5); }
.order-summary-card h2:first-child { margin-top: 0; }

/* ---------- 開單頁：品項卡（取代表格列，工作人員/職位/級別橫向排） ---------- */

.item-card {
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-left: 3px solid var(--color-brand);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  padding: var(--space-4) var(--space-5);
  margin-bottom: var(--space-4);
}
.item-card-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}
.item-card-title { font-weight: 700; font-size: 1rem; }
.item-card-price { color: var(--color-brand-dark); font-weight: 700; }
.item-card-meta { color: var(--text-muted); font-size: .82rem; }
.relation-card-removed { opacity: .5; }
.item-card-staff-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--space-4);
}
.item-card-staff-row .field { display: flex; flex-direction: column; gap: 2px; min-width: 120px; }
.item-card-staff-row label { margin: 0; }
.item-card-staff-row .field-designated { display: flex; flex-direction: row; align-items: center; gap: 6px; min-width: 0; }
.item-card-staff-row .field-designated label { font-size: .88rem; color: var(--text-secondary); }
.item-card-dept-row { margin-bottom: var(--space-3); }
.item-card-links-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-top: var(--space-2);
}
.item-card-missing-staff {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  background: var(--status-yellow-bg);
  color: var(--status-yellow-text);
  font-size: .86rem;
  font-weight: 600;
}
.item-card-missing-staff form { margin: 0; }
.item-card-missing-staff button { margin: 0; padding: 6px 12px; font-size: .82rem; }
.item-card-collapse {
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--border-soft);
}
.item-card-collapse summary {
  cursor: pointer;
  font-weight: 600;
  font-size: .88rem;
  color: var(--text-secondary);
}
.item-card-collapse summary:hover { color: var(--text-primary); }
.item-card-actions { margin-top: var(--space-3); display: flex; gap: var(--space-2); align-items: center; }

@media (max-width: 600px) {
  .item-card-header { flex-direction: column; align-items: flex-start; gap: 4px; }
  .item-card-staff-row { flex-direction: column; align-items: stretch; }
  .item-card-staff-row .field { min-width: 0; }
  .item-card-staff-row .field-designated { flex-direction: row; }
  .item-card-links-row { flex-direction: column; gap: var(--space-2); }
}

/* ---------- 開單頁：淺灰唯讀佔位（神美有、我們目前沒有的欄位／區塊） ---------- */

.placeholder-field, .placeholder-pill, .placeholder-link {
  color: var(--text-muted);
  cursor: not-allowed;
  user-select: none;
}
.placeholder-field {
  display: inline-block;
  background: var(--bg-page);
  border: 1px dashed var(--border-soft);
  border-radius: var(--radius-sm);
  padding: 5px 10px;
  font-size: .82rem;
}
.placeholder-pill {
  display: inline-flex;
  align-items: center;
  background: var(--bg-page);
  border: 1px dashed var(--border-soft);
  border-radius: var(--radius-pill);
  padding: 5px 14px;
  font-size: .82rem;
}
.placeholder-link {
  font-size: .82rem;
  text-decoration: underline dashed;
}
.item-card-title-placeholder { margin-left: var(--space-2); font-size: .74rem; vertical-align: middle; }
.placeholder-textarea {
  display: block;
  width: 100%;
  min-height: 60px;
  background: var(--bg-page);
  border: 1px dashed var(--border-soft);
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  padding: 8px 10px;
  font-size: .85rem;
  font-family: inherit;
  resize: none;
  margin-top: var(--space-1);
}

/* ---------- 開單頁：頂部工具列 / 會員標籤 / 客人統計列 ---------- */

.order-topbar-fields, .order-member-tag-row, .order-stats-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}
.order-topbar-real { color: var(--text-secondary); font-size: .88rem; }
.order-stat-real { color: var(--text-primary); font-weight: 600; font-size: .92rem; }

.link-button {
  display: inline;
  background: none;
  border: none;
  box-shadow: none;
  padding: 0;
  margin: 0;
  color: var(--color-brand-dark);
  font-weight: 400;
  font-size: inherit;
  cursor: pointer;
}
.link-button:hover { color: var(--text-primary); transform: none; box-shadow: none; }

/* ---------- 開單頁：會員搜尋列／儲值加值 ---------- */

.member-search-row {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}
.member-search-box { position: relative; flex: 1; min-width: 220px; }
.member-search-box input {
  width: 100%;
  margin: 0;
}
.member-search-results {
  position: absolute;
  z-index: 5;
  top: 100%;
  left: 0;
  right: 0;
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-md);
  max-height: 260px;
  overflow-y: auto;
  margin-top: 4px;
}
.member-search-result-item {
  padding: 8px 12px;
  font-size: .85rem;
  cursor: pointer;
  border-bottom: 1px solid var(--border-softer);
}
.member-search-result-item:last-child { border-bottom: none; }
.member-search-result-item:hover { background: var(--color-brand-soft); }

/* 「會員登入」彈窗（2026-08-03）：跟頂部搜尋列共用 .member-search-result-item，
   但這裡每一列多一顆明確的「登入」按鈕（不是點整列就綁定）——選錯人＝扣到別人
   的儲值，要一個明確的確認動作，不是點到名字就送出。 */
#order-member-login-results .member-search-result-item {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
  cursor: default;
}

.top-up-collapse { flex-basis: 100%; margin-top: var(--space-2); }
.top-up-collapse summary { display: inline-flex; }
.top-up-collapse form { margin-top: var(--space-2); }

/* ---------- 開單頁：儲值加值（收現金動作，要用強調色跳出來，不能長得像淺灰佔位） ---------- */

.top-up-entry-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  cursor: pointer;
  background: linear-gradient(180deg, var(--color-brand-light), var(--color-brand-dark));
  color: #fff;
  border-radius: var(--radius-pill);
  padding: 8px 18px;
  font-size: .9rem;
  font-weight: 700;
  box-shadow: var(--shadow-sm);
  user-select: none;
}
.top-up-entry-btn:hover { box-shadow: var(--shadow-md); }
.top-up-confirm-btn { font-size: 1rem; padding: 10px 22px; font-weight: 700; }

/* ---------- 開單頁：服務時間唯讀顯示（時間戳現在記在 appointment 上，開單頁只讀不寫） ---------- */

.service-time-done {
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-5);
  color: var(--text-secondary);
  font-weight: 600;
}

/* ---------- 預約卡：開始/結束服務按鈕（記在 appointment 上，跟開單/draft 生命週期脫鉤） ---------- */

.appt-card-service-btn {
  display: block;
  width: 100%;
  margin: 4px 0;
  padding: 8px 10px;
  font-size: .82rem;
  font-weight: 700;
  border-radius: var(--radius-md);
  text-align: center;
  border: none;
}
.appt-card-service-start { background: linear-gradient(180deg, var(--color-brand-light), var(--color-brand-dark)); }
.appt-card-service-end { background: linear-gradient(180deg, #e08a5c, #c2673a); }
.appt-card-service-done {
  font-size: .7rem;
  color: var(--text-secondary);
  font-weight: 600;
  margin: 4px 0;
}
@media (max-width: 600px) {
  .appt-card-service-btn { padding: 14px; font-size: 1rem; }
}

/* ---------- 開單頁：緊湊頁首工具列（單號/日期/狀態在左，刪除／作廢在右，取代原本
   四角散開、留白很大的 draft 狀態方框）---------- */

.order-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-4);
}
.order-toolbar-left { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-3); }
.order-toolbar-right { display: flex; align-items: center; gap: var(--space-2); flex-shrink: 0; }
.order-toolbar-back { font-size: .88rem; }
.order-toolbar-no { font-weight: 700; font-size: 1rem; color: var(--text-primary); }
.order-toolbar-date { font-size: .84rem; color: var(--text-secondary); }
.order-toolbar-edit-link { font-size: .86rem; font-weight: 600; }
.order-toolbar-danger-btn { margin: 0; padding: 8px 16px; font-size: .84rem; }
@media (max-width: 600px) {
  .order-toolbar { flex-direction: column; align-items: stretch; }
  .order-toolbar-right { justify-content: flex-end; }
}

/* ---------- 開單頁：右側消費摘要／付款區（固定順序：總金額/折扣/合計/已付/差額/
   付款紀錄/付款輸入/備註/確認結帳；桌面版隨頁面捲動固定顯示，手機自然掉到品項下方，
   不會水平溢出）---------- */

.order-summary-balance { padding-top: 4px; border-top: 1px dashed var(--border-soft); }

/* 消費摘要矩陣：欄＝有品項的分類＋合計，列＝總金額/折扣/合計/已付/差額。
   >900px（跟 .order-layout 兩欄變一欄同一個斷點）用橫向表格；窄螢幕改成
   每個分類一塊直向堆疊——欄位一多，窄螢幕橫向表格會被擠到要捲動，這裡直接
   改版面而不是加 overflow-x，跟場務表摺疊格那次同樣的理由（不要讓人需要
   橫向捲動才看得到差額）。兩種版面同一份資料，樣板端各自渲染一次、用 CSS
   互斥顯示，不是同一組 DOM 用 JS 重排。*/
.order-summary-matrix-narrow { display: none; }
.order-summary-matrix {
  width: 100%; border-collapse: collapse; font-size: .85rem;
}
.order-summary-matrix th, .order-summary-matrix td {
  padding: 6px 8px; text-align: right; border-bottom: 1px solid var(--border-softer);
}
.order-summary-matrix th:first-child, .order-summary-matrix td:first-child {
  text-align: left; color: var(--text-secondary); font-weight: 600;
}
.order-summary-matrix tr:first-child th { border-bottom: 2px solid var(--border-soft); }
.order-summary-matrix tr.order-summary-balance td,
.order-summary-matrix tr.order-summary-balance th { border-top: 1px dashed var(--border-soft); border-bottom: none; }

.order-summary-matrix-block {
  border: 1px solid var(--border-soft); border-radius: var(--radius-md);
  padding: var(--space-3); margin-bottom: var(--space-3);
}
.order-summary-matrix-block h3 { margin: 0 0 6px; font-size: .92rem; }
.order-summary-matrix-block-total { background: var(--bg-page); }
.order-summary-matrix-row {
  display: flex; justify-content: space-between; padding: 3px 0; font-size: .85rem;
}
.order-summary-matrix-row.order-summary-balance { border-top: 1px dashed var(--border-soft); margin-top: 4px; padding-top: 6px; }

.order-summary-uncategorized-warning {
  margin-top: var(--space-3); padding: 8px 10px; border-radius: var(--radius-md);
  background: var(--status-yellow-bg); color: var(--status-yellow-text); font-size: .82rem; font-weight: 600;
}

@media (max-width: 900px) {
  .order-summary-matrix-wide { display: none; }
  .order-summary-matrix-narrow { display: block; }
}

.order-summary-confirm-form { margin-top: var(--space-4); }
.order-summary-confirm-btn { display: block; width: 100%; font-size: 1rem; padding: 13px 20px; }

/* ---------- 票券主檔：分區式編輯器（票券與商品／庫存完全分開） ---------- */

.ticket-page-heading {
  display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-5);
  margin-bottom: var(--space-5);
}
.ticket-page-heading h1 { margin-bottom: var(--space-1); }
.ticket-page-heading p { margin: 0; }
.ticket-breadcrumb { color: var(--color-brand-dark) !important; font-size: .82rem; letter-spacing: .03em; }

.ticket-list-card, .ticket-create-panel, .ticket-import-panel {
  background: var(--bg-card); border: 1px solid var(--border-soft); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm); margin-bottom: var(--space-5); overflow: hidden;
}
.ticket-list-toolbar {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-4);
  padding: var(--space-4) var(--space-5); border-bottom: 1px solid var(--border-soft);
}
.ticket-list-toolbar div { display: flex; align-items: baseline; gap: var(--space-3); }
.ticket-list-toolbar span { color: var(--text-muted); font-size: .82rem; }
.ticket-list-toolbar label { display: flex; align-items: center; gap: var(--space-2); margin: 0; }
.ticket-list-toolbar select { width: auto; }
.ticket-list-card table { border: 0; box-shadow: none; border-radius: 0; margin-bottom: 0; }
.ticket-list-table { min-width: 1380px !important; }
.ticket-list-thumb { width: 72px; aspect-ratio: 16 / 9; object-fit: cover; border-radius: 6px; display: block; }
.ticket-no-image {
  display: inline-flex; align-items: center; justify-content: center; width: 72px; aspect-ratio: 16 / 9;
  border: 1px dashed var(--border-soft); border-radius: 6px; color: var(--text-muted); font-size: .7rem;
}
.ticket-table-sub { display: block; color: var(--text-muted); margin-top: 2px; font-size: .75rem; }
.ticket-row-actions { white-space: nowrap; }
.ticket-row-actions button { margin-left: 6px; padding: 5px 9px; font-size: .76rem; }
.status-badge { display: inline-flex; padding: 3px 9px; border-radius: var(--radius-pill); font-size: .74rem; font-weight: 700; }
.status-badge.status-active { background: var(--status-green-bg); color: var(--status-green-text); }
.status-badge.status-inactive { background: var(--status-gray-bg); color: var(--status-gray-text); }

.ticket-create-panel > summary, .ticket-import-panel > summary {
  cursor: pointer; list-style: none; padding: var(--space-4) var(--space-5); font-weight: 700;
  font-size: 1.05rem; background: #fbfaf7; border-bottom: 1px solid transparent;
}
.ticket-create-panel > summary::-webkit-details-marker,
.ticket-import-panel > summary::-webkit-details-marker { display: none; }
.ticket-create-panel > summary::after, .ticket-import-panel > summary::after {
  content: '＋'; float: right; color: var(--color-brand-dark);
}
.ticket-create-panel[open] > summary, .ticket-import-panel[open] > summary { border-bottom-color: var(--border-soft); }
.ticket-create-panel[open] > summary::after, .ticket-import-panel[open] > summary::after { content: '−'; }
.ticket-import-body { padding: 0 var(--space-5) var(--space-5); }

.ticket-editor { background: var(--bg-page); }
.ticket-tabs {
  display: grid; grid-template-columns: repeat(4, 1fr); background: var(--bg-card);
  border-bottom: 1px solid var(--border-soft); padding: 0 var(--space-5);
}
.ticket-tab {
  appearance: none; background: transparent; color: var(--text-secondary); border: 0;
  border-bottom: 3px solid transparent; border-radius: 0; box-shadow: none; margin: 0;
  padding: 16px 12px; font-weight: 600;
}
.ticket-tab:hover { background: var(--color-brand-soft); color: var(--text-primary); transform: none; box-shadow: none; }
.ticket-tab.active { color: var(--color-brand-dark); border-bottom-color: var(--color-brand); background: transparent; }
.ticket-tab-summary {
  display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-5); padding: var(--space-3) var(--space-5);
  color: var(--text-muted); background: #faf8f3; border-bottom: 1px solid var(--border-soft); font-size: .78rem;
}
.ticket-tab-summary span::before { content: '•'; color: var(--color-brand); margin-right: 6px; }
.ticket-panel { padding: var(--space-5); }
.ticket-panel[hidden] { display: none !important; }
.ticket-basic-grid { display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(320px, .75fr); gap: var(--space-4); align-items: start; }
.ticket-section-card {
  background: var(--bg-card); border: 1px solid var(--border-soft); border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm); padding: var(--space-5); margin-bottom: var(--space-4);
}
.ticket-section-card h2 { display: inline; margin: 0; font-size: 1.08rem; }
.ticket-section-heading {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
  padding-bottom: var(--space-3); margin-bottom: var(--space-4); border-bottom: 1px solid var(--border-soft);
}
.ticket-section-heading > div { display: flex; align-items: center; gap: var(--space-2); }
.ticket-section-heading p { margin: 0; font-size: .76rem; }
.ticket-step {
  display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px;
  border-radius: 50%; background: var(--color-brand-soft); color: var(--color-brand-dark); font-size: .72rem; font-weight: 700;
}
.required-mark { color: var(--status-red-text); }
.ticket-field-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 var(--space-4); }
.ticket-field-wide { grid-column: 1 / -1; }
.ticket-editor input:not([type="checkbox"]):not([type="file"]),
.ticket-editor select, .ticket-editor textarea { width: 100%; }
.ticket-editor textarea { resize: vertical; }
.ticket-money-input { display: flex; align-items: stretch; }
.ticket-money-input > span {
  display: flex; align-items: center; padding: 0 11px; background: #f7f5f0; color: var(--text-secondary);
  border: 1px solid var(--border-soft); border-right: 0; border-radius: var(--radius-sm) 0 0 var(--radius-sm);
}
.ticket-money-input input { border-radius: 0 var(--radius-sm) var(--radius-sm) 0 !important; }

.ticket-switch-row {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-4);
  padding: var(--space-3) var(--space-4); background: #fbfaf7; border: 1px solid var(--border-soft);
  border-radius: var(--radius-sm); margin-top: var(--space-4);
}
.ticket-switch-row span { display: flex; flex-direction: column; }
.ticket-switch-row strong { color: var(--text-primary); }
.ticket-switch-row small { color: var(--text-muted); font-weight: 400; }
.ticket-switch-row input[type="checkbox"] { width: 22px; height: 22px; accent-color: var(--color-brand-dark); flex-shrink: 0; }

.ticket-image-upload {
  min-height: 230px; display: flex; align-items: center; justify-content: center; position: relative;
  overflow: hidden; border: 1px dashed var(--color-brand); border-radius: var(--radius-md);
  background: linear-gradient(135deg, #fbf7ed, #f4ead2); cursor: pointer; margin: 0;
}
.ticket-image-upload input { position: absolute; inset: 0; opacity: 0; cursor: pointer; width: 100%; }
.ticket-image-upload img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; display: block; }
.ticket-image-placeholder { display: flex; flex-direction: column; align-items: center; gap: 8px; text-align: center; color: var(--color-brand-dark); }
.ticket-image-placeholder small { color: var(--text-muted); font-weight: 400; }
.ticket-remove-image { margin-top: var(--space-2); }
.ticket-customer-preview {
  margin-top: var(--space-4); padding: var(--space-4); border: 1px solid var(--border-soft);
  border-radius: var(--radius-sm); background: #fff;
}
.ticket-preview-kicker { display: block; color: var(--text-muted); font-size: .72rem; margin-bottom: 5px; }
.ticket-customer-preview > strong { display: block; font-size: 1.05rem; margin-bottom: var(--space-2); }
.ticket-customer-preview > div { display: flex; justify-content: space-between; color: var(--text-secondary); }

.ticket-choice-fieldset { box-shadow: none; padding: var(--space-3) 0 0; border: 0; border-top: 1px solid var(--border-soft); border-radius: 0; }
.ticket-choice-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-2); }
.ticket-choice {
  display: flex; align-items: center; gap: var(--space-2); min-height: 44px; margin: 0; padding: 9px 12px;
  border: 1px solid var(--border-soft); border-radius: var(--radius-sm); background: #fff;
}
.ticket-choice:hover { border-color: var(--color-brand); background: var(--color-brand-soft); }
.ticket-choice input { width: auto; accent-color: var(--color-brand-dark); }
.ticket-choice span { display: flex; flex-direction: column; }
.ticket-choice small { color: var(--text-muted); font-weight: 400; }
.ticket-policy-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-3); }
.ticket-policy-grid .ticket-switch-row { margin-top: var(--space-3); }
.ticket-form-note { padding: var(--space-3); background: var(--color-brand-soft); border-left: 3px solid var(--color-brand); font-size: .8rem; }
.ticket-empty-state { color: var(--text-muted); text-align: center; padding: var(--space-5); }
.ticket-form-actions {
  position: sticky; bottom: 0; z-index: 4; display: flex; justify-content: flex-end; gap: var(--space-3);
  padding: var(--space-4) var(--space-5); background: rgba(255,255,255,.96); border-top: 1px solid var(--border-soft);
  box-shadow: 0 -8px 20px rgba(24,20,10,.05); backdrop-filter: blur(8px);
}
.ticket-form-actions .btn, .ticket-form-actions button { min-width: 130px; margin: 0; text-align: center; }
.ticket-validity-relative { max-width: 360px; }

/* ---------- 商品主檔：基本資料（含庫存來源）／贈品設定 ---------- */

.product-list-table { min-width: 1180px !important; }
/* 「編號」結構上本來就在勾選框右邊，看起來卻隔了一大段：真因是全域的
   input{width:260px} 套到了這兩個勾選框上（它們沒像別處那樣寫 width:auto），
   第一欄被撐成 295px。把勾選框收回 auto，欄寬就跟著縮到內容大小。 */
.product-list-table .js-select-all,
.product-list-table .js-row-select { width: auto; }
.product-list-table th:first-child,
.product-list-table td:first-child { width: 1%; white-space: nowrap; }
.product-flow-steps {
  display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-3);
  padding: var(--space-4) var(--space-5); background: #faf8f3;
  border-bottom: 1px solid var(--border-soft); font-size: .82rem; font-weight: 600;
}
.product-flow-step { color: var(--text-muted); }
.product-flow-step.active { color: var(--color-brand-dark); }
.product-flow-arrow { color: var(--border-soft); font-weight: 400; }
.product-tabs { grid-template-columns: repeat(2, 1fr); }
.product-edit-panel {
  background: var(--bg-card); border: 1px solid var(--border-soft); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm); overflow: hidden;
}
.product-inventory-facts {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--space-3);
  margin: var(--space-4) 0;
}
.product-inventory-facts > div {
  display: flex; flex-direction: column; gap: 6px; min-height: 78px; padding: var(--space-3);
  border: 1px solid var(--border-soft); border-radius: var(--radius-sm); background: #fbfaf7;
}
.product-inventory-facts span { color: var(--text-muted); font-size: .76rem; }
.product-inventory-facts strong { color: var(--text-primary); font-size: 1rem; }
.product-inventory-link { display: inline-flex; margin-top: var(--space-2); font-weight: 700; }
.product-gift-targets { margin-top: var(--space-4); }

@media (max-width: 1050px) {
  .ticket-basic-grid { grid-template-columns: 1fr; }
  .ticket-choice-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .product-inventory-facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 700px) {
  .ticket-page-heading { flex-direction: column; }
  .ticket-tabs { grid-template-columns: repeat(2, 1fr); padding: 0; }
  .ticket-tab-summary { display: none; }
  .ticket-panel { padding: var(--space-3); }
  .ticket-field-grid, .ticket-policy-grid, .ticket-choice-grid { grid-template-columns: 1fr; }
  .ticket-field-wide { grid-column: auto; }
  .ticket-form-actions { padding: var(--space-3); }
  .ticket-form-actions .btn, .ticket-form-actions button { flex: 1; min-width: 0; }
  .product-tabs { grid-template-columns: 1fr; }
  .product-inventory-facts { grid-template-columns: 1fr; }
}

/* ---------- 平板全螢幕模式（is_tablet_only 帳號專用，<html class="tablet-fullscreen">，
   桌面/一般 admin 帳號完全不受影響）：整頁不捲動，只有 <main> 內部捲動，
   側欄照舊自己捲；用 overscroll-behavior 擋 iOS 橡皮筋彈動，overflow-x 擋橫向溢出，
   safe-area-inset 讓內容不被瀏海/home indicator 切到。 ---------- */
html.tablet-fullscreen, html.tablet-fullscreen body {
  height: 100%;
  overflow: hidden;
  overscroll-behavior: none;
}
/* .tablet-topbar 是 body 的手足、不是 .app-shell 的子元素（見 _tablet_topbar.html
   在 base.html 裡的位置）。原本 .app-shell 自己又是 height:100dvh，等於在頂欄
   已經佔掉一段高度之後，還要求自己拿到「整個視窗」的高度，一定會下緣溢出視窗，
   溢出量剛好等於頂欄高度——這是真機捲不到底的根因，不是內容或斷點問題。
   修法：只讓最外層的 body 用 100dvh（真的對應真實可視高度），body 本身變成
   flex column，把這個高度分給 .tablet-topbar（flex:0 0 auto，維持它自己算出來的
   實際高度，不管單行雙行、不管換行變多高，見 tablet.css）跟 .app-shell
   （flex:1 1 auto + min-height:0，吃剩下的空間）。.app-shell/.main-wrap 都不再
   自己宣告 100vh/100dvh，高度完全由 flex 分配決定，不寫死頂欄高度的任何假設。 */
html.tablet-fullscreen body {
  display: flex;
  flex-direction: column;
}
html.tablet-fullscreen .app-shell {
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
}
html.tablet-fullscreen .main-wrap {
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
}
html.tablet-fullscreen main {
  height: 100%;
  overflow-y: auto;
  overflow-x: hidden;
  overscroll-behavior: none;
  -webkit-overflow-scrolling: touch;
  padding-bottom: max(var(--space-6), env(safe-area-inset-bottom));
  padding-left: max(var(--space-4), env(safe-area-inset-left));
  padding-right: max(var(--space-4), env(safe-area-inset-right));
}
html.tablet-fullscreen .brand { padding-top: max(22px, env(safe-area-inset-top)); }

/* ---------- 模擬登入橫幅：owner 唯讀檢視某位技師畫面時的明顯提示，顏色刻意跟
   平常（金色品牌色/一般狀態色）不同，避免被誤認成正常操作畫面。sticky 貼頂，
   z-index 蓋過 sidebar，任何頁面（含 base.html 以外的手機版員工首頁）都看得到。 ---------- */
.impersonation-banner {
  position: sticky;
  top: 0;
  z-index: 999;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 10px 16px;
  background: #7a2e2e;
  color: #fff;
  font-weight: 700;
  font-size: .88rem;
  text-align: center;
}
.impersonation-banner button {
  width: auto;
  background: #fff;
  color: #7a2e2e;
  border: none;
  border-radius: 6px;
  padding: 4px 14px;
  font-weight: 700;
  cursor: pointer;
}

/* ---------- #124 服務項目直條圖：一張圖、依次數排序、顏色分類，不分頁。
   真正的垂直柱狀圖——X 軸＝品項、Y 軸＝次數，Y 軸刻度固定在左側不隨橫向捲動跑掉，
   手機 390px 下十幾根柱子放不下就整張圖橫向捲動（.ipop-vbar-scroll），不改圖型。
   跟儀表板/美容師首頁共用同一份 CSS，兩邊視覺語言保持一致。 ---------- */
.ipop-filter-bar { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-bottom: var(--space-3); }
.ipop-filter-btn {
  width: auto; background: var(--bg-card); border: 1px solid var(--border-color);
  border-radius: 999px; padding: 4px 12px; cursor: pointer; font-size: .82rem;
  color: var(--text-muted);
}
.ipop-filter-btn.is-active {
  color: #fff; background: var(--color-brand); border-color: var(--color-brand); font-weight: 700;
}

.ipop-staff-switcher { display: flex; align-items: center; gap: var(--space-2); margin-bottom: var(--space-3); }
.ipop-staff-switcher label { font-size: .82rem; color: var(--text-muted); }
.ipop-staff-switcher select { width: auto; max-width: 220px; }

.ipop-vbar-chart { display: flex; align-items: flex-start; gap: 4px; }
.ipop-vbar-yaxis {
  position: relative; flex: 0 0 auto; width: 30px; height: 180px; margin-top: 10px;
}
.ipop-vbar-tick {
  position: absolute; right: 4px; transform: translateY(50%);
  font-size: .7rem; color: var(--text-muted); white-space: nowrap;
}
.ipop-vbar-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; flex: 1 1 auto; min-width: 0; }
.ipop-vbar-plot {
  /* 🔴 標籤改直排之後高度不再一致（品項名長短不同），用 flex-start 讓所有欄的
     「柱子頂端」對齊 Y 軸刻度；用 flex-end（底部對齊）會讓柱子本身跟著標籤
     高度上下亂跑，刻度就對不準了。 */
  display: flex; align-items: flex-start; gap: 18px; min-width: max-content;
  border-left: 1px solid var(--border-soft); padding: 10px 10px 10px;
}
.ipop-vbar-col { display: flex; flex-direction: column; align-items: center; width: 26px; flex: 0 0 auto; }
.ipop-vbar-col[hidden] { display: none; }
.ipop-vbar-track { height: 180px; width: 100%; display: flex; align-items: flex-end; justify-content: center; }
.ipop-vbar-fill {
  width: 26px; min-height: 2px; border-radius: 4px 4px 2px 2px; cursor: default;
  animation: bar-grow .5s var(--ease-standard) both; opacity: .85;
}
.ipop-vbar-fill:hover { opacity: 1; }
.ipop-vbar-count { font-size: .76rem; font-weight: 700; margin-top: 4px; white-space: nowrap; }
/* 老闆裁決（2026-08-02 第三輪）：只留直排，拿掉斜置——「讀的到，太斜了，文字要
   正的」。writing-mode 讓字元逐個往下排；text-orientation:upright 連英數字元
   也保持正立、不側轉，符合「逐字換行」，標籤從柱子正下方垂直往下，不傾斜。
   不截斷、不寫死高度：column 沒有 max-height/overflow:hidden，最長的品項名
   會自然把整個容器撐高，不會被切掉。 */
.ipop-vbar-label {
  writing-mode: vertical-rl;
  text-orientation: upright;
  font-size: .7rem;
  line-height: 1.15;
  color: var(--text-secondary);
  margin-top: 6px;
  white-space: nowrap;
}
.ipop-empty, .ipop-unattributed { font-size: .84rem; color: var(--text-muted); margin: var(--space-2) 0 0; }

.ipop-cat-dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; flex: 0 0 auto; margin-top: 3px; }
.ipop-cat-main.ipop-cat-dot, .ipop-vbar-fill.ipop-cat-main { background: var(--status-blue-text); }
.ipop-cat-addon.ipop-cat-dot, .ipop-vbar-fill.ipop-cat-addon { background: var(--status-purple-text); }
.ipop-cat-campaign.ipop-cat-dot, .ipop-vbar-fill.ipop-cat-campaign { background: var(--status-green-text); }
html.tablet-fullscreen .sidebar-footer { padding-bottom: max(var(--space-3), env(safe-area-inset-bottom)); }

/* 會員等級管理（/settings/stored_value_contract）：列表 + 右上新增鈕 + 搜尋列。
   等級徽章本身的顏色不在這裡——那是主檔的 bg_color/text_color 逐列 inline 套上去的。 */
.level-section-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.level-section-head h2 { margin-bottom: 0; }
.level-toolbar { display: flex; align-items: center; gap: 14px; margin: 10px 0 12px; flex-wrap: wrap; }
.level-toolbar input[type=search] { max-width: 260px; }
.level-toolbar-toggle { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.level-color-fields { display: flex; gap: 18px; align-items: flex-end; flex-wrap: wrap; }
.level-color-fields input[type=color] { width: 56px; height: 34px; padding: 2px; }

/* 儲值契約的品項挑選清單（設定頁的「加入贈送項目」、儲值加值的合約彈窗）。
   🔴 這裡一定要有 [hidden] 這條：列本身是 display:flex 的 flex 容器，而
   display 的行內/類別樣式會蓋過瀏覽器預設的 [hidden]{display:none}——少了這條，
   JS 的 row.hidden = true 就完全不生效，分頁籤（服務項目/商品/票券）與搜尋
   看起來「有切換但清單沒變」，店員會對著沒過濾的整份清單挑錯東西。
   開單頁自己有一條同樣用途的規則，但那條綁在 .checkout-page 底下，這兩頁吃不到。 */
.contract-catalog-row { display: flex; width: 100%; gap: 10px; text-align: left; padding: 6px 10px; }
.contract-catalog-row[hidden] { display: none; }

/* ---------- 排班・休假頁改版（2026-08-04）：左右並列＋單一月曆＋選取層 ---------- */

/* 原則＝要編輯的在左邊、要看的在右邊。窄畫面自然落回單欄堆疊。 */
.sched-split {
  display: grid;
  grid-template-columns: minmax(300px, 360px) minmax(0, 1fr);
  gap: var(--space-4);
  align-items: start;
}
@media (max-width: 900px) {
  .sched-split { grid-template-columns: minmax(0, 1fr); }
}
.sched-split > fieldset { margin: 0; min-width: 0; }

/* 月曆正上方的兩顆選取模式按鈕（不是下拉），預設「多選單日」。 */
.sched-pick-modes { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; margin-bottom: var(--space-2); }
.sched-pick-modes button {
  width: auto; margin: 0; padding: 5px 12px; font-size: .8rem;
  background: #fff; color: var(--text-secondary); border: 1px solid var(--border-soft);
  border-radius: var(--radius-pill); box-shadow: none;
}
.sched-pick-modes button.is-active {
  background: var(--color-brand); color: #fff; border-color: var(--color-brand);
}
.sched-pick-summary { font-size: .78rem; color: var(--text-secondary); margin: 0 0 var(--space-2); }
.sched-pick-summary.sched-pick-warning { color: var(--status-red-text, #b3261e); font-weight: 600; }

/* 格子密度：每格要放得下 8 個人＝格內 2 欄 × 4 列的名字 pill。
   日期格拉高一點、左右縮一點（padding 收窄，7 欄等分的寬度不動）。 */
.sched-overview td { height: 138px; }
.sched-overview .sched-day-box { padding: 8px 5px; height: 100%; box-sizing: border-box; }
.sched-overview .day-status-lines {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-auto-rows: min-content;
  gap: 2px 4px;
}
.sched-overview .day-status-line { font-size: .62rem; }
.sched-overview td[data-day] { cursor: pointer; }

/* 🔴 選取標示只有一種：黃底＝本次新選取。
   不做灰底表示「已存在的休假」——那件事總覽上技師自己的彩色 pill 已經在講了，
   再疊一層灰底只會讓兩種訊息互相干擾（老闆指定）。 */
.sched-overview td.is-picked { background: #FDF3C7; }
.sched-overview td.is-picked:hover { background: #FAE9A4; }

/* ---------- 生日輸入：年／月／日三個下拉（2026-08-05） ---------- */
/* 原生 input[type=date] 對「幾十年前的日期」是最差解（見 app/static/birthday_select.js
   的說明）。這裡的三個下拉在桌機與 iPad 上都是一眼看得完、年份可直接跳選。
   全域 select{width:260px} 在這裡要收掉，三個並排才放得下。 */
.birthday-field { display: flex; gap: 8px; align-items: center; max-width: 340px; }
.birthday-field select { width: auto; flex: 1 1 0; min-width: 0; margin: 0; }
@media (max-width: 380px) {
  .birthday-field { gap: 5px; }
  .birthday-field select { padding: 9px 6px; font-size: .86rem; }
}
