/* findping（IP 段存活扫描）页面样式。
   与 tool.css 的分工：tool.css 是各工具页共用的表单/结果区基础样式，
   这里只放本页独有的统计条、视图切换、分组与 IP 胶囊。

   ⚠️ 本页结果区**不是表格**。按 /24 分组后每组是一个独立区块（标题 + 胶囊墙），
   塞进单张表要多级 tbody + 组标题行，语义差且难看。容器是 div#result-tbody。 */

/* ===== 表单 =====
   左「IP 段输入」右「扫描按钮」，与 ech 页同构（同样的两栏 → 右侧按钮列）。

   ★ 按钮与输入框的水平对齐靠「两栏顶线一致 + 两侧首个子元素都是 46px 控件」。

   关键前提：模板里左侧 .form-group 虽然写了 <label>，但
   `site/workspace.css` 有一条
     .tool-page>.tool-form .form-row .form-group>label { display:none }
   把它整个隐藏了 —— 所以输入框就是左栏的**第一行**，上方没有任何留白。
   因此右侧按钮列**不需要**任何上边距/占位块去"跳过 label"，加了反而会把
   按钮压低 27px，造成新的错位（这是上一版的错误）。

   两侧顶线对齐后：输入框 46px、按钮 46px，上下边缘自然在同一条水平线上。 */
