/* app.css —— 页面布局层（Task 37 D-3）：index 三栏研究员工作台 + audit 审计面板。
   只放布局结构与一次性页面样式；颜色走 tokens.css、可复用外观走 components.css。
   本文件不出现裸色值；间距/字号一律引用变量，仅几何尺寸（宽高/定位/描边）保留 px。 */

/* ===================== 基础 reset / 正文 ===================== */
* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; }
body {
  font-family: var(--font-sans); font-size: var(--font-size-base);
  line-height: var(--line-base); color: var(--color-text-primary);
  background: var(--color-bg-page); -webkit-font-smoothing: antialiased;
}
/* index 是占满视口的弹性三栏应用；audit 是自然滚动文档（不加此类） */
body.app-body { display: flex; flex-direction: column; overflow: hidden; }
::selection { background: var(--color-selection); }

/* ===================== index · 顶栏 ===================== */
.app-header {
  height: var(--layout-header-h); flex-shrink: 0; position: relative; z-index: var(--z-header);
  display: flex; align-items: center; gap: var(--space-3-5); padding: 0 var(--space-4-5);
  background: var(--color-surface-glass); backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--color-border);
}
.logo { display: flex; align-items: baseline; gap: var(--space-2-5); }
.logo .name {
  position: relative; font-family: var(--font-serif); font-size: var(--font-size-2xl);
  letter-spacing: .03em; font-weight: var(--weight-regular);
}
.logo .name .grad { background: var(--gradient-primary); -webkit-background-clip: text; background-clip: text; color: transparent; }
.logo .name::after {
  content: ""; position: absolute; bottom: -3px; left: 0; height: 3px; width: 100%;
  border-radius: var(--radius-sm); background: var(--gradient-underline);
}
.logo small { font-family: var(--font-mono); font-size: var(--font-size-2xs); letter-spacing: .14em; text-transform: uppercase; color: var(--color-text-tertiary); }
.app-header .spacer { flex: 1; }
.app-header .chip { border: 1px solid var(--color-border); background: var(--color-bg-subtle); padding: var(--space-1-5) var(--space-3); }
.app-header .chip b { color: var(--color-primary); font-weight: var(--weight-medium); }
select.role {
  font-family: var(--font-sans); font-size: var(--font-size-md);
  padding: var(--space-1-5) var(--space-3); border-radius: var(--radius-xl);
  background: var(--color-bg-surface); color: var(--color-text-primary);
  border: 1px solid var(--color-border); cursor: pointer;
  transition: border-color .2s, box-shadow .2s;
}
select.role:focus { outline: none; border-color: var(--color-ring); box-shadow: var(--shadow-focus); }
.left-toggle { display: none; }
/* Task 51 · 右栏移动端抽屉入口（桌面默认隐藏；≤900px 见下方媒体查询） */
.right-close { display: none; }
.right-fab {
  /* Task 55 · 层级已是全局 token var(--z-guide)=10000（在变暗环之上、气泡之下），
     不放进媒体查询；display 仍由媒体查询控制。 */
  display: none; position: fixed; right: 16px; bottom: 16px; z-index: var(--z-guide);
  align-items: center; gap: 6px;
}
/* Task 52 F2：抽屉打开时隐藏 FAB（避免“两个入口打架”） */
body.right-open .right-fab { display: none !important; }
/* Task 52.1（Clawy 热修）：引导进行中隐藏悬浮入口。
   手机端气泡是底部浮层 → 必然盖住右下角 FAB，点它会“无任何反应”；
   引导期由主链负责开合右栏（step8 revealRight），不需要这个入口。
   .tour-active 由 tour.js 在气泡存在时设置 → 气泡一出现入口就退场，两者不会同时出现。 */
body.tour-active .right-fab { display: none !important; }
/* Task 55 · 引导期层叠全局化（**彻底不用媒体查询**）：
   真机上顶栏溢出会把**布局视口**撑宽 >900px → 写在 @media (max-width:900px) 里的
   层级修复在真机不命中（Playwright 模拟却命中）→ 这就是上次"模拟通过、真机失败"的原因。
   改为**全局**生效：
   · .tour-root 不再 position:fixed（固定定位会生成层叠上下文）→ 环/气泡回到根上下文，
     完全靠 tokens.css 的 z-index 明确排序（--z-scrim < --z-target < --z-guide < --z-tip）。
   · 气泡 = --z-tip(10100) → 恒在变暗环(9900)与右栏抽屉(10000)之上，必不被压暗/遮挡。 */
body .tour-root { position: static; z-index: auto; }
body .tour-tip { z-index: var(--z-tip); }

/* 小节标题（左右栏通用） */
.l-sec h4, .r-sec h4 {
  display: flex; justify-content: space-between; align-items: center; gap: var(--space-2);
  margin-bottom: var(--space-3);
  font-family: var(--font-mono); font-size: var(--font-size-xs); letter-spacing: .15em;
  text-transform: uppercase; color: var(--color-text-tertiary);
}
.l-sec h4 .dot, .r-sec h4 .dot {
  width: 7px; height: 7px; border-radius: var(--radius-pill); background: var(--gradient-primary);
  display: inline-block; animation: pulse 2s infinite;
}

/* ===================== index · 三栏骨架 ===================== */
.app-main { flex: 1; display: flex; min-height: 0; }
aside.left {
  width: var(--layout-left-w); flex-shrink: 0; min-height: 0; overflow-y: auto;
  display: flex; flex-direction: column;
  background: var(--color-bg-surface); border-right: 1px solid var(--color-border);
}
.l-sec { padding: var(--space-3-5); border-bottom: 1px solid var(--color-border); }
.l-sec:last-child { border-bottom: none; flex: 1; }

/* 会话历史 */
.hist-item {
  font-size: var(--font-size-md); padding: var(--space-2) var(--space-2-5);
  margin-bottom: var(--space-1-5); border: 1px solid var(--color-border); border-radius: var(--radius-md);
  background: var(--color-bg-page); cursor: pointer; transition: all .2s ease-out;
}
.hist-item:hover { transform: translateY(-1px); box-shadow: var(--shadow-md); border-color: var(--color-primary-border-soft); }
.hist-item.active { border-color: var(--color-primary); background: var(--color-primary-tint-5); box-shadow: var(--shadow-primary); }
.hist-item .t { display: flex; justify-content: space-between; gap: var(--space-2); align-items: center; font-weight: var(--weight-medium); }
.hist-item .s { font-size: var(--font-size-xs); margin-top: var(--space-0-5); color: var(--color-text-tertiary); }
.hist-item.has-arts { border-left: 3px solid var(--color-primary); padding-left: var(--space-2); }
.hist-item .arts-n {
  display: inline-flex; align-items: center; gap: var(--space-0-5);
  font-family: var(--font-mono); font-size: var(--font-size-2xs); font-weight: var(--weight-semibold);
  background: var(--color-info-tint-10); color: var(--color-info);
  padding: var(--space-0-5) var(--space-1-5); border-radius: var(--radius-pill);
}

/* 跟踪池 */
.wl-item {
  display: flex; justify-content: space-between; align-items: center; gap: var(--space-1-5);
  font-size: var(--font-size-sm); padding: var(--space-1-5) var(--space-2);
  margin-bottom: var(--space-1-5); background: var(--color-bg-page);
  border: 1px solid var(--color-border); border-radius: var(--radius-md);
}
.wl-item .tag2 { font-size: var(--font-size-2xs); color: var(--color-text-tertiary); }
.wl-item .wl-company { font-weight: var(--weight-semibold); }
.wl-item .wl-sector {
  font-family: var(--font-mono); font-size: var(--font-size-2xs);
  padding: var(--space-0-5) var(--space-1-5); border-radius: var(--radius-lg);
  background: var(--color-info-tint-8); color: var(--color-info);
}
.wl-add { display: flex; gap: var(--space-1-5); margin-top: var(--space-2-5); }
.wl-add input {
  flex: 1; font-family: var(--font-sans); font-size: var(--font-size-sm);
  padding: var(--space-1-5) var(--space-2-5); border-radius: var(--radius-md);
  background: var(--color-bg-page);
}
.btn-wl-remove {
  padding: var(--space-0-5) var(--space-2); font-size: var(--font-size-xs);
  background: transparent; color: var(--color-danger-strong);
  border: 1px solid var(--color-danger-strong); border-radius: var(--radius-sm); cursor: pointer;
}
.btn-wl-remove:hover { background: var(--color-danger-strong); color: var(--color-on-primary); }
.new-session-btn { width: 100%; margin-bottom: var(--space-2-5); }

