@charset "UTF-8";
/* ============================================================================
 *  主站样式 · main.css
 * ----------------------------------------------------------------------------
 *  设计读数：B2B 纺织品牌展示站（Persuade + Experience）
 *    深墨绿 + 单金色强调 + 玻璃分层，与防伪查验页同一套品牌世界。
 *  Dials：VARIANCE 7 / MOTION 8 / DENSITY 4
 *
 *  技术前提（沿用项目原则）：
 *    · 原生 PHP 直出，无构建链、无外部依赖
 *    · 字体走系统栈（中文优先，不引 Google Fonts：国内不可达且 CJK 字重体积过大）
 *    · 图标为内联 SVG
 *    · 全部质感由 CSS / SVG data-URI 合成，不引用任何图片文件
 *
 *  两条设计锁（改动前先读）：
 *    1. 主题锁：整页只有一套主题（深墨绿）。区块之间不反转明暗，
 *       只允许同一主题族内的明度分层（surface-0 → surface-3）。
 *    2. 形状锁：卡片 20px / 小件 12px / 交互件全圆角 999px，全站一致。
 *
 *  动效约定：
 *    · 只在 <html class="motion-ready">（由内联脚本置位）时才隐藏待入场元素，
 *      保证 JS 失效或用户禁用动效时内容依然完整可见。
 *    · 只动画 transform / opacity。滚动监听一律用 ScrollTrigger，不用 scroll 事件。
 * ========================================================================== */

/* ===== 1. 设计令牌 ====================================================== */
:root{
  /* 1.1 深绿阶（与 verify.css 同源，保证两页同品牌） */
  --g-950:#01120c;
  --g-900:#021b12;
  --g-880:#02241a;
  --g-850:#03301f;
  --g-800:#07472f;
  --g-700:#0d6344;
  --g-600:#12855a;
  --g-500:#18a06d;

  /* 1.2 金色强调：全站唯一强调色 */
  --gold-1:#f2e2b6;
  --gold-2:#d3b878;
  --gold-3:#c9ac6b;
  --gold-deep:#8a6f34;
  --gold-ink:#1d3b2a;

  /* 1.3 深底文字阶 */
  --w-100:#ffffff;
  --w-92:rgba(255,255,255,.92);
  --w-78:rgba(255,255,255,.78);
  --w-64:rgba(255,255,255,.64);
  --w-52:rgba(255,255,255,.52);
  --w-38:rgba(255,255,255,.38);

  /* 1.4 发丝线与面 */
  --hair:rgba(255,255,255,.10);
  --hair-2:rgba(255,255,255,.16);
  --hair-gold:rgba(211,184,120,.28);

  /* 1.5 分层系统（层次的核心：明度 + 发丝线 + 内高光 + 投影 四件套） */
  --s0:transparent;                              /* 页面底 */
  --s1:rgba(255,255,255,.030);                   /* 浅面板 */
  --s2:rgba(255,255,255,.052);                   /* 卡片 */
  --s3:rgba(255,255,255,.078);                   /* 抬升 / 玻璃 */

  --lift-1:0 1px 2px rgba(0,0,0,.28);
  --lift-2:0 18px 40px -24px rgba(0,0,0,.72);
  --lift-3:0 34px 76px -32px rgba(0,0,0,.82);
  --inset-hi:inset 0 1px 0 rgba(255,255,255,.14);
  --inset-lo:inset 0 -1px 0 rgba(0,0,0,.22);

  /* 1.6 形状锁 */
  --r-card:20px;
  --r-sm:12px;
  --r-pill:999px;

  /* 1.7 动效令牌（统一缓动，避免一处一个感觉） */
  --ease-out:cubic-bezier(.16,1,.3,1);
  --ease-soft:cubic-bezier(.22,.61,.36,1);
  --dur-fast:.18s;
  --dur-mid:.42s;
  --dur-slow:.78s;

  /* 1.8 排版 */
  --font:-apple-system,BlinkMacSystemFont,"HarmonyOS Sans SC","MiSans","PingFang SC",
         "Noto Sans SC","Source Han Sans SC","Microsoft YaHei","Segoe UI",Roboto,sans-serif;
  --mono:ui-monospace,SFMono-Regular,"SF Mono",Consolas,"Liberation Mono",monospace;

  --nav-h:64px;
}

