/* 财务控制台：暗色专业后台，全幅布局（内容吃满屏幕，不做居中版心留白）。
   字号层级：页面标题(20px) > 分区标题(16px) > 正文(13px) > 辅助文字(12px，muted)。 */

/* 带 hidden 属性的元素一律不显示：各个 class 的 display（flex、inline-flex……）会盖过浏览器对 [hidden] 的默认样式，
   以前每踩一次补一条 .xxx[hidden]（下面还留着十来条），漏补的就成了「藏不住」的按钮与表单（账单「改成只收还没收的部分」、
   重置密码成功后的表单）。界面上的显示/隐藏一律用 .hidden 切，没有用 style.display 的，所以 !important 不会打架。 */
[hidden] { display: none !important; }

:root {
  --bg: #0f1115;
  --panel: #171a21;
  --panel-2: #1e222b;
  --border: #2a2f3a;
  --text: #e6e8ec;
  --muted: #8b93a3;
  --accent: #4f8cff;
  --accent-2: #3a6fd6;
  --danger: #e5484d;
  --success: #2fb673;
  --warn: #e0a63a;
  /* 中性标记（迁来、系统来源这类「这行是哪来的」）：不借黄色——黄色只表示待办、缺资料（UI 审视 §4.5） */
  --info: #7aa7ff;
  /* 间距与控件尺寸（2026-10 列表页重排起用；新写的样式取这几档，不再随手写像素） */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --radius: 6px;
  --radius-lg: 8px;
  --control-h: 34px;
  --accent-soft: rgba(79, 140, 255, .14);
  --accent-line: rgba(79, 140, 255, .38);
  --divider: rgba(42, 47, 58, .65); /* 表格行间细分隔线：比 --border 更淡 */
}

* { box-sizing: border-box; }

/* ---------- 滚动条：全站统一深色主题 ----------
   暗色界面上浏览器默认滚动条是浅色宽条，非常刺眼（老板截图反馈）。全仓会滚动的容器：整页
   （html，内容超出视口高度时）、.side-nav（侧栏，导航分组变多后触底更常见）、.table-wrap
   （表格横向滚动）、.overlay（详情浮层内容过长时纵向滚动）——统一在这一处处理，不逐个补。
   标准属性 scrollbar-color/scrollbar-width（Firefox、新版 Chrome/Edge）+ ::-webkit-scrollbar
   系列（Safari、旧版 Chrome）两套都写；颜色一律取现有变量，不硬编码，换主题时这里跟着变。
   不用 overflow:hidden 藏——侧栏在窄屏/缩放下确实需要滚到底（最后一项"审计日志"要够得着）。 */
html,
.side-nav,
.table-wrap,
.overlay {
  scrollbar-color: var(--border) var(--panel);
  scrollbar-width: thin;
}
html::-webkit-scrollbar,
.side-nav::-webkit-scrollbar,
.table-wrap::-webkit-scrollbar,
.overlay::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}
html::-webkit-scrollbar-track,
.side-nav::-webkit-scrollbar-track,
.table-wrap::-webkit-scrollbar-track,
.overlay::-webkit-scrollbar-track {
  background: var(--panel);
}
html::-webkit-scrollbar-thumb,
.side-nav::-webkit-scrollbar-thumb,
.table-wrap::-webkit-scrollbar-thumb,
.overlay::-webkit-scrollbar-thumb {
  background-color: var(--border);
  border-radius: 6px;
}
html::-webkit-scrollbar-thumb:hover,
.side-nav::-webkit-scrollbar-thumb:hover,
.table-wrap::-webkit-scrollbar-thumb:hover,
.overlay::-webkit-scrollbar-thumb:hover {
  background-color: var(--muted);
}

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, "Segoe UI", "PingFang SC", "Microsoft YaHei", Tahoma, Helvetica, Arial, sans-serif;
  font-size: 13px;
  line-height: 1.5;
  width: 100%;
}

button, input, select, textarea { font-family: inherit; font-size: 13px; }

/* ---------- 顶栏（仅登录页使用，登录后由侧栏承载品牌/身份） ---------- */
.topbar {
  padding: 12px 24px;
  border-bottom: 1px solid var(--border);
  background: var(--panel);
}
.topbar h1 { font-size: 20px; font-weight: 600; margin: 0; }

/* ---------- 登录 ---------- */
/* 同上：#login-view{display:flex} 特异度比 [hidden] 更高（ID > 属性选择器），必须显式加
   [hidden] 覆盖规则，否则登录成功后登录表单不会真正消失（仍浮在应用视图上方）。 */
