/*
 * 首页专属样式 — design/pc/首页.jpg (1920×3468) + design/mobile/首页@2x.png (750×4602)
 * 同 URL、同一 DOM；响应式覆盖 1920 / 1440 / 1366 / 768 / 390 / 375。
 * 区块坐标注释与 docs/10-原型复刻执行地图.md G1-02 一致。
 */

/* ---------------------------------------------------------------- hero · PC y=0..767 / mobile y=100..399@2x
 *
 * 自适应策略：固定比例舞台 + 单一缩放因子。
 *
 * 之前用 `height: 85vh` + `object-fit: cover` 是错的，根因是 hero 里同时存在两套缩放函数：
 *   图走 cover  → 系数 = max(容器宽/1920, 容器高/768)
 *   字走 clamp(vw) → 系数 = 容器宽/1920
 * 两者只有在容器正好 2.5:1 时才相等，而 85vh 几乎保证它不是。实测 1440×900 下
 * 图从左裁掉 472px、字号比图小 25%，成稿留给文案的干净底被吃光，标题压到卡车上。
 * （顺丰能这么写是因为它把文案烤进大图，不存在叠层；我们保留 HTML 叠字就不能抄它的容器策略。）
 *
 * 现在：容器比例锁成图的比例（1920:768 = 750:300 = 5:2，PC/移动同比），cover 不再裁；
 * 所有叠层几何用容器查询单位 cqw，与图共用同一个系数，任意宽度都等比复刻成稿。
 * 用 cqw 而不是 vw：vw 含滚动条宽度，比 hero 实际宽度大约 15px（约 0.8%），
 * 那正好又是"两套缩放函数"的翻版。cqw 量的就是 .hero 自己的宽度。
 *
 * --u = 1 个设计 px。descendant 用 calc(<成稿px> * var(--u)) 表达全部几何，
 * 数字直接就是量到的成稿坐标，改稿时可逐条核对。
 */

.page-home .container--wide {
  width: calc(100% - var(--gutter) * 2);
  margin-inline: auto;
}

.hero {
  /* 100cqw ÷ 1920 —— 只被后代使用（容器自身不能查询自己） */
  --u: 0.05208333cqw;
  position: relative;
  width: 100%;
  aspect-ratio: 1920 / 768;
  container-type: inline-size;
  overflow: hidden;
  background: #eef5fb;
}

.hero__track {
  position: absolute;
  inset: 0;
  min-height: 0;
}

.hero__slide {
  position: absolute;
  inset: 0;
  overflow: hidden;
  opacity: 1;
  transform: translateX(100%);
  transition: transform .5s cubic-bezier(.22, 1, .36, 1);
  pointer-events: none;
  z-index: 0;
}

.hero__slide.is-active {
  transform: translateX(0);
  pointer-events: auto;
  z-index: 2;
}

.hero__slide.is-leave-left {
  transform: translateX(-100%);
  z-index: 1;
}

.hero__slide.is-leave-right {
  transform: translateX(100%);
  z-index: 1;
}

.hero__slide.is-enter-left {
  transform: translateX(-100%);
  transition: none;
  z-index: 2;
}

.hero__slide.is-enter-right {
  transform: translateX(100%);
  transition: none;
  z-index: 2;
}

.hero:not(.is-ready) .hero__slide {
  transition: none;
}

/* 翻页用位移；禁止再给整张 4K 底图做持续缩放。 */

/* 容器比例 = 素材比例，正常素材下 cover 不产生裁切；object-position 只在
   后台传了非 5:2 的 slide 时才生效，取 center（原来的 right 会从左边啃掉文案栏）。 */
.hero__bg {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  opacity: 1;
}

/* 成稿实测：标题 ink x=121..899 / y=209..275，副标题 ink x=119..676 / y=307..326。
   模板上还挂着 .container--wide，这里显式关掉它的宽度与居中。 */
.hero__copy {
  position: absolute;
  left: calc(116 * var(--u));
  /* 成稿位 207，任意宽度都纯比例走，没有兜底 —— 有兜底就意味着某个区间偏离了成稿。
     窄桌面压不到透明页头，是因为页头本身在 769~1040 收到 64px（tokens.css，09-Q25）：
     `207 * --u = --header-h + 16` 的交叉点落在 742px，已经在移动断点以下。 */
  top: calc(207 * var(--u));
  right: auto;
  width: auto;
  max-width: calc(100% - 234 * var(--u));
  margin-inline: 0;
  padding: 0;
  z-index: 2;
}

.hero__slide.is-active .hero__copy {
  animation: hero-copy-in .85s cubic-bezier(.22, 1, .36, 1) .12s both;
}

@keyframes hero-copy-in {
  from { opacity: 0; translate: 0 24px; }
  to { opacity: 1; translate: none; }
}

.hero__title {
  font-size: calc(72 * var(--u));
  line-height: 1;
  color: var(--ink);
}

.hero__title em {
  font-style: normal;
  color: var(--brand);
}

/* 成稿字距 33.6 = 字号 22 + 字间距 11.6 */
.hero__sub {
  margin-top: calc(27 * var(--u));
  font-size: calc(22 * var(--u));
  letter-spacing: calc(11.6 * var(--u));
  line-height: 1;
  color: var(--ink-soft);
}

/* 副标题下的蓝色短线：成稿实测 x=119..182 / y=350..353（64×4），
   横向渐变 srgb(13,71,178) → srgb(69,140,202)。原实现整条漏了。
   移动稿这条的几何和 PC 不成比例（移动标题 ink 高 33/750 vs PC 67/1920），
   需要单独量，归到 T-29，先在 ≤768 关掉。 */
.hero__sub::after {
  content: "";
  display: block;
  width: calc(64 * var(--u));
  height: calc(4 * var(--u));
  margin-top: calc(22 * var(--u));
  margin-left: calc(3 * var(--u));
  background: linear-gradient(90deg, #0d47b2, #458cca);
}

/* hero 底部 5 能力项 · 左栏 HTML（与图内能力环并存，成稿如此）
   成稿实测：圆圈中心 x=147/293/440/585/729（步距 145.5）、中心 y=426、⌀51。
   5 等分栅格 → 左边界 147-145.5/2=74.25，总宽 5×145.5=727.5，图标行 top=400.5。 */
.hero__caps {
  position: absolute;
  left: calc(74.25 * var(--u));
  top: calc(400.5 * var(--u));
  bottom: auto;
  width: calc(727.5 * var(--u));
  max-width: none;
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 0;
  z-index: 2;
  transition: opacity .25s ease, visibility .25s ease;
}

/* 标题、副标题均为空时，该轮播按纯图片展示，不叠固定能力文案。 */
.hero:has(.hero__slide--image-only.is-active) .hero__caps {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

.hero__caps li {
  position: relative;
  display: grid;
  justify-items: center;
  text-align: center;
  gap: 0;
}

/* 项间竖分隔线：成稿实测 x=222/367/513/658、y=410..496（1px，中段最深 srgb(217,224,234)，两端渐隐）。
   贴栅格线画（74.25+145.5k = 219.75/365.25/510.75/656.25，比实测左约 2px），
   不按 slug 逐条补偿——成稿这四个值本身就带 ±1.5px 量测噪声。原实现整组漏了。 */
.hero__caps li + li::before {
  content: "";
  position: absolute;
  left: 0;
  top: calc(9.5 * var(--u));
  width: calc(1 * var(--u));
  height: calc(87 * var(--u));
  background: linear-gradient(180deg,
    rgba(196, 209, 226, .35), rgba(196, 209, 226, 1) 50%, rgba(196, 209, 226, .35));
}

/* T-07：能力项图标走 /img/icons.svg sprite（<use>），不再各引一份 SVG。 */
.hero__caps .icon,
.hero__caps [data-icon] {
  display: block;
  width: calc(51 * var(--u));
  height: calc(51 * var(--u));
  flex: 0 0 auto;
}

/* 成稿实测 ink：粗标签 x=412..467 / y=469..482（4 字），小字 x=400..479 / y=491..501（7 字）。
   字号由渲染反标定而来：CJK advance 恒等于字号，所以 ink 宽 ÷ 字数才是字号，
   按 ink 宽直接除会高估（56/4=14 而非目测的 16）。14.2 / 11.4 是标定后的值。 */
.hero__caps b {
  margin-top: calc(17.5 * var(--u));
  font-size: calc(14.2 * var(--u));
  line-height: 1;
  color: var(--ink);
}

.hero__caps span {
  margin-top: calc(7.8 * var(--u));
  font-size: calc(11.4 * var(--u));
  line-height: 1;
  color: var(--ink-soft);
  white-space: nowrap;
}

/* 轮播点不在成稿里（成稿只有单张 banner），沿用原先 1920 下的观感值 144/34.5 换算成舞台单位 */
.hero__dots {
  position: absolute;
  left: 50%;
  bottom: calc(34.5 * var(--u));
  display: flex;
  gap: calc(18 * var(--u));
  z-index: 3;
  transform: translateX(-50%);
}

.hero__dots button {
  width: calc(12 * var(--u));
  height: calc(12 * var(--u));
  padding: 0;
  border: var(--hairline) solid rgba(255, 255, 255, .85);
  border-radius: 50%;
  background: transparent;
  cursor: pointer;
  transition:
    width .35s cubic-bezier(.22, 1, .36, 1),
    background-color .25s ease,
    border-color .25s ease;
}

.hero__dots button.is-active {
  width: calc(32 * var(--u));
  background: var(--brand);
  border-color: var(--brand);
  border-radius: 999px;
}

/* 左右箭不在成稿里（成稿只有单张 banner）；桌面悬停出现，移动端点按舞台后出现。 */
.hero__arrow {
  position: absolute;
  top: 50%;
  z-index: 3;
  width: calc(48 * var(--u));
  height: calc(48 * var(--u));
  padding: 0;
  border: none;
  border-radius: 50%;
  background: rgba(10, 27, 57, .32);
  cursor: pointer;
  opacity: 0;
  pointer-events: none;
  translate: 0 -50%;
  transition: opacity .2s ease, background-color .2s ease;
}

.hero__arrow::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: calc(10 * var(--u));
  height: calc(10 * var(--u));
  border-top: 2px solid #fff;
  border-right: 2px solid #fff;
}

.hero__arrow--prev { left: calc(24 * var(--u)); }
.hero__arrow--next { right: calc(24 * var(--u)); }
.hero__arrow--prev::before { transform: translate(-35%, -50%) rotate(-135deg); }
.hero__arrow--next::before { transform: translate(-65%, -50%) rotate(45deg); }

.hero:hover .hero__arrow,
.hero__arrow:focus-visible {
  opacity: 1;
  pointer-events: auto;
}

.hero__arrow:hover {
  background: rgba(10, 27, 57, .5);
}

.hero__arrow:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 3px;
}

