
/* : About hero H1 拆分（h1 + p.hero-title-ch）——间距与动画还原为原 h1 内 span 效果 */
.hero .hero-title { margin-bottom: 0; }
.hero .hero-title-ch {
  margin: var(--space-3) 0 var(--space-6);
  opacity: 0;
  transform: translateY(24px);
  animation: fade-up 900ms var(--ease-out-expo) 450ms forwards;
}
/* About timeline dark section */
.about-timeline {
  position: relative;
  background: var(--navy-800);
  min-height: 620px;
  /* 2026-10-08：原 80px 0 96px（上下不对称，且与自身移动档 64/64 不同源）
     → 走内容分区尺度。⚠️ 本文件是 page-about.css 的源，改样式必须改这里。 */
  padding-block: var(--section-pad-block);
  overflow: hidden;
  color: var(--white);
}
/* 🔴 2026-10-17 删除 `.about-timeline-bg`：
   它引用的 `assets/about-timeline-bg.jpg` 是一张 **1920×900 的占位图**，
   中间印着「hero 占位」四个字（实测 std 3.45 / mean 235.8 = 近乎纯色 + 一行字），
   而这段的遮罩是 `rgba(11,31,58,.82→.62)` —— 压得住颜色、压不住字，
   于是「hero 占位」直接透在正式页面上了（体检报告 §9）。
   现在改成实色底 `--navy-800`（= #0B1F3A，与遮罩同色），渐变遮罩保留做层次。
   ⚠️ 将来换真图：把 background-image 加到 `.about-timeline` 上即可，
      不要再建一个只装占位图的中间层（那层正是让占位图漏出来的原因）。 */
.about-timeline-overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(135deg, rgba(11,31,58,.82), rgba(11,31,58,.62));
  z-index: 1;
}
.about-timeline-inner {
  position: relative;
  z-index: 2;
}
.about-timeline-title {
  font-size: 2.25rem;
  font-weight: 700;
  color: var(--white);
  margin-bottom: var(--space-12);
  letter-spacing: 0.04em;
}
.about-timeline-wrap {
  display: grid;
  grid-template-columns: 140px 1fr;
  gap: var(--space-16);
  align-items: start;
}
.about-timeline-years {
  display: flex;
  flex-direction: column;
  gap: 0;
  position: relative;
  padding-left: var(--space-6);
  border-left: 1px solid rgba(255,255,255,.18);
  /* 节点再多区块高度也恒定：超出在年份轴内部滚动 */
  max-height: 480px;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: rgba(255,255,255,.25) transparent;
}
.about-timeline-years::-webkit-scrollbar { width: 4px; }
.about-timeline-years::-webkit-scrollbar-thumb { background: rgba(255,255,255,.25); border-radius: var(--radius-sm); }
.about-timeline-years::-webkit-scrollbar-track { background: transparent; }
.about-timeline-year {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: var(--space-4-5) 0;
  background: transparent;
  border: none;
  /* 2026-10-17：0.45 白在 #0B1F3A 上是 4.34（17px 需 4.5）⇒ 0.55 = 5.82。
     仍保持对照：选中 100% / hover 75% / 未选 55%，层级没被压平。 */
  color: rgba(255,255,255,.55);
  font-family: var(--font-en);
  font-size: var(--fs-body-lg);
  font-weight: 600;
  cursor: pointer;
  transition: color var(--duration-normal);
  text-align: left;
}
.about-timeline-year:hover { color: rgba(255,255,255,.75); }
.about-timeline-year.active { color: var(--white); }
.about-timeline-dot {
  position: absolute;
  left: -29px;
  top: 50%;
  transform: translateY(-50%);
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: rgba(255,255,255,.25);
  border: 2px solid transparent;
  transition: all var(--duration-normal);
}
.about-timeline-year.active .about-timeline-dot {
  background: var(--blue-500);
  box-shadow: 0 0 0 4px rgba(197,162,79,.25);
}
.about-timeline-panels {
  position: relative;
  min-height: 260px;
}
.about-timeline-panel {
  display: none;
  animation: aboutFadeIn .5s ease both;
}
.about-timeline-panel.active { display: block; }
.about-timeline-big-year {
  font-family: var(--font-en);
  font-size: 5rem;
  font-weight: 800;
  line-height: 1;
  color: var(--white);
  margin-bottom: var(--space-5);
  opacity: .95;
}
.about-timeline-panel h3 {
  font-size: var(--fs-xl);
  font-weight: 600;
  color: var(--blue-400);
  margin-bottom: var(--space-3-5);
}
.about-timeline-panel p {
  font-size: var(--fs-body);
  line-height: 1.85;
  color: rgba(255,255,255,.72);
  max-width: 560px;
}
@keyframes aboutFadeIn {
  from { opacity: 0; transform: translateY(12px); }
  to { opacity: 1; transform: translateY(0); }
}

