/* 采集需求「规则说明」弹窗 —— 独立可复用样式（2026-09-21 第四轮从 styles.css 抽出）。
 *
 * 这套 UI 是一个**说明组件**，三个部分配套：
 *   结构：index.html 的 #configRuleHelpDialog（一级页签 + 左栏导航 + 右栏内容）
 *   逻辑：app.js 的 initRuleHelpFrame / switchRuleHelpPage / selectRuleSection /
 *         renderRuleParams / renderRuleParamsOverview / renderRuleParamsBoundaries / buildRuleParams
 *   数据：rule-params.js 的参数定义（参数说明页的唯一真源）
 *
 * **换页面复用**：把这三处一起搬走，保证 HTML 里有 #configRuleHelpDialog 那套骨架，
 * 并调用 initRuleHelpFrame() 即可；颜色与圆角全走全局 CSS 变量（--ink / --muted / --line /
 * --blue / --blue-soft），换主题只改变量。
 *
 * **加一个参数**：往 rule-params.js 的 COLLECT_PARAMS 加一条数据 ——
 * 左栏导航、参数分页、要点列表全部自动生成，本文件不需要改。
 * 注意：新文件要登记进 src/server.mjs 的静态资源白名单，否则 404（表现为整页空白）。
 */

/* 一级页签（2026-09-21 第二轮）：说明书的两个"页"——规则讲解 / 参数说明。
   为什么用**下划线式**而不是全站那种填充式页签：它下面紧跟着左栏导航，
   两者若都用填充块，读者会分不清"哪一行是换页、哪一行是换节"。
   下划线是"文档分册"的语言，填充块留给层级更低的左栏分节。 */
/* `align-items: center` 是防御：页签行现在是内容高（见 `.config-rule-help-card` 的行模板），
   但万一将来这一行再被撑高（比如并排塞了别的东西），页签也不该被拉伸成一条 100px 的高块、
   把标签和选中态下划线拉到相隔几十像素的两处。 */
.rule-help__top { display: flex; align-items: center; gap: 4px; margin: 0 0 12px; }
.rule-help__top-item {
  padding: 6px 12px; border: 0; border-bottom: 2px solid transparent;
  background: transparent; color: var(--muted); font-size: 13px; font-weight: 600;
}
.rule-help__top-item:hover { color: var(--ink); }
.rule-help__top-item[aria-selected="true"] { border-bottom-color: var(--blue); color: var(--blue); }
/* 「采集需求：流程与规则」弹窗：宽度必须加在 **`<dialog>` 本身**上，不能只加在里面的 `.dialog-card`。
   原因：全局 `dialog { width: min(430px, …) }` 决定的是弹窗盒子，卡片设成 720px 会**溢出弹窗盒子**
   （实测卡片 x=215 而弹窗 x=505），渲染出来是一块对不齐、还透着底页内容的浅色框。
   人工 2026-09-21 改成**分节导航 + 内容区**：760 → 880px（左栏 176 + 间距 + 右栏 ≈ 620，
   正好让第 2 节那张状态表不用横向挤）。 */
