/* ============================================================
   CIFANG 此方地标营造 · 官网样式（黑色主题 + 红色点缀）
   页面：首页 / 宣恩详情 / 利川详情（共享）
   ============================================================ */

/* ---------- 英文字体（自托管）----------
   Space Grotesk 可变字体：拉丁 + 数字子集，21.8KB，OFL 许可。
   ⚠️ 背景：原先 --font-en 第一顺位写了 "Space Grotesk"，但全站从未加载过它
   （无 @font-face / 无在线字体 / 无字体文件），英文与所有数字实际渲染成
   Segoe UI（Windows）· Arial（macOS）等系统默认字体。此处补上 @font-face 才真正生效。
   自托管而非引 Google Fonts：国内访问更稳、与静态托管缓存策略一致。
   注意：本字体不含中文字形，中文仍由 --font-cn 的系统中文字体栈承担。 */
@font-face{
  font-family:"Space Grotesk";
  font-style:normal;
  font-weight:300 700;
  font-display:swap;
  src:url(../fonts/space-grotesk-latin-var.woff2) format("woff2");
}

/* ---------- 设计令牌 ---------- */
:root{
  --bg:#0A0A0C;
  --bg-elev:#121216;
  --bg-elev2:#17171C;
  --fg:#F5F5F4;
  --fg-muted:#A1A1AA;
  --fg-dim:#6B6B74;
  --line:rgba(255,255,255,.12);
  --line-strong:rgba(255,255,255,.22);
  --red:#BD1111;
  --red-text:#D44545;
  --red-soft:rgba(189,17,17,.12);
  --radius:8px;
  --radius-lg:16px;
  --container:1440px;
  --gutter:clamp(20px,5vw,96px);
  --sect-gap:clamp(24px,2.5vw,40px);
  --font-cn:-apple-system,BlinkMacSystemFont,"PingFang SC","HarmonyOS Sans SC","Microsoft YaHei","Noto Sans SC",sans-serif;
  --font-en:"Space Grotesk","Segoe UI",Helvetica,Arial,sans-serif;
  --ease:cubic-bezier(.22,.61,.36,1);
}

*{margin:0;padding:0;box-sizing:border-box}
html{scroll-behavior:smooth}
/* ---------- 页面底色 + 极淡噪点颗粒（0.30.2）----------
   经鸣：「只做噪点」—— 在整页底色上叠一层几乎察觉不到的颗粒，
   给大面积纯黑增加哑光「材质感」，避免扁平死板；**与卡片 hover 无关**。

   ⚠️ 实现要点（三个都不能改错）：
   1. 必须写 `background-color` 而不是 `background` 简写
      —— 简写会把下面刚加的 background-image 一并重置，噪点会消失。
   2. 直接平铺在 body 最底层：不占层级、不吃指针、不随滚动重绘。
      （试过 body::before + z-index:-1，会被 body 自身背景色盖住，不可行。）
   3. 噪点走 SVG feTurbulence 内联、零网络请求；`feColorMatrix saturate 0`
      把彩色噪声压成灰阶 —— 彩色颗粒在纯黑底上会「发花」，灰阶才是哑光。
   ⚠️ 强度调参：颗粒由 rect 的 opacity 控制；太强会「显脏」，太弱则看不见。
   ⚠️ 实测教训：第一版取 .05 —— 结果**几乎等于没有**。
      feTurbulence 的输出以中灰为主，再乘 .05 就被完全抹平（逐像素只剩 9/10 两级）。
      提到 .14 后才有可辨的随机颗粒。调这个值必须**逐像素实测**，肉眼在截图上根本看不出来。 */
body{
  background-color:var(--bg);
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.14'/%3E%3C/svg%3E");
  color:var(--fg);
  font:400 16px/1.75 var(--font-cn);
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
::selection{background:var(--red);color:#fff}
a{color:inherit;text-decoration:none}
img{display:block;max-width:100%}
button{font:inherit;cursor:pointer;border:none;background:none;color:inherit}

/* ---------- 跳到主内容（键盘无障碍 / WCAG 2.4.1 Bypass Blocks） ----------
   作用：键盘用户按第一下 Tab 就能跳过顶部长导航直达正文，
   不必逐个 Tab 穿过导航里的二十多个链接（视障用户尤其依赖）。
   平时藏在视口外，只在被聚焦时滑入 —— 鼠标用户永远看不到它。
   ⚠️ 用 transform 位移而非 top（本项目动效约束：只动 transform/opacity）；
   ⚠️ z-index 取 200，必须高于 .nav 的 100，否则被固定导航盖住。 */
.skip-link{
  position:fixed;
  left:12px;top:12px;z-index:200;
  transform:translateY(-220%);
  padding:12px 20px;border-radius:4px;
  background:var(--red);color:#fff;
  font:600 15px/1 var(--font-cn);letter-spacing:.02em;
  text-decoration:none;white-space:nowrap;
  transition:transform .2s var(--ease);
}
.skip-link:focus{transform:none}
@media (prefers-reduced-motion:reduce){.skip-link{transition:none}}
/* 跳转落点不能被顶部固定导航遮住；锚点本身高度为 0，不占布局 */
#main{scroll-margin-top:clamp(72px,8vw,96px)}
.skip-anchor{display:block;height:0}

/* ---------- 悬浮「联系我们」入口（FAB） ----------
   贴在视口右边缘、垂直居中：平时是一枚右圆左平的胶囊。
   ⚠️ z-index 取 90，**低于 .nav 的 100**，避免盖住顶部导航的下拉菜单。
   ⚠️ 窄屏（≤1024px）降级为右下角圆钮并隐藏文字 —— 侧边胶囊在手机上会压到正文。
   元素由 main.js 动态创建，样式写在这里是为了复用设计令牌与动效约束。 */
.contact-fab{
  position:fixed;top:50%;right:0;z-index:90;
  transform:translateY(-50%);
  display:inline-flex;align-items:center;
  padding:14px 12px;
  background:var(--red);color:#fff;
  font:600 14px/1 var(--font-cn);letter-spacing:.02em;
  text-decoration:none;white-space:nowrap;
  border-radius:999px 0 0 999px;
  box-shadow:0 6px 24px rgba(0,0,0,.38);
  transition:padding .25s var(--ease),box-shadow .25s var(--ease);
}
.contact-fab svg{flex:none}
/* 平时文字收起（只占 ≈41px，几乎不遮内容）；hover/聚焦才展开
   —— 最初做成常开胶囊，实测会压住最右一列卡片，故改为「图标常驻 + 文字按需」。
   用 max-width 过渡而非 display，保证键盘 Tab 到它时也能展开。 */
.contact-fab span{
  max-width:0;overflow:hidden;
  margin-left:0;                        /* 收起时不留间距（用负 margin 会把图标盖住） */
  transition:max-width .28s var(--ease),margin-left .28s var(--ease);
}
.contact-fab:hover,.contact-fab:focus-visible{padding-right:18px;box-shadow:0 8px 30px rgba(189,17,17,.42)}
.contact-fab:hover span,.contact-fab:focus-visible span{max-width:130px;margin-left:9px}
.contact-fab:active{transform:translateY(-50%) scale(.97)}
@media (max-width:1024px){
  .contact-fab{
    top:auto;bottom:20px;right:16px;
    transform:none;
    padding:15px;border-radius:999px;
  }
  .contact-fab:hover{padding-right:15px}
  .contact-fab:active{transform:scale(.97)}
  .contact-fab span{display:none}
}
@media print{.contact-fab{display:none}}

/* ---------- 「回到上方」按钮（0.29.76）----------
   经鸣：右侧再加一个回到上方的按钮。
   做法与「联系我们」FAB 保持同一套语言：**右侧贴边、同形状（左半圆）**，
   排在 FAB 正下方（FAB 是 top:50% 居中，故这里 50% + 偏移）。
   ⚠️ 默认 opacity:0 + visibility:hidden —— 只在滚动超过一屏后才浮出，
      避免刚进页面就挂个没用的按钮。
   ⚠️ 用 visibility 而不是 display —— display 无法参与过渡，会突兀闪现。 */
.to-top{
  position:fixed;top:calc(50% + 40px);right:0;z-index:90;
  width:46px;height:46px;
  display:grid;place-items:center;
  border:1px solid var(--line-strong);border-right:none;
  border-radius:999px 0 0 999px;
  background:rgba(16,16,19,.9);
  -webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);
  color:var(--fg-muted);cursor:pointer;padding:0;
  box-shadow:0 6px 24px rgba(0,0,0,.32);
  opacity:0;visibility:hidden;transform:translateX(10px);
  transition:opacity .3s var(--ease),transform .3s var(--ease),
             visibility .3s linear,color .2s,border-color .2s;
}
.to-top.is-on{opacity:1;visibility:visible;transform:none}
.to-top:hover,.to-top:focus-visible{color:var(--fg);border-color:var(--fg-muted)}
.to-top:active{transform:scale(.94)}
@media (prefers-reduced-motion:reduce){
  .to-top{transition:opacity .01s linear,visibility .01s linear}
  .to-top{transform:none}
}
@media print{.to-top{display:none}}

/* ---------- 「此页暂无该语言版本」提示条 ----------
   由 main.js 在检测到 ?fallback=<lang> 时创建。
   ⚠️ 固定在**底部**而非顶部：`.nav` 是 fixed;top:0，且滚动时高度会变
   （滚过 24px 才加毛玻璃），放顶部就得算偏移，很脆。 */
.fallback-bar{
  position:fixed;left:0;right:0;bottom:0;z-index:95;
  display:flex;align-items:center;gap:16px;
  padding:14px clamp(16px,4vw,40px);
  background:var(--bg-elev2);
  border-top:1px solid var(--line-strong);
  box-shadow:0 -8px 28px rgba(0,0,0,.42);
}
.fallback-bar .fallback-text{
  flex:1;margin:0;
  display:flex;flex-direction:column;gap:2px;
  font-size:13.5px;line-height:1.5;color:var(--fg-muted);
}
.fallback-bar .fallback-native{color:var(--fg);font-weight:500}
.fallback-bar .fallback-en{font-size:12.5px;color:var(--fg-dim)}
.fallback-bar .fallback-close{
  flex:none;width:32px;height:32px;border-radius:50%;
  color:var(--fg-muted);font-size:14px;line-height:1;
  transition:color .2s var(--ease),background .2s var(--ease);
}
.fallback-bar .fallback-close:hover{color:var(--fg);background:rgba(255,255,255,.06)}
@media print{.fallback-bar{display:none}}

.container{max-width:var(--container);margin:0 auto;padding-left:var(--gutter);padding-right:var(--gutter)}

/* ---------- 通用区块 ---------- */
.section{padding:var(--sect-gap) 0;position:relative;overflow:visible}
#workflow::before{
  content:"";
  position:absolute;
  right:-6%;bottom:-10%;
  width:clamp(300px,38vw,500px);height:clamp(300px,38vw,500px);
  background:url(../img/logo-line.png) no-repeat center/contain;
  opacity:.06;
  pointer-events:none;
  z-index:0;
}
.section-head{margin-top:calc(-1*clamp(40px,5vw,100px));margin-bottom:clamp(8px,1vw,16px)}
.eyebrow{
  font-weight:600;
  font-size:clamp(18px,2vw,26px);
  font-family:var(--font);
  letter-spacing:.18em;
  color:var(--red);
  margin-bottom:16px;
  text-transform:none;
}
.section-title{
  font-size:clamp(32px,4.2vw,52px);
  font-weight:700;
  line-height:1.25;
  letter-spacing:.02em;
}
.section-sub{
  margin-top:14px;
  color:var(--fg-muted);
  font-size:clamp(15px,1.6vw,18px);
  max-width:720px;
}

/* 区块大编号（背景水印式） */
.section-num{
  position:absolute;
  top:clamp(16px,2vw,32px);
  right:var(--gutter);
  font:700 clamp(96px,16vw,220px)/0.72 var(--font-en);
  color:rgba(255,255,255,.035);
  pointer-events:none;
  user-select:none;
  z-index:0;
}
.section>.container,.section>*{position:relative;z-index:1}

/* ---------- 占位图（纯文字粗体，不生成图片） ---------- */
.ph{
  position:relative;
  display:flex;
  align-items:center;
  justify-content:center;
  width:100%;
  height:100%;
  background:
    radial-gradient(120% 90% at 70% 20%,#17171f 0%,#0d0d11 55%,#0a0a0c 100%);
  overflow:hidden;
}
.ph::before{ /* 模拟光带 */
  content:"";
  position:absolute;left:0;right:0;top:50%;
  height:1px;
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.14),transparent);
}
.ph-text{
  position:relative;
  font:700 clamp(16px,2.6vw,30px)/1.4 var(--font-cn);
  color:rgba(255,255,255,.14);
  letter-spacing:.08em;
  text-align:center;
  padding:0 24px;
}
.ph .ph-note{
  position:absolute;
  bottom:14px;right:20px;
  font:500 11px/1 var(--font-en);
  letter-spacing:.18em;
  text-transform:uppercase;
  color:rgba(255,255,255,.22);
}
.ph img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:0}

/* ---------- Logo 水印（低透明度大红字，叠加案例图） ---------- */
.wm::after{
  content:"CIFANG";
  position:absolute;
  right:clamp(16px,3vw,48px);
  bottom:clamp(16px,3vw,40px);
  font:800 clamp(56px,9vw,140px)/1 var(--font-en);
  letter-spacing:-.02em;
  color:var(--red);
  opacity:.05;
  pointer-events:none;
  user-select:none;
  z-index:2;
  transition:opacity .35s var(--ease);
}
.case-card:hover .wm::after{opacity:.09}

/* ---------- 导航 ---------- */
.nav{
  position:fixed;top:0;left:0;right:0;z-index:100;
  transition:background .35s var(--ease),border-color .35s var(--ease),backdrop-filter .35s, transform .35s var(--ease);
  border-bottom:1px solid transparent;
}
.nav.scrolled{
  background:rgba(10,10,12,.82);
  backdrop-filter:blur(14px);
  -webkit-backdrop-filter:blur(14px);
  border-bottom-color:var(--line);
}
.nav.hidden{
  transform:translateY(-100%);
}
.nav-inner{
  max-width:var(--container);
  margin:0 auto;
  padding:0 var(--gutter);
  height:72px;
  display:flex;align-items:center;justify-content:space-between;
}
.brand{display:flex;align-items:center;gap:12px;font-weight:700;letter-spacing:.04em}
.brand-mark{
  width:38px;height:38px;flex:none;
  display:flex;align-items:center;justify-content:center;
}
.brand-mark img{width:100%;height:100%;object-fit:contain;display:block}
.brand-text{display:inline-block;vertical-align:middle}
.brand-cn{display:block;font-size:16px;white-space:nowrap;text-align:center}
.brand-en{display:block;width:0;min-width:100%;font:700 9px/1 var(--font-en);letter-spacing:.10em;color:var(--fg-muted);text-transform:uppercase;margin-top:3px;text-align:justify;text-align-last:justify}
.nav-links{display:flex;align-items:center;justify-content:space-between;flex:1;gap:clamp(14px,2vw,30px);padding-left:clamp(24px,4vw,60px)}
.nav-group{display:flex;align-items:center;gap:clamp(14px,2vw,24px)}
.nav-links a{font-size:15px;color:var(--fg-muted);transition:color .25s;position:relative;padding:6px 0}
.nav-links a::after{
  content:"";position:absolute;left:0;right:100%;bottom:0;height:2px;background:var(--red);
  transition:right .25s var(--ease);
}
.nav-links a:hover,.nav-links a.active{color:var(--fg)}
.nav-links a.active::after{right:0}
/* 悬浮时红条也展开（经鸣 2026-09-18）。
   复用上面那条 ::after：left:0 固定、right 100%→0，即「从左往右长出来」、
   移开时再从右往左收回；与 .active 共用同一个 transition，
   所以悬浮态与选中态的动效完全一致（不会一个扫一个淡）。
   ⚠️ 必须排除两类链接，否则红条会挂得很怪：
     ① .btn-contact ——「联系」是红色按钮，红字下面再压一条红横线很怪
       （它自己的 .active::after 也是 display:none，见下方两行）
     ② .nav-dropdown-item —— 下拉浮层里的菜单项，每项都挂一条红条会乱成一团
       （它们本来就是浮层里高亮，不需要下划线） */
.nav-links a:hover:not(.btn-contact):not(.nav-dropdown-item)::after{right:0}
.btn-contact{
  color:var(--red-text);opacity:.9;
  transition:color .25s,opacity .25s;
}
.btn-contact:hover{color:var(--red);opacity:1}
/* 「联系」是红色按钮：滚到联系板块时它是选中的，但不该套用普通的
   白字 + 下划线样式（红色按钮上挂一条红横线很怪）。
   此处提高特异性盖过 .nav-links a.active，并隐藏 ::after。 */
.nav-links a.btn-contact.active{color:var(--red);opacity:1}
.nav-links a.btn-contact.active::after{display:none}
/* 语言下拉
   ⚠️ 语言块现在位于 </nav> 之外、.nav-inner 的直接子元素（汉堡按钮左侧），
      不再被 .nav-links 的 gap 撑开间距，故用 margin-left 补回。 */
.lang-wrap{position:relative;margin-left:clamp(14px,2vw,30px)}
.lang-btn{
  display:flex;align-items:center;gap:6px;
  font:600 13px var(--font-en);letter-spacing:.08em;
  color:var(--fg-muted);background:none;border:none;
  padding:6px 4px;cursor:pointer;
  transition:color .25s;
}
.lang-btn:hover{color:var(--fg)}
.lang-btn .cur{color:var(--red-text);opacity:.9}
.lang-btn svg{transition:transform .25s}
.lang-wrap.open .lang-btn svg{transform:rotate(180deg)}
.lang-menu{
  display:none;
  position:absolute;top:calc(100% + 6px);right:0;
  min-width:180px;
  background:var(--bg-elev2);
  border:1px solid var(--line-strong);
  border-radius:var(--radius);
  box-shadow:0 8px 32px rgba(0,0,0,.6);
  overflow:hidden;
  z-index:200;
}
.lang-wrap.open .lang-menu{display:block}
/* ---------- 悬停即展开（0.29.67）----------
   经鸣：语言栏和紧邻的导航下拉手感不一致（那边 hover 就弹，这边要点一下）。
   ⚠️ 仅在有精确指针的鼠标设备上启用；触摸设备仍走原来的「点击 → .open」，
      @media 已把它排除，两者互不干扰。
   ⚠️ 不加 :focus-within —— .lang-btn 是 <button>，键盘 Enter 本就会触发 click
      切到 .open；若再加 focus-within，焦点留在按钮上时菜单将无法被
      「点空白处关闭」的逻辑收起来。
   ⚠️ 不要用 .lang-menu::before 做桥：菜单自己有 overflow:hidden，伪元素会被裁掉。 */
@media (hover:hover) and (pointer:fine){
  /* 透明"桥"：补住按钮与菜单之间的缝隙，让鼠标从按钮移向菜单时不掉 hover。
     只在 hover 时生成，平时不占位、不遮挡下方内容的点击。
     ⚠️⚠️ 0.30.1 修正：原来写的是 `left:0;right:0`（= 只有按钮那么宽），
        但菜单是 `right:0` + `min-width:180px`，比 40px 的按钮【向左宽出 140px】。
        于是【斜着】从左上往右下移向菜单时，鼠标会先离开 .lang-wrap → hover 断 → 菜单收起。
        实测（1440 视口）：
          .lang-wrap 40×31 (left=1328) · .lang-menu 180×337 (left=1188) → 左缘差 140px
          按钮底 52 → 菜单顶 58（缝 6px）
          沿"按钮左下角 → 菜单左上角"采样 7 点，5 点落在 .lang-wrap 之外 ✗
     修法：把桥【向左铺满菜单宽度】，高度也从 10px 加到 16px（覆盖 6px 缝 + 斜穿余量）。 */
  .lang-wrap:hover::after{
    content:"";position:absolute;
    /* ⚠️ 从 100% 上移 4px：斜穿会掠过按钮【左下角外侧】那 2px，
       起点若正好卡在 100%（=按钮底）会漏掉（实测采样 (1321,50) 断在这里）。 */
    top:calc(100% - 4px);
    right:0;
    left:-140px;   /* ⚠️ 对齐菜单左缘（菜单 min-width:180 − 按钮 40 = 140） */
    height:20px;   /* 上移 4px 后仍要盖到 68（= 按钮底 52 + 16） */
  }
  .lang-wrap:hover .lang-menu{display:block}
  .lang-wrap:hover .lang-btn svg{transform:rotate(180deg)}
}
.lang-menu a{
  display:flex;align-items:center;justify-content:space-between;
  padding:10px 16px;font-size:14px;color:var(--fg-muted);
  border-bottom:1px solid var(--line);transition:background .2s,color .2s;
  /* ⚠️ 显式 line-height：.lang-zh 内部嵌了两个 inline 的 <a>（简 / 繁），
     若两边都靠继承，行盒高度会差 1px（实测 47 vs 46），中文那行就比别的行高一点点。
     统一写死，两边必然等高。 */
  line-height:1.5;
}
.lang-menu a:last-child{border-bottom:none}
.lang-menu a:hover{background:rgba(255,255,255,.04);color:var(--fg)}
.lang-menu a.active{color:var(--red-text)}
.lang-menu a .code{font:600 11px var(--font-en);color:var(--fg-dim);letter-spacing:.1em}
/* ---------- 中文项：「简 | 繁」占一行（0.29.66）----------
   经鸣指出：把「简体中文 / 繁體中文」并列成两个语言条目是政治错误 ——
   简繁是**同一语言的两种书写形式**，不该与 English / Deutsch 平级并列。
   最终形态（经鸣定）：中文仍占**一个高度**，左侧就是「简 | 繁」两个单字，
   右侧照旧是代号 ZH —— 与其它语言项**同一版式、等高对齐**。
   ⚠️ 这一格不是 <a>，而是 <div class="lang-zh">（内部两个 <a>），
      因为一个 <a> 里不能再嵌 <a>；故 .lang-menu a 的样式不适用于它，
      这里要**完整照抄** .lang-menu a 的盒模型（flex / space-between / padding / border-bottom），
      否则行高与分隔线会和相邻语言项对不齐。 */
.lang-zh{
  display:flex;align-items:center;justify-content:space-between;
  padding:10px 16px;font-size:14px;color:var(--fg-muted);
  border-bottom:1px solid var(--line);
  line-height:1.5;   /* 必须与 .lang-menu a 相同（见上方注释），否则差 1px */
}
.lang-zh .pair{display:flex;align-items:center;gap:6px;line-height:1.5}
/* ⚠️ 内层这两个 <a>（简 / 繁）会被 .lang-menu a 规则命中，必须逐项抵消：
      · border-bottom —— 不抵消则每个 <a> 高 22px（21+1），整行比别的语言项高 1px
      · display:flex —— 让它内部文本按 flex 居中排版，位置会偏
      · padding —— 否则两个单字被 10px/16px 的菜单内距撑开 */
.lang-zh .pair a{padding:0;border-bottom:none;display:inline-block;color:inherit;line-height:1.5;transition:color .2s}
.lang-zh .pair a:hover{color:var(--fg)}
.lang-zh .pair a.active{color:var(--red-text)}
.lang-zh .pair .sep{color:var(--line-strong);font-size:12px;opacity:.75;user-select:none}
.lang-zh .code{font:600 11px var(--font-en);color:var(--fg-dim);letter-spacing:.1em}
.nav-toggle{display:none;flex-direction:column;gap:5px;width:26px}
.nav-toggle span{height:2px;background:var(--fg);transition:.3s}
.nav-toggle.open span:nth-child(1){transform:translateY(7px) rotate(45deg)}
.nav-toggle.open span:nth-child(2){opacity:0}
.nav-toggle.open span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}

/* ---------- Hero ---------- */
.hero{
  position:relative;
  height:100vh;min-height:640px;
  display:flex;align-items:center;
  overflow:hidden;
}
.hero .ph{position:absolute;inset:0}
/* ---------- 首屏照片缓慢推近（Ken Burns，0.29.40）----------
   模拟无人机巡航的呼吸感：26s 一个来回、scale 仅 1 → 1.08、伴随极小位移。
   ⚠️ 幅度必须小：位移量（1.6%/1.2%）始终小于缩放带来的裁切余量（每边约 4%），
      因此任何时间点都不会露出图片边缘。
   ⚠️ .hero 已有 overflow:hidden，缩放超出部分被裁掉，不影响布局。
   ⚠️ 只动 transform（合成层），不触发布局/重绘。 */
.hero .ph img,
.case-hero .ph img{ /* 案例详情页头图同样用这套推近（0.29.43 同步） */
  transform-origin:50% 45%;
  will-change:transform;
  animation:hero-kenburns 26s ease-in-out infinite alternate;
}
@keyframes hero-kenburns{
  0%{transform:scale(1) translate3d(0,0,0)}
  100%{transform:scale(1.08) translate3d(-1.6%,-1.2%,0)}
}
@media (prefers-reduced-motion:reduce){
  .hero .ph img,
  .case-hero .ph img{animation:none;will-change:auto;transform:none}
}
.hero .ph::after{ /* 暗化 60% 保证文字对比 */
  content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(10,10,12,.55) 0%,rgba(10,10,12,.45) 45%,rgba(10,10,12,.92) 100%);
}
.hero-inner{position:relative;z-index:3;max-width:var(--container);margin:0 auto;padding:clamp(140px,22vh,300px) var(--gutter) 0;width:100%}
.hero-en{
  font:700 clamp(16px,2.2vw,26px) var(--font-en);
  letter-spacing:.42em;text-transform:uppercase;
  color:var(--fg-muted);margin-bottom:24px;
}
.hero-title{
  font-size:clamp(38px,6.4vw,84px);
  font-weight:800;
  line-height:1.12;
  letter-spacing:.02em;
  max-width:12em;
}
.hero-title .hl{
  background:var(--red);
  color:#fff;
  padding:0 .12em;
  box-decoration-break:clone;
  -webkit-box-decoration-break:clone;
  transition:background .3s var(--ease),color .3s var(--ease),text-shadow .3s var(--ease);
  cursor:pointer;
}
.hero-title .hl:hover{
  background:transparent;
  color:var(--red);
  text-shadow:
    0 0 40px rgba(189,17,17,.35),
    0 0 18px rgba(189,17,17,.25),
    0 2px 10px rgba(0,0,0,.55);
}
/* ---------- 首屏「亮灯」标题入场（0.29.40）----------
   工艺点题：每个字按 DOM 顺序依次亮起，像楼体一层层亮灯，
   光晕在点亮瞬间最强、随后衰减，最后落在常亮状态。
   ⚠️ 只做「一次性入场」，不循环、不进 IntersectionObserver —— 首屏元素进入即播。
   ⚠️ 「惊喜地标」是 .hl 红底白字整块（有 box-decoration-break + hover 交互），
      故整体作为「一个单元」最后亮起，拆字会把红底切成四块且毁掉 hover。
   ⚠️ 光晕用 text-shadow / box-shadow（非 transform/opacity）：仅一次性、元素极小，
      代价是可接受的一次重绘；如后续嫌掉帧可改为 ::after 覆盖层。
   ⚠️ 键值动画不含 background/color/text-shadow（.hl 的 hover 属性），
      故 animation-fill-mode:forwards 不会锁死 .hl 的既有 hover 效果。 */
