/* =============================================================================
   链桥 ChainBridge —— 动效与插图层（motion.css）
   =============================================================================
   与 app.css 的分工：
     app.css    结构与静态外观（不写动画意图相关的装饰层）
     motion.css 环境光、滚动进入、卡片光影、数字滚动、插画框、链轨等"活的"部分

   三条硬约束：
     ① 色值一律从 tokens.css 取，透明度用 color-mix() 派生，不新增十六进制字面量。
     ② 装饰层全部 aria-hidden，且 pointer-events:none，不参与点击与读屏。
     ③ 所有动画在 prefers-reduced-motion: reduce 下一律停用并回到静态终态，
        不允许"关了动效内容就消失"（滚动进入的 opacity:0 只在 .cs-motion-active 下生效）。
   ============================================================================= */

:root {
  --motion-ease: cubic-bezier(.16, 1, .3, 1);
  --motion-ease-soft: cubic-bezier(.4, 0, .2, 1);
  --motion-dur: 620ms;
  --motion-stagger: 70ms;
}

/* ===================== ① 首屏环境光（极光 + 点阵网格） ===================== */
/* 只在营销页 Hero 里出现。两层径向渐变缓慢漂移，给纯黑底一点纵深，
   但峰值透明度压在 18% 以内——再亮就会和正文抢注意力。 */
.cs-hero { isolation: isolate; }
.cs-hero > .cs-container { position: relative; z-index: 2; }

/* 覆盖 app.css 里那条 620px 高的径向渐变：它底部会留下一条硬边（实测可见）。
   这里把整层重写成"渐变在盒子内部就淡完"的写法——最后一档透明度停在 62%，
   远早于盒子边界，因此任何视口高度下都不会出现截断线。 */
.cs-hero::before {
  content: "";
  position: absolute;
  inset: -40% -8% auto -8%;
  height: 145%;
  pointer-events: none;
  z-index: 0;
  background:
    radial-gradient(58% 72% at 18% 24%, color-mix(in srgb, var(--primary) 8%, transparent), transparent 62%),
    radial-gradient(52% 66% at 82% 10%, color-mix(in srgb, var(--blueMarketing) 6%, transparent), transparent 62%),
    radial-gradient(46% 58% at 56% 74%, color-mix(in srgb, var(--primary) 4%, transparent), transparent 62%);
  filter: blur(6px);
  animation: cs-aura-drift 24s var(--motion-ease-soft) infinite alternate;
}
@keyframes cs-aura-drift {
  from { transform: translate3d(-2%, 0, 0) scale(1); }
  to   { transform: translate3d(3%, 2%, 0) scale(1.08); }
}

/* 点阵网格：drpc 的技术感来源。用 mask 让它从中心向四周淡出，
   避免在 Hero 下边缘出现一条生硬的截止线。 */
