/* ==========================================================================
   配色系统（iOS 风格，浅色毛玻璃）
   三套皮肤靠 body[data-theme] 切换，所有下面的样式规则都只认这些变量，
   不直接写死颜色——这样换皮肤只需要换这一段，不用改别的地方。
   ========================================================================== */
:root, body[data-theme="blue"] {
  --accent: #007AFF;
  --accent-hover: #0066d6;
  --accent-deep: #0b3d91;
  --accent-tint: rgba(0,122,255,0.12);
  --accent-tint-strong: rgba(0,122,255,0.22);
  --on-accent: #ffffff;

  --bg-page: #F2F2F7;
  --bg-glass: rgba(255,255,255,0.68);
  --bg-glass-strong: rgba(255,255,255,0.88);
  --bg-card: #ffffff;
  --bg-fill: #F2F2F7;
  --bg-fill-2: #E9E9EC;
  --hover-tint: rgba(0,0,0,0.05);

  --text-primary: #1c1c1e;
  --text-secondary: #6e6e73;
  --text-tertiary: #9a9aa0;

  --border-color: rgba(60,60,67,0.14);
  --separator: rgba(60,60,67,0.10);

  --shadow-sm: 0 2px 8px rgba(0,0,0,0.06);
  --shadow-md: 0 8px 24px rgba(0,0,0,0.10);
  --shadow-lg: 0 20px 50px rgba(0,0,0,0.18);

  --switch-off: #E9E9EA;
  --danger: #FF3B30;
  --danger-tint: rgba(255,59,48,0.12);
  --success: #34C759;
  --warn: #ffd400;

  --radius-xl: 22px;
  --radius-lg: 16px;
  --radius-md: 12px;
  --radius-sm: 9px;
  --blur: blur(24px) saturate(180%);
}

body[data-theme="red"] {
  --accent: #B52D4F;
  --accent-hover: #99253F;
  --accent-deep: #5c1626;
  --accent-tint: rgba(181,45,79,0.12);
  --accent-tint-strong: rgba(181,45,79,0.22);
}

body[data-theme="dark"] {
  --accent: #0A84FF;
  --accent-hover: #3396ff;
  --accent-deep: #000000;
  --accent-tint: rgba(10,132,255,0.18);
  --accent-tint-strong: rgba(10,132,255,0.32);
  --on-accent: #ffffff;

  --bg-page: #000000;
  --bg-glass: rgba(28,28,30,0.68);
  --bg-glass-strong: rgba(28,28,30,0.9);
  --bg-card: #1c1c1e;
  --bg-fill: #1c1c1e;
  --bg-fill-2: #2c2c2e;
  --hover-tint: rgba(255,255,255,0.08);

  --text-primary: #f5f5f7;
  --text-secondary: #98989d;
  --text-tertiary: #6e6e73;

  --border-color: rgba(255,255,255,0.14);
  --separator: rgba(255,255,255,0.10);

  --shadow-sm: 0 2px 8px rgba(0,0,0,0.4);
  --shadow-md: 0 8px 24px rgba(0,0,0,0.5);
  --shadow-lg: 0 24px 60px rgba(0,0,0,0.6);

  --switch-off: #3a3a3c;
  --danger: #FF453A;
  --danger-tint: rgba(255,69,58,0.18);
  --success: #30D158;
  --warn: #ffd60a;
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body {
  margin: 0; padding: 0; height: 100%;
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
  background: var(--bg-page); color: var(--text-primary);
  overscroll-behavior: none;
  transition: background 0.25s ease, color 0.25s ease;
}
.hidden { display: none !important; }

/* ---------- 登录 ---------- */
.login-screen {
  height: 100vh; display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, var(--accent), var(--accent-deep));
}
.login-box {
  background: var(--bg-glass-strong); backdrop-filter: var(--blur); -webkit-backdrop-filter: var(--blur);
  padding: 36px 32px; border-radius: var(--radius-xl); width: 320px;
  box-shadow: var(--shadow-lg); border: 1px solid rgba(255,255,255,0.4);
  display: flex; flex-direction: column; gap: 12px;
}
.brand-logo { width: 64px; height: 64px; object-fit: contain; display: block; margin: 0 auto 4px; }
.login-box h1 { font-size: 20px; margin: 0; text-align: center; color: var(--text-primary); }
.login-box .sub { margin: 0 0 8px; text-align: center; color: var(--text-secondary); font-size: 13px; }

/* ---------- 项目/楼层下拉（登录页副标题 + 顶栏标题旁） ---------- */
.floor-picker-wrap { position: relative; }
.floor-picker-center { display: flex; justify-content: center; margin: 0 0 8px; }
.floor-picker-btn {
  display: flex; align-items: center; gap: 6px; padding: 5px 10px; border: 1px solid var(--border-color);
  border-radius: var(--radius-sm); background: var(--bg-fill); color: var(--text-secondary); font-size: 13px;
  cursor: pointer; transition: background .15s ease;
}
.floor-picker-btn:hover { background: var(--hover-tint); }
.floor-picker-caret { font-size: 10px; opacity: .7; }
.floor-picker-btn-topbar { padding: 3px 8px; font-size: 12px; font-weight: 600; }
.topbar-floor-picker { margin-left: 2px; }
.floor-picker-menu {
  position: absolute; top: calc(100% + 6px); left: 50%; transform: translateX(-50%);
  background: var(--bg-glass-strong); backdrop-filter: var(--blur); -webkit-backdrop-filter: var(--blur);
  border-radius: var(--radius-md); border: 1px solid var(--separator);
  box-shadow: var(--shadow-md); padding: 6px; min-width: 200px; z-index: 30; max-height: 320px; overflow-y: auto;
}
.topbar-floor-picker .floor-picker-menu { left: 0; transform: none; }
.floor-menu-group-title {
  font-size: 11px; font-weight: 700; color: var(--text-tertiary); padding: 6px 10px 2px; text-transform: uppercase;
}
.floor-menu-option {
  display: block; width: 100%; padding: 8px 10px; border: none; background: none; border-radius: var(--radius-sm);
  cursor: pointer; font-size: 13px; color: var(--text-primary); text-align: left; transition: background .15s ease;
}
.floor-menu-option:hover { background: var(--hover-tint); }
.floor-menu-option-active { color: var(--accent); font-weight: 700; }
/* 下拉最下面的"管理项目与楼层"快捷入口——只有有权限的账号才看得到，点了直接跳转到
   M21 那个专门的管理页（新增项目/楼层、改名、传底图都在那边做，这里不重复）。 */
.floor-menu-divider { border-top: 1px solid var(--separator); margin: 6px 4px; }
.floor-menu-manage-btn {
  display: flex; align-items: center; justify-content: space-between; gap: 8px; width: 100%;
  padding: 8px 10px; border: none; background: none; border-radius: var(--radius-sm);
  cursor: pointer; font-size: 12.5px; color: var(--accent); font-weight: 600; text-align: left;
  transition: background .15s ease;
}
.floor-menu-manage-btn:hover { background: var(--hover-tint); }
.login-box input {
  width: 100%; padding: 11px 14px; border: 1px solid var(--border-color); border-radius: var(--radius-md); font-size: 14px;
  background: var(--bg-fill); color: var(--text-primary);
}
.login-box input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-tint); }
.login-box button {
  padding: 12px; border: none; border-radius: 999px; background: var(--accent); color: var(--on-accent);
  font-size: 15px; font-weight: 600; cursor: pointer; transition: transform .12s ease, opacity .12s ease;
}
.login-box button:hover { background: var(--accent-hover); }
.login-box button:active { transform: scale(0.97); }
.login-box .hint { font-size: 12px; color: var(--text-tertiary); text-align: center; margin: 4px 0 0; }

.pw-field { position: relative; display: flex; }
.pw-field input { flex: 1; width: 100%; padding-right: 34px; }
.pw-eye {
  position: absolute; right: 4px; top: 50%; transform: translateY(-50%);
  border: none; background: none; cursor: pointer; font-size: 14px; color: var(--text-tertiary);
  padding: 4px 6px; border-radius: 5px; line-height: 1; user-select: none;
}
.pw-eye:hover { color: var(--text-primary); }
.pw-eye:active { color: var(--accent); background: var(--accent-tint); }
.login-box .error { color: var(--danger); font-size: 13px; text-align: center; min-height: 18px; margin: 0; }

/* ---------- 通用小号文字链接按钮（登录页"点击申请开通"、注册页"返回登录"/"重新选择身份"等） ---------- */
.link-btn {
  border: none; background: none; padding: 0; margin: 0; cursor: pointer;
  font-size: 12.5px; color: var(--accent); text-decoration: underline; text-align: center;
}
.link-btn:hover { color: var(--accent-hover); }

/* ---------- 自助注册（R1.1/R1.2） ---------- */
.register-box { width: 360px; max-height: 88vh; overflow-y: auto; }
.reg-step-hint { font-size: 12.5px; color: var(--text-secondary); text-align: center; margin: 0 0 4px; }
.reg-identity-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }
.reg-identity-btn {
  display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 16px 10px;
  border: 1px solid var(--border-color); border-radius: var(--radius-md); background: var(--bg-fill);
  color: var(--text-primary); font-size: 13.5px; font-weight: 600; cursor: pointer; transition: background .15s ease;
}
.reg-identity-btn:hover { background: var(--hover-tint); border-color: var(--accent); }
.reg-identity-btn-disabled { opacity: 0.5; cursor: not-allowed; }
.reg-identity-btn-disabled:hover { background: var(--bg-fill); border-color: var(--border-color); }
.reg-coming-soon { font-size: 10.5px; color: var(--text-tertiary); font-weight: 500; }
.reg-change-identity { align-self: flex-start; }
.reg-field { display: flex; flex-direction: column; gap: 5px; }
.reg-field label { font-size: 12px; color: var(--text-secondary); font-weight: 600; }
.reg-field select {
  width: 100%; padding: 10px 12px; border: 1px solid var(--border-color); border-radius: var(--radius-md);
  font-size: 14px; background: var(--bg-fill); color: var(--text-primary);
}
.reg-merchant-results { margin-top: 6px; display: flex; flex-direction: column; gap: 6px; }
.reg-merchant-empty { font-size: 12px; color: var(--text-tertiary); margin: 0; }
.reg-merchant-candidate {
  display: block; width: 100%; text-align: left; padding: 8px 10px; border: 1px solid var(--border-color);
  border-radius: var(--radius-sm); background: var(--bg-fill); color: var(--text-primary); font-size: 13px; cursor: pointer;
}
.reg-merchant-candidate:hover { background: var(--hover-tint); border-color: var(--accent); }
.reg-merchant-selected {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 13px; color: var(--text-primary);
  padding: 8px 10px; background: var(--accent-tint); border-radius: var(--radius-sm);
}
.reg-submit-btn { width: 100%; }
.reg-success { text-align: center; padding: 10px 4px; display: flex; flex-direction: column; gap: 10px; align-items: center; }
.reg-success-icon {
  width: 48px; height: 48px; border-radius: 50%; background: rgba(52,199,89,0.15); color: var(--success);
  display: flex; align-items: center; justify-content: center; font-size: 24px; font-weight: 700;
}
.reg-success h3 { margin: 0; font-size: 16px; }
.reg-success p { margin: 0; font-size: 13px; color: var(--text-secondary); line-height: 1.6; }

/* 登录页右上角的语言切换——固定在视口角落，跟登录卡片本身不挤在一起，样式复用应用内
   顶栏那一套 .lang-switch-btn/.lang-switch-menu，只是外层定位从 relative 换成 fixed。
   默认贴右边，阿语（body.is-rtl）翻到左边——应用内顶栏那份是靠 flex 在 dir=rtl 下自动
   镜像做到"阿语跑到左边"的，这里是固定定位、不会跟着 flex 镜像，所以用 is-rtl 类手动翻一次，
   保证两处"只有阿语才在左边"的视觉规则一致。 */
.login-lang-switch { position: fixed; top: 20px; right: 20px; z-index: 40; }
.login-lang-switch .lang-switch-btn { background: var(--bg-glass-strong); backdrop-filter: var(--blur); -webkit-backdrop-filter: var(--blur); border-color: rgba(255,255,255,0.4); }
body.is-rtl .login-lang-switch { right: auto; left: 20px; }
.lang-switch-wrap { position: relative; }

/* 多语言同时显示：主文字正常显示，次要语言（用户勾选的"同时显示"）以小号浅色文字紧跟
   在后面，各占自己一行，不影响主文字的字号/字重。阿语次要文字单独标 dir="rtl"（见
   i18n.js 的 tm()），不会被外层的 ltr/rtl 影响导致文字方向反了。 */
.i18n-sub {
  display: block; font-size: 0.78em; font-weight: 400; color: var(--text-tertiary);
  line-height: 1.3; margin-top: 1px;
}

/* ---------- 语言选择 ---------- */
.lang-screen {
  height: 100vh; display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, var(--accent), var(--accent-deep));
}
.lang-box {
  background: var(--bg-glass-strong); backdrop-filter: var(--blur); -webkit-backdrop-filter: var(--blur);
  padding: 40px 34px; border-radius: var(--radius-xl); width: 320px;
  box-shadow: var(--shadow-lg); border: 1px solid rgba(255,255,255,0.4); text-align: center;
}
.lang-box .lang-title { font-size: 14px; color: var(--text-secondary); margin: 0 0 20px; }
.lang-flags { display: flex; flex-direction: column; gap: 10px; }
.lang-flag-btn {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  padding: 12px; border: 1px solid var(--border-color); border-radius: var(--radius-md); background: var(--bg-fill);
  font-size: 15px; cursor: pointer; color: var(--text-primary); transition: transform .12s ease, background .15s ease;
}
.lang-flag-btn:hover { background: var(--accent-tint); border-color: var(--accent); }
.lang-flag-btn:active { transform: scale(0.98); }
.lang-flag-btn .flag { width: 28px; height: 20px; border-radius: 4px; box-shadow: 0 0 0 1px rgba(0,0,0,0.1); flex-shrink: 0; overflow: hidden; }
.lang-flag-btn .flag svg { width: 100%; height: 100%; display: block; }

/* ---------- 整体布局 ---------- */
.app { display: flex; flex-direction: row; height: 100vh; }
.app-main { flex: 1; display: flex; flex-direction: column; min-width: 0; height: 100vh; }

/* 侧边栏改成 macOS/iOS 那种浅色毛玻璃侧栏：半透明+高斯模糊，能透出后面页面的底色，
   不再是纯色深蓝底。用 --hover-tint 而不是写死的黑/白，这样暗色模式下自动换成白色调的
   hover 效果，不用另外写一套。 */
.sidebar {
  position: relative;
  width: var(--sidebar-w, 210px); flex-shrink: 0; height: 100vh;
  background: var(--bg-glass); backdrop-filter: var(--blur); -webkit-backdrop-filter: var(--blur);
  color: var(--text-primary); border-right: 1px solid var(--separator);
  display: flex; flex-direction: column; overflow-y: auto; overflow-x: hidden;
  transition: width 0.2s ease;
}
/* 折叠状态：宽度收到 0，内容跟着一起被裁掉，主内容区自动补上这块空间（.sidebar 是
   flex-shrink:0 的固定宽度块，改宽度就行，不用另外改 .app-main）。 */
.sidebar.collapsed { width: 0; border-right: none; }
/* 拖拽调宽期间关掉 transition，不然每次 mousemove 都要等 0.2s 缓动才跟上，拖起来会一卡一卡的；
   松手之后（去掉 .resizing）恢复正常过渡动画，折叠/展开按钮那种场景还是有平滑效果。 */
.sidebar.resizing { transition: none; }

/* PS 那种面板边线拖拽调宽：贴着侧边栏右边线一条很窄的透明热区，鼠标移上去出现细线提示、
   光标变成左右拖拽箭头；折叠状态下（宽度是 0）没有意义，直接隐藏，不然会跟展开按钮重叠。 */
