/* ============================================================================
   home.css — 首页专属样式（新模块用）
   ============================================================================
   只被 4 个 index*.html 引用。site.css 是全站共享的（24 个页面），
   本文件不改动 site.css 的任何规则 —— 这样改动物理上不可能波及子页。

   类名一律避开 site.css 既有类名（.container / .feat-card / .btn /
   .hero / .features / .cta / footer …），新模块用新前缀：
   .wrap / .band / .eyebrow / .rv-* / .scan-* / .mini-* / .pipe-*

   设计 token 在这里定义一份，site.css 里仍是硬编码 —— 这是有意的：
   把 site.css 全站变量化会改动 24 个页面的渲染，收益为零、风险不小。

   ★ 装饰线一律用 "=" 不用 "-"：双连字符在 XML 注释里非法，
     万一本文件被内联进 XML/SVG 上下文就会报 parse error。
   ============================================================================ */

:root {
  /* 品牌色（数值与 site.css 的硬编码一致） */
  --brand:      #FF7B00;
  --brand-hi:   #FF9823;
  --brand-dim:  rgba(255, 123, 0, .14);
  --brand-glow: rgba(255, 123, 0, .06);

  /* 表面层次 —— 用明度阶梯制造段落感。
     ★ 不用 RadialZ 那种米色暖带：站上 12 张截图全是深色 UI，
       贴在浅色底上会像浮着的黑方块；且品牌识别就是纯黑 + 橙。 */
  --bg:        #0d0d0d;
  --bg-alt:    #111;
  --bg-deep:   #0a0a0a;
  --surface:   #1a1a1a;
  --surface-2: #141414;

  --line:   #222;
  --line-2: #2a2a2a;

  --t1: #fff;  --t2: #e0e0e0;  --t3: #aaa;
  --t4: #888;  --t5: #666;     --t6: #555;

  --r: 12px;  --r-s: 8px;  --r-xs: 6px;
  --wrap: 1080px;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

/* 新模块的容器，比 site.css 的 .container(960px) 宽 —— marquee 要通栏、
   三栏演示要排得开。★ 不改 .container，24 个页面在用它。 */
.wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 24px; }

/* ── 段落带 ────────────────────────────────────────────────────────────── */
.band { position: relative; padding: 76px 0; border-top: 1px solid var(--line); }
.band--alt  { background: var(--bg-alt); }
.band--deep { background: var(--bg-deep); }
/* 顶部极淡的橙色辉光 —— 替代"浅色带"提供换段感 */
.band::before {
  content: ""; position: absolute; inset: -1px 0 auto 0; height: 320px;
  background: radial-gradient(60% 100% at 50% 0, var(--brand-glow), transparent 70%);
  pointer-events: none;
}

.eyebrow {
  font: 600 12px/1 var(--mono); letter-spacing: .14em;
  text-transform: uppercase; color: var(--brand); margin-bottom: 16px;
}
/* ★ 区块标题放大：原来 27px。radialz 的 section-head h2 是 clamp(40px,6vw,80px)，
   我们容器更窄（1080 vs 1180），取一个不换行的上限。 */
.band h3 {
  font-size: clamp(31px, 4.1vw, 56px);
  font-weight: 800; line-height: 1.06; letter-spacing: -0.035em;
  color: var(--t1); margin-bottom: 14px;
}
.band .lede {
  font-size: clamp(15px, 1.25vw, 17.5px);
  line-height: 1.65; color: var(--t4); max-width: 680px; margin-bottom: 34px;
}

/* ══════════════════════════════════════════════════════════════════════════
   入场动画
   ★ 默认全部可见；只有 html.js 存在时才隐藏待入场。
     这样"关掉 JS / 爬虫 / 社交预览"看到的是完整内容，而不是一片空白 ——
     一个零 JS 的站点不该因为加了动画就变成"关掉 JS 就瞎"。
   ══════════════════════════════════════════════════════════════════════════ */
html.js .reveal {
  opacity: 0; transform: translateY(16px);
  transition: opacity .55s ease, transform .55s cubic-bezier(.2, .7, .3, 1);
  transition-delay: calc(var(--d, 0) * 70ms);
}
html.js .reveal.in { opacity: 1; transform: none; }

/* ══════════════════════════════════════════════════════════════════════════
   评价墙（marquee）
   ★★ .rv-track 里必须【恰好两份完全一致】的内容 —— rv-scroll 位移 -50%
      靠这个成立。删掉一半卡片会让动画瞬移半屏。
   ══════════════════════════════════════════════════════════════════════════ */
.rv-viewport {
  overflow: hidden; padding: 26px 0;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}
