/* sift · 界面
   设计系统沿用 ERP_CC（森茂报价系统）的 theme.py / _css.py：
   K&K Living 品牌橙 #ed6c00 (Pantone 158C) · 飞书风：浅色底 + 白卡片 + 干净边
   + 充足间距，几乎不用阴影 · 小圆角 8px · 色只在重点上 */

:root {
  --brand:        #ed6c00;   /* K&K Living 标准橙 */
  --brand-hover:  #ff8124;
  --brand-dark:   #c75900;
  --brand-bg:     #fff3e6;
  --brand-border: #ffd5b0;

  --bg:      #f7f8fa;   /* 页面主背景（飞书风浅灰） */
  --card:    #ffffff;
  --subtle:  #f0f1f3;   /* 卡内 section 区分 */
  --line:    #e5e7eb;
  --line-2:  #e7e9ec;

  --t1: #1f2329;   /* 标题 / 大字 */
  --t2: #373c43;   /* 正文 */
  --t3: #646a73;   /* 次要 */
  --t4: #8f959e;   /* 占位 */

  --ok:    #059669;   /* emerald，与品牌橙互补 */
  --ok-bg: #e8f6f0;
  --warn:    #f59e0b;
  --warn-bg: #fef6e7;
  --err:     #ef4444;
  --err-bg:  #fdeeee;
  --info:    #1677ff;
  --gray-bg: #f0f1f3;

  --r:    8px;
  --r-sm: 6px;
  --r-xs: 4px;
  --sh:    0 1px 2px rgba(15, 23, 42, .04);
  --sh-up: 0 4px 10px rgba(15, 23, 42, .05);
}

* { box-sizing: border-box; }

html, body {
  margin: 0; background: var(--bg); color: var(--t2);
  font: 14px/1.6 -apple-system, BlinkMacSystemFont, "PingFang SC", "Segoe UI",
        "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
  -webkit-font-smoothing: antialiased;
  /* S6·走查 D9：抽屉关闭态是 position:fixed; right:0; transform:translateX(100%)——
     关着的时候整块盒子的左边界正好卡在视口右边界，一路探到视口外 420px 处。
     Chrome 实测里 fixed 元素伸到视口外照样会撑出文档的横向滚动条。只裁 x 轴、
     不动 y 轴，也不碰抽屉本身的 position/transform——动画效果（Ken 认过的那个
     交互）一点没改，只是不让关着的抽屉在视口外的那截贡献滚动范围。 */
  overflow-x: clip;
}
.hidden { display: none !important; }
h1, h2, h3 { margin: 0; color: var(--t1); font-weight: 600; }

/* ---------- Hero 区（日期 → 大标题 → 智能问候）---------- */

.hero { padding: 8px 0 0; }
.hero__crumb {
  font-size: 11px; color: var(--t4); font-weight: 500;
  letter-spacing: .05em; text-transform: uppercase; margin-bottom: 6px;
}
.hero__title {
  font-size: 26px; font-weight: 600; color: var(--t1);
  letter-spacing: -.02em; line-height: 1.15; margin-bottom: 4px;
}
.hero__sub { font-size: 13px; color: var(--t3); }
.hero__sub b { color: var(--t1); }
.hero__sub b.is-err  { color: var(--err); }
.hero__sub b.is-warn { color: var(--warn); }
.hero__row { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.divider { border-bottom: 1px solid var(--line); margin: 16px 0 24px; }

/* ---------- KPI 卡：白底 + 左侧 3px 色条 ---------- */

.kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 8px; }
.kpi {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r);
  border-left: 3px solid var(--line);
  padding: 10px 14px; box-shadow: var(--sh);
  transition: box-shadow .18s ease;
}
.kpi:hover { box-shadow: var(--sh-up); }
.kpi--brand { border-left-color: var(--brand); }
.kpi--red   { border-left-color: var(--err); }
.kpi--amber { border-left-color: var(--warn); }
.kpi--ok    { border-left-color: var(--ok); }
.kpi__label { font-size: 11px; color: var(--t4); font-weight: 500; letter-spacing: .02em; }
.kpi__value {
  font-size: 24px; font-weight: 700; color: var(--t1); line-height: 1.05;
  font-variant-numeric: tabular-nums; letter-spacing: -.02em; margin: 2px 0;
}
.kpi__delta { font-size: 10.5px; font-weight: 500; color: var(--t4); }
.kpi__delta--brand { color: var(--brand); }
.kpi__delta--red   { color: var(--err); }
.kpi__delta--amber { color: var(--warn); }

/* ---------- 卡片 ---------- */

.card {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--r); box-shadow: var(--sh);
}

/* ---------- 登录门禁 ---------- */

.gate {
  position: fixed; inset: 0; z-index: 100;
  display: flex; align-items: center; justify-content: center;
  padding: 24px; background: var(--bg);
}
.card--gate { width: min(392px, 100%); padding: 30px; display: flex; flex-direction: column; gap: 16px; }
.gate__mark {
  display: inline-block; font-size: 11px; font-weight: 700; letter-spacing: .16em;
  text-transform: uppercase; color: var(--brand); background: var(--brand-bg);
  border: 1px solid var(--brand-border);
  padding: 3px 8px; border-radius: var(--r-xs); margin-bottom: 10px;
}
.gate__title { font-size: 22px; }
.gate__sub { margin: 5px 0 0; color: var(--t3); font-size: 12.5px; }

/* ---------- 表单 ---------- */

.field { display: flex; flex-direction: column; gap: 6px; }
.field__label {
  font-size: 12.5px; font-weight: 500; color: var(--t2);
  display: flex; justify-content: space-between; align-items: baseline;
}
.counter { font-style: normal; color: var(--t4); font-variant-numeric: tabular-nums; font-size: 11.5px; }
.counter.is-over { color: var(--err); }

/* S6·走查 D9 真正的根因：这条全局规则原来无差别命中所有 input，包括
   type=checkbox。抽屉开关用的 .pc-d 就是一个 checkbox（position:absolute;
   opacity:0，没设 left/right），一旦被 width:100% 撑开，包含块算出来的宽度
   能到 1900px 多，比 .pc-dw 本身伸到视口外的那截还宽，是横向滚动条真正的
   最大来源——只裁 .pc-dw 不够，这一条不排除，数字还是会超。checkbox/radio
   从来没有「撑满宽度」的场景，排除掉是通用修正，不是给 .pc-d 单独打补丁。 */
input:not([type="checkbox"]):not([type="radio"]), select, textarea {
  width: 100%; padding: 8px 11px;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--card); color: var(--t1);
  font: inherit; font-size: 13.5px;
  transition: border-color .15s, box-shadow .15s;
}
textarea { resize: vertical; min-height: 54px; }   /* 3 行改 2 行起，不够自己拉 */
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--brand);
  box-shadow: 0 0 0 3px var(--brand-bg);
}
::placeholder { color: var(--t4); }

.chips { display: flex; flex-wrap: wrap; gap: 6px; }
.chip {
  padding: 7px 15px; border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--card); color: var(--t2);
  font: inherit; font-size: 13.5px; cursor: pointer; transition: all .15s;
}
.chip:hover { border-color: var(--brand-border); color: var(--brand); }
.chip.is-on {
  background: var(--brand-bg); border-color: var(--brand); color: var(--brand-dark); font-weight: 600;
}

/* ---------- 按钮 ---------- */

.btn {
  padding: 8px 18px; border: 1px solid transparent; border-radius: var(--r-sm);
  font: inherit; font-size: 13.5px; font-weight: 500; cursor: pointer;
  transition: all .15s; white-space: nowrap;
}
.btn--primary { background: var(--brand); color: #fff; }
.btn--primary:hover { background: var(--brand-hover); }
.btn--ghost { background: var(--card); border-color: var(--line); color: var(--t2); }
.btn--ghost:hover { border-color: var(--brand-border); color: var(--brand); }
.btn--block { width: 100%; }
.btn--sm { padding: 5px 12px; font-size: 12.5px; }
.btn--ok   { background: var(--ok-bg);   color: var(--ok);   }
.btn--hold { background: var(--gray-bg); color: var(--t3);   }
.btn--stop { background: var(--err-bg);  color: var(--err);  }
.btn--ok:hover, .btn--hold:hover, .btn--stop:hover { filter: brightness(.97); }
.btn:disabled { opacity: .5; cursor: default; }

/* ---------- 提示 ---------- */

.note { margin: 0; font-size: 12px; line-height: 1.6; color: var(--t4); }
.note--error { color: var(--err); }
.note b, .note strong { color: var(--t2); font-weight: 600; }

/* ---------- 顶栏 ---------- */

.app { min-height: 100vh; display: flex; flex-direction: column; padding-top: var(--header-h, 50px); }
/* Ken 2026-08-25：「你导航栏直接不要做成悬浮的，把它固定在头上。」
   原来是 sticky——sticky 要靠祖先盒子的边界才知道自己能待到哪，只要哪一层盒子
   比页面早结束，它就跟着被顶走；这条路上已经踩过两次（devbar 盖住、抽屉盖住）。
   改成 fixed 就跟任何祖先盒子都无关了，永远钉在视口顶上。代价是它不再占位，
   所以 .app 要补一份等高的 padding-top（高度由 syncHeaderH() 实时量，不写死）。 */
.topbar {
  position: fixed; top: var(--devbar-h, 0px); left: 0; right: 0; z-index: 20;
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; padding: 0 20px; height: 50px;
  background: var(--card); border-bottom: 1px solid var(--line);
}
.topbar__left { display: flex; align-items: center; gap: 18px; min-width: 0; }
.topbar__mark {
  font-size: 11px; font-weight: 700; letter-spacing: .16em; text-transform: uppercase;
  color: var(--brand);
}
.topbar__right { display: flex; align-items: center; gap: 10px; }
.who { font-size: 12.5px; color: var(--t3); }

.tabs { display: flex; gap: 2px; overflow-x: auto; }
.tab {
  position: relative; padding: 6px 12px; border: 0; border-radius: var(--r-sm);
  background: transparent; color: var(--t3);
  font: inherit; font-size: 13.5px; cursor: pointer; white-space: nowrap; transition: all .15s;
}
.tab:hover { color: var(--t1); background: var(--subtle); }
.tab.is-active { color: var(--brand); background: var(--brand-bg); font-weight: 600; }
.tab__dot { position: absolute; top: 4px; right: 4px; width: 5px; height: 5px; border-radius: 50%; background: var(--err); }

/* ---------- 主区 ---------- */

.main { flex: 1; width: min(1080px, 100%); margin: 0 auto; padding: 20px 20px 64px; }

/* 常驻底部操作条开着的时候，页面底部多留一份等高的空白——滚到底要能看到
   最后一个字段，不能被条盖住。--actionbar-h 由 app.js 的 syncActionBarH() 按
   #actionbar 实际渲染高度实时量，条不在的时候这条规则不生效（body 没有这个 class）。 */
body.has-actionbar .main { padding-bottom: calc(var(--actionbar-h, 56px) + 24px); }

/* Ken 2026-08-25：「每当我拉到最底部的时候，左边的这些字全部都消失掉了。」
   左侧步骤栏（.frail）是 sticky。sticky 的活动范围不是它的父盒子，是**它所在的那一
   格 grid 区域**——也就是 .frail 和 .sform__body 共处的那一行，行高由更高的那个
   （.sform__body）决定。而表单底下还有一截真内容（下一段/门的提示块）加上给操作条
   让位的空白，一共三百多像素，都在这一行外面。拉到底时行的下边界已经升到视口上半部，
   步骤栏被它往上顶：1280×460 实测 top=-131，七条只剩三条完整可见（813 高的窗口刚好
   看不出来，所以第一次没查出来）。
   ⚠️ padding 必须加在 .sform__body 上——加在 .sform（grid 容器）上撑的是容器的
   padding box，行高一点没变，步骤栏照样被顶。踩过一次。
   加 padding 把行撑长，再用等量的负 margin 把后面的排版拉回原位：两个数一样大，
   不管表单长短，后面的东西位置都不变。 */
.sform { --frail-tail: 420px; }
.sform__body { padding-bottom: var(--frail-tail); }
.sform { margin-bottom: calc(-1 * var(--frail-tail)); }

/* ---------- 常驻底部操作条 ----------
   P9c（Ken 2026-08-22）：「每一个页面理论上都应该有『提交』或『下一步』这种按钮…
   现在好像都没有这种了」——按钮原来都是页面里的普通排版元素，埋在表单最下面，
   长页面要滚好几屏才看得到。这里改成 position:fixed 钉在视口底部，独立于任何一个
   .view，只在阶段工作台/方案卡/候选卡/登记候选这几个「能填东西」的页面上由
   showActionBar()/hideActionBar() 控制显隐；只读页面（总览/数据/项目档案/交付物/
   门页只读态）不出现，见 CLAUDE.md 第六条「一个页面做一件事」。
   z-index 30——低于抽屉的遮罩(60)和抽屉本体(61)，抽屉一开，遮罩和抽屉面板天然
   盖到条上面（遮罩半透明+吃掉点击），不用另写"开抽屉时把条藏起来"的逻辑。 */
.actionbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
  background: var(--card); border-top: 1px solid var(--line);
  box-shadow: 0 -2px 10px rgba(31, 35, 41, .08);
}
.actionbar.hidden { display: none; }
.actionbar__inner {
  width: min(1080px, 100%); margin: 0 auto; box-sizing: border-box;
  display: flex; align-items: center; gap: 9px; flex-wrap: nowrap;
  padding: 12px 20px;
}
/* 「还差什么」——常驻条上唯一决定「能不能交」的信息，不能被挤没：
   占满剩余空间，装不下就省略号收尾（title 属性带全文），按钮永远保持整行不折。 */
