* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; font-family: -apple-system, "PingFang SC", "Helvetica Neue", "Microsoft YaHei", sans-serif; font-size: 13px; color: #111827; background: #f5f5f7; }
/* case 页布局: body 固定 viewport 高 + overflow hidden, 唯一的滚动容器是 .scroll-area; 页头 / declarations / source / legend / 表格全装在里面.
滚动时它们一起向上滚走, 只有 thead 因 position: sticky 留在顶 — 这是用户要求的"只冻结表头两行". */
body { height: 100vh; overflow: hidden; }
header.page-header { padding: 14px 20px 8px; background: #fff; border-bottom: 1px solid #e5e7eb; }
header.page-header h1 { margin: 0 0 6px; font-size: 16px; font-weight: 600; }
header.page-header .meta { color: #6b7280; font-size: 12px; line-height: 1.5; }
/* 工序头部 + declare 块 */
details.declarations { margin: 12px 20px 0; background: #fff; border: 1px solid #e2e8f0; border-radius: 6px; }
details.declarations[open] summary { border-bottom: 1px solid #e2e8f0; }
details.declarations summary { padding: 10px 14px; cursor: pointer; font-size: 13px; line-height: 1.65; list-style: none; }
details.declarations summary::-webkit-details-marker { display: none; }
details.declarations summary::before { content: '▼ '; color: #94a3b8; font-size: 10px; margin-right: 4px; }
details.declarations:not([open]) summary::before { content: '▶ '; }
details.declarations .proc-name { color: #1f2937; font-size: 14px; }
details.declarations .decl-purpose { color: #475569; margin-left: 12px; font-size: 12px; }
details.declarations .decl-meta { color: #6b7280; font-size: 11.5px; margin-left: 16px; }
details.declarations .tag-mini { display: inline-block; padding: 1px 7px; font-size: 11px; background: #fef3c7; border-radius: 3px; color: #92400e; margin-left: 8px; }
.decl-body { padding: 12px 18px 14px; display: flex; flex-wrap: wrap; gap: 14px 32px; }
.decl-section { min-width: 260px; flex: 1 1 280px; }
.decl-label { color: #475569; font-size: 11.5px; font-weight: 600; margin-bottom: 6px; padding-bottom: 4px; border-bottom: 1px dashed #e2e8f0; }
.decl-row { padding: 3px 0; font-size: 12.5px; line-height: 1.65; }
.decl-row .name { font-weight: 500; color: #1f2937; margin-left: 4px; }
.decl-row .decl-default { color: #6b7280; font-size: 11.5px; margin-left: 6px; }
.decl-row .decl-desc { color: #6b7280; font-size: 11.5px; margin-left: 6px; }
/* 原文 */
details.source-block { margin: 8px 20px 12px; background: #fff; border: 1px solid #e2e8f0; border-radius: 6px; }
details.source-block summary { padding: 8px 14px; cursor: pointer; font-size: 12px; color: #475569; list-style: none; }
details.source-block summary::-webkit-details-marker { display: none; }
details.source-block summary::before { content: '▶ '; color: #94a3b8; font-size: 10px; margin-right: 4px; }
details.source-block[open] summary::before { content: '▼ '; }
.source-body { padding: 6px 18px 12px; font-size: 12.5px; line-height: 1.65; }
.source-body a { color: #2563eb; word-break: break-all; }
.source-body .source-meta { color: #94a3b8; font-size: 11px; margin-top: 4px; }
.source-body .source-excerpt { color: #1f2937; margin: 8px 0; padding: 8px 10px; background: #f8fafc; border-left: 3px solid #94a3b8; font-size: 12px; }
.source-body hr.src-divider { border: 0; border-top: 1px dashed #cbd5e1; margin: 10px 0; }
.source-body .src-p { margin: 6px 0; color: #1f2937; }
.source-body .src-img-wrap, .source-body .src-cover { text-align: center; margin: 8px 0; }
.source-body .src-img { max-width: 100%; max-height: 480px; border-radius: 4px; border: 1px solid #e2e8f0; }
.source-body .src-video { margin: 8px 0; }
.source-body .src-video a { display: inline-block; padding: 4px 10px; background: #fef3c7; color: #78350f; text-decoration: none; border-radius: 3px; font-size: 11.5px; }
.source-body .source-full { max-height: 720px; overflow-y: auto; padding: 6px 12px; background: #fff; border: 1px solid #e2e8f0; border-radius: 4px; }
/* Legend */
.legend { padding: 10px 20px; background: #fff; border-bottom: 1px solid #e5e7eb; font-size: 11.5px; color: #6b7280; display: flex; flex-wrap: wrap; gap: 6px 12px; align-items: center; }
.legend .group { display: inline-flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.legend .group .gh { display: inline-block; padding: 2px 8px; border-radius: 3px; color: #1f2937; font-weight: 600; cursor: pointer; user-select: none; }
.legend .group .gh:hover { filter: brightness(0.92); }
.legend .group .gh.all-off { opacity: 0.45; text-decoration: line-through; }
.legend .group.gray .gh { background: #e2e8f0; }
.legend .group.yellow .gh { background: #fde68a; }
.legend .group.green .gh { background: #bbf7d0; }
.legend .group.blue .gh { background: #bfdbfe; }
.legend .col-toggle { display: inline-block; padding: 2px 7px; border: 1px solid #cbd5e1; border-radius: 3px; background: #fff; cursor: pointer; font-size: 11.5px; color: #334155; user-select: none; }
.legend .col-toggle:hover { background: #f1f5f9; }
.legend .col-toggle.off { color: #94a3b8; background: #f1f5f9; text-decoration: line-through; border-color: #e2e8f0; }
.legend .inferred-toggle { display: inline-block; padding: 2px 8px; border: 1px solid #d97706; border-radius: 3px;
background: #fffbeb; color: #92400e; cursor: pointer; font-size: 11.5px;
font-weight: 600; user-select: none; margin-left: 8px; }
.legend .inferred-toggle.on { background: #fef3c7; box-shadow: inset 0 0 0 1px #d97706; }
.legend .legend-hint { color: #94a3b8; font-size: 11px; margin-left: auto; }
/* 表格容器 */
.table-wrap { background: #fff; }
/* case 页 .scroll-area: 占满 body, 自身承担两轴滚动. 内部不嵌套 overflow 容器, 否则 sticky 锚点会被抢走.
(browser 页不会走这条 — 它在 .browser-main 内, 不直接挂 body 下) */
body > .scroll-area { height: 100%; overflow: auto; background: #f5f5f7; }
table.proc { width: max-content; min-width: 100%; border-collapse: collapse; background: #fff; table-layout: auto; font-size: 12px; }
table.proc th, table.proc td { border: 1px solid #e5e7eb; padding: 6px 8px; vertical-align: top; line-height: 1.5; }
table.proc thead th { font-weight: 600; text-align: center; font-size: 12.5px; padding: 8px 6px; }
table.proc tbody td { font-size: 12px; }
/* 列宽 (需求 3 列固定 width, 其他 min-width) */
table.proc th.col-idx, table.proc td.idx { width: 38px; min-width: 38px; max-width: 38px; text-align: center; }
table.proc th.col-intent, table.proc td.intent { width: 240px; min-width: 240px; max-width: 240px; }
table.proc th.col-effect, table.proc td.effect { width: 80px; min-width: 80px; max-width: 80px; }
table.proc th.col-via { min-width: 110px; }
table.proc th.col-action { min-width: 130px; }
table.proc th.col-directive { min-width: 200px; }
table.proc th.col-config { min-width: 150px; }
table.proc th.col-decorator { min-width: 130px; }
table.proc th.col-memo { min-width: 220px; }
table.proc th.col-control { min-width: 80px; }
table.proc th.col-feature { min-width: 80px; }
/* 值列整段 <...> — 表示该值是对内容的描述, 不是内容本身. 整段 inline italic gray bg. */
.value-desc { display: inline; padding: 1px 4px; border-radius: 3px;
background: rgba(241, 245, 249, 0.7); color: #475569; font-style: italic; }
/* 值列不允许截断 */
table.proc td.in-value, table.proc td.out-value {
white-space: pre-wrap; word-break: break-word; overflow-wrap: anywhere;
max-width: 320px;
}
table.proc td.directive, table.proc td.config,
table.proc td.decorator, table.proc td.memo {
white-space: pre-wrap; word-break: break-word; overflow-wrap: anywhere;
max-width: 280px;
}
/* 实质/形式 列 — 内容是短路径, 收窄列宽强制换行 (避免空旷低信息密度) */
table.proc th.col-in-substance, table.proc td.in-substance,
table.proc th.col-out-substance, table.proc td.out-substance,
table.proc th.col-in-form, table.proc td.in-form,
table.proc th.col-out-form, table.proc td.out-form { width: 90px; min-width: 90px; max-width: 90px;
word-break: break-all; overflow-wrap: anywhere; }
table.proc th.col-in-type, table.proc th.col-out-type { min-width: 90px; }
table.proc th.col-in-name, table.proc th.col-out-name { min-width: 110px; }
table.proc th.col-in-value, table.proc th.col-out-value { min-width: 180px; }
table.proc th.col-in-anchor, table.proc th.col-out-anchor { min-width: 110px; }
/* 冻结 需求 组 (idx + 目的 + 作用) — left 累计 = 0 / 38 / 278 */
table.proc th.col-idx, table.proc td.idx { position: sticky; left: 0; z-index: 2; }
table.proc th.col-intent, table.proc td.intent { position: sticky; left: 38px; z-index: 2; }
table.proc th.col-effect, table.proc td.effect { position: sticky; left: 278px; z-index: 2; }
table.proc thead th.col-group-demand { position: sticky; left: 0; z-index: 3; }
table.proc thead th.col-idx, table.proc thead th.col-intent, table.proc thead th.col-effect { z-index: 3; }
table.proc td.effect, table.proc thead th.col-effect, table.proc thead th.col-group-demand {
box-shadow: 6px 0 8px -4px rgba(0,0,0,0.18);
}
/* 冻结 表头 — 滚动时组名/列名行 stick to top */
table.proc thead th { position: sticky; top: 0; z-index: 3; }
table.proc thead tr:nth-child(2) th { top: 33px; }
/* 4 个 corner cell (sticky-left + sticky-top 同时生效) z-index 加高, 避免被 tbody sticky-left 列覆盖 */
table.proc thead th.col-group-demand,
table.proc thead th.col-idx,
table.proc thead th.col-intent,
table.proc thead th.col-effect { z-index: 5; }
/* 颜色分组背景 */
table.proc td.idx, table.proc td.intent, table.proc td.effect { background: #f8fafc; }
table.proc thead th.col-group-demand { background: #1e293b; color: #fff; }
table.proc thead tr:nth-child(2) th.col-idx,
table.proc thead tr:nth-child(2) th.col-intent,
table.proc thead tr:nth-child(2) th.col-effect { background: #475569; color: #fff; }
table.proc td.in-substance, table.proc td.in-form, table.proc td.in-type, table.proc td.in-name, table.proc td.in-value, table.proc td.in-anchor { background: #fefce8; }
table.proc thead th.col-group-input { background: #b45309; color: #fff; }
table.proc thead tr:nth-child(2) th.col-in-substance,
table.proc thead tr:nth-child(2) th.col-in-form,
table.proc thead tr:nth-child(2) th.col-in-type,
table.proc thead tr:nth-child(2) th.col-in-name,
table.proc thead tr:nth-child(2) th.col-in-value,
table.proc thead tr:nth-child(2) th.col-in-anchor { background: #d97706; color: #fff; }
table.proc td.via, table.proc td.action, table.proc td.directive, table.proc td.config,
table.proc td.decorator, table.proc td.memo, table.proc td.control, table.proc td.feature { background: #f0fdf4; }
table.proc thead th.col-group-impl { background: #065f46; color: #fff; }
table.proc thead tr:nth-child(2) th.col-via,
table.proc thead tr:nth-child(2) th.col-action,
table.proc thead tr:nth-child(2) th.col-directive,
table.proc thead tr:nth-child(2) th.col-config,
table.proc thead tr:nth-child(2) th.col-decorator,
table.proc thead tr:nth-child(2) th.col-memo,
table.proc thead tr:nth-child(2) th.col-control,
table.proc thead tr:nth-child(2) th.col-feature { background: #047857; color: #fff; }
table.proc td.out-substance, table.proc td.out-form, table.proc td.out-type, table.proc td.out-name, table.proc td.out-value, table.proc td.out-anchor { background: #eff6ff; }
table.proc thead th.col-group-output { background: #1e40af; color: #fff; }
table.proc thead tr:nth-child(2) th.col-out-substance,
table.proc thead tr:nth-child(2) th.col-out-form,
table.proc thead tr:nth-child(2) th.col-out-type,
table.proc thead tr:nth-child(2) th.col-out-name,
table.proc thead tr:nth-child(2) th.col-out-value,
table.proc thead tr:nth-child(2) th.col-out-anchor { background: #2563eb; color: #fff; }
/* 组间分隔粗线 */
table.proc th.col-effect, table.proc td.effect,
table.proc th.col-in-anchor, table.proc td.in-anchor,
table.proc th.col-feature, table.proc td.feature { border-right: 3px solid #94a3b8; }
/* 行边框 / 块头 / nested */
table.proc tr.step-main > td { border-top: 1.5px solid #94a3b8; }
table.proc tr.step-sub > td { border-top: 1px dashed #cbd5e1; }
table.proc tr.block-header { font-weight: 600; }
table.proc tr.block-header > td.intent { background: #e2e8f0; }
table.proc tr.step-nested > td.idx { color: #6b7280; }
/* ───────── 原子能力 atom rows + badge ─────────
atom = step 沿单个 (实质 OR 形式) 维度的投影. 默认全收起, 点击 step 行 idx 列的 ⚛N 徽章展开/收起. */
table.proc tr.atom-row { display: none; }
table.proc tr.atom-row.show, table.proc tr.atom-row:target { display: table-row; }
/* :target 高亮 — 从能力浏览页跳转过来时让对应 step/atom 行闪烁定位 */
table.proc tr:target > td {
animation: rowTargetFlash 1.6s ease-out;
box-shadow: inset 4px 0 0 #6d28d9;
}
@keyframes rowTargetFlash {
0% { background-color: #fef3c7 !important; }
100% { background-color: inherit; }
}
table.proc tr.atom-row > td { border-top: 1px dotted #d8b4fe !important; }
/* atom 行整体淡紫底, sticky 三列 (idx/intent/effect) 加深一档 */
table.proc tr.atom-row > td.in-substance, table.proc tr.atom-row > td.in-form,
table.proc tr.atom-row > td.in-type, table.proc tr.atom-row > td.in-name,
table.proc tr.atom-row > td.in-value, table.proc tr.atom-row > td.in-anchor {
background: #fdf4ff !important;
}
table.proc tr.atom-row > td.via, table.proc tr.atom-row > td.action,
table.proc tr.atom-row > td.directive, table.proc tr.atom-row > td.config,
table.proc tr.atom-row > td.decorator, table.proc tr.atom-row > td.memo,
table.proc tr.atom-row > td.control, table.proc tr.atom-row > td.feature {
background: #faf5ff !important;
}
table.proc tr.atom-row > td.out-substance, table.proc tr.atom-row > td.out-form,
table.proc tr.atom-row > td.out-type, table.proc tr.atom-row > td.out-name,
table.proc tr.atom-row > td.out-value, table.proc tr.atom-row > td.out-anchor {
background: #fdf4ff !important;
}
table.proc tr.atom-row > td.idx, table.proc tr.atom-row > td.intent,
table.proc tr.atom-row > td.effect {
background: #f3e8ff !important;
}
table.proc tr.atom-row > td.idx.atom-idx {
color: #6d28d9; font-style: italic; text-align: center; font-size: 11px;
}
table.proc tr.atom-row .atom-name {
color: #6d28d9; font-weight: 600; font-size: 11.5px; margin-bottom: 4px;
padding: 1px 6px; background: #ede9fe; border-radius: 3px; display: inline-block;
}
/* atom badge — 挂在 step 行 idx 列下方, 点击展开/收起该 step 的 atoms */
.atom-badge {
display: inline-block; margin-top: 4px; padding: 1px 5px;
font-size: 9.5px; background: #ede9fe; color: #6d28d9;
border-radius: 8px; cursor: pointer; user-select: none;
font-weight: 600; white-space: nowrap; line-height: 1.3;
}
.atom-badge:hover { background: #ddd6fe; }
.atom-badge.open { background: #6d28d9; color: #fff; }
.atom-badge .atom-arrow { font-size: 8px; }
/* 返回行 */
tr.return-row > td { background: #fde68a !important; font-weight: 600; padding: 8px; }
/* chip — 中性灰底 (供 declaration / drawer / 返回行); 表格内 type chip 由下方列色覆盖 */
.chip { display: inline-block; padding: 1px 7px; border-radius: 10px; font-size: 11.5px; color: #1f2937; background: #d1d5db; cursor: pointer; user-select: none; }
.chip:hover { filter: brightness(0.95); box-shadow: 0 0 0 1px #1e293b; }
/* 表格 in-type / out-type 列内 chip 统一列色 (黄/蓝区分输入输出) */
table.proc td.in-type .chip { background: #fde68a !important; color: #78350f; }
table.proc td.out-type .chip { background: #bfdbfe !important; color: #1e3a8a; }
/* keyword / name / flow */
.kw { color: #6d28d9; font-weight: 600; }
.name { color: #0f172a; }
.name:hover, .name.var-highlight { background: #fef3c7; cursor: pointer; }
.flow { color: #6b7280; font-size: 11.5px; font-style: italic; }
/* intent tokens */
.intent-text { color: #1f2937; line-height: 1.55; }
.intent-tok { display: inline-block; padding: 1px 5px; border-radius: 3px; margin: 0 1px; font-size: 11.5px; }
/* intent token: 底色对应其引用的列. 输入列黄, 输出列蓝, 实现列绿, 需求列灰. */
/* 需求 (灰) */
.intent-tok.ik-effect { background: #cbd5e1; color: #1f2937; }
/* 实现 (绿系) — 3 个不同饱和度区分 */
.intent-tok.ik-via { background: #d1fae5; color: #064e3b; font-family: ui-monospace, "SF Mono", monospace; font-size: 11px; }
.intent-tok.ik-act { background: #86efac; color: #14532d; }
.intent-tok.ik-control { background: #99f6e4; color: #134e4a; }
/* feature 禁止 intent 引用; 用 ik-other 警告色 */
.intent-tok.ik-other { background: #fee2e2; color: #991b1b; text-decoration: line-through; }
/* 输入·类型 (黄圆胶囊) / 输出·类型 (蓝圆胶囊) */
.intent-tok.ik-in-type { background: #fde68a; color: #78350f; border-radius: 10px; padding: 1px 8px; font-weight: 500; }
.intent-tok.ik-out-type { background: #bfdbfe; color: #1e3a8a; border-radius: 10px; padding: 1px 8px; font-weight: 500; }
/* 输入·实质 / 输出·实质 (矩形 tag) */
.intent-tok.ik-in-sub { background: #fef3c7; color: #92400e; }
.intent-tok.ik-out-sub { background: #dbeafe; color: #1e40af; }
/* 输入·形式 / 输出·形式 (矩形 tag 斜体) */
.intent-tok.ik-in-form { background: #fef3c7; color: #92400e; font-style: italic; }
.intent-tok.ik-out-form { background: #dbeafe; color: #1e40af; font-style: italic; }
/* substance/form 路径文本 */
td.in-substance > span, td.in-form > span,
td.out-substance > span, td.out-form > span {
display: inline-block; padding: 1px 4px; border-radius: 2px; font-size: 11px;
color: #1f2937; background: rgba(255,255,255,0.6); border: 1px solid rgba(0,0,0,0.06);
word-break: break-all; line-height: 1.4; cursor: pointer;
}
td.effect > span, td.action > span, td.feature > span {
display: inline-block; padding: 1px 5px; border-radius: 2px; font-size: 11.5px;
color: #0f172a; background: rgba(255,255,255,0.7); cursor: pointer; border: 1px solid rgba(0,0,0,0.06);
}
/* 指令/配置/运行/备注 列 — 多条目 vertical 堆叠 */
td.directive .instr-item, td.config .instr-item, td.decorator .instr-item, td.memo .instr-item {
display: block; font-size: 11.5px; color: #1f2937; margin: 2px 0; line-height: 1.5;
}
/* row-focus 加深底色 */
td.row-focus { font-weight: 600; color: #0f172a; }
td.idx.row-focus, td.intent.row-focus, td.effect.row-focus { background: #e2e8f0 !important; }
td.in-substance.row-focus, td.in-form.row-focus, td.in-type.row-focus, td.in-name.row-focus, td.in-value.row-focus, td.in-anchor.row-focus { background: #fde68a !important; }
td.via.row-focus, td.action.row-focus, td.directive.row-focus, td.config.row-focus,
td.decorator.row-focus, td.memo.row-focus, td.control.row-focus, td.feature.row-focus { background: #bbf7d0 !important; }
td.out-substance.row-focus, td.out-form.row-focus, td.out-type.row-focus, td.out-name.row-focus, td.out-value.row-focus, td.out-anchor.row-focus { background: #bfdbfe !important; }
/* inferred 角标 */
sup.inferred { color: #b45309; font-size: 10px; font-weight: bold; padding: 0 2px; cursor: help; }
/* 任意 cell 推断补全标记 — 「推」角标 + hover 显示 reason (不再加虚线下划线, 由角标承担识别) */
td.is-inferred {
cursor: help;
}
td.is-inferred::after {
content: '推';
display: inline-block;
font-size: 9px;
color: #92400e;
background: rgba(254, 243, 199, 0.9);
padding: 0 3px;
border-radius: 2px;
margin-left: 4px;
vertical-align: top;
font-weight: 600;
border: 1px solid #fbbf24;
}
/* 低置信留空变体: AI 想过但拿不准, 故意留空; 角标变 推? 与高置信 推 区分 (spec §推断补全标记 C) */
td.is-inferred.is-low-confidence::after { content: '推?'; }
/* 高亮模式: legend 点击"高亮推断" 时, body 加 show-inferred 类, 所有推断 cell 加重底色 */
body.show-inferred td.is-inferred {
background: #fef3c7 !important;
box-shadow: inset 0 0 0 1px #d97706;
}
/* 列隐藏 */
.col-hidden { display: none !important; }
/* drawer */
.drawer-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.35); display: none; z-index: 100; }
.drawer-overlay.open { display: block; }
.drawer { position: fixed; right: 0; top: 0; bottom: 0; width: 520px; max-width: 90vw; background: #fff; box-shadow: -4px 0 16px rgba(0,0,0,0.15); z-index: 101; overflow-y: auto; transform: translateX(100%); transition: transform 0.2s ease-out; }
.drawer.open { transform: translateX(0); }
.drawer header { padding: 14px 18px; background: #1e293b; color: #fff; border-bottom: 0; position: sticky; top: 0; z-index: 2; }
.drawer header h2 { margin: 0; font-size: 14px; }
.drawer .close { position: absolute; right: 12px; top: 12px; background: transparent; color: #fff; border: 0; cursor: pointer; font-size: 18px; }
.drawer .content { padding: 14px 18px; font-size: 12.5px; line-height: 1.6; color: #1f2937; }
.drawer .content h3 { margin: 14px 0 6px; font-size: 12.5px; color: #047857; }
.drawer .content pre { background: #f3f4f6; padding: 8px; border-radius: 3px; font-size: 11.5px; overflow-x: auto; line-height: 1.5; white-space: pre-wrap; }
.drawer .content .row { margin: 4px 0; }
.drawer .content .row b { color: #374151; }
.drawer .tree { font-family: ui-monospace, "SF Mono", monospace; font-size: 11.5px; }
.drawer .tree .node { padding: 1px 0; }
.drawer .tree .highlight { background: #fde68a; padding: 1px 4px; border-radius: 2px; font-weight: 600; }
.drawer .warning { background: #fef3c7; border-left: 3px solid #f59e0b; padding: 8px 10px; margin: 8px 0; font-size: 12px; }