/* ===========================================================================
 * prodflow · topic.css —— 布局与组件（结构层）
 * 铁律：本文件只引用 tokens.css 的 CSS 变量，不出现任何写死的色值/字号/圆角。
 *       Designer 的 design-tokens.json 到位后只需替换 tokens.css，本文件不改。
 * =========================================================================== */

body { font-family: var(--font); font-size: var(--fs-md); line-height: var(--lh); }
/* overflow-x 必须用 clip 不能用 hidden：hidden 会让 overflow-y 计算为 auto，
   使 .h5-app 成为 sticky 的滚动容器，而它自身不滚动 → 全站 .sticky-foot 失效。
   clip 同样裁掉横向溢出，但不创建滚动容器，sticky 仍相对视口生效。 */
.h5-app { max-width: var(--canvas-w); background: var(--bg); overflow-x: clip; }

/* ---------- 屏幕外壳 ---------- */
.screen { display: flex; flex-direction: column; min-height: 100vh; }
.scroll { flex: 1; padding-bottom: calc(var(--tabbar-h) + var(--sp-6)); }
.scroll.no-tab { padding-bottom: var(--sp-6); }
.pad { padding: var(--sp-4); }
.pad-x { padding-left: var(--sp-4); padding-right: var(--sp-4); }

/* ---------- 顶栏 ---------- */
.appbar {
  position: sticky; top: 0; z-index: 20; display: flex; align-items: center; gap: var(--sp-2);
  height: var(--appbar-h); padding: 0 var(--sp-3);
  background: var(--surface); border-bottom: 1px solid var(--border);
}
.ab-title { flex: 1; min-width: 0; font-size: inherit; font-weight: inherit; }
.ab-title b { display: block; font-size: var(--fs-lg); font-weight: var(--fw-bold); line-height: var(--lh-tight); }
.ab-title em { display: block; font-style: normal; font-size: var(--fs-xs); color: var(--muted); }
.ab-brand { display: inline-flex; color: var(--brand); }
.ab-right { display: flex; align-items: center; gap: var(--sp-1); }
.ab-btn {
  display: inline-flex; align-items: center; gap: var(--sp-1); border: 1px solid transparent;
  background: none; color: var(--fg-2); padding: var(--sp-1) var(--sp-2);
  border-radius: var(--radius-pill); cursor: pointer; font-size: var(--fs-xs);
}
.ab-btn:active { background: var(--surface-2); }
.ab-role { border-color: var(--border); }

/* ---------- 底部导航 ---------- */
.tabbar {
  position: fixed; bottom: 0; left: 50%; transform: translateX(-50%);
  width: 100%; max-width: var(--canvas-w); height: var(--tabbar-h); z-index: 20;
  display: grid; grid-template-columns: repeat(5, 1fr);
  background: var(--surface); border-top: 1px solid var(--border);
  padding-bottom: env(safe-area-inset-bottom);
}
.tab {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  color: var(--faint); font-size: var(--fs-xs);
}
.tab.on { color: var(--brand); font-weight: var(--fw-bold); }

/* ---------- 卡片与区块 ---------- */
.card {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow); padding: var(--sp-4); margin-bottom: var(--sp-3);
}
.card.tight { padding: var(--sp-3); }
.card.flat { box-shadow: none; }
.sec { margin: var(--sp-5) 0 var(--sp-2); display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-2); }
.sec h2 { font-size: var(--fs-sm); font-weight: var(--fw-bold); color: var(--muted); letter-spacing: .06em; }
.sec a, .sec button { font-size: var(--fs-xs); color: var(--brand); background: none; border: 0; cursor: pointer; }
.muted { color: var(--muted); }
.faint { color: var(--faint); font-size: var(--fs-xs); }
.row { display: flex; align-items: center; gap: var(--sp-2); }
.row.top { align-items: flex-start; }
.between { justify-content: space-between; }
.wrap { flex-wrap: wrap; }
.grow { flex: 1; min-width: 0; }
.ellip { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.stack > * + * { margin-top: var(--sp-2); }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-2); }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-2); }
hr.sep { border: 0; border-top: 1px solid var(--border); margin: var(--sp-3) 0; }

/* ---------- 状态标签（色值全部走 --st-* 插槽） ---------- */
.st {
  display: inline-flex; align-items: center; gap: 3px; font-size: var(--fs-xs);
  font-weight: var(--fw-bold); padding: 2px var(--sp-2); border-radius: var(--radius-pill);
  border: 1px solid currentColor; white-space: nowrap;
}
.st::before { content: ''; width: 5px; height: 5px; border-radius: 50%; background: currentColor; }
.st-draft { color: var(--st-draft); }
.st-analyzing { color: var(--st-analyzing); }
.st-reviewing { color: var(--st-reviewing); }
.st-confirmed { color: var(--st-confirmed); }
.st-building { color: var(--st-building); }
.st-accepting { color: var(--st-accepting); }
.st-done { color: var(--st-done); }
.st-rejected { color: var(--st-rejected); }
.st-cancelled { color: var(--st-cancelled); }
.st-stale { color: var(--st-stale); text-decoration: line-through; }

/* ---------- 优先级 ---------- */
.pri {
  display: inline-block; font-size: var(--fs-xs); font-weight: var(--fw-bold);
  padding: 1px var(--sp-2); border-radius: var(--radius-sm);
  background: var(--surface-2); color: var(--fg-2);
}
.pri-P0 { background: var(--brand); color: var(--on-brand); }

/* ---------- 影响等级（冲击波） ---------- */
.impact {
  display: inline-block; font-size: var(--fs-xs); font-weight: var(--fw-bold);
  padding: 1px var(--sp-2); border-radius: var(--radius-sm); border: 1px solid currentColor;
}
.impact-must { color: var(--impact-must); }
.impact-eval { color: var(--impact-eval); }
.impact-manual { color: var(--impact-manual); }

/* ---------- AI 可感知性 ---------- */
.ai-tag {
  display: inline-flex; align-items: center; gap: 3px; font-size: var(--fs-xs);
  padding: 1px var(--sp-2); border-radius: var(--radius-sm);
  background: var(--ai-tint); color: var(--fg-2); border: 1px dashed var(--ai-line);
}
.ai-block { background: var(--ai-tint); border: 1px dashed var(--ai-line); border-radius: var(--radius); padding: var(--sp-3); }
.ai-block .faint { color: var(--text-2); }
.watermark { position: relative; overflow: hidden; }
.watermark::after {
  content: attr(data-watermark); position: absolute; right: -18px; top: 10px;
  transform: rotate(28deg); font-size: var(--fs-2xl); font-weight: var(--fw-bold);
  color: var(--ai-watermark); pointer-events: none; letter-spacing: .1em;
}
.conf { display: inline-flex; align-items: center; gap: 4px; font-size: var(--fs-xs); color: var(--muted); }
.conf-bar { display: inline-block; width: 34px; height: 4px; border-radius: 2px; background: var(--surface-3); overflow: hidden; }
.conf-bar i { display: block; height: 100%; background: currentColor; }
.conf-hi { color: var(--success); }
.conf-mid { color: var(--warn); }
.conf-lo { color: var(--danger); }
.conf-human { color: var(--fg-2); }

/* ---------- 分步进度 ---------- */
.steps { list-style: none; margin: var(--sp-2) 0; }
.step { display: flex; gap: var(--sp-2); padding: var(--sp-2) 0; align-items: flex-start; color: var(--muted); }
.step b { display: block; font-size: var(--fs-md); font-weight: var(--fw-med); color: var(--fg-2); }
.step em { display: block; font-style: normal; font-size: var(--fs-xs); }
.step-done { color: var(--success); }
.step-done b { color: var(--fg); }
.step-active { color: var(--brand); }
.step-active b { color: var(--fg); font-weight: var(--fw-bold); }
.step-failed { color: var(--danger); }
.step-todo { color: var(--faint); }

/* ---------- 列表项 ---------- */
.item {
  display: block; background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: var(--sp-3); margin-bottom: var(--sp-2);
}
.item-title { font-weight: var(--fw-med); font-size: var(--fs-md); line-height: var(--lh-tight); }
.item-meta { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: var(--sp-2); font-size: var(--fs-xs); color: var(--muted); }
.item .code { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--muted); }