.findping-form-body {
    display: flex;
    flex-wrap: wrap;
    gap: 20px;
    /* 覆盖 workspace.css 给 .form-row 的 align-items:flex-end：
       那是给「无 label 的单行控件」用的底对齐，本页两栏高度不同
       （左栏还有提示行），必须改用顶对齐。 */
    align-items: flex-start;
}
.findping-form-main {
    /* 覆盖 workspace.css 的 `.form-row .form-group { flex: 1 }`：那条只有 (0,4,0)，
       本选择器 (0,1,0) 压不住，所以必须带上同样的前缀才生效（见下方按钮规则）。 */
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.tool-page>.tool-form .form-row>.findping-form-main { flex: 1 1 320px; }
.tool-page>.tool-form .form-row>.findping-form-side { flex: 0 0 200px; }
.findping-form-side {
    display: flex;
    flex-direction: column;
    gap: 10px;
    /* 不写 padding-top / ::before 占位：label 已被隐藏，左栏第一行就是输入框。 */
    /* ⚠️ 右栏自己是 flex 容器且只有一行按钮，align-self 必须显式 flex-start：
       父级 .findping-form-body 是 flex-start，但本栏高度由内容决定，
       一旦某条同类规则把它拉到 stretch，按钮就会被垂直拉高/居中而错位。 */
    align-self: flex-start;
}

/* 输入框必须显式设高：style.css 里 `.tool-page > .tool-form .form-group input`
   给的是 44px + 无纵向内边距，单行文本框本身没问题，但本页输入的是地址段
   （含 "1.1.1.1-1.1.1.254" 这类长串），等宽字体更易核对「点/横线」是否打错。 */
.findping-form-body .findping-form-main input[type="text"] {
    width: 100%;
    height: 46px;
    padding: 0 14px;
    border: 1px solid #d0dde3;
    border-radius: 8px;
    font-family: Menlo, Consolas, "Microsoft YaHei", monospace;
    font-size: 14px;
    color: #254150;
    /* 与右侧按钮逐项同理：锁定盒模型，两边才是"同一个 46px"。
       若按 content-box 计算，46px 会变成 46 + 2(上下边框) = 48px，
       比按钮高出 2px，下沿就对不齐了。 */
    box-sizing: border-box;
}
.findping-form-body .findping-form-main input[type="text"]:focus {
    border-color: #4285ed;
    box-shadow: 0 0 0 2px rgba(66, 133, 237, .15);
    outline: none;
}
/* 说明行：解释三种写法与上限。放在输入框下方而不是 label 里 —— label 太长会
   挤压输入框宽度，且读屏器会把整段说明当成字段名念出来。 */
.findping-hint { margin: 0; color: #7a8b96; font-size: 12px; line-height: 1.7; }
.findping-hint code {
    padding: 1px 5px;
    border-radius: 4px;
    background: #f2f6f9;
    color: #3d5a6c;
    font-family: Menlo, Consolas, monospace;
    font-size: 11px;
}

/* 按钮与输入框同高（都是 46px），这是"水平对齐"的另一半。
   ⚠️ 这里要同时压制 workspace.css 的两条规则，它们是错位的直接原因：
     .tool-page>.tool-form .btn            { height:44px; padding:0 12px; border-radius:3px; font-size:15px }
     .tool-page>.tool-form .btn-lg         { height:44px; padding:0 14px; font-size:15px }
     .tool-page>.tool-form .form-row .btn  { height:44px }
   三者特异性都在 (0,4,0)~(0,4,1)，裸写 `.findping-form-side .btn`（(0,2,0)）
   完全压不住 —— 按钮会保持 44px 的矮个头、3px 小圆角，与 46px/8px 圆角的
   输入框并排时上沿齐、下沿差一截，看着就是"没对齐"。
   因此下面这条必须写全 `.tool-page>.tool-form .form-row .findping-form-side .btn`。

   另外三处易错点一并处理：
   · padding 复位成 0 14px：否则 base.css 的 `.btn-lg { padding:12px 32px }`
     在 box-sizing:border-box 下把内容挤到 46px 框里，文字上下被裁；
   · border-radius 对齐输入框的 8px，否则一个 3px 一个 8px，边缘对不齐；
   · font-size 用 15px（与 workspace.css 一致）。不写 line-height：
     按钮是 inline-flex + align-items:center，图标与文字由 flex 居中即可。 */
.tool-page>.tool-form .form-row .findping-form-side .btn {
    width: 100%;
    height: 46px;
    padding: 0 14px;
    border-radius: 8px;
    font-size: 15px;
    /* 不写 line-height：按钮是 inline-flex + align-items:center，文字与图标
       由 flex 居中，再叠一层 line-height 反而会让它们在 46px 内偏上/偏下。 */
    align-self: flex-start;
}

/* ===== 常显说明 =====
   与 ech-disclaimer 同一套视觉语言（左侧强调线 + 淡黄底），但文案不同：
   本页要说清的是「不回包 ≠ 主机不存在」，这是最容易误读的一条。 */
.findping-disclaimer {
    margin: 0 0 18px;
    padding: 12px 16px;
    border-left: 3px solid #e6a23c;
    background: #fdf6ec;
    border-radius: 6px;
    color: #7a5b21;
    font-size: 13px;
    line-height: 1.75;
}
.findping-disclaimer strong { color: #8a5a00; }
.findping-disclaimer a { color: #b8821b; text-decoration: underline; }

/* 面板主体的左右留白。
   .ping-results-panel 本身没有内边距（ping 页的表格是贴边铺满的），
   但本页统计条、工具条、胶囊墙都是有边界的块，贴边会显得局促且与
   标题栏的 14px 缩进对不齐。这里统一给一个横向留白容器，
   避免四处分别写 padding 后忘了其中一处。 */
/* ⚠️ 这里刻意**不含** .findping-alive-groups：结果区自身是带边框的
   左右分栏容器（见下方 .findping-split），外层再加 14px 会让它的边框
   缩进到与统计条、工具条对不齐的位置，看着像"结果区被往右推了一点"。 */
.findping-stats,
.findping-toolbar { padding-left: 14px; padding-right: 14px; }

/* ===== 统计条 =====
   三项并排：查找范围 / ICMP 在线数量 / ICMP 在线率。

   ★ 每张卡内部是**横排单行**（参考图 2026-11-10）：
       查找范围：192.168.0.0 - 192.168.9.255   共 [2560] 个
       标签、数值、副标题全在同一行，靠 gap 与 margin-left:auto 拉开。
   原先是"标签在上、数值居中、副标题在下"的竖排三行，卡片高达 80px，
   把结果区整体往下推；横排后每张卡约 46px，与工具条一起收进一屏。

   三张**独立卡片**而不是一条连体的三等分（连体条的读法是"一条记录三个
   字段"，而这三项是三个并列结论：范围是输入条件，数量与在线率是结果）。 */
.findping-stats {
    display: grid;
    /* 参考图里三张卡接近等宽，第一张只略宽一点（要放下"范围 + 共 N 个"）。
       1.25fr 而不是早先的 1.6fr：范围值本身可以省略，多给宽度反而是浪费，
       而右边两张卡里的"已扫 254 个"在 1fr 下容易贴边。 */
    grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr) minmax(0, 1fr);
    gap: 12px;
    margin: 14px 0 16px;
}
/* 单行不让换行：换行会让三张卡高度不一致、底部参差。
   内容超宽时由"范围值"那一条自己省略（见下方 :not(.is-alive):not(.is-rate)）。 */
.findping-stat {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 8px;
    padding: 12px 16px;
    background: #fff;
    border: 1px solid #e2e8ed;
    border-radius: 8px;
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
}
/* 标签后带中文冒号，与参考图一致（"查找范围："）。
   flex:0 0 auto 不收缩：标签被压缩会先从"ICMP 在线"处断开，读起来像另一个词。 */
.findping-stat-label {
    flex: 0 0 auto;
    color: #96a3ad;
    font-size: 13px;
}
.findping-stat-label::after { content: '：'; }
/* 第一张卡（查找范围）的标签前有个放大镜图标（参考图）。
   用内联 SVG 背景而不是额外插一个 <svg>：模板不改，图标也不可能被
   "点一下"误触；尺寸 13px 与 13px 标签字高基本齐平。 */
.findping-stat:first-child .findping-stat-label {
    padding-left: 19px;
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%2396a3ad' stroke-width='1.5' stroke-linecap='round'%3E%3Ccircle cx='7' cy='7' r='4.6'/%3E%3Cpath d='M10.4 10.4 14 14'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: 0 center;
    background-size: 13px 13px;
}
/* 主数值：等宽字体让「在线率 6.95%」与「数量 89」在切换时宽度不跳。 */
.findping-stat-value {
    flex: 0 0 auto;
    color: #254150;
    font-family: Menlo, Consolas, monospace;
    font-size: 14px;
    font-weight: 500;
    line-height: 1.4;
}
/* 查找范围是三者中唯一可能很长的项（"192.168.0.0 - 192.168.9.255"），
   允许它收缩并单行省略 —— 截断的是结尾那几位，前面的网段仍然可读。
   另两项（数量/在线率）永远很短，走上面的 flex:0 0 auto 不收缩。 */
.findping-stat-value:not(.is-alive):not(.is-rate) {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    color: #3d7ce0;
}
/* 在线数量与在线率的数字用蓝色计数徽标：它们是这条页面的结论，
   卡片里其它文字（标签、备注）都退成灰色辅助信息。
   徽标边框为淡蓝、底色近白，密集出现时也不会糊成一片。 */
.findping-stat-value.is-alive,
.findping-stat-value.is-rate {
    display: inline-block;
    padding: 1px 9px;
    border: 1px solid #b9d3f5;
    border-radius: 4px;
    background: #f5f9ff;
    color: #3d7ce0;
    font-size: 14px;
    font-weight: 600;
    /* 徽标宽度随数字变化，但变化幅度很小；给个下限让「0」也不会缩成一个点。 */
    min-width: 32px;
    text-align: center;
    box-sizing: border-box;
}
/* 副标题（"共 2560 个" / "已扫 254 个" / "扫描完成"）：
   推到卡片最右端（margin-left:auto），与左侧"标签：数值"拉开一段距离，
   这正是参考图里"共〔2560〕个"贴着右边的排版。 */
.findping-stat-sub {
    flex: 0 0 auto;
    margin-left: auto;
    color: #96a3ad;
    font-size: 12px;
}
/* 副标题里的数字也是小徽标（参考图的 "共〔2560〕个"）。
   比主数值徽标更浅：它是注释而不是结论，不该与主数值抢同一层视觉重量。 */
.findping-stat-sub b {
    display: inline-block;
    padding: 0 6px;
    border: 1px solid #cfdef0;
    border-radius: 4px;
    background: #f7fafd;
    color: #5b8fd2;
    font-family: Menlo, Consolas, monospace;
    font-weight: 500;
    line-height: 18px;
}

/* ===== 工具条 =====
   左视图切换、右复制与导出。「分段/合并」是本页的核心交互：
   分段能看出"哪几段有人"，合并方便一次性复制全部 IP。 */
.findping-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    /* 只写纵向：横向留白由上面那条共享规则给，用 padding 简写会把
       padding-left/right 一并重置成 0（同特异性、靠书写顺序决胜负）。 */
    padding-bottom: 12px;
}
.findping-view-switch { display: inline-flex; align-items: center; gap: 8px; }
/* 切换按钮（参考图 2026-11-10）：两个**描边胶囊**，各带一个图标。
   选中项 = 白底 + 蓝字 + 蓝描边；未选中 = 白底 + 灰字 + 浅灰描边。
   原先是"选中实心蓝"的画法，与参考图不符 —— 实心块在这条浅色工具条上
   过重，描边胶囊更轻，也让右侧的下载/复制按钮不至于抢戏。 */
.findping-view-tab {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 4px 10px;
    border: 1px solid #e2e8ed;
    background: #fff;
    border-radius: 5px;
    color: #6b7b88;
    font-size: 13px;
    line-height: 18px;
    cursor: pointer;
    transition: border-color .15s ease, color .15s ease;
    white-space: nowrap;
}
/* 图标走 currentColor，颜色随文字一起变，不必为选中/未选中各写一份。 */
.findping-view-tab svg { display: block; flex: 0 0 auto; }
/* :not(.is-active) 是必需的：不加的话鼠标划过选中项会把它覆盖成灰字，
   两者权重相同、靠书写顺序决胜负，选中项一悬停就"褪色"。 */
.findping-view-tab:not(.is-active):hover { border-color: #c8d7e4; color: #4a6070; }
.findping-view-tab.is-active {
    border-color: #9dc0f2;
    color: #2f74d8;
    background: #fff;
}
.findping-view-tab:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px rgba(66, 133, 237, .18);
}

.findping-toolbar-right { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

/* 复制按钮：与右侧 result.actions 的导出胶囊**逐项同高同圆角**
   （min-height 28 / padding 0 9 / border-radius 4 / font-size 12）。
   这三个导出按钮是站内通用组件，复制按钮若单独用别的尺寸，
   同一行右侧会一小一大，看着像两套控件拼在一起。 */
.findping-copy-btn {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    min-height: 28px;
    padding: 0 9px;
    border: 1px solid #d6e0e6;
    border-radius: 4px;
    background: #fff;
    color: #526675;
    font-size: 12px;
    line-height: 1;
    cursor: pointer;
    transition: border-color .15s ease, color .15s ease, background-color .15s ease;
}
.findping-copy-btn svg { display: block; flex: 0 0 auto; }
.findping-copy-btn:hover:not(:disabled) {
    border-color: #4285ed;
    color: #326fce;
    background: #edf4ff;
}
.findping-copy-btn:disabled { color: #b3bfc8; cursor: not-allowed; }

/* ===== 结果区：左段列表 + 右地址面板 =====
   本页的主视觉。原先每段「标题 + 胶囊墙」上下堆成一长条，段一多就得
   反复上下翻找，且右侧大片宽度空着不用。改成左右分栏后：

   - 左栏窄（约 210px）、只放"段名 + 存活数"，作用是**挑一段去看**；
   - 右栏吃掉剩余宽度，只渲染选中段里的地址，纵向滚动。
   两者各自独立滚动，左栏选段不会把右栏的滚动位置带跑。

   ⚠️ 深度约束：.findping-alive-groups 是 div#result-tbody 本身，内容由
   JS 每帧整体 innerHTML 替换，所以这两个类只出现在 JS 拼出的结构里。 */
.findping-split {
    display: grid;
    /* 左栏固定 240px（对齐参考图：左栏约占结果区 1/5 强，段名与徽标之间
       留出充足空隙）。右列写成 minmax(0, 1fr) 而不是 1fr：1fr 的最小值是
       auto，内容宽（长地址）会把列撑出容器，产生横向溢出。 */
    grid-template-columns: 240px minmax(0, 1fr);
    /* 单行网格，行高受容器定高约束（minmax(0,1fr) 而非 auto），
       这样两栏才能在内部滚动而不是把行撑高。 */
    grid-template-rows: minmax(0, 1fr);
    /* 两栏之间留 12px 深色缝：参考图里左栏是一块独立的浅灰圆角卡，
       右栏是另一块，中间露出面板底色的窄缝 —— 两栏不再靠 1px 描边分隔。 */
    gap: 12px;
    /* 横向与统计条/工具条对齐：那两个块各自带 14px 内边距，
       本容器改用同值外边距，边框才能落在同一条竖线上。 */
    margin: 0 14px 4px;
    /* 外层不再画边框：两栏各自带圆角与底色，外框会形成"框中框"。 */
    border: 0;
    /* ★ 高度**固定 535px**（用户明确要求，2026-11-10）。
       原先是 max-height:60vh —— 那是"上限"而非定高，只有一两个段时
       结果区会缩成一小截，窗口一高一矮高度就变。改成定高后：
       无论段有多少、窗口多高，两块面板始终是同一尺寸，页面不再跳动。
       ⚠️ 定高能生效的前提仍是下面两条（缺一不可）：
         ① 子项 min-height:0（否则子项拒绝压缩，把行撑高）；
         ② 行高为 minmax(0,1fr)（auto 行会按内容长高）。
       行高由 grid-template-rows 吃掉全部 535px，两栏各自内部滚动。 */
    height: 535px;
}
/* 左栏：段列表。
   浅灰蓝底 + 圆角，与右栏并排成两块独立卡片（参考图口径）。
   overflow-y:auto 让段列表独立滚动；右栏滚到一半时左栏仍停在原处。 */
.findping-split-left {
    display: flex;
    flex-direction: column;
    /* 6px 而不是 2px：参考图里五条之间有清晰的分隔带，
       2px 时色块挨得太近，整列看起来像一根连续的浅蓝条。 */
    gap: 6px;
    /* 上下左右均 8px：图里第一条距栏顶、距左边缘都是这个量级，
       与条目内部 10px 的左右内边距相加后，段名前留白约 18px。 */
    padding: 8px;
    border-radius: 4px;
    background: #eef2f6;
    overflow-y: auto;
    overflow-x: hidden;
    /* ⚠️ min-height:0 必须写：grid/flex 子项的 min-height 默认是 auto，
       于是子项拒绝被压缩到内容高度以下 —— 段多时左栏被整个撑开、
       把 .findping-split 的 max-height 顶破，滚动条便不会出现。
       代价是整个结果区随段数无限变长、统计条被顶出首屏。 */
    min-height: 0;
}
/* 右栏：选中段内的存活地址，单列逐行。
   单列而不是胶囊墙（flex-wrap）：段内常有几十个地址，逐行才好核对与计数。
   底色与左栏同为浅灰蓝 —— 参考图里两栏是同一种卡面色，不是一深一白。 */
.findping-split-right {
    display: flex;
    flex-direction: column;
    padding: 10px 14px;
    border-radius: 4px;
    overflow-y: auto;
    background: #eef2f6;
    /* 同上：地址多（一个 /24 最多 254 条）时，不写这条会用内容高度撑开
       网格行，max-height:60vh 失效，右栏永远不出滚动条。 */
    min-height: 0;
}

/* 两栏的滚动条：细、圆角、悬停加深。
   默认滚动条在 Windows 下约 17px 宽，会把 210px 的左栏挤掉近 1/10；
   且两栏各自滚动时两条粗滚动条并列，视觉上很吵。

   ⚠️ 只写 ::-webkit-scrollbar 这一套，**不要**同时写 scrollbar-width /
   scrollbar-color：Chromium 一旦识别到标准属性，就会停用全部
   ::-webkit-scrollbar 规则，结果圆角与悬停加深全部失效、退回系统默认样式。 */
.findping-split-left::-webkit-scrollbar,
.findping-split-right::-webkit-scrollbar,
.findping-flat-list::-webkit-scrollbar {
    width: 8px;
    height: 8px;
}
.findping-split-left::-webkit-scrollbar-track,
.findping-split-right::-webkit-scrollbar-track,
.findping-flat-list::-webkit-scrollbar-track {
    background: transparent;
}
.findping-split-left::-webkit-scrollbar-thumb,
.findping-split-right::-webkit-scrollbar-thumb,
.findping-flat-list::-webkit-scrollbar-thumb {
    border-radius: 4px;
    background: #d5dee5;
}
.findping-split-left::-webkit-scrollbar-thumb:hover,
.findping-split-right::-webkit-scrollbar-thumb:hover,
.findping-flat-list::-webkit-scrollbar-thumb:hover {
    background: #b7c6cf;
}
/* Firefox 走标准属性；放在上面那组之后统一声明，
   不影响 Chromium（它已由上方 ::-webkit- 规则接管滚动条外观）。 */
@supports not selector(::-webkit-scrollbar) {
    .findping-split-left,
    .findping-split-right,
    .findping-flat-list {
        scrollbar-width: thin;
        scrollbar-color: #d5dee5 transparent;
    }
}

/* 段条目：整行可点，段名靠左、存活数靠右。
   用 button 而不是 div：它本来就是一个"切换右侧内容"的开关，
   键盘 Tab / 回车天然可用，不必自己补 tabindex 与 keydown。 */
.findping-group-row {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    /* 定高 30px（参考图：13px 字 + 上下留白，不再是 padding 撑出来的）。 */
    height: 30px;
    padding: 0 10px;
    border: none;
    border-radius: 4px;
    /* 未选中底：必须比栏底（#eef2f6）明显深一档，否则色块等于看不见。
       #e6ebf5 与栏底几乎同色，是"看着没有间距"的主因。 */
    background: #e4e9f2;
    text-align: left;
    cursor: pointer;
    transition: background .12s ease, color .12s ease, box-shadow .12s ease;
}
/* 悬停只换底色、不做位移（与站内其它列表一致）。
   底色比基准略深一点点即可，过深会与选中态混淆。 */
.findping-group-row:hover:not(.is-active) { background: #d7e0ee; }
.findping-group-row:focus-visible {
    outline: none;
    box-shadow: 0 0 0 2px rgba(66, 133, 237, .28) inset;
}
/* 段名等宽：用户核对"扫的是不是这段"全靠它，点与数字须等宽对齐。 */
.findping-group-prefix {
    /* 不伸缩：段名很长（如 other 组）时不能把徽标挤没。 */
    flex: 0 0 auto;
    color: #4b5f73;
    font-family: Menlo, Consolas, monospace;
    font-size: 13px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* 存活数徽标：中性淡蓝。刻意不用红色——红色会被读成"告警"，
   而"这段活了 15 个"是中性的观察结果。

   margin-left:auto 贴到条目右端（距右边缘 10px，即条目内边距）；
   min-width + 居中让个位数与两位数徽标等宽，五条才能竖直对齐。 */
.findping-group-count {
    flex: 0 0 auto;
    margin-left: auto;
    min-width: 22px;
    padding: 0 6px;
    border-radius: 9px;
    background: rgba(255, 255, 255, .8);
    color: #4d7fc4;
    font-family: Menlo, Consolas, monospace;
    font-size: 12px;
    line-height: 18px;
    text-align: center;
    white-space: nowrap;
}
/* 选中态：蓝色**渐变**（左上浅右下深）+ 白字，与参考图一致。
   纯色平涂会显得死角、和未选中的浅蓝块层级拉不开；渐变加一道极浅的
   蓝色投影，让选中块"浮"在列表之上。
   徽标必须单独覆盖：它有自己的 background/color，不写就会在蓝底上
   留下一块白，看着像没选中完整。 */
.findping-group-row.is-active {
    background: linear-gradient(135deg, #6fa8f2 0%, #4a86e8 100%);
    box-shadow: 0 2px 6px rgba(74, 134, 232, .28);
}
.findping-group-row.is-active .findping-group-prefix { color: #fff; }
.findping-group-row.is-active .findping-group-count {
    background: rgba(255, 255, 255, .28);
    color: #fff;
}

/* ===== 初次渲染的示例骨架 =====
   is-placeholder 只是给 JS 用的标记（判断示例数据是否已注入），
   DOM 结构与真实结果完全相同，且**可正常点击**切换左栏网段。
   因此这里不写任何视觉修饰或 pointer-events —— 首屏就是个正常的结果面板，
   真数据到达后 customRenderResults 整体覆盖，外观无缝衔接。 */

/* 右栏单个地址：一行一个，**只显示 IP**。
   参考图（2026-11-10）里右栏是纯地址清单，没有延迟数字：
   这份结果的用途是"确认哪些地址活着、整段复制走"，延迟属于附加信息，
   混在每行末尾会让整列参差、也不便于纵向扫读比对地址。
   延迟仍然保留在 data-latency-ms 上（悬停提示与复制逻辑仍可用）。 */
.findping-ip-chip {
    display: block;
    padding: 1px 0;
    color: #445868;
    font-family: Menlo, Consolas, monospace;
    font-size: 13px;
    /* 行距参考图约 26px（13px 字 + 1.75 行高），密但不挤。 */
    line-height: 1.75;
    cursor: default;
}
/* 悬停：整行淡白底 + 左右补内边距。用负外边距抵消，避免鼠标移入时
   整行内容横向跳动（padding 一旦只在 hover 出现就会挤动文字）。 */
.findping-ip-chip:hover {
    margin: 0 -6px;
    padding: 1px 6px;
    border-radius: 3px;
    background: rgba(255, 255, 255, .7);
}
.findping-ip { white-space: nowrap; }
/* 延迟已从界面移除（见上），这里保留样式以便后续需要时一处改回即可。
   颜色仍由 latencyClass 的 lat-qN 决定（与其它页同口径）。 */
.findping-ip-lat {
    font-size: 12px;
    white-space: nowrap;
}

/* 合并视图：所有地址单列铺开，便于"从上往下全选复制"。
   卡面底色与左右分栏同值（#eef2f6 + 4px 圆角 + 14px 外边距），
   这样切到合并视图时结果区看起来还是"同一块面板"，而不是突然变白。 */
.findping-flat-list {
    display: flex;
    flex-direction: column;
    margin: 0 14px 4px;
    padding: 10px 14px;
    border-radius: 4px;
    background: #eef2f6;
    max-height: 60vh;
    overflow-y: auto;
}

/* 空态：等待 / 完成但无存活。用 p 而不是 tr：容器已经不是表格。 */
.findping-empty {
    margin: 0;
    padding: 26px 12px;
    color: #91a0a9;
    font-size: 13px;
    text-align: center;
}

/* ===== 扫描中的加载态（参考图 2026-11-10）=====
   整块居中竖排三行：转圈 / 主文案 / 「预计 N 秒内完成」。

   为什么不再用一行灰字：它挤在统计条与进度条之间、字号与正文同级，
   用户第一眼读到的是"没反应"；参考图的加载态是一块**独立的居中视觉**，
   转圈说明"在动"，文案说明"在扫什么 + 还要多久"。

   高度与结果区定高（535px）对齐：加载态是结果区的**替代内容**，
   若只按自身内容撑高，结果区会先塌成一小截再弹回 535px，
   整个页面跟着跳一下。这里让它撑满父级。 */
.findping-loading {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    /* 留出与结果区相称的高度：结果区定高 535px 时正好垂直居中；
       窄屏父级 height:auto，则由下面的 min-height 兜住。 */
    min-height: 220px;
    height: 100%;
    padding: 24px 12px;
    text-align: center;
}
/* 转圈圆环：与站内 probe-progress-spinner 同一套画法
   （透明圆 + 单边有色 border + 旋转），尺寸放大到 28px。
   ⚠️ 四边 border 必须**同宽**：只给上边着色、其余透明才只出现一段弧；
   某边写成 0 会缺口成扇形，转起来像抖动。 */
.findping-loading-ring {
    display: block;
    width: 28px;
    height: 28px;
    border: 3px solid #e3ebf5;
    border-top-color: #4285ed;
    border-radius: 50%;
    animation: findping-spin .8s linear infinite;
}
@keyframes findping-spin {
    to { transform: rotate(360deg); }
}
/* 主文案：在扫哪一段。与正文同号但加深，保证它是加载态里的第一落点。 */
.findping-loading-title {
    margin: 14px 0 0;
    color: #445868;
    font-size: 13px;
}
/* 副文案：「预计 N 秒内完成」。数字单独加粗染蓝 ——
   这是整块加载态里唯一的变化量，也是用户唯一想扫的字符。 */
.findping-loading-sub {
    margin: 6px 0 0;
    color: #91a0a9;
    font-size: 12px;
}
.findping-loading-sub b {
    color: #4285ed;
    font-weight: 600;
}
/* 尊重系统「减少动态效果」：转圈改成静态圆环，避免前庭敏感者不适。 */
@media (prefers-reduced-motion: reduce) {
    .findping-loading-ring {
        animation: none;
        border-top-color: #e3ebf5;
        border-left-color: #4285ed;
    }
}

/* 窄屏：按钮列换行占满，避免 200px 固定宽度把输入框挤成一行两三个字符。 */
@media (max-width: 640px) {
    /* 换行占满整行：按钮独占一行，不再需要与输入框并排对齐。 */
    .findping-form-side { flex: 1 1 100%; }
    .findping-form-side .btn { width: 100%; }
    /* 统计条在窄屏改为单列：三等分会让「1.1.1.0/24」和「6.95%」都缩到截断。 */
    .findping-stats { grid-template-columns: 1fr; }
    .findping-toolbar { align-items: flex-start; }
}

/* 中等宽度（平板/窄窗口）：双栏改为上下堆叠。
   左栏横过来铺成一行可横向滚动的段标签，右栏给固定高度自己滚动。
   横向标签而不是继续纵向堆两栏：手机上一屏高度有限，若上下两个
   纵向列表各占一半，两边都不够看。 */
@media (max-width: 760px) {
    .findping-split {
        grid-template-columns: minmax(0, 1fr);
        grid-template-rows: auto minmax(0, 1fr);
        /* 桌面版定高 535px 在窄屏下会顶出视口高度（手机横屏普遍只有
           360~420px），这里改成跟随视口的区间，而不是写死。 */
        height: auto;
        min-height: 0;
    }
    .findping-split-left {
        flex-direction: row;
        gap: 4px;
        padding: 8px;
        border-right: none;
        border-bottom: 1px solid #e6ecf1;
        overflow-x: auto;
        overflow-y: hidden;
        /* 横排时这一栏由 grid-template-rows 的 auto 行决定高度，
           桌面版那条 min-height:0 在此会让横条被压扁，必须复位。 */
        min-height: auto;
    }
    /* 横排时每段按钮按内容宽度排布，不被父级压扁成等分。
       高度改回 auto：桌面版定高 30px 是为逐行竖向对齐，
       横排成胶囊后由 padding 决定高度，硬顶 30px 会挤压文字。 */
    .findping-group-row {
        flex: 0 0 auto;
        width: auto;
        height: auto;
        padding: 6px 10px;
    }
    .findping-split-right { max-height: 52vh; }
}
