/* ============================================================================
 * profirst.cn （server/public/assets/front.css）
 * ----------------------------------------------------------------------------
 * ★ ：docs/07-.md（Trust & Authority）
 * ★ RTL ：****（inset-inline / margin-inline / padding-inline /
 *   border-inline-* / text-align: start|end / inline-size）。 left|right 。
 * ★ ：** --sp-* **，。
 * ★ ：** --fs-* **（7 ）。
 * ★  2026-09-16 ，****（）。
 * ★ LTR ：.keep-ltr（CAS /  / SKU /  /  / ） LTR。
 * ★  emoji（ SVG）； cursor:pointer；focus 。
 * ==========================================================================*/

/* -------------------------------  ------------------------------- */
:root {
  /* （★ ，） */
  --brand-primary: #0a2463;
  --brand-primary-dark: #0f3070;
  --brand-primary-light: #245091;
  --brand-accent: #3e92cc;
  /* （spec §1.2） */
  --accent-fill: #2670a8;
  --accent-text: #2a6fa8;
  --accent-on-dark: #3e92cc;

  /*  */
  --surface: #ffffff;
  --surface-alt: #f7f9fc;
  --surface-sunken: #eef2f8;
  --text: #1a2332;
  --text-muted: #5b6b85;
  --border: #e3e8ef;
  --border-strong: #d3dbe6;

  /* ★ 第 37 批（设计参考《PROFIRST 品牌视觉策划方案 v1.0》落地清单「功能色接入」直接采用）：
   *   功能三色仅用于**状态语义**（表单校验错误 / 成功回执），不作装饰；
   *   底/边为同族衍生色（浅底 + 细边，沿用原结果块的「浅底色块」形态）。 */
  --ok: #2e7d4f;
  --ok-bg: #e6f2ea;
  --ok-bd: #b7d4c2;
  --warn: #b7791f;
  --err: #b3403a;
  --err-bg: #fbeae9;
  --err-bd: #efc4c1;

  /* （spec §1.2） */
  --on-dark: #eaf1fb;
  --on-dark-muted: rgba(234, 241, 251, 0.78);
  --hairline: rgba(255, 255, 255, 0.16);

  /* （spec §3，4/8 ） */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 20px;
  --sp-6: 24px;
  --sp-7: 32px;
  --sp-8: 40px;
  --sp-9: 48px;
  --sp-10: 56px;
  --sp-11: 64px;
  --sp-12: 80px;

  /* （spec §2.2，7 ） */
  --fs-xs: 0.75rem;
  --fs-sm: 0.875rem;
  --fs-base: 1.125rem; /* 2026-09-21 甲方：16px → 18px（全局上调） */
  --fs-lg: 1.25rem;    /* 2026-09-21 甲方：18px → 20px（全局上调） */
  --fs-xl: 1.375rem;
  --fs-2xl: clamp(1.5rem, 2.2vw, 1.75rem);
  --fs-3xl: clamp(2rem, 4vw, 3rem);
  --lh-body: 1.7;
  --lh-heading: 1.25;

  /* （spec §2.1，，） */
  --font-heading: 'Poppins', 'Segoe UI', system-ui, -apple-system, sans-serif;
  --font-body: 'Open Sans', 'Segoe UI', system-ui, -apple-system, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  /*  /  / （rem ， px） */
  --container: 75rem; /* 1200px */
  --gutter: var(--sp-5);
  --header-h: 7.5rem; /*  scroll-padding， */

  /* （，） */
  --radius-sm: var(--sp-2); /* 8px */
  --radius: var(--sp-3); /* 12px */
  /* ★ 55 批修复：本令牌此前**从未声明**，而 `var(--radius-md)` 在 :1691 / :1942 被用了两处
     ⇒ 那两处 `border-radius` 实际失效为 0（CSS 里未声明的 var 会让整条声明在计算期作废）。
     取值=max(与 --radius 同档 12px)：不新增刻度值，最小意外；如需中间档再另开一批改。 */
  --radius-md: var(--sp-3); /* 12px */
  --radius-lg: var(--sp-4); /* 16px */
  --radius-pill: 999rem;

  /* （） */
  --shadow-sm: 0 1px 3px rgba(10, 36, 99, 0.06);
  --shadow-md: 0 6px 18px rgba(10, 36, 99, 0.1);
  --shadow-lg: 0 16px 36px rgba(10, 36, 99, 0.16);
}

/* ：， */
html[lang="ar"] {
  --font-heading: 'Noto Kufi Arabic', 'Segoe UI', system-ui, sans-serif;
  --font-body: 'Noto Naskh Arabic', 'Segoe UI', system-ui, sans-serif;
}
/*  */
html[lang="zh"] {
  --font-heading: 'Noto Sans SC', 'Microsoft YaHei', 'PingFang SC', sans-serif;
  --font-body: 'Noto Sans SC', 'Microsoft YaHei', 'PingFang SC', sans-serif;
}
/* （Cyrillic） */
html[lang="ru"] {
  --font-heading: 'Poppins', 'PT Sans', 'Segoe UI', sans-serif;
  --font-body: 'Open Sans', 'PT Sans', 'Segoe UI', sans-serif;
}
/* 葡萄牙语（Latin 含 ã õ ç 等变音符号，与默认拉丁栈同族，显式声明以便后续单独微调） */
html[lang="pt"] {
  --font-heading: 'Poppins', 'Inter', 'Segoe UI', sans-serif;
  --font-body: 'Inter', 'Open Sans', 'Segoe UI', sans-serif;
}

/* -------------------------------  ------------------------------- */
*,
*::before,
*::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-block-start: var(--header-h);
}

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--fs-base);
  color: var(--text);
  background: var(--surface);
  line-height: var(--lh-body);
  overflow-wrap: break-word;
}

h1, h2, h3, h4 {
  font-family: var(--font-heading);
  text-align: start;
  line-height: var(--lh-heading);
  margin-block: 0 var(--sp-3);
  color: var(--brand-primary);
  font-weight: 700;
  letter-spacing: -0.01em;
  overflow-wrap: anywhere;
}

p { margin-block: 0 var(--sp-4); }

a {
  color: var(--brand-primary);
  text-decoration: none;
  transition: color 0.18s ease;
  cursor: pointer;
}
a:hover { color: var(--accent-text); text-decoration: underline; text-underline-offset: 2px; }

img { max-inline-size: 100%; block-size: auto; }

/* ：focus  */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible {
  outline: 2px solid var(--brand-green);
  outline-offset: 2px;
}

/* LTR ：CAS /  / SKU /  /  /   */
.keep-ltr {
  direction: ltr;
  unicode-bidi: isolate;
  text-align: start;
  font-family: var(--font-mono);
  display: inline-block;
}
/* （PROFIRST） keepLtr  bidi ，**** */
.pf-front__hero-title .keep-ltr,
.pf-front__copyright .keep-ltr {
  font-family: inherit;
  letter-spacing: inherit;
  font-weight: inherit;
}

/* -------------------------------  ------------------------------- */
.pf-front__skip {
  position: absolute;
  inset-block-start: calc(var(--sp-12) * -1);
  inset-inline-start: var(--sp-4);
  z-index: 100;
  padding: var(--sp-2) var(--sp-4);
  background: var(--brand-primary);
  color: var(--surface);
  border-radius: var(--radius-sm);
  transition: inset-block-start 0.18s ease;
}
.pf-front__skip:focus-visible { inset-block-start: var(--sp-2); }

/* ------------------------------- （ + ； docs/15 ①） ------------------------------- */
.pf-front__header {
  position: sticky;
  inset-block-start: 0;
  z-index: 50;
  display: flex;
  flex-direction: column;
  /*  2026-09-20 ⑤：（）****。
      #0a2463 → #0f3070 → #14418a → #17509b → #19539f ****：
      --brand-primary-dark(#0f3070) →  #14418a（****， :root ；
     ，，）。
     ：--on-dark(#eaf1fb) on #14418a ≈ 8.6:1（≥4.5， .probe/sw-eng-chrome）。 bg ，。 */
  background: #14418a;
  color: var(--on-dark);
  border-block-end: 2px solid var(--brand-green);
  box-shadow: var(--shadow-sm);
}

/* （）；docs/16 ①：， .pf-front__nav-row。 */
.pf-front__header-side {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--sp-2);
}
/* docs/16 ①：（<ul>） .pf-front__nav-row；、flex 、。 */
.pf-front__header-contact {
  /* ★ 2026-09-19 （RTL ， ar@390 「 409 > 390」）：
      `flex: 0 0 auto`（****）⇒  max-content（「البريد الإلكتروني」
     ， 389px）， RTL **** 19px。
     、，。
      flex （flex-wrap ）。 */
  flex: 0 1 auto;
  min-inline-size: 0;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-5);
  margin: 0;
  padding: 0;
  padding-inline: var(--sp-5);
  list-style: none;
  /*  2026-09-20 ⑤：/（）：--fs-sm(14px) → --fs-base(16px)。 */
  font-size: var(--fs-base);
}
.pf-front__header-contact-item { min-inline-size: 0; }
.pf-front__header-contact-item { color: var(--on-dark-muted); }
.pf-front__header-contact-label { color: var(--on-dark); font-weight: 600; }
.pf-front__header-contact a { color: var(--on-dark-muted); }
.pf-front__header-contact a:hover { color: var(--surface); text-decoration: none; }

/* ：LOGO +  */
.pf-front__header-top {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  flex-wrap: wrap;
  inline-size: 100%;
  max-inline-size: var(--container);
  margin-inline: auto;
  padding-block: var(--sp-3);
  padding-inline: var(--gutter);
}
.pf-front__brand { display: inline-flex; align-items: center; gap: var(--sp-3); margin-inline-end: auto; }
.pf-front__brand:hover { text-decoration: none; }
.pf-front__brand-logo {
  display: block;
  /* docs/16 ②：48px → 64px； 2026-09-19 3：64px → 80px（--sp-11 → --sp-12，+25%） */
  block-size: var(--sp-12);
  inline-size: auto;
  max-block-size: var(--sp-12);
  border-radius: var(--radius-sm);
  padding-inline: var(--sp-2);
  padding-block: var(--sp-1);
}
/*  2026-09-19：LOGO ****（；RTL  dir="ltr" ）。
   ：--on-dark(#eaf1fb) on  #14418a ≈ 8.6:1（≥4.5）。
   nowrap ； LOGO  .pf-front__brand  gap(--sp-3)。 */
.pf-front__brand-legal {
  /*  2026-09-19（2）： 2  14px(--fs-sm) → 18px(--fs-lg)。 */
  font-size: var(--fs-lg);
  font-weight: 600;
  line-height: 1.2;
  color: var(--on-dark);
  white-space: nowrap;
}

/* docs/16 ①：（ / ）。 .pf-front__nav  /  / 。 */
.pf-front__nav-row {
  display: flex;
  align-items: stretch;
  flex-wrap: wrap;
  gap: var(--sp-5);
  inline-size: 100%;
  max-inline-size: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
  border-block-start: 1px solid var(--hairline);
}
/* ：、、 ≥48px（/ .pf-front__nav-row）。 */
.pf-front__nav {
  display: flex;
  align-items: stretch;
  flex-wrap: wrap;
  flex: 1 1 auto;
}
.pf-front__nav-link {
  display: inline-flex;
  align-items: center;
  min-block-size: var(--sp-9);
  padding-block: var(--sp-3);
  padding-inline: var(--sp-5);
  /*  2026-09-19：， .pf-front__header ，
     ****（ --hairline ）。 */
  background: transparent;
  color: var(--on-dark);
  font-family: var(--font-heading);
  /*  2026-09-19（2）： 1  16px(--fs-base) → 18px(--fs-lg)。 */
  font-size: var(--fs-lg);
  font-weight: 600;
  letter-spacing: 0.02em;
  white-space: nowrap;
  border-inline-end: 1px solid var(--hairline);
  border-block-end: 2px solid transparent;
  transition: background 0.18s ease, color 0.18s ease, border-color 0.18s ease;
}
.pf-front__nav-link:first-child { border-inline-start: 1px solid var(--hairline); }
.pf-front__nav-link:hover {
  background: rgba(255, 255, 255, 0.09);
  color: var(--surface);
  text-decoration: none;
}
.pf-front__nav-link[aria-current="page"] {
  /*  2026-09-19：， --accent-fill（#2670a8，
      .pf-front__lang-link[aria-current] ），「」。 */
  background: var(--accent-fill);
  color: var(--surface);
  border-block-end-color: var(--brand-green);
}

/*  */
/* docs/16 ②： 14px → 16px、 4px → 8px； ≥40px 。 */
.pf-front__lang { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; font-size: var(--fs-base); }
.pf-front__lang-link { display: inline-flex; align-items: center; min-block-size: var(--sp-8); padding: var(--sp-2) var(--sp-3); color: var(--on-dark-muted); border-radius: var(--radius-sm); }
.pf-front__lang-link:hover { color: var(--surface); text-decoration: none; }
.pf-front__lang-link[aria-current="true"] { background: var(--accent-fill); color: var(--surface); font-weight: 600; }

/* ★ C 落地（2026-09-21）：移动端语言切换下拉触发按钮；桌面隐藏，仅 ≤767px 显示 */
.pf-front__lang-toggle {
  display: none;
  align-items: center;
  gap: var(--sp-1);
  inline-size: auto;
  min-block-size: var(--sp-8);
  padding-inline: var(--sp-3);
  border: 1px solid var(--hairline);
  background: rgba(255, 255, 255, 0.08);
  color: var(--surface);
  border-radius: var(--radius-sm);
  cursor: pointer;
  font: inherit;
  font-size: var(--fs-sm);
  line-height: 1;
  transition: background 0.18s ease;
}
.pf-front__lang-toggle:hover { background: rgba(255, 255, 255, 0.18); }
.pf-front__lang-toggle[aria-expanded="true"] { background: rgba(255, 255, 255, 0.18); }

/* （ front.js ，） */
.pf-front__nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: var(--sp-1);
  inline-size: var(--sp-9);
  block-size: var(--sp-8);
  padding-inline: var(--sp-3);
  border: 1px solid var(--hairline);
  background: rgba(255, 255, 255, 0.08);
  color: var(--surface);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background 0.18s ease;
}
.pf-front__nav-toggle:hover { background: rgba(255, 255, 255, 0.18); }
.pf-front__nav-toggle-bar { display: block; inline-size: 100%; block-size: 2px; background: currentColor; border-radius: 2px; }

/* -------------------------------  ------------------------------- */
.pf-front__crumbs {
  padding-block: var(--sp-3);
  padding-inline: var(--gutter);
  background: var(--surface-alt);
  border-block-end: 1px solid var(--border);
}
.pf-front__crumbs ol {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin: 0;
  padding: 0;
  max-inline-size: var(--container);
  margin-inline: auto;
  list-style: none;
  font-size: var(--fs-sm);
  color: var(--text-muted);
}
.pf-front__crumb + .pf-front__crumb::before { content: "/"; margin-inline-end: var(--sp-2); color: var(--border-strong); }

/* -------------------------------  ------------------------------- */
.pf-front__main {
  display: block;
  padding-block: var(--sp-8);
  padding-inline: var(--gutter);
  max-inline-size: var(--container);
  margin-inline: auto;
}

.pf-front__page-title { font-size: var(--fs-3xl); margin-block-end: var(--sp-5); }
.pf-front__block-title { font-size: var(--fs-xl); margin-block: var(--sp-7) var(--sp-3); }
.pf-front__lead { font-size: var(--fs-lg); color: var(--text); margin-block-end: var(--sp-6); max-inline-size: 70ch; } /* ★#135： --text-muted→--text（， 18 ） */
.pf-front__note { color: var(--text-muted); font-size: var(--fs-base); }

/* （ HTML ） */
.pf-front__prose { max-inline-size: 72ch; font-size: var(--fs-base); line-height: var(--lh-body); color: var(--text); }
.pf-front__prose > :first-child { margin-block-start: 0; }
.pf-front__prose h2, .pf-front__prose h3 { margin-block-start: var(--sp-7); }
.pf-front__prose ul, .pf-front__prose ol { padding-inline-start: var(--sp-6); }
.pf-front__prose img { border-radius: var(--radius); margin-block: var(--sp-4); }
.pf-front__prose table { inline-size: 100%; border-collapse: collapse; margin-block: var(--sp-4); }
.pf-front__prose th, .pf-front__prose td { border: 1px solid var(--border); padding: var(--sp-2) var(--sp-3); text-align: start; }
/* ★ batch 65（2026-10-07 甲方）：正文里的链接**看不出是链接** ——
   全局 `a` 是 --brand-primary(#0a2463) + text-decoration:none，而正文色是 --text(#1a2332)，
   两者在屏幕上几乎无差（实测 computed: color rgb(10,36,99) / text-decoration none）。
   ⇒ 正文容器内显式给出「可点」信号：强调色 + 下划线；悬停加深并加粗下划线。
   ★ 全站实测：正文容器内共 895 个锚点，**全部无 class**（仅 4 个带 class，来自第三方嵌入 HTML）
   ⇒ 本规则不会误伤任何组件链接。 */
.pf-front__prose a,
.pf-front__article-body a { color: var(--accent-fill); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 2px; }
.pf-front__prose a:hover,
.pf-front__article-body a:hover { color: var(--brand-primary); text-decoration-thickness: 2px; }
/* ★#135 ④： 16px 。 <16px **** `<font size>`（ <font>  color， size），
    <sub>/<sup>（ 0.833em ⇒ 16×0.833 = 13.33px）。。
   ★#136 （team-lead ）：sub/sup  `inherit`（、），
    `0.9em` ⇒ 16×0.9 = 14.4px， 13.33px 、 <16px 「」。
    `font[size]{font-size:inherit}` （，）。 */
.pf-front__prose sub, .pf-front__prose sup,
.pf-front__article-body sub, .pf-front__article-body sup { font-size: 0.9em; }
.pf-front__prose font[size], .pf-front__article-body font[size] { font-size: inherit; }

/* ------------------------------- Hero ------------------------------- */
.pf-front__hero {
  /* docs/15 ②：（ ≤ #19539f ）。 */
  background: linear-gradient(150deg, #14418a 0%, #17509b 55%, #19539f 100%);
  color: var(--surface);
  border-radius: var(--radius-lg);
  padding: var(--sp-8) var(--sp-6);
  text-align: start;
  box-shadow: var(--shadow-md);
}
.pf-front__eyebrow {
  margin: 0 0 var(--sp-3);
  font-family: var(--font-heading);
  font-size: var(--fs-sm);
  /* ★ 第 106zx 批（P0 美化②）：眉标科技感 —— 字距拉开 + 科技蓝（原为纯白） */
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent-on-dark);
}
.pf-front__hero-title { margin: 0 0 var(--sp-3); font-size: var(--fs-3xl); color: var(--surface); }
.pf-front__hero-sub { margin: 0; max-inline-size: 60ch; color: var(--surface); font-size: var(--fs-xl); } /* ★#145：on-dark→surface；18→22px */

/* ★ 第 37 批（参考 §4.1 Hero 行直接采用）：① 标题下 56×4px 科技蓝短横线，强化 hero 焦点；
 *   ② M1「扩散圆弧」母题角饰（参考 §2.3：超铺展意象；约束=每屏 ≤1 个母题、透明度 ≤8%、
 *   仅作深色区块角饰——hero 是首屏唯一母题宿主，圆心出血到画布外只露四分之一弧）。
 * ★ overflow:hidden 仅为裁角饰出血；hero 自身 box-shadow 不受影响，子元素本不出容器。
 * ★ 内容提层 z-index:1，保证角饰永远垫在文案/媒体之下。
 * ★ RTL 安全：inset-inline-* 定位，图形无方向性。 */
.pf-front__home-hero { position: relative; overflow: hidden; }
.pf-front__home-hero::before {
  content: "";
  position: absolute;
  inset-inline-start: -110px;
  inset-block-end: -110px;
  inline-size: 320px;
  block-size: 320px;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 80'%3E%3Cg fill='none' stroke='%233e92cc' stroke-width='2'%3E%3Ccircle cx='60' cy='40' r='10'/%3E%3Ccircle cx='60' cy='40' r='22' opacity='.6'/%3E%3Ccircle cx='60' cy='40' r='34' opacity='.35'/%3E%3Ccircle cx='60' cy='40' r='46' opacity='.18'/%3E%3C/g%3E%3Ccircle cx='60' cy='40' r='5' fill='%232670a8'/%3E%3C/svg%3E") center/contain no-repeat;
  opacity: 0.08;
  pointer-events: none;
}
.pf-front__home-hero-copy,
.pf-front__home-hero-media-col { position: relative; z-index: 1; }
.pf-front__home-hero .pf-front__hero-title::after {
  content: "";
  display: block;
  inline-size: 56px;
  block-size: 4px;
  margin-block-start: var(--sp-3);
  border-radius: 2px;
  background: var(--accent-on-dark);
}
.pf-front__home-hero { display: grid; gap: var(--sp-8); align-items: center; }
.pf-front__home-hero-copy { min-inline-size: 0; }
.pf-front__home-hero-actions { display: flex; flex-wrap: wrap; gap: var(--sp-3); margin-block-start: var(--sp-6); }
.pf-front__hero-img {
  inline-size: 100%;
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  object-fit: cover;
  aspect-ratio: 1200 / 630;
}

/* docs/16 ③：Hero （ / ）。RTL 。 */
.pf-front__home-hero-media-col { min-inline-size: 0; }
.pf-front__home-hero-media {
  position: relative;
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow-lg);
  aspect-ratio: 16 / 9;
}
.pf-front__hero-video { display: block; inline-size: 100%; block-size: 100%; object-fit: cover; }
/* ： media（ .pf-front__hero-img  1200/630 ）。 */
.pf-front__home-hero-media--empty .pf-front__hero-img {
  inline-size: 100%;
  block-size: 100%;
  aspect-ratio: auto;
  object-fit: cover;
  border-radius: 0;
}
.pf-front__hero-play-slot {
  position: absolute;
  /* ★ 2026-09-19 （RTL ， ar@768/ar@390 ）：
      `inset-block-start:50% + inset-inline-start:50% + transform: translate(-50%,-50%)`
     —— ** inset  transform**：RTL  `inset-inline-start:50%`  `right:50%`，
      50%  ⇒ （「 44px」），
     390px （ 409px >  390px）。
     ****： inset 0 + margin:auto， max-inline-size 。 */
  inset: 0;
  margin: auto;
  inline-size: max-content;
  block-size: max-content;
  max-inline-size: calc(100% - var(--sp-6));
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-5);
  border-radius: 999px;
  background: rgba(10, 36, 99, .55);
  color: var(--surface);
  font-size: var(--fs-sm);
  text-align: center;
  backdrop-filter: blur(2px);
  pointer-events: none;
}
.pf-front__hero-play-slot svg { inline-size: var(--sp-6); block-size: var(--sp-6); }
.pf-front__hero-playlist { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-block-start: var(--sp-3); }
.pf-front__hero-playlist-item {
  min-block-size: var(--sp-8);
  padding: var(--sp-2) var(--sp-4);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--on-dark);
  font-size: var(--fs-sm);
  cursor: pointer;
}
.pf-front__hero-playlist-item[aria-current="true"] { background: var(--accent-fill); color: var(--surface); }

/* docs/17 ③⑤：YouTube **lite ** ——  +  `button`（）；
    `front.js`  `.pf-front__hero-video-frame`（iframe） lite 。
   ★  `inset:0; margin:auto`（）——  inset  transform
     （docs/16 ）。 */
.pf-front__hero-video-lite { position: relative; inline-size: 100%; block-size: 100%; }
.pf-front__hero-video-poster { display: block; inline-size: 100%; block-size: 100%; object-fit: cover; }
.pf-front__hero-play-btn {
  position: absolute;
  inset: 0;
  margin: auto;
  inline-size: max-content;
  block-size: max-content;
  max-inline-size: calc(100% - var(--sp-6));
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-5);
  border: 0;
  border-radius: 999px;
  background: rgba(10, 36, 99, .62);
  color: var(--surface);
  font-family: var(--font-heading);
  font-size: var(--fs-sm);
  font-weight: 600;
  text-align: center;
  cursor: pointer;
}
.pf-front__hero-play-btn:hover { background: var(--accent-fill); color: var(--surface); }
.pf-front__hero-play-btn svg { inline-size: var(--sp-6); block-size: var(--sp-6); }
.pf-front__hero-play-btn:focus-visible { outline: 2px solid var(--brand-green); outline-offset: 2px; }
.pf-front__hero-video-frame { display: block; inline-size: 100%; block-size: 100%; border: 0; }

/* -------------------------------  ------------------------------- */
.pf-front__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  padding-block: var(--sp-3);
  padding-inline: var(--sp-6);
  border-radius: var(--radius-sm);
  font-family: var(--font-heading);
  font-size: var(--fs-base);
  font-weight: 600;
  line-height: 1.2;
  border: 1px solid transparent;
  cursor: pointer;
  white-space: nowrap;
  /* ★ 第 106zx 批（P0 美化①）：按钮交互升级 —— hover 上浮 + 阴影（现代质感） */
  transition: background-color 0.18s ease, color 0.18s ease, border-color 0.18s ease,
    transform 0.15s ease, box-shadow 0.15s ease;
}
.pf-front__btn:hover { text-decoration: none; }
.pf-front__btn--primary { background: var(--accent-fill); color: var(--surface); }
.pf-front__btn--primary:hover {
  background: var(--brand-primary-light);
  color: var(--surface);
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(38, 112, 168, 0.35);
}
.pf-front__btn--ghost { background: transparent; color: var(--surface); border-color: var(--accent-on-dark); }
.pf-front__btn--ghost:hover { background: rgba(255, 255, 255, 0.14); color: var(--surface); }
.pf-front__home-cta .pf-front__btn--primary { background: var(--surface); color: var(--brand-primary); }
.pf-front__home-cta .pf-front__btn--primary:hover { background: var(--accent-on-dark); color: #06213f; }

/* （SVG， → ；spec §4.2） */
.pf-front__link-arrow { display: inline-block; inline-size: 1em; block-size: 1em; margin-inline-start: var(--sp-1); vertical-align: -0.12em; }

/* -------------------------------  ·  ------------------------------- */
.pf-front__sections { margin-block-start: var(--sp-12); }
.pf-front__home-section { margin-block-start: var(--sp-12); }
/* ★  2026-09-20：「、」⇒  +1  --fs-base， --text-muted→--text。
    `[data-b01-main="home"]`（）⇒ ；:root  --fs-sm / --text-muted 。 */
[data-b01-main="home"] .pf-front__value-text { font-size: var(--fs-base); color: var(--text); }
[data-b01-main="home"] .pf-front__home-faq-a { font-size: var(--fs-base); }
[data-b01-main="home"] .pf-front__eyebrow { font-size: var(--fs-lg); font-weight: 700; }           /* ★#145：16→18px； font-weight 700（） */
[data-b01-main="home"] .pf-front__hero-play-btn-text { font-size: var(--fs-base); } /*  */
/* ★ ③ （）：「」 ≤14px， +1 ；
   `.pf-front__doc-text` （ value-text ）⇒  --text。 */
[data-b01-main="home"] .pf-front__doc-text { font-size: var(--fs-base); color: var(--text); }
[data-b01-main="home"] .pf-front__doc-acro { font-size: var(--fs-base); }
/* ★ ② ：80px → 112px（，）。
   <768 （ --sp-9=48px） 48 → 67px，（ 112）。 */
[data-b01-main="home"] .pf-front__home-section { margin-block-start: calc(var(--sp-12) * 1.4); }
@media (max-width: 767px) {
  [data-b01-main="home"] .pf-front__home-section { margin-block-start: calc(var(--sp-9) * 1.4); }
}
.pf-front__section-title {
  position: relative;
  font-size: var(--fs-2xl);
  padding-inline-start: var(--sp-4);
  margin-block-end: var(--sp-6);
}
.pf-front__section-title::before {
  content: "";
  position: absolute;
  inset-inline-start: 0;
  inset-block: 0.2em;
  inline-size: var(--sp-1);
  border-radius: var(--radius-sm);
  background: var(--brand-green);
}
.pf-front__section-more { margin-block-start: var(--sp-6); font-family: var(--font-heading); font-weight: 600; }

/*  */
.pf-front__value-grid,
.pf-front__product-entrance-grid,
.pf-front__featured-grid,
.pf-front__grid,
.pf-front__solution-grid,
.pf-front__resource-cat-grid,
.pf-front__doc-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 15rem), 1fr));
  gap: var(--sp-6);
  align-items: stretch;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* -------------------------------  ·  ------------------------------- */
.pf-front__value-card {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--sp-6);
  box-shadow: var(--shadow-sm);
  transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}
.pf-front__value-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); border-color: var(--brand-green); }
.pf-front__value-title { font-size: var(--fs-xl); margin-block-end: var(--sp-2); }
.pf-front__value-text { margin: 0; color: var(--text-muted); font-size: var(--fs-base); margin-block-start: auto; }

/* -------------------------------  ·  ------------------------------- */
.pf-front__product-entrance { display: flex; }
.pf-front__product-entrance-link {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  inline-size: 100%;
  block-size: 100%;
  padding: var(--sp-6);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  cursor: pointer;
  transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}
.pf-front__product-entrance-link:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
  border-color: var(--brand-green);
  text-decoration: none;
}
.pf-front__product-entrance-name { font-family: var(--font-heading); font-weight: 700; font-size: var(--fs-lg); color: var(--brand-primary); }
.pf-front__product-entrance-link:hover .pf-front__product-entrance-name { color: var(--accent-text); }
.pf-front__product-entrance-desc { color: var(--text-muted); font-size: var(--fs-base); margin-block-start: auto; }

/* 分类图标底座（第 34 批甲方：四卡加图标，须「贴切、精致、和环境协调」）。
 * ★ 几何自洽：48px 方圆底座 + 24px 图标（四周各 12px 内边距，比例＝黄金舒适区）；
 *   圆角 `--radius`(12px) 与卡片圆角同族 ⇒ 一眼同套设计语言。
 * ★ 环境协调：底色 `--surface-sunken`（淡蓝灰，与首页色带 `--band-tint` 同色系）——
 *   卡片本身是白底，底座下沉一档 ⇒ 形成「带 → 卡 → 图标块」三级浅层次，不抢标题。
 * ★ hover 联动：底座反相为品牌科技蓝实底 + 白色图标，与卡片边框/标题的 hover 同拍。
 *   （`currentColor` 承接描边色，SVG 内不需再声明颜色。）
 * ★ RTL 安全：inline-flex 纯居中，无方向性属性。 */
.pf-front__product-entrance-icon,
.pf-front__value-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: var(--sp-9);
  block-size: var(--sp-9);
  border-radius: var(--radius);
  background: var(--surface-sunken);
  border: 1px solid var(--border);
  color: var(--brand-green);
  margin-block-end: var(--sp-1);
  transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}
.pf-front__product-entrance-icon svg,
.pf-front__value-icon svg { inline-size: var(--sp-6); block-size: var(--sp-6); display: block; }
.pf-front__product-entrance-link:hover .pf-front__product-entrance-icon,
.pf-front__value-card:hover .pf-front__value-icon {
  background: var(--brand-green);
  border-color: var(--brand-green);
  color: #fff;
}

/* -------------------------------  · （，） ------------------------------- */
.pf-front__featured-card { display: flex; }
.pf-front__featured-link {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  inline-size: 100%;
  block-size: 100%;
  padding: var(--sp-4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  cursor: pointer;
  transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}
.pf-front__featured-link:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
  border-color: var(--brand-green);
  text-decoration: none;
}
.pf-front__featured-thumb {
  display: block;
  inline-size: 100%;
  /* docs/15 ⑤： 5/7  1/1（ object-fit:contain ）。 */
  aspect-ratio: 1 / 1;
  overflow: hidden;
  border-radius: var(--radius-sm);
  background: linear-gradient(135deg, var(--surface-sunken), var(--surface-alt));
  border: 1px solid var(--border-strong);
  /*  2026-09-23：「」（1px  + ）。 */
  box-shadow: 0 1px 3px rgba(10, 36, 99, .08);
  /*  2026-09-19：， img（inline/block-size:100%）****
     （global box-sizing:border-box ⇒ padding ，img ）。 */
  padding: var(--sp-4);
}
.pf-front__featured-thumb img { display: block; inline-size: 100%; block-size: 100%; object-fit: contain; background: var(--surface); }
.pf-front__featured-link:hover .pf-front__featured-thumb { box-shadow: 0 2px 6px rgba(10, 36, 99, .14); }
.pf-front__featured-name {
  font-family: var(--font-heading); font-weight: 600; color: var(--brand-primary); overflow-wrap: anywhere; margin-block-start: auto;
  /* ★ 第 37 批（参考 §4.1「产品名两行截断」直接采用）：两行封顶，防个别长名把整排卡撑高；
   *   全名保留在 <a> 内的 title 属性（home.js 模板）⇒ 悬停可见、读屏可及，信息不丢。 */
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;
}
.pf-front__featured-sku { font-size: var(--fs-xs); color: var(--text-muted); }

/* 「」（docs/15 ④： CTA ）。 */

/* -------------------------------  · （） ------------------------------- */
.pf-front__doc-card {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  padding: var(--sp-6);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
  /* 2026-09-21：卡片已由 <li> 改为 <a>，重置链接默认样式 */
  text-decoration: none;
  color: inherit;
  cursor: pointer;
}
.pf-front__doc-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); border-color: var(--brand-green); }
.pf-front__doc-acro {
  display: inline-flex;
  align-items: center;
  inline-size: fit-content;
  padding-block: var(--sp-1);
  padding-inline: var(--sp-3);
  background: var(--brand-primary);
  color: var(--surface);
  border-radius: var(--radius-sm);
  font-family: var(--font-heading);
  font-size: var(--fs-sm);
  font-weight: 700;
  letter-spacing: 0.04em;
}
.pf-front__doc-title { font-family: var(--font-heading); font-weight: 700; color: var(--brand-primary); overflow-wrap: anywhere; }
.pf-front__doc-text { color: var(--text-muted); font-size: var(--fs-base); margin-block-start: auto; }

/* -------------------------------  ·  ------------------------------- */
.pf-front__solution-card { display: flex; }
.pf-front__solution-link {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  inline-size: 100%;
  block-size: 100%;
  padding: var(--sp-6);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  font-family: var(--font-heading);
  font-weight: 600;
  color: var(--brand-primary);
  cursor: pointer;
  transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}
.pf-front__solution-link:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
  border-color: var(--brand-green);
  color: var(--accent-text);
  text-decoration: none;
}
.pf-front__solution-name { font-size: var(--fs-lg); }
.pf-front__solution-desc { font-weight: 400; font-size: var(--fs-base); color: var(--text-muted); margin-block-start: auto; }