/* ---------- 筛选条 ---------- */
.chips { display: flex; gap: var(--sp-2); overflow-x: auto; padding: var(--sp-2) var(--sp-4); scrollbar-width: none; }
.chips::-webkit-scrollbar { display: none; }
.chip {
  flex: 0 0 auto; font-size: var(--fs-sm); padding: var(--sp-1) var(--sp-3);
  border: 1px solid var(--border); border-radius: var(--radius-pill);
  background: var(--surface); color: var(--fg-2); cursor: pointer; white-space: nowrap;
}
.chip.on { background: var(--brand); color: var(--on-brand); border-color: var(--brand); font-weight: var(--fw-bold); }

/* ---------- 按钮补充 ---------- */
.btn { border-radius: var(--radius-sm); font-size: var(--fs-md); }
.btn-sm { padding: var(--sp-1) var(--sp-3); font-size: var(--fs-sm); }
.btn-primary { background: var(--brand); color: var(--on-brand); border-color: transparent; box-shadow: none; }
.btn-danger { background: var(--surface); color: var(--danger); border-color: var(--danger); }
.btn-row { display: flex; gap: var(--sp-2); }
.btn-row .btn { flex: 1; }
/* 粘底操作条：必须让开固定底部页签（tabbar 是 fixed/bottom:0/z-index:20），
   否则主 CTA 被完全盖住——点击会打到 tabbar 触发跳路由。
   带页签的屏抬高一个页签高度；hideTab 的屏贴底。桌面端页签变左侧栏，恢复贴底。 */
.sticky-foot {
  position: sticky; bottom: var(--tabbar-h); display: flex; gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4);
  background: var(--surface); border-top: 1px solid var(--border); z-index: 10;
}
.scroll.no-tab .sticky-foot { bottom: 0; }
.sticky-foot .btn { flex: 1; }

/* ---------- KPI ---------- */
.kpi { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: var(--sp-3); }
.kpi-l { font-size: var(--fs-xs); color: var(--muted); }
.kpi-v { font-size: var(--fs-xl); font-weight: var(--fw-bold); line-height: 1.2; margin-top: 2px; }
.kpi-d { font-size: var(--fs-xs); color: var(--muted); margin-top: 2px; }
.kpi-d.up { color: var(--success); }
.kpi-d.down { color: var(--danger); }
.trend { width: 100%; height: 56px; color: var(--brand); }

/* ---------- 状态机进度条 ---------- */
.fsm { display: flex; gap: 2px; margin: var(--sp-3) 0; }
.fsm-node { flex: 1; text-align: center; font-size: 10px; color: var(--faint); }
.fsm-node i { display: block; height: 3px; border-radius: 2px; background: var(--surface-3); margin-bottom: 4px; }
.fsm-node.done i { background: var(--st-done); }
.fsm-node.done { color: var(--muted); }
.fsm-node.now i { background: var(--brand); }
.fsm-node.now { color: var(--brand); font-weight: var(--fw-bold); }

/* ---------- 血缘图谱 ---------- */
.graph { position: relative; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: var(--sp-3); overflow: hidden; }
.canvas-lineage { min-width: 0; }
.graph svg { display: block; width: 100%; height: auto; }
.g-edge { stroke: var(--border-strong); stroke-width: 1.4; fill: none; }
.g-edge.hot { stroke: var(--impact-must); stroke-width: 2.2; stroke-dasharray: 7 5; animation: pf-signal var(--dur-inkwave) linear infinite; }
.g-edge.warm { stroke: var(--impact-eval); stroke-width: 1.8; stroke-dasharray: 5 5; animation: pf-signal var(--dur-inkwave) linear infinite; }
.g-node rect, .g-node circle { fill: var(--surface-2); stroke: var(--border-strong); stroke-width: 1.2; }
.g-node text { fill: var(--fg); font-size: 9px; font-family: var(--font); }
.g-node .g-sub { fill: var(--muted); font-size: 7.5px; }
.g-node.root rect { fill: var(--surface-3); stroke: var(--brand); stroke-width: 2; }
.g-node.must rect { stroke: var(--impact-must); stroke-width: 2.4; }
.g-node.eval rect { stroke: var(--impact-eval); stroke-width: 2; stroke-dasharray: 4 2; }
.g-node.manual rect { stroke: var(--impact-manual); stroke-width: 1.6; stroke-dasharray: 2 2; }
.g-node.out rect { opacity: .38; }
.g-legend { display: flex; flex-wrap: wrap; gap: var(--sp-3); font-size: var(--fs-xs); color: var(--muted); margin-top: var(--sp-2); }
.g-legend span { display: inline-flex; align-items: center; gap: 4px; }
.g-legend i { width: 10px; height: 10px; border-radius: 2px; border: 2px solid currentColor; }
.pulse { animation: pf-pulse 1.6s ease-in-out infinite; transform-origin: center; }
@keyframes pf-pulse { 0%,100% { opacity: 1 } 50% { opacity: .45 } }
@keyframes pf-signal { to { stroke-dashoffset: -24; } }

/* ---------- 影响清单 ---------- */
.impact-row {
  display: flex; gap: var(--sp-2); padding: var(--sp-3);
  margin-bottom: var(--sp-2); background: var(--surface-2);
  border: 1px solid var(--border-strong); border-left: 2px solid var(--border-strong);
  border-radius: var(--radius-sm); box-shadow: var(--shadow-lg);
  transition: opacity var(--dur-lift) ease-out, background var(--dur-lift) ease-out;
}
.impact-row:has(.impact-must) { border-left-color: var(--impact-must); }
.impact-row:has(.impact-eval) { border-left-color: var(--impact-eval); }
.impact-row:has(.impact-manual) { border-left-color: var(--impact-manual); }
.impact-row:last-child { border-bottom: 0; }
.impact-row.off { opacity: 1; background: var(--surface-2); box-shadow: none; text-decoration: line-through; }
.chk {
  flex: 0 0 auto; width: 22px; height: 22px; border-radius: var(--radius-sm);
  border: 1px solid var(--border-strong); background: var(--surface);
  display: inline-flex; align-items: center; justify-content: center; cursor: pointer; color: transparent;
}
.chk.on { background: var(--brand); border-color: var(--brand); color: var(--on-brand); }

/* ---------- 时间线 ---------- */
.tl { list-style: none; position: relative; padding-left: var(--sp-5); }
.tl::before { content: ''; position: absolute; left: 6px; top: 4px; bottom: 4px; width: 1px; background: var(--border); }
.tl li { position: relative; padding: 0 0 var(--sp-4) 0; }
.tl li::before {
  content: ''; position: absolute; left: calc(-1 * var(--sp-5) + 2px); top: 5px;
  width: 9px; height: 9px; border-radius: 50%; background: var(--surface); border: 2px solid var(--border-strong);
}
.tl li.on::before { border-color: var(--brand); background: var(--brand); }
.tl b { font-size: var(--fs-md); font-weight: var(--fw-med); }
.tl em { font-style: normal; display: block; font-size: var(--fs-xs); color: var(--muted); }
.tl p { font-size: var(--fs-sm); color: var(--fg-2); margin-top: 2px; }

/* ---------- diff 视图 ---------- */
.diff { border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; font-family: var(--font-mono); font-size: var(--fs-sm); }
.diff-head { display: grid; grid-template-columns: 1fr 1fr; background: var(--surface-2); font-family: var(--font); }
.diff-head div { padding: var(--sp-2) var(--sp-3); font-size: var(--fs-xs); color: var(--muted); font-weight: var(--fw-bold); }
.diff-head div + div { border-left: 1px solid var(--border); }
.diff-line { display: flex; gap: var(--sp-2); padding: var(--sp-2) var(--sp-3); border-top: 1px solid var(--border); background: var(--surface); }
.diff-line .sign { flex: 0 0 14px; color: var(--muted); }
.diff-add { background: var(--ai-tint); }
.diff-add .sign { color: var(--success); }
.diff-del .sign { color: var(--danger); }
.diff-del span { text-decoration: line-through; color: var(--muted); }
.diff-src { font-family: var(--font); font-size: var(--fs-xs); color: var(--muted); padding: var(--sp-1) var(--sp-3) var(--sp-2); }

/* ---------- 泳道（三条生产线） ---------- */
.lanes { display: flex; gap: var(--sp-2); overflow-x: auto; padding-bottom: var(--sp-2); scrollbar-width: none; }
.lanes::-webkit-scrollbar { display: none; }
.lane { flex: 0 0 82%; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: var(--sp-3); }
.lane.on { border-color: var(--brand); }
.lane-h { display: flex; align-items: center; gap: var(--sp-2); margin-bottom: var(--sp-2); }
.lane-h b { font-size: var(--fs-md); font-weight: var(--fw-bold); }
.struct { list-style: none; font-size: var(--fs-sm); color: var(--fg-2); }
.struct li { display: flex; gap: var(--sp-2); padding: 3px 0; }
.struct li::before { content: ''; flex: 0 0 4px; height: 4px; margin-top: 8px; border-radius: 50%; background: var(--border-strong); }

