/* Stratovape vape hardware site — zero-JS stylesheet
   Design goals: no external fonts, no JS dependency, stable CLS, high contrast. */

:root {
  /* 配色取自一张绯红 / 藏蓝的撞色卡片：
       绯红 #E41726（CMYK 12 97 88 0）  藏蓝 #000035（CMYK 100 100 64 51）
     两个色都是"实心平涂"性格，所以全站不靠渐变撑场面：
     藏蓝当墨色与深底，绯红只用在需要被看见的地方（链接、CTA、选中态、数字）。
     改这一组变量就能整站换肤，下面所有规则都只认变量。 */
  --crimson: #e41726;   /* 绯红：品牌色 / 强调 / 选中 */
  --crimson-ink: #b0111d; /* 绯红压深一档：hover，白底对比度 6.4:1 */
  --navy: #000035;      /* 藏蓝：墨色与深底 */
  --navy-2: #1a1a4d;    /* 藏蓝提亮一档：深底上的分隔线与次级文字 */
  --ink: #000035;
  --ink-2: #35355f;     /* 正文：白底对比度 8.6:1，比原来的 #38455a 更深更蓝 */
  --muted: #5b5b82;
  /* 边框三档，按"要不要看见"分工：
     --line    仅作分隔（表格行线、FAQ 分割、区块之间），不该抢内容
     --edge    容器外框（卡片、KPI、表格、目录框），要明确看得见
     --edge-2  容器悬停态，比 --edge 再深一档，形成可见反馈
     对白底对比度分别为 1.41 : 1 / 1.85 : 1 / 2.58 : 1（原 --line 只有 1.24） */
  /* 三档边框整体往藏蓝偏一点，白底上的对比度保持原样
     （1.41 : 1 / 1.85 : 1 / 2.58 : 1），只是色相从冷灰变成蓝灰 */
  --line: #d6d8e8;
  --line-2: #bfc3d8;
  --edge: #b9bed6;
  --edge-2: #949ac0;
  --bg: #ffffff;
  --soft: #f4f5fa;   /* 浅底也带一点蓝，和绯红放一起才不脏 */
  --soft-2: #ecedf6;
  --brand: var(--crimson);
  --brand-ink: var(--crimson-ink);
  --accent: var(--crimson);
  --accent-soft: #fdecee;
  /* 报价区专用的深红。换品牌时只改这两个值，全站 7 处 CTA 同步变。 */
  --cta: var(--crimson);
  --cta-deep: #a00f1a;
  --radius: 10px;
  --container: 1120px;
  --font: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue",
    Arial, "Noto Sans", "PingFang SC", "Microsoft YaHei", sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.7;
  color: var(--ink-2);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}

img, svg { max-width: 100%; height: auto; display: block; }

a { color: var(--brand); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { color: var(--brand-ink); }

:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
  border-radius: 3px;
}

.skip {
  position: absolute; left: -9999px; top: 0;
  background: var(--brand); color: #fff; padding: 10px 16px; z-index: 100;
}
.skip:focus { left: 8px; top: 8px; }

.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: 24px;
}

/* ---------- header ---------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(255, 255, 255, 0.94);
  backdrop-filter: saturate(1.2) blur(6px);
  border-bottom: 1px solid var(--edge);
}

.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  min-height: 68px;
}

.logo { display: flex; flex-direction: column; text-decoration: none; line-height: 1.1; }
.logo b { font-size: 20px; letter-spacing: 0.14em; color: var(--brand-ink); font-weight: 700; }
.logo span { font-size: 9px; letter-spacing: 0.18em; color: var(--muted); }

.nav { display: flex; align-items: center; gap: 4px; }
.nav a {
  padding: 8px 12px;
  font-size: 14px;
  color: var(--ink-2);
  text-decoration: none;
  border-radius: 6px;
  white-space: nowrap;
}
.nav a:hover { background: var(--soft); color: var(--brand); }
.nav a[aria-current="page"] { color: var(--brand); font-weight: 600; background: var(--soft-2); }

.lang {
  border: 1px solid var(--line-2);
  border-radius: 6px;
  padding: 6px 10px;
  font-size: 13px;
  color: var(--ink-2);
  text-decoration: none;
  white-space: nowrap;
}
.lang:hover { border-color: var(--brand); color: var(--brand); }

/* 移动端菜单用原生 <details>，不引入任何 JS */
.nav-desktop { display: flex; }
.menu { display: none; position: relative; }
.menu > summary {
  display: none;
  list-style: none;
  cursor: pointer;
  border: 1px solid var(--line-2);
  border-radius: 6px;
  padding: 8px 14px;
  font-size: 14px;
  color: var(--ink);
  user-select: none;
}
.menu > summary::-webkit-details-marker { display: none; }
.menu > summary::marker { content: ""; }

/* ---------- hero ---------- */

.hero {
  padding: 64px 0 48px;
  border-bottom: 1px solid var(--edge);
  background: linear-gradient(180deg, var(--soft) 0%, #ffffff 100%);
}
.hero-grid {
  display: grid;
  grid-template-columns: 1.15fr 0.85fr;
  gap: 48px;
  align-items: center;
}
.eyebrow {
  display: inline-block;
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
  background: var(--accent-soft);
  border-radius: 999px;
  padding: 4px 12px;
  margin-bottom: 18px;
}
h1 {
  font-size: clamp(1.85rem, 3.6vw, 2.7rem);
  line-height: 1.2;
  letter-spacing: -0.015em;
  color: var(--ink);
  margin: 0 0 18px;
  font-weight: 700;
}
.lede { font-size: 1.06rem; color: var(--ink-2); margin: 0 0 26px; max-width: 62ch; }

.cta-row { display: flex; flex-wrap: wrap; gap: 12px; }

/* ---------- 首屏背景板：六张产品图，每 3 秒换一张 ----------

   图片由 _build/make_hero.py 合成：宽 1680、高 700，左侧已经是白色渐隐，
   设备在右侧 68%~97% 的位置。所以这里不需要额外的模糊或遮罩去救可读性，
   只在正文那一列再压一层很轻的白，防止窄屏时渐变边缘顶到字。

   排期（一个循环 18 秒 = 6 张 × 3 秒）：
     每张 0–0.6s 淡入 → 0.6–3.0s 常亮 → 3.0–3.6s 淡出，
     下一张正好在第 3.0s 开始淡入，两张透明度之和始终为 1，
     底下的近白色不会透上来，也不会"闪一下白"。
   六张的 animation-delay 依次相差 3 秒，首张用 -1.2s 让打开页面时已经亮着。
                              */

.hero-media {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}

.hero-media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* 靠右对齐：首屏高度会随标题换行变化，cover 的缩放比也跟着变。
     若按中心对齐，同一张图在英文页和中文页会横向漂移几十像素，
     设备一会儿在卡右边、一会儿整支躲到卡后面。贴住右边缘就稳定了。 */
  object-position: 100% 50%;
  opacity: 0;
  /* 设备本身画到比画布还高，上下都被裁掉一截，
     这样它"穿过"整个首屏，而不是缩在中间被信息卡拦腰截断。 */
  transform: scale(1.01);
  animation: hero-plate 18s linear infinite;
}

/* 负延迟让第一张在打开页面时就已经亮着；六张依次错开 3 秒，循环接缝不变。 */
.hero-media img:nth-of-type(1) { animation-delay: -1.2s; }
.hero-media img:nth-of-type(2) { animation-delay: 1.8s; }
.hero-media img:nth-of-type(3) { animation-delay: 4.8s; }
.hero-media img:nth-of-type(4) { animation-delay: 7.8s; }
.hero-media img:nth-of-type(5) { animation-delay: 10.8s; }
.hero-media img:nth-of-type(6) { animation-delay: 13.8s; }

@keyframes hero-plate {
  0%      { opacity: 0; }
  3.333%  { opacity: 1; }   /* 0.6s 淡入完成 */
  16.667% { opacity: 1; }   /* 3.0s 常亮结束 */
  20%     { opacity: 0; }   /* 3.6s 淡出完成，下一张同时淡入 */
  100%    { opacity: 0; }
}

/* 正文一侧再压一道白，只在 56% 以前起作用，设备那一侧保持干净 */
.hero-media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg,
    rgba(255, 255, 255, 0.55) 0%,
    rgba(255, 255, 255, 0.40) 34%,
    rgba(255, 255, 255, 0.10) 56%,
    rgba(255, 255, 255, 0) 72%);
}

/* 背景板在动，右侧信息卡改成磨砂玻璃：
   设备从卡片背后透出来，但不影响卡里 13~14px 的表字。 */
.hero .fact-box {
  background: rgba(255, 255, 255, 0.93);
  border-color: rgba(255, 255, 255, 0.95);
  box-shadow: 0 26px 54px -38px rgba(9, 32, 46, 0.6);
  -webkit-backdrop-filter: blur(30px) saturate(1.04);
  backdrop-filter: blur(30px) saturate(1.04);
}

/* 不支持 backdrop-filter 时退回接近实心，别让卡片变成半透明的糊块 */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .hero .fact-box { background: rgba(255, 255, 255, 0.95); }
}

/* 暂停开关：自动播放的轮播必须能停（WCAG 2.2.2），沿用下面 showcase 的写法 */
.hero-stop {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.hero-stop-btn {
  position: absolute;
  right: 66px;
  bottom: 26px;
  z-index: 2;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  /* 白底而不是深色半透明：按钮大概率落在设备那一侧，
     深色叠在紫色机身上看不清；白底与"回到顶部"是同一套按钮语言。 */
  background: rgba(255, 255, 255, 0.92);
  border: 1px solid var(--line-2);
  box-shadow: 0 2px 8px -4px rgba(9, 32, 46, 0.4);
  cursor: pointer;
  opacity: 0.55;
  transition: opacity 0.15s, background 0.15s;
}
.hero-stop-btn:hover { opacity: 1; background: #fff; }
.hero-stop:focus-visible + .hero-stop-btn {
  opacity: 1;
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}
/* 暂停图标：两条竖线 */
.hero-stop-btn::before {
  content: "";
  position: absolute;
  inset: 7px 6px;
  background: linear-gradient(to right, var(--brand) 0 3px, transparent 3px 6px, var(--brand) 6px 9px);
}
/* 勾上以后变成播放三角 */
.hero-stop:checked ~ .hero-stop-btn::before {
  inset: 6px 5px 6px 8px;
  background: none;
  border-left: 7px solid var(--brand);
  border-top: 4.5px solid transparent;
  border-bottom: 4.5px solid transparent;
}
.hero-stop:checked ~ .hero-media img { animation-play-state: paused; }

.btn {
  display: inline-block;
  position: relative;
  overflow: hidden;
  padding: 12px 20px;
  border-radius: 8px;
  font-size: 15px;
  font-weight: 600;
  text-decoration: none;
  border: 1px solid transparent;
  transition: background-color 0.15s ease, transform 0.12s ease, box-shadow 0.2s ease;
}

/* 主按钮：一块绯红从左扫到右盖满。
   用伪元素做填充而不是直接换 background-color，是因为"扫过"比"变深"
   更像一次操作被接受了；也让白字在扫过的瞬间始终压在纯色上，不会闪。 */
.btn-primary { background: var(--brand); color: #fff; }
.btn-primary::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--brand-ink);
  transform: translateX(-101%);
  transition: transform 0.34s cubic-bezier(0.4, 0, 0.2, 1);
}
.btn-primary:hover::before,
.btn-primary:focus-visible::before { transform: translateX(0); }
.btn-primary > * { position: relative; }

/* 次按钮：底色不动，绯红从下往上长出来，边框同步转绯红 */
.btn-ghost { background: #fff; color: var(--brand); border-color: var(--line-2); }
.btn-ghost::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--accent-soft);
  transform: translateY(101%);
  transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.btn-ghost:hover::before,
.btn-ghost:focus-visible::before { transform: translateY(0); }
.btn-ghost:hover { border-color: var(--brand); }
.btn-ghost > * { position: relative; }

/* 按下：整颗按钮下沉 1px 并收一点阴影。
   没有这个反馈的话，点击在触屏上"没有落点"，尤其深色按钮上更明显。 */
.btn:active { transform: translateY(1px); box-shadow: none; }
.btn-primary:active { box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.22); }

.fact-box {
  background: #fff;
  border: 1px solid var(--edge);
  border-radius: var(--radius);
  padding: 22px 24px;
}
.fact-box h2 { font-size: 13px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); margin: 0 0 14px; font-weight: 600; }
.fact-box dl { margin: 0; display: grid; grid-template-columns: auto 1fr; gap: 8px 16px; font-size: 14px; }
.fact-box dt { color: var(--muted); }
.fact-box dd { margin: 0; color: var(--ink); font-weight: 600; }

/* ---------- sections ---------- */

section { padding: 56px 0; }
section + section { border-top: 1px solid var(--line); }
.section-head { max-width: 74ch; margin-bottom: 32px; }
h2 {
  font-size: clamp(1.35rem, 2.4vw, 1.75rem);
  line-height: 1.3;
  color: var(--ink);
  margin: 0 0 12px;
  font-weight: 700;
  letter-spacing: -0.01em;
}
h3 { font-size: 1.08rem; color: var(--ink); margin: 0 0 8px; font-weight: 600; }
h4 { font-size: 0.98rem; color: var(--ink); margin: 0 0 6px; font-weight: 600; }

/* ---------- 更新时间与署名 ---------- */
/* AI 摘要偏好带时间戳的事实：日期必须可见，且与 JSON-LD 的 dateModified 一致 */
.updated {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 20px;
  margin: 14px 0 0;
  font-size: 0.8rem;
  line-height: 1.5;
  color: var(--muted);
}
.updated span { display: inline-flex; flex-wrap: wrap; gap: 5px; }
.updated time { font-variant-numeric: tabular-nums; }
.updated a { color: var(--ink-2); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 2px; }
.updated a:hover { color: var(--accent); }
.updated + .answer,
.updated + .lede { margin-top: 16px; }

.answer {
  border-left: 3px solid var(--accent);
  padding: 2px 0 2px 16px;
  margin: 0 0 20px;
  font-size: 1.02rem;
  color: var(--ink);
  max-width: 78ch;
}

p { margin: 0 0 16px; }
ul, ol { margin: 0 0 18px; padding-left: 22px; }
li { margin-bottom: 8px; }
small, .small { font-size: 13px; color: var(--muted); }

/* ---------- cards ---------- */

.grid { display: grid; gap: 20px; }
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }

.card {
  background: #fff;
  border: 1px solid var(--edge);
  border-radius: var(--radius);
  padding: 22px;
  display: flex;
  flex-direction: column;
}
.card h3 { margin-bottom: 6px; }
/* 卡片标题在小屏/索引页用 h2 表达层级时，视觉仍按 h3 显示，层级是给机器看的 */
.card h2 { font-size: 1.08rem; font-weight: 600; letter-spacing: 0; margin: 0 0 6px; }
.card p:last-child { margin-bottom: 0; }
.card .meta { font-size: 12px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--accent); margin-bottom: 8px; }

.thumb img { width: 100%; height: 100%; object-fit: contain; }

.product-card { transition: border-color 0.15s ease; }
.product-card:hover { border-color: var(--edge-2); }
.product-card .spec-row { display: flex; gap: 18px; margin: 12px 0 16px; font-size: 13px; color: var(--muted); }
.product-card .spec-row b { display: block; font-size: 18px; color: var(--ink); font-weight: 700; }
.product-card a.more { margin-top: auto; font-size: 14px; font-weight: 600; }