/* right:0（不往外伸）是因为 .sidebar 自己开了 overflow-x:hidden（给里面横向内容用的），
   伸到盒子外面的部分会被裁掉，热区会变窄——干脆让热区整条都贴在盒子内侧右边缘。 */
.sidebar-resize-handle {
  position: absolute; top: 0; right: 0; width: 6px; height: 100%;
  cursor: col-resize; z-index: 10; background: transparent;
}
.sidebar-resize-handle::after {
  content: ''; position: absolute; top: 0; right: 0; width: 2px; height: 100%;
  background: transparent; transition: background .15s ease;
}
.sidebar-resize-handle:hover::after, .sidebar-resize-handle.active::after { background: var(--accent); }
.sidebar.collapsed .sidebar-resize-handle { display: none; }
/* 拖拽过程中给 body 加这个类，防止拖动时手一抖顺带框选中页面上的文字。 */
body.sidebar-resizing { user-select: none; cursor: col-resize; }
/* 固定在 .sidebar 顶部，不随下面 .sidebar-groups 的内容一起滚动/被卷走——.sidebar 自己就是
   滚动容器（overflow-y:auto），sticky 相对它就近生效，不用另外拆一层滚动区域。背景色跟
   .sidebar 保持一致（毛玻璃底），不然滚动内容会从标题条底下透出来。 */
.sidebar-title {
  position: sticky; top: 0; z-index: 5; flex-shrink: 0;
  background: var(--bg-glass); backdrop-filter: var(--blur); -webkit-backdrop-filter: var(--blur);
  padding: 18px 14px 10px 18px; font-size: 12px; font-weight: 700; color: var(--text-tertiary);
  letter-spacing: 0.04em; text-transform: uppercase;
  display: flex; align-items: center; justify-content: space-between; gap: 8px; white-space: nowrap;
}
.sidebar-title-actions { display: flex; align-items: center; gap: 2px; flex-shrink: 0; }
.sidebar-toggle-btn {
  position: relative; flex-shrink: 0; width: 26px; height: 26px; border-radius: var(--radius-sm);
  border: none; background: none; color: var(--text-tertiary); cursor: pointer;
  display: flex; align-items: center; justify-content: center; transition: background .15s ease, color .15s ease;
}
.sidebar-toggle-btn:hover { background: var(--hover-tint); color: var(--text-primary); }
/* 工作台编辑模式开关（M3.10）：开着的时候常亮高亮，提醒"现在拖拽把手/置顶开关是显示着的，
   别忘了弄完退出编辑模式"——跟地图列表自己那个编辑图标（.sidebar-maplist-edit-toggle）是
   同一个视觉语言，只是这个管的是整个工作台，那个只管地图列表自己。 */
#workbenchEditToggleBtn.active { background: var(--accent-tint); color: var(--accent); }
/* 收起之后侧边栏本身宽度是 0，里面的展开按钮会被一起裁掉，所以"展开"用的是另一个独立按钮，
   钉在屏幕固定位置，跟 .sidebar 没有 DOM 嵌套关系——这样也不会被 .sidebar 的 backdrop-filter
   影响到 fixed 定位的参照系（之前拖拽排序踩过这个坑，这里直接绕开）。 */
.sidebar-expand-btn {
  position: fixed; top: 14px; left: 10px; z-index: 47;
  background: var(--bg-glass-strong); backdrop-filter: var(--blur); -webkit-backdrop-filter: var(--blur);
  border: 1px solid var(--separator); box-shadow: var(--shadow-md); border-radius: 50%;
}
/* 侧边栏收起之后，悬浮的展开按钮会挡在顶栏标题最左边，给标题让一点位置出来。 */
body.sidebar-collapsed .topbar-left { padding-left: 30px; }
.sidebar-groups { display: flex; flex-direction: column; gap: 2px; padding-bottom: 14px; }
/* 四个大分区（系统/部门/通用/商户模块）用一条带背景色的通栏标题条，字号/字重都明显
   比部门子标题、普通功能行更重——之前四级标题（大分区/部门/占位符父项/占位符子项）看起来
   差不多重，容易分不清现在到底展开到第几层。这条标题条加了背景色块+更大字号，一眼就能
   跟下面缩进的部门子标题、普通功能行区分开。分区之间再加一条分隔线，一屏内多个分区滚动
   浏览时也不会连成一片。 */
.sidebar-group { margin: 0 8px; }
.sidebar-group + .sidebar-group { margin-top: 6px; padding-top: 10px; border-top: 1px solid var(--separator); }
.sidebar-group-title {
  padding: 7px 10px; margin-bottom: 4px; font-size: 12.5px; font-weight: 800; color: var(--text-primary);
  letter-spacing: 0.03em; text-transform: uppercase; background: var(--bg-fill); border-radius: var(--radius-sm);
}
.sidebar-list { position: relative; display: flex; flex-direction: column; gap: 6px; padding: 0 2px 14px; }
/* "地图列表"（M3.8）：跟普通模块走同一套 sidebarRowHtml/wireDragReorder（能拖排序/能跨分区拖），
   只是点开不是直接执行动作，而是展开下面这三个可切换的地图子选项。 */
.sidebar-maplist-chevron { margin-left: auto; color: var(--text-tertiary); font-size: 14px; flex-shrink: 0; }
.sidebar-maplist-sub { position: relative; display: flex; flex-direction: column; gap: 2px; padding: 4px 0 6px 10px; }
.sidebar-maplist-opt-row { display: flex; align-items: center; gap: 2px; }
.sidebar-maplist-opt {
  display: flex; align-items: center; gap: 8px; padding: 7px 10px; border-radius: var(--radius-sm);
  color: var(--text-secondary); font-size: 12.5px; cursor: pointer; border: none; background: none;
  text-align: left; transition: background .15s ease; flex: 1; min-width: 0;
}
.sidebar-maplist-opt:hover { background: var(--hover-tint); }
.sidebar-maplist-opt.active { background: var(--accent-tint); color: var(--accent); font-weight: 600; }
/* 每个地图选项旁边的小导出按钮——原来独立一个的"导出地图图片"模块合并到这儿了，
   点了直接跳转导出配置页（M19），带着这张地图的模式一起过去。position:relative 是给
   它自己的编号标签（.admin-code-circle）当定位基准，标签摆在按钮右上角，不会撑大
   这个 26px 的小圆按钮、也不会跟旁边选项自己的标签挤在一起。 */
.sidebar-maplist-export-btn {
  position: relative; display: flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; flex-shrink: 0;
  border-radius: var(--radius-sm); border: none; background: none; color: var(--text-tertiary);
  font-size: 12px; cursor: pointer; transition: background .15s ease, color .15s ease;
}
.sidebar-maplist-export-btn:hover { background: var(--hover-tint); color: var(--accent); }

/* 地图列表右上角的小编辑图标（只有超管看得到）：点了切换"编辑模式"。 */
.sidebar-maplist-edit-toggle {
  display: flex; align-items: center; justify-content: center; width: 24px; height: 24px; flex-shrink: 0;
  border-radius: var(--radius-sm); border: none; background: none; color: var(--text-tertiary);
  font-size: 12px; cursor: pointer; transition: background .15s ease, color .15s ease;
}
.sidebar-maplist-edit-toggle:hover { background: var(--hover-tint); color: var(--accent); }
.sidebar-maplist-edit-toggle.active { background: var(--accent-tint); color: var(--accent); }

/* 编辑模式下的每一行：拖拽把手 + 名字 + 改名/删除图标按钮，删除按钮只有 deletable 的
   地图（新增出来的空白地图）才有，物业/财务这两张系统地图没有删除按钮。 */
.sidebar-maplist-edit-row {
  display: flex; align-items: center; gap: 6px; padding: 6px 8px; border-radius: var(--radius-sm);
  background: var(--bg-fill);
}
.sidebar-maplist-edit-label { flex: 1; min-width: 0; font-size: 12.5px; color: var(--text-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sidebar-maplist-icon-btn {
  display: flex; align-items: center; justify-content: center; width: 24px; height: 24px; flex-shrink: 0;
  border-radius: var(--radius-sm); border: none; background: none; color: var(--text-tertiary);
  font-size: 12px; cursor: pointer; transition: background .15s ease, color .15s ease;
}
.sidebar-maplist-icon-btn:hover { background: var(--hover-tint); color: var(--accent); }
.sidebar-maplist-delete-btn:hover { color: var(--danger); }
.sidebar-maplist-add-btn { width: 100%; margin-top: 4px; }
.sidebar-item-block { border-radius: var(--radius-md); padding: 4px; transition: background .15s ease; }
.sidebar-item-block:hover { background: var(--hover-tint); }
.sidebar-item-row { display: flex; align-items: center; gap: 4px; }
.sidebar-item {
  display: flex; align-items: center; gap: 8px; padding: 9px 10px; border-radius: var(--radius-sm);
  color: var(--text-primary); font-size: 13.5px; font-weight: 500; cursor: pointer; border: none; background: none;
  text-align: left; flex: 1; min-width: 0; transition: background .15s ease, transform .1s ease;
}
.sidebar-item:hover { background: var(--hover-tint); }
.sidebar-item:active { transform: scale(0.98); }
.sidebar-item.btn-active { background: var(--accent); color: var(--on-accent); font-weight: 600; }

/* ---------- 工作台占位符（权限树里"权限位有了/规划里写了，代码还没有"的功能，点开只看说明，
   不是真的能用）：跟真实模块用同一套 .sidebar-item-block/.sidebar-item 结构，但虚线边框+
   降低不透明度，一眼能看出"这个还没做"，不会跟已经能用的功能混在一起看不出区别。 */
.sidebar-item-placeholder { opacity: 0.62; }
.sidebar-item-placeholder .sidebar-item-placeholder-btn {
  border: 1px dashed var(--separator); font-weight: 400;
}
.sidebar-item-placeholder .sidebar-item-placeholder-btn:hover { opacity: 1; background: var(--hover-tint); }
.sidebar-item-placeholder.sidebar-item-placeholder-child { padding-left: 20px; }
.sidebar-item-placeholder.sidebar-item-placeholder-child .sidebar-item-placeholder-btn { font-size: 12px; padding: 6px 10px; }
/* 挂着子功能点的占位符父项（比如"字典与基础配置管理"）：点它不是去看说明，是展开/收起
   底下那几条子功能点，所以按钮里带个跟其它可展开模块一样的小箭头，靠右对齐。 */
.sidebar-item-placeholder-btn .sidebar-maplist-chevron { margin-left: auto; }
/* position:relative 是给编辑模式下拖拽用的（见下面 .drag-lifted 的说明：拖起来的元素
   相对"最近的 position:relative 容器"定位），跟 .sidebar-list 是同一个道理。 */
.sidebar-placeholder-children { position: relative; display: flex; flex-direction: column; gap: 4px; }

/* 部门模块板块里，每个部门（人力/物业/财务/市场/招商/贸易）自己一个小标题+一份占位功能清单，
   标题本身就是这个部门自己的展开/收起开关。左边一条竖线 + 缩进，跟上面通栏底色的大分区
   标题拉开明显差距——一眼能看出这是"大分区标题下面又分了一层"，不是同一级。 */
.sidebar-dept-block { margin-top: 6px; padding-left: 10px; border-left: 2px solid var(--separator); }
.sidebar-dept-title-row { display: flex; align-items: center; justify-content: space-between; gap: 4px; }
.sidebar-dept-title {
  padding: 4px 6px; font-size: 11.5px; font-weight: 700; color: var(--text-secondary);
}
.sidebar-dept-title-toggle {
  display: flex; align-items: center; gap: 6px; cursor: pointer; user-select: none; flex: 1; min-width: 0;
}
.sidebar-dept-list { position: relative; display: flex; flex-direction: column; gap: 6px; padding: 4px 0 2px; }

/* 四个大分区（系统/部门/通用/商户模块）的标题现在也是展开/收起开关，箭头统一放在文字
   前面（跟部门/占位符父项箭头放右边不一样——大分区这一档更像"目录标题"，箭头在前面更
   符合常见文件树的阅读习惯，小一级的开关沿用原来"箭头跟在按钮文字后面"那套就不用改）。 */
.sidebar-group-title-toggle {
  display: flex; align-items: center; gap: 6px; cursor: pointer; user-select: none;
}
.sidebar-accordion-chevron { font-size: 13px; flex-shrink: 0; color: var(--text-tertiary); }

/* 占位符详情页正文：一句说明 + 如果有更细的功能点，列一份清单。 */
.ph-note { color: var(--text-secondary); font-size: 13.5px; line-height: 1.6; }
.ph-children-title { margin-top: 18px; font-size: 12px; font-weight: 700; color: var(--text-tertiary); text-transform: uppercase; letter-spacing: 0.04em; }
.ph-children-list { margin: 8px 0 0; padding-left: 20px; }
.ph-children-list li { font-size: 13px; color: var(--text-primary); line-height: 2; }
.sidebar-item-sub {
  display: flex; align-items: center; justify-content: space-between; padding: 3px 10px 2px;
}
/* noQuickbar 模块（比如地图列表）没有"加入常用工具栏"开关，这一行只剩拖拽把手，
   靠右对齐（跟其它模块的把手对齐在同一条竖线上）。 */
.sidebar-item-sub-nocheck { justify-content: flex-end; }
.sidebar-item-check { display: flex; align-items: center; gap: 6px; font-size: 10.5px; color: var(--text-tertiary); cursor: pointer; }

/* iOS 风格的小开关（胶囊+圆点），比原生方框勾选框更贴近 iOS 观感。
   结构是 input[checkbox] 紧跟一个 span.ios-switch-track，用相邻选择器 + 控制外观，
   input 本身透明铺满整个胶囊当点击热区，不用额外写 JS。 */
.ios-switch { position: relative; display: inline-flex; width: 30px; height: 18px; flex-shrink: 0; }
.ios-switch input {
  position: absolute; inset: 0; margin: 0; opacity: 0; cursor: pointer; z-index: 1;
}
.ios-switch-track {
  position: absolute; inset: 0; background: var(--switch-off); border-radius: 999px;
  transition: background .18s ease;
}
.ios-switch-track::before {
  content: ''; position: absolute; top: 2px; left: 2px; width: 14px; height: 14px; border-radius: 50%;
  background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,0.35); transition: transform .18s ease;
}
.ios-switch input:checked + .ios-switch-track { background: var(--success); }
.ios-switch input:checked + .ios-switch-track::before { transform: translateX(12px); }

.sidebar-drag-handle {
  display: flex; align-items: center; justify-content: center; width: 22px; height: 18px;
  border-radius: 4px; color: var(--text-tertiary); font-size: 12px; line-height: 1; flex-shrink: 0;
  cursor: grab; touch-action: none; user-select: none;
}
.sidebar-drag-handle:hover { background: var(--hover-tint); }
.sidebar-drag-handle:active { cursor: grabbing; }
.sidebar-empty { padding: 10px 12px; font-size: 12px; color: var(--text-tertiary); }

/* 每个模块名字旁边的小圈问号：鼠标悬停才弹出说明，像个小对话气泡，挪开鼠标就收起来 */
.sidebar-hint-wrap { position: relative; flex-shrink: 0; }
.sidebar-hint-icon {
  display: flex; align-items: center; justify-content: center; width: 16px; height: 16px;
  border-radius: 50%; background: var(--hover-tint); color: var(--text-tertiary);
  font-size: 10px; font-weight: 700; cursor: help; user-select: none;
}
.sidebar-hint-icon:hover { background: var(--accent-tint); color: var(--accent); }
.sidebar-hint-bubble {
  /* 用 JS 在鼠标悬停时算好屏幕坐标再显示（position: fixed），
     这样气泡才能跑出 .sidebar 的 overflow-y:auto 裁剪区域，不会被切掉看不见 */
  display: none; position: fixed; width: 250px; background: var(--bg-glass-strong);
  backdrop-filter: var(--blur); -webkit-backdrop-filter: var(--blur);
  color: var(--text-primary); padding: 10px 12px; border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg); font-size: 12px; line-height: 1.6; z-index: 200;
  border: 1px solid var(--separator);
}
.sidebar-hint-bubble::before {
  content: ''; position: absolute; right: 100%; top: 50%; transform: translateY(-50%);
  border: 6px solid transparent; border-right-color: var(--bg-glass-strong);
}