/* ===================== index · 中栏 ===================== */
section.mid { flex: 1; display: flex; flex-direction: column; min-width: 0; min-height: 0; background: var(--color-bg-page); }
.stream {
  flex: 1; min-height: 0; overflow-y: auto;
  padding: var(--space-4-5) var(--space-5-5);
  display: flex; flex-direction: column; gap: var(--space-3);
}
.stream > * { flex-shrink: 0; }
.stream > .card {
  max-width: 780px; transition: box-shadow .25s, transform .25s;
  animation: fadeUp .42s cubic-bezier(.2,.8,.2,1) both;
}
.stream > .card:hover { box-shadow: var(--shadow-md); }
.card .head {
  display: flex; justify-content: space-between; align-items: center;
  margin-bottom: var(--space-2); font-size: var(--font-size-md); color: var(--color-text-tertiary);
}
.card .head b { color: var(--color-text-primary); font-size: var(--font-size-base); font-weight: var(--weight-semibold); }
.card .val { font-size: var(--font-size-xl); margin: var(--space-1) 0; line-height: var(--line-snug); }
.card .val b { color: var(--color-primary); font-weight: var(--weight-bold); }
.card .src { font-size: var(--font-size-xs); color: var(--color-text-tertiary); }
.card .src em { font-style: normal; color: var(--color-primary); }
.card.denied { border-color: var(--color-danger-border); background: var(--gradient-card-denied); }
.card.denied .msg { color: var(--color-danger); font-size: var(--font-size-md); margin: var(--space-1) 0; font-weight: var(--weight-medium); }
.card.featured {
  border: 2px solid transparent;
  background: linear-gradient(var(--color-bg-surface), var(--color-bg-surface)) padding-box, var(--gradient-primary) border-box;
  box-shadow: var(--shadow-primary);
}
.user-card {
  align-self: flex-end; max-width: 68%; border: none; border-radius: var(--radius-3xl) var(--radius-3xl) var(--radius-xs) var(--radius-3xl);
  background: var(--gradient-primary); color: var(--color-on-primary);
}
.user-card .msg-body { font-size: var(--font-size-base); line-height: var(--line-base); white-space: pre-wrap; word-break: break-word; }

/* 压缩提示条 */
.compress-bar {
  display: flex; justify-content: space-between; align-items: center; gap: var(--space-2-5);
  margin-bottom: var(--space-2-5); font-size: var(--font-size-sm);
  padding: var(--space-2) var(--space-3-5); border-radius: var(--radius-xl);
  background: var(--color-warning-bg); color: var(--color-warning);
  border: 1px solid var(--color-warning-border-soft);
}
.compress-bar .btns { display: flex; gap: var(--space-1-5); }

/* 上下文 chips */
.ctx-chips { display: flex; flex-wrap: wrap; gap: var(--space-1-5); align-items: center; }
.ctx-chip {
  display: inline-flex; align-items: center; gap: var(--space-1); cursor: pointer;
  font-size: var(--font-size-xs); padding: var(--space-0-5) var(--space-2);
  border-radius: var(--radius-pill); border: 1px solid var(--color-primary-border-soft);
  background: var(--color-primary-tint-8); color: var(--color-primary);
  transition: all .15s;
}
.ctx-chip:hover { background: var(--color-primary-tint-15); }
.ctx-chip .x { opacity: .5; font-size: var(--font-size-2xs); }
.ctx-chip:hover .x { opacity: 1; }

/* 底部输入区 */
.composer {
  flex-shrink: 0; padding: var(--space-3) var(--space-5-5) var(--space-3-5);
  border-top: 1px solid var(--color-border);
  background: var(--color-surface-glass-strong); backdrop-filter: blur(8px);
}
.composer .mode-row {
  display: flex; align-items: center; gap: var(--space-3-5); margin-bottom: var(--space-2-5);
  font-size: var(--font-size-sm); color: var(--color-text-tertiary); flex-wrap: wrap;
}
.composer .mode-row .set { margin-left: auto; font-family: var(--font-mono); font-size: var(--font-size-xs); letter-spacing: .04em; }
.composer .mode-row .set .ic {
  display: inline-flex; align-items: center; gap: var(--space-1);
  cursor: pointer; padding: var(--space-0-5) var(--space-1-5);
  border-radius: var(--radius-sm); transition: background .2s, color .2s;
}
.composer .mode-row .set .ic:hover { background: var(--color-primary-tint-8); color: var(--color-primary); }
.composer .box { display: flex; gap: var(--space-2-5); align-items: stretch; }
.composer input {
  flex: 1; font-family: var(--font-sans); font-size: var(--font-size-lg);
  padding: var(--space-3) var(--space-4); border-radius: var(--radius-xl);
  background: var(--color-bg-surface); box-shadow: var(--shadow-sm);
}
.composer input:focus { box-shadow: var(--shadow-focus), var(--shadow-md); }
.composer input::placeholder { color: var(--color-text-tertiary); opacity: .55; }
.composer .hint {
  margin-top: var(--space-2-5); display: flex; gap: var(--space-2-5); flex-wrap: wrap; align-items: center;
  font-size: var(--font-size-sm); color: var(--color-text-tertiary);
}
.composer .hint .try {
  color: var(--color-primary); cursor: pointer; text-decoration: none;
  border-bottom: 1px dotted var(--color-primary-border-strong); transition: color .2s;
}
.composer .hint .try:hover { color: var(--color-primary-400); }

/* 结果表 */
table.result { width: 100%; border-collapse: collapse; margin-top: var(--space-3); font-size: var(--font-size-md); }
table.result th, table.result td {
  text-align: left; padding: var(--space-2) var(--space-2-5);
  border-bottom: 1px solid var(--color-border); vertical-align: top;
}
table.result thead th {
  font-family: var(--font-mono); font-size: var(--font-size-2xs); font-weight: var(--weight-medium);
  letter-spacing: .1em; text-transform: uppercase; color: var(--color-text-tertiary);
  border-bottom: 1px solid var(--color-text-primary);
}
table.result td.val {
  font-family: var(--font-serif); font-size: var(--font-size-2xl); font-weight: var(--weight-bold);
  letter-spacing: -.02em; white-space: nowrap; padding: var(--space-2-5) var(--space-2-5); position: relative;
}
table.result td.val::after {
  content: ""; display: inline-block; width: var(--space-1); height: var(--space-1);
  border-radius: var(--radius-pill); background: var(--color-primary);
  margin-left: var(--space-2); vertical-align: middle; opacity: .4;
}
table.result td.company { font-weight: var(--weight-semibold); }
table.result tbody tr:hover td { background: var(--color-primary-tint-2); }
.trace { color: var(--color-text-tertiary); font-size: var(--font-size-sm); line-height: 1.5; margin-top: var(--space-0-5); }
.st-ok { color: var(--color-success-text); }
.st-denied { color: var(--color-danger-strong); font-weight: var(--weight-semibold); }
.st-unavailable { color: var(--color-neutral-500); }

/* 来源徽标（信息色固定语义：内=蓝/实时=绿/缓存=橙/Wind=紫/拒=红/无=灰） */
.card .src {
  padding: var(--space-0-5) var(--space-2); border-radius: var(--radius-md);
  font-family: var(--font-mono); font-weight: var(--weight-semibold); letter-spacing: .02em;
}
.src-internal { background: var(--color-src-internal-bg); color: var(--color-src-internal-fg); }
.src-akshare { background: var(--color-src-akshare-bg); color: var(--color-src-akshare-fg); }
.src-cache { background: var(--color-src-cache-bg); color: var(--color-src-cache-fg); }
.src-wind_mock { background: var(--color-src-wind-bg); color: var(--color-src-wind-fg); }
.src-denied { background: var(--color-src-denied-bg); color: var(--color-src-denied-fg); }
.src-unavailable { background: var(--color-src-unavailable-bg); color: var(--color-src-unavailable-fg); }
.btn-approval {
  margin-top: var(--space-1); padding: var(--space-1) var(--space-2-5);
  font-size: var(--font-size-sm); background: var(--color-info); color: var(--color-on-primary);
  border: 0; border-radius: var(--radius-sm); cursor: pointer;
}
.btn-approval:disabled { background: var(--color-text-disabled); cursor: not-allowed; }

/* 任务步骤行 */
.step-row {
  display: flex; justify-content: space-between; align-items: center; gap: var(--space-2);
  font-size: var(--font-size-md); padding: var(--space-1-5) var(--space-0-5);
  border-bottom: 1px dashed var(--color-border);
}
.step-row:last-child { border-bottom: none; }
.step-row .tool { color: var(--color-text-tertiary); font-size: var(--font-size-xs); font-family: var(--font-mono); }
.step-row .sn { font-weight: var(--weight-medium); }
.t-step-status { font-family: var(--font-mono); font-size: var(--font-size-xs); letter-spacing: .06em; text-transform: uppercase; }
.t-step-status.st-pending { color: var(--color-text-tertiary); }
.t-step-status.st-running { color: var(--color-info); }
.t-step-status.st-done { color: var(--color-success-text); }
.t-step-status.st-denied, .t-step-status.st-failed { color: var(--color-danger-strong); }
.t-step-tool { color: var(--color-text-tertiary); font-size: var(--font-size-xs); font-family: var(--font-mono); margin-left: var(--space-1-5); }

