/* ============================================================
   双子星云手机 · 重新设计样式系统
   参考：红手指/雷电云/VMOS/掌派 四款友商官网
   特点：
   - 明亮蓝白商务感 + 轻科技渐变点缀
   - 统一容器/间距/按钮/卡片/标签/栅格 设计系统
   - 区块清晰分层，信息层级强，适合产品官网
   ============================================================ */

/* ---------- 1. 设计变量 / Design Tokens ---------- */
:root {
    /* 色板 */
    --c-bg: #ffffff;
    --c-bg-soft: #f5f8ff;
    --c-bg-mid: #eef4ff;
    --c-bg-deep: #e6efff;
    --c-brand: #1b5cff;
    --c-brand-dark: #0e42c4;
    --c-brand-light: #4f8cff;
    --c-accent: #00b8ff;
    --c-success: #17c964;
    --c-warn: #f5a524;
    --c-danger: #f31260;
    --c-text: #0f172a;
    --c-text-2: #475569;
    --c-text-3: #64748b;
    --c-text-4: #94a3b8;
    --c-border: #e2e8f0;
    --c-border-2: #f1f5f9;

    /* 渐变 */
    --grad-brand: linear-gradient(135deg, #1b5cff 0%, #00b8ff 100%);
    --grad-brand-soft: linear-gradient(135deg, rgba(27, 92, 255, 0.1), rgba(0, 184, 255, 0.1));
    --grad-hero: linear-gradient(180deg, #f0f6ff 0%, #ffffff 65%);

    /* 阴影 */
    --sh-sm: 0 1px 3px rgba(15, 23, 42, 0.06);
    --sh-md: 0 6px 20px rgba(15, 23, 42, 0.07);
    --sh-lg: 0 20px 50px rgba(27, 92, 255, 0.12);
    --sh-glow: 0 14px 40px rgba(27, 92, 255, 0.22);

    /* 半径 */
    --r-sm: 8px;
    --r-md: 12px;
    --r-lg: 16px;
    --r-xl: 24px;
    --r-pill: 999px;

    /* 字号 */
    --fs-xs: 12px;
    --fs-sm: 14px;
    --fs-base: 16px;
    --fs-lg: 18px;
    --fs-xl: 22px;
    --fs-2xl: 28px;
    --fs-3xl: 38px;
    --fs-4xl: 52px;

    /* 间距 */
    --sp-xs: 6px;
    --sp-sm: 12px;
    --sp-md: 20px;
    --sp-lg: 32px;
    --sp-xl: 56px;
    --sp-2xl: 96px;

    /* 过渡 */
    --ease: cubic-bezier(0.22, 1, 0.36, 1);
    --dur: 0.3s;

    /* 字体 */
    --font-body: "PingFang SC", "Microsoft YaHei", "Helvetica Neue", Helvetica, Arial, -apple-system, sans-serif;
    --font-display: "PingFang SC", "Microsoft YaHei", system-ui, -apple-system, "Segoe UI", sans-serif;
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
    background: #fff;
    color: var(--c-text);
    font-family: var(--font-body);
    font-size: var(--fs-base);
    line-height: 1.65;
    -webkit-font-smoothing: antialiased;
}

/* v17: 标题排版增强 — display 字体 + text-wrap:balance + letter-spacing 精修 */
h1, h2, h3, h4 {
    font-family: var(--font-display);
    text-wrap: balance;
}
a { color: inherit; text-decoration: none; }
img { max-width: 100%; display: block; }

/* v16: 全局 focus-visible 可访问性 */
a:focus-visible,
button:focus-visible,
.rd-btn:focus-visible,
.rd-download-item:focus-visible,
.rd-sub-tab:focus-visible,
.rd-sub-item:focus-visible,
.rd-plan-tier:focus-visible,
.rd-contact-card:focus-visible,
.rd-help-box:focus-visible,
.rd-qr-card:focus-visible,
.rd-pagination a:focus-visible {
    outline: 2px solid var(--c-brand);
    outline-offset: 2px;
    border-radius: var(--r-sm);
}

/* ---------- 2. 容器 / Container ---------- */
.rd-container {
    width: 100%;
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 24px;
}
.rd-section {
    padding: var(--sp-2xl) 0;
    position: relative;
}
.rd-section.bg-soft { background: var(--c-bg-soft); }
.rd-section.bg-mid { background: var(--c-bg-mid); }

/* 通用区块头 */
.rd-head {
    text-align: center;
    margin-bottom: var(--sp-xl);
}
.rd-head .eyebrow {
    display: inline-block;
    color: var(--c-brand);
    font-size: var(--fs-sm);
    font-weight: 600;
    letter-spacing: 3px;
    padding: 6px 16px;
    border-radius: var(--r-pill);
    background: rgba(27, 92, 255, 0.08);
    border: 1px solid rgba(27, 92, 255, 0.15);
    margin-bottom: 16px;
}
.rd-head h2 {
    font-size: var(--fs-3xl);
    color: var(--c-text);
    margin: 0 0 12px;
    font-weight: 800;
    line-height: 1.2;
    letter-spacing: -0.5px;
}
.rd-head h2 .em {
    background: var(--grad-brand);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}
.rd-head p {
    color: var(--c-text-2);
    font-size: var(--fs-lg);
    max-width: 680px;
    margin: 0 auto;
    line-height: 1.7;
}
/* v51: 需要「按句拆成两行」的副标题。
   用 <br> 显式断行，再收窄 max-width 保证两行都不会被浏览器二次折行。
   text-wrap: balance 作为兜底（支持的浏览器会额外均衡两行长度）。 */
.rd-head p.p--2l {
    max-width: 620px;
    text-wrap: balance;
}
/* v51: 窄屏下强制断行反而会把每行挤短，故取消 <br> 的强制换行，
   让文字自然回流。用 ::first-line 无法取消 br，所以直接改 display。 */
@media (max-width: 640px) {
    .rd-head p.p--2l { max-width: 100%; }
    .rd-head p.p--2l br { display: none; }
}

/* ---------- 3. 按钮系统 / Buttons ---------- */
.rd-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 12px 26px;
    font-size: var(--fs-base);
    font-weight: 600;
    border-radius: var(--r-pill);
    border: none;
    cursor: pointer;
    transition: all var(--dur) var(--ease);
    white-space: nowrap;
    text-decoration: none;
    line-height: 1.2;
}
.rd-btn-primary {
    background: var(--grad-brand);
    color: #fff;
    box-shadow: 0 6px 18px rgba(27, 92, 255, 0.32);
}
.rd-btn-primary:hover {
    box-shadow: var(--sh-glow);
    transform: translateY(-2px);
}
.rd-btn-outline {
    background: #fff;
    color: var(--c-brand);
    border: 1.5px solid rgba(27, 92, 255, 0.25);
}
.rd-btn-outline:hover {
    border-color: var(--c-brand);
    background: rgba(27, 92, 255, 0.05);
    transform: translateY(-2px);
}
.rd-btn-ghost {
    background: transparent;
    color: var(--c-text-2);
    border: 1px solid var(--c-border);
}
.rd-btn-ghost:hover { border-color: var(--c-brand); color: var(--c-brand); }
.rd-btn-lg { padding: 16px 36px; font-size: var(--fs-lg); }
.rd-btn-sm { padding: 8px 18px; font-size: var(--fs-sm); }

/* 标签 / Tags */
.rd-tag {
    display: inline-block;
    padding: 4px 12px;
    border-radius: var(--r-pill);
    font-size: var(--fs-xs);
    font-weight: 600;
    background: rgba(27, 92, 255, 0.1);
    color: var(--c-brand);
    border: 1px solid rgba(27, 92, 255, 0.2);
}
.rd-tag.cyan { background: rgba(0, 184, 255, 0.1); color: #0092c9; border-color: rgba(0, 184, 255, 0.22); }
.rd-tag.green { background: rgba(23, 201, 100, 0.1); color: #0f9b4b; border-color: rgba(23, 201, 100, 0.22); }
.rd-tag.amber { background: rgba(245, 165, 36, 0.12); color: #c88108; border-color: rgba(245, 165, 36, 0.22); }
.rd-tag.rose { background: rgba(243, 18, 96, 0.1); color: #c40a4e; border-color: rgba(243, 18, 96, 0.22); }

/* ---------- 4. 卡片系统 / Cards ---------- */
.rd-card {
    background: #fff;
    border: 1px solid var(--c-border);
    border-radius: var(--r-lg);
    padding: 28px;
    transition: all var(--dur) var(--ease);
}
.rd-card:hover {
    transform: translateY(-4px);
    box-shadow: var(--sh-lg);
    border-color: rgba(27, 92, 255, 0.25);
}

/* Bento 功能矩阵卡片样式见区段 19 */

/* (removed: rd-scene-card dead code — not used in any HTML) */

/* 交替分栏卡片 */
.rd-split {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 80px;
    align-items: center;
    padding: 56px 0;
}
.rd-split.reverse .rd-split-text { order: 2; }
.rd-split .eyebrow { color: var(--c-brand); font-size: var(--fs-sm); font-weight: 600; letter-spacing: 2px; margin-bottom: 14px; }
.rd-split h3 { font-size: 32px; font-weight: 800; margin: 0 0 16px; color: var(--c-text); line-height: 1.22; letter-spacing: -0.3px; }
.rd-split h3 .em { background: var(--grad-brand); -webkit-background-clip: text; background-clip: text; color: transparent; }
.rd-split p { color: var(--c-text-2); font-size: var(--fs-base); line-height: 1.85; margin: 0 0 22px; }
.rd-split ul { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 12px; }
.rd-split li { display: flex; align-items: flex-start; gap: 10px; color: var(--c-text); font-size: var(--fs-sm); }
.rd-split li::before {
    content: "";
    width: 20px; height: 20px; flex-shrink: 0;
    margin-top: 2px;
    border-radius: 50%;
    /* 白色对勾作为 SVG 背景层，在圆点内绝对居中（替代旧 ::after 偏移方案） */
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E"), var(--grad-brand);
    background-size: 12px 12px, 100% 100%;
    background-position: center, center;
    background-repeat: no-repeat, no-repeat;
    box-shadow: 0 3px 10px rgba(27, 92, 255, 0.3);
}
.rd-split-visual {
    min-height: 360px;
    border-radius: var(--r-xl);
    background: var(--grad-brand-soft);
    position: relative;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid rgba(27, 92, 255, 0.12);
}
.rd-split-visual::before {
    content: "";
    position: absolute;
    inset: 0;
    background-image:
        linear-gradient(rgba(27, 92, 255, 0.07) 1px, transparent 1px),
        linear-gradient(90deg, rgba(27, 92, 255, 0.07) 1px, transparent 1px);
    background-size: 28px 28px;
}

/* ---------- v38: 「24小时云端运行」上下式区块 ----------
   布局：标题 + 副标题居中 → 四条卖点 2×2 居中网格 → 全宽配图。
   与左右分栏（.rd-split）并存，互不影响。 */

/* 标题区与下方内容间距收紧（默认 --sp-xl 偏大，上下式会显得空旷） */
.rd-head-tight { margin-bottom: 28px; }

/* 四条卖点：v49 起改为【1×4 横排】，整行关于中轴对称（与上方标题同中轴） */
.rd-check-grid {
    list-style: none;
    padding: 0;
    margin: 0 auto 40px;
    display: grid;
    /* ---------- v49: 由 2×2 改为 1×4 横排，四条并排居中 ----------
       需求：四条卖点横排成一行，与上方标题「24小时云端运行」同一中轴。

       布局计算（每条内容 = 图标20 + gap10 + 文字182 = 212px）：
         4×212 + 3×gap。取 gap=28 → 总宽 932px，容器宽 1200px 完全容纳。
       居中方式：本元素是 .rd-container 的直接子元素（块级、宽度自适应），
         用 max-content 让网格收缩到内容实际宽度，再 margin:0 auto 居中。
         —— 这样整行左右两侧空白天然相等，中轴与标题严格对齐。

       ⚠️ 不用 justify-content:center 的原因：该属性只在其宽度大于内容时起作用；
          这里宽度已是 max-content，配合 auto 外边距更直接可靠。

       ⚠️ 响应式必须降级：4 列 × 212 + 3×28 = 932px，
          视口 < 约 960px 时容器装不下会横向溢出，故下方按阶梯降级。 */
    grid-template-columns: repeat(4, max-content);
    width: max-content;
    max-width: 100%;
    gap: 14px 28px;
}

/* 中屏（1000px 以下）：4 列放不下 → 退回 2 列 × 2 行，仍整体居中
   ⚠️ 断点取 1000 而非 960：4 列内容实际宽 932px，
      而容器宽 = min(1200, 视口 - 2×24 padding)。
      视口 961~979px 时容器仅 913~931px < 932px → 会横向溢出。
      取 1000px 断点可确保切到 2 列时容器已足够（实测 1000px 视口容器 952px > 456px×2 需求）。 */
@media (max-width: 1000px) {
    .rd-check-grid {
        grid-template-columns: repeat(2, max-content);
        gap: 14px 32px;
    }
}

/* 窄屏（640px 以下）：2 列也可能放不下 → 退回单列竖排
   ⚠️ 此处必须把 width 从 max-content 重置为 auto，
      否则 max-content 会让网格撑到内容宽度、无视 max-width 而溢出。 */
@media (max-width: 640px) {
    .rd-check-grid {
        grid-template-columns: 1fr;
        width: auto;
        max-width: 420px;
        gap: 12px;
    }
}
.rd-check-grid li {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    color: var(--c-text);
    font-size: var(--fs-sm);
    line-height: 1.5;
}
/* 圆形蓝色对勾，复用 .rd-split li::before 的实现 */
.rd-check-grid li::before {
    content: "";
    width: 20px; height: 20px; flex-shrink: 0;
    margin-top: 1px;
    border-radius: 50%;
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E"), var(--grad-brand);
    background-size: 12px 12px, 100% 100%;
    background-position: center, center;
    background-repeat: no-repeat, no-repeat;
    box-shadow: 0 3px 10px rgba(27, 92, 255, 0.3);
}

/* 全宽配图：容器等宽，内部图片 cover 填满
   ---------- v55: 去掉配图外围的"框" ----------
   用户要求「24小时云端运行视频」「数据安全保障图片」的外框
   按首屏配图（v54）同样的标准处理 —— 去掉外框、完全融入页面。

   与首屏那次的区别（很重要）：
   首屏的"框"在图片文件内部（画布裁断卡片圆角 + 页面渐变接缝），
   改 CSS 是白改；而这两块的"框"是**容器真实的 CSS 样式**：
     border-radius: 24px + border 1px 蓝 + box-shadow + 渐变底色
   运行时实测确认（修复前）：
     radius "24px" / border "1px solid rgba(27,92,255,0.12)"
     shadow "rgba(15,23,42,0.07) 0px 6px 20px 0px"
   所以这次是**真·删 CSS**。

   用户选择：两个区块都"完全去框"，且数据安全插图**不抠图**
   （保留其自带的纯白底，实测四边为 254,254,254，与页面白底差异极小）。
   故四个属性一并移除：圆角、描边、投影、底色。
   overflow:hidden 也一并去掉 —— 没有圆角就不需要裁剪，
   留着反而会在图片加载前把空框裁成硬边。 */
.rd-cloud-visual {
    position: relative;
}
.rd-cloud-visual img {
    display: block;
    width: 100%;
    /* ---------- v47: 换图后容器比例改为跟随新图 ----------
       新图（数据安全保障）源尺寸 1536×1024 = 1.5:1，
       内容边界 x 231~1359 / y 100~891，四周均为 254/255 近白留白。
       若沿用旧的 1.6:1 容器 + cover：scale=max(857/1536, 536/1024)=0.5579，
       渲染为 857×571，容器仅 536 高 → **上下各裁 18px**（纵向溢 36px）。
       虽然裁到的只是白留白（内容距裁切线尚有 100/132px 余量，内容零损失），
       但为保持「中心塔 + 四角节点」对称构图完整、且不再有任何裁切，
       容器比例直接改为与新图一致，object-fit 用 cover 但实际缩放比恰好相等
       → 渲染尺寸与容器尺寸完全相同，**零裁切**。
       ⚠️ 与视频版（.rd-cloud-visual--video, 1918/1048）同理：
          容器比例必须与源图一致，否则 cover 必然裁切。
          后续若再换图，需同步更新此比例。 */
    aspect-ratio: 3 / 2;
    object-fit: cover;
    /* ---------- v43: 修复「图片未加载时露出黑带」 ----------
       现象：数据安全保障区块配图下方出现一条纯黑横带。
       根因：图片带 loading="lazy" + CSS 写死 aspect-ratio: 1.6/1，
             浏览器会**先**按该比例分配出一块 857×536 的占位框；
             若此时图片请求尚未完成（currentSrc 为空 / naturalWidth===0），
             这块占位框内没有任何内容，而父级 .rd-cloud-visual 是
             overflow:hidden + 半透明渐变，空框就被渲染成黑色。
       修复：① 给 img 自身补一层浅色兜底背景，空框时也显示浅色而非黑；
             ② 用 color/background-color 双保险，兼容 poster 缺失场景。
       注：这里刻意不用 #fff 纯白，而是取与容器渐变同色系的浅蓝，
           这样即使短暂可见也不会与周围白底形成突兀色差。
       v55 补充：容器底框已去掉，但 img 自身的兜底色**保留** ——
           它防的是「图片加载前空框」这个独立问题，与容器有没有框无关；
           且 238,243,255 在白底上几乎不可见，不会重新造出"框"。 */
    background-color: #eef3ff;
}

/* ---------- v41: 视频版配图（24小时云端运行区块） ----------
   与 <img> 版共用 .rd-cloud-visual 容器，只替换内部元素。

   ⚠️ v40 曾用「1.6:1 容器 + object-fit: cover」，导致视频左右各被裁掉约 6%
   （视频源 1918×1048 = 1.8302:1，容器 1.6:1，总裁切约 13%），
   左侧「批量控制操作」设备列表和右侧设备预览面板都被切掉。
   用户要求展示完整画面 → 改为：容器不再固定比例，直接跟随视频原始比例；
   同时 object-fit 用 contain 兜底，任何情况下都不裁切。 */
.rd-cloud-visual--video {
    /* v55: 去掉白色底（用户要求完全去框）。
       但**不能设成 transparent**：本文件 .rd-cloud-visual--video video
       的兜底背景是 --grad-brand-soft（浅蓝渐变），若去掉这层白，
       浅蓝就会从视频背后透出来 —— 视频加载前会看到一块浅蓝板，
       等于换了个颜色继续"有框"。页面本来就是白底，置白即可无缝。 */
    background: #fff;
}
.rd-cloud-visual--video video,
.rd-cloud-video {
    display: block;
    width: 100%;
    /* 视频原始比例 = 1918:1048 ≈ 1.8302:1。
       （v55 修正：此处旧注释写的是 1976/1080≈1.8296，与实际不符，
         实测 ffmpeg 读出容器为 1918x1048 / SAR 1:1 / DAR 959:524。
         用旧值算出的容器高比实际多 0.18px —— 视觉无影响，
         但注释与数值一并订正，避免后人据此推算时被误导。）
       用真实比例替代原先写死的 1.6:1，容器被完整撑满，不会产生任何裁切。
       注：这里用固定值而非 auto，是为了在视频元数据加载前就锁定版面高度，
       避免 CLS（布局偏移）；若后续替换视频，需同步更新此比例。 */
    aspect-ratio: 1918 / 1048;
    object-fit: contain;
    background: var(--grad-brand-soft);
}
/* 视频右下角的静音角标已按需求移除（v42）。
   静音能力本身不受影响 —— 仍由 <video muted> 属性保证，
   该属性是浏览器自动播放的硬前提，不能去掉，且不会渲染任何 UI。 */
/* v49: 此处原有的「略窄屏下改为单列」@media (max-width:640px) 规则已删除。
   原因：该规则与 .rd-check-grid 主定义下的同名媒体查询重复，
        且因写在更后面而覆盖后者的 gap 声明，属隐蔽的重复定义。
        窄屏单列逻辑已统一收敛到 .rd-check-grid 主定义下方（见文件前部）。 */

/* ---------- v39: 带图标的卖点网格（数据安全保障区块） ----------
   「24小时云端运行」是纯文字单行条目；「数据安全保障」每条含
   「图标 + 标题 + 描述」两行，需要额外一档样式。
   .rd-check-grid--rich 复用同一套栅格与间距，只改条目内部结构：
   把原本 ::before 的圆形蓝勾换成真实图标块。 */
.rd-check-grid--rich {
    max-width: 1040px;         /* 三条并排，比 4 条网格放宽 */
    /* ⚠️ 该变体固定 3 条卖点。若写成 2 列，第 3 条会独占第二行左侧、
       右侧留白，版面明显失衡 —— 故改为三列等宽并排。 */
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 24px 36px;
    align-items: start;
    margin-bottom: 44px;
}
/* 取消纯文字版的圆形蓝勾（该变体用独立 .ico 图标块） */
.rd-check-grid--rich li::before { display: none; }
.rd-check-grid--rich li { gap: 14px; }

.rd-check-grid--rich .ico {
    width: 44px;
    height: 44px;
    border-radius: var(--r-md);
    background: var(--grad-brand-soft);
    color: var(--c-brand);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}
.rd-check-grid--rich .ico svg { width: 22px; height: 22px; }

.rd-check-grid--rich .txt h4 {
    margin: 0 0 4px;
    font-size: var(--fs-lg);
    font-weight: 700;
    color: var(--c-text);
    line-height: 1.35;
}
.rd-check-grid--rich .txt p {
    margin: 0;
    font-size: var(--fs-sm);
    color: var(--c-text-2);
    line-height: 1.6;
}
/* ⚠️ 该媒体查询必须写在上方 .rd-check-grid--rich 的三列声明「之后」。
   同权重选择器由源码顺序决定胜负，若写在前面，390px 下仍是三列，
   每条仅分到 ~91px（实测），长文案会被挤成很多行。 */
@media (max-width: 640px) {
    .rd-check-grid--rich {
        grid-template-columns: 1fr;
        max-width: 420px;
        gap: 20px;
    }
}

/* ================= v56: 「数据安全保障」卖点贴合配图定位 =================
   需求：三条卖点不再横排居中，而是按用户标注的红框位置，
        贴合到配图中对应的图形旁 ——
          云端独立环境 → 左下方设备        数据加密存储 → 中央穹顶上方
          多重备份机制 → 右下方设备

   ── 几何基准（配图 img/feat-datasecure.webp，1536×1024）──
   实测内容边界：x 231..1359，y 100..891
     · 中央穹顶顶点 y≈100（画布高 9.77%），穹顶水平中心 x≈768（正好画布中线）
     · 左下设备中心 ≈(370, 700)   右下设备中心 ≈(1165, 690)
     · 左上台座区 y≈200..300       右上设备区 y≈200..330
   故「穹顶上方」标签取画布 y≈0~9% 这一条横带；
      左右两侧标签取画布 y≈42%~52%（与下排设备同一水平带）。

   ── 为什么用「容器 + 百分比绝对定位」而不是写死 px ──
   配图是 width:100% 的响应式元素，容器宽度随视口变化（实测 1152px @1470 视口）。
   若给标签写死 px 坐标，一旦容器变宽/变窄，标签就会和图形错位。
   用百分比定位 → 标签随容器等比移动，与图形的相对关系恒定。

   ── 与视觉中轴的关系 ──
   配图容器本身在 .rd-container 内居中（容器 1200，配图 1152，左右各 24）。
   穹顶顶点实测 x≈768 = 1536/2，即**配图正中**。
   故「数据加密存储」用 left:50% + translateX(-50%) 即落在配图视觉中轴上，
   与上方标题 h2 的中轴天然对齐，无需额外补偿。

   ── 为什么给标签加半透明白底 + 轻微模糊 ──
   标签压在插图上，插图的电路纹理/浅蓝底座会显著降低文字可读性。
   加一层高不透明度的白色圆角底 + backdrop-filter 模糊，
   既保证可读，又不完全遮断插图的连续感（去掉底会与电路纹理糊在一起）。 */

.rd-sec-stage {
    position: relative;
}

.rd-sec-anchor {
    list-style: none;
    padding: 0;
    margin: 0;
    /* 桌面端：整层脱离文档流、浮在配图上。
       pointer-events:none 让鼠标事件穿透到下层配图，
       避免标签区域变成"死区"（虽然配图本身无交互，但保持层语义干净）。 */
    position: absolute;
    inset: 0;
    pointer-events: none;
}
.rd-sec-anchor li {
    position: absolute;
    display: flex;
    align-items: flex-start;
    gap: 12px;
    max-width: 300px;
    padding: 12px 16px 12px 14px;
    border-radius: var(--r-md);
    background: rgba(255, 255, 255, 0.9);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    /* 极轻的投影：只用来把标签从复杂插图上"托"起来，不制造"卡片框"感
       （区块外框已在 v55 去掉，这里不能再引入明显边框） */
    box-shadow: 0 2px 12px rgba(15, 23, 42, 0.05);
}

/* ── 几何基准（配图 img/feat-datasecure.webp，1536×1024）实测 ──
   深色实体（设备本体）聚类中心（换算成画布百分比）：
     上排左设备  x≈24%, y≈35%      上排右设备  x≈79%, y≈36%
     下排左设备  x≈24.5%, y≈75.8%  下排右设备  x≈79.5%, y≈76.7%
     中央穹顶    顶点 y≈100px(9.8%)，穹顶尖端水平范围 x 648..923，中心 x≈51.1%
   注意：穹顶**尖端**中心在 51.1%（透视导致略偏右），
        但穹顶**整体**（含底座）的水平中心与画布中线一致，
        且上方标题 h2 也在画布中线 —— 故标签仍按 50% 居中，
        与标题同中轴优先于与尖端严格对齐（差 1.1% ≈ 13px，肉眼不可辨）。 */

/* 中央穹顶上方：水平居中于配图视觉中轴，压在穹顶顶点之上 */
.rd-sec-anchor--top {
    left: 50%;
    top: 1%;
    transform: translateX(-50%);
}
/* 左下方设备：贴在设备左上侧。
   设备实体中心 x≈24.5%（渲染宽 1152 → 约 282px）、y≈76%（约 583px）。
   标签取 left:2%(≈23px)、top:44%(≈338px)：
     · 水平：标签起排 23px，视觉上落在设备左侧上方，不压住设备本体；
     · 垂直：44%≈338px，位于设备主体（y 504..661px）之上、上排设备（y≈270px）之下，
       正好落在画面左侧中段的空档里，与用户标注红框位置一致。
   注：这里与下方两排设备都留有余量，避免标签盖住任何一个设备本体。 */
.rd-sec-anchor--left {
    left: 2%;
    top: 44%;
}
/* 右下方设备：与左侧镜像对称 */
.rd-sec-anchor--right {
    right: 2%;
    top: 44%;
}

/* 标签内的图标与文字（沿用 --rich 变体的视觉语言，尺寸按浮层略缩） */
.rd-sec-anchor .ico {
    width: 38px;
    height: 38px;
    border-radius: var(--r-md);
    background: var(--grad-brand-soft);
    color: var(--c-brand);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}
.rd-sec-anchor .ico svg { width: 20px; height: 20px; }
.rd-sec-anchor .txt h4 {
    margin: 0 0 3px;
    /* ⚠️ 字号用 --fs-base(16px)，本文件没有 --fs-md —— 写了未定义变量会静默失效、
       回落成继承值。所有变量名均已核对存在于 :root。 */
    font-size: var(--fs-base);
    font-weight: 700;
    color: var(--c-text);
    line-height: 1.3;
    white-space: nowrap;
}
.rd-sec-anchor .txt p {
    margin: 0;
    font-size: var(--fs-xs);
    color: var(--c-text-2);
    line-height: 1.5;
}

/* ---------- 窄屏回退：<1000px 恢复为「配图 + 下方横排卖点」 ----------
   ⚠️ 断点与 .rd-check-grid 的 1000px 保持一致（同一区块的两种形态切换点）。
   窄屏下配图等比缩小，绝对定位的标签会与图形重叠、文字被压成多行，
   故整体回退为文档流内的普通网格 —— 可读性优先于贴合感。
   实现方式：取消 stage 的相对定位与浮层，把 ul 还原成常规网格。 */
@media (max-width: 1000px) {
    .rd-sec-anchor {
        position: static;
        inset: auto;
        pointer-events: auto;
        display: grid;
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: 20px 28px;
        max-width: 1040px;
        margin: 32px auto 0;
    }
    .rd-sec-anchor li {
        position: static;
        transform: none;
        max-width: none;
        padding: 0;
        background: transparent;
        -webkit-backdrop-filter: none;
        backdrop-filter: none;
        box-shadow: none;
        gap: 14px;
    }
    .rd-sec-anchor .ico { width: 44px; height: 44px; }
    .rd-sec-anchor .ico svg { width: 22px; height: 22px; }
    .rd-sec-anchor .txt h4 {
        font-size: var(--fs-lg);
        white-space: normal;
    }
    .rd-sec-anchor .txt p { font-size: var(--fs-sm); }
}
@media (max-width: 640px) {
    .rd-sec-anchor {
        grid-template-columns: 1fr;
        max-width: 420px;
        gap: 18px;
    }
}

/* 数字 KPI 栏 */
.rd-kpis {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 24px;
    padding: 40px;
    background: var(--grad-brand);
    border-radius: var(--r-xl);
    color: #fff;
    box-shadow: var(--sh-glow);
}
.rd-kpi { text-align: center; }
.rd-kpi .num { font-size: 40px; font-weight: 800; line-height: 1.1; letter-spacing: -1px; }
.rd-kpi .label { font-size: var(--fs-sm); opacity: 0.85; margin-top: 8px; }

/* ---------- 5. 栅格 ---------- */
.rd-grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: 24px; }
.rd-grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }
.rd-grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px; }
.rd-grid-6 { display: grid; grid-template-columns: repeat(6, 1fr); gap: 20px; }

/* ---------- 6. 导航栏 ---------- */
.rd-nav {
    position: sticky;
    top: 0;
    z-index: 100;
    background: rgba(255, 255, 255, 0.9);
    backdrop-filter: saturate(180%) blur(18px);
    -webkit-backdrop-filter: saturate(180%) blur(18px);
    border-bottom: 1px solid var(--c-border-2);
}
.rd-nav-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 68px;
}
.rd-nav-logo {
    width: 250px;
    font-size: 20px;
    font-weight: 800;
    color: var(--c-brand);
    letter-spacing: 0.5px;
    display: flex;
    align-items: center;
    gap: 8px;
    white-space: nowrap;
}
.rd-nav-logo .rd-logo-mark {
    width: 30px; height: 30px;
    flex-shrink: 0;
    filter: drop-shadow(0 0 8px rgba(27, 92, 255, 0.45));
}
.rd-nav-logo img {
    height: 44px;
    width: auto;
    display: block;
    flex-shrink: 0;
}
.rd-nav-links {
    display: flex;
    align-items: center;
    gap: 32px;
    list-style: none;
    padding: 0; margin: 0;
}
.rd-nav-links a {
    color: var(--c-text-2);
    font-weight: 500;
    font-size: var(--fs-sm);
    transition: color var(--dur);
    position: relative;
}
.rd-nav-links a:hover { color: var(--c-brand); }
.rd-nav-links a.active { color: var(--c-brand); font-weight: 600; }
.rd-nav-links a.active::after {
    content: "";
    position: absolute;
    left: 50%; bottom: -24px;
    transform: translateX(-50%);
    width: 36px; height: 3px;
    border-radius: 2px;
    background: var(--grad-brand);
}
.rd-nav-cta { display: flex; gap: 10px; align-items: center; }

/* ---------- 7. Hero 首屏 ---------- */
.rd-hero {
    position: relative;
    padding: 110px 0 100px;
    background: var(--grad-hero);
    overflow: hidden;
}
/* v63: 首屏改为「整块背景图」——新图 img/hero-bg.webp 本身就是一张完整的
   首屏设计稿：左侧留大片淡蓝渐变空白（给真实文案排版），右侧画好
   「电脑界面 + 手机界面」组合视觉，右下角带浅蓝有机曲角色块。

   摆放方式（领导指定「100% 宽度顶部对齐」）：
     background-size: 100% auto   → 宽度撑满、高度等比自适应
     background-position: top center → 顶部对齐，下方多出的部分自然被裁
   这样图上「顶部渐变区」能完整保留，不会像 cover 那样被上下各裁 28%。

   底色 --grad-hero 必须保留：它是图下方（首屏高度 > 图高时）的过渡色，
   且图中透明区会透出它。图顶部是 #f0f6ff 系淡蓝，与 --grad-hero 的
   #f0f6ff 起色一致，接缝不可见。改图后必须同步升 ?v=
   （静态资源带 max-age immutable，改内容不升版本号不生效）。 */
.rd-hero.has-bg-image {
    background: url("../img/hero-bg.webp?v=2") top center / 100% auto no-repeat, var(--grad-hero);
    /* v66: 图顶部那圈「颜色不一致的部分」已裁掉。
       ---- 为什么要裁（实测数据）----
       原图 3840x2458，顶部第 0~51 行是「完全透明」的一条宽带（alpha 全为 0），
       第 52 行 alpha 单行跳变 0 -> 100，画布（淡蓝底）从这一行硬切开始。
       摆放到首屏后，这 52 行透明区透出的是 --grad-hero 的 #f0f6ff，
       而画布本身是 rgb(210,220,244) 左右的蓝，两者明度差 12~14 级 ——
       于是在页面 y≈88.8 处出现一条肉眼可见的横向接缝（领导截图圈出的就是这条）。
       另注：图底部是真渐变淡出（alpha 从 95 平滑衰减到 0），无接缝，不需要处理。
       故直接裁掉顶部 52 行，让画布顶边成为图片顶边，接缝从根上消失。

       ---- 裁剪后的数值 ----
       3840x2406（原 2458 高裁掉 52 行，占 2.12%），比例 2406/3840 = 0.62656。
       min-height 系数随之从 64.01vw 改为 62.66vw（= 图的渲染高，完整不裁）。
       裁掉 52 行后图变矮约 13px（1462 容器下），clamp 上下限维持原值即可。

       ---- 原 v63 的说明（保留备查）----
       新图 3840x2458（比例 1.5622）。按 100% auto 铺开，图渲染高 = 容器宽 * 0.64010。
       若首屏高度沿用固定 padding（原来固定约 677px），宽屏下图会被压得很矮：
         视口宽 1462 → 图渲染高 936，而首屏仅 677 → 底部 27.7% 被裁
       被裁的正好是图右下的「手机界面」区块 —— 观感是手机界面被 KPI 数据栏切掉一半。
       所以这里令 min-height 随视口宽线性增长，保证图能完整（或接近完整）展示。
       但 64vw 在超宽屏会过大（2560px 视口 → 1638px 高，一屏看不到 KPI），
       故用 clamp 夹在 660px ~ 1080px：
         660px  下限 = 原固定高度量级，保证窄屏首屏仍是个正常高度
         1080px 上限 = 约等于 1440x900 笔记本的一屏余量
       同时 padding 归零（min-height 已接管高度），避免 padding + min-height 双重叠加。 */
    min-height: clamp(660px, 62.66vw, 1080px);
    padding-top: 0;
    padding-bottom: 0;
    display: flex;
    align-items: center;
}
/* v63: 右栏视觉组合已整体移除（HTML 与旧图文件在 v63 一并删除），
   但保留 .rd-hero-inner 的两列 grid 结构 —— 左列用来约束文案宽度。

   ---- 为什么是 36% 而不是原来的 47.7% ----
   实测新图逐列饱和度分布（每 2.5% 采样，定位「界面视觉」的起点）：
     x   0%..37.5%  饱和度 0.140  ← 纯渐变空白，可放文字
     x  37.5%..50%  饱和度 0.142→0.210  ← 开始出现内容
     x  50%..100%   饱和度 0.21→0.32    ← 界面视觉主体
   即图的「安全空白区」到 37.5% 为止。
   原两列 grid 下左栏实测占容器宽 47.7%（697px / 1462px），
   已越过 37.5% 这条线，文字右缘会压到图上开始出现内容的区域。
   故 hero-bg-mode 下把左列压到 36%（留 1.5% 安全余量）。 */
.rd-hero.hero-bg-mode .rd-hero-inner {
    grid-template-columns: minmax(0, 36%) minmax(0, 1fr);
}
.rd-hero.hero-bg-mode .rd-hero-visual-col {
    visibility: hidden;
    height: 0;
    min-height: 0;
    overflow: hidden;
}
.rd-hero::before {
    content: "";
    position: absolute;
    inset: 0;
    background:
        radial-gradient(circle 620px at 90% -10%, rgba(27, 92, 255, 0.14), transparent 70%),
        radial-gradient(circle 520px at 5% 120%, rgba(0, 184, 255, 0.12), transparent 70%);
    pointer-events: none;
}
.rd-hero-inner {
    position: relative;
    z-index: 1;
    display: grid;
    /* v32: 右列加宽，让首屏图放大后与左侧内容上下齐平 */
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.273fr);
    gap: 52px;
    align-items: center;
    /* 覆盖 .rd-container 的 1200px，为放大的首屏图让出空间 */
    max-width: 1344px;
}
.rd-hero-text-col { position: relative; z-index: 2; }
/* v64: 左栏文案块整体上移，使其底边与右侧配图的实际内容底边齐平。
   ---- 为什么需要 ----
   背景图 hero-bg.webp 上画好的「电脑界面 + 手机界面」组合，其绘制内容
   在图上止于内部 y≈581px（页面 y=650）；而左栏文案块底边（.rd-download
   的 1px 边框盒）在页面 y=741。两者相差 91px，视觉上右侧配图「浮」在
   文案块上方，底部不齐。
   ---- 数值怎么来的（实测）----
   .rd-hero 是 display:flex; align-items:center，.rd-hero-inner 在首屏里垂直居中。
   给左栏加 margin-bottom，flex 会把「内容 + 外边距」这个更大的盒子重新居中 ——
   多出的下外边距有一半会把内容顶上去，即 **位移 = margin-bottom / 2**。
   这个 1/2 系数是实测拟合出来的，不是推算的（1470px 视口，逐值实测）：
     mb=  0 -> .rd-download 底边 731
     mb=182 -> 640
     mb=238 -> 612
     mb=290 -> 586
     mb=346 -> 558     逐段斜率恒为 -0.5

   注意：上面这组早期数据是在**还没给 .rd-download 加 margin-bottom:32px**
   的状态下测的。后来 .rd-download 带了 32px 下外边距，而 getBoundingClientRect()
   量的是**边框盒**（不含外边距），flex 又是把「边框盒 + 32px 外边距」一起居中，
   等于常量整体下移 32/2 = 16px。所以现在的关系是：
     dlBottom = 731 - mb/2 + 18      （+18 = 32/2 的常量偏移，与 mb 无关）
   实测复核（裁剪后、真实样式下逐值实测，斜率仍恒为 -0.5）：
     mb=202 -> 648    mb=220 -> 639    mb=238 -> 630
     mb=256 -> 621    mb=274 -> 612    mb=292 -> 603

   ---- v67 修正：238px（原 v66 的 202px）----
   图顶部裁掉 52 行后（见上面 .rd-hero.has-bg-image 的 v66 说明），
   background-position:top center 把「新图第一行」贴到首屏顶部，
   于是配图整体上移 52 image px = 19.8 CSS px，
   配图内容底边从页面 y=650 变为 y=630。
   代入本次复核出的式子：731 - mb/2 + 18 = 630  ->  mb = 238。
   实测确认：mb=238 -> .rd-download 底边 630.0，红线正压在配图内容底边上。

   （踩坑记录：v66 曾按 731 - mb/2 = 630 反推出 202px，漏算了 .rd-download
   那 32px 下外边距带来的 +18 常量项，结果实际落在 648，比配图底边低 18px。
   症状是「红线只在左侧文案卡片上，右侧配图下面还露着一截」。
   教训：flex 居中的容器里，凡子元素自身带外边距，量出来的边框盒位置
   一定含一个「外边距的一半」的常量偏移，不能拿裸值直接反推。）

   ---- v73 修正：227px（原 v67 的 238px）—— 改为「居中于配图」----
   领导要求「文案向下移动，和图片保持一样的高度」。
   实测：文案块 467px 高（177~644），配图 420px 高（206~626）——
   **文案比配图高 47px，做不到严格等高**。
   故采用垂直居中对齐（向领导确认后选定）：
     配图中心 (206+626)/2 = 416.0      文案中心 (177+644)/2 = 410.5
     需下移 5.5px
   在 flex align-items:center 下，**减少** margin-bottom 会让内容**下移**（减少量的一半）：
     Δmb = -2 × 5.5 = -11   =>   238 - 11 = 227px
   实测确认：mb=227 -> 文案中心 415.5 ≈ 配图中心 416，上下各溢出约 23px。

   注：这条规则与上面的 .rd-download 底边对齐（v67）是**两套不同诉求**——
   v67 追求「文案底边＝配图底边」，v73 改为「文案整体居中于配图」。
   后者让文案下移，视觉重心更稳，也不会出现「文案比配图高出一截」的悬浮感。

   ---- 为什么用 margin 而不是 transform ----
   transform 虽能得到同样的位移，但它不参与 flex 布局计算，后续若调整首屏
   min-height 或左栏内容高度，位移量不会跟着自适应；margin 是真实布局尺寸，
   与 align-items:center 协同，改动更稳。
   ---- 为什么只写在桌面端 ----
   ≤1100px 断点下 .rd-hero.has-bg-image 退化为纯渐变背景、display:block，
   背景图不再渲染，没有「右侧配图底边」这个对齐基准，故该处需归零。 */
