@import url("vendor/roboto.css?v=1");
/* ══════════════════════════════════════════════════════════════════
   ExpertHub Design Tokens — 依《ExpertHub UX Design Guidelines v2.7》
   單一真相來源(6.1):所有頁面第一個載入,任何顏色/間距/字級一律取用變數。
   數值照抄規範,零發明;guideline 改版時只改本檔,全站生效。

   硬性底線(不可改):Token 語意命名(5.1-5.5)、主色 #006CE1、警示 #DB2828、
   字型 Roboto+微軟正黑體、WCAG AA 對比、Focus Ring 不可移除。
   建議預設(可依 6.5 治理流程附理由調整):衍生色階、幾何尺寸。
   ══════════════════════════════════════════════════════════════════ */

:root {
  /* ── 色彩:功能語意(5.4 / 5.4.1)──────────────────────────
     括號內為對白底實測對比度(AA 底線:內文 4.5:1、大字/UI 邊框 3.0:1) */
  --color-primary-default: #006CE1;      /* ASUS Blue-600 (4.96:1) 主鈕/Link/選中/Focus */
  --color-primary-hover:   #0059BC;      /* 深一階:置於底灰上的 Link 用(主色對底灰僅4.47) */
  --color-status-success:  #15803D;      /* 深綠 (於淡綠底 #F0FDF4 為 4.8:1) */
  --color-status-success-bg: #F0FDF4;
  --color-status-warning:  #8A5A00;      /* 警告文字(於淡黃底 5.38:1);規範未給黃色 hex,
                                            此為衍生值,已實算通過 AA(原擬 #B06F00 僅3.73:1 已否決) */
  --color-status-warning-bg: #FDF3E0;
  --color-status-warning-fill: #B45309;  /* 警示「填色」用(白字對其 5.02:1 ✓)。
                                            與 -warning(淡底文字用)分開,避免把文字色
                                            拿去當按鈕底色而顯土黃 —— 同 danger 拆兩色的邏輯 */
  --color-status-danger:   #DB2828;      /* ASUS Red-600 (4.83:1) 破壞性填色/Badge填色 */
  --color-status-danger-text: #B91C1C;   /* 深紅 (於淡紅底 #FEF2F2 為 5.9:1) 錯誤文字 */
  --color-status-danger-bg: #FEF2F2;
  --color-info-text: #006CE1;            /* 資訊態=主色 */
  --color-info-bg:   #EDF4FF;
  /* 狀態邊框(衍生值,僅供 Badge/Alert 描邊用;UI 邊框門檻 3.0:1 非內文) */
  --color-status-success-border: #B5E6D2;
  --color-status-warning-border: #F3DDAE;
  --color-status-danger-border:  #F4C2C2;
  --color-info-border:           #C3DDFB;
  --color-primary-subtle-bg:     #F0F7FF;   /* Outline 按鈕 Hover 底 */
  --color-search-highlight-bg:   #FFF3C4;   /* 搜尋命中標示底(11.5);深色內文置於其上
                                               對比 13.8:1。原本用琥珀字配淡琥珀底只有
                                               1.7:1,命中的關鍵字反而最難讀 */
  --color-skeleton-base:         #EEF0F4;

  /* ── 圖表配色(13章)────────────────────────────────────────
     canvas 內無法使用 CSS 變數,由 JS 以 getComputedStyle 讀出後傳給 Chart.js。
     置於此處的理由:圖表色也該是單一真相來源,且能被 check_contrast.py 驗證。
     全部對白底 ≥3:1(WCAG 1.4.11 圖形物件門檻),已實算。

     seq = 順序型(如銷售階段漏斗):同一色相由深至淺,表達「同一件事的程度差異」。
     cat = 類別型(如訪談型態):不同色相,表達「互不相干的分類」。
     選錯會誤導 —— 對順序型資料用彩虹色,讀者會以為各階段是不同類別。 */
  --chart-seq-1: #002E5F;   /* 13.50:1 */
  --chart-seq-2: #00459A;   /*  9.06:1 */
  --chart-seq-3: #0059BC;   /*  6.66:1 */
  --chart-seq-4: #006CE1;   /*  4.96:1 主色 */
  --chart-seq-5: #2A80D9;   /*  4.05:1 */
  --chart-cat-1: #006CE1;   /*  4.96:1 藍 */
  --chart-cat-2: #15803D;   /*  5.02:1 綠 */
  --chart-cat-3: #B45309;   /*  5.02:1 橙 */
  --chart-cat-4: #6B7785;   /*  4.56:1 灰 */

  /* ── 色彩:文字階層(5.4.1)── */
  --color-text-primary:   #1D2129;       /* 16.1:1 內文/表頭/輸入字 */
  --color-text-secondary: #4E5969;       /* 7.1:1  Label/次要描述 */
  --color-text-tertiary:  #6B7785;       /* 4.6:1  Hint/Placeholder(勿更淺) */
  --color-text-disabled:  #C9CDD4;
  --color-text-inverse:   #FFFFFF;       /* 置於主色/危險色填色之上 */

  /* ── 色彩:背景與邊框 ── */
  --color-bg-body:      #F2F3F5;         /* 系統主背景 */
  --color-bg-container: #FFFFFF;         /* Card / Modal / Drawer */
  --color-bg-subtle:    #FAFBFE;         /* 巢狀區塊/唯讀區 */
  --color-bg-hover:     #F5F7FA;         /* 表頭底/列 Hover/下拉高亮 */
  --color-border:       #E4E7ED;         /* 卡片與分隔線 1px */
  --color-border-strong:#C9CDD4;         /* 輸入框線 */
  --color-focus-ring:   #006CE1;         /* 全域 Focus Outline(不可移除,7.4) */
  --color-overlay-scrim: rgba(35, 37, 44, .6);  /* #23252C @60% Modal/Drawer 遮罩 */

  /* ── 間距:8px 網格(5.1);12px 為 OX 高密度唯一特例 ── */
  --space-3xs: 2px;    /* 極微型邊界補正 */
  --space-2xs: 4px;    /* 微型元件內距 */
  --space-xs:  8px;    /* 原子元件 Gap / 並列按鈕 */
  --space-sm:  12px;   /* OX 緊湊網格:表格行內 Gap、Dense Filter */
  --space-md:  16px;   /* 組件間距、卡片預設 Padding */
  --space-lg:  24px;   /* 主區外距、面板卡片大內距 */
  --space-xl:  32px;   /* 危險按鈕隔離區、區塊分離 */
  --space-2xl: 48px;   /* 頁面級垂直大區塊 */

  /* ── 圓角:內縮比例(5.2)──
     ⚠ Soft Default 偏離(2026-07-30,依 6.5 治理流程留痕):
     規範建議值為 lg 8px / sm 4px;本專案採 lg 12px / sm 6px。
     業務理由:CRM 使用者(業務團隊)實測反映 4/8 過於方硬;ASUS 官網視覺語言
     亦偏柔和。維持規範的硬性部分——Token 語意命名不變、內縮比例不變
     (內層 6 < 外層 12)、未使用膠囊圓角(仍遠低於 20px+ 的行銷風格)。
     若設計系統小組認為應回歸 8/4,改這兩行即可全站生效。 */
  --radius-lg: 12px;   /* 外層容器 Card/Drawer/Modal/Panel */
  --radius-sm: 6px;    /* 內層 Button/Input/Select/Tag/Alert */

  /* ── 字型與字級:八級制(5.5,v2.7 對齊 ASUS)── */
  --font-family: Roboto, "Microsoft JhengHei", "微軟正黑體", "Noto Sans TC", sans-serif;
  --font-size-caption: 12px;   /* 輔助/Hint/趨勢對比 */
  --font-size-body:    14px;   /* 表格與內文 */
  --font-size-h6:      16px;   /* 區塊標題 */
  --font-size-h5:      18px;   /* 卡片標題 */
  --font-size-h4:      20px;   /* 頁面標題 */
  --font-size-h3:      24px;   /* 大區塊標題 */
  --font-size-h2:      30px;
  --font-size-h1:      36px;
  --font-size-metric:  36px;   /* 儀表板指標數值 */
  --font-weight-regular: 400;
  --font-weight-medium:  500;
  --font-weight-semibold:600;
  --font-weight-bold:    700;
  --line-height-tight: 1.4;
  --line-height-base:  1.6;

  /* ── 陰影(5.5):避免更重的擴散陰影 ── */
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, .06);   /* 卡片 Hover */
  --shadow-md: 0 4px 12px rgba(0, 0, 0, .10);  /* Modal/Drawer/Popover */

  /* ── 層級(5.5):間隔 100;Toast/Tooltip 永遠最上 ── */
  --z-sticky:  100;
  --z-drawer:  1000;
  --z-modal:   1100;
  --z-dialog:  1200;   /* 高於 Drawer(6.5) */
  --z-toast:   1300;
  --z-tooltip: 1400;

  /* ── 動效(5.5):B2B 避免 >300ms 裝飾性動畫 ── */
  --duration-fast:   120ms;   /* Hover / Focus */
  --duration-normal: 240ms;   /* Drawer / Modal 進出場 */
  --easing-standard: cubic-bezier(.2, 0, 0, 1);

  /* ── 框架尺寸(4.1 / 6.1):建議預設,可 min/max 響應式 ── */
  --shell-sidebar-width: 240px;
  --shell-topbar-height: 64px;
  /* 品牌字級:走排版級距的 h3(24px)。曾試過 48px,實測在 64px 的列裡佔到 53px
     高、509px 寬,1024–1150px 視窗會把功能膠囊擠到最小尺寸,故收回一級。 */
  --shell-brand-font-size: var(--font-size-h3);
  --modal-width-min: 450px;
  --modal-width-default: 480px;
  --modal-width-large: 700px;
  --drawer-width: 560px;
  --table-header-height: 40px;
  --table-row-height: 48px;
}

