/* ============ 工作台改版（钉钉 / 飞书风格：宫格入口 + 底部导航） ============ */

:root {
  --tabbar-h: 60px;
}

html { scroll-padding-bottom: calc(var(--tabbar-h) + 16px); }

/* ---------- 底部导航 ---------- */
.tabbar {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  bottom: 0;
  z-index: 900;
  display: flex;
  width: 100%;
  max-width: 760px;
  height: calc(var(--tabbar-h) + env(safe-area-inset-bottom, 0px));
  padding-bottom: env(safe-area-inset-bottom, 0px);
  background: rgba(255, 255, 255, 0.96);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-top: 1px solid rgba(0, 0, 0, 0.06);
  box-shadow: 0 -4px 24px rgba(0, 0, 0, 0.06);
}
.tabbar .tab {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  border: 0;
  background: none;
  color: #9aa0a6;
  font-size: 11px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.tabbar .tab svg { width: 22px; height: 22px; }
.tabbar .tab.on { color: #c0111a; font-weight: 600; }
body.not-logged-in .tabbar { display: none; }
/* 桌面端专用：底部「感应带」，手机端不出现 */
.tabbar-hot { display: none; }

/* ---------- 桌面端：底部导航平时隐藏，鼠标在底部感应带上停留片刻才浮出；手机端常驻 ----------
   关键：隐藏时必须 pointer-events:none —— 否则透明的导航条仍然会拦截鼠标，
   横向拖拽 / 拖滚动条拖到页面底部时会误触把导航顶出来，甚至误点到标签。 */
@media (min-width: 821px) {
  .tabbar {
    opacity: 0;
    pointer-events: none;
    transform: translateX(-50%) translateY(8px);
    transition: opacity .18s ease, transform .18s ease;
  }
  .tabbar.show {
    opacity: 1;
    pointer-events: auto;
    transform: translateX(-50%) translateY(0);
  }
  /* 页面最底下的一条透明感应带：鼠标停在这里 260ms 才浮出导航 */
  .tabbar-hot {
    display: block;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    height: 16px;
    z-index: 890;
    background: transparent;
  }
}
/* 触摸屏（大屏平板）：没有 hover 概念，导航常驻，不搞感应带 */
@media (min-width: 821px) and (hover: none) {
  .tabbar {
    opacity: 1;
    pointer-events: auto;
    transform: translateX(-50%);
  }
  .tabbar-hot { display: none; }
}

/* ---------- 顶栏头像：点一下进「我的」 ---------- */
.topbar-user { cursor: pointer; border-radius: 8px; padding: 4px 8px; transition: background .15s; }
.topbar-user:hover { background: rgba(0, 0, 0, 0.06); }
.topbar-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  margin-right: 6px;
  border-radius: 50%;
  background: #c0111a;
  color: #fff;
  font-size: 13px;
  font-weight: 600;
  vertical-align: middle;
}
.wb-avatar { cursor: pointer; }

/* ---------- 宫格图标右上角的红色数字角标（像手机 App 图标，没有就不显示） ---------- */
.wb-item .wb-ico { position: relative; overflow: visible; }
.wb-badge {
  position: absolute;
  top: -6px;
  right: -6px;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 9px;
  background: #e5342a;
  color: #fff;
  font-size: 11px;
  font-weight: 600;
  line-height: 18px;
  text-align: center;
  box-shadow: 0 0 0 2px #fff;
  box-sizing: border-box;
}

/* 给主内容让出底部空间（手机上导航常驻，必须留；桌面端导航平时隐藏，不留） */
main.view {
  padding-bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom, 0px) + 16px);
}
@media (min-width: 821px) {
  main.view { padding-bottom: 24px; }
}

/* ---------- 统计聚焦模式：内容铺满整个视口，底部不出现空白断层 ---------- */
/* ---------- 项目看板（2026-11-05）：完整打开时只显示「项目列表」这块看板；
   待办 / 任务日历 / 风险预警 / 拖期提醒都有独立入口（工作台宫格、底部「日历」tab），
   平铺在下面只会把看板拉得很长。DOM 保留（聚焦模式从宫格 / 日历 tab 进来还要用），
   只在完整模式下隐藏 ---------- */