.hero-title--lit .ht-ch{
  display:inline-block;
  opacity:0;
  transform:translateY(.22em);
  animation:ht-light-up .52s var(--ease) forwards;
  animation-delay:calc(.24s + var(--i) * 55ms);
}
@keyframes ht-light-up{
  0%{opacity:0;transform:translateY(.22em);text-shadow:0 0 0 rgba(255,255,255,0)}
  38%{opacity:1;transform:translateY(0);text-shadow:0 0 22px rgba(255,255,255,.70)}
  100%{opacity:1;transform:translateY(0);text-shadow:0 0 0 rgba(255,255,255,0)}
}
/* 高亮块：白字配红色扩散光晕，呼应灯光打亮楼体 */
.hero-title--lit .hl.ht-ch{animation-name:ht-light-up-hl}
@keyframes ht-light-up-hl{
  0%{opacity:0;transform:translateY(.22em);box-shadow:0 0 0 rgba(189,17,17,0)}
  38%{opacity:1;transform:translateY(0);box-shadow:0 0 28px rgba(189,17,17,.55)}
  100%{opacity:1;transform:translateY(0);box-shadow:0 0 0 rgba(189,17,17,0)}
}
/* ⚠️ 窄屏必须把高亮块还原成 inline ——
   英文/法语的 .hl 是长词组（SURPRISE LANDMARK / REPÈRE QUI SURPREND），
   中文只有 4 字，但 CSS 无法按语言区分。inline-block 会禁止块内换行，
   窄屏下这个长词组必然横向溢出 → 改为 inline 可正常换行，
   动画相应降级为「纯淡入 + 光晕」（transform 对 inline 元素无效，故只用 opacity）。 */
@media (max-width:720px){
  .hero-title--lit .hl.ht-ch{
    display:inline;
    transform:none;
    animation-name:ht-light-up-hl-inline;
  }
}
@keyframes ht-light-up-hl-inline{
  0%{opacity:0;box-shadow:0 0 0 rgba(189,17,17,0)}
  38%{opacity:1;box-shadow:0 0 24px rgba(189,17,17,.5)}
  100%{opacity:1;box-shadow:0 0 0 rgba(189,17,17,0)}
}
@media (prefers-reduced-motion:reduce){
  .hero-title--lit .ht-ch{opacity:1;transform:none;animation:none}
}

.hero-sub{
  margin-top:26px;
  color:var(--fg-muted);
  max-width:720px;
}
.hero-sub-main{font-size:clamp(16px,1.9vw,21px);line-height:1.55}
.hero-sub-sub{
  margin-top:14px;
  font-size:clamp(13px,1.4vw,16px);
  color:var(--fg-dim);
  letter-spacing:.04em;
  line-height:1.7;
}

.hero-scroll{
  position:absolute;left:50%;bottom:32px;transform:translateX(-50%);
  z-index:3;
  display:flex;flex-direction:column;align-items:center;gap:10px;
  color:rgba(255,255,255,.65);
  font:500 10px var(--font-en);letter-spacing:.35em;text-transform:uppercase;
  animation:hero-scroll-pulse 2.4s ease-in-out infinite;
}
@keyframes hero-scroll-pulse{
  0%,100%{opacity:.55}
  50%{opacity:1}
}
.hero-scroll-mouse{
  width:22px;height:34px;
  color:rgba(255,255,255,.55);
  display:block;
}
.hero-scroll-dot{
  animation:hero-scroll-roll 1.8s ease-in-out infinite;
  transform-origin:center;
}
@keyframes hero-scroll-roll{
  0%{cy:9;opacity:1}
  60%{cy:20;opacity:.8}
  100%{cy:9;opacity:1}
}
.hero-scroll-line{
  width:1px;height:24px;
  background:rgba(255,255,255,.18);
  position:relative;overflow:hidden;
}
.hero-scroll-bar{
  position:absolute;left:0;top:0;width:100%;height:40%;
  background:linear-gradient(180deg,var(--red),rgba(200,60,60,.15));
  animation:hero-scroll-bar 1.8s ease-in-out infinite;
}
@keyframes hero-scroll-bar{
  0%{transform:translateY(-100%);opacity:0}
  15%{opacity:1}
  85%{opacity:1}
  100%{transform:translateY(250%);opacity:0}
}
.hero-scroll-label{
  color:rgba(255,255,255,.45);
  font:500 10px var(--font-en);letter-spacing:.35em;
}
@media (max-width:720px){
  .hero-scroll{bottom:20px;gap:8px}
  .hero-scroll-mouse{width:18px;height:28px}
  .hero-scroll-line{height:18px}
}
.trust{border-top:1px solid var(--line);border-bottom:1px solid var(--line);padding:clamp(36px,5vw,64px) 0}
.trust-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--line)}
.trust-item{background:var(--bg);padding:28px 26px;display:flex;flex-direction:column;gap:10px}
.trust-item .k{font-size:clamp(17px,2vw,22px);font-weight:700;line-height:1.4}
.trust-item .v{font-size:14px;color:var(--fg-muted);line-height:1.7}
.trust-item .v.small{font-size:12.5px;color:var(--fg-dim)}

/* ---------- 服务板块 ---------- */
.svc-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:1px;background:var(--line);border:1px solid var(--line)}
.svc-item{
  position:relative;overflow:hidden;
  background:var(--bg-elev);padding:30px 26px;display:flex;flex-direction:column;gap:14px;
  transition:background .3s;
}
.svc-item::before{
  content:"";position:absolute;inset:0;z-index:0;
  background-image:var(--bg);
  background-size:cover;background-position:center;
  opacity:0;
  transition:opacity .4s var(--ease);
}
.svc-item::after{
  content:"";position:absolute;inset:0;z-index:0;
  background:linear-gradient(135deg,rgba(10,10,12,.5) 0%,rgba(10,10,12,.85) 100%);
  opacity:0;
  transition:opacity .4s var(--ease);
}
.svc-item>*{position:relative;z-index:1}
@media (hover:hover){
  .svc-item:hover::before,.svc-item:hover::after{opacity:1}
}
.svc-num{font:700 40px var(--font-en);color:var(--red);line-height:1}
.svc-name{font-size:19px;font-weight:700}
.svc-desc{font-size:14px;color:var(--fg-muted);line-height:1.75}
.svc-ext{font-size:13px;color:var(--red-text);display:inline-flex;gap:6px;align-items:center;margin-top:auto}

/* ---------- 产品体系 ---------- */
.prod-block{margin-top:clamp(48px,7vw,88px)}
.prod-title{font-size:clamp(22px,2.6vw,30px);font-weight:700;margin-bottom:8px}
.prod-tagline{color:var(--red-text);font-size:15px;margin-bottom:28px;letter-spacing:.02em}
.mod-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:1px;background:var(--line);border:1px solid var(--line)}
.mod-item{background:var(--bg-elev);padding:28px 24px;display:flex;flex-direction:column;gap:12px}
.mod-no{font:700 14px var(--font-en);color:var(--red);letter-spacing:.1em}
.mod-name{font-size:18px;font-weight:700}
.mod-desc{font-size:13.5px;color:var(--fg-muted);line-height:1.8}

/* 表格（GEO 友好） */
.tbl-wrap{border:1px solid var(--line);overflow:hidden;border-radius:var(--radius-lg)}
table{width:100%;border-collapse:collapse;font-size:14.5px}
th,td{text-align:left;padding:16px 20px;border-bottom:1px solid var(--line)}
th{background:var(--bg-elev2);font-weight:600;color:var(--fg);font-size:13.5px;letter-spacing:.04em}
tbody tr:last-child td{border-bottom:none}
td{color:var(--fg-muted)}
td strong{color:var(--fg);font-weight:600}
td .red{color:var(--red-text);font-weight:600}
.tier-row td{font-weight:500}
.tbl-note{font-size:13px;color:var(--fg-dim);margin-top:14px}

/* 试算入口 */
.calc-cta{
  margin-top:22px;
  border:1px dashed var(--line-strong);
  border-radius:var(--radius-lg);
  padding:22px 26px;
  background:var(--bg-elev);
}
.calc-cta-head{
  display:flex;align-items:center;justify-content:space-between;gap:18px;flex-wrap:wrap;
}
.calc-cta .t{font-size:15px;color:var(--fg)}
.calc-cta .t small{display:block;color:var(--fg-dim);font-size:12.5px;margin-top:4px}
.calc-cta .t small strong{color:var(--red-text);font-weight:600}
.btn-primary{
  display:inline-flex;align-items:center;gap:8px;
  background:var(--red);color:#fff;
  padding:12px 28px;border-radius:999px;
  font-size:15px;font-weight:600;
  transition:transform .2s var(--ease),box-shadow .2s;
}
.btn-primary:hover{transform:translateY(-2px);box-shadow:0 8px 28px rgba(189,17,17,.35)}
/* 设计审计：按下反馈（清单要求 scale .98），并统一过渡时长 */
.btn-primary{transition:transform .25s var(--ease),box-shadow .25s}
.btn-primary:active{transform:translateY(0) scale(.98)}

/* ===== 无障碍：键盘焦点环（全站原先只有表单有，链接/按钮没有） ===== */
:focus-visible{
  outline:2px solid var(--red-text);
  outline-offset:2px;
  border-radius:2px;
}

/* 试算展开表单 */
.calc-form{
  margin-top:22px;
  padding-top:22px;
  border-top:1px solid var(--line);
  animation:slideDown .35s var(--ease);
}
@keyframes slideDown{
  from{opacity:0;transform:translateY(-8px)}
  to{opacity:1;transform:none}
}
.calc-form-grid{
  display:grid;
  grid-template-columns:repeat(2,1fr);
  gap:16px 20px;
}
.form-field{display:flex;flex-direction:column;gap:6px}
.form-field-full{grid-column:1/-1}
.form-field label{font-size:13px;color:var(--fg-muted);font-weight:500}
.form-field input,
.form-field select,
.form-field textarea{
  width:100%;
  background:var(--bg);
  border:1px solid var(--line);
  border-radius:var(--radius);
  padding:10px 14px;
  color:var(--fg);
  font-size:14px;
  font-family:inherit;
  transition:border-color .25s, box-shadow .25s;
  outline:none;
}
.form-field input:focus,
.form-field select:focus,
.form-field textarea:focus{
  border-color:var(--red);
  box-shadow:0 0 0 3px var(--red-soft);
}
.form-field textarea{resize:vertical;min-height:72px}
.calc-form-foot{
  margin-top:18px;
  display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap;
}
.calc-tip{font-size:12.5px;color:var(--fg-dim);max-width:520px}

/* 产品标签（ToB 等） */
.prod-tag{
  display:inline-block;
  font-size:11px;
  font-weight:600;
  letter-spacing:.06em;
  padding:2px 8px;
  border-radius:4px;
  background:var(--red-soft);
  color:var(--red-text);
  vertical-align:middle;
  margin-left:6px;
}

/* 行内链接按钮 */
.link-btn{
  font-size:12.5px;
  color:var(--red-text);
  padding:0;
  margin-left:8px;
  font-weight:500;
  vertical-align:middle;
  transition:opacity .2s;
}
.link-btn:hover{opacity:.75}

/* 建筑亮化行：整行可点击 */
/* 建筑亮化 · details 展开（参考 FAQ 模式） */
.bld-details{
  border:1px solid var(--line);
  border-radius:var(--radius-lg);
  background:var(--bg-elev);
  overflow:hidden;
  transition:border-color .3s;
}
.bld-details[open]{border-color:var(--line-strong)}
.bld-summary{
  list-style:none;
  cursor:pointer;
  padding:18px 22px;
  display:grid;
  grid-template-columns:1.5fr 2fr 1fr;
  gap:16px;
  align-items:center;
  font-size:14.5px;
  transition:background .25s var(--ease);
  position:relative;
}
.bld-summary::-webkit-details-marker{display:none}
.bld-summary::after{
  content:"+";
  position:absolute;
  right:22px;top:50%;
  transform:translateY(-50%);
  font-size:22px;
  font-weight:300;
  color:var(--red);
  transition:transform .3s var(--ease);
  line-height:1;
}
.bld-details[open] .bld-summary::after{transform:translateY(-50%) rotate(45deg)}
.bld-summary:hover{background:var(--bg-elev2)}
.bld-sum-left strong{font-size:15px}
.bld-sum-mid{color:var(--fg-muted)}
.bld-sum-right{
  display:flex;
  gap:16px;
  justify-content:flex-end;
  padding-right:28px;
}
.bld-sum-cycle{color:var(--fg-muted);font-size:13.5px}
.bld-sum-price{color:var(--red-text);font-weight:600;font-size:14px}
.bld-panel{
  padding:0 22px 20px;
  color:var(--fg-muted);
  font-size:14.5px;
  line-height:1.85;
}
.bld-list{margin:0;padding-left:20px}
.bld-list li{margin-bottom:6px}
.bld-list b{color:var(--fg);font-weight:600}

@media (max-width:860px){
  .bld-summary{
    grid-template-columns:1fr;
    gap:8px;
    padding-right:48px;
  }
  .bld-sum-right{justify-content:flex-start;padding-right:0}
}

/* 建筑亮化体系展开块 */
.quote-block{
  margin-top:34px;
  border-left:3px solid var(--red);
  background:var(--bg-elev);
  border-radius:0 var(--radius-lg) var(--radius-lg) 0;
  padding:26px 30px;
}
.quote-block .qk{font-size:19px;font-weight:700;margin-bottom:16px}
.quote-block ul{list-style:none;display:grid;gap:12px}
.quote-block li{font-size:14.5px;color:var(--fg-muted);display:flex;gap:12px}
.quote-block li b{color:var(--fg);font-weight:600;white-space:nowrap}

/* about-summary 底纹版 */
.section-about-summary .about-summary-grid{position:relative}
.about-summary-list{position:relative;z-index:1}

/* ---------- 案例中心 ---------- */
.case-group{margin-bottom:clamp(56px,8vw,96px)}
.case-group-title{
  display:flex;align-items:baseline;gap:16px;
  margin-bottom:28px;
}
.case-group-title .no{font:800 clamp(28px,4vw,44px) var(--font-en);color:var(--red);line-height:1}
.case-group-title h3{font-size:clamp(20px,2.4vw,28px);font-weight:700}
.case-card{
  position:relative;
  display:grid;
  grid-template-columns:minmax(0,1.6fr) minmax(0,1fr);
  border:1px solid var(--line);
  border-radius:var(--radius-lg);
  overflow:hidden;
  margin-bottom:24px;
  background:var(--bg-elev);
  transition:border-color .3s,transform .3s var(--ease);
}
.case-card:hover{border-color:var(--red);transform:translateY(-3px)}
.case-media{
  position:absolute;inset:0;
  aspect-ratio:auto;
  overflow:hidden;
  z-index:0;
}
.case-media .ph{position:absolute;inset:0}
.case-body{
  position:relative;z-index:2;overflow:hidden;
  margin-left:auto;
  grid-column:2;
  padding:clamp(22px,3vw,38px);
  display:flex;flex-direction:column;gap:14px;
  background:linear-gradient(90deg,rgba(10,10,12,.35) 0%,rgba(10,10,12,.6) 14%,rgba(10,10,12,.76) 35%,rgba(10,10,12,.82) 100%);
}
.case-body::before{
  content:"";position:absolute;inset:0;z-index:-1;
  background:linear-gradient(90deg,rgba(10,10,12,.5) 0%,rgba(10,10,12,.8) 14%,rgba(10,10,12,.92) 35%,rgba(10,10,12,.96) 100%);
  opacity:0;
  transition:opacity .35s var(--ease);
  pointer-events:none;
}
.case-card:hover .case-body::before{opacity:1}
.case-name{font-size:clamp(19px,2.2vw,25px);font-weight:700;line-height:1.35}
.case-brief{font-size:14.5px;color:var(--fg-muted);line-height:1.8}
.case-tags{display:flex;flex-wrap:wrap;gap:8px;margin-top:2px}
.case-tag{
  font:500 12px var(--font-cn);
  color:var(--fg-muted);
  border:1px solid var(--line-strong);
  border-radius:999px;
  padding:3px 12px;
}
.case-link{
  margin-top:auto;
  display:inline-flex;align-items:center;gap:8px;
  color:var(--red-text);font-weight:600;font-size:14.5px;
  width:fit-content;
}
.case-role{margin-top:4px;font-size:13.5px;color:var(--fg-dim);line-height:1.75}
.case-role-k{font:600 11px/1 var(--font-cn);color:#fff;background:var(--red);border-radius:4px;padding:4px 8px;letter-spacing:.04em;white-space:nowrap}
.case-role-v{color:var(--fg-muted);font-size:13.5px}
.case-ourwork{margin-top:2px;font-size:14px;color:var(--fg-muted);line-height:1.8}
.case-ourwork-k{color:var(--red-text);font-weight:600;margin-right:4px}
.case-year{margin-top:4px;font-size:12.5px;color:var(--fg-dim);line-height:1.6}
.case-card-mini .case-role{font-size:12.5px}
.case-card-mini .case-role-k{font-size:10px;padding:3px 6px}
.case-card-mini .case-ourwork{font-size:12.5px}
.case-card-mini .case-year{font-size:11.5px}
.calc-soon-badge{display:inline-flex;align-items:center;white-space:nowrap;font:600 13px var(--font-cn);color:#fff;background:var(--red);border-radius:999px;padding:6px 16px;align-self:center}

/* ---------- 数据区 ---------- */
.data-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--line);border:1px solid var(--line)}
.data-item{background:var(--bg-elev);padding:34px 28px;display:flex;flex-direction:column;gap:10px}
.data-num{font:800 clamp(38px,5vw,64px) var(--font-en);color:var(--red);line-height:1}
.data-num small{font-size:.55em;color:var(--fg-muted);font-weight:600;margin-left:4px}
.data-desc{font-size:14.5px;color:var(--fg);line-height:1.7}
.data-src{font-size:12px;color:var(--fg-dim)}
.data-foot{margin-top:30px;font-size:13.5px;color:var(--fg-muted);border-top:1px solid var(--line);padding-top:20px}

/* ---------- 团队 ---------- */
.team-card{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.2fr);
  gap:clamp(24px,4vw,56px);
  align-items:start;
  border:1px solid var(--line);
  border-radius:var(--radius-lg);
  overflow:hidden;
  background:var(--bg-elev);
}
.team-media{position:relative;aspect-ratio:3/4;min-height:0;border-radius:var(--radius-lg);overflow:hidden}
.team-media .ph{position:absolute;inset:0;background:var(--bg-elev)}
.team-media img{width:100%;height:100%;object-fit:cover;display:block}
.team-body{padding:clamp(26px,4vw,52px)}
.team-name{font-size:clamp(22px,2.6vw,32px);font-weight:800}
.team-role{color:var(--red-text);font-size:15px;margin-top:6px;letter-spacing:.04em}
.team-list{list-style:none;margin-top:24px;display:grid;gap:13px}
.team-list li{font-size:14.5px;color:var(--fg-muted);display:flex;gap:12px;line-height:1.8}
/* ---------- FAQ ---------- */
.faq-list{max-width:880px;margin:0 auto;display:grid;gap:14px}
.faq-item{border:1px solid var(--line);border-radius:var(--radius-lg);background:var(--bg-elev);overflow:hidden;transition:border-color .3s}
.faq-item[open]{border-color:var(--line-strong)}
.faq-q{
  list-style:none;
  padding:22px 26px;
  font-size:16.5px;font-weight:600;
  cursor:pointer;
  display:flex;align-items:center;justify-content:space-between;gap:16px;
  user-select:none;
}
.faq-q::-webkit-details-marker{display:none}
.faq-q::after{
  content:"+";
  font:400 26px var(--font-en);
  color:var(--red);
  flex:none;
  transition:transform .3s var(--ease);
}
.faq-item[open] .faq-q::after{transform:rotate(45deg)}
.faq-a{padding:0 26px 24px;color:var(--fg-muted);font-size:14.5px;line-height:1.85}

/* ---------- 证言/评价（横向滚动） ---------- */
.testimonial-section{padding:clamp(28px,3.5vw,44px) 0;background:var(--bg-elev2)}
.testimonial-lead{
  text-align:center;
  font-size:clamp(12px,1.4vw,14px);
  color:var(--muted,rgba(255,255,255,.55));
  margin:clamp(8px,1vw,14px) auto clamp(20px,2.5vw,32px);
  font-style:italic;
  max-width:52ch;
}
.testimonial-rows{display:flex;flex-direction:column;gap:clamp(12px,1.5vw,20px);padding:4px var(--gutter)}
.testimonial-row{
  display:flex;gap:clamp(12px,1.5vw,20px);
  overflow-x:scroll;
  padding:4px 0;
  scrollbar-width:none;-ms-overflow-style:none;
  -webkit-overflow-scrolling:touch;
  cursor:grab;
  user-select:none;-webkit-user-select:none;
  touch-action:pan-x;
}
.testimonial-row::-webkit-scrollbar{display:none}
.testimonial-row.dragging{cursor:grabbing}
.testimonial-card{
  flex:0 0 clamp(220px,18vw,300px);
  min-height:clamp(200px,22vw,280px);
  background:var(--bg-elev);
  border:1px solid var(--line);
  border-left:3px solid var(--red);
  border-radius:var(--radius);
  padding:clamp(20px,2.4vw,32px);
  display:flex;flex-direction:column;gap:14px;
}
.testimonial-quote{
  font-size:clamp(16px,1.3vw,18px);
  line-height:1.85;color:var(--fg);
  flex:1;
}
.testimonial-author{position:relative;display:flex;flex-direction:column;gap:2px;min-height:40px}
.testimonial-author .testimonial-name,
.testimonial-author .testimonial-role,
.testimonial-author .testimonial-source{transition:opacity .25s ease}
.testimonial-name{font-size:14px;font-weight:700;color:var(--fg)}
.testimonial-role{font-size:13px;color:var(--fg-dim)}
/* hover 翻转：姓名/身份 ↔ 出处 */
.testimonial-source{position:absolute;top:0;left:0;right:0;opacity:0;pointer-events:none;font-size:11px;color:var(--fg-dim);font-style:italic;line-height:1.5}
.testimonial-card:hover .testimonial-name, .testimonial-card:hover .testimonial-role{opacity:0}
.testimonial-card:hover .testimonial-source{opacity:1}

/* ---------- 联系 ---------- */
.contact{border-top:1px solid var(--line);overflow:visible}
.contact-grid{display:grid;grid-template-columns:1.2fr 1fr;gap:clamp(32px,5vw,80px);align-items:center}
.contact-title{font-size:clamp(26px,3.6vw,42px);font-weight:800;line-height:1.25}
.contact-title .hl{color:var(--red)}
.contact-desc{margin-top:18px;color:var(--fg-muted);font-size:15.5px;line-height:1.9}
.contact-card{
  border:1px solid var(--line);
  border-radius:var(--radius-lg);
  background:var(--bg-elev);
  padding:clamp(26px,3.6vw,44px);
  display:grid;
  grid-template-columns:1fr auto;
  gap:0;
}
.contact-card-info{display:grid;gap:22px}
.contact-card-logo{
  display:flex;align-items:center;justify-content:center;
  padding-left:clamp(24px,3vw,40px);
  border-left:1px solid var(--line);
}
.contact-card-logo img{height:clamp(80px,10vw,120px);width:auto;opacity:.85}
.contact-row{display:flex;gap:14px;align-items:flex-start}
.contact-row .ic{
  flex:none;width:40px;height:40px;
  display:flex;align-items:center;justify-content:center;
  border:1px solid var(--line-strong);border-radius:50%;
  color:var(--red);
}
.contact-row .l{font-size:12px;color:var(--fg-dim);letter-spacing:.08em;text-transform:uppercase}
.contact-row .v{font-size:16px;font-weight:600;word-break:break-all}
.contact-row .v a:hover{color:var(--red)}
.socials{display:flex;gap:14px;flex-wrap:wrap;border-top:1px solid var(--line);padding-top:20px;padding-bottom:24px;margin-top:4px}
.socials .l{flex-basis:100%;font-size:12px;color:var(--fg-dim);letter-spacing:.1em;text-transform:uppercase}
.social{
  position:relative;
  width:42px;height:42px;
  display:flex;align-items:center;justify-content:center;
  border:1px solid var(--line-strong);border-radius:50%;
  color:var(--fg-muted);
  transition:border-color .25s,color .25s,transform .2s var(--ease);
}
.social-label{
  position:absolute;
  top:calc(100% + 6px);
  left:50%;transform:translateX(-50%);
  font-size:11px;white-space:nowrap;
  color:var(--fg-dim);pointer-events:none;
}
.social:hover{border-color:var(--red);color:var(--red);transform:translateY(-2px)}
.qr-pop{
  display:none;
  position:absolute !important;
  bottom:calc(100% + 12px) !important;left:0 !important;
  width:220px !important;height:220px !important;
  min-width:220px !important;max-width:220px !important;
  border:1px solid var(--line-strong);border-radius:var(--radius);
  background:var(--bg-elev2);padding:8px;
  z-index:999 !important;
  box-shadow:0 12px 32px rgba(0,0,0,.6);
  pointer-events:none;
}
.qr-pop.show{display:block}
.qr-pop img{width:204px !important;height:204px !important;max-width:none !important;object-fit:contain;border-radius:2px;background:#fff}
.contact-row.has-qr{position:relative;cursor:pointer}
.social-qr-pop{
  display:none;
  position:absolute !important;
  bottom:calc(100% + 12px) !important;left:50% !important;transform:translateX(-50%) !important;
  width:220px !important;height:auto !important;
  min-width:220px !important;max-width:220px !important;
  border:1px solid var(--line-strong);border-radius:var(--radius);
  background:var(--bg-elev2);padding:8px;
  z-index:999 !important;
  box-shadow:0 12px 32px rgba(0,0,0,.6);
  pointer-events:none;
}
.social-qr-pop.show{display:block}
.social-qr-pop img{width:204px !important;height:204px !important;max-width:none !important;opacity:1 !important;object-fit:contain;border-radius:2px;background:#fff}
.social-qr-pop .qr-desc{
  text-align:center;font-size:12px;color:var(--fg);
  padding:8px 0 2px;
}
.socials{position:relative}
.socials .social.has-qr{position:relative}
/* 品牌图标（B站/小红书）hover 微亮 */
.social img{width:18px;height:18px;opacity:.72;transition:opacity .25s var(--ease)}
.social:hover img{opacity:1}

/* ---------- 浪漫卡路里 · 延伸项目板块 ---------- */
.rc-section{border-top:1px solid var(--line);padding-top:clamp(32px,4vw,56px)}
.rc-hero{
  display:grid;grid-template-columns:1fr 1fr;gap:clamp(24px,3vw,48px);
  align-items:center;margin-top:24px;
  padding:clamp(20px,2.4vw,32px);
  background:var(--bg-elev);border:1px solid var(--line);border-radius:var(--radius-lg);
}
.rc-media{aspect-ratio:4/3;border-radius:var(--radius);overflow:hidden;background:var(--bg)}
.rc-title{font-size:clamp(20px,2.4vw,28px);font-weight:800;line-height:1.3;margin-bottom:10px}
.rc-brief{font-size:clamp(14px,1.6vw,16px);color:var(--fg-muted);line-height:1.8;margin-bottom:16px}
.rc-meta{display:flex;flex-direction:column;gap:8px}
.rc-meta-row{display:flex;gap:10px;font-size:14px;line-height:1.6}
.rc-meta-k{flex:none;font:600 11px var(--font-cn);color:var(--red-text);background:var(--red-soft);border-radius:4px;padding:3px 8px;letter-spacing:.04em;white-space:nowrap;align-self:flex-start;margin-top:2px}
.rc-meta-v{color:var(--fg-muted)}
@media (max-width:860px){
  .rc-hero{grid-template-columns:1fr}
}

/* ---------- Footer ---------- */
.footer{border-top:1px solid var(--line);padding:32px 0 28px}
.footer-brand{display:block;margin-bottom:24px}
.footer-logo{height:80px;width:auto;opacity:.92}
.footer-bottom{
  display:grid;grid-template-columns:1fr 1fr 1fr;align-items:center;
  margin-top:28px;padding-top:20px;
  border-top:1px solid var(--line);
  font-size:12.5px;color:var(--fg-dim);
  /* 备案号与版权里的数字/符号（© 2026、2026049144、ICP）走英文字体，
     中文部分（鄂ICP备、武汉市此方…、网站地图…）自动回落中文字体栈 */
  font-family:var(--font-en);
}
.footer-bottom-c{text-align:center}
.footer-bottom-r{display:flex;gap:16px;justify-content:flex-end}
.footer-bottom a{color:var(--fg-dim);transition:color .25s}
.footer-bottom a:hover{color:var(--fg-muted)}
.watermark-footer{display:none}

/* ---------- 法律文档（隐私声明 / 法律条款）---------- */
.legal-doc{max-width:78ch}
.legal-doc .meta{
  font-size:13px;color:var(--fg-dim);letter-spacing:.02em;
  padding-bottom:18px;margin-bottom:26px;border-bottom:1px solid var(--line);
}
.legal-doc h2{
  font-size:clamp(17px,1.9vw,21px);font-weight:700;color:var(--fg);
  margin:clamp(30px,3.4vw,42px) 0 12px;letter-spacing:.01em;
}
.legal-doc h2:first-of-type{margin-top:0}
.legal-doc p{font-size:15.5px;line-height:1.85;color:var(--fg-muted);margin-bottom:12px}
.legal-doc ul{margin:0 0 14px;padding-left:1.25em}
.legal-doc li{font-size:15.5px;line-height:1.85;color:var(--fg-muted);margin-bottom:8px}
.legal-doc a{color:var(--red-text);text-decoration:none;border-bottom:1px solid rgba(212,69,69,.35)}
.legal-doc a:hover{color:var(--fg);border-bottom-color:var(--fg)}
.legal-doc strong{color:var(--fg);font-weight:600}

/* ---------- 404 页面 ----------
   简中 + 英并列：中文主行、英文副行（改用 --font-en）。
   大号 404 是装饰水印（HTML 里已 aria-hidden），不参与读屏，也不参与选词。 */
.nf-section{min-height:60vh}
.nf{max-width:620px}
.nf-code{
  font:300 clamp(64px,12vw,128px)/1 var(--font-en);
  font-variant-numeric:tabular-nums;
  letter-spacing:.02em;
  color:var(--red);opacity:.22;
  margin-bottom:clamp(4px,1vw,12px);
  user-select:none;pointer-events:none;
}
.nf-title{font-size:clamp(25px,3.2vw,38px);font-weight:700;line-height:1.3;letter-spacing:.01em}
.nf-title .nf-en{
  display:block;margin-top:8px;
  font:500 clamp(14px,1.6vw,18px)/1.5 var(--font-en);
  color:var(--fg-muted);letter-spacing:.04em;
}
.nf-desc{
  margin-top:clamp(16px,2.2vw,24px);
  color:var(--fg-muted);
  font-size:clamp(14.5px,1.6vw,16.5px);line-height:1.8;
  max-width:54ch;
}
.nf-desc .nf-en{
  display:block;margin-top:10px;
  font-family:var(--font-en);color:var(--fg-dim);font-size:15px;
}
.nf-actions{
  margin-top:clamp(26px,3.4vw,40px);
  display:flex;flex-wrap:wrap;align-items:center;gap:14px;
}
.nf-btn-ghost{
  display:inline-flex;align-items:center;gap:8px;
  padding:12px 26px;border-radius:999px;
  border:1px solid var(--line-strong);color:var(--fg);
  font-size:15px;font-weight:600;
  transition:border-color .25s var(--ease),background .25s var(--ease),transform .25s var(--ease);
}
.nf-btn-ghost:hover{border-color:var(--fg);background:rgba(255,255,255,.04)}
.nf-btn-ghost:active{transform:scale(.98)}
.nf-sep{opacity:.38;margin:0 6px}
.nf-en-inline{font-family:var(--font-en)}

/* ---------- 案例详情页 ---------- */
.case-hero{position:relative;min-height:78vh;display:flex;align-items:flex-end;overflow:hidden}
.case-hero .ph{position:absolute;inset:0}
.case-hero .ph::after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,rgba(10,10,12,.5),rgba(10,10,12,.88) 78%)}
.case-hero-inner{position:relative;z-index:3;max-width:var(--container);margin:0 auto;padding:0 var(--gutter);width:100%;padding-bottom:clamp(40px,6vw,80px)}
.case-hero-en{font:500 clamp(11px,1.3vw,14px) var(--font-en);letter-spacing:.4em;text-transform:uppercase;color:var(--fg-muted);margin-bottom:16px}
.case-hero-title{font-size:clamp(30px,5vw,62px);font-weight:800;line-height:1.15;max-width:14em}
.case-hero-sub{margin-top:16px;color:var(--fg-muted);font-size:clamp(15px,1.8vw,19px)}
.case-hero .tags{display:flex;flex-wrap:wrap;gap:8px;margin-top:24px}
/* ---------- 案例详情页横向图片条 ---------- */
.photo-row{
  position:relative;left:50%;right:50%;
  width:100vw;margin-left:-50vw;margin-right:-50vw;
  padding:0;margin-top:clamp(28px,4vw,40px);
  overflow-x:auto;overflow-y:hidden;
  scrollbar-width:none;-ms-overflow-style:none;
  -webkit-overflow-scrolling:touch;
  cursor:grab;user-select:none;-webkit-user-select:none;
  touch-action:pan-x;
  background:rgba(0,0,0,.35);
}
.photo-row::-webkit-scrollbar{display:none}
.photo-row.dragging{cursor:grabbing}
.photo-track{display:flex;width:max-content}
.photo-card{
  flex:0 0 auto;margin:0;
  width:clamp(240px,26vw,340px);
  position:relative;overflow:hidden;
}