.cs-gridlines {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background-image:
    linear-gradient(color-mix(in srgb, var(--textPrimary) 3.5%, transparent) 1px, transparent 1px),
    linear-gradient(90deg, color-mix(in srgb, var(--textPrimary) 3.5%, transparent) 1px, transparent 1px);
  background-size: 72px 72px;
  -webkit-mask-image: radial-gradient(66% 62% at 32% 30%, #000 0%, transparent 76%);
  mask-image: radial-gradient(66% 62% at 32% 30%, #000 0%, transparent 76%);
  opacity: .75;
}

/* ===================== ② Hero 插画（AI 生成的网络意象图） ===================== */
/* 定位在右上、用径向 mask 淡出，并用 screen 混合让黑色底自然消失，
   这样同一张图在浅色主题下也不会出现一块方形灰。 */
.cs-hero__art {
  position: absolute;
  top: -14%;
  right: -14%;
  width: min(900px, 68vw);
  aspect-ratio: 3 / 2;
  pointer-events: none;
  z-index: 1;
  background: url("../img/art/hero-mesh.webp") center / contain no-repeat;
  opacity: .34;
  mix-blend-mode: screen;
  -webkit-mask-image: radial-gradient(closest-side, #000 34%, transparent 82%);
  mask-image: radial-gradient(closest-side, #000 34%, transparent 82%);
  animation: cs-art-float 22s var(--motion-ease-soft) infinite alternate;
}
@keyframes cs-art-float {
  from { transform: translate3d(0, -8px, 0) scale(1); }
  to   { transform: translate3d(-14px, 10px, 0) scale(1.04); }
}

/* 内页 Hero 的插画底：用 ::after（::before 已被环境光占用）。
   四个变体按产品线选图，URL 写在 CSS 里，这样不同目录深度的页面都不用改相对路径。
   图上压一层同色系 scrim，保证 30% 亮度下标题仍然清晰。 */
.cs-hero--art { --cs-art-img: url("../img/art/cta-band.webp"); }
.cs-hero--art-security { --cs-art-img: url("../img/art/security-hero.webp"); }
.cs-hero--art-connect  { --cs-art-img: url("../img/art/product-connect.webp"); }
.cs-hero--art-network  { --cs-art-img: url("../img/art/product-nodes.webp"); }
.cs-hero--art-mesh     { --cs-art-img: url("../img/art/hero-mesh.webp"); }

.cs-hero--art::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  /* 第一层是压在文字后面的暗色 scrim：不压的话「Multi-chain RPC」正好落在
     最亮的玻璃方块上，白字对比度会掉到 3:1 以下。 */
  background-image:
    radial-gradient(62% 96% at 50% 40%, color-mix(in srgb, var(--background) 74%, transparent), transparent 74%),
    var(--cs-art-img);
  background-size: 100% 100%, cover;
  background-position: center center, center 44%;
  background-repeat: no-repeat, no-repeat;
  opacity: .55;
  -webkit-mask-image: radial-gradient(78% 96% at 50% 34%, #000 0%, transparent 76%);
  mask-image: radial-gradient(78% 96% at 50% 34%, #000 0%, transparent 76%);
}
/* 插画变体挂在 .cs-hero--center 上，正文必须压在上层 */
.cs-hero--art > .cs-container { position: relative; z-index: 2; }

/* ===================== ③ 滚动进入（reveal） ===================== */
/* 只有 motion.js 确认能跑（给 <html> 加了 cs-motion-active）时才隐藏元素；
   脚本被拦、被禁、或浏览器不支持时，内容保持完全可见。 */
.cs-motion-active .cs-reveal {
  opacity: 0;
  transform: translate3d(0, 18px, 0);
  transition:
    opacity var(--motion-dur) var(--motion-ease),
    transform var(--motion-dur) var(--motion-ease);
  transition-delay: var(--reveal-delay, 0ms);
}
.cs-motion-active .cs-reveal.is-in {
  opacity: 1;
  transform: none;
}
/* 进入后不再需要 will-change：长期挂着会白占显存 */
.cs-motion-active .cs-reveal.is-in { will-change: auto; }
.cs-motion-active .cs-reveal { will-change: opacity, transform; }

/* ===================== ④ 卡片光影 ===================== */
/* 指针跟随的高光：JS 只写 --mx/--my 两个自定义属性，不碰布局，
   因此卡片尺寸/换行完全不受影响。 */
.cs-glow { position: relative; overflow: hidden; }
.cs-glow::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  transition: opacity .38s var(--motion-ease-soft);
  background: radial-gradient(
    260px circle at var(--mx, 50%) var(--my, 0%),
    color-mix(in srgb, var(--primary) 15%, transparent),
    transparent 68%);
}
.cs-glow:hover::after,
.cs-glow:focus-visible::after { opacity: 1; }

/* 卡片悬停：上浮 + 品牌绿描边发光，与 drpc 的产品卡一致 */
.cs-card--link { transition: transform .3s var(--motion-ease), border-color .3s var(--motion-ease-soft), box-shadow .3s var(--motion-ease-soft); }
.cs-card--link:hover {
  transform: translateY(-4px);
  border-color: color-mix(in srgb, var(--primary) 42%, transparent);
  box-shadow: var(--shadow-card-hover);
}

/* ===================== ⑤ 卡片媒体图（AI 产品插画） ===================== */
/* 负边距吃掉 .cs-card 的 24px padding，让图贴到圆角边界。
   16:10 裁切保证三张卡在同一行时视觉高度一致。 */
.cs-card__media {
  display: block;
  position: relative;
  margin: -24px -24px 20px;
  aspect-ratio: 16 / 10;
  border-radius: calc(var(--Radius-500) - 1px) calc(var(--Radius-500) - 1px) 0 0;
  overflow: hidden;
  background: var(--backgroundTertiary);
}
.cs-card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transform: scale(1.01);
  /* 生成图的绿色比品牌绿更饱和，直接铺进卡片像游戏皮肤；
     降饱和 + 压亮度后与 #41e278 的克制感对齐 */
  filter: saturate(.82) brightness(.86) contrast(1.04);
  transition: transform .7s var(--motion-ease), filter .7s var(--motion-ease);
}
.cs-card--link:hover .cs-card__media img { transform: scale(1.06); }
/* 图底压一层从卡片底色到透明的渐变，避免图的暗部与卡片背景出现色阶断层 */
.cs-card__media::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(180deg, transparent 52%, var(--backgroundSecondary) 100%);
}
.cs-card--dark .cs-card__media::after { background: linear-gradient(180deg, transparent 52%, var(--backgroundLandingDark) 100%); }

/* ===================== ⑥ 数字滚动与徽标微动 ===================== */
/* 关键数字是页面主角（docs/02 §好看验收清单）。滚动到视口时从 0 数上去，
   位数用 tabular-nums 固定，避免每帧宽度跳动。 */
.cs-countup { font-variant-numeric: tabular-nums; }

/* 在线小圆点呼吸：只用于「实时/在线」语义，纯装饰不承载信息 */
.cs-pill__dot,
.cs-promise__dot {
  animation: cs-dot-breathe 2.6s var(--motion-ease-soft) infinite;
}
@keyframes cs-dot-breathe {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--primary) 55%, transparent); }
  50%      { box-shadow: 0 0 0 5px color-mix(in srgb, var(--primary) 0%, transparent); }
}