/* -------------------------------  ·  ------------------------------- */
.pf-front__home-trust {
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--sp-8) var(--sp-6);
}
/* `.pf-front__trust-stat` 与 `.pf-front__trust-stat span` 两条规则已于 2026-10-11 删除
 * （甲方：「截图里的 `30+ countries served` 删掉，六语统一」）。
 * 该 DOM 已不再生成 —— `templates/home.js#trust` 移除了 stat 的拼接，`<li>` 只剩正文；
 * 配套键 `home.trust.statNumber` / `home.trust.statUnit` 已从 `front-ui.js`（六语）与
 * `ui-schema.js` 删除 ⇒ 后台「信任背书」分组不再显示这两个输入框。
 * ★ 原第 35 / 36 批关于 stat 位置（列表末尾）与行内化的设计说明随之作废，
 *   历史判据保留在 `docs/qa/2026-09-29-home-trust-order/` 与 `...-home-trust-inline/`。 */
.pf-front__trust-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
  /* 第 34 批甲方「排版弄好」：列间距与行间距分离 ——
   *   桌面三列时**列间隙**要够（16px 在 400px 列宽下显得三列挤成一坨）⇒ 提到 --sp-6(24px)；
   *   窄屏塌成单列时由**行间距**接管，--sp-4(16px) 与 20px 字号/34px 行高搭配不拥挤。 */
  column-gap: var(--sp-6);
  row-gap: var(--sp-4);
  margin: var(--sp-5) 0 0;
  padding: 0;
  list-style: none;
}
/* 第 34 批甲方：「字大一号」。18px（继承 body 的 --fs-base）→ 20px（--fs-lg，升一档）。
 * ★ 圆点垂直位置改用**几何自洽**算式，不再写死 0.55em：首行行盒高 = --lh-body × 1em，
 *   其几何中心 = 半高；圆点是 --sp-2(8px) 见方 ⇒ 顶边 = 半高 − 半径(--sp-1)。字号再变也自动对齐。
 *   （实测旧值 0.55em 在 18px 下 = 9.9px，理想 11.3px，本来就偏上 1.4px；升字号后偏差会放大到 2px。） */
.pf-front__trust-item {
  position: relative;
  padding-inline-start: var(--sp-6);
  color: var(--text);
  font-size: var(--fs-lg);
}
.pf-front__trust-item::before {
  content: "";
  position: absolute;
  inset-inline-start: 0;
  inset-block-start: calc(var(--lh-body) / 2 * 1em - var(--sp-1));
  inline-size: var(--sp-2);
  block-size: var(--sp-2);
  border-radius: 50%;
  background: var(--brand-green);
}

/* -------------------------------  ·  / （） ------------------------------- */
.pf-front__link-list { display: grid; gap: var(--sp-2); margin: 0; padding: 0; list-style: none; }
.pf-front__link-list li { padding-block: var(--sp-2); border-block-end: 1px dashed var(--border); }
.pf-front__link-list li:last-child { border-block-end: 0; }
/* 「 / 」（****， .pf-front__link-list；
    resource.js ）。 */
@media (min-width: 768px) {
  .pf-front__link-list--two-col { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--sp-7); }
}
.pf-front__resource-latest-item { display: flex; flex-wrap: wrap; gap: var(--sp-3); justify-content: space-between; align-items: baseline; }
.pf-front__resource-latest-item time { color: var(--text-muted); font-size: var(--fs-base); }
.pf-front__resource-empty { color: var(--text-muted); }

/* ------------------------------- （page slug='sitemap' ） ------------------------------- */
/* （RTL ）； min(100%, 15rem) 。 */
.pf-front__sitemap { display: grid; gap: var(--sp-9); }
.pf-front__sitemap-intro { max-inline-size: 70ch; color: var(--text-muted); margin: 0; }
.pf-front__sitemap-group { display: grid; gap: var(--sp-3); }
.pf-front__sitemap-list,
.pf-front__sitemap-tree,
.pf-front__sitemap-children { margin: 0; padding: 0; list-style: none; display: grid; gap: var(--sp-2); }
.pf-front__sitemap-list,
.pf-front__sitemap-tree { grid-template-columns: repeat(auto-fill, minmax(min(100%, 15rem), 1fr)); }
.pf-front__sitemap-node { display: grid; gap: var(--sp-2); align-content: start; }
.pf-front__sitemap-node > a { font-family: var(--font-heading); font-weight: 600; cursor: pointer; }
.pf-front__sitemap-children { gap: var(--sp-1); padding-inline-start: var(--sp-4); border-inline-start: 2px solid var(--border); }
.pf-front__sitemap-children .pf-front__sitemap-item a { font-size: var(--fs-base); color: var(--text-muted); }
@media (min-width: 768px) {
  .pf-front__sitemap { gap: var(--sp-10); }
}

/* -------------------------------  ·  ------------------------------- */
.pf-front__home-faq { display: grid; gap: var(--sp-4); margin: 0; }
.pf-front__home-faq-item { padding: var(--sp-5); background: var(--surface-alt); border: 1px solid var(--border); border-radius: var(--radius); }
.pf-front__home-faq-q { font-family: var(--font-heading); font-weight: 700; color: var(--brand-primary); margin-block-end: var(--sp-2); }
.pf-front__home-faq-a { margin: 0; color: var(--text); font-size: var(--fs-base); line-height: var(--lh-body); }
/* ★ batch79：FAQ 第 1 项（如何使用本站）答案后的跳转链接。 */
.pf-front__home-faq-link { display: inline-flex; align-items: center; gap: var(--sp-2); margin-block-start: var(--sp-3); font-family: var(--font-heading); font-weight: 600; color: var(--brand-primary); }

/* -------------------------------  ·  CTA ------------------------------- */
.pf-front__home-cta {
  /* docs/15 ②：（ ≤ #19539f ）。 */
  background: linear-gradient(150deg, #14418a, #17509b 60%, #19539f);
  color: var(--surface);
  border-radius: var(--radius-lg);
  padding: var(--sp-11) var(--sp-6);
  text-align: center;
  box-shadow: var(--shadow-md);
}
.pf-front__home-cta .pf-front__section-title { color: var(--surface); padding-inline-start: 0; display: inline-block; }
.pf-front__home-cta .pf-front__section-title::before { display: none; }
.pf-front__home-cta-text { max-inline-size: 60ch; margin-inline: auto; color: var(--on-dark); margin-block-end: var(--sp-6); }
/* docs/15 ④： about  +  CTA。 */
.pf-front__home-cta-about { max-inline-size: 70ch; margin-inline: auto; color: var(--on-dark); margin-block-end: var(--sp-6); }
.pf-front__home-cta-contact {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--sp-2) var(--sp-6);
  margin: 0 0 var(--sp-6);
  padding: 0;
  list-style: none;
  color: var(--on-dark);
}
.pf-front__home-cta-contact-item { color: var(--on-dark); }
.pf-front__home-cta-contact-label { font-weight: 600; }
.pf-front__home-cta-contact a { color: var(--on-dark); text-decoration: underline; text-underline-offset: 2px; }
.pf-front__home-cta-contact a:hover { color: var(--surface); }

/* -------------------------------  / （） ------------------------------- */
.pf-front__card {
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--sp-5);
  box-shadow: var(--shadow-sm);
  cursor: pointer;
  transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}
.pf-front__card:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); border-color: var(--brand-green); }
.pf-front__card-title { font-size: var(--fs-xl); margin-block: 0 var(--sp-2); }
.pf-front__card-sku { display: inline-block; font-size: var(--fs-base); color: var(--text); } /* ★#135： SKU 14→16、muted→text */
.pf-front__card-cas { margin: 0 0 var(--sp-2); font-size: var(--fs-base); color: var(--text); } /* ★#135： CAS 14→16、muted→text（ keep-ltr ） */
.pf-front__card-desc { color: var(--text); font-size: var(--fs-base); flex: 1 1 auto; } /* ★#136： 14→16、muted→text（ SKU/CAS ） */
.pf-front__card-link { margin-block-start: auto; font-family: var(--font-heading); font-weight: 600; font-size: var(--fs-base); color: var(--text); align-self: flex-start; } /* ★#136： 14→16 +  --text */
/* ★  6 ：（； overflow:hidden ，）。
   —— .pf-front__news-card， :not() ，/。
    aspect-ratio （CLS）；。 */
.pf-front__card:not(.pf-front__news-card) { padding: 0 0 var(--sp-4); overflow: hidden; }
.pf-front__card-media { display: block; }
.pf-front__card-img { display: block; inline-size: 100%; aspect-ratio: 4 / 3; object-fit: cover; background: var(--surface-alt); }
.pf-front__card:not(.pf-front__news-card) .pf-front__card-title { margin: 0; padding-block-start: var(--sp-4); padding-inline: var(--sp-4); }
.pf-front__card:not(.pf-front__news-card) .pf-front__card-sku,
.pf-front__card:not(.pf-front__news-card) .pf-front__card-cas { padding-inline: var(--sp-4); }
/* （ +  .pf-front__grid--products）： 4 / 2 / 1。
   ★  2026-09-23： ——  #132 ，****。
      grep ： product.js#productGrid （products_index + category ），
      ⇒ 。（`.pf-front__catalog-box` ，。） */
.pf-front__grid--products { grid-template-columns: 1fr; }
@media (min-width: 768px) {
  .pf-front__grid--products { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1024px) {
  .pf-front__grid--products { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
/* ★ （ + ）： contain（）+ （）+ ； 2  clamp。 */
/* ★ 第 17 批（审计②2「统一视觉意象」）：画框由 4:3 横版改为 **3:4 竖版**。
   实测依据：129 在架产品里 **98 张**封面是 530×750（比例 0.707）的白底产品图，而 4:3 横框 +
   contain 让它们左右大留白、绘制面积只占画框 **58.9%**；同一批 8 张卡实时实测改 3:4 后
   填充率 **89.5%**，16 张方图 / 4 张横图 / 7 张异常比例图一并被归一 ⇒ 零配图成本统一观感。
   （脚本与原始数据：docs/qa/2026-09-27-products-catalog/tune-card-frame.cjs） */
.pf-front__grid--products .pf-front__card-img { aspect-ratio: 3 / 4; object-fit: contain; background: var(--surface); padding: var(--sp-2); }
/* ★ 第 17 批（审计②1「解决文本截断问题」）：名称由 2 行放宽到 **3 行**
   （改造前实测 136 个标题中 29 个被截断、最长 78 字符）；同时模板给 h3 挂 `title` 属性
   ⇒ 悬停/长按可见完整型号，满足审计「允许换行（最多两到三行），或悬停显示全名的交互」。 */
.pf-front__grid--products .pf-front__card-title { display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
/* ★ 第 17 批（审计②3「增加核心信息密度」）：核心卖点行 + 资料索取入口。
   卖点取自**已有** `short_desc_<lang>`（模板 product.js#uspText 去掉与上方重复的名称/CAS
   前缀后截取），不新增字段、不新增文案；资料入口指向该产品详情页的询盘区
   （`tds_file`/`msds_file`/`coa_file` 在 129 条产品里**全为空** ⇒ 不做假下载图标，
   不给「点了没有文件」的死链，审计的「TDS/SDS 下载图标」待甲方提供文件后再换）。 */
.pf-front__grid--products .pf-front__card-usp {
  margin: var(--sp-2) 0 0;
  padding-inline: var(--sp-4);
  font-size: var(--fs-base);
  color: var(--text);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.pf-front__grid--products .pf-front__card-docs { margin: auto 0 0; padding-block-start: var(--sp-3); padding-inline: var(--sp-4); }
.pf-front__card-doc { display: inline-flex; align-items: center; gap: var(--sp-2); font-family: var(--font-heading); font-weight: 600; font-size: var(--fs-base); color: var(--brand-primary); }
.pf-front__card-doc:hover { color: var(--brand-green); text-decoration: none; }
.pf-front__card-doc:focus-visible { outline: 2px solid var(--brand-green); outline-offset: 2px; }
/* ★ 箭头类名**故意不**以 `pf-front__card-doc` 为前缀：自检脚本按类名子串计数，
   从前缀命名会把箭头多算成一个资料入口（第 16 批 `.pf-front__about-cta` 已踩过一次）。 */
.pf-front__doc-arrow { display: inline-block; transition: transform 0.18s ease; }
.pf-front__card-doc:hover .pf-front__doc-arrow { transform: translateX(3px); }
[dir="rtl"] .pf-front__doc-arrow { transform: scaleX(-1); }
[dir="rtl"] .pf-front__card-doc:hover .pf-front__doc-arrow { transform: scaleX(-1) translateX(3px); }
/* 「索取 TDS/SDS」跳产品详情页 `#product-inquiry` ⇒ 给锚点留出滚动余量 */
.pf-front__product-aside { scroll-margin-block-start: var(--sp-6); }
/* ★  2026-09-23：「」（1px  + ）——「」，
   。****（.pf-front__card-media） <img>， contain ；
   （）「」。， .pf-front__card 。 */
.pf-front__grid--products .pf-front__card-media {
  margin: var(--sp-4) var(--sp-4) 0;
  border: 1px solid var(--border-strong);
  box-shadow: 0 1px 3px rgba(10, 36, 99, .08);
  border-radius: var(--radius);
  overflow: hidden;
}
.pf-front__grid--products .pf-front__card:hover .pf-front__card-media { box-shadow: 0 2px 6px rgba(10, 36, 99, .14); }
.pf-front__date { display: block; color: var(--text); font-size: var(--fs-base); margin-block-end: var(--sp-2); } /* ★#135： 14→16、muted→text */

/* ★  2026-09-20（3 ）：（）。
   （ .pf-front__news）+  .pf-front__news-card。
   「Latest news」 .pf-front__link-list（ .pf-front__news）⇒ 。
    #0f3070 → #17509b，。 */
.pf-front__news .pf-front__grid { grid-template-columns: repeat(auto-fill, minmax(min(100%, 17rem), 1fr)); gap: var(--sp-6); }
.pf-front__news-card {
  display: flex; flex-direction: column; gap: var(--sp-3);
  padding: var(--sp-6); background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease;
}
.pf-front__news-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); border-color: var(--brand-green); }
.pf-front__news-date {
  align-self: flex-start; padding: 2px var(--sp-3); border-radius: var(--radius-pill);
  background: var(--surface-sunken); border: 1px solid var(--border-strong);
  color: var(--brand-primary); font-size: var(--fs-sm); font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.pf-front__news .pf-front__card-title { font-size: var(--fs-xl); line-height: 1.3; margin-block: 0;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.pf-front__news .pf-front__card-desc { margin: 0; font-size: var(--fs-base); color: var(--text); line-height: var(--lh-body);
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.pf-front__news .pf-front__card-link { margin-block-start: auto; font-size: var(--fs-base); font-weight: 600; color: var(--accent-text); align-self: flex-start; }
.pf-front__news .pf-front__card-link:hover { color: var(--brand-primary); }
.pf-front__news-arrow { display: inline-block; margin-inline-start: var(--sp-1); transition: transform .18s ease; }
.pf-front__news .pf-front__card-link:hover .pf-front__news-arrow { transform: translateX(2px); }
[dir="rtl"] .pf-front__news-arrow { transform: scaleX(-1); }
/* featured： 2 ， +  */
@media (min-width: 1024px) { .pf-front__news-card--featured { grid-column: span 2; } }
.pf-front__news-card--featured { background: linear-gradient(135deg, #0f3070, #17509b); border-color: transparent; color: var(--on-dark); }
.pf-front__news-card--featured .pf-front__card-title { font-size: var(--fs-2xl); }
.pf-front__news-card--featured .pf-front__card-title a,
.pf-front__news-card--featured .pf-front__card-desc { color: var(--surface); }
.pf-front__news-card--featured .pf-front__card-desc { color: var(--on-dark-muted); }
.pf-front__news-card--featured .pf-front__news-date { background: rgba(255,255,255,.16); border-color: rgba(255,255,255,.3); color: var(--surface); }
/* ★ E4 ：--accent-on-dark(#3e92cc)  ≈2.3–2.9:1（＜4.5）， featured 
    --on-dark(#eaf1fb)（≥8.6:1），。 */
.pf-front__news-card--featured .pf-front__card-link { color: var(--on-dark); text-decoration: underline; text-underline-offset: 2px; }

/* -------------------------------  /  ------------------------------- */
.pf-front__product,
.pf-front__news-detail,
.pf-front__news,
.pf-front__resource-detail,
.pf-front__solution,
.pf-front__contact,
.pf-front__page { display: block; }
.pf-front__product-cat { font-size: var(--fs-base); color: var(--text-muted); } /* ★#135： 14→16（ navy，） */
.pf-front__product-attr { color: var(--text); margin-block-end: var(--sp-2); }
/* ★  6 ：（， lazy）。max-inline-size 、
   ； ⇒ RTL ；。
   ★  6 「」：36rem(576px) → 12rem(192px)， 1/3。 */
.pf-front__product-media { margin: 0 0 var(--sp-6); max-inline-size: min(100%, 12rem); }
.pf-front__product-img { display: block; inline-size: 100%; block-size: auto; border-radius: var(--radius); background: var(--surface-alt); }
/* ★  6 「」：**** H1 （48px → 24px = 1.5rem）。
   ：--fs-xl  1.375rem=22px（ 24px）， 1.5rem。
    .pf-front__product  ⇒ // .pf-front__page-title。 */
.pf-front__product .pf-front__page-title { font-size: 1.5rem; }
/* ★  2026-09-20 ①：****（： + ；：）。
    ⇒ aside （「」）。 ⇒ RTL 。
   ： ≥700px、 ≥340px @1440（container 1320 - gap 48 → 1.55fr:1fr ≈ 773 / 499）。
    position: sticky（header  sticky/fixed，）。 */
.pf-front__product-grid { display: grid; grid-template-columns: 1fr; gap: var(--sp-9); align-items: start; }
.pf-front__product-aside {
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--sp-6);
}
@media (min-width: 1024px) {
  .pf-front__product-grid { grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr); }
}
/* ------------------------------- 第 67 批：产品详情页「本产品相关资料」列表 -------------------------------
   ★ 落点：正文下方、prev/next 导航条**上方**（模板在 ${navHtml} 之前插入）。
   ★ 形态：列表链接——标题（heading）+ 类型标签（pill）+ 摘要；grid-template-areas 让标签在标题右侧、
     窄屏自动落到标题下方。逻辑属性 ⇒ RTL 自动镜像。 */
.pf-front__product-resources { margin-block-start: var(--sp-10); }
.pf-front__product-resources .pf-front__section-title { font-size: var(--fs-2xl); }
.pf-front__res-list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-4); }
.pf-front__res-item {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas: "title tag" "summary summary";
  gap: var(--sp-1) var(--sp-3);
  align-items: baseline;
  padding: var(--sp-4) var(--sp-5);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  transition: border-color .2s ease, box-shadow .2s ease, transform .2s ease;
}
.pf-front__res-item:hover { border-color: var(--brand-green); box-shadow: var(--shadow-sm); transform: translateY(-2px); }
.pf-front__res-link {
  grid-area: title;
  font-family: var(--font-heading); font-weight: 700;
  font-size: var(--fs-xl); line-height: 1.35;
  color: var(--brand-primary); text-decoration: none;
}
.pf-front__res-link:hover { color: var(--brand-green); text-decoration: underline; text-underline-offset: 2px; }
.pf-front__res-tag {
  grid-area: tag; justify-self: end; align-self: center;
  padding: 2px var(--sp-3); border-radius: var(--radius-pill);
  background: var(--surface-sunken); border: 1px solid var(--border-strong);
  color: var(--brand-primary); font-size: var(--fs-sm); font-weight: 700; white-space: nowrap;
}
.pf-front__res-summary { grid-area: summary; margin: 0; font-size: var(--fs-base); color: var(--text-muted); line-height: var(--lh-body); }
@media (max-width: 560px) {
  .pf-front__res-item { grid-template-columns: 1fr; grid-template-areas: "title" "tag" "summary"; }
  .pf-front__res-tag { justify-self: start; }
}
/* ★ #138  2026-09-20 ：（ / ）****。
    #137 （：，）；
   ****（）。
    72ch（）， ⇒ ，「」。
   「」 .pf-front__aside-related / -item。 ⇒ RTL 。 */
.pf-front__article-single { max-inline-size: 72ch; margin-inline: auto; }
.pf-front__article-single > .pf-front__prose,
.pf-front__article-single > .pf-front__article-body { max-inline-size: none; }
.pf-front__article-related { margin-block-start: var(--sp-10); }
/* ★ 2026-09-28 甲方：「新闻内容，和下面的 LATEST NEWS 导航条，距离太近了，加多两个空行」。
   一个「空行」= 正文一行高 = --fs-lg(20px) × --lh-body(1.7) = 34px ⇒ 两行 = 68px。
   故在原 --sp-10(56px) 之上再让出两行（≈124px）。
   只作用于**新闻详情页**（`<main data-b01-main="news">`，见 render.js:1040）；
   资源文章页（data-b01-main="resource"）维持原 --sp-10 —— 不在本次要求范围内。 */
[data-b01-main="news"] .pf-front__article-related {
  margin-block-start: calc(var(--sp-10) + 2 * var(--fs-lg) * var(--lh-body));
}
.pf-front__aside-related { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-2); }
.pf-front__aside-related-item { padding-block-end: var(--sp-2); border-block-end: 1px solid var(--border); font-size: var(--fs-lg); line-height: 1.4; } /* ★#145： 16→18px */
.pf-front__aside-related-item:last-child { padding-block-end: 0; border-block-end: 0; }
.pf-front__aside-related-item a { color: var(--text); }
.pf-front__aside-related-item a:hover { color: var(--brand-primary); }
/* ★  6 ：（YouTube <iframe width="560" height="315">）
   （390px  190px）。****， ——
   ****：`.pf-front__prose`（//， product.js|news.js|page.js）
    `.pf-front__article-body`（， resource.js ，）。
   ：`max-inline-size:100%` 「」「」⇒  1440  iframe  560×315（）；
    `aspect-ratio:16/9` + `block-size:auto` 、（）。 */
.pf-front__prose iframe,
.pf-front__prose video,
.pf-front__article-body iframe,
.pf-front__article-body video {
  max-inline-size: 100%;
  block-size: auto;
  aspect-ratio: 16 / 9;
}
.pf-front__prose img,
.pf-front__article-body img { max-inline-size: 100%; block-size: auto; }
/* ★ 2026-10-23（甲方：视频要能像图片一样居中）：正文里 align="center" 的段落中的
   视频/嵌入，补一条 auto 外边距兜底（图片走 text-align，视频在内联块下同样受益）。 */
.pf-front__prose [align="center"] > video,
.pf-front__prose [align="center"] > iframe,
.pf-front__article-body [align="center"] > video,
.pf-front__article-body [align="center"] > iframe { margin-inline: auto; }
/* ★ 第 45 批（2026-09-30）：老站产品正文的配图普遍写成 `<p align="center"><img …/></p>`
   （实测 168 处块级配图中 130 处带 `align="center"`）。`align` 是废弃属性，
   现代浏览器在标准模式下**不生效** ⇒ 恢复后图片会左对齐、与老站观感不符。
   故按属性选择器补回居中（只作用于正文，不影响其它区）。 */
.pf-front__prose p[align="center"],
.pf-front__prose div[align="center"],
.pf-front__article-body p[align="center"],
.pf-front__article-body div[align="center"] { text-align: center; }
/* 图片**自身**带 align="center"（不在居中块内）⇒ `text-align` 管不到，改用块级 + 自动外边距。 */
.pf-front__prose img[align="center"],
/* ★ 2026-10-22（甲方）：证书这类"两张图并排"的内容，原来被强制 block ⇒ 一图一行。
   改回 inline-block：同一 <p> 内的多张图**并排一行**，单张图仍由 p[align=center] 居中。 */
.pf-front__article-body img[align="center"],
.pf-front__prose img[align="center"] { display: inline-block; margin-inline: 6px; vertical-align: middle; }
.pf-front__prose table,
.pf-front__article-body table { display: block; max-inline-size: 100%; overflow-x: auto; }
.pf-front__specs {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 15rem), 1fr));
  gap: var(--sp-2) var(--sp-6);
  margin: var(--sp-6) 0;
  padding: var(--sp-5);
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.pf-front__spec { display: flex; flex-direction: column; gap: var(--sp-1); }
.pf-front__spec dt { font-size: var(--fs-base); color: var(--text); } /* ★#135： 14→16、muted→text（ label ） */
.pf-front__spec dd { margin: 0; font-weight: 600; }

/* -------------------------------  /  ------------------------------- */
/*  5 ：「」。
   flex-direction ；align-items: flex-start ——
   LTR 、RTL ，（ / ，RTL ）。 */
.pf-front__subcats { display: flex; flex-direction: column; align-items: flex-start; gap: var(--sp-2); margin-block-end: var(--sp-6); }
.pf-front__subcat {
  display: inline-block;
  padding-block: var(--sp-1);
  padding-inline: var(--sp-3);
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  font-size: var(--fs-sm);
  cursor: pointer;
}
.pf-front__subcat:hover { border-color: var(--brand-green); text-decoration: none; }
/* ---------- 产品栏目页：左侧手风琴分类 + 右侧分页网格（第 17 批 · 外部审计第三轮） ----------
 * 审计「整体版式布局建议」原话：「采用『左侧手风琴式菜单 + 右侧产品网格』(Left Sidebar +
 *   Right Grid) 是目前 B2B 行业最标准且好用的版式」；甲方 2026-09-27 拍板**采纳**，
 *   且左栏每一项都是**真实分类页 URL**（不做 JS 拦截式页内筛选）。
 * 本块**取代**第 5 批的「顶部四宫格分类框」（`.pf-front__cats` / `.pf-front__cat-item` /
 *   `.pf-front__catalog-box`）—— 那套四列并排在 1440 屏实测占 **562px** 垂直空间（审计①2），
 *   四个选择器已无模板产出，随本批一并下线。
 * 子分类标签由「白底 + 左侧 3px 蓝粗线」改为**胶囊标签**：审计①1 原话「采用了带左侧蓝色
 *   粗线的卡片样式。这种样式在大量堆叠时显得有些笨重。建议改用更轻量化的『胶囊形标签
 *   (Pill tags)』或简单的文字悬浮变色效果」。 */
.pf-front__catalog-layout { display: grid; grid-template-columns: 1fr; gap: var(--sp-8); align-items: start; }
@media (min-width: 1024px) {
  /* 左栏固定宽；右侧 minmax(0,1fr) 保证网格不被长分类名撑破。
   * ★ 第 107j 批（2026-10-14 甲方）：「分类框适当拉宽一些」—— 16rem → **18rem**。
   *   实测（Chromium 1440px · Poppins 700）：名称区由 ~158px 扩到 ~190px。 */
  .pf-front__catalog-layout { grid-template-columns: 18rem minmax(0, 1fr); }
}
.pf-front__catalog-sidebar {
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--sp-5);
}
@media (min-width: 1024px) {
  .pf-front__catalog-sidebar { padding: var(--sp-6); }
}
.pf-front__catalog-main { min-inline-size: 0; }
.pf-front__sidebar-title {
  margin: 0 0 var(--sp-4);
  font-family: var(--font-heading);
  font-size: var(--fs-xl);
  font-weight: 700;
  color: var(--brand-primary);
}

/* 「跳到产品列表」：左栏有 20+ 条分类链接，键盘/读屏用户需要一条直通路径
 * （默认视觉隐藏、聚焦时显形 —— 标准 skip-link 形态）。 */
.pf-front__catalog-skip {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}
.pf-front__catalog-skip:focus {
  position: static;
  inline-size: auto;
  block-size: auto;
  margin: 0 0 var(--sp-4);
  padding: var(--sp-2) var(--sp-4);
  overflow: visible;
  clip: auto;
  background: var(--brand-primary);
  color: var(--surface);
  border-radius: var(--radius-sm);
}

/* 一级分类 = 原生 <details> 手风琴（零 JS；模板给首个分组加 open 默认展开） */
.pf-front__cat-groups { display: flex; flex-direction: column; margin: 0; padding: 0; list-style: none; }
.pf-front__cat-group-item { margin: 0; }
.pf-front__cat-group { border-block-end: 1px solid var(--border); }
.pf-front__cat-group-item:last-child .pf-front__cat-group { border-block-end: 0; }
.pf-front__cat-summary {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding-block: var(--sp-3);
  font-family: var(--font-heading);
  /* ★ 第 107j 批（2026-10-14 甲方）：「分类的字体能否缩小一些」——由 var(--fs-lg)（18px）
   *   降到固定 16px（同 89 批「直写字号」先例）。与左栏加宽到 18rem 配合，四大英文类目名
   *   一行显示（实测最长的「Pesticides & Fertilizers」16px = 170px，可用宽度 ~190px）。 */
  font-size: 1rem;
  font-weight: 700;
  color: var(--brand-primary);
  cursor: pointer;
  list-style: none;
}
.pf-front__cat-summary::-webkit-details-marker { display: none; }
/* 自绘指示箭头（零字体/emoji 依赖；展开时翻转）。边框用逻辑属性 ⇒ RTL 自动镜像。 */
.pf-front__cat-summary::after {
  content: '';
  flex: 0 0 auto;
  inline-size: 0.5rem;
  block-size: 0.5rem;
  border-inline-end: 2px solid currentColor;
  border-block-end: 2px solid currentColor;
  transform: rotate(45deg) translate(-1px, -1px);
  transition: transform 0.2s ease;
}
.pf-front__cat-group[open] > .pf-front__cat-summary::after { transform: rotate(225deg) translate(-2px, -2px); }
.pf-front__cat-summary:hover { color: var(--brand-green); }
.pf-front__cat-summary:focus-visible { outline: 2px solid var(--brand-green); outline-offset: 2px; }
.pf-front__cat-name { flex: 1 1 auto; min-inline-size: 0; }
/* 数量徽标 = 该一级分类的**直接子分类个数**（非产品数）—— 甲方（图1）既有口径，保留。
 * 审计①3「建议增加轻微的背景色（如浅灰色圆角背景）」在本站**已具备**（浅灰底 + 描边 +
 * 全圆角，第 135 批已做），故本批只做位置/字重适配，不改配色语义。 */
.pf-front__cat-count {
  flex: 0 0 auto;
  margin-inline-start: auto;
  font-family: var(--font-body);
  font-size: var(--fs-base);
  font-weight: 600;
  color: var(--text);
  background: var(--surface-sunken);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  padding: 0 var(--sp-2);
  line-height: 1.7;
  font-variant-numeric: tabular-nums;
}
.pf-front__cat-panel { padding-block-end: var(--sp-3); }
.pf-front__cat-all { margin: 0 0 var(--sp-3); }
.pf-front__cat-all a { display: inline-flex; align-items: center; gap: var(--sp-2); font-weight: 600; color: var(--brand-primary); }
.pf-front__cat-all a:hover { color: var(--brand-green); }
.pf-front__cat-all-arrow { display: inline-block; transition: transform 0.18s ease; }
.pf-front__cat-all a:hover .pf-front__cat-all-arrow { transform: translateX(3px); }
[dir="rtl"] .pf-front__cat-all-arrow { transform: scaleX(-1); }
[dir="rtl"] .pf-front__cat-all a:hover .pf-front__cat-all-arrow { transform: scaleX(-1) translateX(3px); }

/* 二/三级子分类：**胶囊标签**，换行排布 + 悬浮反色（审计①1） */
.pf-front__cat-subs { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin: 0; padding: 0; list-style: none; }
.pf-front__cat-sub { display: flex; flex-direction: column; align-items: flex-start; gap: var(--sp-2); margin: 0; max-inline-size: 100%; }
.pf-front__cat-subs .pf-front__subcat {
  display: inline-block;
  inline-size: auto;
  padding: 5px 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  color: var(--brand-primary);
  font-size: var(--fs-base);
  line-height: 1.45;
  transition: background-color 0.16s ease, border-color 0.16s ease, color 0.16s ease;
}
.pf-front__cat-subs .pf-front__subcat:hover {
  background: var(--brand-primary);
  border-color: var(--brand-primary);
  color: var(--surface);
  text-decoration: none;
}
.pf-front__cat-subs .pf-front__subcat--l3 { font-size: var(--fs-sm); }
/* ★ 第 107j 批（2026-10-14）：左栏「当前分类」高亮（分类页在看的类目）。
   ① 一级组：summary 用强调蓝（该组同时保持展开，展开态逻辑见模板 buildCatalogSidebar）；
   ② 二/三级项：深蓝填充胶囊，与分类页顶部 chips 的 `--current` 同款视觉。
   ★ 特异性说明：`.pf-front__cat-subs .pf-front__subcat`（0,2,0）会盖过通用 `.pf-front__subcat--current`
   （0,1,0），故此处以同特异性、后置声明覆盖；`:hover` 一并写出覆盖同级 hover 规则。 */
.pf-front__cat-group--current > .pf-front__cat-summary { color: var(--brand-green); }
.pf-front__cat-subs .pf-front__subcat--current,
.pf-front__cat-subs .pf-front__subcat--current:hover {
  background: var(--brand-primary);
  border-color: var(--brand-primary);
  color: var(--surface);
  font-weight: 600;
}
/* 三级分类：缩进 + 细竖线，视觉上从属于其二级父项（**仅限左栏**，不动分类页导航条） */
.pf-front__cat-sub > .pf-front__subcat-subs {
  flex-direction: row;
  flex-wrap: wrap;
  gap: var(--sp-1);
  margin: 0;
  padding: 0 0 0 var(--sp-3);
  border-inline-start: 2px solid var(--border);
}
/* ★ 兼容保留：分类页导航条（`.pf-front__subnav`）仍用 `.pf-front__subcat-group` 承载「父 + 子」，
   该结构由 ssg/templates/product.js#categoryPage 产出，样式见下方 `.pf-front__subnav-scroll` 段。 */
.pf-front__subcat-group { display: flex; flex-direction: column; align-items: flex-start; gap: var(--sp-2); }
/* ★  6 ：「」（ + ）。
   、；、、、。
    sticky（，）；，RTL 。 */
.pf-front__subnav { margin-block-end: var(--sp-6); border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); overflow: hidden; }
.pf-front__subnav .pf-front__crumbs { padding: var(--sp-2) var(--sp-4); background: transparent; border: 0; border-block-end: 1px solid var(--border); }
.pf-front__subnav .pf-front__crumbs ol { max-inline-size: none; margin-inline: 0; }
/* ★ 66 批：子分类条由**横向滚动**改为**换行铺开**。
   原 `overflow-x:auto + white-space:nowrap` ⇒ 内容 2497px / 可视 1134px，后面的 chip
   必须横向拖动才看得到（移动端几乎不可用）。现改为多行换行，全部 chip 直接可见。
   `.pf-front__subnav` 上仍有 `overflow:hidden`，圆角不会被换行内容顶破。 */
