/* ==========================================================================
   AI 客服後台 — 全域樣式

   單一深色主題，不提供淺色切換：本系統是內部維運工具，使用情境固定，
   雙套色票只會增加維護面與 FOUC 風險。
   全站不引用任何 CDN、外部字體或圖片；圖示一律以 inline SVG 提供，
   背景層次改用 gradient 而非圖檔，確保離線／內網環境下外觀完全一致。
   ========================================================================== */

:root {
  /* color-scheme 必須宣告：瀏覽器原生元件（捲軸、autofill、密碼顯示按鈕）
     預設走淺色，會在深色卡片上直接破版 */
  color-scheme: dark;

  /* 三階層次：底 → 卡片 → 輸入框，靠明度差而非純黑製造深度 */
  --bg: #0B0D10;
  /* 比 --bg 再暗一階：畫布這種「放東西的底」要比頁面更沉，卡片才浮得起來 */
  --surface-sunken: #090B0E;
  --surface: #14171C;
  --surface-input: #1A1E25;
  --surface-input-focus: #171B21;
  --surface-hover: rgba(255, 255, 255, 0.05);

  --border: #232830;
  /* 輸入框邊框比卡片邊框亮一階，否則在深底上會看不出可輸入區域的範圍 */
  --border-input: #2E343E;
  --border-input-hover: #3A414D;

  --text: #E6E9EF;
  --text-muted: #9BA3AF;
  /* 對 --surface 只有約 3.7:1，達不到 WCAG AA 的 4.5:1：
     僅供 placeholder 與純裝飾性圖示使用，不可拿來排任何需要閱讀的文字
     （狀態列、輔助說明、次要標籤一律用 --text-muted）。
     視覺階層一律靠字級與字重拉開，不靠再淡一階的顏色。 */
  --text-faint: #6B7280;

  --accent: #3B82F6;
  --accent-hover: #60A5FA;
  --accent-active: #2563EB;
  --accent-soft: rgba(59, 130, 246, 0.12);
  --accent-soft-border: rgba(59, 130, 246, 0.28);

  --danger: #F87171;
  --danger-text: #FCA5A5;
  --danger-bg: rgba(248, 113, 113, 0.09);
  --danger-border: rgba(248, 113, 113, 0.34);

  --success: #34D399;
  --success-text: #6EE7B7;
  --success-bg: rgba(52, 211, 153, 0.09);
  --success-border: rgba(52, 211, 153, 0.32);

  --radius: 12px;
  --radius-sm: 8px;

  /* 對焦環：2px 實心外光暈 + 一圈更淡的擴散，讓鍵盤操作者一眼看到焦點位置 */
  --ring: 0 0 0 2px rgba(59, 130, 246, 0.5), 0 0 0 5px rgba(59, 130, 246, 0.13);

  --shadow-card: 0 1px 2px rgba(0, 0, 0, 0.4), 0 18px 40px -20px rgba(0, 0, 0, 0.75);

  --font: system-ui, -apple-system, "Segoe UI", "Noto Sans TC", sans-serif;

  --card-width: min(400px, 92vw);
}

/* --------------------------------------------------------------------------
   基礎
   -------------------------------------------------------------------------- */

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

html {
  /* 避免 iOS 橫置時自動放大字級，破壞既有的字級階層 */
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  min-height: 100dvh;
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.6;
  color: var(--text);
  background-color: var(--bg);
  /* 兩道極淡的徑向光暈：純平的深色底會顯得廉價，用 gradient 製造景深即可，
     不必為此引入任何圖片資源 */
  background-image:
    radial-gradient(900px 480px at 50% -14%, rgba(59, 130, 246, 0.10), transparent 68%),
    radial-gradient(700px 420px at 90% 112%, rgba(59, 130, 246, 0.05), transparent 70%);
  background-repeat: no-repeat;
  background-attachment: fixed;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h1,
p {
  margin: 0;
}

::selection {
  background: rgba(59, 130, 246, 0.35);
  color: #FFFFFF;
}

/* 全域保底的鍵盤焦點樣式；表單元件在下方各自覆寫成更貼合外型的光暈 */
:focus-visible {
  outline: 2px solid var(--accent-hover);
  outline-offset: 2px;
}

/* --------------------------------------------------------------------------
   版面
   -------------------------------------------------------------------------- */

.app {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}

.auth {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
  /* 底部留白略少於頂部，視覺重心才會落在畫面中線偏上，比正中央更耐看 */
  padding: 48px 20px 40px;
}

/* 用 auto margin 而非 justify-content:center 做垂直置中。
   內容高於視窗時（矮視窗、虛擬鍵盤彈出、字級放大），flex 置中會把卡片頂端
   推到捲動範圍之外而永遠碰不到；auto margin 在空間不足時會塌成 0，
   內容自然靠上並保留正常捲動。 */
.auth > :first-child {
  margin-top: auto;
}

.auth > :last-child {
  margin-bottom: auto;
}

.auth__card {
  width: var(--card-width);
  padding: 32px 28px 30px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-card);
}

.auth__foot {
  width: var(--card-width);
  /* 用 text-align 而非 flex 置中：裡面的 .btn 是 inline-flex，靠繼承就能置中，
     且 login 頁的 <br> 換行在一般區塊流程中的行為才穩定（flex 容器內的
     匿名項目如何處理 <br> 各家引擎不一致） */
  font-size: 13.5px;
  line-height: 1.6;
  /* 用次階而非極淡：極淡色在 13.5px 只有約 3.7:1 對比，達不到 WCAG AA。
     極淡色僅保留給 placeholder 這類有可見 label 撐著的輔助文字 */
  color: var(--text-muted);
  text-align: center;
}

/* --------------------------------------------------------------------------
   品牌標頭
   -------------------------------------------------------------------------- */

.brand {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 5px;
  margin-bottom: 24px;
}

.brand__mark {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  margin-bottom: 9px;
  color: var(--accent-hover);
  background: var(--accent-soft);
  border: 1px solid var(--accent-soft-border);
  border-radius: 13px;
}

/* 登入成功的確認訊息用綠色，與登入／改密碼頁的藍色主行動區隔開 */
.brand__mark--success {
  color: var(--success);
  background: var(--success-bg);
  border-color: var(--success-border);
}

.brand__name {
  font-size: 20px;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: 0.01em;
}

.brand__tagline {
  font-size: 14px;
  line-height: 1.5;
  color: var(--text-muted);
  /* 儀表板用這行顯示 email（level），而 email 在 @ 和 . 處沒有預設斷行點，
     長網域會在窄螢幕把卡片撐破，故強制允許任意位置斷行 */
  overflow-wrap: anywhere;
}

/* --------------------------------------------------------------------------
   訊息橫幅
   -------------------------------------------------------------------------- */

.alert {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin-bottom: 18px;
  padding: 11px 13px;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  font-size: 14.5px;
  line-height: 1.55;
}

.alert__icon {
  flex: 0 0 auto;
  width: 17px;
  height: 17px;
  /* 與第一行文字的視覺基線對齊，圖示置頂會顯得偏高 */
  margin-top: 2px;
}

.alert__text {
  min-width: 0;
  /* 錯誤訊息可能含長字串（例如 email），強制斷行以免橫向溢出卡片 */
  overflow-wrap: anywhere;
}

.alert--error {
  color: var(--danger-text);
  background: var(--danger-bg);
  border-color: var(--danger-border);
}

.alert--error .alert__icon {
  color: var(--danger);
}

.alert--success {
  color: var(--success-text);
  background: var(--success-bg);
  border-color: var(--success-border);
}

.alert--success .alert__icon {
  color: var(--success);
}

/* 既非錯誤也非成功，而是「動手之前必須先知道的一件事」（例如編輯頁的憑證留空語意）。
   刻意用強調色而不是灰階：這類說明若排版得像背景文字就會被跳過，
   而它要防的正好是「沒讀到說明就照自己的猜想操作」。
   文字用 --text 而非 --accent-hover——整段藍字在深底上的可讀性反而比白字差。 */
.alert--info {
  color: var(--text);
  background: var(--accent-soft);
  border-color: var(--accent-soft-border);
}

.alert--info .alert__icon {
  color: var(--accent-hover);
}

/* --------------------------------------------------------------------------
   身分資訊（變更密碼頁）
   -------------------------------------------------------------------------- */

.identity {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 16px;
  padding: 11px 13px;
  background: var(--surface-input);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}

.identity__avatar {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--accent-soft);
  border: 1px solid var(--accent-soft-border);
  color: var(--accent-hover);
  font-size: 16px;
  font-weight: 600;
  line-height: 1;
}

.identity__text {
  /* min-width:0 是讓子元素的 ellipsis 生效的必要條件，flex 子項預設不會縮到內容寬度以下 */
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.identity__name,
.identity__email {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.identity__name {
  font-size: 15px;
  font-weight: 600;
  line-height: 1.45;
}

.identity__email {
  font-size: 13.5px;
  line-height: 1.45;
  color: var(--text-muted);
}

.note {
  margin-bottom: 18px;
  font-size: 14px;
  line-height: 1.65;
  color: var(--text-muted);
}

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

.form {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 7px;
}

.field__label {
  font-size: 13.5px;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--text-muted);
}

.field__input {
  width: 100%;
  padding: 10px 12px;
  font: inherit;
  font-size: 16px;
  color: var(--text);
  background: var(--surface-input);
  border: 1px solid var(--border-input);
  border-radius: var(--radius-sm);
  /* 關掉 iOS Safari 的內建圓角與內陰影，否則深色底上會出現一圈灰邊 */
  -webkit-appearance: none;
  appearance: none;
  transition: border-color 0.15s ease, box-shadow 0.15s ease, background-color 0.15s ease;
}

.field__input::placeholder {
  color: var(--text-faint);
}

.field__input:hover {
  border-color: var(--border-input-hover);
}

/* 文字輸入框用 :focus 而非 :focus-visible：滑鼠點擊也應該看得到焦點在哪一格 */
.field__input:focus {
  background: var(--surface-input-focus);
  border-color: var(--accent);
  box-shadow: var(--ring);
  /* 保留一圈透明 outline，Windows 高對比模式下才不會完全失去焦點指示 */
  outline: 2px solid transparent;
  outline-offset: 2px;
}

.field__hint {
  font-size: 13.5px;
  line-height: 1.5;
  /* 密碼規則屬於必要資訊而非裝飾，對比度不能犧牲，故用次階色 */
  color: var(--text-muted);
}

/* 唯讀的欄位值（例如渠道的類型），與輸入框同一行高，看起來是一格而不是一句話。 */
.field__static {
  padding: 8px 0;
  font-size: 15px;
  color: var(--text);
}

.form__actions {
  /* 送出鍵與最後一個欄位拉開一點，讓「填寫」與「動作」在視覺上分區 */
  margin-top: 6px;
}

/* Chrome／Safari 的自動填入會強制覆蓋成淺色底並改寫文字顏色。
   目前唯一穩定的壓制方式是用超大 inset shadow 蓋掉底色 +
   把 background-color 的 transition 拉到實質上不會發生。 */
.field__input:-webkit-autofill,
.field__input:-webkit-autofill:hover,
.field__input:-webkit-autofill:active {
  -webkit-text-fill-color: var(--text);
  caret-color: var(--text);
  -webkit-box-shadow: 0 0 0 1000px var(--surface-input) inset;
  box-shadow: 0 0 0 1000px var(--surface-input) inset;
  transition: background-color 600000s 0s, color 600000s 0s;
}

/* 自動填入狀態下仍要保留對焦環，否則 inset shadow 會把它整個蓋掉 */
.field__input:-webkit-autofill:focus {
  -webkit-box-shadow: 0 0 0 1000px var(--surface-input-focus) inset, var(--ring);
  box-shadow: 0 0 0 1000px var(--surface-input-focus) inset, var(--ring);
}

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

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 11px 16px;
  font: inherit;
  font-size: 16px;
  font-weight: 600;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease, transform 0.06s ease;
}

/* 主按鈕的對焦環用「底色隔開 + 亮藍外環」，直接疊藍色光暈在藍底上會看不見 */
.btn:focus-visible {
  outline: 2px solid transparent;
  outline-offset: 2px;
  box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--accent-hover);
}

.btn--primary {
  width: 100%;
  color: #FFFFFF;
  background: var(--accent);
  border-color: var(--accent);
}

.btn--primary:hover {
  background: var(--accent-hover);
  border-color: var(--accent-hover);
}

.btn--primary:active {
  background: var(--accent-active);
  border-color: var(--accent-active);
  /* 1px 下沉取代動畫，給出明確的「已按下」回饋 */
  transform: translateY(1px);
}

.btn--primary:disabled {
  color: #7C8697;
  background: #25324A;
  border-color: #25324A;
  cursor: not-allowed;
  transform: none;
}

/* 次要動作（登出）刻意做成低視覺重量，避免與主要動作競爭 */
.btn--ghost {
  padding: 6px 10px;
  font-size: 14px;
  font-weight: 500;
  color: var(--text-muted);
  background: transparent;
  border-color: transparent;
}

.btn--ghost:hover {
  color: var(--text);
  background: var(--surface-hover);
}

.btn--ghost:active {
  background: rgba(255, 255, 255, 0.08);
}

.btn--ghost:focus-visible {
  box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px var(--accent-hover);
}