/* 荣誉分组：证书主体不同，小标题明示主体（避免把关联企业资质显示成品牌自身荣誉） */
.honors-group + .honors-group {
  margin-top: var(--space-16);
}
.honors-group-title {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font-size: var(--fs-body-lg);
  font-weight: 700;
  color: var(--navy-900);
  margin-bottom: var(--space-5-5);
}
.honors-group-title::before {
  content: '';
  width: 4px;
  height: 18px;
  border-radius: var(--radius-sm);
  background: var(--color-decorative);
}
/* Honors with images（覆盖 shared.css 文字卡片版式） */
.honors-grid {
  grid-template-columns: 1fr;
}
@media (min-width: 640px) {
  .honors-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (min-width: 1024px) {
  .honors-grid {
    /* 固定 4 列（2026-10-10 由 3 列改判）。
       🔴 原 3 列的问题：品牌组只有 4 张 ⇒ 3 列下第 2 行**只放 1 张卡**（孤行），
          白占一整行高约 520px。实测 3 列 2858px / 4 列 2036px（同画框比例），
          **一行孤行 = 822px**，是这面墙开销里占比最高的一笔。
       ⚠️ 不用 auto-fill：大屏（5+ 列）会开出空轨道，同一组内卡片宽度互不相等。
       ⚠️ 4 列下母公司组默认展示 4 张（HONORS_MAX_SHOW），与品牌组 4 张合成默认 8 张、两行排满。
          2026-10-22 由 6 改判：6 张在 4 列下是 **4+2**，第二行右侧空两位，读作"没排完"而不是"精选"。
          原先"为排满去加两张同质证书不划算 ⇒ 保留 6 张、接受留白"的结论**不成立** ——
          留白不是取舍，是排不齐；现在默认 4 张、其余进展开，两边都齐。 */
    grid-template-columns: repeat(4, 1fr);
  }
}
.honor-card {
  padding: 0;
  background: var(--white);
  border-radius: var(--radius-lg);
  overflow: hidden;
  /* 边界感（2026-10-08）：白卡叠白页底，仅靠 8% 柔影读不出边缘 —— 实测卡外 246 /
     卡内 255，阶跃 9 级（1.04:1）。加 1px 环形描边。⚠️ 用 box-shadow 环而**不是**
     border：border 会把卡高推 2px，连带改掉证书画框的实测 sd 基线（1:1 画框的整齐度
     判据是方差）。0 0 0 1px 必须排第一 —— box-shadow 列表「先画者在上」。
     描边取 --gray-200（环 1.22:1）而非 --gray-100：后者 1.09:1，肉眼不可见。
     2026-10-11 收口：第二层投影原写成 `--shadow-md` 的**裸字面值**
     （`0 12px 40px rgba(11, 31, 58, 0.08)`）⇒ 同一个投影在 shared.css 走令牌、
     在这里绕过令牌 = 「一份视觉语言两份实现」。现改回 `var(--shadow-md)`：
     **计算值逐像素不变**（实测改前改后 computed box-shadow 字符串完全相同），
     只是把实现收回 shared.css（此前这条投影在 shared.css 与 page-about.css 各写了一份）。⚠️ 那道 1px 环是**有实证的刻意差异**（白卡叠白底，
     仅靠 8% 柔影只有 1.04:1），**保留不动**，不要顺手删。 */
  box-shadow: 0 0 0 1px var(--gray-200), var(--shadow-md);
  display: flex;
  flex-direction: column;
  /* 悬停反馈（2026-10-22）：卡片本就能点开大图（.honor-zoom → 案例灯箱），此前**一条 hover 都没有**，
     光标也是 auto ⇒ 用户不知道能点。
     🔴 必须把 `.reveal` 的 opacity / transform 两条原样写回：两者同为单类选择器，本文件在
        shared.css 之后加载、同优先级后写者赢 —— 只写 translate/box-shadow 会把滚动 reveal 的过渡整条顶掉
        （卡片会变成"瞬间出现"）。
     🔴 抬升用 `translate` 而不是 `transform`：`.reveal` 的 reveal 动画占用 transform，
        两个属性互不干扰，才能同时做到"入场 600ms 上浮 32px"和"悬停 240ms 抬 4px"。 */
  transition: opacity .6s cubic-bezier(.16, 1, .3, 1),
              transform .6s cubic-bezier(.16, 1, .3, 1),
              translate .24s ease,
              box-shadow .24s ease;
}
.honor-card:hover {
  translate: 0 -4px;
  /* 环从 --gray-200 提到 --gray-300：白卡在白页底上，浅环肉眼读不出（1.22:1 → 1.6:1） */
  box-shadow: 0 0 0 1px var(--gray-300), var(--shadow-lg);
}
/* 证书图轻微推近。画框 inset 20px 有余量，1.03 不会顶到卡边（卡本身 overflow:hidden 兜底） */
.honor-img-wrap img { transition: transform .5s cubic-bezier(.22, .61, .36, 1); }
.honor-card:hover .honor-img-wrap img { transform: scale(1.03); }
/* 键盘用户拿不到 :hover —— 焦点进入放大按钮时给同一套反馈 */
.honor-card:focus-within {
  box-shadow: 0 0 0 1px var(--gray-300), var(--shadow-lg);
}
/* 统一 4:3 展示框：所有卡片高度严格一致，证书完整居中（横版左右留白是专业证书墙样式）。
   🔴 2026-10-10 由 1:1 改判为 4:3。**这不是取舍，是三项指标同时更优** ——
      用 content/about-content.json 里 23 张证书的真实像素尺寸复算「contain 下每张占框高的比例」：
        3:4  sd 23.29 · 均值填满 80.6%
        1:1  sd 15.30 · 均值填满 87.8%   ← 此前在「3:4 vs 1:1」两者间选的赢家
        4:3  sd  4.48 · 均值填满 96.8%   ← 本次选它
        3:2  sd  0.08 · 均值填满 100.0%
      ⚠️ 当年只比了 3:4 与 1:1（两条都偏「竖」），**没试过比证书更宽的框**。
         证书的宽高比中位数是 1.01 / 0.77（两组），绝大多数是横版 ⇒ 越接近横版比例越整齐。
      为什么不取 3:2（sd 几乎为 0）：3:2 框高只有卡宽的 66.7%（4:3 是 75%），
         证书**显示尺寸反而更小**；4:3 是「填满度 × 显示尺寸」两项都占优的平衡点。
      判据是**方差不是均值**：sd 4.48 意味着每一张证书在框里的大小几乎一样，整面墙读作一个矩阵。
   ② 图片改绝对定位：② 图片改绝对定位：flex 下 `max-height:100%` 与 `aspect-ratio` 形成循环依赖， 实测画框被内容撑成 8 种高度（505–563；横版矮、超窄竖版高）。 ⚠️ 另一条药 `min-height:0` 也能让画框等高，但图片百分比 max-height 随之失去 解析基准 → 图片**溢出画框**（实测填高最高 310%），已弃用。 ③ 内边距从 wrap 的 padding 挪到 img 的 inset —— 绝对定位的包含块是 padding box， 留着 padding 会在 inset 之外再叠一层（两处各写一份必然漂移）。 ④ img 尺寸用 `auto + max-*`，不用显式 width/height：显式尺寸配 object-fit:contain 会让**元素框大于可见图**，box-shadow 变成比证书更宽的一圈灰边（竖版实测每侧多 49px）。 auto + max-* 走替换元素「约束冲突保持宽高比」规则，元素框紧贴图片。 */
.honor-img-wrap {
  background: var(--cool-100);
  position: relative;
  aspect-ratio: 4 / 3;
}
.honor-img-wrap img {
  position: absolute;
  inset: 20px;
  width: auto;
  height: auto;
  margin: auto;
  max-width: calc(100% - 40px);
  max-height: calc(100% - 40px);
  object-fit: contain;
  box-shadow: 0 8px 24px rgba(11,31,58,.12);
}
/* 证书点击放大（2026-10-08）：按钮绝对铺满画框。img 的 inset 解析基准随之从 wrap
   变成按钮，而按钮 inset:0 ⇒ **几何完全不变**，1:1 画框与同行等高性不受影响。 */
.honor-img-wrap .honor-zoom {
  position: absolute;
  inset: 0;
  display: block;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: zoom-in;
}
/* 焦点环画在环内（outline-offset 负值）—— 卡片 overflow:hidden 会剪掉外扩的环 */
.honor-img-wrap .honor-zoom:focus-visible {
  outline: 2px solid var(--blue-500);
  outline-offset: -3px;
}
/* 奖杯实物竖照：极窄水晶条，框内垂直收缩留白，像展柜器物般精致居中（不顶满卡片）。
   🔴 2026-10-10 参数随画框 4:3 重算：原 inset:28px/20px + max-height:74% 是配 **1:1（框高 379）**
      调的 —— 换成 4:3/4 列后框高只剩 209，74% 与 inset 28px 叠加后实测奖杯只有 **48px 宽**（细条）。
      现将 inset 收窄到 8px、max-height 提到 96%，让奖杯吃满可用高度：实测 **约 60px 宽 / 193px 高**。
      ⚠️ 这是**几何上限**，不是调参没调够：扁框里竖图的宽度上限恒等于「框高 × 宽高比」
         （209 × 0.31 = 65px）。要奖杯更大只能加高画框，那会破坏「所有卡片等高」。
      ⚠️ 1:1 时代记的「留着 74% 更整齐（sd 11.88 vs 12.75）」在此已不适用 —— 那条是在高框里
         比较「奖杯填 74% 还是 100%」；现在框本身矮，填不满只会更小。 */
.honor-card.honor-trophy .honor-img-wrap {
  background: linear-gradient(180deg, var(--cool-100) 0%, var(--gray-100) 100%);
}
.honor-card.honor-trophy .honor-img-wrap img {
  inset: 8px 20px;
  max-width: 62%;
  max-height: 96%;
  object-fit: contain;
  box-shadow: 0 14px 34px rgba(11,31,58,.16);
}
.honor-meta {
  padding: var(--space-6);
  text-align: center;
}
.honor-meta span {
  display: inline-block;
  padding: var(--space-1-5) var(--space-3-5);
  background: color-mix(in srgb, var(--blue-500) 12%, var(--white));
  color: var(--navy-700);
  border-radius: var(--radius-full);
  font-size: var(--fs-nano);
  font-weight: 700;
  margin-bottom: var(--space-3-5);
}
/* 过期证书标记：仍是历史荣誉，但必须一眼看出不是现行（2026-10-21 复审） */
.honor-meta .honor-expired {
  display: inline-block;
  margin-left: var(--space-2);
  vertical-align: middle;
  padding: 0 var(--space-1-5);
  border: 1px dashed var(--gray-400);
  border-radius: var(--radius-full);
  color: var(--gray-600);
  background: var(--white);
  font-weight: 500;
}
.honor-meta h3 {
  font-size: var(--fs-body-sm);
  color: var(--navy-900);
  line-height: 1.55;
  font-weight: 500;
}
/* 超出默认展示数的证书默认隐藏；展开后显示（图片始终在 DOM，GEO 无损） */
.honor-card.honor-extra { display: none; }
/* 展开时不要 15 张"啪"地砸出来：280ms 错峰淡入（每张按 --i 递增 18ms，最多约 270ms）。
   ⚠️ 只给 `.expanded` 加动画：折叠态的卡片是 display:none，动画不会白跑；
      `both` 让结尾停在"可见"，压过 .reveal 的 opacity:0（被 display:none 挡住的卡永远等不到 observer）。 */
.honors-grid.expanded .honor-card.honor-extra {
  display: flex;
  animation: honorUnfold .28s ease both;
  animation-delay: calc(var(--i, 0) * 18ms);
}
@keyframes honorUnfold {
  from { opacity: 0; translate: 0 8px; }
  to   { opacity: 1; translate: 0 0; }
}
.honors-toggle-wrap {
  text-align: center;
  margin-top: var(--space-12);
}
.honors-toggle {
  min-width: 180px;
}
/* 荣誉区为浅色背景，.btn-outline 白色玻璃字不可见——这里切为实心品牌高对比样式 */
.honors-section .honors-toggle-wrap .honors-toggle {
  color: var(--white);
  background: var(--color-interactive);
  border: none;
  box-shadow: var(--shadow-brand);
}
.honors-section .honors-toggle-wrap .honors-toggle:hover {
  color: var(--white);
  background: var(--color-interactive-hover);
  transform: translateY(-2px);
  box-shadow: var(--shadow-brand-hover);
}

/* About intro — editorial magazine layout */
.about-intro-editorial {
  background: var(--cream-100);
  position: relative;
  overflow: hidden;
}
.about-intro-editorial::before {
  content: '';
  position: absolute;
  inset: 0;
  background:
    radial-gradient(circle at 85% 20%, rgba(74,144,226,.06) 0%, transparent 35%),
    radial-gradient(circle at 10% 90%, rgba(7,18,35,.03) 0%, transparent 30%);
  pointer-events: none;
}
.about-intro-editorial .about-intro-grid {
  position: relative;
  z-index: 1;
  grid-template-columns: 1fr;
  gap: var(--space-10);
  align-items: center;
}
.about-intro-headline {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}
.about-intro-headline .gold-line {
  width: 48px;
  height: 4px;
  background: var(--blue-500);
  border-radius: var(--radius-sm);
  margin-bottom: var(--space-5);
}
.about-intro-eyebrow {
  font-size: var(--fs-caption);
  letter-spacing: .12em;
  color: var(--color-interactive);
  font-weight: 600;
  margin-bottom: var(--space-3);
}
.about-intro-title {
  font-family: var(--font-display);
  font-size: clamp(2.75rem, 7vw, 4.5rem);
  font-weight: 700;
  line-height: 1.05;
  color: var(--navy-900);
  margin-bottom: var(--space-4);
}
.about-intro-subtitle {
  font-size: var(--fs-body);
  color: var(--gray-500);
  letter-spacing: .05em;
}
.about-intro-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}
.about-intro-body p {
  font-size: var(--fs-body);
  line-height: 1.9;
  color: var(--gray-700);
}
.about-intro-lead {
  font-size: var(--fs-body-lg) !important;
  line-height: 1.8 !important;
  color: var(--navy-900) !important;
  font-weight: 500;
}
.about-intro-closing {
  color: var(--navy-900) !important;
  font-weight: 500;
  padding-left: var(--space-5);
  border-left: 3px solid var(--blue-500);
}
@media (min-width: 1024px) {
  .about-intro-editorial .about-intro-grid {
    grid-template-columns: .9fr 1.1fr;
    gap: var(--space-16);
    align-items: center;
  }
  .about-intro-headline {
    /* 去掉 sticky：原 top 会把标题推低，破坏左右顶对齐 */
  }
}

