/* ─────────────────────────────────────────────────────────────
   LanZ · 产业链溯源 Agent 产品页(/products/chain/)专属样式

   来源:外部设计交付(Lanzdata产业链溯源.zip)。这一版的主题是**流动**:
   除首屏外每一段都有持续运行的动效,不靠静态卡片撑画面。
   只被这一个页面引用 —— 首页与其余五个产品页都不加载。

   集成时做了五处改造, 都是本站硬约束逼出来的, 别改回去:

   1. **所有选择器收进 .chainx 作用域。** 设计稿用的是 .hero / .wrap /
      .btn / .nav / .chip / .dot / .panel / .body 这些通用类名, 而
      style.css 全站加载、同名类全都有。不隔离的话两边互相覆盖,
      顶栏会散架, 页面也拿不到设计稿的样子。
      (:root 留在全局 —— 本文件只在这一页加载, 漏不出去;
       变量名已逐个比对过, 与 tokens.css / style.css 零重名。)

   2. **动画名加了 cx- 前缀。** 设计稿的 @keyframes breathe / sweep /
      rise 与 style.css 里的同名, 后加载的那份会整体覆盖前一份。

   3. **字体换成站里的系统字体栈。** 原稿引 Google Fonts, 本站 CSP 是
      default-src 'none' 起步, 外链字体会被浏览器直接拦掉, 而且不报错
      —— 只会静默回退。SVG 里的 font-family 属性也一并删掉了, 靠
      继承拿 --font-body, 带 class="mono" 的组继承 --font-mono。
      ⚠ 代价:原稿的 font-weight:900 在系统中文字体里没有对应字重,
      会回退到 700, 标题比设计稿略轻。

   4. **设计稿自带的胶囊顶栏与页脚样式整段删掉。** 那两块用站里统一的
      (build.sh 逐页比对, 不一致直接失败)。

   5. **[data-rise] 的隐藏态挂在 html.cx-rise 上。** 原稿直接写
      [data-rise]{opacity:0}, JS 一挂整段内容就永远不显示。本站的规矩
      是「内容默认可见, JS 只负责隐藏」—— 见 style.css 的 .reveal。

   设计系统说明见交付附带的 README;色值是设计稿给的 hex,
   ⚠ 没有转成 OKLCH —— 与 tokens.css 的口径不一致, 是笔已知的账。
   ───────────────────────────────────────────────────────────── */
:root{
  --ink:#12112B;  /* 主文字 */
  --ink-2:#3A3752;  /* 正文 */
  --ink-3:#6B6884;  /* 弱文字 / 标签 */
  --bg:#EEF0F7;  /* 浅底 */
  --bg-card:#fff;
  --dark:#0B0A1E;  /* 深底（首屏 / CTA） */
  --dark-2:#08071A;
  --panel:#131130;  /* 深色图表卡 */
  --panel-bar:#0E0C24;  /* 卡片标题栏 */
  --node:#1D1A44;  /* 图内节点填充 */
  --node-line:#4C3D87;  /* 图内连线 / 描边 */
  --purple:#7B4DEB;  /* 主品牌紫 */
  --purple-d:#6D3FE0;  /* 浅底上的紫（文字可用） */
  --purple-l:#8B62F0;
  --purple-lt:#A98CFF;  /* 深底上的紫（文字可用） */
  --purple-pale:#B79EFF;
  --on-dark:#EDEBF7;
  --on-dark-2:#B4B1C9;
  --on-dark-3:#9E9BB8;
  --on-dark-4:#8A87A6;
  --warn:#E8734A;  /* 断点橙 */
  --warn-l:#F09D7B;
  --grid:rgba(160,150,255,.055);
  --hair-d:rgba(180,170,255,.16);  /* 深色上的分隔线 */
  --hair-l:rgba(18,17,43,.14);  /* 浅色上的分隔线 */
  /* 只用于 h1 里「Agent」的渐变收尾, 本页没有别的用途 ——
     在供需页它是有语义的(青 = 供给侧), 这里纯装饰。 */
  --cyan:#3FD2E8;
  --maxw:1280px;
  --pad:40px;
}
body{ background:var(--bg); color:var(--ink) }
.chainx, .chainx *{ box-sizing:border-box }
.chainx a{ color:var(--purple-d); text-decoration:none }
.chainx a:hover{ color:var(--purple-l) }
.chainx .mono{ font-family:var(--font-mono) }
.chainx .wrap{ max-width:var(--maxw); margin:0 auto; padding:0 var(--pad) }
.chainx .grid-tex{
  position:absolute;
  inset:0;
  pointer-events:none;
  background-image:linear-gradient(var(--grid) 1px,transparent 1px),linear-gradient(90deg,var(--grid) 1px,transparent 1px);
  background-size:64px 64px;
}
/* 图内文字:删掉原稿的 font-family 属性后靠继承拿字体栈。
   用继承而不是 .chainx svg text{...} —— 后者会盖掉 <g class="mono">
   往下传的等宽字体, 坐标轴数字就跟正文一个字体了。 */