/* ── 響應式斷點(5.3.1)供文件參照:xs<768 / sm 768-1023 / md 1024-1439
   / lg 1440-1919(預設驗證基準) / xl ≥1920。CSS 無法定義變數化 media query,
   各頁一律使用這五個值,勿自創斷點。 ── */

/* ══════════════════════════════════════════════════════════════════
   基礎重置與全域樣式
   ══════════════════════════════════════════════════════════════════ */
*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--color-bg-body);
  color: var(--color-text-primary);
  font-family: var(--font-family);
  font-size: var(--font-size-body);
  line-height: var(--line-height-base);
  -webkit-font-smoothing: antialiased;
}

/* Focus Ring 為硬性底線(7.4):不得以 outline:none 移除且不提供替代 */
:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 2px;
}

a { color: var(--color-primary-default); text-decoration: none; }
a:hover { text-decoration: underline; }

/* ── 標題階層 ── */
h1 { font-size: var(--font-size-h1); font-weight: var(--font-weight-bold); margin: 0 0 var(--space-md); }
h2 { font-size: var(--font-size-h2); font-weight: var(--font-weight-semibold); margin: 0 0 var(--space-md); }
h3 { font-size: var(--font-size-h3); font-weight: var(--font-weight-semibold); margin: 0 0 var(--space-sm); }
h4 { font-size: var(--font-size-h4); font-weight: var(--font-weight-semibold); margin: 0 0 var(--space-sm); }
h5 { font-size: var(--font-size-h5); font-weight: var(--font-weight-semibold); margin: 0 0 var(--space-xs); }
h6 { font-size: var(--font-size-h6); font-weight: var(--font-weight-semibold); margin: 0 0 var(--space-xs); }

/* ══════════════════════════════════════════════════════════════════
   共用元件 class(規範第五部分元件庫的基礎樣式)
   ══════════════════════════════════════════════════════════════════ */

/* ── 卡片容器(13.1):白底 + 1px 淡灰框 + 圓角8 + 內距24 ── */
.ux-card {
  background: var(--color-bg-container);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-lg);
}
.ux-card--hover:hover { box-shadow: var(--shadow-sm); }

/* ── 按鈕(3.2 層級 / 6.6 對齊 / 6.4 文案)
   單一工作區僅一個 Filled 主鈕;次要 Outlined;取消 Text ── */
.ux-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2xs);
  min-height: 36px; padding: var(--space-xs) var(--space-md);
  border-radius: var(--radius-sm); border: 1px solid transparent;
  font-family: inherit; font-size: var(--font-size-body); font-weight: var(--font-weight-medium);
  cursor: pointer; transition: background var(--duration-fast) var(--easing-standard),
                               border-color var(--duration-fast) var(--easing-standard);
  text-decoration: none;
}
.ux-btn--primary { background: var(--color-primary-default); color: var(--color-text-inverse); }
.ux-btn--primary:hover { background: var(--color-primary-hover); }
.ux-btn--outline {
  background: var(--color-bg-container); color: var(--color-primary-default);
  border-color: var(--color-primary-default);
}
.ux-btn--outline:hover { background: var(--color-primary-subtle-bg); }
.ux-btn--text { background: transparent; color: var(--color-text-secondary); }
.ux-btn--text:hover { background: var(--color-bg-hover); }
.ux-btn--danger { background: var(--color-status-danger); color: var(--color-text-inverse); }
.ux-btn--danger-outline {
  background: var(--color-bg-container); color: var(--color-status-danger-text);
  border-color: var(--color-status-danger);
}
.ux-btn:disabled { background: var(--color-bg-hover); color: var(--color-text-disabled);
                   border-color: var(--color-border); cursor: not-allowed; }
.ux-btn--sm { min-height: 28px; padding: var(--space-2xs) var(--space-sm); font-size: var(--font-size-caption); }
/* 破壞性動作與一般動作並存時的隔離區(6.6:底線16px,建議32px) */
.ux-btn-group { display: flex; gap: var(--space-md); align-items: center; }
.ux-btn-group--isolate-danger { gap: var(--space-xl); }

/* ── 狀態 Badge(11.3 / 5.4.2):淡底深字 + 必須搭配圖標或文字,不可只靠顏色 ── */
.ux-badge {
  display: inline-flex; align-items: center; gap: var(--space-3xs);
  height: 24px; padding: 0 var(--space-xs);
  border-radius: var(--radius-sm); border: 1px solid transparent;
  font-size: var(--font-size-caption); font-weight: var(--font-weight-semibold);
  white-space: nowrap;
}
.ux-badge--success { background: var(--color-status-success-bg); color: var(--color-status-success); border-color: var(--color-status-success-border); }
.ux-badge--warning { background: var(--color-status-warning-bg); color: var(--color-status-warning); border-color: var(--color-status-warning-border); }
.ux-badge--danger  { background: var(--color-status-danger-bg);  color: var(--color-status-danger-text); border-color: var(--color-status-danger-border); }
.ux-badge--info    { background: var(--color-info-bg); color: var(--color-info-text); border-color: var(--color-info-border); }
.ux-badge--neutral { background: var(--color-bg-hover); color: var(--color-text-secondary); border-color: var(--color-border); }

