/* common/ux.css：後台／超管共用樣式第 2／2 支「Bootstrap 原廠色收編、列表操作鈕與狀態徽章、設定頁卡片、狀態圖例、2026-10-01 共用元件（對話框、空狀態與載入失敗、提示框、分段選擇、儲存列、即存狀態、時間下拉）」（2026-10-12 由 common.css 第 993～1730 行逐字切出；依 tenant/layout.html 的 link 順序串接＝原檔）---- 以下逐字搬自拆分前的 common.css ---- */
/* ========================================
   Bootstrap 原廠色收編（2026-07-31 質感審計 #1）
   根因：:root 有好 token（#4361ee/#34c759/#ff3b30/#86868b）但 Bootstrap 元件
   從未 re-theme，原廠色（#0d6efd/#198754/#dc3545/#6c757d/#ffc107）與 token 同屏打架。
   此覆蓋層把 Bootstrap 常用元件全部收編到設計 token，全站（tenant+admin）生效。
   ======================================== */

.form-check-input:checked { background-color: var(--primary-color); border-color: var(--primary-color); }
.form-check-input:focus { border-color: var(--primary-color); box-shadow: 0 0 0 3px rgba(67,97,238,.25); }
/* 描邊按鈕的「字」走 --*-text 深一階（2026-10-15 手機 axe 稽核）：描邊鈕沒有底色，字直接壓在頁底 #f5f5f7 或淡色卡上，
   原廠色當字不到 4.5:1——#6c757d 4.30、#198754 4.16、#dc3545 配 #fff3cd 4.08、#ffc107 配白 1.63、#4361ee 配 #eef1fe 4.45。
   邊框與 hover 實心底維持原色（非文字只要 3:1）；hover 時字是白字壓實心底，不受影響。
   對比由 tests/ui-components-check.js 實算（每個描邊鈕的字色對白、頁底、淡色卡都要 ≥4.5）。 */
.btn-outline-primary { --bs-btn-color: var(--primary-text); --bs-btn-border-color: var(--primary-color);
  --bs-btn-hover-bg: var(--primary-color); --bs-btn-hover-border-color: var(--primary-color); }
.btn-outline-secondary { --bs-btn-color: var(--text-secondary); }
.btn-outline-success { --bs-btn-color: var(--success-text); }
.btn-outline-danger { --bs-btn-color: var(--danger-text); }
.btn-outline-warning { --bs-btn-color: var(--warning-text); }
/* Bootstrap 自己的連結色（.nav-link／.btn-link／.link-* 讀 --bs-link-color，原廠 #0d6efd 在 #ecf3ff 上 4.03）收編到 --primary-text */
:root {
    --bs-link-color: #2a3eb1;
    --bs-link-color-rgb: 42, 62, 177;
    --bs-link-hover-color: #3a56d4;
    --bs-link-hover-color-rgb: 58, 86, 212;
}
/* Bootstrap 的 .text-secondary（#6c757d）＝與 .text-muted 同一個語意，一起收編到 --text-secondary */
.text-secondary { color: var(--text-secondary) !important; }
/* ⚠️ 必須用 rgba(..., var(--bs-bg-opacity,1)) 形式：直接寫 `background-color: var(--x) !important`
   會讓 Bootstrap 的 `.bg-opacity-10/25/50` 全站失效（2026-08-01 UX 評審抓到：
   「危險操作」卡片 header 本來要淡紅底深紅字，實際變成實心亮紅 + 紅字幾乎看不見）。
   opacity 預設 1 → 沒帶 bg-opacity 的既有用法外觀完全不變。 */