#login-view[hidden] { display: none; }
#login-view { display: flex; flex-direction: column; align-items: center; }
#login-view .topbar { width: 100%; }
#login-view .login-form { margin: 80px 24px 0; }
.login-form {
  width: 320px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 24px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.login-form h2 { font-size: 16px; margin: 0 0 4px; font-weight: 600; }
.login-form label { display: flex; flex-direction: column; gap: 6px; color: var(--muted); font-size: 12px; }

/* ---------- 通用表单元素 ---------- */
/* :not([type=checkbox]) 而不是逐个列举 type 值——不带 type 属性的 <input>（浏览器隐式当
   text 处理，但属性选择器 input[type="text"] 匹配不到不带该属性的元素）踩过这个坑：筛选栏的
   输入框全部落回浏览器默认白底黑字，暗色主题当场破功。checkbox 需要保留原生小方框样式，单独排除。 */
input:not([type="checkbox"]), select, textarea {
  background: var(--panel-2);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 4px;
  padding: 6px 8px;
}
input:focus, select:focus, textarea:focus { outline: 1px solid var(--accent); }

.btn {
  background: var(--accent);
  color: #fff;
  border: none;
  border-radius: 4px;
  padding: 6px 14px;
  cursor: pointer;
}
.btn:hover { background: var(--accent-2); }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn-primary { background: var(--accent); }
.btn-ghost { background: transparent; border: 1px solid var(--border); color: var(--text); }
.btn-danger { background: var(--danger); }
.btn-warn { background: var(--warn); color: #1a1200; }
.btn-sm { padding: 3px 9px; font-size: 12px; }

.error { color: var(--danger); font-size: 12px; min-height: 14px; }
.muted { color: var(--muted); font-size: 12px; }

/* ---------- 左侧菜单 + 右侧内容区（老板指定，参照 geo 运营台观感） ---------- */
.console { display: flex; align-items: stretch; min-height: 100vh; }

.side-nav {
  flex: 0 0 220px;
  width: 220px;
  display: flex;
  flex-direction: column;
  background: var(--panel);
  border-right: 1px solid var(--border);
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
}
.side-nav-logo {
  display: flex;
  align-items: center;
  gap: .55rem;
  padding: 18px 16px;
  font-weight: 600;
  font-size: 15px;
  color: var(--text);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.side-nav-logo svg { flex: none; color: var(--accent); }

/* ---------- 企业切换器（超管全局态，见控制台企业维度 spec） ---------- */
.side-nav-enterprise {
  display: flex; flex-direction: column; gap: 4px;
  padding: 12px 16px; border-bottom: 1px solid var(--border);
}
.side-nav-enterprise-label { color: var(--muted); font-size: 11px; }
.side-nav-enterprise select { width: 100%; }
.session-enterprise-name { font-weight: 600; overflow-wrap: anywhere; }

/* .tab 类名与 data-tab 属性不变——console.js 的 switchTab 靠这两个钩子工作，
   这里只重排视觉（横向 tabs 改竖排菜单项），不碰 JS。 */
.side-nav-menu { flex: 1; display: flex; flex-direction: column; gap: 3px; padding: 10px 8px; }
.side-nav-menu .tab {
  display: flex;
  align-items: center;
  gap: 10px;
  background: none;
  border: none;
  border-left: 3px solid transparent;
  border-radius: 4px;
  color: var(--muted);
  padding: 9px 10px;
  cursor: pointer;
  text-align: left;
}
/* 同 .overlay[hidden] 那处踩过的坑：author 样式表的 .side-nav-menu .tab{display:flex} 优先级
   高于浏览器给 [hidden] 元素加的默认 display:none，不显式声明会让超管专属入口（企业管理/
   企业账号/审计日志）对企业用户"hidden=true 但视觉仍然显示"——2026-08-29 导航重排验收时
   实测发现：三个入口一直是可见的，只是点进去后端 403，不是本次改动引入，顺手修在这。 */
.side-nav-menu .tab[hidden] { display: none; }
.side-nav-menu .tab svg { flex: none; }
.side-nav-menu .tab:hover { background: var(--panel-2); color: var(--text); }
/* 分组标题：纯视觉分隔，不是 .tab（不带 data-tab，switchTab 的 querySelectorAll('.tab')
   选不中它，点了也没反应——2026-08-29 导航重排，五组："收款/付款/记账/档案/设置"，
   老板反馈"分区平铺、理不清"后按使用频率分组）。 */
.side-nav-group-label {
  padding: 14px 10px 4px;
  color: var(--muted);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .04em;
}
.side-nav-group-label:first-child { padding-top: 4px; }
.side-nav-menu .tab.active {
  background: var(--panel-2);
  color: var(--accent);
  border-left-color: var(--accent);
  font-weight: 600;
}

.side-nav-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 14px 16px;
  border-top: 1px solid var(--border);
  color: var(--muted);
  font-size: 12px;
}

.console-main { flex: 1; min-width: 0; width: 100%; padding: 20px 24px 60px; }

/* 窄屏（≤900px）：侧栏改成从左边拉出的抽屉，顶上一条「☰ + 分区名」——见 console-mobile.css、nav-drawer.js */

section.tab-panel h2 { font-size: 16px; font-weight: 600; margin: 0 0 12px; }
section.tab-panel h3 { font-size: 16px; font-weight: 600; margin: var(--space-5) 0 var(--space-3); color: var(--text); } /* 分区标题 16，分区之间 24、标题到内容 12 */
/* h4：三级子标题（如「应付单」小节里的「新建应付单」表单入口）——此前没有任何分区用到 h4，
   浏览器默认 h4 与正文同大小，视觉权重和 h3 分不清。明确比 h3 更轻（更小 + muted 灰），
   让"标题包含关系"一眼可辨（应付 h2 > 应付单 h3 > 新建应付单 h4），照本仓 CLAUDE.md
   「瑕疵即修」处理，与 h2/h3 同一处规则挨着放，不散落。 */
section.tab-panel h4 { font-size: 12px; font-weight: 600; margin: 16px 0 8px; color: var(--muted); text-transform: uppercase; letter-spacing: .03em; }

/* ---------- 分区内二级切换（.subtab） ---------- */
/* 目前只有「报表」分区用（四张只读报表共一个顶级入口，见 public/js/console/reports.js）。
   刻意不叫 .tab：core.js 顶层 querySelectorAll('.tab') 绑的是顶级导航切换，复用类名会让
   二级按钮去调 switchTab(undefined)。视觉上也该有区别——顶级入口在侧栏，这一排是内容区
   自己的分页，做成下划线式而不是侧栏那种整块高亮。 */
.subtabs { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 16px; border-bottom: 1px solid var(--border); }
.subtab {
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  color: var(--muted);
  padding: 6px 12px 8px;
  font: inherit;
  font-size: 13px;
  cursor: pointer;
  margin-bottom: -1px;
}
.subtab:hover { color: var(--text); }
.subtab.active { color: var(--accent); border-bottom-color: var(--accent); font-weight: 600; }

/* ---------- 工具栏（筛选） ---------- */
.toolbar { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; align-items: center; }
.toolbar input, .toolbar select { min-width: 120px; }
/* 带筛选控件的工具栏与应付/账单的 .list-toolbar 同一个样子（一条浅色卡片、控件一样高）；只有按钮的（如审计日志翻页）不套卡片 */
.toolbar:has(select, input) { padding: var(--space-3); background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius-lg); }
.toolbar:has(select, input) :is(input:not([type="checkbox"]), select, .btn) { height: var(--control-h); }

/* ---------- 列表页（应付、账单；2026-10 重排）：页头 · 一行工具栏 · 提示条 · 表格卡片 ----------
   结构：.page-head（标题 + 一行说明 + 主操作）→ .list-toolbar（list-toolbar.js：月份前后翻、状态分段、
   搜索框、更多筛选弹层）→ .lt-chips（生效的高级条件）→ .list-info（往月未结/截断）→ .table-card > .table-wrap.table-sticky > table.list-table。
   全是新类名、按需套用，不改 .toolbar / table.data-table 的全站默认样式——其它分区要同款观感直接套这几个类。 */
.page-head { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: var(--space-3) var(--space-4); margin-bottom: var(--space-4); }
section.tab-panel .page-head h2 { font-size: 20px; margin: 0 0 var(--space-1); } /* 页标题 20（文件头的字号层级） */
.page-desc { margin: 0; color: var(--muted); font-size: 12px; }
.page-action { flex: none; height: var(--control-h); padding: 0 var(--space-4); font-weight: 500; }
.page-actions { display: flex; flex: none; flex-wrap: wrap; gap: var(--space-2); }

.list-toolbar {
  position: relative; /* 窄屏时「更多筛选」弹层以整条工具栏为准定位（见下方 700px 断点） */
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-3);
  padding: var(--space-3); background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius-lg);
}
.list-toolbar input, .list-toolbar select, .list-toolbar .btn { height: var(--control-h); }