.thumb {
  background: var(--soft);
  border-radius: 8px;
  margin-bottom: 16px;
  /* 产品图全是 3:4 竖图：容器 16:9 时 contain 之后左右大片留白，
     产品缩成中间一小条，整排看就是"高低不齐、排版歪"。改成同比例。 */
  aspect-ratio: 3 / 4;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

/* ---------- tables ---------- */

.table-wrap { overflow-x: auto; border: 1px solid var(--edge); border-radius: var(--radius); margin-bottom: 18px; }
table { width: 100%; border-collapse: collapse; font-size: 14px; background: #fff; }
caption {
  caption-side: top;
  text-align: left;
  padding: 14px 16px 10px;
  font-size: 13px;
  color: var(--muted);
}
th, td { text-align: left; padding: 11px 16px; border-bottom: 1px solid var(--line); vertical-align: top; }
/* 表头与数据之间是本页最重要的一条分界，比行线深一档，避免视线串行 */
thead th { background: var(--soft); color: var(--ink); font-weight: 600; font-size: 13px; white-space: nowrap; border-bottom: 1px solid var(--edge); }
tbody tr:last-child td { border-bottom: 0; }
tbody tr:nth-child(even) { background: #fcfdfe; }
td.num, th.num { font-variant-numeric: tabular-nums; }

.spec-table td:first-child { width: 42%; color: var(--muted); }

/* ---------- callout ---------- */

.callout {
  background: var(--soft);
  border: 1px solid var(--edge);
  border-left: 3px solid var(--brand);
  border-radius: 8px;
  padding: 18px 22px;
  margin: 0 0 20px;
}
.callout.warn { border-left-color: var(--accent); background: var(--accent-soft); }
.callout p:last-child { margin-bottom: 0; }
.callout strong { color: var(--ink); }

/* ---------- faq ---------- */

.faq-item { border-bottom: 1px solid var(--edge); padding: 22px 0; }
.faq-item:first-of-type { border-top: 1px solid var(--edge); }
.faq-item h3,
.faq-item h2 { font-size: 1.02rem; font-weight: 600; letter-spacing: 0; margin: 0 0 8px; }
.faq-item p { margin: 0; color: var(--ink-2); }

/* ---------- footer ---------- */

.site-footer {
  background: var(--brand-ink);
  color: #c6d4e0;
  padding: 52px 0 28px;
  margin-top: 0;
  font-size: 14px;
}
.site-footer a { color: #dbe7f1; text-decoration: none; }
.site-footer a:hover { color: #fff; text-decoration: underline; }
.site-footer h2 { color: #fff; font-size: 13px; letter-spacing: 0.1em; text-transform: uppercase; margin: 0 0 14px; }
.footer-grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1.2fr; gap: 32px; }
.footer-grid ul { list-style: none; margin: 0; padding: 0; }
.footer-grid li { margin-bottom: 8px; }
.footer-legal {
  border-top: 1px solid rgba(255, 255, 255, 0.14);
  margin-top: 36px;
  padding-top: 20px;
  display: flex;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  font-size: 12.5px;
  color: #9fb3c6;
}
.footer-logo b { color: #fff; font-size: 18px; letter-spacing: 0.14em; }

/* ---------- breadcrumb ---------- */

.crumbs { font-size: 13px; color: var(--muted); padding: 18px 0 0; }
.crumbs ol { list-style: none; display: flex; flex-wrap: wrap; gap: 8px; margin: 0; padding: 0; }
.crumbs li + li::before { content: "/"; margin-right: 8px; color: var(--line-2); }

/* ---------- misc ---------- */

.page-head { padding: 40px 0 8px; }
.page-head h1 { font-size: clamp(1.7rem, 3vw, 2.3rem); margin-bottom: 12px; }
.kpi-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; margin: 26px 0 0; }
.kpi { border: 1px solid var(--edge); border-radius: var(--radius); padding: 18px 20px; background: #fff; }
.kpi b { display: block; font-size: 1.5rem; color: var(--ink); font-variant-numeric: tabular-nums; }
.kpi span { font-size: 13px; color: var(--muted); }

.steps { counter-reset: s; list-style: none; padding: 0; }
.steps > li {
  counter-increment: s;
  position: relative;
  padding-left: 44px;
  margin-bottom: 24px;
}
.steps > li::before {
  content: counter(s);
  position: absolute;
  left: 0; top: 2px;
  width: 28px; height: 28px;
  border-radius: 50%;
  background: var(--brand);
  color: #fff;
  font-size: 13px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}

.formula {
  font-family: var(--mono);
  font-size: 14px;
  background: var(--soft-2);
  border-radius: 8px;
  padding: 16px 18px;
  margin: 0 0 18px;
  overflow-x: auto;
  color: var(--brand-ink);
}

.toc { background: var(--soft); border: 1px solid var(--edge); border-radius: var(--radius); padding: 18px 22px; margin-bottom: 28px; }
.toc h2 { font-size: 13px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); margin-bottom: 10px; }
.toc ol { margin: 0; padding-left: 20px; font-size: 14px; }

.cta-band {
  /* 全站唯一的强对比色块。深蓝是信任色，用来铺整页；
     报价区要抢住视线，所以单独给一套红，且只在这一块出现，不污染其它组件。 */
  background: linear-gradient(135deg, var(--cta) 0%, var(--cta-deep) 100%);
  border-radius: var(--radius);
  padding: 34px;
  text-align: center;
  color: #fff;
  box-shadow: 0 20px 44px -34px var(--cta-deep);
}
.cta-band h2 { margin-bottom: 10px; color: #fff; }
.cta-band p { max-width: 62ch; margin-inline: auto; color: rgba(255, 255, 255, 0.88); }

/* 红底上的按钮：主按钮反白（白底红字），次按钮改描边，
   沿用原来的深蓝实心按钮会和红底打架，对比度也不够。 */
.cta-band .btn-primary { background: #fff; color: var(--cta-deep); border-color: #fff; }
.cta-band .btn-primary:hover { background: #f7ecee; border-color: #f7ecee; color: var(--cta-deep); }
.cta-band .btn-ghost {
  background: transparent;
  color: #fff;
  border-color: rgba(255, 255, 255, 0.6);
}
.cta-band .btn-ghost:hover {
  background: rgba(255, 255, 255, 0.14);
  border-color: #fff;
  color: #fff;
}
.cta-band a:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }

/* 窄屏下按钮改等宽撑满：两个按钮一长一短会显得没对齐 */
@media (max-width: 560px) {
  .cta-band .cta-row { flex-direction: column; align-items: stretch; }
  .cta-band .btn { text-align: center; }
}

/* ---------- responsive ---------- */

@media (max-width: 980px) {
  .hero-grid { grid-template-columns: 1fr; gap: 32px; }
  .grid-4, .grid-3 { grid-template-columns: repeat(2, 1fr); }
  .footer-grid { grid-template-columns: 1fr 1fr; }
  /* 这个断点起首屏变单列。全屏铺底的产品背景板若还留着，
     设备会直接压在标题、介绍段和公司信息卡上（用户看到的"重叠"），
     所以在改单列的同一断点就关掉背景板，而不是等到 760px。 */
  .hero-media, .hero-stop-btn { display: none; }
}

@media (max-width: 760px) {
  body { font-size: 15.5px; }
  .hero { padding: 40px 0 36px; }
  section { padding: 40px 0; }
  .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; }
  .kpi-row { grid-template-columns: 1fr; }

  .nav-desktop { display: none; }
  .menu { display: block; }
  .menu > summary { display: inline-block; }
  .menu .nav {
    display: none;
    position: absolute;
    left: 0; right: 0; top: calc(100% + 10px);
    background: #fff;
    border: 1px solid var(--edge);
    border-radius: var(--radius);
    flex-direction: column;
    align-items: stretch;
    padding: 8px;
    gap: 2px;
    box-shadow: 0 10px 24px rgba(14, 22, 33, 0.08);
  }
  .menu[open] .nav { display: flex; }
  .nav a { padding: 12px; }

  .footer-grid { grid-template-columns: 1fr; }
  .cta-band { padding: 26px 20px; }

  /* 窄屏直接关掉背景板。首屏变成一列后，图会被放大到只剩一条竖切片，
     设备的 BRAND 字样会从按钮后面透出来，像渲染坏了；
     而要压住它就得把白加到 0.9 以上，那时图也等于没有了。
     手机端省下这 3 张图，首屏回到纯渐变，反而更干净。 */
  .hero-media, .hero-stop-btn { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { transition: none !important; }

  /* 关掉轮播就只剩第一张，其余两张必须显式藏掉，否则会全空 */
  .hero-media img { animation: none; }
  .hero-media img:nth-of-type(n + 2) { display: none; }
  .hero-media img:nth-of-type(1) { opacity: 1; }
  .hero-stop-btn { display: none; }
}

@media print {
  .site-header, .site-footer, .cta-row, .cta-band { display: none; }
  .hero-media, .hero-stop-btn { display: none; }
  body { font-size: 12pt; }
}

.fact-list {
  display: grid;
  grid-template-columns: minmax(120px, 34%) 1fr;
  gap: 9px 18px;
  margin: 0 0 22px;
  font-size: 14px;
  border-top: 1px solid var(--line);
  padding-top: 16px;
}
.fact-list dt { color: var(--muted); }
.fact-list dd { margin: 0; color: var(--ink); }

.cta-band .cta-row { justify-content: center; margin-top: 20px; }

@media (max-width: 520px) {
  .fact-list { grid-template-columns: 1fr; gap: 2px; }
  .fact-list dd { margin-bottom: 10px; }
}

/* ---------------------------------------------------------------------------
   询盘表单
   --------------------------------------------------------------------------- */
.nav a.nav-cta {
  background: var(--brand);
  color: #fff;
  border-radius: 6px;
  padding: 8px 14px;
  font-weight: 600;
  margin-left: 6px;
}
.nav a.nav-cta:hover { background: var(--brand-ink); color: #fff; }

.narrow { max-width: 760px; }

.form-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(280px, 1fr);
  gap: 40px;
  align-items: start;
}

.inquiry-form fieldset {
  border: 0;
  padding: 0;
  margin: 0 0 26px;
  min-width: 0;
}
.inquiry-form legend {
  font-size: 12px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--accent);
  font-weight: 700;
  padding: 0;
  margin-bottom: 14px;
}
.field { margin-bottom: 14px; min-width: 0; }
.field-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}
.field label {
  display: block;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
  margin-bottom: 6px;
}
.field .req { color: var(--accent); }
.field input,
.field select,
.field textarea {
  width: 100%;
  font-family: inherit;
  font-size: 15px;
  color: var(--ink);
  background: #fff;
  border: 1px solid var(--edge-2);
  border-radius: 8px;
  padding: 10px 12px;
  line-height: 1.5;
}
.field textarea { resize: vertical; min-height: 120px; }
.field select { appearance: none; background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%), linear-gradient(135deg, var(--muted) 50%, transparent 50%); background-position: calc(100% - 18px) 18px, calc(100% - 13px) 18px; background-size: 5px 5px, 5px 5px; background-repeat: no-repeat; padding-right: 36px; }
.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: 2px solid var(--brand);
  outline-offset: 1px;
  border-color: var(--brand);
}
.field-hint { font-size: 12.5px; color: var(--muted); margin: 6px 0 0; }
.field-error {
  display: block;
  font-size: 12.5px;
  color: #b3261e;
  margin-top: 5px;
}
.field.has-error input,
.field.has-error select,
.field.has-error textarea { border-color: #d94a3f; }

.consent {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  font-size: 13.5px;
  color: var(--ink-2);
  padding: 14px 16px;
  background: var(--soft);
  border: 1px solid var(--edge);
  border-radius: 8px;
  margin-bottom: 20px;
}
.consent input { margin-top: 3px; width: 17px; height: 17px; accent-color: var(--brand); flex: none; }
.consent label { margin: 0; font-weight: 400; cursor: pointer; }

.form-actions { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.form-actions .btn { font-size: 15px; padding: 12px 26px; }
.form-actions .btn[disabled] { opacity: 0.6; cursor: progress; }
.form-note { font-size: 13px; color: var(--muted); }

.form-status { display: none; }
.form-status.show { display: block; }
.form-status .callout { margin-bottom: 20px; }

.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.form-aside .card { margin-bottom: 16px; }
.aside-title {
  font-size: 13px;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 12px;
  font-weight: 600;
}
.steps { margin: 0; padding-left: 20px; font-size: 14px; }
.steps li { margin-bottom: 10px; }
.steps li:last-child { margin-bottom: 0; }
ul.tight { margin: 0; padding-left: 20px; font-size: 14px; }
ul.tight li { margin-bottom: 6px; }

.form-success {
  border: 1px solid #c9e4d2;
  background: #f3faf5;
  border-radius: 10px;
  padding: 28px 26px;
}
.form-success h2 { margin-top: 0; }
.form-success p:last-child { margin-bottom: 0; }

@media (max-width: 980px) {
  .form-grid { grid-template-columns: 1fr; gap: 28px; }
}
@media (max-width: 620px) {
  .field-row { grid-template-columns: 1fr; gap: 0; }
  .field-row .field { margin-bottom: 14px; }
}

/* ============================================================================
   容器立体感 —— 让 1px 边框"立起来"
   ----------------------------------------------------------------------------
   只有边框没有阴影，浅灰线在白底上仍然是平的；加一层极轻的外投影，边界
   就有了厚度感。阴影不占布局，CLS 保持 0，也不影响任何文字对比度。

   故意写得很淡（alpha 0.06）：这是给边框做配重，不是给卡片做浮层。
   再重就会变成"卡片飘在页面上的 SaaS 风"，与工业品的克制感相反。
   ============================================================================ */

.card,
.kpi,
.fact-box,
.table-wrap,
.toc {
  box-shadow: 0 1px 2px rgba(10, 46, 70, 0.06);
}

/* ============================================================================
   动效与互动层 —— 纯 CSS，零 JS
   ----------------------------------------------------------------------------
   三条硬约束，任何一条破了就不要合进来：

   1. 默认可见。所有内容在没有任何动画的情况下都是完整可见的：不使用
      「opacity:0 起手 + 等 JS 触发」这种写法。动画只是锦上添花，
      @supports 不支持就整段不生效，页面退回静态但完全可读。
   2. 不碰 DOM。不加节点、不改文本、不依赖脚本。AI 爬虫（GPTBot / ClaudeBot /
      PerplexityBot / Google-Extended）取的是 HTML 文本，本层改动为零影响。
   3. 只动 transform / opacity。不触发重排，CLS 保持 0，滚动不掉帧。

   关闭方式：系统「减少动态效果」会自动全关；要彻底去掉，删掉本段即可。
   ============================================================================ */

:root {
  /* 滚动渐显的起始透明度。改成 1 就只保留位移、完全不做淡入（更保守的观感）。 */
  --hyh-reveal-from: 0;
}

/* ---------- 1. 滚动进度条（页面顶部 3px） ---------- */

@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    body::after {
      content: "";
      position: fixed;
      inset: 0 0 auto 0;
      height: 3px;
      z-index: 60;
      transform: scaleX(0);
      transform-origin: 0 50%;
      background: linear-gradient(90deg, var(--brand) 0%, var(--accent) 100%);
      animation: hyh-progress linear both;
      animation-timeline: scroll(root block);
      pointer-events: none;
    }
  }
}

@keyframes hyh-progress {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

/* ---------- 2. 吸顶导航：滚动后压一道阴影 ---------- */

@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    .site-header {
      animation: hyh-header linear both;
      animation-timeline: scroll(root block);
      animation-range: 0 140px;
    }
  }
}

@keyframes hyh-header {
  from { box-shadow: 0 0 0 0 rgba(10, 46, 70, 0); }
  to   { box-shadow: 0 10px 26px -20px rgba(10, 46, 70, 0.55); }
}

/* ---------- 3. 首屏氛围：两团光斑极缓漂移（装饰层，不承载任何文字） ---------- */

.hero { position: relative; overflow: hidden; }
.hero > .container { position: relative; z-index: 1; }

.hero::before {
  content: "";
  position: absolute;
  inset: -35% -12% auto -12%;
  height: 150%;
  background:
    radial-gradient(38% 52% at 16% 32%, rgba(16, 69, 107, 0.10), transparent 70%),
    radial-gradient(32% 44% at 84% 16%, rgba(180, 98, 26, 0.09), transparent 72%);
  pointer-events: none;
  z-index: 0;
}

@media (prefers-reduced-motion: no-preference) {
  .hero::before { animation: hyh-drift 30s ease-in-out infinite alternate; }
}

@keyframes hyh-drift {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(-2.2%, 1.6%, 0) scale(1.05); }
}

/* ---------- 4. 滚动渐显：区块标题、卡片、FAQ、表格、KPI ---------- */

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .section-head,
    .card,
    .faq-item,
    .table-wrap,
    .kpi,
    .callout {
      animation: hyh-rise linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 52%;
    }

    /* 同行卡片错开一点点，避免整排同时跳出来 */
    .grid > .card:nth-child(2) { animation-range: entry 4% entry 56%; }
    .grid > .card:nth-child(3) { animation-range: entry 8% entry 60%; }
    .grid > .card:nth-child(4) { animation-range: entry 12% entry 64%; }
    .kpi-row > .kpi:nth-child(2) { animation-range: entry 5% entry 57%; }
    .kpi-row > .kpi:nth-child(3) { animation-range: entry 10% entry 62%; }
  }
}

@keyframes hyh-rise {
  from { opacity: var(--hyh-reveal-from, 0); transform: translateY(20px) scale(0.994); }
  to   { opacity: 1; transform: none; }
}

/* ---------- 5. 指针悬停的互动（触屏不触发） ---------- */

@media (hover: hover) and (pointer: fine) {
  .card,
  .kpi,
  .table-wrap {
    transition: translate 0.28s cubic-bezier(0.22, 0.61, 0.36, 1),
                box-shadow 0.28s ease,
                border-color 0.28s ease;
  }

  /* 注意：这里用独立的 translate 属性，不用 transform。
     滚动渐显动画会以 fill: both 把 transform 钉在 none 上，
     若 hover 也写 transform，抬升效果会被动画值压掉（悬停只有阴影没有位移）。 */
  .card:hover {
    translate: 0 -3px;
    border-color: var(--edge-2);
    box-shadow: 0 16px 34px -26px rgba(10, 46, 70, 0.6);
  }

  .kpi:hover {
    translate: 0 -2px;
    border-color: var(--edge-2);
    box-shadow: 0 12px 26px -22px rgba(10, 46, 70, 0.55);
  }

  /* 卡片里的组件缩略图轻微推近，卡片整体没动图也不会糊 */
  .card .thumb svg,
  .card .thumb img {
    transition: transform 0.5s cubic-bezier(0.22, 0.61, 0.36, 1);
  }
  .card:hover .thumb svg,
  .card:hover .thumb img { transform: scale(1.035); }

  /* 卡片内「查看更多」箭头右移，替代整块变色 */
  .card a.more { transition: color 0.18s ease; }

  .btn {
    transition: background-color 0.16s ease, border-color 0.16s ease,
                transform 0.16s ease, box-shadow 0.22s ease;
  }
  .btn:hover { transform: translateY(-1px); }
  .btn:active { transform: translateY(0); }
  .btn-primary:hover { box-shadow: 0 10px 20px -12px rgba(10, 46, 70, 0.75); }
  .btn-ghost:hover { box-shadow: 0 8px 18px -14px rgba(10, 46, 70, 0.45); }

  tbody tr { transition: background-color 0.14s ease; }
  tbody tr:hover { background: #f3f8fd; }

  .nav a { transition: background-color 0.14s ease, color 0.14s ease; }
  .site-footer a { transition: color 0.14s ease; }

  .lang { transition: border-color 0.16s ease, color 0.16s ease; }
}

/* ---------- 6. 锚点跳转后目标块闪一下，让人知道落在哪 ---------- */

@keyframes hyh-target {
  0%   { box-shadow: 0 0 0 0 rgba(180, 98, 26, 0.34); }
  70%  { box-shadow: 0 0 0 10px rgba(180, 98, 26, 0); }
  100% { box-shadow: 0 0 0 0 rgba(180, 98, 26, 0); }
}

@media (prefers-reduced-motion: no-preference) {
  :target { animation: hyh-target 1.1s ease-out 1; }
}

/* ---------- 7. 滚动联动：首屏视差、下滑提示、页脚升起 ---------- */

/* 7.1 首屏视差
   内容层不下移，只让它「比页面走得慢一点」并轻微收小、变淡，
   与后面的静态背景拉开纵深。滚到 520px 时首屏已基本离开视口，不会看到突兀的退场。 */

@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    .hero > .container {
      animation: hyh-hero-par linear both;
      animation-timeline: scroll(root block);
      animation-range: 0 520px;
    }
  }
}

@keyframes hyh-hero-par {
  /* 只做位移，不压透明度：超长屏幕上首屏可能还留在视口里，
     内容一旦变淡就会被误当成「页面坏了」。 */
  from { transform: none; }
  to   { transform: translateY(-26px) scale(0.99); }
}

/* 7.2 下滑提示：首屏右下角一个鼠标轮廓，滚动即淡出
   纯装饰，不含任何文字，不占正文，屏幕阅读器和爬虫都读不到（content 里的伪元素）。 */

.hero::after {
  content: "";
  position: absolute;
  right: 30px;
  bottom: 22px;
  width: 20px;
  height: 32px;
  border: 1.5px solid var(--line-2);
  border-radius: 11px;
  /* 第二层半透明白底：首屏现在有产品图，下滑提示可能正好压在机身上，
    只描边的话在深色区域等于消失；白底在浅色区域又看不出来，不影响原观感。 */
  background:
    linear-gradient(var(--brand), var(--brand)) center 7px / 2px 7px no-repeat,
    rgba(255, 255, 255, 0.78);
  opacity: 0.55;
  pointer-events: none;
  z-index: 0;
}

@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    .hero::after {
      animation: hyh-cue-out linear both;
      animation-timeline: scroll(root block);
      animation-range: 30px 240px;
    }
  }
}

@keyframes hyh-cue-out {
  from { opacity: 0.55; transform: none; }
  to   { opacity: 0; transform: translateY(10px); }
}

/* 窄屏首屏铺满整宽，这个提示会压到内容，直接不显示 */
@media (max-width: 1100px) {
  .hero::after { display: none; }
}

/* ---------- 8. 回到顶部按钮 ---------- */

/* 默认状态就是「可见可点」。不支持滚动驱动动画的浏览器（如 Firefox）
   直接看到按钮，功能不受影响；支持的浏览器才做「往下滑才浮出来」。
   这里不能用「默认 opacity:0 + 等脚本/类名」的做法——那会让无 CSS 能力的环境拿不到入口。 */

.to-top {
  position: fixed;
  right: 22px;
  bottom: 22px;
  z-index: 55;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  border: 1px solid var(--line-2);
  background: rgba(255, 255, 255, 0.94);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  color: var(--brand);
  font-size: 17px;
  line-height: 1;
  text-decoration: none;
  box-shadow: 0 10px 26px -16px rgba(10, 46, 70, 0.65);
  transition: background-color 0.18s ease, border-color 0.18s ease,
              color 0.18s ease, box-shadow 0.22s ease,
              translate 0.22s ease;
}

.to-top:hover {
  background: var(--brand);
  border-color: var(--brand);
  color: #fff;
  translate: 0 -2px;
  box-shadow: 0 14px 30px -16px rgba(10, 46, 70, 0.8);
}

.to-top:active { translate: 0 0; }

.to-top:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    .to-top {
      animation: hyh-to-top linear both;
      animation-timeline: scroll(root block);
      animation-range: 200px 420px;
    }
  }
}

@keyframes hyh-to-top {
  from { opacity: 0; visibility: hidden; transform: translateY(10px) scale(0.9); }
  to   { opacity: 1; visibility: visible; transform: none; }
}

@media (max-width: 600px) {
  .to-top {
    right: 14px;
    /* 加安全区，避开 iPhone 底部横条 */
    bottom: calc(14px + env(safe-area-inset-bottom, 0px));
    width: 40px;
    height: 40px;
    font-size: 15px;
  }
}