.bg-primary { background-color: rgba(67, 97, 238, var(--bs-bg-opacity, 1)) !important; }
.bg-success { background-color: rgba(52, 199, 89, var(--bs-bg-opacity, 1)) !important; }
.bg-danger  { background-color: rgba(255, 59, 48, var(--bs-bg-opacity, 1)) !important; }
.bg-secondary { background-color: rgba(134, 134, 139, var(--bs-bg-opacity, 1)) !important; }
.bg-warning { background-color: rgba(255, 159, 10, var(--bs-bg-opacity, 1)) !important; }
.alert-primary { --bs-alert-bg: #eef1fe; --bs-alert-color: #2a3eb1; --bs-alert-border-color: transparent; }
.alert-success { --bs-alert-bg: #eafaf0; --bs-alert-color: #1e7e43; --bs-alert-border-color: transparent; }

/* Alert 色彩收斂（2026-08-01 UX 評審）：說明/教學/提示類 alert 在後台大量出現，
   全部上色會讓「真正需要注意的錯誤與破壞性警告」失去辨識度。
   .alert-info / .alert-light 這兩種「純資訊」語意降為中性淺灰卡，
   左側 3px 灰條保留「這是一段註記」的形狀；alert-danger / alert-warning 維持原有語意色不動。 */
.alert-info,
.alert-light {
    --bs-alert-bg: #f7f7f9;
    --bs-alert-color: #4a4a52;
    --bs-alert-border-color: transparent;
    border-left: 3px solid rgba(0, 0, 0, 0.12);
}

/* 中性 alert 內的圖示同步降彩度（原本常是藍/黃圖示配灰底，顯得雜） */
.alert-info > i:first-child,
.alert-light > i:first-child {
    color: var(--secondary-color);
}
/* 次要文字一律走 --text-secondary（#6e6e73，白底 5.07:1）。
   2026-10-01 前是 #86868b（白底 3.62:1，不到 AA），全站每頁數十到上百處。 */
.text-muted { color: var(--text-secondary) !important; }

/* ========================================
   列表操作鈕去彩化（2026-07-31 質感審計 #3）
   取代列表每列四顆四色實心/描邊方鈕：灰 ghost icon 鈕，hover 才顯色；
   取消/刪除類用 .btn-ghost-danger（hover 轉紅）。只換 class，onclick/title/icon 不動。
   ======================================== */

.btn-ghost {
    color: #6e6e73;
    background-color: transparent;
    border: 1px solid transparent;
}
.btn-ghost:hover,
.btn-ghost:focus-visible {
    color: var(--primary-color);
    background-color: rgba(67, 97, 238, 0.08);
    border-color: transparent;
}
.btn-ghost:active {
    color: var(--primary-hover);
    background-color: rgba(67, 97, 238, 0.14);
}
.btn-ghost-danger:hover,
.btn-ghost-danger:focus-visible {
    color: var(--danger-text);
    background-color: rgba(255, 59, 48, 0.08);
}
.btn-ghost-danger:active {
    color: #d70015;
    background-color: rgba(255, 59, 48, 0.14);
}
/* 狀態型 ghost（如商品「上架中」）：靜態就顯綠，表達目前狀態而非動作語意 */
.btn-ghost-success {
    color: var(--success-text);
}
.btn-ghost-success:hover,
.btn-ghost-success:focus-visible {
    color: var(--success-text);
    background-color: rgba(52, 199, 89, 0.10);
}
.btn-ghost-success:active {
    color: #248a3d;
    background-color: rgba(52, 199, 89, 0.16);
}
/* btn-group 內的 ghost 鈕之間不需要分隔框線 */
.btn-group .btn-ghost { border-radius: 6px; }

/* ========================================
   列表操作鈕去彩虹 — CSS 防守層（2026-08-01 UX 評審）
   .btn-ghost 只推到部分頁面，其餘 8 頁列表仍是「一列 3-4 顆彩色描邊鈕」的彩虹排。
   這層不改任何 HTML/JS：只把「表格列內」的 outline 按鈕降成中性描邊，hover 才回到語意色。
   （表格外的按鈕——頁首主要動作、Modal 按鈕、表單送出——完全不受影響。）
   ======================================== */
.data-table-body td .btn-outline-primary,
.data-table-body td .btn-outline-success,
.data-table-body td .btn-outline-warning,
.data-table-body td .btn-outline-info,
.data-table-body td .btn-outline-secondary,
.data-table-body td .btn-outline-danger {
    --bs-btn-color: #6e6e73;
    --bs-btn-border-color: rgba(0, 0, 0, 0.12);
}
.data-table-body td .btn-outline-primary:hover,
.data-table-body td .btn-outline-primary:focus-visible {
    --bs-btn-hover-bg: var(--primary-color);
    --bs-btn-hover-border-color: var(--primary-color);
}
.data-table-body td .btn-outline-success:hover,
.data-table-body td .btn-outline-success:focus-visible {
    --bs-btn-hover-bg: var(--success-text);
    --bs-btn-hover-border-color: var(--success-text);
}
.data-table-body td .btn-outline-danger:hover,
.data-table-body td .btn-outline-danger:focus-visible {
    --bs-btn-hover-bg: var(--danger-text);
    --bs-btn-hover-border-color: var(--danger-text);
}

/* ========================================
   列表狀態徽章改 soft tint（2026-08-01 UX 評審）
   原本一列裡 3-5 顆 100% 飽和實心藥丸互相搶注意力，掃視時反而找不到重點。
   ⚠️ 色相語意完全不變（藍=已確認 / 綠=已完成 / 黃=待確認 / 灰=已取消 / 紫=爽約 / 橘=未處理），
   只降飽和：淡底 + 深字。行事曆事件（.fc-event.status-*）維持實心色塊不動——
   那裡色塊本身就是主要辨識物，兩者色相仍一致（根 CLAUDE.md「預約狀態顏色」規範精神保留）。
   ⚠️ tint 不能淡到「掃視時找不到」：純淡底版經生產實測在整頁檢視下幾乎讀不出來，
   故每顆都補同色相的 1px 邊框，讓它仍明確是一顆「狀態標籤」。
   ======================================== */
.badge.bg-status-pending {
    background-color: #fff1d6 !important;
    color: #7a4f00 !important;
    border: 1px solid rgba(255, 159, 10, 0.45);
}
.badge.bg-status-confirmed {
    background-color: #e4eaff !important;
    color: #24358f !important;
    border: 1px solid rgba(67, 97, 238, 0.4);
}
.badge.bg-status-completed {
    background-color: #ddf5e6 !important;
    color: #146c37 !important;
    border: 1px solid rgba(52, 199, 89, 0.45);
}
.badge.bg-status-cancelled {
    background-color: #eeeef0 !important;
    color: #55555b !important;
    border: 1px solid rgba(134, 134, 139, 0.4);
}
.badge.bg-no-show {
    background-color: #ece2fb !important;
    color: #4d2b8c !important;
    border: 1px solid rgba(111, 66, 193, 0.4);
}
.badge.bg-unprocessed {
    background-color: #fce0d0 !important;
    color: #9c3600 !important;
    border: 1px solid rgba(230, 81, 0, 0.45);
}
.badge {
    font-weight: 600;
}

/* 通用狀態徽章同樣走 tint（2026-08-01 複評）：原本只有預約狀態 tint 化，
   商品訂單/票券/點數等列表仍是 100% 飽和實心，同一套系統出現兩種視覺語言。
   ⚠️ 限定 .data-table-body td 內，頁首說明區與 Modal 的實心徽章維持不變
   （那些是「圖例」用途，需要跟表格內的實際狀態對照，色塊本身即說明）。 */
/* ⚠️ opt-out：「計數警示徽章」必須維持實心（2026-08-02 第四輪複評抓到我自己造成的 regression）
   把 tint 去 scope 後規則擴散到全站，側欄「預約管理 16」「顧客訊息 3」與頁首「待處理: 12」
   從實心紅/橘變成近黑側欄上的淡粉藥丸 —— 那是「需要一眼看到的待辦數」，不是狀態標籤。
   凡是計數用途的徽章掛 .badge-count 即可 opt-out。 */
.badge.badge-count.bg-danger {
    /* 白字計數徽章（側欄「預約管理 16」等）：#ff3b30 配白字 3.55:1 → 深一階 5.75:1（2026-10-01 2H） */
    background-color: var(--danger-text) !important;
    color: #fff !important;
    border: none;
}
.badge.badge-count.bg-warning {
    background-color: var(--warning-color) !important;
    color: #1d1d1f !important;
    border: none;
}
.badge.badge-count.bg-primary {
    background-color: var(--primary-color) !important;
    color: #fff !important;
    border: none;
}

.badge.bg-success,
.badge.bg-primary,
.badge.bg-warning,
.badge.bg-secondary,
.badge.bg-danger,
.badge.bg-info {
    font-weight: 600;
}
.badge.bg-success {
    background-color: #ddf5e6 !important;
    color: #146c37 !important;
    border: 1px solid rgba(52, 199, 89, 0.45);
}
.badge.bg-primary {
    background-color: #e4eaff !important;
    color: #24358f !important;
    border: 1px solid rgba(67, 97, 238, 0.4);
}
.badge.bg-warning {
    background-color: #fff1d6 !important;
    color: #7a4f00 !important;
    border: 1px solid rgba(255, 159, 10, 0.45);
}
.badge.bg-secondary {
    background-color: #eeeef0 !important;
    color: #55555b !important;
    border: 1px solid rgba(134, 134, 139, 0.4);
}
.badge.bg-danger {
    background-color: #ffe5e3 !important;
    color: #a51f16 !important;
    border: 1px solid rgba(255, 59, 48, 0.4);
}
.badge.bg-info {
    background-color: #e2f4fd !important;
    color: #1a6b8f !important;
    border: 1px solid rgba(90, 200, 250, 0.5);
}

/* ========================================
   設定頁通知 tab 分組卡片化（2026-07-31 質感審計 #6）
   20+ switch 瀑布 → gray-50 圓角區塊分組 + 放大 switch + 標題層級
   （只包 wrapper div，input/label 順序與 id 不動）
   ======================================== */

.settings-group {
    background-color: #fafafa;
    border: 1px solid #e8e8ed;
    border-radius: var(--border-radius-lg);
    padding: 1.25rem 1.25rem 0.75rem;
    margin-bottom: 1rem;
}
.settings-group > h6 {
    font-weight: 700;
    margin-bottom: 1rem;
}
/* 2026-09-30：原本這裡另外給 settings-group 的開關一組 2.4em×1.3em＋padding-left:3.1em／margin-left:-3.1em。
   全站勾選框／開關已改成 tenant.css 的兩欄 grid（尺寸只由 --fc-w／--fc-h 決定），
   這組負邊距在 grid 裡會把開關拉出自己的欄位（特異度 0,3,0 還蓋得過 grid 那條），已刪除。
   設定頁的開關因此與全站同尺寸（桌機 40×24、觸控 44×28，符合 WCAG 24px）。 */

/* 卡片式列表（portfolio）的主要動作鈕：ghost 但保留一圈淡框，
   讓「編輯」在卡片底部仍是可辨識的按鈕，而不是一段裸文字 */
.btn-ghost-bordered {
    border-color: #e3e6ef;
    color: #4a5169;
    background: #fff;
}
.btn-ghost-bordered:hover,
.btn-ghost-bordered:focus-visible {
    border-color: rgba(67, 97, 238, 0.35);
}

/* ========================================
   狀態圖例（.legend-inline）— 全站單一元件（2026-08-02 第 12 輪評審）
   之前同一種東西有三種做法：products/campaigns 在卡表頭、bookings 是卡片外裸列、
   coupons 是帶左色條的獨立橫幅。改成統一放列表卡表頭右側。
   手機不顯示（390px 排不下，且列表本身已把狀態併進主要欄副標行）。
   ======================================== */
.legend-inline {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem 1rem;
    margin-left: auto;
    font-size: 0.8125rem;
    color: #6e6e73;
    align-items: center;
}
@media (max-width: 991.98px) {
    .legend-inline { display: none; }
}

/* 圖例「同時是篩選器」時（campaigns 2026-09-08 群組 4）：不可在手機隱藏。
   原本這排只是說明文字，藏起來沒有損失；改成可點之後藏起來＝手機／平板完全沒有篩選入口。
   小螢幕只留徽章本身（.legend-text 是說明文字，排不下就收起來）。 */
.legend-inline--filter .campaign-filter { cursor: pointer; }
/* 2026-10-15：沒選中的徽章原本調成 0.55 透明，字只剩 2.2～3.6:1（手機 axe 稽核）。改成徽章永遠不透明，
   「選中哪一顆」用外框藍圈表示（顏色以外的訊號，色盲也分得出）。 */
.legend-inline--filter .campaign-filter .badge { transition: box-shadow .15s; }
.legend-inline--filter .campaign-filter.active .badge { box-shadow: 0 0 0 2px #fff, 0 0 0 4px var(--primary-color); }
.legend-inline--filter .campaign-filter:hover .badge { box-shadow: 0 0 0 2px #fff, 0 0 0 4px var(--border-color); }
.legend-inline--filter .campaign-filter.active:hover .badge { box-shadow: 0 0 0 2px #fff, 0 0 0 4px var(--primary-color); }
@media (max-width: 991.98px) {
    .legend-inline--filter { display: flex; gap: 0.35rem 0.5rem; }
    .legend-inline--filter .legend-text { display: none; }
}

/* ========================================
   2026-10-01 UX 改版 1A：共用元件
   對應 common.js 的 showConfirm(opts)／showDangerConfirm／showPrompt／showCopyDialog、
   renderEmptyState／renderLoadFailure、trackPageDirty 儲存列、runInstantSave 狀態、bindSeg。
   全部是新 class，舊頁面沒有用到就零影響。
   ======================================== */

/* ---------- 對話框（只作用在新版對話框 .app-dialog；舊的 showConfirm 不帶 opts 時不會有這個 class） ---------- */
.app-dialog .modal-body {
    overflow-wrap: anywhere;
}
.app-dialog .app-dialog-message {
    display: block;
    white-space: pre-line;
    color: var(--dark-color);
    font-size: var(--fs-body);
    line-height: 1.6;
}
.app-dialog .modal-footer > .btn {
    min-height: 40px;
}
.app-dialog-danger .modal-title {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}
.app-dialog-danger-icon {
    color: var(--danger-color);
    flex: 0 0 auto;
}
.app-prompt-meta {
    display: flex;
    gap: 0.5rem;
    margin-top: 0.375rem;
}
.app-prompt-meta .form-text {
    margin-top: 0;
}
.app-prompt-count {
    margin-left: auto;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}
.app-copy-field {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: var(--fs-caption);
    background-color: var(--neutral-subtle);
}
.app-copy-field[readonly] {
    background-color: var(--neutral-subtle);
}
@media (pointer: coarse) {
    .app-dialog .modal-footer > .btn {
        min-height: 44px;
    }
}
/* 手機：兩顆鈕並排各佔一半、至少 44px 高，長動詞（「取消這筆預約」）可折行，不擠出視窗 */
@media (max-width: 575.98px) {
    .app-dialog .modal-footer {
        flex-wrap: nowrap;
        gap: 0.5rem;
    }
    .app-dialog .modal-footer > .btn {
        flex: 1 1 0;
        min-width: 0;
        min-height: 44px;
        margin: 0;
        white-space: normal;
    }
}

/* ---------- 空狀態與載入失敗（刻意兩種長相：灰色＝真的沒有；琥珀色虛線框＝讀不到） ---------- */
.app-empty,
.app-load-failure {
    text-align: center;
    padding: 2.5rem 1rem;
    max-width: 30rem;
    margin: 0 auto;
}
.app-empty-icon {
    display: inline-block;
    font-size: 3rem;          /* 48px（09-30 報告方向 5） */
    line-height: 1;
    color: var(--secondary-color);
    margin-bottom: 0.75rem;
}
.app-empty-title {
    font-size: var(--fs-card-title);
    font-weight: 600;
    color: var(--dark-color);
    margin-bottom: 0.25rem;
    overflow-wrap: break-word;
}
.app-empty-desc {
    font-size: var(--fs-caption);
    color: var(--text-secondary);
    line-height: 1.6;
    margin: 0 auto 0.875rem;
    overflow-wrap: break-word;
}
.app-empty-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    justify-content: center;
}
.app-empty-compact {
    padding: 1.25rem 0.75rem;
}
.app-empty-compact .app-empty-icon {
    font-size: 2rem;
    margin-bottom: 0.5rem;
}
.app-load-failure {
    background-color: #fffaf2;
    border: 1px dashed rgba(255, 159, 10, 0.55);
    border-radius: var(--radius-lg);
    margin: 0.75rem auto;
}
.app-load-failure .app-empty-icon {
    color: var(--warning-text);
}
.app-load-failure-code {
    font-size: var(--fs-min);
    color: var(--text-secondary);
    margin-bottom: 0.75rem;
    font-variant-numeric: tabular-nums;
}
/* 表格裡的空狀態那一列：不吃 hover 底色與底線 */
.table > tbody > tr.app-block-row > td {
    --bs-table-bg-state: transparent;
    --bs-table-accent-bg: transparent;
    border-bottom-width: 0;
    padding: 0.5rem;
    white-space: normal;
}
@media (max-width: 575.98px) {
    .app-empty,
    .app-load-failure {
        padding: 1.75rem 0.75rem;
    }
    .app-empty-icon {
        font-size: 2.5rem;
    }
    .app-empty-actions > .btn {
        flex: 1 1 auto;
        min-height: 44px;
    }
}

/* ---------- 提示框三級：說明 notice-info／提醒 notice-warn／錯誤 notice-error ----------
   說明：淺灰底、無邊框、13px 次要文字，長的用 details 收合（initCollapsibleNotices 記住開合）
   提醒：白底卡＋左側 4px 色條（預設黃；加 notice-primary 變藍）＋右側一個動作
   錯誤：左側 4px 紅條＋淺紅底
   顯示／隱藏請用 d-none（BootstrapDisplayOverrideGuardTest），不要在 .notice 上寫 inline display。 */
.notice {
    display: flex;
    align-items: flex-start;
    gap: 0.625rem;
    padding: 0.75rem 1rem;
    margin-bottom: 1rem;
    border-radius: var(--radius-md);
    font-size: var(--fs-caption);
    line-height: 1.6;
}
.notice > .bi:first-child {
    flex: 0 0 auto;
    font-size: 1rem;
    line-height: 1.35;
}
.notice-body {
    flex: 1 1 auto;
    min-width: 0;
    overflow-wrap: break-word;
}
.notice-title {
    font-size: var(--fs-body);
    font-weight: 600;
    margin-bottom: 0.125rem;
}
.notice-action {
    flex: 0 0 auto;
    align-self: center;
}
/* 連結型按鈕（<a class="btn">）被撐高或撐寬時文字要置中——<button> 會自動置中，<a> 不會 */
.notice-action > .btn,
.app-empty-actions > .btn,
.save-bar-actions > .btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.notice-info {
    background-color: var(--neutral-subtle);
    color: var(--text-secondary);
    border: 0;
}
.notice-info .notice-title {
    color: var(--dark-color);
}
.notice-warn {
    background-color: #fff;
    color: var(--dark-color);
    border: 1px solid var(--border-color);
    border-left: 4px solid var(--warning-color);
    box-shadow: var(--shadow-sm);
}
.notice-warn > .bi:first-child {
    color: var(--warning-text);
}
.notice-warn.notice-primary {
    border-left-color: var(--primary-color);
}
.notice-warn.notice-primary > .bi:first-child {
    color: var(--primary-color);
}
.notice-error {
    background-color: var(--danger-subtle);
    color: var(--dark-color);
    border: 0;
    border-left: 4px solid var(--danger-color);
}
.notice-error > .bi:first-child,
.notice-error .notice-title {
    color: var(--danger-text);
}
/* 可收合說明：details.notice（summary＝露出的那一句） */
details.notice {
    display: block;
}
details.notice > summary {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    cursor: pointer;
    list-style: none;
    color: var(--dark-color);
    font-weight: 500;
}
details.notice > summary::-webkit-details-marker {
    display: none;
}
details.notice > summary::after {
    content: "";
    flex: 0 0 auto;
    margin-left: auto;
    width: 0.5rem;
    height: 0.5rem;
    border-right: 2px solid var(--secondary-color);
    border-bottom: 2px solid var(--secondary-color);
    transform: rotate(45deg) translate(-2px, -2px);
    transition: transform 0.15s ease;
}
details.notice[open] > summary::after {
    transform: rotate(-135deg) translate(-2px, -2px);
}
details.notice > summary:focus-visible {
    outline: 2px solid var(--primary-color);
    outline-offset: 2px;
    border-radius: var(--radius-sm);
}
details.notice > .notice-body {
    margin-top: 0.5rem;
}
@media (pointer: coarse) {
    details.notice > summary {
        min-height: 44px;
    }
}
/* 欄位說明「一行重點＋說明」：details.notice.notice-inline（2026-10-21 老闆：說明太多看起來很複雜）
   <details class="notice notice-inline">
     <summary>一行重點（新寫的短句）</summary>
     <div class="notice-body">完整說明（原文一字不刪）</div>
   </details>
   summary 是原生的展開鈕：鍵盤 Enter／Space、展開狀態自動告訴輔助科技，觸控沿用上面 44px。
   後面的「說明／收起」是 CSS 字，不必每處重寫。沒有 data-notice-key＝不記開合（每次預設收起）。
   不可收的（照舊整段展開，不要包進來）：會造成不可逆後果、會收錢或停止收錢、會讓顧客端當下失效的警告
   （例：Messaging API 啟用後不能改 Provider、停用金流後顧客無法付款、還原後顧客不會收到通知）。 */
details.notice.notice-inline {
    display: block;
    padding: 0;
    margin: 0.25rem 0 0;
    background: none;
    border: 0;
    border-radius: 0;
    color: var(--text-secondary);
    font-size: var(--fs-caption);
    line-height: 1.5;
}
details.notice.notice-inline > summary {
    display: block;
    color: var(--text-secondary);
    font-weight: 400;
}
details.notice.notice-inline > summary::after {
    content: "說明 ▾";
    display: inline-block;
    width: auto;
    height: auto;
    margin-left: 0.375rem;
    border: 0;
    transform: none;
    color: var(--primary-text);
    font-weight: 500;
    white-space: nowrap;
    text-decoration: underline dotted;
    text-underline-offset: 3px;
}
details.notice.notice-inline[open] > summary::after {
    content: "收起 ▴";
    transform: none;
}
details.notice.notice-inline > .notice-body {
    margin-top: 0.25rem;
    padding-left: 0.625rem;
    border-left: 2px solid var(--border-color);
    color: var(--text-secondary);
}
@media (pointer: coarse) {
    /* 觸控：整列至少 44px 高（沿用上面 details.notice 的 min-height），字仍是一般段落排法、「說明」緊接在句尾 */
    details.notice.notice-inline > summary {
        display: block;
        padding: 0.625rem 0;
    }
}
@media (max-width: 575.98px) {
    .notice {
        flex-wrap: wrap;
    }
    .notice-action {
        flex: 1 1 100%;
    }
    .notice-action > .btn {
        width: 100%;
        min-height: 44px;
    }
}

/* ---------- 分段選擇 .seg（同一種切換只留這一個長相；bindSeg 處理選中） ---------- */
.seg {
    display: inline-flex;
    gap: 2px;
    padding: 2px;
    max-width: 100%;
    background-color: var(--seg-bg);
    border-radius: var(--radius-md);
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    vertical-align: middle;
}
.seg::-webkit-scrollbar {
    display: none;
}
.seg-item {
    flex: 0 0 auto;
    min-height: 32px;
    padding: 0.3rem 0.875rem;
    border: 0;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--text-secondary);
    font-size: var(--fs-body);
    font-weight: 500;
    line-height: 1.4;
    white-space: nowrap;
    cursor: pointer;
    transition: background-color 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;
}
.seg-item:hover {
    color: var(--dark-color);
}
.seg-item.active {
    background-color: #fff;
    color: var(--dark-color);
    font-weight: 600;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
}
.seg-item:focus-visible {
    outline: 2px solid var(--primary-color);
    outline-offset: 1px;
}
.seg-item:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}
.seg-block {
    display: flex;
    width: 100%;
}
.seg-block > .seg-item {
    flex: 1 1 0;
}
@media (pointer: coarse) {
    .seg-item {
        min-height: 44px;
    }
}

/* ---------- 底部儲存列（trackPageDirty 的 saveBar；乾淨時 d-none） ---------- */
.save-bar {
    position: sticky;     /* #content-wrapper 刻意用 overflow-x: clip 而不是 hidden，sticky 才有效 */
    bottom: 0;
    z-index: 1020;
    margin-top: 1rem;
    padding-bottom: calc(0.5rem + env(safe-area-inset-bottom, 0px));
}
.save-bar-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.625rem 0.75rem 0.625rem 1rem;
    background-color: #fff;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    box-shadow: 0 -2px 16px rgba(0, 0, 0, 0.08);
}
.save-bar-status {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    min-width: 0;
    font-size: var(--fs-body);
    font-weight: 600;
    color: var(--warning-text);
}
.save-bar-dot {
    flex: 0 0 auto;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background-color: var(--warning-color);
}
.save-bar-actions {
    display: flex;
    gap: 0.5rem;
    flex: 0 0 auto;
}
.save-bar.is-saved .save-bar-status {
    color: var(--success-text);
}
.save-bar.is-saved .save-bar-dot {
    background-color: var(--success-color);
}
.save-bar.is-saved .save-bar-actions {
    visibility: hidden;
}
@media (max-width: 575.98px) {
    .save-bar-inner {
        flex-wrap: wrap;
    }
    .save-bar-actions {
        flex: 1 1 100%;
    }
    .save-bar-actions > .btn {
        flex: 1 1 0;
        min-height: 44px;
    }
}

/* ---------- 即存欄位的小字狀態（runInstantSave／createSaveStatus） ---------- */
.save-status {
    display: inline-block;
    margin-left: 0.5rem;
    font-size: var(--fs-min);
    font-weight: 500;
    vertical-align: middle;
}
.save-status:empty {
    display: none;
}
.save-status.is-saving {
    color: var(--text-secondary);
}
.save-status.is-saved {
    color: var(--success-text);
}
.save-status.is-failed {
    color: var(--danger-text);
}

/* ---------- 時間下拉（.form-control.time-select）補下拉箭頭 ----------
   全站約 48 處時間下拉寫成 form-control 而不是 form-select，Bootstrap 的 form-control 不畫箭頭，
   看起來像純文字欄（09-30 後台報告：營業時間設定在 iPhone 上）。只補這個組合，
   已經是 form-select 的、或光禿禿的 select.time-select 都不動。 */
select.form-control.time-select {
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    padding-right: 2.25rem;
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%236e6e73' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
    background-repeat: no-repeat;
    background-position: right 0.75rem center;
    background-size: 16px 12px;
}
select.form-control.form-control-sm.time-select {
    padding-right: 1.75rem;
    background-position: right 0.5rem center;
    background-size: 14px 10px;
}
