/* ============================================================
   CDNGOD — sections.css
   ============================================================ */

/* =========================================================
   HERO
   ========================================================= */
.hero{
  position:relative;
  min-height:100vh;
  min-height:100svh;
  display:flex; align-items:center;
  padding-top:clamp(104px, 13vh, 150px);
  /* 为底部滚动提示完整预留空间：提示约 83px 高，再加 bottom 偏移与安全间距。
     内容较高时让 hero 自然超过一屏，避免绝对定位的提示压住 KPI。 */
  padding-bottom:clamp(140px, 17vh, 152px);
  overflow:hidden;
  background:
    radial-gradient(120% 90% at 78% 42%, #ffffff 0%, rgba(255,255,255,0) 58%),
    linear-gradient(180deg, #f7f8fb 0%, var(--paper) 46%, #f6f7fa 100%);
}
.hero__stage{
  position:absolute; z-index:0;
  right:-8%; top:50%; transform:translateY(-50%);
  width:min(860px, 58vw); aspect-ratio:1/1;
}
.hero__stage canvas{ width:100%; height:100%; }
.hero__halo{
  position:absolute; inset:8%;
  background:radial-gradient(circle at 50% 50%, rgba(61,142,245,.13), rgba(61,142,245,.04) 46%, transparent 66%);
  filter:blur(28px);
  pointer-events:none;
}
.hero__inner{ position:relative; z-index:2; }
/* 让空白处的指针事件透传给地球（可拖拽旋转），交互元素单独恢复 */
.hero__inner{ pointer-events:none; }
.hero__inner a,
.hero__inner h1,
.hero__inner p,
.hero__inner button,
.hero__inner .kpis{ pointer-events:auto; }

.hero__title{
  font-size:clamp(36px, 4.6vw, 66px);
  line-height:1.16;
  letter-spacing:-.005em;
  /* 中文下 1ch 约等于半个字宽，用绝对值更可控，保证每行 10 字不折行。
     66px × 10 字 = 660px，留一点余量防不同中文字体的字距差异 */
  max-width:min(680px, 54vw);
}
.ink-shine{
  background:linear-gradient(96deg, #1a1a1c 12%, #4b5566 38%, #0b64d8 58%, #1a1a1c 84%);
  background-size:220% 100%;
  -webkit-background-clip:text; background-clip:text;
  -webkit-text-fill-color:transparent; color:transparent;
  animation:shine 9s var(--ease-2) infinite;
}
@keyframes shine{
  0%,100%{ background-position:120% 0 }
  50%{ background-position:-20% 0 }
}
@media (prefers-reduced-motion: reduce){ .ink-shine{ animation:none } }

.hero__sub{
  margin-top:26px; max-width:min(500px, 48vw);
  font-size:clamp(16px, 1.35vw, 18.5px);
  line-height:1.66; color:var(--muted);
  text-wrap:pretty;
}
.hero__cta{ margin-top:34px; display:flex; flex-wrap:wrap; gap:12px; }

/* ---------- 访客归属地胶囊 ---------- */
.geochip{
  margin-top:22px;
  display:inline-flex; align-items:center; gap:10px; flex-wrap:wrap;
  max-width:min(640px, 66vw);
  padding:9px 16px 9px 13px;
  border:1px solid var(--line-2); border-radius:16px;
  background:rgba(255,255,255,.72);
  -webkit-backdrop-filter:saturate(160%) blur(10px);
  backdrop-filter:saturate(160%) blur(10px);
  box-shadow:var(--shadow-s);
  font-size:13px; line-height:1.5; color:var(--muted);
  text-align:left; cursor:pointer;
  opacity:0; transform:translateY(8px);
  transition:opacity .7s var(--ease), transform .7s var(--ease),
             border-color .3s var(--ease), box-shadow .3s var(--ease);
}
.geochip.is-in{ opacity:1; transform:none; }
.geochip:hover,
.geochip:focus-visible{ border-color:rgba(11,100,216,.34); box-shadow:var(--shadow-m); }
.geochip__pin{
  flex:none; width:17px; height:17px; color:var(--accent);
  animation:geoPin 2.8s var(--ease-2) infinite;
}
.geochip__pin svg{ width:100%; height:100%; display:block; }
@keyframes geoPin{
  0%,72%,100%{ transform:translateY(0) }
  84%{ transform:translateY(-3px) }
}
.geochip__txt{ flex:1 1 auto; min-width:0; }
.geochip__txt b{ color:var(--ink); font-weight:600; }
.geochip__txt .geochip__ms{ color:var(--ok); }
.geochip__act{
  flex:none; padding-left:12px;
  border-left:1px solid var(--line);
  font-size:12px; color:var(--accent); white-space:nowrap;
}
@media (prefers-reduced-motion: reduce){
  .geochip{ opacity:1; transform:none; transition:none; }
  .geochip__pin{ animation:none; }
}
@media (max-width:980px){
  /* 窄屏用块级 flex + fit-content：文案再长也只在容器内换行，不会顶出屏幕 */
  .geochip{ display:flex; width:fit-content; max-width:100%; }
  .geochip__act{ display:none; }
}

.kpis{
  margin-top:clamp(48px, 7vh, 84px);
  display:grid; grid-template-columns:repeat(4, minmax(0,1fr));
  gap:clamp(12px, 1.8vw, 26px);
  max-width:min(700px, 56vw);
}
.kpis li{
  padding-left:16px;
  border-left:1px solid var(--line-2);
}
.kpis .num{
  display:block;
  font-size:clamp(21px, 2.1vw, 29px);
  font-weight:500; letter-spacing:-.02em; line-height:1.1;
  /* 数值带单位后缀，绝不允许折行——否则整排标签基线错位 */
  white-space:nowrap; word-spacing:-.06em;
  color:var(--ink);
}
.kpis span{
  display:block; margin-top:7px;
  font-size:12.5px; color:var(--muted-2); letter-spacing:.01em;
}

.hero__foot{
  position:absolute; z-index:2; left:50%; transform:translateX(-50%);
  bottom:clamp(22px, 4vh, 40px);
  display:flex; flex-direction:column; align-items:center; gap:12px;
}
.hero__hint{ font-size:12px; color:var(--muted-2); letter-spacing:.05em; }
.hero__rail{
  position:relative; width:1px; height:52px;
  background:var(--line-2); overflow:hidden;
}
.hero__rail i{
  position:absolute; left:0; top:-40%; width:1px; height:40%;
  background:linear-gradient(180deg, transparent, var(--accent));
  animation:railRun 2.4s var(--ease-2) infinite;
}
@keyframes railRun{ to{ top:110% } }

@media (max-width:980px){
  .hero{ min-height:auto; padding-top:120px; padding-bottom:80px; }
  .hero__stage{ right:-34%; top:36%; width:132vw; opacity:.46; }
  /* 标题是硬换行的两行，第一行整 10 个汉字必须容得下，否则会被挤成
     「让世界的每一次访 / 问，」这种断字。所以窄屏改用随视口线性缩放的字号。 */
  .hero__title{ max-width:none; font-size:clamp(26px, 8.6vw, 60px); }
  .hero__sub{ max-width:52ch; }
  .kpis{ grid-template-columns:1fr 1fr; gap:22px 18px; max-width:none; }
  .hero__foot{ display:none; }
}

/* =========================================================
   信任滚动条
   ========================================================= */
.marquee-sec{
  padding-block:clamp(44px,6vw,72px);
  border-top:1px solid var(--line);
  background:var(--paper);
  overflow:hidden;
}
.marquee-sec__label{
  text-align:center; color:var(--muted-2);
  font-size:13px; letter-spacing:.06em; margin-bottom:34px;
}
.marquee{
  position:relative;
  mask-image:linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
  -webkit-mask-image:linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}
.marquee__track{
  display:flex; gap:clamp(38px,5vw,72px); width:max-content;
  animation:slide 46s linear infinite;
}
.marquee:hover .marquee__track{ animation-play-state:paused; }
.marquee__track span{
  font-size:clamp(16px,1.7vw,21px); font-weight:600; letter-spacing:-.01em;
  color:#a9a9b1; white-space:nowrap;
  transition:color .4s var(--ease);
}
.marquee__track span:hover{ color:var(--ink-2); }
@keyframes slide{ to{ transform:translateX(-50%) } }
@media (prefers-reduced-motion: reduce){ .marquee__track{ animation:none } }

/* =========================================================
   演示 01 · 全球网络
   ========================================================= */
.netdemo{
  display:grid; gap:clamp(16px,2vw,24px);
  grid-template-columns:minmax(0,1fr) 328px;
  align-items:stretch;
}
.netdemo__stage{
  position:relative;
  border-radius:var(--r-l);
  border:1px solid var(--line-d);
  background:
    radial-gradient(90% 70% at 50% 0%, rgba(61,142,245,.07), transparent 62%),
    linear-gradient(180deg, #0c0e12, #090a0d);
  overflow:hidden;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.06), 0 30px 70px rgba(0,0,0,.35);
  min-height:420px;
}
.netdemo__stage canvas{
  width:100%; height:100%;
  position:absolute; inset:0;
  cursor:crosshair;
}
.netdemo__topbar{
  position:absolute; z-index:2; inset:0 0 auto 0;
  display:flex; align-items:center; justify-content:space-between;
  gap:14px; flex-wrap:wrap;
  padding:16px 18px;
  pointer-events:none;
}
.mode-tag{
  display:inline-flex; align-items:center; gap:9px;
  padding:7px 13px 7px 11px; border-radius:100px;
  background:rgba(255,255,255,.06);
  border:1px solid var(--line-d);
  -webkit-backdrop-filter:blur(10px); backdrop-filter:blur(10px);
  font-size:12.5px; letter-spacing:.02em; color:var(--on-dark);
  transition:background .5s var(--ease), border-color .5s var(--ease);
}
.mode-tag i{
  width:7px; height:7px; border-radius:50%; background:var(--warn-2);
  box-shadow:0 0 10px rgba(219,163,60,.8);
  transition:background .5s var(--ease), box-shadow .5s var(--ease);
}
.mode-tag[data-on="true"]{ background:rgba(31,138,85,.14); border-color:rgba(53,176,113,.4); }
.mode-tag[data-on="true"] i{ background:var(--ok-2); box-shadow:0 0 10px rgba(53,176,113,.85); }

.netdemo__legend{ display:flex; gap:16px; flex-wrap:wrap; }
.lg{
  display:inline-flex; align-items:center; gap:7px;
  font-size:11.5px; color:var(--on-dark-2); letter-spacing:.02em;
}
.lg::before{
  content:""; width:8px; height:8px; border-radius:50%;
}
.lg--user::before{ background:#3d8ef5; }
.lg--edge::before{ background:#f2f3f5; box-shadow:0 0 8px rgba(255,255,255,.5); }
.lg--origin::before{ background:var(--warn-2); border-radius:2px; }
.lg--miss::before{ background:transparent; box-shadow:inset 0 0 0 1.5px var(--bad-2); }
.lg--you::before{ background:var(--ok-2); box-shadow:0 0 8px rgba(53,176,113,.7); }
.lg--you{ color:rgba(146,214,180,.95); }

.netdemo__tip{
  position:absolute; z-index:2; left:18px; bottom:15px;
  font-size:11.5px; color:rgba(158,163,172,.75); letter-spacing:.02em;
  pointer-events:none;
}

/* —— 侧栏面板 —— */
.netdemo__panel, .shield__panel{
  border-radius:var(--r-l);
  border:1px solid var(--line-d);
  background:linear-gradient(180deg, rgba(255,255,255,.05), rgba(255,255,255,.018));
  -webkit-backdrop-filter:blur(14px); backdrop-filter:blur(14px);
  padding:22px;
  display:flex; flex-direction:column; gap:22px;
}
.switch-row{
  display:flex; align-items:center; justify-content:space-between; gap:16px;
  padding-bottom:20px; border-bottom:1px solid var(--line-d);
}
.switch-row__t{ font-size:16px; font-weight:600; letter-spacing:-.01em; }
.switch-row__s{
  font-size:11px; color:var(--on-dark-2); margin-top:3px;
  font-family:var(--mono); letter-spacing:.06em; text-transform:uppercase;
}
.switch{
  position:relative; flex:none;
  width:52px; height:31px; border-radius:100px; border:0; cursor:pointer;
  background:rgba(255,255,255,.16);
  transition:background .45s var(--ease);
}
.switch__dot{
  position:absolute; top:3px; left:3px; width:25px; height:25px; border-radius:50%;
  background:#fff; box-shadow:0 2px 6px rgba(0,0,0,.3);
  transition:transform .45s var(--ease), background .45s var(--ease);
}
.switch--on{ background:var(--accent); }
.switch--on .switch__dot{ transform:translateX(21px); }

/* —— 指标 —— */
.metrics{ display:flex; flex-direction:column; gap:17px; }
.metric__head{
  display:flex; align-items:baseline; justify-content:space-between; gap:10px;
  font-size:13px; color:var(--on-dark-2); margin-bottom:8px;
}
.metric__head b{ font-weight:500; color:var(--on-dark); display:inline-flex; align-items:baseline; gap:3px; }
.metric__head .v{
  font-family:var(--mono); font-variant-numeric:tabular-nums;
  font-size:19px; letter-spacing:-.02em;
}
.metric__head em{ font-style:normal; font-size:11px; color:var(--on-dark-2); }
.bar{
  height:4px; border-radius:100px; overflow:hidden;
  background:rgba(255,255,255,.09);
}
.bar > i{
  display:block; height:100%; border-radius:100px;
  background:linear-gradient(90deg, var(--accent), var(--accent-2));
  transition:width .55s var(--ease);
}
.bar--ok  > i{ background:linear-gradient(90deg, var(--ok), var(--ok-2)); }
.bar--warn> i{ background:linear-gradient(90deg, var(--warn), var(--warn-2)); }
.bar--bad > i{ background:linear-gradient(90deg, var(--bad), var(--bad-2)); }

/* —— 日志 —— */
.netlog{ margin-top:auto; }
.netlog__t{
  font-size:10.5px; letter-spacing:.14em; text-transform:uppercase;
  color:var(--on-dark-2); margin-bottom:11px;
  font-family:var(--mono);
}
.netlog ul{ display:flex; flex-direction:column; gap:7px; min-height:96px; }
.netlog li{
  font-family:var(--mono); font-size:11.5px; line-height:1.5;
  color:rgba(158,163,172,.9);
  display:flex; gap:8px;
  animation:logIn .5s var(--ease) both;
}
.netlog li time{ color:rgba(158,163,172,.5); flex:none; }
.netlog li.is-warn{ color:var(--warn-2); }
.netlog li.is-bad{ color:var(--bad-2); }
.netlog li.is-ok{ color:var(--ok-2); }
@keyframes logIn{ from{ opacity:0; transform:translateY(-5px) } }

@media (max-width:920px){
  /* 只管 .netdemo：.shield 的基础规则写在本行之后，媒体查询不加权重，
     在这里覆盖会被后面的 .shield{grid-template-columns} 反压回去
     （曾导致窄屏防护演示被压成 6px 的一条竖缝）。它的覆盖放在自己那节里。 */
  .netdemo{ grid-template-columns:1fr; }
  /* min-height 给出的确定高度会被 aspect-ratio 反向换算回宽度
     （340 × 16/11 = 495px），舞台于是撑出自己的网格轨道、被 body 的
     overflow-x:clip 裁掉右半边（图例就是这样断在屏幕外的）。
     max-width 把这条换算重新钉回容器宽度：窄到放不下 16:11 时，
     以 min-height 为准变成近方形，而不是溢出。 */
  .netdemo__stage{ min-height:340px; aspect-ratio:16/11; max-width:100%; }
}

/* =========================================================
   演示 02 · 缓存管道
   ========================================================= */
.cache__grid{
  display:grid; gap:clamp(24px,4vw,64px);
  grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr);
  align-items:start;
}
/* 网格用了 align-items:start，包裹层会被收缩成内容高度；
   它是 .cache__sticky 的包含块，高度一旦等于内容高度，sticky 就没有任何可移动区间
   ——表现为「完全没生效」。让包裹层撑满整行，吸附才有行程。 */
.cache__visual{ align-self:stretch; }
.cache__sticky{
  position:sticky; top:104px;
  display:flex; flex-direction:column; gap:16px;
}
.pipe{
  position:relative;
  border-radius:var(--r-l);
  border:1px solid var(--line);
  background:linear-gradient(180deg, #fff, #f8f9fc);
  box-shadow:var(--shadow-m);
  padding:12px 12px 0;
  overflow:hidden;
}
.pipe svg{ width:100%; height:auto; overflow:visible; }

.rail{ fill:none; stroke:var(--line-2); stroke-width:1.5; }
.rail--dash{ stroke-dasharray:5 5; }
.rail.is-live{ stroke:var(--accent); stroke-opacity:.55; }
.rail.is-live-warn{ stroke:var(--warn); stroke-opacity:.6; }
.rail{ transition:stroke .4s var(--ease), stroke-opacity .4s var(--ease); }

.pnode rect{
  fill:#fff; stroke:var(--line-2); stroke-width:1;
  filter:drop-shadow(0 6px 16px rgba(16,18,24,.07));
  transition:stroke .45s var(--ease), fill .45s var(--ease);
}
.pnode.is-hot rect{ stroke:var(--accent); }
.pnode.is-stress rect{ stroke:var(--warn); fill:#fffdf7; }
.pnode__t{
  font-family:var(--sans); font-size:14px; font-weight:600; fill:var(--ink);
  text-anchor:middle; letter-spacing:-.01em;
}
.pnode__s{
  font-family:var(--mono); font-size:9.5px; fill:var(--muted-2);
  text-anchor:middle; letter-spacing:.08em;
}
.pnode__badge{
  font-family:var(--mono); font-size:11px; font-weight:600;
  text-anchor:middle; letter-spacing:.08em; fill:var(--muted-2);
  opacity:0; transition:opacity .35s var(--ease), fill .35s var(--ease);
}
.pnode__badge.is-show{ opacity:1; }
.rail__lab{
  font-family:var(--mono); font-size:10px; fill:var(--muted-2);
  text-anchor:middle; letter-spacing:.04em;
  opacity:0; transition:opacity .4s var(--ease);
}
.rail__lab.is-show{ opacity:1; }

.slot{ fill:rgba(0,0,0,.05); transition:fill .5s var(--ease); }
.slot.is-full{ fill:var(--accent); }
.slot.is-warm{ fill:var(--accent-3); }

.pipe__hud{
  display:flex; gap:26px; padding:14px 14px 16px;
  border-top:1px solid var(--line); margin-top:4px;
}
.hud-item{ display:flex; flex-direction:column; gap:3px; }
.hud-item span{ font-size:10.5px; letter-spacing:.1em; text-transform:uppercase; color:var(--muted-2); font-family:var(--mono); }
.hud-item b{ font-size:15px; font-weight:500; letter-spacing:-.01em; }
.hud-item b i{ font-family:var(--mono); font-style:normal; font-variant-numeric:tabular-nums; }

/* —— 命中率控制 —— */
.hitctl{
  border-radius:var(--r-m);
  border:1px solid var(--line);
  background:#fff;
  padding:18px 20px 20px;
  box-shadow:var(--shadow-s);
}
.hitctl__head{
  display:flex; align-items:baseline; justify-content:space-between; gap:12px;
  font-size:13.5px; color:var(--muted); margin-bottom:14px;
}
.hitctl__head b{
  font-family:var(--mono); font-size:17px; color:var(--accent);
  font-variant-numeric:tabular-nums; margin-left:6px; letter-spacing:-.02em;
}
.hitctl__head span{ font-size:11.5px; color:var(--muted-2); }
.hitctl__out{
  display:grid; grid-template-columns:repeat(4,1fr); gap:14px;
  margin-top:20px; padding-top:18px; border-top:1px solid var(--line);
}
.hitctl__out div{ display:flex; flex-direction:column; gap:5px; }
.hitctl__out b{
  font-family:var(--mono); font-size:clamp(15px,1.6vw,19px); font-weight:500;
  letter-spacing:-.02em; font-variant-numeric:tabular-nums;
}
.hitctl__out span{ font-size:11px; color:var(--muted-2); }

/* —— 滑块 —— */
input[type=range]{
  -webkit-appearance:none; appearance:none;
  width:100%; height:22px; background:transparent; cursor:pointer;
}
input[type=range]::-webkit-slider-runnable-track{
  height:4px; border-radius:100px;
  background:linear-gradient(90deg, var(--accent) 0 var(--p,50%), rgba(0,0,0,.1) var(--p,50%) 100%);
}
input[type=range]::-moz-range-track{ height:4px; border-radius:100px; background:rgba(0,0,0,.1); }
input[type=range]::-moz-range-progress{ height:4px; border-radius:100px; background:var(--accent); }
input[type=range]::-webkit-slider-thumb{
  -webkit-appearance:none; appearance:none;
  width:20px; height:20px; border-radius:50%; margin-top:-8px;
  background:#fff; border:1px solid var(--line-2);
  box-shadow:0 1px 3px rgba(0,0,0,.18), 0 4px 12px rgba(0,0,0,.1);
  transition:transform .25s var(--ease);
}
input[type=range]::-moz-range-thumb{
  width:20px; height:20px; border-radius:50%; border:1px solid var(--line-2);
  background:#fff; box-shadow:0 1px 3px rgba(0,0,0,.18);
}
input[type=range]:active::-webkit-slider-thumb{ transform:scale(1.15); }

/* —— 步骤列表 —— */
.cache__steps{
  /* 步间距 = 每一步占据的滚动行程，直接决定叙事推进速度；
     太小则一屏内连跳数步，读者根本来不及看管道图的变化 */
  --cgap:clamp(72px,30vh,300px);
  display:flex; flex-direction:column;
  gap:var(--cgap);
  /* 底部余量必须够大：吸附块自身高 ~540px，加上 top:104px 已占掉半屏，
     余量不足时管道图会在第 05 步还亮着的时候就先滑走 */
  padding-block:clamp(20px,10vh,90px) clamp(80px,34vh,320px);
}
.cstep{
  position:relative; padding-left:60px;
  opacity:.34; filter:blur(.4px);
  transition:opacity .7s var(--ease), filter .7s var(--ease), transform .7s var(--ease);
}
.cstep.is-on{ opacity:1; filter:none; }
.cstep__i{
  position:absolute; left:0; top:2px;
  font-family:var(--mono); font-size:12px; letter-spacing:.06em;
  color:var(--muted-2);
  transition:color .5s var(--ease);
}
.cstep.is-on .cstep__i{ color:var(--accent); }
.cstep__i::after{
  /* 连接线要跨过整个步间距，否则加长行程后会变成一截悬空的短线 */
  content:""; position:absolute; left:1px; top:22px; width:1px;
  bottom:calc(6px - var(--cgap, 30px));
  background:var(--line-2);
}
.cstep:last-child .cstep__i::after{ display:none; }
.cstep h3{ font-size:clamp(19px,2.1vw,25px); letter-spacing:-.022em; }
.cstep p{
  margin-top:11px; color:var(--muted); font-size:15.5px; line-height:1.62;
  max-width:44ch;
}
.cstep p b{ color:var(--ink); font-weight:600; }

@media (max-width:960px){
  .cache__grid{ grid-template-columns:1fr; }
  .cache__sticky{ position:sticky; top:70px; z-index:3;
    background:var(--paper); padding-bottom:10px; }
  .cache__steps{ --cgap:clamp(30px,7vh,70px); padding-block:30px 0; }
  .hitctl__out{ grid-template-columns:repeat(2,1fr); }
}

/* =========================================================
   演示 03 · 安全防护
   ========================================================= */
.shield{
  display:grid; gap:clamp(16px,2vw,24px);
  grid-template-columns:minmax(0,1fr) 328px;
}
.shield__stage{
  position:relative; min-height:420px;
  border-radius:var(--r-l); overflow:hidden;
  border:1px solid var(--line-d);
  background:
    radial-gradient(70% 100% at 0% 50%, rgba(176,63,47,.10), transparent 60%),
    linear-gradient(180deg, #0c0e12, #090a0d);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.06), 0 30px 70px rgba(0,0,0,.35);
}
.shield__stage canvas{ position:absolute; inset:0; width:100%; height:100%; }
.shield__tags{
  position:absolute; z-index:2; left:18px; bottom:15px;
  display:flex; gap:14px; flex-wrap:wrap; pointer-events:none;
}
.stag{
  font-size:11.5px; letter-spacing:.02em; color:var(--on-dark-2);
  display:inline-flex; align-items:center; gap:7px;
}
.stag::before{ content:""; width:8px; height:8px; border-radius:50%; }
.stag--bad::before{ background:var(--bad-2); box-shadow:0 0 8px rgba(212,97,77,.8); }
.stag--good::before{ background:var(--accent-2); box-shadow:0 0 8px rgba(61,142,245,.8); }
.stag--wall::before{ background:var(--ok-2); border-radius:2px; }

.slider-row label{
  display:flex; align-items:baseline; justify-content:space-between; gap:12px;
  font-size:13px; color:var(--on-dark-2); margin-bottom:10px;
}
.slider-row label b{
  font-family:var(--mono); font-size:16px; color:var(--on-dark); font-weight:500;
  font-variant-numeric:tabular-nums; letter-spacing:-.02em;
}
.shield__panel input[type=range]::-webkit-slider-runnable-track{
  background:linear-gradient(90deg, var(--bad-2) 0 var(--p,50%), rgba(255,255,255,.14) var(--p,50%) 100%);
}
.shield__panel input[type=range]::-moz-range-track{ background:rgba(255,255,255,.14); }
.shield__panel input[type=range]::-moz-range-progress{ background:var(--bad-2); }
.shield__panel input[type=range]::-webkit-slider-thumb{ border-color:rgba(255,255,255,.3); }

.shield__note{
  margin-top:auto; padding-top:18px; border-top:1px solid var(--line-d);
  font-size:12.5px; line-height:1.6; color:var(--on-dark-2);
  transition:color .4s var(--ease);
}
.shield__note.is-bad{ color:var(--bad-2); }

@media (max-width:920px){
  .shield{ grid-template-columns:1fr; }
  /* 同 .netdemo__stage：没有 max-width 时 320 × 16/11 = 465px，会溢出轨道 */
  .shield__stage{ min-height:320px; aspect-ratio:16/11; max-width:100%; }
}

/* =========================================================
   演示 04 · 瀑布图与延迟表
   ========================================================= */
.wf{
  border-radius:var(--r-l);
  border:1px solid var(--line);
  background:#fff;
  box-shadow:var(--shadow-m);
  overflow:hidden;
}
.wf__tabs{
  position:relative;
  display:flex; gap:4px; padding:14px 16px;
  border-bottom:1px solid var(--line);
  background:linear-gradient(180deg,#fcfcfe,#f7f8fa);
}
.wf__tab{
  position:relative; z-index:1;
  border:0; background:none; cursor:pointer;
  padding:9px 18px; border-radius:100px;
  font-size:14px; color:var(--muted);
  transition:color .35s var(--ease);
}
.wf__tab.is-active{ color:#fff; }
.wf__pill{
  position:absolute; z-index:0; top:14px; left:16px;
  height:36px; border-radius:100px; background:var(--ink);
  transition:transform .55s var(--ease), width .55s var(--ease);
}
/* 列宽集中定义：时间轴必须和柱条轨道用同一套值，否则刻度会整体错位 */
.wf__body{
  --wf-name: 158px;
  --wf-gap: clamp(10px,1.6vw,20px);
  --wf-ms: 52px;
  padding:clamp(18px,2.4vw,30px) clamp(16px,2.4vw,30px) 8px;
}

.wfrow{
  display:grid; grid-template-columns:minmax(96px, var(--wf-name)) 1fr var(--wf-ms);
  align-items:center; gap:var(--wf-gap);
  padding:7px 0;
}
.wfrow__n{
  font-family:var(--mono); font-size:12px; color:var(--ink-2);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.wfrow__track{
  position:relative; height:14px; border-radius:4px;
  background:rgba(0,0,0,.035);
}
.wfrow__bar{
  position:absolute; top:0; height:100%; border-radius:4px;
  display:flex; overflow:hidden;
  transition:left .85s var(--ease), width .85s var(--ease);
  box-shadow:0 1px 2px rgba(0,0,0,.06);
}
.wfrow__seg{ height:100%; transition:background .5s var(--ease); }
.seg--wait{ background:#d9dbe0; }
.seg--dns{ background:#b9c0cc; }
.seg--conn{ background:var(--accent-3); }
.seg--ttfb{ background:var(--accent-2); }
.seg--load{ background:var(--accent); }
.wfrow__ms{
  font-family:var(--mono); font-size:11.5px; color:var(--muted);
  font-variant-numeric:tabular-nums; min-width:52px; text-align:right;
}
.wfrow.is-origin .wfrow__n::after{
  content:"回源"; margin-left:8px; font-size:9px; letter-spacing:.06em;
  color:var(--warn); border:1px solid rgba(184,128,30,.4);
  padding:1px 4px; border-radius:4px; vertical-align:1px;
}
.wfrow.is-hit .wfrow__n::after{
  content:"HIT"; margin-left:8px; font-size:9px; letter-spacing:.06em;
  color:var(--ok); border:1px solid rgba(31,138,85,.35);
  padding:1px 4px; border-radius:4px; vertical-align:1px;
}

.wf__axis{
  position:relative; height:30px;
  /* 左右缩进 = 名称列 / 耗时列，与 .wfrow 的网格严格对齐 */
  margin:6px calc(var(--wf-ms) + var(--wf-gap)) 0 calc(var(--wf-name) + var(--wf-gap));
  border-top:1px solid var(--line);
}
.wf__axis span{
  position:absolute; top:7px; transform:translateX(-50%);
  font-family:var(--mono); font-size:10.5px; color:var(--muted-2);
}
.wf__axis span::before{
  content:""; position:absolute; left:50%; top:-7px; width:1px; height:5px;
  background:var(--line-2);
}
.wf__legend{
  display:flex; gap:16px; flex-wrap:wrap;
  padding:14px 0 16px;
  border-top:1px solid var(--line);
}
.k--dns::before{ background:#b9c0cc; }
.k--conn::before{ background:var(--accent-3); }
.k--ttfb::before{ background:var(--accent-2); }
.k--load::before{ background:var(--accent); }

.wf__sum{
  display:grid; grid-template-columns:repeat(4,1fr);
  border-top:1px solid var(--line);
  background:linear-gradient(180deg,#fbfbfd,#f6f7f9);
}
.wf__sum div{
  padding:20px clamp(14px,2vw,26px);
  border-right:1px solid var(--line);
  display:flex; flex-direction:column; gap:6px;
}
.wf__sum div:last-child{ border-right:0; }
.wf__sum b{
  font-size:clamp(20px,2.4vw,30px); font-weight:500; letter-spacing:-.03em;
}
.wf__sum b i{ font-family:var(--mono); font-style:normal; font-variant-numeric:tabular-nums; }
.wf__sum span{ font-size:11.5px; color:var(--muted-2); }

@media (max-width:640px){
  .wf__sum{ grid-template-columns:1fr 1fr; }
  .wf__sum div:nth-child(2){ border-right:0; }
  .wf__sum div:nth-child(1),.wf__sum div:nth-child(2){ border-bottom:1px solid var(--line); }
  .wfrow{ --wf-name:96px; }
  .wf__body{ --wf-name:96px; --wf-ms:46px; }
  /* 窄屏下名称列容不下角标，隐藏以免被裁切 */
  .wfrow.is-origin .wfrow__n::after,
  .wfrow.is-hit .wfrow__n::after{ display:none; }
}

/* —— 延迟表 —— */
.latgrid{
  margin-top:clamp(28px,4vw,48px);
  border-radius:var(--r-l); border:1px solid var(--line);
  background:#fff; box-shadow:var(--shadow-s);
  padding:clamp(20px,2.6vw,32px);
}
.latgrid__head{
  display:flex; align-items:center; justify-content:space-between;
  gap:16px; flex-wrap:wrap; margin-bottom:22px;
}
.latgrid__head h3{ font-size:17px; letter-spacing:-.015em; }
.latgrid__key{ display:flex; gap:16px; }
.k{ font-size:11.5px; color:var(--muted); display:inline-flex; align-items:center; gap:7px; }
.k::before{ content:""; width:14px; height:5px; border-radius:100px; }
.k--off::before{ background:#d9dbe0; }
.k--on::before{ background:linear-gradient(90deg,var(--accent),var(--accent-2)); }

.latgrid ul{ display:flex; flex-direction:column; gap:2px; }
.latrow{
  display:grid; grid-template-columns:minmax(72px,110px) 1fr minmax(96px,124px);
  align-items:center; gap:clamp(10px,2vw,22px);
  padding:11px 0; border-bottom:1px solid var(--line);
}
.latrow:last-child{ border-bottom:0; }
.latrow__c{ font-size:14px; }
.latrow__c em{
  display:block; font-style:normal; font-size:10.5px; color:var(--muted-2);
  font-family:var(--mono); letter-spacing:.06em; margin-top:2px;
}
.latrow__bars{ display:flex; flex-direction:column; gap:5px; }
.lbar{ height:6px; border-radius:100px; background:rgba(0,0,0,.04); overflow:hidden; }
.lbar i{
  display:block; height:100%; width:0; border-radius:100px;
  transition:width 1.2s var(--ease);
}
.lbar--off i{ background:#d9dbe0; }
.lbar--on  i{ background:linear-gradient(90deg,var(--accent),var(--accent-2)); }
.latrow__d{
  text-align:right; font-family:var(--mono); font-size:12.5px;
  font-variant-numeric:tabular-nums; color:var(--muted);
}
.latrow__d b{ color:var(--ok); font-weight:600; }

/* 访客所在区域：整行提亮，绿色角标 */
.latrow.is-you{
  background:linear-gradient(90deg, rgba(53,176,113,.075), rgba(53,176,113,0) 72%);
  border-radius:10px;
  box-shadow:inset 2px 0 0 var(--ok-2);
  padding-inline:10px;
}
.latrow__you{
  display:inline-block; margin-left:8px;
  padding:1px 7px; border-radius:999px;
  background:rgba(53,176,113,.14); color:var(--ok);
  font-size:10.5px; font-weight:600; letter-spacing:.02em;
  vertical-align:1px;
}

/* =========================================================
   产品能力卡片
   ========================================================= */
.cards{
  display:grid; gap:clamp(12px,1.4vw,18px);
  grid-template-columns:repeat(6,1fr);
}
.card{
  position:relative; overflow:hidden;
  grid-column:span 2;
  border-radius:var(--r-l);
  border:1px solid var(--line);
  background:#fff;
  padding:clamp(24px,2.6vw,34px);
  box-shadow:var(--shadow-s);
  transition:transform .55s var(--ease), box-shadow .55s var(--ease), border-color .55s var(--ease);
}
.card--wide{ grid-column:span 3; }
.card::before{
  content:""; position:absolute; inset:0; pointer-events:none;
  opacity:0; transition:opacity .5s var(--ease);
  background:radial-gradient(360px circle at var(--mx,50%) var(--my,0%), rgba(11,100,216,.075), transparent 62%);
}
.card:hover{ transform:translateY(-4px); box-shadow:var(--shadow-m); border-color:rgba(11,100,216,.22); }
.card:hover::before{ opacity:1; }
.card__ic{
  width:42px; height:42px; border-radius:12px;
  display:grid; place-items:center; margin-bottom:20px;
  background:linear-gradient(180deg, rgba(11,100,216,.1), rgba(11,100,216,.045));
  border:1px solid rgba(11,100,216,.16);
}
.card__ic svg{
  width:21px; height:21px; fill:none;
  stroke:var(--accent); stroke-width:1.6;
  stroke-linecap:round; stroke-linejoin:round;
}
.card h3{ font-size:19px; letter-spacing:-.02em; }
.card p{ margin-top:10px; font-size:14.8px; line-height:1.62; color:var(--muted); }
.card__tags{ display:flex; flex-wrap:wrap; gap:7px; margin-top:18px; }
.card__tags li{
  font-family:var(--mono); font-size:10.5px; letter-spacing:.04em;
  color:var(--ink-2); background:var(--paper-2);
  border:1px solid var(--line); border-radius:100px; padding:4px 10px;
}
@media (max-width:900px){
  .cards{ grid-template-columns:repeat(2,1fr); }
  .card, .card--wide{ grid-column:span 1; }
}
@media (max-width:560px){
  .cards{ grid-template-columns:1fr; }
}

/* =========================================================
   接入流程
   ========================================================= */
.flow{
  --fgap:clamp(18px,2.4vw,30px);
  position:relative;
  display:grid; grid-template-columns:repeat(4,1fr);
  gap:var(--fgap);
  padding-top:38px;
}
.flow__line{
  /* 进度轨只延伸到第 04 个圆点为止：越过最后一个里程碑会读成「还没走完」。
     第 4 列左边缘 = 75% + 3/4 gap，所以右侧内缩 25% − 3/4 gap。 */
  position:absolute; top:0; left:0; right:calc(25% - var(--fgap) * .75); height:1px;
  background:var(--line-d);
}
.flow__line i{
  display:block; height:100%; width:0;
  background:linear-gradient(90deg, var(--accent), var(--accent-2));
  box-shadow:0 0 12px rgba(61,142,245,.5);
  transition:width 1.6s var(--ease);
}
.flow__i{ position:relative; }
.flow__i::before{
  content:""; position:absolute; top:-38px; left:0;
  width:7px; height:7px; border-radius:50%;
  background:var(--dark); border:1px solid var(--line-d2);
  transform:translateY(-3px);
  transition:background .5s var(--ease), border-color .5s var(--ease), box-shadow .5s var(--ease);
}
.flow__i.is-in::before{
  background:var(--accent-2); border-color:var(--accent-2);
  box-shadow:0 0 0 4px rgba(61,142,245,.18);
}
.flow__n{
  font-family:var(--mono); font-size:11.5px; letter-spacing:.1em;
  color:var(--accent-3);
}
.flow__i h3{ margin-top:14px; font-size:19px; letter-spacing:-.02em; }
.flow__i p{ margin-top:10px; font-size:14.5px; line-height:1.6; color:var(--on-dark-2); }
@media (max-width:820px){
  .flow{ grid-template-columns:1fr 1fr; gap:32px 24px; padding-top:24px; }
  /* 折行成两排后，顶部那条轨只覆盖第一排，第二排的圆点会悬在空处——
     窄屏干脆去掉轨，让圆点退化成每一步自己的标记 */
  .flow__line{ display:none; }
  /* 但圆点若还悬在序号上方，就正好落在两步之间的空隙中央，
     上下距离一样、归属不明。挪到序号左侧同一行，读成「● 01」才无歧义。 */
  .flow__i{ padding-left:18px; }
  .flow__i::before{ top:4px; transform:none; }
}
@media (max-width:480px){
  .flow{ grid-template-columns:1fr; }
}

/* =========================================================
   客户之声
   ========================================================= */
.quote-sec{ padding-block:clamp(70px,9vw,130px); }
.quote{ margin:0; max-width:900px; margin-inline:auto; text-align:center; }
.quote p{
  font-size:clamp(21px,3vw,38px); font-weight:500;
  letter-spacing:-.028em; line-height:1.34; text-wrap:balance;
}
.quote p b{ color:var(--accent); font-weight:500; }
.quote footer{
  margin-top:34px; display:inline-flex; align-items:center; gap:13px;
  font-size:14px; color:var(--muted);
}
.quote footer b{ color:var(--ink); font-weight:600; }
.quote__av{
  width:40px; height:40px; border-radius:50%; flex:none;
  display:grid; place-items:center;
  background:linear-gradient(160deg,#e8ebf1,#d5dae3);
  color:var(--ink-2); font-size:15px; font-weight:600;
  border:1px solid rgba(0,0,0,.06);
}

/* =========================================================
   价格
   ========================================================= */
.plans{
  display:grid; gap:clamp(14px,1.6vw,20px);
  grid-template-columns:repeat(3,1fr);
  align-items:start;
}
.plan{
  position:relative;
  border-radius:var(--r-xl);
  border:1px solid var(--line);
  background:#fff;
  padding:clamp(26px,2.8vw,38px);
  box-shadow:var(--shadow-s);
  transition:transform .55s var(--ease), box-shadow .55s var(--ease);
}
.plan:hover{ transform:translateY(-3px); box-shadow:var(--shadow-m); }
.plan--hot{
  border-color:transparent;
  box-shadow:0 0 0 1.5px var(--accent), var(--shadow-m);
  z-index:1;
}
.plan__flag{
  position:absolute; top:-1px; right:26px; transform:translateY(-50%);
  background:var(--accent); color:#fff;
  font-size:11px; letter-spacing:.04em; padding:5px 12px; border-radius:100px;
  box-shadow:0 6px 16px rgba(11,100,216,.3);
}
.plan h3{ font-size:19px; letter-spacing:-.02em; }
.plan__p{
  margin-top:18px;
  font-family:var(--mono); font-size:clamp(34px,4vw,46px); font-weight:500;
  letter-spacing:-.04em; line-height:1;
  display:flex; align-items:baseline; gap:2px;
}
.plan__p em{ font-style:normal; font-size:.48em; }
.plan__p span{
  font-family:var(--sans); font-size:14px; font-weight:400;
  color:var(--muted-2); margin-left:8px; letter-spacing:0;
}
.plan__p--txt{ font-family:var(--sans); font-size:clamp(30px,3.4vw,40px); }
.plan__d{
  margin-top:14px; font-size:14px; color:var(--muted); line-height:1.6;
  min-height:44px;
}
.plan ul{
  display:flex; flex-direction:column; gap:11px;
  margin:24px 0 28px; padding-top:22px; border-top:1px solid var(--line);
}
.plan li{
  position:relative; padding-left:24px; font-size:14.5px; color:var(--ink-2);
}
.plan li::before{
  content:""; position:absolute; left:1px; top:7px;
  width:11px; height:6px; border-left:1.6px solid var(--accent);
  border-bottom:1.6px solid var(--accent);
  transform:rotate(-45deg);
}
.plans__note{
  margin-top:26px; text-align:center; font-size:12.5px; color:var(--muted-2);
}
@media (max-width:900px){
  .plans{ grid-template-columns:1fr; }
  .plan__flag{ right:auto; left:26px; }
}

/* =========================================================
   CTA
   ========================================================= */
.cta{
  position:relative; overflow:hidden;
  background:var(--dark); color:var(--on-dark);
  padding-block:clamp(88px,12vw,150px);
  text-align:center;
}
.cta canvas{ position:absolute; inset:0; width:100%; height:100%; opacity:.75; }
.cta::after{
  content:""; position:absolute; inset:0; pointer-events:none;
  background:radial-gradient(70% 70% at 50% 46%, transparent 30%, rgba(8,9,11,.72) 78%);
}
.cta__inner{ position:relative; z-index:2; }
.cta h2{
  font-size:clamp(30px,4.6vw,58px); letter-spacing:-.032em; line-height:1.08;
}
.cta > .container > p{
  margin-top:22px; color:var(--on-dark-2); font-size:clamp(15.5px,1.4vw,18px);
}
.cta__form{
  margin:38px auto 0; max-width:580px;
  display:flex; gap:10px;
}
.cta__form input{
  flex:1; min-width:0; height:52px; padding:0 20px;
  border-radius:26px; border:1px solid var(--line-d2);
  background:rgba(255,255,255,.06); color:#fff;
  font-size:15.5px; font-family:var(--sans);
  -webkit-backdrop-filter:blur(10px); backdrop-filter:blur(10px);
  transition:border-color .4s var(--ease), background .4s var(--ease);
}
.cta__form input::placeholder{ color:rgba(158,163,172,.75); }
.cta__form input:focus{
  outline:none; border-color:var(--accent-2);
  background:rgba(255,255,255,.09);
  box-shadow:0 0 0 4px rgba(61,142,245,.16);
}
.cta__msg{
  margin-top:18px; min-height:22px; font-size:13.5px;
  color:var(--accent-3); font-family:var(--mono);
  opacity:0; transform:translateY(6px);
  transition:opacity .5s var(--ease), transform .5s var(--ease);
}
.cta__msg.is-show{ opacity:1; transform:none; }
@media (max-width:560px){
  .cta__form{ flex-direction:column; }
  .cta__form input{ text-align:center; }
}

/* 小屏换行控制
   .br-m 全部落在标点边界上（「四步，十分钟。| 不动一行业务代码。」）。
   小屏一度把它隐藏掉，结果浏览器改在任意字间断行——中文没有词间空格，
   于是出现「不 / 动」「服 务 / 其后」「阶 / 梯」这类把词组劈开的尾行。
   所以窄屏反而要保留这个硬换行，改成压字号来保证每段都放得下。 */
@media (max-width:560px){
  /* 最长的一段是 10 个汉字（「攻击流量止步于边缘，」）。
     可用宽度 = 100vw − 2×20px 内边距，故字号上限约 (10vw − 4px)；
     再让出 1px 余量，避免不同中文字体的字距差异把末字挤下去。 */
  .sec-title{ font-size:min(31px, calc(10vw - 5px)); }
}