/* 跳转目标锚点：零尺寸，不占布局，只为让 #top 有个可滚动的落点 */
.anchor-top {
  display: block;
  height: 0;
  overflow: hidden;
}

/* ---------- 9. 收尾：尊重系统设置、打印时清场 ---------- */

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

@media print {
  body::after,
  .hero::before,
  .hero::after,
  .to-top { display: none !important; }
  *,
  *::before,
  *::after {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
    box-shadow: none !important;
  }
}

/* ==========================================================================
   Stratovape theme layer
   底子是同一套骨架样式，这里只换品牌色、补上本目录新增的组件。
   放在文件末尾，靠层叠覆盖骨架样式里的默认值。
   ========================================================================== */

:root {
  --brand: var(--crimson);
  --brand-ink: var(--crimson-ink);
  --accent: var(--crimson);
  --accent-soft: #fdecee;
  --cta: var(--crimson);
  --cta-deep: #a00f1a;
}

/* 产品卡：竖版设备，16:9 会把笔型机压成一条线，改成 4:5 */
.product-card .thumb { aspect-ratio: 3 / 4; }  /* 产品图本身就是 3:4，容器改成同比例，两侧就不会留大片空白 */
.product-card .thumb img { width: 100%; height: 100%; object-fit: contain; }

/* 型号详情页的主图 */
.product-shot {
  background: var(--soft);
  border: 1px solid var(--edge);
  border-radius: var(--radius);
  padding: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.product-shot img { max-width: 100%; height: auto; }

/* 口味清单：可换行的胶囊标签，比一串逗号好扫读 */
.flavor-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.flavor-list li {
  background: var(--soft);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 7px 15px;
  font-size: 14px;
  color: var(--ink-2);
}

/* FAQ 用 h3 提问（h2 留给分组标题），视觉与 h2 版一致 */
.faq-item h3 {
  font-size: 1.02rem;
  font-weight: 600;
  letter-spacing: 0;
  margin: 0 0 8px;
}

/* 页脚合规警示：整站每一页都要出现，所以给它一条独立的分隔带 */
.footer-warn {
  margin: 30px 0 0;
  padding: 14px 16px;
  border-left: 3px solid var(--accent);
  background: rgba(255, 255, 255, 0.05);
  border-radius: 0 6px 6px 0;
  font-size: 13px;
  line-height: 1.65;
  color: #cbd8e4;
}

@media (max-width: 720px) {
  .product-card .thumb { aspect-ratio: 1 / 1; }
  .product-shot { padding: 10px; }
}

/* 型号详情页首屏：主图与参数表。默认 1.15/0.85 会把参数值挤到换行，
   这里把比例倒过来，表格拿到更宽的一侧。 */
.product-hero {
  display: grid;
  grid-template-columns: 0.82fr 1.18fr;
  gap: 40px;
  align-items: start;
}
@media (max-width: 980px) {
  .product-hero { grid-template-columns: 1fr; gap: 26px; }
}

/* 小屏微调：首屏标题在这个宽度下按 clamp 最小值仍偏大，
   一行只放得下三四个词，读起来像被切成碎片。 */
@media (max-width: 600px) {
  h1 { font-size: 1.55rem; line-height: 1.28; }
  .hero h1 { font-size: 1.62rem; }
  .fact-box dl { grid-template-columns: 1fr; gap: 2px 0; }
  .fact-box dt { margin-top: 10px; font-size: 12.5px; }
  .fact-box dd { font-weight: 600; }
  .lede { font-size: 15.5px; }
}

/* 标题换行：避免最后一行只剩一个词（如 "job" / "sell"）。
   不支持 text-wrap: balance 的浏览器会忽略这条，回到普通换行。 */
h1, h2, h3 { text-wrap: balance; }

/* ---------------------------------------------------------------------------
   图片版块：目录里的实拍图不能只做缩略图，得在正文里撑起段落之间的呼吸。
   --------------------------------------------------------------------------- */

/* ---------------------------------------------------------------------------
   自动滚动产品带
   两组相同内容首尾相接，轨道整体位移 -50% 正好是一个循环，接缝处不跳。
   --------------------------------------------------------------------------- */
.range-marquee {
  position: relative;
  overflow: hidden;
  padding: 4px 0 16px;
  /* 两侧淡出，让设备从边上"化"进背景，而不是被硬边切断 */
  -webkit-mask-image: linear-gradient(to right, transparent, #000 48px, #000 calc(100% - 48px), transparent);
          mask-image: linear-gradient(to right, transparent, #000 48px, #000 calc(100% - 48px), transparent);
}
.range-track {
  display: flex;
  width: max-content;
  /* 33 台设备时速度要按张数放大，否则走一圈比原来快近三倍、看着像快进。
     72s 是 12 张时的值，这里按 33/12 放大到 180s。 */
  animation: range-drift 180s linear infinite;
}
.range-marquee:hover .range-track,
.range-marquee:focus-within .range-track { animation-play-state: paused; }

@keyframes range-drift {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

.range-group {
  display: flex;
  gap: 14px;
  padding-right: 14px;   /* 与 gap 等宽，-50% 才能精确落在接缝上 */
}
.range-group .range-card {
  display: block;
  width: 168px;
  flex: none;
  text-decoration: none;
  color: inherit;
  -webkit-tap-highlight-color: transparent;
}
.range-group .shot {
  background: var(--soft);
  border: 1px solid var(--line);
  border-radius: 10px;
  aspect-ratio: 3 / 4;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  transition: transform .22s ease, border-color .22s ease, box-shadow .22s ease;
}
.range-group img { width: 100%; height: 100%; object-fit: contain; }
/* 可点：悬停/键盘聚焦时卡片微微抬起、边框加深，型号变色。
   只做位移和颜色，不做缩放——缩放会让 3:4 的图在滚动带上抖。 */
.range-card:hover .shot,
.range-card:focus-visible .shot {
  transform: translateY(-3px);
  border-color: var(--edge-2);
  box-shadow: 0 10px 22px rgba(11, 32, 51, .10);
}
.range-card:hover b,
.range-card:focus-visible b { color: var(--accent); }
.range-card:focus-visible { outline: 2px solid var(--accent); outline-offset: 6px; border-radius: 12px; }
.range-group .cap {
  margin-top: 8px;
  font-size: 12.5px;
  color: var(--muted);
  line-height: 1.4;
}
.range-group .cap b { display: block; color: var(--ink); font-size: 13.5px; }

/* ---------------------------------------------------------------------------
   首页展示图：三张自动切换
   交叉淡入，每 7 秒一张。时间轴是同一个 21 秒周期错开 7 秒，
   淡出区间和下一张的淡入区间重叠 1 秒，中间不会闪白。
   --------------------------------------------------------------------------- */
.showcase { padding: 8px 0 10px; }

.showcase-frame {
  position: relative;
  border-radius: var(--radius);
  overflow: hidden;
  background: #0a1c27;
  box-shadow: 0 18px 44px -28px rgba(9, 32, 46, 0.55);
}

/* 文案条不叠在图上，而是占掉自己的高度。
   只要条是浮在图片上的，就一定会切掉图的下沿——
   三张从目录页裁的图，底部不是口味名就是下一排设备的头顶。 */
.showcase-slide {
  position: absolute;
  inset: 0;
  margin: 0;
  opacity: 0;
  animation: showcase-fade 21s infinite;
}
/* 第一张留在文档流里，由"图 + 文案"撑起容器高度 */
.showcase-slide:first-of-type { position: relative; opacity: 1; }
.showcase-slide:first-of-type figcaption { position: static; }

.showcase-slide img {
  width: 100%;
  height: auto;
  display: block;
  animation: showcase-push 21s infinite;
}

.showcase-frame::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 96px;
  background: linear-gradient(to bottom, rgba(6, 18, 26, 0.42), transparent);
  z-index: 2;
  pointer-events: none;
}

.showcase-slide {
  position: absolute;
  inset: 0;
  margin: 0;
  opacity: 0;
  animation: showcase-fade 21s infinite;
}
/* 负延迟让第一张在页面加载时就已经"亮着"，
   否则头 0.9 秒画面是空的，看起来像图挂了。
   三张间隔仍是 7 秒，循环接缝不变。 */
.showcase-slide:nth-of-type(1) { animation-delay: -2s; }
.showcase-slide:nth-of-type(2) { animation-delay: 5s; }
.showcase-slide:nth-of-type(3) { animation-delay: 12s; }
.showcase-slide img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  animation: showcase-push 21s infinite;
}
.showcase-slide:nth-of-type(1) img { animation-delay: -2s; }
.showcase-slide:nth-of-type(2) img { animation-delay: 5s; }
.showcase-slide:nth-of-type(3) img { animation-delay: 12s; }
@keyframes showcase-fade {
  0%    { opacity: 0; }
  4.5%  { opacity: 1; }
  33%   { opacity: 1; }
  38%   { opacity: 0; }
  100%  { opacity: 0; }
}
@keyframes showcase-push {
  0%   { transform: scale(1.055); }
  42%  { transform: scale(1); }
  100% { transform: scale(1); }
}

.showcase-slide figcaption {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 10px 28px 12px;
  /* 实心条，不用渐变：图是从目录页整条裁的，底部本来印着口味名，
     半透明遮罩压不干净，字会透上来和型号打架。宁可切掉图的下沿一点。
     高度给个下限，中文文案比英文短一行，条一矮就会露出被裁的第二排设备。 */
  min-height: 68px;
  justify-content: center;
  background: #0a1c27;
  color: #fff;
  display: flex;
  flex-direction: column;
  gap: 3px;
  z-index: 2;
}
.showcase-head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
}
.showcase-tag {
  font-size: 10.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #7fd8cc;
}
.showcase-slide figcaption b { font-size: 1.06rem; letter-spacing: -0.01em; }
.showcase-copy {
  font-size: 13px;
  line-height: 1.4;
  color: #b9cbd6;
  max-width: 76ch;
}

/* 暂停开关：自动播放的轮播必须让人能停住（WCAG 2.2.2）。
   用 checkbox 而不是脚本，整站还是零 JS。 */
.showcase-stop {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.showcase-stop-btn {
  position: absolute;
  top: 16px;
  right: 18px;
  z-index: 4;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: rgba(10, 28, 39, 0.5);
  border: 1px solid rgba(255, 255, 255, 0.42);
  cursor: pointer;
  transition: background 0.15s;
}
.showcase-stop-btn:hover { background: rgba(10, 28, 39, 0.78); }
/* 暂停图标：两条竖线 */
.showcase-stop-btn::before {
  content: "";
  position: absolute;
  inset: 8px 7px;
  background: linear-gradient(to right, #fff 0 3px, transparent 3px 6px, #fff 6px 9px);
}
/* 勾上以后变成播放三角 */
.showcase-stop:checked ~ .showcase-stop-btn::before {
  inset: 7px 6px 7px 9px;
  background: #fff;
  clip-path: polygon(0 0, 100% 50%, 0 100%);
}
.showcase-stop:checked ~ .showcase-slide,
.showcase-stop:checked ~ .showcase-slide img,
.showcase-stop:checked ~ .showcase-dots i { animation-play-state: paused; }
.showcase-stop:focus-visible ~ .showcase-stop-btn {
  outline: 2px solid #7fd8cc;
  outline-offset: 2px;
}

.showcase-dots {
  position: absolute;
  right: 54px;
  top: 22px;
  z-index: 3;
  display: flex;
  gap: 7px;
}
.showcase-dots i {
  width: 26px;
  height: 4px;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.34);
  animation: showcase-dot 21s infinite;
}
.showcase-dots i:nth-child(1) { animation-delay: -2s; }
.showcase-dots i:nth-child(2) { animation-delay: 5s; }
.showcase-dots i:nth-child(3) { animation-delay: 12s; }
@keyframes showcase-dot {
  0%, 32%   { background: #fff; }
  34%, 100% { background: rgba(255, 255, 255, 0.34); }
}

@media (max-width: 720px) {
  /* 小屏不再固定容器比例，改由图自己定高：2.75:1 在 375px 宽下只剩 130px，
     设备会缩成一条线。裁成 16:10 更好认。 */
  /* 手机端按 2.75:1 原比例走只剩 120px 高，设备小到看不清。
     改成 16:9 让图片裁边放大，宁可少看一台设备。 */
  .showcase-slide img { aspect-ratio: 16 / 9; object-fit: cover; }
  .showcase-slide figcaption { padding: 9px 14px 10px; min-height: 0; }
  .showcase-slide figcaption b { font-size: 1rem; }
  .showcase-copy { font-size: 13px; }
  .showcase-dots { right: 14px; top: 12px; }
  .showcase-dots i { width: 18px; }
  .range-group .range-card { width: 132px; }
  .range-track { animation-duration: 150s; }
}

/* 关闭动效：轮播停在第一张，产品带交回用户自己拖 */
@media (prefers-reduced-motion: reduce) {
  .showcase-slide { animation: none; }
  .showcase-slide:first-of-type { opacity: 1; }
  .showcase-slide img { animation: none; }
  .showcase-dots i { animation: none; }
  .range-track { animation: none; }
  .range-marquee {
    overflow-x: auto;
    -webkit-mask-image: none;
            mask-image: none;
  }
}

/* 正文配图：包装、外箱、警示标签这类"看得出实物"的图 */
figure.photo {
  margin: 0 0 6px;
  border: 1px solid var(--edge);
  border-radius: var(--radius);
  background: var(--soft);
  overflow: hidden;
}
figure.photo img { width: 100%; height: auto; display: block; }
figure.photo figcaption {
  padding: 12px 16px;
  font-size: 13px;
  color: var(--muted);
  line-height: 1.6;
  border-top: 1px solid var(--line);
  background: #fff;
}

/* 双图并排 */
.photo-pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 18px;
}
@media (max-width: 720px) { .photo-pair { grid-template-columns: 1fr; } }

/* 口味胶囊：前面一个色点，按口味名自动取色 */
.chip-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 9px;
}
.chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 14px 7px 10px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: #fff;
  font-size: 14px;
  color: var(--ink-2);
}
.chip i {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 1px solid rgba(0, 0, 0, 0.12);
  flex: none;
}

