/* ==========================================================================
   湖北盈马汽车科技有限公司 · 官网设计系统
   主色：科技蓝 #004D9B ／ 深蓝端 #022EA9 ／ 品牌绿 #7CB518（Logo 提取）
   ========================================================================== */

/* finesse · register=brand · A=brand-blue + PingFang/HarmonyOS SC + DIN numerals
 * B=700/800 display vs 400 body · C=six full-height snap panels, one idea per screen
 * D=R1 CSS only, no motion library · E=precision industrial — measured, not decorative
 * 此页为既有页面回填戳（short form）：SOUL/SPECTACLE/DENSITY 从未记录过，故留空而不是编造。
 * 动效轮转记录以 .finesse/log.json 为准，本戳仅作它丢失时的兜底。 */

/* ---------- 1. Design Tokens ---------- */
:root {
  /* 蓝 —— 主色体系 */
  --blue-900: #061A36;
  --blue-800: #0A2A54;
  --blue-700: #003D7C;
  --blue-600: #004D9B;   /* 主色 */
  --blue-500: #005FB8;
  --blue-400: #1E7AD1;
  --blue-300: #5AA3E4;
  --blue-200: #A8CCEE;
  --blue-100: #DCE9F7;
  --blue-50:  #F1F6FC;
  --electric: #022EA9;   /* 深蓝端，用于渐变与光效 */

  /* 绿 —— 品牌色（Logo 提取），仅作强调 */
  --green-700: #4A7A0C;
  --green-600: #5F9A12;
  --green-500: #7CB518;  /* 品牌绿 */
  --green-400: #97CE3C;
  --green-100: #EDF7DA;

  /* 中性 —— 全部向品牌蓝（约 215°）偏几度，不用纯白/纯灰
     对比度按 --bg (#F5F8FC) 校验：ink 17.1:1 / ink-2 8.7:1 / ink-3 6.7:1 / ink-4 4.8:1
     ink-3、ink-4 承担 13px 级辅助文字，必须过 4.5:1，不做浅灰装饰字 */
  --ink:     #0E1524;
  --ink-2:   #3E485A;
  --ink-3:   #4E586B;
  --ink-4:   #646E80;
  /* 描边一律半透明：换底色时自动融合，不会浮出一根硬灰线 */
  --line:    rgba(14, 21, 36, .12);
  --line-2:  rgba(14, 21, 36, .075);
  --line-3:  rgba(14, 21, 36, .18);
  --bg:      #F5F8FC;   /* 页面底：向品牌蓝偏的银灰白 */
  --bg-2:    #EDF1F8;
  --bg-3:    #E3E9F3;
  /* 这一族令牌原叫 paper，本轮正名为 surface。改名的原因不是审美：
     cream / sand / paper 这一族名词会把「默认的米色手作调性」写进代码里，
     而本站是蓝绿工业调性 —— 名字在向后来的读者撒谎。它实际就是
     「压在底色之上的一层表面」，故正名。 */
  --surface: #FCFDFF;   /* 卡片/浮层表面：只比底色亮一丝，靠描边 + 阴影分层 */
  --dark:    #081327;
  --dark-2:  #0C1B33;
  /* 页脚提亮底：深色收尾不变，但明度整体抬一档。
     上半是淡雅浅色背景图，下半若是原来的 --dark 会显得突然塌下去、
     整块发闷；抬到 #112A4C 后与上段衔接自然，也把页脚从"翻到底"变成"有光"。 */
  --dark-3:  #112A4C;

  /* 深色区文字 */
  --on-dark:  #F5F8FF;
  --on-dark-2: rgba(245, 248, 255, .76);
  --on-dark-3: rgba(245, 248, 255, .50);
  --dark-line: rgba(255, 255, 255, .13);

  /* 尺寸与节奏 */
  --nav-h: 76px;
  --maxw: 1800px;              /* 版心上限 */
  --maxw-in: 1320px;           /* 图文内页（偏长文）版心 */
  --gutter: clamp(20px, 4vw, 56px);
  --sec-y: clamp(64px, 7.2vw, 118px);
  --r-xs: 4px;
  --r-sm: 8px;
  --r-md: 14px;
  --r-lg: 22px;

  /* 阴影 */
  --sh-1: 0 1px 2px rgba(16, 21, 29, .05);
  --sh-2: 0 6px 20px -6px rgba(16, 33, 72, .13);
  --sh-3: 0 18px 46px -14px rgba(16, 33, 72, .22);
  --sh-4: 0 30px 70px -20px rgba(6, 26, 54, .34);

  /* 字体 */
  --font: "PingFang SC", "HarmonyOS Sans SC", "Microsoft YaHei", "Hiragino Sans GB",
          "Source Han Sans SC", "Noto Sans SC", -apple-system, BlinkMacSystemFont,
          "Segoe UI", Roboto, sans-serif;
  /* 数字/拉丁强调：DIN 系（工业标牌感），避开被用滥的 Inter */
  --font-num: "DIN Alternate", "Bahnschrift", "DIN Condensed", "Segoe UI", Arial, sans-serif;
  --font-en:  "DIN Alternate", "Bahnschrift", "DIN Condensed", "Helvetica Neue",
              "Segoe UI", Arial, sans-serif;

  --ease: cubic-bezier(.22, .61, .36, 1);
  --ease-out: cubic-bezier(.16, 1, .3, 1);
}

/* ---------- 2. Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.72;
  color: var(--ink-2);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  /* ---------- 横向溢出裁切用 clip，不用 hidden ----------
     原来写的是 overflow-x: hidden。它有个不显眼的副作用：hidden 会让 body
     成为滚动容器（另一轴被一并算成 auto），而站头那句 position: sticky 的
     吸附参照就变成了 body 而不是视口 —— 结果是「在一个并不滚动的容器里吸顶」，
     桌面端往下滚，吸顶导航跟着一起滚走。
     clip 只裁切、不建立滚动容器，sticky 恢复成正常的视口吸顶。
     不写 hidden 兜底：那正是要修掉的那个声明。 */
  overflow-x: clip;
}
body.is-locked { overflow: hidden; }
h1, h2, h3, h4, h5, p, figure, blockquote { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
img { display: block; max-width: 100%; height: auto; }
a { color: inherit; text-decoration: none; }
button, input, textarea, select { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; }
table { border-collapse: collapse; width: 100%; }
::selection { background: var(--blue-600); color: var(--on-dark); }

:focus-visible { outline: 2px solid var(--blue-400); outline-offset: 3px; border-radius: 2px; }

/* ---------- 3. 布局工具 ---------- */
/* 版心：默认占视口 90%（左右各留 5%），上限 1800px */
.wrap {
  width: 90%;
  max-width: var(--maxw);
  margin-inline: auto;
}
.wrap--narrow { max-width: 1040px; }
.wrap--wide { max-width: var(--maxw); }
/* 长文/表单类：控制在易读行宽内 */
.wrap--text { width: 90%; max-width: var(--maxw-in); margin-inline: auto; }

/* 版心放宽到 1800px 后，纯文字段落需限制行长以保证可读性
   （只约束版心的直接文本子元素，不影响网格 / 卡片内部的文字） */
.wrap > p, .wrap > .lede, .wrap > ul:not([class]), .wrap > ol:not([class]) { max-width: 82ch; }
.sec { padding-block: var(--sec-y); position: relative; }
.sec--tight { padding-block: clamp(40px, 4.5vw, 72px); }
.sec--bg { background: var(--bg-2); }
.sec--bg3 { background: var(--bg-3); }
.sec--dark { background: var(--dark); color: var(--on-dark-2); }
.sec--dark .display, .sec--dark .h2, .sec--dark .h3, .sec--dark .h4 { color: var(--on-dark); }
.sec--dark .lede, .sec--dark p { color: var(--on-dark-2); }
.sec--dark .eyebrow { color: var(--blue-300); }
.sec--blue { background: var(--blue-600); color: rgba(255,255,255,.8); }
.sec--blue .h2, .sec--blue .h3 { color: var(--on-dark); }

/* ---------- 4. 排版 ---------- */
.eyebrow {
  display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--font-en);
  font-size: 13px; font-weight: 700; letter-spacing: .15em;
  text-transform: uppercase; color: var(--blue-600);
  margin-bottom: 18px;
}
.eyebrow::before {
  content: ""; width: 26px; height: 2px; background: var(--green-500);
  flex: none; border-radius: 2px;
}
.eyebrow--onDark { color: var(--blue-300); }

.display {
  font-size: clamp(32px, 4.6vw, 60px);
  line-height: 1.07; font-weight: 800; letter-spacing: -.03em;
  color: var(--ink);
}
.h2 {
  font-size: clamp(25px, 2.85vw, 37px);
  line-height: 1.23; font-weight: 800; letter-spacing: -.022em;
  color: var(--ink);
}
.h3 {
  font-size: clamp(19px, 1.6vw, 23px);
  line-height: 1.36; font-weight: 700; letter-spacing: -.012em;
  color: var(--ink);
}
.h4 { font-size: 17px; line-height: 1.48; font-weight: 700; color: var(--ink); }
.lede {
  font-size: clamp(15px, 1.08vw, 17px); line-height: 1.82;
  color: var(--ink-3); max-width: 62ch;
}
.small { font-size: 13.5px; line-height: 1.7; color: var(--ink-3); }

/* 断行处理：标题避孤字（balance），正文末行避孤字（pretty） */
.display, .h2, .h3, .h4, .sec-head > h2, .panel__head h2, .newsx__side h2 { text-wrap: balance; }
p, .lede, .small, li { text-wrap: pretty; }
.num { font-family: var(--font-num); font-variant-numeric: tabular-nums; }
.accent { color: var(--blue-600); }
.accent-g { color: var(--green-700); }   /* 文字级绿色用加深版：浅底 4.8:1 */

.sec-head { max-width: 760px; margin-bottom: clamp(30px, 3.6vw, 54px); }
.sec-head--c { margin-inline: auto; text-align: center; }
.sec-head--c .eyebrow { justify-content: center; }
.sec-head--c .lede { margin-inline: auto; }

/* ---------- 5. 按钮 ---------- */
.btn {
  display: inline-flex; align-items: center; gap: 10px;
  height: 46px; padding-inline: 26px; border-radius: 100px;
  font-size: 14px; font-weight: 600; letter-spacing: .01em;
  background: var(--blue-600); color: var(--on-dark);
  transition: background .25s var(--ease), transform .25s var(--ease), box-shadow .25s var(--ease);
  white-space: nowrap; border: 1px solid transparent;
}
.btn:hover { background: var(--blue-700); transform: translateY(-2px); box-shadow: var(--sh-2); }
.btn svg { width: 15px; height: 15px; flex: none; transition: transform .3s var(--ease); }
.btn:hover svg { transform: translateX(3px); }
.btn--ghost { background: transparent; color: var(--blue-600); border-color: var(--line); }
.btn--ghost:hover { background: var(--blue-50); border-color: var(--blue-200); color: var(--blue-700); }
.btn--light { background: var(--surface); color: var(--blue-700); }
.btn--light:hover { background: var(--blue-50); color: var(--blue-700); }
.btn--onDark { background: rgba(255,255,255,.1); color: var(--on-dark); border-color: var(--dark-line); backdrop-filter: blur(8px); }
.btn--onDark:hover { background: rgba(255,255,255,.18); }
.btn--green { background: var(--green-500); }
.btn--green:hover { background: var(--green-600); }
.btn--sm { height: 38px; padding-inline: 18px; font-size: 13px; }
.btn--lg { height: 52px; padding-inline: 32px; font-size: 15px; }

.link-more {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 13.5px; font-weight: 600; color: var(--blue-600);
  transition: gap .25s var(--ease), color .25s var(--ease);
}
.link-more svg { width: 14px; height: 14px; transition: transform .3s var(--ease); }
.link-more:hover { gap: 11px; color: var(--blue-700); }

/* ---------- 6. 主导航 ---------- */
.nav {
  position: sticky; top: 0; z-index: 50;
  background: rgba(250,252,255,.86);
  backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid var(--line-2);
  transition: box-shadow .3s var(--ease), background .3s var(--ease);
}
.nav.is-stuck { box-shadow: var(--sh-2); background: rgba(250,252,255,.94); }
/* 参考图布局：logo 贴左 · 菜单居中 · 工具组贴右
   菜单用 flex:1 + justify-content:center 在剩余空间内居中，
   空间不足时会被压缩，不会像 grid 1fr 那样撑破版心 */
.nav__in { display: flex; align-items: center; height: var(--nav-h); gap: clamp(12px, 1.6vw, 30px); }
.brand { display: flex; align-items: center; gap: 12px; flex: none; }
.brand img { height: 42px; width: auto; }
.brand__tx { display: flex; flex-direction: column; line-height: 1.2; }
.brand__cn { font-size: 15.5px; font-weight: 800; color: var(--ink); letter-spacing: .01em; white-space: nowrap; }
.brand__en {
  font-family: var(--font-en); font-size: 10.5px; font-weight: 600;
  letter-spacing: .075em; color: var(--ink-4); text-transform: uppercase; white-space: nowrap;
}

.menu { flex: 1; min-width: 0; display: flex; align-items: center; justify-content: center; height: 100%; }
.menu__item { position: relative; height: 100%; display: flex; align-items: center; }
.menu__a {
  display: flex; align-items: center; gap: 4px;
  padding: 0 clamp(7px, .8vw, 14px); height: 100%;
  font-size: clamp(13.5px, .92vw, 14.5px); font-weight: 600; color: var(--ink-2);
  white-space: nowrap; position: relative; transition: color .25s var(--ease);
}
.menu__a::after {
  content: ""; position: absolute; left: clamp(7px, .8vw, 14px); right: clamp(7px, .8vw, 14px);
  bottom: 0; height: 3px; background: var(--blue-600);
  transform: scaleX(0); transform-origin: center; transition: transform .34s var(--ease);
  border-radius: 3px 3px 0 0;
}
.menu__a:hover, .menu__item.is-active > .menu__a { color: var(--blue-600); }
.menu__a:hover::after, .menu__item.is-active > .menu__a::after { transform: scaleX(1); }
.menu__a svg { width: 11px; height: 11px; opacity: .45; }
.menu__item.is-active > .menu__a svg { opacity: .8; }

.sub {
  position: absolute; top: 100%; left: 50%; transform: translateX(-50%) translateY(10px);
  min-width: 178px; background: var(--surface); border: 1px solid var(--line-2);
  border-radius: var(--r-md); box-shadow: var(--sh-3); padding: 8px;
  opacity: 0; visibility: hidden;
  transition: opacity .26s var(--ease), visibility .26s var(--ease), transform .26s var(--ease);
}
.menu__item:hover .sub { opacity: 1; visibility: visible; transform: translateX(-50%) translateY(0); }
.sub a {
  display: block; padding: 9px 14px; border-radius: var(--r-sm);
  font-size: 13.5px; color: var(--ink-2); transition: .2s var(--ease); white-space: nowrap;
}
.sub a:hover { background: var(--blue-50); color: var(--blue-600); padding-left: 18px; }

/* 右侧工具组：电话 + 语言 + 搜索 + CTA */
.navtools { display: flex; align-items: center; gap: clamp(2px, .4vw, 8px); flex: none; }
.navtools__tel {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--font-num); font-size: 16.5px; font-weight: 700; color: var(--ink);
  transition: color .22s var(--ease); white-space: nowrap;
}
.navtools__tel svg { width: 17px; height: 17px; color: var(--blue-600); flex: none; }
.navtools__tel:hover { color: var(--blue-600); }
.iconbtn {
  width: 38px; height: 38px; border-radius: 50%; display: grid; place-items: center;
  color: var(--ink-2); transition: background .22s var(--ease), color .22s var(--ease);
}
.iconbtn svg { width: 19px; height: 19px; }
.iconbtn:hover, .ntool.is-open .iconbtn { background: var(--blue-50); color: var(--blue-600); }

/* ═══════════════════════════════════════════════════════════════════════
   🔴 非默认语言（en / ru）：菜单与 logo **同一行居中、不换行** —— 2026-10-21 改版
   ───────────────────────────────────────────────────────────────────────
   背景：上一版把 en/ru 改成「两行」（第 1 行 logo + 工具组，第 2 行整行菜单），
        理由是单行放不下（实测 1280 宽：en 需 800px、可用 568px）。
   本版为什么能单行：**en/ru 页头去掉了「公司名文字块」与「Contact us 按钮」**
        （见 site-header.tsx 的 isDefaultLang 分支），横向腾出约 370px
        （文字块 ≈222px + 按钮 ≈120px + 两个间隙）。
   仍要防溢出，因此 en/ru 的字号与左右内边距**跟着视口线性收放**：
        · ≥1440：字号 14px、内边距 12px（接近中文版的观感）
        · 1121（桌面最窄）：字号 12.5px、内边距 8px
   算例（按实测 en 800px / ru 833px @13.5px 反推的"每 px 字号对应宽度"）：
        1121 宽可用 ≈780px；en ≈672px、ru ≈704px ⇒ 还有 76–108px 余量。
   窄于 1121 走既有的手机断点（菜单折叠成汉堡），本段不管。
   ⚠️ 中文（html[lang="zh-CN"]）**一条规则都不加** —— 它本来就是单行且放得下。
   =================================══════════════════════════════════════════════════ */
@media (min-width: 1121px) {
  /* 单行：不许换行；行高回到统一的 --nav-h */
  html[lang="en"] .nav__in,
  html[lang="ru"] .nav__in {
    flex-wrap: nowrap;
    height: var(--nav-h);
    min-height: 0;
    gap: clamp(10px, 1.1vw, 20px);
  }

  /* 三块都是单行：logo / 菜单 / 工具组 */
  html[lang="en"] .brand,
  html[lang="ru"] .brand { order: 0; }
  html[lang="en"] .navtools,
  html[lang="ru"] .navtools { order: 0; margin-left: 0; }

  /* 菜单：占满中间剩余空间并居中；min-width:0 才允许在窄屏被压缩而不撑破版心 */
  html[lang="en"] .menu,
  html[lang="ru"] .menu {
    order: 0;
    flex: 1 1 auto;
    min-width: 0;
    height: 100%;
    justify-content: center;
    padding: 0;
  }

  html[lang="en"] .menu__item,
  html[lang="ru"] .menu__item { height: 100%; }

  /* 字号 / 内边距随视口收放。系数是**实测**反推的（Chrome 量 .menu 的 scrollWidth）：
     菜单文本宽度 ≈ 62px × 字号（en）/ ≈ 70px × 字号（ru），每项再加 2 × 内边距。
     en：1121 → 10.5px；1280 → 12.1px；1366 → 13.1px；1440+ → 14px ⇒ 1121–1920 实测 0 溢出。
     ru：俄文比英文再长约 10%，单独一档（字号略小 + 字距 -0.012em + 内边距更紧），
         1121 → 10px；1280 → 11.8px；1440 → 13.5px；1600+ → 14px。
     两档都留了 20–50px 余量，不会压到右侧工具组。 */
  html[lang="en"] .menu__a,
  html[lang="ru"] .menu__a {
    height: 100%;
    padding-block: 0;
    font-size: clamp(10.5px, 1.12vw - 2.2px, 14px);
    padding-inline: clamp(6px, .5vw, 12px);
  }
  html[lang="ru"] .menu__a {
    font-size: clamp(10px, 1vw - 1.4px, 14px);
    letter-spacing: -.012em;
    padding-inline: clamp(4px, .45vw, 12px);
  }

  /* 下拉箭头（纯视觉提示）在 en/ru 让位给字号：7 项各带一个 11px 图标 + 4px 间距，
     合计约 75px —— 不去掉的话，1121–1280 这一段要么压字、要么压工具组。
     子菜单照旧：悬停仍然弹出，只是没有那个小三角。 */
  html[lang="en"] .menu__a svg,
  html[lang="ru"] .menu__a svg { display: none; }

  /* 下划线回到按钮底部（单行时菜单项与导航等高） */
  html[lang="en"] .menu__a::after,
  html[lang="ru"] .menu__a::after { bottom: 0; }

  /* 下拉子菜单仍从该项底部弹出 */
  html[lang="en"] .sub,
  html[lang="ru"] .sub { top: 100%; }
}


/* 弹出层（语言 / 搜索） */
.ntool { position: relative; display: flex; align-items: center; }
.pop {
  position: absolute; top: calc(100% + 12px); right: 0; z-index: 70;
  background: var(--surface); border: 1px solid var(--line-2); border-radius: var(--r-md);
  box-shadow: var(--sh-3);
  opacity: 0; visibility: hidden; transform: translateY(-8px) scale(.98);
  transform-origin: top right;
  transition: opacity .26s var(--ease), transform .26s var(--ease), visibility .26s;
}
.ntool.is-open .pop { opacity: 1; visibility: visible; transform: translateY(0) scale(1); }

.pop--lang { width: 262px; padding: 18px; }
.pop__h { font-size: 13px; font-weight: 700; color: var(--ink); margin-bottom: 5px; }
.pop__t { font-size: 12.5px; line-height: 1.6; color: var(--ink-4); margin-bottom: 14px; }
.pop__list { display: flex; flex-direction: column; gap: 2px; }
.pop__list a {
  display: block; padding: 9px 12px; border-radius: var(--r-sm);
  font-size: 13.5px; color: var(--ink-2); transition: .2s var(--ease);
}
.pop__list a:hover { background: var(--blue-50); color: var(--blue-600); padding-left: 16px; }
.pop__list a[aria-current="true"] { color: var(--blue-600); font-weight: 700; background: var(--blue-50); }

.pop--search { width: min(440px, calc(100vw - 40px)); padding: 14px; }
.srch {
  display: flex; align-items: center; gap: 10px; height: 46px;
  padding: 0 6px 0 13px; border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--bg-2);
  transition: border-color .22s var(--ease), background .22s var(--ease), box-shadow .22s var(--ease);
}
.srch:focus-within { border-color: var(--blue-400); background: var(--surface); box-shadow: 0 0 0 3px var(--blue-50); }
.srch__ico { width: 17px; height: 17px; color: var(--ink-4); flex: none; }
.srch__in { flex: 1; min-width: 0; border: 0; background: none; outline: none; font-size: 14px; color: var(--ink); }
.srch__in::-webkit-search-cancel-button { display: none; }
.srch__go {
  width: 34px; height: 34px; border-radius: var(--r-xs); display: grid; place-items: center;
  background: var(--blue-600); color: var(--on-dark); flex: none; transition: background .22s var(--ease);
}
.srch__go:hover { background: var(--blue-700); }
.srch__go svg { width: 15px; height: 15px; }
.srch__res { max-height: 308px; overflow-y: auto; margin-top: 8px; }
.srch__res:empty { display: none; }
.srch__r { display: block; padding: 10px 12px; border-radius: var(--r-sm); transition: background .18s var(--ease); }
.srch__r:hover { background: var(--blue-50); }
.srch__r b { display: block; font-size: 13.5px; font-weight: 600; color: var(--ink); margin-bottom: 2px; }
.srch__r span { font-size: 12.5px; color: var(--ink-4); }
.srch__r mark { background: rgba(151,206,60,.35); color: inherit; border-radius: 2px; padding: 0 1px; }
.srch__empty { padding: 16px 12px; font-size: 13px; color: var(--ink-4); text-align: center; }

.burger { display: none; width: 42px; height: 42px; position: relative; flex: none; }
.burger span {
  position: absolute; left: 11px; width: 20px; height: 2px; background: var(--ink);
  border-radius: 2px; transition: .3s var(--ease);
}
.burger span:nth-child(1) { top: 15px; }
.burger span:nth-child(2) { top: 20px; }
.burger span:nth-child(3) { top: 25px; }
.burger.is-on span:nth-child(1) { top: 20px; transform: rotate(45deg); }
.burger.is-on span:nth-child(2) { opacity: 0; }
.burger.is-on span:nth-child(3) { top: 20px; transform: rotate(-45deg); }

/* 移动抽屉 */
.drawer {
  position: fixed; inset: 0; z-index: 90; background: var(--surface);
  transform: translateX(100%); transition: transform .38s var(--ease-out);
  display: flex; flex-direction: column; overflow-y: auto;
}
.drawer.is-open { transform: translateX(0); }
.drawer__hd {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px var(--gutter); border-bottom: 1px solid var(--line-2); flex: none;
}
.drawer__hd img { height: 38px; }
.drawer__close { width: 40px; height: 40px; display: grid; place-items: center; color: var(--ink); }
.drawer__close svg { width: 22px; height: 22px; }
.drawer__body { padding: 8px var(--gutter) 40px; }
.dm { border-bottom: 1px solid var(--line-2); }
.dm__a {
  display: flex; align-items: center; justify-content: space-between;
  padding: 17px 2px; font-size: 16.5px; font-weight: 700; color: var(--ink);
}
.dm__a svg { width: 16px; height: 16px; color: var(--ink-4); transition: transform .3s var(--ease); }
.dm.is-open .dm__a svg { transform: rotate(180deg); color: var(--blue-600); }
.dm__sub { overflow: hidden; max-height: 0; transition: max-height .34s var(--ease); }
.dm.is-open .dm__sub { max-height: 420px; }
.dm__sub a {
  display: block; padding: 12px 2px 12px 18px; font-size: 14.5px;
  color: var(--ink-3); border-left: 2px solid var(--line); margin-left: 2px;
}
.dm__sub a:last-child { margin-bottom: 12px; }
.drawer__ft { padding: 22px var(--gutter) 46px; margin-top: auto; }
.drawer__ft .btn { width: 100%; justify-content: center; }
.drawer__tel {
  margin-top: 22px; text-align: center; font-size: 13px; color: var(--ink-3);
}
.drawer__tel b { display: block; font-family: var(--font-num); font-size: 22px; color: var(--blue-700); margin-top: 4px; }

/* ---------- 7. Hero（首页） ----------
   原 .hero / .hero__* 整套样式已随首页重做（现为 .hero2）撤除，死代码不留。
   .scroll-hint 与 @keyframes hintMove 是它的附属，一并删除 —— 现首页首屏
   右下角用的是 .hero2__mouse，无 JS 引用的 keyframe 在这里没有任何角色。 */

/* ---------- 8. 数字条 ---------- */
.stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px; background: var(--line-2); }
.stats--dark { background: var(--dark-line); }
.stat { background: var(--bg); padding: clamp(22px, 2.6vw, 36px) clamp(16px, 1.8vw, 28px); }
.sec--dark .stat, .stats--dark .stat { background: var(--dark); }
.stat__n {
  display: flex; align-items: baseline; gap: 3px;
  font-family: var(--font-num); font-size: clamp(30px, 3.4vw, 46px);
  font-weight: 700; color: var(--blue-600); line-height: 1; letter-spacing: -.02em;
}
.stat__n em { font-size: .46em; font-style: normal; font-weight: 700; }
.sec--dark .stat__n { color: var(--green-400); }
.stat__l { font-size: 13.5px; color: var(--ink-3); margin-top: 10px; }
.sec--dark .stat__l { color: var(--on-dark-3); }

/* ---------- 9. 卡片 ---------- */
.grid { display: grid; gap: clamp(16px, 1.7vw, 26px); }
/* 防止子项（尤其是含百分比宽度图片的容器）以 min-content 撑破网格列 */
.split > *, .grid > *, .stats > *, .gal > *, .steps > *, .nlist > * { min-width: 0; }
.g2 { grid-template-columns: repeat(2, 1fr); }
.g3 { grid-template-columns: repeat(3, 1fr); }
.g4 { grid-template-columns: repeat(4, 1fr); }
.g5 { grid-template-columns: repeat(5, 1fr); }
.g-2-1 { grid-template-columns: 2fr 1fr; }
.g-1-2 { grid-template-columns: 1fr 2fr; }

