/* ============================================================
   design-v5.css · 视觉系统 v5（可操作性修复，2026-09-23）
   ------------------------------------------------------------
   本文件只做三件事，不覆盖 v1–v4 的业务语义：
     1) 导航一律在顶部且吸顶（手机版是一条可横向滑动的页签条），底部导航下线；
     2) 横向溢出归零（长文本允许换行，宽块只在自身容器内横滑）；
     3) 信息密度收紧：顶栏压成一行、KPI/结论带/表格行高收紧、
        大块默认折叠（点击展开），单页高度控制在 2 屏（桌面）/4 屏（手机）内。
   约束：不改鉴权、不改客户只读隔离、不动任何数据与接口。
   ============================================================ */

:root{
  --top-h:44px;        /* 顶栏实测高度（app.js 写入），用于页签条吸顶偏移 */
  --nav-h:44px;        /* 页签条目标高度 */
  --tbl-max:340px;     /* 表格容器最大高度（超出在容器内滚动） */
  --chart-bd-max:150px;/* 图表主体最大高度 */
  --list-max:340px;    /* 长列表（主题/档案卡）最大高度 */
}

/* ============================================================
   1 · 顶栏：压缩成一行紧凑条（首屏让位给结论）
   ============================================================ */
header.top{
  position:sticky;top:0;z-index:32;
  padding:4px 12px;gap:8px;align-items:center;flex-wrap:nowrap;
  min-height:0;overflow:hidden;   /* 顶栏永远不撑宽页面（被强制成窄窗口时自动裁切，不产生横向滚动） */
}
header.top .brand{gap:6px;min-width:0;flex:0 1 auto;overflow:hidden}
header.top .brand .logo{height:18px;width:auto;display:block}
header.top .brand h1{font-size:12.5px;line-height:1.25;white-space:nowrap;margin:0}
header.top .brand .sub{
  font-size:11px;color:var(--fg2);white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis;max-width:18ch;
}
header.top .topinfo{
  gap:5px;font-size:11px;flex:1 1 auto;min-width:0;
  flex-wrap:wrap;align-items:center;line-height:1.25;
}
header.top .topinfo .small{padding:1px 6px;font-size:11px;min-height:0;line-height:1.6;white-space:nowrap}
header.top select,header.top input{padding:1px 6px;font-size:11.5px;min-height:0;height:auto;line-height:1.6}
header.top .projsel{gap:4px;font-size:11px;align-items:center;flex:0 1 auto;min-width:0;white-space:nowrap}
header.top .projsel select{max-width:190px;min-width:0}
/* 时间与口径：数字一律保留，空间不够时先让「口径/上次监测」换省略号，绝不让时间消失 */
header.top #dataAsOf,header.top #viewChip{flex:0 0 auto}
header.top #lastRun,header.top #projMeta{font-size:11px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:0 1 auto;min-width:0}
header.top #progress{font-size:11px}
body.is-desktop header.top .topinfo,body.is-tablet header.top .topinfo{flex-wrap:nowrap}
.dataasof{font-size:11px;padding:1px 7px;white-space:normal}   /* 窄屏允许换行：横向溢出归零 */
.dataasof .asof-short{display:none}

/* ============================================================
   2 · 页签导航：顶部 + 吸顶 + 紧凑（电脑版换行、手机版横向滑动）
   ============================================================ */
.tabs{
  position:sticky;top:var(--top-h,44px);z-index:31;
  display:flex;flex-wrap:wrap;align-items:center;gap:4px;
  padding:4px 12px;min-height:var(--nav-h);
  background:var(--card);border-bottom:1px solid var(--line);
  backdrop-filter:saturate(1.1);
  box-shadow:0 1px 3px rgba(20,22,26,.04);
}
.tab{
  padding:6px 12px;font-size:12.5px;font-weight:600;line-height:1.15;
  border-radius:var(--r-pill);min-height:30px;flex:0 0 auto;
  border:1px solid transparent;background:transparent;color:var(--fg2);
  white-space:nowrap;
}
.tab:hover{border-color:var(--brand-200);color:var(--brand-deep)}
.tab.active{
  box-shadow:none;background:var(--brand-wash);color:var(--brand-deep);
  border-color:var(--brand-200);font-weight:800;
}
.tabgroup{
  padding:2px 8px;font-size:10.5px;flex:0 0 auto;
}
/* 长按/悬浮显示完整页签名（位置由 app.js 贴着被指页签算） */
.tab-tip{
  position:fixed;z-index:80;top:0;left:0;
  transform:translateX(-50%);
  background:#1b1c20;color:#fff;font-size:12.5px;font-weight:600;
  padding:7px 12px;border-radius:var(--r-pill);box-shadow:var(--sh-3);
  max-width:88vw;text-align:center;pointer-events:none;
}
.tab-tip.hidden{display:none}
/* 回到顶部（底部导航下线后的替代小功能，不是导航入口） */
.totop{
  position:fixed;right:12px;bottom:calc(12px + env(safe-area-inset-bottom,0px));z-index:35;
  padding:6px 10px;font-size:11.5px;font-weight:700;border-radius:var(--r-pill);
  background:color-mix(in srgb,var(--card) 92%,transparent);border:1px solid var(--line);
  color:var(--fg2);backdrop-filter:blur(8px);box-shadow:var(--sh-2);
}
.totop.hidden{display:none}