.photo-card a{display:block;cursor:zoom-in}
.photo-card img{
  width:100%;display:block;aspect-ratio:9/16;object-fit:cover;
  transition:transform .4s var(--ease);
}
.photo-card:hover img{transform:scale(1.04)}
.photo-card figcaption{
  position:absolute;left:0;right:0;bottom:0;z-index:2;
  padding:clamp(14px,1.8vw,22px);
  font:600 clamp(13px,1.4vw,16px)/1.35 var(--font-cn);
  color:#fff;letter-spacing:.02em;
}
.photo-card figcaption .pc-sub{
  display:block;margin-top:4px;
  font:400 clamp(11.5px,1.1vw,13px)/1.5 var(--font-cn);
  color:rgba(255,255,255,.7);font-weight:400;
}
/* figcaption 里 <br> 后面的 span 自动套用副文字样式（灰色小字号） */
.photo-card figcaption br ~ span{
  display:block;margin-top:4px;
  font:400 clamp(11.5px,1.1vw,13px)/1.5 var(--font-cn);
  color:rgba(255,255,255,.65);
  font-weight:400;
  letter-spacing:.01em;
}
.photo-card::after{
  content:"";position:absolute;inset:auto 0 0 0;height:55%;
  background:linear-gradient(180deg,transparent 0%,rgba(0,0,0,.7) 50%,rgba(0,0,0,.92) 100%);
  pointer-events:none;z-index:1;
}

/* ---------- 完整展示图（hero 全幅，暗化） ---------- */
.case-full-photo{
  position:relative;width:100%;
  margin:clamp(32px,5vw,56px) 0;
  overflow:hidden;border-radius:var(--radius-lg);
}
.case-full-photo img{
  width:100%;height:auto;display:block;
  filter:brightness(.45) saturate(.85);
  transition:filter .5s var(--ease);
}
.case-full-photo:hover img{filter:brightness(.6) saturate(.9)}
.case-full-photo-caption{
  position:absolute;bottom:20px;left:50%;transform:translateX(-50%);
  color:rgba(255,255,255,.6);font-size:12.5px;letter-spacing:.12em;
  text-transform:uppercase;font-weight:500;
}

/* ---------- Hero 图延伸为后续 section 背景 ---------- */
.case-bg-section{
  background-image:url('../assets/img/case-licheng-rebake-factory.jpg');
  background-size:cover;background-position:center top;background-attachment:fixed;
  position:relative;
}
.case-bg-section::before{
  content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(10,10,12,.6) 0%,rgba(10,10,12,.85) 40%,rgba(10,10,12,.95) 100%);
  pointer-events:none;z-index:0;
}
.case-bg-section>.container{position:relative;z-index:1}
@media (max-width:768px){
  .case-bg-section{background-attachment:scroll}
}
.prose{max-width:880px}
.prose h2{
  font-size:clamp(22px,2.8vw,32px);font-weight:700;
  margin:clamp(48px,7vw,72px) 0 20px;
  display:flex;align-items:center;gap:16px;
}
.prose h2 .no{font:800 clamp(20px,2.6vw,30px) var(--font-en);color:var(--red);letter-spacing:.06em}
.prose h3{font-size:19px;font-weight:700;margin:30px 0 12px}
.prose p{color:var(--fg-muted);font-size:15.5px;line-height:2;margin-bottom:18px}
.prose p b{color:var(--fg);font-weight:600}
.prose ul,.prose ol{margin:0 0 18px;padding-left:0;list-style:none;display:grid;gap:12px}
.prose li{color:var(--fg-muted);font-size:15px;line-height:1.9;display:flex;gap:12px}
/* ⚠️ 这里原本是 .prose .callout 的 6 条声明，但**选择器在历史改动中丢失**，
   于是它们成为孤立声明、被浏览器整块丢弃 —— 案例页的 9 个 .callout
   （cases/xuanen-night-tour.html:77,398、cases/lichuan-thermometer.html:109
     及 en/ 与 zh-TW/ 的对应页）因此没有底色 / 内边距 / 圆角，以普通正文形态呈现。
   2026-09-18：按「零版式改动」原则**暂不恢复**，只把原文注释保留在此备查 ——
   恢复后这 9 处会变成带底色的高亮框（属可见的版式变化），需经鸣拍板。
   若要恢复：把下面 6 条声明的注释符去掉，并在其上方补一行选择器即可。 */
/*
  background:var(--bg-elev);
  border-radius:0 var(--radius-lg) var(--radius-lg) 0;
  padding:24px 28px;
  margin:28px 0;
  color:var(--fg-muted);font-size:15px;line-height:2;
*/
.prose .callout b{color:var(--fg)}
.prose blockquote{
  border-left:3px solid var(--red);
  padding:6px 0 6px 24px;
  margin:28px 0;
  color:var(--fg);font-size:17px;line-height:2;font-weight:500;
}
.data-strip{
  display:grid;grid-template-columns:repeat(4,1fr);gap:1px;
  background:var(--line);border:1px solid var(--line);
  margin:30px 0;
}
.data-strip .item{background:var(--bg-elev);padding:24px 20px}
.data-strip .n{font:800 clamp(26px,3.4vw,42px) var(--font-en);color:var(--red);line-height:1}
.data-strip .d{font-size:12.5px;color:var(--fg-muted);margin-top:8px;line-height:1.6}
.next-case{
  margin-top:clamp(56px,8vw,100px);
  border:1px solid var(--line);border-radius:var(--radius-lg);
  overflow:hidden;display:block;
  transition:border-color .3s;
  position:relative;
}
.next-case:hover{border-color:var(--red)}
.next-case .ph{min-height:300px}
.next-case-label{position:absolute;top:24px;left:26px;z-index:3;font:500 13px var(--font-en);letter-spacing:.3em;text-transform:uppercase;color:var(--fg-muted)}
.next-case-title{position:absolute;left:26px;bottom:26px;z-index:3;font-size:clamp(20px,2.6vw,30px);font-weight:700;max-width:16em}

/* ---------- 滚动进入动画 ---------- */
/* ⚠️ 参数按 Apple 那类「滚动入场」的量级调过（经鸣 2026-09-18）：
     位移 26 → 40px（更"升腾"）· 时长 .7 → .8s（更从容）
   ⚠️ 错峰【不在 CSS 里做】—— 见 main.js：那里按父容器自动分组，
      给元素写 inline 的 animation-delay。
      （若放到 CSS 里用 nth-child，得为全站几十种容器各写一套，太脆）
   ⚠️⚠️ 入场用 animation 而不是 transition（2026-09-18 修掉的一个既有 bug）：
      transition 是【整体属性】—— 元素自身那条 hover 用的 transition
      （如 .lab-card{transition:border-color .35s}、.prod-item{transition:…,.3s}）
      会把这里声明的 opacity/transform 过渡【整个覆盖掉】，
      导致全站 20 多个元素（lab-card / prod-item / cred-item / partner-item /
      dyn-tile / story-card / story-case / cred-gallery-item …）的入场
      实际是"直接蹦出来"，既不淡入也不上移。
      animation 与 transition 互不干扰 → 入场走 animation、hover 走 transition，
      两边都正常。animation-delay 做错峰也不会波及 hover。 */
/* ⚠️ 参数第二次调整（经鸣 2026-09-18：「apple 的渐显更慢，更不同步」）：
     时长 .8 → 1.05s（更慢）· 位移 40 → 48px（配合更长时间，行程更足）
     曲线 var(--ease) → cubic-bezier(.16,1,.3,1)（快进慢出，Apple 那类最常用的收尾感）
     ⚠️ 曲线【只给 reveal 用】，不动 --ease —— 那是全站过渡共用的变量
        （导航红条、卡片 hover 等都依赖它，改了会波及全站手感） */
.reveal{opacity:0;transform:translateY(48px)}
@keyframes revealIn{
  from{opacity:0;transform:translateY(48px)}
  to  {opacity:1;transform:none}
}
/* `both`：延迟期间先套用 from（否则会先闪一下），结束后保持 to */
.reveal.in{opacity:1;transform:none;animation:revealIn 1.05s cubic-bezier(.16,1,.3,1) both}
/* Hero 首屏元素立即可见，不走 IntersectionObserver。
   ⚠️⚠️ 必须连 animation 一起关掉 —— 只写 opacity:1 !important 是挡不住的：
      animation 的 from/to 优先级高于普通声明，会把首屏元素又拉回"透明+下沉"，
      表现为「首屏加载完才往上飘一下」。 */
.case-hero .reveal,
.section-hero .reveal,
.section-hero-sm .reveal,
.hero .reveal{
  opacity:1 !important;
  transform:none !important;
  animation:none !important;
}
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  /* ⚠️ 入场已由 transition 换成 animation（2026-09-18），这里要跟着改，
        否则"减少动态效果"关不掉入场动画 */
  .reveal{opacity:1;transform:none;animation:none}
  .case-card,.social,.btn-primary{transition:none}
}
/* ⚠️ JS 不可用时的兜底【不在这里做】：
   .reveal 的初态是 opacity:0，全靠 JS 加 .in 才显示，一旦 JS 被禁用，
   全站 900+ 个元素会永久不可见。
   兜底放在各页 <head> 的 <noscript><style>…</style></noscript> 里
   （HTML 规范允许 head 内 noscript 只含 link/style/meta）。
   ⚠️ 为什么不用 @media (scripting:none)：它是 CSS Media Queries L5 的新特性，
      只有 Chrome/Edge 120+、Safari 17+ 才认 —— 老浏览器会整条忽略，
      而国内访问者里老浏览器占比不低。<noscript> 则所有浏览器都支持。 */

/* ---------- 响应式 ---------- */
@media (max-width:1080px){
  .trust-grid{grid-template-columns:repeat(2,1fr)}
  .data-grid{grid-template-columns:repeat(2,1fr)}
  .data-strip{grid-template-columns:repeat(2,1fr)}
}
@media (max-width:860px){
  .nav-links{
    position:fixed;inset:72px 0 auto 0;
    flex-direction:column;align-items:flex-start;gap:6px;
    background:rgba(10,10,12,.97);
    padding:20px var(--gutter) 28px;
    border-bottom:1px solid var(--line);
    transform:translateY(-8px);
    opacity:0;pointer-events:none;
    transition:.3s var(--ease);
    z-index:99;
    /* 高度上限 + 可滚动：菜单里加入语言列表后内容会超过一屏，
       不设上限会顶出屏幕外，底部的语言项永远点不到。
       ⚠️ 用 dvh（动态视口高度）兜底而非只用 100vh：
          移动端地址栏收起/展开时 100vh 会算错，菜单底部被裁掉。 */
    max-height:calc(100vh - 72px);
    max-height:calc(100dvh - 72px);
    overflow-y:auto;
    -webkit-overflow-scrolling:touch;
  }
  .nav-links.open{transform:none;opacity:1;pointer-events:auto}
  .nav-links a{font-size:17px;padding:10px 0;width:100%}
  .nav-group{display:contents}
  .nav-toggle{display:flex}
  .nav-search{display:none}
  /* ---------- 语言切换（移动端）----------
     ⚠️ 原先此处是 `.lang-wrap{display:none}` —— 直接隐藏，且全站**没有任何替代入口**
     （页脚只有网站地图 / 隐私条款 / 法律声明），导致 **860px 以下（手机 + 平板）
     38 个页面全都无法切换语言**。桌面端不受影响，所以长期未被发现。
     现按经鸣要求：放在**导航条上、汉堡按钮左侧**。
     为此语言块已从 .nav-links 内**移到 </nav> 之外**（见 nav.js 的同名注释），
     所以这里只需把它排在导航条上即可。
     ⚠️ .nav-inner 是 justify-content:space-between，若不干预，三个可见子元素
        （brand / lang-wrap / nav-toggle）会被平均分散到整条导航条上，
        语言按钮会飘到中间 → 用 .brand 的 auto margin 吃掉剩余空间，让语言与汉堡一起贴右。
        （只给 .brand 加，不要给 .lang-wrap 也加 auto：两个 auto margin 会平分空间，反而贴不了右。）
     ⚠️ 下拉菜单**保持桌面那套绝对定位浮层**，不要改成静态展开：
        导航条上空间不够，静态展开会把导航条撑高。 */
  .brand{margin-right:auto}
  .lang-wrap{display:block;margin-left:0;margin-right:10px}
  .lang-btn{padding:6px 2px}
  .lang-menu{min-width:160px}
  .case-card,.team-card,.contact-grid{grid-template-columns:1fr}
  .case-media{position:relative;aspect-ratio:16/10}

.case-media img{
  width:100%;
  height:100%;
  object-fit:cover;
  display:block;
}
  .case-body{
    position:relative;z-index:auto;
    margin-left:0;
    grid-column:auto;
    background:var(--bg-elev);
  }
  .trust-grid{grid-template-columns:1fr}
  .calc-form-grid{grid-template-columns:1fr}
}
@media (max-width:560px){
  .data-grid{grid-template-columns:1fr}
  .data-strip{grid-template-columns:1fr}
}

/* ============================================================
   v2.0 重构新增：产品线 / 设计理念 / 工作流 / 关于摘要 / 网站地图
   ============================================================ */

/* ---------- 区块副标题 ---------- */
.section-sub{
  margin-top:14px;
  font-size:clamp(15px,1.6vw,17px);
  color:var(--fg-muted);
  max-width:56ch;
}

/* ---------- 导航：搜索占位 ----------
   ⚠️ 按钮当前【已移除】（0.29.85，经鸣要求先藏掉放大镜入口）：
      · nav.js 模板里的 <button class="nav-search"> 已删除（覆盖 43 个注入页）
       · index.html / zh-TW/index.html 两个硬编码页里的那个也已删除
      本节样式【刻意保留】，以后做搜索时把按钮加回来即可（无元素时自然不生效）。
   ⚠️⚠️ 恢复按钮前必须理顺下面两处 display 声明 —— 它们现在是矛盾的：
      ① @media (max-width:860px) 里  .nav-search{display:none}          （先声明）
      ② @media (max-width:560px) 里  .nav-search{display:inline-flex}   （本处，后声明）
      特异性相同 → ② 靠后取胜 → 【≤560px 时按钮其实是显示的】，与 ① 的意图相反。
      本次因按钮已无元素，故不影响渲染，未动。 */
.nav-search{
  display:inline-flex;align-items:center;justify-content:center;
  width:34px;height:34px;border-radius:50%;
  color:var(--fg-muted);
  border:1px solid transparent;
  transition:color .25s,border-color .25s;
}
.nav-search:hover{color:var(--fg);border-color:var(--line-strong)}
.nav-search[aria-disabled="true"]{cursor:default;opacity:.7}
.nav-search[aria-disabled="true"]:hover{color:var(--fg-muted);border-color:transparent}

/* ---------- 产品展开卡（与 prod-item 同尺寸） ---------- */
.prod-hero{
  background:var(--bg-elev);
  border:1px solid var(--line);
  border-radius:var(--radius-lg);
  padding:clamp(18px,2vw,24px);
  overflow:hidden;
  transition:border-color .3s var(--ease),transform .3s var(--ease),box-shadow .3s var(--ease);
}
.prod-hero:hover{
  border-color:var(--red);
  transform:translateY(-4px);
  box-shadow:0 12px 40px rgba(0,0,0,.35),0 0 0 1px rgba(189,17,17,.25);
}
.prod-hero[open]{border-color:rgba(189,17,17,.4);grid-column:span 2}
.prod-hero[open]:hover{transform:none;box-shadow:0 0 0 1px rgba(189,17,17,.25)}
.prod-hero summary{
  list-style:none;cursor:pointer;
  padding:0;
  display:block;
}
.prod-hero summary::-webkit-details-marker{display:none}
.prod-hero summary::after{
  content:"";
  display:block;
  margin-top:8px;
  height:1px;background:var(--line);
  opacity:0;transition:opacity .3s;
}
.prod-hero[open] summary::after{opacity:1}
.prod-hero summary .prod-name{margin-bottom:10px}
.prod-hero summary .prod-desc{margin-bottom:14px}
.prod-hero summary .prod-links{margin-top:6px}
.prod-hero-body{padding:clamp(18px,2vw,24px) 0 0}
.prod-section{margin-bottom:clamp(28px,4vw,40px)}
.prod-section:last-child{margin-bottom:0}
.prod-h4{
  font-size:clamp(15px,1.6vw,18px);font-weight:700;
  margin-bottom:16px;color:var(--fg);
}
.prod-value-grid{
  display:grid;grid-template-columns:repeat(4,1fr);
  gap:1px;background:var(--line);border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;
}
.prod-value-item{background:var(--bg-elev2);padding:18px 14px;display:flex;flex-direction:column;gap:4px}
.prod-value-item strong{font-size:14px;color:var(--red-text)}
.prod-value-item span{font-size:12.5px;color:var(--fg-muted)}
.prod-form-grid{
  display:grid;grid-template-columns:repeat(4,1fr);
  gap:1px;background:var(--line);border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;
}
.prod-form-item{background:var(--bg-elev2);padding:18px 14px;display:flex;flex-direction:column;gap:4px}
.prod-form-no{font:700 13px var(--font-en);color:var(--red);letter-spacing:.08em}
.prod-form-item strong{font-size:14px}
.prod-form-item span{font-size:12.5px;color:var(--fg-muted)}
.prod-delivery-grid{
  display:grid;grid-template-columns:repeat(2,1fr);
  gap:1px;background:var(--line);border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;
}
.prod-delivery-item{background:var(--bg-elev2);padding:20px 18px;display:flex;gap:12px;align-items:flex-start}
.prod-d-no{font:700 20px var(--font-en);color:var(--red);flex-shrink:0;line-height:1}
.prod-delivery-item strong{display:block;font-size:14px;margin-bottom:3px}
.prod-delivery-item span{font-size:12.5px;color:var(--fg-muted);line-height:1.7}
.prod-revenue-grid{
  display:grid;grid-template-columns:repeat(4,1fr);
  gap:1px;background:var(--line);border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;
}
.prod-rev-item{background:var(--bg-elev2);padding:18px 14px;display:flex;flex-direction:column;gap:4px}
.prod-rev-item strong{font-size:14px;color:var(--red-text)}
.prod-rev-item span{font-size:12.5px;color:var(--fg-muted)}
.prod-timeline{
  display:grid;grid-template-columns:repeat(4,1fr);
  gap:1px;background:var(--line);border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;
}
.prod-tl-item{background:var(--bg-elev2);padding:20px 18px;display:flex;flex-direction:column;gap:6px}
.prod-tl-no{font:800 28px var(--font-en);color:var(--red);line-height:1}
.prod-tl-item strong{font-size:14px}
.prod-tl-item span{font-size:12.5px;color:var(--fg-muted)}
.prod-download{margin-top:clamp(20px,3vw,32px);text-align:center}

/* ---------- 产品线 ---------- */
/* S2 产品线：标题区与第一排卡片、两排卡片、卡片与试算区之间的垂直间距统一 */
#products .section-head{margin-top:calc(-1*clamp(40px,5vw,100px));margin-bottom:clamp(8px,1vw,16px)}
#products .calc-cta{margin-top:0}
.prod-grid{
  display:grid;grid-template-columns:1fr;
  gap:clamp(16px,2vw,24px);
  margin-bottom:clamp(16px,2vw,24px);
}
.prod-grid-sub{grid-template-columns:1fr}
/* calc-cta 在 prod-grid 里跨整行 */
.prod-grid .calc-cta{grid-column:1 / -1}
.prod-item{
  position:relative;
  background:var(--bg-elev);
  border:1px solid var(--line);
  border-radius:var(--radius-lg);
  padding:clamp(22px,2.4vw,32px);
  transition:border-color .3s var(--ease),transform .3s var(--ease),box-shadow .3s var(--ease);
  overflow:hidden;
}
.prod-item:hover{
  border-color:var(--red);
  transform:translateY(-4px);
  box-shadow:0 12px 40px rgba(0,0,0,.35),0 0 0 1px rgba(189,17,17,.25);
}
.prod-item::before{
  content:"";position:absolute;inset:0;
  background:var(--red-soft);
  opacity:0;transition:opacity .3s var(--ease);
  pointer-events:none;
}
.prod-item:hover::before{opacity:1}
.prod-item>*{position:relative;z-index:1}
.prod-no{
  font:700 20px var(--font-en);
  color:var(--red);
  display:block;margin-bottom:14px;
  letter-spacing:.06em;
}
.prod-name{font-size:clamp(17px,1.8vw,21px);font-weight:700;margin-bottom:10px;line-height:1.35}
.prod-desc{font-size:14.5px;color:var(--fg-muted);line-height:1.7;margin-bottom:16px}
.prod-links{display:flex;flex-wrap:wrap;gap:8px 14px;margin-top:auto}
.prod-link{
  font-size:13.5px;color:var(--red-text);
  border-bottom:1px solid transparent;
  transition:border-color .25s;
}
.prod-link:hover{border-color:var(--red-text)}
.prod-link-muted{color:var(--fg-dim);border-bottom:none;cursor:default}
.prod-link-muted:hover{border-bottom:none}

