/* ==========================================================================
   QuantiHealth — 新官网设计系统 v2
   方向：临床文献式的克制编辑排版 + 品牌「序列纹样」签名图形
   品牌：Caribbean Green #00B09A / Charcoal / White
         （依据 QuantiHealth Brand Guidelines Late 2020）
   ========================================================================== */

/* ---------- 1. 字体（英文自托管；中文走系统字体，避免 7MB CJK 拖慢首屏） ---- */
@font-face { font-family: 'Source Sans Pro'; font-style: normal; font-weight: 400; font-display: swap; src: url('../fonts/source-sans-pro-400.woff2') format('woff2'); }
@font-face { font-family: 'Source Sans Pro'; font-style: normal; font-weight: 600; font-display: swap; src: url('../fonts/source-sans-pro-600.woff2') format('woff2'); }
@font-face { font-family: 'Source Sans Pro'; font-style: normal; font-weight: 700; font-display: swap; src: url('../fonts/source-sans-pro-700.woff2') format('woff2'); }

/* ---------- 2. 设计令牌 ---------- */
:root {
  /* 品牌 */
  --brand: #00B09A;          /* 装饰：细线、图标、纹样 */
  --brand-ink: #0A6B5C;      /* 文字/链接，白底 ≈5.7:1 */
  --brand-ink-h: #074C41;
  --brand-fill: #0A7A69;     /* 主按钮填充，白字 ≈4.9:1 */
  --brand-fill-h: #075A4C;
  --brand-bright: #4FE0C4;   /* 深色底上的品牌色 */
  --brand-mid: #73C5B7;      /* 手册次级绿 */
  --brand-soft: #E9F7F4;
  --brand-tint: #F3FAF8;
  --brand-grad: linear-gradient(90deg, var(--brand-ink) 0%, var(--brand) 100%);

  /* 中性（Charcoal 家族，微偏冷绿） */
  --ink: #0E1A17;
  --text: #39423F;
  --muted: #67726F;
  --line: #E4EAE8;
  --line-2: #CFD8D5;
  --bg: #FFFFFF;
  --bg-soft: #F4F7F6;
  --bg-alt: #FBFCFC;

  /* 深色区块 */
  --dark: #0A1E1A;
  --dark-2: #0F2B25;

  /* 语义色（ink 文字 + soft 底） */
  --ok-ink: #0B6B4B;     --ok-soft: #E6F5EE;
  --warn-ink: #8A5200;   --warn-soft: #FDF2E0;
  --danger-ink: #A32218; --danger-soft: #FCEBE9;
  --info-ink: #0A6B5C;   --info-soft: #E9F7F4;

  --r-xs: 6px;
  --r-sm: 8px;
  --r: 12px;
  --r-lg: 16px;
  --r-xl: 22px;

  --shadow-sm: 0 1px 2px rgba(8, 40, 34, .05), 0 10px 24px -20px rgba(8, 40, 34, .4);
  --shadow: 0 2px 6px rgba(8, 40, 34, .05), 0 32px 64px -40px rgba(8, 40, 34, .5);
  --shadow-lift: 0 2px 6px rgba(8, 40, 34, .05), 0 40px 72px -44px rgba(8, 40, 34, .62);

  /* 节奏（留白）：区块纵向呼吸 + 栅格间距 + 侧边距 */
  /* 区块纵向内边距。1440px 下相邻两节的"视觉间距"≈ 2×此值，
     实测 8.2vw/136px 时达到 236px，页面读起来发空（pFMT 专题尤其明显），
     故收到约 85px/节 → 节间 ≈ 170px。 */
  --sp-section: clamp(56px, 5.9vw, 96px);
  --sp-section-tight: clamp(40px, 4.4vw, 72px);
  --sp-gap: clamp(24px, 2.2vw, 32px);
  --gutter: clamp(20px, 4vw, 32px);

  /* 运动曲线：统一缓动，避免各组件各写一套 */
  --ease: cubic-bezier(.22, .61, .36, 1);
  --ease-out: cubic-bezier(.16, 1, .3, 1);
  --ease-in-out: cubic-bezier(.65, .05, .36, 1);

  /* 吸顶导航高度：main.js 在滚动后切到 nav-compact 收窄，
     供首屏锚点、pFMT 目录条等需要避让导航的元素共享 */
  --header-h: 72px;
  /* 吸顶导航在**锚点落位**时的避让高度（= 导航 62–72px + 呼吸）。
     html 的 scroll-padding-top 用它；专题页要用同一个数，改这里全站生效。 */
  --header-pad: 88px;

  --maxw: 1240px;
}
html.nav-compact { --header-h: 62px; }

/* ---------- 3. 基础 ---------- */
* { margin: 0; padding: 0; box-sizing: border-box; }
html {
  font-size: 16px;
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: var(--header-pad);
}
body {
  font-family: "Source Sans Pro", -apple-system, BlinkMacSystemFont, "PingFang SC",
               "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans SC", sans-serif;
  font-size: clamp(1rem, .965rem + .15vw, 1.0625rem);
  line-height: 1.85;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* 中西文自动间距 / 全角标点行首收缩：Chrome 130+ & Safari 18.4+ 生效，
     旧浏览器按原生排版降级，不影响可读性 */
  text-autospace: normal;
  text-spacing-trim: trim-start;
  font-kerning: normal;
}
img, svg, video { max-width: 100%; height: auto; display: block; }
a { color: var(--brand-ink); text-decoration: none; transition: color .18s ease; }
/* 正文段落里的行内链接：默认就带下划线。
   站内链接默认 `text-decoration: none`，正文中只能靠颜色与周围文字区分——
   `--brand-ink`(#0a6b5c) 与正文灰 #67726f 的对比度只有 1.28:1，不满足 WCAG 1.4.1
   "不能仅靠颜色传达信息"（Lighthouse link-in-text-block，2026-10-10 实测 3 个页面命中）。
   只作用于 <main> 内的段落：页脚、导航、按钮（.btn）与卡片出口（.more）不受影响。 */