@media (max-width: 767px) {
  /* 2026-10-08：原 .about-timeline{padding:64px 0} 与 --section-pad-block 的移动档同值，
     删掉以免同一条节奏出现两处定义。 */
  .about-timeline-wrap { grid-template-columns: 1fr; gap: var(--space-8); }
  .about-timeline-years {
    flex-direction: row;
    border-left: none;
    border-bottom: 1px solid rgba(255,255,255,.18);
    padding-left: 0;
    padding-bottom: var(--space-2);
    overflow-x: auto;
    /* 移动端为横向滑动，解除限高 */
    max-height: none;
    overflow-y: hidden;
  }
  .about-timeline-year {
    white-space: nowrap;
    padding: var(--space-3) var(--space-4);
    font-size: var(--fs-body);
  }
  .about-timeline-dot {
    left: 50%;
    bottom: -5px;
    top: auto;
    transform: translateX(-50%);
  }
  .about-timeline-big-year { font-size: 3.5rem; }
}

/* News list（关于页资讯卡片：标题 + 摘要 + 阅读全文） */
.news-item .news-info { flex: 1; display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; }
.news-item .news-summary { font-size: var(--fs-caption); color: var(--gray-500); line-height: 1.7; }
/* 🔴 2026-10-10 harden 批：`.news-more` 此前只有字号/颜色，无纵向内距 ⇒
   命中区高实测 23.8，**低于 WCAG 2.5.8（AA）的 24 下限**。
   它在 `.news-item`（flex 卡片）内，撑高不会压到相邻行。只补到过 AA，
   站点口径 44 留在探针 LOW 档提示（不阻塞）。 */