.month-stepper { display: inline-flex; align-items: stretch; border: 1px solid var(--border); border-radius: var(--radius); background: var(--panel-2); overflow: hidden; }
.month-stepper .ms-btn { width: 30px; background: none; border: none; color: var(--muted); font-size: 16px; cursor: pointer; }
.month-stepper .ms-btn:hover { color: var(--text); background: var(--border); }
.month-stepper .ms-input { border: none; border-radius: 0; background: transparent; width: 140px; text-align: center; height: calc(var(--control-h) - 2px); }
.month-stepper.is-overridden .ms-input { opacity: .4; } /* 自定义日期生效时月份不起作用：灰掉，标签行写着实际的日期段 */

.segmented { display: inline-flex; padding: 2px; gap: 2px; background: var(--panel-2); border: 1px solid var(--border); border-radius: var(--radius); }
.segmented button {
  height: calc(var(--control-h) - 6px); padding: 0 var(--space-3); border: none; border-radius: 4px;
  background: none; color: var(--muted); cursor: pointer; white-space: nowrap;
}
.segmented button:hover { color: var(--text); }
.segmented button.is-active { background: var(--accent-soft); color: var(--accent); font-weight: 600; }

.lt-search { position: relative; flex: 1 1 260px; min-width: 200px; max-width: 520px; display: flex; align-items: center; }
.lt-search svg { position: absolute; left: 10px; color: var(--muted); pointer-events: none; }
.lt-search input { width: 100%; padding-left: 30px; }

