/* ===== 开源收缴数据模块样式（独立 op 前缀） ===== */

/* ---- 统计卡 ---- */
.op-stats-bar{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:14px;margin-bottom:16px}
.op-stat{display:flex;align-items:center;gap:12px;background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);padding:14px 16px;box-shadow:var(--shadow-xs)}
.op-stat-icon{width:42px;height:42px;flex-shrink:0;border-radius:12px;display:flex;align-items:center;justify-content:center}
.op-stat-icon svg{width:20px;height:20px}
.op-stat-info{min-width:0}
.op-stat-value{display:block;font-size:19px;font-weight:700;color:var(--text);line-height:1.2;white-space:nowrap}
.op-stat-label{display:block;font-size:12px;color:var(--text-muted);margin-top:2px}
.op-stat-sub{font-size:11px;color:var(--text-muted)}

/* ---- 通用卡片 ---- */
.op-card{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);padding:16px;box-shadow:var(--shadow-xs);margin-bottom:16px}
.op-card-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:12px;flex-wrap:wrap;gap:8px}
.op-card-header h3{font-size:14px;font-weight:600;color:var(--text);margin:0}
.op-card-header .op-actions{display:flex;align-items:center;gap:8px}

/* ---- 未缴费提醒（淡红呼吸 + 置顶） ----
 * ⚠️ 这套样式原来把背景写成"半透明白"（rgba(255,255,255,.6)）、文字用深红（#991b1b / #7f1d1d），
 *    是照着**浅色底**设计的。放到深色主题上就出问题：
 *      ① 60% 白压在深色页面上，混成一层灰蒙蒙的灰底（不深不浅，很脏）；
 *      ② 里面"片区/经办/欠费"这些小字用的是 var(--text-muted) ——
 *         它在深色主题下是给深底配的中灰 #94a3b8，压在浅灰底上几乎看不清；
 *      ③ 深红字（#7f1d1d）在深底上同样看不见。
 *    三者叠加就是用户看到的"很模糊"。
 *    现在**背景一律跟主题走**：浅色=白卡片、深色=深色卡片；红色只用来强调，不再当背景。 */
