/* ============================================================
   大肥鱼控制台 · 设计系统 v2
   配色：暖白纸感 + 墨玉绿(brand) + 赤陶(accent) + 深墨(ink)
   目标：不单调、有层次、高级、长时间看不累眼
   ============================================================ */

:root {
  /* 底色（暖纸，不是死白） */
  --bg: #f6f3ee;
  --bg-grad-1: #fbf9f5;
  --bg-grad-2: #f1ece3;
  --surface: #ffffff;
  --surface-2: #fbf9f6;
  --surface-3: #f4efe7;

  /* 文字 */
  --txt: #1b1a17;
  --txt-2: #7b746a;
  --txt-2b: #6b6357;   /* 用于 --surface-3 底色上（pill / tabs 未选中）更稳的对比度 */
  --txt-3: #8a8277;

  /* 线 */
  --line: rgba(27, 26, 23, 0.08);
  --line-strong: rgba(27, 26, 23, 0.14);

  /* 品牌：墨玉绿 */
  --brand: #0e7c66;
  --brand-2: #17a58a;
  --brand-ink: #ffffff;
  --brand-soft: rgba(14, 124, 102, 0.1);
  --brand-soft-2: rgba(14, 124, 102, 0.18);

  /* 强调：赤陶 */
  --accent: #c2703d;
  --accent-soft: rgba(194, 112, 61, 0.12);

  /* 语义 */
  --ok: #2f855a;
  --ok-soft: rgba(47, 133, 90, 0.12);
  --warn: #b7791f;
  --warn-soft: rgba(183, 121, 31, 0.14);
  --danger: #c0392b;
  --danger-soft: rgba(192, 57, 43, 0.12);

  /* 气泡 */
  --me-bubble: linear-gradient(135deg, #0e7c66 0%, #17a58a 100%);
  --other-bubble: #ffffff;

  /* 形状与光影 */
  --r-lg: 22px;
  --r-md: 16px;
  --r-sm: 12px;
  --r-pill: 999px;
  --shadow-1: 0 1px 2px rgba(27, 26, 23, 0.04), 0 2px 8px rgba(27, 26, 23, 0.04);
  --shadow-2: 0 4px 14px rgba(27, 26, 23, 0.07), 0 12px 32px rgba(27, 26, 23, 0.06);
  --shadow-3: 0 12px 40px rgba(27, 26, 23, 0.14);
  --ring: 0 0 0 3px var(--brand-soft-2);

  --sat: env(safe-area-inset-top, 0px);
  --sab: env(safe-area-inset-bottom, 0px);

  /* ---- 悬浮按钮列：唯一真源（7 个面板都按这套变量定位，别再各写各的 bottom） ----
     槽位 = --fab-base + n × --fab-gap，n=0..7 → 84 / 142 / 200 / 258 / 316 / 374 / 432 / 490（490 = 账务 billing）
     间距 58 = 按钮 50 + 8，热区两两不重叠；--fab-lift 在聊天页给输入区让位。 */
  --fab-r: 14px;
  --fab-size: 50px;
  --fab-gap: 58px;
  --fab-base: 84px;
  --fab-lift: 0px;

  /* ---- 层级：一层遮罩一起抬，别再有 200/210 混着用 ---- */
  --z-fab: 120;
  --z-mask: 400;      /* 所有弹层遮罩 */
  --z-toast: 600;     /* 提示要压在所有弹层上面 */
  --z-otabar: 500;    /* 更新提示条 */
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0e1013;
    --bg-grad-1: #12161a;
    --bg-grad-2: #0b0d10;
    --surface: #171b20;
    --surface-2: #1b2026;
    --surface-3: #20262d;

    --txt: #ebe8e2;
    --txt-2: #9a9489;
    --txt-2b: #a9a297;
    --txt-3: #8b857b;

    --line: rgba(255, 255, 255, 0.08);
    --line-strong: rgba(255, 255, 255, 0.14);

    --brand: #34d3b4;
    --brand-2: #22b596;
    --brand-ink: #05221d;
    --brand-soft: rgba(52, 211, 180, 0.12);
    --brand-soft-2: rgba(52, 211, 180, 0.22);

    --accent: #e08a52;
    --accent-soft: rgba(224, 138, 82, 0.14);

    --ok: #4ade80;
    --ok-soft: rgba(74, 222, 128, 0.14);
    --warn: #fbbf24;
    --warn-soft: rgba(251, 191, 36, 0.16);
    --danger: #f87171;
    --danger-soft: rgba(248, 113, 113, 0.16);

    --me-bubble: linear-gradient(135deg, #1f8f79 0%, #2fc3a3 100%);
    --other-bubble: #1e242b;

    --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.4), 0 2px 10px rgba(0, 0, 0, 0.3);
    --shadow-2: 0 6px 18px rgba(0, 0, 0, 0.45), 0 16px 40px rgba(0, 0, 0, 0.35);
    --shadow-3: 0 18px 50px rgba(0, 0, 0, 0.55);
  }
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { height: 100%; }
body {
  margin: 0;
  font: 15px/1.6 "PingFang SC", "HarmonyOS Sans SC", "MiSans", "Source Han Sans SC", "Noto Sans CJK SC", "OPPO Sans", "vivo Sans", -apple-system, BlinkMacSystemFont, "Microsoft YaHei", "Segoe UI", sans-serif;
  color: var(--txt);
  background:
    radial-gradient(1200px 600px at 10% -10%, var(--brand-soft) 0%, transparent 60%),
    radial-gradient(900px 500px at 110% 10%, var(--accent-soft) 0%, transparent 55%),
    linear-gradient(180deg, var(--bg-grad-1) 0%, var(--bg) 45%, var(--bg-grad-2) 100%);
  background-attachment: fixed;
  overscroll-behavior-y: none;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
button, input, textarea, select { font: inherit; color: inherit; }
button { cursor: pointer; border: 0; background: none; }
button, .nav, .tabs, .list-item, .switch { touch-action: manipulation; -webkit-user-select: none; user-select: none; }
input, textarea, .bubble, .msg-row, .logbox, .sheet-body, .m-text { -webkit-user-select: text; user-select: text; }
a { color: var(--brand); text-decoration: none; }
.hide { display: none !important; }
.mono { font-family: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace; }
/* 数字统一等宽，避免额度/计数跳动 */
#app, #login { font-variant-numeric: tabular-nums; }
/* 移动端滚动容器：惯性滚动 + 不把滚动传给页面 + 隐藏滚动条 */
.chat-scroll, .list, .tab-body, .sheet-body, .logbox, .emoji-panel, .tabs {
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  scrollbar-width: none;
}
.chat-scroll::-webkit-scrollbar, .list::-webkit-scrollbar, .tab-body::-webkit-scrollbar,
.sheet-body::-webkit-scrollbar, .logbox::-webkit-scrollbar, .tabs::-webkit-scrollbar { width: 0; height: 0; }

/* ---------------- 登录 ---------------- */
#login {
  position: fixed; inset: 0; display: grid; place-items: center; padding: 24px; z-index: 100;
  background:
    radial-gradient(900px 500px at 20% 0%, rgba(23, 165, 138, 0.35), transparent 60%),
    radial-gradient(800px 600px at 100% 100%, rgba(194, 112, 61, 0.28), transparent 55%),
    linear-gradient(160deg, #0b3b33 0%, #0e2a26 45%, #0b1a18 100%);
}
.login-card {
  width: 100%; max-width: 392px; padding: 30px 24px 22px;
  border-radius: 26px;
  background: #fcfaf6;
  background: color-mix(in srgb, #fcfaf6 95%, transparent);
  backdrop-filter: blur(18px) saturate(140%);
  box-shadow: var(--shadow-3), inset 0 1px 0 rgba(255, 255, 255, 0.5);
  border: 1px solid rgba(255, 255, 255, 0.35);
}
@media (prefers-color-scheme: dark) {
  .login-card {
    background: #171b20;
    background: color-mix(in srgb, #171b20 92%, transparent);
    border-color: rgba(255, 255, 255, 0.12);
    box-shadow: var(--shadow-3), inset 0 1px 0 rgba(255, 255, 255, 0.06);
  }
}
.login-card h1 {
  margin: 0 0 6px; font-size: 24px; letter-spacing: -0.02em;
  background: linear-gradient(100deg, var(--brand), var(--accent));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.login-card p { margin: 0 0 20px; color: var(--txt-2); font-size: 13px; }

/* ---------------- 表单元素 ---------------- */
.field { margin-bottom: 14px; }
.field label { display: block; font-size: 12px; color: var(--txt-2); margin-bottom: 7px; letter-spacing: 0.02em; }
.input, .textarea, .select {
  width: 100%; padding: 12px 14px; border-radius: var(--r-sm);
  border: 1px solid var(--line-strong); background: var(--surface-2); color: var(--txt);
  outline: none; transition: border-color .16s, box-shadow .16s, background .16s;
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.02);
}
.input::placeholder, .textarea::placeholder { color: var(--txt-2); opacity: .85; }
.input:focus, .textarea:focus, .select:focus { border-color: var(--brand); box-shadow: var(--ring); background: var(--surface); }
.textarea { min-height: 96px; resize: vertical; line-height: 1.6; }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 12px 18px; border-radius: var(--r-sm); width: 100%;
  background: linear-gradient(135deg, var(--brand) 0%, var(--brand-2) 100%);
  color: var(--brand-ink); font-weight: 600; font-size: 15px; letter-spacing: 0.01em;
  box-shadow: 0 6px 18px var(--brand-soft-2), inset 0 1px 0 rgba(255, 255, 255, 0.18);
  transition: transform .12s ease, box-shadow .16s, filter .16s;
  white-space: nowrap;
}
.btn:active { transform: translateY(1px) scale(.995); filter: brightness(.97); }
.btn[disabled] { opacity: .5; box-shadow: none; }
.btn.ghost { background: transparent; color: var(--brand); border: 1.5px solid var(--brand-soft-2); box-shadow: none; }
.btn.gray { background: var(--surface-3); color: var(--txt); box-shadow: none; border: 1px solid var(--line); }
.btn.danger { background: linear-gradient(135deg, var(--danger), #a83226); color: #fff; box-shadow: 0 6px 16px var(--danger-soft); }
.btn.sm { padding: 8px 13px; font-size: 13px; width: auto; border-radius: 10px; flex: 0 0 auto; }
/* 列表里的危险操作（删除 / 拉黑）：红色文字 + 淡红底，和普通次级按钮区分开 */
.btn.sm.danger { background: var(--danger-soft); color: var(--danger); border: 1px solid rgba(192, 57, 43, 0.28); box-shadow: none; font-weight: 600; }
.btn.sm.danger:active { background: rgba(192, 57, 43, 0.2); }
@media (prefers-color-scheme: dark) {
  .btn.sm.danger { border-color: rgba(248, 113, 113, 0.3); }
}
.login-card .err { color: var(--danger); font-size: 13px; min-height: 18px; margin: 6px 0 2px; }

/* ---------------- 布局 ---------------- */
/* --kb：键盘顶起的高度（JS 用 visualViewport 算），让输入框不被键盘盖住 */
#app { position: fixed; inset: 0; bottom: var(--kb, 0px); display: flex; flex-direction: column; }
.topbar {
  height: calc(56px + var(--sat)); padding: var(--sat) 14px 0;
  display: flex; align-items: center; gap: 10px; flex: 0 0 auto; z-index: 5;
  color: #fff; position: relative;
  background: linear-gradient(120deg, #0b5f52 0%, #0e7c66 45%, #15a287 100%);
  box-shadow: 0 6px 24px rgba(11, 63, 53, 0.28);
}
.topbar::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(400px 120px at 85% -20%, rgba(255, 255, 255, 0.35), transparent 70%);
}
.topbar .title { font-weight: 650; font-size: 16.5px; flex: 1; display: flex; align-items: center; gap: 8px; letter-spacing: 0.01em; }
.dot-wrap { display: inline-flex; align-items: center; justify-content: center; width: 7px; height: 7px; flex: 0 0 7px; }
.dot { display: block; width: 7px; height: 7px; border-radius: 50%; background: rgba(255, 255, 255, 0.5); box-shadow: none; transition: background .2s, box-shadow .2s; }
.dot.on { background: #8dffd6; box-shadow: 0 0 6px rgba(141, 255, 214, 0.95); }
.dot.off { background: #ff9a8a; box-shadow: 0 0 6px rgba(255, 154, 138, 0.75); }
.icon-btn {
  width: 36px; height: 36px; border-radius: 50%; display: grid; place-items: center;
  color: #fff; font-size: 17px; transition: background .16s, transform .12s;
}
.icon-btn:active { background: rgba(255, 255, 255, 0.2); transform: scale(.94); }
.topbar .pill { background: rgba(255, 255, 255, 0.16); color: #fff; border: 1px solid rgba(255, 255, 255, 0.18); }
.badge {
  position: absolute; top: -6px; left: 13px; background: linear-gradient(135deg, #ff6b5e, #d63a2c);
  color: #fff; font-size: 10px; line-height: 1; min-width: 16px; height: 16px; border-radius: 8px; padding: 0 4px;
  display: grid; place-items: center; box-shadow: 0 2px 6px rgba(214, 58, 44, 0.4);
  font-variant-numeric: tabular-nums; font-weight: 600;
}

.pages { flex: 1; position: relative; overflow: hidden; }
.page {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  transform: translateX(100%); transition: transform .26s cubic-bezier(.22, .8, .28, 1);
  background:
    radial-gradient(680px 320px at 100% 0%, var(--brand-soft) 0%, transparent 62%),
    radial-gradient(560px 300px at 0% 100%, var(--accent-soft) 0%, transparent 58%),
    var(--bg);
}
.page.active { transform: translateX(0); }

/* ---------------- 聊天 ---------------- */
#page-chat { transform: none; background: transparent; }
.chat-scroll {
  flex: 1; overflow-y: auto; padding: 16px 12px 8px; -webkit-overflow-scrolling: touch;
  background:
    radial-gradient(700px 320px at 100% 0%, var(--brand-soft) 0%, transparent 60%),
    radial-gradient(600px 300px at 0% 100%, var(--accent-soft) 0%, transparent 55%);
}
.msg { display: flex; gap: 9px; margin-bottom: 16px; align-items: flex-start; animation: rise .22s ease both; }
@keyframes rise { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
.msg.me { flex-direction: row-reverse; }
.avatar {
  width: 40px; height: 40px; border-radius: 13px; flex: 0 0 auto; display: grid; place-items: center;
  color: #fff; font-size: 16px; font-weight: 600; overflow: hidden;
  background: linear-gradient(140deg, #17796a, #22b596);
  box-shadow: 0 3px 10px rgba(14, 124, 102, 0.25), inset 0 1px 0 rgba(255, 255, 255, 0.25);
}
.msg.me .avatar { background: linear-gradient(140deg, #c2703d, #e0a06f); box-shadow: 0 3px 10px rgba(194, 112, 61, 0.25); }
.avatar.big { width: 54px; height: 54px; border-radius: 17px; font-size: 24px; }
.avatar img { width: 100%; height: 100%; object-fit: cover; }
.bubble-wrap { max-width: 76%; display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }
.msg.me .bubble-wrap { align-items: flex-end; }
.bubble {
  padding: 11px 15px; border-radius: 18px 18px 18px 6px;
  background: var(--other-bubble); color: var(--txt);
  font-size: 16.5px; line-height: 1.72; letter-spacing: .012em; word-break: break-word; white-space: pre-wrap;
  font-family: inherit; -webkit-font-smoothing: antialiased;
  box-shadow: var(--shadow-1); border: 1px solid var(--line);
}
.msg.me .bubble {
  background: var(--me-bubble); color: #fff; border: 0;
  border-radius: 18px 18px 6px 18px;
  box-shadow: 0 6px 18px var(--brand-soft-2);
}
.bubble img { max-width: 210px; border-radius: 12px; display: block; margin-bottom: 4px; background: var(--surface-3); }
.meta-line { font-size: 11px; color: var(--txt-2b); padding: 0 6px; display: flex; gap: 8px; align-items: center; letter-spacing: 0.02em; }
.speak { opacity: .7; font-size: 12px; transition: opacity .15s; display: inline-flex; align-items: center; gap: 3px; color: var(--txt-2); }
.speak svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.speak:active { opacity: 1; color: var(--brand); }
.typing { display: flex; gap: 7px; align-items: center; color: var(--txt-2b); font-size: 12.5px; padding: 0 16px 12px; }
.typing .dots span {
  display: inline-block; width: 5px; height: 5px; border-radius: 50%; background: var(--brand);
  margin-right: 2px; animation: blink 1.3s infinite; opacity: .4;
}
.typing .dots span:nth-child(2) { animation-delay: .18s; }
.typing .dots span:nth-child(3) { animation-delay: .36s; }
@keyframes blink { 0%, 60%, 100% { opacity: .25; transform: translateY(0); } 30% { opacity: 1; transform: translateY(-2px); } }

.composer {
  flex: 0 0 auto; display: flex; align-items: flex-end; gap: 8px;
  padding: 9px 10px calc(9px + var(--sab));
  background: var(--surface);
  background: color-mix(in srgb, var(--surface) 92%, transparent);
  backdrop-filter: blur(14px);
  border-top: 1px solid var(--line);
  box-shadow: 0 -6px 24px rgba(27, 26, 23, 0.05);
}
.composer textarea {
  flex: 1; resize: none; max-height: 120px; min-height: 42px; padding: 10px 15px;
  border-radius: var(--r-pill); border: 1px solid var(--line-strong);
  background: var(--surface-2); outline: none; transition: border-color .16s, box-shadow .16s;
}
.composer textarea:focus { border-color: var(--brand); box-shadow: var(--ring); background: var(--surface); }
.composer .send {
  width: 64px; height: 42px; border-radius: var(--r-pill); font-weight: 650; color: #fff;
  background: linear-gradient(135deg, var(--brand), var(--brand-2));
  box-shadow: 0 6px 16px var(--brand-soft-2);
  transition: transform .12s, filter .16s;
}
.composer .send:active { transform: scale(.96); }
.composer .send[disabled] { opacity: .45; box-shadow: none; }
.round { width: 40px; height: 40px; border-radius: 50%; display: grid; place-items: center; font-size: 19px; color: var(--txt-2); transition: background .16s, color .16s; }
.round svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.round:active svg { stroke: var(--brand); }
.round:active { background: var(--brand-soft); color: var(--brand); }

/* ---------------- 列表 ---------------- */
.list { flex: 1; overflow-y: auto; padding: 10px 12px calc(16px + var(--sab)); }
.list-item {
  display: flex; gap: 12px; padding: 14px; align-items: center;
  background: var(--surface); border-radius: var(--r-md); margin-bottom: 10px;
  border: 1px solid var(--line); box-shadow: var(--shadow-1);
  transition: transform .12s, box-shadow .16s, border-color .16s;
}
.list-item:active { transform: scale(.995); box-shadow: var(--shadow-2); border-color: var(--brand-soft-2); }
.list-item .li-main { flex: 1; min-width: 0; }
.list-item .li-title { font-weight: 620; font-size: 15px; display: flex; gap: 8px; align-items: center; min-width: 0; }
.list-item .li-title > .li-t {
  flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.list-item .li-title > .pill { flex: 0 0 auto; }
.list-item .li-sub { color: var(--txt-2); font-size: 12.5px; margin-top: 3px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pill {
  font-size: 11px; padding: 2px 9px; border-radius: var(--r-pill); font-weight: 500;
  background: var(--surface-3); color: var(--txt-2b); border: 1px solid var(--line);
  white-space: nowrap; flex: 0 0 auto;
}
.pill.ok { background: var(--ok-soft); color: var(--ok); border-color: transparent; }
.pill.warn { background: var(--warn-soft); color: #8a5310; border-color: transparent; }
.pill.bad { background: var(--danger-soft); color: var(--danger); border-color: transparent; }
@media (prefers-color-scheme: dark) {
  .pill.warn { color: var(--warn); }
}
.chip {
  display: inline-block; padding: 1px 8px; border-radius: var(--r-pill); background: var(--brand-soft);
  color: var(--brand); font-size: 11px; margin-left: 6px;
  white-space: nowrap; max-width: 40vw; overflow: hidden; text-overflow: ellipsis; vertical-align: bottom;
}
.section-title { padding: 16px 16px 8px; font-size: 12px; color: var(--txt-2b); font-weight: 650; letter-spacing: 0.06em; text-transform: uppercase; }

/* ---------------- 空状态 / 错误态 ---------------- */
.empty {
  padding: 52px 24px; text-align: center; color: var(--txt-2b); font-size: 13.5px; line-height: 1.7;
}
.empty .empty-ic {
  width: 46px; height: 46px; margin: 0 auto 14px; display: block; opacity: .5;
  fill: none; stroke: currentColor; stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round;
}
.empty .empty-t { font-size: 14.5px; font-weight: 620; color: var(--txt); margin-bottom: 6px; }
.empty .empty-d { font-size: 12.5px; color: var(--txt-2b); max-width: 300px; margin: 0 auto; }
.empty .empty-act { margin-top: 14px; }
.empty.is-error .empty-ic { color: var(--danger); opacity: .75; }
.empty.is-error .empty-t { color: var(--danger); }
.empty.is-loading .empty-ic { animation: spin 1.1s linear infinite; opacity: .6; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------------- 标签页 ---------------- */
.tabs-wrap { position: relative; flex: 0 0 auto; }
.tabs-wrap::after {
  content: ''; position: absolute; top: 0; right: 0; bottom: 1px; width: 34px; pointer-events: none;
  background: linear-gradient(90deg, transparent, var(--surface) 78%);
  opacity: 0; transition: opacity .2s;
}
.tabs-wrap.more::after { opacity: .96; }
@media (prefers-color-scheme: dark) {
  .tabs-wrap::after { background: linear-gradient(90deg, transparent, var(--surface) 78%); }
}
.tabs {
  display: flex; gap: 8px; padding: 12px 30px 12px 12px; overflow-x: auto; flex: 0 0 auto;
  background: var(--surface);
  background: color-mix(in srgb, var(--surface) 80%, transparent);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line);
  scrollbar-width: none;
  scroll-behavior: smooth;
}
.tabs button {
  padding: 8px 15px; border-radius: var(--r-pill); font-size: 13px; white-space: nowrap;
  background: var(--surface-3); color: var(--txt-2b); border: 1px solid transparent;
  transition: all .16s; flex: 0 0 auto;
}
.tabs button.active {
  background: linear-gradient(135deg, var(--brand), var(--brand-2)); color: var(--brand-ink);
  box-shadow: 0 4px 12px var(--brand-soft-2); font-weight: 600;
}
.tab-body { flex: 1; overflow-y: auto; padding: 14px 12px calc(28px + var(--sab)); }

/* ---------------- 卡片 ---------------- */
.card {
  background: var(--surface); border-radius: var(--r-lg); padding: 16px; margin-bottom: 14px;
  border: 1px solid var(--line); box-shadow: var(--shadow-1);
  position: relative; overflow: hidden;
}
.card::before {
  content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: linear-gradient(180deg, var(--brand), transparent);
  opacity: .55;
}
.card h3 {
  margin: 0 0 12px; font-size: 14px; font-weight: 650; letter-spacing: 0.01em;
  display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap;
}
/* 卡片标题里的名字：长了就省略，不要把 chip / pill 挤成多行 */
.card h3 > .h3-t {
  flex: 1 1 120px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.card h3 > .chip, .card h3 > .pill, .card h3 > .mini, .card h3 > .btn { flex: 0 0 auto; white-space: nowrap; }
.row { display: flex; gap: 8px; align-items: center; }
.row > * { min-width: 0; }
.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.grid3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.kv {
  display: flex; justify-content: space-between; align-items: center; gap: 10px;
  padding: 9px 0; font-size: 13px; border-bottom: 1px dashed var(--line);
}
.kv:last-child { border-bottom: 0; }
.kv > span:first-child, .kv > b:first-child { flex: 0 0 auto; max-width: 46%; }
/* 右侧"值"列：开关这种固定尺寸控件不参与拉伸 */
.kv > b, .kv > span:last-child:not(.switch) { flex: 1 1 auto; min-width: 0; text-align: right; overflow-wrap: anywhere; }
.kv > .switch { flex: 0 0 auto; text-align: left; }
/* 只有一列（前面没有标签）时不要按"右侧值"排版 */
.kv > span:only-child, .kv > b:only-child { flex: 1 1 100%; max-width: 100%; text-align: left; }
.kv > span.switch:only-child { flex: 0 0 auto; }
.kv b { font-weight: 620; font-variant-numeric: tabular-nums; }
.hint { font-size: 12px; color: var(--txt-2b); line-height: 1.65; }
.mini { font-size: 12px; color: var(--txt-2b); }

.switch { position: relative; width: 46px; height: 27px; flex: 0 0 auto; }
.switch input { opacity: 0; width: 0; height: 0; }
.switch i { position: absolute; inset: 0; background: var(--surface-3); border-radius: var(--r-pill); transition: .2s; border: 1px solid var(--line); }
.switch i::after {
  content: ''; position: absolute; width: 21px; height: 21px; border-radius: 50%; background: #fff;
  top: 2px; left: 3px; transition: .2s cubic-bezier(.3, .8, .3, 1); box-shadow: 0 1px 4px rgba(0, 0, 0, .22);
}
.switch input:checked + i { background: linear-gradient(135deg, var(--brand), var(--brand-2)); border-color: transparent; }
.switch input:checked + i::after { transform: translateX(19px); }

/* 统计 */
.stat-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-bottom: 12px; }
.stat {
  padding: 14px 10px; text-align: center; border-radius: var(--r-md);
  background: linear-gradient(160deg, var(--brand-soft), transparent 70%), var(--surface-2);
  border: 1px solid var(--line);
}
.stat b { display: block; font-size: 20px; font-weight: 680; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.stat span { font-size: 11px; color: var(--txt-2b); }

.logbox {
  background: #0f1418; color: #cfe3dc; border-radius: var(--r-md); padding: 12px;
  font-size: 11.5px; font-family: ui-monospace, Menlo, Consolas, monospace;
  max-height: 46vh; overflow: auto; white-space: pre-wrap; line-height: 1.6;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.04);
}
/* 日志：时间 / 级别 定宽，正文换行时悬挂缩进，长串不撑破卡片 */
.logrow {
  display: grid; grid-template-columns: 58px 40px 1fr; gap: 6px;
  padding: 2px 0; border-bottom: 1px solid rgba(255, 255, 255, .04);
}
.logrow:last-child { border-bottom: 0; }
.logrow .l-t { color: #7f9d94; font-variant-numeric: tabular-nums; }
.logrow .l-lv { font-weight: 700; }
.logrow .l-lv.info { color: #7fd1b9; }
.logrow .l-lv.warn { color: #f2c14e; }
.logrow .l-lv.error { color: #ff8b7f; }
.logrow .l-m { white-space: pre-wrap; overflow-wrap: anywhere; word-break: break-word; }

/* ---------------- 二维码 ---------------- */
.qr-stage {
  width: 232px; height: 232px; margin: 4px auto 0; padding: 8px; position: relative;
  border-radius: 20px; background: var(--surface-2); border: 1px solid var(--line);
  box-shadow: var(--shadow-1);
}
.qr-tip {
  position: absolute; top: 0; left: 50%; transform: translate(-50%, -50%);
  padding: 3px 10px; border-radius: var(--r-pill); white-space: nowrap;
  font-size: 11px; font-weight: 600; letter-spacing: 0.01em;
  color: var(--brand); background: var(--surface);
  border: 1px solid var(--brand-soft-2); box-shadow: var(--shadow-1);
}
.qr-wrap {
  width: 216px; height: 216px; border-radius: 14px; overflow: hidden;
  display: grid; place-items: center; position: relative;
  background: var(--surface-3); border: 1px dashed var(--line-strong); color: var(--txt-2);
}
.qr-wrap img {
  width: 216px; height: 216px; object-fit: contain; display: block;
  background: #fff; padding: 8px; border-radius: 12px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
  image-rendering: crisp-edges;
}
.qr-wrap.has-qr { border-style: solid; border-color: var(--line); background: #fff; padding: 0; }
.qr-ph { display: grid; place-items: center; gap: 8px; text-align: center; padding: 10px; }
.qr-ph svg { width: 34px; height: 34px; fill: none; stroke: currentColor; stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round; opacity: .6; }
.qr-ph span { font-size: 11.5px; line-height: 1.5; }
.qr-wrap.has-qr .qr-ph, .qr-wrap img[hidden] { display: none; }
.qr-wrap.is-loading .qr-ph span::after { content: '…'; }
.qr-hint { text-align: center; margin-top: 14px; }
.qr-actions { display: flex; justify-content: center; margin-top: 10px; }

/* ---------------- 两步验证 ---------------- */
.kv-sw { align-items: flex-start; }
.kv-sw > span:first-child { max-width: 74%; line-height: 1.5; font-size: 13px; }
.kv-sw .switch { margin-top: 1px; }
.step-list { margin: 0 0 4px; padding: 0; list-style: none; counter-reset: st; }
.step-list li {
  position: relative; padding: 0 0 0 26px; margin-bottom: 8px; font-size: 12.5px;
  line-height: 1.6; color: var(--txt-2b); counter-increment: st;
}
.step-list li::before {
  content: counter(st); position: absolute; left: 0; top: 1px; width: 17px; height: 17px;
  border-radius: 50%; background: var(--brand-soft); color: var(--brand);
  font-size: 10.5px; font-weight: 700; display: grid; place-items: center;
}
.totp-secret {
  display: flex; flex-wrap: wrap; gap: 4px 6px; padding: 12px 8px; margin: 4px 0 10px;
  background: var(--surface-2); border: 1px dashed var(--line-strong); border-radius: var(--r-sm);
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 13.5px; letter-spacing: .1em; justify-content: center;
}
.totp-secret b { font-weight: 700; color: var(--txt); letter-spacing: .1em; }
.rec-box { background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-sm); padding: 10px 12px; }
.rec-list {
  display: grid; grid-template-columns: 1fr 1fr; gap: 6px 10px; margin: 8px 0 0;
  font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 12.5px; color: var(--txt);
}
.rec-list span { word-break: break-all; }
.code-row { display: flex; gap: 8px; align-items: center; }
.code-row .input { flex: 1 1 auto; letter-spacing: .22em; text-align: center; font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 17px; }
.code-row .btn { flex: 0 0 auto; }
.totp-done { display: grid; gap: 8px; }
.totp-done .ok-line { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--ok); font-weight: 600; }
.totp-done .ok-line svg { width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* ---------------- 底部导航 ---------------- */
.nav {
  display: flex; flex: 0 0 auto; padding: 8px 10px calc(8px + var(--sab));
  background: var(--surface);
  background: color-mix(in srgb, var(--surface) 90%, transparent);
  backdrop-filter: blur(16px); border-top: 1px solid var(--line);
  box-shadow: 0 -8px 28px rgba(27, 26, 23, 0.06);
}
.nav button {
  flex: 1; padding: 7px 0 6px; font-size: 11.5px; color: var(--txt-2);
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  border-radius: var(--r-sm); transition: color .16s, background .16s;
  min-width: 0;
}
.nav button .ic { font-size: 19px; line-height: 1; position: relative; display: inline-flex; }
.nav button.active { color: var(--brand); font-weight: 600; }
.nav button.active .ic { transform: translateY(-1px); transition: transform .16s; }
.nav button .ic { transition: transform .16s; }

/* ---------------- 她的动态 ---------------- */
.moment-head {
  display: flex; gap: 12px; padding: 16px 14px; align-items: center; flex: 0 0 auto;
  background: linear-gradient(120deg, var(--brand-soft), transparent 70%), var(--surface);
  border-bottom: 1px solid var(--line);
}
.moment-head .li-main, .card .row > .li-main { flex: 1 1 auto; min-width: 0; }
.moment-head .li-title { font-weight: 620; font-size: 15px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.moment-head .li-sub { color: var(--txt-2); font-size: 12.5px; margin-top: 3px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.moment-head .btn { flex: 0 0 auto; }
.moment-head .avatar.big { overflow: hidden; }
.moment-head .avatar.big img { width: 100%; height: 100%; object-fit: cover; }
.moment {
  background: var(--surface); padding: 16px; margin-bottom: 12px;
  border-radius: var(--r-lg); border: 1px solid var(--line); box-shadow: var(--shadow-1);
}
.moment .m-head { display: flex; gap: 10px; align-items: center; margin-bottom: 10px; }
.moment .m-text { white-space: pre-wrap; line-height: 1.7; font-size: 14.5px; letter-spacing: 0.005em; overflow-wrap: anywhere; }
.moment .m-imgs { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
.moment .m-imgs img { width: 104px; height: 104px; object-fit: cover; border-radius: 14px; box-shadow: var(--shadow-1); background: var(--surface-3); }
.moment .m-foot { display: flex; gap: 14px; color: var(--txt-2b); font-size: 12px; margin-top: 10px; align-items: center; flex-wrap: wrap; }
.moment .m-foot .m-act { display: inline-flex; align-items: center; gap: 4px; }
.moment .m-foot svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.moment .row .btn { flex: 0 0 auto; white-space: nowrap; }
.reply {
  background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: 9px 12px; margin-top: 8px; font-size: 13px; line-height: 1.6; overflow-wrap: anywhere;
}
.reply b { color: var(--brand); font-weight: 620; }

/* ---------------- 进度 / 告警 / 消息行 ---------------- */
.bar { height: 7px; background: var(--surface-3); border-radius: var(--r-pill); overflow: hidden; margin-top: 8px; }
.bar i { display: block; height: 100%; border-radius: var(--r-pill); background: linear-gradient(90deg, var(--brand), var(--brand-2)); transition: width .4s ease; }
.bar.warn i { background: linear-gradient(90deg, #d69e2e, #b7791f); }
.bar.bad i { background: linear-gradient(90deg, #e05252, #c0392b); }

.alert-item {
  border-radius: var(--r-md); padding: 13px 14px; margin-bottom: 10px;
  background: var(--surface); border: 1px solid var(--line); border-left: 3px solid var(--danger);
  box-shadow: var(--shadow-1);
}
.alert-item.high { border-left-color: var(--danger); }
.alert-item.medium { border-left-color: var(--warn); }
.alert-item.low { border-left-color: var(--txt-3); }
/* 已处理的告警压暗，跟"待处理"一眼分得开（角标只算未处理的） */
.alert-item.done { opacity: .58; border-left-color: var(--line-strong); }
.alert-item .a-top { display: flex; justify-content: space-between; gap: 8px; align-items: center; font-size: 12px; color: var(--txt-2b); margin-bottom: 6px; }
.alert-item .a-top .a-kind { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.alert-item .a-body { overflow-wrap: anywhere; word-break: break-word; }
.alert-item .a-words { font-size: 11.5px; color: var(--txt-2b); margin-top: 6px; }
.sev { font-size: 11px; font-weight: 650; padding: 1px 7px; border-radius: var(--r-pill); white-space: nowrap; flex: 0 0 auto; }
.sev.high { color: #fff; background: linear-gradient(135deg, #e05252, #c0392b); }
.sev.medium { color: #7a4e07; background: rgba(214, 158, 46, .22); }
.sev.low { color: var(--txt-2b); background: var(--surface-3); }
@media (prefers-color-scheme: dark) {
  .sev.high { color: #2a0b08; background: linear-gradient(135deg, #ff8b7f, #f87171); }
  .sev.medium { color: #3a2600; background: rgba(251, 191, 36, .8); }
  .sev.low { color: var(--txt); background: var(--surface-3); }
}

.msg-row { padding: 9px 2px; border-bottom: 1px dashed var(--line); font-size: 13.5px; line-height: 1.6; overflow-wrap: anywhere; word-break: break-word; }
.msg-row .who { font-size: 11px; color: var(--txt-2b); margin-right: 8px; }
.msg-row.hit { background: var(--danger-soft); border-radius: 8px; padding-left: 8px; }

/* ---------------- 弹层 / 提示 ---------------- */
.sheet { position: fixed; inset: 0; background: rgba(12, 14, 16, 0.5); display: flex; align-items: flex-end; z-index: 150; backdrop-filter: blur(3px); }
.sheet-panel {
  position: relative; width: 100%;
  border-radius: 26px 26px 0 0;
  background: var(--surface);
  box-shadow: 0 -20px 60px rgba(0, 0, 0, .28);
  border-top: 1px solid var(--line-strong);
  animation: sheetUp .26s cubic-bezier(.22, .8, .28, 1);
  overflow: hidden;
}
.sheet-close {
  position: absolute; top: 10px; right: 10px; width: 32px; height: 32px; border-radius: 50%;
  display: grid; place-items: center; color: var(--txt-2); background: var(--surface-3);
  border: 1px solid var(--line); z-index: 2;
}
.sheet-close svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
.sheet-close:active { color: var(--txt); background: var(--surface-2); }
.sheet-body {
  width: 100%; max-height: 86vh; overflow: auto; padding: 22px 18px calc(22px + var(--sab));
}
@keyframes sheetUp { from { transform: translateY(40px); opacity: .6; } to { transform: none; opacity: 1; } }
.sheet-body h3 { margin: 0 0 16px; padding-right: 40px; font-size: 16.5px; font-weight: 680; }

.toast {
  position: fixed; left: 50%; bottom: calc(136px + var(--sab)); transform: translateX(-50%) translateY(6px);
  background: #14181b; color: #fff;
  background: color-mix(in srgb, #14181b 92%, transparent);
  padding: 11px 18px; border-radius: var(--r-pill); font-size: 13px; z-index: 200;
  transition: opacity .22s, transform .22s; opacity: 0; pointer-events: none; max-width: 86vw;
  box-shadow: var(--shadow-2); border: 1px solid rgba(255, 255, 255, .08);
  text-align: center;
}
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }

.banner {
  display: flex; align-items: center; gap: 10px; padding: 10px 14px;
  font-size: 12.5px; color: #8a5a12;
  background: linear-gradient(100deg, rgba(214, 158, 46, 0.18), rgba(214, 158, 46, 0.06));
  border-bottom: 1px solid rgba(214, 158, 46, 0.22);
}
@media (prefers-color-scheme: dark) {
  .banner { color: #f3c775; background: linear-gradient(100deg, rgba(251, 191, 36, .16), rgba(251, 191, 36, .05)); }
}
.banner span { flex: 1; line-height: 1.45; }
.banner button {
  flex: 0 0 auto; padding: 6px 12px; border-radius: var(--r-pill); font-size: 12px; font-weight: 650;
  background: linear-gradient(135deg, #d69e2e, #b7791f); color: #fff;
  box-shadow: 0 4px 12px rgba(183, 121, 31, .3);
}

/* 表情面板 */
.emoji-panel {
  position: absolute; left: 10px; right: 10px; bottom: calc(64px + var(--sab));
  background: var(--surface); border: 1px solid var(--line-strong); border-radius: var(--r-lg); padding: 12px;
  /* 7 列而不是 8 列：每格从 43px 抬到 50px，手指点得准 */
  display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px; z-index: 20;
  box-shadow: var(--shadow-2); animation: rise .18s ease both;
}
.emoji-panel button { font-size: 21px; padding: 8px 0; min-height: 44px; border-radius: 10px; transition: background .14s, transform .14s; }
.emoji-panel button:active { background: var(--brand-soft); transform: scale(.9); }

/* 桌面版：居中一个"手机" */
@media (min-width: 760px) {
  #app {
    max-width: 460px; margin: 0 auto; height: calc(100% - 40px); top: 20px; bottom: 20px;
    border-radius: 30px; overflow: hidden;
    box-shadow: 0 30px 80px rgba(27, 26, 23, 0.28), 0 0 0 1px var(--line-strong);
  }
}
/* 横屏 / 极矮屏幕：压缩顶栏与底栏，保证内容区可用 */
@media (max-height: 560px) {
  .topbar { height: calc(46px + var(--sat)); }
  .topbar .title { font-size: 15px; }
  .nav { padding: 5px 10px calc(5px + var(--sab)); }
  .nav button { font-size: 10.5px; padding: 4px 0 3px; }
  .nav svg { width: 20px; height: 20px; }
  .composer { padding: 6px 8px calc(6px + var(--sab)); }
}

/* ---------------- 线性图标 ---------------- */
.icon-btn svg, .nav svg {
  width: 21px; height: 21px; fill: none; stroke: currentColor;
  stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round;
}
.icon-btn svg { width: 20px; height: 20px; }
.nav svg { width: 23px; height: 23px; }
.nav button.active svg { stroke-width: 2.05; }
.icon-btn.muted .wave { opacity: .25; }
.nav .ic { display: inline-flex; }

/* ============================================================
   悬浮按钮列 · 统一行为层（7 个自注入面板共用）
   规则只写"状态"不写"位置"：位置由各面板读 --fab-* 变量，
   这里只管：登录页不显示 / 面板打开时不可点 / 关掉后恢复。
   ============================================================ */

/* 1) 没登录就别在登录页上漂一排按钮 */
#login:not(.hide) ~ #vaultFab,
#login:not(.hide) ~ #inviteFab,
#login:not(.hide) ~ #opsFab,
#login:not(.hide) ~ #ownerFab,
#login:not(.hide) ~ #memFab,
#login:not(.hide) ~ #sysFab,
#login:not(.hide) ~ #costFab { display: none !important; }

/* 2) 任何弹层打开时，其他悬浮按钮一律不可点（不是被遮罩"吃掉"，是真的点不到） */
body.ui-overlay-open #vaultFab,
body.ui-overlay-open #inviteFab,
body.ui-overlay-open #opsFab,
body.ui-overlay-open #ownerFab,
body.ui-overlay-open #memFab,
body.ui-overlay-open #sysFab,
body.ui-overlay-open #costFab {
  pointer-events: none !important;
  opacity: 0 !important;
  visibility: hidden !important;
}

/* 3) 聊天页有输入区，整列往上让，别压住发送键 */
body.with-composer { --fab-lift: 56px; }

/* 4) 关闭按钮热区统一 ≥44×44（视觉上仍是个小 ×，靠 padding 撑热区） */
#sheetClose, #opsClose, #inviteClose, #ownClose, #memClose, #sysClose,
.vclose, .cclose, .ui-x {
  min-width: 44px;
  min-height: 44px;
  display: grid;
  place-items: center;
  box-sizing: border-box;
}

/* 5) 弹层层级统一：遮罩 400 / 提示 600 / 更新条 500 */
.sheet { z-index: var(--z-mask, 400); }
.toast { z-index: var(--z-toast, 600); }

/* 6) 弹层里的文字不要顶到关闭按钮下面 */
.sheet-body { padding-right: 18px; }

/* 7) 输入区热区统一到 ≥44×44（发送键原来 42 高、表情/图片 40×40） */
.composer .send { height: 44px; min-width: 64px; flex: 0 0 auto; }
.composer .round { width: 44px; height: 44px; flex: 0 0 44px; }
/* 小屏优先保住输入框宽度：图标按钮缩到刚好 44 */
@media (max-width: 360px) {
  .composer { gap: 6px; padding-left: 8px; padding-right: 8px; }
  .composer .send { min-width: 56px; }
}

/* 8) 矮屏（iPhone SE 568 / 横屏）：7 个按钮一列排不下，
      压缩按钮与间距，并把整列夹在顶栏和输入区之间，别顶到标题栏 */
@media (max-height: 700px) {
  :root { --fab-size: 44px; --fab-gap: 52px; --fab-base: 92px; }
  body.with-composer { --fab-lift: 44px; }
}