/* ==========================================================================
   论文管理系统 · 视觉样式 v3「墨绿沉稳」
   浅色克制风 + 墨绿主色；8pt 栅格；统一圆角与柔和阴影
   方案由雄哥 2026-10-03 从 4 套方案中选定（方案 B）
   ========================================================================== */

:root{
  --bg:#eef1f0; --bg-2:#e6ebe8;        /* 页面底色：浅灰绿，不再惨白 */
  --panel:#ffffff; --panel-2:#f6f9f8;
  --border:#d7e3df; --line:#e3ebe8;

  --text:#0f1c18; --text-2:#3b5049; --muted:#758984; --muted-2:#a5b6b1; --muted3:#c8d6d2;

  --brand:#0f766e; --brand-d:#0d5f59; --brand-dd:#0a4a45;
  --brand-l:#e2f2f0; --brand-l2:#c9e8e4;

  --red:#b91c1c;   --red-l:#fceaea;  --red-b:#f5cfcf;
  --blue:#0f766e;  --blue-l:#e2f2f0; --blue-b:#c9e8e4;
  --orange:#b45309;--orange-l:#fdf1e3;--orange-b:#f3ddbe;
  --green:#15803d; --green-l:#e7f6ec; --green-b:#c4e8d0;
  --purple:#7c5cff;

  /* ====== 状态语义色（雄哥 2026-10-06 定）======
     完成=绿、初稿=红、修改=蓝（用于数据总览的环形图与处理进度条）。
     --st-done / --st-draft 直接引用 --green / --red，深色模式自动跟随；
     只有"蓝"需要单独写深色版。
     ⚠️ 不要用 --blue —— 它在墨绿主题里其实是主色绿，改它会影响全站 pill。 */
  --st-done:var(--green);
  --st-draft:var(--red);
  --st-revise:#2563eb;

  --side-bg:#fbfdfc; --side-bg-2:#f4f9f7;   /* 侧栏改浅色（雄哥反馈黑底丑） */

  /* ====== 中性色补充变量（雄哥 2026-10-05 加）======
     🔴 整改前有一批**偏蓝的旧配色残留在墨绿主题里**：
       #c9d3e2(按钮悬停边框) #cfd8e6/#d3dae6/#bcc6d6(全站滚动条)
       #fbfcfc(输入框底) #f2f5f9/#f1f4f9(进度条底/分段控件底)
     ——灰里带蓝，放在墨绿界面里"说不上来哪里脏"，是"不精致"的隐形来源。
     现在统一成墨绿系的 3 个中性档，全部走变量。 */
  --neutral-1:#eef2f0;   /* 最浅：轨道/填充底（进度条、分段控件） */
  --neutral-2:#dbe4e0;   /* 中：滚动条、输入框底（原 #fbfcfc 的替代，略深更清晰） */
  --neutral-3:#b9c9c3;   /* 深：滚动条悬停、按钮悬停边框 */
  --side-text:#3b5049;

  --r-sm:7px; --r:10px; --r-lg:14px; --r-xl:20px;
  --shadow-xs:0 1px 2px rgba(16,24,40,.04);
  --shadow-sm:0 1px 3px rgba(16,24,40,.06),0 1px 2px rgba(16,24,40,.04);
  --shadow:0 2px 6px rgba(16,24,40,.06),0 4px 16px rgba(16,24,40,.05);
  --shadow-lg:0 12px 32px rgba(16,24,40,.10),0 4px 12px rgba(16,24,40,.06);
  --shadow-xl:0 24px 60px rgba(16,24,40,.16);
  --ring:0 0 0 3px rgba(15,118,110,.16);

  /* ====== 字号尺度（雄哥 2026-10-05 定）======
     🔴 整改前全站有 **24 种**字号（正文级就有 10/10.5/11/11.5/12/12.5/13/13.5/14/14.5/15/15.5
     12 种），相邻档只差 0.5px —— 肉眼分辨不出，但会让界面"说不上来哪里不一致"。
     现在收敛成 6 档，**新代码一律用变量，不再写死 px**。
     用途对照：
       --fs-xs   11px  微型标签（药丸、单位、脚注）
       --fs-sm   12px  辅助文字（副行参数、说明、次要标签）
       --fs-base 12.5px 正文默认（按钮、表头、普通文字）★最常用
       --fs-md   13px  强调正文（姓名、关键值、小标题）
       --fs-lg   14px  表格单元格内容
       --fs-xl   20px  大数字（统计卡）
       --fs-2xl  29px  页面主标题大数字
     字号与颜色无关，故**不设深色覆盖**（尺寸深浅一致）。 */
  --fs-xs:11px; --fs-sm:12px; --fs-base:12.5px; --fs-md:13px;
  --fs-lg:14px; --fs-xl:20px; --fs-2xl:29px;
}

/* ====== 深色模式（雄哥 2026-10-03 加）======
   只覆盖颜色类变量，布局与尺寸完全复用浅色那套，避免两套样式走样 */