/* 关联型号卡片：给一张小图，比纯文字好认 */
.card .thumb-sm {
  background: var(--soft);
  border-radius: 8px;
  /* 图源是 3:4 竖图，4:3 容器两侧会空出一大截 */
  aspect-ratio: 3 / 4;
  margin-bottom: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.card .thumb-sm img { width: 100%; height: 100%; object-fit: contain; }

/* 竖构图配图：按高度收住，避免一张 812×1800 的图把整屏撑满 */
figure.photo.tall { background: #fff; text-align: center; }
figure.photo.tall img { height: min(58vh, 480px); width: auto; margin: 0 auto; }

/* 双图并排时统一高度，避免一张高一张矮、左右不齐 */
.photo-pair figure.photo img {
  height: 420px;
  width: 100%;
  object-fit: contain;
  background: #fff;
}
@media (max-width: 720px) {
  .photo-pair figure.photo img { height: 320px; }
}

/* ==========================================================================
   视觉升级层 — 精密制造商的气质：大留白、细线、深墨、克制的青绿点缀
   放在最末，覆盖上面的骨架默认值。只动视觉，不动布局与结构。
   ========================================================================== */

:root {
  /* 中性色重新排：背景不再是纯白，卡片才是纯白。
     靠 1.5% 的明度差把卡片"托"起来，比加粗边框高级，也更耐看。 */
  /* 中性色整体往藏蓝偏：和绯红撞在一起才干净，
     原来的冷灰（#33414e / #64748b）配绯红会发脏。 */
  --ink:      var(--navy);
  --ink-2:    #35355f;   /* 正文：白底 8.6:1 */
  --muted:    #5b5b82;
  --bg:       #fbfbfe;
  --surface:  #ffffff;
  --soft:     #f4f5fa;
  --soft-2:   #ecedf6;

  /* 两档边框：常态几乎看不见，靠阴影表达"独立一块"；悬停才显形 */
  --card-edge:   rgba(11, 23, 36, 0.085);
  --card-edge-2: rgba(11, 23, 36, 0.17);

  /* 三层阴影，一层比一层"远" */
  --shadow-1: 0 1px 2px rgba(11, 23, 36, 0.04);
  --shadow-2: 0 1px 2px rgba(11, 23, 36, 0.04), 0 10px 30px -16px rgba(11, 23, 36, 0.18);
  --shadow-3: 0 2px 6px rgba(11, 23, 36, 0.05), 0 26px 60px -30px rgba(11, 23, 36, 0.26);

  --radius: 14px;
  --container: 1200px;

  /* 所有过渡走同一条曲线，避免每个组件各用各的 ease */
  --ease: cubic-bezier(0.2, 0.7, 0.3, 1);

  /* 品牌色：绯红。两个色都是平涂性格，这里不再做去饱和处理 */
  --brand: var(--crimson);
  --brand-ink: var(--crimson-ink);
  --accent: var(--crimson);
  --accent-soft: #fdecee;
  --cta: var(--crimson);
  --cta-deep: #a00f1a;
}

body { background: var(--bg); line-height: 1.72; }

::selection { background: rgba(228, 23, 38, 0.22); color: var(--ink); }

/* ---------- 导航 ---------- */

.site-header {
  background: rgba(251, 252, 253, 0.82);
  backdrop-filter: saturate(1.5) blur(14px);
  -webkit-backdrop-filter: saturate(1.5) blur(14px);
  border-bottom-color: rgba(11, 23, 36, 0.07);
}
.header-inner { min-height: 74px; }
.logo b { letter-spacing: 0.16em; }
.nav { gap: 2px; }
.nav a {
  padding: 9px 13px;
  border-radius: 8px;
  font-size: 13.5px;
  transition: color 0.2s var(--ease), background-color 0.2s var(--ease);
}
.nav a:hover { background: transparent; }
/* 当前页用一条 2px 下划线，比灰底块干净 */
.nav a[aria-current="page"] {
  background: transparent;
  position: relative;
  color: var(--brand);
  font-weight: 600;
}
.nav a[aria-current="page"]::after {
  content: "";
  position: absolute;
  left: 13px;
  right: 13px;
  bottom: 3px;
  height: 2px;
  border-radius: 1px;
  background: var(--accent);
}

/* ---------- 首屏 ---------- */

.hero {
  padding: 104px 0 80px;
  border-bottom: 1px solid rgba(11, 23, 36, 0.06);
  background: linear-gradient(180deg, #f7fafb 0%, var(--bg) 100%);
}
/* 原来这层光晕里写死了模版遗留的橙色，和青绿品牌色打架 */
.hero::before {
  background:
    radial-gradient(42% 56% at 14% 30%, rgba(228, 23, 38, 0.07), transparent 72%),
    radial-gradient(34% 46% at 86% 14%, rgba(18, 58, 82, 0.08), transparent 74%);
}
.hero-grid { gap: 64px; }

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  padding: 0;
  border-radius: 0;
  background: none;
  font-size: 11.5px;
  letter-spacing: 0.16em;
  color: var(--accent);
  margin-bottom: 24px;
}
.eyebrow::before {
  content: "";
  width: 24px;
  height: 1px;
  background: currentColor;
  opacity: 0.5;
  flex: none;
}

h1 {
  font-size: clamp(1.62rem, 4.2vw, 3.15rem);
  line-height: 1.08;
  letter-spacing: -0.028em;
  margin-bottom: 22px;
}
.lede {
  font-size: 1.115rem;
  line-height: 1.62;
  color: var(--ink-2);
  margin-bottom: 30px;
}

/* ---------- 按钮 ---------- */

.btn {
  padding: 13px 24px;
  border-radius: 10px;
  font-size: 14.5px;
  letter-spacing: -0.004em;
  transition: background-color 0.22s var(--ease), color 0.22s var(--ease),
              border-color 0.22s var(--ease), box-shadow 0.22s var(--ease),
              transform 0.22s var(--ease);
}
.btn-primary {
  box-shadow: 0 1px 2px rgba(11, 23, 36, 0.14), 0 10px 22px -12px rgba(18, 58, 82, 0.55);
}
.btn-primary:hover {
  transform: translateY(-1px);
  box-shadow: 0 2px 4px rgba(11, 23, 36, 0.16), 0 16px 30px -14px rgba(18, 58, 82, 0.6);
}
.btn-ghost {
  border-color: var(--card-edge-2);
  background: var(--surface);
}
.btn-ghost:hover {
  background: var(--surface);
  border-color: var(--brand);
  transform: translateY(-1px);
  box-shadow: var(--shadow-1);
}

/* ---------- 信息框 ---------- */

.fact-box {
  background: var(--surface);
  border: 1px solid var(--card-edge);
  border-radius: 16px;
  padding: 26px 28px;
  box-shadow: var(--shadow-2);
}
.fact-box h2 {
  font-size: 11px;
  letter-spacing: 0.16em;
  margin-bottom: 18px;
  color: var(--muted);
}
.fact-box dl { gap: 11px 18px; font-size: 13.5px; }
.fact-box dt { font-size: 13px; }

/* ---------- 区块节奏 ---------- */

section { padding: 88px 0; }
section + section { border-top: 1px solid rgba(11, 23, 36, 0.055); }
.section-head { margin-bottom: 42px; }

h2 {
  font-size: clamp(1.34rem, 2.6vw, 2.05rem);
  line-height: 1.2;
  letter-spacing: -0.022em;
  margin-bottom: 14px;
}
h3 { font-size: 1.1rem; letter-spacing: -0.008em; }

/* ---------- 卡片 ---------- */

.grid { gap: 24px; }

.card {
  background: var(--surface);
  border: 1px solid var(--card-edge);
  border-radius: 16px;
  padding: 26px;
  box-shadow: var(--shadow-1);
  transition: border-color 0.26s var(--ease), box-shadow 0.26s var(--ease),
              transform 0.26s var(--ease);
}
.card:hover {
  border-color: var(--card-edge-2);
  box-shadow: var(--shadow-2);
  transform: translateY(-2px);
}
.card .meta { letter-spacing: 0.08em; font-size: 11.5px; }
.thumb {
  border-radius: 12px;
  background: linear-gradient(180deg, var(--soft) 0%, #fbfdfe 100%);
}

/* ---------- 表格 ---------- */

.table-wrap {
  border-color: var(--card-edge);
  border-radius: 14px;
  box-shadow: var(--shadow-1);
  background: var(--surface);
}
table { font-size: 13.5px; }
th {
  background: #fafcfd;
  font-size: 11.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--muted);
}
td { border-bottom-color: rgba(11, 23, 36, 0.055); }
tr:last-child td { border-bottom: 0; }

/* ---------- 问答 ---------- */

.faq-item { border-bottom-color: var(--card-edge); padding: 26px 0; }
.faq-item:first-of-type { border-top-color: var(--card-edge); }

/* ---------- 小屏 ---------- */

@media (max-width: 900px) {
  .hero { padding: 64px 0 52px; }
  .hero-grid { gap: 36px; }
}
@media (max-width: 720px) {
  section { padding: 56px 0; }
  .hero { padding: 48px 0 40px; }
  .grid { gap: 16px; }
  .card { padding: 20px; border-radius: 14px; }
  .fact-box { padding: 20px; }
  .section-head { margin-bottom: 28px; }
  .nav a[aria-current="page"]::after { left: 9px; right: 9px; }
}

/* ---------- 链接分层：正文里保留可辨识的下划线，标题与卡片里不要 ---------- */

/* 正文链接：下划线压淡一档，hover 才实心。整页几十条链接都带同等黑线，
   读起来像 2008 年的网页。 */
a { text-decoration-color: rgba(18, 58, 82, 0.28); transition: color 0.18s var(--ease); }
a:hover { text-decoration-color: currentColor; }

/* 标题里的链接：标题本身就是可点区域，下划线会让每张卡的首行都变脏 */
.card h2 a,
.card h3 a,
.card h4 a,
.faq-item h2 a,
.faq-item h3 a {
  text-decoration: none;
  color: var(--ink);
}
.card h2 a:hover,
.card h3 a:hover,
.card h4 a:hover,
.faq-item h2 a:hover,
.faq-item h3 a:hover { color: var(--accent); }

/* 卡片里的"查看参数 →"这类尾链接：去掉下划线，箭头在 hover 时前移 */
.card a.more { text-decoration: none; color: var(--brand); display: inline-block; }
.card a.more:hover { color: var(--accent); }

/* 卡片阴影抬一档：上一版几乎看不见，卡片和背景糊在一起 */
:root {
  --shadow-1: 0 1px 2px rgba(11, 23, 36, 0.05), 0 3px 10px -6px rgba(11, 23, 36, 0.10);
}

/* ---------- 第二遍微调 ---------- */

/* 背景压到带蓝味的浅灰：纯白页面上白卡全靠阴影撑，整页"没颜色"。
   #ecf0f8 在白卡旁边能看出层次，和绯红/藏蓝一个色系，不会发脏。 */
:root { --bg: #ecf0f8; }

/* 摘要段左边的 3px 实心青绿像引用块，压到 2px 半透明，退成"提示"而不是"警示" */
.answer {
  border-left: 2px solid rgba(228, 23, 38, 0.55);
  padding-left: 18px;
}

/* 产品图容器改白底：产品图自己带浅色渐变底，容器再铺一层灰就变成"色块套色块" */
.thumb { background: #fff; }

/* 网格再松一点 */
.grid { gap: 28px; }
@media (max-width: 720px) { .grid { gap: 16px; } }

/* 背景压深后，首屏那段渐变两端几乎同色，层次没了。上端再提亮一档。 */
.hero { background: linear-gradient(180deg, #eef3f8 0%, var(--bg) 78%); }

/* ---------- 页脚 ---------- */

.site-footer {
  padding: 72px 0 32px;
  background:
    /* 左上角一团绯红光，模拟参考图里"藏蓝底上一小块绯红"的撞色关系；
       不用大面积渐变，保持平涂性格 */
    radial-gradient(58% 120% at 10% 0%, rgba(228, 23, 38, 0.20), transparent 62%),
    var(--navy);
}
.footer-grid { gap: 44px; }
.footer-grid h2 {
  letter-spacing: 0.14em;
  margin-bottom: 16px;
  color: rgba(255, 255, 255, 0.55);
  font-weight: 600;
  font-size: 11px;
}
.footer-grid li { margin-bottom: 9px; }
.site-footer a { transition: color 0.18s var(--ease); }
.site-footer a:hover { text-decoration-color: rgba(255, 255, 255, 0.6); }
.footer-logo b { letter-spacing: 0.18em; }
.footer-legal {
  margin-top: 44px;
  border-top-color: rgba(255, 255, 255, 0.1);
  font-size: 12px;
  color: rgba(255, 255, 255, 0.5);
}
.footer-warn {
  border-left: 2px solid var(--accent);
  background: rgba(255, 255, 255, 0.045);
  border-radius: 0 8px 8px 0;
  margin-top: 36px;
}

/* ---------- 问答卡：问题与答案之间留一口气 ---------- */

.faq-item h3,
.faq-item h2 { margin-bottom: 10px; }

/* ---------- 产品带：和白卡体系对齐 ---------- */

.range-group .shot {
  background: var(--surface);
  border-color: var(--card-edge);
  border-radius: 12px;
}
.range-group .cap { font-size: 12.5px; margin-top: 10px; }
.range-group .cap b { font-size: 13.5px; letter-spacing: -0.005em; }

/* ---------- 阅读行宽：正文一行 78 个字符太长，眼睛要横跳两三次 ---------- */

.section-head { max-width: 68ch; }
.answer { max-width: 72ch; }

h1 { font-size: clamp(1.6rem, 3.9vw, 2.95rem); }

/* ---------- 表单控件：给边界一点实体 ---------- */

.field input,
.field select,
.field textarea {
  border-radius: 10px;
  border-color: #c3ccd7;
  background: #fff;
  box-shadow: inset 0 1px 2px rgba(11, 23, 36, 0.03);
  transition: border-color 0.18s var(--ease), box-shadow 0.18s var(--ease);
}
.field input:hover,
.field select:hover,
.field textarea:hover { border-color: #a9b5c2; }
.field input:focus,
.field select:focus,
.field textarea:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(228, 23, 38, 0.16);
  outline: none;
}
.field label { font-size: 12.5px; letter-spacing: 0.01em; margin-bottom: 7px; }

/* ---------- 表格：行再松一点，表头与内容之间划清 ---------- */

th, td { padding: 13px 16px; }
th { border-bottom: 1px solid rgba(11, 23, 36, 0.09); }
caption {
  padding: 15px 16px 12px;
  border-bottom: 1px solid rgba(11, 23, 36, 0.06);
  font-size: 12.5px;
  letter-spacing: 0.01em;
}

/* ---------- 型号页主图：容器别把产品挤小 ---------- */

.product-shot { padding: 12px; background: #fff; border-color: var(--card-edge); }

/* ---------- 中文：负字距是给拉丁字母的，汉字不需要 ---------- */
/* 英文靠 -0.028em 收紧标题，同样的值套在汉字上会让笔画粘连。 */
:lang(zh) h1 { letter-spacing: -0.004em; }
:lang(zh) h2 { letter-spacing: -0.006em; }
:lang(zh) h3 { letter-spacing: 0; }
:lang(zh) .eyebrow { letter-spacing: 0.1em; }

/* ==========================================================================
   3D 产品环廊（products 页首屏下方）
   --------------------------------------------------------------------------
   没有 JS 时：`.ring-track` 是一条可横向滚动的产品列表，每张卡是一个普通链接。
   JS 接管后根节点挂上 data-ring-on，列表切成 0×0 的 3D 舞台，卡片由脚本
   切成 8 条竖片贴到圆筒上。样式只负责"两种形态各自该长什么样"。
   ========================================================================== */

.ring-band {
  padding: 40px 0 8px;
  background: linear-gradient(180deg, var(--soft) 0%, #fff 72%);
  border-top: 1px solid var(--line);
}

.ring-band .section-head { margin-bottom: 10px; }

/* 首页那一份没有标题区：hero 已经给过 H1，再来一个 h2 会和下面
   "五条产品线"抢层级。hero 自带下边框，这里不再加线，只留呼吸。 */
.ring-band--home {
  padding: 22px 0 0;
  border-top: 0;
  background: #fff;
}

.ring-shell {
  position: relative;
  margin: 0 -8px;
  touch-action: pan-y;
}

/* 高度只在脚本接管后才固定：没有 JS 时这里是横向列表，撑多高算多高 */
.ring-shell[data-ring-on] {
  height: clamp(380px, 38vw, 500px);
}

.ring-stage { position: static; }

[data-ring-on] .ring-stage {
  position: absolute;
  inset: 0 0 104px;
  z-index: 1;
  opacity: 0;
  transition: opacity 0.5s ease;
}

/* 无脚本 / 脚本未接管：退回一条横向列表 */
.ring-track {
  display: flex;
  gap: 16px;
  margin: 0;
  padding: 8px 8px 14px;
  list-style: none;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
}

.ring-card { flex: none; scroll-snap-align: center; }

.ring-link {
  display: block;
  width: 176px;
  text-decoration: none;
  color: inherit;
}

.ring-link img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--edge);
  border-radius: 12px;
  background: #fff;
}

.ring-link .ring-cap {
  display: block;
  margin-top: 8px;
  font-size: 12.5px;
  line-height: 1.4;
  color: var(--muted);
}

.ring-link .ring-cap b { display: block; color: var(--ink); font-size: 13px; }

/* —— 脚本接管后 —— */

/* 环底下的一层投影：卡片本身有边有影，但整体悬空，加一道椭圆阴影才"落地" */
.ring-shell::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 90px;
  width: 54%;
  height: 22px;
  transform: translateX(-50%);
  border-radius: 50%;
  background: radial-gradient(ellipse at center,
    rgba(9, 32, 46, 0.16) 0%, rgba(9, 32, 46, 0.07) 45%, rgba(9, 32, 46, 0) 72%);
  filter: blur(3px);
  pointer-events: none;
}

.ring-shell[data-ring-on] { cursor: grab; }
.ring-shell[data-ring-on]:active { cursor: grabbing; }

[data-ring-ready] .ring-stage { opacity: 1; }

[data-ring-on] .ring-track {
  position: absolute;
  left: 0;
  top: 0;
  display: block;
  width: 0;
  height: 0;
  padding: 0;
  overflow: visible;
  transform-style: preserve-3d;
  scroll-snap-type: none;
}

[data-ring-on] .ring-camera {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 0;
  height: 0;
  transform-style: preserve-3d;
  will-change: transform;
}

[data-ring-on] .ring-card {
  position: absolute;
  left: 0;
  top: 0;
  width: 0;
  height: 0;
  flex: none;
  transform-style: preserve-3d;
  will-change: transform;
}

.ring-box {
  display: block;
  /* 少了这行，竖片的 translate3d/rotateY 会被拍平到卡片平面里，弧面就没了 */
  transform-style: preserve-3d;
}

[data-ring-on] .ring-cap { display: none; }

/* 卡片外框：白底 + 2px 近黑描边。
   底板在 ring.js 里比卡片外扩 6px，所以这圈描边是露在图片之外的——
   图片四周 3px 白留白 + 3px 黑边，像裱了一张卡，而不是图片自带的灰线。 */
.ring-plate {
  position: absolute;
  display: block;
  border-radius: 18px;      /* 比图片圆角 12 多一个外扩量，两圈才同心 */
  background: #fff;
  border: 3px solid #0b1119;
  box-shadow: 0 18px 30px -20px rgba(9, 32, 46, 0.62);
  transform: translateZ(-16px);
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}

/* 转到正面的那张再加一道内描边：黑边略微加粗，视觉上"选中"
   用 inset box-shadow 而不是改 border 宽度，避免卡片尺寸跳动 */
[data-ring-on] .ring-card[data-active] .ring-plate {
  box-shadow:
    0 0 0 1px #0b1119,
    0 22px 34px -18px rgba(9, 32, 46, 0.66);
}


.ring-tile {
  position: absolute;
  display: block;
  transform-style: preserve-3d;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}

.ring-frame {
  position: absolute;
  inset: 0;
  display: block;
  overflow: hidden;
  background: #fff;
  box-shadow: 0 1px 0 rgba(11, 32, 51, 0.04);
}

.ring-frame img {
  position: absolute;
  top: 0;
  display: block;
  max-width: none;
  object-fit: cover;
  pointer-events: none;
  user-select: none;
  -webkit-user-drag: none;
}

.ring-shade {
  position: absolute;
  inset: 0;
  display: block;
  /* JS 写进卡片的 --ring-fade 是 0~0.74 的透明度数值；
     淡出"颜色"另用 --ring-fade-color：浅色带默认白，深色带覆盖成藏蓝 */
  background: var(--ring-fade-color, #fff);
  opacity: var(--ring-fade, 0);
  pointer-events: none;
}

/* 背板：从缝隙看过去是"筒的内壁"，浅灰而不是透明 */
.ring-back {
  position: absolute;
  display: block;
  transform: rotateY(180deg);
  border-radius: 12px;
  background: linear-gradient(180deg, #e9eff6, #dfe7f0);
  box-shadow: inset 0 0 0 1px rgba(11, 32, 51, 0.06);
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}

.ring-hit {
  position: absolute;
  display: block;
  transform: translateZ(2px);
  border-radius: 12px;
  outline: none;
  -webkit-tap-highlight-color: transparent;
}

.ring-hit:focus-visible {
  box-shadow: 0 0 0 2px var(--accent), 0 0 0 5px rgba(180, 98, 26, 0.22);
}

[data-ring-on] .ring-card[data-active] .ring-frame { box-shadow: 0 6px 18px -10px rgba(9, 32, 46, 0.45); }

/* 下方标题：跟着转到正面的那张卡走 */
.ring-caption {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: none;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  text-align: center;
  pointer-events: none;
}

[data-ring-on] .ring-caption { display: flex; }

.ring-caption b {
  font-size: 15px;
  letter-spacing: -0.01em;
  color: var(--ink);
}

.ring-caption span {
  font-size: 12.5px;
  color: var(--muted);
}

.ring-count {
  font-variant-numeric: tabular-nums;
  font-size: 11.5px !important;
  letter-spacing: 0.04em;
  color: var(--muted);
  opacity: 0.75;
}

.ring-live {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.ring-toggle {
  position: absolute;
  right: 6px;
  bottom: 14px;
  z-index: 3;
  width: 28px;
  height: 28px;
  padding: 0;
  border-radius: 50%;
  border: 1px solid var(--edge);
  background: rgba(255, 255, 255, 0.94);
  box-shadow: 0 2px 8px -4px rgba(9, 32, 46, 0.35);
  cursor: pointer;
  opacity: 0.6;
  transition: opacity 0.15s, background 0.15s;
}

.ring-toggle[hidden] { display: none; }
.ring-toggle:hover { opacity: 1; background: #fff; }

.ring-toggle::before {
  content: "";
  position: absolute;
  inset: 9px 8px;
  background: linear-gradient(to right, var(--brand) 0 3px, transparent 3px 6px, var(--brand) 6px 9px);
}

.ring-toggle[aria-pressed="true"]::before {
  inset: 8px 7px 8px 10px;
  background: none;
  border-left: 8px solid var(--brand);
  border-top: 5px solid transparent;
  border-bottom: 5px solid transparent;
}

.ring-hint {
  margin: 6px 0 0;
  text-align: center;
  font-size: 12px;
  color: var(--muted);
}

@media (max-width: 760px) {
  .ring-shell[data-ring-on] { height: clamp(360px, 100vw, 470px); margin: 0; overflow: hidden; }
  /* 舞台底部留 88px：标题一行 + 参数一行 + 计数一行，再留呼吸；
     56px 时卡片底边会压住型号名 */
  [data-ring-on] .ring-stage { inset: 0 0 88px; }
  .ring-shell::after { bottom: 72px; width: 66%; height: 16px; }
  .ring-toggle { right: 2px; bottom: 10px; }
  .ring-link { width: 150px; }
}

@media (prefers-reduced-motion: reduce) {
  [data-ring-on] .ring-stage { transition: none; }
}

/* ---------- 开屏动画：一条铜线，开成整屏 ----------

   时序（总长 2.55s，全部由 keyframes 驱动，零 JS）：
     0.09–0.51s  铜线从中间向两侧拉出，成为 96px 的一道横线
     0.18–0.80s  Stratovape 十个字母依次从线后面升起来（每个错开 60ms）
     0.48–0.80s  副标淡入
     0.99–1.11s  字标退场（必须赶在竖缝张开之前，否则白字压在亮缝上看不清）
     1.10–1.47s  横线向上、向下张开成一条竖缝（1px → 100%）
     1.43–1.81s  竖缝向左右推开成整屏（96px → 100%）
     1.81–1.94s  整屏停留
     1.94–2.10s  画面沉回暗底
     2.10–2.55s  暗底撤走，首页亮起来

   为什么从"一条线"起手，而不是一个圆角卡片：
   卡片浮在深色底上永远是"图放进框里"，框边就是一条和画面无关的硬边。
   从线张开，框边一开始不存在——观众先看到的是品牌字样和一道铜线，
   然后画面从这条缝里长出来，收尾时框边又消失在外框之外。
   动作是同一个（小窗推到整屏，即 ScrollExpand 的那条曲线），起点体面得多。

   图也不再用产品样机原图：原图是紫皮 + 桃色底的平涂，铺满整屏就是一张
   商品详情页。改为 make_splash.py 抠图后重调色（深青暗部 / 铜金高光）、
   加辉光、暗角、颗粒，做成一张暗场微距。开屏的"高级感"八成来自这张图。

   三层关闭方式，都不需要脚本：
     · 点画面任意处 → label 勾选隐藏 checkbox → display:none；
     · 键盘 Tab 到那个 checkbox → 右上角才浮出"跳过"提示；
     · 同一次会话只开一次 → head 里一行脚本给 <html> 加 .splash-off。
   系统开启"减少动效"时整块不渲染。                        */

.splash {
  --lw: 132px;             /* 起始线长，也是竖缝的宽度 */
  position: fixed;
  inset: 0;
  z-index: 90;
  overflow: hidden;
  background:
    radial-gradient(74% 58% at 50% 46%, #0d2b3d 0%, #071a28 52%, #030d16 100%);
  animation: splash-out 2.55s linear both;
}

/* 收尾。最后把 visibility 一起设为 hidden：
   只把 opacity 归零的话，这块仍然会吃掉页面的点击。 */
@keyframes splash-out {
  0%, 83%  { opacity: 1; visibility: visible; }
  100%     { opacity: 0; visibility: hidden; }
}

/* 画面本体：1px 高的横线 → 96px 宽的竖缝 → 整屏。
   2026-11-03：用户要求去掉开屏里的产品照片，这里改成一块"暗场灯箱"——
   比外层底色略亮一档的深青，中间一团铜金暖光，缝里透出来的是光，不是图。
   动效（splash-h / splash-w）完全不变。 */
.splash-window {
  position: absolute;
  left: 50%;
  top: 50%;
  width: var(--lw);
  height: 1px;
  transform: translate(-50%, -50%);
  overflow: hidden;
  /* 窗口本身不放任何"面"：只负责裁剪，里面由 .splash-beam 提供光 */
  background: none;
  box-shadow: 0 0 74px rgba(196, 138, 86, 0.17), 0 0 16px rgba(232, 185, 140, 0.12);
  /* 高度、宽度分两条动画：高度要"先快后慢"地窜出去，
     否则 96px×200 的那一小段会停成一个正方形，看起来像开了个小窗，
     而不是一道光缝被拉开。宽度再"先慢后快"地推到两边。 */
  animation:
    splash-h 2.55s cubic-bezier(.28, .56, .2, 1) both,
    splash-w 2.55s cubic-bezier(.6, .02, .2, 1) both;
  will-change: width, height;
}

/* 光缝本体。两层互相垂直的渐变交叉叠加，横竖都收到透明，
   所以窗口长成什么比例都不会露出矩形硬边。
   关键在 splash-beam：光在"展开"的同时熄灭 —— 否则铺满整屏后会变成
   一大片灰雾，像蒙了层脏玻璃，而不是"灯亮了一下"。 */
.splash-beam {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(90deg,
      rgba(255, 240, 222, 0) 0%,
      rgba(255, 240, 222, 0.34) 50%,
      rgba(255, 240, 222, 0) 100%),
    linear-gradient(180deg,
      rgba(226, 168, 112, 0) 0%,
      rgba(226, 168, 112, 0.30) 46%,
      rgba(226, 168, 112, 0) 100%);
  animation: splash-beam 2.55s linear both;
}

@keyframes splash-beam {
  0%, 54%   { opacity: 1; }
  72%, 100% { opacity: 0; }
}

@keyframes splash-h {
  0%, 43%     { height: 1px; }
  57.5%, 100% { height: 100%; }
}

@keyframes splash-w {
  0%, 56%     { width: var(--lw); }
  71%, 100%   { width: 100%; }
}

/* 开屏里已经没有 <img> 了（2026-11-03 去掉产品照片）。
   保留这条规则只为兜底：万一以后又在窗口里放图，别再退回"按宽度缩放"的老坑。 */
.splash-window img {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 100vw;
  height: 100vh;
  transform: translate(-50%, -50%);
  object-fit: cover;
  object-position: 50% 44%;
  user-select: none;
  -webkit-user-drag: none;
}


/* 收尾：先把画面沉回暗底，再整块撤走。
   直接淡成透明的话，底下的首页会从画面里"透"上来，同一台机器出现两次；
   沉到纯色再撤，读起来是"灯关掉 → 页面亮起"，不会有重影。 */
.splash-scrim {
  position: absolute;
  inset: 0;
  background: #030d16;
  opacity: 0;
  animation: splash-scrim 2.55s linear both;
}

@keyframes splash-scrim {
  0%, 74%     { opacity: 0; }
  83%, 100%   { opacity: 1; }
}

/* 铜线：起手那道横线，竖缝张开后化掉 */
.splash-rule {
  position: absolute;
  left: 50%;
  top: 50%;
  width: var(--lw);
  height: 1px;
  transform: translateX(-50%) scaleX(0);
  background: linear-gradient(90deg,
    rgba(196, 138, 86, 0) 0%,
    #b9814f 16%,
    #e8b98c 50%,
    #b9814f 84%,
    rgba(196, 138, 86, 0) 100%);
  animation: splash-rule 2.55s cubic-bezier(.4, 0, .2, 1) both;
}

@keyframes splash-rule {
  0%, 3.5%  { transform: translateX(-50%) scaleX(0); opacity: 0; }
  6%        { opacity: 1; }
  20%, 43%  { transform: translateX(-50%) scaleX(1); opacity: 1; }
  47%, 100% { transform: translateX(-50%) scaleX(1); opacity: 0; }
}

/* 字标：钉在线的上方，整体在竖缝张开时退场 */
.splash-mark {
  position: absolute;
  inset: 0;
  animation: splash-mark 2.55s linear both;
}

@keyframes splash-mark {
  0%, 39%   { opacity: 1; }
  43.5%, 100% { opacity: 0; }
}

.splash-mark b {
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(50% + 34px);
  padding-left: 0.26em;    /* 补掉字距在右侧多出来的那一格，视觉才居中 */
  overflow: hidden;        /* 字母从线后面升上来，超出部分切掉 */
  font-size: clamp(20px, 2.5vw, 34px);
  font-weight: 700;
  letter-spacing: 0.24em;
  line-height: 1.1;
  text-align: center;
  color: #fff;
}

.splash-mark b i {
  display: inline-block;
  font-style: normal;
  transform: translateY(108%);
  animation: splash-letter 0.5s cubic-bezier(.16, .84, .24, 1) both;
}

.splash-mark b i:nth-child(2) { animation-delay: 0.06s; }
.splash-mark b i:nth-child(3) { animation-delay: 0.12s; }

@keyframes splash-letter {
  0%   { transform: translateY(108%); }
  100% { transform: translateY(0); }
}

.splash-mark span {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(50% + 32px);
  font-size: 11px;
  letter-spacing: 0.34em;
  text-indent: 0.34em;
  text-align: center;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.40);
  opacity: 0;
  animation: splash-sub 0.32s ease both 0.48s;
}

@keyframes splash-sub {
  0%   { opacity: 0; transform: translateY(6px); }
  100% { opacity: 1; transform: translateY(0); }
}

/* 整屏都是点击区 */
.splash-hit {
  position: absolute;
  inset: 0;
  cursor: pointer;
}

/* 隐藏但可聚焦的跳过开关：鼠标走 label，键盘走到这里 */
.splash-skip {
  position: fixed;
  top: 8px;
  left: 8px;
  width: 1px;
  height: 1px;
  margin: 0;
  padding: 0;
  opacity: 0;
  z-index: 91;
  clip-path: inset(50%);
  animation: splash-skip-off 2.55s linear both;
}

/* 动画放完就让它退出 Tab 顺序：否则键盘会停在一个看不见的开关上 */
.splash-skip:checked { display: none; }

@keyframes splash-skip-off {
  0%, 82.5% { visibility: visible; }
  100%      { visibility: hidden; }
}

.splash-skip:checked ~ .splash { display: none; }

/* 只有键盘聚焦时才出现，鼠标用户看不到这块 */
.splash-chip {
  position: absolute;
  top: 16px;
  right: 16px;
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 6px 12px;
  border: 1px solid rgba(255, 255, 255, 0.32);
  border-radius: 999px;
  background: rgba(4, 12, 20, 0.55);
  color: #fff;
  font-size: 12px;
  opacity: 0;
  pointer-events: none;
}

.splash-chip em {
  font-style: normal;
  font-size: 10px;
  letter-spacing: 0.08em;
  color: rgba(255, 255, 255, 0.55);
}

.splash-skip:focus-visible ~ .splash .splash-chip { opacity: 1; }

/* 同一次会话的第二页起，连元素都不渲染 */
html.splash-off .splash,
html.splash-off .splash-skip { display: none; }

/* 中文副标不能套 0.3em 字距：CJK 每个字都成了孤字 */
html[lang="zh-CN"] .splash-mark span {
  font-size: 11px;
  letter-spacing: 0.14em;
  text-indent: 0.14em;
  color: rgba(255, 255, 255, 0.52);
}

@media (max-width: 700px) {
  .splash { --lw: 72px; }
  .splash-mark b { font-size: 30px; bottom: calc(50% + 26px); }
  .splash-mark span { font-size: 9px; top: calc(50% + 24px); letter-spacing: 0.22em; }
}

@media (prefers-reduced-motion: reduce) {
  .splash,
  .splash-skip { display: none; }
}

/* ---------- 立体展示：平面产品图的"可摆动舞台" ----------
   由 assets/js/depth.js 接管时才出现这两层包裹；没有脚本时 DOM 里
   根本不存在这些元素，页面与原来一模一样。

   三层结构：
     .depth-stage   —— 只负责透视（perspective 必须挂在被变换元素的父级）
     .depth-lift    —— 承载 rotateX/rotateY/位移/缩放，图就躺在里面
     .depth-shadow  —— 图下方那团接触阴影，跟着倾斜挪动、跟着俯仰缩放

   为什么不用 :hover 的 CSS 变换就够了：
   纯 CSS 只能做"进/出"两态，做不出惯性、自动摆动、拖拽、双击复位，
   也做不出"只在视口内才动"。这些是文档里那个 ModelViewer 的全部内容，
   所以这里用一小段脚本按同样的参数移植了一遍。               */

.depth-stage {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  perspective: 560px;    /* 视点越近，透视的形变越明显；820 时几乎看不出来 */
  /* 竖向手势留给页面滚动，只有横向拖动才转图形——否则手机上没法翻页 */
  touch-action: pan-y;
  cursor: grab;
}

.depth-stage.is-grab { cursor: grabbing; }

/* 悬浮层本身就是一张"可见的卡"。
   为什么必须给它一圈可见的边：产品图是白底的整块矩形，而卡片底色是
   --soft #f5f8fb，两者亮度只差 3%——矩形转 14° 时那条边根本看不见，
   眼睛读到的还是一张平图。给它白底 + 一道极淡的描边 + 投影之后，
   转动的是一张有边缘的物体，梯形的边立刻可读。
   描边压到 8% 黑：只在转起来时提供边界，静止时几乎察觉不到。 */
.depth-lift {
  position: relative;
  z-index: 1;
  display: block;
  width: 100%;
  height: 100%;
  transform-style: preserve-3d;
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 10px -6px rgba(10, 24, 38, 0.5);
}

.depth-lift::after {
  content: "";
  position: absolute;
  inset: 0;
  border: 1px solid rgba(14, 22, 33, 0.09);
  border-radius: inherit;
  pointer-events: none;
}

/* .thumb 是 overflow:hidden 的 16:9 框，影子放在框内下沿才不会被裁掉 */
.depth-shadow {
  position: absolute;
  z-index: 0;
  left: 14%;
  right: 14%;
  bottom: 4%;
  height: 12%;
  border-radius: 50%;
  background: radial-gradient(50% 50% at 50% 50%,
    rgba(10, 24, 38, 0.62) 0%, rgba(10, 24, 38, 0) 72%);
  filter: blur(8px);
  pointer-events: none;
  opacity: 0;
}

/* 详情页主图那一类没有 overflow 裁剪，影子可以坐得更低一点、更散一点 */
.product-shot .depth-shadow {
  left: 10%;
  right: 10%;
  bottom: 2%;
  height: 10%;
  filter: blur(10px);
}

/* 高光：平面物体最有力的立体线索。
   一张照片转 14° 时，几何形变只有几个百分点，眼睛未必读得出来；
   但"一道光随着转动在表面扫过去"是大脑判断曲面/立体的强信号。
   这层就是那道光——不转时几乎看不见，转起来才亮。 */
.depth-sheen {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  opacity: 0;
  background: linear-gradient(112deg,
    rgba(255, 255, 255, 0) 26%,
    rgba(255, 255, 255, 0.55) 47%,
    rgba(255, 255, 255, 0.12) 56%,
    rgba(255, 255, 255, 0) 70%);
  mix-blend-mode: screen;
}

/* 打印时不保留任何摆动的痕迹 */
@media print {
  .depth-lift { transform: none !important; opacity: 1 !important; }
  .depth-shadow { display: none; }
}

/* ---------- 选中态与互动反馈 ----------
   参考配色是"绯红 / 藏蓝"两张平涂色，所以反馈也走平涂路线：
   不发光、不渐变、不模糊，只做三件事——换到绯红、长出来、沉下去。
   全部都有 :focus-visible 的对应写法，键盘用户拿到的是同一套反馈。   */

/* 选中文字：整块翻成绯红底白字。
   半透明底色在深色区块上会读不清，实心平涂才是这套配色的脾气。 */
::selection { background: var(--crimson); color: #fff; }

/* 正文链接：下划线从左侧扫出来，而不是"凭空出现"。
   原来的 text-decoration 一出现就是整条，跳动感很强。 */
main p a:not(.btn),
main li a:not(.btn) {
  text-decoration: none;
  background-image: linear-gradient(var(--crimson), var(--crimson));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0% 1px;
  transition: background-size 0.28s cubic-bezier(0.4, 0, 0.2, 1), color 0.18s ease;
}
main p a:not(.btn):hover,
main li a:not(.btn):hover,
main p a:not(.btn):focus-visible,
main li a:not(.btn):focus-visible { background-size: 100% 1px; }

/* 表格行：整行染一层绯红极淡的底，比只改文字色更容易追踪游标 */
tbody tr { transition: background-color 0.15s ease; }
tbody tr:hover { background: var(--accent-soft); }

/* 卡片：悬停时边框转绯红（原来转的是蓝灰，看不出"被选中"） */
.card, .product-card, .fact-box, .answer-box {
  transition: border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s var(--ease);
}
.card:hover, .product-card:hover { border-color: var(--crimson-ink); }

/* 环廊：转到正面的那张 = 当前选中项，给一道绯红内描边 + 绯红标题。
   之前只有一圈黑框，选中和未选中在深色背景上差别很小。 */
[data-ring-on] .ring-card[data-active] .ring-plate {
  border-color: var(--crimson);
  box-shadow:
    0 0 0 2px rgba(228, 23, 38, 0.35),
    0 22px 34px -18px rgba(9, 32, 46, 0.66);
}
.ring-caption b { color: var(--ink); }
[data-ring-on] .ring-shell:hover .ring-caption b { color: var(--crimson-ink); }

/* 表单：聚焦时一圈绯红光晕，代替原来的实心描边，
   光晕不会改变盒子尺寸，不会让表单在聚焦瞬间抖一下 */
input:focus-visible,
textarea:focus-visible,
select:focus-visible {
  outline: none;
  border-color: var(--crimson);
  box-shadow: 0 0 0 3px rgba(228, 23, 38, 0.18);
}

/* 导航当前项：下划线从左侧长出（原来一进来就是整条） */
.nav a[aria-current="page"]::after {
  transform: scaleX(0);
  transform-origin: left center;
  animation: nav-underline-in 0.32s cubic-bezier(0.4, 0, 0.2, 1) forwards;
}

@keyframes nav-underline-in {
  to { transform: scaleX(1); }
}

/* 口味胶囊：悬停翻成绯红底白字，扫读时手指（或鼠标）有落点 */
.chip {
  transition: background-color 0.16s ease, color 0.16s ease, border-color 0.16s ease;
}
.chip:hover { background: var(--crimson); color: #fff; border-color: var(--crimson); }

/* 目录 / 跳到顶部这一类小控件：悬停时图标也跟着动一点 */
.to-top { transition: background-color 0.18s ease, transform 0.18s var(--ease); }
.to-top:hover { background: var(--crimson); color: #fff; transform: translateY(-2px); }

/* 系统开启"减少动效"时，保留颜色反馈但取消所有位移与扫过 */
@media (prefers-reduced-motion: reduce) {
  .btn, .chip, .to-top, tbody tr, .card, .product-card { transition: none; }
  .btn:active { transform: none; }
  .to-top:hover { transform: none; }
  .nav a[aria-current="page"]::after { animation: none; transform: scaleX(1); }
  main p a:not(.btn), main li a:not(.btn) { transition: none; }
}

/* ---------- 首屏文字滑动切换 + 数据带 ---------- */

/* 那行会滑动切换的文案：5 格竖排（4 条 + 第 1 条的副本），
   track 一格一格往上推，推到第 5 格时画面与第 1 格完全相同，
   循环因此无缝。高度写死 1.7em：只有"一格高"的窗口才能让
   上下相邻的两条被干净地切掉，不会露出半行。 */
.hero-ticker {
  height: 1.7em;
  margin: 0 0 12px;
  overflow: hidden;
  font-size: 14px;
  line-height: 1.7em;
}

.hero-ticker-track {
  display: block;
  animation: ticker 12s cubic-bezier(0.65, 0, 0.35, 1) infinite;
}

.hero-ticker b {
  display: block;
  height: 1.7em;
  font-weight: 600;
  color: var(--crimson);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 每条前面一个小方块：参考图里的"色块"感，也当作这条在切换的锚点 */
.hero-ticker b::before {
  content: "";
  display: inline-block;
  width: 6px;
  height: 6px;
  margin-right: 9px;
  vertical-align: 2px;
  background: var(--crimson);
}

@keyframes ticker {
  0%,   20%  { transform: translateY(0); }
  25%,  45%  { transform: translateY(-1.7em); }
  50%,  70%  { transform: translateY(-3.4em); }
  75%,  100% { transform: translateY(-5.1em); }
}

/* 数据带：藏蓝底 + 绯红数字，对应参考图下半那块藏蓝。
   数字用 tabular-nums：滚动时字宽不能跳，否则整行会左右抖。 */
.stat-band {
  background: var(--navy);
  padding: 52px 0;
  margin-top: 46px;
}

.stat-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 28px;
}

.stat { text-align: center; }

.stat b {
  display: block;
  font-size: clamp(34px, 4.4vw, 54px);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.01em;
  color: var(--crimson);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

.stat span {
  display: block;
  margin-top: 8px;
  font-size: 13px;
  color: rgba(255, 255, 255, 0.62);
}

@media (max-width: 760px) {
  .stat-band { padding: 38px 0; }
  .stat-grid { grid-template-columns: repeat(2, 1fr); gap: 24px 16px; }
}

/* 减少动效：文字停在第一条，数字保持最终值（脚本也不跑） */
@media (prefers-reduced-motion: reduce) {
  .hero-ticker-track { animation: none; }
}

/* ==========================================================================
   背景色与展示带修正层（2026-11-02 第二轮）
   --------------------------------------------------------------------------
   用户反馈：主界面图片太单调、整站背景没颜色、部分图片裁剪/排版歪。
   三件事在这里一起收口：
     1. 全站 body 底色已在前一层压成 #ecf0f8（带蓝味的浅灰）；
     2. 首页 3D 环廊改成藏蓝深色展示带，白卡 + 黑边在深底上才"跳"出来；
     3. 环卡图片加统一内边距 + contain，产品不再顶边、不再被裁。
   ========================================================================== */

/* ---------- 首页环廊：深色展示带 ---------- */

.ring-band--home {
  padding: 50px 0 46px;
  /* 环卡淡出("远景雾化")的颜色：深底上若还往白里淡，会像发霉；
     往藏蓝里淡才是"沉进背景"。变量由 .ring-shade 读取。 */
  --ring-fade-color: #05052e;
  background:
    radial-gradient(46% 74% at 84% 2%, rgba(228, 23, 38, 0.22), transparent 60%),
    radial-gradient(40% 60% at 4% 100%, rgba(228, 23, 38, 0.12), transparent 62%),
    linear-gradient(180deg, #06063a 0%, #01012b 54%, #13134e 100%);
}

.ring-band--home .ring-caption b { color: #fff; }
.ring-band--home .ring-caption span { color: rgba(255, 255, 255, 0.66); }
.ring-band--home .ring-hint { color: rgba(255, 255, 255, 0.55); }

/* 深底上地面阴影改用纯黑：原来的藏蓝灰阴影会消失 */
.ring-band--home .ring-shell::after {
  background: radial-gradient(ellipse at center,
    rgba(0, 0, 8, 0.60) 0%, rgba(0, 0, 8, 0.24) 45%, rgba(0, 0, 8, 0) 72%);
}

/* 筒内壁也压成深色：从缝隙看过去是"暗筒"，不是一块亮补丁 */
.ring-band--home .ring-back {
  background: linear-gradient(180deg, #20206a, #151552);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.07);
}

/* 环带和数据带直接相连：收掉 46px 浅色缝，用一道细线分层 */
.stat-band { margin-top: 0; border-top: 1px solid rgba(255, 255, 255, 0.08); }

/* ---------- 环卡图片：统一内边距，不再顶边 ---------- */

/* 平面卡（curve=0）才安全：弧面切片按整卡坐标定位，加内边距会错位，
   所以 ring.js 在弧面分支会挂 .ring-curved，这里只对平面卡生效。
   contain + 内边距 = 每台设备四周留同样的白边，视觉重量一致。 */
[data-ring]:not(.ring-curved) .ring-frame img {
  box-sizing: border-box;
  padding: 4.6%;
  object-fit: contain;
}

/* ---------- 数据带文字在深底上的层级 ---------- */

.stat span { color: rgba(255, 255, 255, 0.62); }

/* ==========================================================================
   全站色彩节奏层（2026-11-02 第三轮）
   --------------------------------------------------------------------------
   上一轮只给首页环廊和 body 铺了色，其余 400 多个正文 <section> 仍是白底，
   内页打开还是一片白。这一层把"有颜色"扩展到全站：

   · 5 组雾色按 section 顺序轮换：绯红雾 / 藏蓝雾 / 紫雾 / 金雾 / 白蓝雾，
     都是同一色相环（红—紫—蓝）内的邻近色 + 一点铜金，不引入外来色系。
   · 每块再叠两处柔和光斑（radial-gradient），背景不是平涂色块，
     而是"有光源的纸面"，比单纯换底色耐看。
   · 所有雾色明度 ≥ 94%，正文 #35355f 在其上对比度仍 > 8:1，不影响可读性。
   · 内页头部单独给一条绯红→紫→蓝的渐变带，第一屏就有颜色。
   · 强色块（hero 深色板 / 环廊深带 / 数据带 / 红色报价区 / 页脚）保持不变，
     它们是节奏里的重音；雾色是弱拍，不抢戏。
   ========================================================================== */

:root {
  --mist-rose:  #fdf1f3;   /* 绯红雾 */
  --mist-blue:  #eaf0fb;   /* 藏蓝雾 */
  --mist-lilac: #f2effb;   /* 红蓝之间的紫雾 */
  --mist-gold:  #fbf5ea;   /* 铜金雾，呼应开屏那道铜线 */
  --mist-mint:  #e9f6f5;   /* 蓝绿之间的极淡青雾 */
}

/* 正文区块：5 色轮换 + 两处光斑。
   :not() 排除自带强背景的块；nth-of-type 计数包含它们，所以各页相位不同，
   翻页时不会每页都从同一块颜色开始——这正是"不要单调"。 */
main > section:not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head) {
  --sec-a: #ffffff;
  --sec-b: #ffffff;
  --sec-glow: transparent;
  --sec-glow2: transparent;
  background:
    radial-gradient(56% 72% at 92% 2%, var(--sec-glow), transparent 64%),
    radial-gradient(46% 64% at 0% 100%, var(--sec-glow2), transparent 62%),
    linear-gradient(168deg, var(--sec-a) 0%, var(--sec-b) 100%);
}

/* 1 · 绯红雾 → 紫雾 */
main > section:nth-of-type(5n+1):not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head) {
  --sec-a: var(--mist-rose);
  --sec-b: #f7eefb;
  --sec-accent: var(--crimson);
  --sec-glow: rgba(228, 23, 38, 0.13);
  --sec-glow2: rgba(0, 0, 53, 0.07);
}
/* 2 · 蓝雾 → 青雾 */
main > section:nth-of-type(5n+2):not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head) {
  --sec-a: var(--mist-blue);
  --sec-b: var(--mist-mint);
  --sec-accent: var(--navy);
  --sec-glow: rgba(0, 0, 53, 0.10);
  --sec-glow2: rgba(228, 23, 38, 0.06);
}
/* 3 · 紫雾 → 近白 */
main > section:nth-of-type(5n+3):not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head) {
  --sec-a: var(--mist-lilac);
  --sec-b: var(--mist-rose);
  --sec-accent: #6b3fa0;
  --sec-glow: rgba(0, 0, 53, 0.09);
  --sec-glow2: rgba(228, 23, 38, 0.08);
}
/* 4 · 金雾 → 玫瑰雾（暖一档，缓和红蓝冷调） */
main > section:nth-of-type(5n+4):not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head) {
  --sec-a: var(--mist-gold);
  --sec-b: var(--mist-rose);
  --sec-accent: #b8862f;
  --sec-glow: rgba(228, 23, 38, 0.10);
  --sec-glow2: rgba(0, 0, 53, 0.06);
}
/* 5 · 青雾 → 紫雾（不留纯白段：长表格区也要有底色） */
main > section:nth-of-type(5n+5):not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head) {
  --sec-a: var(--mist-mint);
  --sec-b: var(--mist-lilac);
  --sec-accent: #147d78;
  --sec-glow: rgba(228, 23, 38, 0.08);
  --sec-glow2: rgba(0, 0, 53, 0.08);
}

/* ---------- 内页头部：第一屏就有颜色 ---------- */

.page-head {
  padding: 52px 0 34px;
  border-bottom: 1px solid rgba(0, 0, 53, 0.07);
  background:
    radial-gradient(42% 110% at 96% 0%, rgba(228, 23, 38, 0.12), transparent 62%),
    radial-gradient(38% 96% at 0% 100%, rgba(0, 0, 53, 0.07), transparent 60%),
    linear-gradient(118deg, var(--mist-rose) 0%, var(--mist-lilac) 48%, var(--mist-blue) 100%);
}
/* H1 下面一小段绯红，给每个内页一个统一的"起手式" */
.page-head h1::after {
  content: "";
  display: block;
  width: 46px;
  height: 3px;
  margin-top: 14px;
  border-radius: 2px;
  background: var(--crimson);
}

/* ---------- 产品页环廊（浅色带）：也带上色 ---------- */

.ring-band:not(.ring-band--home) {
  background:
    radial-gradient(44% 72% at 90% 0%, rgba(228, 23, 38, 0.10), transparent 62%),
    radial-gradient(38% 64% at 0% 100%, rgba(0, 0, 53, 0.06), transparent 60%),
    linear-gradient(180deg, var(--mist-lilac) 0%, var(--mist-rose) 100%);
}

/* ---------- 彩色底上的白卡 / 提示块：浮起来，不糊在一起 ---------- */

/* 目录框：原来是 var(--soft)，和雾色只差 1%，会看不出边界 */
.toc {
  background: #fff;
  border-color: rgba(0, 0, 53, 0.10);
  box-shadow: var(--shadow-1);
}
/* 提示块同理；警示块保留一点绯红，但从"整块粉"改成"从粉到白的渐变" */
.callout {
  background: #fff;
  border-color: rgba(0, 0, 53, 0.10);
  box-shadow: var(--shadow-1);
}
.callout.warn {
  border-left-color: var(--crimson);
  background: linear-gradient(90deg, var(--accent-soft) 0%, #fff 62%);
}

/* FAQ：一排细线改成一张张浮起来的白卡，列表不再是一整片白 */
.faq-item {
  background: rgba(255, 255, 255, 0.78);
  border: 1px solid rgba(0, 0, 53, 0.075);
  border-radius: 12px;
  padding: 20px 24px;
  margin-bottom: 12px;
}
.faq-item:first-of-type { border-top: 1px solid rgba(0, 0, 53, 0.075); }
@media (max-width: 560px) { .faq-item { padding: 16px 18px; } }

/* 表格容器：白底 + 阴影，在雾色底上是明确的"一张纸" */
.table-wrap { box-shadow: var(--shadow-2); }

/* ---------- 标题色条：每个区块一个小色标，颜色跟着该块的相位走 ----------
   只取"区块标题"（.section-head 里的 h2、以及 container 直接下的 h2），
   不碰 FAQ 问句、卡片标题，避免整页到处都是色条。 */
main > section:not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head) .section-head h2,
main > section:not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head) > .container > h2 {
  position: relative;
  padding-left: 17px;
}
main > section:not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head) .section-head h2::before,
main > section:not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head) > .container > h2::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.16em;
  width: 5px;
  height: 0.92em;
  border-radius: 3px;
  background: var(--sec-accent, var(--crimson));
  opacity: 0.85;
}

/* ---------- 导航底部一道红蓝双色线：全站每页都有的细节点缀 ---------- */
.site-header { border-bottom-color: rgba(0, 0, 53, 0.10); }
.site-header::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 2px;
  pointer-events: none;
  background: linear-gradient(90deg,
    var(--crimson) 0 13%, var(--navy) 13% 26%, transparent 26%);
  opacity: 0.55;
}

/* ---------- 表格：长参数区不能再是一整片白 ----------
   首页那张 33 行总览表是页面最长的一段，纯白 + 细线读起来很平。
   用藏蓝表头当一次"重音"，配淡绯红斑马纹和雾色 caption，
   颜色仍只在绯红/藏蓝体系内，不引入新色。 */
table caption {
  background: linear-gradient(90deg, var(--mist-rose) 0%, #fff 72%);
  border-bottom-color: rgba(0, 0, 53, 0.07);
  color: var(--ink-2);
  font-weight: 500;
}
thead th {
  background: linear-gradient(90deg, #08083a 0%, #1c1c5e 100%);
  color: #fff;
  border-bottom: 0;
  font-weight: 600;
}
/* 表格行：淡绯红斑马纹，浓度要够肉眼分得清，否则长表还是一片白 */
tbody tr:nth-child(even) { background: rgba(228, 23, 38, 0.06); }
/* 无 thead 的规格表：左侧行标题给一层淡藏蓝雾，读出"两列"结构 */
th[scope="row"] { background: rgba(0, 0, 53, 0.028); }

/* ---------- 收尾：页脚小字在藏蓝底上提亮一档 ---------- */
.footer-legal { color: rgba(255, 255, 255, 0.64); }
.site-footer a { color: rgba(255, 255, 255, 0.86); }
.site-footer a:hover { color: #fff; text-decoration-color: var(--crimson); }

/* ==========================================================================
   360° 产品展示台（详情页主图，先用于 Stratovape-038）
   --------------------------------------------------------------------------
   这一块刻意"没有颜色"：产品帧本身是透明 PNG，容器无背景、无边框、无内边距，
   原来的粉底产品图 + 白底卡片（.product-shot）整套去掉，产品直接浮在页面上。
   立体感来自 6 个真实角度 + 拖拽时的 rotateY 补间、透视、俯仰和地面阴影。
   无 JS 时只显示第一帧，就是一张普通的 <img>。
   ========================================================================== */

.spin360 {
  position: relative;
  width: 100%;
  aspect-ratio: 3 / 4;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 0;
  padding: 0;
  margin: 0;
  cursor: grab;
  touch-action: pan-y;
  user-select: none;
  -webkit-user-select: none;
  --spin-tilt: 0;
}
.spin360:active { cursor: grabbing; }
.spin360:focus-visible {
  outline: 2px solid var(--crimson);
  outline-offset: 4px;
  border-radius: 12px;
}

.spin360-stage {
  position: relative;
  width: 100%;
  height: 100%;
  perspective: 1200px;
  transform-style: preserve-3d;
}

.spin360-frame {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  -webkit-user-drag: none;
  pointer-events: none;
}
.spin360-frame[hidden] { display: none; }

/* 接管后所有帧叠在同一位置，只显示离当前角度最近的一张 */
[data-spin-on] .spin360-frame {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 0.14s linear;
}
[data-spin-on] .spin360-frame[data-current] { opacity: 1; }

/* 地面接触阴影：转动时略微变淡，给"物体在转"一个物理线索 */
.spin360-shadow {
  position: absolute;
  left: 50%;
  bottom: 6%;
  width: 46%;
  height: 5%;
  transform: translateX(-50%);
  border-radius: 50%;
  background: radial-gradient(ellipse at center,
    rgba(6, 10, 40, 0.20) 0%, rgba(6, 10, 40, 0.07) 55%, rgba(6, 10, 40, 0) 72%);
  filter: blur(6px);
  pointer-events: none;
  opacity: calc(0.92 - var(--spin-tilt) * 0.28);
}

.spin360-hint {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 2px;
  margin: 0;
  text-align: center;
  font-size: 12px;
  color: var(--muted);
  pointer-events: none;
}
.spin360-reset {
  position: absolute;
  right: 4px;
  top: 4px;
  z-index: 2;
  padding: 6px 12px;
  font: inherit;
  font-size: 12px;
  color: var(--ink);
  background: rgba(255, 255, 255, 0.9);
  border: 1px solid var(--edge);
  border-radius: 999px;
  cursor: pointer;
}
.spin360-reset:hover { border-color: var(--crimson); color: var(--crimson); }
.spin360-reset[hidden] { display: none; }
.spin360-live {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* 主图区单独收干净：去掉上一轮那团粉色斜切光斑和参数行的粉色底，
   让透明产品图不被彩色块干扰。其它页面的色彩节奏保持不变。
   选择器要带上和前面 5 色轮换规则同等数量的 :not()，否则特异性不够会被压过。 */
main > section:not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head):has(.spin360) {
  --sec-a: #ffffff;
  --sec-b: #ffffff;
  --sec-glow: transparent;
  --sec-glow2: transparent;
  background: #fff;
}
main > section:has(.spin360) tbody tr:nth-child(even) { background: transparent; }
main > section:has(.spin360) th[scope="row"] { background: transparent; }
main > section:has(.spin360) table caption { background: #fff; }

@media (prefers-reduced-motion: reduce) {
  [data-spin-on] .spin360-frame { transition: none; }
}

/* ==========================================================================
   公司信息独立带（修"产品展示图跟公司介绍重叠"）
   --------------------------------------------------------------------------
   原来「公司信息」是 hero 右列的一块半透明磨砂卡，产品背景板从它背后透出来；
   窄屏（761–980px）hero 变单列后，卡片和标题还会直接压在产品图上。
   现在把卡片移出 hero，单独成一条浅色带：首屏只留文字 + 右侧产品图，
   两者在任何宽度下都不再叠放。
   ========================================================================== */

/* 选择器带上与 7.10 五组轮换同等数量的 :not()，才能压过它的雾色 + 光斑 */
main > section.fact-band:not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head) {
  --sec-glow: transparent;
  --sec-glow2: transparent;
  padding: 40px 0;
  background: linear-gradient(180deg, #fdf1f3 0%, #f2effb 100%);
}
.fact-band .container { display: flex; justify-content: center; }
.fact-band .fact-box {
  width: 100%;
  max-width: 820px;
  padding: 26px 30px;
  background: #fff;
  border-color: rgba(0, 0, 53, 0.10);
  border-radius: 14px;
  box-shadow: var(--shadow-2);
}
/* 7 项参数排成两列，别让这条带子变成一长条竖列表 */
.fact-band .fact-box dl {
  grid-template-columns: max-content 1fr max-content 1fr;
  gap: 10px 22px;
}
@media (max-width: 760px) {
  main > section.fact-band:not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head) { padding: 28px 0; }
  .fact-band .fact-box { padding: 20px; }
  .fact-band .fact-box dl { grid-template-columns: max-content 1fr; }
}

/* hero 右列现在故意留空给产品图：文字列宽度由 1.15fr 决定，
   产品板靠右对齐，两者中间由 hero-media::after 的白色渐隐隔开。 */
.hero-grid > div:first-child { max-width: 62ch; }

/* ==========================================================================
   全站深蓝渐变背景层（2026-11-02 第八轮 · 用户选「深蓝底＋白卡」）
   --------------------------------------------------------------------------
   4 张截图里的浅粉 / 浅紫 / 浅金雾色区块全部换成「深蓝 → 淡蓝」渐变：
     · 每块两处光斑（左上深蓝、右下淡蓝）+ 一道 142°~170° 的深蓝→淡蓝渐变；
       角度按 5 组相位微调，翻页有节奏，但不再出现红/紫/金/青等外来色系。
     · 区块标题、说明、小字反白；白卡 / 表格 / FAQ / 提示块保持白底深字，
       浮在蓝上 —— 内容可读性不靠"整页变深"去赌。
     · 只动颜色，HTML 结构与文本零改动，AI 抓取不受影响。
   本层放在文件最末；选择器 :not() 数量与 7.10 轮换层一致，后写覆盖。
   ========================================================================== */

:root {
  --blue-0: #00123a;    /* 深藏蓝 */
  --blue-1: #06245f;
  --blue-2: #103b8c;
  --blue-3: #2a68bd;
  --blue-4: #5a97d8;
  --blue-5: #86b6ee;    /* 淡蓝 */
  --on-blue: #ffffff;
  --on-blue-2: rgba(255, 255, 255, 0.78);
  --on-blue-link: #ff4757;   /* 深底上的链接色：原来是浅粉 #ffadb4，按要求统一改红 */
  --paper-blue: #f2f7ff;
}

body { background: var(--blue-0); }

/* ---------- 1. 正文区块：统一深蓝 → 淡蓝 ---------- */
main > section:nth-of-type(n):not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head) {
  --sec-glow: transparent;
  --sec-glow2: transparent;
  --sec-accent: #ff4757;
  --bg-angle: 158deg;
  color: var(--on-blue);
  background:
    radial-gradient(56% 76% at 92% 2%, rgba(0, 8, 34, 0.60), transparent 64%),
    radial-gradient(48% 66% at 2% 100%, rgba(170, 210, 255, 0.18), transparent 62%),
    linear-gradient(var(--bg-angle),
      var(--blue-0) 0%, var(--blue-1) 26%, var(--blue-2) 55%,
      var(--blue-3) 80%, var(--blue-5) 100%);
}
/* 相位只改渐变角度，色阶始终同一套蓝 */
main > section:nth-of-type(5n+1):not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head) { --bg-angle: 148deg; }
main > section:nth-of-type(5n+2):not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head) { --bg-angle: 170deg; }
main > section:nth-of-type(5n+3):not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head) { --bg-angle: 156deg; }
main > section:nth-of-type(5n+4):not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head) { --bg-angle: 166deg; }
main > section:nth-of-type(5n+5):not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head) { --bg-angle: 142deg; }

main > section + section { border-top-color: rgba(255, 255, 255, 0.10); }

/* ---------- 2. 裸露在深蓝底上的文字：反白 ----------
   只取 .section-head 内与 .container 直接子级，白卡里的同名元素不在此路径上，
   不会被误改成白底白字。 */
main > section:nth-of-type(n):not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head) .section-head :is(h2, h3, h4, p, .answer, .eyebrow, .updated, small, .small, li),
main > section:nth-of-type(n):not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head) > .container > :is(h2, h3, h4, p, ul, ol, li, blockquote, .answer, .eyebrow, .updated, small, .small) {
  color: var(--on-blue);
  text-shadow: 0 1px 12px rgba(0, 10, 36, 0.42);
}
main > section:nth-of-type(n):not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head) .answer {
  border-left-color: rgba(255, 71, 87, 0.85);
}
main > section:nth-of-type(n):not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head) > .container a:not(.btn),
main > section:nth-of-type(n):not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head) .section-head a:not(.btn) {
  color: var(--on-blue-link);
}