/* ---------- 设计理念 ---------- */
.section-philosophy{background:var(--bg-elev)}
.philosophy-grid{
  display:grid;grid-template-columns:repeat(2,1fr);
  gap:clamp(20px,3vw,40px);
}
.philosophy-item{
  position:relative;overflow:hidden;
  text-align:center;
  padding:clamp(28px,4vw,48px) clamp(16px,2.4vw,32px);
  border:1px solid var(--line);
  border-radius:var(--radius-lg);
  background:var(--bg);
  transition:border-color .3s var(--ease);
}
/* ===== 设计理念入场动画（与工作流同模式） ===== */
.philosophy-grid[data-philosophy-animate]:not(.flow-playing) .philosophy-item{
  opacity:0;transform:translateY(24px);
}
.philosophy-grid.flow-playing .philosophy-item{
  opacity:1;transform:none;
  transition:opacity .5s var(--ease),transform .5s var(--ease);
}
.philosophy-grid.flow-playing .philosophy-item:nth-child(1){transition-delay:0s}
.philosophy-grid.flow-playing .philosophy-item:nth-child(2){transition-delay:.13s}
.philosophy-grid.flow-playing .philosophy-item:nth-child(3){transition-delay:.26s}
.philosophy-grid.flow-playing .philosophy-item:nth-child(4){transition-delay:.39s}
@media (prefers-reduced-motion:reduce){
  .philosophy-grid[data-philosophy-animate]:not(.flow-playing) .philosophy-item{opacity:1;transform:none}
  .philosophy-grid.flow-playing .philosophy-item{transition:none}
}
.philosophy-item:hover{border-color:var(--red)}
/* 序号底纹：框内大号罗马数字，粗体、低透明度水印 */
.philosophy-no{
  position:absolute;top:-.1em;left:.08em;
  font:800 clamp(56px,7vw,96px)/1 var(--font-cn);
  color:rgba(255,255,255,.07);
  letter-spacing:0;
  pointer-events:none;user-select:none;
  z-index:0;
}
.philosophy-item .philosophy-k,.philosophy-item .philosophy-v{position:relative;z-index:1}
.philosophy-k{
  display:block;
  font:700 clamp(20px,2.4vw,28px) var(--font-cn);
  color:var(--red);
  margin-bottom:12px;
  letter-spacing:.08em;
}
.philosophy-v{font-size:15px;color:var(--fg-muted);line-height:1.7}
.intro-body p{
  max-width:72ch;font-size:15.5px;line-height:1.9;color:var(--fg);
  margin-bottom:1.15em;text-align:justify;
}
.intro-section .section-head{max-width:72ch;margin-bottom:clamp(28px,4vw,48px)}
.intro-section .section-title{font-size:clamp(26px,3.4vw,42px)}

/* ---------- 资质荣誉图片展示 ---------- */
.cred-gallery{
  display:grid;grid-template-columns:repeat(4,1fr);gap:clamp(12px,1.6vw,20px);
  margin-top:clamp(32px,4vw,48px);
}
.cred-gallery-item{
  border:1px solid var(--line);border-radius:var(--radius-lg);overflow:hidden;
  background:#0e0e10;margin:0;cursor:zoom-in;
  transition:border-color .25s var(--ease);
}
.cred-gallery-item:hover{border-color:var(--red)}
.cred-gallery-item a{display:block;aspect-ratio:4/3;background:#fff;overflow:hidden;position:relative;border-radius:6px}
.cred-gallery-item img{
  width:100%;height:100%;display:block;
  object-fit:contain;background:#fff;
  filter:brightness(.72) contrast(.92);
  transition:filter .35s,transform .35s;
}
.cred-gallery-item:hover img{filter:brightness(1) contrast(1);transform:scale(1.02)}
.cred-gallery-item figcaption{
  padding:10px 14px;font-size:12.5px;color:var(--fg-dim);line-height:1.5;
  text-align:center;border-top:1px solid var(--line);
}

/* ---------- 图片放大 Lightbox ---------- */
.lb-overlay{
  position:fixed;inset:0;z-index:9999;
  background:rgba(0,0,0,.88);
  display:none;align-items:center;justify-content:center;
  padding:40px;cursor:zoom-out;
}
.lb-overlay.active{display:flex}
.lb-img{
  max-width:90vw;max-height:80vh;object-fit:contain;
  border-radius:var(--radius);box-shadow:0 20px 60px rgba(0,0,0,.5);
}
.lb-close{
  position:absolute;top:20px;right:28px;font-size:28px;color:#fff;
  width:44px;height:44px;border-radius:50%;background:rgba(255,255,255,.12);
  display:flex;align-items:center;justify-content:center;
  transition:background .2s;cursor:pointer;
}
.lb-close:hover{background:rgba(255,255,255,.25)}
.lb-caption{
  position:absolute;bottom:24px;left:50%;transform:translateX(-50%);
  color:#aaa;font-size:13px;text-align:center;max-width:80vw;
}

/* ---------- 工作流 14 环节 ---------- */
.flow-wrap{
  display:grid;grid-template-columns:repeat(4,1fr);
  gap:clamp(14px,1.6vw,20px);
}
.flow-stage{
  position:relative;overflow:hidden;
  background:var(--bg-elev);
  border:1px solid var(--line);
  border-radius:var(--radius-lg);
  padding:clamp(20px,2.4vw,28px);
}
.flow-stage-num{
  position:absolute;
  top:clamp(4px,1vw,8px);right:clamp(8px,1.5vw,14px);
  font:700 clamp(48px,6vw,80px)/1 var(--font-cn);
  color:rgba(255,255,255,.045);
  pointer-events:none;user-select:none;z-index:0;
}
.flow-stage>*:not(.flow-stage-num){position:relative;z-index:1}
.flow-stage-name{
  display:inline-block;
  /* ⚠️ 2026-09-18 经鸣：「前期工作 这四个红色标题也改大一些」
     （指的就是这四颗红边胶囊：前期工作 / 概念设计 / 深化设计 / 落地交付） */
  font:700 clamp(14px,1.05vw,15.5px) var(--font-cn);
  letter-spacing:.2em;
  color:var(--red);
  border:1px solid var(--red);
  border-radius:999px;
  padding:clamp(4px,.4vw,6px) clamp(16px,1.35vw,21px);
  margin-bottom:18px;
}
.flow-steps{display:flex;flex-direction:column;gap:10px}
.flow-step{
  position:relative;
  /* ⚠️ 2026-09-18 经鸣：「四个药丸再大一些，**不改变外框**」
     → 只放大药丸本身（字号 + 内边距），绝不动 .flow-stage 的边框 / 背景 / 圆角。
     ⚠️ 用 clamp 而非固定值：4 列在窄屏会被压窄，固定大字号会挤到折行。 */
  font-size:clamp(14px,1.05vw,15.5px);color:var(--fg);
  padding:clamp(11px,.85vw,14px) clamp(14px,1.1vw,17px);
  background:var(--bg);
  border:1px solid var(--line);
  border-radius:var(--radius);
  transition:border-color .25s;
}
.flow-step:hover{border-color:var(--red-text)}
.flow-step::before{
  content:"";position:absolute;left:14px;top:-10px;
  width:1px;height:10px;background:var(--line-strong);
}
.flow-stage .flow-steps .flow-step:first-child::before{display:none}
.flow-note{
  margin-top:clamp(24px,3vw,36px);
  font-size:14.5px;color:var(--fg-muted);
  text-align:center;
}

/* ============================================================
   工作流「光点下流」（0.30.7 · 经鸣定案）
   ------------------------------------------------------------
   一句话：竖线上的流动光点 + 到达时药丸亮灯 + 整列边框微光 + 交叉淡化换列。
   节奏：单颗停留 .9s · 竖线滑落 .35s · 列间交叉 .15s，一轮 ≈ 20.6s。
   ⚠️⚠️ 关键取舍：**播完一轮就彻底静止**，不做"极低频轮巡" ——
      常驻动画会让"静止"这个状态消失（页面在等你读，角落却一直在动），
      那不是背景音，是背景音乐开着。背景音的定义就是「平时听不见，一动就注意到」。
      悬停某列 → 从该列重新亮起；移出 → 停在该列，不回开头。
   ⚠️ 光点不用伪元素：`.flow-step::before` 已被药丸间那根竖线占用。
   ⚠️ 位置不写死在 CSS：竖线的绝对 x 取决于 .flow-stage 的 padding，断点还会变，
      故由 JS 量出实际坐标再设 left/top。
   ============================================================ */
.flow-wrap{position:relative}
.flow-spark{
  position:absolute;width:6px;height:6px;border-radius:50%;
  margin:-3px 0 0 -3px;                    /* 让光点中心对准坐标点 */
  background:#fff;
  box-shadow:0 0 4px 1px rgba(255,255,255,.85),0 0 16px 5px rgba(189,17,17,.5);
  opacity:0;z-index:3;pointer-events:none;
  transition:top .35s cubic-bezier(.4,0,.2,1),opacity .16s linear;
}
.flow-spark.on{opacity:1}
/* ⚠️ 「.is-hit / .is-passed / .is-live 的覆盖规则」**统一放在本文件最末尾** ——
   它们必须晚于下面的 `.flow-wrap.flow-playing .flow-step{opacity:.45}`（同特异性、靠位置取胜）。
   曾经写在这里（更早的位置）→ 被播放态规则压住 → 药丸到了也不亮。 */
/* 整列微光：安静的那一半。10~15% 的红，只在当前列 */
.flow-stage{transition:border-color .6s var(--ease),box-shadow .6s var(--ease)}
.flow-stage.is-live{
  border-color:rgba(212,69,69,.36);
  box-shadow:0 0 0 1px rgba(212,69,69,.07),0 0 34px rgba(189,17,17,.055);
}
@media (prefers-reduced-motion:reduce){
  .flow-spark{display:none}
  .flow-wrap.flow-playing .flow-step{opacity:1}     /* 兜底：不动画就必须全部可见 */
  .flow-wrap .flow-step.is-passed{opacity:1}
  .flow-step.is-hit,.flow-stage.is-live{box-shadow:none}
}

/* ===== 工作流入场动画 ===== */
.flow-wrap[data-flow-animate]:not(.flow-playing) .flow-stage{
  opacity:0;transform:translateY(24px);
}
.flow-wrap[data-flow-animate]:not(.flow-playing) .flow-step{
  opacity:.08;
}
.flow-wrap.flow-playing .flow-stage{
  opacity:1;transform:none;
  transition:opacity .5s var(--ease),transform .5s var(--ease);
}
/* ⚠️ 播放态【不再】把药丸整批变亮 —— 由光点到达时才点亮（.is-hit）。
   但⚠️⚠️ 基础亮度不能太低：实测 .12 时，若光点没跑（IO 未触发 / 用户截图在动画开始前），
   整块就是一片死灰、完全不可读 —— 被经鸣报「样式变得很怪」。
   现在的基础态是「读得清、但明显未激活」，光点走过再明显提亮，对比依然成立。 */
.flow-wrap.flow-playing .flow-step{
  opacity:.45;
  transition:opacity .45s var(--ease),border-color .3s,box-shadow .4s,color .3s;
}
/* ⚠️⚠️ 这里原有 16 条写死的 transition-delay（列 0/.55/1.1/1.65s，列内 +.1s 递进），
   做的是「整批错峰淡入」。0.30.7 已被「光点下流」取代并删除，原因有三：
     ① 它把 4 列药丸**一起**点亮，等于"流程"两个字没被演出来，只是集体出现；
     ② `nth-child(1..4)` 写死 —— 某语言药丸数不是 4 个就会错位（隐患）；
     ③ 与新的逐颗点亮机制同时存在会打架（两套都想控制 opacity）。
   ✅ 现在改为：stage 仍然淡入（解决"从无到有"），药丸则由光点逐颗点亮
      （见下方 .flow-step.is-hit / .is-passed，时序由 main.js 读 DOM 实时算）。 */
.flow-wrap.flow-playing .flow-stage:nth-child(2){transition-delay:.18s}
.flow-wrap.flow-playing .flow-stage:nth-child(3){transition-delay:.36s}
.flow-wrap.flow-playing .flow-stage:nth-child(4){transition-delay:.54s}

/* ---------- 关于摘要 ---------- */
.section-about-summary{background:var(--bg-elev)}
/* 05 板块顶部留白与邻块对齐：
   01–04 等板块的 .container 第一个子元素是 .section-head，而它带
   margin-top:calc(-1*clamp(40px,5vw,100px))。.container 没有 padding-top / border-top，
   这条负 margin 会「塌陷」到 container 自身，把它整体上拉约 70px（1400px 视口下）。
   05 板块没有 section-head，第一个子元素直接是 .about-summary-grid，
   于是少了这 70px 上拉，顶部空白比邻块大一截。这里补一条等值的负 margin。
   ⚠️ 排查提示：塌陷改变的是「位置」而非属性值，container 的 margin-top 计算值
      仍是 0px，所以只靠 getComputedStyle 逐项对比是查不出来的。 */
.section-about-summary > .container{
  margin-top:calc(-1*clamp(40px,5vw,100px));
}

/* 09 联系我们：与 05 同一个毛病——container 首个子元素不是 .section-head，
   少了它那条负 margin 的塌陷上拉，顶部留白比其它板块多约 70px。补等值负 margin。 */
.contact > .container{
  margin-top:calc(-1*clamp(40px,5vw,100px));
}
/* 联系卡里的「值」（邮箱 / 微信 / 电话）是拉丁与数字，改用英文字体，
   与全站数字统一（原先落到 --font-cn 的系统中文栈，字形不搭） */
.contact-card .v,
.contact-card .v a{font-family:var(--font-en)}
/* 内联样式清理：原本写在 HTML 上的两处间距/字号 */
.contact-card .l--tight{margin-top:8px}
.contact-card .l--hours{margin-top:4px;font-size:11px;opacity:.6}

/* ---------- 05 板块 · 大事记时间线 ---------- */
.about-chrono{
  grid-column:1 / -1;
  margin-top:clamp(24px,3vw,36px);
  padding-top:clamp(22px,2.6vw,32px);
  border-top:1px solid var(--line);
}
.about-chrono-label{
  font:600 12px/1 var(--font-cn);
  color:var(--fg-muted);
  letter-spacing:.1em;
  text-transform:uppercase;
  margin-bottom:clamp(16px,2vw,22px);
}
.chrono-cols{
  display:grid;
  grid-template-columns:1fr 1fr;
  column-gap:clamp(30px,5vw,84px);
}
.chrono-col{
  list-style:none;
  margin:0;
  padding:2px 0 0 20px;
  border-left:1px solid var(--line);
}
.chrono-col li{
  position:relative;
  padding:0 0 13px;
  font-size:13.5px;
  line-height:1.65;
  color:var(--fg-muted);
}
.chrono-col li:last-child{padding-bottom:0}
/* 时间线圆点：落在左侧竖线上 */
.chrono-col li::before{
  content:"";
  position:absolute;
  left:-23.5px;
  top:7px;
  width:7px;height:7px;
  border-radius:50%;
  background:var(--red);
}
/* 最新一条（各列最后一行）用空心点强调「进行中」 */
.chrono-col li.is-latest::before{
  background:var(--bg-elev);
  box-shadow:0 0 0 2px var(--red) inset;
}

/* ===== 大事记动效（仅两层：年份扫描 + 悬浮高亮，勿加其它） =====
   高亮统一切换 .active 类（由 chrono-motion.js 控制）。 */
.chrono-col li{
  border-radius:4px;   /* 与数据卡/伙伴盒统一 */
  transition:background-color .45s,color .45s;
}
.chrono-col li.active{
  background:rgba(255,45,45,.07);   /* 极浅红底 */
  color:var(--fg);                  /* 说明文字由灰提亮为白 */
}
.chrono-col li::before{
  transition:transform .3s,box-shadow .3s,background-color .3s;
}
.chrono-col li.active::before{
  transform:scale(1.45);
  background-color:var(--red);
  box-shadow:0 0 10px rgba(255,45,45,.9);
}
.chrono-col li.active.is-latest::before{
  background-color:var(--bg-elev);
  box-shadow:0 0 0 2px var(--red) inset,0 0 10px rgba(255,45,45,.8);
}
/* 年份高亮：光带只作用在**文字笔画**上（不是整块矩形），故不会露出方框；
   用「双层背景」保证数字永远不会消失：
     第一层 = 会移动的光带（被文字裁剪）
     第二层 = 常驻纯红底（铺满整段文字，永远盖住文字区域） */
.chrono-col li b{transition:color .45s}
.chrono-col li.active b{
  background-image:
    linear-gradient(90deg,transparent 0%,rgba(255,175,175,.95) 50%,transparent 100%),
    linear-gradient(var(--red),var(--red));
  background-size:56px 100%,100% 100%;
  background-repeat:no-repeat,no-repeat;
  background-position:-56px 0,0 0;
  -webkit-background-clip:text;
  background-clip:text;
  -webkit-text-fill-color:transparent;
  animation:chrono-sweep 1.3s linear;
}
@keyframes chrono-sweep{
  from{background-position:-56px 0,0 0}
  to{background-position:100% 0,0 0}
}
/* 减弱动态：全部动画/过渡关闭，仅静态显示高亮色 */
@media (prefers-reduced-motion:reduce){
  .chrono-col li,
  .chrono-col li::before,
  .chrono-col li b{transition:none}
  .chrono-col li.active b{
    animation:none;
    background-image:none;
    -webkit-text-fill-color:currentColor;
    color:var(--red);
  }
  .chrono-col li.active::before{transform:none}
}
.chrono-col li b{
  display:inline-block;
  min-width:48px;
  margin-right:10px;
  font:700 13px var(--font-en);
  color:var(--red-text);
  letter-spacing:.02em;
}
@media(max-width:768px){
  .chrono-cols{grid-template-columns:1fr;row-gap:22px}
  .chrono-col{border-left:1px solid var(--line)}
}
/* 注：此处原先有一条 `.section-about-summary > .container{width:100%}`，
   是为「section 用 inline style 设为 flex 容器、导致 .container 的 margin:auto 收缩」
   而加的补偿。该 inline flex 已移除，section 现在是普通 block，
   这条补偿不再需要（保留反而会让 container 顶比其它板块多出 72px）。 */
/* 05 板块 = 三段式：①序号+标题 ②数据条+保障+伙伴 ③大事记，逐带纵向排列。
   每带内部各自横排，段间靠 .asb-divider 分隔，故这里是单列网格。 */
.about-summary-grid{
  display:grid;
  grid-template-columns:1fr;
  row-gap:0;
}
.about-summary-main .section-title{margin-bottom:18px}
/* 需求 1：「了解更多」归属标题组——与主标题同行、垂直居中，紧跟标题右侧
   （不再孤悬右栏，右栏也不必为它留顶部空间） */
.about-summary-head{
  display:flex;
  align-items:center;
  flex-wrap:wrap;
  gap:clamp(16px,2.4vw,32px);
}
.about-summary-head .about-summary-actions{flex:none;margin:0}
/* 标题行内的 h2 去掉下边距，副标题贴近标题（需求：三位一体与上一行近一些） */
.about-summary-head .section-title{margin-bottom:0}
.section-about-summary .about-summary-main .section-sub{margin-top:8px}
/* ART 装饰字：直接跟在 .section-num(05) 后面、同一行的普通文本——
   与 05 天然同高（同一行盒），也天然不额外占高度（行盒高度已由 05 撑起）。
   全灰、更浅（6% 白），不做红色 accent。用独立类 .art-deco，避免影响 en/zh-TW 的旧结构。 */
.section-about-summary .art-deco{
  position:relative;                         /* relative 仅做视觉微调，不占布局、不改变行盒 */
  top:clamp(-58px,-4.2vw,-28px);             /* 与 05 视觉中心齐平（默认 baseline 会落在 05 脚部） */
  display:inline;
  margin-left:clamp(10px,1.4vw,20px);        /* 与 05 之间留一点气口 */
  font:700 clamp(24px,2.6vw,38px)/1 var(--font-en);
  letter-spacing:.02em;
  color:rgba(255,255,255,.06);
  white-space:nowrap;
  pointer-events:none;
  user-select:none;
}
.section-about-summary .art-deco .art-en-accent{color:inherit}
.about-summary-desc{font-size:15.5px;color:var(--fg-muted);line-height:1.8;margin-bottom:28px;max-width:48ch}
.about-summary-list{display:flex;flex-direction:column;gap:14px}
.about-summary-list .trust-item{
  display:flex;flex-direction:column;gap:4px;
  padding:18px 22px;
  background:var(--bg);
  border:1px solid var(--line);
  border-radius:var(--radius-lg);
}
.about-summary-list .trust-item .k{font-weight:700;font-size:15.5px}
.about-summary-list .trust-item .v{font-size:13.5px;color:var(--fg-muted)}
.about-summary-list .trust-item .v.small{font-size:12.5px;color:var(--fg-dim)}

/* ---------- 内页小 Hero ---------- */
.section-hero-sm{padding:clamp(80px,10vw,140px) 0 clamp(40px,5vw,64px)}
.section-hero-sm .section-title{font-size:40px}
.section-hero-sm .section-sub{margin-top:20px}

/* ---------- 资质荣誉网格 ---------- */
.cred-grid{
  display:grid;grid-template-columns:repeat(4,1fr);
  gap:1px;background:var(--line);
  border:1px solid var(--line);border-radius:var(--radius-lg);
  overflow:hidden;
}
.cred-item{
  background:var(--bg-elev);
  padding:clamp(24px,3vw,36px);
  display:flex;flex-direction:column;gap:10px;
  transition:background .3s var(--ease);
}
.cred-item:hover{background:var(--bg-elev2)}
.cred-item .cred-k{font-size:clamp(16px,1.8vw,20px);font-weight:700;line-height:1.4}
.cred-item .cred-v{font-size:14px;color:var(--fg-muted);letter-spacing:.04em}

/* ---------- LAB 海报墙 ---------- */
.lab-grid{
  display:grid;grid-template-columns:repeat(4,1fr);
  gap:clamp(16px,2vw,24px);
}
.lab-card{
  position:relative;overflow:hidden;
  border-radius:var(--radius-lg);
  border:1px solid var(--line);
  aspect-ratio:4/3;
  cursor:pointer;
  transition:border-color .35s var(--ease);
}
.lab-card:hover{border-color:var(--red)}
.lab-card-media{position:absolute;inset:0;z-index:1}
.lab-card-media .ph{position:absolute;inset:0}
.lab-card-overlay{
  position:absolute;inset:0;z-index:2;
  display:flex;flex-direction:column;justify-content:flex-end;
  padding:clamp(20px,3vw,32px);
  background:linear-gradient(to top,rgba(10,10,12,.95) 0%,rgba(10,10,12,.7) 55%,transparent 100%);
  opacity:0;
  transition:opacity .4s var(--ease);
}
.lab-card:hover .lab-card-overlay{opacity:1}
.lab-card-date{
  font:500 12px var(--font-en);
  letter-spacing:.12em;
  color:var(--red-text);
  margin-bottom:8px;
}
.lab-card-title{
  font-size:clamp(18px,2vw,24px);
  font-weight:700;line-height:1.3;
  margin-bottom:10px;
}
.lab-card-sub{font-size:13px;font-weight:400;color:rgba(255,255,255,.55);margin-left:6px;letter-spacing:0}
.lab-card-desc{
  font-size:13.5px;color:var(--fg-muted);line-height:1.7;
}

/* ---------- LAB 研究卡（暂无配图 · 内容常显） ----------
   与实验卡的三点差异，都是有意的：
   ① 媒体区不是照片，而是「研究编号 + 英文主题」的水印排版；
   ② **不用 .ph 占位符** —— .ph 的视觉语义是"这里还缺图"，研究卡会看起来像没做完；
   ③ **overlay 常显**（实验卡是 hover 才揭示）—— 研究内容本身就是要被读的，
      纯文字卡再藏进 hover，静止时整张卡就只剩一个编号，信息量为零。 */
/* 研究卡横跨两格：lab-grid 是 4 列，2 张研究卡各占 2 格 → 正好铺满一行，
   否则只剩 2 格、右边空一块；宽度翻倍后文字也不再挤成一条。
   比例单独放宽到 16/7 —— 沿用实验卡的 4/3 会让宽卡变成近 500px 高的巨块。 */
.lab-card--research{
  grid-column:span 2;
  aspect-ratio:16/7;
}
@media (max-width:768px){
  /* 窄屏 lab-grid 变单列，span 2 会撑破格子 */
  .lab-card--research{grid-column:span 1;aspect-ratio:4/3}
}
.lab-card--research .lab-card-media{
  background:linear-gradient(135deg,rgba(255,255,255,.035),rgba(255,255,255,.008));
}
.lab-research-mark{
  position:absolute;inset:0;
  display:flex;flex-direction:column;justify-content:flex-start;
  gap:12px;padding:clamp(20px,3vw,32px);
}
.lab-research-no{
  font:300 clamp(38px,5.5vw,68px)/1 var(--font-en);
  font-variant-numeric:tabular-nums;
  color:var(--fg);opacity:.15;letter-spacing:.02em;
}
.lab-research-en{
  font:500 11px/1.5 var(--font-en);
  letter-spacing:.22em;text-transform:uppercase;
  color:var(--red-text);opacity:.9;
}
.lab-card--research .lab-card-overlay{opacity:1}
.lab-cta{
  display:flex;flex-direction:column;align-items:center;gap:20px;
  text-align:center;
}
.lab-cta-text{
  font-size:clamp(18px,2.4vw,28px);
  color:var(--fg-muted);font-weight:500;
}

/* ---------- 简略案例 ---------- */
.case-card-mini .case-body{
  padding:18px 20px;
}
.case-card-mini .case-name{font-size:17px;margin-bottom:6px}
.case-card-mini .case-brief{font-size:13.5px}
.case-link-muted{color:var(--fg-dim);cursor:default}
.case-link-muted:hover{color:var(--fg-dim)}
.case-cta-row{margin-top:14px;display:flex;flex-wrap:wrap;gap:12px;align-items:center}

/* ---------- 网站地图（桌面常态展开） ---------- */
.sitemap{
  padding-top:0;
}
.sitemap-head{
  font:700 13px var(--font-en);
  letter-spacing:.32em;text-transform:uppercase;
  color:var(--fg-dim);
  margin-bottom:20px;
}
.sitemap-grid{
  display:grid;grid-template-columns:repeat(5,1fr);
  gap:clamp(20px,3vw,40px);
}
.sitemap-col{display:flex;flex-direction:column;gap:8px}
.sitemap-col-title{
  font-size:13px;font-weight:700;
  color:var(--fg);
  letter-spacing:.08em;
  margin-bottom:6px;
}
.sitemap-col a{font-size:13.5px;color:var(--fg-muted);transition:color .25s}
.sitemap-col a:hover{color:var(--red-text)}

/* ---------- 大事记 / 时间线 ---------- */
.chrono-table{
  width:100%;border-collapse:collapse;
  margin:20px 0 16px;
  border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;
}
.chrono-table th{
  background:var(--bg-elev2);
  font:700 12.5px var(--font-cn);
  letter-spacing:.06em;color:var(--fg-muted);
  padding:12px 14px;text-align:left;
  border-bottom:1px solid var(--line);
}
.chrono-table td{
  padding:14px;border-bottom:1px solid var(--line);
  font-size:14px;line-height:1.7;vertical-align:top;
}
.chrono-table td:first-child{
  font-weight:700;color:var(--red-text);
  white-space:nowrap;font-size:13px;
}
.chrono-table td:nth-child(2){
  font:600 13px var(--font-en);
  color:var(--fg-muted);white-space:nowrap;
}
.chrono-table tbody tr:last-child td{border-bottom:none}
.chrono-table tbody tr:hover{background:var(--bg-elev)}

.chrono-table-sm{
  width:100%;border-collapse:collapse;
  margin:16px 0;
  font-size:13.5px;
}
.chrono-table-sm th{
  background:var(--bg-elev2);
  font:600 12px var(--font-cn);
  color:var(--fg-muted);
  padding:10px 12px;text-align:left;
  border-bottom:1px solid var(--line-strong);
}
.chrono-table-sm td{
  padding:10px 12px;
  border-bottom:1px solid var(--line);
  line-height:1.65;vertical-align:top;
}
.chrono-table-sm tbody tr:last-child td{border-bottom:none}

.chrono-expand{
  border:1px solid var(--line);
  border-radius:var(--radius);
  background:var(--bg-elev);
  overflow:hidden;
}
.chrono-expand[open]{border-color:rgba(189,17,17,.3)}
.chrono-expand summary{
  list-style:none;cursor:pointer;
  padding:18px 22px;
  font:600 15px var(--font-cn);
  color:var(--red-text);
  display:flex;align-items:center;gap:8px;
  transition:background .25s var(--ease);
}
.chrono-expand summary:hover{background:var(--bg-elev2)}
.chrono-expand summary::-webkit-details-marker{display:none}
.chrono-expand[open] summary{border-bottom:1px solid var(--line)}
/* chrono-expand 展开增强 — 独立箭头 + 脉动提示（覆盖 FAQ 全局 + 冲突） */
.chrono-expand summary::before{
  content:"";
  width:10px;height:10px;
  border-right:2px solid var(--red);
  border-bottom:2px solid var(--red);
  transform:rotate(45deg) translateY(-2px);
  margin-right:10px;
  flex:none;
  transition:transform .35s var(--ease);
}
.chrono-expand summary::after{content:"" !important}  /* 干掉 FAQ 全局的 + */
.chrono-expand[open] summary::before{
  transform:rotate(-135deg) translateY(-2px);
}
.chrono-expand summary{
  position:relative;
  padding:clamp(16px,1.8vw,22px) clamp(18px,2vw,26px);
  font:600 clamp(15px,1.5vw,17px) var(--font-cn);
  color:var(--red-text);
}
.chrono-expand summary .chrono-hint{
  font:400 12px var(--font-cn);
  color:var(--fg-dim);
  margin-left:10px;
  letter-spacing:.04em;
}
/* 脉动光圈提示：前 3 秒或永远 */
.chrono-expand:not([open]){
  animation:chrono-pulse 3s ease-in-out infinite;
}
@keyframes chrono-pulse{
  0%,100%{box-shadow:0 0 0 0 rgba(189,17,17,.0)}
  50%{box-shadow:0 0 0 3px rgba(189,17,17,.12)}
}
.chrono-expand summary:hover{
  background:var(--bg-elev2);
  color:var(--fg);
}
.chrono-body{padding:24px clamp(20px,3vw,36px) 32px}
.chrono-h3{
  font:700 16px var(--font-cn);
  color:var(--fg);
  margin:28px 0 12px;
  padding-left:12px;
  border-left:3px solid var(--red);
}
.chrono-h3:first-child{margin-top:0}
.chrono-body p{font-size:14.5px;line-height:1.8;margin:8px 0}
.chrono-body ul{margin:8px 0 12px;padding-left:20px}
.chrono-body li{font-size:14.5px;line-height:1.75;margin:4px 0}
.chrono-body .callout-sm{
  background:var(--red-soft);
  border-left:3px solid var(--red);
  padding:12px 16px;
  margin:12px 0;
  font-size:13.5px;
  color:var(--fg-muted);
  border-radius:0 var(--radius) var(--radius) 0;
}

/* ---------- 响应式（v2.0 新增） ---------- */
@media (max-width:1024px){
  .prod-grid{grid-template-columns:1fr}
  .prod-value-grid{grid-template-columns:repeat(2,1fr)}
  .prod-form-grid{grid-template-columns:repeat(2,1fr)}
  .prod-delivery-grid{grid-template-columns:1fr}
  .prod-revenue-grid{grid-template-columns:repeat(2,1fr)}
  .prod-timeline{grid-template-columns:1fr}
  .flow-wrap{grid-template-columns:repeat(2,1fr)}
  .about-summary-grid{grid-template-columns:1fr}
  .cred-grid{grid-template-columns:repeat(2,1fr)}
  .lab-grid{grid-template-columns:repeat(2,1fr)}
  .chrono-table-wrap,.chrono-table-sm-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch}
  .chrono-table,.chrono-table-sm{display:block;overflow-x:auto;-webkit-overflow-scrolling:touch}
}
@media (max-width:768px){
  .prod-grid{grid-template-columns:1fr}
  .prod-hero[open]{grid-column:span 1}
  .prod-value-grid{grid-template-columns:1fr}
  .prod-form-grid{grid-template-columns:1fr}
  .prod-revenue-grid{grid-template-columns:1fr}
  .philosophy-grid{grid-template-columns:1fr}
  .flow-wrap{grid-template-columns:1fr}
  .sitemap-grid{grid-template-columns:repeat(2,1fr)}
  .cred-grid{grid-template-columns:1fr}
  .cred-gallery{grid-template-columns:repeat(2,1fr)}
  .lab-grid{grid-template-columns:1fr}
  .footer-bottom{grid-template-columns:1fr;gap:8px;text-align:center}
  .footer-bottom-r{justify-content:center}
  .contact-card{grid-template-columns:1fr}
  .contact-card-logo{display:none}
  .chrono-body{padding:16px 18px 24px}
  .chrono-table td,.chrono-table-sm td{font-size:13px;padding:10px 8px}
}
@media (hover:none){
  .lab-card-overlay{opacity:1}
}
@media (max-width:480px){
  .sitemap-grid{grid-template-columns:1fr}
  .cred-gallery{grid-template-columns:1fr}
}