/* 手机版：页签条 = 一条可横向滑动的条（全部页签都能滑到，不依赖任何抽屉） */
body.is-mobile .tabs{
  display:flex;flex-wrap:nowrap;overflow-x:auto;overflow-y:hidden;
  -webkit-overflow-scrolling:touch;scrollbar-width:none;
  gap:4px;padding:4px 10px;min-height:var(--nav-h);
  max-width:100%;
}
body.is-mobile .tabs::-webkit-scrollbar{height:0;display:none}
body.is-mobile .tab{padding:6px 11px;font-size:12.5px;min-height:32px}
body.is-mobile .tabgroup{font-size:10px;padding:2px 6px;border-left-width:2px}
body.is-mobile main{
  padding:8px 12px calc(56px + env(safe-area-inset-bottom,0px));
}
/* 底部导航彻底下线（v4 里的 display:grid 一并失效） */
.bottomnav,#bottomNav{display:none!important}
body.is-mobile .bottomnav,body.is-mobile #bottomNav{display:none!important}

/* ============================================================
   3 · 密度：结论带 / 一句话总结 / KPI / 说明段 / 表格行高
   ============================================================ */
main{padding:12px 14px 40px}
h2{margin:var(--sp-3) 0 6px;font-size:12.5px}
h3{font-size:13px;margin:var(--sp-2) 0 6px}
p.muted,.muted{line-height:1.55}
main > .panel > p.muted,.notice p,.state p{max-width:82ch;margin:4px 0 6px}