/* ── 輸入元件(2.3 視覺靜默:淡灰線框、Label 深灰)── */
.ux-input, .ux-select, .ux-textarea {
  width: 100%; min-height: 36px; padding: var(--space-xs) var(--space-sm);
  background: var(--color-bg-container); color: var(--color-text-primary);
  border: 1px solid var(--color-border-strong); border-radius: var(--radius-sm);
  font-family: inherit; font-size: var(--font-size-body);
}
.ux-input::placeholder, .ux-textarea::placeholder { color: var(--color-text-tertiary); }
.ux-input:focus, .ux-select:focus, .ux-textarea:focus {
  border-color: var(--color-primary-default); outline: 2px solid var(--color-focus-ring); outline-offset: 1px;
}
.ux-label {
  display: block; margin-bottom: var(--space-2xs);
  color: var(--color-text-secondary); font-size: var(--font-size-body); font-weight: var(--font-weight-medium);
}
.ux-hint { color: var(--color-text-tertiary); font-size: var(--font-size-caption); }
.ux-error { color: var(--color-status-danger-text); font-size: var(--font-size-caption); }

/* ── 高密度表格(11.3):表頭40px/#F5F7FA、行高48px ── */
.ux-table { width: 100%; border-collapse: collapse; font-size: var(--font-size-body); }
.ux-table thead th {
  height: var(--table-header-height); padding: 0 var(--space-sm);
  background: var(--color-bg-hover); color: var(--color-text-secondary);
  font-size: var(--font-size-caption); font-weight: var(--font-weight-medium);
  text-align: left; border-bottom: 1px solid var(--color-border);
}
.ux-table tbody td {
  height: var(--table-row-height); padding: 0 var(--space-sm);
  color: var(--color-text-primary); border-bottom: 1px solid var(--color-border);
}
.ux-table tbody tr:hover { background: var(--color-bg-hover); }

/* ── 行內警示框 Tier 2(9.1):嵌入表單/卡片頂端,不拉遮罩 ── */
.ux-alert {
  display: flex; gap: var(--space-xs); align-items: flex-start;
  padding: var(--space-sm) var(--space-md); margin-bottom: var(--space-md);
  border: 1px solid transparent; border-radius: var(--radius-sm);
  font-size: var(--font-size-body);
}
.ux-alert--danger  { background: var(--color-status-danger-bg);  color: var(--color-status-danger-text); border-color: var(--color-status-danger-border); }
.ux-alert--warning { background: var(--color-status-warning-bg); color: var(--color-status-warning); border-color: var(--color-status-warning-border); }
.ux-alert--success { background: var(--color-status-success-bg); color: var(--color-status-success); border-color: var(--color-status-success-border); }
.ux-alert--info    { background: var(--color-info-bg); color: var(--color-info-text); border-color: var(--color-info-border); }

/* ══════════════════════════════════════════════════════════════════
   框架殼層(4.1):Sidebar 240px + Top Bar 64px
   實作見 js/components/shell.js(注入式,20 頁共用一份導覽定義)。
   尺寸一律取 --shell-* Token,不寫死。
   ══════════════════════════════════════════════════════════════════ */
/* .ux-shell-on 由 shell.js 加在 <html> 上,故所有殼層樣式都以它為前綴 ——
   未套殼層的頁面(登入頁)完全不受影響。

   ⚠ 內容讓位(避開 Sidebar/Top Bar)刻意「不」寫在這裡,而是由 shell.js
   以 inline style 設在 body 的 margin 上。這是實測後的決定,不是偷懶:
     · 下在 body 的 padding-left:被 style.css 的 `body{padding:2rem}` 蓋掉,
       即使搬到最後載入的 legacy-bridge 並加 !important 仍無效。
     · 改下在 html 的 padding-left:被 style.css 的 `*{padding:0}` 通用重置蓋掉
       (實測連 !important 都壓不過),但 padding-top 卻會生效 —— 行為不一致。
     · 改用 body 的 inline margin:穩定生效,實測內容左緣 114px → 272px,
       且完全不與任何舊規則競爭。
   結論:在有大量舊有 reset 的專案裡,結構性位移交給 JS inline style 才可靠。
   若日後 style.css 退場,可考慮改回純 CSS。 */

/* html 背景需與 body 一致:body 有 margin 後,margin 區域露出的是 html 的背景,
   不補這行會在殼層邊緣看到白邊 */
html.ux-shell-on { background: var(--color-bg-body); }

/* 讓位採「CSS + JS inline」雙保險,兩者不衝突:
   · 這條 CSS 負責預設的展開狀態,並用 !important 壓過 style.css 的 `*{margin:0}`;
     好處是即使 JS 還沒跑完,內容也不會有一瞬間壓在側欄下。
   · shell.js 的 inline margin 負責「收合 / 窄螢幕」等狀態切換(inline 優先於此)。
   任一機制失效時另一個仍能撐住,不會出現內容被側欄蓋住的情形。 */
html.ux-shell-on body {
  margin-left: var(--shell-sidebar-width) !important;
  margin-top: var(--shell-topbar-height) !important;
}
/* 過渡動畫只在 .ux-shell-anim 之後才生效(該 class 由 shell.js 在首幀後才加)。
   原本無條件下 transition,而 JS 是在載入後才把 margin 設成收合值 ——
   於是每換一頁都會播一次 240px→64px 的滑動,看起來就是「閃一下、不流順」。
   收合鈕點擊等載入後的狀態切換仍然有動畫,體感不變。 */
html.ux-shell-anim body { transition: margin-left var(--duration-normal) var(--easing-standard); }
html.ux-shell-on.ux-shell--collapsed body { margin-left: 64px !important; }
@media (max-width: 1023px) {
  html.ux-shell-on body,
  html.ux-shell-on.ux-shell--collapsed body { margin-left: 0 !important; }
}

/* ── Sidebar ──
   top 從 Top Bar 底緣開始:Top Bar 改為「橫貫全寬」(品牌列與頁面動作同一列),
   側欄退到它底下。這是 2026-07-31 的版面調整,見下方 Top Bar 區塊說明。 */
.ux-sidebar {
  position: fixed; top: var(--shell-topbar-height); left: 0; bottom: 0;
  width: var(--shell-sidebar-width);
  display: flex; flex-direction: column;
  background: var(--color-bg-container);
  border-right: 1px solid var(--color-border);
  z-index: var(--z-drawer);
  overflow: hidden;
}
/* 同 body 讓位:動畫延後到首幀之後,避免每次換頁側欄都寬度動畫一次 */
html.ux-shell-anim .ux-sidebar {
  transition: width var(--duration-normal) var(--easing-standard),
              transform var(--duration-normal) var(--easing-standard);
}
.ux-shell--collapsed .ux-sidebar { width: 64px; }

.ux-sidebar__nav { flex: 1; overflow-y: auto; padding: var(--space-xs) 0; }

.ux-sidebar__group {
  padding: var(--space-sm) var(--space-md) var(--space-2xs);
  color: var(--color-text-tertiary);
  font-size: var(--font-size-caption); font-weight: var(--font-weight-medium);
  white-space: nowrap;
}