/* ---------- 自动轮播（单图框，横向切换） ---------- */

/* ---------- 自动轮播（垂直滚动，右指示点） ---------- */
.ph-auto-slider{
  position:relative;width:100%;overflow:hidden;
  border-radius:var(--radius-lg);
  aspect-ratio:1600/424;
  background:var(--bg-elev);
}
.ph-auto-track{
  display:flex;flex-direction:column;width:100%;
  height:100%;
  transition:transform .6s cubic-bezier(.22,.61,.36,1);
}
.ph-auto-track img{
  flex:0 0 100%;width:100%;height:100%;
  object-fit:cover;display:block;
  filter:brightness(.85);
  transition:filter .4s;
}
.ph-auto-slider:hover .ph-auto-track img{filter:brightness(1)}
.ph-auto-dots{
  position:absolute;right:14px;top:50%;transform:translateY(-50%);
  display:flex;flex-direction:column;gap:8px;z-index:2;
}
.ph-auto-dots button{
  width:6px;height:20px;border-radius:3px;border:none;
  background:rgba(255,255,255,.3);cursor:pointer;
  transition:background .2s,transform .2s;
  padding:0;
}
.ph-auto-dots button.active{
  background:var(--red);transform:scaleY(1.3);
}
.ph-auto-dots button:hover{background:rgba(255,255,255,.6)}

/* ---------- 改造前中后 三栏 ---------- */
.bna-grid{
  display:grid;grid-template-columns:repeat(4,1fr);
  gap:clamp(12px,1.5vw,20px);
}
.bna-item{margin:0;position:relative;overflow:hidden;border-radius:var(--radius-lg)}
.bna-item .ph{aspect-ratio:4/3}
.bna-item img{width:100%;height:100%;object-fit:cover;display:block;filter:brightness(.85);transition:filter .4s}
.bna-item:hover img{filter:brightness(1)}
.bna-item figcaption{
  position:absolute;left:0;right:0;bottom:0;padding:10px 14px;
  font:600 13px/1.4 var(--font-cn);color:#fff;letter-spacing:.04em;
  background:linear-gradient(180deg,transparent,rgba(0,0,0,.75));
  pointer-events:none;
}
@media (max-width:768px){
  .bna-grid{grid-template-columns:1fr}
}
/* next-case 图片暗化（Gamma 亮化曲线） */
.next-case .ph{position:relative;overflow:hidden}
.next-case .ph img{
  position:absolute;inset:0;object-fit:cover;
  transition:transform 1.2s cubic-bezier(.22,.61,.36,1);
  will-change:transform;
}
.next-case .ph img.ph-gamma-bright{filter:brightness(1);z-index:1}
.next-case .ph img.ph-gamma-dark{
  filter:brightness(.5);z-index:2;
  -webkit-mask-size:100% 100%;mask-size:100% 100%;
  -webkit-mask-position:center;mask-position:center;
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
  -webkit-mask-opacity:1;mask-opacity:1;
  transition:-webkit-mask-opacity 2.2s cubic-bezier(.15,.65,.3,1),
              mask-opacity 2.2s cubic-bezier(.15,.65,.3,1),
              filter 1.4s cubic-bezier(.22,.61,.36,1);
}
.next-case:hover .ph img.ph-gamma-dark{
  -webkit-mask-opacity:0;mask-opacity:0;
  filter:brightness(.65);
}
.next-case:hover .ph img{transform:scale(1.06)}
.next-case:hover .ph img{
  filter:brightness(1);
  transform:scale(1.03);
}
/* ---------- 轮播叠化模式 ---------- */
.ph-auto-track.ph-auto-fade{
  position:relative;width:100%;height:100%;
}
.ph-auto-track.ph-auto-fade img{
  position:absolute;inset:0;
  opacity:0;
  transition:opacity .7s ease;
  object-fit:cover;
}
.ph-auto-track.ph-auto-fade img.active{
  opacity:1;
}
/* fade 模式下指示点保持在右侧 */
.ph-auto-slider.ph-auto-fade .ph-auto-dots button.active{
  background:var(--red);
}
/* ---------- P2.6 实拍图 + 设计师金句叠加 ---------- */
.case-shot-wrap .case-shot-quote{
  position:absolute;left:0;right:0;bottom:0;padding:32px 40px 28px;
  background:linear-gradient(180deg,transparent 0%,rgba(0,0,0,.88) 100%);
  color:#fff;
}
.case-shot-wrap .case-shot-text{
  font:600 clamp(18px,2.2vw,28px)/1.6 var(--font-cn);
  letter-spacing:.02em;margin:0;
}
.case-shot-wrap .case-shot-src{
  font:500 12px/1 var(--font-en);color:rgba(255,255,255,.55);
  letter-spacing:.12em;text-transform:uppercase;margin-top:10px;
}
@media (max-width:768px){
  .case-shot-wrap .case-shot-quote{padding:20px 24px 18px}
  .case-shot-wrap .case-shot-text{font-size:16px}
}
/* ---------- 宣恩延伸项目 2×2 rc-hero ---------- */
.xuanen-2x2{
  display:grid;grid-template-columns:repeat(2,1fr);
  gap:clamp(20px,2.4vw,36px);
  margin-top:clamp(24px,3vw,40px);
}
.xuanen-2x2 .rc-hero{
  gap:clamp(16px,2vw,28px);
  padding:clamp(16px,1.8vw,24px);
  background:var(--bg-elev);
  border:1px solid var(--line);
  border-radius:var(--radius-lg);
  transition:border-color .3s var(--ease),background .3s var(--ease);
  margin-top:0;
}
.xuanen-2x2 .rc-hero:hover{
  border-color:var(--red);
  background:var(--bg-elev2);
}
.xuanen-2x2 .rc-media{aspect-ratio:4/3;border-radius:var(--radius)}
.rc-info{display:flex;flex-direction:column;gap:6px;min-width:0}
.rc-info .rc-title{font-size:clamp(16px,1.6vw,20px);margin-bottom:4px}
.rc-info .rc-brief{font-size:13.5px;margin-bottom:8px;line-height:1.7}
.rc-role{font-size:12.5px;color:var(--fg-dim);line-height:1.7}
.rc-work{font-size:13px;color:var(--fg-muted);line-height:1.75}
.rc-year{font-size:11.5px;color:var(--fg-dim);line-height:1.6}
.rc-loc{font-size:11.5px;color:var(--fg-dim);line-height:1.6;font-style:italic}
.rc-official{margin-top:8px;font-size:11.5px;color:var(--red-text);line-height:1.6;letter-spacing:.01em}
@media (max-width:860px){
  .xuanen-2x2{grid-template-columns:1fr}
}
/* ===== RC Hero 轮播（叠化 + 左侧指示点） ===== */
.rc-media.rc-carousel{position:relative;overflow:hidden}
.rc-carousel-track{position:relative;width:100%;height:100%}
.rc-carousel-slide{
  position:absolute;inset:0;
  width:100%;height:100%;object-fit:cover;
  opacity:0;transition:opacity 0.8s ease;
  pointer-events:none;
}
.rc-carousel-slide.is-active{opacity:1;pointer-events:auto;z-index:1}
.rc-carousel-dots{
  position:absolute;left:10px;top:50%;
  transform:translateY(-50%);
  display:flex;flex-direction:column;gap:8px;
  z-index:10;
}
.rc-carousel-dot{
  width:6px;height:6px;border-radius:50%;
  background:rgba(255,255,255,0.5);
  border:none;cursor:pointer;padding:0;
  transition:all 0.3s ease;
}
.rc-carousel-dot.is-active{
  width:18px;border-radius:3px;
  background:#fff;
}
.rc-carousel:hover .rc-carousel-dots .rc-carousel-dot{background:rgba(255,255,255,0.7)}

/* case-mini-grid: 简略案例 2 列 */
.case-mini-grid{
  display:grid;
  grid-template-columns:repeat(2,1fr);
  gap:clamp(16px,2vw,24px);
}

/* ============================================================
   #cases-2「Ⅱ 建筑与景观亮化」—— 三行交替网格（0.30.2 · 经鸣 2026-09-18 重排）
   ------------------------------------------------------------
   布局意图（每行左右比例交替，形成流动的错落）：
     行1（矮）  利川 2/3         ｜ 中国一冶 1/3
     行2        丹峰贡水龙城 1/3 ｜ 太原百花谷 2/3
     行3        上湖塘 2/3       ｜ 翠叠施南别業酒店 1/3
   ⚠️ 六张卡统一为「图铺满 + 文字贴底浮层」，与案例页 .cases-all 同一视觉语言。
      （原先首页是「左主卡 + 右 3 竖卡 + 下方 lab-grid」三套不同外观，已废弃。）
   ⚠️ 上湖塘 / 贡水龙城 / 酒店 三张原为 .lab-card，现已改写为 .case-card；
      轮播结构（.rc-carousel）原样保留 → main.js 的轮播初始化照旧生效。
   ⚠️ 全部规则以 #cases-2 限定作用域，不动首页其它组，也不动案例页。
   ============================================================ */
#cases-2 .grp2-grid{
  display:grid;
  grid-template-columns:repeat(3,1fr);
  gap:clamp(10px,1vw,16px);
}
/* 宽度：data-w = 占 3 列中的列数 */
#cases-2 .grp2-grid > [data-w="2"]{grid-column:span 2}
#cases-2 .grp2-grid > [data-w="1"]{grid-column:span 1}
/* 行高：data-h="s" 为矮行（经鸣：「第一行矮一点，高度参考利川的文字高度」）。
   ⚠️ 利川那张有 6 个字段（标题/标签/简介/角色/年份/链接），压缩字号后实测需 ≈220px，
      故矮行给 clamp(190px,17vw,240px)；再矮会挤。其余行统一 250–340px。 */
#cases-2 .grp2-grid > [data-h="s"]{min-height:clamp(190px,17vw,240px)}
#cases-2 .grp2-grid > [data-w]:not([data-h="s"]){min-height:clamp(250px,26vw,340px)}

/* ---------- 卡片本体 ---------- */
#cases-2 .grp2-grid > article{
  position:relative;overflow:hidden;
  border:1px solid var(--line);border-radius:var(--radius-lg);
  background:var(--bg-elev);
  margin:0;min-height:0;
  transition:border-color .3s,transform .3s var(--ease);
}
#cases-2 .grp2-grid > article:hover{border-color:var(--red);transform:translateY(-3px)}

/* ---------- 媒体层铺满整卡 ----------
   ⚠️⚠️ .case-media 必须显式写 aspect-ratio:auto ——
      它在某条响应式规则里被设成了 16/10，窄屏（≤900px）下会把容器撑到 451px 高，
      而卡片只有 320px，图片于是按 451px 取景、被多裁一大截，肉眼看像「只显示了一条」。
      （.rc-media 同理，见下一行。） */
#cases-2 .grp2-grid .case-media,
#cases-2 .grp2-grid .ph{position:absolute;inset:0;aspect-ratio:auto;overflow:hidden}
#cases-2 .grp2-grid .ph img,
#cases-2 .grp2-grid .case-media > img{display:block;width:100%;height:100%;object-fit:cover}
/* 轮播（上湖塘 / 酒店）——沿用 main.js 的 .rc-carousel 结构 */
#cases-2 .grp2-grid .rc-media{position:absolute;inset:0;aspect-ratio:auto;border-radius:0}
/* 轮播在此网格里也要整卡铺满（.lab-card-media 时代有 filter/尺寸残留，一并复位） */
#cases-2 .grp2-grid .case-media img,
#cases-2 .grp2-grid .rc-media img{width:100%;height:100%;object-fit:cover;position:absolute;inset:0}
#cases-2 .grp2-grid .rc-carousel-track{position:absolute;inset:0}
#cases-2 .grp2-grid .rc-carousel-slide{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  opacity:0;transition:opacity .8s ease;pointer-events:none;
}
#cases-2 .grp2-grid .rc-carousel-slide.is-active{opacity:1;pointer-events:auto;z-index:1}
/* ⚠️ 超窄横幅（480×116，比例 4.14）：直接 cover 会被裁到只剩一条，改为**完整显示**
   （object-fit:contain）+ 两侧空白用暗色渐变填充 —— 经鸣：「用黑底渐变暗化填充」。
   渐变里的斜纹与 .cases-all .ph 的占位底色同一套，避免出现"纯黑空洞"。 */
#cases-2 .grp2-grid .case-media img.rc-slide-narrow{
  object-fit:contain;
  /* ⚠️ 显式居中：contain 后上下会留空，必须让窄条落在正中（别被将来任何 bottom 规则顶下去）。
     ⚠️ 经鸣：「不要裁切，保持原比例」→ 这里**只** contain，绝不用 cover。 */
  object-position:center;
  background:
    repeating-linear-gradient(135deg,rgba(255,255,255,.03) 0 10px,transparent 10px 20px),
    linear-gradient(160deg,#17171b 0%,#0d0d10 58%,#141418 100%);
}

/* ---------- 文字浮层：铺满整卡 + 由下往上淡出的渐变遮罩 ----------
   ⚠️⚠️ 0.31.5 回退为 inset:0（铺满整卡）—— 与 Ⅲ（石首园）同一套做法。
   原委：0.31.2 曾改成「贴底自适应高度」，本意是"渐变只盖文字块"，
   但**把渐变压进短小的文字块里，反而造出了"没有上边缘渐变"的硬边**
   （经鸣连续多轮报的问题，最后点明"直接抄下面卡片的代码"）。
   ✅ 正解：像 Ⅲ 那样铺满整卡，用【由下往上的渐变】淡出——
      底部低透明度的黑、往上自然消失，不再有硬边。
   ⚠️ 峰值 .30 是经鸣多轮选值定下的（.95 ✗ → .78 ✗ → .30 ✓），
      靠文字 text-shadow 兜底可读性，**别再调回 .9x**。 */
#cases-2 .grp2-grid .case-body{
  position:absolute;inset:0;
  z-index:2;
  display:flex;flex-direction:column;justify-content:flex-end;
  padding:clamp(12px,1.2vw,18px);
  gap:8px;
  margin:0;grid-column:auto;
  /* ⚠️⚠️ Ⅱ 的渐变＝「**从底部往上淡出，到 76% 就彻底干净**」（0.31.8）
     经鸣画了箭头标注：「就是一个向上的渐变啊」。
     关键三点，改任何一个都会变味：
       ① `to top` —— 方向必须向上（底下最黑、越往上越淡）
       ② **76% 处就 transparent** —— 顶上约四分之一完全还给图片，
          不要拖到 100% 才结束（那样顶部仍有 .1~.3 的黑，整张看着都暗）
       ③ 峰值 .75 足够垫文字，且 74% 以上已全透明
     ⚠️ 素材是**夜景暗图**（贡水龙城/中国一冶/上湖塘/酒店），
        峰值不能照抄 Ⅲ 石首园的 .95/.7 —— 石首园照片本身亮，压 .7 还透得出来，
        暗图压 .7 就是纯黑（0.31.6 踩过，经鸣截图证实三张全黑）。
     ⚠️ 敢压到 .75 是因为 Ⅱ 的文字【有 text-shadow】兜底（本规则最后一行）；
        Ⅲ 没有 shadow、全靠渐变撑对比，故 Ⅲ 保持自己的值不动。 */
  background:linear-gradient(to top,
    rgba(10,10,12,.75) 0%,rgba(10,10,12,.42) 38%,transparent 76%);
  text-shadow:0 1px 3px rgba(0,0,0,.85),0 0 14px rgba(0,0,0,.5);
  opacity:0;
  transition:opacity .32s var(--ease);
  overflow:hidden;
  pointer-events:none;
}
#cases-2 .grp2-grid .wm::after{
  right:clamp(12px,2vw,32px);bottom:clamp(12px,2vw,28px);
  font-size:clamp(40px,6vw,92px);
}
/* ⚠️⚠️⚠️ 必须关掉 base 的 `.case-body::before`！——
   它是【案例页两栏卡】的横向压暗层：
       .case-body::before{ background:linear-gradient(90deg, α .5 → .8 → .92 → .96) }
       .case-card:hover .case-body::before{ opacity:1 }
   在案例页 `.case-body` 只占右半边一列，那个"越往右越黑"正合适；
   可在首页 Ⅱ 的网格里 `.case-body` 是 inset:0 **铺满整卡** ⇒ 悬浮时它把
   **整张卡从左到右压黑**（一直加到 α=.96）。
   ⇒ 经鸣从 0.31.0 起反复报的「悬浮后图片死黑」「从右向左的渐变」就是它。
   ⚠️ 之所以查了十轮没查到：面板只报了 `.case-body` 自己的 background，
      **从没查伪元素**；而 headless 没有鼠标、`.case-card:hover` 不成立，
      它在我这边**永远不打开** ⇒ 一直是亮的。
   ⚠️ Ⅱ 的文字对比由 `.case-body` 自己的 `to top` 渐变 + text-shadow 兜底，不需要这一层。 */
#cases-2 .grp2-grid > article .case-body::before{opacity:0 !important;background:none}
/* ---------- 图片亮度：平时略暗 → 悬浮恢复正常 ----------
   ⚠️⚠️ 2026-09-18 经鸣报：「鼠标悬浮之后，图片死黑」。
      根因是**方向反了**，与 Ⅲ .lab-card 恰好相反：
        Ⅲ ：平时 brightness(.72) → 悬浮提亮    ⇒ 悬浮的净效果是「变亮」
        Ⅱ ：平时【不改亮度】→ 悬浮叠上深渐变 ⇒ 悬浮的净效果是「变暗」→ 看着像死黑
      渐变本身没错（它是给文字铺底的），错的是「平时没有相应的暗化」——
      两边亮度落差全靠 hover 那一下完成，于是像突然熄灯。
      ✅ 修法：给图片本身补上「平时略暗」，与 Ⅲ 同一手法、同一数值。
   ⚠️ 亮度必须用 filter 调，**不能再叠一层黑** ——
      filter 管「图片本身多亮」，渐变管「文字底下压多深」，两件事分开；
      靠叠黑做"平时暗"会在悬浮时变成双层黑。
   ⚠️ 只在有 hover 能力的设备上生效：触屏没有 hover、文字本来就常显，
      再压暗是白吃亏（Ⅲ 在触屏上确实也是暗的，但那是既有行为，不往 Ⅱ 扩散）。 */
@media (hover:hover) and (pointer:fine){
  #cases-2 .grp2-grid .case-media img{filter:brightness(.72) saturate(.92)}
  #cases-2 .grp2-grid > article:hover .case-media img,
  #cases-2 .grp2-grid > article:focus-within .case-media img{
    filter:brightness(1) saturate(1);
  }
}

/* 悬停 / 键盘聚焦浮出（与案例页一致，保证无障碍） */
@media (hover:hover) and (pointer:fine){
  #cases-2 .grp2-grid > article:hover .case-body,
  #cases-2 .grp2-grid > article:focus-within .case-body{opacity:1;pointer-events:auto}
}
/* ⚠️ 触屏（0.31.1 改）：原来是「常显，否则手机上永远看不到信息」——
   经鸣改为**默认只显示图、点一下才出文字**（图配轻缓的自动放大）。
   ✅ 静止时画面干净、图能看全；信息仍可达（文字还在 DOM 里，读屏软件照旧读得到）。
   ⚠️ 关闭态必须同时 `pointer-events:none` —— 否则那块**看不见的 `.case-link`**
      会变成"隐形可点区域"，用户一戳就莫名跳转。
   ⚠️ `.is-open` 由 main.js 的触屏点击模块添加（只在真触屏上绑定）。 */
@media (hover:none),(pointer:coarse){
  #cases-2 .grp2-grid .case-body{opacity:0;pointer-events:none}
  #cases-2 .grp2-grid > article.is-open .case-body{opacity:1;pointer-events:auto}
}

/* ---------- 文字字号：整体收紧（矮行要塞下 6 个字段，不删任何文案） ---------- */
#cases-2 .grp2-grid .case-name{font-size:clamp(16px,1.5vw,20px);line-height:1.3;margin-bottom:2px}
#cases-2 .grp2-grid .case-tags{gap:5px}
#cases-2 .grp2-grid .case-tag{font-size:10.5px;padding:2px 7px}
#cases-2 .grp2-grid .case-brief{font-size:12.5px;line-height:1.5;margin:0}
#cases-2 .grp2-grid .case-role,
#cases-2 .grp2-grid .case-ourwork{font-size:11.5px;line-height:1.45;margin:0}
#cases-2 .grp2-grid .case-year{font-size:11px;line-height:1.4;margin:0}
#cases-2 .grp2-grid .case-link{font-size:12px;margin-top:0;align-self:flex-start}
/* ⚠️ .case-link 原带 `margin-top:auto` —— 在绝对定位的 flex 列里会把链接甩到卡底、
   标题顶到卡顶，中间留大片空白（这正是案例页「宣恩的字靠上」的老问题）。此处一并去掉。 */

/* ---------- 国网南瑞纯文字卡：继续隐藏（0.30.2 重写） ----------
   ⚠️ 原规则是 `#cases-2 .case-mini-right .case-card-textonly{display:none}` ——
      它依赖 .case-mini-right 这层容器，而本次重构已把该容器撤除，规则随之失效，
      国网卡会在首页意外冒出来（实测确认过）。
   ✅ 改为不依赖任何旧容器：只要在 #cases-2 里，纯文字卡就隐藏。
   ⚠️ data-hidden="1" 是 HTML 侧同时打上的标记，两者互为冗余、更保险。
   要恢复这张卡：把 display 改成 block（或删掉本段）。 */
#cases-2 .grp2-grid > [data-hidden="1"],
#cases-2 .grp2-grid > .case-card-textonly{display:none}

/* ---------- ≤900px：降为单列，卡片整宽、按内容高 ---------- */
@media (max-width:900px){
  #cases-2 .grp2-grid{grid-template-columns:1fr;gap:clamp(10px,3vw,16px)}
  #cases-2 .grp2-grid > [data-w]{grid-column:1 / -1}
  #cases-2 .grp2-grid > [data-h="s"],
  #cases-2 .grp2-grid > [data-w]:not([data-h="s"]){min-height:clamp(220px,58vw,320px)}
  /* 窄屏无 hover，直接常显 */
  #cases-2 .grp2-grid .case-body{opacity:1;pointer-events:auto}
}
@media (max-width:560px){
  #cases-2 .grp2-grid > [data-h="s"],
  #cases-2 .grp2-grid > [data-w]:not([data-h="s"]){min-height:clamp(210px,66vw,280px)}
  #cases-2 .grp2-grid .case-name{font-size:16px}
}

.lab-card-media img{
  width:100%;height:100%;object-fit:cover;
  position:absolute;inset:0;
  filter:brightness(.72) saturate(.92);
  transition:filter .5s ease, transform .5s ease;
}
.lab-card:hover .lab-card-media img{
  filter:brightness(.85) saturate(1);
  transform:scale(1.03);
}

/* group Ⅱ 新布局：左 1 大卡 + 右 3 小卡 同高 */