/* ===== 2. 基础 ========================================================== */
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html{
  -webkit-text-size-adjust:100%;
  scroll-behavior:smooth;
  scroll-padding-top:calc(var(--nav-h) + 16px);
}
body{
  font-family:var(--font);
  font-size:15px;
  line-height:1.7;
  color:var(--w-92);
  background:var(--g-950);
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  text-rendering:optimizeLegibility;
  overflow-x:hidden;
}
a{color:inherit;text-decoration:none}
img{display:block;max-width:100%}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
:focus-visible{outline:2px solid var(--gold-2);outline-offset:3px;border-radius:4px}
::selection{background:rgba(211,184,120,.30);color:#fff}

/* 数字统一等宽，避免跳动 */
.num,.pcard-model,.spec-list .v,.stat-n{font-variant-numeric:tabular-nums}

/* ===== 3. 背景系统（三层合成，与防伪页同一语言） ======================== */
.bg{position:fixed;inset:0;z-index:0;pointer-events:none;overflow:hidden;
  background:
    radial-gradient(128% 68% at 66% -8%, var(--g-700) 0%, var(--g-800) 30%,
                    var(--g-850) 62%, var(--g-900) 100%);
}

/* ⚠ 内容层必须抬到 .bg 之上 —— 这条不是可选优化，删了详情页文字会消失。
 *
 *  .bg 是 position:fixed + z-index:0 的【定位】元素。按 CSS 绘制顺序，
 *  定位元素（第 6 步）画在【未定位的内联内容】（第 5 步）【之上】。
 *  而 .bg 铺满全屏且渐变完全不透明（--g-700 ~ --g-900 都是实色）。
 *
 *  结果：没被提升层级的整段文字会被它整片盖住 —— 元素在 DOM 里、占位也在、
 *  页面也读得到，就是"看不见/像透明的"。受影响的正是详情页的文字：
 *  面包屑、产品名大标题、型号、规格表，以及首页的区块小标题。
 *
 *  当初首页 hero 打过局部补丁（见下方 .hero .wrap{z-index:1}），
 *  但详情页没有 .hero，于是整页文字都被盖住 —— 这就是"详情页看不到产品名"
 *  的真正原因。这里在容器层统一解决，不要再逐个页面打补丁。
 *
 *  为什么不是给 .bg 加 z-index:-1：body 有不透明底色（--g-950），
 *  负层级会让 .bg 沉到 body 底色之下，整块背景反而看不见了。
 *
 *  层级关系（自上而下）：.topnav(30) > #main(1) > .bg(0) > body 底色
 */
#main{position:relative;z-index:1}
/* 斜向柔光带：一道从左上掠过的光 */
.bg::before{
  content:'';position:absolute;inset:-24%;
  background:linear-gradient(113deg,
    rgba(255,255,255,0)    26%,
    rgba(255,255,255,.055) 38%,
    rgba(150,255,200,.10)  46%,
    rgba(255,255,255,.032) 53%,
    rgba(255,255,255,0)    66%);
  filter:blur(7px);
}
/* 颗粒噪点：压住渐变色带 */
.bg::after{
  content:'';position:absolute;inset:0;opacity:.12;mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}
/* 织物织纹：本行当的行业质感 */
.bg .weave{position:absolute;inset:0;opacity:.14;mix-blend-mode:soft-light;
  background-image:
    repeating-linear-gradient( 48deg, rgba(255,255,255,.10) 0 1px, rgba(255,255,255,0) 1px 3px),
    repeating-linear-gradient(-42deg, rgba(0,0,0,.18)        0 1px, rgba(0,0,0,0)        1px 3px)}

/* ===== 4. 布局原语 ====================================================== */
.wrap{width:100%;max-width:1180px;margin:0 auto;padding:0 22px}
.section{position:relative;padding:72px 0 84px}
.stack-sm > * + *{margin-top:10px}
.stack > * + *{margin-top:20px}

/* ===== 5. 深度与面（层次系统） ========================================== */
.surface{
  background:var(--s2);
  border:1px solid var(--hair);
  border-radius:var(--r-card);
  box-shadow:var(--lift-2), var(--inset-hi);
}
.glass{
  background:linear-gradient(145deg, rgba(255,255,255,.085), rgba(255,255,255,.035));
  -webkit-backdrop-filter:blur(22px) saturate(150%);
  backdrop-filter:blur(22px) saturate(150%);
  border:1px solid var(--hair-2);
  border-radius:var(--r-card);
  box-shadow:var(--lift-2), var(--inset-hi), var(--inset-lo);
}
.hairline{height:1px;background:linear-gradient(90deg,transparent,var(--hair-2) 18%,var(--hair-2) 82%,transparent)}

/* ===== 6. 排版阶 ======================================================== */
.eyebrow{
  display:inline-flex;align-items:center;gap:9px;
  font-size:11px;font-weight:600;letter-spacing:.16em;text-transform:uppercase;
  color:var(--gold-2);
}
.eyebrow::before{content:'';width:16px;height:1px;background:currentColor;opacity:.7}
.h-display{font-size:clamp(30px,5.4vw,54px);font-weight:900;line-height:1.12;letter-spacing:.01em;color:#fff}
.h-section{font-size:clamp(19px,2.4vw,24px);font-weight:800;letter-spacing:.02em;color:#fff}
.lede{font-size:15.5px;line-height:1.85;color:var(--w-64);max-width:34em}
.muted{color:var(--w-52)}
.tiny{font-size:12px;letter-spacing:.03em}

/* ===== 7. 顶部导航 ====================================================== */
.topnav{
  position:sticky;top:0;z-index:30;height:var(--nav-h);
  background:rgba(2,24,16,.72);
  -webkit-backdrop-filter:blur(18px) saturate(140%);
  backdrop-filter:blur(18px) saturate(140%);
  border-bottom:1px solid var(--hair);
  transition:background var(--dur-fast) var(--ease-soft),border-color var(--dur-fast) var(--ease-soft);
}
.topnav.is-stuck{background:rgba(2,20,14,.90);border-bottom-color:var(--hair-2)}
/* 滚动期间临时撤掉毛玻璃（由 motion.js 的 initScrollPerf 切换）。
   理由见 motion.js 第 8 节：sticky 吸顶 + backdrop-filter 等于滚动全程
   都在做一次全宽高斯模糊，是移动端掉帧的大头。滚动中本来就看不清
   背景的模糊程度，换成更实的底色视觉几乎无差，手一停立刻恢复玻璃质感。 */
.topnav.is-scrolling{
  -webkit-backdrop-filter:none;backdrop-filter:none;
  background:rgba(2,20,16,.86);
}
.topnav .wrap{display:flex;align-items:center;gap:16px;height:100%}
.brand{display:flex;align-items:center;gap:11px;color:#fff}
.brand-bar{width:3.5px;height:22px;border-radius:2px;flex:0 0 auto;
  background:linear-gradient(180deg,var(--gold-1),var(--gold-3))}
.brand-txt{font-size:16px;font-weight:800;letter-spacing:.06em;line-height:1.1}
.brand-txt small{display:block;font-size:8.5px;font-weight:500;letter-spacing:.18em;
  color:var(--w-38);margin-top:3px}
.nav-links{margin-left:auto;display:flex;gap:4px}
.nav-links a{padding:8px 15px;border-radius:var(--r-pill);font-size:13.5px;color:var(--w-64);
  transition:background var(--dur-fast) var(--ease-soft),color var(--dur-fast) var(--ease-soft)}
.nav-links a:hover{background:rgba(255,255,255,.08);color:#fff}
.nav-links a.is-on{color:var(--gold-1)}

/* ===== 8. 首屏 ==========================================================
 *  层次构成：环境底（.bg）→ 品牌发光体（.hero-glow）→ 内容层 → 数据条
 *  文本元素严格 4 个以内：eyebrow / h1 / 副文案 / CTA
 * ====================================================================== */
.hero{position:relative;padding:clamp(56px,9vw,96px) 0 clamp(48px,7vw,80px);overflow:hidden}
/* 品牌发光体：给首屏一个视觉焦点，不是纯文字墙 */
.hero-glow{
  position:absolute;z-index:0;top:-18%;right:-10%;
  width:min(660px,72vw);aspect-ratio:1;border-radius:50%;
  background:radial-gradient(circle at 50% 50%,
    rgba(24,160,109,.30) 0%, rgba(13,99,68,.16) 38%, rgba(2,27,18,0) 70%);
  filter:blur(14px);pointer-events:none;
}
/* 金色同心环：呼应测温/校验的行业意象，纯装饰但克制 */
.hero-rings{
  position:absolute;z-index:0;top:50%;right:2%;
  width:min(420px,54vw);aspect-ratio:1;transform:translateY(-50%);
  border-radius:50%;border:1px solid var(--hair-gold);opacity:.5;pointer-events:none;
}
.hero-rings::before,.hero-rings::after{
  content:'';position:absolute;border-radius:50%;border:1px solid var(--hair-gold);
}
.hero-rings::before{inset:14%;opacity:.7}
.hero-rings::after{inset:30%;opacity:.5}

/* 涟漪：三枚同心圆错开相位，从最内圈持续向外扩散并淡出，
   给静态的同心里环一层"脉冲感"，呼应测温/校验的行业意象。
 *
 *  · 只动 transform / opacity —— 走合成层，不触发重排重绘
 *  · 纯 CSS，不依赖 JS —— motion.js / GSAP 加载失败也照常扩散
 *  · 刻意【不】挂到 .motion-ready 上：那个类表示"JS 没起来"的降级信号，
 *    不是"用户要求减少动效"，与这段动画无关
 *  · 减少动效：由文件末尾的 prefers-reduced-motion 块统一关闭
 *    （那里对全部元素设了 animation-duration:.01ms !important），此处不重复
 *
 *  起点 inset:30% = 与 ::after 那层最内圈完全重合；
 *  终点 scale(2.6)：最内圈 420px×0.4=168px，×2.6≈437px，正好越过最外圈。
 *
 *  ⚠ 已知取舍：transform 会把 1px 描边一起放大（末端约 2.6px）。
 *    所以把不透明度峰值放在前段、尾段一路衰减到 0 ——
 *    线宽变粗只发生在几乎看不见的时候，观感上察觉不到。
 *    如果以后要严格恒定线宽，得改成 SVG 圆环，不值当。
 *
 *  ⚠ 别去"修"这里的亮度关系：.hero-rings 容器本身带 opacity（移动端
 *    会再压暗一档），涟漪作为子元素会被同比例乘掉。这正是想要的 ——
 *    涟漪峰值始终约为静态三层环的 2 倍，任何断点下都只是"比静态环亮一档"，
 *    既看得见又不会喧宾夺主。单独给涟漪调高 opacity 突破不了这个乘积上限。 */
.hero-ripple{
  position:absolute;inset:30%;
  border-radius:50%;border:1px solid var(--hair-gold);
  opacity:0;                      /* 静止态不可见：动画没跑起来也不会留脏边 */
  animation:hero-ripple 4.2s var(--ease-soft) infinite;
}
/* 负延迟 = 首帧就处在不同相位，避免开头 2.8 秒"一枚枚依次亮起"的等待感 */
.hero-ripple:nth-child(1){animation-delay:-2.8s}
.hero-ripple:nth-child(2){animation-delay:-1.4s}
.hero-ripple:nth-child(3){animation-delay:0s}

@keyframes hero-ripple{
  0%  {transform:scale(1);   opacity:0}
  10% {                      opacity:.55}
  40% {                      opacity:.22}
  100%{transform:scale(2.6); opacity:0}
}

.hero .wrap{position:relative;z-index:1}
.hero-inner{max-width:640px}
.hero .h-display{margin-top:18px}
/* 逐行揭示的容器。刻意【不】使用 overflow:hidden 遮罩裁切：
   中文在 line-height 1.12 的紧行高下，字形上下缘会被遮罩切掉笔画，
   而"位移 + 淡入"同样能做出逐行层次，且永远不会裁字。 */
.hero .h-display .line{display:block}
.hero .h-display .line > span{display:block;will-change:transform,opacity}
.hero .lede{margin-top:20px}
.hero-cta{margin-top:30px;display:flex;flex-wrap:wrap;gap:12px;align-items:center}

/* 首屏严格控制在 4 个文本元素内：eyebrow / 标题 / 副文案 / CTA。
   统计条、信任背书这类内容一律下移到独立区块，不塞进首屏。 */

/* 按钮 */
.btn{display:inline-flex;align-items:center;gap:8px;height:44px;padding:0 22px;
  border-radius:var(--r-pill);font-size:14px;font-weight:700;letter-spacing:.02em;
  white-space:nowrap;cursor:pointer;
  transition:transform var(--dur-fast) var(--ease-out),
             box-shadow var(--dur-fast) var(--ease-out),
             background var(--dur-fast) var(--ease-out)}
.btn:active{transform:translateY(1px) scale(.985)}
.btn-gold{color:var(--gold-ink);
  background:linear-gradient(180deg,var(--gold-1),var(--gold-2));
  box-shadow:0 10px 26px -12px rgba(211,184,120,.6), var(--inset-hi)}
.btn-gold:hover{box-shadow:0 16px 36px -14px rgba(211,184,120,.75), var(--inset-hi)}
.btn-ghost{color:var(--w-92);background:var(--s2);border:1px solid var(--hair-2);
  box-shadow:var(--inset-hi)}
.btn-ghost:hover{background:var(--s3)}

/* ===== 9. 区块标题 ====================================================== */
.sec-head{display:flex;align-items:flex-end;gap:16px;margin-bottom:30px;flex-wrap:wrap}
.sec-head .spacer{flex:1 1 auto}
.sec-head .count{font-size:12.5px;color:var(--w-52)}

/* ===== 10. 产品网格（非对称：首件整行横排，形成目录的视觉入口） ========
 *  图片比例统一 3:4 竖构图（见 10.3 的「图片适配契约」）。
 *  产品照多为竖拍，用横构图框会被 cover 大幅放大裁切、主体被切掉。
 * ==================================================================== */
/* 12 栏栅格。
   ⚠ 这里必须是 minmax(0,1fr)，不能写成 1fr。
   裸 1fr 的最小尺寸是 auto，一旦某个格子里的内容（宽图、长型号、
   长英文单词）min-content 很宽，整列就会被撑宽、页面被顶出屏幕。
   因为 L106 有 overflow-x:hidden，这个问题不会表现为横向滚动条，
   而是"右边内容被切掉" —— 极难排查，所以从源头堵住。 */
.grid{display:grid;gap:22px;grid-template-columns:repeat(12,minmax(0,1fr))}
/* 常规卡：一行 3 张。用 12 栏是为了让首件能整行跨满而不留空洞 */
.pcard{grid-column:span 4}
/* 首件横排：图占 32% 宽，按 3:4 竖构图自然得到高度，文字列居中留白。
   图宽不能再大 —— 竖构图下 54% 宽会算出近 800px 的卡高，把目录顶下去。 */
.pcard.is-featured{grid-column:span 12;flex-direction:row;align-items:stretch}
.pcard.is-featured .pcard-img{flex:0 0 32%;aspect-ratio:3/4}
.pcard.is-featured .pcard-bd{flex:1 1 auto;justify-content:center;padding:34px 40px}
.pcard.is-featured .pcard-title{font-size:clamp(22px,2.9vw,30px);line-height:1.28}
.pcard.is-featured .pcard-model .k{font-size:11.5px}
.pcard.is-featured .pcard-model .v{font-size:17px}
.pcard.is-featured .pcard-spec{-webkit-line-clamp:3;font-size:12.5px;max-width:34em}
.pcard.is-featured .pcard-foot .go{font-size:12.5px}

.pcard{
  position:relative;display:flex;flex-direction:column;overflow:hidden;
  /* min-width:0 = 允许卡片被栅格压窄，而不是反过来把栅格撑宽。
     栅格项的最小尺寸默认是 auto（等于内容最小宽度），配上
     repeat(12,minmax(0,1fr)) 后这里再兜一道，双保险。 */
  min-width:0;
  border-radius:var(--r-card);
  background:linear-gradient(160deg, rgba(255,255,255,.062), rgba(255,255,255,.026));
  border:1px solid var(--hair);
  box-shadow:var(--lift-2), var(--inset-hi);
  /* 注意：这里刻意不写 transform 过渡。
     transform 由 motion.js 的 GSAP 逐帧写入（入场 + 指针倾斜），
     若 CSS 同时给 transform 加 transition，两者会互相打架导致迟滞。 */
  transition:border-color var(--dur-mid) var(--ease-out),
             box-shadow var(--dur-mid) var(--ease-out);
  transform-style:preserve-3d;
}
.pcard:hover{border-color:var(--hair-gold);box-shadow:var(--lift-3), var(--inset-hi)}
/* 指针跟随的柔光（由 JS 写入 --mx/--my） */
.pcard::after{
  content:'';position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  opacity:0;transition:opacity var(--dur-mid) var(--ease-soft);
  background:radial-gradient(280px circle at var(--mx,50%) var(--my,50%),
             rgba(211,184,120,.16), transparent 62%);
}
.pcard:hover::after{opacity:1}

/* ---- 图片适配契约（全站产品图统一遵守，改之前先读） --------------------
 *  目标：产品图一律按 3:4 竖向裁切显示，任何情况下都不许被拉伸变形。
 *
 *  分工：
 *    · 容器负责"定比例 + 裁切"：position+overflow:hidden + aspect-ratio:3/4
 *    · 图片负责"填满并等比裁切"：
 *        width:100% + height:100% + object-fit:cover + object-position:center
 *      → cover 先等比放大再裁掉多余部分，绝不改变长宽比
 *
 *  ⚠ 为什么必须写 object-fit：
 *      img{width:100%;height:100%} 而不写 object-fit，等于把图双向拉满。
 *      这正是"手机上图片被拉变形"的典型成因，务必保持 object-fit 在位。
 *
 *  ⚠ 老内核兜底：
 *      极少数不支持 object-fit 的老 WebView 会命中文件末尾的
 *      @supports not (object-fit:cover) 兜底块，改为按宽度等比缩放 ——
 *      宁可下方留一点容器底色，也绝不拉伸。现代浏览器完全不受该块影响。
 *
 *  ⚠ 不要为了"更保险"改成 width:auto + min-width:100% 那种 cover 模拟写法：
 *      那会让图片的固有尺寸参与父级 min-content 计算，在 repeat(12,1fr)
 *      栅格里把整列撑宽，页面被顶出屏幕（已被 overflow-x:hidden 掩盖，
 *      极难排查）。这条契约是踩过坑之后定下来的，别再改。
 * -------------------------------------------------------------------- */
.pcard-img{position:relative;overflow:hidden;background:#f4f8f6;aspect-ratio:3/4}
.pcard-img img{width:100%;height:100%;object-fit:cover;object-position:center;
  transition:transform var(--dur-slow) var(--ease-out)}
.pcard:hover .pcard-img img{transform:scale(1.045)}
/* ⚠ 入场动画期间必须关掉图片自身的 transform 过渡（别删这条）
 *
 *  背景：motion.js 的卡片入场合舞会逐帧给这张 img 写 transform
 *  （scale 1.07 → 1）。如果这里同时挂着 transition:transform，
 *  GSAP 的每一帧都会被 CSS 过渡再插值一次，两者互相打架：
 *    · 观感上：图片入场迟滞、拖尾，开头几帧被过渡吃掉
 *    · 性能上：每帧都要重启一次过渡计算并重新合成
 *
 *  .pcard 本体早就按同一道理刻意不写 transform 过渡（见上面 .pcard 的注释），
 *  这里是同一个坑，此前漏在了子元素上 —— 这正是"图片动效卡顿"的直接原因。
 *
 *  为什么用 [data-reveal="card"] 做条件：入场动画完成时 motion.js 会移除
 *  该属性（finish()），所以这条规则【天然只在入场期间生效】—— 动画一结束，
 *  hover 的 scale(1.045) 立刻恢复平滑过渡，日常观感完全不变。 */
.pcard[data-reveal="card"] .pcard-img img{transition:none}
.pcard-img .ph{position:absolute;inset:0;display:grid;place-items:center;
  font-size:11.5px;letter-spacing:.14em;color:rgba(18,48,36,.42);
  background:
    linear-gradient(150deg,#f4f8f6,#e9f1ed)}
/* 图片下缘与深色卡片之间的过渡，避免生硬切边。
   竖构图下卡片图更高，过渡带相应收窄，避免压住主体 */
.pcard-img::after{content:'';position:absolute;inset:auto 0 0;height:26%;
  background:linear-gradient(180deg,transparent,rgba(2,20,14,.42))}

/* ===== 10.4 卡片内部排版层级 ===========================================
 *  卡片是一块独立的排版单元，必须有自己的主次（否则一片文字看不出重点）。
 *  字号阶（常规卡）：产品名 18 → 型号值 15 → 参数 12 → 动作 12
 *  字号阶（首件卡）：产品名 22~30 → 型号值 17 → 参数 12.5 → 动作 12.5
 *  关键做法：型号拆成「小标签 + 大数值」，让 B2B 采购一眼认货的型号
 *  真正站在第二层级，而不是和平铺参数一个字号。
 * ==================================================================== */
.pcard-bd{padding:18px 20px 20px;display:flex;flex-direction:column;gap:9px;flex:1 1 auto}

.pcard-title{
  font-size:18px;font-weight:800;letter-spacing:.01em;line-height:1.4;color:#fff;
}

.pcard-model{display:flex;align-items:baseline;gap:7px;margin-top:1px}
/* 标签用 --w-64 而非更暗的灰：卡片底色是深绿，--w-38 实测对比度仅约 2.7:1，
   低于 WCAG AA 的 4.5:1。层级靠字号差（18/15/12）拉开，不靠牺牲可读性。 */
.pcard-model .k{font-size:11px;letter-spacing:.1em;color:var(--w-64)}
.pcard-model .v{font-size:15px;font-weight:800;letter-spacing:.02em;line-height:1.2;
  color:var(--gold-2);font-variant-numeric:tabular-nums}

.pcard-spec{margin-top:3px;font-size:12px;line-height:1.78;color:var(--w-64);
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}

.pcard-foot{margin-top:auto;padding-top:15px;display:flex;align-items:center;
  justify-content:space-between;border-top:1px solid var(--hair)}
.pcard-foot .go{font-size:12px;font-weight:700;letter-spacing:.05em;color:var(--gold-2);
  display:inline-flex;align-items:center;gap:7px}
/* 箭头用 transform 推出：gap 是布局属性，动画它会触发重排，不是合成层动画 */
.pcard-foot .go .icon{transition:transform var(--dur-fast) var(--ease-out)}
.pcard:hover .pcard-foot .go .icon{transform:translateX(4px)}

/* ===== 11. 详情页 ======================================================= */
/* 面包屑是导航文字，--w-38 在深绿底上实测仅约 2.7:1，不足以承载信息 */
.crumb{padding:24px 0 0;font-size:12.5px;color:var(--w-64)}
.crumb a{color:var(--w-64);transition:color var(--dur-fast) var(--ease-soft)}
.crumb a:hover{color:var(--gold-2)}
.crumb span[aria-hidden]{margin:0 8px;opacity:.45}

.detail{padding:26px 0 76px}
.detail-top{display:grid;grid-template-columns:minmax(0,1.08fr) minmax(0,1fr);
  gap:46px;align-items:start}

/* ===== 11.1 产品图（单图） =============================================
 *  只展示封面图，固定 3:4 竖构图。
 *
 *  图片适配契约（改之前先读第 10 节的完整说明）：
 *    · 容器定比例 3:4 + overflow:hidden，负责裁切
 *    · 图片 width:100% + height:100% + object-fit:cover + object-position:center
 *      → 等比放大后裁掉多余部分，绝不改变长宽比
 *    · 绝不出现"img 同时给了宽高却没写 object-fit"——那才是真正的双向拉伸
 *
 *  这一块刻意【不加任何入场动画】（没有 data-reveal）：
 *    图片能不能显示，不依赖 JS、不依赖滚动触发、不依赖 GSAP 是否加载成功。
 *    移动端最稳的做法就是让图片老老实实地静态渲染。
 *    （多图轮播已按需求回退：横向轨道里的懒加载在手机上不可靠，
 *      会出现"已经翻到这一张、但图还没开始下载"的空图。）
 * ====================================================================== */
.gallery-wrap{position:sticky;top:calc(var(--nav-h) + 22px)}
.gallery{border-radius:var(--r-card);overflow:hidden;
  background:linear-gradient(160deg, rgba(255,255,255,.07), rgba(255,255,255,.03));
  border:1px solid var(--hair);
  box-shadow:var(--lift-3), var(--inset-hi)}

.gal-stage{position:relative;overflow:hidden;aspect-ratio:3/4;background:#f4f8f6}
.gal-img{display:block;width:100%;height:100%;object-fit:cover;object-position:center}
.gal-stage .ph{position:absolute;inset:0;display:grid;place-items:center;
  font-size:12px;letter-spacing:.14em;color:rgba(18,48,36,.42);
  background:linear-gradient(150deg,#f4f8f6,#e9f1ed)}

/* ===== 11.2 详情页字号阶 ===============================================
 *  与产品卡同一套逻辑：一块版面必须有可读出的主次。
 *    产品名 30~42px  →  型号值 17px  →  规格值 15px
 *    →  规格标签 12px（灰）  →  长文标题 20px  →  长文正文 15px
 * ==================================================================== */
/* 产品页大标题：grid-column:1/-1 让它横跨两栏压在信息区最上面，
   所以【任何断点】下产品名都在产品图上方；窄屏单列时顺序自然变成
   产品名 → 大图 → 型号 → 规格。
   字号按"页面标题"给（不再按"信息栏第一行"给）：下限 30px 保证小屏也是大字，
   上限 42px 避免宽屏下一行太长难读。 */
.detail-title{grid-column:1/-1;
  font-size:clamp(30px,7.6vw,42px);font-weight:900;letter-spacing:.01em;
  line-height:1.18;color:#fff}

/* 型号：与产品卡一致，拆成「小标签 + 大数值」。
   型号是采购认货的第一识别号，不能和正文一样是 12.5px。 */
.detail-info .model{display:flex;align-items:baseline;gap:9px;margin-top:13px}
.detail-info .model .k{font-size:11.5px;letter-spacing:.12em;color:var(--w-64)}
.detail-info .model .v{font-size:17px;font-weight:800;letter-spacing:.02em;line-height:1.2;
  color:var(--gold-2);font-variant-numeric:tabular-nums}

/* 型号下方的次级识别参数（克重 / 长宽）：与型号同一列、同一套行结构（.model），
   但加 .is-sub 降一级视觉权重 —— 型号是采购认货的第一识别号，用金色高亮；
   这两项是补充信息，改用白色小一号，避免三个大数字互相抢注意力。
   字号/颜色可按需微调，但请保住「型号 > 克重/长宽」这个层级关系。 */
.detail-info .model.is-sub .v{font-size:15px;color:#fff}

.detail-info .rule{width:52px;height:3px;border-radius:2px;margin:24px 0;
  background:linear-gradient(90deg,var(--gold-1),var(--gold-3))}

/* 标题已经移到 .detail-top（不在信息栏内），所以信息栏的第一项
   —— 有型号时是 .model，没有型号时是 .rule —— 会带着自己的上外边距
   顶到栏顶，桌面端就会比左侧产品图低 13~24px。
   这里把首项的上外边距清零，保证信息栏与产品图顶部齐平。 */
.detail-info > :first-child{margin-top:0}

/* 规格表：原来标签与数值同为 13.5px，只靠颜色区分，读起来没有主次。
   现在标签压到 12px 灰、数值提到 15px 粗白，一眼能扫到值。
   另：标签原用 --w-38（实测约 2.7:1，低于 WCAG AA），已提到 --w-64。 */
.spec-list{list-style:none;border-top:1px solid var(--hair)}
.spec-list li{display:grid;grid-template-columns:92px minmax(0,1fr);gap:18px;
  padding:15px 2px;border-bottom:1px solid var(--hair);align-items:baseline}
.spec-list .k{font-size:12px;letter-spacing:.06em;color:var(--w-64)}
.spec-list .v{font-size:15px;font-weight:700;color:#fff;overflow-wrap:anywhere;
  font-variant-numeric:tabular-nums}

/* 长文区块：栏宽受控保证可读；标题与正文拉开 5px 差，区块边界才清楚 */
.article{margin-top:56px;padding-top:44px;border-top:1px solid var(--hair)}
.article h2{font-size:20px;font-weight:800;letter-spacing:.02em;margin-bottom:20px;color:#fff;
  display:flex;align-items:center;gap:11px}
.article h2::before{content:'';width:3.5px;height:19px;border-radius:2px;
  background:linear-gradient(180deg,var(--gold-1),var(--gold-3))}
.article-body{font-size:15px;line-height:2.05;color:var(--w-64);white-space:pre-wrap;
  overflow-wrap:anywhere;max-width:66ch}

/* ===== 11.3 相关产品（紧凑横排卡）======================================
 *  这里只需要"指路"，不需要再摆一次产品大卡：
 *  原来直接用 .pcard（220px 宽的竖版卡，含大图 + 三行文字 + 页脚按钮），
 *  一节"其他产品"占掉近 300px 高度。改为横排小卡：
 *  62px 缩略图 + 单行名称 + 型号，整条约 84px 高，信息密度反而更高。
 * ==================================================================== */
.related{margin-top:64px;padding-top:44px;border-top:1px solid var(--hair)}
.related-grid{display:grid;gap:12px;grid-template-columns:repeat(auto-fill,minmax(268px,1fr))}
/* 区块标题跟着卡片一起收小：这里是次要区块，
   用和「全部产品」同级的大标题会把紧凑卡片压得失衡 */
.related .sec-head{margin-bottom:18px}
.related .sec-head .h-section{font-size:16px}

.relcard{
  display:flex;align-items:center;gap:14px;
  padding:10px 12px;border-radius:var(--r-sm);
  background:var(--s1);border:1px solid var(--hair);
  transition:background var(--dur-fast) var(--ease-out),
             border-color var(--dur-fast) var(--ease-out);
}
.relcard:hover{background:var(--s3);border-color:var(--hair-gold)}

.relcard .thumb{width:62px;height:62px;flex:0 0 auto;overflow:hidden;
  border-radius:9px;background:#f4f8f6}
.relcard .thumb img{width:100%;height:100%;object-fit:cover;object-position:center;
  transition:transform var(--dur-mid) var(--ease-out)}
.relcard:hover .thumb img{transform:scale(1.06)}
.relcard .thumb .ph{width:100%;height:100%;display:grid;place-items:center;
  font-size:8.5px;letter-spacing:.08em;color:rgba(18,48,36,.42)}

.relcard .meta{min-width:0;flex:1 1 auto}
.relcard .name{font-size:13.5px;font-weight:700;line-height:1.42;color:#fff;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.relcard .model{display:flex;align-items:baseline;gap:6px;margin-top:5px;
  font-size:11px;letter-spacing:.08em;color:var(--w-64)}
.relcard .model b{font-size:13px;font-weight:800;letter-spacing:.02em;color:var(--gold-2);
  font-variant-numeric:tabular-nums}
.relcard .icon{flex:0 0 auto;color:var(--gold-2);opacity:.65;
  transition:transform var(--dur-fast) var(--ease-out), opacity var(--dur-fast) var(--ease-out)}
.relcard:hover .icon{transform:translateX(3px);opacity:1}

/* ===== 12. 分页 / 空态 / 骨架 =========================================== */
.emptybox{padding:78px 22px;text-align:center;color:var(--w-52);
  border-radius:var(--r-card);border:1px dashed var(--hair-2);background:var(--s1)}
.emptybox b{display:block;font-size:16.5px;color:var(--w-78);margin-bottom:7px}

.pager{display:flex;gap:7px;align-items:center;flex-wrap:wrap;justify-content:center;
  padding:44px 0 0}
.pg{display:inline-flex;align-items:center;justify-content:center;
  min-width:38px;height:38px;padding:0 13px;border-radius:var(--r-sm);
  border:1px solid var(--hair);background:var(--s1);font-size:13px;color:var(--w-64);
  transition:background var(--dur-fast) var(--ease-soft),
             border-color var(--dur-fast) var(--ease-soft),
             color var(--dur-fast) var(--ease-soft)}
.pg:hover{background:var(--s3);border-color:var(--hair-2);color:#fff}
.pg.is-on{background:linear-gradient(180deg,var(--gold-1),var(--gold-2));
  border-color:var(--gold-3);color:var(--gold-ink);font-weight:800}
.pg.is-off{opacity:.32;pointer-events:none}
.pg-sep{padding:0 5px;color:var(--w-38)}

/* ===== 13. 页脚 ========================================================= */
.sitefoot{position:relative;margin-top:12px;padding:46px 0 40px;
  background:linear-gradient(180deg,rgba(2,20,14,0),rgba(1,14,9,.85));
  border-top:1px solid var(--hair)}
.sitefoot .wrap{text-align:center}
.foot-brand{display:inline-flex;align-items:center;gap:10px;margin-bottom:14px}
.foot-line{font-size:12.5px;color:var(--w-52)}
.foot-copy{margin-top:8px;font-size:11px;letter-spacing:.08em;color:var(--w-38)}
.foot-sep{width:38px;height:2px;border-radius:2px;margin:18px auto 0;
  background:linear-gradient(90deg,transparent,var(--gold-3),transparent)}

/* ===== 14. 图片加载淡入 ================================================= */
img[data-src]{opacity:0}
img.is-loaded{opacity:1;transition:opacity var(--dur-slow) var(--ease-out)}

/* ===== 15. 动效基座 =====================================================
 *  关键安全设计：只有 .motion-ready 存在时才隐藏待入场元素。
 *  JS 未加载 / 执行失败 / 用户禁用动效 → 内容直接可见，绝不出现空白页。
 *  说明：这里只负责"藏"，不负责"动"；GSAP 到位后写入行内样式接管，
 *        行内样式的优先级高于本组规则，因此不需要 clearProps 回退。
 * ====================================================================== */
.motion-ready [data-reveal]{opacity:0;transform:translate3d(0,22px,0)}
.motion-ready [data-reveal="fade"]{transform:none}
.motion-ready [data-reveal="scale"]{transform:translate3d(0,18px,0) scale(.985)}
.motion-ready [data-reveal="card"]{opacity:0;transform:translate3d(0,30px,0) scale(.985)}
/* 首屏标题：先藏住，避免文字在错误位置闪一下 */
.motion-ready .hero .h-display .line > span{opacity:0}

/* 无 JS / 动效退出时的兜底：一律放开，保持最终态 */
.no-motion [data-reveal],
.no-motion .hero .h-display .line > span{opacity:1 !important;transform:none !important}
/* 卡片内部元素由 motion.js 写入行内起始态（标题/型号/参数/页脚的文字位移与透明），
   动效一旦退出必须连内部一起放开，否则会停在"文字透明"的中间态 */
.no-motion [data-reveal] *{
  opacity:1 !important;transform:none !important;
}

/* ===== 16. 响应式 ======================================================= */
@media (max-width:1024px){
  .pcard{grid-column:span 6}
  /* 竖构图下图片列收窄：3:4 的比例会放大高度，38% 是"还能看全文字"的上限 */
  .pcard.is-featured .pcard-img{flex:0 0 38%}
  .pcard.is-featured .pcard-bd{padding:28px 28px}
  .gallery-wrap{position:static}
}
@media (max-width:860px){
  /* 详情页窄屏：变成单列后顺序天然就是
     产品名(.detail-title 跨栏) → 大图 → 型号 → 分隔线 → 规格表。
     标题已在 .detail-top 里横跨两栏，单列时它就是第一项，
     所以这里【不需要】任何 order / display:contents 之类的取巧。 */
  .detail-top{grid-template-columns:minmax(0,1fr);gap:28px}
  .hero{padding:52px 0 44px}
  .section{padding:52px 0 60px}
  .hero-rings{opacity:.32}
  /* 首件卡在窄屏改为竖排，保持 3:4 不变 */
  .pcard.is-featured{flex-direction:column}
  .pcard.is-featured .pcard-img{flex:none;width:100%;aspect-ratio:3/4}
  /* 规格表标签列在窄屏收窄，给数值留出更多宽度 */
  .spec-list li{grid-template-columns:76px minmax(0,1fr);gap:14px}
}
@media (max-width:620px){
  :root{--nav-h:58px}
  .grid{gap:16px}
  .pcard{grid-column:span 12}
  .pcard.is-featured .pcard-title{font-size:18px}
  .pcard-bd{padding:15px 16px 17px}
  .pcard.is-featured .pcard-bd{padding:18px 17px 20px}
  .wrap{padding:0 16px}
  .article-body{font-size:14.5px}
  .article h2{font-size:18px}
  /* 相关产品在窄屏进一步收紧 */
  .related{margin-top:48px;padding-top:34px}
  .related-grid{gap:10px}
  .relcard{padding:9px 10px;gap:12px}
  .relcard .thumb{width:54px;height:54px}
  .relcard .name{font-size:13px}
}

/* ===== 17. 无障碍与偏好 ================================================= */
/* 降低动态：一次性取消所有位移与过渡，内容保持最终态 */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
  }
  [data-reveal],
  .hero .h-display .line > span{opacity:1 !important;transform:none !important}
}
/* 降低透明度：玻璃质感退化为实色，保证对比度达标 */
@media (prefers-reduced-transparency:reduce){
  .glass,.topnav{
    -webkit-backdrop-filter:none;backdrop-filter:none;
    background:rgba(3,40,27,.97);
  }
  .pcard{background:rgba(255,255,255,.07)}
}
/* 高对比：加粗发丝线，强化边界 */
@media (prefers-contrast:more){
  :root{--hair:rgba(255,255,255,.24);--hair-2:rgba(255,255,255,.34);--w-64:rgba(255,255,255,.86)}
}

/* ===== 15. 老内核图片兜底（不支持 object-fit 时）=========================
 *  现代浏览器全部走上面的 width/height:100% + object-fit:cover，
 *  本块对它们【完全不生效】（@supports 条件不成立）。
 *
 *  只有极老的 WebView（没有 object-fit）会命中这里。此时若继续沿用
 *  height:100%，图片会被双向拉满 —— 就是"手机上图片被拉变形"。
 *  所以改为 width:100% + height:auto：按图片自身比例等比缩放。
 *
 *    竖构图源图 → 正好铺满容器（产品图绝大多数是竖图）
 *    横构图源图 → 下方留一点容器底色
 *
 *  取舍很明确：宁可留一点底色，也绝不把图拉变形。
 *
 *  说明：@supports 的浏览器支持（2013 起）远早于 object-fit（2016 起），
 *        所以"不支持 object-fit 的内核"一定能正确执行这段兜底。
 * ====================================================================== */
@supports not (object-fit:cover){
  /* 支持不了 cover，就至少让图片在容器里居中，避免只裁到一边 */
  .pcard-img,
  .gal-stage,
  .relcard .thumb{
    display:flex;align-items:center;justify-content:center;
  }
  .pcard-img img,
  .gal-img,
  .relcard .thumb img{
    width:100%;height:auto;min-height:0;max-height:none;
  }
}