/* --------------------------------------------------------------------------
   響應式
   -------------------------------------------------------------------------- */

@media (max-width: 420px) {
  .auth {
    padding: 32px 16px 28px;
  }

  .auth__card {
    padding: 26px 20px 24px;
  }

  .brand__name {
    font-size: 19px;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }

  /* 上面的 !important 會一併拆掉壓制 autofill 底色所倚賴的超長 transition，
     這裡補回來。此 transition 本來就不會產生任何可見動態，與減少動態的訴求無衝突。 */
  .field__input:-webkit-autofill,
  .field__input:-webkit-autofill:hover,
  .field__input:-webkit-autofill:focus,
  .field__input:-webkit-autofill:active {
    transition: background-color 600000s 0s, color 600000s 0s !important;
  }
}

/* ==========================================================================
   公司與管理者帳號管理（root 專用）

   本區段一律「只新增、不改動」上方任何既有變數與規則：登入流程已實測通過，
   一旦回頭調整既有選擇器，風險就會擴散到本次範圍之外。
   需要壓過既有規則之處（例如 .btn--primary 的滿版寬度）改以「同特異度但排在後面」
   的新 modifier 處理，這也是本區段必須留在檔案末尾的原因。
   ========================================================================== */

/* 只補本區段用得到的 token；色票沿用上方定義，不新增第二套。 */
:root {
  /* 表單頁刻意窄：輸入框拉到滿版寬會讓「一格要填多少」失去暗示 */
  --form-max: 760px;

  /* --surface 的全透明版本。捲動陰影需要「同色但透明」的漸層端點；
     直接寫 transparent 在部分瀏覽器會經透明黑插值，深色底上會浮出一圈灰邊 */
  --surface-fade: rgba(20, 23, 28, 0);
  /* 置頂列的半透明底：內容捲到列下方時仍看得出層次，又不會完全遮死 */
  --surface-translucent: rgba(20, 23, 28, 0.82);

  /* 與 --ring 同結構、換成危險色，供驗證失敗的欄位使用 */
  --ring-danger: 0 0 0 2px rgba(248, 113, 113, 0.45), 0 0 0 5px rgba(248, 113, 113, 0.12);
}

/* --------------------------------------------------------------------------
   共用小工具
   -------------------------------------------------------------------------- */

/* 螢幕閱讀器專用文字。憑證狀態以圖示 + 顏色表達，
   單靠顏色不構成可存取的資訊，必須另有文字說明實際狀態。 */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  white-space: nowrap;
  border: 0;
  clip-path: inset(50%);
}

/* 卡片式面板。背景刻意用 background-color 長寫法而非 background 簡寫：
   .table-wrap 會在同一個元素上疊多層 background-image 做捲動陰影，
   簡寫會把 background-image 一併重設，兩者的先後順序就變成隱性依賴。 */
.panel {
  background-color: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.link {
  color: var(--accent-hover);
  text-decoration: none;
}

.link:hover {
  text-decoration: underline;
}

/* --------------------------------------------------------------------------
   按鈕擴充
   -------------------------------------------------------------------------- */

a.btn {
  text-decoration: none;
}

/* .btn--primary 寫死 width:100%（登入頁的滿版送出鍵）。
   這裡靠「同特異度、排在後面」覆寫成內容寬，不去改動既有規則。 */
.btn--inline {
  width: auto;
}

.btn--block {
  width: 100%;
}

.btn--compact {
  padding: 8px 13px;
  font-size: 14.5px;
}

/* 中性次要動作（取消、編輯、清除搜尋）：有邊框、無填色，
   與主要動作明確分層，又比 .btn--ghost 更像可點擊的按鈕。 */
.btn--secondary {
  color: var(--text);
  background-color: var(--surface-input);
  border-color: var(--border-input);
}

/* hover 用一層極淡的白色漸層疊上去，而不是另外調一個十六進位色：
   既有色票沒有「比 --surface-input 亮一階」的 token，
   疊圖層可以只用現成變數就做出提亮，日後改色票也會跟著走。 */
.btn--secondary:hover {
  background-image: linear-gradient(var(--surface-hover), var(--surface-hover));
  border-color: var(--border-input-hover);
}

.btn--secondary:active {
  transform: translateY(1px);
}

/* 強調但非主要：用與 .brand__mark 相同的藍色淡底，
   避免同一張卡片上出現兩顆一模一樣的實心藍按鈕而分不出主次。 */
.btn--accent {
  color: var(--accent-hover);
  background-color: var(--accent-soft);
  border-color: var(--accent-soft-border);
}

.btn--accent:hover {
  background-image: linear-gradient(var(--accent-soft), var(--accent-soft));
  border-color: var(--accent);
}

.btn--accent:active {
  transform: translateY(1px);
}

.btn__icon {
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
}

/* --------------------------------------------------------------------------
   頁面標頭與工具列
   -------------------------------------------------------------------------- */

.backlink {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 14px;
  font-size: 14px;
  color: var(--text-muted);
  text-decoration: none;
  border-radius: var(--radius-sm);
}

.backlink:hover {
  color: var(--text);
}

.backlink svg {
  width: 15px;
  height: 15px;
}

.page-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 18px;
}

.page-head__title {
  font-size: 22px;
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: 0.01em;
}

.page-head__meta {
  margin-top: 3px;
  font-size: 14px;
  color: var(--text-muted);
}

.toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-bottom: 14px;
}

.search {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 1 1 260px;
  /* 搜尋框不該把整條工具列吃滿；超過這個寬度只是留白 */
  max-width: 460px;
}

.search__box {
  position: relative;
  flex: 1 1 auto;
  min-width: 0;
}

.search__icon {
  position: absolute;
  left: 11px;
  top: 50%;
  transform: translateY(-50%);
  width: 15px;
  height: 15px;
  color: var(--text-faint);
  /* 圖示落在輸入框範圍內，不攔截點擊，否則點到圖示不會聚焦到欄位 */
  pointer-events: none;
}

.search__input {
  padding-left: 34px;
}

/* --------------------------------------------------------------------------
   資料表格
   -------------------------------------------------------------------------- */

/* 橫向捲動容器。四層背景是「捲動陰影」：兩層與底色同色的遮罩隨內容捲動
   （background-attachment: local），兩層陰影固定在容器邊緣。
   內容捲到底時遮罩會蓋住陰影，陰影自動消失——因此邊緣有沒有陰影
   直接等同於「該方向還有沒有內容」，比固定的漸層更誠實。 */
.table-wrap {
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background-color: var(--surface);
  background-image:
    linear-gradient(to right, var(--surface) 38%, var(--surface-fade)),
    linear-gradient(to left, var(--surface) 38%, var(--surface-fade)),
    radial-gradient(farthest-side at 0 50%, rgba(0, 0, 0, 0.45), rgba(0, 0, 0, 0)),
    radial-gradient(farthest-side at 100% 50%, rgba(0, 0, 0, 0.45), rgba(0, 0, 0, 0));
  background-position: left center, right center, left center, right center;
  background-repeat: no-repeat;
  background-size: 46px 100%, 46px 100%, 15px 100%, 15px 100%;
  background-attachment: local, local, scroll, scroll;
}

/* 可捲動區域要能用鍵盤操作，故加了 tabindex；補上對焦樣式讓焦點看得見 */
.table-wrap:focus-visible {
  outline: 2px solid var(--accent-hover);
  outline-offset: 2px;
}

.data-table {
  width: 100%;
  /* 低於這個寬度欄位會互相擠壓到無法閱讀，寧可讓容器橫向捲動 */
  min-width: 880px;
  border-collapse: collapse;
  font-size: 15px;
}

.data-table th,
.data-table td {
  padding: 12px 14px;
  text-align: left;
  vertical-align: middle;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}

/* 表頭刻意不給底色：.table-wrap 的捲動陰影畫在容器背景上，
   任何不透明的子元素底色都會把該段陰影擋掉，變成「表頭那一條看不出還能捲」。
   改以較粗的下框線 + 小字級標籤區分表頭。 */
.data-table thead th {
  font-size: 13.5px;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--text-muted);
  border-bottom-color: var(--border-input);
}

.data-table tbody tr:last-child td {
  border-bottom: none;
}

.data-table tbody tr:hover td {
  background-color: var(--surface-hover);
}

/* 公司名稱與 email 是唯二可能超長的欄位：限寬並允許換行，
   否則單一筆長資料就會把整張表拉寬到得捲很久才看得到操作欄。 */
.data-table .cell-name,
.data-table .cell-email {
  white-space: normal;
  max-width: 26ch;
  overflow-wrap: anywhere;
}

.data-table .cell-name {
  font-weight: 600;
}

.data-table .cell-email {
  color: var(--text-muted);
}

.data-table .cell-time {
  font-size: 14px;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

.data-table .cell-actions {
  text-align: right;
}

/* 窄螢幕的補充提示。捲動陰影是視覺線索，但第一次使用的人未必解讀得出來，
   小螢幕再明說一次，避免誤以為欄位被截斷。 */
.table-hint {
  display: none;
  margin-top: 8px;
  font-size: 13.5px;
  color: var(--text-muted);
}

/* --------------------------------------------------------------------------
   狀態徽章與憑證狀態
   -------------------------------------------------------------------------- */

.badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 9px;
  border: 1px solid transparent;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 500;
  line-height: 1.6;
  white-space: nowrap;
}

.badge__dot {
  flex: 0 0 auto;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
}

.badge--active {
  color: var(--success-text);
  background: var(--success-bg);
  border-color: var(--success-border);
}

/* 停用是正常的營運狀態而非錯誤，用中性灰而不是危險紅，
   否則列表上每個停用租戶都像出了問題。 */
.badge--suspended {
  color: var(--text-muted);
  background: var(--surface-input);
  border-color: var(--border-input);
}

.creds {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.cred {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 8px;
  border: 1px solid var(--border-input);
  border-radius: var(--radius-sm);
  font-size: 13px;
  line-height: 1.6;
  /* 未設定用次階色而非最淡色：13px 下最淡色達不到 WCAG AA */
  color: var(--text-muted);
  background: var(--surface-input);
  white-space: nowrap;
}

.cred--on {
  color: var(--success-text);
  background: var(--success-bg);
  border-color: var(--success-border);
}

.cred__icon {
  flex: 0 0 auto;
  width: 13px;
  height: 13px;
}

/* --------------------------------------------------------------------------
   空狀態
   -------------------------------------------------------------------------- */

.empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 7px;
  padding: 60px 24px;
}

.empty__mark {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  margin-bottom: 6px;
  color: var(--accent-hover);
  background: var(--accent-soft);
  border: 1px solid var(--accent-soft-border);
  border-radius: 14px;
}

/* 圖示對照表（admin/_icons.html）刻意不吐 width/height——尺寸交給呼叫端決定，
   同一顆圖示才能放在選單、頁首與空狀態三種尺寸下。空狀態的尺寸就寫在這裡。 */
.empty__mark-icon {
  width: 22px;
  height: 22px;
}

.empty__title {
  margin: 0;
  font-size: 17px;
  font-weight: 600;
  line-height: 1.4;
}

.empty__text {
  max-width: 44ch;
  font-size: 14.5px;
  line-height: 1.65;
  color: var(--text-muted);
  overflow-wrap: anywhere;
}

.empty__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  margin-top: 10px;
}

/* --------------------------------------------------------------------------
   分頁
   -------------------------------------------------------------------------- */

.pager {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 6px;
  margin-top: 18px;
}

.pager__item {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 36px;
  height: 34px;
  padding: 0 10px;
  font-size: 14.5px;
  color: var(--text-muted);
  background-color: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  text-decoration: none;
  transition: color 0.15s ease, border-color 0.15s ease;
}

.pager__item:hover {
  color: var(--text);
  border-color: var(--border-input-hover);
}

.pager__item--current {
  color: #FFFFFF;
  background-color: var(--accent);
  border-color: var(--accent);
  font-weight: 600;
}

/* 首／末頁的上下頁鈕：留在原位保持版面穩定，但明確標示不可點 */
.pager__item--disabled {
  opacity: 0.4;
  pointer-events: none;
}

.pager__gap {
  padding: 0 2px;
  color: var(--text-faint);
  font-size: 14.5px;
}

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

.form-card {
  padding: 26px 26px 24px;
}

/* fieldset 的 UA 樣式（邊框、內距、min-width:min-content）會干擾自訂版面；
   min-width:0 尤其必要，否則裡面的 grid 欄位不會縮到內容寬度以下，窄螢幕會溢出。 */
.fieldset {
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.fieldset + .fieldset {
  margin-top: 26px;
  padding-top: 24px;
  border-top: 1px solid var(--border);
}

.fieldset__legend {
  /* legend 預設會浮在 fieldset 邊框上；邊框已移除，這裡當成一般標題排版 */
  display: block;
  width: 100%;
  padding: 0;
  margin-bottom: 3px;
  font-size: 15.5px;
  font-weight: 600;
  line-height: 1.5;
  color: var(--text);
}

.fieldset__desc {
  margin-bottom: 16px;
  font-size: 13.5px;
  line-height: 1.65;
  color: var(--text-muted);
}

/* 短欄位兩欄並排，減少表單的垂直長度；長字串欄位（email、憑證）維持整列 */
.form--grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
}

.field--full {
  grid-column: 1 / -1;
}

