:root{
  color-scheme: light;
  --surface:#fcfcfb; --page:#f9f9f7;
  --ink:#0b0b0b; --ink2:#52514e; --muted:#898781;
  --grid:#e1e0d9; --baseline:#c3c2b7; --ring:rgba(11,11,11,.10);
  --s1:#2a78d6; --s2:#eb6834; --s3:#1baf7a;
  --good:#0ca30c; --warn:#fab219; --serious:#ec835a; --crit:#d03b3b;
  --good-text:#006300;
  --brand:#2a78d6; --brand-deep:#1c5cab;
}
*{box-sizing:border-box; margin:0; padding:0;}
body{font-family:system-ui,-apple-system,"Segoe UI","Microsoft YaHei",sans-serif;
     background:var(--page); color:var(--ink); font-size:14px;}

/* ===== 登录页 ===== */
#loginView{min-height:100vh; display:flex; align-items:center; justify-content:center;
  background:linear-gradient(160deg,#1c5cab 0%,#2a78d6 55%,#5598e7 100%);}
.login-card{background:var(--surface); border-radius:14px; padding:40px 44px; width:370px;
  box-shadow:0 20px 60px rgba(13,54,107,.35);}
.login-card h1{font-size:20px; margin-bottom:4px;}
.login-card .sub{color:var(--muted); font-size:12.5px; margin-bottom:26px;}
.field{margin-bottom:14px;}
.field label{display:block; font-size:12.5px; color:var(--ink2); margin-bottom:6px;}
.field input,.field select,.field textarea{width:100%; padding:10px 12px;
  border:1px solid var(--grid); border-radius:8px; font-size:14px; background:#fff;
  font-family:inherit;}
.field input:focus,.field select:focus,.field textarea:focus{outline:2px solid var(--s1);
  border-color:transparent;}
/* 数字框右边那两个上下小箭头【全部去掉】——（潘工原话：这个滚轮都去掉吧）
   一来占地方、把框里的数挤到看不全；二来点数、金额这种数
   本来就该照着单据敲，不是靠点箭头一格一格拱出来的。
   （鼠标滚轮滚过去会偷偷改数这件事，在 base.html 里一并挡掉了） */
input[type=number]::-webkit-outer-spin-button,
input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none; margin:0;}
input[type=number]{-moz-appearance:textfield; appearance:textfield;}
.btn-primary{width:100%; padding:11px; background:var(--brand); color:#fff; border:none;
  border-radius:8px; font-size:15px; cursor:pointer; margin-top:8px;}
.btn-primary:hover{background:var(--brand-deep);}
.login-note{margin-top:18px; font-size:12px; color:var(--muted); text-align:center; line-height:1.7;}

/* ===== 主框架 ===== */
.topbar{position:sticky; top:0; z-index:30; height:52px; background:var(--surface);
  border-bottom:1px solid var(--grid);
  display:flex; align-items:center; padding:0 20px; gap:16px;}
.logo{font-weight:700; font-size:15.5px; color:var(--brand-deep); white-space:nowrap;}
.logo span{color:var(--ink); font-weight:500;}
.topbar .spacer{flex:1;}
.userchip{display:flex; align-items:center; gap:8px; font-size:13px; color:var(--ink2);}
.avatar{width:28px; height:28px; border-radius:50%; background:var(--s1); color:#fff;
  display:flex; align-items:center; justify-content:center; font-size:13px; flex-shrink:0;}
.layout{display:flex;}
/* 侧边栏钉住不跟着滚 —— 台账几千行，翻到中间还要滚回顶上才能换栏目太难受。
   顶栏也一起钉住，sticky 之间 top 要错开 52px（顶栏自己的高度）。 */
.side{width:168px; background:var(--surface); border-right:1px solid var(--grid);
  min-height:calc(100vh - 52px); padding:14px 10px; flex-shrink:0;
  position:sticky; top:52px; align-self:flex-start;
  height:calc(100vh - 52px); overflow-y:auto;}
