/* 陸府生活家 後台 —— 設計系統
   來源：kingown-design（慶旺興業品牌規範）。色彩取自制服印製色票
   PANTONE 2228 U #12B6CB（主）與 PANTONE 2008 U #F7C376（輔），
   標準字灰 #7C7D7D 展開為中性階。字體為源泉圓體 GenSenMaruGothicTW。

   本檔分兩段：
     1. 前半是品牌基底，元件（按鈕、表單、表格、對話框）沿用 king-own-web/styles.css
        的同一段；**色票則直接對齊「慶旺興業 Design System」的 tokens/colors.css**，
        因此與前台不同 —— 前台的青／沙色階整體位移了一階，詳見下方色階區塊的說明。
        另外多了一組 DS 的資訊藍，前台沒有。
     2. 「後台擴充」段是側欄、資料表、狀態徽章、計價編輯器這些前台沒有的元件。
        前台的市集元件（服務卡、分類磚）沒有帶過來，後台用不到。

   後台是工作介面不是行銷頁：字級與間距整體比前台緊一階（見後台擴充段開頭）。 */

/* ── 字體 ───────────────────────────────────────────────────────────
   子集化的 woff2 由 tools/build-fonts.sh 產生（原始 TTF 每個 14MB）。
   子集只含站內出現過的字，改文案後請重跑該腳本。 */
@font-face{font-family:"GenSenMaruGothicTW";font-style:normal;font-weight:400;font-display:swap;
  src:url("assets/fonts/GenSenMaruGothicTW-Regular.woff2") format("woff2")}
@font-face{font-family:"GenSenMaruGothicTW";font-style:normal;font-weight:500;font-display:swap;
  src:url("assets/fonts/GenSenMaruGothicTW-Medium.woff2") format("woff2")}
@font-face{font-family:"GenSenMaruGothicTW";font-style:normal;font-weight:700;font-display:swap;
  src:url("assets/fonts/GenSenMaruGothicTW-Bold.woff2") format("woff2")}
@font-face{font-family:"GenSenMaruGothicTW";font-style:normal;font-weight:900;font-display:swap;
  src:url("assets/fonts/GenSenMaruGothicTW-Heavy.woff2") format("woff2")}

:root {
  --color-bg: #ffffff;
  --color-surface: #f4f5f5;       /* 沉陷面：分區底色、卡片底 */
  --color-text: #1e1f1f;
  --color-accent: #12b6cb;        /* PANTONE 2228 U */
  --color-accent-2: #f7c376;      /* PANTONE 2008 U —— 全站唯一的強調色，一個畫面最多一處 */
  --color-divider: #e9eaea;
  /* 深色面 —— 側欄與登入頁。用 DS semantic.css 的 --surface-inverse（neutral-900）。
     前台那支 styles.css 這個位置是深橄欖 #383F33，那是「陸府生活家」頁尾的顏色，
     屬於前台白牌的視覺，後台不沿用。 */
  --color-inverse: #1e1f1f;       /* DS neutral-900 */

  /* 中性階 —— 以標準字灰 #7C7D7D 為 500 展開 */
  --color-neutral-25: #fafbfb;
  --color-neutral-50: #f4f5f5;
  --color-neutral-100: #e9eaea;
  --color-neutral-200: #d6d7d7;
  --color-neutral-300: #bcbdbd;
  --color-neutral-400: #9c9d9d;
  --color-neutral-500: #7c7d7d;
  --color-neutral-600: #626363;
  --color-neutral-700: #4a4b4b;
  --color-neutral-800: #333434;
  --color-neutral-900: #1e1f1f;

  /* 主色階 —— 青（PANTONE 2228 U）
     值取自「慶旺興業 Design System」的 tokens/colors.css，逐階對齊。
     注意：前台 king-own-web 的同一段色階整體位移了一階（它的 accent-50 與
     accent-100 重複都是 #E7F8FA，因此少了 DS 的 cyan-400 #26BFD2）。
     後台以 DS 為準，兩邊的 --color-accent-100 ~ -400 因此不同值。 */
  --color-accent-50:  #e7f8fa;    /* DS cyan-50  */
  --color-accent-100: #c4eff4;    /* DS cyan-100 */
  --color-accent-200: #8ee0ea;    /* DS cyan-200 */
  --color-accent-300: #52cedd;    /* DS cyan-300 */
  --color-accent-400: #26bfd2;    /* DS cyan-400 —— 前台沒有這一階 */
  --color-accent-500: #12b6cb;    /* DS cyan-500 */
  --color-accent-600: #0e96a8;
  --color-accent-700: #0b7685;
  --color-accent-800: #095b66;
  --color-accent-900: #06424a;

  /* 輔色階 —— 沙（PANTONE 2008 U）。同樣依 DS 對齊，補回 sand-500 #F2AF4E。 */
  --color-accent-2-50:  #fef7eb;  /* DS sand-50  */
  --color-accent-2-100: #fdecd1;  /* DS sand-100 */
  --color-accent-2-200: #fbdca9;  /* DS sand-200 */
  --color-accent-2-300: #f9ce8b;  /* DS sand-300 */
  --color-accent-2-400: #f7c376;  /* DS sand-400 —— 品牌輔色本色 */
  --color-accent-2-500: #f2af4e;  /* DS sand-500 —— 前台沒有這一階 */
  --color-accent-2-600: #de9528;
  --color-accent-2-700: #b4761d;
  --color-accent-2-800: #8a5a16;
  --color-accent-2-900: #5e3d0f;

  /* 狀態色 —— 刻意壓抑，不與品牌青搶眼 */
  --color-danger-100: #fbddd8;
  --color-danger-500: #e04e3c;
  --color-danger-700: #a33325;
  --color-success-100: #d6f2e5;
  --color-success-500: #1fa971;
  --color-success-700: #14724d;

  /* 資訊藍 —— DS 有這一組，前台沒用到，後台需要它。
     後台的青色已經被按鈕、連結、側欄選中態、列 hover 佔滿；狀態徽章若也用青色，
     眼睛分不出「這是可以點的」還是「這是狀態」。進行中的狀態改用藍色，
     青色就專心表示互動。 */
  --color-info-100: #d9ebfa;
  --color-info-500: #3b87ce;
  --color-info-700: #25608f;

  --font-body: "GenSenMaruGothicTW", "Noto Sans TC", "PingFang TC", "Microsoft JhengHei", sans-serif;
  --font-heading: var(--font-body);
  --font-heading-weight: 700;

  /* 中文需要字距才透氣；純英數串用 0 */
  --tracking-cjk: 0.04em;
  --tracking-cjk-tight: 0.02em;
  --tracking-caps: 0.12em;

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

  /* 標誌是四塊磚，每塊被切掉一個特大四分圓；圓角因此走得寬 */
  --radius-sm: 6px;
  --radius-md: 10px;   /* 控件 */
  --radius-lg: 20px;   /* 卡片 */
  --radius-xl: 28px;   /* 大面板 */
  --radius-pill: 999px;
  --radius-tile-cut: 70px;  /* 那個特大四分圓，一個畫面用一到兩次 */

  /* 陰影一律低對比、純中性、無彩色偏移 */
  --shadow-sm: 0 1px 2px rgba(30, 31, 31, .06);
  --shadow-md: 0 6px 16px -4px rgba(30, 31, 31, .10);
  --shadow-lg: 0 14px 32px -8px rgba(30, 31, 31, .14);
  --shadow-brand: 0 8px 20px -6px rgba(18, 182, 203, .45);  /* 唯一的彩色陰影：主按鈕 hover */
  --ring-brand: 0 0 0 3px rgba(18, 182, 203, .28);
  --ring-danger: 0 0 0 3px rgba(224, 78, 60, .26);

  /* 主要動作色 —— 刻意偏離設計系統，請見下方說明。
     「慶旺興業 Design System」的 tokens/semantic.css 定義
     --action-primary: var(--cyan-500) (#12B6CB)，按鈕配白字。
     但白字對 #12B6CB 的對比只有 2.45:1，遠低於 WCAG AA 對 14px 粗體要求的 4.5:1。
     後台是一天要看八小時的工作介面，可讀性優先，因此改用 cyan-700 (#0B7685)，
     對比 5.36:1，通過 AA，色相仍在品牌青系內。
     若要回到規範原色，把下面三行換成 -500 / -600 / -700（會失去 AA 合規）。 */
  --action-primary: var(--color-accent-700);
  --action-primary-hover: var(--color-accent-800);
  --action-primary-active: var(--color-accent-900);

  /* 黏著元素的上緣位移。頁首捲動後約 61px 高，留一點空隙。
     試算面板、篩選欄、金額摘要都用這個值，改一次全站一致。 */
  --sticky-top: 76px;

  /* 動態：短、單向、無彈跳 */
  --ease-out: cubic-bezier(.22, .61, .36, 1);
  --dur-fast: 140ms;
  --dur-base: 200ms;
}

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-neutral-700);
  font-family: var(--font-body);
  font-size: 16px;
  font-weight: 400;
  line-height: 1.65;
  letter-spacing: var(--tracking-cjk);
  -webkit-font-smoothing: antialiased;
  text-wrap: pretty;
}

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  color: var(--color-text);
  line-height: 1.2;
  letter-spacing: var(--tracking-cjk-tight);
  margin: 0 0 var(--space-2);
  text-wrap: balance;
}
h1 { font-size: 44px; }
h2 { font-size: 30px; }
h3 { font-size: 24px; }
h4 { font-size: 18px; }
h5 { font-size: 16px; }
h6 { font-size: 13px; letter-spacing: var(--tracking-caps); text-transform: uppercase; }