/* 简报预览（随消息流完整展开，不做内部滚动） */
.briefing-preview {
  margin-top: var(--space-3); border: 1px solid var(--color-border); border-radius: var(--radius-lg);
  padding: var(--space-3) var(--space-4); background: var(--color-bg-page);
}
.briefing-preview h3 {
  margin: 0 0 var(--space-2); font-size: var(--font-size-base); letter-spacing: .02em;
  display: flex; justify-content: space-between; align-items: center;
}
.briefing-preview h3 .filename { font-size: var(--font-size-2xs); font-weight: var(--weight-regular); color: var(--color-text-tertiary); font-family: var(--font-mono); }
.briefing-preview .md-body {
  font-family: var(--font-serif); font-size: var(--font-size-md); line-height: var(--line-relaxed);
  white-space: pre-wrap; word-break: break-word;
}
.briefing-preview .md-body.empty { color: var(--color-text-tertiary); font-style: italic; }

/* ===================== index · 右栏 ===================== */
aside.right {
  width: var(--layout-right-w); flex-shrink: 0; overflow-y: auto;
  display: flex; flex-direction: column;
  /* Task 55 · 抽屉层级改为**全局** token（不放进媒体查询）：
     该元素本身是 static（z-index 无效果），只有 ≤900px 变 fixed 为抽屉时才生效。
     display/position 仍由下方的媒体查询控制。 */
  z-index: var(--z-guide);
  background: var(--color-bg-surface); border-left: 1px solid var(--color-border);
}
.r-sec { padding: var(--space-3-5) var(--space-4); border-bottom: 1px solid var(--color-border); }
aside.right > .tabs {
  position: sticky; top: 0; z-index: var(--z-tab);
  padding: var(--space-2) var(--space-3) 0; background: var(--color-bg-surface);
}
aside.right > .tabs .tab { position: relative; flex: 1; padding: var(--space-2) var(--space-1); font-size: var(--font-size-2xs); letter-spacing: .1em; }
.tab-badge {
  position: absolute; top: 2px; right: calc(50% - 28px);
  min-width: 16px; height: 16px; padding: 0 var(--space-1);
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--color-danger); color: var(--color-on-primary); border-radius: var(--radius-pill);
  font-family: var(--font-mono); font-size: var(--font-size-3xs); font-weight: var(--weight-bold);
  line-height: 1; box-shadow: var(--shadow-danger-sm); pointer-events: none;
  transform: translateY(-1px); animation: badgePulse 2.2s infinite ease-in-out;
}

/* 概况统计卡 */
.stats { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2-5); }
.stats .stat {
  position: relative; overflow: hidden; cursor: pointer;
  background: var(--color-bg-page); border: 1px solid var(--color-border); border-radius: var(--radius-xl);
  padding: var(--space-2-5) var(--space-3);
  transition: all .2s ease-out;
}
.stats .stat:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); border-color: var(--color-primary-border); }
.stats .stat::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 2px;
  background: var(--gradient-primary); opacity: 0; transition: opacity .2s;
}
.stats .stat:hover::before { opacity: 1; }
.stats .stat.active { border-color: var(--color-primary); background: var(--color-primary-tint-5); }
.stats .stat .n { font-size: var(--font-size-2xl); font-weight: var(--weight-bold); letter-spacing: -.02em; line-height: 1.1; }
.stats .stat .l, .stats .stat .label {
  font-family: var(--font-mono); font-size: var(--font-size-2xs); letter-spacing: .1em;
  text-transform: uppercase; color: var(--color-text-tertiary);
}
.stats .stat .d { font-size: var(--font-size-xs); color: var(--color-primary); margin-top: var(--space-0-5); }

/* 审批条目 */
.aprv-item {
  font-size: var(--font-size-md); margin-bottom: var(--space-2);
  padding: var(--space-2-5) var(--space-3); border: 1px solid var(--color-border);
  border-radius: var(--radius-lg); background: var(--color-bg-page); transition: box-shadow .2s;
}
.aprv-item:hover { box-shadow: var(--shadow-md); }
.aprv-item .a { display: flex; justify-content: space-between; align-items: center; margin-bottom: var(--space-1); gap: var(--space-2); }
.aprv-item .a b { font-weight: var(--weight-semibold); font-size: var(--font-size-md); }
.aprv-item .who { color: var(--color-text-tertiary); font-size: var(--font-size-xs); }
.aprv-item .reason { margin-top: var(--space-1-5); font-size: var(--font-size-sm); line-height: 1.5; }
.aprv-item .note {
  margin-top: var(--space-1-5); padding: var(--space-1-5) var(--space-2);
  font-size: var(--font-size-sm); border-left: 3px solid var(--color-border); background: var(--color-inset-wash);
}
.aprv-item .btns { display: flex; gap: var(--space-2); margin-top: var(--space-2); }
.aprv-item.expandable { cursor: pointer; }
.aprv-item .aprv-caret { font-size: var(--font-size-3xs); color: var(--color-text-tertiary); display: inline-block; transition: transform .2s; margin-left: var(--space-1); }
.aprv-item.open .aprv-caret { transform: rotate(90deg); }
.aprv-item .x-detail { display: none; margin-top: var(--space-2); padding-top: var(--space-2); border-top: 1px dashed var(--color-border); cursor: default; }
.aprv-item.open .x-detail { display: block; }
.x-tl { font-size: var(--font-size-xs); line-height: 1.9; color: var(--color-text-tertiary); }
.x-tl .tl-row { display: flex; gap: var(--space-2); align-items: baseline; }
.x-tl .tl-dot { width: 6px; height: 6px; border-radius: var(--radius-pill); background: var(--color-primary); flex-shrink: 0; position: relative; top: -2px; }
.x-tl .tl-row:last-child .tl-dot { background: var(--color-success); }
.grant-ok { color: var(--color-success-text); font-weight: var(--weight-semibold); }
.grant-expired { color: var(--color-text-tertiary); }

/* 深色反区块：合规风险（既有亮点，语义色在深色底上反转） */
.risk-box {
  position: relative; overflow: hidden;
  background: var(--color-bg-inverse); border-radius: var(--radius-2xl);
  padding: var(--space-3-5) var(--space-4); box-shadow: var(--shadow-lg);
}
.risk-box::before {
  content: ""; position: absolute; top: -60px; right: -60px; width: 160px; height: 160px;
  border-radius: var(--radius-pill); background: var(--glow-risk); pointer-events: none;
}
.risk-box h5 {
  margin-bottom: var(--space-2-5); font-family: var(--font-mono); font-size: var(--font-size-2xs);
  letter-spacing: .15em; text-transform: uppercase; color: var(--color-text-on-dark);
}
.risk {
  display: flex; gap: var(--space-2); align-items: flex-start;
  font-size: var(--font-size-sm); border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-2-5); margin-bottom: var(--space-1-5);
}
.risk:last-child { margin-bottom: 0; }
.risk.warn { background: var(--color-on-warning-bg); border: 1px solid var(--color-on-warning-border); color: var(--color-on-warning); }
.risk.bad { background: var(--color-on-danger-bg); border: 1px solid var(--color-on-danger-border); color: var(--color-on-danger); }
.risk.ok { background: var(--color-on-success-bg); border: 1px solid var(--color-on-success-border); color: var(--color-on-success); }
.risk .pulse-dot {
  width: 6px; height: 6px; margin-top: 5px; flex-shrink: 0;
  border-radius: var(--radius-pill); animation: pulse 2s infinite;
}
.risk.bad .pulse-dot { background: var(--color-on-danger-dot); }
.risk.warn .pulse-dot { background: var(--color-on-warning-dot); }
.risk.ok .pulse-dot { background: var(--color-on-success); }