.nav-item{display:flex; align-items:center; gap:9px; padding:10px 12px; border-radius:8px;
  color:var(--ink2); cursor:pointer; font-size:13.5px; margin-bottom:2px; user-select:none;
  text-decoration:none;}
.nav-item:hover{background:#f1f0ec;}
.nav-item.active{background:#e7f0fb; color:var(--brand-deep); font-weight:600;}
.nav-item .ico{width:18px; text-align:center;}
.nav-badge{margin-left:auto; background:var(--crit); color:#fff; font-size:10.5px;
  border-radius:9px; padding:1px 6px;}
/* 【父项 + 子项】—— 财务底下东西多了（付款单、各工程管理费、凭证），
   全平铺在侧边栏上找不着。子项缩进一格、字小一号，前面一根短横当引导线
   （潘工原话：财务管理我需要做成多子项在里面的，财务管理分财务管理和凭证管理）*/
.nav-item.nav-sub{padding:6px 12px 6px 30px; font-size:12.5px; margin-bottom:1px;
  color:var(--muted); position:relative;}
.nav-item.nav-sub::before{content:""; position:absolute; left:19px; top:50%;
  width:6px; height:1px; background:var(--grid);}
.nav-item.nav-sub.on{background:#e7f0fb; color:var(--brand-deep); font-weight:600;}
.nav-item.nav-sub.on::before{background:var(--brand-deep);}
.nav-item.nav-parent.active{background:transparent;}
/* 表格列多，右边留白太浪费；宽屏时铺满，最多到 1920 免得字行太长 */
.main{flex:1; min-width:0; padding:20px 24px 40px; max-width:1920px;}
.page-title{font-size:17px; font-weight:700; margin-bottom:2px;}
.page-sub{color:var(--muted); font-size:12.5px; margin-bottom:18px;}

/* ===== 通用卡片/表格 ===== */
.card{background:var(--surface); border:1px solid var(--grid); border-radius:12px; padding:16px 18px;}
.grid{display:grid; gap:14px;}
/* 卡片数量会变（加了「本年已开票」就是 5 个），用自适应别写死 4 列 */
.tiles{grid-template-columns:repeat(auto-fit,minmax(210px,1fr));}
a.tile:hover{border-color:var(--brand);}
.tile .lbl{font-size:12.5px; color:var(--ink2); margin-bottom:6px;}
.tile .val{font-size:26px; font-weight:600;}
.tile .delta{font-size:12px; margin-top:4px;}
.up{color:var(--good-text);} .warn-t{color:#8a5b00;}
.row2{grid-template-columns:1.05fr .95fr; margin-top:14px;}
.row3{grid-template-columns:1fr 1fr; margin-top:14px;}
h3.blk{font-size:13.5px; margin-bottom:12px; color:var(--ink);}
table{width:100%; border-collapse:collapse; font-size:13px;}
th{color:var(--muted); font-weight:500; text-align:left; padding:8px 8px;
   border-bottom:1px solid var(--grid); white-space:nowrap; font-size:12.5px;}
td{padding:9px 8px; border-bottom:1px solid #f0efec; vertical-align:middle;}
/* 操作列：用 flex + gap 排，每两个按钮之间的间距完全一样
   （以前靠 .link 的 margin-right，遇到 form 包着的「删除」就对不齐了）。
   屏幕不够宽时自动折行 —— 宁可行高高一点，也不能有按钮被挤出屏幕点不到。 */
td:last-child{white-space:nowrap;}
.acts{display:flex; flex-wrap:wrap; align-items:center; gap:6px 14px;
  /* max-content：宽屏时把整格撑到"一行放得下"，不然表格布局会按最窄的一个按钮
     算这一列的宽度，几个按钮就被挤成竖着一列了 */
  min-width:max-content;}
.acts .link{margin-right:0; white-space:nowrap;}
.acts form{display:inline; margin:0;}
@media (max-width:1700px){
  td:last-child{white-space:normal;}
  .acts{min-width:132px;}     /* 窄屏放开，允许折成两行 */
}
/* 更窄的屏（笔记本 1280 / 1440，或者缩放到 125%）：把几个宽列再收一点，
   保证整张表还在屏幕里，最右边的「删除」不用横向拖也点得到。
   v1.34 加了「管理费」这一列，整张表更宽了，所以这个断点从 1400 提到 1600。 */
@media (max-width:1600px){
  td:last-child{min-width:96px;}
  td.wrap{min-width:150px;}
  td.wrap2{min-width:96px;}
  table{font-size:12.5px;}
  td{padding:8px 6px;}
  th{padding:8px 6px;}
  .acts{gap:4px 10px;}
}
/* 再窄一点（1366 的老笔记本）：项目名和甲方两列继续收 */
@media (max-width:1366px){
  td.wrap{min-width:130px;}
  td.wrap2{min-width:84px;}
  table{font-size:12px;}
  td{padding:7px 5px;}
  th{padding:7px 5px;}
}
/* 第一列常常是很长的工程名，让它换行、别撑宽表格 */
td:first-child{white-space:normal; word-break:break-word;}
/* 【最右边那一列（操作）钉住不动】：表格列多了以后（v1.34 又加了「管理费」），
   窄屏上整张表放不下，最右边的「查看 / 编辑 / 删除」就被挤出屏幕，
   得横着拖才点得到 —— 潘工原话：「这里排版在换行还是怎么样？又有点缩进去了」。
   现在它贴着右边固定，表格再宽也一直看得见；左边照样能横向拖着看。 */
.card > table td:last-child,
.card > table th:last-child{
  position:sticky; right:0; background:var(--surface,#fff); z-index:1;
  box-shadow:-8px 0 8px -8px rgba(0,0,0,.18);
}
/* 甲方 / 内包人那两个输入框的即时下拉（替代浏览器原生 datalist：
   原生的条目一多要按回车才筛、打四五个字还有延迟） */
.ac-list{display:none; position:absolute; z-index:30; margin-top:2px;
  background:var(--surface,#fff); border:1px solid var(--grid,#e3e6ea);
  border-radius:8px; box-shadow:0 6px 18px rgba(0,0,0,.10);
  max-height:260px; overflow:auto; min-width:260px; max-width:520px;}
.ac-list.on{display:block;}
.ac-item{padding:7px 12px; cursor:pointer; font-size:13px; white-space:nowrap;}
.ac-item:hover{background:#eef4ff;}
.field{position:relative;}
td.nw{white-space:nowrap;}          /* 合同编号这类不该折行的列 */
/* 工期「2026-07-25 ~ 2027-03-27」一行要 150px，屏幕不够时让它折成两行，
   省下来的宽度留给右边的「操作」—— 那几个按钮点不到才是真麻烦 */
td.dates{white-space:nowrap;}
@media (max-width:1700px){ td.dates{white-space:normal; min-width:96px;} }
/* 【内包人】一条台账可能挂着七八个人（企业库那种：邵连丰、金仁义、王绍凯…），
   不折行就是一行 400 多像素，整张表被撑得比屏幕还宽，右边的「状态」那一列
   直接顶到横向滚动条外面去，看着像整列消失
   （潘工原话：内包人这栏没换行，导致给隐藏到后面去了）。
   宽度封在 150px 里面折行 —— 上限写在里面那个 div 上，
   写在 td 上浏览器会当没看见（auto 布局的表格不认 td 的 max-width）。 */
td.persons{white-space:normal; word-break:break-word; min-width:64px;}
td.persons > div{max-width:150px;}
td.wrap{white-space:normal; word-break:break-word; min-width:220px;}
td.wrap2{white-space:normal; word-break:break-word; min-width:130px;}
/* 项目名可以很长，下拉不限宽会把整条筛选栏撑到换行 */
.toolbar select{max-width:220px;}
td:last-child form{display:inline;}
tr:hover td{background:#f7f7f4;}
td.num{font-variant-numeric:tabular-nums; text-align:right;}
th.num{text-align:right;}
.pill{display:inline-flex; align-items:center; gap:5px; padding:2px 9px; border-radius:20px;
  font-size:12px; white-space:nowrap;}
.pill::before{content:""; width:7px; height:7px; border-radius:50%; background:currentColor;}
.p-run{background:#e7f0fb; color:#1c5cab;}
.p-done{background:#e2f5ec; color:#0a6b4c;}
.p-wait{background:#fdeee6; color:#a04012;}
.p-over{background:#fbe7e7; color:#a02c2c;}
.p-void{background:#f2f2ef; color:#7a7873;}   /* 已作废：灰掉，跟"已完工"分清楚 */
/* 业务员单独一个紫色 —— 以前跟普通员工一样是橙的，一列看下来分不出谁是谁 */
.p-sales{background:#f0eaf9; color:#5b3a9e;}
.link{color:var(--brand-deep); cursor:pointer; text-decoration:none; margin-right:10px;
  font-size:12.5px; background:none; border:none; padding:0; font-family:inherit;}
.link:hover{text-decoration:underline;}
.link.danger{color:var(--crit);}
.toolbar{display:flex; gap:10px; margin-bottom:14px; flex-wrap:wrap; align-items:center;}
.toolbar input,.toolbar select{padding:8px 11px; border:1px solid var(--grid); border-radius:8px;
  font-size:13px; background:var(--surface); font-family:inherit;}
.toolbar input{width:220px;}
.btn{padding:8px 16px; border-radius:8px; border:1px solid var(--grid); background:var(--surface);
  cursor:pointer; font-size:13px; font-family:inherit; text-decoration:none; display:inline-block;
  color:var(--ink);}
.btn:hover{background:#f1f0ec;}
.btn.blue{background:var(--brand); border-color:var(--brand); color:#fff;}
.btn.blue:hover{background:var(--brand-deep);}
.btn.sm{padding:5px 11px; font-size:12.5px;}
.toolbar .spacer{flex:1;}
.empty{text-align:center; color:var(--muted); padding:34px 10px; font-size:13px;}

/* ===== 图表 ===== */
.chart-wrap{display:flex; gap:18px; align-items:center;}
.legend{font-size:12.5px; color:var(--ink2); display:flex; flex-direction:column; gap:8px;}
.legend .li{display:flex; align-items:center; gap:7px;}
.sw{width:10px; height:10px; border-radius:3px;}
.bars .brow{display:grid; grid-template-columns:130px 1fr 74px; align-items:center;
  gap:10px; margin-bottom:10px;}
.bars .bname{font-size:12.5px; color:var(--ink2); text-align:right; white-space:nowrap;
  overflow:hidden; text-overflow:ellipsis;}
.bars .btrack{height:18px; display:flex; align-items:center;}
.bars .bfill{height:18px; background:var(--s1); border-radius:0 4px 4px 0; min-width:3px;}
.bars .bval{font-size:12px; color:var(--ink2); font-variant-numeric:tabular-nums;}

/* 月度开票小柱子：12 根，哪个月开得多、哪个月断档一眼看得出 */
.mbars{display:flex; align-items:flex-end; gap:6px; height:92px;}
.mbars .mb{flex:1; display:flex; flex-direction:column; align-items:center; height:100%;}
/* 今年一根、去年一根，【并排】站着比 —— 叠在一起灰的会被蓝的盖住看不出来 */
.mbars .mb-track{flex:1; width:100%; display:flex; align-items:flex-end;
  justify-content:center; gap:3px;
  background:#f4f3ef; border-radius:4px 4px 0 0; padding:0 2px;}
.mbars .mb-fill{width:100%; background:var(--s1); border-radius:4px 4px 0 0; min-height:2px;}
.mbars .mb-fill.now{background:var(--s2);}
.mbars .mb-track.duo .mb-fill{width:56%;}
/* 去年同月：明显深一档的灰，还带斜纹，跟今年那根一眼分得开 */
.mbars .mb-last{width:40%; min-height:2px; border-radius:4px 4px 0 0;
  background:repeating-linear-gradient(45deg,#a9b0bd 0 3px,#c3c9d4 3px 6px);}
.mbars .mb-lbl{font-size:11px; color:var(--muted); margin-top:4px;}
.mbars .mb-lbl.now{color:var(--s2); font-weight:600;}

/* ===== 待办 ===== */
.todo-item{display:flex; align-items:flex-start; gap:10px; padding:10px 4px;
  border-bottom:1px solid #f0efec;}
.todo-item:last-child{border-bottom:none;}
.todo-item input[type=checkbox]{margin-top:3px; accent-color:var(--brand); cursor:pointer;}
/* 系统看得出办没办的自动提醒不给打勾框 —— 打勾只是把提醒藏起来，事还在那儿 */
.todo-lock{margin-top:1px; font-size:12px; opacity:.42; cursor:help; width:14px;
  display:inline-block; text-align:center; flex:none;}
.todo-item .btn{padding:3px 10px; font-size:12px; flex:none;}
.todo-main{flex:1;}
.todo-t{font-size:13.5px;}
.todo-m{font-size:12px; color:var(--muted); margin-top:2px;}
.tag{font-size:11px; padding:1px 7px; border-radius:4px; white-space:nowrap;}
.tag.due{background:#fbe7e7; color:#a02c2c;}
.tag.today{background:#fdf3dc; color:#8a5b00;}
.tag.week{background:#e7f0fb; color:#1c5cab;}
.tag.done{background:#e2f5ec; color:#0a6b4c;}
.tag.auto{background:#f1f0ec; color:#6d6b66;}
/* 「还缺哪一份合同」那种提示：只是说明手上有什么、没什么，
   不是要催人办事 —— 只签内包、只签分包本来就都正常，所以不用红的 */
.tag.lack{background:#f2f2ef; color:#6d6b66;}
.group-t{font-size:12.5px; color:var(--muted); margin:14px 0 4px; font-weight:600;}
.group-t:first-child{margin-top:0;}

/* ===== 抽屉 / 弹窗 ===== */
.drawer{position:fixed; top:0; right:-460px; width:440px; height:100vh; background:var(--surface);
  border-left:1px solid var(--grid); box-shadow:-12px 0 30px rgba(0,0,0,.08); z-index:40;
  transition:right .25s; padding:22px; overflow-y:auto;}
.drawer.open{right:0;}
.drawer h3{font-size:15px; margin-bottom:2px;}
.drawer .close{position:absolute; top:16px; right:16px; cursor:pointer; color:var(--muted);
  font-size:18px; border:none; background:none;}
.kv{display:grid; grid-template-columns:88px 1fr; gap:7px 10px; font-size:13px; margin:16px 0;}
.kv .k{color:var(--muted);}
.doc-item{display:flex; align-items:center; gap:9px; padding:9px 10px; border:1px solid var(--grid);
  border-radius:8px; margin-bottom:8px; font-size:13px;}
.doc-item .ico{font-size:16px;}
.doc-item .spacer{flex:1;}
.mask{position:fixed; inset:0; background:rgba(0,0,0,.18); z-index:30; display:none;}
.mask.on{display:block;}

.modal{position:fixed; inset:0; background:rgba(0,0,0,.28); z-index:50; display:none;
  align-items:flex-start; justify-content:center; padding:40px 16px; overflow-y:auto;}
.modal.on{display:flex;}
.modal-box{background:var(--surface); border-radius:14px; padding:22px 24px; width:560px;
  max-width:100%; box-shadow:0 24px 60px rgba(0,0,0,.22);}
.modal-box h3{font-size:15.5px; margin-bottom:14px;}
.form-grid{display:grid; grid-template-columns:1fr 1fr; gap:12px 14px;}
.form-grid .full{grid-column:1/-1;}
.modal-actions{display:flex; gap:10px; justify-content:flex-end; margin-top:18px;}

/* ===== 提示条 ===== */
.hint{background:#fdf3dc; border:1px solid #f2dfae; color:#6b4c00; border-radius:10px;
  padding:10px 14px; font-size:12.5px; margin-bottom:16px;}
.flash{border-radius:10px; padding:10px 14px; font-size:13px; margin-bottom:14px;}
.flash.ok{background:#e2f5ec; border:1px solid #b6e3ce; color:#0a6b4c;}
.flash.err{background:#fbe7e7; border:1px solid #f0c4c4; color:#a02c2c;}

/* ===== 合同填表页 ===== */
.fsec{margin-bottom:16px;}
.fsec > h3{font-size:13.5px; margin-bottom:12px; padding-bottom:8px;
  border-bottom:1px solid var(--grid);}
.fgrid{display:grid; grid-template-columns:repeat(3,1fr); gap:12px 16px;}
.fgrid .f-wide{grid-column:span 2;}
.fgrid .f-full{grid-column:1/-1;}
.chk{display:flex; align-items:center; gap:8px; font-size:13.5px; cursor:pointer;}
.chk input{accent-color:var(--brand); width:16px; height:16px;}
.sticky-actions{position:sticky; bottom:0; background:var(--surface);
  border-top:1px solid var(--grid); padding:12px 0; margin-top:18px;
  display:flex; gap:10px; justify-content:flex-end;}
.tip{font-size:12px; color:var(--muted); margin-top:4px;}

@media (max-width:1000px){
  .fgrid{grid-template-columns:repeat(2,1fr);}
}
@media (max-width:900px){
  .tiles{grid-template-columns:repeat(2,1fr);}
  .row2,.row3{grid-template-columns:1fr;}
  .side{width:56px;}
  .side .nav-item span.txt{display:none;}
  /* 窄屏侧边栏只剩图标，子项没图标、全缩成一条 —— 直接收起来，
     父项点进去照样到得了 */
  .side .nav-item.nav-sub{display:none;}
  .main{padding:14px;}
  .fgrid{grid-template-columns:1fr;}
  .form-grid{grid-template-columns:1fr;}
  .drawer{width:100%; right:-100%;}
}

/* ===== 工程搜索框（关联工程用） =====
   工程有几千个，原来那个下拉根本拉不动，改成打字搜。 */
.pk{position:relative;}
.pk-list{position:absolute; left:0; right:0; top:100%; z-index:60;
  background:#fff; border:1px solid var(--line); border-radius:8px;
  box-shadow:0 8px 24px rgba(0,0,0,.12); max-height:280px; overflow-y:auto;
  margin-top:4px; display:none;}
.pk-list.on{display:block;}
.pk-item{padding:7px 10px; cursor:pointer; font-size:13px; line-height:1.5;
  border-bottom:1px solid #f2f2ef;}
.pk-item:last-child{border-bottom:none;}
.pk-item:hover,.pk-item.sel{background:#f4f7ff;}
.pk-item .m{font-size:11.5px; color:var(--muted);}
.pk-none{padding:10px; color:var(--muted); font-size:12.5px;}
.pk-picked{margin-top:5px; font-size:12px; color:#1a7f37;}
.pk-picked b{color:var(--ink);}
/* 【辅助项选工程】的下拉。用 position:fixed 挂在 body 上，
   不受表格那个横向滚动条裁剪 —— 放在格子里会被裁掉、点不中
   （潘工原话：项目名称需要双击或是写入项目名称大概能进行选择筛选）*/
.axbox{position:fixed; z-index:300; background:#fff; min-width:280px;
  border:1px solid var(--line); border-radius:8px; display:none;
  box-shadow:0 10px 28px rgba(0,0,0,.16); max-height:300px; overflow-y:auto;}
.axbox.on{display:block;}
.axbox .ax{padding:7px 10px; cursor:pointer; font-size:13px; line-height:1.5;
  border-bottom:1px solid #f2f2ef;}
.axbox .ax:last-child{border-bottom:none;}
.axbox .ax:hover,.axbox .ax.sel{background:#f4f7ff;}
.axbox .ax .m{font-size:11.5px; color:var(--muted);}
.axbox .axnone{padding:10px; color:var(--muted); font-size:12.5px;}