p { margin: 0 0 var(--space-3); }
a { color: var(--color-accent-700); text-decoration: none; text-underline-offset: 3px;
    transition: color var(--dur-fast) var(--ease-out); }
a:hover { color: var(--color-accent-800); text-decoration: underline; }
img { display: block; max-width: 100%; }
figure { margin: 0; }
figcaption { font-size: 12px; margin-top: var(--space-1); color: var(--color-neutral-500); }
.text-muted { color: var(--color-neutral-500); }
:focus { outline: none; }
:focus-visible { outline: none; box-shadow: var(--ring-brand); border-radius: var(--radius-sm); }
::selection { background: var(--color-accent-200); color: var(--color-accent-900); }

/* 品牌造型母題：磚塊被切掉一個特大四分圓 */
.tile-cut-br { border-bottom-right-radius: var(--radius-tile-cut); }
.tile-cut-tr { border-top-right-radius: var(--radius-tile-cut); }

/* — 分隔線 — */
.hr { height: 1px; border: 0; margin: var(--space-4) 0; background: var(--color-divider); }

/* — 圖框 —
   品牌不做濾鏡、不加顆粒、不用網點：照片就是照片，只給圓角與底色。 */
.fig {
  overflow: hidden;
  border-radius: var(--radius-lg);
  background: var(--color-neutral-100);
}

/* — 數據 —
   取代原本的 CMYK 分色數字；重量由字重與青色承擔，不靠印刷特效。 */
.stat-num {
  font-family: var(--font-heading);
  font-weight: 900;
  line-height: 1.1;
  letter-spacing: 0;
  color: var(--color-accent-700);
}

/* — 圖示 —
   規範明訂不用 emoji、也不用 unicode 符號（✓ ★ ✕）當圖示。這裡以 CSS mask
   內嵌 Lucide 圖形（2px 圓端圓角描邊，與圓體的圓收筆同調），因此會繼承
   currentColor，尺寸跟著字級走。 */
.icon {
  display: inline-block; width: 1em; height: 1em; flex: none;
  vertical-align: -0.13em; background-color: currentColor;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center; mask-position: center;
  -webkit-mask-size: contain; mask-size: contain;
}
.i-check {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><path d='M20 6 9 17l-5-5'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><path d='M20 6 9 17l-5-5'/></svg>");
}
.i-star {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M12 2.6l2.9 5.9 6.5.9-4.7 4.6 1.1 6.4-5.8-3-5.8 3 1.1-6.4L2.6 9.4l6.5-.9z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M12 2.6l2.9 5.9 6.5.9-4.7 4.6 1.1 6.4-5.8-3-5.8 3 1.1-6.4L2.6 9.4l6.5-.9z'/></svg>");
}
.i-bell {
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M10.3 21a2 2 0 0 0 3.4 0'/><path d='M3.3 15.3A1 1 0 0 0 4 17h16a1 1 0 0 0 .7-1.7C19.4 14 18 12.5 18 8A6 6 0 0 0 6 8c0 4.5-1.4 6-2.7 7.3'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M10.3 21a2 2 0 0 0 3.4 0'/><path d='M3.3 15.3A1 1 0 0 0 4 17h16a1 1 0 0 0 .7-1.7C19.4 14 18 12.5 18 8A6 6 0 0 0 6 8c0 4.5-1.4 6-2.7 7.3'/></svg>");
}
/* 未讀圓點 */
.unread {
  display: inline-block; width: 8px; height: 8px; flex: none;
  border-radius: 50%; background: var(--color-accent-2-600); margin-right: 10px;
  vertical-align: 0.1em;
}