.card {
  background: var(--surface); border: 1px solid var(--line-2); border-radius: var(--r-md);
  overflow: hidden; position: relative;
  transition: transform .34s var(--ease), box-shadow .34s var(--ease), border-color .34s var(--ease);
}
.card:hover { transform: translateY(-5px); box-shadow: var(--sh-3); border-color: var(--blue-100); }
.card__media { position: relative; aspect-ratio: 4 / 3; overflow: hidden; background: var(--bg-3); }
.card__media img { width: 100%; height: 100%; object-fit: cover; transition: transform .7s var(--ease); }
.card:hover .card__media img { transform: scale(1.06); }
.card__body { padding: clamp(16px, 1.5vw, 24px); }
.card__body h3 { margin-bottom: 8px; }
.card__body p { font-size: 13.5px; line-height: 1.72; color: var(--ink-3); }
.card__foot {
  display: flex; align-items: center; justify-content: space-between;
  margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line-2);
}

/* 单件产品的宽卡：图左文右铺满整行。
   用于分类页只有一件产品的情况（新能源冷却系统 / 进气系统）——
   三列网格摆一件产品会在右侧留下近七成空白，看着像没排版。 */
.card--wide > a {
  display: grid; grid-template-columns: minmax(0, .82fr) minmax(0, 1fr);
  align-items: stretch;
}
.card--wide .card__media { aspect-ratio: auto; height: 100%; min-height: clamp(220px, 24vw, 300px); }
.card--wide .card__body {
  display: flex; flex-direction: column;
  padding: clamp(24px, 2.6vw, 40px) clamp(24px, 3vw, 46px);
}
.card--wide .card__body p { font-size: 14.2px; line-height: 1.8; }
.card--wide .card__foot { margin-top: auto; }
@media (max-width: 760px) {
  .card--wide > a { grid-template-columns: 1fr; }
  .card--wide .card__media { aspect-ratio: 4 / 3; min-height: 0; }
  .card--wide .card__body { padding: clamp(16px, 4vw, 24px); }
}

/* 特性 / 优势 */
.feat { display: flex; gap: 16px; }
.feat__ico {
  width: 44px; height: 44px; flex: none; border-radius: 11px;
  display: grid; place-items: center; background: var(--blue-50); color: var(--blue-600);
  transition: .35s var(--ease);
}
.feat:hover .feat__ico { background: var(--blue-600); color: var(--on-dark); transform: rotate(-6deg); }
.feat__ico svg { width: 22px; height: 22px; }
.feat h4 { margin-bottom: 6px; }
.feat p { font-size: 13.5px; line-height: 1.7; color: var(--ink-3); }

/* 编号步骤 .steps / .step
   —— 已废弃：原用于公司简介「从需求到量产」与生产/研发流程页，
   这些页面均已改用 .flow（横向工序 + 连接箭头 + 阶段轴），全站已无 .steps 引用。
   为记录沿革保留此注释，样式本体已移除，避免留一堆永远不会命中的死规则。 */

/* ---------- 27.2 阶段化流程轴（生产流程 / 研发流程） ----------
   背景：这两页的工序是 N 个样式完全相同的长条卡片纵向堆叠 —— 全是文字、
   没有层次，一眼看不出「哪几道是一组、每组在解决什么」。
   解法不是换皮，而是把内容自带的结构显出来：生产流程页的 lede 已经写明
   「前三道决定材质、中间四道决定尺寸、后三道决定能不能出厂」，
   于是按 3 / 4 / 3 分段 —— 分段依据来自文案本身，不是硬凑的。
   每组一行横向排布、组内工序用箭头连成方向，组标题说明这一组在决定什么。
   于是「十道工序」先被读成三段，再被读成一条从材料到交付的线。 */
.flow { display: grid; gap: clamp(24px, 2.8vw, 42px); }

.flow__hd {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: 10px 14px;
  margin-bottom: clamp(14px, 1.6vw, 20px);
  padding-bottom: clamp(10px, 1.1vw, 14px);
  border-bottom: 1px solid var(--line-2);
}
.flow__tag {
  flex: none;
  font-family: var(--font-num); font-size: 12px; font-weight: 700;
  letter-spacing: .12em;
  color: var(--blue-600);
  background: var(--blue-50);
  border: 1px solid var(--blue-100);
  border-radius: 100px;
  padding: 4px 12px;
}
.flow__name {
  font-size: clamp(17px, 1.5vw, 21px); font-weight: 700;
  color: var(--ink); letter-spacing: -.01em; margin: 0;
}
.flow__meta { font-size: 13px; color: var(--ink-4); margin-left: auto; }

.flow__row { display: flex; align-items: stretch; }

.flow__i {
  flex: 1 1 0; min-width: 0;
  position: relative;
  padding-right: 30px;            /* 给连接箭头留位 */
}
.flow__i:last-child { padding-right: 0; }
/* 连接箭头：两条边旋转 -45° 就是一个 chevron。
   用 border 拼而不塞一个 SVG —— 它随 currentColor 与主题走，
   且这一段是纯装饰，不值得为它增加 DOM 或请求。 */
.flow__i:not(:last-child)::after {
  content: ""; position: absolute;
  right: 9px; top: 44px;
  width: 9px; height: 9px;
  border-right: 2px solid var(--blue-200);
  border-bottom: 2px solid var(--blue-200);
  transform: rotate(-45deg);
  /* ---------- 27.3 工序连接箭头的逐段生成 ----------
     原先十道工序的箭头一开屏就全在，工序轴读起来是一张静态图。
     现在让箭头跟着它左边那张卡片一起到场：卡片没滚到时箭头缩成一个点、
     不可见；卡片落位时箭头从 35% 长到实尺，方向与旋转角不变。
     于是「这道工序接上下一道」这件事是随滚动逐段发生的。
     纯 CSS —— .flow__i 已经带 .rv，进视口即有 is-in，不需要新增任何脚本。 */
  transition: opacity .52s var(--ease-out), transform .52s var(--ease-out);
}
.flow__i:not(.is-in):not(:last-child)::after {
  opacity: 0;
  transform: rotate(-45deg) scale(.35);
}

.flow__card {
  height: 100%;
  background: var(--surface);
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  padding: clamp(16px, 1.7vw, 22px);
  transition: border-color .34s var(--ease), box-shadow .34s var(--ease),
              transform .34s var(--ease);
}
.flow__card:hover {
  border-color: var(--blue-200);
  box-shadow: var(--sh-2);
  transform: translateY(-3px);
}
.flow__no {
  display: block;
  font-family: var(--font-num); font-size: 26px; font-weight: 700;
  line-height: 1; letter-spacing: -.02em;
  color: var(--blue-100);
  margin-bottom: 10px;
  transition: color .35s var(--ease);
}
.flow__card:hover .flow__no { color: var(--blue-400); }
.flow__card h4 { font-size: 15.5px; font-weight: 700; color: var(--ink); margin: 0 0 4px; }
.flow__card em {
  display: block; font-style: normal;
  font-family: var(--font-en); font-size: 11.5px; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--blue-500);
  margin-bottom: 8px;
}
.flow__card p { font-size: 13.2px; line-height: 1.7; color: var(--ink-3); margin: 0; }

/* 工序行在窄屏失去「一行」的意义，箭头也就不再指得准 ——
   两列时隐藏箭头，让卡片自己成网格；一列时干脆是一次纵向的工序列表。 */
@media (max-width: 1000px) {
  .flow__row { flex-wrap: wrap; gap: 14px; }
  .flow__i { flex: 1 1 calc(50% - 7px); padding-right: 0; }
  .flow__i:not(:last-child)::after { display: none; }
}
@media (max-width: 560px) {
  .flow__i { flex: 1 1 100%; }
}

/* 新闻列表 */
.nlist { display: grid; gap: 1px; background: var(--line-2); border-radius: var(--r-md); overflow: hidden; }
.nitem {
  display: grid; grid-template-columns: 92px 1fr auto auto; align-items: center;
  gap: clamp(14px, 1.8vw, 28px); padding: clamp(16px, 1.6vw, 22px) clamp(16px, 1.8vw, 28px);
  background: var(--surface); transition: .3s var(--ease);
}
.nitem:hover { background: var(--blue-50); }
.nitem__d { text-align: center; font-family: var(--font-num); }
.nitem__d b { display: block; font-size: 24px; font-weight: 700; color: var(--blue-600); line-height: 1; }
.nitem__d span { font-size: 12.5px; color: var(--ink-4); letter-spacing: .04em; }
.nitem__t { min-width: 0; }
.nitem__t h4 { font-size: 15.5px; font-weight: 700; color: var(--ink); margin-bottom: 5px;
  display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; overflow: hidden; }
.nitem__t p { font-size: 13px; color: var(--ink-3); line-height: 1.6;
  display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; overflow: hidden; }
.nitem__cat {
  font-size: 12.5px; padding: 4px 12px; border-radius: 100px;
  background: var(--blue-50); color: var(--blue-600); border: 1px solid var(--blue-100);
  white-space: nowrap; flex: none;
}
.nitem__arw { width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center;
  border: 1px solid var(--line); color: var(--ink-4); flex: none; transition: .3s var(--ease); }
.nitem:hover .nitem__arw { background: var(--blue-600); border-color: var(--blue-600); color: var(--on-dark); }
.nitem__arw svg { width: 14px; height: 14px; }

/* 新闻卡（首页） */
.ncard { background: var(--surface); border: 1px solid var(--line-2); border-radius: var(--r-md); overflow: hidden;
  display: flex; flex-direction: column; transition: .34s var(--ease); }
.ncard:hover { transform: translateY(-5px); box-shadow: var(--sh-3); border-color: var(--blue-100); }
.ncard__media { aspect-ratio: 16 / 10; overflow: hidden; background: var(--bg-3); position: relative; }
.ncard__media img { width: 100%; height: 100%; object-fit: cover; transition: transform .7s var(--ease); }
.ncard:hover .ncard__media img { transform: scale(1.06); }
.ncard__cat {
  position: absolute; top: 12px; left: 12px; z-index: 2;
  font-size: 12.5px; padding: 4px 11px; border-radius: 100px;
  background: rgba(6,26,54,.8); color: var(--on-dark); backdrop-filter: blur(6px);
}
.ncard__body { padding: clamp(16px, 1.5vw, 22px); flex: 1; display: flex; flex-direction: column; }
.ncard__date { font-family: var(--font-num); font-size: 12.5px; color: var(--ink-4); letter-spacing: .05em; margin-bottom: 9px; }
.ncard__body h3 {
  font-size: 15.5px; font-weight: 700; line-height: 1.48; color: var(--ink); margin-bottom: 10px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.ncard:hover .ncard__body h3 { color: var(--blue-600); }
.ncard__body p { font-size: 13px; color: var(--ink-3); line-height: 1.7; flex: 1;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }

/* ---------- 10. 页脚（已合并，此处是标记位） ----------
   ⚠️ 2026-10-08：内页原来那套 `.foot` / `.foot__*` 已**整体删除**。
   全站 28 个页面现在共用同一份页脚：结构在 26 节（.foot2__*），
   定义在 src/tpl/footer.html，由 src/apply_footer.py 套用。

   删除清单：.foot、.foot::before、.foot__main、.foot__brand、.foot__tags、
             .foot__h、.foot__links、.foot__ct、.foot__bar、.foot__barNav

   留一个空段是刻意的 —— 提醒后来者「页脚只有一套」，
   不要在这里重新长出一份实现。改页脚请去 26 节和那个模板文件。 */

/* 悬浮返回顶部 */
.totop {
  position: fixed; right: 22px; bottom: 26px; z-index: 40;
  width: 44px; height: 44px; border-radius: 12px; display: grid; place-items: center;
  background: var(--surface); border: 1px solid var(--line); color: var(--blue-600);
  box-shadow: var(--sh-2); opacity: 0; visibility: hidden; transform: translateY(12px);
  transition: .3s var(--ease);
}
.totop.is-on { opacity: 1; visibility: visible; transform: translateY(0); }
.totop:hover { background: var(--blue-600); color: var(--on-dark); border-color: var(--blue-600); }
.totop svg { width: 18px; height: 18px; }

/* ---------- 11. 内页头部 ---------- */
.phead {
  position: relative; background: var(--blue-900); color: var(--on-dark);
  padding-block: clamp(50px, 6vw, 104px); overflow: hidden;
}
.phead__bg { position: absolute; inset: 0; }
.phead__bg img { width: 100%; height: 100%; object-fit: cover; opacity: .3; }
.phead__bg::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(104deg, rgba(6,26,54,.95) 0%, rgba(6,26,54,.72) 46%, rgba(2,46,169,.44) 100%);
}
.phead__in { position: relative; z-index: 2; }
.phead .eyebrow { color: var(--blue-300); }
.phead .display { color: var(--on-dark); }
.phead .lede { color: rgba(255,255,255,.72); margin-top: 16px; }
.crumb {
  display: flex; align-items: center; gap: 9px; flex-wrap: wrap;
  font-size: 13px; color: rgba(255,255,255,.7); margin-top: 22px;
}
.crumb a { transition: color .2s var(--ease); }
.crumb a:hover { color: var(--on-dark); }
.crumb svg { width: 12px; height: 12px; opacity: .5; }
.crumb b { color: rgba(255,255,255,.85); font-weight: 600; }

/* 子栏目 Tab */
.tabs {
  display: flex; flex-wrap: wrap; gap: 6px;
  border-bottom: 1px solid var(--line); margin-bottom: clamp(28px, 3vw, 46px);
}
.tabs a {
  position: relative; padding: 13px 20px; font-size: 14.5px; font-weight: 600;
  color: var(--ink-3); white-space: nowrap; transition: color .25s var(--ease);
}
.tabs a::after {
  content: ""; position: absolute; left: 14px; right: 14px; bottom: -1px; height: 2.5px;
  background: var(--blue-600); transform: scaleX(0); transition: transform .3s var(--ease);
  border-radius: 3px;
}
.tabs a:hover { color: var(--blue-600); }
.tabs a.is-on { color: var(--blue-600); }
.tabs a.is-on::after { transform: scaleX(1); }

/* ---------- 12. 时间轴 ---------- */
.tl { position: relative; padding-left: 30px; }
.tl::before {
  content: ""; position: absolute; left: 5px; top: 8px; bottom: 8px; width: 2px;
  background: linear-gradient(to bottom, var(--blue-200), var(--green-400), var(--line-2));
  border-radius: 2px;
}
.tl__i { position: relative; padding-bottom: clamp(26px, 3vw, 44px); }
.tl__i:last-child { padding-bottom: 0; }
.tl__i::before {
  content: ""; position: absolute; left: -30px; top: 6px;
  width: 12px; height: 12px; border-radius: 50%; background: var(--surface);
  border: 3px solid var(--blue-400); transition: .3s var(--ease);
}
.tl__i:hover::before { border-color: var(--green-500); transform: scale(1.16); }
.tl__y {
  font-family: var(--font-num); font-size: 21px; font-weight: 700;
  color: var(--blue-600); line-height: 1.2; margin-bottom: 7px;
}
.tl__i h4 { margin-bottom: 6px; }
.tl__i p { font-size: 13.6px; line-height: 1.75; color: var(--ink-3); }

/* ---------- 13. 图集 / 证书墙 ---------- */
.gal { display: grid; gap: clamp(10px, 1.2vw, 18px); }
.gal--3 { grid-template-columns: repeat(3, 1fr); }
.gal--4 { grid-template-columns: repeat(4, 1fr); }
.gal--5 { grid-template-columns: repeat(5, 1fr); }
.gal__i {
  position: relative; overflow: hidden; border-radius: var(--r-sm);
  background: var(--bg-3); aspect-ratio: 4 / 3; cursor: pointer;
}
.gal__i img { width: 100%; height: 100%; object-fit: cover; transition: transform .6s var(--ease); }
.gal__i:hover img { transform: scale(1.08); }
.gal__i::after {
  content: ""; position: absolute; inset: 0; background: rgba(6,26,54,0);
  transition: background .35s var(--ease);
}
.gal__i:hover::after { background: rgba(6,26,54,.34); }
.gal__i--cert { aspect-ratio: 3 / 4; background: var(--surface); border: 1px solid var(--line-2); }
.gal__i--cert img { object-fit: contain; padding: 10px; }

/* 证书类的格子：扫描件是竖长的，4:3 的格子里用 object-fit:cover 会把上下
   各切掉一截、连证书编号都读不到；所以这类格子改成「完整装入」。
   留白取 --surface —— 证书纸张实测边框均值 #F8F8F4，与这个令牌只差
   1-3 级，肉眼接不上；原来这里写的是内联的纯白，属于绕过设计系统的一次性
   颜色，已收回令牌。
   .figure 里也用到同一套（荣誉资质页三张体系证书），故选择器并列写出。 */
.gal__i--contain, .figure--contain { background: var(--surface); }
.gal__i--contain img, .figure--contain img { object-fit: contain; }

/* ---------- 14. 表单 ---------- */
.form { display: grid; gap: 18px; }
.field { display: grid; gap: 8px; }
.field label { font-size: 13.5px; font-weight: 600; color: var(--ink); }
.field label em { color: #D6453D; font-style: normal; margin-left: 3px; }
.field input, .field textarea, .field select {
  width: 100%; padding: 13px 16px; border: 1px solid var(--line);
  border-radius: var(--r-sm); background: var(--surface); font-size: 14.5px;
  transition: border-color .22s var(--ease), box-shadow .22s var(--ease);
}
.field textarea { min-height: 140px; resize: vertical; line-height: 1.7; }
.field input:focus, .field textarea:focus, .field select:focus {
  outline: none; border-color: var(--blue-400); box-shadow: 0 0 0 3px var(--blue-50);
}
.field input::placeholder, .field textarea::placeholder { color: var(--ink-4); }
.form__row { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }

/* ---------- 15. 联系信息卡 ---------- */
.cinfo { display: grid; gap: 1px; background: var(--line-2); border-radius: var(--r-md); overflow: hidden; }
.cinfo li {
  background: var(--surface); padding: 20px clamp(18px, 2vw, 26px);
  display: flex; gap: 14px; align-items: flex-start;
}
.cinfo svg { width: 19px; height: 19px; color: var(--blue-600); flex: none; margin-top: 3px; }
.cinfo b { display: block; font-size: 13px; color: var(--ink-4); font-weight: 600;
  letter-spacing: .06em; margin-bottom: 4px; }
.cinfo span { font-size: 14.5px; color: var(--ink); line-height: 1.7; }
.cinfo span.tel { font-family: var(--font-num); font-size: 19px; font-weight: 700; color: var(--blue-700); }

/* ---------- 15b. 联系我们 · 厂区地图（高德地图） ----------
   原先是 .map：一个虚线框占位块，里面写着「建议接入高德 / 百度地图…」。
   现在换成真的高德地图容器，占位那三行说明整段删掉。

   ⚠️ 高德要求容器有确定尺寸，否则渲染出 0 高、看着像没加载。这里用 aspect-ratio
      给死宽高比，内层 stage 绝对定位铺满；map 开了 resizeEnable，容器变宽自己跟上。
   ⚠️ 兜底层（Key 没配 / 脚本加载失败 / 网络不通）**默认显示**，只有地图真的
      is-live 了才收起。反过来写的话，Key 未配置时地图区就是一块空白，
      比原来的虚线占位还难看。 */
.cmap {
  position: relative; aspect-ratio: 16 / 9;
  border-radius: var(--r-md); overflow: hidden;
  background: var(--bg-3); border: 1px solid var(--line);
  isolation: isolate;
}
.cmap__stage { position: absolute; inset: 0; z-index: 0; }
/* 高德的信息窗是它自己注入的 DOM，样式得挂在全局，不能被 .cmap 作用域挡住 */
.cmap__iw { padding: 3px 2px; max-width: 250px; }
.cmap__iw b { display: block; font-size: 14px; color: var(--ink); margin-bottom: 4px; }
.cmap__iw span { display: block; font-size: 12.5px; line-height: 1.62; color: var(--ink-3); }

.cmap__fb {
  position: absolute; inset: 0; z-index: 1;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 11px; padding: 24px; text-align: center; text-decoration: none;
  background: var(--bg-3); transition: background .3s var(--ease);
}
.cmap__fb:hover { background: var(--blue-50); }
.cmap__fb i {
  width: 44px; height: 44px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--blue-600); color: var(--on-dark);
}
.cmap__fb i svg { width: 22px; height: 22px; }
.cmap__fb span { font-size: 14px; font-weight: 600; color: var(--blue-600); }
.cmap.is-live .cmap__fb { display: none; }
/* 窄屏 16:9 只剩一条缝，地图没法操作 —— 放高一点 */
@media (max-width: 560px) { .cmap { aspect-ratio: 4 / 3; } }

/* ---------- 16. 产品详情 ---------- */
.pd { display: grid; grid-template-columns: 1.05fr 1fr; gap: clamp(26px, 3.4vw, 58px); align-items: start; }
.pd__media {
  border-radius: var(--r-md); overflow: hidden; background: var(--surface);
  border: 1px solid var(--line-2); aspect-ratio: 4 / 3; display: grid; place-items: center;
}
.pd__media img { max-width: 100%; max-height: 100%; object-fit: contain; }
.spec { border: 1px solid var(--line-2); border-radius: var(--r-md); overflow: hidden; }
.spec th, .spec td { padding: 13px 18px; font-size: 13.8px; text-align: left; border-bottom: 1px solid var(--line-2); }
.spec th { background: var(--bg-2); font-weight: 600; color: var(--ink); width: 38%; }
.spec tr:last-child th, .spec tr:last-child td { border-bottom: 0; }

/* ---------- 17. 富文本正文 ---------- */
.prose { font-size: 15px; line-height: 1.95; color: var(--ink-2); }
.prose > * + * { margin-top: 1.05em; }
.prose h2 { font-size: clamp(21px, 2vw, 27px); font-weight: 800; color: var(--ink);
  line-height: 1.35; margin-top: 2em; letter-spacing: -.015em; }
.prose h3 { font-size: clamp(17px, 1.5vw, 20px); font-weight: 700; color: var(--ink);
  line-height: 1.45; margin-top: 1.7em; }
.prose h4 { font-size: 15.5px; font-weight: 700; color: var(--ink); margin-top: 1.5em; }
.prose p { margin-top: .9em; }
.prose ul, .prose ol { margin-top: .9em; display: grid; gap: .55em; }
.prose li { padding-left: 20px; position: relative; }
.prose li::before {
  content: ""; position: absolute; left: 2px; top: .72em;
  width: 5px; height: 5px; border-radius: 50%; background: var(--blue-400);
}
.prose ol { counter-reset: n; }
.prose ol li::before {
  counter-increment: n; content: counter(n); width: auto; height: auto;
  background: none; color: var(--blue-600); font-weight: 700; font-size: 13px;
  font-family: var(--font-num); top: 0; left: 0;
}
.prose blockquote {
  border-left: 3px solid var(--blue-400); background: var(--blue-50);
  padding: 16px 22px; border-radius: 0 var(--r-sm) var(--r-sm) 0;
  font-size: 14.5px; color: var(--ink-2);
}
.prose strong { color: var(--ink); font-weight: 700; }
.prose hr { border: 0; border-top: 1px solid var(--line-2); margin-block: 2em; }
.prose img { border-radius: var(--r-sm); margin-inline: auto; }
.prose figure figcaption { font-size: 13px; color: var(--ink-4); text-align: center; margin-top: 10px; }

/* ---------- 18. 手风琴 FAQ ---------- */
.faq { border-top: 1px solid var(--line-2); }
.faq__i { border-bottom: 1px solid var(--line-2); }
.faq__q {
  width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 18px;
  padding: 22px 4px; text-align: left; font-size: 16px; font-weight: 700; color: var(--ink);
  transition: color .25s var(--ease);
}
.faq__q:hover { color: var(--blue-600); }
.faq__q i {
  width: 26px; height: 26px; flex: none; border-radius: 50%; display: grid; place-items: center;
  background: var(--bg-2); color: var(--blue-600); transition: .3s var(--ease);
}
.faq__q i svg { width: 13px; height: 13px; transition: transform .3s var(--ease); }
.faq__i.is-open .faq__q { color: var(--blue-600); }
.faq__i.is-open .faq__q i { background: var(--blue-600); color: var(--on-dark); }
.faq__i.is-open .faq__q i svg { transform: rotate(45deg); }
.faq__a { overflow: hidden; max-height: 0; transition: max-height .36s var(--ease); }
.faq__a > div { padding: 0 4px 24px; font-size: 14.2px; line-height: 1.82; color: var(--ink-3); max-width: 78ch; }

/* ---------- 19. 客户 Logo 墙 ---------- */
.clients { display: grid; grid-template-columns: repeat(6, 1fr); gap: 1px; background: var(--line-2);
  border-radius: var(--r-md); overflow: hidden; }
.client {
  background: var(--surface); padding: clamp(18px, 2vw, 30px) 14px; display: grid; place-items: center;
  gap: 8px; text-align: center; transition: .3s var(--ease);
}
.client:hover { background: var(--blue-50); }
.client b { font-size: 14.5px; font-weight: 700; color: var(--ink); }
.client span { font-size: 12.5px; color: var(--ink-4); letter-spacing: .05em; }
.sec--dark .client { background: rgba(255,255,255,.03); }
.sec--dark .client:hover { background: rgba(255,255,255,.07); }
.sec--dark .client b { color: var(--on-dark); }
.sec--dark .client span { color: var(--on-dark-3); }

/* ---------- 20. 视频 ---------- */
.vbox { position: relative; border-radius: var(--r-md); overflow: hidden; background: var(--dark); aspect-ratio: 16 / 9; }
.vbox video { width: 100%; height: 100%; object-fit: cover; display: block; }
/* 竖屏素材在 16:9 画框里的装法。
   staff-3（540x960）与 staff-4（720x1280）是竖屏片子，先前和横屏片子共用
   object-fit:cover —— 一只 16:9 的取景框去套 9:16 的画面，左右各裁一大截，
   实际只剩中间不到三分之一可见。反之，单纯改成 contain 也只是把问题从
   「裁掉内容」换成「画框里一条 96px 的窄带 + 两块空档」。
   这里用双层的标准做法：正片 contain 完整装入不裁切，底下垫一层同海报图的
   重度虚化填充 —— 画框被填满，视线读作「这是一段竖屏影像」而不是排版出错。
   填充层直接继承 .vbox 上的背景图（就是那张 poster），不发任何新请求。
   方向由素材决定，所以写成 class，不用运行时按 videoWidth 判断 ——
   否则首帧会先按 cover 画一次、加载完再跳回 contain。 */
.vbox--portrait { position: relative; }
.vbox--portrait::before {
  content: ""; position: absolute; inset: -8%;
  background-image: inherit;
  background-size: cover; background-position: center;
  filter: blur(22px) saturate(.85);
  transform: scale(1.06);
  opacity: .55;
}
.vbox--portrait video { object-fit: contain; position: relative; z-index: 1; }
.vbox--portrait .vbox__play { z-index: 2; }
.vbox__play {
  position: absolute; inset: 0; display: grid; place-items: center;
  background: rgba(6,26,54,.42); transition: background .3s var(--ease);
}
.vbox__play:hover { background: rgba(6,26,54,.26); }
.vbox__play i {
  width: 68px; height: 68px; border-radius: 50%; background: rgba(255,255,255,.94);
  display: grid; place-items: center; color: var(--blue-700);
  box-shadow: 0 10px 34px rgba(0,0,0,.34); transition: transform .3s var(--ease);
}
.vbox__play:hover i { transform: scale(1.09); }
.vbox__play svg { width: 24px; height: 24px; margin-left: 3px; }
/* 小画框里的播放键收一号：68px 的白圆放在 304px 宽的片子带上占掉五分之一
   宽度，比画面本身还抢眼。视频展示页的片子带（.vgrid）与员工风采页的
   「团队瞬间」（.g3）属同一量级的画框，取同一个尺寸，别一页 68 一页 52。 */
.vgrid .vbox__play i,
.g3 > .vbox .vbox__play i { width: 54px; height: 54px; }
.vgrid .vbox__play svg,
.g3 > .vbox .vbox__play svg { width: 20px; height: 20px; }

