/* ============================================================
   WorldOfQuality | Quality ToolKit — components.css
   统一壳层组件（顶栏 / 页脚 / 品牌锁定组合 / 浅色工作层）
   依赖：tokens.css（必须在此之前加载）
   适用范围：123 个工具页（培训 / 试算引擎 / 采集 app）+ 隐私条款等外壳/导引页之外的页面。
   规则来源：docs/网站设计规范_v1.0.md §6 页头 / §7 页脚 / §8 品牌 / §3.1a 浅色工作层。
   设计语言：深色品牌外壳（顶栏 + 页脚，#0B0E14 / #080B11）+ 浅色工作层（#F6F7F9）。
   零外链、离线可用；所有取值取自 tokens.css，禁止裸十六进制。
   ============================================================ */

/* ---------- 浏览器默认边距复位（壳层统一承担） ----------
   CR-2026-071j：此前**没有任何壳层 CSS 复位 body 的 UA 默认 margin**，
   只有部分页面自己的内联样式碰巧写了 `html,body{margin:0}`。
   于是「不写内联复位」的页面（典型如试算引擎页）会保留浏览器默认的
   `body { margin: 8px }`，把顶栏整体右移 + 下移 8px，右缘还会露出一条底色。
   顶栏 / 页脚要「贴视口边缘」就必须先复位外边距 —— 这是壳层的职责，
   不能指望每个页面各写一份。 */
html, body { margin: 0; padding: 0; }

/* ---------- 盒模型复位（壳层统一承担） ----------
   CR-2026-071o：此前只有 site.css 与各页内联写 `*{box-sizing:border-box}`，
   而 components.css 没有。试算页（tools/engines/*）只引 tokens+components+engine.css，
   于是按 content-box 计算：.topbar-inner 的 max-width:1160 未含左右 24px padding
   → 实际 1208px，比其他页宽 48px；.topbar 的 height:64px 未含 1px 下边框
   → 实际 65px。两者叠加就是「页头忽大忽小、位置在动」。
   壳层是所有页面的公共依赖，盒模型基准必须由壳层给，页面不得各写一份。 */
*, *::before, *::after { box-sizing: border-box; }

/* ---------- 滚动条（全站统一，壳层承担） ----------
   CR-2026-071o：滚动条槽宽直接决定视口可用宽度，进而决定顶栏/页脚内层的
   居中位置。槽宽若因页面各自的 ::-webkit-scrollbar 规则而不同（实测 10px vs
   15px vs 6px），顶栏就会在页面切换时左右跳动。
   统一为 10px 细圆条、轨道透明（露出页面底色）；hover/active 提亮到品牌色。
   特指度 html body *::-webkit-scrollbar (0,0,3) 高于 site.css 与页面内联的
   *::-webkit-scrollbar (0,0,1)，确保壳层规则恒定胜出。 */
html:root, html body * { scrollbar-width: thin; scrollbar-color: var(--shell-line2) transparent; }
html:root::-webkit-scrollbar,
html body *::-webkit-scrollbar { width: 10px; height: 10px; }
html:root::-webkit-scrollbar-track,
html body *::-webkit-scrollbar-track { background: transparent; border: none; }
html:root::-webkit-scrollbar-thumb,
html body *::-webkit-scrollbar-thumb {
  background: var(--shell-line2); border-radius: 99px;
  border: 2px solid transparent; background-clip: content-box;
}
html:root::-webkit-scrollbar-thumb:hover,
html body *::-webkit-scrollbar-thumb:hover { background: var(--brand); background-clip: content-box; }
html:root::-webkit-scrollbar-thumb:active,
html body *::-webkit-scrollbar-thumb:active { background: var(--brand-strong); background-clip: content-box; }
html:root::-webkit-scrollbar-corner,
html body *::-webkit-scrollbar-corner { background: transparent; }
/* CR-2026-071o：滚动条统一由壳层在**根元素 html** 上控制，各页面一律不得再声明
   body/html 级 overflow。理由（双层滚动条 + 顶栏跳动的唯一根因）：
     · `html{overflow-y:scroll}` 已让视口常驻滚动条槽，页面长短不影响顶栏/页脚宽度；
     · 若页面再写 `html,body{overflow-x:clip}`（或 hidden/auto），CSS 规范会把 overflow-y
       从 visible 计算成 auto —— body 变成**第二个滚动容器**，于是出现两条竖直滚动条，
       且两者槽宽不同（clip 不占经典槽宽），顶栏/页脚左右位置在页面间来回跳动。
   横向溢出（培训页 MathJax 公式等）同样收敛到 html 的 overflow-x:hidden，
   不再由各页 body 承担。 */