/* ---------- 按钮 ---------- */
.chainx .btn{
  display:inline-block;
  white-space:nowrap;
  padding:19px 46px;
  border-radius:999px;
  background:var(--purple);
  color:#fff;
  font-size:17px;
  font-weight:700;
  box-shadow:0 14px 44px rgba(123,77,235,.5);
}
.chainx .btn:hover{ background:var(--purple-l); color:#fff }

/* ---------- 首屏 ---------- */
/* ⚠ 原稿是 margin-top:-88px —— 那是为了钻到它自带的 sticky 胶囊导航
   下面。本站顶栏是 position:fixed, 不占文档流, 首屏本来就从页面顶端
   开始, 再拉 -88px 会把大标题整个顶出屏幕。改成 0, 上边距交给 padding。
   min-height 不是 height —— 窄屏上内容会比 100vh 高, 写死 height 会
   让它溢出到下一屏并被 overflow:hidden 切掉。 */
.chainx .cx-hero{
  position:relative;
  padding:186px 0 130px;
  min-height:100vh;
  display:flex;
  align-items:center;
  background:var(--dark);
  color:var(--on-dark);
  overflow:hidden;
}
.chainx .cx-hero > .wrap{ width:100% }
.chainx .cx-hero .glow-a{
  position:absolute;
  top:-180px;
  left:8%;
  width:820px;
  height:620px;
  filter:blur(10px);
  background:radial-gradient(ellipse at center,rgba(123,77,235,.38),rgba(11,10,30,0) 68%);
}
.chainx .cx-hero .glow-b{
  position:absolute;
  top:120px;
  right:-120px;
  width:640px;
  height:640px;
  background:radial-gradient(circle at center,rgba(64,196,255,.13),rgba(11,10,30,0) 70%);
}
.chainx .hero-grid{
  position:relative;
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,1.02fr);
  gap:66px;
  align-items:center;
}
.chainx .cx-hero h1{
  margin:0;
  font-size:clamp(40px,4.2vw,62px);
  line-height:1.14;
  font-weight:900;
  letter-spacing:-.02em;
  color:#fff;
}
/* 「Agent」那一段的渐变字。⚠ 与另外四个 Agent 页逐字相同, 改一处要五处
   一起改 —— 五页的标题摆在一起看, 渐变角度或色标差一点就很显眼。
   ⚠ color:transparent 收在 @supports 里:万一 background-clip:text 不生效,
   落回实色标题, 而不是一个看不见的大标题。 */