/* — 按鈕 —
   Hover 加深一階，主按鈕亮起品牌陰影；Press 下移 1px 再深一階。
   永不縮放：scale 與圓體的柔和收筆相衝。 */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  cursor: pointer; text-decoration: none;
  font-family: var(--font-heading); font-weight: 700;
  font-size: 14px; line-height: 1.2; letter-spacing: var(--tracking-cjk-tight);
  color: var(--color-neutral-800);
  background: transparent; border: 1.5px solid transparent;
  padding: 11px 20px; min-height: 44px;
  border-radius: var(--radius-md);
  transition: background-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out),
              transform var(--dur-fast) var(--ease-out);
}
.btn:hover { text-decoration: none; }
.btn:active { transform: translateY(1px); }
.btn svg { display: block; }
.btn:disabled, .btn[aria-disabled="true"] {
  background: var(--color-neutral-100); color: var(--color-neutral-400);
  border-color: transparent; cursor: not-allowed; transform: none; box-shadow: none;
}
.btn-primary { background: var(--action-primary); color: #fff; border-color: var(--action-primary); }
.btn-primary:hover { background: var(--action-primary-hover); border-color: var(--action-primary-hover);
                     color: #fff; box-shadow: var(--shadow-brand); }
.btn-primary:active { background: var(--action-primary-active); border-color: var(--action-primary-active); box-shadow: none; }
/* 次要按鈕依規範是青色髮絲外框，不是中性灰框 */
.btn-secondary { background: #fff; color: var(--color-accent-700); border-color: var(--color-accent-500); }
.btn-secondary:hover { background: var(--color-accent-100); color: var(--color-accent-800); border-color: var(--color-accent-500); }
.btn-secondary:active { background: var(--color-accent-200); }
.btn-ghost { color: var(--color-accent-700); padding-inline: var(--space-3); }
.btn-ghost:hover { background: var(--color-neutral-50); color: var(--color-accent-800); }
.btn-ghost:active { background: var(--color-neutral-100); }
.btn-icon { width: 44px; height: 44px; padding: 0; }
.btn-block { width: 100%; margin-top: var(--space-2); }

/* — 表單 — */
.field > label {
  display: block; font-size: 14px; font-weight: 500; margin-bottom: 6px;
  color: var(--color-neutral-800);
}
.input {
  width: 100%; min-height: 44px; padding: 10px 14px; font: inherit;
  font-size: 15px; letter-spacing: var(--tracking-cjk);
  color: var(--color-neutral-900); caret-color: var(--color-accent-500);
  background: #fff;
  border: 1.5px solid var(--color-neutral-200); border-radius: var(--radius-md);
  transition: border-color var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out);
}
.input::placeholder { color: var(--color-neutral-400); }
.input:hover { border-color: var(--color-neutral-300); }
.input:focus-visible { border-color: var(--color-accent-500); box-shadow: var(--ring-brand); }
.input[aria-invalid="true"] { border-color: var(--color-danger-500); }
.input[aria-invalid="true"]:focus-visible { box-shadow: var(--ring-danger); }
textarea.input { min-height: 110px; resize: vertical; line-height: 1.65; }
select.input { appearance: none; padding-right: 40px; cursor: pointer;
  background-image: linear-gradient(45deg, transparent 50%, var(--color-neutral-500) 50%),
                    linear-gradient(135deg, var(--color-neutral-500) 50%, transparent 50%);
  background-position: calc(100% - 20px) 50%, calc(100% - 14px) 50%;
  background-size: 6px 6px, 6px 6px; background-repeat: no-repeat; }

.radio { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; font-size: 15px; }
.radio input, .seg-opt input {
  position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none;
}
.radio .dot {
  width: 20px; height: 20px; flex: none; border-radius: 50%;
  border: 1.5px solid var(--color-neutral-300);
  transition: border-color var(--dur-fast) var(--ease-out), background-color var(--dur-fast) var(--ease-out);
}
.radio:hover .dot { border-color: var(--color-accent-500); }
.radio input:checked + .dot {
  border-color: var(--color-accent-500); background: var(--color-accent-500);
  box-shadow: inset 0 0 0 5px #fff;
}
.radio input:focus-visible + .dot { box-shadow: var(--ring-brand); }

/* 分段控制項 */
.seg {
  display: inline-flex; overflow: hidden;
  border: 1.5px solid var(--color-neutral-200); border-radius: var(--radius-md);
  background: #fff;
}
.seg-opt {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 10px 16px; font-size: 14px; font-weight: 500; cursor: pointer;
  color: var(--color-neutral-700);
  transition: background-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.seg-opt + .seg-opt { border-left: 1.5px solid var(--color-neutral-200); }
.seg-opt:has(input:checked) { background: var(--action-primary); color: #fff; }
.seg-opt:not(:has(input:checked)):hover { background: var(--color-neutral-50); }
.seg-opt:has(input:focus-visible) { box-shadow: inset var(--ring-brand); }

/* — 卡片 — */
.card {
  display: flex; flex-direction: column; gap: var(--space-2);
  padding: var(--space-6); border-radius: var(--radius-lg);
  background: #fff; border: 1px solid var(--color-divider);
}
.card-kicker {
  font-size: 12px; font-weight: 500; letter-spacing: var(--tracking-caps);
  text-transform: uppercase; color: var(--color-accent-700);
}
.card-title {
  font-family: var(--font-heading); font-weight: 700;
  font-size: 18px; line-height: 1.3; letter-spacing: var(--tracking-cjk-tight);
  color: var(--color-text);
}
.card-body { margin: 0; font-size: 14px; color: var(--color-neutral-600); flex: 1; }
.card-meta { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--color-neutral-500); }
.elev-sm { box-shadow: var(--shadow-sm); }
.elev-md { box-shadow: var(--shadow-md); }
.elev-lg { box-shadow: var(--shadow-lg); }

/* — 標籤 — */
.tag {
  display: inline-flex; align-items: center; gap: 5px; font-size: 12px; font-weight: 500;
  letter-spacing: var(--tracking-cjk-tight); padding: 4px 12px;
  border-radius: var(--radius-pill);
}
.tag-accent { background: var(--color-accent-100); color: var(--color-accent-800); }
.tag-accent-2 { background: var(--color-accent-2-200); color: var(--color-accent-2-900); }
.tag-neutral { background: var(--color-neutral-100); color: var(--color-neutral-700); }
.tag-outline { border: 1.5px solid var(--color-accent-500); color: var(--color-accent-700); }
.tag-danger { background: var(--color-danger-100); color: var(--color-danger-700); }
.tag-success { background: var(--color-success-100); color: var(--color-success-700); }

/* — 導覽 —
   黏性頁首是全站唯一的黏性元素，白色 88% + blur(14px)。
   各頁 nav 帶著 inline 的 max-width:1160px，這裡用 padding 把內容列置中，
   讓底色能滿版出血；因此需要 !important 蓋掉那個 inline 寬度。 */
.nav {
  display: flex; align-items: center; gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
  position: sticky; top: 0; z-index: 40;
  max-width: none !important;
  padding-inline: max(var(--space-6), calc((100% - 1160px) / 2));
  background: rgba(255, 255, 255, .88);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--color-divider);
}
.nav-brand {
  display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--font-heading); font-weight: 700;
  font-size: 20px; letter-spacing: var(--tracking-cjk-tight);
  color: var(--color-text); margin-right: auto;
}
/* 橫式標誌最小使用高度 28px；34px 讓副標的 KING OWN Ltd. 還讀得出來 */
.nav-brand img { height: 34px; width: auto; }
.nav-brand:hover { text-decoration: none; color: var(--color-text); }
.nav a { color: var(--color-neutral-700); text-decoration: none; font-size: 15px; font-weight: 500; }
.nav a:hover { color: var(--color-accent-700); text-decoration: none; }
.nav a[aria-current='page'] { color: var(--color-accent-700); }
.nav .btn-primary, .nav .btn-secondary, .nav .btn-ghost { color: unset; }
.nav .btn-primary { color: #fff; }

/* — 表格 — */
.table { width: 100%; border-collapse: collapse; font-size: 15px; }
.table th {
  text-align: left; font-size: 12px; font-weight: 500;
  letter-spacing: var(--tracking-caps); text-transform: uppercase;
  color: var(--color-neutral-500);
  padding: var(--space-3) var(--space-2); border-bottom: 1px solid var(--color-neutral-200);
}
.table td { padding: var(--space-3) var(--space-2); border-bottom: 1px solid var(--color-divider); }
.table tbody tr { transition: background-color var(--dur-fast) var(--ease-out); }
.table tbody tr:hover { background: var(--color-neutral-25); }

/* — 對話框 — */
.dialog-backdrop {
  position: fixed; inset: 0; display: grid; place-items: center;
  padding: var(--space-4);
  background: rgba(30, 31, 31, .55);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
}
.dialog {
  width: min(480px, 100%); display: flex; flex-direction: column; gap: var(--space-3);
  padding: var(--space-8); border-radius: var(--radius-xl);
  background: #fff; box-shadow: var(--shadow-lg);
}
.dialog-title {
  font-family: var(--font-heading); font-weight: 700; font-size: 24px;
  letter-spacing: var(--tracking-cjk-tight); color: var(--color-text);
}
.dialog-body { font-size: 15px; color: var(--color-neutral-600); }
.dialog-actions { display: flex; justify-content: flex-end; gap: var(--space-2); margin-top: var(--space-2); }

/* ══════════════════════════════════════════════════════════════════════
   後台擴充 —— king-own-admin
   前台是行銷頁，一屏講一件事，字級大、留白多。後台是一天要看八小時的工作
   介面，同一屏要塞下三十列訂單，所以整體緊一階：內文 15px、標題階梯壓低、
   表格列高 44px。這一段只覆寫尺寸，顏色與圓角一律沿用上面的品牌變數。
   ══════════════════════════════════════════════════════════════════════ */

body {
  font-size: 15px;
  line-height: 1.6;
  background: var(--color-neutral-25);
}
h1 { font-size: 26px; }
h2 { font-size: 21px; }
h3 { font-size: 17px; }
h4 { font-size: 15px; }

:root {
  --side-w: 240px;
  --topbar-h: 60px;
}

/* — 版面骨架 —
   側欄固定不捲，內容區自己捲。整頁不捲（body overflow hidden）是為了讓
   資料表的 sticky 表頭有明確的捲動容器；掛在 body 上的話 iOS Safari 會跳。 */
.shell {
  display: grid;
  grid-template-columns: var(--side-w) 1fr;
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
}

/* — 側欄 —
   淺色面，用 DS 的 --surface-sunken（neutral-50）。整個後台因此有三層深度：
   側欄（最沉）→ 內容區 neutral-25 → 面板純白。層次靠明度差與一條分隔線做出來，
   不靠陰影，也不靠大面積色塊。
   選中項的品牌青是側欄上唯一的顏色，一眼就知道現在在哪一頁。 */
.side {
  display: flex; flex-direction: column;
  background: var(--color-neutral-50);
  border-right: 1px solid var(--color-divider);
  color: var(--color-neutral-600);
  overflow-y: auto;
}
.side-brand {
  display: flex; align-items: center; gap: var(--space-3);
  padding: var(--space-6) var(--space-6) var(--space-4);
  flex: none;
}
/* 四塊磚母題。淺灰底上直接用全彩版，青與沙都跳得出來。 */
.side-brand .mark { width: 28px; height: auto; flex: none; }
.side-brand .tx { min-width: 0; }
.side-brand .wm {
  display: block; font-family: var(--font-heading); font-weight: 900; font-size: 17px;
  letter-spacing: var(--tracking-cjk-tight); color: var(--color-text); white-space: nowrap;
}
.side-brand .sub {
  display: block; font-size: 10px; font-weight: 500; letter-spacing: var(--tracking-caps);
  text-transform: uppercase; color: var(--color-accent-700); margin-top: 1px;
}
.side-nav { flex: 1; padding-bottom: var(--space-6); }
.side-group {
  padding: var(--space-4) var(--space-6) 6px;
  font-size: 11px; font-weight: 500; letter-spacing: var(--tracking-caps);
  text-transform: uppercase; color: var(--color-neutral-400);
}
.side-link {
  display: flex; align-items: center; gap: 10px;
  padding: 9px var(--space-6); font-size: 14px; font-weight: 500;
  color: var(--color-neutral-700); text-decoration: none;
  border-left: 3px solid transparent;
  transition: background-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out);
}
.side-link .icon { font-size: 17px; color: var(--color-neutral-400); }
.side-link:hover {
  background: var(--color-neutral-100); color: var(--color-accent-800); text-decoration: none;
}
.side-link:hover .icon { color: var(--color-accent-600); }
/* 選中項用純白底 —— 側欄是 neutral-50，白色在這裡是「浮起來」，
   剛好跟內容區的白色面板連成一片，視覺上表示「你正在看這一頁」。 */
.side-link[aria-current="page"] {
  background: var(--color-bg); color: var(--color-accent-800); font-weight: 700;
  border-left-color: var(--color-accent-500);
}
.side-link[aria-current="page"] .icon { color: var(--color-accent-600); }
/* 側欄項目右側的待辦數字。0 不顯示 —— 常態掛著一個灰色 0 會讓人不再去看它。 */
.side-badge {
  margin-left: auto; min-width: 20px; padding: 1px 6px;
  font-size: 11px; font-weight: 700; text-align: center;
  border-radius: var(--radius-pill);
  background: var(--color-accent-2-500); color: var(--color-accent-2-900);
}
/* 還沒建置的項目。列出來讓人看得到範圍，但不可點，也不做假的入口。 */
.side-link.is-soon { color: var(--color-neutral-400); cursor: default; }
.side-link.is-soon .icon { color: var(--color-neutral-300); }
.side-link.is-soon .side-badge {
  background: var(--color-neutral-200); color: var(--color-neutral-600); font-weight: 500;
}
.side-foot {
  flex: none; padding: var(--space-4) var(--space-6);
  border-top: 1px solid var(--color-divider);
  font-size: 12px; color: var(--color-neutral-400);
}

/* — 內容區 — */
.body { display: flex; flex-direction: column; overflow: hidden; }

.topbar {
  flex: none; height: var(--topbar-h);
  display: flex; align-items: center; gap: var(--space-4);
  padding-inline: var(--space-8);
  background: #fff; border-bottom: 1px solid var(--color-divider);
}
.crumb { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--color-neutral-500); }
.crumb a { color: var(--color-neutral-600); }
.crumb .icon { font-size: 12px; opacity: .5; }
.crumb b { color: var(--color-neutral-800); font-weight: 500; }
.topbar-side { margin-left: auto; display: flex; align-items: center; gap: var(--space-3); }