/* 详情 tab */
.detail .d-row {
  display: flex; justify-content: space-between; align-items: center; gap: var(--space-2);
  font-size: var(--font-size-md); padding: var(--space-1-5) var(--space-0-5);
  border-bottom: 1px dashed var(--color-border);
}
.detail .d-row:last-child { border-bottom: none; }
.file {
  display: flex; justify-content: space-between; align-items: center; gap: var(--space-2);
  font-size: var(--font-size-md); margin-bottom: var(--space-1-5);
  padding: var(--space-1-5) var(--space-2-5); border: 1px solid var(--color-border);
  border-radius: var(--radius-md); background: var(--color-bg-page); transition: box-shadow .2s;
}
.file:hover { box-shadow: var(--shadow-md); }
.art-tag {
  margin-right: var(--space-1-5); padding: var(--space-0-5) var(--space-1-5);
  border-radius: var(--radius-lg); background: var(--color-info-tint-8); color: var(--color-info);
  font-family: var(--font-mono); font-size: var(--font-size-2xs); text-transform: uppercase;
}
.art-tag.docx { background: var(--color-src-akshare-bg); color: var(--color-success-text); }
.art-tag.xlsx { background: var(--color-src-wind-bg); color: var(--color-purple); }
.art-download {
  font-size: var(--font-size-sm); color: var(--color-primary); cursor: pointer; text-decoration: none;
  border-bottom: 1px solid transparent; padding-bottom: var(--space-0-5);
}
.art-download:hover { border-bottom-color: var(--color-primary); }
ul.artifacts, ul.ti-steps {
  list-style: none; padding: 0; margin: var(--space-1-5) 0 0;
  display: flex; flex-direction: column; gap: var(--space-1);
}
ul.artifacts li, ul.ti-steps li {
  display: flex; justify-content: space-between; align-items: center; gap: var(--space-2); flex-wrap: wrap;
  padding: var(--space-1) var(--space-2); border: 1px solid var(--color-border);
  border-radius: var(--radius-sm); font-size: var(--font-size-md);
}
ul.artifacts li.empty, ul.ti-steps li.empty {
  color: var(--color-text-tertiary); text-align: center; justify-content: center; border-style: dashed;
}
.col-label {
  margin: var(--space-2-5) 0 var(--space-1-5); font-family: var(--font-mono); font-size: var(--font-size-2xs);
  letter-spacing: .12em; text-transform: uppercase; color: var(--color-text-tertiary);
}
.sec-note { padding-top: var(--space-1-5); font-size: var(--font-size-xs); color: var(--color-text-tertiary); text-align: center; line-height: 1.5; }
.footer-note {
  margin-top: auto; padding: var(--space-3) var(--space-4-5);
  border-top: 1px dashed var(--color-border);
  font-family: var(--font-mono); font-size: var(--font-size-2xs); color: var(--color-text-tertiary); line-height: 1.8;
}
.footer-note b { color: var(--color-primary); }

/* 记忆 tab */
.mem-stats { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: var(--space-2); margin-bottom: var(--space-3); }
.mem-stats .stat { padding: var(--space-2) var(--space-2-5); border-radius: var(--radius-lg); background: var(--color-bg-page); border: 1px solid var(--color-border); }
.mem-stats .stat .n { font-size: var(--font-size-xl); font-weight: var(--weight-bold); }
.mem-stats .stat .l { font-family: var(--font-mono); font-size: var(--font-size-2xs); letter-spacing: .04em; color: var(--color-text-tertiary); }
.mem-stats .num-query { color: var(--color-info); }
.mem-stats .num-report { color: var(--color-warning); }
.mem-filter { display: flex; gap: var(--space-1-5); margin-bottom: var(--space-3); flex-wrap: wrap; }
.mem-filter input, .mem-filter select {
  flex: 1; min-width: 0; font-family: var(--font-sans); font-size: var(--font-size-sm);
  padding: var(--space-1-5) var(--space-2-5); border-radius: var(--radius-md); background: var(--color-bg-page);
}
.fact-card {
  margin-bottom: var(--space-2); padding: var(--space-2-5) var(--space-3);
  border: 1px solid var(--color-border); border-radius: var(--radius-lg);
  background: var(--color-bg-page); cursor: pointer; transition: box-shadow .2s, border-color .2s;
}
.fact-card:hover { box-shadow: var(--shadow-sm); border-color: var(--color-primary-border-soft); }
.fact-card.open { border-color: var(--color-primary); background: var(--color-primary-tint-4); }
.fact-head { display: flex; justify-content: space-between; align-items: flex-start; gap: var(--space-2); margin-bottom: var(--space-1); }
.fact-head .cm { font-weight: var(--weight-semibold); font-size: var(--font-size-md); min-width: 0; }
.fact-head .cm .c { color: var(--color-text-primary); }
.fact-head .cm .m { color: var(--color-text-tertiary); font-weight: var(--weight-medium); font-size: var(--font-size-sm); margin-left: var(--space-1); }
.fact-val { font-family: var(--font-serif); font-size: var(--font-size-xl); font-weight: var(--weight-bold); color: var(--color-primary); white-space: nowrap; }
.fact-meta { display: flex; gap: var(--space-1-5); flex-wrap: wrap; align-items: center; margin-top: var(--space-1); font-family: var(--font-mono); font-size: var(--font-size-2xs); color: var(--color-text-tertiary); }
.fact-badge { padding: var(--space-0-5) var(--space-1-5); border-radius: var(--radius-sm); font-size: var(--font-size-3xs); letter-spacing: .03em; font-weight: var(--weight-medium); }
.fact-badge.query { background: var(--color-info-tint-10); color: var(--color-info); }
.fact-badge.report { background: var(--color-src-cache-bg); color: var(--color-warning); }
.fact-conf { padding: var(--space-0-5) var(--space-1-5); border-radius: var(--radius-xs); font-size: var(--font-size-3xs); font-weight: var(--weight-semibold); }
.fact-conf.high { background: var(--color-src-akshare-bg); color: var(--color-success); }
.fact-conf.mid { background: var(--color-src-cache-bg); color: var(--color-warning); }
.fact-conf.low { background: var(--color-src-unavailable-bg); color: var(--color-neutral-500); }
.fact-trace {
  color: var(--color-text-tertiary); font-size: var(--font-size-2xs); cursor: pointer; text-decoration: none;
  border-bottom: 1px dotted var(--color-primary-border-strong); padding-bottom: .5px; transition: color .15s;
}
.fact-trace:hover { color: var(--color-primary); border-bottom-color: var(--color-primary); }
.fact-timeline {
  display: none; max-height: 180px; overflow-y: auto;
  margin-top: var(--space-2-5); padding: var(--space-2) var(--space-2-5);
  border: 1px dashed var(--color-border); border-radius: var(--radius-md);
  background: var(--color-bg-surface);
  font-family: var(--font-mono); font-size: var(--font-size-xs); color: var(--color-text-tertiary);
}
.fact-card.open .fact-timeline { display: block; }
.fact-timeline .tl-item { padding: var(--space-0-5) 0; border-bottom: 1px dotted var(--color-border); }
.fact-timeline .tl-item:last-child { border-bottom: none; }
.fact-timeline .tl-arrow { color: var(--color-primary); font-weight: var(--weight-bold); margin: 0 var(--space-1); }
.mem-empty { text-align: center; padding: var(--space-7) var(--space-3); color: var(--color-text-tertiary); font-size: var(--font-size-md); line-height: 1.8; }
.mem-empty .big { font-family: var(--font-serif); font-size: var(--font-size-2xl); color: var(--color-text-primary); margin-bottom: var(--space-1-5); }

/* 输出偏好 md/docx 切换 */
.fmt-toggle {
  display: inline-flex; align-items: center; gap: 0; overflow: hidden;
  border: 1px solid var(--color-border); border-radius: var(--radius-md);
  background: var(--color-bg-surface); font-family: var(--font-mono); font-size: var(--font-size-2xs);
}
.fmt-toggle .seg { padding: var(--space-0-5) var(--space-2-5); cursor: pointer; color: var(--color-text-tertiary); font-weight: var(--weight-medium); transition: all .18s; }
.fmt-toggle .seg.active { background: var(--gradient-primary); color: var(--color-on-primary); }
.fmt-toggle .seg:hover:not(.active) { background: var(--color-primary-tint-6); color: var(--color-primary); }
.fmt-toggle .ic { font-size: var(--font-size-sm); margin-right: var(--space-0-5); }
.fmt-hint { margin-left: var(--space-1-5); padding: var(--space-0-5) 0; max-width: 170px; font-size: var(--font-size-2xs); color: var(--color-text-tertiary); line-height: 1.4; }
.fmt-hint b { color: var(--color-primary); font-weight: var(--weight-medium); }

/* 任务卡查看产物按钮 */
.view-arts-btn {
  display: inline-flex; align-items: center; gap: var(--space-1);
  margin-top: var(--space-2-5); padding: var(--space-1-5) var(--space-3-5);
  background: var(--gradient-primary-soft); color: var(--color-primary);
  border: 1px solid var(--color-primary-border); border-radius: var(--radius-md);
  font-size: var(--font-size-md); font-weight: var(--weight-semibold);
  cursor: pointer; transition: all .2s ease-out;
}
.view-arts-btn:hover { background: var(--gradient-primary); color: var(--color-on-primary); box-shadow: var(--shadow-primary); transform: translateY(-1px); }

/* 记忆清空按钮 */
.mem-clear-btn {
  padding: var(--space-1-5) var(--space-3); white-space: nowrap;
  font-size: var(--font-size-xs); font-weight: var(--weight-medium);
  background: transparent; color: var(--color-text-tertiary);
  border: 1px solid var(--color-border); border-radius: var(--radius-md); cursor: pointer; transition: all .18s;
}
.mem-clear-btn:hover { color: var(--color-danger); border-color: var(--color-danger-border-soft); background: var(--color-danger-tint-5); }