main p a:not(.btn):not(.more),
main .callout a:not(.btn) { text-decoration: underline; text-underline-offset: 2px; }
a:hover { color: var(--brand-ink-h); }
ul, ol { list-style: none; }
strong, b { font-weight: 600; color: var(--ink); }
:focus-visible { outline: 2px solid var(--brand); outline-offset: 3px; border-radius: 4px; }
::selection { background: var(--brand); color: #fff; }

/* 跳到主要内容：键盘 / 读屏用户按 Tab 的第一站，避免逐条走完整个导航才能到正文 */
.skip-link {
  position: fixed; top: 10px; left: var(--gutter); z-index: 200;
  padding: 11px 20px; border-radius: 10px;
  background: var(--ink); color: #fff; font-size: .9375rem; font-weight: 600;
  box-shadow: var(--shadow-lift);
  transform: translateY(-200%);
  transition: transform .18s var(--ease);
}
.skip-link:focus { transform: translateY(0); color: #fff; }

/* 仅给读屏的文本：用于补齐标题层级（视觉上不占位）。
   与 .skip-link 不同，这类文本任何时候都不显示。 */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
/* <main tabindex="-1"> 只是跳转落点，聚焦时不画整块描边（内容位移本身即为反馈） */
main[tabindex="-1"]:focus, main[tabindex="-1"]:focus-visible { outline: none; }

/* ---------- 4. 排版 ---------- */
/* 中英混排的字距策略：中文标题不给负字距（负值会把方块字压得过紧），
   改用略正的字距 + 更大的字号建立层级；拉丁字母靠字体本身的字距。 */
h1, h2, h3, h4 { color: var(--ink); font-weight: 700; }
/* 中文避头尾：标点不在行首、行尾不悬挂（Chrome/Safari 默认已是 auto，strict 更严） */
h1, h2, h3, h4, .lead, p { line-break: strict; }
/* 中文断词：区块标题按「词组 + 标点」断行，不在复合词中间断开
   （如「两条核心技术路线，/ 湿实验到干实验的完整闭环」）。
   `overflow-wrap: anywhere` 是兜底——整段确实放不下时仍可断开，绝不溢出；
   正文段落不套用（长中文段落只在标点断行会非常参差）。 */
h2, h3, h4 { word-break: keep-all; overflow-wrap: anywhere; }
h1 {
  font-size: clamp(2.35rem, 1.28rem + 4vw, 4.25rem);
  line-height: 1.14; letter-spacing: .005em;
  text-wrap: balance;
}
h2 {
  font-size: clamp(1.7rem, 1.16rem + 2.15vw, 2.8rem);
  line-height: 1.26; letter-spacing: .005em;
  text-wrap: balance;
}
h3 { font-size: clamp(1.0625rem, 1.02rem + .2vw, 1.1875rem); font-weight: 600; line-height: 1.5; }
h4 { font-size: 1rem; font-weight: 600; line-height: 1.55; }
p { color: var(--text); text-wrap: pretty; }

/* 导语：主站用 .lead、pFMT 专题用 .subtitle、白皮书用 .wp-subtitle——三套类名是历史
   遗留，角色是同一个（区块/首屏导语），字号与行高只在这里写一次。
   差异只在"是否限宽"：.wp-subtitle 自带 <br> 手动断行、且栏宽本来就窄（.wp-wrap 940px），
   给它套 62ch 会把既有断行打乱，故限宽只管 .lead / .subtitle。 */
.lead, .subtitle, .wp-subtitle {
  font-size: clamp(1.0625rem, 1rem + .3vw, 1.1875rem);
  line-height: 1.9; color: var(--muted);
}
.lead, .subtitle {
  max-width: 62ch;
  text-wrap: pretty;
}
.note { font-size: .875rem; line-height: 1.75; color: var(--muted); }
.center { text-align: center; }
.brand { color: var(--brand-ink); }

/* 编号式小标题：品牌色短横 + 全大写英文标签 */
.eyebrow {
  display: inline-flex; align-items: center; gap: 10px;
  font-size: .78125rem; font-weight: 700; letter-spacing: .18em; text-transform: uppercase;
  color: var(--brand-ink); margin-bottom: 18px;
}
.eyebrow::before {
  content: ''; flex: none; width: 22px; height: 2px; border-radius: 2px; background: var(--brand);
}
.eyebrow--num { font-variant-numeric: tabular-nums; }

/* 数字统一用等宽数位，避免动画/对齐时跳动 */
.num, .stat .num, .spec__idx, .step .idx { font-variant-numeric: tabular-nums; }

/* ---------- 5. 布局 ---------- */
.container { width: 100%; max-width: var(--maxw); margin: 0 auto; padding: 0 var(--gutter); }
.section { padding: var(--sp-section) 0; }
.section--tight { padding: var(--sp-section-tight) 0; }
.bg-soft { background: var(--bg-soft); }
.bg-alt { background: var(--bg-alt); }
.bg-tint { background: var(--brand-tint); }
.bg-ink { background: var(--ink); }

.grid { display: grid; gap: var(--sp-gap); }
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }

/* 编辑式区块标题：上方细线 + 大标题 + 导语 */
.section-head {
  padding-top: 26px; border-top: 1px solid var(--line);
  margin-bottom: clamp(34px, 3.6vw, 52px);
}
/* 用 em 而非 ch：中文 1 字≈1em，ch 以数字宽度计会低估，导致标题提前折行 */
.section-head h2 { max-width: 22em; }
.section-head .lead { margin-top: 18px; }
/* 无 eyebrow 的区块标题也补一个品牌短横，保持全站节奏一致
   （split 版式为两列网格，伪元素会占格导致标题错位，故排除） */
.section-head:not(:has(.eyebrow)):not(.section-head--split)::before {
  content: ''; display: block; width: 28px; height: 2px; border-radius: 2px;
  background: var(--brand); margin-bottom: 20px;
}
.section--dark .section-head:not(:has(.eyebrow)):not(.section-head--split)::before,
.section--brand .section-head:not(:has(.eyebrow)):not(.section-head--split)::before { background: var(--brand-bright); }
.section-head.center { padding-top: 0; border-top: 0; max-width: 820px; margin-left: auto; margin-right: auto; text-align: center; }
.section-head.center h2 { max-width: none; }
.section-head.center .eyebrow { justify-content: center; }
.section-head.center:not(:has(.eyebrow)):not(.section-head--split)::before { margin-left: auto; margin-right: auto; }
.section-head--split { display: grid; grid-template-columns: minmax(0, 1.06fr) minmax(0, .94fr); gap: 20px 64px; align-items: start; }
.section-head--split h2 { max-width: none; }
/* 分栏标题的右列是「页边注」（margin note），不是正文段，也不是"半边导语"。
   之前它跟正文同一个尺度（19px），一旦内容长起来，右列方块就比左侧标题还高、
   还密 —— 两栏于是变成"互相比块头"的关系，怎么对齐都是右重左轻。
   这里的处理是换掉它的**层级**而不是位置：右列降到注脚尺度（.9rem / 行高 1.75）
   并保持顶对齐，让它明确是标题的旁注。注脚尺度下，实测全部 25 处的右列都
   不超过左侧标题块的高度（最长的 144 字导语 4 行 ≈ 101px < 标题块 106px）。 */
.section-head--split .lead { margin-top: 4px; font-size: .875rem; line-height: 1.75; }

/* ---------- 6. 品牌纹样（企业符号图案） ---------- */
.pattern { display: block; width: 100%; height: auto; }
/* 内页 hero 背景层：纹样长在首屏里，不占额外纵向空间，也不会把 hero 与正文隔开 */
.hero-pattern {
  /* 底边对齐区块下沿：纹样的基线正好落在首屏边界上，短棒圆头完整可见。
     此前是 bottom: -6%（向下溢出），棒身被区块底边裁断，再加上首屏的
     1px 下边框，看起来像"条带下面压了一条多余的横线"。
     2026-10-10：`bottom: 0` 只保证 SVG 盒子贴边，棒尖落在哪由 build.py 的
     `pattern_svg()` 决定——此前基线画在盒子底边之上约 6px（h=160 / 1440 宽实测），
     看着就是"条带没落到背景最底下"；已把 base_y 改到 h - stroke/2。 */
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 0;
  overflow: hidden; opacity: .20; pointer-events: none;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 9%, #000 91%, transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 9%, #000 91%, transparent 100%);
}
.hero-pattern svg { display: block; width: 100%; height: auto; }
.dark-pattern svg, .footer-pattern svg{ width: 100%; height: auto; }
.dark-pattern { margin-top: clamp(40px, 5vw, 64px); opacity: .18; }

/* 深色区块以纹样收尾 */
.section--dark.has-pattern, .section--brand.has-pattern { padding-bottom: 0; }
/* 区块底边留给"出血压边"的插画：内容直抵底边、不留内边距。
   与上面 has-pattern 那条同类，但这里是**内容图**压边（/knowledgebase/ 四步流程的最后一张
   报告图），不是纹样收尾，所以另开一个语义明确的类，别去套 has-pattern。 */
.section--bleed-bottom { padding-bottom: 0; }

/* ---------- 7. 深色区块 ---------- */
.section--dark, .section--brand {
  position: relative; overflow: hidden;
  background: var(--dark); color: rgba(255, 255, 255, .78);
}
.section--dark .container, .section--brand .container { position: relative; z-index: 1; }
.section--dark h2, .section--dark h3, .section--dark h4,
.section--brand h2, .section--brand h3, .section--brand h4 { color: #fff; }
.section--dark p, .section--dark .lead,
.section--brand p, .section--brand .lead { color: rgba(255, 255, 255, .74); }
/* 深色区块里的步骤说明：`.step p { color: var(--muted) }` 与上面这条**特异性相同、位置更靠后**，
   会把正文压回 --muted（#67726f）——在深底 #0a1e1a 上只有 3.47 对比度（Lighthouse 2026-10-10 实测）。
   这里用更高的特异性把深色区块里的步骤正文拉回浅色。 */
.section--dark .step p, .section--brand .step p { color: rgba(255, 255, 255, .74); }
.section--dark .eyebrow, .section--brand .eyebrow { color: var(--brand-bright); }
.section--dark .eyebrow::before, .section--brand .eyebrow::before { background: var(--brand-bright); }
.section--dark .section-head, .section--brand .section-head { border-top-color: rgba(255, 255, 255, .18); }
.section--dark a, .section--brand a { color: var(--brand-bright); }
.section--dark .note, .section--brand .note { color: rgba(255, 255, 255, .6); }

/* ---------- 8. 按钮 ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 14px 28px; border-radius: 11px; border: 1.5px solid transparent;
  font-size: .9375rem; font-weight: 600; line-height: 1.4; cursor: pointer;
  transition: background-color .24s var(--ease), border-color .24s var(--ease),
              color .24s var(--ease), transform .3s var(--ease-out), box-shadow .35s var(--ease);
}
.btn-primary { background: var(--brand-fill); color: #fff; box-shadow: 0 12px 26px -18px rgba(7, 90, 76, .9); }
.btn-primary:hover {
  background: var(--brand-fill-h); color: #fff;
  transform: translateY(-2px); box-shadow: 0 20px 36px -18px rgba(7, 90, 76, .85);
}
.btn-outline { border-color: var(--line-2); color: var(--ink); background: transparent; }
.btn-outline:hover { border-color: var(--brand); color: var(--brand-ink); background: var(--brand-tint); }
.btn:active { transform: translateY(0) scale(.985); }
.btn-sm { padding: 9px 18px; font-size: .875rem; }
.btn-row { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }
.section--dark .btn-outline, .section--brand .btn-outline, .cta-band .btn-outline{
  border-color: rgba(255, 255, 255, .3); color: #fff;
}
.section--dark .btn-outline:hover, .section--brand .btn-outline:hover, .cta-band .btn-outline:hover{
  background: rgba(255, 255, 255, .1); border-color: #fff; color: #fff;
}

/* ---------- 9. 导航 ---------- */
.site-header {
  position: sticky; top: 0; z-index: 100;
  background: rgba(255, 255, 255, .88);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid var(--line);
  transition: box-shadow .3s var(--ease), background-color .3s var(--ease), border-color .3s var(--ease);
}
/* 滚动后：收缩高度 + 收起底部分隔线，让首屏更大、导航更轻 */
.site-header.scrolled {
  background: rgba(255, 255, 255, .95);
  border-bottom-color: transparent;
  box-shadow: 0 1px 0 var(--line), 0 18px 40px -36px rgba(8, 40, 34, .6);
}
html.nav-compact .nav-brand svg { height: 34px; }
.nav { display: flex; align-items: center; gap: 32px; height: var(--header-h); transition: height .3s var(--ease); }

.nav-brand { display: inline-flex; align-items: center; gap: 11px; color: var(--brand); flex: none; }
.nav-brand:hover { color: var(--brand-ink); }
/* 首页时 logo 带 .nav-brand.active（当前页语义标记）：**刻意不加任何视觉样式**。
   logo 全站恒为品牌绿、仅 hover 变 --brand-ink；顶部导航也没有独立"首页"项，
   首页的"当前页"提示交由正文首屏与面包屑承担，避免 logo 常驻异化。 */
.nav-brand svg { height: 40px; width: auto; flex: none; display: block; transition: height .3s var(--ease); }

.nav-links { display: flex; align-items: center; gap: 4px; margin-left: auto; }
.nav-links > a, .nav-group > .nav-group-label {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 8px 14px; border-radius: 8px;
  color: var(--text); font-size: .9375rem; font-weight: 400; line-height: 1.4;
  transition: color .18s, background-color .18s;
}
/* 排除 .nav-cta：它的 hover 底色由下方专属规则决定，
   否则本选择器（specificity 0,2,1）会盖掉 .nav-cta:hover（0,2,0）的底色，
   出现白字 + 近白底的不可读状态 */
.nav-links > a:not(.nav-cta):hover, .nav-group:hover > .nav-group-label {
  color: var(--brand-ink); background: var(--brand-tint);
}
/* 键盘焦点（:focus-visible）才展开下拉：鼠标点标签会把焦点交给开关 checkbox，
   若沿用 :focus-within，菜单会在鼠标移开后仍然赖着不走 */
.nav-group:has(:focus-visible) > .nav-group-label {
  color: var(--brand-ink); background: var(--brand-tint);
}
.nav-links > a.active { color: var(--brand-ink); font-weight: 600; }
.nav-links > a.active::after {
  content: ''; position: absolute; left: 14px; right: 14px; bottom: 2px; height: 2px;
  border-radius: 2px; background: var(--brand);
}
.nav-links > a { position: relative; }

.nav-group { position: relative; }
/* 下拉开关（分组 / 三级菜单）：必须“不可见但可聚焦”。原先的 display: none 会把
   整个分组从 Tab 序列里删掉——键盘用户走不到任何一项下拉链接。改为 1px 透明元素，
   焦点环改画在可见的标签上。 */
.nav-group-toggle, .nav-sub-toggle {
  position: absolute; width: 1px; height: 1px; margin: 0;
  opacity: 0; pointer-events: none;
}
.nav-group-toggle:focus-visible + .nav-group-label,
.nav-sub-toggle:focus-visible ~ .nav-sub-row .nav-sub-caret {
  outline: 2px solid var(--brand); outline-offset: 2px; border-radius: 8px;
}
.nav-group-label { cursor: pointer; }
.nav-group.active > .nav-group-label { color: var(--brand-ink); font-weight: 600; }
.nav-caret { transition: transform .2s; flex: none; }
.nav-group:hover .nav-caret { transform: rotate(180deg); }
.nav-group:has(:focus-visible) .nav-caret { transform: rotate(180deg); }
.nav-dropdown {
  position: absolute; top: calc(100% + 8px); left: 0;
  min-width: 230px; padding: 8px; display: flex; flex-direction: column; gap: 2px;
  background: #fff; border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 24px 48px -28px rgba(8, 40, 34, .5);
  opacity: 0; visibility: hidden; transform: translateY(6px);
  transition: opacity .18s, transform .18s, visibility .18s;
}
.nav-dropdown::before { content: ''; position: absolute; top: -10px; left: 0; right: 0; height: 10px; }
/* 含三级菜单的分组：右侧箭头独立成列，需要更宽的容器，避免激活态加粗标签折行 */
.nav-dropdown--sub { min-width: 250px; }
.nav-group:hover .nav-dropdown { opacity: 1; visibility: visible; transform: translateY(0); }
.nav-group:has(:focus-visible) .nav-dropdown { opacity: 1; visibility: visible; transform: translateY(0); }
.nav-dropdown a { padding: 9px 12px; border-radius: 8px; font-size: .9063rem; color: var(--text); }
.nav-dropdown a:hover { background: var(--bg-soft); color: var(--brand-ink); }
.nav-dropdown a.active { color: var(--brand-ink); font-weight: 600; }

/* ---------- 9b. 三级菜单（下拉内嵌子分组） ---------- */
.nav-sub { position: relative; }
/* 一行两件：左侧标签是指向子分组首页的链接，右侧箭头是展开三级菜单的开关 */
.nav-sub-row {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  border-radius: 8px; transition: background-color .18s;
}
.nav-sub-label {
  display: flex; align-items: center; gap: 8px;
  padding: 9px 12px;
  font-size: .9063rem; color: var(--text);
  transition: color .18s;
}
.nav-sub-caret {
  display: flex; align-items: center; padding: 9px 10px; cursor: pointer;
  color: var(--muted); transition: color .18s;
}
.nav-sub:hover > .nav-sub-row, .nav-sub.active > .nav-sub-row { background: var(--bg-soft); }
.nav-sub:has(:focus-visible) > .nav-sub-row { background: var(--bg-soft); }
.nav-sub:hover > .nav-sub-row .nav-sub-label, .nav-sub.active > .nav-sub-row .nav-sub-label,
.nav-sub:hover > .nav-sub-row .nav-sub-caret {
  color: var(--brand-ink);
}
.nav-sub:has(:focus-visible) > .nav-sub-row .nav-sub-label,
.nav-sub:has(:focus-visible) > .nav-sub-row .nav-sub-caret { color: var(--brand-ink); }
.nav-sub.active > .nav-sub-row .nav-sub-label { font-weight: 600; }
.nav-sub-row .nav-caret { transition: transform .2s; }
.nav-sub:hover .nav-caret { transform: rotate(180deg); }
.nav-sub:has(:focus-visible) .nav-caret { transform: rotate(180deg); }
.nav-sub-dropdown {
  display: none; flex-direction: column; gap: 1px;
  margin: 2px 0 4px 10px; padding-left: 8px; border-left: 1px solid var(--line);
}
.nav-sub:hover > .nav-sub-dropdown { display: flex; }
.nav-sub:has(:focus-visible) > .nav-sub-dropdown { display: flex; }
/* 不支持 :has() 的旧浏览器（Firefox <121 / Safari <15.4 / Chrome <105）：
   退回 :focus-within，键盘展开照常可用；代价是鼠标点过标签后菜单会保持展开 */
@supports not selector(:has(*)) {
  .nav-group:focus-within > .nav-group-label { color: var(--brand-ink); background: var(--brand-tint); }
  .nav-group:focus-within .nav-caret { transform: rotate(180deg); }
  .nav-group:focus-within .nav-dropdown { opacity: 1; visibility: visible; transform: translateY(0); }
  .nav-sub:focus-within > .nav-sub-row { background: var(--bg-soft); }
  .nav-sub:focus-within > .nav-sub-row .nav-sub-label,
  .nav-sub:focus-within > .nav-sub-row .nav-sub-caret { color: var(--brand-ink); }
  .nav-sub:focus-within .nav-caret { transform: rotate(180deg); }
  .nav-sub:focus-within > .nav-sub-dropdown { display: flex; }
}
.nav-sub-dropdown a { padding: 7px 10px; border-radius: 7px; font-size: .875rem; color: var(--muted); }
.nav-sub-dropdown a:hover { background: var(--bg-soft); color: var(--brand-ink); }
.nav-sub-dropdown a.active { color: var(--brand-ink); font-weight: 600; }

.nav-right { display: flex; align-items: center; gap: 16px; flex: none; }
.nav-toggle, .nav-toggle-label { display: none; }
.nav-cta {
  padding: 10px 20px !important; border-radius: 9px;
  background: var(--brand-fill); color: #fff !important; font-weight: 600;
}
.nav-links > a.nav-cta:hover, .nav-links > a.nav-cta:focus-visible {
  background: var(--brand-fill-h); color: #fff !important;
}
.nav-cta.active::after { display: none; }

/* ---------- 10. 首屏（信息型 hero） ---------- */
.hero {
  position: relative; overflow: hidden;
  padding: clamp(56px, 7vw, 104px) 0 clamp(48px, 5.5vw, 80px);
  background: linear-gradient(180deg, var(--bg-alt) 0%, #fff 78%);
}
.hero::after {
  content: ''; position: absolute; inset: 0; pointer-events: none; z-index: 0;
  background: radial-gradient(72% 62% at 88% 6%, rgba(0, 176, 154, .10) 0%, rgba(0, 176, 154, 0) 62%);
}
.hero > .container { position: relative; z-index: 1; }
.hero-grid {
  display: grid; grid-template-columns: minmax(0, 1.12fr) minmax(0, .88fr);
  gap: clamp(40px, 5vw, 84px); align-items: center;
}
.hero h1 { max-width: 15ch; margin-top: 2px; }
.hero .lead { margin-top: 26px; max-width: 44ch; }
.hero .btn-row { margin-top: 36px; }
.hero-facts {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px;
  margin-top: clamp(40px, 4.4vw, 56px); padding-top: 26px; border-top: 1px solid var(--line);
}
.hero-facts strong { display: block; color: var(--ink); font-size: .9375rem; font-weight: 600; }
.hero-facts span { font-size: .8125rem; line-height: 1.6; color: var(--muted); }
.hero-media {
  position: relative; border-radius: var(--r-xl); overflow: hidden;
  border: 1px solid var(--line-2); background: var(--dark);
  box-shadow: 0 56px 96px -56px rgba(8, 40, 34, .78), 0 2px 6px rgba(8, 40, 34, .04);
}
/* 影像卡左上角的一线高光，避免深色矩形贴在白底上显得"糊" */
.hero-media::before {
  content: ''; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(180deg, rgba(255, 255, 255, .10) 0%, rgba(255, 255, 255, 0) 22%);
  mix-blend-mode: overlay;
}
.hero-media img {
  width: 100%; aspect-ratio: 5 / 6; object-fit: cover; object-position: center 42%;
  /* 轻微上浮以留出视差余量（--py 由 main.js 按滚动位置写入） */
  transform: scale(1.10) translate3d(0, var(--py, 0px), 0);
}
.hero-media video { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; filter: brightness(1.06) contrast(1.02); }
.hero-media .cap {
  position: absolute; left: 14px; bottom: 14px; display: inline-flex; align-items: center; gap: 8px;
  padding: 7px 13px; border-radius: 999px; font-size: .75rem; letter-spacing: .04em;
  color: #fff; background: rgba(8, 32, 28, .66);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
}
.hero-media .cap::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: var(--brand-bright); }

/* ---------- 11. 内页 hero ---------- */
.page-hero {
  position: relative; overflow: hidden;
  padding: clamp(48px, 6vw, 88px) 0 clamp(56px, 6.4vw, 92px);
  background: linear-gradient(180deg, var(--bg-alt) 0%, #fff 100%);
}
.page-hero .container { position: relative; z-index: 1; }
/* 品牌光晕：给内页首屏一层纵深，低透明度不干扰文字 */
.page-hero::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(88% 72% at 88% 0%, rgba(0, 176, 154, .11) 0%, rgba(0, 176, 154, 0) 62%);
}
.page-hero h1 { max-width: 22ch; }
.page-hero h1 + .lead { margin-top: 20px; }
.page-hero .lead { max-width: 56ch; }
.page-hero .eyebrow { margin-bottom: 14px; }
/* 内页左上角的当前位置：首页 / 栏目 / 当前页（栏目名由 NAV 推导，见 build.py）。
   ① 中段"栏目"是纯文本、不可点击——顶部导航的分组标签本身没有落地页，
      不给面包屑造一个打不开的链接。它的作用是给出"你在哪个栏目"的路径，
      而不是把下面的大标题再说一遍（早期版本只有"首页 / 当前页"，就是复述）。
   ② 当前页用 --text 而不是 --ink：它跟 h1 本来就同字，若再同色，13px 那行
      会成为标题的影子；降一档后这行读作"路径"，重音留给标题。
   ③ 斜杠压到 45% 透明度并给足左右留白，避免"手打斜杠"的毛边感。 */
.breadcrumb { font-size: .8125rem; line-height: 1.5; color: var(--muted); margin-bottom: 22px; letter-spacing: .01em; }
.breadcrumb a { color: var(--muted); }
.breadcrumb a:hover { color: var(--brand-ink); }
/* 中段的"栏目"与"首页"同为辅助色：它是路径的一部分，不是当前页 */
.breadcrumb .crumb-section { color: var(--muted); }
.breadcrumb .crumb-sep { margin: 0 .55em; opacity: .45; }
.breadcrumb .crumb-current { color: var(--text); }

/* ---------- 12. 数据条 ---------- */
/* 与 pFMT 专题的 `.section:has(> .container > .stats)` 用同一个紧凑档，避免同类数据条两套节奏
   （2026-10-10：专题数据条已改用本表的 `.stats` 类名，两侧现在字面上就是同一个组件） */
.statbar { padding: var(--sp-section-tight) 0; border-bottom: 1px solid var(--line); }
/* 数据条层的纹样水印 + 光晕 */
.statbar { position: relative; overflow: hidden; }
.statbar::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(90% 120% at 8% 0%, rgba(0, 176, 154, .09) 0%, rgba(0, 176, 154, 0) 62%);
}
.statbar > .container { position: relative; z-index: 1; }
.band-pattern {
  position: absolute; left: 0; right: 0; bottom: -10%; z-index: 0;
  opacity: .05; pointer-events: none;
}
.band-pattern svg { width: 100%; height: auto; display: block; }
/* 数据条：数字与标签统一为等高单元（标签预留两行，避免 1/2 行混排造成参差） */
.stats { display: grid; grid-template-columns: repeat(4, 1fr); align-items: stretch; }
.stat {
  display: flex; flex-direction: column; justify-content: flex-start;
  padding: 2px 32px; border-left: 1px solid var(--line);
}
.stat:first-child { border-left: 0; padding-left: 0; }
.stat .num {
  font-size: clamp(2rem, 1.15rem + 3vw, 3.1rem); font-weight: 700; line-height: 1.1;
  color: var(--brand-ink); letter-spacing: -.005em;
}
.stat .lbl {
  display: flex; align-items: center;
  margin-top: 12px; font-size: .875rem; line-height: 1.6; color: var(--muted);
  min-height: 3.2em; text-wrap: pretty;
}
/* 含数据条的区块用紧凑档留白 + 一道纹理水印（原在 pfmt.css，2026-10-10 上移：
   它作用的 `.stats` 是共享组件，规则本身就属于这里，主站首页的 `.statbar` 同一节奏）。
   `position: relative` 同时给水印提供定位上下文——水印是绝对定位的。 */
.section:has(> .container > .stats) { position: relative; overflow: hidden; padding: var(--sp-section-tight) 0; }
.section:has(> .container > .stats) > .container { position: relative; z-index: 1; }

/* ---------- 13. 卡片 ---------- */
.card {
  position: relative; background: #fff; border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 34px 34px;
  transition: border-color .3s var(--ease), box-shadow .4s var(--ease), transform .4s var(--ease-out);
}
.card:hover {
  border-color: rgba(0, 176, 154, .55);
  box-shadow: 0 30px 60px -42px rgba(8, 40, 34, .72);
  transform: translateY(-3px);
}
.card h3 { margin-bottom: 10px; }
/* 卡内标题链接（2026-10-14）：资质卡「WDCM 注册」用标题做外链，字色与同组卡片保持一致
   （对齐 pFMT 资质卡 .cert-card h3 a 的口径），hover 才转品牌色 + 下划线，提示可点击。 */
.card h3 a { color: inherit; }
.card h3 a:hover { color: var(--brand-ink); text-decoration: underline; text-underline-offset: 3px; }
.card p { color: var(--muted); font-size: .9375rem; line-height: 1.78; }
/* 卡内图片圆角（原在 pfmt.css，2026-10-10 上移：卡内图片是 .card 这个共享组件的
   一部分，样式不该只对某一组页面生效。实测主站各页目前卡内图片为 0 张，属无变化）。 */
.card img { border-radius: var(--r-sm); }
.card .more {
  display: inline-flex; align-items: center; gap: 7px; margin-top: 20px;
  font-size: .875rem; font-weight: 600; color: var(--brand-ink);
  transition: gap .3s var(--ease-out);
}
.card:hover .more { gap: 12px; color: var(--brand-ink-h); }
.card-link { display: block; color: inherit; }
.card-link:hover { color: inherit; }
/* 卡片出口「了解更多 →」统一定位到卡片右下角：
   含 .more 的卡片转纵向 flex，出口用 margin-top:auto 顶到底部，
   同一行卡片等高，出口因此对齐在同一位置（主站 5 张 + pFMT 4 张共用）。 */
.card:has(> .more) { display: flex; flex-direction: column; }
.card > .more { margin-top: auto; align-self: flex-end; padding-top: 20px; }
.card-icon {
  width: 44px; height: 44px; margin-bottom: 22px; border-radius: 11px;
  background: var(--brand-soft); display: flex; align-items: center; justify-content: center;
  transition: background-color .3s var(--ease), transform .4s var(--ease-out);
}
.card:hover .card-icon { background: var(--brand); transform: translateY(-1px); }
.card:hover .card-icon svg { stroke: #fff; }
.card-icon svg { width: 21px; height: 21px; stroke: var(--brand-ink); stroke-width: 1.7; fill: none; stroke-linecap: round; stroke-linejoin: round; }
/* /knowledgebase/ 的卡片图标统一取自 Phosphor Icons（MIT，视图框 256）：
   ·「核心分析能力」六张卡 —— chart-bar / network / shield-check /
     circles-three / chart-line-up / file-text
   ·「参考数据库体系」六张卡 —— database / path / dna / shield / atom /
     chart-scatter
   路径内联在 build.py 的 CONTENT 里（不加载 JS、不引外链），按 Phosphor 的
   原始几何换算成站内笔画风格（描边宽度 16 → 18，与 24 视图框的 1.7 等值）。
   Phosphor 用 256 视图框而站内其余图标为 24，故描边按 256/24 折算；改图标时
   记得同步这里。 */
.card-icon svg.icon-ph { stroke-width: 18; }
/* Phosphor 填充型图标（`/pfmt/` 「11 / 临床观察」四张卡，2026-10-10）：
   这里用的是 Phosphor 官方 regular 资产的**本形** —— 它本身是填充轮廓
   （16/256 的描边当量 ≈ 站内 24 视图框的 1.5），所以 fill 才是它的正解，
   不能像上面 `.icon-ph` 那样再去描边（描边会把 16 宽的轮廓再胀成 34，糊成一坨）。
   颜色与 hover 变白因此要单独写 fill：`.card-icon svg { stroke: … }` 那两条
   只管了 stroke，管不到 fill。hover 那条必须同时压掉 stroke，否则 specificity
   低于 `.card:hover .card-icon svg`，实心图标会被再描一圈白边。 */
.card-icon svg.icon-ph-fill { fill: var(--brand-ink); stroke: none; }
.card:hover .card-icon svg.icon-ph-fill { fill: #fff; stroke: none; }
.card-icon.big { width: 48px; height: 48px; }
.card-icon.big svg { width: 24px; height: 24px; }

/* 菌株档案卡（probiotics 展示页） */
.strain-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 12px; margin-bottom: 16px; }
.strain-code {
  display: inline-flex; align-items: center; padding: 5px 11px; border-radius: 8px;
  background: var(--brand-soft); color: var(--brand-ink);
  font-size: .9375rem; font-weight: 700; letter-spacing: .04em;
}
.strain-species { font-size: .875rem; color: var(--muted); }
.strain-species i { font-style: italic; }
.strain-meta {
  display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 7px 14px;
  margin: 0 0 16px; padding-bottom: 16px; border-bottom: 1px solid var(--line);
}
.strain-meta dt { font-size: .8125rem; color: var(--muted); white-space: nowrap; }
.strain-meta dd { font-size: .8125rem; color: var(--ink); font-weight: 600; }

/* 菌库筛菌与入藏流程组（/culture-collection/、/probiotics/）
   三张图统一 4:5 画幅；桌面三列，移动端单列。阶段标题落到图下，
   避免深色胶囊压在照片上把影像切碎。 */
.process-gallery {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--sp-gap); margin-top: 38px;
}
.process-gallery figure { min-width: 0; margin: 0; }
.process-gallery__frame {
  position: relative; aspect-ratio: 4 / 5; overflow: hidden;
  border: 1px solid var(--line-2); border-radius: var(--r-lg);
  background: var(--bg-soft);
}
.process-gallery img {
  width: 100%; height: 100%; object-fit: cover;
}
.process-gallery figcaption {
  display: flex; flex-direction: column; gap: 4px; margin-top: 14px;
  color: var(--muted); font-size: .8125rem; line-height: 1.65; text-wrap: pretty;
}
.process-gallery figcaption strong {
  color: var(--ink); font-size: .875rem; font-weight: 600; line-height: 1.4;
}
/* 组图和 4 列指标属于同一叙事，但必须换层：给统计条一条独立分界线，
   同时避免共享的 `.section:has(> .container > .stats)` 把整个图文大段压成
   纯数据条的紧凑档。 */
.screening-stats {
  margin-top: 42px; padding-top: 34px; border-top: 1px solid var(--line-2);
}

/* 菌库数据资产：圆盘横置后取右半圆，靠左作为整块底层背景；
   左侧数据放在半透明面板上，保证数字、标题和说明文字清晰可读。 */
.data-asset {
  position: relative; display: flex; align-items: center;
  min-height: 760px; margin-top: 58px; padding: 24px 0;
  border-top: 1px solid var(--line-2); overflow: hidden;
}
.section.bg-soft:has(> .container > .data-asset) { padding-bottom: 28px; }
.data-asset__copy {
  position: relative; z-index: 2; width: min(640px, 58%);
  padding: 38px 40px;
  border: 1px solid rgba(0, 176, 154, .18); border-radius: 28px;
  background: rgba(247, 250, 249, .82);
  box-shadow: 0 24px 64px -42px rgba(8, 40, 34, .45);
  -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
}
.data-asset .section-head { margin-bottom: 0; padding-top: 0; border-top: 0; }
.data-asset__stats { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 28px 0; margin-top: 30px; }
.data-asset__stats .stat:nth-child(odd) { padding-left: 0; border-left: 0; }
.data-asset__stats .stat:nth-child(even) { padding-left: 28px; }
.data-asset__stats .stat:nth-child(n+3) { padding-top: 26px; border-top: 1px solid var(--line); }
.data-asset__stats .num { font-size: clamp(1.9rem, 1.2rem + 2.2vw, 2.8rem); }
.data-wheel {
  position: absolute; inset: 0; z-index: 0;
  min-width: 0; margin: 0; pointer-events: none;
}
.data-wheel__viewport {
  position: absolute; inset: 0; width: auto; height: auto; overflow: hidden;
}
.data-wheel__rotor {
  position: absolute; top: 50%; left: 0;
  width: min(2100px, 180vw); height: auto; max-width: none;
  border-radius: 50%; opacity: .8;
  transform: translate(-50%, -50%) rotate(var(--wheel-angle, 90deg));
  transform-origin: 50% 50%;
}
.data-wheel.is-spinning .data-wheel__rotor {
  animation: taxonomy-wheel-spin 80s linear infinite;
}
.data-wheel.is-paused .data-wheel__rotor { animation-play-state: paused; }

@keyframes taxonomy-wheel-spin {
  from { transform: translate(-50%, -50%) rotate(var(--wheel-angle, 90deg)); }
  to { transform: translate(-50%, -50%) rotate(calc(var(--wheel-angle, 90deg) + 360deg)); }
}

@media (max-width: 860px) {
  .process-gallery {
    grid-template-columns: 1fr; gap: 28px;
    max-width: 520px; margin-left: auto; margin-right: auto;
  }
  .data-asset { min-height: 760px; padding: 20px 0; }
  .data-asset__copy { width: 100%; padding: 28px 24px; }
  .data-wheel__rotor {
    left: 0; width: 1200px; opacity: .5;
    animation: none !important;
  }
}

/* 圆点列表（卡片内要点） */
.dot-list li {
  position: relative; padding-left: 16px; margin: 9px 0;
  font-size: .9375rem; line-height: 1.7; color: var(--muted);
}
.dot-list li::before {
  content: ''; position: absolute; left: 2px; top: 11px;
  width: 5px; height: 5px; border-radius: 50%; background: var(--brand);
}

.card--brand { background: rgba(255, 255, 255, .05); border-color: rgba(255, 255, 255, .16); }
.card--brand h3 { color: #fff; }
.card--brand p { color: rgba(255, 255, 255, .74); }
.card--brand .card-icon { background: rgba(255, 255, 255, .1); }
.card--brand .card-icon svg { stroke: var(--brand-bright); }
.card--brand .more { color: var(--brand-bright); }
.card--brand:hover { border-color: rgba(255, 255, 255, .5); box-shadow: 0 28px 56px -40px rgba(0, 0, 0, .9); }

/* ---------- 14. 规格网格（01/02/03 三栏，细线分隔） ---------- */
.spec { display: grid; grid-template-columns: repeat(3, 1fr); border-top: 1px solid var(--line-2); border-bottom: 1px solid var(--line-2); }
.spec__item { padding: 38px 36px 40px; border-left: 1px solid var(--line); }
.spec__item:first-child { border-left: 0; padding-left: 0; }
.spec__item:last-child { padding-right: 0; }
.spec__idx {
  display: block; margin-bottom: 20px; font-size: .75rem; font-weight: 700;
  letter-spacing: .18em; color: var(--brand-ink);
}
.spec__item h3 { margin-bottom: 8px; }
.spec__item p { color: var(--muted); font-size: .9375rem; line-height: 1.78; }
/* 益生菌「鉴定 / 筛选 / 保藏」图文三栏：不能复用 .spec 的不对称首尾内边距，
   否则中间列两侧各少 36px，图片会明显比左右两列窄。 */
.process-spec {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--sp-gap); margin-top: 38px; padding: 38px 0 40px;
  border-top: 1px solid var(--line-2); border-bottom: 1px solid var(--line-2);
}
.process-spec__item { display: flex; flex-direction: column; min-width: 0; }
.process-spec__num {
  display: block; margin-bottom: 20px; color: var(--brand-ink);
  font-size: .75rem; font-weight: 700; letter-spacing: .18em;
  font-variant-numeric: tabular-nums;
}
.process-spec__item h3 { margin-bottom: 8px; }
.process-spec__item p { margin-bottom: 28px; color: var(--muted); font-size: .9375rem; line-height: 1.78; }
.process-spec__item figure {
  margin: auto 0 0; border: 1px solid var(--line-2); border-radius: var(--r-lg);
  overflow: hidden; aspect-ratio: 4 / 5; background: var(--bg-soft);
}
.process-spec__item img { width: 100%; height: 100%; object-fit: cover; }
@media (max-width: 860px) {
  .process-spec {
    grid-template-columns: 1fr; gap: 0; padding: 0; border-bottom: 0;
  }
  .process-spec__item { padding: 28px 0; border-bottom: 1px solid var(--line); }
  .process-spec__item:last-child { padding-bottom: 0; border-bottom: 0; }
}

.link-list { border-top: 1px solid var(--line-2); }
.link-list li {
  /* 第一列宽度要容得下最长标签「医疗机构合作（含量化精准FMT）」——
     实测 240px（16px 字号）；原值 15rem(240px) 恰好卡在边界上，
     不同平台字体度量略有差异就折行，而右侧正文列还空着一大片。
     这里给到 17rem(272px)，留约 13% 余量。
     （不能改用 max-content：每个 li 都是独立的 grid 容器，
       max-content 会变成"每行各自量宽"，各行正文起始位置参差。） */
  display: grid; grid-template-columns: minmax(0, 17rem) minmax(0, 1fr); gap: 8px 40px;
  padding: 24px 0; border-bottom: 1px solid var(--line);
  transition: padding-left .3s var(--ease-out);
}
.link-list li:hover { padding-left: 6px; }
.link-list strong { color: var(--ink); font-weight: 600; }
.link-list span { color: var(--muted); font-size: .9375rem; }

/* ---------- 16. 分栏 ---------- */
.split { display: grid; grid-template-columns: 1.02fr .98fr; gap: clamp(32px, 5vw, 64px); align-items: center; }
.split.reverse { grid-template-columns: .98fr 1.02fr; }
.split img { border-radius: var(--r); border: 1px solid var(--line); }

/* ---------- 17. 表格 ---------- */
.table-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--r); }
table { width: 100%; border-collapse: collapse; font-size: .9375rem; }
th, td { padding: 17px 22px; text-align: left; border-bottom: 1px solid var(--line); vertical-align: top; }
thead th {
  background: var(--bg-soft); font-size: .8125rem; font-weight: 600; letter-spacing: .04em;
  color: var(--ink); white-space: nowrap;
}
tbody tr:last-child td { border-bottom: none; }
tbody tr { transition: background-color .2s var(--ease); }
tbody tr:hover { background: var(--brand-tint); }
td strong { color: var(--brand-ink); }
/* 分组行：同一分析模块下的多行归入一个小标题行 */
tbody tr.group-row td {
  background: var(--bg-soft); font-weight: 600; color: var(--brand-ink);
  letter-spacing: .01em;
}
/* 分析模块清单表：模块列定宽；窄屏改为按比例，让内容列拿到更多宽度
   （两列表格整体放得下，不触发横向滚动） */