.field__required {
  margin-left: 3px;
  color: var(--danger-text);
}

.field__optional {
  margin-left: 6px;
  font-weight: 400;
  color: var(--text-muted);
}

/* 欄位層級的錯誤訊息。頂部橫幅只說「有錯」，真正要修哪一格得長在該格旁邊 */
.field__error {
  display: flex;
  align-items: flex-start;
  gap: 6px;
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--danger-text);
  overflow-wrap: anywhere;
}

.field__error svg {
  flex: 0 0 auto;
  width: 14px;
  height: 14px;
  margin-top: 2px;
  color: var(--danger);
}

.field__input[aria-invalid="true"] {
  border-color: var(--danger-border);
}

.field__input[aria-invalid="true"]:hover {
  border-color: var(--danger);
}

.field__input[aria-invalid="true"]:focus {
  border-color: var(--danger);
  box-shadow: var(--ring-danger);
}

/* 不可編輯的既有值（例如編輯頁的 admin email）。
   刻意用虛線框與非輸入框的底色，一眼就看得出「這格不是給你填的」。 */
.readonly-value {
  padding: 10px 12px;
  font-size: 15px;
  color: var(--text-muted);
  background: var(--surface-input);
  border: 1px dashed var(--border-input);
  border-radius: var(--radius-sm);
  overflow-wrap: anywhere;
}

/* 下拉選單：外觀交給自訂箭頭，避免各平台原生樣式在深色底上不一致。
   箭頭放在包裝層而不是 background-image——.field__input:focus 用的是
   background 簡寫，會把 background-image 重設掉，箭頭一聚焦就會消失。 */
.select {
  position: relative;
  display: flex;
  min-width: 0;
}

.select__input {
  padding-right: 34px;
  cursor: pointer;
}

.select__arrow {
  position: absolute;
  right: 12px;
  top: 50%;
  transform: translateY(-50%);
  width: 14px;
  height: 14px;
  color: var(--text-muted);
  pointer-events: none;
}

/* --------------------------------------------------------------------------
   憑證輸入
   -------------------------------------------------------------------------- */

/* 現有憑證的遮蔽提示（例如 sk-…8f2a）。做成有框的小標籤而非普通文字，
   讓人一眼看出這是系統產生的殘缺提示，不是可以照抄的完整值。 */
.hint-value {
  display: inline-block;
  padding: 1px 6px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 13px;
  color: var(--text);
  background: var(--surface-input);
  border: 1px solid var(--border-input);
  border-radius: 5px;
  overflow-wrap: anywhere;
}

.secret {
  position: relative;
  display: flex;
  min-width: 0;
}

.secret__input {
  padding-right: 42px;
  /* 憑證是不換行的長字串，等寬字型才看得出有沒有多打一個字元 */
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 15px;
}

.secret__input::placeholder {
  font-family: var(--font);
}

/* Edge 會在密碼欄位右側自己長出一顆顯示按鈕，與自訂切換鈕重複 */
.secret__input::-ms-reveal {
  display: none;
}

.secret__toggle {
  position: absolute;
  right: 5px;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  padding: 0;
  color: var(--text-muted);
  background: transparent;
  border: 1px solid transparent;
  border-radius: 6px;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  transition: color 0.15s ease, background-color 0.15s ease;
}

/* 切換鈕預設帶 hidden，由 JS 取消隱藏（漸進增強）。
   .secret__toggle 的 display:flex 會蓋掉 hidden 的 UA display:none，故明確補回。 */
.secret__toggle[hidden] {
  display: none;
}

.secret__toggle:hover {
  color: var(--text);
  background: var(--surface-hover);
}

.secret__toggle:focus-visible {
  outline: 2px solid transparent;
  outline-offset: 0;
  box-shadow: 0 0 0 2px var(--accent-hover);
}

.secret__toggle svg {
  width: 17px;
  height: 17px;
}

/* 兩個圖示疊在同一顆按鈕上，靠狀態切換顯示哪一個 */
.secret__toggle .icon-hide,
.secret__toggle.is-on .icon-show {
  display: none;
}

.secret__toggle.is-on .icon-hide {
  display: block;
}

/* --------------------------------------------------------------------------
   表單動作列
   -------------------------------------------------------------------------- */

.form-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 26px;
  padding-top: 22px;
  border-top: 1px solid var(--border);
}

/* --------------------------------------------------------------------------
   響應式
   -------------------------------------------------------------------------- */

/* 表格開始橫捲的門檻是「可用寬度 < .data-table 的 min-width 880px」，
   而外殼的可用寬度 = 視窗寬 − --side-w − 2 × --pad-x − .table-wrap 的兩道 1px 邊框。
   完整選單（236 + 2×30 + 2）→ 視窗 < 1178 就開始捲，因此斷點取 1177。
   側選單縮成圖示軌時可用寬度變多，門檻跟著下移，那兩種情況在 D 段（外殼）
   的響應式區另有兩條例外把提示收回去——這串數字是從上面那條算式推出來的，
   日後調整 --side-w／--pad-x／min-width 時三處要一起重算。 */
@media (max-width: 1177px) {
  .table-hint {
    display: block;
  }
}

@media (max-width: 680px) {
  .page-head {
    align-items: stretch;
  }

  .page-head__title {
    font-size: 20px;
  }

  .search {
    max-width: none;
  }

  .form-card {
    padding: 22px 18px 20px;
  }

  .form--grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (max-width: 520px) {
  /* 動作鈕改為滿版直排。用 column-reverse 讓主要動作留在上方——
     直排時最上面才是拇指與視線最先抵達的位置。 */
  .form-actions {
    flex-direction: column-reverse;
    align-items: stretch;
  }

  .form-actions .btn {
    width: 100%;
  }

  .page-head .btn {
    width: 100%;
  }
}

/* ==========================================================================
   軟刪除、帳號管理與危險操作（root 專用）

   與上一段同樣的原則：只在檔案末尾新增，不回頭改動任何既有變數與規則。
   本段要解決的是一個純視覺的問題——「刪除」在本系統有兩種後果完全不同的形式
   （可還原的軟刪除、不可復原的永久清除），畫成同一種紅色按鈕的話，
   使用者遲早會把其中一個當成另一個來按。因此兩者在色彩重量、確認步數與
   文案上都刻意分開，而不是共用同一組樣式。
   ========================================================================== */

:root {
  /* --danger（#F87171）是為「深底上的紅字」挑的亮紅，拿來當實心按鈕的底色時
     白字只有約 2.9:1，達不到 WCAG AA。實心危險按鈕另外用一組更深的紅：
     白字對 #DC2626 約 4.8:1，hover／active 再往下壓，對比只會更好不會更差。
     既有的 --danger 系列一律不動，這裡只是補上原本沒有的「實心」那一階。 */
  --danger-solid: #DC2626;
  --danger-solid-hover: #B91C1C;
  --danger-solid-active: #991B1B;
}

/* --------------------------------------------------------------------------
   危險動作按鈕
   -------------------------------------------------------------------------- */

/* 實心紅：只給「按下去就真的發生了」的最後一步用（永久清除的送出、
   展開確認後的刪除送出）。頁面上同時出現兩顆實心紅按鈕即為設計失誤。 */
.btn--danger {
  color: #FFFFFF;
  background-color: var(--danger-solid);
  border-color: var(--danger-solid);
}

.btn--danger:hover {
  background-color: var(--danger-solid-hover);
  border-color: var(--danger-solid-hover);
}

.btn--danger:active {
  background-color: var(--danger-solid-active);
  border-color: var(--danger-solid-active);
  transform: translateY(1px);
}

.btn--danger:disabled {
  color: #C7A3A3;
  background-color: #4A2020;
  border-color: #4A2020;
  cursor: not-allowed;
  transform: none;
}

/* 淡紅：用於「展開確認」「前往清除頁」這類還沒有實際後果的入口。
   結構與 .btn--accent 相同，只是換成危險色票——同一頁上因此看得出
   「這是危險方向，但還不是那一步」。 */
.btn--danger-soft {
  color: var(--danger-text);
  background-color: var(--danger-bg);
  border-color: var(--danger-border);
}

.btn--danger-soft:hover {
  background-image: linear-gradient(var(--danger-bg), var(--danger-bg));
  border-color: var(--danger);
}

.btn--danger-soft:active {
  transform: translateY(1px);
}

/* 既有的 .btn:focus-visible 用藍色外環；紅底上的藍環辨識度差，
   而且會讓「這顆是危險按鈕」的訊號在鍵盤操作時被稀釋。 */
.btn--danger:focus-visible,
.btn--danger-soft:focus-visible {
  outline: 2px solid transparent;
  outline-offset: 2px;
  box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--danger);
}

/* --------------------------------------------------------------------------
   已刪除狀態的標示
   -------------------------------------------------------------------------- */

/* 「這家公司已被刪除」的橫幅。外觀與 .alert--error 相同（同一組危險色票），
   但類別名稱另取：它陳述的是一個狀態，不是這次操作失敗，
   兩者若共用類別，日後想單獨調整其中一種就會連動到另一種。 */
.alert--deleted {
  color: var(--danger-text);
  background: var(--danger-bg);
  border-color: var(--danger-border);
}

.alert--deleted .alert__icon {
  color: var(--danger);
}

/* 列表用。停用是正常營運狀態（灰），已刪除則不是，故用危險色與之分開。 */
.badge--deleted {
  color: var(--danger-text);
  background: var(--danger-bg);
  border-color: var(--danger-border);
}

/* 已刪除的列：在最左側補一道紅色標記，狀態另有 .badge--deleted。
   刻意不再降一階顏色——管理者 email 與刪除時間正是「要還原還是永久清除」的判斷依據，
   最淡色對卡片底只有 3.7:1，達不到 WCAG AA（見檔案開頭 --text-faint 的說明）。
   用 inset box-shadow 而非 border-left：border-collapse 下相鄰儲存格的
   邊框會互相塌陷，實際畫出來的粗細不可靠。 */
.data-table tr.is-deleted td {
  color: var(--text-muted);
}

.data-table tr.is-deleted td:first-child {
  box-shadow: inset 3px 0 0 var(--danger);
}

/* --------------------------------------------------------------------------
   檢視切換（正常／已刪除）
   -------------------------------------------------------------------------- */

/* 做成分段控制而不是下拉或核取方塊：兩個檢視是互斥的，
   而且「目前在看哪一份資料」必須隨時看得見——列表頁最危險的誤會就是
   把已刪除的清單當成全部的公司。 */
.viewswitch {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 3px;
  background-color: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}

.viewswitch__item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  font-size: 14px;
  color: var(--text-muted);
  text-decoration: none;
  border-radius: 6px;
  white-space: nowrap;
  transition: color 0.15s ease, background-color 0.15s ease;
}

.viewswitch__item:hover {
  color: var(--text);
  background-color: var(--surface-hover);
}

.viewswitch__item--current {
  color: var(--text);
  background-color: var(--surface-input);
}

/* 目前這一格是「已刪除」時給紅色文字：切到這個檢視之後，
   底下每一列都是已刪除的資料，這件事要在切換鈕本身就講清楚。 */
.viewswitch__item--current.viewswitch__item--deleted {
  color: var(--danger-text);
  background-color: var(--danger-bg);
}

/* 工具列裡靠右的一組。搜尋框是 flex:1，靠 auto margin 把切換推到另一端，
   窄螢幕 flex-wrap 換行時也不會留下奇怪的空隙。 */
.toolbar__end {
  margin-left: auto;
}

/* --------------------------------------------------------------------------
   面板堆疊（編輯頁）
   -------------------------------------------------------------------------- */

/* 編輯頁從「一張表單卡」變成多張卡片：HTML 的 form 不能巢狀，
   而管理者帳號、密碼重設、帳號狀態與刪除各自送到不同的路由，
   因此只能是彼此獨立的兄弟表單。 */
.panel + .panel {
  margin-top: 20px;
}

.panel + .danger-zone {
  /* 危險區與上方的一般編輯區要拉開到「不是同一組東西」的距離 */
  margin-top: 34px;
}

.panel__heading {
  /* 與 .fieldset__legend 同一階，但用在 h2 上（非 fieldset 的卡片標題）。
     下方間距也跟著對齊，否則標題會與緊接著的說明文字黏成一行 */
  margin: 0 0 3px;
  font-size: 15.5px;
  font-weight: 600;
  line-height: 1.5;
  color: var(--text);
}

/* 同一張卡片裡的第二個以後的段落標題：與上一段拉開，
   否則兩段說明會黏成一段，看起來像同一件事的續篇。 */
.panel__heading--gap {
  margin-top: 26px;
}

/* 同一張卡片內的數個獨立表單。之間必須看得出分隔，
   否則使用者會以為底下的按鈕會一併儲存上面那幾格。 */
.subform + .subform {
  margin-top: 22px;
  padding-top: 20px;
  border-top: 1px solid var(--border);
}

/* 前面不是另一個 subform 時（永久清除頁的確認表單接在對照卡之後）
   得自己要求這道分隔，否則「確認」會看起來像對照卡的一部分。
   間距略大於上面那條：那是同一張卡片內連續的兩段，這裡跨的是兩種不同的內容。 */
.subform--separated {
  margin-top: 26px;
  padding-top: 24px;
  border-top: 1px solid var(--border);
}