.pf-front__subnav-scroll { overflow: visible; }
.pf-front__subnav-scroll .pf-front__subcats {
  flex-flow: row wrap;          /* ★ 换行铺开（原来是 nowrap） */
  align-items: center;
  gap: var(--sp-2);
  margin: 0;
  padding: var(--sp-3) var(--sp-4);
}
.pf-front__subnav-scroll .pf-front__subcat { flex: 0 0 auto; }
/* 父项 + 其子项：整组不跨行断开，子项本身可换行 */
.pf-front__subnav-scroll .pf-front__subcat-group {
  display: inline-flex;
  flex-flow: row wrap;
  align-items: center;
  gap: var(--sp-2);
}
.pf-front__subnav-scroll .pf-front__subcat-subs {
  display: inline-flex;
  flex-flow: row wrap;
  align-items: center;
  gap: var(--sp-2);
}
/* （）。 */
.pf-front__subcat--current { background: var(--brand-primary); border-color: var(--brand-primary); color: var(--surface); font-weight: 600; }

/* -------------------------------  ------------------------------- */
.pf-front__resources-intro { max-inline-size: 70ch; color: var(--text-muted); margin-block-end: var(--sp-6); }
.pf-front__resource-cat-grid { margin-block-end: var(--sp-10); }
.pf-front__resource-cat { display: flex; }
.pf-front__resource-cat-link {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  inline-size: 100%;
  block-size: 100%;
  padding: var(--sp-6);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  cursor: pointer;
  transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}
.pf-front__resource-cat-link:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); border-color: var(--brand-green); text-decoration: none; }
.pf-front__resource-cat-name { font-family: var(--font-heading); font-weight: 700; color: var(--brand-primary); }
.pf-front__resource-cat-desc { font-size: var(--fs-base); color: var(--text-muted); margin-block-start: auto; }
/* ★  2026-09-20（1 ·）： + 
   （ --text-muted 「」， --text）。 `.pf-front__resources-index`
   （ / ，）；（.pf-front__resource-cat-*
    .pf-front__link-list ）。 */
.pf-front__resources-index .pf-front__resource-cat-name { font-size: var(--fs-lg); }
.pf-front__resources-index .pf-front__resources-intro { font-size: var(--fs-lg); color: var(--text); } /* ★#135： 16→18、muted→text */
.pf-front__resources-index .pf-front__resource-cat-desc { font-size: var(--fs-lg); color: var(--text); } /* ★#135： 16→18 */
.pf-front__resources-index .pf-front__link-list li { font-size: var(--fs-lg); border-block-end-color: var(--border-strong); }
.pf-front__resources-index .pf-front__resource-latest-item time { font-size: var(--fs-base); color: var(--text); }
.pf-front__article-meta { font-size: var(--fs-base); color: var(--text); } /* ★#145：14→16px；muted→text */
.pf-front__article-summary { font-size: var(--fs-xl); color: var(--text); max-inline-size: 70ch; } /* ★#145：18→22px；muted→text */
.pf-front__article-body { max-inline-size: 72ch; font-size: var(--fs-lg); line-height: var(--lh-body); color: var(--text); } /* ★#145：16→18px； --text */
/* ★#145：「」（18px）。 [data-b01-main="news"]
   （news  page.kind='news'， render.js data-b01-main=page.kind）；
    .pf-front__prose（L390，/，）。 */
[data-b01-main="news"] .pf-front__prose { font-size: var(--fs-lg); }
.pf-front__faq-list { display: grid; gap: var(--sp-3); margin: 0; }
.pf-front__faq-q { font-family: var(--font-heading); font-weight: 700; color: var(--brand-primary); }
.pf-front__faq-a { margin: 0 0 var(--sp-4); color: var(--text); }
.pf-front__back { margin-block-start: var(--sp-10); font-family: var(--font-heading); font-weight: 600; }

/* -------------------------------  ------------------------------- */
.pf-front__solution-intro { max-inline-size: 70ch; color: var(--text-muted); }
.pf-front__solution-cap-list,
.pf-front__solution-benefit-list,
.pf-front__solution-flow-list { display: grid; gap: var(--sp-2); margin: 0; padding-inline-start: var(--sp-6); }
/* ★  2026-09-21 ⑤：Solution 「 +  + 」。
   （.pf-front__solution-main）：Solution(h1) → intro → Our Capabilities → Services（）；
   （.pf-front__solution-about-col）：About Us 。（h1/h2 top ）。
   ★  `.pf-front__solution-split`  —— ** solution **
     （D2  / renderSub ）⇒  solution ， 20 。
    ⇒ RTL ；，。 */
.pf-front__solution-split { display: grid; grid-template-columns: 1fr; gap: var(--sp-10); align-items: start; margin-block-start: 0; }
.pf-front__solution-main { display: grid; gap: var(--sp-11); }
/* （ bg/border/radius/padding）⇒ ，h1/h2 。 */
.pf-front__solution-about-col { display: grid; gap: var(--sp-6); }
@media (min-width: 1024px) {
  .pf-front__solution-split { grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); }
}
/* ：「」（ auto-fill ；，）。
    2026-09-20 ①：：gap sp-6(24px) → sp-7(32px)。 */
.pf-front__solution-split .pf-front__solution-grid { grid-template-columns: 1fr; gap: var(--sp-7); }
/*  2026-09-20 ②：（ #129  1 ）。，。
   ：--fs-2xl/--fs-3xl  vw ，@1440  28px / 48px（ clamp  24/32px）。
    --fs-3xl（ 28→48px ）， calc(--fs-2xl + 0.375rem) ≈ 34px@1440。 */
.pf-front__solution-split .pf-front__section-title { font-size: var(--fs-3xl); }              /* ， */
.pf-front__solution-split .pf-front__solution-intro { font-size: var(--fs-2xl); }             /* xl → 2xl */
.pf-front__solution-split .pf-front__solution-cap-list li { font-size: var(--fs-2xl); }       /* xl → 2xl */
.pf-front__solution-split .pf-front__solution-name { font-size: calc(var(--fs-2xl) + 0.375rem); } /* 2xl → 2xl+6px */
.pf-front__solution-split .pf-front__solution-desc { font-size: var(--fs-xl); }               /* lg → xl */
.pf-front__solution-split .pf-front__solution-about-col .pf-front__prose { font-size: var(--fs-2xl); line-height: 1.5; } /* xl → 2xl;  1.7 → 1.5（，:root --lh-body ） */

/* -------------------------------  ------------------------------- */
/* ★ 2026-09-20 ③：contact ， intro / ，
   .pf-front__contact-intro / __contact-trust / __contact-list ，。
    .pf-front__contact-layout ≥768  1.4fr 1fr（ / ）。 */
.pf-front__contact-layout { display: grid; grid-template-columns: 1fr; gap: var(--sp-10); align-items: start; }
.pf-front__field { margin-block-end: var(--sp-4); }
.pf-front__label { display: block; font-size: var(--fs-base); color: var(--text); margin-block-end: var(--sp-1); text-align: start; } /* ★#135： 14→16、muted→text（；contact  + ） */
.pf-front__input,
.pf-front__textarea,
.pf-front__select {
  inline-size: 100%;
  padding-block: var(--sp-3);
  padding-inline: var(--sp-4);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font: inherit;
  font-size: var(--fs-base); /* ★#135： 16px， <16px  iOS  */
  background: var(--surface);
  color: var(--text);
  transition: border-color 0.18s ease, box-shadow 0.18s ease;
}
.pf-front__input:focus,
.pf-front__textarea:focus,
.pf-front__select:focus { border-color: var(--brand-green); box-shadow: 0 0 0 var(--sp-1) rgba(62, 146, 204, 0.2); outline: none; }
.pf-front__error { color: var(--err); font-size: var(--fs-xs); margin-block-start: var(--sp-1); text-align: start; }
.pf-front__input[aria-invalid="true"],
.pf-front__textarea[aria-invalid="true"] { border-color: var(--err); }
.pf-front__honeypot { position: absolute; inset-inline-start: -624.9375rem; inline-size: 1px; block-size: 1px; overflow: hidden; }
/* ★ R1 ：（front.js ， role=status /  role=alert）。 */
.pf-front__form-result {
  margin-block-start: var(--sp-4);
  padding-block: var(--sp-3);
  padding-inline: var(--sp-4);
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  font-size: var(--fs-base);
  text-align: start;
}
/* ★ 第 37 批：成功/错误回执色改走 :root 功能色令牌（--ok/--err，参考 §2.1③「仅用于状态」）。
 *   色值微调（#1b5e20→#2e7d4f 等）为参考给定的可访问色对，浅底形态不变。 */
.pf-front__form-result--success { color: var(--ok); background: var(--ok-bg); border-color: var(--ok-bd); }
.pf-front__form-result--error { color: var(--err); background: var(--err-bg); border-color: var(--err-bd); }
.pf-front__form[aria-busy="true"] button[type="submit"] { opacity: 0.6; cursor: progress; }

/* -------------------------------  ------------------------------- */
/* ★ #140 ：「，」。
   ****（ <footer> 、 gutter）
   ⇒  1376px vs / 1320px， 60px、。
   ：<footer>  + ；
   .pf-front__footer-inner， .pf-front__header-top / .pf-front__nav-row / .pf-front__main
   「inline-size:100% + max-inline-size:var(--container) + margin-inline:auto
   + padding-inline:var(--gutter)」（ .pf-front__container ，）。
   ⚠️ ****：，<footer> **** max-inline-size / margin-inline。 */
.pf-front__footer {
  padding-block: var(--sp-10);
  margin-block-start: var(--sp-12);
  /*  2026-09-20 ④：****，
     #0a2463 → #0f3070 → #14418a → #17509b → #19539f ：#14418a → #17509b。 */
  background: #17509b;
  color: var(--on-dark-muted);
}
/* ：。 auto-fit  5 （4  + grid-column:1/-1  bottom）
    5  ⇒  4/5，。：
    1  / ≥768  / ≥1024 。 */
.pf-front__footer-inner {
  inline-size: 100%;
  max-inline-size: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--sp-6);
}
@media (min-width: 768px) {
  .pf-front__footer-inner { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1024px) {
  .pf-front__footer-inner { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
.pf-front__footer-col { max-inline-size: var(--container); }
.pf-front__footer-title { color: var(--surface); font-size: var(--fs-xl); margin-block-end: var(--sp-3); } /* ③  2026-09-20：lg → xl */
.pf-front__footer-list { display: grid; gap: var(--sp-2); list-style: none; margin: 0; padding: 0; font-size: var(--fs-base); } /* ③  2026-09-20：sm → base */
.pf-front__footer-list a { color: var(--on-dark); }
.pf-front__footer-list a:hover { color: var(--surface); }
/* 2026-09-19 ：（ / ），。 */
.pf-front__footer-bottom {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  margin-block-start: var(--sp-6);
  padding-block-start: var(--sp-4);
  border-block-start: 1px solid var(--hairline);
  /* ★ #137 ②：****「」，。
      = (64=--sp-11) + (20=--sp-5) + (16=--sp-4) = 100px。
     **** padding-inline-end ⇒  RTL （RTL ）。
     「」（）。 */
  padding-inline-end: calc(var(--sp-11) + var(--sp-5) + var(--sp-4));
}
.pf-front__copyright {
  margin: 0;
  font-size: var(--fs-lg); /* ③  2026-09-20：base → lg */
  color: var(--on-dark-muted);
}
/* docs/15 ⑩：（，）。 */
.pf-front__icp-link { color: var(--on-dark-muted); text-decoration: underline; text-underline-offset: 2px; }
.pf-front__icp-link:hover { color: var(--surface); }
.pf-front__footer-native { color: var(--on-dark); }

/* docs/15 ⑨ + 2026-09-19 ：， .pf-front__footer-bottom
   flex （ / ）→  grid-column ； margin-inline-start:auto 。 */
.pf-front__footer-social {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  flex-wrap: wrap;
  gap: var(--sp-3);
  margin-inline-start: auto;
}
.pf-front__footer-social-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: var(--sp-8);
  block-size: var(--sp-8);
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, 0.08);
  color: var(--on-dark);
  transition: background-color 0.18s ease, color 0.18s ease, transform 0.18s ease;
}
.pf-front__footer-social-link:hover {
  background: var(--accent-on-dark);
  color: var(--surface);
  text-decoration: none;
  transform: translateY(-1px);
}
.pf-front__footer-social-icon { inline-size: var(--sp-5); block-size: var(--sp-5); }

/* ------------------------------- （） ------------------------------- */

/* sm 480 */
@media (min-width: 480px) {
  :root { --gutter: var(--sp-6); }
}

/* md 768 */
@media (min-width: 768px) {
  .pf-front__hero { padding: var(--sp-10) var(--sp-8); }
  .pf-front__main { padding-block: var(--sp-10); }
  .pf-front__home-section { margin-block-start: var(--sp-12); }
  .pf-front__contact-layout { grid-template-columns: 1.4fr 1fr; }
  .pf-front__home-hero { grid-template-columns: 1.05fr 1fr; }
  .pf-front__home-section[data-section="featured-products"] .pf-front__featured-grid { grid-template-columns: repeat(2, 1fr); }
  /* docs/15 ⑧：FAQ ≥768 ； 3（），。 */
  .pf-front__home-faq { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* ★ batch79：仅当**项数为奇数**（原 3 项）时末项跨满整行；**4 项时呈标准 2×2**。 */
  .pf-front__home-faq-item:last-child:nth-child(odd) { grid-column: 1 / -1; }
}

/* ： 4  /  2×2 /  1 （docs/07 §5）。
    auto-fill  ~800–1099px  3  →  4 ； 2×2。 */
@media (min-width: 768px) and (max-width: 1099px) {
  .pf-front__value-grid { grid-template-columns: repeat(2, 1fr); }
}

/* lg 1024 */
@media (min-width: 1024px) {
  :root { --gutter: var(--sp-7); }
  /*  2026-09-19：** 4 **（4  296px， 26%）。 */
  .pf-front__home-section[data-section="featured-products"] .pf-front__featured-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* xl 1440 */
@media (min-width: 1440px) {
  :root { --container: 82.5rem; }
}

/* xxl 1920 */
@media (min-width: 1920px) {
  :root { --container: 90rem; }
}

/* ：（ front.js  .pf-front__header-top） */
/* ★ C 落地（2026-09-21）：移动端 header 收紧 —— 工具行与 logo 同排、语言改下拉、联系信息收进抽屉 */
@media (max-width: 767px) {
  .pf-front__nav-toggle { display: inline-flex; }
  .pf-front__lang-toggle { display: inline-flex; }
  /*  2026-09-19 3： Logo  +1  48px(--sp-9) → 56px(--sp-10)。 */
  .pf-front__brand-logo { block-size: var(--sp-10); max-block-size: var(--sp-10); }
  /*  2026-09-19（2）： +2  12px(--fs-xs) → 16px(--fs-base)，。 */
  .pf-front__brand-legal { font-size: var(--fs-base); }
  /* 工具行：与 logo 同排右对齐（不再满宽纵向堆叠） */
  .pf-front__header-side {
    inline-size: auto;
    flex-direction: row;
    align-items: center;
    justify-content: flex-end;
    gap: var(--sp-2);
    position: relative;
  }
  /* 语言：桌面 5 链接 → 移动端下拉面板 */
  .pf-front__lang { display: none; }
  .pf-front__lang.is-open {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    position: absolute;
    inset-inline-end: 0;
    inset-block-start: calc(100% + var(--sp-2));
    min-inline-size: 9rem;
    padding: var(--sp-1);
    background: var(--surface);
    border: 1px solid var(--hairline);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md);
    z-index: 60;
  }
  .pf-front__lang.is-open .pf-front__lang-link {
    color: var(--text);
    justify-content: flex-start;
    min-block-size: var(--sp-9);
  }
  .pf-front__lang.is-open .pf-front__lang-link[aria-current="true"] {
    background: var(--accent-fill);
    color: var(--surface);
  }
  /* 抽屉（菜单 + 联系信息）：默认收起，汉堡展开 */
  .pf-front__nav-row { display: none; }
  body.pf-nav-open .pf-front__nav-row { display: block; }
  .pf-front__nav { display: flex; flex-direction: column; align-items: stretch; }
  .pf-front__nav-link {
    justify-content: flex-start;
    inline-size: 100%;
    min-block-size: 0;
    padding-block: var(--sp-3);
    border-inline: 0;
    border-block-end: 1px solid var(--hairline);
  }
  .pf-front__nav-link:first-child { border-inline-start: 0; }
  .pf-front__nav-link[aria-current="page"] { border-block-end-color: var(--hairline); }
  /* 联系信息收进抽屉内，纵向排列、与菜单分隔 */
  .pf-front__header-contact {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--sp-2);
    justify-content: flex-start;
    padding-inline: 0;
    padding-block: var(--sp-3);
    border-block-start: 1px solid var(--hairline);
    font-size: var(--fs-sm);
  }
  .pf-front__main { padding-block: var(--sp-8); }
  .pf-front__home-section { margin-block-start: var(--sp-9); }
  .pf-front__home-cta { padding-block: var(--sp-9); }
}

/* --------------------------- RTL （docs/06 §1.5） ---------------------------
 * ；：
 *   ① LTR ：CAS /  / SKU /  /  / （.keep-ltr） AR  LTR；
 *   ② ： RTL 。
 */
[dir="rtl"] .keep-ltr { direction: ltr; unicode-bidi: isolate; text-align: left; }
[dir="rtl"] .pf-front__crumbs ol { flex-direction: row-reverse; }

/* 「」 */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ============================================================================
 * #136 ： /  / 「」
 * ----------------------------------------------------------------------------
 * ★ RTL：****（inset-inline-end / padding-inline / margin-inline）⇒
 *    RTL 、。
 * ★ ： @media (prefers-reduced-motion: reduce)（），。
 * ★ ： z-index(40) < (50)，；。
 * ★ ： #135 ， ≥--fs-base(16px)。
 * ==========================================================================*/

/* ：（ label）。 */
.pf-front__visually-hidden {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ------------------------------  ------------------------------ */
.pf-front__search { display: flex; align-items: center; gap: var(--sp-2); }
.pf-front__search-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: var(--sp-8);
  block-size: var(--sp-8);
  padding: 0;
  border: 1px solid var(--hairline);
  background: rgba(255, 255, 255, 0.08);
  color: var(--surface);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background 0.18s ease;
}
.pf-front__search-toggle:hover { background: rgba(255, 255, 255, 0.18); }
.pf-front__search-icon { display: block; }
.pf-front__search-form { display: flex; align-items: center; gap: var(--sp-1); }
.pf-front__search-form[hidden] { display: none; }
.pf-front__search-input {
  block-size: var(--sp-8);
  min-inline-size: 11rem;
  max-inline-size: 16rem;
  padding-inline: var(--sp-3);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: var(--fs-base);
}
.pf-front__search-submit {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: var(--sp-8);
  block-size: var(--sp-8);
  padding: 0;
  border: 0;
  background: var(--accent-fill);
  color: var(--surface);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background 0.18s ease;
}
.pf-front__search-submit:hover { background: var(--brand-primary); }

/* ------------------------------  ------------------------------ */
.pf-front__search-page-form {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  margin-block: var(--sp-5) var(--sp-6);
  max-inline-size: 44rem;
}
.pf-front__search-page-input { flex: 1 1 16rem; }
.pf-front__search-status { color: var(--text-muted); font-size: var(--fs-base); min-block-size: 1.5em; }
.pf-front__search-results { margin-block-start: var(--sp-4); }
.pf-front__search-group { margin-block-start: var(--sp-7); }
.pf-front__search-group-title { font-size: var(--fs-xl); margin-block-end: var(--sp-3); }
.pf-front__search-group-count { color: var(--text-muted); font-size: var(--fs-base); font-weight: 600; }
.pf-front__search-list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-3); }
.pf-front__search-hit {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--sp-3) var(--sp-4);
  background: var(--surface);
}
.pf-front__search-hit-title { font-family: var(--font-heading); font-size: var(--fs-lg); font-weight: 600; }
.pf-front__search-hit-desc { margin: var(--sp-1) 0 0; color: var(--text); font-size: var(--fs-base); }

/* --------------------------- 「」 --------------------------- */
/* column-reverse：DOM 「」，****。
   inset-block-end + inset-inline-end  ⇒ RTL 。 */
.pf-front__chat {
  position: fixed;
  inset-block-end: var(--sp-5);
  inset-inline-end: var(--sp-5);
  z-index: 40;
  display: flex;
  flex-direction: column-reverse;
  align-items: flex-end;
  gap: var(--sp-3);
}
.pf-front__chat-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: var(--sp-11);
  block-size: var(--sp-11);
  padding: 0;
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--brand-primary);
  color: var(--surface);
  box-shadow: var(--shadow-lg);
  cursor: pointer;
  transition: background 0.18s ease, transform 0.18s ease;
}
.pf-front__chat-toggle:hover { background: var(--brand-primary-light); transform: translateY(-2px); }
.pf-front__chat-toggle-icon { display: block; }
.pf-front__chat-panel {
  inline-size: min(20rem, calc(100vw - var(--sp-10)));
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: var(--sp-5);
}
.pf-front__chat-panel[hidden] { display: none; }
.pf-front__chat-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  margin-block-end: var(--sp-3);
}
.pf-front__chat-title { margin: 0; font-family: var(--font-heading); font-size: var(--fs-lg); font-weight: 700; color: var(--brand-primary); }
.pf-front__chat-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: var(--sp-7);
  block-size: var(--sp-7);
  padding: 0;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-muted);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background 0.18s ease, color 0.18s ease;
}
.pf-front__chat-close:hover { background: var(--surface-sunken); color: var(--text); }
.pf-front__chat-list { list-style: none; margin: 0 0 var(--sp-4); padding: 0; display: grid; gap: var(--sp-2); }
.pf-front__chat-link {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--text);
  transition: background 0.18s ease, border-color 0.18s ease;
}
.pf-front__chat-link:hover { background: var(--surface-alt); border-color: var(--brand-green); text-decoration: none; }
.pf-front__chat-ico { flex: 0 0 auto; color: var(--brand-primary); }
.pf-front__chat-text { display: flex; flex-direction: column; min-inline-size: 0; }
.pf-front__chat-label { font-weight: 600; }
.pf-front__chat-value { font-size: var(--fs-base); color: var(--text-muted); overflow-wrap: anywhere; }
.pf-front__chat-inquiry { display: block; text-align: center; }

/* ：；（）。 */
@media (max-width: 767px) {
  /* ★ C 落地：搜索表单在移动端从「满宽行内」改为「工具行右侧下拉面板」，配合 header-side 横向紧凑布局 */
  .pf-front__search { inline-size: auto; position: static; }
  /* ★ 2026-09-26 修复（A 方案）：移动端搜索面板左边界出屏。
     根因：三个下拉面板（搜索／语言／菜单）都锚在 `.pf-front__header-side`，
     该行是 flex 内容宽、靠左（360px 屏仅 137.6px），而面板宽 min(20rem, 78vw) ≈ 81vw
     ⇒ `inset-inline-end: 0` 必然向左冲出屏幕（实测左边界 −133.4px，46% 在屏外）。
     修法：锚点由「工具行右边缘」改为「工具行左边缘」并限宽进屏。
     ★ 只把搜索按钮挪到工具行最右侧无效（实测仍出屏 73.4px）——面板宽度不变，锚点不换必然出头。
     实测：360px 屏 20→311px，100% 进屏；语言下拉位置不变；RTL 自动镜像。 */
  .pf-front__search-form { position: absolute; inset-inline-end: auto; inset-inline-start: 0; inset-block-start: calc(100% + var(--sp-2)); flex: 0 0 auto; min-inline-size: min(20rem, 78vw); max-inline-size: calc(100vw - 2 * var(--gutter)); background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius-md); padding: var(--sp-2); box-shadow: var(--shadow-md); z-index: 60; }
  .pf-front__search-input { min-inline-size: 0; max-inline-size: none; flex: 1 1 auto; }

  /* ★★ 2026-09-26 手机端页头两行重排（甲方三项要求）
     ────────────────────────────────────────────────────────────
     ② 第一行「Logo + 公司名」整组居中。
        实测未居中时公司名右边缘 351.4 > 内容右边界 340（单侧溢出 11.4px，
        视觉上顶到屏幕右缘）；居中后左右对称、整组落在屏内。
     ③ 第二行三枚按钮（搜索 / 语言 / 菜单）三等分铺满整行。
        实测原状三枚挤在左侧 20→221.6，右侧留白 118.4px。
        ★ 结构限制：前两枚在 `.pf-front__header-side` 内、第三枚 `.pf-front__nav-toggle`
          是该容器**外面**的兄弟节点 ⇒ 单纯调 flex 无法三等分。
          故用 grid：header-side 跨 2 列、nav-toggle 跨 1 列，并把 header-side 内 gap
          对齐成同一个 16px ⇒ 三格精确等宽（360px 屏实测各 96px）。
        ★ 不使用 `display: contents` 打散 header-side —— 那会毁掉它作为搜索／语言
          两个下拉面板绝对定位锚点的 `position: relative`。 */
  .pf-front__header-top {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--sp-3);
  }
  .pf-front__brand {
    grid-column: 1 / -1;
    inline-size: 100%;
    margin-inline-end: 0;
    justify-content: center;
  }
  .pf-front__header-side {
    grid-column: span 2;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--sp-3);
  }
  /* search 自身是 flex 容器（内含触发的 button），让 button 填满该格 */
  .pf-front__header-side .pf-front__search { flex: 1 1 0; }
  .pf-front__search-toggle { flex: 1 1 0; }
  .pf-front__lang-toggle { justify-content: center; }
  /* nav-toggle 基础规则写死了 inline-size: --sp-9，grid item 不会 stretch ⇒ 须显式放开；
     align-items: center 让汉堡条在新宽度里居中（基础规则只有 justify-content，原宽度刚好填满看不出）。 */
  .pf-front__nav-toggle { grid-column: span 1; inline-size: auto; align-items: center; }
  /* 汉堡条基础规则为 inline-size: 100%，按钮一拉宽就变成一条长横线 ⇒ 固定回原实测宽度 22px。 */
  .pf-front__nav-toggle-bar { inline-size: 22px; }

  .pf-front__chat { inset-inline-end: var(--sp-4); inset-block-end: var(--sp-4); }
  /* ★ #137 ②：（64 → 48）， 24 → 20；：
      48 +  16 +  16 = 80px（ ⇒ RTL ）。 */
  .pf-front__chat-toggle { inline-size: 48px; block-size: 48px; }
  .pf-front__chat-toggle-icon { inline-size: 20px; block-size: 20px; }
  /* ★ 2026-09-26（第二批）甲方（手机端）：页脚「Shanghai Profirst Co., Ltd.」与
   *   「沪ICP备10200502号-4」被从中间折断（折成「…Co.,」/「Ltd.」「…沪ICP」/「备…号-4」）。
   *
   * 根因＝这里原有的 80px 预留。其上方注释写明是为**自研**悬浮客服按钮让位
   *   （chat-toggle 48px + 16 + 16 = 80px）；但本站现已接入 Tawk.to ⇒ 自研
   *   `.pf-front__chat` **根本不渲染**（线上 HTML 里 grep 不到该 class，只有 `tawk`）
   *   ⇒ 这 80px 只是把版权行可用宽从 320px 压到 240px，**没保护任何东西**。
   *   ★ 另一个必须绕开的坑：**手机字体比桌面 Chrome 的度量宽**（HarmonyOS Sans vs 系统回退），
   *     桌面实测 226px 的「Shanghai Profirst Co., Ltd.」到真机约 250px
   *     ⇒ 解法只能是「放宽可用宽」，不能靠「精确凑像素」。
   *
   * 修法：① 取消预留（社媒图标行已改为靠左铺满，天然避开右下角潜在的客服位）；
   *       ② 公司法定名与备案号声明为**不可拆分整体**（nowrap）⇒ 断行只发生在空格处，
   *          不会再出现「…Co.,」/「Ltd.」这种把专名劈开的难看折行。
   * 实测（真实浏览器，320/360/393/412 + 六语 + RTL）：四行整齐、无横向滚动。 */
  .pf-front__footer-bottom { padding-inline-end: 0; }
  .pf-front__copyright .keep-ltr { white-space: nowrap; }
  .pf-front__icp-link { white-space: nowrap; }

  /* ★ 2026-09-26 甲方（手机端）：6 个社媒图标掉成「4+2 / 5+1」两行，WhatsApp 单独一行，难看。
   * 根因：上一行为悬浮客服按钮预留 80px（实测 padR=80px）⇒ 底部行可用宽只有
   *   320−80 = 240px（360 屏）；而基础规则下 6 个图标需 6×40 + 5×12 = 300px ⇒ 必然换行。
   * 修法＝移动端把容器从 flex 改成 **6 列网格**（列宽 40px 为上限、间距 4px）：
   *   360 屏 → 每格 36.7×40，6 个 240px 恰好铺满一行；393 屏及以上 → 每格回到 40px。
   *   · minmax(0, 40px) 让列宽在窄屏自动等比收窄（320 屏 30px），**永不换行**；
   *   · 网格没有 flex 的换行语义 ⇒ 无论多窄都恒定一行，这是选 grid 而非 flex 的根本原因。
   * ★ 不用 `repeat(6, 1fr)`：1fr 在 767px 屏会把每格拉到 ~108px，图标散得太开。
   * ★ gap 取实测最优 4px（--sp-1）：0px 时 6 个圆角底块会连成一条长带；12px 时
   *   底块被压成 30×40 的竖长条。4px 下底块仍近正方、且彼此清晰可分（三种已出图对比）。
   * ★ 必须同时给容器 `inline-size: 100%`：否则容器按 max-content 收缩，
   *   240px 的可用宽里图标只占右半边。
   * ★ 链接基础规则写死 inline-size: --sp-8（40px），窄屏会溢出格子 ⇒ 在移动端改为填满格子。 */
  .pf-front__footer-social {
    display: grid;
    grid-template-columns: repeat(6, minmax(0, 40px));
    justify-content: start;
    gap: var(--sp-1);
    inline-size: 100%;
  }
  .pf-front__footer-social-link { inline-size: 100%; }
}

/* ★ 2026-09-26 极窄屏兜底：内容宽 = 屏宽 − 2×20px，品牌组自然宽实测 331.4px
   ⇒ 只有屏宽 < 331.4px 时居中后两端才会被屏幕裁切（320px 屏 logo 左缘跑到 −5.7px）。
   ★ 断点必须卡在 331px：曾误设 371px，把主流的 360px 屏也拉进换行分支，
     导致 360 屏页头凭空多一行（留白 14.3 → 74.7）——360/393/412 本来都放得下。
   ★ 改动前 320px 屏溢出 51.4px，本条把残余的 5.7px 也收干净。 */
@media (max-width: 331px) {
  .pf-front__brand { flex-wrap: wrap; row-gap: var(--sp-1); }
}

/* ============================================================================
 * Hero 宣传视频轮播（C 方案：YouTube 主源 + 自托管 mp4 兜底）
 * ----------------------------------------------------------------------------
 * 由 templates/home.js#heroCarousel 产出结构、assets/front.js#initHeroCarousel 驱动。
 * ★ 库为空时**不产出**该结构，本节样式自然不生效（对既有产物零影响）。
 * ★ 固定宽高比：容器撑满 `.pf-front__home-hero-media`（16/9），slide 一律**绝对定位 + 透明度**
 *   切换（**不用 display:none**）⇒ 切换时高度恒定、不跳版。
 * ★ 颜色复用既有 CSS 变量与既有「rgba(10,36,99,α)」品牌底色写法，不硬编码品牌色。
 * ==========================================================================*/
.pf-front__hero-carousel {
  position: relative;
  inline-size: 100%;
  block-size: 100%;
  aspect-ratio: 16 / 9;              /* 与 .pf-front__home-hero-media 同步（兜底） */
  background: var(--brand-primary);  /* 封面加载前的底色，避免露白 */
  border-radius: inherit;
  overflow: hidden;
}
/* slides 列表容器：仅消掉 ul 浏览器默认样式（margin/padding/list-style），
   ★ 不设 position ⇒ slide 的定位基准仍是 .pf-front__hero-carousel */
.pf-front__hero-slides { margin: 0; padding: 0; list-style: none; }
/* 幻灯片：绝对定位叠放；仅用透明度/可见性切换 —— 高度由容器固定比例撑住，不塌陷不跳版 */
.pf-front__hero-slide {
  position: absolute;
  inset: 0;
  margin: 0;
  list-style: none;
  opacity: 0;
  visibility: hidden;
  z-index: 1;
  transition: opacity 0.4s ease;
}
.pf-front__hero-slide.is-active { opacity: 1; visibility: visible; z-index: 2; }
.pf-front__hero-slide-poster { display: block; inline-size: 100%; block-size: 100%; object-fit: cover; }
/* 播放器（iframe / video）注入后撑满整张 slide */
.pf-front__hero-slide > .pf-front__hero-video-frame,
.pf-front__hero-slide > .pf-front__hero-video { position: absolute; inset: 0; }

/* 标题条：覆盖在封面底部，半透明底 + 白字，text-shadow 保证可读 */
.pf-front__hero-slide-title {
  position: absolute;
  inset-inline: 0;
  inset-block-end: calc(var(--sp-2) + 1.75rem);   /* 让出底部圆点行 */
  display: block;
  padding: var(--sp-2) var(--sp-4);
  background: linear-gradient(to top, rgba(10, 36, 99, 0.72), rgba(10, 36, 99, 0.24));
  color: var(--surface);
  font-family: var(--font-heading);
  font-size: var(--fs-lg);
  font-weight: 600;
  line-height: 1.3;
  text-align: start;                               /* RTL 下自动右对齐 */
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.55);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 圆点条（≥2 条时） */
.pf-front__hero-dots {
  position: absolute;
  inset-inline: 0;
  inset-block-end: var(--sp-2);
  z-index: 4;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: var(--sp-2);
  pointer-events: none;                            /* 空白处不挡播放按钮 */
}
.pf-front__hero-dot {
  pointer-events: auto;
  inline-size: var(--sp-3);
  block-size: var(--sp-3);
  padding: 0;
  border: 1px solid var(--surface);
  border-radius: 999px;
  background: rgba(10, 36, 99, 0.45);
  cursor: pointer;
  transition: background-color 0.18s ease, transform 0.18s ease;
}
.pf-front__hero-dot[aria-selected="true"] { background: var(--surface); transform: scale(1.18); }
.pf-front__hero-dot:hover { background: var(--accent-on-dark); }
.pf-front__hero-dot:focus-visible { outline: 2px solid var(--surface); outline-offset: 2px; }

/* 上/下一张（逻辑方向定位；RTL 下按钮左右自动对调，图标再镜像） */
.pf-front__hero-prev,
.pf-front__hero-next {
  position: absolute;
  inset-block-start: 50%;
  transform: translateY(-50%);
  z-index: 5;
  inline-size: var(--sp-9);
  block-size: var(--sp-9);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: rgba(10, 36, 99, 0.5);
  color: var(--surface);
  cursor: pointer;
}
.pf-front__hero-prev { inset-inline-start: var(--sp-2); }
.pf-front__hero-next { inset-inline-end: var(--sp-2); }
.pf-front__hero-prev:hover,
.pf-front__hero-next:hover { background: var(--accent-fill); color: var(--surface); }
.pf-front__hero-prev:focus-visible,
.pf-front__hero-next:focus-visible { outline: 2px solid var(--surface); outline-offset: 2px; }
.pf-front__hero-prev svg,
.pf-front__hero-next svg { inline-size: var(--sp-5); block-size: var(--sp-5); }
[dir="rtl"] .pf-front__hero-prev svg,
[dir="rtl"] .pf-front__hero-next svg { transform: scaleX(-1); }