.news-item .news-more { display: inline-block; padding-block: var(--space-1); white-space: nowrap; font-size: var(--fs-caption); color: var(--color-interactive); font-weight: 600; }
.news-item .news-more:hover { color: var(--navy-900); }
/* 资讯行悬停（2026-10-22）：此前同样一条都没有。
   🔴 transition 里的 opacity / transform 是 `.reveal` 的原值，理由同 .honor-card（同优先级后写者赢）。
   🔴 抬升走 translate，别动 transform —— 那是 reveal 动画的。 */
.news-item {
  transition: opacity .6s cubic-bezier(.16, 1, .3, 1),
              transform .6s cubic-bezier(.16, 1, .3, 1),
              translate .2s ease,
              box-shadow .2s ease;
}
.news-item:hover {
  translate: 0 -2px;
  /* 底影换成令牌 --shadow-md（比原来的柔影深一档），再叠 1px 交互色环：
     只换环会把底影丢掉，白卡看着会变平。环用 color-mix 调透明度，不新增裸色值。 */
  box-shadow: var(--shadow-md),
              inset 0 0 0 1px color-mix(in srgb, var(--color-interactive) 55%, transparent);
}
/* 🔴 2026-10-29：标题改成**真链接**（`.news-item-link`），与悬停时的下划线对上了。
   此前标题是纯 `<h3>`：悬停出链接样式、点下去没反应 —— hover 与 click 语义不一致。
   ⚠️ 先试过「给 `.news-more` 加 `::after{inset:0}` 把点击面铺满卡片」，实测**不生效**：
      `elementFromPoint` 会返回链接，但 click 的 target 是卡片里的文字节点，跳转不发生。
      要「整卡可点」得把卡片本身套进链接，别用伪元素取巧。 */
.news-item-link { color: inherit; text-decoration: none; }
.news-item-link:focus-visible { outline: 2px solid var(--color-interactive); outline-offset: 3px; }
.news-item .news-more { transition: transform var(--duration-fast) var(--ease-out-quart); }
.news-item:hover .news-more { transform: translateX(4px); }
/* 「查看全部 N 篇」：关于页资讯只放 3 条，这里是通往资讯中心的出口（那边才是全量） */
.news-all {
  margin-top: var(--space-6);
  padding-top: var(--space-5);
  border-top: 1px solid var(--gray-100);
  text-align: right;
}
.news-all-link {
  display: inline-block;
  padding-block: var(--space-1);   /* 命中区 > 24（WCAG 2.5.8 AA），与 .news-more 同口径 */
  font-size: var(--fs-caption);
  font-weight: 600;
  color: var(--color-interactive);
}
.news-all-link:hover { color: var(--navy-900); }
.news-all-link span { display: inline-block; transition: transform var(--duration-fast) var(--ease-out-quart); }
.news-all-link:hover span { transform: translateX(4px); }
@media (max-width: 640px) {
  .news-item { flex-wrap: wrap; }
  .news-item .news-more { width: 100%; text-align: right; }
}

/* ── 资讯中心：页首全幅 hero（2026-10-22 第二版）─────────────────────
   头条即页首：整幅图（stage 1440×900，1:1 不放大）+ 左下角题注。
   替掉原来那张 648px 的「材料静物」装饰图 —— 它把第一条内容推到 1008px 之后，
   首屏一篇文章都看不到。
   🔴 必须配 scrim：案例封面多为亮图，白字直接压上去读不出（`.hero--light` 那条同族坑）。 */
