/* ===== 物业管理系统 · 共享样式 ===== */
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
:root{
  --primary:#2A5BFF;--primary-hover:#1E4FE0;--primary-soft:#EAF0FF;
  --primary-gradient:linear-gradient(135deg,#2A5BFF,#6366F1);
  --bg:#F5F7FB;--surface:#FFFFFF;--border:#E6EAF2;
  --text:#1F2937;--text-sub:#67738A;--text-faint:#98A2B6;
  --success:#16A34A;--warn:#D97706;--danger:#E5484D;
  --success-soft:#E9F7EF;--warn-soft:#FBF3E3;--danger-soft:#FDEBEC;
  --info-soft:#EAF0FF;
  --sbw:232px;
  --font:"Segoe UI","PingFang SC","Microsoft YaHei","Microsoft JhengHei","Helvetica Neue",Arial,sans-serif;
  --mono:"SF Mono","Cascadia Code",Consolas,monospace;
  --r-sm:8px;--r-md:12px;--r-lg:16px;
  --shadow-sm:0 1px 2px rgba(31,41,55,.06);
  --shadow-md:0 6px 20px rgba(31,41,55,.08);
  --shadow-lg:0 16px 40px rgba(31,41,55,.14);
}
html,body{height:100%}
body{font-family:var(--font);background:var(--bg);color:var(--text);font-size:14px;line-height:1.55;-webkit-font-smoothing:antialiased}
body::before{content:"";position:fixed;inset:0;background:radial-gradient(900px 360px at 85% -6%,rgba(42,91,255,.06),transparent 60%);z-index:0;pointer-events:none}
.app{position:relative;z-index:1}
.ic{display:inline-flex;align-items:center;justify-content:center;width:1em;height:1em;vertical-align:-0.14em}
.ic svg{width:1.18em;height:1.18em;stroke:currentColor;fill:none;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
.ic.caret svg{width:.85em;height:.85em}

/* ---------- Sidebar ---------- */
.shell-nav{position:fixed;inset:0 auto 0 0;width:var(--sbw);background:#111A2E;color:#C7D0E4;display:flex;flex-direction:column;z-index:20}
.brand{display:flex;align-items:center;gap:10px;padding:20px 20px 16px}
.brand-mark{width:34px;height:34px;border-radius:9px;background:linear-gradient(135deg,#2A5BFF,#5B8CFF);color:#fff;display:flex;align-items:center;justify-content:center}
.brand-mark .ic{font-size:19px}
.brand-name{font-size:16px;font-weight:700;color:#fff;letter-spacing:.2px}
.project-menu{position:relative;margin:0 14px 18px}
.project-chip{display:flex;align-items:center;gap:8px;width:100%;padding:9px 12px;background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.08);border-radius:var(--r-sm);color:#E6EBF6;font-size:13px;font-family:inherit;text-align:left;cursor:pointer;white-space:nowrap}
.project-chip span{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.project-chip .ic{opacity:.8;flex-shrink:0}
.project-chip .caret{margin-left:auto;flex-shrink:0}
.project-drop{position:absolute;top:calc(100% + 8px);left:0;right:0;background:#1e2642;border:1px solid rgba(255,255,255,.1);border-radius:var(--r-md);box-shadow:0 10px 28px rgba(0,0,0,.35);padding:6px;opacity:0;visibility:hidden;transform:translateY(-6px);transition:.16s;z-index:60}
.project-menu.open .project-drop{opacity:1;visibility:visible;transform:none}
.project-option{display:flex;align-items:center;gap:9px;width:100%;padding:9px 11px;border-radius:var(--r-sm);background:transparent;border:0;color:#E6EBF6;font-size:13px;text-align:left;cursor:pointer}
.project-option span{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.project-option:hover{background:rgba(255,255,255,.08)}
.project-option.active{background:rgba(42,91,255,.25);color:#fff}
.project-option .ic{font-size:16px;opacity:.9}
.nav{flex:1;overflow-y:auto;padding:0 10px}
.nav-item{display:flex;align-items:center;gap:11px;padding:10px 12px;margin:2px 0;border-radius:var(--r-sm);color:#A9B4CC;font-size:14px;text-decoration:none;transition:background .15s,color .15s}
.nav-item .ic{font-size:18px;opacity:.9}
.nav-item:hover{background:rgba(255,255,255,.05);color:#E6EBF6}
.nav-item.active{background:var(--primary-gradient);color:#fff;box-shadow:0 2px 8px rgba(42,91,255,.4)}
/* 二级菜单 */
.nav-group{margin:2px 0}
.nav-group-head{display:flex;align-items:center;gap:11px;padding:10px 12px;border-radius:var(--r-sm);color:#A9B4CC;font-size:14px;cursor:pointer;user-select:none;transition:background .15s,color .15s}
.nav-group-head:hover{background:rgba(255,255,255,.05);color:#E6EBF6}
.nav-group-head .ic{font-size:18px;opacity:.9}
.nav-group-head .g-label{flex:1}
.nav-group-head .caret{opacity:.6;transition:transform .2s}
.nav-group.has-active>.nav-group-head{color:#E6EBF6}
.nav-group.open>.nav-group-head .caret{transform:rotate(180deg)}
.nav-sub{max-height:0;overflow:hidden;transition:max-height .24s ease;padding-left:12px;margin-left:9px;border-left:1px solid rgba(255,255,255,.08)}
.nav-group.open>.nav-sub{max-height:520px}
.nav-sub .nav-item{padding:9px 12px;font-size:13.5px}
.nav-sub .nav-item .ic{font-size:16px}
.nav-foot{border-top:1px solid rgba(255,255,255,.07);padding:10px}
button.nav-item{width:100%;background:none;border:0;font-family:inherit;font-size:inherit;text-align:left;cursor:pointer}

/* ---------- Top bar ---------- */
.shell-top{position:fixed;top:0;right:0;left:var(--sbw);height:60px;background:rgba(255,255,255,.92);backdrop-filter:blur(6px);border-bottom:1px solid var(--border);display:flex;align-items:center;justify-content:space-between;padding:0 28px;z-index:15}
.top-title{font-size:17px;font-weight:700;letter-spacing:.2px}
.top-actions{display:flex;align-items:center;gap:14px}
.top-search{display:flex;align-items:center;gap:8px;background:var(--bg);border:1px solid var(--border);border-radius:var(--r-sm);padding:7px 12px;width:260px;color:var(--text-faint)}
.top-search input{border:none;outline:none;background:transparent;font-family:var(--font);font-size:13px;color:var(--text);width:100%}
.icon-btn{position:relative;width:38px;height:38px;border:1px solid var(--border);background:var(--surface);border-radius:var(--r-sm);display:flex;align-items:center;justify-content:center;cursor:pointer;color:var(--text-sub);transition:.15s}
.icon-btn:hover{border-color:var(--primary);color:var(--primary)}
.icon-btn .dot{position:absolute;top:8px;right:9px;width:7px;height:7px;border-radius:50%;background:var(--danger);border:1.5px solid #fff}
.user-chip{display:flex;align-items:center;gap:10px;padding:5px 4px 5px 6px;border-radius:var(--r-sm);cursor:pointer;background:none;border:0;font-family:inherit;text-align:left;color:inherit}
.user-chip:hover{background:var(--bg)}
.user-menu{position:relative}
.user-drop{position:absolute;top:calc(100% + 10px);right:0;min-width:158px;background:var(--surface);border:1px solid var(--border);border-radius:var(--r-md);box-shadow:var(--shadow-lg);padding:6px;opacity:0;visibility:hidden;transform:translateY(-6px);transition:.16s;z-index:60}
.user-menu.open .user-drop{opacity:1;visibility:visible;transform:none}
.user-drop a{display:flex;align-items:center;gap:9px;padding:9px 11px;border-radius:var(--r-sm);color:var(--text);font-size:13.5px;text-decoration:none}
.user-drop a:hover{background:var(--bg);color:var(--primary)}
.user-drop a .ic{font-size:16px;color:var(--text-sub)}
.avatar{width:36px;height:36px;border-radius:50%;background:linear-gradient(135deg,#2A5BFF,#7C9CFF);color:#fff;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:15px}
.user-meta b{display:block;font-size:13px;color:var(--text);line-height:1.2}
.user-meta small{font-size:11.5px;color:var(--text-faint)}
/* ---------- 通知中心（顶栏铃铛下拉） ---------- */
.notify-menu{position:relative}
.notify-drop{position:absolute;top:calc(100% + 10px);right:0;width:320px;background:var(--surface);border:1px solid var(--border);border-radius:var(--r-md);box-shadow:var(--shadow-lg);opacity:0;visibility:hidden;transform:translateY(-6px);transition:.16s;z-index:60;overflow:hidden}
.notify-menu.open .notify-drop{opacity:1;visibility:visible;transform:none}
.notify-title{padding:12px 14px;font-size:13.5px;font-weight:600;border-bottom:1px solid var(--border);color:var(--text)}
.notify-body{max-height:320px;overflow:auto}
.notify-item{display:block;padding:11px 14px;border-bottom:1px solid var(--border);text-decoration:none;color:var(--text)}
.notify-item:hover{background:var(--bg)}
.notify-item .t{display:block;font-size:13px;font-weight:600;margin-bottom:3px}
.notify-item .m{font-size:12px;color:var(--text-faint)}
.notify-empty{padding:22px 14px;text-align:center;color:var(--text-faint);font-size:13px}
.notify-foot{border-top:1px solid var(--border);padding:9px 14px;text-align:center}
.notify-foot a{font-size:12.5px;color:var(--primary);text-decoration:none}

/* ---------- Main ---------- */
.shell-main{margin-left:var(--sbw);padding:84px 28px 40px;position:relative}
.page-head{display:flex;align-items:flex-end;justify-content:space-between;margin-bottom:22px;gap:16px;flex-wrap:wrap}
.page-head h1{font-size:22px;font-weight:700;letter-spacing:.2px}
.page-head .sub{color:var(--text-sub);font-size:13.5px;margin-top:4px}
.head-actions{display:flex;gap:10px;align-items:center}

/* ---------- Buttons ---------- */
.btn{display:inline-flex;align-items:center;gap:7px;padding:9px 16px;border-radius:var(--r-sm);font-family:var(--font);font-size:13.5px;font-weight:600;cursor:pointer;border:1px solid transparent;transition:.16s;white-space:nowrap}
.btn .ic{font-size:16px}
.btn-primary{background:var(--primary-gradient);color:#fff;box-shadow:0 2px 8px rgba(42,91,255,.28)}
.btn-primary:hover{filter:brightness(1.05);box-shadow:0 4px 12px rgba(42,91,255,.34)}
.btn-secondary{background:var(--surface);border-color:var(--border);color:var(--text)}
.btn-secondary:hover{border-color:var(--primary);color:var(--primary)}
.btn-ghost{background:transparent;color:var(--text-sub)}
.btn-ghost:hover{background:var(--bg);color:var(--text)}
.btn:disabled{cursor:not-allowed;opacity:.45;box-shadow:none}
.btn-primary:disabled{background:var(--border);color:var(--text-sub)}
.btn-secondary:disabled{background:var(--bg);color:var(--text-faint);border-color:var(--border)}
.batch-summary{font-size:12.5px;color:var(--text-sub);padding:0 4px;white-space:nowrap}
/* 预览明细重复行与删除确认弹窗 */
tr.bp-dup{background:rgba(220,38,38,.06)}
tr.bp-dup td:first-child{box-shadow:inset 3px 0 0 #dc2626}
.confirm-msg{font-size:14px;line-height:1.7;color:var(--text)}
.dup-sub{display:inline-block;margin-top:4px;color:var(--text-sub);font-size:13px}
.dup-list{margin-top:10px}
.dup-list ul{margin:6px 0 0;padding-left:18px}
.dup-list li{font-size:13px;color:var(--text-sub);margin:3px 0}
.dup-mini{margin:8px 0 0;padding-left:18px;list-style:disc}
.dup-mini li{font-size:13px;color:var(--text-sub);margin:3px 0}
/* 重复账单提示：红字警示，突出"已跳过"的提醒 */
#bpDupWarn{color:#dc2626;font-weight:600}
#bpDupWarn b{color:#dc2626}
#bpDupWarn .dup-mini li{color:#b91c1c;font-weight:400}
#bpDupWarn .dup-list, #bpDupWarn .dup-list b{color:#b91c1c}
.btn-danger{background:var(--danger);color:#fff}
.btn-danger:hover{background:#c93d42}
.btn-sm{padding:6px 12px;font-size:12.5px}
.btn[disabled]{opacity:.5;cursor:not-allowed}

/* ---------- Form ---------- */
.field{display:flex;flex-direction:column;gap:6px;margin-bottom:16px}
.field-label{font-size:13px;font-weight:600;color:var(--text)}
.field-label .req{color:var(--danger)}
.field-hint{font-size:12px;color:var(--text-sub);line-height:1.4}
.input,.select,.textarea{width:100%;padding:9px 12px;border:1px solid var(--border);border-radius:var(--r-sm);font-family:var(--font);font-size:13.5px;color:var(--text);background:var(--surface);outline:none;transition:border .15s,box-shadow .15s}
.textarea{min-height:80px;resize:vertical}
.input:focus,.select:focus,.textarea:focus{border-color:var(--primary);box-shadow:0 0 0 3px rgba(42,91,255,.12)}
.select{appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%2367738A' stroke-width='2'%3E%3Cpath d='m3 4.5 3 3 3-3'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 12px center}
.check-row{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--text-sub)}
/* 字段级开关：控制该字段是否带入发票备注（启用/禁用状态明确） */
.field-label-row{display:flex;align-items:center;justify-content:space-between;gap:8px}
.switch{position:relative;display:inline-flex;align-items:center;gap:6px;cursor:pointer;user-select:none;flex:none}
.switch input{position:absolute;opacity:0;width:0;height:0}
.switch .track{width:34px;height:18px;border-radius:999px;background:#d4d9e2;transition:.16s;position:relative;flex:none}
.switch .track::after{content:"";position:absolute;top:2px;left:2px;width:14px;height:14px;border-radius:50%;background:#fff;box-shadow:0 1px 2px rgba(0,0,0,.2);transition:.16s}
.switch input:checked + .track{background:var(--primary)}
.switch input:checked + .track::after{transform:translateX(16px)}
.switch .lbl{font-size:12px;color:var(--text-faint);white-space:nowrap}
.switch .lbl::before{content:"不带入备注"}
.switch input:checked ~ .lbl{color:var(--primary)}
.switch input:checked ~ .lbl::before{content:"带入备注"}
.switch input:disabled + .track{opacity:.55}
.switch input:disabled ~ .lbl{opacity:.55}

/* ---------- Card ---------- */
.card{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-md);box-shadow:var(--shadow-sm)}
.card-head{display:flex;align-items:center;justify-content:space-between;padding:16px 18px;border-bottom:1px solid var(--border)}
.card-head h3{font-size:14.5px;font-weight:700}
.card-head .actions{display:flex;gap:8px}
.card-body{padding:18px}

/* ---------- Stat cards ---------- */
.stats{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;margin-bottom:22px}
.stat{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-md);box-shadow:var(--shadow-sm);padding:18px;display:flex;gap:14px;align-items:flex-start}
.stat-ic{width:44px;height:44px;border-radius:12px;display:flex;align-items:center;justify-content:center;flex-shrink:0}
.stat-ic .ic{font-size:21px}
.stat.bu .stat-ic{background:var(--primary-soft);color:var(--primary)}
.stat.ye .stat-ic{background:var(--success-soft);color:var(--success)}
.stat.wo .stat-ic{background:var(--warn-soft);color:var(--warn)}
.stat.al .stat-ic{background:var(--danger-soft);color:var(--danger)}
.stat-meta{min-width:0}
.stat-meta .label{font-size:12.5px;color:var(--text-sub)}
.stat-meta .value{font-size:25px;font-weight:700;line-height:1.15;font-variant-numeric:tabular-nums}
.stat-meta .delta{font-size:12px;color:var(--text-sub);margin-top:5px;display:flex;align-items:center;gap:4px}
.stat-meta .delta .up{color:var(--success)}.stat-meta .delta .down{color:var(--danger)}
.stat-meta .delta .ic{font-size:13px}

/* ---------- Layout grid ---------- */
.grid-2{display:grid;grid-template-columns:2fr 1fr;gap:16px}
.grid-3{display:grid;grid-template-columns:repeat(3,1fr);gap:16px}
.grid-4{display:grid;grid-template-columns:repeat(4,1fr);gap:16px}
.grid-2-1{display:grid;grid-template-columns:1.4fr 1fr;gap:16px}
.mt-16{margin-top:16px}.mt-20{margin-top:20px}.mb-16{margin-bottom:16px}
.section-title{font-size:15px;font-weight:700;margin:24px 0 14px;display:flex;align-items:center;gap:8px}
.section-title .ic{color:var(--primary)}

/* ---------- Toolbar ---------- */
.toolbar{display:flex;align-items:center;gap:10px;margin-bottom:16px;flex-wrap:wrap}
.toolbar .input,.toolbar .select{width:auto}
.toolbar .spacer{flex:1}
.tabs{display:flex;gap:2px;background:var(--bg);border:1px solid var(--border);padding:3px;border-radius:var(--r-sm)}
.tabs .tab{display:inline-flex;align-items:center;gap:6px;padding:6px 14px;border-radius:6px;font-size:13px;font-weight:600;color:var(--text-sub);cursor:pointer;border:none;background:transparent;font-family:var(--font)}
.tabs .tab.active{background:var(--surface);color:var(--primary);box-shadow:var(--shadow-sm)}

/* ---------- Table ---------- */
.table-wrap{overflow-x:auto}
.table{width:100%;border-collapse:collapse;font-size:13.5px}
/* 列表页表头（列名）统一居中；列宽、排序、筛选等交互不受影响（仅改对齐方式） */
.table thead th{padding:10px 14px;text-align:center;font-size:12.5px;color:var(--text-sub);font-weight:600;background:var(--bg);border-bottom:1px solid var(--border);white-space:nowrap}
.table tbody tr{border-bottom:1px solid var(--border);transition:background .12s}
.table tbody tr:hover{background:#F8FAFF}
.table tbody td{padding:11px 14px;vertical-align:middle}
.table .cell-num{text-align:right;font-variant-numeric:tabular-nums}
/* 数值列的表头也居中（.cell-num 优先级高于 .table thead th，需单独覆盖）；单元格内容仍右对齐 */
.table thead th.cell-num{text-align:center}
.table .cell-strong{font-weight:600}
.table .row-actions{display:flex;gap:6px;justify-content:flex-end;flex-wrap:nowrap}
/* 操作列按钮：同一按钮内的图标与文字必须保持同一行，
   避免「发票查看」「换开」等较长的提示文字被折成两行 */
.table .row-actions .link-btn{white-space:nowrap}
/* 账单列表「操作」列：表头与单元格内的按钮组整体居中（其余表格仍保持右对齐） */
.table .cell-ops{text-align:center}
.table .cell-ops .row-actions{justify-content:center}
.link-btn{background:none;border:none;color:var(--primary);font-size:13px;cursor:pointer;font-family:var(--font);padding:4px;border-radius:6px;white-space:nowrap}
.link-btn:hover{background:var(--primary-soft)}
.link-btn.danger{color:var(--danger)}
.link-btn.danger:hover{background:var(--danger-soft)}

/* ---------- 列表分页（由 app.js 通用分页模块生成） ---------- */
.table-pager{display:flex;align-items:center;gap:14px;flex-wrap:wrap;padding:10px 2px 2px;font-size:13px;color:var(--text-sub)}
.table-pager .tp-size{display:inline-flex;align-items:center;gap:6px;white-space:nowrap}
.table-pager .tp-select{font-family:var(--font);font-size:13px;padding:3px 8px;border:1px solid var(--border);border-radius:6px;background:var(--surface);color:var(--text);cursor:pointer}
.table-pager .tp-nav{display:inline-flex;align-items:center;gap:4px;margin-left:auto;flex-wrap:nowrap}
.table-pager .tp-btn{min-width:30px;height:28px;padding:0 9px;font-family:var(--font);font-size:13px;color:var(--text);background:var(--surface);border:1px solid var(--border);border-radius:6px;cursor:pointer;white-space:nowrap}
.table-pager .tp-btn:hover:not(:disabled){border-color:var(--primary);color:var(--primary)}
.table-pager .tp-btn.active{background:var(--primary);border-color:var(--primary);color:#fff;font-weight:600}
.table-pager .tp-btn:disabled{opacity:.45;cursor:not-allowed}
.table-pager .tp-gap{color:var(--text-sub);padding:0 2px}

/* 打印时放开被分页隐藏的行，确保打印件包含全部数据 */
@media print{
  .table-pager{display:none!important}
  .table tbody tr[data-paged="0"]{display:table-row!important}
}
.avatar-sm{width:30px;height:30px;border-radius:50%;background:var(--primary-soft);color:var(--primary);display:inline-flex;align-items:center;justify-content:center;font-size:12px;font-weight:700;margin-right:8px}

/* ---------- Tags ---------- */
.tag{display:inline-flex;align-items:center;gap:5px;padding:2px 9px;border-radius:20px;font-size:12px;font-weight:600;white-space:nowrap}
.tag::before{content:"";width:6px;height:6px;border-radius:50%;background:currentColor}
.tag-success{background:var(--success-soft);color:var(--success)}
.tag-warn{background:var(--warn-soft);color:var(--warn)}
.tag-danger{background:var(--danger-soft);color:var(--danger)}
.tag-info{background:var(--info-soft);color:var(--primary)}
.tag-muted{background:var(--bg);color:var(--text-sub)}
/* 已退款：红色字体标识（白底红边，与「逾期」红底区分） */
.tag-refund{background:#fff;color:#d4380d;border:1px solid #ffa39e}
/* 缴费流水：退款冲抵的负数金额（红色，便于与正常收款区分） */
.pay-neg{color:#d4380d;font-weight:700;font-variant-numeric:tabular-nums}

/* ---------- 演示数据标识 ---------- */
.demo-banner{display:flex;align-items:center;gap:8px;margin-bottom:18px;padding:10px 14px;background:var(--warn-soft);border:1px solid var(--warn);border-radius:var(--r-sm);color:var(--warn);font-size:13px;font-weight:600}
.demo-banner .ic{font-size:16px;opacity:.9}

/* ---------- Modal ---------- */
.modal-overlay{position:fixed;inset:0;background:rgba(17,26,46,.5);backdrop-filter:blur(2px);z-index:100;display:flex;align-items:center;justify-content:center;opacity:0;pointer-events:none;transition:opacity .18s}
.modal-overlay.open{opacity:1;pointer-events:auto}
.modal{background:var(--surface);border-radius:var(--r-lg);box-shadow:var(--shadow-lg);width:560px;max-width:94vw;max-height:88vh;overflow-y:auto;transform:translateY(10px) scale(.98);transition:transform .2s}
.modal-overlay.open .modal{transform:none}
.modal-lg{width:920px}
/* 计费规则弹窗：加宽并放宽高度，避免竖向/横向滚动条 */
#ruleModal .modal{width:840px;max-width:96vw;max-height:94vh;overflow-x:hidden}
/* 关联费用类别：表头 + 行式配置，列宽由同一套 grid-template-columns 约束，
   表头与每行数据严格按列对齐（表头常显，无数据行时也保留列名） */
#ruleModal .fee-scroll{overflow-x:auto}
#ruleModal .fee-head,
#ruleModal .fee-grid{display:grid;grid-template-columns:32px minmax(140px,1.5fr) 96px 104px 122px minmax(88px,1fr) 96px;gap:8px;align-items:center}
#ruleModal .fee-head{margin:0 0 6px;padding:0 13px;color:var(--text-sub);font-size:12px;font-weight:600;line-height:1.6;white-space:nowrap}
#ruleModal .fee-head>span{overflow:hidden;text-overflow:ellipsis}
#ruleModal .fee-head .fee-op{text-align:right}
#ruleModal .fee-row{border:1px solid var(--border);border-radius:8px;padding:10px 12px;margin-bottom:8px;background:#fafbfc}
#ruleModal .fee-grid .select,
#ruleModal .fee-grid .input{width:100%;max-width:none}
#ruleModal .fee-no{color:#888;font-size:13px}
#ruleModal .fee-unit{margin:0;font-size:12px;line-height:1.4}
#ruleModal .fee-ops{display:flex;gap:2px;justify-content:flex-end}
#ruleModal .fee-ops .icon-btn{width:30px;height:30px}
#ruleModal .fee-note{margin-top:6px;padding-left:40px;color:var(--text-sub);font-size:12px;line-height:1.5}
#ruleModal .fee-empty{padding:6px 0;color:#888;font-size:13px}
@media (max-width:640px){
  #ruleModal .fee-head,#ruleModal .fee-grid{min-width:600px}
}
.modal-head{display:flex;align-items:center;justify-content:space-between;padding:18px 22px;border-bottom:1px solid var(--border)}
.modal-head h2{font-size:16px;font-weight:700}
.modal-body{padding:20px 22px}
.modal-foot{padding:14px 22px;border-top:1px solid var(--border);display:flex;justify-content:flex-end;gap:10px}

/* Modal · 右侧抽屉形态（如 residents.html 的「入住登记 / 新增人员」）
   复用同一套 .modal-overlay / .modal 结构与开关逻辑，仅在遮罩上追加 .drawer：
   面板贴右侧、占满可视高度、自右向左滑入；头尾操作栏固定，仅表单区内部滚动。 */
.modal-overlay.drawer{justify-content:flex-end;align-items:stretch}
.modal-overlay.drawer .modal{width:min(720px,70vw);max-width:92vw;height:100%;max-height:100vh;border-radius:var(--r-lg) 0 0 var(--r-lg);display:flex;flex-direction:column;overflow:hidden;transform:translateX(36px)}
.modal-overlay.drawer.open .modal{transform:none}
.modal-overlay.drawer .modal-head,.modal-overlay.drawer .modal-foot{flex:none}
.modal-overlay.drawer .modal-body{flex:1 1 auto;overflow-y:auto}
/* 抽屉贴右下角，需为固定的版本号徽标（app.js 注入，bottom:8px）留出让位，避免压住操作按钮 */
.modal-overlay.drawer .modal-foot{padding-bottom:34px}
/* 宽度策略（常规右侧抽屉 + 页面背景大面积可见）：
   宽窗口（≥1029px）固定 720px；窗口收窄时按 70vw 收缩，左侧背景始终保持约 30% 可见
   （遮罩可点击关闭，不会出现"只剩一条缝"的铺满观感）；仅手机宽度（≤640px）才铺满。 */
@media (max-width:640px){
  .modal-overlay.drawer .modal{width:100%;max-width:100%;border-radius:0}
}

/* ===== 账单生成预览弹窗（billing.html #billPreviewModal）专属排版 =====
   目标：列标题居中；日期控件精简；字段强制单行；小区名附加；超出横向滚动 */
#billPreviewModal .modal{width:1240px;max-width:96vw}
#billPreviewModal .modal-body{padding:20px 18px}
/* 列标题居中 */
#billPreviewModal .table thead th{text-align:center;white-space:nowrap}
/* 所有字段内容禁止换行，必要时由 .table-wrap 提供横向滚动 */
#billPreviewModal .table tbody td{white-space:nowrap}
/* 房屋代码 + 附加小区名称 */
#billPreviewModal .table tbody td.cell-strong .bp-code{font-weight:600}
#billPreviewModal .table tbody td.cell-strong .bp-comm{margin-right:6px;color:var(--text-sub);font-weight:400;font-size:12.5px}
/* 税率/开票字段强制单行不换行 */
#billPreviewModal .table tbody td:nth-child(4){white-space:nowrap}
/* 金额：完整显示不被截断 */
#billPreviewModal .table tbody td:nth-child(6){min-width:92px}
#billPreviewModal .bp-amt{width:92px;text-align:right}
/* 日期选择器控件：精简尺寸、去除多余空白（宽度贴合 YYYY-MM-DD 内容） */
#billPreviewModal .bp-s,#billPreviewModal .bp-e,#billPreviewModal .bp-due{padding:5px 6px;width:100px;min-width:0;font-size:13px}
/* 计费起止/缴费截止日期列宽度与控件匹配，避免挤压 */
#billPreviewModal .table tbody td:nth-child(7),
#billPreviewModal .table tbody td:nth-child(8),
#billPreviewModal .table tbody td:nth-child(9){min-width:100px;padding-left:4px;padding-right:4px}
/* 操作按钮保持单行不换行 */
#billPreviewModal .table tbody td.row-actions{white-space:nowrap}
.form-grid{display:grid;grid-template-columns:1fr 1fr;gap:0 16px}
/* 手工建单「高级设置」折叠区：低频字段默认收起，保持主表单精简；展开后字段与原布局一致 */
.mb-adv{margin-top:4px;border:1px solid var(--border);border-radius:10px;background:var(--bg);padding:0 14px}
.mb-adv>summary{cursor:pointer;padding:10px 0;font-size:13px;font-weight:600;color:var(--text-sub);outline:none;list-style-position:inside}
.mb-adv>summary:hover{color:var(--primary)}
.mb-adv[open]>summary{color:var(--primary)}
.mb-adv .form-grid{padding:2px 0 14px}
.mb-adv .field{margin-bottom:12px}

/* ---------- Progress / mini bars ---------- */
.progress{height:8px;background:var(--bg);border-radius:20px;overflow:hidden}
.progress>span{display:block;height:100%;border-radius:20px}
.progress.pl>span{background:linear-gradient(90deg,#2A5BFF,#6E94FF)}
.progress.pc>span{background:linear-gradient(90deg,#16A34A,#4ade80)}
.bar-legend{display:flex;gap:18px;margin-top:12px;font-size:12.5px;color:var(--text-sub)}
.bar-legend span{display:inline-flex;align-items:center;gap:6px}
.bar-legend i{width:10px;height:10px;border-radius:3px;display:inline-block}

/* ---------- Empty ---------- */
.empty{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:44px 20px;color:var(--text-faint);text-align:center}
.empty .ic{font-size:40px;opacity:.5;margin-bottom:10px}
.empty b{color:var(--text-sub);font-size:14px;margin-bottom:4px}
.empty p{font-size:12.5px}

/* 预览中金额为0的房产标红提示（面积/单价/固定额缺失导致，需补全后再保存） */
.bp-zero{background:rgba(255,128,132,.10)}
.bp-zero .bp-amt{color:var(--danger);font-weight:600}

/* ---------- Toast ---------- */
/* 容器固定底部居中：位于弹窗下方，视线自然落点；z-index 高于弹窗避免被遮挡；多端用 min(92vw,560px) 防溢出 */
#toastContainer{position:fixed;left:50%;bottom:calc(22px + env(safe-area-inset-bottom,0px));transform:translateX(-50%);z-index:9999;display:flex;flex-direction:column;align-items:center;gap:10px;width:min(92vw,560px);pointer-events:none}
.toast{display:flex;align-items:center;gap:10px;background:#111A2E;color:#F4F7FD;padding:13px 18px;border-radius:12px;box-shadow:var(--shadow-lg);border:1px solid rgba(255,255,255,.1);font-size:14.5px;line-height:1.5;max-width:100%;word-break:break-word;opacity:0;transform:translateY(16px);transition:opacity .3s ease,transform .3s ease}
.toast.show{opacity:1;transform:none}
.toast .ic{font-size:18px;flex-shrink:0}
.toast-msg{display:inline-block;text-align:left}
.toast-success .ic{color:#4ade80}
.toast-danger .ic{color:#ff8084}
.toast-warning .ic{color:#fbbf24}
.toast-info .ic{color:#60a5fa}

/* ---------- Misc ---------- */
.progress-ring{position:relative}
.chart-note{font-size:12px;color:var(--text-faint)}
.mini-list{list-style:none}
.mini-list li{display:flex;align-items:center;gap:10px;padding:10px 0;border-bottom:1px solid var(--border);font-size:13px}
.mini-list li:last-child{border-bottom:none}
.mini-list .ic{color:var(--primary);font-size:16px}

/* ---------- Billing / 收费专用 ---------- */
.chip{display:inline-flex;align-items:center;gap:5px;padding:3px 10px;border-radius:20px;font-size:12px;font-weight:600;background:var(--primary-soft);color:var(--primary)}
.amount-lg{font-size:30px;font-weight:700;line-height:1.1;font-variant-numeric:tabular-nums}
.stat-sum{display:flex;gap:24px;margin-top:12px;font-size:12.5px;color:var(--text-sub);flex-wrap:wrap}
.stat-sum b{color:var(--text);font-variant-numeric:tabular-nums;font-weight:650}
.seg-group{display:inline-flex;background:var(--bg);border:1px solid var(--border);border-radius:var(--r-sm);padding:3px}
.seg-group button{display:inline-flex;align-items:center;gap:6px;border:none;background:transparent;padding:6px 12px;font-size:12.5px;font-weight:600;color:var(--text-sub);border-radius:6px;cursor:pointer;font-family:var(--font)}
.seg-group button.active{background:var(--surface);color:var(--primary);box-shadow:var(--shadow-sm)}
.bill-toolbar{display:flex;align-items:center;gap:10px;flex-wrap:nowrap;overflow-x:auto}
.bill-toolbar .select,.bill-toolbar .input{width:auto;flex:0 1 auto;min-width:0}
.bill-toolbar .top-search{width:auto;flex:1 1 180px;min-width:140px}
.bill-toolbar .spacer{flex:0 0 4px}
.bill-toolbar .seg-group{flex-shrink:0}
.bill-toolbar .seg-group button{white-space:nowrap}
/* 窄屏：压缩间距与字号，保证工具栏仍为一行；极窄时由 overflow-x 横向滚动兜底 */
@media (max-width:900px){
  .bill-toolbar{gap:8px}
  .bill-toolbar .select{padding:6px 8px;font-size:12.5px}
  .bill-toolbar .top-search{flex-basis:120px;min-width:110px}
  .bill-toolbar .seg-group button{padding:6px 8px;font-size:12px}
}
@media (max-width:640px){
  .bill-toolbar .select{min-width:96px}
}
.amount-row{display:none;align-items:center;justify-content:space-between;padding:10px 16px;border:1px solid var(--border);border-radius:var(--r-sm);background:var(--bg);margin-bottom:16px}
.amount-row.show{display:flex}
.amount-row .lbl{font-size:12.5px;color:var(--text-sub)}
.amount-row .v{font-size:17px;font-weight:700;font-variant-numeric:tabular-nums}
.detail-row{display:flex;justify-content:space-between;padding:11px 0;border-bottom:1px solid var(--border);font-size:13.5px}
.detail-row:last-child{border-bottom:none}
.detail-row .k{color:var(--text-sub)}
.detail-row .v{font-weight:600;font-variant-numeric:tabular-nums}
.sel-card{display:flex;align-items:center;gap:10px;border:1px solid var(--border);border-radius:var(--r-md);padding:12px 14px;cursor:pointer;transition:.15s;background:var(--surface)}
.sel-card:hover{border-color:var(--primary)}
.sel-card.selected{border-color:var(--primary);background:var(--primary-soft);box-shadow:0 0 0 3px rgba(42,91,255,.15)}
.sel-card .radio{width:16px;height:16px;border-radius:50%;border:2px solid var(--border-check,#CBD5E1);flex-shrink:0;position:relative}
.sel-card.selected .radio{border-color:var(--primary)}
.sel-card.selected .radio::after{content:"";position:absolute;inset:2px;border-radius:50%;background:var(--primary)}
.pay-status{display:flex;align-items:center;gap:7px;font-size:12.5px;color:var(--text-sub);margin-top:8px}
.pay-status .ok{color:var(--success)}
.pay-status .pending{color:var(--warn)}

/* ---------- 收款弹窗 · 费用明细行（逐行独立，字段对齐） ---------- */
.pay-items{display:flex;flex-direction:column;gap:10px}
.pay-head{display:none}
.pay-item{position:relative;border:1px solid var(--border);border-radius:var(--r-md);padding:12px 14px 12px 44px;cursor:pointer;transition:.15s;background:var(--surface)}
.pay-item:hover{border-color:var(--primary)}
.pay-item.selected{border-color:var(--primary);background:var(--primary-soft);box-shadow:0 0 0 3px rgba(42,91,255,.15)}
.pay-item.disabled{opacity:.55;cursor:not-allowed}
.pay-item .radio{position:absolute;left:15px;top:14px;width:16px;height:16px;border-radius:50%;border:2px solid var(--border-check,#CBD5E1);flex-shrink:0}
.pay-item.selected .radio{border-color:var(--primary)}
.pay-item.selected .radio::after{content:"";position:absolute;inset:2px;border-radius:50%;background:var(--primary)}
.pay-item .pi-amt{position:absolute;right:14px;top:12px;display:flex;flex-direction:column;align-items:flex-end;gap:4px;text-align:right}
.pay-item .pi-amt b{font-size:15px;font-variant-numeric:tabular-nums}
.pay-item .pi-line{display:flex;flex-wrap:wrap;gap:2px 8px;font-size:13px;line-height:1.55}
.pay-item .pi-line + .pi-line{margin-top:5px}
.pay-item .pi-k{color:var(--text-sub);margin-right:4px}
.pay-item .pi-strong{font-weight:600}
.pay-item .pi-owner{font-weight:600}
/* 收款码弹窗 */
.qr-img{display:inline-flex;align-items:center;justify-content:center;width:208px;height:208px;padding:14px;background:#fff;border:1px solid var(--border);border-radius:12px;color:var(--text-sub);font-size:12px;text-align:center;word-break:break-all}

/* ===== 收款码弹窗（#payQrModal）：纵向 flex 自适应，二维码完整呈现且不出现纵向滚动 =====
   布局意图：头部/摘要/脚注固定高度（flex:none），中间二维码区吃掉剩余高度（flex:1），
   二维码由 JS 按该区域尺寸以「整数设备像素/模块」重绘（见 drawQrCanvas），因此
   任何屏幕尺寸下都整幅可见、清晰可扫，且不会挤出自上而下的滚动条。 */
#payQrModal .modal{width:min(620px,94vw);height:min(94vh,800px);max-height:94vh;display:flex;flex-direction:column;overflow:hidden}
#payQrModal .modal-head{padding:10px 16px;flex:none}
#payQrModal .modal-head h2{font-size:15px}
#payQrModal .modal-body{padding:10px 16px;flex:1 1 auto;min-height:0;display:flex;flex-direction:column;overflow:hidden}
#payQrModal .modal-foot{padding:8px 16px;flex:none;gap:8px}
#payQrModal #qrSummary{flex:none;padding:0;line-height:1.5}
#payQrModal #qrStatus{flex:none;margin-top:5px;line-height:1.5}
/* 二维码区：由 flex 决定高度（clientHeight 即真实可用高度，不受画布自身尺寸影响）；
   二维码卡片绝对定位居中，避免"画布撑大容器 → 测量失真 → 越画越小"的循环 */
#payQrModal .qr-box{position:relative;flex:1 1 auto;min-height:0;margin:6px 0;overflow:hidden;display:flex;align-items:center;justify-content:center;text-align:center}
#payQrModal .qr-card{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);background:#fff;border-radius:10px;padding:4px;line-height:0}
#payQrModal .qr-card canvas,#payQrModal .qr-card img{display:block}
#payQrModal .qr-foot{flex:none;text-align:center}
#payQrModal .qr-side{flex:none;display:flex;flex-direction:column;min-width:0}
#payQrModal .qr-side > *{flex:none}
/* 移动端浏览器地址栏收缩时 100vh 会大于可视区，优先用 dvh 避免弹窗超出屏幕 */
@supports (height:100dvh){
  #payQrModal .modal{height:min(94dvh,800px)}
}
/* 屏幕很矮（如 768p 笔记本）时进一步压缩留白，把空间让给二维码 */
@media (max-height:760px){
  #payQrModal .modal-body{padding:8px 14px}
  #payQrModal .qr-box{margin:4px 0}
  #payQrModal #qrSummary{font-size:12px}
}
/* 弹窗打开时锁定背景滚动：类由 app.js syncModalScrollLock 切换；
   :has() 作为支持浏览器的自愈兜底（避免任何遗漏的关闭路径留下滚动条） */
body.modal-locked,body:has(.modal-overlay.open){overflow:hidden}

/* ===== 全屏放大二维码（#qrZoom）：整屏纯白底 + 尽可能大的整数像素二维码 =====
   用于光线不足 / 屏幕小 / 距离远 / 反光等现场场景：白底同时拉高屏幕自身照度，
   二维码仍按「整数设备像素/模块」重绘，放大后不会发虚。 */
.qr-zoom{position:fixed;inset:0;z-index:2000;background:#fff;display:none;flex-direction:column;align-items:center;justify-content:center;gap:8px;padding:14px 16px}
.qr-zoom.open{display:flex}
.qr-zoom .qz-head{flex:none;width:100%;display:flex;align-items:center;justify-content:space-between;gap:12px}
.qr-zoom .qz-head span{font-weight:700;font-size:14px;color:#111}
.qr-zoom .qz-body{flex:1 1 auto;min-height:0;width:100%;display:flex;align-items:center;justify-content:center}
.qr-zoom .qz-body canvas{display:block;max-width:100%;max-height:100%}
.qr-zoom .qz-tip{flex:none;font-size:13px;color:#333;text-align:center;line-height:1.6}

/* 打印设置弹窗：纸张选择段位按钮 */
#printModal .seg-group button{display:inline-flex;align-items:center;gap:6px}
#printModal .seg-group button .ic{width:14px;height:14px}

/* 宽而矮的屏幕（典型：1366×768 / 1280×720 笔记本）：
   改为左右两栏，把可用高度全部让给二维码 —— 避免"高度不够 → 二维码被压成小方块" */
@media (min-width:880px) and (max-height:700px){
  #payQrModal .modal{width:min(780px,94vw);height:min(92vh,560px)}
  #payQrModal .modal-body{flex-direction:row;align-items:stretch;gap:14px}
  #payQrModal .qr-box{flex:1 1 auto;min-width:0;margin:0}
  #payQrModal .qr-side{flex:0 0 44%;justify-content:center;gap:6px;text-align:left}
}

/* ---------- Responsive (扩充) ---------- */
@media (max-width:1200px){.stats{grid-template-columns:repeat(2,1fr)}.grid-3,.grid-4{grid-template-columns:repeat(2,1fr)}}
@media (max-width:900px){.grid-2,.grid-2-1{grid-template-columns:1fr}.top-search{width:180px}.stats{grid-template-columns:repeat(2,1fr)}}
@media (max-width:640px){.stats{grid-template-columns:1fr}.shell-nav{width:200px}.shell-top{left:200px}.shell-main{margin-left:200px;padding:84px 16px 32px}.form-grid{grid-template-columns:1fr}.page-head{flex-direction:column;align-items:flex-start}}

/* ---------- 收费与财务页（billing）：压缩纵向留白，为账单列表腾出更多可视区域 ----------
   仅作用于 data-page="billing"，不影响其它页面 */
body[data-page="billing"] .shell-main{padding:72px 24px 24px}
body[data-page="billing"] .page-head{margin-bottom:12px}
body[data-page="billing"] .page-head .sub{margin-top:2px}
body[data-page="billing"] .stats{gap:12px;margin-bottom:12px}
body[data-page="billing"] .stat{padding:12px 14px;gap:10px}
body[data-page="billing"] .stat-ic{width:36px;height:36px;border-radius:10px}
body[data-page="billing"] .stat-ic .ic{font-size:18px}
body[data-page="billing"] .stat-meta .value{font-size:21px}
body[data-page="billing"] .stat-meta .delta{margin-top:3px}
body[data-page="billing"] .section-title{margin:12px 0 10px}
body[data-page="billing"] .tabs .tab{padding:5px 12px}
body[data-page="billing"] .toolbar{margin-bottom:10px}
body[data-page="billing"] .card-head{padding:10px 14px}
body[data-page="billing"] .card-body{padding:14px}
body[data-page="billing"] .table thead th{padding:7px 12px}
body[data-page="billing"] .table tbody td{padding:8px 12px}

/* ============ 发票管理：红蓝票合并展示 / 发票查看弹窗 ============ */
/* 发票详情：已冲红醒目横幅（红底红边 + 左侧色条 + 警示图标） */
.inv-red-banner{display:flex;gap:10px;align-items:flex-start;margin:0 0 14px;padding:12px 14px;
  border:1px solid #FFB8B8;border-left:4px solid #d4380d;border-radius:8px;background:#FFF4F2}
.inv-red-banner .ic{flex:0 0 auto;font-size:20px;color:#d4380d;margin-top:1px}
.inv-red-banner .inv-red-body{min-width:0}
.inv-red-banner b{display:block;font-size:14.5px;color:#A8071A;margin-bottom:4px;letter-spacing:.2px}
.inv-red-banner .inv-red-lines{font-size:12.5px;line-height:1.75;color:#7A2E1F;word-break:break-word;overflow-wrap:anywhere}
.inv-red-banner .inv-red-lines .k{color:#A8071A;font-weight:600}
/* 「发票号码」列：蓝字票单行；已冲红的票两行 —— 第一行蓝字号码，第二行红字号码（红色字体） */
.inv-no-cell{display:flex;flex-direction:column;gap:2px;line-height:1.45}
.inv-no-cell .inv-no-blue{font-weight:700;font-variant-numeric:tabular-nums;color:var(--text)}
.inv-no-cell .inv-no-red{color:#d4380d;font-weight:700;font-variant-numeric:tabular-nums}
/* 红票号码尚未取得时的占位：同色但弱化，保持两行高度一致 */
.inv-no-cell .inv-no-red.is-pending{font-weight:600;opacity:.75}

/* 换开提示（账单列表「换开」→ 开票弹窗顶部）：说明「先红冲原票、再按新抬头重开」的口径 */
.inv-tip{margin-bottom:12px;padding:10px 12px;border-radius:8px;background:#FFF7E6;border:1px solid #FFE0B2;color:#B45309;font-size:12.5px;line-height:1.7;text-align:left}
/* 开票受理中：已查询次数 */
.inv-poll{font-size:12px;color:#9aa3b2;margin-left:6px}
/* 开票状态列：固定两行 —— 第一行状态标签、第二行票通提示信息。
   两行均不折行，列宽随两行内容自动撑开（表格 auto 布局）；宽度不足时由 .table-wrap 横向滚动，
   保证不会溢出、截断或出现第三行。 */
.inv-status-cell{display:flex;flex-direction:column;align-items:flex-start;gap:4px;min-width:0}
.inv-status-cell>.tag{flex:none;white-space:nowrap;line-height:18px}
.inv-status-msg{font-size:12px;line-height:1.4;color:var(--text-sub);white-space:nowrap;max-width:none}
.inv-status-msg.is-empty{color:#b9c0cc}
/* 发票详情弹窗：加宽展示，头/尾固定、仅内容区滚动；
   发票图片按容器宽度等比渲染，不出现横向滚动或裁切 */
.modal-inv{width:1120px;max-width:96vw;max-height:94vh;overflow:hidden;display:flex;flex-direction:column}
.modal-inv .modal-head,.modal-inv .modal-foot{flex:none}
.modal-inv .modal-body{flex:1 1 auto;overflow-y:auto;overflow-x:hidden}
@media (max-width:1200px){.modal-inv{width:96vw}}
/* 台账信息两列排布；长值（如票通回执）强制换行，避免被 overflow-x:hidden 裁掉 */
.inv-face-grid{display:grid;grid-template-columns:1fr 1fr;gap:0 18px}
.inv-face-grid .detail-row{border-bottom:1px dashed var(--border);padding:6px 0;align-items:flex-start;gap:12px}
.inv-face-grid .detail-row .k{flex:0 0 auto}
.inv-face-grid .detail-row .v{min-width:0;text-align:right;word-break:break-word;overflow-wrap:anywhere}
@media (max-width:720px){.inv-face-grid{grid-template-columns:1fr}}
/* 发票图片：票通版式文件（PDF）在前端渲染成图片后展示 */
.inv-face-img{display:block;width:100%;max-width:100%;height:auto;margin:0 auto 12px;
  border:1px solid var(--border);border-radius:8px;background:#fff;box-shadow:0 1px 3px rgba(15,23,42,.06)}

/* ---------- 房产检索（手工建单 / 生成账单：编码 / 位置 / 业主 / 手机号） ---------- */
.prop-search{position:relative;flex:1 1 260px;min-width:200px}
.prop-search .input{width:100%}
.prop-search-panel{position:absolute;z-index:40;left:0;right:0;top:calc(100% + 4px);display:none;
  max-height:260px;overflow:auto;background:var(--surface);border:1px solid var(--border);border-radius:8px;
  box-shadow:0 10px 24px rgba(23,35,61,.14)}
.prop-search-panel.open{display:block}
.prop-search-item{padding:8px 10px;cursor:pointer;border-bottom:1px dashed var(--border)}
.prop-search-item:last-child{border-bottom:0}
.prop-search-item:hover,.prop-search-item.active{background:#F3F7FF}
.prop-search-item .ps-main{display:block;font-size:12.5px;font-weight:600;color:var(--text);word-break:break-all}
.prop-search-item .ps-sub{display:block;margin-top:2px;font-size:12px;color:var(--text-sub);font-variant-numeric:tabular-nums}
.prop-search-empty{padding:10px 12px;font-size:12.5px;color:var(--text-sub)}
.prop-search-more{padding:6px 12px;font-size:12px;color:var(--text-sub);border-top:1px dashed var(--border)}
/* ---------- 已选房屋高亮（生成账单 / 手工建单共用） ----------
   仅在「已选房屋：房屋编码|位置|业主」提示行整行显示绿色；房屋下拉与检索列表保持原样。
   JS 在选中/切换/取消选择时同步增删该类，避免残留旧的绿色状态。 */
.field-note.prop-picked-note{color:var(--success);font-weight:600}