.subform__title {
  margin: 0 0 3px;
  font-size: 14.5px;
  font-weight: 600;
  line-height: 1.5;
  color: var(--text);
}

.subform__desc {
  margin-bottom: 14px;
  font-size: 13.5px;
  line-height: 1.65;
  color: var(--text-muted);
}

.subform__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-top: 14px;
}

/* 帳號目前狀態那一行：徽章與補充說明並排 */
.statusline {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
}

.statusline__note {
  font-size: 13.5px;
  color: var(--text-muted);
}

/* --------------------------------------------------------------------------
   後果清單
   -------------------------------------------------------------------------- */

/* 危險操作的說明不寫成一整段：整段文字會被跳讀，而這裡每一條都是
   使用者按下去之後真的會發生的事。逐條列出並用圖示區分「保留」與「消失」，
   讓兩種刪除的差異用掃的就看得出來。 */
.consequences {
  display: flex;
  flex-direction: column;
  gap: 7px;
  margin: 10px 0 0;
  padding: 0;
  list-style: none;
}

.consequences__item {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--text-muted);
  overflow-wrap: anywhere;
}

.consequences__item svg {
  flex: 0 0 auto;
  width: 14px;
  height: 14px;
  /* 與第一行文字的視覺基線對齊 */
  margin-top: 3px;
  color: var(--text-faint);
}

/* 會保留下來的用綠色勾、會消失或立刻改變的用紅色叉、需要另外注意的用藍色驚嘆號。
   顏色只是輔助，句子本身已經把結果講完，色盲使用者不會漏掉資訊。
   同一份清單裡兩種結果常常交錯出現（軟刪除就是「保留資料但中斷服務」），
   因此修飾詞下在項目而不是清單上。 */
.consequences__item--keep svg {
  color: var(--success);
}

.consequences__item--lose svg {
  color: var(--danger);
}

.consequences__item--note svg {
  color: var(--accent-hover);
}

/* 整份清單同一種結果時（永久清除頁的「會消失的東西」）用清單層級的修飾詞，
   不必在每一項重複。 */
.consequences--lose .consequences__item svg {
  color: var(--danger);
}

/* --------------------------------------------------------------------------
   頁內二次確認（details/summary）
   -------------------------------------------------------------------------- */

/* 本專案禁止用 confirm()：它無法排版、無法說明後果，而且在多數瀏覽器裡
   長得跟釣魚視窗一樣。改用原生的展開區塊——不需要任何 JS 就能運作，
   關掉 JS 的環境不會退化成「一按就刪」，鍵盤與螢幕報讀器也原生支援。 */
.disclosure {
  margin-top: 14px;
}

/* summary 同時掛著 .btn 系列的類別。.btn 的 display:inline-flex 已經
   蓋掉 list-item，Chrome／Firefox 的三角形因此消失；Safari 另有一顆
   ::-webkit-details-marker，必須單獨關掉，否則按鈕左邊會多一個三角。 */
.disclosure__summary {
  list-style: none;
  cursor: pointer;
}

.disclosure__summary::-webkit-details-marker {
  display: none;
}

.disclosure__summary::marker {
  content: "";
}

/* 展開後的確認區。有自己的邊框與底色，讓「你已經進到確認步驟」這件事
   在視覺上是一個明確的狀態，而不只是多冒出一顆按鈕。 */
.disclosure__panel {
  margin-top: 12px;
  padding: 14px 16px;
  border: 1px solid var(--border-input);
  border-radius: var(--radius-sm);
  background-color: var(--surface-input);
}

.disclosure__panel--danger {
  border-color: var(--danger-border);
  background-image: linear-gradient(var(--danger-bg), var(--danger-bg));
}

.disclosure__question {
  font-size: 14.5px;
  font-weight: 600;
  line-height: 1.55;
  color: var(--text);
}

.disclosure__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-top: 14px;
}

/* --------------------------------------------------------------------------
   危險操作區
   -------------------------------------------------------------------------- */

.danger-zone {
  border-color: var(--danger-border);
  /* .panel 用的是 background-color 長寫法，這裡疊 image 把整張卡片染上一層
     極淡的紅：不改既有規則就能做出色調差異（同 .btn--secondary:hover 的作法）。
     只染標頭而不染整張卡的話，捲到下半部時就看不出自己還在危險區裡。 */
  background-image: linear-gradient(
    rgba(248, 113, 113, 0.04),
    rgba(248, 113, 113, 0.04)
  );
}

.danger-zone__head {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 16px 20px;
  border-bottom: 1px solid var(--danger-border);
  background-image: linear-gradient(var(--danger-bg), var(--danger-bg));
  /* 內容要貼齊外框的圓角，扣掉 1px 的邊框寬度 */
  border-radius: calc(var(--radius) - 1px) calc(var(--radius) - 1px) 0 0;
}

.danger-zone__mark {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  color: var(--danger);
  background: var(--danger-bg);
  border: 1px solid var(--danger-border);
  border-radius: 10px;
}

.danger-zone__mark svg {
  width: 17px;
  height: 17px;
}

.danger-zone__title {
  margin: 0;
  font-size: 15.5px;
  font-weight: 600;
  line-height: 1.5;
  color: var(--danger-text);
}

.danger-zone__desc {
  margin-top: 2px;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--text-muted);
}

.danger-item {
  padding: 18px 20px 20px;
}

.danger-item + .danger-item {
  border-top: 1px solid var(--danger-border);
}

.danger-item__title {
  margin: 0;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.5;
  color: var(--text);
}

.danger-item__text {
  margin-top: 4px;
  font-size: 13.5px;
  line-height: 1.65;
  color: var(--text-muted);
}

/* --------------------------------------------------------------------------
   永久清除確認頁
   -------------------------------------------------------------------------- */

.purge-card {
  padding: 24px 26px 26px;
}

/* 軟刪除與永久清除並排對照。這是整份設計的重點：兩者都叫「刪除」，
   後果卻一個可逆一個不可逆，只有把兩欄放在一起才看得出差在哪裡。 */
.compare {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
  margin-top: 18px;
}

.compare__card {
  padding: 14px 16px 16px;
  border: 1px solid var(--border-input);
  border-radius: var(--radius-sm);
  background-color: var(--surface-input);
}

.compare__card--danger {
  border-color: var(--danger-border);
  background-image: linear-gradient(var(--danger-bg), var(--danger-bg));
}

/* 標籤本身要讀得出來：窄螢幕收成單欄之後，「已經做過／你正要做」是唯一區分
   可逆與不可逆的線索，12.5px 用最淡色在輸入框底上只有 3.5:1（危險卡更低）。 */
.compare__label {
  font-size: 12.5px;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  text-transform: uppercase;
}

.compare__title {
  margin: 2px 0 0;
  font-size: 14.5px;
  font-weight: 600;
  line-height: 1.5;
  color: var(--text);
}

.compare__card--danger .compare__title {
  color: var(--danger-text);
}

/* 會一併消失的資料清單 */
.purge-targets {
  display: flex;
  flex-direction: column;
  gap: 0;
  margin: 14px 0 0;
  padding: 0;
  list-style: none;
  border: 1px solid var(--border-input);
  border-radius: var(--radius-sm);
  overflow: hidden;
}

.purge-targets__item {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 10px 14px;
  font-size: 14px;
  line-height: 1.6;
  background-color: var(--surface-input);
  overflow-wrap: anywhere;
}

.purge-targets__item + .purge-targets__item {
  border-top: 1px solid var(--border);
}

.purge-targets__label {
  flex: 0 0 auto;
  min-width: 7.5em;
  color: var(--text-muted);
  font-size: 13.5px;
}

.purge-targets__value {
  min-width: 0;
  color: var(--text);
}

/* 未來才會有的資料（知識庫、對話紀錄）也必須列出來：使用者要判斷的是
   「清掉之後會失去什麼」，只列現在有的會讓人低估後果。
   顏色只比現有資料低一階（--text-muted），不用最淡色：這一整頁的目的就是
   讓人看清楚後果，讀不清楚的後果等於沒有列。 */
.purge-targets__value--future {
  color: var(--text-muted);
}

/* 要逐字輸入的公司名稱。做成一個可整段選取的區塊而非行內文字：
   使用者必須先看清楚要打的到底是什麼，
   user-select:all 讓一次點擊就能選起整串，避免只複製到一半。

   邊框刻意用虛線——與 .readonly-value 同一套語彙（「這一格不是給你填的」）。
   實線加上輸入框底色的話，它會和正下方那個真的輸入框長得一模一樣，
   使用者第一個動作就是想往這一格裡打字。 */
.confirm-target {
  display: block;
  padding: 9px 12px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 15px;
  line-height: 1.6;
  color: var(--text);
  background: var(--surface-input);
  border: 1px dashed var(--border-input);
  border-radius: var(--radius-sm);
  /* 空白一律照原樣呈現。預設的 normal 會把公司名稱中間的連續半形空白摺成一個，
     於是畫面顯示的、點一下複製到的，都與伺服器端逐字比對的 tenants.name 不同——
     那家公司就再也無法通過這一頁的確認。pre-wrap 而非 pre：
     配合下面的 overflow-wrap，長名稱仍然會換行而不是把版面撐開。 */
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  -webkit-user-select: all;
  user-select: all;
}

/* 即時比對結果。保留固定高度，字出現時版面不會跳動。
   這只是輔助——是否放行一律由伺服器端重新比對決定。 */
.confirm-state {
  display: flex;
  align-items: center;
  gap: 6px;
  min-height: 20px;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--text-muted);
}

.confirm-state svg {
  flex: 0 0 auto;
  width: 14px;
  height: 14px;
}

.confirm-state--match {
  color: var(--success-text);
}

/* --------------------------------------------------------------------------
   響應式
   -------------------------------------------------------------------------- */

@media (max-width: 680px) {
  /* 兩欄對照在窄螢幕會擠成兩條細長的柱子，反而看不出對照關係 */
  .compare {
    grid-template-columns: minmax(0, 1fr);
  }

  .toolbar__end {
    /* 換行之後靠右的推力沒有意義，改為與搜尋框同一個起點對齊 */
    margin-left: 0;
  }

  .viewswitch {
    width: 100%;
  }

  .viewswitch__item {
    flex: 1 1 0;
    justify-content: center;
  }

  .danger-zone__head,
  .danger-item {
    padding-left: 16px;
    padding-right: 16px;
  }

  .purge-card {
    padding: 20px 18px 22px;
  }

  .purge-targets__item {
    flex-direction: column;
    gap: 2px;
  }
}

@media (max-width: 520px) {
  .subform__actions .btn,
  .disclosure__actions .btn,
  .disclosure__summary {
    width: 100%;
  }

  /* 既有的 .form-actions 在窄螢幕改用 column-reverse，讓主要動作留在最上面
     （拇指與視線最先抵達的位置）。永久清除頁不適用這個原則：那一頁的主要動作
     不可逆，放在最順手的位置只會提高誤按的機率，寧可讓「取消」先出現。
     以同特異度、排在後面的規則覆寫，不去改動既有那一條。 */
  .form-actions--danger {
    flex-direction: column;
  }
}

/* ==========================================================================
   應用程式外殼（app/templates/admin/_shell.html）

   與前兩段同樣的原則：只在檔案末尾新增，不回頭改動任何既有變數與規則。
   外殼把視窗切成「頂列 / 側選單 / 主內容 / 狀態列」四塊，登入頁與變更密碼頁
   不套這一層（那兩頁是單張置中卡片，`.auth` 那一套仍然完整有效）。

   本段刻意不重寫 .btn、.badge、.select、.table-wrap、.pager 這些既有元件：
   C 版面稿為了能單獨開啟而附了自己的一份，貼進來會蓋掉上面的規則
   （例如 C 的 .btn 是 background:transparent，會把所有實心按鈕的顏色洗掉）。
   外殼只補「原本沒有」的東西。

   ── 命名上要注意的一件事 ────────────────────────────────────────────────
   `.page-head`（有連字號，本檔上方）是遷入外殼前各頁自己畫的標題區，
   `.pagehead`（無連字號，本段）是外殼提供的那一個。兩者目前並存：
   公司管理等既有頁面維持自己的 .page-head（換外框不改畫面），
   新頁面（admin/_placeholder.html）則由外殼的 pagehead block 統一畫。
   等既有頁面全部改用外殼的頁首之後，.page-head 那一段才能清掉。
   ========================================================================== */

/* --------------------------------------------------------------------------
   骨架與圖示軌開關
   -------------------------------------------------------------------------- */

/* 骨架尺寸掛在 .shell 而不是 :root：登入頁與變更密碼頁不在外殼裡，
   把這些值放進 :root 等於讓兩套完全不同的版型共用同一組尺寸變數，
   日後調整外殼時很難確定會不會波及登入流程。 */
