@charset "UTF-8";
/* ============================================================
   墨聚芯能 MJXN 官网 2.0 · 全站样式
   色彩依据《MJXN 官网颜色规范》：墨黑 #171A1D / 暖白 #F3F1EA /
   能量橙 #FF8A3D / 金属灰 #B8BFC6 / 冷青灰 #A7B7D9 / 功能白 #FFFFFF
   视觉原则：暖白是空间，墨黑是品牌，橙色是能量，灰色是材料，冷青灰是数字化。
   ============================================================ */

/* ---------- 1. 令牌 ---------- */
:root {
  /* 品牌六色：规范给定值，此处只作档案记录，实际取用一律走下面的工作令牌。
     冷雾蓝 #A7B7D9 属品牌色但站上暂无落点，先留着不删。 */
  --black: #171A1D;
  --warm: #F3F1EA;
  --orange: #FF8A3D;
  --metal: #B8BFC6;
  --cool: #A7B7D9;
  --white: #FFFFFF;

  /* 文字：浅底三档，均过 AA（在暖白上 15.46 / 6.69 / 5.39 比 1） */
  --ink: #171A1D;
  --ink-2: #4E555C;
  --ink-3: #5C636A;
  /* 压在照片上的次级文字。实测照片底色是中调（亮度 112–140）+ 承载层后为 156–204，
     --ink-2 #4E555C 在最暗处只有 3.6:1；#3F464D 也只有 3.8:1。
     这一档要压到 #343A40，在承载面最暗处（亮度 156）仍有 4.5:1。 */
  --ink-2-photo: #2F353B;

  /* 橙分三档：浅底上原色只有 2.07:1，只能做装饰线；
     浅底文字与图标走沉橙 #A94E0C（4.91:1）；
     实底填充用原色配墨黑字（7.45:1）。 */
  --accent: #A94E0C;
  /* 深橙：压在照片上时用。原色 #FF8A3D 在浅墙上只有 1.32:1，读不出来。
     这一档的取值由**最不利底色**反推，底色跟着文案位置走：
       · 2026-10-05 之前文案中心在视口 48%，眉题落在亮度 163 处 → #5A2605（相对亮度 0.0357）4.86:1；
       · 2026-10-05 起按用户标注把整块上提到中心 40%（见 `.hero-copy`），眉题落到画面
         顶部的中间调，六档实测底色最不利处只有 152（1280×720）→ 要守 4.5:1，
         文字色的相对亮度必须压到 0.0307 以下。#4E2204 是 0.0272，同一位置 4.70:1。
     色相仍是橙，只是又压深一档；橙色**短线**始终用原色 #FF8A3D——
     明橙短线 + 深橙小字，整条眉题是橙色系，短线承担那个「亮橙色信号」。
     **以后只要再动首屏文案的垂直位置，这一档就要重新反推。** */
  --accent-deep: #4E2204;
  --accent-fill: #FF8A3D;
  --accent-soft: #FBEADF;
  --accent-line: #FF8A3D;

  /* 面 */
  --bg: #F3F1EA;
  --bg-soft: #F8F6F2;   /* 介于暖白与纯白之间：后续模块的背景层次只在这两色之间变化 */
  --bg-deep: #171A1D;
  --surface: #FFFFFF;
  --mask: rgba(15, 18, 20, .6);

  /* 线：金属灰只做线与边，低透明度使用 */
  --line: rgba(23, 26, 29, .12);
  --line-strong: rgba(23, 26, 29, .22);
  --line-dark: rgba(255, 255, 255, .16);

  /* 深底文字 */
  --text-on-dark: #C9CFD6;
  --text-on-dark-2: #9AA1A9;

  /* 度量 */
  --wrap: 1240px;
  --gut: 24px;
  /* 首屏图宽高比（当前 1672×940）。首屏高度与窄屏照片区都按它算，换图时同步改。 */
  --hero-ar: 1.7787;
  /* 首屏文案（eyebrow／主标题／副标题）的左缘。
     **这个值由照片决定，不由版式偏好决定**——它要保证文案压在画面左侧那条连续的浅墙上。
     历史上写的是固定 vw（2026-10-05 由 `8vw` 右移到 `13vw`），但固定 vw 只在某一个
     视口尺寸下成立：竖线在屏幕上的位置随 cover 的铺满方式漂移，实测六档，
     标题右端越过竖线的量是 1201→67px、1280→52px、1366→25px、1440→60px、
     1680→69px、1920→9px——**除最宽的那一档，其余全是深色字压在墙外的暗区上**。
     2026-10-13 用户就是看着 1920 那 9px 说「被背景的那条竖线挡住字」。

     **V2.59 起改成「跟着竖线走」**：先算出竖线的屏幕坐标 `--hero-wall-right`，
     再往回推「标题宽 + 空隙」，得到左缘。这样每一档留出的空隙都是同一个数，
     不再有哪一档压线，也不必为某一档单独调值。
     竖线在图内的 x≈496（占图宽 29.7%）是逐列亮度扫描出来的实测值，
     **换首屏图必须重新量**（脚本与数据见 `backup/首页首屏文案左移_20261013/`）。
     左缘由 `--hero-copy-w`（文案块里最长的那一行）往回推——**V2.60 起那一行是「有没有
     标题或副标题比它更长」，不是固定按标题算**（见 `--hero-copy-w` 的注释）。

     **这一条现在只服务首屏文案**。页头、中间各段、页脚都走 `.wrap`（1240 居中），
     所以文案与页头 Logo 不在同一条线上，这是刻意的取舍（见下面 `.hero-copy` 的注释）。 */
  /* 竖线（浅墙右界）在屏幕上的 x。cover 有两种铺满方式，各写一个式子，用 min() 取实际生效的那个：
       · 按宽铺满（超宽视口）→ 496 / 1672 = 29.66vw；
       · 按高铺满（常见桌面）→ 50vw − 36.17svh
         （推导：x = 496·H/940 + (W − 1672·H/940)/2 = W/2 − 340·H/940，而首屏高 H = 100svh）。 */
  --hero-wall-right: min(29.66vw, calc(50vw - 36.17svh));
  /* 文案块里**最长的那一行**的宽度，用来反推左缘。两行各自算，取大：
       · 主标题行「不止一种答案」6 字 × 字号 clamp(28px, 3.1vw, 52px) → clamp(168px, 18.6vw, 312px)；
       · 副标题第一行「从空间采暖、日常穿戴到草本应用，」16 字 × 16px ＝ **260px**
         （16 × 16 ＝ 256，再加 `.hero-sub` 的 `letter-spacing: .01em` ≈ 2.6px）。
     **副标题在 1201–1366 这几档比标题还宽**（16px 是固定字号、不随视口缩），
     所以不能只按标题算——只按标题算的话，那几档副标题会压到竖线上。
     **任一行改字数，这里就要跟着改。** */
  --hero-copy-w: max(clamp(168px, 18.6vw, 312px), 260px);
  --hero-edge: max(24px, calc(var(--hero-wall-right) - var(--hero-copy-w) - 28px));

  /* 圆角四档：小控件 → 单元格 → 卡片 → 大容器 */
  --radius-sm: 10px;     /* 按钮、导航悬停块、小控件 */
  --radius-md: 12px;     /* 矩阵单元格、参数块、右下浮条 */
  --radius-card: 14px;   /* 卡片、图片、场景块 */
  --radius-lg: 20px;     /* 转化卡、弹层 */

  --header-h: 76px;      /* 页头高：独立的暖白品牌层，规范给 76px */
  --ease: cubic-bezier(.22, .61, .36, 1);
  --shadow-card: 0 1px 2px rgba(23, 26, 29, .03), 0 10px 26px -18px rgba(23, 26, 29, .14);
  --shadow-lift: 0 2px 5px rgba(23, 26, 29, .05), 0 20px 40px -24px rgba(23, 26, 29, .20);
}

/* ---------- 2. 基础 ---------- */
*, *::before, *::after { box-sizing: border-box; }

/* 横向溢出交给视口裁切。
   注意：不能在 body 上用 overflow-x: hidden —— 那会让 body 变成滚动容器，
   子元素的 position: sticky（目录页吸顶分类条）会失去参照而不再跟随滚动。
   clip 不建立滚动容器，sticky 正常。html 上保留 hidden 作旧浏览器兜底。 */
html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  overflow-x: hidden;
  /* 站内锚点跳转的落点补偿：让开固定页头再留 24px。
     带吸顶树目（`.cat-tree`）的页面由下面那条 `:has()` 规则覆盖——
     吸顶元素的高度随断点变，写不进这里的静态值。 */
  scroll-padding-top: calc(var(--header-h) + 24px);
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  overflow-x: clip;
  font-family: "Inter", "HarmonyOS Sans SC", "MiSans", "PingFang SC", "Noto Sans SC",
               "Source Han Sans SC", "Hiragino Sans GB", "Microsoft YaHei",
               -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: 16px;
  line-height: 1.75;
  letter-spacing: .01em;
  -webkit-font-smoothing: antialiased;
  font-feature-settings: "tnum" 0;
}

img { max-width: 100%; display: block; border-style: none; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
ul, ol { margin: 0; padding: 0; list-style: none; }
table { border-collapse: collapse; width: 100%; }
h1, h2, h3, h4, p { margin: 0; }
svg { display: block; }
:focus-visible { outline: 2px solid var(--accent-fill); outline-offset: 3px; }
::selection { background: var(--accent-soft); color: var(--ink); }

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  padding: 10px 18px; background: var(--ink); color: #fff; border-radius: 0 0 var(--radius-sm) 0;
}
.skip-link:focus { left: 0; }

/* ---------- 3. 版式 ---------- */
.wrap { width: 100%; max-width: var(--wrap); margin: 0 auto; padding: 0 var(--gut); }

/* 分段留白的尺度（V1.39 用户指定「留白太多，类似至少要缩小到只有三分之一」）。
   原来每一段上下各 104px，两段相接处就是 208px 的空档；分类块之间更宽
   （上下各 84px＝168px）。全部按 **1/3** 收一档——数值直接除以三，
   不改结构、不动内容，只把段间距收紧。 */
.section { padding: 35px 0; }
.section--tight { padding: 24px 0; }
.section--surface { background: var(--surface); }
.section--soft { background: var(--bg-soft); }
.section--deep { background: var(--bg-deep); color: var(--white); }

.eyebrow {
  display: inline-flex; align-items: center; gap: 10px;
  font-size: 12.5px; font-weight: 600; letter-spacing: .16em; text-transform: uppercase;
  color: var(--accent);
}
.eyebrow::before {
  content: ""; width: 22px; height: 2px; border-radius: 2px;
  background: var(--accent-line); flex: none;
}
.section--deep .eyebrow { color: var(--orange); }
.section--deep .eyebrow::before { background: var(--orange); }

.section-head { max-width: 780px; margin-bottom: 19px; }
.section-head--center { margin-left: auto; margin-right: auto; text-align: center; }
.section-head--center .eyebrow { justify-content: center; }

h1, .h1 { font-size: clamp(34px, 5vw, 58px); line-height: 1.18; font-weight: 600; letter-spacing: -.012em; }
h2, .h2 { font-size: clamp(26px, 3.4vw, 40px); line-height: 1.24; font-weight: 600; letter-spacing: -.01em; }
h3, .h3 { font-size: clamp(19px, 2vw, 23px); line-height: 1.4; font-weight: 600; letter-spacing: -.004em; }
h4, .h4 { font-size: 17px; line-height: 1.5; font-weight: 600; }

.section-head h2 + .section-sub { margin-top: 18px; }
.section-sub { color: var(--ink-2); font-size: 17px; line-height: 1.8; max-width: 62ch; }
.section--deep .section-sub { color: var(--text-on-dark); }
.lead { color: var(--ink-2); font-size: 17px; line-height: 1.85; }
.muted { color: var(--ink-3); }
.en {
  display: block; font-size: 12.5px; font-weight: 600; letter-spacing: .18em;
  text-transform: uppercase; color: var(--ink-3); margin-top: 12px;
}
.section--deep .en { color: var(--text-on-dark-2); }
.rule { height: 1px; background: var(--line); border: 0; margin: 0; }

/* ---------- 8. 常见问题 ----------
   原来每组是一个两列白卡片网格：23 条问答长得一模一样、穿插的 4 张照片把两列拉成
   参差的锯齿（照片 393px 高、旁边的文字卡只有 130px），整页读下来既没有层次、
   也不知道该从哪条看起。改成**条目列表**：一条一行，行内三列＝序号 / 问题 / 答案。
   三个后果正是想要的——问题竖成一列，眼睛顺着往下扫就能挑到要的那条；
   答案与问题同高对齐，行高可预期；每条之间只留一条 1px 细线，
   内容不再被 23 个白盒子各包一层。
   分类沿用产品线页那一套 `.cat-layout` / `.cat-tree`：左侧树目吸顶、≤1080 变上排
   换行芯片。全站因此只剩这一种「页内分类」的形态，`.anchor-nav` 那条吸顶药丸条
   也随之退场（本站最后一处使用就是这一页）。 */
.qa-list { --qa-no: 42px; --qa-q: 360px; --qa-gap: 20px; }
.qa {
  display: grid;
  grid-template-columns: var(--qa-no) var(--qa-q) minmax(0, 1fr);
  gap: 0 var(--qa-gap); align-items: start;
  padding: 20px 0;
  border-top: 1px solid var(--line);
}
/* 序号不从第一行顶端齐平——它要跟问题那一行对齐，所以单独补一点上边距。 */
.qa-no {
  padding-top: 6px;
  font-size: 12.5px; font-weight: 600; letter-spacing: .1em;
  color: var(--accent); font-variant-numeric: tabular-nums;
}
/* 问题列宽 360px 是量出来的最长一条定的：「同一种发热材料为什么能做这么多产品？」
   20 个字 × 17px ＝ 340px，收窄一档就折行，问答的节奏会散。 */
.qa-q { font-size: 17px; font-weight: 600; line-height: 1.6; }
.qa-a { font-size: 15px; line-height: 1.85; color: var(--ink-2); }
.qa-a a { color: var(--accent); text-decoration: underline; text-underline-offset: 3px; }
/* 插图**对齐到答案那一列**、按原图 3:2 出、不裁切。它落在文本的纵向节奏上，
   不再是网格里一块参差的空白；宽度跟着答案列走，也就跟着视口自适应。 */
.qa-photo {
  margin: 4px 0 4px calc(var(--qa-no) + var(--qa-q) + var(--qa-gap) * 2);
  border-radius: var(--radius-card); overflow: hidden; background: var(--bg-soft);
}
.qa-photo img { display: block; width: 100%; height: auto; aspect-ratio: 3 / 2; object-fit: cover; }

/* ---------- 8.5 联系我们 ----------
   两栏：左栏是公司信息，右栏是二维码。原来右栏是一个空的白色大卡（只有中间一个
   虚线方块），左右都空、整页没有落点。现在右栏走墨黑底——**全页只有这一块深色**，
   「怎么联系」一眼就能找到；二维码必须落在浅底上才扫得动，所以卡内单独留一块暖白方框。 */
.ct-layout { display: grid; grid-template-columns: minmax(0, 1fr) 384px; gap: 64px; align-items: start; }
/* V2.25 联系我们页重排（用户 2026-10-11 01:23：C 项「内容排版简约高级点。
   不能过于复杂又不能信息内容少。因为这是唯一可以转化的入口一定要设计好」）。
   上一版把对外信息全塞进一张五行表（公司全称／地址／邮箱／官网／备用域名）——
   **能点的动作**（电话、邮箱、官网）与**不能点的背景**（全称、地址）混在同一层里，
   谁都读不突出；而这一页的 KPI 是「把访客转成一条来电或一条微信」。
   这一版按**「能不能点走」重分层**：
     · `.ct-ways`＝三项可以直接点走的联络入口，21px 大字 + 等宽数字 + 上下 1px 细线，
       读起来是一条清单而不是一张表；
     · `.ct-reg`＝公司全称与经营地址，降成 14.5px 次级小字收尾。
   信息一条没少（两个备用域名并进官网那一行），只是从「一张表」变成「两组」。
   样式只用细线、不再套壳：纯白页面上再叠一层白卡是多余的一层。 */
.ct-ways { margin-top: 38px; border-top: 1px solid var(--line); }
.ct-ways li {
  display: grid; grid-template-columns: 82px minmax(0, 1fr); align-items: baseline;
  gap: 18px; padding: 18px 0 17px; border-bottom: 1px solid var(--line);
}
.ct-way-k { font-size: 13.5px; letter-spacing: .08em; color: var(--ink-3); }
.ct-way-v {
  display: inline-block;
  font-size: 21px; font-weight: 600; letter-spacing: -.012em; line-height: 1.35;
  color: var(--ink); font-variant-numeric: tabular-nums;
}
a.ct-way-v { transition: color .2s var(--ease); }
a.ct-way-v:hover, a.ct-way-v:focus-visible { color: var(--accent); }
.ct-way-note {
  display: block; margin-top: 7px;
  font-size: 13.5px; font-style: normal; letter-spacing: 0; color: var(--ink-3);
}
.ct-reg { margin-top: 24px; }
.ct-reg > div { display: grid; grid-template-columns: 82px minmax(0, 1fr); gap: 18px; }
.ct-reg > div + div { margin-top: 9px; }
.ct-reg dt { font-size: 13.5px; letter-spacing: .08em; color: var(--ink-3); }
.ct-reg dd { margin: 0; font-size: 14.5px; line-height: 1.7; color: var(--ink-2); }
.ct-card {
  /* 右栏比左栏矮一截，顶端对齐会在右下方留一块空档；居中之后这一块
     落在左栏的中段、与它的重心齐平，整段看起来才是一左一右两件东西。
     **V2.23：底色由墨黑改纯白**（用户 00:59 两条指令合起来指向这里——
     「这种的黑框也不要了。都调整把框给取了」＋「联系我们…中间区域统一纯白色背景」）。
     这一块是同一族的深色圆角卡，留在这儿与「中间全白」直接冲突；
     改成白底之后与左栏同色，文字走浅底那一档，
     二维码占位不再是「白底无边框」（那在纯白卡上会消失），回落到站内虚线占位那一档。
     **V2.25 保留**：这一页重排时它是唯一「整块的行动入口」（扫码加微信），
     左栏改成细线清单之后，右边留一块实心白卡恰好把主次分开，不再动它。 */
  align-self: center; text-align: center;
  padding: 34px 30px 32px; border-radius: var(--radius-lg);
  background: var(--surface); color: var(--ink);
}
.ct-card h3 { margin-top: 14px; font-size: 20px; color: var(--ink); }
.ct-card .ct-card-x { margin-top: 10px; font-size: 14.5px; line-height: 1.8; color: var(--ink-2); }
.ct-card .ph-qr { margin: 24px auto 0; }

/* ---------- 4. 页头 ----------
   导航透明叠在首屏摄影上，不做独立色块、不做毛玻璃、不做黑色导航条（规格第八节）。
   文字恒为暖白一种颜色、全站一个值——首页首屏、滚出首屏后、内页都不随背景取色。
   底色按场景分两套，只动底色、不动文字色：
     · 首页桌面首屏：透明，图从 y=0 铺满，画面连续无切割；
     · 其余全部（内页、窄屏、滚出首屏后）：墨黑底——暖白字压在暖白正文上会消失。 */
.site-header {
  position: fixed; inset: 0 0 auto 0; z-index: 90;
  background: var(--bg-deep);
  border-bottom: 1px solid var(--line-dark);
  transition: background .3s var(--ease), border-color .3s var(--ease);
}
/* 首屏是「整幅摄影」的页面，页头透明叠在图上。三类页面都走这一条：
   首页 `.hero`、有图的内页首屏 `.page-hero--img`、产品详情页 `.pd-top`。
   滚出这一屏后由脚本加 `.is-solid` 回到墨黑底。
   **前提是图顶那条深色渐变**（`.hero::before` / `.page-hero-bg::after`）——
   没有它，暖白字压在高亮照片上读不出来。 */
@media (min-width: 1201px) {
  body:has(.hero) .site-header:not(.is-solid),
  body:has(.page-hero--img) .site-header:not(.is-solid),
  body:has(.pd-top) .site-header:not(.is-solid) {
    background: transparent;
    border-bottom-color: transparent;
  }
}
.header-inner {
  display: flex; align-items: center; gap: 24px;
  height: var(--header-h);
}

/* 品牌标识单元：Logo 作为锚点。导航全程在深底或照片暗部上，一律用反白版。 */
.brand { display: inline-flex; align-items: center; flex: none; }
/* 显示尺寸跟着画布比例走。画布 829×278（比例 2.98）按 134×45 contain 渲染后，
   字标约 22.8px 高、中文约 14.1px 高——中文在 1 倍屏下四字清楚，又不与 MJXN 争主识别。
   换 logo 图时同步核这两个值（`_gen/build_logo.py` 的 CN_RATIO 与 GAP）。

   **尺寸比上一版收 9.5%（148×50 → 134×45）**：首屏的第一视觉应该是画面里的人与生活场景，
   148px 宽的锁定组合在 76px 高的页头里压过了 14.5px 的导航字。
   收一档之后字标与导航字的体量关系回到同一条线上，同时给最紧的 1201px 档多让出 14px 可用宽。
   **不再往下收**：中文行只有 14px 高，再小就回到 V1.9 那种「像脚注」的状态。 */
.brand-logo {
  width: 134px; height: 45px; display: block;
  background: url(../images/brand/logo-mjxn-white.png) left center/contain no-repeat;
}
/* **首页页头与其余页面同一个 `.wrap` 栅格**（2026-10-05 收窄）。
   曾经给首页单开过一条 `max-width: none; padding: 0 var(--hero-edge)`（8vw），
   为的是让 Logo 左缘与首屏文案左缘严格重合。撤销的原因是**版面宽度**：
   8vw 内边距下 1920 的内容铺到 1612px，比其余页面的 1240px 栅格宽 372px，
   首页与内页看着不是一套版面。现在首页与内页同宽、同居中，左右缘逐像素一致。

   **取舍**：首页首屏的文案仍留在 `--hero-edge`（8vw）上，与页头 Logo 不再对齐
   （1920 下 154 与 357）。这一处收不进去——文案压在照片左侧那条唯一的连续浅墙上
   （画面 x 8%–27%），跟着栅格走到 19% 起时可用宽度只剩 154px，
   放不下 44px 字号的一行标题。1440 下两者只差 9px（115 与 124），看不出来。 */

/* 导航整体偏右、Logo 之后留出大片呼吸空间——刻意不做「左 Logo + 居中导航」
   那种左右对称的模板比例。`margin-left: auto` 把导航推到右端，
   Logo 与导航之间就是整段留白。 */
.site-nav {
  flex: 0 1 auto; display: flex; margin-left: auto; min-width: 0;
}
.nav-list { display: flex; align-items: center; gap: 2px; }
.nav-list > li { position: relative; }
/* 宽视口下头部内容随视口变宽，「进入商城」会落到画面最右那片落地窗上（亮度 231–239），
   暖白字的中位对比只剩 4.08:1。给整行导航极轻的深色柔光：不铺底色、不加边框，
   在暗底上完全看不出，只在亮窗上把字托住。用统一的规则而不是单独给某一项，
   避免同一行导航出现两种观感。 */
.nav-list > li > a {
  /* 两层：0 0 1px 的紧贴暗边只在亮底上生效、暗底上范围小到看不见；
     0 1px 8px 的柔光负责把字从中间调里托出来。 */
  text-shadow: 0 0 1px rgba(23, 26, 29, .55), 0 1px 8px rgba(23, 26, 29, .50);
}
/* V1.72：`products/index.html` 删除后，「产品中心」这一项不再是链接（只带子菜单）。
   它仍走上面那套字色与字距，但**鼠标不要显示成可点的手型**——它点下去不跳页。
   键盘仍能聚焦（`tabindex="0"`），聚焦时子菜单由 :focus-within 展开。 */
.nav-list > li > a.nav-plain { cursor: default; }
/* 九项等距：每项左右各 12px 内边距 + 列表 2px 间隔，全行只有一种节奏。
   字距从 .04em 收到 .02em——中文在 .04em 下字与字之间会散开，收回来才成为
   一块规整的矩形，「干净规整的几何形态」靠的是这个而不是加装饰。

   **字号与字重与右侧那个橙色按钮完全一致（14.5px / 600）。**
   原先导航 14px/500、按钮 13px/600，同一行里两种规格，看过去就是「按钮的字比菜单大」。
   统一之后整行只有一种字，主次改由橙色实底承担——这也是「少即是多」里
   该由形状而不是字号来分层的部分。
   字重从 500 提到 600 会让中文宽约 2%，导航整体宽约 20px；相应地内边距从 12px 收到 10px
   把这点宽度让回来。**1201px 是最紧的一档**——首页页头在这一档用 `--hero-edge`（8vw）
   做左右内边距，可用宽只剩约 1009px，而 Logo 148 + 导航 + CTA 93 + 两处 gap 48
   加起来的余量本来就不到 30px；不收这一档会静默压扁导航（`min-width: 0` + 项 `nowrap`）。
   改完用 `nav_measure.mjs` 复核：**「Logo→导航留白」等于 `.header-inner` 的 gap（24px）
   就说明已经压到底了**，正常应大于它。

   **文字色取实色 #F3F1EA（原来是 86% 不透明的同一色）。** 页头这一行压在照片上，
   右侧几项会落到那片落地窗（亮度 231–239）；半透明的暖白在亮底上会与背景互相咬合，
   实色相当于把可用的那点对比全部留给字本身。 */
.nav-list > li > a {
  position: relative;
  display: inline-flex; align-items: center; gap: 4px;
  padding: 9px 10px; border-radius: var(--radius-sm);
  font-size: 14.5px; font-weight: 600; letter-spacing: .02em; color: var(--warm);
  transition: color .2s var(--ease);
  white-space: nowrap;
}
/* 悬停转能量橙（规格第五节：橙用于 hover 与强调），不做位移、不做底色块。 */
.nav-list > li > a:hover { color: var(--accent-fill); }
/* 当前栏目：暖白文字 + 一条极细橙线，不做色块 */
.nav-list > li > a[aria-current="page"] { color: var(--white); font-weight: 600; }
.nav-list > li > a[aria-current="page"]::after {
  content: ""; position: absolute; left: 10px; right: 10px; bottom: 1px; height: 2px;
  border-radius: 2px; background: var(--accent-fill);
}
/* 下拉箭头：做成 a 里的一个实元素而不是 a 的伪元素——a 的 ::after 已经被
   当前栏目的橙线占用，两者要在「产品中心」这一项上同时存在。
   尺寸与透明度都压到最小，只承担「这里可以展开」的功能提示，不作装饰。 */
.nav-caret {
  width: 5px; height: 5px; margin-top: -2px; flex: none;
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg); opacity: .5;
  transition: opacity .2s var(--ease);
}
.has-sub:hover .nav-caret, .has-sub:focus-within .nav-caret { opacity: .9; }
/* 下拉面板。三条口径：
   ① **左缘与一级项的左缘对齐**（`left: 0`，不再居中）——居中的写法会让面板向左伸出
      到「首页」底下，看不出它属于哪一项。
   ② **顶部一个指向一级项的小三角**，落在「产品中心」四个字的中线下方；
      再加一段 12px 高的透明「过桥」把面板与标题之间的缝填掉，鼠标从标题往下移
      经过那道 10px 空隙时不会掉 hover。
   ③ **浅色面板**（暖白底 + 墨黑字）。原来是墨黑面板，压在照片上与页头叠成一片，
      看不出边界；浅底与页头的深色层分开，也与抽屉里的子菜单是同一套观感。 */
.sub-menu {
  position: absolute; top: calc(100% + 10px); left: 0;
  min-width: 264px; padding: 8px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius-card);
  box-shadow: 0 20px 44px -26px rgba(23, 26, 29, .42);
  opacity: 0; visibility: hidden; transform: translateY(-6px);
  transition: .22s var(--ease);
}
.sub-menu::before {
  /* 过桥：盖住面板与标题之间的那 10px 缝，纯透明、不参与视觉 */
  content: ""; position: absolute; left: 0; right: 0; top: -12px; height: 12px;
}
.sub-menu::after {
  /* 指向一级项的小三角。左边距 10px（项的左内边距）+ 4 字标题的半宽 ≈ 39px */
  content: ""; position: absolute; top: -5.5px; left: 39px;
  width: 10px; height: 10px;
  background: var(--surface);
  border-left: 1px solid var(--line); border-top: 1px solid var(--line);
  transform: rotate(45deg);
}
.has-sub:hover .sub-menu,
.has-sub:focus-within .sub-menu { opacity: 1; visibility: visible; transform: translateY(0); }
.sub-menu a { display: block; padding: 10px 12px; border-radius: var(--radius-sm); font-size: 15px; font-weight: 600; color: var(--ink); }
.sub-menu a:hover { background: var(--bg); color: var(--ink); }
/* 子菜单里的说明行与小字：浅底配色（深底那套已随面板一起换掉） */
.sub-desc { display: block; font-size: 12.5px; font-weight: 400; color: var(--ink-3); letter-spacing: 0; margin-top: 3px; }
.sub-brand { font-style: normal; font-size: 12.5px; font-weight: 400; color: var(--ink-3); }

/* 右端曾经挂一个橙色实底的 400 电话（V1.22 起）。V1.39 按用户要求删除：
   号码与右下联系条重复，同一屏出现两处同一个号码；页头右端现在只剩导航。
   `.header-cta` / `.header-tel` 一组规则随之删掉，不留死样式。
   导航仍靠 `.site-nav` 的 `margin-left: auto` 偏右——Logo 与导航之间那整段留白不变。
   移动端那一档的右推改挂在 `.nav-burger` 上（原来由 `.header-cta` 的 auto 外边距承担）。 */

.nav-toggle { position: absolute; opacity: 0; pointer-events: none; }
.nav-burger { display: none; }

/* ---------- 5. 按钮 / 标签 / 链接 ---------- */
/* 圆角统一走 --radius-md（12px）而不是小控件那一档。
   全站按钮一个值：页头 CTA、正文主次按钮、转化块的按钮都取 12px，
   与卡片（14px）只差一档。规格第二十二节给的页头 CTA 圆角是 12–14px；
   若只改页头那一处，同一页上就会出现 10px 与 12px 两种按钮，
   「统一圆角」这条反而不成立。 */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  padding: 13px 24px; border-radius: var(--radius-md);
  font-size: 15px; font-weight: 600; letter-spacing: .01em;
  border: 1px solid transparent; cursor: pointer;
  transition: transform .18s var(--ease), background .2s var(--ease),
              border-color .2s var(--ease), color .2s var(--ease), box-shadow .2s var(--ease);
  white-space: nowrap;
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0); }