.lt-more { position: relative; margin-left: auto; }
.lt-more-btn { display: inline-flex; align-items: center; gap: 6px; }
.lt-more-btn.is-active { border-color: var(--accent-line); color: var(--accent); }
.lt-count { min-width: 18px; padding: 0 5px; border-radius: 9px; background: var(--accent); color: #fff; font-size: 11px; line-height: 18px; text-align: center; }
.lt-count[hidden] { display: none; }
.lt-popover {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 20; width: 360px;
  display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-3); padding: var(--space-4);
  background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: 0 12px 32px rgba(0, 0, 0, .45);
}
.lt-popover[hidden] { display: none; } /* display:grid 会盖掉 hidden（同 .overlay[hidden] 的坑） */
.lt-field { display: grid; grid-template-columns: 5.5em minmax(0, 1fr); align-items: center; gap: var(--space-2); min-width: 0; }
.lt-field > span { color: var(--muted); font-size: 12px; }
.lt-field select { width: 100%; min-width: 0; height: var(--control-h); }
.lt-range { display: flex; align-items: center; gap: 6px; }
.lt-range input { flex: 1; min-width: 0; height: var(--control-h); }
.lt-note { margin: calc(-1 * var(--space-1)) 0 0; }
.lt-pop-actions { display: flex; align-items: center; justify-content: space-between; padding-top: var(--space-3); border-top: 1px solid var(--border); }

.lt-chips { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: var(--space-2); }
.lt-chips[hidden] { display: none; }
.chip {
  display: inline-flex; align-items: center; gap: 2px; max-width: 360px; padding: 2px 4px 2px 10px;
  border: 1px solid var(--accent-line); border-radius: 999px; background: var(--accent-soft); font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.chip-x { background: none; border: none; color: var(--muted); cursor: pointer; font-size: 14px; line-height: 1; padding: 0 4px; }
.chip-x:hover { color: var(--text); }

.list-info {
  margin-top: var(--space-3); padding: var(--space-2) var(--space-3); font-size: 12px; color: var(--muted);
  background: var(--panel); border: 1px solid var(--border); border-left: 3px solid var(--accent); border-radius: var(--radius);
}
.list-info .row-link { padding: 0 4px; }
.list-info-warn { border-left-color: var(--warn); color: var(--warn); }
.list-totals b { color: var(--text); font-variant-numeric: tabular-nums; } /* 列表合计条（list-totals.js）：数字用正文色，说明文字仍是弱化色 */

.table-card { margin-top: var(--space-3); background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius-lg); overflow: hidden; }
.table-card > .table-wrap { border: none; border-radius: 0; }
/* 表头吸顶：滚动发生在卡片里（横向本来就在这里滚），所以给卡片一个视口内的高度上限 */
.table-sticky { max-height: calc(100vh - 230px); overflow: auto; }
.table-sticky thead th { position: sticky; top: 0; z-index: 2; }
table.list-table th { padding: 10px 12px; background: var(--panel); border-bottom: 1px solid var(--border); }
table.list-table td { padding: 10px 12px; height: 44px; border-bottom: 1px solid var(--divider); vertical-align: middle; }
table.list-table tbody tr:hover { background: var(--panel-2); }
table.list-table tbody tr.table-state:hover { background: none; }
table.list-table tr.table-state td { height: auto; padding: 48px 14px; text-align: center; font-size: 13px; }
table.list-table.hide-entity .col-entity { display: none; }
.cell-title, .cell-sub { max-width: 18em; overflow: hidden; text-overflow: ellipsis; }
.cell-title { font-weight: 500; }
.cell-sub { margin-top: 2px; color: var(--muted); font-size: 12px; }
.cell-clip { display: inline-block; max-width: 9em; overflow: hidden; text-overflow: ellipsis; vertical-align: bottom; }
/* 状态格里的几个徽标（状态、迁移、逾期）上下排，不横着把表格撑宽 */
table.list-table td.cell-status .badge { display: block; width: max-content; }
table.list-table td.cell-status .badge + .badge { margin-top: 4px; }
table.list-table td.num-minor { color: var(--muted); font-size: 12px; }
table.list-table td.num-key { font-weight: 600; font-size: 14px; }