/* ---------- 角色选择 ---------- */

/* ---------- 表单 ---------- */
.field { margin-bottom: var(--sp-3); }
.field label { display: block; font-size: var(--fs-xs); color: var(--muted); margin-bottom: var(--sp-1); }
.field input, .field textarea, .field select {
  width: 100%; padding: var(--sp-2) var(--sp-3); background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--radius-sm); color: var(--fg);
}
.field textarea { min-height: 72px; resize: vertical; }

/* ---------- 提示条 ---------- */
.notice { display: flex; gap: var(--sp-2); padding: var(--sp-3); border-radius: var(--radius); background: var(--surface-2); border: 1px solid var(--border); font-size: var(--fs-sm); }
.notice.err { border-color: var(--danger); color: var(--danger); }
.notice.ok { border-color: var(--success); }
.notice b { display: block; margin-bottom: 2px; }
.notice p { color: var(--fg-2); }

/* ---------- 折叠 ---------- */
.fold { display: none; }
.fold.open { display: block; }

/* ---------- 可访问性 ---------- */
:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
@media (prefers-reduced-motion: reduce) { * { animation: none !important; transition: none !important; } }

/* ===========================================================================
 * 设计契约落地：无衬线标题 + 等宽证据编号
 * =========================================================================== */
.ab-title b, .sec h2, .item-title, .lane-h b, .kpi-v, .h5-modal__title, .tl b {
  font-family: var(--font-display); letter-spacing: var(--ls-h2);
}
.ab-title b { font-size: var(--fs-xl); letter-spacing: var(--ls-h1); }
.ab-title em { letter-spacing: var(--ls-h1sub); }
/* 全部 ID 编号走等宽（REQ/CR/PROTO/UI/CODE/TEST/ACC/TSK） */
.code, .id, .item .code { font-family: var(--font-num); letter-spacing: .04em; }
.kpi-v { font-size: var(--fs-2xl); }
.btn { font-family: var(--font-display); }

.h5-app::before { display: none; }
.screen { position: relative; z-index: 1; }

/* ===========================================================================
 * 响应式双形态：mobile 390 / tablet 768 / desktop 1280+
 * 导航模式随断点切换：底部页签 ↔ 左侧常驻导航
 * 断点值登记在 tokens.css 的 --bp-md / --bp-lg（媒体查询内必须写字面量）
 * =========================================================================== */

/* ---- 平板过渡 768–1279（breakpoints.forms.tablet, priority:low）----
   契约：沿用移动单列，页边距升至 24（tokens 已覆写 --page-pad-x），
   卡片最大宽 640 居中；不单独设计、不提前分栏。 */
@media (min-width: 768px) {
  .h5-app { max-width: var(--canvas-w-md); }
  .tabbar { max-width: var(--canvas-w-md); }
  .pad { padding-left: var(--page-pad-x); padding-right: var(--page-pad-x); }
}

/* ---- 桌面 ≥1280：左侧常驻导航 + 内容多栏 ---- */
@media (min-width: 1280px) {
  body { background: var(--stage); }
  .h5-app { max-width: none; width: 100%; background: var(--bg); }

  /* DOM 顺序仍是 appbar → main → tabbar；用 grid-area 重排，无需改结构 */
  .screen {
    display: grid;
    grid-template-columns: var(--sidebar-w) minmax(0, 1fr);
    grid-template-rows: var(--appbar-h) minmax(0, 1fr);
    grid-template-areas: "bar bar" "nav main";
    min-height: 100vh;
  }
  .appbar { grid-area: bar; padding: 0 var(--sp-6); }
  .appbar .ab-title b { font-size: var(--fs-xl); }
  .scroll { grid-area: main; padding-bottom: var(--sp-8); overflow: visible; }

  /* 底部页签 → 左侧常驻导航（同一 DOM，换布局模式） */
  .tabbar {
    grid-area: nav; position: sticky; top: var(--appbar-h);
    transform: none; left: auto; bottom: auto;
    width: var(--sidebar-w); max-width: none;
    height: calc(100vh - var(--appbar-h));
    display: flex; flex-direction: column; align-items: stretch; gap: var(--sp-1);
    padding: var(--sp-4) var(--sp-2); border-top: 0; border-right: 1px solid var(--border);
  }
  .tab {
    flex-direction: row; justify-content: flex-start; gap: var(--sp-3);
    min-height: var(--nav-item-h); padding: 0 var(--sp-3);
    font-size: var(--fs-md); border-radius: var(--radius);
  }
  .tab.on { background: var(--surface-2); }

  /* 内容容器：居中定宽（designWidth 1440），卡片双列流 */
  .scroll > .pad, .scroll > .pad-x, .scroll > .sheet {
    max-width: var(--shell-w); margin: 0 auto;
    padding: var(--sp-6) var(--page-pad-x);
    column-count: 2; column-gap: var(--col-gap);
  }
  .scroll > .pad > *, .scroll > .pad-x > *, .scroll > .sheet > * { break-inside: avoid; }
  .sec, .sticky-foot { column-span: all; }
  /* 结算条横跨视口底部（breakpoints.forms.desktop.lineage） */
  .sticky-foot { bottom: 0; padding-left: var(--page-pad-x); padding-right: var(--page-pad-x); }
  .chips { max-width: var(--shell-w); margin: 0 auto; padding-left: var(--page-pad-x); padding-right: var(--page-pad-x); }

  /* 工作台：gridTemplates.workbench-desktop —— 内容区再分 1fr / 400px 两栏 */
  [data-screen="workbench"] .scroll > .pad,
  [data-screen="workbench"] .scroll > .pad-x,
  [data-screen="workbench"] .scroll > .sheet {
    column-count: initial;
    display: grid; grid-template-columns: minmax(0, 1fr) 400px;
    gap: var(--col-gap); align-items: start;
  }
  [data-screen="workbench"] .sec { grid-column: 1 / -1; }

  /* 血缘图谱 hero：主舞台 + 右侧常驻影响清单 + 全宽后续证据 */
  [data-screen="lineage"] .scroll > .pad,
  [data-screen="lineage"] .scroll > .sheet {
    column-count: initial;
    display: grid; grid-template-columns: minmax(0, 1fr) var(--list-panel-w);
    gap: var(--col-gap); align-items: start;
  }
  [data-screen="lineage"] .lineage-summary,
  [data-screen="lineage"] .lineage-alert,
  [data-screen="lineage"] .lineage-followup { grid-column: 1 / -1; }
  [data-screen="lineage"] .lineage-canvas { grid-column: 1; min-width: 0; position: sticky; top: calc(var(--appbar-h) + var(--sp-5)); }
  [data-screen="lineage"] .lineage-impact-panel { grid-column: 2; min-width: 0; }
  [data-screen="lineage"] .lineage-canvas .sec,
  [data-screen="lineage"] .lineage-impact-panel .sec,
  [data-screen="lineage"] .lineage-followup .sec { grid-column: auto; }
  [data-screen="lineage"] .graph svg { max-height: 66vh; }

  /* 三条生产线：桌面并排铺满，不再横向滑动 */
  [data-screen="ai-production"] .scroll > .pad,
  [data-screen="ai-production"] .scroll > .sheet { column-count: initial; }
  [data-screen="ai-production"] .lanes { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); overflow: visible; }
  [data-screen="ai-production"] .lane { flex: initial; }

  /* diff 评审：对比区加宽，评论与责任记录并列 */
  [data-screen="diff-review"] .diff-line { padding: var(--sp-2) var(--sp-4); }

  /* 变更中心：列表 + 时间线双栏 */
  [data-screen="change-center"] .scroll > .pad,
  [data-screen="change-center"] .scroll > .sheet { column-count: 2; }

  /* 桌面 hover 基线（仅真实指针设备） */
  @media (hover: hover) {
    .item:hover, .chip:hover { border-color: var(--border-strong); }
    .impact-row:hover { background: var(--surface-2); }
    .tab:hover { background: var(--surface-2); }
  }
}

/* ---- 超宽 ≥1680：只放宽内容容器，不再增栏 ---- */
@media (min-width: 1680px) {
  .scroll > .pad, .scroll > .sheet, .sticky-foot, .chips { max-width: 1440px; }
}