.ux-sidebar__item {
  display: flex; align-items: center; gap: var(--space-sm);
  /* 44px 高:高於 WCAG 2.5.8 目標尺寸下限(24×24)甚多,且一個畫面容得下完整導覽樹 */
  min-height: 44px; padding: 0 var(--space-md);
  color: var(--color-text-secondary); text-decoration: none;
  font-size: var(--font-size-body); white-space: nowrap;
  border-left: 3px solid transparent;
}
.ux-sidebar__item:hover {
  background: var(--color-bg-hover);
  color: var(--color-text-primary);
  text-decoration: none;
}
/* 選中態多重線索(5.4.2):底色 + 左側色條 + 主色文字 + 加粗,不只靠顏色 */
.ux-sidebar__item.is-active {
  background: var(--color-primary-subtle-bg);
  border-left-color: var(--color-primary-default);
  color: var(--color-primary-default);
  font-weight: var(--font-weight-semibold);
}
.ux-sidebar__icon {
  width: 20px; text-align: center; flex-shrink: 0;
  font-size: var(--font-size-h6); line-height: 1;
}

.ux-sidebar__collapse {
  display: flex; align-items: center; gap: var(--space-sm);
  min-height: 44px; padding: 0 var(--space-md); flex-shrink: 0;
  border: none; border-top: 1px solid var(--color-border);
  background: transparent; cursor: pointer;
  color: var(--color-text-tertiary); font-family: inherit;
  font-size: var(--font-size-body); white-space: nowrap;
}
.ux-sidebar__collapse:hover { background: var(--color-bg-hover); color: var(--color-text-primary); }

/* 收合後只留圖示;文字用 clip 隱藏而非 display:none,保留給輔助技術朗讀 */
.ux-shell--collapsed .ux-sidebar__label,
.ux-shell--collapsed .ux-sidebar__group {
  position: absolute; width: 1px; height: 1px; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}
/* 收合鈕的面板圖示:兩個狀態同一個圖形,不再翻轉。
   原本是 «/» 雙箭頭字元,靠 scaleX(-1) 在收合態反向;改成面板圖示後不需要方向,
   狀態差異由 aria-label(收合/展開側邊導覽)與側欄本身的寬度表達。 */
.ux-sidebar__collapse-icon { flex-shrink: 0; }

/* ── Top Bar ──
   橫貫全寬(left:0):品牌 → 麵包屑 → 頁面動作 → 使用者 → 搜尋 全部在同一列,
   側欄由它底下起算。這麼做的理由:
     · 品牌只需要一個落點,放在極左的頂列比塞在側欄頂端更接近一般後台慣例;
     · 原本頁內 <header> 的功能膠囊會另佔一整列(約 100px),等於首屏被兩條
       水平列吃掉;併進 Top Bar 後內容直接從第二列開始,首屏多出一整列表格。
   z-index 高於 Drawer:Top Bar 現在橫跨側欄上方,窄螢幕抽屜的遮罩(scrim)
   不應把它一起蓋暗,否則漢堡鈕會失去點擊回饋。 */
.ux-topbar {
  position: fixed; top: 0; right: 0; left: 0;
  height: var(--shell-topbar-height);
  display: flex; align-items: center; gap: var(--space-sm);
  padding: 0 var(--space-lg) 0 var(--space-md);
  background: var(--color-bg-container);
  border-bottom: 1px solid var(--color-border);
  z-index: calc(var(--z-drawer) + 1);
  /* Top Bar 本身是 <header> 元素,會吃到 style.css 的裸 `header` 規則 ——
     其中 @media(max-width:1200px) 的 `header{flex-direction:column!important}`
     會把整條列拆成三行(品牌/膠囊/搜尋各一行),把 64px 高的固定列擠爆。
     那條規則是為頁內舊頁首寫的,對殼層無效;故此處以 !important 明確排除。
     margin 歸零同理:裸 header 帶 margin-bottom:2rem。 */
  flex-direction: row !important;
  flex-wrap: nowrap !important;
  margin: 0 !important;
}

/* 品牌:全名 ASUS EXPERTHUB CRM,三段同一字級。
   寬度改為 auto(原本固定成側欄寬,是為了讓麵包屑對齊內容左緣;
   麵包屑移除後那個理由不存在了,固定寬只會裁到放大後的字)。
   字級走 --shell-brand-font-size(單一調整點),line-height 壓到 1.1 以免
   放大字級時撐破 64px 的列高。 */
.ux-topbar__brand {
  display: flex; align-items: baseline; gap: var(--space-xs);
  flex-shrink: 0; white-space: nowrap; text-decoration: none;
  font-size: var(--shell-brand-font-size); line-height: 1.1;
}
.ux-topbar__brand:hover { text-decoration: none; }
/* brand-mark = 用主色強調的那一段。2026-08-03 起是「CRM」(原本是 ASUS)——
   與登入頁及所有舊頁一致(style.css:207 的 .logo span 就是把主色給 CRM)。
   letter-spacing 從 -.5px 改為 .5px:負字距是為了收緊「ASUS」四個大寫字母,
   套在只有三個字母的 CRM 上會顯得擠。 */
.ux-topbar__brand-mark {
  color: var(--color-primary-default);
  font-weight: var(--font-weight-bold); font-size: inherit;
  letter-spacing: .5px; flex-shrink: 0;
}
/* brand-text = 其餘段落(現為「ASUS EXPERTHUB」),用主要文字色 */
.ux-topbar__brand-text {
  color: var(--color-text-primary);
  font-weight: var(--font-weight-semibold); font-size: inherit;
  letter-spacing: .5px;
}

/* 由 shell.js 從頁內 <header> 搬上來的頁面動作(如智能中心的統計膠囊)。
   gap 用 sm:膠囊本身已有內距,再放大會擠掉搜尋鈕。

   ⚠ 不可加 overflow:hidden/auto —— 使用者選單的 .dropdown-content 是絕對定位、
   往 Top Bar 下方展開,任何 overflow 裁切都會讓選單只露出一小截。
   寬度不足時交給膠囊自身的 flex-shrink 與既有的縮小斷點處理。 */
.ux-topbar__actions {
  display: flex; align-items: center; gap: var(--space-sm);
  min-width: 0;
}
/* 由 shell.js 掛在「原本不是 flex」的舊頁首容器上,避免它在單列裡上下堆疊。

   選擇器刻意寫成「父 > 子」兩層(權重 0,2,0):被搬上來的容器往往同時掛著舊 class,
   例如總覽儀表板是 `.action-bar.dropdown` —— style.css 的 `.dropdown{display:inline-block}`
   權重同為 0,1,0 而**載入順序在 tokens.css 之後**,單層 class 會輸給它。
   提高權重即可不受載入順序影響,也不必動到舊頁的規則。

   仍不加 !important:頁面 JS 常以 inline `style.display` 切換這些控制項的顯示,
   inline 必須贏過這條,否則該隱藏的按鈕會被強制顯示出來。 */
.ux-topbar__actions > .ux-topbar__actions-row {
  display: flex; align-items: center; gap: var(--space-xs);
}
/* 頁面動作列:頁內 <header> 的品牌被殼層吸收後,只剩該頁自己的操作按鈕
   (重新整理、匯出資料…)。這些是**頁面層級**的操作,刻意留在內容區而不上 Top Bar
   —— 放上去會讓人以為那是每一頁都有的全站功能(2026-07-31 Ken 回報)。
   靠右對齊:頁首原是 space-between,品牌沒了會讓按鈕塌到最左邊。
   選擇器用 `header.class`(權重 0,1,1)壓過 style.css 的 `.admin-header`(0,1,0),
   不需要 !important。 */