.col-module { width: 196px; }

/* ---------- 18. 标签 / 徽章 / 提示 ---------- */
.refs { margin: 0; padding: 0; list-style: none; counter-reset: ref; }
.refs li {
  position: relative; padding-left: 30px; margin: 12px 0;
  font-size: .875rem; line-height: 1.78; color: var(--muted);
  counter-increment: ref;
}
.refs li::before {
  content: "[" counter(ref) "]"; position: absolute; left: 0; top: 0;
  font-size: .8125rem; font-weight: 600; color: var(--brand-ink);
  font-variant-numeric: tabular-nums;
}
.refs li i { color: var(--text); }
sup a { color: var(--brand-ink); font-weight: 600; text-decoration: none; }
sup a:hover { text-decoration: underline; }

.chips { display: flex; flex-wrap: wrap; gap: 10px; }
.chip {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 8px 15px; border-radius: 999px;
  background: #fff; border: 1px solid var(--line-2);
  font-size: .875rem; font-weight: 600; color: var(--ink);
}
.chip::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: var(--brand); flex: none; }
.section--dark .chip, .section--brand .chip { background: rgba(255, 255, 255, .07); border-color: rgba(255, 255, 255, .18); color: #fff; }

.badge { display: inline-flex; align-items: center; gap: 6px; padding: 5px 12px; border-radius: 999px; font-size: .8125rem; font-weight: 600; }
.badge.ok { background: var(--ok-soft); color: var(--ok-ink); }
.badge.warn { background: var(--warn-soft); color: var(--warn-ink); }
.badge.danger { background: var(--danger-soft); color: var(--danger-ink); }
.badge.info { background: var(--info-soft); color: var(--info-ink); }

.callout {
  background: var(--brand-tint); border: 1px solid var(--line);
  border-left: 3px solid var(--brand); border-radius: var(--r-sm);
  padding: 18px 22px; font-size: .9375rem; color: var(--text);
}
.disclaimer {
  font-size: .8125rem; line-height: 1.7; color: var(--muted);
  background: var(--bg-soft); border-radius: var(--r-sm); padding: 16px 20px;
}

/* 资质凭证网格（细线格，像证书清单） */
.creds {
  display: grid; grid-template-columns: repeat(3, 1fr);
  border-top: 1px solid var(--line-2); border-left: 1px solid var(--line-2);
  background: #fff;
}
.creds li {
  display: flex; align-items: center; gap: 11px;
  padding: 20px 22px; border-right: 1px solid var(--line); border-bottom: 1px solid var(--line);
  font-size: .9375rem; font-weight: 600; color: var(--ink); line-height: 1.5;
}
.creds li::before { content: ''; flex: none; width: 6px; height: 6px; border-radius: 50%; background: var(--brand); }

/* ---------- 19. 时间线 / 步骤 ---------- */
.steps { display: grid; gap: 0; }
.step { position: relative; display: grid; grid-template-columns: 44px 1fr; gap: 22px; padding-bottom: 30px; }
.step:not(:last-child)::before {
  content: ''; position: absolute; left: 21px; top: 46px; bottom: 0; width: 2px; background: var(--line);
}
.step .idx {
  position: relative; z-index: 1; width: 44px; height: 44px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: #fff; border: 1.5px solid var(--brand);
  color: var(--brand-ink); font-weight: 700; font-size: .9375rem;
}
.step h3 { margin-bottom: 6px; font-size: 1rem; line-height: 1.55; }
.step p { color: var(--muted); font-size: .9375rem; }
.section--dark .step:not(:last-child)::before, .section--brand .step:not(:last-child)::before { background: rgba(255, 255, 255, .2); }
.section--dark .step .idx, .section--brand .step .idx { background: var(--dark); border-color: var(--brand-bright); color: var(--brand-bright); }

/* 宽屏改成横向里程碑导轨：竖排时右侧会空出三分之二版面，
   横排后标题与刻度连线一起铺满容器，读者一眼看完整条时间/流程轴。
   auto-fit + minmax(0,1fr) 保证无论 4/5/6 段都排成一行，不会出现尾行孤项。 */
@media (min-width: 1200px) {
  .steps { grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); gap: 0 30px; }
  .step { display: block; padding-bottom: 0; }
  .step:not(:last-child)::before {
    left: 54px; right: -30px; top: 21px; bottom: auto;
    width: auto; height: 2px; background: var(--line-2);
  }
  .step .idx { margin-bottom: 20px; }
  .step h3 { font-size: .9375rem; line-height: 1.45; margin-bottom: 8px; }
  .step p { font-size: .875rem; line-height: 1.7; }
}