#configRuleHelpDialog { width: min(880px, calc(100vw - 32px)); }
/* 卡片是纵向**四段**：标题 / 一级页签 / 两栏正文 / 底部按钮。**卡片自己不滚动**——
   滚动下放到右栏（`.rule-help__panes`），否则"看完第 5 节还要滚回顶才能换节"。
   高度**固定**（不是 max-height）：分节切换时内容长短不同（第 1 节流程图 ~300px、
   第 2 节状态表 ~520px），跟着内容伸缩会让底部「知道了」上下跳、两块栏高也跟着变。
   高度**取定值**而不是"尽量高"（具体值见下方 `height` 那一段的取舍说明）：
   680px 时最长的那节刚好塞满、右栏滚不动，
   反而看不出"长内容在自己的栏里滚"这件事（实测 526px 内容 vs 526px 可视区）。

   ⚠ 行数必须与卡片里的子元素**逐个对齐**（2026-09-21 第六轮修正）：
   模板曾经只有 3 行（`auto 1fr auto`），而卡片里是 4 个子元素 —— 浏览器会把一级页签
   `.rule-help__top` 放进 `minmax(0, 1fr)` 那一行、把本该吃满剩余高度的 `.rule-help`
   挤到 auto 行。实测后果（1443×902，两页签对比）：
     · 页签行高度 = 剩余空间（= 520 − 卡头 − 正文自然高 − 卡尾），**内容越短白带越大**：
       讲解页 109px、参数页 33px；
     · 页签按钮是 flex 子项、默认 `stretch`，被拉成 109px 高，按钮文字垂直居中 →
       标签飘在空带正中、选中态下划线被甩到离标签 50px 处（"居中得很奇怪"）；
     · `.rule-help` 行变成 auto（285 / 361 随内容变）→ 两个页签的正文块起点差 76px，
       左栏底板跟着错位（"两个页签的分页高度不同"）；
     · 卡片外高仍被 height 钉死，所以只断言"卡片外高一致"的用例抓不到这个问题。
   修法就是补第 2 行，让页签行按内容高、正文行拿 1fr。 */