/* 流向图的动效见 ①-b（连线光点），这里只留中心节点的呼吸 */
.cs-flow__node { animation: cs-node-glow 3.2s var(--motion-ease-soft) infinite; }
@keyframes cs-node-glow {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--primary) 0%, transparent); }
  50%      { box-shadow: 0 0 22px 2px color-mix(in srgb, var(--primary) 22%, transparent); }
}

/* ===================== ⑦ 区块光带 ===================== */
/* --alt 区块上下各一条从中间渐隐的细光带，替代硬边分隔，
   让长页面滚动时有节奏而不是一刀切。 */
.cs-section--alt { position: relative; }
.cs-section--alt::before,
.cs-section--alt::after {
  content: "";
  position: absolute;
  left: 0; right: 0;
  height: 1px;
  pointer-events: none;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--primary) 34%, transparent), transparent);
  opacity: .5;
}
.cs-section--alt::before { top: 0; }
.cs-section--alt::after { bottom: 0; }

/* 区块标题下的品牌短横线：给出视觉锚点，尺寸固定不随文案长度变化 */
.cs-section-head .cs-eyebrow { position: relative; }
.cs-section-head .cs-eyebrow::after {
  content: "";
  display: block;
  width: 28px;
  height: 2px;
  margin-top: 8px;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--primary), transparent);
}
.cs-section-head--center .cs-eyebrow::after { margin-left: auto; margin-right: auto; }

/* ===================== ⑧ 能力标签轮播：两侧渐隐 ===================== */
/* 原来第一条文字会从边缘"切"进来，像被裁掉的 bug。加 mask 后是自然的淡入淡出。 */
.cs-logos { -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); }

/* ===================== ⑨ 收尾 CTA 光带 ===================== */
.cs-cta-band {
  position: relative;
  overflow: hidden;
  isolation: isolate;
}
.cs-cta-band::before {
  content: "";
  position: absolute;
  inset: -40% -10% auto;
  height: 150%;
  pointer-events: none;
  z-index: -1;
  background: url("../img/art/cta-band.webp") center 40% / cover no-repeat;
  opacity: .3;
  mix-blend-mode: screen;
}


/* ===================== ①-b drpc 风格请求流向图 ===================== */
/* drpc 首屏的视觉焦点不是照片，而是一张"盒子 + 细绿线 + 中心发光球"的图。
   这里把原来的三列文字卡片改造成同一套语言：
     · 端点盒：极淡的绿底 + 22% 绿描边，代替原来的中性灰边
     · 连接线：一条 12% 绿的细线，上面跑一颗绿色光点，表示请求在流动
     · 中心节点：背后一圈径向光晕，作为整张图的焦点 */