/* 主 CTA：能量橙实底 + 墨黑字（7.45:1）。规范禁用白字压橙。 */
.btn-primary { background: var(--accent-fill); color: var(--ink); }
.btn-primary:hover { background: #FF9A57; }

/* 次按钮：墨黑实底 + 白字（17.47:1） */
.btn-dark { background: var(--ink); color: var(--white); }
.btn-dark:hover { background: #24282C; }

/* 描边按钮：暖白底 */
.btn-ghost { border-color: var(--line-strong); color: var(--ink); background: transparent; }
.btn-ghost:hover { border-color: var(--ink); background: rgba(23, 26, 29, .04); }

/* 首屏次按钮：透明底 + 1px 金属灰边 + 墨黑字（规范指定）。
   压在照片上不给它垫浅色底——那等于在图上放一块半透明信息框。 */
.btn-outline {
  border-color: var(--metal); color: var(--ink);
  background: transparent;
  backdrop-filter: none; -webkit-backdrop-filter: none;
}
.btn-outline:hover { border-color: var(--accent-fill); }

/* 描边按钮：深底 */
.btn-ghost-light { border-color: var(--line-dark); color: var(--white); background: transparent; }
.btn-ghost-light:hover { border-color: rgba(255, 255, 255, .5); background: rgba(255, 255, 255, .08); }

.btn-sm { padding: 10px 18px; font-size: 14.5px; }
.btn .ico { width: 17px; height: 17px; flex: none; }

.arrow-link {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 15px; font-weight: 600; color: var(--accent);
  transition: gap .2s var(--ease), color .2s var(--ease);
}
.arrow-link::after {
  content: ""; width: 6px; height: 6px;
  border-right: 1.8px solid currentColor; border-top: 1.8px solid currentColor;
  transform: rotate(45deg); transition: transform .2s var(--ease);
}
.arrow-link:hover::after { transform: rotate(45deg) translate(2px, -2px); }
.section--deep .arrow-link { color: var(--orange); }

.tag {
  display: inline-flex; align-items: center;
  padding: 4px 11px; border-radius: 999px;
  font-size: 12.5px; font-weight: 500; line-height: 1.7;
  border: 1px solid var(--line-strong); color: var(--ink-2);
  background: transparent; white-space: nowrap;
}
.tag--solid { background: var(--ink); color: var(--white); border-color: var(--ink); }
.tag--accent { border-color: var(--accent-fill); color: var(--accent); }
.tag--soft { background: var(--accent-soft); border-color: transparent; color: var(--accent); }
.tag-row { display: flex; flex-wrap: wrap; gap: 8px; }

.dots { display: flex; gap: 8px; flex-wrap: wrap; }

/* ---------- 6. 首屏（一张单图） ----------
   一张完整连续的品牌摄影，三条产品线在同一场景里共存，不做轮播、不做三张拼图。
   页面上不出现任何形式的遮罩：无矩形色块、无玻璃卡、无渐变、无发光晕。
   摄影是明亮的暖白高调，左侧 34%–40% 是留给文字的安静区，所以首屏文字走墨黑，
   可读性由构图承担，见 _gen/process.py 的首屏与 build_p1.py 的说明。 */
/* 首屏从 y=0 起铺满、高度严格等于一屏（规格第七节 A）。
   **不要写成 `max(100svh, 100vw / var(--hero-ar))`**：视口比图片更「宽」时
   （1440×780、1536×824、2560×1080 等）那一项会大于视口高，首屏被撑长、
   页面出现下拉——实测 2560×1080 会多出 361px。写成 100svh 后，
   cover 会自动按宽度铺满、把上下裁掉一点，首屏永远正好一屏。 */
.hero {
  position: relative;
  height: 100svh;
  display: flex; align-items: center;
  overflow: hidden; background: var(--bg-soft);
}
.hero-media { position: absolute; inset: 0; z-index: 0; }

/* 顶部自然压暗（规格第八节允许的那一条：向下约 80–110px 自然淡出）。
   导航要透明叠图、文字要暖白，而这页图顶部左侧是浅墙（亮度 98–149）、
   最右是落地窗（231–239），暖白字压在 149 上只有 2.65:1、压在 239 上只有 1.02:1。
   经实测，把顶部压到达标只需要一条很轻的暗带：文字所在高度（y≈38px）处 α≈0.41，
   右侧落地窗由 239 降到 165——是摄影里给过曝天空压暗的量级，不是一条 UI 黑条。
   范围限于画面顶部 16%，主体与人物完全不受影响。 */
.hero::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 150px;
  z-index: 1; pointer-events: none;
  background: linear-gradient(180deg,
    rgba(23, 26, 29, .50) 0, rgba(23, 26, 29, .40) 42px,
    rgba(23, 26, 29, .22) 84px, rgba(23, 26, 29, .08) 118px,
    rgba(23, 26, 29, 0) 150px);
}
/* 图（1672×941）与容器同比例时 cover 等于不裁。桌面视口比图片更「高」，
   裁掉的是左右两侧边缘：16:9 下最多各裁 4%–5%，六个人物全在画面内。 */
.hero-img {
  width: 100%; height: 100%; object-fit: cover; object-position: center;
  animation: hero-img-in 1.1s var(--ease) both;
}
@keyframes hero-img-in {
  from { opacity: 0; transform: scale(1.02); }
  to { opacity: 1; transform: none; }
}

/* 文案块不挂任何承载：不加底色、不设卡片、不加边框、不加阴影、不做柔光（规格第六节）。
   这张图左侧是一条连续无人的浅墙，文字直接排在这块天然留白上。
   **左缘走 `--hero-edge`（V2.59 起＝竖线右界往回推「标题宽 + 28px」），不跟 1240 居中栅格走**
   ——栅格在宽屏上会把左缘一路推到画面 19%（1920 下 357），那条浅墙剩下的宽度放不下一行标题。
   页头走的是 `.wrap`，所以这一处与 Logo 不同线，是刻意的取舍（见 `--hero-edge` 注释）。
   **文案右端与竖线之间的空隙在各档都是 28px**：逐次调整都要用
   `backup/首页首屏文案左移_20261013/` 那份逐列亮度扫描复验。 */
.hero .wrap { max-width: none; padding: 0; }
.hero-copy {
  position: relative; z-index: 2;
  /* 左缘由 `--hero-edge` 给出（跟着竖线走）；块宽仍是 19vw、下限 264px。
     **块宽必须大于文案块里最长的那一行**（含 `.hero-sub` 的 `letter-spacing`），否则会折行：
     1920 下块宽 365 > 最长的 312；最紧的 1201 档块宽 264 > 副标题那行 258.6。
     下限 V2.60 从 258px 提到 264px——副标题换成 16 字一行之后，258px 恰好差 0.6px，
     实测 1201／1280 两档会把它折成两行（`letter-spacing: .01em` 的那一点宽度）。 */
  margin-left: var(--hero-edge);
  width: min(19vw, 448px); min-width: 264px;
  /* 垂直定位就是**整块相对首屏居中**，不加任何顶部偏移。
     原因是块高随视口变（字号有 clamp、首屏高各档不同），写死顶部偏移会让
     低视口下整块越滑越下——实测 1280×720 时副标题掉到画面 66%，底色只有 134。
     居中之后块中心恒在首屏 50%，各档表现一致。
     **不要再加 padding-top**：这一列（x 8vw 起、宽 19vw）在首屏图上的「可读带」
     （中位底色 ≥170，即 #3A4046 能到 4.5:1 的底线）实测是 1440 下的 y 310–570、
     1280 下的 y 265–465，两档的中心都在视口高度 49%–51%，正好是居中位置。
     曾经写过 padding-top: 8svh（把块推到 54%），那是首屏还挂着一个主按钮、
     块高 32% 时为了把副标题留在亮带里的补偿；按钮撤掉后块高回到 23%，
     这个偏移反而把副标题推出了下边界（实测 1280 下副标题中位底只剩 4.01:1）。
     块高（首屏 23%）装得进可读带。

     **再往下留 20svh 的空**（2026-10-05 用户指定）：用户在 1920×925 的首屏上标注，
     要让眉题顶边落到画面 28.1% 处（原为 36.1%）。下方留 20svh 等于把整块上提 10svh
     （居中项的 padding 只影响一半），块内容中心从视口 48% 移到 **40%**。
     原先这里是 4svh（中心 48%），那是五档实测出来的「最靠上且不出可读带」的位置
     （1280 的 50.0%、1366 的 49.5%、1440 的 48.0%、1680 的 49.5%、1920 的 49.6%）。
     现在比那个位置高出 8svh，**代价是眉题滑进画面顶部的中间调**——
     改完逐档实测过，见 README 第五节与 `backup/首屏文案上移_20261005/`。 */
  padding: 0 0 20svh;
}
/* 进场顺序：图片先淡入，眉题 → 主标题 → 副标题依次出现，全程约 0.8s。
   全部用 CSS 动画，脚本关掉时也完整呈现（规格第十四节：动效极轻、慢、只服务层级）。 */
.hero-copy > * { animation: hero-in .6s var(--ease) both; }
.hero-copy > *:nth-child(1) { animation-delay: .22s; }
.hero-copy > *:nth-child(2) { animation-delay: .36s; }
.hero-copy > *:nth-child(3) { animation-delay: .50s; }
.hero-copy > *:nth-child(4) { animation-delay: .62s; }
@keyframes hero-in {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}

/* 眉题：一行小英文，前置一条 26×1px 能量橙短线（规格第十一节给了这个组合）。
   整条眉题走橙色系——短线用原色 `#FF8A3D`（装饰元素、不受 AA 约束），
   文字用同一色相的压深档 `--accent-deep`：原色压在浅墙上只有 1.32:1，
   完全读不出来。这是「橙色只做一个小品牌信号」在浅底照片上唯一能同时成立的做法。 */
.hero-eyebrow {
  display: inline-flex; align-items: center; gap: 12px;
  font-size: 12.5px; font-weight: 600; letter-spacing: .21em; text-transform: uppercase;
  color: var(--accent-deep); white-space: nowrap;
  /* 视口比例接近 16:9 时，文案落在画面最左侧那一段，底色比 1440 那种裁过左右的
     视口低一截，橙字的底色也会跟着掉。加一道极轻的深色柔光把字托住：
     不铺底色、不加边框，在亮底上只是一圈看不出边的暗晕。
     注意这道柔光**不计入** WCAG 比值——contrast.py 量的是纯色对底色，
     所以文字色本身必须够深（见 --accent-deep 的说明），柔光只作观感补充。 */
  text-shadow: 0 1px 6px rgba(23, 26, 29, .42);
}
.hero-eyebrow::before {
  content: ""; width: 26px; height: 1px; background: var(--accent-fill); flex: none;
}
/* 主标题：两行手写断行（每行一个 span，窄屏也各占一行），行高 1.17。
   字号按视口比例走而不是写死 52px——文案列右边界必须留在画面 27% 以内，
   1440 下这一列只有 295px，52px 的六字一行会撑破这条线。 */
.hero h1, .hero .hero-title {
  margin-top: 16px; color: #33332F;
  font-size: clamp(28px, 3.1vw, 52px); line-height: 1.17;
  font-weight: 600; letter-spacing: -.005em;
}
.hero-title span { display: block; }
/* 副标题：16px / 行高 1.7 / 与主标题间距 17px（规格第十一节）。
   两句各自成行（窄屏并回一行自然折行）。字色偏离规格给的 #68675F——
   实测压在浅墙上只有 3.19:1；压到 #3A4046 后中位底 6.0:1、最暗片层 4.7:1。 */
.hero-sub {
  margin-top: 17px; font-size: 16px; color: #3A4046; line-height: 1.7;
  letter-spacing: .01em;
}
.hero-sub span { display: block; }
/* 副标题之后只挂一个入口：主按钮「产品中心」。定稿版第十节原本要求首屏
   一个按钮都不留，实际使用后补回这一个——三条产品线的入口需要有落点，
   而导航里的「产品中心」在右侧、滚动后才会再看到。
   主按钮仍是橙底墨黑字（墨黑压橙 7.08:1）。 */
.hero-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin-top: 30px; }
.hero-actions .btn { padding: 12px 22px; font-size: 15px; }
/* 序号不做橙色：11px 的小字压在照片上，橙（#A94E0C）只有 1.0:1，墨黑才有 4.6:1。
   「当前项」的橙色强调交给下面那条细线，信息不重复。 */

/* ---------- 7. 通用块 ---------- */
.grid { display: grid; gap: 28px; }
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }
.grid-5 { grid-template-columns: repeat(5, 1fr); }

.card {
  display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-card);
  overflow: hidden; transition: box-shadow .3s var(--ease), border-color .3s var(--ease);
}
/* hover 只做极轻的抬升与图片 1.02 缓推，不做浮夸位移 */
.card:hover { box-shadow: var(--shadow-card); border-color: var(--line-strong); }
/* height:auto 必须有：img 上的 height 属性会钉死高度，令 aspect-ratio 失效并纵向拉伸 */
.card-img {
  width: 100%; height: auto; aspect-ratio: 4 / 3; object-fit: cover;
  background: var(--bg-soft); transition: transform .55s var(--ease);
}
.card:hover .card-img { transform: scale(1.02); }
.card-img--wide { aspect-ratio: 16 / 10; }
.card-body { padding: 24px 26px 28px; display: flex; flex-direction: column; flex: 1 1 auto; }
.card-body .h3 { margin-bottom: 10px; }
.card-body p { color: var(--ink-2); font-size: 14.5px; line-height: 1.8; }
.card-foot { margin-top: auto; padding-top: 18px; }
.card-no {
  font-size: 12.5px; font-weight: 600; letter-spacing: .12em; color: var(--ink-3);
  margin-bottom: 10px; display: block;
}

/* ---------- 产品展陈单元（首页「石墨烯发热用品体系」三条线专用） ----------
   刻意与上面的 `.card` 分开另开一套：`.card` 是全站 43 个页面在用的通用卡片
   （307 处），带白底、描边与阴影；首页这一屏要的是展陈而不是信息卡，
   所以这里的每一项是「一张主视觉 + 一块轻量文字」两层：
     · 没有白底、没有描边、没有阴影，边界只由图片自己的圆角给出
     · 文字排在图片下方的自然留白里，不加底、不加框
     · 图片 4:5 竖幅（V1.30 起用 `images/home/systems-*.jpg`，源图本身就是 4:5，
       不再像 V1.26–V1.29 那样从 16:10 的横图里居中裁切），是这一屏唯一的视觉主体
   文字一律是文档流里的普通内容：不加透明度动画、不延迟显示、不依赖 hover，
   页面首次渲染时图片、名称、说明与链接同时可见。 */

/* 三列网格另开一类，不去动通用的 `.grid-3`（它还管着合作区与内页）。
   三条线等宽等权重，不做「大卡 + 小卡」。
   平板两列、窄屏一列也写在这里：媒体查询不加权重，
   同权重下后写的胜出，所以这类覆盖要跟在本组规则后面，不能散到别处。 */
/* V2.18：用户 2026-10-10 20:22 给了这一块的尺寸——区块内容宽约 1120、
   三列各约 360、图高约 330–350、比例近 1:1、列间距 24。
   1120 = 3×357 + 2×24，与「三列各约 360」对得上；**不动全站 `--wrap`（1240）**，
   只给这一组网格限宽，其他区块的栅格不受影响。
   **V2.19 修**：V2.18 当初写了 `margin: 0 auto` 把网格居中，于是左侧多出一条 36px
   的空白带（用户圈图：「把这个挪回去前面不要有空格」）→ **去掉居中、改左对齐**，
   与上方「PRODUCT SYSTEMS」标题左边缘齐平。 */
.pline-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px;
  max-width: 1120px; }
.pline { display: flex; flex-direction: column; }
.pline-media {
  /* margin: 0 必须有：figure 的 UA 默认样式是 `margin: 1em 40px`，
     不归零的话图片左右各被挤掉 40px、比单元窄 80px。 */
  margin: 0; position: relative; overflow: hidden;
  border-radius: var(--radius-card); background: var(--bg-soft);
}
.pline-media img {
  display: block; width: 100%; height: auto;
  /* V2.18：原 4:5（源图就是 800×1000），按用户要求改近方形；360/340 ≈ 1.06:1，
     三列各 357px 时图高约 337px，落在用户给的 330–350 区间里。
     源图仍留 4:5 不重裁，靠 `object-fit: cover` 收上下——三张的主体都在安全区内。 */
  aspect-ratio: 360 / 340; object-fit: cover;
  transition: transform .6s var(--ease);
}
/* hover 只做三件极轻的事：图片推 1.5%、箭头右移、链接转深一档色。
   没有位移、没有遮罩、没有浮层，也没有任何文字在 hover 前是隐藏的。 */
.pline:hover .pline-media img { transform: scale(1.015); }
.pline-body { padding-top: 26px; display: flex; flex-direction: column; flex: 1 1 auto; }
.pline-body h3 { font-size: 20px; font-weight: 600; color: var(--ink); }
/* `text-wrap: balance` 必须有：说明每句 29–30 字、约 420px，而三列时列宽只有 371px
   （一行 25 字），第一句必然折两行。不拉平时第二行只剩「应用。」这种两三个字的孤字
   （实测 367 / 44px），拉平后第一列与第二列各两行满宽、第三列三行均分，
   **三列都不出现孤字**。曾试过在两句之间插 `<br>` 强制断句，那样三列会各留一个孤字；
   也试过 `text-wrap: pretty`，对中文孤字不起作用（实测 367 / 44 不变）。 */
/* 字号 14px / 列间隙 32px 是**按最长那条说明反推出来的**，不是随手取的：
   三段说明最长的是采暖的 51 字，两行排的话每行要 26 字。字号 14.5px 时 26 字 ＝ 377px，
   而列宽只有 371px（间隙还是 40px 时）——差 6px 掉到三行，`balance` 再把三行平均成
   17 字，右侧就空出一大块（2026-10-08 用户圈出来的就是这块）。现在：
   列宽 (1192 − 32×2) ÷ 3 ＝ 376px，26 字 × 14px ＝ 364px，**留 12px 余量**；
   换字或换字体都不至于立刻再破。三段的实测行数因此统一成 2 / 2 / 2。
   **改这三段文案前先按这个式子算一遍**：两行 → 字数 ÷ 2 ≤ 列宽 ÷ 字号。 */
.pline-body p { margin-top: 10px; margin-bottom: 18px; font-size: 14.5px; line-height: 1.75; color: var(--ink-2); text-wrap: balance; }
/* align-self 必须有：`.arrow-link` 是 inline-flex，进了 flex 容器就按默认的
   stretch 被拉满整行宽，箭头会跑到最右边去。
   `margin-top: auto` 把三条链接钉在各自单元的底部——三句说明由两句组成、折出的行数
   不一定相同，不钉的话三条链接各按自己的文字高度落位，右侧两条会与第一条错开一行。
   说明与链接之间的最小间距由 `p` 的 `margin-bottom` 兜住（flex 容器的 margin 不合并）。 */
.pline-body .arrow-link { align-self: flex-start; margin-top: auto; }
.pline:hover .arrow-link { gap: 12px; color: var(--accent-deep); }

/* 平板两列、窄屏一列。竖幅图在单列下会独占大半屏，所以窄屏用 48px 行距把三项分开。 */
@media (max-width: 1080px) {
  .pline-grid { grid-template-columns: repeat(2, 1fr); gap: 32px; }
}
@media (max-width: 760px) {
  .pline-grid { grid-template-columns: 1fr; gap: 48px; }
  .pline-body { padding-top: 22px; }
}

.feature { display: flex; flex-direction: column; gap: 14px; }
.feature-num {
  font-size: 12.5px; font-weight: 700; letter-spacing: .14em; color: var(--accent);
  padding-bottom: 12px; border-bottom: 1px solid var(--line);
}
.feature h3 { font-size: 20px; }
.feature p { color: var(--ink-2); font-size: 14.5px; line-height: 1.8; }

.scene {
  position: relative; display: block; overflow: hidden;
  border-radius: var(--radius-card); border: 1px solid var(--line); background: var(--surface);
}
.scene img { width: 100%; height: auto; aspect-ratio: 1 / 1; object-fit: cover; transition: transform .55s var(--ease); }
.scene:hover img { transform: scale(1.02); }
.scene-body { padding: 18px 20px 22px; }
.scene-body h4 { font-size: 16px; margin-bottom: 6px; }
.scene-body p { font-size: 13.5px; color: var(--ink-2); line-height: 1.7; }

.media { border-radius: var(--radius-card); overflow: hidden; background: var(--bg-soft); }
.media img { width: 100%; height: 100%; object-fit: cover; }

.split { display: grid; grid-template-columns: 1fr 1fr; gap: 64px; align-items: center; }
.split--wide-left { grid-template-columns: 1.15fr .85fr; }
.split--wide-right { grid-template-columns: .85fr 1.15fr; }

.stat-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 32px; padding-top: 32px; border-top: 1px solid var(--line); }
.stat-num { font-size: clamp(28px, 3vw, 38px); font-weight: 700; letter-spacing: -.02em; color: var(--accent); line-height: 1.1; }
.stat-lbl { margin-top: 8px; font-size: 14.5px; color: var(--ink-2); }
.section--deep .stat-row { border-top-color: var(--line-dark); }
.section--deep .stat-num { color: var(--orange); }
.section--deep .stat-lbl { color: var(--text-on-dark); }

/* 表 */
.tbl { font-size: 14.5px; }
.tbl caption { text-align: left; font-size: 13.5px; color: var(--ink-3); padding-bottom: 10px; }
.tbl th, .tbl td { padding: 13px 16px; text-align: left; border-bottom: 1px solid var(--line); vertical-align: top; }
.tbl th { width: 38%; font-weight: 600; color: var(--ink-2); background: var(--bg); }
.tbl td { color: var(--ink); }
.tbl tr:last-child th, .tbl tr:last-child td { border-bottom: 0; }
.tbl-note { margin-top: 14px; font-size: 13.5px; color: var(--ink-3); }

/* ---------- 8. 首页区块 ---------- */
/* 第二屏：核心材料 → 产品 → 应用。
   **左文 43%、右图 47%、中间 10% 的缝**（用户给定）——不是对半硬切，
   两侧各自留白，右图比左文略宽一点，视线先落在图上再回到文字。
   `align-items: center`（继承 `.split`）让较矮的文字块在右侧竖幅旁垂直居中。 */
.split--core { grid-template-columns: 43fr 47fr; gap: 10%; }

/* 竖幅组合图：三张真实照片（材料微距 / 发热披肩 / 人物使用）纵向拼成 1:1，
   拼接脚本见 `_gen/build_p1.py` 里 `CORE_IMG` 的注释。
   圆角取 `--radius-lg`（20px）而不是卡片的 14px——560px 宽的图上 14px 看不出圆角。 */
.core-visual { margin: 0; }
.core-visual img { display: block; width: 100%; height: auto; border-radius: var(--radius-lg); }

/* 正文：一到两句，宽不超 34em，保持两三行的自然折行 */
.core-lead { margin-top: 22px; font-size: 17px; line-height: 1.9; color: var(--ink-2); max-width: 34em; }

/* 三个能力词：只作轻量辅助。**不是数据区、不是卡片**——
   上边一条极细的分隔线接住版面节奏（原先这里是一组统计数字，删掉后不能留空），
   下面三个词平铺，词间用 1px 竖线分隔，字号 14.5px，颜色与正文同档。 */
.cap-row {
  display: flex; flex-wrap: wrap; align-items: center;
  margin-top: 34px; padding-top: 26px; border-top: 1px solid var(--line);
}
.cap-row li { font-size: 14.5px; color: var(--ink-2); letter-spacing: .02em; }
.cap-row li + li::before {
  content: ""; display: inline-block; width: 1px; height: 12px;
  margin: 0 18px; vertical-align: -1px; background: var(--line-strong);
}

/* 合作方式 */
.steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
.step {
  padding: 30px 28px 32px; border-radius: var(--radius-card);
  border: 1px solid var(--line); background: var(--surface);
}
.step-no { font-size: 12.5px; font-weight: 700; letter-spacing: .14em; color: var(--accent); }
.step h3 { margin-top: 14px; font-size: 20px; }
.step p { margin-top: 10px; color: var(--ink-2); font-size: 14.5px; }
.step ul { margin-top: 14px; display: flex; flex-direction: column; gap: 7px; }
.step li { position: relative; padding-left: 16px; font-size: 13.5px; color: var(--ink-2); }
.step li::before {
  content: ""; position: absolute; left: 0; top: .62em;
  width: 5px; height: 5px; border-radius: 50%; background: var(--metal);
}

/* ---------- 无卡片信息格（V1.29 建，V1.45 起只剩「联系我们」在用） ----------
   与通用的 `.step` 白卡片分开：`.step` 在 4 个页面（合作模式／关于我们／核心材料／
   联系我们）用的是白底 + 描边 + 圆角；这一套要的是「无白卡片」的信息格，容器写
   修饰类 `.steps--bare`。**首页「合作方式」在 V1.45 换成了 `.coop` 无框矩阵**
   （见下面那条），所以这里现在只有「联系我们」的四格在用——改这个类之前先确认
   它只影响那一页。
   做法：
     · 去掉白底、描边、圆角，格子的边界只由顶部一条 1px 细线给出（细线在列间断开）
     · 列间 56px、行间 44px 的空当把格子分开，不加竖线、不加底色
     · 层次靠「细线 → 序号 → 标题 → 说明」四级做出来：序号与说明次灰、标题墨黑
       （**序号实际不是 `--accent` 的沉橙**：`.step-no` 是 `<p>`，被后面那条
       `.step p { color: var(--ink-2) }` 按书写顺序压掉了。现状如此，先记着。）
     · 不加图标、不加阴影、不加渐变
   容器写成 `.steps.steps--bare` 两段式而不是单写 `.steps--bare`：媒体查询里那条
   `.steps { 两列 }` 只到 900px，特异性相同，只靠顺序压不住，两段式才能稳。
   列数由 `--steps` 给（默认 3，联系我们的四格是 4），断点里那两条两列/单列规则
   对所有列数一视同仁，不必为 4 列再写一套。 */
.steps.steps--bare { display: grid; grid-template-columns: repeat(var(--steps, 3), 1fr); gap: 44px 56px; }
.steps--bare .step {
  padding: 26px 0 0; border: 0; border-top: 1px solid var(--line);
  border-radius: 0; background: transparent;
}
/* margin-top 必须有：基础样式里的 `.step p` 给所有段落加了 10px 上边距，
   序号也是 `<p>`，不归零就跟在细线下面 36px 处，层次第一级就散了。 */
.steps--bare .step-no { margin-top: 0; font-size: 12.5px; letter-spacing: .18em; }
.steps--bare .step h3 { margin-top: 16px; font-size: 20px; font-weight: 600; }
.steps--bare .step p { margin-top: 12px; line-height: 1.8; }

@media (max-width: 1080px) {
  .steps.steps--bare { grid-template-columns: repeat(2, 1fr); gap: 40px 44px; }
}
@media (max-width: 760px) {
  .steps.steps--bare { grid-template-columns: 1fr; gap: 34px; }
}

/* ---------- 合作方式（首页 B2B 入口，V1.45 重做）----------
   V1.29 那一版把白卡片换成「只留顶部细线」的六格，方向对，但还差三处：
   ①六格各有一条独立细线、列与列之间没有连起来，读起来仍是六个小方块，不成网格；
   ②每项只有「序号 → 标题 → 一段说明」两级，说明还是整句长文案，偏说明书；
   ③底部两个按钮（获取方案 / 联系商务）抢戏，而合作方式本身没有统一出口。
   现在改成一个**完整的无框矩阵**：3 列 × 2 行，列与列之间用竖细线真正连成网格，
   横向细线由每格的 `border-top` 拼成、纵向细线由第 2/3 列的 `border-left` 给出，
   **四周不封边**（只在下沿补一条收口的横线）——所以是「无框」而不是「六张卡」。
   每格三层＝「编号 · 英文小标签」一行 → 中文标题 → 一句说明，说明是一行的短句、
   不是段落。底部只留一个统一入口，不给每项单独配按钮。
   **配色只在本节生效**（分隔线 #D9D6CE / 标题 #30312E / 说明 #68675F），
   不动站内全局令牌——`.steps--bare` 现在归「联系我们」用，两边样式不再共用。
   英文标签走 `--accent`（沉橙 #A94E0C）而不是 `--accent-fill`（亮橙 #FF8A3D）：
   亮橙压暖白只有 2.07:1，站内早有一条硬约束「浅底文字一律走沉橙」，见《颜色》一节。 */
.coop {
  --coop-line: #D9D6CE;
  display: grid; grid-template-columns: repeat(3, 1fr);
  border-top: 1px solid var(--coop-line);
}
/* **V2.41：横线由「每格的上边」改到「每格的下边」**（用户 2026-10-13 圈着首页合作方式区：
   第二行右两格下方没有线，看着断开）。原方案是「各格上边线 ＋ 整块底边线」，条目数不是列数的
   整数倍时（现在 7 项排 3 列），末行的空格与上一行右格的下方就没有线。
   改成「整块顶边线（`.coop` 的 border-top）＋ 每格下边线」之后：
     · 每一行下面都有线，包括最后一行；
     · 行与行之间只有一条（不再上、下两条叠在一起）；
     · 条目不足一行时，空位没有格子也就没有线 —— 移动端折行后不会冒出多余的横线。
   竖线仍是「每行第 2 列起」加左边线（见下面的 nth-child 规则）。
   第 1 列左边距 0、第 3 列右边距 0，于是文字的左缘与右缘正好落在 `.wrap` 的两端。 */
.coop-cell {
  padding: 30px 32px 34px 0;
  border-bottom: 1px solid var(--coop-line);
  transition: border-bottom-color .3s var(--ease);
}
.coop-cell:nth-child(3n + 2),
.coop-cell:nth-child(3n) { border-left: 1px solid var(--coop-line); padding-left: 32px; }
.coop-cell:nth-child(3n) { padding-right: 0; }
/* hover 只做四件极轻的事，且**没有一件是「显示内容」**——四项内容首屏就全在，
   不依赖 hover 才读得到。位移放在子元素上，不动格子本身，否则边线会跟着一起挪。 */
.coop-cell > * { transition: transform .3s var(--ease), color .3s var(--ease); }
.coop-cell:hover { border-bottom-color: var(--accent-fill); }
.coop-cell:hover > * { transform: translateX(3px); }
.coop-cell:hover .coop-no { color: var(--accent); }
.coop-cell:hover h3 { color: var(--ink); }
/* 编号与英文标签并成同一行（中间一个「·」）——两者同属「标记」这一层，
   分两行只会让每格多占一行、整段被撑高，读的时候还要跨过一行空白。
   编号走 #68675F，英文走沉橙，靠颜色区分而不是靠换行。 */