/* ---------- 21. 进场动画 ---------- */
.rv { opacity: 0; transform: translateY(26px); transition: opacity .78s var(--ease-out), transform .78s var(--ease-out); }
.rv.is-in { opacity: 1; transform: none; }
.rv-l { opacity: 0; transform: translateX(-30px); transition: opacity .78s var(--ease-out), transform .78s var(--ease-out); }
.rv-l.is-in { opacity: 1; transform: none; }
.rv-r { opacity: 0; transform: translateX(30px); transition: opacity .78s var(--ease-out), transform .78s var(--ease-out); }
.rv-r.is-in { opacity: 1; transform: none; }
.rv-s { opacity: 0; transform: translateY(26px) scale(.97); transition: opacity .8s var(--ease-out), transform .8s var(--ease-out); }
.rv-s.is-in { opacity: 1; transform: none; }
[data-d="1"] { transition-delay: .08s; }
[data-d="2"] { transition-delay: .16s; }
[data-d="3"] { transition-delay: .24s; }
[data-d="4"] { transition-delay: .32s; }
[data-d="5"] { transition-delay: .4s; }
[data-d="6"] { transition-delay: .48s; }
[data-d="7"] { transition-delay: .56s; }
[data-d="8"] { transition-delay: .64s; }
[data-d="9"] { transition-delay: .72s; }
[data-d="10"] { transition-delay: .8s; }

/* --- 21.1 子元素级错峰入场（.rvk = reveal kids） ---
   容器获得 .is-in 后，其直接子元素依次进场。
   用 animation（而非 transition）实现，避免覆盖卡片/按钮自身的 hover transition；
   关键帧只声明 from，动画结束后不残留 transform，hover 位移照常工作。 */
.rvk > * { opacity: 0; }
.rvk.is-in > * { opacity: 1; animation: rvKid .74s var(--ease-out) backwards; }
.rvk.is-in > *:nth-child(1) { animation-delay: .04s; }
.rvk.is-in > *:nth-child(2) { animation-delay: .12s; }
.rvk.is-in > *:nth-child(3) { animation-delay: .2s; }
.rvk.is-in > *:nth-child(4) { animation-delay: .28s; }
.rvk.is-in > *:nth-child(5) { animation-delay: .36s; }
.rvk.is-in > *:nth-child(6) { animation-delay: .44s; }
.rvk.is-in > *:nth-child(7) { animation-delay: .52s; }
.rvk.is-in > *:nth-child(8) { animation-delay: .6s; }
.rvk.is-in > *:nth-child(n+9) { animation-delay: .66s; }
@keyframes rvKid {
  from { opacity: 0; transform: translateY(22px); }
}
/* 变体：左右向入场（配合 .split 的两栏结构） */
.rvk--l.is-in > * { animation-name: rvKidL; }
@keyframes rvKidL { from { opacity: 0; transform: translateX(-28px); } }
.rvk--r.is-in > * { animation-name: rvKidR; }
@keyframes rvKidR { from { opacity: 0; transform: translateX(28px); } }

/* ⚠️ 无 JS 兜底 —— 必须留着。
   `.rvk > * { opacity: 0 }` 是把子元素先藏起来、等脚本加上 .is-in 再放出来。
   脚本被禁用 / 被 CSP 拦掉 / 干脆报错时，没有任何东西会加 .is-in，
   于是整块内容**永久不可见**且看不出哪里坏了（页脚、内页板块都挂了这个类）。
   这里在「根元素没有 js 标记」时直接放行；有 JS 时这条不生效，动画照常。 */
html:not(.js) .rvk > * { opacity: 1; transform: none; }

/* ⚠️ 无 JS 兜底（2026-10-08 补）：整站的 .rv / .rv-l / .rv-r / .rv-s 默认态是
   opacity: 0，靠 site.js 加 .is-in 才显示 —— 之前只有上面 .rvk 这一条有兜底，
   JS 没执行（被拦截、脚本 404、企业内网策略）时这些元素会**整块不可见**，
   实测 about 页 20/20 个入场元素全部隐藏。
   补一行与 .rvk 同款的兜底，成本为零，最坏情况从「白屏」变成「没有动画」。 */
html:not(.js) .rv, html:not(.js) .rv-l,
html:not(.js) .rv-r, html:not(.js) .rv-s { opacity: 1; transform: none; }

/* --- 21.2 图片入场：淡入 + 缩放回正 + 自下而上遮罩揭示 --- */
.rv-img { position: relative; overflow: hidden; }
.rv-img img { opacity: 0; }
.rv-img.is-in img { opacity: 1; animation: rvZoom 1.05s var(--ease-out) backwards; }
@keyframes rvZoom { from { opacity: 0; transform: scale(1.06); } }
.rv-img::after {
  content: ""; position: absolute; inset: 0; z-index: 1;
  background: var(--rv-mask, var(--bg));
  transform-origin: bottom; pointer-events: none;
}
.rv-img.is-in::after { animation: rvWipe .92s var(--ease-out) .06s forwards; }
@keyframes rvWipe {
  from { transform: scaleY(1); }
  to { transform: scaleY(0); }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; animation-delay: 0s !important; transition-duration: .001ms !important; }
  .rv, .rv-l, .rv-r, .rv-s { opacity: 1; transform: none; }
  .rvk > *, .rv-img img { opacity: 1; transform: none; }
  .rv-img::after { display: none; }
  /* 新闻资讯：标题与右列小卡都是「以预备态起手」的，降级时必须回到终态 */
  html.pg-index .newsx__h .ln > span { transform: none; }
  html.pg-index .newsx__mini > .nmini { opacity: 1; animation: none; }
  .hero2__slide .hero2__h,
  .hero2__slide .hero2__p,
  .hero2__slide .hero2__spec,
  .hero2__slide .hero2__vow,
  .hero2__slide .hero2__btns { transition-delay: 0s !important; }
  /* 滚动提示的循环动画一并停掉 */
  .hero2__mouse i::after { animation: none; opacity: 1; }
  /* 背景推近：停掉动画让它停在基准位（scale 1），而不是停在推到一半的构图 */
  .hero2__slide .hero2__bg img { animation: none; transform: scale(1); }
}

/* ---------- 22. 内页共用块 ---------- */
.split { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(26px, 3.6vw, 64px); align-items: center; }
.split--wide-l { grid-template-columns: 1.25fr 1fr; }
.split--wide-r { grid-template-columns: 1fr 1.25fr; }
.figure { border-radius: var(--r-md); overflow: hidden; position: relative; background: var(--bg-3); }
.figure img { width: 100%; height: 100%; object-fit: cover; }
.figure--43 { aspect-ratio: 4 / 3; }
.figure--32 { aspect-ratio: 3 / 2; }
.figure--11 { aspect-ratio: 1 / 1; }
.figure--169 { aspect-ratio: 16 / 9; }
.figure__tag {
  position: absolute; left: 16px; bottom: 16px; z-index: 2;
  padding: 7px 14px; border-radius: 100px; font-size: 12.5px; font-weight: 600;
  background: rgba(6,26,54,.76); color: var(--on-dark); backdrop-filter: blur(8px);
}
.badge {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12.5px; font-weight: 600; padding: 4px 11px; border-radius: 100px;
  background: var(--green-100); color: var(--green-700);
}
.badge--blue { background: var(--blue-50); color: var(--blue-600); }
.badge--gray { background: var(--bg-3); color: var(--ink-3); }

.kv { display: grid; gap: 14px; }
.kv li { display: grid; grid-template-columns: 92px 1fr; gap: 14px; font-size: 14px; }
.kv b { color: var(--ink-4); font-weight: 600; font-size: 13px; }
.kv span { color: var(--ink); }

.quote {
  border-left: 3px solid var(--green-500); padding: 4px 0 4px 22px;
  font-size: clamp(15px, 1.35vw, 18px); line-height: 1.8; color: var(--ink);
  font-weight: 500;
}

/* 灯箱 */
.lb {
  position: fixed; inset: 0; z-index: 200; background: rgba(6,12,24,.94);
  display: grid; place-items: center; padding: 40px 70px; opacity: 0; visibility: hidden;
  transition: .3s var(--ease); cursor: zoom-out;
}
.lb.is-on { opacity: 1; visibility: visible; }
.lb img { max-width: 100%; max-height: 100%; object-fit: contain; border-radius: var(--r-sm); }
.lb__x {
  position: absolute; top: 24px; right: 26px; width: 42px; height: 42px;
  border-radius: 50%; background: rgba(255,255,255,.12); color: var(--on-dark);
  display: grid; place-items: center; cursor: pointer;
}
.lb__x svg { width: 20px; height: 20px; }

/* 分页 */
.pager { display: flex; align-items: center; justify-content: center; gap: 7px; margin-top: clamp(30px, 3.4vw, 52px); flex-wrap: wrap; }
.pager a, .pager span {
  min-width: 40px; height: 40px; padding-inline: 12px; border-radius: var(--r-sm);
  display: grid; place-items: center; font-size: 14px; font-family: var(--font-num);
  border: 1px solid var(--line); color: var(--ink-2); transition: .25s var(--ease); background: var(--surface);
}
.pager a:hover { border-color: var(--blue-400); color: var(--blue-600); }
.pager .is-on { background: var(--blue-600); border-color: var(--blue-600); color: var(--on-dark); font-weight: 700; }
.pager .is-dis { opacity: .4; pointer-events: none; }

/* ==========================================================================
   23. 响应式
   ========================================================================== */

/* --- 1700 以下：电话只留图标，给菜单让出空间 --- */@media (max-width: 1700px) {
  .navtools__tel b { display: none; }
}

/* --- 1300 以下：收起英文副标与电话图标 --- */
@media (max-width: 1300px) {
  .brand__en { display: none; }
  .navtools__tel { display: none; }
}
@media (max-width: 1240px) {
  .navtools__cta {
    width: 38px; height: 38px; padding: 0; border-radius: 50%;
    justify-content: center; gap: 0; font-size: 0;
  }
  .navtools__cta svg { width: 16px; height: 16px; }
}

/* --- 1120 以下：主菜单转抽屉 --- */
@media (max-width: 1120px) {
  :root { --nav-h: 66px; }
  .menu, .navtools__cta { display: none; }
  .navtools { margin-left: auto; }
  .burger { display: block; }
  /* 弹出层脱离工具组的窄容器，改为贴顶栏整体宽度，避免向右溢出 */
  .pop {
    position: fixed; left: 20px; right: 20px; width: auto;
    top: calc(var(--nav-h) + 4px); transform-origin: top center;
  }
  .pop--lang, .pop--search { width: auto; }
  .brand img { height: 36px; }
  .g5 { grid-template-columns: repeat(4, 1fr); }
  .clients { grid-template-columns: repeat(3, 1fr); }
  /* 页脚断点统一移到文件末尾第 28 节，此处不再重复声明（顺序冲突见该节注释） */
}

/* --- 960 以下：两列 → 单列 --- */
@media (max-width: 960px) {
  body { font-size: 14.5px; }
  .g4, .g3 { grid-template-columns: repeat(2, 1fr); }
  .g-2-1, .g-1-2 { grid-template-columns: 1fr; }
  .split, .split--wide-l, .split--wide-r { grid-template-columns: 1fr; }
  .stats { grid-template-columns: repeat(2, 1fr); }
  .gal--5, .gal--4 { grid-template-columns: repeat(3, 1fr); }
  .pd { grid-template-columns: 1fr; }
  .nitem { grid-template-columns: 68px 1fr auto; }
  .nitem__cat { display: none; }
}

/* --- 720 以下：移动端 --- */
@media (max-width: 720px) {
  :root {
    --gutter: 18px;
    --sec-y: clamp(46px, 11vw, 68px);
    --r-md: 12px;
    --r-lg: 16px;
  }
  body { font-size: 14px; line-height: 1.72; }
  .g3, .g4, .g5 { grid-template-columns: 1fr; }
  .gal--3, .gal--4, .gal--5 { grid-template-columns: repeat(2, 1fr); }
  .stats { grid-template-columns: 1fr 1fr; }
  .stat { padding: 20px 16px; }
  .clients { grid-template-columns: repeat(2, 1fr); }
  .display { font-size: clamp(24px, 6.6vw, 32px); }
  .h2 { font-size: clamp(21px, 5.6vw, 27px); }
  .h3 { font-size: 17.5px; }
  .sec-head { margin-bottom: 26px; }
  .split { gap: 24px; }
  .step { grid-template-columns: 1fr; gap: 8px; padding: 20px 18px; }
  .step__no { font-size: 24px; }
  .nitem { grid-template-columns: 54px 1fr; padding: 15px 16px; gap: 14px; }
  .nitem__arw { display: none; }
  .nitem__d b { font-size: 20px; }
  .nitem__t h4 { font-size: 14.5px; -webkit-line-clamp: 2; }
  .nitem__t p { display: none; }
  .tabs { gap: 0; overflow-x: auto; flex-wrap: nowrap; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
  .tabs::-webkit-scrollbar { display: none; }
  .tabs a { padding: 12px 15px; font-size: 14px; }
  .form__row { grid-template-columns: 1fr; }
  .kv li { grid-template-columns: 78px 1fr; gap: 10px; }
  .cinfo li { padding: 16px; }
  .tl { padding-left: 26px; }
  .tl::before { left: 4px; }
  .tl__i::before { left: -26px; width: 10px; height: 10px; border-width: 2.5px; }
  .totop { right: 14px; bottom: 16px; width: 40px; height: 40px; }
  .lb { padding: 20px; }
  .phead { padding-block: 40px; }
  .btn { height: 44px; padding-inline: 22px; font-size: 14px; }
  .btn--lg { height: 48px; }
  .sec-head--c { text-align: left; }
  .sec-head--c .eyebrow, .sec-head--c .lede { margin-inline: 0; justify-content: flex-start; }
  /* 单列布局下横向进场位移会造成左右各 30px 越界，改为纵向位移 */
  .rv-l, .rv-r { transform: translateY(24px); }
  /* 地图占位：aspect-ratio 与 min-height 并存会反推出最小宽度撑破容器，小屏改为固定高度 */
  .map { aspect-ratio: auto; height: 220px; }
}

/* --- 640 以下：导航工具组收紧 --- */
@media (max-width: 640px) {
  .navtools__tel { display: none; }
}

/* --- 440 以下：小屏 ---
   ⚠️ 导航在这一档必须一起收：公司全称从「湖北盈马汽车科技」补成
      「湖北盈马汽车科技有限公司」后多了 3 个字，390px 下会把导航顶宽 1px、
      360px 下宽 10px、320px 下宽 48px（实测）。
      导航这一行是「logo + 全称 + 两个图标 + 汉堡」，全是 flex:none 的硬宽度，
      没有可压缩项，所以只能逐个减。收的顺序按「先动装饰、后动字号」：
      留白 → 图标按钮 → 字号。 */
@media (max-width: 440px) {
  .brand__cn { font-size: 12.5px; letter-spacing: 0; }
  .brand { gap: 9px; }
  .brand img { height: 30px; }
  .nav__in { gap: 9px; }
  .iconbtn { width: 34px; height: 34px; }
  .iconbtn svg { width: 17px; height: 17px; }
  .burger { width: 38px; height: 38px; }
  .gal--3, .gal--4, .gal--5 { grid-template-columns: 1fr; }
  .g2 { grid-template-columns: 1fr; }
  .stats { grid-template-columns: 1fr; }
}

/* --- 350 以下：极窄屏 ---
   上面那一档能让 360px 刚好一排装下（实测内容 324 = 容器 324，一分不剩），
   再窄就只能让公司全称**折成两行**，而不是继续缩字号 ——
   12.5px 折两行仍然读得清，缩到 11px 就只剩「勉强能看」。
   导航行高 66px，两行 12.5px 完全放得下，logo 与图标都不动。
   限幅用 em 而不是 px：字号将来一改，断行位置跟着走。 */
@media (max-width: 350px) {
  .brand__cn {
    white-space: normal;          /* 覆盖 .brand__cn 的 nowrap */
    line-height: 1.14;
    max-width: 6.4em;             /* 6 字一行 →「湖北盈马汽车 / 科技有限公司」 */
  }
}

/* ---------- 24. 打印 ---------- */
@media print {
  /* 页脚不再进隐藏名单：内页旧页脚（.foot）已删除，全站只剩 .foot2。
     它在打印时是有用信息（联系方式 / 地址 / 认证），首页本来就打印，
     现在全站一致。 */
  .nav, .drawer, .totop, .hero2__ctrl { display: none; }
  body { color: var(--ink); }
  .sec { padding-block: 20px; page-break-inside: avoid; }
}

/* ---------- 25. 工具类 ---------- */
.mt-0 { margin-top: 0 !important; }
.mt-1 { margin-top: 8px; }
.mt-2 { margin-top: 16px; }
.mt-3 { margin-top: 24px; }
.mt-4 { margin-top: 34px; }
.mt-5 { margin-top: 48px; }
.mb-2 { margin-bottom: 16px; }
.mb-3 { margin-bottom: 24px; }
.tc { text-align: center; }
.tr { text-align: right; }
.flex { display: flex; }
.fw { flex-wrap: wrap; }
.ac { align-items: center; }
.jb { justify-content: space-between; }
.jc { justify-content: center; }
.gap-1 { gap: 8px; }
.gap-2 { gap: 16px; }
.gap-3 { gap: 24px; }
.hide { display: none !important; }
@media (max-width: 720px) { .hide-sm { display: none !important; } }
@media (min-width: 721px) { .only-sm { display: none !important; } }
/* 跳到主要内容：默认只对读屏器可见，键盘 Tab 到它时浮出为可见按钮 */
.sr {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}
.sr:focus,
.sr:focus-visible {
  position: fixed; top: calc(var(--nav-h) + 12px); left: 50%;
  transform: translateX(-50%);
  z-index: 200;
  width: auto; height: auto; margin: 0; padding: 12px 26px;
  clip: auto; overflow: visible;
  border-radius: 100px;
  background: var(--blue-600); color: var(--on-dark);
  font-size: 14px; font-weight: 600; letter-spacing: .02em;
  box-shadow: 0 16px 38px -12px rgba(6, 26, 54, .6);
  outline: 2px solid var(--on-dark); outline-offset: 2px;
}

/* ==========================================================================
   26. 首页专用（整屏吸附 · 6 屏）
   —— 仅作用于 html.pg-index / body.pg-index，不影响其他页面
   ========================================================================== */

/* ---------- 26.1 滚动吸附与面板基础 ---------- */
html.pg-index { scroll-snap-type: y mandatory; }
/* 首页同样用 clip（理由见第 2 节 body 那条）。
   吸附滚动对滚动容器尤其敏感：body 一旦成为滚动容器，
   scroll-snap-type 挂在 html 上就与它错位，分屏会抖。 */
html.pg-index body { overflow-x: clip; }

/* 六屏：首屏 / 关于 / 产品 / 实力 / 新闻 / 页脚 */
html.pg-index .hero2,
html.pg-index .panel,
html.pg-index .foot2 {
  scroll-snap-align: start;
  scroll-snap-stop: always;
  position: relative;
}
html.pg-index .panel,
html.pg-index .foot2 { min-height: 100svh; }
/* 面板内容垂直居中，并让开固定导航 */
html.pg-index .panel__in {
  min-height: 100svh;
  display: flex; flex-direction: column; justify-content: center;
  padding-top: calc(var(--nav-h) + 30px);
  padding-bottom: clamp(30px, 4vh, 56px);
}
html.pg-index .panel--bg { background: var(--bg-2); }
html.pg-index .panel--news { border-top: 1px solid var(--line-2); }

/* ---------- 产品屏背景：满幅实景底图（蓝色丝带） ---------- */
/* 本屏原先是一层极淡的原生 WebGL 流体色场，现按用户要求换成一张满幅实景图；
   WebGL 那套（.prodbg + prodBends()）已整体移除 —— 背景是真图之后它既看不见、
   又白占一个渲染循环。三条约束：
     ① **它是底图不是内容**：整层 aria-hidden、pointer-events:none；图未加载时
        露出面板自己的浅底，本屏照常可读可点。
     ② **上下边缘必须收回底色**：本屏夹在「关于我们」与「新闻资讯」之间，
        图的上沿偏白、下沿正好是那条深蓝绸带。若不处理，下沿会在两屏交界处
        留下一道硬边。用纵向遮罩把上下各约一成高度淡回底色。
     ③ **卡片必须能从图上"浮"起来**：这张图大面积接近纯白，而产品卡本身的底色
        也是近白的（比本屏底色亮不到 3%）。仅靠原设计那道 12% 透明描边会糊成
        一片，所以本屏的卡片另加一层常驻投影（见下方 .panel--prod .pcard）。 */
html.pg-index .panel--prod { position: relative; background: var(--bg-2); }
html.pg-index .cpbg {
  position: absolute; inset: 0; z-index: 0;
  overflow: hidden; pointer-events: none;
  /* 遮罩取的是 alpha 通道，颜色本身不参与运算 —— 这里用站点的有色近黑
     而不是纯黑，效果完全一致，但守住了「不用纯黑纯白」这条底线。 */
  -webkit-mask-image: linear-gradient(180deg,
      rgba(14, 21, 36, 0) 0%, rgba(14, 21, 36, 1) 9%,
      rgba(14, 21, 36, 1) 91%, rgba(14, 21, 36, 0) 100%);
          mask-image: linear-gradient(180deg,
      rgba(14, 21, 36, 0) 0%, rgba(14, 21, 36, 1) 9%,
      rgba(14, 21, 36, 1) 91%, rgba(14, 21, 36, 0) 100%);
}
html.pg-index .cpbg img {
  display: block; width: 100%; height: 100%;
  object-fit: cover; object-position: center;
}
html.pg-index .panel--prod .panel__in { position: relative; z-index: 1; }

/* 卡片浮起：这张底图最亮处已接近纯白，与卡片自身的底色几乎同明度，
   于是卡片的边界只能靠描边与投影建立。描边从 12% 提到 16%、
   并给一个常驻的中等投影（不是只在悬停时才有）。 */
html.pg-index .panel--prod .pcard {
  border-color: rgba(14, 21, 36, .16);
  box-shadow: 0 14px 34px -14px rgba(16, 33, 72, .20);
}
html.pg-index .panel--prod .pcard:hover {
  box-shadow: 0 22px 50px -14px rgba(16, 33, 72, .30);
}

.panel__head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 24px; flex-wrap: wrap; margin-bottom: clamp(26px, 3.4vw, 46px);
}
.panel__acts { display: flex; flex-wrap: wrap; gap: 12px; }

/* ---------- 26.2 首页导航：浮在浅色 banner 上 → 滚过首屏变白吸顶 ---------- */
html.pg-index .nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 61;
  background: transparent; border-bottom-color: transparent; box-shadow: none;
  backdrop-filter: none;
  transition: background .35s var(--ease),
              box-shadow .35s var(--ease), border-color .35s var(--ease);
}
/* 首屏为银灰浅底：导航文字与 logo 全程保持深色，无需反白切换 */
html.pg-index:not(.is-scrolled) .menu__a::after { background: var(--blue-600); }

/* 滚过首屏：导航吸顶变白 */
html.pg-index.is-scrolled .nav {
  background: rgba(255,255,255,.96); border-bottom-color: var(--line-2);
  box-shadow: var(--sh-2); backdrop-filter: saturate(180%) blur(14px);
}

/* ---------- 26.3 首屏：满幅实景 · 三帧镜头换景 ---------- */
/* 底衬保留一层银灰金属渐变：三帧背景图全部缺席时（图挂了 / 脚本被拦），
   这一层就是本屏的底，文案照常可读。 */
.hero2 {
  position: relative; height: 100svh; min-height: 640px; overflow: hidden;
  color: var(--ink);
  background: linear-gradient(116deg, #f7f9fb 0%, #e7ebef 28%, #d4dae1 58%, #eef1f4 100%);
}
/* 原「斜向金属切面」（.hero2__facet）已整块删除：三帧现在各有一张满幅照片
   盖在上面，这层切面再也照不到，留着就是永不渲染的死代码。 */

.hero2__slides { position: absolute; inset: 0; z-index: 2; }
.hero2__slide {
  position: absolute; inset: 0; opacity: 0; visibility: hidden;
  transition: opacity .95s var(--ease), visibility .95s;
}
.hero2__slide.is-on { opacity: 1; visibility: visible; }

/* 首屏文案错峰进场：切到该张时逐级上浮，形成层次 */
.hero2__slide .hero2__h,
.hero2__slide .hero2__p,
.hero2__slide .hero2__spec,
.hero2__slide .hero2__vow,
.hero2__slide .hero2__btns {
  opacity: 0; transform: translateY(18px);
  transition: opacity .8s var(--ease), transform .95s var(--ease-out);
}
.hero2__slide.is-on .hero2__h    { opacity: 1; transform: none; transition-delay: .06s; }
.hero2__slide.is-on .hero2__p    { opacity: 1; transform: none; transition-delay: .16s; }
.hero2__slide.is-on .hero2__spec,
.hero2__slide.is-on .hero2__vow  { opacity: 1; transform: none; transition-delay: .24s; }
.hero2__slide.is-on .hero2__btns { opacity: 1; transform: none; transition-delay: .32s; }

/* ---------- 满幅实景背景层 ---------- */
/* 三张 banner 各自是一张 1920×1080 的满幅照片，取代了原先右侧那张
   斜切实景卡片 + 悬浮产品抠图 —— 背景本身就是照片时，再叠一张图就是重复。
   该层只作场景不作内容：整层 aria-hidden，文案层压在它之上。 */
.hero2__bg {
  position: absolute; inset: 0; z-index: 0; overflow: hidden;
  background: var(--bg-2);            /* 图未到位时先垫底色，不出现白闪 */
}
.hero2__bg img {
  display: block; width: 100%; height: 100%;
  object-fit: cover; object-position: center;
  /* 推近的起点即基准位；animation 被撤下时由这条过渡把图平滑收回基准位，
     避免切换瞬间出现"啪"地缩一下。这条过渡只在 animation 撤下的那一刻起作用，
     动画运行期间由 animation 接管，两者不打架。 */
  transform: scale(1);
  transition: transform .5s var(--ease-out);
}
/* 文字可读性：左侧压一层极浅的本底白，把标题区从照片里"托"出来。
   浓度刻意压得很低 —— 三张图左侧本就偏亮，重了就把照片糊没了。 */
.hero2__bg::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(100deg,
    rgba(247, 249, 251, .60) 0%,
    rgba(247, 249, 251, .24) 34%,
    rgba(247, 249, 251, 0) 60%);
}

/* ---------- 切换动效：镜头换景（缓慢推近）---------- */
/* 进入的那一张从略大的位置推回原位，读起来像镜头缓缓推近；
   每一次切换重新触发，所以每张图在自己的停留期里始终在轻微移动，
   而不是切过去就死住。全程只动 transform，走合成器。
   时长 6s 刻意略长于自动切换的 5s —— 这样推近永远不会"推完停住"，
   每一帧在整个停留期里都是活的。 */
@keyframes hero2ken {
  from { transform: scale(1.055); }
  to   { transform: scale(1); }
}
.hero2__slide.is-on .hero2__bg img {
  animation: hero2ken 6s cubic-bezier(.22, .68, .28, 1) both;
}

/* ---------- 文案区 ---------- */
.hero2__body {
  position: relative; z-index: 3;
  height: 100%; display: flex; flex-direction: column; justify-content: center;
  padding-top: calc(var(--nav-h) + 40px);
  /* 底部让开控件栏（箭头 / 滚动提示 / 页码） */
  padding-bottom: clamp(96px, 12vh, 132px);
}
.hero2__main { max-width: min(700px, 46vw); }
.hero2__main--vision { max-width: min(640px, 44vw); }

/* 标题上方那行全大写英文小字（eyebrow）已移除，样式一并删除。
   留在这里的原因记录在 index.html 对应位置：三帧的英文都是中文标题的逐字翻译，
   与正文重复。首屏标题现在直接从 .hero2__h 起排。 */