/* YouTube 不可达且无 mp4 时的兜底链接（在播放器下方，避开圆点行） */
.pf-front__hero-open {
  position: absolute;
  inset-inline: 0;
  inset-block-end: calc(var(--sp-2) + 1.75rem);
  z-index: 3;
  display: block;
  padding: var(--sp-1) var(--sp-4);
  background: rgba(10, 36, 99, 0.72);
  color: var(--surface);
  font-size: var(--fs-sm);
  text-align: center;
}
.pf-front__hero-open:hover { color: var(--surface); text-decoration: underline; }

/* 轮播播报节点（屏幕阅读器专用） */
.pf-front__hero-live {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* 窄屏：标题字号收紧、圆点间距收紧、箭头缩小并贴近容器内缘 */
@media (max-width: 768px) {
  .pf-front__hero-slide-title {
    font-size: var(--fs-base);
    inset-block-end: calc(var(--sp-1) + 1.375rem);
    padding: var(--sp-1) var(--sp-3);
  }
  .pf-front__hero-dots { gap: var(--sp-1); inset-block-end: var(--sp-1); }
  .pf-front__hero-dot { inline-size: var(--sp-2); block-size: var(--sp-2); }
  .pf-front__hero-prev,
  .pf-front__hero-next { inline-size: var(--sp-7); block-size: var(--sp-7); }
  .pf-front__hero-prev { inset-inline-start: var(--sp-1); }
  .pf-front__hero-next { inset-inline-end: var(--sp-1); }
  .pf-front__hero-prev svg,
  .pf-front__hero-next svg { inline-size: var(--sp-4); block-size: var(--sp-4); }
}

/* 尊重「减少动态效果」：去掉切换过渡（轮播禁用逻辑在 front.js） */
@media (prefers-reduced-motion: reduce) {
  .pf-front__hero-slide { transition: none; }
}

/* ============================================================================
 * 2026-09-23 甲方 UI 微调（8 项）— 追加覆写层
 * ----------------------------------------------------------------------------
 * 约定：本节只做「追加覆写」，不改动上方任何既有规则 ⇒ 每一条都可单独回滚。
 *  ① 大面积蓝底调浅 + 询盘 CTA / 页脚减薄
 *  ② 页头搜索框并入语言导航同一行（紧邻 English）
 *  ③ 新闻列表页固定「2 排 × 4 列」= 8 条，取消特写大卡
 *  ④ 产品索引页只出推荐产品（模板侧改，见 ssg/templates/product.js）
 *  ⑤ 白底正文 / 次级文字加大对比（--text、--text-muted 加深）
 *  ⑥ 解决方案页「关于我们」栏小一号（28px → 22px）
 *  ⑦ 询盘表单标签加大加粗
 *  ⑧ 右下角浮窗定位与尺寸规范化
 *
 * 对比度实测（WCAG AA 正文 ≥4.5:1；--on-dark = #eaf1fb）：
 *   页头 #1a4d93        × --on-dark        = 7.07:1  OK
 *   页头 #1a4d93        × --on-dark-muted  = 6.95:1  OK
 *   CTA  #2b6aac(中值)  × --on-dark        = 4.79:1  OK
 *   页脚 #2a6bad        × --on-dark        = 4.79:1  OK
 *   页脚 #2a6bad        × --on-dark-muted  = 4.73:1  OK
 * ==========================================================================*/

/* ---------- ① 蓝底调浅 + 减薄；⑤ 文字对比（共用变量） ---------- */
:root {
  /* 白底文字：加深一档（原 #1a2332 / #5b6b85） */
  --text: #101a2c;
  --text-muted: #3c4a63;
  /* 深底文字：提高不透明度，避免发灰（原 0.78） */
  --on-dark-muted: rgba(244, 248, 254, 0.94);
  /* 大面积蓝底（新增语义变量，便于后续统一调整） */
  --blue-surface: #2a6bad;
  --blue-surface-deep: #1a4d93;
}
.pf-front__header { background: var(--blue-surface-deep); }
.pf-front__home-cta {
  background: linear-gradient(140deg, #2764a6, #2b6aac 55%, #2e6fb0);
  padding-block: var(--sp-8);
}
.pf-front__home-cta-text,
.pf-front__home-cta-about { margin-block-end: var(--sp-4); }
.pf-front__home-cta-contact { margin-block-end: var(--sp-4); }
.pf-front__footer {
  background: var(--blue-surface);
  padding-block: var(--sp-8);
  margin-block-start: var(--sp-9);
}
.pf-front__footer-bottom { margin-block-start: var(--sp-5); }

/* ---------- ② 页头搜索框并入语言导航同一行 ---------- */
.pf-front__header-side {
  flex-direction: row;
  align-items: center;
  justify-content: flex-end;
  flex-wrap: wrap;
  gap: var(--sp-3);
}
.pf-front__header-side .pf-front__search { order: 0; }
.pf-front__header-side .pf-front__lang { order: 1; }
.pf-front__header-side .pf-front__lang-link { min-block-size: var(--sp-8); }

/* ---------- ③ 新闻列表：固定 2 排 × 4 列 ---------- */
.pf-front__news .pf-front__grid { grid-template-columns: 1fr; gap: var(--sp-5); }
@media (min-width: 560px) {
  .pf-front__news .pf-front__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1024px) {
  .pf-front__news .pf-front__grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
.pf-front__news-card { padding: var(--sp-5); gap: var(--sp-2); }
/* ★ 关键：`.pf-front__news-card` 自带 `display:flex`，会盖掉 UA 的 `[hidden]{display:none}`
   ⇒ 折叠卡片必须显式置 none，否则「加载更多」之前所有卡片照样铺满页面。
   （选择器权重 0,2,0 > 0,1,0，无需 !important；实测：漏掉本行时页面高 14,182px） */
.pf-front__news-card[hidden] { display: none; }
.pf-front__news-more-wrap { margin-block-start: var(--sp-7); text-align: center; }
.pf-front__news-more {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-block-size: var(--sp-9);
  padding-block: var(--sp-2);
  padding-inline: var(--sp-6);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-pill);
  background: var(--surface);
  color: var(--brand-primary);
  font: inherit;
  font-size: var(--fs-base);
  font-weight: 600;
  cursor: pointer;
  transition: background 0.18s ease, border-color 0.18s ease, color 0.18s ease;
}
.pf-front__news-more:hover { background: var(--surface-alt); border-color: var(--brand-green); color: var(--brand-primary); }
.pf-front__news-more[hidden] { display: none; }

/* ---------- ⑤ 白底文字加大对比 ---------- */
.pf-front__resource-latest-item a,
.pf-front__link-list a { font-weight: 600; }
.pf-front__resource-latest-item time { color: var(--text-muted); font-weight: 600; }
.pf-front__resources-intro,
.pf-front__resource-cat-desc,
.pf-front__sitemap-intro,
.pf-front__solution-intro { color: var(--text); }
.pf-front__card-desc,
.pf-front__value-text,
.pf-front__doc-text,
.pf-front__solution-desc { color: var(--text-muted); }

/* ---------- ⑥ 解决方案页「关于我们」栏小一号 ---------- */
.pf-front__solution-split .pf-front__solution-about-col .pf-front__prose {
  font-size: var(--fs-xl);
  line-height: 1.6;
}

/* ---------- ⑦ 询盘表单标签加大加粗 ---------- */
.pf-front__label { font-size: var(--fs-lg); font-weight: 600; color: var(--text); }

/* ---------- ⑧ 右下角浮窗：定位与尺寸规范化 ---------- */
.pf-front__chat {
  inset-block-end: var(--sp-6);
  inset-inline-end: var(--sp-6);
  gap: var(--sp-3);
}
.pf-front__chat-toggle { inline-size: 56px; block-size: 56px; }
.pf-front__chat-toggle-icon { inline-size: 26px; block-size: 26px; }
@media (max-width: 767px) {
  .pf-front__chat { inset-block-end: var(--sp-4); inset-inline-end: var(--sp-4); }
  .pf-front__chat-toggle { inline-size: 52px; block-size: 52px; }
  .pf-front__chat-toggle-icon { inline-size: 24px; block-size: 24px; }
}

/* ==========================================================================
 * 第 2 批甲方微调（2026-09-23 下午）—— 9 项
 *   ①技术资源 4 条（模板层）②CTA 再减薄 ③首页整体性 ④页脚贴底
 *   ⑤正文页加宽 ⑥资源中心加宽 ⑦页脚地址（渲染层）⑧后台特色产品勾选（已存在）⑨联系页减块（数据层）
 * ========================================================================== */

/* ---------- ② 首页 CTA 再减薄（419px → ~340px：内外边距+标题间距+正文折行数 三处一起收） ----------
 * ⚠️ 选择器**双重限定**（`[data-b01-main="home"] .pf-front__home-section.pf-front__home-cta`）：
 *    CTA 自身也是 `.pf-front__home-section`，下面 ③ 的板块色带规则与它同权重，
 *    只写 `.pf-front__home-cta`(0,1,0) 会被 ③ 的 56px 内边距盖掉（实测 h 卡在 390px）。
 */
[data-b01-main="home"] .pf-front__home-section.pf-front__home-cta { padding-block: var(--sp-6); }
@media (max-width: 767px) {
  [data-b01-main="home"] .pf-front__home-section.pf-front__home-cta { padding-block: var(--sp-7); }
}
.pf-front__home-cta .pf-front__section-title { margin-block-end: var(--sp-3); }
.pf-front__home-cta-text { max-inline-size: 72ch; margin-block-end: var(--sp-3); }
/* 正文段落放宽 ⇒ 少折一行（4 行 → 3 行），同时行高收到 1.5 */
.pf-front__home-cta-about { max-inline-size: 88ch; line-height: 1.5; margin-block-end: var(--sp-3); }
.pf-front__home-cta-contact { margin-block-end: var(--sp-4); }

/* ---------- ③ 首页整体性：全宽交替色带 + 统一节奏 ----------
 * 问题：各板块之间只有 112px 空白，没有「共同底色」，视觉上像 10 个互不相干的段落。
 * 做法（三条同时生效，视觉上把首页缝成一整张）：
 *   1) 每个板块自带**通栏出血**色带（`inset-inline: calc(50% - 50vw)`；因 .pf-front__main
 *      左右各留一个 gutter 且居中，该式恰好把色带铺到视口两边）；
 *   2) 白 / 极浅蓝（#f4f8fd）交替 ⇒ 相邻板块**永远不同色**，天然形成连续节奏；
 *      色带相邻贴合（板块外边距归 0、靠自身 padding 呼吸），不再有「断开的空白」；
 *   3) 所有板块共用同一套上下内边距（56px），标题→正文间距统一，节奏一致。
 * ⚠️ 色带按 `data-section` 显式指定（不依赖 DOM 顺序）：若日后调整板块顺序，
 *    只需改下面这一组选择器即可保持交替。
 * ⚠️ 出血用 50vw 会略超视口宽度（Windows 滚动条 ≈15px）⇒ 由 body{overflow-x:clip} 裁掉。
 */
:root { --band-tint: #eff5fc; }
[data-b01-main="home"] { padding-block: var(--sp-8) 0; }
[data-b01-main="home"] .pf-front__home-section {
  position: relative;
  margin-block-start: 0;
  padding-block: var(--sp-10);
}
/* ⚠️ 色带伪元素**不能**配 `isolation: isolate`：一旦板块自身成为层叠上下文，
 *    `z-index:-1` 的色带会画在「板块自己的背景」**之上**（CSS 绘制顺序：元素背景 → 负 z 子层），
 *    实测会把 CTA 的蓝色渐变整块盖成浅色、白字看不见。
 *    保持板块为「positioned + z-index:auto」（不成为层叠上下文）时，色带落在最近的层叠上下文
 *    的负层里，反而**在板块自身背景之下** ⇒ CTA 蓝底、trust 透明底都正常。 */
[data-b01-main="home"] .pf-front__home-section::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset-block: 0;
  inset-inline: calc(50% - 50vw);
  background: var(--surface);
}
/* ★ batch 63（2026-10-07）：改为**按顺序自动交替**，不再按 data-section 显式列举。
   `main[data-b01-main="home"]` 下全部板块都是**直接 `<section>` 子元素**，hero 为第 1 个：
     1 hero · 2 value-props · 3 product-entrances · 4 featured-products · 5 documents · … · 11 cta
   原显式组 = 第 3/5/7/9/11 位 ≡ `2n+3`（在 11 个板块时与本规则**完全等价**，等价性已实测）；
   删掉 documents 后（10 个板块）自动顺延为 3/5/7/9 位 ⇒ 交替不断档。
   ⚠️ 约束：首页板块必须保持为 main 的**直接 `<section>` 子元素**，否则 nth-of-type 会错位。 */
[data-b01-main="home"] > section:nth-of-type(2n+3)::before {
  background: var(--band-tint);
}
/* trust 原本自带底色 + 描边（色带里会变成一张“孤岛卡片”）⇒ 交还给色带统一呈现；
   但上下内边距必须与其它板块**一致**（否则 tinted 带里的内容会贴到相邻板块上）。 */
[data-b01-main="home"] .pf-front__home-section.pf-front__home-trust {
  background: transparent;
  border: 0;
  border-radius: 0;
  padding-block: var(--sp-10);
  padding-inline: 0;
}

/* ---------- ④ 页脚贴底（内容不足一屏时不再悬在页面中部） ----------
 * body 变纵向 flex：main 吃掉剩余高度 ⇒ 页脚永远压在视口底部（搜索页等短页面）。
 * `.pf-front__main` 自身有 `max-inline-size + margin-inline:auto`，在 flex 容器里会被
 * 交叉轴的 auto 外边距改写成「按内容收缩」⇒ 必须显式补 `inline-size: 100%` 才会
 * 与页头/页脚同宽（实测：漏掉本行时搜索页正文宽度会随内容缩水）。
 */
html { block-size: 100%; }
body {
  min-block-size: 100vh;
  display: flex;
  flex-direction: column;
  overflow-x: clip; /* 配合首页通栏色带（50vw 出血），避免出现横向滚动条 */
}
body > .pf-front__main { flex: 1 1 auto; inline-size: 100%; }

/* ---------- ⑤ 正文页（资源文章 / 新闻详情 / FAQ）内容区加宽：699px → 960px ----------
 * `.pf-front__article-single` 原为 72ch（中文≈699px），甲方反馈「内容部分扩展宽一些」。
 * 正文/问答块在 base 里已声明 `max-inline-size:none`，故放大容器即整体变宽。
 */
.pf-front__article-single { max-inline-size: min(100%, 60rem); }

/* ---------- ⑥ 资源中心：分类卡片铺满整行（3 张 3 等分）+ 引言放宽 ---------- */
.pf-front__resource-cat-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.pf-front__resources-index .pf-front__resources-intro { max-inline-size: 92ch; }
@media (max-width: 900px) {
  .pf-front__resource-cat-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 560px) {
  .pf-front__resource-cat-grid { grid-template-columns: 1fr; }
}

/* ---------- ⑦ 页脚联系地址行（render.js#buildFooterAddress 产出） ---------- */
.pf-front__footer-addr { color: var(--on-dark-muted); }

/* ---------- ⑤b FAQ 详情：与页面标题同题的答案块（不再重复出题） ---------- */
.pf-front__faq-answer {
  color: var(--text);
  font-size: var(--fs-lg);
  line-height: var(--lh-body);
  margin-block-end: var(--sp-4);
}

/* ==========================================================================
 * 第 3 批甲方微调（2026-09-23 傍晚）—— 7 项
 *   ①CTA 蓝条复现（根因在构建流程：CSS 改了但 HTML 未重建 ⇒ `?v=` 未变 + CSS 响应头
 *     `immutable` ⇒ 浏览器一直用旧 CSS。样式本身无需改；对策见 tools/bump-asset-version.cjs）
 *   ②页脚四栏收拢 + Contact ≤5 行   ③单页正文铺满   ④联系页两栏底部拉平
 *   ⑤首页「最新动态」4 条（模板层 home.js）  ⑥第三方实时对话（server/lib/livechat.js）
 * ========================================================================== */

/* ---------- ② 页脚：四栏均匀铺满整行（2026-09-23 第 5 批修订） ----------
 * 三轮演进，互为约束，改前先看清楚：
 *   原生    `repeat(4, minmax(0,1fr))` —— 每栏等宽 ~290px，而栏内文字只有 90~150px
 *           ⇒ 栏间留 ~200px 空洞（甲方第 3 批：「四栏靠近一些」）。
 *   第 3 批 `repeat(3, max-content) minmax(0,1fr)` —— 前三栏紧贴左侧、Contact 独吞余宽，
 *           但 Contact 的文字只吃到约一半宽度 ⇒ 四栏整体缩在左边、右侧大片留白
 *           （甲方第 5 批：「这四栏均匀分布，不是偏在左边，最右边可以和上面的蓝块平齐」）。
 *   本批    改用 flex + `justify-content: space-between`，同时满足两边要求：
 *           · 各栏按**内容宽**排布 ⇒ 栏内不产生空洞（保住第 3 批「靠近」的成果）；
 *           · 首栏贴容器左缘、末栏贴容器右缘，余量**等分**到 3 个栏间距
 *             ⇒ 四栏均匀铺满整行，末栏右缘与上方 CTA 蓝块右缘视觉平齐。
 *           · Contact 栏仍靠自身 54ch / 中文 46ch 限宽，保持「Tel+Email 一行 / 两条地址各两行」。
 * 容器口径：--container=1320、--gutter=32 ⇒ 内容区 92~1348，与 CTA 板块同一容器（不必再对齐）。
 * 视口窄于 1024 时回到 grid 的两列 / 单列，不受影响。
 */
@media (min-width: 1024px) {
  .pf-front__footer-inner {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: flex-start;
    column-gap: clamp(8px, 1.2vw, 56px);
  }
  .pf-front__footer-col { flex: 0 1 auto; min-inline-size: 0; }
  /* 版权行独占一行（等价于原 grid-column: 1 / -1，在 flex 下无效需显式声明） */
  .pf-front__footer-bottom { flex: 1 1 100%; }
  /* ★ 第 4 栏（Contact）**必须显式压宽**，不能靠「按内容宽」。
     原因（实测 1440／英文）：该栏内两条地址带 `text-wrap: balance`，浏览器的
     max-content 计算把它算成 672px，而实际排版只需要 466px(=54ch)。
     于是末栏虽然右缘贴到容器右缘，栏内文字右侧仍空 ~200px ⇒ 甲方看到的仍是
     「四栏偏在左边、没铺满」。显式设成地址真正要的宽度后：
       四栏总宽 111+177+96+466 = 850，余量 406 由 space-between 三等分 ⇒ 栏间距 135px，
       四栏从左缘 92 一直铺到右缘 1348，末栏文字贴右缘。
     中文页地址走 46ch（见下方 :lang(zh) 规则），故第 4 栏同步收窄到 46ch。 */
  .pf-front__footer-col:nth-child(4) { flex: 0 1 min(100%, 54ch); }
  :lang(zh) .pf-front__footer-col:nth-child(4) { flex: 0 1 min(100%, 46ch); }
}
/* 地址行：字号取 --fs-sm(14) 与 --fs-base(18) 之间的 16px —— 与栏内其它条目差别不刺眼，
   又能让「Office / Research Center」两条长地址各自只占一行（18px 时会多折一行 ⇒ 变 6 行）。 */
.pf-front__footer-addr { font-size: 1rem; line-height: 1.5; }

/* ---------- ③ 单页（关于我们 / 质量控制 / 服务…）正文铺满整行 ----------
 * `.pf-front__prose` 原 72ch（英文 ≈699px）贴在容器左侧，右侧空出近 560px
 * ⇒ 甲方「只有左边有内容，没有放在中间放两边扩展」。
 * 仅作用于 `page` 模板的**直属** prose（`.pf-front__page > .pf-front__prose`），
 * 不动联系页 / 解决方案页里被窄栏约束的同名块。
 */
[data-b01-main="page"] .pf-front__page > .pf-front__prose { max-inline-size: none; }

/* ---------- ④ 联系页：左右两栏底部拉平 ----------
 * 实测（1440 视口）：左栏（老站联系表格）底边 1603px、右栏（询盘表单）底边 1364px，
 * 相差 239px ⇒ 视觉上左表格拖出一截。
 * 做法：两栏 stretch 等高 + 右栏纵向 flex + Message 文本域吃掉余量，
 * 让「Send inquiry」紧贴栏底 ⇒ 与左侧表格底边落在同一条线。
 */
@media (min-width: 768px) {
  .pf-front__contact-layout { align-items: stretch; }
  .pf-front__contact-form-col { display: flex; flex-direction: column; }
  .pf-front__contact-form-col > .pf-front__form { display: flex; flex-direction: column; flex: 1 1 auto; }
  .pf-front__contact-form-col .pf-front__field:has(> .pf-front__textarea) { display: flex; flex-direction: column; flex: 1 1 auto; }
  .pf-front__contact-form-col .pf-front__textarea { flex: 1 1 auto; min-block-size: 148px; resize: vertical; }
}
/* 老站表格尾部的纯 &nbsp; 填充段已在数据层清掉；表尾外边距一并归零，
   否则「表格底边」比「栏底」高出一个 --sp-4，按钮就压不到同一条线上。 */
.pf-front__contact-info-col .pf-front__prose > table:last-child { margin-block-end: 0; }

/* ---------- ⑥ 第三方实时对话：本机/自研浮窗与第三方并存的兜底 ----------
 * 配置了第三方 provider 时，render.js 不再输出自研`.pf-front__chat`，
 * 这里再加一条保险：万一两者同时出现（如缓存中的旧 HTML），隐藏自研那个。 */
html[data-livechat] .pf-front__chat { display: none; }

/* ==========================================================================
 * 第 4 批甲方微调（2026-09-23 晚）—— 页脚 Contact 列重排（2 项）
 *   ① 电话 / 邮箱并排一行（原先各占一行 ⇒ 该栏 6 行）
 *   ② 两个地址各占两行：标签行（Office / Research Center）+ 地址行
 *   落点：render.js#buildFooter 的 contactLine / buildFooterAddress
 * × 与第 3 批②（四栏收拢 + Contact ≤5 行）同源：本批把该栏收敛到 5 行
 *   （1 行联系方式 + 2×2 行地址），并让地址字号回到与全栏一致的 16px。
 * ========================================================================== */

/* ---------- ① 电话 + 邮箱同行 ---------- */
.pf-front__footer-contact-line {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: var(--sp-6);   /* 两项之间留白；窄屏折行后由 row 间距接管 */
  row-gap: var(--sp-1);
}
.pf-front__footer-contact-item { display: inline-flex; align-items: baseline; gap: 6px; }
/* 标签取全亮色（与栏内条目同）、值取柔色 —— 与地址块「标签亮 / 内容柔」同一套层次。 */
.pf-front__footer-contact-label { color: var(--on-dark); }
.pf-front__footer-contact-value { color: var(--on-dark-muted); }
.pf-front__footer-list a.pf-front__footer-contact-value { color: var(--on-dark-muted); text-decoration: none; }
.pf-front__footer-list a.pf-front__footer-contact-value:hover { color: var(--surface); text-decoration: underline; text-underline-offset: 2px; }

/* ---------- ② 每条地址恒占两行 ----------
 * 结构 = 「标签 + 主体」同一文本流（render.js 里两个 span，中间 &nbsp; 绑定）。
 * 列宽放任不管时，地址在英文下要 ~640px、西语 ~700px（该栏俄语页只有 ~550px）
 * ⇒ 要么折成 3 行、要么把字号压到 14px 才勉强一行。两者都不好看。
 * 做法：**主动限宽** `54ch`（≈475px）把整块折成 2 行，再用 `text-wrap: balance`
 * 把断行点推到最均衡的逗号处 ⇒ 五语恒为两行、字号保持 1rem 与全栏统一。
 * 54ch 是**实测扫参**选出来的唯一解（1440 视口，逐值测各语行数）：
 *   46ch → es/ru 变 3 行；50ch → ru 仍 3 行；58ch 起 → 中文与阿语掉回 1 行；
 *   54ch → en/es/ru/ar 全部 2 行、中文 2+1 行（中文地址本身短，不强求）。
 * 窄屏（<560px）由 100% 接管，自然折行，不产生横向溢出。 */
.pf-front__footer-addr {
  max-inline-size: min(100%, 54ch);
  text-wrap: balance;
  font-size: 1rem;
  line-height: 1.5;
}
.pf-front__footer-addr-label { color: var(--on-dark); }
.pf-front__footer-addr-line { color: var(--on-dark-muted); }
/* 中文页脚：地址靠字与字之间换行，行宽需求比拉丁文小得多（30 余个全角字 ≈ 480px），
 * 用 54ch(475px) 时短的「研发中心」那条会掉回 1 行 ⇒ 中文单独收窄到 46ch(405px)，
 * 实测两条地址都稳定折成 2 行。:lang(zh) 只命中中文页（html lang="zh"）。 */
:lang(zh) .pf-front__footer-addr { max-inline-size: min(100%, 46ch); }
/* 软断行约束：地址主体被切成「逗号片段」，片段内不断行（片段间的一个空格是唯一断点）
 * ⇒ balance 只能在逗号后断行，不会出现「Hunan | Road」这种把路名劈开的断点。
 * 见 render.js#frameAddress（含 CJK 的地址不走这条路，保持自然折行）。 */
.pf-front__footer-addr-seg { white-space: nowrap; }
/* 两条地址之间比栏内默认 gap(8px) 稍松一点，避免上一条的地址行与下一条标签行粘连。 */
.pf-front__footer-addr + .pf-front__footer-addr { margin-block-start: 2px; }
/* 回退形态（值内无「标签:」结构）沿用旧样：整行一行、柔色、16px。 */
.pf-front__footer-addr--plain { max-inline-size: none; text-wrap: wrap; color: var(--on-dark-muted); }

/* ==========================================================================
 * 第 6 批甲方微调（2026-09-23 夜）—— 联系方式字体可读性（1 项）
 *   甲方：「邮箱 profirst.cn，字母 p 看不清楚」。
 *
 *   根因（CDP `CSS.getPlatformFontsForNode` 实测，非推测）：
 *     render.js / templates/home.js 用 `keepLtr()` 给**所有**拉丁串统一套
 *     `<span dir="ltr" class="keep-ltr">`，而 `.keep-ltr` 自带
 *       `font-family: var(--font-mono)` = ui-monospace → … → Consolas → monospace
 *     ⇒ 电话与邮箱被**顺手**渲染成了等宽字体。中文页实测：
 *       页头邮箱 span → Consolas（16 glyphs）   页头「邮箱」标签 → Noto Sans SC
 *       页头电话 span → Consolas（15 glyphs）   页脚地址行       → Noto Sans SC
 *     即「同一行里标签是人文无衬线粗体、值是等宽细体」。Consolas 的 `p`
 *     上碗小、下伸部细长且笔画最轻，18px 浅字压深蓝底（#1a4d93）时最先糊掉 ——
 *     甲方看到的正是这个字。字体本身也不是设计选项，是 keep-ltr 的副作用。
 *
 *   处理：**联系方式不是代码串**（CAS / SKU / 型号才是），把三处联系方式
 *     （页头信息条 / 首页 CTA 联系块 / 页脚 Contact 列，外加仍在线上的自研浮窗）
 *     回退到**正文字体**；并加 `tabular-nums` 让电话数字等宽（不跳动）。
 *     `dir=ltr` + `unicode-bidi:isolate` 的 RTL 隔离职责由 `.keep-ltr` 本体承担，
 *     与字体无关，阿语页不受影响。
 *   ★ 与既有先例同一手法：`.pf-front__hero-title / .pf-front__copyright .keep-ltr
 *     { font-family: inherit }`（同名文字本就不该走等宽）。
 *   ★ 只加宽不改行：`letter-spacing` 0.01em 让 18px 下的 `i/f/p` 字腔不粘连，
 *     量级 0.18px/字，对栏宽影响 <1%（实测见 docs/qa/2026-09-23-email-legibility）。
 * ========================================================================== */
.pf-front__header-contact .keep-ltr,
.pf-front__home-cta-contact .keep-ltr,
.pf-front__footer-contact-line .keep-ltr,
.pf-front__chat-value.keep-ltr {
  font-family: inherit;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
}

/* ============================================================================
 * 第 7 批 UI 微调（2026-09-24 甲方截图批）—— 全部为**覆写层**，不改上方既有规则
 *   ① 页头顶端留空 + 两行之间的留空
 *   ④ 「为什么选择 PROFIRST」标题下加一行副标题
 * ★ 第 7 批原 ⑤「首页特色产品 8 卡网格 → 4 个产品目录轮播」已于**第 9 批回退**
 *   （甲方澄清轮播该放在产品栏目页）：首页模板恢复原样，相关 CSS 一并移除；
 *   轮播改落在产品栏目页 —— 见本文件末尾 ⑤「产品栏目页『全部产品』轮播」。
 * ==========================================================================*/

/* ---------- ① 页头留白 ----------
 * 甲方原话：「顶端留空多些，两行之间留空多一点」。
 * 实测基线（1440/en）：.pf-front__header-top 高 104px（padding 12/12）、
 *   .pf-front__nav-row 高 61px（padding 0/0）、两行净空隙 0px、页头总高 167px。
 * ★ 页头是 position:sticky ⇒ 加高会直接吃掉内容视口，故桌面加足、移动端克制。 */
@media (min-width: 768px) {
  .pf-front__header-top { padding-block-start: var(--sp-6); }  /* 12 → 24（顶端 +12px） */
  .pf-front__nav-row { padding-block-start: var(--sp-3); }     /*  0 → 12（两行之间 +12px） */
}
@media (max-width: 767px) {
  .pf-front__header-top { padding-block-start: var(--sp-4); }  /* 12 → 16（顶端 +4px） */
  .pf-front__nav-row { padding-block-start: var(--sp-2); }     /*  0 →  8（两行之间 +8px） */
}

/* ---------- ④ 板块副标题（h2 之下的一行品牌承诺） ----------
 * ★ 2026-09-24 甲方追加：「字太小，太不醒目！」。
 *   加强前基线：20px(`--fs-lg`) / `--text-muted`(#5b6b85 灰蓝) / 字重 400
 *   ⇒ 视觉重量**低于**正文卡片标题，被上方 h2 完全压住。
 *   加强（四管齐下，仍不压过 h2 的 24~28px）：
 *     ① 字号 20px → `clamp(21px, 1.65vw, 24px)`（1440 视口实测 23.76px）；
 *     ② 颜色 灰蓝 muted → 正文深色 `--text`(#1a2332)；
 *     ③ 字重 400 → 600，并切到标题字体 `--font-heading`；
 *     ④ 加**浅品牌蓝底 + 左侧 5px 品牌条**（与 h2 的 `::before` 竖条呼应而不重复——
 *        h2 是「裸竖条」，这里是「色块条」，层次分明）。
 *   ★ 一律用**逻辑属性**（`border-inline-start` / `margin-block` / `padding-inline`）
 *     ⇒ ar(RTL) 下左侧条自动贴到文字起点（右侧），六语同构。
 *   ★ h2 自带 margin-block-end: 24px ⇒ 上边距收回至净 12px（色块需比纯文字多留一点气口），
 *     色块之下留 32px 到内容块。
 *
 * ★ 2026-09-24（第 10 批）甲方追加：「第二行拉宽一点，和第三行的内容合为一行」。
 *   实测基线（en@1440，视口 1440 / 内容区 1256 / 字号 23.76px）：
 *     色块外框 949.75px（被 `max-inline-size: 72ch` 卡住）、内文可用 901.75px；
 *     而整句 `We ship adjuvants that have been tested, matched, and de-risked before
 *     they leave our door!` **排成一行需要 1004px** ⇒ 放不下才折成两行
 *     （行1 到 `…they leave`，行2 只剩 `our door!`）。
 *   处理：**解除 72ch 上限**，改用「一行能装下」的自适应上限：
 *     `max-inline-size: min(100%, 1060px)` —— 1060 = 一行实测 1004px + 左右内边距 48px + 余量 8px。
 *     ★ 用 `min(100%, …)` 而非写死宽度：窄屏（≤1060+容器边距）自动退化为**满宽**，
 *       不会横向溢出；≥1060 时封顶，避免色块无谓地铺满超宽屏。
 *     ★ **不降字号**（甲方明确要「拉宽」，不是「缩小」），故 23.76px 保持不变。
 *   ★ 六语实测（1440/1024/390 三视口）见 `docs/qa/2026-09-24-ui10/`：
 *        en / es / pt 拉丁语系在 ≥1024 稳定**单行**；
 *        zh（中文）本就 1~2 行；ru（西里尔，字符更宽）与 ar（RTL）在 1440 单行、
 *        1024 起自然回落到两行（属正常折行，非溢出）。
 *   ★ `text-wrap: pretty` 保留 ⇒ 万一必须折行，也会尽量让末行不那么孤。 */
.pf-front__section-sub {
  margin-block: calc(var(--sp-3) - var(--sp-6)) var(--sp-7);
  font-family: var(--font-heading);
  font-size: clamp(1.3125rem, 1.65vw, 1.5rem);   /* 21px → 24px；第 10 批**未降** */
  font-weight: 600;
  line-height: 1.42;
  color: var(--text);
  background: #eaf1fb;                            /* 浅品牌蓝（与 --on-dark 同族，浅底深字） */
  border-inline-start: 5px solid var(--brand-green);
  padding: var(--sp-4) var(--sp-6);
  border-radius: var(--radius);
  max-inline-size: min(100%, 1060px);            /* ★ 第 10 批：72ch → 一行能装下（窄屏满宽、超宽屏封顶） */
  text-wrap: pretty;
}

/* ---------- ⑤ 产品栏目页「全部产品」分页网格（第 17 批；第 9 批那版轮播已下线） ----------
 * ★ 口径变更（甲方 2026-09-27 拍板「取消轮播 → 网格 + 分页器」）：
 *   审计③ 原话「'8 per screen, rotating automatically' 的设定对 B2B 产品目录并不友好。
 *   专业用户需要按照自己的节奏浏览、对比和查找。建议取消自动轮播，改用常规的网格布局
 *   配合分页器 (Pagination)，或『加载更多 (Load More)』按钮。」
 *   ⇒ 自动轮播（30s）、圆点、上下屏全部移除；改为**编号分页器**，每页 12 个（4 列 × 3 排）。
 *   第 9 批的 `.pf-front__catalog-carousel / -slides / -slide / -controls / -dots / -dot /
 *   -live` 一套选择器已无模板产出，随本批下线。
 * ★ 结构：`ssg/templates/product.js#catalogPager` 产出、`assets/front.js` 第 3 块驱动。
 * ==========================================================================*/
/* 换页后回滚到网格顶部（skip-link 与分页器都指向 #catalog-list） */
.pf-front__catalog-pager-wrap { scroll-margin-block-start: var(--sp-6); }
.pf-front__catalog-status { margin: 0 0 var(--sp-4); font-size: var(--fs-base); color: var(--text); }

/* ★ 页容器**叠放**（grid-area:1/1）⇒ 容器高度 = 最高的一页，换页时**不跳版**。
 * ★ 非当前页用 `visibility:hidden` + `content-visibility:hidden`（**不是** display:none）：
 *   ① DOM 里 129 条产品链接全部保留 ⇒ 爬虫一次性可见（内部链接不回退）；
 *   ② `content-visibility:hidden` 跳过非当前页的渲染 ⇒ **不会一次性拉 129 张产品图**
 *      （实测：只有当前页的 12 张会发请求）。
 * ★ 不支持 `content-visibility` 的老浏览器退化为「图片按 lazy 规则加载」，功能不受影响。
 * ★★ **绝不可改成 `display:none`**：那会让非当前页的 117 条内链从可访问性树与爬虫视野消失。
 * ★ 无 JS：模板内嵌 `<noscript><style>` 把 11 页全部展开（CSP `style-src` 允许内联样式；
 *   `script-src 'self'` 禁止内联脚本，故不能用内联 <script> 挂 html 类名）。 */
.pf-front__catalog-pages {
  display: grid;
  margin: 0;
  padding: 0;
  list-style: none;
}
.pf-front__catalog-page {
  grid-area: 1 / 1;
  margin: 0;
  list-style: none;
  opacity: 0;
  visibility: hidden;
  content-visibility: hidden;
  transition: opacity 0.3s ease;
}
.pf-front__catalog-page.is-active {
  opacity: 1;
  visibility: visible;
  content-visibility: visible;
}

/* 右侧栏被左栏挤窄 ⇒ 列数与分类页**分开定义**，且**封顶 3 列**。
 * ★ 第 17 批实测（docs/qa/2026-09-27-products-catalog/tune-title-fit.cjs）：
 *   1440 屏容器 1256px − 侧栏 256 − 间距 32 ⇒ 主栏仅 960px。若仍用 4 列，
 *   卡片只有 **222px**，而卡片标题是 `--fs-xl`(22px) ⇒ 每行 ~14 字符，
 *   129 个标题里 **32 个被截断**（最长 78 字符溢出 83px）；
 *   改 3 列后卡片 **304px**，截断降到 **8 个**（↓75%），1280 屏 43 → 14。
 *   ★ 之所以**不动标题字号**：22px 是第 129 批甲方要求的全局上调（`--fs-xl`），
 *     为一次版面改动去回调甲方已拍板的字号，属越权；改列数即可达成同一目标。
 *   ★ 高屏（如 1920）也不放 4 列：容器封顶 1440px ⇒ 主栏 1088px，4 列仅 260px 又会截断。
 * 分类页（无左栏）不受影响，仍走 `.pf-front__grid--products` 的 1/2/4 列。 */
.pf-front__catalog-main .pf-front__grid--products { grid-template-columns: 1fr; }
@media (min-width: 768px) {
  .pf-front__catalog-main .pf-front__grid--products { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1024px) {
  .pf-front__catalog-main .pf-front__grid--products { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* 分页器：‹ 1 2 3 … n › 居中一行，静态流式布局（不覆盖卡片，与 Hero 轮播的浮层不同） */
.pf-front__catalog-pager {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  margin-block-start: var(--sp-10);
}
.pf-front__catalog-nums { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: var(--sp-1); }
.pf-front__catalog-num {
  min-inline-size: 2.5rem;
  block-size: 2.5rem;
  padding: 0 var(--sp-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  font-family: var(--font-heading);
  font-size: var(--fs-base);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition: background-color 0.18s ease, color 0.18s ease, border-color 0.18s ease;
}
.pf-front__catalog-num:hover { border-color: var(--brand-primary); color: var(--brand-primary); }
.pf-front__catalog-num.is-current { background: var(--brand-primary); border-color: var(--brand-primary); color: var(--surface); }
.pf-front__catalog-num:focus-visible { outline: 2px solid var(--brand-green); outline-offset: 2px; }
.pf-front__catalog-prev,
.pf-front__catalog-next {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  inline-size: var(--sp-9);
  block-size: var(--sp-9);
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: var(--brand-primary);
  cursor: pointer;
  transition: background-color 0.18s ease, color 0.18s ease, border-color 0.18s ease;
}
.pf-front__catalog-prev:hover:not(:disabled),
.pf-front__catalog-next:hover:not(:disabled) { background: var(--brand-primary); border-color: var(--brand-primary); color: var(--surface); }
.pf-front__catalog-prev:disabled,
.pf-front__catalog-next:disabled { opacity: 0.4; cursor: not-allowed; }
.pf-front__catalog-prev:focus-visible,
.pf-front__catalog-next:focus-visible { outline: 2px solid var(--brand-green); outline-offset: 2px; }
.pf-front__catalog-prev svg,
.pf-front__catalog-next svg { inline-size: var(--sp-5); block-size: var(--sp-5); }
[dir="rtl"] .pf-front__catalog-prev svg,
[dir="rtl"] .pf-front__catalog-next svg { transform: scaleX(-1); }

/* 尊重「减少动态效果」：去掉换页过渡（**本批已无自动切换**，故此项只关过渡） */
@media (prefers-reduced-motion: reduce) {
  .pf-front__catalog-page { transition: none; }
}

/* ---------- ⑥ Hero 播放窗口：YouTube「网络不可达」兜底面板（第 9 批） ----------
 * 甲方口径「优先播本地 mp4、YouTube 只作海外增强」。该条**只有 YouTube**（频道视频集）
 * 且当前网络访问不到（国内出口）时，front.js 看门狗 3 秒未加载就把播放器换成
 * 「封面 + 一行说明 + 在 YouTube 上打开」——不再留一块永远转圈的黑窗口。
 * 视觉沿用既有 `.pf-front__hero-open` 深蓝底白字条，新增文案条落在它上方。 */
.pf-front__hero-offline-note {
  position: absolute;
  inset-inline: 0;
  inset-block-end: calc(var(--sp-2) + 3.5rem);
  z-index: 3;
  margin: 0;
  padding: var(--sp-2) var(--sp-4);
  background: rgba(10, 36, 99, 0.82);
  color: var(--surface);
  font-size: var(--fs-sm);
  line-height: 1.4;
  text-align: center;
}

/* =====================================================================
 * 第 13 批（2026-09-26）—— 品牌强调色激活 + 主导航去蓝
 *
 * 【甲方反馈】设计审计意见两条：
 *   ① 视觉头重脚轻：最顶部工具条 / 中部主导航 / 下方 Hero **三块全是大面积深蓝**，
 *      区块之间没有过渡与留白，缺「呼吸感」；
 *   ② 缺核心强调色：交互元素（当前选中语言、CTA 按钮）**只用「稍亮一点的蓝」**，
 *      首屏没有一个能在视觉上跳脱出来、引导点击的对比色。
 *   建议：提取 Logo 里的亮绿作强调色；主导航改白底（或极浅灰）+ 深蓝字。
 *
 * 【实测复现】（1440×900 / en，见 docs/qa/2026-09-26-brand-accent/recon.json）
 *   · 页头 #1a4d93，高 191px ＝ 工具行 116 + 导航行 73，**同色 ⇒ 视觉上是一整块**；
 *   · 88px 缝隙 → Hero 渐变 #14418a→#19539f，高 423px；
 *   · ⇒ 首屏 900px 里 601px 是蓝（2/3），三块深蓝首尾相连；
 *   · 导航当前项 / 语言当前项 / Hero 主按钮 **三者同色 #2670a8**（＝--accent-fill）。
 *
 * 【处置①】主导航去蓝
 *   `.pf-front__nav-row` 与其内的联系条改白底、深蓝字 ⇒ 在「工具条」与「Hero」
 *   两块蓝之间插入一条白带，页头由「一整块蓝」变成「蓝条 + 白条」。
 *
 * 【处置②】关键操作按钮改品牌绿
 *   绿色取自 logo.png 的球体（脚本采样：核心饱和绿众数 #08a040，高饱和样本 #3e92cc，
 *   高光渐至 #a0e060）⇒ 取 --brand-accent: #3e92cc（**Logo 原色，不做主观偏移**）。
 *
 * ★★ 绿底上的文字色是**算出来的，不是挑的**（对比度矩阵见同目录 palette 实测输出）：
 *      绿 #077e32 + 白字 5.20 ✓ ｜ 但该绿压在 Hero 蓝(#14418a) 上只有 1.88 ✗ ⇒ 按钮糊进背景
 *      绿 #08913a + 白字 4.10 ✗ ｜ Hero 蓝上 2.38
 *      绿 #3e92cc + 白字 3.24 ✗ ｜ Hero 蓝上 3.01 ✓（≥3:1 UI 组件门槛）
 *      绿 #3e92cc + 深字 #06213f = **4.99 ✓** ｜ Hero 蓝上 3.01 ✓
 *   ⇒ 「白字够 4.5」与「在深蓝底上跳得出来」在同一支绿上**互斥**：要过 4.5 必须压暗，
 *     一压暗在蓝底上就只剩 1.9:1。唯一两组门槛同时通过的组合是
 *     **Logo 原色 #3e92cc + 深墨蓝字 --on-green**（同 Spotify 绿底深字的路子）。
 *   ★ 若坚持「白字」，只能二选一：① 接受按钮在 Hero 上对比掉到 3.24（轮廓仍可见）；
 *     或 ② 换一支非 Logo 的深绿（在蓝底上会糊）。不能既要又要。
 * ------------------------------------------------------------------- */
:root {
  --brand-green: #08a542;        /* logo.png 球体核心绿 */
  --brand-green-hover: #0b9440;
  --on-green: #06213f;           /* 绿底文字：on #08a542 = 4.99:1 ✓ */
}

/* ---------- ① 主导航 → 白底深蓝字（断开三块蓝） ---------- */
.pf-front__nav-row {
  background: var(--surface);
  border-block-start-color: transparent;   /* 紧邻上方蓝条，硬边已足够，不再叠一条浅线 */
}
.pf-front__nav-link { color: var(--brand-primary); border-inline-end-color: var(--border); }
.pf-front__nav-link:first-child { border-inline-start-color: var(--border); }
.pf-front__nav-link:hover { background: var(--surface-alt); color: var(--brand-primary); }
.pf-front__nav-link[aria-current="page"] {
  background: transparent;
  color: var(--brand-primary);
  border-block-end-color: var(--brand-green);
}
/* 页头底线原为 2px 品牌蓝；改浅灰发丝线。绿**不放在整条底线**上，
   否则会与「当前项」的绿下划线连成一体、当前页标记失效。 */
.pf-front__header { border-block-end-color: var(--border); }

/* 联系条原为「深底浅字」，随导航行一并翻转为「白底深字」 */
.pf-front__header-contact { color: var(--text-muted); }   /* 容器兜底：电话号是 <li> 里的裸文本 */
.pf-front__header-contact-item { color: var(--text-muted); }
.pf-front__header-contact-label { color: var(--brand-primary); }
.pf-front__header-contact a { color: var(--text-muted); }
.pf-front__header-contact a:hover { color: var(--brand-primary); text-decoration: underline; }

/* 移动端抽屉与桌面共用同一容器 ⇒ 白底下分隔线须从 white-16% 换成看得见的浅灰 */
@media (max-width: 767px) {
  .pf-front__nav-link { border-block-end-color: var(--border); }
  .pf-front__header-contact { border-block-start-color: var(--border); }
}

/* ---------- ② 关键操作按钮 → 品牌绿 ---------- */
.pf-front__btn--primary { background: var(--brand-green); color: var(--on-green); }
.pf-front__btn--primary:hover { background: var(--brand-green-hover); color: var(--on-green); }
.pf-front__home-cta .pf-front__btn--primary { background: var(--brand-green); color: var(--on-green); }
.pf-front__home-cta .pf-front__btn--primary:hover { background: var(--brand-green-hover); color: var(--on-green); }

/* ============================================================================
   ★ 2026-09-26 第 14 批｜新闻索引页（/news/）卡片重构
   —— 甲方转来外部审计意见 7 条，逐条落地（仅本批，勿与首页 latest-news 混淆）：
     ① 日期全部相同（逻辑缺陷）→ **数据层**修（`tools/apply-news-dates.cjs`），与 CSS 无关
     ② 整卡可点              → 标题链接用 `::after` 拉伸成覆盖层（见下方 .card-title a::after）
     ③ 摘要 2~3 行 + 等高    → `-webkit-line-clamp` + 固定最小行高 + 卡片 flex 列布局
     ④ 增加缩略图            → 模板已加 `.pf-front__news-cover`（缺图走品牌渐变占位）
     ⑤ 去蓝实线边框          → 默认 `border-color: transparent`，hover 只加深柔和投影。
                               ★ 审计看到的「明显的蓝色实线边框」其实是 **hover 态**：原规则把
                                 border 染成 `--brand-accent`(#3e92cc 科技蓝)；普通态本就是浅灰
                                 `--border`(#e3e8ef)。故修法是「hover 不再变色」+「去边框存在感」。
     ⑥ 标题字号/字重下调      → 22px→20px、字重 700→650，卡片内留白加大（缓解拥挤感）
     ⑦ 宽屏改 3 列           → ≥1024px：4 列 → 3 列（卡内多了图，每列更宽、更透气）
   ============================================================================ */

/* ⑤ 卡片外观：白卡 + 柔和投影，淡化「实线边框」 */
.pf-front__news .pf-front__news-card {
  position: relative;              /* ② 整卡覆盖层的定位父级 */
  padding: 0;                      /* 图区要贴边 ⇒ 内边距移交 .pf-front__news-body */
  gap: 0;
  overflow: hidden;                /* 让卡片圆角把图区一并裁掉 */
  border-color: transparent;
  transition: transform .22s ease, box-shadow .22s ease;
}
.pf-front__news .pf-front__news-card:hover,
.pf-front__news .pf-front__news-card:focus-within {
  transform: translateY(-3px);
  box-shadow: 0 12px 28px rgba(10, 36, 99, .14);
  border-color: transparent;       /* ★ 关键：hover 不再变成蓝框 */
}

/* ④ 缩略图区：固定 16:9 ⇒「有图 / 无图」卡片高度完全一致 */
.pf-front__news-cover {
  position: relative;
  aspect-ratio: 16 / 9;
  inline-size: 100%;
  overflow: hidden;
  background: var(--surface-sunken);
}
.pf-front__news-cover img {
  display: block;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  transition: transform .4s ease;
}
.pf-front__news-card:hover .pf-front__news-cover img { transform: scale(1.045); }

/* 缺图占位：品牌深蓝 → Logo 绿渐变（呼应第 13 批强调色）+ 一枚淡光斑 */
.pf-front__news-cover--placeholder {
  background:
    radial-gradient(115% 120% at 14% 20%,
      rgba(8, 165, 66, .62) 0%, rgba(8, 165, 66, 0) 58%),
    linear-gradient(135deg, #0a2463 0%, #14418a 58%, #1d5cab 100%);
}
.pf-front__news-cover--placeholder::after {
  content: '';
  position: absolute;
  inset-inline-end: 10%;
  inset-block-end: 12%;
  inline-size: 30%;
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  background: rgba(255, 255, 255, .09);
}

/* 正文容器：承接原卡片内边距（⑥ 留白略加大） */
.pf-front__news-body {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  gap: var(--sp-3);
  padding: var(--sp-5) var(--sp-5) var(--sp-6);
}

/* ⑥ 标题：字号降一档、字重减轻；③ 固定最多/最少 2 行 ⇒ 同排标题基线对齐 */
.pf-front__news .pf-front__card-title {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  min-block-size: calc(2 * 1.35em);
  font-size: 1.25rem;              /* 原 --fs-xl = 22px → 20px */
  font-weight: 650;
  line-height: 1.35;
  letter-spacing: -.003em;
  margin-block: 0;
}

/* ③ 摘要：固定 3 行（多了省略、少了留白）⇒ 同排卡片高度绝对对齐 */
.pf-front__news .pf-front__card-desc {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  min-block-size: calc(3 * 1.6em);
  margin: 0;
  line-height: 1.6;
  color: var(--text-muted);
}

/* ② 整卡可点：标题链接拉伸铺满整张卡（图区 + 日期 + 标题 + 摘要都进入点击区） */
.pf-front__news .pf-front__card-title a::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
}
/* 「阅读更多」浮在覆盖层之上仍可单独点；贴底 ⇒ 同排卡片链接基线对齐 */
.pf-front__news .pf-front__card-link {
  position: relative;
  z-index: 2;
  margin-block-start: auto;
  align-self: flex-start;
}

/* ⑦ 宽屏 3 列（原 4 列）；≥560px 双列与移动端单列保持不变 */
@media (min-width: 1024px) {
  .pf-front__news .pf-front__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}



/* ============================================================================
 * 第 15 批 · 资源中心板块改造（甲方 2026-09-26 转来的外部视觉审计，7 条）
 * ----------------------------------------------------------------------------
 * 审计 7 条 → 本文末覆写层落点（结构改动见 ssg/templates/resource.js）：
 *   ① 全局搜索 + 主题筛选  → .pf-front__res-tools / -search / -filter
 *   ② 列表信息密度         → .pf-front__res-summary / -read
 *   ③ 面包屑「清晰」        → .pf-front__crumbs 强化（分隔符 › ／当前项加深加粗）
 *                            ★ 面包屑本就全站存在（render.js#buildBreadcrumb），
 *                              审计的真实问题是**视觉层级不清**，故只改样式、不新建。
 *   ④ 分类卡图标           → .pf-front__resource-cat-icon
 *   ⑤ 列表缩略图           → .pf-front__res-thumb（无封面走品牌渐变占位）
 *   ⑥ 日期调小调灰 + 标题焦点 → .pf-front__res-date（14px + --text-muted）／标题 22px 700 深蓝
 *                            ★ 与 #135/#145「muted→text、加大字号」方向相反，甲方已确认回调
 *   ⑦ Hover 微动效         → 分类卡上浮加深阴影 + 标题变色；列表项标题变色 + 缩略图微缩放
 * ★ 全部选择器以 .pf-front__resources-index 或新类名限定 ⇒ 不波及产品/新闻/首页
 *   （那些页面同样使用 .pf-front__link-list）。
 * ==========================================================================*/

/* ---------- ③ 面包屑：让「层级」一眼可见 ---------- */
/* 原样式：14px + --text-muted + 浅灰底 + `/` 分隔 + 当前项与链接**同色同字重**
   ⇒ 存在但读不出层级（审计原话「应提供清晰的面包屑导航」）。 */
.pf-front__crumbs { padding-block: var(--sp-4); }
.pf-front__crumbs ol { font-size: var(--fs-sm); gap: var(--sp-1); align-items: center; }
.pf-front__crumb a { color: var(--text-muted); font-weight: 500; }
.pf-front__crumb a:hover { color: var(--brand-green); text-decoration: underline; text-underline-offset: 2px; }
/* 分隔符：`/` → `›`（指向明确的层级箭头），并给它一点存在感 */
.pf-front__crumb + .pf-front__crumb::before {
  content: '›';
  margin-inline-end: var(--sp-1);
  color: var(--border-strong);
  font-weight: 700;
}
/* 当前项：加深 + 加粗 ⇒ 与可点链接形成明确区分 */
.pf-front__crumb:last-child span { color: var(--brand-primary); font-weight: 700; }
/* RTL（阿语）：箭头方向随书写方向翻转 */
[dir="rtl"] .pf-front__crumb + .pf-front__crumb::before { content: '‹'; }

/* ---------- ① 工具栏：搜索框 + 主题筛选条 ---------- */
.pf-front__res-tools { display: grid; gap: var(--sp-4); margin-block: var(--sp-5) var(--sp-8); }
.pf-front__res-search { display: flex; flex-wrap: wrap; gap: var(--sp-2); max-inline-size: 34rem; margin: 0; }
.pf-front__res-search-input {
  flex: 1 1 12rem;
  min-inline-size: 0;
  padding: var(--sp-3) var(--sp-4);
  font-family: inherit;
  font-size: var(--fs-base);
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  transition: border-color 0.18s ease, box-shadow 0.18s ease;
}
.pf-front__res-search-input::placeholder { color: var(--text-muted); }
.pf-front__res-search-input:focus {
  outline: none;
  border-color: var(--brand-green);
  box-shadow: 0 0 0 var(--sp-1) rgba(62, 146, 204, 0.2);
}
/* 提交按钮沿用第 13 批确立的「Logo 绿 + 深墨蓝字」（白字在绿上仅 3.24 不达标） */
.pf-front__res-search-btn {
  flex: 0 0 auto;
  padding: var(--sp-3) var(--sp-6);
  font-family: inherit;
  font-size: var(--fs-base);
  font-weight: 600;
  color: var(--on-green);
  background: var(--brand-green);
  border: 1px solid var(--brand-green);
  border-radius: var(--radius);
  cursor: pointer;
  transition: background 0.18s ease;
}
.pf-front__res-search-btn:hover { background: var(--brand-green-hover); border-color: var(--brand-green-hover); }
.pf-front__res-filterbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3); }
.pf-front__res-filter-label { font-size: var(--fs-sm); font-weight: 600; color: var(--text-muted); }
.pf-front__res-filter-row { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.pf-front__res-filter {
  padding: var(--sp-2) var(--sp-4);
  font-family: inherit;
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition: background 0.18s ease, border-color 0.18s ease, color 0.18s ease;
}
.pf-front__res-filter:hover { border-color: var(--brand-green); color: var(--brand-green); }
.pf-front__res-filter.is-active {
  color: var(--surface);
  background: var(--brand-primary);
  border-color: var(--brand-primary);
}
.pf-front__res-status { margin: 0; font-size: var(--fs-sm); color: var(--text-muted); }
.pf-front__res-status:empty { display: none; }

/* ---------- ④ 分类卡图标 + ⑦ 分类卡动效增强 ---------- */
.pf-front__resource-cat-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 46px;
  block-size: 46px;
  margin-block-end: var(--sp-1);
  color: var(--brand-green);
  background: var(--surface-sunken);
  border-radius: var(--radius-sm);
  transition: background 0.2s ease, color 0.2s ease, transform 0.2s ease;
}
/* 分类卡：原 hover 会把边框染成科技蓝（同类蓝框问题已在第 14 批新闻卡上定型为「不再变色」）
   ⇒ 改为「上浮 3px + 更深阴影 + 图标反白」，边界靠阴影表达而非描边。 */
.pf-front__resources-index .pf-front__resource-cat-link:hover {
  transform: translateY(-3px);
  box-shadow: 0 14px 30px rgba(10, 36, 99, 0.13);
  border-color: var(--border);
  text-decoration: none;
}
.pf-front__resources-index .pf-front__resource-cat-link:hover .pf-front__resource-cat-icon {
  color: var(--surface);
  background: var(--brand-primary);
  transform: translateY(-1px);
}
.pf-front__resources-index .pf-front__resource-cat-link:hover .pf-front__resource-cat-name { color: var(--brand-green); }

/* ---------- ⑤ 列表：图文混排（缩略图 + 标题 + 摘要 + 元信息） ---------- */
/* 覆盖基础 .pf-front__link-list li（虚线分隔 + 20px 字号），改为实线细分割的行式布局 */
.pf-front__resources-index .pf-front__link-list.pf-front__res-list { gap: 0; }
.pf-front__resources-index .pf-front__link-list.pf-front__res-list > li.pf-front__res-item {
  display: grid;
  grid-template-columns: 152px minmax(0, 1fr);
  gap: var(--sp-6);
  align-items: start;
  padding-block: var(--sp-6);
  font-size: var(--fs-base);
  border-block-end: 1px solid var(--border);
}
/* ★ 必须显式声明：li 被设为 grid 后，UA 的 [hidden]{display:none} 会被作者样式覆盖。
   ★★ 但光写 `.pf-front__res-item[hidden]` 也不够 —— 那是 (0,2,0)，会被上面主规则的
       (0,4,1)（`.pf-front__resources-index .pf-front__link-list.pf-front__res-list > li.pf-front__res-item`）
       反压回去 ⇒ 隐藏项仍算出 display:grid（第 15 批实测踩到）。
       ⇒ 必须带**完整选择器链**把特异度提到 (0,5,1)。 */
.pf-front__res-item[hidden] { display: none; }
.pf-front__resources-index .pf-front__link-list.pf-front__res-list > li.pf-front__res-item[hidden] { display: none; }
.pf-front__resources-index .pf-front__link-list.pf-front__res-list > li.pf-front__res-item:first-child { padding-block-start: 0; }
.pf-front__resources-index .pf-front__link-list.pf-front__res-list > li.pf-front__res-item:last-child {
  padding-block-end: 0;
  border-block-end: 0;
}

.pf-front__res-thumb {
  position: relative;
  display: block;
  inline-size: 100%;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--surface-sunken);
  border-radius: var(--radius);
}
.pf-front__res-thumb img {
  display: block;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  transition: transform 0.4s ease;
}
/* 无封面 → 品牌色渐变占位（与第 14 批新闻卡同一手法，不引外部图、不破图） */
.pf-front__res-thumb-ph {
  position: relative;
  display: block;
  inline-size: 100%;
  block-size: 100%;
  background:
    radial-gradient(115% 120% at 14% 20%, rgba(8, 165, 66, 0.62) 0%, rgba(8, 165, 66, 0) 58%),
    linear-gradient(135deg, #0a2463 0%, #14418a 58%, #1d5cab 100%);
}
.pf-front__res-thumb-ph::after {
  content: '';
  position: absolute;
  inset-inline-end: 10%;
  inset-block-end: 12%;
  inline-size: 30%;
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.09);
}

.pf-front__res-body { display: flex; flex-direction: column; gap: var(--sp-2); min-inline-size: 0; }
/* ⑥ 标题：深蓝 + 700（视觉焦点），日期退到 14px 灰 ⇒ 层级拉开 */
.pf-front__res-title {
  margin: 0;
  font-family: var(--font-heading);
  font-size: var(--fs-xl);
  font-weight: 700;
  line-height: 1.35;
  letter-spacing: -0.003em;
}
.pf-front__res-title a { color: var(--brand-primary); font-weight: 700; text-decoration: none; }
.pf-front__res-title a:focus-visible { outline: 2px solid var(--brand-green); outline-offset: 2px; }
/* ② 摘要：最多 2 行（超出省略），保证同屏各行高度稳定 */
.pf-front__res-summary {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  margin: 0;
  font-size: var(--fs-base);
  line-height: 1.6;
  color: var(--text-muted);
}
.pf-front__res-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
  margin: 0;
  margin-block-start: auto;
  padding-block-start: var(--sp-1);
  font-size: var(--fs-sm);
}
.pf-front__res-col { font-size: var(--fs-sm); font-weight: 600; color: var(--accent-text); }
.pf-front__res-read { font-size: var(--fs-sm); color: var(--text-muted); white-space: nowrap; }
/* ⑥ 日期：字号降一档 + 灰色 ⇒ 不与深蓝标题争夺注意力（甲方确认回调 #135/#145 方向） */
.pf-front__res-date { font-size: var(--fs-sm); font-weight: 500; color: var(--text-muted); white-space: nowrap; }
.pf-front__res-sep { color: var(--border-strong); }

/* ⑦ 列表项 hover 微动效：标题变色 + 下划线，缩略图轻微放大 */
.pf-front__res-item:hover .pf-front__res-title a { color: var(--brand-green); text-decoration: underline; text-underline-offset: 3px; }
.pf-front__res-item:hover .pf-front__res-thumb img { transform: scale(1.05); }

/* ---------- 窄屏：缩略图收窄、标题降一档（不改变「左图右文」形态） ---------- */
@media (max-width: 640px) {
  .pf-front__resources-index .pf-front__link-list.pf-front__res-list > li.pf-front__res-item {
    grid-template-columns: 96px minmax(0, 1fr);
    gap: var(--sp-4);
    padding-block: var(--sp-5);
  }
  .pf-front__res-title { font-size: var(--fs-lg); }
  .pf-front__res-summary { -webkit-line-clamp: 3; }
  .pf-front__res-search { max-inline-size: none; }
  .pf-front__res-search-btn { flex: 1 1 auto; }
  .pf-front__res-tools { margin-block: var(--sp-4) var(--sp-7); }
}

/* ==========================================================================
   第 16 批（2026-09-26）：解决方案页 / 关于我们 —— 外部审计 7 条落地
   --------------------------------------------------------------------------
   ①1 修语法与拼写（数据层，tools/apply-about-rewrite.cjs）
   ①2 精简「关于我们」并分离产品信息（数据层删目录 + 本层 .pf-front__about-cta 补入口）
   ①3 「Our Capabilities」与「Services」合并（模板层，templates/solution.js#capabilitiesSection）
   ②4 打破长文本：正文 h3 小标题 —— 见本层「关于我们」块
   ②5 关键数据 → 数据计数器 .pf-front__stats-*
   ②6 服务卡片 → 浅色矢量图标 .pf-front__solution-icon
   ②7 Solution / About Us 两标题：页头留白 + 通栏数据条 + 浅灰面板包裹

   ★ 本批**不动任何正文字号**（#129 的字号上调原样保留）：
     · h1 页标题继续用 --fs-3xl（@1440 = 48px）
     · 页内区块标题由 --fs-3xl 降为 36px —— 原实现里 h1/h2 同为 48px，
       审计 ②7 明确指出「两个大标题使用了相同的深蓝色和字号」，
       降 h2 是恢复正确的 h1 > h2 层级（非缩小正文字号）。
   ★ 全逻辑属性（padding-inline / margin-block / inset-inline）⇒ 阿语 RTL 零适配。
   ========================================================================== */

/* ---------- ②7 页头：h1 + 引言从 split 中移出，独占一行 ---------- */
.pf-front__solution-head { margin-block-end: var(--sp-8); }
/* 引言保持 #129 上调后的 28px（原规则挂在 .pf-front__solution-split 下，本批已移出该容器） */
.pf-front__solution-head .pf-front__solution-intro {
  font-size: var(--fs-2xl);
  margin-block: 0;
  max-inline-size: 70ch;
}

/* ---------- ②5 数据计数器：复用首页信任块的视觉语言（--surface-alt 面板 + 48px 数字） ---------- */
.pf-front__solution-stats {
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--sp-7) var(--sp-6);
  margin-block-end: var(--sp-12); /* ★ 审计 ②7：h1 与 About Us 之间的「更宽的留白」 */
}
.pf-front__stats-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-6) var(--sp-5);
  margin: 0;
  padding: 0;
  list-style: none;
}
@media (min-width: 768px) {
  .pf-front__stats-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
.pf-front__stats-item { text-align: center; }
.pf-front__stats-num {
  font-family: var(--font-heading);
  font-size: var(--fs-3xl);
  font-weight: 800;
  line-height: 1.05;
  color: var(--brand-primary);
  margin: 0 0 var(--sp-2);
  font-variant-numeric: tabular-nums; /* 递增动画时数字不左右跳动 */
  /* ★ 第 16 批 RTL 实测修正（ar）：`30` 与 `+` 是两个 span，页面 dir=rtl 时按 bidi
     排成 `+30`（实测 suffixLeft 1134 < valueLeft 1168）。数字是 LTR 安全内容，
     强制本段 direction:ltr ⇒ 六语一律显示 `30+`；父项 text-align:center 保证居中不变。 */
  direction: ltr;
}
.pf-front__stats-suffix { color: var(--brand-green); }
.pf-front__stats-label {
  margin: 0;
  font-size: var(--fs-base);
  color: var(--text-muted);
  line-height: 1.4;
}
/* 独立页面（/page/about）：号码条在 h1 之下、正文之上 */
.pf-front__about-page .pf-front__solution-stats { margin-block: var(--sp-6) var(--sp-9); }

/* ---------- ②6 服务卡片：浅色矢量图标（44px 浅底 chip + 品牌蓝描边图标） ---------- */
.pf-front__solution-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  align-self: flex-start; /* 卡片是 column flex，否则图标会被拉满整行 */
  inline-size: 2.75rem;
  block-size: 2.75rem;
  border-radius: var(--radius);
  background: var(--surface-sunken);
  color: var(--brand-green);
  margin-block-end: var(--sp-2);
  transition: background 0.2s ease, color 0.2s ease;
}
.pf-front__solution-icon svg { inline-size: 1.5rem; block-size: 1.5rem; display: block; }
.pf-front__solution-link:hover .pf-front__solution-icon { background: var(--brand-green); color: var(--surface); }