#viewStats:not(.focus-mode) #statsSplit,
#viewStats:not(.focus-mode) #statSoon,
#viewStats:not(.focus-mode) #statCatch { display: none !important; }
@media (min-width: 821px) {
  /* height 而不是 min-height：让 viewStats 自己成为滚动容器（内容在它内部滚）。
     如果只写 min-height，内容会把整个 viewStats 撑高、实际滚动发生在整页上，
     顶部条的 sticky 就永远不触发（sticky 只对最近的可滚动祖先生效）。
     padding-top 必须清零：sticky 只能贴到滚动容器的内边距之内，
     留着 14px 的话滚动时内容会从顶部条上方的缝里透出来。 */
  #viewStats.focus-mode { display: flex; flex-direction: column; height: calc(100vh - 48px); min-height: 0; padding-top: 0; }
  #viewStats.focus-mode #statsTop { padding-top: 16px; }   /* 视觉间距挪进顶部条自己身上，粘住时把缝盖严 */
  #viewStats.focus-mode #statsSplit { flex: 1; display: flex; flex-direction: column; }
  #viewStats.focus-mode .top-col { flex: 1; display: flex; flex-direction: column; }
  #viewStats.focus-mode .top-col > section.panel,
  #viewStats.focus-mode #statsSplit > section.panel,
  #viewStats.focus-mode > section.panel { flex: 1; }
  /* 待办 / 日历聚焦：目标卡片高度随内容生长（31 条就 31 条全显示），
     不再 flex:1 拉到屏幕底——待办少的时候底下空一大片，看着像没加载完 */
  #viewStats.focus-mode .top-col > section.panel.focus-target,
  #viewStats.focus-mode #statsSplit > section.panel.focus-target,
  #viewStats.focus-mode > section.panel.focus-target { flex: 0 0 auto; }
  /* 没有目标面板的那一整列（比如待办聚焦时右边的日历列）整体收掉，
     目标列才能独占整行、一直铺到屏幕底部 */
  #viewStats.focus-mode .top-col:not(:has(> section.panel.focus-target)) { display: none !important; }
  /* 两列里都没有目标面板时（拖期 / 完成度聚焦），整个分栏容器也收掉，
     否则它还占着三四百像素的空高度，把面板挤到页面下半截 */
  #viewStats.focus-mode #statsSplit:not(:has(.focus-target)) { display: none !important; }
  /* 拖期面板按内容自适应高度：条目少时卡片到内容为止就结束，
     不再把淡红底色强行拉伸到屏幕底（下面看起来像缺内容）。
     同时放开 catchBody 的 200px 内滚限制，列表完整展开、整页滚动 */
  #viewStats.focus-mode #statCatch { flex: 0 0 auto; min-height: 0; }
  #viewStats.focus-mode #catchBody { max-height: none; overflow: visible; }
  /* 风险预警聚焦：面板撑满整屏、47 条卡片在面板内部滚动 ——
     否则面板只有内容那么高，视口剩下的大片空白看起来像「没加载完 / 渲染坏了」 */
  #viewStats.focus-mode #statSoon.focus-target {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-height: 0;
  }
  #viewStats.focus-mode #statSoon.focus-target .catch-head { flex: 0 0 auto; }
  #viewStats.focus-mode #statSoon.focus-target #soonBody {
    flex: 1;
    overflow-y: auto;
    max-height: none;
    -webkit-overflow-scrolling: touch;
  }
  /* 聚焦页顶部整条（品牌 / 返回完整统计 / 同步状态）锁定：往下翻列表时不跟走 */
  #viewStats.focus-mode #statsTop {
    position: sticky;
    top: 0;
    z-index: 20;
    background: #fff;
    box-shadow: 0 2px 10px rgba(16, 30, 50, 0.08);
  }
  /* 顶栏合并进来的聚焦页头：和主页顶栏同款红色（盖掉上面的白底） */
  #viewStats.focus-mode #statsTop.merged-head {
    background: linear-gradient(118deg, var(--brand-dark), var(--brand) 52%, #d8323c);
    color: #fff;
    box-shadow: 0 2px 12px rgba(140, 12, 20, 0.26);
  }
  #viewStats.focus-mode #statsTop.merged-head h2,
  #viewStats.focus-mode #statsTop.merged-head .btn,
  #viewStats.focus-mode #statsTop.merged-head .icon-btn { color: #fff; }
}

/* ---------- 审批 / 我的任务：整页显示，观感对齐「拖期提醒」面板 ---------- */
/* 层级必须压过底部导航(900)，否则打开后导航还浮在页面上，看起来仍像弹窗。
   style.css 里 #modalApprovals{z-index:70} 是 ID 优先级，这里也要用 ID 才压得住 */