.coop-meta { display: flex; align-items: baseline; }
.coop-no {
  font-size: 12.5px; font-weight: 600; letter-spacing: .1em;
  color: #68675F; font-variant-numeric: tabular-nums;
}
.coop-no::after { content: "·"; padding: 0 9px; font-weight: 400; }
.coop-en {
  font-size: 12.5px; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase; color: var(--accent);
}
.coop-cell h3 { margin-top: 12px; font-size: 20px; font-weight: 600; color: #30312E; }
.coop-x { margin-top: 10px; font-size: 14.5px; line-height: 1.7; color: #68675F; }
.coop-more { display: flex; justify-content: center; margin-top: 30px; }

/* 断点只换列数，四项内容一个字不动。每档先整体复位（`.coop .coop-cell` 与基础里的
   `:nth-child()` 同为 0,2,0，靠书写顺序覆盖），再按新列数补线——
   下面那条复位写在媒体查询里，位置在后，所以能压住基础规则。 */
@media (max-width: 1080px) {
  .coop { grid-template-columns: repeat(2, 1fr); }
  .coop .coop-cell { padding: 26px 0 30px; border-left: 0; }
  .coop-cell:nth-child(odd) { padding-right: 28px; }
  .coop-cell:nth-child(even) { border-left: 1px solid var(--coop-line); padding-left: 28px; }
}
@media (max-width: 760px) {
  .coop { grid-template-columns: 1fr; }
  .coop .coop-cell { padding: 22px 0 26px; border-left: 0; }
  .coop-cell h3 { font-size: 18px; }
  .coop-more { margin-top: 24px; }
}

/* ---------- 合作模式页（V1.48 建，V1.49 精简）----------
   这一页与首页分工：首页只回答「有哪些合作方式」（轻、三行一格），
   这一页回答「每一种大概是怎么回事」（六段大幅图文交替 + 一段说明 + 一行关键词）。
   全篇只有**两种**排版单位，不引入第三种：六段详情用 `.pm` 图文交替、流程用 `.flow`。
   **不新增「合作内容 / 可以开展 / 适合客户 / 合作要求」这类小标题**——
   六个模块各挂四五个同级小标题，整页会冒出三十来个标题，层级直接塌掉。
   V1.49 删掉了两块**只重复清单、不带来新信息**的区块：顶部那条「合作方式概览」
   六格矩阵（与首页同一份数据、同样三层）与底部那条「找到更合适的合作方向」
   六条目录——两者都在把 `.pm` 里已经讲过的六项再各说一遍，
   同一件事读三遍，阅读顺序反而糊。现在这一页只讲一次。
   概览用的 `.coop` 因此只剩首页一处引用，样式本身要留（首页在用）。 */

/* 六段详情：图文交替。媒体列略宽于文字列（1.02 : 1），因为读者先看图再读字。 */
.pm-list { display: flex; flex-direction: column; margin-top: 30px; }
.pm {
  display: grid; grid-template-columns: 1.02fr 1fr; gap: 64px; align-items: center;
  padding: 60px 0; border-top: 1px solid var(--line);
}
/* 首尾两段不要上下多余的分隔与留白：第一条不画线、最后一条不留底部空档，
   上下由 `section-head` 与 section 自身的 padding 承担。 */
.pm:first-child { border-top: 0; padding-top: 8px; }
.pm:last-child { padding-bottom: 8px; }
/* 交替靠 `order` 调换媒体列，**不动 DOM 顺序**——文字块在源码里始终排在 `<figure>` 之前，
   于是屏幕阅读器与关掉样式时都是先读到「这一段讲什么」再是那张图。
   媒体列默认 `order:-1` 落在左列；`.pm--rev` 把它推到 `1`，让文字接手左列。 */
.pm-media { order: -1; margin: 0; border-radius: var(--radius-card); overflow: hidden; background: var(--bg); }
.pm--rev .pm-media { order: 1; }
.pm-media img { display: block; width: 100%; height: auto; aspect-ratio: 3 / 2; object-fit: cover; }
.pm-meta { display: flex; align-items: baseline; }
.pm-no {
  font-size: 12.5px; font-weight: 600; letter-spacing: .1em;
  color: #68675F; font-variant-numeric: tabular-nums;
}
.pm-no::after { content: "·"; padding: 0 9px; font-weight: 400; }
.pm-en {
  font-size: 12.5px; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase; color: var(--accent);
}
.pm-body h3 { margin-top: 14px; font-size: 32px; font-weight: 600; line-height: 1.25; color: #30312E; }
.pm-desc { margin-top: 18px; font-size: 16px; line-height: 1.8; color: var(--ink-2); }
/* 合作内容关键词：横排，词间一条 1px 细竖线。**不做标签、不给每个词一个小卡片**，
   那会把「一行词」变成五个控件，视觉重量盖过标题。 */
.pm-tags { margin-top: 24px; font-size: 14.5px; color: #68675F; }
.pm-tags span + span::before {
  content: ""; display: inline-block; width: 1px; height: 11px;
  margin: 0 12px; vertical-align: -1px; background: var(--line-strong);
}

/* 合作流程：一条极细横线穿四列，序号压在线上作节点。
   线画在容器上、序号用底色把身后那段线遮掉，于是读起来是「线穿过节点」而不是「四段短线」。
   序号底色必须写 section 的实际底色（这里是 `--bg-soft`），否则深底页上会露白块。 */
.flow { position: relative; display: grid; grid-template-columns: repeat(4, 1fr); gap: 40px; list-style: none; }
.flow::before {
  content: ""; position: absolute; top: 11px; left: 0; right: 0; height: 1px;
  background: var(--line-strong);
}
.flow li { position: relative; padding-top: 42px; }
.flow-no {
  position: absolute; top: 0; left: 0; padding-right: 14px;
  background: var(--bg-soft); font-size: 22px; font-weight: 600; line-height: 22px;
  color: var(--accent); font-variant-numeric: tabular-nums;
}
.flow li h3 { font-size: 20px; font-weight: 600; color: var(--ink); }
.flow li > p:last-child { margin-top: 10px; font-size: 14.5px; line-height: 1.75; color: #68675F; }

/* 收尾商务区（V2.23：**由「整幅墨黑」改浅底**——用户 2026-10-11 00:59 圈出合作模式页
   这一块：「这个区域页需要调整成纯白色」。段类由 `section--deep cta-strong` 改为 `cta-strong`，
   所以下面三条文字色也从「深底那一档」换成「浅底那一档」：标题走墨色（不写即继承）、
   说明句 `--ink-2`、电话标签 `--ink-3`、电话号码墨色。橙色仍只出现在眉题与链接上。 */
.cta-strong { padding: 76px 0 80px; }
.cta-strong h2 { margin-top: 16px; font-size: 40px; font-weight: 600; line-height: 1.25; }
.cta-strong-sub { margin-top: 16px; font-size: 16px; line-height: 1.8; color: var(--ink-2); max-width: 46em; }
.cta-strong-row {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 40px;
  margin-top: 44px;
}
.cta-tel-label { font-size: 13.5px; font-weight: 600; letter-spacing: .12em; color: var(--ink-3); }
.cta-tel-num {
  display: block; margin-top: 8px;
  font-size: 32px; font-weight: 600; letter-spacing: .01em;
  color: var(--ink); font-variant-numeric: tabular-nums;
  transition: color .2s var(--ease);
}
.cta-tel-num:hover { color: var(--accent); }

@media (max-width: 1080px) {
  .pm { gap: 44px; padding: 44px 0; }
  .pm-body h3 { font-size: 30px; }
  /* 两列时那条贯通线会横穿两行、把第二行的序号甩在外面，所以这一档撤掉线，
     每格改用顶部一条短线分隔（与站内其它信息格同一套办法）。 */
  .flow { grid-template-columns: repeat(2, 1fr); gap: 30px 36px; }
  .flow::before { display: none; }
  .flow li { padding-top: 20px; border-top: 1px solid var(--line); }
  .flow-no { position: static; padding: 0; background: none; font-size: 19px; line-height: 1.4; }
  .flow li h3 { margin-top: 10px; }
  .cta-strong { padding: 56px 0 60px; }
  .cta-strong h2 { font-size: 32px; }
}
@media (max-width: 760px) {
  .pm { grid-template-columns: 1fr; gap: 26px; padding: 34px 0; }
  /* 单列时**统一改成文字在前、图片在后**（桌面那套左右交替在这一档没有意义）：
     一屏里先看到「这一段讲什么」，图片作为佐证跟在下面。
     文字块本来就是 DOM 里的第一个孩子，所以这一档只要把媒体的 `order` 复位即可——
     不加这条，`.pm--rev` 那三段（媒体 `order:1`）会让文字掉到图片下面。 */
  .pm-media { order: 1; }
  .pm-body h3 { font-size: 26px; }
  .pm-desc { font-size: 15px; }
  .pm-tags { font-size: 13.5px; }
  .flow { grid-template-columns: 1fr; gap: 0; }
  .flow li { padding: 20px 0 0; }
  .flow li + li { margin-top: 20px; }
  .cta-strong h2 { font-size: 27px; }
  .cta-strong-row { flex-direction: column; align-items: flex-start; gap: 26px; margin-top: 32px; }
  .cta-tel-num { font-size: 26px; }
}

/* ---------- 9. 频道页 / 目录页 / 详情页首屏 ---------- */
/* 有图的内页首屏与首页同一套做法：图从 y=0 起铺满、固定页头透明叠在图上、
   滚出这一屏后由脚本补墨黑底。两条令牌管住全局：
     --banner-h   有图内页首屏的最小高度。用户 2026-10-06 指定「除首页外至少占视口
                  3/4 高，要比原来高」，由 64svh 提到 **75svh**，并取消原来
                  「只在 ≥1201px 生效」的限制——窄屏原先靠内容撑高，实测
                  760px 档只有 48%、1200px 档 60%；带子比图矮时 `cover` 从上下裁，
                  图看不出全貌，抬高度就是为了少裁。
   顶上那条深色渐变是导航的承载面——**它必须和首页一样是深色**。
   这一版之前这里是暖白渐变（因为页头当时是墨黑实体层，暖白只是把硬边化开），
   页头改成透明叠图之后，暖白底上的暖白字会直接消失。 */
:root { --banner-h: 75svh; }

.page-hero {
  position: relative; padding: 172px 0 86px;
  background: var(--bg-soft); overflow: hidden;
}
.page-hero--deep { background: var(--bg-deep); color: var(--white); }
/* ---------- 三条产品目录页的首屏（V1.50，用户规范）----------
   规范要求目录页用「较克制的产品页 Hero」：**56vh、实际视觉高度约 520–600px**，
   不要做成首页那种接近全屏的。首页仍是 100svh、其余内页仍是 75svh——
   目录页的任务是让读者快一点进到产品里，hero 不该占掉一整屏。
   `clamp` 的下限 560 是「三个目录页首屏一样高」的落点：V1.54 把文字块压到 142px 起排后，
   内容最高的采暖／艾草两页是 555px（发热用品只 524px，说明句少一行），下限低于 555 就会
   被内容顶开、三页高度不一；抬到 560 之后三页在任何视口都同高。上限 600 挡住
   1080 以上视口的 56vh 继续变高。 */
.page-hero--line { --banner-h: clamp(560px, 56vh, 600px); }
/* ---------- 独立内页的首屏高度（V1.52，用户指定）----------
   核心材料 / 合作模式 / 关于我们 / 常见问题 / 联系我们 五页原先吃的是内页默认的
   `--banner-h: 75svh`，比三条产品目录页高出一大截。用户要求「参照产品目录页的尺寸
   调整」——所以这五页与目录页共用同一条高度：56vh、实际视觉高度 520–600px。
   **只取高度这一条**：目录页另挂的 `.page-hero--line` 还带着「去掉顶部那条合成压暗层 /
   去掉文字覆盖层 / 文字块 156px 起排 / 宽度收到 560px」一整套头图构图规则，那套只对
   目录页那三张「上缘本身就是深色承载面」的头图成立。这五页仍是浅顶照片，页头承载面
   本来就靠那条 170px 压暗（`.page-hero-bg::after`），两者不能混用。
   加了这个类之后，五页的正文块仍从默认的 `padding-top: 120px` 起排——高度掉到 520px
   后文字块离页头更近，但面包屑仍在压暗带之下，用 `contrast.mjs` 复测过。 */
.page-hero--compact { --banner-h: clamp(520px, 56vh, 600px); }
/* ---------- 37 个产品详情页的首屏高度统一（V1.53，用户指定）----------
   用户要求详情页顶部 banner「也跟其他页面统一高」。原先吃内页默认的 `75svh`
   （1440×900 下 675px），现在与三条目录页、五个独立页同一条：`clamp(520px, 56vh, 600px)`。
   **图片的铺法没动**：`.page-hero-bg img` 是 `object-fit: cover`、`object-position: center`，
   图按宽度铺满、上下对称裁。
   **要知道的取舍**：37 张详情页头图是产品场景照，比例 1.33–1.78:1，而带子在 1440 宽下是
   2.77:1——`cover` 必然要纵向裁掉约 40%（75svh 那档是 25%）。想让整张照片不被裁，
   只能把 37 张头图重出成 3.5:1（与三条目录页同一做法），那是 37 张图的量，未做。 */
.pd-top--img { --banner-h: clamp(520px, 56vh, 600px); }
/* ---------- 三条目录页：顶部不再叠任何东西（V1.53，用户规格）----------
   这份规格把「顶部黑色条带 / 顶部渐变 / 半透明黑色遮罩 / 单独设计导航背景」**全部列进禁忌项**，
   要求「整张图片从顶部到底部连续」。所以 V1.52 那条 120px / α .32 的轻渐隐也一齐关掉，
   页头承载面完全交给照片自身——三张新头图的上缘都是一条**横贯整幅、明度明显偏低**的
   建筑暗部（天花与墙/柜体的交界、柔和阴影，过渡连续无硬边，且不含窗户、天空、灯光、人物）。
   实测页头带（全宽 y0-84）白导航：采暖 5.79、发热用品 7.73、艾草 10.65；
   右侧一半分别是 7.10 / 10.66 / 12.41。**换头图必须重测这三处，不能目测。**
   `object-position` 取 **18%**：带子比图更宽时（≥1680 这种超宽视口）纵向裁切会吃掉顶部，
   锚点上移让裁掉的量落到下方的地板，而不是画面顶端那条暗部。 */
.page-hero--line .page-hero-bg::after { display: none; }
.page-hero--line .page-hero-bg img { object-position: 0% 18%; }
@media (min-width: 1201px) {
  /* **文案整块靠上（V1.39，用户标注）**：原来是 `align-items: center`，
     675px 高的带子里文字块浮在中间（实测面包屑顶在 y≈194）；
     用户在截图上画了一道红线，要求把整块提到贴着页头下沿。
     改成 `flex-start` 之后文字从 padding-top（120px）起排 ≈ 红线位置，
     带子下半段让给照片——与「banner 至少占视口 3/4」是同一件事的两面：
     抬高度的目的就是多出画面，文字不占中段才看得见。 */
  .page-hero--img {
    display: flex; align-items: flex-start;
    min-height: var(--banner-h); padding: 120px 0 72px;
  }
  .pd-top--img {
    display: flex; align-items: flex-start;
    min-height: var(--banner-h); padding: 120px 0 72px;
  }
}
/* 最小高度补成全档生效（2026-10-06）：上面那条只在 ≥1201px 给。
   窄屏原先完全靠内容撑高，760px 档实测只有视口的 48%。 */
.page-hero--img,
.pd-top--img { min-height: var(--banner-h); }

.page-hero-bg { position: absolute; inset: 0; }
.page-hero-bg img { width: 100%; height: 100%; object-fit: cover; }
/* 顶部自然压暗：只覆盖画面顶部 170px、向下衰减到 0，不形成整幅蒙版。
   与首页 `.hero::before` 同一口径（首页 150px / α0.50，这里略宽一点，
   因为内页首屏图顶部比首页那张更容易出现高亮天空或白墙）。
   `z-index: 2` 是为了压在 `.page-hero--nomask::before`（z-index 1）之上——
   页头是透明叠图，承载面必须是深色。 */
.page-hero-bg::after {
  content: ""; position: absolute; z-index: 2; inset: 0 0 auto 0; height: 170px;
  background: linear-gradient(180deg,
    rgba(23, 26, 29, .52) 0, rgba(23, 26, 29, .42) 48px,
    rgba(23, 26, 29, .24) 96px, rgba(23, 26, 29, .08) 134px,
    rgba(23, 26, 29, 0) 170px);
}
/* 内页首屏文案左对齐，与页头 logo 同一条左边缘。
   宽度用子元素约束：直接给本元素 max-width 会被 .wrap 的 auto margin 整块居中。
   **660px 同时也是这条柔光的上限**——文字块越宽，那条暖白柔光就得越大，
   大到一定程度就变成糊在照片上的一层雾。详情页首屏的说明句与渠道标签
   原先各有自己的宽度（76ch / 不限），加起来近 900px；收到 660px 后
   渠道标签折成两行、说明句折成三行，柔光才收得回来。 */
.page-hero--img .page-hero-inner > *,
.pd-top-inner > * { max-width: 660px; }
.page-hero-inner { position: relative; z-index: 2; }
/* 文字安全区：向外扩出的椭圆柔光，左右两侧都衰减到 0（左侧零点落在视口之外）。
   外扩量取 260px：既够容纳标题的负空间，右侧又不会糊到产品图上。
   详情页首屏共用同一条（`.pd-top-inner::before` 一并与它并列写在这里），
   不再单独写一套更宽的——宽柔光在照片上就是一层雾。 */
.page-hero--img .page-hero-inner::before,
.pd-top-inner::before {
  content: ""; position: absolute; z-index: 0; pointer-events: none;
  inset: -46px -260px -48px -260px;
  /* 纵向半径取 105%（不是 78%）：眉题在文字块的最上面，78% 的椭圆到那一行只剩
     约 0.16 的不透明度，等于没有承载——深底页实测眉题中位底只有 3.55:1。
     拉到 105% 之后顶部那一行能分到约 0.5，深底页的亮橙眉题才够。
     中段 48% 那一档从 .58 一路提到 .80：说明句到第三行时右端会伸到画面里的人物身上
     （实测发热披肩页最暗 5% 只有 1.28:1，那几个字正压在深色马甲上）。
     抬中段是唯一不用改文案、也不用把文字块缩到读不下去的办法。 */
  background: radial-gradient(ellipse 36% 106% at 31% 50%,
    rgba(243, 241, 234, .96) 0%, rgba(243, 241, 234, .93) 26%,
    rgba(243, 241, 234, .80) 48%, rgba(243, 241, 234, .36) 66%,
    rgba(243, 241, 234, 0) 80%);
}
.page-hero--img .page-hero-inner > *,
.pd-top-inner > * { position: relative; z-index: 1; }
/* 深底照片（实测左区平均亮度 <100）改用白字 + 墨黑保护层。
   底色暗的图上，墨黑柔光几乎看不出痕迹，比在暗图上糊一层暖白干净得多。
   顶部压暗与浅底那套共用同一条（已经是深色），这里不再另写。 */
.page-hero--dark .page-hero-inner::before {
  /* 深底页的眉题是**亮橙** #FF8A3D（不是浅底页那种压深的橙），它的相对亮度固定在 0.42，
     要守住 4.5:1 就必须把底压到 66 以下。第一版照搬浅底那套参数（.86 / 78% 半径），
     顶部那一行只分到 0.25 左右，实测中位底 3.55:1。
     改法：椭圆中心上移到 46%、纵向半径拉到 118%、起手不透明度提到 .94——
     眉题所在的那一行分到 0.5 上下，底色落到 60 附近。 */
  inset: -58px -260px -48px -260px;
  background: radial-gradient(ellipse 36% 118% at 34% 46%,
    rgba(23, 26, 29, .94) 0%, rgba(23, 26, 29, .88) 26%,
    rgba(23, 26, 29, .60) 48%, rgba(23, 26, 29, .20) 64%,
    rgba(23, 26, 29, 0) 76%);
}
/* 三条线目录页的文案底色（2026-10-06 用户指定「字后面那块色块必须去掉」）：
   原来那块挂在内层上，是一个半径 36%、α 到 .96 的椭圆——**它自己有边界**：
   椭圆盒之外忽然没有覆盖，截图里能圈出轮廓（用户圈的就是这条边）。
   改成挂在首屏自身、**铺满整幅的横向渐隐**：左边 α .58 起，沿宽度一路衰减到 88% 处归零，
   切在哪一段都读得出是照片本身的光。盒子与首屏等大，四边不再有第二种覆盖量。
   z-index 取 1：压在图之上、页头那条压暗（`.page-hero-bg::after`，z-index 2）之下，
   页头文字仍旧落在深色承载面上。
   为什么不能一点底色都不留：这三张头图在文字落点上都是中间调（采暖页说明句一带
   中位 L=139、最暗 5% L=62；艾草页压在深色柜体上），裸字实测说明句中位底 2.4–3.6:1、
   空心标签最暗处 1.0:1，远不到 AA。调参必须用 `contrast.mjs` 逐页复测。
   **顶部那 170px 压暗不在此列**：它服务的是透明页头，去掉会让页头文字掉进照片里。 */
.page-hero--nomask::before,
.pd-top--nomask::before {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(93deg,
    rgba(243, 241, 234, .58) 0%, rgba(243, 241, 234, .52) 30%,
    rgba(243, 241, 234, .42) 46%, rgba(243, 241, 234, .28) 60%,
    rgba(243, 241, 234, .12) 74%, rgba(243, 241, 234, 0) 88%);
  /* 顶部让开页头那一条：不遮的话这层会把压暗层垫亮，导航的暖白字从 9 档掉到
     3.54:1（实测）。**文案整块 V1.39 上移到 padding-top（120px）起排**，
     所以这条 ramp 也要跟着上收：84px 以下透明、124px 起全量。
     页头（0–77px）完全不受影响；两段都是渐变，不会在页头上切出一条边。 */
  -webkit-mask-image: linear-gradient(180deg, transparent 0, transparent 84px, #000 124px);
  mask-image: linear-gradient(180deg, transparent 0, transparent 84px, #000 124px);
}
/* 详情页的底色要更厚一档（V1.39）：37 张详情页头图是产品场景，中调与暗块比
   三条线页那三张居家图多得多——同一组 α（.58 起）在
   `products/textile/top` 上说明句只有 3.07:1、空心标签 3.74:1，量出来才改的。
   线页那几张是亮底，用厚一档反而会把照片洗白，所以两套并存、各按各的底图定。 */
.pd-top--nomask::before {
  background: linear-gradient(93deg,
    rgba(243, 241, 234, .78) 0%, rgba(243, 241, 234, .72) 30%,
    rgba(243, 241, 234, .62) 46%, rgba(243, 241, 234, .46) 60%,
    rgba(243, 241, 234, .22) 74%, rgba(243, 241, 234, 0) 90%);
}
/* 深底页面（核心材料 / 常见问题 / 招贤纳士）用同一套几何，只把暖白换成墨黑——
   这三页的文字是暖白，底色必须是暗的。更换的只是形状：由有边界的椭圆
   变成铺满整幅的渐隐，所以「色块」这件事一样被解决。 */
.page-hero--dark.page-hero--nomask::before {
  background: linear-gradient(93deg,
    rgba(23, 26, 29, .74) 0%, rgba(23, 26, 29, .68) 30%,
    rgba(23, 26, 29, .56) 46%, rgba(23, 26, 29, .36) 60%,
    rgba(23, 26, 29, .14) 74%, rgba(23, 26, 29, 0) 88%);
}
/* 内层那条椭圆整条关掉。**选择器要写足三个类**：≤760px 那条
   （`.page-hero--img .page-hero-inner::before`）排在文件更后面、特异性相同，
   写两个类会被它按顺序压掉。 */
.page-hero--img.page-hero--nomask .page-hero-inner::before,
.pd-top--img.pd-top--nomask .pd-top-inner::before { display: none; }

/* 三条目录页的首屏（V1.60）：照片满铺含导航、照片上零覆盖、文字压图。
   规则统一写在本文件**末尾**的「V1.60 首屏收口」一节——放在这里会被 ≤760 那个媒体块
   按顺序压掉（它同样给 `.page-hero--nomask::before` 与 `.page-hero--img .page-hero-inner::before` 设值）。 */

/* ---------- 详情页也去掉文字后面那层暖白（V1.53，用户指定）----------
   用户原话「图上不要有遮罩让人看起来雾蒙蒙的，去掉文字后面的遮罩」。37 个详情页的
   首屏图是产品场景照，原先靠 `.pd-top--nomask::before` 那条 α .78 起的暖白横向渐隐
   给墨色文字垫底——那层把照片左侧压成一块没有纹理的平色，正是「雾蒙蒙」的来源。
   这一版把文字整块移出了照片，所以这层**全档撤掉**，不再保留窄屏例外（V1.60 文字回到图上，
   但这一层没有再开——用户要求照片上零遮罩）。 */
.pd-top--img.pd-top--nomask::before { display: none; }
/* 窄档（≤1200）页头是墨黑实体层、不叠在图上，详情页首屏又已经没有文字了，
   那条顶压暗在这里没有任何服务对象——一并关掉，照片上一处遮罩都不留。
   ≥1201 留着：那一档页头透明叠图，没有它就是白 Logo 与白导航直接落在照片上。 */
@media (max-width: 1200px) {
  .pd-top--img .page-hero-bg::after { display: none; }
}

.page-hero h1 { margin-top: 14px; }
/* V2.21：四个独立页的首屏标题由「两三个字的栏目名」改成整句短语（用户给定的文案，
   最长是「专注石墨烯技术研发与应用」12 字）。全局那档 `clamp(34px, 5vw, 58px)`
   在 1440 下是 58px，12 字要 700px 出头、装不进 660px 的框，实测会甩出一个孤字
   （「…与应 / 用」）。这一类标题统一收一档到 52px，12 字正好一行。
   只挂 `page-hero--slogan`，其余内页的标题仍走全局那一档。 */
.page-hero--slogan h1 { font-size: clamp(30px, 3.9vw, 52px); }
.page-hero .page-sub { margin-top: 20px; font-size: 17px; color: var(--ink-2); line-height: 1.85; }
.page-hero .en { margin-top: 10px; }
/* 去掉柔光之后，压在照片上的次要文字要换用「压照片」那一档灰。
   `--ink-2 #4E555C` 与 `--ink-3 #5C636A` 是按暖白底（或那条柔光，底 202）算的，
   直接落在照片上只剩 3.4:1——柔光一撤就掉到 AA 之下。
   `--ink-2-photo #2F353B` 就是为这个场景留的令牌：同一个底上 5.4:1 起。
   主标题与眉题不用动（实测中位底 9.8–10.2 / 8.2–8.9）。
   **这三条必须排在上面的基础规则之后**——`.page-hero .page-sub` 与 `.page-hero--nomask .page-sub`
   特异性相同（都是两个类），靠顺序定胜负。 */
/* **详情页这四条要写足三个类**：`.pd-top .pd-en`（1040 行）与 `.pd-top .pd-desc`（1046 行）
   排在文件更后面、特异性与本条相同（都是两个类），写两个类会被它们按顺序压掉——
   实测就是这两处停在 `--ink-3`/`--ink-2` 上、掉到 3.0–3.2:1。 */
.page-hero--nomask .crumb,
.page-hero--nomask .crumb a,
.pd-top.pd-top--nomask .crumb,
.pd-top.pd-top--nomask .crumb a { color: var(--ink-2-photo); }
.page-hero--nomask .page-sub,
.pd-top.pd-top--nomask .pd-desc { color: var(--ink-2-photo); }
/* 英文小行（线页 `.en` / 详情页 `.pd-en`）原本走 `--ink-3`，同样是为暖白底算的。 */
.page-hero--nomask .en,
.pd-top.pd-top--nomask .pd-en { color: var(--ink-2-photo); }
/* 空心标签的描边落在照片上比暖白底难辨认，一并加深一档。 */
.page-hero--nomask .tag,
.pd-top.pd-top--nomask .tag { border-color: rgba(23, 26, 29, .34); color: var(--ink-2-photo); }
.page-hero .en { margin-top: 10px; }
/* 有图首屏上的眉题：`.eyebrow` 默认那档沉橙 `--accent #A94E0C` 是给暖白底算的，
   压在这条暖白柔光上（实测底 202）只有 3.39:1。改用压得更深的 `--accent-deep`
   ——与首页首屏眉题同一个值、同一套理由。短线仍保留原色作亮橙信号。 */
.page-hero--img .eyebrow { color: var(--accent-deep); }
.page-hero--img .eyebrow::before { background: var(--accent-fill); }

/* 深底首屏的文字色。整块必须排在基础规则之后：
   .page-hero--dark .page-sub 与 .page-hero .page-sub 特异性相同（同为 0,2,0），
   胜负只由书写顺序决定。放在前面会被基础色 --ink-2 反超——浅底页看不出问题，深底页正文直接读不出来。 */
.page-hero--dark h1 { color: var(--white); }
.page-hero--dark .page-sub { color: rgba(255, 255, 255, .86); }
.page-hero--dark .crumb, .page-hero--dark .crumb a { color: rgba(255, 255, 255, .74); }
.page-hero--dark .en { color: rgba(255, 255, 255, .62); }
.page-hero--dark .eyebrow { color: var(--orange); }
.page-hero--dark .eyebrow::before { background: var(--orange); }
.page-hero--dark .tag { border-color: rgba(255, 255, 255, .38); color: rgba(255, 255, 255, .9); }
.page-hero--dark .tag--solid { background: var(--white); color: var(--ink); border-color: var(--white); }
.page-hero--dark .tag--accent { border-color: var(--orange); color: var(--orange); }

/* ---------- 采暖页首屏曾单挂深底变体（V1.56），V1.58 已撤 ----------
   2026-10-08 用户先给了一张「左暗」的成片（左墙 L≈20、上缘 L≈50），那一页因此单挂
   `.page-hero--dark` 走暖白字，并配了三条覆写：标签改实底暖白芯片（1440 档标签压在
   受光地板上，底 L=157，白字只有 2.71:1）、眉题改暖白（1201 档落点底 L=82，亮橙只有
   3.38:1）、文字块收到 460px（2560 档说明句右端越进亮区）。
   同一天用户又换上一张**明亮的横向空间**（左侧一排背光立柱 L≈23–44、中右受光的浅墙与
   落地窗 L≈130–238），三页字色统一到 `.page-hero--onlight`，那三条只为
   `.page-hero--line.page-hero--dark` 生效的覆写随之删除——**不留死样式**。
   教训：同一组页面里换一张头图就可能把字色整套掀掉；换图后「顶部带（托白字还是托墨字）」
   与「正文块落点」两处都要重量一遍，再决定挂哪一套。 */
.page-hero--dark .tag--soft { background: rgba(255, 138, 61, .18); border-color: transparent; color: var(--orange); }

/* 面包屑：V1.39 由 13px 提到 14.5px（用户反馈「太小」）。
   取 14.5px 是因为它就站内已有的那一档——与导航项同一个字号，
   比眉题（12.5–13px）大一头、比说明句（17px）小一档，仍是三级里的中间层。
   再往上到 15px 就与说明句抢层级了。 */
.crumb { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; font-size: 14.5px; color: var(--ink-3); }
.crumb a:hover { color: var(--accent); }
.crumb span.sep { opacity: .5; }

/* ---------- 线页左侧树形目录（V1.39，替换原来那条吸顶分类条）----------
   与产品卡左右并排：左栏固定 216px、右栏自适应（`minmax(0,1fr)` 防止长内容把栅格撑破），
   `align-items: start` 让树自己吸顶。树用 `position: sticky` + `top: var(--header-h)`——
   **行为与原来那条吸顶条完全一致**（滚出首屏后一直挂在页头下沿），只是从横条变成竖列。
   视觉上不铺白底、不描边、不加圆角：树是版面的左栏，不是一个卡片。
   当前项只靠三件事表示：序号转沉橙、文字转墨黑、左侧一条 2px 橙色竖线。
   **右栏窄了，三列卡片自然跟着缩**（1440 下每张由 378px 收到 292px）——
   这是「加了树形菜单、右边卡片要缩小」的实现方式，不需要另给卡片定尺寸。 */
/* 左栏宽度 V2.23 起与三条目录页的 `.line-layout` 对齐（240px / 56px）——
   用户 2026-10-11 00:59：「常见问题 的左侧菜单页一并调整成跟前面目录页一样」。
   下面那组规则是照 `.line-nav`（V2.17 定的那套纯白极简）逐条搬过来的，
   只把类名前缀从 `.line-nav*` 换成 `.cat-tree*`，**不动 `.line-*` 的共用规则**：
     · 容器 `position: sticky` + `top: 页头 + 28px`，纯白底、无圆角阴影；
     · 标题区「英文小标在上、中文标题在下」，标题下一条 `#E8E8E5` 横线；
     · 章节行 20px 上下留白、章节间 1px 分隔线、编号固定列宽 26px；
     · **当前项只留一条铜橙 `#B95C32` 定位线**（不用橙色填充块），编号转铜橙。
   与目录页唯一的差别：目录页标题是「本页导航」，这一页是「问题分类」（内容不同、不硬套词）。 */
.cat-layout { display: grid; grid-template-columns: 240px minmax(0, 1fr); gap: 56px; align-items: start; }
.cat-tree {
  position: sticky; top: calc(var(--header-h) + 28px); z-index: 30;
  background: #FFFFFF; padding: 26px 20px; margin: 0 -20px;
  --nav-orange: #B95C32;
  --nav-line: #E8E8E5;
  --nav-ink: #252622;
  --nav-ink-2: #30312D;
  --nav-ink-3: #777872;
  --nav-ink-4: #898A84;
}
.cat-tree-en { font-size: 12.5px; letter-spacing: .24em; color: var(--nav-ink-4); }
.cat-tree-t {
  margin-top: 8px; padding-bottom: 14px;
  border-bottom: 1px solid var(--nav-line);
  font-size: 24px; font-weight: 500; color: var(--nav-ink);
}
.cat-tree ul { display: flex; flex-direction: column; }
.cat-tree li + li { border-top: 1px solid var(--nav-line); }
.cat-tree a {
  display: flex; gap: 10px; align-items: baseline;
  padding: 20px 12px; border-left: 2px solid transparent;
  font-size: 15.5px; font-weight: 500; line-height: 1.4; color: var(--nav-ink-2);
  transition: color .2s var(--ease), border-left-color .2s var(--ease);
}
.cat-tree-no {
  flex: none; width: 26px; font-size: 12.5px; letter-spacing: .02em;
  color: var(--nav-ink-4); font-variant-numeric: tabular-nums;
  transition: color .2s var(--ease);
}
.cat-tree-nm { font-size: 15.5px; font-weight: 500; }
.cat-tree a:hover { color: var(--nav-ink); }
.cat-tree a.is-active {
  background: transparent; border-left-color: var(--nav-orange);
  color: var(--nav-ink); font-weight: 600;
}
.cat-tree a.is-active .cat-tree-no { color: var(--nav-orange); font-weight: 600; }

/* 有树形目录的页，锚点偏移只要让开页头（原来还要让开那条 66px 的吸顶条）。 */
html:has(.cat-tree) { scroll-padding-top: calc(var(--header-h) + 24px); }

/* 分类块上下留白 28 → 44px（V1.50，用户规范）：
   「分类之间使用足够留白，让用户浏览过程中有明显的章节感」。上一轮把全站留白压到
   三分之一时这里跟着收到了 28px，四个分类连成一片、看不出章节。只回这一处，
   全站 `.section` 的节奏不动。 */
.cat-block { padding: 44px 0; }
.cat-block + .cat-block { border-top: 1px solid var(--line); }
.cat-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; margin-bottom: 22px; }
.cat-head .cat-count { font-size: 13.5px; color: var(--ink-3); letter-spacing: .06em; }

/* ---------- 核心优势：一条优势一张卡（V1.51 恢复，4 列）----------
   V1.50 曾把它压成「3 张大模块 + 模块下挂文字行」，那样每条优势并不都有自己的图，
   用户看到的是「有的有图有的无图」。规范要的是 **4 列视觉卡片**，于是整段回到
   卡片网格（`.card` + `.card-img--wide`，16:10，图 800×500），只把列数从 3 提到 4。
   窄屏列数只给核心优势这一处：`.grid-4` 在核心材料 / 产品中心 / 招贤纳士也在用，
   动它会波及那三页，所以另挂 `adv-cards`。 */
@media (max-width: 760px) { .adv-cards { grid-template-columns: 1fr; } }

/* ---------- 9.5 招贤纳士 ---------- */
.job-list { display: flex; flex-direction: column; gap: 20px; }
.job {
  padding: 34px 36px 36px; border-radius: var(--radius-card);
  border: 1px solid var(--line); background: var(--surface);
}
.job-head {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 10px 18px;
  padding-bottom: 20px; border-bottom: 1px solid var(--line);
}
.job-head h3 { font-size: 20px; }
.job-meta { font-size: 13.5px; color: var(--ink-3); }
.job-meta .sep { opacity: .45; margin: 0 6px; }
.job-body { display: grid; grid-template-columns: 1fr 1fr; gap: 26px 48px; padding-top: 22px; }
.job-body h4 { font-size: 14.5px; font-weight: 600; color: var(--accent); letter-spacing: .06em; margin-bottom: 12px; }
.job-body ul { display: flex; flex-direction: column; gap: 8px; }
.job-body li { position: relative; padding-left: 16px; font-size: 14.5px; line-height: 1.75; color: var(--ink-2); }
.job-body li::before {
  content: ""; position: absolute; left: 0; top: .68em;
  width: 4px; height: 4px; border-radius: 50%; background: var(--metal);
}

/* ---------- 10. 产品详情页 ---------- */
/* 产品详情页首屏。以前是一块暖白纯色，37 页全无图；现在与目录页同一套：
   图整幅铺底、固定页头透明叠在图上、滚出后补墨黑底。
   文字仍走墨黑 + 暖白椭圆柔光——这条柔光与 `.page-hero--img` 同一条，
   在上面 660px 那条规则里并列写过（早先给详情页单独写了一条更宽的，
   结果是照片上糊一层雾，已撤）。 */
.pd-top { position: relative; padding: 158px 0 72px; background: var(--bg-soft); overflow: hidden; }
.pd-top-inner { position: relative; z-index: 2; }
.pd-top h1 { margin-top: 16px; }
/* 详情页首屏（V1.60）：照片满铺含导航、零覆盖、标题块压回图上贴底。
   规则见本文件末尾「V1.60 首屏收口」一节。V1.53 那次为躲遮罩把标题块移到了
   照片下方，V1.60 用户要求与目录页同一逻辑，已改回图上。 */
.pd-top .pd-en { margin-top: 12px; font-size: 12.5px; font-weight: 600; letter-spacing: .18em; text-transform: uppercase; color: var(--ink-3); }
/* 宽度交给上一条 `.pd-top-inner > *`（660px）统一管。
   **不要在这里写 `max-width`（包括 `none`）**——`.pd-top .pd-desc` 是两个类、
   `.pd-top-inner > *` 只有一个类，写什么都由前者胜出，`none` 会把 660px 顶掉。 */
.pd-top .pd-desc { margin-top: 24px; font-size: 17px; line-height: 1.9; color: var(--ink-2); }
.pd-top .tag-row { margin-top: 26px; }

/* ---------- 详情页「页面位置 + 返回产品列表」条（V1.40）----------
   原来详情页只有一行面包屑，而且压在首屏照片上、只到产品线一级。用户从列表点进
   一个产品之后就不知道自己在哪一层、也找不到回列表的入口。改成：
   · 面包屑**移出首屏**，落在首屏与正文之间一条独立的暖白条上（不占 banner
     区域、不吸顶、不悬浮——用户对这一条的要求明确写了「禁止吸顶导航」）；
   · 层级补全到五级：首页 / 产品中心 / 产品线 / 分类 / 产品名，末级置灰不可点；
   · 同一行右端放「返回产品列表」，落点是列表页里该产品所属分类的锚点。
   这一条只承担「我在哪、怎么走」，所以文字走 `--ink-3`／`--ink-2`，视觉上明确
   弱于产品标题；底色取 `--bg`（暖白），与下面 `--surface`（纯白）的正文分开。 */
.pd-crumb-bar { background: var(--bg); border-bottom: 1px solid var(--line); }
.pd-crumb-bar .wrap {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px 24px; padding-top: 15px; padding-bottom: 15px;
}
.pd-crumb-bar .crumb { flex: 1 1 auto; min-width: 0; }
/* 返回按钮做成细描边的胶囊而不是裸文字：它要在一屏照片的下面被一眼找到，
   但又不能与产品标题抢——描边走 `--line-strong`、文字走 `--ink-2`，
   悬停才升到墨黑。箭头与站内其余图标同一套线宽（1.7 / round）。 */
.pd-back {
  flex: none; display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 14px 7px 11px; border-radius: 999px;
  border: 1px solid var(--line-strong);
  font-size: 13.5px; font-weight: 500; color: var(--ink-2);
  transition: color .2s var(--ease), border-color .2s var(--ease), background .2s var(--ease);
}
.pd-back svg { width: 15px; height: 15px; flex: none; }
.pd-back:hover { color: var(--ink); border-color: var(--ink); background: rgba(23, 26, 29, .04); }

.pd-info { padding: 28px 0; background: var(--surface); }
.pd-info-grid { display: grid; grid-template-columns: 1.02fr .98fr; gap: 64px; align-items: start; }
.pd-info-media { border-radius: var(--radius-card); overflow: hidden; background: var(--bg); }
/* 产品图按 16:10 出，与图库里的实际比例一致（原先写 4:3，会把 16:10 的源图上下各切一块） */
.pd-info-media img { width: 100%; height: auto; aspect-ratio: 16 / 10; object-fit: cover; }
.pd-info-sub { font-size: 17px; color: var(--ink-2); line-height: 1.85; margin-bottom: 28px; }
.pd-info h3 { margin-bottom: 16px; }
.pd-params { background: var(--bg); border-radius: var(--radius-md); overflow: hidden; }

.pd-features { padding: 28px 0; background: var(--surface); }
.pd-features .grid { margin-top: 0; }

.pd-scenes { padding: 28px 0; background: var(--bg-soft); }
.scene-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px; }
.scene-grid .scene img { aspect-ratio: 1 / 1; }

.pd-status { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 22px; }
.pd-status .chip {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 15px; border-radius: 999px; font-size: 13.5px;
  border: 1px solid var(--line-strong); color: var(--ink-2);
}
.pd-status .chip::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--accent-fill); flex: none;
}

/* 转化区
   原先整块能量橙实底，橙色面积太大，与「橙色只占 3%–5%」的用色比例冲突。
   改为墨黑实底 + 橙色主按钮：深底压得住，橙色只留在按钮上。 */
/* V2.23：**去掉深色圆角卡**（用户 2026-10-11 00:59 圈出这张卡：「这种的黑框也不要了。
   都调整把框给取了」）。原先 `.cta-card` 是「墨黑实底 + 大圆角 + 56/60 内边距」的一只盒子，
   现在三层全去掉——底色透明（露出所在页面的底）、圆角归零、内边距归零，
   内容直接与上下区块同一条左边缘起排，与站内其余分区一个版式。
   文字回到浅底那一档（标题走墨色、正文 `--ink-2`），次按钮由 `btn-ghost-light`
   （深底白描边）换成 `btn-ghost`（浅底墨描边）——**按钮类在 `sitecore.cta_band()` 里同步改了**。
   窄档那两条给 `.cta-card` 补 padding 的规则也一并归零，否则会在小屏把内边距加回来。 */
.cta-band { padding: 44px 0; }
.cta-card {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 32px;
}
.cta-card h2 { max-width: 22ch; }
/* V2.52（2026-10-13）：46ch → 62ch。原来 46ch ≈ 370px，而默认那句「渠道合作 · OEM ·
   ODM · 品牌定制 · 项目采购 · 产品开发。」单行实测要 432px，末尾「发。」被挤到第二行，
   用户报「就一个字还换行很诡异」；常见问题那页的自定义句（「产品选型、方案洽谈与品牌定制，
   都可以直接联系我们。」）同样吃紧。
   **实测确认**：`.cta-card p` 是伸缩项里的块，宽度本来就按单行内容取（432px），
   所以只要上限 ≥ 432 就不换行，**上限调大不会让这一行变长**（视觉零变化）。
   62ch ≈ 500px 留 16% 余量，数值同时与详情页 04 区那句的 `.pdv-coop-tx`（也是 62ch）拉平。
   窄档的容器本来就比它窄，该换行时照旧换行。 */
.cta-card p { margin-top: 12px; color: var(--ink-2); font-size: 15.5px; max-width: 62ch; }
.cta-card .cta-actions { display: flex; flex-wrap: wrap; gap: 14px; }

/* ---------- 11. 页脚 / 浮条 / 弹层 ---------- */
.site-footer { background: var(--bg-deep); color: var(--text-on-dark); padding: 72px 0 0; }
/* 六组：品牌 + 产品体系 + 关于我们 + 企业与合作 + 联系我们 + 扫码关注。
   **V2.55 照用户给的参照稿重排**（用户：「底部参照这个排版给优化下」）。参照稿是
   「品牌 ｜ 产品体系 ｜ 关于我们 ｜ 企业与合作 ｜ 联系我们 ｜ 两个二维码」，五个文字组 ＋ 一列码。
   原来的四组是「产品线／了解我们（4 条挤一列）／联系方式（一坨 `footer-meta` 文本）／扫码联系」，
   这一版：① 「产品线」改名 **产品体系**（与首页那一段同一个词）；② 4 条链接拆成
   **关于我们（公司简介·招贤纳士）／企业与合作（合作模式·常见问题）** 两列，列与列之间才有呼吸；
   ③ 「联系方式」改成 **图标 ＋ 一行一项**（电话／邮箱／地址／官网）；④ 码下面补一行说明。
   **列宽由内容定、余量全部进列与列之间的缝（V1.12 从「按比例分配」改过来）。**
   按比例分配（原 1.1fr .68fr .68fr 1.44fr 268px）在 1240px 栅格上看着还行，
   但首页页脚要跟页头一样走 `--hero-edge`（见下面那条 `body:has(.hero)` 规则），
   1920 下整幅内容宽到 1598px——比内容本身多出 600 多 px。那些余量若按比例分，
   会摊成「一列 476px 宽、里面只装 315px 的字」这种空膛；改成 space-between 之后
   余量落在缝里，   读起来还是「六组并排」，只是更透气，与页头「左右各自贴边、
   中间留大片空」的性格一致。列间距用 `clamp(24px, 2.2vw, 52px)`（1920 下 42px、1201 下 26px）。 */
.footer-grid {
  display: grid;
  /* 两个固定轨：**联系我们 248px、扫码关注 360px**，都不参与 `auto` 伸缩。
     扫码那列钉死是因为二维码被压扁了就不是二维码（V2.67 起该列改成双栏白卡：
     1240 栅格下两卡各 172、码 140，故由 268 加宽到 360；1150 的三列档与 900 的
     两列档下卡片自动收缩，实测无溢出）；
     联系我们那列钉死是因为**地址的 max-content 有 378px**——若让它 auto，它会一个人
     吃掉整行的余量、把别的列挤到没有缝（参照稿里地址本来就是折两行的）。
     248px 是 V2.58 从 232 加上去的：四行补了小标题之后，值那一列只剩 188px，
     28 个字的地址刚好折两行（再窄就三行、再宽会挤到 1081–1090 那一档的缝）。 */
  grid-template-columns: auto auto auto auto 248px 360px;
  justify-content: space-between;
  column-gap: clamp(24px, 2.2vw, 52px);
  row-gap: 30px;
  padding-bottom: 52px;
}
/* 左品牌块定宽上限 240px（`auto` 轨道会取内容的最大宽度，不设上限时品牌块会跟着内容撑宽）。
   **V2.62（2026-10-13，用户指定）品牌语换成「生活，不止一种答案」**——9 字，一行放得下，
   模板里**不再带 `<br>`**。这一句现在与**首屏主标题**同文（V2.60 时它与首屏副标题同文）。
   **品牌块的实际宽度由内容定**：旧句（16 字）是 235px，现在约 130px；`auto` 轨道会跟着缩，
   余量落进列与列之间的缝里，所以**换句之后要复量一遍页脚各档**（本次已量 1201／1280／1440／1920）。
   上限 240px 现在只在品牌语写得更长时才起作用（232 → 240 是 V2.60 为 16 字那一行定的）。
   **以后改品牌语句，注意这一行是否需要重新加 `<br>`。**
   规格第三节要的「左侧品牌区域保持稳定」落在这条上限上。 */
.footer-brand { max-width: 240px; }
/* **页脚与首页中间六段内容，都回到与内页同一个 `.wrap` 栅格**（2026-10-05 收窄）。
   这两个位置曾经单独走 `--hero-edge`（8vw）：页脚是 2026-10-05 早些时候为了
   「底栏与顶栏同一条左右基准」加的，中间内容是紧随其后为了「上下贴边、中间也要贴边」加的。
   两条合起来把首页内容铺到 1612px（1920 下），比其余页面的 1240px 栅格宽 372px。

   撤销的判断依据是**与内页的观感一致性**：核心材料、应用场景、合作模式等页面都是
   1240px 居中，首页宽出一大截，两块放一起就不是一套版面。现在三处（页头、
   中间内容、页脚）统一到 `.wrap`，左右缘与核心材料页逐像素一致。

   页脚栅格本身（`auto` 轨道 + `space-between` + 末列 268px）**保留**：
   它在 1192px 下同样正常工作，且是「余量进缝、二维码不被压」那条的实现，
   与基准是两件事。 */

/* 标题折行时把两行拉平，别让末行只剩一个字。
   首页第一段与深底「材料」段的标题都是完整短句（「从核心材料，到温暖产品」／
   「材料，是产品创新的起点。」），窄视口（1201–1240 档，左列 402–463px）按默认断法
   会把末字甩到第二行，只剩「点」这样的单个字。`text-wrap: balance` 让两行等宽——
   **单行时它不生效**，所以 1440 及以上看不到任何变化（实测像素级比对差异为空）。
   只给首页：内页标题不在改动范围内。 */
body:has(.hero) main > .section h2,
body:has(.hero) main > .section h3 { text-wrap: balance; }
.footer-brand .footer-logo {
  /* 画布 829×278（比例 2.98）：140px 宽对应 47px 高。
     原来写 56px 高是照早先的比例留的，多出来的 9px 全是空的（contain 会上下居中），
     看起来像 Logo 与下面那句品牌简介之间多了一层间距。盒子收到真比例。 */
  width: 140px; height: 47px; display: block;
  background: url(../images/brand/logo-mjxn-white.png) left center/contain no-repeat;
}
.footer-slogan { margin-top: 24px; font-size: 14.5px; line-height: 1.9; color: var(--text-on-dark); max-width: 34ch; }
.footer-en { margin-top: 14px; font-size: 12.5px; letter-spacing: .2em; color: var(--text-on-dark-2); }
.footer-col h2, .footer-col h4 { font-size: 13.5px; line-height: 1.5; letter-spacing: .1em; color: var(--white); margin-bottom: 18px; font-weight: 600; }
.footer-col ul { display: flex; flex-direction: column; gap: 11px; }
.footer-col a { font-size: 14.5px; color: var(--text-on-dark); transition: color .2s var(--ease); }
.footer-col a:hover { color: var(--orange); }
.footer-meta { font-size: 13.5px; line-height: 1.9; color: var(--text-on-dark); }
/* V2.55：「联系我们」由一坨 `footer-meta` 文本改成**图标 ＋ 一行一项**（照参照稿）——
   电话／邮箱／地址／官网，图标统一 15px、与首行文字对齐（`margin-top` 补的不是居中而是基线）。
   **`.footer-meta` 从此没有页面在用**（页脚那一段已换成这组），按站内惯例规则留在原处备回退。 */
/* V2.58：「联系我们」四行各补一个小标题（电话／邮箱／地址／官网）——用户「这个电话号码的
   logo，人家不知道什么意思」。行内改成**三列 grid：图标 15px ｜ 小标题 ｜ 值**，
   三列对齐之后四行的值起点在同一条竖线上（flex 做不到这点，因为小标题宽度不定）。
   小标题自身是暗色，值才是亮色。地址与官网两行现在都是链接（地址去高德搜，官网回首页），
   hover 走站内橙。列宽也从 232 提到 **248**，好让值那一列有 188px，28 字的地址正好折两行。 */
.footer-contact { gap: 12px; }
.footer-contact li { display: grid; grid-template-columns: 15px auto 1fr; column-gap: 9px; align-items: start; }
.footer-contact svg { width: 15px; height: 15px; margin-top: 3.5px; color: var(--text-on-dark-2); }
.footer-contact .fc-k { font-size: 13px; line-height: 1.75; color: var(--text-on-dark-2); }
.footer-contact a { font-size: 13.5px; line-height: 1.75; color: var(--text-on-dark); }
.footer-contact a:hover { color: var(--orange); }

/* 页脚「关注墨聚芯能」＝一行双栏等宽卡片（V2.67，2026-10-14，用户指定）。
   上一版是「两张码直接并排、右卡一个虚线占位框」，三处问题：虚线框与「（待替换）」
   会随源码上线、两张码在深色底上没有承载面、整块读不出是一个模块。这一版把两栏
   收进**统一圆角白卡**：间距 16、圆角走 `--radius-card`、阴影压到极淡（深色底上靠
   「一点贴地影 ＋ 一圈外扩影」立住，不做大范围模糊）；虚线框与「（待替换）」全删。
   等宽由 `repeat(2, minmax(0, 1fr))` 保证；码尺寸不写死，交给 `aspect-ratio` 随卡片
   自适应——1150 的三列档、900 的两列档能一路缩到 123px 而不溢出。列宽上限 360px：
   1240 栅格下两卡各 172px、码 140px（比上一版的 120px 略大）。 */
.qr-row {
  /* 用户 2026-10-15：「这的也是。留白太多了。扎眼。二维码放大」——
     卡片内距 16 → **10px**、卡间距 16 → **12px**、整排上限 360 → **384px**，
     二维码从 140 放大到 **166px**（卡片 172 → 186）。 */
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px; max-width: 384px;
}
/* 两卡等宽的前提是**两个 item 都能收缩**，所以这里显式写 `min-width: 0` */
.qr-item { margin: 0; min-width: 0; }
.qr-card {
  display: block; padding: 10px;
  background: var(--white); border-radius: var(--radius-card);
  box-shadow: 0 1px 2px rgba(11, 17, 23, .22),
              0 14px 30px -22px rgba(0, 0, 0, .75);
  transition: transform .22s var(--ease), box-shadow .22s var(--ease);
}
/* hover 只做「柔和提亮」——上浮 2px ＋ 阴影加深一档；不加光晕、不换底色、不做缩放 */
.qr-item:hover .qr-card {
  transform: translateY(-2px);
  box-shadow: 0 2px 4px rgba(11, 17, 23, .26),
              0 20px 38px -22px rgba(0, 0, 0, .8);
}
/* 码的容器。**尺寸完全由布局决定**（宽度撑满卡片内宽、方形由 `aspect-ratio` 维持），
   `object-fit: contain` 兜住非正方形的源图，不让码被拉变形。 */
.qr-code { position: relative; aspect-ratio: 1 / 1; }
.qr-code > img {
  display: block; width: 100%; height: 100%;
  object-fit: contain; border-radius: 5px; background: var(--white);
}
/* 码中心那枚品牌标志。**尺寸按百分比**给（20.5%＝公众号码里那枚的实测占比：
   1280 的码里标志方块 262px），换码或改卡宽都不用重算。
   `pointer-events: none` 保证扫码时这一层不吃鼠标事件。 */
/* 码下面两行——名称（白、中等字重）＋ 一句用途（浅灰、字号小一档），都在深色底上。 */
.qr-item figcaption {
  margin-top: 12px; display: flex; flex-direction: column; gap: 4px;
  font-size: 13px; font-weight: 500; line-height: 1.5; color: var(--white);
}
.qr-item figcaption span { font-size: 11.5px; font-weight: 400; line-height: 1.6; color: var(--text-on-dark-2); }
/* 旧类保留备回退（V2.67 起全站无引用）：`.qr-ph`＝页脚虚线占位框（已被白卡取代）、
   `.qr-box`＝企微弹层早期版本用过的占位框。 */
.qr-ph, .qr-box {
  border: 1px dashed rgba(255, 255, 255, .3); background: rgba(255, 255, 255, .06);
  display: flex; align-items: center; justify-content: center; text-align: center;
  font-size: 12.5px; line-height: 1.6; color: var(--text-on-dark-2);
}
.qr-ph { width: 120px; height: 120px; border-radius: var(--radius-sm); }
.qr-box { width: 118px; height: 118px; border-radius: var(--radius-sm); }
.footer-bottom {
  /* **横向内边距不能是 0**（V2.55 修）：这一条原写 `padding: 24px 0 30px`，左右归零，
     而它同时是 `.wrap`（左右 24px）——归零之后底栏两行字**顶到 wrap 的边框盒边**，
     比上面几列的内容缘往外多出 24px；窄档下右边那串链接正好压在视口边上（实测 900 档
     第二个 span 收在 705→900，最后一个字贴着屏幕边）。改成 `var(--gut)` 后与页脚各列对齐，
     分隔线仍然是整幅 1240（它的边框盒没变）。 */
  border-top: 1px solid var(--line-dark); padding: 24px var(--gut) 30px;
  display: flex; flex-wrap: wrap; gap: 12px; justify-content: space-between;
  font-size: 12.5px; color: var(--text-on-dark-2);
}.footer-bottom a:hover { color: var(--orange); }
/* 加了「版权所有」与公安备案之后，左侧法务行变长；默认 flex 基线把它压到 ~467px，
   于是「沪公网安备…」被挤到第三行、右边却空着 578px。放开让它吃掉剩余宽度，
   1440 档下三组信息回到一行，窄屏再自然折行。 */
.footer-bottom > span:first-child { flex: 1 1 auto; min-width: 0; }
/* 公安联网备案徽标：**图标在前、编号在右**（2026-10-13 号码到位时核对过格式，
   平台样板是「（徽标）京公网安备11010102000001号」，编号与「号」之间不留空格）。
   **必须写 `display: inline-block`**——站内全局有 `img { display: block }`（本文件第 129 行），
   不覆盖的话徽标会自成一行、把备案号挤到下一行去。
   `height` 定死、`width:auto` 走原图比例（现图标 36×40，与换掉的那张 168×187 同比例），
   不拉伸变形；HTML 上另写了 width/height 属性只为免抖动，实际尺寸以这两行为准。 */
.beian-ico { display: inline-block; height: 16px; width: auto; vertical-align: -3.5px; margin-right: 3px; }
/* 徽标与编号是一个整体，不许在中间折行（否则徽标会单独落一行） */
.footer-bottom a.beian { white-space: nowrap; }

.dock-bar { display: none; }

/* ---------- 右侧联系入口（V1.39 建；V2.43 改透明图标；**V2.45 改成毛玻璃竖胶囊**）----------
   为什么再改：V2.43 那版是**无底色、无描边**的透明图标（`--ink-2` 19px）。用户 2026-10-13：
   「右侧的这几个图标不行，显示不清楚，无论是白色还是有图的时候都显示不清楚…给我设计得
   高级一点…不管有图背景还是纯白背景都能显示出来」。
   根因不是图标本身，是**没有承载面**：纯白页上它没有边界、中调照片上灰线糊在背景里。
   所以这一版给它一块承载面，并把「高级」落在三件具体的事上：
     ① 四个按钮收进**一条 999px 圆角竖胶囊**——读成「一组控件」，不是四块方块拼的工具条；
     ② 玻璃＝暖白 78% ＋ `backdrop-filter` 模糊 18px／饱和 1.6，另加**内顶高光**
        （`inset 0 1px 0` 白 70%）与两段投影——玻璃的「贵」就在这层高光与贴地＋外扩的双投影上；
     ③ 图标从 19px 中灰改成 **20px 墨黑 `--ink`**，hover／聚焦时该格填**能量橙 `--accent-fill`
        配墨黑图标**（与站内「实底用原橙配墨字」的令牌口径一致），状态在任何底上都一眼可辨。
   承载面是浅色玻璃，所以**白页上靠描边与投影立得住、照片上靠那层白纱压得住**：
   实测图标与承载面 13:1，承载面压在中调照片上仍有 10:1 以上，深色照片只会更清楚。
   位置：`top: calc(50% - 74px)`＝按**三格高度**（6 ＋ 44×1.5 ＋ 2）居中——这样「回到顶部」
   从 0 高度长出来时只向下延伸，上面三格一个像素都不动（见文末 `.rail-top`）。
   **V2.54（2026-10-13）**：用户仍不满意——「还是不够清晰，图标也不高级还看不清看不全，
   整体没有突出感，要再高级大气点，符合 B 端官网调性」。定位到三处，逐一改：
     · **图标**：`ICO_QR` 重画成扫码框（见 `sitecore.py`），原来的二维码点阵在 20px 下糊成灰渣；
       渲染尺寸 20 → **21px**、线宽经 css 提到 **1.8**（四个图标线重终于一致）；
     · **承载面**：白纱 78% → **90%**，描边 .08 → **.10**，投影加大到 `0 24px 48px -22px`——
       白页上「有边、有影、有厚度」，不再是贴在纸上的一个浅印；
     · **体量**：单格 42 → **44px**（胶囊随之变长，`top` 同步改成 −74px）。 */
.contact-rail {
  /* **格子收紧（V2.67p）**：用户「我希望这三个浮窗的时候精致点，不要有不必要的留白出现。显得不专业」——
     44px 的格子里只放 21px 的图标（四周各留 11.5px），竖着三格就显得空。
     改成 **格 44 → 38px、内距 6 → 5px**：图标周围留白 11.5 → 8.5px，胶囊总高 148 → 128px。
     这仍是桌面专属（≤1080 整条隐藏、手机走吸底条），鼠标环境 38px 的点击区足够。
     **★ `top` 必须同步改**：胶囊是按"三格高度"垂直居中的（`50% - 74px` = 148/2），
     格高变了不改这里，整条就会偏上。新值 = (3×38 + 2×2 + 2×5)/2 = **64px**。 */
  --rail-pad: 5px; --rail-cell: 38px; --rail-gap: 2px;
  position: fixed; right: 20px; top: calc(50% - 64px);
  z-index: 80;
  display: flex; flex-direction: column; align-items: center;
  gap: var(--rail-gap); padding: var(--rail-pad);
  background: rgba(255, 255, 255, .9);
  border: 1px solid rgba(23, 26, 29, .10);
  border-radius: 999px;
  box-shadow: 0 1px 2px rgba(23, 26, 29, .06),
              0 24px 48px -22px rgba(23, 26, 29, .48),
              inset 0 1px 0 rgba(255, 255, 255, .9);
  -webkit-backdrop-filter: blur(18px) saturate(1.6);
  backdrop-filter: blur(18px) saturate(1.6);
  transition: opacity .24s var(--ease), visibility .24s var(--ease);
}
/* 不支持 backdrop-filter 的老浏览器（老 Firefox 等）把白纱提到 96%，观感差别很小 */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .contact-rail { background: rgba(255, 255, 255, .96); }
}
/* 窄屏正文列会收到 1240px 以内，而浮条始终贴在视口右侧，两者必然相交。
   让浮条在真正压到内容时整体淡出（见 js/main.js 第 7 段，名单里含 `.svc-card` 与 `.chat`——
    这两个类由 `css/service.css` 定义，2026-10-15 起不再在本文件里）。
   **不能再写 transform**：这一版定位已经不用 `translateY(-50%)`，覆盖它同样会跳位。 */
.contact-rail.is-hidden { opacity: 0; visibility: hidden; }
/* V2.45：胶囊里的一格。图标 20px、墨黑；hover／聚焦时这一格填能量橙、图标转墨黑——
   与站内「原橙实底配墨黑字」（`--accent-fill` 的口径）一致，在玻璃、纯白、照片上都认得出。 */
.rail-btn {
  position: relative;
  width: var(--rail-cell); height: var(--rail-cell); padding: 0;
  display: flex; align-items: center; justify-content: center;
  background: none; border: 0; border-radius: 999px;
  color: var(--ink); font-family: inherit;
  cursor: pointer;
  transition: color .18s var(--ease), background .18s var(--ease);
}
/* V2.54：图标 20 → 21px，线宽经 css 提到 1.8（SVG 表现属性可被 CSS 覆盖，写在 `svg` 上会
   向下继承给各条 path）。**V2.56：1.8 → 2**——用户连着两轮说浮条图标「不直观、都是残缺的」，
   除了把 `ICO_CHAT`／`ICO_QR` 重画成闭合轮廓（见 `sitecore.py`），这一档线重也再压厚一点，
   21px 下一格图标才立得住。 */
.rail-btn svg { width: 21px; height: 21px; flex: none; stroke-width: 2; }
.rail-btn:hover,
.rail-btn:focus-visible { color: var(--ink); background: var(--accent-fill); }
.rail-btn:focus-visible { outline: 2px solid var(--ink); outline-offset: 1px; }
/* 文字提示：默认不显示，鼠标移上去或键盘聚焦时在**按钮左侧**浮出。
   偏移从 8px 提到 14px：V2.45 起按钮外面还包着 6px 的胶囊内边距，留出这一步才不贴住胶囊边。 */
.rail-tip {
  position: absolute; right: calc(100% + 14px); top: 50%;
  transform: translateY(-50%) translateX(4px);
  white-space: nowrap; padding: 5px 10px; border-radius: 6px;
  background: var(--ink); color: var(--warm);
  font-size: 12.5px; font-weight: 500; line-height: 1.4;
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity .18s var(--ease), visibility .18s var(--ease), transform .18s var(--ease);
}
.rail-btn:hover .rail-tip,
.rail-btn:focus-visible .rail-tip { opacity: 1; visibility: visible; transform: translateY(-50%) translateX(0); }
/* 企业微信的二维码收在浮层里，鼠标移上去（或键盘聚焦）才展开。
   浮层向左开——按钮右侧已经没有空间。
   **V2.67（2026-10-14）**：上一版 168px（码实际只有 144px），用户嫌小；这一版
   放到 **216px**，码随之到 192px（＋33%），卡片内边距与文案行距都不动。 */
.rail-pop {
  /* 与浮动条的间距 16 → 12px（V2.67h）：右侧箭头要能"接上"按钮，
     原来留 16px（实测缝 9px）时箭头只指到缝里、指了个空。 */
  position: absolute; right: calc(100% + 12px); top: 50%;
  /* 三颗浮层统一尺寸。宽度 **300 → 248px、内距 18/20/16 → 四边 16px**（V2.67o）：
     用户「哪俩悬浮窗，左右的空白太多了去掉点。用不着太大」——
     300 宽时二维码到浮层边缘是 **46px**（内距 20 ＋ 内容区居中让出的 26），太松；
     248 之后内容宽 216、二维码 208 居中，**到边缘 20px**，收掉 26px。
     校验过文字不挤：企微那句最长 200px、客服页脚 187px，都小于 216。 */
  width: 248px; padding: 16px;
  transform: translateY(-50%) translateX(6px);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius-card);
  box-shadow: 0 18px 36px -22px rgba(23, 26, 29, .5);
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity .2s var(--ease), visibility .2s var(--ease), transform .2s var(--ease);
}
.rail-wx:hover .rail-pop {
  opacity: 1; visibility: visible; pointer-events: auto;
  transform: translateY(-50%) translateX(0);
}
/* 键盘聚焦也展开，但**必须用 `:focus-visible` 而不是 `:focus-within`**（V2.67k，2026-10-15 修 bug）：
   鼠标点一下这颗，`tabindex="0"` 的 div 就拿到焦点、`:focus-within` 随即成立，于是**鼠标移开后
   浮层挂着不关**（三颗实测全中）。`:focus-visible` 只在键盘导航时匹配，鼠标点击不匹配——
   与上面 `.rail-tip` 那套（`.rail-btn:focus-visible .rail-tip`）本来就是同一个口径。
   拆成独立一条、不并进上面那组：不支持 `:focus-visible` 的浏览器会**整条丢弃**，
   并在一起会连 hover 一起丢；拆开后最坏只是失去"键盘展开"。 */
.rail-wx:focus-visible .rail-pop {
  opacity: 1; visibility: visible; pointer-events: auto;
  transform: translateY(-50%) translateX(0);
}
/* 码位：`position: relative` 保留（中心 `.qr-logo` 品牌标叠层已于 2026-10-15 移除，二维码自带企微标）。
   `overflow: hidden` 把缩放后的源图裁进圆角。 */
.rail-pop-qr {
  position: relative; aspect-ratio: 1 / 1; border-radius: 8px;
  background: #fff; overflow: hidden;
  /* **必须写 `margin: 0 auto`**：这是块元素，一旦给了固定宽度就默认左对齐——
     用户 2026-10-15 圈出「二维码是歪的没居中」就是这个。企业微信那颗当时没暴露，
     是因为它没设宽度、撑满内容区，看不出问题。 */
  width: 208px; height: 208px; margin-left: auto; margin-right: auto;
}
.rail-pop-qr > img { display: block; width: 100%; height: 100%; object-fit: contain; }
.rail-pop p { margin-top: 14px; font-size: 12.5px; color: var(--ink-3); text-align: center; }
/* 「回到顶部」并入同一组按钮（`.rail-btn`），**V2.25 起改为滚动之后才出现**
   （用户 2026-10-11 01:23：「返回顶部的这个按钮，不是一直都出现的。只有页面滚动后才会出现」）。
   这一条历史上按 scrollY 显隐过，后来因为「整组垂直居中、逐个显隐会把整组顶得上下一跳」
   改成了全时段可见。这次把这个副作用彻底消掉再改回来：
     · **用 `height` 从 0 长到 42px**（不是 `display:none`）——高度可以过渡，胶囊是平滑伸长；
     · 胶囊定位按**三格高度**居中（`top: calc(50% - 71px)`，见上文），所以伸出来的这一格
       只向**下**长，上面三格一个像素都不动，不会「顶上去」。
   阈值 300px，状态由 `js/main.js` 第 7 段随滚动切换（复用那里已有的 rAF 节流）。 */
.rail-top {
  height: 0;
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: height .26s var(--ease),
              opacity .26s var(--ease), visibility .26s var(--ease),
              background .2s var(--ease), color .2s var(--ease);
}
.contact-rail.is-scrolled .rail-top { height: var(--rail-cell); opacity: 1; visibility: visible; pointer-events: auto; }
/* 手机吸底条里那个「顶部」用同一条规则（`js/main.js` 一并切 `is-scrolled`）。
   吸底条是 `grid auto auto auto 1fr`，**同样不能用 `display:none`**——
   那一格一塌，右边那枚通栏的电话按钮会立刻变宽，整条跟着跳。
   opacity 淡出保留占位，四格宽度自始至终不变。 */
.dock-top {
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity .26s var(--ease), visibility .26s var(--ease);
}
.dock-bar.is-scrolled .dock-top { opacity: 1; visibility: visible; pointer-events: auto; }
/* 手机端吸底条里的入口：图标 + 文字，字号压到 12.5px，
   与主行动（页头那个橙色电话按钮）拉开主次。 */
.dock-btn {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  min-width: 52px; padding: 7px 4px; border-radius: var(--radius-sm);
  font-size: 12.5px; font-weight: 500; color: var(--ink);
}
.dock-btn svg { width: 18px; height: 18px; }
.dock-btn:hover { background: rgba(23, 26, 29, .05); }

.modal { position: fixed; inset: 0; z-index: 120; display: none; }
.modal.is-open { display: block; }
/* 锁滚动锁在根元素上：body 一旦变成滚动容器，目录页吸顶条会失去参照 */
html.is-locked { overflow: hidden; }
.modal-mask { position: absolute; inset: 0; background: var(--mask); }
.modal-box {
  position: relative; width: min(92vw, 400px); margin: 12vh auto 0;
  background: var(--surface); border-radius: var(--radius-lg); padding: 34px 34px 30px;
  text-align: center; box-shadow: var(--shadow-lift);
}
.modal-box h2 { font-size: 22px; }
.modal-line { margin-top: 10px; color: var(--ink-2); font-size: 14.5px; }
.modal-tip { margin-top: 6px; color: var(--ink-3); font-size: 13.5px; }

/* 弹层里的通道切换：电话 / 企业微信 /（后续）在线客服。
   用一个弹层而不是每项各做一个，是因为三条通道的出口是同一个「联系商务」，
   拆成三个弹层只会让二维码这类唯一素材散到三处。
   没有下划线、没有滑块，只靠实底与字重区分当前项。 */
.chn-tabs {
  display: flex; gap: 6px; margin-top: 22px; padding: 4px;
  background: var(--bg); border-radius: var(--radius-md);
}
.chn-tab {
  flex: 1 1 0; padding: 9px 6px; border-radius: 9px;
  font-size: 14.5px; font-weight: 500; color: var(--ink-2);
  transition: background .2s var(--ease), color .2s var(--ease);
}
.chn-tab[aria-selected="true"] { background: var(--ink); color: var(--warm); font-weight: 600; }
.chn-panel[hidden] { display: none; }
/* 两个通道的内容高度差得不多（电话两块、二维码三块），但一高一低会让弹层
   在切换时跳一下。给面板一个统一的最小高度并让内容垂直居中，切换时外框不动。 */
.chn-panel {
  min-height: 248px; padding-top: 20px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
}
.ph-qr {
  margin: 0 auto; width: 176px; height: 176px; border-radius: var(--radius-md);
  border: 1px dashed var(--line-strong); background: var(--bg);
  display: flex; align-items: center; justify-content: center;
  font-size: 13.5px; color: var(--ink-3); text-align: center; line-height: 1.7;
}
/* 电话：号码用等宽数字排成一行大字，下面一个低调的复制按钮。
   桌面浏览器点 tel: 一般没有反应，所以「复制号码」不是装饰，是桌面上唯一能接上的动作。 */
.chn-phone {
  display: block; margin-top: 4px;
  font-size: 27px; font-weight: 600; letter-spacing: .01em;
  color: var(--ink); font-variant-numeric: tabular-nums;
}
.chn-phone:hover { color: var(--accent); }
.chn-note { margin-top: 12px; color: var(--ink-3); font-size: 13.5px; }
/* 「扫一扫」不许在中间折行——居中排下 13.5px 会把三个字拆到两行，读起来断句（V2.46） */
.chn-note .nb { white-space: nowrap; }
/* V2.46：企业微信弹层里的二维码图槽，尺寸与原来的虚线占位框一致（176×176），
   **换图直接覆盖 `images/brand/qr-wecom.png`，联系页／客服页／这里三处一起生效**。 */
.chn-qr {
  display: block; width: 176px; height: 176px; margin: 0 auto;
  border: 1px solid var(--line); border-radius: var(--radius-md);
  background: var(--surface); object-fit: contain;
}
.chn-copy {
  margin-top: 18px; padding: 9px 18px; border-radius: var(--radius-sm);
  border: 1px solid var(--line-strong); font-size: 13.5px; font-weight: 500; color: var(--ink);
  transition: border-color .2s var(--ease), background .2s var(--ease);
}
.chn-copy:hover { border-color: var(--ink); background: rgba(23, 26, 29, .04); }
.modal-close {
  position: absolute; top: 14px; right: 14px; width: 34px; height: 34px;
  display: grid; place-items: center; border-radius: var(--radius-sm); color: var(--ink-3);
}
.modal-close:hover { background: var(--bg); color: var(--ink); }
.modal-close svg { width: 18px; height: 18px; }

/* ---------- 12. 响应式 ---------- */
/* 首屏在 1200px 以下改上下结构（照片在上、文案落在下方暖白区）。
   这张图是 16:9，与绝大多数桌面视口同比例，叠加版式只裁 4%–5%、人物全在，
   所以不必再按视口宽高比额外设限（上一版图是 2.12 的宽幅，才必须那样处理）。 */
@media (max-width: 1200px) {
  /* 首屏改上下结构：照片在上、文案落在下方暖白区，文案不压照片。
     页头在这一档是墨黑实体层，照片从页头下沿起铺，所以顶部不需要压暗。 */
  .hero {
    display: block; min-height: 0; height: auto;
    margin-top: var(--header-h); background: var(--bg);
  }
  .hero::before { display: none; }
  /* 照片按图片本来的比例出：完整显示、不做任何裁切，也不再用 svh 硬切高度 */
  .hero-media { position: relative; inset: auto; height: auto; aspect-ratio: var(--hero-ar); overflow: hidden; }
  .hero-img { object-position: center; }
  .hero .wrap { max-width: var(--wrap); margin: 0 auto; padding: 26px var(--gut) 88px; }
  .hero-actions { margin-top: 22px; }
  /* 文案落在照片下方，块的垂直位置由上一层的页边距决定，不需要那条为桌面写的
     20svh 补偿（在 block 布局里它会变成纯多出来的 160–180px 空白，把页面推长）。
     整条 padding 在这里复位，只留改前就有的一档下方留白。 */
  .hero-copy { margin-left: 0; width: 100%; min-width: 0; max-width: none; padding: 0 0 4svh; }
  .hero h1, .hero .hero-title { font-size: clamp(28px, 5vw, 44px); }
  .hero-sub { font-size: 16px; }
  /* 文案已落在暖白区、占满整宽，两句并回一行自然折行（桌面各占一行） */
  .hero-sub span { display: inline; }
}

@media (max-width: 760px) {
  .hero h1, .hero .hero-title { font-size: clamp(28px, 7.6vw, 36px); }
}

/* V2.58：把页脚的三列档**提前到 1150px**。「联系我们」加宽到 248px 之后，六个 `auto`
   在 1081–1150 这一档也排不下——实测 1085 下整行差 31px，浏览器的做法是压 `auto` 轨，
   结果「石墨烯发热用品」被折成两行（1201 档还有 103px 宽，不折）。
   这一条写在 ≤1080 那个块**之前**，所以 ≤1080 仍由那一块的同名规则接管（值相同），
   ≤900 的 `1fr 1fr` 与 ≤760 的单列写在更后面，照旧压住它。 */
@media (max-width: 1150px) {
  .footer-grid { grid-template-columns: repeat(3, 1fr); gap: 30px 22px; }
  /* 页脚「关注墨聚芯能」在 ≤1150 一律改成**上下堆叠**（用户指定）。
     上面三条栅格在这一档把扫码列压到最窄 269px（900 档以下更宽，但 901–1150 是最窄的
     一段），两卡并排时每卡只剩 95–126px、码缩到 78–111px，扫不动；
     堆叠后列宽上限 240px → **码恒为 208px**，1080／1150／760／375／320 五档一致。
     ≤900 的两列与 ≤760 的单列都写在更后面，但这三条 `.qr-row` 值相同、无冲突。 */
  .qr-row { grid-template-columns: 1fr; gap: 14px; max-width: 240px; }
}

@media (max-width: 1080px) {
  /* 树形目录在 ≤1080 由「左栏竖列」改成「上排芯片」。**不能再做成一条横滚条**：
     五个分类在 375 下只露得出三个（列表内容 561px、可视 350px），第四个之后被裁在
     视口外，用户既看不到、也想不到要横着划（2026-10-06 用户报「看不全」）。
     改成换行芯片——全部分类一屏铺完，不产生第二个横向滚动条。
     两栏并排在这一档会把卡片挤到读不下去，所以仍然「树在上、内容在下」。 */
  .cat-layout { grid-template-columns: 1fr; gap: 0; }
  .cat-tree {
    /* `min-width: 0` 必须有：grid 项的默认 min-width 是 auto。 */
    min-width: 0;
    top: var(--header-h); margin-bottom: 14px;
    padding: 9px 0 11px;
    /* V2.23：底色跟着「中间区全白」走（原先是暖白 `rgba(243,241,234,.95)`）。 */
    background: rgba(255, 255, 255, .95);
    backdrop-filter: saturate(1.4) blur(12px);
    -webkit-backdrop-filter: saturate(1.4) blur(12px);
    border-bottom: 1px solid var(--line);
  }
  /* V2.23：这一档标题区整块收起，新加的英文小标也一并收起。 */
  .cat-tree-t, .cat-tree-en { display: none; }
  .cat-tree ul { flex-direction: row; flex-wrap: wrap; gap: 6px; }
  .cat-tree a {
    padding: 6px 13px; border-radius: 999px; gap: 6px; line-height: 1.35;
    border-left: 0;
    background: rgba(23, 26, 29, .05);
  }
  .cat-tree a::before { display: none; }
  .cat-tree-nm { font-size: 14.5px; font-weight: 500; }
  .cat-tree-no { font-size: 12.5px; }
  .cat-tree a.is-active { background: var(--ink); color: var(--white); font-weight: 600; }
  .cat-tree a.is-active .cat-tree-no { color: var(--accent-fill); }
  /* 这一档树是横条、吸在页头下沿：原生锚点跳转只让开页头，会让分类标题被压在
     这条横条下面。js/main.js 第 9 段会自己按实际高度算落点，这里给无脚本时兜底。 */
  html:has(.cat-tree) { scroll-padding-top: calc(var(--header-h) + 96px); }

  /* 常见问题的条目列窄了以后，问题列与序号列一起收一档，答案列才有得看。 */
  .qa-list { --qa-no: 44px; --qa-q: 300px; --qa-gap: 18px; }
  /* 联系我们两栏并排在平板下会把信息卡与二维码卡都压窄，改成上下（二维码在上：
     它是这一页的落点，先看到它比先看到地址更符合「怎么联系」这个问题）。 */
  .ct-layout { grid-template-columns: 1fr; gap: 32px; }
  .ct-card { order: -1; }
  .ct-ways { margin-top: 26px; }
  .ct-reg { margin-top: 20px; }

  .section { padding: 28px 0; }
  .scene-grid { grid-template-columns: repeat(3, 1fr); }
  /* V2.55：六组之后这一档（1080–901）横排不下——「产品体系」那列要 102px、
     联系我们那列要 248px，六个 `auto` 加起来比这一档的正文宽（853–1032px）还大，
     硬排会把「石墨烯发热用品」折成两行。改成 **3 列 × 2 行**，每列 ~270px，
     与 900 以下的 2 列、760 以下的 1 列接得上。
     **V2.58 起这一档已由上面那条 `max-width: 1150px` 提前接管**，这里保留同名规则
     （值相同），免得改动那条时漏掉这一档。 */
  .footer-grid { grid-template-columns: repeat(3, 1fr); gap: 30px 22px; }

  /* 抽屉式菜单从 1080px 起接管。原先设在 760px，760–1080 这一档硬塞完整导航：
     九项（含「进入商城」）实测需要约 730px，加上 Logo 132px、右侧 CTA 88px
     与两侧 24px 内边距共需约 1000px，1080 以下就开始互相压字
     （实测 1100px 时「联系我们」与「进入商城」已经叠在一起）。
     与其在 900–1080 之间把字号和留白一路压扁，不如在这个宽度就收到抽屉里，
     完整导航只在它真能站得住的时候出现。 */
  .site-header {
    z-index: 100;
    background: var(--bg-deep);
    border-bottom-color: var(--line-dark);
  }
  .brand-logo { width: 120px; height: 41px; }

  .nav-burger {
    display: flex; flex-direction: column; justify-content: center; gap: 5px;
    width: 42px; height: 42px; border-radius: var(--radius-sm);
    order: 3;
    /* 不许被压：flex-shrink 默认为 1，宽度不够时它会静默缩水（实测 360px 上被压到
       21px，三条线还在、横向溢出也查不出来，只有量宽度才发现）。页头这三种元素
       都设 `flex: none`，宽度不够时由 CTA 自己收（见 420px 那一档）。 */
    flex: none;
  }
  .nav-burger span { display: block; width: 20px; height: 1.8px; background: var(--warm); border-radius: 2px; transition: .25s var(--ease); margin: 0 auto; }
  .nav-toggle:checked ~ .nav-burger span:nth-child(1) { transform: translateY(6.8px) rotate(45deg); }
  .nav-toggle:checked ~ .nav-burger span:nth-child(2) { opacity: 0; }
  .nav-toggle:checked ~ .nav-burger span:nth-child(3) { transform: translateY(-6.8px) rotate(-45deg); }
  .brand { order: 1; }
  /* 页头右端已经没有 CTA，右推改挂在汉堡上（原来靠 `.header-cta` 的 `margin-left: auto`）。 */
  .nav-burger { order: 3; margin-left: auto; }

  .site-nav {
    position: fixed; inset: 0 0 0 auto; width: min(86vw, 360px);
    margin-left: 0;
    background: var(--surface); z-index: 95;
    padding: 76px 24px 32px; overflow-y: auto;
    transform: translateX(100%); transition: transform .3s var(--ease);
    box-shadow: -20px 0 60px -30px rgba(23, 26, 29, .5);
  }
  .nav-toggle:checked ~ .site-nav { transform: translateX(0); }
  .nav-list { flex-direction: column; align-items: stretch; gap: 2px; }
  /* 抽屉是白面，这里的导航项回到墨黑——页头本身仍是墨黑底 + 暖白字，两者互不影响。
     「产品中心」在抽屉里同时是链接（点标题进目录页）与可展开项（三行子项直接列在下方），
     箭头因此转到朝下。 */
  .nav-list > li > a {
    display: flex; width: 100%; justify-content: space-between;
    padding: 14px 12px; font-size: 16px; border-radius: var(--radius-sm);
    color: var(--ink); letter-spacing: .01em;
  }
  .nav-list > li > a:hover { color: var(--accent); }
  .nav-list > li > a[aria-current="page"] { color: var(--ink); }
  .nav-list > li > a[aria-current="page"]::after { display: none; }
  .nav-caret { transform: rotate(45deg) translate(-1px, -1px); opacity: .45; }
  /* 抽屉是 .site-header 的子元素，它的 z-index 95 会盖住同级的品牌、汉堡与 CTA——
     抽屉一打开，右上角那个已经变成叉的汉堡就被压在下面，点不到也关不掉。
     把这三个同级元素提到抽屉之上（父级 .site-header 已经建立层叠上下文，
     这里比的是兄弟之间的顺序）。 */
  .brand, .nav-burger { position: relative; z-index: 96; }
  /* 汉堡此时压在白色抽屉上，暖白条会整个看不见 → 展开态改墨黑 */
  .nav-toggle:checked ~ .nav-burger span { background: var(--ink); }
  /* 抽屉是白面，子菜单跟着回到浅色：深色卡片压在白色抽屉上会读成另一个控件 */
  .sub-menu {
    position: static; transform: none; opacity: 1; visibility: visible;
    background: transparent; border: 0; box-shadow: none;
    min-width: 0; padding: 0 0 8px 12px;
  }
  /* 桌面版那两个伪元素（指向三角、鼠标过桥）在抽屉里没有意义 */
  .sub-menu::before, .sub-menu::after { display: none; }
  .sub-menu a { padding: 10px 12px; font-size: 14.5px; font-weight: 500; color: var(--ink-2); }
  .sub-menu a:hover { background: rgba(23, 26, 29, .05); color: var(--ink); }
}

@media (max-width: 900px) {
  .grid-4, .grid-5 { grid-template-columns: repeat(2, 1fr); }
  .split, .split--wide-left, .split--wide-right, .split--core { grid-template-columns: 1fr; gap: 36px; }
  /* 单列时竖幅图不再铺满宽度：852px 宽的 1:1 图会独占一屏，
     收到 520px 居中，与正文同一视觉尺度。 */
  .core-visual { max-width: 520px; margin-inline: auto; }
  .pd-info-grid { grid-template-columns: 1fr; gap: 34px; }
  .steps { grid-template-columns: 1fr 1fr; }
  /* V2.23：卡壳已去掉，窄档不再补内边距。 */
  .cta-card { padding: 0; }
  .footer-grid { grid-template-columns: 1fr 1fr; gap: 36px; }
}

@media (max-width: 760px) {
  :root {
    --gut: 20px;
    --header-h: 64px;
  }
  /* 面包屑五级在窄屏排不到一行，横排会把「返回产品列表」挤到边上或换行后错位。
     这一档改成上下两行：先「我在哪」，再「怎么回去」。字号各收半档。 */
  .pd-crumb-bar .wrap { flex-direction: column; align-items: flex-start; gap: 10px; padding-top: 12px; padding-bottom: 12px; }
  .pd-crumb-bar .crumb { font-size: 12.5px; gap: 6px; }
  .pd-back { font-size: 13.5px; padding: 6px 13px 6px 10px; }

  .section { padding: 21px 0; }
  .section--tight { padding: 16px 0; }
  .section-head { margin-bottom: 12px; }
  .grid { gap: 20px; }
  .grid-2, .grid-3 { grid-template-columns: 1fr; }
  /* 常见问题的条目在窄屏把三列收成两列：序号自己一列、问题与答案在右列上下排。
     答案必须跟着问题左缘对齐，否则读起来像两条不相干的内容。 */
  .qa { grid-template-columns: 32px minmax(0, 1fr); gap: 0 12px; padding: 16px 0; }
  .qa-no { padding-top: 4px; letter-spacing: .06em; }
  .qa-q { grid-column: 2; font-size: 16px; }
  .qa-a { grid-column: 2; margin-top: 8px; font-size: 14.5px; }
  .qa-photo { margin: 4px 0 4px 44px; }
  .ct-card { padding: 28px 22px 26px; }
  .ct-ways li { grid-template-columns: 64px minmax(0, 1fr); gap: 12px; }
  .ct-reg > div { grid-template-columns: 64px minmax(0, 1fr); gap: 12px; }
  .ct-way-v { font-size: 19px; }

  /* 窄屏首屏改成上下结构（照片在页头之下），页头背后没有照片可叠，透明会让暖白字
     落在暖白页面上、整条导航看不见 → 保持墨黑底（与内页、滚动态同一套底色）。
     z-index 提到抽屉之上，否则抽屉盖住页头，汉堡按钮点不到、菜单关不掉。 */
  .site-header {
    z-index: 100;
    background: var(--bg-deep);
    border-bottom-color: var(--line-dark);
  }
  /* 页头在这一档收窄：Logo 与汉堡都压小，把宽度让给正文。
     抽屉与汉堡的规则在 1080px 那一档，这里只改尺码。 */
  .header-inner { height: var(--header-h); }
  .brand-logo { width: 107px; height: 36px; }

  .page-hero { padding: 108px 0 54px; }
  .page-hero--img { padding: 116px 0 60px; }
  .page-hero-inner > * { max-width: none; }
  /* 窄屏文案占满宽，椭圆柔光改为整幅压底，保证任何图上都读得清 */
  .page-hero--img .page-hero-inner::before,
  .pd-top-inner::before { inset: -34px -20px -36px -20px; background: rgba(243, 241, 234, .82); }
  /* 三条线目录页的底色在窄屏不能是横向的：文案占满整宽，横向渐隐盖不住最右一列字。
     这一档换成纵向渐隐，同样是铺满整幅、四边没有第二种覆盖量。 */
  .page-hero--nomask::before,
  .pd-top--nomask::before {
    background: linear-gradient(180deg,
      rgba(243, 241, 234, .72) 0%, rgba(243, 241, 234, .62) 58%,
      rgba(243, 241, 234, .46) 100%);
    /* 这一档页头是墨黑实体层、不叠在图上，顶部不需要让位；
       保留纵向遮罩反而会削掉文案块上沿的覆盖。 */
    -webkit-mask-image: none; mask-image: none;
  }
  /* 深底页在窄屏同样是「整幅压底」，只是换成墨黑。 */
  .page-hero--dark.page-hero--nomask::before {
    background: linear-gradient(180deg,
      rgba(23, 26, 29, .82) 0%, rgba(23, 26, 29, .74) 58%,
      rgba(23, 26, 29, .60) 100%);
  }
  /* 详情页窄屏同样比线页厚一档（与桌面那套的理由相同）。 */
  .pd-top--nomask::before {
    background: linear-gradient(180deg,
      rgba(243, 241, 234, .86) 0%, rgba(243, 241, 234, .78) 58%,
      rgba(243, 241, 234, .64) 100%);
  }
  .page-hero--dark .page-hero-inner::before { background: rgba(23, 26, 29, .84); }
  .page-hero--dark .page-hero-bg::after {
    background: linear-gradient(180deg,
      rgba(23, 26, 29, .52) 0, rgba(23, 26, 29, .36) 64px,
      rgba(23, 26, 29, .16) 104px, rgba(23, 26, 29, .1) 100%);
  }
  .page-hero-bg::after {
    background: linear-gradient(180deg,
      rgba(243, 241, 234, .96) 0, rgba(243, 241, 234, .9) 64px,
      rgba(243, 241, 234, .5) 104px, rgba(243, 241, 234, .28) 100%);
  }
  .pd-top { padding: 122px 0 52px; }
  .pd-info, .pd-features, .pd-scenes, .cat-block { padding: 19px 0; }

  /* 与常驻页头同高，否则吸顶条会被页头压住 6px */
  .anchor-nav { top: var(--header-h); }
  .scene-grid { grid-template-columns: repeat(2, 1fr); gap: 14px; }
  .scene-body { padding: 14px 14px 16px; }
  .scene-body h4 { font-size: 15px; }
  .scene-body p { font-size: 12.5px; }
  .steps { grid-template-columns: 1fr; }
  .job { padding: 26px 22px 28px; }
  .job-body { grid-template-columns: 1fr; gap: 22px; }
  .stat-row { grid-template-columns: 1fr; gap: 22px; }
  .cat-head { flex-direction: column; align-items: flex-start; gap: 10px; }

  .contact-rail { display: none; }
  /* 窄屏的浮条替代品。原先整条铺能量橙，橙色面积远超「只占 3%–5%」的比例，
     改为暖白条 + 橙色只留在主行动上，与桌面浮条同一口径。
     四项：电话 / 企业微信 / 顶部三个图标 + 一个橙色的 400 电话主按钮
     （与页头右端那个按钮同一件事，点击直接拨号）。
     图标项只给 12.5px 小字，主按钮吃满剩余宽度，层级一眼分得开。 */
  .dock-bar {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 85;
    display: grid; grid-template-columns: auto auto auto 1fr; gap: 8px;
    padding: 10px 14px;
    background: rgba(243, 241, 234, .96);
    backdrop-filter: saturate(1.4) blur(12px);
    -webkit-backdrop-filter: saturate(1.4) blur(12px);
    border-top: 1px solid var(--line);
    box-shadow: 0 -8px 24px -18px rgba(23, 26, 29, .45);
  }
  .dock-bar .dock-cta {
    display: flex; align-items: center; justify-content: center; gap: 8px;
    padding: 13px 18px; font-size: 15px; font-weight: 600; border-radius: var(--radius-sm);
    background: var(--accent-fill); color: var(--ink);
    font-variant-numeric: tabular-nums;
  }
  /* 图标必须给尺寸：这枚 SVG 只有 viewBox、没有 width/height，
     作为 flex item 会被撑到默认大小（实测把整条吸底条顶到 125px 高）。 */
  .dock-bar .dock-cta svg { width: 18px; height: 18px; flex: none; }

  .site-footer { padding-top: 52px; }
  /* 吸底转化条高约 50px，底部版权行让位 */
  .footer-bottom { padding-bottom: 84px; }
  .footer-grid { grid-template-columns: 1fr; gap: 30px; padding-bottom: 36px; }
  .cta-band { padding: 19px 0 96px; }
  /* V2.23：同上，卡壳已去掉。 */
  .cta-card { padding: 0; }
  .cta-card .cta-actions .btn { width: 100%; }
}

/* 矮屏手机（如 375×667）：照片已按 2:1 完整出，整屏仍偏挤，
   把纵向间距再收一档，避免首屏最后一行被固定吸底条盖住。 */
@media (max-width: 760px) and (max-height: 730px) {
  .hero .wrap { padding-top: 20px; padding-bottom: 78px; }
  .hero h1, .hero .hero-title { font-size: clamp(26px, 7vw, 32px); }
  .hero-sub { font-size: 15.5px; }
}

@media (max-width: 420px) {
  .scene-grid { grid-template-columns: 1fr 1fr; }
  .tag { font-size: 12.5px; padding: 3px 9px; }
  /* 极窄屏：页头右端已无号码，只需给「Logo + 汉堡」让出余量。 */
  .header-inner { gap: 14px; }
  /* 吸底条的橙色主按钮也换成号码之后，这一档要一起收，否则号码会折成两行
     （实测 360px 下主按钮被顶到 79px 高、整条吸底条 100px）。三个图标格
     从 52px 收到 46px——仍是 44px 以上的触摸目标；主按钮内边距与字号各降一档。 */
  .dock-bar { gap: 6px; }
  .dock-btn { min-width: 46px; }
  .dock-bar .dock-cta { padding: 12px; font-size: 13.5px; gap: 6px; }
  .dock-bar .dock-cta svg { width: 16px; height: 16px; }
  /* 详情页位置条在极窄屏会折到三行（320 下整条 122px）。这一档再把字号与
     间距各收一档，让它回到两行——五级层级不能省，能省的只有行高与间隙。 */
  .pd-crumb-bar .wrap { gap: 8px; padding-top: 10px; padding-bottom: 10px; }
  .pd-crumb-bar .crumb { font-size: 12.5px; gap: 5px; line-height: 1.55; }
}

/* 320–359 这一档（iPhone SE 一代、把桌面窗口拖到最窄）：
   页头只剩 Logo + 汉堡两件，收一档 Logo 与内层间距即可。
   合计 = Logo 96 ＋ 汉堡 42 ＋ 间距 10 ＋ 左右内边距 40 = 188px，320 下余 132px。 */
@media (max-width: 359px) {
  .brand-logo { width: 96px; height: 32px; }
  .header-inner { gap: 10px; }
  /* 吸底条的主按钮在这一档还差几个 px，把列间距与内边距再收一档、字号降到 12px。
     三个图标格的 46px 不再往下压——44px 是触摸目标的下限。 */
  .dock-bar { gap: 5px; }
  .dock-bar .dock-cta { padding: 11px 10px; font-size: 12.5px; gap: 5px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
  html { scroll-behavior: auto; }
}

/* ---------- 核心材料页（V1.39 版式优化）----------
   文字一字未删，改的是承载方式：四张特性卡加图标、发热机理做成一条三步流、
   三重防护改成「级 + 名称 + 说明」的三段、两个对比表各自换成更合身的形态
   （辐射对照改成三列、工频磁场改成对数刻度的条状图）。
   图标一律走 `--accent` 单色线条，与站内其它图标同一口径，不做彩色图标。 */
.mat-card {
  padding: 24px 22px; background: var(--bg);
  border: 1px solid var(--line); border-radius: var(--radius-card);
}
.mat-ico { display: inline-flex; color: var(--accent); }
.mat-ico svg { width: 24px; height: 24px; }
.mat-card .mat-ico { margin-bottom: 18px; }
.mat-card h3 { font-size: 17px; font-weight: 600; color: var(--ink); }
.mat-card p { margin-top: 10px; font-size: 14.5px; line-height: 1.85; color: var(--ink-2); }

/* 发热机理：三步并排，用一条竖分隔线断句（不做箭头——这里讲的是先后关系，不是流程跳转） */
.mat-flow { display: grid; grid-template-columns: repeat(3, 1fr); }
.mat-step { padding-right: 22px; }
.mat-step + .mat-step { padding-left: 22px; border-left: 1px solid var(--line); }
.mat-step .mat-ico { margin-bottom: 14px; }
.mat-step-t { font-size: 15px; font-weight: 600; color: var(--ink); }
.mat-step-x { margin-top: 9px; font-size: 13.5px; line-height: 1.85; color: var(--ink-2); }

.mat-shield {
  padding: 26px 24px; background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--radius-card);
}
.mat-lv { margin-top: 16px; font-size: 12.5px; font-weight: 600; letter-spacing: .12em; color: var(--accent); }
.mat-shield h3 { margin-top: 7px; font-size: 17px; font-weight: 600; color: var(--ink); }
.mat-shield p:last-child { margin-top: 10px; font-size: 14.5px; line-height: 1.85; color: var(--ink-2); }

/* 辐射对照：拆成「项目 / 非电离 / 电离」三列。原来两边的结论挤在一格用「｜」隔开，
   而两列之间的差别正是这张表要讲的重点。 */
.cmp { border: 1px solid var(--line); border-radius: var(--radius-card); overflow: hidden; }
.cmp-row { display: grid; grid-template-columns: 1.05fr 1fr 1fr; border-top: 1px solid var(--line); }
.cmp-row:first-child { border-top: 0; }
.cmp-row p { padding: 12px 14px; font-size: 13.5px; line-height: 1.7; }
.cmp-row p + p { border-left: 1px solid var(--line); }
.cmp-row--head p { background: var(--bg-soft); font-weight: 600; color: var(--ink); }
.cmp-k { color: var(--ink); }
.cmp-a { color: var(--ink-2); }
.cmp-b { color: var(--ink-3); }

/* 工频磁场：对数刻度条状图。产品值 0.08–0.3 μT 与 100 μT 差两三个数量级，
   线性刻度画出来就是一条看不见的线——对数刻度才把「差多远」画清楚。
   最上面那行「国标限值」的满格条就是尺子。 */
.em { border: 1px solid var(--line); border-radius: var(--radius-card); overflow: hidden; }
.em-row {
  display: grid; grid-template-columns: minmax(0, 1fr) 116px 76px;
  align-items: center; gap: 12px; padding: 12px 14px;
  border-top: 1px solid var(--line);
}
.em-row:first-child { border-top: 0; }
.em-k { font-size: 13.5px; color: var(--ink); }
.em-track { height: 8px; border-radius: 999px; background: var(--bg-soft); overflow: hidden; }
.em-bar { display: block; height: 100%; border-radius: 999px; background: var(--accent-fill); }
.em-v { font-size: 13.5px; color: var(--ink-2); font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; }
.em-n { grid-column: 1 / -1; margin-top: -4px; font-size: 12.5px; line-height: 1.7; color: var(--ink-3); }

@media (max-width: 900px) {
  .mat-flow { grid-template-columns: 1fr; }
  .mat-step { padding-right: 0; }
  .mat-step + .mat-step { padding-left: 0; border-left: 0; border-top: 1px solid var(--line); padding-top: 20px; margin-top: 20px; }
  .cmp-row { grid-template-columns: 1fr; }
  .cmp-row p + p { border-left: 0; border-top: 1px solid var(--line); }
  .em-row { grid-template-columns: minmax(0, 1fr) 76px 68px; gap: 9px; }
}

/* ================================================================
   V1.60 首屏收口：照片满铺含导航、照片上零覆盖、文字压在图上
   ================================================================
   用户 2026-10-08 对三条产品目录页提了三条，并要求详情页同一逻辑：
     ① 背景图需覆盖顶部导航，满铺在上面的区域内；
     ② 背景图上不加任何遮罩；
     ③ 下面的文字标题内容移动到背景图上。
   这一节写在文件最后，是为了**不被任何媒体块按顺序压回**——上面
   `.page-hero--nomask::before`（桌面与 ≤760 各一条）、`.page-hero--img .page-hero-inner::before`、
   `.page-hero-bg::after` 三处都还在给这几页的覆盖层设值。

   **零覆盖的代价，写在明处**：没有垫底层，字色就只能按照片落点逐页选
   （`_gen/pick_textcolor.py`：落点亮度中位 ≥122 走墨字、<122 走暖白字），
   并给每一档文字配一层**贴着字形**的光晕。光晕只跟着笔画走，不覆盖照片，
   不是「为导航/为文字做的一块底色」。改动这一节必须用 `contrast.mjs` 逐页逐档复测。 */

/* ---- 1｜覆盖层全关：三条目录页 + 37 个详情页，全档生效 ---- */
.page-hero--line.page-hero--bare::before,
.page-hero--line.page-hero--bare .page-hero-inner::before,
.page-hero--line.page-hero--bare .page-hero-bg::after,
.pd-top.pd-top--bare::before,
.pd-top.pd-top--bare .pd-top-inner::before,
.pd-top.pd-top--bare .page-hero-bg::after { display: none; }

/* ---- 1b｜全站统一的顶部浅遮罩（V1.71，用户指定「除首页外都加一样的遮罩」）----
   **除首页外，所有首屏是摄影的页面共用同一条纵向渐隐**：峰值 α .36、26% 处 .26、
   62% 处 .12、84% 处归零，照片下缘约 16% 一处不盖。首页保留它自己那条
   `.hero::before`（150px / α .50），不在这组里；隐私政策首屏没有配图，也不涉及。
   它**取代**原来那条只覆盖 170px 的 `.page-hero-bg::after`（α .52 起）——为了让所有
   页面真正「一样」，那一条的高度与 α 都不再单独生效，一律走这里的值。要单独调某一类
   页面（例如 `.page-hero--dark` 那三页想更深），在下面这条之后另写一条更高的选择器即可。
   **`height` 必须显式写 100%**：基础规则（1115 行）把这个伪元素钉在 `height: 170px`，
   只写 `inset: 0` 会只罩到 y≈180 就断（V1.70 踩过，查法是把加遮罩前后的截图逐行相减）。
   **选择器要写足三个类**：`.page-hero--line.page-hero--bare` 那组「覆盖层全关」
   （V1.60 收口第 1 节）是三个类，两个类的写法压不过它；同理也要压过 ≤1200 那条
   只为 `.pd-top--img` 写的 `display: none`。 */
.page-hero--img .page-hero-bg::after,
.pd-top--img .page-hero-bg::after,
.page-hero--line.page-hero--bare .page-hero-bg::after,
.pd-top.pd-top--bare .page-hero-bg::after {
  content: ''; display: block; position: absolute; z-index: 2;
  inset: 0; height: 100%; pointer-events: none;
  background: linear-gradient(180deg,
              rgba(23, 26, 29, .36) 0,
              rgba(23, 26, 29, .26) 26%,
              rgba(23, 26, 29, .12) 62%,
              rgba(23, 26, 29, 0) 84%);
}

/* ---- 2｜版式：照片 `inset: 0` 顶到 y=0（含页头那一条），文字块与「联系我们」页同高 ----
   **文字块的位置不自写 padding，直接沿用站内那套**：`.page-hero--img` 与 `.pd-top--img`
   在 ≥1201 就是 `display:flex; align-items:flex-start; padding: 120px 0 72px`
   ——这三条目录页与 37 个详情页因此与核心材料／合作模式／关于我们／常见问题／联系我们
   五页的**文字块顶逐像素对齐**（1440 档都在 y=120），窄屏的各档也一并跟着走。
   （2026-10-08 那一版是「照片满铺 + 文字推到底」，用户 2026-10-09 要求
   「参照联系我们页顶部字的高度，统一上调」——所以这里回到站内默认的顶对齐。
   照片是绝对定位填满整块，不受 padding 影响，`inset: 0` 照旧覆盖页头那一条。） */
.page-hero--line.page-hero--bare .page-hero-bg,
.pd-top.pd-top--bare .page-hero-bg { inset: 0; }
.page-hero--line.page-hero--bare .page-hero-inner,
.pd-top.pd-top--bare .pd-top-inner { position: relative; z-index: 3; }
/* 详情页首屏的 padding **必须显式写**：基础规则 `.pd-top { padding: 158px 0 72px }`
   排在 `.pd-top--img`（1100 行）之后、特异性同为 (0,1,0)，把 ≥1201 那条 120px 压掉了，
   于是详情页各档都停在 158——比「联系我们」页低 38px。
   下面三档的值抄自 `.page-hero--img` 那条（也就是联系我们页实际拿到的值）。 */
.pd-top.pd-top--bare { padding: 172px 0 86px; }
@media (min-width: 1201px) { .pd-top.pd-top--bare { padding: 120px 0 72px; } }
@media (max-width: 760px) { .pd-top.pd-top--bare { padding: 116px 0 60px; } }
/* 文字块内部间距：目录页沿用用户 V1.54 给的那条链（眉题 +30 在模板内联、主标题 +16、
   说明句 +25）。主标题这条要压过 `.page-hero h1`（14px）。
   **详情页主标题上面没有别的元素**（面包屑在照片下方的 `.pd-top--crumb-bar`… 不是首屏里），
   所以它取 0 而不是 16——否则整块的顶会比目录页低 16px，「统一」就不成立。 */
.page-hero--line.page-hero--bare h1 { margin-top: 16px; }
.pd-top.pd-top--bare h1 { margin-top: 0; }
.page-hero--line.page-hero--bare .page-sub { margin-top: 25px; }

/* ---- 3｜字色（默认墨字）----
   写足三个类是为了压过 `.page-hero--nomask ...` / `.pd-top.pd-top--nomask ...`
   那两组压照片用的 `--ink-2-photo`（它们也是三个类）。 */
.page-hero--line.page-hero--bare h1,
.pd-top.pd-top--bare h1 { color: var(--ink); }
.page-hero--line.page-hero--bare .crumb,
.page-hero--line.page-hero--bare .crumb a,
.pd-top.pd-top--bare .crumb,
.pd-top.pd-top--bare .crumb a { color: var(--ink); }
/* 正文两行（说明句、英文小行）原本用压照片那档灰 `--ink-2-photo #2F353B`。
   零覆盖之后那档灰在照片的中调上只剩 2–4:1，与主标题一样提到 `--ink` 本体；
   层级改由字号承担（主标题 44px、说明句 17px），不再靠颜色分。 */
.page-hero--line.page-hero--bare .page-sub,
.pd-top.pd-top--bare .pd-desc,
.page-hero--line.page-hero--bare .eyebrow,
.pd-top.pd-top--bare .pd-en { color: var(--ink); }
.pd-top.pd-top--bare .tag { border-color: rgba(23, 26, 29, .38); color: var(--ink); }
.pd-top.pd-top--bare .pd-status { color: var(--ink-2-photo); }
/* 贴字形的暖白光晕：只作用在笔画周围，照片本身一处不遮。
   **半径必须跟着字号走**：小字（13–17px）挂 16px 的模糊半径会连成一片云，
   整块读起来就是「照片上糊了一层雾」——正是用户退回过的那种观感。
   所以主标题单列一条给大半径，其余统统收在 4px 以内。 */
.page-hero--line.page-hero--bare h1,
.pd-top.pd-top--bare h1 {
  text-shadow: 0 1px 3px rgba(243, 241, 234, .85), 0 0 14px rgba(243, 241, 234, .60);
}
.page-hero--line.page-hero--bare .page-sub, .pd-top.pd-top--bare .pd-desc,
.page-hero--line.page-hero--bare .crumb, .page-hero--line.page-hero--bare .crumb a,
.pd-top.pd-top--bare .crumb, .pd-top.pd-top--bare .crumb a,
.page-hero--line.page-hero--bare .eyebrow, .pd-top.pd-top--bare .pd-en,
.pd-top.pd-top--bare .tag, .pd-top.pd-top--bare .pd-status {
  text-shadow: 0 1px 1px rgba(243, 241, 234, .92), 0 0 4px rgba(243, 241, 234, .78);
}

/* ---- 4｜字色（暖白字）：落点为暗底的照片，由 `_gen/textcolor.json` 逐页决定 ---- */
.page-hero--line.page-hero--lighttxt h1,
.pd-top.pd-top--lighttxt h1 { color: var(--white); }
.page-hero--line.page-hero--lighttxt .crumb,
.page-hero--line.page-hero--lighttxt .crumb a,
.pd-top.pd-top--lighttxt .crumb,
.pd-top.pd-top--lighttxt .crumb a { color: rgba(255, 255, 255, .88); }
.page-hero--line.page-hero--lighttxt .page-sub,
.pd-top.pd-top--lighttxt .pd-desc,
.page-hero--line.page-hero--lighttxt .eyebrow,
.pd-top.pd-top--lighttxt .pd-en { color: var(--white); }
.pd-top.pd-top--lighttxt .tag { border-color: rgba(255, 255, 255, .46); color: rgba(255, 255, 255, .92); }
.pd-top.pd-top--lighttxt .pd-status { color: rgba(255, 255, 255, .88); }
.page-hero--line.page-hero--lighttxt h1, .pd-top.pd-top--lighttxt h1,
.page-hero--line.page-hero--lighttxt .page-sub, .pd-top.pd-top--lighttxt .pd-desc,
.page-hero--line.page-hero--lighttxt .crumb, .page-hero--line.page-hero--lighttxt .crumb a,
.pd-top.pd-top--lighttxt .crumb, .pd-top.pd-top--lighttxt .crumb a,
.page-hero--line.page-hero--lighttxt .eyebrow, .pd-top.pd-top--lighttxt .pd-en,
.pd-top.pd-top--lighttxt .tag, .pd-top.pd-top--lighttxt .pd-status {
  text-shadow: 0 1px 3px rgba(23, 26, 29, .80), 0 0 14px rgba(23, 26, 29, .52);
}
.page-hero--line.page-hero--lighttxt .page-sub, .pd-top.pd-top--lighttxt .pd-desc,
.page-hero--line.page-hero--lighttxt .crumb, .page-hero--line.page-hero--lighttxt .crumb a,
.pd-top.pd-top--lighttxt .crumb, .pd-top.pd-top--lighttxt .crumb a,
.page-hero--line.page-hero--lighttxt .eyebrow, .pd-top.pd-top--lighttxt .pd-en,
.pd-top.pd-top--lighttxt .tag, .pd-top.pd-top--lighttxt .pd-status {
  text-shadow: 0 1px 1px rgba(23, 26, 29, .88), 0 0 4px rgba(23, 26, 29, .72);
}


/* ---- 6｜页头字色：照片顶部够暗的页面走全站默认的暖白字，亮顶那几页翻墨字 ----
   照片铺满之后，≥1201 的页头是「透明叠图」态，Logo 与七项导航直接压在照片上。
   哪一页该翻墨字由 `_gen/pick_textcolor.py` 按 **Logo 与导航两个真实落点**逐页定
   （不是量整条页头带——导航整行偏右，中间大段是照片里的窗与天花，全宽平均会把结论稀释掉）。
   两个落点各按最坏情况比：墨字看第 5 百分位、暖白字看第 95 百分位，取更差的那一个。
   Logo 换成墨版是**另一张图**（`logo-mjxn-ink.png`），不是把白版调色。
   **必须限定 `min-width: 1201px`**：只有那一档页头才透明；1200 以下页头本身是墨黑实体层，
   把导航改成墨字会直接消失。滚出 24px 后脚本加 `.is-solid`，这一组自动失效。 */
@media (min-width: 1201px) {
  body.on-light .site-header:not(.is-solid) .brand-logo {
    background-image: url(../images/brand/logo-mjxn-ink.png);
  }
  body.on-light .site-header:not(.is-solid) .nav-list > li > a {
    color: var(--ink);
    text-shadow: 0 1px 2px rgba(243, 241, 234, .70), 0 0 12px rgba(243, 241, 234, .58);
  }
  body.on-light .site-header:not(.is-solid) .nav-list > li > a:hover { color: var(--accent); }
  body.on-light .site-header:not(.is-solid) .nav-list > li > a[aria-current="page"] { color: var(--ink); }
}

/* ================================================================
   V1.72 三条产品目录页改版（用户 2026-10-09 给的改版规格）
   ================================================================
   只服务石墨烯采暖 / 石墨烯发热用品 / 石墨烯艾草暖敷三页——全部挂在这一套新类名上
   （`.line-layout` `.line-nav` `.line-main` `.line-sec` `.prod-grid` `.adv-list` `.chan-list`）。
   常见问题页仍在用旧的 `.cat-layout` / `.cat-tree`，两者互不影响；首页、详情页、
   页脚、全站导航与设计系统这一节一条都没写到（规格第三节「严格修改范围」）。
   写在文件末尾：`display` / `grid-template-columns` 这类属性要与前面的规则比顺序，
   放前面会被压掉。 */

/* ---------- 1｜两栏骨架：左侧本页导航 + 右侧主内容 ----------
   V2.17 按用户给的《MJXN 官网侧边导航改造规范 V2.1》：导航列 200→240px、
   与正文间距 44→56px（规范：栏宽 220–260、间距 48–72）。 */
.line-layout { display: grid; grid-template-columns: 240px minmax(0, 1fr); gap: 56px; align-items: start; }
.line-main { min-width: 0; }
.line-sec + .line-sec { margin-top: 88px; }
/* 适配渠道与合作落地两块原来用浅暖灰卡片「收一下」、与上方产品区拉开层次（规格第六、七节）。
   **V2.19**：用户 2026-10-10 20:40 圈出这两块：「这个都不要有外框了」→ **整条卡片壳都去掉**
   （浅底 / 1px 边框 / 圆角 / 内边距），与上面「产品目录」「核心优势」一样是**纯白无壳**，
   四块统一；块间距也从 32px 回到与 `.line-sec + .line-sec` 相同的 88px。 */
.line-sec--soft { background: none; border: 0; border-radius: 0; padding: 0; }
.line-sec--soft + .line-sec--soft { margin-top: 88px; }

/* ---------- 2｜左侧本页导航：两级、sticky、纯白极简、默认展开 ----------
   V1.72 的当前态只有「淡橙底」一层，滚动时几乎看不出在跟（用户 2026-10-09
   「目录的跟随效果不好不明显」）；V1.73 起加了左侧 2px 竖线 + 序号转橙 + 字重 600。
   **V2.16 按《纯白极简版》去掉橙色填充块、只留定位线。**
   **V2.17 按《MJXN 官网侧边导航改造规范 V2.1》再调**，与 V2.16 的差异：
     · 标题区改为 **英文小标题在上、中文主标题在下**（中文放大到 24px/Medium），
       标题下方加一条 `#E8E8E5` 横向分隔线；
     · 品牌橙改用规范值 **`#B95C32`**（低饱和铜橙）；辅助色／默认编号 `#898A84`；
     · 一级章节行上下留白 20px、章节间 1px 分隔线；编号固定列宽（一级 26px、二级 20px）；
     · 「产品目录」右侧加 **`+` / `−` 展开符号**（12–14px、`#777872`），
       **默认展开**、点击可收起（子项 없는章节不显示符号）；
     · 子菜单竖线改用 `#E5E5E2`。
   竖线仍走常驻 `border-left`（非当前态给透明），换态时不会因为多出 2px 把文字推得左右跳。 */
.line-nav {
  position: sticky; top: calc(var(--header-h) + 28px);
  background: #FFFFFF;
  padding: 26px 20px;
  margin: 0 -20px;
  --nav-orange: #B95C32;
  --nav-line: #E8E8E5;
  --nav-guide: #E5E5E2;
  --nav-ink: #252622;
  --nav-ink-2: #30312D;
  --nav-ink-3: #777872;
  --nav-ink-4: #898A84;
}
.line-nav-en { font-size: 12.5px; letter-spacing: .24em; color: var(--nav-ink-4); }
.line-nav-t {
  margin-top: 8px; padding-bottom: 14px; border-bottom: 1px solid var(--nav-line);
  font-size: 24px; font-weight: 500; color: var(--nav-ink);
}
.line-nav-list, .line-nav-sub { list-style: none; margin: 0; padding: 0; }
.line-nav-list > li { position: relative; }
.line-nav-list > li + li { border-top: 1px solid var(--nav-line); }
.line-nav-list a {
  display: flex; gap: 10px; align-items: baseline;
  padding: 20px 26px 20px 12px;
  border-left: 2px solid transparent;
  font-size: 15.5px; font-weight: 500; line-height: 1.4; color: var(--nav-ink-2);
  transition: color .2s var(--ease), border-left-color .2s var(--ease);
}
.line-nav-list a:hover { color: var(--nav-ink); }
.line-nav-list .ln-no {
  flex: none; width: 26px; font-size: 12.5px; letter-spacing: .02em;
  color: var(--nav-ink-4); font-variant-numeric: tabular-nums;
}
/* 当前项：只用一条铜橙定位线，不加底色 */
.line-nav-list a.is-active {
  background: transparent; border-left-color: var(--nav-orange);
  color: var(--nav-ink); font-weight: 600;
}
.line-nav-list a.is-active .ln-no { color: var(--nav-orange); font-weight: 600; }
/* 展开 / 收起符号：只有带子项的一级章节才有 */
.line-nav-tg {
  position: absolute; right: 0; top: 21px;
  width: 20px; height: 20px; padding: 0; margin: 0;
  background: none; border: 0; cursor: pointer;
  font: inherit; font-size: 14.5px; line-height: 20px; text-align: center;
  color: var(--nav-ink-3);
  transition: color .2s var(--ease);
}
.line-nav-tg:hover { color: var(--nav-ink); }
.line-nav-tg::before { content: '−'; }
.line-nav-list > li.is-collapsed .line-nav-tg::before { content: '+'; }
.line-nav-list > li.is-collapsed .line-nav-sub { display: none; }
.line-nav-sub { margin: 0 0 12px 12px; padding-left: 12px; border-left: 1px solid var(--nav-guide); }
.line-nav-sub a {
  font-size: 13.5px; font-weight: 400; padding: 8px 10px 8px 10px; color: var(--nav-ink-3);
}
.line-nav-sub .ln-no { width: 20px; font-size: 12.5px; color: var(--nav-ink-4); }
.line-nav-sub a:hover { color: var(--nav-ink-2); }
/* 二级当前项：同样只有铜橙细定位线、无底色 */
.line-nav-sub a.is-active {
  background: transparent; border-left-color: var(--nav-orange);
  color: var(--nav-ink); font-weight: 500;
}
.line-nav-sub a.is-active .ln-no { color: var(--nav-orange); }

/* 移动端：顶部可展开的目录面板（原生 `<details>`，不依赖脚本）。≥1081 隐藏。 */
.line-nav-m {
  display: none; background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius-sm); padding: 0 14px;
}
.line-nav-m > summary {
  cursor: pointer; padding: 14px 0; font-size: 15px; font-weight: 600; color: var(--ink);
  list-style: none;
}
.line-nav-m > summary::-webkit-details-marker { display: none; }
.line-nav-m > summary::after {
  content: ''; float: right; width: 8px; height: 8px; margin-top: 6px;
  border-right: 1.7px solid var(--ink-3); border-bottom: 1.7px solid var(--ink-3);
  transform: rotate(45deg); transition: transform .25s var(--ease);
}
.line-nav-m[open] > summary::after { transform: rotate(225deg); margin-top: 9px; }
.line-nav-m .line-nav-list { margin: 0 0 14px; }

