/* ============================================================
   一键连接 · 卡片变形动画（主稿 node-final 用）
   状态类挂在 .nconn（即 body() 里的 .nsec）：
     .nconn.is-connecting   水波从左漫入
     .nconn.is-on           已连接（卡片摘掉 .cur--rec，成为标准当前卡）
   水波填充 / 前缘三层正弦波 / 按钮三态 / 指标展开 / 列表归位
   ============================================================ */

 }

/* ============================================================
   卡片本体
   ============================================================ */
.cd-card {
  position: relative; overflow: hidden;
  transition: background .85s cubic-bezier(.22, .9, .25, 1),
              border-color .85s cubic-bezier(.22, .9, .25, 1),
              box-shadow .85s cubic-bezier(.22, .9, .25, 1),
              color .85s, transform .22s;
}
.cd-card.is-press { transform: scale(.978); }

/* 卡片表面扫光 */
.cd-sheen {
  position: absolute; top: -40%; bottom: -40%; width: 55%;
  background: linear-gradient(100deg, transparent, rgba(255, 255, 255, .62), transparent);
  transform: translateX(-220%) rotate(10deg);
  pointer-events: none; opacity: 0;
}
.nconn.is-connecting .cd-card .cd-sheen { animation: cd-sheen 1.15s cubic-bezier(.3, .6, .3, 1) .1s; }
@keyframes cd-sheen {
  0%   { transform: translateX(-220%) rotate(10deg); opacity: 1 }
  100% { transform: translateX(260%) rotate(10deg); opacity: 0 }
}

/* ============================================================
   ★ 水波填充：品牌蓝从左到右漫过整张卡片
   ============================================================ */
