/* ─────────────────────────────────────────────────────────────
   LanZ · 客户 Agent 产品页(/products/client/)专属样式

   来源:外部设计交付(Lanzdata客户产品页面重设计.zip)。
   与其余三个 Agent 页共用同一套色板与字体,但**动效语汇不重合** ——
   这一页的主题是「汇聚与组装」。只被这一个页面引用。

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

   1. **所有选择器收进 .clientx 作用域。** 设计稿用的是 .hero / .wrap /
      .btn / .bar / .pane 这些通用类名, 而 style.css 全站加载、同名类
      全都有。不隔离的话两边互相覆盖, 顶栏会散架。

   2. **.hero → .cl-hero、.bar → .docbar、.pane → .docpane。**
      光靠作用域压不住这三个:style.css 的 .bar 是进度条(height:9px),
      .pane 是带 padding 的面板 —— 这类「我们没声明的属性」会照样继承
      过来。方案书的标题行被压成 9 高, 文字直接溢出去。

   3. **动画名加了 cl- 前缀。** 设计稿的 @keyframes breathe / rise 与
      style.css 里的同名, 后加载的那份会整体覆盖前一份。
      ⚠ 溯源页 cx-、招商页 iv-、政策页 pl-, 四页各一套, 不要合并 ——
      合并就等于四页共用一份动效, 改一边会静默动到另外三边。

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

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

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

   ⚠ 另外删掉了原稿里没有任何元素用到的 .chip-card 与 drift / glide
     两个 keyframes(交付说明里写了那版压边小卡已移除, 样式是残留)。

   设计系统说明见交付附带的 README;色值是设计稿给的 hex,
   ⚠ 没有转成 OKLCH —— 与 tokens.css 的口径不一致, 是笔已知的账。
   ───────────────────────────────────────────────────────────── */
:root{
  --ink:#12112B;  /* 主文字 */
  --ink-2:#3A3752;  /* 正文 */
  --ink-3:#6B6884;  /* 弱文字 / 等宽标签 */
  --dark:#0B0A1E;
  --dark-2:#08071A;
  --panel:#131130;
  --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;
  --grid:rgba(160,150,255,.055);
  --soft:#EFECF9;  /* 中间三段的平色底 —— ⚠ 勿改成渐变 */
  /* 只用于 h1 里「Agent」的渐变收尾, 本页没有别的用途 ——
     在供需页它是有语义的(青 = 供给侧), 这里纯装饰。 */
  --cyan:#3FD2E8;
  --maxw:1280px;
  --pad:40px;
}
body{ background:#EEF0F7; color:var(--ink) }
.clientx, .clientx *{ box-sizing:border-box }
.clientx a{ color:var(--purple-d); text-decoration:none }
.clientx a:hover{ color:var(--purple-l) }
.clientx button{ font-family:inherit }
.clientx .mono{ font-family:var(--font-mono) }
.clientx .wrap{ max-width:var(--maxw); margin:0 auto; padding:0 var(--pad) }
.clientx .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;
}

/* ---------- 动效基座 ----------
   ⚠ 这一页的动画**全部由滚入视野触发, 滚出复位**(client.js 的 onView)。
   写法统一是「初态写在元素上, .play 祖先类触发」—— 别把初态挪进
   .play 里, 那样元素在播放前就是终态, 滚下去只看到一个静止的图。 */
@keyframes cl-breathe{ 0%,100%{ opacity:.4 } 50%{ opacity:1 } }
@keyframes cl-orbit{ to{ transform:rotate(360deg) } }
@keyframes cl-rise{ from{ opacity:0; transform:translateY(26px) } to{ opacity:1; transform:none } }
/* 隐藏态挂在 html.cl-rise 上:只有 JS 确认 IntersectionObserver 可用
   才加这个类。JS 挂了 = 内容照常显示, 不会白屏。 */
html.cl-rise .clientx [data-rise]{ opacity:0 }
.clientx [data-rise="in"]{ animation:cl-rise .9s cubic-bezier(.16,.84,.34,1) both }
.clientx .dot{
  width:6px;
  height:6px;
  border-radius:999px;
  background:var(--purple-l);
  animation:cl-breathe 2.4s ease-in-out infinite;
}