.shell {
  --nav-h: 60px;      /* 頂部列 */
  --status-h: 32px;   /* 底部狀態列 */
  --side-w: 236px;    /* 左側選單 */
  --pad-x: 30px;      /* 主內容區左右留白 */

  /* 側選單有兩種形態：完整選單與只剩圖示的軌。切換的觸發條件有兩個
     ——使用者自己按了收合（html.side-collapsed），或視窗窄到放不下（媒體查詢）。
     CSS 沒辦法用一個選擇器同時表達這兩者，若把每一條規則各寫兩次，
     日後改一個內距就要記得改兩個地方。因此改成「切換的只有下面這組變數」，
     真正的樣式規則只寫一次。 */
  --rail-label-display: block;              /* 收合後要消失的文字 */
  --rail-justify: flex-start;
  --rail-brand-pad: 0 16px 0 20px;
  --rail-item-gap: 11px;
  --rail-item-pad: 9px 10px;
  --rail-group-gap: 22px;
  --rail-group-pad: 0;
  --rail-group-line: 0 solid transparent;   /* 收合後改用一道線取代分組標題 */
  --rail-collapse-display: flex;
  --rail-caret-rotate: 0deg;

  /* 外殼自己吃滿視窗高度並管理捲動：只有主內容區會捲，
     頂列／側選單／狀態列因此天生固定，不需要 position:fixed
     （fixed 會脫離文件流，還得手動補回它佔掉的空間，容易與捲動條打架）。
     body 的 min-height:100dvh 與捲動維持原樣，登入頁不受影響。 */
  height: 100dvh;
  overflow: hidden;
  display: grid;
  grid-template-columns: var(--side-w) minmax(0, 1fr);
  grid-template-rows: var(--nav-h) minmax(0, 1fr) var(--status-h);
  grid-template-areas:
    "brand  topbar"
    "side   main"
    "status status";
}

.shell__brand  { grid-area: brand; }
.shell__topbar { grid-area: topbar; }
.shell__side   { grid-area: side; }
.shell__main   { grid-area: main; }
.shell__status { grid-area: status; }

/* 使用者按下收合鈕（狀態存在 localStorage，見 _shell.html 的 script） */
html.side-collapsed .shell {
  --side-w: 68px;
  --rail-label-display: none;
  --rail-justify: center;
  --rail-brand-pad: 0 12px;
  --rail-item-gap: 0;
  --rail-item-pad: 10px 0;
  --rail-group-gap: 18px;
  --rail-group-pad: 14px;
  --rail-group-line: 1px solid var(--border);
  --rail-caret-rotate: 180deg;
}

/* 沒有選單資料的頁面（404：網址沒對上，current_user 這個 dependency 根本沒跑過，
   request.state.user 不存在，nav_groups 因此是空的）。側選單整個不畫，
   欄位也必須一起收掉：欄寬仍是 236px 的話，畫面左邊會留下一條高及頁底的空面板，
   看起來像壞掉而不是「找不到頁面」。品牌角改由內容撐寬，主內容與狀態列橫跨兩欄。 */
.shell--nonav {
  --side-w: auto;
  grid-template-areas:
    "brand  topbar"
    "main   main"
    "status status";
}

/* --------------------------------------------------------------------------
   跳過選單的捷徑
   -------------------------------------------------------------------------- */

/* 側選單有十個項目，鍵盤使用者每翻一頁都要先 Tab 過整排連結才碰得到內容。
   平常收在畫面外，一取得焦點就滑出來。 */
.skiplink {
  position: fixed;
  left: 12px;
  top: -64px;
  z-index: 100;
  padding: 9px 14px;
  font-size: 14.5px;
  font-weight: 600;
  color: #FFFFFF;
  background-color: var(--accent);
  border-radius: var(--radius-sm);
  text-decoration: none;
  transition: top 0.15s ease;
}

/* 用 :focus 而非 :focus-visible：這條連結只有鍵盤操作者碰得到，
   而部分瀏覽器在程式化聚焦時不會判定為 focus-visible。 */
.skiplink:focus {
  top: 12px;
}

/* --------------------------------------------------------------------------
   品牌角
   -------------------------------------------------------------------------- */

.shell__brand {
  display: flex;
  align-items: center;
  justify-content: var(--rail-justify);
  gap: 10px;
  min-width: 0;
  padding: var(--rail-brand-pad);
  color: var(--text);
  text-decoration: none;
  background-color: var(--surface);
  border-bottom: 1px solid var(--border);
  border-right: 1px solid var(--border);
}

/* 對焦環必須往內畫。品牌角就坐在 .shell padding box 的 (0,0)，
   全域 :focus-visible 的 outline-offset:2px 會把上緣與左緣那兩段畫到座標 −2～−4px，
   落在 .shell 的 overflow:hidden 之外，環會缺一角。
   同段其他控制項慣用的 box-shadow 光暈同樣往外擴 4px，一樣救不了，
   因此改用與 .usermenu__item:focus-visible 相同的內縮 outline。 */
.shell__brand:focus-visible {
  outline: 2px solid var(--accent-hover);
  outline-offset: -2px;
}

.shell__brand-mark {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  color: var(--accent-hover);
  background: var(--accent-soft);
  border: 1px solid var(--accent-soft-border);
  border-radius: 10px;
}

.shell__brand-mark svg {
  width: 19px;
  height: 19px;
}

.shell__brand-text {
  display: var(--rail-label-display);
  min-width: 0;
}

.shell__brand-name {
  display: block;
  font-size: 15.5px;
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: 0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 公司名稱。長度不可控（客戶自己取的名字），故截斷而不是把整條列撐開 */
.shell__brand-org {
  display: block;
  font-size: 12.5px;
  line-height: 1.35;
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* --------------------------------------------------------------------------
   頂部列
   -------------------------------------------------------------------------- */

/* position + z-index：使用者選單是絕對定位的浮層，要蓋在側選單與主內容之上。
   兩者在 DOM 裡都排在頂列後面，不建立堆疊脈絡的話浮層會被壓在底下。 */
.shell__topbar {
  position: relative;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 14px;
  min-width: 0;
  padding: 0 20px 0 22px;
  background-color: var(--surface);
  border-bottom: 1px solid var(--border);
}

.topbar__spacer {
  flex: 1 1 auto;
}

.topbar__tools {
  display: flex;
  align-items: center;
  gap: 2px;
}

.topbar__divider {
  width: 1px;
  height: 24px;
  margin: 0 8px;
  background: var(--border);
}

/* --- 全域搜尋 --- */

.gsearch {
  position: relative;
  flex: 1 1 auto;
  /* 搜尋框不吃滿整條列：超過這個寬度只是徒增游標移動距離 */
  max-width: 460px;
  min-width: 0;
}

.gsearch__icon {
  position: absolute;
  left: 12px;
  top: 50%;
  transform: translateY(-50%);
  display: block;
  width: 16px;
  height: 16px;
  color: var(--text-faint);
  /* 圖示落在輸入框範圍內，不攔截點擊 */
  pointer-events: none;
}

.gsearch__icon svg {
  width: 16px;
  height: 16px;
}

.gsearch__input {
  width: 100%;
  padding: 8px 12px 8px 36px;
  font: inherit;
  font-size: 14.5px;
  color: var(--text);
  background: var(--surface-input);
  border: 1px solid var(--border-input);
  border-radius: var(--radius-sm);
  -webkit-appearance: none;
  appearance: none;
  transition: border-color 0.15s ease, box-shadow 0.15s ease, background-color 0.15s ease;
}

.gsearch__input::placeholder {
  color: var(--text-faint);
}

.gsearch__input:hover {
  border-color: var(--border-input-hover);
}

/* 文字輸入框用 :focus 而非 :focus-visible：滑鼠點擊也該看得到焦點在哪 */
.gsearch__input:focus {
  background: var(--surface-input-focus);
  border-color: var(--accent);
  box-shadow: var(--ring);
  outline: 2px solid transparent;
  outline-offset: 2px;
}

/* 尚未接上搜尋後端。畫成可用的樣子（打了字、按了 Enter 卻什麼也沒發生）
   與放一個假數字是同一種謊，因此明確停用；placeholder 也寫明「尚未開放」。 */
.gsearch__input:disabled {
  color: var(--text-muted);
  background: transparent;
  border-style: dashed;
  cursor: not-allowed;
}

/* --- 圖示鈕 --- */

/* 無底無框，靠 hover 才浮出，避免頂部列變成一排按鈕牆 */
.iconbtn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  padding: 0;
  color: var(--text-muted);
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  transition: color 0.15s ease, background-color 0.15s ease;
}

.iconbtn:hover {
  color: var(--text);
  background: var(--surface-hover);
}

.iconbtn:focus-visible {
  outline: 2px solid transparent;
  box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--accent-hover);
}

/* 通知與說明都還沒有後端。停用狀態不必再加 hover，
   淡化到看得見但明顯按不動即可。 */
.iconbtn:disabled {
  color: var(--text-faint);
  background: transparent;
  cursor: not-allowed;
}

.iconbtn svg {
  width: 18px;
  height: 18px;
}

/* --- 使用者選單 --- */

.usermenu {
  position: relative;
  min-width: 0;
}

/* summary 掛的是 .userbtn（inline-flex），Chrome／Firefox 的三角形因此消失；
   Safari 另有一顆 ::-webkit-details-marker，必須單獨關掉。
   同 .disclosure__summary 的處理方式。 */
.userbtn {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  min-width: 0;
  padding: 5px 9px 5px 5px;
  font: inherit;
  color: var(--text);
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  list-style: none;
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease;
}

.userbtn::-webkit-details-marker {
  display: none;
}

.userbtn::marker {
  content: "";
}

.userbtn:hover {
  background: var(--surface-hover);
  border-color: var(--border);
}

.userbtn:focus-visible {
  outline: 2px solid transparent;
  box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--accent-hover);
}

/* 展開時維持按下的外觀，讓「浮層是從這顆按鈕長出來的」看得出來 */
.usermenu[open] > .userbtn {
  background: var(--surface-hover);
  border-color: var(--border);
}

.avatar {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  color: var(--accent-hover);
  background: var(--accent-soft);
  border: 1px solid var(--accent-soft-border);
  font-size: 14px;
  font-weight: 600;
  line-height: 1;
}

.userbtn__text {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  min-width: 0;
  text-align: left;
}

.userbtn__name {
  max-width: 16ch;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  font-size: 14px;
  font-weight: 600;
  line-height: 1.3;
}

.userbtn__role {
  font-size: 12px;
  line-height: 1.35;
  color: var(--text-muted);
  white-space: nowrap;
}

.userbtn__caret {
  flex: 0 0 auto;
  width: 14px;
  height: 14px;
  color: var(--text-faint);
  transition: transform 0.15s ease;
}

.usermenu[open] > .userbtn .userbtn__caret {
  transform: rotate(180deg);
}

.usermenu__panel {
  position: absolute;
  right: 0;
  top: calc(100% + 8px);
  z-index: 1;
  min-width: 224px;
  padding: 6px;
  background-color: var(--surface);
  /* 邊框比卡片亮一階：浮層下方就是同樣是 --surface 的頂列與側選單，
     用一般的 --border 會分不出邊界在哪 */
  border: 1px solid var(--border-input);
  border-radius: var(--radius);
  box-shadow: var(--shadow-card);
}

.usermenu__head {
  padding: 8px 10px 10px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 6px;
}

.usermenu__name {
  font-size: 14px;
  font-weight: 600;
  line-height: 1.45;
  overflow-wrap: anywhere;
}

/* email 沒有天然斷點，長網域必須強制斷行，否則會把浮層撐開 */
.usermenu__email {
  font-size: 13px;
  line-height: 1.45;
  color: var(--text-muted);
  overflow-wrap: anywhere;
}

.usermenu__item {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  padding: 8px 10px;
  font: inherit;
  font-size: 14px;
  color: var(--text);
  text-align: left;
  text-decoration: none;
  background: transparent;
  border: 0;
  border-radius: var(--radius-sm);
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  transition: color 0.15s ease, background-color 0.15s ease;
}

.usermenu__item:hover {
  background: var(--surface-hover);
}

.usermenu__item:focus-visible {
  outline: 2px solid var(--accent-hover);
  outline-offset: -2px;
}

.usermenu__icon {
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
  color: var(--text-muted);
}

/* 登出不是危險操作（不會失去任何資料），但它是這份選單裡唯一會改變登入狀態的項目，
   因此只在 hover 時才轉紅——平常保持中性，避免看起來像警告。 */
.usermenu__item--danger:hover {
  color: var(--danger-text);
}

.usermenu__item--danger:hover .usermenu__icon {
  color: var(--danger);
}

.usermenu__form {
  margin: 0;
}

/* --------------------------------------------------------------------------
   左側選單
   -------------------------------------------------------------------------- */

.shell__side {
  display: flex;
  flex-direction: column;
  min-height: 0;
  background-color: var(--surface);
  border-right: 1px solid var(--border);
}

/* 項目數超過矮視窗高度時，選單自己捲，不去推擠主內容區 */
.side__scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: 18px 12px 12px;
}

/* 分組是這一版最重要的一手：十個平鋪的項目要讀完才知道哪個是哪個，
   分成三組之後，第一次使用的人用掃的就能縮小到三選一。 */
.navgroup + .navgroup {
  margin-top: var(--rail-group-gap);
  padding-top: var(--rail-group-pad);
  border-top: var(--rail-group-line);
}

.navgroup__title {
  display: var(--rail-label-display);
  padding: 0 10px;
  margin-bottom: 7px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.09em;
  color: var(--text-muted);
}

.navgroup__list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.nav__item {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: var(--rail-justify);
  gap: var(--rail-item-gap);
  padding: var(--rail-item-pad);
  margin-bottom: 2px;
  font-size: 14.5px;
  line-height: 1.5;
  color: var(--text-muted);
  text-decoration: none;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  transition: color 0.15s ease, background-color 0.15s ease;
}