.hero2__h {
  font-size: clamp(30px, 4.3vw, 58px); line-height: 1.14; font-weight: 800;
  color: var(--ink); letter-spacing: -.025em; margin-bottom: 20px;
}
.hero2__h em { font-style: normal; color: var(--blue-600); }
.hero2__p {
  font-size: clamp(14px, 1.05vw, 16px); line-height: 1.9;
  color: var(--ink-2); max-width: 44ch; margin-bottom: 30px;
}
.hero2__btns { display: flex; flex-wrap: wrap; gap: 14px; align-items: center; }
/* 浅色首屏上的描边按钮：默认 --line 过淡，此处加深保证边界清晰 */
.hero2__btns .btn--ghost { border-color: rgba(16, 21, 29, .22); background: rgba(255, 255, 255, .5); }
.hero2__btns .btn--ghost:hover { border-color: var(--blue-600); background: var(--surface); }

/* 参考站式胶囊按钮：主色底 + 尾部白色圆箭头 */
.hero2__cta { padding-right: 8px; gap: 18px; }
.hero2__ctaDot {
  width: 36px; height: 36px; border-radius: 50%; background: var(--surface); color: var(--blue-600);
  display: grid; place-items: center; flex: none;
  transition: transform .3s var(--ease);
}
.hero2__cta:hover .hero2__ctaDot { transform: translateX(3px); }
.hero2__cta:hover svg { transform: none; }
.hero2__ctaDot svg { width: 15px; height: 15px; }

/* 核心产品规格 */
.hero2__spec {
  display: flex; gap: clamp(22px, 3vw, 46px); margin-bottom: 30px;
  padding-top: 22px; border-top: 1px solid rgba(16, 21, 29, .12);
}
.hero2__spec li b {
  display: block; font-family: var(--font-num); font-size: clamp(24px, 2.5vw, 34px);
  font-weight: 700; color: var(--ink); line-height: 1; letter-spacing: -.02em;
}
.hero2__spec li span { display: block; font-size: 13px; color: var(--ink-3); margin-top: 7px; }

/* 企业愿景十六字 */
.hero2__vow { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 30px; }
.hero2__vow em {
  font-style: normal; font-size: 13.5px; font-weight: 600; color: var(--blue-700);
  padding: 8px 18px; border-radius: 100px; letter-spacing: .06em;
  background: rgba(255, 255, 255, .78); border: 1px solid rgba(16, 21, 29, .1);
}

/* ---------- 首屏底部控件栏（左右箭头 + 滚动提示 + 页码，参考图式） ---------- */
/* 与版心对齐：left:50% + 90%/1800px，和 .wrap 完全一致 */
.hero2__ctrl {
  position: absolute; left: 50%; transform: translateX(-50%);
  width: 90%; max-width: var(--maxw);
  bottom: clamp(22px, 3.6vh, 42px); z-index: 6;
  display: flex; align-items: center; justify-content: space-between;
  pointer-events: none;
}
.hero2__ctrl > * { pointer-events: auto; }

/* 左右箭头：左＝描边圆钮，右＝主色实心圆钮 */
.hero2__arrows { display: flex; align-items: center; gap: 12px; }
.hero2__arrow {
  width: 46px; height: 46px; border-radius: 50%; flex: none;
  display: grid; place-items: center; cursor: pointer;
  border: 1px solid rgba(16, 21, 29, .22); background: rgba(255, 255, 255, .66);
  color: var(--ink-2); backdrop-filter: blur(6px);
  transition: background .3s var(--ease), border-color .3s var(--ease),
              color .3s var(--ease), transform .3s var(--ease);
}
.hero2__arrow svg { width: 17px; height: 17px; }
.hero2__arrow:hover { border-color: var(--ink); color: var(--ink); transform: translateY(-2px); }
/* 主色实心圆钮：沿用品牌蓝，与站内 CTA 保持一致（参考图为模板自带红色，此处不照搬） */
.hero2__arrow--next {
  border-color: transparent; background: var(--blue-600); color: var(--on-dark);
  box-shadow: 0 10px 24px -10px rgba(0, 77, 155, .72);
}
.hero2__arrow--next:hover {
  border-color: transparent; background: var(--blue-700, #003c79); color: var(--on-dark);
}

/* 中部鼠标滚动提示：胶囊 + 内圆点循环下落 */
.hero2__mouse {
  position: absolute; left: 50%; transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: 9px;
  color: var(--ink-4); font-size: 12px; letter-spacing: .18em; text-transform: uppercase;
}
.hero2__mouse i {
  display: block; width: 24px; height: 38px; border-radius: 100px;
  border: 1.5px solid rgba(16, 21, 29, .3); position: relative;
}
.hero2__mouse i::after {
  content: ""; position: absolute; left: 50%; top: 7px;
  width: 3px; height: 7px; border-radius: 100px; background: var(--ink-3);
  transform: translateX(-50%);
  animation: hero2wheel 1.9s var(--ease) infinite;
}
@keyframes hero2wheel {
  0%   { opacity: 0; transform: translate(-50%, 0); }
  22%  { opacity: 1; }
  72%  { opacity: 1; transform: translate(-50%, 13px); }
  100% { opacity: 0; transform: translate(-50%, 17px); }
}

/* 右下页码：当前序号大号 + 横线 + 其余序号小号，可点切换 */
.hero2__pager {
  display: flex; align-items: center; gap: 12px;
  font-family: var(--font-num); line-height: 1;
}
.hero2__pager button {
  padding: 0; margin: 0; border: 0; background: none; cursor: pointer;
  font: inherit; color: var(--ink-4); font-size: 13px; letter-spacing: .06em;
  transition: color .3s var(--ease), font-size .35s var(--ease);
}
.hero2__pager button:hover { color: var(--ink); }
.hero2__pager button.is-on {
  font-size: 24px; font-weight: 700; color: var(--ink); letter-spacing: -.01em;
  pointer-events: none;
}
/* 排序：当前序号 → 横线 → 其余序号（由 JS 仅切 .is-on，顺序自动重排） */
.hero2__pager button.is-on { order: 1; }
.hero2__pager button:not(.is-on) { order: 3; }
.hero2__pager i {
  display: block; width: clamp(26px, 3.4vw, 46px); height: 1px;
  background: rgba(16, 21, 29, .3); flex: none; order: 2;
}

/* ---------- 26.4 关于我们 ---------- */
/* 工业纹理底：细斜纹 + 网格 + 顶部渐隐，避免纯色发闷 */
html.pg-index .panel--about {
  /* 图片揭示遮罩色跟随本屏纹理底色，避免扫过时出现白色色块 */
  --rv-mask: #eef1f6;
  background-color: #f4f6f9;
  background-image:
    /* 细斜纹（45° 工业拉丝感） */
    repeating-linear-gradient(45deg,
      rgba(16, 21, 29, .028) 0 1px, rgba(16, 21, 29, 0) 1px 7px),
    /* 大网格 */
    linear-gradient(rgba(16, 21, 29, .022) 1px, transparent 1px),
    linear-gradient(90deg, rgba(16, 21, 29, .022) 1px, transparent 1px),
    /* 右上冷光 + 左下暖白，制造体积感 */
    radial-gradient(120% 90% at 88% 6%, rgba(0, 77, 155, .07), rgba(0, 77, 155, 0) 60%),
    linear-gradient(160deg, #fbfcfd 0%, #eef1f5 46%, #e7ebf0 100%);
  background-size: auto, 62px 62px, 62px 62px, auto, auto;
  background-position: 0 0, 0 0, 0 0, 0 0, 0 0;
}
/* 纹理上加一层极淡噪点，压掉塑料感 */
html.pg-index .panel--about::before {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  opacity: .5;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.055'/%3E%3C/svg%3E");
}
html.pg-index .panel--about > .wrap { position: relative; z-index: 1; }

/* 数据条：凸显数字 —— 加大字号、主色强调、数字下方一条短线托底
   （列与列之间不画竖分隔线：四栏已由等宽内边距区隔，再加一根竖线会把整排切碎） */
html.pg-index .stats--line { background: transparent; gap: 0; }
html.pg-index .stats--line .stat {
  background: transparent;
  padding: 0 clamp(16px, 2.1vw, 30px);
}
html.pg-index .stats--line .stat:first-child { padding-left: 0; }
html.pg-index .stats--line .stat__n {
  font-size: clamp(36px, 3.9vw, 60px); line-height: 1;
  letter-spacing: -.03em;
}
/* 只给数字本身着色。用子选择器而不是后代选择器：
   .roll__k（滚动用的隐形占位字）必须保持 transparent，
   否则它会与上层滚动窗里的数字叠成双影 */
html.pg-index .stats--line .stat__n > span { color: var(--blue-600); }
html.pg-index .stats--line .stat__n em {
  font-size: .46em; font-weight: 700; margin-left: 3px; vertical-align: super;
  letter-spacing: 0;
}
html.pg-index .stats--line .stat__l {
  font-size: 13px; color: var(--ink-3); margin-top: 12px;
  padding-top: 12px; border-top: 1px solid var(--line);
  letter-spacing: .02em;
}
/* 关于我们：数字条从左侧文字栏里搬出来，改为横跨整幅版心的通栏秤砣
   —— 两栏只留「文字 + 宣传片」，上下分层，节奏更清楚
   （不画通栏顶线：每列标签上方的短线已经足够分隔，多一条横线会显脏） */
html.pg-index .panel--about .stats--line {
  margin-top: 80px;
  flex: none;
}

/* ---------- 数字滚动（里程表式） ----------
   每一位数字是一根 0-9 两圈的纵向滚轮，靠 translateY 滚到目标位。
   关键在把结构分成两层：
     .roll__k 留在正常流里、用 transparent 藏起来 —— 它负责列宽、行高基线与
               读屏朗读/复制粘贴时的真实数值；
     .roll__w 是绝对定位的 1em 高裁切窗，overflow:hidden 只加在它身上。若把这层
               直接写在 .roll__d 上，inline-block 的基线会按规范退化成盒子底边，
               整排数字会被顶上去半行。
   起止落在同一个数字上（终点前进一整圈），于是「滚一轮、停回原值」——
   看得见滚动，又不会先显示一串 0；无 JS、打印、减少动态效果时显示的仍是正确数值。 */
.roll { display: inline; font-variant-numeric: tabular-nums; }
.roll__d { position: relative; display: inline-block; }
/* 内联块之间不吃 letter-spacing，这里用负外边距还原 .stat__n 的字距 */
.roll__d, .roll__c { letter-spacing: 0; margin-right: -.03em; }
.roll__c { display: inline-block; }
.roll__k { color: transparent; }
.roll__w {
  position: absolute; left: 0; top: 0; right: 0; height: 1em; overflow: hidden;
  pointer-events: none; user-select: none; -webkit-user-select: none;
}
.roll__t {
  display: block; will-change: transform;
  transform: translateY(calc(var(--r0, 0) * -1em));
  /* 缓出偏线性：尾部不要拖太久，否则「半数字」的中间态会在结尾挂着不动 */
  transition: transform var(--roll-dur, 880ms) cubic-bezier(.25, .8, .25, 1);
}
.roll__t > span { display: block; height: 1em; line-height: 1; text-align: center; }
.roll.is-in .roll__t { transform: translateY(calc(var(--r1, 0) * -1em)); }
/* 高位先停、末位最后停：落地有先有后才像机械表 */
.roll__d:nth-of-type(1) .roll__t { transition-delay: 0ms; }
.roll__d:nth-of-type(2) .roll__t { transition-delay: 40ms; }
.roll__d:nth-of-type(3) .roll__t { transition-delay: 80ms; }
.roll__d:nth-of-type(4) .roll__t { transition-delay: 120ms; }
.roll__d:nth-of-type(5) .roll__t { transition-delay: 160ms; }
.roll__d:nth-of-type(n+6) .roll__t { transition-delay: 200ms; }
@media (prefers-reduced-motion: reduce) {
  .roll__t { transition: none; }
}
/* 强制色模式下 transparent 会被系统改成前景色、与窗内数字叠成双影 —— 退回静态数字 */
@media (forced-colors: active) {
  .roll__w { display: none; }
  .roll__k { color: inherit; }
}

figure.figure--sh { box-shadow: var(--sh-3); }

/* ---------- 企业宣传视频（关于我们 · 右上） ---------- */
.aboutvideo {
  position: relative; margin: 0; border-radius: var(--r-md); overflow: hidden;
  background: #0d1420; box-shadow: var(--sh-3);
  /* 16:10 画幅：右侧独立成像，与左侧文字栏等高区 */
  aspect-ratio: 16 / 10;
}
.aboutvideo video {
  display: block; width: 100%; height: 100%; object-fit: cover;
}
/* 播放前：封面图 + 主色蒙版；播放后整体隐藏
   注：宣传片全程烧入双语字幕。封面若按比例铺满，底部会与 .aboutvideo__tag 叠成两层字，
   故将封面纵向放大并把溢出全部推向底边，把字幕条挤出可视区。 */
.aboutvideo__cover {
  position: absolute; inset: 0; z-index: 2;
  display: grid; place-items: center; cursor: pointer;
  background-color: #0d1420;
  background-repeat: no-repeat;
  background-position: center top;
  background-size: auto 127%;
  transition: opacity .5s var(--ease), visibility .5s;
}
.aboutvideo.is-playing .aboutvideo__cover { opacity: 0; visibility: hidden; pointer-events: none; }
/* 默认蒙版：品牌蓝半透明，统一色调的同时把播放钮托起来 */
.aboutvideo__cover::before {
  content: ""; position: absolute; inset: 0;
  background:
    linear-gradient(180deg,
      rgba(0, 61, 124, .34) 0%,
      rgba(0, 77, 155, .42) 46%,
      rgba(3, 18, 40, .76) 100%),
    linear-gradient(0deg, rgba(0, 110, 204, .16), rgba(0, 110, 204, .16));
}
/* 播放按钮：主色实心（脉冲圆环外扩） */
.aboutvideo__btn {
  position: relative; z-index: 1;
  width: clamp(62px, 5.4vw, 82px); height: clamp(62px, 5.4vw, 82px);
  border: 0; border-radius: 50%; cursor: pointer;
  background: var(--blue-600); color: var(--on-dark);
  box-shadow: 0 12px 30px -8px rgba(0, 38, 78, .62),
              inset 0 0 0 1px rgba(255, 255, 255, .18);
  display: grid; place-items: center;
  transition: background .3s var(--ease), transform .3s var(--ease),
              box-shadow .3s var(--ease);
}
.aboutvideo__btn svg { width: 26px; height: 26px; margin-left: 3px; }
.aboutvideo__btn::before,
.aboutvideo__btn::after {
  content: ""; position: absolute; inset: 0; border-radius: 50%;
  border: 1.5px solid rgba(174, 208, 244, .82);
  animation: avPulse 2.4s var(--ease-out) infinite;
}
.aboutvideo__btn::after { animation-delay: 1.2s; }
@keyframes avPulse {
  0%   { transform: scale(1); opacity: .75; }
  100% { transform: scale(1.85); opacity: 0; }
}
.aboutvideo__cover:hover .aboutvideo__btn {
  background: var(--blue-500); transform: scale(1.06);
  box-shadow: 0 16px 38px -8px rgba(0, 38, 78, .7),
              inset 0 0 0 1px rgba(255, 255, 255, .26);
}
/* 封面上的说明标签 */
.aboutvideo__tag {
  position: absolute; z-index: 1; left: clamp(14px, 1.6vw, 22px); bottom: clamp(14px, 1.6vw, 22px);
  right: clamp(14px, 1.6vw, 22px);
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  color: var(--on-dark); font-size: 13px; letter-spacing: .04em;
  text-shadow: 0 1px 14px rgba(4, 10, 20, .8), 0 1px 3px rgba(4, 10, 20, .6);
}
.aboutvideo__tag b { font-size: clamp(14px, 1.15vw, 16px); font-weight: 700; display: block; }
.aboutvideo__tag span { opacity: .9; }
/* 播放中的原生控制条 */
.aboutvideo video::-webkit-media-controls-panel { background-image: linear-gradient(transparent, rgba(0,0,0,.55)); }

/* ---------- 26.5 产品展示 ---------- */
/* 板块名称标签（左侧，参考图式：蓝色竖条 + 小字） */

/* 右侧：翻页器（描边圆钮 + 页码 + 主色圆钮） */
.prodnav { display: flex; align-items: center; gap: clamp(14px, 1.8vw, 26px); }
.prodnav__pg { display: flex; align-items: center; gap: 12px; }
.prodnav__n {
  font-family: var(--font-num); font-size: 13px; color: var(--ink-4); letter-spacing: .06em;
  line-height: 1; min-width: 2.4em; text-align: right;
}
.prodnav__n b { font-size: 24px; font-weight: 700; color: var(--blue-600); letter-spacing: -.01em; }
.prodnav__btn {
  width: 46px; height: 46px; border-radius: 50%; flex: none;
  display: grid; place-items: center; cursor: pointer;
  border: 1px solid rgba(16, 21, 29, .2); background: var(--surface); color: var(--ink-2);
  transition: background .3s var(--ease), border-color .3s var(--ease),
              color .3s var(--ease), transform .3s var(--ease), opacity .3s var(--ease);
}
.prodnav__btn svg { width: 17px; height: 17px; }
.prodnav__btn:hover { border-color: var(--ink); color: var(--ink); transform: translateY(-2px); }
.prodnav__btn--next {
  border-color: transparent; background: var(--blue-600); color: var(--on-dark);
  box-shadow: 0 10px 24px -10px rgba(0, 77, 155, .72);
}
.prodnav__btn--next:hover { background: var(--blue-700, #003c79); color: var(--on-dark); }
.prodnav__btn[disabled] { opacity: .32; cursor: not-allowed; transform: none; }

/* 产品卡：横向滚动轨道（翻页器与之联动） */
.pgrp {
  display: flex; gap: clamp(14px, 1.6vw, 24px);
  overflow-x: auto; overflow-y: hidden;
  scroll-snap-type: x mandatory; scroll-behavior: smooth;
  /* 纵向留出 hover 上浮与投影的空间，横向负外边距让首尾卡片贴版心 */
  padding: 6px 0 14px;
  scrollbar-width: none; -ms-overflow-style: none;
}
.pgrp::-webkit-scrollbar { display: none; }
.pgrp > .pcard {
  flex: 0 0 calc((100% - 3 * clamp(14px, 1.6vw, 24px)) / 4);
  scroll-snap-align: start;
  min-width: 0;
}
.pcard {
  display: flex; flex-direction: column; background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--r-md); overflow: hidden;
  transition: transform .35s var(--ease), box-shadow .35s var(--ease), border-color .35s var(--ease);
}
.pcard:hover { transform: translateY(-6px); box-shadow: var(--sh-3); border-color: var(--blue-200); }
.pcard__im { position: relative; aspect-ratio: 4 / 3; overflow: hidden; background: var(--bg-3); }
.pcard__im img { width: 100%; height: 100%; object-fit: cover; transition: transform .6s var(--ease); }
.pcard:hover .pcard__im img { transform: scale(1.06); }
.pcard__bd { padding: clamp(16px, 1.7vw, 24px); display: flex; flex-direction: column; flex: 1; }
.pcard__no {
  font-size: 12.5px; font-weight: 700; letter-spacing: .1em; color: var(--blue-600);
  margin-bottom: 9px;
}
.pcard__bd h3 { margin-bottom: 9px; }
.pcard__bd p { font-size: 13.4px; line-height: 1.72; color: var(--ink-3); margin-bottom: 14px; }
.pcard__tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: auto; }
.pcard__tags i {
  font-style: normal; font-size: 12.5px; padding: 3px 10px; border-radius: 100px;
  background: var(--blue-50); color: var(--blue-700); border: 1px solid var(--blue-100);
}

/* ---------- 26.6 新闻资讯（单行双端头部 + 三张新闻大卡 + 三条竖式图文卡） ---------- */
/* 注：原「实力展示」（.pgrid/.pfeats/.pfeat/.plab/.pcert）随首页该屏一并移除。
   相关能力与证书内容现分别位于 technology.html 与 honors.html。

   高度预算 · 本屏是整屏吸附块，内容高必须小于「视口 − 导航 − 上下留白」，
   否则滚动吸附会卡在半屏。桌面 1440×900 可用约 758px，实测分配：
     头部 ≈ 150 · 三张大卡 ≈ 295 · 间距 23 · 三条竖卡 ≈ 245  →  713
   所以卡片配图一律走「受控高度」（vw 流式 + clamp 封顶），
   而不是交给 aspect-ratio 跟着列宽无限长高 —— 列宽从 320 涨到 415 时，
   16:10 的图会从 200px 一路涨到 260px，直接把本屏顶出视口。 */

/* 头部：左「板块标签 + 主标题」／右「分类页签 + 更多资讯」，双端对齐 */
html.pg-index .newsx__head { align-items: flex-end; margin-bottom: clamp(22px, 2.8vw, 40px); }
html.pg-index .newsx__hdL { min-width: 0; }
html.pg-index .newsx__hdR {
  display: flex; align-items: center; gap: clamp(14px, 1.6vw, 26px);
  flex-wrap: wrap; justify-content: flex-end;
}
html.pg-index .newsx__h { font-size: clamp(24px, 2.34vw, 36px); line-height: 1.15; }

/* 标题单行升起：.ln 是裁切窗，内层 span 自下方归位。
   以终态撰写（内层默认停在原位），初始位移只作为「预备态」施加。
   主标题只有一行，因此没有第二条的错峰延迟。 */
html.pg-index .newsx__h .ln { display: block; overflow: hidden; padding-bottom: .09em; margin-bottom: -.09em; }
html.pg-index .newsx__h .ln > span { display: block; transform: translateY(112%); transition: transform .84s var(--ease-out); }
html.pg-index .newsx__head.is-in .newsx__h .ln > span { transform: none; }

/* 分类页签：横排胶囊，落在右上角 */
html.pg-index .newsx__tabs { display: flex; align-items: center; gap: clamp(6px, .6vw, 10px); }
html.pg-index .newsx__tab {
  padding: 8px 16px; border: 1px solid var(--line); border-radius: 100px;
  background: var(--surface); cursor: pointer; font: inherit;
  font-size: 13px; font-weight: 600; color: var(--ink-3); white-space: nowrap;
  transition: color .26s var(--ease), background-color .26s var(--ease), border-color .26s var(--ease);
}
html.pg-index .newsx__tab:hover { color: var(--blue-600); border-color: var(--blue-200); }
html.pg-index .newsx__tab.is-on { background: var(--blue-600); border-color: var(--blue-600); color: var(--on-dark); }

/* 「更多资讯 →」：轻量文字链，与分类同排但不抢戏 */
html.pg-index .newsx__more {
  display: inline-flex; align-items: center; gap: 8px; white-space: nowrap;
  font-size: 13.5px; font-weight: 600; color: var(--ink-2);
  transition: color .26s var(--ease);
}
html.pg-index .newsx__more svg { width: 14px; height: 14px; transition: transform .3s var(--ease); }
html.pg-index .newsx__more:hover { color: var(--blue-600); }
html.pg-index .newsx__more:hover svg { transform: translateX(4px); }

/* 三列矩阵（左图文大卡 ／ 中主色重点卡 ／ 右横式小卡列表）。
   列宽 1 : 1 : 1.06 —— 右列装的是「左缩略图 + 文字」，比纯文字列更吃宽。
   刻意不用 grid-template-areas：命名区域会把卡片钉死在固定格位，
   点分类过滤后中间留出空洞；自动流让命中的卡片自己靠拢重排。 */
html.pg-index .newsx {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1.06fr);
  gap: clamp(14px, 1.5vw, 24px);
  align-items: stretch;
}
html.pg-index .newsx > * { min-width: 0; }

/* 通用新闻卡 */
html.pg-index .ncard {
  position: relative; display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md);
  overflow: hidden; height: 100%;
  transition: transform .42s var(--ease-out), box-shadow .42s var(--ease), border-color .42s var(--ease);
}
html.pg-index .ncard:hover { transform: translateY(-6px); box-shadow: var(--sh-3); border-color: var(--blue-200); }
/* 配图：受控高度（见段首高度预算说明）。
   大卡的图改用 flex:1 吃掉列高差 —— 右列四条把它撑多高，图就长多高，
   文字区固定贴底，所以永远不会有「卡片被拉长后中间留一块空白」的情况。 */
html.pg-index .ncard__im { position: relative; height: clamp(126px, 10.2vw, 176px); overflow: hidden; background: var(--bg-3); flex: none; }
html.pg-index .ncard__im img { width: 100%; height: 100%; object-fit: cover; transition: transform .8s var(--ease-out); }
html.pg-index .ncard:hover .ncard__im img { transform: scale(1.06); }
/* ⚠️ 大卡图区必须用绝对定位图层，不能只写 flex:1 + height:100%。
   原因：图区高度 = 卡片高 − 文字区高，而卡片高在三列布局下由 grid 的 stretch 决定；
   一旦筛掉其他列、列数减少，这个「确定高度」就没了 —— flex:1 会退化成 auto，
   于是内部 height:100% 的图片改按自身原始比例撑开（1440 实测 454 → 581px，
   列变少反而更高）。改成绝对定位后，图片不参与父级高度计算，
   图区高度纯由 flex 分配或 min-height 兜底，两种情况都稳定。 */
html.pg-index .ncard--lead .ncard__im { flex: 1; height: auto; min-height: clamp(150px, 12.5vw, 214px); }
html.pg-index .ncard--lead .ncard__im img { position: absolute; inset: 0; }
html.pg-index .ncard--lead .ncard__bd { flex: none; }
html.pg-index .ncard__bd { padding: clamp(14px, 1.4vw, 20px); display: flex; flex-direction: column; flex: 1; }
/* 日期：大号日 + 斜杠 + 月份，年份推到最右（参考图式 16 / 8……2021）。
   斜杠走 ::before 生成，HTML 里只保留纯数字，语义不掺排版字符。 */
html.pg-index .ndate { display: flex; align-items: baseline; gap: 7px; margin-bottom: 10px; }
html.pg-index .ndate b { font-family: var(--font-num); font-size: 26px; font-weight: 700; line-height: 1; letter-spacing: -.02em; color: var(--ink); }
html.pg-index .ndate i { font-style: normal; font-family: var(--font-num); font-size: 13px; color: var(--ink-4); }
html.pg-index .ndate i::before { content: "/"; margin-right: 7px; opacity: .5; }
html.pg-index .ndate em { font-style: normal; font-size: 12.5px; color: var(--ink-4); margin-left: auto; letter-spacing: .04em; }
html.pg-index .ncard__bd h3 {
  font-size: clamp(14px, 1.06vw, 15.5px); line-height: 1.55; font-weight: 700; color: var(--ink);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  transition: color .25s var(--ease);
}
html.pg-index .ncard:hover .ncard__bd h3 { color: var(--blue-600); }
html.pg-index .ncard__bd p {
  font-size: 13.5px; line-height: 1.7; color: var(--ink-3); margin-top: 9px;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}

/* 重点卡：主色实底。日期是这张卡的视觉锚点，放大到全组最大；
   内容用 space-between —— 日期组在上、按钮沉底，中间那块留白与参考图一致。 */