/* ---------- 3. 白底内容块：内部文字恢复深色 ----------
   .btn / .chip / .num 等有自身配色规则，故意不列入，免得被覆盖。 */
main > section :is(.card, .product-card, .toc, .callout, .faq-item,
  .table-wrap, .fact-box, .spec-table, .ring-card, .range-card,
  .product-shot, .thumb, .thumb-sm, .shot, .steps, .guide, .quote-box) {
  color: var(--ink-2);
}

/* ---------- 4. 内页头部 ---------- */
.page-head {
  color: var(--on-blue);
  border-bottom-color: rgba(255, 255, 255, 0.12);
  background:
    radial-gradient(42% 110% at 96% 0%, rgba(228, 23, 38, 0.18), transparent 62%),
    radial-gradient(38% 96% at 0% 100%, rgba(0, 6, 28, 0.52), transparent 60%),
    linear-gradient(118deg, var(--blue-0) 0%, var(--blue-1) 44%, var(--blue-3) 100%);
}
.page-head :is(h1, p, .eyebrow, .updated, .meta, .crumbs, small, .small) { color: var(--on-blue); }
.page-head a:not(.btn) { color: var(--on-blue-link); }

/* ---------- 5. 产品页环廊 / 公司信息带：并入蓝调 ---------- */
.ring-band:not(.ring-band--home) {
  color: var(--on-blue);
  background:
    radial-gradient(44% 72% at 90% 0%, rgba(228, 23, 38, 0.16), transparent 62%),
    linear-gradient(180deg, var(--blue-0) 0%, var(--blue-1) 56%, var(--blue-2) 100%);
}
.ring-band:not(.ring-band--home) :is(.ring-caption b, .ring-caption span, .ring-hint) {
  color: var(--on-blue);
}
.ring-band:not(.ring-band--home) .ring-caption span,
.ring-band:not(.ring-band--home) .ring-hint { color: var(--on-blue-2); }