.rv-track {
  display: flex; gap: 16px; width: max-content;
  animation: rv-scroll 46s linear infinite;
  will-change: transform;
}
.rv-track + .rv-track { margin-top: 16px; }
.rv-track--b { animation-direction: reverse; animation-duration: 58s; }
@keyframes rv-scroll {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }
}
.rv-viewport:hover .rv-track { animation-play-state: paused; }

.rv {
  flex: 0 0 320px; display: flex; flex-direction: column; gap: 14px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r); padding: 18px 20px;
  transition: transform .28s cubic-bezier(.2, .7, .3, 1),
              border-color .28s, box-shadow .28s;
}
.rv:hover {
  transform: translateY(-4px) scale(1.025);
  border-color: var(--brand);
  box-shadow: 0 0 0 1px rgba(255, 123, 0, .30), 0 14px 34px rgba(255, 123, 0, .13);
}
.rv-quote { font-size: 14px; line-height: 1.7; color: var(--t2); flex: 1; }

/* 卡片顶部一行：五星 + 语境徽章 */
.rv-top {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
/* 内联图标定义容器（五星的 symbol）—— 不占位、不可见 */
.icon-defs { position: absolute; width: 0; height: 0; overflow: hidden; }

.rv-stars { display: inline-flex; gap: 3px; color: var(--brand); }
.rv-stars svg { width: 13px; height: 13px; display: block; }
.rv-who { display: flex; align-items: center; gap: 12px; }
.rv-avatar {
  flex: 0 0 34px; height: 34px; border-radius: 50%;
  display: grid; place-items: center;
  font: 700 15px/1 var(--mono); color: var(--brand);
  background: radial-gradient(circle at 32% 26%, hsl(var(--h, 26) 62% 26%), #151515 72%);
  border: 1px solid rgba(255, 255, 255, .06);
}
.rv-meta b { display: block; font-size: 13px; font-weight: 600; color: var(--t1); }
.rv-meta i { font-size: 11.5px; font-style: normal; color: var(--t5); }
.rv-src {
  font: 500 10.5px/1 var(--mono); letter-spacing: .06em;
  color: var(--t5); border: 1px solid var(--line-2);
  border-radius: 999px; padding: 4px 9px; white-space: nowrap;
}
/* 明示说明行：一行字，不伤转化，但把"这是不是编的"这个疑虑直接拆掉 */
.rv-note { font-size: 12.5px; color: var(--t4); max-width: 660px; margin-bottom: 10px; }

@media (prefers-reduced-motion: reduce) {
  html.js .reveal { opacity: 1; transform: none; transition: none; }
  .rv-track { animation-duration: 180s; }   /* 减速而非停止 */
}

@media (max-width: 900px) {
  .rv { flex: 0 0 280px; }
}
/* 首页 FAQ —— 复用 site.css 的 .faq-item，只加个易读宽度 */
.faq-list { max-width: 820px; }

@media (max-width: 640px) {
  .band { padding: 56px 0; }
  .band h3 { font-size: 22px; }
}

/* ── 首屏 h1 ──────────────────────────────────────────────────────────────
   ★ 首页此前用 <h2> 当主标题，全页没有 h1 —— 这是最基础的 SEO 失分项。
     这里把 site.css 里 .hero h2 的样式原样复刻给 h1（不改 site.css，
     它被 24 个页面共用）。 */
.hero-h1 {
  /* ★ 字号放大：原来固定 38px，按 radialz 的层级（他们 hero 是 clamp(76px,13vw,176px)）
     取一个适配我们 1080px 容器的值。大 + 粗 + 紧排 = 他们那种"浮夸"的来源。 */
  font-size: clamp(46px, 6.6vw, 92px);
  font-weight: 800;
  line-height: 1.02;
  letter-spacing: -0.045em;
  color: #fff; margin-bottom: 18px;
  /* 入场：标题轻微上浮 + 字距收拢，做出"落定"的高级感 */
  animation: hero-in .9s cubic-bezier(.2, .7, .3, 1) both;
}
.hero-h1 { text-align: center; }
.hero-h1 span, .hero-h1 .z { color: var(--brand); }
@keyframes hero-in {
  from { opacity: 0; transform: translateY(14px); letter-spacing: .04em; }
  to   { opacity: 1; transform: none; letter-spacing: -0.045em; }
}
@media (max-width: 640px) { .hero-h1 { font-size: clamp(34px, 9vw, 46px); } }

/* 首屏副标题跟着标题一起放大，否则 h1 一大就显得"头重脚轻"。
   .hero-fact 是那句定义性的长描述（也是 p），单独排除掉。 */
.hero p:not(.hero-fact) {
  font-size: clamp(16px, 1.5vw, 20px);
  line-height: 1.6; color: var(--t3);
}
.hero-fact { font-size: clamp(13.5px, 1.1vw, 15.5px); }

/* ══════════════════════════════════════════════════════════════════════════
   功能卡（#features）
   ★ 文字在上、图片在下 —— 不再是 site.css 那种左右分栏。图片尽量放大，
     让客户能看清切图里的细节。
   ★ 全宽与半宽（两联）混排：宽图独占一行、方图半宽并排。哪些走全宽由
     _home.py 的 _CARD_WIDE 决定，依据是每张切图的真实宽高比。
   ══════════════════════════════════════════════════════════════════════════ */
.feat-grid {
  display: grid; grid-template-columns: repeat(2, 1fr);
  gap: 52px 26px; align-items: start;
}

/* ── 前 4 张宽图：滚动时叠成"牌堆" ──────────────────────────────────────
   机制借自 radialz 的 STEP 卡片：position: sticky + 递减的 top 让每张卡
   停在不同高度、依次叠上来。滚动时由 home.js 给"被盖住的那张"加
   scale / translateY / opacity，做出纵深。
   ★ 布局仍是我们自己的上下结构（文字在上、图在下），只借动效。 */
.feat-stack {
  display: flex; flex-direction: column; gap: 28px; margin-bottom: 56px;
}
.feat-item--stack {
  position: sticky;
  top: calc(78px + var(--i, 0) * 20px);
  z-index: calc(10 + var(--i, 0));
  /* 必须是不透明底，否则下面的卡会透出来，叠不出牌堆感 */
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: 26px;
  transform-origin: center top;
  will-change: transform, opacity;
  box-shadow: 0 34px 74px -44px rgba(0, 0, 0, .95);
}
/* 牌堆里的图压一压高度，保证卡片整体不高于视口，堆叠才看得见 */
.feat-item--stack .shot img { max-height: 48vh; object-fit: cover; }
.feat-item--stack .shot { display: flex; justify-content: center; }

.feat-item { margin: 0; display: flex; flex-direction: column; gap: 16px; }
.feat-item--wide { grid-column: span 2; }
/* 半宽对里的第二张轻微下移，做出错落感 */
.feat-item--offset { margin-top: 44px; }

/* ★ 卡片标题放大：原来 19px。radialz 的 step-card h3 是 clamp(32px,3.4vw,46px)。 */
.feat-item figcaption h4 {
  font-size: clamp(23px, 2.5vw, 34px);
  font-weight: 800; line-height: 1.1; letter-spacing: -0.03em;
  color: var(--brand); margin-bottom: 10px;
}
.feat-item figcaption p {
  font-size: clamp(14.5px, 1.15vw, 16.5px);
  color: var(--t4); line-height: 1.7; margin: 0;
  max-width: 760px;        /* 全宽时别把文字拉成一条长线，影响阅读 */
}

.feat-item img {
  width: 100%; height: auto; display: block;
}

/* ── 切图的"相框" ─────────────────────────────────────────────────────────
   hover 时图片在框内轻微放大（scale 被 overflow 裁住），边框与辉光渐亮。
   这是整页最能出"质感"的一处：动得少、但顺滑。 */
.feat-item .shot {
  display: block; overflow: hidden;
  border-radius: var(--r-s); border: 1px solid var(--line);
  background: var(--surface-2);
  transition: border-color .5s ease, box-shadow .6s ease;
}
.feat-item .shot img {
  transition: transform .8s cubic-bezier(.2, .7, .3, 1);
  will-change: transform;
}
.feat-item:hover .shot {
  border-color: rgba(255, 123, 0, .5);
  box-shadow: 0 28px 60px -34px rgba(0, 0, 0, .95),
              0 0 0 1px rgba(255, 123, 0, .22),
              0 0 80px -28px rgba(255, 123, 0, .5);
}
.feat-item:hover .shot img { transform: scale(1.035); }
.feat-item figcaption h4 { transition: color .3s ease; }
.feat-item:hover figcaption h4 { color: var(--brand-hi); }
/* 触屏没有 hover，用 :active 给一点同样的反馈 */
@media (hover: none) {
  .feat-item:active .shot img { transform: scale(1.02); }
}

/* ══════════════════════════════════════════════════════════════════════════
   区块标题下的细线 —— 进入视口时从左展开
   ★ 用 transition 而不是 animation，这样能直接挂在已有的 .reveal.in 上，
     不需要再写一套 IntersectionObserver 逻辑。
   ══════════════════════════════════════════════════════════════════════════ */
h3.reveal::after {
  content: ""; display: block; width: 56px; height: 2px; margin-top: 16px;
  background: linear-gradient(90deg, var(--brand), rgba(255, 123, 0, 0));
  transform: scaleX(0); transform-origin: left;
  transition: transform .9s cubic-bezier(.2, .7, .3, 1) .12s;
}
html.js h3.reveal.in::after { transform: scaleX(1); }
html:not(.js) h3.reveal::after { transform: scaleX(1); }

/* ══════════════════════════════════════════════════════════════════════════
   首屏的呼吸光 —— 极慢、极淡，只是让静止画面"活着"
   ══════════════════════════════════════════════════════════════════════════ */
.hero { position: relative; }
.hero::before {
  content: ""; position: absolute; inset: -80px 0 auto 0; height: 460px;
  background: radial-gradient(52% 60% at 50% 0,
              rgba(255, 123, 0, .10), transparent 72%);
  pointer-events: none; z-index: -1;
  animation: hero-breathe 9s ease-in-out infinite alternate;
}
@keyframes hero-breathe {
  from { opacity: .55; transform: scale(1); }
  to   { opacity: 1;   transform: scale(1.06); }
}

@media (prefers-reduced-motion: reduce) {
  .feat-item .shot, .feat-item .shot img { transition: none; }
  .feat-item:hover .shot img { transform: none; }
  h3.reveal::after { transition: none; transform: scaleX(1); }
  .hero::before { animation: none; }
  /* 牌堆退化成普通堆叠 —— 不做滚动缩放/淡出 */
  .feat-item--stack { position: static; transform: none !important; opacity: 1 !important; }
  /* 同理，marquee 与演示动画已在各自段落处理 */
}

@media (max-width: 760px) {
  .feat-grid { grid-template-columns: 1fr; gap: 40px; }
  .feat-item--wide { grid-column: auto; }
  .feat-item--offset { margin-top: 0; }   /* 窄屏取消错位，避免看起来像没对齐 */
  .feat-item figcaption h4 { font-size: 17px; }
}

/* ══════════════════════════════════════════════════════════════════════════
   Mini 悬浮窗演示（#mini）
   ★ 用真实截图，不用 CSS 模拟界面 —— 规格与真机一致：
     mini_l2 = 270×460、mini_l3 = 270×900（V1.4 的档位高度 L2=460 / L3=900）
   ══════════════════════════════════════════════════════════════════════════ */
.mini-stage {
  position: relative; margin: 0 0 22px;
  border: 1px solid var(--line); border-radius: var(--r);
  overflow: hidden; background: var(--surface-2);
}
.mini-stage img { width: 100%; height: auto; display: block; }
.mini-stage figcaption {
  position: absolute; left: 16px; bottom: 14px;
  font: 500 11px/1 var(--mono); letter-spacing: .08em; text-transform: uppercase;
  color: var(--t3); background: rgba(10, 10, 10, .78);
  border: 1px solid var(--line-2); border-radius: 999px; padding: 6px 12px;
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
}

.mini-levels {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 18px; align-items: end;   /* 底部对齐 —— 自然显出高度差，不需要额外标注 */
}
.lv {
  margin: 0; background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-s); padding: 12px; text-align: center;
  transition: border-color .25s, transform .25s;
}
.lv:hover { border-color: var(--brand); transform: translateY(-3px); }
.lv img {
  width: 100%; height: auto; display: block;
  border-radius: var(--r-xs); margin-bottom: 10px;
}
.lv figcaption { font-size: 12px; color: var(--t4); }

@media (max-width: 640px) {
  .mini-levels { grid-template-columns: 1fr; }
  .mini-stage figcaption {
    position: static; display: block; border: 0; background: none; padding: 10px 12px;
  }
}

/* ══════════════════════════════════════════════════════════════════════════
   笔刷库扫描演示（#scan）
   ★ 站上没有真实笔刷缩略图素材 → 用 promo/assets/brush-glyphs.svg 的
     6 个抽象符号复用出 24 格，靠旋转角 --r 与错峰 --i 错开重复感。
   ★ 动画只在 .anim-scope.running 时跑（home.js 用 IntersectionObserver 控制），
     离开视口即暂停 —— 页尾的无限动画不该在你读页首时空转。
   ══════════════════════════════════════════════════════════════════════════ */
.scan {
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: var(--r); padding: 18px; overflow: hidden;
}
.scan-bar {
  display: flex; justify-content: space-between; align-items: center; gap: 12px;
  margin-bottom: 14px; font: 500 11.5px/1 var(--mono); color: var(--t5);
}
.scan-path { color: var(--t4); }
.scan-count b { color: var(--brand); font-weight: 700; }

.scan-grid {
  position: relative; display: grid; grid-template-columns: repeat(6, 1fr);
  gap: 8px; margin-bottom: 14px;
}
.bt {
  position: relative; aspect-ratio: 1; display: block;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-xs); overflow: hidden;
  transition: border-color .3s;
}
/* 真实笔刷缩略图（软件缓存里的 96×96 PNG）—— 不用 contain 会裁切，
   且绝不加旋转：那是真实预览图，转了就假了 */