/* ===========================================================================
 * engine 运行时样式覆盖（components.js 把 <style id="h5-runtime"> 注入 head，
 * 位置在本文件 <link> 之后 → 同特异度下它会赢，故这里统一提高一级特异度）。
 * 目的：把引擎里写死的 toast / 遮罩色值收敛为令牌引用，
 *       换设计系统时只改 tokens.css，不改 engine（engine 复制不魔改）。
 * =========================================================================== */
body .h5-toast {
  background: var(--surface-3); color: var(--fg);
  border: 1px solid var(--border-strong); border-radius: var(--radius);
  box-shadow: none; font-size: var(--fs-md); font-family: var(--font);
}
body .h5-toast.ok { background: var(--success); color: var(--on-brand); border-color: transparent; }
body .h5-toast.err { background: var(--danger); color: var(--on-brand); border-color: transparent; }
body .h5-toast.warn { background: var(--warn); color: var(--on-brand); border-color: transparent; }
body .h5-mask { background: var(--overlay); }
body .h5-modal {
  background: var(--surface); color: var(--fg);
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  box-shadow: none;
}
body .h5-modal__title { font-family: var(--font-display); font-size: var(--fs-lg); color: var(--fg); }
body .h5-modal__body { color: var(--fg-2); font-size: var(--fs-md); }

/* ===========================================================================
 * Workflow Studio v3 · shared application shell
 * Four desktop zones: global rail / context library / task stage / inspector.
 * Mobile keeps the existing single-task flow and hides contextual side panels.
 * =========================================================================== */
.window-dots, .workspace-docs, .context-library, .workspace-inspector { display: none; }
.appbar { box-shadow: none; }
.appbar .ab-title b { font-weight: 650; }
.card, .item, .kpi, .lane, .graph, .notice { box-shadow: var(--shadow); }
.card, .item, .lane, .graph, .notice, .kpi { transition: border-color .16s ease, box-shadow .16s ease, transform .16s ease; }
.btn { min-height: 36px; padding: var(--sp-2) var(--sp-4); font-weight: 650; }
.btn-primary { box-shadow: 0 8px 20px color-mix(in srgb, var(--brand) 18%, transparent); }
.ai-tag { color: var(--brand); border-style: solid; border-color: color-mix(in srgb, var(--brand) 35%, var(--border)); background: var(--indigo-bg); }
.graph { background-color: var(--surface); background-image: radial-gradient(var(--border) 1px, transparent 1px); background-size: 18px 18px; }
.g-node rect, .g-node circle { filter: drop-shadow(0 7px 11px color-mix(in srgb, var(--fg) 8%, transparent)); }
.field input:focus, .field textarea:focus, .field select:focus { border-color: var(--brand); box-shadow: 0 0 0 3px var(--indigo-bg); outline: 0; }

@media (min-width: 1280px) {
  body { overflow: hidden; }
  .h5-app { height: 100vh; overflow: hidden; }
  .screen {
    height: 100vh; min-height: 0;
    grid-template-columns: var(--sidebar-w) var(--context-panel-w) minmax(0, 1fr) var(--side-panel-w);
    grid-template-rows: var(--appbar-h) minmax(0, 1fr);
    grid-template-areas: "bar bar bar bar" "nav context main inspect";
  }
  .appbar { grid-area: bar; padding: 0 var(--sp-3); gap: var(--sp-2); background: var(--surface); }
  .window-dots { display: inline-flex; gap: 5px; padding: 0 var(--sp-1); }
  .window-dots i { width: 8px; height: 8px; border-radius: 50%; background: var(--border-strong); }
  .ab-brand { width: 31px; height: 31px; display: grid; place-items: center; border-radius: 9px; color: var(--on-brand); background: var(--brand); }
  .ab-title { display: none; }
  .workspace-docs { display: flex; align-items: center; min-width: 0; gap: var(--sp-1); }
  .workspace-doc { height: 32px; min-width: 156px; max-width: 230px; padding: 0 var(--sp-3); display: flex; align-items: center; gap: var(--sp-2); border: 1px solid transparent; border-radius: var(--radius-sm); color: var(--muted); font-size: var(--fs-xs); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .workspace-doc i { width: 6px; height: 6px; flex: 0 0 6px; border-radius: 50%; background: var(--brand); }
  .workspace-doc.on { color: var(--fg); border-color: var(--border); background: var(--bg); }
  .ab-right { margin-left: auto; }
  .ab-btn { min-height: 32px; border-radius: var(--radius-sm); }

  .tabbar {
    grid-area: nav; position: relative; top: auto; width: var(--sidebar-w); height: 100%;
    padding: var(--sp-3) var(--sp-2); gap: var(--sp-2); background: var(--surface); border-right: 1px solid var(--border);
  }
  .tab { min-height: 36px; height: 36px; padding: 0; justify-content: center; border-radius: 9px; }
  .tab span { display: none; }
  .tab.on { color: var(--brand); background: var(--indigo-bg); }
  .tab:nth-child(5) { margin-top: auto; }

  .context-library { grid-area: context; display: block; min-width: 0; overflow: auto; background: var(--surface); border-right: 1px solid var(--border); }
  .context-head { height: 58px; padding: 0 var(--sp-4); display: flex; align-items: center; justify-content: space-between; border-bottom: 1px solid var(--border); }
  .context-head b { font-size: var(--fs-sm); }
  .context-search { width: calc(100% - var(--sp-3) * 2); height: 34px; margin: var(--sp-3); padding: 0 var(--sp-3); display: flex; align-items: center; gap: var(--sp-2); color: var(--muted); border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--bg); font-size: var(--fs-xs); text-align: left; cursor: pointer; }
  .context-search > span { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .context-search:hover { color: var(--fg); border-color: var(--border-strong); }
  .context-search:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; }
  .context-label { padding: var(--sp-3) var(--sp-4) var(--sp-2); display: flex; justify-content: space-between; color: var(--faint); font-size: var(--fs-2xs); letter-spacing: .08em; text-transform: uppercase; }
  .context-item { margin: 0 var(--sp-2) var(--sp-2); padding: 10px; display: grid; grid-template-columns: 32px minmax(0, 1fr) auto; gap: var(--sp-2); align-items: center; border: 1px solid var(--border); border-radius: 10px; background: var(--surface); }
  .context-item.on { border-color: color-mix(in srgb, var(--brand) 42%, var(--border)); background: color-mix(in srgb, var(--brand) 4%, var(--surface)); }
  .context-item.compact { border-color: transparent; background: transparent; }
  .context-icon { width: 32px; height: 32px; display: grid; place-items: center; border: 1px solid color-mix(in srgb, var(--brand) 18%, var(--border)); border-radius: 8px; color: var(--brand); background: var(--indigo-bg); font: 700 9px var(--font-num); }
  .context-item b, .context-item small { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .context-item b { font-size: var(--fs-xs); font-weight: 650; }
  .context-item small { margin-top: 2px; color: var(--faint); font-size: var(--fs-2xs); }
  .context-item em { color: var(--memo); font-style: normal; }

  .scroll { grid-area: main; height: 100%; min-width: 0; overflow-y: auto; overflow-x: clip; padding-bottom: var(--sp-8); background-color: var(--bg); background-image: radial-gradient(var(--border) .7px, transparent .7px); background-size: 18px 18px; }
  .scroll > .pad, .scroll > .pad-x, .scroll > .sheet { max-width: none; width: 100%; margin: 0; padding: 18px; column-count: initial; column-gap: initial; }
  .scroll > .pad > *, .scroll > .pad-x > *, .scroll > .sheet > * { break-inside: auto; }
  [data-screen="workbench"] .scroll > .pad, [data-screen="workbench"] .scroll > .pad-x, [data-screen="workbench"] .scroll > .sheet { grid-template-columns: minmax(0, 1fr) 320px; gap: var(--sp-4); }
  [data-screen="lineage"] .scroll > .pad, [data-screen="lineage"] .scroll > .sheet { display: block; }
  [data-screen="lineage"] .lineage-canvas { position: static; }
  [data-screen="lineage"] .graph svg { max-height: none; }
  [data-screen="change-center"] .scroll > .pad, [data-screen="change-center"] .scroll > .sheet { column-count: initial; }
  [data-screen="ai-production"] .lanes { gap: var(--sp-3); }
  [data-screen="ai-production"] .lane { min-width: 0; }
  .sticky-foot { bottom: 0; margin: 0 -18px -18px; padding: var(--sp-3) 18px; box-shadow: 0 -12px 30px color-mix(in srgb, var(--fg) 5%, transparent); }

  .workspace-inspector { grid-area: inspect; position: relative; display: flex; min-width: 0; flex-direction: column; overflow: auto; background: var(--surface); border-left: 1px solid var(--border); }
  .inspector-tabs { margin: var(--sp-3); padding: 3px; display: grid; grid-template-columns: repeat(3, 1fr); border: 1px solid var(--border); border-radius: 9px; background: var(--bg); }
  .inspector-tabs span { height: 28px; display: grid; place-items: center; border-radius: 7px; color: var(--muted); font-size: var(--fs-2xs); }
  .inspector-tabs .on { color: var(--on-brand); background: var(--brand); }
  .inspector-section { padding: 0 var(--sp-4) var(--sp-4); }
  .inspector-section h2 { margin: var(--sp-3) 0; font-size: var(--fs-xs); }
  .inspector-section p { margin-top: var(--sp-3); color: var(--muted); font-size: var(--fs-xs); line-height: 1.6; }
  .inspector-stat { display: grid; grid-template-columns: 1fr 1fr; border: 1px solid var(--border); border-radius: 10px; overflow: hidden; }
  .inspector-stat span { padding: var(--sp-3); }
  .inspector-stat span + span { border-left: 1px solid var(--border); }
  .inspector-stat b, .inspector-stat small { display: block; }
  .inspector-stat b { font-size: var(--fs-lg); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .inspector-stat small { color: var(--faint); font-size: var(--fs-2xs); }
  .inspector-progress { height: 6px; margin: var(--sp-3) 0; overflow: hidden; border-radius: var(--radius-pill); background: var(--indigo-bg); }
  .inspector-progress i { display: block; width: 68%; height: 100%; background: var(--brand); }
  .inspector-row { min-height: 34px; display: flex; align-items: center; justify-content: space-between; font-size: var(--fs-xs); }
  .ui-switch { width: 28px; height: 16px; padding: 2px; border-radius: var(--radius-pill); background: var(--border-strong); }
  .ui-switch::after { content: ''; display: block; width: 12px; height: 12px; border-radius: 50%; background: var(--surface); }
  .ui-switch.on { background: var(--brand); }
  .ui-switch.on::after { margin-left: 12px; }
  .inspector-select { min-height: 36px; padding: 0 var(--sp-3); display: flex; align-items: center; justify-content: space-between; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--bg); font-size: var(--fs-xs); }
  .inspector-action { position: sticky; bottom: 0; min-height: 40px; margin: auto var(--sp-3) var(--sp-3); display: flex; align-items: center; justify-content: center; border-radius: var(--radius-sm); color: var(--on-brand); background: var(--brand); font-size: var(--fs-xs); font-weight: 700; box-shadow: 0 10px 24px color-mix(in srgb, var(--brand) 20%, transparent); }
}

@media (min-width: 1280px) and (max-width: 1439px) {
  .screen { grid-template-columns: var(--sidebar-w) 220px minmax(0, 1fr) 280px; }
  [data-screen="workbench"] .scroll > .pad, [data-screen="workbench"] .scroll > .sheet { display: block; }
}

@media (hover: hover) {
  .context-item:hover, .card:hover, .item:hover, .lane:hover { border-color: color-mix(in srgb, var(--brand) 32%, var(--border)); }
  .context-item:hover { box-shadow: var(--shadow); }
}

/* ===========================================================================
 * Product architecture shell v4
 * Clear six-center IA, role-aware access, project context and delivery stages.
 * =========================================================================== */
.appbar-main { width: 100%; display: flex; align-items: center; gap: var(--sp-2); min-width: 0; }
.product-name, .project-switch, .global-search { display: none; }
.role-avatar { width: 28px; height: 28px; flex: 0 0 28px; display: grid; place-items: center; border-radius: 8px; color: var(--on-brand); background: var(--brand); font: 700 var(--fs-2xs) var(--font); }
.role-copy { display: none; text-align: left; min-width: 0; }
.role-copy small, .role-copy b { display: block; }
.role-copy small { color: var(--faint); font-size: var(--fs-2xs); font-weight: 500; }
.role-copy b { color: var(--fg); font-size: var(--fs-xs); white-space: nowrap; }
.tab { border: 0; background: transparent; font-family: var(--font); cursor: pointer; }

@media (max-width: 1279px) {
  /* Mock 环境层让开底部 tabbar（mock-dock.css 的唯一对外插槽） */
  .mockdock { --md-safe-bottom: calc(var(--tabbar-h) + 10px); }
  .appbar { padding: 0 var(--sp-3); }
  .ab-role { padding: 2px; border: 0; }
  .ab-role > svg { display: none; }
  .tabbar { grid-template-columns: repeat(6, 1fr); }
  .tab { min-width: 0; padding: 0 2px; }
  .tab-copy { min-width: 0; }
  .tab-copy b { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--fs-2xs); font-weight: 650; }
}

