/* ============================================================
   2FA_Hub_Online / static/app/style.css
   行動優先的深色介面。原型階段以「清楚、好點」為主，精緻打磨留後。
   ============================================================ */

/* ============================================================
   🎨 顯示色調（移植自 LinkHub 的 data-tone 機制）
   切 <html data-theme="…"> 一個屬性，整組 CSS 變數換掉，全站跟著變。
   屬性選擇器特異度(0,1,1) > :root(0,1,0)，所以手動選的色調一定蓋得過預設。
   ⚠️ 新增色調時三件事要一起做：這裡加一組變數、main.js 的 THEMES 加一筆、
      色票要連 --topbar-bg / --toast-bg / --accent-glow 一起給（那三個原本是寫死的顏色）。
   ============================================================ */
:root, :root[data-theme="slate"] {          /* 石板深藍（本專案原本的樣子，預設） */
  color-scheme: dark;
  --bg: #0f172a; --surface: #1e293b; --surface2: #172033; --border: #334155;
  --ink: #e2e8f0; --muted: #94a3b8; --faint: #64748b;
  --accent: #38bdf8; --accent-ink: #082f49;
  --good: #22c55e; --warn: #f59e0b; --bad: #ef4444;
  --topbar-bg: rgba(15,23,42,.92); --toast-bg: #0b1220;
  --accent-glow: rgba(56,189,248,.4); --accent-tint: rgba(56,189,248,.4);
  --radius: 14px;
}
:root[data-theme="paper"] {                 /* 紙感暖陽 */
  color-scheme: light;
  --bg: #f4f1ea; --surface: #fffdf7; --surface2: #f0ebe0; --border: #e6ded0;
  --ink: #2f2a24; --muted: #8a8175; --faint: #a89c8a;
  --accent: #e07a4f; --accent-ink: #ffffff;
  --good: #3f8f6a; --warn: #c98a2e; --bad: #d5573b;
  --topbar-bg: rgba(255,253,247,.92); --toast-bg: #fffdf7;
  --accent-glow: rgba(224,122,79,.35); --accent-tint: rgba(224,122,79,.45);
  --radius: 14px;
}
:root[data-theme="sepia"] {                 /* 羊皮紙 */
  color-scheme: light;
  --bg: #f2e8d5; --surface: #faf3e4; --surface2: #f0e6d0; --border: #e0d2b8;
  --ink: #3a2f22; --muted: #8f7f66; --faint: #ab9a80;
  --accent: #c2703c; --accent-ink: #ffffff;
  --good: #6b8f5e; --warn: #b8862f; --bad: #b8452f;
  --topbar-bg: rgba(250,243,228,.92); --toast-bg: #faf3e4;
  --accent-glow: rgba(194,112,60,.35); --accent-tint: rgba(194,112,60,.45);
  --radius: 14px;
}
:root[data-theme="green"] {                 /* 森林綠 */
  color-scheme: light;
  --bg: #e3ede0; --surface: #eef5ec; --surface2: #e7f0e4; --border: #cdddc8;
  --ink: #2a332a; --muted: #7c8f7a; --faint: #9aab97;
  --accent: #3f8f6a; --accent-ink: #ffffff;
  --good: #3f8f6a; --warn: #b5892c; --bad: #c0523a;
  --topbar-bg: rgba(238,245,236,.92); --toast-bg: #eef5ec;
  --accent-glow: rgba(63,143,106,.32); --accent-tint: rgba(63,143,106,.45);
  --radius: 14px;
}
:root[data-theme="blue"] {                  /* 海洋藍 */
  color-scheme: light;
  --bg: #e6eef3; --surface: #f1f6f9; --surface2: #e9f1f5; --border: #cddce4;
  --ink: #26313a; --muted: #7c8992; --faint: #98a5ad;
  --accent: #3a7ca5; --accent-ink: #ffffff;
  --good: #3d8f6a; --warn: #b5862c; --bad: #c25242;
  --topbar-bg: rgba(241,246,249,.92); --toast-bg: #f1f6f9;
  --accent-glow: rgba(58,124,165,.32); --accent-tint: rgba(58,124,165,.45);
  --radius: 14px;
}
:root[data-theme="night"] {                 /* 夜間深色（暖調） */
  color-scheme: dark;
  --bg: #1c1a17; --surface: #26231e; --surface2: #211e1a; --border: #3a352d;
  --ink: #ece5d8; --muted: #9c9384; --faint: #7a7264;
  --accent: #e08a5f; --accent-ink: #241a12;
  --good: #6fbfab; --warn: #e0a94f; --bad: #ef6d54;
  --topbar-bg: rgba(28,26,23,.92); --toast-bg: #14120f;
  --accent-glow: rgba(224,138,95,.35); --accent-tint: rgba(224,138,95,.45);
  --radius: 14px;
}
* { box-sizing: border-box; }
html { scrollbar-gutter: stable; }
body {
  margin: 0; min-height: 100vh; background: var(--bg); color: var(--ink);
  font-family: "Microsoft JhengHei", system-ui, -apple-system, sans-serif; font-size: 15px; line-height: 1.5;
}
button { font-family: inherit; cursor: pointer; }
input, textarea, select, button { font-size: 15px; }
.hidden { display: none !important; }
.spinner { width: 18px; height: 18px; border: 2px solid var(--border); border-top-color: var(--accent);
  border-radius: 50%; animation: spin .8s linear infinite; display: inline-block; vertical-align: middle; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------- 登入 / 創世 ---------- */
.auth-wrap { min-height: 100vh; display: grid; place-items: center; padding: 24px; }
.auth-card { width: 100%; max-width: 440px; background: var(--surface); border: 1px solid var(--border);
  border-radius: 18px; padding: 30px 26px; box-shadow: 0 16px 48px rgba(0,0,0,.45); }
.auth-card h1 { margin: 0 0 4px; font-size: 24px; }
.auth-card .sub { color: var(--muted); margin: 0 0 22px; font-size: 14px; }
.field { margin-bottom: 14px; }
.field label { display: block; font-size: 13px; color: var(--muted); margin-bottom: 6px; }
.field .with-eye { position: relative; }
.field input, .field textarea, .field select {
  width: 100%; padding: 11px 12px; background: var(--surface2); border: 1px solid var(--border);
  border-radius: 10px; color: var(--ink); outline: none; }
.field input:focus, .field textarea:focus, .field select:focus { border-color: var(--accent); }
.with-eye input { padding-right: 42px; }
/* 自訂密碼產生器面板 */
.pwgen { margin-top: 10px; padding: 12px; border: 1px solid var(--border); border-radius: 10px; background: var(--surface2); display: flex; flex-direction: column; gap: 8px; }
.pwgen-row { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
.pwgen-opts { gap: 8px 14px; }
.pwgen-lbl { color: var(--muted); font-size: 13px; }
.pwgen-hint { color: var(--muted); font-size: 12px; }
/* 面板在密碼欄 .field 內，會吃到 .field input{width:100%}；用更高特異度把長度框收窄。 */
.pwgen .pwgen-len { width: 88px; }
.pwgen-chk { display: inline-flex; align-items: center; gap: 5px; font-size: 13.5px; color: var(--ink); cursor: pointer; }
.pwgen-chk input { width: auto; }
.pwgen-out { width: 100%; box-sizing: border-box; padding: 10px 12px; background: var(--surface); border: 1px solid var(--border); border-radius: 8px; color: var(--ink); outline: none; font-family: Consolas, ui-monospace, monospace; font-size: 15px; letter-spacing: 1px; }
.pwgen-len:focus, .pwgen-out:focus { border-color: var(--accent); }
.pwgen-strength { font-size: 12.5px; color: var(--muted); }
.pwgen-toggle.on { border-color: var(--accent); color: var(--accent); }
/* 套用產生的密碼後，密碼欄邊框綠色閃一下（1 秒） */
@keyframes pwFlashGreen {
  0%, 70% { border-color: var(--good); box-shadow: 0 0 0 3px rgba(34, 197, 94, .4); }
  100% { border-color: var(--border); box-shadow: 0 0 0 0 rgba(34, 197, 94, 0); }
}
.field input.flash-green { animation: pwFlashGreen 1s ease-out; }
.eye-btn { position: absolute; right: 4px; top: 50%; transform: translateY(-50%); background: none;
  border: none; font-size: 18px; padding: 6px 8px; opacity: .8; }
.eye-btn:hover { opacity: 1; }
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; width: 100%;
  padding: 12px 14px; border: none; border-radius: 10px; background: var(--accent); color: var(--accent-ink);
  font-weight: 700; }
.btn:disabled { opacity: .55; cursor: default; }
.btn.secondary { background: var(--surface2); color: var(--ink); border: 1px solid var(--border); font-weight: 600; }
.btn.ghost { background: none; color: var(--muted); border: 1px solid var(--border); font-weight: 600; }
.btn.danger { background: var(--bad); color: #fff; }
.btn.small { width: auto; padding: 7px 12px; font-size: 13.5px; }
.msg { margin-top: 12px; padding: 10px 12px; border-radius: 10px; font-size: 13.5px; display: none; }
.msg.show { display: block; }
.msg.err { background: rgba(239,68,68,.12); border: 1px solid rgba(239,68,68,.4); color: var(--bad); }
.msg.ok { background: rgba(34,197,94,.12); border: 1px solid rgba(34,197,94,.4); color: var(--good); }
.msg.info { background: rgba(56,189,248,.1); border: 1px solid rgba(56,189,248,.35); color: var(--accent); }
.hint { font-size: 12px; color: var(--faint); margin-top: 8px; line-height: 1.6; }

/* ---------- 主框架 ---------- */
.topbar { position: sticky; top: 0; z-index: 20; display: flex; align-items: center; gap: 10px;
  padding: 12px 16px; background: var(--topbar-bg); backdrop-filter: blur(8px); border-bottom: 1px solid var(--border); }
.topbar .brand { font-weight: 800; font-size: 17px; white-space: nowrap; }
.topbar .who { color: var(--muted); font-size: 12.5px; margin-left: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.topbar .spacer { flex: 1; }
.icon-btn { background: var(--surface2); border: 1px solid var(--border); color: var(--ink); border-radius: 10px;
  padding: 8px 10px; font-size: 15px; line-height: 1; }
.icon-btn:hover { border-color: var(--accent); }
.container { max-width: 820px; margin: 0 auto; padding: 16px; }
.searchbar { display: flex; gap: 8px; margin-bottom: 14px; }
.searchbar input { flex: 1; padding: 11px 12px; background: var(--surface); border: 1px solid var(--border);
  border-radius: 10px; color: var(--ink); outline: none; }
.searchbar input:focus { border-color: var(--accent); }

/* ---------- 清單卡片 ---------- */
.count { color: var(--faint); font-size: 12.5px; margin: 2px 2px 12px; }
/* color 一定要在這裡明寫成 var(--ink)：CSS 的 color 是以「計算後的值」往下繼承的，
   卡片自訂底色時我們是在卡片自己身上覆寫 --ink，若這裡不重新宣告一次，
   .title 這種沒有自己 color 宣告的元素會繼續沿用 body 早就算好的舊顏色（深底配深字 → 看不見）。*/
.card-item { background: var(--surface); color: var(--ink); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 13px 14px; margin-bottom: 10px; }
.card-item .row1 { display: flex; align-items: center; gap: 8px; }
.card-item .title { font-weight: 700; font-size: 15.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.badge { font-size: 11.5px; padding: 2px 8px; border-radius: 999px; background: var(--surface2);
  border: 1px solid var(--border); color: var(--muted); white-space: nowrap; }
.badge.used { color: var(--warn); border-color: rgba(245,158,11,.4); }
.badge.method { color: var(--accent); border-color: var(--accent-tint); }
.badge.suspended { color: var(--faint); border-color: var(--border); }
.card-item.suspended { opacity: .55; }
/* 密碼老化徽章 */
.badge.age.age-fresh { color: var(--muted); }
.badge.age.age-mid { color: var(--warn); border-color: rgba(245,158,11,.4); }
.badge.age.age-old { color: var(--bad); border-color: rgba(239,68,68,.45); }
.badge.age.age-unknown { color: var(--faint); }
/* 摺疊：每張卡片左上的 +/- 鈕 */
.collapse-btn { flex: none; width: 22px; height: 22px; line-height: 1; padding: 0; border-radius: 6px;
  background: var(--surface2); border: 1px solid var(--border); color: var(--muted); font-size: 15px; }
.collapse-btn:hover { border-color: var(--accent); color: var(--accent); }
.card-item.collapsed { padding-top: 11px; padding-bottom: 11px; }
/* 計數列 + 全部收合/展開 */
.count-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin: 2px 2px 12px; flex-wrap: wrap; }
.count-row .count { margin: 0; }
.count-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
/* 卡片左側的資料庫流水編號 */
.row-id { flex: none; font-size: 11.5px; color: var(--faint); font-variant-numeric: tabular-nums; min-width: 24px; }
/* 頂列文字按鈕（封存區／垃圾桶） */
.icon-btn.text-btn { padding: 8px 12px; font-size: 13.5px; white-space: nowrap; }
.icon-btn.text-btn.on { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
/* 封存區卡片的「恢復」鈕 */
.chip.restore { color: var(--good); border-color: rgba(34,197,94,.45); }
.chip.danger { color: var(--bad); border-color: rgba(239,68,68,.45); }
/* 編輯視窗裡「恢復至正常清單」的綠色系（比照卡片綠色 chip.restore） */
.btn.restore-green { background: var(--surface2); color: var(--good); border: 1px solid rgba(34,197,94,.45); font-weight: 600; }
.btn.restore-green:hover { border-color: var(--good); }
/* 編輯視窗裡「刪除」改外框紅字黑底（比照卡片 chip.danger，不再是實心紅） */
.btn.danger-outline { background: var(--surface2); color: var(--bad); border: 1px solid rgba(239,68,68,.45); font-weight: 600; }
.btn.danger-outline:hover { border-color: var(--bad); }
/* 卡片上的即時 2FA：動態碼＋倒數＋進度條；連點兩下複製 */
.card-totp { display: flex; align-items: center; gap: 10px; margin: 8px 0 2px; padding: 5px 8px;
  background: var(--surface2); border: 1px solid var(--border); border-radius: 9px;
  font-variant-numeric: tabular-nums; cursor: pointer; user-select: none; width: fit-content; max-width: 100%;
  height: 34px; box-sizing: border-box; }
/* 沒有 2FA 的卡片：保留同高度的空位，維持每張卡片高度一致 */
.card-totp-placeholder { height: 34px; margin: 8px 0 2px; }
/* 時間校對橫幅 */
.time-banner { margin: 0 0 12px; padding: 10px 14px; border-radius: 10px; font-size: 13.5px; line-height: 1.5; }
.time-banner.bad { background: rgba(239,68,68,.12); border: 1px solid rgba(239,68,68,.4); color: var(--bad); }
.time-banner.warn { background: rgba(245,158,11,.12); border: 1px solid rgba(245,158,11,.4); color: var(--warn); }
.card-totp:hover { border-color: var(--accent); }
.card-totp .ct-lbl { color: var(--muted); font-size: 12.5px; flex: none; }
.card-totp .ct-code { font-size: 18px; letter-spacing: 3px; color: var(--ink); font-weight: 700; }
.card-totp:hover .ct-code { color: var(--accent); }
.card-totp .ct-eye { background: none; border: none; cursor: pointer; font-size: 13px; line-height: 1; padding: 0 2px; flex: none; opacity: .75; }
.card-totp .ct-eye:hover { opacity: 1; }
.card-totp .ct-left { color: var(--muted); font-size: 12px; flex: none; }
.card-totp .ct-barwrap { width: 60px; height: 3px; background: var(--bg); border-radius: 2px; overflow: hidden; flex: none; }
.card-totp .ct-bar { height: 100%; background: var(--accent); transition: width .9s linear; }
/* 翻頁列 */
.pager { display: flex; align-items: center; justify-content: center; gap: 6px; flex-wrap: wrap; margin: 16px 0 6px; }
.pager .pager-mid { color: var(--muted); font-size: 13px; display: inline-flex; align-items: center; gap: 4px; }
.pager input { width: 54px; text-align: center; padding: 6px 4px; background: var(--surface);
  border: 1px solid var(--border); border-radius: 8px; color: var(--ink); outline: none; }
.pager input:focus { border-color: var(--accent); }
.card-item .sub { color: var(--muted); font-size: 13px; margin-top: 3px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.card-item .actions { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 11px; }
.chip { display: inline-flex; align-items: center; gap: 5px; background: var(--surface2); border: 1px solid var(--border);
  color: var(--ink); border-radius: 9px; padding: 6px 10px; font-size: 12.5px; }
.chip:hover { border-color: var(--accent); }
.chip.pin.on { color: var(--warn); border-color: rgba(245,158,11,.4); }
.empty { text-align: center; color: var(--faint); padding: 60px 20px; }
.fab { position: fixed; right: 18px; bottom: 20px; width: 56px; height: 56px; border-radius: 50%;
  background: var(--accent); color: var(--accent-ink); border: none; font-size: 28px; font-weight: 700;
  box-shadow: 0 8px 24px var(--accent-glow); z-index: 30; }

/* ---------- 抽屜 / 對話框 ---------- */
.overlay { position: fixed; inset: 0; background: rgba(0,0,0,.55); z-index: 40; display: none; }
.overlay.show { display: block; }
.sheet { position: fixed; z-index: 41; left: 0; right: 0; bottom: 0; max-height: 92vh; overflow-y: auto;
  background: var(--surface); border-top-left-radius: 20px; border-top-right-radius: 20px;
  border-top: 1px solid var(--border); padding: 18px 18px calc(18px + env(safe-area-inset-bottom)); }
@media (min-width: 640px) {
  .sheet { left: 50%; right: auto; bottom: auto; top: 50%; transform: translate(-50%,-50%);
    width: 560px; max-height: 88vh; border-radius: 18px; border: 1px solid var(--border); }
}
.sheet h2 { margin: 2px 0 16px; font-size: 19px; }
.sheet .grip { width: 40px; height: 4px; border-radius: 2px; background: var(--border); margin: 0 auto 14px; }
.section-label { font-size: 12px; color: var(--faint); text-transform: none; margin: 18px 2px 8px;
  border-top: 1px dashed var(--border); padding-top: 14px; }
.section-label:first-of-type { border-top: none; padding-top: 0; }
.inline-row { display: flex; gap: 8px; }
.inline-row .field { flex: 1; }
.custom-row { display: flex; gap: 8px; align-items: flex-end; margin-bottom: 10px; }
.custom-row .field { margin-bottom: 0; }
.custom-row .del-x { flex: none; }
.sheet-actions { display: flex; gap: 10px; margin-top: 22px; }
.sheet-actions .btn { flex: 1; }
.copy-toast { position: fixed; left: 50%; bottom: 90px; transform: translateX(-50%); z-index: 60;
  background: var(--toast-bg); border: 1px solid var(--border); color: var(--ink); padding: 10px 16px;
  border-radius: 999px; font-size: 13px; box-shadow: 0 8px 24px rgba(0,0,0,.5); opacity: 0;
  transition: opacity .18s; pointer-events: none; }
.copy-toast.show { opacity: 1; }

/* 唯讀檢視列 */
.view-row { display: flex; align-items: center; gap: 8px; padding: 10px 0; border-bottom: 1px solid var(--surface2); }
.view-row:last-child { border-bottom: none; }
.view-row .k { color: var(--muted); font-size: 12.5px; width: 92px; flex: none; }
.view-row .v { flex: 1; word-break: break-all; }
.view-row .v.mask { letter-spacing: 2px; }
.view-row .mini { background: none; border: none; color: var(--muted); font-size: 16px; padding: 4px 6px; }
.view-row .mini:hover { color: var(--accent); }

/* ============================================================
   👑 管理員專區（分頁籤／設定列／稽核）
   ============================================================ */
.adm-tabs { display: flex; gap: 6px; flex-wrap: nowrap; overflow-x: auto; padding-bottom: 4px; margin-bottom: 12px; }
.adm-tab { flex: none; padding: 8px 14px; background: var(--surface); color: var(--muted);
  border: 1px solid var(--border); border-radius: 999px; font-size: 14px; white-space: nowrap; }
.adm-tab:hover { border-color: var(--accent); color: var(--ink); }
.adm-tab.on { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); font-weight: 700; }
.adm-hint { margin: 0 2px 12px; line-height: 1.6; }
.adm-body { margin-top: 4px; }
.adm-selfnote { color: var(--faint); font-size: 13px; }
.adm-code { font-family: Consolas, ui-monospace, monospace; letter-spacing: 1px; }
/* 設定列（左說明右控制項；改了自動存） */
.setting-row { display: flex; gap: 14px; align-items: center; justify-content: space-between;
  padding: 12px 14px; margin-bottom: 8px; background: var(--surface); border: 1px solid var(--border); border-radius: 10px; }
.setting-row .sr-main { flex: 1; min-width: 0; }
.setting-row .sr-name { font-size: 14.5px; color: var(--ink); }
.setting-row .sr-desc { font-size: 12.5px; color: var(--muted); margin-top: 3px; line-height: 1.5; }
.setting-row .sr-ctrl { flex: none; }
.setting-row input[type="checkbox"] { width: 20px; height: 20px; }
.adm-num { width: 110px; padding: 8px 10px; background: var(--surface2); border: 1px solid var(--border);
  border-radius: 8px; color: var(--ink); outline: none; }
.adm-text { padding: 8px 10px; background: var(--surface2); border: 1px solid var(--border);
  border-radius: 8px; color: var(--ink); outline: none; }
.adm-sel { padding: 8px 10px; background: var(--surface2); border: 1px solid var(--border);
  border-radius: 8px; color: var(--ink); outline: none; }
.adm-num:focus, .adm-text:focus, .adm-sel:focus { border-color: var(--accent); }
.setting-row input:disabled, .adm-num:disabled, .adm-text:disabled { opacity: .55; cursor: not-allowed; }
/* 稽核日誌 */
.adm-filter { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-bottom: 10px; }
.adm-filter .adm-text { flex: 1; min-width: 160px; }
.audit-row .sub { font-size: 12.5px; }
.audit-row.bad { border-color: rgba(239, 68, 68, .5); background: rgba(239, 68, 68, .08); }
.audit-row.bad .title { color: var(--bad); }
/* 登入/註冊畫面底部的切換連結 */
.auth-alt { display: flex; align-items: center; justify-content: center; gap: 8px; flex-wrap: wrap;
  margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--border); }
.auth-alt-t { color: var(--muted); font-size: 13px; }
.linkish { background: none; border: none; color: var(--accent); font-size: 13.5px; font-weight: 700;
  padding: 4px 6px; border-radius: 6px; }
.linkish:hover { text-decoration: underline; background: var(--surface2); }

/* ============================================================
   🔐 兩步驟驗證面板
   ============================================================ */
.tfa-step { font-size: 14.5px; color: var(--ink); margin: 10px 2px 6px; line-height: 1.6; }
.tfa-block { margin: 10px 0 4px; padding: 12px; background: var(--surface2); border: 1px solid var(--border); border-radius: 10px; }
.tfa-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.tfa-row .adm-text { flex: 1; min-width: 150px; }
.tfa-code { font-family: Consolas, ui-monospace, monospace; letter-spacing: 2px; font-size: 16px; }
.tfa-secret { font-family: Consolas, ui-monospace, monospace; letter-spacing: 1px; font-size: 14px; }
/* QR：白底才掃得到（深色背景的 QR 很多 App 讀不出來） */
.tfa-qr { display: flex; justify-content: center; margin: 10px 0; }
.tfa-qr img { background: #fff; padding: 10px; border-radius: 10px; max-width: 100%; height: auto; }
/* 備用碼 */
.tfa-codes { display: grid; grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap: 8px; margin: 10px 0; }
.tfa-code-item { padding: 8px 10px; background: var(--surface2); border: 1px solid var(--border); border-radius: 8px;
  font-family: Consolas, ui-monospace, monospace; font-size: 14.5px; letter-spacing: 1px; text-align: center; user-select: all; }
.tfa-ack { display: flex; align-items: center; gap: 8px; margin: 12px 2px 0; font-size: 13.5px; color: var(--ink); cursor: pointer; }
.tfa-ack input { width: 18px; height: 18px; }
.tfa-low { color: var(--bad); }
/* 解除綁定的危險區 */
.tfa-danger { margin-top: 18px; padding: 12px; border: 1px solid rgba(239, 68, 68, .4); border-radius: 10px; background: rgba(239, 68, 68, .06); }
.tfa-danger-t { color: var(--bad); font-weight: 700; font-size: 14.5px; }
.tfa-danger .tfa-block { background: transparent; border: none; padding: 0; }
/* 面板裡的 msg 預設是隱藏的，這裡用到的都是直接帶 show */
.msg.warn { background: rgba(245, 158, 11, .12); border: 1px solid rgba(245, 158, 11, .4); color: var(--warn); }

/* ============================================================
   🗂️ 左側欄分類區 ＋ 拖拉排序 ＋ 項目色板
   （移植自 LinkHub；差異：手機版刻意不給拖拉，見檔尾的 @media）
   ============================================================ */
.layout { display: flex; align-items: flex-start; }
/* --topbar-h 由 main.js 用 ResizeObserver 量實際高度寫回；
   寫死高度在家庭備忘錄那邊咬過（頂列一換行側欄就錯位），所以這裡一律量測。 */
.sidebar {
  width: var(--sidebar-w, 260px); flex: 0 0 auto;
  border-right: 1px solid var(--border); background: var(--surface2);
  padding: 12px 8px 16px; position: sticky; top: var(--topbar-h, 57px);
  height: calc(100vh - var(--topbar-h, 57px)); overflow-y: auto;
  display: flex; flex-direction: column; gap: 4px;
}
.side-head { display: flex; align-items: center; gap: 6px; padding: 2px 6px 8px; }
.side-head .side-title { font-size: 12.5px; color: var(--faint); font-weight: 700; letter-spacing: .5px; }
.side-head .spacer { flex: 1; }
.side-add { background: var(--surface); border: 1px solid var(--border); color: var(--ink);
  border-radius: 8px; padding: 3px 8px; font-size: 13px; line-height: 1.4; }
.side-add:hover { border-color: var(--accent); color: var(--accent); }
#cat-list { display: flex; flex-direction: column; gap: 2px; }
.side-item { display: flex; align-items: center; gap: 6px; padding: 7px 8px; border-radius: 9px;
  cursor: pointer; border: 1px solid transparent; min-height: 36px; }
.side-item:hover { background: var(--surface); border-color: var(--border); }
.side-item.active { background: var(--surface); border-color: var(--accent); }
.side-item.active .si-name { color: var(--accent); font-weight: 700; }
.side-item .si-name { flex: 1; min-width: 0; font-size: 13.5px; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.side-item .si-pill { flex: none; font-size: 11px; padding: 1px 7px; border-radius: 999px;
  background: var(--surface2); border: 1px solid var(--border); color: var(--muted);
  font-variant-numeric: tabular-nums; }
.side-item.active .si-pill { border-color: var(--accent-tint); color: var(--accent); }
.side-sep { height: 1px; background: var(--border); margin: 8px 4px; flex: none; }
/* 分類列上的改名／刪除：平時藏起來，滑過或選中才浮出（觸控裝置永遠顯示，見檔尾） */
.si-acts { display: flex; gap: 2px; flex: none; opacity: 0; transition: opacity .12s; }
.side-item:hover .si-acts, .side-item.active .si-acts { opacity: 1; }
.si-acts button { background: none; border: none; color: var(--muted); font-size: 12.5px;
  padding: 2px 4px; border-radius: 6px; line-height: 1; }
.si-acts button:hover { color: var(--accent); background: var(--surface2); }
/* 側欄底部：顯示色調 */
.side-foot { margin-top: auto; padding: 12px 6px 2px; border-top: 1px solid var(--border); }
.side-foot label { display: block; font-size: 12px; color: var(--faint); margin-bottom: 6px; }
.side-foot select { width: 100%; padding: 7px 8px; background: var(--surface); border: 1px solid var(--border);
  border-radius: 8px; color: var(--ink); outline: none; font-size: 13.5px; }
.side-foot select:focus { border-color: var(--accent); }
/* 側欄裡的主區容器：置中的 max-width 在有側欄時會偏掉，改成靠左起算 */
.layout .container { flex: 1; min-width: 0; margin: 0; }

/* ---------- 拖曳（⠿ 握把；只有握把抓得動，避免拖到一半誤觸卡片） ---------- */
/* ⚠️ 不能叫 .grip —— .sheet .grip 已經是抽屜頂端那條灰色橫桿了（名稱衝突）。 */
.drag-grip { cursor: grab; color: var(--faint); font-size: 14px; user-select: none; flex: 0 0 auto;
  line-height: 1; padding: 2px 3px; touch-action: none; border-radius: 5px; }
.drag-grip:hover { color: var(--accent); background: var(--surface2); }
.drag-grip:active { cursor: grabbing; }
.sorting { opacity: .45; outline: 2px dashed var(--accent); outline-offset: 2px; border-radius: 10px; }
/* 把項目拖到左側分類上時的落點提示 */
.side-item.drop-target { background: var(--surface); border-color: var(--accent);
  outline: 2px dashed var(--accent); outline-offset: 1px; }

/* ---------- 項目底色（顏色按鈕） ---------- */
/* 底色一上去就把邊框吃掉，不然會有一圈跟底色打架的框（LinkHub 同樣處理）。 */
.card-item[style*="background"] { border-color: transparent; }
.cp-overlay { position: fixed; inset: 0; z-index: 50; background: rgba(0,0,0,.55);
  display: flex; align-items: center; justify-content: center; padding: 18px; }
.cp-panel { width: 100%; max-width: 380px; max-height: 88vh; overflow-y: auto;
  background: var(--surface); border: 1px solid var(--border); border-radius: 16px; padding: 16px; }
.cp-head { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }
.cp-head .cp-t { font-size: 16px; font-weight: 700; flex: 1; }
.cp-x { background: none; border: none; color: var(--muted); font-size: 18px; padding: 2px 6px; }
.cp-x:hover { color: var(--ink); }
.cp-tabs { display: flex; gap: 6px; margin-bottom: 10px; }
.cp-tab { flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 7px 8px; background: var(--surface2); border: 1px solid var(--border); border-radius: 9px;
  color: var(--muted); font-size: 13px; }
.cp-tab.on { border-color: var(--accent); color: var(--accent); font-weight: 700; }
/* tab 上的小圓點＝該項目前的顏色；沒設就用棋盤格表示「未設定」 */
.cp-dot { width: 14px; height: 14px; border-radius: 4px; border: 1px solid var(--border); flex: none;
  background-image: linear-gradient(45deg, var(--faint) 25%, transparent 25%, transparent 75%, var(--faint) 75%),
                    linear-gradient(45deg, var(--faint) 25%, transparent 25%, transparent 75%, var(--faint) 75%);
  background-size: 8px 8px; background-position: 0 0, 4px 4px; }
.cp-grid { display: flex; flex-wrap: wrap; gap: 5px; max-height: 220px; overflow-y: auto;
  padding: 8px; background: var(--surface2); border: 1px solid var(--border); border-radius: 10px; }
.cp-sw { width: 26px; height: 26px; border-radius: 6px; border: 1px solid var(--border); padding: 0; flex: none; }
.cp-sw:hover { outline: 2px solid var(--accent); outline-offset: 1px; }
.cp-hexrow { display: flex; gap: 6px; align-items: center; margin-top: 10px; }
.cp-hexrow input { flex: 1; min-width: 0; padding: 8px 10px; background: var(--surface2);
  border: 1px solid var(--border); border-radius: 8px; color: var(--ink); outline: none;
  font-family: Consolas, ui-monospace, monospace; }
.cp-hexrow input:focus { border-color: var(--accent); }
.cp-prev { width: 34px; height: 34px; border-radius: 8px; border: 1px solid var(--border); flex: none; padding: 0; }
.cp-drop { flex: none; background: var(--surface2); border: 1px solid var(--border); color: var(--ink);
  border-radius: 8px; padding: 8px 10px; font-size: 15px; line-height: 1; }
.cp-drop:disabled { opacity: .4; cursor: not-allowed; }

/* ---------- 手機抽屜 ---------- */
.menu-btn { display: none; }
#sidebar-backdrop { display: none; }

/* ============================================================
   📱 手機＝「簡易版」／💻 電腦＝「專業版」
   她的原話：「手機不用拖拉，手機通常更多的是能看到內容答案和查找。」
   所以 720px 以下：側欄變抽屜、**所有拖曳握把整個不渲染**（JS 端也不掛拖曳事件，
   這裡的 display:none 只是第二道保險），把畫面全留給看內容與搜尋。
   ============================================================ */
@media (max-width: 720px) {
  .menu-btn { display: inline-block; }
  /* 頂列有 8 顆按鈕，375px 寬的手機一排塞不下，會把整頁撐寬到 600 多 px（畫面可以左右拉）。
     解法：讓原本用來「把按鈕推到右邊」的 .spacer 在手機變成一條 100% 寬的隱形換行符，
     按鈕群自然掉到第二排。--topbar-h 是量測出來的，所以側欄抽屜會自己對齊到新的高度。 */
  .topbar { flex-wrap: wrap; padding: 10px; gap: 6px; }
  .topbar .spacer { flex: 0 0 100%; height: 0; margin: 0; }
  .topbar .who { flex: 1 1 auto; min-width: 0; }
  .topbar .icon-btn.text-btn { padding: 8px 9px; font-size: 13px; }
  .sidebar {
    position: fixed; left: 0; top: var(--topbar-h, 57px); bottom: 0; z-index: 35;
    width: min(82vw, 300px); height: auto; transform: translateX(-100%);
    transition: transform .2s ease; box-shadow: 8px 0 28px rgba(0,0,0,.35);
  }
  .sidebar.open { transform: none; }
  .sidebar.open + #sidebar-backdrop { display: block; position: fixed; inset: 0; z-index: 34;
    background: rgba(0,0,0,.45); }
  .layout .container { margin: 0 auto; }
  .drag-grip { display: none !important; }
  /* 觸控裝置沒有 hover，分類的改名／刪除鈕改成永遠看得到 */
  .si-acts { opacity: 1; }
}
@media (hover: none) {
  .si-acts { opacity: 1; }
}

/* ---------- 抽屜頁首：拖曳橫桿 ＋ 右上角關閉 ✕ ---------- */
/* .sheet 本身就是捲動容器，所以頁首要 sticky——不然表單一捲下去就看不到關閉鈕了。
   margin 的負值是為了抵銷 .sheet 的 18px 內距，讓底色鋪滿整個寬度、並貼齊最上緣；
   top 也要跟著設成 -18px：sticky 的參考原點是捲動容器的**內容框**（已經扣掉 18px 內距），
   寫 top:0 的話瀏覽器會把上面那個負 margin 又推回去，✕ 就會掉到內距下面（實測過）；
   .sheet 有 overflow-y:auto，會自動把這塊底色裁進圓角裡，不必自己再設一次 border-radius。 */
.sheet-head { position: sticky; top: -18px; z-index: 5;
  margin: -18px -18px 10px; padding: 14px 16px 10px; background: var(--surface); }
.sheet-head .grip { margin: 0 auto; }
/* 用絕對定位而不是 flex：這樣灰色橫桿維持在正中間，不會被 ✕ 的寬度推歪。 */
.sheet-x { position: absolute; top: 8px; right: 10px; width: 32px; height: 32px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--surface2); border: 1px solid var(--border); color: var(--muted);
  border-radius: 9px; font-size: 14px; line-height: 1; }
.sheet-x:hover { border-color: var(--bad); color: var(--bad); }
.sheet-x:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ---------- 「有還沒儲存的變更」三選一 ---------- */
/* z-index 要壓過 .sheet(41)，但低於 .copy-toast(60)，複製提示才不會被蓋住。 */
.confirm-overlay { position: fixed; inset: 0; z-index: 55; background: rgba(0,0,0,.6);
  display: flex; align-items: center; justify-content: center; padding: 20px; }
.confirm-box { width: 100%; max-width: 400px; background: var(--surface);
  border: 1px solid var(--border); border-radius: 16px; padding: 20px;
  box-shadow: 0 16px 48px rgba(0,0,0,.5); }
.confirm-t { font-size: 16.5px; font-weight: 700; color: var(--ink); }
.confirm-d { font-size: 13.5px; color: var(--muted); margin-top: 8px; line-height: 1.6; }
/* 直排：三個選項的文字都不短，橫排在手機上會擠成兩行還對不齊。 */
.confirm-acts { display: flex; flex-direction: column; gap: 8px; margin-top: 18px; }

/* ---------- 🔒 自動上鎖：頂列按鈕與下拉選單 ---------- */
/* 暫停時整顆變琥珀色——「防線關著」這件事一定要一眼看得到，不能只藏在 title 裡。 */
.icon-btn.text-btn.warn { color: var(--warn); border-color: var(--warn); }
.menu { position: fixed; z-index: 45; min-width: 210px; padding: 6px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 12px;
  box-shadow: 0 12px 32px rgba(0,0,0,.45); }
.menu-item { display: block; width: 100%; text-align: left; background: none; border: none;
  color: var(--ink); font-size: 13.5px; padding: 8px 10px; border-radius: 8px; white-space: nowrap; }
.menu-item:hover { background: var(--surface2); }
.menu-item.on { color: var(--accent); font-weight: 700; }
.menu-sep { height: 1px; background: var(--border); margin: 6px 4px; }
.menu-note { font-size: 11.5px; color: var(--faint); line-height: 1.5; padding: 6px 10px 4px;
  border-top: 1px solid var(--border); margin-top: 6px; white-space: normal; max-width: 240px; }

/* ---------- 🔓 這台裝置的快速解鎖 ---------- */
/* 登入畫面上的解鎖捷徑。放在帳密欄上方＝她按 F5 之後最常走的那條路要最好按到。
   ⚠️ 底下的帳密表單永遠同時存在：這只是捷徑，不是唯一入口。 */
.qu-panel { margin: 0 0 18px; padding: 12px; border: 1px solid var(--accent-tint);
  border-radius: 12px; background: var(--surface2); }
.qu-title { font-size: 12.5px; color: var(--muted); margin-bottom: 8px; }
.qu-btn { width: 100%; justify-content: flex-start; margin-bottom: 6px; }
.qu-btn:last-child { margin-bottom: 0; }
/* PIN 輸入框：數字大一點、字距拉開，手機上比較好對 */
.qu-pin { width: 100%; padding: 12px; background: var(--surface2); border: 1px solid var(--border);
  border-radius: 10px; color: var(--ink); outline: none;
  font-size: 20px; letter-spacing: 6px; text-align: center;
  font-family: Consolas, ui-monospace, monospace; }
.qu-pin:focus { border-color: var(--accent); }
/* 我的裝置清單 */
.dev-row { display: flex; align-items: center; gap: 10px; padding: 11px 12px; margin-bottom: 8px;
  background: var(--surface2); border: 1px solid var(--border); border-radius: 10px; }
.dev-row.revoked { opacity: .55; }
.dev-main { flex: 1; min-width: 0; }
.dev-name { font-size: 14.5px; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dev-meta { font-size: 12px; color: var(--faint); margin-top: 3px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---------- 📱 手機版的「⋯ 更多」 ---------- */
/* 電腦版看不到這顆（按鈕全部攤在頂列上）；手機版反過來，只留 ☰ 和 ⋯。
   2026-08-22 修：頂列在 375px 上原本會擠成 3 排 138px 的圖示牆，她因此找不到 ⚙️。 */
.more-btn { display: none; }
@media (max-width: 720px) {
  .more-btn { display: inline-block; }
  /* ⚠️ 用 display:none 而不是把按鈕拿掉——「⋯ 更多」選單就是直接 .click() 這些藏起來的真按鈕，
     所以它們必須留在 DOM 裡。隱藏的按鈕照樣收得到程式觸發的點擊。 */
  .topbar-sec { display: none !important; }
  /* 按鈕都收進選單了，頂列不必再換行，spacer 恢復成正常的「把 ⋯ 推到右邊」 */
  .topbar { flex-wrap: nowrap; }
  .topbar .spacer { flex: 1; height: auto; }
}

/* ============================================================
   📣 公告
   ⚠️ 公告是明文的（見 app/announce.py 檔頭）——這是零知識的刻意例外。
   ============================================================ */

/* ---- 富文本編輯器 ---- */
.rt-wrap { border: 1px solid var(--border); border-radius: 10px; background: var(--surface2); overflow: hidden; }
.rt-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; padding: 7px 8px;
  background: var(--surface); border-bottom: 1px solid var(--border); }
.rt-btn { background: transparent; color: var(--muted); border: 1px solid transparent; border-radius: 7px;
  padding: 4px 8px; font-size: 13px; line-height: 1.3; cursor: pointer; min-width: 28px; }
.rt-btn:hover { background: var(--surface2); color: var(--ink); border-color: var(--border); }
.rt-btn:active { transform: translateY(1px); }
.rt-sep { width: 1px; height: 18px; background: var(--border); margin: 0 3px; }
.rt-colors { display: inline-flex; gap: 3px; }
.rt-color { width: 17px; height: 17px; border-radius: 50%; border: 1px solid var(--border); cursor: pointer; padding: 0; }
.rt-color:hover { transform: scale(1.18); }
.rt-area { min-height: 170px; max-height: 46vh; overflow-y: auto; padding: 12px 13px;
  color: var(--ink); font-size: 14.5px; line-height: 1.75; outline: none; }
.rt-area:focus { background: var(--surface); }

/* 編輯區與檢視區共用的內文排版 */
.rt-area h1, .ann-body h1, .rt-area h2, .ann-body h2 { font-size: 17px; font-weight: 700; margin: 14px 0 6px; color: var(--ink); }
.rt-area h3, .ann-body h3, .rt-area h4, .ann-body h4 { font-size: 15px; font-weight: 700; margin: 12px 0 5px; color: var(--ink); }
.rt-area p, .ann-body p { margin: 0 0 8px; }
.rt-area ul, .ann-body ul, .rt-area ol, .ann-body ol { margin: 6px 0 8px; padding-left: 22px; }
.rt-area li, .ann-body li { margin: 3px 0; }
.rt-area blockquote, .ann-body blockquote { margin: 8px 0; padding: 6px 12px;
  border-left: 3px solid var(--accent); background: var(--surface2); color: var(--muted); border-radius: 0 8px 8px 0; }
.rt-area code, .ann-body code { background: var(--surface2); padding: 1px 5px; border-radius: 5px;
  font-family: ui-monospace, "SFMono-Regular", Consolas, monospace; font-size: 13px; }
.rt-area pre, .ann-body pre { background: var(--surface2); padding: 10px 12px; border-radius: 8px;
  overflow-x: auto; font-size: 13px; margin: 8px 0; }
.rt-area a, .ann-body a { color: var(--accent); text-decoration: underline; word-break: break-all; }
.rt-area hr, .ann-body hr { border: none; border-top: 1px solid var(--border); margin: 12px 0; }

/* ---- 管理端清單 ---- */
.ann-row { display: flex; align-items: center; gap: 10px; padding: 11px 12px; background: var(--surface2);
  border: 1px solid var(--border); border-radius: 10px; margin-bottom: 8px; }
.ann-row.draft { opacity: .62; border-style: dashed; }
.ann-main { flex: 1; min-width: 0; }
.ann-title { font-size: 14.5px; font-weight: 650; color: var(--ink); word-break: break-word; }
.ann-meta { font-size: 11.5px; color: var(--faint); margin-top: 3px; line-height: 1.6; word-break: break-word; }
.ann-acts { display: flex; gap: 6px; flex-shrink: 0; }

/* ---- 對象挑選 ---- */
.ann-aud { display: flex; align-items: center; gap: 8px; padding: 7px 2px; font-size: 14px; color: var(--ink); cursor: pointer; }
.ann-aud input { width: auto; margin: 0; flex-shrink: 0; }
.ann-pick { margin: 4px 0 6px 24px; padding: 8px 10px; background: var(--surface2);
  border: 1px solid var(--border); border-radius: 9px; max-height: 210px; overflow-y: auto; }
.ann-pick-item { display: flex; align-items: center; gap: 8px; padding: 5px 2px; font-size: 13.5px; color: var(--ink); cursor: pointer; }
.ann-pick-item input { width: auto; margin: 0; flex-shrink: 0; }

/* ---- 成員端：清單上方的橫幅 ---- */
.ann-banner { margin: 0 0 10px; }
.ann-banner-in { display: flex; align-items: center; gap: 10px; padding: 9px 12px;
  background: rgba(56,189,248,.10); border: 1px solid var(--accent-tint); border-radius: 10px; }
.ann-banner-t { flex: 1; min-width: 0; font-size: 13.5px; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* 頂列 📣 有未讀時的小紅點 */
#nav-ann.has-unread { color: var(--accent); font-weight: 700; }

/* ---- 成員端：檢視 ---- */
.ann-view { padding: 12px 0; border-bottom: 1px solid var(--border); }
.ann-view:last-of-type { border-bottom: none; }
.ann-view-head { display: flex; align-items: center; gap: 7px; }
.ann-view-t { font-size: 15.5px; font-weight: 700; color: var(--ink); word-break: break-word; }
.ann-dot { font-size: 10.5px; font-weight: 700; color: var(--accent-ink); background: var(--accent);
  border-radius: 999px; padding: 1px 7px; flex-shrink: 0; }
.ann-body { margin-top: 9px; font-size: 14.5px; line-height: 1.78; color: var(--ink); word-break: break-word; }

@media (max-width: 720px) {
  /* 手機：工具列可能兩行，編輯區縮一點免得按鈕被鍵盤蓋住 */
  .rt-area { min-height: 130px; max-height: 34vh; }
  .rt-btn { padding: 5px 7px; font-size: 12.5px; }
  .ann-row { flex-direction: column; align-items: stretch; }
  .ann-acts { justify-content: flex-end; }
}