.config-rule-help-card {
  display: grid;
  grid-template-rows: auto auto minmax(0, 1fr) auto;
  /* 高度**固定但比原来矮**：原来 620px 是按"讲解页最长的第 2 节刚好塞满"定的，
     参数说明页改成一参数一分页之后，一页内容只有约 400px —— 620px 会在右栏和左栏
     底部各留 200px 空白（截图验收时看到的就是这一片）。
     560px：讲解页最长节仍可滚（右栏本就是 `overflow: auto`），参数页的空白只剩原来的一半。 */
  height: min(560px, calc(100vh - 64px));
  overflow: hidden;
}
.config-rule-help-card .dialog-heading { position: static; padding: 0; margin: 0 0 14px; background: #fff; }
/* 分节外壳：左导航（定宽、自己可滚）+ 右内容（吃掉剩余宽度、自己可滚）。
   左栏给一块**浅色底板**（人工 2026-09-21：原来光秃秃浮在白底上，看不出这是一块导航区）：
   底板 + 内边距把 7 项圈成一个整体，右侧内容区仍是白底，两块的分界一眼能看出来。 */
.rule-help { display: grid; grid-template-columns: 184px minmax(0, 1fr); gap: 16px; min-height: 0; }
.rule-help__nav {
  /* 底板颜色 = **专属变量**，不复用 `--panel`（2026-09-21 第六轮）：
     `--panel` 是 #f7f9fc，用在表格表头那种"四周有框线"的地方刚好；但这里是**白卡上的一块
     浮岛**，没有任何参照物，#f7f9fc 与 #fff 的对比度只有约 1.05:1，肉眼看就是一片白 ——
     人工的反馈正是"底板的颜色都消失了，就像是一坨白色放在上面"。
     加深到 #eef2f7（对比度约 1.12:1）后仍属"浅色底板"，但边界一眼可见。
     换主题只改这一个值。 */
  --rule-help-rail: #eef2f7;
  /* 底板边框色：比全站 `--line`(#e5e9ef) 再深一档 —— 目标是"框是画出来的"，
     与卡片自身的外框拉开层级（内层的框若和外层一样浅，读者会把两块看成同一层）。
     三档并排实测（2x 截图对比）后取中间档：`--line` 偏虚、#cdd7e4 偏重。 */
  --rule-help-rail-line: #d8e0ec;
  display: grid; align-content: start; gap: 2px; overflow: auto;
  /* `min-width: 0` 关掉栅格项的自动最小宽度：左栏定宽 184px，
     若允许被内容撑开，长标题会把整个弹窗顶宽（而不是在本栏内换行）。 */
  min-width: 0;
  /* 底板**拉通整列**（2026-09-21 第六轮改，此前是 `align-self: start` 只包住导航项）：
     两边各有理由，最终按人工口径取"整列"——
       · `start`（贴合内容）的代价：讲解页 7 项 = 252px、参数说明页 9 项 = 320px，
         同一次切换下左栏高度就变一次，人工反馈"两个页签的分页高度不同"；
       · `stretch` 的代价：项数少的一页，导航项下面会留一段底板色。
     行模板修好之后正文行高度两个页签已经一致（都是 1fr），底板跟着这行拉通，
     两页签的左右两栏就完全同形；那段"多余"的底板色正是"这是一条固定导航栏"的表达，
     比一页一块高度不一的灰岛更稳。`.rule-help__panes` 仍吃满剩余高度、自己滚动。 */
  align-self: stretch;
  max-height: 100%;
  /* **底框 + 边界**（人工 2026-09-21 第七轮："增加底框和边界，使得看上去更加明显"）：
     只有底色时，底板靠"灰 vs 白"的微弱色差立着，在偏亮的显示器上仍然发虚；
     补一圈边框后，底板的**四边是画出来的线**而不是"色差猜出来的边"，
     左栏与右栏的分界也不再依赖亮度判断。 */
  padding: 8px; border: 1px solid var(--rule-help-rail-line); border-radius: 6px; background: var(--rule-help-rail);
}
.rule-help__nav-item {
  display: block; width: 100%;
  padding: 8px 10px; border: 0; border-left: 2px solid transparent; border-radius: 0 5px 5px 0;
  background: transparent; color: var(--muted); font-size: 12px; font-weight: 600;
  text-align: left; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* 悬停底色用白色（比底板更亮）：在浅灰底板上"提亮"比"加深"更像可点。 */
.rule-help__nav-item:hover { background: #fff; color: var(--ink); }
/* 选中态与全站页签同一套语言：蓝字 + 蓝色左标记（这里导航是竖排，标记落在左边）；
   底色用浅蓝，压在浅灰底板上仍然清楚。 */
.rule-help__nav-item[aria-selected="true"] { border-left-color: var(--blue); background: var(--blue-soft); color: var(--blue); }
.rule-help__panes { min-width: 0; min-height: 0; overflow: auto; padding-right: 2px; }
/* 分节模式下"节与节之间"不再上下相邻，第一条分隔线要撤掉。 */
.rule-help__panes .rule-section + .rule-section { margin-top: 0; padding-top: 0; border-top: 0; }
/* 断点 = **620px**，不是 760px（2026-09-21 第五轮修正）。
   原来写 760px，后果是"浏览器窗口 900px 左右"这种很常见的桌面窗口也会命中窄屏分支：
   卡片变 `display: block`（高度被内容撑开）、左栏底板 `background: transparent`（底板消失）、
   弹窗几乎占满窗口 —— 这是窄屏分支自身的正确性，与本轮那个行模板缺陷是两件事。

   ⚠ 归因更正（2026-09-21 第六轮）：第五轮把人工反馈的"两个页签高度不同 / 居中很奇怪 /
   底板变白"记成了这条断点误命中，**记错了**。实测人工截图的视口是 1443×902，
   `matchMedia('(max-width: 620px)')` 为 false，窄屏分支根本没进；那三个现象的真因是
   `.config-rule-help-card` 的行模板比子元素少一行（见文件上方那段注释）。
   结论：620px 这个值继续留着（900px 窗口确实不该塌），但不要再把两件事混为一谈。

   为什么是 620px：弹窗宽 `min(880px, calc(100vw - 32px))`，卡片左右各 20px 内边距，
   所以两栏可用宽 = 弹窗宽 − 40；左栏 184 + 间距 16 + 右栏至少约 380 = 620。
   即"卡片内宽 < 620"（视口约 620）时两栏才真的展不开，这时才该塌成单栏。 */
@media (max-width: 620px) {
  /* 手机宽度放不下两栏：导航变顶部横向标签条（可横滑），内容在下方，整体改为卡片自己滚。 */
  .config-rule-help-card { display: block; max-height: min(760px, calc(100vh - 32px)); overflow: auto; }
  .rule-help { display: block; }
  /* 横向条形态下不再需要底板（它自己就是一整条），内边距、圆角与**四边框**一并撤掉，
     否则浅灰块/方框会在标题下方多出一条莫名其妙的色带或一个只有三边的框
     （只写 `border-bottom` 是压不住基础规则里那条 `border` 简写的另外三边的）。 */
  .rule-help__nav {
    grid-auto-flow: column; grid-auto-columns: max-content; align-content: stretch;
    overflow-x: auto; overflow-y: hidden;
    padding: 0 0 6px; border-radius: 0; background: transparent;
    margin-bottom: 12px; border: 0; border-bottom: 1px solid var(--line);
  }
  .rule-help__nav-item { border-left: 0; border-bottom: 2px solid transparent; border-radius: 5px 5px 0 0; }
  /* 横滑条形态下不换行：这是"一条可以左右滑的标签条"，条目换行会把条高撑成两倍。 */
  .rule-help__nav-item { white-space: nowrap; overflow-wrap: normal; }
  .rule-help__nav-item[aria-selected="true"] { border-left-color: transparent; border-bottom-color: var(--blue); }
  .rule-help__panes { overflow: visible; }
}
.rule-section + .rule-section { margin-top: 20px; padding-top: 18px; border-top: 1px solid var(--line); }
.rule-section__title { margin: 0 0 10px; color: var(--ink); font-size: 13px; }
.rule-section__note { margin: 10px 0 0; color: var(--muted); font-size: 12px; line-height: 1.7; }
/* 流程图（弹窗第一段）：纵向步骤链 + 连接线与箭头。
   用 CSS 画而不是塞图片：图片在窄屏/缩放下会糊，改一个字还得重导。
   连接线画在每个节点左侧（`::before`）、箭头画在连接线末端（`::after`），
   最后一个节点两样都不画——它是出口，不是"链上的某一环"。 */
.collect-flow { display: grid; margin: 0; padding: 0; list-style: none; }
.collect-flow__step { position: relative; display: grid; grid-template-columns: 26px minmax(0, 1fr); gap: 10px; padding: 0 0 14px 0; }
.collect-flow__step:last-child { padding-bottom: 0; }
.collect-flow__step::before { content: ''; position: absolute; left: 12px; top: 26px; bottom: 0; width: 2px; background: var(--line); }
.collect-flow__step:last-child::before { display: none; }
.collect-flow__step::after {
  content: ''; position: absolute; left: 9px; bottom: 3px;
  border-left: 5px solid transparent; border-right: 5px solid transparent; border-top: 6px solid var(--line);
}
.collect-flow__step:last-child::after { display: none; }
.collect-flow__marker {
  display: inline-grid; place-items: center; width: 26px; height: 26px; border-radius: 50%;
  border: 1px solid #bcdcff; background: var(--blue-soft); color: var(--blue); font-size: 12px; font-weight: 700;
}
/* 琥珀色 = "还在循环里，不是结束"；绿色 = 出口。这两个颜色是全站既有语义，不新造。 */
.collect-flow__step.is-loop .collect-flow__marker { border-color: #ffe0a3; background: #fff7e6; color: #a86a00; }
.collect-flow__step.is-terminal .collect-flow__marker { border-color: #b7e4c8; background: #e8f8ef; color: #1a7f47; }
.collect-flow__body { display: grid; gap: 2px; min-width: 0; padding-top: 2px; }
.collect-flow__body strong { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 13px; }
.collect-flow__body small { color: var(--muted); font-size: 12px; line-height: 1.6; }
.collect-flow__body b { color: var(--ink); }
.collect-flow__tag {
  padding: 0 6px; border: 1px solid #ffe0a3; border-radius: 9px; background: #fff7e6; color: #a86a00;
  font-size: 10px; font-style: normal; font-weight: 600; line-height: 16px; white-space: nowrap;
}
.config-rule-help { display: grid; gap: 14px; margin: 0; padding-top: 16px; border-top: 1px solid var(--line); }
.config-rule-help > div { display: grid; grid-template-columns: 96px minmax(0, 1fr); gap: 12px; align-items: start; }
.config-rule-help dt { color: var(--muted); font-size: 12px; font-weight: 600; line-height: 1.7; }
.config-rule-help dd { margin: 0; font-size: 12px; line-height: 1.7; }
.config-rule-help b { color: var(--ink); }

/* ── 参数说明页：一参数一分页（2026-09-21 第四轮）──────────────────────────────
   人工要求："左侧一个参数一个分页，对应分页内就都是这个参数的信息"。
   所以一页只渲染**一个**参数：标题大一号、要点字号上调（不再需要为"并排两个模块"压缩行高）。

   这套样式与 rule-params.js 的数据一一对应（渲染在 app.js 的 renderRuleParams）：
     .rule-param__name   参数名（数据里的 name）
     .rule-param__scope  作用域标签（scope："改这个数会影响谁"）
     .rule-param__value  当前值与可填范围（当前值读页面上那个 input，读不到才用 fallback）
     .rule-param__points 要点数组（points，每条以加粗小标题起头）
     .rule-param__see-also 需要对照着看的其他参数 */
.rule-param { display: flex; flex-direction: column; gap: 14px; }
.rule-param__head { display: grid; gap: 7px; }
.rule-param__name { margin: 0; color: var(--ink); font-size: 15px; font-weight: 700; }
/* 作用域标签自己一行：它是"改这个数会影响谁"，与名称一起回答"这是什么"，
   放在值行之前读起来最顺。 */
.rule-param__scope {
  justify-self: start; padding: 2px 9px; border: 1px solid var(--line); border-radius: 9px;
  background: var(--blue-soft); color: var(--blue); font-size: 11px; font-weight: 600; line-height: 17px;
}
/* 值行：当前值（或默认值）用蓝色强调 + 范围弱化跟在后面。
   为什么值是蓝色：一页只讲一个参数，读者来这一页**最想知道的就是"现在是多少"**。 */
.rule-param__value { margin: 0; color: var(--muted); font-size: 12px; line-height: 1.7; }
.rule-param__value b { color: var(--blue); font-size: 13px; }
.rule-param__range {
  margin-left: 10px; padding-left: 10px; border-left: 1px solid var(--line); font-size: 11px;
}
/* 正文用**无序列表**而不是段落：每个参数的说明天然是 2~4 条独立要点，
   排成一段会连成一片，正是"难阅读"的来源。 */
.rule-param__points { margin: 0; padding-left: 20px; }
.rule-param__points li { margin: 0 0 9px; color: var(--muted); font-size: 12.5px; line-height: 1.8; }
.rule-param__points li:last-child { margin-bottom: 0; }
.rule-param__points b { color: var(--ink); }
/* 每条要点里的**小标题**（"管哪两端""最常见配错"之类）：加粗前置，
   扫读时只看这几处也能懂个大概。 */
.rule-param__points strong { color: var(--ink); font-weight: 600; }
/* 「要对比着看」：一页只放一个参数之后，**对照关系必须显式给出来** ——
   否则读者要来回点（"任务间冷却"与"同一需求再派冷却"差在哪，本该并排看）。 */
.rule-param__see-also {
  margin: 0; padding-top: 11px; border-top: 1px dashed var(--line);
  color: var(--muted); font-size: 12px;
}
.rule-param__see-also b { color: var(--blue); }
