:root {
  --bg: #f5f6f8;
  --card: #fff;
  --line: #e3e5e9;
  --text: #1f2328;
  --muted: #656d76;
  --accent: #2f5fd0;
  --overdue: #d64545;
  --risk: #d98324;
  --ok: #2e9e5b;
  --done: #8a93a0;
}
* { box-sizing: border-box; }
/* hidden 属性要压过下面各处的 display 规则，否则藏不住
   （登录页的「姓名」「确认密码」就栽在这儿） */
[hidden] { display: none !important; }
body {
  margin: 0;
  font: 14px/1.6 "Microsoft YaHei", "PingFang SC", system-ui, sans-serif;
  background: var(--bg);
  color: var(--text);
}
header {
  background: #fff;
  border-bottom: 1px solid var(--line);
  padding: 12px 20px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
}
h1 { font-size: 18px; margin: 0; }
h2 { font-size: 15px; margin: 24px 0 4px; }
.toolbar { display: flex; gap: 14px; align-items: center; flex-wrap: wrap; }
.toolbar label, .filters label { font-size: 13px; color: var(--muted); }
select, input[type="date"], input[type="number"], input[type="text"] {
  font: inherit;
  padding: 4px 6px;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: #fff;
  color: var(--text);
}
button {
  font: inherit;
  padding: 5px 12px;
  border: 1px solid var(--accent);
  background: var(--accent);
  color: #fff;
  border-radius: 4px;
  cursor: pointer;
}
button.ghost { background: #fff; color: var(--accent); }
button:hover { filter: brightness(1.08); }
button.mini { padding: 2px 8px; font-size: 12px; }

.tabs { display: flex; gap: 2px; padding: 0 20px; background: #fff;
        border-bottom: 1px solid var(--line); }
.tab { background: none; border: none; color: var(--muted); padding: 10px 16px;
       border-bottom: 2px solid transparent; border-radius: 0; }
.tab.active { color: var(--accent); border-bottom-color: var(--accent); font-weight: 600; }
main { padding: 16px 20px 60px; }
.panel { display: none; }
.panel.active { display: block; }
.hint { color: var(--muted); font-size: 13px; margin: 4px 0 12px; }

.summary { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 12px; }
.stat { background: #fff; border: 1px solid var(--line); border-radius: 6px;
        padding: 10px 16px; min-width: 110px; }
.stat b { display: block; font-size: 22px; line-height: 1.2; }
.stat span { color: var(--muted); font-size: 12px; }
.stat.bad b { color: var(--overdue); }
.stat.warn b { color: var(--risk); }

.filters { display: flex; gap: 14px; margin-bottom: 12px; flex-wrap: wrap; }
.cards { display: flex; flex-direction: column; gap: 10px; }
.card { background: var(--card); border: 1px solid var(--line); border-radius: 6px;
        padding: 12px 14px; border-left: 4px solid var(--done); }
.card.overdue { border-left-color: var(--overdue); }
.card.at_risk { border-left-color: var(--risk); }
.card.on_track { border-left-color: var(--ok); }
.card-top { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.card-top .title { font-weight: 600; font-size: 15px; }
.card-top .amount { margin-left: auto; font-weight: 600; font-size: 15px; }
.badge { font-size: 12px; padding: 1px 8px; border-radius: 10px; color: #fff; }
.badge.overdue { background: var(--overdue); }
.badge.at_risk { background: var(--risk); }
.badge.on_track { background: var(--ok); }
.badge.skip { background: #7d5ba6; }
.card-row { color: var(--muted); font-size: 13px; margin-top: 4px; }
.card-row b { color: var(--text); }
.card-actions { margin-top: 8px; display: flex; gap: 8px; flex-wrap: wrap; }

.grid { border-collapse: collapse; width: 100%; background: #fff; font-size: 13px; }
.grid th, .grid td { border: 1px solid var(--line); padding: 5px 8px; text-align: left; }
.grid th { background: #eef0f4; font-weight: 600; white-space: nowrap; }
.grid td.num, .grid th.num { text-align: right; font-variant-numeric: tabular-nums; }
.grid tr:hover td { background: #fafbfc; }
.grid td.bad { color: var(--overdue); font-weight: 600; }
.scroll-x { overflow-x: auto; }

.board { display: flex; flex-direction: column; gap: 4px; }
.board-row { display: flex; align-items: center; gap: 8px; background: #fff;
             border: 1px solid var(--line); border-radius: 4px; padding: 6px 10px; }
.board-row .label { width: 150px; flex: none; font-size: 13px; }
.board-row .label small { color: var(--muted); }
.board-row .track { display: flex; gap: 2px; flex: 1; }
.board-row .meta { width: 150px; flex: none; text-align: right; font-size: 12px;
                   color: var(--muted); }
.cell { flex: 1; height: 20px; border-radius: 2px; cursor: default; min-width: 8px; }
.chip { font-size: 12px; padding: 1px 8px; border-radius: 3px; margin-right: 4px; }
.s-done_on_time, .cell.s-done_on_time { background: #c6efce; }
.s-done_late,    .cell.s-done_late    { background: #ffe08a; }
.s-overdue,      .cell.s-overdue      { background: #f5a3a3; }
.s-due_soon,     .cell.s-due_soon     { background: #ffd0a1; }
.s-pending,      .cell.s-pending      { background: #e6e8ec; }
.s-na,           .cell.s-na           { background: #cfd3da; }

.chart { background: #fff; border: 1px solid var(--line); border-radius: 6px; padding: 12px; }
.bar-row { display: flex; align-items: center; gap: 8px; margin-bottom: 5px; font-size: 13px; }
.bar-row .bl { width: 190px; flex: none; }
.bar-row .bt { flex: 1; background: #f0f1f4; height: 18px; position: relative;
               border-radius: 3px; overflow: hidden; }
.bar-row .fill { height: 100%; background: var(--ok); }
.bar-row .fill.over { background: var(--overdue); }
.bar-row .sla { position: absolute; top: -2px; bottom: -2px; width: 2px;
                background: #333; }
.bar-row .bv { width: 150px; flex: none; text-align: right; color: var(--muted); }

/* ---- 对账总表：照原表的两行表头和分组 ---- */
.sheet-bar { display: flex; gap: 16px; align-items: center; flex-wrap: wrap;
             margin-bottom: 6px; }
.sheet-bar .hint { margin: 0; }
.sheet-bar label { font-size: 13px; color: var(--muted); }
.legend { margin-bottom: 8px; }
.sheet-wrap {
  overflow: auto;
  max-height: calc(100vh - 248px);
  border: 1px solid #aeb4bf;
  border-radius: 4px;
  background: #fff;
}
/* table-layout:fixed 配 colgroup 定宽时，必须给表显式宽度。
   否则在滚动容器里会被 shrink-to-fit 压窄，列宽小于声明值，
   冻结列的 left 偏移就对不上，表头跟着错位。 */
table.sheet {
  border-collapse: separate;
  border-spacing: 0;
  font-size: 12px;
  table-layout: fixed;
}
table.sheet th, table.sheet td {
  border-right: 1px solid #dcdfe5;
  border-bottom: 1px solid #dcdfe5;
  padding: 4px 6px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  background: #fff;
  vertical-align: middle;
}

/* 表头：两行都吸顶，第 1 行深、第 2 行浅 */
table.sheet thead th {
  position: sticky;
  font-weight: 600;
  text-align: center;
  white-space: normal;
  word-break: break-all;
  line-height: 1.4;
  color: #273142;
  background: #ccd6e5;
  border-right: 1px solid #aeb8c6;
  border-bottom: 1px solid #aeb8c6;
  z-index: 3;
}
table.sheet thead tr:first-child th { top: 0; }
table.sheet thead tr:first-child th[rowspan="2"] { background: #c3cfe0; }
/* top 由 JS 按第 1 行的实际高度设置（--h1）。写死像素的话，
   表头文字换行高度一变就和第 2 行重叠，首行数据会被压在底下。 */
table.sheet thead tr:nth-child(2) th {
  top: var(--h1, 38px);
  font-weight: 500;
  font-size: 11.5px;
  background: #e4eaf2;
  color: #39445a;
}
/* 大类之间加一道深分隔线，一眼看出分组边界 */
table.sheet thead th.gstart, table.sheet tbody td.gstart {
  border-left: 1px solid #9aa4b4;
}

/* 左侧冻结列 */
table.sheet .frz { position: sticky; background: #fff; z-index: 2; }
table.sheet thead .frz { z-index: 5; }
table.sheet .frz.frz-last { border-right: 2px solid #8f99a8; }
table.sheet tbody td.frz { background: #fafbfd; font-weight: 500; }

table.sheet tbody tr:nth-child(even) td { background: #fbfcfd; }
table.sheet tbody tr:nth-child(even) td.frz { background: #f5f7fa; }
table.sheet tbody tr:hover td { background: #eef4ff; }
table.sheet tbody tr:hover td.frz { background: #e2ecff; }

/* 环节状态底色。必须压过上面的斑马纹和 hover，所以选择器写得更具体。 */
table.sheet tbody tr td.s-done_on_time,
table.sheet tbody tr:hover td.s-done_on_time { background: #c6efce; }
table.sheet tbody tr td.s-done_late,
table.sheet tbody tr:hover td.s-done_late { background: #ffe08a; }
table.sheet tbody tr td.s-overdue,
table.sheet tbody tr:hover td.s-overdue { background: #f5a3a3; }
table.sheet tbody tr td.s-due_soon,
table.sheet tbody tr:hover td.s-due_soon { background: #ffd0a1; }
table.sheet tbody tr td.s-pending,
table.sheet tbody tr:hover td.s-pending { background: #eceef2; }
table.sheet tbody tr td.s-na,
table.sheet tbody tr:hover td.s-na { background: #cfd3da; }
table.sheet td.num { text-align: right; font-variant-numeric: tabular-nums; }
table.sheet td.gap, table.sheet th.gap { background: #e9ecf1; padding: 0;
                                          border-right-color: #c9cfd8; }
table.sheet tbody tr:hover td.gap { background: #e9ecf1; }

table.sheet td.stage { text-align: center; cursor: pointer; }
table.sheet td.stage:hover { outline: 2px solid var(--accent); outline-offset: -2px; }
table.sheet td.stage .due { display: block; font-size: 10px; color: #7a828d;
                            line-height: 1.25; }
table.sheet td.editable:hover { outline: 1px dashed var(--accent); outline-offset: -1px; }

/* 公式列：系统按原表公式算出来的，不给编辑框，底色和输入格区分开 */
table.sheet tbody tr td.calc,
table.sheet tbody tr:hover td.calc { background: #f1f3f7; color: #39404b; }
table.sheet tbody tr td.calc::after {
  content: "ƒ"; float: left; color: #a8b0bd; font-size: 10px; margin-right: 2px;
}
table.sheet td.calc { cursor: not-allowed; }

/* 预估回款时间：正文放系统算出的目标日，顺延另起一行小字 */
table.sheet td.target { text-align: center; font-variant-numeric: tabular-nums; }
table.sheet td.target b { color: var(--accent); }
table.sheet td.target .slip { display: block; font-size: 10px; color: #b06a24;
                              line-height: 1.25; }
table.sheet td.cur { box-shadow: inset 0 0 0 2px #2f5fd0; }
table.sheet td.skipmark { box-shadow: inset 0 0 0 2px #7d5ba6; }
.chip.skipmark { background: #fff; box-shadow: inset 0 0 0 2px #7d5ba6; }
table.sheet input.cellin { width: 100%; border: 1px solid var(--accent); padding: 1px 3px;
                           font: inherit; }

/* ---- 参数设定 ---- */
.settings { display: flex; gap: 20px; flex-wrap: wrap; background: #fff;
            border: 1px solid var(--line); border-radius: 6px; padding: 10px 16px;
            margin-bottom: 8px; }
.settings label { display: flex; flex-direction: column; gap: 3px; font-size: 13px;
                  color: var(--muted); }
.settings small { color: #8a929e; font-size: 11.5px; }

/* 参数表：每格上面是天数输入框，下面是算出来的日期 */
table.sheet.ptable thead th { vertical-align: bottom; padding: 5px 4px; height: 56px; }
table.sheet.ptable thead th .pseq {
  display: block; font-size: 10.5px; color: #6b7585; font-weight: 500;
}
table.sheet.ptable td { padding: 3px 5px; }
table.sheet.ptable td.pcell { text-align: center; padding: 3px 4px; }
table.sheet.ptable td.pcell input {
  width: 100%; max-width: 62px; text-align: center; font: inherit;
  border: 1px solid #c9cfd8; border-radius: 3px; padding: 2px 3px;
  font-variant-numeric: tabular-nums;
}
table.sheet.ptable td.pcell input:focus { border-color: var(--accent); outline: none; }
table.sheet.ptable td.pcell input:placeholder-shown { color: #9aa2ae; }
table.sheet.ptable .pdate {
  display: block; margin-top: 2px; font-size: 10.5px; color: #5b6472;
  font-variant-numeric: tabular-nums;
}
table.sheet.ptable .pdate small { color: #99a1ad; margin-left: 3px; }
table.sheet.ptable td.paydate { font-variant-numeric: tabular-nums; white-space: nowrap; }
table.sheet.ptable td.paydate .pcalc { color: #8a929e; font-size: 11px; }
table.sheet.ptable td.paydate b { color: var(--accent); margin-left: 5px; }
table.sheet.ptable td.chainend { font-variant-numeric: tabular-nums; }
table.sheet.ptable td.slack { color: var(--ok); font-weight: 600; }
table.sheet.ptable td.slack.bad { color: var(--bad); }

.settings .fixedrule { font-size: 13px; color: #444c59; align-self: center;
                       padding: 4px 0; }
.settings .fixedrule b { color: var(--fg); }
.settings .fixedrule .eg { color: #8a929e; font-size: 11.5px; margin-left: 5px;
                           font-variant-numeric: tabular-nums; }
.settings .fixedrule .sep { color: #c3c9d2; margin: 0 9px; }
table.sheet.ptable tr.defrow td { background: #eef1f6; font-weight: 500; }
table.sheet.ptable tr.defrow td.frz { background: #e8ecf3; }
table.sheet.ptable tbody tr:hover td.pcell input { border-color: #a8b2c0; }


/* ---- 参数页：未保存改动 ---- */
.savebar { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.dirty-note { font-size: 13px; color: var(--muted); }
.dirty-note.on { color: #8a5a10; background: #fff6e0; border: 1px solid #e8cf92;
                 border-radius: 3px; padding: 2px 9px; }
table.sheet.ptable td.pcell input.dirty {
  background: #fff6e0; border-color: #d9a94a; font-weight: 600;
}
table.sheet.ptable td.pcell input:disabled,
table.sheet.ptable input.whoin:disabled {
  background: #f2f3f5; color: #9aa2ae; cursor: not-allowed;
}
table.sheet.ptable input.whoin {
  width: 100%; font: inherit; border: 1px solid #c9cfd8; border-radius: 3px;
  padding: 2px 4px;
}
table.sheet.ptable input.whoin.dirty { background: #fff6e0; border-color: #d9a94a; }
table.sheet.ptable tr.locked td.frz { background: #f4f5f7; }
.lockmark { font-size: 10px; color: #98a0ac; border: 1px solid #ccd2db;
            border-radius: 2px; padding: 0 3px; margin-left: 4px; }
.newproj { background: #fff; border: 1px solid var(--line); border-radius: 6px;
           padding: 9px 14px; margin-top: 10px; }
.newproj b { font-size: 13px; }
.grid td.projlist { max-width: 300px; white-space: normal; line-height: 1.5; }
.grid td .bad, .bad { color: var(--overdue); }

.toast { position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%);
         background: #1f2328; color: #fff; padding: 8px 16px; border-radius: 4px;
         opacity: 0; transition: opacity .2s; pointer-events: none; }
.toast.show { opacity: 1; }
.empty { color: var(--muted); padding: 24px; text-align: center; background: #fff;
         border: 1px dashed var(--line); border-radius: 6px; }
.warnbar { background: #fff8e6; border: 1px solid #e8cf92; border-left: 4px solid #d98324;
           border-radius: 4px; padding: 9px 14px; margin-bottom: 10px; font-size: 13px;
           line-height: 1.7; color: #5c4a22; }
.warnbar a { color: var(--accent); }

/* 右上角当前用户 */
.whoami { margin-left: auto; display: inline-flex; align-items: center; gap: 10px;
          font-size: 13px; color: var(--muted); }
.whoami .logout { color: var(--accent); text-decoration: none; }
.whoami .logout:hover { text-decoration: underline; }