/* ---------- ②7 「关于我们」浅灰面板：与左栏形成明确视觉区隔；②4 h3 小标题分段 ---------- */
.pf-front__solution-about-col {
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--sp-7);
}
/* 页内区块标题 48 → 36px：重建 h1 > h2 层级（审计 ②7「相同的深蓝色和字号」）。
   ★ 置于文件末尾 ⇒ 同特异度下晚出现者胜，压过第 #129 批那条 --fs-3xl。 */
.pf-front__solution-split .pf-front__section-title { font-size: calc(var(--fs-2xl) + 0.5rem); }
/* 右栏正文的小标题（★ 第 102 批：26px → **20px**，降一档）。
 *   甲方便此意：「development 行，减小一个字号」——分节标题过大，与下方正文
 *   层级差被拉得太开（26 vs 14px = 1.86 倍），读起来像两个不同层级的东西。
 *   实测（1280/en，89 批整表降档后）：`--fs-xl` = 1.25rem = **20px**；
 *   原 `calc(--fs-xl + 0.375rem)` = 26px。 */
.pf-front__solution-about-col .pf-front__prose h3,
.pf-front__about-page .pf-front__prose h3 {
  font-family: var(--font-heading);
  font-size: var(--fs-xl);
  font-weight: 700;
  line-height: var(--lh-heading);
  color: var(--brand-primary);
  margin-block: var(--sp-7) var(--sp-2);
}
/* ★ 第 102 批：About 页正文 **14px → 16px**（升一档）。
 *   实测根变量（89 批整表降档后）：`--fs-base` = 0.875rem = **14px**（当前正文）、
 *   `--fs-lg` = 1.125rem = **18px**、`--fs-xl` = 1.25rem = **20px**（h3 新值）。
 *   若直接取 `--fs-lg`(18px)，正文与 h3 只差 2px ⇒ 层级又贴太近，正文反而抢戏；
 *   故取二者之间的 **16px（1rem）**，形成 20 / 16 = 1.25 倍的舒适层级差。
 *   ★ 显式写 rem 而非档位变量：档位是全站体系，此处只需本区块微调。 */
.pf-front__about-page .pf-front__prose { font-size: 1rem; }
.pf-front__solution-about-col .pf-front__prose { font-size: 1rem; }
/* ⚠ h3 的 20px 是显式指定，不随 prose 的 1rem 变动 ⇒ 层级稳定（20 / 16 = 1.25 倍）。
 *   引言式首行（welcome）下面单列，须与 h3 同步降档，否则又变回大一号。 */