.op-alert-wrap{border:1.5px solid rgba(239,68,68,.45);background:rgba(239,68,68,.06);border-radius:var(--radius);padding:14px 16px;margin-bottom:16px}
.op-alert-title{display:flex;align-items:center;gap:8px;font-size:14px;font-weight:700;color:#b91c1c;margin-bottom:10px}
html.theme-dark .op-alert-title{color:#fca5a5}
.op-alert-title svg{width:18px;height:18px}
.op-alert-count{background:#dc2626;color:#fff;border-radius:20px;padding:1px 10px;font-size:12px;font-weight:700}
.op-alert-groups{display:flex;flex-direction:column;gap:10px}
.op-alert-group{background:var(--bg-card);border:1px solid var(--border);border-radius:10px;padding:8px 12px}
.op-alert-group-head{font-size:12px;font-weight:600;color:#b91c1c;margin-bottom:6px;display:flex;align-items:center;gap:6px}
html.theme-dark .op-alert-group-head{color:#fca5a5}
.op-alert-group-head .op-gcount{font-weight:700;color:#dc2626}
html.theme-dark .op-alert-group-head .op-gcount{color:#f87171}
/* 分组标题前的"人物"图标（原来是彩色 📌 emoji，颜色不可控）：蓝色，随主题调亮度。
 * 对比度实测：#2563eb 压白卡片 5.17、#60a5fa 压深卡片 #1e293b 5.80，都远高于图形元素 3:1 的门槛。 */
.op-alert-group-head .op-a-head-ico{color:#2563eb;flex-shrink:0}
html.theme-dark .op-alert-group-head .op-a-head-ico{color:#60a5fa}
.op-alert-items{display:flex;flex-wrap:wrap;gap:8px}
@keyframes opBreath{0%,100%{background-color:rgba(239,68,68,.08);border-color:rgba(239,68,68,.35);box-shadow:0 0 0 0 rgba(239,68,68,.15)}50%{background-color:rgba(239,68,68,.22);border-color:rgba(239,68,68,.7);box-shadow:0 0 10px 2px rgba(239,68,68,.18)}}
.op-alert-item{display:inline-flex;align-items:flex-start;gap:8px;padding:7px 12px;border:1.5px solid rgba(239,68,68,.35);border-radius:9px;font-size:12.5px;color:var(--text);cursor:pointer;animation:opBreath 2.2s ease-in-out infinite;transition:transform .15s}
.op-alert-item:hover{transform:translateY(-1px)}
.op-alert-item .op-a-name{font-weight:600}
.op-alert-item .op-a-amt{color:#dc2626;font-weight:700}
html.theme-dark .op-alert-item .op-a-amt{color:#f87171}
/* 「片区/经办/对接/电话」这些 11px 小字：条目的底色本身是一层淡红（呼吸动画），
 * 直接沿用 --text-muted 的话，浅色主题下 #64748b 压在淡红上对比度只有 3.8 —— 低于
 * WCAG AA 正文 4.5 的门槛，正是用户说的"看不清/模糊"。这里单独加深一档：
 * 浅色用 slate-600 #475569，深色用 slate-300 #cbd5e1。 */
.op-alert-item .op-a-meta{color:#475569}
html.theme-dark .op-alert-item .op-a-meta{color:#cbd5e1}
.op-alert-empty{display:flex;align-items:center;gap:8px;color:#16a34a;font-size:13px;padding:10px 4px}
html.theme-dark .op-alert-empty{color:#4ade80}

/* ---- 横向缴费表 ---- */
.op-table-wrap{overflow:auto;max-height:520px;border:1px solid var(--border);border-radius:10px}
.op-input-table{border-collapse:separate;border-spacing:0;font-size:12.5px;min-width:100%}
.op-input-table th{position:sticky;top:0;background:#f1f5f9;z-index:2;padding:8px 6px;border-bottom:1px solid var(--border);font-weight:600;color:var(--text-muted);text-align:center;white-space:nowrap}
.op-input-table th.op-col-cust{left:0;z-index:3;text-align:left;padding-left:12px;min-width:150px}
.op-input-table td{border-bottom:1px solid var(--border-light);text-align:center;padding:3px 2px}
.op-input-table tr:hover td{background:#f8fafc}
.op-input-table td.op-col-cust{position:sticky;left:0;background:#fff;z-index:1;text-align:left;padding:4px 12px;border-right:1px solid var(--border)}
.op-input-table td.op-col-cust .op-c-name{font-weight:600;color:var(--text);font-size:12.5px}
.op-input-table td.op-col-cust .op-c-area{font-size:11px;color:var(--text-muted)}
.op-month-cell{position:relative}
.op-month-cell input{width:100%;min-width:62px;padding:6px 6px;border:1.5px solid transparent;border-radius:6px;text-align:center;font-size:12.5px;background:transparent;color:var(--text);outline:none;font-family:inherit;box-sizing:border-box}
.op-month-cell input:focus{border-color:var(--primary);background:#fff}
.op-month-cell input:disabled{color:#cbd5e1;cursor:not-allowed}
.op-month-cell.op-unpaid input{border-color:rgba(239,68,68,.5);background:rgba(239,68,68,.08);color:#b91c1c;font-weight:600}
.op-month-cell.op-unpaid input::placeholder{color:#fca5a5}
.op-month-cell.op-paid input{border-color:rgba(16,185,129,.35);background:rgba(16,185,129,.06);color:#047857}
.op-month-cell.op-ended input{border-color:transparent;background:#f1f5f9;color:#cbd5e1}

/* ---- 台账列表 ---- */
.op-table{width:100%;border-collapse:collapse;font-size:13px}
.op-table th{text-align:center;font-weight:600;color:var(--text-muted);padding:8px 10px;border-bottom:1px solid var(--border);white-space:nowrap;background:var(--border-light)}
.op-table td{padding:8px 10px;border-bottom:1px solid var(--border-light);color:var(--text)}
.op-table .op-num{text-align:right;font-variant-numeric:tabular-nums}
.op-table .op-amount{color:#dc2626;font-weight:600}
.op-table tbody tr:hover{background:#f8fafc}

/* ---- 操作按钮（对齐水电配色） ---- */
.op-op-btn{border:1px solid var(--border);background:#fff;border-radius:6px;padding:3px 10px;font-size:12px;color:var(--text-muted);cursor:pointer;margin-right:6px;transition:all .15s}
.op-op-btn[data-act="edit"]{border-color:var(--primary);color:var(--primary)}
.op-op-btn[data-act="edit"]:hover{background:var(--primary-light)}
.op-op-btn[data-act="del"]{border-color:var(--danger);color:var(--danger)}
.op-op-btn[data-act="del"]:hover{background:var(--danger-light)}
.op-op-btn[data-act="jump"]{border-color:var(--warning);color:#b45309}
.op-op-btn[data-act="jump"]:hover{background:var(--warning-light)}

/* ---- 下拉菜单 ---- */
.op-io-drop{position:relative}
.op-io-menu{position:absolute;top:calc(100% + 4px);right:0;background:var(--bg-card);border:1px solid var(--border);border-radius:10px;box-shadow:var(--shadow-lg);z-index:200;min-width:168px;padding:4px}
.op-io-item{display:flex;align-items:center;gap:10px;width:100%;padding:9px 12px;border:none;background:transparent;border-radius:7px;font-size:13px;color:var(--text);cursor:pointer;text-align:left}
.op-io-item svg{width:16px;height:16px;flex-shrink:0}
.op-io-item:hover{background:var(--primary-light);color:var(--primary)}
.op-io-item.op-del-item:hover{background:var(--danger-light);color:var(--danger)}

/* ---- 客户管理 ---- */
.op-list{max-height:440px;overflow-y:auto;border:1px solid var(--border);border-radius:10px}
.op-list-item .del-btn{visibility:hidden}
.op-list-item:hover .del-btn{visibility:visible}
.op-list-item.op-ended .op-li-name{color:#94a3b8;text-decoration:line-through}
.op-empty{padding:24px;text-align:center;color:var(--text-muted);font-size:13px}
.op-hint{margin-top:10px;font-size:12px;color:var(--text-muted)}
.op-hint.success{color:var(--success)}
.op-hint.error{color:var(--danger)}

@media (max-width:1200px){.op-manage-grid{grid-template-columns:1fr}}

/* ---- 补充：图表网格 / 管理页 ---- */
.op-chart-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px}
.op-chart-grid .op-card canvas{height:280px !important;width:100% !important}
/* ===== 收缴看板深色模式 ===== */
.tab-panel.op-dash-dark{
  --bg-card:#1e293b;
  --border:#334155;
  --text:#f1f5f9;
  --text-muted:#94a3b8;
  --shadow-xs:none;
  background:#0f172a;
}
.op-dash-dark input[type="month"],.op-dash-dark input[type="number"],.op-dash-dark input[type="date"]{
  background:#1e293b;color:#f1f5f9;border-color:#334155
}
.op-dash-dark .op-io-menu{background:#1e293b;border-color:#334155}
.op-dash-dark .op-io-item{color:#cbd5e1}
.op-dash-dark .op-io-item:hover{background:#334155}
.op-dash-dark .panel-header h2{color:#f1f5f9}
.op-dash-dark .panel-desc{color:#94a3b8}
/* 深色看板激活时，外层容器同步深色（消除四周白框；切走自动恢复） */
.main-area:has(.tab-panel.active.op-dash-dark),
.tab-content:has(.tab-panel.active.op-dash-dark){background:#0f172a}
.tab-content:has(.tab-panel.active.op-dash-dark)::-webkit-scrollbar{width:10px}
.tab-content:has(.tab-panel.active.op-dash-dark)::-webkit-scrollbar-thumb{background:#334155;border-radius:5px}
.tab-content:has(.tab-panel.active.op-dash-dark)::-webkit-scrollbar-track{background:#0f172a}
@media(max-width:1200px){.op-chart-grid{grid-template-columns:1fr}}

/* ---- 横向表日期/周期/月费列 ---- */
.op-col-date{min-width:118px;padding:2px 4px !important}
.op-col-date input{width:100%;padding:4px 6px;border:1px solid transparent;border-radius:6px;font-size:11.5px;background:transparent;color:var(--text);outline:none;box-sizing:border-box;font-family:inherit}
.op-col-date input:focus{border-color:var(--primary);background:#fff}
.op-col-cycle{min-width:60px;padding:2px 4px !important}
.op-col-cycle select{width:100%;padding:4px 4px;border:1px solid transparent;border-radius:6px;font-size:11.5px;background:transparent;color:var(--text);outline:none;font-family:inherit}
.op-col-cycle select:focus{border-color:var(--primary);background:#fff}
.op-col-monthly{min-width:72px;padding:2px 4px !important}
.op-col-monthly input{width:100%;padding:4px 6px;border:1px solid transparent;border-radius:6px;font-size:11.5px;background:transparent;color:var(--text);outline:none;box-sizing:border-box;font-family:inherit;text-align:right}
.op-col-monthly input:focus{border-color:var(--primary);background:#fff}

/* ---- 横向表 片区/合计/文本列 ---- */
.op-col-area{min-width:80px;padding:2px 4px !important}
.op-col-area input{width:100%;padding:4px 6px;border:1px solid transparent;border-radius:6px;font-size:11.5px;background:transparent;color:var(--text);outline:none;box-sizing:border-box;font-family:inherit}
.op-col-area input:focus{border-color:var(--primary);background:#fff}
.op-col-total{min-width:64px;text-align:right;color:#059669;font-weight:600;font-variant-numeric:tabular-nums;font-size:12px}
.op-col-text{min-width:74px;padding:2px 4px !important}
.op-col-text input{width:100%;padding:4px 6px;border:1px solid transparent;border-radius:6px;font-size:11.5px;background:transparent;color:var(--text);outline:none;box-sizing:border-box;font-family:inherit}
.op-col-text input:focus{border-color:var(--primary);background:#fff}
.op-col-note{min-width:100px}

/* ---- 录入页新增客户行 ---- */
.op-add-cust .btn{white-space:nowrap}

/* ---- 新增客户表单：网格统一对齐 ---- */
.op-form-row{display:grid;grid-template-columns:repeat(auto-fill,minmax(170px,1fr));gap:12px 12px;align-items:end}
.op-form-row .input-group{margin:0;min-width:0}
.op-form-row .input-group label{display:block;font-size:12px;color:var(--text-muted);font-weight:500;margin-bottom:5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.op-form-row .input-group input,
.op-form-row .input-group select{width:100%;padding:7px 10px;border:1.5px solid var(--border);border-radius:8px;font-size:.82rem;outline:none;font-family:inherit;box-sizing:border-box;height:36px}
.op-form-row .input-group input:focus,
.op-form-row .input-group select:focus{border-color:var(--primary);box-shadow:0 0 0 3px rgba(59,130,246,.12)}
.op-form-row .op-fg-wide{grid-column:span 2}
.op-form-save{align-self:end}
.op-form-save .btn{height:36px;white-space:nowrap;width:100%;min-width:96px}
.op-form-row .input-group input{height:36px !important}
.op-form-row .input-group input[type="date"]{padding:6px 8px}
.op-form-row .input-group input,.op-form-row .input-group select{min-height:0 !important}
/* 开始服务前的月份：空白 */
.op-month-cell.op-nostart{background:#f8fafc}
.op-month-cell.op-nostart input{background:transparent;border-color:transparent;color:transparent;cursor:default}

.op-chart-grid .op-chart-wide{grid-column:1/-1}
.op-chart-grid .op-chart-wide canvas{height:300px !important}

/* 预警跳转：对应客户行红色呼吸高亮
 *
 * ⚠️ 千万不要用 background-color 做这个呼吸 —— 深色主题里有
 *    `html.theme-dark td{background:#1e293b !important}`（每个单元格都自带不透明底色），
 *    而按 CSS 层叠顺序，**!important 的作者声明排在 CSS 动画之上**：
 *    动画算出来的颜色会被逐个 td 自己的底色整片盖掉。
 *    实测证据（2026-09-19）：点击催缴预警后类名确实加到了正确的行上，
 *    但连续采样 33 次，td 的背景色**只有一种**（rgb(30,41,59) = #1e293b），
 *    呼吸一秒都没动 —— 界面上只剩那圈静态的红描边，看起来就是"效果异常"。
 *
 *    两个改动：
 *      ① 改用 **inset box-shadow** 铺红（box-shadow 没有被 !important 抢走的竞争者）；
 *      ② 动画加在 **td** 上而不是 tr 上 —— tr 自己的背景同样会被 td 盖住。
 *    描边也放进关键帧里跟着一起呼吸，不再用 outline
 *    （outline 画在 <tr> 上各浏览器表现不一致，而且 body 有 zoom 会被缩放）。
 *    只用 box-shadow 不改变布局。
 */
@keyframes opRowFlash{
  0%,100%{box-shadow:inset 0 0 0 2px rgba(239,68,68,.5), inset 0 0 0 9999px rgba(239,68,68,.12)}
  50%{box-shadow:inset 0 0 0 2px rgba(239,68,68,.95), inset 0 0 0 9999px rgba(239,68,68,.3)}
}
.op-row-flash>td{animation:opRowFlash .8s ease-in-out 4}

/* ---- 缴费登记表：缩小行高 ---- */
.op-input-table td{line-height:1.2;padding-top:2px !important;padding-bottom:2px !important}
.op-input-table .op-month-cell input{padding:2px 3px !important;min-width:52px;font-size:11px}
.op-input-table .op-col-text input,.op-input-table .op-col-area input,.op-input-table .op-col-monthly input,.op-input-table .op-col-date input{padding:2px 5px !important;font-size:11px}
.op-input-table .op-col-cycle select{padding:2px 4px !important;font-size:11px}
.op-input-table .op-c-name{font-size:12px}

.op-input-table input,.op-input-table select{min-height:0 !important;height:auto !important}