.topbar {
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 18px; background: var(--bg-glass); backdrop-filter: var(--blur); -webkit-backdrop-filter: var(--blur);
  color: var(--text-primary); flex-wrap: wrap; gap: 8px; border-bottom: 1px solid var(--separator);
  position: relative; z-index: 46; /* 保证语言/个人信息按钮始终在商户列表侧栏之上，不被盖住 */
}
.topbar h1 { font-size: 16px; margin: 0; font-weight: 700; }
.topbar-left { flex-shrink: 0; display: flex; align-items: center; gap: 8px; }
.topbar-logo { width: 26px; height: 26px; object-fit: contain; flex-shrink: 0; }
/* 搜索框跟浏览器地址栏一个道理：不是死死焊在屏幕正中间，而是左右两块工具栏之间剩下多少
   空间就在多少空间里居中——常用工具栏（右边）东西一多把空间挤没了，搜索框就自然跟着往左让，
   不会被常用按钮盖住。 */
.topbar-center {
  flex: 1 1 auto; min-width: 40px;
  display: flex; justify-content: center;
}
.topbar-right { display: flex; align-items: center; gap: 8px; flex-shrink: 1; min-width: 0; }
#searchBox {
  padding: 8px 14px; border-radius: 999px; border: 1px solid var(--separator); font-size: 13px;
  width: 280px; max-width: 100%; min-width: 60px; background: var(--bg-fill); color: var(--text-primary);
}
#searchBox:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-tint); }
#searchBox::placeholder { color: var(--text-tertiary); }

.btn {
  padding: 8px 16px; border: none; border-radius: 999px; background: var(--accent); color: var(--on-accent);
  font-size: 13px; font-weight: 600; cursor: pointer; transition: transform .12s ease, opacity .12s ease, background .15s ease;
}
.btn:hover { background: var(--accent-hover); }
.btn:active { transform: scale(0.96); }
.btn-link { background: transparent; color: var(--accent); text-decoration: underline; }
.btn-active { background: var(--accent); color: var(--on-accent); font-weight: 600; }
.btn-sm { padding: 4px 10px; font-size: 11.5px; }
.whoami { font-size: 12px; color: var(--text-secondary); }

.quick-bar { position: relative; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; min-width: 0; flex: 1 1 auto; }
.quick-bar button { touch-action: none; }

/* ---------- 通用"拖拽排序"样式（wireDragReorder 用，顶部工具栏/侧边栏/弹窗模板共用同一套） ----------
   拖起来的那一项：position:absolute，相对最近的 position:relative 容器定位（每处列表容器
   都单独声明了 position:relative，见 .quick-bar / .sidebar-list / .pt-list），不用 fixed，
   也不会被挪到别的父节点下面，所以不受任何祖先 backdrop-filter 影响，也不会中途弄丢
   pointer capture。占位符是一个干净的空 div，不继承被拖元素的任何 class，纯粹用来占位置、
   标记"松手会插到这里"。 */
.drag-lifted {
  position: absolute; box-shadow: var(--shadow-lg); opacity: 0.96; pointer-events: none; z-index: 200;
}
.drag-placeholder {
  border: 1.5px dashed var(--border-color); border-radius: var(--radius-md);
  background: var(--hover-tint); box-sizing: border-box; flex-shrink: 0;
}

.icon-btn {
  display: flex; align-items: center; justify-content: center; width: 34px; height: 34px;
  border: 1px solid var(--separator); border-radius: var(--radius-sm); background: var(--bg-fill);
  color: var(--text-primary); cursor: pointer; font-size: 16px; flex-shrink: 0; transition: background .15s ease;
}
.icon-btn:hover { background: var(--hover-tint); }
.icon-btn-glyph { line-height: 1; }

.profile-btn {
  display: flex; align-items: center; gap: 8px; padding: 4px 12px 4px 4px;
  border: 1px solid var(--separator); border-radius: 999px; background: var(--bg-fill);
  color: var(--text-primary); cursor: pointer; transition: background .15s ease;
}
.profile-btn:hover { background: var(--hover-tint); }
.profile-avatar {
  width: 28px; height: 28px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 700; color: #fff; flex-shrink: 0; overflow: hidden;
}
.profile-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.profile-text { display: flex; flex-direction: column; align-items: flex-start; line-height: 1.25; }
.profile-name { font-size: 12px; font-weight: 600; }
.profile-role { font-size: 10px; color: var(--text-secondary); }

.lang-switch-btn {
  display: flex; align-items: center; gap: 6px; padding: 6px 10px;
  border: 1px solid var(--separator); border-radius: var(--radius-sm);
  background: var(--bg-fill); cursor: pointer; transition: background .15s ease;
}
.lang-switch-btn:hover { background: var(--hover-tint); }
.lang-switch-globe { font-size: 15px; line-height: 1; }
.lang-switch-flag-wrap { display: flex; align-items: center; }
.lang-switch-flag-wrap svg { width: 20px; height: 14px; border-radius: 3px; box-shadow: 0 0 0 1px rgba(0,0,0,0.15); display: block; }

.lang-switch-menu {
  position: absolute; top: calc(100% + 6px); right: 0; background: var(--bg-glass-strong);
  backdrop-filter: var(--blur); -webkit-backdrop-filter: var(--blur);
  border-radius: var(--radius-md); border: 1px solid var(--separator);
  box-shadow: var(--shadow-md); padding: 6px; min-width: 220px; z-index: 30;
}
/* 每一行分两块：左边点旗子/名字（.lang-switch-option-main）= 切主语言，右边"同时显示"
   复选框（.lang-switch-also）= 多语言同显，两者互不干扰，所以外层 .lang-switch-option
   现在是一个不可点击的行容器，不是按钮本身。 */
.lang-switch-option {
  display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 2px;
}
.lang-switch-option-main {
  display: flex; align-items: center; gap: 10px; flex: 1; padding: 7px 8px;
  border: none; background: none; border-radius: var(--radius-sm); cursor: pointer;
  font-size: 13px; color: var(--text-primary); text-align: left; transition: background .15s ease;
}
.lang-switch-option-main:hover { background: var(--hover-tint); }
.lang-switch-option-main .lang-switch-flag-wrap svg { box-shadow: 0 0 0 1px rgba(0,0,0,0.12); }
/* "同时显示"复选框：当前已经是主语言的那一行不需要再勾（本来就显示着），JS 会把它
   禁用掉，避免用户以为多勾一次会有什么额外效果。 */
.lang-switch-also {
  display: flex; align-items: center; gap: 5px; font-size: 11px; color: var(--text-tertiary);
  cursor: pointer; flex-shrink: 0; white-space: nowrap; padding: 4px 6px;
}
.lang-switch-also-cb { cursor: pointer; }
.lang-switch-also-cb[disabled] { cursor: default; opacity: 0.4; }

/* ---------- 通用右对齐下拉弹窗（功能模块 / 个人信息） ---------- */
.dropdown-wrap { position: relative; }
.dropdown-panel {
  position: absolute; top: calc(100% + 8px); right: 0; background: var(--bg-glass-strong);
  backdrop-filter: var(--blur); -webkit-backdrop-filter: var(--blur); color: var(--text-primary);
  border-radius: var(--radius-lg); border: 1px solid var(--separator);
  box-shadow: var(--shadow-lg); width: 360px; max-width: 92vw;
  max-height: 78vh; overflow-y: auto; z-index: 40;
}
.dropdown-head {
  display: flex; align-items: center; justify-content: space-between; padding: 14px 18px;
  border-bottom: 1px solid var(--separator); font-weight: 700; font-size: 14px;
  position: sticky; top: 0; background: var(--bg-glass-strong);
  backdrop-filter: var(--blur); -webkit-backdrop-filter: var(--blur); z-index: 1;
}
.dropdown-close { border: none; background: none; font-size: 20px; cursor: pointer; color: var(--text-tertiary); line-height: 1; }
.dropdown-close:hover { color: var(--text-primary); }
.dropdown-body { padding: 16px 18px; }

.legend {
  display: flex; flex-wrap: wrap; gap: 10px; padding: 10px 18px; background: var(--bg-glass);
  backdrop-filter: var(--blur); -webkit-backdrop-filter: var(--blur);
  border-bottom: 1px solid var(--separator); font-size: 12px; color: var(--text-primary);
}
/* 非编辑态工具栏只有铅笔图标，跟色块同一行更紧凑（原来的样子，见 renderLegend 注释）；
   编辑态工具栏占满一整行（.legend-toolbar 自己 width:100%），这里额外声明 column 方向，
   避免它跟色块同一层 wrap 排列时互相抢位置。 */
.legend.legend-editing { flex-direction: column; }
/* 色块单独一层 flex 容器，跟上面的工具栏（.legend-toolbar）是兄弟节点不是同一层——拖拽排序
   （wireDragReorder）只在这层容器内部找兄弟节点算插入位置，工具栏那些按钮不会混进来干扰，
   不然拖的时候旁边色块不会跟着让位置（工具栏那个 100% 宽的按钮条会被误当成一个"兄弟色块"参与
   位置计算）。position:relative 是给拖拽用的，见下面 wireDragReorder 通用样式段落的说明。 */
.legend-items { position: relative; display: flex; flex-wrap: wrap; gap: 10px; }
.legend-item { display: flex; align-items: center; gap: 5px; }
.legend-swatch { width: 12px; height: 12px; border-radius: 4px; display: inline-block; border: 1px solid rgba(0,0,0,0.15); }

/* ---------- 图例编辑（超管专属）：颜色/名称可编辑 + 选中一个颜色当画笔点铺位刷状态 ---------- */
.legend-toolbar { display: flex; align-items: center; gap: 6px; width: 100%; padding-bottom: 6px; margin-bottom: 2px; border-bottom: 1px dashed var(--separator); }
/* 未编辑时工具栏只有一个铅笔切换按钮，去掉整行样式，让它跟色块并排在同一行 */
.legend-toolbar-compact { width: auto; padding-bottom: 0; margin-bottom: 0; border-bottom: none; }
.legend-tool-btn {
  width: 26px; height: 26px; border-radius: var(--radius-sm); border: none; background: none;
  color: var(--text-tertiary); cursor: pointer; display: flex; align-items: center; justify-content: center;
  font-size: 13px; transition: background .15s ease, color .15s ease;
}
.legend-tool-btn:hover { background: var(--hover-tint); color: var(--accent); }
.legend-tool-btn:disabled { opacity: 0.35; cursor: default; }
.legend-tool-btn:disabled:hover { background: none; color: var(--text-tertiary); }
.legend-edit-hint { font-size: 11px; color: var(--text-tertiary); }
/* 编辑模式下每个色块变成可点的小胶囊：点色块本身开颜色选择器，点铅笔改名字，
   点胶囊其它地方（比如名字文字）是"选中当画笔"，选中了会有一圈强调边框（.armed）。 */