/* 「四步分析流程」步内配图（/knowledgebase/，2026-10-10）
   这几张是老站深灰底（#4b5154）时期的数据插画，主体色 #CFCFCF——只在深色区块上读得出来，
   故该节用 `.section--dark` 承载（组件自带 .step 的反白规则，不必另写一套）。
   四张比例差得远（8.5:1 ～ 1.9:1），所以统一限高；宽屏四步等高，配图压到各自列底部对齐。
   **必须写在上面的 `@media (min-width:1200px)` 之后**：那段里有 `.step { display:block }`
   与 `.step p { font-size }`，同特异度时后者胜出——写在前面会被静默盖掉。 */
.step-figure { display: block; margin-top: 18px; width: auto; max-width: 100%; max-height: 200px; }
/* 最后一步的配图（报告）压到区块底边，并按原始尺寸显示——比其余三张高一档，
   作为整条流程的"产出"收尾。宽度不放大到满栏：素材 920px（@2x 1840），
   再拉宽就等于把原图放大，违反本项目的素材口径（不得拉伸/放大原图）。 */
.step--media:last-child { padding-bottom: 0; }
.step--media:last-child .step-figure { max-height: none; }
/* 竖线：**每一步各一段**，从本步圆标下缘落到本步与下一步之间的那条分隔线上，
   末步的一段向下渐隐（后面没有下一步了）。

   为什么把线段挂在**文字列**（`.step--media > div:last-child`）而不是步骤盒子上：
   步骤盒子的顶边在圆标**上方**（第 2 步起还有 40px 分隔留白），线段写死 `top:46px`
   就会比圆标高出一截——这就是之前"数字上方出头／圆标上方有断缝"的来源。
   文字列的顶边恰好与圆标的顶边齐平，`top:46px` 因此天然落在圆标下缘（44px 圆标 + 2px 缝）。
   `left:-44px` 把线挪回圆标中心（文字列左边距 = 44px 圆标 + 22px 栅格间距）。
   站点默认的 `.step::before` 连线在这节关掉，避免两套线并存。 */