/* 新建表单弹窗（form-dialog.js，控制台所有「＋ 新建…」共用）：比详情浮层窄一些；内容过长时在弹窗里滚，
   底部操作条（取消 / 主按钮）贴底常在，不用滚到最下面才找得到「保存」 */
.overlay-panel.form-dialog { max-width: 860px; max-height: calc(100vh - 80px); overflow-y: auto; padding-bottom: 0; }
.dialog-hint { margin: -4px 0 var(--space-4); }
.dialog-form { display: flex; flex-direction: column; gap: var(--space-2); }
.dialog-form > .form-row input, .dialog-form > .form-row select { max-width: none; }
.dialog-actions {
  position: sticky; bottom: 0; z-index: 1; display: flex; justify-content: flex-end; gap: var(--space-2);
  margin: var(--space-3) calc(-1 * var(--space-5)) 0; padding: var(--space-3) var(--space-5) var(--space-4);
  background: var(--panel); border-top: 1px solid var(--border);
}
.form-grid > .dialog-actions, .form-grid > .bill-notice { grid-column: 1 / -1; }
/* 弹窗比 26em 还窄时（手机）一列也不能撑破弹窗 */
.form-dialog .form-grid { grid-template-columns: repeat(auto-fit, minmax(min(26em, 100%), 1fr)); }
.form-dialog .table-wrap { margin: var(--space-2) 0; }
.form-dialog .table-wrap input { width: 100%; }
.overlay-panel.form-dialog { scrollbar-color: var(--border) var(--panel); scrollbar-width: thin; }
@media (max-width: 700px) {
  .overlay:has(.form-dialog) { padding: var(--space-4) var(--space-3); }
  .overlay-panel.form-dialog { max-height: calc(100vh - 32px); padding: var(--space-4) var(--space-4) 0; }
  .dialog-actions { margin: var(--space-3) calc(-1 * var(--space-4)) 0; padding: var(--space-3) var(--space-4); }
}

@media (max-width: 700px) {
  .lt-search { flex-basis: 100%; max-width: none; order: 3; }
  .lt-more { margin-left: 0; position: static; } /* 弹层改以工具栏为准：按钮换到行首也不会跑出屏幕 */
  .lt-popover { left: var(--space-3); right: var(--space-3); width: auto; }
  .lt-field { grid-template-columns: minmax(0, 1fr); gap: var(--space-1); } /* 标签放上面，日期框才放得下 */
}
@media (max-width: 900px) {
  .table-sticky { max-height: none; } /* 窄屏整页滚：卡片里再套一层纵向滚动在手机上很难用 */
}

/* ---------- 表格 ---------- */
.table-wrap { width: 100%; overflow-x: auto; border: 1px solid var(--border); border-radius: 6px; }
table.data-table { width: 100%; border-collapse: collapse; white-space: nowrap; }
table.data-table th, table.data-table td { padding: 8px 10px; border-bottom: 1px solid var(--border); text-align: left; }
table.data-table th { color: var(--muted); font-weight: 500; font-size: 12px; background: var(--panel); }
table.data-table tbody tr:hover { background: var(--panel-2); }
table.data-table tbody tr:last-child td { border-bottom: none; }
/* 带上 table.data-table：只写 td.num 的特异度（0,1,1）低于上面的 table.data-table td（0,1,2），金额列一直是左对齐的 */
td.num, th.num, table.data-table td.num, table.data-table th.num { text-align: right; font-variant-numeric: tabular-nums; }
tr.clickable { cursor: pointer; }

/* ---------- 企业管理：下辖关系展开（老板反馈"看不出企业下面有哪些主体/账号/系统"，
   2026-08-29 补）——原生 <details>，不新写展开/收起的 JS 状态管理。white-space 局部转
   normal：表格全局 nowrap，明细名字长了要能换行，不然横向撑出滚动条。 */
.ent-detail-list { white-space: normal; margin: 4px 0 0; padding-left: 16px; font-size: 12px; color: var(--muted); }