.cs-flow {
  position: relative;
  overflow: hidden;
  border-color: color-mix(in srgb, var(--primary) 14%, transparent);
  /* 箭头列从 20px 放宽到 26px：连线要有一段长度，光点跑起来才看得见，
     又能让左右三列的单行文案不被挤断行（40px 时「Backend service」会折成两行） */
  grid-template-columns: minmax(0, 1fr) 26px minmax(0, 1.1fr) 26px minmax(0, 1fr);
}
.cs-flow::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 320px;
  height: 320px;
  transform: translate(-50%, -50%);
  pointer-events: none;
  background: radial-gradient(closest-side, color-mix(in srgb, var(--primary) 14%, transparent), transparent 70%);
}
.cs-flow > * { position: relative; }

.cs-flow__tag {
  border-color: color-mix(in srgb, var(--primary) 22%, transparent);
  background: color-mix(in srgb, var(--primary) 4%, transparent);
  transition: border-color .25s var(--motion-ease-soft), background .25s var(--motion-ease-soft);
}
.cs-flow__tag:hover {
  border-color: color-mix(in srgb, var(--primary) 46%, transparent);
  background: color-mix(in srgb, var(--primary) 8%, transparent);
}

/* 箭头原字符（→）用 font-size:0 收掉，改为自绘的连线 + 流动光点 */
.cs-flow__arrow {
  font-size: 0;
  position: relative;
  height: 14px;
}
.cs-flow__arrow::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 1px;
  transform: translateY(-50%);
  background: color-mix(in srgb, var(--primary) 26%, transparent);
}
.cs-flow__arrow::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 0;
  width: 16px;
  height: 2px;
  border-radius: 2px;
  transform: translateY(-50%);
  background: linear-gradient(90deg, transparent, var(--primary));
  animation: cs-flow-run 2.4s linear infinite;
}
.cs-flow__arrow:nth-of-type(2)::after { animation-delay: 1.2s; }
@keyframes cs-flow-run {
  0%   { left: -18px; opacity: 0; }
  15%  { opacity: 1; }
  85%  { opacity: 1; }
  100% { left: 100%; opacity: 0; }
}

.cs-flow__node {
  position: relative;
  border-color: color-mix(in srgb, var(--primary) 40%, transparent);
  background: color-mix(in srgb, var(--primary) 10%, transparent);
}
.cs-flow__node::before {
  content: "";
  position: absolute;
  inset: -22px;
  border-radius: 50%;
  pointer-events: none;
  background: radial-gradient(closest-side, color-mix(in srgb, var(--primary) 20%, transparent), transparent 72%);
  z-index: -1;
}

/* ===================== ⑩ 无障碍：尊重 reduced-motion ===================== */
@media (prefers-reduced-motion: reduce) {
  .cs-hero::before,
  .cs-hero__art,
  .cs-flow__arrow,
  .cs-flow__node,
  .cs-pill__dot,
  .cs-promise__dot { animation: none; }
  .cs-motion-active .cs-reveal {
    opacity: 1;
    transform: none;
    transition: none;
    will-change: auto;
  }
  .cs-card--link:hover { transform: none; }
  .cs-card__media img { transition: none; }
}

/* 打印时一律回到终态：滚动进入的 opacity:0 会让未滚动到的区块印成空白 */
@media print {
  .cs-reveal,
  .cs-motion-active .cs-reveal { opacity: 1 !important; transform: none !important; }
  .cs-hero__art,
  .cs-hero--art::after,
  .cs-gridlines { display: none !important; }
}

/* ===================== ⑪ 窄屏收敛 ===================== */
@media (max-width: 900px) {
  .cs-hero__art { width: 120vw; right: -46%; top: -2%; opacity: .32; }
  .cs-gridlines { background-size: 56px 56px; opacity: .5; }
}
@media (max-width: 560px) {
  /* 390px 下产品图会把首屏顶掉，直接不显示媒体图，文字优先 */
  .cs-card__media { aspect-ratio: 16 / 9; margin: -18px -18px 16px; }
}