/* ---------------------------------------------------------------- 运单查询 · PC y=768..855；移动隐藏 */

/*
 * 蓝条 88px。查询胶囊跟下方五张主营业务卡对齐：
 * 左缘 ≈ 第一张卡中线，右缘 ≈ 第三张卡右缘。
 * 右侧搜索钮是贴胶囊上下边的椭圆（不留缝），不要「查询/搜索」文字。
 */
.waybill {
  --biz-gap: 14px;
  --biz-w: min(1680px, calc(100% - 192px));
  --biz-card: calc((var(--biz-w) - 4 * var(--biz-gap)) / 5);
  --biz-left: calc((100% - var(--biz-w)) / 2);
  background: var(--brand);
  height: 88px;
  min-height: 88px;
  padding: 0;
  box-sizing: border-box;
  position: relative;
  z-index: 5;
}

.waybill__form {
  width: calc(var(--biz-card) * 2.5 + var(--biz-gap) * 2);
  max-width: calc(100% - var(--gutter) * 2);
  margin-left: 0;
  margin-right: 0;
  margin-top: 0;
  padding: 0 0 0 20px;
  display: flex;
  align-items: stretch;
  gap: 8px;
  height: 48px;
  min-height: 48px;
  position: absolute;
  left: max(var(--gutter), calc(var(--biz-left) + var(--biz-card) / 2));
  right: auto;
  top: 20px;
  box-sizing: border-box;
  border: var(--hairline) solid #fff;
  border-radius: 999px;
  background: transparent;
  box-shadow: none;
}

/* 贴在 hero 底下，site.js 会把它当首屏直接放行，data-reveal 播不出来。
   只用 CSS 入场；delay 要长过首屏绘制，backwards 填 delay，结束后不 forwards。 */
@keyframes waybill-in {
  from { opacity: 0; translate: 0 28px; }
  to { opacity: 1; translate: none; }
}

@media (prefers-reduced-motion: no-preference) {
  .waybill__form {
    animation: waybill-in .85s cubic-bezier(.22, 1, .36, 1) .32s backwards;
  }
}

.waybill__form input {
  flex: 1;
  min-width: 0;
  height: 100%;
  padding: 0;
  border: 0;
  outline: 0;
  background: transparent;
  color: #fff;
  font-size: 16px;
  line-height: 1;
  font-family: inherit;
  appearance: none;
  -webkit-appearance: none;
  box-shadow: none;
}

.waybill__form input:focus,
.waybill__form input:focus-visible {
  outline: 0;
  box-shadow: none;
}

.waybill__form input::placeholder {
  color: rgba(255, 255, 255, .72);
  opacity: 1;
}

.waybill__form button {
  flex: 0 0 62px;
  width: 62px;
  height: auto;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: #fff;
  color: var(--brand);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  align-self: stretch;
  gap: 0;
  font: inherit;
  line-height: 0;
  box-shadow: none;
  transition: transform .2s ease;
}

.waybill__form button:hover { background: #fff; }
.waybill__form button:active { transform: scale(.96); }

.waybill__form [data-icon="search"] {
  display: block;
  width: 19px;
  height: 19px;
  /* 素材 19×19 / 38×38，墨迹铺满画布、几何居中，不再下移。 */
  background: url("/img/home/home-icon-search.png") 50% 50% / 19px 19px no-repeat;
  background-image: image-set(
    url("/img/home/home-icon-search.png") 1x,
    url("/img/home/home-icon-search@2x.png") 2x
  );
  transition: scale .25s cubic-bezier(.22, 1, .36, 1);
}

@media (hover: hover) and (pointer: fine) {
  .waybill__form button:hover {
    background: #fff;
  }

  .waybill__form button:hover [data-icon="search"] {
    scale: 1.08;
  }
}

.waybill__hint {
  position: absolute;
  left: 0;
  top: 100%;
  max-width: calc(100% - 56px);
  margin: 0;
  padding: 2px 0 0;
  font-size: 12px;
  line-height: 16px;
  color: #fff;
}

.waybill__hint:empty { display: none; }

/* ---------------------------------------------------------------- 主营业务 · PC y=856..1512 / mobile y=400..2053@2x */

.biz {
  background: var(--bg-page);
  padding-bottom: 0;
}

/*
 * 五张卡在成稿上是均匀网格，不是非均匀坐标：
 * y=1200 整行扫描得 x=130/476/822/1168/1514，每张宽 332，步距 346（间距 14），
 * 上下边 1043..1442（高 400），五张完全一致。跨度 130..1845 = 1716px。
 * 之前按"非均匀"读稿并用 per-card translate 逐张补偿，是对同一处误差的二次拟合。
 *
 * 8.20：标题与五卡改为居中（推翻 Q2 左偏）。width 仍按成稿 1716。
 */
.page-home .biz__grid {
  width: min(1680px, calc(100% - 192px));
  max-width: none;
  margin-inline: auto;
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 14px;
  margin-top: 38px;
}

.page-home .biz .section-title {
  transform: none;
}

.page-home .biz .section-title__text {
  font-size: var(--section-title-size);
  line-height: 44px;
}

.page-home .biz .section-title__rule {
  transform: translateY(-2px);
}

/* 悬停阴影放在 li，避免 a 上 overflow:hidden 裁掉 drop-shadow；
   container 建在 li 上，避免 a 自引用 cqw 落到视口（会变成 ~110px）。 */
.biz__card {
  container-type: inline-size;
  container-name: biz-card;
  transition: translate .38s cubic-bezier(.22, 1, .36, 1), filter .38s ease;
}

.biz__card a {
  position: relative;
  display: block;
  /* UI 原图圆角：@2x R≈38 → @1x 19（332 宽卡） */
  border-radius: 5.72cqw;      /* 19/332，相对 .biz__card */
  overflow: hidden;
}

.biz__card img {
  width: 100%;
  height: auto;
  aspect-ratio: 332 / 400;   /* 成稿实测 332×400，不是 334×392 */
  object-fit: cover;
  display: block;
  border-radius: inherit;
  transition: scale .38s cubic-bezier(.22, 1, .36, 1);
}

/* UI 无字底图偏亮；叠一层底部暗蓝渐变，保证白字对比（对齐原烤字稿） */
.biz__card a::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    180deg,
    rgba(5, 32, 84, 0) 38%,
    rgba(5, 32, 84, .42) 62%,
    rgba(5, 32, 84, .88) 100%
  );
  pointer-events: none;
  z-index: 1;
}

/*
 * 文案落点对齐旧烤字位图（332×400 实测）：
 * 标题起点 y≈215 x≈33；单行标题时绿条 y≈261、摘要 y≈287。
 * 块从标题起点流式排布：中文单行与烤字对齐；英文折行时绿条/摘要随标题下移。
 */
.biz__copy {
  position: absolute;
  top: 53.75%;                 /* 215/400 */
  left: 9.94%;                 /* 33/332 */
  right: 9.94%;
  bottom: 4%;
  z-index: 2;
  color: #fff;
  pointer-events: none;
}