.cd-fill {
  position: absolute; left: 0; top: 0; bottom: 0;
  width: 0;
  z-index: 1; pointer-events: none;
  /* 与 .cur 已连接态的背景完全一致 —— 漫满后淡出也看不出接缝 */
  background: linear-gradient(150deg, #6FA8F0 0%, #4A8AE6 52%, #3D7BD4 100%);
  /* ★ 未连接时完全隐藏：否则宽度为 0 时，前缘波浪会往右探出卡片 */
  visibility: hidden; opacity: 0;
  transition: width 1.5s cubic-bezier(.35, .05, .25, 1),
              opacity .35s ease, visibility 0s linear .35s;
}
.nconn.is-connecting .cd-card .cd-fill {
  width: 100%; visibility: visible; opacity: 1;
  transition: width 1.5s cubic-bezier(.35, .05, .25, 1),
              opacity .2s ease, visibility 0s linear 0s;
}
.nconn.is-on .cd-card .cd-fill {
  width: 100%; visibility: hidden; opacity: 0;
  transition: opacity .45s ease, visibility 0s linear .45s;
}

/* 前缘：三层正弦波叠加（振幅/周期/方向/速度都不同） */
.cd-fill__wave {
  position: absolute; right: -52px; top: -100%;
  width: 60px; height: 300%;
  pointer-events: none;
}
.cd-fill__wave:nth-of-type(1) { animation: cd-drift 4.4s linear infinite; }
.cd-fill__wave:nth-of-type(2) { right: -46px; animation: cd-drift 3.2s linear infinite reverse; }
.cd-fill__wave:nth-of-type(3) { right: -38px; animation: cd-drift 2.3s linear infinite; }
@keyframes cd-drift {
  from { transform: translateY(0) }
  to   { transform: translateY(33.333%) }   /* = 一个完整波形周期，无缝循环 */
}

/* 水面上掠过的一道流光 */
.cd-fill__shimmer {
  position: absolute; top: -30%; bottom: -30%; width: 42%;
  background: linear-gradient(100deg, transparent, rgba(255, 255, 255, .34), transparent);
  animation: cd-flow 1.6s ease-in-out infinite;
}
@keyframes cd-flow { 0% { left: -55% } 100% { left: 115% } }

/* 卡片内容必须浮在水面之上 */
.cd-card .cur__top,
.cd-card .cur__body,
.cd-card .cd-stats { position: relative; z-index: 2; }

/* ============================================================
   槽位：两个内容占同一格交叉淡入淡出（不用绝对定位）
   ============================================================ */
.cd-stack { display: inline-grid; align-items: center; }
.cd-stack > .cd-slot { grid-area: 1 / 1; }
/* ★ 必须是 inline-flex：.dot 只有宽高、没有 display，靠父级 flex 才成块盒 */
.cd-slot {
  display: inline-flex; align-items: center; gap: 6px;
  transition: opacity .45s ease, transform .45s cubic-bezier(.22, .9, .25, 1);
}
.cd-slot--on { opacity: 0; transform: translateY(6px); }
.nconn.is-on .cd-card .cd-slot--idle { opacity: 0; transform: translateY(-6px); }
.nconn.is-on .cd-card .cd-slot--on { opacity: 1; transform: none; }
.cd-slot--cat { color: #0A6BD8; }
.cd-slot--note { color: #8E97A4; font-weight: 750; }

/* 区块标题（推荐节点 ↔ 当前节点）：结构不变，只做一次淡出淡入再由 JS 换文案 */
.nconn .fsec[data-sec-t] { transition: opacity .2s ease; }
.nconn .fsec.is-swap { opacity: 0; }

/* ============================================================
   操作按钮：三个槽位（一键连接 / 正在建立保护 / 断开）
   ============================================================ */
.cd-btn {
  position: relative; overflow: hidden;
  min-width: 88px;
  transition: background .6s, color .6s, border-color .6s,
              min-width .55s cubic-bezier(.22, .9, .25, 1),
              box-shadow .6s, opacity .4s;
}
.cd-btn__slot {
  transition: opacity .32s ease, transform .32s cubic-bezier(.22, .9, .25, 1);
  white-space: nowrap;
}
.cd-btn__busy, .cd-btn__on {
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%) translateY(7px);
  opacity: 0;
}
/* 连接中：白色药丸（白卡与蓝水上都读得清） */
.nconn.is-connecting .cd-card .cd-btn {
  min-width: 148px;
  background: #fff; color: #0A5FC4;
  border-color: transparent;
  box-shadow: 0 4px 12px rgba(20, 50, 100, .16);
}
.nconn.is-connecting .cd-card .cd-btn__idle { opacity: 0; transform: translateY(-7px); }
.nconn.is-connecting .cd-card .cd-btn__busy { opacity: 1; transform: translate(-50%, -50%); }
.nconn.is-connecting .cd-card .cd-btn__busy::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, rgba(10, 132, 255, .18), transparent);
  animation: cd-run 1.1s linear infinite;
}
@keyframes cd-run { 0% { transform: translateX(-100%) } 100% { transform: translateX(100%) } }
/* 已连接 → 与标准卡的 .cur .nact--off 完全一致 */
.nconn.is-on .cd-card .cd-btn {
  min-width: 76px;
  background: rgba(255, 255, 255, .22);
  color: #fff;
  border-color: rgba(255, 255, 255, .46);
  box-shadow: none;
}
.nconn.is-on .cd-card .cd-btn__idle { opacity: 0; transform: translateY(-7px); }
.nconn.is-on .cd-card .cd-btn__on { opacity: 1; transform: translate(-50%, -50%); }
.nconn.is-on .cd-card .cd-btn:hover {
  background: #fff; color: #0A6BD8; border-color: #fff;
  box-shadow: 0 5px 14px rgba(0, 40, 90, .22);
}

/* ============================================================
   底部指标 / 列表新增行：0fr → 1fr 平滑展开
   ============================================================ */
.cd-stats { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .7s cubic-bezier(.22, .9, .25, 1); }
.nconn.is-on .cd-card .cd-stats { grid-template-rows: 1fr; }
.cd-stats__in { overflow: hidden; }

.cd-reveal { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .6s cubic-bezier(.22, .9, .25, 1); }
.nconn.is-on .cd-reveal { grid-template-rows: 1fr; }
.cd-reveal__in { overflow: hidden; }

/* ============================================================
   节点列表：连接中下沉淡出，已连接交错滑回
   ============================================================ */
.nconn .frow { transition: opacity .5s ease, transform .6s cubic-bezier(.22, .9, .25, 1); }
.nconn.is-connecting .frow { opacity: 0; transform: translateY(26px); }
.nconn.is-on .frow { transition-delay: calc(var(--i, 0) * 70ms); }

/* 底部提示文字 */
.cd-hintslot { display: inline-grid; }
.cd-hintslot > .cd-slot { grid-area: 1 / 1; }
.nconn.is-on .fhint .cd-slot--idle { opacity: 0; }
.nconn.is-on .fhint .cd-slot--on { opacity: 1; }

/* 子元素颜色过渡（白→蓝渐变而不是跳变） */
.cd-card .cur__name,
.cd-card .cur__lat,
.cd-card .cur__flag,
.cd-card .loadbar,
.cd-card .load__t,
.cd-card .cur__live { transition: background .85s cubic-bezier(.22, .9, .25, 1), color .85s, border-color .85s; }