/* group Ⅱ：左主卡 + 右 flex 容器 3 张横向 */

/* ===== group Ⅱ 左主卡 + 右 flex 容器 ===== */

/* ===== group Ⅱ 简化：右卡继承全局 case-card ===== */
/* ⚠️⚠️ 以下「左主卡 + 右 3 竖卡」的旧规则已于 0.30.2 停用：
   首页 #cases-2 已改为三行交替网格（见上方「#cases-2 三行网格」一节），
   全站已无元素带 .case-mini-grid / .case-grid-tall。
   ⚠️ 这里【刻意保留不删】—— 与 #cases-2 相邻的样式（.case-card-main / -narrow / -textonly、
      .lab-card 系列）【案例页与其它语言页仍在大量使用】，删错会连带塌掉别处。
      实测：.lab-card-overlay 在 cases.html 有 7 处、en/lab.html 有 9 处 …
   要彻底清理，需先单独核查这几个类名在全站的引用。 */
.case-mini-grid.case-grid-tall{
  display:grid;
  grid-template-columns: 0.9fr 1.1fr;
  gap: clamp(4px,0.4vw,8px);
}
.case-grid-tall .case-card-main{
  grid-column:1;
  min-height: clamp(740px, 76vh, 1040px);
}
.case-grid-tall .case-mini-right{
  grid-column:2;
  min-height: clamp(740px, 76vh, 1040px);
  display:flex;
  justify-content:flex-end;
  flex-direction:column;
  gap: clamp(4px,0.4vw,8px);
}
/* 右容器里的卡：继承全局 display:grid + position:absolute + 渐变遮罩 */
/* 只调：去掉全局 margin-bottom，加 flex:1 */
.case-mini-right .case-card-mini{
  margin-bottom:0;
  flex:1 1 0;          /* ← 等分剩余空间，自然撑高 */
  min-height:0;
}
/* 南瑞纯文字卡：隐藏图片 + 单列 + 视觉上紧凑 */
.case-mini-right .case-card-textonly .case-media{
  display:none;
}
.case-mini-right .case-card-textonly{
  flex:0 0 auto;                /* ← 不等高，按内容 */
  width:100%;                   /* ← 等宽！和上面两张一样宽 */
  align-self:stretch;
  max-height: clamp(180px, 18vh, 260px);  /* ← 矮很多 */
  grid-template-columns:1fr;
  background: var(--surface-2);
  min-height:0;
  padding: clamp(10px,1vw,14px);
  border:1px dashed var(--line-strong);
}
.case-mini-right .case-card-textonly .case-body{
  padding:0 !important;
  background:transparent !important;
  display:flex !important;
  flex-direction:column !important;
  justify-content:center;
  gap: clamp(2px,0.3vw,5px);
  overflow:hidden;
}
.case-mini-right .case-card-textonly .case-body::before{
  display:none !important;
}
.case-mini-right .case-card-textonly .case-name{
  font-size: clamp(14px,1.4vw,18px);
  font-weight:600;
  line-height:1.25;
}
.case-mini-right .case-card-textonly .case-tags{
  display:flex;
  gap:6px;
}
.case-mini-right .case-card-textonly .case-tag{
  font-size: clamp(10px,0.8vw,12px);
  padding:2px 8px;
}
.case-mini-right .case-card-textonly .case-brief{
  font-size: clamp(12px,1vw,14px);
  color:var(--fg-muted);
  line-height:1.5;
  margin:0;
}
.case-mini-right .case-card-textonly .case-role,
.case-mini-right .case-card-textonly .case-ourwork,
.case-mini-right .case-card-textonly .case-year{
  display:none;
}
/* 右卡文字区更紧凑 */
.case-mini-right .case-card-mini .case-body{
  padding: clamp(10px,1.2vw,16px);
  gap: clamp(4px,0.5vw,8px);
}
.case-mini-right .case-card-mini .case-name{
  font-size: clamp(13px,1.2vw,16px);
  line-height:1.25;
}
.case-mini-right .case-card-mini .case-brief{
  font-size: clamp(11px,0.9vw,13px);
}

/* ============================================================
   手机/平板：#cases 的「左主卡 + 右 3 小卡」改为【单列纵向、整宽】
   ------------------------------------------------------------
   ⚠️⚠️ 原来的 bug（经鸣 2026-09-18 报「一冶/百花谷/南瑞这三个有 bug」）：
     这里只把网格改成 1 列 `grid-template-columns:1fr`，
     却【没重置子元素的 grid-column】—— 主卡仍是 `grid-column:1`、
     右容器仍是 `grid-column:2`。在只有 1 列的网格里，
     `grid-column:2` 会创建一个【隐式第二列】（尺寸 auto，会抢空间），
     结果显式的 `1fr` 那一列被挤成 **2px**，主卡整个塌掉：
       实测 .case-grid-tall → columns = "2px 329px"，主卡 2×2634（几乎不可见）
     ✅ 修法：同时把两个子元素的 grid-column 归到 1。
   ⚠️ 另外桌面端为了「右 3 小卡与大卡等高」设了
     `min-height: clamp(740px,76vh,1040px)`，移动端必须清掉，
     否则容器被硬撑 1000px 高、里面只塞着两列小卡（也是经鸣说的「太小」）。
   ============================================================ */
@media (max-width: 900px){
  .case-mini-grid.case-grid-tall{
    grid-template-columns:1fr;
    gap:clamp(10px,3vw,16px);   /* 手机上是纵向排列，原来 4px 太挤 */
  }
  /* ⚠️ 关键：不重置这两条，就会出现隐式第二列 → 主卡塌成 2px */
  .case-grid-tall .case-card-main,
  .case-grid-tall .case-mini-right{
    grid-column:1;
  }
  /* 主卡：清掉“与大卡等高”的超高 min-height，按屏幕宽给个合理高度 */
  .case-grid-tall .case-card-main{
    min-height:clamp(320px,78vw,460px);
  }
  /* 右容器：改为纵向单列（原来是 row+wrap 挤成两列） */
  .case-grid-tall .case-mini-right{
    flex-direction:column;
    flex-wrap:nowrap;
    min-height:0;
    gap:clamp(10px,3vw,16px);
  }
  /* 3 张卡：不再等分，一律整宽、按内容高 */
  .case-mini-right .case-card-mini{
    flex:0 0 auto;
    width:100%;
    min-height:clamp(260px,66vw,380px);
  }
  /* 南瑞纯文字卡：解除桌面的高度上限，整宽；给个下限免得扁成一条 */
  .case-mini-right .case-card-textonly{
    max-height:none;
    min-height:clamp(150px,44vw,240px);
  }
}
@media (max-width: 560px){
  .case-mini-right .case-card-mini{
    flex:0 0 auto;      /* 原来 flex:1 1 100% 会在纵向容器里等分撑高 */
    width:100%;
  }
}
/* ===== 导航栏案例下拉菜单 ===== */
.nav-dropdown{
  position:relative;
  display:inline-block;
}
.nav-dropdown-trigger{
  display:inline-flex;
  align-items:center;
  gap:4px;
  cursor:pointer;
}
.nav-dropdown-trigger svg{
  transition:transform .25s var(--ease);
}
.nav-dropdown:hover .nav-dropdown-trigger svg, .nav-dropdown:focus-within .nav-dropdown-trigger svg{
  transform:rotate(180deg);
}
.nav-dropdown-menu{
  position:absolute;
  top:calc(100%);
  left:50%;
  transform:translateX(-50%) translateY(-2px);
  min-width:260px;
  background:var(--bg-elev);
  border:1px solid var(--line-strong);
  border-radius:12px;
  padding:8px;
  box-shadow:0 16px 40px rgba(0,0,0,.45);
  opacity:0;
  visibility:hidden;
  pointer-events:none;
  transition:opacity .2s var(--ease), transform .2s var(--ease), visibility .2s;
  z-index:200;
}
.nav-dropdown:hover .nav-dropdown-menu, .nav-dropdown:focus-within .nav-dropdown-menu{
  opacity:1;
  visibility:visible;
  pointer-events:auto;
  transform:translateX(-50%) translateY(0);
}
.nav-dropdown-item{
  display:flex;
  align-items:center;
  gap:12px;
  padding:10px 14px;
  border-radius:8px;
  color:var(--fg);
  text-decoration:none;
  transition:background .15s;
}
.nav-dropdown-item:hover{
  background:var(--surface-2);
  color:var(--red-text);
}
.nav-dd-no{
  font:700 13px var(--font-en);
  color:var(--red-text);
  width:22px;
  text-align:center;
}
.nav-dd-title{
  font-size:13px;
  white-space:nowrap;
}
/* 小屏 */
@media (max-width: 780px){
  .nav-dropdown-menu{
    min-width:auto;
    left:0;
    transform:translateX(0) translateY(-8px);
  }
  .nav-dropdown:hover .nav-dropdown-menu, .nav-dropdown:focus-within .nav-dropdown-menu{
    transform:translateX(0) translateY(0);
  }
}
/* 锚点定位补偿：固定导航栏遮挡问题 */
#cases-1, #cases-2, #cases-3{
  scroll-margin-top: 90px;
}
/* section#cases 本身也要补，因为"案例"主链接跳它 */
#cases{
  scroll-margin-top: 80px;
}
/* 产品子分类锚点 + testimonials */
#p-story, #p-retrofit, #p-device,
#p-research, #p-landscape, #p-content,
#testimonials{
  scroll-margin-top: 100px;
}
/* 关于 ▾ 导航指向的锚点补偿（about.html / 注入板块） */
#hero-about, #intro, #team, #gallery, #credential, #partner,
#philosophy, #contact{
  scroll-margin-top: 96px;
}



/* ⚠️ 取景方向备忘（以后再调时看）：`object-position` 的 y 越【大】越看图片【下部】，
   y 越小越看顶部 —— 经鸣说的「图往上挪」= y 增大。「底边对齐」= center bottom。 */
/* ⚠️ 2026-09-18 经鸣最终定案：**这条特例规则已删除**。
   原委：英文页那张百花谷 `alt="Taiyuan Baihuagu commercial complex"`（不含中文"百花谷"），
   从未被这条规则命中，用的就是默认 `object-position: 50% 50%` —— 经鸣看过觉得那张「定位是 ok 的」，
   于是「直接抄过来」= 让中文/繁中也回到默认居中，不再需要任何特例。
   ⚠️ 删掉后中文/繁中的 `object-position` 回落到初始值 center（与英文页完全一致），
      此后若要再微调单张，请用**独立的语义属性**（如 `data-img-pos`）而不是靠 alt 文案匹配 ——
      alt 是给读屏和 SEO 用的，按它选元素太脆（语言一变就失效）。 */


/* 设计理念区 quote + 落款 */
.method-quote{
  margin-top:48px;
  text-align:center;
  font-size:clamp(20px,2.8vw,34px);
  font-weight:600;
  letter-spacing:.04em;
  line-height:1.6;
  padding:0 24px;
  color:var(--fg);
  display:block
}
.method-quote-l1,
.method-quote-l2{
  display:block;
}

.method-quote-l2{
  margin-top:4px;
}

.method-quote-sign{
  margin-top:20px;
  font-size:clamp(12px,1.2vw,15px);
  font-weight:400;
  letter-spacing:.12em;
  color:var(--fg-muted);
  text-align:right;
  font-style:normal;
}


/* ART 底纹 —— 挨着 05 section-num */


.section-about-summary .art-en-accent{
  color:rgba(200,60,60,.38);
}


/* ART 装饰字：普通流，紧跟「博士团队 · 技艺匠心」大标题。
   原先用绝对定位（相对 section）——但左栏内容在 grid 的 align-items:center 下
   会随右栏高度动态居中，两者参照系不同，永远会对不齐（曾撞上大标题 -31px）。
   改回文档流后天然跟随，不再有对齐问题。 */
.section-about-summary .art-en{
  display:block;
  margin:-6px 0 22px;
  font:700 clamp(17px,1.9vw,25px)/1 var(--font-en);
  letter-spacing:.02em;
  color:rgba(255,255,255,.13);
  white-space:nowrap;
  overflow:hidden;
  text-overflow:ellipsis;
  pointer-events:none;
  user-select:none;
}

/* ART 装饰字与「了解更多 →」并排：左装饰字、右 CTA。
   原先按钮单独占一行、紧贴在标题下方，与下面的数据卡几乎贴住；
   移到装饰字行右侧后，整块留白更均衡（箭头所指的那片空白）。
   注意：.art-en 是 nowrap + ellipsis，作为 flex item 必须给 min-width:0，
   否则它会把按钮挤出去。 */
.art-row{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:clamp(16px,3vw,48px);
  flex-wrap:wrap;            /* 窄屏时按钮自动换行，不硬挤 */
  margin:-6px 0 22px;        /* 接替 .art-en 原本的上下间距 */
}
.art-row .about-summary-actions{
  flex:none;
  /* 胶囊按钮往左收一带：不贴版式右边缘，与右栏文字的右对齐边缘错开一档 */
  margin-right:clamp(24px,4vw,56px);
}
/* ART 装饰字（ART = Artist + Researcher + Technician）从标题区挪到按钮行下方，
   作为低调底纹收尾。method-art 通用样式是 flex+居中，此处改为普通流左对齐，
   与左栏的阅读轴线一致。 */


/* ============================================================
  group Ⅲ 景观展园 · 互动装置 —— lab-card 格式
  ============================================================ */

/* lab-card 里的占位符（适配 lab-card 绝对定位布局） */
.lab-card-media .ph.ph-lab{
  position:absolute;inset:0;
  display:flex;align-items:center;justify-content:center;
  text-align:center;
  background:var(--bg-elev);
  color:var(--fg-dim);
  font-size:clamp(14px,1.4vw,16px);
  line-height:1.6;
}

/* group Ⅱ 建筑与景观亮化 —— 3 张卡均分宽度 */
#cases-2 .lab-grid{
  grid-template-columns:repeat(3,1fr);
}

/* ============================================================
   移动端：#cases-2 的 3 张 lab-card 改为【单列 · 每个占一个整宽】
   （经鸣 2026-09-18：「这三个卡……分开 占一个宽」）
   ------------------------------------------------------------
   ⚠️ 原 bug：上面 `#cases-2 .lab-grid{repeat(3,1fr)}` 写在【媒体查询之外】，
      而且带 ID 特异性 **(1,1,0)** —— 压过了下面媒体查询里的 `.lab-grid`
      (0,1,0)，于是【无论屏幕多窄都锁死 3 列】，手机上三张卡被挤到约 100px 宽。
      （`#cases-3 .lab-grid` 没设列数，所以它手机上正常 —— 这也解释了为什么只有
        这三张有问题。）
   ✅ 修法：用【同等特异性】在移动端覆盖成 1 列（特异性相同时靠书写顺序取胜）。
   ============================================================ */
@media (max-width:900px){
  #cases-2 .lab-grid{
    grid-template-columns:1fr;
    gap:clamp(10px,3vw,16px);
  }
}

/* ⚠️ 经鸣指定：隐藏 #cases-2 里的「国家电网南瑞集团武汉总部」纯文字卡。
   要恢复就删掉这一段（或改成 display:block）。 */
#cases-2 .case-mini-right .case-card-textonly{
  display:none;
}

/* group Ⅲ 的 section 结构 —— 复用 lab-grid 三列 */
#cases-3 .lab-grid{
  margin-top:clamp(32px,4vw,48px);
}

/* group Ⅲ case-group-title 适配新结构 */
#cases-3 .case-group-title{
  margin-bottom:0;
}

/* lab-card 内的 img：确保占满 media 容器 */
.lab-card-media img{
  width:100%;height:100%;
  object-fit:cover;
  display:block;
}

/* a.lab-card 覆盖 article 的默认行为 */
a.lab-card{
  text-decoration:none;
  color:inherit;
  cursor:pointer;
}
a.lab-card:hover{color:inherit}

/* rc-carousel 在 lab-card 内的适配 */
.lab-card-media .rc-media.rc-carousel{
  position:absolute !important;
  inset:0 !important;
  aspect-ratio:auto !important;
}
.lab-card-media .rc-carousel-track{
  position:absolute;inset:0;
}
.lab-card-media .rc-carousel-slide{
  object-fit:cover;
}
.lab-card-media .rc-carousel-dots{
  z-index:5;
}
.lab-card-desc-strong{color:rgba(255,255,255,.9);font-weight:600}


/* ===== 产品占位符（预留单页高度） ===== */
.prod-eyebrow{ display:inline-block; font-size:12px; font-weight:500; letter-spacing:.2em; color:var(--red); opacity:.7; margin-bottom:8px; }
.prod-single{ padding:clamp(28px,3vw,40px); }


/* ===== 产品卡配图 ===== */
.prod-photo{ margin:16px 0; border-radius:var(--radius-md); overflow:hidden; aspect-ratio:16/9; background:rgba(0,0,0,.3); display:flex; align-items:center; justify-content:center; }
.prod-photo img{ max-width:100%; max-height:100%; width:auto; height:auto; object-fit:contain; filter:brightness(.85); transition:filter .4s; display:block; }
.prod-single:hover .prod-photo img{ filter:brightness(1); }

/* ============================================================
   v2.1 关于页重构新增：Hero Badge / 简介 / 照片墙 / 合作伙伴 / 社会责任 CTA
   ============================================================ */

/* ---------- Hero Badge 横排 ---------- */
.hero-badges{
  display:flex;flex-wrap:wrap;gap:clamp(8px,1.2vw,16px);
  margin-top:clamp(20px,2.8vw,36px);
}
.hero-badge{
  display:inline-flex;align-items:center;
  padding:8px 18px;
  border:1px solid var(--line-strong);
  border-radius:999px;
  background:rgba(255,255,255,.02);
  font-size:clamp(12px,1.3vw,14px);
  color:var(--fg-muted);
  letter-spacing:.04em;
  transition:border-color .25s,color .25s;
}
.hero-badge:hover{border-color:var(--red);color:var(--fg)}

/* ---------- 公司简介 ---------- */
.about-intro .intro-body{max-width:62ch}
.about-intro .intro-body p{font-size:16px;line-height:1.8;color:var(--fg);margin-bottom:14px}
.about-intro .intro-body p:first-child{font-size:clamp(18px,2.1vw,22px);font-weight:500;color:var(--fg)}
.about-intro .intro-body p:last-child{margin-bottom:0}
.data-unit{font-size:.55em;color:var(--fg-muted);margin-left:4px;font-weight:400}

/* ---------- 照片墙（不可点，无 lightbox） ---------- */
.photo-wall{
  display:grid;grid-template-columns:repeat(4,1fr);
  gap:clamp(8px,1vw,14px);
  margin-top:clamp(32px,4vw,48px);
  cursor:default; /* 强制默认箭头，暗示不可点 */
}
.pw-item{margin:0;cursor:default}
.pw-media{
  position:relative;
  aspect-ratio:3/2;
  overflow:hidden;
  border-radius:var(--radius);
  background:var(--bg-elev);
}
.pw-media img{
  width:100%;height:100%;object-fit:cover;
  transition:transform .35s var(--ease),filter .35s var(--ease);
  filter:brightness(.78); /* 暗图提亮一点 */
  cursor:default;
}
.pw-item:hover .pw-media img{
  transform:scale(1.03);
  filter:brightness(.92);
}
.pw-item figcaption{
  position:absolute;
  left:0;right:0;bottom:0;
  padding:28px 14px 10px;
  font:500 13px/1.4 var(--font-cn);
  color:#fff;
  letter-spacing:.04em;
  background:linear-gradient(180deg, rgba(0,0,0,0) 0%, rgba(0,0,0,.65) 100%);
  opacity:0;
  transform:translateY(8px);
  transition:opacity .3s var(--ease), transform .3s var(--ease);
  pointer-events:none;
}
.pw-item:hover figcaption{
  opacity:1;
  transform:translateY(0);
}
@media (max-width:860px){
  .photo-wall{grid-template-columns:repeat(2,1fr)}
}

/* ---------- 合作伙伴 ---------- */
.partner-wall{
  display:grid;grid-template-columns:repeat(4,1fr);
  gap:1px;background:var(--line);border:1px solid var(--line);
  border-radius:var(--radius-lg);overflow:hidden;
  margin-top:clamp(32px,4vw,48px);
}
.partner-item{
  display:flex;align-items:center;gap:clamp(14px,1.6vw,22px);
  padding:clamp(18px,2.2vw,28px) clamp(16px,1.8vw,24px);
  background:var(--bg-elev);
  transition:background .25s;
}
.partner-item:hover{background:var(--bg-elev2)}
.partner-logo{
  flex:none;
  width:clamp(56px,6vw,72px);
  height:clamp(40px,4.4vw,52px);
  display:flex;align-items:center;justify-content:center;
  border:1px solid var(--line);
  border-radius:6px;
  background:var(--bg);
  font:700 clamp(11px,1vw,13px)/1.1 var(--font-en);
  letter-spacing:.06em;
  color:var(--fg-muted);
  text-align:center;
  transition:border-color .25s,color .25s;
  overflow:hidden;
}
.partner-item:hover .partner-logo{border-color:var(--red);color:var(--fg)}
.partner-logo-text{white-space:nowrap}
.partner-logo img{max-width:100%;max-height:100%;object-fit:contain;filter:brightness(0) invert(1) opacity(.35);transition:filter .3s}
.partner-item:hover .partner-logo img{filter:brightness(0) invert(1) opacity(.75)}
.partner-info{min-width:0}
.partner-name{font:600 clamp(14px,1.5vw,16px) var(--font-cn);color:var(--fg);letter-spacing:.02em}
.partner-desc{margin-top:4px;font-size:clamp(12px,1.2vw,13.5px);color:var(--fg-dim);line-height:1.65}
.partner-desc br{display:block;margin-top:2px}
@media (max-width:860px){
  .partner-wall{grid-template-columns:repeat(2,1fr)}
}
@media (max-width:560px){
  .partner-wall{grid-template-columns:1fr}
}

/* ---------- 社会责任 CTA ---------- */
.resp-cta .resp-cta-inner{
  display:flex;align-items:center;justify-content:space-between;gap:clamp(16px,2vw,32px);
  padding:clamp(28px,3.6vw,40px) clamp(24px,3vw,36px);
  border:1px solid var(--line-strong);
  border-radius:var(--radius-lg);
  background:linear-gradient(135deg,var(--bg-elev) 0%,var(--bg-elev2) 100%);
}
.resp-cta .resp-cta-inner > div{flex:1;min-width:0}
.resp-cta .btn-primary{flex:none}
@media (max-width:720px){
  .resp-cta .resp-cta-inner{flex-direction:column;text-align:center}
  .resp-cta .resp-cta-inner > div{display:flex;flex-direction:column;align-items:center}
}
/* ============================================================
   主页动态 · 实验大图入口带
   ============================================================ */
.section-dynamic{padding-top:clamp(48px,6vw,72px)}
.dyn-band{
  display:grid;grid-template-columns:1fr 1fr;
  gap:clamp(12px,1.6vw,24px);
  margin-top:clamp(24px,3vw,40px);
}
.dyn-tile{
  position:relative;display:block;
  aspect-ratio:16/9;
  border-radius:var(--radius-lg);
  overflow:hidden;
  text-decoration:none;color:inherit;
  transition:transform .35s var(--ease);
}
.dyn-tile:hover{transform:translateY(-4px)}
.dyn-media{position:absolute;inset:0}
.dyn-media img{
  width:100%;height:100%;object-fit:cover;
  transition:transform .6s var(--ease),filter .5s var(--ease);
  filter:brightness(.55);
}
.dyn-tile:hover .dyn-media img{
  transform:scale(1.06);
  filter:brightness(.72);
}
.dyn-overlay{
  position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(0,0,0,.1) 30%,rgba(0,0,0,.85) 100%);
}
.dyn-body{
  position:absolute;inset:auto 0 0 0;
  padding:clamp(16px,2.2vw,28px);
  z-index:2;
  display:flex;flex-direction:column;gap:6px;
}
.dyn-tag{
  font:700 clamp(11px,1vw,13px)/1 var(--font-en);
  letter-spacing:.25em;
  color:var(--red);
}
.dyn-title{
  font:700 clamp(18px,2vw,26px)/1.35 var(--font-cn);
  color:var(--fg);
  margin:0;
}
.dyn-cta{
  font-size:clamp(12px,1.2vw,14px);
  color:var(--fg-muted);
  letter-spacing:.04em;
  transition:color .25s;
}
.dyn-tile:hover .dyn-cta{color:var(--red)}
@media (max-width:720px){
  .dyn-band{grid-template-columns:1fr}
}
/* ============================================================
   about.html 团队总览 + 成员卡 ×6
   ============================================================ */
.team-overview{
  margin-top:clamp(24px,3vw,36px);
  padding:clamp(16px,2vw,24px) clamp(18px,2vw,28px);
  border:1px solid var(--line);border-radius:var(--radius);
  background:var(--bg-elev);
  font-size:clamp(13.5px,1.4vw,15px);
  line-height:1.85;color:var(--fg-muted);
}
.team-overview .ph{
  display:inline-block;min-width:2em;
  border-bottom:1px dashed var(--line-strong);
  color:transparent;
}
.team-members{
  display:grid;grid-template-columns:repeat(6,1fr);
  gap:clamp(10px,1.1vw,14px);
  margin-top:clamp(24px,3vw,36px);
}
.team-member-card{
  background:var(--bg-elev);
  border:1px solid var(--line);
  border-radius:var(--radius);
  overflow:hidden;
  transition:border-color .25s,transform .25s var(--ease);
}
.team-member-card:hover{border-color:var(--red);transform:translateY(-3px)}
.team-member-ph{
  position:relative;aspect-ratio:3/4;
  overflow:hidden;background:var(--bg);
}
.team-member-ph .ph{
  position:absolute;inset:0;
  background:linear-gradient(135deg,var(--bg-elev) 0%,var(--bg-elev2) 100%);
}
.team-member-ph img{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
}
.team-member-info{padding:clamp(10px,1.2vw,14px) clamp(12px,1.4vw,16px)}
.team-member-name{
  font:600 clamp(13px,1.3vw,15px) var(--font-cn);
  color:var(--fg);
}
.team-member-role{
  margin-top:2px;
  font-size:clamp(12px,1.1vw,13px);
  color:var(--fg-dim);
}
@media (max-width:1024px){
  .team-members{grid-template-columns:repeat(4,1fr)}
}
@media (max-width:720px){
  .team-members{grid-template-columns:repeat(3,1fr)}
}