.news-hero {
  position: relative; isolation: isolate; overflow: hidden;
  display: flex; align-items: center;
  /* 上下限写 rem：clamp() 里出现 px 会被「令牌与尺寸」那道门禁判红（根字号显式 16px，值恒等） */
  min-height: clamp(32.5rem, 72svh, 46rem);
  background: var(--navy-900);
}
.news-hero-media { position: absolute; inset: 0; z-index: 0; }
.news-hero-img { width: 100%; height: 100%; object-fit: cover; object-position: center; display: block; }
.news-hero-veil {
  position: absolute; inset: 0; z-index: 1;
  /* 两层：① 左侧横向压暗（文字全在左边）；② 底部纵向压暗（托住标题块）。
     🔴 只写纵向是不够的：实测「品牌资讯」那行落在亮墙面上，白字对比只有 **2.32**
        （正文文字都过 5.4，唯独它不过）—— 横向那层就是为它加的。 */
  background:
    linear-gradient(90deg, rgba(7, 18, 35, .74) 0%, rgba(7, 18, 35, .42) 45%, rgba(7, 18, 35, 0) 76%),
    linear-gradient(180deg, rgba(7, 18, 35, .34) 0%, rgba(7, 18, 35, .42) 40%, rgba(7, 18, 35, .84) 100%);
}
/* 2026-10-23：改为垂直居中后，原来那条「底部 8~16 留白」会把整块内容往上顶偏，故清零。 */
.news-hero-in { position: relative; z-index: 2; padding-block: 0; }
/* 页名（h1）：2026-10-23 视觉统一 —— 原来是 13px 小字（当时刻意做小，想让头条当主角），
   但首屏因此没有任何「页面级」标识，用户第一眼不知道自己在资讯页。
   现放大到与内页 .hero-title 同档（clamp 上限 5.5rem = 88px），头条降为二级信息。
   ⚠️ 放大后退回 `--font-display`（衬线）：13px 时用 `--font-en` 是为了跟英文小标一致，
      放大成标题后必须与全站 h1 同字族，否则字形突兀。
   ⚠️ `pointer-events: none` 必须保留：整幅大图是链接，标题不能挡住点击。 */
.news-hero-page {
  margin: 0 0 var(--space-8);
  font-family: var(--font-display);
  font-size: var(--fs-d2);
  font-weight: 700; line-height: 1.04; letter-spacing: 0;
  color: var(--white);
  text-wrap: balance;
  pointer-events: none;   /* 让点击穿到整幅链接上，别在标题上卡住 */
}
.news-hero-card { display: grid; gap: var(--space-3); max-width: 780px; text-decoration: none; color: var(--white); }
.news-hero-card::after { content: ''; position: absolute; inset: 0; z-index: 1; }
.news-hero-meta { display: flex; align-items: center; gap: var(--space-3); }
.news-hero-meta time { font-family: var(--font-en); font-size: var(--fs-small); color: rgba(255, 255, 255, .72); letter-spacing: .04em; }
.news-hero-meta .news-tag { background: rgba(255, 255, 255, .16); color: var(--white); }
.news-hero-title {
  margin: 0; font-family: var(--font-display); font-weight: 700;
  font-size: clamp(1.75rem, 3.4vw, 2.75rem); line-height: 1.32; color: var(--white);
  text-wrap: balance;
}
.news-hero-sum {
  font-size: var(--fs-body); line-height: 1.85; color: rgba(255, 255, 255, .82);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.news-hero-more { font-size: var(--fs-caption); font-weight: 600; color: var(--white); }
.news-hero-more i { font-style: normal; display: inline-block; transition: transform var(--duration-fast) var(--ease-out-quart); }
.news-archive-wrap { max-width: 1080px; }
.news-archive .section-heading { margin-bottom: var(--space-10); }

.news-row-meta { display: flex; align-items: center; gap: var(--space-3); }
.news-row-meta time {
  font-family: var(--font-en); font-size: var(--fs-small);
  color: var(--gray-500); letter-spacing: .04em;
}
.news-tag {
  display: inline-block; padding: 3px var(--space-2-5); border-radius: var(--radius-full);
  background: color-mix(in srgb, var(--blue-500) 12%, var(--white));
  color: var(--navy-700); font-size: var(--fs-nano); line-height: 1.4; letter-spacing: .04em;
}

.news-row {
  display: grid; grid-template-columns: 208px minmax(0, 1fr) 32px;
  gap: clamp(var(--space-4), 2.5vw, var(--space-8)); align-items: center;
  padding: var(--space-6) 0; border-bottom: 1px solid var(--gray-200);
  text-decoration: none; color: inherit;
}
.news-row-shot { display: block; aspect-ratio: 4 / 3; border-radius: var(--radius-md);
  overflow: hidden; background: var(--gray-100); }
.news-row-shot img { width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform .5s cubic-bezier(.22, .61, .36, 1); }
.news-row-body { display: grid; gap: var(--space-2); }
.news-row-title { margin: 0; font-family: var(--font-display); font-size: var(--fs-body-lg); font-weight: 700;
  line-height: 1.6; transition: color var(--duration-fast) var(--ease-out-quart); }
/* 摘要两行截断：10 条各写三行会把节奏拉散，两行足够让人决定点不点 */
.news-row-sum { font-size: var(--fs-caption); color: var(--gray-500); line-height: 1.8;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.news-row-more { font-size: var(--fs-body-lg); color: var(--color-interactive); text-align: right;
  transition: transform var(--duration-fast) var(--ease-out-quart); }

/* 🔴 悬停反馈整组收进 (hover: hover)：触摸端 :hover 会"粘住"，
   抬升/放大态抬起手指后不会复原 —— 与其在 shared.css 里写复位，不如一开始就不生效。 */
@media (hover: hover) {
  .news-lead:hover .news-lead-shot img { transform: scale(1.03); }
  .news-lead:hover .news-lead-more i { transform: translateX(4px); }
  .news-row:hover .news-row-shot img { transform: scale(1.05); }
  .news-row:hover .news-row-title { color: var(--navy-700); }
  .news-row:hover .news-row-more { transform: translateX(4px); }
}

@media (max-width: 1023px) {
  .news-lead { grid-template-columns: 1fr; }
  .news-row { grid-template-columns: 140px minmax(0, 1fr) 24px; }
}
@media (max-width: 640px) {
  /* 摘要要在手机上活下来（UX-19，2026-10-28）：原来这里是 display:none，10 条只剩标题
     ⇒ 每行等高、看不出该点哪篇（实测 390 下 9 行全部 123px、摘要可见数 0）。
     缩略图 112 + 间距 16 ⇒ 正文列约 214px，13px 三行 ≈ 39 字，多数摘要能读完整句；
     两行只有 26 字，实测每行都在句中「…」断开，反而像被截断的标题。
     ⚠️ 恢复显示必须写 `-webkit-box`（基础规则那三行 clamp 是一套）：改成 block 会让
     -webkit-line-clamp 失效，摘要直接铺满四行以上。
     ⚠️ 缩略图 104×78 → 112×112：正文有三行了，4:3 的图只占行高一半，图下空一大块；
     方图 + 112 与三行文字等高接近（行高 197 / 图 112）。
     ⚠️ align-items 由 center 改 start：正文比图高，居中会让图浮在整行中间、与首行标题错位。 */
  .news-row { grid-template-columns: 112px minmax(0, 1fr); gap: var(--space-4);
    padding: var(--space-5) 0; align-items: start; }
  .news-row-more { display: none; }
  .news-row-shot { aspect-ratio: 1 / 1; }
  .news-row-sum { display: -webkit-box; font-size: var(--fs-small); line-height: 1.7;
    -webkit-line-clamp: 3; }
  .news-row-title { font-size: var(--fs-body); }
}

/* ── 详情页：封面 + 相关的家（2026-10-22）─────────────────────────── */
.news-detail-cover { margin: var(--space-8) 0 var(--space-10); }
.news-detail-cover img { display: block; width: 100%; height: auto; aspect-ratio: 16 / 9;
  object-fit: cover; border-radius: var(--radius-lg); }
.news-cases { margin-top: var(--space-12); padding-top: var(--space-8); border-top: 1px solid var(--gray-200); }
.news-cases-title { font-family: var(--font-display); font-size: var(--fs-h3); font-weight: 700; }
.news-cases-desc { margin-top: var(--space-2); font-size: var(--fs-caption); color: var(--gray-500); }
.news-cases-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-6); margin-top: var(--space-6); }
@media (max-width: 640px) { .news-cases-grid { grid-template-columns: 1fr; } }