.steps--media .step::before { content: none; }
.step--media > div:last-child { position: relative; }
.step--media > div:last-child::before {
  content: ''; position: absolute; left: -45px; top: 46px; bottom: -46px; width: 2px;
  background: rgba(255, 255, 255, .20); pointer-events: none;
}
/* 末步：线到本步底部为止，并且向下渐隐 */
.step--media:last-child > div:last-child::before {
  bottom: 0;
  background: linear-gradient(to bottom,
    rgba(255, 255, 255, .20) 0%, rgba(255, 255, 255, .12) 34%, rgba(255, 255, 255, 0) 90%);
}
@media (max-width: 1199px) {
  /* 竖排（44px 圆标 + 文字列）：配图给满文字列宽度，高度由比例决定 */
  .step-figure { width: 100%; max-height: none; }
}
/* ≥900px：每步的**标题与说明并排一行**，配图另起一行。
   图幅够宽，一行读完再看图比"标题一行、说明一行"紧凑，这一节因此矮约 30px/步。
   标题列给固定宽度（7.6em ≈ 114px，容得下最长的"预测模型及报告"），
   让四条说明的左缘对齐——用 auto 的话会按各标题字数错开一两个字。 */
@media (min-width: 900px) {
  /* 标题与说明并排后文字只有一行（≈22px），而圆标是 44px——不处理的话文字顶对齐、
     看起来浮在圆标上半部。这里把文字行下沉 (44 − 行高)/2 ≈ 11px，让**标题中心与圆标中心
     对齐**；同时把配图的上间距从 16px 收到 5px，抵消这 11px，配图位置与"压底边"都不变。 */
  .step--media > div:last-child { display: grid; grid-template-columns: 7.6em minmax(0, 1fr); gap: 4px 18px; align-items: baseline; padding-top: 11px; }
  .step--media > div:last-child > h4 { grid-column: 1; margin-bottom: 0; }
  .step--media > div:last-child > p { grid-column: 2; margin: 0; }
  .step--media > div:last-child > .step-figure { grid-column: 1 / -1; margin-top: 5px; }
  /* 四步之间的分隔：不是实线，而是从左（竖线那侧）向右**淡出**的发丝线，
     给段落感又不把版面切成四格。深底上取 28% → 10% → 0 的白。 */
  .step--media + .step--media { padding-top: 40px; }
  .step--media + .step--media::after {
    content: ''; position: absolute; left: 21px; right: 0; top: 0; height: 1px;
    background: linear-gradient(90deg,
      rgba(255, 255, 255, .28) 0%, rgba(255, 255, 255, .10) 42%, rgba(255, 255, 255, 0) 86%);
  }
}
@media (min-width: 1200px) {
  /* 带配图的四步（/knowledgebase/）在宽屏**也走竖排**：每步一行、文字在上、配图在下。
     不做成"文左图右"的原因：四张比例差 4.5 倍（8.5:1 ～ 1.9:1），并排时行高由最高的那张
     （report）决定，其余行的文字会悬在一片空白里；文字横跨整行压在配图上方就没有这个问题，
     配图也能放大到 220px 高（report 仍比原来 271px 宽的一版大一截）。

     选择器一律要挂在 `.steps--media`/`.step--media` 上，别写裸 `.steps`：上面那段
     通用横向导轨也是 `@media (min-width:1200px)`，裸类会把 /linenrich/ /about/ /news/
     /quantitest/ 的工作流程一起改回单列，渲染成「圆标 + 一条向右戳出去的横线 +
     标题挤在圆标下方」的错位（2026-10-10 修复）。 */
  .steps--media { grid-template-columns: 1fr; gap: 0; }
  .step--media { display: grid; grid-template-columns: 44px minmax(0, 1fr); gap: 0 22px; padding-bottom: 46px; }
  .step--media .step-figure { margin-top: 20px; padding: 0; max-height: 220px; width: auto; max-width: 100%; }
}