.pf-front__solution-about-col .pf-front__prose > :first-child,
.pf-front__about-page .pf-front__prose > :first-child { margin-block-start: 0; }
/* 引言式首行（老站正文的居中粗体「Welcome to PROFIRST」）。
 * ★ 第 101 批：改为与 h3 一致（26px）；★ 第 102 批：随 h3 同步降为 **20px**。 */
.pf-front__solution-about-col .pf-front__prose p[align="center"] b,
.pf-front__about-page .pf-front__prose p[align="center"] b {
  font-family: var(--font-heading);
  font-size: var(--fs-xl);
  font-weight: 700;
  line-height: var(--lh-heading);
  color: var(--brand-primary);
}

/* ---------- ②7 两栏之间更宽的留白 + 按内容体量重分配栏宽 ---------- */
/* ★ 为什么必须改栏宽（实测，不是主观感觉）：
     · 合并「能力 + 服务」后左栏只剩 4 张卡 ⇒ 高 1018px；
     · 右栏「关于我们」正文 1650px、面板合计 1916px；
     · 原 1.6fr:1fr 把右栏压到 452px（面板内 367px / 22px 字 ⇒ 每行仅 ~28 字符，
       远低于可读区间 45–75），行数被推到 47 行，
       结果左栏底部空出 898px（= 右栏的 47%）。
     改为 1.1fr:1.3fr ⇒ 左 531px / 右 645px（面板内 ~581px ⇒ 每行 ~50 字符），
     两栏高度基本齐平。栏宽随**内容体量**走，而非沿用「左栏必须更宽」的旧假设。 */
@media (min-width: 1024px) {
  .pf-front__solution-split {
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 1.3fr);
    gap: var(--sp-12);
  }
}

/* ---------- ①2 产品目录移出后：指向产品页的入口 ---------- */
.pf-front__about-cta {
  margin: 0;
  margin-block-start: var(--sp-7);
  padding-block-start: var(--sp-5);
  border-block-start: 1px solid var(--border);
  font-family: var(--font-heading);
  font-weight: 600;
}
.pf-front__about-arrow { display: inline-block; margin-inline-start: var(--sp-2); }
[dir="rtl"] .pf-front__about-arrow { transform: scaleX(-1); }

/* ---------- ②7 附：证书「资质」通栏条（第 16 批附，实测驱动） ---------- */
/* ★ 为什么把证书图从右栏正文里**抽出来**（数字来自真实浏览器实测，逻辑见 ssg/solution-blocks.js#splitTrailingFigure）：
     · 中文版右栏正文末尾的「危险品经营许可证」图渲染 **571×402** ⇒ 该块独占 **442px**；
     · 中文右栏因此 1738px，而中文左栏（卡片文案比英文紧凑）只有 1018px
       ⇒ 左栏底部空出 **720px（= 右栏 41%）**，而英文仅 18% —— 语种间版面失衡；
     · 抽出后右栏回落至 **1213px**、两栏高差 **195px（16%）**，且证书拿到了独立醒目的位置。
   ★ 其余五语正文没有该图 ⇒ 模板不产出本容器 ⇒ 结构与本批之前**逐字一致**。 */
.pf-front__solution-cert {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-6);
  margin-block: var(--sp-12) 0;
  padding: var(--sp-6) var(--sp-7);
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}
.pf-front__solution-cert-label {
  margin: 0;
  font-family: var(--font-heading);
  font-size: var(--fs-lg);
  font-weight: 600;
  color: var(--brand-primary);
}
.pf-front__solution-cert-media { margin: 0; }
.pf-front__solution-cert-media p { margin: 0; }
.pf-front__solution-cert-media img {
  /* ★ max-block-size + inline-size:auto ⇒ 等比缩放到缩略图（原图 width=1000 会拉满整栏） */
  max-block-size: 200px;
  max-inline-size: 100%;
  inline-size: auto;
  block-size: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}
@media (max-width: 767px) {
  .pf-front__solution-cert { flex-direction: column; align-items: flex-start; }
}

/* ==========================================================================
 * 第 18 批甲方微调（2026-09-27）—— 联系页信息卡化 + 询盘表单增强 + 页脚四栏同排
 *   A. 页脚：西/俄语下四栏断行 ⇒ 四栏独立容器 .pf-front__footer-cols（nowrap）
 *   B. 联系页左栏：老站表格 → 无边框个人信息卡（头像 / 姓名 / 头衔 / 产品线胶囊 / 联系方式 / IM）
 *   C. 联系页左栏：新增企业实体卡（地址 + Google 地图外链）
 *   D. 询盘表单：产品「下拉 + 可手输」、TDS/SDS 与样品勾选框、隐私声明
 * 落点：ssg/render.js#buildFooter（容器）、ssg/templates/contact.js（卡片与表单）。
 * ========================================================================== */

/* ---------- A. 页脚四栏永不断行 ----------
 * 旧写法：`.pf-front__footer-inner` 自身 `flex-wrap: wrap` + 各栏 `flex: 0 1 auto`
 *   ⇒ 换行按**未收缩**的假设主轴尺寸判定，栏内文字越长越容易断
 *   （实测换行区间：es ≤1152 / pt ≤1080 / ru ≤1366；en/cn/ar 从不换行）。
 * 新写法：四栏单独包一层 `.pf-front__footer-cols`，只在这一层 nowrap；
 *   宽度不够时四栏按 flex-shrink 等比收缩、栏内文字自然折行，版权行仍独占一行。 */
.pf-front__footer-inner { display: block; gap: 0; }
.pf-front__footer-cols { display: grid; grid-template-columns: 1fr; gap: var(--sp-6); }
@media (min-width: 768px) {
  .pf-front__footer-cols { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1024px) {
  .pf-front__footer-cols {
    display: flex;
    flex-wrap: nowrap;
    justify-content: space-between;
    align-items: flex-start;
    column-gap: clamp(8px, 1.2vw, 56px);
  }
}

/* ---------- B. 联系页：引导语 + 个人信息卡 ---------- */
.pf-front__contact-lead { margin-block-end: var(--sp-6); }
.pf-front__contact-lead-title {
  margin: 0 0 var(--sp-2);
  font-family: var(--font-heading);
  font-size: var(--fs-2xl);
  line-height: var(--lh-heading);
  font-weight: 700;
  color: var(--text);
  text-wrap: balance;
}
.pf-front__contact-lead-sub { margin: 0; font-size: var(--fs-base); color: var(--text-muted); }

.pf-front__contact-cards {
  display: grid;
  gap: var(--sp-4);
  margin: 0 0 var(--sp-6);
  padding: 0;
  list-style: none;
}
/* ★ 审计 ①1 明写「**无边框**的个人信息卡片，通过留白、图标和字体粗细来区分」
 *   ⇒ 刻意**不画描边、不打投影**，改用浅底 + 大圆角 + 留白分层。
 *   浅底取 `--surface-sunken`（#eef2f8）而不是更淡的 `--surface-alt`（#f7f9fc）：
 *   后者叠在白底上对比仅 ~1.03，实际观感等于没画（等于只有留白、卡片不成立）。 */
.pf-front__contact-card {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--sp-4);
  align-items: start;
  padding: var(--sp-5);
  border: 0;
  border-radius: var(--radius-lg);
  background: var(--surface-sunken);
  box-shadow: none;
}
.pf-front__contact-avatar {
  display: grid;
  place-items: center;
  inline-size: 48px;
  block-size: 48px;
  flex: none;
  border-radius: 50%;
  background: var(--brand-primary);
  color: var(--surface);
  font-family: var(--font-heading);
  font-size: var(--fs-lg);
  font-weight: 700;
  letter-spacing: 0.02em;
}
.pf-front__contact-name { margin: 0; font-family: var(--font-heading); font-size: var(--fs-xl); font-weight: 700; color: var(--text); }
.pf-front__contact-role { margin: 0 0 var(--sp-3); font-size: var(--fs-base); font-weight: 600; color: var(--text-muted); }
.pf-front__contact-chips { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin: 0 0 var(--sp-3); padding: 0; list-style: none; }
/* 胶囊在浅底卡片上改用纯白：卡片已占 #eef2f8，胶囊再同色会「陷进去」看不见。 */
.pf-front__contact-chip {
  padding: 2px var(--sp-3);
  border-radius: var(--radius-pill);
  background: var(--surface);
  color: var(--brand-primary);
  font-size: var(--fs-sm);
  font-weight: 600;
}
.pf-front__contact-ways { display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-5); margin: 0; padding: 0; list-style: none; }
.pf-front__contact-way {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  color: var(--accent-text);
  font-size: var(--fs-base);
  font-weight: 600;
  text-decoration: none;
}
.pf-front__contact-way:hover { text-decoration: underline; text-underline-offset: 2px; }
.pf-front__contact-way-icon { inline-size: 18px; block-size: 18px; flex: none; }

/* ---------- C. 联系页：企业实体卡（地址 + 地图外链） ----------
 * 同样**无边框**；用「品牌蓝 6% 底」与上方个人信息卡（中性浅灰）区分层次。 */
.pf-front__contact-entity {
  padding: var(--sp-5);
  border: 0;
  border-radius: var(--radius-lg);
  background: rgba(10, 36, 99, 0.06);
}
.pf-front__contact-entity-title {
  margin: 0 0 var(--sp-3);
  font-family: var(--font-heading);
  font-size: var(--fs-lg);
  font-weight: 700;
  color: var(--text);
}
.pf-front__contact-entity-list { display: grid; gap: var(--sp-3); margin: 0; padding: 0; list-style: none; }
.pf-front__contact-entity-row { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--sp-1) var(--sp-3); }
.pf-front__contact-entity-label { font-weight: 700; color: var(--text); }
.pf-front__contact-entity-value { color: var(--text-muted); }
.pf-front__contact-map-link {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  color: var(--accent-text);
  font-size: var(--fs-sm);
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}
.pf-front__contact-map-link:hover { text-decoration: underline; text-underline-offset: 2px; }

/* ---------- D. 询盘表单：勾选框 + 隐私声明 ---------- */
.pf-front__checks { display: grid; gap: var(--sp-2); margin: 0 0 var(--sp-4); }
.pf-front__check { display: flex; align-items: flex-start; gap: var(--sp-2); font-size: var(--fs-base); color: var(--text); cursor: pointer; }
/* ★ 取品牌强调色（Logo 绿）作勾选色；不引外部资源、不破坏 CSP。 */
.pf-front__check input { inline-size: 18px; block-size: 18px; margin: 2px 0 0; flex: none; accent-color: #08A542; }
.pf-front__form-privacy { margin: var(--sp-3) 0 0; font-size: var(--fs-sm); color: var(--text-muted); }

/* ---------- B 续：卡片正文列与长串折行 ----------
 * 卡片是 `grid-template-columns: auto minmax(0,1fr)`；正文列必须显式 `min-inline-size:0`，
 * 否则长邮箱（如 shine@profirst.cn）会把 1fr 轨道顶开、卡片被撑破。 */
.pf-front__contact-body { min-inline-size: 0; }
.pf-front__contact-way-text { min-inline-size: 0; overflow-wrap: anywhere; }

/* ---------- C 续：实体卡（法务全称 + 地图外链箭头） ---------- */
.pf-front__contact-entity-company { margin: 0 0 var(--sp-3); font-size: var(--fs-base); font-weight: 600; color: var(--text); }
.pf-front__contact-map-arrow { inline-size: 14px; block-size: 14px; flex: none; }

/* 极窄屏（<380）：卡片内头像与正文改为上下排列，把宽度全留给邮箱等长串 */
@media (max-width: 379px) {
  .pf-front__contact-card { grid-template-columns: 1fr; }
}

/* ==========================================================================
 * 第 19 批甲方微调（2026-09-27）—— 页脚「第 3 栏标题被拦腰折断」
 * --------------------------------------------------------------------------
 * 现象（甲方截图 2 张）：es/pt「Empresa」→「Empres／a」、ru「Компания」→「Компани／я」，
 *   即单词被从中间断开、且**不带连字符**。第 1 栏（双词标题）只是按空格正常折行，非缺陷。
 *
 * 根因（实测 docs/qa/2026-09-27-contact-cards/probe-footer-title-break.cjs）：
 *   ① 全局 `h1,h2,h3,h4 { overflow-wrap: anywhere }` 落到了页脚标题 <h2> 上。
 *      `anywhere`（不同于 `break-word`）会把「软换行机会」**计入 min-content**
 *      ⇒ 该 <h2> 的 min-content 塌成≈单字符宽，所在栏因此能被压到比整词还窄，
 *         浏览器于是把这个单词从中间切开（这正是屏幕上看到的「折断」）。
 *   ② ≥1024 时 `.pf-front__footer-col { min-inline-size: 0 }` 允许 flex 项收缩到
 *      min-content 以下，进一步放大①。
 *   实测（单词标题「整词所需宽度」vs「该栏实得宽度」）：
 *     es/pt「Empresa」需 86px → 1080 屏实得 80/83px（折断）；
 *     ru  「Компания」需 108px → 1366 屏实得 107px（**只差 1px**，所以宽屏也偶发）。
 *
 * 修法（两条，互相配合，缺一不可）：
 *   A. 标题恢复 `overflow-wrap: normal` ⇒ 单词永不拦腰断，其 min-content 回到「整词宽度」；
 *   B. 栏位 `min-inline-size: min-content` ⇒ flex 收缩**止于该栏最宽单词**，不再压穿标题。
 *   ★ 两处都基于浏览器自己算的 min-content（自洽），**不靠跨端凑像素**：
 *     哪怕像 ru 那样只剩 1px 余量的情形，栏宽下限就等于本机的整词宽度，自动纠正。
 * 影响面：A 在任意宽度生效（<1024 时栏宽远大于单词，无副作用）；
 *         B 只在 ≥1024 生效。1440 及以上本就不发生收缩 ⇒ 观感零变化。
 * ========================================================================== */
.pf-front__footer-title { overflow-wrap: normal; }
@media (min-width: 1024px) {
  .pf-front__footer-col { min-inline-size: min-content; }
}

/* ==========================================================================
 * 第 20 批甲方微调（2026-09-27）—— 页脚「第四栏往右些」
 * --------------------------------------------------------------------------
 * 现象（甲方截图 · 西语页脚）：四栏右缘本就贴容器右缘，但第 4 栏（Contact）与第 3 栏
 *   （Empresa）只隔 13px，且栏内文字右侧空出 109px ⇒ 甲方要求「第四栏往右些」。
 *
 * 几何事实（实测 docs/qa/2026-09-27-contact-cards/probe-footer-col4.cjs）：
 *   第 4 栏因 `justify-content: space-between` **右缘恒贴容器右缘**
 *   ⇒ 其**左缘 = 容器右缘 − 第 4 栏宽度** ⇒ 要让它整体右移，**只能收窄第 4 栏**。
 *   而第 4 栏宽度被 `flex-basis: min(100%, 54ch)` 定死：这里的 54ch 在**栏自身字号(18px)**下
 *   算 ≈524px；栏内地址块上限 `max-inline-size: min(100%, 54ch)` 却在**地址字号(16px)**下
 *   算 ≈466px ⇒ 两者相差 ~58px 是**纯死空间**（栏比内容宽 58px）。
 *
 * 治本修法（不写死像素、不用魔法数）：
 *   ① 地址块上限去掉百分比：`min(100%, 54ch)` → `54ch`。
 *      ★ 关键机制：**百分比在固有尺寸（max-content）计算里不生效** ⇒ 原来那层 `100%`
 *        在计算第 4 栏 basis 时等于「没有上限」，浏览器按地址「整串不折」宽 ≈617px 计
 *        —— 这正是历史上「末栏右缘贴边、栏内文字右侧空 ~200px」的根因（当时补丁是给栏写死 54ch）。
 *        改纯 54ch 后，固有计算里地址的贡献 = 54ch@16px = 466px（= 地址真正需要的宽度）✓
 *        布局期宽度仍是 `min(栏宽, 54ch)` ⇒ 窄屏不溢出（与百分比版本等价）。
 *   ② ≥1100 起第 4 栏改 `flex: 0 0 auto`：宽度 = 内容真正所需（地址块 / 联系方式行 / 标题 三者最大）
 *      ⇒ 死空间消失、左缘自动右移；释放的宽度由前三栏（按内容宽）与栏间隙吸收。
 *
 * 阈值为何取 1100（实测扫参 docs/qa/2026-09-27-contact-cards/confirm-col4.cjs）：
 *   1024–1099 容器（= 视口宽 − 2×gutter）装不下四栏自然宽（俄语最紧：自然合计 1041 > 可用 921）。
 *   此时若把第 4 栏钉死在内容宽，被挤掉的行会落到第 1 栏（俄语 6→7 行）⇒ 该区间**沿用原规则**
 *   （四栏按比例收缩），1100 起才切换为「按内容宽」。实测 1100–1680 六语**行数零回退、无横向溢出**：
 *     第 4 栏左缘右移 58px（en/es/pt/ru）、52px（cn）；栏内文字距行尾 109→51px（es@1280）；
 *     栏隙 30→49px（es@1280）更透气。1440 以上同样 +58px。
 *   ★ 甲方视口实测 ≈1264 CSS px（其 2527×644 截图按 DPR 2 反推，见 match-client-shot.cjs）
 *     ⇒ 正落在生效区间内，得到的就是上面那 58px 的右移。
 * ========================================================================== */
.pf-front__footer-addr { max-inline-size: 54ch; }
:lang(zh) .pf-front__footer-addr { max-inline-size: 46ch; }
@media (min-width: 1100px) {
  .pf-front__footer-cols > .pf-front__footer-col:nth-child(4) { flex: 0 0 auto; }
}

/* ==========================================================================
 * 第 21 批甲方微调（2026-09-28）—— 新闻详情页：标题减一号 + 摘要改斜体
 * --------------------------------------------------------------------------
 * 甲方（截图＝新闻详情页）：①「标题，字体减一号」②「摘要，改为斜体字」。
 *
 * ★ 为什么必须**限定在新闻详情页**（`<main data-b01-main="news">`，见 render.js#pageShell）
 *   而不能改基类：
 *   ① `.pf-front__page-title` 是**全站页面 h1 共用类**（news / product / resource /
 *      solution / contact / page / search 共 18 处调用）⇒ 改基类会连产品、资源、
 *      方案等所有页面的 h1 一起变小，超出甲方所指范围。
 *   ② `.pf-front__lead` 除新闻详情外，**产品页也在用**（templates/product.js:400 / :482
 *      —— 产品简介与产品描述）。同理只能收窄到新闻详情页。
 *   ⇒ 列表页是 `data-b01-main="news_index"`，故索引页标题**不受影响**（甲方只要详情页）。
 *
 * ① 标题字号：`--fs-3xl` → `calc(var(--fs-3xl) - 0.5rem)`
 *      = 48px → **40px**（≥1200 视口；甲方视口 ≈1264 CSS px）。
 *      沿用 `calc(token ± 0.375/0.5rem)` 这一本项目既有写法（见 §解决方案页），
 *      不写死像素、不新增 token。
 * ② 摘要斜体：`.pf-front__lead` 加 `font-style: italic`（字号/颜色/间距一律不动）。
 * ========================================================================== */
[data-b01-main="news"] .pf-front__page-title { font-size: calc(var(--fs-3xl) - 0.5rem); }
[data-b01-main="news"] .pf-front__lead { font-style: italic; }

/* ==========================================================================
 * 第 28 批甲方微调（2026-09-29）—— 新闻详情页三处
 * --------------------------------------------------------------------------
 * 甲方原话（截图＝新闻详情页 /en/news/info-267）：
 *   ①「标题字太大，改到 32」
 *   ②「标题和内容之间，如没有摘要部分，就加一个空行」
 *   ③「其他新闻的列表行，贴近底部蓝色」
 *
 * ★ 三处落点**全部限定在新闻详情页** `<main data-b01-main="news">`
 *   （见 render.js#pageShell）；新闻**列表**页是 `data-b01-main="news_index"`，
 *   不在本次范围内。理由同第 21 批：`.pf-front__page-title` / `.pf-front__prose`
 *   都是全站共用类（news / product / resource / solution / contact / page / search），
 *   改基类会把产品页、资源页、方案页一起改掉。
 *
 * ① 标题字号：40px → **32px**。
 *     上一版为 `calc(var(--fs-3xl) - 0.5rem)`，在 ≥1200 视口解得 48 − 8 = **40px**
 *     （实测确认）；但该式在窄屏会随 `--fs-3xl` 的 clamp 下限一路降到 24px（如 375px 视口）。
 *     本次甲方给的是**绝对数值 32**，故用 `min(2rem, 上一版公式)` **封顶**为 32px：
 *       · ≥1000 视口 → min(32, 40~49) = **32px**（甲方所看 1264 视口实测 = 32px ✓）
 *       · 375 / 768 窄屏 → min(32, 24~30) = 24~30px —— **与改前逐字节相同，手机端零劣化**
 *     直接写死 `2rem` 会让手机端标题从 24px 涨到 32px（甲方未要求，且窄屏更挤），故不用。
 *     根字号 16px 且全站无 `html{font-size}` 覆写 ⇒ 2rem = 32px。
 *     用 `main[...]` 提高特异性覆盖上面第 21 批那条（0,1,1 > 0,1,0），保留历史留痕。
 *
 * ② 无摘要（无 `.pf-front__lead`）时，标题块与正文之间补**一个空行**。
 *     实测现状：`<time class="pf-front__date">` 只有 `margin-block-end: --sp-2`(8px)，
 *     于是「日期 → 正文」仅隔 8px（一篇文章有正文时才出日期，无正文时直接标题→正文）。
 *     「一个空行」沿用本项目既有口径（见本文件 §新闻详情页 related 区块注释）：
 *       1 空行 = --fs-lg(20px) × --lh-body(1.7) = **34px**
 *     ⇒ 加在正文 `.pf-front__prose` 的 `margin-block-start`：一处即可同时覆盖
 *       「有日期」（日期后空一行）与「无日期」（标题后空一行）两种结构。
 *     ★ 判定用 `:not(:has(.pf-front__lead))`（`:has()` 本文件 2396 行已在用），
 *       与模板 news.js#newsDetail 的 `showLead` 同源同义；**有摘要时完全不动**。
 *
 * ③ 正文下方「Latest news」列表 → 页脚蓝底之间：104px → **24px**。
 *     实测 104px = main 下内边距 `--sp-10`(56px) + 页脚上外边距 `--sp-9`(48px，见本文件 2131 行)。
 *     甲方「贴近底部蓝色」⇒ 该页 main 下内边距压到 24px、页脚上外边距归零。
 *     ★ 用 `main[...] + .pf-front__footer` 相邻兄弟选择器 —— render.js#pageShell 里
 *       `</main>` 紧接 `buildFooter()`，故可精确命中且不外溢到其它页面。
 *     ★ 特异性 (0,2,1) 稳过媒体查询里的 `.pf-front__main`(0,1,0)（本文件 1508 / 1611 行）。
 * ========================================================================== */
main[data-b01-main="news"] .pf-front__page-title {
  font-size: min(2rem, calc(var(--fs-3xl) - 0.5rem));
}

main[data-b01-main="news"] .pf-front__article-single:not(:has(.pf-front__lead)) .pf-front__prose {
  margin-block-start: calc(var(--fs-lg) * var(--lh-body));
}

main[data-b01-main="news"] { padding-block-end: 24px; }
main[data-b01-main="news"] + .pf-front__footer { margin-block-start: 0; }

/* ==========================================================================
 * 第 29 批（2026-09-29，甲方截图）：新闻详情页「前翻 / 后翻」指向条
 * --------------------------------------------------------------------------
 * 甲方原话：「新闻底部的导航条，没有前翻，后翻的指向条，加上。」
 * 经拍板取「两者都加」：
 *   ① 正文下方新增**文章级「上一篇 / 下一篇」**（按 publish_at 相邻，跳到另一篇新闻）；
 *   ② 底部「Latest news」标题行右侧新增**列表翻页控件**（每页 5 条，全量 169 条 ⇒ 34 页）。
 *
 * ★★ 为什么翻页控件放**标题行右侧**，而不是压在列表下方：
 *   第 28 批刚刚把「列表最后一行 → 页脚蓝条」从 104px 压到 24px（见本文件上一段）。
 *   若把控件放在列表下方，该距离会被重新撑到 ~76px，等于把上一批的成果直接推翻。
 *   放标题行右侧 ⇒ 列表下方维持 24px；且「Latest news 条」自身就成了那条导航条。
 *
 * ★ 数据侧：翻页数据来自静态 `/{prefix}/news-feed.json`（lib/ssg/news-feed.js），
 *   服务端只渲染首屏 5 条；**不把 169 条塞进 DOM**（体积 + SEO 链接农场风险，详见该文件注释）。
 *
 * ★ 落点隔离：`.pf-front__article-nav*` 为第 29 批新增类，**第 30 批起由三个模板共用**
 *   （news.js / resource.js / product.js；渲染实现统一在 lib/ssg/article-nav.js）。
 *   翻页控件同理由 `[data-list-pager]` 限定在**确实带列表的页面**
 *   （新闻详情 + 资源文章详情；第 30 批由 `[data-news-pager]` 更名而来）
 *   ⇒ 产品详情页只有上下篇、没有列表控件；其余页型零外溢。
 * ★ RTL：本区块自 2026-10-11 起使用**物理 left/right 对齐**，保证六语
 *   （含 ar）翻页条视觉方向统一；箭头不再镜像，列表分页按钮仍保持镜像。
 *   （此前曾用逻辑值自动镜像，现已按甲方「6语统一靠左/靠右」要求修正。）
 * ========================================================================== */

/* ① 文章级「上一篇 / 下一篇」 ------------------------------------------------ */

.pf-front__article-nav {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-4);
  margin-block-start: var(--sp-9);
}

.pf-front__article-nav-item {
  display: grid;
  align-content: start;
  gap: var(--sp-1);
  padding: var(--sp-4);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface-alt);
  text-decoration: none;
  transition: border-color 0.15s ease, background-color 0.15s ease;
}

/* 首篇无「上一篇」、末篇无「下一篇」时渲染的占位格：撑住列宽，不可见不可点。 */
.pf-front__article-nav-item.is-empty {
  border-color: transparent;
  background: none;
  pointer-events: none;
}

a.pf-front__article-nav-item:hover {
  border-color: var(--brand-primary);
  background: var(--surface);
}

.pf-front__article-nav-label {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  font-size: var(--fs-sm);
  font-weight: 700;
  color: var(--brand-primary);
}

.pf-front__article-nav-arrow {
  inline-size: 1em;
  block-size: 1em;
  flex: none;
}

.pf-front__article-nav-title {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  font-size: var(--fs-lg);
  font-weight: 600;
  line-height: 1.4;
  color: var(--text);
}

a.pf-front__article-nav-item:hover .pf-front__article-nav-title { color: var(--brand-primary); }

.pf-front__article-nav-date {
  font-size: var(--fs-sm);
  color: var(--text-muted);
}

/* 2026-10-11：左格是「下一篇」（箭头向左 ←），内容全部左对齐；
   右格是「上一篇」（箭头向右 →），内容全部右对齐。使用物理 left/right，
   六语（含 ar）保持同一视觉方向。 */
.pf-front__article-nav-item--next { text-align: left; }
.pf-front__article-nav-item--next .pf-front__article-nav-label { justify-content: flex-start; }
.pf-front__article-nav-item--prev { text-align: right; }
.pf-front__article-nav-item--prev .pf-front__article-nav-label { justify-content: flex-end; }

/* ★ 正文与「Latest news」之间原本留了「两个空行」（≈124px，见上一段第 28 批注释）。
   现在中间多了上下篇导航 ⇒ 该页改用常规间距，避免 124px 空档把导航条孤立起来。 */
[data-b01-main="news"] .pf-front__article-single:has(.pf-front__article-nav) .pf-front__article-related {
  margin-block-start: var(--sp-9);
}

/* ② 「Latest news」标题行 + 翻页控件 ---------------------------------------- */

.pf-front__article-related-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  flex-wrap: wrap;
}

/* 标题移入 flex 行后，其自带的 24px 下外边距改由行容器承担 */
.pf-front__article-related-head .pf-front__section-title { margin-block-end: 0; }
.pf-front__article-related-head + .pf-front__aside-related { margin-block-start: var(--sp-5); }

.pf-front__aside-pager {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  flex: none;
}

/* `hidden` 属性会被 display:inline-flex 覆盖 ⇒ 显式兜底（无 JS / 不足两页时必须不可见） */
.pf-front__aside-pager[hidden] { display: none; }

.pf-front__aside-pager-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: var(--sp-8);
  block-size: var(--sp-8);
  padding: 0;
  border: 1px solid var(--border-strong);
  border-radius: 50%;
  background: var(--surface);
  color: var(--brand-primary);
  cursor: pointer;
  transition: border-color 0.15s ease, background-color 0.15s ease, color 0.15s ease;
}

.pf-front__aside-pager-btn svg {
  inline-size: var(--sp-4);
  block-size: var(--sp-4);
}

.pf-front__aside-pager-btn:hover:not(:disabled) {
  border-color: var(--brand-primary);
  background: var(--brand-primary);
  color: var(--surface);
}

.pf-front__aside-pager-btn:disabled { opacity: 0.35; cursor: default; }

.pf-front__aside-pager-btn:focus-visible {
  outline: 2px solid var(--brand-green);
  outline-offset: 2px;
}

.pf-front__aside-pager-status {
  min-inline-size: 4.5em;
  text-align: center;
  font-size: var(--fs-sm);
  font-variant-numeric: tabular-nums;
  color: var(--text-muted);
  /* ★ RTL（ar）：计数值恒为「当前 / 总数」。若继承段落 RTL，两侧空格使中性符
     "/" 归入 RTL 层，数字被拆成两段并重排 ⇒ 视觉变成「总数 / 当前」，语义反了。
     强制 LTR + isolate ⇒ 视觉恒为 "1 / 34"，与 LTR 各语一致。 */
  direction: ltr;
  unicode-bidi: isolate;
}

/* ③ RTL（阿拉伯语）：文章级翻页箭头保持物理方向（左格←、右格→），
   不再镜像；列表分页按钮仍须镜像，保持「下一页」箭头指向阅读方向。 */

[dir="rtl"] .pf-front__aside-pager-btn svg { transform: scaleX(-1); }

/* ★★ 第 94 批实测修正：grid 容器在 `dir="rtl"` 下**列序自动镜像**（首列排到右侧），
   导致「下一篇」虽在 DOM 的第一位，视觉上却被挤到右格 —— 与其余五语相反。
   甲方要求「next 放最左边、previous 放最右边」六语统一，故 RTL 下须显式钉死列方向：
   `direction: ltr` 让 grid 按物理左→右排布（next 在左），再用 `unicode-bidi: isolate`
   保证格内阿拉伯语文本仍按 RTL 正确显示与左/右对齐。缺 isolate 会把子元素文字方向
   一并带成 LTR。 */
[dir="rtl"] .pf-front__article-nav {
  direction: ltr;
}
[dir="rtl"] .pf-front__article-nav > * {
  unicode-bidi: isolate;
}

/* ④ 窄屏：上下篇改堆叠；占位格不再显示 -------------------------------------- */

@media (max-width: 768px) {
  .pf-front__article-nav {
    grid-template-columns: 1fr;
    gap: var(--sp-3);
    margin-block-start: var(--sp-8);
  }
  .pf-front__article-nav-item.is-empty { display: none; }
  .pf-front__article-nav-item--next { text-align: left; }
  .pf-front__article-nav-item--next .pf-front__article-nav-label { justify-content: flex-start; }
  .pf-front__article-nav-item--prev { text-align: right; }
  .pf-front__article-nav-item--prev .pf-front__article-nav-label { justify-content: flex-end; }
  .pf-front__article-related-head { gap: var(--sp-3); }
  .pf-front__aside-pager-btn { inline-size: var(--sp-9); block-size: var(--sp-9); }
}

/* ==========================================================================
 * 第 30 批（2026-09-30，甲方截图）：产品详情 / 资源文章详情 也要「前翻 / 后翻」
 * --------------------------------------------------------------------------
 * 甲方原话：「产品详情页…没有前翻，后翻的指向条，加上。」
 *          「资源文章页同新闻一样，没有前翻，后翻的指向条，加上。」
 *
 * ★★ 本批**不新增任何样式** —— 直接复用上面第 29 批那整套 `.pf-front__article-nav*`
 *    / `.pf-front__aside-pager*`（渲染实现已抽到 lib/ssg/article-nav.js，三处模板共用）。
 *    这正是当初把控件样式写成「类名驱动、不绑页面」的回报：产品 / 资源页拿到即用，
 *    没有一行重复样式，也就不存在三份样式日后各自漂移的风险。
 *
 * ★ 三处唯一的差异是**序列口径**，与样式完全无关：
 *     · 新闻 = 全部已发布新闻，publish_at 升序（第 29 批）；
 *     · 资源 = 同栏目文章，publish_at 升序（本批，与新闻同规则）；
 *     · 产品 = 「全部产品」目录顺序 catalogOrder（本批；甲方 2026-09-29 拍板按目录顺序串联，
 *       不另立「仅同分类内相邻」的规则 —— 后者会让只有 1 个产品的分类整条导航消失）。
 *
 * ★ 间距沿用既有值，**未作任何调整**（先量后改：三处都落在合理区间）：
 *     · 上下篇自身 margin-block-start = --sp-9(48px)（沿用第 29 批）；
 *     · 资源页「正文 → 上下篇 → ← Back to resources → Related articles」=
 *       48 / 56(`.pf-front__back`) / 56(`.pf-front__article-related`) px。
 *     · 产品页上下篇放在 `.pf-front__product-main`（左栏）内部 ⇒ 卡片宽度与正文列一致，
 *       不会被右侧询盘框挤成长条；窄屏堆叠时位于正文与询盘框之间。
 * ========================================================================== */