/* ---------- 3｜产品网格：桌面四列（规格第四节）---------- */
.prod-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 24px; }

/* ---------- 4｜核心优势：图标 + 标题 + 描述的小卡（V1.73）----------
   用户 2026-10-09：「都换成对应的小图标加标题加描述形式，加点风格，不要就单纯的没背景的」。
   原先是一条优势一张 16:10 实拍大卡（图 700×437），V1.72 收到 88px 方形 .jpg 小图但
   仍然裸放在底色上；这一版**换成线性图标并给整条铺白卡**——图标坐在淡橙方块里，
   标题在下、描述再下一行，三者竖排。
   图标走 `--accent`（4.91:1，见 :root 注释），不额外上高饱和填充：
   规格要求「避免大面积高饱和橙色、过度阴影、炫光」，所以卡面只有 1px 线 + 悬停时
   一点位移与极浅投影。 */
.adv-list {
  list-style: none; margin: 0; padding: 0; display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 18px;
}
.adv-item {
  display: flex; flex-direction: column; gap: 12px;
  padding: 22px 20px 24px; background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--radius-card);
  transition: border-color .25s var(--ease), transform .25s var(--ease),
              box-shadow .25s var(--ease);
}
.adv-item:hover {
  border-color: rgba(169, 78, 12, .32); transform: translateY(-2px);
  box-shadow: 0 10px 22px rgba(58, 42, 28, .07);
}
.adv-ico {
  display: grid; place-items: center; flex: none;
  width: 42px; height: 42px; border-radius: var(--radius-sm);
  background: var(--accent-soft); color: var(--accent);
}
.adv-ico svg { width: 23px; height: 23px; }
.adv-item h3 { font-size: 17px; font-weight: 700; color: var(--ink); }
.adv-item p { font-size: 13.5px; line-height: 1.72; color: var(--ink-2); }
.adv-group + .adv-group { margin-top: 36px; }
.adv-group > .h3 { margin-bottom: 18px; }