.bt img {
  width: 100%; height: 100%; object-fit: contain; display: block;
}

/* 扫描线 */
.scan-sweep {
  position: absolute; inset: 0 auto 0 0; width: 18%; pointer-events: none;
  background: linear-gradient(90deg, transparent, rgba(255, 123, 0, .22), transparent);
}
html.js .scan-sweep { animation: sc-sweep 9s ease-in-out infinite; }
@keyframes sc-sweep {
  0%        { transform: translateX(-100%); }
  22%, 100% { transform: translateX(640%); }
}

/* 分格浮现：错峰变量 i 让相邻格依次出现，形成一道对角扫描波 */
html.js .bt {
  opacity: 0; transform: scale(.86);
  animation: sc-pop 9s cubic-bezier(.2, .7, .3, 1) infinite;
  animation-delay: calc(var(--i) * 110ms);
}
@keyframes sc-pop {
  0%, 3%   { opacity: 0; transform: scale(.86); }
  8%, 100% { opacity: 1; transform: scale(1); }
}

/* 搜索框逐字输入 */
html.js .scan-search .q {
  display: inline-block; overflow: hidden; white-space: nowrap; width: 0;
  animation: sc-type 9s steps(4, end) infinite;
}
@keyframes sc-type { 0%, 34% { width: 0; } 40%, 100% { width: 4ch; } }
html.js .scan-search .caret { animation: sc-blink 1s steps(1) infinite; }
@keyframes sc-blink { 50% { opacity: 0; } }