/* 角色切換 —— 雛型專用。客戶第一個問題一定是「廠商看到的跟我一樣嗎」，
   與其解釋，不如給一個開關當場切。接了真正的權限系統後這塊直接移除。 */
.role-switch {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 6px 4px 12px; border-radius: var(--radius-pill);
  background: var(--color-accent-2-100); border: 1px solid var(--color-accent-2-300);
  font-size: 12px; color: var(--color-accent-2-900);
}
.role-switch select {
  appearance: none; border: 0; background: transparent; font: inherit;
  font-weight: 700; color: var(--color-accent-2-900); cursor: pointer;
  padding: 2px 4px;
}
.who { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--color-neutral-700); }
.who .av {
  width: 30px; height: 30px; flex: none; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--color-accent-100); color: var(--color-accent-800);
  font-size: 12px; font-weight: 700;
}

.main { flex: 1; overflow-y: auto; padding: var(--space-8); }
.main-narrow { max-width: 960px; }

.page-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--space-6); margin-bottom: var(--space-6);
}
.page-head h1 { margin: 0; }
.page-head .sub { margin: 6px 0 0; font-size: 14px; color: var(--color-neutral-600); }
.page-acts { display: flex; gap: var(--space-2); flex: none; }
/* 後台的按鈕比前台矮一階：一列工具列常常並排四五顆，44px 會把畫面吃光 */
.main .btn { min-height: 38px; padding: 8px 16px; font-size: 14px; }
.main .btn-icon { width: 38px; height: 38px; padding: 0; }
.main .btn-sm { min-height: 30px; padding: 4px 12px; font-size: 13px; border-radius: var(--radius-sm); }

/* — 面板 — */
.panel {
  background: #fff; border: 1px solid var(--color-divider);
  border-radius: var(--radius-lg); overflow: hidden;
}
.panel + .panel { margin-top: var(--space-6); }
.panel-head {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-4);
  padding: var(--space-4) var(--space-6);
  border-bottom: 1px solid var(--color-divider);
}
.panel-head h3 { margin: 0; }
.panel-body { padding: var(--space-6); }
.panel-body-flush { padding: 0; }

/* — 指標卡 —
   數字用 stat-num（品牌規範的青色 900 字重），下面一行說明用中性灰。
   趨勢箭頭只在有比較基準時出現，沒有基準就不要編一個出來。 */
.stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-4); margin-bottom: var(--space-6); }
.stat {
  padding: var(--space-4) var(--space-6);
  background: #fff; border: 1px solid var(--color-divider); border-radius: var(--radius-lg);
}
.stat .k { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--color-neutral-600); }
.stat .k .icon { font-size: 14px; color: var(--color-neutral-400); }
.stat .v { font-size: 30px; margin-top: 4px; }
.stat .d { font-size: 12px; color: var(--color-neutral-500); margin-top: 2px; }
.stat .d.up { color: var(--color-success-700); }
.stat .d.down { color: var(--color-danger-700); }

/* — 篩選列 — */
.filters {
  display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap;
  padding: var(--space-3) var(--space-6);
  border-bottom: 1px solid var(--color-divider);
  background: var(--color-neutral-25);
}
.filters .input { min-height: 34px; padding: 5px 12px; font-size: 14px; width: auto; }
.filters select.input { padding-right: 34px; background-position: calc(100% - 17px) 50%, calc(100% - 11px) 50%; }
.filters .search { position: relative; }
.filters .search .icon {
  position: absolute; left: 11px; top: 50%; transform: translateY(-50%);
  font-size: 15px; color: var(--color-neutral-400); pointer-events: none;
}
.filters .search .input { padding-left: 34px; width: 240px; }
.filters .spacer { margin-left: auto; }
.filters .count { font-size: 13px; color: var(--color-neutral-500); }

/* 狀態快篩。選中的那顆用實心青，未選是髮絲灰框 —— 這排是最常按的東西，
   所以放在篩選列最前面，不藏進下拉選單裡。 */
.chips { display: flex; gap: 6px; flex-wrap: wrap; }
.chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 5px 12px; font-size: 13px; font-weight: 500;
  border-radius: var(--radius-pill); cursor: pointer;
  border: 1px solid var(--color-neutral-200); background: #fff; color: var(--color-neutral-700);
  transition: background-color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.chip:hover { border-color: var(--color-accent-400); color: var(--color-accent-800); }
.chip[aria-pressed="true"] {
  background: var(--action-primary); border-color: var(--action-primary); color: #fff;
}
.chip .n { font-variant-numeric: tabular-nums; opacity: .75; }

/* — 資料表 —
   表頭 sticky 在捲動容器（.main）內。列高壓到 44px，數字欄一律 tabular-nums
   並靠右，金額才對得齊；中文欄位靠左。 */
.dtable { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 14px; }
.dtable th {
  position: sticky; top: 0; z-index: 2;
  text-align: left; white-space: nowrap;
  font-size: 12px; font-weight: 500; letter-spacing: var(--tracking-caps);
  text-transform: uppercase; color: var(--color-neutral-500);
  padding: var(--space-3) var(--space-4);
  background: var(--color-neutral-50);
  border-bottom: 1px solid var(--color-neutral-200);
}
.dtable td {
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--color-divider);
  vertical-align: middle;
}
.dtable tbody tr { transition: background-color var(--dur-fast) var(--ease-out); }
.dtable tbody tr:hover { background: var(--color-accent-50); }
.dtable tbody tr:last-child td { border-bottom: 0; }
.dtable .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.dtable .mono { font-variant-numeric: tabular-nums; letter-spacing: 0; }
.dtable .acts { text-align: right; white-space: nowrap; }
.dtable .t { font-weight: 500; color: var(--color-neutral-900); }
.dtable .s { font-size: 12px; color: var(--color-neutral-500); }
/* 整列可點時，游標與 hover 要說得出來，否則使用者不會知道可以點 */
.dtable tbody tr.row-link { cursor: pointer; }
.tbl-wrap { overflow-x: auto; }

/* — 狀態徽章 —
   狀態是後台看得最快的東西，所以用實心色塊而不是文字。色票對應：
   灰＝還沒開始動、藍＝進行中、沙＝等別人回應、綠＝完成、紅＝中止。
   進行中用 DS 的資訊藍而不是品牌青：青色在後台代表「可以互動」（按鈕、連結、
   選中的側欄項、hover 的列），狀態徽章跟著用青色會分不出兩者。
   一種狀態只准對應一個顏色，不要為了好看換色。 */
.pill {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 10px; font-size: 12px; font-weight: 500; white-space: nowrap;
  border-radius: var(--radius-pill);
  background: var(--color-neutral-100); color: var(--color-neutral-700);
}
.pill::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; opacity: .65; }
.pill-wait    { background: var(--color-neutral-100);    color: var(--color-neutral-700); }
.pill-doing   { background: var(--color-info-100);       color: var(--color-info-700); }
.pill-hold    { background: var(--color-accent-2-200);   color: var(--color-accent-2-900); }
.pill-done    { background: var(--color-success-100);    color: var(--color-success-700); }
.pill-dead    { background: var(--color-danger-100);     color: var(--color-danger-700); }

/* — 狀態流程軸 —
   訂單詳情頁用。已走過的節點填實，當前節點加圈，未來的節點留空。
   讓營運人員一眼看出「現在卡在哪、下一步是誰要動」。 */
.flow { display: flex; align-items: flex-start; gap: 0; padding: var(--space-2) 0; }
.flow-step { flex: 1; text-align: center; position: relative; }
.flow-step .dot {
  width: 14px; height: 14px; margin: 0 auto 8px; border-radius: 50%;
  background: var(--color-neutral-200); position: relative; z-index: 1;
}
.flow-step .lb { font-size: 12px; color: var(--color-neutral-500); }
.flow-step .tm { font-size: 11px; color: var(--color-neutral-400); margin-top: 2px; }
.flow-step::after {
  content: ""; position: absolute; top: 6px; left: 50%; width: 100%; height: 2px;
  background: var(--color-neutral-200);
}
.flow-step:last-child::after { display: none; }
.flow-step.is-past .dot { background: var(--color-accent-500); }
.flow-step.is-past::after { background: var(--color-accent-500); }
.flow-step.is-past .lb { color: var(--color-neutral-700); }
.flow-step.is-now .dot { background: var(--color-accent-600); box-shadow: 0 0 0 4px var(--color-accent-200); }
.flow-step.is-now .lb { color: var(--color-accent-800); font-weight: 700; }