/* 一句话总结：结论一行不漏，纵向收紧 */
.onesum{padding:10px 12px;margin:0 0 8px}
.onesum-hd{gap:8px;margin-bottom:4px}
.onesum-verdict{font-size:22px;line-height:1.15}
.onesum-note{margin:0 0 6px;line-height:1.5;font-size:13px;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.onesum-chips{gap:6px}
.onesum .chip{padding:2px 8px;font-size:11.5px}

/* 结论带：压缩为「一行主结论 + 一行依据」 */
.concl{padding:10px 12px;gap:var(--sp-3);margin-bottom:10px}
.concl-main{padding-left:6px}
.concl-kicker{font-size:10.5px;margin-bottom:2px}
.concl-value{font-size:clamp(24px,3.2vw,38px);line-height:1.05}
.concl-label{font-size:12px;margin-top:3px;line-height:1.4}
.concl-side{gap:6px}
.concl-delta{padding:4px 8px}
.concl-delta b{font-size:13px}
.concl-note{font-size:12px;line-height:1.5;max-width:70ch;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.concl-hi{font-size:12px;line-height:1.45;padding:4px 8px;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}

/* KPI：去掉多余内边距，首屏能看到 3–6 个数字 */
.kpis{gap:6px;margin:6px 0 4px}
.kpi{padding:7px 9px 8px;border-radius:10px}
.kpi .v{font-size:calc(var(--fs-data) * .72);line-height:1.05}
.kpis > .kpi:first-child .v{font-size:calc(var(--fs-data) * .82)}
.kpi .k{font-size:11.5px;margin-top:3px;line-height:1.35}
.kpi .n{font-size:11px;margin-top:2px;line-height:1.4;color:var(--fg2)}
.kpis > .kpi:first-child .n{font-size:11px}
.kpi .conf-line{margin-top:3px;gap:4px}
.kpi-u{font-size:.5em;font-weight:700;margin-left:1px}
.kpi .conf{font-size:10.5px;padding:1px 6px}
.kpi .sample-line{font-size:10.5px}

/* 表格：行高收紧 + 容器限高（超出在容器内滚动，不拉长整页） */
table{font-size:12.5px}
th,td{padding:5px 8px;line-height:1.4}
th{font-size:11.5px}
.tablewrap{max-height:var(--tbl-max);overflow:auto;-webkit-overflow-scrolling:touch}
.tblnote{font-size:11px;color:var(--fg2);margin:2px 0 6px}
.heat-wrap{max-height:240px;overflow:auto}

/* 图表：主体限高，卡片高度统一 */
.chart{padding:10px 12px}
.chart-hd{font-size:12.5px;margin-bottom:6px}
.chart-bd{max-height:var(--chart-bd-max);overflow:auto}
.bar-row{margin:3px 0;font-size:11.5px;grid-template-columns:92px 1fr 88px;gap:6px}
.charts{gap:8px}
.legend{gap:8px;margin-top:4px;font-size:11px}

/* 长列表 / 卡片网格：限高，避免一页拉出十几屏 */
.theme-list{max-height:var(--list-max);overflow:auto;padding-right:2px;gap:8px}
.theme-item{padding:10px 12px}
.prof-grid{max-height:360px;overflow:auto;padding-right:2px;gap:8px}
.sent-top{gap:8px}
.quote-cards{gap:8px}
.coverage-mini{margin:6px 0 8px}
.cov-legend{gap:10px;font-size:10.5px;margin-top:6px}
.cov-bar{height:10px}
.runbar,.filters,.settings{gap:6px;margin:4px 0 6px}
.runbar button,.runbar .btn,.filters .btn{padding:5px 10px;font-size:12px}
.filters input,.filters select,.runbar select{padding:4px 8px;font-size:12px;min-height:30px}
.effectform{gap:6px;margin:6px 0}
.effectform textarea{min-height:80px}
.notice{padding:10px 12px;margin:6px 0}
.gaps{margin:6px 0;padding-left:18px}
footer.foot{padding:10px 14px;font-size:11px;gap:8px}

/* ============================================================
   4 · 折叠块（点击展开明细；默认只露一行结论）
   ============================================================ */
details.fold7{
  border:1px solid var(--line);border-radius:var(--r-ctl);
  background:var(--bg);margin:6px 0;padding:0;
}
details.fold7 > summary{
  cursor:pointer;list-style:none;min-height:34px;
  display:flex;align-items:center;gap:6px;flex-wrap:wrap;
  padding:6px 10px;font-size:12px;font-weight:600;color:var(--fg);
}
details.fold7 > summary::-webkit-details-marker{display:none}
details.fold7 > summary::before{
  content:"▸";color:var(--brand);font-weight:800;font-size:11px;flex:0 0 auto;
}
details.fold7[open] > summary::before{content:"▾"}
details.fold7[open] > summary{border-bottom:1px solid var(--line);background:var(--brand-wash)}
details.fold7 > .fold7-bd{padding:8px 10px 10px}
details.fold7 .fold7-digest{font-weight:400;color:var(--fg2);font-size:11.5px}

/* 自己验证：每道题默认只露「题目 + 我方占有率 + 样本」，点开看明细 */
details.self7{border:1px solid var(--line);border-radius:var(--r-card);background:var(--card);margin:0 0 8px}
details.self7 > summary{
  cursor:pointer;list-style:none;display:flex;gap:8px;align-items:baseline;
  padding:9px 12px;font-size:12.5px;
}
details.self7 > summary::-webkit-details-marker{display:none}
details.self7 > summary::before{content:"▸";color:var(--brand);font-weight:800;font-size:11px}
details.self7[open] > summary::before{content:"▾"}
details.self7[open] > summary{border-bottom:1px solid var(--line)}
details.self7 .self7-no{
  flex:0 0 auto;width:20px;height:20px;border-radius:50%;
  display:inline-flex;align-items:center;justify-content:center;
  background:var(--brand-wash);color:var(--brand-deep);font-weight:800;font-size:10.5px;
  border:1px solid var(--brand-200);
}
details.self7 .self7-q{
  flex:1 1 auto;min-width:0;font-weight:600;line-height:1.35;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
details.self7 .self7-m{flex:0 0 auto;font-variant-numeric:tabular-nums;font-weight:800;color:var(--brand-deep);font-size:12px}
details.self7 > .self-card{border:0;border-radius:0;box-shadow:none;margin:0;padding:10px 12px}
details.self7 .self-qbox{padding:8px 10px;margin-bottom:8px}
details.self7 .self-hd{margin-bottom:6px}
details.self7 .self-metrics{margin-bottom:6px}
details.self7 .dim-ev,details.self7 .theme-ev{margin-top:6px}

/* 口径说明折叠：默认一行，点开看完整口径 */
details.fold7.fold7-note > summary{font-size:11.5px;min-height:30px}
details.fold7.fold7-note > .fold7-bd{font-size:11.5px;line-height:1.6;color:var(--fg2)}

/* ============================================================
   5 · 手机版密度（单页 ≤4 屏）
   ============================================================ */
body.is-mobile{
  font-size:14px;
  --fs-1:12.5px; --fs-2:13.5px; --fs-3:14px;
  --tbl-max:280px; --chart-bd-max:120px; --list-max:300px;
}
/* 手机版顶栏：真的压成「一行紧凑条」——项目选择器 / 口径与记录数 / 数据截至 / 上次监测
   全部保留在这一行里，行内可横滑（不换行、不撑高），不吸顶：顶部永久占位只留给页签条。 */
body.is-mobile header.top{
  position:static;flex-direction:row;flex-wrap:nowrap;align-items:center;gap:6px;padding:5px 10px;
}
body.is-mobile header.top .brand{gap:5px;flex:0 0 auto;align-items:center}
body.is-mobile header.top .brand h1,body.is-mobile header.top .brand .sub{display:none}  /* 项目名已在选择器里，不重复占行 */
body.is-mobile header.top .topinfo{
  flex:1 1 auto;min-width:0;display:flex;flex-wrap:nowrap;align-items:center;gap:6px;
  overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;scrollbar-width:none;
  font-size:11px;padding-bottom:1px;
}
body.is-mobile header.top .topinfo::-webkit-scrollbar{height:0;display:none}
body.is-mobile header.top .topinfo > *{flex:0 0 auto!important;max-width:none!important;order:0!important}
body.is-mobile header.top .projsel{width:auto}
body.is-mobile #projSel{width:auto;min-height:30px;font-size:11.5px;padding:2px 6px;max-width:190px}
body.is-mobile header.top #btnNewProj{min-height:30px;padding:1px 7px;font-size:11px}
body.is-mobile header.top #viewChip{min-height:22px}
body.is-mobile header.top #projMeta,body.is-mobile header.top #lastRun,body.is-mobile header.top #dataAsOf{
  display:inline;font-size:10.5px;padding:1px 6px;white-space:nowrap;
}
body.is-mobile .dataasof{display:inline-flex;gap:6px}
body.is-mobile .dataasof .asof-full{display:none}
body.is-mobile .dataasof .asof-short{display:inline}
body.is-mobile .tabs{top:0}   /* 顶栏滚走，只有页签条吸顶 */
body.is-mobile .kpis{grid-template-columns:repeat(2,minmax(0,1fr))}
body.is-mobile .kpi{padding:6px 8px 7px}
body.is-mobile .kpi .v{font-size:22px}
body.is-mobile .kpis > .kpi:first-child .v{font-size:24px}
body.is-mobile .kpi .k{font-size:11px}
body.is-mobile .kpi .n{font-size:10.5px}
body.is-mobile h2{font-size:12.5px;margin:10px 0 5px}
/* 手机版：结论带横向两段压缩，不竖排撑高 */
body.is-mobile .concl{flex-direction:row;flex-wrap:wrap;padding:9px 10px;gap:8px}
body.is-mobile .concl-main{flex:1 1 46%;min-width:140px}
body.is-mobile .concl-side{flex:1 1 46%;min-width:140px;width:auto}
body.is-mobile .concl-value{font-size:clamp(24px,8vw,32px)}
body.is-mobile .concl-label{font-size:11.5px}
body.is-mobile .concl-note{-webkit-line-clamp:3}
body.is-mobile .concl-hi{-webkit-line-clamp:3}
body.is-mobile .onesum-verdict{font-size:20px}
/* 手机版：可点元素仍 ≥40px，但不许把页面撑高 */
body.is-mobile button,body.is-mobile .btn,body.is-mobile select,body.is-mobile input,
body.is-mobile textarea,body.is-mobile .tab,body.is-mobile summary{min-height:38px}
body.is-mobile .tab{min-height:32px}
body.is-mobile .chip,body.is-mobile .conf{min-height:22px}
body.is-mobile .self-metrics{grid-template-columns:1fr 1fr;gap:6px}
body.is-mobile .self-metric{padding:7px 9px}
body.is-mobile .self-metric .v{font-size:20px}
body.is-mobile .dim-grid{grid-template-columns:1fr 1fr;gap:6px;max-height:760px;overflow:auto}
body.is-mobile .prof-grid{grid-template-columns:1fr;max-height:300px}
body.is-mobile .quote-cards{max-height:640px;overflow:auto}
body.is-mobile .tablewrap table{min-width:520px}
body.is-mobile .tablewrap{max-height:280px}
body.is-mobile .heat-wrap{max-height:220px}
body.is-mobile details.fold7 > summary{padding:7px 9px;font-size:12px}
body.is-mobile .totop{display:block}
body.skin-client.is-mobile .concl-value{font-size:clamp(24px,8vw,32px)}

/* 电脑版：KPI 一行 6 个、图表两列起步，卡片收紧 */
body.is-desktop .kpis{grid-template-columns:repeat(6,minmax(0,1fr));gap:6px}
body.is-desktop .charts{grid-template-columns:repeat(auto-fit,minmax(330px,1fr))}
body.is-desktop th,body.is-desktop td{padding:5px 8px}
body.is-desktop .tab{padding:6px 13px}
body.is-tablet .kpis{grid-template-columns:repeat(3,minmax(0,1fr))}

/* ============================================================
   6 · 客户只读端（body.skin-client）
   v2 的交付皮肤里 `.tabs` 是 static + 居中：窄屏上第一个页签会被挤到
   负坐标、滑动也回不来（点不到）。这里统一成「吸顶 + 左对齐」，
   并把过大的内边距收回来 —— 只动展示，内容与隔离策略一字不改。
   ============================================================ */
body.skin-client .tabs{position:sticky;top:var(--top-h,44px);z-index:31;justify-content:flex-start}
body.is-mobile body.skin-client .tabs{top:0}
body.skin-client .tab{font-size:12.5px;padding:6px 12px}
body.skin-client .kpis{gap:6px}
body.skin-client .kpi{padding:9px 10px 10px}
body.skin-client .kpi .v{font-size:calc(var(--fs-data) * .8)}
body.skin-client .kpis > .kpi:first-child .v{font-size:calc(var(--fs-data) * .95)}
body.skin-client .chart{padding:10px 12px}
body.skin-client .concl{grid-template-columns:minmax(0,1fr) minmax(0,1.05fr);gap:var(--sp-3);padding:10px 12px}
body.skin-client .concl-value{font-size:clamp(28px,3.4vw,42px)}
body.skin-client h2{font-size:13px;margin:var(--sp-3) 0 6px}
body.skin-client main{max-width:1400px;padding:12px 14px 44px}
body.is-mobile body.skin-client main{padding:8px 12px calc(54px + env(safe-area-inset-bottom,0px))}
body.skin-client.is-mobile .concl-value{font-size:clamp(24px,8vw,32px)}
body.skin-client.is-mobile .onesum-verdict{font-size:20px}
body.skin-client.is-mobile .concl-note,body.skin-client.is-mobile .concl-hi{-webkit-line-clamp:2}
/* 客户只读端顶部的报告头：手机上压紧（它只是抬头，不是结论） */
body.is-mobile .report-head{padding:6px 8px;margin-bottom:6px;gap:4px}
body.is-mobile .report-head h2{font-size:15px;margin:2px 0 0;line-height:1.3}
body.is-mobile .report-head .rh-name{font-size:10px;letter-spacing:.08em}
body.is-mobile .report-head .rh-meta{font-size:10.5px;margin-top:2px}
body.is-mobile .report-head .rh-tags{gap:4px}
body.is-mobile .report-head .rh-tags span{padding:2px 7px;font-size:10.5px}
body.is-mobile .report-head .rh-logo{display:none}   /* 手机版抬头不重复放 logo（顶栏已有） */
/* 电脑版客户只读端：抬头与图表网格也收一收，单页高度对齐 2 屏目标 */
body.is-desktop.skin-client .report-head{padding:10px 12px;margin-bottom:10px}
body.is-desktop.skin-client .report-head h2{font-size:18px}
body.skin-client .charts{grid-template-columns:repeat(auto-fit,minmax(320px,1fr));gap:8px}
body.is-desktop.skin-client .kpi{padding:8px 9px 9px}
body.is-desktop.skin-client .kpi .v{font-size:calc(var(--fs-data) * .72)}
body.is-desktop.skin-client .kpis > .kpi:first-child .v{font-size:calc(var(--fs-data) * .86)}

@media (prefers-color-scheme: dark){
  .tab-tip{background:#f2f2f5;color:#17181c}
  header.top, .tabs{background:var(--card)}
}

/* ============================================================
   4 · 总览首屏修复 v6（2026-09-23）
      A) 卡片头部与正文严禁重叠（含悬浮提示条越界）
      B) KPI 卡：同行等高、每行 3 张（恰好 4 张时一行放满）、卡片紧凑
      C) 操作行（监测范围 / 发起监测 / 报告）已移到 KPI 区之后（见 index.html）
   ============================================================ */

/* --- A：卡片头部与正文之间只靠 margin 撑开，任何情况下不得相交 ------ */
.onesum-hd{
  display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  margin:0 0 8px;min-height:0;line-height:1.25;
}
.onesum-hd > *{margin:0;min-width:0}
.onesum-kicker{display:block;line-height:1.25}
.onesum-verdict{line-height:1.15}
.onesum-note{display:-webkit-box;margin:0 0 8px;line-height:1.5}
/* 同类型卡片头部（结论带 / 图表 / 维度卡）同样收紧，杜绝负边距或绝对定位压字 */
.concl-kicker,.chart-hd,.dim-hd,.prof-h4{position:static;line-height:1.3;margin-top:0}
.concl-kicker{margin-bottom:4px}
.chart-hd{margin-bottom:6px}
.dim-hd{margin-bottom:6px}

/* --- B：KPI 卡 ------------------------------------------------------ */
/* 卡内只放 .v/.k/.n 三块文本，纵向 flex 让内容各自贴合顶部；
   同行等高由 grid 的 align-items:stretch + grid-auto-rows:1fr 保证（高度差恒为 0）。 */
.kpis{align-items:stretch;grid-auto-rows:1fr}
.kpi{
  display:flex;flex-direction:column;min-width:0;min-height:0;height:auto;
  align-self:stretch;overflow:hidden;
}
/* 超长文本截断：折行/文案长短都不再改变卡片高度 */
.kpi .v{flex:0 0 auto}
.kpi .k,.kpi .n{overflow:hidden;overflow-wrap:anywhere;
  display:-webkit-box;-webkit-box-orient:vertical}
.kpi .k{-webkit-line-clamp:2}
.kpi .n{-webkit-line-clamp:3}

/* 电脑版：每行 3 张；恰好 4 张时 4 张一行放满。
   取消 v2 的「首卡跨 2 列」——那正是 5+1 断行 + 右侧大片空白的来源。 */
body.is-desktop .kpis,body.is-tablet .kpis{grid-template-columns:repeat(3,minmax(0,1fr));gap:6px}
body.is-desktop .kpis > .kpi:first-child,
body.is-tablet .kpis > .kpi:first-child{grid-column:auto;max-width:none}
body.is-desktop .kpis:has(> .kpi:nth-child(4):last-child),
body.is-tablet .kpis:has(> .kpi:nth-child(4):last-child){grid-template-columns:repeat(4,minmax(0,1fr))}
body.is-desktop .kpis:has(> .kpi:nth-child(2):last-child),
body.is-tablet .kpis:has(> .kpi:nth-child(2):last-child){grid-template-columns:repeat(2,minmax(0,1fr))}
body.is-desktop .kpis:has(> .kpi:first-child:last-child),
body.is-tablet .kpis:has(> .kpi:first-child:last-child){grid-template-columns:minmax(0,1fr)}
/* 电脑版首卡不再跨界，字号与其余卡片对齐（同一行里数字大小不一致最像排版事故） */
body.is-desktop .kpis > .kpi:first-child .v,
body.skin-client .kpis > .kpi:first-child .v{font-size:calc(var(--fs-data) * .72)}
body.is-desktop .kpis > .kpi:first-child .n{font-size:11px}

/* 手机版：双列，同样等高、同样取消首卡跨列 */
body.is-mobile .kpis{grid-template-columns:repeat(2,minmax(0,1fr));gap:6px}
body.is-mobile .kpis > .kpi:first-child{grid-column:auto;padding:6px 8px 7px}
body.is-mobile .kpis > .kpi:first-child .v{font-size:22px}
body.is-mobile .kpi .n{-webkit-line-clamp:3}

/* --- C：操作行移到 KPI 之后，与上方数字留出固定间距 ------------------ */
.runbar{margin:10px 0 12px}
body.is-mobile .runbar{margin:8px 0 10px}

/* ============================================================
   5 · 顶栏「当前登录身份」（2026-09-23）
      - 电脑版：姓名 · 角色（如「杜碧涵 · 管理员」「主账号 · 管理员」）
      - 手机版：只留姓名首字小头像（空间紧），长按/悬浮看全名与说明
      - 客户视图：始终显示完整「客户视图（只读）」，且不含任何员工姓名
      - 任何情况下都不显示口令
   ============================================================ */
.identity{
  display:inline-flex;align-items:center;gap:5px;
  font-weight:700;color:var(--brand-deep);
  background:var(--brand-wash);border-color:var(--brand-200);
  cursor:default;user-select:none;
}
.identity .id-avatar{
  display:none;flex:0 0 auto;align-items:center;justify-content:center;
  width:18px;height:18px;border-radius:50%;
  background:var(--brand);color:#fff;font-size:10.5px;font-weight:800;line-height:1;
}
.identity .id-label{white-space:nowrap}
.identity.is-client{
  color:var(--fg2);background:var(--bg);border-color:var(--line);
}
.identity[hidden]{display:none}   /* 身份没拿到之前不占位，也不显示假身份 */
body.is-desktop .identity,body.is-tablet .identity{font-size:11.5px}
/* 手机版：只显示首字头像（客户视图例外——「只读」这两个字必须看得见） */
body.is-mobile .identity{padding:2px 6px;gap:0}
body.is-mobile .identity .id-label{display:none}
body.is-mobile .identity .id-avatar{display:inline-flex}
body.is-mobile .identity.is-client{padding:2px 8px;gap:5px}
body.is-mobile .identity.is-client .id-label{display:inline;font-size:11px}
body.is-mobile .identity.is-client .id-avatar{display:none}

/* ============================================================
   6 · 协作痕迹（2026-09-23）
      - 小字一行「最后修改：谁 · 时间」贴在可编辑对象上
      - 点顶栏身份名弹出「协作记录」面板（只留痕迹、不加锁）
      - 客户只读端：入口与姓名整块移除（app.js applyClientMode）
   ============================================================ */
.lastedit{
  display:inline-block;font-size:10.5px;line-height:1.35;color:var(--fg2);
  background:var(--bg);border:1px solid var(--line);border-radius:var(--r-pill);
  padding:0 6px;white-space:nowrap;font-variant-numeric:tabular-nums;
}
.lastedit.hidden{display:none}
.lastedit-line{margin:6px 0 0;font-size:10.5px;color:var(--fg2)}
tr td .lastedit{margin-top:2px}
.qinput{width:100%;min-width:220px;font-size:12px}
.qrow-btns{white-space:nowrap}
.qrow-btns button{margin-right:4px}

/* ---------- ① 题目输入口：范围条 + 表格列宽（2026-10-08 碧涵需求 #3/#4） ----------
   诉求：题目内容尽量完整显示；意图/层级/采样等右移并压缩占用空间；题库按项目过滤。
   做法：固定列宽（table-layout:fixed），题目列吃掉剩余宽度且用自适应 textarea 换行显示全文。 */
.q-scope{
  display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap;
  margin:2px 0 8px;padding:8px 10px;background:var(--brand-wash,#faf7fd);
  border:1px solid var(--line);border-left:3px solid var(--brand,#8b5cf6);border-radius:8px;
}
.q-scope-l,.q-scope-r{display:flex;align-items:center;gap:8px;flex-wrap:wrap;font-size:11.5px}
.q-scope-t{font-weight:700;color:var(--brand-deep,#4c1d95);font-size:11.5px;letter-spacing:.3px}
.q-scope .muted{font-size:11.5px;color:var(--fg2)}
.q-scope select{min-height:26px;padding:1px 6px;font-size:11.5px;max-width:190px}
.q-scope button.small{min-height:26px;padding:2px 9px;font-size:11.5px}
.seg{display:inline-flex;border:1px solid var(--line);border-radius:999px;overflow:hidden;background:var(--card)}
.seg-b{
  border:0;background:transparent;cursor:pointer;padding:3px 11px;font-size:11.5px;
  color:var(--fg2);display:inline-flex;align-items:center;gap:5px;min-height:0;
}
.seg-b b{font-weight:700;font-variant-numeric:tabular-nums;opacity:.85}
.seg-b.on{background:var(--brand,#8b5cf6);color:#fff}
.seg-b.on b{opacity:1}
#qTable{table-layout:fixed;width:100%}
#qTable col.c-chk{width:30px}
#qTable col.c-intent{width:104px}
#qTable col.c-tier{width:110px}
#qTable col.c-sample{width:58px}
#qTable col.c-state{width:74px}
#qTable col.c-edit{width:132px}
#qTable col.c-act{width:158px}
#qTable td.q-chk,#qTable th.q-chk{text-align:center;padding-left:2px;padding-right:2px}
#qTable .qinput{
  min-width:0;width:100%;font-size:12.5px;line-height:1.45;resize:none;
  overflow:hidden;border:1px solid transparent;background:transparent;padding:2px 4px;
  border-radius:4px;font-family:inherit;white-space:pre-wrap;word-break:break-word;
}
#qTable .qinput:hover{border-color:var(--line);background:var(--card)}
#qTable .qinput:focus{border-color:var(--brand,#8b5cf6);background:var(--card);outline:none;box-shadow:0 0 0 2px rgba(139,92,246,.14)}
#qTable td.q-textcell{padding-right:6px}
#qTable td.q-edit{font-size:10.5px}
#qTable .q-notmine{display:inline-block;margin-top:2px;font-size:10px;color:#B45309;background:#FFF4E0;border-radius:4px;padding:0 5px}
/* 窄屏：意图/层级/采样等右移列不再挤占题目，改为自动换行堆叠 */
@media (max-width:1080px){
  #qTable col.c-edit{width:0}
  #qTable td.q-edit,#qTable th:nth-child(7){display:none}
}

/* ---------- 平台报错说明（原因 + 怎么处理）2026-10-08 碧涵需求 #2 ---------- */
.plat-fix{margin-top:3px;font-size:11px;color:var(--fg2);line-height:1.5}
.plat-raw{margin-top:3px;font-size:10px;color:#9aa1ac;line-height:1.4;word-break:break-all}
#platformStatusTable td .plat-fix{max-width:520px;white-space:normal}

/* 协作记录浮层：贴顶栏下沿、右侧对齐，不遮正文（和页签提示条同一套「不越界」约束） */
.collab{
  position:fixed;z-index:90;top:calc(var(--top-h,44px) + var(--nav-h,44px) + 6px);right:12px;
  width:min(520px,calc(100vw - 24px));max-height:min(60vh,520px);
  display:flex;flex-direction:column;
  background:var(--card);border:1px solid var(--line);border-radius:var(--r-card);
  box-shadow:var(--sh-3);overflow:hidden;
}
.collab.hidden{display:none}
.collab-hd{
  display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  padding:8px 10px;border-bottom:1px solid var(--line);background:var(--brand-wash);
}
.collab-hd b{font-size:13px;color:var(--brand-deep)}
.collab-hd .muted{font-size:10.5px;flex:1 1 auto;min-width:0}
.collab-tip{margin:0;padding:6px 10px;font-size:10.5px;line-height:1.5;color:var(--fg2);border-bottom:1px solid var(--line)}
.collab-list{
  margin:0;padding:4px 0;list-style:none;overflow:auto;-webkit-overflow-scrolling:touch;
  flex:1 1 auto;counter-reset:cl;
}
.collab-list li{
  display:flex;gap:8px;align-items:baseline;flex-wrap:wrap;
  padding:5px 10px;font-size:11.5px;line-height:1.45;border-bottom:1px dashed var(--line);
}
.collab-list li:last-child{border-bottom:0}
.collab-list .cl-who{font-weight:700;color:var(--brand-deep);flex:0 0 auto}
.collab-list .cl-when{font-size:10.5px;color:var(--fg2);font-variant-numeric:tabular-nums;flex:0 0 auto}
.collab-list .cl-what{flex:1 1 100%;color:var(--fg);overflow-wrap:anywhere}
body.skin-client .lastedit,body.skin-client .collab{display:none!important}   /* 客户只读端兜底：不出现协作痕迹 */
body.is-mobile .collab{top:calc(var(--top-h,44px) + var(--nav-h,44px) + 4px);right:8px;left:8px;width:auto;max-height:64vh}
body.is-mobile .collab-list li{font-size:12px}

/* ============================================================
   7 · 执行链路（8 节点）+ 三个输入口（2026-09-23）
      电脑版：横向流水线 + 箭头；手机版：纵向时间轴
   ============================================================ */
.pipe{margin:8px 0 10px}
.pipe-live{
  display:flex;align-items:center;gap:6px;flex-wrap:wrap;
  font-size:11.5px;color:var(--fg2);background:var(--bg);
  border:1px solid var(--line);border-radius:var(--r-pill);
  padding:4px 10px;margin-bottom:8px;
}
.pipe-live b{color:var(--fg)}
.pipe-live .dot{width:8px;height:8px;border-radius:50%;background:var(--line);flex:0 0 auto}
.pipe-live .dot.on{background:var(--ok);box-shadow:0 0 0 3px color-mix(in srgb,var(--ok) 25%,transparent);animation:pulse 1.6s infinite}
@keyframes pulse{50%{opacity:.45}}
.pipe-row{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;align-items:stretch}
.parrow{display:none}
.pnode{
  position:relative;
  display:flex;flex-direction:column;gap:6px;
  background:var(--card);border:1px solid var(--line);border-left:4px solid var(--line);
  border-radius:var(--r-card);padding:8px 9px;min-width:0;
}
/* 节点之间的上下游箭头（每行最后一列不画，避免指向空白） */
.pnode::after{
  content:'→';position:absolute;right:-8px;top:50%;transform:translateY(-50%);
  color:var(--brand);font-weight:800;font-size:14px;pointer-events:none;
}
.pnode:nth-child(4n)::after{display:none}
.pnode .pn-hd{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.pnode .pn-idx{
  width:18px;height:18px;border-radius:50%;flex:0 0 auto;
  display:inline-flex;align-items:center;justify-content:center;
  background:var(--bg);border:1px solid var(--line);font-size:11px;font-weight:800;color:var(--fg2);
}
.pnode .pn-hd h4{margin:0;font-size:12.5px;line-height:1.3;flex:1 1 auto;min-width:0}
.pnode .pn-status{
  font-size:10.5px;font-weight:700;padding:1px 7px;border-radius:var(--r-pill);
  background:var(--bg);border:1px solid var(--line);color:var(--fg2);white-space:nowrap;
}
.pnode .pn-body{display:flex;flex-direction:column;gap:3px}
.pnode .pn-kv{display:flex;gap:6px;align-items:baseline;font-size:11px}
.pnode .pn-kv > span{color:var(--fg2);flex:0 0 auto}
.pnode .pn-kv > b{font-weight:700;min-width:0;overflow-wrap:anywhere}
.pnode .pn-src{font-style:normal;font-size:10px;color:var(--fg2);border:1px dashed var(--line);border-radius:var(--r-pill);padding:0 5px;flex:0 0 auto}
.pnode .pn-sum{font-size:10.5px;line-height:1.45;color:var(--fg2);overflow-wrap:anywhere}
.pnode .pn-err{margin:0;padding-left:16px;font-size:10.5px;line-height:1.45;color:var(--warn-ink)}
.pnode .pn-more{align-self:flex-start;margin-top:auto}
/* 状态色：左边框 + 状态徽标 */
.pnode.st-done{border-left-color:var(--ok)}
.pnode.st-done .pn-status{color:var(--ok-ink);border-color:color-mix(in srgb,var(--ok) 45%,var(--line))}
.pnode.st-run{border-left-color:var(--brand);box-shadow:0 0 0 2px color-mix(in srgb,var(--brand) 18%,transparent)}
.pnode.st-run .pn-status{color:var(--brand-deep);border-color:var(--brand-200);background:var(--brand-wash)}
.pnode.st-fail{border-left-color:var(--warn)}
.pnode.st-fail .pn-status{color:var(--warn-ink);border-color:color-mix(in srgb,var(--warn) 45%,var(--line))}
.pnode.st-pend{border-left-color:var(--line);opacity:.92}
.pnode.st-manual{border-left-color:#8b7ad6}
.pnode.st-manual .pn-status{color:#5b4bb0;border-color:#cfc7ef}
.pnode.st-ready{border-left-color:var(--ok)}
.pnode.st-wait{border-left-color:#d8a13a}
.pnode.st-wait .pn-status{color:#8a6212;border-color:#eccf94}
/* 下钻面板 */
.pipe-detail{margin:6px 0 10px;padding:8px 10px;background:var(--bg);border:1px solid var(--line);border-radius:var(--r-card)}
.pipe-detail .drill-hd{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;margin-bottom:6px}
.pipe-detail .drill-hd b{font-size:12.5px}
.pipe-detail .drill-hd .muted{font-size:10.5px}
.pipe-detail .drill-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:6px}
.pipe-detail .drill-kv{background:var(--card);border:1px solid var(--line);border-radius:var(--r-ctl);padding:5px 8px;display:flex;flex-direction:column;gap:2px}
.pipe-detail .drill-kv span{font-size:10.5px;color:var(--fg2)}
.pipe-detail .drill-kv b{font-size:14px;font-variant-numeric:tabular-nums}
.drill-h4{margin:8px 0 4px;font-size:12px}
.retest-list{margin:0;padding-left:18px;font-size:11.5px;line-height:1.6;max-height:240px;overflow:auto}
.retest-list .rt-no{color:var(--brand-deep);font-weight:700;margin-right:4px}
/* 三个输入口 */
.inputs{margin-top:10px}
.inbox{background:var(--card);border:1px solid var(--line);border-radius:var(--r-card);padding:8px 10px;margin:8px 0}
.inbox h3{margin:0 0 6px;font-size:13px}
.inbox .inrow{display:flex;gap:6px;align-items:center;flex-wrap:wrap;margin-bottom:6px}
.inbox .inrow input,.inbox .inrow select,.inbox .inrow textarea{min-height:0}
.inbox .inrow .inlab{display:inline-flex;align-items:center;gap:4px;font-size:11px;color:var(--fg2)}
.inbox .inrow .inlab input{width:88px}
.inbox textarea.wide{flex:1 1 320px;min-width:200px;min-height:52px}
.inbox .tablewrap{max-height:300px}
.warn-banner{border-color:#e0b360;background:#fdf6e6;color:#7a5410}
.banner--ok{border-color:color-mix(in srgb,var(--ok) 45%,var(--line));background:color-mix(in srgb,var(--ok) 10%,var(--card));color:var(--ok-ink)}
@media (prefers-color-scheme: dark){ .warn-banner{background:#3a2f16;color:#f0d9a8;border-color:#7a6224} }
/* 手机版：纵向时间轴（箭头转成向下） */
body.is-mobile .pipe-row{grid-template-columns:minmax(0,1fr);gap:14px}
body.is-mobile .pnode{max-width:none}
body.is-mobile .pnode::after{content:'↓';right:50%;top:auto;bottom:-12px;transform:translateX(50%)}
body.is-mobile .pnode:nth-child(4n)::after{display:block}
body.is-mobile .pnode:last-child::after{display:none}
body.is-mobile .pnode .pn-body{display:grid;grid-template-columns:1fr;gap:2px}
body.is-mobile .pnode .pn-sum{font-size:11px}
body.is-mobile .inbox .inrow .inlab input{width:100%}

/* --- 本期周期面板 --- */
.sched{background:var(--card);border:1px solid var(--line);border-radius:var(--r-card);padding:8px 10px;margin:8px 0 10px}
.sched-hd{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:4px}
.sched-hd > b{font-size:13px;color:var(--brand-deep)}
.sched-cur{font-size:11.5px;color:var(--fg2)}
.sched-cur b.over{color:var(--warn-ink)}
.sched-badge{font-size:10.5px;font-weight:700;padding:1px 8px;border-radius:var(--r-pill);border:1px solid var(--line);background:var(--bg)}
.sched-badge.ok{color:var(--ok-ink);border-color:color-mix(in srgb,var(--ok) 40%,var(--line))}
.sched-badge.over{color:#fff;background:var(--warn);border-color:var(--warn)}
.sched-note{margin:0 0 6px;font-size:10.5px;line-height:1.5;color:var(--fg2)}
.sched .tablewrap{max-height:470px}
/* 节点说明只留一行，避免「计划日」这一列被注释放大后把表格撑出容器（7 行要能一眼看全） */
.sched td:first-child .muted{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1;overflow:hidden}
.sched th,.sched td{padding:4px 8px;font-size:11.5px;vertical-align:top}
.sched td b{font-size:12px}
.sched .over{color:var(--warn-ink);font-weight:700}
.pn-status.sc-done{color:var(--ok-ink);border-color:color-mix(in srgb,var(--ok) 45%,var(--line))}
.pn-status.sc-run{color:var(--brand-deep);border-color:var(--brand-200);background:var(--brand-wash)}
.pn-status.sc-over{color:#fff;background:var(--warn);border-color:var(--warn)}
.pn-status.sc-pend{color:var(--fg2)}
.sched-edit{margin-top:6px;font-size:11.5px}
.sched-edit summary{cursor:pointer;font-weight:600;color:var(--fg2)}
.sched-form{display:flex;gap:10px;flex-wrap:wrap;align-items:center;margin-top:6px}
.sched-form .inlab{font-size:11px;color:var(--fg2);display:inline-flex;align-items:center;gap:4px}
.sched-form .inlab input{width:52px}
body.is-mobile .sched .tablewrap{max-height:360px}
body.is-mobile .sched-form .inlab input{width:44px}
/* 三个输入口：可折叠（电脑版默认展开；手机版默认收起，见 applyView） */
.inputs > summary{cursor:pointer;font-weight:700;font-size:13px;color:var(--brand-deep);padding:6px 2px}
.inputs[open] > summary{border-bottom:1px solid var(--line);margin-bottom:6px}
.inputs > h2{margin-top:6px}
body.is-mobile .inputs > summary{font-size:12.5px;padding:8px 2px}
body.is-mobile .inbox .tablewrap{max-height:220px}
