/* FONT-SCALED-2026-10-09 */
/* 青城管家 · PC 管理后台 */
:root {
  --brand: #2b6dff;
  --brand-dark: #1a54d6;
  --brand-deep: #123c9e;
  --brand-soft: #eaf1ff;
  --text: #101828;
  --text-2: #475467;
  --text-3: #98a2b3;
  --bg: #f4f6fb;
  --border: #e9edf3;
  --green: #12b76a;
  --green-soft: #e7f8f0;
  --orange: #f79009;
  --orange-soft: #fef4e6;
  --red: #f04438;
  --red-soft: #feeceb;
  --gray-soft: #f2f4f7;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html, body {
  height: 100%;
  font-family: "PingFang SC", "Microsoft YaHei", "Helvetica Neue", Arial, sans-serif;
  background: var(--bg);
  color: var(--text);
  font-size: 15px;
}

.hidden { display: none !important; }

/* ================= 登录页 ================= */
.auth-screen {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(150deg, #123c9e 0%, #1a54d6 55%, #2b6dff 100%);
  padding: 40px 16px;
}

.auth-wrap { width: 400px; max-width: 100%; }

.auth-brand { text-align: center; color: #fff; margin-bottom: 22px; }
.auth-logo { font-size: 44px; line-height: 1; filter: drop-shadow(0 4px 10px rgba(0,0,0,.25)); }
.auth-logo-img { width: 88px; height: 88px; border-radius: 22px; background: #fff; padding: 6px; box-sizing: border-box; object-fit: contain; }
.auth-name { font-size: 24px; font-weight: 700; margin-top: 10px; letter-spacing: 2px; }
.auth-sub { font-size: 14px; opacity: .85; margin-top: 6px; }

.auth-card {
  background: #fff;
  border-radius: 16px;
  padding: 26px 26px 22px;
  box-shadow: 0 18px 50px rgba(9, 30, 66, .35);
}

.auth-foot { text-align: center; color: rgba(255,255,255,.75); font-size: 13px; margin-top: 16px; }

/* 署名第二行：技术支持方，比主文案小一号、浅一号（两端署名保持一致） */
.auth-foot-sub { margin-top: 6px; font-size: 12px; color: rgba(255,255,255,.5); }

.auth-tabs { display: flex; gap: 4px; background: var(--gray-soft); border-radius: 10px; padding: 4px; margin-bottom: 20px; }
.auth-tab {
  flex: 1; text-align: center; padding: 8px 0; border-radius: 8px; cursor: pointer;
  font-size: 14px; color: var(--text-2); transition: all .15s; user-select: none;
}
.auth-tab.active { background: #fff; color: var(--brand); font-weight: 600; box-shadow: 0 1px 4px rgba(16,24,40,.1); }

.auth-pane-title { font-size: 18px; font-weight: 700; margin-bottom: 16px; }
.auth-pane-desc { font-size: 14px; color: var(--text-3); line-height: 1.7; margin-bottom: 16px; }

.auth-link { color: var(--brand); cursor: pointer; font-size: 14px; user-select: none; }
.auth-link:hover { text-decoration: underline; }

.auth-error {
  background: var(--red-soft); color: var(--red); border-radius: 8px;
  padding: 8px 12px; font-size: 14px; margin-top: 12px; line-height: 1.6;
}

/* ================= 表单元素 ================= */
.field { margin-bottom: 14px; }
.field-label { display: block; font-size: 14px; font-weight: 600; color: var(--text-2); margin-bottom: 6px; }
.field-required { color: var(--red); margin-left: 2px; }
/* 🔴 2026-10-09 由 #98a2b3 调深为 --text-2。
 *   原因：长 placeholder 从输入框**移到这里**显示（见 ui.js 的phTooLong 降级），
 *   它承载的是「怎么填这份表单」的关键说明，不再是可有可无的补充文字。
 *   #98a2b3 在白底上的对比度约 2.5:1，达不到 WCAG AA 的 4.5:1；
 *   --text-2(#475467) 约 7:1，长时间阅读不累。
 *   ⚠️ 不要改回 --text-3：这批文案原先被截断才挪下来，调淡等于问题重现。 */
.field-hint { font-size: 13px; color: var(--text-2); margin-top: 5px; line-height: 1.5; }
.field-hint.file-picked { color: var(--green); font-weight: 600; }

/* 登录页体验入口（方案 C：引导自助注册，2026-10-07）
   🔴 这几个类此前只存在于 HTML 里、CSS 从未定义 —— 展开后是裸排版。
      新增登录页元素时必须同步在这里加样式，否则表现为"样式全丢"。 */
.auth-demo { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--border); }
.auth-demo-toggle { display: inline-block; }
.auth-demo-panel {
  margin-top: 12px;
  padding: 14px 16px;
  border-radius: 10px;
  background: var(--brand-soft);
  border: 1px solid var(--border);
}
.auth-demo-title { font-size: 14px; font-weight: 500; margin-bottom: 8px; color: var(--brand-deep); }
.auth-demo-list { margin: 0 0 12px; padding-left: 18px; }
.auth-demo-list li { font-size: 13px; color: var(--text-2); line-height: 1.7; margin-bottom: 4px; }
.btn-demo { background: var(--brand); color: #fff; border-color: var(--brand); }
.btn-demo:hover { background: var(--brand-dark); border-color: var(--brand-dark); }

/* 多选复选框组（formModal 的 type: 'checks'） */
.check-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-bottom: 8px;
}
.check-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 8px 12px; }
.check-item {
  display: flex; align-items: center; gap: 8px; cursor: pointer;
  padding: 8px 10px; border: 1px solid var(--border); border-radius: 8px;
  font-size: 14px; color: var(--text-2); background: #fff; user-select: none;
}
.check-item:hover { border-color: var(--brand); }
.check-item input { width: 15px; height: 15px; accent-color: var(--brand); cursor: pointer; }

.input, .select, .textarea {
  width: 100%; border: 1px solid var(--border); border-radius: 8px;
  padding: 9px 12px; font-size: 15px; color: var(--text); background: #fff;
  outline: none; transition: border .15s, box-shadow .15s; font-family: inherit;
}
.input:focus, .select:focus, .textarea:focus { border-color: var(--brand); box-shadow: 0 0 0 3px rgba(43,109,255,.12); }
.textarea { resize: vertical; min-height: 84px; line-height: 1.6; }
.input-code { font-family: "SF Mono", Consolas, monospace; letter-spacing: 2px; }

.input-row { display: flex; gap: 8px; }
.input-row .input, .input-row .select { flex: 1; }
.input-row .btn-code { flex-shrink: 0; min-width: 108px; }
.btn-code[disabled] { opacity: .55; cursor: not-allowed; }

.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 16px; }
.form-grid .span-2 { grid-column: span 2; }

.switch-row { display: flex; align-items: center; gap: 10px; padding: 4px 0; }
.switch-row input { width: 17px; height: 17px; accent-color: var(--brand); cursor: pointer; }
.switch-row span { font-size: 15px; color: var(--text-2); }

/* ================= 按钮 ================= */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  border: 1px solid transparent; border-radius: 8px; padding: 9px 18px;
  font-size: 15px; cursor: pointer; font-family: inherit; transition: all .15s;
  background: var(--brand); color: #fff; white-space: nowrap;
}
.btn:hover { background: var(--brand-dark); }
.btn:active { transform: translateY(1px); }
.btn[disabled] { opacity: .55; cursor: not-allowed; }
.btn-block { width: 100%; }
.btn-sm { padding: 6px 12px; font-size: 14px; border-radius: 7px; }
.btn-ghost { background: #fff; color: var(--text-2); border-color: var(--border); }
.btn-ghost:hover { color: var(--brand); border-color: var(--brand); background: var(--brand-soft); }
.btn-danger { background: var(--red); }

/* 🔴 2026-10-09 撤回一次错误的修复。
 *
 * 当时判断「新增小区弹层只有右上角 × 能点」的根因是
 * "map-pick-mask 整套类在 CSS 里没定义"，于是补了一份到 style.css。
 *
 * ❌ **那个判断是错的**：这套样式**本来就存在**，在 `community-map.css:348-420`。
 * 我只 grep 了 style.css 就下了"从未定义"的结论，**没检查其他 CSS 文件**。
 *
 * 后果：两份定义同时生效。style.css 在 index.html 里后加载，
 * 它的 `z-index: 150` 覆盖了原文件的 `z-index: 400`，
 * 于是选点弹层被压在 `.modal-mask`(100) 之下 → **真正的点不动**。
 * 我修 bug 时制造了新 bug。
 *
 * 教训：断言"某东西不存在"之前，必须确认它的**查找范围是完整的**。
 * 同项目还有 community-map.css / demo-mode.css，
 * 只查一个文件就下结论，等于没查。
 * （scripts/verify-js-css-classes.js 第一版也犯了同样的错，
 *   误报 40+ 个类，第二版改成扫全部 3 个 CSS 文件才正确。）
 *
 * 完整的选点弹层样式见 community-map.css，不要在本文���件重复定义。
 */

/* ==========================================================================
   JS 在用但 CSS 从未定义的类（2026-10-09 补）
   ==========================================================================
   由 scripts/verify-js-css-classes.js 扫出来 —— 那个脚本是查
   「新增小区弹层点不动」时写的（我当时误判了根因）。

   这批是"缺样式只是没排版"，文字照常显示、按钮照常能点，
   所以一直没人报。分两次扫描得到：
     · 第一版只扫 style.css → 误报 40+ 个（实际在 community-map.css 里）
     · 修正为扫全部 3 个 CSS 文件后 → 真实的 11 个

   其中 .btn-primary / .tag / .row / .flex-1 影响面最大 ——
   门禁授权页、服务订单页都用它们，少了样式会让主按钮看起来像次要按钮。
   */
.btn-primary { background: var(--brand); color: #fff; }
.btn-primary:hover { background: var(--brand-dark); }

/* 横向 flex 行：大量页面用它做「左标签 + 右值」的两列排布 */
.row { display: flex; align-items: center; }
/* 弹性占位：把右侧内容推到最右（弹层头部、表单行的右对齐都靠它） */
.flex-1 { flex: 1; min-width: 0; }

/* 状态标签：服务订单等页面的状态列。配色与其他 .tag-* 变体保持一致 */
.tag {
  display: inline-flex; align-items: center; flex-shrink: 0;
  padding: 2px 8px; border-radius: 6px; font-size: 13px;
  background: var(--gray-soft); color: var(--text-2);
}
.tag-blue { background: var(--brand-soft); color: var(--brand); }

/* 表单必填标记与错误提示 */
.req { color: var(--red); margin-left: 2px; }
.form-error {
  background: var(--red-soft); color: var(--red);
  border-radius: 8px; padding: 8px 12px; font-size: 14px;
  margin-bottom: 12px; line-height: 1.6;
}

/* 加载中占位（账号中心等页面的异步块） */
.loading-block {
  padding: 32px; text-align: center;
  color: var(--text-3); font-size: 14px;
}

/* 结算总账页的小节标题（与 .dash-section-title 配套） */
.section-title { font-size: 15px; font-weight: 700; margin-bottom: 10px; }
/* 结算总账：欠款条目列表 */
.sl-owed-list { display: flex; flex-direction: column; gap: 8px; }
/* 通用统计行：左标签 + 右数值 */
.stat-row {
  display: flex; align-items: center; justify-content: space-between;
  padding: 8px 0; border-bottom: 1px solid var(--line);
}
.btn-danger:hover { background: #d92d20; }
.btn-danger-ghost { background: #fff; color: var(--red); border-color: #fda29b; }
.btn-danger-ghost:hover { background: var(--red-soft); border-color: var(--red); }
.btn-green { background: var(--green); }
.btn-green:hover { background: #0e9f5c; }
.btn-mini { padding: 4px 10px; font-size: 13px; border-radius: 6px; }

/* ================= 应用外壳 ================= */
.app-shell { display: flex; min-height: 100vh; }

/* ---------------- 侧栏（固定宽度，不可折叠） ----------------
 * 🔴 2026-10-09 **移除了折叠功能**（用户要求「改成不隐藏」）。
 *
 * 为什么彻底移除而不是修 bug：折叠态下 56px 侧栏的可用内容区只有
 *   56 - padding 14×2 = 28px，而折叠按钮本身就要 26px ——
 *   放按钮就得挤掉 logo，放不下就必然溢出、按钮被推出视野，
 *   于是「折叠按钮把自己折没了」，用户再也打不开侧栏。
 *   这是**几何上无解**的：折叠态的宽度设计从一开始就没算过按钮的位置。
 *
 * 教训：折叠类功能的最小宽度，必须先减去「恢复入口」本身的占位，
 *   再决定剩余空间能给内容多少 —— 恢复入口是最后的安全绳，
 *   不能靠"再调调 padding"凑出来。
 *
 * 若日后要重新支持折叠，最低要求：
 *   ① 折叠态隐藏 logo（否则按钮放不下）
 *   ② padding 收到 8px（内容区 28px → 40px）
 *   ③ 保留 Ctrl+B 之外再加一道 JS 兜底：按钮不可见时自动展开
 * 本次一并移除了 .side-toggle 按钮、Ctrl+B 快捷键与 localStorage 记忆。
 */
.sidebar {
  width: 224px; flex-shrink: 0; display: flex; flex-direction: column;
  background: linear-gradient(180deg, #123c9e 0%, #0e2f7a 100%);
  color: #fff; position: sticky; top: 0; height: 100vh; overflow-y: auto;
}

.side-brand {
  display: flex; align-items: center; gap: 10px; padding: 20px 14px 16px;
  font-size: 18px; font-weight: 700; letter-spacing: 1px;
  border-bottom: 1px solid rgba(255,255,255,.12);
  white-space: nowrap;
}
.side-logo { width: 28px; height: 28px; border-radius: 8px; background: #fff; padding: 2px; box-sizing: border-box; object-fit: contain; flex-shrink: 0; }

.side-nav { flex: 1; padding: 10px 12px 16px; }
.nav-group { margin-top: 14px; }
.nav-group-label { font-size: 12px; color: rgba(255,255,255,.45); padding: 0 10px 6px; letter-spacing: 1px; }

.nav-item {
  display: flex; align-items: center; gap: 10px; padding: 9px 10px; border-radius: 8px;
  color: rgba(255,255,255,.82); cursor: pointer; font-size: 15px; margin-bottom: 2px;
  transition: background .15s; user-select: none; position: relative;
  white-space: nowrap;
}
.nav-item:hover { background: rgba(255,255,255,.1); color: #fff; }
.nav-item.active { background: rgba(255,255,255,.16); color: #fff; font-weight: 600; }
.nav-item.active::before {
  content: ""; position: absolute; left: -12px; top: 8px; bottom: 8px; width: 3px;
  border-radius: 2px; background: #7db0ff;
}
.nav-icon { width: 20px; text-align: center; font-size: 16px; flex-shrink: 0; }

/* 角标：数字气泡（固定宽度侧栏下总能显示完整数字，不需要折叠态的小圆点变体） */
.nav-badge {
  margin-left: auto; background: #f79009; color: #fff; font-size: 12px;
  border-radius: 999px; padding: 1px 7px; font-weight: 600;
}

.side-foot { padding: 14px 18px; font-size: 12px; color: rgba(255,255,255,.35); }
.side-foot-sub { margin-top: 4px; font-size: 12px; color: rgba(255,255,255,.26); }

.main { flex: 1; min-width: 0; display: flex; flex-direction: column; }

.topbar {
  height: 60px; background: #fff; border-bottom: 1px solid var(--border);
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 24px; position: sticky; top: 0; z-index: 20;
}
.top-title { font-size: 20px; font-weight: 700; }
.top-right { display: flex; align-items: center; gap: 14px; }
.admin-chip {
  display: inline-flex; align-items: center; gap: 8px; font-size: 14px; color: var(--text-2);
  background: var(--gray-soft); border-radius: 999px; padding: 5px 14px;
}

.view { padding: 22px 24px 40px; max-width: 1280px; width: 100%; margin: 0 auto; }

/* ================= 通用组件 ================= */
.card {
  background: #fff; border-radius: 14px; border: 1px solid var(--border);
  padding: 18px 20px; margin-bottom: 18px;
}
.card-title { font-size: 16px; font-weight: 700; margin-bottom: 14px; display: flex; align-items: center; gap: 8px; }
.card-title .link { margin-left: auto; }

.toolbar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 16px; }
.toolbar .spacer { flex: 1; }
.toolbar .select, .toolbar .input { width: auto; min-width: 150px; }

.tabs { display: inline-flex; gap: 4px; background: var(--gray-soft); border-radius: 10px; padding: 4px; }
.tab {
  padding: 7px 18px; border-radius: 8px; cursor: pointer; font-size: 14px;
  color: var(--text-2); user-select: none; transition: all .15s;
}
.tab.active { background: #fff; color: var(--brand); font-weight: 600; box-shadow: 0 1px 4px rgba(16,24,40,.1); }

/* 统计卡 */
/* 迷你列表（进行中报修等） */
.mini-list { display: flex; flex-direction: column; }
.mini-row {
  display: flex; align-items: center; gap: 10px;
  padding: 11px 0; border-bottom: 1px solid var(--border);
}
.mini-row:last-child { border-bottom: none; }
.mini-main { min-width: 0; }
.mini-title { font-size: 14px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mini-sub { font-size: 13px; color: var(--text-3); margin-top: 3px; }


/* 表格 */
.table-wrap { overflow-x: auto; }
.table { width: 100%; border-collapse: collapse; }
.table th {
  text-align: left; font-size: 13px; color: var(--text-3); font-weight: 600;
  padding: 12px 14px; border-bottom: 1px solid var(--border); white-space: nowrap;
  background: #fafbfd;
}
.table td {
  padding: 14px; border-bottom: 1px solid var(--border); font-size: 14.5px;
  color: var(--text-2); vertical-align: middle;
}
.table tr:last-child td { border-bottom: none; }
.table tbody tr { transition: background .1s; }
.table tbody tr:hover { background: #f8faff; }
.table .actions { display: flex; gap: 8px; flex-wrap: wrap; }
.table .strong { color: var(--text); font-weight: 600; }
.table .sub { font-size: 13px; color: var(--text-3); margin-top: 2px; }

.empty-box { text-align: center; color: var(--text-3); padding: 44px 0; font-size: 14px; }
.empty-box .icon { font-size: 32px; margin-bottom: 10px; }

.loading-box { text-align: center; color: var(--text-3); padding: 60px 0; font-size: 14px; }

/* 状态徽标 */
.badge {
  display: inline-flex; align-items: center; border-radius: 999px;
  padding: 3px 10px; font-size: 13px; font-weight: 600; white-space: nowrap;
}
.badge-blue { background: var(--brand-soft); color: var(--brand); }
.badge-green { background: var(--green-soft); color: var(--green); }
.badge-orange { background: var(--orange-soft); color: #d97706; }
.badge-red { background: var(--red-soft); color: var(--red); }
.badge-gray { background: var(--gray-soft); color: var(--text-3); }
.badge-purple { background: #f4f0ff; color: #7a5af8; }

.mono { font-family: "SF Mono", Consolas, monospace; font-size: 13.5px; }

/* 分页 */
.pager { display: flex; align-items: center; justify-content: flex-end; gap: 10px; margin-top: 14px; font-size: 14px; color: var(--text-3); }
.pager .btn { min-width: 32px; padding: 5px 10px; }

/* 广告卡片 */
.ad-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 16px; }
.ad-card { background: #fff; border: 1px solid var(--border); border-radius: 14px; overflow: hidden; }
/* 图片是竖版广告（1280x2278），用 contain 完整显示整张，letterbox 处用卡片底色填充。
   不能用固定 height + cover —— 那会把竖图裁成只剩中间一条（用户反馈"只看到半张图"）。 */
.ad-img { width: 100%; height: auto; max-height: 520px; object-fit: contain; display: block; background: var(--gray-soft); }
.ad-img-empty {
  min-height: 200px; height: auto; display: flex; align-items: center; justify-content: center;
  color: var(--text-3); font-size: 13px; background: var(--gray-soft);
  text-align: center; padding: 24px 12px; word-break: break-all;
}
.ad-body { padding: 12px 14px 14px; }
.ad-name { font-weight: 700; font-size: 15px; display: flex; align-items: center; gap: 8px; }
.ad-meta { font-size: 13px; color: var(--text-3); margin-top: 5px; line-height: 1.6; word-break: break-all; }
.ad-actions { display: flex; gap: 6px; margin-top: 10px; flex-wrap: wrap; }

.img-preview {
  width: 100%; max-height: 160px; object-fit: contain; border-radius: 8px;
  border: 1px dashed var(--border); background: var(--gray-soft); margin-top: 6px;
}

/* 商家门头照 / 环境图缩略图 */
.mc-shots { display: flex; gap: 6px; flex-wrap: wrap; }
.mc-shot {
  width: 56px; height: 56px; object-fit: cover; border-radius: 8px; display: block;
  background: var(--gray-soft); border: 1px solid var(--border); cursor: zoom-in;
}
.mc-shot:hover { border-color: var(--brand); }
.mc-shot-empty { font-size: 13px; color: var(--text-3); }
.mc-loc { font-size: 13px; color: var(--text-2); line-height: 1.5; }
.mc-loc a { color: var(--brand); text-decoration: none; }
.mc-loc a:hover { text-decoration: underline; }
.mc-loc-empty { font-size: 13px; color: var(--red); }

/* 提示块 */
.tip-box {
  background: var(--brand-soft); border-radius: 10px; padding: 12px 16px;
  font-size: 14px; color: var(--brand-deep); line-height: 1.8; margin-bottom: 16px;
}
.tip-box b { font-weight: 700; }
.scene-chip {
  display: inline-flex; align-items: center; gap: 8px; background: #fff;
  border: 1px solid var(--border); border-radius: 8px; padding: 4px 10px;
  font-size: 13.5px;
}

/* ================= 弹窗 ================= */
/* 🔴 2026-10-07 重做弹窗高度约束（用户反馈「新增小区只有名称和关闭能点」）。
 *
 * 原来的写法有两个致命问题：
 *   ① `.modal-mask` 用 `align-items: flex-start` + 固定 `padding: 60px 16px 30px`
 *      → 弹窗永远顶在距顶 60px 处，**不垂直居中，也不保证整体可见**；
 *   ② `.modal-body` 的 `max-height: 62vh` 是**相对于视口**的固定比例，
 *      矮窗口（如 560px）时 62vh 只有 347px，**字段被裁在滚动区里**，
 *      露出的那点残缺区域点不动 → 用户看到「只有最上面的名称能点」。
 *
 * 改成「**弹窗整体不超视口，只有中间内容滚动**」：
 *   - mask 用 align-items: center + padding 20px（上下对称，弹窗垂直居中）
 *   - .modal 用 max-height: calc(100vh - 40px) + flex 列布局
 *   - .modal-head / .modal-foot 加 flex-shrink:0 → **标题栏与按钮永远可见可点**
 *   - .modal-body 用 flex:1 + min-height:0 → 唯一可滚动区域，且留出下边距
 */
.modal-mask {
  position: fixed; inset: 0; background: rgba(16,24,40,.5); z-index: 100;
  display: flex; align-items: center; justify-content: center;
  padding: 20px 16px; overflow: hidden;
  animation: fadeIn .15s ease;
}
.modal {
  background: #fff; border-radius: 16px; width: 520px; max-width: 100%;
  /* 🔴 整窗不超过视口：上下各留 20px */
  max-height: calc(100vh - 40px);
  /* 🔴 关键：改成列flex，让 body 成为唯一可伸缩滚动区 */
  display: flex; flex-direction: column;
  box-shadow: 0 24px 60px rgba(9,30,66,.3); animation: popIn .18s ease;
}
.modal.wide { width: 680px; }
.modal-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 18px 22px 0;
  /* 🔴 永不压缩 —— 否则标题栏会被挤没、×点不到 */
  flex: 0 0 auto;
}
.modal-title { font-size: 17px; font-weight: 700; }
.modal-close {
  border: none; background: var(--gray-soft); color: var(--text-3); width: 30px; height: 30px;
  border-radius: 8px; cursor: pointer; font-size: 16px; line-height: 1;
  flex-shrink: 0;
}
.modal-close:hover { background: var(--red-soft); color: var(--red); }
/* 🔴 唯一的滚动区：flex:1 + min-height:0（缺 min-height:0 不会真正收缩） */
.modal-body {
  padding: 16px 22px 4px; overflow-y: auto;
  flex: 1 1 auto; min-height: 0;
}
.modal-error { background: var(--red-soft); color: var(--red); border-radius: 8px; padding: 8px 12px; font-size: 14px; margin-bottom: 12px; line-height: 1.6; }
/* 🔴 底部按钮永不压缩、不被裁掉 */
.modal-foot {
  display: flex; justify-content: flex-end; gap: 10px;
  padding: 14px 22px 20px; flex: 0 0 auto;
}

/* 🔴 「下方还有内容」滚动提示（2026-10-07）。
   矮窗口下表单装不下时，字段藏在 .modal-body 的滚动区里，
   用户看不到就会以为「只有上面几个能点」。这条提示消除该误解。
   只在确实可滚动时由 JS 显示，滚到底自动淡出。 */
.modal-scroll-hint {
  flex: 0 0 auto;
  padding: 6px 0 2px;
  text-align: center;
  font-size: 13px;
  color: var(--text-3);
  background: linear-gradient(to bottom, rgba(255,255,255,0), #fff 55%);
  transition: opacity .18s ease;
  pointer-events: none;
  user-select: none;
}
.modal-scroll-hint[style*="display: none"] { display: none; }

/* 门禁管理弹窗内的分区（白名单 + 临时授权） */
.sub-block { border: 1px solid var(--border); border-radius: 12px; padding: 14px 16px; margin-bottom: 14px; background: #fbfcfe; }
.sub-block:last-child { margin-bottom: 0; }
.sub-title { font-size: 15px; font-weight: 700; color: var(--text); margin-bottom: 6px; }
.sub-tip { font-size: 13px; font-weight: 400; color: var(--text-3); margin-left: 8px; }
.perm-list { margin-top: 6px; }
.perm-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 0; border-top: 1px dashed var(--border); }
.perm-row:first-child { border-top: none; }
.perm-main { min-width: 0; }
.perm-scope { font-size: 15px; font-weight: 600; color: var(--text); }
.perm-expiry { font-weight: 400; color: var(--text-2); font-size: 14px; }
.perm-side { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
.perm-side .actions { display: flex; gap: 6px; }

@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes popIn { from { opacity: 0; transform: scale(.96) translateY(-8px); } to { opacity: 1; transform: none; } }

/* ================= Toast ================= */
/* ---- 全局 Toast ----
 * 🔴 2026-10-06 位置修复：原来 top:18px，而顶栏 .topbar 高60px 且是
 * sticky + z-index:20，toast 的 z-index:200 比它高 → 邻里圈「下架/恢复」
 * 等操作后，toast 直接压在顶栏上、把页面标题遮住（用户反馈的截图症状）。
 * 改为 top:76px = 顶栏高度 60 + 16 间距，落在顶栏下方不再遮挡。
 * ⚠️ 改topbar 高度时要同步改这里，否则会再次重叠。 */
.toast-wrap {
  position: fixed; top: 76px; left: 50%; transform: translateX(-50%);
  z-index: 200; display: flex; flex-direction: column; gap: 8px; align-items: center;
  pointer-events: none;
}
.toast {
  background: #101828; color: #fff; border-radius: 10px; padding: 10px 20px;
  font-size: 14.5px; box-shadow: 0 10px 30px rgba(9,30,66,.35);
  animation: toastIn .2s ease; max-width: 80vw;
  /* 纯提示，不拦截点击（否则透明容器会挡住下方按钮） */
  pointer-events: none;
}
.toast.err { background: var(--red); }
.toast.ok { background: #101828; }
@keyframes toastIn { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: none; } }

/* ================= 角色权限（2026-10-09 按账号中心分类分组） =================
 * 原来是一坨平铺卡片，只能看出顺序、看不出「这几个是一类」。
 * 现在按 ROLE_GROUPS 分组，组标题的措辞与账号中心 ACC_TABS 对齐。
 */

.rp-wrap { display: flex; flex-direction: column; gap: 18px; }

.rp-group { }

/* 组标题：名称 + 说明 + 数量，横向一行 */
.rp-group-head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-bottom: 10px;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--border);
}
.rp-group-name { font-size: 15px; font-weight: 700; color: var(--text); }
.rp-group-desc { font-size: 13px; color: var(--text-3); }
/* 数量右对齐，方便扫一眼就知道这组有几个角色 */
.rp-group-count { margin-left: auto; font-size: 13px; color: var(--text-3); }

/* 兜底区（自定义角色）用虚线左边框，与正式分组区分开 */
.rp-group-rest .rp-group-head { border-bottom-style: dashed; }

.rp-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 12px;
}

.rp-card { margin: 0; padding: 14px 16px; }

/* 权限点徽章区：行高留足，避免多行徽章把卡片撑得过高 */
.rp-perms {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 10px;
  line-height: 1.8;
}

.rp-ops { display: flex; gap: 8px; }

/* 页尾说明：交代账号中心那 3 类不是角色的账号 */
.rp-note {
  font-size: 13px;
  color: var(--text-3);
  line-height: 1.8;
  background: var(--bg-soft);
  border-radius: 8px;
  padding: 12px 14px;
}
.rp-note b { color: var(--text-2); }

/* ================= 结算总账（2026-10-09 重设计：一句话口径 + 三个关键数 + 谁欠多少） =================
 * 原版有 4 张数字卡 + 「钱是怎么分的」流程图 + 待打款对象 + 各业务占比，
 * 同一笔钱被叙述4 遍，运营要跨区块对账。现改为每个数字只出现一次。
 */

/* 打不出去的账：唯一用红色的区块，因为它需要人立刻动手 */
.sl-alert { padding: 14px 18px; margin-bottom: 14px; border-left: 3px solid #e5484d; background: #fff5f5; }
.sl-alert-t { font-size: 15px; font-weight: 600; color: #e5484d; }
.sl-alert-n { margin-top: 6px; font-size: 13px; color: var(--text-2); line-height: 1.7; }

/* 三段式关键数：收 → 平台留→ 欠。用「→」分段而不是四张卡，一眼看出钱的流向 */
.sl-key { display: flex; align-items: stretch; gap: 0; margin-bottom: 8px; flex-wrap: wrap; }
.sl-key-cell {
  flex: 1 1 200px; margin: 0; padding: 14px 18px;
  background: var(--bg-soft); border: 1px solid var(--border); border-radius: 10px;
}
.sl-key-own { background: #eaf4ff; border-color: #cfe4ff; }
/* 有未打款时这张卡描边加重 —— 页面唯一需要「行动」的数 */
.sl-key-wait { background: #fffaf0; border-color: #f0b429; }
.sl-key-op {
  align-self: center; padding: 0 10px; font-size: 13px; color: var(--text-3); white-space: nowrap;
}
.sl-key-k { font-size: 14px; color: var(--text-2); }
.sl-key-v { font-size: 22px; font-weight: 600; margin: 4px 0 2px; }
.sl-key-t { font-size: 13px; color: var(--text-3); }
.sl-note { font-size: 13px; color: var(--text-3); line-height: 1.7; margin-bottom: 14px; }

/* 谁还欠多少钱：表格化，不用卡片 —— 每行一个对象，扫一眼就知道谁欠多少 */
.sl-owed { padding: 0; margin-bottom: 14px; overflow: hidden; }
.sl-owed-head {
  display: flex; align-items: baseline; justify-content: space-between;
  padding: 13px 18px; border-bottom: 1px solid var(--border); flex-wrap: wrap; gap: 6px;
}
.sl-owed-title { font-size: 14px; font-weight: 600; }
.sl-owed-sub { font-size: 13px; color: var(--text-3); }
.sl-owed-row {
  display: grid; grid-template-columns: minmax(90px, 1.1fr) 88px minmax(140px, 2fr) 110px;
  gap: 10px; align-items: center; padding: 11px 18px; border-bottom: 1px solid var(--border);
}
.sl-owed-row:last-child { border-bottom: 0; }
.sl-owed-row.is-missing { background: #fffaf0; }
.sl-owed-no { font-size: 14px; font-weight: 600; }
.sl-owed-role { font-size: 13px; color: var(--text-3); }
.sl-owed-meta { font-size: 13px; color: var(--text-3); }
.sl-owed-meta b { color: #e5484d; font-weight: 600; }
.sl-owed-amt { font-size: 16px; font-weight: 600; text-align: right; }
@media (max-width: 900px) {
  .sl-owed-row { grid-template-columns: 1fr 1fr; }
  .sl-owed-meta { grid-column: 1 / -1; }
}

/* ---------------- 邻里圈管理（views-neighbor.js） ---------------- */

.nb-pc-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* 🔴 2026-10-09：待审帖左侧描边加重 —— 待审是这个页面唯一有时效的动作，
   滚到列表中间时靠颜色就能认出哪几条还没处理，不必逐条读状态徽章。 */
.nb-pc-item {
  padding: 14px 16px;
  border-left: 3px solid transparent;
}

.nb-pending {
  border-left-color: #f0b429;
  background: #fffdf7;
}

.nb-pc-head {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.nb-pc-content {
  margin-top: 8px;
  font-size: 14px;
  line-height: 1.7;
  color: var(--text-1);
  white-space: pre-wrap;
  word-break: break-word;
}

/* 帖子数据取不到时的占位（区别于「帖子真的被删了」） */
.nb-pc-missing { color: var(--text-3); font-style: normal; }

/* 状态筛选按钮组（取代原<select>，待审永远排第一并带条数） */
.nb-stabs {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}

.nb-stab {
  font-size: 14px;
  padding: 5px 12px;
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--text-2);
  cursor: pointer;
  user-select: none;
}

.nb-stab:hover { border-color: var(--brand); }

.nb-stab-on {
  background: var(--brand);
  border-color: var(--brand);
  color: #fff;
}

.nb-pc-shots {
  margin-top: 10px;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.nb-pc-shots img {
  width: 84px;
  height: 84px;
  object-fit: cover;
  border-radius: 8px;
  background: #f1f3f7;
}

.nb-pc-ops {
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
  display: flex;
  gap: 8px;
}

/* 邻里圈：帖子/举报 Tab + 举报理由块（views-neighbor.js） */

.nb-tabs {
  display: flex;
  gap: 8px;
}

.nb-pc-meta {
  font-size: 13px;
  color: var(--text-3);
}

.nb-pc-reason {
  margin-top: 8px;
  font-size: 13.5px;
  color: var(--red);
  background: var(--red-soft);
  border-radius: 6px;
  padding: 6px 10px;
}

/* ---------------- 会员与积分管理（views-members.js） ---------------- */

/* 会员列表用紧凑表格：一行一人，会员上千条也能一屏看完并横向对比。
   .mb-addr 用省略号截断长地址，完整内容放 title 属性悬停可见。 */
.mb-addr {
  display: block;
  max-width: 230px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ============ 全局默认模块面板（2026-10-06 由弹窗改为页内） ============ */
/* 只给超管看：平台级配置，一改影响所有小区 */
.gmp-card {
  margin-bottom: 18px;
  border-left: 4px solid #7a5af8;
}

.gmp-card .card-title .sub {
  font-weight: 400;
  margin-left: 4px;
}

.gmp-card .card-title .link {
  margin-left: auto;
}

/* 分组分段后必须单列（2026-10-08）
   原来是两列 grid 平铺 19 个模块 —— 分组后若仍用 grid，各组的标题会被
   挤到同一个网格里，段落关系全乱。改成单列 + 分组之间留白，层级才清楚。 */
.gmp-body {
  display: block;
}

/* 每个分组一块，带浅底色与左侧色条，便于快速扫读 */
.gmp-group {
  margin-bottom: 18px;
  padding: 12px 14px;
  border-radius: 10px;
  background: var(--gray-soft);
}

.gmp-group:last-of-type {
  margin-bottom: 8px;
}

.gmp-group-head {
  display: flex;
  align-items: baseline;
  gap: 10px;
}

.gmp-group-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
}

.gmp-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 10px;
  border-radius: 8px;
  cursor: pointer;
  transition: background .12s;
}

.gmp-row:hover {
  background: var(--gray-soft);
}

.gmp-row input {
  width: 16px;
  height: 16px;
  cursor: pointer;
  flex-shrink: 0;
}

.gmp-icon {
  font-size: 16px;
  flex-shrink: 0;
}

.gmp-label {
  font-size: 14px;
  color: var(--text-2);
}

.gmp-row .badge {
  margin-left: auto;
}

.gmp-actions {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}

/* ======================================================================
   工作台（2026-10-06 第二次重做：以功能优先，压缩纵向空间）
   设计取向：**功能性 > 展示美观**
   - 每一块的信息密度优先：数字排成一行，不为每组信息单独开一张卡
   - 0 值不额外占高度（仍显示，避免被误认为漏统计）
   - 只有「需要你操作的东西」才用卡片承载
   ====================================================================== */

/* ---- 问候条：从 100px 渐变大卡压成单行 ---- */
.dash-hello {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 0 2px 12px; margin-bottom: 4px;
  border-bottom: 1px solid var(--border);
  color: var(--text-2);
}
.dash-hello-text { font-size: 16px; font-weight: 700; color: var(--text); }
.dash-hello-dot { color: var(--text-3); }
.dash-hello-meta { font-size: 14px; color: var(--text-3); }
/* 角色关注点：仍然保留（功能性信息：告诉角色「这页为你定制」），但改成小字标签 */
.dash-hello-focus {
  padding: 2px 10px;
  background: var(--brand-soft); color: var(--brand);
  border-radius: 999px; font-size: 13px;
}

/* ---- 区块标题：更紧凑（原来 16px+12px 下边距，占两行）---- */
.dash-section { margin-bottom: 16px; }
.dash-section-head {
  display: flex; align-items: baseline; gap: 8px; margin-bottom: 8px;
}
.dash-section-title { font-size: 15px; font-weight: 700; color: var(--text); }
.dash-section-sub { font-size: 13px; color: var(--text-3); }

/* 🔴 2026-10-09 工作台待办改为置顶分组卡片（renderTodoFirst）。
   原来的 .todo-mini-*（平铺清单）与 .todo-stream/.todo-chip（徽标流）
   随旧实现一并移除，见 js/views-core.js 顶部的历史说明。 */

/* ---- 待办分组卡：每组一块，组内每项一格 ---- */
.todo-groups {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 12px;
}
.todo-group {
  margin: 0;
  padding: 14px 16px;
  /* 左描边用组色调：扫一屏就能按颜色分清审核/物业/商业/门禁 */
  border-left: 3px solid var(--border);
}
.todo-audit { border-left-color: #f0b429; }
.todo-property { border-left-color: #4a8cff; }
.todo-business { border-left-color: #7a5af8; }
.todo-access { border-left-color: #12b5a5; }

.todo-group-head { display: flex; align-items: center; gap: 8px; }
.todo-group-icon { font-size: 16px; }
.todo-group-name { font-size: 15px; font-weight: 700; color: var(--text); }
/* 组合计放右上角最大号：这是运营决定「先处理哪组」的依据 */
.todo-group-total {
  margin-left: auto; font-size: 22px; font-weight: 800; color: var(--text);
}
.todo-group-desc { margin-top: 2px; font-size: 13px; color: var(--text-3); line-height: 1.6; }

.todo-group-items {
  margin-top: 10px;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.todo-cell {
  flex: 1 1 118px;
  display: flex;
  align-items: baseline;
  gap: 6px;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  cursor: pointer;
  transition: background .12s, border-color .12s;
}
.todo-cell:hover { background: var(--brand-soft); border-color: var(--brand); }
.todo-cell-num { font-size: 18px; font-weight: 800; color: var(--brand); }
.todo-cell-label {
  flex: 1; min-width: 0; font-size: 13px; color: var(--text-2);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.todo-cell-go { font-size: 14px; color: var(--text-3); }

/* 没有待办时的确认态：给一句肯定的话，而不是空白 */
.todo-done {
  display: flex; align-items: center; gap: 8px;
  padding: 18px 20px; font-size: 14px; color: var(--text-3);
}
.todo-done-icon {
  width: 22px; height: 22px; border-radius: 50%;
  background: #e8f6ee; color: #1a9d5c;
  display: flex; align-items: center; justify-content: center;
  font-size: 14px; font-weight: 700;
}

/* ---- 平台概况：规模类指标（最后一屏右栏）---- */
.scale-list { display: flex; flex-direction: column; }
.scale-row {
  display: flex; align-items: baseline; justify-content: space-between;
  padding: 9px 0; border-bottom: 1px solid var(--border);
}
.scale-row:last-child { border-bottom: none; }
.scale-label { font-size: 14px; color: var(--text-2); }
.scale-value { font-size: 17px; font-weight: 700; color: var(--text); }
.scale-value.warn { color: var(--orange); }
.scale-note {
  margin-top: 10px; font-size: 13px; color: var(--orange);
  background: #fffaf0; border-radius: 6px; padding: 8px 10px; line-height: 1.6;
}
/* ---- 关键指标：一行数字条。
   2026-10-09 从 7 项收敛到 4 项：原来混入了「门禁设备总数 / 注册会员 / 在岗管家」
   这类几乎不变的规模数，占了半行却不会让人行动；规模类已移到底部「平台概况」。---- */
.stat-bar {
  display: flex; flex-wrap: wrap;
  background: #fff; border: 1px solid var(--border); border-radius: 10px;
  overflow: hidden;
}
.stat-bar-item {
  flex: 1 1 auto; min-width: 96px;
  display: flex; align-items: baseline; gap: 6px;
  padding: 9px 14px;
  border-right: 1px solid var(--border);
  cursor: pointer; transition: background .12s;
}
.stat-bar-item:last-child { border-right: none; }
.stat-bar-item:hover { background: var(--brand-soft); }
.stat-bar-num { font-size: 21px; font-weight: 800; color: var(--text); }
.stat-bar-num.warn { color: var(--orange); }
.stat-bar-num.bad { color: var(--red); }
.stat-bar-label { font-size: 13px; color: var(--text-3); }
@media (max-width: 900px) {
  .stat-bar-item { min-width: 33.33%; border-bottom: 1px solid var(--border); }
}

/* ---- 经营概览：一行金额条（原来 4 张卡 + 一段说明文字）---- */
.money-bar {
  display: flex; align-items: stretch; flex-wrap: wrap;
  background: #fff; border: 1px solid var(--border); border-radius: 10px;
  overflow: hidden;
}
.money-item {
  flex: 1 1 auto; min-width: 140px;
  display: flex; flex-direction: column; gap: 2px;
  padding: 10px 16px;
  border-right: 1px solid var(--border);
}
.money-value { font-size: 20px; font-weight: 800; color: var(--brand); }
.money-value.purple { color: #7a5af8; }
.money-value.orange { color: var(--orange); }
.money-label { font-size: 13px; color: var(--text-3); }
.money-go {
  display: flex; align-items: center; padding: 0 14px;
  font-size: 13px; color: var(--text-3); cursor: pointer; white-space: nowrap;
}
.money-go:hover { color: var(--brand); background: var(--brand-soft); }

/* ---- 动态区：四张卡排成两列（原来四个独立块纵向堆叠）---- */
.dash-cols {
  display: grid; grid-template-columns: 1fr 1fr; gap: 14px;
}
@media (max-width: 1080px) { .dash-cols { grid-template-columns: 1fr; } }
/* ---------------- 开门方式分布统计条（2026-10-09，四种开门方式） ----------------
   放在筛选栏与表格之间。做成可点击的 chip 而不是纯数字：
   运营看到「蓝牙 0 次」时，直接点一下就知道是筛出来的还是真没有。 */
.dl-method-stat {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 10px 14px; margin-bottom: 12px;
  background: #fff; border: 1px solid var(--border); border-radius: 10px;
}
.dl-ms-label { font-size: 13px; color: var(--text-3); margin-right: 2px; }
.dl-ms-chip {
  display: inline-flex; align-items: baseline; gap: 6px;
  padding: 5px 11px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--border); background: #f7f9fc;
  font-size: 13px; color: var(--text-2);
  transition: background .15s, border-color .15s;
}
.dl-ms-chip:hover { background: #eef3fb; border-color: #b9cdf0; }
/* 选中态用蓝底而不是加粗 —— 加粗会让所有 chip 的字重都变化，视觉噪音大 */
.dl-ms-chip.on { background: var(--brand, #2b6dff); border-color: var(--brand, #2b6dff); color: #fff; }
.dl-ms-chip.on .dl-ms-name,
.dl-ms-chip.on .dl-ms-pct { color: #fff; }
.dl-ms-name { color: var(--text-1); }
.dl-ms-num { font-size: 15px; font-weight: 600; }
/* 失败数用红字提示，不做成大段文字 —— 它是异常，不是主体信息 */
.dl-ms-fail {
  font-size: 12px; color: #e5484d;
  padding-left: 4px; border-left: 1px solid rgba(0, 0, 0, .12);
}
.dl-ms-chip.on .dl-ms-fail { color: #ffd7d9; border-left-color: rgba(255, 255, 255, .4); }
/* ⚠️ 这三处原本写11px，违反了本项目「最小 12px」的约定
   （2026-10-07 全体放大字号时定的，校验脚本 verify-pc-font-nav 断言这条）。
   校验脚本本轮才把它抓出来 —— 说明新增样式时容易忘了这个约定。 */
.dl-ms-pct { font-size: 12px; color: var(--text-3); }
.dl-ms-note { font-size: 12px; color: var(--text-3); margin-left: auto; }

/* ---- 近期开门记录：紧凑行列表（2026-10-06，从 5 列表格改来）---- */
/* 表格在这个卡片宽度下日期折行、操作人竖排、设备名把列宽挤扁 → 改「流水」式单行。 */
.log-list { display: flex; flex-direction: column; }
.log-row {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 0; border-bottom: 1px solid var(--border);
  font-size: 14px;
}
.log-row:last-child { border-bottom: none; }
/* 状态点：一眼看成功失败，比文字列「成功/失败」省地方 */
.log-dot {
  flex-shrink: 0; width: 7px; height: 7px; border-radius: 50%;
  background: var(--red);
}
.log-dot.ok { background: var(--green); }
.log-who { flex-shrink: 0; font-weight: 600; color: var(--text); }
.log-device {
  flex: 1; min-width: 0; color: var(--text-2);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.log-meta { flex-shrink: 0; font-size: 13px; color: var(--text-3); }
.log-time { flex-shrink: 0; font-size: 13px; color: var(--text-3); min-width: 78px; text-align: right; }

/* ---- 本月收入排行（2026-10-06 从账号中心搬进工作台，取代快捷入口）---- */
/* 排行榜是「谁赚得最多」，经营信息里最值得一眼看到的一项，之前藏在账号中心要点两下。 */
.rank-card { display: flex; flex-wrap: wrap; padding: 0; overflow: hidden; }
.rank-col {
  flex: 1 1 50%; min-width: 260px;
  padding: 6px 0;
  border-right: 1px solid var(--border);
}
.rank-col:last-child { border-right: none; }
.rank-col-head {
  display: flex; align-items: center; gap: 7px;
  padding: 10px 16px 7px;
  font-size: 14px; font-weight: 700; color: var(--text-2);
  border-bottom: 1px solid var(--border);
}
/* 栏标题必须自带主体（🧑‍💼服务管家 / 🏪商家），否则分不清是哪张榜 */
.rank-col-icon { flex-shrink: 0; font-size: 15px; }
.rank-col-title { display: flex; align-items: baseline; gap: 6px; min-width: 0; }
.rank-col-sub { font-style: normal; font-size: 12px; font-weight: 400; color: var(--text-3); }
.rank-col-head .link { margin-left: auto; font-size: 13px; font-weight: 400; flex-shrink: 0; }
.rank-row {
  display: flex; align-items: center; gap: 9px;
  padding: 7px 16px; cursor: pointer; transition: background .12s;
}
.rank-row:hover { background: var(--brand-soft); }
/* 前三名用金色名次，其余灰色 —— 一眼分出头部 */
.rank-no {
  flex-shrink: 0; width: 18px; height: 18px; border-radius: 9px;
  background: #f2f4f8; color: var(--text-3);
  font-size: 12px; font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center;
}
.rank-no.top { background: #fef3e2; color: #d97706; }
.rank-name {
  flex: 1; min-width: 0; font-size: 14px; color: var(--text-2);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.rank-orders { flex-shrink: 0; font-size: 13px; color: var(--text-3); }
.rank-income { flex-shrink: 0; font-size: 14px; font-weight: 700; color: var(--brand); min-width: 74px; text-align: right; }
.rank-empty { padding: 16px; font-size: 14px; color: var(--text-3); }

/* 🔴 2026-10-09 删除：.todo-mini-* （旧「待办与提醒」平铺清单）。
   待办已改为置顶的分组卡片，见本文件上方 .todo-groups 区块。 */

/* ================= 🔴 2026-10-11 工作台视觉升级（覆盖层） =================
   设计语言与小程序端统一：问候横幅渐变化 + 待办卡片带色块图标 + 指标大字重。
   追加同名类定义实现覆盖，不改 views-core.js 任何结构与逻辑。 */

/* 问候横幅：品牌渐变横幅替代原来的分隔线形式 */
.dash-hello {
  background: linear-gradient(120deg, #0f2a52 0%, #1d5fbf 100%);
  border-radius: 12px;
  padding: 18px 22px;
  margin-bottom: 14px;
  border-bottom: none;
  color: rgba(255, 255, 255, 0.92);
  box-shadow: 0 4px 14px rgba(15, 42, 82, 0.25);
}

.dash-hello-text {
  font-size: 20px;
  font-weight: 700;
  color: #ffffff;
}

.dash-hello-dot,
.dash-hello-meta {
  color: rgba(255, 255, 255, 0.75);
}

.dash-hello-focus {
  background: rgba(255, 215, 122, 0.25);
  color: #ffd77a;
  border-radius: 999px;
  padding: 3px 12px;
  font-weight: 600;
}

/* 待办数字强调：待办卡片里数字用主题色大字 */
.stat-bar {
  border-radius: 12px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
  border: none;
}

.stat-bar-item {
  cursor: pointer;
  transition: background 0.15s ease;
  padding: 12px 10px;
  border-right: 1px solid var(--border-tertiary, #eef0f4);
}

.stat-bar-item:last-child { border-right: none; }

.stat-bar-item:hover { background: #f0f5ff; }

/* 分区标题：左侧色条 */
.dash-section-title {
  position: relative;
  padding-left: 12px;
}

.dash-section-title::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 4px;
  height: 16px;
  border-radius: 999px;
  background: #1d5fbf;
}

/* 卡片统一圆角阴影 */
.dash-section .card,
.dash-cols .card {
  border-radius: 12px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
  border-color: transparent;
}

/* 🔴 2026-10-11 账号切换辅助样式 */
.recent-chips {
  display: flex; gap: 8px; flex-wrap: wrap; margin-top: 8px;
}

.recent-chip {
  font-size: 13px; color: var(--text-2);
  background: #f0f5ff; border: 1px solid #c9d8f5;
  border-radius: 999px; padding: 4px 12px;
  cursor: pointer; transition: all 0.15s ease;
}

.recent-chip:hover { background: #1d5fbf; color: #fff; border-color: #1d5fbf; }

/* 顶栏身份切换下拉 */
.id-switch-menu {
  position: fixed; z-index: 3000;
  background: #fff; border: 1px solid var(--border);
  border-radius: 12px; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
  padding: 6px; min-width: 220px;
}

.id-switch-item {
  display: flex; flex-direction: column; gap: 2px;
  padding: 10px 14px; border-radius: 8px; cursor: pointer;
}

.id-switch-item:hover { background: #f0f5ff; }

.id-switch-item-on { background: #f0f5ff; }

.id-switch-item .sub { font-size: 12px; color: var(--text-3); }

.id-switch-caret {
  cursor: pointer; font-size: 13px; color: var(--text-2);
  padding: 2px 6px; border-radius: 6px;
}

.id-switch-caret:hover { background: #f0f5ff; }

/* ================= 🔴 2026-10-11 角色主题强调色（用户要求） =================
   body.role-<role_key> 由 auth.js enterApp 挂载。各角色 --accent 驱动
   问候横幅渐变、分区色条、身份徽标等，实现「不同角色不同主题」。 */

body { --accent: #1d5fbf; --accent-deep: #0f2a52; }        /* 默认（超管）：品牌蓝 */

body.role-agent { --accent: #059669; --accent-deep: #064e3b; }          /* 代理：翠绿 */
body.role-project_admin { --accent: #0e7490; --accent-deep: #155e63; }  /* 项目管理员：青 */
body.role-project_operator { --accent: #0e7490; --accent-deep: #155e63; }
body.role-biz_ops { --accent: #ea580c; --accent-deep: #7c2d12; }        /* 商业服务：琥珀橙 */
body.role-courier_manager { --accent: #6d28d9; --accent-deep: #4c1d95; }/* 管家调度：紫 */

/* 问候横幅按角色变色 */
body.role-agent .dash-hello {
  background: linear-gradient(120deg, #064e3b 0%, #059669 100%);
  box-shadow: 0 4px 14px rgba(6, 78, 59, 0.25);
}

body.role-project_admin .dash-hello,
body.role-project_operator .dash-hello {
  background: linear-gradient(120deg, #155e63 0%, #0891b2 100%);
  box-shadow: 0 4px 14px rgba(21, 94, 99, 0.25);
}

body.role-biz_ops .dash-hello {
  background: linear-gradient(120deg, #7c2d12 0%, #ea580c 100%);
  box-shadow: 0 4px 14px rgba(124, 45, 18, 0.25);
}

body.role-courier_manager .dash-hello {
  background: linear-gradient(120deg, #4c1d95 0%, #7c3aed 100%);
  box-shadow: 0 4px 14px rgba(76, 29, 149, 0.25);
}

/* 分区色条跟随角色强调色 */
.dash-section-title::before { background: var(--accent); }

/* 🔴 2026-10-11 修正：侧栏选中态与身份徽标**不能**用 accent 当文字/底色 ——
   侧栏是深色底、徽标在深色顶栏上，设成同系深色后文字几乎看不见（用户反馈"选择后字体太暗"）。
   侧栏只保留左边框高亮；徽标改白底 + 主题色字，任何主题下都清晰。 */
.sidebar a.active,
.sidebar .nav-item.active {
  border-left-color: var(--accent);
}

.admin-chip .badge {
  background: rgba(255, 255, 255, 0.94) !important;
  color: var(--accent) !important;
}

/* 🔴 2026-10-11 弹窗宽度体系升级：wide 680→760，新增 xl 940（超长表单）
   小程序内嵌的 form-group 两列布局在 xl 下更从容 */
.modal.wide { width: 760px; }
.modal.wide.xl { width: 940px; }

.modal.wide.xl .form-group {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

/* 🔴 2026-10-11 表单分区标题（设备表单 xl 重排配套） */
.form-sec {
  font-size: 13px; font-weight: 700; color: var(--accent-deep, #0f2a52);
  background: #f0f5ff; border-radius: 8px;
  padding: 6px 12px; margin: 6px 0 2px;
}

/* 🔴 2026-10-11 会员与积分搜索框加大（用户要求） */
.mb-search {
  width: 380px;
  max-width: 60vw;
  height: 38px;
  font-size: 14px;
}

/* 🔴 2026-10-11 切换账号/身份按钮：显眼化（主题蓝边框 + 主题色文字） */
.id-switch-btn {
  border: 1px solid var(--accent, #1d5fbf) !important;
  color: var(--accent, #1d5fbf) !important;
  background: #fff !important;
  font-weight: 600;
  margin-left: 8px;
}

.id-switch-btn:hover {
  background: var(--accent, #1d5fbf) !important;
  color: #fff !important;
}

/* 🔴 2026-10-11 业主操作按钮颜色区分（用户要求）：门禁权限=蓝 / 联系人=灰 / 到期时间=橙
   （解绑沿用既有 btn-danger-ghost 红色），房号以浅灰小标签单独展示 */
.btn-op-blue { background: #eef4ff !important; color: #1d5fbf !important; border: 1px solid #c9d8f5 !important; }
.btn-op-blue:hover { background: #1d5fbf !important; color: #fff !important; }
.btn-op-gray { background: #f4f5f7 !important; color: #52596b !important; border: 1px solid #dcdfe6 !important; }
.btn-op-gray:hover { background: #52596b !important; color: #fff !important; }
.btn-op-orange { background: #fff7ed !important; color: #c2410c !important; border: 1px solid #fed7aa !important; }
.btn-op-orange:hover { background: #c2410c !important; color: #fff !important; }

.house-op-group { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-bottom: 4px; }
.house-op-tag {
  font-size: 12px; color: #6b7280; background: #f3f4f6;
  border-radius: 999px; padding: 2px 10px; font-weight: 600;
}

/* 🔴 2026-10-11 设备能力等开关字段：卡片化 + 说明文字小字分行（用户反馈"这个地方乱"）
   原因：多个 switch 字段两列并排时，checkbox 紧贴长说明文字，折行参差不齐。 */
.switch-row {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 10px 12px; border: 1px solid var(--border); border-radius: 10px;
  background: #fafbfc; line-height: 1.55;
}
.switch-row:hover { border-color: var(--brand); background: #f6f9ff; }
.switch-row input[type="checkbox"] {
  margin-top: 2px; flex: 0 0 auto; width: 16px; height: 16px; accent-color: var(--brand); cursor: pointer;
}
.switch-row span { font-size: 13px; color: var(--text-2); }

/* 开关类字段的网格（设备能力区）间距加大，卡片之间有呼吸感 */
.form-grid .switch-row, .modal-body .switch-row { margin-bottom: 2px; }

/* 🔴 2026-10-11 业主列表「绑定房屋 / 到期时间」每套房独立一行（用户反馈两套挤在一起不舒服） */
.house-line {
  padding: 4px 0;
  line-height: 1.6;
  border-bottom: 1px dashed #f0f2f6;
}
.house-line:last-child { border-bottom: none; }
.house-line:hover { color: var(--brand); }

/* 操作列按钮组：与上方房屋行对齐，行间留白 */
.house-op-group { padding: 4px 0; }