.badge { display: inline-block; padding: 2px 8px; border-radius: 10px; font-size: 11px; background: var(--panel-2); color: var(--muted); border: 1px solid var(--border); }
.badge-paid { color: var(--success); border-color: var(--success); }
.badge-partially_paid, .badge-partial { color: var(--warn); border-color: var(--warn); }
.badge-void, .badge-written_off { color: var(--danger); border-color: var(--danger); }
.badge-issued { color: var(--accent); border-color: var(--accent); }
.badge-overdue { color: var(--warn); border-color: var(--warn); } /* 逾期是要去催的待办，用警示色；红色只留给作废、报错与危险操作（UI 审视 §4.5） */

/* ---------- 客户档案：历史迁移行标灰（存量散客误建档，不进认领/合并） ---------- */
tr.row-legacy { color: var(--muted); }
tr.row-legacy td { color: inherit; }

/* ---------- 主体卡片（③ 主体分区） ---------- */
.ent-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(360px, 1fr)); gap: 16px; }
.ent-card {
  background: var(--panel); border: 1px solid var(--border); border-radius: 8px;
  padding: 16px; display: flex; flex-direction: column; gap: 10px;
}
.ent-card-top { display: flex; align-items: center; justify-content: flex-end; gap: 6px; }
.ent-name-th { font-size: 18px; font-weight: 600; }
.ent-name-en { font-size: 13px; margin-top: -6px; }
.ent-kv { display: flex; flex-direction: column; gap: 4px; padding-top: 4px; border-top: 1px solid var(--border); }
.ent-kv-row { display: grid; grid-template-columns: 48px 1fr; gap: 10px; }
.ent-kv-label { color: var(--muted); font-size: 12px; }
.ent-kv-value { font-size: 13px; }
.ent-vat-row { display: flex; align-items: center; gap: 10px; font-size: 12px; }
.ent-vat-yes { color: var(--success); border-color: var(--success); }
.ent-vat-no { color: var(--muted); }

/* ---------- 通用表单行（老板定标准：label 与输入框同行，不竖排堆叠） ---------- */
/* label 列固定宽度靠右对齐 + 控件占余宽；:has(textarea) 让多行控件的 label 顶对齐而不是
   垂直居中（否则「地址」这种两行 textarea 会把 label 文字挤到中间，观感很怪）。 */
.form-row {
  display: grid;
  grid-template-columns: minmax(7em, 9em) 1fr;
  align-items: center;
  gap: 4px 12px;
}
/* .form-row{display:grid} 与 [hidden]{display:none} 特异度相同（都是 0,1,0），author 样式表
   优先于 UA 默认样式表——同 .overlay[hidden] 那次踩过的坑（见下方账单详情浮层注释），条件显隐的
   .form-row（如 vendors.js 的个人税号行、wht-certificates.js 的其它说明行）不显式声明会一直显示。 */
.form-row[hidden] { display: none; }
.form-row:has(textarea) { align-items: start; }
.form-row-label { color: var(--muted); font-size: 12px; text-align: right; padding-top: 1px; }
/* 输入控件封顶：不封顶时在宽屏下会拉满整屏（1800px+ 的输入框），与 geo 运营台同款上限对齐 */
.form-row input, .form-row select, .form-row textarea { width: 100%; max-width: 34em; resize: vertical; }
.form-row textarea { max-width: 56em; }
@media (max-width: 700px) {
  .form-row { grid-template-columns: 1fr; }
  .form-row-label { text-align: left; padding-top: 0; }
}

/* 窄类，不改 .form-row 本身（全站共用）：完整表单（多个 .form-row 字段，如「新建应付单」）在
   宽屏下单列堆到底会浪费横向空间、把面板拉得很高。这个容器让直接子级 .form-row 按可用宽度
   自动分列流动，窄屏自动回落单列——不是把字段拆细改结构，只是让本来就存在的 .form-row 序列
   在宽屏下并排摆放。.form-row input 的全局 34em 上限在这里会让格子里的控件缩水留空，
   在容器内局部去掉（不动全局规则，其它分区的 .form-row 不受影响）。操作按钮/错误提示行
   要跨满整行，否则会被塞进某一列显得突兀。 */
.form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(26em, 1fr)); gap: 4px 24px; }
.form-grid .form-row input, .form-grid .form-row select, .form-grid .form-row textarea { max-width: none; }
.form-grid > .ent-form-actions, .form-grid > .error, .form-grid > h3, .form-grid > p { grid-column: 1 / -1; }
/* 应付单的「扣缴凭证默认值」子表单（payable-edit.js wireCertDefaults）：容器本身不占格，里面的行照常按网格流动 */
.form-grid > .cert-defaults { display: contents; }
.form-grid > .cert-defaults > p { grid-column: 1 / -1; }