.legend-item-editable {
  cursor: pointer; padding: 3px 6px 3px 8px; border-radius: 999px; border: 1px solid transparent;
  transition: background .15s ease, border-color .15s ease;
}
.legend-item-editable:hover { background: var(--hover-tint); }
.legend-item-editable.armed { border-color: var(--accent); background: var(--accent-tint); font-weight: 600; }
.legend-swatch-edit { cursor: pointer; }
.legend-drag-handle {
  cursor: grab; touch-action: none; color: var(--text-tertiary); font-size: 11px; flex-shrink: 0;
  margin-left: -2px; line-height: 1;
}
.legend-drag-handle:active { cursor: grabbing; }
.legend-rename-btn {
  width: 18px; height: 18px; border: none; background: none; color: var(--text-tertiary); cursor: pointer;
  font-size: 10px; display: flex; align-items: center; justify-content: center; border-radius: 4px; flex-shrink: 0;
}
.legend-rename-btn:hover { background: var(--hover-tint); color: var(--accent); }
.legend-delete-btn {
  width: 18px; height: 18px; border: none; background: none; color: var(--text-tertiary); cursor: pointer;
  font-size: 12px; display: flex; align-items: center; justify-content: center; border-radius: 4px; flex-shrink: 0;
}
.legend-delete-btn:hover { background: var(--danger-tint, rgba(220,53,69,0.12)); color: var(--danger, #dc3545); }

/* ---------- 地图 ---------- */
.mapWrap { flex: 1; position: relative; overflow: hidden; background: var(--bg-page); touch-action: none; }
.mapStage {
  width: 100%; height: 100%; position: relative; cursor: grab;
}
.mapStage.dragging { cursor: grabbing; }
/* 图例编辑模式下武装了画笔：光标换成十字线，提示这时候拖动是刷状态，不是平移地图（见 app.js updateMapStageCursor）。 */
.mapStage.map-edit-armed, .mapStage.map-edit-armed.dragging { cursor: crosshair; }
.marquee-box {
  position: absolute; border: 1.5px dashed var(--accent); background: var(--accent-tint);
  pointer-events: none; z-index: 4;
}
#mapSvg {
  position: absolute; top: 0; left: 0; transform-origin: 0 0;
  user-select: none;
}
/* 底图是张黑线白底的 PNG（floor_1f.png），本身没有跟着换肤——暗色模式下直接把这张图反色，
   黑线变白线、白底变黑底，跟周围的深色界面才不会显得突兀。只反底图，铺位色块（状态色）
   是另外单独叠加的 SVG 矩形，不受这条规则影响，颜色不变。 */
body[data-theme="dark"] #mapSvg image {
  filter: invert(1) hue-rotate(180deg);
}
.shop-rect {
  stroke: rgba(0,0,0,0.55); stroke-width: 1; cursor: pointer; fill-opacity: 0.55;
  pointer-events: fill; vector-effect: non-scaling-stroke;
  /* 加上 vector-effect 之后，边框粗细就是屏幕上的固定像素值，不会随缩放倍数一起被放粗 */
}
.shop-rect:hover { fill-opacity: 0.85; stroke-width: 1; }
.shop-rect.selected { stroke: #ff2d55; stroke-width: 1.2; fill-opacity: 0.9; }
.shop-rect.search-match { stroke: var(--warn); stroke-width: 1; }
/* 物业/财务地图互相对比用的小圆点：只有同时有两边部门权限的账号才看得到（JS 里控制），
   加一圈浅色描边，免得圆点颜色跟底下铺位色块太接近的时候糊在一起分不清。 */
.compare-dot { stroke: rgba(255,255,255,0.9); stroke-width: 0.8px; vector-effect: non-scaling-stroke; pointer-events: none; }

.mapControls {
  position: absolute; right: 16px; bottom: 16px; display: flex; flex-direction: column; gap: 8px;
}
.mapControls button {
  position: relative; width: 40px; height: 40px; border-radius: 50%; border: 1px solid rgba(255,255,255,0.5);
  background: var(--bg-glass-strong); backdrop-filter: var(--blur); -webkit-backdrop-filter: var(--blur);
  color: var(--text-primary);
  font-size: 18px; cursor: pointer; box-shadow: var(--shadow-md); transition: transform .12s ease;
}
.mapControls button:active { transform: scale(0.92); }
.mapControls #zoomResetBtn { font-size: 11px; }
.mapControls #mapCompareBtn.active { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }

/* ---------- 数据对比：下拉多选面板 + 悬浮弹窗，都是 position:fixed 挂在 body 下面，
   不嵌在任何可能带 backdrop-filter/transform 的容器里，用 JS 现算屏幕坐标定位。 ---------- */
.compare-dropdown {
  position: fixed; z-index: 210; min-width: 180px; padding: 10px 12px; border-radius: var(--radius-md);
  background: var(--bg-glass-strong); backdrop-filter: var(--blur); -webkit-backdrop-filter: var(--blur);
  border: 1px solid var(--separator); box-shadow: var(--shadow-lg); color: var(--text-primary);
}
.compare-dropdown-title { font-size: 12px; font-weight: 700; color: var(--text-secondary); margin-bottom: 6px; }
.compare-dropdown-item { display: flex; align-items: center; gap: 8px; padding: 6px 4px; font-size: 13px; cursor: pointer; }
.compare-dropdown-item input { cursor: pointer; accent-color: var(--accent); }
.compare-dropdown-hint { font-size: 11px; color: var(--text-tertiary); margin: 6px 0 0; max-width: 220px; }

.compare-popup {
  position: fixed; z-index: 220; min-width: 160px; padding: 9px 11px; border-radius: var(--radius-md);
  background: var(--bg-glass-strong); backdrop-filter: var(--blur); -webkit-backdrop-filter: var(--blur);
  border: 1px solid var(--separator); box-shadow: var(--shadow-lg); color: var(--text-primary);
  font-size: 12px; transform: translate(-50%, -100%); cursor: pointer;
}
.compare-popup-head { font-weight: 700; margin-bottom: 6px; display: flex; align-items: center; gap: 6px; }
.compare-popup-diff { font-size: 10px; padding: 1px 6px; border-radius: 999px; background: rgba(230,126,34,0.18); color: var(--warn); font-weight: 700; }
.compare-popup-row { display: flex; align-items: center; gap: 6px; padding: 2px 0; }
.compare-popup-swatch { width: 9px; height: 9px; border-radius: 3px; flex-shrink: 0; display: inline-block; border: 1px solid rgba(0,0,0,0.15); }
.compare-popup-map { color: var(--text-tertiary); flex-shrink: 0; }
.compare-popup-val { font-weight: 600; }
.compare-popup-hint { font-size: 10.5px; color: var(--text-tertiary); margin-top: 6px; }

.compare-detail-note { font-size: 13px; padding: 10px 12px; border-radius: var(--radius-md); margin-top: 14px; }
.compare-detail-note-ok { background: rgba(47,125,225,0.12); color: var(--accent); }
.compare-detail-note-diff { background: rgba(230,126,34,0.15); color: var(--warn); }


.batch-size-panel {
  position: absolute; top: 56px; left: 50%; transform: translateX(-50%);
  background: var(--bg-glass-strong); backdrop-filter: var(--blur); -webkit-backdrop-filter: var(--blur);
  border-radius: var(--radius-lg); border: 1px solid var(--separator);
  padding: 10px 12px; box-shadow: var(--shadow-md);
  display: flex; align-items: center; gap: 8px; z-index: 6; font-size: 12px;
}
.batch-size-panel span { color: var(--text-primary); white-space: nowrap; }
.batch-size-panel .btn { font-size: 12px; padding: 7px 12px; white-space: nowrap; }
.batch-size-panel .btn:disabled { background: var(--bg-fill-2); color: var(--text-tertiary); cursor: default; }

.box-edit-panel {
  position: absolute; left: 16px; bottom: 16px; background: var(--bg-glass-strong);
  backdrop-filter: var(--blur); -webkit-backdrop-filter: var(--blur);
  border-radius: var(--radius-lg); border: 1px solid var(--separator);
  padding: 14px 16px; box-shadow: var(--shadow-md); width: 220px; z-index: 6;
}
.box-edit-title { font-size: 13px; font-weight: 700; margin-bottom: 8px; color: var(--text-primary); }
.box-edit-title.drag-handle { cursor: move; user-select: none; touch-action: none; }
.box-edit-row { display: flex; align-items: center; gap: 6px; margin-bottom: 8px; }
.box-edit-row label { font-size: 12px; color: var(--text-secondary); width: 20px; }
.box-edit-row input {
  flex: 1; width: 0; padding: 6px 8px; border: 1px solid var(--border-color); border-radius: var(--radius-sm);
  font-size: 12px; background: var(--bg-fill); color: var(--text-primary);
}
.box-edit-row input:focus { outline: none; border-color: var(--accent); }
.box-edit-copysize { width: 100%; font-size: 12px; padding: 8px; margin-bottom: 8px; }
.box-edit-actions { display: flex; gap: 8px; }
.box-edit-actions .btn { flex: 1; font-size: 12px; padding: 8px; }

.shop-rect.editing { stroke: rgba(255, 212, 0, 0.85); stroke-width: 1; fill-opacity: 0.3; cursor: move; vector-effect: non-scaling-stroke; }
.shop-rect.batch-selected { stroke: var(--accent); fill-opacity: 0.75; }
.box-outline-center {
  display: none; /* 中间那条黑线去掉了，只留铺位本体的黄框 */
}
.box-handle { fill: rgba(255, 212, 0, 0.85); stroke: rgba(27, 58, 107, 0.85); stroke-width: 1.5; cursor: nwse-resize; vector-effect: non-scaling-stroke; }

/* ---------- 弹窗 ---------- */
.overlay {
  position: fixed; inset: 0; background: rgba(0,0,0,0.35); z-index: 40;
  backdrop-filter: blur(2px); -webkit-backdrop-filter: blur(2px);
}
.popup {
  position: fixed; z-index: 50; background: var(--bg-glass-strong);
  backdrop-filter: var(--blur); -webkit-backdrop-filter: var(--blur);
  border: 1px solid var(--separator); color: var(--text-primary);
  border-radius: var(--radius-xl); width: 320px;
  max-width: 90vw; box-shadow: var(--shadow-lg);
  top: 50%; left: 50%; transform: translate(-50%, -50%);
  max-height: 85vh; display: flex; flex-direction: column;
}
.popup-head {
  display: flex; justify-content: space-between; align-items: center;
  padding: 14px 18px; border-bottom: 1px solid var(--separator); font-weight: 700;
}
.popup-close { position: relative; border: none; background: none; font-size: 20px; cursor: pointer; color: var(--text-tertiary); }
.popup-body { padding: 16px 18px; overflow-y: auto; }

.field-row { margin-bottom: 10px; }
.field-row label { display: block; font-size: 12px; color: var(--text-secondary); margin-bottom: 4px; }
.field-row input, .field-row select, .field-row textarea {
  width: 100%; padding: 8px 10px; border: 1px solid var(--border-color); border-radius: var(--radius-sm); font-size: 13px;
  font-family: inherit; background: var(--bg-fill); color: var(--text-primary);
}
.field-row input:focus, .field-row select:focus, .field-row textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-tint); }
.field-row textarea { resize: vertical; min-height: 50px; }
.field-static { font-size: 13px; padding: 4px 0; color: var(--text-primary); }
.popup-actions { display: flex; gap: 8px; margin-top: 14px; flex-wrap: wrap; }
.popup-actions .btn-secondary { background: var(--bg-fill-2); color: var(--text-primary); }
.popup-actions .btn-danger { background: var(--danger); }
.popup-actions .btn-danger:hover { opacity: 0.88; }

/* ---------- 状态下拉框（自定义组件）：文字保持正常颜色，右边挂一枚小胶囊色块 ---------- */
.status-opt-label { color: var(--text-primary); font-size: 13px; }
.status-dot {
  display: inline-block; width: 20px; height: 9px; border-radius: 999px; flex-shrink: 0;
}
.status-select { position: relative; }
.status-select-btn {
  width: 100%; display: flex; align-items: center; gap: 8px;
  padding: 5px 10px; border: 1px solid var(--border-color); border-radius: var(--radius-sm);
  background: var(--bg-fill); cursor: pointer; font-family: inherit;
}
.status-select-btn .status-opt-label { flex: 1; text-align: left; }
.status-select-btn:disabled { cursor: default; opacity: 0.65; }
.status-select-btn:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-tint); }
.status-select-caret { color: var(--text-tertiary); font-size: 11px; flex-shrink: 0; }
.status-select-panel {
  position: fixed; z-index: 95; background: var(--bg-card); border: 1px solid var(--separator);
  border-radius: var(--radius-md); box-shadow: var(--shadow-lg); padding: 6px;
  max-height: 320px; overflow-y: auto; display: flex; flex-direction: column; gap: 2px;
}
.status-opt { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 6px 8px; border-radius: var(--radius-sm); cursor: pointer; }
.status-opt:hover { background: var(--hover-tint); }
.status-opt.active { background: var(--accent-tint); }

/* ---------- 电子ID卡 ---------- */
.idcard-modal {
  position: fixed; z-index: 70; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: 300px; border-radius: var(--radius-xl); overflow: hidden; box-shadow: var(--shadow-lg);
  background: var(--bg-card); border: 1px solid var(--separator);
}
.idcard-close {
  position: absolute; top: 8px; right: 10px; z-index: 2; border: none; background: rgba(255,255,255,0.25);
  color: #fff; width: 28px; height: 28px; border-radius: 50%; font-size: 18px; cursor: pointer; line-height: 1;
}
.idcard-close:hover { background: rgba(255,255,255,0.4); }
.idcard-header {
  background: linear-gradient(135deg, var(--accent), var(--accent-deep)); color: #fff; padding: 22px 20px 50px; text-align: center;
}
.idcard-header .idcard-brand { font-size: 12px; letter-spacing: 0.08em; opacity: 0.85; margin-bottom: 2px; }
.idcard-header .idcard-title { font-size: 16px; font-weight: 700; }
.idcard-photo {
  width: 92px; height: 92px; border-radius: 50%; border: 4px solid var(--bg-card); margin: -46px auto 0;
  background: #ccc; display: flex; align-items: center; justify-content: center; overflow: hidden;
  font-size: 34px; font-weight: 700; color: #fff; box-shadow: 0 4px 14px rgba(0,0,0,0.25); position: relative; z-index: 1;
}
.idcard-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.idcard-name { text-align: center; font-size: 19px; font-weight: 700; margin-top: 10px; color: var(--text-primary); }
.idcard-sub { text-align: center; font-size: 12px; color: var(--text-secondary); margin-top: 3px; }
.idcard-rows { padding: 16px 22px 22px; }
.idcard-row { display: flex; gap: 10px; align-items: center; padding: 8px 0; border-bottom: 1px dashed var(--separator); font-size: 13px; }
.idcard-row:last-child { border-bottom: none; }
.idcard-row .idcard-icon { width: 18px; text-align: center; color: var(--accent); }
.idcard-row .idcard-label { color: var(--text-tertiary); width: 56px; flex-shrink: 0; }
.idcard-row .idcard-value { color: var(--text-primary); font-weight: 600; word-break: break-all; }
.idcard-empty { padding: 24px 22px; font-size: 13px; color: var(--text-secondary); text-align: center; line-height: 1.6; }

/* ---------- 商户列表常驻侧栏（不是弹窗：不遮罩、点地图不会关掉它，方便对照地图看） ---------- */
.mlist-panel {
  position: fixed; z-index: 45; top: var(--topbar-h, 56px); right: 0; bottom: 0; width: 320px; max-width: 90vw;
  background: var(--bg-glass-strong); backdrop-filter: var(--blur); -webkit-backdrop-filter: var(--blur);
  box-shadow: var(--shadow-lg); border-left: 1px solid var(--separator);
  display: flex; flex-direction: column; color: var(--text-primary);
  /* 顶部让开顶栏高度（JS 动态量出写入 --topbar-h），避免搜索框被顶栏盖住 */
}
/* 这个面板用的是 fixed + 物理方向的 right:0，不会跟着 <html dir="rtl"> 自动镜像
   （dir 只影响 flex 主轴方向/文字方向这些"逻辑属性"，物理的 left/right 不受影响，
   页面其它靠 flex 布局的地方——顶栏、侧边栏——已经会跟着 dir 自动镜像，只有这种
   写死 right:0 的固定面板需要单独在 RTL 下手动换成 left:0）。阿语习惯商户列表这类
   侧栏出现在左边，跟阅读方向的"起始边"一致。 */
body.is-rtl .mlist-panel {
  right: auto; left: 0;
  border-left: none; border-right: 1px solid var(--separator);
}
.mlist-head {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 14px 14px 10px;
  border-bottom: 1px solid var(--separator); font-weight: 700; font-size: 14px; flex-shrink: 0;
}
.mlist-head > span:first-child { flex: 1; }
.mlist-fulllist-btn { padding: 6px 12px; font-size: 12px; flex-shrink: 0; }
.mlist-search { flex-basis: 100%; padding: 8px 12px; border: 1px solid var(--border-color); border-radius: 999px; font-size: 13px; font-weight: 400; background: var(--bg-fill); color: var(--text-primary); }
.mlist-search:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-tint); }
.mlist-body { overflow-y: auto; padding: 10px 12px 16px; flex: 1; }
.mlist-card {
  border: 1px solid var(--separator); background: var(--bg-card); border-radius: var(--radius-md); padding: 11px 13px; margin-bottom: 10px; font-size: 12.5px;
  cursor: pointer; transition: transform .12s ease, border-color .15s ease;
}
.mlist-card:hover { background: var(--accent-tint); border-color: var(--accent); }
.mlist-card:active { transform: scale(0.99); }
.mlist-card-name { font-weight: 700; font-size: 13.5px; margin-bottom: 6px; color: var(--text-primary); }
.mlist-card-row { display: flex; gap: 6px; padding: 3px 0; color: var(--text-secondary); }
.mlist-card-row .mlist-card-label { color: var(--text-tertiary); flex-shrink: 0; min-width: 68px; }
.mlist-card-shops { display: flex; flex-wrap: wrap; gap: 4px; }
.mlist-shopchip {
  /* 背景色是 JS 按铺位当前状态现算的（跟地图上那块色块同一个颜色），所以这里不写死背景色，
     只留形状/间距；hover 用 filter 而不是换背景，免得把状态色盖掉。 */
  display: inline-block; padding: 3px 8px; border-radius: 999px;
  font-size: 12px; font-weight: 600; cursor: pointer; border: 1px solid transparent;
  transition: filter .12s ease, transform .12s ease;
}
.mlist-shopchip:hover { filter: brightness(0.92); }
.mlist-shopchip:active { transform: scale(0.95); }

.mlist-card.active { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-tint); }
.mlist-detail-btn { padding: 5px 10px; font-size: 12px; white-space: nowrap; margin-top: 8px; width: 100%; }
.mlist-empty { padding: 34px 14px; text-align: center; color: var(--text-tertiary); font-size: 13px; }

/* ---------- 详情页 ---------- */
.detail-view {
  position: fixed; inset: 0; background: var(--bg-page); z-index: 60; overflow-y: auto; color: var(--text-primary);
}
.detail-head {
  display: flex; align-items: center; gap: 14px; padding: 14px 20px; border-bottom: 1px solid var(--separator);
  position: sticky; top: 0; background: var(--bg-glass-strong);
  backdrop-filter: var(--blur); -webkit-backdrop-filter: var(--blur); z-index: 2;
}
.detail-head span { font-weight: 700; font-size: 15px; }
.detail-body { padding: 20px; max-width: 720px; margin: 0 auto; }
.detail-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
@media (max-width: 640px) { .detail-grid { grid-template-columns: 1fr; } }
.detail-section { margin-top: 22px; }
.detail-section h3 { font-size: 14px; color: var(--text-secondary); border-bottom: 1px solid var(--separator); padding-bottom: 6px; }
.log-item { font-size: 12px; padding: 8px 0; border-bottom: 1px dashed var(--separator); }
.log-item .log-meta { color: var(--text-tertiary); }