.biz__name {
  margin: 0;
  font-size: 8.13cqw;          /* 27/332：烤字「临床供应链」宽≈137 → ≈27.4/字 */
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: .02em;
}

.biz__rule {
  display: block;
  width: 9.34cqw;              /* 31/332 */
  height: 1.2cqw;              /* 4/332 */
  /* 单行标题底≈242 → 绿条 261：间距 ≈19；实测再收 1.3px */
  margin: 5.33cqw 0 0;
  background: var(--accent);
}

.biz__summary {
  margin: 6.63cqw 0 0;         /* 绿条底≈265 → 摘要 287：间距 ≈22 */
  font-size: 5.27cqw;          /* 17.5/332：贴近烤字首行 263px / 15 字 */
  font-weight: 400;
  line-height: 1.771;          /* 31/17.5：烤字行起点 287→318→348 */
  color: rgba(255, 255, 255, .92);
}

@media (hover: hover) and (pointer: fine) {
  /* reveal 终态 `translate: none` 选择器更重，不抬权重的话悬停上浮会被吃掉。 */
  html.motion-ready [data-reveal-group].is-revealed > .biz__card:hover,
  html.motion-ready [data-reveal-group].is-revealed > .biz__card:focus-within,
  .biz__card:hover,
  .biz__card:focus-within {
    translate: 0 -10px;
    filter: drop-shadow(0 16px 22px rgba(10, 27, 57, .18));
  }

  .biz__card:hover img,
  .biz__card:focus-within img {
    scale: 1.08;
  }

  /* 能力卡 overflow:hidden，悬停只用 transform 上浮，避免阴影被裁、也不跟入场 translate 抢属性。 */
  html.motion-ready .page-home .caps__card.is-revealed:hover,
  html.motion-ready .page-home .caps__card.is-revealed:focus-within {
    transform: translateY(-8px);
  }
  html.motion-ready .page-home .caps__card.is-revealed:hover .caps__icon,
  html.motion-ready .page-home .caps__card.is-revealed:focus-within .caps__icon {
    transition-delay: 0ms;
    scale: 1.08;
  }
  html.motion-ready .page-home .caps__card.is-revealed:hover .caps__photo,
  html.motion-ready .page-home .caps__card.is-revealed:focus-within .caps__photo {
    transition-delay: 0ms;
    scale: 1.06;
  }
}

html.motion-ready .page-home .caps__card.is-revealed:active {
  transform: translateY(-6px);
}
html.motion-ready .page-home .caps__card.is-revealed:active .caps__icon {
  scale: 1.08;
}

@media (prefers-reduced-motion: no-preference) {
  html.motion-ready .page-home [data-reveal],
  html.motion-ready .page-home [data-reveal-group] > * {
    translate: 0 36px;
  }
  html.motion-ready .page-home [data-reveal="left"] { translate: -36px 0; }
  html.motion-ready .page-home [data-reveal="right"] { translate: 36px 0; }
  html.motion-ready .page-home [data-reveal].is-revealed,
  html.motion-ready .page-home [data-reveal-group].is-revealed > * {
    opacity: 1;
    translate: none;
    transition:
      opacity .85s cubic-bezier(.22, 1, .36, 1),
      translate .85s cubic-bezier(.22, 1, .36, 1);
  }
  html.motion-ready .biz__grid[data-reveal-group] > :nth-child(2) { transition-delay: 100ms; }
  html.motion-ready .biz__grid[data-reveal-group] > :nth-child(3) { transition-delay: 200ms; }
  html.motion-ready .biz__grid[data-reveal-group] > :nth-child(4) { transition-delay: 300ms; }
  html.motion-ready .biz__grid[data-reveal-group] > :nth-child(5) { transition-delay: 400ms; }

  /* 核心能力：每张卡独立入场；PC 三列从左错峰，移动端竖排各自从下方出现。 */
  html.motion-ready .page-home .caps .section-title[data-reveal]:not(.is-revealed) .section-title__rule {
    scale: .18 1;
  }
  html.motion-ready .page-home .caps .section-title[data-reveal].is-revealed .section-title__rule {
    scale: 1;
    transition: scale .7s cubic-bezier(.22, 1, .36, 1) .16s;
  }

  html.motion-ready .page-home .caps__grid[data-reveal-from="x"] > [data-reveal] {
    translate: -42px 0;
  }
  html.motion-ready .page-home .caps__grid[data-reveal-from="x"] > .is-revealed {
    translate: none;
    transition:
      opacity .85s cubic-bezier(.22, 1, .36, 1) calc(var(--reveal-i, 0) * 90ms),
      translate .85s cubic-bezier(.22, 1, .36, 1) calc(var(--reveal-i, 0) * 90ms),
      transform .32s cubic-bezier(.22, 1, .36, 1);
  }
  html.motion-ready .page-home .caps__card[data-reveal-replay]:not(.is-revealed) {
    transition:
      opacity .55s cubic-bezier(.22, 1, .36, 1),
      translate .55s cubic-bezier(.22, 1, .36, 1),
      transform .32s cubic-bezier(.22, 1, .36, 1);
  }
  html.motion-ready .page-home .caps__grid[data-reveal-from="x"] > :nth-child(1) { --reveal-i: 0; }
  html.motion-ready .page-home .caps__grid[data-reveal-from="x"] > :nth-child(2) { --reveal-i: 1; }
  html.motion-ready .page-home .caps__grid[data-reveal-from="x"] > :nth-child(3) { --reveal-i: 2; }
  html.motion-ready .page-home .caps__grid[data-reveal-from="x"] > :nth-child(4) { --reveal-i: 3; }
  html.motion-ready .page-home .caps__grid[data-reveal-from="x"] > :nth-child(5) { --reveal-i: 4; }
  html.motion-ready .page-home .caps__grid[data-reveal-from="x"] > :nth-child(6) { --reveal-i: 5; }

  html.motion-ready .page-home .caps__card[data-reveal] .caps__photo {
    scale: 1.1;
  }
  html.motion-ready .page-home .caps__card.is-revealed .caps__photo {
    scale: 1;
    transition: scale 1.15s cubic-bezier(.22, 1, .36, 1);
    transition-delay: calc(var(--reveal-i, 0) * 90ms);
  }

  html.motion-ready .page-home .caps__card[data-reveal] .caps__icon {
    opacity: 0;
    scale: .68;
  }
  html.motion-ready .page-home .caps__card.is-revealed .caps__icon {
    opacity: 1;
    scale: 1;
    transition:
      opacity .55s cubic-bezier(.22, 1, .36, 1),
      scale .55s cubic-bezier(.34, 1.45, .64, 1);
    transition-delay: calc(var(--reveal-i, 0) * 90ms + 140ms);
  }

  html.motion-ready .page-home .caps__card[data-reveal] .caps__panel h3,
  html.motion-ready .page-home .caps__card[data-reveal] .caps__en {
    opacity: 0;
    translate: 0 12px;
  }
  html.motion-ready .page-home .caps__card.is-revealed .caps__panel h3,
  html.motion-ready .page-home .caps__card.is-revealed .caps__en {
    opacity: 1;
    translate: none;
    transition:
      opacity .5s cubic-bezier(.22, 1, .36, 1),
      translate .5s cubic-bezier(.22, 1, .36, 1);
  }
  html.motion-ready .page-home .caps__card.is-revealed .caps__panel h3 {
    transition-delay: calc(var(--reveal-i, 0) * 90ms + 200ms);
  }
  html.motion-ready .page-home .caps__card.is-revealed .caps__en {
    transition-delay: calc(var(--reveal-i, 0) * 90ms + 260ms);
  }

  html.motion-ready .page-home .caps__card[data-reveal] .caps__points li {
    opacity: 0;
    translate: -12px 0;
  }
  html.motion-ready .page-home .caps__card.is-revealed .caps__points li {
    opacity: 1;
    translate: none;
    transition:
      opacity .45s cubic-bezier(.22, 1, .36, 1),
      translate .45s cubic-bezier(.22, 1, .36, 1);
  }
  html.motion-ready .page-home .caps__card.is-revealed .caps__points li:nth-child(1) {
    transition-delay: calc(var(--reveal-i, 0) * 90ms + 300ms);
  }
  html.motion-ready .page-home .caps__card.is-revealed .caps__points li:nth-child(2) {
    transition-delay: calc(var(--reveal-i, 0) * 90ms + 360ms);
  }
  html.motion-ready .page-home .caps__card.is-revealed .caps__points li:nth-child(3) {
    transition-delay: calc(var(--reveal-i, 0) * 90ms + 420ms);
  }
  html.motion-ready .page-home .caps__card.is-revealed .caps__points li:nth-child(4) {
    transition-delay: calc(var(--reveal-i, 0) * 90ms + 480ms);
  }

  html[data-layout="mobile"].motion-ready .page-home .caps__grid[data-reveal-from="x"] > [data-reveal] {
    translate: 0 32px;
  }
  html[data-layout="mobile"].motion-ready .page-home .caps__grid[data-reveal-from="x"] > .is-revealed {
    --reveal-i: 0;
    translate: none;
    transition-delay: 0ms;
  }
  html[data-layout="mobile"].motion-ready .page-home .caps__card[data-reveal] .caps__points li {
    translate: 0 10px;
  }
}