main > section.fact-band:not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head) {
  color: var(--on-blue);
  background: linear-gradient(180deg, var(--blue-1) 0%, var(--blue-3) 100%);
}

/* ---------- 6. 蓝调细节 ---------- */
table caption {
  background: linear-gradient(90deg, var(--paper-blue) 0%, #fff 72%);
  color: var(--ink-2);
}
th[scope="row"] { background: rgba(16, 59, 140, 0.045); }
/* Stratovape-038 的 360° 展示台要干净底，用极淡蓝白，不再是一块突兀的纯白 */
main > section:not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head):has(.spin360) {
  background: var(--paper-blue);
}

/* ---------- 7. 顶部导航：深蓝玻璃，不再留一条白条割裂 ---------- */
.site-header {
  background: rgba(0, 18, 58, 0.88);
  border-bottom-color: rgba(255, 255, 255, 0.14);
}
.site-header :is(.logo b, .logo span, .nav a, .lang, .menu a) { color: #fff; }
.site-header .logo span { color: var(--on-blue-2); }
.site-header .nav a:hover { background: rgba(255, 255, 255, 0.10); color: #fff; }
.site-header .nav a[aria-current="page"] {
  color: var(--on-blue-link);
  background: rgba(255, 255, 255, 0.10);
}
.site-header .lang { border-color: rgba(255, 255, 255, 0.30); }
.site-header::after { opacity: 0.9; }

/* ---------- 9. 表格条纹：淡绯红 → 淡蓝，白卡不再"发粉" ---------- */
tbody tr:nth-child(even) { background: rgba(16, 59, 140, 0.055); }

/* ---------- 10. 收尾：深蓝底上残留的深色字 ----------
   探针发现有些标题/表单文字不在 .section-head 也不在 .container 直接子级
   （about 的 h2 嵌在 hero-grid 的 div 里、询盘表单的 label/legend），
   前面的白字规则够不着。这里先给裸露文字兜底变白，再把白卡内部恢复深色。 */
main > section:not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head) :is(h2, h3, h4, p, label, legend, small, .small, dt, dd, blockquote, figcaption, .field-hint, .meta, .updated) {
  color: var(--on-blue);
}
main > section:not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head) :is(.card, .product-card, .toc, .callout, .faq-item, .table-wrap, .fact-box, .spec-table, .ring-card, .range-card, .product-shot, .thumb, .thumb-sm, .shot, .steps, .inquiry-form, figure.photo) :is(h2, h3, h4, p, label, legend, small, .small, dt, dd, blockquote, figcaption, .field-hint, .meta, .updated) {
  color: var(--ink-2);
}
/* 面包屑在 section 之外，直接落在 body 的深蓝底上 */
.crumbs, .crumbs ol, .crumbs li { color: var(--on-blue-2); }
.crumbs a { color: var(--on-blue-link); }
/* 询盘表单整块做成白卡：label / legend / 提示文字在白底上恢复深色，
   输入框也不再散落在深蓝里。 */