.nav__item:hover {
  color: var(--text);
  background: var(--surface-hover);
}

.nav__item:focus-visible {
  outline: 2px solid transparent;
  box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--accent-hover);
}

/* 選中狀態同時給三個訊號：藍字、藍底、左緣藍條。
   只靠底色的話，在深色底上與 hover 幾乎分不出來。 */
.nav__item--current {
  color: var(--accent-hover);
  background: var(--accent-soft);
  border-color: var(--accent-soft-border);
  font-weight: 600;
}

.nav__item--current:hover {
  color: var(--accent-hover);
  background: var(--accent-soft);
}

/* 圖示軌沒有左緣可以畫這道條（項目本身已置中），跟著標籤一起收起來 */
.nav__item--current::before {
  content: "";
  display: var(--rail-label-display);
  position: absolute;
  left: -12px;
  top: 50%;
  transform: translateY(-50%);
  width: 3px;
  height: 20px;
  background: var(--accent-hover);
  border-radius: 0 3px 3px 0;
}

.nav__icon {
  flex: 0 0 auto;
  width: 17px;
  height: 17px;
}

.nav__label {
  display: var(--rail-label-display);
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* 數字徽章。目前所有選單項的 badge 都是 None（待處理數還沒有資料來源），
   這組樣式是為了它接上時不必再回頭改版面。 */
.nav__badge {
  flex: 0 0 auto;
  min-width: 20px;
  padding: 1px 6px;
  font-size: 12px;
  font-weight: 600;
  line-height: 1.55;
  text-align: center;
  font-variant-numeric: tabular-nums;
  border-radius: 999px;
  color: var(--text-muted);
  background: var(--surface-input);
  border: 1px solid var(--border-input);
}

/* --- 收合選單 --- */

/* 這一格只為了裝收合鈕而存在。窄視窗下收合鈕不出現（版面本來就已經是圖示軌，
   按了沒有第二種狀態），整格要跟著消失，否則側選單底部會多出一條無主的分隔線。 */
.side__foot {
  display: var(--rail-collapse-display);
  flex: 0 0 auto;
  padding: 10px 12px 14px;
  border-top: 1px solid var(--border);
}

/* 同理：關掉 JS 時收合鈕帶著 hidden 不會畫出來，這條線也不該獨自留下。 */
.side__foot:has(.collapse[hidden]) {
  display: none;
}

.collapse {
  display: var(--rail-collapse-display);
  align-items: center;
  justify-content: var(--rail-justify);
  gap: 10px;
  width: 100%;
  padding: 8px 10px;
  font: inherit;
  font-size: 13.5px;
  color: var(--text-muted);
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  transition: color 0.15s ease, background-color 0.15s ease;
}

/* 這顆按鈕預設帶 hidden，由 JS 取消隱藏（沒有 JS 就記不住收合狀態，
   按了只會在下一次翻頁彈回來）。display 會蓋掉 hidden 的 UA 樣式，故明確補回。 */
.collapse[hidden] {
  display: none;
}

.collapse:hover {
  color: var(--text);
  background: var(--surface-hover);
}

.collapse:focus-visible {
  outline: 2px solid transparent;
  box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--accent-hover);
}

.collapse__icon {
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
  transform: rotate(var(--rail-caret-rotate));
}

.collapse__text {
  display: var(--rail-label-display);
}

/* --------------------------------------------------------------------------
   主內容區
   -------------------------------------------------------------------------- */

.shell__main {
  min-width: 0;
  overflow-y: auto;
  /* 必須是 positioned 元素：overflow 只裁切「containing block 在自己內部」的
     絕對定位子孫。少了這一行，主內容區裡的 .visually-hidden（position:absolute
     但沒有 top/left）會以初始 containing block 定位，靜態位置落在視窗高度以下時
     會把整份文件撐高，外層冒出第二條捲軸——一捲就把頂列、側選單與狀態列
     整個推出畫面，正好破壞上方「只有主內容區會捲」那條不變量。 */
  position: relative;
  background-color: var(--bg);
  /* 登入頁那道極淡的藍色光暈，換算到內容區的左上角。
     用 local 讓它跟著內容捲動：固定的光暈在長列表上會像是螢幕髒了。
     body 的兩道 fixed 光暈仍在，只是被外殼蓋住，登入頁不受影響。 */
  background-image: radial-gradient(1100px 420px at 26% -12%, rgba(59, 130, 246, 0.085), transparent 70%);
  background-repeat: no-repeat;
  background-attachment: local;
}

/* 主畫面滿版：主內容區有多寬就用多寬，列表、表格、表單與畫布自己撐開。
   先前 1180px 的版心在寬螢幕上會在側選單與內容之間留下一大塊空白。
   後台所有頁面都滿版（含新增／編輯表單與試問）；只剩錯誤頁用 main__inner--narrow
   維持閱讀寬度，margin: 0 auto 留著是為了讓它置中。 */
.main__inner {
  margin: 0 auto;
  padding: 30px var(--pad-x) 44px;
}

.main__inner--narrow {
  max-width: var(--form-max);
}

/* --- 外殼提供的頁首 --- */

.pagehead {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 18px;
  padding-bottom: 22px;
  margin-bottom: 24px;
  /* 頁首與內容之間一道實線：這一版的分區靠「界線」而不是只靠間距 */
  border-bottom: 1px solid var(--border);
}

.pagehead__text {
  min-width: 0;
}

.crumb {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 7px;
  font-size: 13px;
  color: var(--text-muted);
}

.crumb svg {
  width: 12px;
  height: 12px;
}

/* 字級階層刻意拉開：27px 對 15px 的說明、14.5px 的選單，
   一眼就知道「我在哪一頁」而不必逐字讀。 */
.pagehead__title {
  margin: 0;
  font-size: 27px;
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: 0.005em;
}

.pagehead__desc {
  margin-top: 7px;
  max-width: 62ch;
  font-size: 15px;
  line-height: 1.6;
  color: var(--text-muted);
}

.pagehead__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
}

/* --------------------------------------------------------------------------
   底部狀態列
   -------------------------------------------------------------------------- */

/* 低調的作法是「不給填色、字級小一階、只用一道上框線」，
   而不是把字調得更淡——最淡色在 13px 上達不到 WCAG AA。 */
.shell__status {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 18px;
  font-size: 13px;
  line-height: 1;
  color: var(--text-muted);
  background-color: var(--surface);
  border-top: 1px solid var(--border);
  overflow: hidden;
}

.status__spacer {
  flex: 1 1 auto;
}

.status__sep {
  flex: 0 0 auto;
  width: 1px;
  height: 14px;
  background: var(--border);
}

/* 環境標示是這條列上唯一需要「一眼認出」的東西：
   接到開發模式的機器而不自知，代價遠高於這一點視覺重量。 */
.status__env {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  flex: 0 0 auto;
  padding: 2px 8px;
  font-size: 12px;
  font-weight: 600;
  line-height: 1.6;
  color: var(--success-text);
  background: var(--success-bg);
  border: 1px solid var(--success-border);
  border-radius: 999px;
  white-space: nowrap;
}

/* 非正式環境（目前唯一能判斷的訊號是 settings.debug）。
   換的是顏色而不只是文字：文字要讀，顏色用掃的就看得到。 */
.status__env--alt {
  color: var(--accent-hover);
  background: var(--accent-soft);
  border-color: var(--accent-soft-border);
}

.status__dot {
  flex: 0 0 auto;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
}

.status__ver {
  flex: 0 0 auto;
  font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   響應式
   -------------------------------------------------------------------------- */

/* 選單自動收合成圖示軌。切換的仍然只有那組變數，樣式規則不重寫一次。 */
@media (max-width: 1080px) {
  .shell {
    --side-w: 68px;
    --pad-x: 24px;
    --rail-label-display: none;
    --rail-justify: center;
    --rail-brand-pad: 0 12px;
    --rail-item-gap: 0;
    --rail-item-pad: 10px 0;
    --rail-group-gap: 18px;
    --rail-group-pad: 14px;
    --rail-group-line: 1px solid var(--border);
    /* 這個寬度本來就放不下完整選單，收合鈕按了也沒有第二種狀態可切 */
    --rail-collapse-display: none;
  }
}

/* 側選單縮成圖示軌之後，表格的可用寬度變多，橫捲的門檻跟著下移，
   上面那條 1177px 的提示會在「其實還沒開始捲」的區間誤報。兩種圖示軌各一條例外：
   媒體查詢造成的（68 + 2×24 + 2）→ 視窗 ≥ 998 就還塞得下；
   使用者自行收合造成的（68 + 2×30 + 2，--pad-x 仍是 30）→ 視窗 ≥ 1010 還塞得下。
   提示寧可不出現，也不要在沒有捲動的地方說「可左右捲動」。 */
@media (min-width: 998px) and (max-width: 1080px) {
  .table-hint {
    display: none;
  }
}

@media (min-width: 1010px) {
  html.side-collapsed .table-hint {
    display: none;
  }
}

/* 圖示軌沒有空間放數字，改成右上角一個小點，仍保留「這裡有事」的訊號。
   兩個觸發條件（使用者收合、視窗過窄）在 CSS 裡無法用同一個選擇器表達，
   這條規則是本段唯一必須寫兩次的樣式。 */
html.side-collapsed .nav__badge {
  position: absolute;
  top: 4px;
  right: 12px;
  min-width: 8px;
  width: 8px;
  height: 8px;
  padding: 0;
  font-size: 0;
  border-radius: 50%;
  background: var(--accent);
  border-color: var(--surface);
}

@media (max-width: 1080px) {
  .nav__badge {
    position: absolute;
    top: 4px;
    right: 12px;
    min-width: 8px;
    width: 8px;
    height: 8px;
    padding: 0;
    font-size: 0;
    border-radius: 50%;
    background: var(--accent);
    border-color: var(--surface);
  }
}

@media (max-width: 980px) {
  /* 搜尋框與身分文字是輔助資訊，優先把寬度讓給品牌與動作 */
  .gsearch {
    display: none;
  }

  .userbtn__text {
    display: none;
  }

  .pagehead__title {
    font-size: 23px;
  }
}

@media (max-width: 720px) {
  .shell {
    --pad-x: 16px;
  }

  .main__inner {
    padding-top: 22px;
  }

  .shell__topbar {
    padding: 0 14px;
  }

  .pagehead {
    align-items: stretch;
  }

  .usermenu__panel {
    /* 窄螢幕的浮層貼齊右緣就好，再寬會頂出視窗 */
    min-width: 200px;
  }
}

/* ==========================================================================
   知識題組

   只新增這一節需要的規則，既有的 .panel / .data-table / .btn / .field / .badge
   一律沿用——同一種東西在不同頁面長得不一樣，使用者會以為那是不同的東西。
   ========================================================================== */

/* 頁首右側的動作按鈕群。既有的 .page-head（本檔前段）已是
   flex + wrap + space-between，這裡只補上它沒有的兩個子元素，
   不重新定義 .page-head 本身——那會連帶改動既有頁面的對齊方式。 */
.page-head__text {
  flex: 1 1 320px;
  min-width: 0;
}

.page-head__actions {
  display: flex;
  gap: 8px;
  /* 不換行，且不可被壓縮。
     允許換行時，容器寬度會被算成略小於按鈕總寬，於是最後一顆掉到第二行，
     再被 flex 的預設 stretch 拉成整行寬——看起來像一顆誤放的巨大主要動作。
     真的放不下時，整個按鈕群會由 .page-head 的 wrap 一起換到下一行，
     那才是預期中的窄螢幕行為。 */
  flex: 0 0 auto;
  flex-wrap: nowrap;
  /* 與標題的第一行對齊，而不是與整個文字區的中線對齊：
     說明文字有兩行時，置中會讓按鈕看起來往下掉。 */
  align-items: flex-start;
  padding-top: 2px;
}

/* 篩選列。搜尋是獨立的表單（要能按 Enter 送出），篩選是另一個，
   兩者並排在同一條工具列上。 */
.filterbar {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

/* 表格列內的動作按鈕若各自是一個 <form>，預設的區塊排版會讓它們換行。
   inline-form 只是讓表單本身不佔版面，按鈕才能與相鄰的連結排在同一行。 */
.inline-form {
  display: inline-flex;
  margin: 0;
}

.qa-table .cell-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.qa-table .cell-name {
  min-width: 220px;
}

/* 停用中的題目：整列降低對比，但不到看不清楚的程度——
   它仍然是要被閱讀與編輯的內容，只是需要一眼看出「這一列現在不生效」。 */
.data-table tr.is-disabled .cell-name .link,
.data-table tr.is-disabled td {
  color: var(--text-muted);
}

/* --- 答案訊息編輯器 ---------------------------------------------------- */

.msgs {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.msg {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-input-focus);
  padding: 14px 16px 4px;
}

.msg__head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
}

.msg__no {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-muted);
}

.msg__kind {
  font-size: 13px;
  color: var(--text-muted);
  border: 1px solid var(--border-input);
  border-radius: 999px;
  padding: 2px 10px;
}

.msg__spacer {
  flex: 1;
}

.msgs__add {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 12px;
}

/* 推薦問題的選項：兩個輸入框加一顆移除鈕。
   按鈕文字通常很短、送出的問題較長，因此寬度給 1:2。 */