/* ---------------------------------------------------------------- 核心能力 · 首页2.0 PC y=1554..2469 / 375 y=973..1895 */

.caps {
  --u: 0.05208333cqw;
  container-type: inline-size;
  background: var(--bg-page);
  padding-bottom: calc(80 * var(--u));
}

.caps .section-title {
  padding-top: calc(60 * var(--u));
}

.caps .section-title__rule {
  margin-top: calc(8 * var(--u));
}

.caps__grid {
  display: grid;
  width: calc(1716 * var(--u));
  max-width: calc(100% - 204 * var(--u));
  margin: calc(78 * var(--u)) auto 0;
  padding: 0;
  list-style: none;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  column-gap: calc(30 * var(--u));
  row-gap: calc(29 * var(--u));
}

.caps__card {
  position: relative;
  height: calc(304 * var(--u));
  border-radius: calc(12 * var(--u));
  overflow: hidden;
  background: #f2f8ff;
  box-shadow: 0 0 6px rgba(3, 99, 178, .2);
}

.caps__photo {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: right center;
  display: block;
}

/* 稿：矩形 3 铺满整卡 552×304，linear-gradient(204.96deg, transparent → #F2F8FF 95%) */
.caps__card::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(204.96deg, rgba(242, 248, 255, 0) 0%, rgba(242, 248, 255, .95) 100%);
}

.caps__panel {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: calc(64 * var(--u)) minmax(0, 1fr);
  column-gap: calc(18 * var(--u));
  align-content: start;
  height: 100%;
  padding: calc(30 * var(--u)) calc(12 * var(--u)) calc(30 * var(--u)) calc(30 * var(--u));
  background: linear-gradient(202.11deg, rgba(242, 248, 255, 0) 0%, rgba(242, 248, 255, 0.95) 100%);
}

.caps__icon {
  grid-row: 1 / 3;
  width: calc(64 * var(--u));
  height: calc(64 * var(--u));
  object-fit: contain;
}

.caps__panel h3 {
  margin: 0;
  font-size: calc(24 * var(--u));
  font-weight: 700;
  line-height: 1.25;
  color: var(--ink);
}

.caps__en {
  margin: calc(4 * var(--u)) 0 0;
  font-size: calc(18 * var(--u));
  line-height: 1.2;
  font-weight: 400;
  color: var(--ink-soft);
}

.caps__points {
  grid-column: 1 / -1;
  margin: calc(24 * var(--u)) 0 0;
  padding: 0;
  list-style: none;
}

.caps__points li {
  position: relative;
  padding-left: calc(28 * var(--u));
  font-size: calc(18 * var(--u));
  line-height: calc(36 * var(--u));
  color: var(--ink);
  white-space: nowrap;
}

.caps__points li::before {
  content: "";
  position: absolute;
  left: calc(10 * var(--u));
  top: calc(15 * var(--u));
  width: calc(6 * var(--u));
  height: calc(6 * var(--u));
  border-radius: 50%;
  background: var(--brand);
}

/* ---------------------------------------------------------------- 服务网络 · PC y=1513..2266 / mobile y=2054..3029@2x */

.network {
  --network-bg: var(--navy);
  background: var(--network-bg);
  color: #fff;
  /* 高度随地图比例盒走；写死高度会在响应式缩放后产生底部空带。 */
  height: auto;
  padding: 0;
}

/* 版心盒与主营业务同源：min(1680, 100%-192) 居中，令统计栏左缘=第一张卡左缘、
   地图右缘=最后一张卡右缘，全宽区间两端恒对齐（背景仍整屏铺满）。
   容器基准与 --u 从 .network（全屏）迁到本盒：--u = 盒宽/1680，
   即设计稿 x=120..1800（五卡盒）映射到盒 0..100%；横向定位值随之减去原点 120。 */
.network__inner {
  container-type: inline-size;
  --u: 0.05952381cqw;
  /* DOM 上并挂了 .container（max-width:1200）：必须显式解除，否则版心盒被压到 1200。 */
  max-width: none;
  width: min(1680px, calc(100% - 192px));
  margin-inline: auto;
  padding-inline: 0;
  display: grid;
  grid-template-columns: minmax(0, min(600px, 36%)) minmax(0, 1fr);
  /* 行高始终由地图层的成稿比例盒决定；统计栏只跟随行高，不反向拉伸地图。 */
  align-items: stretch;
  gap: 0;
}

.network__stats {
  /* 与地图层同格：地图横跨整行铺在底下，统计栏浮在左侧，因此这里不能再自带不透明底。 */
  grid-area: 1 / 1 / 2 / 2;
  position: relative;
  z-index: 1;
  padding-top: calc(47 * var(--u));
  /* 末行数字到底边：成稿 55px；用 --u 让 1680 版心缩小时同比收。 */
  padding-bottom: calc(55 * var(--u));
  background: transparent;
}

/* 左边距相对版心盒：图标圆左缘贴盒左（=第一张卡左缘），标题/线/数字较图标内收 12（设计稿 132-120）。
   数字走 --u（=盒宽/1680），769~1919 随盒收，不再另开 1870 clamp 档。 */
.network__title {
  margin-top: calc(8 * var(--u));
  margin-left: calc(12 * var(--u));
  font-size: calc(36 * var(--u));
  line-height: calc(44 * var(--u));
  transform: translateY(calc(-8 * var(--u)));
}

.network__rule::before { background: var(--brand); }
.network__rule::after  { background: var(--accent); }

.network__rule {
  justify-content: flex-start;
  margin-left: calc(12 * var(--u));
  transform: translateY(calc(-6 * var(--u)));
}

.network__figures {
  display: contents;
}

.network__major {
  display: grid;
  grid-template-columns: 1fr;
  gap: calc(38 * var(--u));
  margin-top: calc(37 * var(--u));
  margin-left: 0;
}

.network__major li {
  display: grid;
  grid-template-columns: calc(72 * var(--u)) 1fr;
  grid-template-rows: auto auto;
  column-gap: calc(20 * var(--u));
  align-items: center;
}

.network__major [data-icon] {
  grid-row: 1 / span 2;
  width: calc(72 * var(--u));
  height: calc(72 * var(--u));
  background: center / contain no-repeat;
}

.network__major [data-icon="globe"]    { background-image: url("/img/home/home-icon-globe.png"); }
.network__major [data-icon="building"] { background-image: url("/img/home/home-icon-building.png"); }

.network__major b {
  font-size: calc(40 * var(--u));
  line-height: 1.1;
  color: var(--accent);
}

.network__major span {
  font-size: 16px;
  color: #fff;
}

.network__minor {
  position: relative;
  display: grid;
  grid-template-columns: repeat(2, calc(200 * var(--u)));
  gap: calc(53 * var(--u)) calc(20 * var(--u));
  margin-left: calc(12 * var(--u));
  margin-top: calc(40 * var(--u));
}

.network__minor::before {
  content: "";
  position: absolute;
  top: calc(99 * var(--u));
  left: 0;
  width: calc(444 * var(--u));
  height: var(--hairline);
  background: #253e66;
  box-shadow: 0 calc(121 * var(--u)) 0 #253e66;
}

.network__minor b {
  display: block;
  font-size: calc(30 * var(--u));
  line-height: 1.2;
  color: var(--accent);
}

.network__minor span {
  display: block;
  margin-top: calc(4 * var(--u));
  font-size: 16px;
  color: #fff;
}

/* PC 为两列三行；移动稿改为三列两行，因此两端对第 4/5 项采用不同视觉顺序。 */
.network__minor li:nth-child(1) { order: 1; }
.network__minor li:nth-child(2) { order: 2; }
.network__minor li:nth-child(3) { order: 3; }
.network__minor li:nth-child(4) { order: 5; }
.network__minor li:nth-child(5) { order: 4; }
.network__minor li:nth-child(6) { order: 6; }

/* 地图层横跨整行（不只右列）：成稿里地图左缘在 x=505，压在统计栏那一列的右段，
   只有让它跨列才能复刻这段衔接——限在右列内会在统计栏与大陆之间留一条空海带。
   aspect-ratio 只作行高下限（按成稿 1920×753）；上下溢出由本层裁掉。
   width:100% 必须显式写：版心盒收到 1680 后，盒宽算出的地图高（≈盒宽×753/1920）会小于
   统计栏内容高（6 个次要数字排三行时约 695），行被内容撑高；此时若地图宽度是 auto，
   aspect-ratio 会按被撑高的行高反算出更大的宽度（实测 1772 > 1680）向右溢出盒外。
   钉死 width:100% 让宽度恒等于版心盒，aspect-ratio 只能算高，右缘稳定=最后一张卡右缘。 */