#modalApprovals.modal-page,
#modalTasks.modal-page {
  z-index: 950;
  padding: 14px 18px;
  overflow-y: auto;
  background: #f2f4f8;
  align-items: start;                /* 内容贴顶，不垂直居中悬在半空 */
}
.modal-mask.modal-page .modal {
  width: 100%;
  max-width: none;
  min-height: 0;                     /* 高度跟内容走，内容完卡片就结束 */
  max-height: calc(100vh - 28px);
  overflow-y: auto;                  /* 卡片自己滚：标题栏的 sticky 相对它生效
                                        （原来 mask 滚 + modal overflow:hidden，sticky 被彻底废掉） */
  margin: 0;
  border: 1px solid #e8b4ae;
  border-left: 5px solid #c0392b;    /* 和拖期面板同款：左侧红色竖条 */
  border-radius: 8px;
  background: #fff;
  box-shadow: 0 6px 24px rgba(16, 30, 50, .08);
}
.modal-mask.modal-page .modal-head {
  gap: 8px;
  padding: 12px 18px 10px;
  border-bottom: 1px dashed #e8b4ae;
  /* 标题栏锁定：往下翻长列表时它一直贴在顶上（mask 是滚动容器，sticky 相对它生效） */
  position: sticky;
  top: 0;
  z-index: 5;
  background: #fff;
  border-radius: 8px 8px 0 0;
}
.modal-mask.modal-page .modal-head h3 { color: #b3281c; font-size: 16px; margin: 0; }
.modal-mask.modal-page .modal-body { padding: 10px 18px 16px; }
/* 整页（950）之上还要再弹的：确认框 / 输入框 / 变更对比 / 提交 / 版本历史。
   style.css 里它们只有 60~80，从审批或我的任务整页里点出来会被整页挡在后面
   —— 撤回点确定时看不见确认框，就是这个原因。ID 选择器才压得住 style.css 里的同款规则。 */
#modalPrompt { z-index: 1100; }
#modalConfirm { z-index: 1120; }
#modalDiff, #modalAudit { z-index: 1080; }
#modalSubmit, #modalVersions, #modalVerDetail, #modalAggr { z-index: 1080; }

/* ---------- 项目管理：筛选工具栏压成一行小图标，与「产线项目推进表」标题同行 ---------- */
/* 重复类名提高优先级：压过下面「顶栏合并」的 .panel-head{flex-wrap:wrap}（446 行） */
.plan-head.plan-head { flex-wrap: nowrap; align-items: center; gap: 10px; }
/* 顶栏的品牌文字块（「产线项目管理」大标题 + 副标题）删掉：
   页面里本来就有各自的标题（如「产线项目推进表」），顶栏只留产线红方块和返回/前进键。
   不带 .topbar 前缀：顶栏合并后这块可能挂在 panel-head 里 */
.brand-text { display: none !important; }
.plan-head .panel-title { flex: 0 0 auto; }
.plan-head .panel-title h2 { white-space: nowrap; }
.plan-filters { flex: 1 1 auto; justify-content: flex-end; flex-wrap: nowrap; gap: 4px; }
/* 搜索框收成一个小放大镜图标：点击 / 聚焦展开成完整输入框，
   有内容时保持展开；空了失焦自动缩回。
   用 ID 权重写：style.css 里 .filters #fKeyword 是 ID 规则，class 写法压不过 */
/* 双写 ID 提权：压过 theme.css 的 .filters #fKeyword{width:300px;min-width:180px}（0,1,1） */
#fKeyword#fKeyword {
  width: 32px; min-width: 32px; flex: 0 0 32px;
  height: 30px; padding: 0 8px; font-size: 12px;
  border-radius: 15px; cursor: pointer;
  color: transparent;
  background: #fff url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%237a8aa0' stroke-width='2' stroke-linecap='round'><circle cx='11' cy='11' r='7'/><path d='M20 20l-4.2-4.2'/></svg>") no-repeat center / 17px 17px;
  transition: width .18s ease, flex-basis .18s ease;
}
#fKeyword#fKeyword::placeholder { color: transparent; }
#fKeyword#fKeyword:focus,
#fKeyword#fKeyword:not(:placeholder-shown) {
  width: 200px; min-width: 200px; flex-basis: 200px; cursor: text;
  color: var(--text, #21313f);
  padding-left: 28px;
  background-position: 8px center;
}
/* 小图标下拉按钮（类型 / 负责人 / 项目 / 事项 / 行距）：
   圆角小按钮里放 SVG 图标，透明的原生 select 盖在上面负责弹出选项；
   选了非默认值时右侧亮红点 */