/* 文章页相关资讯 */
.news-related { margin-top: var(--space-10); padding-top: var(--space-8); border-top: 1px solid var(--gray-100); }
.news-related-title { font-size: var(--fs-body-lg); font-weight: 700; color: var(--navy-900); margin-bottom: var(--space-5); }
.news-related-list { display: flex; flex-direction: column; gap: var(--space-3); }
.news-related-item { display: flex; align-items: baseline; gap: var(--space-4); padding: var(--space-3) var(--space-4); background: var(--gray-100); border-radius: var(--radius-md); transition: background var(--duration-fast) var(--ease-out-quart); }
.news-related-item:hover { background: var(--cream-100); }
.news-related-date { flex-shrink: 0; font-size: var(--fs-nano); color: var(--gray-500); font-family: var(--font-en); }
.news-related-title-text { font-size: var(--fs-body-sm); color: var(--navy-900); font-weight: 500; }
.news-detail-back { display: flex; gap: var(--space-4); flex-wrap: wrap; }

/* News detail（新闻详情子页） */
/* 新闻详情页无深色 hero：固定 header 始终实色，避免白底白字不可见；首屏内容下移到 header 之下 */
/* 2026-10-08：本条与 shared.css 的 .scrolled 版是同一件事写了两遍 —— 但这条
   不带 .scrolled，等于 about/news 系列**永远**半透明 ⇒ 滚动时内容透出。改全不透明。 */
.site-header { background: var(--white); box-shadow: var(--shadow-xs); }
/* 🔴 2026-10-24（客户报「news/about 菜单为什么发灰」）：本页族是**白底页头**，
   必须显式关掉 shared.css 的页头暗 scrim。
   原因不是「白底不需要压暗」这么简单 —— `.site-header:not(.scrolled)::before` 的暗渐变
   带 `z-index:-1`，而页头自身有 `z-index`（已形成层叠上下文）⇒ 负 z-index 子层画在
   **页头背景之上**，白条被压成灰条（实测顶部 143、底部 199，本该 255）。
   这三页（about / news 列表）都带深色首屏容器，JS 不会给它们加 `.scrolled`，
   于是 `:not(.scrolled)` 一直命中。scrim 是给「透明页头压在图上的白字」准备的，这里没有那场景。
   ⚠️ 想改成透明页头？先看实测：白字压这三页首图顶部最坏只有 3.13–3.49:1（15px 需 4.5），
      而白底深字是 18.75:1 —— 所以这三页就该是白底。真要改，需连 scrim 强度一起重算。 */
.site-header::before { display: none; }
.site-header .nav-link { color: var(--navy-900); }
.site-header .nav-link::after { background: var(--navy-900); }
.site-header .brand-logo-white { opacity: 0; }
.site-header .brand-logo-color { opacity: 1; }
.news-detail { padding-top: calc(var(--header-height) + var(--space-10)); }
.news-detail-container { max-width: 680px; }
.breadcrumb {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: var(--space-2); font-size: var(--fs-small); color: var(--gray-500);
  margin-bottom: var(--space-10);
}
.breadcrumb a { color: var(--gray-500); text-decoration: none; }
.breadcrumb a:hover { color: var(--navy-900); }
.breadcrumb [aria-current] { color: var(--navy-900); }
.news-detail-author {
  display: inline-block; margin-left: var(--space-3);
  font-size: var(--fs-small); letter-spacing: .04em; color: var(--gray-500);
}
.news-detail-header {
  padding-bottom: var(--space-8);
  margin-bottom: var(--space-8);
  border-bottom: 1px solid var(--gray-100);
}
.news-detail-date {
  display: inline-block;
  font-family: var(--font-en);
  font-size: var(--fs-small); font-weight: 700; letter-spacing: .06em;
  color: var(--color-interactive);
  margin-bottom: var(--space-4);
}
.news-detail-title {
  font-family: var(--font-display);
  font-size: clamp(1.75rem, 4vw, 2.5rem);
  font-weight: 700; line-height: 1.3;
  color: var(--navy-900);
  margin-bottom: var(--space-5);
}
.news-detail-summary {
  font-size: var(--fs-body-lg); line-height: 1.8;
  color: var(--gray-700);
  padding-left: var(--space-5);
  border-left: 3px solid var(--blue-500);
}
.news-detail-body p {
  font-size: var(--fs-body); line-height: 1.8;   /* 1rem × 1.8 = 28.8px 行盒 */
  color: var(--gray-700);
  margin-bottom: var(--space-8);       /* 32px 段距 > 28.8px 行盒 ⇒ 段落边界才读得出来 */
}
/* 正文小标题（2026-10-24）：19px 不是拍的 —— 正文 16/1.8，段距 32；小标题取 19px 刚好比正文
   大一档（1.19×），再大会跟 h1(40px) 抢层级、再小就与加粗正文分不开。
   上距 40 > 下距 10：小标题要「粘住」它下面那段，而不是浮在上一段尾巴上。 */