html { overflow-y: scroll; overflow-x: hidden; }

/* ---------- 顶栏（深色品牌外壳，全站统一） ----------
   CR-2026-071o：底色统一实色 --shell-bg（原 rgba(11,14,20,.72) 毛玻璃只在下方也是深色时
   才等价，一旦下方是浅色工作层就会透视发灰，且各页底色不同 → 切换时顶栏色块会变）。 */
.topbar {
  position: sticky; top: 0; z-index: 50;
  height: var(--topbar-h);
  background: var(--shell-bg);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  border-bottom: 1px solid var(--shell-line2);
  transition: background var(--dur-base) var(--ease), border-color var(--dur-base) var(--ease);
}
.topbar-inner {
  max-width: var(--wrap);
  margin: 0 auto;
  height: 100%;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 0 var(--space-4);
}
/* CR-2026-071o：顶栏改为**全站实色**，不再区分 work-main / 根级页。
   此前根级页用 rgba(11,14,20,.72) 毛玻璃、工具页用实色 --shell-bg，切换页面时
   顶栏右侧会因透视下方内容而出现深浅不一的色块（用户反馈「页头忽大忽小」的观感来源之一）。
   顶栏是全站恒定的深色外壳，实色后导航/培训/试算/工作台的顶栏像素完全一致。 */