/* ---------- 账号管理 ---------- */
.um-list { display: flex; flex-direction: column; gap: 14px; margin-bottom: 24px; }
.um-row {
  border: 1px solid var(--separator); border-radius: var(--radius-md); padding: 14px 16px; background: var(--bg-card);
}
.um-row-super { background: rgba(255,214,10,0.1); border-color: rgba(255,214,10,0.4); }
.um-row-head { margin-bottom: 8px; font-size: 14px; }
.um-super-tag { font-size: 12px; color: #8a6d00; }
.um-perm-list { display: flex; flex-wrap: wrap; gap: 10px 18px; margin: 10px 0; }
.um-perm-item { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--text-primary); }
.um-perm-item input { cursor: pointer; accent-color: var(--accent); }
.um-perm-select {
  font-size: 12px; padding: 3px 6px; border-radius: var(--radius-sm); border: 1px solid var(--separator);
  background: var(--bg-fill-1); color: var(--text-primary); cursor: pointer;
}
/* 每一项权限旁边再挂一个小的"对此账号隐藏"勾选框——勾了之后这个账号自己看权限树的时候
   连这一项存不存在都看不到（不是灰色可申请，是压根不出现），跟主勾选框视觉上拉开一点距离。 */
.um-perm-item-row { display: flex; align-items: center; gap: 8px; }
.um-perm-hide { display: flex; align-items: center; gap: 3px; font-size: 11px; color: var(--text-tertiary); cursor: pointer; }
.um-perm-hide input { cursor: pointer; accent-color: var(--text-tertiary); width: 12px; height: 12px; }
.um-actions { display: flex; gap: 8px; margin-top: 10px; }
.um-msg { font-size: 12px; color: var(--success); min-height: 16px; margin: 6px 0 0; }
.um-msg-error { color: var(--danger); }
.um-new-row { border-style: dashed; }

/* ---------- 待审批（自助注册审批队列，R1.3） ---------- */
.um-reg-section { margin-bottom: 26px; }
.um-reg-section h3 { font-size: 14.5px; font-weight: 700; margin: 0 0 12px; }
.um-reg-row .um-row-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.um-reg-row-processed { opacity: 0.75; }
.um-reg-badge { display: inline-block; padding: 2px 9px; border-radius: 999px; font-size: 11px; font-weight: 600; }
.um-reg-badge-employee { background: #e5f1ff; color: #0a72d6; }
.um-reg-badge-merchant { background: #fff4d9; color: #b8830a; }
.um-reg-time { font-size: 12px; color: var(--text-tertiary); margin-left: auto; }
.um-reg-detail { font-size: 12.5px; color: var(--text-secondary); margin-top: 4px; }
.um-reg-status { padding: 2px 9px; border-radius: 999px; font-size: 11px; font-weight: 600; margin-left: auto; }
.um-reg-status-approved { background: rgba(52,199,89,0.15); color: var(--success); }
.um-reg-status-rejected { background: var(--danger-tint); color: var(--danger); }

/* 商户的"负责人"是个可增删的列表（不止一个人的时候），每人自己一块小卡片，
   主负责人靠一个单选按钮标出来（同一个商户下只能有一个主负责人）。 */
.mch-contacts { margin: 10px 0; padding: 10px 12px; border: 1px dashed var(--separator); border-radius: var(--radius-md); }
.mch-contacts-label { font-size: 12px; color: var(--text-secondary); margin-bottom: 8px; font-weight: 600; }
.mch-contacts-list { display: flex; flex-direction: column; gap: 8px; margin-bottom: 8px; }
.mch-contact-row { padding: 8px 10px; border: 1px solid var(--separator); border-radius: var(--radius-sm); background: var(--bg-fill); }
.mch-contact-row-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; }
.mch-contact-primary { display: flex; align-items: center; gap: 5px; font-size: 12px; color: var(--text-secondary); cursor: pointer; }
.mch-contact-primary input { cursor: pointer; accent-color: var(--accent); }
.mch-contact-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
@media (max-width: 560px) { .mch-contact-grid { grid-template-columns: 1fr 1fr; } }
.mch-contact-grid input {
  padding: 6px 8px; border: 1px solid var(--border-color); border-radius: 6px; font-size: 12px;
  background: var(--bg-card); color: var(--text-primary); width: 100%; box-sizing: border-box;
}
.mch-contact-grid input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-tint); }

/* 商户资料文件（营业执照/签署文件）：已经传了就显示文件名链接+删除，没传就是个文件选择框。 */
.mch-docs { margin: 10px 0; padding: 10px 12px; border: 1px dashed var(--separator); border-radius: var(--radius-md); }
.mch-docs-hint { font-size: 12px; color: var(--text-tertiary); margin: 10px 0; }
.mch-doc-cell { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.mch-doc-link { font-size: 12.5px; color: var(--accent); text-decoration: underline; word-break: break-all; }
.mch-signed-list { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; width: 100%; }
.mch-doc-row { display: flex; align-items: center; gap: 8px; }

/* 商户详情页/详细列表里"负责人"这一格：一人一行，主负责人挂个小标签。 */
.mch-contact-line { padding: 2px 0; }
.mch-primary-badge {
  display: inline-block; margin-left: 4px; padding: 1px 7px; border-radius: 999px; font-size: 10.5px;
  background: var(--accent-tint); color: var(--accent); font-weight: 600;
}
.mch-contact-extra { color: var(--text-tertiary); font-size: 12px; margin-left: 4px; }

/* ---------- 商户详细列表（M18）：整页卡片列表，铺位分组/铺位状态可以直接在这里改，
   其它字段还是只读 ---------- */
.mfull-card {
  border: 1px solid var(--separator); border-radius: var(--radius-md); background: var(--bg-card);
  padding: 14px 16px; margin-bottom: 14px;
}
.mfull-card-head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; font-size: 15px; }
.mfull-index {
  display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px;
  border-radius: 50%; background: var(--accent-tint); color: var(--accent); font-size: 11.5px; font-weight: 700; flex-shrink: 0;
}
/* 新/老客户状态：一个可点的小胶囊按钮，点一下就切换（切换前会弹二次确认），老客户是
   默认的中性配色，新客户换成强调色，一眼能看出这个商户续租测算该查哪一档单价。 */
.mfull-customer-type-btn {
  margin-left: auto; flex-shrink: 0; border: 1px solid var(--separator); border-radius: 999px;
  background: var(--bg-fill); color: var(--text-secondary); font-size: 11px; padding: 3px 10px;
  cursor: pointer; transition: background .15s ease, border-color .15s ease, color .15s ease;
}
.mfull-customer-type-btn:hover { background: var(--hover-tint); }
.mfull-customer-type-btn.is-new { background: var(--accent-tint); color: var(--accent); border-color: transparent; }
.mfull-row { display: grid; grid-template-columns: 110px 1fr; gap: 10px; padding: 6px 0; border-top: 1px dashed var(--separator); font-size: 13px; }
.mfull-row:first-of-type { border-top: none; }
.mfull-row label { color: var(--text-tertiary); font-size: 12px; }
@media (max-width: 560px) { .mfull-row { grid-template-columns: 1fr; gap: 2px; } }

/* 铺位分组：每一行是一组"物理上打通/算一间"的铺位，拖胶囊换行就是换组。
   position:relative 是给拖拽用的（见 .drag-lifted 的说明）。 */
.mfull-shopgroups { display: flex; flex-direction: column; gap: 6px; }
.mfull-group-row { position: relative; display: flex; flex-wrap: wrap; align-items: center; gap: 6px; min-height: 26px; padding: 2px; border-radius: var(--radius-sm); }
.mfull-group-row:hover { background: var(--hover-tint); }
.mfull-group-chip { position: relative; cursor: grab; touch-action: none; }
.mfull-group-chip:active { cursor: grabbing; }
/* 胶囊角上的小圆点单独显示财务状态颜色（胶囊主体一直是物业状态颜色）——两个颜色对不上
   就是物业/财务两边数据有出入，鼠标悬停胶囊能看到具体文字，先人工核对用。 */
.mfull-chip-finance-dot {
  position: absolute; top: -3px; right: -3px; width: 9px; height: 9px; border-radius: 50%;
  border: 1.5px solid var(--bg-card); box-shadow: 0 0 0 0.5px rgba(0,0,0,0.15); pointer-events: none;
}
/* 新建分组的空拖放区：没拖东西进来之前显示虚线框+提示文字（:empty 伪类判断"这一行现在
   一个胶囊都没有"，提示文字用 ::before 伪元素顶，不是真的 DOM 节点——这样拖拽排序那套
   "读容器里的兄弟元素算位置"的逻辑不会被这句提示文字干扰）。 */
.mfull-group-newdrop { border: 1px dashed var(--separator); }
.mfull-group-newdrop:empty::before {
  content: attr(data-hint); color: var(--text-tertiary); font-size: 11.5px; padding: 2px 6px;
}

/* 员工（负责人）+ 自己站的那组铺位：一个员工一个 block，员工信息行下面紧跟一条缩进的
   拖放区，视觉上明确"这组铺位是这个员工的"，同时不影响拖拽读取 DOM 的逻辑（拖拽只认
   .mfull-group-row 这个 class，不管它嵌在哪一层）。 */
.mfull-employee-block + .mfull-employee-block { margin-top: 4px; }
.mfull-employee-block .mfull-group-row { margin-left: 4px; padding-left: 6px; border-left: 2px solid var(--separator); }
.mfull-employee-info { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; }
.mfull-employee-empty { color: var(--text-tertiary); font-size: 12px; }
.mfull-unassigned-label { font-size: 11.5px; color: var(--text-tertiary); margin-top: 2px; }
.mfull-add-employee-btn { align-self: flex-start; }

/* 新增/编辑员工的轻量浮层面板——跟 .status-select-panel 一样是贴着触发按钮定位的浮层，
   字段复用 M11 商户负责人表单同款输入框样式（.mch-contact-grid input），保持视觉一致。 */
.employee-edit-panel {
  position: fixed; z-index: 95; background: var(--bg-card); border: 1px solid var(--separator);
  border-radius: var(--radius-md); box-shadow: var(--shadow-lg); padding: 10px; width: 220px;
  display: flex; flex-direction: column; gap: 6px;
}
.employee-edit-panel input {
  width: 100%; padding: 6px 8px; border: 1px solid var(--separator); border-radius: var(--radius-sm);
  background: var(--bg-fill); color: var(--text-primary); font-size: 13px; box-sizing: border-box;
}
.employee-edit-panel input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-tint); }
.employee-edit-actions { display: flex; gap: 6px; justify-content: flex-end; margin-top: 2px; }

/* ---------- 导出配置页（M19）：左边编辑，右边实时预览，跟弹窗模板编辑器（M15）用的是
   同一套 .pt-layout/.pt-editor/.pt-preview 布局，这里只加这页自己特有的控件样式。 ---------- */
.mex-mode-picker { display: flex; gap: 8px; flex-wrap: wrap; }
.mex-mode-btn {
  padding: 8px 14px; border-radius: var(--radius-sm); border: 1px solid var(--separator);
  background: var(--bg-fill); color: var(--text-primary); font-size: 13px; cursor: pointer;
  transition: background .15s ease, border-color .15s ease;
}
.mex-mode-btn:hover { background: var(--hover-tint); }
.mex-mode-btn.active { background: var(--accent); color: var(--on-accent); border-color: var(--accent); font-weight: 600; }
.mex-title-input {
  width: 100%; padding: 8px 12px; border: 1px solid var(--border-color); border-radius: 8px;
  font-size: 13px; background: var(--bg-fill); color: var(--text-primary); box-sizing: border-box;
}
.mex-title-input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-tint); }
.mex-toggle-row { display: flex; align-items: center; gap: 8px; cursor: pointer; font-size: 13px; color: var(--text-primary); }
/* "汇总数据"具体展示什么还没定，先放一个占位区，弱化显示，别让人以为这里已经能用了。 */
.mex-summary-placeholder { opacity: 0.6; }
.mex-coming-soon { font-size: 12px; color: var(--text-tertiary); margin: 4px 0 0; }
.mex-preview-frame {
  border: 1px solid var(--separator); border-radius: var(--radius-md); background: var(--bg-fill);
  padding: 10px; display: flex; align-items: center; justify-content: center;
}
.mex-preview-frame canvas { max-width: 100%; border-radius: 4px; box-shadow: var(--shadow-sm); display: block; }

.um-tabs {
  display: flex; gap: 4px; padding: 0 20px; border-bottom: 1px solid var(--separator);
  position: sticky; top: 57px; background: var(--bg-glass-strong);
  backdrop-filter: var(--blur); -webkit-backdrop-filter: var(--blur); z-index: 1;
}
.um-tab-btn {
  padding: 10px 16px; border: none; background: none; cursor: pointer; font-size: 13px;
  color: var(--text-secondary); border-bottom: 2px solid transparent; margin-bottom: -1px; font-weight: 500;
}
.um-tab-btn:hover { color: var(--accent); }
.um-tab-btn.active { color: var(--accent); border-bottom-color: var(--accent); font-weight: 700; }
/* "待审批" tab 上的未处理数量角标（R1.3），有待处理申请时才显示，见 refreshRegBadge()。 */
.um-tab-badge {
  display: inline-block; min-width: 16px; padding: 0 5px; margin-left: 4px; border-radius: 999px;
  background: var(--danger); color: #fff; font-size: 10.5px; font-weight: 700; line-height: 16px; text-align: center;
}

.link-select { width: 100%; padding: 8px 10px; border: 1px solid var(--border-color); border-radius: var(--radius-sm); font-size: 13px; background: var(--bg-fill); color: var(--text-primary); }

.um-import-row { background: var(--accent-tint); border-color: var(--accent); }
.um-import-hint { font-size: 12px; color: var(--text-secondary); margin: 8px 0 0; }

/* ---------- 个人信息页 ---------- */
.profile-summary { display: flex; align-items: center; gap: 16px; margin-bottom: 20px; }
.avatar-upload-wrap {
  position: relative; width: 56px; height: 56px; border-radius: 50%; flex-shrink: 0; cursor: pointer;
}
.avatar-upload-wrap .profile-avatar-lg {
  width: 56px; height: 56px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  font-size: 22px; font-weight: 700; color: #fff; overflow: hidden;
}
.avatar-upload-wrap .profile-avatar-lg img { width: 100%; height: 100%; object-fit: cover; display: block; }
.avatar-upload-badge {
  position: absolute; inset: 0; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  background: rgba(0,0,0,0.45); color: #fff; font-size: 16px; opacity: 0; transition: opacity 0.15s;
}
.avatar-upload-wrap:hover .avatar-upload-badge { opacity: 1; }
.avatar-remove-link {
  display: inline-block; margin-top: 4px; font-size: 11px; color: var(--text-tertiary); background: none; border: none;
  cursor: pointer; padding: 0; text-decoration: underline;
}
.avatar-remove-link:hover { color: var(--danger); }
.profile-summary-text .p-name { font-size: 18px; font-weight: 700; color: var(--text-primary); }
.profile-summary-text .p-role { font-size: 12px; color: var(--text-secondary); margin-top: 2px; }
.avatar-msg { font-size: 11px; color: var(--danger); margin: 4px 0 0; }

.perm-tags { display: flex; flex-wrap: wrap; gap: 8px; margin: 8px 0 24px; }
.perm-tag {
  font-size: 12px; padding: 6px 12px; border-radius: 999px; background: var(--accent-tint); color: var(--accent);
}
.perm-tag.perm-off { background: var(--bg-fill-2); color: var(--text-tertiary); text-decoration: line-through; }
/* 权限树四色语义：深蓝＝主分支/子权限全部拿到；浅蓝＝部分子权限或只有主分支只读；
   灰＝没开通、理论上可以申请；隐藏的节点直接不渲染，不需要单独的颜色。 */