/* — 抽屜 —
   看一筆訂單不該離開列表：右側滑出，關掉還在原本的捲動位置與篩選條件。
   訂單詳情另外有獨立網址（order.html），是為了能貼給同事看。 */
.drawer-backdrop {
  position: fixed; inset: 0; z-index: 40;
  background: rgba(30, 31, 31, .40);
  opacity: 0; pointer-events: none;
  transition: opacity var(--dur-base) var(--ease-out);
}
.drawer-backdrop.is-on { opacity: 1; pointer-events: auto; }
.drawer {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 41;
  width: min(560px, 100vw);
  display: flex; flex-direction: column;
  background: #fff; box-shadow: var(--shadow-lg);
  transform: translateX(100%);
  transition: transform var(--dur-base) var(--ease-out);
}
.drawer.is-on { transform: none; }
.drawer-head {
  flex: none; display: flex; align-items: center; justify-content: space-between; gap: var(--space-4);
  padding: var(--space-4) var(--space-6); border-bottom: 1px solid var(--color-divider);
}
.drawer-head h3 { margin: 0; }
.drawer-body { flex: 1; overflow-y: auto; padding: var(--space-6); }
.drawer-foot {
  flex: none; display: flex; gap: var(--space-2); justify-content: flex-end;
  padding: var(--space-4) var(--space-6); border-top: 1px solid var(--color-divider);
  background: var(--color-neutral-25);
}

/* — 敘述式欄位 —
   聯絡資訊、施作地址這種「標籤：值」的成對資料。表格太重，段落又散。 */
.kv { display: grid; grid-template-columns: 96px 1fr; gap: 10px var(--space-4); font-size: 14px; }
.kv dt { color: var(--color-neutral-500); }
.kv dd { margin: 0; color: var(--color-neutral-900); }

/* — 表單版面 — */
.form-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-4) var(--space-6); }
.form-grid .full { grid-column: 1 / -1; }
/* A 軌：原本只作用在 .field 底下，但「解釋這個數字或這個區塊怎麼來的」到處都需要
   （報價有效期、金額出處、未指派件數），選擇器放寬成單獨的 .hint。 */
.hint { font-size: 12px; color: var(--color-neutral-500); margin-top: 4px; }
.field .err { font-size: 12px; color: var(--color-danger-700); margin-top: 4px; }
.main .input { min-height: 38px; padding: 7px 12px; font-size: 14px; }
.main textarea.input { min-height: 88px; }
.main select.input { padding-right: 36px; background-position: calc(100% - 18px) 50%, calc(100% - 12px) 50%; }
.field-row { display: flex; gap: var(--space-2); align-items: center; }
.field-row .input { flex: 1; }
.suffix { font-size: 13px; color: var(--color-neutral-500); white-space: nowrap; }

/* 勾選框 —— 基底只有 radio，加購項編輯器需要 checkbox */
.check { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; font-size: 14px; }
.check input { position: absolute; opacity: 0; width: 0; height: 0; }
.check .box {
  width: 18px; height: 18px; flex: none; border-radius: var(--radius-sm);
  border: 1.5px solid var(--color-neutral-300); background: #fff;
  display: grid; place-items: center; color: transparent; font-size: 11px;
  transition: background-color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}
.check:hover .box { border-color: var(--color-accent-500); }
.check input:checked + .box {
  background: var(--action-primary); border-color: var(--action-primary); color: #fff;
}
.check input:focus-visible + .box { box-shadow: var(--ring-brand); }

/* — 分頁 — */
.tabs { display: flex; gap: var(--space-6); border-bottom: 1px solid var(--color-divider); padding-inline: var(--space-6); }
.tab {
  padding: var(--space-3) 0; font-size: 14px; font-weight: 500; cursor: pointer;
  color: var(--color-neutral-600); background: none; border: 0; border-bottom: 2px solid transparent;
  transition: color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}
.tab:hover { color: var(--color-accent-800); }
.tab[aria-selected="true"] { color: var(--color-accent-800); border-bottom-color: var(--color-accent-500); }

/* — 空狀態 — */
.empty { padding: 64px var(--space-6); text-align: center; color: var(--color-neutral-500); }
.empty .icon { font-size: 40px; color: var(--color-neutral-300); }
.empty h4 { margin: var(--space-3) 0 4px; color: var(--color-neutral-700); }
.empty p { font-size: 14px; margin: 0; }

/* — 浮出提示 — */
.toast {
  position: fixed; left: 50%; bottom: 28px; z-index: 60;
  display: flex; align-items: center; gap: 10px;
  padding: 12px 20px; border-radius: var(--radius-pill);
  background: var(--color-neutral-900); color: #fff; font-size: 14px;
  box-shadow: var(--shadow-lg);
  transform: translate(-50%, 12px); opacity: 0;
  transition: opacity var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out);
}
.toast.is-on { transform: translate(-50%, 0); opacity: 1; }
.toast .icon { color: var(--color-accent-300); }

/* — 登入頁 —
   後台登入不套 .shell，自己一個置中版面。 */
.auth { min-height: 100vh; display: grid; place-items: center; padding: var(--space-6);
        background: var(--color-inverse); }
.auth-box {
  width: 100%; max-width: 380px; padding: var(--space-8);
  background: #fff; border-radius: var(--radius-xl); box-shadow: var(--shadow-lg);
}
.auth-box h1 { font-size: 22px; margin-bottom: 4px; }
.auth-box .lead { font-size: 14px; color: var(--color-neutral-600); margin-bottom: var(--space-6); }
.auth-demo {
  margin-top: var(--space-6); padding-top: var(--space-4);
  border-top: 1px solid var(--color-divider);
  font-size: 12px; color: var(--color-neutral-500);
}

/* — 計價編輯器 —
   服務編輯頁的核心。左邊是欄位，右邊黏著即時試算。
   sticky 掛在 <aside> 而不是裡面的面板：這個 grid 設了 align-items:start，
   aside 只有內容高度，掛在子元素上就沒有可黏的空間（前台踩過同一個坑）。 */
.edit-layout { display: grid; grid-template-columns: 1fr 360px; gap: var(--space-8); align-items: start; }
.edit-layout > aside { position: sticky; top: 0; max-height: calc(100dvh - var(--topbar-h) - var(--space-8) * 2); overflow-y: auto; }

/* 加價項編輯器的一列。控件與效果各自是下拉，右邊是金額，最右是刪除。 */
.mod-row {
  display: grid; grid-template-columns: 1.4fr 110px 130px 110px 34px;
  gap: var(--space-2); align-items: center;
  padding: var(--space-3); border: 1px solid var(--color-divider);
  border-radius: var(--radius-md); background: var(--color-neutral-25);
}
.mod-row + .mod-row { margin-top: var(--space-2); }
.mod-row .input { min-height: 34px; font-size: 13px; padding: 5px 10px; }
.mod-row select.input { padding-right: 30px; background-position: calc(100% - 15px) 50%, calc(100% - 9px) 50%; }
.mod-opts { grid-column: 1 / -1; padding-left: var(--space-4); border-left: 2px solid var(--color-accent-200); }
.mod-opt { display: grid; grid-template-columns: 1fr 110px 110px 34px; gap: var(--space-2); align-items: center; }
.mod-opt + .mod-opt { margin-top: 6px; }
.mod-head {
  display: grid; grid-template-columns: 1.4fr 110px 130px 110px 34px; gap: var(--space-2);
  padding: 0 var(--space-3) 6px;
  font-size: 11px; font-weight: 500; letter-spacing: var(--tracking-caps);
  text-transform: uppercase; color: var(--color-neutral-500);
}

/* 級距編輯器 */
.tier-row { display: grid; grid-template-columns: 1fr 130px 1fr 34px; gap: var(--space-2); align-items: center; }
.tier-row + .tier-row { margin-top: var(--space-2); }
.tier-row .input { min-height: 34px; font-size: 13px; padding: 5px 10px; }

/* 條列編輯器（服務內容、不包含、流程、常見問題） */
.list-row { display: grid; grid-template-columns: 1fr 34px; gap: var(--space-2); align-items: center; }
.list-row + .list-row { margin-top: 6px; }
.list-row .input { min-height: 34px; font-size: 13px; padding: 5px 10px; }

/* — 即時試算 —
   欄位一動就重算，用的是 js/pricing.js，跟前台同一支檔案。
   後台看到的金額就是前台會算出來的金額，不會兩套邏輯各自漂移。 */
.calc { padding: var(--space-4) var(--space-6); }
.calc h4 { margin: 0 0 var(--space-3); }
.calc-line { display: flex; justify-content: space-between; gap: var(--space-4); font-size: 13px; padding: 5px 0; }
.calc-line.sub { color: var(--color-neutral-600); padding-left: var(--space-3); }
.calc-line .v { font-variant-numeric: tabular-nums; white-space: nowrap; }
.calc-total {
  display: flex; justify-content: space-between; align-items: baseline;
  margin-top: var(--space-3); padding-top: var(--space-3);
  border-top: 1px solid var(--color-divider);
}
.calc-total .v { font-size: 22px; }