/* 未命中变暗。★ 打在 img 上而非 .bt 上 —— 否则会和 sc-pop 抢 opacity 属性 */
html.js .bt img { animation: sc-dim 9s ease infinite; }
@keyframes sc-dim {
  0%, 56%  { opacity: 1; filter: none; }
  66%, 92% { opacity: .12; filter: grayscale(1); }
  100%     { opacity: 1; filter: none; }
}

/* 命中格亮橙 */
html.js .bt.is-hit {
  animation: sc-pop 9s cubic-bezier(.2, .7, .3, 1) infinite,
             sc-hit 9s ease infinite;
  animation-delay: calc(var(--i) * 110ms), 0s;
}
@keyframes sc-hit {
  0%, 56%  { border-color: var(--line); box-shadow: none; }
  66%, 92% { border-color: var(--brand);
             box-shadow: 0 0 0 1px var(--brand), 0 0 18px var(--brand-dim); }
  100%     { border-color: var(--line); box-shadow: none; }
}
html.js .bt.is-hit img { animation: none; opacity: 1; filter: brightness(1.18); }

/* 搜索栏 */
.scan-search {
  display: flex; align-items: center; gap: 8px;
  background: var(--surface); border: 1px solid var(--line-2);
  border-radius: var(--r-xs); padding: 10px 12px;
  font: 500 13px/1 var(--mono); color: var(--t2);
}
.scan-search .caret { width: 2px; height: 14px; background: var(--brand); margin-left: -4px; }
.scan-search .hits {
  margin-left: auto; font-size: 11px; color: var(--t5); letter-spacing: .04em;
}