.news-subhead {
  font-size: var(--fs-h4); font-weight: 600; line-height: 1.5;
  color: var(--navy-900); margin: var(--space-10) 0 var(--space-2-5);
}
.news-subhead:first-child { margin-top: 0; }

/* 阅读时长：跟在摘要下方，独立一行小字（不进摘要正文，避免与摘要混读） */
.news-detail-readtime {
  display: block;
  margin-top: var(--space-3);
  font-size: var(--fs-small);
  letter-spacing: .04em;
  color: var(--gray-500);
}

/* 目录：≥1024 右侧 sticky；≤1023 折成正文上方可展开的 details。
   ⚠️ 宽度用 calc(--space-16 × 3)=192px 而不是写 220px：设计令牌门禁对阶梯外
      裸字面只许收敛，新增一处就会被拦下。 */
/* 容器原来 680px（单栏阅读宽度）。加右栏后若不放宽，正文只剩 344px ≈ 21 字/行，
   比原来窄一半 —— 那是「加了目录反而更难读」。⇒ ≥1024 放到 896（正文 ≈656，与原先持平）。 */
@media (min-width: 1024px) {
  .news-detail-container { max-width: calc(var(--space-16) * 14); }
}
.news-body-wrap {
  display: grid;
  grid-template-columns: minmax(0, 1fr) calc(var(--space-16) * 3);
  gap: var(--space-10) var(--space-12);
  align-items: start;
}
/* DOM 顺序是 TOC 在前（读屏先给目录），视觉要把正文放左、目录放右 ⇒ 显式指派列 */
.news-detail-body { grid-column: 1; grid-row: 1; }
.news-toc { grid-column: 2; grid-row: 1; }
.news-toc {
  position: sticky;
  top: calc(var(--header-height) + var(--space-6));
  padding-left: var(--space-4);
  border-left: 1px solid var(--gray-100);
  font-size: var(--fs-small);
  max-height: calc(100svh - var(--header-height) - var(--space-16));
  overflow: auto;
}
.news-toc-title {
  margin: 0 0 var(--space-3);
  font-size: var(--fs-nano);
  letter-spacing: .14em;
  color: var(--gray-500);
}
.news-toc ol, .news-toc-mobile ol {
  margin: 0; padding: 0; list-style: none;
  display: grid; gap: var(--space-2-5);
}
.news-toc a, .news-toc-mobile a {
  display: block;
  padding-left: var(--space-3);
  margin-left: calc(var(--space-3) * -1);   /* 让 2px 竖线压在正文左缘上，不额外多 1px */
  border-left: 2px solid transparent;
  color: var(--gray-600);
  line-height: 1.5;
  text-decoration: none;
}
@media (hover: hover) {
  .news-toc a:hover, .news-toc-mobile a:hover {
    color: var(--blue-600);
    border-left-color: var(--blue-300);
  }
}
.news-toc-mobile { display: none; }
/* 锚点：不加这条，点目录后标题会钻到 sticky 站头下面 */
.news-subhead { scroll-margin-top: calc(var(--header-height) + var(--space-4)); }

@media (max-width: 1023px) {
  .news-body-wrap { display: block; }
  .news-toc { display: none; }
  .news-toc-mobile {
    display: block;
    margin: 0 0 var(--space-6);
    padding: var(--space-3) var(--space-4);
    border: 1px solid var(--gray-200);
    border-radius: var(--radius-md);
  }
  .news-toc-mobile summary {
    cursor: pointer;
    font-size: var(--fs-small);
    font-weight: 600;
    color: var(--navy-900);
  }
  .news-toc-mobile ol { margin-top: var(--space-3); }
}

.news-detail-body a {
  color: var(--blue-600);
  font-weight: 600;
  text-decoration: underline;
  text-decoration-color: rgba(183, 148, 62, .45);
  text-underline-offset: 4px;
  transition: color var(--duration-fast) var(--ease-out-quart), text-decoration-color var(--duration-fast) var(--ease-out-quart);
}
.news-detail-body a:hover {
  color: var(--color-interactive);
  text-decoration-color: var(--color-interactive);
}
.news-nav {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: var(--space-4);
  margin: var(--space-10) 0 var(--space-8);
  padding-top: var(--space-8);
  border-top: 1px solid var(--gray-100);
}
.news-nav-item {
  display: flex; flex-direction: column; gap: var(--space-2);
  padding: var(--space-5);
  background: var(--cream-100);
  border-radius: var(--radius-lg);
  text-decoration: none;
  transition: transform var(--duration-fast) var(--ease-out-quart), background var(--duration-fast) var(--ease-out-quart);
}
a.news-nav-item:hover { transform: translateY(-2px); background: var(--cream-200); }
.news-nav-next { text-align: right; }
.news-nav-disabled { opacity: .5; }
.news-nav-label { font-size: var(--fs-nano); color: var(--color-interactive); font-weight: 700; letter-spacing: .08em; }
.news-nav-title { font-size: var(--fs-caption); color: var(--navy-900); line-height: 1.5; }
.news-detail-back { text-align: center; }
@media (max-width: 640px) {
  .news-nav { grid-template-columns: 1fr; }
}

/* ===== 首屏「穿窗」（2026-10-22 · 方案②：暗壳 + 开口放大）=====
   思路来自 GreenSock 的 ScrollTrigger Image Zoom（首屏随滚动推近）。
   做法改成：**把画面裁成一扇窗，滚动时窗放大到铺满** ——
   观感是「站在暗处，看着一扇发光的窗，然后走进去」，且**零新素材**。
   骨架：外层 200svh 给行程 + 内层 sticky 100svh 钉住；JS 每帧只写 clip-path / transform / opacity。 */
.hero-zoom { position: relative; height: 100svh; }
.hero--zoom { position: sticky; top: 0; height: 100svh; min-height: 0; }
/* 暗壳：洞口以外全是它（不铺的话会露出白底）。
   ⚠️ 必须走令牌：裸 hex 会被色板审计判成「体系外色值」。
   中央再加一层极淡的径向白光 =「光从窗里洒到墙上」的暗示；纯 rgba，不引入新色值。 */