/* 起價可達性 —— 這是後台唯一會擋下存檔的檢查。
   卡片上寫「NT$1,600 起」就必須真的有一種組合是 1,600；廣告價低於實際最低價
   是欺騙使用者，所以是 error 不是 warning。反過來（有折扣讓實際更低）只提示。 */
.floor-check { margin-top: var(--space-4); padding: var(--space-3) var(--space-4); border-radius: var(--radius-md); font-size: 13px; }
.floor-check .r { display: flex; justify-content: space-between; gap: var(--space-4); }
.floor-check .r + .r { margin-top: 4px; }
.floor-check .v { font-variant-numeric: tabular-nums; font-weight: 700; }
.floor-ok   { background: var(--color-success-100); color: var(--color-success-700); }
.floor-note { background: var(--color-accent-2-100); color: var(--color-accent-2-900); }
.floor-bad  { background: var(--color-danger-100);  color: var(--color-danger-700); }
.floor-check .msg { margin-top: 6px; font-size: 12px; opacity: .9; }

/* — 行內提示條 —
   需要解釋當前狀態、但還不到錯誤程度的地方。改色就變成警示或錯誤版。 */
.note {
  display: flex; align-items: flex-start; gap: 8px;
  padding: var(--space-3) var(--space-4); margin-bottom: var(--space-6);
  background: var(--color-accent-2-100); border: 1px solid var(--color-accent-2-300);
  border-radius: var(--radius-md); font-size: 13px; color: var(--color-accent-2-900);
}
.note .icon { font-size: 15px; flex: none; margin-top: 2px; }

/* — 計價編輯器的窄螢幕（B 軌）—
   上面的窄螢幕段落只把 .mod-row 與 .mod-head 收成兩欄，漏了 .mod-opt 與 .tier-row。
   這兩個的欄寬是寫死的 px（110/110/34），420px 上加起來就超過容器，
   最右邊那顆刪除鈕會被切掉 —— 按不到，不只是難看。跟著 .mod-row 一起收成兩欄。 */
@media (max-width: 900px) {
  .mod-opt, .tier-row { grid-template-columns: 1fr 1fr; }
}

/* — 資料表的最小寬度（B 軌）—
   .tbl-wrap 設了 overflow-x: auto，但表格本身是 width: 100%，
   所以窄螢幕上它不會溢出、而是把欄位一路壓扁 —— 中文欄位會變成一行一個字，
   橫向捲動永遠不會出現。給一個最小寬度，窄螢幕才會改成橫向捲動而不是把字擠成一行一個。

   為什麼是 1080 而不是 max-content：服務列表十一欄的自然寬度約 1230px，
   用 max-content 的話 1440px 視窗（側欄佔掉 240px）也要橫向捲動才看得到「編輯」鈕，
   那是把窄螢幕的問題搬到桌機上。1080 剛好讓 1440px 視窗完整放得下，
   又足以讓「居家清潔」這種四字欄位維持一行。 */
.tbl-wrap .dtable { min-width: 1080px; }

/* — 上下架切換（B 軌）—
   服務與分類都要在列表上直接切換上下架。用一顆會變色的小按鈕而不是 checkbox：
   一列裡已經有一個批次選取的 checkbox，兩個方框並排會分不出誰是誰。
   下架不是錯誤狀態，所以用中性灰而不是紅色 —— 紅色留給「起價不符」那種真的要修的事。 */
.sw {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 10px; font-size: 12px; font-weight: 500; white-space: nowrap;
  border-radius: var(--radius-pill); cursor: pointer;
  border: 1px solid var(--color-success-100); background: var(--color-success-100);
  color: var(--color-success-700);
  transition: background-color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}
.sw .icon { font-size: 13px; }
.sw:hover { border-color: var(--color-success-700); }
.sw.is-off {
  background: var(--color-neutral-100); border-color: var(--color-neutral-200);
  color: var(--color-neutral-600);
}
.sw.is-off:hover { border-color: var(--color-neutral-400); }
/* 下架的列整列壓暗，掃一眼就知道哪些東西前台看不到 */
.dtable tbody tr.is-off .t, .dtable tbody tr.is-off td { color: var(--color-neutral-500); }

/* — 排序上下移（B 軌）—
   分類與輪播都是十來筆的手排清單，用上下移而不是拖曳：沒有相依套件，鍵盤也按得到。
   到頂或到底的那一顆要 disabled，不然按了沒反應會被當成壞掉。 */
.ord-btns { display: inline-flex; flex-direction: column; gap: 2px; }
.ord-btns .btn { width: 26px; height: 20px; min-height: 0; padding: 0; border-radius: var(--radius-sm); }
.ord-btns .icon { font-size: 13px; }

/* — 照片欄位（B 軌）—
   服務、商品、輪播三張表都有一個 photo 欄位，吃 Pexels 編號、完整網址，
   或上傳後轉成的 data URL。三頁共用同一組控件與同一支縮圖邏輯。 */
.photo-field { display: grid; grid-template-columns: 108px 1fr; gap: var(--space-4); align-items: start; }
.photo-thumb {
  aspect-ratio: 4 / 3; border-radius: var(--radius-md); overflow: hidden;
  background: var(--color-neutral-100); display: grid; place-items: center;
  border: 1px solid var(--color-divider);
}
.photo-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.photo-thumb .icon { font-size: 22px; color: var(--color-neutral-400); }
.photo-acts { display: flex; gap: var(--space-2); margin-top: 6px; flex-wrap: wrap; }
.photo-field input[type="file"] { display: none; }

/* ── 對象（C 軌）───────────────────────────────────────────────────
   會員、票券、合作申請這三頁看的都是「一個對象＋它的狀態」，
   下面三組是它們共用的單元。只有兩頁以上用得到的才放這裡，
   單頁專用的（例如廠商編輯的區域多選）留在頁內 <style>。 */

/* — 對象列 —
   頭像＋名字＋一行副標。會員列表、票券核銷、合作申請、會員詳情都是這個形狀。
   頭像用姓名末兩字（見 KO.fmt.initials），沒有真的大頭照要放。 */
.person { display: flex; align-items: center; gap: 10px; min-width: 0; }
.person .av {
  width: 34px; height: 34px; flex: none; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--color-accent-100); color: var(--color-accent-800);
  font-size: 12px; font-weight: 700; letter-spacing: 0;
}
.person .av.is-org { border-radius: var(--radius-sm); background: var(--color-neutral-100); color: var(--color-neutral-700); }
.person .tx { min-width: 0; display: flex; flex-direction: column; line-height: 1.35; }
.person .n { font-weight: 500; color: var(--color-neutral-900); }
.person .m { font-size: 12px; color: var(--color-neutral-500); }
.person .n, .person .m { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* — 票券餘額列 —
   會員詳情與票券核銷頁共用。條狀進度是「已核銷 ÷ 已購買」——
   營運人員最常被問的是「我還剩幾次」，所以剩餘次數要比條狀圖更顯眼。 */
.wal { padding: var(--space-4) var(--space-6); border-bottom: 1px solid var(--color-divider); }
.wal:last-child { border-bottom: 0; }
.wal-h { display: flex; align-items: baseline; gap: var(--space-3); }
.wal-h .t { font-size: 15px; font-weight: 700; color: var(--color-neutral-900); }
.wal-h .left { margin-left: auto; font-variant-numeric: tabular-nums; white-space: nowrap; }
.wal-h .left b { font-size: 20px; }
.wal-bar {
  margin-top: var(--space-3); height: 6px; border-radius: var(--radius-pill);
  background: var(--color-neutral-100); overflow: hidden; display: flex;
}
.wal-bar > i { display: block; height: 100%; }
.wal-bar > .used { background: var(--color-accent-500); }
.wal-bar > .gone { background: var(--color-danger-100); }
.wal-meta {
  display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-4);
  margin-top: 6px; font-size: 12px; color: var(--color-neutral-500);
}
.wal-meta .soon { color: var(--color-accent-2-900); font-weight: 500; }

/* — 多選標籤 —
   可服務區域、可承接分類。項目多（十六個行政區）、彼此不互斥、選好之後要能一眼掃完，
   用一排可切換的標籤比十六個 checkbox 省一半高度。
   合作申請的「一鍵轉廠商」與廠商編輯頁用的是同一組，所以放這裡。
   一律加上 .picks 前綴：.pick 這個名字太通用，orders.html 的勾選欄
   （td.pick / th.pick）也叫這個，不限定範圍會把表格儲存格變成一顆藥丸。 */
.picks { display: flex; flex-wrap: wrap; gap: 6px; }
.picks .pick {
  display: inline-flex; align-items: center; gap: 5px; cursor: pointer;
  padding: 5px 11px; border-radius: var(--radius-pill); font-size: 13px;
  border: 1.5px solid var(--color-neutral-200); background: #fff;
  color: var(--color-neutral-700);
  transition: border-color var(--dur-fast) var(--ease-out), background-color var(--dur-fast) var(--ease-out);
}
.picks .pick:hover { border-color: var(--color-accent-400); }
.picks .pick input { position: absolute; opacity: 0; width: 0; height: 0; }
.picks .pick:has(input:checked) {
  border-color: var(--action-primary); background: var(--color-accent-50);
  color: var(--color-accent-800); font-weight: 500;
}
.picks .pick:has(input:focus-visible) { box-shadow: var(--ring-brand); }