/* ---------- 统计卡（手工记账月度汇总：收入/成本/毛利三数） ---------- */
/* max 240px（不是 1fr）：auto-fit + 1fr 会把空轨道全部吞给已有卡片，宽屏下 3 张卡被拉到
   约 660px 各装一个数字，空得离谱（老板反馈）。封顶后空轨道折叠为 0 宽，卡片自然靠左紧凑排列，
   窄屏下 minmax 下限仍在，正常堆叠不受影响。 */
.stat-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 240px)); gap: 12px; margin: 12px 0; }
.stat-card {
  background: var(--panel); border: 1px solid var(--border); border-radius: 8px;
  padding: 14px 16px; display: flex; flex-direction: column; gap: 6px;
}
.stat-card-label { color: var(--muted); font-size: 12px; }
.stat-card-value { font-size: 22px; font-weight: 600; font-variant-numeric: tabular-nums; }
.stat-card-highlight { border-color: var(--accent); }
.stat-card-highlight .stat-card-value { color: var(--accent); }

/* ---------- 主体卡片：50 ทวิ 签名/印章上传（AP-2） ---------- */
/* 控件一行（选文件 + 清除）、预览图单独一行放在下面：此前三者挤在一个自动换行的容器里，卡片一窄
   预览图就被挤到上一行、看着像挂在上一个字段下面（2026-09-11 用户截图）。 */