/* 空态能力卡网格 */
.cap-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2-5);
  margin: var(--space-5) auto 0; max-width: 520px;
}
.cap-card {
  position: relative; overflow: hidden; text-align: left; cursor: pointer;
  background: var(--color-bg-surface); border: 1px solid var(--color-border);
  border-radius: var(--radius-xl); padding: var(--space-3);
  transition: all .22s ease-out;
}
.cap-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); border-color: var(--color-primary-border); }
.cap-card::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 2px;
  background: var(--gradient-primary); opacity: 0; transition: opacity .2s;
}
.cap-card:hover::before { opacity: 1; }
.cap-card .cap-ic {
  width: 30px; height: 30px; margin-bottom: var(--space-1-5);
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--radius-md); font-size: var(--font-size-lg);
}
.cap-card[data-cap="query"] .cap-ic { background: var(--color-info-tint-10); color: var(--color-info); }
.cap-card[data-cap="report"] .cap-ic { background: var(--color-src-akshare-bg); color: var(--color-success); }
.cap-card[data-cap="briefing"] .cap-ic { background: var(--color-src-cache-bg); color: var(--color-warning); }
.cap-card[data-cap="minutes"] .cap-ic { background: var(--color-src-wind-bg); color: var(--color-purple); }
.cap-card .cap-t { font-size: var(--font-size-md); font-weight: var(--weight-semibold); margin-bottom: var(--space-0-5); color: var(--color-text-primary); }
.cap-card .cap-d { font-size: var(--font-size-2xs); color: var(--color-text-tertiary); line-height: 1.45; }
.cap-card .cap-ex {
  margin-top: var(--space-1-5); padding: var(--space-0-5) var(--space-1-5);
  background: var(--color-bg-page); border-radius: var(--radius-sm);
  font-family: var(--font-mono); font-size: var(--font-size-2xs); color: var(--color-primary);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* SVG 图标体系 */
.ui-ic {
  width: 15px; height: 15px; display: inline-block; vertical-align: -2px;
  stroke: currentColor; stroke-width: 1.8; fill: none;
  stroke-linecap: round; stroke-linejoin: round;
}
.ui-ic.sm { width: 13px; height: 13px; }
.ui-ic.lg { width: 18px; height: 18px; }

/* 导出防呆 */
button#exportcard.is-disabled { opacity: .45; filter: grayscale(1); cursor: not-allowed; }

/* 遮罩弹窗 */
.md-modal-mask {
  position: fixed; inset: 0; z-index: var(--z-modal-mask);
  display: none; align-items: center; justify-content: center; padding: var(--space-6);
  background: var(--color-scrim);
}
.md-modal-mask.show { display: flex; }
.md-modal {
  display: flex; flex-direction: column; overflow: hidden;
  width: 100%; max-width: 820px; max-height: 86vh;
  background: var(--color-bg-page); border: 1px solid var(--color-border); border-radius: var(--radius-lg);
}
.md-modal header {
  display: flex; justify-content: space-between; align-items: center;
  height: auto; padding: var(--space-3) var(--space-4-5);
  border-bottom: 1px solid var(--color-border); background: var(--color-bg-surface); backdrop-filter: none;
}
.md-modal header h3 { margin: 0; font-family: var(--font-sans); font-size: var(--font-size-lg); letter-spacing: .02em; }
.md-modal header .close {
  cursor: pointer; font-family: var(--font-mono); font-size: var(--font-size-md);
  color: var(--color-text-tertiary); border: 1px solid var(--color-border);
  border-radius: var(--radius-xs); padding: var(--space-0-5) var(--space-2-5);
}
.md-modal .md-body {
  overflow: auto; padding: var(--space-4) var(--space-5);
  font-family: var(--font-serif); font-size: var(--font-size-base); line-height: var(--line-relaxed);
  white-space: pre-wrap; word-break: break-word;
}
.md-modal .md-body.loading { color: var(--color-text-tertiary); font-style: italic; }

/* ===================== index · 响应式（断点保持原状，不做单栏改造 Task 40）===================== */
@media (max-width: 1120px) {
  aside.left {
    /* Task 38：顶边让出脱敏横幅高度（横幅插入后顶栏整体下移 --layout-strip-h） */
    position: fixed; left: 0; top: calc(var(--layout-header-h) + var(--layout-strip-h)); bottom: 0; z-index: var(--z-sidebar);
    transform: translateX(-100%); transition: transform .3s ease; box-shadow: var(--shadow-xl);
  }
  aside.left.open { transform: translateX(0); }
  .left-toggle { display: inline-flex; }
}
/* Task 51 F1 · 右栏改为移动端抽屉（照左栏模式；≤900px 才生效） */
@media (max-width: 900px) {
  aside.right {
    position: fixed; right: 0; top: calc(var(--layout-header-h) + var(--layout-strip-h)); bottom: 0;
    width: min(92vw, 380px);
    transform: translateX(102%); transition: transform .3s ease; box-shadow: var(--shadow-xl);
    display: flex;
  }
  aside.right.open { transform: translateX(0); }
  .right-close { display: inline-flex; }
  .right-fab { display: inline-flex; }
}

/* ===================== audit · 编辑文档骨架 ===================== */
.wrap { max-width: 960px; margin: 0 auto; padding: var(--space-10) var(--space-5) var(--space-14); }
.site-header { position: relative; padding-bottom: var(--space-5-5); margin-bottom: var(--space-2); border-bottom: 1px solid var(--color-border); }
.site-header .nav { position: absolute; top: var(--space-1); right: 0; }
.site-header .nav a {
  font-family: var(--font-mono); font-size: var(--font-size-xs); letter-spacing: .12em;
  text-transform: uppercase; color: var(--color-primary); text-decoration: none;
  border-bottom: 1px solid transparent; padding-bottom: var(--space-0-5); transition: border-color .2s ease-out;
}
.site-header .nav a:hover { border-bottom-color: var(--color-primary); }
.eyebrow {
  margin: 0 0 var(--space-2-5); font-family: var(--font-mono); font-size: var(--font-size-sm);
  font-weight: var(--weight-medium); letter-spacing: .15em; text-transform: uppercase; color: var(--color-primary);
}
.site-header h1 {
  margin: 0 0 var(--space-2); font-family: var(--font-serif); font-weight: var(--weight-bold);
  font-size: clamp(var(--font-size-5xl), 6vw, var(--font-size-6xl));
  line-height: 1.12; letter-spacing: -.01em;
}
.site-header .sub { margin: 0; max-width: 46rem; color: var(--color-text-tertiary); font-size: var(--font-size-lg); line-height: 1.6; }
.readonly {
  display: inline-block; margin-left: var(--space-2-5); vertical-align: middle;
  padding: var(--space-0-5) var(--space-2-5); border-radius: var(--radius-pill);
  background: var(--color-bg-subtle); color: var(--color-text-tertiary);
  font-family: var(--font-mono); font-size: var(--font-size-2xs); font-weight: var(--weight-medium);
  letter-spacing: .1em; text-transform: uppercase;
}
.section-label {
  display: flex; align-items: center; gap: var(--space-3-5); margin: 0 0 var(--space-1);
  font-family: var(--font-mono); font-size: var(--font-size-xs); font-weight: var(--weight-medium);
  letter-spacing: .15em; text-transform: uppercase; color: var(--color-primary);
}
.section-label::before, .section-label::after { content: ""; height: 1px; background: var(--color-border); flex: 1 1 auto; }
.section-label span { flex: 0 0 auto; }
.site-footer {
  margin-top: var(--space-9); padding-top: var(--space-4-5); border-top: 1px solid var(--color-border);
  text-align: center; color: var(--color-text-tertiary);
  font-family: var(--font-mono); font-size: var(--font-size-xs); letter-spacing: .06em;
}
.wrap .tabs { margin-top: var(--space-5-5); }

/* audit 统计条 */
.stats-bar { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-3-5); margin-top: var(--space-5-5); }
.stats-bar .stat {
  position: relative; overflow: hidden;
  background: var(--color-bg-surface); border: 1px solid var(--color-border); border-radius: var(--radius-md);
  padding: var(--space-3-5) var(--space-4); box-shadow: var(--shadow-sm);
}
.stats-bar .stat::before { content: ""; position: absolute; inset: 0 0 auto 0; height: 2px; background: var(--color-primary); opacity: .6; }
.stats-bar .stat .k {
  font-family: var(--font-mono); font-size: var(--font-size-2xs); font-weight: var(--weight-medium);
  letter-spacing: .12em; text-transform: uppercase; color: var(--color-text-tertiary);
}
.stats-bar .stat .v {
  margin-top: var(--space-1); font-family: var(--font-serif); font-weight: var(--weight-bold);
  font-size: var(--font-size-4xl); line-height: 1.2; font-variant-numeric: tabular-nums;
}
.stats-bar .stat .v small { font-family: var(--font-sans); font-size: var(--font-size-lg); font-weight: var(--weight-semibold); color: var(--color-text-tertiary); }