@media (max-width: 767px) {
  body .h5-modal { width: calc(100% - 24px); max-width: none; max-height: calc(100vh - 24px); padding: var(--sp-4); display: flex; flex-direction: column; border-radius: var(--radius-lg); }
  body .h5-modal__title { flex: 0 0 auto; }
  body .h5-modal__body { min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
  body .h5-modal__foot { flex: 0 0 auto; }
}

@media (min-width: 768px) {
  body .h5-modal { max-width: 720px; }
}

@media (min-width: 1280px) {
  .screen {
    grid-template-columns: var(--sidebar-w) var(--context-panel-w) minmax(0, 1fr);
    /* 定位器行按内容定高：接力轨 52px、项目分布 64px，写死 42px 会让第二行
     * 溢出顶栏压住侧栏与正文（--desktop-appbar-h 只作最小高度兜底）。 */
    grid-template-rows: auto minmax(0, 1fr);
    grid-template-areas: "bar bar bar" "nav context main";
  }
  [data-screen="ai-production"], [data-screen="diff-review"], [data-screen="lineage"] {
    grid-template-columns: var(--sidebar-w) var(--context-panel-w) minmax(0, 1fr) var(--side-panel-w);
    grid-template-areas: "bar bar bar bar" "nav context main inspect";
  }
  .appbar { height: auto; min-height: var(--desktop-appbar-h); padding: 0; display: grid; grid-template-rows: 62px auto; gap: 0; align-items: stretch; }
  .appbar-main { height: 62px; padding: 0 var(--sp-4); gap: var(--sp-3); border-bottom: 1px solid var(--border); }
  .window-dots { display: none; }
  .ab-brand { display: none; }
  .product-name { width: calc(var(--sidebar-w) - var(--sp-4)); flex: 0 0 calc(var(--sidebar-w) - var(--sp-4)); display: flex; align-items: baseline; gap: var(--sp-2); color: var(--fg); }
  .product-name b { font-size: var(--fs-lg); letter-spacing: -.03em; }
  .product-name small { color: var(--faint); font: 650 8px var(--font-num); letter-spacing: .16em; }
  .project-switch { width: calc(var(--context-panel-w) - var(--sp-3)); height: 42px; flex: 0 0 calc(var(--context-panel-w) - var(--sp-3)); padding: 0 var(--sp-2); display: grid; grid-template-columns: 30px minmax(0, 1fr) 14px; align-items: center; gap: var(--sp-2); border: 1px solid var(--border); border-radius: var(--radius-sm); color: var(--fg); background: var(--surface); text-align: left; cursor: pointer; }
  .project-mark { width: 30px; height: 30px; display: grid; place-items: center; border-radius: 7px; color: var(--brand); background: var(--indigo-bg); font: 700 9px var(--font-num); }
  .project-switch small, .project-switch b { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .project-switch small { color: var(--faint); font-size: 9px; }
  .project-switch b { font-size: var(--fs-xs); }
  .workspace-docs { flex: 0 1 auto; min-width: 120px; gap: var(--sp-2); color: var(--faint); font-size: var(--fs-xs); }
  .workspace-docs i { color: var(--border-strong); font-style: normal; }
  .workspace-docs b { overflow: hidden; color: var(--fg); text-overflow: ellipsis; white-space: nowrap; }
  .global-search { width: min(250px, 18vw); height: 34px; margin-left: auto; padding: 0 var(--sp-3); display: flex; align-items: center; gap: var(--sp-2); border: 1px solid var(--border); border-radius: var(--radius-sm); color: var(--muted); background: var(--bg); cursor: pointer; }
  .global-search span { flex: 1; overflow: hidden; text-align: left; text-overflow: ellipsis; white-space: nowrap; font-size: var(--fs-xs); }
  .global-search kbd { color: var(--faint); font: 600 9px var(--font-mono); }
  .ab-role { min-width: 178px; height: 42px; padding: 0 var(--sp-2); border-color: var(--border); border-radius: var(--radius-sm); background: var(--surface); }
  .role-copy { display: block; flex: 1; }

  .tabbar { top: auto; width: var(--sidebar-w); height: 100%; padding: var(--sp-3); gap: 3px; }
  .tab { width: 100%; height: 48px; min-height: 48px; padding: 0 var(--sp-3); display: flex; justify-content: flex-start; gap: var(--sp-3); border-radius: var(--radius-sm); color: var(--muted); text-align: left; }
  .tab-copy { flex: 1; min-width: 0; }
  .tab .tab-copy { display: block; }
  .tab-copy b { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .tab-copy b { color: inherit; font-size: var(--fs-xs); font-weight: 650; }
  .tab.on { color: var(--brand); background: var(--indigo-bg); }
  .tab:nth-child(5) { margin-top: 0; }

  .context-library { display: flex; flex-direction: column; }
  .context-head { height: 66px; padding: 0 var(--sp-4); }
  .context-head > span small, .context-head > span b { display: block; }
  .context-head small { color: var(--faint); font-size: 9px; }
  .context-head b { margin-top: 1px; font-size: var(--fs-sm); }
  .context-head button { width: 28px; height: 28px; display: grid; place-items: center; border: 0; border-radius: 7px; color: var(--muted); background: transparent; }
  .role-context { margin: var(--sp-3) var(--sp-3) 0; padding: var(--sp-3); display: flex; align-items: center; gap: var(--sp-2); border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--bg); }
  .role-context > span:last-child { min-width: 0; }
  .role-context small, .role-context b { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .role-context small { color: var(--brand); font-size: 9px; }
  .role-context b { margin-top: 2px; font-size: var(--fs-2xs); }
  .context-search { margin-top: var(--sp-2); }
  .context-search kbd { margin-left: auto; color: var(--faint); font: 600 8px var(--font-mono); }
  /* ≥1280 起侧栏资源库自带搜索框，appbar 的图标入口不再重复 */
  .ab-search { display: none; }
  .context-label { letter-spacing: .06em; text-transform: none; }
  .context-item { min-height: 50px; margin-bottom: 3px; border-color: transparent; border-radius: var(--radius-sm); }
  .context-item.on { border-color: transparent; background: var(--indigo-bg); }
  .context-icon { border: 0; background: var(--surface-2); }
  .context-item.on .context-icon { color: var(--on-brand); background: var(--brand); }
  .context-item em { padding: 2px 5px; border-radius: var(--radius-pill); color: var(--brand); background: var(--surface); font-size: 8px; }
  .context-spacer { flex: 1; min-height: var(--sp-4); }
  .context-role-scope { margin: var(--sp-3); padding: var(--sp-3); border-top: 1px solid var(--border); }
  .context-role-scope small, .context-role-scope b { display: block; }
  .context-role-scope small { color: var(--faint); font-size: 9px; }
  .context-role-scope b { margin-top: 2px; font-size: var(--fs-xs); }
  .context-role-scope p { margin: var(--sp-2) 0; color: var(--muted); font-size: var(--fs-2xs); line-height: 1.55; }
  .context-role-scope button { padding: 0; border: 0; color: var(--brand); background: transparent; font: 650 var(--fs-2xs) var(--font); cursor: pointer; }

  .workspace-inspector { display: none; }
  [data-screen="ai-production"] .workspace-inspector,
  [data-screen="diff-review"] .workspace-inspector,
  [data-screen="lineage"] .workspace-inspector { display: flex; }
}

@media (min-width: 1280px) and (max-width: 1439px) {
  .screen { grid-template-columns: 184px 220px minmax(0, 1fr); }
  [data-screen="ai-production"], [data-screen="diff-review"], [data-screen="lineage"] { grid-template-columns: 184px 220px minmax(0, 1fr) 260px; }
  .tabbar { width: 184px; }
  .product-name { width: 168px; flex-basis: 168px; }
  .project-switch { width: 208px; flex-basis: 208px; }
  .global-search { display: none; }
}

/* ≥1440 appbar 有完整搜索条，侧栏那个就是重复入口 */
@media (min-width: 1440px) {
  .context-search { display: none; }
}

/* Mature interaction layer: Tabler overlays + Chart.js / Sortable enhancements. */
:root {
  --tblr-body-bg: var(--bg);
  --tblr-body-color: var(--fg);
  --tblr-border-color: var(--border);
  --tblr-primary: var(--brand);
  --tblr-primary-rgb: 91, 80, 230;
  --tblr-secondary-color: var(--muted);
  --tblr-card-bg: var(--surface);
}
/* Tabler 的 Bootstrap 栅格也使用 .row；产研通原有 .row 是轻量 flex 原语，需明确隔离。 */
body .row { --tblr-gutter-x: 0; margin-right: 0; margin-left: 0; flex-wrap: nowrap; }
body .row.wrap { flex-wrap: wrap; }
body .row > * { width: auto; max-width: 100%; padding-right: 0; padding-left: 0; }
body .row > .grow { flex: 1 1 0; min-width: 0; }
.project-menu { min-width: 0; }
.project-dropdown { width: 290px; padding: var(--sp-2); border-color: var(--border); border-radius: var(--radius); background: var(--surface); box-shadow: var(--shadow-lg); }
.project-dropdown .dropdown-item { min-height: 52px; padding: var(--sp-2); display: grid; grid-template-columns: 32px minmax(0, 1fr) 16px; align-items: center; gap: var(--sp-2); border-radius: var(--radius-sm); color: var(--fg); }
.project-dropdown .dropdown-item.active { color: var(--brand); background: var(--indigo-bg); }
.project-dropdown .dropdown-item span:nth-child(2) { min-width: 0; }
.project-dropdown .dropdown-item b, .project-dropdown .dropdown-item small { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.project-dropdown .dropdown-item b { font-size: var(--fs-xs); }
.project-dropdown .dropdown-item small { color: var(--muted); font-size: var(--fs-2xs); }

body .modal-content, body .offcanvas { color: var(--fg); border-color: var(--border); background: var(--surface); }
body .modal-header, body .offcanvas-header { border-color: var(--border); }
body .modal-title, body .offcanvas-title { color: var(--fg); font: 700 var(--fs-lg) var(--font-display); }
body .text-secondary { color: var(--muted) !important; }
body .form-control, body .form-select { color: var(--fg); border-color: var(--border); background: var(--bg); }
body .form-control:focus, body .form-select:focus { border-color: var(--brand); box-shadow: 0 0 0 3px var(--indigo-bg); }
body .btn.active { color: var(--on-brand); border-color: var(--brand); background: var(--brand); }
body .alert-info { color: var(--fg-2); border-color: color-mix(in srgb, var(--brand) 28%, var(--border)); background: var(--indigo-bg); }
.pf-command-hint { padding: var(--sp-2) 0; display: flex; justify-content: space-between; color: var(--faint); font-size: var(--fs-2xs); }
.pf-command-results { max-height: min(52vh, 460px); overflow-y: auto; border: 1px solid var(--border); border-radius: var(--radius-sm); }
.pf-search-result { min-height: 58px; padding: var(--sp-3); display: flex; align-items: center; gap: var(--sp-3); color: var(--fg); background: var(--surface); }
.pf-search-result .grow { min-width: 0; text-align: left; }
.pf-search-result b, .pf-search-result small { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pf-search-result b { font-size: var(--fs-sm); }
.pf-search-result small { margin-top: 2px; color: var(--muted); font-size: var(--fs-xs); }
.pf-settings { width: min(420px, 94vw) !important; }

/* ---- 提醒面板：铃铛拉起的「别人推给你的事」 ----
 * 行语法沿用工单卡（左侧色轨 + 三行信息 + 右侧动作），与工作台同源；
 * 未读只用一个左侧实心轨与加粗标题表示，不再叠加第二种未读语言。 */
.pf-inbox { width: min(460px, 96vw) !important; }
.pf-inbox .offcanvas-body { padding-top: var(--sp-3); }
.pf-inbox-top { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); padding-bottom: var(--sp-2); color: var(--muted); font-size: var(--fs-xs); }
.pf-inbox-top b { color: var(--brand); font-family: var(--font-num); font-size: var(--fs-md); }
.pf-inbox-readall { padding: 0; border: 0; color: var(--brand); background: transparent; font: 650 var(--fs-xs) var(--font); cursor: pointer; }
.pf-inbox-readall:disabled { color: var(--faint); cursor: default; }
.pf-inbox .pf-seclabel { margin-top: var(--sp-4); }
.pf-notif {
  position: relative; display: flex; align-items: stretch; gap: var(--sp-3);
  margin-bottom: var(--sp-2); padding: var(--sp-3) var(--sp-3) var(--sp-3) 0;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  color: var(--fg); background: var(--surface); text-decoration: none;
}
.pf-notif:hover { border-color: var(--border-strong); }
.pf-notif-rail { flex: 0 0 3px; border-radius: var(--radius-sm) 0 0 var(--radius-sm); background: var(--border-strong); }
.pf-notif-memo { background: var(--memo); }
.pf-notif-seal { background: var(--danger); }
.pf-notif-ink { background: var(--brand); }
.pf-notif.unread { border-color: color-mix(in srgb, var(--brand) 26%, var(--border)); }
.pf-notif:not(.unread) { opacity: .74; }
.pf-notif:not(.unread) .pf-notif-rail { background: var(--border-strong); }
.pf-notif-body { min-width: 0; flex: 1; }
.pf-notif-top { display: flex; align-items: center; gap: var(--sp-2); font-size: var(--fs-2xs); }
.pf-notif-top em { font-style: normal; font-weight: 700; color: var(--muted); letter-spacing: .04em; }
.pf-notif-top time { margin-left: auto; color: var(--faint); font-family: var(--font-mono); }
.pf-notif-due { color: var(--warn); font-family: var(--font-mono); }
.pf-notif-body b { display: block; margin: 3px 0 2px; font-size: var(--fs-sm); font-weight: 600; line-height: 1.45; }
.pf-notif.unread .pf-notif-body b { font-weight: 700; }
.pf-notif-body small { display: block; overflow: hidden; color: var(--muted); font-size: var(--fs-2xs); text-overflow: ellipsis; white-space: nowrap; }
.pf-notif-go { flex: 0 0 auto; align-self: center; color: var(--brand); font-size: var(--fs-xs); font-weight: 650; white-space: nowrap; }
.pf-inbox-empty { padding-top: var(--sp-6); }
.inspector-tabs button { height: 28px; display: grid; place-items: center; border: 0; border-radius: 7px; color: var(--muted); background: transparent; font: 500 var(--fs-2xs) var(--font); cursor: pointer; }
.inspector-tabs button.on { color: var(--on-brand); background: var(--brand); }
.inspector-panel[hidden] { display: none !important; }
.inspector-select { width: 100%; cursor: pointer; }
.ui-switch { display: block; padding: 2px; border: 0; cursor: pointer; }
.inspector-log { margin: 0; padding: 0; list-style: none; }
.inspector-log li { padding: var(--sp-2) 0; border-bottom: 1px solid var(--border); }
.inspector-log b, .inspector-log small { display: block; }
.inspector-log b { font-size: var(--fs-xs); }
.inspector-log small { margin-top: 2px; color: var(--faint); font-size: var(--fs-2xs); }
.trend-chart { width: 100% !important; height: 120px !important; margin-top: var(--sp-2); }
.sortable-ghost { opacity: .48; border: 1px dashed var(--brand) !important; background: var(--indigo-bg) !important; }
[data-screen="ai-production"] .lane-h { cursor: grab; }
[data-screen="ai-production"] .lane-h:active { cursor: grabbing; }
.section-focus { animation: sectionFocus .9s ease; }
@keyframes sectionFocus { 0%, 100% { color: inherit; } 35% { color: var(--brand); } }
[data-density="compact"] .card, [data-density="compact"] .item, [data-density="compact"] .lane { padding-top: var(--sp-2); padding-bottom: var(--sp-2); }
[data-density="compact"] .context-item { min-height: 42px; }
[data-density="compact"] .scroll > .pad, [data-density="compact"] .scroll > .sheet { padding-top: var(--sp-3); }
@media (min-width: 1280px) {
  .project-menu { width: calc(var(--context-panel-w) - var(--sp-3)); flex: 0 0 calc(var(--context-panel-w) - var(--sp-3)); }
  .project-menu .project-switch { width: 100%; }
  [data-show-journey="false"] .appbar { height: 62px; min-height: 0; grid-template-rows: 62px; }
  [data-show-journey="false"] .screen { grid-template-rows: 62px minmax(0, 1fr); }
}
@media (max-width: 767px) {
  .pf-command .modal-dialog { margin: var(--sp-3); }
  .pf-command .modal-content { max-height: calc(100vh - 24px); }
}

/* ===========================================================================
 * 流水线形式语言 · approved v2
 * ---------------------------------------------------------------------------
 * 题面明写的六环节即产品骨架。流水线条从「工作台的一个组件」升格为全局定位器：
 * 每屏常驻、移动端同样可见，回答「你现在在哪一环」。各中心因此不再另设二级导航，
 * 导航层级由四层（全局侧栏 + 中心导航 + 流程条 + 右面板）收敛为三层。
 * 容器语法与 MeetSync 的票据刻意相反：直角、网格底、等宽编号、工单行取代卡片，
 * 两题并排不会认错。
 * ========================================================================= */

/* ---- 移动端流水线：六环节定位器独占顶栏第二行 ----
 * .appbar 在移动端是单行 flex，定位器作为兄弟节点会挤扁标题列，
 * 因此这里让顶栏换行并把定位器撑满整行（形态细节见 flow.css）。 */
@media (max-width: 1279px) {
  .appbar { height: auto; min-height: var(--appbar-h); flex-wrap: wrap; padding-bottom: 0; }
  .appbar-main { min-height: var(--appbar-h); }
  .relay-bar { flex: 1 1 100%; width: 100%; }
}

/* ---- 血缘节点：图例四色必须落到节点本身 ----
 * 原实现只改 stroke，2.4px 描边在缩略图里读不出来，节点整片灰 —— 图例写了
 * 四色而节点全灰，等于图例说谎。这里补 fill 与影响标签色，同源于 --impact-*。 */
.g-node.must rect   { fill: var(--seal-bg); }
.g-node.eval rect   { fill: var(--memo-bg); }
.g-node.manual rect { fill: var(--pencil-bg); }
.g-node.root rect   { fill: var(--indigo-bg); }
.g-node.must text   { fill: var(--impact-must); }
.g-node.eval text   { fill: var(--impact-eval); }
.g-node.manual text { fill: var(--impact-manual); }
.g-node.must .g-sub, .g-node.eval .g-sub, .g-node.manual .g-sub { fill: currentColor; opacity: .78; }
.g-node.out rect    { fill: var(--surface-2); }
.g-node.out text, .g-node.out .g-sub { fill: var(--faint); }
/* 未波及节点保持中性——「没被影响」本身就是要读出来的信息 */
.g-node:not(.root):not(.must):not(.eval):not(.manual) rect { fill: var(--surface-2); stroke: var(--border); }
/* 基线连线也走虚线，与冲击波连线同族不同强度 */
.g-edge { stroke-dasharray: 6 5; }
.g-edge.hot { stroke-dasharray: none; }

/* 页签标签：移动端取短名（六个四字标签在 390px 下会挤成两行小字）。
 * 用 .tab-copy b 前缀提升特异度——外壳里有更早的规则会把 b 内的裸 span 收掉。 */
.tab-copy b .pf-tab-long { display: inline; }
.tab-copy b .pf-tab-short { display: none; }
@media (max-width: 1279px) {
  .tab-copy b .pf-tab-long { display: none; }
  .tab-copy b .pf-tab-short { display: inline; }
}

/* ---- 蓝图容器：直角 + 网格底 + 等宽编号 ---- */
.pf-blueprint {
  background-image:
    linear-gradient(color-mix(in srgb, var(--border) 62%, transparent) 1px, transparent 1px),
    linear-gradient(90deg, color-mix(in srgb, var(--border) 62%, transparent) 1px, transparent 1px);
  background-size: 22px 22px;
}
/* L1 主体：坐在页面底色上，不加框 */
.pf-subject { padding: var(--sp-4) 0 var(--sp-2); }
.pf-subject u {
  display: block; text-decoration: none; font-family: var(--font-mono);
  font-size: var(--fs-2xs); font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--faint);
}
.pf-subject b { display: block; margin-top: 3px; font-size: var(--fs-xl); font-weight: 700; letter-spacing: var(--ls-h1); line-height: 1.2; }

/* L2 工单行：直角、1px 实线、左侧状态轨，取代等重卡片 */
/* 优先级即视觉重量：最急那一件才配放大与红轨 */

/* 分组标签：一条压到底的细线，不是又一张卡 */
.pf-seclabel {
  display: flex; align-items: center; gap: var(--sp-2); margin: var(--sp-4) 0 var(--sp-2);
  font-family: var(--font-mono); font-size: var(--fs-2xs); font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; color: var(--faint);
}
.pf-seclabel::after { content: ""; flex: 1; height: 1px; background: var(--border); }

/* L3 特权容器：全屏唯一有填充色的东西，只给「卡在你这里」与冲击波 */
.pf-callout {
  padding: var(--sp-3) var(--sp-4); border-radius: var(--radius-sm);
  background: var(--indigo-bg); border-left: 3px solid var(--brand);
}
.pf-callout u { display: block; text-decoration: none; font-size: var(--fs-xs); font-weight: 700; color: var(--brand); }
.pf-callout b { display: block; margin-top: 4px; font-size: var(--fs-lg); font-weight: 700; letter-spacing: var(--ls-h2); line-height: 1.32; }
.pf-callout p { margin: 6px 0 0; font-size: var(--fs-sm); color: var(--fg-2); line-height: 1.55; }
.pf-callout[data-tone="danger"] { background: var(--seal-bg); border-left-color: var(--danger); }
.pf-callout[data-tone="danger"] u { color: var(--danger); }

/* 接力链：上一棒 → 你 → 下一棒。回答「这活儿从谁那来、做完给谁」。 */
/* 三段一行不换行：390 下靠等分 + 省略号收，换行会让箭头孤立在行尾 */
.stop-chain { display: flex; align-items: stretch; gap: var(--sp-1); margin-top: var(--sp-3); }
.stop-chain > span {
  min-width: 0; flex: 1 1 0;
  padding: var(--sp-1) var(--sp-2); border-radius: var(--radius-chip);
  background: var(--surface); border: 1px solid var(--border);
  font-size: var(--fs-sm); font-weight: 650; color: var(--fg-2);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.stop-chain small {
  display: block; margin-top: 1px; font-size: var(--fs-2xs); font-weight: 400; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.stop-chain i { flex: 0 0 auto; align-self: center; font-style: normal; color: var(--faint); }
.stop-chain .stop-me { flex-grow: 1.35; border-color: var(--brand); color: var(--brand); background: var(--surface); }
/* 10px 小字不能再降透明度：opacity .8 会把对比度压到 3.81，低于 4.5 阈值 */
.stop-chain .stop-me small { color: var(--brand); }
.stop-chain .stop-prev { color: var(--success); }
.stop-chain .stop-next { border-style: dashed; color: var(--muted); }

/* 我交出去的：交接链的发起方视图，每行可原地撤回 */
.sent-row {
  display: flex; align-items: center; flex-wrap: wrap; gap: var(--sp-2) var(--sp-3);
  padding: var(--sp-3); border: 1px solid var(--border);
  border-radius: var(--radius-sm); background: var(--surface);
}
.sent-who { display: flex; align-items: center; gap: 5px; font-size: var(--fs-sm); }
.sent-who b { font-weight: 650; color: var(--fg-2); }
.sent-who b.to { color: var(--brand); }
.sent-who i { font-style: normal; color: var(--faint); }
.sent-what { flex: 1 1 100%; font-size: var(--fs-xs); color: var(--muted); }
.sent-meta { display: flex; align-items: center; gap: var(--sp-2); }
.sent-meta em { font-style: normal; font-size: var(--fs-2xs); font-family: var(--font-mono); color: var(--faint); }
.sent-row > .btn { margin-left: auto; }

/* 非主责生产线：折叠为只读上下文，避免对该身份冗余 */
.lane-fold { margin-top: var(--sp-3); }
.lane-fold > summary {
  display: flex; align-items: center; gap: var(--sp-2); padding: var(--sp-2) var(--sp-3);
  border: 1px dashed var(--border-strong); border-radius: var(--radius-sm);
  color: var(--muted); font-size: var(--fs-sm); cursor: pointer; list-style: none;
}
.lane-fold > summary::-webkit-details-marker { display: none; }
.lane-fold[open] > summary { margin-bottom: var(--sp-3); color: var(--fg-2); }
.lane-fold[open] .lane { opacity: .82; }

/* ---- 血缘画布：节点按冲击等级真配色，连线为虚线贝塞尔 ---- */
.wf-shell { border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); overflow: hidden; }
.wf-head {
  display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap;
  padding: 9px 12px; border-bottom: 1px solid var(--border); background: var(--surface-2);
}
.wf-head .wf-title { font-family: var(--font-mono); font-size: var(--fs-2xs); font-weight: 700; letter-spacing: .09em; text-transform: uppercase; color: var(--faint); }
.wf-head .wf-spacer { flex: 1; }
.wf-canvas { position: relative; overflow: auto; -webkit-overflow-scrolling: touch; }
.wf-canvas-inner { position: relative; }
.wf-edges { position: absolute; inset: 0; pointer-events: none; }
.wf-edges path { fill: none; stroke: var(--border-strong); stroke-width: 1.6; stroke-dasharray: 7 5; stroke-linecap: round; }
.wf-edges path.is-hot { stroke: var(--impact-must); stroke-dasharray: none; stroke-width: 2; }
.wf-node {
  position: absolute; display: block; text-align: left;
  border: 1.5px solid var(--border-strong); border-radius: var(--radius-chip);
  background: var(--surface); padding: 8px 10px; cursor: pointer;
}
.wf-node .wf-kind { display: block; font-family: var(--font-mono); font-size: 9px; letter-spacing: .07em; text-transform: uppercase; color: var(--faint); }
.wf-node .wf-name { display: block; margin-top: 2px; font-size: var(--fs-sm); font-weight: 700; line-height: 1.25; color: var(--fg); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wf-node .wf-impact { display: inline-block; margin-top: 5px; font-family: var(--font-mono); font-size: 9px; font-weight: 700; letter-spacing: .04em; }
/* 冲击等级 → 节点配色。图例四色与节点必须同源，否则图例说谎。 */
.wf-node[data-impact="root"]   { border-color: var(--brand); background: var(--indigo-bg); }
.wf-node[data-impact="root"]   .wf-impact { color: var(--brand); }
.wf-node[data-impact="must"]   { border-color: var(--impact-must); background: var(--seal-bg); }
.wf-node[data-impact="must"]   .wf-impact { color: var(--impact-must); }
.wf-node[data-impact="eval"]   { border-color: var(--impact-eval); background: var(--memo-bg); }
.wf-node[data-impact="eval"]   .wf-impact { color: var(--impact-eval); }
.wf-node[data-impact="manual"] { border-color: var(--impact-manual); background: var(--pencil-bg); }
.wf-node[data-impact="manual"] .wf-impact { color: var(--impact-manual); }
.wf-node[data-impact="none"]   { border-color: var(--border); background: var(--surface-2); }
.wf-node[data-impact="none"]   .wf-name { color: var(--muted); }
.wf-node[data-impact="none"]   .wf-impact { color: var(--faint); }
.wf-node.is-current { box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand) 26%, transparent); }
@media (hover: hover) and (pointer: fine) { .wf-node:hover { border-color: var(--fg); } }
/* 底部统计条：画布的元信息，不占画布面积 */
.wf-foot {
  display: flex; align-items: center; gap: var(--sp-3) var(--sp-4); flex-wrap: wrap;
  padding: 8px 12px; border-top: 1px solid var(--border); background: var(--surface-2);
  font-family: var(--font-mono); font-size: var(--fs-2xs); color: var(--muted);
}
.wf-foot .wf-legend { display: inline-flex; align-items: center; gap: 5px; }
.wf-foot .wf-legend i { width: 9px; height: 9px; border-radius: 2px; border: 1.5px solid currentColor; }
.wf-foot .wf-legend[data-impact="must"]   { color: var(--impact-must); }
.wf-foot .wf-legend[data-impact="eval"]   { color: var(--impact-eval); }
.wf-foot .wf-legend[data-impact="manual"] { color: var(--impact-manual); }
.wf-foot .wf-legend[data-impact="none"]   { color: var(--faint); }
.wf-foot .wf-hint { margin-left: auto; color: var(--faint); }
/* 图谱内嵌用法：统计条贴在画布下沿，与 .graph 的圆角对齐 */
.graph .wf-foot {
  margin: var(--sp-3) calc(var(--sp-3) * -1) calc(var(--sp-3) * -1);
  border-radius: 0 0 var(--radius) var(--radius);
}