/* ==========================================================================
 * 第 31 批（2026-09-29，甲方截图）：产品详情页「摘要」与「具体内容」视觉区分
 * --------------------------------------------------------------------------
 * 甲方原话：「产品详情页，包含两部分内容，上面一部分是摘要，下面一部分是具体内容。
 *   请用设计，如斜体，阴影，将两部分内容区分开来。全部的产品，都需要进行这样的处理。
 *   6 语言版本都统一。」
 *
 * ★ 两个字面对应的字段（库里早已存在，**无需改数据**）：
 *     · 摘要     = `.pf-front__lead`  ← `short_desc_<lang>`（templates/product.js:443）
 *     · 具体内容 = `.pf-front__prose` ← `translations.description`（同文件 :448）
 *   实测 en 站 128 个产品详情页：114 页两者俱全、116 页有具体内容、14 页无摘要。
 *
 * ★★ 本批**纯 CSS、零模板改动、零重建**：
 *   两个类名在全部 128 个产品 × 6 语上**早已存在且稳定** ⇒ 甲方「全部产品都要这样处理、
 *   六语统一」只要一条**按页型限定**的规则即可全覆盖；不需要 rebuild / prune / 双库同步。
 *   发布走「bump 版本号 → `--mode=html` ＋ 单文件原子替换 `front.css`」（见 §2b）。
 *
 * ★★★ 为什么必须限定 `[data-b01-main="product"]`（render.js#pageShell，值 = `page.kind`）：
 *   `.pf-front__lead` 是**全站共用类**，实测至少 4 处在用 ——
 *     · 产品**详情**页  product.js:443  ← 本次目标（`data-b01-main="product"`）
 *     · 产品**分类**页  product.js:526  ← 分类简介，`data-b01-main="category"`，**不能动**
 *     · **新闻详情**页  news.js:298     ← `data-b01-main="news"`；第 21 批已拍板「只加斜体」，
 *       本批**绝不能**给它套卡片（否则新闻页一起变卡、越出甲方所指）。
 *       ★ 甲方这次说的「同新闻一样」指的是**上一批的导航条**，**不是**这次的摘要卡。
 *     · solution / page 等页面的导语同理
 *   产品**列表**页是 `data-b01-main="products_index"`，不在范围内。
 *
 * ★ 设计（甲方点名「斜体、阴影」两个手法，都落实）：
 *     · 摘要 → 做成「摘要卡」：斜体 + **白底**(`--surface`) + 左侧品牌竖条(`--brand-accent`)
 *       + 阴影(`--shadow-md`) + 圆角(`--radius`)；
 *     · 具体内容 → **保持常规正文不动**（不倾斜、无底色、无边框）⇒ 与上面的卡形成
 *       「概览 vs 详情」的明确对照。**不动正文**同时意味着正文零回归风险。
 *
 * ★★ 为什么用**白底**而不是浅灰底（`--surface-alt`）—— 本批实测后改的一版：
 *   产品页上的规格块 `.pf-front__specs` **本身就已是浅灰底卡**（front.css:1091
 *   `background: var(--surface-alt)` + 1px 边框 + 12px 圆角）。若摘要卡也用同一灰底，
 *   在 76 个「有规格块」的产品上两者会紧邻出现（摘要 → 规格 → 正文），观感上像
 *   「两个兄弟灰块」，摘要不够突出。改白底后形成**三级层次**：
 *     白底 + 阴影（摘要，最"轻浮"）> 灰底 + 边框（规格，静态数据）> 纯文本（正文）。
 *   ★ 三个选项（灰底/白底 × shadow-md/lg）已出对照图 `variant-*.png` 留档。
 *
 * ★ 全部用既有 token，不新增变量、不写死颜色/尺寸：
 *     · 阴影用 `--shadow-md` —— 站内**内容块**的标准档（首页 Hero 用的就是它）；
 *       `--shadow-lg` 是**媒体**档（Hero 图/视频），语义上不属于正文块，故未采用。
 *     · `border-inline-start` 是**逻辑属性** ⇒ 阿拉伯语 `dir="rtl"` 下竖条自动落到右侧，
 *       与第 29 / 30 批的导航箭头同理，**无需单独写 RTL 分支**；
 *     · `max-inline-size: none` —— 卡片铺满左栏（约 690px），与正文列**同宽、右缘对齐**；
 *       若沿用基类的 `70ch` 上限，卡片会比正文窄一截，看起来「没对齐」。
 *
 * ★ 无摘要的 14 个产品：本规则自然不命中，仅显示常规正文（不产生空卡 / 空底）。
 * ========================================================================== */
[data-b01-main="product"] .pf-front__lead {
  font-style: italic;
  background: var(--surface);
  border-inline-start: 4px solid var(--brand-green);
  border-radius: var(--radius);
  padding: var(--sp-5) var(--sp-6);
  box-shadow: var(--shadow-md);
  max-inline-size: none;
}

/* ============================================================================
 * 55 批（2026-10-06）· AI 前端接线：搜索语义徽标 + 浮窗「AI 技术助手」问答
 * ----------------------------------------------------------------------------
 * ★ 全部用既有 token（--sp-* / --fs-* / --brand-* / --surface* / --radius*），
 *   不新增变量、不写死颜色与尺寸。
 * ★ **只新增类名族**，不改任何既有规则；有两条是对既有选择器的补充声明
 *   （面板限高、徽标），按本文件尾部既有的「追加式覆写层」惯例放在这里。
 * ★ 定位一律逻辑属性（inset-* / margin-inline-* / border-inline-start）
 *   ⇒ 阿语 RTL 下自动镜像，**无需单独写 RTL 分支**。
 * ========================================================================== */

/* --- 搜索页：语义命中徽标（只给 semantic / concept 加，keyword 不加） --- */
.pf-front__search-hit-badge {
  display: inline-block;
  margin-inline-start: var(--sp-2);
  padding: 0 var(--sp-2);
  border: 1px solid var(--brand-green);
  border-radius: var(--radius-pill);
  color: var(--brand-primary);
  background: var(--surface-alt);
  font-size: var(--fs-xs);
  font-weight: 600;
  line-height: 1.6;
  vertical-align: middle;
  white-space: nowrap;
}