.inquiry-form {
  background: #fff;
  border: 1px solid var(--card-edge);
  border-radius: 16px;
  padding: 26px 28px;
  box-shadow: var(--shadow-2);
}
@media (max-width: 760px) { .inquiry-form { padding: 18px; } }

/* ---------- 11. 两处收尾 ----------
   ① 首屏"最后更新/作者"里的链接原本是深墨色，反白后在深蓝上看不见；
   ② 公司信息带压深一档，和上方首屏、下方环廊的明度台阶收平。 */
main > section:not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head) .updated a,
.page-head .updated a { color: var(--on-blue-link); }
main > section:not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head) :is(.card, .product-card, .toc, .callout, .faq-item, .table-wrap, .fact-box, .inquiry-form) .updated a { color: var(--ink-2); }
main > section.fact-band:not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head) {
  background: linear-gradient(180deg, var(--blue-0) 0%, var(--blue-1) 55%, var(--blue-2) 100%);
}

/* ==========================================================================
   含产品图区块：紫色 → 蓝色渐变（2026-11-02 第十一轮）
   --------------------------------------------------------------------------
   用户三张截图里的产品卡区 / 整条产品线带等「图片部分」背景，
   从第八轮的「深蓝→淡蓝」换成「紫→蓝」；纯文字区块、导航、页脚、
   首屏、环廊、数据带一律保持原样。

   命中条件用 :has(img) 客观判定「含产品图」，:not(:has(.spin360)) 把
   JEC-038 的 360° 展示台排除（它要极淡蓝白干净底，见第 6 节）。
   沿用第 1 节的 --bg-angle 相位，5 组区块仍有节奏、不千篇一律。
   :not() 数量与第 1 节一致，再加 :has() 提高特异性，后写覆盖。
   ========================================================================== */

:root {
  --violet-0: #2b0a5c;   /* 深紫起点 */
  --violet-1: #4b1596;   /* 紫 */
  --violet-2: #3a3ab5;   /* 蓝紫过渡 */
  --violet-3: #2a5cc0;   /* 蓝 */
}

main > section:nth-of-type(n):not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head):has(img):not(:has(.spin360)) {
  background:
    radial-gradient(56% 76% at 92% 2%, rgba(24, 4, 62, 0.58), transparent 64%),
    radial-gradient(48% 66% at 2% 100%, rgba(170, 210, 255, 0.18), transparent 62%),
    radial-gradient(38% 52% at 4% 34%, rgba(146, 70, 226, 0.16), transparent 70%),
    linear-gradient(var(--bg-angle, 158deg),
      var(--violet-start, var(--violet-0)) 0%, var(--violet-1) 24%, var(--violet-2) 50%,
      var(--violet-3) 76%, var(--blue-5) 100%);
}

/* 紫底上的区块标题色条同步换成淡紫，和背景同一色系；白卡内部不受影响 */
main > section:nth-of-type(n):not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head):has(img):not(:has(.spin360)) {
  --sec-accent: #c9a3ff;
}

/* 5 组相位的紫色起点拉开差异：连续的产品线区块不会连成一片，
   有的偏深紫、有的偏品红紫、有的偏蓝紫，但终点都收在同一套蓝。 */
main > section:nth-of-type(5n+1):not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head):has(img):not(:has(.spin360)) { --violet-start: #2b0a5c; }
main > section:nth-of-type(5n+2):not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head):has(img):not(:has(.spin360)) { --violet-start: #45107a; }
main > section:nth-of-type(5n+3):not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head):has(img):not(:has(.spin360)) { --violet-start: #1c0949; }
main > section:nth-of-type(5n+4):not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head):has(img):not(:has(.spin360)) { --violet-start: #521486; }
main > section:nth-of-type(5n+5):not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head):has(img):not(:has(.spin360)) { --violet-start: #241272; }

/* 紫→蓝渐变上标题的可读性兜底：渐变较亮处白字容易发虚，
   叠一层深色柔光阴影，不改背景、不影响白卡内部文字。 */
main > section:nth-of-type(n):not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head):has(img):not(:has(.spin360)) .section-head :is(h2, h3, h4, p, .answer, .eyebrow, small, li),
main > section:nth-of-type(n):not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head):has(img):not(:has(.spin360)) > .container > :is(h2, h3, h4, p, li, blockquote, .answer, .eyebrow, small) {
  text-shadow: 0 1px 10px rgba(8, 2, 30, 0.72), 0 2px 22px rgba(8, 2, 30, 0.46);
}

/* ==========================================================================
   第十二轮（2026-11-03）：除首页外，全站内页统一「紫 → 蓝」渐变
   --------------------------------------------------------------------------
   判定：首页 <main> 的第一个子级是 <section class="hero">，内页没有这个节点，
   所以用 body:not(:has(main > .hero)) 精确圈定内页 —— 首页（首屏、环廊、
   数据带、六款卡区）一格不动，内页的正文区块 / 内页头部 / 产品环廊 /
   公司信息带 / 含产品图区块全部命中。

   实现方式是「页面级重映射色阶」而不是逐块重写渐变：第 1 / 4 / 5 / 11 节
   所有 background 都写成 linear-gradient(... var(--blue-0) ... var(--blue-5))，
   在 body 上换掉这几个变量的值，等于整页换肤 —— 组件自身的白卡、反白文字、
   按钮、阴影、色条全部自动跟随，不会漏掉某一块，也不会出现两块颜色打架。

   紫色起点沿用第十一轮的 #2b0a5c，终点仍是 --blue-5 #86b6ee 淡蓝，
   与首页「含产品图区块」的紫蓝渐变同一套色，站内前后一致。
   ========================================================================== */

body:not(:has(main > .hero)) {
  --blue-0: #2b0a5c;     /* 深紫：区块顶端 */
  --blue-1: #4b1596;     /* 紫 */
  --blue-2: #3a3ab5;     /* 蓝紫过渡 */
  --blue-3: #2a5cc0;     /* 蓝 */
  --paper-blue: #f6f2ff; /* 淡紫纸：表格题注、360° 展台这类浅色小底跟着偏紫 */
}

/* 内页头部：红色光斑在紫底上会发脏，换成紫红光并压淡，主渐变仍由色阶驱动 */
body:not(:has(main > .hero)) .page-head {
  background:
    radial-gradient(42% 110% at 96% 0%, rgba(206, 46, 126, 0.24), transparent 62%),
    radial-gradient(38% 96% at 0% 100%, rgba(10, 0, 34, 0.55), transparent 60%),
    linear-gradient(118deg, var(--blue-0) 0%, var(--blue-1) 44%, var(--blue-3) 100%);
}

/* 顶部导航在紫底上保持同一块玻璃：藏蓝换成近黑的紫，白字对比不变 */
body:not(:has(main > .hero)) .site-header { background: rgba(24, 7, 48, 0.90); }

/* 白卡内的表格细节：表头深藏蓝 → 深紫，斑马纹与行标题的冷蓝 → 冷紫。
   不改则白卡里会残留一块"上一套蓝"，和周围紫底脱节。 */
body:not(:has(main > .hero)) thead th {
  background: linear-gradient(90deg, #24094f 0%, #3c1180 100%);
}
body:not(:has(main > .hero)) th[scope="row"] { background: rgba(76, 32, 140, 0.05); }
body:not(:has(main > .hero)) tbody tr:nth-child(even) { background: rgba(76, 32, 140, 0.06); }

/* JEC-038 的 360° 展台：区块本体并入紫蓝渐变（原来是整块近白，会打断页面），
   展台自己给一块淡紫玻璃，透明底的产品图才不至于沉进深紫里。 */
body:not(:has(main > .hero)) main > section:not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head):has(.spin360) {
  color: var(--on-blue);
  background:
    radial-gradient(56% 76% at 92% 2%, rgba(24, 4, 62, 0.58), transparent 64%),
    radial-gradient(48% 66% at 2% 100%, rgba(170, 210, 255, 0.18), transparent 62%),
    linear-gradient(var(--bg-angle, 158deg),
      var(--blue-0) 0%, var(--blue-1) 26%, var(--blue-2) 55%,
      var(--blue-3) 80%, var(--blue-5) 100%);
}
body:not(:has(main > .hero)) main > section:has(.spin360) .spin360 {
  padding: 8px 8px 22px;
  border-radius: 20px;
  background: linear-gradient(162deg, rgba(255, 255, 255, 0.95) 0%, rgba(240, 235, 255, 0.88) 100%);
  box-shadow: 0 22px 54px -32px rgba(8, 2, 28, 0.85);
}
body:not(:has(main > .hero)) main > section:has(.spin360) .spin360-hint { color: var(--ink-2); }

/* ---------- 白卡里的链接：浅粉收回品牌红 ----------
   第 8 节为了让深色底上的链接显眼，把所有 .container a 改成浅粉 --on-blue-link；
   这条规则连带命中了白卡里的链接 —— 浅粉压在白卡上对比度只有 1.9:1，
   产品卡标题、「参数与口味 →」、全系总览的型号列几乎看不见（原本是品牌红）。

   不在选择器上跟那条规则硬拼优先级，而是把卡片内的 --on-blue-link 直接
   重映射回品牌红：那条规则读的就是这个变量，换值即换色，细节样式一律不动。 */
main > section :is(.card, .product-card, .toc, .callout, .faq-item,
  .table-wrap, .fact-box, .spec-table, .ring-card, .range-card,
  .product-shot, .steps, .guide, .quote-box, .inquiry-form, figure.photo) {
  --on-blue-link: var(--brand);
}
/* hover 再压深一档：需要和那条 5 个 :not() 的规则同等特异性才盖得住 */
main > section:nth-of-type(n):not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(.page-head) :is(.card, .product-card, .toc, .callout, .faq-item, .table-wrap, .fact-box, .steps, .guide, .quote-box, .inquiry-form) a:not(.btn):hover {
  color: var(--brand-ink);
}

/* ---------- 内页环廊的标题区：第 8 节把 .ring-band 排除在反白之外 ----------
   于是产品总览页「转一圈，看清每种形态」的 h2 还是藏蓝 #000035、
   引言也是藏蓝，压在深紫环廊上几乎看不见（只剩一抹暗红轮廓）。
   只补 .section-head 这一段，环廊卡片和淡出雾色保持不变。 */
body:not(:has(main > .hero)) .ring-band:not(.ring-band--home) .section-head :is(h2, h3, p, .answer, .small, small) {
  color: #fff;
  text-shadow: 0 1px 12px rgba(8, 2, 30, 0.62);
}
body:not(:has(main > .hero)) .ring-band:not(.ring-band--home) .section-head .eyebrow {
  color: var(--on-blue-link);
}
body:not(:has(main > .hero)) .ring-band:not(.ring-band--home) .section-head a:not(.btn) {
  color: var(--on-blue-link);
}

/* ---------- 环廊卡片：每张都描一圈绯红 ----------
   原来 .ring-plate 是 3px 近黑 #0b1119，压在深紫/藏蓝的环廊底色上等于没有边，
   卡片看着像一块浮着的白板；只有转到正面的那张会换成绯红，其余全靠白底自身
   和背景的明度差。这里把描边统一成绯红，正面对的那张再加一圈光晕区分选中态。

   只改 border-color（宽度仍是 3px、盒模型是 border-box），卡片外框尺寸
   和 3D 位置一点不动，环廊滚动不会因为加边而错位。 */
.ring-plate { border-color: var(--crimson); }

[data-ring-on] .ring-card[data-active] .ring-plate {
  border-color: var(--crimson);
  box-shadow:
    0 0 0 2px rgba(228, 23, 38, 0.38),
    0 22px 34px -18px rgba(9, 32, 46, 0.66);
}

/* ---------- 按钮扫光层不能盖住文字 ----------
   .btn-primary / .btn-ghost 的 hover 效果是一块 ::before 从边上扫进来。
   原本靠 `.btn-primary > * { position: relative }` 把文字抬到它上面 ——
   但按钮里的文字是裸文本（`<a class="btn">让工程师帮我选</a>`），没有子元素，
   这条规则一个都选不中。结果鼠标一放上去，色块盖住标签，只剩一个空红框。

   改成：让按钮自己形成层叠上下文，扫光层退到 z-index:-1。
   这样扫光压在按钮底色之上、文字之下 —— 文字始终可见，动画不变，
   HTML 一个字节都不用改（89 个页面、所有按钮一次修好）。 */
.btn { isolation: isolate; }
.btn::before { z-index: -1; }

/* ---------- 悬停时文字掉色（真正的原因） ----------
   全站在顶部写了 `a:hover { color: var(--brand-ink) }`（11:1 的深红），
   而 `.btn-primary` 只有 `color:#fff` 一条、特异性 (0,1,0) 低于 `a:hover` (0,1,1)。
   于是鼠标一放上去，白字被判成深红 #b0111d，正好和扫光层同色 ——
   看上去就是"有个东西盖住了按钮"，其实字还在，只是和底色一样看不见。

   把颜色按状态写死，和扫光层（已退到 z-index:-1）一起保证文字永远在最上面。 */