.hero--portal {
  background:
    radial-gradient(ellipse 74% 58% at 50% 32%, rgba(255, 255, 255, .06) 0%, rgba(255, 255, 255, 0) 72%),
    var(--navy-900);
}
/* 🔴 `is-ready` 由 JS 加，**没它就不启用动效** —— 无 JS / 关动效 / ≤767px 时保持普通整幅首屏 */
/* 方案①：洞口是**真实画面里的洞**（洞底在视口 87% 左右），标题只能落在洞口下方
   那一条走廊地面上，否则白字直接压在沙发与窗景上。
   按这条反推：标题块总高必须 ≤ 视口 10%（1080 ⇒ 105px）⇒ 本页单独收字号。 */
.hero--portal.is-ready { align-items: flex-end; padding-bottom: 3.2svh; }
.hero--portal .hero-title {
  font-size: clamp(2.25rem, 3.9vw, 3.5rem);
  margin-bottom: var(--space-3);
}
.hero--portal .hero-title-ch {
  font-size: clamp(1.05rem, 1.7vw, 1.5rem);
  margin-top: var(--space-2);
}
/* 方案① 双层（2026-10-22）：不再用 clip-path 造假洞。
   后层 = 完整画面（含走廊墙），前层 = 同一张图把洞口挖空。
   起始帧两层完全重合 ⇒ 看不出是两层；滚动时前层 1.988×、后层 2.286×，
   洞口边先到边、洞内还在往里走 ⇒ 真位移（不是整张放大）。 */
.hero--portal .hero-bg { clip-path: none; }
.hero--portal .hero-bg--front { pointer-events: none; }
/* 移动端不启用穿越（沿用 ≤767px 关闭策略）：前层直接不参与渲染，
   后层单独成一张普通整幅首屏，不需要门框层 */
@media (max-width: 767px) {
  .hero--portal .hero-bg--front { display: none; }
}
.hero--portal .hero-bg img {
  /* 🔴 底图本来带 hero-kenburns 无限动画：CSS 动画会压过内联 transform ⇒ 不清掉 JS 写了也看不见 */
  animation: none;
  transform: scale(1);
  transform-origin: 50% 50%;
  will-change: transform;
  backface-visibility: hidden;
}
/* 方案① 的文字落在**真实画面**上（走廊墙 + 明亮门槛），不再落在暗壳上 ⇒
   压暗层不能一进 is-ready 就撤：留着它，由 JS 跟着文字一起淡出（0.30→0.50）。
   这里不给静态 opacity —— 静态值会盖住 JS 写的内联值。 */
/* 新底图比原来的木作微距亮得多（中间调 138 : 38）⇒ 压暗层按「亮图」配一版；
   不抬高的话，白字落在窗景与奶油地面上只剩 2 点几的对比度。只作用于本页，不动 shared 默认。 */
/* 新底图比原来的木作微距亮得多（中间调 138 : 38）⇒ 压暗层不能照抄 shared 的「整幅压」：
   整幅压下去，收尾那帧又暗回来，正好把「走进去是亮的」这件事抵消掉。
   改成**只压底部**（标题在 66–78%），中段几乎全透，亮感留到最后一帧。
   实测：标题区底 L≈0.23，底部 α 0.62 时白字 5.9:1。只作用于本页，不动 shared 默认。 */
/* 方案①：底图本身就是亮画面（不是暗壳），**不能再整幅压 navy** ——
   顶部一压，奶油墙直接变灰，整屏脏。改成只压底部一条：
   50% 以上全透（保住洞内亮度与墙面的暖），再往下渐深，托住标题。
   实测（1920×1080，无字控制组）：标题区 90 分位白字对比度 7.7:1、副标 12.7:1，
   远高于 AA 4.5 ⇒ 不必压到 .84，压死会把走廊地面（方案里要有的⑦）做成一块黑。 */
.hero--portal .hero-overlay {
  background: linear-gradient(
    180deg,
    rgba(7, 18, 35, 0) 0%,
    rgba(7, 18, 35, 0) 50%,
    rgba(7, 18, 35, .22) 72%,
    rgba(7, 18, 35, .52) 88%,
    rgba(7, 18, 35, .68) 100%
  );
}
/* 移动端走竖构图（裁的是画面中央）：标题正压在窗景与茂叶上，实测文字区 p95 亮度 0.24
   ⇒ 对白字只有 3.6:1、不到 4.5。这一段单独加深，桌面端不需要。 */
/* 移动端竖构图（9:16 单独出图）里，房间本身就占满画面、底部是浅橡木地面，
   照抄旧图的 .74/.60/.86 会把整幅压成灰泥，房间看不清。
   改成「上下压、中间放」，同时把标题压到地毯与地面那一带，别盖住餐桌和花器。 */
@media (max-width: 767px) {
  .hero--portal .hero-overlay {
    background: linear-gradient(
      180deg,
      rgba(7, 18, 35, .52) 0%,
      rgba(7, 18, 35, .30) 38%,
      rgba(7, 18, 35, .46) 62%,
      rgba(7, 18, 35, .88) 100%
    );
  }
  .hero--portal .hero-content {
    margin-top: auto;
    /* 2026-10-26 全站审评后调整：手机端标题 30.4px 太小 —— 这一屏只有「富喆整装」四个字，
       在 390 宽上占不到 1/5 行宽，撑不住整幅房间。放大到 ~39px（块高 +10px，向上长）。
       ⚠️ margin-bottom 保持 12svh 不动：块底一变，"下滑探索" 与 CTA 的间距就要重排。
       ⚠️ **只改 ≤767**：桌面端标题被「洞口下方的走廊地面」这条硬约束卡住
          （标题块总高必须 ≤ 洞底以下那条带，否则白字压到亮窗景上），48.96px 已是上限。
          要改桌面得先动洞口裁切，属另一件事，别在这里顺手放大。 */
    margin-bottom: 12svh;
  }
  .hero--portal .hero-title { font-size: clamp(2.4rem, 10vw, 3rem); }
  .hero--portal .hero-title-ch { font-size: var(--fs-body-lg); }
}
.hero--portal .hero-content { will-change: opacity; }
.hero--portal.is-ready .scroll-cue { display: none; }
@media (prefers-reduced-motion: reduce) {
  .hero-zoom { height: 100svh; }
  .hero--portal .hero-bg { clip-path: none; }
  .hero--portal .hero-bg img { transform: none; will-change: auto; }
}
/* 触摸端 hover 残留复位 —— 必须写在页面级 CSS 内：shared.css 先加载，同优先级下复位会被本文件覆盖 */

@media (hover: none) {
  .honors-section .honors-toggle-wrap .honors-toggle:hover,
  a.news-nav-item:hover {
    transform: none;
  }
}