.ent-image-field { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }
.ent-image-controls { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.ent-image-preview { max-height: 72px; max-width: 160px; background: #fff; border-radius: 4px; padding: 2px; }
.form-row:has(.ent-image-field) { align-items: start; }

/* ---------- 主体卡片：编辑态 ---------- */
/* 编辑态卡片跨满整行（.ent-list 是自动分列的卡片网格，查看态一格一张；编辑时字段多，占满整行
   再按 .form-grid 横向流动，不然宽屏下只用左边一格、右边全空）。地址跨满整行。 */
.ent-card-edit { grid-column: 1 / -1; }
.ent-card-edit > .form-row:has(textarea), .ent-card-edit > h4 { grid-column: 1 / -1; }
.ent-vat-field .ent-vat-inputs { display: flex; align-items: center; gap: 14px; }
.ent-checkbox-label { display: flex; align-items: center; gap: 6px; white-space: nowrap; flex-shrink: 0; }
.ent-form-actions { display: flex; gap: 8px; }
.ent-vat-hint { margin: -2px 0 0; }
/* 开证子表单里的"与惯例不符"提示（wht-certificates.js certFieldsFormHtml）：只给消息本身上底色，占 .form-row 第二格 */
/* 扣缴凭证台账（wht-ledger.js）：长串泰文法条截断，全文在 title */
.wl-ellipsis { max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cert-warn-msg { background: var(--warn); color: #1a1200; padding: 8px 10px; border-radius: 6px; font-size: 12px; max-width: 34em; /* 与 .form-row input/select 同宽 */ }

/* ---------- 账单详情浮层 ---------- */
/* [hidden] 与 .overlay 类选择器特异度相同（都是 0,1,0），author 样式表优先级高于浏览器
   默认样式表，.overlay{display:flex} 会盖掉浏览器给 [hidden] 元素加的 display:none——
   结果是"隐藏"的浮层其实仍以全屏 flex 容器渲染，吞掉整页所有点击（真实踩过：登录按钮点不动）。
   必须显式声明 [hidden] 优先级更高，才能让 hidden 属性真正生效。 */
.overlay[hidden] { display: none; }
.overlay {
  position: fixed; inset: 0; background: rgba(0,0,0,.6);
  display: flex; justify-content: center; align-items: flex-start;
  padding: 40px 24px; overflow-y: auto;
  z-index: 40; /* 要高过窄屏时吸顶的侧栏（z-index 30），否则手机上浮层被菜单盖住大半屏 */
}
.overlay-panel {
  width: 100%; max-width: 980px;
  background: var(--panel); border: 1px solid var(--border); border-radius: 8px;
  padding: 24px;
}
.detail-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; }
.detail-header h2 { margin: 0; }
.detail-meta { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 8px 20px; margin-bottom: 8px; }
.detail-meta .item .label { color: var(--muted); font-size: 11px; display: block; }
.detail-meta .item .value { font-variant-numeric: tabular-nums; }

/* 复用 lib/routes/admin-print.js 税票打印页同名 .print-warn 视觉（黄底警示条），账单详情浮层
   不是打印页、不需要 @media print 隐藏规则——但样式统一，别为同一件事再造第二套外观。 */
.print-warn { background: #fff3cd; border: 1px solid #e0b400; border-radius: 6px; padding: 10px 14px; margin-bottom: 14px; color: #7a5b00; }

.inline-form { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 8px 0; }

/* ---------- 应付单详情的金额链条（窄作用域） ---------- */
.ap-amount-chain { max-width: 320px; }
.ap-amount-row { display: flex; justify-content: space-between; gap: 12px; padding: 3px 0; }
.ap-amount-row .num { font-variant-numeric: tabular-nums; }
.ap-amount-row.ap-amount-sub { color: var(--muted); font-size: 13px; }
.ap-amount-row.ap-amount-total { border-top: 1px solid var(--border); margin-top: 4px; padding-top: 6px; font-weight: 600; }

/* ---------- 表格行内操作列：文字链接而非按钮（老板原话"scroller 很难看，操作区为什么
   不用超链接的形式呢"——先在 wht-certificates.js 定型，2026-08-29 推广到全部控制台分区）。
   按钮的边框+内边距在表格行内是重控件，几个挤一格必然撑出横向滚动条；换成文字链接后横向
   空间大幅下降，滚动条自然消失，不用再靠 flex-wrap 硬换行。全站共用类，禁止各分区各写一份
   （复用铁律）——新增行内操作列一律套这三个类，不要照抄一份改名字。
   仍用 <button> 标签（不是 <a href>）：这些是 JS 触发的动作，不是页面跳转，语义上按钮才对，
   这里只改视觉表现——data-* 属性和 querySelectorAll 事件绑定完全不动。 ---------- */
.row-actions { display: flex; flex-wrap: wrap; align-items: center; white-space: nowrap; }
.row-link {
  background: none; border: none; padding: 2px 8px; margin: 0;
  color: var(--accent); font-size: 12px; font-family: inherit; cursor: pointer;
}
.row-link:first-child { padding-left: 0; }
.row-link:not(:first-child) { border-left: 1px solid var(--border); }
.row-link:hover { text-decoration: underline; }
.row-link-danger { color: var(--danger); }

/* ---------- 资料上传位（attachments.js）：一类资料一行，资料名 + 已传文件 + 上传 ---------- */
table.data-table tr.todo-group td { background: var(--panel); }
.att-slots { display: flex; flex-direction: column; gap: 2px; }
.att-slot { display: flex; align-items: center; gap: 2px 6px; font-size: 12px; white-space: nowrap; }
.att-label { color: var(--muted); min-width: 5em; }
.att-file { display: inline-flex; align-items: center; }
.att-upload { cursor: pointer; }
.att-msg { white-space: normal; }
.att-msg:empty { display: none; }
/* 付款表里的冲回行与已作废的行：灰显，与有效付款区分开 */
tr.leg-muted td { color: var(--muted); }

/* 收付款表「资料」点开后的那一行 */
tr.att-expand td { background: var(--panel-2); }

/* ---------- 详情与弹窗共用的提示条（详情版面在 console-detail.css） ---------- */
/* 需要人先处理的提示条（补开单据、录入被拒的原因）：警示色边框，按钮跟在文字后面 */
.bill-notice { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; border: 1px solid var(--warn); border-radius: 6px; padding: 8px 12px; margin: 8px 0; }
.bill-notice[hidden] { display: none; }
.doc-missing, .bill-entry-over { color: var(--warn); }

/* ---------- Token 明文提示 ---------- */
.token-reveal {
  background: var(--warn); color: #1a1200; padding: 12px 14px; border-radius: 6px;
  margin-bottom: 14px; display: flex; flex-direction: column; gap: 6px;
}
.token-reveal code { background: rgba(0,0,0,.15); padding: 4px 8px; border-radius: 4px; word-break: break-all; font-size: 12px; }

/* ---------- Toast ---------- */
.toast {
  position: fixed; bottom: 24px; right: 24px; z-index: 50; /* 高过浮层：浮层里的操作结果要看得见 */
  background: var(--success); color: #06170f; padding: 10px 16px; border-radius: 6px;
  font-size: 13px; max-width: 360px;
}
.toast.error { background: var(--danger); color: #fff; }

/* 主体卡片里的号段设置：卡片本来就窄，四列表格必然要横向滚动（很难用），
   所以每个号段占一块、标签在上输入在下，输入框宽度自适应，任何宽度下都不横向滚。 */
.ent-numbering:not(:empty) { margin-top: 12px; border-top: 1px solid var(--line, #e5e5e5); padding-top: 12px; }
.ent-no-list { display: flex; flex-direction: column; gap: 10px; }
.ent-no-item { display: flex; flex-direction: column; gap: 4px; }
.ent-no-head { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.ent-no-edit { display: flex; gap: 6px; }
.ent-no-edit input { flex: 1 1 auto; min-width: 0; }