.perm-tag.perm-dark { background: var(--accent); color: #fff; }
.perm-tag.perm-light { background: var(--accent-tint); color: var(--accent); }
.perm-tag.perm-gray { background: var(--bg-fill-2); color: var(--text-tertiary); }
.perm-legend { display: flex; flex-wrap: wrap; gap: 14px; margin: 4px 0 18px; font-size: 12px; color: var(--text-secondary); }
.perm-legend-item { display: flex; align-items: center; gap: 6px; }
.perm-legend-dot { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; }
.perm-legend-dot.perm-dark { background: var(--accent); }
.perm-legend-dot.perm-light { background: var(--accent-tint); border: 1px solid var(--accent); }
.perm-legend-dot.perm-gray { background: var(--bg-fill-2); border: 1px solid var(--separator); }

/* ---------- 权限树（通用：账号管理里的可编辑勾选框树 + 个人信息里的只读展示树都用这套结构） ---------- */
.perm-tree-group { margin-bottom: 16px; }
.perm-tree-group-title {
  font-size: 12px; font-weight: 700; color: var(--text-tertiary); text-transform: uppercase; letter-spacing: 0.04em;
  margin-bottom: 8px;
}
.perm-tree-dept { margin-top: 10px; }
.perm-tree-dept-title { font-size: 12px; font-weight: 600; color: var(--text-secondary); margin-bottom: 6px; }
/* 功能清单：没有独立权限位、纯参考展示的功能条目，跟上面能读/改/隐藏的权限标签区分开，
   用列表行而不是圆角标签，弱化视觉权重（这些不是"可操作的权限"，只是给超管看的功能盘点）。 */
.feature-inv-block { margin-top: 10px; padding-top: 8px; border-top: 1px dashed var(--separator); }
.feature-inv-title { font-size: 11px; color: var(--text-tertiary); margin-bottom: 6px; }
.feature-inv-row { display: flex; align-items: baseline; gap: 8px; padding: 3px 0; font-size: 12px; color: var(--text-secondary); }
.feature-inv-desc { flex: 1; }

.profile-divider { border-top: 1px solid var(--separator); margin: 16px 0 10px; }
.profile-logout-btn {
  width: 100%; padding: 11px; border: 1px solid var(--danger-tint); border-radius: 999px; background: var(--danger-tint);
  color: var(--danger); font-size: 13px; font-weight: 700; cursor: pointer; transition: transform .12s ease, opacity .15s ease;
}
.profile-logout-btn:hover { opacity: 0.85; }
.profile-logout-btn:active { transform: scale(0.97); }

/* ---------- 铺位弹窗模板设置页 ---------- */
.pt-body { max-width: 1040px; }
.pt-intro { font-size: 13px; color: var(--text-secondary); line-height: 1.6; margin: 0 0 14px; }
.pt-toolbar { display: flex; align-items: center; gap: 8px; margin-bottom: 16px; flex-wrap: wrap; }
.pt-toolbar-spacer { flex: 1; }
.pt-toolbar .btn:disabled { opacity: 0.4; cursor: default; }
.pt-layout { display: flex; gap: 26px; align-items: flex-start; }
.pt-editor { flex: 1 1 480px; min-width: 0; }
.pt-list { position: relative; display: flex; flex-direction: column; gap: 8px; }
.pt-row {
  display: flex; align-items: center; gap: 10px; border: 1px solid var(--separator);
  background: var(--bg-card); border-radius: var(--radius-md); padding: 10px 14px;
}
.pt-row-name { flex: 1; font-size: 13.5px; font-weight: 600; color: var(--text-primary); }
.pt-icon-btn {
  border: none; background: var(--hover-tint); color: var(--text-secondary); cursor: pointer;
  width: 26px; height: 26px; border-radius: 50%; font-size: 12px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
}
.pt-icon-btn:hover { background: var(--accent-tint); color: var(--accent); }
.pt-delete-btn:hover { background: var(--danger-tint); color: var(--danger); }
.pt-drag-handle { color: var(--text-tertiary); }
.pt-drag-handle:hover { background: var(--hover-tint); }
.pt-drag-handle:active { cursor: grabbing; }

/* 右边那一栏：实时预览，跟左边的勾选/排序同步更新，不用来回切换页面才知道弹窗长什么样 */
.pt-preview { flex: 0 0 320px; position: sticky; top: 24px; }
.pt-preview-label {
  font-size: 12px; font-weight: 700; color: var(--text-tertiary); text-transform: uppercase;
  letter-spacing: 0.04em; margin-bottom: 10px;
}
.pt-preview-popup {
  background: var(--bg-glass-strong); backdrop-filter: var(--blur); -webkit-backdrop-filter: var(--blur);
  border: 1px solid var(--separator); border-radius: var(--radius-xl); box-shadow: var(--shadow-lg);
  max-height: 74vh; display: flex; flex-direction: column; overflow: hidden;
}
.pt-preview-popup .popup-body { overflow-y: auto; }
.pt-preview-popup .popup-actions .btn { cursor: default; }
.pt-preview-empty { color: var(--text-tertiary); font-size: 13px; text-align: center; padding: 20px 0; }

#ptFieldOverlay { z-index: 79; }
.pt-field-dialog { z-index: 80; }
.pt-field-dialog .field-row { position: relative; }
.pt-translate-btn {
  position: absolute; right: 0; top: 0; font-size: 11.5px; padding: 0; text-decoration: none;
  color: var(--accent); cursor: pointer;
}
.pt-translate-btn:hover { text-decoration: underline; }
.pt-translate-status { font-size: 12px; color: var(--text-secondary); margin: -4px 0 10px; }
@media (max-width: 860px) {
  .pt-layout { flex-direction: column; }
  .pt-preview { position: static; width: 100%; }
}

/* ---------- 皮肤 / 配色切换（个人信息弹窗里） ---------- */
.theme-picker-title {
  font-size: 12px; font-weight: 700; color: var(--text-tertiary); text-transform: uppercase;
  letter-spacing: 0.04em; margin: 4px 0 10px;
}
.theme-picker { display: flex; gap: 12px; margin-bottom: 4px; }
.theme-swatch {
  flex: 1; display: flex; flex-direction: column; align-items: center; gap: 6px;
  border: none; background: none; cursor: pointer; padding: 2px; border-radius: var(--radius-md);
}
.theme-swatch-dot {
  width: 40px; height: 40px; border-radius: 50%; border: 2px solid transparent;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,0.06); transition: transform .12s ease, border-color .15s ease;
  display: flex; align-items: center; justify-content: center; font-size: 16px; color: #fff;
}
.theme-swatch:hover .theme-swatch-dot { transform: scale(1.06); }
.theme-swatch.active .theme-swatch-dot { border-color: var(--accent); box-shadow: 0 0 0 2px var(--bg-glass-strong), 0 0 0 4px var(--accent); }
.theme-swatch-label { font-size: 11px; color: var(--text-secondary); }
.theme-swatch.active .theme-swatch-label { color: var(--text-primary); font-weight: 600; }

/* ---------- 界面元素编号标签（M1.1 这种），只给超管沟通用，不影响普通用户 ----------
   默认全局隐藏，登录后如果是超级管理员，showApp() 会给 body 加 is-super-admin，才显示。
   登录页/语言选择页这时候还没登录、不知道是不是超管，所以也一并隐藏——不再像以前那样
   对这两个页面单独放行，避免任何人打开登录页都能看到这些开发调试用的编号。 */
.admin-code-tag {
  display: none; margin-left: 6px; padding: 1px 6px; border-radius: 5px;
  font-size: 10px; font-weight: 700; line-height: 1.5; letter-spacing: 0.02em;
  color: var(--text-tertiary); background: var(--bg-fill-2); border: 1px solid var(--border-color);
  vertical-align: middle; white-space: nowrap; font-family: -apple-system, "SF Mono", Menlo, monospace;
}
body.is-super-admin .admin-code-tag {
  display: inline-block;
}
/* 没有 <label> 文字可以挂靠的孤零零输入框（比如登录框），用这套壳子把标签钉在输入框右上角，
   不会挤进 flex 布局多出一整行。 */
.field-with-tag { position: relative; }
.admin-code-corner { position: absolute; top: -9px; right: 6px; margin-left: 0; }
/* 圆形小图标按钮（比如地图放大缩小）塞不下文字标签，钉在圆圈右上角外面。 */
.admin-code-circle { position: absolute; top: -6px; right: -8px; margin-left: 0; }

/* ---------- 项目与楼层管理页 ---------- */
.pf-intro { font-size: 13px; color: var(--text-secondary); margin: 0 0 16px; }
.pf-project-card {
  border: 1px solid var(--separator); border-radius: var(--radius-lg); padding: 14px 16px; margin-bottom: 14px;
  background: var(--bg-card);
}
.pf-project-head { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.pf-project-name { font-size: 15px; font-weight: 700; color: var(--text-primary); flex: 1; }
.pf-floor-list { display: flex; flex-direction: column; gap: 8px; }
.pf-floor-row {
  display: flex; align-items: center; gap: 10px; padding: 8px; border-radius: var(--radius-md);
  background: var(--bg-fill); flex-wrap: wrap;
}
.pf-floor-thumb { width: 48px; height: 34px; object-fit: cover; border-radius: 6px; flex-shrink: 0; background: #fff; border: 1px solid var(--border-color); }
.pf-floor-thumb-empty {
  display: flex; align-items: center; justify-content: center; font-size: 10px; color: var(--text-tertiary);
  text-align: center; line-height: 1.2; padding: 2px;
}
.pf-floor-name { font-size: 13.5px; font-weight: 600; color: var(--text-primary); flex: 1; min-width: 60px; }
.pf-upload-bg-label { font-size: 12px; padding: 6px 10px; cursor: pointer; }
.pf-add-floor-row, .pf-new-project {
  margin-top: 12px; padding-top: 12px; border-top: 1px dashed var(--separator);
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
}
.pf-new-project { flex-direction: column; align-items: stretch; border: none; margin-top: 4px; padding-top: 0; }
.pf-new-title { font-size: 13px; font-weight: 700; color: var(--text-primary); margin-bottom: 4px; }
.pf-name-row { display: flex; gap: 8px; flex-wrap: wrap; flex: 1; }
.pf-name-row input {
  flex: 1; min-width: 100px; padding: 8px 10px; border: 1px solid var(--border-color); border-radius: var(--radius-sm);
  font-size: 13px; background: var(--bg-fill); color: var(--text-primary);
}
.pf-msg { font-size: 12px; color: var(--text-secondary); }
.pf-msg-error { color: var(--danger); }
.pf-floor-msg { width: 100%; }

/* 改名就地编辑：跟"新增"用的是同一套三语输入框（.pf-name-row），外面套一层容器方便
   跟保存/取消按钮排版；.pf-floor-row-editing 编辑态下取消原本的水平居中对齐，
   改成靠上对齐，不然缩略图会跟着三行输入框一起被拉高、位置很怪。 */
.pf-edit-name-wrap { display: flex; flex-direction: column; gap: 8px; flex: 1; min-width: 200px; }
.pf-edit-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.pf-floor-row-editing { align-items: flex-start; }

/* ---------- 铺位价格标准（M22）：4个商铺类别各一行，老/新客户单价并排 ---------- */
.ps-intro { font-size: 13px; color: var(--text-secondary); margin: 0 0 14px; }
.ps-table { display: flex; flex-direction: column; gap: 10px; }
.ps-row {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap; padding: 10px 14px;
  border: 1px solid var(--separator); border-radius: var(--radius-md); background: var(--bg-card);
}
.ps-cat { font-size: 14px; font-weight: 600; min-width: 140px; }
.ps-field { display: flex; align-items: center; gap: 8px; }
.ps-field label { font-size: 12px; color: var(--text-tertiary); }
.ps-field input {
  width: 110px; padding: 6px 8px; border: 1px solid var(--separator); border-radius: var(--radius-sm);
  background: var(--bg-fill); color: var(--text-primary); font-size: 13px;
}
.ps-field input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-tint); }
.ps-updated-hint { font-size: 11.5px; color: var(--text-tertiary); margin-top: 12px; }

/* ---------- 生成确认书（M23）：类型切换 + 铺位续租/退铺条件按钮 + 保证金/扣减参数表单 ---------- */
.cl-type-tabs { display: flex; gap: 8px; margin-bottom: 16px; }
.cl-type-tab {
  padding: 8px 16px; border-radius: var(--radius-sm); border: 1px solid var(--separator);
  background: var(--bg-fill); color: var(--text-primary); font-size: 13px; cursor: pointer;
  transition: background .15s ease, border-color .15s ease, color .15s ease;
}
.cl-type-tab.active { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 600; }
.cl-section-title { font-size: 13px; font-weight: 600; margin: 16px 0 8px; color: var(--text-primary); }
.cl-shop-list { display: flex; flex-direction: column; gap: 6px; margin-bottom: 8px; }
.cl-shop-row {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap; padding: 8px 12px;
  border: 1px solid var(--separator); border-radius: var(--radius-sm); background: var(--bg-card);
}
.cl-shop-label { font-size: 13px; flex: 1; min-width: 140px; }
.cl-shop-role-toggle { display: flex; gap: 4px; }
.cl-role-btn {
  padding: 4px 12px; border-radius: 999px; border: 1px solid var(--separator); background: var(--bg-fill);
  color: var(--text-secondary); font-size: 12px; cursor: pointer; transition: background .15s ease, color .15s ease;
}
.cl-role-btn.active { background: var(--accent-tint); color: var(--accent); border-color: transparent; font-weight: 600; }
.cl-freeuse-check { display: flex; align-items: center; gap: 5px; font-size: 12px; color: var(--text-secondary); cursor: pointer; }
/* 服务费折扣按钮：默认（没点过）是灰色"折扣：无"，点一下切成高亮的"折扣：95折"——
   跟 .cl-role-btn 一样是个开关按钮，只是颜色用橙色系跟"续租/退铺"的强调色区分开，
   一眼能看出这是个额外的、非默认状态的开关。 */