/* audit 工具条 */
.toolbar { display: flex; gap: var(--space-3); flex-wrap: wrap; align-items: center; }
.toolbar select { min-width: 160px; }
.toolbar .spacer { flex: 1 1 auto; }
.count { color: var(--color-text-tertiary); font-family: var(--font-mono); font-size: var(--font-size-xs); letter-spacing: .08em; }
.exportmsg { margin-top: var(--space-3); font-size: var(--font-size-md); color: var(--color-text-tertiary); }
.exportmsg.ok { color: var(--color-success-text); }

/* audit 事件类型徽标（页面专属分类法，色值收口到 token） */
.badge { padding: var(--space-0-5) var(--space-2-5); font-weight: var(--weight-medium); }
.b-request_received, .b-response_sent, .b-task_created { background: var(--color-info-bg); color: var(--color-info-text); }
.b-intent_parsed { background: var(--color-info-bg-indigo); color: var(--color-info-text); }
.b-permission_checked, .b-task_suspended, .b-approval_requested { background: var(--color-amber-bg); color: var(--color-amber-text); }
.b-route_decided, .b-task_plan_generated, .b-task_completed { background: var(--color-success-bg-soft); color: var(--color-success-text); }
.b-retrieval_hits, .b-task_resumed, .b-approval_decided { background: var(--color-purple-bg); color: var(--color-purple); }
.b-output_generated, .b-task_step_finished { background: var(--color-cyan-bg); color: var(--color-cyan-text); }
.b-output_whitelist_checked { background: var(--color-amber-deep-bg); color: var(--color-amber-deep); }
.b-file_written, .b-task_step_started, .b-default { background: var(--color-slate-bg); color: var(--color-slate-text); }
.r-success, .r-allowed, .r-received, .r-ok, .r-done, .r-approved { color: var(--color-success-text); }
.r-denied, .r-blocked, .r-error, .r-failed, .r-rejected { color: var(--color-danger-strong); font-weight: var(--weight-semibold); }
.r-unavailable, .r-degraded, .r-waiting_approval, .r-running, .r-planning { color: var(--color-amber-text); }
.wrap pre {
  margin: 0; font-family: var(--font-mono); font-size: var(--font-size-md);
  color: var(--color-text-secondary); white-space: pre-wrap; word-break: break-word;
}

/* audit 事件流 */
.log { margin-top: var(--space-2); }
.log-head {
  display: grid; grid-template-columns: 68px 150px 1fr 96px 108px; gap: var(--space-3);
  padding: var(--space-2-5) var(--space-3); border-bottom: 1px solid var(--color-text-primary);
  font-family: var(--font-mono); font-size: var(--font-size-2xs); font-weight: var(--weight-medium);
  letter-spacing: .12em; text-transform: uppercase; color: var(--color-text-tertiary);
}
.evt {
  display: grid; grid-template-columns: 68px 150px 1fr 96px 108px; gap: var(--space-3);
  padding: var(--space-3); border-bottom: 1px solid var(--color-border);
  cursor: pointer; align-items: baseline; transition: background .15s ease-out;
}
.evt:hover { background: var(--color-bg-inset); }
.evt .k { display: none; }
.evt .id { font-family: var(--font-mono); color: var(--color-text-tertiary); font-variant-numeric: tabular-nums; font-size: var(--font-size-md); }
.evt .ts { font-family: var(--font-mono); color: var(--color-text-tertiary); font-size: var(--font-size-sm); white-space: nowrap; }
.evt .etype { min-width: 0; }
.params { display: none; padding: var(--space-1) var(--space-3) var(--space-4); background: var(--color-bg-inset); border-bottom: 1px solid var(--color-border); }
.params.show { display: block; }

/* audit 任务卡 */
.task-list { margin-top: var(--space-2); }
.wrap .card {
  position: relative; overflow: hidden; margin-top: var(--space-5-5);
  padding: var(--space-6-5);
}
.wrap .card::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 2px;
  background: var(--gradient-primary); opacity: .85;
}
.task-card {
  margin-top: var(--space-3); padding: var(--space-3-5) var(--space-4);
  background: var(--color-bg-surface); border: 1px solid var(--color-border); border-left: 3px solid var(--color-text-tertiary);
  border-radius: var(--radius-md); box-shadow: var(--shadow-sm); cursor: pointer;
  transition: box-shadow .15s ease-out, border-color .15s ease-out;
}
.task-card:hover { box-shadow: var(--shadow-md); border-color: var(--color-primary-400); }
.task-card.s-done { border-left-color: var(--color-success-text); }
.task-card.s-failed { border-left-color: var(--color-danger-strong); }
.task-card.s-wait { border-left-color: var(--color-amber); }
.task-card.s-run { border-left-color: var(--color-info-text); }
.tc-head { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }
.tc-id { font-family: var(--font-mono); font-weight: var(--weight-medium); color: var(--color-text-tertiary); font-size: var(--font-size-md); }
.tc-status {
  display: inline-block; padding: var(--space-0-5) var(--space-2-5); border-radius: var(--radius-pill);
  font-family: var(--font-mono); font-size: var(--font-size-xs); font-weight: var(--weight-semibold); letter-spacing: .04em;
}
.tc-status.s-done { background: var(--color-success-bg-soft); color: var(--color-success-text); }
.tc-status.s-failed { background: var(--color-danger-bg-soft); color: var(--color-danger-strong); }
.tc-status.s-wait { background: var(--color-amber-bg); color: var(--color-amber-text); }
.tc-status.s-run { background: var(--color-info-bg); color: var(--color-info-text); }
.tc-user { font-family: var(--font-mono); font-size: var(--font-size-sm); color: var(--color-text-tertiary); }
.tc-time { margin-left: auto; font-family: var(--font-mono); font-size: var(--font-size-2xs); color: var(--color-text-tertiary); white-space: nowrap; }
.tc-req { margin-top: var(--space-2); color: var(--color-text-primary); font-size: var(--font-size-lg); line-height: 1.55; }
.tc-meta { display: flex; gap: var(--space-4-5); margin-top: var(--space-2); font-family: var(--font-mono); font-size: var(--font-size-2xs); color: var(--color-text-tertiary); letter-spacing: .04em; }
.tc-fail { margin-top: var(--space-2); font-size: var(--font-size-md); color: var(--color-danger-strong); line-height: 1.5; }
.tc-hint { margin-top: var(--space-2); font-family: var(--font-mono); font-size: var(--font-size-2xs); letter-spacing: .12em; text-transform: uppercase; color: var(--color-text-tertiary); }

/* 行为链时间线 */
.chain { margin-top: var(--space-0-5); }
.chain[hidden] { display: none; }
.timeline { border: 1px solid var(--color-border); border-radius: var(--radius-md); background: var(--color-bg-inset); overflow: hidden; }
.chain-item {
  display: grid; grid-template-columns: 130px 1fr; gap: var(--space-3-5);
  padding: var(--space-3) var(--space-3-5); border-bottom: 1px solid var(--color-border); align-items: baseline;
}
.chain-item:last-child { border-bottom: none; }
.chain-item.key { background: var(--color-bg-key); }
.ci-time { font-family: var(--font-mono); font-size: var(--font-size-2xs); color: var(--color-text-tertiary); white-space: nowrap; }
.ci-body { min-width: 0; }
.ci-body .badge { margin-right: var(--space-2); }
.ci-result { font-family: var(--font-mono); font-size: var(--font-size-2xs); margin-right: var(--space-2); }
.ci-dur { font-family: var(--font-mono); font-size: var(--font-size-2xs); color: var(--color-text-tertiary); }
.ci-body pre { margin-top: var(--space-1-5); background: var(--color-bg-surface); border: 1px solid var(--color-border); border-radius: var(--radius-sm); padding: var(--space-2) var(--space-2-5); }

/* audit 窄屏卡片化（保持原 620 断点） */
@media (max-width: 620px) {
  .site-header .nav { position: static; display: block; margin-bottom: var(--space-3-5); }
  .wrap .tabs .tab { padding: var(--space-2-5) var(--space-3-5); font-size: var(--font-size-xs); }
  .stats-bar { grid-template-columns: repeat(2, 1fr); }
  .toolbar select { min-width: 46%; flex: 1 1 46%; }
  .log-head { display: none; }
  .evt {
    display: block; margin-top: var(--space-3); padding: var(--space-3-5) var(--space-4);
    background: var(--color-bg-surface); border: 1px solid var(--color-border); border-left: 3px solid var(--color-primary);
    border-radius: var(--radius-md); box-shadow: var(--shadow-sm);
  }
  .evt:hover { background: var(--color-bg-surface); }
  .evt > div { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-3); padding: var(--space-0-5) 0; }
  .evt .k {
    display: inline-block; flex: 0 0 auto;
    font-family: var(--font-mono); font-size: var(--font-size-3xs); font-weight: var(--weight-medium);
    letter-spacing: .12em; text-transform: uppercase; color: var(--color-text-tertiary);
  }
  .evt .v { text-align: right; word-break: break-word; }
  .evt .ts { white-space: normal; }
  .params { margin-top: var(--space-0-5); border: 1px solid var(--color-border); border-radius: var(--radius-md); background: var(--color-bg-inset); }
  .tc-time { margin-left: 0; flex-basis: 100%; }
  .chain-item { grid-template-columns: 1fr; gap: var(--space-1-5); }
  .ci-time { white-space: normal; }
}