/* ---------- 5｜适配渠道：一行高的图标 + 名称卡片（V1.73）----------
   用户 2026-10-09：「13 款产品标注该渠道，这种话术都去掉，然后缩小对应的高度」。
   原卡片是「图标 / 名称 / 计数句」三行竖排；去掉计数句后改成**横向一行**，
   内边距同步收到 14px，整张高度由约 116px 降到约 54px。渠道名与顺序一字未改。 */
.chan-list {
  list-style: none; margin: 0; padding: 0; display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px;
}
.chan-card {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 16px; background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  transition: border-color .22s var(--ease);
}
.chan-card:hover { border-color: rgba(169, 78, 12, .32); }
.chan-ico { flex: none; width: 20px; height: 20px; color: var(--accent); }
.chan-ico svg { display: block; width: 100%; height: 100%; }
.chan-nm { font-size: 14.5px; font-weight: 600; line-height: 1.45; color: var(--ink); }

/* ---------- 6｜响应式（规格第九节）---------- */
@media (max-width: 1200px) {
  .line-layout { grid-template-columns: 184px minmax(0, 1fr); gap: 32px; }
  .prod-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .adv-list, .chan-list { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 1080px) {
  /* 窄档不再固定左侧栏，改成顶部可展开的目录面板 */
  .line-layout { grid-template-columns: minmax(0, 1fr); gap: 28px; }
  .line-nav { display: none; }
  .line-nav-m { display: block; }
}
@media (max-width: 860px) {
  .prod-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .adv-list, .chan-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .line-sec + .line-sec { margin-top: 64px; }
  .line-sec--soft { padding: 28px 22px; }
}
/* 优势卡竖排三行，窄屏一列到底；渠道卡只有一行高，再窄也扛得住两列。 */
@media (max-width: 560px) {
  .adv-list { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 420px) {
  .prod-grid, .chan-list { grid-template-columns: minmax(0, 1fr); }
}

/* ================================================================
   V1.77 单个产品详情页模板（`.pdv-` 前缀；先只挂「发热马甲」一页）
   ================================================================
   依据：用户 2026-10-09 给的重设计稿。版式照它落地——
     首屏 ＝ 面包屑 ＋ 左文右图（图 4:5）
     01   ＝ 白底区：编号／英文小标／中文标题 ＋ 左参数表＋渠道标签、右产品图
     02   ＝ 页面底色区：三列卡片，每卡带编号
     03   ＝ 白底区：三列场景卡，图 16:10
     04   ＝ 合作分区：左文 ＋ 一个按钮（V1.80 起走页面底色，不再用深色带）
   颜色、字体、圆角一律走站内令牌（`--bg`／`--surface`／`--ink*`／`--accent*`／
   `--radius-*`／`--line`）——重设计稿的那套色值与站内令牌本来就同源，
   不另起一套色板。页头、页脚、导航、右侧联系条仍是全站共享组件，未动。
   作用域：全部选择器带 `.pdv-` 或挂 `main.pdv`；目录页 `.line-*`、其余 36 个详情页的
   `.pd-*`、常见问题页的 `.cat-*` 一处不碰。

   **重设计稿里没有采用的部分**（逐条见 README V1.77）：
     · 首屏图上那层黑色渐变＋白字图注——照片上不加遮罩是用户两次明令过的；
     · 场景卡右上角那串 `s2`／`s1` 编号——那是稿子里把素材文件名露出来了；
     · 稿子里改写过或新加的文案（副标题、参数值、特点与场景说明、公司地址／电话／邮箱／
       备案号）——一律不import，正文仍逐字取产品卡；若要用，得先补资料。 */

/* V2.21：**整页纯白**（用户 2026-10-10 22:37 对首屏与合作区两处圈图：「这两处都是纯白色」）。
   上一轮 V2.20 只把中间三段改白、暖白留给首屏与 04；这一轮首屏与 04 也一并改白，
   所以 `--bg` 暖白在详情页上已经不用了（它仍是 body 的底色，其它页照旧）。 */
main.pdv { background: var(--surface); }

/* ---------- 1｜首屏：面包屑 ＋ 左文右图（图 4:5）---------- */
/* V1.80：面包屑上方的留白按重设计稿的 `pt-20` 给足 80px（此前 30px）——
   用户 2026-10-10 给的两张对照图里，稿子那张面包屑落在页头下方 80px。
   **V2.20：首屏自动占满一屏**（用户 2026-10-10 21:19：「顶部的这块区域自动站一屏幕到
   屏幕下边」）。做法是给区块一个 `min-height: 100vh − 页头高`（页头已在 `margin-top`
   里让出），再用 flex 把内容块垂直居中——**内容比一屏高时（4:5 竖幅那批）区块自然增
   高，不裁不压**；比一屏矮时（4:3 横构图那批）就居中留白，下边缘正好落在屏幕底。
   `svh` 那一行是给移动端浏览器地址栏用的，不认 `svh` 的浏览器会丢掉它、用上面那行。
   **下内边距 96 → 40（V2.21 收口）**：96 那档让 4:5 竖幅的首图只有 458 宽、离列宽 560
   差 100 出头，右侧留白偏大；收到 40 后 1440×900 下是 502 宽，更贴列、也更靠近屏幕底。
   这条与下面 `.pdv-hero-media img` 的固定占位是**一对**，改一处必须同步改另一处。 */
.pdv-hero {
  margin-top: var(--header-h); padding: 80px 0 40px;
  min-height: calc(100vh - var(--header-h));
  min-height: calc(100svh - var(--header-h));
  display: flex; align-items: center;
}
/* flex 子项按内容收缩会把 `1fr` 栅格压塌，显式给满宽；`max-width` 与 `margin:auto`
   仍在 `.wrap` 自己身上，宽屏下照旧是 1240 居中。 */
.pdv-hero > .wrap { width: 100%; }
/* V1.99：字号 12.5 → 14.5（用户 2026-10-10 14:54：「这个导航字大 2 号」）。 */
main.pdv .pdv-crumb { font-size: 14.5px; letter-spacing: .02em; color: var(--ink-3); }
main.pdv .pdv-crumb a { color: var(--ink-3); }
main.pdv .pdv-crumb a:hover { color: var(--accent); }
main.pdv .pdv-crumb .is-current { color: var(--ink); font-weight: 600; }
.pdv-hero-grid {
  margin-top: 48px;
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 56px; align-items: center;
}
.pdv-eyebrow { margin-bottom: 2px; }
main.pdv .pdv-hero h1 {
  margin-top: 14px; font-size: clamp(32px, 3.6vw, 52px); font-weight: 700;
  line-height: 1.14; letter-spacing: -.015em; color: var(--ink);
}
.pdv-hero-sub { margin-top: 16px; font-size: 17px; line-height: 1.75; color: var(--ink-2); }
/* 三条关键项：参数名在上、卡内原值在下，三列平铺，与上方文案用 1px 线分隔。 */
.pdv-facts {
  margin: 32px 0 0; padding-top: 22px; border-top: 1px solid var(--line);
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px;
}
.pdv-facts dt { font-size: 12.5px; letter-spacing: .02em; color: var(--ink-3); }
.pdv-facts dd { margin: 6px 0 0; font-size: 14.5px; font-weight: 600; line-height: 1.5; color: var(--ink); }
.pdv-hero-media { margin: 0; border-radius: var(--radius-card); overflow: hidden; background: var(--bg-soft); }
/* 源图 1600×1000（8:5）。4:5 竖幅居中裁到 800 宽＝只留人物与后腰热区、充电宝那一段，
   主体完整、上下无裁切；8:5 横铺会带进大片空墙，反而不如这一档聚焦。 */
.pdv-hero-media img {
  display: block; width: 100%; height: auto; aspect-ratio: 4 / 5;
  object-fit: cover; object-position: 50% 50%;
}
/* V1.85：艾草／采暖两线的首屏图是 1536×960 的横构图场景（房间、桌面、施工），
   照 4:5 竖裁要切掉约一半宽度、主体常被切到 → 这两线改用 4:3（源宽只收 17%）。 */
.pdv-hero-media--43 img { aspect-ratio: 4 / 3; }

/* ---------- 1b｜首屏右侧图：尺寸锁进「一屏之内」（V2.21）----------
   用户 2026-10-10 22:37：「我希望右边的图都是固定尺寸，正好可以一屏幕看完全图，
   同时底部的这个区域也是正好一个屏幕，不要再往下滚动了」——并点明了根因
   「可能是因为这个图片太高了，然后把这个区域往下拉……还有一小半的区域超出了当前屏幕」。
   实测：4:5 竖幅那批（发热用品线）在 1440×900 下版面上是 560×700，
   加上上下内边距 80+96、面包屑 28、栅格上边距 48，首屏内容共 952px，
   而可用高度只有 900−76＝824 → **多出 128px 被顶到屏幕外**，首屏下边缘看不见。
   做法：桌面档把首屏图的**高度**锁成「一屏减页头再减那 196px 固定占位」，
   宽度交给 `aspect-ratio` 自己算——**整幅可见，不裁不切**，右对齐贴住栅格右缘，
   圆角挪到图自身上（图的宽度不再等于列宽，figure 那层圆角就管不到它的两侧了）。
   4:3 横构图那批本来就矮于可用高度（560→420），按列宽铺满即可，另给一条复位。
   占位 196 ＝ 内边距 80+40 ＋ 面包屑 28 ＋ 栅格上边距 48；首屏因此**正好一屏**，
   下边缘落在屏幕底，`min-height` 那条不再被内容顶开。
   **V2.21 收口：下内边距由 96 收到 40**（用户 2026-10-11 00:38 认可这个取舍）。
   96 那档算出来的 4:5 竖幅只有 458 宽、离列宽 560 还差 100 出头，右侧留白偏大；
   收到 40 之后 1440×900 下是 **502 宽**，明显更贴列，图的下沿也离屏幕底更近。
   代价只是图与下一段之间的呼吸位从 96 减到 40。
   窄档（≤1024）栅格翻成上下结构，一屏本来就放不下，这一组不生效、图回自然比例。 */
@media (min-width: 1025px) {
  .pdv-hero-media { background: transparent; }
  .pdv-hero-media img {
    height: calc(100vh - var(--header-h) - 196px);
    height: calc(100svh - var(--header-h) - 196px);
    width: auto; margin-left: auto;
    border-radius: var(--radius-card);
  }
  .pdv-hero-media--43 img { height: auto; width: 100%; margin-left: 0; }
}

/* ---------- 2｜区块通用：编号＋英文小标＋中文标题 ---------- */
/* **V2.20：中间三段统一纯白**（用户 2026-10-10 21:19：「产品详情页除了顶部与底部，
   中间统一纯白色背景」）。原先是 01／03 白底、02 走页面底色（`--bg` 暖白）的交替，
   现在 `main.pdv` 的暖白只留给顶部首屏与底部合作区，中间 88px 区块一律 `--surface`。
   01／03 的上下 1px 细线保留——白底连成一片后，那几条线就是段与段之间唯一的界。 */
.pdv-sec { padding: 88px 0; background: var(--surface); }
.pdv-sec--card { background: var(--surface); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.pdv-head { padding-bottom: 22px; border-bottom: 1px solid var(--line); }
/* `--split`：左「编号＋标题」、右一句引导语（两份重设计稿都是这个结构）。
   **V1.78 只加了那一句、漏了这条规则**，引导句一直堆在标题下方；V1.81 补上。
   窄档（≤768）落回上下结构，与稿子的 `md:` 断点一致。 */
.pdv-head--split { display: flex; align-items: flex-end; justify-content: space-between; gap: 40px; }
.pdv-scene-lead { max-width: 34em; font-size: 14.5px; line-height: 1.8; color: var(--ink-2); }
.pdv-kicker {
  font-size: 12.5px; font-weight: 600; letter-spacing: .16em;
  text-transform: uppercase; color: var(--accent);
}
main.pdv .pdv-sec h2,
main.pdv .pdv-coop h2 {
  margin-top: 10px; font-size: clamp(24px, 2.4vw, 32px); font-weight: 700;
  letter-spacing: -.01em; line-height: 1.25; color: var(--ink);
}

/* ---------- 3｜01 产品介绍与规格：左参数右图 ---------- */
.pdv-intro {
  margin-top: 44px; display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 56px; align-items: start;
}
.pdv-intro-txt { min-width: 0; }
.pdv-lead { font-size: 16px; line-height: 1.85; color: var(--ink-2); }
.pdv-sub-t { margin: 38px 0 0; font-size: 14.5px; font-weight: 700; letter-spacing: .02em; color: var(--ink); }
/* 参数表：外框 ＋ 行间 1px 线。**V1.99 去掉隔行浅底**
   （用户 2026-10-10 14:54：「这种表格里面带有颜色的…都给它去掉」）——
   原写法是 `.pdv-prow:nth-child(odd){background:var(--bg-soft)}`，四行里第 1、3 行带底色。 */
.pdv-params { margin: 14px 0 0; border: 1px solid var(--line); border-radius: var(--radius-md); overflow: hidden; }
.pdv-prow { display: grid; grid-template-columns: 96px minmax(0, 1fr); gap: 16px; padding: 14px 18px; font-size: 13.5px; }
.pdv-prow + .pdv-prow { border-top: 1px solid var(--line); }
.pdv-prow dt { color: var(--ink-3); }
.pdv-prow dd { margin: 0; font-weight: 500; line-height: 1.6; color: var(--ink); }
.pdv-note { margin-top: 12px; font-size: 12.5px; color: var(--ink-3); }
.pdv-chips { list-style: none; margin: 14px 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 8px; }
.pdv-chips li {
  padding: 7px 14px; background: var(--bg-soft); border: 1px solid var(--line);
  border-radius: var(--radius-sm); font-size: 12.5px; font-weight: 500; color: var(--ink);
}
.pdv-intro-media { margin: 0; border: 1px solid var(--line); border-radius: var(--radius-card); overflow: hidden; background: var(--bg-soft); }
/* 源图 1200×900 本来就是 4:3，不裁切。 */
.pdv-intro-media img { display: block; width: 100%; height: auto; aspect-ratio: 4 / 3; object-fit: cover; }

/* ---------- 4｜02 产品核心特点：三列卡片（编号＋标题＋说明）---------- */
.pdv-feat-grid {
  list-style: none; margin: 44px 0 0; padding: 0; display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px;
}
.pdv-feat-item {
  padding: 30px 28px; background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--radius-card);
  transition: box-shadow .25s var(--ease), transform .25s var(--ease);
}
.pdv-feat-item:hover { box-shadow: 0 12px 30px rgba(23, 26, 29, .08); transform: translateY(-2px); }
/* 图标与编号同一行：图标在左、编号在右（重设计稿 `flex items-center justify-between`）。 */
.pdv-feat-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.pdv-feat-ico { display: block; flex: none; }
.pdv-feat-no {
  font-size: 12.5px; font-weight: 700; letter-spacing: .1em;
  color: var(--accent); font-variant-numeric: tabular-nums;
}
.pdv-feat-item h3 { margin-top: 20px; font-size: 17px; font-weight: 700; color: var(--ink); }
.pdv-feat-item p { margin-top: 10px; font-size: 13.5px; line-height: 1.8; color: var(--ink-2); }

/* ---------- 5｜03 多元应用场景：三列卡片，图 16:10 ---------- */
.pdv-scenes {
  list-style: none; margin: 44px 0 0; padding: 0; display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 34px 24px;
}
/* V1.81：条目数是 4 的倍数时排 4 列（发热上衣 8 条 → 两行，不出孤行；
   马甲 9 条仍走 3 列）。窄档由下面那两个媒体查询统一收成 2 列 / 1 列。 */
.pdv-scenes--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
/* V1.85：采暖两款的场景是 10 条、5 条——排 5 列各成整行（排 3 列会剩一条孤行）。 */
.pdv-scenes--5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.pdv-scene { min-width: 0; }
.pdv-scene-media { margin: 0; border: 1px solid var(--line); border-radius: var(--radius-md); overflow: hidden; background: var(--bg-soft); }
/* 源图 800×800 方图，统一裁 16:10。 */
.pdv-scene img { display: block; width: 100%; height: auto; aspect-ratio: 16 / 10; object-fit: cover; }
.pdv-scene h3 { margin-top: 14px; font-size: 17px; font-weight: 700; color: var(--ink); }
.pdv-scene p { margin-top: 7px; font-size: 13.5px; line-height: 1.75; color: var(--ink-2); }

/* ---------- 6｜04 合作：独立分区，左文右按钮 ----------
   **V1.80：由「深色带」改为页面底色分区**（用户 2026-10-10：「这块的『与墨聚芯能合作』
   独立出去，不要混在底部内容中」）。原深色带用的 `--bg-deep` 与页脚 `.site-footer`
   **是同一个色值 #171A1D**，两块紧挨着连成一片、读起来像页脚的上一段。改走 `--bg`
   （＝ 02 那一档暖白），与前面 03 的白底成交替、与后面页脚的黑形成硬分界；
   文字回墨色、眉题用浅底那一档沉橙（原色在浅底只有 2.07:1，站内规矩只做装饰线）。
   **V2.21：底色由 `--bg` 暖白改成 `--surface` 纯白**（用户 2026-10-10 22:37 圈图：
   「这两处都是纯白色」）。与上方 03 的分界只剩 03 自己的 1px 下边框，与页脚的黑仍是硬分界。 */
.pdv-coop { padding: 76px 0; background: var(--surface); }
.pdv-coop-in { display: flex; align-items: center; justify-content: space-between; gap: 48px; }
.pdv-coop-tx { margin-top: 14px; max-width: 62ch; font-size: 15px; line-height: 1.8; color: var(--ink-2); }
/* V1.85：按钮由 1 个改回 2 个（用户对照旧版 04 区块：「内容少了」）——
   「联系我们」照旧走实底橙，「合作模式」在浅底上走 `btn-ghost`（深底那枚 `btn-ghost-light`
   在暖白底上读不出来）。 */
.pdv-coop-act { flex: none; display: flex; flex-wrap: wrap; gap: 14px; }

/* ---------- 7｜响应式（照重设计稿的 lg / md 断点）---------- */
@media (max-width: 1024px) {
  .pdv-hero { padding-bottom: 72px; }
  .pdv-hero-grid, .pdv-intro { grid-template-columns: minmax(0, 1fr); gap: 32px; }
  .pdv-feat-grid, .pdv-scenes { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pdv-coop-in { flex-direction: column; align-items: flex-start; gap: 30px; }
}
@media (max-width: 768px) {
  /* 稿子的 md 断点：≥768 走 pt-20（80px），以下收成 pt-12（48px）。 */
  .pdv-hero { padding: 48px 0 56px; }
  /* 03 标题行同样照稿子的 md 断点落回上下结构。 */
  .pdv-head--split { display: block; }
  .pdv-scene-lead { margin-top: 12px; max-width: none; }
  .pdv-hero-grid { margin-top: 28px; }
  .pdv-sec { padding: 56px 0; }
  .pdv-intro { margin-top: 32px; }
  .pdv-facts { margin-top: 26px; grid-template-columns: minmax(0, 1fr); gap: 16px; }
  .pdv-feat-grid { margin-top: 32px; grid-template-columns: minmax(0, 1fr); gap: 16px; }
  .pdv-scenes { margin-top: 32px; grid-template-columns: minmax(0, 1fr); }
  .pdv-prow { grid-template-columns: 84px minmax(0, 1fr); gap: 14px; padding: 12px 14px; }
}

/* ================================================================
   V2.23 四个独立页收口（用户 2026-10-11 00:59 一次六条）
   ================================================================
   1）**中间区统一纯白**：合作模式／关于我们／常见问题／联系我们四页，`<main>` 挂 `pg-white`，
      中间内容区一律纯白（页头是照片、页脚是墨黑，都不在此列）。这四页原先靠
      `.section--soft`（`--bg-soft`）与 body 的 `--bg` 暖白做层次，现在全部收平。
   2）**首屏暖白字、零遮罩**：挂 `page-hero--dark`（那一档给的是一整套暖白字色），
      再加 `page-hero--noscrim` 把两层渐隐关掉——横向那层 `.page-hero--nomask::before`、
      以及它派生出来的窄档纵向那层。窄档那两条只改 `background`，这里用 `display:none`，
      属性不冲突；本块写在文件末尾，同特异性的规则也压得住。
      **顶部那 170px 压暗（`.page-hero-bg::after`）保留**——它服务的是透明页头，
      去掉之后白 Logo 与白导航会直接落进照片里。 */
main.pg-white { background: var(--surface); }
main.pg-white .section--soft,
main.pg-white .cta-band { background: var(--surface); }

.page-hero--noscrim.page-hero--nomask::before,
.page-hero--noscrim .page-hero-inner::before { display: none; }

/* ---- V2.24：四个独立页的顶部遮罩加深一档（用户 2026-10-11 01:13）----
   用户原话：「顶部banner中参照 石墨烯艾草暖敷目录页的banner遮罩，同步给四个页面顶部banner也加一下」。
   先说明实情：**这四页吃的本来就是艾草页那一条**（V1.71 全站统一浅遮罩，
   `.page-hero--img` 全组命中），实测五页 `::after` 的 computed background 逐字相同
   （峰 α .36、26% .26、62% .12、84% 归零、`height: 100%`）。
   「看着不一样」的根源是**照片本身**：艾草页那张顶部本就暗（0–40 行右半中位 104–107），
   四页是明亮商务场景（125–172），同一条 α .36 落在亮照片上几乎看不出来——
   页头白字实测最低只有 2.0–3.5:1，不到 AA。
   参数怎么定的：**不能照抄 .36，要照抄「效果」**。两张照片的顶部亮度差了 1.7 倍——
   反解遮罩前后的实测值，艾草页那张顶部原图约 149，四页分别是 210／182／223／253
   （联系我们页顶部本就是近纯白的天空）。同一条 α .36 落在 253 的照片上只剩 170，
   等于没有；落在 149 的照片上才是艾草页那个 104。
   所以取**目标＝艾草页顶部那一档亮度（约 105）**，逐页反算需要的 α 后取中位，
   定为峰 **α .58**（26% .42、62% .19、84% 归零；形状与 V1.71 那条同比例，
   `.72` 与 `.33` 两个系数照搬，只是密度不同）。
   加深后四页顶部落到 102／90／107／119，与艾草页的 104 同档；
   页头带（0–60px）的暖白字对比从 2.4–3.9 提到 3.0–5.0。
   `height` 不在这里重写，仍由 V1.71 那条的 `100%` 供给。
   **只挂这四页**：`page-hero--deeplight` 只写在这四页的 hero 上；另三条目录页、
   37 个详情页、careers 与 service 页一律走 V1.71 的原值。
   选择器写足三个类，压过 V1.71 那条（两个类）。 */
.page-hero--img.page-hero--deeplight .page-hero-bg::after {
  background: linear-gradient(180deg,
              rgba(23, 26, 29, .58) 0,
              rgba(23, 26, 29, .42) 26%,
              rgba(23, 26, 29, .19) 62%,
              rgba(23, 26, 29, 0) 84%);
}

/* ================================================================
   V2.26 全站字号统一（用户 2026-10-11 01:36：「检查全站的字体看看哪里没有统一的
   直接进行调整。要让人看清，能看到，能看懂…不得删东西，只是让你把字大小不合适的
   进行调整」）
   ================================================================
   审计工具 `_gen/font_audit.mjs`（遍历 48 页，抓每一个「有直接文本的可见元素」的
   computed font-size，输出 /tmp/font_audit.json）。**改前实测 5016 处文字**：
     · 固定 px 档位 **25 种**；小字区挤了 10 档
       （10.5 / 11.5 / 12 / 12.5 / 13 / 13.5 / 14 / 14.5 / 15 / 15.5）——
       相邻只差 0.5px 的档位肉眼分不出来，是逐轮微调攒下来的；
     · **`h3` 一个元素在站内有 11 种字号**（15 / 15.5 / 17 / 18 / 19 / 20 / 21 / 23 / 38），
       同一个语义元素这么多档，是这次最该收的；
     · 全站最小的字 **10.5px**（目录页与 FAQ 左栏的 `ON THIS PAGE`，4 处），
       其次 **11.5px 共 253 处**（浮动条三个按钮的文字、页脚英文小标、二维码占位…）。
   本次调整（**只改字号，一处内容没动，HTML 零变化**）：
     一、小字下限抬到 **12.5px**，并收敛成 6 档：
         10.5 / 11.5 / 12 → **12.5**；13 → **13.5**；14 → **14.5**；16.5 → **16**。
         15（按钮与交互）与 15.5（导航与卡片标题）各自语义清楚，保留。
     二、`h3` 从 11 种收到 **3 档**：**17**（并列小标题）／**20**（卡片标题）／**23**（模块标题）。
         `.feature h3` `.step h3` `.flow li h3` `.ct-card h3` `.job-head h3` → 20；
         `.adv-item h3` `.pdv-scene h3` → 17；
           （原列的 `.svc-card h3` 已随客服样式迁至 `css/service.css`）
         `.pm-body h3` 38 → **32**（它本来就是「段标题」，与详情页段标题同档）。
     三、`.cta-strong h2` 42 → **40**（与全局 h2 上限一致）。
         （原「`.svc-phone` 19 → **21**，与联系我们页的电话同档」一项，已随客服样式迁至 `css/service.css`）。
     **媒体查询里的降档一律不动**——窄屏标题变小是响应式设计，不是碎片。
   改后：基础规则档位 25 → **12 种**（12.5 / 13.5 / 14.5 / 15 / 15.5 / 16 / 17 / 21 / 22 / 24 / 32 / 40）；
   连同媒体查询内的降档合计 18 种。验收走 `font_audit.mjs` 复核分布 +
   `render_check.mjs <绝对路径> all` 复核溢出（**注意：根目录必须传绝对路径**，
   传 `.` 会拼出无效的 `file://about/index.html`、Chrome 落到错误页而静默「全通过」）。 */

/* ================================================================
   V2.27 招贤纳士整页重排（用户 2026-10-11 01:48 六条要求）
   ================================================================
   用户原话里有三条互相拉扯：「岗位尽可能的全面」／「页面一定要简洁，高级感、
   简约感并存」／「目前这个页面排版设计看起来很累」。做法是**用结构换密度**：
     · 岗位从「17 张带边框的大卡 + 每张两列十来条 bullet」改成**细线分隔＋默认折叠**
       的名单式——折叠态只露编号、岗位名与一行概括，扫一眼能看全 17 个岗位；
       要看细节点开，职责与要求仍是两列、一条不删。
     · 左栏两级吸顶菜单（分类 → 岗位），点岗位名直接跳到该条并展开（js/main.js 第 10 段）。
     · 去掉顶部照片 banner，页头区改纯白「左标题右简介 + 一行数字」。**去掉 banner
       的连带结果是页头从「透明压照片」回到墨黑实底**（`body:has(.page-hero--img)` 那条
       不再命中），这正是纯白页面上该有的样子。
     · 全页纯白（`main.pg-white`），与另外几个独立页一致。
   外观沿用 V2.16/V2.17 侧栏那套语言：纯白、无圆角无阴影、细线分层、
   **铜橙 `#B95C32` 只用于编号与极少量点缀**。
   数据侧：`JOBS[i]['status']` 为 `open` 的进「在招岗位」、`filled` 的进「已招到」，
   改一个字段即可迁移，页面无需任何其它改动。 */
main.pg-white { --cr-orange: #B95C32; }

/* ---------- 1｜页头区：纯白，无 banner ---------- */
.cr-head { padding: calc(var(--header-h) + 78px) 0 0; }
.cr-head-grid {
  display: grid; grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr);
  gap: 28px 72px; align-items: end; padding-bottom: 46px;
}
.cr-head h1 { margin-top: 16px; }
.cr-head-x p { font-size: 15px; line-height: 1.95; color: var(--ink-2); }
.cr-head-x p + p { margin-top: 12px; }
.cr-stats {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px;
  padding-top: 30px; border-top: 1px solid var(--line);
}
.cr-stat-num {
  font-size: clamp(26px, 2.6vw, 34px); font-weight: 700; line-height: 1.05;
  letter-spacing: -.02em; color: var(--ink); font-variant-numeric: tabular-nums;
}
.cr-stat-lbl { margin-top: 8px; font-size: 14px; color: var(--ink-3); }

/* ---------- 2｜主体：左菜单 + 岗位名单 ---------- */
.cr-jobs { padding: 76px 0 96px; }
.cr-layout { display: grid; grid-template-columns: 240px minmax(0, 1fr); gap: 56px; align-items: start; }

.cr-nav { position: sticky; top: calc(var(--header-h) + 28px); }
.cr-nav-en {
  font-size: 12.5px; font-weight: 500; letter-spacing: .18em;
  text-transform: uppercase; color: var(--ink-3);
}
.cr-nav-t {
  margin-top: 6px; padding-bottom: 14px; border-bottom: 1px solid var(--line);
  font-size: 20px; font-weight: 600; color: var(--ink); letter-spacing: -.01em;
}
.cr-nav-t--sub { margin-top: 26px; }
.cr-nav-list { margin-top: 16px; }
.cr-nav-list > li + li { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--line); }
.cr-nav-cat > a {
  display: flex; align-items: baseline; gap: 10px;
  font-size: 15.5px; font-weight: 600; color: var(--ink);
  transition: color .2s var(--ease);
}
.cr-nav-cat > a:hover { color: var(--cr-orange); }
.cr-nav-no {
  flex: none; width: 20px; font-size: 12.5px; font-weight: 700;
  color: var(--cr-orange); font-variant-numeric: tabular-nums;
}
.cr-nav-ct { margin-left: auto; font-size: 12.5px; font-weight: 500; color: var(--ink-3); }
.cr-nav-sub { margin-top: 9px; padding-left: 20px; }
.cr-nav-sub a {
  display: block; padding: 4px 0;
  font-size: 13.5px; line-height: 1.55; color: var(--ink-3);
  transition: color .2s var(--ease);
}
.cr-nav-sub a:hover { color: var(--ink); }
.cr-nav-empty { margin-top: 12px; font-size: 13.5px; color: var(--ink-3); }

/* 右栏引导句 */
.cr-intro { max-width: 700px; }
.cr-intro h2 { margin-top: 14px; }
.cr-intro-x { margin-top: 14px; font-size: 15.5px; line-height: 1.9; color: var(--ink-2); }
.cr-intro-x a, .cr-apply-x a { color: var(--accent); text-decoration: underline; text-underline-offset: 3px; }

/* 分类块 */
.cr-group { margin-top: 58px; }
.cr-group-hd {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 14px;
  padding-bottom: 16px; border-bottom: 1px solid var(--ink);
}
.cr-group-t { font-size: 22px; font-weight: 600; color: var(--ink); letter-spacing: -.01em; }
.cr-group-n { font-size: 13.5px; color: var(--ink-3); }
.cr-group-x { flex-basis: 100%; margin-top: 8px; font-size: 14px; line-height: 1.7; color: var(--ink-3); }

/* 岗位条：折叠态一行，展开看职责与要求 */
.cr-job { border-bottom: 1px solid var(--line); }
.cr-job-sum {
  display: grid; grid-template-columns: 38px minmax(0, 1fr) auto 16px;
  align-items: center; gap: 6px 22px;
  padding: 22px 2px; cursor: pointer; list-style: none;
}
.cr-job-sum::-webkit-details-marker { display: none; }
.cr-job-no {
  align-self: start; padding-top: 4px;
  font-size: 13px; font-weight: 700; letter-spacing: .04em;
  color: var(--ink-3); font-variant-numeric: tabular-nums;
}
.cr-job-main { min-width: 0; }
.cr-job-nm {
  display: block; font-size: 18px; font-weight: 600; line-height: 1.4;
  color: var(--ink); transition: color .2s var(--ease);
}
.cr-job-x { display: block; margin-top: 7px; font-size: 14px; line-height: 1.7; color: var(--ink-3); }
.cr-job-meta { font-size: 13.5px; color: var(--ink-3); white-space: nowrap; }
.cr-job-tg { position: relative; width: 14px; height: 14px; justify-self: end; }
.cr-job-tg::before, .cr-job-tg::after {
  content: ""; position: absolute; left: 50%; top: 50%; background: var(--ink-3);
  transition: transform .25s var(--ease), background .25s var(--ease);
}
.cr-job-tg::before { width: 14px; height: 1.5px; border-radius: 2px; transform: translate(-50%, -50%); }
.cr-job-tg::after { width: 1.5px; height: 14px; border-radius: 2px; transform: translate(-50%, -50%); }
.cr-job[open] {
  /* 展开态给一个极浅的底，让「当前看的是哪一条」一目了然，也把长内容与上下条分开 */
  background: linear-gradient(180deg, rgba(23, 26, 29, .022), rgba(23, 26, 29, 0));
}
.cr-job[open] .cr-job-tg::after { transform: translate(-50%, -50%) scaleY(0); }
.cr-job-sum:hover .cr-job-nm { color: var(--cr-orange); }
.cr-job-sum:hover .cr-job-tg::before, .cr-job-sum:hover .cr-job-tg::after { background: var(--cr-orange); }
.cr-job-sum:focus-visible { outline: 2px solid var(--cr-orange); outline-offset: 2px; }

.cr-job-body {
  display: grid; grid-template-columns: 1fr 1fr; gap: 22px 52px;
  padding: 2px 2px 32px 60px;
}
.cr-job-col h3, .cr-job-col h4 {
  margin-bottom: 13px;
  font-size: 13px; line-height: 1.5; font-weight: 600; letter-spacing: .06em; color: var(--cr-orange);
}
.cr-job-col ul { display: flex; flex-direction: column; gap: 9px; }
.cr-job-col li {
  position: relative; padding-left: 15px;
  font-size: 14.5px; line-height: 1.78; color: var(--ink-2);
}
.cr-job-col li::before {
  content: ""; position: absolute; left: 0; top: .7em;
  width: 4px; height: 4px; border-radius: 50%; background: var(--metal);
}

/* 投递 */
.cr-apply {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 24px 40px; margin-top: 66px; padding-top: 40px; border-top: 1px solid var(--ink);
}
.cr-apply h2 { margin-top: 12px; }
.cr-apply-x { margin-top: 14px; max-width: 54ch; font-size: 15px; line-height: 1.9; color: var(--ink-2); }

/* ---------- 3｜窄档 ---------- */
@media (max-width: 1080px) {
  .cr-head-grid { grid-template-columns: 1fr; gap: 22px; align-items: start; padding-bottom: 34px; }
  .cr-stats { grid-template-columns: repeat(2, 1fr); gap: 20px 24px; }
  .cr-layout { grid-template-columns: 1fr; gap: 26px; }
  /* 左菜单在窄档收成一行分类 chips：二级岗位与标题都藏起来，
     否则 17 个岗位名会把页面顶部撑得很长。 */
  .cr-nav { position: static; }
  .cr-nav-en, .cr-nav-t, .cr-nav-empty { display: none; }
  .cr-nav-list { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 0; }
  .cr-nav-list > li + li { margin: 0; padding: 0; border: 0; }
  .cr-nav-cat > a {
    gap: 0; padding: 8px 15px; border: 1px solid var(--line);
    border-radius: 999px; font-size: 14px; font-weight: 500;
  }
  .cr-nav-no, .cr-nav-ct, .cr-nav-sub { display: none; }
  .cr-jobs { padding: 40px 0 72px; }
}
@media (max-width: 760px) {
  .cr-head { padding-top: calc(var(--header-h) + 46px); }
  .cr-job-sum { grid-template-columns: 30px minmax(0, 1fr) 16px; gap: 4px 14px; padding: 20px 2px; }
  .cr-job-nm { font-size: 16.5px; }
  .cr-job-meta { grid-column: 2 / 3; }
  .cr-job-body { grid-template-columns: 1fr; gap: 26px; padding: 2px 2px 28px 30px; }
  .cr-apply { margin-top: 48px; padding-top: 30px; }
}

/* ---------- V2.27 续｜「为什么加入」加回、空态收紧、间距 ----------
   用户说「以我现在的结构」，所以原来那句「为什么加入」保留下来，
   只是从四张带边框的卡收成**一行四项**（编号 + 标题 + 一句），
   与岗位区共用同一套细线语言，不额外占视觉分量。 */
.cr-why { padding: 46px 0 0; }
.cr-why-grid {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 30px;
  margin-top: 26px; padding-top: 28px; border-top: 1px solid var(--line);
}
.cr-why-no {
  display: block; margin-bottom: 12px;
  font-size: 12.5px; font-weight: 700; letter-spacing: .12em; color: var(--cr-orange);
}
.cr-why-item h3 { font-size: 17px; font-weight: 600; color: var(--ink); }
.cr-why-item p { margin-top: 10px; font-size: 14.5px; line-height: 1.8; color: var(--ink-2); }

/* 「已招到」空态：不画那条分类下划线，标题与说明并成一行，避免在无内容时
   还留一块带线的空档（与下方「投递方式」的墨线叠在一起会显得多余）。 */
.cr-group--empty { margin-top: 42px; }
.cr-group--empty .cr-group-hd { border-bottom: 0; padding-bottom: 0; }
.cr-group--empty .cr-group-x { flex-basis: auto; margin-top: 0; }

/* 「为什么加入」插在页头与岗位区之间，重排这两段的上下间距 */
.cr-jobs { padding-top: 62px; }
@media (max-width: 1080px) {
  .cr-why-grid { grid-template-columns: 1fr 1fr; gap: 24px; }
  .cr-jobs { padding-top: 36px; }
}
@media (max-width: 760px) {
  .cr-why-grid { grid-template-columns: 1fr; gap: 0; }
  .cr-why-item { padding: 18px 0; border-bottom: 1px solid var(--line); }
  .cr-why-item:last-child { padding-bottom: 0; border-bottom: 0; }
  .cr-why-item:first-child { padding-top: 0; }
}

/* ================================================================
   V2.28 联系我们：按「转化入口」重做（用户 2026-10-11 01:58）
   ================================================================
   上一版的三条「可点走」的联络项被做成了细线清单里的三行——字与正文差不多大，
   看不出是行动项，电话（转化最快的那条）还和最不快的官网平权。这一版的层级是
   **通道优先、信息其后**：
     · `.ct-channels`＝三张等宽通道卡（电话／邮件／企业微信），网格等高；
     · `.ct-ch`＝卡本体：1px 细线 + 卡片圆角，**号值 24px 大字**；
       电话与邮件两张是 `<a>`，**整卡可点**，hover 抬升 2px 并把描边转墨黑——
       鼠标移到任何位置都知道「这一整块可以点」；
     · `.ct-ch-x`＝「什么情况用这条通道」的一句说明，动词化，降低沟通门槛；
     · 企业微信那张不可点，宽度给二维码，同宽同高，与另两张并排不塌。
   `.ct-reg--foot`：公司全称／经营地址／官网收成结尾小字，上方一条细线与正文分开——
   它们原先和电话、邮箱同权重，是这页最该改的层级问题。
   数据侧：电话走 `sitecore.PHONE`／`PHONE_TEL`（与页脚同源），邮箱字面写在函数里。 */
.ct-channels { --ct-orange: #B95C32; display: grid; grid-template-columns: repeat(3, 1fr); gap: 26px; }
.ct-ch {
  display: flex; flex-direction: column;
  padding: 32px 30px 30px;
  border: 1px solid var(--line); border-radius: var(--radius-card);
  background: var(--surface); color: var(--ink);
  transition: border-color .22s var(--ease), transform .22s var(--ease), box-shadow .22s var(--ease);
}
a.ct-ch:hover, a.ct-ch:focus-visible {
  border-color: var(--ink); transform: translateY(-2px);
  box-shadow: 0 22px 44px -32px rgba(23, 26, 29, .6);
}
.ct-ch-no { font-size: 12.5px; font-weight: 700; letter-spacing: .14em; color: var(--ct-orange); }
.ct-ch-lbl { margin-top: 14px; font-size: 13.5px; letter-spacing: .08em; color: var(--ink-3); }
.ct-ch-val {
  margin-top: 8px; font-size: 24px; font-weight: 600; line-height: 1.28;
  letter-spacing: -.014em; color: var(--ink);
  font-variant-numeric: tabular-nums; word-break: break-all;
}
.ct-ch-x { margin-top: auto; padding-top: 16px; font-size: 13.5px; line-height: 1.8; color: var(--ink-3); }
.ct-ch--qr .ph-qr { margin: 18px 0 0; width: 150px; height: 150px; }
.ct-biz-t { display: block; margin-top: 10px; font-weight: 600; color: var(--ink); }
.ct-biz-steps { margin-top: 46px; }
.ct-reg--foot { margin-top: 52px; padding-top: 28px; border-top: 1px solid var(--line); }
.ct-reg-a { color: var(--accent); text-decoration: underline; text-underline-offset: 3px; }
.ct-reg-note { display: block; margin-top: 5px; font-size: 13px; font-style: normal; color: var(--ink-3); }

@media (max-width: 1080px) {
  .ct-channels { gap: 18px; }
  .ct-ch { padding: 26px 22px 24px; }
  .ct-ch-val { font-size: 20px; }
  .ct-ch--qr .ph-qr { width: 132px; height: 132px; }
}
@media (max-width: 760px) {
  .ct-channels { grid-template-columns: 1fr; gap: 14px; }
  .ct-ch--qr .ph-qr { width: 150px; height: 150px; }
  .ct-biz-steps { margin-top: 32px; }
  .ct-reg--foot { margin-top: 36px; padding-top: 22px; }
}


/* ================================================================
   V2.31
   ================================================================ */

/* ---------- 三条目录页的首屏改成「原图按比例整幅显示」 ----------
   用户 2026-10-11 21:12 圈着石墨烯发热用品页的 banner 问：「为什么我 banner 的大背景图
   感觉都被你裁了一部分，显得视角更近了。我希望是原图正好在 banner 中展示出来」。
   原因是高度与图的比例对不上：`--banner-h` 由视口高度定（clamp(560px, 56vh, 600px)），
   而头图是 1920×640＝3:1。1440 宽的带子要 480 高才与图严丝合缝，560 高时
   `cover` 只能把图放大到 0.875 倍、左右各裁掉 120px；1080 宽下更狠，每侧 300px。
   视角就是这样变近的。
   改法：**桌面上让带子高度跟着图的比例走**——3:1 的图＝宽度的三分之一，
   所以 `--banner-h` 取 `33.334vw`。1440 → 480、1920 → 640，两条线都不再裁。
   下限 400 是 1201 视口下的落点（＝那张图需要的 400 高，同时是文字块的下限；
   真放不下时 `min-height` 会被内容撑开，多出的几像素由 `cover` 吃掉，不影响排布）。
   上限 640＝1920 视口的完整高度，更宽的屏维持这一高度。
   **只改桌面这一档**：≤1200 仍是 clamp(560px, 56vh, 600px)——窄屏要完整显示这张图
   只需 360 高，装不下文字块，那里仍以文字为先。
   **改这条要同步改 `_gen/pick_textcolor.py` 的 `BAND_LINE_H` / `BAND_LINE`**，
   那两个值是按首屏几何写死的。 */
@media (min-width: 1201px) {
  .page-hero--line { --banner-h: clamp(400px, 33.334vw, 640px); }
}

/* ---------- V2.32：四个独立页的首屏高度与三条目录页**拉平** ----------
   用户 2026-10-11 22:37 把上一版否掉了：「这四个 Banner 图不是让你默认打开的时候
   显示一屏幕，是让你参照石墨烯采暖那个页面的 Banner 图的高度，然后去设定这四个页面的
   Banner 高度。就是我想统一懂吗？」
   —— 上一版我按他 22:06 那句「我要看到我的全图」把高度改成了图自己的比例
   （`56.22vw`，1440 视口＝809，差不多一屏），而他真正要的是**与目录页同高**。
   这两件事本来就不可兼得：这四页的头图是 1672×940＝16:9，目录页那三张是 1920×640＝3:1，
   要在同一个高度里都完整显示是不可能的。**以「统一」为准**——四页与目录页共用同一条
   `clamp(400px, 33.334vw, 640px)`（1440 → 480、1920 → 640），
   代价是这四张 16:9 的图在 `cover` 下纵向裁掉约 40%（与 V2.31 之前一样）。
   ≤1200 档两边的原值本来就不同（目录页 560 起、四页 520 起），保持不动。 */
@media (min-width: 1201px) {
  .page-hero--compact { --banner-h: clamp(400px, 33.334vw, 640px); }
}

/* ---------- 联系我们页（V2.32，按用户给的《联系我们页面改造规范》重做） ----------
   规范给的方向是「高级、克制、清晰、平和」，并点了上一版三处语气问题
   （逐条见 `_gen/build_p2.py` 的 `build_contact` 注释）。样式上有四条硬要求：
     ① 三个联系入口**白底、一条细线、充足留白**——不铺底色、不加阴影、不做大圆角，
        `hover` 只允许换文字色与箭头（规范 4.2 / 9.4）；
     ② 视觉层级靠**字号、间距、细线**建立，不靠卡片堆叠（规范 9.3）；
     ③ 三列同基线同一间距，公司信息做成一条细线一张表（规范 4.2 / 6.3）；
     ④ 全页只留一个橙色实心按钮（规范 10.4）——就是收口那个「联系墨聚芯能」。
   旧的 `.ct-channels` / `.ct-ch` / `.ct-reg` 一组自 V2.32 起没有页面在用，样式留在
   文件里（删掉要连着动别处注释），新页面一律走 `.ct-way*`。 */
.ct-ways { display: grid; grid-template-columns: repeat(3, 1fr); }
#ct-ways { scroll-margin-top: 96px; }
.ct-way { display: block; padding: 8px 44px 8px 0; color: inherit; text-decoration: none; }
.ct-way + .ct-way { padding-left: 44px; border-left: 1px solid var(--line); }
.ct-way-no { display: block; font-size: 12.5px; font-weight: 700; letter-spacing: .16em; color: var(--accent); }
.ct-way-t {
  margin-top: 18px; font-size: 20px; font-weight: 600; line-height: 1.4;
  letter-spacing: -.008em; color: var(--ink); transition: color .18s ease;
}
.ct-way-x { margin-top: 10px; font-size: 14.5px; line-height: 1.85; color: var(--ink-3); }
.ct-way-val {
  display: block; margin-top: 26px; font-size: 17px; font-weight: 600;
  letter-spacing: -.006em; color: var(--ink);
  font-variant-numeric: tabular-nums; word-break: break-all;
}
.ct-way-act {
  display: inline-flex; align-items: center; gap: 6px; margin-top: 14px;
  font-size: 14.5px; color: var(--accent); transition: color .18s ease;
}
.ct-way-arw { font-size: 13.5px; line-height: 1; transition: transform .18s ease; }
/* V2.42：企业微信那张改成**预留二维码位**（用户 2026-10-13：「把二维码区域给我预留出来，
   到时候直接换图」，同时删掉原来那两句状态文案「联系入口正在完善／上线后在这里提供二维码」）。
   **换图不用改代码**：直接覆盖 `images/brand/qr-wecom.png`（正方形，建议 ≥ 430×430）即可。
   1px 实线边框是为了让二维码在白底页面上有边界，换成正式码之后照样合适。 */
.ct-way-qr { margin-top: 24px; }
.ct-way-qr img {
  display: block; width: 150px; height: 150px; object-fit: contain;
  border: 1px solid var(--line); border-radius: var(--radius-md); background: var(--surface);
}
a.ct-way:hover .ct-way-t { color: var(--accent); }
a.ct-way:hover .ct-way-arw { transform: translate(2px, -2px); }
a.ct-way:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
/* 企业微信那张：活码还没从企业微信后台导出，按规范 10.3 **不做成可点、也不放占位二维码**，
   只写状态——「不要让用户点击后没有反应」。 */
.ct-way--idle .ct-way-val,
.ct-way--idle .ct-way-act { font-weight: 500; color: var(--ink-3); }
.ct-biz-h { margin-top: 14px; }
.ct-biz-lead { margin-top: 20px; font-size: 17px; line-height: 1.85; color: var(--ink-2); }
.ct-biz-tip { margin-top: 10px; font-size: 15px; line-height: 1.85; color: var(--ink-3); }
.ct-biz-steps { margin-top: 44px; }
.ct-biz-note {
  margin-top: 40px; padding-top: 26px; border-top: 1px solid var(--line);
  font-size: 14.5px; line-height: 1.85; color: var(--ink-3);
}
/* V2.33：公司信息块补一个安静的小标签。原先它没有标题、上下都是细线，夹在
   「商务对接」与收口之间读起来像凭空插进来的一段（用户圈着问「是不是很突兀」）。
   标签用中性灰、13.5px、不加橙色——信息要留，但不能与三个联系入口抢注意力。 */
.ct-reg-lbl { font-size: 13.5px; letter-spacing: .06em; color: var(--ink-3); }
/* V2.38：公司信息由三行表换成地图（用户 2026-10-13）。两条要点：
   ① `.ct-map` 必须有确定高度——地图容器高度为 auto 时画布算不出尺寸，什么也不显示；
   ② V2.43 起改由 **Leaflet ＋ 高德官方瓦片**渲染，**不需要 key**（原「高德 JS API ＋ key
      占位符」那条路 key 没填就是白板）。瓦片来源仍是高德，属合规的国内地图服务。 */
.ct-map-block { margin-top: 16px; padding-top: 24px; border-top: 1px solid var(--line); }
/* ★ **容器必须自建层叠上下文**（`position` ＋ `z-index` ＋ `isolation`）：
   Leaflet 内部的层级是 `.leaflet-map-pane { z-index: 400 }`、
   `.leaflet-control-*` 那一层 `z-index: 800`、`.leaflet-top/.leaflet-bottom { z-index: 1000 }`。
   容器只写 `position: relative`（`z-index: auto`）时**不构成层叠上下文**，这些值会跑到根层叠
   上下文里直接参与排序，于是**地图会盖住 `position: fixed; z-index: 90` 的页头**——
   用户 2026-10-13 报的「地图滚动的时候会超出去」就是这个：往下滚到地图压到固定导航时，
   图块、缩放控件和气泡会画在导航上面。
   加上 `z-index: 0` ＋ `isolation: isolate` 后，Leaflet 的 400/800/1000 全部被关在容器内，
   地图整体按容器自身参与排序（0）——页头 90、吸底条 85、浮动条 80 都在它之上。 */
.ct-map {
  width: 100%; height: 380px; overflow: hidden;
  position: relative; z-index: 0; isolation: isolate;
  border: 1px solid var(--line); border-radius: var(--radius-md); background: var(--bg-soft);
}
.ct-map-meta { margin-top: 18px; }
/* 地图容器的兜底文字：地图画出来之后由脚本移除；瓦片加载不出来（或脚本被拦）时，
   这里至少显示公司名与地址，不让那一块整个空着。 */
.ct-map-fb { padding: 22px 24px; font-size: 13.5px; line-height: 1.8; color: var(--ink-2); }
.ct-map-fb b { display: block; font-size: 15px; color: var(--ink); }
.ct-map-fb span { display: block; margin-top: 4px; }
.ct-map-name { font-size: 15px; font-weight: 600; color: var(--ink); }
.ct-map-addr { margin-top: 6px; font-size: 13.5px; line-height: 1.9; color: var(--ink-2); }
.ct-map-act { margin-top: 14px; display: flex; flex-wrap: wrap; gap: 20px; align-items: center; font-size: 13.5px; }
.ct-map-nav { color: var(--accent-deep); text-decoration: underline; text-underline-offset: 3px; }
.ct-map-nav:hover { color: var(--orange); }
.ct-map-arw { margin-left: 3px; font-size: .9em; }
.ct-map-site { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }
.ct-map-site:hover { color: var(--accent); }
/* Leaflet ＋ 高德瓦片（V2.43）。地图是第三方库画的，这几条只做三件事：
   ① 图钉去掉 Leaflet 给 divIcon 默认的方块底与边框；② 让字体继承站内而非 12px 的库默认值；
   ③ 气泡、右下角来源标注收成站内观感（圆角、字色、投影都走既有令牌）。 */
.ct-map-pin { background: transparent; border: none; }
.ct-map .leaflet-container { font: inherit; background: var(--bg-soft); }
.ct-map .leaflet-popup-content { margin: 12px 16px; font-size: 13px; line-height: 1.75; color: var(--ink-2); }
.ct-map .leaflet-popup-content strong { display: block; margin-bottom: 3px; font-size: 14px; color: var(--ink); }
.ct-map .leaflet-popup-content-wrapper { border-radius: var(--radius-md); box-shadow: 0 6px 26px -12px rgba(23, 26, 29, .45); }
.ct-map .leaflet-popup-tip { box-shadow: none; }
.ct-map .leaflet-control-attribution { font-size: 11px; background: rgba(255, 255, 255, .72); color: var(--ink-3); }
.ct-map .leaflet-control-attribution a { color: var(--ink-2); }
/* 旧类保留：`.ct-map-label` 与 `.ct-map-iw` 是高德 JS API 那版（Marker 标签、InfoWindow
   内容）用的，V2.43 换 Leaflet 后页面不再产生这两个类，留着以便回退。 */
.ct-map-label {
  display: inline-block; padding: 3px 9px; border-radius: 4px;
  background: var(--surface); border: 1px solid var(--line);
  font-size: 12.5px; font-weight: 600; color: var(--ink); white-space: nowrap;
  box-shadow: 0 1px 4px rgba(23, 26, 29, .08);
}
.ct-map-iw { display: flex; flex-direction: column; gap: 4px; max-width: 260px; font-size: 13px; line-height: 1.7; color: var(--ink-2); }
.ct-map-iw b { font-size: 14px; color: var(--ink); }
.ct-info { margin-top: 16px; border-top: 1px solid var(--line); }
.ct-info > div {
  display: grid; grid-template-columns: 180px minmax(0, 1fr); gap: 28px;
  padding: 20px 0; border-bottom: 1px solid var(--line);
}
.ct-info dt { font-size: 13.5px; line-height: 1.9; color: var(--ink-3); }
.ct-info dd { font-size: 13.5px; line-height: 1.9; color: var(--ink-2); }
.ct-info dd a { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }
.ct-info dd a:hover { color: var(--accent); }
.ct-info dd em { display: block; margin-top: 4px; font-size: 13px; font-style: normal; color: var(--ink-3); }
.ct-close {
  display: flex; align-items: center; justify-content: space-between;
  gap: 48px 56px; flex-wrap: wrap;
  padding-top: 52px; border-top: 1px solid var(--line);
}
.ct-close-h { font-size: 26px; font-weight: 600; line-height: 1.4; letter-spacing: -.012em; }
.ct-close-x { margin-top: 12px; font-size: 15px; line-height: 1.85; color: var(--ink-2); }
.ct-close-act { display: flex; align-items: center; gap: 24px; flex: none; }
.ct-close-alt { font-size: 15px; color: var(--ink-2); text-decoration: underline; text-underline-offset: 4px; }
.ct-close-alt:hover { color: var(--ink); }
@media (max-width: 1080px) {
  .ct-ways { grid-template-columns: 1fr; }
  .ct-way { padding: 0 0 34px; }
  .ct-way + .ct-way { padding: 34px 0 0; border-left: 0; border-top: 1px solid var(--line); }
  .ct-info > div { grid-template-columns: 140px minmax(0, 1fr); gap: 20px; }
  .ct-close { gap: 28px; }
}
@media (max-width: 760px) {
  .ct-way-t { font-size: 18px; }
  .ct-way-val { margin-top: 20px; }
  .ct-info > div { grid-template-columns: 1fr; gap: 6px; padding: 18px 0; }
  .ct-biz-steps { margin-top: 32px; }
  .ct-biz-note { margin-top: 30px; padding-top: 22px; }
  .ct-close { padding-top: 36px; }
  .ct-close-h { font-size: 22px; }
  .ct-close-act { width: 100%; }
  .ct-close-act .btn { flex: 1; justify-content: center; }
}

/* ---------- 合作模式页：合作方向 ＋ 材料与产品（V2.33） ----------
   用户给的《合作模式页配图方案》两句话定了这两段的形：
     · 合作方向——「不要给五种合作模式各配一张普通的商务场景图，也不要每个模块都塞一张图。
       这样很容易又变成传统企业官网的图文介绍页」「使用编号、细分隔线和清晰排版区分五项」；
     · 材料与产品——「这一部分才是配图的主角」，1 张横向大图 ＋ 3 张产品线小图。
   所以合作方向这一段**整段没有图**，靠两列网格、每项一条上细线与留白分开；
   关键词不做成带边框的标签（用户 2026-10-11 00:59 明确「这种的黑框也不要了」），
   改用「·」串联的灰字。 */
.ct-modes { list-style: none; padding: 0; margin: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 72px; }
/* 每项做成列向 flex、关键词组 `margin-top: auto` 贴底——同一行两项的说明句行数不同时
   （「渠道合作」两行、「区域代理」一行），标签也不会一高一低。 */
.ct-mode { display: flex; flex-direction: column; padding: 34px 0; border-top: 1px solid var(--line); }
.ct-mode-meta { display: flex; align-items: baseline; gap: 12px; }
.ct-mode-no { font-size: 12.5px; font-weight: 700; letter-spacing: .16em; color: var(--accent); }
.ct-mode-en { font-size: 12.5px; letter-spacing: .16em; color: var(--ink-3); }
.ct-mode-t {
  margin-top: 14px; font-size: 21px; font-weight: 600; line-height: 1.4;
  letter-spacing: -.01em; color: var(--ink);
}
.ct-mode-d { margin-top: 12px; font-size: 15px; line-height: 1.85; color: var(--ink-2); }
.ct-mode-tags { margin-top: auto; padding-top: 16px; display: flex; flex-wrap: wrap; }
.ct-mode-tags span { font-size: 13.5px; color: var(--ink-3); }
.ct-mode-tags span + span::before { content: "·"; margin: 0 10px; color: var(--line-strong); }
.ct-mp { margin: 10px 0 0; }
.ct-mp img { display: block; width: 100%; height: auto; border-radius: 8px; }
/* `.ct-lines*`（三条产品线小图）与 `.ct-line*`：**V2.35 起没有页面在用**——
   合作模式页那三张小图按用户 2026-10-12 09:42「三张小图删掉」删了（见
   `build_p2.py` 该节注释）。规则与那三张图都留在原处，随时可回退，
   与 `.pm*`／`mode-0N.jpg` 的处理一致。 */
.ct-lines { margin-top: 28px; display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; }
.ct-line { margin: 0; }
.ct-line img {
  display: block; width: 100%; height: auto;
  aspect-ratio: 4 / 3; object-fit: cover; border-radius: 6px;
}
.ct-line-cap { margin-top: 16px; }
.ct-line-t { font-size: 17px; font-weight: 600; color: var(--ink); }
.ct-line-x { margin-top: 6px; font-size: 14px; color: var(--ink-3); }
@media (max-width: 1080px) {
  .ct-modes { grid-template-columns: 1fr; gap: 0; }
  .ct-lines { gap: 20px; }
}
@media (max-width: 760px) {
  .ct-mode { padding: 28px 0; }
  .ct-mode-t { font-size: 19px; }
  .ct-lines { grid-template-columns: 1fr; gap: 26px; }
}

/* ---------- 常见问题：单栏 QA ----------
   V2.31 去掉了左侧目录、改成单栏；**V2.33 按用户给的《常见问题页面高端极简改造规范》
   再调一遍尺寸**（2026-10-11 23:08）。规范点名的几条与原来的差距：
     · 「主体内容容器建议最大宽度 1040–1120px」——原先只有 820px，规范还说
       「不要将全部问答限制在……非常狭窄的阅读列里」→ 加宽到 **1080px**；
     · 「分类标题字号建议 24–28px」→ 23 → **26px**；
     · 「不同分类之间留出 64–88px」→ 56 → **76px**；
     · 「每组问答之间留出 26–34px」→ 34 → **30px**；
     · 「小号编号」写进了每一组问答的结构，且「编号不能比问题标题更抢眼」
       → 加回组内编号，13px 中性灰（`--ink-3`），不进结构化数据；
     · 「桌面端图片宽度建议 320–420px，使用自然比例」——原先三张图是**满宽 1080**
       并强制 `aspect-ratio: 3/2` 裁切，现在改成 **420px、`height: auto` 自然比例、居中**，
       圆角 6px。规范同时要求「不让图片连续堆叠」——这三张本来就穿插在组内的不同问题之后，
       位置没动。
   不用卡片、不铺底色、不加图标与箭头——规范第 5.1 节把这几条列进了禁止项，与 V2.31 一致。 */
.faq-page { max-width: 1080px; margin: 0 auto; }
.faq-sec { padding: 76px 0; }
.faq-sec:first-child { padding-top: 0; }
.faq-sec + .faq-sec { border-top: 1px solid var(--line); }
.faq-h {
  margin-top: 12px; font-size: 26px; font-weight: 600; line-height: 1.35;
  letter-spacing: -.014em; color: var(--ink);
}
.faq-list { margin-top: 28px; display: flex; flex-direction: column; gap: 30px; }
.faq-q { font-size: 17px; font-weight: 600; line-height: 1.6; letter-spacing: -.005em; color: var(--ink); }
/* V2.37：问答的标签由纯数字改成 **Q01 / A**；V2.40（用户 2026-10-13「把后面的 01、02
   这种序号全部去掉」）再把序号去掉，只留 **Q / A** 两个字母。两个标签同为 13px 中性灰、
   都给 `min-width: 1em` 占同一格，问题正文与答案正文因此左缘对齐。
   字距 `.04em`——V2.37 从 `.12em` 收下来的，那一档是给**多字符编号**定的，去掉序号后
   再放宽会把单字母与正文拉太开。 */
.faq-no, .faq-a-no {
  display: inline-block; min-width: 1em; margin-right: 14px;
  font-size: 13px; font-weight: 700; letter-spacing: .04em;
  color: var(--ink-3);
}
.faq-a { margin-top: 12px; font-size: 15px; line-height: 1.9; color: var(--ink-2); }
.faq-a a { color: var(--accent); text-decoration: underline; text-underline-offset: 3px; }
/* V2.34：配图由**居中**改成**左对齐**。用户 2026-10-11 23:55：「常见问题这里的配图就在
   这个正中间，感觉很不协调」。不协调的根子是**对齐**——整页的问题、答案都沿同一条左缘排，
   唯独图横在正中间，视觉上像贴上去的一张。改成与提问同左缘之后，它读起来就是「文中的一张插图」。
   **数量仍是 3 张、挑着配**：规范第 7.1 节明说「不要求每个问题都配图」「不要为了追求视觉丰富
   而大量增加图片」，而且站内与问答内容真正对得上的素材就这 3 张（都在「产品方向」一组里，
   各自跟在对应的问题后面）；「合作方式」是条款式问答、「购买与联系」只有两条，
   硬配图会违反规范 7.2「图片必须与所在问答内容有明确关联」。 */
.faq-fig { margin: 8px 0; }
.faq-fig img {
  display: block; width: 420px; max-width: 100%; height: auto;
  border-radius: 6px;
}
@media (max-width: 1080px) {
  .faq-page { max-width: none; }
  .faq-sec { padding: 60px 0; }
}
@media (max-width: 760px) {
  .faq-sec { padding: 44px 0; }
  .faq-list { margin-top: 22px; gap: 26px; }
  .faq-h { font-size: 22px; }
  .faq-q { font-size: 16.5px; }
  .faq-no, .faq-a-no { margin-right: 10px; }
  .faq-a { margin-top: 10px; font-size: 14.5px; }
}
/* V2.34：**常见问题页底部那条 CTA 要对齐到正文列**。用户 23:55：「最底部的……文字跟上面的
   内容好像有点不太对齐，还有别的问题有点太靠左了，然后……联系我们、合作模式这两个按钮
   又靠太右了。这样会不会太累看起来？」
   量出来的原因：正文用的是 `.faq-page` 的 **1080px** 居中（1440 视口下左缘 180），
   而 `.cta-band` 吃的是全站 `.wrap`（`--wrap` 1240 + 两侧 24 内边距，左缘 124）——
   **两边差 56px**，于是标题看着靠左、按钮看着靠右。
   全站别的内容页都是 1240 一脉到底，只有常见问题这一页因为规范要求收成 1080，
   所以这里只给这一页收窄，不动 `.cta-band` 的基础规则。 */
main:has(.faq-page) .cta-band .cta-card { max-width: 1080px; margin: 0 auto; }

/* ---------- 隐私政策：正式文书版式 ----------
   用户 2026-10-11 21:12 给了一份新的《隐私政策》正文（11 章），要求
   「内容更新成这个。排版专业点。背景要纯白色」。
   原先这一页只有四小节、每节一句话，是「官网上放一段说明」那种写法；
   新正文是正式条款，所以版式按条款来：
     · 章标题 20px 加粗 + 底部一条细线——一条章线就能让十一节能一眼扫过去；
     · 节下的小标题（一）（二）16px、上间距 26px，与正文拉开；
     · 编号条目一律 `list-style: none` 后手写 `01` 式的圆点，行高 1.9，
       条与条之间 8px——条款读起来密，靠行高而不是靠空行；
     · 正文 15px／1.9，与站内 `.faq-a` 同档。
   **一个类都不复用站内既有的 `.lead` / `.section`**：那几套是给展示型页面用的，
   行高与间距都比条款松。 */
.pp-page { max-width: 820px; margin: 0 auto; }
.pp-meta {
  padding-bottom: 22px; border-bottom: 1px solid var(--line);
  font-size: 14.5px; line-height: 1.9; color: var(--ink-3);
}
.pp-meta b { font-weight: 600; color: var(--ink-2); }
.pp-lead { margin-top: 26px; font-size: 15px; line-height: 1.95; color: var(--ink-2); }
.pp-note {
  margin-top: 28px; padding: 22px 26px;
  border-left: 2px solid var(--accent); background: var(--bg-soft);
}
.pp-note-t { font-size: 14.5px; font-weight: 600; letter-spacing: .02em; color: var(--ink); }
.pp-note ol { margin-top: 12px; padding-left: 20px; }
.pp-note li { font-size: 14.5px; line-height: 1.85; color: var(--ink-2); }
.pp-note li + li { margin-top: 6px; }
.pp-sec { margin-top: 52px; }
.pp-h {
  padding-bottom: 14px; border-bottom: 1px solid var(--line);
  font-size: 20px; font-weight: 600; line-height: 1.4;
  letter-spacing: -.01em; color: var(--ink);
}
.pp-h3 { margin-top: 28px; font-size: 16px; font-weight: 600; line-height: 1.6; color: var(--ink); }
.pp-page p { margin-top: 12px; font-size: 15px; line-height: 1.9; color: var(--ink-2); }
.pp-page p b, .pp-page li b { font-weight: 600; color: var(--ink); }
.pp-page a { color: var(--accent); text-decoration: underline; text-underline-offset: 3px; }
.pp-ol, .pp-ul { margin-top: 12px; padding-left: 22px; }
.pp-ol { list-style: decimal; }
.pp-ul { list-style: none; padding-left: 0; }
.pp-ol li, .pp-ul li { font-size: 15px; line-height: 1.9; color: var(--ink-2); }
.pp-ol li + li, .pp-ul li + li { margin-top: 8px; }
.pp-ul li { position: relative; padding-left: 20px; }
.pp-ul li::before {
  content: ""; position: absolute; left: 4px; top: .82em;
  width: 5px; height: 5px; border-radius: 50%; background: var(--accent);
}
.pp-ol ol { margin-top: 8px; padding-left: 22px; list-style: lower-alpha; }
.pp-ol ol li { font-size: 14.5px; line-height: 1.85; }
@media (max-width: 760px) {
  .pp-sec { margin-top: 40px; }
  .pp-h { font-size: 18px; padding-bottom: 12px; }
  .pp-note { padding: 18px 20px; }
  .pp-page p, .pp-ol li, .pp-ul li { font-size: 14.5px; }
}
/* V2.31：隐私政策页的首屏是**无图**的 `.page-hero`（底色走 `--bg-soft` 暖白），
   与下面 `pg-white` 的纯白内容区之间会出现一条看得见的分界。用户这一轮的要求里有
   「背景要纯白色」，所以把 `pg-white` 页面里的**无图首屏**一并转白。
   站内只有隐私政策页命中——其余挂 `pg-white` 的页（合作模式／关于我们／常见问题／
   联系我们）首屏都带 `--img`，选不到它们。 */
main.pg-white .page-hero:not(.page-hero--img) { background: var(--surface); }

/* V2.38：联系我们页公司地图的窄档。容器高度必须给死值，否则高德 JS API 不渲染。 */
@media (max-width: 760px) {
  .ct-map { height: 300px; }
  .ct-map-act { gap: 14px; }
}

/* ================================================================
   V2.65（2026-10-14）手机端适配：首屏「图上、文下」＋ 吸底条收口
   ================================================================
   用户同一天两条：
     ①「联系我们、常见问题、关于我们、合作模式、石墨烯艾草暖敷、石墨烯发热用品、
        石墨烯采暖，这些页面手机移动端看的时候，顶部 banner 背景图看不到全图。给做下适配。」
     ②「移动端查看时，这个底部就非常的怪。请优化下。注意：这里原来是回到顶部有个按钮，
        这个放到页面上出现吧。不要在这底部出现了。」

   ---- ① 首屏为什么手机上「看不到全图」，以及为什么只能这么改 ----
   这 7 页的首屏图是**横图**，而手机是**竖屏**，`object-fit: cover` 必然狂裁：
     · 4 个独立页（联系我们／常见问题／关于我们／合作模式）：图 1672×940＝1.78，
       手机容器 390×(clamp(520px,56vh,600px) → 520) ＝ 0.75 —— **横向只剩 42%**；
     · 3 条目录页（采暖／发热用品／艾草）：图 1920×640＝3.0（艾草 2048×644＝3.18），
       容器 390×560 ＝ 0.70 —— **横向只剩 23%**。
   想把「整张图」显示出来，只有两条路：换竖版图（`_gen/` 与出图原料已随归档删除，
   做不到），或者**改版式**。这里取后者：**手机上把首屏拆成「图在上、文字在下」**，
   图按自身比例完整显示（`height: auto`），文字移到图下方、改浅底深字。
   ——这是移动端对横版 banner 的通行处理，也是唯一能真正看到全图的 CSS 做法。
   **只作用在 ≤760px**；桌面档（≥1201 那张 400–640px 的带子）一个像素没动；
   **37 个产品详情页（`.pd-top--img`）不在这次范围内**（用户点名的就是这 7 页）。

   两处必须说明的连带处理：
     · **顶部压暗层（`.page-hero-bg::after`）在手机端关掉**：它服务的是「透明页头压在照片上」，
       而 ≤1200 页头本来就是墨黑／纯白实体层（`body:has(.page-hero--img) .site-header:not(.is-solid)`
       那条只在 ≥1201 生效），手机上它既没有服务对象、又会给图糊一层暗带。
     · **`text-shadow` 光晕一并关掉**：目录页那套贴字光晕是为「墨字压浅照片」做的，
       文字挪到纯色暖白底上之后毫无意义。

   ---- ② 吸底条「非常怪」的根因 ----
   `.dock-top`（回到顶部）原先在吸底条里做第 3 格，默认 `opacity:0; visibility:hidden`
   ——**为了不跳动而保留了占位**，于是那条 `auto auto auto 1fr` 的栅格里永远空着一格，
   手机上看就是「客服 微信 【一块空白】 电话按钮」。这里把它**从条里拿出来**：
   改成相对 `.dock-bar` 绝对定位的**圆形悬浮钮**，浮在吸底条上方右侧（`bottom:100% + 12px`），
   仍复用原来那套「滚动超过 300px 才出现」的显隐（`.dock-bar.is-scrolled .dock-top`，见上文），
   栅格同时收成三列。
   悬浮钮放在 `.dock-bar` **里面**（不动 HTML、48 页零改动）——`.dock-bar` 是 `position: fixed`
   且带 `backdrop-filter`（会自建包含块），所以它的绝对定位子元素**正好以吸底条为参照**。 */

@media (max-width: 760px) {
  /* ---- 1｜首屏改为「图 + 文」两段式 ----
     **页头是 `position: fixed`（不占位）**，原来图满铺含页头是有意的（图从 y=0 起、
     页头压在图上）；现在图不再满铺，必须**把页头那一条让出来**，否则图顶 64px
     会被实底页头盖掉、等于还是看不到全图。`--header-h` 在这一档是 64px。 */
  .page-hero--img {
    display: block; min-height: 0;
    padding: var(--header-h) 0 32px;
    background: var(--bg);
  }
  .page-hero--img .page-hero-bg,
  .page-hero--line.page-hero--bare .page-hero-bg { position: static; inset: auto; }
  .page-hero--img .page-hero-bg img {
    display: block; width: 100%; height: auto;
    object-fit: contain; object-position: center;
  }
  /* 覆盖层全关（压暗层与两层渐隐：文字已不在图上，页头也不压图） */
  .page-hero--img .page-hero-bg::after,
  .page-hero--line.page-hero--bare .page-hero-bg::after,
  .page-hero--img.page-hero--deeplight .page-hero-bg::after,
  .page-hero--img.page-hero--noscrim.page-hero--nomask::before,
  .page-hero--img.page-hero--nomask::before,
  .page-hero--img.page-hero--nomask .page-hero-inner::before { display: none; }

  /* 文字块：贴在图下方，左右内边距仍走 `.wrap`（这里只补上内距） */
  .page-hero--img .page-hero-inner { padding-top: 26px; }
  .page-hero--img .page-hero-inner > * { max-width: none; }

  /* ---- 2｜字色：浅底深字 ---- */
  .page-hero--img .page-hero-inner h1 { color: var(--ink); text-shadow: none; }
  .page-hero--img .page-hero-inner .page-sub { color: var(--ink-2); text-shadow: none; }
  .page-hero--img .page-hero-inner .crumb,
  .page-hero--img .page-hero-inner .crumb a { color: var(--ink-3); text-shadow: none; }
  .page-hero--img .page-hero-inner .en { color: var(--ink-3); text-shadow: none; }
  .page-hero--img .page-hero-inner .eyebrow { color: var(--accent-deep); text-shadow: none; }
  .page-hero--img .page-hero-inner .eyebrow::before { background: var(--accent-deep); }

  /* ---- 3｜吸底条：三格 ＋「回到顶部」改成条上方右侧的圆形悬浮钮 ---- */
  .dock-bar { grid-template-columns: auto auto 1fr; }
  .dock-top {
    position: absolute; right: 14px; bottom: calc(100% + 12px);
    width: 46px; height: 46px; min-width: 0; padding: 0; gap: 0;
    border-radius: 50%;
    background: rgba(255, 255, 255, .94);
    border: 1px solid var(--line);
    box-shadow: 0 6px 18px -8px rgba(23, 26, 29, .45);
    -webkit-backdrop-filter: blur(12px) saturate(1.4);
    backdrop-filter: blur(12px) saturate(1.4);
  }
  .dock-top span { display: none; }
  .dock-top svg { width: 20px; height: 20px; }
}

/* ================================================================
   V2.66（2026-10-14）移动端导航抽屉重做
   ================================================================
   用户：「移动端的导航菜单看着不高级 不奢华 不简洁 不大气 不清楚，优化下。」
   原状（截图）：白面板里一列纯文字——主项 16px、子项 14.5px 都左对齐，
   主项之间没有分隔、当前项没有高亮（`aria-current` 只给了同色墨黑 = 等于没标），
   「产品中心」与它下面三条产品线看不出从属关系。

   本版**只改视觉、HTML 一字未动**（48 页共用同一段导航结构；站点已无生成器，
   改 48 份 HTML 是没必要冒的风险）。六件事：
     ① 面板加宽到 392px、顶部留白按「页头高 + 34px」起排、隐藏滚动条，
        进场曲线换成更缓的 `cubic-bezier`（原 `.3s ease` 收尾略顿）；
     ② 主项之间用 **1px 细线**分层（站点一贯的语言），去掉原来 2px 的紧贴间距；
        「产品中心」那一条**不画下边线**——它下面紧跟三条子项，另起一组；
     ③ 主项 17px/600、内距 17px、字距 .02em；hover 轻微右移 + 转沉橙
        （不做底色块，与站内「橙只做强调」一致）；
     ④ **当前页**：文字转沉橙 + 左侧一条 3px 橙色短条（桌面档那条下划线在抽屉里关掉，
        它是给横向导航用的，竖排里读不出"当前"）；
     ⑤ **子菜单**：左侧一条 1px 竖线 + 缩进 20px，条目降到 15px/400 次级色——
        主项与子项的层级一眼可读，"产品中心"与三条产品线的关系就成立了；
     ⑥ 入场**不做逐项淡入**——列表随抽屉一起滑出、到位即清晰（渐显会有一瞬"蒙层"）。
   **不改**：遮罩层（纯 CSS 做不出"点遮罩关闭"，只能做出一层挡住却仍可点的假遮罩，
   反而更糟；要么连 JS 一起改、要么不做，这次不做）。 */

@media (max-width: 1080px) {
  /* ① 面板 */
  .site-nav {
    width: min(88vw, 392px);
    padding: calc(var(--header-h) + 34px) 26px 34px;
    /* **边界用一条实线划清，不用模糊阴影**（用户 2026-10-14：「不要有糊状感觉」）——
       原来那条 `-28px 0 80px -34px` 的模糊半径 80px，会在左侧原页面上摊出一道灰雾，
       「糊」就是它。改成 1px 实线：抽屉与页面之间一根线，清清楚楚。 */
    border-left: 1px solid var(--line);
    box-shadow: none;
    transition: transform .36s cubic-bezier(.22, .61, .36, 1);
    scrollbar-width: none;
  }
  .site-nav::-webkit-scrollbar { display: none; }

  /* ② 主项细线分层 */
  .nav-list { gap: 0; }
  .nav-list > li { border-bottom: 1px solid var(--line); }
  .nav-list > li:first-child { border-top: 1px solid var(--line); }
  /* 「产品中心」这一条**保留**下边框——它在 li 的最底部（三条子项之后），
     正好把「产品中心组」与下一组分开；标题与子项之间本来就没有线。 */

  /* ③ 主项
     **必须关掉基础规则那层 `text-shadow`**（用户 2026-10-14：「总感觉这些字有模糊的感觉加粗厚」）：
     它是给桌面导航"暖白字压在照片上"做的暗色托底柔光（`0 0 1px α.55` ＋ `0 1px 8px α.50`），
     在抽屉里字是**墨黑压在纯白**上，这层暗影等于给每个字描了一圈淡黑边——笔画发虚、显厚。
     （子项 `.sub-menu a` 不在 `.nav-list > li > a` 的选择器上、没继承到，所以它一直是清楚的，
     这也正是截图里"主项糊、子项清"的原因。）
     **字重 600 → 500**：中文在白底上 17px/600 偏厚，500 更透气；层级改由字号（17／15）＋
     颜色（`--ink`／`--ink-2`）＋粗细（500／400）三者共同承担，不靠单点加粗。
     `-webkit-font-smoothing: antialiased` 让 macOS 走灰度抗锯齿（比次像素更细），
     与"不要加粗厚"同一目的。 */
  .nav-list > li > a {
    padding: 17px 2px; border-radius: 0;
    font-size: 17px; font-weight: 500; letter-spacing: .02em;
    text-shadow: none;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    transition: color .22s var(--ease), padding-left .22s var(--ease);
  }
  /* 抽屉内的子项同理，明确关一次（防以后基础规则改动波及） */
  .sub-menu a { text-shadow: none; }
  .nav-list > li > a:hover { color: var(--accent-deep); padding-left: 6px; }

  /* ④ 当前页 */
  .nav-list > li > a[aria-current="page"] { color: var(--accent-deep); }
  .nav-list > li > a[aria-current="page"]::after { display: none; }
  .nav-list > li > a[aria-current="page"]::before {
    content: ""; position: absolute; left: -15px; top: 50%;
    transform: translateY(-50%); width: 3px; height: 18px;
    background: var(--accent-fill);
  }

  /* ⑤ 子菜单 */
  .sub-menu {
    padding: 2px 0 18px 20px; margin-left: 2px;
    border-left: 1px solid var(--line);
  }
  .sub-menu a {
    display: block; padding: 11px 10px; border-radius: 0;
    font-size: 15px; font-weight: 400; color: var(--ink-2);
    transition: color .2s var(--ease), padding-left .2s var(--ease);
  }
  .sub-menu a:hover { background: transparent; color: var(--accent-deep); padding-left: 14px; }

  /* ⑥ 入场**不做逐项淡入**（2026-10-14 用户「不要有糊状感觉」）：列表随抽屉一起滑出、
     到位即清晰，比"逐项渐显"利落。抽屉自身的 `transform` 滑入保留。 */

  /* 汉堡：展开态浮在白抽屉上——直角、不用圆角底（用户同日「不要圆角线」） */
  .nav-burger { border-radius: 0; transition: background .2s var(--ease); }
  .nav-burger:hover { background: rgba(23, 26, 29, .06); }
}

/* ================================================================
   V2.67（2026-10-15）在线咨询通道（微信客服）
   ================================================================
   用户给了一条微信客服链接 `https://work.weixin.qq.com/kfid/kfc10369fbbfd93512e`，
   要求把这颗入口接到它上面，并「好好想想」各种环境。做法是**弹层里两条路并列**：
   二维码（谁都能扫）+「在微信中打开」（装了微信的一步直达）——
   微信内、手机浏览器、电脑有/没有微信，四种情况都被这一个弹层覆盖，
   所以不需要做 UA 判断、也不直接跳转（直接跳最大的问题是"电脑没装微信"会卡在中间页）。
   二维码是本地生成的（内容＝该链接），不依赖企微后台导出。 */
/* 说明里需要强调的词（「无需添加好友」「人工」）用墨黑加粗，不另起颜色 */
.chn-panel .chn-note b { font-weight: 600; color: var(--ink); }

/* ---------- 浮层文字层级（V2.67n，三颗共用同一套）----------
   用户：「这两个的悬浮框我希望设计的美观 精致 且大小一致 排版一致。重新规划设计下」——
   三颗浮层（电话／在线咨询／企业微信）现在共用**同一套文字排布**：
     主句 `.rail-pop-line`（13.5/600 墨黑）→ 附注 `.rail-pop-line--dim`（12.5 灰，距主句 5px）
     → 可选页脚 `.rail-pop-line--foot`（12.5 灰，上方 1px 细线 + 12px 内距）。
   企业微信那句也按这个结构拆成「扫码添加企业微信」＋「可随时咨询产品、获取样品方案」。
   **选择器一律写成两个类**（`.rail-pop .rail-pop-line`）——单类会被上面 `.rail-pop p`（0,1,1）压掉。 */
.rail-pop .rail-pop-line {
  margin-top: 16px; font-size: 13.5px; font-weight: 600; line-height: 1.45;
  color: var(--ink); text-align: center;
}
.rail-pop .rail-pop-line--dim {
  margin-top: 5px; font-size: 12.5px; font-weight: 400; color: var(--ink-3);
}
.rail-pop .rail-pop-line--foot {
  margin-top: 14px; padding-top: 12px;
  border-top: 1px solid var(--line);
  font-size: 12.5px; font-weight: 400; color: var(--ink-3);
}

/* ---------- V2.67g（2026-10-15 用户给定稿）：只留二维码，去掉按钮 ----------
   用户的定稿：「标题：在线咨询／微信扫码开启咨询／[二维码区域]／手机微信扫一扫进入对话／
   回复【人工】转接专员／服务时间：09:00–21:00／**不要按钮了**」。
   于是删掉「在微信中打开」按钮及其 `.chn-go` 样式——**入口只剩二维码一个**，
   回到最朴素的一种：扫。三行说明里第一行是主（怎么用），后两行是次（转人工、服务时间）。 */
#chn-panel-kf .chn-note { margin-top: 14px; }
#chn-panel-kf .chn-note--dim { margin-top: 5px; color: var(--ink-3); }

/* ---------- V2.67f（历史）：曾试过"不做设备分类"的两入口版 ----------
   六轮走法：v1 并列 → v2 按设备只给一件（被否）→ v3 都留＋灰字 → v4 都留＋点亮当前设备（判错，被否）
   → v5 都留＋「在电脑上／在手机上」同等标签 → **v6 用户一句话点破：「在电脑上：那我也能点击在微信中打开啊；
   在手机上：我也能微信扫码…这狗屁逻辑」——那套"设备→方式"的对应关系是我自己编的，不是事实**：
   电脑装了微信照样能点按钮，手机照样能长按识别二维码。
   **两个入口没有"该选哪个"的问题，任选其一都能进同一个会话。**
   所以：**删掉全部设备标签**，只留两个动作 + 各自的动作说明（「用微信「扫一扫」，或长按识别」／
   「点一下进入微信会话」），由副标题点明"都能进入会话"。 */
#chn-panel-kf .chn-note { margin-top: 12px; }
#chn-panel-kf .chn-note--foot { margin-top: 22px; color: var(--ink-3); }
/* 标签下面紧跟它那件东西：二维码／按钮都不要再吃上边距 */

/* ================================================================
   V2.67h（2026-10-15）「在线咨询」那颗改成鼠标悬浮出二维码框
   ================================================================
   用户：「这个改成鼠标悬浮弹出框。类似：企业微信的悬浮。不过这个框要大点。」
   原来 hover 出的是 `.rail-tip` 文字小气泡（"点击在线咨询"）——现在换成与企业微信那颗同款的
   `.rail-pop` 二维码浮层，但**尺寸更大**（企业微信 216px ／本框 300px，二维码 220px）。
   **V2.67j（2026-10-15 19:36 用户）**：① 浮层里的码由客服码换成**公众号码**
   （`qr-kf.png` → `qr-mp.jpg`，`alt` 同步；三行文字一字未动）；② **这颗不再有点击**——
   用户「我发现这个图标还存在点击事件。改掉吧」，`data-chn="kf"` 已从这颗按钮上摘掉，
   只剩 hover／focus 展开浮层；**浮层展开走的是 class 选择器（`.rail-svc:hover`），不受影响**。
   手机端浮动条本来就不显示（≤760 隐藏），所以这是纯桌面交互；手机端客服入口仍是
   吸底条那颗「客服」按钮（`data-chn="kf"` 保留）与页脚那行「在线客服」链接。
   **★ 注意**：大弹层 `#contact-modal` 里 `#chn-panel-kf` 那张码**仍是客服码**（用户只点名了浮层这张），
   两处现在内容不一致——等用户表态是否一并换。 */
/* 内容重排（用户：「这个排版太丑了」）——原来是三行同字号同颜色居中，读起来是一坨。
   改成**一主两附 + 页脚分层**：
     · 主句「手机微信扫一扫进入对话」13.5px/600 墨黑，与二维码留 14px；
     · 附注「回复【人工】转接专员」12.5px 灰，紧跟 4px；
     · 「服务时间」单列成**底部一条**（上方 1px 细线 + 11px 内距）——站内一贯的细线分层。 */
/* 悬浮展开：与企业微信那颗同一套（`.rail-wx:hover .rail-pop`），这里补上本颗。
   聚焦态用 `:focus-visible`——理由同上面 `.rail-wx` 那条（V2.67k 修「点击后浮层不关」）。 */
.rail-svc:hover .rail-pop { opacity: 1; visibility: visible; transform: translateY(-50%) translateX(0); }
.rail-svc:focus-visible .rail-pop { opacity: 1; visibility: visible; transform: translateY(-50%) translateX(0); }

/* ---------- 浮层右侧的小箭头（两颗浮层通用）----------
   用户 2026-10-15：「浮动窗口没有右箭头的视觉，是出自哪个按钮。企微的也是。」
   ——浮层悬在浮动条左边，没有箭头就看不出它是从哪一颗里出来的。
   画法照站内 `.sub-menu::after`（下拉面板那个指向一级项的三角）：一个 10px 方块
   转 45°、只留朝外的两条边，底色与浮层一致，正好与浮层的右边缘接上。
   **写通用选择器 `.rail-pop::before`**，所以企业微信那颗一并补上。 */
.rail-pop::before {
  /* 尺寸 10 → 14px（V2.67h）：10px 的尖在照片背景上几乎看不见，
     放大后"指向右侧按钮"这件事才读得出来；边线与浮层同色同宽。 */
  content: ""; position: absolute; right: -7px; top: 50%; margin-top: -7px;
  width: 14px; height: 14px;
  background: var(--surface);
  border-right: 1px solid var(--line);
  border-top: 1px solid var(--line);
  transform: rotate(45deg);
}

/* ================================================================
   V2.67j（2026-10-15）电话那颗：hover 显示电话号码
   ================================================================
   用户：「电话那个图标，现在看不到电话号码。这个咋解决。」
   原来 hover 只出 `.rail-tip` 一行小字「点击拨打电话」，**号码本身没露脸**。
   改成与另外两颗同款的浮层，把号码放大到 19px 居中——与企微／在线咨询三颗统一。
   **号码是硬编码在 49 页 HTML 里的**（`sitecore.PHONE` 只作用于生成器，站点已无生成器）——
   改号时要注意：这里 49 页 ＋ `js/main.js` 客服话术那处都要改。 */

.rail-pop .rail-pop-tel {
  /* 用户 2026-10-15：「这个电话号码凸显一点 然后在 大些」——19 → **24px**、600 → **700**。
     **选择器必须写到两个类**：`.rail-pop p`（0,1,1）比单个类（0,1,0）更具体，
     只写 `.rail-pop-tel` 的话字号会被那条 12.5px 盖掉（第一版就是这样，量出来还是 12.5px）。
     `margin-top: 0` 覆盖 `.rail-pop p` 的 14px——那 14px 是给"二维码下方的文字"留的，
     号码是浮层里第一件东西，不需要。 */
  margin-top: 0;
  font-size: 24px; font-weight: 700; letter-spacing: .01em;
  color: var(--ink); text-align: center; font-variant-numeric: tabular-nums;
}

/* 悬浮展开改成**通用规则**（三颗都用），不再一颗一条。
   **V2.67k（2026-10-15 用户：「这俩按钮，点击后在移动走，悬浮关闭就有BUG」）**：
   原 `:focus-within` 就是 bug 源——鼠标点一下按钮即获得焦点 → `:focus-within` 成立 →
   **鼠标移开后浮层仍 `opacity:1/visible` 挂着不消失**（wx／svc／tel 三颗实测全中）。
   改 `:focus-visible`：只在键盘导航时匹配、鼠标点击不匹配（与 `.rail-btn:focus-visible .rail-tip` 同口径）。
   两条拆开写——不支持该伪类的浏览器会整条丢弃，并在一起会连 hover 一起丢。 */
.rail-btn:hover .rail-pop { opacity: 1; visibility: visible; transform: translateY(-50%) translateX(0); }
.rail-btn:focus-visible .rail-pop { opacity: 1; visibility: visible; transform: translateY(-50%) translateX(0); }