html.pg-index .ncard--blue {
  background: var(--blue-600); border-color: transparent; color: var(--on-dark);
}
html.pg-index .ncard--blue:hover { border-color: transparent; box-shadow: var(--sh-3); }
html.pg-index .ncard--blue .ncard__bd { justify-content: flex-start; }
html.pg-index .ncard--blue .ncard__bd h3 { color: var(--on-dark); font-size: clamp(15px, 1.16vw, 17px); }
html.pg-index .ncard--blue:hover .ncard__bd h3 { color: var(--on-dark); }
html.pg-index .ncard--blue .ncard__bd p { color: rgba(255, 255, 255, .78); }
html.pg-index .ncard--blue .ndate { margin-bottom: 14px; }
html.pg-index .ncard--blue .ndate b { font-size: clamp(32px, 2.9vw, 44px); letter-spacing: -.03em; }
html.pg-index .ncard--blue .ndate b, html.pg-index .ncard--blue .ndate i, html.pg-index .ncard--blue .ndate em { color: var(--on-dark); }
html.pg-index .ncard--blue .ndate i, html.pg-index .ncard--blue .ndate em { opacity: .7; }
html.pg-index .ncard--blue .ncard__go { margin-top: auto; padding-top: 14px; }
html.pg-index .ncard__go {
  margin-top: 14px; display: inline-flex; align-items: center; gap: 9px;
  font-size: 13px; font-weight: 600; color: var(--on-dark);
}
html.pg-index .ncard__go span {
  width: 30px; height: 30px; border-radius: 50%; background: var(--surface); color: var(--blue-600);
  display: grid; place-items: center; flex: none; transition: transform .36s var(--ease-out) .05s;
}
html.pg-index .ncard__go svg { width: 13px; height: 13px; }
html.pg-index .ncard--blue:hover .ncard__go span { transform: translateX(4px); }
/* 蓝色卡装饰底纹：悬停时缓慢外扩，给实底一点呼吸（纯装饰，移除不影响信息） */
html.pg-index .ncard--blue::after {
  content: ""; position: absolute; right: -34px; bottom: -34px; width: 150px; height: 150px;
  border-radius: 50%; background: rgba(255, 255, 255, .07); pointer-events: none;
  transition: transform .9s var(--ease-out);
}
html.pg-index .ncard--blue:hover::after { transform: scale(1.32); }

/* 右列：横式小卡列表（左缩略图 + 右标题与分类）。
   grid-auto-rows: 1fr 让四条等高、整列撑满 —— 列高由它与大卡共同决定。
   缩略图宽度走百分比列定义而不是固定像素，随列宽自然伸缩。 */
html.pg-index .newsx__mini {
  display: grid; grid-auto-rows: 1fr;
  gap: clamp(10px, .9vw, 14px);
  min-width: 0;
}
html.pg-index .newsx__mini.is-off { display: none; }
/* 筛选后右列可能只剩一两条：让它们按自然高度收到顶部，
   否则 1fr 会把单条拉成一整列高（比左侧大卡还高），整屏比例就散了。
   注意这里给的是「行高上限」而不是 1fr —— 上限让卡片保持舒服的横式比例。 */
html.pg-index .newsx__mini.is-loose { align-content: start; grid-auto-rows: clamp(96px, 8.6vw, 132px); }
/* 其余两列都被筛掉、右列独占整宽时：内部并成两列，
   否则单张横式卡会横跨 1400px，缩略图被拉成一条巨幅照片。 */
html.pg-index .newsx__mini.is-wide {
  grid-template-columns: repeat(2, 1fr);
  grid-auto-rows: clamp(96px, 12vw, 128px);
  align-content: start;
}
/* 只剩一条：整幅单张，高度按横式卡的自然比例给，不撑满 */
html.pg-index .newsx__mini.is-solo {
  grid-template-columns: 1fr;
  grid-auto-rows: clamp(96px, 7.4vw, 124px);
  align-content: start;
}
html.pg-index .nmini {
  position: relative; display: grid; grid-template-columns: 38% 1fr;
  min-width: 0; min-height: 0; overflow: hidden;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md);
  transition: transform .42s var(--ease-out), box-shadow .42s var(--ease), border-color .42s var(--ease);
}
/* 悬停＝「被拉起」：整条右移、图反向并推近、箭头最后甩出。
   三个动作的 duration 与 delay 各不相同（.42 / .8 / .42+.07），
   尾巴长度不一致才有惯性感 —— 全部同速同延迟只会读成一次生硬的位移。 */
html.pg-index .nmini:hover { transform: translateX(6px); box-shadow: var(--sh-3); border-color: var(--blue-200); }
html.pg-index .nmini__im { position: relative; height: 100%; min-height: 0; overflow: hidden; background: var(--bg-3); }
html.pg-index .nmini__im img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transition: transform .8s var(--ease-out); }
html.pg-index .nmini:hover .nmini__im img { transform: scale(1.09) translateX(-7px); }
html.pg-index .nmini__bd { padding: clamp(11px, 1vw, 15px); display: flex; flex-direction: column; min-width: 0; }
html.pg-index .nmini__bd b {
  font-size: clamp(13px, .95vw, 13.8px); line-height: 1.5; font-weight: 600; color: var(--ink-2);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  transition: color .25s var(--ease), transform .5s var(--ease-out);
}
html.pg-index .nmini:hover .nmini__bd b { color: var(--blue-600); transform: translateX(2px); }
html.pg-index .nmini__ft {
  margin-top: auto; padding-top: 8px;
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
}
html.pg-index .nmini__cat {
  display: inline-flex; align-items: center; gap: 7px; min-width: 0;
  font-size: 12px; color: var(--ink-4); letter-spacing: .04em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
html.pg-index .nmini__cat::before {
  content: ""; width: 5px; height: 5px; border-radius: 50%; background: var(--blue-400); flex: none;
}
html.pg-index .nmini__arw {
  width: 24px; height: 24px; border-radius: 50%; flex: none;
  display: grid; place-items: center;
  background: var(--blue-50); color: var(--blue-600);
  transition: transform .42s var(--ease-out) .07s, background-color .3s var(--ease);
}
html.pg-index .nmini__arw svg { width: 13px; height: 13px; }
html.pg-index .nmini:hover .nmini__arw { transform: translateX(6px); background: var(--blue-100); }

/* 小卡错峰入场：与三张大卡共享同一个 .newsx.is-in 触发点。
   刻意不在这里再挂 .rvk —— 嵌套两层会让「整块升起」和「逐条升起」叠在一起。 */
html.pg-index .newsx__mini > .nmini { opacity: 0; }
html.pg-index .newsx.is-in .newsx__mini > .nmini { opacity: 1; animation: rvKid .74s var(--ease-out) backwards; }
html.pg-index .newsx.is-in .newsx__mini > .nmini:nth-child(2) { animation-delay: .1s; }
html.pg-index .newsx.is-in .newsx__mini > .nmini:nth-child(3) { animation-delay: .18s; }
html.pg-index .newsx.is-in .newsx__mini > .nmini:nth-child(4) { animation-delay: .26s; }

/* 动效降级：悬停位移与装饰扩散全部取消，卡片回到纯静态可读可点。
   注意这里只关过渡、把终态显式写回，不改任何布局尺寸 ——
   reduced-motion 要的是「同样的构图，只是不动」。 */
@media (prefers-reduced-motion: reduce) {
  html.pg-index .ncard,
  html.pg-index .nmini,
  html.pg-index .ncard__im img,
  html.pg-index .nmini__im img,
  html.pg-index .nmini__bd b,
  html.pg-index .nmini__arw,
  html.pg-index .ncard__go span,
  html.pg-index .ncard--blue::after { transition: none; }
  html.pg-index .ncard:hover,
  html.pg-index .nmini:hover { transform: none; }
  html.pg-index .ncard:hover .ncard__im img,
  html.pg-index .nmini:hover .nmini__im img { transform: none; }
  html.pg-index .ncard--blue:hover::after { transform: none; }
  html.pg-index .nmini:hover .nmini__arw { transform: none; }
  html.pg-index .nmini:hover .nmini__bd b { transform: none; }
  html.pg-index .ncard--blue:hover .ncard__go span { transform: none; }
  html.pg-index .newsx__mini > .nmini { opacity: 1; animation: none; }
}

/* 分类过滤：未命中的卡片收起，命中的卡片交给 View Transitions 自己移位 */
html.pg-index .panel--news .is-off { display: none; }

/* 分类重排过渡（R3 · View Transitions）
   root 的整页交叉淡化关掉（否则整屏会闪一下），只留六个命名卡片做 FLIP；
   未支持的浏览器直接落到「瞬间重排」，功能不受影响。 */
::view-transition-group(*) {
  animation-duration: .46s;
  animation-timing-function: cubic-bezier(.22, .8, .24, 1);
}
::view-transition-old(root), ::view-transition-new(root) { animation: none; }
@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation-duration: .001ms !important; }
}

/* ---------- 26.7 页脚（首页版） ----------
   结构分两段：
     · 上段 = 一整块「合作伙伴」展示区：实景底图从这一段的**最顶**铺起，
       标题行与 logo 带都落在图上
     · 下段 = 提亮一档的深色底（--dark-3），装主内容与版权条
   整屏吸附要求 footer 恰好一屏高，所以上段用 flex: 1 吃掉剩余空间、
   下段由内容撑开 —— 内容不足一屏时上段自动变高，更接近「各占一半」的观感；
   内容偏多时由上段 min-height 兜底，再由高度档分级压缩。

   ⚠️ 2026-09-30 二次调整：导航避让的留白（--foot2-avoid）从 .foot2 的 padding
      搬进了 .foot2__top 的 padding-top。原因是底图要覆盖到板块最顶 ——
      留白只要还挂在 .foot2 上，那一条就永远是 .foot2 的纯底色，底图顶不上去。
      搬完总量守恒（.foot2 少 100px、.foot2__top 多 100px，后者是 flex:1，
      高度由 footer 决定），所以整屏吸附的高度预算不受影响。 */
.foot2 {
  background: var(--dark-3);
  /* 底色抬亮后，页脚内的小字必须同步提亮，否则 13px 级文字对比度会跌破 4.5:1
     （.50 白的合成色压在 #112A4C 上约 4.46:1，抬到 .60 后约 5.75:1） */
  --on-dark-3: rgba(245, 248, 255, .60);
  /* --foot2-avoid：让开固定导航的留白，由上段的 padding-top 承担
     --foot2-pad  ：上段的上下呼吸，各高度档单独收紧 */
  --foot2-avoid: calc(var(--nav-h) + clamp(20px, 2.6vh, 40px));
  --foot2-pad: clamp(38px, 5.2vh, 68px);
  color: var(--on-dark-3);
  display: flex; flex-direction: column;
}

/* ---------- 26.7.0 上段 · 合作伙伴（实景底图 + 白卡 logo 轨道） ----------
   背景是一张商务实景照，标题与链接直接压在照片上。

   ⚠️ padding-top 里含 --foot2-avoid（导航避让留白）——
      底图的 inset 是 0，所以留白那一条也在图上，整段从顶到底没有纯色带。

   ⚠️ 这里刻意不用 justify-content:center：
      标题行必须**贴在上段顶部**（距顶恰好 = padding-top），承托层（26.8.2）
      才能拿 padding 值算出自己的起点。若整体居中，标题的实际位置会随
      「logo 带占多高」浮动，承托层就找不到自己的锚点了。
      所以改成：标题贴顶；logo 带用 margin-block:auto 在**剩余空间**里居中
      —— 观感与原来的「整组居中」几乎一致，但标题位置变成确定的。 */
.foot2__top {
  position: relative; isolation: isolate; overflow: hidden;
  flex: 1 1 auto;
  min-height: clamp(272px, 40vh, 424px);
  display: flex; flex-direction: column;
  padding-top: calc(var(--foot2-avoid) + var(--foot2-pad));
  padding-bottom: var(--foot2-pad);
}
/* 背景层：只放底图本体，不叠任何东西。

   ⚠️ 2026-09-30 按要求去掉了原先的「柔化白雾 + 底部收尾渐变」两层，
      底图现在按原始反差直接呈现，也不再向上/向下做任何过渡 ——
      上段与下段的交界是一道干净的直边。

   ⚠️ background-position 取 top（顶对齐）：
     底图是 3.56:1 的宽幅，容器比例视视口在 3.1–4.8 之间浮动，cover 必然在
     某个方向裁掉一条。裁切一律从底部吃掉（`top`），保证画面里人物的头顶、
     窗格上沿永远完整 —— 构图重心在画面上部，底部裁掉的是桌面与暗角。
     这条比居中裁切更稳：居中时「衣服/墙面」这类高频细节会随视口高度上下游走，
     标题正好压在哪一段完全不可控。

   ⚠️ 去蒙版后文字的可读性由「标题带的顶部压暗渐隐」承担，见 26.8.2。
     那是一条只覆盖标题那一小段的柔化层，不是整幅 —— 不要在底图上重新加回
     全幅柔化层，那会把实景洗成一片奶白，也就是第一轮要去掉的东西。 */
.foot2__topBg {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background-image: url('../img/foot/partners-bg.jpg');
  background-size: cover;
  background-position: top center;
  background-repeat: no-repeat;
}
/* ⚠️ .wrap 必须自己撑满上段的内容高度，否则里面的 margin-block:auto 无处可算
   （.wrap 是 block，高度 hug 内容时 logo 带会直接贴在标题下面、下段空一大片）。
   撑开后 logo 带就能在「标题以下的剩余空间」里居中。 */
.foot2__top > .wrap {
  position: relative; z-index: 1;
  flex: 1 1 auto; display: flex; flex-direction: column;
}

/* ---------- 26.7.2 下段 · 深色底（主内容 + 版权条） ----------
   纹理层（115° 斜纹 + 62px 网格）、logo 剪影水印与极慢流光已按要求整体去掉。
   只留一层静态纵向渐变 —— 顶部沿用上段收尾的提亮色、底部回到更沉的一端，
   让下半有光感层次而不至于是一块平色，同时没有任何东西在动。 */
.foot2__dn {
  position: relative;
  padding-block: clamp(32px, 4.2vh, 54px) clamp(22px, 2.8vh, 38px);
  background: linear-gradient(180deg, var(--dark-3) 0%, #0E2342 56%, #0B1C36 100%);
}
.foot2__dnIn { position: relative; z-index: 1; }

.foot2__main {
  display: grid; grid-template-columns: 1.5fr 1.25fr 1.15fr auto;
  gap: clamp(22px, 3vw, 50px); align-items: start;
}
/* ⚠️ `width: auto` 不能省。
   内页旧页脚（.foot__brand img）只写了 height 却没写 width:auto，
   而 <img> 上挂着 width="140" 这个**表现性属性** —— 于是浏览器把宽固定成
   140px、高按 CSS 压到 46px，图片被横向拉伸 2.7 倍（真实比例应为 52.6×46），
   圆形马标被拉成椭圆。全站页脚合并后这条规则是唯一一份，务必保留 width:auto。
   图片用**反白版**（logo-white）：彩色版是深绿 #1B9238 + 正红 #D41C24，
   压在深蓝页脚底上两个颜色都糊。 */
.foot2__brand img { height: 64px; width: auto; margin-bottom: 16px; }
.foot2__brand p { font-size: 13.2px; line-height: 1.8; color: var(--on-dark-3); max-width: 56ch; }
.foot2__tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 15px; }
/* 标签有两种元素：认证类是不可点的 <span>，营业执照是可点的 <a>。
   两者共用同一套胶囊外观 —— 但**可点的那个必须看得出来可点**，见下。 */
.foot2__tags span,
.foot2__tags a {
  font-size: 12.5px; padding: 3px 10px; border-radius: 100px;
  background: rgba(255,255,255,.06); color: rgba(255,255,255,.6);
  border: 1px solid var(--dark-line);
}
/* 营业执照：企业主体资格凭证，与「体系 / 产品认证」不是一类东西，
   用主色描边区分开，避免被读成第六张体系证书。
   它是标签条里唯一能动的一项，所以常态就比旁边亮一档，
   悬停 / 键盘聚焦再提亮并抬起 1px —— 否则「能点」这件事没有任何线索。 */
.foot2__tags a.is-hl {
  background: rgba(0, 95, 184, .22); color: rgba(255, 255, 255, .88);
  border-color: rgba(96, 165, 250, .4);
  transition: background-color .24s var(--ease), border-color .24s var(--ease),
              color .24s var(--ease), transform .24s var(--ease);
}
.foot2__tags a.is-hl:hover {
  background: rgba(0, 95, 184, .44);
  border-color: rgba(140, 190, 250, .78);
  color: #fff; transform: translateY(-1px);
}
.foot2__tags a.is-hl:focus-visible {
  outline: 2px solid var(--blue-400); outline-offset: 2px;
  background: rgba(0, 95, 184, .44);
  border-color: rgba(140, 190, 250, .78);
  color: #fff;
}
.foot2__h {
  font-size: 14px; font-weight: 700; color: var(--on-dark); margin-bottom: 17px;
  display: flex; align-items: center; gap: 9px; letter-spacing: .02em;
}
.foot2__h::before { content: ""; width: 3px; height: 14px; background: var(--green-500); border-radius: 2px; flex: none; }
.foot2__cols { display: grid; grid-template-columns: 1fr 1fr; gap: 12px 20px; }
.foot2__links { display: grid; gap: 10px; align-content: start; }
.foot2__links a { font-size: 13.2px; color: var(--on-dark-3); transition: .22s var(--ease); width: fit-content; }
.foot2__links a:hover { color: var(--on-dark); transform: translateX(3px); }
.foot2__ct { display: grid; gap: 13px; }
.foot2__ct li { display: flex; gap: 10px; font-size: 13px; line-height: 1.68; color: var(--on-dark-3); }
.foot2__ct svg { width: 15px; height: 15px; flex: none; margin-top: 4px; color: var(--blue-400); }
.foot2__ct a:hover { color: var(--on-dark); }
.foot2__ct b { color: rgba(255,255,255,.9); font-family: var(--font-num); }

/* ---------- 26.7.3 二维码（公众号真码 + 小程序码占位） ---------- */
.foot2__qr { min-width: 0; }
.qrbox { display: flex; gap: 14px; }
.qrbox__i { display: flex; flex-direction: column; align-items: center; gap: 8px; }
.qrbox__im {
  position: relative; display: block; width: 104px; height: 104px;
  border-radius: var(--r-sm); background: var(--surface); padding: 5px;
  overflow: hidden;                       /* 裁掉扫描线在框外的部分 */
  box-shadow: 0 6px 18px -8px rgba(0,0,0,.5);
  transition: transform .34s var(--ease), box-shadow .34s var(--ease);
}
.qrbox__im img { width: 100%; height: 100%; object-fit: contain; border-radius: 4px; }

/* ---------- 小程序码占位（26.7.3.1） ----------
   小程序码还没有真实素材，这一格留成「明确的占位」而不是留空：
   留空会被读成图挂了，随便塞一张假码更糟（扫出来没东西 = 骗人）。
   做法是把这一格从"白色实体卡"换成"透明虚线框" —— 与旁边那张真码
   在质感上直接区分开，一眼看得出是待补的位置，而不是一张坏图。

   ⚠️ 同时关掉两个属于「真码」的视觉暗示：
      · .qrbox__im::before 的四角扫描框 —— 那是"可以扫"的暗示，空框上会误导；
      · .qrbox__im::after 的循环扫描线 —— 同理。
     所以这一格既不带白底、也不带角标、也不动。
   ⚠️ 这组规则必须排在 .qrbox__im::before / ::after 之后 ——
      两者特异性相同（都是 0,1,1），靠的是源码顺序取胜。
      曾经把它们写在 ::before 定义之前，结果角标照旧画在空框上：
      不报错、不提示，只有看图才发现。 */

/* 四角扫描框：用 8 条渐变拼出四个 L 形角标（每角一横一竖）。
   这是「可扫」的通用视觉暗示 —— 比文字提示更快被认出来。 */
.qrbox__im::before {
  content: ""; position: absolute; inset: 4px; z-index: 2; pointer-events: none;
  --c: var(--blue-500); --l: 13px; --t: 2px;
  background:
    linear-gradient(var(--c), var(--c)) left  top    / var(--l) var(--t) no-repeat,
    linear-gradient(var(--c), var(--c)) left  top    / var(--t) var(--l) no-repeat,
    linear-gradient(var(--c), var(--c)) right top    / var(--l) var(--t) no-repeat,
    linear-gradient(var(--c), var(--c)) right top    / var(--t) var(--l) no-repeat,
    linear-gradient(var(--c), var(--c)) left  bottom / var(--l) var(--t) no-repeat,
    linear-gradient(var(--c), var(--c)) left  bottom / var(--t) var(--l) no-repeat,
    linear-gradient(var(--c), var(--c)) right bottom / var(--l) var(--t) no-repeat,
    linear-gradient(var(--c), var(--c)) right bottom / var(--t) var(--l) no-repeat;
}
/* 循环扫描线：一道浅蓝光带自上而下扫过，70% 处跑完、余下时间静止，
   避免"永远在动"引起余光干扰 */
.qrbox__im::after {
  content: ""; position: absolute; left: 0; right: 0; height: 26px; top: -26px;
  z-index: 3; pointer-events: none;
  background: linear-gradient(180deg,
    transparent, rgba(0, 95, 184, .38) 44%,
    rgba(174, 208, 244, .78) 50%,
    rgba(0, 95, 184, .38) 56%, transparent);
  animation: qrScan 3.4s cubic-bezier(.45, .05, .55, .95) infinite;
}
@keyframes qrScan {
  0%   { top: -26px; }
  70%  { top: 100%; }
  100% { top: 100%; }
}
.qrbox__i:hover .qrbox__im {
  transform: translateY(-5px) scale(1.03);
  box-shadow: 0 14px 30px -10px rgba(0,0,0,.62), 0 0 0 1px var(--blue-400),
              0 0 22px -4px rgba(0, 140, 255, .5);
}
.qrbox__i figcaption { font-size: 13px; color: rgba(255,255,255,.8); letter-spacing: .02em; }
/* 提示句排一行（宽度由 grid 的 auto 列自适应撑开）。
   窄屏交给媒体查询放开换行，否则会顶出列宽。 */
.qrbox__tip { font-size: 13px; line-height: 1.65; color: rgba(255,255,255,.64); margin-top: 12px; white-space: nowrap; }

/* ---------- 小程序码占位（26.7.3.1 · 见本节开头说明） ----------
   位置在 ::before / ::after 之后，用同特异性覆盖掉真码的角标与扫描线；
   双类名再兜一层，防止将来有人调整这里的顺序又把它写回失效。 */
.qrbox__im.qrbox__im--ph {
  background: rgba(255, 255, 255, .05);
  border: 1px dashed rgba(255, 255, 255, .32);
  box-shadow: none;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 5px;
}
.qrbox__im.qrbox__im--ph::before,
.qrbox__im.qrbox__im--ph::after { content: none; animation: none; }
.qrbox__phIco { width: 28px; height: 28px; flex: none; color: rgba(255, 255, 255, .36); }
.qrbox__phTx {
  font-size: 11px; line-height: 1; letter-spacing: .04em;
  color: rgba(255, 255, 255, .42);
}
.qrbox__i--ph figcaption { color: rgba(255, 255, 255, .60); }
/* 占位格不参与悬停抬起 —— 它不是可交互的东西 */
.qrbox__i--ph:hover .qrbox__im { transform: none; box-shadow: none; }

.foot2__bar {
  border-top: 1px solid var(--dark-line); margin-top: clamp(24px, 3vw, 40px);
  padding-top: 18px; display: flex; align-items: center; justify-content: space-between;
  gap: 18px; flex-wrap: wrap; font-size: 13px; color: rgba(255,255,255,.64);
}
.foot2__bar a { transition: color .22s var(--ease); }
.foot2__bar a:hover { color: rgba(255,255,255,.92); }
.foot2__barNav { display: flex; gap: 18px; flex-wrap: wrap; }

@media (prefers-reduced-motion: reduce) {
  /* 二维码扫描线是纯装饰的循环动画，降级时直接移除，静态四角扫描框保留 */
  .qrbox__im::after { display: none; }
}

/* ---------- 26.8 页脚 · 合作伙伴（标题行 + 实景照片 logo 带） ----------
   素材沿用已去底的透明 PNG —— 白卡是干净的中性承载面，透明边缘不会在白底上
   露出抠图残留；若换回原始白底 JPG，白卡直接容纳也可以，不需要任何前置处理。

   ⚠️ 标题行与 logo 带同在一块底图之上，标题压在图上。
      可读性由 26.8.2 的顶部渐隐承担 —— 底图本身仍是原始反差，没有被洗淡。 */
/* 标题行：与 logo 带同处底图之上，底部留白就是它与 logo 带之间的呼吸 */
.foot2__ptnWrap { position: relative; padding-bottom: clamp(14px, 1.9vh, 26px); }
/* logo 带在标题下方的剩余空间里居中（见 26.7.0 的说明） */
.foot2__ptn { padding-bottom: clamp(4px, .6vw, 10px); margin-block: auto; }
.foot2__ptnHd {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 20px; flex-wrap: wrap;
}
/* ---------- 26.8.1 标题行的配色（深色底版） ----------
   ⚠️ 这一行原先压在照片上，用的是浅色底 + 深墨字一套（--ink / rgba(14,21,36,.66)）。
      去蒙版后它搬到了照片上方的深色底（--dark-3 #112A4C）上，
      配色必须整组跟着翻，不能只改一处 —— 深墨字压在 #112A4C 上只有约 1.2:1，
      等于把标题直接抹掉。
      现在的实测对比度（对 #112A4C）：
        h2 主标 --on-dark #F5F8FF .......... 15.1:1
        h2 英文小标 rgba(245,248,255,.66) ... 6.7:1（13–16px 需 4.5:1）
        右侧链接 --blue-300 #5AA3E4 ......... 5.3:1 */
.foot2__ptnHd h2 {
  font-size: clamp(20px, 1.7vw, 27px); font-weight: 700; color: var(--on-dark);
  letter-spacing: -.01em; line-height: 1.2;
}
.foot2__ptnHd h2 span {
  font-family: var(--font-en); font-size: .58em; font-weight: 600; letter-spacing: .16em;
  text-transform: uppercase; color: rgba(245, 248, 255, .66);
  margin-left: 12px; vertical-align: middle;
}
.foot2__ptnAll {
  display: inline-flex; align-items: center; gap: 7px; flex: none;
  font-size: 13px; color: var(--blue-300); transition: color .24s var(--ease);
}
.foot2__ptnAll:hover { color: var(--on-dark); }
.foot2__ptnAll svg { width: 13px; height: 13px; transition: transform .24s var(--ease); }
.foot2__ptnAll:hover svg { transform: translateX(3px); }

/* ---------- 26.8.2 标题的承托层（顶部压暗渐隐） ----------
   ⚠️ 为什么必须有这一层：底图顶部那一条横带的亮度实测横跨 25–179
      —— 同一行里既有接近黑的暗部，也有接近亮的墙面。
      白字压在 179 上约 1.9:1，深墨字压在 25 上约 1.2:1，两个方向都读不出来。
      这不是换字号、加文字阴影能解决的：字压在实景图上就必须有承托。

   ⚠️ 它与第一轮删掉的「整幅柔化白雾」不是一回事，三点区别：
        · 位置：只覆盖顶部一条（上段最顶 → 标题下方 56px 淡出），
               照片主体、人物、logo 带完全不在它的作用范围内；
        · 方向：压暗，不是洗淡 —— 照片的原始反差与通透感保留；
        · 归属：挂在标题行自己身上（::before），高度随标题行内容走，
               窄屏标题换行时自动变高，不需要任何额外断点。

   渐隐曲线：标题带上沿 alpha 维持 .86–.84，到标题下方才快速归零，
   保证「主标 / 英文小标 / 右侧链接」三处都落在 alpha ≥ .62 的区间内。

   ⚠️ --ptn-fade 是「标题下方再多铺多远」。桌面档 56px 时承托层约占上段 44%；
      窄屏上固定留白（导航避让 + 呼吸）占掉上段的比例大得多，同一个 56px
      会盖到 75%，所以窄屏单独收到 34px。 */