.qr {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.qr__row {
  display: grid;
  grid-template-columns: 1fr 2fr auto;
  gap: 8px;
  align-items: center;
}

@media (max-width: 720px) {
  .qr__row {
    grid-template-columns: 1fr;
  }
}

/* --- 分類樹 ------------------------------------------------------------ */

.cattree,
.cattree__children {
  list-style: none;
  margin: 0;
  padding: 0;
}

.cattree__node + .cattree__node {
  border-top: 1px solid var(--border);
}

.cattree__row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 0;
}

.cattree__children {
  /* 靠縮排與一條線表達層級，而不是靠字級或顏色：
     層級是結構，用結構性的視覺表達才不會與「重要程度」混淆。 */
  margin-left: 14px;
  border-left: 1px solid var(--border);
  padding-left: 14px;
}

.cattree__name {
  font-weight: 500;
}

.cattree__children .cattree__name {
  font-weight: 400;
  color: var(--text-muted);
}

.cattree__count {
  font-size: 13px;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}

.cattree__spacer {
  flex: 1;
}

/* --- 試問結果 ---------------------------------------------------------- */

.hits {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  counter-reset: hit;
}

.hit {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-input-focus);
}

/* 分數的顏色對應「像不像」，與狀態徽章的成功／失敗語意無關，
   因此用左緣的色條而不是整塊底色——後者會讓人以為那是一種狀態。 */
.hit--high {
  border-left: 3px solid var(--success);
}

.hit--mid {
  border-left: 3px solid var(--accent);
}

.hit--low {
  border-left: 3px solid var(--border-input-hover);
}

.hit__score {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 62px;
}

.hit__value {
  font-size: 18px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.hit--high .hit__value {
  color: var(--success-text);
}

.hit__tier {
  font-size: 12px;
  color: var(--text-muted);
}

.hit__body {
  min-width: 0;
  flex: 1;
}

.hit__question {
  font-weight: 500;
}

.hit__meta {
  margin: 4px 0 0;
  font-size: 13px;
  color: var(--text-muted);
  /* 相似語句可能很長，允許換行而不是撐破卡片。 */
  overflow-wrap: anywhere;
}


.page-head__actions .btn {
  white-space: nowrap;
}

/* 欄位標籤與其右側的輔助動作（例如「用 AI 產生」）。
   標籤本身仍是 <label>，按鈕另外放——把按鈕包進 label 裡會讓
   點按鈕變成點標籤，焦點被送到輸入框而不是觸發動作。 */
.field__labelrow {
  display: flex;
  align-items: center;
  gap: 10px;
}

.field__labelrow .field__label {
  margin-right: auto;
}

/* 欄位下方的即時訊息（成功／失敗）。與 .field__hint 同一階，
   但顏色會隨狀態變，且平時是隱藏的。 */
.field__msg {
  margin: 0;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--success-text);
}

.field__msg--error {
  color: var(--danger-text);
}

/* ==========================================================================
   生成式知識

   只新增這一節需要的規則，既有的 .panel / .data-table / .btn / .field / .badge
   一律沿用——同一種東西在不同頁面長得不一樣，使用者會以為那是不同的東西。
   ========================================================================== */

/* 參考資料欄要放得下「標題 + 網址」兩行。
   .data-table .cell-name 只有 max-width: 26ch，沒有下限；這一頁的操作欄有五顆按鈕，
   把名稱欄擠到剩兩三個字寬，網址會變成一個字一行。實測過，所以給明確的下限。 */
.source-table .cell-name {
  min-width: 260px;
  max-width: 34ch;
}

.source-table .cell-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* 表格列內的第二行說明（網址、檔名、失敗原因）。
   比主要文字小一級並降低對比：它是辨識用的線索，不是要被閱讀的內容。 */
.cell-sub {
  margin: 3px 0 0;
  font-size: 13.5px;
  font-weight: 400;
  color: var(--text-muted);
  overflow-wrap: anywhere;
}

.cell-sub--danger {
  color: var(--danger-text);
}

/* 勾選框。整個 label 可點，而不是只有那個小方塊——
   小方塊在觸控裝置上是一個很難命中的目標。 */
.checkbox {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 14.5px;
  color: var(--text);
  cursor: pointer;
}

.checkbox input[type="checkbox"] {
  width: 15px;
  height: 15px;
  accent-color: var(--accent);
  cursor: pointer;
}

/* 兩個數字欄位並排（切段長度／重疊字數）。它們是一組設定，
   分成上下兩行會讓人以為是兩件不相干的事。 */
.field__row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

.field__inline {
  display: flex;
  flex-direction: column;
  gap: 5px;
  max-width: 10rem;
}

.field__sublabel {
  font-size: 13px;
  color: var(--text-muted);
}

/* 唯讀的「目前狀態」清單。用 dl 而不是表格：這是一組屬性，
   不是可排序、可比較的多列資料。 */
.meta-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 0;
}

.meta-list__row {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 16px;
  align-items: baseline;
}

.meta-list__key {
  flex: 0 0 8rem;
  font-size: 13.5px;
  color: var(--text-muted);
}

.meta-list__val {
  margin: 0;
  font-size: 14.5px;
  overflow-wrap: anywhere;
}

.meta-list__val--danger {
  color: var(--danger-text);
}

/* 週期學習欄：狀態文字 + 動作按鈕。
   兩者必須看得出誰是誰——只有一顆按鈕時，「開啟」既像狀態也像動作。 */
.cycle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  white-space: nowrap;
}

.cycle__state {
  font-size: 14px;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

/* 試問結果裡的片段全文。片段本來就是一整段文字，要能讀，
   所以不截斷、不省略——這一頁的用途就是看「到底撈到什麼」。 */
.chunk-text {
  margin: 6px 0 0;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background-color: var(--surface-hover);
  font-size: 14px;
  line-height: 1.75;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* ==========================================================================
   工作區頁首（_workspace.html）

   渠道是最上層：進了一個渠道（或共用知識庫）之後，上面一排是它的四個頁籤，
   底下一排是頁籤裡的子頁。舊的渠道膠囊列拿掉了——它把共用知識畫成第二個渠道。
   ========================================================================== */

.ws {
  margin-bottom: 18px;
  border-bottom: 1px solid var(--border);
}

.ws__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 12px;
  margin: 6px 0 12px;
}

.ws__text {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  min-width: 0;
}

.ws__title {
  font-size: 22px;
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: 0.01em;
}

.ws__kind {
  padding: 2px 9px;
  border: 1px solid var(--border-input);
  border-radius: 999px;
  font-size: 13px;
  color: var(--text-muted);
  white-space: nowrap;
}

.ws__note {
  flex-basis: 100%;
  font-size: 14px;
  color: var(--text-muted);
}

.ws__actions {
  flex-shrink: 0;
}

.ws-tabs {
  display: flex;
  gap: 4px;
  overflow-x: auto;
}

.ws-tabs__item {
  padding: 9px 14px;
  margin-bottom: -1px;
  border-bottom: 2px solid transparent;
  font-size: 14.5px;
  color: var(--text-muted);
  text-decoration: none;
  white-space: nowrap;
  transition: color 0.15s ease;
}

.ws-tabs__item:hover {
  color: var(--text);
}

.ws-tabs__item--current {
  color: var(--text);
  font-weight: 600;
  border-bottom-color: var(--accent);
}

/* 子頁籤沿用 .viewswitch 的分段控制；只補與主頁籤的間距。 */
.ws-subtabs {
  margin: 10px 0 12px;
}

/* 監管規則清單。每一類規則各有一句判斷依據，普通的 checkbox 排排站
   會讓說明文字擠在勾選框後面而讀不下去，因此每一項自成一列。 */
.rulelist {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: 10px 18px;
  margin: 4px 0 0;
  padding: 0;
  list-style: none;
}

.rulelist__item {
  padding: 8px 10px;
  border: 1px solid var(--border-input);
  border-radius: 8px;
  background-color: var(--surface);
}

.rulelist__hint {
  margin: 4px 0 0 23px;
  font-size: 13px;
  line-height: 1.55;
  color: var(--text-muted);
}

/* 恆開的那幾類。徽章而不是把整列變灰：變灰讀起來像「這條沒生效」，
   實際上它們是唯一保證會生效的。 */
.rulelist__lock {
  margin-left: 6px;
  padding: 1px 6px;
  border-radius: 999px;
  font-size: 12px;
  color: var(--text-muted);
  background-color: var(--surface-hover);
}

/* 決策路徑。每一關一列：名稱、通過與否、說明。
   用清單而不是表格：說明的長度差異很大，表格會被最長的那一列撐開。 */
.steps {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 10px 0 0;
  padding: 0;
  list-style: none;
  counter-reset: none;
}

.steps__item {
  display: grid;
  grid-template-columns: 7.5rem 1.5rem 1fr;
  align-items: baseline;
  gap: 8px;
  padding: 9px 12px;
  border: 1px solid var(--border-input);
  border-left-width: 3px;
  border-radius: 8px;
  background-color: var(--surface);
  font-size: 14px;
  line-height: 1.6;
}

/* 三態各有自己的左邊框顏色。「未執行」不可以畫成「未通過」——
   前者要去改設定，後者要去改門檻或知識，是兩件不同的事。 */
.steps__item--pass { border-left-color: var(--success); }
.steps__item--fail { border-left-color: var(--danger); }
.steps__item--skip { border-left-color: var(--border-input); }

.steps__name {
  color: var(--text-muted);
}

.steps__mark {
  text-align: center;
  font-weight: 600;
}

.steps__item--pass .steps__mark { color: var(--success); }
.steps__item--fail .steps__mark { color: var(--danger); }
.steps__item--skip .steps__mark { color: var(--text-muted); }

.steps__detail {
  color: var(--text);
}

.steps__score {
  margin-left: 8px;
  padding: 1px 7px;
  border-radius: 999px;
  font-size: 13px;
  color: var(--text-muted);
  background-color: var(--surface-hover);
  white-space: nowrap;
}

@media (max-width: 640px) {
  .steps__item {
    grid-template-columns: 1fr 1.5rem;
  }
  .steps__detail {
    grid-column: 1 / -1;
  }
}

/* --------------------------------------------------------------------------
   知識流程畫布
   左邊是分類面板，右邊是舞台。樹的座標由後端算好（app/services/flow.py），
   這裡只負責長相；平移／縮放是 .flow__world 上的一個 transform（knowledge-flow.js）。
   -------------------------------------------------------------------------- */

.flow {
  display: grid;
  grid-template-columns: 280px minmax(0, 1fr);
  gap: 16px;
  /* 佔滿視窗剩下的高度，但別短過 560px：太矮的畫布連兩層分支都放不下 */
  height: clamp(560px, calc(100dvh - 240px), 960px);
  margin-bottom: 18px;
}

/* --- 分類面板 --- */

.flow__cats {
  display: flex;
  flex-direction: column;
  min-height: 0;
  border: 1px solid var(--border-input);
  border-radius: var(--radius);
  background-color: var(--surface);
  overflow: hidden;
}

.cats__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 14px 14px 10px;
}

.cats__title {
  margin: 0;
  font-size: 15px;
  font-weight: 600;
}

.cats__search {
  padding: 0 14px 10px;
}

.cats__tree {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: 0 8px 10px;
}

.cats__empty,
.cats__note {
  margin: 0;
  padding: 10px 14px;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--text-muted);
}

.cats__note {
  border-top: 1px solid var(--border);
}

.cats__orphans {
  max-height: 40%;
  overflow-y: auto;
  padding: 10px 14px 12px;
  border-top: 1px solid var(--border);
}

.cats__subtitle {
  margin: 0 0 6px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-muted);
}

.orphans {
  list-style: none;
  margin: 0;
  padding: 0;
}

.orphans__row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 0;
  font-size: 13.5px;
}

.orphans__name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.orphans__kind {
  flex: 1;
  font-size: 13px;
  color: var(--text-muted);
}

/* 可點選版的分類樹：每一列是連結，目前看的那一列用主色標記 */
.cattree--nav .cattree__node + .cattree__node {
  border-top: 0;
}

.cattree--nav .cattree__children {
  margin-left: 10px;
  padding-left: 8px;
}

.cattree__link {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-left: 2px solid transparent;
  border-radius: var(--radius-sm);
  color: var(--text);
  text-decoration: none;
}

.cattree__link:hover {
  background-color: var(--surface-hover);
}

.cattree__link.is-current {
  background-color: var(--accent-soft);
  border-left-color: var(--accent);
}

.cattree__link .cattree__name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cattree--nav .cattree__children .cattree__name {
  color: var(--text);
}

/* --- 舞台 --- */

.flow__stage {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: 0;
  border: 1px solid var(--border-input);
  border-radius: var(--radius);
  background-color: var(--surface-sunken);
  /* 點狀格線：畫布要看得出「這是一塊可以拖的地方」，又不能搶節點的戲 */
  background-image: radial-gradient(circle, var(--border) 1px, transparent 1.3px);
  background-size: 22px 22px;
  overflow: hidden;
  contain: layout paint;
}

/* 工具列是舞台的第一列，不是浮在畫布上：浮著會蓋住第一排節點 */
.flow__topbar {
  position: relative;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
  padding: 12px 12px 10px;
}