.network__map {
  grid-area: 1 / 1 / 2 / -1;
  position: relative;
  min-width: 0;
  width: 100%;
  aspect-ratio: 1920 / 753;
  overflow: hidden;
  background: var(--network-bg);
}

/* 成稿标定（互相关拟合 design/pc/首页.jpg y=1513..2266 与本素材，见 docs/10 2026-08-15）：
   地图 1360×777 落在成稿 (505, -18)。百分比现相对 .network__inner 版心盒（=五卡盒，成稿 x=120..1800）：
   左 (505-120)/1680=22.9167%；右缘按需求钉到盒右=最后一张卡右缘，故宽收到 77.0833%
   （右缘 22.9167+77.0833=100%，比成稿右缘 1865 收进 65px@1920，是对设计稿的有意覆盖，见 docs/09）。
   translate 用自身高度的百分比，与容器高度无关，纵向裁切量不随行高漂移。
   底图与 SVG 都锚在本盒 inset:0，比例盒不变，路线与地图的相对关系一像素不动。 */
.network__art {
  position: absolute;
  top: 0;
  left: 22.9167%;
  width: 77.0833%;
  aspect-ratio: 1660 / 948;
  translate: 0 -2.3175%;
  overflow: hidden;
  background: var(--network-bg);
}

.network__art picture {
  position: absolute;
  inset: 0;
  display: block;
  z-index: 0;
}

.network__art img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: fill;
}

.network__map.is-map-missing .network__art img {
  opacity: 0;
}

/* 地图左缘并非每一行都等于底色，硬接会露一条亮缝；在素材之上做短羽化，
   只把左缘那片海过渡回同一个 --network-bg，不改地图主体或线路坐标。
   上限 69px：左缘往右约 77px 就是北美西海岸的城市光带（成稿 x≈582），糊到那里就丢内容了。 */
.network__art::after {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  z-index: 1;
  width: calc(69 * var(--u));
  background: linear-gradient(90deg, var(--network-bg) 0%, rgba(0, 18, 58, .72) 45%, transparent 100%);
  pointer-events: none;
}

/* 右缘同理：地图最右一列的洋色逐行在 rgb(0,16,51)~(0,18,61) 间浮动，与超宽屏右侧露出的
   纯色 --network-bg 留白硬接时，MacBook 等 P3 面板在近黑端能分辨这 ±几单位，显一条随行
   起伏的竖缝（普通 sRGB 外接屏把暗部压死，看不出，故双屏表现不一致）。单一纯色不可能同时
   贴合一条本身在变的边缘——正解是在素材右缘之上做短羽化，把最外缘那片海强制融回同一
   --network-bg：硬边界消失，且因底色≈洋色，这段过渡本身不可见。
   宽度只取 14u：右缘往里约 13u（≈26px@素材）就是澳洲东岸/新西兰灯带，再宽会糊到内容
   （尾部到灯带处约 9% 不透明，可忽略）。-mobile 素材裁切不同、右缘没有这条缝，
   所以这段只在 PC 布局（≥640）生效。 */
html:not([data-layout="mobile"]) {
  .network__art::before {
    content: "";
    position: absolute;
    inset: 0 0 0 auto;
    z-index: 1;
    width: calc(14 * var(--u));
    background: linear-gradient(90deg, transparent 0%, rgba(0, 18, 58, .72) 55%, var(--network-bg) 100%);
    pointer-events: none;
  }
}

/* 动态辐射层：底图与 SVG 始终共用 `.network__art` 的同一个二维变换。
   唯一枢纽为广州 (1316,441)，脉冲永远由枢纽流向城市并循环，不再一次性播完停住。
   性能约束（移动端反馈打开卡顿）：本层不再使用 SVG 滤镜与 mix-blend-mode——
   两者都会让每一帧重算整层；发光改由线宽与亮色承担。 */
.network__routes {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
}

/* 常驻底线：始终画满整条航线。密虚线 + 高不透明度是「线路要更明显」的落点，
   稀疏点线在夜景底图的亮区上会被灯光淹掉。 */
.network__route-line {
  fill: none;
  stroke: rgba(150, 232, 255, .58);
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-dasharray: .022 .026;
  vector-effect: non-scaling-stroke;
}

/* 脉冲：一小段亮线沿同一条 d 由 dashoffset 1 → 0 推进，方向恒为广州 → 城市。 */
.network__route-pulse {
  fill: none;
  stroke: #d5f4ff;
  stroke-width: 3.8;
  stroke-linecap: round;
  stroke-dasharray: .075 .925;
  stroke-dashoffset: 1;
  vector-effect: non-scaling-stroke;
  opacity: 0;
}

.network__route-dot {
  fill: #a9f4ff;
  opacity: .7;
  transform-box: fill-box;
  transform-origin: center;
}

.network__hub-wave {
  fill: none;
  stroke: rgba(142, 237, 255, .9);
  stroke-width: 2;
  vector-effect: non-scaling-stroke;
  transform-box: fill-box;
  transform-origin: center;
}