header.ux-page-actions {
  justify-content: flex-end;
  /* 內距/外距/底線一律歸零(2026-07-31 Ken 回報「頂部空間沒有統一」):
     舊頁首是「品牌 + 操作」的完整一列,故 style.css 給了 `padding: 2rem 0`、
     `margin-bottom: 2rem` 與一條底線。品牌被殼層吸收後只剩幾顆按鈕,
     那些留白就變成內容上方一條約 90px 的空白帶(32 上 + 32 下 + 24 外距 + 1 線),
     和沒有頁首的頁面(Pipeline)差了一大截。
     歸零後動作列緊貼內容區頂端,各頁的起始高度就一致了。 */
  padding: 0 !important;
  margin: 0 0 var(--space-md) !important;
  border-bottom: 0 !important;
  min-height: 0;
}

/* 舊頁首容器帶著頁面版面用的外距(例:`.action-bar{margin-bottom:2rem}`)。
   在 align-items:center 的單列裡,外距會算進置中計算 —— 32px 的下外距會把整塊
   往上推 16px,按鈕就被列的上緣裁掉(y=-9)。搬進 Top Bar 後這些外距沒有意義,一律歸零。
   同樣用兩層選擇器提高權重,才壓得過載入順序在後的 style.css。 */
.ux-topbar .ux-topbar__actions > * { margin: 0; }

.ux-topbar__spacer { flex: 1; }

/* ── 使用者選單(僅殼層自建的那一份)────────────────────────────────
   2026-08-03 Ken 回報「Sales Pipeline 右上角使用者按鈕有問題」:選單三個項目
   (問題回饋/帳號安全與密碼/登出系統)直接攤開在 Top Bar 上、還溢出到列的上方,
   使用者名稱則完全看不見。

   成因:UI.js 的 UI.Dropdown() 只負責產生 DOM 與 active class,
   「未展開時收起來」這件事是靠 CSS ——
       style.css:692  .dropdown-content { display: none; ... }
       style.css:694  .dropdown.active .dropdown-content { display: block; }
   而 pipeline.html / matching.html 是純 tokens.css 的新頁,**沒有**載入 style.css
   與 legacy-bridge.css(全站 19 頁只有這兩頁如此)。於是:
     · .dropdown-content 沒有 display:none → 三個連結永遠可見,並以 block 堆疊在
       align-items:center 的 64px 單列裡,約 90px 高 → 上下都溢出(截圖現象)
     · .status-dot 沒有 8×8 尺寸 → 狀態點消失
     · #userName 帶行內 color:white(UI.js:189),白底白字 → 名字看不見
       (17 個舊頁是靠 legacy-bridge.css:420 的行內樣式攔截救回來的)

   為什麼不直接讓這兩頁補載 style.css + legacy-bridge.css:
   style.css 是深色主題的舊基底(body 深底、padding:2rem、大量白字),
   legacy-bridge 則是專為「壓制那些舊樣式」而存在的補丁層。為了一顆選單把兩層
   共數千行搬進乾淨頁,等於把剛擺脫的東西請回來,版面風險遠大於收益。

   ── 2026-08-03 第二輪(Ken:圖2 圖3 要跟圖1「大小相同、位子相同」)────
   補完上述缺漏後仍有三處不一致,原因是「同一顆選單卻有兩套來源」:
     · index / master_dashboard 的 #userMenuRoot 寫在 HTML 裡(index.html:315),
       幾何靠行內樣式,且身處 .header-capsules-container、與兩顆統計膠囊並排
     · 其餘 17 頁是 shell.js ensureUserMenu() 現場建的裸 div,什麼幾何都沒有
   造成:名片審核等 15 頁有 .user-profile 的框但沒有 48px 限制 → 框被拉到整列高
   64px 的白盒(圖3);pipeline / matching 連框都沒有(圖2);而 index 因為多了一個
   空的 .ux-topbar__user 插槽佔掉 Top Bar 的 gap,膠囊距右緣 36px、其他頁 24px。

   故本段的定位改為:**全站唯一的使用者選單樣式來源**,不再只是補兩頁的破洞。
   選擇器分兩類,刻意不同:
     · #userMenuRoot 起頭 → 膠囊本體與面板,對「所有頁面」生效(含 index)
     · .ux-topbar__user 起頭 → 只有殼層自建那份才需要的補件(舊 CSS 已提供的部分,
       不去重複定義,避免與 style.css/legacy-bridge 互相打架)
   取值一律走 Token(亮色原生,不必再被 bridge 壓)。 */

/* 膠囊本體。幾何沿用 index 的既有值(48px / 1.2rem)而非改成 8px 網格 ——
   本次任務是「把其他頁對齊成圖1」,動基準值會連 Ken 指定的參考頁一起改掉。
   index 自己的行內樣式優先序高於本條,值相同,參考頁畫面不變;
   於是「膠囊長什麼樣」實質上只有這一份定義,不會兩套各自漂移。

   position:relative 是面板的定位參考(見下一條),放在膠囊上而非插槽上的理由:
   index 的選單不在 .ux-topbar__user 裡(它被搬進 .ux-topbar__actions 的膠囊容器),
   只有 #userMenuRoot 是三種情境共有的節點,錨在它身上才能全站一致。 */
#userMenuRoot {
  box-sizing: border-box;
  position: relative;
  height: 48px; padding: 0 1.2rem;
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--space-xs);
  background: var(--color-bg-container);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  white-space: nowrap; flex-shrink: 0;
  /* 刻意不宣告 font-size:index 的 .user-profile 用 0.9rem(14.4px),
     這裡若補上 --font-size-body(14px)會以 ID 權重反過來蓋掉參考頁 ——
     為了 0.4px 去動 Ken 指定的基準,風險大於收益。
     沒有舊 CSS 的頁面則繼承 body 的 14px,差距肉眼不可辨。 */
}

/* index 沒有用到殼層自建的插槽,但那個空 div 仍是 Top Bar 的 flex 項目,
   會吃掉一份 gap(--space-sm 12px),讓 index 的膠囊比其他頁多退 12px。
   :empty 把它收掉,三種情境的膠囊右緣就都落在 Top Bar 自己的 24px 內距上
   —— 與極左品牌的內距同一條線。 */
.ux-topbar__user:empty { display: none; }
.ux-topbar__user { display: flex; align-items: center; flex-shrink: 0; }

/* 面板:固定貼在 Top Bar 下緣、右緣對齊 Top Bar 內距。
   用 position:fixed 而不是 absolute + top:100%,是因為百分比會跟著「膠囊當下的高度」
   跑:膠囊在 index 於 ≤1600 / ≤1366 兩個斷點會被 style.css 縮成 40 / 36px
   (.header-capsules-container .user-profile,帶 !important),百分比算出來的落點
   就跟著上移、鑽進列裡疊住一截(實測 index -7px、其他頁 +3px)。
   Top Bar 本身是 fixed 且沒有任何 transform/filter(那些會變成 fixed 的包含塊),
   故 fixed 的參考就是視窗 —— 落點永遠等於列高,與膠囊尺寸、所在容器都無關。

   權重 (1,1,0) 壓過 style.css:692 的 .dropdown-content(0,1,0),
   不受載入順序影響,也不需要 !important。 */