.btn-primary,
.btn-primary:hover,
.btn-primary:focus-visible,
.btn-primary:active { color: #fff; }

.btn-ghost { color: var(--brand); }
.btn-ghost:hover,
.btn-ghost:focus-visible { color: var(--brand-ink); }

/* ---------- 红色报价区里的两颗按钮 ----------
   .cta-band 的底色本身是绯红，两颗按钮各自反色（主按钮白底红字、
   次按钮透明底白字），但扫光层的颜色还沿用默认值：
   主按钮是深红扫光，扫上来正好盖住深红字；次按钮是淡粉扫光，扫上来
   变成白字压淡粉。两个都在悬停时"字没了"。
   这里把扫光层换成各自的目标底色，保留了扫过的手感，文字全程可读。 */
.cta-band .btn-primary::before { background: #f7ecee; }
.cta-band .btn-ghost::before { background: rgba(255, 255, 255, 0.16); }


/* ==========================================================================
   按钮交互重构（2026-11-03 第三版）：取消覆盖层，hover 只改底色
   --------------------------------------------------------------------------
   前两版都在用 `::before` 做"扫光填充"，为此要跟层叠顺序、全局 a:hover 的
   颜色、反色区块的底色逐一搏斗 —— 每加一种按钮配色就多一个可能盖住文字的点。

   这一版把这条路彻底掐掉：
   ① 所有 `.btn::before` 直接下线（display:none），按钮内部不再有任何
      覆盖层，文字从机制上不可能被盖住；
   ② 金属表面改用 `.btn::after`（z-index:-1，恒定在文字之下）承载，
      而且是半透明的高光/拉丝，底下的 background-color 能透出来；
   ③ hover 只改 `background-color`，颜色变化由 transition 补间 ——
      平滑、可读、没有任何位移和遮挡。

   `.cta-band` 的反色按钮同样走这条规则，只是把底色换成白 / 透明。
   ========================================================================== */

/* ① 扫光层下线 */
.btn::before { display: none !important; }

/* ② 金属表面层：恒定居于文字之下，只做高光与拉丝，不参与交互 */
.btn { isolation: isolate; }
.btn::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  border-radius: inherit;
}

/* ③ 主按钮：阳极氧化红 —— 底色负责明暗，::after 负责弧面与拉丝 */
.btn-primary {
  background: var(--brand);
  border-color: rgba(120, 6, 16, 0.55);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.38),
    inset 0 -1px 0 rgba(0, 0, 0, 0.22),
    0 1px 2px rgba(11, 23, 36, 0.16),
    0 10px 22px -12px rgba(132, 8, 20, 0.55);
  transition: background-color 0.22s var(--ease), box-shadow 0.22s var(--ease),
              transform 0.12s var(--ease), color 0.22s var(--ease);
}
.btn-primary::after {
  background:
    repeating-linear-gradient(0deg,
      rgba(255, 255, 255, 0.10) 0 1px,
      rgba(255, 255, 255, 0) 1px 3px),
    repeating-linear-gradient(0deg,
      rgba(0, 0, 0, 0.05) 0 1px,
      rgba(0, 0, 0, 0) 1px 5px),
    linear-gradient(180deg,
      rgba(255, 255, 255, 0.26) 0%,
      rgba(255, 255, 255, 0.06) 38%,
      rgba(0, 0, 0, 0.06) 62%,
      rgba(0, 0, 0, 0.16) 100%);
}
.btn-primary:hover,
.btn-primary:focus-visible { background-color: var(--brand-ink); }
.btn-primary:active { background-color: #8f0d17; }

/* ④ 次按钮：拉丝银 —— 白底 + 半透明高光 = 银，悬停只把底色换成暖玫瑰银 */
.btn-ghost {
  background: #ffffff;
  border-color: #c9d2e0;
  color: var(--brand);
  box-shadow:
    inset 0 1px 0 #fff,
    inset 0 -1px 0 rgba(16, 32, 64, 0.10),
    0 1px 2px rgba(11, 23, 36, 0.10),
    0 8px 18px -14px rgba(11, 32, 64, 0.35);
  transition: background-color 0.22s var(--ease), border-color 0.22s var(--ease),
              color 0.22s var(--ease), box-shadow 0.22s var(--ease);
}
.btn-ghost::after {
  background:
    repeating-linear-gradient(0deg,
      rgba(255, 255, 255, 0.55) 0 1px,
      rgba(23, 43, 77, 0.014) 1px 3px),
    repeating-linear-gradient(0deg,
      rgba(255, 255, 255, 0.32) 0 1px,
      rgba(23, 43, 77, 0.010) 1px 5px),
    linear-gradient(180deg,
      rgba(255, 255, 255, 0.95) 0%,
      rgba(255, 255, 255, 0.30) 36%,
      rgba(23, 43, 77, 0.07) 52%,
      rgba(255, 255, 255, 0.55) 70%,
      rgba(255, 255, 255, 0.92) 100%);
}
.btn-ghost:hover,
.btn-ghost:focus-visible {
  background-color: #fdf1f3;
  border-color: var(--brand);
  color: var(--brand-ink);
}

/* ⑤ 红色报价区：两颗反色按钮不套金属，底色直接过渡 */
.cta-band .btn-primary,
.cta-band .btn-primary:hover {
  background: #fff;
  border-color: #fff;
  color: var(--cta-deep);
  box-shadow: none;
}
.cta-band .btn-primary:hover { background: #f7ecee; border-color: #f7ecee; }
.cta-band .btn-primary::after { display: none; }

.cta-band .btn-ghost,
.cta-band .btn-ghost:hover {
  background: transparent;
  border-color: rgba(255, 255, 255, 0.6);
  color: #fff;
  box-shadow: none;
}
.cta-band .btn-ghost:hover {
  background: rgba(255, 255, 255, 0.16);
  border-color: #fff;
  color: #fff;
}
.cta-band .btn-ghost::after { display: none; }

/* ==========================================================================
   表格行底色：紫 / 粉 → 蓝（2026-11-03）
   --------------------------------------------------------------------------
   用户截图里 JEC-019 那一行的粉色来自悬停色 --accent-soft (#fdecee)，
   斑马纹和左侧型号格则是第十一轮留下的紫。表格是全站信息密度最高的地方，
   粉色压在白卡上既不呼应紫蓝渐变，也容易被误读成"错误 / 警告"。

   这里把三层底色统一收到同一个蓝：型号格（最淡）→ 斑马纹（次淡）→ 悬停（最深），
   深浅成阶梯，鼠标划过时能看出"整行被点亮"，而不是只剩一块色。
   只改底色，边框、字号、行高、链接色一律不动。
   ========================================================================== */

:root {
  --row-head:  rgba(42, 92, 192, 0.050);   /* 型号列 */
  --row-zebra: rgba(42, 92, 192, 0.058);   /* 偶数行 */
  --row-hover: rgba(42, 92, 192, 0.165);   /* 悬停行 */
}

tbody tr:nth-child(even),
body:not(:has(main > .hero)) tbody tr:nth-child(even) { background: var(--row-zebra); }

th[scope="row"],
body:not(:has(main > .hero)) th[scope="row"] { background: var(--row-head); }

/* 悬停必须压过斑马纹：原来两条规则特异性相同、斑马纹在后，
   偶数行 hover 一直是失效的（这也是为什么只有某一行会"突然变粉"）。 */
tbody tr:hover,
tbody tr:nth-child(even):hover,
body:not(:has(main > .hero)) tbody tr:hover,
body:not(:has(main > .hero)) tbody tr:nth-child(even):hover { background: var(--row-hover); }

/* JEC-038 的 360° 区块里那张表沿用原有的"无斑马纹"处理，别把条纹加回来 */
main > section:has(.spin360) tbody tr:nth-child(even) { background: transparent; }

/* 悬停时型号列也跟着一起亮：th 自带底色会盖住整行的 hover，
   不加这条，鼠标划过只剩右半边变色，像被切成两段。 */
tbody tr:hover th[scope="row"],
body:not(:has(main > .hero)) tbody tr:hover th[scope="row"] { background: transparent; }

/* ==========================================================================
   背景流动（2026-11-03，第二版：整片「紫 → 蓝」呼吸）
   --------------------------------------------------------------------------
   第一版是往底色上叠一层很淡的光斑（0.13 / 34s / ±5%），实测两帧平均色差
   只有 3/255，用户反馈"看不出来"。原因不是幅度不够，是**没有参照物**：
   大面积柔光缓慢平移，人眼会触发变化盲视，盯着看也像静止的。

   这一版换思路 —— 不再"叠光"，而是让整片背景的颜色本身在紫调和蓝调之间来回：
   · ::before 是紫层，::after 是蓝层，两层叠在区块底色之上；
   · 两层做互补的 opacity 动画（0.68→0 与 0→0.68），和恒为 0.68，
     所以底色始终透出 32%，原有渐变的层次不会被抹平；
   · 每层再各加一个反向的 transform 漂移，紫团往左上、蓝团往右下，
     色团位置也在变，不是单纯的明暗呼吸。

   为什么用 opacity：opacity 和 transform 都是合成属性，动画过程零重绘零重排，
   主线程完全不参与。试过 background-position / 渐变角度，每帧要重绘整块
   1440×900 的渐变，滚动时掉帧。

   层叠：父级 isolation:isolate，伪元素 z-index:-2 / -1，正好落在
   「区块底色之上、正文之下」，压不到任何文字。

   排除：首屏（有实拍图）、环廊（3D 卡片）、数据带、红色报价区、360° 区块；
   系统开启「减少动态效果」时整段不生效。
   ========================================================================== */

@media (prefers-reduced-motion: no-preference) {
  main > section:not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(:has(.spin360)) {
    position: relative;
    overflow: hidden;
    isolation: isolate;
  }

  main > section:not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(:has(.spin360))::before,
  main > section:not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(:has(.spin360))::after {
    content: "";
    position: absolute;
    inset: -14%;
    pointer-events: none;
  }

  /* 紫层 */
  main > section:not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(:has(.spin360))::before {
    z-index: -2;
    background:
      radial-gradient(64% 74% at 16% 22%, rgba(168, 118, 255, 0.95), transparent 66%),
      radial-gradient(58% 66% at 84% 80%, rgba(88, 28, 179, 0.95), transparent 72%),
      linear-gradient(122deg, #3a0570 0%, #6d28d9 44%, #7c3aed 100%);
    opacity: 0.62;
    animation:
      bg-tint-a 13s ease-in-out infinite alternate,
      bg-drift-a 15s ease-in-out infinite alternate;
  }

  /* 蓝层 */
  main > section:not(.hero):not(.ring-band):not(.stat-band):not(.cta-band):not(:has(.spin360))::after {
    z-index: -1;
    background:
      radial-gradient(82% 90% at 76% 22%, rgba(126, 180, 255, 0.72), transparent 70%),
      radial-gradient(58% 66% at 18% 84%, rgba(29, 78, 216, 0.92), transparent 72%),
      linear-gradient(122deg, #0c1f4f 0%, #1d4ed8 40%, #3b82f6 74%, #60a5fa 100%);
    opacity: 0;
    animation:
      bg-tint-b 13s ease-in-out infinite alternate,
      bg-drift-b 15s ease-in-out infinite alternate;
  }
}

/* 两层互补：加起来始终是 0.62，底色透出的比例不会忽多忽少 */
@keyframes bg-tint-a { from { opacity: 0.62; } to { opacity: 0; } }
@keyframes bg-tint-b { from { opacity: 0; }   to { opacity: 0.62; } }

/* 反向漂移：紫团往左上走的同时蓝团往右下走，颜色像两股水互相穿过 */
@keyframes bg-drift-a {
  from { transform: translate3d(-9%, -6%, 0) scale(1.04); }
  to   { transform: translate3d(9%, 5%, 0) scale(1.10); }
}
@keyframes bg-drift-b {
  from { transform: translate3d(9%, 6%, 0) scale(1.10); }
  to   { transform: translate3d(-9%, -5%, 0) scale(1.04); }
}

/* ==========================================================================
   首屏数据条（2026-11-03）
   --------------------------------------------------------------------------
   起因：1180 下文字列在 x≈500 结束、产品图到 x≈880 才开始，中间空出 380px；
   1440 下按钮到 hero 下沿还有 90px 空高。用户反馈「两边过于空旷」。

   补一条四项数据放在 CTA 下面：既填掉这块空白，又把买家最先问的四件事
   （多少款、多少口、做了几年、多久交货）在首屏讲完，不用往下滚。
   数据全部取自站内既有事实：PRODUCTS 长度、PUFF_MIN/PUFF_MAX、founded、
   OEM 交期 20–25 个工作日 —— 不新增任何未经确认的数字。

   单列断点（980）下文字不再受 62ch 约束，数据条铺满容器，右侧不再空一块。
   ========================================================================== */
.hero-facts {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  margin: 34px 0 0;
  padding: 22px 0 0;
  border-top: 1px solid rgba(11, 23, 36, 0.11);
  max-width: 62ch;
}
.hero-facts > div {
  padding: 0 16px;
  border-left: 1px solid rgba(11, 23, 36, 0.09);
  min-width: 0;
}
.hero-facts > div:first-child { padding-left: 0; border-left: 0; }
.hero-facts > div:last-child { padding-right: 0; }
.hero-facts dt {
  margin: 0 0 7px;
  font-size: 11px;
  line-height: 1.3;
  letter-spacing: 0.09em;
  color: var(--muted);
  font-weight: 500;
}
.hero-facts dd {
  margin: 0;
  font-size: clamp(0.96rem, 1.3vw, 1.14rem);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.hero-facts dd small {
  font-size: 0.7em;
  font-weight: 600;
  letter-spacing: 0;
  color: var(--ink-2);
}

@media (max-width: 980px) {
  /* 变单列后整行都归文字所有，再把内容压在左侧一半就真的空了 */
  .hero-grid > div:first-child { max-width: none; }
  .hero-grid .lede { max-width: 62ch; }
  .hero-facts { max-width: none; }
}

@media (max-width: 620px) {
  .hero-facts {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 18px 0;
    margin-top: 28px;
  }
  .hero-facts > div:nth-child(3) { padding-left: 0; border-left: 0; }
}

/* 数据条宽度跟列宽走：只放松长行、不放松段落 —— 正文仍按 62ch 断行，
   但 4 列数据需要 700px 左右才放得下 "600 – 1,000,000" 不折行。 */
@media (min-width: 981px) {
  .hero-grid { grid-template-columns: 1.32fr 0.68fr; }
  .hero-grid > div:first-child { max-width: min(720px, 100%); }
  .hero-facts { max-width: none; }
}

.hero-facts > div { padding: 0 14px; }
.hero-facts dd { white-space: nowrap; font-size: clamp(0.92rem, 1.2vw, 1.1rem); }

/* ==========================================================================

/* ==========================================================================
   全站左侧流金竖线（2026-11-03）
   --------------------------------------------------------------------------
   在内容区左边界外侧 16px 挂一条 1px 金线，从视口顶穿到底，线上有一段
   420px 的金色流光自上而下走，8 秒一趟。首页、内页、页脚都在。

   为什么用 fixed 而不是 absolute + 文档高度：每页文档高 3000~8000px 不等，
   background-position 的百分比会按各自高度换算，速度忽快忽慢；fixed 的高度
   恒等于视口，节奏稳定，滚动时也完全不参与合成。

   z-index: 3 —— 区块背景不透明，负值会被盖掉；导航是 sticky + z-index 50，
   所以滚到顶时线会被导航压住，正是想要的效果。

   位置：留白中心再往里 56px —— 1440 下金线离正文 80px，1368 以上始终是 80px。
   只在 >=1281 显示：更窄的视口 container 只剩 40px 留白，线和正文会贴到一起。
   系统开启「减少动态效果」时只留金线，不跑流光。
   ========================================================================== */
@media (min-width: 1281px) {
  body::before {
    content: "";
    position: fixed;
    top: 0;
    bottom: 0;
    left: max(24px, calc((100% - 1200px) / 2 - 56px));
    width: 12px;
    margin-left: -6px;
    z-index: 3;
    pointer-events: none;
    -webkit-mask-image: linear-gradient(90deg,
      transparent 0%, rgba(0, 0, 0, 0.32) 26%, #000 42%, #000 58%,
      rgba(0, 0, 0, 0.32) 74%, transparent 100%);
    mask-image: linear-gradient(90deg,
      transparent 0%, rgba(0, 0, 0, 0.32) 26%, #000 42%, #000 58%,
      rgba(0, 0, 0, 0.32) 74%, transparent 100%);
    background:
      /* 金色流光段：象牙 → 亮金 → 标准金，两头淡出 */
      linear-gradient(180deg,
        rgba(255, 248, 214, 0) 0%,
        rgba(255, 248, 214, 0.92) 16%,
        rgba(245, 215, 110, 1) 34%,
        rgba(212, 175, 55, 0.96) 52%,
        rgba(212, 175, 55, 0) 100%) 0 -420px / 100% 420px no-repeat,
      /* 线的底色：淡金。白底上是浅金线，深底上是暗金线 */
      linear-gradient(180deg,
        rgba(212, 175, 55, 0.34),
        rgba(212, 175, 55, 0.30) 68%,
        rgba(212, 175, 55, 0.14)) 0 0 / 100% 100% no-repeat;
    animation: site-streak 8s cubic-bezier(0.45, 0.05, 0.55, 0.95) infinite;
  }
}

@keyframes site-streak {
  /* -420px = 光段整段在视口上方；calc(100% + 420px) = 整段滑到视口下方 */
  0%, 4%    { background-position: 0 -420px, 0 0; }
  96%, 100% { background-position: 0 calc(100% + 420px), 0 0; }
}

@media (prefers-reduced-motion: reduce) {
  body::before { animation: none; background-position: 0 -420px, 0 0; }
}

@media print {
  body::before { display: none; }
}

/* ==========================================================================
   左侧产品图带（2026-11-03）
   --------------------------------------------------------------------------
   金线左边那 60px 原本是全空的，放一列产品缩略图：33 款各一张，竖排，
   整体缓慢上滚，鼠标停上去暂停，点任意一张进该型号详情页。

   宽度：4→56px（52px 宽），金线在 58→70，两者不重叠也不贴死。
   高度：每项 104px + 10px margin-bottom。

   为什么用 margin-bottom 而不是 gap：无缝循环靠 translateY(-50%)，
   66 项之间有 65 个间隙，用 gap 的话半程会和一份的高度差 5px，
   循环到接缝处会跳一下。

   图片是 104×208 的 jpg（@2x，每张 4KB），不是拿 600×800 的 thumb 直接缩 ——
   33 张 thumb 合计近 3MB，全站每页都挂会拖死首屏。
   ========================================================================== */
.rail { display: none; }

@media (min-width: 1281px) {
  .rail {
    display: block;
    position: fixed;
    left: 4px;
    top: 0;
    bottom: 0;
    /* 单排，始终一列。宽度取「到金线的距离」和 168px 里小的那个：
       1440 下 52px（正好贴住金线），1720 起封顶 168px。
       不再按可用宽度加列 —— 用户要的是单排滚动，多列会变成产品墙。 */
    width: min(168px, calc(max(24px, (100vw - 1200px) / 2 - 56px) - 8px));
    z-index: 3;
    overflow: hidden;
    /* 上下两头渐隐，产品带不会硬生生切断 */
    -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 7%, #000 93%, transparent 100%);
    mask-image: linear-gradient(180deg, transparent 0, #000 7%, #000 93%, transparent 100%);
  }

  .rail-track {
    --rail-gap: 10px;
    display: grid;
    grid-template-columns: 1fr;   /* 单排 */
    gap: var(--rail-gap);
    animation: rail-scroll 90s linear infinite;
    will-change: transform;
  }

  /* 悬停或键盘聚焦时停住，方便点 */
  .rail:hover .rail-track,
  .rail:focus-within .rail-track { animation-play-state: paused; }

  .rail-item {
    display: block;
    width: 100%;
    aspect-ratio: 1 / 2;   /* 图是 1:2 的竖条，宽变高跟着变 */
    border-radius: 5px;
    overflow: hidden;
    box-shadow: 0 1px 3px rgba(11, 23, 36, 0.16);
    transition: box-shadow 0.2s ease, transform 0.2s ease;
  }

  .rail-item img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
  }

  .rail-item:hover {
    box-shadow: 0 0 0 2px rgba(212, 175, 55, 0.95), 0 4px 10px rgba(11, 23, 36, 0.22);
    transform: scale(1.04);
  }

  .rail-item:focus-visible {
    outline: 2px solid #d4af37;
    outline-offset: 2px;
  }
}

@keyframes rail-scroll {
  /* 用 grid 的 gap 之后，两份内容之间有 2N-1 个间隙，
     -50% 会比一份高出半个 gap，接缝处跳 5px，所以补掉 */
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(0, calc(-50% - var(--rail-gap) / 2), 0); }
}

@media (prefers-reduced-motion: reduce) {
  .rail-track { animation: none; }
}

@media print {
  .rail { display: none; }
}