/* ===== 关于摘要 · 共享组件 ===== */
.about-data-strip{
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(150px,1fr));
  gap:12px;
  margin:48px 0 36px;
}
.about-data-strip .data-item{
  text-align:left;
  padding:20px 18px;
  background:var(--bg-elev2);
  border:1px solid var(--line);
  border-radius:4px;   /* 设计审计：圆角家族统一到 4px（原 2px 与伙伴盒 4px、时间线 6px 不一致） */
}
.about-data-strip .data-v{
  /* flex + 底部对齐：数值行**底边**落在同一条线上，
     这样字号小一档的文字型卡（「头版报道」）不会比数字卡浮高一截 */
  display:flex;
  align-items:flex-end;
  /* 固定占位高度：保证「数值 / 标签 / 描述」三行在每张卡里落在同一水平线上 */
  min-height:clamp(26px,3.2vw,40px);
  font:800 clamp(26px,3.2vw,40px)/1 var(--font-en);
  color:var(--fg);
}
/* 红色只留一个焦点：仅「头版报道」卡用红数字——重点才立得住 */
.about-data-strip .data-item--focus .data-v{color:var(--red-text)}
/* 数字后的单位（如 万+㎡）字号小一号，和数字区分 */
.about-data-strip .data-v-unit{
  font-size:.58em;
  font-weight:700;
  color:var(--fg-muted);
  margin-left:2px;
}
/* 短词类大数字（如 千万内）字号小一号 */
.about-data-strip .data-v--sm{
  /* 多字词卡（如「头版报道」）：整体小一档 + nowrap，词绝不从中间断行（需求 4） */
  font-size:clamp(20px,2.4vw,27px);
}
.about-data-strip .data-v{white-space:nowrap}
/* 设计审计（taste-skill 规则）：数值用等宽数字，五张卡的位数/宽度天然对齐 */
.about-data-strip .data-v,
.chrono-col li b,
.section-num{font-variant-numeric:tabular-nums}
/* 设计审计：标题防孤字（末行只有一个字/词） */
.section-title{text-wrap:balance}
.about-data-strip .data-u{
  display:block;
  font:600 14px/1.4 var(--font-cn);
  color:var(--fg);
  margin-top:8px;
}
.about-data-strip .data-d{
  display:block;
  font:400 12px/1.5 var(--font-cn);
  color:var(--fg-muted);
  margin-top:6px;
  /* 说明固定一行：五张卡高度一致，也避免「宣恩一河两岸」这类硬断行 */
  white-space:nowrap;
  overflow:hidden;
  text-overflow:ellipsis;
}
.about-employer-mini,
.about-partner-mini{
  align-self:stretch;
  margin-top:0;
  padding:24px 0 0;
  border-top:0;
}
.about-employer-mini .apm-label,
.about-partner-mini .apm-label{
  font:600 12px/1 var(--font-cn);
  color:var(--fg-muted);
  letter-spacing:.1em;
  margin-bottom:18px;
  text-transform:uppercase;
}
.about-employer-mini .apm-list,
.about-partner-mini .apm-list{
  display:flex;
  flex-wrap:wrap;
  gap:14px 28px;
  align-items:center;
}
.about-employer-mini .apm-item,
.about-partner-mini .apm-item{
  font:700 15px/1 var(--font-en);
  color:rgba(255,255,255,.35);
  letter-spacing:.05em;
  transition:color .2s;
  cursor:default;
}
/* 合作伙伴真实 logo：默认置灰压暗（与暗底协调、不抢数据卡的戏），hover 恢复原色 */
.about-partner-mini .apm-item img{
  display:block;
  height:30px;width:auto;
  filter:grayscale(1);
  opacity:.55;
  transition:filter .25s,opacity .25s;
}
.about-partner-mini .apm-item:hover img{
  filter:none;
  opacity:1;
}
.about-employer-mini .apm-item:hover,
.about-partner-mini .apm-item:hover{ color:var(--fg); }


/* ===== 社会责任 · 证照图片 ===== */
.resp-cred-photos{
  margin-top:32px;
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(220px,1fr));
  gap:20px;
}
.resp-cred-photos .rc-photo-item{
  margin:0;
  text-align:center;
}
.resp-cred-photos .rc-photo-item img{
  width:100%;
  height:auto;
  border:1px solid var(--border);
  background:#fff;
  transition:transform .25s, box-shadow .25s;
  cursor:zoom-in;
}
.resp-cred-photos .rc-photo-item img:hover{
  transform:translateY(-2px);
  box-shadow:0 8px 24px rgba(0,0,0,.4);
}
.resp-cred-photos .rc-photo-item figcaption{
  margin-top:10px;
  font:500 12px/1.4 var(--font-cn);
  color:var(--fg-muted);
}

/* ===== 无数字卡片（业绩背书） ===== */
.about-data-strip .data-item--textonly .data-u{
  color:var(--fg);
  font-size:12px;
  font-weight:500;
  letter-spacing:.02em;
}

/* ===== 双图交替（存量改造） ===== */
.prod-photo.prod-photo--dual{position:relative;overflow:hidden}
.prod-photo--dual .prod-photo-img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:0;animation:prodFadeOut 12s ease-in-out infinite}
.prod-photo--dual .prod-photo-img:first-child{opacity:1;animation:prodFadeOut 12s ease-in-out infinite}
.prod-photo--dual .prod-photo-img--alt{animation:prodFadeIn 12s ease-in-out infinite}
@keyframes prodFadeOut{
  0%,33%{opacity:1}
  66%{opacity:0}
  100%{opacity:0}
}
@keyframes prodFadeIn{
  0%,33%{opacity:0}
  66%{opacity:1}
  100%{opacity:1}
}
.prod-photo--dual .prod-photo-label{
  position:absolute;left:16px;bottom:14px;
  font:600 12px/1 var(--font-en);letter-spacing:.08em;
  color:#fff;padding:6px 12px;border-radius:2px;
  background:rgba(0,0,0,.35);backdrop-filter:blur(4px);
}

/* ===== LAB 三图轮播卡片 ===== */
.lab-card-media--triple{overflow:hidden}
.lab-card-media--triple .lab-card-img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:0;filter:brightness(.85) saturate(1);transition:none}
.lab-card-media--triple .lab-card-img--1{animation:labTriple 9s ease-in-out infinite;animation-delay:0s}
.lab-card-media--triple .lab-card-img--2{animation:labTriple 9s ease-in-out infinite;animation-delay:3s}
.lab-card-media--triple .lab-card-img--3{animation:labTriple 9s ease-in-out infinite;animation-delay:6s}
@keyframes labTriple{
  0%,28%{opacity:1}
  33%,100%{opacity:0}
}
/* hover 暂停轮播 */
.lab-card:hover .lab-card-media--triple .lab-card-img{animation-play-state:paused}

/* ===== 城市故事剧场 产品页 ===== */

/* Hero 副标题加大 */
.section-sub--big{font-size:clamp(16px,1.8vw,20px);color:var(--fg);line-height:1.8}

/* 四大构成 */
.story-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:clamp(20px,2.8vw,36px);margin-top:clamp(28px,3.6vw,48px)}
.story-card{
  position:relative;padding:clamp(24px,2.8vw,36px);
  border:1px solid var(--line);border-radius:var(--radius-lg);
  background:var(--bg-elev);transition:border-color .3s var(--ease),transform .3s var(--ease);
}
.story-card:hover{border-color:var(--red);transform:translateY(-2px)}
.story-card-num{
  position:absolute;top:clamp(12px,1.4vw,18px);right:clamp(16px,1.8vw,24px);
  font:800 clamp(28px,3.2vw,44px)/1 var(--font-en);
  color:rgba(255,255,255,.06);letter-spacing:.02em;
}
.story-card h3{font:700 clamp(18px,2vw,24px)/1.4 var(--font-cn);margin-bottom:12px;color:var(--fg)}
.story-card p{font-size:15px;color:var(--fg-muted);line-height:1.8}

/* 案例卡 */
.story-cases{display:grid;grid-template-columns:repeat(2,1fr);gap:clamp(20px,2.8vw,36px);margin-top:clamp(28px,3.6vw,48px)}
.story-case{
  display:block;border:1px solid var(--line);border-radius:var(--radius-lg);overflow:hidden;
  background:var(--bg-elev);text-decoration:none;color:inherit;
  transition:border-color .3s var(--ease),transform .3s var(--ease);
}
.story-case:hover{border-color:var(--red);transform:translateY(-2px)}
.story-case-media{aspect-ratio:16/9;overflow:hidden}
.story-case-media img{width:100%;height:100%;object-fit:cover;transition:transform .6s var(--ease)}
.story-case:hover .story-case-media img{transform:scale(1.04)}
.story-case-body{padding:clamp(18px,2vw,28px)}
.story-case-tag{display:inline-block;font:600 11px/1 var(--font-en);letter-spacing:.14em;text-transform:uppercase;color:var(--red);margin-bottom:8px}
.story-case h3{font:700 clamp(16px,1.8vw,20px)/1.4 var(--font-cn);margin-bottom:8px}
.story-case p{font-size:14px;color:var(--fg-muted);line-height:1.7}

/* 宣恩县区域数据 */
.story-datasheet{
  margin-top:clamp(32px,4vw,56px);padding:clamp(20px,2.4vw,32px);
  border:1px solid var(--line);border-radius:var(--radius-lg);
  background:linear-gradient(135deg,rgba(189,17,17,.06) 0%,rgba(189,17,17,0) 60%);
}
.story-datasheet-label{font-size:13px;color:var(--fg-muted);margin-bottom:18px;font-style:italic}
.story-datasheet-label strong{color:var(--red);font-style:normal}
.story-data-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:clamp(16px,2vw,28px)}
.story-data-item .n{font:800 clamp(24px,2.8vw,36px)/1 var(--font-en);color:var(--red);font-variant-numeric:tabular-nums}
.story-data-item .u{font:500 clamp(12px,1.3vw,14px) var(--font-cn);color:var(--fg-muted);margin-left:4px}
.story-data-item .d{font-size:13px;color:var(--fg-dim);margin-top:6px}

/* CTA */
.story-cta{
  text-align:center;padding:clamp(40px,5vw,72px) clamp(20px,2.4vw,32px);
  border:1px solid var(--line);border-radius:var(--radius-lg);
  background:var(--bg-elev);
}
.story-cta h2{font:700 clamp(22px,2.6vw,32px)/1.4 var(--font-cn);margin-bottom:10px}
.story-cta p{font-size:15px;color:var(--fg-muted);margin-bottom:24px}
.story-cta .btn-primary{display:inline-block}

/* 响应式 */
@media(max-width:768px){
  .story-grid{grid-template-columns:1fr}
  .story-cases{grid-template-columns:1fr}
  .story-data-grid{grid-template-columns:repeat(2,1fr)}
}
@media(max-width:480px){
  .story-data-grid{grid-template-columns:1fr}
}

/* ===== 城市故事剧场 产品页 · 2026-09-15 改版新增 ===== */

/* Hero 左右分栏 */
.story-hero{display:grid;grid-template-columns:1.15fr 1fr;gap:clamp(28px,4vw,64px);align-items:center}
@media(max-width:900px){.story-hero{grid-template-columns:1fr;gap:clamp(24px,5vw,40px)}}

/* Hero 主标语（视觉钩子） */
.story-slogan{font:600 clamp(20px,2.6vw,28px)/1.45 var(--font-cn);color:var(--fg-muted);margin-top:clamp(10px,1.4vw,16px)}

/* Hero 产品公式 */
.story-formula{font:500 clamp(14px,1.5vw,16px)/1.8 var(--font-cn);color:var(--fg-muted);margin-top:12px;white-space:nowrap}
/* 小屏：公式允许换行，避免撑宽卡片造成横向溢出 */
@media(max-width:768px){
  .story-formula{white-space:normal}
}

/* Hero 数据条（三格 + 上下细线） */
.story-stats{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(16px,2vw,28px);margin-top:clamp(22px,3vw,32px);padding:clamp(16px,2vw,22px) 0;border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.story-stats .story-data-item .d{color:var(--fg-muted)}
@media(max-width:560px){.story-stats{grid-template-columns:1fr;gap:14px}}

/* Hero 按钮行 + 次级按钮 */
.story-actions{display:flex;flex-wrap:wrap;gap:14px;align-items:center;margin-top:clamp(24px,3vw,34px)}
.story-btn-ghost{display:inline-flex;align-items:center;gap:8px;padding:12px 28px;border:1px solid var(--line-strong);border-radius:999px;font-size:15px;font-weight:600;color:var(--fg);transition:border-color .3s var(--ease),transform .3s var(--ease)}
.story-btn-ghost:hover{border-color:var(--red);transform:translateY(-2px)}

/* Hero 右图 + 角标 */
.story-media{position:relative;border:1px solid var(--line);border-radius:var(--radius-lg);overflow:hidden;background:var(--bg-elev)}
.story-media img{display:block;width:100%;aspect-ratio:4/3;object-fit:cover}
@media(max-width:900px){.story-media img{aspect-ratio:16/9}}
.story-media-cap{position:absolute;left:14px;bottom:14px;z-index:2;font:500 12px/1 var(--font-cn);letter-spacing:.06em;color:#fff;background:rgba(10,10,12,.6);padding:7px 12px;border-radius:999px;backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px)}

/* 三列数据网格（交付节奏 7-30-30） */
.story-data-grid--3{grid-template-columns:repeat(3,1fr)}
@media(max-width:768px){.story-data-grid--3{grid-template-columns:repeat(2,1fr)}}
@media(max-width:480px){.story-data-grid--3{grid-template-columns:1fr}}

/* 修既有 CSS 的特异性缺陷：`.prod-form-item span` / `.prod-tl-item span` 会压掉红色编号与档位金额 */
.prod-form-item .prod-form-no{font:700 13px/1 var(--font-en);color:var(--red);letter-spacing:.08em}
.prod-tl-item .prod-tl-no{font:800 clamp(19px,2.2vw,26px)/1.2 var(--font-en);color:var(--red);letter-spacing:.01em}

/* ===== 首页 · 城市故事剧场 全屏产品卡（2026-09-15） ===== */
.prod-screen{
  position:relative;overflow:hidden;display:flex;align-items:center;
  min-height:100vh;min-height:100svh;
  padding:clamp(40px,6vw,88px) clamp(24px,4vw,72px);
}
.prod-screen:hover{transform:none;box-shadow:none}
.prod-screen:hover::before{opacity:.18}
.prod-screen-bg{position:absolute;inset:0;z-index:0}
.prod-screen-bg img{width:100%;height:100%;object-fit:cover;display:block}
.prod-screen-bg::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(90deg,rgba(10,10,12,.95) 0%,rgba(10,10,12,.86) 46%,rgba(10,10,12,.40) 100%);
}
.prod-screen-inner{position:relative;z-index:1;width:100%;max-width:760px}
.prod-screen-title{font-size:clamp(26px,3.2vw,42px);margin-bottom:10px}
.prod-screen-tagline{font:600 clamp(16px,1.8vw,22px)/1.5 var(--font-cn);color:var(--fg);margin-bottom:10px}
.prod-screen-formula{font-size:14.5px;color:var(--fg-muted);line-height:1.8;margin-bottom:clamp(20px,2.6vw,30px)}
.prod-screen-pillars{grid-template-columns:repeat(2,1fr)}
.prod-screen-pillars .prod-form-item{background:rgba(18,18,22,.74);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px)}
.prod-screen-pillars .prod-form-item span{line-height:1.65}
.prod-screen .story-stats{margin-top:clamp(20px,2.6vw,28px);padding:clamp(14px,1.8vw,20px) 0;grid-template-columns:repeat(3,1fr);gap:clamp(14px,2vw,26px)}
.prod-screen-rhythm{font-size:14px;color:var(--fg-muted);line-height:1.7;margin-top:clamp(16px,2vw,22px)}
.prod-screen-rhythm strong{color:var(--fg);font-weight:600;margin-right:10px}
.prod-screen-chips{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px}
.prod-screen-chips span{font-size:12.5px;color:var(--fg-muted);border:1px solid var(--line);border-radius:999px;padding:6px 12px}
.prod-screen-links{margin-top:clamp(22px,3vw,32px);gap:14px;align-items:center}
.prod-screen-note{position:absolute;right:clamp(16px,2vw,28px);bottom:clamp(14px,2vw,24px);z-index:2;font-size:11.5px;letter-spacing:.08em;color:rgba(255,255,255,.45)}
@media(max-width:900px){
  .prod-screen{min-height:0;padding:clamp(32px,7vw,56px) clamp(20px,5vw,32px)}
  .prod-screen-bg::after{background:linear-gradient(180deg,rgba(10,10,12,.86) 0%,rgba(10,10,12,.93) 55%,rgba(10,10,12,.96) 100%)}
  .prod-screen-inner{max-width:100%}
}
@media(max-width:640px){
  .prod-screen-pillars{grid-template-columns:1fr}
  .prod-screen .story-stats{grid-template-columns:1fr;gap:12px}
  .prod-screen-chips span{font-size:12px;padding:5px 10px}
}

/* ---------- 关于摘要 · 底部贯穿分隔线 ---------- */
.asb-divider{
  grid-column:1 / -1;
  border-top:1px solid var(--line);
  margin-top:clamp(24px,3vw,40px);
}
/* ---------- 05 板块 · 三段式版式 ----------
   ① 05 序号 + 标题文字
   ② 数据条 + 团队保障 + 合作伙伴（同一带）
   ③ 大事记
   两条 .asb-divider 作为带间分隔。
   注：①里的「05」仍走 .section-num 的全局定位（absolute / top / right），
      那是本板块版式的一部分，不要改。 */

/* A · 05 板块的序号与留白
   不要在这里覆盖 .section-num！它和全站其它板块一样走
   `.section > *{position:relative}` + `.section-num{top:2vw;right:gutter}`：
   表现为**左侧、半出界**（left 计算为 -gutter），并占一定行高，
   使 container 顶落在 143px —— 与 products / cases / philosophy / workflow / faq 完全一致。
   之前误把序号改成 absolute，它会跑到**右上角**，和其它板块不一致。 */



/* ② 数据条 + 团队保障 + 合作伙伴 同一带 */
.about-band{
  grid-column:1 / -1;
  display:grid;
  /* 数据卡（左）加宽回来：1.9fr:1.1fr → 2.1fr:1fr；
     右栏虽然窄了，但内容改右对齐后仍贴着版式右边缘，视觉不亏 */
  grid-template-columns:minmax(0,2.1fr) minmax(0,1fr);
  column-gap:clamp(28px,4vw,60px);
  /* 需求 3：顶部对齐（默认 stretch 即可），右栏内容用 space-between 拉开撑满，
     顶部与数据卡顶齐、底部也齐平——不再上紧下松 */
  align-items:stretch;
}
.about-band > .about-data-strip{
  margin:0;
  position:relative;   /* 原先是 HTML 内联 style，改由 CSS 承担（设计审计：清理内联样式） */
  grid-template-columns:repeat(auto-fit,minmax(112px,1fr));
}
.about-band-side{
  display:flex;
  flex-direction:column;
  justify-content:space-between;   /* 两块内容拉开，撑满数据卡同高 */
  gap:clamp(16px,2vw,24px);
  /* 右栏内容靠右对齐 */
  text-align:right;
  /* 需求 3：去掉通栏细线，改用「小标签 + 留白」分组（线越少越高级） */
}
/* 需求 3：组标题 13px 灰字 */
.about-band-side .about-employer-mini .apm-label,
.about-band-side .about-partner-mini .apm-label{
  font:600 13px/1 var(--font-cn);
  margin-bottom:12px;
}
/* 需求 3：团队保障三项一行一项、均分、统一居中（不再出现第三项单独贴右）；
   「双休与法定节假日」8 字横向放不下图标，故图标在上、文字在下 */
.about-band-side .about-employer-mini .apm-list{
  display:grid;
  grid-template-columns:repeat(3,minmax(0,1fr));
  gap:10px;
  justify-content:stretch;
}
.about-band-side .about-employer-mini .apm-item{
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:4px;
  font:500 12.5px/1.45 var(--font-cn);
  color:var(--fg-muted);
  text-align:center;
  letter-spacing:0;
}
.about-band-side .about-employer-mini .apm-item svg{width:13px;height:13px}
.about-band-side .about-employer-mini .apm-item svg{color:var(--red);opacity:.75}
/* 需求 3：合作伙伴 logo 装进统一 56px 高盒子，2×2 网格严格对齐；
   灰度 + 60% 透明（暗站标准做法），hover 恢复全彩 */
.about-band-side .about-partner-mini .apm-list{
  display:grid;
  grid-template-columns:repeat(2,1fr);
  gap:10px;
}
.about-band-side .about-partner-mini .apm-item{
  height:47px;                     /* 与字体标签一并缩减高度 */
  display:flex;
  align-items:center;
  justify-content:center;
  background:rgba(255,255,255,.03);
  border:1px solid var(--line);
  border-radius:4px;
  padding:5px 8px;
}
.about-band-side .about-partner-mini .apm-item img{
  max-height:28px;
  max-width:100%;
  height:auto;
  filter:grayscale(1);
  opacity:.6;
  transition:filter .25s,opacity .25s;
}
.about-band-side .about-partner-mini .apm-item:hover img{filter:none;opacity:1}
.about-band-side .apm-list{
  justify-content:flex-end;   /* flex 列表的光标标 / 合作伙伴项贴右 */
}
.about-band-side .about-employer-mini,
.about-band-side .about-partner-mini{
  padding-top:0;
}

/* ---------- 05 板块 · 窄屏 ----------
   ⚠️ 原先**只有** .about-summary-grid 有断点，.about-band 一直没有 ——
   于是 430px 手机上它仍是「184px ｜ 88px」两栏：右栏只有 88px，
   里面 192px 宽的 logo 盒子根本放不下，把整页撑出 113px 横向滚动。 */
@media (max-width:900px){
  .about-band{
    grid-template-columns:1fr;              /* 数据条与右栏改为上下堆叠 */
    row-gap:clamp(20px,3vw,28px);
  }
  .about-band-side{text-align:left}          /* 堆叠后不再右对齐 */
  .about-band-side .apm-list{justify-content:flex-start}
  /* logo 用 auto-fit：窄屏自动 2 列、900px 附近自动 3–4 列，
     避免固定 2 列时每格被拉到 330px 宽、而 logo 只有 28px 高显得空 */
  .about-band-side .about-partner-mini .apm-list{
    grid-template-columns:repeat(auto-fit,minmax(150px,1fr));
  }
  /* ART 装饰行：443px 的不可断行长串，窄屏必然横向溢出，而它只是装饰水印
     → 直接隐藏（实测它是 430px 下 113px 溢出的元凶）。 */
  .section-about-summary .art-deco{display:none}
}
@media (max-width:560px){
  /* 手机上把「团队保障」三项与「合作伙伴」2×2 都保持满宽，避免 88px 那种挤压 */
  .about-band-side .about-employer-mini .apm-list{grid-template-columns:repeat(3,minmax(0,1fr))}
}

/* ---------- 05 板块 · 数据卡换行（**除中文外全部生效**）----------
   ⚠️ 这里用「**排除中文**」而不是「列出 en / fr」——
   0.29.46 只写了 `:lang(en)` / `:lang(fr)`，于是新加的**日语页（lang="ja"）直接漏掉**，
   出现一模一样的文字裁切（经鸣 2026-09-17 截图报「日语版本出现了同样的问题」）。
   改成排除中文后，en / fr / ja / de / es / ru / ar **全都不用再改这里**。

   病根回顾：中文的「68项」「头版报道」只有 2–5 字，拉丁/日文要 9–13 个字符，
   而 .data-v 是 nowrap、.data-d 是 nowrap+overflow:hidden（为中文「五张卡不换行」定的）
   → 在 ~156px 宽的卡里直接把这些词裁掉（fr 曾显示成 "68 breve"、"Première pa"）。
   中文 / 繁体**保持原设定**（本体不受影响）。 */
/* ⚠️ .data-v 是 display:flex（为了让「数字 + 单位」底边对齐），
   flex 容器**不换行** —— 只写 white-space:normal 没用，必须再给 flex-wrap:wrap。 */
html:not(:lang(zh-CN)):not(:lang(zh-TW)) .about-data-strip .data-v{
  white-space:normal;flex-wrap:wrap;align-items:baseline;row-gap:2px;
  font-size:clamp(20px,2.3vw,29px);   /* 非中文数值字号统一收一档 */
}
html:not(:lang(zh-CN)):not(:lang(zh-TW)) .about-data-strip .data-d{
  white-space:normal;overflow:visible;text-overflow:clip;
}
html:not(:lang(zh-CN)):not(:lang(zh-TW)) .about-band > .about-data-strip{
  grid-template-columns:repeat(auto-fit,minmax(150px,1fr));
}
/* 「Première page」「Front page」这类多词短句：再压一档，避免换行后卡过高 */
html:not(:lang(zh-CN)):not(:lang(zh-TW)) .about-data-strip .data-v--sm{
  font-size:clamp(17px,2vw,24px);
}
/* unit（如 patents / brevets / villes）本身较长，字号再收一档，避免整行被它撑爆 */
html:not(:lang(zh-CN)):not(:lang(zh-TW)) .about-data-strip .data-v-unit{font-size:.5em}
/* 法语文本更长，数值字号再收半档 */
html:lang(fr) .about-data-strip .data-v{font-size:clamp(19px,2.2vw,28px)}
/* 团队保障（左）与合作伙伴（右）回到同一行 —— 横线下方并排的两块信息条。
   注意：不要给 .about-partner-mini 加 grid-column:1/-1，那会把它挤到下一行，
   两块就不在同一水平线上了。 */

/* ===== 关于页 · 专家顾问 ===== */
.advisor-grid{
  display:grid;grid-template-columns:repeat(5,1fr);
  gap:clamp(12px,1.3vw,16px);margin-top:clamp(24px,3vw,36px);
}
@media (max-width:1024px){
  .advisor-grid{grid-template-columns:repeat(3,1fr)}
}
@media (max-width:720px){
  .advisor-grid{grid-template-columns:repeat(2,1fr)}
}
.advisor-card{
  background:var(--bg-elev);border:1px solid var(--line);
  border-radius:var(--radius);overflow:hidden;
  transition:border-color .25s,transform .25s var(--ease);
}
.advisor-card:hover{border-color:var(--red);transform:translateY(-3px)}
.advisor-ph{position:relative;aspect-ratio:3/4;overflow:hidden;background:var(--bg)}
.advisor-ph img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.advisor-info{padding:clamp(12px,1.4vw,16px) clamp(14px,1.6vw,18px)}
.advisor-name{font:600 clamp(14px,1.4vw,16px) var(--font-cn);color:var(--fg)}
.advisor-role{margin-top:3px;font-size:clamp(12px,1.1vw,13px);color:var(--red-text)}
.advisor-list{margin-top:10px;padding-left:1em;list-style:disc}
.advisor-list li{font-size:clamp(12px,1.1vw,13px);line-height:1.7;color:var(--fg-muted)}

/* ===== 关于页 · 院校网络 / 项目覆盖标签（共用） ===== */
.academia-tags,.client-tags{
  display:flex;flex-wrap:wrap;gap:clamp(8px,1vw,12px);
  margin-top:clamp(20px,2.4vw,28px);
}
.aca-tag,.cli-tag{
  display:inline-block;padding:8px 14px;
  border:1px solid var(--line);border-radius:999px;
  background:var(--bg-elev);
  font-size:clamp(12px,1.15vw,13.5px);color:var(--fg-muted);
  transition:border-color .25s,color .25s var(--ease);
}
.aca-tag:hover,.cli-tag:hover{border-color:var(--red);color:var(--fg)}
.aca-note,.cli-note{
  margin-top:14px;font-size:clamp(12px,1.1vw,13px);
  color:var(--fg-dim);
}

/* ============================================================
   案例中心 · 筛选条 + 尺寸网格（bento）+ hover 浮层文字（0.29.74）
   ------------------------------------------------------------
   经鸣（2026-09-18）：
     · 6 档尺寸：1×1 / 2×1 / 1×2 / 2×2 / 1×3 / 3×2（卡片跨几列 × 跨几行）
     · 3 列基准
     · **6 号（中国一冶集团总部大楼）用竖卡**，且明确「不要拉伸比例」
     · **所有卡片都是悬浮后出现文字**
     · 无图卡保留，给纯色 / 纹理占位底
   ⚠️ 所有规则以 .cases-all 限定作用域 —— 首页的 .case-card / .lab-card / .rc-hero 一字不动。
   ============================================================ */

/* ---------- 筛选条 ---------- */
/* ⚠️ margin-top 负值把「胶囊行」整体上提（经鸣：这行胶囊往上些）。
   上方那块留白来自 .section-hero-sm 的 padding-bottom（≤64px），
   从案例页这一侧抵消掉，不去动 hero 的通用样式（其它页面也在用）。 */