#userMenuRoot .dropdown-content {
  display: none;
  position: fixed;
  top: var(--shell-topbar-height); right: var(--space-lg);
  min-width: 220px; padding: var(--space-xs);
  background: var(--color-bg-container);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  z-index: calc(var(--z-drawer) + 2);
}
#userMenuRoot .dropdown.active .dropdown-content { display: block; }

#userMenuRoot .dropdown-item {
  display: flex; align-items: center; gap: var(--space-xs);
  /* 36px:選單項目比側欄的 44px 緊湊,仍高於 WCAG 2.5.8 的 24×24 下限 */
  min-height: 36px; padding: 0 var(--space-sm);
  color: var(--color-text-primary); text-decoration: none;
  font-size: var(--font-size-body); border-radius: var(--radius-sm);
  white-space: nowrap; cursor: pointer;
}
#userMenuRoot .dropdown-item:hover {
  background: var(--color-bg-hover); text-decoration: none;
}
/* 破壞性項目(登出)用深紅文字,對白底 5.9:1 */
#userMenuRoot .dropdown-item.text-danger { color: var(--color-status-danger-text); }

/* 分隔線:UI.js 以行內樣式指定 border-top: 1px solid var(--glass-border),
   而 --glass-border 只定義在 legacy-bridge.css —— 在沒載入它的頁面是未定義變數,
   整條宣告失效(線畫不出來)。故以 !important 換成 Token 的邊框色。 */
#userMenuRoot .dropdown-content hr {
  border: 0 !important;
  border-top: 1px solid var(--color-border) !important;
  margin: var(--space-2xs) 0 !important;
}

/* ── 以下只補「殼層自建」那份缺少的東西 ──
   舊 CSS 已經提供這些的 15 個頁面不必重複宣告,免得兩邊互相覆蓋。 */
/* 行內 color:white 必須用 !important 才壓得過(行內樣式優先於 class)。
   15 個舊頁是靠 legacy-bridge.css:420 的行內樣式攔截做同一件事。 */
.ux-topbar__user #userName {
  color: var(--color-text-primary) !important;
  font-size: var(--font-size-body);
}
/* 狀態點的顏色/光暈由 UI.js 依通知狀態行內指定,這裡只給尺寸與形狀
   (對應 style.css:222 的 .status-dot) */
.ux-topbar__user .status-dot {
  width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0;
}

/* 頭像首字母:UI.js:166 寫死 color:white,在 Pipeline / PERSONA 後台是白字,
   其餘 15 頁則被 legacy-bridge.css:420 的行內白字攔截換成深色 —— 同一個頭像兩種樣子
   (2026-08-03 Ken 回報)。統一成深色,與那 15 頁一致。
   深色也是對比較好的一邊:實算 #1D2129 對紅色頭像底 #ef4444 是 4.40:1,白字只有 3.76:1。

   選擇器刻意鎖在 #userMenuRoot 底下,不做全域的白字轉換 —— tokens.css 是全站基底,
   在這裡放 [style*="color: white"] 的通用攔截會波及所有頁面的行內白字
   (那是 legacy-bridge 這個過渡層才該做的事)。 */
#userMenuRoot span[style*="color: white"] {
  color: var(--color-text-primary) !important;
}

/* 項目圖示 <i class="crm-icon icon-*"> 的遮罩圖檔定義在 style.css,pipeline / matching
   沒載入 → 在這兩頁是零寬度的空 <i>,仍會吃掉 flex 的 gap,文字左邊多 8px 內縮。
   刻意不處理:
     · 加 display:none 會連帶命中另外 15 個「圖示本來就正常」的頁面,把它們的
       選單圖示一起關掉 —— 為了兩頁的 8px 破壞 15 頁的既有樣貌,划不來。
     · 把遮罩定義搬進 tokens.css 則會讓圖示系統變成兩份真相來源。
   8px 均等內縮在每個項目上都一樣,讀起來只是左內距略寬,不影響辨識。
   這兩頁完成遷移(改載 tokens 版圖示)後本註解可移除。 */

/* ── PERSONA 卡片:每個區塊一個收合單位(2026-08-03 Ken 指示)──────────────
   幾何刻意沿用原本那張卡的值(白底、1px 框、左側 3px 語意色條、radius-lg、
   內距 md/lg、間距 sm),只是外層由 <div> 換成 <details> —— 收合前後看起來
   要是同一張卡,不能因為多了收合功能就變成另一種元件。
   左側色條顏色由 record_detail.js 以行內 border-left-color 指定(各區塊語意色)。

   用原生 <details>:收合零 JS,鍵盤與螢幕閱讀器原生支援。
   代價是三種瀏覽器的預設三角形都要關掉,才能換成自己的箭頭(下面三條)。 */
.pv2-card {
  background: var(--color-bg-container);
  border: 1px solid var(--color-border);
  border-left: 3px solid var(--color-primary-default);
  border-radius: var(--radius-lg);
  padding: var(--space-md) var(--space-lg);
  margin-bottom: var(--space-sm);
}
.pv2-card__head {
  display: flex; align-items: center; gap: var(--space-2xs);
  cursor: pointer; list-style: none;                    /* Firefox 的 marker */
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-primary);
  font-size: var(--font-size-h6);
}
.pv2-card__head::-webkit-details-marker { display: none; }   /* Safari / 舊 Chromium */
.pv2-card__head::marker { content: ""; }                     /* 新版標準 */
.pv2-card__head:hover .pv2-card__title { color: var(--color-primary-default); }
.pv2-card__chev {
  display: inline-block; flex-shrink: 0; width: 1em;
  color: var(--color-text-tertiary);
  transition: transform var(--duration-fast, .15s) var(--easing-standard, ease);
}
.pv2-card[open] > .pv2-card__head .pv2-card__chev { transform: rotate(90deg); }
/* 標題與內文的上下間距:原本卡片是標題 margin-bottom:--space-sm,
   移到 body 的 padding-top,收合時才不會留一段空白。 */
.pv2-card__body { padding-top: var(--space-sm); }

/* .ux-topbar__crumb(麵包屑)已於 2026-07-31 隨版面調整移除,故此處無對應樣式 */
.ux-topbar__burger {
  display: none; align-items: center; justify-content: center;
  width: 36px; height: 36px; flex-shrink: 0;
  border: 1px solid var(--color-border-strong); border-radius: var(--radius-sm);
  background: var(--color-bg-container); cursor: pointer;
  color: var(--color-text-secondary); font-size: var(--font-size-h6);
}
/* .ux-topbar__search / .ux-topbar__kbd(「🔍 搜尋 Ctrl K」按鈕)已於 2026-07-31
   移除:與同列的「智能中心」膠囊目的地相同、外觀相近。全域搜尋改由 Ctrl+K 提供。 */

/* 遮罩只蓋內容區:Top Bar 橫貫全寬且在遮罩之上,漢堡鈕才不會連帶變暗 */
.ux-shell-scrim {
  display: none; position: fixed;
  top: var(--shell-topbar-height); right: 0; bottom: 0; left: 0;
  background: var(--color-overlay-scrim);
  z-index: calc(var(--z-drawer) - 1);
}