.flow__search {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 0 1 640px;
  min-width: 0;
  padding: 6px 10px 6px 8px;
  border: 1px solid var(--border-input);
  border-radius: 999px;
  background-color: var(--surface);
}

.flow__search .search__box {
  flex: 1 1 200px;
  min-width: 120px;
}

.flow__search .field__input {
  padding-top: 6px;
  padding-bottom: 6px;
}

.flow__filter {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
  font-size: 13.5px;
  color: var(--text-muted);
}

.flow__viewport {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  /* clip 而不是 hidden：hidden 的容器仍可被程式捲動，聚焦節點時瀏覽器會把它捲進視野，
     scrollLeft/Top 一變，JS 記的平移量就跟畫面對不上 */
  overflow: clip;
  cursor: grab;
  touch-action: none;
  user-select: none;
}

.flow__viewport.is-dragging {
  cursor: grabbing;
}

.flow__world {
  position: absolute;
  left: 0;
  top: 0;
  transform-origin: 0 0;
  will-change: transform;
}

.flow__wires {
  position: absolute;
  left: 0;
  top: 0;
  overflow: visible;
  pointer-events: none;
}

.wire {
  fill: none;
  stroke-width: 1.4;
}

.wire--dashed {
  stroke: var(--border-input);
  stroke-dasharray: 4 4;
}

.wire--solid {
  stroke: var(--text-faint);
  marker-end: url(#flow-arrow);
}

#flow-arrow path {
  fill: var(--text-faint);
}

.flow__zoom {
  position: absolute;
  left: 12px;
  bottom: 12px;
  z-index: 3;
  display: flex;
  gap: 6px;
}

.zoombtn,
.framebtn {
  display: inline-grid;
  place-items: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 1px solid var(--border-input);
  border-radius: var(--radius-sm);
  background-color: var(--surface);
  color: var(--text-muted);
  cursor: pointer;
}

.zoombtn svg,
.framebtn svg {
  width: 16px;
  height: 16px;
}

.zoombtn:hover,
.framebtn:hover {
  color: var(--text);
  border-color: var(--border-input-hover);
  background-color: var(--surface-hover);
}

.flow__pager {
  position: absolute;
  right: 12px;
  bottom: 12px;
  z-index: 3;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 6px 12px;
  border: 1px solid var(--border-input);
  border-radius: 999px;
  background-color: var(--surface);
  font-size: 13.5px;
}

.flow__pager-text {
  color: var(--text-muted);
}

.flow__empty {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  padding: 24px;
  text-align: center;
  pointer-events: none;
}

.flow__empty a {
  pointer-events: auto;
}

.flow__empty-title {
  margin: 0 0 6px;
  font-size: 16px;
  font-weight: 600;
}

.flow__empty-text {
  margin: 0;
  max-width: 46ch;
  font-size: 14px;
  line-height: 1.6;
  color: var(--text-muted);
}

/* --- 節點（尺寸與 app/services/flow.py 的常數一致） --- */

.fnode {
  position: absolute;
  box-sizing: border-box;
  margin: 0;
  -webkit-appearance: none;
  appearance: none;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 12px;
  border: 1px solid var(--border-input);
  border-radius: 10px;
  background-color: var(--surface);
  color: var(--text);
  font: inherit;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  overflow: hidden;
}

.fnode:hover {
  border-color: var(--accent);
  background-color: var(--surface-hover);
}

.fnode:focus-visible,
.fnode--selected,
.fnode--focus {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.fnode__icon {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: 8px;
  color: var(--text-muted);
  background-color: var(--surface-hover);
}

.fnode__icon svg {
  width: 16px;
  height: 16px;
}

.fnode__text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.fnode__title {
  font-size: 14px;
  font-weight: 600;
  line-height: 1.3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.fnode__sub {
  font-size: 12.5px;
  line-height: 1.3;
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.fnode--category,
.fnode--category:hover {
  cursor: default;
  border-color: var(--accent-soft-border);
  background-color: var(--accent-soft);
}

.fnode--category .fnode__icon,
.fnode--question .fnode__icon {
  color: var(--accent);
  background-color: var(--accent-soft);
}

.fnode--item_answer .fnode__icon,
.fnode--answer .fnode__icon {
  color: var(--success);
  background-color: var(--success-bg);
}

/* 轉接代表「AI 放棄了」，那件事在圖上要一眼看得到 */
.fnode--transfer .fnode__icon {
  color: var(--danger);
  background-color: var(--danger-bg);
}

.fnode--trigger {
  border-radius: 999px;
  background-color: var(--surface-hover);
}

.fnode--trigger .fnode__title {
  font-weight: 500;
}

.fnode--ref {
  border-style: dashed;
}

.fnode--plus {
  justify-content: center;
  padding: 0;
  border-radius: 50%;
  border-style: dashed;
  color: var(--text-muted);
  background-color: transparent;
}

.fnode--plus svg {
  width: 14px;
  height: 14px;
}

.fnode--plus:hover {
  color: var(--accent);
  border-style: solid;
  background-color: var(--accent-soft);
}

.fnode--disabled,
.fnode--unindexed {
  opacity: 0.6;
}

.fnode--dimmed {
  opacity: 0.45;
}

.fnode--empty .fnode__title {
  font-weight: 400;
  color: var(--text-muted);
}

/* --- 基礎流程畫布（固定形狀的路由圖）：單欄、三種節點、線上有標籤 --- */

.flow--single {
  grid-template-columns: minmax(0, 1fr);
}

.flow__topbar--lead {
  justify-content: flex-start;
}

.flow__lead {
  margin: 0;
  padding: 6px 12px;
  border: 1px solid var(--border-input);
  border-radius: 999px;
  background-color: var(--surface);
  font-size: 13.5px;
  color: var(--text-muted);
}

.fnode--static,
.fnode--static:hover {
  cursor: default;
  border-color: var(--border-input);
  background-color: var(--surface);
}

.fnode--step .fnode__icon {
  color: var(--accent);
  background-color: var(--accent-soft);
}

.fnode--outcome .fnode__icon {
  color: var(--success);
  background-color: var(--success-bg);
}

.fnode--start .fnode__icon {
  color: var(--text);
  background-color: var(--surface-hover);
}

.fnode--link {
  border-style: dashed;
}

/* 標籤壓在線上：用 paint-order 先描一圈底色，字才不會被線切過 */
.wire__label {
  font-size: 11.5px;
  fill: var(--text-muted);
  paint-order: stroke;
  stroke: var(--surface-sunken);
  stroke-width: 4px;
  stroke-linejoin: round;
}

.wire--dimmed,
.wire__label--dimmed {
  opacity: 0.4;
}

/* --- 彈窗：原生 <dialog>，showModal() 提供焦點陷阱、Esc 與 ::backdrop --- */

.dialog {
  width: min(560px, calc(100vw - 32px));
  max-height: calc(100dvh - 48px);
  padding: 0;
  border: 1px solid var(--border-input);
  border-radius: var(--radius);
  background-color: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-card);
}

.dialog[open] {
  display: flex;
  flex-direction: column;
}

/* 新增分支的 <form> 包住整個彈窗內容，display: contents 讓頭／身／腳仍是 flex 的子項 */
.dialog > form {
  display: contents;
}

.dialog::backdrop {
  background-color: rgba(0, 0, 0, 0.55);
}

.dialog__head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--border);
}

.dialog__title {
  flex: 1;
  min-width: 0;
  margin: 0;
  font-size: 16px;
  font-weight: 600;
}

.dialog__body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  /* 捲到底不要把後面的主內容區一起捲走 */
  overscroll-behavior: contain;
  padding: 18px;
}

.dialog__lead {
  margin: 0 0 14px;
  color: var(--text-muted);
}

.dialog__loading {
  margin: 0;
  color: var(--text-muted);
}

.dialog__actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  padding: 12px 18px;
  border-top: 1px solid var(--border);
}

.dialog__row {
  display: flex;
  justify-content: flex-end;
  margin-top: 12px;
}

.dialog__danger {
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
}

/* 抽屜：貼右、滿高。UA 給 dialog 的 max-height 與 margin:auto 一定要蓋掉，否則不會貼邊 */
.dialog--drawer {
  position: fixed;
  inset: 0 0 0 auto;
  width: min(620px, 100vw);
  max-width: 100vw;
  height: 100dvh;
  max-height: 100dvh;
  margin: 0;
  border-radius: 0;
  border-width: 0 0 0 1px;
}

/* 這個外殼真正在捲的是 .shell__main，不是 html */
body:has(dialog[open]) .shell__main {
  overflow: hidden;
}

.step {
  display: flex;
  gap: 12px;
  margin-bottom: 18px;
}

.step__no {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background-color: var(--accent-soft);
  color: var(--accent);
  font-size: 12.5px;
  font-weight: 600;
}

.step__body {
  flex: 1;
  min-width: 0;
}

.step__body .field + .field {
  margin-top: 12px;
}

.kindpick {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
  margin-top: 6px;
}

.kindpick__item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px;
  border: 1px solid var(--border-input);
  border-radius: var(--radius-sm);
  cursor: pointer;
}

.kindpick__item:has(:checked) {
  border-color: var(--accent);
  background-color: var(--accent-soft);
}

.kindpick__item:has(:focus-visible) {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.kindpick__item input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.kindpick__icon {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: 8px;
  color: var(--accent);
  background-color: var(--accent-soft);
}

.kindpick__icon--danger {
  color: var(--danger);
  background-color: var(--danger-bg);
}

.kindpick__icon svg {
  width: 16px;
  height: 16px;
}

.kindpick__text {
  display: flex;
  flex-direction: column;
  min-width: 0;
  font-size: 13.5px;
  line-height: 1.3;
}

.kindpick__text small {
  font-size: 12px;
  color: var(--text-muted);
}

.branch-kind {
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

/* 沒選中的那組欄位：disabled 的 fieldset 不驗證、不送出，這裡再讓它不顯示 */
.branch-kind:disabled {
  display: none;
}

.field__input--short {
  max-width: 160px;
}

.form-actions__aside {
  margin-right: auto;
  font-size: 13.5px;
}

/* ── 分析報表 ───────────────────────────────────────────────── */

/* 篩選列。每一組是「標籤＋一排可點的值」，值本身是連結而不是 <select>——
   這一頁的每個組合都值得能被貼給同事，而 select 的狀態進不了網址列。 */
.filterbar__group {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}

.filterbar__group + .filterbar__group {
  margin-left: 18px;
}

.filterbar__label {
  color: var(--text-muted);
  font-size: 13px;
  margin-right: 2px;
}

.chip {
  display: inline-flex;
  align-items: center;
  padding: 5px 11px;
  border: 1px solid var(--border-input);
  border-radius: 999px;
  color: var(--text-muted);
  font-size: 13.5px;
  text-decoration: none;
  white-space: nowrap;
  transition: border-color 0.12s, color 0.12s, background-color 0.12s;
}

.chip:hover {
  border-color: var(--border-input-hover);
  color: var(--text);
}

/* 選中的那一顆用邊框與底色一起標，不只靠顏色——色覺不同的人只看得到
   「有一顆比較亮」時，分不出是選中還是 hover。 */
.chip--on {
  border-color: var(--accent-soft-border);
  background: var(--accent-soft);
  color: var(--text);
}

/* 概況的四個數字。命中率是主角，格子給它多一點份量。 */
.statgrid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: 14px;
  margin: 0;
}

.statgrid__cell {
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-sunken);
}

.statgrid__cell--hero {
  border-color: var(--accent-soft-border);
  background: var(--accent-soft);
}

.statgrid__key {
  color: var(--text-muted);
  font-size: 13px;
}

.statgrid__val {
  margin: 4px 0 0;
  font-size: 28px;
  font-weight: 600;
  line-height: 1.15;
  /* 等寬數字：切換篩選時數字不會左右跳動。 */
  font-variant-numeric: tabular-nums;
}

.statgrid__unit {
  font-size: 15px;
  font-weight: 400;
  color: var(--text-muted);
  margin-left: 2px;
}

.statgrid__sub {
  margin: 3px 0 0;
  color: var(--text-muted);
  font-size: 12.5px;
}

.report-table .cell-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.report-table .cell-bar {
  width: 42%;
  min-width: 120px;
}

/* 比例長條。一條 div 就能表達的東西不值得引進一個圖表函式庫；
   寬度用 inline style 設（同 flow.html 與 base_flow.html 的畫布座標）。
   aria-hidden：旁邊那一欄的百分比數字才是給螢幕閱讀器讀的內容。 */
.ratiobar {
  display: block;
  height: 8px;
  border-radius: 999px;
  background: var(--surface-input);
  overflow: hidden;
}

.ratiobar__fill {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--accent);
  /* 佔比極小時仍要看得見一點顏色，否則「有 1 次」與「0 次」長得一樣。 */
  min-width: 2px;
}

@media (max-width: 960px) {
  .flow {
    grid-template-columns: minmax(0, 1fr);
    height: auto;
  }
  .flow__cats {
    max-height: 260px;
  }
  /* 容器高度是 auto 時百分比 max-height 失效，孤兒一多會把分類樹擠到 0 */
  .cats__orphans {
    max-height: 120px;
  }
  .flow__stage {
    height: 560px;
  }
  .dialog--drawer {
    width: 100vw;
  }
  .kindpick {
    grid-template-columns: 1fr;
  }
}