/* 计数器。@property 支持度：Chrome 85+ / Safari 16.4+ / Firefox 128+。
   不支持时数字离散跳变而非平滑增长 —— 优雅降级，不需要 fallback。 */
@property --n { syntax: '<integer>'; inherits: false; initial-value: 0; }
html.js .cnt { animation: sc-count 9s cubic-bezier(.15, .9, .2, 1) infinite; }
html.js .cnt::after { counter-reset: n var(--n); content: counter(n); }
@keyframes sc-count { 0% { --n: 0; } 26%, 100% { --n: 6482; } }

/* 演示动画的启停：进视口才 running（home.js 加 .running） */
html.js .anim-scope * { animation-play-state: paused; }
html.js .anim-scope.running * { animation-play-state: running; }

@media (max-width: 640px) {
  .scan-grid { gap: 6px; }
  .scan-bar { font-size: 10.5px; }
}

/* ══════════════════════════════════════════════════════════════════════════
   发送到 ZBrush 链路演示（#send）
   ★★ 两个包与三个节点的反应共用【同一个 7s 周期】，靠关键帧百分比对齐。
      这里【不能】用 animation-delay 错峰 —— 那会让"包到达"和"节点反应"
      对不上时刻，看起来就是不同步。扫描演示才用 delay 错峰（那里要的正是波）。
   ══════════════════════════════════════════════════════════════════════════ */