.actionbar__fm {
  margin-right: auto; font-size: 12.5px; color: var(--t3);
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.actionbar__fm b.is-err { color: var(--err); }
/* 方案卡/候选卡复用的是既有的 .pc-fm（原来在 .pc-foot 里就是这个类），挪进常驻条后
   补上同一套「装不下就省略号，不换行」——跟 .actionbar__fm 同一条道理。 */
.actionbar__inner .pc-fm { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.actionbar__inner .sform__msg { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.actionbar__inner .btn, .actionbar__inner select { flex: 0 0 auto; }
.actionbar__inner select { max-width: 220px; }
@media (max-width: 1180px) {
  .actionbar__inner select { max-width: 150px; }
}

/* ---------- 灵感卡（网格，图为主体）---------- */

.grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(272px, 1fr)); gap: 8px;
  align-items: start;   /* 有图卡和纯文字卡高度差很大，不要让矮的被拉长 */
}
/* 单列列表（周评审）：图放左边固定宽，不要拉成一条空荡荡的横条 */
.cards { display: flex; flex-direction: column; gap: 8px; }
.cards .icard__main--img { display: grid; grid-template-columns: 200px 1fr; align-items: stretch; }
.cards .icard__thumb, .cards .thumb-dead { height: 100%; min-height: 132px; border-bottom: 0; border-right: 1px solid var(--line); }
@media (max-width: 640px) {
  .cards .icard__main--img { grid-template-columns: 1fr; }
  .cards .icard__thumb, .cards .thumb-dead { height: 172px; border-right: 0; border-bottom: 1px solid var(--line); }
}

.icard {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r);
  border-left: 3px solid var(--line);
  box-shadow: var(--sh); transition: box-shadow .18s ease;
  display: flex; flex-direction: column; overflow: hidden;
}
.icard:hover { box-shadow: var(--sh-up); }
.icard--待响应   { border-left-color: var(--warn); }
.icard--待评审   { border-left-color: var(--brand); }
.icard--继续观察 { border-left-color: var(--t4); }
.icard--已采纳   { border-left-color: var(--ok); }
.icard--已否决   { border-left-color: var(--err); }
.badge--进行中 { background: var(--brand-bg); color: var(--brand-dark); }
.badge--已终止 { background: var(--err-bg); color: var(--err); }

/* 固定高度而不是宽高比：图卡和纯文字卡的高度要接近，
   否则网格会被最高的一张撑出大片空洞。原图在工作台里看全的。 */
.icard__thumb {
  width: 100%; height: 172px; object-fit: cover;
  background: var(--subtle); display: block; border-bottom: 1px solid var(--line);
}
/* 常驻区那张灵感图外面包一层 <a target=_blank>，点了在新标签页看大图——
   最简单的「放大看」，不引灯箱库。line-height:0 去掉 <img> 默认 inline 底下那道空隙。 */