/* --- 浮窗面板限高 + 内部滚动（新增 AI 问答块后，移动端不得超出视口） --- */
.pf-front__chat-panel {
  /* ★ 55 批：宽度 20rem → 22rem（20rem 时输入框占位文案被截断，实测甲方可见）。
     仍留 `100vw - gutter` 上限，窄屏行为不变。 */
  inline-size: min(22rem, calc(100vw - var(--sp-10)));
  max-block-size: min(34rem, calc(100vh - var(--sp-11)));
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* --- 浮窗内「AI 技术助手」问答块 --- */
.pf-front__chat-ai { margin-block-end: var(--sp-4); }
.pf-front__chat-ai[hidden] { display: none; }
.pf-front__chat-ai-title {
  margin: 0 0 var(--sp-2);
  font-family: var(--font-heading);
  font-size: var(--fs-base);
  font-weight: 700;
  color: var(--brand-primary);
}
.pf-front__chat-ai-form { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
/* ★ 57 批「双通道搜索」：查询态（`data-chat-ai-mode="query"`）没有输入框，
   只有「提示语 + 提问按钮」——提示语明说这是**通道②**（用同一个查询词问 AI），
   按钮左对齐、限宽，避免在整栏宽度下被拉成一个巨大的色块。 */
.pf-front__chat-ai-hint {
  margin: 0 0 var(--sp-3);
  color: var(--text-muted);
  font-size: var(--fs-sm);
  line-height: 1.55;
}
.pf-front__chat-ai-askrow { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.pf-front__chat-ai-ask { flex: 0 0 auto; }
.pf-front__chat-ai-input { flex: 1 1 9rem; min-inline-size: 0; }
.pf-front__chat-ai-send { flex: 0 0 auto; }
/* ★ 55 批：浮窗内**竖排**输入与发送。
   浮窗面板只有 22rem（减内边距后 ≈19rem 可用），横排时输入框被压到约 10rem，
   占位文案「Ask a technical question…」被截成「What is your minimu…」（甲方看演示时可见）。
   竖排后输入框吃满整行、按钮整行在下，占位完整；搜索页内是整栏容器，故**只覆写浮窗内那一份**。 */
.pf-front__chat .pf-front__chat-ai-input,
.pf-front__chat .pf-front__chat-ai-send { flex: 1 1 100%; }
.pf-front__chat-ai-status {
  margin: var(--sp-2) 0 0;
  color: var(--text-muted);
  font-size: var(--fs-sm);
  min-block-size: 1.4em;
}
.pf-front__chat-ai-answer {
  margin-block-start: var(--sp-2);
  padding: var(--sp-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-alt);
  font-size: var(--fs-sm);
  overflow-wrap: anywhere;
  white-space: pre-wrap;
}
.pf-front__chat-ai-answer[hidden] { display: none; }
.pf-front__chat-ai-sources-wrap { margin-block-start: var(--sp-2); }
.pf-front__chat-ai-sources-wrap[hidden] { display: none; }
.pf-front__chat-ai-sources-title {
  margin: 0 0 var(--sp-1);
  font-size: var(--fs-xs);
  font-weight: 700;
  color: var(--text-muted);
  letter-spacing: 0.04em;
}
.pf-front__chat-ai-sources { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-2); }
.pf-front__chat-ai-source {
  padding-inline-start: var(--sp-3);
  border-inline-start: 2px solid var(--border);
  font-size: var(--fs-sm);
}
.pf-front__chat-ai-source-link { display: block; font-weight: 600; color: var(--brand-primary); overflow-wrap: anywhere; }
.pf-front__chat-ai-source-snippet { display: block; margin-block-start: 2px; color: var(--text-muted); font-style: normal; }
.pf-front__chat-ai-human { display: block; margin-block-start: var(--sp-2); text-align: center; }
.pf-front__chat-ai-human[hidden] { display: none; }
.pf-front__chat-ai-disclaimer {
  margin: var(--sp-2) 0 0;
  color: var(--text-muted);
  font-size: var(--fs-xs);
  line-height: 1.5;
}

/* --- 搜索页内的 AI 问答块（55 批「改挂搜索页」；与浮窗内那份共用 .pf-front__chat-ai 类族，
       这里只换外层容器：整栏卡片 + 与搜索表单同宽，视觉上归入搜索页而不是浮窗） --- */
.pf-front__search-ai {
  margin-block-start: var(--sp-6);
  padding: var(--sp-4) var(--sp-5);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  max-inline-size: 44rem;
}
.pf-front__search-ai[hidden] { display: none; }
.pf-front__search-ai .pf-front__chat-ai { margin-block-end: 0; }

/* ============================================================================
 * 2026-10-07 · 资源中心索引页「全部资源 + 底部翻页向导条」
 * ----------------------------------------------------------------------------
 * 分页标记与产品目录**共用同一套**（`.pf-front__catalog-pager*` 一族，见 lib/ssg/list-pager.js），
 * 故这里只补两条，不新增任何分页样式：
 *   ① 资源列表放进分页容器后的外边距归零（页内是 `<ul>`，产品页内是网格 `<div>`）；
 *   ② 标签筛选生效时（`.is-filtered`，由 front.js#initResourceFilter 添加）
 *      **展开全部页 + 隐藏分页器与状态行** —— 否则命中项散落在后几页，
 *      用户会误以为「只筛出这么几条」。
 * ★ `is-filtered` 只会出现在资源索引页 ⇒ 产品目录行为不受影响。
 * ========================================================================== */
.pf-front__catalog-pager-wrap .pf-front__res-list { margin: 0; }

.pf-front__catalog-pager-wrap.is-filtered .pf-front__catalog-pages { display: block; }
.pf-front__catalog-pager-wrap.is-filtered .pf-front__catalog-page {
  display: block;
  opacity: 1;
  visibility: visible;
  content-visibility: visible;
}
.pf-front__catalog-pager-wrap.is-filtered .pf-front__catalog-pager,
.pf-front__catalog-pager-wrap.is-filtered .pf-front__catalog-status { display: none; }

/* ============================================================================
 * 2026-10-10 · 询单框（右栏）收窄 1/4 —— 左栏相应扩大（全站统一 · 六语自动一致）
 * ----------------------------------------------------------------------------
 * 甲方：「只要有询单框，都缩小 1/4，左边的内容相应扩大些，全网站同样处理。」
 *
 * 询单框全站只出现 2 处，且都由**这一份 CSS** 控制 ⇒ 改这里 = 六语、所有产品页同时生效：
 *   ① 联系页     `.pf-front__contact-layout`（≥768px 起为两栏）
 *   ② 产品详情页 `.pf-front__product-grid`（≥1024px 起为两栏）
 *
 * 做法：**两栏总宽不变**，只改「右栏 : 左栏」的 fr 配比 —— 使右栏 = 原宽 × 0.75，
 *       左栏吃掉腾出的全部宽度（栅格容器宽由 max-width 决定，与配比无关）。
 *       配比推导（保持 fr 总和不变 ⇒ 左右两栏宽度之和恒定）：
 *         · 联系页  原 1.4 : 1（合 2.4）⇒ 右栏占 1/2.4，目标 0.75/2.4
 *                   ⇒ 右 0.75fr、左 (2.4 − 0.75) = 1.65fr ⇒ **2.2 : 1**
 *         · 产品页  原 1.55 : 1（合 2.55）⇒ 右栏占 1/2.55，目标 0.75/2.55
 *                   ⇒ 右 0.75fr、左 (2.55 − 0.75) = 1.8fr ⇒ **2.4 : 1**
 *   实测（线上 82.157.64.186 · 六语逐项 0.00px 极差）：
 *     · 1440 —— 联系页 右 500 → **375**、左 700 → **825**
 *     · 1440 —— 产品页 右 473.72 → **355.29**、左 734.27 → **852.70**
 *   窄屏（联系页 <768、产品页 <1024）本即**单列堆叠**，不存在「左栏」⇒ 维持原样不动。
 *   ★ 若日后新增第三处询单框，请把它也纳入这里的比例体系，勿单独写死宽度。
 * ========================================================================== */
@media (min-width: 768px) {
  .pf-front__contact-layout { grid-template-columns: 2.2fr 1fr; }
}

@media (min-width: 1024px) {
  .pf-front__product-grid { grid-template-columns: minmax(0, 2.4fr) minmax(0, 1fr); }
}

/* ============================================================================
 * 2026-10-10 · 第 89 批 ① 全站字号整体降一档（最小号保持不变）
 * ----------------------------------------------------------------------------
 * 甲方：「全站的字号，都缩小一号，除最小的字号外。」
 *
 * 做法：**字号体系是 7 档变量（--fs-*），这里整表下移一档** —— 每一档取「原来低一档」的值，
 *       最小档 --fs-xs 按指令**原样不动**（它是地板，再往下就没有了）。
 *       ★ 不新增/不删除档位，只平移取值 ⇒ 排版比例关系（几档之间的相对大小）整体保持。
 *
 *   档位        原值                          新值（= 原低一档）        渲染（16px 根字号）
 *   --fs-xs     0.75rem                       0.75rem  ← 不动            12px
 *   --fs-sm     0.875rem                      0.75rem                   14px → 12px
 *   --fs-base   1.125rem（18px）              0.875rem                  18px → 14px（正文）
 *   --fs-lg     1.25rem（20px）               1.125rem                  20px → 18px
 *   --fs-xl     1.375rem（22px）              1.25rem                   22px → 20px
 *   --fs-2xl    clamp(1.5rem,2.2vw,1.75rem)   1.375rem                  24~28px → 22px
 *   --fs-3xl    clamp(2rem,4vw,3rem)          clamp(1.5rem,2.2vw,1.75rem)  32~48px → 24~28px
 *
 *   ★ 已知副作用（如实记录）：下移后 `--fs-sm` 与 `--fs-xs` **同值 0.75rem**
 *     —— 这是「最小号不动」这条约束的必然结果，不是写错。
 *     若日后想恢复两者差异，只需把 `--fs-sm` 改成 0.8125rem（13px）。
 *
 *   ★ 另有 5 处**直写字号**（不是变量，不随上表联动）已同步下移一档，见本段末尾。
 * ========================================================================== */
:root {
  --fs-xs: 0.75rem;                            /* ← 最小号：按指令不变 */
  --fs-sm: 0.75rem;                            /* 原 --fs-xs */
  --fs-base: 0.875rem;                         /* 原 --fs-sm（14px） */
  --fs-lg: 1.125rem;                           /* 原 --fs-base（18px） */
  --fs-xl: 1.25rem;                            /* 原 --fs-lg（20px） */
  --fs-2xl: 1.375rem;                          /* 原 --fs-xl（22px） */
  --fs-3xl: clamp(1.5rem, 2.2vw, 1.75rem);     /* 原 --fs-2xl（24~28px） */
}

/* ---------- 5 处直写字号：同样下移一档（与新体系对齐，否则会「比新正文大一大截」） ---------- */
/* 1) 产品详情 H1：原为「比通用 H1 小一档」的 24px ⇒ 跟着降一档到 22px */
.pf-front__product .pf-front__page-title { font-size: 1.375rem; }
/* 2)(3) 页脚地址：原 16px（夹在旧 sm 14 / 旧 base 18 之间）⇒ 降一档到 14px
       （约束仍是「两条长地址各占一行」，字号变小只会更容易单行，不会回退成 3 行） */
.pf-front__footer-addr { font-size: 0.875rem; }
/* 4) 栏目标题条（浅蓝底那条）：原 clamp(21px,1.65vw,24px) ⇒ 降一档 */
.pf-front__section-sub { font-size: clamp(1.1875rem, 1.5vw, 1.375rem); }
/* 5) 新闻列表卡标题：原 20px（当时 --fs-xl 降而来）⇒ 降一档到 18px */
.pf-front__news .pf-front__card-title { font-size: 1.125rem; }

/* ============================================================================
 * 2026-10-10 · 第 89 批 ② 页头上条（logo 这一条）改白底 + LOGO 换回品牌原版
 * ----------------------------------------------------------------------------
 * 甲方：「公司 Logo 被蓝色遮盖后，有点失真。可以在 logo 这一条变为白色的吗？」
 *
 * 根因取证（2× 截图 + 文件比对）：
 *   · 原页头整体 #1a4d93 深蓝，LOGO 用的是 `/assets/logo-inverse.png`（**反白描边版**，
 *     3,329 B）—— 实测该版字母是**描边而非实心**，放大到 155×80 后发虚；
 *   · 品牌原版 `/assets/logo.png`（22,937 B）是**蓝字 + 蓝弧 + 绿球**，本就为**浅底**设计。
 * ⇒ 正解＝把 logo 那一条改白底，LOGO 换回原版（改动见 `render.js#ASSET_LOGO`）。
 *
 * ★ 与第 13 批「主导航去蓝」同源同法：那条白带当时已把 `.pf-front__nav-row` 翻成白底深蓝字，
 *   本批把**上条**一并翻过来 ⇒ 整个页头成为「白底 + 发丝线」，
 *   与「蓝条 + 白条」相比更干净，也和页面的浅底正文连成一体。
 * ★ 上条与导航条原靠「蓝/白撞色」分隔，翻白后需补一条发丝线，否则两行粘成一块。
 * ★ 上条内 4 个控件（搜索钮 / 语言链 / 语言下拉钮 / 汉堡钮）原本都按「深底浅字」写死，
 *   白底下会**看不见**（近白色字 + 8% 白底）⇒ 一并翻成「浅底深蓝字」，悬停改浅灰。
 *
 * ★★ 关键补充（实测坐标，1440 视口）：`.pf-front__header-top` 与 `.pf-front__nav-row`
 *   **都带 `max-inline-size: var(--container)`＝82.5rem＝1320px 且水平居中**
 *   ⇒ 只把这两行刷白，两侧会各露出 **60px 的深蓝**（页头容器本身的底色），
 *     看上去像页头被「框」了一道蓝边。故**必须把页头容器本身也刷白**：
 *       实测（1440）：header x=0 w=1440 bg #1a4d93 ｜ header-top x=60 w=1320 ｜ nav-row x=60 w=1320
 *     改后：header bg=#fff（满宽）⇒ 两行白条与页头连成一体，蓝边消失。
 *   （窄视口 ≤1320 时容器本就满宽，无此现象。）
 * ★ 分隔发丝线保留在 `.pf-front__header-top` 的下边（宽度＝容器宽 1320，与内容栅格对齐）。
 * ========================================================================== */
.pf-front__header {
  background: var(--surface); /* ★ 满宽刷白，消除两侧 60px 蓝边 */
}
.pf-front__header-top {
  background: var(--surface);
  border-block-end: 1px solid var(--border); /* 与下方导航条分隔（原靠蓝白撞色） */
}
.pf-front__header-top .pf-front__brand-legal { color: var(--brand-primary); }

/* 上条内的控件：深底浅字 → 浅底深蓝字 */
.pf-front__header-top .pf-front__search-toggle,
.pf-front__header-top .pf-front__lang-toggle,
.pf-front__header-top .pf-front__nav-toggle {
  border-color: var(--border-strong);
  background: var(--surface);
  color: var(--brand-primary);
}
.pf-front__header-top .pf-front__search-toggle:hover,
.pf-front__header-top .pf-front__lang-toggle:hover,
.pf-front__header-top .pf-front__lang-toggle[aria-expanded="true"],
.pf-front__header-top .pf-front__nav-toggle:hover,
.pf-front__header-top .pf-front__nav-toggle[aria-expanded="true"] {
  background: var(--surface-alt);
}
/* 桌面语言链（移动端隐藏、走下拉，规则不冲突） */
.pf-front__header-top .pf-front__lang-link { color: var(--text-muted); }
.pf-front__header-top .pf-front__lang-link:hover { color: var(--brand-primary); }
.pf-front__header-top .pf-front__lang-link[aria-current="true"] {
  background: var(--accent-fill);
  color: var(--surface);
}
/* 搜索框展开后的输入框本就在浅底上定义，此处只需保证与白条同色 */
.pf-front__header-top .pf-front__search-input { background: var(--surface); }

/* ============================================================================
 * 2026-10-10 · 第 90 批 ① 主导航条改「品牌蓝」——把页头从「整条白」拆回「白条 + 蓝条」
 * ----------------------------------------------------------------------------
 * 甲方：「Logo 条变为白色后，页头部分太单调，Home/News 主导航条变为蓝色是否可以破色，好看些？」
 *
 * 判断：**推荐做**，且这正是第 13 批「主导航去蓝」的**反向回调** ——
 *   当时的诉求是「页头三块深蓝首尾相连、缺呼吸感」，于是把导航条刷白；
 *   现在 Logo 条也白了 ⇒ 页头变成**一整条白**，反而**丢了层次**。
 *   把导航条刷回蓝、Logo 条留白，等于用「白/蓝」两色把「品牌区」与「导航区」分开 ——
 *   既解决单调，又不会退回第 13 批否定过的「三块蓝连成一片」。
 *
 * 取色：`--blue-surface-deep`(#1a4d93) —— **站内既有的大面积蓝**（第 13 批前的页头色、
 *   与页脚 `--blue-surface` #2a6bad 同族），不新增第五种蓝。
 * 对比度（沿用第 13 批已算过的矩阵）：
 *   · 导航文字 `--on-dark` #eaf1fb on #1a4d93 ≈ **8.6:1** ✓（远超 4.5:1）
 *   · 当前项绿下划线 `--brand-accent` #3e92cc on #1a4d93 ≈ **3.01:1** ✓（≥3:1 UI 组件门槛）
 * ★ 绿**只做当前项的下划线**，不铺满整条底线 —— 否则会和当前项标记连成一体、标记失效
 *   （与第 13 批同一条结论）。
 * ★ 上条与导航条之间**不再需要发丝线**：蓝/白撞色本身就是硬边（与第 13 批同法）。
 * ★★ 通栏处理（实测发现问题后补）：`.pf-front__nav-row` 自身带
 *   `max-inline-size: var(--container)`＝1320px 且居中 ⇒ 直接刷蓝只有 1320px 宽，
 *   1440 视口下两侧各留 60px 白边，蓝条像「浮在半空的一小段」。
 *   ⇒ 用 **`box-shadow` 大范围扩散 + `clip-path: inset(0 -100vmax)`** 把它做成**通栏色带**
 *     （只在横向溢出、纵向保持不变），**不改结构、不加包装元素**。
 * ========================================================================== */
/* ★★ 第 106k 修复（甲方实测：下拉子菜单只露出第一项）：
 *   原实现用 `box-shadow: 0 0 0 100vmax` + **`clip-path: inset(0 -100vmax)`** 做通栏色带，
 *   但 **`clip-path` 会裁剪该元素的全部溢出内容**（不只是背景）—— 导航下拉面板本就要
 *   **向下溢出** nav-row，于是被齐平剪掉，只剩第一项可见（solutions/resources 同样）。
 *   ⇒ 改为 **`::before` 伪元素**承担通栏背景（自身不裁剪），内容层用 z-index 抬到背景之上。
 *   通栏效果与配色**完全不变**（仍是 `--blue-surface-deep` 横向铺满视口）。
 * ========================================================================== */
.pf-front__nav-row {
  position: relative;
  background: transparent;
}
.pf-front__nav-row::before {
  content: '';
  position: absolute;
  inset-block: 0;
  /* ★★ 2026-10-28 修复（甲方实测阿语首页近乎空白）：
   *   原值 `-100vmax` 让伪元素向左右各溢出 100vmax（1440×900 视口下 = 各 1440px），
   *   把文档 scrollWidth 撑到 2820px（实测 en/cn/es/pt/ru/ar **六语种全部如此**）。
   *   LTR 下只是能横向拖出一片空白；RTL（阿语）下溢出方向翻转 ⇒
   *   首屏内容被整体推到视口外，看起来像空白页（内容本身渲染正常）。
   *   改为「按视口对齐」：从 nav-row 中心向两侧各 50vw ⇒ 宽度≈视口，不再产生溢出。 */
  inset-inline: calc(50% - 50vw);
  background: var(--blue-surface-deep);
  pointer-events: none;
  z-index: 0;
}
/* 内容抬到背景之上（★ 注意层叠顺序：nav 必须**高于** header-contact，
   否则下拉面板会被后面 DOM 顺序的联系信息盖住 / 透出来——甲方 2026-10-13 截图实测） */
.pf-front__nav { position: relative; z-index: 2; }
.pf-front__header-contact { position: relative; z-index: 1; }
.pf-front__header-top { border-block-end-color: transparent; }

.pf-front__nav-link { color: var(--on-dark); border-inline-end-color: var(--hairline); }
.pf-front__nav-link:first-child { border-inline-start-color: var(--hairline); }
.pf-front__nav-link:hover { background: rgba(255, 255, 255, 0.12); color: var(--surface); }
.pf-front__nav-link[aria-current="page"] {
  background: transparent;
  color: var(--surface);
  border-block-end-color: var(--brand-green);
}

/* 联系条（Tel / Email）与导航同在一个 `.pf-front__nav-row` 内 ⇒ 一并翻回「深底浅字」 */
.pf-front__header-contact,
.pf-front__header-contact-item,
.pf-front__header-contact a { color: var(--on-dark-muted); }
.pf-front__header-contact-label { color: var(--on-dark); }
.pf-front__header-contact a:hover { color: var(--surface); }

/* 移动端抽屉：`.pf-front__nav-row` 即抽屉本体（默认收起）⇒ 一并蓝底；
   行分隔线由浅灰换成 white-16%（深底上浅灰看不见）。 */
@media (max-width: 767px) {
  .pf-front__nav-link { border-block-end-color: var(--hairline); }
  .pf-front__header-contact { border-block-start-color: var(--hairline); }
}

/* ============================================================================
 * 2026-10-10 · 第 90 批 ② 产品详情页三处版式修正（甲方截图 ×2，全部产品 · 六语统一）
 * ----------------------------------------------------------------------------
 * 落点全部按页型限定 `[data-b01-main="product"]`（`render.js#pageShell` 写入 `page.kind`）
 *   ⇒ `.pf-front__lead` / `.pf-front__prose` 是**全站共用类**（新闻 / 资源 / 分类页 / 单页都在用），
 *     不限定就会误伤；限定后「所有产品页统一、其余页零改动」。
 *
 * ② -1 摘要字号「降 2 号」
 *      摘要 `.pf-front__lead` 当前走 `--fs-lg` = 1.125rem = **18px**。
 *      ★ 严格按 7 档体系「降 2 档」＝ lg → base → sm ＝ **12px**；
 *        但**实测出图后否掉了 12px**（见 `variant-lead-{a-12px,b-14px,c-16px}.png`）：
 *        12px **小于正文 `--fs-base`(14px)** ⇒ 摘要变成「比正文更小的注释」，
 *        与甲方一贯口径「最小号要保护、不要太小」相冲，观感也像失误而非设计。
 *      ⇒ 落地 **`--fs-base`(0.875rem = 14px)**：比原来小 4px、与正文同号，
 *        在「不抢正文」与「摘要不该比正文小」之间取稳。三档对照图已留档，
 *        若要 12px 或 16px，改这一行即可（`--fs-sm` / `1rem`）。
 *      同时把卡片内边距收一档（sp-5/sp-6 → sp-4/sp-5），否则文字变小、盒子显得空。
 *
 * ② -2 正文宽度 = 摘要宽度
 *      摘要卡第 55 批已设 `max-inline-size: none`（铺满左栏），
 *      但正文 `.pf-front__prose` 仍受基类 `max-inline-size: 72ch` 约束（≈554px）⇒ 比摘要窄一截。
 *      实测（1440）：摘要卡 853px、正文 554px。⇒ 产品页正文一并放开为 `none`。
 *
 * ② -3 正文表格「右侧空白」去掉 + 表格居中
 *      根因（实测 HTML + CSS）：产品正文表格来自**老站迁移的原始 HTML**，形如
 *        `<table border="1" align="center">…</table>`，只有 2 列；而基类把它设成
 *        `.pf-front__prose table { inline-size: 100% }`（front.css:436）＋
 *        `display: block; overflow-x: auto`（:1260）⇒ **表格边框被拉满整行**，
 *        右侧于是留出一大片「框内空白」。
 *      ⇒ 产品页内改为 `inline-size: fit-content` ＋ `margin-inline: auto`（居中）；
 *        实测：表宽 853 → **334px**、左留白 = 右留白 = **259px**（精确居中）。
 *        仍保留 `max-inline-size: 100%` + `overflow-x: auto` ⇒ 宽表照旧可横向滚动，不会溢出。
 *      ★ 只改产品页。新闻 / 资源 / 单页 / 联系页（老站联系表格）的表格**不动**。
 * ========================================================================== */
[data-b01-main="product"] .pf-front__lead {
  font-size: var(--fs-base);          /* 18px → 14px（原为 lg；12px 实测过小，见上） */
  padding: var(--sp-4) var(--sp-5);   /* 随字号收一档 */
}

[data-b01-main="product"] .pf-front__prose {
  max-inline-size: none;              /* 与上方摘要卡同宽（第 55 批已给摘要 none） */
}

[data-b01-main="product"] .pf-front__prose table {
  inline-size: fit-content;           /* 不再拉满整行 ⇒ 右侧空白消失 */
  max-inline-size: 100%;
  margin-inline: auto;                /* 表格居中 */
}

/* ============================================================================
 * 2026-10-10 · 第 91 批 首页视频区：缩略图胶片条 + 计数徽标（解决「看不出是不同的视频」）
 * ----------------------------------------------------------------------------
 * 甲方：「首页视频缩略图不完整，而且这个视频展示部分的设计，**不能很快让人理解是不同的
 *        产品视频展示**，提出解决方案。」
 *
 * 问题一（缩略图不完整）＝**素材层面**，不在本节：库里 7 张封面中 **6 张是竖图**
 *   （530×750 / 370×475），被塞进 16:9 框 + `object-fit: cover` ⇒ 上下被裁掉约 60%。
 *   ⇒ 处置＝**用视频本身抽帧重制 11 张 16:9 封面**（ffmpeg，见 `_staging/posters/`），
 *     并逐条写回 `settings.video_library[i].poster`。
 *
 * 问题二（看不出是不同的视频）＝**设计与数据双重原因**：
 *   · 数据：11 条里 **5 条共用同一张封面** ⇒ 每 6 秒自动换一张，看着像"同一张图换标题"；
 *   · 设计：唯一的导航是**一排 11 个小圆点**，辨不出数量与内容。
 *   ⇒ 处置＝主画面**下方加一条缩略图胶片条**（本节样式）+ 右上角**计数徽标**。
 *
 * ★ 胶片条是 `.pf-front__home-hero` 的**第三个直接子元素**，靠 `grid-column: 1 / -1`
 *   横贯整个 hero 宽度（≥1024 约 1320px）⇒ 11 张**一屏全见**，不必横向滚动。
 *   （首版曾把它塞在媒体列内，媒体列仅约 554px、一次只看得到 5~6 张 ⇒ 已否决。）
 *   ★ 负外边距 `calc(var(--sp-4) - var(--sp-8))`：hero 的 `row-gap` 是 `--sp-8`(40px)，
 *     直接相邻会"离得太开、像另一节"；抵消到视觉 **16px** —— 与主画面形成明确的从属关系。
 *     ★ 不改 `.pf-front__home-hero` 的 gap 本身（那会连带改变移动端「文案↔媒体」的间距）。
 * ★ 缩略图 `flex: 1 1 0` **等分** ⇒ 视频条数变化时自动重排，不写死宽度。
 * ★ 与圆点不重复：**≥768 隐藏圆点**（胶片条本身就是更好的导航），窄屏保留圆点。
 * ★ 全部用既有 token，不新增变量、不写死品牌色。
 * ========================================================================== */
.pf-front__hero-strip {
  grid-column: 1 / -1;                       /* 横贯 hero 两列 */
  display: flex;
  gap: var(--sp-2);
  margin-block-start: calc(var(--sp-4) - var(--sp-8));   /* 40px 行距 ⇒ 视觉 16px */
  padding: 2px;                              /* 给选中态的描边留出不被裁的余量 */
  overflow-x: auto;
  scrollbar-width: thin;
}
.pf-front__hero-thumb {
  flex: 1 1 0;
  min-inline-size: 0;
  padding: 0;
  border: 2px solid transparent;
  border-radius: var(--radius-sm);
  background: var(--brand-primary);          /* 缩略图加载前不露白 */
  line-height: 0;
  cursor: pointer;
  overflow: hidden;
  opacity: 0.62;                             /* 未选中压暗 ⇒ 当前项更跳 */
  transition: opacity 0.18s ease, border-color 0.18s ease;
}
.pf-front__hero-thumb img {
  display: block;
  inline-size: 100%;
  block-size: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}
.pf-front__hero-thumb:hover { opacity: 1; border-color: var(--brand-green); }
.pf-front__hero-thumb[aria-selected="true"] { opacity: 1; border-color: var(--brand-green); }
.pf-front__hero-thumb:focus-visible { outline: 2px solid var(--surface); outline-offset: 2px; opacity: 1; }

/* 右上角计数徽标「3 / 11」—— 由 front.js#initHeroCarousel 随 slide 同步更新 */
.pf-front__hero-count {
  position: absolute;
  inset-block-start: var(--sp-3);
  inset-inline-end: var(--sp-3);
  z-index: 6;
  padding: 0 var(--sp-3);
  border-radius: var(--radius-pill);
  background: rgba(10, 36, 99, 0.82);
  color: var(--surface);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: 0.02em;
  line-height: 1.7;
}

/* ≥768：胶片条已足够导航 ⇒ 收起圆点（窄屏仍保留圆点，手指更好点） */
@media (min-width: 768px) {
  .pf-front__hero-dots { display: none; }
}
/* 窄屏：胶片条改横向滚动、每张定宽 84px（等分会让每张只剩 20 多像素） */
@media (max-width: 767px) {
  .pf-front__hero-strip { gap: var(--sp-1); }
  .pf-front__hero-thumb { flex: 0 0 84px; }
}

/* ==========================================================================
 * 第 96 批（2026-10-11，甲方截图指令）：解决方案页删除「关于我们」右栏 + 重排为单栏
 * --------------------------------------------------------------------------
 * 背景：右栏正文与 `/page/about` **同一份来源**（translations `pg_lgcy_about`），
 *       且第 95 批起主导航已有独立「关于我们」入口 ⇒ 同一内容两处重复，
 *       且右栏把四张服务卡片压成单列窄条（甲方截图即此现象）。
 * 处置：模板层删除右栏；本层把「能力与服务」升格为通栏主模块，卡片恢复多列铺满。
 * ★ 置于此处（文件末尾）⇒ 同特异度下晚出现者胜，可压过第 16 批写在中段的
 *   `.pf-front__solution-split …` 系列（那些选择器随 split 一起失效，双保险）。
 * ========================================================================== */

/* ① 主模块上下留白（替代原 split 容器） */
.pf-front__solution-capabilities {
  margin-block-start: var(--sp-10);
}

/* ② 四张服务卡片：桌面 4 列铺满、中屏 2 列、窄屏 1 列。
   ★ 原 `.pf-front__solution-split .pf-front__solution-grid { grid-template-columns: 1fr }`
     把它压成单列；split 已删除 ⇒ 回到基础规则的 auto-fill minmax(15rem,1fr)，
     此处显式写死断点以保证「1280px 下正好 4 列」的排版意图明确、可验收。 */
.pf-front__solution-capabilities .pf-front__solution-grid {
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--sp-7);
}
/* ★ 断点定1199（而非 1023）：容器内宽 = 视口 − 左右留白，1024 视口下实际内容宽仅约 930px，
   4 列每列约 210px 偏窄 ⇒ ≥1200 才给 4 列，1024~1199 给 2 列。 */
@media (max-width: 1199px) {
  .pf-front__solution-capabilities .pf-front__solution-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (max-width: 599px) {
  .pf-front__solution-capabilities .pf-front__solution-grid {
    grid-template-columns: 1fr;
  }
}

/* ③ 模块标题字号：原本靠 `.pf-front__solution-split .pf-front__section-title`
   提到 2xl+0.5rem（因为要跟右栏 h2 区分）；单栏后 h1 → h2 层级自然成立，
   回到与其他页型一致的 --fs-3xl，避免标题比 h1 还抢眼。 */
.pf-front__solution-capabilities .pf-front__section-title {
  font-size: var(--fs-3xl);
}

/* ④ 产品目录入口：原挂在右栏末尾，删栏后转为主模块之后的独立通栏行动点。 */
.pf-front__solution-products-cta {
  margin-block-start: var(--sp-8);
}


/* ── 第 103 批：About 页欢迎语提升为独立块（位于数据条上方）────────────────
 * 甲方便此意：「Welcome to Profirst 这一行放到 30+, 100+, 这一行的上面」。
 * 模板已把它从正文首段提取为 `.pf-front__welcome`（data-section="welcome"），
 * 此处给样式：居中 + 与 h3 同号（20px，第 102 批定档），下边距略大以贴近数据条。
 */
.pf-front__welcome {
  margin-block-end: var(--sp-7);
  text-align: center;
}
.pf-front__welcome p { margin-block: 0; }
.pf-front__welcome b,
.pf-front__welcome strong {
  font-family: var(--font-heading);
  font-size: var(--fs-xl);      /* 20px＝与分节标题 h3 同级（第 102 批） */
  font-weight: 700;
  line-height: var(--lh-heading);
  color: var(--brand-primary);
}

/* ══════════════════════════════════════════════════════════════════════════
   第 106k 批（甲方 2026-10-13）：导航**悬停子菜单**
   ----------------------------------------------------------------------------
   需求：鼠标移到 Products / Solutions / Resources 时弹出子目录（对齐老站
   www.profirst.cn 的交互）。结构由 lib/ssg/render.js#buildNav 输出：
     <div class="pf-front__nav-item">
       <a class="pf-front__nav-link">Products</a>
       <div class="pf-front__subnav"><a class="pf-front__subnav-link">…</a></div>
     </div>
   交互：桌面 **hover 展开**（focus-within 支持键盘 Tab）；触摸端**不展开**
   （避免导航过长，子项仍可从栏目页进入）。
   ══════════════════════════════════════════════════════════════════════════ */
.pf-front__nav-item {
  position: relative;
  display: inline-flex;
  align-items: stretch;
}
.pf-front__subnav {
  position: absolute;
  inset-block-start: 100%;
  inset-inline-start: 0;
  z-index: 60;
  min-inline-size: 236px;
  padding-block: 6px;
  /* ★ 第 106m 批（甲方：「颜色更深，改淡一些、明亮一些」）：
     原用 --brand-primary(#0a2463 最深的品牌蓝)，在蓝底导航条下显得发闷；
     改用站内既有的 --blue-surface(#2a6bad，页脚同款)—— 比导航条(#1a4d93)**亮一档**，
     层次清晰、观感更明快。文字 --on-dark(#eaf1fb) on #2a6bad ≈ 5.6:1 ✓（≥4.5:1）。 */
  background: var(--blue-surface);
  /* 亮蓝底上，半透明白边比深色发丝线更清晰 */
  border: 1px solid rgba(255, 255, 255, 0.22);
  box-shadow: 0 14px 30px rgba(4, 18, 42, 0.30);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
  transition: opacity 0.16s ease, transform 0.16s ease, visibility 0.16s;
}
.pf-front__nav-item:hover .pf-front__subnav,
.pf-front__nav-item:focus-within .pf-front__subnav {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}
.pf-front__subnav-link {
  display: block;
  padding-block: 9px;
  padding-inline: 18px;
  color: var(--on-dark);
  font-family: var(--font-heading);
  font-size: var(--fs-base);
  font-weight: 500;
  white-space: nowrap;
  border-inline-start: 2px solid transparent;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.pf-front__subnav-link:hover {
  background: rgba(255, 255, 255, 0.18);   /* ★ 亮蓝底上略提高（原 0.10 偏弱） */
  border-inline-start-color: var(--brand-green);
  text-decoration: none;
}
/* 触摸端（窄屏）：不展开子菜单，保持导航简洁 */
@media (max-width: 900px) {
  .pf-front__subnav { display: none; }
}

/* ============================================================================
 * 第 107k 批（2026-10-14）· 视觉整体提升 —— 第三方方案·第 1+3 批落地
 * ----------------------------------------------------------------------------
 * 甲方交办《PROFIRST 视觉提升方案与模拟验证》（QwenWork）：「检测是否可以实现，
 * 第二步不做；如可实现，现在实现。」
 * ★ 核实结论：**可实现** —— 方案引用的 10 个选择器（hero-title / home-hero /
 *   btn--primary / section-title / eyebrow / footer / featured-* / value-card /
 *   nav-link / lang-link）**全部真实存在**；「字体从未加载」等诊断经实测属实。
 * 本批落地范围（甲方裁定：「只是 02 这一步不做，不是第二批不做」）：
 *   01 字体落地（自托管 woff2；Poppins 标题 / Inter 正文）
 *   02 排版层级重建 —— **整项不做**（H1 34~50px / 区块标题 24~30px / 渐变短横线，均保持现状）
 *   03 Hero 质感升级（三层背景 + 网点纹理 + 媒体景深 + 播放按钮放大）
 *   04 色彩聚焦（页脚归深蓝家族 + 绿顶条、行动绿 #3e92cc、按钮绿色光晕、眉标亮蓝）
 *   05 产品卡精修（摄影棚台面 + 悬浮 -4px/缩放 + 圆角 16px）
 *   06 动效系统（--ease 令牌统一 0.18s；按钮焦点环强化）
 *   07 区块节奏（Why Choose 浅蓝色带 + 标题色条蓝→绿渐变）
 *   08 多语言字体策略（ru → Inter 西里尔、ar → Tajawal + 眉标字距豁免；zh 保持系统栈）
 * ----------------------------------------------------------------------------
 * ★ 与方案原文的两处工程化调整（已在交付说明中注明）：
 *   ① 字体改**自托管**（原方案用 jsDelivr CDN）：文件落 `assets/fonts/`（16 个
 *      woff2，共 ~310KB，OFL 许可随附同目录），零第三方依赖、任何地区可达。
 *   ② 字体栈覆盖**同时重写各语言分支**（原方案只改 :root，会被下文
 *      `html[lang=ar|zh|ru|pt]` 既有分支盖掉）。
 * ★ unicode-range 分片：各页只加载**用到的字形子集**（en/es/pt→latin；
 *   ru→cyrillic+latin；ar→arabic+latin），跨语言互不拖累。
 * ★ 字体文件名为**不可变资产**（无 ?v）：日后替换字体请用新文件名。
 * ★ 全局 prefers-reduced-motion 保护**已存在**（本文件 1827 行），故未重复添加。
 * ========================================================================== */

/* ---------------- 01 · 字体（自托管；font-display:swap；子集分片） ---------------- */
@font-face { font-family:'Poppins'; font-style:normal; font-display:swap; font-weight:600;
  src:url("fonts/poppins-latin-600-normal.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face { font-family:'Poppins'; font-style:normal; font-display:swap; font-weight:700;
  src:url("fonts/poppins-latin-700-normal.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face { font-family:'Inter'; font-style:normal; font-display:swap; font-weight:400;
  src:url("fonts/inter-latin-400-normal.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face { font-family:'Inter'; font-style:normal; font-display:swap; font-weight:500;
  src:url("fonts/inter-latin-500-normal.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face { font-family:'Inter'; font-style:normal; font-display:swap; font-weight:600;
  src:url("fonts/inter-latin-600-normal.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face { font-family:'Inter'; font-style:normal; font-display:swap; font-weight:700;
  src:url("fonts/inter-latin-700-normal.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face { font-family:'Inter'; font-style:normal; font-display:swap; font-weight:400;
  src:url("fonts/inter-latin-ext-400-normal.woff2") format("woff2");
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF; }
@font-face { font-family:'Inter'; font-style:normal; font-display:swap; font-weight:500;
  src:url("fonts/inter-latin-ext-500-normal.woff2") format("woff2");
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF; }
@font-face { font-family:'Inter'; font-style:normal; font-display:swap; font-weight:600;
  src:url("fonts/inter-latin-ext-600-normal.woff2") format("woff2");
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF; }
@font-face { font-family:'Inter'; font-style:normal; font-display:swap; font-weight:700;
  src:url("fonts/inter-latin-ext-700-normal.woff2") format("woff2");
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF; }
@font-face { font-family:'Inter'; font-style:normal; font-display:swap; font-weight:400;
  src:url("fonts/inter-cyrillic-400-normal.woff2") format("woff2");
  unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116; }
@font-face { font-family:'Inter'; font-style:normal; font-display:swap; font-weight:500;
  src:url("fonts/inter-cyrillic-500-normal.woff2") format("woff2");
  unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116; }
@font-face { font-family:'Inter'; font-style:normal; font-display:swap; font-weight:600;
  src:url("fonts/inter-cyrillic-600-normal.woff2") format("woff2");
  unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116; }
@font-face { font-family:'Inter'; font-style:normal; font-display:swap; font-weight:700;
  src:url("fonts/inter-cyrillic-700-normal.woff2") format("woff2");
  unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116; }
@font-face { font-family:'Tajawal'; font-style:normal; font-display:swap; font-weight:400;
  src:url("fonts/tajawal-arabic-400-normal.woff2") format("woff2");
  unicode-range:U+0600-06FF,U+0750-077F,U+0870-088E,U+0890-0891,U+0897-08E1,U+08E3-08FF,U+200C-200E,U+2010-2011,U+204F,U+2E41,U+FB50-FDFF,U+FE70-FE74,U+FE76-FEFC,U+102E0-102FB,U+10E60-10E7E,U+10EC2-10EC4,U+10EFC-10EFF,U+1EE00-1EE03,U+1EE05-1EE1F,U+1EE21-1EE22,U+1EE24,U+1EE27,U+1EE29-1EE32,U+1EE34-1EE37,U+1EE39,U+1EE3B,U+1EE42,U+1EE47,U+1EE49,U+1EE4B,U+1EE4D-1EE4F,U+1EE51-1EE52,U+1EE54,U+1EE57,U+1EE59,U+1EE5B,U+1EE5D,U+1EE5F,U+1EE61-1EE62,U+1EE64,U+1EE67-1EE6A,U+1EE6C-1EE72,U+1EE74-1EE77,U+1EE79-1EE7C,U+1EE7E,U+1EE80-1EE89,U+1EE8B-1EE9B,U+1EEA1-1EEA3,U+1EEA5-1EEA9,U+1EEAB-1EEBB,U+1EEF0-1EEF1; }
@font-face { font-family:'Tajawal'; font-style:normal; font-display:swap; font-weight:700;
  src:url("fonts/tajawal-arabic-700-normal.woff2") format("woff2");
  unicode-range:U+0600-06FF,U+0750-077F,U+0870-088E,U+0890-0891,U+0897-08E1,U+08E3-08FF,U+200C-200E,U+2010-2011,U+204F,U+2E41,U+FB50-FDFF,U+FE70-FE74,U+FE76-FEFC,U+102E0-102FB,U+10E60-10E7E,U+10EC2-10EC4,U+10EFC-10EFF,U+1EE00-1EE03,U+1EE05-1EE1F,U+1EE21-1EE22,U+1EE24,U+1EE27,U+1EE29-1EE32,U+1EE34-1EE37,U+1EE39,U+1EE3B,U+1EE42,U+1EE47,U+1EE49,U+1EE4B,U+1EE4D-1EE4F,U+1EE51-1EE52,U+1EE54,U+1EE57,U+1EE59,U+1EE5B,U+1EE5D,U+1EE5F,U+1EE61-1EE62,U+1EE64,U+1EE67-1EE6A,U+1EE6C-1EE72,U+1EE74-1EE77,U+1EE79-1EE7C,U+1EE7E,U+1EE80-1EE89,U+1EE8B-1EE9B,U+1EEA1-1EEA3,U+1EEA5-1EEA9,U+1EEAB-1EEBB,U+1EEF0-1EEF1; }

/* 令牌：字体栈 / 动效曲线 / 行动绿（须晚于既有 :root 与 html[lang] 分支声明才生效） */
:root {
  --font-heading: 'Poppins', 'Inter', 'PingFang SC', 'Microsoft YaHei', system-ui, -apple-system, sans-serif;
  --font-body: 'Inter', 'PingFang SC', 'Microsoft YaHei', system-ui, -apple-system, sans-serif;
  /* 06 · 动效令牌：一条曲线走全站（交互反馈 0.18s / 悬浮抬升 0.32s） */
  --ease: cubic-bezier(.2, .7, .3, 1);
  /* 04 · 行动绿：原 #08a542（Logo 采样）→ #0ca54f（去"塑料感"；明度同级，对比度不降） */
  --brand-green: #0ca54f;
  --brand-green-hover: #0b9440;
}
html[lang="ru"] {
  /* 西里尔：Poppins 不含西里尔字形 ⇒ 逐字回落 Inter（同源现代感） */
  --font-heading: 'Poppins', 'Inter', 'Segoe UI', sans-serif;
  --font-body: 'Inter', 'Segoe UI', sans-serif;
}
html[lang="pt"] {
  --font-heading: 'Poppins', 'Inter', 'Segoe UI', sans-serif;
  --font-body: 'Inter', 'Segoe UI', sans-serif;
}
html[lang="ar"] {
  /* 阿语：Tajawal 打头（新增自托管）；Noto Kufi/Naskh 保留为二顺位（装有机字体者仍生效） */
  --font-heading: 'Tajawal', 'Noto Kufi Arabic', 'Segoe UI', system-ui, sans-serif;
  --font-body: 'Tajawal', 'Noto Naskh Arabic', 'Segoe UI', system-ui, sans-serif;
}
/* zh 分支保持原样（中文字体走系统 PingFang/雅黑，无需加载——方案 08 明确）。 */

/* ---------------- 04 · 眉标（原方案 02 组内条目，按甲方指示**保留**；02 其余不做） ----------------
   ★ 甲方裁定：《02 排版层级重建》整项不做 ⇒ H1 34~50px、区块标题 24~30px、
     64×4 渐变短横线**一律保持现状**。眉标属 04 色彩聚焦（"眼眉文字改亮蓝 #8ec7ff，
     在深底上形成第一层级"），故保留。 */
.pf-front__eyebrow { color: #8ec7ff; letter-spacing: .16em; }
/* ★ ar 豁免：阿拉伯连写体上大值 letter-spacing 会拆断字腔连接 ⇒ 眉标禁用字距（08 多语策略） */
html[lang="ar"] .pf-front__eyebrow { letter-spacing: 0; }

/* ---------------- 04 · 色彩聚焦 ---------------- */
/* 页脚：中蓝 #2a6bad → 深蓝家族 #0f3070（与 Hero 同族）+ 3px 品牌绿顶条 */
.pf-front__footer { background: #0f3070; border-top: 3px solid #0ca54f; }
/* 主按钮（行动绿）：常驻柔和光晕 + 悬浮加深（取代旧蓝色阴影；保留上浮手感） */
.pf-front__btn--primary { box-shadow: 0 6px 18px rgba(12, 165, 79, .32); }
.pf-front__btn--primary:hover {
  background: var(--brand-green-hover);
  color: var(--on-green);
  transform: translateY(-2px);
  box-shadow: 0 10px 26px rgba(12, 165, 79, .42);
}

/* ---------------- 06 · 动效系统 ---------------- */
/* 交互控件统一走 --ease（0.18s 档）；悬浮抬升由各组件自身 0.32s 档消费（本批已统一曲线） */
.pf-front__btn { transition: background-color .18s var(--ease), color .18s var(--ease), border-color .18s var(--ease), transform .18s var(--ease), box-shadow .18s var(--ease); }
.pf-front__nav-link { transition: background-color .18s var(--ease), color .18s var(--ease), border-color .18s var(--ease); }
.pf-front__lang-link { transition: background-color .18s var(--ease), color .18s var(--ease); }
/* 按钮焦点环强化（全局 2px 基础上加粗一档；品牌强调蓝在深/浅底均可辨） */
.pf-front__btn:focus-visible { outline: 3px solid var(--brand-green); outline-offset: 3px; }

/* ---------------- 03 · Hero 质感升级（三层背景 + 网点纹理 + 媒体景深） ----------------
 * ★ 工程校正：真实站点里 hero 蓝面板 = `.pf-front__hero`（**外层**，带 padding/圆角/渐变）；
 *   原方案片段写 `.pf-front__home-hero`（内层网格）—— 若照抄会加错宿主（面板不着色）。
 *   ⇒ 本批对准真实宿主 `.pf-front__hero`。 */
.pf-front__hero {
  position: relative; /* 承载网点纹理伪元素 */
  background:
    radial-gradient(820px 420px at 82% -10%, rgba(120, 190, 255, .30), transparent 62%),
    radial-gradient(600px 340px at -8% 108%, rgba(64, 150, 220, .24), transparent 58%),
    linear-gradient(155deg, #0d3071 0%, #14418a 52%, #1a55a8 100%);
}
/* 网点纹理（纯 CSS 圆点 + mask 右侧渐显；border-radius:inherit 保证圆角处不出方形漏点）。
   既有「扩散圆弧」母题在内层 `.pf-front__home-hero::before`（左下角、opacity .08），两者并存。 */
.pf-front__hero::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  border-radius: inherit;
  background-image: radial-gradient(rgba(255, 255, 255, .115) 1px, transparent 1.4px);
  background-size: 26px 26px;
  -webkit-mask-image: linear-gradient(115deg, transparent 30%, #000 78%);
          mask-image: linear-gradient(115deg, transparent 30%, #000 78%);
}
/* 内容层压在纹理之上：文案列 / 媒体列已有 z-index:1；胶片条此前为 static（会被网点轻盖）⇒ 提层 */
.pf-front__hero-strip { position: relative; z-index: 1; }
/* 视频舞台：1px 内描边 + 深投影 —— 与背景分离出"景深" */
.pf-front__home-hero-media { border: 1px solid rgba(255, 255, 255, .14); box-shadow: 0 24px 48px rgba(4, 16, 44, .45); }
/* 播放按钮：放大（≈56px 高）+ 内描边 + 深投影 + 悬浮缩放反馈 */
.pf-front__hero-play-btn {
  min-block-size: 56px;
  padding: var(--sp-3) var(--sp-6);
  gap: var(--sp-3);
  border: 1px solid rgba(255, 255, 255, .3);
  box-shadow: 0 8px 24px rgba(4, 16, 44, .35);
  transition: background-color .18s var(--ease), transform .18s var(--ease), box-shadow .18s var(--ease);
}
.pf-front__hero-play-btn svg { inline-size: 28px; block-size: 28px; }
.pf-front__hero-play-btn:hover {
  background: var(--accent-fill);
  color: var(--surface);
  transform: scale(1.06);
  box-shadow: 0 12px 30px rgba(4, 16, 44, .45);
}

/* ---------------- 05 · 产品卡精修（摄影棚台面 + 悬浮叙事；圆角 16px） ---------------- */
/* 产品图容器加"摄影棚台面"（radial 浅蓝灰）→ 不同批次产品照色调视觉归一 */
.pf-front__featured-thumb { background: radial-gradient(120% 90% at 50% 116%, #dbe7f5 0%, #f6f9fd 62%); }
/* 卡片：圆角统一 16px；过渡统一 0.32s + --ease */
.pf-front__featured-link,
.pf-front__value-card {
  border-radius: var(--radius-lg);
  transition: transform .32s var(--ease), box-shadow .32s var(--ease), border-color .32s var(--ease);
}
/* 悬浮：-4px + 大阴影 + 柔化描边（取代旧 -2px/品牌蓝描边） */
.pf-front__featured-link:hover,
.pf-front__value-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 16px 36px rgba(10, 36, 99, .14);
  border-color: #b9cfe8;
}
/* 悬浮时产品图同步微放大（容器已 overflow:hidden，放大被裁在框内） */
.pf-front__featured-thumb img { transition: transform .32s var(--ease); }
.pf-front__featured-link:hover .pf-front__featured-thumb img { transform: scale(1.045); }

/* ---------------- 07 · 区块节奏（Why Choose 浅蓝色带 + 标题色条渐变） ---------------- */
/* 激活既有闲置令牌 --band-tint（#eff5fc）：白 → 浅蓝 → 白 的滚动呼吸（仅首页 value-props 段） */
[data-section="value-props"] {
  background: linear-gradient(180deg, transparent, var(--band-tint) 12%, var(--band-tint) 88%, transparent);
}
/* 区块标题左侧色条：纯蓝 → 蓝→绿渐变（强化双主色记忆；CTA 变体的 display:none 规则不受影响） */
.pf-front__section-title::before { background: linear-gradient(180deg, #3e92cc, #0ca54f); }

/* ============================================================================
 * 第 107o 批（2026-10-14 · 甲方）· Hero 视频区改版 + 左侧文字放大 + 产品页视频
 * ----------------------------------------------------------------------------
 * 甲方原话：「下面放 6 个小视频框，和视频播放器对齐，好看些。…… 左边的字，写大一些，
 *   和右边的 6 个小视频框基本平齐。」→ 终版补充：「PASS×4 + PASS-LF 1 个，放在一个框里面，
 *   称为 PASS 系列。另外的 5 个产品，一个产品一个框，最后一个是 youtube，一共 7 个框。」
 * 口径（终版）：**全部 11 条视频都在轮播**；缩略条按**组**出 7 框 =
 *   「PASS 系列」×1（PASS×4 + PASS-LF×1 合为一框，点击在系列内轮转）
 *   + 5 个产品各 1 框 + YouTube×1（单独、压轴）。
 * ========================================================================== */

/* ① 缩略条：移入媒体列 → 7 列等分网格（覆盖原「横贯两列 flex + 负外边距 + 横向滚动」） */
.pf-front__home-hero-media-col .pf-front__hero-strip {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: var(--sp-2);
  margin-block-start: var(--sp-3);   /* 覆盖原 calc(sp-4 - sp-8) 的负外边距（那是两列行距补偿） */
  overflow: visible;
}
.pf-front__home-hero-media-col .pf-front__hero-thumb { flex: none; } /* 网格内不再参与 flex 等分 */
/* 系列框角标（显示该框含几条视频，如 PASS 系列 = 5）；thumb 需定位上下文。 */
.pf-front__hero-thumb { position: relative; }
.pf-front__hero-thumb-badge {
  position: absolute;
  inset-block-start: 3px;
  inset-inline-end: 3px;
  min-inline-size: 17px;
  padding: 0 4px;
  border-radius: var(--radius-pill);
  background: rgba(10, 36, 99, .85);
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  line-height: 17px;   /* thumb 为 line-height:0，角标自带行高 */
  text-align: center;
}

/* ② 左侧文字放大（甲方：「写大一些，和右边的 6 个小视频框基本平齐」）
 *   ★ 第 107o 补（2026-10-14，甲方「笔记本视觉不好」）：原为 1440 单点校准的固定值
 *   （42/27px），在 1024–1366 笔电宽度下左栏比右栏 **高 95–116px**（实测）⇒ 改 **clamp 随视口缩放**：
 *   1024→34/21px，1280→38/25px，1440→42/27px；右栏（播放器+7框）高度近似随视口线性变化，
 *   两侧比例保持（各宽度实测差 ≤25px，见 docs/qa/2026-10-14-batch107o）。 */
.pf-front__hero-title { font-size: clamp(34px, 3vw, 42px); }                     /* 原 28px（--fs-3xl） */
.pf-front__hero-sub { font-size: clamp(21px, 1.95vw, 27px); line-height: 1.55; } /* 原 20px（--fs-xl） */
.pf-front__eyebrow { font-size: 15px; }                                          /* 原 12px（--fs-sm） */
[data-b01-main="home"] .pf-front__eyebrow { font-size: clamp(14px, 1.25vw, 18px); } /* 原 18px（--fs-lg） */
.pf-front__home-hero-actions { margin-block-start: clamp(22px, 2.8vw, 40px); }   /* 原 --sp-6（24→40px） */
@media (max-width: 767px) {
  .pf-front__hero-title { font-size: 34px; }
  .pf-front__hero-sub { font-size: 22px; }
}

/* ③ 产品页视频块（「一个产品一个视频」；模板 product.js#productVideoBlock） */
.pf-front__product-video { margin-block-start: var(--sp-8); }
.pf-front__product-video .pf-front__section-title { margin-block-end: var(--sp-4); }
.pf-front__product-video-box {
  max-inline-size: 720px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: #000;
  box-shadow: var(--shadow-md);
}
.pf-front__product-video-box video { display: block; inline-size: 100%; block-size: auto; aspect-ratio: 16 / 9; }

/* ============================================================================
 * 第 107p 批（2026-10-15 · 甲方）· 产品描述「规格表」统一样式
 * ----------------------------------------------------------------------------
 * 甲方：表格「整理整齐，没有内容的删掉，整理完整，好看」——内容层已由
 * tools/fix-107p-content.cjs 重建为两列 K-V 表（.pf-spec-table）⇒ 本层给统一样式。
 * ========================================================================== */
.pf-front__prose .pf-spec-table {
  inline-size: min(100%, 680px);
  border: 1px solid var(--border);
  border-collapse: collapse;
  font-size: var(--fs-base);
}
[data-b01-main="product"] .pf-front__prose .pf-spec-table { margin-block: var(--sp-5); }
.pf-front__prose .pf-spec-table td {
  border: 0;
  border-block-end: 1px solid var(--border);
  padding: var(--sp-3) var(--sp-4);
  vertical-align: top;
  text-align: start;
}
.pf-front__prose .pf-spec-table tr:last-child td { border-block-end: 0; }
.pf-front__prose .pf-spec-table .pf-spec-k {
  inline-size: 168px;
  min-inline-size: 168px;
  color: var(--text-muted);
  font-weight: 600;
  background: var(--surface-sunken);
}
.pf-front__prose .pf-spec-table .pf-spec-v { overflow-wrap: anywhere; }
.pf-front__prose .pf-spec-table .pf-spec-v img { max-inline-size: 100%; block-size: auto; }

/* ============================================================================
 * 第 107p 补3（2026-10-15 · 甲方）· 按钮底对齐 + 描述图片统一整齐
 * ----------------------------------------------------------------------------
 * ① 「两个按钮，下来一点，和小视频框平齐」：两列都改 **flex 列 + 底边推齐**——
 *    左列按钮 margin-top:auto 压到列底，右列缩略条同样压底 ⇒ **任意宽度下按钮底边
 *    与小视频框行底边精确对齐**（替代此前按宽度估算的 margin 方案）。
 * ② 「把图片整理整齐…全部排整齐」：正文图片统一 **两列等宽、等高裁切（object-fit:cover）、
 *    圆角**；窄屏改单列。规格表内图片（结构式）豁免。
 * ========================================================================== */
.pf-front__home-hero-copy,
.pf-front__home-hero-media-col { display: flex; flex-direction: column; align-self: stretch; }
.pf-front__home-hero-copy > .pf-front__eyebrow,
.pf-front__home-hero-copy > .pf-front__hero-title,
.pf-front__home-hero-copy > .pf-front__hero-sub { flex: 0 0 auto; }
.pf-front__home-hero-actions { margin-block-start: auto; padding-block-start: clamp(16px, 2vw, 28px); }
.pf-front__home-hero-media-col .pf-front__hero-strip { margin-block-start: auto; padding-block-start: var(--sp-3); }

/* ★★ 第 107aw 批（2026-10-20 · 甲方：「正文图片无法调整大小，前台会自动裁剪」）：
   取消 107p 补3 的「两列等宽等高 + object-fit:cover」**定高裁切**——正文图片改为
   **按原比例完整显示（不裁剪）**；大小由编辑器「图小/图中/图全」写入的 class 控制：
     .pf-img-s ≈ 40% 宽 · .pf-img-m ≈ 62% 宽 · .pf-img-f = 整行 100%。
   旧站遗留的 width/height 属性（如 wscnph 图）会被这里的 CSS 覆盖。 */
.pf-front__prose img {
  inline-size: auto;
  max-inline-size: 100%;
  block-size: auto;
  object-fit: contain;
  display: block;
  margin-block: var(--sp-3);
  border-radius: var(--radius);
}
.pf-front__prose img.pf-img-s { inline-size: 40%; }
.pf-front__prose img.pf-img-m { inline-size: 62%; }
.pf-front__prose img.pf-img-f { inline-size: 100%; }
@media (max-width: 767px) {
  .pf-front__prose img { inline-size: 100%; block-size: auto; }
}
/* 规格表内图片（结构式等）豁免：保持自然尺寸 */
.pf-front__prose .pf-spec-table img {
  inline-size: auto;
  block-size: auto;
  max-inline-size: 100%;
  object-fit: contain;
  display: block;
  margin-block: 0;
}

/* ============================================================================
 * 第 107r 批（2026-10-15 · 甲方）· 全站字号统一：每页正文 ≤3 级
 * ----------------------------------------------------------------------------
 * 甲方：「全部页面字号检查，一篇文章，字号变化不超过 3 种。」
 * 三级体系：h1 = 32px（--fs-3xl）/ h2·章节 = 24px（--fs-2xl）/ 其余全部 = 16px（--fs-base）。
 * 范围：<main> 内容区（文章/产品/FAQ/目录/新闻/方案/单页）；
 *       排除：页头（语言切换 13.3、顶栏 14）、页脚、Hero 展示级（42/27/18，107o 校准）、
 *       表单状态（pf-ok/pf-no）。规格表内图片规则不受影响。
 * ========================================================================== */
main[data-b01-main] :is(h3, h4, h5, h6, p, li, dt, dd, td, th, figcaption):not(.pf-front__eyebrow):not(.pf-front__hero-sub) {
  font-size: var(--fs-base);
}
main[data-b01-main] :is(h3, h4, h5, h6) { font-weight: 700; }
.pf-front__card-title { font-size: var(--fs-base); }
.pf-front__news .pf-front__card-title { font-size: var(--fs-base); }
.pf-front__catalog-num { font-size: var(--fs-base); }
.pf-front__value-title { font-size: var(--fs-base); }
[data-b01-main] .pf-front__btn { font-size: var(--fs-base); }
.pf-front__hero-thumb-badge { font-size: var(--fs-base); line-height: 1.2; padding-block: 2px; }
.pf-front__prose :is(div, .blue-button, .error-code) { font-size: var(--fs-base); }
.pf-front__news-date { font-size: 14px !important; }

/* ============================================================================
 * 第 107r 批 v2（2026-10-15 · 甲方）· 三级字号制（!important 锁定）
 * ----------------------------------------------------------------------------
 * 甲方规则：「一篇文章，字号变化不超过 3 种」⇒ 三级：**28（页标题）/ 18（章节·小标题·导语）/
 * 14（正文·辅助）**。v1 的 var(--fs-base) 方案实测无效（base 实为 14px 且被历史规则压制）
 * ⇒ v2 直接以像素 + !important 锁定（内容区 main 内；**首页 Hero 展示级 42/27/18 例外**——
 * 107o 甲方校准成果，不在「文章」范畴）。UI 控件（按钮/语言切换/徽标）豁免。
 * ========================================================================== */
main[data-b01-main]:not([data-b01-main="home"]) :is(h1) { font-size: 28px !important; }
main[data-b01-main] :is(h2, h3, h4, .pf-front__section-title, .pf-front__lead) { font-size: 18px !important; }
main[data-b01-main] :is(h5, h6, p, li, dt, dd, td, th, figcaption, span, div, a, b, strong, em, small, label):not(.pf-front__eyebrow):not(.pf-front__hero-sub):not(.pf-front__hero-thumb-badge):not(.pf-front__btn):not(:is(h1, h2, h3, h4, .pf-front__section-title, .pf-front__lead) *) {
  font-size: 14px !important;
}

/* ============================================================================
 * 第 107s 批 v2（2026-10-15 · 甲方）· 产品详情页正文强调色统一亮蓝
 * ----------------------------------------------------------------------------
 * 甲方澄清：「我指的是产品详情页里面的内容」——老站迁移的正文内联色（橙标题/橙链接/
 * 蓝段落）⇒ 统一为亮蓝 #1e90ff；正文默认色不变。**模板侧的强调绿已按甲方指令回滚**
 * （107s v1 的全站换蓝作废）。每页内容色 = 深字 + 亮蓝 ≤3 ✓。
 * ========================================================================== */
main[data-b01-main="product"] .pf-front__prose :is([style*="color"], font[color]) { color: #1e90ff !important; }
main[data-b01-main="product"] .pf-front__prose a { color: #1e90ff !important; }


/* ============================================================================
 * 第 107bl 批（2026-10-21 · 甲方：资源文章页内嵌视频）
 * 正文视频块：YouTube / TikTok / Facebook / Instagram 统一 16:9 自适应；
 * 无法嵌入的平台（如分享链接）降级为「前往观看」按钮卡片。
 * ========================================================================== */
.pf-front__video { margin-block: var(--sp-5); }
.pf-front__video iframe,
.pf-front__video video {
  display: block;
  inline-size: 100%;
  aspect-ratio: 16 / 9;
  block-size: auto;
  border: 0;
  border-radius: var(--radius);
  background: #000;
}
.pf-front__video figcaption {
  margin-block-start: var(--sp-2);
  font-size: 0.9rem;
  color: var(--text-muted);
  text-align: center;
}
.pf-front__video-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 18px;
  border-radius: var(--radius);
  background: var(--surface-alt);
  color: var(--accent-fill);
  font-weight: 600;
  text-decoration: none;
}
.pf-front__video-link:hover { background: var(--surface-sunken); }