.pipe {
  display: grid; grid-template-columns: auto 1fr auto 1fr auto;
  align-items: center; gap: 0;
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: var(--r); padding: 26px 22px;
}

.pipe-node {
  margin: 0; display: flex; flex-direction: column; align-items: center;
  gap: 8px; justify-self: center;
}
.pipe-node img {
  width: 96px; height: auto; display: block;
  border-radius: var(--r-xs); border: 1px solid var(--line-2);
}
.pipe-node figcaption {
  font: 500 9.5px/1 var(--mono); letter-spacing: .1em; text-transform: uppercase;
  color: var(--t5);
}

.pipe-node--mid {
  width: 76px; height: 76px; border-radius: 50%;
  border: 1px solid var(--line-2); background: var(--surface);
  justify-content: center; gap: 3px;
}
.pipe-node--mid b { font: 700 13px/1 var(--mono); color: var(--t2); }
.pipe-node--mid small {
  font: 500 9px/1 var(--mono); letter-spacing: .1em;
  text-transform: uppercase; color: var(--t5);
}

.pipe-node--zb {
  width: 76px; height: 76px; border-radius: var(--r-s);
  border: 1px dashed var(--line-2); background: var(--surface);
  justify-content: center;
}
.zb-thumb { width: 40px; height: 40px; object-fit: contain; border-radius: 4px; }
.pipe-node--zb .ok {
  font: 600 9px/1 var(--mono); letter-spacing: .1em; text-transform: uppercase;
  color: var(--brand); opacity: 0;
}

/* 连线：虚线管道 */
.pipe-wire {
  position: relative; height: 2px; width: 100%; align-self: center;
  background: repeating-linear-gradient(90deg,
    var(--line-2) 0 6px, transparent 6px 12px);
}

/* 数据包 */
.packet {
  position: absolute; top: 50%; margin-top: -6px; left: 0;
  width: 12px; height: 12px; border-radius: 50%;
  background: var(--brand); box-shadow: 0 0 14px var(--brand);
}
html.js .pk1 { animation: pk1 7s cubic-bezier(.4, 0, .2, 1) infinite; }
html.js .pk2 { animation: pk2 7s cubic-bezier(.4, 0, .2, 1) infinite; }
@keyframes pk1 {
  0%, 4%    { left: 0; opacity: 0; transform: scale(.5); }
  8%        { opacity: 1; transform: scale(1); }
  22%       { left: calc(100% - 12px); opacity: 1; }
  27%, 100% { left: calc(100% - 12px); opacity: 0; }
}
@keyframes pk2 {
  0%, 26%   { left: 0; opacity: 0; transform: scale(.5); }
  30%       { opacity: 1; transform: scale(1); }
  44%       { left: calc(100% - 12px); opacity: 1; }
  49%, 100% { left: calc(100% - 12px); opacity: 0; }
}

/* 节点反应：时刻与包到达对齐（同一 7s 时间轴） */
html.js .pipe-node--mid { animation: mid-hit 7s ease infinite; }
@keyframes mid-hit {
  0%, 20%   { border-color: var(--line-2); box-shadow: none; }
  24%, 30%  { border-color: var(--brand); box-shadow: 0 0 20px var(--brand-dim); }
  36%, 100% { border-color: var(--line-2); box-shadow: none; }
}
html.js .zb-glyph { animation: zb-get 7s ease infinite; }
@keyframes zb-get {
  0%, 42%   { opacity: .25; transform: scale(.8); color: var(--t6); }
  48%, 86%  { opacity: 1; transform: scale(1); color: var(--brand); }
  92%, 100% { opacity: .25; transform: scale(.8); color: var(--t6); }
}
html.js .pipe-node--zb .ok { animation: ok-in 7s ease infinite; }
@keyframes ok-in {
  0%, 46%   { opacity: 0; transform: translateY(4px); }
  52%, 86%  { opacity: 1; transform: none; }
  92%, 100% { opacity: 0; transform: translateY(4px); }
}

@media (max-width: 900px) {
  /* 窄屏改为纵向：管道转 90° */
  .pipe { grid-template-columns: 1fr; gap: 16px; }
  .pipe-wire {
    width: 2px; height: 40px; justify-self: center;
    background: repeating-linear-gradient(180deg,
      var(--line-2) 0 6px, transparent 6px 12px);
  }
}
@media (max-width: 640px) {
  .pipe { padding: 20px 16px; }
}