/* ---------- 20. 招聘 / 联系 ---------- */
.job { border: 1px solid var(--line); border-radius: var(--r); padding: 26px 30px; margin-bottom: 14px; background: #fff; }
.job h3 { font-size: 1.0625rem; }
.job .job-meta { font-size: .8125rem; color: var(--muted); margin: 8px 0 14px; }
.job ul { margin-top: 12px; }
.job ul li { position: relative; padding-left: 18px; color: var(--muted); font-size: .9375rem; margin: 5px 0; }
.job ul li::before { content: ''; position: absolute; left: 2px; top: 12px; width: 5px; height: 5px; border-radius: 50%; background: var(--brand); }

.contact-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; }
.contact-card { border: 1px solid var(--line); border-radius: var(--r); padding: 30px 32px; background: #fff; }
.contact-card h3 { margin-bottom: 8px; }
.contact-card a { font-weight: 600; }
/* 双栏联系卡（/contact/ 04）：两栏内容行数不等，等高拉伸后短的一侧底部
   会空出大片留白。让它成为纵向 flex，把补充说明用 margin-top:auto 压到底，
   空出来的位置就变成"卡片间距"而不是"漏排"。 */
.contact-card--col { display: flex; flex-direction: column; }
.contact-card--col .contact-list { margin-bottom: 22px; }
.contact-foot {
  margin-top: auto; padding-top: 16px; border-top: 1px solid var(--line);
  font-size: .8125rem; line-height: 1.7; color: var(--muted);
}
.contact-list { margin-top: 18px; }
.contact-list p { color: var(--muted); font-size: .9375rem; margin: 7px 0; }
/* 分行内注（如电话旁的"工作日 9:00–18:00"）：跟在值后面、降到注脚尺度，
   比单独占一行更贴合"这条信息的限定条件"的语义。 */
.contact-note { margin-left: 10px; font-size: .8125rem; }
/* 快捷入口列表：细线分隔 + 右侧箭头随 hover 前移 */
.quick-links { margin-top: 14px; }
.quick-links li + li { border-top: 1px solid var(--line); }
.quick-links a {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 12px 0; font-weight: 600;
}
.quick-links a::after {
  content: '→'; flex: none; color: var(--brand); font-weight: 400;
  transition: transform .3s var(--ease-out);
}
.quick-links a:hover::after { transform: translateX(4px); }

/* ---------- 20b. 表单（联系我们页） ---------- */
.form-card-wrap {
  border: 1px solid var(--line); border-radius: var(--r);
  background: #fff; padding: 30px 32px;
}
.form-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 22px; }
.form-group { margin-bottom: 18px; }
.form-group--full { grid-column: 1 / -1; }
.form-group label { display: block; margin-bottom: 7px; font-size: .875rem; font-weight: 600; color: var(--ink); }
.form-group input, .form-group select, .form-group textarea {
  width: 100%; padding: 12px 14px; font: inherit; font-size: .9375rem; line-height: 1.45;
  color: var(--text); background: #fff;
  border: 1.5px solid var(--line-2); border-radius: 10px;
  transition: border-color .18s, box-shadow .18s;
}
/* 输入框与下拉框统一到同一高度：<select> 的固有高度各浏览器算法不同，
   不锁死时它会比同排 input 高出 2–6px，整排输入框因此对不齐。 */
.form-group input, .form-group select { min-height: 50px; }
/* <select> 的原生外观各浏览器差异极大（Safari 的圆角渐变按钮、Windows 上
   另一套箭头与内边距，缩放下还会出现发虚的双层描边）。统一去掉原生外观，
   换成与设计系统同源的 SVG 折角箭头，箭头颜色取品牌墨绿。 */
.form-group select {
  appearance: none; -webkit-appearance: none;
  padding-right: 44px; cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%230A6B5C' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 14px center; background-size: 16px 16px;
}
.form-group select::-ms-expand { display: none; }
/* 未选择时（placeholder 选项处于选中态）文字降为辅助色，
   避免"请选择合作类型"看起来像一个已经填好的值。 */
.form-group select:required:invalid { color: var(--muted); }
.form-group select option { color: var(--text); }
.form-group textarea { resize: vertical; min-height: 120px; line-height: 1.7; }
.form-group input:focus, .form-group select:focus, .form-group textarea:focus {
  outline: none; border-color: var(--brand);
  box-shadow: 0 0 0 4px rgba(0, 176, 154, .12);
}
/* 必填星号：色值走语义令牌；字号与基线锁死，避免各浏览器把 * 渲染成
   忽大忽小、忽上忽下的孤星（这是"表单必填项在某些浏览器特别丑"的主因）。 */
.required { color: var(--danger-ink); font-size: .9em; font-weight: 700; margin-left: 3px; vertical-align: .08em; }
.form-footnote { margin-top: 14px; font-size: .8125rem; line-height: 1.75; color: var(--muted); }

/* ---------- 21. CTA 带（全站统一一条：单列左对齐卡） ---------- */
/* 单按钮不再用「左文案 + 右按钮」两栏（右列会空出一大片），
   改为单列：标题 → 正文 → 按钮；右下的品牌纹样负责补足空白，
   底色用 --dark-2（比页脚的 --dark 略亮），避免页尾出现两块同色黑板。 */