.thumblink { display: inline-block; line-height: 0; }
.thumb-dead {
  width: 100%; height: 172px; display: flex; align-items: center; justify-content: center;
  flex-direction: column; gap: 3px; background: var(--subtle); border-bottom: 1px solid var(--line);
  font-size: 12px; color: var(--t4); text-align: center; padding: 0 10px;
}
.thumb-dead a { color: var(--t3); }
.icard__body { padding: 12px 14px; display: flex; flex-direction: column; gap: 8px; }
.icard__top { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.icard__id { font-size: 11px; font-weight: 700; color: var(--t4); font-variant-numeric: tabular-nums; }
.icard__note { font-size: 14px; font-weight: 600; color: var(--t1); line-height: 1.5; }
.icard__carrier {
  font-size: 12.5px; color: var(--t3); background: var(--subtle);
  padding: 7px 10px; border-radius: var(--r-sm); word-break: break-word;
  max-height: 66px; overflow: hidden;
}
.icard__meta { display: flex; flex-wrap: wrap; gap: 4px 12px; font-size: 11.5px; color: var(--t4); }
.icard__reason {
  font-size: 12.5px; color: var(--err); background: var(--err-bg);
  padding: 7px 10px; border-radius: var(--r-sm);
}
/* 归档过又翻回来的：理由留痕，但它是历史不是当前状态——不能跟「现在就是归档」
   长得一样，否则卡片上「可创建方案」和一块红底的归档原因并排摆着，
   看起来像既已归档又能立项（新人审查 P1-02）。灰底、不报警。 */
.icard__reason--hist {
  color: var(--t3); background: var(--bg);
  border-left: 2px solid var(--line);
}
.icard__reason--hist em { color: var(--t4); font-style: normal; }
.icard__actions {
  display: flex; gap: 6px; flex-wrap: wrap;
  padding: 10px 14px; border-top: 1px solid var(--line);
  background: #fcfcfd;
}

.badge {
  font-size: 11px; font-weight: 600; padding: 2px 7px; border-radius: var(--r-xs);
  background: var(--subtle); color: var(--t3);
}
.badge--dir  { background: var(--brand-bg); color: var(--brand-dark); border: 1px solid var(--brand-border); }
.badge--待响应   { background: var(--warn-bg); color: var(--warn); }
.badge--待评审   { background: var(--brand-bg); color: var(--brand-dark); }
.badge--继续观察 { background: var(--gray-bg);  color: var(--t3); }
.badge--已采纳   { background: var(--ok-bg);    color: var(--ok); }
.badge--已否决   { background: var(--err-bg);   color: var(--err); }
.badge--overdue  { background: var(--err-bg);   color: var(--err); }

/* 候选池状态（candidate.candidateState 的六个取值，P7 加了「填写中」）——「说不出」
   专指卡在④，不是否决，用 warn 而不是 err，颜色上就不该跟「已否决」混在一起；
   「填写中」是①②③还没齐的中性状态，颜色比「说不出」更淡，不该看起来像风险。 */
.badge--未看   { background: var(--gray-bg);  color: var(--t3); }
.badge--填写中 { background: var(--gray-bg);  color: var(--t3); }
.badge--说不出 { background: var(--warn-bg);  color: var(--warn); }
.badge--说得出 { background: var(--ok-bg);    color: var(--ok); }
.badge--已归档 { background: var(--gray-bg);  color: var(--t4); }
.badge--已创建方案 { background: var(--brand-bg); color: var(--brand-dark); }

/* ---------- 工作台（点开一条 → 单条处理）---------- */

.bench__back {
  display: inline-flex; align-items: center; gap: 6px;
  margin-bottom: 12px; font-size: 13px; color: var(--t3);
  background: none; border: 0; cursor: pointer; padding: 0;
}
.bench__back:hover { color: var(--brand); }

.steps { display: flex; align-items: center; gap: 0; margin: 4px 0 18px; }
.step { display: flex; align-items: center; gap: 7px; font-size: 12.5px; color: var(--t4); }
.step__num {
  width: 20px; height: 20px; border-radius: 50%;
  display: grid; place-items: center;
  font-size: 11px; font-weight: 700;
  background: var(--subtle); color: var(--t4);
}
.step.is-done .step__num { background: var(--ok-bg); color: var(--ok); }
.step.is-now  .step__num { background: var(--brand); color: #fff; }
.step.is-now  { color: var(--brand); font-weight: 600; }
.step__line { width: 34px; height: 1px; background: var(--line); margin: 0 10px; }

.bench { display: grid; grid-template-columns: 1.35fr 1fr; gap: 8px; align-items: start; }
.panel { background: var(--card); border: 1px solid var(--line); border-radius: var(--r); padding: 16px 18px; box-shadow: var(--sh); }
.panel + .panel { margin-top: 8px; }
.panel h3 { font-size: 13.5px; margin-bottom: 3px; }
.panel__sub { font-size: 12px; color: var(--t4); margin: 0 0 12px; }
.panel__sub:empty { display: none; }
.panel__hero { font-size: 17px; font-weight: 600; color: var(--t1); line-height: 1.5; }
.panel__img {
  width: 100%; max-height: 420px; object-fit: contain; background: var(--subtle);
  border-radius: var(--r-sm); border: 1px solid var(--line); display: block;
}

.kv { display: flex; gap: 10px; padding: 6px 0; font-size: 13px; border-bottom: 1px solid var(--subtle); }
.kv:last-child { border-bottom: 0; }
.kv__k { width: 84px; flex-shrink: 0; color: var(--t4); font-size: 12.5px; }
.kv__v { color: var(--t2); min-width: 0; }

/* B5：表格类上游引用——标签放上面、表格占满这一行的宽度，不跟编辑区
   那套 180~220px 列宽走，不然阶段 6 的六列改造方案表会把 details 区顶出横向滚动条。 */
.kv--table { flex-direction: column; gap: 4px; }
.kv--table .kv__k { width: auto; }
.kv__table { width: 100%; border-collapse: collapse; table-layout: fixed; font-size: 12.5px; }
.kv__table th, .kv__table td {
  border: 1px solid var(--line); padding: 4px 6px; text-align: left;
  overflow-wrap: break-word; word-break: break-word;
}
.kv__table th { background: var(--subtle); color: var(--t3); font-weight: 600; }

/* ---------- 条形 ---------- */

.bar { display: flex; align-items: center; gap: 10px; padding: 6px 0; font-size: 13px; }
.bar__label { width: 150px; flex-shrink: 0; color: var(--t2); }
.bar__track { display: block; flex: 1; height: 6px; background: var(--subtle); border-radius: 3px; overflow: hidden; }
.bar__fill  { display: block; height: 100%; background: var(--brand); border-radius: 3px; }
.bar__value { width: 60px; text-align: right; color: var(--t4); font-variant-numeric: tabular-nums; font-size: 12px; }

.filters { display: flex; gap: 5px; flex-wrap: wrap; margin-bottom: 12px; }

.panel__sub--dim { color: var(--t4); font-size: 11.5px; }

/* 首页那个「流程说明」小入口——不占顶栏，一行小字。 */
.guidelink { margin: -4px 0 14px; }

/* 流程说明页 */
.gcard { padding: 18px 20px; margin-bottom: 14px; }
.gcard h3 { margin: 0 0 8px; font-size: 15px; }
.gcard p { margin: 0 0 8px; font-size: 13px; line-height: 1.75; color: var(--t2); }
.gcard__sub { color: var(--t3) !important; font-size: 12.5px !important; }
/* 说明页的「整条流程」：上面一条链（跟总览同一套 .rail 类），下面按三步分组的说明卡。
   链条上点一格 → 滚到它的说明并高亮一下。 */
.rail--guide { flex-wrap: wrap; row-gap: 10px; padding: 4px 0 10px; }
.rail--guide .rail__node { cursor: pointer; }
.rail--guide .rail__node:hover .rail__name { color: var(--brand-dark); }
.rail--guide .rail__line { min-width: 10px; }

.gphase { margin-top: 14px; }
.gphase__t { margin: 0 0 8px; font-size: 13px; color: var(--t2); font-weight: 600; }
.gphase__b { display: grid; grid-template-columns: repeat(auto-fill, minmax(232px, 1fr)); gap: 10px; }

.gstep { border: 1px solid var(--line); border-radius: var(--r-sm); padding: 10px 12px; background: #fff; }
.gstep--gate { border-color: var(--brand-border); background: var(--brand-bg); }
.gstep__h { font-size: 13px; line-height: 1.5; }
.gstep--gate .gstep__h > b { color: var(--brand-dark); }
.gstep__alias { margin-left: 6px; font-size: 11px; color: var(--t4); font-weight: 400; }
.gstep__m { margin-top: 2px; font-size: 11.5px; color: var(--t4); }
.gstep__why { margin: 6px 0 0; font-size: 12px; line-height: 1.65; color: var(--t2); }
.gstep--gate .gstep__why:first-of-type { color: var(--brand-dark); font-weight: 600; }
.gstep.is-hit { box-shadow: 0 0 0 2px var(--brand); }

.glist { margin: 6px 0 0; padding-left: 20px; }
.glist li { margin-bottom: 9px; font-size: 13px; line-height: 1.7; }
.glist__m { display: block; font-size: 11.5px; color: var(--t4); }
.glist__gate { display: block; font-size: 11.5px; color: var(--brand-dark); }
.glist__g > b { color: var(--brand-dark); }
/* 任务行：责任角色和下一步 */
.mrow__role { font-style: normal; font-size: 11px; color: var(--t4); margin-left: 6px; }
.mrow__next { font-size: 11.5px; color: var(--t4); }

/* 阶段页顶的「下一步」——一行，不是一块。谁接手、要过哪道门，人看完这一行
   就知道自己这一段做完之后球去哪儿了。 */
.panel__next {
  margin: 6px 0 0; font-size: 12px; color: var(--brand-dark);
  background: var(--brand-bg); border-left: 3px solid var(--brand-border);
  border-radius: var(--r-xs); padding: 5px 10px; display: inline-block;
}

/* 总览工具条：搜索 / 分类 / 排序。桌面优先，一行摆得下就一行，摆不下再换行。 */
.ovbar {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: 8px 14px;
  padding: 10px 14px; margin-bottom: 12px;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r);
}
.ovbar label { display: flex; flex-direction: column; gap: 3px; }
.ovbar label > span { font-size: 11px; color: var(--t4); }
.ovbar select, .ovbar input {
  font: inherit; font-size: 12.5px; color: var(--t1);
  border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: 5px 8px; background: #fff; min-width: 120px;
}
.ovbar__q input { min-width: 200px; }
.ovbar__f--sort { margin-left: auto; }
.ovbar .btn { align-self: flex-end; }

/* 翻页条。有页码——人要知道自己在第几页、一共多少页，不做无限滚动。 */
.pager {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin: 14px 0 4px; font-size: 12.5px; color: var(--t3);
}
.pager__n { margin-right: auto; }
.pager__p { font-variant-numeric: tabular-nums; font-weight: 600; color: var(--t2); }
.pager .btn[disabled] { opacity: .4; cursor: default; }
.empty {
  padding: 40px 20px; text-align: center; color: var(--t4); font-size: 13px;
  background: var(--card); border: 1px dashed var(--line); border-radius: var(--r);
}
.reject, .adopt { display: flex; flex-direction: column; gap: 8px; padding: 12px 14px; border-top: 1px solid var(--line); background: #fcfcfd; }
.adopt__row { display: flex; gap: 8px; flex-wrap: wrap; }
.adopt__row .field { flex: 1; min-width: 150px; }

@media (max-width: 860px) {
  .bench { grid-template-columns: 1fr; }
}
@media (max-width: 640px) {
  .topbar { height: auto; padding: 8px 14px; flex-wrap: wrap; }
  .topbar__left { width: 100%; flex-direction: column; align-items: flex-start; gap: 6px; }
  .main { padding: 16px 14px 56px; }
  .hero__row { flex-direction: column; }
  .hero__title { font-size: 22px; }
  .grid { grid-template-columns: 1fr; }
  .bar__label { width: 92px; }
}

/* ================================================================
   全流程主线 —— 总览的核心
   参照 ERP_CC 报价系统总览卡里的节点链条（_chain_html）：
   已完成打勾 · 当前高亮 · 未开始灰 · 停止的按停下时的位置显示。
   区别是我们有 15 段不是 6 段，所以链条要能横向滚动。
   ================================================================ */

.legend {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  font-size: 11.5px; color: var(--t4); margin: 0 0 12px;
}
.legend span { display: inline-flex; align-items: center; gap: 5px; }
.legend__dot { width: 10px; height: 10px; border-radius: 50%; display: inline-block; }
.legend__dot.is-done    { background: var(--ok); }
.legend__dot.is-current { background: var(--brand); }
.legend__dot.is-pending { background: #dfe1e5; }
.legend__dot.is-stopped { background: var(--err); }
.legend__gate {
  border: 1px solid var(--brand-border); background: var(--brand-bg); color: var(--brand-dark);
  border-radius: var(--r-xs); padding: 0 5px; font-size: 10px; font-weight: 600;
}

.rail {
  display: flex; align-items: flex-start;
  margin: 10px 0 8px; padding-bottom: 2px;
  overflow-x: auto; scrollbar-width: thin;
}
.rail__node {
  display: flex; flex-direction: column; align-items: center;
  flex: 0 0 auto; width: 48px; gap: 3px;
}
.rail__dot {
  width: 21px; height: 21px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 600; color: #fff; background: #dfe1e5;
  font-variant-numeric: tabular-nums;
}
.rail__name { font-size: 10.5px; color: var(--t4); white-space: nowrap; line-height: 1.2; }
.rail__gate {
  font-size: 9px; font-weight: 600; line-height: 1.4;
  color: var(--brand-dark); background: var(--brand-bg);
  border: 1px solid var(--brand-border); border-radius: var(--r-xs); padding: 0 4px;
}
.rail__gate--none { visibility: hidden; }

/* 链条改成 16 个独立节点之后（Ken 2026-08-26），门不再是挂在阶段底下的小标签，
   而是自己一格。形状上跟阶段分开——门是另一个人的一次独立操作，不是同一段的附属。
   菱形用 45° 旋转的方块做，里面的字反着转回来，不用额外的图形资源。 */
.rail__node--gate .rail__dot {
  border-radius: 3px; transform: rotate(45deg);
  background: #c8ccd0;
}
.rail__node--gate .rail__dot > * { display: inline-block; transform: rotate(-45deg); }
.rail__node--gate .rail__name { color: var(--brand-dark); font-weight: 600; }
.rail__node--gate.is-pending .rail__name { color: var(--t4); font-weight: 400; }
/* 层 1/层 2 的三张卡（灵感 / 候选 / 方案）——它们不占段号，点数字没有意义，画个点。 */
.rail__node--card .rail__dot { font-size: 13px; }
/* 当前站在哪一格：整格套一个框，阶段/门/卡都一样。 */
.rail__node.is-viewing {
  outline: 2px solid var(--brand); outline-offset: 2px; border-radius: var(--r-xs);
}
.rail__node[data-chain-kind] { cursor: pointer; }
.rail__node[data-chain-kind]:hover .rail__name { color: var(--brand-dark); }
/* 链条上的门标签是「点进门独立页」的入口——挂了 data-gatelink-key 的才可点。 */
.rail__gate[data-gatelink-key],
.rail__node.has-gate[data-gatelink-key] { cursor: pointer; }
.rail__gate[data-gatelink-key]:hover { background: var(--brand-border); }
/* 门页现在也画这条链条，当前这道门要标出来——不然人看得见链条，却不知道自己站在哪。 */
.rail__gate.is-viewing { background: var(--brand); color: #fff; border-color: var(--brand); }

.rail__node.is-done    .rail__dot { background: var(--ok); }
.rail__node.is-done    .rail__name { color: var(--t3); }
.rail__node.is-current .rail__dot { background: var(--brand); box-shadow: 0 0 0 3px var(--brand-bg); }
.rail__node.is-current .rail__name { color: var(--brand-dark); font-weight: 600; }
.rail__node.is-stopped .rail__dot { background: var(--err); }
.rail__node.is-stopped .rail__name { color: var(--err); font-weight: 600; }
.rail__node.is-parked  .rail__dot { background: var(--t4); }
.rail__node.is-parked  .rail__name { color: var(--t3); font-weight: 600; }
.rail__node.is-bounced .rail__dot { background: var(--warn); }

.rail__line { flex: 1 1 auto; min-width: 5px; height: 2px; background: #e9ebee; margin-top: 10px; }
.rail__line.is-done { background: var(--ok); opacity: .45; }

/* ---------- 总览行：缩略图 ｜ 信息+链条 ｜ 操作 ---------- */

.rows { display: flex; flex-direction: column; gap: 8px; }

.prow {
  /* Ken 2026-08-26：「那里面的那个条，现在因为过长还要左右拖动，这个不行……特别是
     PD019 那里，它有『打开』『方案』『归档』这三个按钮，就更加压缩了它的宽度。」
     链条 17 格实测 896px，塞在中间那一列里只剩 765–834px，必然要拖。
     改成它自己占一整行（跨三列），拿到整行 1040px——不缩字、不换行、不用拖。
     行内其余部分（缩略图 / 信息 / 按钮）排版一点没变。 */
  display: grid; grid-template-columns: 76px 1fr auto; gap: 14px 14px; align-items: center;
  background: var(--card); border: 1px solid var(--line); border-left: 3px solid var(--brand);
  border-radius: var(--r); padding: 14px 16px; box-shadow: var(--sh);
  cursor: pointer; transition: box-shadow .18s ease;
}
.prow > .rail { grid-column: 1 / -1; margin: 2px 0 0; }
.prow:hover { box-shadow: var(--sh-up); }
.prow.is-stopped { border-left-color: var(--err); }
.prow.is-stopped .prow__title { color: var(--t3); }

.prow__img {
  width: 76px; height: 60px; object-fit: cover; display: block;
  border-radius: var(--r-sm); border: 1px solid var(--line); background: var(--subtle);
}
.prow__img--none {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px;
  background: linear-gradient(135deg, #f5f6f8, #eceef1);
}
.prow__img--none b { font-size: 15px; color: var(--t3); font-weight: 700; }
.prow__img--none span { font-size: 9.5px; color: var(--t4); }
.prow .thumb-dead { width: 76px; height: 60px; border: 1px solid var(--line); border-radius: var(--r-sm); font-size: 9px; }
.prow .thumb-dead a { display: none; }

.prow__body { min-width: 0; }
.prow__top { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.prow__id { font-size: 11.5px; font-weight: 700; color: var(--t2); font-variant-numeric: tabular-nums; }
.prow__from { font-size: 10.5px; color: var(--t4); }
.prow__title { font-size: 14.5px; font-weight: 600; color: var(--t1); margin: 4px 0 2px; line-height: 1.45; }
.prow__meta { display: flex; flex-wrap: wrap; gap: 3px 12px; font-size: 11.5px; color: var(--t4); }
.prow__cur { font-size: 12px; color: var(--t3); }
.prow__cur b { color: var(--t1); }
.prow__clock { color: var(--t4); }
.prow__clock.is-warn { color: var(--warn); font-weight: 600; }
.prow__clock.is-err  { color: var(--err);  font-weight: 600; }
.tag-todo {
  font-size: 10px; color: var(--t4); background: var(--subtle);
  border-radius: var(--r-xs); padding: 1px 5px; margin-left: 4px;
}
.prow__act { align-self: center; }

/* ---------- 工作台里的链条与时钟 ---------- */

.bench__rail { margin: 2px 0 12px; }
.clockbar {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r);
  padding: 9px 14px; margin-bottom: 8px; box-shadow: var(--sh);
}
.clockbar__k { font-size: 12px; color: var(--t4); }
.clockbar__v { font-size: 15px; font-weight: 700; color: var(--t1); font-variant-numeric: tabular-nums; }
.clockbar__v.is-warn { color: var(--warn); }
.clockbar__v.is-err  { color: var(--err); }
.clockbar__n { font-size: 11.5px; color: var(--t4); }

.todo-box {
  font-size: 12.5px; line-height: 1.7; color: var(--t3);
  background: var(--subtle); border-radius: var(--r-sm); padding: 12px 14px;
}

/* ---------- 工作台右栏：15 段清单 ---------- */

.stagelist { display: flex; flex-direction: column; }
.stagelist__row {
  display: grid; grid-template-columns: 22px 1fr auto auto 34px;
  gap: 8px; align-items: center;
  padding: 5px 0; border-bottom: 1px solid var(--line);
  font-size: 12px; color: var(--t4);
}
.stagelist__row:last-child { border-bottom: 0; }
.stagelist__no {
  width: 20px; height: 20px; border-radius: 50%; background: #dfe1e5; color: #fff;
  display: flex; align-items: center; justify-content: center; font-size: 10.5px; font-weight: 600;
}
.stagelist__name { color: var(--t3); }
.stagelist__owner, .stagelist__days { font-size: 11px; }
.stagelist__gate { font-size: 10px; color: var(--brand-dark); font-weight: 600; text-align: right; }
.stagelist__row.is-done .stagelist__no { background: var(--ok); }
.stagelist__row.is-done .stagelist__name { color: var(--t2); }
.stagelist__row.is-current { background: var(--brand-bg); margin: 0 -8px; padding: 5px 8px; border-radius: var(--r-sm); }
.stagelist__row.is-current .stagelist__no { background: var(--brand); }
.stagelist__row.is-current .stagelist__name { color: var(--brand-dark); font-weight: 600; }
.stagelist__row.is-stopped .stagelist__no { background: var(--err); }
.stagelist__row.is-stopped .stagelist__name { color: var(--err); font-weight: 600; }
.stagelist__row.is-parked .stagelist__no { background: var(--t4); }

@media (max-width: 860px) {
  .prow { grid-template-columns: 56px 1fr; }
  .prow__act { grid-column: 1 / -1; }
  .prow__img, .prow .thumb-dead { width: 56px; height: 48px; }
  .bench { grid-template-columns: 1fr; }
}

/* ================================================================
   工作台顶栏：返回 + 记录名 + 时钟 + 可点的 15 段链条
   链条吸顶 —— 滚到页面多下面都能跳回任意一段的工作台。
   ================================================================ */

.benchbar {
  /* 顶栏改成 fixed 之后它不再占位，任何 top: 50px 这种写死的偏移都会滑到顶栏底下。
     一律改读 --header-h（syncHeaderH() 实测，含测试模式那条 devbar 的高度）。 */
  position: sticky; top: var(--header-h, 50px); z-index: 15;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r);
  padding: 12px 16px 10px; margin: 4px 0 8px; box-shadow: var(--sh);
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 12px;
}
.benchbar .bench__back { margin: 0; padding: 0; }
.benchbar__id { font-size: 13px; font-weight: 700; color: var(--t1); font-variant-numeric: tabular-nums; }
.benchbar__title { font-size: 13px; color: var(--t3); flex: 1 1 200px; min-width: 0; }
.benchbar__clock { font-size: 11.5px; color: var(--t4); font-variant-numeric: tabular-nums; }
.benchbar__clock.is-warn { color: var(--warn); font-weight: 600; }
.benchbar__clock.is-err  { color: var(--err);  font-weight: 600; }
.benchbar .rail { flex: 1 1 100%; margin: 6px 0 0; }

/* 可点的链条。
   ⚠️ 这里原来是 `.rail--nav .rail__node { cursor: pointer }`——**所有**节点一律手型，
   可实际上只有挂了 data-chain-kind 的才真能点。还没立项的候选，17 个节点里 14 个
   （门一往后全部）都不可点：鼠标变手型、点下去什么都不发生。
   Ken 2026-08-28：「还是有几个是点了以后不出现框的。」就是这一批。
   CLAUDE.md 第五条：界面上承诺的能力，代码里必须真有。手型也是一种承诺。 */
.rail--nav .rail__node { border-radius: var(--r-sm); padding: 2px 0; }
.rail--nav .rail__node[data-chain-kind] { cursor: pointer; }
.rail--nav .rail__node[data-chain-kind]:hover .rail__dot { transform: scale(1.12); }
.rail--nav .rail__dot { transition: transform .12s ease; }
/* 点不了的：不给手型、压淡，让人一眼看出它现在不是一个入口（鼠标停上去有原因）。 */
.rail--nav .rail__node:not([data-chain-kind]) { cursor: default; opacity: .5; }
.rail--nav .rail__node.is-pending[data-chain-kind] { cursor: pointer; }
.rail--nav .rail__node.is-viewing {
  background: var(--brand-bg); box-shadow: inset 0 0 0 1px var(--brand-border);
}
.rail--nav .rail__node.is-viewing .rail__name { color: var(--brand-dark); font-weight: 600; }

/* 回看/前瞻提示条 */
.benchnote {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  background: var(--brand-bg); border: 1px solid var(--brand-border);
  border-radius: var(--r); padding: 9px 14px; margin-bottom: 8px;
  font-size: 12.5px; color: var(--brand-dark);
}
.benchnote b { font-weight: 600; }
.benchnote--ahead { background: var(--subtle); border-color: var(--line); color: var(--t3); }
.benchnote--ahead b { color: var(--t2); }
.benchnote .btn { margin-left: auto; }

/* 阶段面板抬头：标题 + 这一段的元信息（原来堆在右栏清单里的那些） */
.panel__head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.panel__tag { font-size: 11.5px; color: var(--t4); }

@media (max-width: 860px) {
  .benchbar { position: static; }
}

/* ================================================================
   表单引擎
   15 段共用一套渲染。字段旁的「数据分层 / 人做的判断」标注不是装饰 ——
   费用模型最容易出错的地方就是把代理值写成了数据事实。
   ================================================================ */

.pinned {
  display: flex; flex-wrap: wrap; gap: 8px 24px;
  background: var(--brand-bg); border: 1px solid var(--brand-border);
  border-radius: var(--r-sm); padding: 10px 14px; margin: 4px 0 12px;
}
.pinned__item { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.pinned__k { font-size: 10.5px; color: var(--brand-dark); font-weight: 600; }
.pinned__v { font-size: 13px; color: var(--t1); }

.upstream {
  border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: 8px 12px; margin-bottom: 14px; background: var(--subtle);
}
.upstream summary { font-size: 12.5px; color: var(--t3); cursor: pointer; }
.upstream .kv__k em {
  font-style: normal; font-size: 10px; color: var(--t4);
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--r-xs); padding: 0 4px; margin-left: 5px;
}

.sform { display: flex; flex-direction: column; gap: 4px; }
.fsec { padding: 14px 0 4px; border-top: 1px solid var(--line); }
.fsec:first-child { border-top: 0; padding-top: 4px; }
.fsec h4 { margin: 0 0 2px; font-size: 13.5px; color: var(--t1); font-weight: 600; }
.fsec__note { margin: 0 0 8px; font-size: 11.5px; color: var(--t4); line-height: 1.55; }
.fsec--concl { background: var(--subtle); margin: 8px -18px 0; padding: 14px 18px 8px; border-radius: var(--r-sm); }
.fsec--check .checklist { margin: 4px 0 0; padding-left: 18px; font-size: 12px; color: var(--t3); line-height: 1.9; }

.ffield { margin-bottom: 14px; position: relative; }
.ffield__label {
  display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap;
  font-size: 12.5px; font-weight: 500; color: var(--t2); margin-bottom: 5px;
}
.ffield__hint { font-size: 11px; color: var(--t4); margin-top: 4px; line-height: 1.6; }
.ffield__err { font-size: 11.5px; color: var(--err); margin-top: 4px; font-weight: 500; }
.req { font-style: normal; font-size: 10px; color: var(--err); background: var(--err-bg);
       border-radius: var(--r-xs); padding: 0 4px; font-weight: 600; }
/* 阶段 14 的「开发填写 / 运营填写」组标题——两组分区各自从 A 开始，
   不写出来就像编号错了。 */
.fgroup { grid-column: 1 / -1; margin: 26px 0 2px; font-size: 13px; font-weight: 700;
          color: var(--t2); letter-spacing: .04em; padding-bottom: 8px;
          border-bottom: 2px solid var(--line); }
.fgroup:first-child { margin-top: 4px; }

/* 提醒项：不拦签字，所以不能跟必过项一样画成红的（黑盒审查 P0-12）。 */
.req--soft { color: var(--t4); background: var(--subtle); }
/* 选填：跟必填同一个位置，但不报警——它的作用是让人确认「这一格没标必填」
   是有人定过的，不是漏标的（新人审查 P1-09）。 */
.req--opt { color: var(--t4); background: var(--subtle); font-weight: 500; }
/* 流程说明里「全称（链条上简称）」的那半句——说明性的，不抢标题 */
.glist__alias { margin-left: 8px; font-size: 11.5px; color: var(--t4); font-weight: 400; }
/* 流程说明里「全称（链条上简称）」的那半句——说明性的，不抢标题 */
.glist__alias { margin-left: 8px; font-size: 11.5px; color: var(--t4); font-weight: 400; }

.tier { font-style: normal; font-size: 10px; border-radius: var(--r-xs); padding: 0 4px;
        color: var(--t4); background: var(--subtle); font-weight: 500; }
.tier.t-real   { color: #b45309; background: #fef3c7; }   /* 公司历史：人工填 */
.tier.t-assume { color: var(--t3); background: #eceef1; }
.tier.t-proxy  { color: #0369a1; background: #e0f2fe; }
.tier.t-judge  { color: var(--brand-dark); background: var(--brand-bg); font-weight: 600; }
.unit { font-size: 11.5px; color: var(--t4); margin-left: 6px; }
/* P6·货币统一：全站金额一律美元，$ 固定前缀（跟现有 sayPriceBit/sayRef 等展示文案的
   前缀习惯一致）。flex 布局而不是绝对定位，这样同一份标记能直接套进 .sform/.pc-in/
   表格单元格三种不同的输入框上下文，不用为每种场景单独调 padding。 */
.moneyf { display: flex; align-items: center; gap: 4px; width: 100%; }
.moneyf__cur { font-size: 12.5px; color: var(--t4); flex: 0 0 auto; }
.moneyf input { flex: 1 1 auto; min-width: 0; }
.chk { display: flex; align-items: center; gap: 7px; font-size: 12.5px; color: var(--t2); cursor: pointer; padding: 3px 0; }
.chk input { width: auto; }
.refval { font-size: 13px; color: var(--t3); background: var(--subtle);
          border-radius: var(--r-sm); padding: 8px 11px; }
.uploadbox { display: flex; flex-direction: column; gap: 4px; }
.uploadbox__n { font-size: 11px; color: var(--t4); }

.ftable { overflow-x: auto; }
.ftable table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.ftable th {
  text-align: left; font-weight: 500; color: var(--t4); font-size: 11px;
  padding: 4px 6px 6px; border-bottom: 1px solid var(--line); white-space: nowrap;
}
.ftable td { padding: 3px 3px; }
.ftable input, .ftable select { padding: 5px 8px; font-size: 12.5px; }
.ftable__n { font-size: 11px; color: var(--t4); margin-left: 8px; }
.linkbtn { border: 0; background: transparent; color: var(--t4); cursor: pointer; font-size: 11.5px; padding: 4px; }
.linkbtn:hover { color: var(--err); }

/* 阶段 7 表格模板（下载/上传/粘贴）工具条，挂在 .ftable 下面。 */
.ftable__csv { margin-top: 8px; padding-top: 8px; border-top: 1px dashed var(--line); }
.ftable__csv-hint { font-size: 11.5px; color: var(--t4); margin: 0 0 6px; }
.ftable__csv-row { display: flex; gap: 8px; flex-wrap: wrap; }
.ftable__csv-filebtn { position: relative; overflow: hidden; }
.ftable__csv-paste { margin-top: 8px; }
.ftable__csv-paste.hidden { display: none; }
.ftable__csv-pastebox {
  width: 100%; font-size: 12.5px; font-family: ui-monospace, monospace;
  border: 1px solid var(--line); border-radius: var(--r-sm); padding: 8px; margin-bottom: 6px;
}
.ftable__csv-preview:empty { display: none; }
.ftable__csv-block { margin-top: 8px; background: var(--subtle); border-radius: var(--r-sm); padding: 8px 10px; }
.ftable__csv-t { font-size: 12px; color: var(--t2); margin: 0 0 4px; font-weight: 500; }
.ftable__csv-note { font-size: 11.5px; color: var(--t4); margin: 4px 0; }
.ftable__csv-warn { font-size: 11.5px; color: var(--warn); margin: 4px 0; }
.ftable__csv-err { font-size: 12px; color: var(--err); margin: 4px 0; }
.ftable__csv-errlist { margin: 4px 0; padding-left: 18px; font-size: 11.5px; color: var(--err); }
.ftable__csv-prevtable { width: 100%; border-collapse: collapse; font-size: 11.5px; margin-top: 4px; }
.ftable__csv-prevtable th { text-align: left; color: var(--t4); font-weight: 500; padding: 3px 6px; white-space: nowrap; }
.ftable__csv-prevtable td { padding: 3px 6px; border-top: 1px solid var(--line); }
.ftable__csv-actions { display: flex; align-items: center; gap: 10px; margin-top: 8px; }

.sform__bar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding-top: 14px; margin-top: 6px; border-top: 1px solid var(--line);
}
.sform__msg { flex: 1 1 auto; font-size: 12px; color: var(--t4); }
.sform__msg.is-ok  { color: var(--ok); }
.sform__msg.is-err { color: var(--err); font-weight: 500; }
.sform__done { font-size: 12px; color: var(--ok); font-weight: 500; padding-top: 14px; margin-top: 6px; border-top: 1px solid var(--line); }

/* ---------- 门 ---------- */

.panel--gate { border-left: 3px solid var(--brand); margin-top: 8px; }
.panel--gate.is-passed { border-left-color: var(--ok); }
.panel--gate h3 { font-size: 14.5px; }

/* 方案卡 / 阶段工作台上门的一行状态 + 链接——不再放签字/打回控件，
   那一整套判据/证据/签字挪到独立的门页（openGate）。*/
.panel--gatelink {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  flex-wrap: wrap; margin-top: 8px; border-left: 3px solid var(--brand);
}
.panel--gatelink.is-waiting { border-left-color: var(--warn); }
.panel--gatelink.is-bounced { border-left-color: var(--err); }
.panel--gatelink.is-passed  { border-left-color: var(--ok); }
.panel--gatelink .gatelink__t { font-size: 13px; color: var(--t2); }
.gatecheck { display: flex; flex-direction: column; gap: 2px; margin: 8px 0 12px;
             background: var(--subtle); border-radius: var(--r-sm); padding: 10px 12px; }
.gatescore { margin: 8px 0 12px; }
.gatescore__row {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 5px 0; border-bottom: 1px solid var(--line); font-size: 12.5px; color: var(--t2);
}
.gatescore__row em { font-style: normal; color: var(--t4); font-size: 11px; }
.gatescore__row input { width: 74px; text-align: right; }
.gatescore__total { text-align: right; font-size: 12.5px; color: var(--t3); padding-top: 8px; }
.gatescore__total b { font-size: 18px; color: var(--t1); font-variant-numeric: tabular-nums; }

/* ---------- 周评审的本周议题（L3 自动进的） ---------- */

.agenda {
  background: var(--card); border: 1px solid var(--line); border-left: 3px solid var(--err);
  border-radius: var(--r); padding: 14px 16px; margin: 0 0 16px; box-shadow: var(--sh);
}
.agenda h3 { font-size: 14px; margin-bottom: 10px; }
.agenda__row {
  display: grid; grid-template-columns: 30px 1fr auto auto; gap: 10px; align-items: center;
  padding: 7px 0; border-bottom: 1px solid var(--line); font-size: 12.5px; color: var(--t3);
}
.agenda__lv {
  background: var(--err); color: #fff; border-radius: var(--r-xs);
  font-size: 10px; font-weight: 700; text-align: center; padding: 2px 0;
}
.agenda__lv--gate { background: var(--brand); }
.agenda__t { color: var(--t1); }
.agenda__d { color: var(--err); font-weight: 500; }
.agenda__w { color: var(--t4); font-size: 11.5px; }
.agenda .note { margin-top: 10px; }

/* ---------- 卡点分布 ---------- */

.wanalysis { display: flex; flex-direction: column; }
.wanalysis__row {
  display: grid; grid-template-columns: 150px 1fr 92px 150px 130px; gap: 12px; align-items: center;
  padding: 7px 0; border-bottom: 1px solid var(--line); font-size: 12px; color: var(--t3);
}
.wanalysis__row:last-child { border-bottom: 0; }
.wanalysis__k { color: var(--t1); font-weight: 500; }
.wanalysis__bar { height: 7px; background: var(--subtle); border-radius: 4px; overflow: hidden; }
.wanalysis__bar i { display: block; height: 100%; background: var(--brand); }
.wanalysis__n { text-align: right; font-variant-numeric: tabular-nums; color: var(--t4); }
.wanalysis__p { color: var(--t2); }
.wanalysis__a { color: var(--brand-dark); font-weight: 500; }
@media (max-width: 860px) {
  .wanalysis__row { grid-template-columns: 1fr auto; }
  .wanalysis__bar, .wanalysis__p, .wanalysis__a { grid-column: 1 / -1; }
}

/* ---------- 卡点登记 ---------- */

.panel--wait { border-left: 3px solid var(--warn); margin-top: 8px; }
/* 表单页底下这块提示原来是通栏的，横穿左侧步骤栏那一列。步骤栏现在能一直待到页底
   （见上面 --frail-tail），通栏就会被它压住。让这块跟表单正文左对齐——本来也该对齐，
   它讲的是这一段的事，不是整页的事。 */
.bench:has(.frail) .panel--wait { margin-left: calc(148px + 24px); }
.waitopts { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 6px; margin: 10px 0 12px; }
.waitopt {
  text-align: left; background: var(--card); border: 1px solid var(--line);
  border-radius: var(--r-sm); padding: 9px 12px; cursor: pointer;
  display: flex; flex-direction: column; gap: 2px; font: inherit; transition: all .15s;
}
.waitopt:hover { border-color: var(--brand-border); }
.waitopt.is-on { border-color: var(--brand); background: var(--brand-bg); }
.waitopt b { font-size: 12.5px; color: var(--t1); font-weight: 600; }
.waitopt span { font-size: 10.5px; color: var(--t4); line-height: 1.5; }
.waitopt.is-on b { color: var(--brand-dark); }

/* ================================================================
   ⚠️⚠️  测试模式 · 一键登录 —— 上线前删掉这一整段  ⚠️⚠️
   开着的时候界面上一直挂着红条，就是为了让人不可能忘记关。
   ================================================================ */

.devbar {
  /* 跟导航栏一样钉死在视口顶上，排在它上面一层（导航栏的 top 读 --devbar-h）。
     以前是 static、跟着内容滚走的，那样滚一屏之后导航栏底下会露出一条空白。
     两条都 fixed 之后位置关系固定，--devbar-h 和 --header-h 都由 syncHeaderH() 实测。 */
  position: fixed; top: 0; left: 0; right: 0; z-index: 40;
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  background: repeating-linear-gradient(45deg, #fee2e2, #fee2e2 12px, #fecaca 12px, #fecaca 24px);
  border-bottom: 2px solid var(--err);
  padding: 7px 20px; font-size: 12px; color: #7f1d1d;
}
.devbar__tag {
  background: var(--err); color: #fff; font-weight: 700; font-size: 10.5px;
  letter-spacing: .08em; padding: 2px 8px; border-radius: var(--r-xs);
}
.devbar__n { flex: 1 1 auto; }
.devbar__n b { color: #7f1d1d; }
.devbar__sw { display: flex; align-items: center; gap: 6px; }
.devbar__sw select { width: auto; padding: 3px 8px; font-size: 12px; border-color: var(--err); }

/* 演示环境用同一条横幅，但不用报警色。
   红底斜纹是「你把测试模式开着了」的告警；给全公司看的演示环境本来就该开着，
   摆一条红色警报只会让人以为系统坏了。换成信息蓝——
   醒目、说得清「这是演示」，但不喊救命。
   ⚠️ 两套环境的区分不靠颜色，靠「有没有这条横幅」：正式环境一条都没有。 */
.devbar--demo {
  background: repeating-linear-gradient(45deg, #e0f2fe, #e0f2fe 12px, #bae6fd 12px, #bae6fd 24px);
  border-bottom-color: #0284c7; color: #075985;
}
.devbar--demo .devbar__tag { background: #0284c7; }
.devbar--demo .devbar__n b { color: #075985; }
.devbar--demo .devbar__sw select { border-color: #0284c7; }

.devbox {
  margin-top: 4px; border: 1px dashed var(--err); border-radius: var(--r-sm);
  background: var(--err-bg); padding: 12px 14px;
}
.devbox--demo { border-color: #0284c7; background: #f0f9ff; }
.devbox--demo .devbox__t { color: #075985; }
.devbox--demo .devbox__n { color: #0369a1; }
.devbox__t { font-size: 12.5px; font-weight: 700; color: #7f1d1d; }
.devbox__n { font-size: 11px; color: #991b1b; margin: 3px 0 10px; line-height: 1.6; }
.devbox__list { display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); gap: 5px; }
.devbtn {
  display: flex; flex-direction: column; gap: 1px; align-items: flex-start;
  background: var(--card); border: 1px solid #fca5a5; border-radius: var(--r-xs);
  padding: 6px 9px; cursor: pointer; font: inherit; transition: all .12s;
}
.devbtn:hover { border-color: var(--err); background: #fff5f5; }
.devbtn b { font-size: 12.5px; color: var(--t1); font-weight: 600; }
.devbtn span { font-size: 10px; color: var(--t4); }
.badge--bounced { background: var(--warn-bg); color: #b45309; cursor: help; }
.badge--待过门 { background: var(--brand-bg); color: var(--brand-dark); }
.badge--已完成 { background: var(--ok-bg); color: var(--ok); }

/* ================================================================
   入口：「我的」—— 我今天该干什么
   ================================================================ */

.mblock {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r);
  padding: 14px 16px; margin-bottom: 8px; box-shadow: var(--sh);
}
.mblock h3 { font-size: 14px; }
.mblock__n { margin: 3px 0 10px; font-size: 11.5px; color: var(--t4); line-height: 1.6; }
.mblock__ok { font-size: 12.5px; color: var(--t4); padding: 4px 0; }
.mrow {
  display: grid; grid-template-columns: 34px 74px 1fr auto auto auto;
  gap: 12px; align-items: center; cursor: pointer;
  padding: 9px 8px; margin: 0 -8px; border-radius: var(--r-sm);
  font-size: 12.5px; color: var(--t3); border-bottom: 1px solid var(--line);
}
.mrow:last-child { border-bottom: 0; }
.mrow:hover { background: var(--subtle); }
.mrow__id { font-weight: 700; color: var(--t1); font-variant-numeric: tabular-nums; font-size: 12px; }
.mrow__t { color: var(--t1); min-width: 0; }
.mrow__d { font-variant-numeric: tabular-nums; white-space: nowrap; }
.mrow__w { font-size: 11.5px; color: var(--t4); white-space: nowrap; }
.mlv {
  text-align: center; border-radius: var(--r-xs); font-size: 10px; font-weight: 700;
  padding: 3px 0; color: #fff; background: var(--t4);
}
.mlv--L1 { background: var(--warn); }
.mlv--L2 { background: var(--err); }
.mlv--L3 { background: #991b1b; }
.mlv--gate { background: var(--brand); }
.mlv--idea { background: var(--t4); }
.mwb {
  display: flex; justify-content: space-between; font-size: 12.5px; color: var(--t3);
  padding: 5px 0; border-bottom: 1px solid var(--line);
}
.mwb:last-child { border-bottom: 0; }
.mwb b { color: var(--t1); font-variant-numeric: tabular-nums; }

@media (max-width: 860px) {
  .mrow { grid-template-columns: 30px 1fr auto; }
  .mrow__w, .mrow .btn { grid-column: 1 / -1; }
}

/* ================================================================
   出口：交付物 / 项目档案
   这两页是「结果」不是「表单」—— 排版按文档来，能打印能复制。
   ================================================================ */

.doc { max-width: 940px; margin: 0 auto; }
.doc__bar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 4px 0 12px;
}
.doc__bar .bench__back { margin: 0; padding: 0; }
.doc__which { font-size: 12.5px; font-weight: 600; color: var(--t2); }
.doc__fill { font-size: 11.5px; color: var(--t4); }
.doc__fill.is-partial { color: var(--warn); font-weight: 500; }
.doc__bar .btn { margin-left: auto; }
.doc__bar .btn ~ .btn { margin-left: 0; }

.doc__page {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r);
  padding: 32px 40px 36px; box-shadow: var(--sh);
}
.doc__head { border-bottom: 2px solid var(--t1); padding-bottom: 14px; margin-bottom: 18px; }
.doc__title { font-size: 24px; font-weight: 600; color: var(--t1); letter-spacing: -.02em; }
.doc__sub { font-size: 13px; color: var(--t3); margin-top: 4px; }
.doc__meta { display: flex; flex-wrap: wrap; gap: 6px 18px; font-size: 11.5px; color: var(--t4); margin-top: 8px; }

/* 灵感图放进这一条常驻的「初衷」里——横排，图在左，文字栈在右，
   图的高度（64px）比原来纯文字那三行还矮，这一块不会因为加了图变高。 */
.doc__intent {
  display: flex; align-items: flex-start; gap: 12px;
  background: var(--brand-bg); border-left: 3px solid var(--brand);
  border-radius: var(--r-sm); padding: 11px 14px; margin-bottom: 20px;
}
.doc__intent-main { display: flex; flex-direction: column; gap: 3px; flex: 1 1 auto; min-width: 0; }
.doc__intent-img { width: 84px; height: 64px; object-fit: cover; border-radius: var(--r-sm); border: 1px solid var(--line); flex: 0 0 auto; }
.doc__intent .thumb-dead { width: 84px; height: 64px; border-radius: var(--r-sm); font-size: 9px; flex: 0 0 auto; }
.doc__intent .thumb-dead a { display: none; }
.doc__intent-k { font-size: 10.5px; font-weight: 700; color: var(--brand-dark); letter-spacing: .04em; }
.doc__intent-v { font-size: 15px; font-weight: 600; color: var(--t1); }
.doc__intent-n { font-size: 11.5px; color: var(--t3); }

.doc__sec { margin-bottom: 22px; }
.doc__sec h3 {
  font-size: 14px; padding-bottom: 6px; margin-bottom: 10px;
  border-bottom: 1px solid var(--line);
}
.dv { display: grid; grid-template-columns: 190px 1fr; gap: 16px; padding: 7px 0; align-items: start; }
.dv + .dv { border-top: 1px dashed var(--line); }
.dv__k { font-size: 12.5px; color: var(--t3); display: flex; align-items: baseline; gap: 5px; }
.dv__k em {
  font-style: normal; font-size: 9.5px; font-weight: 600;
  color: var(--brand-dark); background: var(--brand-bg);
  border-radius: var(--r-xs); padding: 0 4px;
}
.dv__v { font-size: 13.5px; color: var(--t1); line-height: 1.65; word-break: break-word; }
.dv--judge .dv__v { font-weight: 600; }
.dv__empty { color: var(--t4); }
.dv__chip {
  display: inline-block; background: var(--subtle); border-radius: var(--r-xs);
  padding: 1px 7px; margin: 0 4px 4px 0; font-size: 12px;
}
.dv__file { color: var(--t3); font-size: 12.5px; }
.dtable { width: 100%; table-layout: fixed; border-collapse: collapse; font-size: 12px; margin: 2px 0; }
.dtable th, .dtable td { border: 1px solid var(--line); padding: 5px 8px; text-align: left; overflow-wrap: break-word; word-break: break-word; }
.dtable th { background: var(--subtle); color: var(--t3); font-weight: 500; font-size: 11px; }

.doc__concl {
  display: flex; align-items: baseline; gap: 12px;
  background: var(--subtle); border-radius: var(--r-sm); padding: 12px 16px; margin-bottom: 18px;
}
.doc__concl-k { font-size: 12px; color: var(--t4); }
.doc__concl-v { font-size: 16px; font-weight: 700; color: var(--t1); }

.doc__gate { border-radius: var(--r-sm); padding: 12px 16px; border-left: 3px solid var(--t4); background: var(--subtle); }
.doc__gate.is-pass { border-left-color: var(--ok); background: var(--ok-bg); }
.doc__gate.is-back { border-left-color: var(--err); background: var(--err-bg); }
.doc__gate.is-wait { border-left-color: var(--brand); background: var(--brand-bg); }
.doc__gate-t { font-size: 13px; font-weight: 600; color: var(--t1); }
.doc__gate-b { font-size: 12.5px; color: var(--t3); margin-top: 4px; }
.doc__gate-n { margin-top: 5px; color: var(--t2); }

.dclocks { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 8px; margin-bottom: 20px; }
.dclock {
  background: var(--subtle); border-radius: var(--r-sm); padding: 10px 14px;
  border-left: 3px solid var(--t4);
}
.dclock.is-stopped { border-left-color: var(--ok); }
.dclock.is-over { border-left-color: var(--err); }
.dclock__k { font-size: 11px; color: var(--t4); display: block; }
.dclock__v { font-size: 20px; font-weight: 700; color: var(--t1); font-variant-numeric: tabular-nums; }
.dclock.is-over .dclock__v { color: var(--err); }
.dclock__n { font-size: 11px; color: var(--t4); display: block; }

.dback { display: flex; flex-direction: column; gap: 2px; padding: 9px 12px; margin-bottom: 6px;
         background: var(--err-bg); border-radius: var(--r-sm); border-left: 3px solid var(--err); }
.dback__w { font-size: 11.5px; font-weight: 600; color: var(--err); }
.dback__r { font-size: 13px; color: var(--t1); }
.dback__m { font-size: 11px; color: var(--t4); }

.dstage { border: 1px solid var(--line); border-radius: var(--r-sm); padding: 10px 14px; margin-bottom: 6px; }
.dstage.is-已完成 { border-left: 3px solid var(--ok); }
.dstage.is-进行中 { border-left: 3px solid var(--brand); }
.dstage.is-未开始 { opacity: .55; }
.dstage__h { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; font-size: 12px; color: var(--t4); }
.dstage__no {
  width: 20px; height: 20px; border-radius: 50%; background: var(--subtle); color: var(--t3);
  display: flex; align-items: center; justify-content: center; font-size: 10.5px; font-weight: 700;
}
.dstage.is-已完成 .dstage__no { background: var(--ok); color: #fff; }
.dstage.is-进行中 .dstage__no { background: var(--brand); color: #fff; }
.dstage__t { font-size: 13.5px; font-weight: 600; color: var(--t1); }
.dstage__d { color: var(--t3); }
.dstage__m { margin-left: auto; }
.dstage__j { margin-top: 8px; padding-top: 8px; border-top: 1px dashed var(--line); }
.dj { display: grid; grid-template-columns: 170px 1fr; gap: 12px; padding: 4px 0; font-size: 12.5px; }
.dj__k { color: var(--t4); }
.dj__v { color: var(--t1); min-width: 0; }
.dstage__n { font-size: 11.5px; color: var(--t4); margin-top: 6px; }
.dstage__c { margin-top: 7px; font-size: 12.5px; color: var(--t3); }
.dgate { margin-top: 8px; font-size: 12px; padding: 7px 10px; border-radius: var(--r-xs); }
.dgate.is-pass { background: var(--ok-bg); color: var(--ok); }
.dgate.is-back { background: var(--err-bg); color: var(--err); }
.dgate__n { color: var(--t2); margin-top: 3px; }

.dwait { display: grid; grid-template-columns: 66px 130px 1fr auto; gap: 10px;
         font-size: 12px; color: var(--t3); padding: 6px 0; border-bottom: 1px solid var(--line); }
.dwait:last-child { border-bottom: 0; }
.dwait__f { color: var(--t1); }
.dwait__m { color: var(--t4); font-size: 11px; }

.linkbtn2 {
  border: 0; background: transparent; color: var(--t4); cursor: pointer;
  font: inherit; font-size: 11.5px; padding: 2px 4px; white-space: nowrap;
}
.linkbtn2:hover { color: var(--brand); }

/* 打印：只留文档本身 */
@media print {
  .topbar, .devbar, .noprint, .benchbar { display: none !important; }
  body, .app, .main { background: #fff; }
  .doc { max-width: none; }
  .doc__page { border: 0; box-shadow: none; padding: 0; }
  .dstage.is-未开始 { display: none; }
  .doc__sec, .dstage, .dback, .doc__gate { break-inside: avoid; }
}

/* ================================================================
   布局收敛
   之前工作台是两栏，表单被挤在 593px 的窄栏里，右边空 4220px。
   现在表单占满宽，短字段并排 —— 同样的内容少滚一半的屏。
   ================================================================ */

.bench { display: block; }
.bench > .panel { margin-bottom: 8px; }

/* 初衷 + 载体 + 元信息压成一条 */
.istrip {
  display: flex; gap: 14px; align-items: flex-start;
  background: var(--card); border: 1px solid var(--line); border-left: 3px solid var(--brand);
  border-radius: var(--r); padding: 12px 16px; margin-bottom: 8px; box-shadow: var(--sh);
}
.istrip__img {
  width: 84px; height: 64px; object-fit: cover; border-radius: var(--r-sm);
  border: 1px solid var(--line); flex: 0 0 auto;
}
.istrip .thumb-dead { width: 84px; height: 64px; border-radius: var(--r-sm); font-size: 9px; flex: 0 0 auto; }
.istrip .thumb-dead a { display: none; }
.istrip__main { flex: 1 1 auto; min-width: 0; }
.istrip__k { font-size: 10.5px; font-weight: 600; color: var(--brand-dark); letter-spacing: .03em; }
.istrip__v { font-size: 15px; font-weight: 600; color: var(--t1); margin: 2px 0 4px; line-height: 1.5; }
.istrip__m { display: flex; flex-wrap: wrap; gap: 4px 14px; font-size: 11.5px; color: var(--t4); align-items: center; }
.istrip__carrier { flex: 0 0 260px; font-size: 12px; }
.istrip__carrier summary { color: var(--t4); cursor: pointer; }
.istrip__carrier .icard__carrier { margin-top: 6px; }

/* 字段两列 */
.fgrid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 22px; align-items: start; }
.ffield--full { grid-column: 1 / -1; }
.ffield--half { grid-column: span 1; }
.ffield { margin-bottom: 10px; }
.ffield__label { flex-wrap: wrap; margin-bottom: 4px; }
.ffield__h {
  font-style: normal; font-size: 11px; color: var(--t4); font-weight: 400;
  flex: 1 1 100%; line-height: 1.5;
}
.ffield__hint { margin: 0 0 5px; }
.fsec { padding: 12px 0 2px; }
.fsec--concl .fgrid { grid-template-columns: 1fr; }

/* 交付物页也跟着窄一点，读起来更像文档 */
@media (max-width: 1080px) {
  .fgrid { grid-template-columns: 1fr; }
  .istrip { flex-wrap: wrap; }
  .istrip__carrier { flex: 1 1 100%; }
}

/* ================================================================
   留痕型字段：链接 / 截图
   能贴链接的别写分析，能贴截图的别抄数字。
   ================================================================ */

.lks__list { display: flex; flex-direction: column; gap: 4px; margin-bottom: 6px; }
.lk {
  display: grid; grid-template-columns: auto minmax(0, 1fr) minmax(0, 1fr) auto;
  gap: 8px; align-items: center;
  background: var(--subtle); border-radius: var(--r-sm); padding: 6px 10px; font-size: 12.5px;
}
.lk__host {
  font-size: 10.5px; font-weight: 600; color: var(--brand-dark);
  background: var(--brand-bg); border-radius: var(--r-xs); padding: 1px 6px; white-space: nowrap;
}
.lk__u { color: var(--t2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lk__n { background: transparent; border: 0; border-bottom: 1px dashed var(--line); border-radius: 0; padding: 3px 2px; font-size: 12px; }
.lk__n:focus { box-shadow: none; border-bottom-color: var(--brand); }
.lks__add { display: flex; gap: 6px; }
.lks__in { flex: 1 1 auto; }

.shots__list { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 6px; }
.shot {
  margin: 0; width: 190px; position: relative;
  border: 1px solid var(--line); border-radius: var(--r-sm); overflow: hidden; background: var(--subtle);
}
.shot img { width: 100%; height: 118px; object-fit: cover; display: block; }
.shot__n { border: 0; border-top: 1px solid var(--line); border-radius: 0; font-size: 11.5px; padding: 5px 8px; }
.shot__n:focus { box-shadow: none; }
.shot__x {
  position: absolute; top: 3px; right: 3px; background: rgba(255,255,255,.92);
  border-radius: var(--r-xs); padding: 1px 6px; font-size: 11px;
}
.shots__drop {
  border: 1px dashed var(--line); border-radius: var(--r-sm);
  padding: 14px; text-align: center; font-size: 12px; color: var(--t4);
  background: var(--subtle); cursor: text; transition: all .15s;
}
.shots__drop:focus, .shots__drop.is-over { border-color: var(--brand); background: var(--brand-bg); color: var(--brand-dark); outline: none; }
.shots__drop b { color: var(--t2); }
.shots__pick { color: var(--brand); cursor: pointer; text-decoration: underline; }
.shots__msg { display: block; margin-top: 4px; color: var(--brand-dark); }

/* 交付物页里的链接和截图 */
.dv__links { display: flex; flex-direction: column; gap: 3px; }
.dv__shots { display: flex; flex-wrap: wrap; gap: 8px; }
.dv__shots figure { margin: 0; width: 210px; }
.dv__shots img { width: 100%; border: 1px solid var(--line); border-radius: var(--r-sm); display: block; }
.dv__shots figcaption { font-size: 11px; color: var(--t4); margin-top: 3px; }

/* AI 取数：只搬数据不做决定，所以这一条要说清楚边界 */
.aibar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  background: var(--subtle); border: 1px dashed var(--line);
  border-radius: var(--r-sm); padding: 9px 14px; margin-top: 12px;
}
.aibar__t { font-size: 12px; font-weight: 700; color: var(--t2); }
.aibar__n { font-size: 11.5px; color: var(--t4); flex: 1 1 220px; }
.aibar__n b { color: var(--t2); }
.aibar__msg { font-size: 11.5px; color: var(--brand-dark); }
.aibar__msg.is-err { color: var(--err); }
.tier.t-ai { color: #0369a1; background: #e0f2fe; cursor: help; }

/* ── 结构问询 ───────────────────────────────────────────────── */
.panel--inq h3 em { font-style: normal; font-weight: 400; color: var(--ink3); font-size: 12.5px; margin-left: 8px; }
.inq__cur { display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  border: 1px solid var(--line); border-radius: 8px; padding: 10px 12px; margin-bottom: 12px; background: var(--bg); }
.inq__cur.is-must { border-color: var(--brand); background: var(--weak); }
.inq__tag { font-size: 12px; padding: 2px 8px; border-radius: 4px; background: #fff; border: 1px solid var(--line); color: var(--ink2); }
.inq__cur.is-must .inq__tag { border-color: var(--brand); color: var(--brand); font-weight: 600; }
.inq__tag--ok { color: #00875a; border-color: #b7e8cd; }
.inq__tag--risk { color: #cb2634; border-color: #fbaca3; background: #ffece8; }
.inq__warn { flex: 1 1 100%; font-size: 12.5px; color: #a8630a; background: #fff7e8;
  border: 1px solid #ffcf8b; border-radius: 6px; padding: 6px 9px; }
.in-ro { padding: 8px 10px; border: 1px dashed var(--line); border-radius: 6px;
  background: var(--bg); color: var(--ink3); font-size: 13px; min-height: 36px; }
.inq__h { font-size: 13px; color: var(--ink2); margin: 16px 0 8px; font-weight: 600; }
.inq__item { border: 1px solid var(--line); border-radius: 8px; padding: 11px 13px; margin-bottom: 8px; }
.inq__item.is-open { border-color: var(--brand); background: #fffdfa; }
.inq__head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; font-size: 13px; }
.inq__who { color: var(--ink2); font-size: 12px; }
.inq__when { color: var(--ink3); font-size: 11.5px; margin-left: auto; }
.inq__q { margin-top: 6px; font-size: 13.5px; }
.inq__meta { margin-top: 4px; font-size: 12px; color: var(--ink3); }
.inq__reason { margin-top: 6px; font-size: 13px; color: var(--ink2);
  border-left: 3px solid var(--line); padding-left: 9px; }
.inq__verdict { font-size: 12px; font-weight: 600; padding: 2px 8px; border-radius: 4px; }
.inq__verdict--yes { color: #00875a; background: #e8fff3; }
.inq__verdict--no { color: #cb2634; background: #ffece8; }
.inq__verdict--maybe { color: #a8630a; background: #fff7e8; }
.inq__ansbox { margin-top: 9px; padding-top: 9px; border-top: 1px dashed var(--line); }
.inq__ansbox .opts { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 7px; }
.inq__ansbox .opt { display: inline-flex; align-items: center; gap: 5px; font-size: 13px;
  border: 1px solid var(--line); border-radius: 6px; padding: 5px 10px; cursor: pointer; background: #fff; }
.inq__ansbox textarea { width: 100%; }
.inq__hist { margin-top: 14px; }
.inq__hist > summary { cursor: pointer; font-size: 13px; color: var(--brand); padding: 8px 0; }


/* ════════════════════════════════════════════════════════════════
   表单区 · 2026-08-19 重做
   视觉沿用 ERP_CC（飞书体系）：浅灰底 + 白卡 + 4~6px 圆角 + 几乎不用阴影。
   色阶直接对齐 ERP_CC theme.py：
     #1f2329 主文字 · #646a73 次 · #8f959e 三级 · #dee0e3 边 · #f7f8fa 页底
   ════════════════════════════════════════════════════════════════ */
.sform {
  --f-ink:#1f2329; --f-ink2:#646a73; --f-ink3:#8f959e;
  --f-line:#dee0e3; --f-line2:#e7e9ec; --f-bg:#f7f8fa; --f-sub:#f0f1f3;
  --f-brand:#ed6c00; --f-brand-bg:#fff3e6; --f-brand-bd:#ffd5b0;
  --f-ok:#059669;
  display: grid; grid-template-columns: 148px minmax(0, 1fr);
  gap: 0 24px; align-items: start;
}
.sform__body { min-width: 0; }
.sform__bar { grid-column: 1 / -1; }

/* ── 路径条：四层结构直接摆在最上面，选到哪点亮到哪 ── */
.fpath {
  display: flex; align-items: stretch; flex-wrap: wrap; gap: 0;
  background: #fff; border: 1px solid var(--line, #dee0e3); border-radius: 6px;
  padding: 4px 6px; margin-bottom: 12px; overflow: hidden;
}
.fpath__i { display: flex; flex-direction: column; gap: 1px; padding: 6px 12px;
  border-radius: 4px; min-width: 0; cursor: pointer; }
.fpath__i:hover { background: #f7f8fa; }
.fpath__i em { font-style: normal; font-size: 11px; color: #8f959e; letter-spacing: .02em; }
.fpath__i b { font-size: 13px; font-weight: 500; color: #bbbfc4; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; max-width: 200px; }
.fpath__i.is-on b { color: #1f2329; font-weight: 600; }
.fpath__i.is-end b { color: #ed6c00; }
.fpath__arrow { align-self: center; color: #dee0e3; font-style: normal; font-size: 15px; }

/* ── 左侧步骤栏：常驻，看得见自己在哪、还剩多少 ── */
/* top 要让开固定顶栏 + 吸顶的工作台条，否则步骤栏会滑到它们底下（顶栏改 fixed 之后
   才暴露出来：写死的 12px 是相对视口顶算的，视口顶现在被顶栏占着）。 */
.frail { position: sticky; top: calc(var(--header-h, 50px) + var(--benchbar-h, 0px) + 12px);
  display: flex; flex-direction: column; gap: 1px;
  /* 窗口很矮时（实测 1280×460）条数比剩下的高度还多，会截掉最后一两条。
     给它一个上限，超了自己滚——截断是看不见，滚是看得见但要动一下，后者不骗人。 */
  max-height: calc(100vh - var(--header-h, 50px) - var(--benchbar-h, 0px) - 24px);
  overflow-y: auto; scrollbar-width: thin; }
.frail__i { display: flex; align-items: center; gap: 8px; padding: 7px 9px; border-radius: 5px;
  text-decoration: none; color: #646a73; font-size: 12.5px; line-height: 1.4;
  border-left: 2px solid transparent; }
.frail__i:hover { background: #f0f1f3; color: #1f2329; }
.frail__i.is-active { background: #fff3e6; border-left-color: #ed6c00; color: #1f2329; }
.frail__n { flex: none; width: 18px; height: 18px; border-radius: 50%; background: #f0f1f3;
  color: #8f959e; font-size: 11px; font-style: normal; display: grid; place-items: center; font-weight: 600; }
.frail__i.is-part .frail__n { background: #fff3e6; color: #ed6c00; }
.frail__i.is-done .frail__n { background: #059669; color: #fff; }
.frail__t { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.frail__c { flex: none; font-style: normal; font-size: 11px; color: #bbbfc4; font-variant-numeric: tabular-nums; }
.frail__i--end { margin-top: 6px; padding-top: 11px; border-top: 1px solid #e7e9ec; border-radius: 0 0 5px 5px; }

/* ── 区块：不再是白框叠白框，只用一条细线和一个编号分开 ── */
.sform .fsec { background: #fff; border: 1px solid #e7e9ec; border-radius: 6px;
  padding: 14px 16px 4px; margin-bottom: 10px; box-shadow: none; scroll-margin-top: 16px; }
.sform .fsec__h { display: flex; align-items: baseline; gap: 10px; margin-bottom: 2px; }
.sform .fsec__h h4 { font-size: 14.5px; font-weight: 600; color: #1f2329; margin: 0; }
.fsec__c { font-size: 11.5px; color: #bbbfc4; font-variant-numeric: tabular-nums;
  border: 1px solid #e7e9ec; border-radius: 10px; padding: 0 7px; }
.fsec__c.is-done { color: #059669; border-color: #b7e8cd; background: #ecfdf5; }
.sform .fsec__note { font-size: 12px; color: #8f959e; line-height: 1.7; margin: 4px 0 10px; }
.sform .fsec--concl { border-color: #ffd5b0; background: #fffaf5; }
.sform .fsec--concl .fsec__h h4 { color: #ed6c00; }

/* ── 字段：密排，提示收到标签右边 ── */
.sform .fgrid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 20px; }
.sform .ffield { padding: 9px 0 11px; border-top: 1px solid #f0f1f3; min-width: 0; }
.sform .fgrid > .ffield:nth-child(-n+2) { border-top: 0; }
.sform .ffield--full { grid-column: 1 / -1; }
.sform .ffield--full + .ffield { border-top: 1px solid #f0f1f3; }
.sform .ffield__label { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap;
  font-size: 13px; font-weight: 600; color: #1f2329; margin-bottom: 5px; }
.sform .ffield__h { font-style: normal; font-weight: 400; font-size: 11.5px; color: #8f959e; }
.sform .ffield__hint { font-size: 11.5px; color: #8f959e; line-height: 1.6; margin: -2px 0 6px; }
.sform .req { font-size: 10.5px; color: #ff4d4f; font-style: normal; font-weight: 500; }
.sform .tier { font-size: 10px; font-style: normal; font-weight: 500; padding: 0 5px;
  border-radius: 3px; border: 1px solid; }
.sform .t-judge { color: #ed6c00; border-color: #ffd5b0; background: #fff3e6; }
.sform .t-real  { color: #646a73; border-color: #dee0e3; background: #f7f8fa; }
.sform .t-ai    { color: #1677ff; border-color: #bedaff; background: #f0f7ff; }

.sform input[type=text], .sform input[type=number], .sform input[type=date],
.sform select, .sform textarea {
  width: 100%; border: 1px solid #dee0e3; border-radius: 5px; padding: 7px 10px;
  font-size: 13.5px; color: #1f2329; background: #fff; font-family: inherit; line-height: 1.5;
}
.sform textarea { resize: vertical; min-height: 54px; }
.sform input:focus, .sform select:focus, .sform textarea:focus {
  outline: none; border-color: #ed6c00; box-shadow: 0 0 0 2px #fff3e6; }
.sform ::placeholder { color: #bbbfc4; }

/* ── radio 改连体分段器：一眼看出是"选一个"，不是"四个按钮" ── */
.sform .chips[data-kind=radio] { display: inline-flex; border: 1px solid #dee0e3;
  border-radius: 5px; overflow: hidden; background: #fff; flex-wrap: wrap; }
.sform .chips[data-kind=radio] .chip { border: 0; border-right: 1px solid #dee0e3;
  border-radius: 0; padding: 6px 13px; font-size: 13px; background: #fff; color: #646a73;
  cursor: pointer; font-family: inherit; }
.sform .chips[data-kind=radio] .chip:last-child { border-right: 0; }
.sform .chips[data-kind=radio] .chip:hover { background: #f7f8fa; }
.sform .chips[data-kind=radio] .chip.is-on { background: #ed6c00; color: #fff; font-weight: 600; }
.sform .chips[data-kind=multi] { display: flex; flex-wrap: wrap; gap: 6px; }
.sform .chips[data-kind=multi] .chip { border: 1px solid #dee0e3; border-radius: 4px;
  padding: 5px 10px; font-size: 12.5px; background: #fff; color: #646a73; cursor: pointer; font-family: inherit; }
.sform .chips[data-kind=multi] .chip.is-on { border-color: #ed6c00; background: #fff3e6; color: #ed6c00; font-weight: 600; }

/* ── 自检：折起来，别当成一屏文字墙 ── */
.fcheck { border: 1px solid #e7e9ec; border-radius: 6px; background: #fff; margin-bottom: 10px; }
.fcheck > summary { cursor: pointer; padding: 11px 16px; font-size: 13px; color: #646a73; }
.fcheck > summary::marker { color: #bbbfc4; }
.fcheck .checklist { margin: 0; padding: 0 16px 12px 34px; }
.fcheck .checklist li { font-size: 12.5px; color: #8f959e; line-height: 1.85; }

/* ── AI 取数：一条细线，不再占一个卡 ── */
.sform .aibar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  border: 1px dashed #dee0e3; border-radius: 6px; padding: 9px 14px; background: #fafbfc; margin-bottom: 10px; }
.sform .aibar__t { font-size: 12.5px; font-weight: 600; color: #1677ff; }
.sform .aibar__n { font-size: 11.5px; color: #8f959e; flex: 1; min-width: 180px; }

.sform__bar { display: flex; align-items: center; gap: 10px; justify-content: flex-end;
  padding: 12px 0 0; margin-top: 2px; border-top: 1px solid #e7e9ec; }
.sform__msg { margin-right: auto; font-size: 12.5px; color: #646a73; }
.sform__msg.is-ok { color: #059669; }
.sform__msg.is-err { color: #ff4d4f; }

@media (max-width: 900px) {
  .sform { grid-template-columns: 1fr; }
  .frail { position: static; flex-direction: row; overflow-x: auto; margin-bottom: 10px; }
  .frail__i { border-left: 0; border-bottom: 2px solid transparent; white-space: nowrap; }
  .frail__i.is-active { border-left: 0; border-bottom-color: #ed6c00; }
  .sform .fgrid { grid-template-columns: 1fr; }
}
.sform .ffield.is-flash { animation: fflash .9s ease; }
@keyframes fflash { 0%,100% { background: transparent; } 25% { background: #fff3e6; } }
.sform .fsec__note b { color: #646a73; font-weight: 600; }
.fsec__note--long { margin: 4px 0 10px; }
.fsec__note--long > summary { cursor: pointer; font-size: 12px; color: #8f959e; line-height: 1.7; list-style: none; }
.fsec__note--long > summary::-webkit-details-marker { display: none; }
.fsec__note--long > summary em { font-style: normal; color: #ed6c00; margin-left: 6px; font-size: 11.5px; }
.fsec__note--long[open] > summary em { display: none; }
.fsec__note--long > div { font-size: 12px; color: #8f959e; line-height: 1.75; padding-top: 2px; }
.sform optgroup { font-size: 12px; color: #8f959e; }
.sform optgroup option { color: #1f2329; }
/* 留痕框收紧：贴链接和粘图不该占掉半屏 */
.sform .shots__drop { padding: 12px 10px; font-size: 12px; border-radius: 5px; }
.sform .links__row input { font-size: 13px; }
.sform .shots__grid { gap: 6px; }
.sform .shot { width: 64px; height: 64px; }
.sform .ffield--half { min-width: 0; }

/* =====================================================================
   层 2 · 方案卡—— 照 demo4/index.html 定稿样稿实现，class 前缀 pc- 隔离。
   一格一卡；卡片结构固定三层：名词标题+?+状态 → 一行 hint → 控件；
   提示不进 placeholder；为什么/规则/例子全部进抽屉。
   ========================================================================== */

.pc-crumb { font-size: 12px; color: var(--t3); margin-bottom: 12px; }
.pc-crumb b { color: var(--t1); }

.pc-say {
  background: var(--card); border: 1px solid var(--brand-border); border-left: 3px solid var(--brand);
  border-radius: var(--r); padding: 14px 18px; font-size: 15px; line-height: 1.95; margin-bottom: 16px;
}
.pc-say b { color: var(--brand); font-weight: 600; }
.pc-say .pc-miss { color: var(--t4); font-weight: 500; border-bottom: 1px dashed var(--t4); }

.pc-cards { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.pc-c { background: var(--card); border: 1px solid var(--line); border-radius: var(--r); padding: 15px 16px 16px; }
.pc-c.full { grid-column: 1 / -1; }
.pc-c.now { border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-bg); }
.pc-c__h { display: flex; align-items: center; gap: 7px; margin-bottom: 3px; }
.pc-c__q { font-size: 15px; font-weight: 600; color: var(--t1); }
.pc-c__i {
  width: 16px; height: 16px; border-radius: 50%; border: 1px solid var(--line); color: var(--t3);
  font-size: 10px; display: grid; place-items: center; cursor: pointer; flex: none; background: var(--card);
}
.pc-c__i:hover { border-color: var(--brand); color: var(--brand); background: var(--brand-bg); }
.pc-c__lock { margin-left: auto; font-size: 10.5px; color: var(--t4); }
.pc-c__lock.is-missing { color: var(--err); }
/* ⚠ 提示不放 placeholder：一打字就被盖掉，想重看还得把输入删掉。
   压缩成一行，常驻在控件上方，永远看得见。 */
.pc-c__hint { font-size: 12px; color: var(--t3); margin-top: 7px; line-height: 1.6; }
.pc-c__v { margin-top: 9px; font-size: 14px; }
.pc-c__ro { padding: 8px 11px; border-radius: var(--r-sm); background: var(--bg); color: var(--t1); font-size: 14px; }
.pc-c__ro.pc-empty { color: var(--t4); }
.pc-sublabel { font-size: 12px; color: var(--t3); margin-bottom: 4px; }

.pc-in {
  width: 100%; border: 1px solid var(--line); border-radius: var(--r-sm); padding: 9px 11px;
  font-size: 14px; font-family: inherit; color: var(--t1); background: var(--card);
}
.pc-in:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-bg); }
.pc-c.now .pc-in { border-color: var(--brand); }
textarea.pc-in { resize: vertical; }

.pc-seg { display: inline-flex; flex-wrap: wrap; border: 1px solid var(--line); border-radius: var(--r-sm); overflow: hidden; margin-top: 9px; }
.pc-seg span {
  padding: 7px 12px; font-size: 12.5px; color: var(--t3); border-right: 1px solid var(--line);
  background: var(--card); cursor: pointer; user-select: none;
}
.pc-seg span:last-child { border-right: 0; }
.pc-seg span.on { background: var(--brand); color: #fff; font-weight: 600; }
.pc-seg span:hover:not(.on) { color: var(--brand); }

.pc-alert {
  margin-top: 10px; background: var(--warn-bg); border: 1px solid #ffcf8b; border-radius: var(--r-sm);
  padding: 9px 11px; font-size: 12.5px; color: #a8630a; line-height: 1.6;
}
.pc-alert b { color: #a8630a; }
.pc-alert--conflict { background: var(--warn-bg); border-color: #ffcf8b; color: #a8630a; }

/* 参照物表：第一行是主参照物，标一个小标签；目标售价的差额是浅字提示，不是规则。 */
.pc-reftable__tag {
  display: inline-block; font-size: 10.5px; font-weight: 600; color: var(--brand);
  background: var(--brand-bg); border-radius: var(--r-sm); padding: 2px 6px; white-space: nowrap;
}
.pc-diff { font-weight: 400; color: var(--t3); }

.pc-foot {
  display: flex; gap: 9px; align-items: center; margin-top: 14px; background: var(--card);
  border: 1px solid var(--line); border-radius: var(--r); padding: 12px 16px;
}
.pc-fm { margin-right: auto; font-size: 12.5px; color: var(--t3); }
.pc-fm b.is-err { color: var(--err); }

.pc-picker {
  background: var(--card); border: 1px dashed var(--line); border-radius: var(--r);
  padding: 24px; text-align: center; color: var(--t3); font-size: 13px;
}
.pc-picker select { margin: 10px 8px 0; }

/* ── 抽屉：checkbox + label + aside 三兄弟，靠原生 :checked 驱动，零 JS ──
   ⚠️ 这里必须用相邻兄弟 + ，不能用 ~ 。
   六个抽屉是并列的兄弟节点（input, label.pc-dt, aside.pc-dw × 6），
   用 ~ 会命中它后面所有的 .pc-dt / .pc-dw —— 点任何一个「?」六个抽屉全部打开，
   叠在一起，看到的永远是最后那个。这是 2026-08-20 demo4 踩过的 bug，这里照抄教训。 */
.pc-d { position: absolute; opacity: 0; pointer-events: none; }
/* 抽屉/遮罩以前是 inset:0 / top:0，物理盖住顶栏（顶栏 z-index 20 < 遮罩 60）。
   现在从顶栏实际渲染高度往下开始——`--header-h` 由 app.js 的 syncHeaderH() 按
   .topbar 的 getBoundingClientRect().bottom 实时算好写进 :root，自动扣掉测试模式
   devbar 的高度（devbar 上线前会删，这里不能写死 50 否则那天就错位）。
   var() 的 50px 只是 JS 跑之前那一瞬间的兜底值。
   transition 只放在各自会变化的属性上（opacity / transform），不用 all——
   否则 --header-h 随 resize/scroll 更新时，top 也会跟着做位移动画，看起来像抽屉在漂。 */
.pc-dt {
  position: fixed; top: var(--header-h, 50px); left: 0; right: 0; bottom: 0;
  background: rgba(31, 35, 41, .28); opacity: 0; pointer-events: none;
  transition: opacity .18s; z-index: 60;
}
.pc-dw {
  position: fixed; top: var(--header-h, 50px); right: 0; bottom: 0; width: 420px; max-width: 92vw;
  background: var(--card); border-left: 1px solid var(--line); transform: translateX(100%);
  transition: transform .22s cubic-bezier(.4, 0, .2, 1);
  z-index: 61; display: flex; flex-direction: column;
}
.pc-d:checked + .pc-dt { opacity: 1; pointer-events: auto; }
.pc-d:checked + .pc-dt + .pc-dw { transform: translateX(0); }
.pc-dw__h { padding: 15px 18px; border-bottom: 1px solid var(--line-2); display: flex; align-items: center; gap: 10px; }
.pc-dw__t { font-size: 15px; font-weight: 600; color: var(--t1); }
.pc-dw__x {
  margin-left: auto; width: 26px; height: 26px; border-radius: var(--r-xs); display: grid; place-items: center;
  color: var(--t3); cursor: pointer; font-size: 16px;
}
.pc-dw__x:hover { background: var(--subtle); }
.pc-dw__b { padding: 16px 18px 40px; overflow-y: auto; flex: 1; }
.agent-drawer { width: 480px; }
.agent-section + .agent-section { border-top: 1px solid var(--line); margin-top: 24px; padding-top: 20px; }
.agent-section h3 { margin: 0 0 10px; font-size: 16px; }
.agent-section p { line-height: 1.6; }
.agent-heading, .agent-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.agent-heading { justify-content: space-between; }
.agent-check { display: flex; align-items: flex-start; gap: 8px; margin: 14px 0; }
.agent-check input { width: auto; margin-top: 4px; }
.agent-help, .agent-source { color: var(--t2); font-size: 12px; }
.agent-diff { border: 1px solid var(--line); border-radius: 8px; padding: 12px; margin: 12px 0; overflow-wrap: anywhere; }
.agent-diff h4 { margin: 0 0 10px; font-size: 14px; }
.agent-before, .agent-proposed { display: grid; grid-template-columns: 32px minmax(0, 1fr); gap: 8px; margin: 8px 0; }
.agent-before > span, .agent-proposed > span { font-size: 12px; color: var(--t2); }
.agent-diff p { margin: 0; white-space: pre-wrap; }
.connector-panel { margin-bottom: 16px; max-width: 880px; }
.connector-panel input { min-width: 0; width: 100%; }
.connector-form { display: flex; align-items: end; gap: 12px; flex-wrap: wrap; margin: 18px 0; }
.connector-form .field:first-child { flex: 1; min-width: 160px; }
.connector-form .field { margin: 0; }
.connector-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 14px 0; border-bottom: 1px solid var(--line); overflow-wrap: anywhere; }
.connector-row:last-child { border-bottom: 0; }
.agent-source { border-top: 1px solid var(--line); padding-top: 8px; }
#agentMessage { overflow-wrap: anywhere; }

.pc-sec { margin-bottom: 20px; }
.pc-sec__t { font-size: 12px; font-weight: 600; color: var(--brand); letter-spacing: .03em; margin-bottom: 6px; }
.pc-sec p { font-size: 13.5px; color: var(--t3); line-height: 1.85; margin: 0; }
.pc-sec ul { margin: 6px 0 0 18px; }
.pc-sec li { font-size: 13.5px; color: var(--t3); line-height: 1.85; margin-bottom: 3px; }
.pc-bad {
  background: var(--err-bg); border: 1px solid #fbaca3; border-radius: var(--r-sm); padding: 10px 12px;
  font-size: 13px; color: #8f1d1d; line-height: 1.8; margin-top: 8px;
}
.pc-good {
  background: var(--ok-bg); border: 1px solid #b7e8cd; border-radius: var(--r-sm); padding: 10px 12px;
  font-size: 13px; color: #0a6b4a; line-height: 1.8;
}
.pc-ex {
  background: var(--bg); border: 1px solid var(--line-2); border-radius: var(--r-sm); padding: 10px 12px;
  font-size: 13px; color: var(--t3); line-height: 1.8; margin-top: 8px;
}
.pc-ex b { color: var(--t1); }
/* 完整示例：明确标注是示例，别让人当成必须照抄 */
.pc-demo { border: 1px solid var(--brand-border); border-radius: var(--r-sm); overflow: hidden; margin-top: 4px; }
.pc-demo__h {
  background: var(--brand-bg); color: var(--brand); font-size: 11.5px; font-weight: 600; padding: 6px 11px;
  border-bottom: 1px solid var(--brand-border);
}
.pc-demo__b { padding: 10px 12px; font-size: 13px; line-height: 1.85; color: var(--t3); }
.pc-demo__b b { color: var(--t1); }
.pc-demo__r { display: grid; grid-template-columns: 96px 1fr; gap: 6px 8px; }
.pc-demo__r span:nth-child(odd) { color: var(--t4); font-size: 12px; }

/* 对账区 —— 跟普通表单区分开：这是「方案说的」跟「实际做到的」当面对，不是又一组要填的字段 */
.fsec--rec { border-left: 3px solid var(--brand, #ed6c00); }
.frec { border: 1px solid #e5e6eb; border-radius: 4px; padding: 12px 14px; margin-top: 10px; background: #fff; }
.frec + .frec { margin-top: 12px; }
.frec__t { font-weight: 600; color: #1f2329; margin-bottom: 8px; }
.frec__bar { display: flex; align-items: center; gap: 10px; justify-content: flex-end; margin-top: 10px; }
.frec__msg { font-size: 12px; color: #646a73; margin-right: auto; }
.frec__msg.is-err { color: #d83931; }
.frec__by { font-size: 12px; color: #8f959e; margin-top: 8px; }
.frec__r--达成 { color: #2ba471; }
.frec__r--让步接收 { color: #d97b00; }
.frec__r--未达 { color: #d83931; }

/* P3 · 阶段 6 落档算式摊开 / 阶段 7 成本自动带出——都是"摆出来供人核对的计算结果"，
   跟要填的字段区分开一个浅底卡片，别让人误以为这是又一组输入框。 */
.freight-breakdown, .cost-computed {
  background: var(--subtle); border-radius: var(--r-sm); padding: 12px 14px; margin-bottom: 12px; font-size: 12.5px;
}
.fb__empty { color: var(--t4); margin: 0; }
.fb__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 8px 16px; margin-bottom: 8px; }
.fb__i { display: flex; flex-direction: column; gap: 2px; }
.fb__i em { font-style: normal; font-size: 11px; color: var(--t4); }
.fb__i b { font-size: 13.5px; color: var(--t1); }
.fb__result { margin: 8px 0 0; font-size: 13px; color: var(--t1); line-height: 1.7; }
.fb__result--warn { color: #a8630a; }
.fb__why { color: var(--t3); font-size: 11.5px; }
.fb__drawer { margin-top: 10px; }
.fb__drawer summary { cursor: pointer; color: var(--brand-dark, var(--brand)); font-size: 12px; }
.fb__table { width: 100%; border-collapse: collapse; table-layout: fixed; font-size: 11.5px; margin-top: 8px; }
.fb__table th, .fb__table td {
  border: 1px solid var(--line); padding: 4px 6px; text-align: left;
  overflow-wrap: break-word; word-break: break-word;
}
.fb__table th { background: var(--card, #fff); color: var(--t3); font-weight: 600; }
.fb__assump { font-size: 11px; color: var(--t4); margin: 8px 0 0; line-height: 1.6; }

.cc__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 8px 16px; }
.cc__i { display: flex; flex-direction: column; gap: 2px; }
.cc__i em { font-style: normal; font-size: 11px; color: var(--t4); }
.cc__i b { font-size: 13.5px; color: var(--t1); }
.cc__i--override b { color: #a8630a; }
.cc__note { margin: 8px 0 0; font-size: 11.5px; color: var(--t4); line-height: 1.6; }

/* 阶段14「目标成本·出厂」配阶段7实际FOB、「目标落地成本·全口径」配实际落地成本——
   两组分开摆、成对呈现，靠这条线隔开，不让人把两组的数字混着比。 */
.cc__pair { padding: 4px 0; }
.cc__pair + .cc__pair { margin-top: 10px; padding-top: 10px; border-top: 1px dashed var(--line); }

/* 标题右边挂一个「?」开抽屉。h3 是块级，直接塞进去那个圆点会掉到下一行。 */
.panel > h3.panel__h { display: flex; align-items: center; gap: 8px; }

/* 打回弹层：退回上游某一段。不做成一个下拉就直接生效——退回去意味着中间几段作废，
   必须先说清楚退到哪、为什么。 */
.bouncebox { position: fixed; inset: 0; z-index: 60; background: rgba(15,17,20,.38);
  display: flex; align-items: center; justify-content: center; }
.bouncebox__inner { background: var(--card); border-radius: var(--r); box-shadow: var(--sh);
  padding: 18px 20px; width: 460px; max-width: 92vw; }
.bouncebox__t { font-size: 15px; font-weight: 600; color: var(--t1); margin-bottom: 4px; }
.bouncebox__p { margin: 0 0 12px; font-size: 12px; color: var(--t3); line-height: 1.6; }
.bouncebox__act { display: flex; justify-content: flex-end; gap: 8px; margin-top: 12px; }

/* 门页证据里的两种提示：对得上（绿）/ 该问一句（黄）。 */
.badge--ok   { background: var(--ok-bg);   color: var(--ok); }
.badge--warn { background: var(--warn-bg); color: var(--warn); }
/* 「不符合，但只是提醒项」——摆事实，不报警。 */
.badge--soft { background: var(--subtle);  color: var(--t3); }

/* 门一的软性警告：不拦人，但签字前必须看得到。 */
.gatewarn { margin: 10px 0 0; padding: 10px 12px; border-radius: var(--r-sm);
  background: var(--warn-bg); border-left: 3px solid var(--warn); }
.gatewarn__t { font-size: 12px; font-weight: 600; color: var(--warn); margin-bottom: 4px; }
.gatewarn ul { margin: 0; padding-left: 18px; font-size: 12px; color: var(--t2); line-height: 1.7; }

/* 方案卡顶上「这条赌注是怎么来的」——填下面六格的前提，不是补充材料，默认展开。 */
.originbox { margin: 0 0 14px; border: 1px solid var(--brand-border); border-radius: var(--r-sm);
  background: var(--brand-bg); padding: 10px 14px; }
.originbox > summary { cursor: pointer; font-size: 12.5px; font-weight: 600; color: var(--brand-dark); }
.originbox__b { margin-top: 8px; }
.originbox__b .kv__k { color: var(--t3); }

/* 「当时看到的」——④成因证据的原始材料，不收进折叠里。 */
.istrip__note { margin: 3px 0 2px; font-size: 12px; color: var(--t3); line-height: 1.6; }

/* 终止之后整条链条画灰：项目已经死了，再挂绿勾会让人以为它还活着。
   停在哪一段仍然用红点标出来（is-stopped）——死在哪儿是判例的一部分。 */
.rail__node.is-dead .rail__dot { background: #d7dade; color: #fff; }
.rail__node.is-dead .rail__name { color: #b4b9bd; }
.rail__line.is-dead { background: #e7e9ec; }

/* 门页的检查清单：一条判据一个区块，证据摆在它自己底下（Ken 2026-08-27）。 */
.gchecks { display: flex; flex-direction: column; gap: 10px; margin-top: 10px; }
.gcheck { border: 1px solid var(--line); border-radius: var(--r-sm); padding: 10px 12px; background: var(--card); }
.gcheck.is-no { border-color: var(--warn); background: var(--warn-bg); }
.gcheck__h { display: flex; align-items: center; gap: 8px; cursor: pointer; flex-wrap: wrap; }
.gcheck__n { flex: none; width: 18px; height: 18px; border-radius: 50%; background: var(--gray-bg);
  color: var(--t3); font-size: 11px; display: grid; place-items: center; font-weight: 600; }
.gcheck__t { font-size: 13px; font-weight: 600; color: var(--t1); }
.gcheck__b { margin: 6px 0 0 26px; }
.gcheck__b .kv__k { color: var(--t3); }
.gchecks__mark { font-size: 13px; color: var(--t4); width: 16px; text-align: center; }
.gchecks__mark.is-ok { color: var(--ok); }
.gchecks__mark.is-no { color: var(--warn); }

/* 「这一段不用填」——这条路走过、只是落到了另一支（CLAUDE.md 第十一条：置灰 + 一句为什么）。
   不隐藏：隐藏会让分区编号跳号，人更懵。 */
.fsec--skipped { opacity: .62; }
.fsec--skipped h4 { color: var(--t3); font-weight: 500; }
.fsec__skip { font-size: 11px; color: var(--t4); background: var(--gray-bg);
  border-radius: var(--r-xs); padding: 1px 7px; }
.fsec__note { margin: 4px 0 0; font-size: 12px; color: var(--t3); line-height: 1.6; }

/* 上传位：真能传文件（检测报告这类）。原来只是个文本框，抽屉却写着「传上来」。 */
.uploadbox__act { display: flex; align-items: center; gap: 10px; margin-top: 6px; flex-wrap: wrap; }
.uploadbox__pick { font-size: 12px; color: var(--brand-dark); background: var(--brand-bg);
  border: 1px solid var(--brand-border); border-radius: var(--r-xs); padding: 3px 10px; cursor: pointer; }
.uploadbox__pick:hover { background: var(--brand-border); }
.uploadbox__msg { font-size: 11.5px; color: var(--t3); }
.uploadbox__msg.is-ok { color: var(--ok); }
.uploadbox__msg.is-err { color: var(--err); }

/* 这一段为什么只能看 / 你在代谁填。服务端 stageWriteGuard 是同一套判断。 */
.notehere { margin: 8px 0; padding: 9px 12px; border-radius: var(--r-sm); font-size: 12.5px; line-height: 1.6; }
.notehere--ro { background: var(--gray-bg); color: var(--t2); border-left: 3px solid var(--line); }
.notehere--proxy { background: var(--warn-bg); color: var(--warn); border-left: 3px solid var(--warn); }

/* 每条判据要么写出「系统按什么判的」，要么说清「你要自己判什么」——不许含糊过去。 */
.gcheck__basis { margin: 0 0 6px; font-size: 11.5px; color: var(--t4); line-height: 1.6; }
.gcheck__human { margin: 0 0 6px; padding: 6px 9px; border-radius: var(--r-xs);
  background: var(--warn-bg); color: var(--warn); font-size: 12px; line-height: 1.6; }

/* 「记完之后底下的数被改过」——不动记录，只说清楚。 */
.frec__stale { margin-top: 8px; padding: 8px 11px; border-radius: var(--r-xs);
  background: var(--warn-bg); color: var(--warn); font-size: 12px; line-height: 1.7; }
.panel--stale { border-left: 3px solid var(--warn); background: var(--warn-bg); }
.panel--stale h3 { color: var(--warn); }

/* 字段级权限：这一格归别的角色填，画成只读值 + 一句谁填（Ken 2026-08-28） */
.ffield.is-otherrole { opacity: .82; }
.ffield__hint--lock { color: var(--brand-dark); margin-top: 4px; }

/* 合规类必过项硬过：原因类型 + 二级复核人（Ken 2026-08-28） */
.ovbox { border: 1px solid var(--warn); border-radius: 8px; padding: 12px 14px; margin-bottom: 12px; background: #fffaf3; }
.ovbox__t { font-size: 13px; font-weight: 600; margin: 0 0 4px; color: var(--warn-dark, #a35b00); }
.ovbox__n { font-size: 12px; color: var(--t3); margin: 0 0 10px; line-height: 1.7; }
.ovrow { border-top: 1px solid var(--line); padding-top: 10px; margin-top: 10px; }
.ovrow:first-of-type { border-top: 0; padding-top: 0; margin-top: 0; }
.ovrow__t { font-size: 12px; font-weight: 500; margin-bottom: 6px; }
.ovrow .field { display: inline-block; width: 48%; margin-right: 2%; vertical-align: top; }
.actionbar__note { font-size: 12px; color: var(--t3); }

/* 登录页：一句话说明系统管什么 + 身份下拉的列名（黑盒审查 P1-01/02） */
.gate__intro { font-size: 12px; color: var(--t3); line-height: 1.9; margin: 10px 0 0; }
.field__cols { display: block; font-size: 11px; color: var(--t4); margin-bottom: 4px; }

/* 上游带下来的事实：摆出来但不给改、不给删（Ken 2026-08-28「只读+留痕」） */
.ftable__note { font-size: 11px; color: var(--t4); margin: 0 0 6px; line-height: 1.7; }
.ftable__ro { display: inline-block; font-size: 12px; color: var(--t2); padding: 4px 2px; }
.ftable__rolock { font-size: 11px; color: var(--t4); }

/* 只读表单：控件真的锁死（新人审查 P1-06——原来页面写着「只能看」，输入框照样能打字）。
   视觉上要一眼看出「这是记录，不是待填」，但仍然可以选中复制。 */
.sform--ro input,
.sform--ro textarea,
.sform--ro select {
  background: var(--bg-sunken, #f6f6f4);
  color: var(--ink-2, #4a4a46);
  border-style: dashed;
  cursor: default;
}
.sform--ro input:focus,
.sform--ro textarea:focus { outline: none; box-shadow: none; }
.sform--ro .field__label::after { content: "（只读）"; color: var(--ink-3, #8a8a84); font-weight: normal; }

/* ── 人员与权限（管理员唯一的活）───────────────────────────────── */
.ptable { width: 100%; border-collapse: collapse; font-size: 13px; }
.ptable th {
  text-align: left; font-size: 11.5px; font-weight: 600; color: var(--t4);
  padding: 6px 8px; border-bottom: 1px solid var(--line);
}
.ptable td { padding: 6px 8px; border-bottom: 1px solid var(--line); vertical-align: middle; }
.ptable .pin { width: 100%; padding: 5px 8px; font-size: 13px; }
/* 停用的人整行压淡——他还在名单里（历史要查得到），但不再是活人 */
.ptr.is-off td { opacity: .5; }
.ptr.is-off .pcode em { font-style: normal; }
.pcode { white-space: nowrap; color: var(--t3); font-size: 12px; }
.pact { white-space: nowrap; text-align: right; }
.pact .btn { margin-right: 6px; }
.pnew {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 10px; margin-bottom: 10px;
}
.puser { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; color: var(--t2); }
/* 新建/重发之后那一把初始码——只显示这一次，要够显眼让人抄走 */
.pissued {
  margin: 10px 0; padding: 10px 12px; border-radius: var(--r-sm);
  background: #fff7ed; border: 1px solid #fdba74; font-size: 12.5px; line-height: 1.9;
}
.pissued code {
  font-size: 14px; font-weight: 700; background: #fff; padding: 1px 7px;
  border-radius: var(--r-xs); border: 1px solid #fdba74;
}
.pissued em { color: var(--t3); font-style: normal; font-size: 11.5px; }

/* 「按角色速查」——流程说明页上按角色列一遍：负责哪几段、能做什么、做不了什么。
   Ken 2026-08-29 定的：这份速查手册里有一份，系统里也放一份。 */
.grole { padding: 10px 0; border-top: 1px solid var(--line); }
.grole:first-of-type { border-top: 0; }
.grole__n { display: block; margin-bottom: 4px; }