/* — 時間軸 —
   聯絡紀錄與申請歷程。跟 order.html 的 .log 是同一個視覺，但那一支只有訂單頁用，
   等第三批把兩邊收斂成一個之前先各自留著，不要為了共用先動 A 軌的檔。 */
.tl { position: relative; padding-left: var(--space-6); }
.tl::before {
  content: ""; position: absolute; left: 5px; top: 6px; bottom: 6px;
  width: 2px; background: var(--color-divider);
}
.tl-item { position: relative; padding-bottom: var(--space-4); }
.tl-item:last-child { padding-bottom: 0; }
.tl-item::before {
  content: ""; position: absolute; left: calc(-1 * var(--space-6) + 1px);
  top: 6px; width: 10px; height: 10px; border-radius: 50%;
  background: var(--color-accent-500);
}
.tl-item.is-muted::before { background: var(--color-neutral-300); }
.tl-item .w { font-size: 14px; color: var(--color-neutral-900); }
.tl-item .m { font-size: 12px; color: var(--color-neutral-500); margin-top: 2px; }
.tl-item .x { position: absolute; right: 0; top: 0; opacity: 0; transition: opacity var(--dur-fast) var(--ease-out); }
.tl-item:hover .x, .tl-item:focus-within .x { opacity: 1; }

/* — 窄螢幕 —
   後台預設在桌機用。平板以下把側欄收成圖示條，再窄就疊成單欄；
   這裡只求不破版，真正的行動版介面等客戶確認流程後再做。 */
@media (max-width: 1180px) {
  .stats { grid-template-columns: repeat(2, 1fr); }
  .edit-layout { grid-template-columns: 1fr; }
  .edit-layout > aside { position: static; max-height: none; }
}
@media (max-width: 900px) {
  :root { --side-w: 64px; }
  .side-brand { justify-content: center; padding-inline: 0; }
  .side-brand .tx, .side-link span, .side-group, .side-foot { display: none; }
  .side-link { justify-content: center; padding-inline: 0; }
  .side-badge { display: none; }
  .main { padding: var(--space-4); }
  .topbar { padding-inline: var(--space-4); }
  .form-grid { grid-template-columns: 1fr; }
  .mod-row, .mod-head { grid-template-columns: 1fr 1fr; }
}

/* — 圖示 —
   全部是 Lucide 0.474.0，以 CSS mask 內嵌（規範：不用 emoji、不用 unicode 符號當圖示）。
   前半段與前台同一組（分類圖標要一致），後半段是後台才用得到的。 */