.foot2__ptnWrap::before {
  content: '';
  position: absolute; z-index: -1; pointer-events: none;
  /* 向上顶到上段最顶（含导航避让留白），向下多留 --ptn-fade 做淡出 */
  top: calc(-1 * (var(--foot2-avoid) + var(--foot2-pad)));
  bottom: calc(-1 * var(--ptn-fade, 56px));
  /* 横向突破 .wrap 版心铺满整宽；溢出部分由 .foot2__top 的 overflow 裁掉 */
  left: -50vw; right: -50vw;
  background: linear-gradient(180deg,
    rgba(7, 18, 36, .86) 0%,
    rgba(7, 18, 36, .84) 62%,
    rgba(7, 18, 36, .62) 82%,
    rgba(7, 18, 36, 0) 100%);
}

/* ---------- logo 轨道 · 三份同内容，无缝横移 ----------
   .plogos（视窗，裁切）> .plogos__track（长条，整体位移）> 3 × .plogos__set
   位移量取「一整份」= -100% / 3：到位那一刻，第 2 份的第 1 格正好落到
   第 1 格的原位上，视觉完全接续，看不出缝隙。
   每份自带 padding-right 补上组间间距（而不是靠 gap），
   于是"一整份"精确等于「6 格 + 6 个间距」，不会因 gap 半格错位。 */
.plogos { --pgap: clamp(14px, 1.4vw, 22px); overflow: hidden; }
.plogos__track {
  display: flex; width: max-content;
  animation: plogoFlow 46s linear infinite;
}
/* 悬停暂停：把节奏交回给想看清某一家 logo 的人 */
.plogos:hover .plogos__track { animation-play-state: paused; }
.plogos__set { display: flex; gap: var(--pgap); padding-right: var(--pgap); }
@keyframes plogoFlow {
  from { transform: translateX(0); }
  to   { transform: translateX(calc(-100% / 3)); }
}

/* 白底卡片：宽度显式给定 —— 三份宽度才完全一致，位移量才可算；
   六格在任何视口下也都是同一节奏的横排。 */
.plogo {
  position: relative;                 /* img 的绝对定位包含块 */
  flex: 0 0 auto;
  width: clamp(140px, 11.8vw, 196px);
  height: clamp(62px, 4.6vw, 84px);
  border-radius: var(--r-md);
  background: var(--surface);
  /* ⚠️ 边框与阴影是本轮为新背景一并加强的（.07→.12 描边、阴影加一层贴地锐边）。
     原因：新底图亮度跨度大（9–189），柔化后画面里仍有约 228 的亮区，
     近白卡压在其上只差 27 级 —— 卡片会"化"进背景、logo 失去承载面。
     加强后卡片靠「贴地锐边 + 离地投影」立住，不再依赖与背景的明度差。
     这是白卡能读出来的唯一前提，不要单独回退其中一项。
     底色用的是 --surface（与本区最亮处相差约 27 级），不用纯白。 */
  border: 1px solid rgba(14, 21, 36, .12);
  box-shadow: 0 1px 2px rgba(12, 27, 52, .10), 0 10px 26px -14px rgba(12, 27, 52, .42);
  transition: transform .34s var(--ease), box-shadow .34s var(--ease);
}
.plogo:hover {
  transform: translateY(-4px);
  box-shadow: 0 1px 2px rgba(12, 27, 52, .12), 0 20px 36px -14px rgba(12, 27, 52, .50);
}
/* ⚠️ 图片必须绝对定位（沿用上一轮踩坑后的结论）：
   .plogo 是 flex item，其内部元素的百分比尺寸会与包含块高度形成循环依赖，
   被浏览器按 auto 处理 —— 图片按原始比例撑开、直接冲出卡片边框。
   绝对定位后包含块高度由 .plogo 的 height 明确给定，100% 可靠解析，
   比例交给 object-fit: contain，无论素材什么比例都不会溢出。 */
.plogo img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: contain;
  box-sizing: border-box;
  padding: clamp(11px, 1.1vw, 17px);
  transition: transform .4s var(--ease);
}
.plogo:hover img { transform: scale(1.05); }

/* logo 自动横移降级（必须写在本段最后 —— 同特异性下靠后者胜，
   写到前面会被上面的基础规则覆盖掉）：
   停掉位移、隐藏两份副本、轨道改换行平铺 —— 六家 logo 一张不落地
   全部可见可读，只是不再流动。
   ⚠️ width 必须一并从 max-content 改回 auto：max-content 的语义是
   「不换行时的理想宽度」，留着它，flex-wrap: wrap 就永远不会发生折行，
   配合 overflow: visible 会直接把内容顶出页面。 */
@media (prefers-reduced-motion: reduce) {
  .plogos { overflow: visible; }
  .plogos__track { width: auto; animation: none; flex-wrap: wrap; }
  .plogos__set[aria-hidden="true"] { display: none; }
  .plogos__set { padding-right: 0; }
}

/* ---------- 26.9 首页响应式 ---------- */
/* 新闻资讯：1280×800 这类「矮而宽」的桌面视口，可用高度只剩约 658px，
   单纯靠 clamp 流式缩放还差十几个像素 —— 单独压一档密度补上。 */
@media (max-width: 1360px) {
  html.pg-index .panel--news .newsx__h { font-size: clamp(23px, 2.2vw, 30px); }
  html.pg-index .newsx__head { margin-bottom: clamp(20px, 2.2vw, 30px); }
  html.pg-index .newsx { gap: clamp(13px, 1.3vw, 18px); }
  html.pg-index .ncard--lead .ncard__im { min-height: clamp(140px, 11.5vw, 178px); }
  html.pg-index .newsx__mini { gap: clamp(9px, .85vw, 12px); }
}
@media (max-width: 1280px) {
  /* 此处原先还有一条 .navtools__tel span { display: none } —— 已删除。
     导航电话里的号码用的是 <b>，不存在 <span>，而整条 .navtools__tel 在
     ≤1300 已被隐藏（见第 23 节），所以这条选择器从来没有命中过任何元素。
     真正生效的是 ≤1700 的 .navtools__tel b { display: none }。 */
  /* 保持四列（二维码不换行）：页脚加了两段结构后，main 一旦折成两行
     高度会从 271 涨到 482 —— 整屏吸附下直接顶破视口。
     1.4/1.15/.95 这一版让 contact 列只剩约 200px，地址「湖北省十堰市经济
     开发区空港产业园」会在「产/业园」中间断开；借 0.1fr 给 contact 后
     单行放得下，brand 与 nav 不受影响。 */
  .foot2__main { grid-template-columns: 1.35fr 1.1fr 1.05fr auto; }
  .qrbox__im { width: 96px; height: 96px; }
  /* 二维码列只剩约 206px，提示句必须放开换行，否则顶出列宽 */
  .qrbox__tip { white-space: normal; }
}
@media (max-width: 1120px) {
  html.pg-index .panel__in { padding-top: calc(var(--nav-h) + 24px); }
  /* 首屏：窄屏下文案区由「左半幅」变成「几乎满幅」，与照片主体必然重叠 ——
     （原先 ≤1120px 时照片整块是不显示的，只有渐变底，所以从没遇到过这个冲突；
       现在照片满幅了才暴露出来。）
     单靠一道纱只能二选一：要么正文读不出，要么把车头洗成一片灰雾。
     这里用两层叠加，各司其职：
       ① 横向纱：护住左侧文案列，到 58% 处归零 —— 右侧主体基本不受影响；
       ② 纵向纱：整幅轻提一档，兜住标题在竖版下的折行与正文落点。
     两层都刻意压得比"刚好够用"再低一点：这是本页唯一一处
     用一点照片通透度换正文可读性的地方，不能再重。 */
  .hero2__bg::after {
    background:
      linear-gradient(100deg,
        rgba(247, 249, 251, .70) 0%,
        rgba(247, 249, 251, .62) 28%,
        rgba(247, 249, 251, .34) 44%,
        rgba(247, 249, 251, .08) 58%,
        rgba(247, 249, 251, 0) 70%),
      linear-gradient(180deg,
        rgba(247, 249, 251, .20) 0%,
        rgba(247, 249, 251, .46) 30%,
        rgba(247, 249, 251, .46) 64%,
        rgba(247, 249, 251, .18) 86%,
        rgba(247, 249, 251, .06) 100%);
  }
  /* 控件栏独占底部：箭头贴左、页码贴右，滚动提示居中 */
  .hero2__ctrl { bottom: 26px; }
  .hero2__body { padding-bottom: 104px; }
  .hero2__main, .hero2__main--vision { max-width: none; }
  .pgrp > .pcard { flex-basis: calc((100% - 1 * clamp(14px, 1.6vw, 24px)) / 2); }
  /* 新闻：头部从「左右双端」转为「上下两段」（标题在上、分类在下左对齐），
     三列保持不折 —— 这一段仍是整屏吸附的 mandatory 区，一折行就顶破视口 */
  html.pg-index .newsx__head { align-items: flex-start; }
  html.pg-index .newsx__hdR { justify-content: flex-start; }
  /* 页脚主内容在 1120–961 区间必须保持四列。
     这里一旦折行，main 会从约 220px 涨到 550px，而这一段仍处于整屏吸附的
     mandatory 区（960 以下才转 proximity）—— 实测 1120×800 页脚会超出 364px，
     每屏都装不进视口。改为「收窄三列 + 缩小二维码 + 提示句放开换行」换取空间。 */
  .foot2__main { grid-template-columns: 1.15fr 1fr 1fr auto; gap: clamp(16px, 2vw, 26px); }
  .qrbox { gap: 12px; }
  .qrbox__im { width: 88px; height: 88px; }
  .qrbox__tip { white-space: normal; }
  /* logo 轨道已改为自动横移，不再随容器折列 —— 这里只需把卡片收小一点，
     让窄视口下同屏能完整看到更多家，流动的节奏也更顺 */
  .plogo { width: clamp(134px, 15vw, 176px); height: clamp(60px, 6.4vw, 78px); }
}
@media (max-width: 960px) {
  html.pg-index .panel, html.pg-index .foot2 { min-height: 0; }
  /* 窄屏面板顶边必须完整让开固定导航：原来上下共用 56px，
     板块标签会紧贴（甚至压到）导航下沿 */
  html.pg-index .panel__in {
    min-height: 0;
    padding-top: calc(var(--nav-h) + 28px);
    padding-bottom: clamp(56px, 9vw, 88px);
  }
  /* 关于我们：通栏数字条在窄屏折成 2×2，需要行间距把两排拉开
     （显式指定 2 列：通用断点在 440 以下会把 .stats 收成单列，
     四行竖排会把本屏拉得过长） */
  html.pg-index .panel--about .stats--line {
    grid-template-columns: repeat(2, 1fr);
    row-gap: clamp(20px, 4vw, 30px);
  }
  /* 2×2 时每行首项回到左边界，两排左边缘对齐 */
  html.pg-index .panel--about .stats--line .stat:nth-child(odd) { padding-left: 0; }
  /* 新闻：脱离整屏吸附后不再受高度预算约束，改两列把配图看大；
     右列的横式小卡列表改跨两列、自身并成两列。 */
  html.pg-index .newsx { grid-template-columns: repeat(2, 1fr); }
  html.pg-index .newsx__mini {
    grid-column: 1 / -1;
    grid-template-columns: repeat(2, 1fr);
    grid-auto-rows: clamp(96px, 14vw, 128px);
  }
  html.pg-index { scroll-snap-type: y proximity; }
  /* .hero2 的子节点（facet / slides / body / vnav）全部是绝对定位，
     一旦把 height 改成 auto 就会塌成 padding 高度、内容被 overflow 裁掉，
     所以窄屏也必须保留整屏高度，只能压缩内边距。 */
  .hero2 { height: 100svh; min-height: 600px; padding-block: 0; }
  .hero2__body { height: 100%; padding-top: calc(var(--nav-h) + 32px); padding-bottom: 96px; }
  .hero2__h { max-width: none; }
  .hero2__h br { display: none; }
  /* 页脚：脱离整屏吸附后才允许折行 —— 两列 + 二维码整行。
     960 以下吸附已转 proximity，页脚可以自然变高，不再受一屏预算约束。 */
  .foot2__main { grid-template-columns: 1fr 1fr; gap: 26px; }
  .foot2__qr { grid-column: 1 / -1; }
  html.pg-index.is-scrolled .nav { background: rgba(255,255,255,.97); }
}
@media (max-width: 720px) {
  html.pg-index { scroll-snap-type: none; }
  .hero2__btns .btn { flex: 1; justify-content: center; min-width: 0; }
  .hero2__cta { padding-right: 6px; gap: 12px; }
  .hero2__ctaDot { width: 32px; height: 32px; }
  .hero2__spec { gap: 18px; }
  .hero2__vow em { font-size: 13px; padding: 6px 14px; }
  /* 窄屏：控件栏收紧，滚动提示让位 */
  .hero2__ctrl { bottom: 20px; gap: 14px; }
  .hero2__mouse { display: none; }
  .hero2__arrow { width: 40px; height: 40px; }
  .hero2__arrow svg { width: 15px; height: 15px; }
  .hero2__pager button { font-size: 12.5px; }
  .hero2__pager button.is-on { font-size: 20px; }
  /* 窄屏：产品卡一格一屏宽，露出一角提示可横滑 */
  .pgrp > .pcard { flex-basis: 84%; }
  /* 窄屏：新闻改为单列堆叠，右列横式卡也各自占满整宽。
     单列后大卡不再有可分配的剩余高度，配图改回显式高度。 */
  html.pg-index .newsx { grid-template-columns: 1fr; gap: 14px; }
  html.pg-index .newsx__mini {
    grid-column: auto;
    grid-template-columns: 1fr;
    grid-auto-rows: clamp(88px, 21vw, 108px);
  }
  html.pg-index .ncard--lead .ncard__im { flex: none; height: clamp(150px, 46vw, 230px); min-height: 0; }
  html.pg-index .newsx__hdR { gap: 12px; }
  .panel__head { margin-bottom: 24px; }
  .foot2__main { grid-template-columns: 1fr; gap: 26px; }
  /* 窄屏 logo 卡片按视口比例放大，一次看到 2–3 家，流动感更清楚 */
  .plogo { width: clamp(126px, 30vw, 168px); height: clamp(56px, 13vw, 74px); }
  .plogo img { padding: 12px; }
  .foot2__ptnHd { align-items: flex-start; }
  .foot2__ptnHd h2 span { display: block; margin: 6px 0 0; }
  .qrbox__im { width: 118px; height: 118px; }
  .foot2__bar { flex-direction: column; align-items: flex-start; gap: 12px; }
  /* ⚠️ 窄屏导航是固定定位且高 --nav-h(66px)，页脚第一件东西是标题行 ——
     避让留白不够会把「合作伙伴」整行塞到白色导航底下（实测压在最上面）。
     这里给足完整导航高度再加一点呼吸；留白现在由上段的 padding-top 承担
     （--foot2-avoid），所以那一条也是底图，不再是纯色。 */
  .foot2 { --foot2-avoid: calc(var(--nav-h) + 12px); --foot2-pad: clamp(34px, 9vw, 56px);
           --ptn-fade: 34px; }
  /* 窄屏上段：脱离整屏吸附后不再受高度预算约束，但也不能只按内容高算 ——
     标题行现在也在照片上，若上段正好等于内容高，照片会被压成一条窄缝
     （实测仅 268px 里 169px 被标题与留白吃掉）。给一个最小高度让底图有呼吸。 */
  .foot2__top { min-height: clamp(300px, 66vw, 400px); }
}
@media (max-width: 440px) {
  .qrbox__im { width: 104px; height: 104px; }
  .hero2__spec { flex-wrap: wrap; gap: 14px 22px; }
}
/* ---------- 页脚高度档 ----------
   页脚从「单段深色」改成「logo 墙 + 握手图区 + 纯色下段」后总高变大，
   而整屏吸附要求每屏都装进视口 —— 原先只有 780px 一档压缩，
   900 / 800 两个最常见的高度完全没覆盖，页面会在这里卡滞。
   因此按视口高度分三档依次收紧，只动页脚，不影响其他面板。 */

/* ① ≤920px 高（1440×900 这类主流笔记本）：轻度收紧 */
@media (min-width: 961px) and (max-height: 920px) {
  .foot2 { --foot2-avoid: calc(var(--nav-h) + 18px); --foot2-pad: clamp(34px, 4.6vh, 56px); }
  /* 上段是 flex:1 的弹性块，内容不足一屏时自动变高、自然趋近各占一半；
     这一档只需把内边距与卡片高度各收一点，就够让总高稳住不破视口 */
  .foot2__top { min-height: clamp(268px, 39vh, 404px); }
  .foot2__ptnWrap { padding-bottom: 18px; }
  .plogo { height: 70px; }
  .plogo img { padding: 13px; }
  .foot2__dn { padding-block: 30px 22px; }
  .foot2__bar { margin-top: 36px; }
}

/* ② ≤850px 高（1366×800 / 1280×800）：logo 卡片压扁一档，
   上段内边距收紧，下段与版权条同步收 */
@media (min-width: 961px) and (max-height: 850px) {
  .foot2 { --foot2-avoid: calc(var(--nav-h) + 12px); --foot2-pad: 28px; }
  .foot2__top { min-height: clamp(250px, 37vh, 340px); }
  .foot2__ptnWrap { padding-bottom: 12px; }
  .plogo { height: 60px; }
  .plogo img { padding: 12px; }
  .foot2__dn { padding-block: 19px 15px; }
  .foot2__bar { margin-top: 19px; padding-top: 14px; }
  .qrbox__im { width: 92px; height: 92px; }
}

/* ③ ≤780px 高（1440×720 等）：首屏面板也要一并压扁，避免被挤变形 */
@media (min-width: 961px) and (max-height: 780px) {
  html.pg-index { scroll-snap-type: y proximity; }
  .hero2__h { font-size: clamp(26px, 3.4vw, 44px); }
  .hero2__p { margin-bottom: 20px; font-size: 14px; }
  .hero2__spec { margin-bottom: 22px; padding-top: 16px; }
  .hero2__vow { margin-bottom: 20px; }
  .hero2__body { padding-top: calc(var(--nav-h) + 30px); padding-bottom: 84px; }
  .hero2__ctrl { bottom: 18px; }
  .hero2__mouse { display: none; }
  html.pg-index .panel__in { padding-top: calc(var(--nav-h) + 18px); padding-bottom: 26px; }
  /* 压缩密度，尽量让每屏贴合一屏 */
  .panel__head { margin-bottom: 20px; }
  html.pg-index .panel { --sec-y: 46px; }
  .pcard__bd { padding: 16px; }
  .pcard__bd p { font-size: 13.5px; margin-bottom: 11px; }
  /* 矮视口（如 1440×720）：新闻屏可用高度只剩约 600px，
     三列必须整体压一档才装得下 —— 头部收窄、配图降底、卡片内边距收紧。 */
  html.pg-index .panel--news .newsx__h { font-size: clamp(22px, 2.1vw, 28px); }
  html.pg-index .newsx__head { margin-bottom: 16px; }
  html.pg-index .newsx { gap: 14px; }
  html.pg-index .ncard--lead .ncard__im { min-height: 132px; }
  html.pg-index .ncard__bd { padding: 14px; }
  html.pg-index .ncard__bd p { -webkit-line-clamp: 2; }
  html.pg-index .ndate b { font-size: 21px; }
  html.pg-index .ncard--blue .ndate b { font-size: 28px; }
  html.pg-index .newsx__mini { gap: 8px; }
  html.pg-index .nmini__bd { padding: 11px; }
  /* 矮视口：页脚再压一档 —— 这一档可用高只剩约 650px，
     logo 卡片、上段内边距、下段与版权条必须一起收，才能继续贴合整屏吸附。 */
  .plogo { height: 50px; }
  .plogo img { padding: 10px; }
  .foot2__ptnWrap { padding-bottom: 9px; }
  .foot2 { --foot2-avoid: calc(var(--nav-h) + 10px); --foot2-pad: 22px; }
  .foot2__top { min-height: 236px; }
  .foot2__dn { padding-block: 15px 12px; }
  .foot2__bar { margin-top: 14px; padding-top: 11px; }
  .qrbox__im { width: 88px; height: 88px; }
  html.pg-index .stats--line .stat__n { font-size: clamp(22px, 2.4vw, 32px); }
}
/* 打印：六屏全部展开 */
@media print {
  html.pg-index { scroll-snap-type: none; }
  html.pg-index .nav { position: static; }
  .hero2, html.pg-index .panel, html.pg-index .foot2 { min-height: 0; height: auto; }
}

/* ---------- 27. 内页页脚二维码（已合并，此处是标记位） ----------
   ⚠️ 2026-10-08：内页那套 `.foot__qr` / `.foot__qrPh` / `.foot__qrI--ph`
   已整体删除 —— 内页页脚改用与首页同一份 `.qrbox__*`（见 26.7.3 / 26.7.3.1），
   小程序码占位也只有一种尺寸与排布，不再有「首页 104 方格上下排、
   内页 96 方格横排」两套需要互相提防的实现。 */

/* ---------- 28. 页脚响应式（已合并，此处是标记位） ----------
   ⚠️ 2026-10-08：原来的 `.foot__main` 四档断点（1400 / 1180 / 760 / 560）
   已随 `.foot__*` 一起删除。页脚响应式现在只有一处 —— 见 26 节与
   「整屏吸附」那几段里的 `.foot2__main` / `.foot2__qr` 断点。

   保留下来的那条结论仍然成立，搬到了 .foot2 上：
   **二维码那一列必须是 auto，不能跟着均分。**
   两格 104px + 14px 间距 = 222px，均分列宽给不了这么多，
   flex 会去压第一格的 figure，于是两张码大小不一 ——
   不溢出、不报错，只有把两个 figure 的宽度并排打印出来才看得见。
*/

/* ======================================================================
   29. 渐进呈现（progressive stage）
   把「一屏铺不完的长图墙 / 长列表」收成先看一眼的摘要，按钮在原地撑开。

   这一节的设计前提是「无 JS 时必须全部可见」：
     · .is-folded 由脚本添加，HTML 里不写；
     · 展开按钮只在 html.js 下出现。
   所以禁用 JS、脚本报错、或脚本被 CSP 拦掉时，得到的是
   全部内容 + 没有按钮 —— 而不是「内容被藏起来且打不开」。
   HTML 里没有 is-folded 也就没有「先渲染成全部、再由脚本收起」的抖动。
   ====================================================================== */

/* 折叠态：超出首屏额度的格子收起。只改 display，不参与布局计算以外的事 */
html.js .stage.is-folded .stage__i[data-over] { display: none; }