/* ===================== Task 38：全站脱敏横幅（两页常显，≤40px 不换行）===================== */
/* 复用 components.css 的 .banner--demo 外观，本类只负责布局：sticky 常贴顶、单行省略、
   在 index 弹性骨架里不被压缩。文字短，390px 宽单行不溢出。 */
.env-strip {
  position: sticky; top: 0; z-index: var(--z-header);
  flex-shrink: 0; height: var(--layout-strip-h);
  padding: 0 var(--space-4); box-sizing: border-box;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* Task 54 · 手机端适配提示条（≤900px 才显示；桌面/宽屏默认隐藏，不影响布局）
   复用 .banner--demo / .env-strip 配色与高度变量，不新造未定义变量。
   它使顶栏再下移一行 → 固定抽屉顶边同步补偿（见文件末尾 ≤900px 块）。 */
.env-strip--mobile-hint { display: none; }
@media (max-width: 900px) {
  .env-strip--mobile-hint {
    display: flex;                  /* 覆写 .env-strip 的默认隐藏；用 flex 保持 .banner--demo 的居中+圆点外观 */
    top: var(--layout-strip-h);     /* 两条 sticky 条叠放：第二条贴第一条之下 */
  }
  /* 顶栏现下移两行（脱敏横幅 + 手机端提示）→ 两个抽屉顶边各再补 --layout-strip-h */
  aside.left, aside.right {
    top: calc(var(--layout-header-h) + var(--layout-strip-h) + var(--layout-strip-h));
  }
}

/* ===================== Task 38：首屏定位句 + 30 秒一键演示引导 ===================== */
.empty-state .hero { margin-bottom: var(--space-4); }
.hero-eyebrow {
  margin-bottom: var(--space-1-5);
  font-family: var(--font-mono); font-size: var(--font-size-xs); font-weight: var(--weight-medium);
  letter-spacing: .18em; text-transform: uppercase; color: var(--color-primary);
}
.hero-line {
  font-size: var(--font-size-xl); font-weight: var(--weight-semibold);
  line-height: var(--line-snug); letter-spacing: .01em; color: var(--color-text-primary);
}
.hero-line b { color: var(--color-primary); font-weight: var(--weight-semibold); }
.empty-state .empty-sub {
  display: block; font-size: var(--font-size-md); line-height: var(--line-snug);
  color: var(--color-text-tertiary);
}

/* Task 39 返工 · W-4：components.css 给 .empty-state 限宽 480px，三步并排时每列文本
   区仅几十像素，中文逐字断行成单字竖排。引导卡须占满中栏——此处解除父级限宽
   （定位句继承居中；能力卡网格自带 max-width:520px 居中，均不会被拉伸）。 */
.empty-state { max-width: none; }

/* 引导条容器：只在空态 DOM 内出现，随空态移除，不使用遮罩/弹窗 */
.onboard {
  width: 100%; max-width: none; margin: 0 auto var(--space-6);
  padding: var(--space-8) var(--space-6) var(--space-6);
  background: var(--color-primary-tint-2);
  border: 1px solid var(--color-primary-border-soft);
  border-radius: var(--radius-2xl);
}
.onboard-hd {
  display: flex; align-items: center; justify-content: center; flex-wrap: wrap;
  gap: var(--space-2) var(--space-3); margin-bottom: var(--space-7);
  font-family: var(--font-mono); font-size: var(--font-size-xl); font-weight: var(--weight-semibold);
  letter-spacing: .12em; color: var(--color-primary-active);
}
.onboard-hd-sub {
  font-family: var(--font-sans); font-weight: var(--weight-regular); letter-spacing: 0;
  font-size: var(--font-size-sm); color: var(--color-text-tertiary);
}
.onboard-live {
  width: var(--space-2-5); height: var(--space-2-5); flex: none;
  border-radius: var(--radius-pill); background: var(--color-success);
  animation: pulse 2s infinite;
}
/* Task 42：引导卡由 3 拍扩到 6 拍——改两行网格（3 列 × 2 行），窄屏降列不溢出 */
.onboard-steps { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-3); }
.ob-step {
  appearance: none; flex: 1 1 0; min-width: 0; cursor: pointer;
  display: flex; align-items: center; gap: var(--space-3);
  text-align: left; background: var(--color-bg-surface);
  border: 1px solid var(--color-border); border-left: 3px solid var(--color-primary);
  border-radius: var(--radius-xl); padding: var(--space-7) var(--space-5);
  min-height: var(--space-14);
  font-family: var(--font-sans);
  transition: transform .2s ease-out, box-shadow .2s ease-out, border-color .2s ease-out;
}
.ob-step:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); border-color: var(--color-primary-border); }
.ob-step:active { transform: scale(.985); }
.ob-step .ob-n {
  flex: none; width: var(--space-8); height: var(--space-8);
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--radius-pill); font-family: var(--font-mono);
  font-size: var(--font-size-lg); font-weight: var(--weight-semibold);
  background: var(--color-primary-tint-8); color: var(--color-primary);
}
.ob-step .ob-body { display: flex; flex-direction: column; min-width: 0; gap: var(--space-1); }
.ob-step .ob-t { font-size: var(--font-size-xl); font-weight: var(--weight-semibold); line-height: 1.2; color: var(--color-text-primary); }
.ob-step .ob-d {
  font-size: var(--font-size-md); line-height: 1.5; color: var(--color-text-tertiary);
  /* Task 39 返工 · W-4：允许正常换行，窄列时多行横排仍可读，杜绝单字竖排/裁切 */
  overflow-wrap: break-word;
}
.ob-step .ob-go {
  margin-left: auto; flex: none; font-size: var(--font-size-lg); color: var(--color-text-tertiary);
  transition: color .2s ease-out;
}
.ob-step:hover .ob-go { color: var(--color-primary); }
/* 第 2 步：危险色强调（最强卖点：越权当场被拦）；第 3 步：成功色（异步产出） */
.ob-step--danger { border-left-color: var(--color-danger); }
.ob-step--danger .ob-n { background: var(--color-danger-bg-soft); color: var(--color-danger-strong); }
.ob-step--danger:hover { border-color: var(--color-danger-border); box-shadow: var(--shadow-danger-sm); }
.ob-step--danger:hover .ob-go { color: var(--color-danger); }
.ob-step--ok { border-left-color: var(--color-success); }
.ob-step--ok .ob-n { background: var(--color-success-bg-soft); color: var(--color-success-text); }
.ob-step--ok:hover { border-color: var(--color-success-border); }
.ob-step--ok:hover .ob-go { color: var(--color-success); }
/* Task 42 新增两拍：④ 试无权数据（琥珀："被拦"的那一下）· ⑤ 换合规视角（蓝：切视角） */
.ob-step--warn { border-left-color: var(--color-warning); }
.ob-step--warn .ob-n { background: var(--color-warning-bg-soft); color: var(--color-warning-text); }
.ob-step--warn:hover { border-color: var(--color-warning-border); }
.ob-step--warn:hover .ob-go { color: var(--color-warning); }
.ob-step--info { border-left-color: var(--color-info); }
.ob-step--info .ob-n { background: var(--color-info-bg); color: var(--color-info-text); }
.ob-step--info:hover { border-color: var(--color-primary-border); }
.ob-step--info:hover .ob-go { color: var(--color-info); }
/* 第二行（闭环三拍）与第一行之间的一行小字（承接语气，非新信息块） */
.onboard-bridge {
  margin: var(--space-5) 0 var(--space-3); text-align: center;
  font-size: var(--font-size-sm); color: var(--color-text-tertiary);
}
.onboard-bridge b { color: var(--color-text-secondary); font-weight: var(--weight-semibold); }
.onboard-steps--loop .ob-step { padding: var(--space-5) var(--space-5); }
.onboard-ft { margin-top: var(--space-5); text-align: center; font-size: var(--font-size-sm); color: var(--color-text-tertiary); }