/* ── 窄螢幕(< md 1024,規範 5.3.1):Sidebar 收為抽屜,Overlay 僅限此情境 ── */
@media (max-width: 1023px) {
  /* 窄螢幕的讓位歸零同樣由 shell.js 處理(見上方說明) */
  .ux-sidebar { transform: translateX(-100%); width: var(--shell-sidebar-width); }
  .ux-shell--drawer-open .ux-sidebar { transform: translateX(0); }
  /* 抽屜開啟時文字要看得見,故取消收合態的隱藏 */
  .ux-shell--drawer-open .ux-sidebar__label,
  .ux-shell--drawer-open .ux-sidebar__group {
    position: static; width: auto; height: auto; margin: 0; clip: auto;
  }
  .ux-topbar__burger { display: flex; }
  /* 窄螢幕一列放不下品牌全稱:縮到只剩 ASUS 字標,把寬度讓給頁面動作
     (動作不隱藏 —— 隱藏會讓業務找不到按鈕,見 shell.js 檔頭) */
  .ux-topbar__brand { width: auto; }
  .ux-topbar__brand-text { display: none; }
  .ux-sidebar__collapse { display: none; }
  .ux-shell--drawer-open .ux-shell-scrim { display: block; }
}

/* 列印:殼層屬導覽,不應出現在紙上 */
@media print {
  .ux-sidebar, .ux-topbar, .ux-shell-scrim { display: none !important; }
  html.ux-shell-on body { margin: 0 !important; }
}

/* ══════════════════════════════════════════════════════════════════
   Drawer 560(6.1):6–15 欄的編輯載體,含 Sticky Footer
   實作見 js/ux-drawer.js
   ══════════════════════════════════════════════════════════════════ */
.ux-drawer {
  position: fixed; top: 0; right: 0; bottom: 0;
  width: min(var(--drawer-width), 100vw);
  display: flex; flex-direction: column;
  background: var(--color-bg-container);
  border-left: 1px solid var(--color-border);
  box-shadow: var(--shadow-md);
  z-index: var(--z-drawer);
  transform: translateX(100%);
  transition: transform var(--duration-normal) var(--easing-standard);
  visibility: hidden;
}
.ux-drawer-open .ux-drawer { transform: translateX(0); visibility: visible; }

.ux-drawer-scrim {
  position: fixed; inset: 0;
  background: var(--color-overlay-scrim);
  z-index: calc(var(--z-drawer) - 1);
  opacity: 0; visibility: hidden;
  transition: opacity var(--duration-normal) var(--easing-standard);
}
.ux-drawer-open .ux-drawer-scrim { opacity: 1; visibility: visible; }

.ux-drawer__head {
  display: flex; align-items: center; gap: var(--space-sm);
  padding: var(--space-md) var(--space-lg); flex-shrink: 0;
  border-bottom: 1px solid var(--color-border);
}
.ux-drawer__title {
  flex: 1; margin: 0;
  font-size: var(--font-size-h5); font-weight: var(--font-weight-semibold);
  color: var(--color-text-primary);
}
.ux-drawer__close {
  width: 32px; height: 32px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--color-border-strong); border-radius: var(--radius-sm);
  background: var(--color-bg-container); color: var(--color-text-secondary);
  cursor: pointer; font-family: inherit; font-size: var(--font-size-body);
}
.ux-drawer__close:hover { background: var(--color-bg-hover); color: var(--color-text-primary); }

.ux-drawer__body { flex: 1; overflow-y: auto; padding: var(--space-lg); }

/* Sticky Footer:長表單捲動時主要動作永遠可見(6.1) */
.ux-drawer__foot {
  display: flex; align-items: center; justify-content: flex-end; gap: var(--space-xs);
  padding: var(--space-md) var(--space-lg); flex-shrink: 0;
  border-top: 1px solid var(--color-border);
  background: var(--color-bg-container);
}

/* 窄螢幕:Drawer 佔滿寬度(5.3.1) */
@media (max-width: 767px) {
  .ux-drawer { width: 100vw; border-left: none; }
}

/* ── 搜尋命中標示(11.5)── */
mark, mark.ux-hl {
  background: var(--color-search-highlight-bg);
  color: var(--color-text-primary);
  border-radius: var(--radius-sm);
  padding: 1px 3px;
  font-weight: var(--font-weight-semibold);
}

/* ══════════════════════════════════════════════════════════════════
   捲軸(2.3 視覺靜默)
   2026-07-31 Ken 回報「左側的拉把不一樣格式」後移進設計系統。

   原本只有 style.css 有一條全域 `::-webkit-scrollbar`,於是:
     · 載入 style.css 的 15 頁 → 12px 寬、淡紫色拉把
       (`rgba(99,102,241,.3)` 是**舊 Indigo 主題的殘留**,不是 ASUS 藍)
     · 只載 tokens.css 的頁面(PERSONA 後台、Pipeline)→ 作業系統原生捲軸(帶上下箭頭)
   同一個側欄因此有兩種捲軸長相。與字型、間距 Token 是同一類問題:
   共用元件的樣式不能只存在於 legacy 樣式表。

   顏色改為中性灰:捲軸是導航裝置而非內容,規範 2.3 要求 OX「視覺靜默」,
   拿品牌色去染捲軸會把視線從資料上拉走。
   寬度維持 12px —— 與舊值相同,避免 15 個頁面的內容寬度發生位移。
   ══════════════════════════════════════════════════════════════════ */
::-webkit-scrollbar { width: 12px; height: 12px; }
::-webkit-scrollbar-track { background: var(--color-bg-hover); }
::-webkit-scrollbar-thumb {
  background: var(--color-border-strong);
  border-radius: var(--radius-lg);
  /* 透明邊框 + padding-box 讓拉把內縮,不必替每種底色各寫一次邊框顏色 */
  border: 3px solid transparent;
  background-clip: padding-box;
}
::-webkit-scrollbar-thumb:hover { background: var(--color-text-tertiary); background-clip: padding-box; }
::-webkit-scrollbar-corner { background: var(--color-bg-hover); }
/* Firefox 不支援 ::-webkit-*,用標準屬性給同一組顏色。

   scrollbar-gutter: stable —— 永遠保留捲軸的位置,不管當下有沒有捲軸。
   2026-08-03 Ken 回報「按 SALES PIPELINE 會閃一下才正常」:
   頁面第一次繪製時內容還沒長出來、沒有捲軸,資料填進去之後捲軸才出現,
   整個版面就被往左擠約 12px —— 那一下位移就是他看到的閃爍。
   名片審核沒這問題,因為它載入 style.css,那裡的 :1473 已經有同一條規則。

   ⚠ 兩份是刻意的,不要「順手合併」:
   form_designer.html 載入 style.css 但**沒有**載 tokens.css(全站唯一一頁),
   把 style.css 那條刪掉會讓它退回會位移的狀態。
   等 form_designer 完成遷移、改載 tokens.css 之後,style.css:1473 才能移除。 */
html {
  scrollbar-width: thin;
  scrollbar-color: var(--color-border-strong) var(--color-bg-hover);
  scrollbar-gutter: stable;
}

/* 註:2026-08-01 曾在此加 `.info-card::-webkit-scrollbar-track` 想用「軌道內縮」
   補救圓角被捲軸吃掉的問題,實測無效已移除 —— 捲軸覆蓋圓角是 Chromium 對
   「有圓角又自己捲動」元素的固有行為,調捲軸配色治不了。
   正解是把捲動下移到內層 .card-scroll(見 legacy-bridge.css)。 */