.pick-ico {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  height: 30px; width: 36px;
  border: 1px solid var(--line, #dde3ec);
  border-radius: 15px;
  background: #fff;
  color: #4a5a6e;
  cursor: pointer;
  user-select: none;
}
.pick-ico svg { width: 18px; height: 18px; display: block; }
.pick-ico:hover { border-color: var(--brand-2, #c0111a); color: var(--brand, #c0111a); }
/* 透明 select 必须 min-width:0 压死在按钮内 —— 不然会被超长的选项文本
   （比如完整项目名）撑到几百像素宽，透明地盖住右边「我的 / 列宽」导致点不到 */
.pick-ico .pick-overlay {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  min-width: 0; max-width: 100%;
  opacity: 0; cursor: pointer;
  border: none; padding: 0; margin: 0;
  font-size: 16px;   /* 手机上点原生下拉，字号影响弹出的选项大小 */
}
.pick-ico.has-val::after {
  content: '';
  position: absolute; right: 3px; top: 3px;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: #c0392b;
}
/* 图标按钮（列宽 ↔ / 显示列 / 全屏）：和 pick-ico 同规格 */
.plan-filters .btn-mini {
  width: 36px; height: 30px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 15px;
}
.plan-filters .btn-mini svg { width: 18px; height: 18px; display: block; }
/* 「我的」小开关：点一下切换，选中高亮 */
.chip-chk { display: inline-flex; cursor: pointer; }
.chip-chk input { position: absolute; opacity: 0; width: 0; height: 0; }
.chip-chk span {
  font-size: 12px;
  padding: 0 10px;
  height: 30px;
  display: inline-flex;
  align-items: center;
  border-radius: 15px;
  border: 1px solid var(--line);
  background: #fff;
  color: var(--muted);
  user-select: none;
  white-space: nowrap;
}
.chip-chk input:checked + span {
  border-color: var(--brand-2);
  background: var(--brand-soft, #eef4fa);
  color: var(--brand);
  font-weight: 600;
}
.btn-mini { padding: 3px 9px; font-size: 12px; }
/* 表头小图标：锁（锁定前 N 列）与眼睛（隐藏该列） */
.col-freeze, .col-hide {
  border: none;
  background: none;
  padding: 0 1px;
  margin-left: 3px;
  color: #b6bfcc;
  cursor: pointer;
  vertical-align: middle;
  line-height: 1;
}
.col-freeze svg, .col-hide svg { width: 12px; height: 12px; display: block; }
.col-freeze:hover, .col-hide:hover { color: var(--brand-2); }
.col-freeze.on { color: #c0392b; }

/* 整页左上角的返回键（和统计聚焦模式的返回一致），点它回到刚才的页面 */
.modal-mask.modal-page .mp-back {
  font-size: 18px;
  line-height: 1;
  padding: 4px 10px;
}

/* ---------- 顶栏品牌旁的返回 / 前进（跟着 brand 走，合并页也在） ---------- */
.hist-btns { display: inline-flex; gap: 4px; margin-right: 8px; }
.brand { cursor: pointer; }
.hist-btns .icon-btn { font-size: 15px; line-height: 1; padding: 3px 8px; }
.modal-mask.modal-page .modal-body {
  width: 100%;
  max-width: 1080px;
  margin: 0 auto;
  padding-left: 24px;
  padding-right: 24px;
  box-sizing: border-box;
}
.modal-mask.modal-page .modal-head,
.modal-mask.modal-page .modal-foot {
  width: 100%;
  max-width: 1080px;
  margin: 0 auto;
  padding-left: 24px;
  padding-right: 24px;
  box-sizing: border-box;
}

/* ---------- 工作台页 ---------- */
.view-home {
  max-width: 1080px;
  margin: 0 auto;
  padding: 18px 16px 0;
}
.wb-hero {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 18px 4px 20px;
}
.wb-avatar {
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: linear-gradient(135deg, #c0111a, #ff6b4a);
  color: #fff;
  font-size: 22px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
}
.wb-hero h2 { margin: 0; font-size: 21px; line-height: 1.25; }
.wb-hero p { margin: 2px 0 0; font-size: 13px; }

.wb-section {
  margin: 18px 2px 10px;
  font-size: 15px;
  font-weight: 700;
  color: #333;
}
.wb-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 18px 8px;
}
@media (min-width: 700px) { .wb-grid { grid-template-columns: repeat(6, 1fr); } }
@media (min-width: 1000px) { .wb-grid { grid-template-columns: repeat(8, 1fr); } }

.wb-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 7px;
  border: 0;
  background: none;
  padding: 0;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.wb-ico {
  width: 54px;
  height: 54px;
  border-radius: 15px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.10);
  transition: transform 0.12s ease;
}
.wb-item:active .wb-ico { transform: scale(0.92); }
@media (hover: hover) { .wb-item:hover .wb-ico { transform: translateY(-2px); } }
.wb-ico svg { width: 26px; height: 26px; }
.wb-item span {
  font-size: 12px;
  color: #444;
  line-height: 1.2;
  text-align: center;
}

/* 图标配色（渐变） */
.c-blue   { background: linear-gradient(135deg, #4f8cff, #2f6bff); }
.c-orange { background: linear-gradient(135deg, #ffb03a, #ff7f2a); }
.c-green  { background: linear-gradient(135deg, #2ed573, #10ac84); }
.c-sky    { background: linear-gradient(135deg, #48dbfb, #0abde3); }
.c-purple { background: linear-gradient(135deg, #a29bfe, #6c5ce7); }
.c-red    { background: linear-gradient(135deg, #ff6b81, #e84118); }
.c-gold   { background: linear-gradient(135deg, #ffd166, #f6a821); }
.c-teal   { background: linear-gradient(135deg, #00d2d3, #01a3a4); }
.c-slate  { background: linear-gradient(135deg, #778ca3, #4b6584); }
.c-violet { background: linear-gradient(135deg, #c39bff, #7c3aed); }
.c-rose   { background: linear-gradient(135deg, #fd79a8, #e84393); }

/* ---------- 我的页 ---------- */
.view-me {
  max-width: 720px;
  margin: 0 auto;
  padding: 18px 16px 0;
}
.me-card {
  display: flex;
  align-items: center;
  gap: 14px;
  background: linear-gradient(135deg, #c0111a, #ff6b4a);
  border-radius: 18px;
  padding: 22px 18px;
  color: #fff;
  box-shadow: 0 8px 24px rgba(192, 17, 26, 0.25);
}
.me-card .wb-avatar { background: rgba(255, 255, 255, 0.22); box-shadow: none; }
.me-card h3 { margin: 0; font-size: 19px; }
.me-card p { margin: 4px 0 0; font-size: 13px; opacity: 0.9; }

.me-list {
  background: #fff;
  border-radius: 14px;
  overflow: hidden;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
  margin-top: 12px;
}
.me-item {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 15px 16px;
  border: 0;
  border-bottom: 1px solid #f2f3f5;
  background: none;
  font-size: 15px;
  color: #333;
  cursor: pointer;
  text-align: left;
  -webkit-tap-highlight-color: transparent;
}
.me-item:last-child { border-bottom: 0; }
.me-item:active { background: #f7f8fa; }
.me-item .me-ico {
  width: 32px;
  height: 32px;
  border-radius: 9px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  flex: none;
}
.me-item .me-ico svg { width: 17px; height: 17px; }
.me-item .me-arrow { margin-left: auto; color: #c4c8cd; font-size: 16px; }
.me-item.danger { color: #d63031; }
.me-item.danger .me-ico { background: linear-gradient(135deg, #ff6b81, #e84118); }

/* ---------- 顶栏只留品牌、同步状态、用户徽章 ----------
   其它按钮的入口都在工作台宫格 / 我的页里，任何屏幕尺寸都不再挤在顶栏 */
.topbar-actions .btn,
.topbar-actions .topbar-sep { display: none !important; }
.topbar .brand { cursor: pointer; }
.topbar .brand:active { opacity: 0.8; }

/* ---------- 统计「聚焦模式」：从工作台单独入口进来，只显示对应那一块 ---------- */
#viewStats.focus-mode section.panel:not(.focus-target):not(.focus-keep) { display: none !important; }
#viewStats.focus-mode .stat-matrix > :not(#statExtras) { display: none !important; }
#viewStats.focus-mode .stat-matrix-panel.focus-keep .stat-matrix { display: block; }
/* statsSplit 的显示与铺满由前面「铺满视口」的 flex 规则负责（这里原来写过 display:block，会把铺满顶掉） */
/* 只有「拖期提醒」入口自己才强制显示拖期面板；待办/日历聚焦时不掺进来 */
#viewStats.focus-mode #statCatch.focus-target { display: block !important; }

/* ---------- 操作提示：放屏幕正中，更大更醒目（不再和底部导航挤在一起） ---------- */
.toast {
  left: 50%;
  top: 44%;
  bottom: auto;
  transform: translate(-50%, -50%);
  max-width: 82vw;
  text-align: center;
  font-size: 15px;
  font-weight: 600;
  padding: 14px 26px;
  border-radius: 14px;
  z-index: 3000;
  box-shadow: 0 14px 44px rgba(0, 0, 0, .3);
  animation: wbToastIn .18s ease;
}
@keyframes wbToastIn {
  from { opacity: 0; transform: translate(-50%, -44%); }
  to   { opacity: 1; transform: translate(-50%, -50%); }
}

/* ---------- 顶栏合并：品牌 / 同步状态 / 用户并进页头行（浅色背景配色） ---------- */
.panel-head, .stats-head { flex-wrap: wrap; row-gap: 6px; }
/* 页头整行压矮：上下内边距 14 → 6，产线红方块 40 → 32（登录页那个不受影响） */
.panel-head, .stats-head { padding-top: 6px; padding-bottom: 6px; }
.panel-head .brand-mark, .stats-head .brand-mark { width: 32px; height: 32px; border-radius: 8px; font-size: 11px; }
.panel-head .brand, .stats-head .brand { gap: 10px; padding-right: 14px; border-right: 1px solid #e6eaf0; }
.panel-head .brand-text h1, .stats-head .brand-text h1 { color: var(--ink, #1c2b3a); font-size: 16px; }
.panel-head .brand-text p, .stats-head .brand-text p { color: var(--muted, #67788e); }
.panel-head .topbar-actions, .stats-head .topbar-actions { margin-left: auto; }
.panel-head .save-state, .stats-head .save-state { color: #5b6b80; background: #f3f5f9; border: 1px solid #e3e8ef; }
.panel-head .topbar-user, .stats-head .topbar-user { color: #33475e; background: #fff; border: 1px solid #dbe2ea; }
.panel-head .topbar-sep, .stats-head .topbar-sep { background: #dfe5ec; }
/* 合并后副标题就不需要了，省出高度 */
.panel-head .panel-title p, .stats-head .stats-sub { display: none; }

/* ---------- 顶栏合并进来的页头（项目管理 / 知识库 / 统计）：整行换成
   与工作台顶栏同款红色渐变，不再是白条 —— 全站顶部观感统一 ---------- */
.panel-head.merged-head, .stats-head.merged-head {
  background: linear-gradient(118deg, var(--brand-dark), var(--brand) 52%, #d8323c);
  border-bottom: none;
  color: #fff;
  box-shadow: 0 2px 12px rgba(140, 12, 20, .26);
}
.panel-head.merged-head .brand, .stats-head.merged-head .brand { border-right-color: rgba(255, 255, 255, .3); }
.panel-head.merged-head .brand-text h1, .stats-head.merged-head .brand-text h1 { color: #fff; }
.panel-head.merged-head .panel-title h2, .stats-head.merged-head h2 { color: #fff; }
.panel-head.merged-head .muted, .stats-head.merged-head .muted { color: rgba(255, 255, 255, .78); }
.panel-head.merged-head .icon-btn, .stats-head.merged-head .icon-btn { color: #fff; }
.panel-head.merged-head .save-state, .stats-head.merged-head .save-state {
  color: #fff; background: rgba(255, 255, 255, .14); border: 1px solid rgba(255, 255, 255, .22);
}
.panel-head.merged-head .topbar-user, .stats-head.merged-head .topbar-user {
  color: #fff; background: rgba(255, 255, 255, .14); border: 1px solid rgba(255, 255, 255, .22);
}
.panel-head.merged-head .topbar-sep, .stats-head.merged-head .topbar-sep { background: rgba(255, 255, 255, .3); }
/* 红底上的按钮：半透明白胶囊（文字 / 图标按钮 / 图标下拉同款） */
.panel-head.merged-head .btn, .stats-head.merged-head .btn {
  color: #fff; background: rgba(255, 255, 255, .1);
  border-color: rgba(255, 255, 255, .38);
}
.panel-head.merged-head .btn:hover:not(:disabled), .stats-head.merged-head .btn:hover:not(:disabled) {
  background: rgba(255, 255, 255, .2);
}
.panel-head.merged-head .btn-primary, .stats-head.merged-head .btn-primary {
  color: #c8262f; background: #fff; border-color: #fff;
}
.panel-head.merged-head .btn-primary:hover:not(:disabled), .stats-head.merged-head .btn-primary:hover:not(:disabled) {
  background: #fdeff0;
}
.panel-head.merged-head .pick-ico, .stats-head.merged-head .pick-ico {
  color: #fff; background: rgba(255, 255, 255, .1); border-color: rgba(255, 255, 255, .38);
}
.panel-head.merged-head .search-pill, .stats-head.merged-head .search-pill {
  color: #fff; background: rgba(255, 255, 255, .1); border-color: rgba(255, 255, 255, .38);
}

/* ---------- 手机上精简顶栏 ---------- */
@media (max-width: 820px) {
  .topbar { padding: 8px 12px; gap: 8px; }
  .topbar .brand-text p { display: none; }
  .topbar .brand-text h1 { font-size: 15px; }
  .topbar .brand-mark { width: 30px; height: 30px; font-size: 12px; }
}
@media (max-width: 820px) {
  .view-home, .view-me { padding-left: 14px; padding-right: 14px; }
}

/* ---------- 日程：可选作业时间 / 时间徽标 / 到点提醒 ----------
   便签可以只写日期（全天，老数据显示不变），也可以带 15:00–15:30 这样的具体时间；
   到点前按「提前 N 分钟」在待办与日历里高亮并弹一次页内提示。 */
.note-time {
  display: inline-flex; align-items: center;
  margin-right: 6px; padding: 0 6px; height: 18px;
  border-radius: 9px;
  background: #eef4fb; border: 1px solid #d6e3f2; color: #2c6aa8;
  font-size: 11px; font-weight: 600; letter-spacing: .2px;
  white-space: nowrap;
}
.note-remind {
  display: inline-flex; align-items: center;
  margin-right: 6px; padding: 0 6px; height: 18px;
  border-radius: 9px;
  background: #fff4e0; border: 1px solid #f3d9a8; color: #b06a00;
  font-size: 11px; font-weight: 600;
  white-space: nowrap;
}
/* 进入提醒窗口的那一条：左侧亮橙条 + 淡色底，一眼能扫到 */
.todo-item.remind-soon,
.cal-item.remind-soon {
  border-left: 3px solid #e8a20c;
  background: #fffaf0;
}

/* ---------- 待办按种类分组 + 折叠 ----------
   组头：种类名 + 数量徽标 + 箭头；点组头收起 / 展开（状态存 localStorage） */
.todo-ghead {
  display: flex; align-items: center; gap: 6px;
  padding: 9px 10px 6px;
  font-size: 14px; font-weight: 700; color: #5a6b80;
  cursor: pointer; user-select: none;
  border-top: 1px dashed #e3ebf4;
}
.todo-group:first-child .todo-ghead { border-top: none; }
.todo-ghead:hover { color: #2c6aa8; }
.todo-ghead .tg-arrow {
  display: inline-block; width: 14px;
  color: #8fa3b8; font-size: 12px; text-align: center;
}
.todo-ghead:hover .tg-arrow { color: #2c6aa8; }
.todo-ghead .tg-count {
  margin-left: auto; min-width: 22px;
  padding: 0 6px; height: 19px; line-height: 19px;
  border-radius: 10px;
  background: #eef3f9; color: #5a6b80;
  font-size: 12px; font-weight: 700; text-align: center;
}
.todo-ghead:hover .tg-count { background: #e2edf8; color: #2c6aa8; }
.todo-group.folded .todo-ghead { color: #8fa3b8; }
.note-time-in { width: 86px; }
.note-remind-sel { width: 104px; }
/* ---------- 便签归档子层级（挂在「我的便签」组内，默认折叠） ---------- */
.todo-arch { margin: 2px 0 6px; }
.todo-arch-head {
  display: flex; align-items: center; gap: 6px;
  padding: 4px 10px 2px 24px;
  font-size: 12px; font-weight: 700; color: #9aaabb;
  cursor: pointer; user-select: none;
}
.todo-arch-head:hover { color: #2c6aa8; }
.todo-arch-head .tg-arrow { display: inline-block; width: 12px; font-size: 11px; }
.todo-arch-head .tg-count {
  margin-left: auto; min-width: 20px;
  padding: 0 5px; height: 16px; line-height: 16px;
  border-radius: 8px; background: #f1f5f9; color: #8fa3b8;
  font-size: 11px; font-weight: 700; text-align: center;
}
.todo-arch-head:hover .tg-count { background: #e2edf8; color: #2c6aa8; }
.todo-arch-body { padding-left: 12px; }

/* ---------- 版本标识（排查手机端是否拿到新页面用） ---------- */
.ver-tag {
  margin: 22px 0 8px;
  text-align: center;
  font-size: 11px;
  color: #b9c4d2;
  letter-spacing: .3px;
}

/* ---------- 手机主屏：长按图标拖动排序 ---------- */
/* 进入拖动的图标浮起来（放大 + 投影），其余图标在 grid 里自动让位 */
.wb-item.wb-drag {
  opacity: .92;
  transform: scale(1.1);
  box-shadow: 0 10px 26px rgba(20, 40, 70, .28);
  z-index: 5;
  position: relative;
  background: #fff;
  transition: transform .12s ease;
}
.wb-grid .wb-item { transition: transform .15s ease; }
/* 「时间 / 提醒 / 日期」小标签不被挤成竖排 */
.note-add .note-date, .note-edit .note-date { white-space: nowrap; }
/* 手机上加时间和提醒两个输入后表单会很长：让时间/提醒各自一行，输入框撑满 */
@media (max-width: 820px) {
  .note-add .note-date, .note-edit .note-date { flex: 1 1 100%; }
  .note-time-in { width: calc(50% - 14px); }
  .note-remind-sel { width: 100%; }
}

/* ---------- 手机端页头压成一行 ----------
   窄屏上顶栏原来会换行成两行（第一行只剩个「产线」，第二行只剩用户名），
   又空又占地方。手机上砍掉用不上的东西，一行放得下：
   「已同步时间 / 返回完整统计 / 刷新统计 / ←→ 历史」都不要（底部导航能切页），
   只留 产线红块 + 页面标题 + 用户胶囊。 */
@media (max-width: 820px) {
  .panel-head, .stats-head {
    flex-wrap: nowrap;
    row-gap: 0;
    padding: 5px 10px;
  }
  .panel-head .brand, .stats-head .brand { gap: 8px; padding-right: 10px; }
  .panel-head .brand-mark, .stats-head .brand-mark { width: 28px; height: 28px; border-radius: 7px; font-size: 10px; }
  .panel-head .brand-text h1, .stats-head .brand-text h1 { font-size: 14px; }
  .panel-head .hist-btns, .stats-head .hist-btns { display: none; }
  .panel-head .stats-actions, .stats-head .stats-actions { display: none; }
  .panel-head .save-state, .stats-head .save-state { display: none; }
  .panel-head .topbar-actions, .stats-head .topbar-actions { gap: 6px; }
  .panel-head .topbar-user, .stats-head .topbar-user { height: 28px; padding: 0 8px; font-size: 12px; gap: 6px; }
  .panel-head .topbar-sep, .stats-head .topbar-sep { display: none; }
}

/* 工作台的红色顶栏同理压成一行：
   导入 / 导出 / 新建 / 退出这些按钮「我的」页和工作台宫格里都有入口，
   手机上顶栏只留 产线红块 + 标题 + 头像胶囊，两行变一行 */
@media (max-width: 820px) {
  .topbar { flex-direction: row; align-items: center; flex-wrap: nowrap; padding: 5px 10px; gap: 8px; }
  .topbar .hist-btns, .topbar .save-state, .topbar .topbar-sep { display: none !important; }
  .topbar #btnImportExcel, .topbar #btnImport, .topbar #btnExportJson,
  .topbar #btnExportExcel, .topbar #btnNewProject, .topbar #btnMyTasks,
  .topbar #btnApprovals, .topbar #btnAudit, .topbar #btnChangePwd,
  .topbar #btnUserAdmin, .topbar #btnTemplate, .topbar #btnOutputTpl,
  .topbar #btnLogout { display: none !important; }
  .topbar .brand { gap: 8px; }
  .topbar .brand-mark { width: 28px; height: 28px; border-radius: 7px; font-size: 10px; }
  .topbar .brand-text h1 { font-size: 14px; }
  .topbar .topbar-actions { flex: 1 1 auto; justify-content: flex-end; gap: 6px; }
  .topbar .topbar-user { height: 28px; padding: 0 8px; font-size: 12px; }
}

/* ---------- 推进表 / 详细计划表：整行按状态填色（Excel 风格） ----------
   四种状态对应截图四色，但都降了饱和度做护眼底色：
   已完成=淡绿、风险预警=淡黄、已拖期=淡红、正常=白。
   规则带 !important 是为了压过 style.css 里「计划完成时间」单元格的旧 !important 色；
   「计划完成时间」那一格再深一档，扫一眼就知道卡在哪个日期上。
   .proj-cell（序号/项目集/项目名称/简介/负责人/类型这些跨行合并格）不参与染色，
   项目信息列始终保持白底，状态色只染业务活动那部分列。 */
#planTable tr.plan-row > td:not(.proj-cell),
#stageTable tbody tr > td { background: #fff; }
#planTable tr.row-done > td:not(.proj-cell),
#stageTable tr.row-done > td { background: #e4f3dc !important; }
#planTable tr.due-soon > td:not(.proj-cell),
#stageTable tr.due-soon > td { background: #fff7c8 !important; }
#planTable tr.due-overdue > td:not(.proj-cell),
#stageTable tr.due-overdue > td { background: #fce1de !important; }
#planTable tr.due-soon > td.due-soon,
#stageTable tr.due-soon > td.due-soon { background: #fdf0a8 !important; }
#planTable tr.due-overdue > td.due-overdue,
#stageTable tr.due-overdue > td.due-overdue { background: #f7c6c1 !important; }
#planTable tr.row-done > td.due-done,
#stageTable tr.row-done > td.due-done { background: #d2ebc8 !important; }
/* 导入待确认行：优先级最高（比状态色更像"必须先处理"），保留整行标红 */
#planTable tr.plan-row.row-warn > td:not(.proj-cell),
#stageTable tr.row-warn > td { background: #fbdcd7 !important; }
/* ---------- 审批「查看改动」的对比模式：改动行蓝色 ----------
   修改行 = 淡蓝，新增行 = 偏绿的蓝，删除行 = 浅红（跟对比弹窗同语义）；
   改动过的格子再深一档蓝，悬停显示改动前的值（title 由行渲染输出） */
#stageTable tr.row-diff > td { background: #dcebfa !important; }
/* 新增行也用同一种淡蓝：整页刷成绿色像「全选高亮」，具体是新增还是修改
   由行下方对照里的「新增」红字说明 */
#stageTable tr.row-diff.row-diff-add > td { background: #dcebfa !important; }
#stageTable tr.row-diff.row-diff-del > td { background: #fbe3e0 !important; }
#stageTable tr.row-diff > td.diff-cell { background: #b0d2f2 !important; }
/* 兜底：style.css 里还有一批不带表 id 的通用行色（tr.row-done > td / tr.due-overdue > td…），
   上面加了 :not(.proj-cell) 之后合并格会回落到那些旧色，这里统一压回白底，
   包括 hover 与冻结列（sticky 需要不透明底色） */
#planTable td.proj-cell,
#planTable tr:hover > td.proj-cell,
#planTable tr.row-done > td.proj-cell,
#planTable tr.due-soon > td.proj-cell,
#planTable tr.due-overdue > td.proj-cell,
#planTable tr.row-filled > td.proj-cell,
#planTable tr.row-warn > td.proj-cell { background: #fff !important; }

/* 单击选中：上下蓝边线 + 左侧粗蓝条，跟四种状态色一眼区分开。
   普通白行再加淡蓝底；有状态色的行保留原色——选中的同时仍能看出
   哪些行拖期 / 预警（box-shadow 不占布局空间，行高不会跳）。 */
#planTable tr.plan-row.is-sel > td {
  box-shadow: inset 0 2px 0 #1f5fa8, inset 0 -2px 0 #1f5fa8;
}
#planTable tr.plan-row.is-sel:not(.row-done):not(.due-soon):not(.due-overdue):not(.row-warn) > td:not(.proj-cell) {
  background: #cfe3f8 !important;
}
#planTable tr.plan-row.is-sel > td:first-child {
  box-shadow: inset 4px 0 0 #1f5fa8, inset 0 2px 0 #1f5fa8, inset 0 -2px 0 #1f5fa8;
}
/* hover 只对普通白行生效（:not 排除状态行与项目信息合并格，免得把底色盖掉） */
#planTable tr.plan-row:not(.row-done):not(.due-soon):not(.due-overdue):not(.row-warn):not(.is-sel):hover > td:not(.proj-cell),
#stageTable tbody tr:not(.row-done):not(.due-soon):not(.due-overdue):not(.row-warn):not(.row-diff):hover > td {
  background: #f2f6fa;
}

/* ---------- Excel 感：外框粗一圈、全格细实线、表头浅灰 ----------
   原来的格线是 --line（#e3e8ef 太浅，打印/投屏几乎看不见）。 */
#planTable, #stageTable { border: 2px solid #8296ab; }
#planTable th, #planTable td,
#stageTable th, #stageTable td {
  border-right: 1px solid #b4c0cd;
  border-bottom: 1px solid #b4c0cd;
}
#planTable thead th, #stageTable thead th {
  background: #edf1f6;
  border-bottom: 2px solid #8296ab;
}