html[data-theme="dark"]{
  --bg:#0d1412; --bg-2:#121a18;
  --panel:#161f1d; --panel-2:#1b2523;
  --border:#26332f; --line:#212d2a;

  --text:#e6f0ed; --text-2:#b6c9c3; --muted:#8ba39c; --muted-2:#6e8880; --muted3:#4d6660;

  --brand:#2fb3a0; --brand-d:#26a08e; --brand-dd:#8ad8cb;
  --brand-l:#122823; --brand-l2:#1a3a33;

  --red:#ff6b6b;   --red-l:#2a1618;  --red-b:#4a2226;
  --blue:#2fb3a0;  --blue-l:#122823; --blue-b:#1a3a33;
  --orange:#f0a13a;--orange-l:#2a2010;--orange-b:#4a3a1c;
  --green:#4ade80; --green-l:#0f2419; --green-b:#1d4030;

  --st-revise:#60a5fa;   /* 深色下的"修改蓝"：提亮保证对比度 */

  --side-bg:#111917; --side-bg-2:#0c1311;

  /* 中性色（深色版）：与浅色同语义，换成深底上的三档灰绿 */
  --neutral-1:#1e2a27;   /* 轨道/填充底 */
  --neutral-2:#2b3a36;   /* 滚动条、输入框底 */
  --neutral-3:#3d514b;   /* 悬停 */
  --side-text:#8ba39c;

  --shadow-xs:0 1px 2px rgba(0,0,0,.3);
  --shadow-sm:0 1px 3px rgba(0,0,0,.4),0 1px 2px rgba(0,0,0,.3);
  --shadow:0 2px 6px rgba(0,0,0,.4),0 4px 16px rgba(0,0,0,.3);
  --shadow-lg:0 12px 32px rgba(0,0,0,.5),0 4px 12px rgba(0,0,0,.35);
  --shadow-xl:0 24px 60px rgba(0,0,0,.6);
  --ring:0 0 0 3px rgba(77,141,255,.24);
}
/* 深色下几处硬编码白底要跟着改 */
html[data-theme="dark"] .table-wrap,
html[data-theme="dark"] .modal,
html[data-theme="dark"] .modal-h,
html[data-theme="dark"] .modal-f,
html[data-theme="dark"] .btn,
html[data-theme="dark"] .input,
html[data-theme="dark"] .select,
html[data-theme="dark"] textarea.input{background:var(--panel)}
/* 深色下输入框边框要用「亮一点的灰绿」，否则浅色的 #94a8a1 会太扎眼 */
html[data-theme="dark"] .input,
html[data-theme="dark"] .select,
html[data-theme="dark"] textarea.input{border-color:#3f5148;box-shadow:inset 0 1px 2px rgba(0,0,0,.25)}
html[data-theme="dark"] .input:hover,
html[data-theme="dark"] .select:hover,
html[data-theme="dark"] textarea.input:hover{border-color:#52685d}
html[data-theme="dark"] .modal,
html[data-theme="dark"] .modal-h,
html[data-theme="dark"] .modal-f{background:var(--panel)}
html[data-theme="dark"] .table-wrap{background:var(--panel)}
html[data-theme="dark"] table.grid tbody tr:hover{background:#1b2724}
html[data-theme="dark"] table.grid tr.row-soon{background:#241f12}
html[data-theme="dark"] table.grid tr.row-overdue{background:#241618}
/* 2026-10-03 补：表格改版后新增的表头/隔行/操作列色，深色模式必须一并覆盖，
   否则浅色底色（#eef5f3 等）会漏到深色界面里，表头发白发灰 */
html[data-theme="dark"] table.grid th{background:#1e2a27;color:#a9c4bd;border-bottom-color:#2c3b37}
html[data-theme="dark"] table.grid td{border-bottom-color:#33463f}
html[data-theme="dark"] table.grid tbody tr:nth-child(even){background:#1e2825}
html[data-theme="dark"] table.grid tbody tr:nth-child(even):hover{background:#1b2724}
html[data-theme="dark"] table.grid tfoot td{background:#1e2a27;border-top-color:#2c3b37}
html[data-theme="dark"] table.grid .ops-col{background:#161f1d;box-shadow:-6px 0 8px -6px rgba(0,0,0,.5)}
html[data-theme="dark"] table.grid thead .ops-col{background:#1e2a27}
html[data-theme="dark"] table.grid tbody tr:nth-child(even) .ops-col{background:#1e2825}
html[data-theme="dark"] table.grid tbody tr:hover .ops-col{background:#1b2724}
html[data-theme="dark"] table.grid tr.row-soon .ops-col{background:#241f12}
html[data-theme="dark"] table.grid tr.row-overdue .ops-col{background:#241618}
/* 两行式（grid-orders2）深色覆盖 —— 铁律：加了硬编码颜色必须补深色 */
html[data-theme="dark"] table.grid.grid-orders2 tr.row-sub td{border-bottom-color:#33463f}
html[data-theme="dark"] table.grid.grid-orders2 tbody tr:nth-child(4n+3) td,
html[data-theme="dark"] table.grid.grid-orders2 tbody tr:nth-child(4n+4){background:#1e2825}
html[data-theme="dark"] table.grid.grid-orders2 tbody tr:nth-child(4n+3):hover td,
html[data-theme="dark"] table.grid.grid-orders2 tbody tr:nth-child(4n+4):hover{background:#1b2724}
/* 拖文件区深色覆盖 */
html[data-theme="dark"] .drop-zone{background:var(--panel-2);border-color:var(--border)}
html[data-theme="dark"] .drop-zone:hover,
html[data-theme="dark"] .drop-zone.over{background:var(--brand-l);border-color:var(--brand)}
html[data-theme="dark"] .note-box code{background:rgba(47,179,160,.14);color:#7fd8c9}
/* 副行去底色后，深色下标签不再需要背景/边框，只调文字色；分隔点提亮否则看不见 */
html[data-theme="dark"] table.grid.grid-orders2 td.sub-cell .kv b{
  background:none;border:none;color:var(--muted)}
html[data-theme="dark"] table.grid.grid-orders2 td.sub-cell .kv + .kv::before{color:#4d6660}
html[data-theme="dark"] .topbar{background:rgba(22,31,29,.9)}
html[data-theme="dark"] .seg{background:#1b2523;border-color:var(--border)}
html[data-theme="dark"] .seg button.on{background:#243431;color:var(--brand)}
html[data-theme="dark"] .bar-track,
html[data-theme="dark"] .mini-track{background:#202c29}
html[data-theme="dark"] .avatar{background:linear-gradient(140deg,var(--brand),#14a08f);color:#06231f}
html[data-theme="dark"] .topbar .who{background:var(--panel);border-color:var(--border)}
html[data-theme="dark"] .table-wrap::-webkit-scrollbar-thumb{background:#39473f}
html[data-theme="dark"] .table-wrap::-webkit-scrollbar-track{background:#161f1d}

*{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%}
body{
  font-family:"Microsoft YaHei","PingFang SC","Helvetica Neue",-apple-system,Arial,sans-serif;
  background:var(--bg); color:var(--text); font-size:14px; line-height:1.6;
  -webkit-font-smoothing:antialiased; -moz-osx-font-smoothing:grayscale;
}
a{color:var(--brand);text-decoration:none}
button,input,select,textarea{font-family:inherit}
::selection{background:var(--brand-l2)}

*::-webkit-scrollbar{width:10px;height:10px}
*::-webkit-scrollbar-thumb{background:var(--neutral-2);border-radius:8px;border:2px solid transparent;background-clip:content-box}
*::-webkit-scrollbar-thumb:hover{background:var(--neutral-3);background-clip:content-box;border:2px solid transparent}
*::-webkit-scrollbar-track{background:transparent}

/* ===================== 登录页 =====================
   样式参照雄哥 2026-10-03 提供的参考图：左绿右白、纯色墨绿大块 + 同心圆纹理 */
.login-wrap{
  min-height:100vh;display:flex;align-items:stretch;justify-content:center;
  position:relative;overflow:hidden;background:#0d3b34;
}
/* 右下角同心圆纹理（用重复径向渐变模拟，无图片依赖） */
.login-wrap::before{
  content:"";position:absolute;right:-12%;bottom:-22%;width:760px;height:760px;
  pointer-events:none;border-radius:50%;opacity:.5;
  background:repeating-radial-gradient(circle at center,
    rgba(255,255,255,.045) 0 1px, transparent 1px 62px);
}
.login-shell{
  position:relative;z-index:1;width:100%;display:grid;
  grid-template-columns:1.06fr .94fr;
}
.login-intro{
  padding:46px 60px 34px;color:#eaf0fb;display:flex;flex-direction:column;
  min-width:0;position:relative;
}
.login-intro .li-top{display:flex;align-items:center;gap:12px}
.li-sysname{font-size:15.5px;font-weight:600;color:#f0f7f5;letter-spacing:.3px}
.login-badge{
  width:32px;height:32px;border-radius:9px;display:flex;align-items:center;justify-content:center;
  background:rgba(255,255,255,.13);border:1px solid rgba(255,255,255,.22);
  font-size:13px;font-weight:800;color:#fff;letter-spacing:.3px;text-transform:lowercase;flex:0 0 32px;
}
/* 大标题区：垂直居中偏上，跟参考图一致 */
.li-head{margin:auto 0;padding:30px 0}
.li-head h1{font-size:33px;font-weight:800;letter-spacing:1px;color:#fff;line-height:1.28}
.li-head h1.h2{margin-bottom:20px}
.login-intro .tagline{margin-top:16px;font-size:var(--fs-md);color:#9dc4bb;line-height:1.95;font-weight:400}
/* 三个数据 */
.li-stats{display:flex;gap:44px;margin-bottom:26px}
.li-stat b{display:block;font-size:25px;font-weight:800;color:#fff;line-height:1.1}
.li-stat span{display:block;font-size:12.5px;color:#8fb5ac;margin-top:5px}
.li-foot{font-size:var(--fs-xs);color:#5c867d;letter-spacing:1.2px;font-weight:500}

/* ===== ICP 备案号（雄哥 2026-10-13 加：监管要求）=====
   《互联网信息服务管理办法》要求：网站页面显著位置展示备案号，且**必须能点击**跳工信部。
   两处用：① 登录页（**白卡内部底部**）② 登录后首页底部。
   ⚠️ 登录页**不能**用"全宽 fixed 贴底" —— 登录页是「左深绿 + 右白」两栏，
      全宽文字正好压在两种背景的分界线上 → 一种颜色无法同时适配，
      右半截在白底上会"隐形"（雄哥 2026-10-13 截图发现，已改为放白卡内）。 */
.icp-foot{font-size:var(--fs-xs);color:var(--muted-2);text-align:center;
  padding:14px 10px 18px;line-height:1.9}
.icp-foot a{color:inherit;text-decoration:none}
.icp-foot a:hover{color:var(--brand);text-decoration:underline}
/* 登录页：贴在**白色卡片内部**底部（底色统一为白 → 文字用中灰，清楚且不抢眼）
   ⚠️ 用 `position:absolute` 而不是 `margin-top:auto`：
      `.login-card` 已有 `justify-content:center`（内容垂直居中），
      两者会打架 —— auto 边距在 center 布局下拿不到剩余空间，会失效（实测）。
      绝对定位**不受父容器布局方式影响**，最稳。 */
.icp-foot-card{position:absolute;left:0;right:0;bottom:0;
  padding:16px 10px 20px;color:var(--muted)}
/* 右侧白卡：内容限宽居中，避免宽屏下输入框拉得过长
   ⚠️ `position:relative` 是给卡内底部的备案号（`.icp-foot-card`）当定位锚点 ——
      少了它，绝对定位会跑到整页去（2026-10-13 加备案号时补上）。 */
.login-card{background:#fff;padding:0 72px 62px;display:flex;flex-direction:column;justify-content:center;
  align-items:center;position:relative}
/* ↑ 底部 padding 62px：给卡内底部的备案号（`.icp-foot-card`，绝对定位）**留出空间**，
   否则它会压在「登 录」按钮/错误提示上（2026-10-13 加备案号时一并处理）。 */
.login-card > *{width:100%;max-width:372px}
.login-card h2{font-size:22px;font-weight:700;letter-spacing:.3px;color:var(--text)}
.login-sub{font-size:12.5px;color:var(--muted);margin-top:7px}
#f{margin-top:28px;display:flex;flex-direction:column}
.lf-row{margin-bottom:22px}
.login-form-sp{margin-top:22px}
.field-l{display:block;font-size:12.5px;color:var(--text-2);font-weight:600;margin-bottom:8px}
.login-input{
  width:100%;height:48px;border:1.5px solid var(--border);border-radius:var(--r);
  padding:0 14px;outline:none;background:var(--panel-2);transition:.18s;font-size:14px;
}
.login-input:focus{border-color:var(--brand);background:#fff;box-shadow:var(--ring)}
/* 密码可见切换 */
.pw-wrap{position:relative}
.pw-wrap .login-input{padding-right:44px}
.pw-eye{
  position:absolute;right:6px;top:50%;transform:translateY(-50%);
  width:32px;height:32px;border:none;background:transparent;cursor:pointer;
  color:var(--muted-2);border-radius:7px;display:flex;align-items:center;justify-content:center;
  transition:.15s;padding:0;
}
.pw-eye:hover{color:var(--brand);background:var(--brand-l)}
.pw-eye.on{color:var(--brand)}
/* 验证码 */
.cap-wrap{display:flex;gap:10px;align-items:stretch}
.cap-wrap .login-input{flex:1;min-width:0;letter-spacing:3px;font-weight:600}
.cap-img{
  flex:0 0 132px;height:48px;padding:0;border:1.5px solid var(--border);border-radius:var(--r);
  background:#f2f5fa;cursor:pointer;overflow:hidden;display:flex;align-items:center;justify-content:center;
  transition:.15s;
}
.cap-img:hover{border-color:var(--brand);box-shadow:var(--ring)}
.cap-img svg{display:block;width:100%;height:100%}
.cap-loading{font-size:12px;color:var(--muted-2)}
/* 记住用户名 */
.lf-remember{
  display:flex;align-items:center;gap:8px;cursor:pointer;user-select:none;
  font-size:13px;color:var(--text-2);margin-bottom:20px;width:fit-content;
}
.lf-remember input{
  width:16px;height:16px;accent-color:var(--brand);cursor:pointer;margin:0;
}
.lf-remember:hover{color:var(--brand)}
/* 期限快捷按钮 */
.dl-wrap{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.dl-wrap .input{flex:1;min-width:150px}
.dl-quick{display:flex;gap:6px;flex-wrap:wrap}
.dl-btn{
  height:36px;padding:0 11px;border:1px solid var(--border);background:#fff;border-radius:var(--r-sm);
  font-size:12.5px;color:var(--text-2);cursor:pointer;transition:.15s;font-weight:500;white-space:nowrap;
}
.dl-btn:hover{border-color:var(--brand);color:var(--brand);background:var(--brand-l)}
.dl-btn:active{transform:translateY(1px)}
/* 弹窗内期限按钮跟输入框等高（42px），避免一大一小参差 */
.modal .dl-btn{height:42px;padding:0 14px;font-size:var(--fs-md)}
.modal .dl-quick{gap:8px}
.dl-btn.dl-clear{color:var(--muted-2)}
.dl-btn.dl-clear:hover{border-color:var(--neutral-3);color:var(--muted);background:var(--panel-2)}
.dl-hint{font-size:12px;color:var(--brand);margin-top:6px;min-height:16px;line-height:1.5}
/* 分页条 */
.pager{
  display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap;
  padding:14px 4px 2px;
}
.pager-info{font-size:12.5px;color:var(--muted)}
.pager-info b{color:var(--text);font-variant-numeric:tabular-nums}
.pager-btns{display:flex;align-items:center;gap:5px;flex-wrap:wrap}
.pg-num,.pg-nav{
  min-width:32px;height:32px;padding:0 9px;border:1px solid var(--border);background:#fff;
  border-radius:var(--r-sm);font-size:13px;color:var(--text-2);cursor:pointer;transition:.15s;
  font-variant-numeric:tabular-nums;font-weight:500;
}
.pg-num:hover:not(.on),.pg-nav:hover:not(:disabled){border-color:var(--brand);color:var(--brand);background:var(--brand-l)}
.pg-num.on{background:linear-gradient(135deg,#0f766e,#14a08f);border-color:transparent;color:#fff;font-weight:600;box-shadow:0 2px 8px rgba(15,118,110,.3)}
.pg-nav{padding:0 12px}
.pg-nav:disabled{opacity:.42;cursor:not-allowed}
.pg-gap{color:var(--muted-2);padding:0 3px;font-size:13px;user-select:none}
.pager-note{font-size:12.5px;color:var(--muted-2);padding:12px 4px 2px}
@media (max-width:820px){
  .pager{flex-direction:column;align-items:stretch;gap:10px}
  .pager-btns{justify-content:center}
}
/* 已登录提示条 */
.login-signed{
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  padding:11px 14px;margin-bottom:22px;border-radius:var(--r);
  background:var(--brand-l);border:1px solid var(--blue-b);
  font-size:12.5px;color:var(--brand-dd);
}
.login-signed span{flex:1;min-width:120px}
.login-signed b{font-weight:600}
.login-signed button{
  border:1px solid var(--blue-b);background:#fff;color:var(--brand);
  height:28px;padding:0 11px;border-radius:7px;font-size:12.5px;cursor:pointer;transition:.15s;font-weight:500;
}
.login-signed button:hover{background:var(--brand);color:#fff;border-color:var(--brand)}
.login-btn{
  width:100%;height:48px;margin-top:auto;border:none;border-radius:var(--r);
  background:linear-gradient(135deg,#0f766e,#14a08f);color:#fff;font-size:15px;font-weight:600;
  letter-spacing:3px;cursor:pointer;transition:.18s;box-shadow:0 7px 20px rgba(15,118,110,.32);
}
.login-btn:hover{background:linear-gradient(135deg,#0d5f59,#0f766e);box-shadow:0 10px 26px rgba(15,118,110,.4);transform:translateY(-1px)}
.login-btn:active{transform:none}
.login-btn:disabled{opacity:.62;cursor:not-allowed;transform:none;box-shadow:none}
.login-err{color:var(--red);font-size:13px;min-height:20px;margin-top:15px;text-align:center;font-weight:500}

/* ===================== 主框架 ===================== */
.layout{display:flex;min-height:100vh;max-width:100%;overflow-x:hidden}

.sidebar{
  width:236px;flex:0 0 236px;height:100vh;
  /* 🔴 关键修复（2026-10-03）：原来是 position:sticky，只粘到「自身高度」用完就跟着滚走；
     页面内容比一屏高时，往下拉会让整条侧栏滚出屏幕，左侧出现大片空白。
     改成 fixed 永远钉在左侧，主内容区用 margin-left 让位。 */
  position:fixed;left:0;top:0;bottom:0;z-index:60;
  background:linear-gradient(180deg,var(--side-bg) 0%,var(--side-bg-2) 100%);
  color:var(--side-text);display:flex;flex-direction:column;
  border-right:1px solid var(--line);
}
/* 主内容区为固定侧栏让出宽度（见 .main 定义） */

.brand{
  height:66px;display:flex;align-items:center;gap:11px;padding:0 20px;color:var(--text);
  font-size:15px;font-weight:700;letter-spacing:.3px;border-bottom:1px solid var(--line);
}
.brand .logo{
  width:30px;height:30px;border-radius:9px;flex:0 0 30px;
  background:linear-gradient(140deg,#0f766e,#14a08f);
  display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:700;color:#fff;
  box-shadow:0 4px 13px rgba(20,160,143,.35);
}
.nav{flex:1;padding:12px 10px;overflow-y:auto;overflow-x:hidden}
/* 侧栏分组标题（「业务」/「系统」）—— 雄哥 2026-10-04：原 11px 太小看不清，加大加粗 */
.nav .group{padding:18px 12px 8px;font-size:12.5px;color:var(--text-3, #758984);
  letter-spacing:1.2px;font-weight:700}
.nav a{
  display:flex;align-items:center;gap:11px;padding:10px 12px;border-radius:var(--r-sm);
  color:var(--side-text);font-size:var(--fs-md);font-weight:500;margin-bottom:2px;cursor:pointer;
  transition:background .16s,color .16s;position:relative;
}
.nav a .ic{width:19px;height:19px;display:inline-flex;align-items:center;justify-content:center;
  font-size:14px;opacity:.85;flex:0 0 19px}
/* 侧栏矢量图标（雄哥 2026-10-04）：stroke 用 currentColor，自动跟随文字颜色，
   悬停 / 选中时图标与文字一起变色 —— 比 emoji 精致、且与墨绿主色统一 */
.ic-svg{width:17px;height:17px;display:block;flex:0 0 17px}
.nav a:hover .ic-svg{stroke-width:1.9}
.nav a.active .ic-svg{stroke-width:2}
.nav a:hover{background:#eaf4f1;color:var(--text)}
/* 选中项：淡绿底 + 深绿字（雄哥反馈原来的黑色底+蓝色大块丑） */
.nav a.active{
  background:var(--brand-l);
  color:var(--brand-d);font-weight:700;
}
.nav a.active .ic{opacity:1}
.nav a.active::before{
  content:"";position:absolute;left:-10px;top:50%;transform:translateY(-50%);
  width:3px;height:18px;border-radius:0 3px 3px 0;background:var(--brand);
}
.side-foot{padding:14px 20px;border-top:1px solid var(--line);
  font-size:12px;color:var(--muted);line-height:1.6}
.side-foot b{color:var(--text-2);font-weight:600}

.main{flex:1;min-width:0;max-width:100%;display:flex;flex-direction:column;margin-left:236px}
.topbar{
  height:66px;display:flex;align-items:center;justify-content:space-between;padding:0 26px;
  background:rgba(255,255,255,.88);backdrop-filter:blur(12px);
  border-bottom:1px solid var(--border);position:sticky;top:0;z-index:20;
}
.topbar h2{font-size:17px;font-weight:600;letter-spacing:.3px}
.topbar .right{display:flex;align-items:center;gap:14px;font-size:13px;color:var(--muted)}
/* 顶部月份：与「用户胶囊」同一套风格（白底 + 细边框 + 圆角），两件呼应
   （雄哥 2026-10-04 定：原来灰色药丸跟旁边胶囊撞色） */
.topbar #ymTag{
  height:30px;padding:0 14px;border-radius:20px;
  background:var(--panel);border:1px solid var(--border);color:var(--text-2);
  font-size:12.5px;font-weight:600;box-shadow:var(--shadow-xs);
  display:inline-flex;align-items:center;
}
.topbar .who{display:flex;align-items:center;gap:9px;cursor:pointer;padding:4px 12px 4px 5px;
  border-radius:22px;border:1px solid var(--border);background:var(--panel);
  transition:.16s;box-shadow:var(--shadow-xs)}
.topbar .who:hover{border-color:var(--brand);box-shadow:0 3px 12px rgba(15,118,110,.13)}
.avatar{
  width:30px;height:30px;border-radius:50%;flex:0 0 30px;
  background:linear-gradient(140deg,var(--brand),#14a08f);color:#fff;
  display:flex;align-items:center;justify-content:center;font-weight:700;font-size:13px;
  box-shadow:0 2px 6px rgba(15,118,110,.30);
}
/* 用户胶囊里的名字 + 角色（上下两行，主次分明） */
.topbar .who-txt{display:flex;flex-direction:column;line-height:1.18;min-width:0}
.topbar .who-txt b{font-size:12.5px;font-weight:700;color:var(--text);white-space:nowrap}
.topbar .who-txt s{font-size:var(--fs-xs);color:var(--muted-2);text-decoration:none;white-space:nowrap}
.topbar .who-caret{color:var(--muted-2);font-size:var(--fs-xs);margin-left:1px}

/* ===================== 顶栏到期提醒（铃铛）=====================
   雄哥 2026-10-08 加。视觉语言**刻意跟右边「用户胶囊」保持一致**
   （同样的圆角、边框、悬停描边），让它看起来是顶栏的一部分。
   🔴 图标色用 `currentColor`，跟随主题变量 → 深色模式自动适配。 */
.bell-wrap{position:relative;display:inline-flex}
.bell{
  width:38px;height:38px;border-radius:50%;cursor:pointer;
  display:flex;align-items:center;justify-content:center;
  border:1px solid var(--border);background:var(--panel);color:var(--text-2);
  transition:.16s;box-shadow:var(--shadow-xs);position:relative;padding:0;
}
.bell:hover{border-color:var(--brand);color:var(--brand);box-shadow:0 3px 12px rgba(15,118,110,.13)}
/* 有提醒时铃铛本身也染成警示色，扫一眼就知道有事 */
.bell.has-alert{color:var(--red);border-color:var(--red-b)}
/* 右上角红点：有数字显示数字，只有 1~9 用数字、更多显示 9+ */
.bell-dot{
  position:absolute;top:-3px;right:-3px;min-width:17px;height:17px;
  padding:0 4px;border-radius:9px;background:var(--red);color:#fff;
  font-size:11px;font-weight:700;line-height:17px;text-align:center;
  border:2px solid var(--panel);box-sizing:content-box;
}
/* 下拉面板 */
.bell-panel{
  position:absolute;top:calc(100% + 9px);right:0;width:340px;max-height:420px;overflow:auto;
  background:var(--panel);border:1px solid var(--border);border-radius:var(--r);
  box-shadow:0 8px 28px rgba(15,40,36,.16);z-index:60;padding:6px 0;
}
.bell-panel .bp-head{
  padding:9px 14px 7px;font-size:var(--fs-xs);font-weight:700;color:var(--muted-2);
  letter-spacing:.4px;text-transform:none;
}
.bell-panel .bp-head .n{color:var(--red);margin-left:4px}
.bell-panel .bp-sep{height:1px;background:var(--line);margin:5px 0}
.bell-panel .bp-item{
  padding:8px 14px;cursor:pointer;display:flex;flex-direction:column;gap:3px;
  border-left:3px solid transparent;transition:.12s;
}
.bell-panel .bp-item:hover{background:var(--neutral-1)}
.bell-panel .bp-item.over{border-left-color:var(--red)}
.bell-panel .bp-item.soon{border-left-color:var(--orange)}
.bell-panel .bp-t{font-size:var(--fs-base);color:var(--text);font-weight:600;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bell-panel .bp-s{font-size:var(--fs-xs);color:var(--muted-2);display:flex;gap:8px;flex-wrap:wrap}
.bell-panel .bp-s .due-over{color:var(--red);font-weight:600}
.bell-panel .bp-s .due-soon{color:var(--orange);font-weight:600}
.bell-panel .bp-empty{padding:18px 14px;text-align:center;color:var(--muted-2);font-size:var(--fs-base)}
.bell-panel .bp-foot{
  padding:8px 14px 4px;border-top:1px solid var(--line);margin-top:5px;
  font-size:var(--fs-xs);color:var(--muted-2);text-align:center;
  display:flex;gap:8px;justify-content:center;align-items:center;
}
/* 底部小按钮（全部已读 / 已读记录）—— 走墨绿主色，扁平不抢戏 */
.bell-panel .bp-btn-allread,.bell-panel .bp-btn-reads,.bell-panel .bp-back{
  border:1px solid var(--border);background:var(--panel);color:var(--text-2);
  border-radius:var(--r-sm);padding:3px 10px;font-size:var(--fs-xs);cursor:pointer;
  transition:.14s;font-family:inherit;
}
.bell-panel .bp-btn-allread:hover,.bell-panel .bp-btn-reads:hover,.bell-panel .bp-back:hover{
  border-color:var(--brand);color:var(--brand);background:var(--brand-l);
}
.bell-panel .bp-back{float:right;margin-left:auto}
/* 每条右侧的「已读 / 撤销」小按钮：默认淡，悬停才明显，不干扰阅读 */
.bell-panel .bp-read{
  position:absolute;right:10px;top:50%;transform:translateY(-50%);
  border:1px solid transparent;background:transparent;color:var(--muted-2);
  border-radius:var(--r-sm);padding:2px 8px;font-size:var(--fs-xs);cursor:pointer;
  transition:.14s;font-family:inherit;opacity:0;
}
.bell-panel .bp-item:hover .bp-read{opacity:1;border-color:var(--border);background:var(--panel)}
.bell-panel .bp-read:hover{color:var(--brand);border-color:var(--brand);background:var(--brand-l)}
.bell-panel .bp-read[disabled]{opacity:.4;cursor:default}
/* 让「已读」按钮有地方站：条目右侧留出空间 */
.bell-panel .bp-item{position:relative;padding-right:62px}
.bell-panel .bp-unread{opacity:1;border-color:var(--border);background:var(--panel)}

/* ===================== 内容区 ===================== */
.content{padding:22px 26px 46px;flex:1;min-width:0;max-width:100%}

/* ===================== 卡片 =====================
   🔴⚠️ 这里踩过一个坑（雄哥 2026-10-05 两次反馈），务必理解清楚再动：

   ① 先用 `auto-fit + minmax(180px,1fr)`（"能塞几个塞几个"）→
      数据总览 7 个卡在 1440/1600px 只放得下 6 个，第 7 个掉到第二行孤零零。
   ② 于是改成 `repeat(7,1fr)`（固定 7 列）→ 总览好了，**但全站其他页被带坏**：
      订单/团队只有 4 个卡、收入/结算只有 3 个卡 —— **却按 7 列排**，
      于是只占前 3~4 格、右边空 500~940px，卡片全挤在左边。

   🔴 教训：`.cards` 是**全站共用**的，各页卡片数不同（7/4/4/3/3），
      所以**必须"按实际数量自适应铺满"**，绝不能写死列数。
      —— 这也再次印证：改共用样式必须**扫全部使用页**，只看一个页面必踩坑。

   采用 `auto-fit + minmax(150px,1fr)`：
     · 150px 足够小 → 7 个卡能塞进一行（7×150+6×12 = 1122px < 内容区）
     · `1fr` 上不封顶 → 3 个卡时自动摊成 3 个大卡铺满整行，右侧不留空
   实测（1440/1600/1920 三档 × 5 个页面，右空全部为 0、都 1 行、无溢出）：
     总览7卡177px / 订单4卡319px / 团队4卡319px / 收入3卡429px / 结算3卡429px @1600px
   ⚠️ 小屏保护：<=1400px 收到 146px 最小宽，避免每卡被压得太窄读不清。*/
.cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px;margin-bottom:18px}
.card{
  background:var(--panel);border:1px solid var(--border);border-radius:var(--r-lg);
  padding:16px 16px;box-shadow:var(--shadow-sm);position:relative;overflow:hidden;transition:.18s;
}
.card::after{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background:var(--brand-l2)}
.card:hover{box-shadow:var(--shadow);transform:translateY(-1px)}
.card .k{font-size:12.5px;color:var(--muted);font-weight:500}
.card .v{font-size:29px;font-weight:700;margin-top:6px;letter-spacing:-.5px;line-height:1.15;
  font-variant-numeric:tabular-nums}
.card .s{font-size:12px;color:var(--muted-2);margin-top:5px}
.card.warn::after{background:linear-gradient(180deg,#ffc861,#e08600)}
.card.warn .v{color:var(--orange)}
.card.danger::after{background:linear-gradient(180deg,#ff9b9b,#e5484d)}
.card.danger .v{color:var(--red)}
.card.ok::after{background:linear-gradient(180deg,#7fd8a5,#0f9d58)}
.card.ok .v{color:var(--green)}
.card.info::after{background:linear-gradient(180deg,#5cc0b2,#0f766e)}

/* ===================== 面板 ===================== */
.panel{
  background:var(--panel);border:1px solid var(--border);border-radius:var(--r-lg);
  box-shadow:var(--shadow-sm);margin-bottom:18px;overflow:hidden;
}
.panel-h{
  padding:15px 20px;border-bottom:1px solid var(--line);display:flex;
  align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;
}
.panel-h .t{font-size:15px;font-weight:600;letter-spacing:.2px;display:flex;align-items:center;gap:9px}
.panel-h .t::before{content:"";width:3px;height:14px;border-radius:2px;background:var(--brand)}
.panel-b{padding:18px 20px}

/* ===================== 按钮 ===================== */
.btn{
  height:36px;padding:0 15px;border-radius:var(--r-sm);border:1px solid var(--border);
  background:#fff;color:var(--text-2);cursor:pointer;font-size:13px;font-weight:500;
  transition:.16s;display:inline-flex;align-items:center;justify-content:center;gap:6px;white-space:nowrap;
}
.btn:hover{border-color:var(--neutral-3);background:var(--panel-2);color:var(--text)}
.btn:active{transform:translateY(1px)}
.btn.primary{
  background:linear-gradient(135deg,#0f766e,#14a08f);border-color:transparent;color:#fff;
  box-shadow:0 3px 11px rgba(15,118,110,.28);
}
.btn.primary:hover{background:linear-gradient(135deg,#0d5f59,#0f766e);color:#fff;
  box-shadow:0 5px 15px rgba(15,118,110,.36)}
.btn.danger{color:var(--red);border-color:var(--red-b)}
.btn.danger:hover{background:var(--red-l);border-color:#ffc2c2;color:var(--red)}
.btn.sm{height:30px;padding:0 11px;font-size:var(--fs-base);border-radius:var(--r-sm)}   /* 圆角 6→7px，与 .toolbar .btn 统一 */
.btn:disabled{opacity:.5;cursor:not-allowed;transform:none !important;box-shadow:none !important}
.btn.ghost{background:transparent;border-color:transparent;color:var(--brand);padding:0 7px;height:28px}
.btn.ghost:hover{background:var(--brand-l);border-color:transparent}

/* ===================== 表单控件 ===================== */
.toolbar{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-bottom:14px}
.toolbar .sp{flex:1}
/* ===== 面板头里的筛选栏整体收一档（雄哥 2026-10-04：太「胖」，要精致）=====
   注意：只收「面板头 / 工具栏」里的控件，**不动弹窗表单**（弹窗输入框保持 42px 好点）
   收紧幅度：高 36 → 31px、字号 13.5 → 12.5px、内边距与圆角同步微调 */
.panel-h .toolbar{gap:8px}
.panel-h .input,
.panel-h .select,
.panel-h .btn,
.toolbar .input,
.toolbar .select,
.toolbar .btn{height:31px;font-size:var(--fs-base);border-radius:var(--r-sm)}
.panel-h .input,
.panel-h .select,
.toolbar .input,
.toolbar .select{padding:0 10px}
.panel-h .btn,
.toolbar .btn{padding:0 12px}
/* 下拉箭头位置随高度上移，保持居中 */
.panel-h .select,
.toolbar .select{padding-right:30px;background-position:right 9px center}
/* 搜索框略宽，别缩得太窄（雄哥 2026-10-04：再加宽一点） */
.panel-h .input.search,
.toolbar .input.search{min-width:240px}
.field{display:flex;flex-direction:column;gap:5px}
.field label{font-size:12.5px;color:var(--text-2);font-weight:600}
.input,.select,textarea.input{
  /* 边框加深 + 淡灰底 + 内阴影：白底上也能一眼看出「这里可以填」
     （雄哥 2026-10-03 反馈「输入框太隐形」，两轮加深到此档） */
  height:36px;border:1.5px solid #94a8a1;border-radius:var(--r-sm);
  padding:0 11px;outline:none;background:var(--neutral-2);min-width:0;color:var(--text);
  transition:.16s;font-size:var(--fs-md);
  box-shadow:inset 0 1px 2px rgba(16,24,40,.05);
}
textarea.input{height:auto;padding:9px 11px;resize:vertical;line-height:1.6}
.input:hover,.select:hover,textarea.input:hover{border-color:#6f8a81}
.input:focus,.select:focus,textarea.input:focus{border-color:var(--brand);background:#fff;box-shadow:var(--ring),inset 0 1px 2px rgba(16,24,40,.04)}
.input::placeholder{color:var(--muted-2)}
.search{width:238px}
.select{appearance:none;padding-right:30px;
  background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 4.5L6 8l3.5-3.5' fill='none' stroke='%23667085' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 10px center;
}

/* ===================== 徽标 ===================== */
.pill{
  display:inline-flex;align-items:center;gap:5px;padding:3px 10px;border-radius:20px;
  font-size:12px;background:var(--neutral-1);color:var(--muted);border:1px solid transparent;font-weight:500;
}
.pill.blue{background:var(--blue-l);color:var(--brand);border-color:var(--blue-b)}
.pill.red{background:var(--red-l);color:var(--red);border-color:var(--red-b)}
.pill.orange{background:var(--orange-l);color:var(--orange);border-color:var(--orange-b)}
.pill.green{background:var(--green-l);color:var(--green);border-color:var(--green-b)}

/* 徽标横排容器（雄哥 2026-10-08 加，2026-10-08 二次修）。
   用途：一格里塞多个徽标时，让它们**横向排列、每个不折行**，装不下才换行。
   背景：用户权限页「身份」列原本用空格分隔徽标 → 窄列下被挤成两行
        （实证：「业绩：全公司」被折成「业绩：全 / 公司」）。
   演进：先改成 `.pill-stack`（竖排）→ 雄哥反馈"宽的宽窄的窄，不服帖" →
        改为**横排 + 允许换行**，并给身份列足够宽度（238px）让它一行放下。 */
.pill-stack{display:flex;flex-wrap:wrap;align-items:center;gap:4px 6px}
.pill-stack .pill{white-space:nowrap}

/* ===================== 表格 ===================== */
.table-wrap{
  overflow-x:auto;overflow-y:hidden;max-width:100%;-webkit-overflow-scrolling:touch;
  border:1px solid var(--line);border-radius:var(--r);background:#fff;
}
.table-wrap::-webkit-scrollbar{height:9px}
.table-wrap::-webkit-scrollbar-thumb{background:var(--neutral-2);border-radius:5px}
.table-wrap::-webkit-scrollbar-track{background:#f6f8fb}

table.grid{width:100%;border-collapse:separate;border-spacing:0;font-size:14px;min-width:1080px}
/* 表格对齐口径（雄哥 2026-10-03 定）：表头+文字/状态/数字 → 居中；
   只有「金额/大小」右对齐（对账时数位才对齐）。2026-10-03 晚雄哥再次确认保持居中 */
table.grid th{
  position:sticky;top:0;background:#eef5f3;text-align:center;font-weight:700;
  color:#2f4740;padding:14px 18px;border-bottom:2px solid #cfe0da;
  white-space:nowrap;z-index:2;font-size:12.5px;letter-spacing:.3px;
}
table.grid td{padding:15px 18px;border-bottom:1px solid #cfe0da;vertical-align:middle;text-align:center;line-height:1.5}
/* 隔行淡色（斑马纹）：长时间盯表不串行 —— 雄哥反馈「看着不舒服」的关键修复 */
/* 隔行淡色（斑马纹）：加深一档 —— 雄哥反馈「看过去全白、分不清行」 */
table.grid tbody tr:nth-child(even){background:#f1f7f5}
table.grid tbody tr{transition:background .13s}
/* 悬停高亮：明显到一眼能定位（原 #f8fafd 太浅，看不出） */
table.grid tbody tr:hover{background:#dff0ec}
table.grid tbody tr:last-child td{border-bottom:none}
table.grid tr.row-soon{background:#fffbf2}
table.grid tr.row-soon:hover{background:#ffefd0}
table.grid tr.row-overdue{background:#fffafa}
table.grid tr.row-overdue:hover{background:#ffe3e3}

/* 从顶栏铃铛点进来的那一条：整行加一圈醒目的环（雄哥 2026-10-08 加）。
   用途：跳过来后一眼看出"我刚才点的是哪条"，不用自己再找。
   2.4 秒后 JS 会移除 .row-focus-blink，避免一直闪。 */
table.grid tr.row-focus{box-shadow:inset 0 0 0 2px var(--brand);position:relative;z-index:1}
table.grid tr.row-focus-blink{animation:rowFocusBlink 1.2s ease-in-out 2}
@keyframes rowFocusBlink{
  0%,100%{box-shadow:inset 0 0 0 2px var(--brand)}
  50%{box-shadow:inset 0 0 0 3px var(--orange)}
}
html[data-theme="dark"] table.grid tr.row-focus{box-shadow:inset 0 0 0 2px var(--brand)}
html[data-theme="dark"] table.grid tr.row-focus-blink{animation:rowFocusBlinkDark 1.2s ease-in-out 2}
@keyframes rowFocusBlinkDark{
  0%,100%{box-shadow:inset 0 0 0 2px var(--brand)}
  50%{box-shadow:inset 0 0 0 3px var(--orange)}
}
table.grid tr.row-done td{color:var(--muted-2)}
/* 金额类：右对齐 + 等宽数字，方便逐位对账 */
table.grid .num{text-align:right;font-variant-numeric:tabular-nums;font-weight:600;color:var(--text)}
table.grid .nowrap{white-space:nowrap}
/* 操作列固定在右侧：表格横向滚动时「编辑/删除」始终可见，不用滑到最右才能点 */
table.grid .ops-col{position:sticky;right:0;background:inherit;box-shadow:-6px 0 8px -6px rgba(16,24,40,.09);z-index:1}
table.grid tbody tr:nth-child(even) .ops-col{background:#f1f7f5}
table.grid thead .ops-col{background:#eef5f3;z-index:3}
table.grid tbody tr:hover .ops-col{background:#dff0ec}
table.grid tr.row-soon .ops-col{background:#fffbf2}
table.grid tr.row-overdue .ops-col{background:#fffafa}
table.grid tfoot td{background:#eef5f3;font-weight:700;border-top:2px solid #cfe0da}

/* ---- 订单表：列宽固定，内容超长省略号（不撑破屏幕，操作列永远可见）----
   雄哥 2026-10-03 反馈「操作列被切一半」——根因是表格无列宽约束、被长文本撑宽。
   用 table-layout:fixed + 逐列百分比，表宽恒等于容器宽，永不横向溢出。 */
table.grid.grid-orders{table-layout:fixed;min-width:0}
table.grid.grid-orders th,
table.grid.grid-orders td{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding-left:12px;padding-right:12px}
/* 列宽（操作列固定像素宽，保证「编辑/删除」放得下；其余按百分比分配）
   🔴 百分比必须加起来 ≈ 100%（雄哥 2026-10-05 定）：
      原来 11+15+26+9+13+11 = 85%，剩 15% "没人认领" →
      浏览器会把富余宽度**按比例分给每一列** → 操作列被撑宽（1920px 下 104 → 146px），
      居中后按钮两侧各空 34px，看起来"操作后面一片空白"。
      改法：把题目列 26% → 40%（吃掉那 15%），操作列就恒为 104px 了。
      实测（操作列宽 / 按钮距左）：1000px 104/13、1400px 104/13、1920px 104/13 ✅ */
table.grid.grid-orders th:nth-child(1){width:40px}    /* 勾选框（固定）*/
table.grid.grid-orders th:nth-child(2){width:13%}    /* 姓名（可能要放「结转」标签）*/
table.grid.grid-orders th:nth-child(3){width:18%}    /* 学校 */
table.grid.grid-orders th:nth-child(4){width:40%}    /* 题目（最宽，吸收富余宽度，保证操作列不被撑宽）*/
table.grid.grid-orders th:nth-child(5){width:92px}   /* 状态（**固定宽**：药丸 59px + 内边距 24px。
                                                        原 9% 在窄窗口被挤到 67px → 药丸出省略号「…」。 */
table.grid.grid-orders th:nth-child(6){width:16%}    /* 期限（竖排：日期 + 提醒药丸）*/
table.grid.grid-orders th:nth-child(7){width:13%}    /* 团队（代理）*/
table.grid.grid-orders th:nth-child(8){width:104px}  /* 操作（固定：刚好放下「编辑+删除」= 78px 按钮 + 24px 内边距 + 余量）
                                                        雄哥 2026-10-05 定：原 124px 太宽，居中后右侧空出 23px
                                                        视觉上像"操作后面一片空白"。收窄到 104px 消除空档。 */
/* ===== 两行式（雄哥 2026-10-04 定）=====
   主行 = 姓名 / 学校 / 题目 / 状态 / 期限 / 团队 / 操作
   副行 = 专业 / 类型 / 成交 / 老师 / 备注（小字铺满整行）
   目的：12 项信息全保留、全看得清，窄屏也不用横滑、不用点开。 */
table.grid.grid-orders2{min-width:0}
/* 主行上边线；副行下边线 —— 两条合起来框住一条订单 */
table.grid.grid-orders2 tr.row-main td{border-bottom:none;padding-top:11px;padding-bottom:3px}
table.grid.grid-orders2 tr.row-sub td{border-bottom:1px solid #cfe0da;padding-top:2px;padding-bottom:11px}
table.grid.grid-orders2 tr.row-sub:hover td{background:#e3eefd}
/* 勾选列（批量删除用，雄哥 2026-10-04）：窄、居中、跨两行 */
table.grid.grid-orders2 th.c-check,
table.grid.grid-orders2 td.c-check{width:40px;text-align:center;vertical-align:middle;padding-left:6px;padding-right:6px}
table.grid.grid-orders2 td.c-check input[type="checkbox"],
table.grid.grid-orders2 th.c-check input[type="checkbox"]{
  width:15px;height:15px;cursor:pointer;accent-color:var(--brand);vertical-align:middle}
/* 主行里的姓名：加粗、不截断（宁可行内折行） */
table.grid.grid-orders2 td.c-name{font-weight:700;color:var(--text-2);vertical-align:middle;
  white-space:nowrap}
/* 主行末列「老师」（雄哥 2026-10-04 定：老师提到主行，团队挪到副行）：
   单人一行；合作单把两位老师**上下两行**排开 + 右侧小标签，省宽度又看得全。 */
table.grid.grid-orders2 th.c-teacher,
table.grid.grid-orders2 td.c-teacher{width:150px;vertical-align:middle;white-space:nowrap;
  overflow:hidden;text-align:left}     /* 表头 + 内容都左对齐（雄哥 2026-10-05 定，见下方说明） */
/* 合作单：两位老师竖排时，「合作」标签**对齐第一行名字**（雄哥 2026-10-05 定）。
   🔴 原来是 align-items:center —— 标签跟「两行名字的整体」居中，会落在两行的分界线上
   （实测比第一行名字中线低 9.4px），看起来"飘在中间、没对齐"。
   改 flex-start 后标签紧跟第一行（实测偏差 0.8px），读作「丁工（合作）/ 小凡」，
   相当于给第一位老师做注释，符合阅读习惯。 */
table.grid.grid-orders2 td.c-teacher .tp-wrap{display:inline-flex;align-items:flex-start;gap:6px}
table.grid.grid-orders2 td.c-teacher .tp-names{display:inline-flex;flex-direction:column;
  line-height:1.5;font-size:12.5px}
table.grid.grid-orders2 td.c-teacher .pill{font-size:var(--fs-xs);padding:1px 6px;flex:0 0 auto;margin-top:1px}
/* 结算表里的姓名（主行/子行通用），与订单表观感一致 */
.nm-strong{font-weight:700;color:var(--text-2)}
/* 副行：小字参数，左对齐、字距舒展
   🔴 雄哥 2026-10-05：11.5px → **12px（--fs-sm）** —— 原值比结算页副行(12px)小半档，
   同一种"副行"在两个页面字号不同 = 不精致。统一到 12px。 */
table.grid.grid-orders2 td.sub-cell{text-align:left;font-size:var(--fs-sm);color:var(--muted);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* 副行的每一项：`专业 机器人技术`。
   —— 雄哥 2026-10-04 二次调整：原来每项套一个浅灰底小标签，五项挤一起像一团、很乱。
      改为**去掉底色**，只留「浅灰项目名 + 正常内容」，项与项之间用淡圆点「·」分隔，清爽一眼扫过。 */
table.grid.grid-orders2 td.sub-cell .kv{display:inline-flex;align-items:baseline;
  white-space:nowrap;max-width:100%}
table.grid.grid-orders2 td.sub-cell .kv + .kv::before{
  content:"·";color:#c3d2cd;margin:0 9px;font-weight:700;flex:0 0 auto}
table.grid.grid-orders2 td.sub-cell .kv b{
  color:var(--muted-2);font-weight:600;margin-right:5px;
  background:none;border:none;padding:0;font-size:var(--fs-xs);letter-spacing:.2px;
  flex:0 0 auto;
}
/* 备注最长，超出用省略号（不挤走前面的项）
   🔴 雄哥 2026-10-05 定「乙」：**备注固定最多约 8 个字**，超出打省略号（悬浮看全文）。
   原因：备注是自由文本、可以很长（如「只交了30%定金学生补款」），
   跟前面 4 个固定字段不是一类；不截断时**有备注的行明显比无备注的行长一大截**，
   上下行长短参差 = 看着乱。
   8 个字 = 8em（`b` 标签另占位，故上限设 9em 留出「备注」二字 + 一点余量）。
   ⚠️ 省略号必须作用在 `.kv-val`（值的那层 span）上 ——
   `.kv` 是 inline-flex，`text-overflow` 对 flex 容器的直接文本节点**不生效**。*/
table.grid.grid-orders2 td.sub-cell .kv-remark{overflow:hidden;min-width:0;max-width:9em}
table.grid.grid-orders2 td.sub-cell .kv-remark .kv-val{display:block;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap;min-width:0}
/* 隔行淡色：每「两行」一组 */
table.grid.grid-orders2 tbody tr:nth-child(4n+3) td,
table.grid.grid-orders2 tbody tr:nth-child(4n+4){background:#f1f7f5}
table.grid.grid-orders2 tbody tr:nth-child(4n+3):hover td,
table.grid.grid-orders2 tbody tr:nth-child(4n+4):hover{background:#e3eefd}
/* 期限列：日期在上、提醒药丸在下 */
table.grid.grid-orders2 td.dl-cell{padding-top:8px;padding-bottom:8px;line-height:1.35}
table.grid.grid-orders2 td.dl-cell .dl-date{display:block;font-weight:600;
  font-variant-numeric:tabular-nums;letter-spacing:.2px;white-space:nowrap}
table.grid.grid-orders2 td.dl-cell .pill{margin-top:3px;font-size:var(--fs-xs);padding:1px 8px}
/* 操作列：跨两行、垂直居中 */
table.grid.grid-orders2 td.ops-col,
table.grid.grid-orders2 th.ops-col{text-align:center;vertical-align:middle}
table.grid.grid-orders2 td.ops-col .btn.ghost{padding:0 6px;height:26px;font-size:12.5px}
/* 旧一行式定义保留（万一要回退），但当前不用 */

/* ===================== 日期选择控件（成交日期用，雄哥 2026-10-04 定稿） =====================
   自制月历弹层：不用 <input type="date"> 的原生面板 —— 各浏览器样式不一、跟墨绿风格不统一，
   且底部没有「清除 / 今天」。这里全部自己画，样式与系统一致。 */
.dd-box{position:relative}
.dd-trigger{
  width:100%;height:36px;display:flex;align-items:center;justify-content:space-between;gap:8px;
  border:1.5px solid #94a8a1;border-radius:var(--r-sm);background:var(--neutral-2);
  padding:0 10px 0 11px;cursor:pointer;font-size:var(--fs-md);color:var(--text);
  transition:.16s;box-shadow:inset 0 1px 2px rgba(16,24,40,.05);text-align:left;
  outline:none;   /* 去掉 button 默认的聚焦圈（否则点开时输入框上会浮一个灰圆） */
  -webkit-tap-highlight-color:transparent;
}
.dd-trigger:focus-visible{border-color:var(--brand)}
.dd-trigger:hover{border-color:#6f8a81}
/* 打开状态：边框变墨绿即可（不加外圈光环 —— 光环跟输入框的聚焦环撞在一起像"双圈"，
   在这个只有 36px 高的控件上有点抢眼）。 */
.dd-trigger.on{border:1.5px solid var(--brand);background:#fff}
.dd-trigger .dd-text{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* ⚠️ 类名必须用 `dd-empty`，不能用 `empty` —— 全站已有 `.empty`（空列表提示，
   带 56px 虚线圆圈 ::before），撞名会让日期文字旁边冒出一个虚线圆圈并把高度撑高。
   （雄哥 2026-10-04 截图里那个"灰圈"就是这个撞名造成的） */
.dd-trigger .dd-text.dd-empty{color:var(--muted-2)}
.dd-trigger .dd-ico{flex:0 0 auto;width:16px;height:16px;color:var(--muted);display:inline-flex}
.dd-trigger .dd-ico svg{width:16px;height:16px}
.dd-trigger.on .dd-ico{color:var(--brand)}

/* ---- 月历面板 ---- */
.cal-panel{
  position:absolute;z-index:80;top:calc(100% + 8px);left:0;width:266px;
  background:#fff;border:1px solid var(--border);border-radius:12px;
  box-shadow:var(--shadow-lg);padding:10px 12px 8px;user-select:none;
}
.cal-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:6px}
.cal-title{
  border:none;background:none;cursor:pointer;font-size:var(--fs-md);font-weight:700;color:var(--text);
  padding:4px 6px;border-radius:7px;display:inline-flex;align-items:center;gap:3px;
}
.cal-title:hover{background:var(--brand-l)}
.cal-title i{font-style:normal;font-size:var(--fs-xs);color:var(--muted)}
.cal-nav{display:flex;gap:2px}
.cal-arrow{
  width:26px;height:26px;border:none;background:none;cursor:pointer;border-radius:7px;
  color:var(--muted);font-size:14px;line-height:1;display:inline-flex;align-items:center;justify-content:center;
}
.cal-arrow:hover{background:var(--brand-l);color:var(--brand)}
/* 星期表头 */
.cal-week{display:grid;grid-template-columns:repeat(7,1fr);margin-bottom:3px}
.cal-week span{text-align:center;font-size:var(--fs-xs);color:var(--muted-2);padding:3px 0}
/* 日期格子 */
.cal-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:1px}
.cal-cell{
  height:31px;border:none;background:none;cursor:pointer;border-radius:8px;
  font-size:12.5px;color:var(--text);font-variant-numeric:tabular-nums;
  display:flex;align-items:center;justify-content:center;transition:.12s;
}
.cal-cell:hover{background:var(--brand-l)}
.cal-cell.out{color:#c3d2cd}                 /* 上/下月的日期：淡灰 */
/* 今天：淡墨绿底 + 墨绿字（未选中时）；与"已选中"（实心墨绿）明确区分 */
.cal-cell.today{background:var(--brand-l);color:var(--brand-d);font-weight:700}
.cal-cell.today:hover{background:var(--brand-l2)}
.cal-cell.sel{background:var(--brand);color:#fff;font-weight:700}   /* 选中：墨绿实心 */
.cal-cell.sel:hover{background:var(--brand-d)}
/* 「今天」同时又被选中 → 以选中为准（实心墨绿），别被 today 的淡底压回去 */
.cal-cell.today.sel,
.cal-cell.today.sel:hover{background:var(--brand);color:#fff}
/* 底部：清除 / 今天 */
.cal-foot{display:flex;align-items:center;justify-content:space-between;
  border-top:1px solid var(--line);margin-top:7px;padding-top:6px}
.cal-link{border:none;background:none;cursor:pointer;font-size:12.5px;color:var(--brand);
  padding:4px 6px;border-radius:6px}
.cal-link:hover{background:var(--brand-l)}
/* 年 / 月快选 */
.cal-picker{display:flex;gap:6px;height:196px}
.cal-pick-col{flex:1;overflow:auto;display:flex;flex-direction:column;gap:1px}
.cal-pick{border:none;background:none;cursor:pointer;text-align:center;padding:5px 0;
  border-radius:6px;font-size:12.5px;color:var(--text)}
.cal-pick:hover{background:var(--brand-l)}
.cal-pick.on{background:var(--brand);color:#fff;font-weight:600}
/* 深色覆盖（铁律：加了硬编码颜色必须补深色） */
html[data-theme="dark"] .dd-trigger{background:var(--panel);border-color:#3f5148;box-shadow:inset 0 1px 2px rgba(0,0,0,.25)}
html[data-theme="dark"] .dd-trigger:hover{border-color:#52685d}
html[data-theme="dark"] .dd-trigger.on{border:1.5px solid var(--brand);background:var(--panel)}
html[data-theme="dark"] .cal-panel{background:#182220;border-color:var(--border);box-shadow:var(--shadow-lg)}
html[data-theme="dark"] .cal-cell.out{color:#4d6660}
html[data-theme="dark"] .cal-title:hover,
html[data-theme="dark"] .cal-arrow:hover,
html[data-theme="dark"] .cal-cell:hover,
html[data-theme="dark"] .cal-link:hover,
html[data-theme="dark"] .cal-pick:hover{background:var(--brand-l2)}
html[data-theme="dark"] .cal-cell.sel{background:var(--brand);color:#06231f}
html[data-theme="dark"] .cal-cell.today{background:var(--brand-l2);color:var(--brand-dd)}
html[data-theme="dark"] .cal-cell.today.sel,
html[data-theme="dark"] .cal-cell.today.sel:hover{background:var(--brand);color:#06231f}
/* 手机端：面板宽度收窄，避免超出屏幕 */
@media (max-width:640px){.cal-panel{width:min(266px,calc(100vw - 56px))}}

/* ---- 结算表：合作单分成「主行 + 每人一行」（雄哥 2026-10-04 定）----
   主行只代表"这一单"，浅底 + 粗姓名校；子行缩进加 └，金额填在子行上。 */
table.grid.grid-settle tr.settle-main td{background:#f2f8f6;border-bottom:none;padding-top:12px;padding-bottom:6px}
table.grid.grid-settle tr.settle-main td:nth-child(2){border-left:3px solid var(--brand)}
/* 主行的勾选格：放一个「合」字印章，明确这行不可勾选（留白会让人以为漏了） */
table.grid.grid-settle td.m-main-mark{text-align:center;vertical-align:middle;color:var(--brand);
  font-size:0}
table.grid.grid-settle td.m-main-mark::before{
  content:"合";font-size:var(--fs-xs);font-weight:700;
  display:inline-flex;align-items:center;justify-content:center;
  width:20px;height:20px;border-radius:5px;background:var(--brand-l);border:1px solid var(--brand-l2)}
table.grid.grid-settle tr.settle-sub td{background:#fff;padding-top:6px;padding-bottom:6px}
table.grid.grid-settle tr.settle-sub td:nth-child(2){padding-left:22px}
table.grid.grid-settle tr.settle-sub .sub-line{color:var(--muted-2);font-weight:400}
/* 🔴 子行的学生名淡化（雄哥 2026-10-05）：
   合作单主行显示一次学生名，下面两位老师各一行**又各显示一次**，
   三行同样醒目 → 第一眼像有 3 个学生。把子行的名字降级为"次要信息"
   （灰色、常规字重、小一号），层次立刻清楚：主行=这一单，子行=谁分多少钱。
   ⚠️ 2026-10-05 二次微调：第一版用了 var(--muted) 偏淡、几乎看不清，
   改用 --text-2 提高一档（仍明显弱于主行，但一眼能认出是"哪个学生的分账"）。
   同时子行的学校/专业已由 JS 置空（它们是这一单的属性，不属于子行）。 */
table.grid.grid-settle tr.settle-sub td:nth-child(2) .sub-name{
  color:var(--text-2);font-weight:400;font-size:var(--fs-sm);opacity:.72}
table.grid.grid-settle tr.settle-sub:last-child td{border-bottom:1px solid #cfe0da;padding-bottom:12px}
table.grid.grid-settle tr.settle-main:hover td{background:#e9f4f1}
table.grid.grid-settle tr.settle-sub:hover td{background:#e3eefd}
table.grid.grid-settle td .btn.ghost{padding:0 7px;height:26px;font-size:var(--fs-base)}
html[data-theme="dark"] table.grid.grid-settle tr.settle-main td{background:#1e2a27}
html[data-theme="dark"] table.grid.grid-settle tr.settle-main:hover td{background:#1b2724}
html[data-theme="dark"] table.grid.grid-settle tr.settle-sub td{background:var(--panel)}
html[data-theme="dark"] table.grid.grid-settle tr.settle-sub:hover td{background:#1b2724}
html[data-theme="dark"] table.grid.grid-settle tr.settle-sub:last-child td{border-bottom-color:#33463f}
html[data-theme="dark"] table.grid.grid-settle tr.settle-main td:nth-child(2){border-left-color:var(--brand)}
html[data-theme="dark"] table.grid.grid-settle td.m-main-mark::before{background:var(--brand-l);border-color:var(--brand-l2)}

/* ---- 操作日志表：同样固定列宽（雄哥 2026-10-03 反馈「右边空一大片、跟菜单栏脱节」）----
   原来该表 min-width:900px 且「内容」列不限宽 → 长内容把表撑超宽、右侧留白。
   改成 table-layout:fixed + 内容列省略号，表宽恒等于容器。 */
table.grid.grid-logs{table-layout:fixed;min-width:0}
table.grid.grid-logs th,
table.grid.grid-logs td{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding-left:14px;padding-right:14px}
table.grid.grid-logs th:nth-child(1){width:172px}   /* 时间（够放 2026-10-03 23:22:17）*/
table.grid.grid-logs th:nth-child(2){width:96px}    /* 操作人 */
table.grid.grid-logs th:nth-child(3){width:72px}    /* 模块 */
table.grid.grid-logs th:nth-child(4){width:72px}    /* 动作 */
table.grid.grid-logs th:nth-child(5){width:22%}     /* 对象 */
table.grid.grid-logs th:nth-child(6){width:auto}    /* 内容（占满剩余） */
/* 日志行内容较矮，收紧行高，避免一屏看不到几条（雄哥 2026-10-03 反馈） */
table.grid.grid-logs td{padding-top:12px;padding-bottom:12px}

/* ---- 汇总小表（如结算「按老师汇总」）：3 列没必要拉很开 ----
   雄哥 2026-10-03 反馈「三列拉得很开、中间空」。去掉过大的 min-width，按内容分配列宽。 */
table.grid.grid-sum{min-width:0}
table.grid.grid-sum th:nth-child(1){width:40%}
table.grid.grid-sum th:nth-child(2){width:24%}
table.grid.grid-sum th:nth-child(3){width:36%}

/* ---- 日志页筛选栏：控件多，窄屏会乱换行 → 专门紧凑化 ---- */
.log-filter{gap:8px;margin:0}
.log-filter .input.search{width:190px;height:34px}
.log-filter .select{height:34px;font-size:13px;min-width:106px}
.log-filter .input[type="date"]{width:132px;height:34px;font-size:13px}
.log-filter .btn{height:34px;padding:0 13px;font-size:var(--fs-base)}   /* 原 13.5px —— 全站按钮统一 12.5px */
.log-filter .muted{font-size:12px}
@media (max-width:1100px){
  /* 更窄时就并成两行整齐排，不再参差 */
  .log-filter{width:100%}
  .log-filter .input.search{width:100%;flex:1 1 100%}
  .log-filter .select{flex:1 1 140px;min-width:120px}
  .log-filter .input[type="date"]{flex:1 1 130px;width:auto}
}

.dot{display:inline-block;width:7px;height:7px;border-radius:50%;margin-right:7px;vertical-align:middle}
/* 订单状态配色（雄哥 2026-10-03 更新：改成彩色药丸，一眼分辨）
   初稿 = 灰（未开始）；修改 = 主色墨绿（进行中）；完成 = 绿
   ※ 早先版本是「只变文字色、初稿连点都隐藏」，雄哥反馈整列看着没颜色，故改为色块。 */
.st-draft,.st-revise,.st-done{
  display:inline-flex;align-items:center;gap:6px;
  padding:3px 11px;border-radius:20px;font-size:12.5px;font-weight:600;line-height:1.7;
}
.st-draft{background:var(--neutral-1);color:#64756f}   /* 原 #eef1f4/#5b6879 是**蓝灰**，在墨绿主题里显脏 → 改墨绿灰 */
.st-draft .dot{display:inline-block;background:var(--neutral-3)}  /* 原 #98a2b3 偏蓝 */
.st-revise{background:var(--brand-l);color:var(--brand-d)}
.st-revise .dot{background:var(--brand)}
/* 深色模式下初稿状态的文字色（浅色是 #64756f，深底上要提亮） */
html[data-theme="dark"] .st-draft{color:#9fb0ab}
.st-done{background:var(--green-l);color:var(--green)}
.st-done .dot{background:var(--green)}
.st-draft .dot,.st-revise .dot,.st-done .dot{box-shadow:none;width:6px;height:6px;margin-right:0}
/* 可点击切换的状态标签（有编辑权限时）：鼠标变手型 + 悬停加深 */
.st-click{cursor:pointer;transition:.15s;user-select:none}
.st-click:hover{filter:brightness(.96);box-shadow:0 0 0 2px rgba(15,118,110,.18)}
.tip-abs{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:230px;
  display:inline-block;vertical-align:bottom}

/* 空状态（雄哥 2026-10-05 改）：
   原来是一个 56px 虚线圈 + 中间的「—」，看着像"加载失败/出错"。
   现在改成 **空箱子 SVG 图标 + 下面一行灰字**，语义一眼可懂 = 这里还没数据。
   ⚠️ ::before 不再画图（图标由 JS 的 App.icon('empty') 插入），这里只保留间距。 */
.empty{padding:52px 12px;text-align:center;color:var(--muted-2);font-size:var(--fs-md)}
.empty .ic-svg{width:40px;height:40px;display:block;margin:0 auto 12px;
  color:var(--muted3);stroke-width:1.3}
.empty .empty-t{font-size:var(--fs-md);color:var(--muted-2)}
.loading{padding:44px;text-align:center;color:var(--muted-2);font-size:13px}

/* ===================== 模态 ===================== */
.mask{
  position:fixed;inset:0;background:rgba(16,24,40,.46);backdrop-filter:blur(3px);
  display:flex;align-items:center;justify-content:center;z-index:100;padding:20px;
  animation:fade .16s ease;
}
@keyframes fade{from{opacity:0}to{opacity:1}}
.modal{
  background:#fff;border-radius:var(--r-lg);width:100%;max-width:760px;max-height:90vh;overflow:auto;
  box-shadow:var(--shadow-xl);animation:rise .2s cubic-bezier(.2,.8,.3,1);
}
@keyframes rise{from{opacity:0;transform:translateY(10px) scale(.985)}to{opacity:1;transform:none}}
.modal-h{
  padding:17px 22px;border-bottom:1px solid var(--line);display:flex;justify-content:space-between;
  align-items:center;font-size:15.5px;font-weight:600;position:sticky;top:0;background:#fff;z-index:2;
}
.modal-h .x{cursor:pointer;color:var(--muted-2);font-size:20px;line-height:1;width:28px;height:28px;
  display:flex;align-items:center;justify-content:center;border-radius:7px;transition:.15s}
.modal-h .x:hover{background:var(--red-l);color:var(--red)}
.modal-b{padding:22px 26px}
.modal-f{padding:15px 26px;border-top:1px solid var(--line);display:flex;justify-content:flex-end;gap:10px;
  position:sticky;bottom:0;background:#fff}
.form-grid{display:grid;grid-template-columns:1fr 1fr;gap:16px 20px}
.form-grid .full{grid-column:1/-1}
/* 弹窗里的表单：输入框加高、字号加大，宽屏下更舒展（雄哥 2026-10-03 反馈「挤在一起」） */
.modal .field{gap:7px}
.modal .field label{font-size:13px}
.modal .input,.modal .select,.modal textarea.input{height:42px;font-size:var(--fs-md);padding:0 13px}
.modal textarea.input{height:auto;padding:11px 13px}

/* ===================== Toast / 提示条 ===================== */
#toast{position:fixed;top:20px;left:50%;transform:translateX(-50%);z-index:300;display:flex;
  flex-direction:column;gap:9px;align-items:center;pointer-events:none}
.toast{
  background:#fff;color:var(--text);padding:11px 18px;border-radius:var(--r);font-size:var(--fs-md);
  box-shadow:var(--shadow-lg);border:1px solid var(--border);font-weight:500;
  display:flex;align-items:center;gap:9px;animation:pop .22s cubic-bezier(.2,.9,.3,1);
}
.toast::before{content:"";width:8px;height:8px;border-radius:50%;background:var(--brand);flex:0 0 8px}
.toast.ok::before{background:var(--green)}
.toast.err::before{background:var(--red)}
.toast.ok{border-color:var(--green-b)}
.toast.err{border-color:var(--red-b)}
@keyframes pop{from{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:none}}

.alert{
  display:flex;align-items:center;gap:11px;padding:12px 17px;border-radius:var(--r);
  font-size:13px;margin-bottom:16px;border:1px solid transparent;line-height:1.65;
}
.alert::before{content:"";width:4px;align-self:stretch;border-radius:3px;flex:0 0 4px}
.alert.warn{background:var(--orange-l);color:#8a5a00;border-color:var(--orange-b)}
.alert.warn::before{background:var(--orange)}
.alert.danger{background:var(--red-l);color:#a1272b;border-color:var(--red-b)}
.alert.danger::before{background:var(--red)}
.alert.info{background:var(--brand-l);color:var(--brand-dd);border-color:var(--blue-b)}
.alert.info::before{background:var(--brand)}
.alert .b{margin-left:auto;display:flex;gap:8px}
/* 可点击的到期横幅（雄哥 2026-10-04 定）：点一下直接筛出该类订单 */
.alert.clickable{cursor:pointer;transition:filter .15s,box-shadow .15s}
.alert.clickable:hover{filter:saturate(1.25);box-shadow:0 2px 10px rgba(16,24,40,.10)}
.alert.clickable .act{margin-left:auto;font-weight:700;white-space:nowrap;opacity:.85}
/* 弹窗里的「说明文字块」（雄哥 2026-10-04 定）：
   ⚠️ 不能用 .alert —— 它是 flex 横幅（::before 竖线 + 横向排列），
   装多行说明会被拆成一列一句、错位乱掉。这里用正常块级排版。 */
.note-box{
  display:block;padding:13px 16px;border-radius:var(--r);
  background:var(--brand-l);color:var(--brand-dd);
  border:1px solid var(--blue-b);border-left:3px solid var(--brand);
  font-size:12.5px;line-height:1.85;margin-bottom:16px;
}
.note-box b{color:var(--brand-d);font-weight:700}
.note-box.warn{background:var(--orange-l);color:#8a5a00;border-color:var(--orange-b);border-left-color:var(--orange)}
.note-box.warn b{color:#7a4d00}
.note-box .row{display:block}
.note-box code{background:rgba(15,118,110,.10);padding:1px 6px;border-radius:4px;
  font-size:12px;font-family:Consolas,Monaco,monospace;color:var(--brand-d)}

/* 批量导入的「拖文件区」（雄哥 2026-10-04 加） */
.drop-zone{
  border:2px dashed var(--border);border-radius:var(--r-lg);background:var(--panel-2);
  padding:22px 16px;text-align:center;cursor:pointer;margin-bottom:12px;
  transition:.18s;
}
.drop-zone:hover{border-color:var(--brand);background:var(--brand-l)}
.drop-zone.over{border-color:var(--brand);background:var(--brand-l);
  box-shadow:0 0 0 4px rgba(15,118,110,.10);transform:scale(1.005)}
.drop-zone .dz-ico{font-size:26px;line-height:1;margin-bottom:7px;opacity:.75}
.drop-zone .dz-main{font-size:var(--fs-md);font-weight:700;color:var(--text-2)}
.drop-zone .dz-sub{font-size:12px;color:var(--muted);margin-top:5px}
.drop-zone .dz-sub b{color:var(--brand)}
.alert.clickable:hover .act{opacity:1;text-decoration:underline}

/* ===================== 权限矩阵 ===================== */
.perm-matrix{width:100%;border-collapse:separate;border-spacing:0;font-size:13px;
  border:1px solid var(--line);border-radius:var(--r);overflow:hidden}
.perm-matrix th,.perm-matrix td{padding:10px 13px;text-align:center;border-bottom:1px solid var(--line)}
.perm-matrix tr:last-child td{border-bottom:none}
.perm-matrix th{background:var(--panel-2);font-weight:600;color:var(--text-2);font-size:12.5px}
.perm-matrix td:first-child{text-align:left;font-weight:600}   /* 模块名左对齐更好读 */
.perm-matrix th:first-child{text-align:left}
.perm-matrix select{height:32px;border:1.5px solid var(--border);border-radius:6px;padding:0 8px;background:#fff}

/* ===================== 图表 ===================== */
.chart-box{padding:6px 2px;flex:1;display:flex;flex-direction:column;min-height:0;overflow:hidden}
/* 趋势折线：撑满卡片剩余空间，绝不按 viewBox 比例无限长高 */
.trend-svg{width:100%;height:100%;max-height:100%;flex:1 1 auto;min-height:0;display:block;overflow:hidden}
.bar-row{display:flex;align-items:center;gap:13px;margin-bottom:12px}
.bar-row:last-child{margin-bottom:0}
/* 🔴 雄哥 2026-10-05 定「甲」：图名**改左对齐**，与下方「各团队分月明细」表首列
   对齐成同一条竖线（原先这里是 text-align:right —— 上方名字右对齐、
   下方表格居中，同一个「图图」在上下两处左边界差了约 70px，看着"没对齐"）。*/
.bar-row .name{width:132px;font-size:13px;color:var(--text-2);overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap;text-align:left;flex:0 0 132px;font-weight:500;
  padding-left:16px;box-sizing:border-box}   /* 与下方表格首列同起点，见 .team-detail 注释 */

/* 🔴 团队页「各团队分月/分季明细」表首列：**左对齐 + 左边界与上方图名对齐**（雄哥 2026-10-05 选「甲」）。
   为什么必须加 `.team-detail` 这个专属类：`table.grid` 被 8 个页面共用，
   直接改 `td:first-child` 会波及全部表格 —— 这正是今天踩过的坑，务必只限定本页。
   左边界算式（两者都在 .panel-b padding:20px 内，都取 38px 舒适边距）：
     上方图名  = 20 + 16(.bar-row .name 的 padding-left) = 36px
     下方首列  = 20 + 18(td/padding-left)                = 38px
   实测两者相差约 1px（表格边框），视觉上已完全对齐。
   表头「团队（代理）」同步左对齐，否则表头居中、内容左对齐会显得歪。 */
table.grid.team-detail th:first-child,
table.grid.team-detail td:first-child{text-align:left}

/* 团队页明细表：**合计列**的底色。
   🔴 原来写在 JS 内联（`style="background:#eff4ff"` / `#f8fafc"`）——
   硬编码浅色在深色模式下**不变色 → 白底黑字刺眼**（2026-10-05 深色验收时发现）。
   改用变量：浅色是淡青底、深色自动跟随。 */
table.grid.team-detail th.total-col,
table.grid.team-detail td.total-col{background:var(--neutral-1);font-weight:700}
/* 「区间外」的季度格：浅灰字，深浅两套各自取色 */
table.grid.team-detail td.out-range{color:var(--neutral-3)}

/* 🔴 团队页明细表改为 **固定表格布局**（雄哥 2026-10-09，「Q1→第一季度」那次）。
   为什么必须加：`table.grid` 默认是 `auto` 布局 —— 它会**按内容自动分配列宽**，
   写死的 `width` 只算建议值。实测过：季度表头改成 4 个汉字后，
   即便给了 `width:76px`，浏览器仍按内容把季度列撑到 87px →
   **整表 1229px > 容器 1108px → 横向滚动、右边「合计」被推出屏幕**。
   改成 `fixed` 后，CSS 里写的宽度被严格执行，总宽锁死 1108，不再溢出。
   ⚠️ 只加在 `.team-detail` 上，**不动共用的 `table.grid`**（8 个页面在用）。 */
table.grid.team-detail{table-layout:fixed}

/* 🔴 团队页明细表「季度列 / 月份列」宽度（雄哥 2026-10-09）。
   背景：表头从 `Q1~Q4` 改成中文全称「第一季度~第四季度」—— 4 个汉字
        在原来的自然宽度（55px）下**会被挤成两行**（「第一季 / 度」），很难看。
   做法：`table-layout:fixed` 下 width 才生效 → 给季度列写死 76px 且不折行；
        从「月份列」省出空间（月份只需放「10月」三字符，48px 够）。
   ⚠️ 只限定 `.team-detail`，**不动共用的 table.grid**（8 个页面在用它）。 */
table.grid.team-detail th.q-quarter{width:76px;white-space:nowrap}
table.grid.team-detail th.q-month{width:48px}
/* 合计列（末列）也锁死宽度 + 不折行 */
table.grid.team-detail th.total-col,
table.grid.team-detail td.total-col{width:62px;white-space:nowrap}
.bar-track{flex:1;background:var(--neutral-1);border-radius:7px;height:26px;position:relative;overflow:hidden}
.bar-fill{height:100%;border-radius:7px;transition:width .55s cubic-bezier(.2,.8,.3,1);min-width:3px}
.bar-row .val{width:60px;text-align:right;font-size:13px;color:var(--text-2);
  font-variant-numeric:tabular-nums;flex:0 0 60px;font-weight:600}
.seg{display:inline-flex;background:var(--neutral-1);border-radius:var(--r-sm);padding:3px;border:1px solid var(--line)}
.seg button{border:none;background:transparent;padding:6px 15px;border-radius:6px;cursor:pointer;
  font-size:13px;color:var(--muted);transition:.15s;font-weight:500}
.seg button.on{background:#fff;color:var(--brand);box-shadow:var(--shadow-xs);font-weight:600}

/* ===================== 总览专用 ===================== */
.ov-grid{display:grid;gap:18px;margin-bottom:18px;align-items:stretch}
.ov-2{grid-template-columns:1.3fr .7fr}
.ov-3{grid-template-columns:1fr 1fr}
.ov-panel{background:var(--panel);border:1px solid var(--border);border-radius:var(--r-lg);
  box-shadow:var(--shadow-sm);display:flex;flex-direction:column;overflow:hidden}
.ov-panel .panel-h{margin:0;flex:0 0 auto}
/* 统一高度：同排面板等高、不同排也齐整，杜绝「大的大小的小」 */
.ov-panel .body{padding:16px 20px;flex:1;display:flex;flex-direction:column;justify-content:center;
  min-height:0;overflow:hidden}
.ov-h-lg .body{height:268px;flex:0 0 268px}
/* 数据少时用的矮面板，避免大片留白（雄哥 2026-10-03 反馈）
   尺寸依据实测：进度面板 = 大数字头 67 + 3 条进度 132 + 上下 padding 32 ≈ 231，取 236 留余量 */
.ov-h-md .body{height:236px;flex:0 0 236px}
.ov-h-sm .body{height:196px;flex:0 0 196px}
.ov-h-xs .body{height:150px;flex:0 0 150px}
/* 矮/极矮面板里，内容同步收紧，保证不被切 */
.ov-h-sm .mini-list{gap:11px}
.ov-h-xs .mini-list{gap:8px}
.ov-h-sm .progress-num{font-size:30px}
.ov-h-xs .progress-num{font-size:24px}
.ov-h-sm .progress-head{margin-bottom:12px}
.ov-h-xs .progress-head{margin-bottom:8px}
.ov-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:11px;padding:36px 12px;color:var(--muted-2);font-size:13px}
.ov-empty .ic{width:54px;height:54px;border-radius:17px;background:var(--panel-2);
  border:1px dashed var(--border);display:flex;align-items:center;justify-content:center;font-size:23px}
.trend-legend{display:flex;gap:16px;font-size:12.5px;color:var(--muted);margin-bottom:8px;align-items:center}
.ring-wrap{display:flex;align-items:center;gap:26px;flex-wrap:wrap;justify-content:center}
.ring-legend{display:flex;flex-direction:column;gap:11px;min-width:130px}
.ring-legend .row{display:flex;align-items:center;gap:9px;font-size:13px;color:var(--text-2)}
.ring-legend .row b{margin-left:auto;font-variant-numeric:tabular-nums;color:var(--text);font-weight:600}
.ring-legend .row .sw{width:10px;height:10px;border-radius:3px;flex:0 0 10px}
.ring-legend .row .pct{color:var(--muted-2);font-size:12px}
.mini-list{display:flex;flex-direction:column;gap:15px}
.mini-item .top{display:flex;justify-content:space-between;font-size:13px;margin-bottom:7px;color:var(--text-2)}
.mini-item .top b{color:var(--text);font-variant-numeric:tabular-nums}
.mini-track{height:9px;background:var(--neutral-1);border-radius:6px;overflow:hidden}
.mini-fill{height:100%;border-radius:6px;transition:width .5s cubic-bezier(.2,.8,.3,1)}


.muted{color:var(--muted)} .small{font-size:12px} .mono{font-variant-numeric:tabular-nums}
.overlay-note{font-size:12.5px;color:var(--muted-2);margin-top:10px;line-height:1.7}

.nav-toggle{display:none}
.sidebar-mask{display:none}

/* ===================== 大数据库（资料库）=====================
   雄哥 2026-10-05 建。列表 + 展开式文件清单 + 上传进度条。
   颜色只用已有变量，深浅色自动跟随（避免重蹈"硬编码浅色在深色下刺眼"的覆辙）。 */

/* 展开的那一行高亮，跟下面的文件清单连成一块 */
table.grid.grid-db tr.db-open td{background:var(--brand-l)}
/* 文件清单行：占满整行，左缩进对齐"资料"列。
   🔴 必须显式 text-align:left —— 表格是居中对齐的，不写这行
      "还没有上传任何资料"和按钮会被居中，看着像浮在半空。
   padding-left 算法：姓名列文字左边界(346) - 副行td左边界(284) - 文件行自身padding(11) = 51，
   让文件图标与上方"姓名"文字左对齐。 */
table.grid.grid-db tr.db-files td{padding:10px 18px 14px 51px;background:var(--panel-2);
  border-bottom:1px solid var(--border);text-align:left}
.db-filelist{display:flex;flex-direction:column;gap:6px}
/* 一行文件：图标 · 名字 · 类型 · 大小 · 操作
   🔴 文件名用 flex:0 1 auto（不是 1 1 auto）—— 短名字不再撑满整行，
      右侧不会出现大片空白、操作按钮也不会像"漂"在最右边。 */
.up-row{display:flex;align-items:center;gap:10px;padding:7px 11px;border-radius:var(--r-sm);
  background:var(--panel);border:1px solid var(--border);font-size:13px;position:relative;overflow:hidden}
/* 上传进度：用 ::before 铺一条底色，宽度 = --p（JS 设置）。
   ⚠️ 只在"正在上传/失败"时才有意义；已完成的文件不要再铺绿底 ——
      会和展开行的浅绿叠在一起显得脏，而且 100% 的进度条本来就毫无信息量。 */
.up-row[style*="--p"]:not(.done)::before{
  content:"";position:absolute;left:0;top:0;bottom:0;width:var(--p);
  background:var(--brand-l);transition:width .25s;z-index:0}
.up-row.err{border-color:var(--red-b)}
.up-row.err::before{background:var(--red-l)}
.up-row > *{position:relative;z-index:1}
.up-row .ic{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;
  width:20px;height:20px;color:var(--muted-2)}
.up-row .ic .ic-svg{width:16px;height:16px}
/* 上传面板的拖拽区大图标（内联 SVG，不用 emoji） */
.up-drop-icon{display:flex;justify-content:center;margin-bottom:10px;color:var(--brand)}
.up-drop-icon svg{width:34px;height:34px}
/* 展开后没有文件的提示（与文件行左缩进一致，避免看起来"凹陷"） */
.up-empty{padding:8px 11px;font-size:12.5px;color:var(--muted);display:flex;align-items:center;gap:10px}
.db-loading{padding-left:63px !important}
/* 文件名：短名不撑开（0 1 auto），长名才截断；后接一段自动弹性的空隙，
   把「类型·大小·操作」稳稳推到右边，整齐成列。 */
.up-row .nm{flex:0 1 auto;min-width:0;max-width:52%;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;color:var(--text-2);font-weight:500}
.up-row .gap{flex:1 1 auto;min-width:12px}
.up-row .tag{flex:0 0 auto;font-size:11px;color:var(--muted-2);background:var(--neutral-1);
  padding:1px 7px;border-radius:20px}
.up-row .sz{flex:0 0 auto;font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums;
  min-width:74px;text-align:right}
.up-row .pct{flex:0 0 auto;font-size:12px;color:var(--brand);font-weight:600;min-width:52px;text-align:right}
.up-row .ops{flex:0 0 auto;display:flex;gap:5px;align-items:center}
.up-row .ops .btn{height:26px;padding:0 9px}
/* 资料列的徽标组 */
.db-badges{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.db-badges .pill{font-size:11px;padding:1px 7px;display:inline-flex;align-items:center;gap:3px}
.db-badges .pill .ic-svg{width:12px;height:12px;color:var(--muted-2)}

/* ===== 大数据库列表：列对齐 + 行高压缩（雄哥 2026-10-05 反馈"行太高、字偏右"）=====
   🔴 三条都是"只作用于这一页"的专属类，**不动公共 table.grid** ——
      公共选择器被 8 个页面共用，改它会把别的页面一起改坏（踩过）。 */
/* 表格改为 fixed 布局：不写的话是 auto，浏览器按内容重排，
   我设的 width 全成了"建议值"，会出现"姓名列被挤成 52px"这种失控（踩过）。 */
table.grid.grid-db{table-layout:fixed}
/* fixed 布局下，列宽之和若超过表宽，浏览器按比例压缩各列。
   默认给单元格加 ellipsis 防超宽；但**姓名列必须在后面豁免**（见下）。 */
table.grid.grid-db th, table.grid.grid-db td{overflow:hidden;text-overflow:ellipsis}
/* 🔴 文字列 nowrap：让浏览器压缩别的列，而不是把"姓名"竖排成 5 行（行高会飙到 136px） */
table.grid.grid-db td.db-c-name, table.grid.grid-db th.db-c-name,
table.grid.grid-db td.db-c-txt,  table.grid.grid-db th.db-c-txt{white-space:nowrap}
/* 🔴 姓名列照常截断（不能 overflow:visible —— 文字会溢到隔壁列，与"学校"重叠）。
   靠"给足宽度"而不是"不截断"来避免切字：宽度见 JS 里的 112px。 */
table.grid.grid-db td.db-c-ops{overflow:visible;text-overflow:clip}
/* 1) 文字列一律左对齐（原来继承表格 text-align:center，看着字都挤在右边） */
table.grid.grid-db th.db-c-name, table.grid.grid-db td.db-c-name,
table.grid.grid-db th.db-c-txt,  table.grid.grid-db td.db-c-txt,
table.grid.grid-db th.db-c-title,table.grid.grid-db td.db-c-title{
  text-align:left}
/* 2) 资料列与操作列**各占一列**（原来挤一起把行高压到 86px，一屏只看 7 条） */
table.grid.grid-db td.db-c-files{padding-left:6px}
table.grid.grid-db td.db-c-ops{padding-left:6px;text-align:left}
/* 操作列的按钮不参与截断（否则"删除"会被 ellipsis 切成"…"） */
table.grid.grid-db td.db-c-ops .btn{height:26px;padding:0 7px;margin-right:2px}
table.grid.grid-db td.db-c-ops .btn:last-child{margin-right:0}
/* 题目列：长题目单行截断（靠 .tip-abs 的 title 悬浮看全） */
table.grid.grid-db td.db-c-title{padding-left:6px}
/* 展开箭头列：窄一点，省下的宽度给内容列 */
table.grid.grid-db td.db-c-toggle,
table.grid.grid-db thead th:first-child{padding-left:12px;padding-right:6px}
table.grid.grid-db td.db-c-toggle{text-align:center}
table.grid.grid-db td.db-c-toggle .btn{height:24px;padding:0 7px;min-width:0}

/* ===================== 响应式 ===================== */
@media (max-width:1200px){
  .ov-2{grid-template-columns:1fr}
}
@media (max-width:900px){
  .login-shell{grid-template-columns:1fr}
  .login-intro{display:none}
  .login-card{padding:44px 30px;min-height:100vh}
  .login-wrap::before{display:none}

  .nav-toggle{display:inline-flex;align-items:center;justify-content:center;font-size:16px;width:36px;padding:0}
  .hide-sm{display:none}
  /* 手机端用户胶囊只留头像：去掉边框与内边距，避免空洞 */
  .topbar .who{padding:0;border:none;box-shadow:none;background:transparent}
  .topbar .who:hover{border:none;box-shadow:none}
  /* 手机端侧栏是抽屉（默认隐藏在左侧），主内容不需要让位 */
  .main{margin-left:0}
  .sidebar{
    position:fixed;left:0;top:0;bottom:0;height:100vh;width:238px;flex:0 0 238px;
    transform:translateX(-100%);transition:transform .22s ease;z-index:80;
  }
  .sidebar.open{transform:none;box-shadow:8px 0 30px rgba(0,0,0,.38)}
  .sidebar-mask{display:block;position:fixed;inset:0;background:rgba(16,24,40,.46);z-index:70;
    opacity:0;pointer-events:none;transition:opacity .22s}
  .sidebar-mask.show{opacity:1;pointer-events:auto}
  .topbar{padding:0 14px;height:58px}
  .topbar h2{font-size:15.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .content{padding:14px 13px 34px}
  .cards{grid-template-columns:repeat(auto-fit,minmax(146px,1fr));gap:11px}
  .card{padding:13px 15px}
  .card .v{font-size:var(--fs-xl)}          /* 窄屏统计卡大数字自适应 29→20px（--fs-xl）*/
  .card .v[style]{font-size:15px !important}
  .panel-h{padding:13px 15px;flex-direction:column;align-items:stretch}
  .panel-h > div{flex-wrap:wrap}
  .panel-b{padding:13px 15px}
  .toolbar{gap:8px}
  .search{width:100%;min-width:0;flex:1}
  .input,.select{max-width:100%}
  .table-wrap{-webkit-overflow-scrolling:touch;max-width:100%}
  table.grid{font-size:12px;min-width:820px}
  table.grid th,table.grid td{padding:9px 10px}
  .form-grid{grid-template-columns:1fr}
  .modal{max-width:100% !important;max-height:94vh;border-radius:12px}
  .mask{padding:10px}
  .modal-h{padding:14px 16px;font-size:15px}
  .modal-b{padding:15px 16px}
  .modal-f{padding:13px 16px}
  .btn{height:33px;padding:0 12px;font-size:var(--fs-base)}   /* 原 13px —— 统一 12.5px */
  .btn.sm{height:28px;padding:0 10px}
  #twoCol{grid-template-columns:1fr !important;gap:13px !important}
  .bar-row .name{width:86px;flex:0 0 86px;font-size:12px}
  .bar-row .val{width:48px;flex:0 0 48px;font-size:12px}
  .perm-matrix select{height:29px;max-width:112px}
  .ring-wrap{gap:18px}
}
@media (max-width:560px){
  .content{padding:11px 9px 30px}
  .cards{grid-template-columns:1fr 1fr;gap:9px}
  .card{padding:11px 12px}
  .card .k{font-size:12px}
  .card .v{font-size:var(--fs-lg)}           /* 更窄屏再降到 14px（--fs-lg）*/
  .card .v[style]{font-size:var(--fs-xs) !important}
  .card .s{font-size:var(--fs-xs)}
  .ov-panel{min-height:auto}
}