/* ══════════════════════════════════════════════════════════════════
   Toast 元件基準(9.1):頂部中央、白底、左側語意色條
   節點由 js/ux-guard.js 建立(頁面沒有 #toast 就自己補一個)。

   為什麼樣式在這裡、而 legacy-bridge.css 裡還有一份帶 !important 的:
     · 這一份是**元件基準** —— tokens.css 是每頁都載入的第一支樣式表,
       故只載 tokens 的頁面(如 PERSONA 後台)也能有合規的 Toast。
       2026-07-31 換皮時就是踩到這點:該頁移除自寫的右下角 Toast 後,
       共用 Toast 因為沒有樣式而變成頁尾的一行裸文字。
     · legacy-bridge 那一份負責**壓過舊頁自寫的 Toast 樣式**(右下角、
       實色底、3 秒),那些舊規則寫在頁內、優先序高,非 !important 壓不動。
   兩份的值必須一致;改動時請同時改。
   ══════════════════════════════════════════════════════════════════ */
.toast {
  position: fixed;
  top: var(--space-md); left: 50%; right: auto; bottom: auto;
  min-height: 48px; max-width: 560px;
  display: flex; align-items: center; gap: var(--space-xs);
  padding: var(--space-sm) var(--space-lg);
  background: var(--color-bg-container);
  color: var(--color-text-primary);
  border: 1px solid var(--color-border);
  border-left: 4px solid var(--color-text-secondary);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-md);
  font-size: var(--font-size-body); font-weight: var(--font-weight-medium);
  /* 未顯示時:上移 16px + 透明 + 不攔截點擊(否則會蓋住底下元素) */
  transform: translateX(-50%) translateY(-16px);
  opacity: 0; pointer-events: none;
  transition: transform var(--duration-normal) var(--easing-standard),
              opacity var(--duration-normal) var(--easing-standard);
  z-index: var(--z-toast);
}
.toast.show { transform: translateX(-50%) translateY(0); opacity: 1; pointer-events: auto; }
/* 類型語意升級(2026-07-31 REN 回報白底+細色條不夠明顯):
   整條改「狀態淡色底 + 狀態深色字」—— 用的都是本檔 17-28 行已標註對比度
   合格的成對 token(4.8:1 ~ 5.9:1),與 .ux-alert 同一套語言。
   圖示必須用 ::before:showToast 以 textContent 寫訊息,HTML 內容會被覆寫。 */
.toast::before {
  flex: 0 0 auto;
  width: 20px; height: 20px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: var(--font-weight-bold, 700); color: #fff;
}
.toast.success::before { content: '✓'; background: var(--color-status-success); }
.toast.error::before   { content: '✕'; background: var(--color-status-danger); }
.toast.warning::before { content: '!'; background: var(--color-status-warning); }
.toast.info::before    { content: 'i'; background: var(--color-info-text); }
.toast.success { background: var(--color-status-success-bg); color: var(--color-status-success);     border-left-color: var(--color-status-success); }
.toast.error   { background: var(--color-status-danger-bg);  color: var(--color-status-danger-text); border-left-color: var(--color-status-danger); }
.toast.warning { background: var(--color-status-warning-bg); color: var(--color-status-warning);     border-left-color: var(--color-status-warning); }
.toast.info    { background: var(--color-info-bg);           color: var(--color-info-text);          border-left-color: var(--color-info-text); }

/* ══════════════════════════════════════════════════════════════════
   指標卡完整元件(13.1)
   規範:白底 + 1px 淡灰框 + 內距 24 + 資訊階梯「標題14中灰 → 數值36深灰 → 註解12」。
   原本首頁四張卡各自寫行內樣式(2rem 內距、24px 圓角、紫/藍/琥珀漸層、
   40px 數值、color:white),既不合規也無法統一調整。改為共用 class。

   為何移除漸層:規範 1.2 明言「裝飾性漸層…在內部作業系統中容易形成噪音,
   建議保留給行銷場景」,2.3 要求 OX「視覺靜默」。語意仍保留 —— 改由左側
   3px 色條表達分類,比整片漸層安靜且不影響數字辨識。
   ══════════════════════════════════════════════════════════════════ */
.ux-metric-card {
  display: flex; flex-direction: column; gap: var(--space-xs);
  padding: var(--space-lg);
  background: var(--color-bg-container);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  transition: box-shadow var(--duration-fast) var(--easing-standard);
}
/* 可點擊的卡片才給 hover 與指標,避免暗示不存在的互動(規範 3.2 可視親和性) */
.ux-metric-card--clickable { cursor: pointer; }
.ux-metric-card--clickable:hover { box-shadow: var(--shadow-sm); border-color: var(--color-border-strong); }
.ux-metric-card__head {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-xs);
  color: var(--color-text-secondary); font-size: var(--font-size-body);
  font-weight: var(--font-weight-medium);
}
.ux-metric-card__head > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ux-metric-card__value {
  color: var(--color-text-primary); font-size: var(--font-size-metric);
  font-weight: var(--font-weight-bold); line-height: 1.2;
  font-variant-numeric: tabular-nums;   /* 等寬數字:多張卡並排時位數不會跳動 */
  min-height: 1.2em;                    /* 無值時卡片高度仍與其他張一致 */
}
.ux-metric-card__foot { color: var(--color-text-tertiary); font-size: var(--font-size-caption); }
/* 分類色條:取代原本的整片漸層(見上方說明) */
.ux-metric-card--accent { border-left: 3px solid var(--color-primary-default); }
.ux-metric-card--accent-warning { border-left: 3px solid var(--color-status-warning-fill); }
.ux-metric-card--accent-success { border-left: 3px solid var(--color-status-success); }

/* ── 指標卡(13.1):資訊階梯 標題14中灰 → 數值36深灰 → 趨勢12 ── */
.ux-metric { }
.ux-metric__label { color: var(--color-text-secondary); font-size: var(--font-size-body); }
.ux-metric__value { color: var(--color-text-primary); font-size: var(--font-size-metric);
                    font-weight: var(--font-weight-semibold); line-height: 1.2; }
.ux-metric__trend { font-size: var(--font-size-caption); }
.ux-metric__trend--up   { color: var(--color-status-success); }
.ux-metric__trend--down { color: var(--color-status-danger-text); }

/* ── 空狀態 / 骨架屏(元件庫、8.3)── */
.ux-empty { padding: var(--space-2xl) var(--space-lg); text-align: center; color: var(--color-text-tertiary); }
.ux-skeleton {
  background: linear-gradient(90deg, var(--color-skeleton-base) 25%, var(--color-border) 37%, var(--color-skeleton-base) 63%);
  background-size: 400% 100%; border-radius: var(--radius-sm);
  animation: ux-skeleton-loading 1.4s ease infinite;
}
@keyframes ux-skeleton-loading { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }

/* ── 12 欄網格(5.3)── */
.ux-grid { display: grid; grid-template-columns: repeat(12, 1fr); gap: var(--space-lg); }
.ux-col-2 { grid-column: span 2; } .ux-col-3 { grid-column: span 3; }
.ux-col-4 { grid-column: span 4; } .ux-col-6 { grid-column: span 6; }
.ux-col-8 { grid-column: span 8; } .ux-col-12 { grid-column: span 12; }
@media (max-width: 1023px) {   /* sm:span-4 以上轉整行(5.3) */
  .ux-col-4, .ux-col-6, .ux-col-8 { grid-column: span 12; }
}

/* ── 工具 class ── */
.ux-text-secondary { color: var(--color-text-secondary); }
.ux-text-tertiary  { color: var(--color-text-tertiary); }
.ux-caption { font-size: var(--font-size-caption); color: var(--color-text-tertiary); }
.ux-sr-only {  /* 螢幕閱讀器專用(7.5) */
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