/* ---------- 按钮 ---------- */
.clientx .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);
}
.clientx .btn:hover{ background:var(--purple-l); color:#fff }

/* ---------- 通用排版 ---------- */
.clientx .sect-h2{
  margin:0;
  font-size:clamp(34px,3.6vw,46px);
  line-height:1.18;
  font-weight:900;
  letter-spacing:-.025em;
}
.clientx .sect-p{
  margin:24px 0 0;
  font-size:17.5px;
  line-height:1.9;
  color:var(--ink-2);
  max-width:27em;
}
.clientx .stats{ display:flex; flex-wrap:wrap; gap:16px 52px }
.clientx .stats .k{ display:block; font-size:12.5px; color:var(--ink-3) }
.clientx .stats .v{
  display:block;
  font-size:32px;
  font-weight:900;
  letter-spacing:-.03em;
  margin-top:3px;
  color:var(--ink);
}
.clientx .stats .v.hi{ color:var(--purple-d) }
.clientx .cap{
  display:flex;
  align-items:center;
  gap:10px;
  padding-bottom:16px;
  font-family:var(--font-mono);
  font-size:11.5px;
  letter-spacing:.1em;
}
.clientx .cap span{ white-space:nowrap }
.clientx .cap.lt{ border-bottom:1px solid rgba(18,17,43,.12); color:var(--ink-3) }
.clientx .cap .r{ margin-left:auto }
.clientx .cluster{ position:relative; min-width:0 }
/* 浅色段的图表装白卡, 阴影很淡。⚠ 累计支出曲线那段**不套卡** ——
   它右侧紧挨着三个白色方案按钮, 再套一层白卡会跟按钮糊在一起。 */
.clientx .card{
  background:#fff;
  border-radius:16px;
  padding:24px 26px 28px;
  box-shadow:0 10px 34px rgba(18,17,43,.07);
}
/* 图表 SVG 占满卡宽。⚠ 原稿的曲线图写了两个 style 属性, 后一个被解析器
   整条丢掉, width:100% 从未生效 —— 集成时合并了, 这条是兜底。
   ⚠ 必须用**直接子代**选择器。写成 .cluster svg 会连方案书标题行里那个
   14px 的 LanZ 标记一起放大到满栏 —— 实测过, 首屏右半边只剩一个巨大的
   logo, 方案书被顶出屏幕。 */
.clientx .cluster > svg,
.clientx .card > svg{ width:100%; height:auto; display:block; margin-top:20px }

/* ---------- 首屏 ---------- */
/* ⚠ 原稿是 margin-top:-88px —— 那是为了钻到它自带的 sticky 胶囊导航
   下面。本站顶栏是 position:fixed, 不占文档流, 首屏本来就从页面顶端
   开始, 再拉 -88px 会把大标题整个顶出屏幕。改成 0, 上边距交给 padding。
   ⚠ 首屏不用卡片:方案书内容直接落在深色底上, 标题行只有一条细分隔线。
   内部所有文字、边框、进度条底色都按深底配色 —— 支出条用灰紫,
   浅底那套紫在这里会糊成一片。 */
.clientx .cl-hero{
  position:relative;
  padding:186px 0 116px;
  /* 首屏占满一屏。min-height 不是 height —— 窄屏上内容会比 100vh 高,
     写死 height 会让它溢出到下一屏并被 overflow:hidden 切掉。
     flex + center 让内容在多出来的高度里居中, 而不是全顶在上内边距下面。 */
  min-height:100vh;
  display:flex;
  align-items:center;
  overflow:hidden;
  color:var(--on-dark);
  background:linear-gradient(148deg,#0B0A1E 0%,#1B1146 50%,#2C1C60 100%);
}
.clientx .cl-hero > .wrap{ width:100% }
.clientx .cl-hero .glow{
  position:absolute;
  top:-170px;
  left:4%;
  width:860px;
  height:640px;
  filter:blur(10px);
  pointer-events:none;
  background:radial-gradient(ellipse at center,rgba(123,77,235,.36),rgba(11,10,30,0) 68%);
}
.clientx .hero-grid{
  position:relative;
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,1.02fr);
  gap:70px;
  align-items:center;
}
.clientx .cl-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 不生效,
   落回实色标题, 而不是一个看不见的大标题。 */
.clientx .cl-hero h1 em{ font-style:normal }
@supports (-webkit-background-clip:text) or (background-clip:text){
  .clientx .cl-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;
  }
}
.clientx .cl-hero p{
  margin:30px 0 0;
  font-size:18.5px;
  line-height:1.85;
  color:var(--on-dark-2);
  max-width:26em;
}
.clientx .cl-hero .btn{ margin-top:44px }
.clientx .hero-foot{ display:flex; flex-wrap:wrap; gap:14px 44px; margin-top:30px }
.clientx .hero-foot .k{ display:block; font-size:12px; color:var(--on-dark-4) }
.clientx .hero-foot .v{
  display:block;
  font-family:var(--font-mono);
  font-size:19px;
  color:#fff;
  margin-top:4px;
}