.topbar,
body.work-main .topbar {
  background: var(--shell-bg);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

/* ---------- 品牌锁定组合（中英双语：E圆 + 质擎 + QualEngine） ----------
   CR-2026-071o：本组规则是**壳层唯一 owner**。此前根级页（index / 七大工具）只引
   site.css，由 site.css 自带一套 .brand-mark(36px)/.brand-zh/.brand-en，工具页走
   components.css 的 24px 版本 —— 两套并存导致切换页面时 logo 大小与文字粗细都在变。
   现已把全部品牌锁定规则收敛到本文件，site.css 只保留导航内容（navlink / 语言按钮）。 */
.brand { display: flex; align-items: center; gap: 10px; text-decoration: none; color: var(--shell-txt); }
.brand:hover { text-decoration: none; }
.brand-mark { width: 28px; height: 28px; flex: 0 0 auto; color: var(--brand); display: block; }
/* CR-2026-075a：根级页 markup 内含 EN 紧排变体（.be-full / .be-q / .brand-mark-q）。
   ZH 模式只显示 be-full；EN 模式**整体**交给英文标准字图（en_wordmark_*.svg）处理。
   ⚠️ 历史缺陷：旧规则 `html[lang="en"] .brand-mark-q{display:block}` 让 20px 紧排 E 圆
   与标准字图**同时显示**，而标准字图内部本身已含 E 圆（作 Q）→ 叠出「CQualEngine」双 logo
   （英文导航页 / SPC 方法库页页头页脚均中招）。紧排变体从未收敛，现统一置为隐藏：
   EN 模式品牌 = 单一标准字图，无第二枚符号。 */
.brand-en .be-q, .f-logo .brand-en .be-q { display: none; }
.brand-mark-q { display: none; color: var(--brand); }
html[lang="en"] .brand-mark-q { display: none; }
html[lang="en"] .brand-mark { display: none; }
.brand-name { display: flex; align-items: center; gap: 9px; white-space: nowrap; }
.brand-zh {
  font-family: var(--font-cn);
  font-weight: var(--fw-cn-brand);   /* 800：与英文 700 视觉等粗 */
  font-size: 21px; letter-spacing: 2px; color: var(--shell-txt); line-height: 1;
}
.brand-en {
  font-family: var(--font-en);
  font-weight: var(--fw-en-brand);   /* 700：比中文 800 降一档 */
  font-size: 21px; letter-spacing: .5px; color: var(--brand); line-height: 1;
}
/* 英文标准字图（方向③）：仅 EN 模式显示。
   尺寸铁律（CR-2026-075a）：**字图高度 = 同位置中文版 .brand-mark 的高度**，
   顶栏 28px（=.brand-mark 28px）、页脚 22px（=.f-logo .brand-mark 22px）。
   等比后字图内英文 em ≈ 28×98.6/110.5 ≈ 25px，与中文版 .brand-en 21px 同量级
   （实测渲染墨迹高 24.9px、E 圆 21px，与中文版 logo 28px 的视觉体量对齐）——
   旧值 18px 明显偏小，是「英文品牌比中文小一圈」的根因。 */
.brand-en-img { display: none; }
html[lang="en"] .brand-en-img { display: block; height: 28px; width: auto; }
html[lang="en"] .brand-mark,
html[lang="en"] .brand-name { display: none; }

/* ---------- 面包屑 / 占位 ---------- */
.crumb {
  font-family: var(--font-en);
  font-size: 13px; color: var(--shell-muted); white-space: nowrap;
}
.spacer { flex: 1 1 auto; }

/* ---------- 顶栏导航按钮（胶囊，深色壳层） ---------- */
.topbar .btn {
  font-family: var(--font-cn);
  font-size: 13px; font-weight: var(--fw-btn);
  color: var(--shell-txt);
  text-decoration: none;
  padding: 7px 14px;
  border: 1px solid var(--shell-line2);
  border-radius: var(--radius-pill);
  background: transparent;
  white-space: nowrap;
  transition: color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.topbar .btn:hover {
  color: var(--brand);
  border-color: var(--brand);
  background: var(--brand-soft);
  text-decoration: none;
}

/* ---------- 页脚（深色外壳，全站统一三列） ---------- */
.footer {
  background: var(--footer-bg);
  border-top: 1px solid var(--shell-line);
  color: var(--shell-muted);
  padding: 22px 0 16px;          /* CR-2026-098/101：压缩竖向留白降低页脚高度 */
  font-family: var(--font-cn);
  margin-top: 0;
}
.footer .wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 var(--space-4); }
.footer-grid {
  display: grid;
  grid-template-columns: 1.5fr 2fr 1.1fr;   /* 品牌列 | 链接列 | 版权列（右，CR-2026-101）*/
  gap: 18px 32px;
  align-items: start;
}
.f-logo { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.f-logo .brand-mark { width: 22px; height: 22px; }
/* CR-2026-075a：EN 模式页脚改用与**顶栏同一张**标准字图（页底 = 页顶，用户明确要求），
   不再用「E圆符号 + brand-en-foot 文字」的混搭（那是页底看起来与页顶不是同一 logo 的原因）。
   高度 = .f-logo .brand-mark 的 22px，与中文版页脚 logo 体量一致。 */
html[lang="en"] .f-logo { gap: 0; }
html[lang="en"] .f-logo .brand-en-img { display: block; height: 22px; width: auto; }
.f-logo .brand-zh { font-size: 19px; }
.f-logo .brand-en { font-size: 19px; }
.f-tag { font-size: 13px; color: var(--shell-muted); line-height: 1.6; max-width: 320px; margin: 0; }
/* 链接：两列网格替代原 8 行竖排，显著降低页脚高度（CR-2026-098）*/
.f-links {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 7px 24px;
  align-content: start;
}
.f-links h4, .f-copy h4 {
  color: var(--shell-txt); font-size: 11px; font-weight: 700;
  margin: 0 0 8px; text-transform: uppercase; letter-spacing: .6px;
}
.f-links h4 { grid-column: 1 / -1; }   /* 标题横跨两列 */
.f-links a {
  color: var(--shell-muted); font-size: 13px; line-height: 1.5; text-decoration: none;
  transition: color var(--dur-fast) var(--ease);
}
.f-links a:hover { color: var(--brand); text-decoration: none; }
/* 版权信息：移到页脚右列，上下两行（质擎 / 潘书），不再占底栏整行（CR-2026-101）*/
.f-copy {
  grid-column: auto;
  display: flex; flex-direction: column; align-items: flex-end; text-align: right;
  gap: 3px; margin-top: 0; padding-top: 0; border-top: none;
}
.f-copy h4 { display: none; }            /* 隐藏冗余「版权信息」标题 */
.f-copy p { color: var(--shell-dim); font-size: 12.5px; margin: 0; line-height: 1.5; }
.f-copy p + p { margin-top: 1px; }
/* ---------- 页脚矢量图标 + 中英双语悬浮提示（CR-2026-100）----------
   设计：页脚常驻矢量图标，风格与 APQP 等页面 t-rail 侧边栏一致（24×24 / stroke-2 /
   currentColor 线性图标）。鼠标悬浮或键盘聚焦时弹出气泡：ZH 模式显示「中文 / English」
   双行；EN 模式由 CSS 隐藏 .zh 行，满足零中文泄漏硬规则。图标来源单一 —— site.js 的
   FOOTER_ICONS 注册表，由 enrichFooters() 按 data-mod（或 href 推断）注入，全站共用。 */
.f-links { display: flex; flex-wrap: wrap; gap: 8px 10px; align-content: start; }
.f-links h4 { flex-basis: 100%; grid-column: auto; margin: 0 0 4px; }
.f-links a {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; padding: 0;
  border-radius: 10px;
  color: var(--shell-muted);
  background: transparent;
  border: 1px solid var(--shell-line);
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.f-links a:hover, .f-links a:focus-visible {
  color: var(--brand); background: var(--brand-soft); border-color: var(--brand);
  text-decoration: none; outline: none;
}
.f-links a:focus-visible { box-shadow: 0 0 0 3px var(--brand-soft); }
.f-ic { width: 22px; height: 22px; display: block; }
.f-tip {
  position: absolute; bottom: calc(100% + 9px); left: 50%; transform: translateX(-50%);
  display: none; flex-direction: column; gap: 1px;
  padding: 6px 10px; border-radius: 8px;
  background: var(--shell-txt); color: var(--footer-bg);
  font-size: 12px; line-height: 1.45; white-space: nowrap;
  box-shadow: 0 8px 20px rgba(0,0,0,.30); pointer-events: none; z-index: 6;
}
.f-tip::after {
  content: ""; position: absolute; top: 100%; left: 50%; transform: translateX(-50%);
  border: 6px solid transparent; border-top-color: var(--shell-txt);
}
.f-tip .zh { font-family: var(--font-cn); font-weight: 600; }
.f-tip .en { font-family: var(--font-en); font-size: 11px; opacity: .8; }
.f-links a:hover .f-tip, .f-links a:focus-visible .f-tip { display: flex; }
html[lang="en"] .f-tip .zh { display: none; }
.f-page {
  max-width: var(--wrap); margin: 24px auto 0; padding: 14px var(--space-4) 0;
  border-top: 1px solid var(--shell-line);
  color: var(--shell-dim); font-size: 12px; font-family: var(--font-en);
}
/* ---------- 新版 Apple 式页脚目录（全站统一，由 site.js renderFooter 生成） ----------
   结构写在这里（深色外壳为默认），使所有页面（含未引 woq-next.css 的页面）
   都能正确渲染新版页脚；工作页的浅色配色由 woq-next.css 的 body.theme-light 覆盖。 */
.footer-grid {
  grid-template-columns: 1.05fr 3fr;
  gap: 36px 32px;
  align-items: start;
}
.f-brand { max-width: 240px; }
.f-logo .brand-zh { color: var(--shell-txt); }
.f-logo .brand-en { color: var(--brand); }   /* 品牌青本体，绝不灰 */
.f-tag { color: var(--shell-muted); }
.f-dir { display: grid; grid-template-columns: repeat(5, 1fr); gap: 24px; }
.f-dir h4 { font-size: 13px; font-weight: 700; color: var(--shell-txt); margin: 0 0 10px; }
.f-dir a { display: block; font-size: 12.5px; color: var(--shell-muted); text-decoration: none; padding: 3px 0; line-height: 1.5; }
.f-dir a:hover { color: var(--brand); }
.footer-legal { border-top: 1px solid var(--shell-line); margin-top: 28px; }
.f-legal {
  display: flex; flex-wrap: wrap; gap: 6px 10px; align-items: center;
  padding: 14px 0 22px; font-size: 12px; color: var(--shell-dim);
}
.f-legal .dot { color: var(--shell-line2); }
.footer .wrap { max-width: 1024px; }

@media (max-width: 900px) {
  .footer-grid { grid-template-columns: 1fr; gap: 18px; }
  .f-links { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .f-dir { grid-template-columns: repeat(2, 1fr); }
}

/* ---------- 浅色工作层（P2 / P3 / P4 主体区） ----------
   CR-2026-071j：`work-main` 挂在 <body> 上，因此**纵向 padding 必须为 0**。
   早期版本写 `padding: var(--space-5) 0`，等价于给 <body> 加 32px 上下内边距：
     · 顶栏是 body 的第一个子元素 → 被推下 32px，页面一进来顶部先露出一条浅色底带；
     · 页脚是 body 的最后一个子元素 → 页脚下方同样露出 32px 浅色底带。
   这就是「培训页 / 试算页页头页脚上下各多一条底色，而七大工具导航页正常」的唯一根因
   ——导航页 body 没有 work-main 类，不受这条规则影响。
   纵向留白改由内容容器（.layout / main / .wrap）自己承担，见下方 .work-main > * 规则。
   CR-2026-071n：回退 071m 的「滚动下放内容容器」方案（视觉不佳、sidebar 易错位），
   改回 body 作为滚动容器（与 071l 一致），但将不稳定的 `scrollbar-gutter: stable`
   替换为 `overflow-y: scroll` —— 强制视口常驻滚动条，所有工作层页面右侧恒定显示
   滚动条槽，无论内容长短页头页脚宽度完全一致，消除「满屏/不满屏页头跳动」。 */
.work-main {
  background: var(--work-bg);
  color: var(--work-txt);
  min-height: 100vh;
  padding: 0;
  display: flex;
  flex-direction: column;
  /* CR-2026-071o：body 不再设 overflow-y。滚动职责完全交给 html（已设 overflow-y:scroll），
     避免 html 滚动条 + body 滚动条叠加形成「双层滚动条」。 */
}
/* 内容区自己承担纵向留白：壳层（顶栏 / 页脚）贴合视口边缘，内容不顶到壳层。
   CR-2026-071k：当内容不足一屏时，<main> 弹性伸展把 <footer> 推到视口底部，
   避免出现「内容结束后页脚悬在半空、下方留大量空白」的异常。
   CR-2026-071l：提升特指度为 body.work-main > *，覆盖培训页/引擎页各自 .layout / main
   的 padding 重置，确保内容区与顶栏、页脚之间始终保留 32px 留白。
   CR-2026-071n：内容容器不再自己滚动（overflow 归视口），只保留上下留白与弹性伸展。 */
body.work-main > .layout,
body.work-main > main,
body.work-main > .wrap {
  padding-top: var(--space-5);
  padding-bottom: var(--space-5);
  flex: 1 1 auto;
}
.work-main .wrap { max-width: var(--wrap); margin: 0 auto; padding-left: var(--space-4); padding-right: var(--space-4); }

/* ---------- 浅色工作层卡片（修复新版工作台深色面板回归） ----------
   CR-2026-10xx：旧版工作台页（柏拉图 / 散布图等）各自内联
     `.panel{background:var(--panel);border:1px solid var(--line)...}` 且把 `--panel` 覆盖为白；
   新版工作台页（GR&R / 能力分析等）**丢失了这条内联规则**，
   于是只剩 woq-io.js 注入的 `.panel.woq-step{background:var(--panel)}` ——
   而 --panel 默认指向深色外壳 --shell-panel(#151A23)，导致步骤卡变成「深底 + 深字」。
   现把工作层 .panel 卡片样式收敛到壳层单一 owner（components.css），全站统一白卡：
     · 普通 .panel         → 白底 + 浅色边框 + 圆角 + 留白；
     · 步骤 .panel.woq-step → 白底 + 左侧彩色步骤条（覆盖 woq-io 注入的深色背景）。
   特指度 body.work-main .panel(0,2,1) > 各页内联 .panel(0,1,0)，旧页一并被统一，不回归。 */
body.work-main .panel {
  background: var(--work-panel);
  border: 1px solid var(--work-line);
  border-radius: var(--radius);
  padding: 16px;
  margin-bottom: 14px;
}
/* 步骤卡：在白卡基础上保留 woq-io 注入的彩色左边框与左内边距，仅把背景翻白。
   特指度 (0,3,1) > 注入规则 .panel.woq-step(0,2,0)，故背景以白卡为准。 */
body.work-main .panel.woq-step {
  background: var(--work-panel);
  border-left: 4px solid var(--woq-step-c, #0E7C8C);
  margin-top: 22px;
  padding-left: 18px;
}

/* ---------- 顶栏导航（5 学科入口 + 悬停卡片面板 · 2026-10-03 R3 §6 第3步） ----------
   壳层单一 owner：全部导航壳层样式集中于此，site.css 不再重复定义（消除双 owner，
   满足 shell-single-owner 门禁）。下拉纯 CSS(:hover / :focus-within) 驱动，无需 JS；
   工具页只引 tokens+components 也能展开。顶栏高度 64 / --shell-bg 实色 / 滚动条槽宽均不变。 */
.topbar-right { display: flex; align-items: center; gap: 18px; margin-left: auto; }
.topbar .sitenav { display: flex; align-items: center; gap: 2px; }
.topbar .navitem { position: relative; height: var(--topbar-h); display: flex; align-items: center; }
/* 悬停桥（hover bridge）：面板 top 为 calc(100% + 8px)，与顶栏底之间存在 8px 空隙。
   鼠标从一级入口下移经过该空隙时既不在 .navitem 也不在 .navpanel 内，:hover 链断开、
   面板消失（移动越快越明显）。此伪元素在 hover 时铺满空隙，使命中区域连续。
   仅在 hover/focus-within/is-open 时显示，避免常驻透明层遮挡下方内容的点击。
   ⚠ 2026-10-17（CR-2026-118d）：**任何主题都不得关掉这条桥**。
     woq-next.css 曾写 `body.theme-light .navitem::after{display:none}`（本想去掉悬停下划线，
     却误杀了桥）→ 浅色页实测「垂直下移 10 步里 6 步断链、斜向 11 步里 10 步断链」，
     用户观感是「鼠标稍动菜单就没，要迅速怼到某个卡片上才稳住」。
     下划线是 `.navlink::after`，与桥无关，去下划线只许动 .navlink::after。
   左右各外扩 8px：斜向下移时先进入桥再进面板，减少擦边出链。 */
.topbar .navitem::after {
  content: ""; position: absolute; left: -8px; right: -8px; top: 100%;
  height: 16px; /* 覆盖 8px 间隙 + 8px 富余 */
  display: none;
}
.topbar .navitem:hover::after,
.topbar .navitem:focus-within::after,
.topbar .navitem.is-open::after { display: block; }
.topbar .navlink {
  position: relative; font-family: var(--font-cn); font-size: 14px; font-weight: 600;
  color: var(--shell-muted); padding: 8px 12px; border-radius: var(--radius-sm);
  text-decoration: none; white-space: nowrap;
  transition: color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.topbar .navlink::after {
  content: ""; position: absolute; left: 12px; right: 12px; bottom: 4px; height: 2px; width: 0;
  background: linear-gradient(90deg, var(--brand), var(--brand-strong));
  border-radius: 2px; transition: width var(--dur-base) var(--ease);
}
.topbar .navitem:hover .navlink,
.topbar .navitem:focus-within .navlink { color: var(--shell-txt); background: var(--brand-soft); }
.topbar .navitem:hover .navlink::after,
.topbar .navitem:focus-within .navlink::after { width: calc(100% - 24px); }

/* 下拉面板：卡片分组（标题 + 2~5 卡），禁裸链接
   多列：.navpanel 已是 grid-auto-flow: column，每个 .navpanel-group 占一列，
   因此「产品工程」等条目多时通过增加 group 横向分列，而非纵向堆叠溢出视口。

   ⚠ 2026-10-17（CR-2026-118d）横向夹取：面板默认「以触发项为中心」，
     宽面板（产品工程 4 列 ≈ 964px）在 ≤1200 视口里必然右溢，被 html{overflow-x:hidden}
     裁掉最右一列 —— 用户反馈「产品工程悬浮时 PCBA 那部分看不到」，实测右溢 294px。
     夹取由 site.js initNavMenus() 逐项算出 --navpanel-dx（缺省 0 = 仍居中），
     CSS 只负责把该位移叠到居中变换上；无 JS 时退化为旧的居中行为（不会更差）。 */
.topbar .navpanel {
  position: absolute; top: calc(100% + 8px); left: 50%;
  transform: translateX(calc(-50% + var(--navpanel-dx, 0px)));
  z-index: 60;
  min-width: 320px; max-width: calc(100vw - 24px);
  background: var(--shell-panel); border: 1px solid var(--shell-line2);
  border-radius: var(--radius); box-shadow: var(--shadow-md);
  padding: 14px; gap: 18px; display: none;
  grid-auto-flow: column; grid-auto-columns: minmax(220px, 1fr);
  /* 分列后单列变矮，但仍加视口高度上限作为兜底，防止小屏或卡片增多时溢出。
     上限用 topbar 高度推导（52/64 两范式通用），比写死 96px 更贴合。 */
  max-height: calc(100vh - var(--topbar-h, 64px) - 16px);
  overflow-y: auto; overscroll-behavior: contain;
}
.topbar .navitem:hover .navpanel,
.topbar .navitem:focus-within .navpanel,
.topbar .navitem.is-open .navpanel { display: grid; }
/* 开合只做极短淡入：面板每开一次 display 从 none 复原，硬切换观感像「闪」；
   120ms 足够柔和，又不会拖慢「指针扫过一排入口」时的跟随感。 */
.topbar .navitem:hover .navpanel,
.topbar .navitem.is-open .navpanel { animation: woqNavIn 120ms var(--ease, ease-out) both; }
@keyframes woqNavIn { from { opacity: 0; transform: translateX(calc(-50% + var(--navpanel-dx, 0px))) translateY(-4px); } }
@media (prefers-reduced-motion: reduce) {
  .topbar .navitem:hover .navpanel,
  .topbar .navitem.is-open .navpanel { animation: none; }
}
/* 中窄视口：列最小宽收窄（4 列仍能一屏放下），再窄则改 2 列纵排 + 面板内滚动 */
@media (max-width: 1180px) {
  .topbar .navpanel { grid-auto-columns: minmax(210px, 1fr); gap: 14px; padding: 12px; }
}
@media (max-width: 980px) {
  .topbar .navpanel {
    grid-auto-flow: row; grid-auto-columns: auto;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    width: calc(100vw - 32px); min-width: 0; max-width: none;
  }
}
@media (max-width: 620px) {
  .topbar .navpanel { grid-template-columns: minmax(0, 1fr); }
}
.topbar .navpanel-group { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
/* CR-2026-101：下拉面板改为「悬浮时居中」——面板水平中心对齐触发项 navitem，
   多列时触发项正对中间列、左右各一列（用户要求）。原 navpanel-r 右对齐锚定废弃，
   当前各面板宽度（1~2 组 ≤ ~480px）在桌面视口居中不会溢出；窄屏仍受 max-width:92vw 约束。 */
.topbar .navpanel.navpanel-r { left: 50%; right: auto; transform: translateX(-50%); }
.topbar .navpanel-title {
  font-family: var(--font-en); font-size: 11px; font-weight: 700; letter-spacing: .6px;
  text-transform: uppercase; color: var(--brand); padding: 0 4px 6px;
  border-bottom: 1px solid var(--shell-line2); margin-bottom: 4px;
}
.topbar .navcard {
  display: block; text-decoration: none;
  background: var(--shell-bg); border: 1px solid var(--shell-line2);
  border-radius: var(--radius-sm); padding: 10px 12px;
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
.topbar .navcard:hover { border-color: var(--brand); background: var(--brand-soft); text-decoration: none; transform: translateY(-1px); }
.topbar .navcard-name { display: block; font-family: var(--font-cn); font-size: 14px; font-weight: 600; color: var(--shell-txt); }
.topbar .navcard-desc { display: block; font-family: var(--font-en); font-size: 12px; color: var(--shell-muted); margin-top: 3px; line-height: 1.4; }
.topbar .navcard.soon { cursor: not-allowed; opacity: .72; }
.topbar .navcard.soon:hover { border-color: var(--shell-line2); background: var(--shell-bg); transform: none; }
.topbar .soon-badge {
  display: inline-block; margin-top: 6px; font-family: var(--font-en); font-size: 10.5px; font-weight: 700;
  letter-spacing: .4px; color: var(--brand); background: var(--brand-soft);
  border: 1px solid var(--brand); border-radius: var(--radius-pill); padding: 1px 8px;
}
/* 语言切换 + 账号区（壳层导航内容，统一到 components.css） */
.lang-switch {
  font-family: var(--font-cn); font-size: 13px; font-weight: 600;
  border: 1px solid var(--shell-line2); color: var(--shell-txt); background: transparent;
  padding: 6px 12px; border-radius: var(--radius-pill); cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.lang-switch:hover { border-color: var(--brand); color: var(--brand); }
.topbar .auth { display: flex; gap: 10px; align-items: center; }
.topbar .auth .who {
  font-family: var(--font-en); font-size: 12.5px; color: var(--shell-muted);
  max-width: 180px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.topbar.scrolled { border-bottom-color: var(--shell-line2); box-shadow: 0 1px 0 var(--shell-line), 0 8px 24px rgba(0,0,0,.28); }

/* 6.5 P6 侧栏 scrollspy 激活态 ------------------------------------------------
 * 只改视觉态（左侧 accent 竖条 + 浅色底），**不改侧栏 flex-basis / 宽度**，
 * 保持 §2.1 的 212px 宽度铁律，跨页不跳动。
 * 侧栏属浅色工作层，故用 --brand-tint(底)/--brand-ink(字)，不用深底专用的 --brand-soft/--brand。
 * ⚠️ 只兜底**旧形态**（.toc）：CR-2026-071v 起侧栏统一为七大工具同族的 .rail-item[.is-on]，
 * 其完整视觉态由页面内样式定义（含直角边框与悬停让位），此处不得干预。 */
.toc a.active,
.toc .ti-active {
  border-left: 3px solid var(--brand-ink);
  background: var(--brand-tint);
  color: var(--brand-ink);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}
/* 激活竖条需要条目有左侧内边距，避免文字贴边 */
.toc a { transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease); }

/* ============================================================================
   CR-2026-071u · §6.4 分段控件激活态 + ⌘K 命令面板（壳层唯一 owner，页面禁覆写）
   ========================================================================= */

/* 6.4.1 激活态：当前所属学科。
   ⚠️ 激活下划线与上方悬停下划线是两条不同规则：悬停用 .navitem:hover .navlink::after（渐变、width 动画），
      激活用 .navitem.is-active（实色、常显）。二者共用 .navlink::after 会导致悬停即误显激活线，故此处
      激活态改由 is-active 类同时控制 ::after 的 width 与常显，不新增伪元素。 */
.topbar .navitem.is-active > .navlink {
  color: var(--shell-txt);
  background: var(--brand-soft);
}
.topbar .navitem.is-active > .navlink::after {
  width: calc(100% - 24px);
  background: var(--brand);
  box-shadow: 0 0 8px var(--brand-soft);
}
/* 无障碍：尊重系统的减少动态偏好，关闭激活/悬停下划线的宽度动画 */
@media (prefers-reduced-motion: reduce) {
  .topbar .navlink::after { transition: none; }
  .topbar .navlink, .topbar .navcard, .topbar .cmdk-btn { transition: none; }
}

/* 6.4.2 ⌘K 命令面板 -------------------------------------------------- */
.topbar .cmdk-btn {
  font-family: var(--font-en); font-size: 12px; font-weight: 600;
  color: var(--shell-muted); background: transparent;
  border: 1px solid var(--shell-line2); border-radius: var(--radius-sm);
  padding: 5px 10px; cursor: pointer; white-space: nowrap;
  display: inline-flex; align-items: center; gap: 6px;
  transition: border-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.topbar .cmdk-btn:hover { border-color: var(--brand); color: var(--brand); }
.topbar .cmdk-btn kbd {
  font-family: var(--font-en); font-size: 11px; color: var(--shell-muted);
  background: var(--shell-bg); border: 1px solid var(--shell-line2);
  border-radius: 4px; padding: 1px 5px;
}

/* 面板挂 body 直属、fixed 居中，独立于顶栏层级 */
.cmdk-backdrop {
  position: fixed; inset: 0; z-index: 200;
  background: rgba(6,9,14,.55);
  display: none; align-items: flex-start; justify-content: center;
  padding-top: 12vh;
}
.cmdk-backdrop.open { display: flex; }
.cmdk-panel {
  width: min(560px, calc(100vw - 24px));
  background: var(--shell-panel); border: 1px solid var(--shell-line2);
  border-radius: var(--radius); box-shadow: var(--shadow-lg);
  overflow: hidden; display: flex; flex-direction: column;
  max-height: 70vh;
}
.cmdk-input {
  width: 100%; border: 0; outline: none;
  background: var(--shell-bg); color: var(--shell-txt);
  font-family: var(--font-cn); font-size: 15px;
  padding: 14px 16px; border-bottom: 1px solid var(--shell-line2);
}
.cmdk-input::placeholder { color: var(--shell-muted); }
.cmdk-results { overflow-y: auto; padding: 8px; }
.cmdk-group-title {
  font-family: var(--font-en); font-size: 11px; font-weight: 700;
  letter-spacing: .6px; text-transform: uppercase; color: var(--brand);
  padding: 8px 8px 4px;
}
.cmdk-item {
  display: block; width: 100%; text-align: left; text-decoration: none;
  background: transparent; border: 0; cursor: pointer;
  padding: 8px 10px; border-radius: var(--radius-sm);
}
.cmdk-item:hover, .cmdk-item.sel { background: var(--brand-soft); }
.cmdk-item-name { display: block; font-family: var(--font-cn); font-size: 14px; font-weight: 600; color: var(--shell-txt); }
.cmdk-item-desc { display: block; font-family: var(--font-cn); font-size: 12px; color: var(--shell-muted); margin-top: 2px; }
.cmdk-item mark { background: transparent; color: var(--brand); font-weight: 700; }
.cmdk-empty { padding: 18px 12px; text-align: center; color: var(--shell-muted); font-size: 13px; }
.cmdk-foot {
  border-top: 1px solid var(--shell-line2); padding: 8px 12px;
  font-family: var(--font-en); font-size: 11px; color: var(--shell-muted);
  display: flex; gap: 12px; flex-wrap: wrap;
}
.cmdk-foot kbd {
  font-family: var(--font-en); background: var(--shell-bg);
  border: 1px solid var(--shell-line2); border-radius: 4px; padding: 1px 5px; margin-right: 3px;
}
/* 移动端：面板全宽；下拉面板改点击触发由 site.js 处理（hover:none） */
@media (max-width: 720px) {
  .cmdk-panel { width: calc(100vw - 24px); }
}

@media (max-width: 720px) {
  .topbar .sitenav { gap: 0; }
  .topbar .navlink { padding: 8px 9px; font-size: 13px; }
  .topbar .navpanel { min-width: 260px; }
  .topbar .cmdk-btn .cmdk-btn-text { display: none; }
}