/* 展开按钮 —— 无 JS 时它不存在 */
.stage__more { display: none; }
html.js .stage[data-stage] .stage__more:not([hidden]) {
  display: flex; width: fit-content; margin: 30px auto 0;
  align-items: center; justify-content: center; gap: 10px;
  padding: 12px 26px; border: 1px solid var(--line); border-radius: 100px;
  background: var(--surface); color: var(--ink-2);
  font: inherit; font-size: 13.5px; font-weight: 600; letter-spacing: .01em;
  cursor: pointer;
  box-shadow: 0 1px 2px rgba(12, 27, 52, .05), 0 10px 24px -16px rgba(12, 27, 52, .30);
  transition: border-color .26s var(--ease), color .26s var(--ease),
              box-shadow .26s var(--ease), transform .26s var(--ease);
}
html.js .stage[data-stage] .stage__more:not([hidden]):hover {
  border-color: var(--blue-300, #9CC2E8); color: var(--blue-600);
  box-shadow: 0 1px 2px rgba(12, 27, 52, .06), 0 16px 30px -16px rgba(0, 61, 124, .34);
  transform: translateY(-2px);
}
html.js .stage[data-stage] .stage__more:not([hidden]):active { transform: translateY(0); }
html.js .stage[data-stage] .stage__more:not([hidden]):focus-visible {
  outline: 2px solid var(--blue-500); outline-offset: 3px;
}
/* 计数器用等宽数字，展开/收起时按钮宽度不跳 */
.stage__more em { font-style: normal; font-family: var(--font-num); font-variant-numeric: tabular-nums; }
.stage__chev {
  width: 8px; height: 8px; margin-top: -3px; flex: none;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: rotate(45deg);                 /* 折叠态：指向下（展开） */
  transition: transform .34s var(--ease);
}
html.js .stage.is-open .stage__chev { transform: rotate(-135deg); margin-top: 3px; }

/* 展开时新出现的格子往上浮一点并依次错峰。
   只动 opacity / transform，走合成器。
   折叠态是 display:none，所以这些项不占首屏成本，也不会被 .rv 观察器提前点亮。 */
@keyframes stageUp {
  from { opacity: 0; transform: translateY(16px) scale(.985); }
  to   { opacity: 1; transform: none; }
}
html.js .stage.is-open .stage__i[data-over] {
  animation: stageUp .54s var(--ease-out) backwards;
  animation-delay: calc(var(--sd, 1) * 46ms);
}

/* 图墙在窄屏会换成更少的列，首屏额度由脚本按列数换算后重算，这里只保证
   折叠态下网格不会因为剩余项太少而拉高每一格 */
@media (max-width: 1000px) {
  html.js .stage[data-stage] .stage__more:not([hidden]) { margin-top: 24px; }
}
@media (max-width: 560px) {
  html.js .stage[data-stage] .stage__more:not([hidden]) {
    width: 100%; padding: 13px 20px; font-size: 13px;
  }
}

/* 未使用 JS 时的兜底文案：按钮不存在，改由这一行说明下面还有内容 */
.stage__hint { display: none; }

/* ---------- 29b. 折叠面板（岗位条目等） ---------- */
.pane { border: 1px solid var(--line); border-radius: var(--r-md); background: var(--surface); overflow: hidden; }
.pane + .pane { margin-top: 12px; }
/* <h3> 只承担语义，视觉全部交给里面的 button —— 直接给 h3 加样式会让
   折叠头继承标题的字号与边距，与其它区块标题打架 */
.pane__h { margin: 0; font: inherit; }
.pane__hd {
  display: flex; align-items: center; gap: 16px; width: 100%;
  padding: 20px 22px; background: none; border: 0; font: inherit;
  text-align: left; cursor: pointer; color: var(--ink);
  transition: background .24s var(--ease);
}
.pane__hd:hover { background: var(--bg-2); }
.pane__hd:focus-visible { outline: 2px solid var(--blue-500); outline-offset: -2px; }
.pane__tt { flex: 1; min-width: 0; }
.pane__name { display: block; font-size: 16.5px; font-weight: 700; letter-spacing: -.01em; }
.pane__meta { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 9px; }
.pane__meta span {
  font-size: 12px; font-weight: 600; padding: 3px 10px; border-radius: 100px;
  background: var(--blue-50); color: var(--blue-600);
}
.pane__meta span.is-g { background: var(--bg-3); color: var(--ink-3); }
.pane__chev {
  width: 9px; height: 9px; flex: none; margin-right: 4px;
  border-right: 2px solid var(--ink-3); border-bottom: 2px solid var(--ink-3);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform .34s var(--ease);
}
/* 折叠面板改用浏览器原生 <details>（默认收起、点击展开，不依赖 JS）——
   这里只做两件事：① 去掉 summary 的原生三角标记 ② 展开时箭头翻转。
   正文的显隐由 <details> 原生负责，不需要任何 display 规则。 */
.pane > summary { list-style: none; cursor: pointer; }
.pane > summary::-webkit-details-marker { display: none; }
.pane[open] > summary .pane__chev { transform: rotate(-135deg) translate(-1px, -1px); }
.pane.is-open .pane__chev { transform: rotate(-135deg) translate(-1px, -1px); }
.pane__bd { }
/* 折叠动画只在 JS 可用时挂上：无 JS 时保持普通块级流，内容全在 */
html.js .pane__bd {
  display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows .42s var(--ease);
}
html.js .pane.is-open .pane__bd { grid-template-rows: 1fr; }

/* ---------------------------------------------------------------------------
   <details> 版折叠面板（2026-10-15）
   岗位条目改为浏览器原生 <details>/<summary> ⇒ 显隐由浏览器负责，**不依赖 JS**。
   这里把上面那套基于 `.is-open` 的 grid 折叠**关掉**（否则正文会被压成 0fr 看不见）：
   同优先级、写在后面 ⇒ 覆盖生效。旧规则保留，静态页面的 .pane 仍可用。
   --------------------------------------------------------------------------- */
html.js .pane__bd { display: block; grid-template-rows: 1fr; }
details.pane > summary.pane__hd { list-style: none; cursor: pointer; }
details.pane > summary.pane__hd::-webkit-details-marker { display: none; }
details.pane > summary.pane__hd::marker { content: ""; }
details.pane[open] > summary.pane__hd .pane__chev { transform: rotate(-135deg) translate(-1px, -1px); }
.pane__bdIn { overflow: hidden; }
.pane__in { padding: 0 22px 24px; border-top: 1px solid var(--line-2); margin-top: 0; }
.pane__in > *:first-child { margin-top: 20px; }
.pane__sub { font-size: 13px; font-weight: 700; color: var(--ink-4); letter-spacing: .02em; margin-bottom: 10px; }
.pane__list { display: grid; gap: 9px; }
.pane__list li {
  position: relative; padding-left: 18px; font-size: 14px; line-height: 1.72; color: var(--ink-2);
}
.pane__list li::before {
  content: ""; position: absolute; left: 2px; top: .62em;
  width: 5px; height: 5px; border-radius: 50%; background: var(--green-500);
}
/* 面板底部：投递入口。与折叠头之间加一条分隔，展开后不至于和正文黏在一起 */
.pane__ft {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap; margin-top: 24px; padding-top: 18px;
  border-top: 1px solid var(--line-2);
}
@media (max-width: 560px) {
  .pane__hd { padding: 17px 18px; gap: 10px; }
  .pane__in { padding: 0 18px 20px; }
  .pane__name { font-size: 15.5px; }
  .pane__ft { margin-top: 20px; }
}

/* ---------- 30. 分组标题的计数徽标 ----------
   图墙/证书墙/问答分组原来只有一个光秃秃的组名，看不出这组有多少内容，
   也就无法判断「要不要展开」。把数量放在组名右侧，先给一个数量预期。 */
.sec-head--gal {
  max-width: none;
  display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
}
.sec-head--gal .ct {
  font-family: var(--font-num); font-variant-numeric: tabular-nums;
  font-size: 12.5px; font-weight: 600; letter-spacing: .02em;
  color: var(--blue-600); background: var(--blue-50);
  padding: 3px 11px; border-radius: 100px;
}
.sec-head--gal .ct::before { content: "共 "; font-size: .92em; letter-spacing: 0; }

/* 页签上的数量：字重比标签轻一点，扫读时标签仍是主体 */
.tabs a em {
  font-style: normal; font-family: var(--font-num); font-variant-numeric: tabular-nums;
  font-size: 11.5px; font-weight: 600; margin-left: 5px;
  opacity: .72;
}

/* 问答分组：切到某一类时整组进出，不参与筛选的兄弟组直接隐藏（.hide 已有） */
.faq-grp + .faq-grp { margin-top: 4px; }

/* 岗位条目容器 —— 条目自带 .pane + .pane 的间距，这里不需要额外 gap */
.panes { display: block; }

/* ==========================================================================
   31. 动态加载：图片「由虚到实」的渐显
   --------------------------------------------------------------------------
   背景：全站 267 张图带 loading="lazy"，滚动到附近才开始下载。此前它们
   是从「一块空白」直接跳成「一张图」，在慢网络下这个跳变很明显 ——
   读者会看到版面先塌着、再突然被填满。

   做法：脚本给「还没加载完」的图打上 .is-ld（由虚），load 完成后换成
   .is-ld-shown（由虚变实）。已经加载完的图（缓存命中、首屏图）脚本直接
   跳过，不参与 —— 否则会给一张早就画好的图再放一次入场动画。
   关键：这套规则全部带 html.js 前缀。没有脚本时图片保持常态、照常显示，
   不会出现「图片永远透明」这种被锁死的结果。
   ========================================================================== */
html.js img.is-ld {
  opacity: 0;
  /* 极轻的模糊与缩放：只是把「还没看清」这件事说出来，
     幅度必须小到图片到位时读不出切换动作。 */
  filter: blur(6px);
  transform: scale(1.012);
}
html.js img.is-ld-shown {
  opacity: 1;
  filter: blur(0);
  transform: none;
  transition: opacity .5s var(--ease-out), filter .5s var(--ease-out), transform .6s var(--ease-out);
}

/* ==========================================================================
   32. 阅读进度：顶栏下方一条细线，随滚动推进
   --------------------------------------------------------------------------
   全站页面普遍 3–6 屏，长页（荣誉 5.8 屏 / 员工 5.8 屏）滚到中段后
   很难判断「还剩多少」。这条线给出位置与剩余量，不占版面高度。
   由脚本创建并驱动（.readbar），无脚本时不存在 —— 属纯增益。 */
.readbar {
  position: fixed; top: 0; left: 0; z-index: 120;
  height: 2px; width: 100%;
  transform-origin: 0 50%;
  transform: scaleX(0);
  background: linear-gradient(90deg, var(--blue-400), var(--blue-600));
  pointer-events: none;
  /* 只动 transform，走合成器；不监听 scroll 里的布局属性 */
  will-change: transform;
}
/* 吸顶导航本身有阴影，进度线贴在它上沿；导航收起时也不会被遮住 */
@media (max-width: 720px) { .readbar { height: 2px; } }
@media (prefers-reduced-motion: reduce) { .readbar { display: none; } }

/* ==========================================================================
   33. 视频条带：影像排成一行
   --------------------------------------------------------------------------
   视频展示页「厂区与团队影像」原有 4 段影像塞在 g3 里，排成 3 + 1：
   第二行那张卡只占 1296px 里的 416px，右侧近七成空白 —— 与产品分类页
   单件产品是同一个毛病（数量不满一行时，网格本身就在制造空洞）。
   4 段正好够一行。但全站 .g4 在 960 以下才收列，1100px 视口下会得到
   233px 宽的卡：16:9 封面只有 131px 高，配三行说明已经读不舒展了。
   所以另起一档断点，让这条带子在还读得清的宽度上才排 4 列。 */
.vgrid { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 1240px) { .vgrid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 720px) { .vgrid { grid-template-columns: 1fr; } }
/* ==========================================================================
   34. 关键数据条：固定背景（往下滚时照片不动，内容从上面滑过去）
   --------------------------------------------------------------------------
   原先这条是纯深色底，四格数据躺在上面。按要求加一张车间实景，
   并做成「鼠标往下滚、背景固定不动」的视差。

   ⚠️ 关键：照片与压暗渐变**必须在同一个 background 栈里、且同为 fixed**。
      渐变若另起一个 ::before 盖上去，它是跟着版块滚的，会与固定的照片错位 ——
      滚动时能看见「暗的那层在动、亮的那层不动」。
   ⚠️ background-attachment: fixed 会把 cover 的参照系由「元素」换成「视口」，
      于是照片始终铺满整屏、这段只是它的一个取景窗口 —— 视差感就是这么来的。
   ⚠️ iOS Safari 不支持 background-attachment: fixed（静默退化成 scroll）。
      下面备了窄屏与 reduced-motion 两处降级，退化成普通滚动背景，
      不会出现「只显示一小块图」那种破相。 */
.sec-stats {
  background-color: var(--dark);            /* 图挂掉时的兜底，仍是深色条 */
  /* 压暗的浓度是量出来的，不是拍的：先按「照片要看得见」定在 .70–.86，
     再逐像素量格子里的实际对比度（见下方 .stat__l 那条注释）。
     再深就只剩一块影子，再浅说明文字就压不住底图。 */
  background-image:
    linear-gradient(180deg,
      rgba(6, 20, 42, .84) 0%,
      rgba(9, 27, 54, .70) 42%,
      rgba(5, 17, 36, .86) 100%),
    url('../img/banner/b2-line.jpg');
  background-size: cover, cover;
  background-position: center, center;
  background-repeat: no-repeat, no-repeat;
  background-attachment: fixed, fixed;
  border-block: 1px solid var(--dark-line);
}
/* 数据格与分隔线原先是**不透明**深色，会整片盖住底图 —— 改成半透明，
   车间照片才透得上来，文字仍压在实色之上。
   ⚠️ 这两条必须写在前面「.sec--dark .stat / .stats--dark .stat」之后：
      特异性相同（都是 0,2,0），靠源码顺序取胜。挪到前面会被不透明底盖回去，
      而且**不报错**，只有看图才发现。 */
.sec-stats .stat { background: rgba(9, 25, 50, .50); }
.sec-stats .stats,
.sec-stats .stats--dark { background: rgba(160, 195, 235, .22); }
/* ⚠️ 说明文字必须在这条里提亮。全站深色底的次级文字是 50% 白（--on-dark-3），
   压在**纯色** #112A4C 上刚好 4.46:1 —— 本来就贴着 4.5:1 的地板。
   现在底子换成照片，格子内部还有明暗起伏，50% 白会有局部跌破地板。
   提到 62% 白后实测最差处仍有 4.9:1 以上。 */
.sec-stats .stat__l { color: rgba(245, 248, 255, .62); }

@media (max-width: 720px) {
  /* 窄屏取景窗口变成一条竖缝，固定背景也拿不到好处（且 Safari 本就不支持），
     退回普通滚动背景：图按元素高度铺满。 */
  .sec-stats {
    background-attachment: scroll, scroll;
    background-size: cover, cover;
    background-position: center, center;
  }
  .sec-stats .stat { background: rgba(9, 25, 50, .68); }
}
/* 视差是滚动联动的运动，前庭敏感的人会不适 —— 这类一律关掉固定背景 */
@media (prefers-reduced-motion: reduce) {
  .sec-stats { background-attachment: scroll, scroll; }
}

/* ==========================================================================
   35. 三大品牌：品牌标识墙
   --------------------------------------------------------------------------
   三张卡里只放品牌标识本身，不再有文字。三个 logo 的尺寸差得很远
   （600×526 近方形 / 186×236 竖长 / 478×115 横长），所以**只能用
   max-width + max-height 双约束等比缩放**；给固定 width/height 会把它们
   塞进同一个框，比例就毁了 —— 这正是内页旧页脚 logo 被拉扁的同一个坑。

   ⚠️ 卡面必须是纯白：三个 logo 都自带白底（第三张原图还是浅灰渐变底，
      已在素材阶段洗成纯白）。卡面一旦染色，每张 logo 四周就会露出一块白方块。
   ⚠️ max-height 用 clamp 而不是定值：窄屏卡片变矮，定值会把最高的那张挤出去。 */
.brandx { align-items: stretch; }
.brandx__i {
  position: relative; margin: 0; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  min-height: clamp(140px, 13vw, 200px);
  padding: clamp(22px, 2.4vw, 40px);
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  /* ⚠️ opacity 必须留在过渡列表里：本元素同时挂着 .rv（入场靠 opacity + transform）。
     这里一旦只写 transform，入场就变成「不淡入、直接平移出现」，
     而且不报错。悬停抬起用更短的 .5s，比入场的 .78s 跟手。 */
  transition: opacity .78s var(--ease-out),
              transform .5s var(--ease-out),
              box-shadow .5s var(--ease-out),
              border-color .32s var(--ease);
}
.brandx__i img {
  display: block;
  max-width: 100%;
  max-height: clamp(74px, 7.2vw, 104px);
  width: auto; height: auto;               /* 等比 —— 少一个都会被拉变形 */
  transition: transform .55s var(--ease-out);
}
/* 三个标识的宽高比相差 5 倍（1.14 / 0.79 / 4.16）。
   只靠「都塞进同一个框」的结果是：横长的那个几乎占满整卡、竖长的缩成一小条，
   三张卡摆在一起不像一套 —— 实测两边差到 4 倍宽。
   这里按视觉重量各收一档：竖长的给高一点、横长的给矮一点。
   两个类只写在对应那张卡上，换素材时记得一起改。 */
/* ⚠️ 必须写成**双类名** `.brandx__i.brandx__i--wide`。
   `brandx__i--wide` 是**一个**类名（BEM 的双短横不是第二个类），
   所以 `.brandx__i--wide img` 与 `.brandx__i img` 特异性完全相同（0,1,1）——
   下面窄屏里那条 `.brandx__i img { max-height: 68px }` 就会按源码顺序把它盖掉，
   而且是**静默**的：三张 logo 在窄屏上又变回同高，不报错、只有量尺寸才发现。
   双类名把它提到 (0,2,1)，与 `.qrbox__im.qrbox__im--ph` 是同一个手法。 */
.brandx__i.brandx__i--tall img { max-height: clamp(84px, 8.4vw, 118px); }
.brandx__i.brandx__i--wide img { max-height: clamp(46px, 4.3vw, 62px); }
/* 指针跟随倾斜挂在内层：外层要给 .rv 的入场和悬停抬起用 transform，
   两层挤在一个元素上会互相覆盖。倾角由脚本写进 --bx / --by（默认 0）。 */
.brandx__tilt {
  display: flex; align-items: center; justify-content: center;
  transform: perspective(760px) rotateX(var(--bx, 0deg)) rotateY(var(--by, 0deg));
  /* .18s：跟手但不抖。脚本每帧写入新的角度，留一点过渡把指针的抖动抹平；
     给太长（.45s 以上）卡片会明显追不上指针，读起来像延迟而不是跟随。 */
  transition: transform .18s var(--ease-out);
  will-change: transform;
}
.brandx__i:hover {
  transform: translateY(-6px);
  box-shadow: 0 26px 48px -26px rgba(12, 34, 68, .38);
  border-color: var(--blue-100);
}
.brandx__i:hover img { transform: scale(1.05); }
/* 键盘走到这里（目前卡片不可点，但保留焦点样式，将来接链接不用再补） */
.brandx__i:focus-within { border-color: var(--blue-300); }

@media (max-width: 720px) {
  /* 126 = 上下内边距 40 + 最高的那张 logo（--tall 的 84）+ 上下描边 2。
     这是个**算出来的**值，不是拍的：竖长那张的实际内容高就是 126，
     短线一档（118 / 124）都会让它把卡片撑出去，三张卡差几像素高，
     并排看就是歪的 —— 不报错，只有量高度才发现。 */
  .brandx__i { min-height: 126px; padding: 20px; }
  .brandx__i img { max-height: 68px; }
  /* 触屏没有 hover，抬起态只在指针设备上才有意义 */
  .brandx__i:hover { transform: none; box-shadow: none; }
}

/* 单行标题（三大品牌那句导语）
   --------------------------------------------------------------------------
   要真正做到「不换行」，必须**同时松开两处宽度限制**：
   .lede 自己的 62ch 与 .sec-head 的 760px。只松一个，文字照样在中间被折断。
   ⚠️ nowrap 只在 ≥700px 生效：这句话 40 个汉字，15px 字号下也要 600px 宽，
      窄屏上强行不折会顶出一条横向滚动条 —— 那比折成两行糟得多。 */
.sec-head--wide { max-width: none; }
.sec-head--wide .lede { max-width: none; }
@media (min-width: 700px) {
  .sec-head--wide .lede--one { white-space: nowrap; }
}

/* ==========================================================================
   36. 区位与产能：六格信息板
   --------------------------------------------------------------------------
   改前是「左 kv 列表 + 右三张图竖着叠成一列」的两栏：
     · 右列 707px 高（一张 4:3 大图 622×467，下面再压两张 299×224）
     · 左列文字只有 284px，grid 又是 align-items:center，上下各空出 210px
     · 整个版块被图撑到 914px —— 在 900px 高的屏幕上装不下，左半边却是空的

   改成六格等高的信息板（3 列 × 2 行），六格等宽等高：
     · 图片从「独占一栏」降为「其中两格」，图片面积 424k → 132k px²
     · 版块高度不再由「最高的那一列」决定，而是「一行格 + 一行格」：914 → 611px
     · 左半边被 4 个事实格填满，不再是一列居中的小字

   ⚠️ .geo 同时挂着 .rv（入场 opacity+translateY）与 :hover 抬起（translateY）。
      过渡里必须保留 opacity —— 只写 transform 会让入场变成「不淡入、直接平移出现」，
      而且不报错。上一轮页脚品牌墙踩的就是这个坑。
   ⚠️ .geo__media 用 inset:-14% 上下各多出 14% 高，是给 data-parallax 的位移留余量。
      不给余量的话滚到两端时图片会被拉出格子、露出底色。14% × 182 ≈ 25px，
      而 data-parallax="0.05" 在 900px 视口里最大位移约 ±22px，刚好够。
   ========================================================================== */
/* 标题行：h2 靠左、导语靠右，撑满整行。
   堆叠写的话导语会被 .lede 自己的 62ch 顶成两行（38 字 × 15.5px = 591px > 62ch≈565px），
   而 h2 下面右边整片空着 —— 那正是这个版块原本的毛病，别在标题行里重演一遍。
   ⚠️ .sec-head 自带 max-width:760px，这里必须显式松开，否则两栏挤在 760 里。 */
.geoh {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: clamp(24px, 4vw, 72px);
  max-width: none;
  margin-bottom: clamp(20px, 2.2vw, 32px);
}
.geoh .lede { max-width: 40em; }
@media (max-width: 900px) {
  .geoh { display: block; }
  /* 48em 而不是 .lede 自带的 62ch：768–900 这段容器已经比句子宽了，
     用 62ch（≈565px）会把本来一行放得下的导语硬折成两行、末行只剩「齐备。」 */
  .geoh .lede { max-width: 48em; margin-top: 10px; }
}

.geog {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(12px, 1.15vw, 18px);
}

.geo {
  position: relative;
  display: flex; flex-direction: column; justify-content: center;
  min-height: clamp(146px, 12.4vw, 182px);
  padding: clamp(18px, 1.7vw, 26px);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  overflow: hidden;
  transition: opacity .78s var(--ease-out),
              transform .5s var(--ease-out),
              box-shadow .5s var(--ease-out),
              border-color .32s var(--ease);
}
.geo__k {
  display: flex; align-items: center; gap: 7px;
  font-size: 12.5px; font-weight: 700; letter-spacing: .06em;
  color: var(--blue-600);
}
.geo__k::before {
  content: ""; width: 3px; height: 12px; border-radius: 2px;
  background: var(--green-500); flex: none;
}
.geo__v {
  margin-top: 9px;
  font-size: clamp(17px, 1.3vw, 21px); line-height: 1.34;
  font-weight: 800; letter-spacing: -.012em; color: var(--ink);
  text-wrap: balance;
}
.geo__d {
  margin-top: 8px;
  font-size: 13.5px; line-height: 1.72; color: var(--ink-3);
}

/* --- 图片格：照片铺满整格，只当质感层 ---
   文字全部落在下半部，所以压暗做「上淡下浓」：顶部 .30 让车间照看得出来，
   底部 .90 保证 13.5px 的说明文字压得住（对比度实测见交付说明）。 */
.geo--ph { padding: 0; background: var(--bg-3); }
.geo__media { position: absolute; inset: -14% 0; z-index: 0; }
.geo__media img {
  display: block; width: 100%; height: 100%; object-fit: cover;
  transition: transform .7s var(--ease-out);
}
.geo--ph::after {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(180deg,
    rgba(6, 20, 42, .32) 0%,
    rgba(7, 23, 47, .72) 38%,
    rgba(5, 16, 35, .92) 100%);
}
/* flex:1 而不是 height:100% —— 父级高度由 grid 拉伸给出是确定的，
   但用 flex 填满不依赖百分比高度的传递，少一层出错的机会 */
.geo--ph .geo__body {
  position: relative; z-index: 2; flex: 1;
  display: flex; flex-direction: column; justify-content: flex-end;
  padding: clamp(18px, 1.7vw, 26px);
}
/* ⚠️ 标签在图片格上不能用绿色字：--green-400 (#97CE3C) 虽然亮，但压在
   车间照的中间调上实测只有 3.94:1（最差 2.91:1），12.5px 达不到 AA 4.5:1。
   改成白字，绿留给人前面那条小竖条（纯装饰，不涉及对比度）。 */
.geo--ph .geo__k { color: rgba(255, 255, 255, .92); }
.geo--ph .geo__k::before { background: var(--green-400); }
.geo--ph .geo__v { color: #fff; }
.geo--ph .geo__d { color: rgba(255, 255, 255, .86); }

/* --- 交互：抬起 + 描边转蓝 + 投影；图片格同时把照片推近一点 --- */
.geo:hover, .geo:focus-within {
  transform: translateY(-4px);
  box-shadow: 0 20px 38px -22px rgba(9, 30, 62, .34);
  border-color: var(--blue-100);
}
.geo--ph:hover .geo__media img { transform: scale(1.045); }

@media (max-width: 860px) {
  .geog { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 600px) {
  .geog { grid-template-columns: 1fr; gap: 12px; }
  .geo { min-height: 0; padding: 20px; }
  .geo--ph { min-height: 152px; padding: 0; }
  .geo--ph .geo__body { padding: 20px; }
  /* 触屏没有 hover，抬起态只对指针设备有意义 */
  .geo:hover, .geo:focus-within { transform: none; box-shadow: none; }
}
/* 视差与抬起都是滚动/指针联动的运动，前庭敏感的人会不适 —— 一律关掉 */
@media (prefers-reduced-motion: reduce) {
  .geo:hover, .geo:focus-within { transform: none; }
  .geo--ph:hover .geo__media img { transform: none; }
}

/* ==========================================================================
   37. 新闻资讯列表页：头条大卡 + 带缩略图的列表
   --------------------------------------------------------------------------
   改前 #nlist 是一个纯文字列表（日期块 + 标题 + 一行摘要 + 分类 pill + 箭头），
   八条长得一模一样，整页一张图都没有 —— 首页与两个子栏目都是 .ncard 图文卡，
   只有「全部资讯」这一页像另一个站。

   改后：第一条升为横向大卡（左图右文），其余七条在原地加一张 16:10 缩略图。
   图片全部复用数据里已有的 n['img']，没有新增素材。

   ⚠️ .nitem--img 系列的特异性只比 .nitem 高一级，**必须写在本文件末尾**才能
      盖过后面的 960 / 720 断点（.nitem 在 1141、1146 行）。挪到前面会静默失效：
      宽屏看着对，一进平板就退回三列、缩略图错位，而且不报错。
   ⚠️ 头条卡与七行必须留在同一个 #nlist 里 —— filters() 是按 #nlist 找
      [data-cat] 做分类筛选的。把头条挪到 #nlist 外面，筛「行业新闻」时
      它会赖着不走。
   ⚠️ .nitem__cat 原本在 ≤960 被 display:none 掉。列表页混着公司动态与行业新闻，
      分类在平板上更不能丢 —— 这里用 .nitem--img .nitem__cat 提权保住它。
   ========================================================================== */

/* --- 头条大卡 --- */
.nlist--rich { display: block; background: none; gap: 0; border-radius: 0; overflow: visible; }
.nlead {
  display: grid; grid-template-columns: 1.06fr 1fr;
  min-height: clamp(248px, 23vw, 322px);
  margin-bottom: clamp(14px, 1.5vw, 20px);
  background: var(--surface); border: 1px solid var(--line-2);
  border-radius: var(--r-md); overflow: hidden;
  transition: .34s var(--ease);
}
.nlead:hover { box-shadow: var(--sh-3); border-color: var(--blue-100); }
.nlead__media { position: relative; overflow: hidden; background: var(--bg-3); min-height: 0; }
.nlead__media img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  transition: transform .9s var(--ease-out);
}
.nlead:hover .nlead__media img { transform: scale(1.045); }
.nlead__cat {
  position: absolute; top: 16px; left: 16px; z-index: 2;
  font-size: 12.5px; padding: 4px 12px; border-radius: 100px;
  background: rgba(6, 26, 54, .8); color: var(--on-dark); backdrop-filter: blur(6px);
}
.nlead__bd {
  padding: clamp(22px, 2.4vw, 40px);
  display: flex; flex-direction: column; justify-content: center;
}
.nlead__date { display: flex; align-items: baseline; gap: 8px; font-family: var(--font-num); margin-bottom: 12px; }
.nlead__date b { font-size: clamp(24px, 2.2vw, 30px); font-weight: 700; color: var(--blue-600); line-height: 1; }
.nlead__date span { font-size: 12.5px; color: var(--ink-4); letter-spacing: .04em; }
.nlead__bd h3 {
  font-size: clamp(18px, 1.55vw, 22px); line-height: 1.42; font-weight: 700;
  color: var(--ink); margin-bottom: 12px; text-wrap: balance;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
  transition: color .28s var(--ease);
}
.nlead:hover h3 { color: var(--blue-600); }
.nlead__bd p {
  font-size: 13.5px; line-height: 1.75; color: var(--ink-3);
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.nlead__go {
  display: inline-flex; align-items: center; gap: 7px; margin-top: 18px;
  font-size: 13.5px; font-weight: 600; color: var(--blue-600);
}
.nlead__go svg { width: 15px; height: 15px; transition: transform .3s var(--ease); }
.nlead:hover .nlead__go svg { transform: translateX(4px); }

/* --- 列表行：加一列 16:10 缩略图 --- */
.nrows { display: grid; gap: 1px; background: var(--line-2); border-radius: var(--r-md); overflow: hidden; }
.nitem--img { grid-template-columns: 76px 1fr 132px 30px; padding-block: 16px; }
.nitem--img .nitem__t { display: flex; flex-direction: column; }
.nitem--img .nitem__cat {
  display: inline-flex; align-self: flex-start; flex: none;
  margin-bottom: 7px;
}
.nitem__ph { aspect-ratio: 16 / 10; overflow: hidden; border-radius: var(--r-sm); background: var(--bg-3); }
.nitem__ph img { width: 100%; height: 100%; object-fit: cover; transition: transform .8s var(--ease-out); }
.nitem--img:hover .nitem__ph img { transform: scale(1.06); }

@media (max-width: 1080px) {
  .nitem--img { grid-template-columns: 70px 1fr 116px 30px; }
}
@media (max-width: 860px) {
  .nlead { min-height: 0; }
  .nlead__bd { padding: clamp(20px, 3vw, 28px); }
  .nlead__bd h3 { -webkit-line-clamp: 2; }
  .nlead__bd p { -webkit-line-clamp: 2; }
  .nitem--img { grid-template-columns: 64px 1fr 104px 30px; }
}
@media (max-width: 700px) {
  /* 窄屏一行塞不下「日期 + 文字 + 缩略图 + 箭头」。缩略图与箭头一起收掉，
     退回原来的两列，文字才不会被挤成一条竖缝。
     头条同步改成上下叠，图片给死 min-height —— 单列时媒体块里只有一张
     绝对定位的图，不写高度会被 grid 的 stretch 压成 0。 */
  .nlead { grid-template-columns: 1fr; }
  .nlead__media { aspect-ratio: 16 / 10; min-height: 190px; }
  .nlead__go { margin-top: 14px; }
  .nitem--img { grid-template-columns: 54px 1fr; }
  .nitem__ph { display: none; }
}

/* ==========================================================================
   首页板块标签（关于我们 / 产品中心 / 新闻资讯）· eyebrow
   绿色竖线 + 板块名。三处共用同一套结构与交互；不改动原有标题层级（<h2> 仍是 <h2>）。
   克制口径：不用渐变文字、不做发光堆砌 —— 质感靠竖线的圆头、低透明度色环与统一缓动。
   ========================================================================== */
.sec-eyebrow {
  display: inline-flex; align-items: center; gap: 10px;
  /* 与下方标题的间距：12px 反馈偏挤 ⇒ 18px，让标签与标题分属两个视觉层 */
  margin-bottom: 18px;
  font-size: 13.5px; font-weight: 600; letter-spacing: .06em; line-height: 1;
  color: var(--green-600);
  transition: color .32s var(--ease);
}
.sec-eyebrow__bar {
  display: block; width: 3px; height: 16px; border-radius: 999px;
  background: var(--green-500);
  /* 色环用品牌绿的低透明度，不用投影 —— 避免"发光"廉价感 */
  box-shadow: 0 0 0 0 rgba(124, 181, 24, 0);
  transform-origin: 50% 50%;
  transition: transform .32s var(--ease), background-color .32s var(--ease), box-shadow .32s var(--ease);
}
/* 统一的 hover 反馈：三处板块头（关于我们 / 产品中心 / 新闻资讯）同一套，不各写一份 */
.panel__txt:hover .sec-eyebrow__bar,
.panel__head:hover .sec-eyebrow__bar,
.newsx__head:hover .sec-eyebrow__bar {
  transform: scaleY(1.35);
  background: var(--green-400);
  box-shadow: 0 0 0 3px rgba(124, 181, 24, .10);
}
.panel__txt:hover .sec-eyebrow,
.panel__head:hover .sec-eyebrow,
.newsx__head:hover .sec-eyebrow { color: var(--green-500); }

/* 板块标题字号收敛（比通用 .h2 小一档） */
.h2--sec { font-size: clamp(22px, 2.4vw, 31px); line-height: 1.28; }
@media (max-width: 900px) { .h2--sec { font-size: clamp(20px, 5vw, 26px); } }

/* 无障碍：用户开了"减少动态"就退化成静态，不给任何位移 */
@media (prefers-reduced-motion: reduce) {
  .sec-eyebrow, .sec-eyebrow__bar { transition: none; }
  .panel__txt:hover .sec-eyebrow__bar,
  .panel__head:hover .sec-eyebrow__bar,
  .newsx__head:hover .sec-eyebrow__bar { transform: none; }
}


/* ==========================================================================
   发展历程 · 时间轴紧凑版（用户要求：板块更矮、一屏看完所有内容）
   只收紧纵向节奏与字号，不改结构；信息一条不少。
   ========================================================================== */
.tl--tight .tl__i { padding-bottom: clamp(13px, 1.5vw, 20px); }
.tl--tight .tl__y { font-size: 17px; margin-bottom: 3px; }
.tl--tight .tl__i h4 { font-size: 15px; margin-bottom: 3px; }
.tl--tight .tl__i p { font-size: 12.8px; line-height: 1.55; }
.tl--tight .tl__i::before { top: 4px; width: 10px; height: 10px; border-width: 2.5px; }

/* ==========================================================================
   内容页（产品 / 新闻）：封面块 · 介绍块 · 上一篇下一篇
   与整站同一套令牌（--line-2 / --bg-2 / --blue-600 / --ease），不引入新配色。
   ========================================================================== */
.pd__cover { border-radius: var(--r-md); overflow: hidden; background: var(--bg-3); }
.pd__cover img { width: 100%; height: auto; display: block; object-fit: cover; }
.pd__intro {
  margin-top: 22px; padding: 18px 20px;
  background: var(--bg-2); border: 1px solid var(--line-2); border-radius: var(--r-md);
}
.pd__intro p { font-size: 14.4px; line-height: 1.85; color: var(--ink-2); }

.pn {
  margin-top: 44px; padding-top: 26px; border-top: 1px solid var(--line-2);
  display: grid; grid-template-columns: 1fr 1fr; gap: 16px;
}
.pn__i {
  display: flex; flex-direction: column; gap: 7px;
  padding: 15px 17px; border: 1px solid var(--line-2); border-radius: var(--r-md);
  background: var(--bg-2); text-decoration: none;
  transition: border-color .28s var(--ease), background-color .28s var(--ease), transform .28s var(--ease);
}
.pn__i--next { align-items: flex-end; text-align: right; }
.pn__i:hover { border-color: var(--blue-400); background: var(--blue-50); transform: translateY(-1px); }
.pn__i--empty { border: 0; background: none; pointer-events: none; }
.pn__k { display: inline-flex; align-items: center; gap: 5px; font-size: 12.6px; color: var(--ink-3); }
.pn__k svg { width: 14px; height: 14px; }
.pn__t { font-size: 14.6px; font-weight: 600; color: var(--ink); line-height: 1.5; }
@media (max-width: 720px) { .pn { grid-template-columns: 1fr; } .pn__i--next { align-items: flex-start; text-align: left; } }

/* ==========================================================================
   内容页（产品 / 新闻）：标题下的元信息行 + 翻页条禁用态
   与整站同一套令牌，不引入新配色。
   ========================================================================== */
.pd-meta { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 14px; }
.pd-meta .small { color: var(--on-dark-3); }

/* 翻页条：两侧恒显 —— 没有了的那侧是禁用态（不空着，保持左右对称） */
.pn { margin-top: 44px; padding-top: 26px; border-top: 1px solid var(--line-2); display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.pn__i {
  display: flex; flex-direction: column; gap: 7px;
  padding: 15px 17px; border: 1px solid var(--line-2); border-radius: var(--r-md);
  background: var(--bg-2); text-decoration: none;
  transition: border-color .28s var(--ease), background-color .28s var(--ease), transform .28s var(--ease);
}
.pn__i--next { align-items: flex-end; text-align: right; }
.pn__i:not(.is-off):hover { border-color: var(--blue-400); background: var(--blue-50); transform: translateY(-1px); }
.pn__k { display: inline-flex; align-items: center; gap: 5px; font-size: 12.6px; color: var(--ink-3); }
.pn__k svg { width: 14px; height: 14px; }
.pn__t { font-size: 14.6px; font-weight: 600; color: var(--ink); line-height: 1.5; }
/* 禁用态：不可点、弱化，但仍占位 */
.pn__i.is-off { opacity: .45; cursor: not-allowed; }
.pn__i.is-off .pn__t { font-weight: 500; color: var(--ink-3); }
@media (max-width: 720px) { .pn { grid-template-columns: 1fr; } .pn__i--next { align-items: flex-start; text-align: left; } }

/* ===== 组件库 geo-intro（AI 速览）自带样式：并入站点样式表，否则线上不生效 ===== */
/* AI 速览（geo-intro）样式 —— 语义类 + 令牌层，无原子类依赖。
 *
 * ⚠️ 本文件是**原物料的 CSS 逐字搬运**，不是重新设计：
 *    来源 `materials-master/components/geo-intro/body.json` 的 `css` 字段
 *    （= designer 侧 `geo-intro-component.ts` 的 `GEO_INTRO_CSS`，两处逐字相同）。
 *    改皮肤请改这份文件（装进站点工程后它就是你自己的源码），而不是在这里加平台语义。
 *
 * 令牌 / 回退：
 *   · 只有「印章 ❖」与「打字光标」吃主题色：`var(--color-theme-primary, #b0894e)`
 *     —— 站点改 `--color-theme-primary` 时它们一起变色；取不到令牌就回落到物料的暖金 #b0894e。
 *   · 其余颜色（边框 #ded3ba / 内描边 #efe6d2 / 文字 #2b2620 / 标签 #8a7f6b）是物料设计里的
 *     **固定暖金纸感**，原本就没有令牌，照原样保留。
 *   · `font-family:inherit`：字体继承页面，不自己引字体。
 *
 * 🔴 有意**没有**的东西（原物料就没有，别以为是漏了）：
 *   · 没有 `@media (max-width: …)` 移动端分支 —— 这个块本来就是流式的
 *     （`max-width:560px` + `margin:24px auto` + 行高/光标全用 em），窄屏自动收窄。
 *   · 没有 `@media (prefers-reduced-motion: reduce)` 分支 —— **减少动效是在 JS 里处理的**
 *     （见 `use-geo-typing.ts`：命中 reduced-motion 就完全不播，保持服务端直出的静态全文）。
 *     不播就不会有光标，所以这里也没有"关掉光标闪烁"要写。
 */

.geo-intro {
  border: 1px solid #ded3ba;
  box-shadow: inset 0 0 0 3px #fff, inset 0 0 0 4px #efe6d2;
  background: #fff;
  border-radius: 2px;
  padding: 20px 26px;
  margin: 24px auto;
  max-width: 560px;
  font-family: inherit;
}

.geo-intro-label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  line-height: 1;
  margin-bottom: 13px;
}

/* ❖ 印章：吃主题色，取不到回落暖金 */
.geo-seal {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  font-size: 13px;
  color: var(--color-theme-primary, #b0894e);
  position: relative;
  top: 0.5px;
}

.geo-lab-txt {
  display: inline-flex;
  align-items: center;
  line-height: 1;
  font-size: 11px;
  letter-spacing: 0.3em;
  color: #8a7f6b;
}

/* 正文：`min-height:2em` 是给还没打完/只有一行时占位，避免整块高度跳动 */
.geo-intro-text {
  text-align: left;
  font-size: 14px;
  line-height: 2;
  color: #2b2620;
  letter-spacing: 0.04em;
  margin: 0;
  min-height: 2em;
}

/* 打字光标：打完由 JS 移除（`el.textContent = full` 顺带把光标节点一起去掉） */
.geo-caret {
  display: inline-block;
  width: 1px;
  height: 1.02em;
  background: var(--color-theme-primary, #b0894e);
  margin-left: 2px;
  vertical-align: -2px;
  animation: geo-blink 1.1s steps(1) infinite;
}

@keyframes geo-blink {
  50% {
    opacity: 0;
  }
}


/* ==========================================================================
   内容页（产品 / 新闻）统一版式 —— 标题 · 元信息 · 摘要 · AI 速览 · 正文
   🔴 关键：这几块的**左右跨度必须完全一致**。所以：
     ① 标题不再放全宽页头（那会让标题比正文宽）；
     ② 所有块都在同一个 .wrap--narrow 列里，且**不额外加左右 margin/padding**；
     ③ 组件自带块（geo-intro）也用同一列宽，只补上下间距。
   ========================================================================== */
.cd__title {
  margin-top: 18px;
  font-size: clamp(24px, 2.9vw, 36px);
  line-height: 1.28;
  text-wrap: balance;
}
.cd__meta { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 14px; }
.cd__meta .small { color: var(--ink-3); }
.cd__abs {
  margin-top: 18px; padding: 14px 16px;
  font-size: 13.8px; line-height: 1.75; color: var(--ink-3);
  background: var(--bg-2); border: 1px solid var(--line-2); border-radius: var(--r-md);
}
/* 速览块与正文的上下间距（宽度交给组件/容器，这里只碰纵向） */
.cd__body { margin-top: 22px; }
.wrap--narrow > .geo-intro { margin-top: 18px; }
/* 正文里的图片与容器同宽，避免"图比文宽" */
.cd__body img { max-width: 100%; height: auto; }

/* 内容页修正 v33
   ① 标题块居中  ② 摘要框与正文同宽  ③ AI 速览与正文同宽 + 改站点品牌绿（覆盖组件默认暖金/白）
   ⚠️ 只改宽度与配色，不动组件内部排版，不引入新变量。 */
.cd__head { text-align: center; margin-top: 4px; }
.cd__head .cd__meta { justify-content: center; }
.cd__abs { width: 100%; box-sizing: border-box; }
.wrap--narrow .geo-intro,
.geo-intro {
  width: 100%; box-sizing: border-box;
  --color-theme-primary: var(--green-600);
  border: 1px solid rgba(124, 181, 24, .34);
  background: var(--green-100);
  border-radius: var(--r-md);
}
.geo-intro .geo-intro-text { color: var(--ink-2); }
.geo-intro .geo-lab-txt { color: var(--green-700); }

/* 内容页同宽 修正 v34
   🔴 关键：组件自带 .geo-intro 里写死了 max-width:560px + margin:24px auto
   ⇒ 光设 width:100% 会被 max-width 卡住（这就是"AI 速览宽度没改"的根因）。
   这里把三块（摘要 / AI 速览 / 正文）统一成"占满同一列、零左右外边距"。
   ③ 另外 .phead__in 也用同一列宽，banner 里的面包屑才和正文左右对齐。 */
.wrap--narrow .cd__abs,
.wrap--narrow .geo-intro,
.wrap--narrow .cd__body {
  width: 100%;
  max-width: none;      /* ← 清掉组件的 560px 上限 */
  margin-left: 0;       /* ← 清掉组件的 auto 居中 */
  margin-right: 0;
  box-sizing: border-box;
}
.wrap--narrow .geo-intro {
  margin-top: 18px;
  margin-bottom: 0;
  --color-theme-primary: var(--green-600);
  border: 1px solid rgba(124, 181, 24, .34);
  background: var(--green-100);
  border-radius: var(--r-md);
  box-shadow: none;     /* ← 去掉组件默认的双层内阴影（暖金边框感） */
}

/* 摘要框 修正 v35
   用户口径：灰色背景框 **和内容主体同宽**，且**框里的文字居中**。 */
.wrap--narrow .cd__abs {
  width: 100%;
  max-width: none;          /* 不被任何上限卡窄 */
  margin-left: 0;
  margin-right: 0;
  text-align: center;       /* ← 框内文字居中 */
  box-sizing: border-box;
}

/* 内容列作用域 v36
   内容页容器已从「窄栏 .wrap--narrow」改为与列表页一致的「.wrap」⇒
   原来的 .wrap--narrow 作用域换成内容列的 .cd（宽度规则本身不变：占满该列、无左右外边距）。 */
.cd .cd__abs,
.cd .geo-intro,
.cd .cd__body {
  width: 100% !important;
  max-width: none !important;
  margin-left: 0 !important;
  margin-right: 0 !important;
  box-sizing: border-box;
}
.cd .geo-intro { margin-top: 18px; margin-bottom: 0; }

/* 右下角悬浮按钮对齐 v37
   🔴 三个元素（从下到上）：回到顶部 .totop → 数字人客服气泡（官方 widget）→ 客服球 .ai-orb
   「以回到顶部为对齐对象、居中对齐」= 三者的**水平中心线同一条**。
   尺寸不同 ⇒ 用 right 值反推，让中心都落在「距右边缘 44px」这条线上：
     .totop  44px : right 22 → 中心 22 + 22 = 44
     气泡    60px : right 14 → 中心 14 + 30 = 44
     客服球  56px : right 16 → 中心 16 + 28 = 44
   纵向：.totop 占 26→70；气泡 84→144；客服球 158→214，两两间距 14px。
   —— 官方组件的定位由它自己的 CSS 变量控制：--dcs-offset-x / --dcs-offset-y（.dcs-bubble 那条写死了 24px，单独覆盖）。 */
:root {
  --ai-orb-x: 16px;
  --ai-orb-y: 158px;
  --dcs-offset-x: 14px;
  --dcs-offset-y: 84px;
}
.ai-orb--bottom-right {
  --ai-orb-x: 16px;
  --ai-orb-y: 158px;
}
.dcs-bubble { right: 14px !important; bottom: 84px !important; }
.dcs-web-bubble, .dcs-mini-bubble { right: var(--dcs-offset-x, 14px) !important; bottom: var(--dcs-offset-y, 84px) !important; }
@media (max-width: 720px) {
  :root { --dcs-offset-y: 78px; --ai-orb-y: 148px; }
  .dcs-bubble { bottom: 78px !important; }
}

/* 悬浮按钮对齐 v38（修正 v37 没生效的原因）
   🔴 根因：页面加载了两个样式表 ——
        site.css（本文，先加载） → index-*.css（Vite 打包的组件样式，后加载）
      组件在 index-*.css 里写了 .ai-orb{--ai-orb-x:24px;--ai-orb-y:78px}
      ⇒ 同为「一个类」的优先级、但它**在后面** ⇒ 把 :root 上的值盖掉 ⇒ 客服球纹丝不动。
   修法：① 用更高优先级（两个类 + html 前缀）② 加 !important
   三元素对齐口径不变：以「回到顶部」为基准，水平中心线重合（中心距右边缘 44px），纵向间距 14px。 */
html .ai-orb,
html .ai-orb.ai-orb--bottom-right,
body .ai-orb--bottom-right {
  --ai-orb-x: 16px !important;
  --ai-orb-y: 158px !important;
}
/* 官方组件：气泡用它的变量（自定义属性可跨 shadow 边界继承）；.dcs-bubble 那条写死 24px，一并覆盖 */
html {
  --dcs-offset-x: 14px;
  --dcs-offset-y: 84px;
}
.dcs-bubble { right: 14px !important; bottom: 84px !important; }

@media (max-width: 720px) {
  html .ai-orb, html .ai-orb.ai-orb--bottom-right, body .ai-orb--bottom-right {
    --ai-orb-y: 148px !important;
  }
  html { --dcs-offset-y: 78px; }
  .dcs-bubble { bottom: 78px !important; }
}

/* 悬浮按钮最终排布 v39
   🔴 事实：官方「数字人客服」气泡是 .dcs-mini-bubble，位置由**平台实例配置**的
      offsetX/offsetY 决定（组件有 offsetX/offsetY/offsetUnit 配置项，且以**内联样式**写在元素上）
      ⇒ 外部 CSS（含 !important、含 :root 变量）都改不动它。当前它固定在 right 24 / bottom 24 / 64px。
   ⇒ 因此改成「以它为基准轴往上排」：三者的水平中心线都落在「距右边缘 56px」这条线上（24 + 64/2）。
       数字人气泡（平台固定） : bottom 24  → 24~88   中心 56
       客服球   56px          : right 28  → bottom 102（88 + 14）
       回到顶部 44px          : right 34  → bottom 172（102 + 56 + 14）
   ⚠️ 若希望「回到顶部」在最底部，需在**平台侧**把该客服实例的 offsetY 调高（组件设置里的位置偏移）——
      那是平台配置，不在本站代码里。 */
html .ai-orb,
html .ai-orb.ai-orb--bottom-right,
body .ai-orb--bottom-right {
  --ai-orb-x: 28px !important;
  --ai-orb-y: 102px !important;
}
.totop { right: 34px !important; bottom: 172px !important; }

@media (max-width: 720px) {
  html .ai-orb, html .ai-orb.ai-orb--bottom-right, body .ai-orb--bottom-right {
    --ai-orb-y: 94px !important;
  }
  .totop { bottom: 160px !important; }
}

/* 图册 v41
   ① 图片排小 + 行高收窄：格子比例由 4:3 改为 16:10，并给每个格子加「不超过 24vh」的高度上限
      ⇒ 两行 ≈ 50vh、三行 ≈ 76vh，**超过一屏的图册自动收进一屏内**（比例由 aspect-ratio 保证，不拉伸）
   ② 大图预览的左右切换按钮 */
.gal__i { aspect-ratio: 16 / 10; max-height: 24vh; }
.gal--4 .gal__i, .gal--5 .gal__i { aspect-ratio: 4 / 3; max-height: 20vh; }
@media (max-width: 900px) { .gal__i, .gal--4 .gal__i, .gal--5 .gal__i { aspect-ratio: 4 / 3; max-height: 30vh; } }

/* 大图预览：左右切换 */
.lb__nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 46px; height: 46px; border-radius: 50%;
  display: grid; place-items: center; cursor: pointer;
  background: rgba(255, 255, 255, .12); border: 1px solid rgba(255, 255, 255, .22);
  color: #fff; transition: background-color .25s var(--ease), border-color .25s var(--ease);
}
.lb__nav:hover { background: rgba(255, 255, 255, .22); border-color: rgba(255, 255, 255, .4); }
.lb__nav svg { width: 22px; height: 22px; }
.lb__prev { left: 22px; }
.lb__next { right: 22px; }
.lb__idx {
  position: absolute; left: 50%; transform: translateX(-50%); bottom: 20px;
  font-size: 13px; color: rgba(255, 255, 255, .78); letter-spacing: .04em;
}
@media (max-width: 720px) { .lb__nav { width: 40px; height: 40px; } .lb__prev { left: 8px; } .lb__next { right: 8px; } }

/* 板块头「标题 + 描述」放一行（员工风采「一线即现场」、人才招聘「在招岗位」等） */
.sec-head--row {
  display: flex; align-items: baseline; gap: clamp(12px, 1.4vw, 22px);
  flex-wrap: wrap;
}
.sec-head--row .h2 { margin: 0; flex: none; }
.sec-head--row .lede { margin: 0; max-width: none; font-size: 14px; }
@media (max-width: 720px) {
  .sec-head--row { align-items: flex-start; gap: 8px; }
}

/* 图册密度 + 预览适配 v43
   ① 图缩小后间距显得过大 ⇒ **每排数量增加**（宽屏 4列→5列、3列→4列）+ 收紧 gap
      ⇒ 同样宽度下内容更密、空白更少；同时把格子上限放宽到 26vh（不再把图压得过小）
   ② 大图预览：竖图超出一屏会看不全 ⇒ 高度按视口算（100vh - 130px），配合 object-fit:contain 整张可见 */
.gal { gap: clamp(8px, .9vw, 13px); }
.gal__i { aspect-ratio: 4 / 3; max-height: 26vh; }
.gal--4 .gal__i, .gal--5 .gal__i { aspect-ratio: 4 / 3; max-height: 24vh; }
@media (min-width: 1200px) {
  .gal--4 { grid-template-columns: repeat(5, 1fr); }
  .gal--3 { grid-template-columns: repeat(4, 1fr); }
  .gal--5 { grid-template-columns: repeat(6, 1fr); }
}
@media (min-width: 1600px) {
  .gal--4 { grid-template-columns: repeat(6, 1fr); }
  .gal--3 { grid-template-columns: repeat(5, 1fr); }
  .gal--5 { grid-template-columns: repeat(7, 1fr); }
}
@media (max-width: 900px) { .gal__i, .gal--4 .gal__i, .gal--5 .gal__i { aspect-ratio: 4 / 3; max-height: 30vh; } }

/* 大图预览：整张看全 */
.lb { padding: 20px 78px; }
.lb img { max-width: 100%; max-height: calc(100vh - 120px); width: auto; height: auto; object-fit: contain; }
@media (max-width: 720px) { .lb { padding: 14px 52px; } .lb img { max-height: calc(100vh - 90px); } }

/* ==========================================================================
   企业文化页 · 图形化排版 v45（去掉照片，改用图形卡）
   · .mvv   ——「使命与愿景」右侧：使命 / 愿景 / 承诺 三张图形卡
   · .teamg ——「人，是质量的最后一公里」左侧：三支队伍 图形卡
   全部用站点既有令牌（--blue-50 / --green-* / --line-2 / --r-md / --ease），不引入新配色。
   ========================================================================== */
.mvv { display: grid; gap: 14px; }
.mvv__i {
  display: flex; align-items: flex-start; gap: 14px;
  padding: 18px 20px; border-radius: var(--r-md);
  background: var(--bg-2); border: 1px solid var(--line-2);
  border-left: 3px solid var(--green-500);
  transition: transform .28s var(--ease), border-color .28s var(--ease), background-color .28s var(--ease);
}
.mvv__i:hover { transform: translateX(3px); border-left-color: var(--blue-600); background: var(--blue-50); }
.mvv__ico {
  flex: none; width: 40px; height: 40px; border-radius: 12px;
  display: grid; place-items: center; color: var(--green-700);
  background: var(--green-100);
}
.mvv__ico svg { width: 21px; height: 21px; }
.mvv__i b { display: block; font-size: 15.4px; color: var(--ink); margin-bottom: 5px; }
.mvv__i span { display: block; font-size: 13.4px; line-height: 1.7; color: var(--ink-3); }

.teamg { display: grid; gap: 14px; }
.teamg__i {
  display: flex; align-items: flex-start; gap: 14px;
  padding: 20px; border-radius: var(--r-md);
  background: var(--surface); border: 1px solid var(--line-2);
  box-shadow: var(--sh-1, 0 2px 10px rgba(6,26,54,.05));
  transition: transform .28s var(--ease), box-shadow .28s var(--ease), border-color .28s var(--ease);
}
.teamg__i:hover { transform: translateY(-2px); border-color: var(--blue-400); }
.teamg__ico {
  flex: none; width: 44px; height: 44px; border-radius: 14px;
  display: grid; place-items: center; color: var(--blue-600);
  background: var(--blue-50);
}
.teamg__ico svg { width: 23px; height: 23px; }
.teamg__i b { display: block; font-size: 15.6px; color: var(--ink); margin-bottom: 5px; }
.teamg__i span { display: block; font-size: 13.4px; line-height: 1.7; color: var(--ink-3); }

/* 招聘正文边距 v48
   平台正文是多段 <p>/<h2>，自带外边距 ⇒ 在折叠面板里会出现"第一行贴顶、段间过大"。
   这里把首尾外边距清零、并给一个统一的左右/上下内边距，视觉和原来一致。 */
.pane__bd { padding: 4px 22px 22px; }
.pane__bd > :first-child { margin-top: 0; }
.pane__bd > :last-child { margin-bottom: 0; }
.pane__bd p { margin: 0 0 10px; font-size: 14px; line-height: 1.8; color: var(--ink-2); }
.pane__bd p:last-child { margin-bottom: 0; }
.pane__bd h2, .pane__bd h3, .pane__bd h4 {
  margin: 18px 0 8px; font-size: 14.6px; font-weight: 700; color: var(--ink);
}
.pane__bd h2:first-child, .pane__bd h3:first-child { margin-top: 0; }
.pane__bd ul, .pane__bd ol { margin: 0 0 10px; padding-left: 20px; display: grid; gap: 6px; }
.pane__bd li { font-size: 14px; line-height: 1.75; color: var(--ink-2); }
@media (max-width: 720px) { .pane__bd { padding: 4px 16px 18px; } }

/* 视频展示：按分类分组的标题
   仅在「有两个及以上分类」时出现（单个分类不显示，保持原来的单列表观感）；
   样式很轻，不动卡片本身。 */
.vgrouph + .vgrouph { margin-top: clamp(30px, 3.4vw, 52px); }
.vgrouph__t { margin: 0 0 16px; display: flex; align-items: center; gap: 12px; }
.vgrouph__t::before {
  content: ""; width: 4px; height: 18px; border-radius: 2px;
  background: var(--green-500); flex: none;
}

/* ==========================================================================
   厂区位置图 —— 静态地图（2026-10-15）
   平台 CSP 不放行高德的域 ⇒ 放弃 JS 地图，改用**一张静态地图图片**（img-src 放行 https）。
   与内容列同宽；整图可点，跳高德看可交互地图。
   ========================================================================== */
.cmap__static {
  position: relative; display: block; overflow: hidden;
  border-radius: var(--r-md); border: 1px solid var(--line-2); background: var(--bg-3);
}
.cmap__static img { width: 100%; height: auto; aspect-ratio: 750 / 420; object-fit: cover; display: block; }
.cmap__badge {
  position: absolute; top: 12px; right: 12px; padding: 6px 12px; border-radius: 100px;
  font-size: 12.4px; font-weight: 600; color: var(--blue-600); background: rgba(255, 255, 255, .93);
  box-shadow: 0 1px 6px rgba(6, 26, 54, .12);
}
.cmap__addr {
  position: absolute; left: 0; right: 0; bottom: 0; padding: 12px 16px;
  font-size: 13px; color: #fff;
  background: linear-gradient(transparent, rgba(6, 26, 54, .74));
}
/* 旧的 JS 地图容器（现在不用了）空着时不要占位 */
.cmap__stage:empty { display: none; }

/* 静态地图接管厂区位置区（v55）
   原型里那块「在高德地图中查看位置」的大占位（.cmap__fb）与 JS 地图容器（.cmap__stage）
   现在都由**静态地图**（.cmap__static，整图可点、自带跳转入口）替代 ⇒ 把旧的隐掉，
   否则它会盖在地图上面，看着"没有任何变化"。
   （用 CSS 隐掉而不是删 DOM：万一 script 没跑、图片没出，也没有空白风险。） */
.cmap__fb { display: none !important; }
.cmap__stage { display: none !important; }
.cmap__static { position: relative; z-index: 1; margin-top: 0; }

/* 容器原本是 16:9 的固定画框（给绝对定位的 JS 地图用）；换成静态地图后让高度由图片决定 */
.cmap:has(.cmap__static) { aspect-ratio: auto; }

/* 板块上间距减半（视频展示页：去掉页内大标题后，上方留白显得过大） */
.sec--halfTop { padding-top: calc(var(--sec-y) / 2); }