.cl-discount-btn {
  padding: 4px 10px; border-radius: 999px; border: 1px solid var(--separator); background: var(--bg-fill);
  color: var(--text-secondary); font-size: 12px; cursor: pointer; transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.cl-discount-btn.active { background: #fff3e0; color: #b8650a; border-color: #f0b46b; font-weight: 600; }
.cl-checkbox-row { display: flex; align-items: center; gap: 8px; font-size: 13px; padding: 6px 0; cursor: pointer; }
.cl-carried-row { display: flex; gap: 8px; align-items: center; margin-bottom: 8px; }
.cl-carried-row input { flex: 1; padding: 6px 8px; border: 1px solid var(--separator); border-radius: var(--radius-sm); background: var(--bg-fill); color: var(--text-primary); font-size: 13px; }

/* ---------- 生成确认书：左边编辑表单 / 右边实时预览（M23） ---------- */
/* .detail-body 默认 max-width:720px 居中单栏，这个页面要放两栏，覆盖成更宽一点。 */
#confirmLetterBody.cl-split-body { max-width: 1360px; }
.cl-split { display: flex; align-items: flex-start; gap: 26px; }
.cl-editor-col { flex: 0 0 420px; min-width: 320px; }
.cl-preview-col { flex: 1; min-width: 0; position: sticky; top: 78px; align-self: flex-start; }
.cl-preview-head { font-size: 12.5px; font-weight: 700; color: var(--text-secondary); margin: 0 0 8px; letter-spacing: 0.02em; }
/* 预览是"一页一页"地出——中文正文/英文正文/表1/表2/表3 各自单独一张卡片（分组规则见
   confirmation-letter.js 的 pageGroup 注释，跟真正生成的 Word 文件强制分页是同一套规则），
   横版的表格页卡片本身也做得更宽，一眼能看出到时候是几页纸、哪几页要横着打印。 */
.cl-preview-pages { max-height: calc(100vh - 130px); overflow-y: auto; padding: 2px; }
.cl-pv-page-wrap { margin: 0 auto 22px; }
.cl-pv-page-wrap:last-child { margin-bottom: 2px; }
.cl-pv-page-label { font-size: 11px; color: var(--text-tertiary); text-align: center; margin-bottom: 6px; }
/* 预览页故意用固定的白底黑字（不跟着系统深色模式换色）——它模拟的是打印出来的 Word 页面，
   不是系统界面本身；字体也固定用 Times New Roman/宋体，跟 docx-writer.js 真正生成文件时
   用的字体一致，这样"预览长什么样"和"下载下来的文件长什么样"才对得上。竖版页面窄一点
   （模拟 A4 纵向比例），横版页面宽一点（模拟 A4 横向），两者宽度不一样是故意的。 */
.cl-pv-page {
  background: #fff; color: #1a1a1a; border: 1px solid var(--separator); border-radius: var(--radius-md);
  box-shadow: var(--shadow-md); font-family: "Times New Roman", "SimSun", "宋体", serif;
  margin: 0 auto; box-sizing: border-box; position: relative; overflow: hidden;
}
/* 用 aspect-ratio 卡真正的 A4 比例（竖版 210:297，横版 297:210）——光设置 aspect-ratio
   不够：这个容器是普通块级盒子、height:auto，按 CSS 正常块级布局规则，只要内容比 ratio
   算出来的高度多，盒子还是会被内容撑高，实际看着就不是标准 A4 形状了（之前的版本就是这样，
   用户反馈"还不是A4纸大小"）。真正锁死比例的办法是让内容不参与外层盒子的高度计算——内容
   包一层 .cl-pv-page-inner，绝对定位铺满整个盒子（position:absolute+inset:0），绝对定位的
   子元素本来就不会撑高父盒子，父盒子的高度就只由 aspect-ratio 决定，永远是标准 A4 比例；
   内容如果超出这个高度，交给 .cl-pv-page-inner 自己的 overflow-y:auto 内部滚动，不会丢数据，
   也不会把外层卡片撑变形。 */
.cl-pv-page-portrait { width: 100%; max-width: 620px; aspect-ratio: 210 / 297; }
.cl-pv-page-landscape { width: 100%; max-width: 100%; aspect-ratio: 297 / 210; }
.cl-pv-page-inner { position: absolute; inset: 0; overflow-y: auto; padding: 30px 36px; box-sizing: border-box; }
.cl-pv-p { margin: 0 0 3px; line-height: 1.55; }
.cl-pv-table-title { text-align: center; font-weight: 700; font-size: 18pt; margin: 4px 0 10px; }
.cl-pv-table-wrap { overflow-x: auto; }
.cl-pv-table { border-collapse: collapse; width: 100%; }
.cl-pv-page-landscape .cl-pv-table { min-width: 720px; }
.cl-pv-table td { border: 1px solid #000; padding: 5px 7px; text-align: center; vertical-align: middle; font-size: 11pt; line-height: 1.35; }
.cl-preview-empty { color: #8a8a8a; font-size: 13px; text-align: center; padding: 40px 10px; font-family: inherit; }
@media (max-width: 980px) {
  .cl-split { flex-direction: column; }
  .cl-editor-col { flex: 1 1 auto; width: 100%; min-width: 0; }
  .cl-preview-col { position: static; width: 100%; }
  .cl-preview-pages { max-height: none; }
  .cl-pv-page-portrait { max-width: 100%; }
}

/* ---------- 商户应缴数据（上半年应缴/下半年应缴/当前已缴/总计应缴）：M9 简版列表只读展示，
   M18.2 详细列表可编辑覆盖 ---------- */
.mlist-finance { margin: 8px 0; }
.mfull-finance { margin: 10px 0 14px; padding: 10px 12px; border: 1px solid var(--separator); border-radius: var(--radius-sm); background: var(--bg-fill); }
.mfin-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px 14px; }
.mfin-cell-label { font-size: 11px; color: var(--text-secondary); display: flex; align-items: center; gap: 4px; }
.mfin-cell-value { font-size: 14px; font-weight: 600; color: var(--text-primary); margin-top: 1px; }
.mfin-manual-tag {
  font-size: 10px; padding: 1px 5px; border-radius: 999px; background: #fff3e0; color: #b8650a;
  font-weight: 600; line-height: 1.5;
}
.mfin-edit-btn { margin-top: 10px; }
.mfin-edit-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px 14px; }
.mfin-edit-field { display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: var(--text-secondary); }
.mfin-edit-field input {
  padding: 6px 8px; border: 1px solid var(--separator); border-radius: var(--radius-sm);
  background: var(--bg-card); color: var(--text-primary); font-size: 13px;
}
.mfin-edit-hint { font-size: 11.5px; color: var(--text-tertiary); margin: 8px 0 0; }
.mfin-edit-actions { display: flex; gap: 8px; margin-top: 10px; }

/* ---------- 商户全生命周期管理（M24） ---------- */
.mlc-onboard-entry-btn.hidden { display: none; }
.mlc-account-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; font-size: 13px; }
.mlc-account-select {
  font-size: 13px; padding: 5px 8px; border-radius: var(--radius-sm); border: 1px solid var(--separator);
  background: var(--bg-fill-1); color: var(--text-primary); min-width: 180px;
}
.mlc-account-hint { font-size: 12.5px; color: var(--text-tertiary); line-height: 1.6; }
.mlc-account-msg { font-size: 12px; margin-top: 6px; color: var(--text-secondary); }
.mlc-account-msg.um-msg-error { color: var(--danger); }
.mlc-basic-head { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 10px 16px; }
.mlc-basic-head h3 { margin: 0; }
.mlc-actions { display: flex; flex-wrap: wrap; gap: 10px; }
/* 基本信息里"商铺号"按负责人分组显示（跟 M18.2 商户详细列表拖分组用的是同一份数据，
   见 mlcGroupedShopsHtml/computeShopGroups）——每个负责人自己一行，名字+这组的铺位胶囊；
   没分到具体负责人的铺位单独一行"未分配"。只读，不能在这页拖拽改组。 */
.mlc-shopgroups-readonly { display: flex; flex-direction: column; gap: 10px; margin-top: 4px; }
.mlc-shopgroup-row { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.mlc-shopgroup-name { font-size: 13px; font-weight: 600; color: var(--text-primary); min-width: 120px; display: flex; align-items: center; gap: 6px; }
.mlc-shopgroup-unassigned { color: var(--text-secondary); font-weight: 500; }
.mlc-shopgroup-shops { display: flex; flex-wrap: wrap; gap: 6px; }
.mlc-shopgroup-empty { color: var(--text-tertiary); font-size: 12px; }
.mlc-btn-muted { background: var(--bg-fill-2); color: var(--text-primary); }
.mlc-btn-muted:hover { background: var(--bg-fill-1); }
.mlc-timeline { display: flex; flex-direction: column; gap: 10px; margin-top: 10px; }
.mlc-evt-card {
  border: 1px solid var(--separator); border-left: 4px solid var(--accent); border-radius: var(--radius-md);
  padding: 10px 14px; background: var(--bg-card);
}
.mlc-evt-card.mlc-evt-new { border-left-color: #34c759; }
.mlc-evt-card.mlc-evt-renewal { border-left-color: var(--accent); }
.mlc-evt-card.mlc-evt-expansion { border-left-color: #ff9f0a; }
.mlc-evt-card.mlc-evt-termination { border-left-color: var(--danger); }
.mlc-evt-head { display: flex; align-items: center; gap: 10px; margin-bottom: 6px; }
.mlc-evt-head strong { font-size: 13.5px; }
.mlc-evt-time { font-size: 11.5px; color: var(--text-tertiary); margin-left: auto; }
.mlc-evt-row { display: flex; gap: 8px; font-size: 12.5px; padding: 2px 0; align-items: baseline; }
.mlc-evt-row label { color: var(--text-tertiary); flex: 0 0 auto; }
.mlc-evt-shops { display: flex; flex-wrap: wrap; gap: 4px; }
.mlc-evt-operator { color: var(--text-tertiary); }
.mlc-expand-panel {
  margin-top: 12px; padding: 14px; border: 1px dashed var(--separator); border-radius: var(--radius-md);
  background: var(--bg-fill-1);
}
.mlc-expand-title { font-weight: 700; font-size: 13.5px; margin-bottom: 6px; }
.mlc-expand-hint { font-size: 12px; color: var(--text-tertiary); line-height: 1.6; margin: 0 0 10px; }
.mlc-expand-actions { display: flex; gap: 10px; margin-top: 10px; }
.mlc-expand-msg { font-size: 12px; margin-top: 6px; color: var(--text-secondary); }
.mlc-expand-msg.um-msg-error { color: var(--danger); }
.mlc-onboard-shop-list {
  display: flex; flex-wrap: wrap; gap: 8px 16px; max-height: 220px; overflow-y: auto;
  padding: 10px; border: 1px solid var(--separator); border-radius: var(--radius-md); background: var(--bg-fill-1);
}
.mlc-onboard-shop-check { display: flex; align-items: center; gap: 6px; font-size: 12.5px; cursor: pointer; }
.mlc-onboard-shop-check input { cursor: pointer; accent-color: var(--accent); }

/* ---------- 铺位详情卡片（原 M8，整合进 M24 页面里，见 mlcShopCardHtml） ---------- */
.mlc-shop-list { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.mlc-shop-card { border: 1px solid var(--separator); border-radius: var(--radius-md); background: var(--bg-card); overflow: hidden; }
.mlc-shop-card-head {
  display: flex; align-items: center; gap: 8px; padding: 9px 14px; cursor: pointer; font-size: 13px; user-select: none;
}
.mlc-shop-card-head:hover { background: var(--bg-fill-1); }
.mlc-shop-dot { width: 9px; height: 9px; border-radius: 50%; flex: 0 0 auto; }
.mlc-shop-card-name { color: var(--text-secondary); font-size: 12.5px; }
.mlc-shop-chevron { margin-left: auto; color: var(--text-tertiary); transition: transform .15s ease; }
.mlc-shop-card-open .mlc-shop-chevron { transform: rotate(90deg); }
.mlc-shop-card-body { padding: 4px 14px 14px; border-top: 1px solid var(--separator); }
.mlc-name-edit-row { display: flex; align-items: center; gap: 8px; }
.mlc-name-edit-row input { flex: 1; min-width: 0; }
.mlc-name-hint { font-size: 11.5px; color: var(--text-tertiary); line-height: 1.5; margin: 4px 0 0; }
.mlc-name-msg { font-size: 12px; margin-top: 4px; color: var(--text-secondary); }
.mlc-name-msg.um-msg-error { color: var(--danger); }
.mlc-danger-zone { margin-top: 30px; padding-top: 16px; border-top: 1px dashed var(--separator); text-align: right; }
.mlc-delete-btn { background: var(--danger); color: #fff; }
.mlc-delete-btn:hover { opacity: 0.88; }

/* ---------- 商户自助端（B2） ---------- */
.merchant-portal { position: fixed; inset: 0; background: var(--bg-page); color: var(--text-primary); overflow-y: auto; z-index: 40; }
.mp-header {
  display: flex; align-items: center; justify-content: space-between; padding: 14px 24px;
  position: sticky; top: 0; background: var(--bg-glass-strong); backdrop-filter: var(--blur);
  -webkit-backdrop-filter: var(--blur); border-bottom: 1px solid var(--separator); z-index: 2;
}
.mp-header-title { display: flex; align-items: center; gap: 10px; font-weight: 700; font-size: 16px; }
.mp-logo { width: 28px; height: 28px; border-radius: 8px; object-fit: cover; }
.mp-header-actions { display: flex; align-items: center; gap: 14px; }
.mp-merchant-name { font-size: 13.5px; color: var(--text-secondary); font-weight: 600; }
.mp-main { max-width: 880px; margin: 0 auto; padding: 24px 20px 60px; }
.mp-loading { text-align: center; color: var(--text-tertiary); padding: 40px 0; }
.mp-section {
  background: var(--bg-card); border: 1px solid var(--separator); border-radius: var(--radius-lg);
  padding: 20px 22px; margin-bottom: 18px; box-shadow: var(--shadow-sm);
}

/* ---------- 收租待办倒计时横幅（R2.1） ---------- */
.mp-rent-banner {
  border-radius: var(--radius-lg); padding: 18px 22px; margin-bottom: 18px; box-shadow: var(--shadow-sm);
}
.mp-rent-banner-pending { background: rgba(255,149,0,0.12); border: 1px solid rgba(255,149,0,0.35); }
.mp-rent-banner-locked { background: var(--danger-tint); border: 1px solid rgba(255,59,48,0.35); }
.mp-rent-banner-title { font-size: 15px; font-weight: 700; margin-bottom: 6px; }
.mp-rent-banner-pending .mp-rent-banner-title { color: #b9690a; }
.mp-rent-banner-locked .mp-rent-banner-title { color: var(--danger); }
.mp-rent-banner-body { font-size: 13px; color: var(--text-secondary); line-height: 1.6; }
.mp-rent-banner-sub { font-size: 12px; color: var(--text-tertiary); margin-top: 6px; }
.mp-rent-banner-countdown {
  margin-top: 10px; font-size: 24px; font-weight: 700; font-variant-numeric: tabular-nums; color: #b9690a;
}
.mp-section h3 { margin: 0 0 14px; font-size: 15px; font-weight: 700; }
.mp-ob-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 12px; }
.mp-ob-card { background: var(--bg-fill); border-radius: var(--radius-md); padding: 14px 16px; }
.mp-ob-period { font-size: 12.5px; color: var(--text-secondary); margin-bottom: 6px; }
.mp-ob-amount { font-size: 19px; font-weight: 700; color: var(--accent); }
.mp-ob-cur { font-size: 12px; font-weight: 500; color: var(--text-tertiary); }
.mp-ob-sub { margin-top: 6px; font-size: 12px; color: var(--text-tertiary); }
.mp-grand-total { margin-top: 14px; font-size: 14px; text-align: right; }
.mp-grand-total strong { color: var(--accent); font-size: 17px; }
.mp-current-plan { font-size: 13px; color: var(--text-secondary); }
.mp-form-hint { font-size: 12.5px; color: var(--text-tertiary); margin: 0 0 14px; line-height: 1.6; }
.mp-inst-row { display: flex; gap: 10px; align-items: center; margin-bottom: 10px; }
.mp-inst-row input {
  padding: 8px 10px; border: 1px solid var(--separator); border-radius: var(--radius-sm);
  background: var(--bg-fill); color: var(--text-primary); font-size: 13px;
}
.mp-inst-date { flex: 0 0 160px; }
.mp-inst-amount { flex: 0 0 150px; }
.mp-inst-note { flex: 1; min-width: 0; }
.mp-inst-remove {
  flex: 0 0 30px; height: 30px; border: none; border-radius: 50%; background: var(--bg-fill-2);
  color: var(--text-secondary); font-size: 16px; cursor: pointer; line-height: 1;
}
.mp-inst-remove:hover:not(:disabled) { background: var(--danger-tint); color: var(--danger); }
.mp-inst-remove:disabled { opacity: 0.35; cursor: not-allowed; }
.mp-form-actions { display: flex; align-items: center; gap: 16px; margin-top: 6px; }
.mp-sum-hint { font-size: 12.5px; color: var(--text-secondary); }
.mp-form-submit { display: flex; align-items: center; gap: 14px; margin-top: 16px; }
.mp-form-error { color: var(--danger); font-size: 12.5px; }
.mp-history-list { display: flex; flex-direction: column; gap: 10px; }
.mp-history-item { background: var(--bg-fill); border-radius: var(--radius-md); padding: 10px 14px; }
.mp-history-meta { font-size: 12px; color: var(--text-tertiary); margin-bottom: 6px; }
.mp-history-installments { display: flex; flex-wrap: wrap; gap: 6px; }
.mp-chip { background: var(--bg-fill-2); border-radius: 999px; padding: 3px 10px; font-size: 12px; color: var(--text-secondary); }

/* ---------- 财务数据看板（G16.2） ---------- */
#financeDashboardBody { max-width: 1180px; }
.fd-summary-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 14px; margin-bottom: 26px; }
.fd-summary-card {
  background: var(--bg-card); border: 1px solid var(--separator); border-radius: var(--radius-lg);
  padding: 16px 18px; box-shadow: var(--shadow-sm);
}
.fd-summary-label { font-size: 12.5px; color: var(--text-secondary); margin-bottom: 8px; }
.fd-summary-value { font-size: 22px; font-weight: 700; color: var(--accent); }
.fd-section-title { font-size: 14.5px; font-weight: 700; margin: 26px 0 12px; }
.fd-chart {
  display: flex; align-items: flex-end; gap: 14px; height: 220px; padding: 10px 6px 0;
  border-bottom: 1px solid var(--separator); overflow-x: auto;
}
.fd-bar-col { display: flex; flex-direction: column; align-items: center; flex: 0 0 56px; height: 100%; }
.fd-bar-amount { font-size: 11px; color: var(--text-secondary); margin-bottom: 4px; white-space: nowrap; }
.fd-bar-track { flex: 1; width: 26px; display: flex; align-items: flex-end; background: var(--bg-fill); border-radius: 6px 6px 0 0; overflow: hidden; }
.fd-bar-fill { width: 100%; background: linear-gradient(180deg, var(--accent), var(--accent-deep)); border-radius: 6px 6px 0 0; }
.fd-bar-label { font-size: 11px; color: var(--text-tertiary); margin-top: 6px; white-space: nowrap; }
.fd-table-scroll { overflow-x: auto; }
.fd-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.fd-table-compact { max-width: 460px; }
.fd-table th, .fd-table td { padding: 9px 12px; border-bottom: 1px solid var(--separator); text-align: left; white-space: nowrap; }
.fd-table th { color: var(--text-secondary); font-weight: 600; font-size: 12.5px; }
.fd-num { text-align: right; font-variant-numeric: tabular-nums; }
.fd-badge { display: inline-block; padding: 2px 10px; border-radius: 999px; font-size: 12px; font-weight: 600; }
.fd-badge-yes { background: rgba(52,199,89,0.15); color: var(--success); }
.fd-badge-no { background: var(--bg-fill-2); color: var(--text-tertiary); }
.fd-badge-owing { background: rgba(255,149,0,0.15); color: #b9690a; }
.fd-badge-credit { background: rgba(52,199,89,0.15); color: var(--success); }

/* ---- 财务数据看板 筛选面板（G16.2 新增） ---- */
.fd-filter-panel {
  background: var(--bg-card); border: 1px solid var(--separator); border-radius: var(--radius-lg);
  padding: 14px 16px; margin-bottom: 22px; max-width: 1180px;
}
.fd-filter-row { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px; }
.fd-filter-row + .fd-filter-row { margin-top: 12px; }
.fd-filter-field { display: flex; flex-direction: column; gap: 5px; min-width: 120px; }
.fd-filter-field-grow { flex: 1 1 220px; }
.fd-filter-field label { font-size: 11.5px; color: var(--text-secondary); font-weight: 600; }
.fd-filter-input {
  padding: 7px 10px; border: 1px solid var(--border-color); border-radius: 8px; font-size: 13px;
  background: var(--bg-fill); color: var(--text-primary); min-width: 0;
}
.fd-filter-input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-tint); }
.fd-filter-input-num { width: 120px; }
.fd-filter-field-actions { flex-direction: row; gap: 8px; }
.fd-filter-field-actions .btn { font-size: 12.5px; padding: 7px 14px; }
.fd-filter-panel .btn-secondary { background: var(--bg-fill-2); color: var(--text-primary); }
.fd-filter-zones-row { align-items: center; }
.fd-filter-zones-label { font-size: 11.5px; color: var(--text-secondary); font-weight: 600; margin-right: 4px; }
.fd-zone-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.fd-zone-chips-empty { font-size: 12.5px; color: var(--text-tertiary); }
.fd-zone-chip {
  display: inline-flex; align-items: center; gap: 5px; padding: 5px 12px; border-radius: 999px;
  border: 1px solid var(--border-color); background: var(--bg-fill); font-size: 12.5px; cursor: pointer; user-select: none;
}
.fd-zone-chip input { margin: 0; accent-color: var(--accent); }
.fd-zone-chip-on { background: var(--accent-tint); border-color: var(--accent); color: var(--accent); font-weight: 600; }

/* ---- 运营数据看板（G16.3）：占用分组卡片 + 状态色点 ---- */
#operationsDashboardBody { max-width: 1180px; }
.od-bucket-card { border-top: 3px solid var(--separator); }
.od-bucket-occupied { border-top-color: #34c759; }
.od-bucket-vacant { border-top-color: #ff9500; }
.od-bucket-follow_up { border-top-color: #af52de; }
.od-bucket-unknown { border-top-color: #9a9a9a; }
.od-bucket-area { font-size: 11.5px; color: var(--text-tertiary); margin-top: 4px; }
.od-bucket-hint { font-size: 12px; color: var(--text-tertiary); line-height: 1.6; margin: 4px 0 0; max-width: 900px; }
.od-status-dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; margin-right: 7px; vertical-align: middle; }

/* ---- 商户数据看板（G16.1）：双栏汇总表 + 生命周期动态卡片 ---- */
#merchantDashboardBody { max-width: 1180px; }
.od-two-col { display: grid; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); gap: 0 32px; }
.od-feed-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 12px; }
.od-feed-card.mlc-evt-card { margin: 0; }

/* ---- 招商数据看板（G16.4）：净增铺位数柱状图（正/负两色） ---- */
#leasingDashboardBody { max-width: 1180px; }
.ld-bar-pos { background: linear-gradient(180deg, #34c759, #1f9e44); }
.ld-bar-neg { background: linear-gradient(180deg, #ff6b6b, #d9363e); }

/* ---- 招商线索管理（D4.1/D4.2）：新建/编辑表单 + 线索卡片 + 跟进记录 ---- */
#leasingLeadsBody { max-width: 1180px; }
.ll-form-card { background: var(--bg-card); border: 1px solid var(--separator); border-radius: 10px; padding: 16px 18px; margin: 14px 0 20px; }
.ll-form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 12px 16px; }
.ll-form-grid .fd-filter-field-grow { grid-column: 1 / -1; }
.ll-textarea { min-height: 64px; resize: vertical; font-family: inherit; }
.ll-form-hint { font-size: 12px; color: var(--text-tertiary); margin: 10px 0 0; }
.ll-lead-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 14px; }
.ll-lead-card { background: var(--bg-card); border: 1px solid var(--separator); border-radius: 10px; padding: 14px 16px; display: flex; flex-direction: column; gap: 8px; }
.ll-lead-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; }
.ll-lead-title { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.ll-lead-company { font-weight: 600; font-size: 14.5px; }
.ll-lead-actions { display: flex; gap: 6px; flex-shrink: 0; }
.ll-status-badge { display: inline-block; padding: 2px 9px; border-radius: 999px; font-size: 11px; font-weight: 600; background: var(--bg-fill); color: var(--text-secondary); }
.ll-status-new { background: #e5f1ff; color: #0a72d6; }
.ll-status-contacted { background: #fff4d9; color: #b8830a; }
.ll-status-negotiating { background: #ffe8d4; color: #c1631a; }
.ll-status-won { background: #e1f7e6; color: #1f9e44; }
.ll-status-lost { background: #f5e3e3; color: #b3392f; }
.ll-lead-info { display: flex; flex-wrap: wrap; gap: 6px 12px; font-size: 12.5px; color: var(--text-secondary); }
.ll-lead-notes { font-size: 12.5px; color: var(--text-secondary); white-space: pre-wrap; margin: 0; }
.ll-lead-meta { font-size: 11px; color: var(--text-tertiary); }
.ll-followups { border-top: 1px dashed var(--separator); padding-top: 8px; margin-top: 2px; display: flex; flex-direction: column; gap: 6px; }
.ll-followups-title { font-size: 12px; font-weight: 600; color: var(--text-secondary); }
.ll-followup-empty { font-size: 12px; color: var(--text-tertiary); margin: 0; }
.ll-followup-card { background: var(--bg-fill); border-radius: 8px; padding: 8px 10px; display: flex; flex-direction: column; gap: 3px; }
.ll-followup-meta { font-size: 11px; color: var(--text-tertiary); }
.ll-followup-note { font-size: 12.5px; white-space: pre-wrap; }
.ll-followup-card .btn-sm { align-self: flex-end; }
.ll-followup-add { display: flex; gap: 8px; align-items: center; }
.ll-followup-add .ll-followup-input { flex: 1; }

/* ---- 催缴与锁店提醒面板（R2.2）：跟招商线索管理共用 fd-summary-*/fd-filter-* 那套外壳，
   这里只补卡片本身+状态徽章的样式。 ---- */
#rentRemindersBody { max-width: 1180px; }
.rr-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 14px; }
.rr-card { background: var(--bg-card); border: 1px solid var(--separator); border-radius: 10px; padding: 14px 16px; display: flex; flex-direction: column; gap: 6px; }
.rr-card-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.rr-merchant-name { font-weight: 600; font-size: 14px; }
.rr-amount { margin-left: auto; font-size: 13px; font-weight: 700; color: var(--accent); font-variant-numeric: tabular-nums; }
.rr-status-badge { display: inline-block; padding: 2px 9px; border-radius: 999px; font-size: 11px; font-weight: 600; background: var(--bg-fill); color: var(--text-secondary); }
.rr-status-pending { background: #fff4d9; color: #b8830a; }
.rr-status-locked { background: var(--danger-tint); color: var(--danger); }
.rr-status-submitted { background: #e1f7e6; color: #1f9e44; }
.rr-status-resolved { background: #e5f1ff; color: #0a72d6; }
.rr-status-cancelled { background: var(--bg-fill-2); color: var(--text-tertiary); }
.rr-timing { font-size: 12.5px; color: var(--text-secondary); }
.rr-timing-locked { color: var(--danger); font-weight: 600; }

/* ---- 工单中心（G15.1/G15.2，员工端队列跟商户端提交表单共用这套 .wo-* 样式）：
   卡片外壳复用 .rr-card/.rr-list/.fd-summary-*/.fd-zone-chip（跟催缴与锁店提醒同款），
   这里只补板块/类型选择器、照片上传预览、状态徽章这些工单专属的部分。 ---- */
.wo-section-tabs { display: flex; gap: 8px; margin-bottom: 12px; flex-wrap: wrap; }
.wo-section-tab {
  padding: 7px 16px; border-radius: 999px; border: 1px solid var(--border-color);
  background: var(--bg-fill); color: var(--text-secondary); font-size: 13px; font-weight: 600; cursor: pointer;
}
.wo-section-tab.active { background: var(--accent); border-color: var(--accent); color: #fff; }
.wo-cat-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 8px; margin-bottom: 16px; }
.wo-cat-btn {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px; padding: 10px 12px;
  border-radius: var(--radius-md); border: 1px solid var(--border-color); background: var(--bg-fill);
  color: var(--text-primary); font-size: 13px; cursor: pointer; text-align: left;
}
.wo-cat-btn.active { border-color: var(--accent); background: var(--accent-tint); color: var(--accent); font-weight: 600; }
.wo-cat-btn.wo-cat-urgent { border-color: rgba(255,59,48,0.35); }
.wo-urgent-tag { font-size: 11px; color: var(--danger); font-weight: 600; }
.wo-pick-hint { font-size: 13px; color: var(--text-tertiary); margin: 0 0 16px; }
.wo-form { background: var(--bg-fill); border-radius: var(--radius-md); padding: 14px 16px; margin-bottom: 20px; }
.wo-desc-input {
  width: 100%; min-height: 72px; resize: vertical; font-family: inherit; font-size: 13px;
  padding: 9px 11px; border: 1px solid var(--border-color); border-radius: var(--radius-sm);
  background: var(--bg-card); color: var(--text-primary); box-sizing: border-box;
}
.wo-photo-upload { display: flex; align-items: center; gap: 12px; margin-top: 10px; }
.wo-photo-add-btn { cursor: pointer; font-size: 12.5px; padding: 7px 14px; }
.wo-photo-hint { font-size: 11.5px; color: var(--text-tertiary); }
.wo-photo-list { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 10px; }
.wo-photo-thumb { position: relative; width: 72px; height: 72px; border-radius: var(--radius-sm); overflow: hidden; border: 1px solid var(--separator); }
.wo-photo-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.wo-photo-remove {
  position: absolute; top: 2px; right: 2px; width: 18px; height: 18px; border-radius: 50%; border: none;
  background: rgba(0,0,0,0.55); color: #fff; font-size: 12px; line-height: 1; cursor: pointer;
}
.wo-form-error { color: var(--danger); font-size: 12.5px; min-height: 16px; margin: 10px 0 0; }
.wo-my-list h4 { font-size: 13.5px; font-weight: 700; margin: 0 0 10px; }
.wo-my-list .wo-card + .wo-card { margin-top: 12px; }
.wo-card { background: var(--bg-card); border: 1px solid var(--separator); border-radius: 10px; padding: 14px 16px; display: flex; flex-direction: column; gap: 8px; }
.wo-card-urgent { border-color: rgba(255,59,48,0.45); box-shadow: 0 0 0 1px rgba(255,59,48,0.15); }
.wo-card-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.wo-status-badge { display: inline-block; padding: 2px 9px; border-radius: 999px; font-size: 11px; font-weight: 600; background: var(--bg-fill); color: var(--text-secondary); }
.wo-status-open { background: #fff4d9; color: #b8830a; }
.wo-status-in_progress { background: #e5f1ff; color: #0a72d6; }
.wo-status-resolved { background: #e1f7e6; color: #1f9e44; }
.wo-status-cancelled { background: var(--bg-fill-2); color: var(--text-tertiary); }
.wo-priority-badge { display: inline-block; padding: 2px 9px; border-radius: 999px; font-size: 11px; font-weight: 700; background: var(--danger-tint); color: var(--danger); }
.wo-section-label { font-size: 12px; color: var(--text-tertiary); }
.wo-cat-label { font-weight: 600; font-size: 13.5px; }
.wo-card-desc { font-size: 12.5px; color: var(--text-secondary); white-space: pre-wrap; }
.wo-card-meta { font-size: 11.5px; color: var(--text-tertiary); }
.wo-card-assignee { font-size: 12px; color: var(--text-secondary); }
.wo-card-photos { display: flex; flex-wrap: wrap; gap: 8px; }
.wo-card-photo-thumb { width: 64px; height: 64px; object-fit: cover; border-radius: var(--radius-sm); border: 1px solid var(--separator); display: block; }
.wo-comments { border-top: 1px dashed var(--separator); padding-top: 8px; display: flex; flex-direction: column; gap: 6px; }
.wo-comment { background: var(--bg-fill); border-radius: 8px; padding: 7px 10px; }
.wo-comment-meta { font-size: 11px; color: var(--text-tertiary); }
.wo-comment-note { font-size: 12.5px; white-space: pre-wrap; margin-top: 2px; }
.wo-comment-input-row { display: flex; gap: 8px; align-items: center; }
.wo-comment-input {
  flex: 1; padding: 7px 10px; border: 1px solid var(--separator); border-radius: var(--radius-sm);
  background: var(--bg-fill); color: var(--text-primary); font-size: 12.5px;
}