.network__hub-core { fill: #fff; }

/* live 由 home.js 在底图解码完成且区块进入视口后打开；
   离屏或切到后台只加 .is-paused 冻结相位，不销毁动画。
   出发间隔 .14s × 21 条 ≈ 一个完整周期：本轮还没发完下一轮就接上，
   任何时刻画面里都有在途脉冲，不会出现「辐射一下就停」的空档。 */
.network__routes[data-network-state="live"] .network__route-pulse {
  animation: network-pulse-travel 2.8s linear infinite;
  animation-delay: calc(var(--i, 0) * .14s);
}

/* 落点闪一下：与脉冲同时长同延迟，靠关键帧位置对齐“脉冲抵达”那一刻。 */
.network__routes[data-network-state="live"] .network__route-dot {
  animation: network-dot-arrive 2.8s linear infinite;
  animation-delay: calc(var(--i, 0) * .14s);
}

.network__routes[data-network-state="live"] .network__hub-wave {
  animation: network-hub-wave 1.7s ease-out infinite;
}

.network__routes[data-network-state="live"] .network__hub-wave--outer {
  animation-delay: .9s;
}

.network__routes.is-paused * { animation-play-state: paused; }

/* 静态态 = 无 JS / 减少动画 / 底图失败时的终态：底线与城市点全部可见，只是不播放。 */
.network__routes[data-network-state="static"] .network__route-pulse { display: none; }
.network__routes[data-network-state="static"] .network__route-dot { opacity: .8; }
.network__routes[data-network-state="static"] .network__hub-wave { display: none; }

@keyframes network-pulse-travel {
  0% { stroke-dashoffset: 1; opacity: 0; }
  8% { opacity: 1; }
  52% { opacity: 1; }
  60% { stroke-dashoffset: 0; opacity: 0; }
  100% { stroke-dashoffset: 0; opacity: 0; }
}

@keyframes network-dot-arrive {
  0%, 54% { opacity: .62; scale: 1; }
  62% { opacity: 1; scale: 2; }
  74%, 100% { opacity: .62; scale: 1; }
}

@keyframes network-hub-wave {
  0% { opacity: .9; scale: .35; }
  75%, 100% { opacity: 0; scale: 1.45; }
}

/* ---------------------------------------------------------------- 合作案例 · PC y=2268..2813 / mobile y=3030..3493@2x */

.partners {
  background: var(--bg-page);
  padding-bottom: 56px;
}

/* 标题 ink 距区块顶 60（全局 section-title 是 77，只覆盖本块）。 */
.partners .section-title {
  padding-top: 60px;
}

/* 成稿块宽 1298 ≠ --container 的 1200，模板上的 .container 只借它的居中，宽度按实测覆盖。
   container-type + cqi：列宽必须相对 viewport 定宽。若用 % 配 width:max-content，
   多页时百分比基线会跟着 max-content 膨胀（T-29 实测 375 下卡宽 269，应为 ~109）。 */
.partners__viewport {
  max-width: 1298px;
  width: calc(100% - var(--gutter) * 2);
  padding: 0;
  margin-top: 40px;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  -webkit-overflow-scrolling: touch;
  container-type: inline-size;
  /* 翻页靠下方短横条；原生横向滚动条会压住底排 logo（移动端尤其明显） */
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.partners__viewport::-webkit-scrollbar {
  width: 0;
  height: 0;
  display: none;
}

.partners__viewport.is-paging {
  overflow: hidden;
}

.partners__viewport:focus-visible {
  outline-offset: 4px;
}

/* 成稿实测（design/pc/首页.jpg）：卡片 250×120，横纵间距均 12，两排 5 列
   → 块宽 5×250 + 4×12 = 1298，左界 (1920-1298)/2 = 311，卡片行 y=2456..2575 / 2588..2707。
   这是均匀网格，同 .biz__grid 口径：只调网格参数，不做逐张补偿。 */
.partners__grid {
  display: grid;
  grid-template-rows: repeat(2, auto);
  grid-auto-flow: column;
  grid-auto-columns: calc((100cqi - 48px) / 5);
  gap: 12px;
  width: max-content;
  min-width: 100%;
}

.partners__grid li {
  /* 默认不吸附：每张卡都 snap 会把「整页翻」卡在半页（移动 3 列/页时尤甚）。
     只在每页第一列的两张卡上开 snap，见下方 nth-child。 */
  scroll-snap-align: none;
  display: grid;
  place-items: center;
  min-width: 0;          /* 防止 grid 项按内容把列撑开 */
  min-height: 120px;
  padding: 12px;
  background: var(--bg-white);
  border-radius: var(--radius);
  overflow: hidden;      /* logo 再宽也不得溢出叠到邻格 */
  transition: translate .35s cubic-bezier(.22, 1, .36, 1), box-shadow .35s ease;
}

/* PC：每页 5 列 × 2 行 = 10 张；第 10n+1/10n+2 是该页第一列 */
.partners__grid li:nth-child(10n + 1),
.partners__grid li:nth-child(10n + 2) {
  scroll-snap-align: start;
}

/* 五张卡的 logo ink 实测 133~145 宽 / 35~48 高 —— 约束的是 logo 尺寸上限，不是卡内边距。
   max-width 必须同时吃「成稿上限」和「卡内可用宽」，否则宽幅 PNG（含白底）会撑出格子。 */
.partners__grid img {
  display: block;
  max-height: 48px;
  max-width: min(145px, 100%);
  width: auto;
  height: auto;
  margin: 0 auto;
  object-fit: contain;
  transition: scale .35s cubic-bezier(.22, 1, .36, 1);
}

.partners__grid li.is-missing img {
  display: none;
}

.partners__fallback {
  display: none;
}

.partners__grid li.is-missing .partners__fallback {
  display: block;
  color: #64748b;
  font-size: 15px;
  line-height: 1.4;
  text-align: center;
}

@media (hover: hover) and (pointer: fine) {
  .partners__grid li:hover {
    translate: 0 -6px;
    box-shadow: 0 14px 28px rgba(10, 27, 57, .11);
  }

  .partners__grid li:hover img { scale: 1.04; }
}

/* 底栏短横条：胶囊形，当前页蓝、其余灰。条数跟着页数走，由 home.js 生成。 */
.partners__controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: 31px;
}

.partners__controls[hidden] {
  display: none;
}

.partners__dot {
  width: 28px;
  height: 6px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: #ddd;
  cursor: pointer;
  transition: background .25s ease;
}

.partners__dot[aria-current="true"] { background: #0064b4; }

/* ---------------------------------------------------------------- CTA · PC y=2814..3083；移动隐藏 */

.cta {
  min-height: 269px;
  /* 底色兜底：bg 透明时，与上一节接缝落在亚像素会透出 body 白底，出现 1px 亮线 */
  background: #584f8d url("/img/home/cta-bg.webp") center / cover no-repeat;
}

.cta__inner {
  min-height: inherit;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 20px;
  text-align: center;
  padding: 40px var(--gutter);
}

/* 成稿：白描边幽灵按钮 + 白说明文；背景用干净 UI 素材，字不烤进图。 */
.cta__btn {
  min-width: 180px;
  background: transparent;
  border-color: #fff;
  color: #fff;
}

.cta__btn:hover {
  background: #fff;
  color: var(--brand);
}

.cta__inner p {
  font-size: 16px;
  color: #fff;
}

.message-dialog {
  width: min(720px, calc(100% - 48px));
  padding: 0;
  border: 0;
  border-radius: 12px;
  background: #fff;
  box-shadow: 0 16px 48px rgba(0, 0, 0, .18);
}

.message-dialog::backdrop {
  background: rgba(1, 21, 65, .45);
}

.message-dialog__form {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  padding: 28px 32px 32px;
}

.message-dialog__head {
  grid-column: 1 / -1;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
}

.message-dialog__head h2 {
  margin: 0;
  font-size: 24px;
  color: var(--brand);
}

.message-dialog__close {
  width: 36px;
  height: 36px;
  border: 0;
  background: transparent;
  font-size: 28px;
  line-height: 1;
  color: var(--ink-soft);
  cursor: pointer;
}

.message-dialog__sub {
  grid-column: 1 / -1;
  margin: 0;
  font-size: 14px;
  color: var(--ink-soft);
}

.message-dialog .contact-form__field {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.message-dialog .contact-form__field--full {
  grid-column: 1 / -1;
}

.message-dialog .contact-form__field .req {
  position: absolute;
  left: 8px;
  top: 14px;
  color: #c00;
  z-index: 1;
}
.message-dialog .contact-form__field:has(.req) input {
  padding-left: 22px;
}

.message-dialog .contact-form input,
.message-dialog .contact-form textarea {
  width: 100%;
  box-sizing: border-box;
  border: var(--hairline) solid var(--line);
  border-radius: 0;
  padding: 12px 14px;
  font: inherit;
}

.message-dialog .contact-form__submit {
  grid-column: 1 / -1;
  justify-self: start;
}

.message-dialog .contact-form__hint {
  grid-column: 1 / -1;
  margin: 0;
  min-height: 1.4em;
  font-size: 13px;
  color: var(--brand);
}

/* 769~1280 窄桌面（含 iPad 横屏）：五列把卡压到 104(769)~218(1280) 宽，
   卡内标题/摘要按 cqw 跟着缩到 8~13px，读不了。同一 DOM 改三行列，
   左右与页头导航齐平（服务页 / 关于我们 / 新闻同界）。这一带没有成稿。
   用 flex 不用 grid：5 张卡排三列时末行只剩 2 张，grid 会把它们钉在左边留一个空格子，
   flex + justify-content:center 让末行两张居中，看着是有意的收尾。
   卡宽封顶成稿的 332，1280 下不会把卡吹到比 1920 稿还大。 */
/* 停用 2026-09-01：双稿改造后不再有中间过渡档，见 docs/14。
   复活时把条件改回 (min-width: 769px) and (max-width: 1280px)。 */
@media not all {
  .waybill {
    --biz-w: calc(100% - 2 * var(--header-pad-x));
    --biz-row: min(var(--biz-w), calc(3 * 332px + 2 * var(--biz-gap)));
    --biz-card: min(332px, calc((var(--biz-row) - 2 * var(--biz-gap)) / 3));
    --biz-left: calc(var(--header-pad-x) + (var(--biz-w) - var(--biz-row)) / 2);
  }

  .page-home .biz__grid {
    width: calc(100% - 2 * var(--header-pad-x));
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
  }

  .page-home .biz__card {
    flex: 0 1 calc((100% - 2 * 14px) / 3);
    max-width: 332px;
  }
}

/* 页头这一带是 20px 内边距，token 仍是 40；跟 layout.css / 服务页对齐，不新开变量。 */
/* 停用 2026-09-01：双稿改造后不再有中间过渡档，见 docs/14。
   复活时把条件改回 (min-width: 769px) and (max-width: 1040px)。 */
@media not all {
  .waybill {
    --biz-w: calc(100% - 40px);
    --biz-row: min(var(--biz-w), calc(3 * 332px + 2 * var(--biz-gap)));
    --biz-card: min(332px, calc((var(--biz-row) - 2 * var(--biz-gap)) / 3));
    --biz-left: calc(20px + (var(--biz-w) - var(--biz-row)) / 2);
  }

  .page-home .biz__grid {
    width: calc(100% - 40px);
  }
}

/* ---------------------------------------------------------------- 移动布局（≤639）：同比单位 + 服务网络走移动排布 */

html[data-layout="mobile"] {
  /* 移动稿基准 375。原来这一段把 375 量到的 px 直接写死，768（iPad 竖屏）下
     主营业务栅格仍是 345、网络次要数字仍是 315，两侧各空 200+ 的白边。
     这里给整段一个同比单位：几何跟着视口放大，375 下 --m 恰好是 1px，成稿值一个不动。
     用 cqi 不用 vw —— vw 含滚动条宽度，桌面窄窗下会算出比可视区更宽的盒子，直接横向溢出。
     只有不在更近容器里的后代才该用它；.biz__card / .hero / .partners__viewport 各有自己的
     容器与 cqw，卡内字号本来就跟着卡宽走，不需要 --m。

     2026-09-01：zoom 后 main 布局宽恒为 375，--m 恒等于 1px；不再封顶。 */
  .page-home {
    container-type: inline-size;
    --m: calc(100cqi / 375);
  }
}

/* 服务网络范围：PC 是左文右图，移动布局沿用「上图下数字」，不再挤成
   左边一条统计栏 + 右边塞地图（1024 实测标签被算到 7.8px，地图还被裁掉一截）。
   docs/02 §5 拿的就是这一块当「用 order 换位、不复制 DOM」的例子。
   切图改由 data-layout-only 双 picture 显隐，不再写 source media。 */
html[data-layout="mobile"] {
  .network {
    background: var(--network-bg);
    height: auto;
    padding: 0;
    /* 第六轮：与上方主营卡留白走 biz 的 padding-bottom（约 24），本段不再垫顶。 */
  }

  .network__inner {
    /* 不用桌面版心盒：还原整屏全宽（否则 min(1680,100%-192) 会把 375 收成 183）。
       margin 用 auto 而不是 0 —— 1200~1280 之间 max-width 会真的生效，钉 0 会整块偏左。 */
    width: 100%;
    max-width: none;
    margin-inline: auto;
    padding-inline: 0;
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
  }

  .network__stats {
    display: contents;
    padding-top: 0;
  }

  /* 第七轮：上 80 标题带 / 中地图 / 下 260 数字带。不再把标题叠在地图上。
     第八轮：标题底 / 地图 / 数字顶在接缝处都落到 --network-bg，去掉硬分界。 */
  .network__heading {
    order: 0;
    grid-row: auto;
    z-index: 1;
    align-self: stretch;
    height: 80px;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 0;
    background: linear-gradient(180deg, #081a37 0%, var(--network-bg) 100%);
  }

  .network__map {
    grid-area: auto;
    grid-row: auto;
    order: 1;
    aspect-ratio: auto;
    background: var(--network-bg);
  }

  .network__figures {
    display: flex;
    flex-direction: column;
    justify-content: center;
    order: 2;
    height: 260px;
    box-sizing: border-box;
    overflow: hidden;
    background: linear-gradient(180deg, var(--network-bg) 0%, #081a37 100%);
  }

  .network__art {
    position: relative;
    left: auto;
    width: 100%;
    aspect-ratio: 1500 / 912;
    translate: none;
    background: var(--network-bg);
  }

  /* 地图上下缘都羽化回 --network-bg，和标题带底色、数字带顶色同一色，不再露横缝。
     上 8% / 下 8%：两端都是开阔洋，糊不到城市灯带。 */

  .network__art::before {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    z-index: 1;
    width: auto;
    height: 8%;
    background: linear-gradient(180deg, var(--network-bg) 0%, rgba(0, 18, 58, .72) 45%, transparent 100%);
    pointer-events: none;
  }

  .network__art::after {
    inset: auto 0 0 0;
    width: auto;
    height: 8%;
    background: linear-gradient(180deg, transparent 0%, rgba(0, 18, 58, .72) 45%, var(--network-bg) 100%);
  }

  /* 移动底图是桌面图的纵向派生版本。路线坐标随底图共用二维变换，
     点与广州波纹反向校正 Y 轴，避免非等比 viewBox 把圆拉成椭圆。 */
  .network__route circle,
  .network__hub circle {
    transform-box: fill-box;
    transform-origin: center;
    transform: scaleY(.9385);
  }

  /* 小图上 21 条线既糊成一团又抬高每帧重绘面积：按 data-mobile 砍掉一半支线，
     线宽同步收细，剩下的城市仍覆盖亚太/中东/欧洲/南北美/大洋洲。
     display:none 只免掉绘制——Chrome 仍会继续推进子树里的动画并每帧重算样式，
     所以必须显式 animation: none，实测样式重算才真正降下来。 */
  .network__route[data-mobile="off"] { display: none; }

  .network__route[data-mobile="off"] .network__route-pulse,
  .network__route[data-mobile="off"] .network__route-dot {
    animation: none;
  }

  .network__route-line { stroke-width: 1.6; }
  .network__route-pulse { stroke-width: 2.6; }

  .network__title {
    margin: 0;
    font-size: var(--section-title-size);
    line-height: 1.3;
    text-align: center;
    color: #fff;
    transform: none;
  }

  .network__rule {
    justify-content: center;
    margin-left: 0;
    margin-top: 3px;
    transform: none;
  }

  .network__rule::before,
  .network__rule::after {
    background: #fff;
  }

  /* 「全球服务网络覆盖国家和地区」14 字在 375 下会折行：字号 12、列内文字宽约 103。
     成稿当年按 8 字量过（字号 14 ⇒ 需 112，列宽不够），字号收到 12/21、左右留白 30→20、
     图标缝 12→10。长标签允许折行，数字带 260 高仍装得下。

     宽度 min(100%, 375*--m)：zoom 后布局宽锁 375，--m 恒等于 1px，取 100%。
     标题带与地图仍满宽，否则白底带两侧会露出深蓝、看着像断了。 */
  .network__major {
    order: 0;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    width: min(100%, calc(375 * var(--m)));
    margin: 0 auto;
    padding: 16px 20px 8px;
    gap: calc(12 * var(--m));
  }

  .network__major li {
    grid-template-columns: calc(48 * var(--m)) minmax(0, 1fr);
    column-gap: calc(10 * var(--m));
  }

  .network__major [data-icon] {
    width: calc(48 * var(--m));
    height: calc(48 * var(--m));
  }

  .network__major b {
    font-size: calc(21 * var(--m));
    color: var(--accent);
  }

  .network__major span {
    font-size: calc(12 * var(--m));
    white-space: normal;
  }

  .network__minor {
    order: 0;
    grid-template-columns: calc(105 * var(--m)) calc(135 * var(--m)) calc(75 * var(--m));
    gap: 0;
    width: calc(315 * var(--m));
    margin: 0 auto;
    padding: 0 0 16px;
  }

  .network__minor::before {
    display: none;
  }

  .network__minor li {
    min-height: calc(60 * var(--m));
    padding: calc(4 * var(--m)) 0;
  }

  .network__minor li:nth-child(n) {
    order: initial;
  }

  .network__minor li:nth-child(n + 4) {
    border-top: var(--hairline) solid rgba(255, 255, 255, .2);
  }

  .network__minor b {
    font-size: calc(22 * var(--m));
  }

  .network__minor span {
    font-size: calc(12 * var(--m));
    line-height: 1.4;
    white-space: normal;
  }
}

/* ---------------------------------------------------------------- 其余移动布局（hero 等） */

html[data-layout="mobile"] {
  /* 2026-08-24：移动端 banner 与 PC 同一张图、同一套 cover，不再换 hero-mobile、不再叠标题或羽化底。 */
  .hero {
    --u: 0.26666667cqw;
  }

  .hero__copy {
    left: var(--gutter);
    top: calc(56 * var(--u));
    max-width: calc(100% - var(--gutter) * 2);
    z-index: 2;
  }

  .hero__title {
    font-size: calc(22 * var(--u));
  }

  .hero__sub {
    margin-top: calc(8 * var(--u));
    font-size: calc(13 * var(--u));
    letter-spacing: normal;
  }

  .hero__sub::after {
    display: none;
  }

  .hero__caps {
    display: none;
  }

  .hero__dots {
    bottom: calc(12 * var(--u));
    left: 50%;
    right: auto;
    transform: translateX(-50%);
  }

  .hero__dots button {
    width: calc(8 * var(--u));
    height: calc(8 * var(--u));
  }

  .hero__dots button.is-active {
    width: calc(24 * var(--u));
  }

  /* 48u 在 375 基 --u 下仍是 48px，约占 150 高舞台的 1/3。
     按桌面 48/1920 等比到 375 只有 9px，点不到；取半：24u，随 --u 缩放。 */
  .hero__arrow {
    width: calc(24 * var(--u));
    height: calc(24 * var(--u));
    opacity: 0;
    pointer-events: none;
  }

  .hero__arrow::before {
    width: calc(5 * var(--u));
    height: calc(5 * var(--u));
  }

  .hero__arrow--prev { left: calc(12 * var(--u)); }
  .hero__arrow--next { right: calc(12 * var(--u)); }

  /* 触摸没有 hover；盖掉桌面 :hover，否则第一次 tap 会被当成 hover 粘住。 */
  .hero:hover .hero__arrow {
    opacity: 0;
    pointer-events: none;
  }

  .hero.is-arrows-on .hero__arrow {
    opacity: 1;
    pointer-events: auto;
  }

  .waybill,
  .cta {
    display: none;
  }

  .biz {
    background: #fff;
    padding-bottom: 24px;
  }

  .caps {
    --u: calc(100cqi / 375);
    background: #fff;
    padding: 0 0 calc(24 * var(--u));
  }

  .caps .section-title {
    padding-top: 0;
  }

  .page-home .caps .section-title__text {
    font-size: 22px;
    line-height: 32px;
    font-weight: 700;
  }

  .caps .section-title__rule {
    margin-top: 3px;
  }

  .caps__grid {
    width: min(calc(343 * var(--u)), calc(100% - 32px));
    max-width: none;
    margin: calc(20 * var(--u)) auto 0;
    grid-template-columns: minmax(0, 1fr);
    column-gap: 0;
    row-gap: calc(12 * var(--u));
  }

  .caps__card--warehouse { order: 1; }
  .caps__card--sourcing { order: 2; }
  .caps__card--network { order: 3; }
  .caps__card--compliance { order: 4; }
  .caps__card--digital { order: 5; }
  .caps__card--equipment { order: 6; }

  .caps__card {
    height: calc(140 * var(--u));
    min-height: 0;
    border-radius: calc(12 * var(--u));
    box-shadow: 0 0 3px rgba(3, 99, 178, .2);
  }

  .caps__card--equipment {
    height: calc(104 * var(--u));
  }

  .caps__panel {
    grid-template-columns: calc(36 * var(--u)) minmax(0, 1fr);
    column-gap: calc(8 * var(--u));
    height: 100%;
    padding: calc(12 * var(--u));
  }

  .caps__card--equipment .caps__panel {
    min-height: 0;
  }

  .caps__icon {
    width: calc(36 * var(--u));
    height: calc(36 * var(--u));
  }

  .caps__panel h3 {
    font-size: calc(14 * var(--u));
  }

  .caps__en {
    margin-top: calc(2 * var(--u));
    font-size: calc(11 * var(--u));
  }

  .caps__points {
    margin-top: calc(8 * var(--u));
  }

  .caps__points li {
    padding-left: calc(20 * var(--u));
    font-size: calc(11 * var(--u));
    line-height: calc(18 * var(--u));
    white-space: normal;
  }

  .caps__points li::before {
    left: calc(5 * var(--u));
    top: calc(6 * var(--u));
    width: calc(6 * var(--u));
    height: calc(6 * var(--u));
  }

  /* padding-top / 线距只留 transform 复位：成稿实测（hero 底 200 → ink 顶 226.5）
     与全局移动值 22 / 3 一致，本页不再另设。 */
  .page-home .biz .section-title,
  .partners .section-title {
    transform: none;
    padding-top: 22px;
  }

  .biz .section-title__rule {
    transform: none;
  }

  /* 行高必须写：桌面那份 `.page-home .biz .section-title__text` 定死 44px，
     比全局移动段的 1.3 更特指，不复位会按 44 排 20px 的字。 */
  .page-home .biz .section-title__text {
    font-size: var(--section-title-size);
    line-height: 1.3;
  }

  .page-home .biz__grid {
    width: min(calc(345 * var(--m)), calc(100% - 30px));
    margin-left: auto;
    margin-right: auto;
    grid-template-columns: minmax(0, 1fr);
    gap: calc(11 * var(--m));
    margin-top: calc(16 * var(--m));
  }

  .biz__card:nth-child(n) {
    transform: none;
  }

  .biz__card img {
    aspect-ratio: 345 / 125;
    object-fit: cover;
  }

  /* 移动卡对齐成稿裁片（690×248@2x → CSS 345×124）：绿条 y≈51 x≈33 */
  .biz__card a::after {
    background: linear-gradient(
      90deg,
      rgba(5, 32, 84, .82) 0%,
      rgba(5, 32, 84, .45) 42%,
      rgba(5, 32, 84, .1) 70%,
      rgba(5, 32, 84, 0) 100%
    );
  }

  /* 运营将标题和副标题都留空时，移动端同样完整展示原图，不再叠可读性羽化层。 */
  .hero__slide--image-only::after {
    display: none;
  }

  .biz__copy {
    top: 20.16%;                 /* 25/124 */
    left: 9.57%;                 /* 33/345 */
    right: 8%;
    bottom: 6%;
    transform: none;
  }

  .biz__name {
    font-size: 5.22cqw;          /* ≈18/345 */
    line-height: 1.15;
  }

  .biz__rule {
    width: 8.99cqw;              /* 31/345 */
    height: 0.87cqw;             /* 3/345 */
    margin-top: 2.9cqw;          /* ≈10：标题底→绿条 y51 */
  }

  .biz__summary {
    margin-top: 3.77cqw;         /* ≈13：绿条→摘要 y67.5 */
    font-size: 3.48cqw;          /* ≈12/345 */
    line-height: 1.55;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    overflow: hidden;
  }

  /* 第七轮 375：白盒 112×54；logo 高钉 24、宽按原图比、盒内居中。 */
  .partners__grid {
    grid-auto-columns: calc(112 * var(--m));
    column-gap: calc((100cqi - 336 * var(--m)) / 2);
    row-gap: calc(16 * var(--m));
    width: max-content;
    min-width: 100%;
  }

  /* 移动：每页 3 列 × 2 行 = 6 张；关掉 PC 的 10n 规则，改 6n */
  .partners__grid li:nth-child(10n + 1),
  .partners__grid li:nth-child(10n + 2) {
    scroll-snap-align: none;
  }

  .partners__grid li:nth-child(6n + 1),
  .partners__grid li:nth-child(6n + 2) {
    scroll-snap-align: start;
  }

  .partners__grid li {
    width: calc(112 * var(--m));
    height: calc(54 * var(--m));
    min-height: calc(54 * var(--m));
    padding: 0;
    background: #fff;
  }

  .partners__grid img {
    width: auto;
    height: calc(24 * var(--m));
    max-width: 100%;
    max-height: calc(24 * var(--m));
    object-fit: contain;
  }

  /* 翻页由 JS 关 snap 后横向滑；末页回到首页用位移，避免 rewind */
  .partners__viewport { scroll-behavior: auto; }
}

/* 停用 2026-09-01：双稿改造后不再有中间过渡档，见 docs/14。
   复活时把条件改回 (max-width: 390px)。 */
@media not all {
  .hero__title { font-size: 20px; }
  /* 与上一段同值，只是重申三列不塌；跟着 --m 走，否则 315 的列会缩在 315*--m 的盒子里偏左。 */
  .network__minor {
    grid-template-columns: calc(105 * var(--m)) calc(135 * var(--m)) calc(75 * var(--m));
  }
}

/* 停用 2026-09-01：双稿改造后不再有中间过渡档，见 docs/14。
   复活时把条件改回 (max-width: 375px)。 */
@media not all {
  .hero__copy { top: 52px; }
  .page-home .biz__grid { gap: 11px; }
}

@media (prefers-reduced-motion: reduce) {
  .waybill__form,
  .waybill__form input,
  .waybill__form button { transition: none; animation: none; }

  .waybill__form button:hover [data-icon="search"] { scale: 1; }

  .hero__slide {
    transition: none;
  }
  .hero__bg {
    opacity: 1;
  }
  .hero__dots button { transition: none; }
  .hero__arrow { transition: none; }
  .hero__slide.is-active .hero__copy { animation: none; }
  .partners__dot { transition: none; }
  .partners__viewport { scroll-behavior: auto; transition: none; }
  .biz__card,
  .biz__card img,
  .partners__grid li,
  .partners__grid img { transition: none; }

  html.motion-ready [data-reveal-group].is-revealed > .biz__card:hover,
  html.motion-ready [data-reveal-group].is-revealed > .biz__card:focus-within,
  .biz__card:hover,
  .biz__card:focus-within {
    translate: none;
    filter: none;
  }

  .biz__card:hover img,
  .biz__card:focus-within img { scale: 1; }

  html.motion-ready .page-home .caps__card.is-revealed:hover,
  html.motion-ready .page-home .caps__card.is-revealed:focus-within,
  html.motion-ready .page-home .caps__card.is-revealed:active {
    transform: none;
  }
  html.motion-ready .page-home .caps__card.is-revealed:hover .caps__icon,
  html.motion-ready .page-home .caps__card.is-revealed:focus-within .caps__icon,
  html.motion-ready .page-home .caps__card.is-revealed:active .caps__icon,
  html.motion-ready .page-home .caps__card.is-revealed:hover .caps__photo,
  html.motion-ready .page-home .caps__card.is-revealed:focus-within .caps__photo {
    scale: 1;
  }

  .page-home .caps .section-title__rule,
  .page-home .caps__card,
  .page-home .caps__photo,
  .page-home .caps__icon,
  .page-home .caps__panel h3,
  .page-home .caps__en,
  .page-home .caps__points li {
    opacity: 1;
    translate: none;
    transform: none;
    scale: 1;
    transition: none;
    animation: none;
  }

  .network__routes[data-network-state] .network__route-lines .network__route path.network__route-line {
    opacity: .8;
    animation: none;
  }

  .network__routes[data-network-state] .network__route-lines .network__route path.network__route-pulse {
    display: none;
    animation: none;
  }

  .network__routes[data-network-state] .network__route-lines .network__route circle,
  .network__hub-core {
    opacity: .8;
    scale: 1;
    animation: none;
  }

  .network__hub-wave { display: none; }
}