.rd-hero.has-bg-image .rd-hero-text-col {
    margin-bottom: 227px;
}
/* ---------- v70 起：首屏浮动徽标（恢复） ----------
   ---- 定位坐标怎么定的（实测，不是估）----
   容器 .rd-hero-badges 铺满 .rd-hero-inner（position:relative 由 .rd-hero-inner 提供），
   徽标按百分比落在背景图「右侧配图」的四个角 / 侧栏两端。
   注：inner 的实测高度随内容微调（694~705），下面公式里的 y 基准以当次实量为准。

   **百分比基准是 .rd-hero-inner（1344px 内容宽 / 705px 高），不是背景图本身** —— 这点极易搞错。
   背景图以 background-size:100% auto 贴在 .rd-hero（满宽 1462）上，
   而 .rd-hero-inner 是 1344 居中，两者宽度不同，换算必须按 inner。

   ---- 配图的实测边界（1470px 视口，全页截图逐像素扫描）----
   判据：右侧 x 760~1400 区间内，统计「深色像素 / 高饱和彩色 / 纯白卡」的行密度。
   结果非常锐利 —— 内容起于页面 y=206，止于 y=626（y=628 起计数直接归 0）。
   另用「配图左侧那条连续深色竖栏」（max(r,g,b)<130 且通道差<60，纵向连续 224px）
   交叉验证：竖栏在 css x 739~758 / y 402~627，与上面一致。
   换算到 .rd-hero-inner（x 59~1403 / y 177~882，高 705）：
     配图  left 50.6%   top 4.1%   bottom 36.3%（右边缘已超出 inner，约到视口右 1468）

   **为什么不用 alpha 阈值量**：整张背景图都是半透明的（alpha 71~192），
   配图区只是 alpha 偏高；用 alpha>=150 框出来是 50.5%~85.9%，明显偏小，
   与肉眼看到的配图范围对不上。行密度法才稳定。

   ---- 最终四个坐标 ----
   配图四角 = (left 50.6%, top 4.1%) 到 (right 越界, bottom 36.3%)
   徽标高约 49px，让它「骑」在配图边缘上（中线压边）而非完全飘在外面：
     tl  right 48.74%  top 28%     —— 骑在配图左侧竖栏的**顶端**
     tr  right 3%      top 4%      —— 压配图右上角
     bl  right 48.74%  bottom 32.35% —— 骑在配图左侧竖栏的**底端**
     br  right 3%      bottom 32%  —— 压配图右下角
   **bottom 这个值踩过坑**：最初写 16% 是按「配图纵向只到 inner 的 11.6% 处」估的，
   结果徽标落到了页面 y=721~769 —— 那是**下一个 section 里**（配图底边只到 626）。
   正确值是 32%（= (882-654)/705，654 为徽标底边目标位置）。

   ---- v81 定稿：左侧两枚骑到「配图侧栏」的上下两端 ----
   领导在原图上画了两个红框 + 箭头，明确要左侧两枚**贴到配图那条深色竖栏上**。
   竖栏实测（截图 2× 缩放，颜色掩码 `max<120 且通道差<60` 求最长连续纵向 run）：
     css x 738~758（宽 20px），css y 402~628（高 226px）
   换算到 .rd-hero-inner（x 59~1403 / 宽 1344，y 183~877 / 高 694）：
     右边缘压住竖栏左缘 10px → 徽标 right_css = 748
         tl/bl 的 right% = (1403-748)/1344 = 48.74%
     纵向让「徽标中心」压在竖栏的端点上（tl 压顶 y402，bl 压底 y628）：
         tl  top%    = (402-49/2-183)/694 = 28.03%  → 取 28%
         bl  bottom% = (877-(628+49/2))/694 = 32.35%
   两个徽标中心距 = 628-402 = 226px，**恰好等于竖栏高度** —— 视觉上就是竖栏的两端。
   宽度用 `right` 锚而非 `left`：徽标宽度随字号/字体渲染变化，
   `left` 锚会让右边缘浮动、与竖栏的相对关系失控；`right` 锚把「压边那侧」钉死。
   （右侧两枚同理用 right 锚，四枚策略统一。）

   ---- 为什么用百分比而不是 px ----
   背景图随视口等比缩放（background-size:100% auto），配图四角位置跟着变；
   写死 px 在 1440 视口调好、到 1920 就全跑偏。百分比随容器等比，天然跟得住。

   ---- 溢出处理 ----
   .rd-hero 有 overflow:hidden，徽标略微超出 inner 也只在首屏内被裁，
   不会撑出横向滚动条。

   ---- v79 修正：左侧两枚原本把配图侧栏盖住了 ----
   上面 left 46% 是「按 inner 宽度算的百分比」，但配图左侧那条深色竖栏实测在
   **css x 738~758**（inner 为 x 59~1403 / 宽 1344），换算成 inner 内百分比是
   (738-59)/1344 = **50.5%**。而 46% → x 677~783，横跨 738 —— 相当于把竖栏
   切掉一半盖住，左侧两枚白底胶囊骑在深色竖栏上，视觉上「压坏」了配图。
   右侧两枚用的是 right:3%，落在配图右边缘之外，没问题；左右不对称才是根因。
   修正：左侧两枚改用 right 定位，锚在配图左边缘往外挪，
     tl  right 54.5%（= 100% - 45.5%，落在 x 605~711，与竖栏 738 留 27px 间隙）
     bl  right 54.5%（同上）
   这样四枚的状态就和原设计一致：左侧两枚飘在配图左侧留白里，右侧两枚飘在右侧留白里。
   （若日后视口改为百分比基准变化，需重新按上面公式标定。） */