.cases-filterwrap{padding-top:4px;margin-top:-44px}
/* ⚠️ 提示的定位锚点改在 .cases-filter 自身上（见下方 .cases-hint）——
   曾试过挂在 .container 上，实测提示跑到屏幕最左边、没能与胶囊起点对齐。 */
.cases-filter{display:flex;flex-wrap:wrap;gap:8px;margin:0 0 12px;position:relative}
.cases-chip{
  /* 经鸣：这行胶囊大一些（原 padding:7px 15px / font-size:13.5px） */
  padding:10px 19px;border:1px solid var(--line-strong);border-radius:999px;
  background:none;color:var(--fg-muted);font-size:14.5px;line-height:1;
  font-family:inherit;cursor:pointer;
  transition:color .2s,border-color .2s,background .2s;
}
.cases-chip:hover{color:var(--fg);border-color:var(--fg-muted)}
.cases-chip.is-on{color:var(--red-text);border-color:var(--red);background:rgba(189,17,17,.08)}
/* 「点标签筛选项目」由**常显说明**改为**鼠标悬浮在胶囊上时才浮出的提示**（经鸣）。
   ⚠️ 必须绝对定位脱离文档流：原先是常显且带 `margin-bottom:26px`，
      既占着胶囊下方一整行、又把卡片区往下推 —— 不占位后胶囊"往上"才有空间。
   ⚠️ 触屏没有 hover，这句提示永远出不来 → 直接不显示（点胶囊本身已足够直观）。 */
.cases-hint{
  position:absolute;top:100%;left:0;margin:6px 0 0;
  padding:5px 11px;
  font-size:12.5px;color:var(--fg-dim);
  /* 提示会浮在卡片图上方，必须有底色才读得清（首版只有文字，压在图上糊成一片） */
  background:rgba(14,14,17,.94);
  border:1px solid var(--line);
  border-radius:6px;
  box-shadow:0 6px 18px rgba(0,0,0,.35);
  opacity:0;pointer-events:none;
  transition:opacity .2s var(--ease);
}
.cases-filter:hover ~ .cases-hint{opacity:1}
@media (hover:none),(pointer:coarse){.cases-hint{display:none}}
@media (prefers-reduced-motion:reduce){.cases-hint{transition:none}}

/* ---------- 尺寸网格 ----------
   固定列数 + 固定行高 → 卡片按 span 占位 → 天然对齐（高度不再受文案长短影响）。
   grid-auto-flow:dense 让小卡自动回填大卡留下的空洞 —— 这是「能对齐」的关键。 */
.cases-all{
  display:grid;
  grid-template-columns:repeat(3,1fr);
  grid-auto-rows:clamp(150px,13.9vw,220px);
  gap:clamp(14px,1.6vw,24px);
  grid-auto-flow:dense;
}
/* 六档跨度。⚠️ 用 :where() 把特异性压到 (0,1,0)，
   好让下面的响应式 .cases-all > [data-size] (0,2,0) 能整体覆盖掉。 */
.cases-all > :where([data-size="1x1"]){grid-column:span 1;grid-row:span 1}
.cases-all > :where([data-size="2x1"]){grid-column:span 2;grid-row:span 1}
.cases-all > :where([data-size="1x2"]){grid-column:span 1;grid-row:span 2}
.cases-all > :where([data-size="2x2"]){grid-column:span 2;grid-row:span 2}
.cases-all > :where([data-size="1x3"]){grid-column:span 1;grid-row:span 3}
.cases-all > :where([data-size="3x2"]){grid-column:span 3;grid-row:span 2}
/* ---------- 精确落位（data-pos = "列,行,跨列,跨行"）----------
   ⚠️ 为什么不用 grid-auto-flow:dense 自动回填：实测会留空洞 ——
      1×3 竖卡跨 3 行，形状凑不齐，中文页曾在第 10 行中间与末行共留 3 格缺口。
      **格数够 ≠ 形状铺得满**（45 格 = 15 行整，dense 仍排不满）。
   ✅ 改为先用求解器算出无空洞排布，再在此写死位置（大卡优先的首次适配装箱）。
   ⚠️⚠️ 跨度必须写在这里：只写 `grid-row:3` 是「起始第 3 行、占 1 行」，
      会把 data-size 的 span 覆盖掉（曾把 1×3 竖卡压成 200px 高）。
   ⚠️ 键里带尺寸：中英两页存在「同位置不同尺寸」，只用行列做键会互相污染。
   ⚠️ 位置是**固定行列号**，增删卡片或改尺寸后必须重跑落位脚本，否则错位。
   ⚠️ 响应式（≤1023px）会整体取消这些落位，见文件末尾。 */
.cases-all > [data-pos="1,1,3,2"]{grid-column:1 / span 3;grid-row:1 / span 2}
.cases-all > [data-pos="1,3,2,2"]{grid-column:1 / span 2;grid-row:3 / span 2}
.cases-all > [data-pos="3,3,1,3"]{grid-column:3 / span 1;grid-row:3 / span 3}
.cases-all > [data-pos="1,5,2,2"]{grid-column:1 / span 2;grid-row:5 / span 2}
.cases-all > [data-pos="3,6,1,2"]{grid-column:3 / span 1;grid-row:6 / span 2}
.cases-all > [data-pos="1,7,2,2"]{grid-column:1 / span 2;grid-row:7 / span 2}
.cases-all > [data-pos="3,8,1,2"]{grid-column:3 / span 1;grid-row:8 / span 2}
.cases-all > [data-pos="1,9,2,2"]{grid-column:1 / span 2;grid-row:9 / span 2}
.cases-all > [data-pos="3,10,1,2"]{grid-column:3 / span 1;grid-row:10 / span 2}
.cases-all > [data-pos="1,11,2,2"]{grid-column:1 / span 2;grid-row:11 / span 2}
.cases-all > [data-pos="3,12,1,2"]{grid-column:3 / span 1;grid-row:12 / span 2}
.cases-all > [data-pos="3,12,1,1"]{grid-column:3 / span 1;grid-row:12 / span 1}
.cases-all > [data-pos="1,13,2,1"]{grid-column:1 / span 2;grid-row:13 / span 1}
.cases-all > [data-pos="3,13,1,1"]{grid-column:3 / span 1;grid-row:13 / span 1}
.cases-all > [data-pos="1,14,1,2"]{grid-column:1 / span 1;grid-row:14 / span 2}
.cases-all > [data-pos="1,14,1,1"]{grid-column:1 / span 1;grid-row:14 / span 1}
.cases-all > [data-pos="2,14,1,1"]{grid-column:2 / span 1;grid-row:14 / span 1}
.cases-all > [data-pos="3,14,1,1"]{grid-column:3 / span 1;grid-row:14 / span 1}
.cases-all > [data-pos="2,15,1,1"]{grid-column:2 / span 1;grid-row:15 / span 1}
.cases-all > [data-pos="3,15,1,1"]{grid-column:3 / span 1;grid-row:15 / span 1}

/* ---------- 卡片本体：填满格子，三种卡统一为「图铺满 + 文字浮层」 ---------- */
.cases-all > [data-case]{
  position:relative;overflow:hidden;
  border:1px solid var(--line);border-radius:var(--radius-lg);
  background:var(--bg-elev);
  margin:0;min-height:0;               /* 高度完全由网格 span 决定 */
}
.cases-all .case-card{display:block}
.cases-all .lab-card{aspect-ratio:auto;cursor:pointer}
/* ⚠️ 这里【只】清掉 .rc-hero 从基础样式（见文件上方 .rc-hero）带来的残留：
   grid→block、自带内边距、自带外边距。案例页的卡是「图铺满 + 绝对定位浮层」，必须是 block 且无内边距。
   ⚠️⚠️ 千万不要在这里写 border:none / background:none / border-radius:0 ——
   它们会盖掉上一条 `.cases-all > [data-case]` 统一给的描边与圆角
   （两者特异性同为 0,2,0，本行靠后 → 本行取胜），
   结果是鹿鸣苑（案例页内**唯一**的 .rc-hero）变成全页唯一没有圆角、没有描边的卡，
   夹在一堆圆角卡中间，看着就像「边框坏了」。2026-09-18 经鸣报此问题，已移除那三项。 */
.cases-all .rc-hero{display:block;margin:0;padding:0}

/* 媒体层铺满整卡 */
.cases-all .case-media,
.cases-all .lab-card-media,
.cases-all .rc-media{position:absolute;inset:0;aspect-ratio:auto;border-radius:0}

/* ⚠️ 经鸣明确「不要拉伸比例」——
   object-fit:cover 按图片【原始比例裁切】填满，绝不拉变形（fill 才会变形，全程不用）。
   竖卡（6 号 1×3）也是靠裁切，不是把横图压扁。 */
.cases-all img{display:block;width:100%;height:100%;object-fit:cover;object-position:center}

/* ⚠️ 逐卡取景微调（0.30.2）
   经鸣（百花谷）：「图片定位点，在框内往上移。需要展示的是下面这部分」
   → 图片整体上挪，把画面【下部】让进框内 ⇒ object-position 的 y 值必须【加大】。
   ⚠️ 方向别搞反：y 越小看的是图片顶部，y 越大看的才是底部。
   ⚠️ 用属性选择器只命中这一张卡；不要改上面那条全局规则（会波及 16 张卡）。
   ⚠️ 键里带语义名而不是 data-pos，避免日后重跑落位脚本时错位失效。 */
.cases-all > [data-img-pos="down"] img{object-position:center 72%}

/* 无图卡（只有 .ph 占位）的底色：深色 + 细斜纹，比纯色有质感又不抢眼 */
.cases-all .ph{
  background:
    repeating-linear-gradient(135deg,rgba(255,255,255,.03) 0 10px,transparent 10px 20px),
    linear-gradient(160deg,#17171b 0%,#0d0d10 58%,#141418 100%);
}
.cases-all .ph-text{color:var(--fg-dim)}

/* ---------- 文字浮层：默认隐藏，hover / 键盘聚焦时浮出 ---------- */
.cases-all .case-body,
.cases-all .lab-card-overlay,
.cases-all .rc-info{
  position:absolute;inset:0;z-index:2;
  display:flex;flex-direction:column;justify-content:flex-end;
  padding:clamp(12px,1.2vw,18px);
  gap:8px;                 /* 原 .case-body 继承的是 14px，缩到 8px（经鸣：宣恩的字靠下） */
  margin:0;grid-column:auto;
  /* ⚠️ 渐变要比「看起来够」更深：浮层文字常压在夜景亮面上（灯带、水面反光），
     第一版 (.96/.78/.30) 实测可读性不足 → 把深色区推到 58% 以上，
     并给整个浮层加 text-shadow 兜底（文字跨在亮暗交界处也能读）。 */
  background:linear-gradient(to top,
    rgba(10,10,12,.97) 0%,rgba(10,10,12,.92) 30%,
    rgba(10,10,12,.74) 58%,rgba(10,10,12,.32) 84%,transparent 100%);
  text-shadow:0 1px 3px rgba(0,0,0,.85),0 0 14px rgba(0,0,0,.5);
  opacity:0;
  transition:opacity .32s var(--ease);
  overflow:hidden;
  pointer-events:none;     /* 平时不吃指针，点哪都穿透到卡片本身 */
}
.cases-all .case-card .case-body::before{display:none}   /* 原「hover 再加一层深色」，统一后多余 */
.cases-all .case-link{align-self:flex-start}

/* ---------- 浮层元素级收紧（0.29.75 · 经鸣「宣恩的字靠下」）----------
   问题：首屏 3×2 超宽卡有 6 个字段（标题 / 标签 / 简介 / 承担工作 / 年份 / 链接），
        内容 378px 而卡片仅 423px → 文字占满整卡、看着「从头铺到脚」。
   ⚠️ 文案一条都不能删（经鸣红线），所以只能压**字号 / 行距 / 间距**。
   ⚠️ 这些全是视觉压缩，**不减少也不改写任何文字**。 */
.cases-all .case-name,
.cases-all .lab-card-title,
.cases-all .rc-title{font-size:clamp(17px,1.5vw,21px);line-height:1.32;margin-bottom:2px}
.cases-all .case-brief,
.cases-all .lab-card-desc,
.cases-all .rc-brief{font-size:12.5px;line-height:1.52;margin-bottom:0}
.cases-all .case-tags{gap:5px}
.cases-all .case-tag{font-size:10.5px;padding:2px 7px}
.cases-all .case-ourwork,
.cases-all .case-role,
.cases-all .rc-work,
.cases-all .rc-role{font-size:11.5px;line-height:1.45;margin:0}
.cases-all .case-year,
.cases-all .rc-year,
.cases-all .rc-loc{font-size:11px;line-height:1.4;margin:0}
/* ⚠️⚠️ 关键：`.case-link` 原有 `margin-top:auto` —— 在 flex column 里它会把链接推到卡片最底，
   而把标题/标签/简介/年份全部顶到卡片【上部】，中间留出一大块空白。
   这正是经鸣看到「宣恩的字靠上」的真正原因（不是内容太多）。
   去掉 auto 后，配合面板的 `justify-content:flex-end`，整块文字才会整体贴底。 */
.cases-all .case-link{font-size:12px;margin-top:0}
.cases-all .lab-card-date{font-size:10.5px}

@media (hover:hover) and (pointer:fine){
  /* 悬停浮出；:focus-within 让键盘 Tab 进来也能看到文字（无障碍） */
  .cases-all > [data-case]:hover .case-body,
  .cases-all > [data-case]:hover .lab-card-overlay,
  .cases-all > [data-case]:hover .rc-info,
  .cases-all > [data-case]:focus-within .case-body,
  .cases-all > [data-case]:focus-within .lab-card-overlay,
  .cases-all > [data-case]:focus-within .rc-info{
    opacity:1;pointer-events:auto;
  }
}
/* ⚠️ 触屏没有 hover —— 若照搬「悬停才出文字」，手机上永远看不到任何信息。
   故降级为常显，并把渐变收窄一点、尽量把图露出来。 */
@media (hover:none),(pointer:coarse){
  .cases-all .case-body,
  .cases-all .lab-card-overlay,
  .cases-all .rc-info{
    opacity:1;pointer-events:auto;
    background:linear-gradient(to top,rgba(10,10,12,.97) 0%,rgba(10,10,12,.80) 48%,rgba(10,10,12,.28) 82%,transparent 100%);
  }
}

/* ---------- 1 格高的卡（1×1 / 2×1）竖向空间紧张：字号与间距收紧，保住主要信息 ---------- */
.cases-all > :where([data-size="1x1"],[data-size="2x1"]) .case-body,
.cases-all > :where([data-size="1x1"],[data-size="2x1"]) .lab-card-overlay,
.cases-all > :where([data-size="1x1"],[data-size="2x1"]) .rc-info{
  padding:clamp(12px,1.3vw,18px);gap:8px;
}
.cases-all > :where([data-size="1x1"],[data-size="2x1"]) .case-name,
.cases-all > :where([data-size="1x1"],[data-size="2x1"]) .lab-card-title,
.cases-all > :where([data-size="1x1"],[data-size="2x1"]) .rc-title{
  font-size:clamp(15px,1.45vw,18px);margin-bottom:2px;
}
.cases-all > :where([data-size="1x1"],[data-size="2x1"]) .case-brief,
.cases-all > :where([data-size="1x1"],[data-size="2x1"]) .lab-card-desc{
  font-size:12.5px;line-height:1.6;
}

/* ---------- 筛选动画 ---------- */
/* 要显示的卡：从下方浮上来（经鸣：要的卡片通过小动画上移）
   ⚠️ 位移从 10px 加大到 24px —— 10px 在 423px 高的大卡上看不出「上移」 */
@keyframes casesIn{
  from{opacity:0;transform:translateY(24px) scale(.985)}
  to{opacity:1;transform:none}
}
/* 被筛掉的卡：向上微缩退场（经鸣：不要的卡片小动画隐去）
   ⚠️ 向上退场而非向下 —— 与「显示的卡从下方浮上来」方向一致，像是一次整体上移 */
@keyframes casesOut{
  from{opacity:1;transform:none}
  to{opacity:0;transform:translateY(-10px) scale(.97)}
}
.cases-all > [data-case].is-in{animation:casesIn .38s var(--ease) both}
/* .is-leaving 是过渡态：淡出播完由 JS 换成 .is-hidden（display:none） */
.cases-all > [data-case].is-leaving{animation:casesOut .22s var(--ease) both;pointer-events:none}
.cases-all > [data-case].is-hidden{display:none}
@media (prefers-reduced-motion:reduce){
  .cases-all > [data-case].is-in{animation:none}
  .cases-all .case-body,
  .cases-all .lab-card-overlay,
  .cases-all .rc-info{transition:none}
}

/* ---------- 响应式：小屏放弃 bento 跨度，统一成等比卡片 ----------
   ⚠️ 必须覆盖 span，否则 3×2 在 1~2 列下会溢出容器。
   这里靠特异性 (0,2,0) 压过上面 :where() 的 (0,1,0)。 */
@media (max-width:1023px){
  .cases-all{grid-template-columns:repeat(2,1fr);grid-auto-rows:auto}
  /* ⚠️⚠️ 必须同时取消【精确落位】：data-pos 是写死的行列号，
     2 列下 grid-column:3 会直接溢出容器、把页面撑破。
     （下面 [data-size] 的 span 1 与它特异性相同且写在后面，会把 grid-column 再覆盖成 span 1） */
  .cases-all > [data-pos]{grid-column:auto;grid-row:auto}
  .cases-all > [data-size]{grid-column:span 1;grid-row:span 1;aspect-ratio:16/11}
}
@media (max-width:639px){
  .cases-all{grid-template-columns:1fr}
  .cases-all > [data-size]{aspect-ratio:16/10}
}


/* ============================================================
   全站统一：图片卡片「悬浮缓缓放大 + 曲线变速」（0.29.83）
   ------------------------------------------------------------
   经鸣：「鼠标悬浮到案例卡片时，图片缓缓放大，曲线变速，应用到全站」

   改动前：全站已有 7 处悬浮缩放，但**各写各的** ——
     比例 1.02/1.03/1.04/1.06 四种；曲线有的用 ease、有的**根本没写 transition**；
     还有一批卡片（.case-media、案例页轮播）**完全没有悬浮反馈**。
   ✅ 本节统一：比例 1.05 · 时长 .85s（"缓缓"）· 曲线 var(--ease)
      （--ease = cubic-bezier(.22,.61,.36,1)，站点统一的缓动曲线）

   ⚠️ 三个刻意取舍：
   1. 放文件末尾 + **沿用原规则的选择器**：特异性相同时靠顺序覆盖，
      不必逐个去改散落全站的旧规则（改动集中、好回退）。
   2. **只作用于「卡片类」容器**，绝不碰 `.hero .ph img` / `.case-hero .ph img` ——
      那是首屏/详情页大图，跑 Ken Burns 入场动画，再加 hover 缩放会打架。
   3. 包在 `@media (hover:hover) and (pointer:fine)` 里 ——
      触屏没有真 hover，否则会出现"点一下图就卡在放大态"。
   ============================================================ */
@media (hover:hover) and (pointer:fine){

  /* ---- 过渡定义（同时补齐原本没有过渡的那批）---- */
  .case-card .case-media img,
  .case-card .ph img,
  .rc-hero .ph img,
  /* ⚠️ 案例页统一卡型后 .rc-hero 的图挂在 .rc-media 下（不是 .ph），
     只写 .rc-hero .ph img 会漏掉它 —— 补一条不限容器的 */
  .rc-hero img,
  .lab-card .lab-card-media img,
  .lab-card .ph img,
  .lab-card .lab-card-img,
  .photo-card img,
  .cred-gallery-item img,
  .next-case .ph img,
  .pw-item .pw-media img,
  .dyn-tile .dyn-media img,
  .story-case .story-case-media img,
  .prod-item img,
  .prod-single .prod-photo img,
  .team-card .team-media img{
    transition:transform .85s var(--ease),filter .5s var(--ease);
    will-change:transform;
  }

  /* ---- 统一放大比例（原来 1.02/1.03/1.04/1.06 四种值 → 一律 1.05）---- */
  .case-card:hover .case-media img,
  .case-card:hover .ph img,
  .rc-hero:hover .ph img,
  .rc-hero:hover img,
  .lab-card:hover .lab-card-media img,
  .lab-card:hover .ph img,
  .lab-card:hover .lab-card-img,
  .photo-card:hover img,
  .cred-gallery-item:hover img,
  .next-case:hover .ph img,
  .pw-item:hover .pw-media img,
  .dyn-tile:hover .dyn-media img,
  .story-case:hover .story-case-media img,
  .prod-item:hover img,
  .prod-single:hover .prod-photo img,
  .team-card:hover .team-media img{
    transform:scale(1.05);
  }
}

/* ⚠️ 用户要求减弱动效时：既不放大、也不要过渡 */
@media (prefers-reduced-motion:reduce){
  .case-card .case-media img,.case-card .ph img,.rc-hero .ph img,.rc-hero img,
  .lab-card .lab-card-media img,.lab-card .ph img,.lab-card .lab-card-img,
  .photo-card img,.cred-gallery-item img,.next-case .ph img,
  .pw-item .pw-media img,.dyn-tile .dyn-media img,.story-case .story-case-media img,
  .prod-item img,.prod-single .prod-photo img,.team-card .team-media img{
    transition:none !important;
    will-change:auto;
  }
  .case-card:hover .case-media img,.case-card:hover .ph img,.rc-hero:hover .ph img,.rc-hero:hover img,
  .lab-card:hover .lab-card-media img,.lab-card:hover .ph img,.lab-card:hover .lab-card-img,
  .photo-card:hover img,.cred-gallery-item:hover img,.next-case:hover .ph img,
  .pw-item:hover .pw-media img,.dyn-tile:hover .dyn-media img,.story-case:hover .story-case-media img,
  .prod-item:hover img,.prod-single:hover .prod-photo img,.team-card:hover .team-media img{
    transform:none !important;
  }
  }

  /* ============================================================
  ⚠️⚠️ 工作流「光点到达 / 走过 / 整列激活」的覆盖规则
  —— **必须放在文件最末尾，不要往上挪**
  ------------------------------------------------------------
  原委：最初写在 .flow-note 之后（文件中部），而「工作流入场动画」段的
      `.flow-wrap.flow-playing .flow-step{opacity:.45}` 在【更靠后】的位置。
      两者特异性相同（都是 0,3,0）→ **靠后的赢** → `.is-hit{opacity:1}` 被压成 .45，
      连 color / border 也没接管 —— 表现就是经鸣两次报的「文字还是没亮」。
  ✅ 教训：**CSS 覆盖 = 特异性 + 位置**，两者都要看。
      覆盖规则要么提高特异性，要么放在目标规则【之后】，二者必居其一。
  ============================================================ */
  .flow-wrap .flow-step.is-hit{
  opacity:1;
  color:#fff;
  border-color:rgba(212,69,69,.5);
  box-shadow:0 0 0 1px rgba(212,69,69,.26),0 0 16px rgba(189,17,17,.16);
  }
  .flow-wrap .flow-step.is-passed{opacity:.8}
  .flow-step.is-passed::before{background:rgba(212,69,69,.5)}
  .flow-wrap .flow-stage.is-live{
  border-color:rgba(212,69,69,.36);
  box-shadow:0 0 0 1px rgba(212,69,69,.07),0 0 34px rgba(189,17,17,.055);
  }

/* ============================================================
   触屏：首图文卡片「平时只显示图 + 轻微缓动放大，点击才出文字」（0.31.1）
   ------------------------------------------------------------
   经鸣：「23 这些图文卡片的手机版，平时只显示图，微微缓动放大，点击后再出现文字」
   =「Ⅱ 建筑与景观亮化」+「Ⅲ 景观展园 · 互动装置」两组（首页）。
   ⚠️ 为什么追加到文件末尾：全站已有一条 `@media (hover:none){.lab-card-overlay{opacity:1}}`
      的触屏降级（服务案例页 / 实验室页等多处），而 Ⅲ 用的正是 `.lab-card`。
      这里靠「更靠后 + 更高特异性（带 #cases-3）」把它在首页**局部**改掉，
      **绝不动那条全站规则** —— 否则案例页、实验室页的常显降级会被一起破坏。
   ⚠️ 追加在这里不会扰动上面那个工作流覆盖块：它要的是「位于它所覆盖的目标规则之后」，
      而那两条目标规则在文件中部（`.flow-wrap.flow-playing` 段），先后关系没变。
   ⚠️ 缓动放大沿用 `.hero .ph img` 的思路（hero-kenburns），但卡片更小、张数更多，
      所以幅度更小、周期更短，且**不加 will-change** ——
      一次给十来张卡各建一个合成层会明显吃手机内存。
   ============================================================ */
@media (hover:none),(pointer:coarse){
  /* Ⅲ：盖掉全站的「常显」降级，改为点击展开（`.is-open` 由 main.js 添加） */
  #cases-3 .lab-grid .lab-card-overlay{opacity:0;pointer-events:none}
  #cases-3 .lab-grid .lab-card.is-open .lab-card-overlay{opacity:1;pointer-events:auto}

  /* 轻微缓动放大：只动 transform（合成层），不触发布局/重绘 */
  #cases-2 .grp2-grid .case-media img,
  #cases-3 .lab-grid .lab-card-media img{
    animation:card-slow-zoom 22s ease-in-out infinite alternate;
  }
  /* 轮播里没显示的那几张不必白跑动画，省手机的电 */
  #cases-2 .grp2-grid .rc-carousel-slide:not(.is-active){animation:none}
}
@keyframes card-slow-zoom{
  from{transform:scale(1)}
  to{transform:scale(1.06)}
}
/* ⚠️ 用户要求减弱动效时：一律不放大（与 `.hero .ph img` 的处理保持一致） */
@media (prefers-reduced-motion:reduce){
  #cases-2 .grp2-grid .case-media img,
  #cases-3 .lab-grid .lab-card-media img{animation:none;transform:none}
}

/* ============================================================
   Ⅲ 首页「景观展园 · 互动装置」：浮层渐变只覆盖文字块（0.31.2）
   ------------------------------------------------------------
   经鸣：「你看看下面一点的石首园的变黑，渐变黑只在正文高度，
          标题和图的其它区域不太影响」
   原 `.lab-card-overlay{inset:0}` 让渐变**铺满整卡** → 悬浮时整张卡都在变黑。
   ✅ 改为「贴底 + 高度自适应」：**渐变高度 = 文字块高度**，标题以上还给图片。
   ⚠️ 只限首页 `#cases-3` —— `.lab-card` 是**全站卡型**
      （案例页 7 处、`en/lab.html` 9 处……），改全局会把那些页面一起改掉。
   ⚠️ 渐变不再铺满 → 标题背后的黑变薄，而 Ⅲ 的浮层**原本没有 text-shadow**，
      所以这里必须补上，否则标题压在亮图上会糊。
      （Ⅱ 的 `.case-body` 本来就有 text-shadow，故无需补。）
   ⚠️ 别把这套几何搬去全局 `.lab-card-overlay` —— 案例页那套是配它自己的
      尺寸网格（高度固定、文案更短）调的，改了要重新量。
   ============================================================ */
#cases-3 .lab-grid .lab-card-overlay{
  /* 0.31.6：几何 inset:0 铺满整卡 + 渐变恢复【部署版石首园】原值 .95 → .7@55% → 0
     （经鸣：「目前部署版的石首园卡片就很漂亮的渐变啊」）。
     ⚠️ 0.31.2~0.31.4 期间我给这里加过 text-shadow、又把峰值改成 .30/.78 —— 全部撤了，
        本条规则现在 = 部署版原样（base `.lab-card-overlay` 之外只覆盖几何）。 */
  position:absolute;inset:0;
  background:linear-gradient(to top,rgba(10,10,12,.95) 0%,rgba(10,10,12,.7) 55%,transparent 100%);
}