/* ══════════════════════════════════════════════════════════════════════════
   焦虑区：大字 + 小字双层标题（2026-09-20）
   小字（.k）先淡入，大字（.b）稍后跟上 —— 用 --cd 做错峰。
   ★ 默认可见，只有 html.js 时才开始隐藏（与全站 .reveal 的约定一致）。
   ══════════════════════════════════════════════════════════════════════════ */
.pain-h, .pivot { display: flex; flex-direction: column; }
.pain-h .k, .pain-h .b, .pivot .b, .pivot .k {
  display: block;
  transition: opacity .5s ease, transform .6s cubic-bezier(.2, .7, .3, 1);
  transition-delay: calc(var(--cd, 0) * 90ms);
}
html.js .reveal:not(.in) .k, html.js .reveal:not(.in) .b {
  opacity: 0; transform: translateY(16px);
}
html:not(.js) .reveal .k, html:not(.js) .reveal .b { opacity: 1; transform: none; }

.pain-h .k { font: 600 12.5px/1 var(--mono); letter-spacing: .16em;
             text-transform: uppercase; color: var(--brand);
             margin-bottom: 12px; --cd: 0; }
.pain-h .b { font-size: clamp(27px, 3.6vw, 46px); font-weight: 800;
             line-height: 1.08; letter-spacing: -.03em; color: var(--t1);
             --cd: 1; }

.pivot { margin: 34px 0 14px; }
.pivot .b { font-size: clamp(23px, 3vw, 36px); font-weight: 800;
            line-height: 1.12; letter-spacing: -.025em; color: var(--brand);
            --cd: 0; }
.pivot .k { margin-top: 10px; font-size: clamp(13px, 1.1vw, 15px);
            color: var(--t4); --cd: 1; }