.rd-hero-badges {
    position: absolute;
    inset: 0;
    pointer-events: none;   /* 纯装饰，别挡住下面下载按钮的点击 */
    z-index: 3;
}
.rd-hero-float-badge {
    position: absolute;
    padding: 10px 20px;
    border-radius: var(--r-pill);
    font-size: var(--fs-base);
    font-weight: 700;
    color: var(--c-brand);
    background: rgba(255, 255, 255, 0.94);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    border: 1px solid rgba(27, 92, 255, 0.12);
    box-shadow: 0 10px 28px rgba(27, 92, 255, 0.14);
    white-space: nowrap;
}
.rd-hero-float-badge.accent {
    color: #fff;
    background: linear-gradient(135deg, #ff9f43 0%, #ffcd56 100%);
    border-color: rgba(255, 159, 67, 0.25);
    box-shadow: 0 10px 28px rgba(255, 159, 67, 0.22);
}
.rd-hero-float-badge.badge-tl { top: 28%; right: 48.74%; }
.rd-hero-float-badge.badge-tr { top: 4%; right: 3%; }
.rd-hero-float-badge.badge-bl { bottom: 32.35%; right: 48.74%; }
.rd-hero-float-badge.badge-br { bottom: 32%; right: 3%; }
.rd-hero-visual-col {
    position: relative;
    /* v32: 去掉 min-height 硬撑，改由图片自身等比撑开，高度自然与左列对齐 */
    display: flex;
    align-items: center;
    justify-content: center;
}
.rd-hero-subtitle {
    font-size: 26px;
    font-weight: 700;
    color: var(--c-text);
    margin: 0 0 14px;
    line-height: 1.3;
    letter-spacing: -0.3px;
}
.rd-hero-subtitle span { color: var(--c-brand); }
.rd-hero .tag-row { margin-bottom: 20px; display: flex; gap: 10px; flex-wrap: wrap; }
.rd-hero h1 {
    font-size: 60px;
    line-height: 1.08;
    font-weight: 900;
    margin: 0 0 22px;
    letter-spacing: -1.5px;
}
.rd-hero h1 .em { background: var(--grad-brand); -webkit-background-clip: text; background-clip: text; color: transparent; }
.rd-hero h1 .br { display: block; }
.rd-hero .sub {
    font-size: var(--fs-lg);
    color: var(--c-text-2);
    line-height: 1.85;
    margin: 0 0 34px;
    max-width: 560px;
}
.rd-hero .cta-row { display: flex; gap: 14px; flex-wrap: wrap; margin-bottom: 44px; }
/* removed: .rd-mini-stats (dead code) */

/* v17: Hero 首屏入场动画 — 错落淡入上移 */
@keyframes rd-hero-enter {
    from { opacity: 0; transform: translateY(18px); }
    to   { opacity: 1; transform: translateY(0); }
}
.rd-hero-text-col > * {
    animation: rd-hero-enter 0.7s var(--ease) both;
}
.rd-hero-text-col > *:nth-child(1) { animation-delay: 0s; }
.rd-hero-text-col > *:nth-child(2) { animation-delay: 0.08s; }
.rd-hero-text-col > *:nth-child(3) { animation-delay: 0.16s; }
.rd-hero-text-col > *:nth-child(4) { animation-delay: 0.24s; }
.rd-hero-text-col > *:nth-child(5) { animation-delay: 0.32s; }
@media (prefers-reduced-motion: reduce) {
    .rd-hero-text-col > * { animation: none; }
}

/* Hero 右：下载面板 */
.rd-download {
    background: #fff;
    border: 1px solid var(--c-border);
    border-radius: var(--r-xl);
    padding: 22px 24px 24px;
    box-shadow: var(--sh-md);
    position: relative;
    margin: 0 0 32px;
}
.rd-download::before {
    content: "";
    position: absolute;
    inset: -1px;
    border-radius: var(--r-xl);
    padding: 1px;
    background: var(--grad-brand);
    -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
    opacity: 0.45;
    pointer-events: none;
}
.rd-download h3 {
    margin: 0 0 4px;
    font-size: var(--fs-xl);
    font-weight: 800;
}
.rd-download .desc {
    font-size: var(--fs-sm);
    color: var(--c-text-3);
    margin-bottom: 22px;
}
.rd-download-list {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 14px;
}
.rd-download-item {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 18px 12px 16px;
    border: 1px solid var(--c-border);
    border-radius: var(--r-lg);
    background: #fff;
    overflow: hidden;
    isolation: isolate;
    min-width: 0;
    text-align: center;
    transition: transform .28s cubic-bezier(.16,1,.3,1),
                box-shadow .28s cubic-bezier(.16,1,.3,1),
                border-color .28s ease;
}
/* 方向性填充：从左侧滑入 */
.rd-download-item::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background: linear-gradient(110deg, rgba(27,92,255,.09) 0%, rgba(0,184,255,.04) 100%);
    transform: translateX(-101%);
    transition: transform .42s cubic-bezier(.16,1,.3,1);
}
/* 顶部强调线：从左向右生长 */
.rd-download-item::after {
    content: "";
    position: absolute;
    left: 16px;
    right: 16px;
    top: 0;
    height: 2px;
    border-radius: 0 0 2px 2px;
    background: var(--grad-brand);
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform .36s cubic-bezier(.16,1,.3,1);
}
.rd-download-item:hover {
    border-color: rgba(27,92,255,.35);
    transform: translateY(-3px);
    box-shadow: 0 14px 30px -8px rgba(27,92,255,.20), 0 4px 10px rgba(15,23,42,.04);
}
.rd-download-item:hover::before { transform: translateX(0); }
.rd-download-item:hover::after { transform: scaleX(1); }
.rd-download-item:active { transform: translateY(-1px) scale(.985); }
.rd-download-item:focus-visible {
    outline: 2px solid var(--c-brand);
    outline-offset: 2px;
}
.rd-download-item .ico {
    width: 46px; height: 46px; border-radius: 14px;
    background: var(--grad-brand-soft);
    color: var(--c-brand);
    display: flex; align-items: center; justify-content: center;
    flex-shrink: 0;
    box-shadow: inset 0 1px 0 rgba(255,255,255,.5);
    transition: transform .3s cubic-bezier(.16,1,.3,1);
}
.rd-download-item:hover .ico { transform: scale(1.08) rotate(-3deg); }
.rd-download-item .ico svg { width: 24px; height: 24px; }
.rd-download-item .t { display: flex; flex-direction: column; min-width: 0; }
.rd-download-item .t strong {
    font-size: 14px; font-weight: 700; color: var(--c-text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.rd-download-item .t span {
    font-size: 11px; color: var(--c-text-4); margin-top: 2px; letter-spacing: .01em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* 二维码角标 */
.rd-download-item .qr-corner {
    position: absolute;
    top: 0;
    right: 0;
    width: 26px;
    height: 26px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: rgba(27,92,255,.55);
    background: linear-gradient(135deg, transparent 50%, rgba(27,92,255,.08) 50%);
    border-bottom-left-radius: var(--r-md);
    z-index: 2;
    pointer-events: none;
}
.rd-download-item .qr-corner svg { width: 14px; height: 14px; }
/* 二维码覆盖层 */
.rd-download-item .qr-layer {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    background: #fff;
    /* v1.4.10：覆盖层自己负责裁切。
       原先改用 img/canvas 上的 max-width/max-height 防溢出，结果把二维码
       压成非方形（见下方 .qr-code img 注释）。改为在这里 overflow: hidden，
       既保证不溢出，又让二维码保持 64×64 正方形。 */
    overflow: hidden;
    opacity: 0;
    visibility: hidden;
    transform: translateY(8px);
    transition: opacity .28s ease, transform .28s cubic-bezier(.16,1,.3,1), visibility .28s;
    z-index: 3;
}
.rd-download-item.has-qr:hover .qr-layer,
.rd-download-item.has-qr:focus-visible .qr-layer {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}
/* v1.4.8 修复：二维码原来被强制成 96px，**比它所在的覆盖层（92px）还宽**，
   于是溢出铺满整张卡片、视觉上顶到边缘。现缩小到 64px 并留出内边距。
   ⚠️ 这里的尺寸必须与 js/site-config.js 里 new QRCode({ width, height }) 保持一致，
      否则 canvas 会先按 64 绘制、再被拉伸到另一尺寸 → 码点发虚、扫码识别率下降。
      两处要改一起改。
   另：qrcodejs 会同时产出 canvas + img（img 走 data:image/png，用于兼容老浏览器），
   两者都要约束，否则漏一个就会被旧样式顶到 96px。 */
.rd-download-item .qr-layer .qr-code img,
.rd-download-item .qr-layer .qr-code canvas {
    display: block;
    /* v1.4.10 修复（重要）：原来这里同时写了
         width/height: 64px !important   和
         max-width: calc(100% - 20px) / max-height: calc(100% - 34px)
       两条**互相打架**的约束。CSS 里 max-* 的优先级**高于** width/height，
       所以 !important 也救不了：父级 .qr-code 只有 64×64，
       百分数结算出来就是 max-width=44px / max-height=30px，
       于是二维码被压成 **44×30 的非方形**（宽高比 1.47，真码是 1:1）。
       而 object-fit: contain 只在**画框内**等比留白，画框本身仍是 44×30，
       所以既没变形到肉眼可辨、又白占了 padding，实际码面只有约 44×30。
       二维码靠正方形模块阵列解码，非方形 + 有效尺寸偏小会直接拉低识别率。
       复现证据（CDP 实测）：解除 max-* 约束后立刻回到 64×64，加回即 44×30。

       正确做法：**尺寸只由 width/height 一处决定**，去掉多余且更高的 max-*。
       防溢出交给父级 .qr-layer 的 overflow: hidden（覆盖层本就该裁切）。 */
    width: 64px !important;
    height: 64px !important;
    /* object-fit：qrcodejs 的兜底 img 不带 width/height 属性，
       容易被全局 `img { max-width: 100% }` 影响。
       强制 contain 保证任何情况下二维码都等比、不变形。 */
    object-fit: contain;
    border-radius: var(--r-sm);
}
/* .qr-code 只是居中容器：去掉行内元素基线间隙，并让上下留白均匀。
   v1.4.10：显式声明 64×64 方块（与 img/canvas 尺寸及 js/site-config.js 的
   new QRCode({width,height}) 三处保持一致），保证二维码容器本身是正方形，
   不再依赖内容撑开。 */
.rd-download-item .qr-layer .qr-code {
    display: block;
    width: 64px;
    height: 64px;
    line-height: 0;
}
.rd-download-item .qr-tip {
    font-size: 12px;
    font-weight: 600;
    color: var(--c-brand);
}

/* 下载按钮：降低动效偏好 */
@media (prefers-reduced-motion: reduce) {
    .rd-download-item,
    .rd-download-item::before,
    .rd-download-item::after,
    .rd-download-item .ico,
    .rd-download-item .qr-layer {
        transition: none;
        transform: none;
    }
    .rd-download-item:hover { transform: none; }
    .rd-download-item:hover .ico { transform: none; }
    .rd-download-item.has-qr:hover .qr-layer,
    .rd-download-item.has-qr:focus-visible .qr-layer {
        transform: none;
    }
}

/* ---------- 9. 定价 / 下载 CTA 大段 ---------- */
.rd-cta-band {
    background: var(--grad-brand);
    color: #fff;
    padding: 80px 0;
    position: relative;
    overflow: hidden;
    border-radius: var(--r-xl);
    text-align: center;
}
.rd-cta-band::before {
    content: "";
    position: absolute;
    inset: 0;
    background:
        radial-gradient(circle 400px at 15% 0%, rgba(255, 255, 255, 0.22), transparent 70%),
        radial-gradient(circle 300px at 100% 120%, rgba(0, 0, 0, 0.2), transparent 70%);
    pointer-events: none;
}
.rd-cta-band > * { position: relative; z-index: 1; }
.rd-cta-band h2 { font-size: 40px; font-weight: 800; margin: 0 0 14px; letter-spacing: -0.5px; }
.rd-cta-band p { font-size: var(--fs-lg); opacity: 0.92; margin: 0 auto 30px; max-width: 600px; line-height: 1.7; }
.rd-cta-band .row { display: flex; gap: 14px; justify-content: center; flex-wrap: wrap; }
.rd-cta-band .rd-btn-primary { background: #fff; color: var(--c-brand); box-shadow: 0 6px 18px rgba(0,0,0,0.2); }
.rd-cta-band .rd-btn-primary:hover { box-shadow: 0 10px 26px rgba(0,0,0,0.25); transform: translateY(-2px); }
.rd-cta-band .rd-btn-outline { background: transparent; color: #fff; border-color: rgba(255,255,255,0.6); }
.rd-cta-band .rd-btn-outline:hover { background: rgba(255,255,255,0.12); border-color: #fff; }

/* ---------- 10. 页脚 ---------- */
.rd-footer {
    background: var(--c-bg-mid);
    color: var(--c-text-2);
    padding: 64px 0 24px;
    margin-top: 48px;
}
.rd-footer-grid {
    display: grid;
    /* v51: 页脚栏目由 4 列减为 2 列（按需求移除「资讯中心」「使用手册」两栏）。
       改为 1.4fr 1fr：品牌介绍占左侧较宽的一列，联系我们紧随其后靠右；
       不用 1fr 1fr，否则两列被平均拉开、联系信息会飘到最右侧显得孤立。 */
    grid-template-columns: 1.4fr 1fr;
    gap: 48px;
    padding-bottom: 48px;
    border-bottom: 1px solid var(--c-border);
}
.rd-footer .brand { color: var(--c-text); font-size: 22px; font-weight: 800; margin-bottom: 14px; }
.rd-footer .brand img { height: 52px; width: auto; display: block; }
.rd-footer .desc { font-size: var(--fs-sm); line-height: 1.85; color: var(--c-text-3); margin: 0 0 20px; max-width: 340px; }
.rd-footer h4 { color: var(--c-text); font-size: 15px; margin: 0 0 18px; font-weight: 700; }
.rd-footer ul { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 12px; }
.rd-footer li { font-size: var(--fs-sm); color: var(--c-text-3); }
.rd-footer a:hover { color: var(--c-brand); }
.rd-foot-bottom {
    display: flex; justify-content: space-between; align-items: center;
    padding-top: 22px;
    font-size: 12px;
    color: var(--c-text-4);
    flex-wrap: wrap;
    gap: 10px;
}

/* ---------- 11. 响应式 ---------- */
@media (max-width: 992px) {
    :root { --fs-3xl: 32px; --fs-4xl: 42px; }
    .rd-hero { padding: 80px 0 70px; }
    .rd-download-list { grid-template-columns: 1fr 1fr; }
    .rd-hero h1 { font-size: 44px; }
    .rd-split { grid-template-columns: 1fr; gap: 32px; padding: 32px 0; }
    .rd-split.reverse .rd-split-text { order: 0; }
    .rd-grid-6 { grid-template-columns: repeat(3, 1fr); }
    .rd-grid-4 { grid-template-columns: repeat(2, 1fr); }
    .rd-grid-3 { grid-template-columns: repeat(2, 1fr); }
    .rd-kpis { grid-template-columns: repeat(2, 1fr); padding: 28px; gap: 20px; }
    .rd-kpi .num { font-size: 32px; }
    .rd-footer-grid { grid-template-columns: 1.2fr 1fr; gap: 32px; }
    /* removed: .rd-nav-links { display: none } — 由 v16 汉堡菜单机制接管（rd-nav-open） */
    .rd-cta-band h2 { font-size: 30px; }
    .rd-section { padding: 72px 0; }
}
@media (max-width: 600px) {
    .rd-container { padding: 0 18px; }
    .rd-hero h1 { font-size: 36px; }
    .rd-hero .sub { font-size: 15px; }
    .rd-grid-6, .rd-grid-4, .rd-grid-3, .rd-grid-2 { grid-template-columns: 1fr; }
    .rd-kpis { grid-template-columns: 1fr 1fr; }
    .rd-footer-grid { grid-template-columns: 1fr; gap: 28px; }
    .rd-download-list { grid-template-columns: 1fr; }
    .rd-head h2 { font-size: 26px; }
    .rd-split h3 { font-size: 24px; }
    .rd-cta-band h2 { font-size: 24px; }
}

/* ---------- 14. (removed: vis-* dead code) ---------- */

/* ---------- 15. 子页面通用样式 ---------- */
/* v77: 页头上下两处空白压缩（领导截图圈出的两个红框）。
   ---- 改前实测（1470px 视口，list-zixun.html）----
     导航底 69 → 面包屑顶 169   = **100px 空白**  ← 截图红框①
     副标题底 299 → 搜索栏顶 465 = **166px 空白**  ← 截图红框②
   ② 那 166px 是两段 padding 叠加出来的：
     .rd-sub-banner 的 padding-bottom 70px
   + .rd-sub-wrap   的 padding-top    96px
   = 166px。

   ---- 改法 ----
   ① 导航→面包屑：padding-top 100px → 44px（省 56px）
   ② 副标题→搜索栏：banner padding-bottom 70px → 36px、
      .rd-sub-wrap padding-top 96px → 48px
      （166 → 84px，省 82px）
   两处都按「约压掉一半」处理，保留必要的呼吸感 ——
   H1 字号 44px、副标题 1.7 行高，再压就会顶到导航或挤成一坨。

   ---- 为什么改这两处而不是删 padding ----
   面包屑上方需要一点留白把页头标题与导航分开，全删会显得「贴」在一起；
   副标题下方同理，留 84px 让标题组与功能栏（搜索框）层次分明。
   ---- 窄屏 ----
   ≤992px 断点里另有 padding: 80px 0 56px（第 1720 行），同步按比例收为 36px 0 28px；
   ≤600px 再收一档。三档都改，避免只改桌面端导致窄屏仍是老间距。 */
.rd-sub-banner {
    position: relative;
    padding: 44px 0 36px;
    background: var(--grad-hero);
    overflow: hidden;
    text-align: center;
}
.rd-sub-banner::before {
    content: "";
    position: absolute;
    inset: 0;
    background:
        radial-gradient(circle 520px at 15% -10%, rgba(27, 92, 255, 0.16), transparent 70%),
        radial-gradient(circle 480px at 90% 120%, rgba(0, 184, 255, 0.14), transparent 70%);
    pointer-events: none;
}
.rd-sub-banner > * { position: relative; z-index: 1; }
.rd-sub-banner .crumb {
    font-size: var(--fs-sm);
    color: var(--c-text-3);
    margin-bottom: 14px;
}
.rd-sub-banner .crumb a { color: var(--c-brand); }
.rd-sub-banner .crumb span { margin: 0 8px; opacity: 0.5; }
.rd-sub-banner h1 {
    font-size: 44px;
    font-weight: 800;
    margin: 0 0 10px;
    letter-spacing: -0.5px;
    line-height: 1.2;
}
.rd-sub-banner h1 .em {
    background: var(--grad-brand);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}
.rd-sub-banner p {
    font-size: var(--fs-lg);
    color: var(--c-text-2);
    max-width: 640px;
    margin: 0 auto;
    line-height: 1.7;
}
/* 子页内容区 */
/* v77: padding-top 由 --sp-2xl（96px）收为 48px。
   它与 .rd-sub-banner 的 padding-bottom 共同构成「副标题→搜索栏」那段空白，
   详见上面 .rd-sub-banner 的 v77 说明。
   padding-bottom 保持 --sp-2xl 不动 —— 那是内容区与页脚之间的距离，
   领导本次只圈了页头上方两处，页脚间距不在本次范围内。 */
.rd-sub-wrap {
    padding: 48px 0 var(--sp-2xl);
}
/* v79: 文章详情页专用加宽容器。
   .rd-sub-wrap 同时挂着 .rd-container，被 max-width:1200px 卡住，
   正文再宽也超不过 1200-48=1152。这里只对文章页把版心放到 1488px，
   正文实测右边界从 1103 推到 1279（正文宽 744 → 1152），左右留白从 359/367 收到 131/139。
   注意：只有 article.html 会拿到 .rd-article-wrap，其余 15 个子页面的版心 1200px 完全不受影响。 */
.rd-article-wrap {
    max-width: 1488px;
}
/* 子页 Tabs */
.rd-sub-tabs {
    display: flex;
    justify-content: center;
    gap: 8px;
    flex-wrap: wrap;
    margin-bottom: 40px;
    padding: 6px;
    background: var(--c-bg-soft);
    border-radius: var(--r-pill);
}
.rd-sub-tab {
    padding: 10px 24px;
    border-radius: var(--r-pill);
    font-size: var(--fs-sm);
    font-weight: 600;
    color: var(--c-text-2);
    cursor: pointer;
    transition: all var(--dur) var(--ease);
    text-decoration: none;
    display: inline-block;
}
.rd-sub-tab:hover { color: var(--c-brand); }
.rd-sub-tab.on {
    background: #fff;
    color: var(--c-brand);
    box-shadow: var(--sh-sm);
}
/* 文章/公告列表卡片 */
.rd-sub-list {
    display: flex;
    flex-direction: column;
    gap: 16px;
}
.rd-sub-item {
    display: grid;
    grid-template-columns: 180px 1fr auto;
    gap: 28px;
    align-items: center;
    background: #fff;
    border: 1px solid var(--c-border);
    border-left: 3px solid transparent;
    border-radius: var(--r-lg);
    padding: 24px;
    transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
    cursor: pointer;
}
.rd-sub-item:hover {
    box-shadow: var(--sh-md);
    border-color: rgba(27, 92, 255, 0.25);
    border-left-color: var(--c-brand);
}
.rd-sub-item .cover {
    width: 180px;
    height: 120px;
    border-radius: var(--r-md);
    background: var(--grad-brand-soft);
    overflow: hidden;
    flex-shrink: 0;
    position: relative;
}
.rd-sub-item .cover img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.rd-sub-item .info .title {
    font-size: var(--fs-xl);
    font-weight: 700;
    color: var(--c-text);
    margin: 0 0 8px;
    line-height: 1.35;
}
.rd-sub-item:hover .info .title { color: var(--c-brand); }
.rd-sub-item .info .meta {
    display: flex;
    gap: 16px;
    flex-wrap: wrap;
    margin-bottom: 10px;
}
.rd-sub-item .info .meta span {
    font-size: 12px;
    color: var(--c-text-3);
    display: inline-flex;
    align-items: center;
    gap: 4px;
}
.rd-sub-item .info .meta .tag {
    padding: 2px 10px;
    border-radius: var(--r-pill);
    background: rgba(27, 92, 255, 0.1);
    color: var(--c-brand);
    font-weight: 600;
}
.rd-sub-item .info .desc {
    font-size: var(--fs-sm);
    color: var(--c-text-2);
    line-height: 1.7;
    margin: 0;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.rd-sub-item .date {
    flex-shrink: 0;
    text-align: right;
}
.rd-sub-item .date .d {
    font-size: 30px;
    font-weight: 800;
    color: var(--c-brand);
    line-height: 1;
    display: block;
}
.rd-sub-item .date .y {
    font-size: 12px;
    color: var(--c-text-3);
    margin-top: 6px;
    display: block;
}
/* 帮助页分类宫格 */
.rd-help-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 20px;
}
.rd-help-box {
    background: #fff;
    border: 1px solid var(--c-border);
    border-radius: var(--r-lg);
    padding: 28px;
    transition: all var(--dur) var(--ease);
}
.rd-help-box:hover {
    border-color: rgba(27, 92, 255, 0.25);
    box-shadow: var(--sh-md);
}
.rd-help-box .hb-head {
    display: flex;
    align-items: center;
    gap: 12px;
    padding-bottom: 18px;
    border-bottom: 1px dashed var(--c-border);
    margin-bottom: 18px;
}
.rd-help-box .hb-ico {
    width: 44px; height: 44px;
    border-radius: var(--r-md);
    background: var(--grad-brand-soft);
    color: var(--c-brand);
    display: flex; align-items: center; justify-content: center;
    flex-shrink: 0;
}
.rd-help-box .hb-ico svg { width: 22px; height: 22px; }
.rd-help-box .hb-title {
    font-size: var(--fs-lg);
    font-weight: 700;
    color: var(--c-text);
    margin: 0;
}
.rd-help-box ul {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.rd-help-box li a {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 14px;
    border-radius: var(--r-sm);
    font-size: var(--fs-sm);
    color: var(--c-text-2);
    transition: all var(--dur);
}
.rd-help-box li a:hover {
    background: var(--c-bg-soft);
    color: var(--c-brand);
}
.rd-help-box li a::after {
    content: "›";
    font-size: 18px;
    color: var(--c-text-4);
    transition: all var(--dur);
}
.rd-help-box li a:hover::after {
    color: var(--c-brand);
    transform: translateX(3px);
}
/* 联系页卡片栅格 */
.rd-contact-grid {
    display: grid;
    /* v33: 联系卡片 5 → 4 张（商务合作/公众号/小程序/使用咨询） */
    grid-template-columns: repeat(4, 1fr);
    gap: 20px;
    margin-bottom: 40px;
}
.rd-contact-card {
    background: #fff;
    border: 1px solid var(--c-border);
    border-radius: var(--r-lg);
    padding: 32px 24px;
    text-align: center;
    transition: all var(--dur) var(--ease);
}
.rd-contact-card:hover {
    border-color: rgba(27, 92, 255, 0.25);
    box-shadow: var(--sh-md);
}
.rd-contact-card:hover .cc-ico {
    transform: scale(1.08) rotate(-6deg);
    background: rgba(27, 92, 255, 0.14);
}
.rd-contact-card .cc-ico {
    width: 60px; height: 60px;
    border-radius: 50%;
    margin: 0 auto 18px;
    background: var(--grad-brand-soft);
    color: var(--c-brand);
    display: flex; align-items: center; justify-content: center;
    transition: transform .3s cubic-bezier(0.22, 1, 0.36, 1), background .3s ease;
}
.rd-contact-card .cc-ico svg { width: 28px; height: 28px; }
.rd-contact-card h4 {
    margin: 0 0 8px;
    font-size: var(--fs-lg);
    font-weight: 700;
    color: var(--c-text);
}
.rd-contact-card p {
    margin: 0;
    font-size: var(--fs-sm);
    color: var(--c-text-2);
    line-height: 1.7;
}
.rd-contact-card .qr-wrap {
    margin-top: 4px;
    display: flex;
    align-items: center;
    justify-content: center;
}
.rd-contact-card .qr-wrap img {
    width: 110px;
    height: 110px;
    object-fit: contain;
    border-radius: var(--r-md);
    border: 1px solid var(--c-border);
    padding: 6px;
    background: #fff;
    transition: all var(--dur) var(--ease);
}
.rd-contact-card:hover .qr-wrap img {
    transform: scale(1.03);
    border-color: rgba(27, 92, 255, 0.25);
    box-shadow: var(--sh-sm);
}
/* v51: 「抖音官方号」卡片给一个品牌色图标底（其余三张仍是统一蓝底）。
   抖音双色里选黑底白标：在浅色卡片上辨识度比红/青更高，也更克制。
   只加颜色，不改尺寸/间距 —— 四张卡片的版式仍严格一致。 */
.rd-contact-card.douyin-card .cc-ico {
    background: linear-gradient(135deg, #161823 0%, #2b2f3a 100%);
    color: #fff;
}
.rd-contact-card.douyin-card:hover .cc-ico {
    background: linear-gradient(135deg, #000 0%, #161823 100%);
}
.rd-about-intro {
    background: #fff;
    border: 1px solid var(--c-border);
    border-radius: var(--r-xl);
    padding: 48px;
    margin-bottom: 40px;
    position: relative;
    overflow: hidden;
}
.rd-about-intro::before {
    content: "";
    position: absolute;
    top: 0; right: 0;
    width: 40%;
    height: 100%;
    background: var(--grad-brand-soft);
    clip-path: polygon(30% 0, 100% 0, 100% 100%, 0% 100%);
    opacity: 0.5;
}
.rd-about-intro h2 {
    font-size: 30px;
    font-weight: 800;
    margin: 0 0 16px;
    position: relative;
    letter-spacing: -0.3px;
}
.rd-about-intro h2 .em {
    background: var(--grad-brand);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}
.rd-about-intro p {
    font-size: var(--fs-base);
    color: var(--c-text-2);
    line-height: 2;
    max-width: 72%;
    position: relative;
}

/* ---------- v86: 「关于臂云科技」左文右图 ----------
   原本这个卡片是「文字 + 右侧 .rd-about-intro::before 斜切渐变装饰」的布局，
   文字用 max-width:72% 给右侧留出一条装饰带。
   领导要求在右侧补一张公司大楼图，正好落在这条装饰带的位置上。
   做法：给该卡片加 .rd-about-intro--media 变体，改成两列 grid，右侧放图。
   注意：其余 .rd-about-intro（双子星产品介绍那张）不带这个变体，
        仍保持原来的 72% 文字 + 渐变装饰，不受影响。 */
.rd-about-intro--media {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 0.62fr);
    gap: 48px;
    align-items: center;
}
/* 两列布局下文字不再需要 72% 上限 —— 列宽已经由 grid 约束 */
.rd-about-intro--media .rd-about-intro-text p {
    max-width: 100%;
}
/* 图形在上层，盖住 ::before 的斜切渐变（渐变仍在，作为图片四周的氛围底） */
.rd-about-intro-media {
    position: relative;
    z-index: 1;
    margin: 0;
    border-radius: var(--r-lg);
    overflow: hidden;
    box-shadow: 0 18px 44px rgba(16, 42, 96, 0.14);
    /* 高度交给图片自身比例，避免拉伸变形 */
    align-self: center;
}
.rd-about-intro-media img {
    display: block;
    width: 100%;
    height: auto;
    /* 图片原生 1024x950，比例偏方。这两列高度差较大时，
       用 aspect-ratio 锁定与源图一致的显示比例，防止任何裁切 */
    aspect-ratio: 1024 / 950;
    object-fit: cover;
}

@media (max-width: 992px) {
    .rd-sub-banner h1 { font-size: 34px; }
    /* v77: 中屏档同步压缩页头空白（桌面端 44/36 与窄屏 32/24 之间的过渡档） */
    .rd-sub-banner { padding: 38px 0 30px; }
    .rd-sub-wrap { padding-top: 40px; }
    .rd-sub-item { grid-template-columns: 140px 1fr; }
    .rd-sub-item .cover { width: 140px; height: 100px; }
    .rd-sub-item .date { display: none; }
    .rd-help-grid { grid-template-columns: 1fr; }
    .rd-contact-grid { grid-template-columns: repeat(2, 1fr); }
    .rd-about-intro { padding: 32px; }
    .rd-about-intro p { max-width: 100%; }
    /* v86: 中屏起改为上下排列。
       若保持两列，按桌面比例 minmax(0,1fr) / minmax(0,0.62fr) 折算：
         vw 992 → 文字 514 / 图 318
         vw 900 → 文字 457 / 图 283
       图片列会掉到 320px 以下，公司大楼图缩成缩略图、细节不可辨，
       所以中屏起放弃两列、改上下堆叠，图片单独占满一行才有可读尺寸。 */
    .rd-about-intro--media {
        grid-template-columns: 1fr;
        gap: 28px;
    }
    .rd-about-intro-media {
        max-width: 520px;
        margin: 0 auto;   /* 单列时图片居中 */
    }
}
@media (max-width: 600px) {
    /* v77: 同步压缩页头空白（桌面端 44/36 的窄屏档）。
       原 80px 0 56px 是给桌面端 100/70 配套的窄屏版，
       桌面端收窄后这里必须跟着收，否则窄屏反而比桌面更松。 */
    .rd-sub-banner { padding: 32px 0 24px; }
    .rd-sub-banner h1 { font-size: 28px; }
    .rd-sub-item { grid-template-columns: 1fr; gap: 16px; }
    .rd-sub-item .cover { width: 100%; height: 180px; }
    .rd-contact-grid { grid-template-columns: 1fr; }
    .rd-contact-card { padding: 28px 20px; }
    /* v86: 窄屏卡片内边距收到 24px，图片无需再限宽（父容器已够窄） */
    .rd-about-intro--media .rd-about-intro-media { max-width: 100%; }
    .rd-about-intro--media { gap: 22px; }
}

/* 兼容：保持 header 原生导航在重设计模式下隐藏（使用 rd-nav 替代） */
body.rd-mode > header#nav,
body.rd-mode > div > .page-banner,
body.rd-mode > div > div > .page-banner,
body.rd-mode > div > div > div > .page-banner { display: none !important; }

/* rd-mode 下清零旧版 subpage-body 的 70px 顶部让位（旧固定导航已隐藏，
   sticky 的 rd-nav 应从页面顶部 0 开始，避免导航栏上方留白不贴顶） */
body.subpage-body.rd-mode { padding-top: 0; }

/* rd-mode 下额外隐藏旧 banner 外层占位 */
body.rd-mode .info-other-top,
body.rd-mode .help-top,
body.rd-mode .about-banner { display: none !important; }

/* ---------- v53: 客服浮窗（#kefuFloat）样式已整体删除 ----------
   浮窗为早期静态客服气泡（欢迎语+快捷问题+假输入框），非真实客服系统。
   现已统一为 js/site-config.js 的居中 webview 弹框（读后台 /api/public/kefu 的
   webUrl），浮窗 DOM/JS/CSS 全部移除，避免误回退到假气泡。 */

/* (removed: v9 vis-* dead code — not used in any HTML) */

/* ============================================================
   v7 新增组件样式
   - 产品套餐卡片 .rd-plan-tier
   - 搜索栏 .rd-search-bar
   - 分页 .rd-pagination
   - Bento 功能矩阵 .rd-bento
   - 二维码网格 .rd-qr-grid
   - 中央 focal 卡片 .rd-bento-hero
   ============================================================ */

/* ---------- 产品套餐卡片 / Plan Tier ---------- */
.rd-plan-tier {
    background: #fff;
    /* 用 border 占位（透明）而非 border:none —— 保证悬停时加边框不会抖动布局宽度 */
    border: 1.5px solid transparent;
    border-radius: 20px;
    padding: 28px 22px 24px;
    text-align: left;
    /* v36: 补上 background / border-color，让「变蓝 → 恢复白」双向都有过渡，
       否则移出时背景是瞬间跳回白色，与文字回落不同步 */
    transition:
        background var(--dur) var(--ease),
        border-color var(--dur) var(--ease),
        transform var(--dur) var(--ease),
        box-shadow var(--dur) var(--ease);
    position: relative;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    height: 100%;
    box-shadow:
        0 2px 4px rgba(15, 23, 42, 0.03),
        0 8px 28px rgba(15, 23, 42, 0.07);
}
/* v36 关键：tech-enhance.js 会给卡片挂 .rd-reveal，而 tech-enhance.css 在其后加载，
   其中的 `.rd-reveal { transition: opacity .7s, transform .7s; }` 会把上面的
   background / border-color 过渡整条覆盖掉，导致变色是"瞬间跳"而非渐变。
   这里用 .rd-reveal.rd-plan-tier 提高特异性把四条过渡重新夺回来
   （同时保留 .7s 的显现时长，不影响滚动入场动画）。 */
.rd-reveal.rd-plan-tier {
    transition:
        opacity .7s var(--ease),
        transform var(--dur) var(--ease),
        background var(--dur) var(--ease),
        border-color var(--dur) var(--ease),
        box-shadow var(--dur) var(--ease);
}
/* 卡片内的文字与分隔线也要有过渡，否则悬停时文字颜色是硬切 */
.rd-plan-tier .tier-name,
.rd-plan-tier .tier-sub,
.rd-plan-tier .tier-desc,
.rd-plan-tier .spec-row .spec-k,
.rd-plan-tier .spec-row .spec-v,
.rd-plan-tier .tier-spec,
.rd-plan-tier .spec-row,
.rd-plan-tier .tier-topline {
    transition:
        color var(--dur) var(--ease),
        border-color var(--dur) var(--ease),
        background var(--dur) var(--ease);
}
/* 顶部品牌蓝渐变线 */
.rd-plan-tier .tier-topline {
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 3px;
    border-radius: 20px 20px 0 0;
    background: linear-gradient(90deg, #2563eb, #06b6d4);
}
/* 头部：图标 + 名称（横排） */
.rd-plan-tier .tier-header {
    display: flex;
    align-items: center;
    gap: 12px;
    margin: 2px 0 14px;
}
.rd-plan-tier .tier-icon {
    width: 52px;
    height: 52px;
    flex-shrink: 0;
    border-radius: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    overflow: hidden;
}
.rd-plan-tier .tier-icon svg {
    width: 24px;
    height: 24px;
    color: #2563eb;
}
/* 套餐品牌图（星动/星曜/星球/星际/定制版 webp） */
.rd-plan-tier .tier-icon .tier-img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: 12px;
    display: block;
}
/* v61：featured 卡片的头部一行向右收，给右上「推荐」角标让出横向空间。
   角标位于 top:12px / right:12px，宽约 48px、高约 24px，
   纵向会与 52px 高的 .tier-icon 顶部（y≈30px 起）擦到一点点，
   但横向只占最右侧 —— 所以只需给头部让出右侧宽度，
   不必像旧版那样用 padding-top:40px 把整块内容下压 12px。
   星曜的名称较短、图标在左，`padding-right` 不会造成换行。 */
.rd-plan-tier.featured .tier-header {
    padding-right: 56px;
}
.rd-plan-tier .tier-icon.planet { background: #fff7ed; }
.rd-plan-tier .tier-name {
    font-size: 22px;
    font-weight: 800;
    color: #0f172a;
    margin: 0;
    line-height: 1.2;
    letter-spacing: 0.5px;
}
/* 副标：蓝色纯文本 */
.rd-plan-tier .tier-sub {
    font-size: 13px;
    font-weight: 600;
    color: #2563eb;
    margin: 0 0 8px;
    letter-spacing: 0;
}
.rd-plan-tier .tier-desc {
    font-size: 13px;
    color: #64748b;
    margin: 0 0 18px;
    line-height: 1.55;
}
/* 规格表：虚线分隔 */
.rd-plan-tier .tier-spec {
    margin-top: auto;
    padding-top: 16px;
    border-top: 1px solid #e2e8f0;
    display: flex;
    flex-direction: column;
}
.rd-plan-tier .spec-row {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    padding: 10px 0;
    font-size: 13px;
    border-bottom: 1px dashed #e2e8f0;
}
.rd-plan-tier .spec-row:last-child {
    border-bottom: none;
}
.rd-plan-tier .spec-row .spec-k {
    color: #94a3b8;
}
.rd-plan-tier .spec-row .spec-v {
    color: #0f172a;
    font-weight: 700;
    font-size: 14px;
}
/* ---------- v36: 多套餐卡片悬停交互 ----------
   设计目标（领导需求：「鼠标放入变蓝色，放出恢复」）：
     · 默认态：白底 + 深色字 + 灰调规格键（静态，不带任何蓝）
     · 悬停/聚焦：整卡切品牌蓝渐变实心，**卡内所有文字、图标、分隔线同步转白**
     · 移出/失焦：全部属性回到默认值（靠 transition 自然回落，无需 JS）
   实现要点：
     · 统一用 :hover + :focus-visible 双选择器，键盘 Tab 可达（a11y）
     · 子元素颜色全部挂在父级悬停态下，避免逐个元素写 hover
     · .tier-topline 在蓝底上改白半透明，否则品牌蓝细线会被同色底吞掉
     · 过渡收敛到 .35s，比全局 --dur 略慢，让整卡变色更顺滑不突兀 */
.rd-plan-tier:hover,
.rd-plan-tier:focus-visible {
    background: var(--grad-brand);
    border-color: transparent;
    transform: translateY(-6px);
    box-shadow: var(--sh-glow);
    outline: none;
}
.rd-plan-tier:hover .tier-topline,
.rd-plan-tier:focus-visible .tier-topline {
    background: rgba(255, 255, 255, 0.5);
}
/* 卡内文字体系：深色 → 白色（次级文字用半透明白拉开层级） */
.rd-plan-tier:hover .tier-name,
.rd-plan-tier:focus-visible .tier-name,
.rd-plan-tier:hover .spec-row .spec-v,
.rd-plan-tier:focus-visible .spec-row .spec-v {
    color: #fff;
}
.rd-plan-tier:hover .tier-sub,
.rd-plan-tier:focus-visible .tier-sub {
    color: rgba(255, 255, 255, 0.9);
}
.rd-plan-tier:hover .tier-desc,
.rd-plan-tier:focus-visible .tier-desc,
.rd-plan-tier:hover .spec-row .spec-k,
.rd-plan-tier:focus-visible .spec-row .spec-k {
    color: rgba(255, 255, 255, 0.75);
}
/* 分隔线与规格区上边框同步转白，避免深色线在蓝底上刺眼 */
.rd-plan-tier:hover .tier-spec,
.rd-plan-tier:focus-visible .tier-spec {
    border-top-color: rgba(255, 255, 255, 0.22);
}
.rd-plan-tier:hover .spec-row,
.rd-plan-tier:focus-visible .spec-row {
    border-bottom-color: rgba(255, 255, 255, 0.18);
}
/* SVG 图标：品牌蓝 → 白 */
.rd-plan-tier:hover .tier-icon svg,
.rd-plan-tier:focus-visible .tier-icon svg {
    color: #fff;
    transition: color var(--dur) var(--ease);
}
/* 图片图标（webp）：蓝底上给一层浅色衬底，避免深色图糊在蓝里 */
.rd-plan-tier:hover .tier-icon .tier-img,
.rd-plan-tier:focus-visible .tier-icon .tier-img {
    box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.55);
}

/* 推荐套餐 .featured：不再永久满色，改为「推荐角标 + 蓝调描边/阴影」轻量标识，
   颜色语言与其余卡片一致 —— 只有悬停才变蓝，避免与悬停语义打架。
   v62：推荐位不再靠「常驻抬升」区分（那条声明本就不生效，见下方注释），
   五卡静止态完全等高，动效也完全一致。 */
.rd-plan-tier.featured {
    border: 1.5px solid rgba(27, 92, 255, 0.35);
    box-shadow:
        0 2px 4px rgba(15, 23, 42, 0.03),
        0 10px 30px rgba(27, 92, 255, 0.14);
    /* v62 删除两处声明：
       ① `transform: translateY(-6px)`（常驻抬升）—— 它【从未生效】：
          页面上 tech-enhance.css 在本文件之后加载，其中
          `.rd-reveal.rd-in { transform: translateY(0) }` 与本规则
          特异性同为 (0,2,0)（.rd-plan-tier.featured = 1 类 + 1 类；
          .rd-reveal.rd-in = 1 类 + 1 类），同权重后声明者胜，
          常驻抬升被静默盖成 0 —— 实测 getComputedStyle 读到
          `matrix(1, 0, 0, 1, 0, 0)`（identity），而非 -6px。
          静默后果：静止时五卡齐平（推荐位毫无视觉重点），可鼠标一移入，
          星曜从 0 跳到 -10px、其余四卡从 0 跳到 -6px —— 起跳点并非
          设计意图的 -6px，跳变幅度也不一致。
          按领导确认「拿掉，五卡完全等高」删除后：静止态五卡像素级平齐
          （cardTop/cardBottom/height/iconTop/nameTop/subTop 全部相等），
          悬停时五卡统一走 .rd-plan-tier:hover 的 -6px，动效规则单一来源。
       ② `background: #fff` —— 它的唯一作用是作为同权重的后声明，
          去盖掉 .rd-plan-tier:hover 的蓝色渐变底（导致「白字白底」）。
          该悬停底现已改由本规则之【前】的 `.rd-plan-tier:hover` 处理，
          而 `.rd-plan-tier.featured:hover` 夺权规则也已随分支一并删除，
          故此处的 #fff 已无存在必要 —— 留着反而会再次盖掉悬停蓝底。
       推荐位视觉改由 border + box-shadow 的蓝调 + 右上「推荐」角标承担。 */
    /* v61 修正：原先 padding-top:40px 想把右上「推荐」角标的位置让出来，
       但角标是 position:absolute 且只占 top:12px 起的右上角，
       真正被它压到的只有 52px 高的 .tier-icon 的上半部分，
       而 padding-top 抬的是**整块内容**——实测结果是星曜的
       图标/名称/副标比同排其余四张卡整体低 12px（40-28），
       看起来"星曜图片比其他的低"（用户报障）。
       这里改回与其余卡片一致的 28px，把避让交给 .tier-header 的
       padding-right（只把头部一行向右收，让开角标宽度），
       从而做到"角标不压图标"且"五张卡首行对齐"。 */
    padding-top: 28px;
}
/* v62: 原先这里有一条 `.rd-plan-tier.featured:hover/:focus-visible { … }`，
   只为做两件事：① 夺回被 `.featured { background:#fff }` 盖掉的悬停蓝底；
   ② 把抬升从 -6px 加大到 -10px。
   现在 `.featured` 已不含 background/transform 声明（v62 删除常驻抬升），
   蓝底不再被盖；而「五卡动效必须完全一致」（领导要求），抬升幅度不应有
   featured 专属分支 —— 故整条规则删除，五卡统一走上面的
   `.rd-plan-tier:hover`，动效规则单一来源。
   注：`.featured` 的 border 声明仍在，但悬停时上面已把 border-color
   设为 transparent（同为 (0,2,0)，本处位于其后 → 生效），无需再夺一次。 */
/* 推荐角标 */
.rd-plan-tier.featured::after {
    content: '推荐';
    position: absolute;
    top: 12px; right: 12px;
    padding: 3px 9px;
    font-size: 11px;
    font-weight: 700;
    line-height: 1.4;
    color: #fff;
    background: var(--grad-brand);
    border-radius: var(--r-pill);
    box-shadow: 0 3px 10px rgba(27, 92, 255, 0.3);
    z-index: 2;
    /* 角标占位：给卡片内容留出右上空间，避免与 tier-icon / tier-name 重叠 */
    pointer-events: none;
}
/* featured 卡片把内容整体下压，让出角标高度（角标约 22px + 12px 上边距） */

/* ---------- 搜索栏 / Search Bar ---------- */
.rd-search-bar {
    max-width: 600px;
    margin: 0 auto 40px;
    position: relative;
}
.rd-search-bar input {
    width: 100%;
    padding: 14px 110px 14px 50px;
    border-radius: var(--r-pill);
    border: 1.5px solid var(--c-border);
    font-size: var(--fs-base);
    background: #fff;
    box-shadow: var(--sh-sm);
    transition: all var(--dur) var(--ease);
    outline: none;
    color: var(--c-text);
}
.rd-search-bar input::placeholder { color: var(--c-text-4); }
.rd-search-bar input:focus {
    border-color: var(--c-brand);
    box-shadow: 0 0 0 4px rgba(27, 92, 255, 0.1);
}
.rd-search-bar .rd-search-ico {
    position: absolute;
    left: 20px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--c-text-4);
    pointer-events: none;
}
.rd-search-bar .rd-search-ico svg { width: 20px; height: 20px; }
.rd-search-bar button {
    position: absolute;
    right: 8px;
    top: 50%;
    transform: translateY(-50%);
    padding: 9px 22px;
    border-radius: var(--r-pill);
    background: var(--grad-brand);
    color: #fff;
    border: none;
    font-size: var(--fs-sm);
    font-weight: 600;
    cursor: pointer;
    transition: all var(--dur) var(--ease);
}
.rd-search-bar button:hover { box-shadow: var(--sh-glow); }

/* ---------- 分页 / Pagination ---------- */
.rd-pagination {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 8px;
    margin-top: 48px;
}
.rd-pagination a,
.rd-pagination span.pg {
    min-width: 42px;
    height: 42px;
    padding: 0 6px;
    border-radius: var(--r-md);
    border: 1px solid var(--c-border);
    background: #fff;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: var(--fs-sm);
    font-weight: 600;
    color: var(--c-text-2);
    transition: all var(--dur) var(--ease);
    cursor: pointer;
    text-decoration: none;
}
.rd-pagination a:hover,
.rd-pagination span.pg:hover {
    border-color: var(--c-brand);
    color: var(--c-brand);
}
.rd-pagination .pg.active {
    background: var(--grad-brand);
    color: #fff;
    border-color: transparent;
    box-shadow: 0 4px 14px rgba(27, 92, 255, 0.3);
}
.rd-pagination .pg-dots {
    border: none;
    background: transparent;
    color: var(--c-text-4);
    min-width: auto;
    cursor: default;
}
.rd-pagination .pg-dots:hover { border: none; color: var(--c-text-4); }
.rd-pagination .pg svg { width: 16px; height: 16px; }

/* ---------- Bento Grid / 功能矩阵 v22（5 功能卡：换机/机型/ROOT/兼容/谷歌框架） ---------- */
.rd-bento-section {
    background:
        radial-gradient(ellipse 120% 80% at 50% 0%, rgba(255, 245, 230, 0.85), transparent 60%),
        radial-gradient(ellipse 100% 60% at 80% 100%, rgba(255, 235, 210, 0.5), transparent 50%),
        #fffdf9;
}
.rd-bento-section .rd-head { margin-bottom: 56px; }
.rd-bento-section .rd-head h2 { letter-spacing: -0.6px; }

.rd-bento {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    grid-auto-rows: minmax(174px, auto);
    gap: 18px;
}

/* Bento 卡片基础 */
.rd-bento-card,
.rd-bento-hero {
    position: relative;
    border-radius: var(--r-xl);
    padding: 24px;
    overflow: hidden;
    transition: transform .45s cubic-bezier(0.22, 1, 0.36, 1), box-shadow .45s ease, border-color .45s ease;
    isolation: isolate;
}
.rd-bento-card {
    background: #fff;
    border: 1px solid rgba(226, 232, 240, 0.9);
    box-shadow: 0 8px 28px rgba(15, 23, 42, 0.04), 0 2px 8px rgba(15, 23, 42, 0.02);
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    gap: 16px;
}

/* 宽度跨度（桌面 6 列） */
.b-w1 { grid-column: span 1; }
.b-w2 { grid-column: span 2; }
.b-w3 { grid-column: span 3; }
.b-w4 { grid-column: span 4; }

/* Spotlight 边框：光标位置驱动的柔光描边 */
.rd-bento-card::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    padding: 1.5px;
    background: radial-gradient(220px circle at var(--mx, 50%) var(--my, 50%),
        rgba(27, 92, 255, 0.65), rgba(27, 92, 255, 0.14) 55%, transparent 72%);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    mask-composite: exclude;
    opacity: 0;
    transition: opacity .35s ease;
    pointer-events: none;
    z-index: 3;
}
.rd-bento-card:hover {
    transform: translateY(-4px);
    box-shadow: 0 20px 46px rgba(15, 23, 42, 0.08), 0 6px 16px rgba(15, 23, 42, 0.04);
}
.rd-bento-card:hover::before { opacity: 1; }

/* 淡蓝 tint 卡 */
.rd-bento-card.tint-blue {
    background: linear-gradient(160deg, #f3f7ff, #eaf1ff);
    border-color: rgba(27, 92, 255, 0.14);
}

/* 深色块卡（无广告：纯净无干扰的暗色语义） */
.rd-bento-card.tint-dark {
    background: linear-gradient(165deg, #1d2d50 0%, #101c36 100%);
    border-color: rgba(27, 92, 255, 0.28);
    box-shadow: 0 14px 34px rgba(16, 28, 54, 0.32);
}
.rd-bento-card.tint-dark:hover {
    box-shadow: 0 24px 50px rgba(16, 28, 54, 0.42);
}
.rd-bento-card.tint-dark .rd-bento-text h3 { color: #fff; }
.rd-bento-card.tint-dark .rd-bento-text p { color: rgba(255, 255, 255, 0.7); }
.rd-bento-card.tint-dark::before {
    background: radial-gradient(220px circle at var(--mx, 50%) var(--my, 50%),
        rgba(255, 255, 255, 0.55), rgba(255, 255, 255, 0.1) 55%, transparent 72%);
}

.rd-bento-text h3 {
    margin: 0 0 6px;
    font-size: 18px;
    font-weight: 800;
    color: var(--c-text);
    letter-spacing: -0.3px;
    line-height: 1.25;
}
.rd-bento-text p {
    margin: 0;
    font-size: 13px;
    color: var(--c-text-3);
    line-height: 1.5;
}

/* 右上角小标签 */
.rd-bento-tag {
    position: absolute;
    top: 18px;
    right: 18px;
    font-size: 11px;
    font-weight: 700;
    color: #fff;
    background: linear-gradient(135deg, #1b5cff, #00b8ff);
    padding: 5px 10px;
    border-radius: var(--r-pill);
    box-shadow: 0 4px 12px rgba(27, 92, 255, 0.25);
    z-index: 2;
}

/* Focal 左侧大卡片（3×2） */
.rd-bento-hero {
    grid-column: 1 / 4;
    grid-row: 1 / 3;
    background: linear-gradient(145deg, #1b5cff 0%, #3670ff 55%, #00b8ff 100%);
    color: #fff;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    box-shadow: 0 24px 60px rgba(27, 92, 255, 0.32), inset 0 1px 0 rgba(255, 255, 255, 0.25);
}
.rd-bento-hero::before {
    content: "";
    position: absolute;
    inset: 0;
    background:
        radial-gradient(circle at 80% 20%, rgba(255, 255, 255, 0.22), transparent 35%),
        radial-gradient(circle at 20% 90%, rgba(140, 200, 255, 0.28), transparent 30%);
    pointer-events: none;
    z-index: 0;
}
.rd-bento-hero:hover {
    transform: translateY(-6px);
    box-shadow: 0 32px 72px rgba(27, 92, 255, 0.38), inset 0 1px 0 rgba(255, 255, 255, 0.25);
}
.rd-bento-hero-text { position: relative; z-index: 1; }
.rd-bento-hero-text h3 {
    margin: 0 0 10px;
    font-size: 34px;
    font-weight: 900;
    line-height: 1.18;
    letter-spacing: -0.8px;
    text-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}
.rd-bento-hero-text p {
    margin: 0;
    font-size: 15px;
    opacity: 0.92;
    font-weight: 500;
}
.rd-bento-hero-mascot {
    position: relative;
    z-index: 1;
    width: 150px;
    height: 150px;
    margin-left: auto;
    margin-top: auto;
    filter: drop-shadow(0 16px 40px rgba(0, 0, 0, 0.14));
    animation: bento-float 5s ease-in-out infinite;
}
@keyframes bento-float {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-8px); }
}
@media (prefers-reduced-motion: reduce) {
    .rd-bento-hero-mascot { animation: none; }
}

/* 一键换机视觉：双机数据迁移 */
.vis-migrate { height: 80px; display: flex; align-items: center; justify-content: flex-end; gap: 14px; }
.mig-phone {
    width: 38px; height: 64px;
    border-radius: 9px;
    background: linear-gradient(180deg, #f8fafc, #e2e8f0);
    border: 1px solid #cbd5e1;
    padding: 5px;
    box-shadow: 0 6px 16px rgba(15, 23, 42, 0.08);
}
.mig-phone .mig-screen {
    width: 100%; height: 100%;
    border-radius: 5px;
    background: linear-gradient(180deg, rgba(27, 92, 255, 0.12), rgba(0, 184, 255, 0.08));
}
.mig-phone.mig-new {
    background: linear-gradient(180deg, #fff, #f1f5f9);
    border-color: rgba(27, 92, 255, 0.4);
    box-shadow: 0 8px 20px rgba(27, 92, 255, 0.18);
}
.mig-arrow { color: var(--c-brand); display: flex; align-items: center; }
.mig-arrow svg { width: 44px; height: 16px; }

/* 机型设置视觉：自定义品牌/型号选择 */
.vis-model { display: flex; flex-direction: column; gap: 10px; padding: 2px 2px 0; }
.sel-row { display: flex; align-items: center; gap: 10px; }
.sel-label {
    font-size: 11px; font-weight: 800;
    color: var(--c-brand);
    letter-spacing: 0.5px;
    width: 32px;
    flex-shrink: 0;
}
.sel-box {
    flex: 1;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 12.5px;
    font-weight: 700;
    color: var(--c-text);
    background: #fff;
    border: 1px solid var(--c-border);
    border-radius: 9px;
    padding: 7px 11px;
    box-shadow: 0 3px 10px rgba(15, 23, 42, 0.05);
    white-space: nowrap;
}
.sel-dot { width: 9px; height: 9px; border-radius: 3px; flex-shrink: 0; }
.sel-dot-brand { background: linear-gradient(135deg, #ff5e3a, #ff8a4c); }
.sel-dot-model { background: linear-gradient(135deg, #1b5cff, #00b8ff); }
.sel-chev { margin-left: auto; width: 14px; height: 14px; color: var(--c-text-4); flex-shrink: 0; transition: color .25s ease; }
.rd-bento-card:hover .sel-chev { color: var(--c-brand); }

/* 支持ROOT视觉：终端（深色卡内） */
.vis-root { display: flex; align-items: center; height: 42px; }
.root-term {
    font-family: "SF Mono", "JetBrains Mono", Consolas, "Courier New", monospace;
    font-size: 12px;
    font-weight: 600;
    color: #7dd3a8;
    background: rgba(0, 0, 0, 0.3);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 8px;
    padding: 7px 11px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    white-space: nowrap;
}
.term-prompt { color: rgba(255, 255, 255, 0.6); }
.term-cursor {
    width: 7px; height: 13px;
    background: #7dd3a8;
    border-radius: 1.5px;
    animation: term-blink 1.1s steps(1) infinite;
}
@keyframes term-blink { 50% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
    .term-cursor { animation: none; }
}

/* 兼容游戏/应用视觉：应用图标 + 手柄 */
.vis-game { display: flex; align-items: center; gap: 16px; height: 66px; justify-content: flex-end; }
.game-apps { flex: none; justify-content: flex-start; }
.game-pad {
    width: 48px; height: 48px;
    flex-shrink: 0;
    border-radius: 14px;
    background: linear-gradient(135deg, #ff8a4c, #ff5e3a);
    display: flex; align-items: center; justify-content: center;
    box-shadow: 0 8px 18px rgba(255, 107, 53, 0.28);
}
.game-pad svg { width: 27px; height: 27px; }

/* 谷歌play视觉 */
.vis-gplay { display: flex; align-items: center; gap: 14px; height: 64px; }
.gplay-tri { width: 44px; height: 44px; filter: drop-shadow(0 6px 14px rgba(52, 168, 83, 0.18)); }
.gplay-orbit { position: relative; width: 44px; height: 44px; }
.gplay-orbit .orb { position: absolute; width: 12px; height: 12px; border-radius: 50%; }
.orb-g { background: #34A853; left: 0; top: 16px; }
.orb-y { background: #FBBC05; left: 16px; top: 0; }
.orb-r { background: #EA4335; left: 28px; top: 28px; }

/* 畅玩应用视觉（宽卡：横排） */
.vis-apps { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; justify-content: flex-end; }
.app-icon {
    width: 32px; height: 32px;
    border-radius: 9px;
    background: var(--bg);
    display: flex; align-items: center; justify-content: center;
    box-shadow: 0 3px 8px rgba(0,0,0,0.1);
    transition: transform .3s cubic-bezier(0.22, 1, 0.36, 1);
}
.app-icon:hover { transform: translateY(-3px) scale(1.08); }
.app-icon svg { width: 17px; height: 17px; }


/* ---------- 二维码网格 / QR Grid ---------- */
.rd-qr-grid {
    display: flex;
    justify-content: center;
    gap: 48px;
    flex-wrap: wrap;
    margin-top: 8px;
}
.rd-qr-card {
    text-align: center;
}
.rd-qr-card img {
    width: 140px;
    height: 140px;
    border-radius: var(--r-md);
    border: 1px solid var(--c-border);
    padding: 8px;
    background: #fff;
    margin-bottom: 12px;
    object-fit: contain;
    transition: all var(--dur) var(--ease);
}
.rd-qr-card:hover img {
    transform: scale(1.04);
    box-shadow: var(--sh-md);
    border-color: rgba(27, 92, 255, 0.25);
}
.rd-qr-card .label {
    font-size: var(--fs-sm);
    color: var(--c-text-2);
    font-weight: 600;
}

/* ---------- 分栏视觉图片适配 / Split Visual Image ---------- */
.rd-split-visual img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* ---------- 安全保障全宽卡 / Security Card ---------- */
.rd-security-card {
    background: #fff;
    border: 1px solid var(--c-border);
    border-radius: var(--r-xl);
    padding: 48px;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 48px;
    align-items: center;
    transition: all var(--dur) var(--ease);
}
.rd-security-card:hover {
    box-shadow: var(--sh-lg);
    border-color: rgba(27, 92, 255, 0.2);
}
.rd-security-card .rd-sec-points {
    display: flex;
    flex-direction: column;
    gap: 18px;
}
.rd-security-card .rd-sec-point {
    display: flex;
    align-items: flex-start;
    gap: 14px;
}
.rd-security-card .rd-sec-point .ico {
    width: 44px;
    height: 44px;
    border-radius: var(--r-md);
    background: var(--grad-brand-soft);
    color: var(--c-brand);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}
.rd-security-card .rd-sec-point .ico svg { width: 22px; height: 22px; }
.rd-security-card .rd-sec-point .txt h4 {
    margin: 0 0 4px;
    font-size: var(--fs-lg);
    font-weight: 700;
    color: var(--c-text);
}
.rd-security-card .rd-sec-point .txt p {
    margin: 0;
    font-size: var(--fs-sm);
    color: var(--c-text-2);
    line-height: 1.6;
}
/* v37: 数据安全区配图。用 aspect-ratio 锁定 1.25:1，object-fit: cover 兜底，
   避免不同视口下容器比例变化把图拉伸变形。 */
.rd-sec-visual {
    width: 100%;
    aspect-ratio: 1.25 / 1;
    object-fit: cover;
    display: block;
    border-radius: var(--r-lg);
    box-shadow: var(--sh-md);
}

/* ---------- v7 响应式补充 ---------- */
@media (max-width: 1100px) {
    .rd-security-card { grid-template-columns: 1fr; gap: 32px; padding: 32px; }
    .rd-bento { grid-template-columns: repeat(2, 1fr); grid-auto-rows: minmax(158px, auto); }
    .rd-bento-hero { grid-column: 1 / -1; grid-row: auto; min-height: 250px; }
    .rd-bento-hero-text h3 { font-size: 30px; }
    .b-w3, .b-w4 { grid-column: span 2; }
    .b-w1, .b-w2 { grid-column: span 1; }
    .rd-hero { padding: 90px 0 80px; }
    /* v63: ≤1100px 时隐藏首屏背景图，回退纯渐变底。
       原因：背景图按 100% auto 铺，窄屏下图高骤降 ——
         768px 视口：图缩放高仅 492，hero 高 813 → 下方 321px 露底色
         390px 视口：图缩放高仅 250，hero 高 842 → 下方 593px 露底色
       结果图上那组「电脑+手机界面」被压成贴顶的一小块（约 200x80），
       还被居中的文案压住，观感是一团杂物糊在标题后面。
       故窄屏直接撤掉背景图，只留 --grad-hero 渐变，版面干净。

       注意：这里必须把 min-height 与 padding 一起复原 ——
       桌面端的 .rd-hero.has-bg-image 设了 min-height: clamp(660px,64.01vw,1080px)
       且 padding 归零（因为 min-height 接管了高度）。窄屏撤图后若不清掉，
       只剩「无图的渐变底 + 强撑的 660px+ 高度 + 零 padding」，
       首屏会变成一片空荡荡的大色块。 */
    .rd-hero.has-bg-image {
        background: var(--grad-hero);
        min-height: 0;
        padding-top: 90px;
        padding-bottom: 80px;
        display: block;
    }
    /* v64: 窄屏撤掉背景图后就没有「右侧配图底边」这个对齐基准，
       桌面端为对齐而加的下外边距（当前 238px）必须归零，
       否则单列布局下会在文案块下方留出一大段空白。 */
    .rd-hero.has-bg-image .rd-hero-text-col { margin-bottom: 0; }
    /* 单列布局下 36% 的列宽约束必须解除，否则文字被压成一竖条 */
    .rd-hero.hero-bg-mode .rd-hero-inner { grid-template-columns: none; }
    .rd-hero-inner { display: flex; flex-direction: column; gap: 44px; }
    .rd-hero-visual-col { min-height: auto; max-width: 680px; margin: 0 auto; }
    .rd-hero-text-col { text-align: center; }
    .rd-hero-text-col .tag-row { justify-content: center; }
    .rd-hero .sub { margin-left: auto; margin-right: auto; }
    /* v70: 窄屏背景图已被撤掉（.rd-hero.has-bg-image 退化为纯渐变），
       徽标失去了「配图四角」这个锚定目标，继续显示会浮在空白渐变上，
       故整组隐藏。桌面端才显示。 */
    .rd-hero-badges { display: none; }
    .rd-download { margin-left: auto; margin-right: auto; max-width: 560px; }
    .rd-download-list { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 600px) {
    .rd-bento { grid-template-columns: 1fr; grid-auto-rows: auto; }
    .rd-bento-hero { grid-column: auto; grid-row: auto; min-height: 260px; }
    .rd-bento-hero-text h3 { font-size: 28px; }
    .rd-bento-hero-mascot { width: 100px; height: 100px; }
    .b-w1, .b-w2, .b-w3, .b-w4 { grid-column: span 1; }
    .rd-bento-card { min-height: 150px; padding: 20px; }
    .rd-security-card { padding: 24px; }
    .rd-qr-grid { gap: 32px; }
    .rd-search-bar input { padding: 12px 96px 12px 46px; }
    .rd-search-bar .rd-search-ico { left: 16px; }
    .rd-search-bar button { padding: 8px 16px; }
    .rd-hero { padding: 70px 0 60px; }
    .rd-hero h1 { font-size: 38px; }
    .rd-hero-subtitle { font-size: 20px; }
    .rd-hero-visual-col { max-width: 100%; }
    .rd-hero-float-badge { padding: 7px 14px; font-size: var(--fs-sm); }
    .rd-hero-float-badge.badge-tl { top: 14px; left: 14px; }
    .rd-hero-float-badge.badge-tr { top: 14px; right: 14px; }
    .rd-download-list { grid-template-columns: 1fr; }
    .rd-download-item {
        flex-direction: row;
        justify-content: flex-start;
        padding: 14px;
        text-align: left;
    }
    .rd-hero-float-badge.badge-bl { bottom: 14px; left: 14px; }
    .rd-hero-float-badge.badge-br { bottom: 14px; right: 14px; }
}
/* ---------- v63: 原「Hero 右侧视觉组合」已整体移除 ----------
   原先这里有：.rd-hero-scene / .rd-hero-scene img / .rd-hero-float-badge
   （含 badge-tl/tr/bl/br 四角定位 + 1100px、600px 两段响应式收位规则）。
   对应的 HTML（index.html 的 .rd-hero-visual-col 整块）与图片
   img/banner-hero.webp 已于 v63 一并删除，这些规则已成死代码，故清理。

   历史结论保留备查（v54 那段排查，改回两栏布局时仍适用）：
   旧配图曾出现"被外框框住"的观感。当时先怀疑 CSS 的 border-radius 与
   box-shadow，实测删掉二者后"框"依旧，说明病根不在 CSS，而在图片内部：
     (1) 图片画布把卡片圆角硬切割了 —— 原图 1572x984 左上"海外矩阵营销"
         白卡占 x 0..355 / y 0..397，左上圆角正好被画布边界切断，
         在 x=0、y=0 处留下直角硬边，渲染后像被外框框住。
     (2) 页面底色接缝 —— .rd-hero 背景是 --grad-hero 渐变
         （顶部 #f0f6ff → 65% 处 #fff）。图片内的纯白卡片与图片外透出的
         渐变蓝在图片矩形包围盒处突兀跳变。实测（修复前，图片左边缘
         y=700 横扫）：x=70 → rgb(243,247,255)，x=76 → rgb(255,255,255)，
         相邻 6px 内跳变 243→255，这就是那道"框"。
   当时的修法是改图不改 CSS：给图片补 24px 透明留白并补回被裁断的圆角，
   让页面渐变能从卡片四周自然过渡过去。所以此处一直保留"无圆角、无投影"。

   v63 起首屏改为「整块背景图」方案：背景图自带右侧视觉，不再需要
   独立的两栏图片元素，上述问题在结构上已被绕开。 */

/* ---------- v16: 移动端汉堡菜单 ---------- */
.rd-nav-toggle {
    display: none;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    width: 40px;
    height: 40px;
    border: 1px solid var(--c-border);
    border-radius: var(--r-sm);
    background: #fff;
    cursor: pointer;
    gap: 5px;
    padding: 0;
    transition: all var(--dur) var(--ease);
}
.rd-nav-toggle span {
    display: block;
    width: 18px;
    height: 2px;
    border-radius: 2px;
    background: var(--c-text);
    transition: all .3s cubic-bezier(0.22, 1, 0.36, 1);
    transform-origin: center;
}
.rd-nav-toggle.active span:nth-child(1) {
    transform: translateY(7px) rotate(45deg);
}
.rd-nav-toggle.active span:nth-child(2) {
    opacity: 0;
    transform: scaleX(0);
}
.rd-nav-toggle.active span:nth-child(3) {
    transform: translateY(-7px) rotate(-45deg);
}

/* ---------- v16: 导航链接 hover 下划线动画 ---------- */
.rd-nav-links a::after {
    content: "";
    position: absolute;
    left: 50%;
    bottom: -24px;
    transform: translateX(-50%);
    width: 0;
    height: 3px;
    border-radius: 2px;
    background: var(--grad-brand);
    transition: width .3s cubic-bezier(0.22, 1, 0.36, 1);
}
.rd-nav-links a:hover::after,
.rd-nav-links a.active::after {
    width: 36px;
}

/* ---------- v16: 按钮按压反馈 ---------- */
.rd-btn:active { transform: translateY(0) scale(0.97); }
.rd-download-item:active { transform: translateY(-1px) scale(0.985); }
.rd-card:active,
.rd-plan-tier:active,
.rd-contact-card:active,
.rd-help-box:active,
.rd-qr-card:active { transform: translateY(0) scale(0.99); }

/* ---------- v16: KPI 区移除 inline style，改用类名 ---------- */
/* v74: 首屏下方空白压缩 50%。
   ---- 问题 ----
   首屏文案块（含下载卡）底边止于页面 y=636，而 KPI 数据栏的文字顶边在 y=940，
   中间留出 305px 的纯空白带（领导截图圈出的就是这条）。
   空白来源有三层叠加：
     ① .rd-hero 是 flex + align-items:center，min-height 撑到 921px（69~990），
        文案块居中后下方天然留白；
     ② .rd-kpi-band 原本已有 transform: translateY(-50px) 往上拉，
        但只拉了 50px，抵不掉 hero 的底边留白；
     ③ .rd-kpis 自带 padding: 40px 0，又往下推 40px。

   ---- 处理 ----
   领导要求「下面内容往上提，提空白的一半」= 305 / 2 = 152.5px，取整 152px。
   做法：把 .rd-kpi-band 的 translateY 从 -50px 加深到 -202px
   （-50 - 152 = -202），即额外再上提 152px。
   实测：KPI 文字顶从 940 变为 788，空白从 305 压到 152（正好剩一半）。

   ---- 为什么改 translateY 而不动 hero 的 min-height ----
   hero 的 min-height（clamp(660px, 62.66vw, 1080px)）是按背景图比例算的，
   动它会连带改变配图渲染高度与徽标百分比定位，牵一发动全身。
   translateY 只影响 KPI 栏自身位置，不参与 hero 的布局计算，是精准的一刀。

   ---- v82：KPI 之后到「24小时云端运行」区块之间还有一条同样宽的空白 ----
   领导又圈了一次（这次圈的是视频那个空位），要求「再往上提 50%」。
   实测（页面绝对坐标）：KPI 带底边 943，下一个 .rd-section 顶边 1145，
   中间空白 **202px**；再往下是该 section 自带的 padding-top: 96px，
   视频容器才从 1418 开始 —— 领导圈的是 943~1418 这一整片。

   **❌ 先踩了两个坑：**

   坑1 —— 继续加深 translateY（-202 → -303）：
     KPI 文字顶确实从 788 上到 687，但下一个 section 顶边**纹丝不动**（1145 → 1145），
     空白反而从 202 变成 303 —— 完全反效果。
     根因：`transform` 是**视觉位移**，不参与文档流，后面元素的布局位置不受影响。

   坑2 —— 把下一个 section 的 padding-top 归零：
     padding-top 96px → 0 生效了，但 section 顶边**还是 1145**，
     只是区块**从内部变矮**（视频顶 1418 → 1322）。gap 依然是 202。
     根因：这 202px **压根不是 section 的 padding 撑出来的**。

   **真正的机理（关键，务必理解）：**
     .rd-kpi-band 在文档流里的占位是 t=990 ~ b=1145（紧接 hero 底边 990）；
     施加 `translateY(-202px)` 后视觉位置变 788 ~ 943。
     **它把自己往上挪走了多少，文档流里就空出多少** ——
       上方视觉留白 = 788 - 636（首屏文案底） = 152  ← v74 要的效果
       下方文档空洞 = 1145 - 943           = 202  ← 就是这 202
     两者是同一个 202px 的两面。所以：
       · 减小 translateY 会让下方空洞变小，但**上方留白同步变大**（v74 成果被推翻）；
       · 改 section 自己的 padding 无效，因为空洞在 band 这一侧。

   **✅ 正解：给紧随其后的 section 一个负 margin-top，把它拉进这个空洞。**
     `.rd-kpi-band + .rd-section { margin-top: -101px; }`
     margin 影响文档流（不像 transform），能把后续元素真正提上来，
     同时 band 的视觉位置不动，v74 那段 152px 留白原样保留。
   实测：section 顶边 1145 → **1044**（上提 101px），视频容器顶 1322 → **1221**，
        下方空白 202 → **101**（正好剩一半），KPI 带仍 788~943 不动。

   ---- 为什么用 `+` 相邻兄弟选择器 ----
   同页有 4 个 .rd-section（24小时/数据安全/…），直接写 `.rd-section` 会全部中招。
   `.rd-kpi-band + .rd-section` 只命中紧跟在 KPI 带之后的那个，范围精确。
   （已实测确认该 section 确实是 .rd-kpi-band 的 nextElementSibling。）

   ---- 三种属性的分工（这类「改了没效果」的通用判据）----
     改**自己**的视觉位置        → transform
     改**自己**在流里的占位      → margin / padding（会影响兄弟节点）
     改**后续**元素的位置        → 后续元素自己的 margin（用 + 或 ~ 限定范围）
   混用前先想清楚「要动的是谁」。

   ---- v74 为什么改 translateY 而不动 hero 的 min-height ----
   hero 的 min-height（clamp(660px, 62.66vw, 1080px)）是按背景图比例算的，
   动它会连带改变配图渲染高度与徽标百分比定位，牵一发动全身。
   translateY 只影响 KPI 栏自身位置，不参与 hero 的布局计算，是精准的一刀。
   （v82 要动的是**后面的 section**，所以换成负 margin，道理同上：选对「动谁」。） */
.rd-kpi-band {
    padding: 0 24px;
    transform: translateY(-202px);
}
/* v82: 把「24小时云端运行」区块整体上提 101px（= 其上方 202px 空白的 50%）。
   必须用 margin-top（影响文档流）而不是 padding-top（只改自身内部高度），
   也不用动 .rd-kpi-band 的 translateY（那会连首屏留白一起改坏）。
   该 section 类名为 .rd-section，但同页有多个 .rd-section，
   故用「紧跟 .rd-kpi-band 之后」的相邻兄弟选择器限定，只命中这一个。
   **数值必须与 .rd-kpi-band 的 translateY 联动**：下方空洞 = |translateY|，
   所以窄屏 translateY 收回 -50px 时，这里也必须同步收到 -25px（50 的一半），
   否则 -101px 会把 section 拽到 KPI 带**上面去**（实测 gap = -51px，即重叠 51px）。
   见下方同断点的媒体查询覆盖。 */
.rd-kpi-band + .rd-section {
    margin-top: -101px;
}
/* v82-窄屏: 与 .rd-kpi-band 的 -50px 联动，同为 50% */
@media (max-width: 1100px) {
    .rd-kpi-band + .rd-section {
        margin-top: -25px;
    }
}
/* v74: 窄屏必须把 -202px 收回到 -50px。
   ---- 为什么这条写在 .rd-kpi-band 规则「之后」而不是塞进上面那个 1100px 媒体查询----
   媒体查询本身不增加选择器权重。上面的 @media (max-width:1100px) 块在文件第 2580 行，
   而 .rd-kpi-band 规则在第 2721 行 —— **同权重下后声明者胜**，
   所以写在前面那条会被后面这条静默覆盖，实测四个断点全返回 -202，规则形同虚设。
   故此处单独起一个媒体查询块，位置在规则之后。
   （判据：改完必须逐断点实测 getComputedStyle 的 transform 值，
   不能只看规则「写没写」—— 这类被顺序吃掉的规则从源码读不出来。）

   ---- 为什么要收回 ----
   窄屏 .rd-hero 退化为 display:block + padding:90px/80px，
   没有「flex 居中撑高」那层留白，-202px 会把 KPI 栏硬拽进首屏压住文案。
   -50px 是这里原本就有的轻微上提量，保留原观感即可。 */
@media (max-width: 1100px) {
    .rd-kpi-band { transform: translateY(-50px); }
}

/* ---------- v16: 移动端导航展开 ---------- */
@media (max-width: 992px) {
    .rd-nav-toggle { display: flex; }
    .rd-nav-links {
        display: flex; /* 关键：覆盖任何 display:none，配合下方 visibility/transform 实现滑入展开 */
        position: fixed;
        top: 68px;
        left: 0;
        right: 0;
        flex-direction: column;
        gap: 0;
        background: #fff;
        border-bottom: 1px solid var(--c-border);
        box-shadow: 0 12px 32px rgba(15, 23, 42, 0.08);
        padding: 8px 24px 16px;
        transform: translateY(-100%);
        opacity: 0;
        visibility: hidden;
        transition: transform .35s cubic-bezier(0.22, 1, 0.36, 1),
                    opacity .35s ease,
                    visibility .35s;
        z-index: 99;
    }
    .rd-nav-links.rd-nav-open {
        transform: translateY(0);
        opacity: 1;
        visibility: visible;
    }
    .rd-nav-links li {
        width: 100%;
        border-bottom: 1px solid var(--c-border-2);
    }
    .rd-nav-links li:last-child { border-bottom: none; }
    .rd-nav-links a {
        display: block;
        padding: 14px 0;
        font-size: var(--fs-base);
    }
    .rd-nav-links a::after { display: none; }
    .rd-nav-links a.active {
        color: var(--c-brand);
        font-weight: 600;
    }
}

/* ============================================================
   v26: 首页联合悬浮框 / 套餐 5 列网格 / 列表·手册搜索过滤
   ============================================================ */

/* ---------- v59: 下载 / 客服 悬浮面板（全站通用） ----------
   白色圆角面板容器（.rd-float-dock）+ 内部 4 个按钮竖排。
   面板提供外层底、边框、柔和阴影与内边距；按钮自身在 v61 起改为
   **白底 + 浅蓝描边 + 圆角 + 柔和投影**的独立小卡片（照用户提供截图），
   悬停/键盘聚焦时填充品牌色浅底，形成"面板内的一排小卡片"。
   —— 旧版（v35~v58）为 4 个各自带边框+投影的独立白按钮直接浮在页面上，
   视觉上像"贴了 4 张贴纸"，无容器归属感，故 v59 补了背景面板；
   v61 再把按钮恢复为描边卡片形态，但保留面板作为外层容器。 */
.rd-float-dock {
    position: fixed;
    right: 20px;
    bottom: 104px;
    z-index: 9990;
    display: flex;
    flex-direction: column;
    /* v61：按钮变成描边卡片后，2px 间距会让两张卡片的描边视觉粘连，放宽到 8px */
    gap: 8px;
    padding: 8px;
    background: #fff;
    border: 1px solid var(--c-border);
    border-radius: var(--r-lg);
    box-shadow: 0 12px 36px rgba(15, 23, 42, 0.12), 0 2px 8px rgba(15, 23, 42, 0.06);
    opacity: 0;
    visibility: hidden;
    transform: translateY(18px) scale(0.95);
    transform-origin: bottom right;
    transition: opacity .35s var(--ease), transform .35s var(--ease), visibility .35s;
}
.rd-float-dock.show {
    opacity: 1;
    visibility: visible;
    transform: translateY(0) scale(1);
}
/* v61：按钮 = 白底圆角描边小卡片（照用户截图）
   描边取截图实测的极浅蓝 #E6F0FF（截图采样 rgb(230,240,255)），
   比主面板的 --c-border 更淡更偏蓝，形成"卡片浮在面板上"的层次。 */
.rd-dock-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-width: 156px;
    padding: 12px 16px;
    border-radius: 14px;
    font-size: var(--fs-sm);
    font-weight: 600;
    cursor: pointer;
    background: #fff;
    color: var(--c-text);
    border: 1px solid #e6f0ff;
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04), 0 4px 12px rgba(27, 92, 255, 0.06);
    transition: background .22s var(--ease), color .22s var(--ease),
                border-color .22s var(--ease), box-shadow .22s var(--ease),
                transform .22s var(--ease);
    white-space: nowrap;
}
.rd-dock-btn svg { width: 17px; height: 17px; flex-shrink: 0; }
/* 悬停 / 键盘聚焦：浅蓝底 + 品牌色文字，并把描边加深一档，保持面板内透气 */
.rd-dock-btn:hover,
.rd-dock-btn:focus-visible {
    background: rgba(27, 92, 255, 0.06);
    border-color: rgba(27, 92, 255, 0.35);
    color: var(--c-brand);
    box-shadow: 0 2px 6px rgba(27, 92, 255, 0.12);
    outline: none;
}
/* 按下反馈 */
.rd-dock-btn:active { transform: scale(0.985); }
/* 兼容旧标记：.primary 现与普通按钮一致 */
.rd-dock-btn.primary { background: #fff; color: var(--c-text); border: 1px solid #e6f0ff; }
.rd-dock-btn.primary:hover,
.rd-dock-btn.primary:focus-visible {
    background: rgba(27, 92, 255, 0.06);
    border-color: rgba(27, 92, 255, 0.35);
    color: var(--c-brand);
}
@media (max-width: 600px) {
    .rd-float-dock { right: 12px; bottom: 96px; padding: 6px; border-radius: var(--r-md); }
    .rd-dock-btn { min-width: 126px; padding: 10px 13px; border-radius: 12px; }
}


/* ---------- 套餐：5 列统一网格 ---------- */
.rd-plan-grid {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 18px;
    align-items: stretch;
}
@media (max-width: 1200px) and (min-width: 1025px) {
    .rd-plan-grid { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 1024px) and (min-width: 601px) {
    .rd-plan-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 600px) {
    .rd-plan-grid { grid-template-columns: 1fr; }
    /* v62: 原先此处有 `.rd-plan-tier.featured { transform: none; }`，
       用于抵消 .featured 的常驻抬升。那条抬升已在 v62 删除，
       五卡静止态本身即为 none，此覆盖已无作用对象，遂移除。
       （悬停抬升由 .rd-plan-tier:hover 统一提供，见触屏兜底段。） */
}

/* ---------- v51: 套餐区末尾备注行 ----------
   该 <p> 是 .rd-container 的直接子元素，此前【没有任何 CSS 定义】，
   因此继承 block 默认的 text-align: left → 视觉上贴在左侧，与上方居中的
   标题/卡片明显不齐。这里显式居中。
   注：不要用 text-align: justify，那会把中英混排的行内间距拉散。 */
.rd-plan-note {
    margin: 28px auto 0;
    text-align: center;
    color: var(--c-text-3);
    font-size: var(--fs-sm);
    line-height: 1.7;
}
.rd-plan-note a {
    color: var(--c-brand);
    font-weight: 600;
    text-decoration: none;
    border-bottom: 1px solid rgba(27, 92, 255, 0.35);
    padding-bottom: 1px;
    transition: border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.rd-plan-note a:hover {
    color: var(--c-brand-dark, var(--c-brand));
    border-bottom-color: var(--c-brand);
}

/* ---------- v36: 触屏兜底 ----------
   触屏设备没有 hover，若只写 :hover，手机上卡片永远不变蓝。
   用 @media (hover: none) 覆写：改为「按下即变色」，
   并把上浮幅度减半（手指按住时整卡大位移会显得晃）。
   同时保证移开手指后 :active 失效、颜色自动恢复。 */
@media (hover: none) {
    .rd-plan-tier:hover:not(:active) {
        background: #fff;
        border-color: transparent;
        transform: translateY(0);
        box-shadow:
            0 2px 4px rgba(15, 23, 42, 0.03),
            0 8px 28px rgba(15, 23, 42, 0.07);
    }
    .rd-plan-tier:active {
        background: var(--grad-brand);
        border-color: transparent;
        transform: translateY(-2px);
        box-shadow: var(--sh-glow);
    }
    .rd-plan-tier:active .tier-topline { background: rgba(255, 255, 255, 0.5); }
    .rd-plan-tier:active .tier-name,
    .rd-plan-tier:active .spec-row .spec-v { color: #fff; }
    .rd-plan-tier:active .tier-sub { color: rgba(255, 255, 255, 0.9); }
    .rd-plan-tier:active .tier-desc,
    .rd-plan-tier:active .spec-row .spec-k { color: rgba(255, 255, 255, 0.75); }
    .rd-plan-tier:active .tier-spec { border-top-color: rgba(255, 255, 255, 0.22); }
    .rd-plan-tier:active .spec-row { border-bottom-color: rgba(255, 255, 255, 0.18); }
    .rd-plan-tier:active .tier-icon svg { color: #fff; }
    /* v62: 原先此处有两条 featured 专属复位：
         `.rd-plan-tier.featured { transform: none; }`
         `.rd-plan-tier.featured:hover:not(:active) { background:#fff; transform:none; }`
       前者抵消已被删除的常驻抬升（无作用对象）；后者用于复位 PC 端
       .featured:hover 的 -10px —— 但那条规则也已在 v62 连同分支一起删除，
       PC 端悬停抬升现统一由 .rd-plan-tier:hover 提供（-6px），
       触屏下由上面的 :active 接管，两条复位均失去意义，遂移除。 */
    /* ⚠️ 保留：.featured 的 background:#fff 权重等同且声明在后，
       会把上面的 :active 蓝底盖掉 → 仍需 .featured 专属的 :active 规则。 */
    .rd-plan-tier.featured:active {
        background: var(--grad-brand);
        border-color: transparent;
        transform: translateY(-2px);
    }
}

/* ---------- 列表页 / 帮助页：搜索过滤 ---------- */
.rd-sub-item.is-hidden { display: none; }
.rd-list-empty {
    display: none;
    text-align: center;
    padding: 56px 24px;
    background: #fff;
    border: 1px dashed var(--c-border);
    border-radius: var(--r-lg);
    color: var(--c-text-3);
    font-size: var(--fs-base);
}
.rd-list-empty.show { display: block; }
/* 空态内的标题与说明（列表页后台无内容时展示，取代原先的静态假数据） */
.rd-list-empty-title {
    font-size: var(--fs-lg);
    font-weight: 600;
    color: var(--c-text);
    margin-bottom: 8px;
}
.rd-list-empty-desc {
    font-size: var(--fs-sm);
    color: var(--c-text-3);
    line-height: 1.7;
}
.rd-help-box.is-hidden { display: none; }
.rd-help-box ul li.is-hidden { display: none; }
.rd-help-empty {
    display: none;
    text-align: center;
    padding: 48px 24px;
    background: #fff;
    border: 1px dashed var(--c-border);
    border-radius: var(--r-lg);
    color: var(--c-text-3);
    font-size: var(--fs-base);
    margin-bottom: 8px;
}
.rd-help-empty.show { display: block; }
/* 帮助页搜索栏与分类区留白 */
.rd-help-search { margin-bottom: 32px; }

/* 封面图未配置的文章卡片：纯文字布局（v29） */
.rd-sub-item.no-cover { grid-template-columns: 1fr auto; }
@media (max-width: 720px) { .rd-sub-item.no-cover { grid-template-columns: 1fr; } }

/* 注：`.rd-article-cover` 样式已移除。
   封面图仅用于列表卡片（`.rd-sub-item .cover`），不再注入文章详情页正文。
   若日后需要，务必先确认产品口径「封面只做卡片缩略图」。 */