/* 方案书。⚠ 原稿的 .bar / .pane 与 style.css 同名, 见文件头第 2 条 */
.clientx .docbar{
  display:flex;
  align-items:center;
  gap:11px;
  padding-bottom:16px;
  border-bottom:1px solid rgba(180,170,255,.18);
  font-family:var(--font-mono);
  font-size:11.5px;
  letter-spacing:.1em;
  color:var(--on-dark-4);
}
/* 标题行已去掉 —— 留白跟着归零。加回 .docbar 时改回 22px */
.clientx .docpane{ padding:0 }
.clientx .blk{
  opacity:0;
  transform:translateY(14px) scale(.98);
  transition:opacity .6s cubic-bezier(.16,.84,.34,1),transform .6s cubic-bezier(.16,.84,.34,1);
}
.clientx .play .blk{ opacity:1; transform:none }
.clientx .doc-id{
  display:flex;
  align-items:center;
  gap:15px;
  padding-bottom:20px;
  border-bottom:1px solid rgba(180,170,255,.16);
}
.clientx .doc-id .av{
  width:46px;
  height:46px;
  border-radius:11px;
  flex:none;
  background:linear-gradient(140deg,var(--purple-lt),var(--purple-d));
  display:flex;
  align-items:center;
  justify-content:center;
  color:#fff;
  font-weight:900;
  font-size:17px;
}
.clientx .doc-id b{ display:block; font-size:17px; font-weight:700; letter-spacing:-.01em; color:#fff }
.clientx .doc-id s{
  display:block;
  text-decoration:none;
  font-family:var(--font-mono);
  font-size:12px;
  color:var(--on-dark-3);
  margin-top:5px;
}
.clientx .doc-3{ display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); margin-top:20px }
.clientx .doc-3 > div{ padding:0 16px; border-right:1px solid rgba(180,170,255,.16) }
.clientx .doc-3 > div:first-child{ padding-left:0 }
.clientx .doc-3 > div:last-child{ border-right:0; padding-right:0 }
.clientx .doc-3 .k{ font-size:11.5px; color:var(--on-dark-3) }
.clientx .doc-3 .v{ font-size:22px; font-weight:900; letter-spacing:-.02em; margin-top:6px; color:#fff }
.clientx .doc-3 .v.hi{ color:var(--purple-lt) }
.clientx .doc-rec{
  margin-top:20px;
  padding:16px 18px;
  border-radius:11px;
  background:rgba(123,77,235,.15);
  border:1px solid rgba(171,140,255,.26);
}
.clientx .doc-rec .k{
  font-family:var(--font-mono);
  font-size:11px;
  letter-spacing:.14em;
  color:var(--purple-pale);
}
.clientx .doc-rec .v{ font-size:16.5px; font-weight:700; color:#fff; margin-top:9px }

/* ---------- 政策瀑布 ---------- */
/* ⚠ 中间三段是同一个平色 --soft, 刻意不用渐变 ——
   三段各写一套渐变, 段与段之间的接缝会出现上下深浅不一致。 */
.clientx .pol{ position:relative; padding:116px 0; background:var(--soft) }
.clientx .pol .wrap{ position:relative }
.clientx .pol-grid{
  display:grid;
  grid-template-columns:minmax(0,.88fr) minmax(0,1.12fr);
  gap:66px;
  align-items:center;
  margin-top:46px;
}
/* transform-box:fill-box 必须留着 —— 不写的话 scaleY 以整个 SVG 的
   viewBox 为参照, 柱子会从图的底边而不是自己的底边长出来。 */
.clientx .wbar{
  transform:scaleY(0);
  transform-origin:bottom;
  transform-box:fill-box;
  transition:transform .75s cubic-bezier(.16,.84,.34,1);
}
.clientx .play .wbar{ transform:none }
.clientx .wfade{ opacity:0; transition:opacity .5s }
.clientx .play .wfade{ opacity:1 }

/* ---------- 租赁曲线 ---------- */
.clientx .lease{ position:relative; padding:116px 0; background:var(--soft) }
.clientx .lease .wrap{ position:relative }
.clientx .lease h2{
  margin:0;
  font-size:clamp(34px,3.6vw,46px);
  line-height:1.18;
  font-weight:900;
  letter-spacing:-.025em;
  color:var(--ink);
}
.clientx .lease p{ margin:24px 0 0; font-size:17.5px; line-height:1.9; color:var(--ink-2); max-width:32em }
.clientx .ls-grid{
  display:grid;
  grid-template-columns:minmax(0,1.22fr) minmax(0,.78fr);
  gap:62px;
  align-items:center;
  margin-top:50px;
}
/* 曲线末端的标签贴着 viewBox 右边界, 不放行溢出会被切掉半个字 */
.clientx #cline,
.clientx #cfill{ transition:d .85s cubic-bezier(.16,.84,.34,1) }
.clientx .curve{ overflow:visible }
.clientx .plans{ display:flex; flex-direction:column; gap:8px }
.clientx .plan{
  appearance:none;
  border:0;
  cursor:pointer;
  text-align:left;
  padding:17px 19px;
  border-radius:12px;
  background:#fff;
  box-shadow:0 2px 10px rgba(18,17,43,.06);
  transition:background .4s,box-shadow .4s;
}
.clientx .plan:hover{ background:#F6F3FD }
.clientx .plan[aria-current="true"]{
  background:rgba(123,77,235,.12);
  box-shadow:inset 0 0 0 1px rgba(123,77,235,.4);
}
/* 这一页唯一的可点元素 —— 键盘焦点必须看得见 */
.clientx .plan:focus-visible{ outline:2px solid var(--purple-d); outline-offset:2px }
.clientx .plan .nm{ display:block; font-size:17px; font-weight:900; letter-spacing:-.01em; color:var(--ink) }
.clientx .plan .sub{
  display:block;
  font-family:var(--font-mono);
  font-size:12px;
  color:var(--ink-3);
  margin-top:6px;
}
.clientx .plan-nums{
  display:grid;
  grid-template-columns:repeat(2,minmax(0,1fr));
  gap:16px 20px;
  margin-top:26px;
  padding-top:24px;
  border-top:1px solid rgba(18,17,43,.12);
}
.clientx .plan-nums .k{ display:block; font-size:12px; color:var(--ink-3) }
.clientx .plan-nums .v{
  display:block;
  font-family:var(--font-mono);
  font-size:19px;
  color:var(--ink);
  margin-top:5px;
}
.clientx .plan-nums .v.hi{ color:var(--purple-d) }

/* ---------- 链上定位 ---------- */
.clientx .chain{ position:relative; padding:116px 0 122px; background:var(--soft) }
.clientx .chain .wrap{ position:relative }
.clientx .ch-grid{
  display:grid;
  grid-template-columns:minmax(0,.86fr) minmax(0,1.14fr);
  gap:64px;
  align-items:center;
  margin-top:46px;
}
.clientx .ch-rows{ margin-top:36px; border-top:1px solid rgba(18,17,43,.12) }
.clientx .ch-row{
  display:grid;
  grid-template-columns:78px minmax(0,1fr);
  gap:20px;
  align-items:baseline;
  padding:20px 0;
  border-bottom:1px solid rgba(18,17,43,.08);
}
.clientx .ch-row .tg{ font-family:var(--font-mono); font-size:12px; color:var(--purple-d) }
.clientx .ch-row .nm{ display:block; font-size:16.5px; font-weight:700; color:var(--ink) }
.clientx .ch-row .ds{ display:block; font-size:14px; color:var(--ink-3); margin-top:6px; line-height:1.7 }
/* --len 是「够长到盖住整条路径」的 dashoffset, 由 client.js 写进来。
   比路径短的话连线一上来就露出一截, 画线动画少了开头。 */
.clientx .lk{
  fill:none;
  stroke:#C3B6F2;
  stroke-width:1.5;
  stroke-dasharray:3 6;
  stroke-dashoffset:var(--len);
  opacity:0;
  transition:stroke-dashoffset 1.3s cubic-bezier(.16,.84,.34,1),opacity .5s;
}
.clientx .play .lk{ stroke-dashoffset:0; opacity:1 }
.clientx .nd{ opacity:0; transition:opacity .5s }
.clientx .play .nd{ opacity:1 }

/* ---------- CTA ---------- */
.clientx .cta-s{
  position:relative;
  padding:118px 0 126px;
  overflow:hidden;
  text-align:center;
  color:var(--on-dark);
  background:linear-gradient(180deg,#140E33 0%,#0A0820 58%,#08071A 100%);
}
.clientx .cta-s .glow{
  position:absolute;
  top:-150px;
  left:50%;
  width:920px;
  height:580px;
  transform:translateX(-50%);
  pointer-events:none;
  animation:cl-breathe 7s ease-in-out infinite;
  background:radial-gradient(ellipse at center,rgba(123,77,235,.34),rgba(11,10,30,0) 70%);
}
.clientx .orb{
  position:absolute;
  left:50%;
  top:58%;
  width:560px;
  height:560px;
  transform:translate(-50%,-50%);
  pointer-events:none;
  animation:cl-orbit 26s linear infinite;
}
.clientx .orb i{ position:absolute; width:5px; height:5px; border-radius:999px; background:var(--purple-lt) }
.clientx .cta-s h2{
  margin:0;
  font-size:clamp(38px,4.4vw,54px);
  line-height:1.16;
  font-weight:900;
  letter-spacing:-.025em;
  color:#fff;
}
.clientx .cta-s p{
  margin:26px auto 0;
  font-size:18px;
  line-height:1.9;
  color:var(--on-dark-2);
  max-width:28em;
}

/* ---------- 响应式 ---------- */
@media (max-width:1080px){
  .clientx .hero-grid,
  .clientx .pol-grid,
  .clientx .ls-grid,
  .clientx .ch-grid{ grid-template-columns:minmax(0,1fr); gap:46px }
  .clientx .cl-hero{ padding:150px 0 84px }
  .clientx .pol,
  .clientx .lease,
  .clientx .chain{ padding-top:88px }
  .clientx .cta-s{ padding-top:98px }
  .clientx .cap{ flex-wrap:wrap }
  .clientx .orb{ width:380px; height:380px }
}
@media (prefers-reduced-motion:reduce){
  .clientx .dot,
  .clientx .orb,
  .clientx .cta-s .glow{ animation:none }
  .clientx [data-rise="in"]{ animation:none }
  html.cl-rise .clientx [data-rise]{ opacity:1 }
  /* 初态一律直接置为终态 —— 不做动画就不能把内容留在初态里 */
  .clientx .blk{ opacity:1; transform:none }
  .clientx .wbar{ transform:none }
  .clientx .wfade,
  .clientx .nd{ opacity:1 }
  .clientx .lk{ stroke-dashoffset:0; opacity:1 }
}