@media (prefers-reduced-motion: reduce) {
  .pain-h .k, .pain-h .b, .pivot .b, .pivot .k { transition: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   焦虑区卡片轨道（2026-09-20）
   —— 横排卡片，一次看 3~4 张，其余横向滚动；入场左右飞入。
   ══════════════════════════════════════════════════════════════════════════ */
/* ★ 这里**没有** scroll-snap，是刻意的（2026-09-20）：
   轨道现在会自动巡航（home.js），而 snap 吸附会在每一帧程序化设置
   scrollLeft 之后把位置拽回吸附点 —— 表现是整条轨道一抖一抖。
   自动巡航和 snap 二选一，选了前者。 */
/* ★ 满屏：.pain-track 在 markup 里是 <section> 的**直接子元素**，不在 .wrap 里
   —— 所以它打穿整页宽度，跟下面的评价墙一样。左右两端用 mask 渐隐。
   ★ 滚动条藏掉：mask 会把两端的滚动条槽也渐隐，露出来就是断的；
     而卡片本来就在自己巡航，滚动条不是唯一提示。 */
.pain-track {
  display: grid; grid-auto-flow: column;
  grid-auto-columns: 300px;
  gap: 16px; margin-top: 26px; padding: 4px 0 16px;
  overflow-x: auto; overscroll-behavior-x: contain;
  scroll-behavior: auto;              /* 防任何 smooth 设定，程序化滚动必须立刻生效 */
  scrollbar-width: none;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
}
.pain-track::-webkit-scrollbar { display: none; }

/* 固定 300×350 —— 等高等宽才排得齐，横向滚动时也不会一卡一卡地变高。
   文字占满剩下的空间（.pt 是 flex:1），所以字号放大也不会把卡片撑开。 */
.pain-card {
  height: 350px;
  display: flex; flex-direction: column; gap: 10px;
  padding: 16px 16px; border-radius: 12px;
  background: linear-gradient(180deg, #161616, #121212);
  border: 1px solid #242424; border-left: 3px solid #7a3300;
  transition: transform .5s cubic-bezier(.2, .7, .3, 1),
              opacity .5s ease, border-color .25s ease;
  transition-delay: calc(var(--i, 0) * 70ms);
}
.pain-card:hover { border-color: #3a3a3a; border-left-color: var(--brand); }
.pain-card .pn { font: 700 13px/1 var(--mono); letter-spacing: .1em;
                 color: var(--brand); opacity: .8; }
/* ★ 卡片里的字是主角 —— 22px → clamp(19px, 1.8vw, 26px)。
   flex:1 让它吃掉编号以外的全部高度，所以放大字号也不会把 350px 撑开。
   ★ 26px / 行高 1.35 是**实测出来的天花板**：再往上（27px，或 26px 时行高 1.4）
     英文第 4 张卡就刚好顶满 293px 可用高度，只剩 2px 余量，换个字体/系统就会溢出。
     现在最挤的语言（en）还剩 12px。要更大只有两条路：卡片加高，或把英文长句改短。 */
.pain-card .pt { flex: 1; font-size: clamp(19px, 1.8vw, 26px); font-weight: 600;
                 line-height: 1.35; color: var(--t2); }

/* 入场：奇数从左飞，偶数从右飞 */
html.js .reveal:not(.in) .pain-card { opacity: 0; }
html.js .reveal:not(.in) .pain-card:nth-child(odd)  { transform: translateX(-46px); }
html.js .reveal:not(.in) .pain-card:nth-child(even) { transform: translateX(46px); }
html:not(.js) .reveal .pain-card { opacity: 1; transform: none; }

/* 数字条（222 / 0 / ~50ms / 1）—— 全页最狠的一组对照，
   字号必须压过正文。site.css 里的 26px 是全站默认值，这里只在首页放大。 */
.stats .stat { padding: 22px 12px; }
.stats .stat b { font-size: clamp(36px, 4.8vw, 56px); letter-spacing: -.02em; }
.stats .stat span { margin-top: 10px; font-size: clamp(13px, 1.15vw, 15.5px); }

/* 只有手机窄到装不下 300px 时才让步（300 + 两侧留白 > 屏幕） */
@media (max-width: 380px) {
  .pain-track { grid-auto-columns: 84vw; }
  .pain-card { height: 320px; }
}

/* 视频上方的大标题 —— 白色放大，居中，和视频同宽对齐 */
h3.video-h {
  max-width: 800px; margin: 56px auto 0; text-align: center;
  color: #fff; font-size: clamp(21px, 2.7vw, 32px); font-weight: 800;
  line-height: 1.3; letter-spacing: -.02em;
}
h3.video-h::after { margin: 16px auto 0; transform-origin: center; }

@media (max-width: 720px) {
  h3.video-h { margin-top: 40px; font-size: clamp(19px, 5vw, 24px); }
}
.pivot .tick { width: 1.05em; height: 1.05em; vertical-align: -.12em;
               margin-right: .3em; overflow: visible; }
.pivot .tick path { fill: none; stroke: #22C55E; stroke-width: 3;
                    stroke-linecap: round; stroke-linejoin: round;
                    stroke-dasharray: 34; stroke-dashoffset: 34; }
html:not(.js) .pivot .tick path { stroke-dashoffset: 0; }
html.js .pivot.in .tick path {
  animation: tickDraw .34s ease forwards;
  animation-delay: .2s; }
@keyframes tickDraw { to { stroke-dashoffset: 0; } }

/* ── 对照表：两栏左右互换（2026-09-20）─────────────────────────────────
   用户要求「配上 SculptBox」挪到**左边**、「你的日常」挪到右边。
   左栏（解决后的样子）文字放大 + 每行一个绿勾；右栏（原来的痛点）保持原样。
   site.css 里的 .tbl.cmp 规定的是旧顺序，这里覆盖掉。 */
table.tbl.cmp td { vertical-align: top; }
table.tbl.cmp td.fx { width: 58%; color: #E8E8E8;
                      font-size: 1.32em; font-weight: 600; line-height: 1.45; }
table.tbl.cmp td.pn-cell { width: 42%; color: #777; }
table.tbl.cmp .tick { width: .92em; height: .92em; vertical-align: -.13em;
                      margin-right: .5em; overflow: visible; }
table.tbl.cmp .tick path { fill: none; stroke: #22C55E; stroke-width: 3;
                           stroke-linecap: round; stroke-linejoin: round;
                           stroke-dasharray: 34; stroke-dashoffset: 34; }
html:not(.js) table.tbl.cmp .tick path { stroke-dashoffset: 0; }
html.js table.tbl.reveal.in .tick path {
  animation: tickDraw .34s ease forwards;
  /* 一行一个勾，前一个收笔下一个才起笔（.38s 一格 > .34s 画线） */
  animation-delay: calc(.2s + var(--d, 0) * .38s); }

@media (max-width: 720px) {
  /* 手机上两栏挤成一条，放大字号会把右栏压没 —— 回到等宽 */
  table.tbl.cmp td.fx { width: 56%; font-size: 1.12em; }
}

@media (prefers-reduced-motion: reduce) {
  .pain-card { transition: none; }
  html.js .reveal:not(.in) .pain-card { opacity: 1; transform: none; }
  html.js .pivot.in .tick path { animation: none; stroke-dashoffset: 0; }
}