.i-sparkles  { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M9.9 2.5 12 8l5.5 2.1L12 12.2 9.9 17.7 7.8 12.2 2.3 10.1 7.8 8z'/><path d='M18 5v4'/><path d='M20 7h-4'/><path d='M17 17v3'/><path d='M18.5 18.5h-3'/></svg>"); }
.i-wind      { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M12.8 19.6A2 2 0 1 0 14 16H2'/><path d='M17.5 8a2.5 2.5 0 1 1 2 4H2'/><path d='M9.8 4.4A2 2 0 1 1 11 8H2'/></svg>"); }
.i-hammer    { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='m15 12-8.4 8.4a2.1 2.1 0 0 1-3-3L12 9'/><path d='M17.6 6.4 22 10.8'/><path d='m18 15 4-4a3 3 0 0 0-4.2-4.2L9.4 15.2'/><path d='m21.5 11.5-1.9-1.9'/></svg>"); }
.i-bug       { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='m8 2 1.9 1.9'/><path d='M14.1 3.9 16 2'/><path d='M9 7.1V6a3 3 0 1 1 6 0v1.1'/><path d='M7.1 12H2'/><path d='M22 12h-5.1'/><path d='M3 19a9 9 0 0 1 3-7'/><path d='M21 19a9 9 0 0 0-3-7'/><path d='M12 20v-9'/><path d='M6.5 9.5A6 6 0 0 1 12 7a6 6 0 0 1 5.5 2.5'/><path d='M6 12v3a6 6 0 0 0 12 0v-3'/></svg>"); }
.i-truck     { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M14 18V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v11a1 1 0 0 0 1 1h2'/><path d='M14 9h4l4 4v4a1 1 0 0 1-1 1h-2'/><circle cx='7' cy='18' r='2'/><circle cx='17' cy='18' r='2'/><path d='M9 18h6'/></svg>"); }
.i-leaf      { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M11 20A7 7 0 0 1 9.8 6.1C15.5 5 17 4.5 19 2c1 2 2 4.2 2 8 0 5.5-4.8 10-10 10Z'/><path d='M2 21c0-3 1.9-5.5 4-7'/></svg>"); }
.i-heart     { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M19 14c1.5-1.5 3-3.2 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.8 0-3 .5-4.5 2-1.5-1.5-2.7-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4 3 5.5l7 7Z'/></svg>"); }
.i-paw       { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='11' cy='4' r='2'/><circle cx='18' cy='8' r='2'/><circle cx='20' cy='16' r='2'/><path d='M9 10a5 5 0 0 1 5 5v3.5a3.5 3.5 0 0 1-6.8 1.2l-.4-1a3.5 3.5 0 0 0-1.7-1.9l-.9-.5A3.5 3.5 0 0 1 4 10Z'/></svg>"); }
.i-bag       { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M6 2 3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4Z'/><path d='M3 6h18'/><path d='M16 10a4 4 0 0 1-8 0'/></svg>"); }
.i-building  { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M6 22V4a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v18Z'/><path d='M6 12H4a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h2'/><path d='M18 9h2a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2h-2'/><path d='M10 6h4'/><path d='M10 10h4'/><path d='M10 14h4'/><path d='M10 18h4'/></svg>"); }
.i-badge     { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M3.9 8.1a2 2 0 0 1 0-2.2l1.1-1.6a2 2 0 0 1 1.2-.8l1.9-.4a2 2 0 0 0 1.2-.8L10.4 1a2 2 0 0 1 3.2 0l1.1 1.3a2 2 0 0 0 1.2.8l1.9.4a2 2 0 0 1 1.2.8l1.1 1.6a2 2 0 0 1 0 2.2l-1 1.7a2 2 0 0 0-.3 1.4l.2 1.9a2 2 0 0 1-.6 1.4l-1.4 1.4a2 2 0 0 1-1.4.6l-1.9-.2a2 2 0 0 0-1.4.3l-1.7 1a2 2 0 0 1-2.2 0l-1.7-1a2 2 0 0 0-1.4-.3l-1.9.2a2 2 0 0 1-1.4-.6L3 15.5a2 2 0 0 1-.6-1.4l.2-1.9a2 2 0 0 0-.3-1.4Z'/><path d='m9 12 2 2 4-4'/></svg>"); }
.i-shield    { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M20 13c0 5-3.5 7.5-7.7 9a1 1 0 0 1-.6 0C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.2-2.7a1 1 0 0 1 1.5 0C14.5 3.8 17 5 19 5a1 1 0 0 1 1 1Z'/><path d='m9 12 2 2 4-4'/></svg>"); }
.i-clock     { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='10'/><path d='M12 6v6l4 2'/></svg>"); }
.i-pin       { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z'/><circle cx='12' cy='10' r='3'/></svg>"); }
.i-chevron-r { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='m9 18 6-6-6-6'/></svg>"); }
.i-search    { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='11' cy='11' r='8'/><path d='m21 21-4.3-4.3'/></svg>"); }
.i-cart      { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='8' cy='21' r='1'/><circle cx='19' cy='21' r='1'/><path d='M2.05 2.05h2l2.66 12.42a2 2 0 0 0 2 1.58h9.78a2 2 0 0 0 1.95-1.57l1.65-7.43H5.12'/></svg>"); }
.i-ticket    { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M2 9a3 3 0 0 1 0 6v2a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-2a3 3 0 0 1 0-6V7a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2Z'/><path d='M13 5v2'/><path d='M13 17v2'/><path d='M13 11v2'/></svg>"); }
.i-file      { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z'/><path d='M14 2v4a2 2 0 0 0 2 2h4'/><path d='M10 9H8'/><path d='M16 13H8'/><path d='M16 17H8'/></svg>"); }
.i-x         { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M18 6 6 18'/><path d='m6 6 12 12'/></svg>"); }
.i-check     { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><path d='M20 6 9 17l-5-5'/></svg>"); }
.i-star      { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M12 2.6l2.9 5.9 6.5.9-4.7 4.6 1.1 6.4-5.8-3-5.8 3 1.1-6.4L2.6 9.4l6.5-.9z'/></svg>"); }

/* 後台專用 */
.i-grid      { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect width='7' height='9' x='3' y='3' rx='1'/><rect width='7' height='5' x='14' y='3' rx='1'/><rect width='7' height='9' x='14' y='12' rx='1'/><rect width='7' height='5' x='3' y='16' rx='1'/></svg>"); }
.i-receipt   { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M4 2v20l2-1 2 1 2-1 2 1 2-1 2 1 2-1 2 1V2l-2 1-2-1-2 1-2-1-2 1-2-1-2 1Z'/><path d='M16 8h-6a2 2 0 1 0 0 4h4a2 2 0 1 1 0 4H8'/><path d='M12 17.5v-11'/></svg>"); }
.i-calendar  { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M8 2v4'/><path d='M16 2v4'/><rect width='18' height='18' x='3' y='4' rx='2'/><path d='M3 10h18'/></svg>"); }
.i-quote     { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M12.5 22H6a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8l4 4v2.5'/><path d='M14 2v4a2 2 0 0 0 2 2h4'/><path d='M13.4 15.6a1 1 0 1 0-3-3l-5 5a2 2 0 0 0-.5.9l-.8 2.9a.5.5 0 0 0 .6.6l2.9-.8a2 2 0 0 0 .9-.5Z'/></svg>"); }
.i-layers    { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M12.8 2.2a2 2 0 0 0-1.7 0L2.6 6.1a1 1 0 0 0 0 1.8l8.6 3.9a2 2 0 0 0 1.7 0l8.6-3.9a1 1 0 0 0 0-1.8Z'/><path d='m22 17.7-9.2 4.1a2 2 0 0 1-1.7 0L2 17.7'/><path d='m22 12.7-9.2 4.1a2 2 0 0 1-1.7 0L2 12.7'/></svg>"); }
.i-package   { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='m7.5 4.3 9 5.1'/><path d='M21 8a2 2 0 0 0-1-1.7l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.7l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z'/><path d='m3.3 7 8.7 5 8.7-5'/><path d='M12 22V12'/></svg>"); }
.i-tag       { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M12.6 2.6A2 2 0 0 0 11.2 2H4a2 2 0 0 0-2 2v7.2a2 2 0 0 0 .6 1.4l8.7 8.7a2.4 2.4 0 0 0 3.4 0l6.6-6.6a2.4 2.4 0 0 0 0-3.4z'/><path d='M7.5 7.5h.01'/></svg>"); }
.i-image     { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect width='18' height='18' x='3' y='3' rx='2'/><circle cx='9' cy='9' r='2'/><path d='m21 15-3.1-3.1a2 2 0 0 0-2.8 0L6 21'/></svg>"); }
.i-users     { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2'/><circle cx='9' cy='7' r='4'/><path d='M22 21v-2a4 4 0 0 0-3-3.9'/><path d='M16 3.1a4 4 0 0 1 0 7.8'/></svg>"); }
.i-user-plus { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2'/><circle cx='9' cy='7' r='4'/><path d='M19 8v6'/><path d='M22 11h-6'/></svg>"); }
.i-chart     { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M3 3v18h18'/><path d='M18 17V9'/><path d='M13 17V5'/><path d='M8 17v-3'/></svg>"); }
.i-settings  { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M12.2 2h-.4a2 2 0 0 0-2 2v.2a2 2 0 0 1-1 1.7l-.4.3a2 2 0 0 1-2 0l-.2-.1a2 2 0 0 0-2.7.7l-.2.4a2 2 0 0 0 .7 2.7l.2.1a2 2 0 0 1 1 1.7v.5a2 2 0 0 1-1 1.8l-.2.1a2 2 0 0 0-.7 2.7l.2.4a2 2 0 0 0 2.7.7l.2-.1a2 2 0 0 1 2 0l.4.3a2 2 0 0 1 1 1.7V20a2 2 0 0 0 2 2h.4a2 2 0 0 0 2-2v-.2a2 2 0 0 1 1-1.7l.4-.3a2 2 0 0 1 2 0l.2.1a2 2 0 0 0 2.7-.7l.2-.4a2 2 0 0 0-.7-2.7l-.2-.1a2 2 0 0 1-1-1.7v-.5a2 2 0 0 1 1-1.7l.2-.1a2 2 0 0 0 .7-2.7l-.2-.4a2 2 0 0 0-2.7-.7l-.2.1a2 2 0 0 1-2 0l-.4-.3a2 2 0 0 1-1-1.7V4a2 2 0 0 0-2-2z'/><circle cx='12' cy='12' r='3'/></svg>"); }
.i-history   { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M3 12a9 9 0 1 0 9-9 9.8 9.8 0 0 0-6.7 2.7L3 8'/><path d='M3 3v5h5'/><path d='M12 7v5l4 2'/></svg>"); }
.i-plus      { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M5 12h14'/><path d='M12 5v14'/></svg>"); }
.i-pencil    { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M21.2 6.8a1 1 0 0 0-4-4L3.8 16.2a2 2 0 0 0-.5.8l-1.3 4.4a.5.5 0 0 0 .6.6l4.4-1.3a2 2 0 0 0 .8-.5z'/><path d='m15 5 4 4'/></svg>"); }
.i-trash     { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M3 6h18'/><path d='M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6'/><path d='M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2'/></svg>"); }
.i-arrow-l   { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='m12 19-7-7 7-7'/><path d='M19 12H5'/></svg>"); }
.i-alert     { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='m21.7 18-8-14a2 2 0 0 0-3.5 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.7-3'/><path d='M12 9v4'/><path d='M12 17h.01'/></svg>"); }
.i-logout    { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4'/><path d='m16 17 5-5-5-5'/><path d='M21 12H9'/></svg>"); }
.i-wallet    { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M19 7V4a1 1 0 0 0-1-1H5a2 2 0 0 0 0 4h15a1 1 0 0 1 1 1v4h-3a2 2 0 0 0 0 4h3a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1'/><path d='M3 5v14a2 2 0 0 0 2 2h15a1 1 0 0 0 1-1v-4'/></svg>"); }
.i-phone     { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M13.8 16.6a1 1 0 0 0 1.2-.3l.4-.5a2 2 0 0 1 1.6-.8h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2A18 18 0 0 1 2 4a2 2 0 0 1 2-2h3a2 2 0 0 1 2 2v3a2 2 0 0 1-.8 1.6l-.5.4a1 1 0 0 0-.3 1.2 14 14 0 0 0 6.4 6.4'/></svg>"); }
.i-trend     { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M16 7h6v6'/><path d='m22 7-8.5 8.5-5-5L2 17'/></svg>"); }
.i-eye       { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M2 12a10.8 10.8 0 0 1 20 0 10.8 10.8 0 0 1-20 0'/><circle cx='12' cy='12' r='3'/></svg>"); }

/* B 軌（商品）新增 */
.i-eye-off   { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M10.7 5.1A10.9 10.9 0 0 1 12 5c7 0 10 7 10 7a13.2 13.2 0 0 1-1.7 2.7'/><path d='M6.6 6.6A13.5 13.5 0 0 0 2 12s3 7 10 7a10 10 0 0 0 5.4-1.6'/><path d='M14.1 14.1a3 3 0 1 1-4.2-4.2'/><path d='m2 2 20 20'/></svg>"); }
.i-copy      { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect width='14' height='14' x='8' y='8' rx='2'/><path d='M4 16a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2'/></svg>"); }
.i-arrow-u   { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='m18 15-6-6-6 6'/></svg>"); }
.i-arrow-d   { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='m6 9 6 6 6-6'/></svg>"); }
.i-upload    { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4'/><path d='m17 8-5-5-5 5'/><path d='M12 3v12'/></svg>"); }
.i-percent   { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M19 5 5 19'/><circle cx='6.5' cy='6.5' r='2.5'/><circle cx='17.5' cy='17.5' r='2.5'/></svg>"); }

/* A 軌（營運）新增 */
.i-chevron-l { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='m15 18-6-6 6-6'/></svg>"); }
.i-download  { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4'/><path d='M7 10l5 5 5-5'/><path d='M12 15V3'/></svg>"); }
.i-paperclip { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M13.2 6.8 7.1 12.9a3 3 0 1 0 4.2 4.2l6.9-6.9a5 5 0 1 0-7-7l-7 6.9a7 7 0 0 0 9.9 9.9L20 14'/></svg>"); }
.i-message   { --d: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z'/></svg>"); }

.i-sparkles, .i-wind, .i-hammer, .i-bug, .i-truck, .i-leaf, .i-heart, .i-paw, .i-bag,
.i-building, .i-badge, .i-shield, .i-clock, .i-pin, .i-chevron-r, .i-search, .i-cart,
.i-ticket, .i-file, .i-x, .i-check, .i-star,
.i-grid, .i-receipt, .i-calendar, .i-quote, .i-layers, .i-package, .i-tag, .i-image,
.i-users, .i-user-plus, .i-chart, .i-settings, .i-history, .i-plus, .i-pencil, .i-trash,
.i-arrow-l, .i-alert, .i-logout, .i-wallet, .i-phone, .i-trend, .i-eye,
.i-eye-off, .i-copy, .i-arrow-u, .i-arrow-d, .i-upload, .i-percent,
.i-chevron-l, .i-download, .i-paperclip, .i-message {
  -webkit-mask-image: var(--d); mask-image: var(--d);
}