.cta-band {
  position: relative; overflow: hidden;
  background: var(--dark-2); color: rgba(255, 255, 255, .78);
  border-radius: var(--r-xl);
  padding: clamp(40px, 4.4vw, 60px) clamp(32px, 4vw, 56px);
  box-shadow: 0 40px 80px -56px rgba(8, 40, 34, .9);
}
.cta-band::before {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(80% 130% at 92% 8%, rgba(0, 176, 154, .22) 0%, rgba(0, 176, 154, 0) 62%);
}
.cta-band > * { position: relative; z-index: 1; }
.cta-band h2 { color: #fff; max-width: 24ch; font-size: clamp(1.5rem, 2.2vw, 1.9rem); }
.cta-band p { color: rgba(255, 255, 255, .74); margin-top: 12px; max-width: 44ch; }
.cta-band .btn-row { justify-content: flex-start; margin-top: 30px; }
.cta-band .band-pattern { position: absolute; opacity: .1; bottom: -14%; }

/* ---------- 22. 页脚 ---------- */
.site-footer {
  position: relative; overflow: hidden;
  background: var(--dark); color: rgba(255, 255, 255, .68);
  padding: clamp(64px, 6.4vw, 96px) 0 clamp(72px, 7.4vw, 104px);
  border-top: 2px solid var(--brand);
}
.site-footer .container { position: relative; z-index: 1; }
.site-footer a { color: rgba(255, 255, 255, .68); transition: color .2s var(--ease); }
.site-footer a:hover { color: #fff; }
.site-footer ul a { text-decoration: underline; text-decoration-color: transparent; text-underline-offset: 3px; transition: color .2s var(--ease), text-decoration-color .25s var(--ease); }
.site-footer ul a:hover { text-decoration-color: rgba(255, 255, 255, .5); }
/* 深底页脚：纹样压在页脚底部当背景（与 .hero-pattern 同一手法），
   不再在版权行之后单占一条尾带，页尾因此收紧约 150px */
.footer-pattern {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 0;
  overflow: hidden; opacity: .14; pointer-events: none;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 7%, #000 93%, transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 7%, #000 93%, transparent 100%);
}
.footer-pattern svg { display: block; width: 100%; height: auto; }
.footer-grid { display: grid; grid-template-columns: 1.5fr 1fr 1fr 1.2fr; gap: clamp(28px, 3.4vw, 48px); }
.footer-brand { display: inline-flex; align-items: center; gap: 11px; margin-bottom: 18px; color: var(--brand); }
.footer-brand svg { height: 32px; width: auto; flex: none; display: block; }
.site-footer .footer-brand { color: #fff; }   /* 深底用白色版（品牌手册） */
.site-footer .footer-brand:hover { color: var(--brand-bright); }
.site-footer h2 { color: #fff; font-size: .875rem; letter-spacing: .04em; line-height: 1.55; margin-bottom: 16px; }
.site-footer ul li { margin: 9px 0; font-size: .875rem; line-height: 1.7; }
.footer-bottom {
  margin-top: clamp(36px, 4vw, 52px); padding-top: 22px;
  border-top: 1px solid rgba(255, 255, 255, .12);
  display: flex; flex-wrap: wrap; justify-content: space-between;
  /* 底对齐：右侧备案块与左侧法务块的最后一行（免责声明）对齐，而不是与版权行齐 */
  align-items: flex-end;
  gap: 12px 24px;
  font-size: .8125rem; color: rgba(255, 255, 255, .5);
}
.footer-bottom a { color: rgba(255, 255, 255, .5); }
/* 左列：版权 / 隐私政策 / 免责声明，三行一组（页脚的"法务区"） */
.footer-legal { min-width: 0; }
/* color 必须显式 inherit：全局有 `p { color: var(--text) }`（深灰 #39423f），
   不覆盖就会落到深色页脚上——对比度仅 1.67，几乎不可读（Lighthouse 2026-10-10 实测）。
   继承 .footer-bottom 的 rgba(255,255,255,.5) 后为 5.13，且与改版前观感一致。 */
.footer-legal p { margin: 0; color: inherit; }
.footer-legal p + p { margin-top: 6px; }
/* 免责声明：字号小一档做弱化即可，颜色不能再用 42%（实测 4.01 < 4.5 不达标） */
.footer-legal .footer-note { font-size: .75rem; line-height: 1.7; color: rgba(255, 255, 255, .5); }
/* 右列：备案块整体不参与压缩、也不折行（图标与编号必须同处一行，图标在链接内部）。
   `flex: none` 挡的是被压窄；`white-space: nowrap` 挡的是块内自行折行——
   两者都要，否则在某些页面它会折成"图标一行、编号一行"。窄屏由外层
   flex-wrap 把整块挪到下一行，不会横向溢出（实测 420px 仍无溢出）。 */
.footer-beian { flex: none; white-space: nowrap; }
/* 公安备案图标：官方 20×20 PNG，按《网站备案办事指南》要求显示于备案编号之前。
   深色页脚上不需要反白——图标本身是金/红彩色，反白会把"公"字糊掉。
   vertical-align 微调让图标视觉上贴着中文行中，而不是被行高顶到上方。
   **display 必须显式写成 inline-block**：站内有全局 `img { display: block }`（见本文
   第 3 节），不覆盖就会让图标独占一行、把编号挤到下一行（2026-10-10 踩过）。 */
.footer-bottom .beian-icon { display: inline-block; width: 14px; height: 14px; vertical-align: -2px; margin-right: 5px; }

/* ---------- 23. 视频 ---------- */
.brandfilm { position: relative; overflow: hidden; background: var(--dark); isolation: isolate; }
.brandfilm video {
  display: block; width: 100%; aspect-ratio: 21 / 9; object-fit: cover;
  transform: scale(1.14) translate3d(0, var(--py, 0px), 0);
  filter: brightness(1.14) contrast(1.06);
  will-change: transform;
}
.brandfilm .brandfilm-scrim {
  position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(6, 20, 18, .24) 0%, rgba(6, 20, 18, .04) 42%, rgba(6, 20, 18, .72) 100%);
}
.brandfilm .brandfilm-cap {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 0 24px clamp(18px, 3vw, 34px);
}
.brandfilm .brandfilm-cap .container { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.brandfilm .tag {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 7px 14px; border-radius: 999px; font-size: .75rem; letter-spacing: .06em;
  color: #fff; background: rgba(8, 32, 28, .58);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
}
.brandfilm .tag::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: var(--brand-bright); }
.brandfilm .tag--plain { background: transparent; color: rgba(255, 255, 255, .78); letter-spacing: .04em; }
.brandfilm .tag--plain::before { display: none; }

.video-band { position: relative; border-radius: var(--r); overflow: hidden; border: 1px solid var(--line); background: var(--dark); }
.video-band video { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; }
.video-figure { position: relative; margin: 0; border-radius: var(--r); overflow: hidden; border: 1px solid var(--line); background: var(--dark); }
.video-figure video { width: 100%; object-fit: cover; }
.video-square video { aspect-ratio: 1 / 1; }
.video-figure .video-cap { padding: 18px 20px; background: #fff; margin: 0; }
.video-grid { display: grid; gap: 24px; }
.video-grid.cols-2 { grid-template-columns: repeat(2, 1fr); }
.video-grid.cols-3 { grid-template-columns: repeat(3, 1fr); }
.video-cap { margin-top: 14px; font-size: .875rem; color: var(--muted); }
.video-card { border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; background: #fff; }
.video-card video { width: 100%; display: block; aspect-ratio: 16 / 9; object-fit: cover; background: var(--dark); }
.video-card .video-card-body { padding: 24px 26px; }
.video-card h3 { margin-bottom: 8px; }
.video-card p { color: var(--muted); font-size: .9375rem; }

/* ---------- 23b. 页内吸顶目录条（.toc-*）----------
   2026-10-10 由 theme/pfmt.css 上移进全站设计系统。此前它只服务 pFMT 三页
   （专题首页分节 / FAQ 分类 / 白皮书章节），法务页 /privacy/ 重做后是第四个
   使用方；组件留在页级文件里，主站页面就拿不到，而同一组件写第二份必然与
   专题页漂移（见 设计规范.md §6.12 的样式分层规则）。 */
.toc-bar {
  position: sticky; top: var(--header-h, 72px); z-index: 20;
  background: rgba(255, 255, 255, .92);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid var(--line);
}
.toc-inner {
  display: flex; justify-content: center;
  width: 100%; max-width: var(--maxw); margin: 0 auto; padding: 10px 24px;
}
/* 凹槽（track）：把全部分类收在一个整体里，避免左侧一排小胶囊 + 右侧大片空白的失衡感 */
.toc-track {
  display: flex; align-items: center; gap: 2px;
  max-width: 100%; padding: 4px; border-radius: 999px;
  background: var(--bg-soft); border: 1px solid var(--line);
  box-shadow: inset 0 1px 2px rgba(8, 40, 34, .04);
  overflow-x: auto; overscroll-behavior-x: contain;
  scrollbar-width: none; -ms-overflow-style: none;
}
.toc-track::-webkit-scrollbar { display: none; }
.toc-link {
  padding: 9px 20px; border-radius: 999px;
  font-size: .9375rem; font-weight: 500; line-height: 1.35;
  color: var(--muted); white-space: nowrap;
  transition: background-color .18s, color .18s, box-shadow .18s;
}
.toc-link:hover { color: var(--brand-ink); background: var(--brand-tint); }
.toc-link.active {
  background: #fff; color: var(--brand-ink); font-weight: 600;
  box-shadow: 0 1px 2px rgba(8, 40, 34, .08), 0 8px 20px -14px rgba(8, 40, 34, .5);
}

/* ---------- 23c. 法务 / 文档页（/privacy/）----------
   阅读列 940px（与白皮书 .wp-wrap 同宽，全站文档页共用一个「纸面」宽度）：
   法务条款是连续长文，行宽超过约 40 个汉字就开始丢行。列宽与首屏容器
   （1240px）刻意不同——文档页是「纸」，页面是「版面」，两者不是一回事。 */
.doc-wrap { width: min(940px, 100% - 2 * var(--gutter)); margin: 0 auto; }
/* 条款分节之间用 --sp-section-tight 收紧，不套页面级的 --sp-section：
   那是「区块带」之间的呼吸，连续十几条法务条款照搬会散架。 */
.doc-section + .doc-section { margin-top: var(--sp-section-tight); }
.doc-section > .section-head { margin-bottom: clamp(22px, 2.4vw, 32px); }
.doc-section p + p { margin-top: 16px; }
/* 条款内的要点清单：与正文同尺度（正文 16–17px），圆点用品牌绿。
   不套卡片用的 .dot-list —— 那是 15px 辅助尺度，放进长文里比正文小一号，
   整段读起来发虚。 */
.doc-list { margin: 18px 0 0; }
.doc-list li {
  position: relative; padding-left: 22px; margin: 12px 0; line-height: 1.85;
}
.doc-list li::before {
  content: ''; position: absolute; left: 2px; top: .78em;
  width: 6px; height: 6px; border-radius: 50%; background: var(--brand);
}
/* 锚点落位：导航那一半由 html 的 scroll-padding-top: var(--header-pad) 负责，
   这里只补 **吸顶目录条** 那一半（桌面 ≈ 62px，与 pFMT 专题同一取值），
   使落点停在目录条下沿而不是被它盖住。 */
.doc-section[id] { scroll-margin-top: 62px; }

/* ---------- 24. 响应式 ---------- */
@media (max-width: 1080px) {
  .hero-grid, .split, .split.reverse, .cta-band { grid-template-columns: 1fr; gap: 36px; }
  .hero h1 { max-width: 20ch; }
  .cta-band .btn-row { justify-content: flex-start; }
  .grid-4, .grid-3 { grid-template-columns: repeat(2, 1fr); }
  .footer-grid { grid-template-columns: repeat(2, 1fr); gap: 32px; }
  .contact-grid { grid-template-columns: 1fr; }
  /* 页内目录条改 static：吸顶条消失，锚点避让只剩导航那一半（--header-pad） */
  .toc-bar { position: static; }
  .toc-inner { justify-content: flex-start; padding: 10px 16px; }
  .toc-track { flex-wrap: wrap; border-radius: 18px; row-gap: 2px; }
  .toc-link { padding: 8px 15px; font-size: .875rem; }
  /* ≤1080px 目录条改 static：额外避让归零，只剩导航那一半 */
  .doc-section[id] { scroll-margin-top: 0; }
  .section-head--split { grid-template-columns: 1fr; align-items: start; }
  /* 单列后右侧不再是"页边注"，回到正文尺度 */
  .section-head--split .lead { margin-top: 16px; font-size: 1rem; line-height: 1.85; }
  .spec { grid-template-columns: 1fr; border-bottom: 0; }
  .spec__item { border-left: 0; border-bottom: 1px solid var(--line); padding: 28px 0; }
  .creds { grid-template-columns: repeat(2, 1fr); }
  .link-list li { grid-template-columns: 1fr; gap: 4px; }
}

@media (max-width: 860px) {
  html { font-size: 15px; }
  /* 窄屏栏宽常放不下一整条无标点标题，keep-all 会把末行挤成一个孤字
     （如「…核心特 / 性」），比正常的汉字间断行更难看，故窄屏回到常规断行 */
  h2, h3, h4 { word-break: normal; overflow-wrap: break-word; }
  /* 移动端不收缩导航（下拉菜单按导航高度定位），避免菜单与导航错位 */
  html.nav-compact { --header-h: 72px; }
  .nav-links {
    position: fixed; left: 0; right: 0; top: var(--header-h);
    flex-direction: column; align-items: stretch; gap: 0;
    margin: 0; padding: 12px 20px 24px;
    background: #fff; border-bottom: 1px solid var(--line);
    box-shadow: 0 24px 48px -28px rgba(8, 40, 34, .5);
    transform: translateY(-130%); visibility: hidden;
    transition: transform .28s ease, visibility .28s;
    max-height: calc(100dvh - var(--header-h)); overflow-y: auto;
  }
  .nav-links > a, .nav-group > .nav-group-label {
    width: 100%; padding: 14px 4px; border-radius: 0;
    border-bottom: 1px solid var(--line); font-size: 1rem;
    justify-content: space-between;
  }
  .nav-links > a.active::after { display: none; }
  .nav-links > a.nav-cta {
    margin-top: 16px; border-bottom: 0; justify-content: center;
    border-radius: 9px; padding: 13px 20px !important;
  }
  .nav-group { width: 100%; }
  .nav-group:hover > .nav-group-label { background: transparent; }
  .nav-dropdown {
    position: static; transform: none; opacity: 1; visibility: visible; display: none;
    min-width: 0; border: 0; box-shadow: none; background: transparent;
    padding: 2px 0 6px 14px; margin: 0;
  }
  .nav-dropdown a { padding: 11px 12px; border-bottom: 1px solid var(--line); border-radius: 0; color: var(--muted); }
  .nav-group-toggle:checked ~ .nav-dropdown { display: flex; }
  .nav-group-toggle:checked ~ .nav-group-label .nav-caret { transform: rotate(180deg); }
  /* 三级菜单：移动端改为 checkbox 展开 */
  .nav-sub-row {
    border-radius: 0; border-bottom: 1px solid var(--line); gap: 0;
  }
  .nav-sub-label {
    padding: 11px 12px; font-size: .9375rem; color: var(--muted);
  }
  .nav-sub-caret {
    padding: 11px 12px; min-width: 46px; justify-content: center; align-self: stretch;
    color: var(--muted);
  }
  .nav-sub:hover > .nav-sub-row, .nav-sub:focus-within > .nav-sub-row { background: transparent; }
  .nav-sub-dropdown {
    display: none; margin: 0; padding: 0 0 4px 16px; border-left: 0;
  }
  .nav-sub:hover > .nav-sub-dropdown, .nav-sub:focus-within > .nav-sub-dropdown { display: none; }
  .nav-sub-toggle:checked ~ .nav-sub-dropdown { display: flex; }
  .nav-sub-toggle:checked ~ .nav-sub-row .nav-caret { transform: rotate(180deg); }
  .nav-sub-dropdown a { padding: 10px 12px; border-bottom: 1px solid var(--line); border-radius: 0; }
  /* 汉堡开关同样要“不可见但可聚焦”，否则移动端键盘用户打不开菜单 */
  .nav-toggle {
    display: block; position: absolute;
    top: calc((var(--header-h) - 42px) / 2); right: var(--gutter);
    width: 42px; height: 42px; margin: 0; opacity: 0; pointer-events: none;
  }
  .nav-toggle:focus-visible + .nav-toggle-label {
    outline: 2px solid var(--brand); outline-offset: 2px; border-radius: 8px;
  }
  .nav-toggle-label {
    display: flex; flex-direction: column; justify-content: center; gap: 5px;
    /* 三条线右对齐，使图标右缘与内容右边界齐平（与左侧 logo 对称）；
       父级 flex-end 只影响点击区内的图标落位，命中区仍为 42×42 */
    align-items: flex-end;
    width: 42px; height: 42px; cursor: pointer; flex: none;
  }
  .nav-toggle-label span { display: block; width: 22px; height: 2px; background: var(--ink); border-radius: 2px; transition: .25s; }
  .nav-toggle:checked ~ .nav-toggle-label span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
  .nav-toggle:checked ~ .nav-toggle-label span:nth-child(2) { opacity: 0; }
  .nav-toggle:checked ~ .nav-toggle-label span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
  .nav-toggle:checked ~ .nav-links { transform: translateY(0); visibility: visible; }
  .nav { gap: 12px; }
  /* 汉堡按钮靠右上角：移动端 .nav-links 是 fixed（脱离文档流），
     原先由（空的）.nav-right 吃掉 margin-left:auto 的剩余空间，
     导致汉堡紧贴 logo、右上角留白。改为让汉堡自身靠右，
     .nav-right（语言切换等）留在汉堡左侧，视觉顺序 logo — 语言 — 汉堡 */
  .nav-toggle-label { order: 3; margin-left: auto; }
  .nav-right { order: 2; margin-left: 0; }

  .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; }
  .creds { grid-template-columns: 1fr; }
  /* 窄屏下表头/单元格会被压成"每列三四个字"（最典型的是 /contact/ 的在招职位表
     与 /knowledgebase/ 的对比表）。给三列及以上的表格一个可横向滚动的最小宽度；
     两列表格本身放得下，:has() 让它们保持原样、不触发滚动。 */
  .table-wrap:has(th:nth-child(3)) table { min-width: 620px; }
  /* 两列的分析模块清单表：窄屏不横向滚动，改为按比例压缩模块列 */
  .col-module { width: 34%; }
  .stats { grid-template-columns: repeat(2, 1fr); gap: 28px 0; }
  .stat { padding: 0 20px; }
  .stat:nth-child(odd) { border-left: 0; padding-left: 0; }
  .stats--cards .stat:nth-child(odd) { padding-left: 24px; }
  .hero-facts { grid-template-columns: 1fr; gap: 14px; }
  .video-grid.cols-2, .video-grid.cols-3 { grid-template-columns: 1fr; }
  .video-21-9 video { aspect-ratio: 16 / 9; }
  .hero-media img { aspect-ratio: 4 / 3; object-position: center 38%; }
  .footer-grid { grid-template-columns: 1fr; gap: 32px; }
}

@media (max-width: 480px) {
  .card { padding: 26px 24px; }
  .job { padding: 22px 22px; }
  .contact-card { padding: 26px 24px; }
  .nav-brand svg { height: 32px; }
  /* 表单在两列时输入框过窄（占位文字被裁切），窄屏改为单列 */
  .form-grid { grid-template-columns: 1fr; gap: 0; }
}

/* ---------- 25. 动效系统 ---------- */
/* 三档动效，全部可降级：
   ① 首屏入场编排（纯 CSS，随 .hero / .page-hero 直接播出）
   ② 滚动浮现 .reveal -> .is-visible（由 main.js 按需挂类，无 JS 时内容照常显示）
   ③ 微交互（hover / active / 图标 / 箭头）
   统一缓动见 :root 的 --ease / --ease-out，时长集中在 .5s–.9s 之间，
   避免"什么都在动"的廉价感。 */

@keyframes rise-in {
  from { opacity: 0; transform: translate3d(0, 20px, 0); }
  to   { opacity: 1; transform: none; }
}
@keyframes media-in {
  from { opacity: 0; transform: translate3d(0, 28px, 0) scale(.99); }
  to   { opacity: 1; transform: none; }
}
@keyframes pattern-in {
  from { opacity: 0; transform: translate3d(0, 16px, 0); }
  to   { opacity: .20; transform: none; }
}

@media (prefers-reduced-motion: no-preference) {
  /* ① 首页首屏：文字自上而下依次落位，影像卡稍后进场 */
  .hero .hero-grid > div > * { animation: rise-in .85s var(--ease-out) both; }
  .hero .hero-grid > div > *:nth-child(2) { animation-delay: .07s; }
  .hero .hero-grid > div > *:nth-child(3) { animation-delay: .14s; }
  .hero .hero-grid > div > *:nth-child(4) { animation-delay: .21s; }
  .hero .hero-grid > div > *:nth-child(5) { animation-delay: .28s; }
  .hero .hero-grid > .hero-media { animation: media-in 1.05s var(--ease-out) .16s both; }

  /* ① 内页首屏：面包屑 → 标签 → 标题 → 导语。
     主站内页 .page-hero 与 pFMT 专题 .section-hero 是**同一个角色**，编排只写这一处
     （原先 pfmt.css 里另抄了一份，等于"同一件事两处维护"：给首屏加一个元素，
     两边都要数 nth-child，漏一处就只有一边动）。第 5 项是专题首页的免责脚注。 */
  .page-hero .container > *, .section-hero .hero-content > * { animation: rise-in .8s var(--ease-out) both; }
  .page-hero .container > *:nth-child(2), .section-hero .hero-content > *:nth-child(2) { animation-delay: .06s; }
  .page-hero .container > *:nth-child(3), .section-hero .hero-content > *:nth-child(3) { animation-delay: .12s; }
  .page-hero .container > *:nth-child(4), .section-hero .hero-content > *:nth-child(4) { animation-delay: .18s; }
  .section-hero .hero-content > *:nth-child(5) { animation-delay: .24s; }
  /* 首屏品牌纹样随文字一起淡入（只动透明度与 16px 位移），
     避免"文字落位完毕、底纹才整块跳出来"。 */
  .page-hero .hero-pattern, .section-hero .hero-pattern { animation: pattern-in 1.2s var(--ease-out) .24s both; }

  /* ② 滚动浮现 */
  .reveal {
    opacity: 0; transform: translate3d(0, 22px, 0);
    transition: opacity .8s var(--ease-out), transform .9s var(--ease-out);
    transition-delay: var(--reveal-delay, 0s);
  }
  .reveal.is-visible { opacity: 1; transform: none; }
}

/* ③ 微交互 */
.chip { transition: border-color .25s var(--ease), background-color .25s var(--ease), color .25s var(--ease); }
.chip:hover { border-color: var(--brand); color: var(--brand-ink); background: var(--brand-tint); }
.creds li { transition: background-color .3s var(--ease); }
.creds li:hover { background: var(--brand-tint); }
.step .idx { transition: background-color .3s var(--ease), color .3s var(--ease); }
.job { transition: border-color .3s var(--ease), box-shadow .4s var(--ease), transform .4s var(--ease-out); }
.job:hover { border-color: rgba(0, 176, 154, .5); box-shadow: 0 26px 52px -42px rgba(8, 40, 34, .7); transform: translateY(-2px); }
.video-card { transition: border-color .3s var(--ease), box-shadow .4s var(--ease), transform .4s var(--ease-out); }
.video-card:hover { border-color: rgba(0, 176, 154, .5); transform: translateY(-3px); box-shadow: 0 30px 56px -44px rgba(8, 40, 34, .72); }

/* ---------- 25b. 检测报告样本（/quantitest/） ---------- */
/* 报告样本拼版：图片自带浅色底与投影，这里只负责圆角与图注 */
.report-figure { margin: 0; }
.report-figure img { display: block; width: 100%; height: auto; border-radius: var(--r); }
.report-figure figcaption { margin-top: 12px; font-size: .8125rem; line-height: 1.7; color: var(--muted); }
/* 「图版」：给**自身是纯白底**的整幅配图（设施渲染图、线稿）一层浅底 + 发丝描边 + 内边距。
   不加这层时，白图直接放在白底区块上会整幅糊进页面、看不出边界——2026-10-10
   /culture-collection/「工程型菌库」那张库房渲染图实测如此（同级区块是白底）。
   底色与描边沿用站点卡片的同一套词汇；放在浅底区块上也读得出来。 */
.figure-plate {
  background: var(--bg-soft); border: 1px solid var(--line); border-radius: var(--r);
  padding: clamp(14px, 1.8vw, 22px);
}
.figure-plate img { border-radius: calc(var(--r) - 4px); }
.figure-plate figcaption { margin-top: 14px; }
/* 圆点清单：报告结构、采样要点等并列条目的通用样式 */
.dot-list { list-style: none; padding: 0; margin: 0; }
.dot-list li { position: relative; padding-left: 18px; margin: 9px 0; font-size: .9375rem; line-height: 1.75; color: var(--muted); }
.dot-list li::before { content: ''; position: absolute; left: 2px; top: 11px; width: 5px; height: 5px; border-radius: 50%; background: var(--brand); }
.dot-list li strong { color: var(--ink); font-weight: 600; }

/* ---------- 26. 动效降级 ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .001ms !important; animation-delay: 0ms !important; transition-duration: .001ms !important; }
  .reveal { opacity: 1 !important; transform: none !important; }
}

/* ---------- 27. 打印 ---------- */
@media print {
  .site-header, .site-footer, .cta-band, .hero-pattern, .dark-pattern { display: none; }
  .section { padding: 24px 0; }
  /* 滚动浮现（.reveal）在纸上没有「滚动」可言：没滚到过的区块会整块印成空白。
     打印一律按最终态输出（与 prefers-reduced-motion 的降级同口径）。 */
  .reveal { opacity: 1 !important; transform: none !important; }
}