/* 续演条：引导消息出结果后出现在对话流末尾（盲测修订：防止访客卡在"找新建会话"） */
.guide-next {
  max-width: 560px; margin: var(--space-3) auto 0;
  padding: var(--space-3) var(--space-4);
  background: var(--color-primary-tint-2);
  border: 1px dashed var(--color-primary-border);
  border-radius: var(--radius-2xl);
}
.guide-next .gn-label {
  margin-bottom: var(--space-2-5); text-align: center;
  font-size: var(--font-size-sm); color: var(--color-text-secondary);
}
.guide-next .ob-step { flex: none; width: 100%; box-sizing: border-box; background: var(--color-bg-surface); }
.guide-next .gn-end {
  text-align: center; font-size: var(--font-size-sm); line-height: var(--line-relaxed);
  color: var(--color-success-text);
}
/* Task 42：闭环三拍的续演条附加行（等待 / 已授权 / 说明 / 终点两个出口） */
.guide-next .gn-wait {
  margin-bottom: var(--space-2); text-align: center;
  font-size: var(--font-size-md); font-weight: var(--weight-semibold); color: var(--color-warning-text);
}
.guide-next .gn-grant {
  margin-bottom: var(--space-2); text-align: center;
  font-size: var(--font-size-sm); font-weight: var(--weight-semibold); color: var(--color-success-text);
}
.guide-next .gn-note {
  margin-bottom: var(--space-2-5); text-align: center;
  font-size: var(--font-size-sm); line-height: var(--line-relaxed); color: var(--color-text-tertiary);
}
.guide-next .gn-exits {
  display: flex; flex-wrap: wrap; gap: var(--space-2-5);
  justify-content: center; margin-top: var(--space-3);
}
/* 引导高亮：把"该点的那个真按钮"（提交审批 / 批准）圈出来，点它才走真实链路 */
.guide-pulse {
  outline: 2px solid var(--color-primary); outline-offset: 2px;
  animation: guidePulse 1.6s ease-out infinite;
}
@keyframes guidePulse {
  0%, 100% { box-shadow: 0 0 0 0 var(--color-primary-border-strong); }
  50%      { box-shadow: 0 0 0 8px var(--color-primary-border-soft); }
}

/* 查询被拒卡上的审计留痕入口（Task 38 · G-3） */
.audit-trace-row {
  display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-2) var(--space-3);
  margin: var(--space-2) 0 var(--space-2-5);
}
.audit-trace-link {
  display: inline-flex; align-items: center; gap: var(--space-1-5);
  padding: var(--space-1-5) var(--space-3-5);
  font-size: var(--font-size-md); font-weight: var(--weight-semibold);
  text-decoration: none; color: var(--color-danger-strong);
  background: var(--color-danger-bg); border: 1px solid var(--color-danger-border);
  border-radius: var(--radius-pill);
  transition: transform .2s ease-out, box-shadow .2s ease-out, background .2s ease-out, color .2s ease-out;
}
.audit-trace-link:hover {
  background: var(--color-danger); color: var(--color-on-primary);
  box-shadow: var(--shadow-danger-sm); transform: translateY(-1px);
}
.audit-trace-link .ui-ic { width: 14px; height: 14px; }
.audit-trace-note { font-size: var(--font-size-sm); color: var(--color-text-tertiary); }

/* 审计页：携 ?user= 跳入时的操作人筛选条（Task 38 · G-3，纯前端过滤） */
.user-filter-bar {
  display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-2) var(--space-3);
  margin: var(--space-3) 0 var(--space-2-5); padding: var(--space-2-5) var(--space-4);
  background: var(--color-primary-tint-5); border: 1px solid var(--color-primary-border-soft);
  border-radius: var(--radius-lg);
}
.user-filter-bar[hidden] { display: none; }
.user-filter-bar.is-unresolved { background: var(--color-bg-subtle); border-color: var(--color-border); }
.ufb-chip {
  display: inline-flex; align-items: center; gap: var(--space-1-5);
  font-size: var(--font-size-md); font-weight: var(--weight-semibold); color: var(--color-primary-active);
}
.ufb-chip .ui-ic { width: 14px; height: 14px; color: var(--color-primary); }
.user-filter-bar.is-unresolved .ufb-chip { color: var(--color-text-secondary); }
.user-filter-bar.is-unresolved .ufb-chip .ui-ic { color: var(--color-text-tertiary); }
.ufb-note { font-size: var(--font-size-sm); color: var(--color-text-tertiary); }
#ufbClear { margin-left: auto; }
.task-card.is-hl { border-color: var(--color-primary); box-shadow: var(--shadow-primary); }
.chain.is-hl .timeline { border-color: var(--color-primary-border); }

/* 窄屏：引导卡降列防溢出（仅引导元素自保；整页单栏改造在 Task 40）
   断点按"中栏内容宽"定：3 列需 ≥~200px/列，低于则降 2 列、再降 1 列（不靠猜） */
@media (max-width: 1300px) {
  .onboard-steps { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 620px) {
  .ob-step .ob-d { white-space: normal; }
}
@media (max-width: 600px) {
  .onboard-steps { grid-template-columns: minmax(0, 1fr); }
  .onboard .ob-step { padding: var(--space-4) var(--space-5); }
}

/* 动效降级（显式列举动画元素，不用 !important） */
@media (prefers-reduced-motion: reduce) {
  .stream > .card, .skeleton, .shimmer, .alert.show, .banner.show,
  .tab-badge, .risk .pulse-dot, .l-sec h4 .dot, .r-sec h4 .dot, .onboard-live,
  .guide-pulse { animation: none; }
  .btn, .hist-item, .stat, .cap-card, .view-arts-btn,
  .ob-step, .audit-trace-link { transition: none; transform: none; }
}

/* ===================== Task 41 · 首屏收敛（空态＝演示态）=====================
   收敛态 = .is-pristine（首次进入 · 尚无会话 · 未发起操作）：
     右栏统计区收起 → 只留一行灰字；左栏会话列表折叠为一行提示（跟踪池保留）。
   实现原则：**只降权，不删 DOM** —— 全部走 display/尺寸，元素与选择器原封不动，
   既有脚本（stats 绑定、筛选联动）与 shots.py 的点击序列都不受影响。
   类名由 app/static/js/pristine.js 维护；静态挂在 <body> 上避免首帧闪一下。
   ========================================================================== */

/* 收敛提示：默认不占位，仅空态可见（右栏统计区的替代物） */
.pristine-hint {
  display: none;
  padding: var(--space-1) 0 var(--space-2);
  font-size: var(--font-size-sm);
  line-height: var(--line-relaxed);
  color: var(--color-text-tertiary);
}
body.is-pristine .stats { display: none; }          /* 6 个为 0 的统计卡先退场 */
body.is-pristine .pristine-hint { display: block; }
body.is-pristine #topchip { display: none; }        /* 顶栏同样是 0/—/0，一并退场 */

/* 左栏：空会话列表折叠为一行（跟踪池有信息量，不动它） */
body.is-pristine .l-sec:first-child h4 .tag { display: none; }
body.is-pristine #sessionList .sec-note {
  padding: 0;
  font-size: var(--font-size-sm);
  line-height: var(--line-snug);
}

/* ===================== Task 41 · S-5：顶栏窄屏溢出修复 =====================
   实测（390~748px）：顶栏内容最小宽 ~751px，390px 视口溢出 357px。
   手法＝按信息优先级逐级降级，不是隐藏功能：先摘 logo 小字，再收起 stats chip，
   最后压缩身份选择与按钮的字号/内距。所有窄屏必需控件（☰历史/身份/审计/引导）全保留。 */

@media (max-width: 760px) {
  .app-header { gap: var(--space-2-5); padding: 0 var(--space-3); }
  .app-header .logo small { display: none; }        /* 副标题：最不值钱的一行 */
  select.role { max-width: 8em; }
  .app-header .btn { font-size: var(--font-size-xs); padding: var(--space-1-5) var(--space-2-5); }
}

/* ≤660px：中栏已单栏、右栏本就被 900 断点收起，顶栏 stats chip 降级为隐藏
   （概况 Tab 同数据；空态下它本来就全是 0，见上一条 body.is-pristine 规则） */
@media (max-width: 660px) {
  #topchip { display: none; }
  .app-header { gap: var(--space-2); padding: 0 var(--space-2-5); }
  select.role { max-width: 7em; }
}

@media (max-width: 430px) {
  .app-header { gap: var(--space-1-5); padding: 0 var(--space-2); }
  select.role { max-width: 6.5em; padding: var(--space-1-5) var(--space-2); font-size: var(--font-size-sm); }
  .app-header .btn { padding: var(--space-1-5) var(--space-2); }
}

/* 窄屏：能力卡示例行改为换行（默认 nowrap+ellipsis 是为桌面单行准备的，
   390px 下 122px 宽的示例框会把“查华兴 & 东岳产能利用率”裁成省略号）。 */
@media (max-width: 480px) {
  .cap-card .cap-ex { white-space: normal; overflow: visible; }
}