.chainx .cx-hero h1 em{ font-style:normal }
@supports (-webkit-background-clip:text) or (background-clip:text){
  .chainx .cx-hero h1 em{
    background:linear-gradient(96deg,#fff 18%,var(--purple-lt) 62%,var(--cyan) 100%);
    -webkit-background-clip:text;
    background-clip:text;
    color:transparent;
  }
}
.chainx .cx-hero p{
  margin:30px 0 0;
  font-size:18.5px;
  line-height:1.85;
  color:var(--on-dark-2);
  max-width:26em;
}
.chainx .cx-hero .btn{ margin-top:44px }

/* ---------- 深色图表卡 ---------- */
.chainx .panel{
  border-radius:16px;
  background:var(--panel);
  border:1px solid var(--hair-d);
  overflow:hidden;
  box-shadow:0 40px 90px rgba(4,3,14,.6);
}
.chainx .panel-bar{
  display:flex;
  align-items:center;
  gap:10px;
  padding:12px 18px;
  background:var(--panel-bar);
  border-bottom:1px solid rgba(180,170,255,.12);
}
.chainx .panel-bar .t{ font-size:11.5px; letter-spacing:.1em; color:var(--on-dark-4) }
.chainx .panel-bar .r{
  margin-left:auto;
  display:flex;
  align-items:center;
  gap:7px;
  font-size:11.5px;
  color:var(--on-dark-4);
}
.chainx .dot{
  width:6px;
  height:6px;
  border-radius:999px;
  background:var(--purple-l);
  animation:cx-breathe 2.4s ease-in-out infinite;
}
.chainx .panel-body{ padding:20px 20px 24px }
.chainx .tiers{
  display:grid;
  grid-template-columns:repeat(3,minmax(0,1fr));
  gap:14px;
  margin-bottom:14px;
  font-size:11px;
  letter-spacing:.16em;
  color:var(--on-dark-4);
}
/* 悬浮白卡（首屏） */
.chainx .float{
  position:absolute;
  z-index:2;
  background:#fff;
  border-radius:12px;
  box-shadow:0 20px 48px rgba(4,3,14,.46);
  animation:cx-drift 7s ease-in-out infinite;
}
.chainx .float.pri{ left:-44px; bottom:-84px; width:196px; padding:14px 16px; animation-delay:-2.4s }
.chainx .float.rate{
  right:-22px;
  top:-88px;
  padding:11px 15px;
  display:flex;
  align-items:center;
  gap:11px;
}
.chainx .float .lbl{ font-size:11.5px; color:var(--ink-3); font-weight:500 }
.chainx .pri-row{ display:flex; align-items:center; gap:9px }
.chainx .pri-row .n{ font-size:10.5px; color:var(--ink-3) }
.chainx .pri-row .name{ font-size:12.5px; color:var(--ink) }
.chainx .pri-row .bar{ margin-left:auto; height:5px; width:44px; border-radius:3px }

/* ============ 全局流动件 ============ */
@keyframes cx-dash{ to{ stroke-dashoffset:-18 } }
@keyframes cx-breathe{ 0%,100%{ opacity:.4 } 50%{ opacity:1 } }
@keyframes cx-sweep{ 0%{ transform:translateX(-110%) } 100%{ transform:translateX(320%) } }
@keyframes cx-drift{ 0%,100%{ transform:translateY(0) } 50%{ transform:translateY(-10px) } }
@keyframes cx-rise{ from{ opacity:0; transform:translateY(24px) } to{ opacity:1; transform:none } }
@keyframes cx-flow{ to{ stroke-dashoffset:-26 } }
@keyframes cx-slideL{ to{ transform:translateX(-50%) } }
@keyframes cx-slideR{ from{ transform:translateX(-50%) } to{ transform:none } }
@keyframes cx-lift{ 0%{ transform:translateY(0); opacity:0 } 12%{ opacity:.7 } 100%{ transform:translateY(-190px); opacity:0 } }
.chainx .dashline{ animation:cx-dash 1.1s linear infinite }
/* 隐藏态挂在 html.cx-rise 上:只有 JS 确认 IntersectionObserver 可用
   才加这个类。JS 挂了 = 内容照常显示, 不会白屏。 */
html.cx-rise .chainx [data-rise]{ opacity:0 }
.chainx [data-rise="in"]{ animation:cx-rise .9s cubic-bezier(.16,.84,.34,1) both }

.chainx .eyebrow{ font-size:12px; letter-spacing:.24em }
.chainx .sect-h2{
  margin:26px 0 0;
  font-size:clamp(34px,3.6vw,46px);
  line-height:1.18;
  font-weight:900;
  letter-spacing:-.025em;
}
.chainx .sect-p{
  margin:24px 0 0;
  font-size:17.5px;
  line-height:1.9;
  color:var(--ink-2);
  max-width:27em;
}
.chainx .stats{ display:flex; flex-wrap:wrap; gap:14px 52px }
.chainx .stats .k{ display:block; font-size:12.5px; color:var(--ink-3) }
.chainx .stats .v{
  display:block;
  font-size:34px;
  font-weight:900;
  letter-spacing:-.03em;
  margin-top:3px;
  color:var(--ink);
}
/* ⚠ 浅底上的橙字用加深过的 #B85423 —— 填充色 --warn 当小字用
   只有 2.4:1, 读不了。描边/填充才用 --warn。 */
.chainx .stats .v.warn{ color:#B85423 }

/* ============ 底座落位：横向流动的企业带 ============ */
.chainx .origin{ position:relative; background:var(--bg); padding:104px 0 110px; overflow:hidden }
/* ⚠ 原稿这两块叫 .head / .foot。.head 在 style.css 里是首页六个 section
   的双栏标题块(display:grid + ::before 一条紫线), 作用域再怎么收也挡不住
   —— 同名类会连 display 一起继承过来, 标题和引言被拆成左右两栏, 上面还
   多出一条线。所以改名 cx-head / cx-foot, 两个一起改是为了成对好认。 */
.chainx .origin .cx-head{ max-width:var(--maxw); margin:0 auto; padding:0 var(--pad) }
.chainx .origin .eyebrow{ color:var(--purple-d) }
/* 两侧淡出, 让带子看着是从画外流进来的, 而不是被容器切断的 */
.chainx .lanes{
  position:relative;
  margin:52px 0 46px;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 9%,#000 91%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 9%,#000 91%,transparent);
}
/* ⚠ 每条带子的内容在 HTML 里重复两遍, 位移到 -50% 正好接回起点 ——
   无缝循环靠这个。删掉后半截会看到明显的回跳。 */
.chainx .lane{ display:flex; gap:14px; width:max-content; padding:7px 0 }
.chainx .lane.a{ animation:cx-slideL 52s linear infinite }
.chainx .lane.b{ animation:cx-slideR 64s linear infinite }
.chainx .lane.c{ animation:cx-slideL 42s linear infinite }
.chainx .pill{
  flex:none;
  padding:11px 19px;
  border-radius:999px;
  background:#fff;
  font-size:14px;
  color:var(--ink-2);
  box-shadow:0 2px 9px rgba(18,17,43,.06);
  white-space:nowrap;
}
.chainx .pill.on{
  background:var(--purple);
  color:#fff;
  font-weight:700;
  box-shadow:0 10px 26px rgba(123,77,235,.34);
}
.chainx .pill.out{ background:transparent; border:1px dashed #D2622F; color:#B85423; box-shadow:none }
.chainx .origin .cx-foot{
  max-width:var(--maxw);
  margin:0 auto;
  padding:0 var(--pad);
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:56px;
  align-items:end;
}

/* ============ 四段：一张持续变形的图谱 ============ */
/* ⚠ #four 必须 overflow-x:clip 而不是 hidden。
   hidden + overflow-y:visible 会被算成 overflow-y:auto, 该元素就变成
   滚动容器, 里面的 sticky 拿它当参照系但它自己不滚 —— 完全不钉住。
   (html 与 body 那两处 style.css 里已经是 clip 了。) */
.chainx #four{ position:relative; overflow-x:clip }
/* 高度由四段文案自己撑开, 不写死。
   ⚠ 原来是 .steps{height:400vh} + .steps-pin{position:sticky} 整块钉住:
     那四屏行程里滚轮只换图谱的 class, 页面看着一动不动 —— 像卡死,
     而且要一路滚回第一段才退得出去。现在钉住的只有右栏图谱,
     左栏文案照常滚, 滚轮行为和站里别处一样。别改回去。 */
.chainx .steps{
  position:relative;
  background:linear-gradient(180deg,var(--bg) 0,#0B0A1E 5%,#0B0A1E 95%,var(--bg) 100%);
}
/* 背景层:网格底纹 + 紫光晕。原本挂在钉住的 .steps-pin 上, 跟着视口走;
   这一段现在有四屏高, 底纹直接铺满会把径向蒙版拉变形, 所以单拎出一层
   sticky 的满屏背景, 再用 margin-bottom:-100vh 把它占的布局高度抵掉。 */
.chainx .steps-bg{
  position:sticky;
  top:0;
  z-index:0;
  height:100vh;
  margin-bottom:-100vh;
  pointer-events:none;
}
.chainx .steps-bg::before{
  content:"";
  position:absolute;
  inset:0;
  background-image:linear-gradient(var(--grid) 1px,transparent 1px),linear-gradient(90deg,var(--grid) 1px,transparent 1px);
  background-size:64px 64px;
  -webkit-mask-image:radial-gradient(ellipse 78% 72% at 34% 50%,#000,transparent);
  mask-image:radial-gradient(ellipse 78% 72% at 34% 50%,#000,transparent);
}
.chainx .steps-bg::after{
  content:"";
  position:absolute;
  left:-12%;
  top:50%;
  width:880px;
  height:740px;
  transform:translateY(-50%);
  background:radial-gradient(ellipse at center,rgba(123,77,235,.28),rgba(11,10,30,0) 66%);
  animation:cx-breathe 7s ease-in-out infinite;
}
.chainx .steps-lay{
  position:relative;
  z-index:1;
  display:grid;
  grid-template-columns:minmax(0,.82fr) minmax(0,1.18fr);
  align-items:start;
  color:var(--on-dark);
}
.chainx .steps-track{ min-width:0 }
/* 右栏图谱钉在视口中央。height:100vh + 居中, 而不是 top:某个值 ——
   图谱本身高度会随窗口宽度变, 居中才不会在窄窗口里贴着顶栏。 */
.chainx .steps-graph{
  position:sticky;
  top:0;
  height:100vh;
  min-width:0;
  display:flex;
  flex-direction:column;
  justify-content:center;
}
/* 每段占满一屏:图谱状态跟着当前段切, 一段太矮会在一次滚动里连跳两段。 */
.chainx .steps-copy{
  position:relative;
  min-height:100vh;
  display:flex;
  flex-direction:column;
  justify-content:center;
  min-width:0;
  padding:0 48px 0 calc(max(0px,(100vw - var(--maxw)) / 2) + var(--pad));
}
.chainx .ghost{
  position:absolute;
  left:-16px;
  top:50%;
  transform:translateY(-56%);
  z-index:0;
  font-family:var(--font-mono);
  font-size:clamp(170px,21vw,300px);
  font-weight:500;
  line-height:.8;
  letter-spacing:-.04em;
  color:rgba(171,140,255,.07);
  pointer-events:none;
  user-select:none;
}
/* 文案要压在 .ghost 那个大号数字上面 */
.chainx .steps-copy > *:not(.ghost){ position:relative; z-index:1 }
.chainx .pips{ display:flex; gap:6px; margin-bottom:32px }
.chainx .pips span{
  position:relative;
  width:46px;
  height:2px;
  background:rgba(180,170,255,.2);
  overflow:hidden;
}
.chainx .pips span i{
  position:absolute;
  inset:0;
  background:var(--purple-lt);
  box-shadow:0 0 14px rgba(169,140,255,.8);
  transform:scaleX(0);
  transform-origin:left;
  transition:transform .5s cubic-bezier(.16,.84,.34,1);
}
.chainx .pips span.on i{ transform:none }
.chainx .steps-copy .eyebrow{ color:var(--purple-lt) }
.chainx .steps-copy h3{
  margin:20px 0 0;
  font-size:clamp(32px,3.3vw,44px);
  line-height:1.16;
  font-weight:900;
  letter-spacing:-.025em;
  color:#fff;
}
.chainx .steps-copy .body{
  margin:22px 0 0;
  font-size:17px;
  line-height:1.9;
  color:var(--on-dark-2);
  max-width:24em;
}
.chainx .steps-stat{
  display:flex;
  align-items:baseline;
  gap:14px;
  margin-top:34px;
  padding-top:24px;
  border-top:1px solid rgba(180,170,255,.18);
}
.chainx .steps-stat .big{
  font-size:clamp(42px,4.8vw,60px);
  font-weight:900;
  letter-spacing:-.04em;
  background:linear-gradient(120deg,#fff 10%,#A98CFF 62%,#7B4DEB 100%);
  -webkit-background-clip:text;
  background-clip:text;
  color:transparent;
}
.chainx .steps-stat .sub{ font-size:14.5px; color:var(--on-dark-3); line-height:1.7; max-width:13em }
.chainx .graph{
  position:relative;
  z-index:1;
  min-width:0;
  padding-right:max(var(--pad),calc((100vw - var(--maxw)) / 2));
}
.chainx .graph .cap{
  display:flex;
  align-items:center;
  gap:10px;
  font-family:var(--font-mono);
  font-size:11.5px;
  letter-spacing:.1em;
  color:var(--on-dark-4);
  padding-bottom:16px;
  border-bottom:1px solid rgba(180,170,255,.16);
}
/* min-height 占住一行:注释在四段之间长短不一, 不占位会让整张图上下跳 */
.chainx .graph .note{
  margin:20px 0 0;
  font-family:var(--font-mono);
  font-size:12.5px;
  letter-spacing:.04em;
  color:var(--purple-pale);
  min-height:1.4em;
}
.chainx .graph svg{ width:100%; height:auto; display:block; margin-top:24px }
/* 节点与连线不重新渲染, render() 只改 class, 变形交给 transition */
.chainx .lk{
  fill:none;
  stroke:#5A4A96;
  stroke-width:1.7;
  stroke-dasharray:4 9;
  animation:cx-flow 1.1s linear infinite;
  transition:stroke .6s,opacity .6s,stroke-width .6s;
}
.chainx .lk.dim{ opacity:.22 }
.chainx .lk.gap{ stroke:#E8734A }
.chainx .lk.on{ stroke:#A98CFF; stroke-width:2.2 }
.chainx .lk.hide{ opacity:0 }
.chainx .nd{ transition:opacity .6s }
.chainx .nd rect{ fill:#1D1A44; stroke:#4C3D87; transition:fill .6s,stroke .6s,opacity .6s }
.chainx .nd text{ fill:#D9D5F0; transition:fill .6s,opacity .6s }
.chainx .nd.dim{ opacity:.3 }
.chainx .nd.hot rect{ fill:#7B4DEB; stroke:#CFC4FF }
.chainx .nd.hot text{ fill:#fff; font-weight:700 }
.chainx .nd.ext rect{ fill:#151330; stroke:#3A3560 }
.chainx .nd.ext text{ fill:#8A87A6 }
.chainx .nd.gap rect{ fill:rgba(232,115,74,.12); stroke:#E8734A; stroke-dasharray:5 4 }
.chainx .nd.gap text{ fill:#F09D7B }
.chainx .nd.hide{ opacity:0 }

/* ============ 回查：溯源轨迹 ============ */
.chainx .trace{ position:relative; background:#fff; padding:108px 0 112px; overflow:hidden }
.chainx .trace .wrap{
  display:grid;
  grid-template-columns:minmax(0,.9fr) minmax(0,1.1fr);
  gap:64px;
  align-items:center;
}
.chainx .trace .eyebrow{ color:var(--purple-d) }
.chainx .chip{
  padding:11px 20px;
  border-radius:999px;
  background:var(--bg);
  font-size:14.5px;
  font-weight:700;
  color:var(--ink);
}
.chainx .tr-lk{
  fill:none;
  stroke:#C3B6F2;
  stroke-width:1.6;
  stroke-dasharray:4 8;
  animation:cx-flow 1.3s linear infinite;
}
.chainx .tr-box rect{ fill:#F4F2FB; stroke:#DCD6F2 }
.chainx .tr-box.hot rect{ fill:var(--purple); stroke:var(--purple) }
.chainx .tr-box text{ fill:var(--ink-2) }
.chainx .tr-box.hot text{ fill:#fff; font-weight:700 }

/* ============ CTA ============ */
.chainx .cta{
  position:relative;
  background:var(--dark);
  color:var(--on-dark);
  padding:112px 0 118px;
  overflow:hidden;
}
.chainx .cta .glow{
  position:absolute;
  top:-150px;
  left:50%;
  width:920px;
  height:580px;
  transform:translateX(-50%);
  background:radial-gradient(ellipse at center,rgba(123,77,235,.34),rgba(11,10,30,0) 70%);
  animation:cx-breathe 7s ease-in-out infinite;
}
.chainx .cta .beam{
  position:absolute;
  top:0;
  left:0;
  right:0;
  height:2px;
  overflow:hidden;
  background:rgba(180,170,255,.1);
}
.chainx .cta .beam i{
  position:absolute;
  top:0;
  bottom:0;
  width:22%;
  background:linear-gradient(90deg,rgba(169,140,255,0),#A98CFF,rgba(169,140,255,0));
  animation:cx-sweep 4.2s linear infinite;
}
.chainx .motes{ position:absolute; inset:0; pointer-events:none }
.chainx .motes i{
  position:absolute;
  bottom:0;
  width:3px;
  height:3px;
  border-radius:999px;
  background:#A98CFF;
  animation:cx-lift 9s linear infinite;
}
.chainx .cta h2{
  margin:0;
  font-size:clamp(38px,4.4vw,54px);
  line-height:1.16;
  font-weight:900;
  letter-spacing:-.025em;
  color:#fff;
}
.chainx .cta p{
  margin:26px auto 0;
  font-size:18px;
  line-height:1.9;
  color:var(--on-dark-2);
  max-width:28em;
}

/* ---------- 响应式 ---------- */
/* 窄屏:两栏并排放不下, 改成图谱钉在顶栏底下、四段文案从它下面滚过去。
   ⚠ 别退回「图谱跟着文案一起滚」—— 图谱是这四段的主语, 滚走了以后
     下面三段文案就没有对照物了。(旧版是窄屏只渲染第一段, 另外三段
     根本读不到, 那是笔已经还掉的账。) */
@media (max-width:1080px){
  .chainx .hero-grid,
  .chainx .trace .wrap,
  .chainx .origin .cx-foot{ grid-template-columns:minmax(0,1fr) }
  .chainx .hero-grid{ gap:40px }
  .chainx .cx-hero{ padding:150px 0 96px }
  .chainx .float{ position:static; margin-top:18px; width:auto }
  .chainx .steps{ background:#0B0A1E }
  .chainx .steps-bg{ display:none }
  .chainx .steps-lay{ display:flex; flex-direction:column }
  /* 80px = 顶栏的 16px 外边距 + 56px 高, 再留 8px。
     钉住的东西必须有不透明底色, 否则文案会从它身下透出来。 */
  .chainx .steps-graph{
    order:-1;
    position:sticky;
    top:80px;
    z-index:2;
    height:auto;
    padding:14px 0 12px;
    background:#0B0A1E;
    box-shadow:0 20px 26px -20px #0B0A1E;
  }
  /* 图谱高度是跟着**宽度**走的(viewBox 2:1), 平板宽度下能长到小半屏 ——
     钉住的东西吃掉半个视口, 下面的文案就只剩一条缝。封个顶:
     带 viewBox 的 svg 会在给定的框里等比居中, 不会拉变形。 */
  .chainx .steps-graph .graph svg{ max-height:32vh }
  .chainx .steps-copy{ min-height:74vh; padding:0 var(--pad) }
  .chainx .steps-track{ padding-bottom:64px }
  .chainx .ghost{ display:none }
  .chainx .graph{ padding:0 var(--pad) }
  .chainx .origin .cx-foot{ gap:36px }
  .chainx .trace .wrap{ gap:44px }
}
@media (prefers-reduced-motion:reduce){
  .chainx .dashline,
  .chainx .dot,
  .chainx .float,
  .chainx .lane,
  .chainx .lk,
  .chainx .tr-lk,
  .chainx .motes i,
  .chainx .cta .beam i,
  .chainx .cta .glow,
  .chainx .steps-bg::after{ animation:none }
  .chainx [data-rise="in"]{ animation:none }
  html.cx-rise .chainx [data-rise]{ opacity:1 }
}
