/* ===========================================================================
   搭聆智服 官网 · 多页版式样式
   ===========================================================================
   ★ 为什么单独一个文件，而不是继续往 site.css 里加：
     site.css 是**首页那一版的版式**，它的缓存键（?v=）已经被
     tools/_cachekey-baseline-site.json 锚定。往里加规则就要升它的版本号，
     而版本号一升，全站 HTML 里的引用都得跟着改 —— 一次纯粹的"新增"
     却要动 6 个文件的版本号，改动面被无谓地放大。
     新开一个文件则天然是"新资源"，不触碰任何既有缓存键。

   ★ 加载顺序：pages.css 必须在 site.css **之后**引用。
     它只做两件事：① 新增内页专用组件；② 少量覆盖 site.css 里
     "只服务单页首页"的假设（例如 .header-actions 在窄屏的排布）。
     覆盖规则依赖后加载，顺序颠倒会被 site.css 压回去。

   ★ 只使用 site.css 已经定义的 CSS 变量（--brand / --ink / --r / --wrap…），
     不在这里重新定义颜色。原因：配色是 VI 的一部分，只有一处的口径；
     两处定义就会出现"改了 site.css 但内页还是旧色"的漂移。
   ========================================================================= */

/* ===========================================================================
   一、导航当前页高亮
   ===========================================================================
   单页版所有导航项都是 #锚点，不存在"当前页"这个概念。多页之后，
   访客需要知道自己在哪一页 —— 这是多页站最基本的一条可用性要求。
   ★ 高亮靠 `aria-current="page"` 而不是单独的 class：
     它是无障碍的**标准属性**，屏幕阅读器会念出"当前页"，
     而 class 只有视觉意义。一处属性同时满足两种需要，不多写一份状态。
   ========================================================================= */
.nav a.is-active,
.nav a[aria-current="page"] {
  color: var(--brand);
  background: var(--brand-light);
}

/* ===========================================================================
   二、内页页头（page-hero）
   ===========================================================================
   首页首屏是"情绪 + 卖点"；内页页头是"我在哪 + 这里有什么"。
   两者不能共用一套样式 —— 内页页头如果和首页一样高，用户每次点导航
   都要先滚过一整屏才能看到正文，多页站反而比单页更难用。
   ========================================================================= */
.page-hero {
  position: relative;
  padding: calc(var(--header-h) + 62px) 0 58px;
  /*
     ★ 2026-10-08 品牌色对齐：这里原来用的是旧主色 rgba(73,88,221,…)，
       随 site.css 一并迁到新主色 rgba(79,70,229,…)。
     ★ 同时把底从纯色 var(--bg) 换成一层极淡的竖向渐变 ——
       内页页头是"这页是干什么的"的第一印象，纯白底会让它和正文糊在一起，
       分不出"页头 / 正文"的层次。渐变只到 #fdfdff，几乎看不出是渐变，
       但页头与正文之间就有了虚实差。
  */
  background:
    radial-gradient(900px 320px at 12% -18%, rgba(79, 70, 229, .11), transparent 62%),
    radial-gradient(700px 300px at 88% -6%, rgba(34, 211, 238, .09), transparent 60%),
    linear-gradient(180deg, #f8f9fe 0%, #fdfdff 100%);
  border-bottom: 1px solid var(--line);
}
.page-hero-inner { max-width: 900px; }
.page-hero h1 {
  margin: 14px 0 0;
  /* ★ 2026-10-08：clamp(28px, 4vw, 48px) 在 1024 上算出 40.96px，不在刻度上。
     改成固定 48px，窄屏档在 ≤1023 里降到 32px（.section-head h2 同一套阶梯）。 */
  font-size: 48px;
  line-height: 1.2;
  letter-spacing: -.02em;
  color: var(--ink);
}
.page-hero-sub {
  margin: 20px 0 0;
  max-width: 760px;
  font-size: 18px;
  line-height: 1.85;
  color: var(--ink-3);
}
.page-hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: 32px;
}
/* 页头下方那行"锚点快捷入口"（长页面的目录） */
.page-jump {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 30px;
}
.page-jump a {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 15px;
  font-size: 14px;
  color: var(--ink-2);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 999px;
  transition: border-color .16s, color .16s, background .16s;
}
.page-jump a:hover { border-color: var(--brand); color: var(--brand); background: var(--brand-light); }

/* 面包屑 —— 多页站的"当前位置"指示 */
.crumb {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  color: var(--ink-3);
}
.crumb a { color: var(--ink-3); }
.crumb a:hover { color: var(--brand); }
.crumb .sep { color: #c7d1e0; }
.crumb .here { color: var(--ink-2); font-weight: 600; }

/* ===========================================================================
   三、功能矩阵：大块"图标 + 标题 + 说明 + 要点"行
   ===========================================================================
   首页的功能卡是"概览"（短句），内页的功能块是"讲透"（句子 + 要点清单）。
   ★ 用 <ul class="ticks"> 而不是 <p> 罗列要点：
     要点之间的关系是**并列项**，语义上就是列表。用段落 + 换行堆出来的
     视觉列表，屏幕阅读器会念成一大坨连续文本。
   ========================================================================= */
.feat-row {
  display: grid;
  grid-template-columns: 64px 1fr;
  gap: 24px;
  padding: 34px 0;
  border-top: 1px solid var(--line);
}
.feat-row:first-of-type { border-top: 0; padding-top: 0; }
.feat-row:last-of-type { padding-bottom: 0; }
.feat-row-icon {
  width: 64px; height: 64px;
  display: grid; place-items: center;
  border-radius: 18px;
  background: linear-gradient(140deg, var(--brand-light), #f6fbff);
  border: 1px solid #dfe6f5;
  color: var(--brand);
}
.feat-row-icon svg { width: 28px; height: 28px; }
.feat-row h2, .feat-row h3 { font-size: 24px; margin: 0 0 12px; letter-spacing: -.01em; }
.feat-row p { margin: 0; font-size: 16px; line-height: 1.85; color: var(--ink-3); }
.feat-row .ticks { margin-top: 16px; }

.ticks { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.ticks li {
  position: relative;
  padding-left: 26px;
  font-size: 14px;
  line-height: 1.75;
  color: var(--ink-2);
}
.ticks li::before {
  content: "";
  position: absolute;
  left: 4px; top: 9px;
  width: 7px; height: 12px;
  border-right: 2px solid var(--brand);
  border-bottom: 2px solid var(--brand);
  transform: rotate(42deg);
}
.ticks.is-dash li::before {
  border: 0;
  width: 12px; height: 2px;
  background: #c7d1e0;
  top: 13px;
  transform: none;
}

/* ===========================================================================
   四、解决方案卡（按行业 / 场景）
   =========================================================================== */
.sol-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; }
.sol-card {
  position: relative;                 /* 指针聚光层（site.css「统一交互层」）的定位基准 */
  display: flex;
  flex-direction: column;
  padding: 30px 28px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  /* 与 site.css 里那套"抬升 + 3D 微倾斜"用同一条曲线，避免两层过渡打架 */
  transition: transform .42s cubic-bezier(.16, 1, .3, 1),
              box-shadow .42s ease, border-color .42s ease;
}
/* ★ 2026-10-08：抬升量改由 --lift 承担（原为 transform: translateY(-4px)）。
   直接写 transform 会盖掉 site.css 交互层里的指针倾斜。 */
.sol-card:hover { --lift: -5px; box-shadow: var(--shadow); border-color: #cfdaea; }
.sol-card .sol-tag {
  align-self: flex-start;
  margin-bottom: 16px;
  padding: 4px 12px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .02em;
  color: var(--brand);
  background: var(--brand-light);
  border-radius: 999px;
}
.sol-card h3 { margin: 0 0 12px; font-size: 20px; }
.sol-card p { margin: 0 0 18px; font-size: 16px; line-height: 1.8; color: var(--ink-3); }
.sol-card .ticks { margin-top: auto; }

/* ===========================================================================
   五、步骤条（"怎么用"/"怎么开始"）
   ===========================================================================
   ★ 与首页的 4 步流程同构，但内页版用纵向排布：
     内页宽度更大、每步的文字更多，横排四列会把每列压到 200px 以内，
     中文在这个宽度下会频繁折行，读完一步要跳三次视线。
   ========================================================================= */
/* ★ 2026-10-08 修正一处"静默吃掉首页间距"的老 bug：
   这里原本是 `.steps { display: grid; gap: 0; counter-reset: step; }`。
   它是为**内页的纵向步骤条**写的（内页用 .step-item / .step-num），
   但它在 pages.css（后加载）里、选择器又和首页那排横向 4 步完全同名 ——
   于是首页 .steps 的 gap 被覆盖成 0，四张步骤卡一直紧贴在一起（实测 gap 0px）。
   而内页其实**一个都没用** .step-item（全站只有 index.html 有 .steps）。
   改成只在真有 .step-item 时生效：:has 不支持的内核这条直接不匹配，
   首页照旧吃 site.css 的 gap: 22px —— 两个方向都不会更糟。 */
.steps:has(.step-item) { display: grid; gap: 0; counter-reset: step; }
.step-item {
  position: relative;
  display: grid;
  grid-template-columns: 56px 1fr;
  gap: 22px;
  padding-bottom: 34px;
}
.step-item:last-child { padding-bottom: 0; }
/* 连接线：画在编号圆点下方，最后一项不画（否则会拖出一条悬空的线） */
.step-item:not(:last-child)::before {
  content: "";
  position: absolute;
  left: 27px; top: 56px; bottom: 6px;
  width: 2px;
  background: linear-gradient(var(--line), var(--line-2));
}
.step-num {
  counter-increment: step;
  width: 56px; height: 56px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--bg);
  border: 2px solid var(--brand);
  color: var(--brand);
  font-size: 20px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.step-item h3 { margin: 12px 0 10px; font-size: 20px; }
.step-item p { margin: 0; font-size: 16px; line-height: 1.85; color: var(--ink-3); }

/* ===========================================================================
   六、对比表
   ===========================================================================
   ★ 窄屏不做"横向滚动"，改成"每档一张卡、字段名在前"（见媒体查询）。
     横向滚动的表格在手机上几乎没人会去滑，等于信息不可见；
     而这张表的每一行恰恰是客户挑套餐时最想比对的那几项。
   ========================================================================= */
.cmp-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.cmp-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 16px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r);
  overflow: hidden;
}
.cmp-table th, .cmp-table td {
  padding: 15px 18px;
  text-align: left;
  border-bottom: 1px solid var(--line-2);
  vertical-align: top;
}
.cmp-table thead th {
  background: var(--bg-alt);
  font-size: 14px;
  font-weight: 700;
  color: var(--ink);
  white-space: nowrap;
}
.cmp-table thead th.is-rec { color: var(--brand); }
.cmp-table tbody th {
  font-weight: 600;
  color: var(--ink-2);
  background: #fcfdff;
  width: 22%;
}
.cmp-table tbody tr:last-child th { border-bottom: 0; }
.cmp-table td { color: var(--ink-3); }
.cmp-table .yes { color: var(--brand); font-weight: 600; }
.cmp-table .no { color: #a9b4c6; }

/* ===========================================================================
   七、中段 CTA 横幅 / 文末 CTA
   ===========================================================================
   .cta-band 是内页中段那条"看完这一节，要不要试试"的转化带；
   它与首页 .final-cta 视觉一致但可重复出现，所以单独命名，
   免得改一处 final-cta 的样式把内页所有横条一起改掉。
   ========================================================================= */
.cta-band {
  padding: 44px 40px;
  border-radius: var(--r-xl);
  background: linear-gradient(135deg, #0b1120, #16203a 62%, #1c2a4d);
  color: #fff;
  text-align: center;
}
/* ★ 2026-10-08：原来是 clamp(24px, 2.6vw, 32px) —— 1440 上 32px 尚可，
   但 1024 上算出 26.624px，落在刻度外。改成固定 32px + 断点下探，
   与 .section-head h2 的 48/32/24 三档阶梯保持一致。 */
.cta-band h2 { color: #fff; margin: 0 0 12px; font-size: 32px; }
.cta-band p { margin: 0 auto 26px; max-width: 620px; color: var(--dark-ink-2); font-size: 16px; line-height: 1.8; }
.cta-band .btn-outline { background: transparent; color: #fff; border-color: rgba(255, 255, 255, .34); }
.cta-band .btn-outline:hover { border-color: #fff; color: #fff; background: rgba(255, 255, 255, .08); }
.cta-band-actions { display: flex; flex-wrap: wrap; gap: 14px; justify-content: center; }

/* 深色底上的次级按钮：site.css 的 .btn-ghost 是为浅底写的，深底上不可读 */
.section-dark .btn-ghost,
.cta-band .btn-ghost { color: var(--dark-ink-2); }
.section-dark .btn-ghost:hover,
.cta-band .btn-ghost:hover { color: #fff; background: rgba(255, 255, 255, .10); }

/* ===========================================================================
   八、长文排版（关于我们 / 条款摘要）
   =========================================================================== */
.prose { max-width: 820px; }
.prose h2 { font-size: 24px; margin: 44px 0 16px; letter-spacing: -.01em; }
.prose h2:first-child { margin-top: 0; }
.prose h3 { font-size: 18px; margin: 30px 0 12px; }
.prose p { margin: 0 0 16px; font-size: 16px; line-height: 1.95; color: var(--ink-2); }
.prose ul { margin: 0 0 18px; padding-left: 22px; }
.prose li { margin-bottom: 9px; font-size: 16px; line-height: 1.85; color: var(--ink-2); }
.prose strong { color: var(--ink); }

/* ===========================================================================
   九、信息瓦片（关于我们：主体信息 / 联系方式）
   =========================================================================== */
.tiles { display: grid; grid-template-columns: repeat(2, 1fr); gap: 18px; }
.tile {
  padding: 22px 24px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r);
}
.tile dt {
  font-size: 14px;
  font-weight: 600;
  letter-spacing: .03em;
  color: var(--ink-3);
  margin-bottom: 8px;
}
.tile dd { margin: 0; font-size: 16px; color: var(--ink); line-height: 1.7; }
.tile dd a { color: var(--brand); }

/* ===========================================================================
   十、空槽位（案例区"待补充真实素材"）
   ===========================================================================
   ★ 与 site.css 的 .case-card 同一套语义，只是内页是两列 / 三列的差异，
     所以这里只补栅格，不改卡片本身的观感 —— 两处的"空槽位"必须长得一样，
     否则访客会以为是两种不同的东西。
   ========================================================================= */
.case-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 22px; }
.case-grid.is-three { grid-template-columns: repeat(3, 1fr); }

/* ===========================================================================
   十一、注册 / 登录页
   ===========================================================================
   ★ 表单页刻意"窄"（460px），且**不挂客服挂件**：
     注册是转化终点，页面上任何多余的出口都是在把刚到手的线索送走。
   ★ 用 --auth-* 前缀单独命名，是因为这一页的卡片样式与营销卡的
     悬停抬升语义不同（表单卡片需要的是"稳定、可信、不动"）。
   ========================================================================= */
.auth-shell {
  min-height: calc(100vh - var(--header-h));
  display: flex;
  align-items: flex-start;
  justify-content: center;
  /* ★ 2026-09-29 高度预算：上内距 56→32、下内距 80→56。
     实测问题是"提交按钮掉到 1080p 折叠线以下"（Edge 154 实测：
     卡片 1131px 高、从 y=128 起，在 1920×940 下底边超出 288px）。
     上内距 56px 是把卡片往下推的第一笔开销 —— 它一分钱信息都不承载，
     却正好抵掉 56px 可视高度。完整高度账见本文件第十五节。 */
  padding: 26px 24px 52px;
  background:
    radial-gradient(800px 320px at 50% -12%, rgba(73, 88, 221, .10), transparent 62%),
    var(--bg-alt);
}
.auth-card {
  width: 100%;
  max-width: 460px;
  /* ★ 2026-09-29：内距 36/34/32 → 28/32/26（省 14px）。
     max-width 在 ≥1024px 时放到 760px 并改两列布局 —— 见第十五节，
     那里有完整的高度账（为什么必须动布局、不能只压间距）。 */
  padding: 26px 32px 22px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: 0 18px 44px -26px rgba(7, 13, 27, .22);
}
.auth-card h1 { margin: 0 0 6px; font-size: 24px; letter-spacing: -.01em; }
.auth-card .auth-sub { margin: 0 0 14px; font-size: 14px; color: var(--ink-3); line-height: 1.7; }
.auth-card .field { margin-bottom: 18px; }
/* 验证码一行：输入框 + 发送按钮 */
.code-row { display: grid; grid-template-columns: 1fr 132px; gap: 10px; }
.code-row .btn { min-height: 46px; white-space: nowrap; }
.auth-foot { margin-top: 14px; font-size: 14px; color: var(--ink-3); text-align: center; }
.auth-foot a { color: var(--brand); font-weight: 600; }
/* 微信登录占位：置灰不可点，但要让人看得出"以后会有"。
   ★ margin-top 26→20：这条分隔线之上没有任何信息，只是分组留白。 */
.auth-alt { margin-top: 16px; padding-top: 22px; border-top: 1px solid var(--line-2); }
.auth-alt-btn {
  width: 100%;
  min-height: 46px;
  display: flex; align-items: center; justify-content: center; gap: 10px;
  font-size: 16px;
  color: #9aa6bb;
  background: var(--bg-alt);
  border: 1px dashed #d7dfec;
  border-radius: var(--r-sm);
  cursor: not-allowed;
}
.auth-alt-btn svg { width: 18px; height: 18px; fill: #b6c0d0; }
.auth-alt-tip { margin: 10px 0 0; font-size: 12px; color: var(--ink-3); text-align: center; font-weight: 400; }

/* ===========================================================================
   十二、对 site.css 的少量覆盖（只针对"单页假设"的部分）
   ===========================================================================
   ★ 每一条都写明"为什么单页版那样写没问题、多页版必须改"。
     没有理由的覆盖会变成下次改动时的谜题。
   ========================================================================= */

/* ① 顶栏右侧动作区在窄屏要收得住。
     单页版这里放的是「查询订单」+「立即开通」两个中文四字按钮，
     多页版换成「查订单」+「立即免费注册」—— 后者是 6 个字，
     在 375px 上会和汉堡按钮一起把顶栏顶成两行。 */
@media (max-width: 760px) {
  .header-actions { gap: 6px; }
  .header-actions .btn { padding: 8px 12px; font-size: 14px; min-height: 38px; }
  .header-actions .btn-ghost { display: none; }
}

/* ② 移动端导航展开后是"从顶栏往下铺开的一列"，
     多页版链接数从 6 条涨到 7 条，需要给出滚动空间。
     ★ 断点用 760px 与 site.css 的第 1767 行保持一致 ——
       那里是 .nav { display: none } / .nav-toggle { display: flex } 的切换点。
       写成别的值（比如 1023）会让 761~1023px 之间出现"横排导航被限高"的
       无用规则；虽然此刻无害，但下次改动时它会变成一句看不懂的代码。 */
@media (max-width: 760px) {
  .nav {
    max-height: calc(100vh - var(--header-h));
    overflow-y: auto;
  }
}

/* ③ 内页的栅格在窄屏一律收敛为单列 —— 与首页保持同一断点，
     免得访客在首页看到单列、点进内页又变成两列。 */
@media (max-width: 1023px) {
  .sol-grid,
  .tiles,
  .case-grid,
  .case-grid.is-three { grid-template-columns: 1fr; }
  .feat-row { grid-template-columns: 1fr; gap: 16px; }
  .feat-row-icon { width: 54px; height: 54px; border-radius: 15px; }
  .page-hero { padding: calc(var(--header-h) + 44px) 0 44px; }
  .page-hero-sub { font-size: 16px; }
  /* ★ 标题/转化带降到窄屏档（与 site.css 的 48/32/24 阶梯对齐） */
  .page-hero h1 { font-size: 32px; }
  .cta-band h2 { font-size: 28px; }
  .cta-band { padding: 34px 24px; }
}

/* ④ 对比表在窄屏"表格 → 卡片"。
     做法是让表格元素在视觉上退化成块，用 data-label 把列名搬到每格前面。
     ★ 保留 <table> 结构、不换成 div：结构与语义不能为了响应式而牺牲，
       屏幕阅读器仍然按"表格 + 行列"来念。 */
@media (max-width: 760px) {
  /* ★ 手机上板块标题统一 24px（与 site.css 的 .section-head h2 同档），
     48 / 32 / 28 / 24 的四档阶梯收口。 */
  .cta-band h2 { font-size: 24px; }
  .cmp-wrap { overflow-x: visible; }
  .cmp-table, .cmp-table thead, .cmp-table tbody, .cmp-table tr, .cmp-table th, .cmp-table td {
    display: block;
    width: auto;
  }
  .cmp-table thead { display: none; }
  .cmp-table {
    border: 0; border-radius: 0; background: transparent;
  }
  .cmp-table tbody tr {
    margin-bottom: 16px;
    padding: 18px 20px;
    background: var(--bg);
    border: 1px solid var(--line);
    border-radius: var(--r);
  }
  .cmp-table tbody th {
    background: transparent;
    padding: 0 0 12px;
    width: auto;
    font-size: 16px;
    color: var(--ink);
  }
  .cmp-table td {
    padding: 7px 0;
    border-bottom: 0;
    display: grid;
    grid-template-columns: 104px 1fr;
    gap: 10px;
  }
  /* 列名由 HTML 的 data-label 提供，这里只负责"把它显示在值的前面" */
  .cmp-table td::before {
    content: attr(data-label);
    font-size: 14px;
    font-weight: 600;
    color: var(--ink-3);
  }
}

/* ⑤ 步骤条在窄屏把"编号 + 正文"的两列并成一行块。
     56px 的编号列在 320px 屏上占比过大，正文只剩 220px。 */
@media (max-width: 480px) {
  .step-item { grid-template-columns: 44px 1fr; gap: 16px; }
  .step-num { width: 44px; height: 44px; font-size: 18px; }
  .step-item:not(:last-child)::before { left: 21px; top: 46px; }
  .code-row { grid-template-columns: 1fr; }
}

/* ===========================================================================
   十三、表单细节：必填星号 / 协议勾选行 / 联系方式行
   ===========================================================================
   ★ .req 用单独一个 span 而不是把 "*" 直接写进 label 文本：
     屏幕阅读器会把星号念成「星号」，读起来像乱码。给它 aria-hidden
     并由 label 的 required 语义（或附近的提示文字）来传达"必填"，
     视觉与听觉各拿各的那一份。
   ========================================================================= */
.req { color: #e04242; font-weight: 700; margin-left: 2px; }

/* 协议勾选行：checkbox 与文字要能整行点（移动端 12px 的方框很难点准） */
.agree-line {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin: 4px 0 6px;
  font-size: 14px;
  line-height: 1.7;
  color: var(--ink-2);
  cursor: pointer;
}
.agree-line input[type="checkbox"] {
  flex: 0 0 auto;
  width: 17px; height: 17px;
  margin: 3px 0 0;
  accent-color: var(--brand);
  cursor: pointer;
}
.agree-line a { color: var(--brand); }

/*
   联系方式行（#contactBlock 的渲染目标）
   ★ 这一块在"业务信息未配置"时会显示若干条「待补充：…」，
     所以必须允许换行（word-break）—— 那句提示很长，
     不允许换行会把容器撑宽、把页面顶出横向滚动条。
     site.css 里 .footer-inner > * 的 min-width:0 是同一个坑的另一个修法。
*/
.contact-lines {
  margin-top: 22px;
  font-size: 14px;
  line-height: 1.9;
  color: var(--dark-ink-2);
  word-break: break-word;
}
.contact-lines b { color: #fff; font-weight: 600; }

/* 浅色底上的版本（联系页 / 关于页的 .tile 里用的是浅底） */
.tile .contact-lines { margin-top: 0; color: var(--ink-2); font-size: 14px; }
.tile .contact-lines b { color: var(--ink); }
.tile .contact-lines .cfg-missing { white-space: normal; }

/* ===========================================================================
   十四、注册页的浅色表单（覆盖 site.css 的深色下单表单样式）
   ===========================================================================
   ★ 为什么必须覆盖：site.css 里的 .field label / .field input / .field-error
     是**为深色下单表单写的** —— label 用 #e2e8f0（近白）、输入框实底 #141c2e
     （深蓝黑）、错误文案 #fca5a5（浅红）。注册页把同一套 .field 复用到
     白色的 .auth-card 上，不覆盖就会出现最糟的组合：
       白底 + 近白 label（等于看不见）+ 深色输入框（像别的网站嵌进来的控件）。
   ★ 只覆盖颜色 / 投影这类"皮肤"属性，**不动 padding / 圆角 / 字号 / min-height**
     —— 表单控件的尺寸在注册页和下单区本来就该完全一致，改了才是真坑
     （用户在两页之间来回时会觉得"这个站有两套表单"）。
   ========================================================================= */
.auth-card .field label { color: var(--ink-2); }

.auth-card .field input {
  background-color: var(--bg);
  border-color: var(--line);
  box-shadow: none;
  color: var(--ink);
}
.auth-card .field input:hover {
  background-color: var(--bg);
  border-color: #cbd5e1;
}
.auth-card .field input:focus {
  background-color: var(--bg);
  border-color: var(--brand);
  box-shadow: 0 0 0 3px rgba(73, 88, 221, .16);
}
/*
   占位符用「淡灰」—— 它必须**明显浅于标题**。这是功能性的，不是审美偏好。
   ---------------------------------------------------------------------------
   ★ 为什么"够淡"是必要的：placeholder 的色值一旦贴近 label（标题），
     用户扫一眼表单会以为"这个框里已经有字了"，于是跳过不填 ——
     这是占位符最典型的失效方式，比"字不够清楚"更常见、也更难在回访里发现。

       label（标题）  --ink-2  #33405a  → 白底 10.39:1
       本行（示例）            #8b98ab  → 白底  2.93:1   （与标题相差 3.55 档）
       输入后的真实文字 --ink  #070d1b  → 白底 19.40:1

     三档之间各隔开一倍以上，扫视时"标题 / 待填 / 已填"一眼可辨。

   ★ 2026-09-29 二次更正（如实记录往返，不掩饰）：
     上一轮我按这条注释里"白底要压深一档、低于 4.5:1 不可读"那句话，
     把值从 #96a2b8（2.57:1）压到了 #63718a（4.93:1）。
     那句话本身没错，但**它只算了对比度，没算分层** ——
     压深之后占位符与标题只差 2.11 档，实测截图里"例如：上海某某科技有限公司"
     看着就像已填好的内容，恰好落进上面那个失效方式里。
     所以正确解法不是"把值压深让注释成立"，而是**改注释、让值淡下来**。

   ★ 取值 #8b98ab（2.93:1）的取舍（明说）：
     它低于 WCAG 2.1 AA 对正文的 4.5:1。理由是 placeholder 属于
     "输入示例"而非需要逐字精读的正文，且分层本身也是可读性的一部分；
     同时它仍高于本站最淡一档 #9aa8bd（2.41:1，搜索框 / 反馈表单在用），
     没有淡到发糊。若将来要完全达标，该改的是"把示例移到框外"，
     而不是把这个色值再压深回去。
*/
.auth-card .field input::placeholder { color: #8b98ab; }

.auth-card .field-error { color: #dc2626; }

/*
   ★ 2026-09-29：空的错误容器不许占位。
   ---------------------------------------------------------------------------
   实测发现的最大一笔"白占高度"：site.css 的 .field-error 带 margin-top: 8px，
   而 register.html 为每个可能报错的字段都预置了一个空的 <div class="field-error">。
   空 div 没有高度，但 **margin 照样生效** —— 7 个字段里有 5 个长期是空的，
   于是这张卡片里稳稳地躺着 5 × 8 = 40px 什么都没有的间距。
   40px 正好是这次"差 4px 放不下"要凑的量级，而且它一分钱信息都不承载。

   ★ 为什么不用"改小 margin-top"：那会在报错时也变小，错误行会贴住输入框。
     用 :empty 才表达出真正想要的语义 —— **没有错误时，这一行不存在**；
     有错误时，8px 间距和红字一起出现。

   ★ 为什么只覆盖 .auth-card、不去改 site.css 里那条：
     同样这条规则如果放到 site.css，会同时改变首页/定价页深色下单表单的行高，
     那是另一套页面、没有高度压力，改它属于范围外。本页的问题在本页解决。
   代价（明说）：报错时该行会"长高"27px，把下面的内容推一下。
   这是表单的常见行为，而且比"永远占着 40px 空白"划算得多。
*/
.auth-card .field-error:empty { display: none; }

/*
   错误态：出错的**那个框**自己也要变色。
   ★ 只靠下面一行红字是不够的 —— 手机上红字离输入框有 8~20px，
     长表单里用户会盯着红字读，却找不到该改哪个框。
     .is-invalid 由 register.js 加上，同时配 aria-invalid 给屏幕阅读器。
*/
.auth-card .field.is-invalid input { border-color: #dc2626; }
.auth-card .field.is-invalid input:focus { box-shadow: 0 0 0 3px rgba(220, 38, 38, .14); }

/* 提示条在窄卡片里要收住：site.css 的 .notice 是给整幅宽的板块调的
   （margin-top: 30px / padding 18px 22px），塞进 460px 的卡片会顶掉按钮。 */
.auth-card .notice { margin: 4px 0 16px; padding: 13px 16px; font-size: 14px; }

/* 按钮下的小字说明：site.css 用的是 --dark-ink-3（#7b8aa6），
   那是给深色区调的，在白卡上偏灰；改回浅色区的次要文字色。 */
.auth-card .actions-hint { margin: 14px 0 0; color: var(--ink-3); }

/*
   开户成功提示（#regDone 的内容，由 register.js 的 renderDoneNotice() 填进来）
   ---------------------------------------------------------------------------
   ★ 2026-09-29 收窄了它的职责：
     改造前它是**唯一的**成功展示，里面放了一个 <dl> 列企业名 / 企业标识 /
     登录账号。现在主呈现换成了弹窗（.reg-dlg-*，见下），
     它就退化成"关掉弹窗后信息不丢"的兜底 —— 所以只需要一行状态 + 账号
     + 一个常驻的入口链接，不该再抢弹窗的注意力。
     <dl> 那三条已经移到弹窗里（那边空间够、也更该显眼），
     这里的 dl 规则随之删除，避免留下永远不会被命中的死样式。
*/
.auth-card .reg-done strong { display: block; margin-bottom: 6px; font-size: 16px; }
.auth-card .reg-done span { font-size: 14px; color: var(--ink-2); line-height: 1.8; }
.auth-card .reg-done b { color: var(--ink); }
/* 常驻入口链接：做成一个内联链接而不是大按钮 —— 弹窗里已经有主按钮了，
   同一屏出现两个同权重的"进入管理后台"会让用户不知道该点哪个。 */
.auth-card .reg-done .reg-done-link {
  display: inline-block;
  margin-top: 10px;
  font-size: 14px;
  font-weight: 600;
  color: var(--brand);
  text-decoration: none;
}
.auth-card .reg-done .reg-done-link:hover { text-decoration: underline; }
/* 「管理后台入口稍后开放」这类提醒要弱于正文，不能抢走"账号已开通"的注意力 */
.auth-card .reg-done .reg-hint-weak { color: var(--ink-3); display: block; margin-top: 6px; }
/* 提示条里的按钮要跟上下的文字拉开距离，否则视觉上粘成一块 */
.auth-card .notice > .btn { margin-top: 14px; }

/* ===========================================================================
   十四·补、注册成功弹窗（.reg-dlg-*，2026-09-29）
   ===========================================================================
   【外层壳子复用 site.css 的 .oc-overlay / .oc-dialog】
     那是订单凭证浮层（order-card.js）用的一套，已经带了：
       · z-index 9000、遮罩 rgba(5,7,15,.8)、淡入 / 弹入动效
       · ≤560px 自动变「底部抽屉」（贴底、只留上圆角、max-height 92vh）
       · body.oc-lock 锁滚动
     本页不加载 order-card.js，但 .oc-* 是**纯 CSS**、在 site.css 里，
     register.html 已引入 —— 所以直接可用，不额外请求、不重复实现响应式。
     下面只写"壳子里装什么"。

   【配色一律走 :root 令牌，不写死色值】
     弹窗白底，正文用 --ink-2、次要说明 --ink-3、分隔线 --line，
     强调用 --brand / --ok。深色令牌（--dark-*）在这里一个都不能用 ——
     那是首屏与页脚深色区专用的，用在白卡上就是白底白字。
   =========================================================================== */

/* ---- 顶部"账号已开通"区 ---- */
.reg-dlg .oc-body { background: var(--bg); }

.reg-dlg-hero { display: flex; gap: 12px; align-items: flex-start; }
.reg-dlg-check {
  flex: 0 0 auto;
  width: 34px; height: 34px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  background: #ecfdf5;            /* --ok(#10b981) 的极浅底，无令牌故直写 */
  color: var(--ok);
}
.reg-dlg-check svg { width: 20px; height: 20px; }
.reg-dlg-hero-t { margin: 4px 0 0; font-size: 16px; font-weight: 700; color: var(--ink); }
.reg-dlg-hero-s { margin: 4px 0 0; font-size: 14px; line-height: 1.7; color: var(--ink-3); }

/* ---- 登录信息三条（标签-值对）----
   ★ 用 <dl> 而不是若干行文字：企业名 / 企业标识 / 登录账号是三个
     "标签-值"对，用定义列表在结构与读屏上都更准确，
     也天然对齐（不用手写空格去凑）。 */
.reg-dlg-rows {
  margin: 16px 0 0;
  padding: 14px 16px;
  display: grid;
  grid-template-columns: 76px 1fr;
  gap: 8px 12px;
  background: var(--bg-alt);
  border-radius: var(--r);
}
.reg-dlg-rows dt { font-size: 14px; color: var(--ink-3); }
.reg-dlg-rows dd {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  color: var(--ink);
  word-break: break-word;   /* 企业名 / 邮箱可能很长，不许撑破弹窗宽度 */
}
.reg-dlg-tip { margin: 12px 0 0; font-size: 12px; line-height: 1.75; color: var(--ink-3); font-weight: 400; }
.reg-dlg-tip b { color: var(--ink-2); }

/* ---- 升级引导区 ----
   ★ 与上面"登录信息"之间用实线分隔：两件事的**优先级不同** ——
     先让用户拿到账号，再谈套餐。不做分隔就会读成一整段，套餐那段被忽略。 */
.reg-dlg-up {
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
}
.reg-dlg-up-h {
  margin: 0 0 8px;
  font-size: 14px;
  font-weight: 700;
  color: var(--ink);
}
/* 标题前那个小色块：让"你现在是免费版"这句被一眼扫到，而不是当正文读过去 */
.reg-dlg-up-h::before {
  content: "";
  display: inline-block;
  width: 4px; height: 14px;
  margin-right: 8px;
  vertical-align: -2px;
  border-radius: 2px;
  background: var(--brand);
}
.reg-dlg-up-l { margin: 0 0 14px; padding-left: 18px; }
.reg-dlg-up-l li {
  margin: 0 0 8px;
  font-size: 14px;
  line-height: 1.75;
  color: var(--ink-2);
}
.reg-dlg-up-l li:last-child { margin-bottom: 0; }
.reg-dlg-up-l b { color: var(--ink); }

/* ---- 窄屏：底部抽屉形态下，头部/脚部要压紧，否则正文只剩很小一截 ---- */
@media (max-width: 560px) {
  .reg-dlg .oc-head { padding: 12px 14px; }
  .reg-dlg .oc-head strong { font-size: 16px; }
  .reg-dlg .oc-body { padding: 14px; }
  .reg-dlg .oc-foot { padding: 12px 14px; }
  .reg-dlg-rows { grid-template-columns: 68px 1fr; padding: 12px; }
}

/* ===========================================================================
   十五、注册表单两列布局：把「1080p 一屏注册完」变成可量化的目标（2026-09-29）
   ===========================================================================
   【问题（Edge 154 实测，不是估算）】
     注册卡片高 1131px、从 y=128 起（顶栏 72 + 上内距 56）。
     1080p 最常见的可用视口是 1920×940（减掉标题栏 + 标签页/地址栏 + 一条书签栏），
     卡片底边超出 288px —— 用户填到手机号那几行时，**看不到「立即免费注册」按钮**。
     连 1080 满屏（无边）也超出 178px。所以这不是"有点长"，是"任何 1080p 视口都放不下"。

   【高度账：为什么必须动布局，而不是"把留白调小一点"】
     每个字段的纵向节奏（实测）：label 26 + 间距 9 + 输入框 52 + 字段行距 18 = 105px
       单列 6 个字段 = 630px ＋ 本次新增「确认密码」= 735px
       两列 → 4 行 = 396px                    ← 省约 340px
     而"压留白"能挤出来的上限只有 100px 出头（把全部间距归零也没有 300px）。
     结论：**行数是唯一的量级杠杆**，间距只能在行数定下来之后做微调。

   【布局决定】
     · 只在 ≥1024px 生效：平板 / 手机保持单列 ——
       窄屏高度压力小、横向空间更紧，硬塞两列会把输入框压到 150px 上下，
       输入的手机号会显示不全。
     · 卡片 max-width 460 → 760px：760 是"两列各 337px 还够填手机号"的下限。
     · 字段**先后顺序与原来完全一致**，两列只是让它们两两同行：
         企业名称 ｜ 手机号      两个"主体信息"
         短信验证码              整行（输入框必须和"获取验证码"按钮在一起）
         登录密码 ｜ 确认密码    两个"凭据"（浏览器密码管理器也认这种相邻关系）
         联系人   ｜ 邮箱        两个选填项
       没有任何字段为了凑格子而挪位 —— 顺序是"表单怎么填"的一部分。
   ========================================================================= */

/*
   标签行：把「格式提示」常驻在 label 右侧（同一行、紧跟标签）。
   ★ 为什么不把提示放在输入框下面再加一行：那要多占 27px，
     而这一页的整个问题就是高度（4 行 × 27 = 108px）。
   ★ 为什么不能只靠 placeholder：占位符在用户敲下第一个字符时**就消失了**，
     而"至少 8 位 + 字母 + 数字"恰恰是他打字时才需要看的信息 ——
     等于在最需要它的那一刻把提示收走。
   ★ 提示紧跟标签、**左对齐**（试过推到该字段的最右端，不行）：
     两列布局下"推到最右端"会让左列字段的提示正好贴住右列的标签，
     中间只剩 27px，读起来像是右列标签的一部分（实测截图确认过）。
     紧跟标签则天然与右列隔开一整段列间距。
   ★ 用 grid 而不是 flex：行高由 26px 的 label + 9px 外边距确定，
     与普通 label 的 26 + 9 逐像素一致，两种行不会出现 2px 的节奏差。
*/
.label-row {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: baseline;
  column-gap: 8px;
  margin-bottom: 9px;          /* ← 必须与 .field label 的 margin-bottom 相同 */
}
.auth-card .label-row label { margin-bottom: 0; }
.auth-card .label-row .field-hint { margin-top: 0; }

/*
   提示文字的颜色（覆盖 site.css 的 .field-hint —— 那个色是给深色底调的）
   ★ 对比度实测（白底；4.5:1 是 WCAG 2.1 AA 对正文的可读线）：
       --dark-ink-3 #7b8aa6 → 3.48:1  ✗（site.css 的默认值）
       --ink-3      #6b7a90 → 4.36:1  ✗ 差一点
       #63718a              → 4.93:1  ✓ 采用
   不直接复用 --ink-3 是因为它卡在 4.36:1：看起来"差不多"，
   但这类"差一点"正是复审时会被逐条挑出来的东西，不如一次给足。
*/
.auth-card .field-hint { color: #63718a; }
/* 密码已符合要求时的绿色（白底 5.26:1）。不用红色系表示"通过"，
   也刻意与错误态的 #dc2626 拉开 —— 两者可能同时出现在同一屏。 */
.auth-card .field-hint.is-ok { color: #0f7b57; }

@media (min-width: 1024px) {
  .auth-card { max-width: 760px; }

  .form-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    /* 列间距 26px：不是随便定的 —— 左列字段的"格式提示"要和右列的标签
       一眼分得开（18px 时实测两者只隔 27px，读起来会串）。 */
    column-gap: 26px;
    row-gap: 11px;
  }
  /* 网格里行距由 row-gap 统一管，字段自己的 margin-bottom 必须清零 ——
     否则每行下方会多出 18px，4 行白丢 72px（而 72px 正是这次要省的东西）。 */
  .auth-card .form-grid > .field { margin-bottom: 0; }
  /* 验证码整行跨两列 */
  .form-grid > .field.is-full { grid-column: 1 / -1; }
}

/* ===========================================================================
   十六、帮助中心：左分类菜单 + 右内容（2026-10-09，常见问题改版）
   ===========================================================================
   【为什么改】
     改版前 faq.html 是「5 个分区 + 18 条 <details> 手风琴」。
     手风琴的每条答案都困在 faq.html 一个 URL 里：
       · 搜「注册要多久」只能落到 /faq.html，落不到那一条；
       · 想单独把某条答案发给客户，只能发「faq.html 打开后往下数第 3 条」；
       · AI 搜索（GEO）引用不到任何一条独立答案。
     所以改成：**左分类菜单（导航）+ 右内容（长文）**，
     每条答案有自己的地址 /faq/<slug>.html。

   【为什么左菜单要"盖章"而不是 JS 渲染】
     菜单链接是爬虫发现详情页的主要路径。若由 JS 注入，
     不执行 JS 的爬虫（国内引擎里不少）就看不到任何一篇文章。
     与顶栏 / 页脚同一处理：模块文件 tools/_lib/faq-index.js 是唯一来源，
     由 tools/stamp-faq-nav.js 盖章进各页 —— 一处改，全站生效。

   【为什么详情页的 hero 要"矮"一档】
     详情页的重点是正文，不是"我在哪"。用完整高度的内页页头，
     访客每次点一篇文章都要先滚过一整屏才看到答案 ——
     而这类页面的访客 90% 是带着具体问题进来的。见 .page-hero-compact。

   【2026-10-09 第二轮打磨（用户反馈驱动）】
     ① 左菜单 18 条全平铺 → 侧栏比一屏还高，长出又窄又贴边的滚动条。
        ⚠️ 中间试过 <details> 折叠，**被用户否掉了**（"手风琴不如之前一目了然"）——
           18 条不属于长导航，平铺才扫得完。最终 = 平铺 + 自己画的 6px 细滚动条。
           详见 tools/_lib/faq-index.js 的 renderNav。见 16.2。
     ② 点左菜单底部的条目 → 跨页跳转 → 回到顶部后"不知道自己点的是哪篇"
        ⇒ 正文列顶部加一条**常驻**的「分类 + 文章标题」条，并跟着滚动。见 16.7。
        ⚠️ 中间试过"页头滚出视口后才浮出"，同样被用户否掉 ——
           困惑发生在刚跳转的那一刻，晚出现的提示没用。**必须进门就可见**。
     ③ 整页硬刷新显得"僵硬" ⇒ 站内跨页过渡，见 site.css 的 @view-transition 段。
     ④ 点了左菜单下半部分的条目，页面**整页跳到顶部、从页头重新开始读**
        ⇒ 站内所有指向详情页的链接（左菜单 / 首页卡片 / 上下篇 / 正文互链）
          一律带 `#article` 锚点，直接落到正文列顶端 = 那条标题条的位置，
          页头整段被跨过。见 16.8。落点数值与 16.7 的吸附线是同一条线。
   ========================================================================= */

/* ---- 16.1 两栏骨架 ---------------------------------------------------- */
.help-layout {
  display: grid;
  /* 272px：中文分类名最长的「技术与接入」6 字 + 缩进后仍能一行放下；
     再窄会出现「技术与接\n入」这种把一个词劈开的折行。 */
  grid-template-columns: 272px minmax(0, 1fr);
  gap: 56px;
  align-items: start;
}
.help-content { min-width: 0; }

/* ---- 16.2 左侧分类菜单（折叠式） -------------------------------------- */
.help-nav {
  /* 跟随滚动，但到距顶栏 24px 处停住 —— 免得它被顶栏盖住半截 */
  position: sticky;
  top: calc(var(--header-h) + 24px);
  max-height: calc(100vh - var(--header-h) - 48px);
  overflow-y: auto;
  padding: 20px 14px 20px 18px;
  background: var(--bg-alt);
  border: 1px solid var(--line);
  border-radius: var(--r);

  /* ★ 细滚动条（2026-10-09，用户反馈"粗的不美观"）。
     18 条平铺时侧栏在 1080p 以下必然超出视口，这条滚动条是**常驻**的，
     所以它的长相直接决定左菜单的观感 —— 系统默认那条又宽又带上下箭头，
     压在圆角卡片内边非常突兀。这里自己画一条 6px 的：
       · scrollbar-width / scrollbar-color  → Firefox + 新版 Chromium
       · ::-webkit-scrollbar                 → Safari + 旧 Chromium
     右侧 padding 收到 14px，让滑块与卡片内边留出呼吸感，
     不然 6px 的滑块紧贴圆角，看起来像"贴边的一条线"。 */
  scrollbar-width: thin;
  scrollbar-color: #d5dce7 transparent;
  overscroll-behavior: contain;
}
.help-nav::-webkit-scrollbar { width: 6px; height: 6px; }
.help-nav::-webkit-scrollbar-track { background: transparent; }
.help-nav::-webkit-scrollbar-thumb {
  background: #d5dce7;
  border-radius: 999px;
}
.help-nav::-webkit-scrollbar-thumb:hover { background: #b4c1d4; }

.help-nav-group + .help-nav-group { margin-top: 22px; }

/* 分类标题（链到帮助中心首页的对应分类锚点）。
   ★ 这版**不做折叠** —— 18 条平铺才"一目了然"，理由见
     tools/_lib/faq-index.js 的 renderNav（那里记了用户否掉手风琴的原话）。 */
.help-nav-title {
  display: block;
  margin: 0 0 10px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .04em;
  color: var(--ink-3);
}
a.help-nav-title:hover { color: var(--brand); }

.help-nav-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.help-nav-item a {
  display: block;
  padding: 8px 10px 8px 12px;
  font-size: 14px;
  line-height: 1.6;
  color: var(--ink-2);
  border-radius: 8px;
  border-left: 2px solid transparent;
  transition: background .16s, color .16s, border-color .16s;
}
.help-nav-item a:hover { background: #fff; color: var(--brand); }
/* 当前文章：左侧竖条 + 实底 + 加粗。三重信号，
   是因为只靠"变色"在低对比度屏幕上容易看不出来。 */
.help-nav-item a.is-current {
  background: var(--brand-light);
  color: var(--brand);
  font-weight: 600;
  border-left-color: var(--brand);
}
/* 尚无详情页的条目：不可点（不是 disabled 按钮，是纯文本），
   但**仍然列出来** —— 让访客知道这个话题我们覆盖，只是还没写完。 */
.help-nav-item.is-soon > span {
  display: block;
  padding: 8px 10px 8px 12px;
  font-size: 14px;
  line-height: 1.6;
  color: #a2adbf;
}
.help-nav-soon {
  margin: 10px 0 0;
  font-size: 12px;
  line-height: 1.7;
  color: var(--ink-3);
}
.help-nav-back {
  display: block;
  margin-bottom: 18px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--line);
  font-size: 14px;
  color: var(--ink-2);
}
.help-nav-back:hover { color: var(--brand); }

/* ---- 16.3 右侧：分类分组的问题卡片 ------------------------------------ */
.help-cat + .help-cat { margin-top: 52px; }
/* 锚点跳转的让位统一在 16.8 声明 —— 别在这里单独写 scroll-margin：
   它会与 site.css 的 html{scroll-padding-top} 叠加成双倍偏移（曾经就是双倍）。 */
.help-cat-head { margin-bottom: 20px; }
.help-cat-head h2 { margin: 0; font-size: 26px; letter-spacing: -.01em; color: var(--ink); }
.help-cat-head p { margin: 8px 0 0; font-size: 15px; line-height: 1.8; color: var(--ink-3); }

.help-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.help-card {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r);
  transition: border-color .16s, box-shadow .16s, transform .16s;
}
/* 有详情页的卡片整块可点 —— 点击目标从一行文字变成整张卡，
   手机上尤其明显（拇指够不到一行 14px 的文字尾巴）。
   ★ .help-card-body 是"还没有详情页"那张卡的对应容器：两者**共用同一份内距**，
     否则同一列里两种卡片的文字起始位置会差几像素，看起来像没对齐。 */
a.help-card-link,
.help-card-body {
  display: block;
  padding: 22px 24px;
  color: inherit;
}
.help-card:hover { border-color: #cfdaea; box-shadow: var(--shadow-sm, 0 10px 24px -18px rgba(7, 13, 27, .3)); }
a.help-card-link:hover { transform: translateY(-1px); }
.help-card h3 {
  margin: 0;
  font-size: 18px;
  line-height: 1.55;
  color: var(--ink);
  letter-spacing: -.01em;
}
a.help-card-link:hover h3 { color: var(--brand); }
.help-card p {
  margin: 10px 0 0;
  font-size: 15px;
  line-height: 1.85;
  color: var(--ink-3);
}
.help-card-more {
  display: inline-block;
  margin-top: 12px;
  font-size: 14px;
  font-weight: 600;
  color: var(--brand);
}
/* 尚在整理：不打 hover 效果、不给"阅读全文"链接（避免点了个死路）。
   底色压淡一档，让"已可读 / 待补充"一眼可分。 */
.help-card.is-soon { background: #fbfcfe; border-style: dashed; }
.help-card.is-soon .help-card-more { color: #a2adbf; font-weight: 400; }
.help-card.is-soon:hover { border-color: var(--line); box-shadow: none; }

/* ---- 16.4 详情页正文（长文排版） -------------------------------------- */
.article { max-width: 780px; }
/* 780px：中文正文单行 32~40 字是舒适区。再宽，读者从行尾回行首会串行。 */
.article > * + * { margin-top: 20px; }
.article h2 {
  margin: 44px 0 0;
  font-size: 24px;
  letter-spacing: -.01em;
  color: var(--ink);
  /* 锚点让位见 16.8（统一声明，避免与 html 的 scroll-padding-top 叠加） */
}
.article h3 { margin: 30px 0 0; font-size: 19px; color: var(--ink); }
.article p { margin: 0; font-size: 16px; line-height: 1.95; color: var(--ink-2); }
.article a { color: var(--brand); text-decoration: underline; text-underline-offset: 3px; }
.article a:hover { color: var(--brand-dark); }
.article b, .article strong { color: var(--ink); font-weight: 600; }
.article ul, .article ol { margin: 0; padding-left: 22px; display: grid; gap: 10px; }
.article li { font-size: 16px; line-height: 1.9; color: var(--ink-2); }
.article > p:first-of-type { font-size: 17px; color: var(--ink-2); }
/* 正文里的代码 / 域名 / 路径 */
.article code {
  padding: 2px 7px;
  font-size: 14px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  color: var(--ink);
  background: var(--bg-alt);
  border: 1px solid var(--line);
  border-radius: 6px;
  word-break: break-all;
}
/* 提示块：回答"这一条容易踩的坑" */
.article-tip {
  padding: 18px 22px;
  font-size: 15px;
  line-height: 1.85;
  color: var(--ink-2);
  background: var(--info-bg);
  border: 1px solid var(--info-line);
  border-radius: var(--r);
}
.article-tip b { color: #075985; }
/* 正文里的表格：窄屏改为横向滚动（详情页表格通常只 2~3 列，不该走"每档一张卡"那套） */
.article .cmp-wrap { margin: 24px 0 0; }

/* ---- 16.5 上下篇 / 返回 ----------------------------------------------- */
.help-pager {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  margin-top: 52px;
  padding-top: 28px;
  border-top: 1px solid var(--line);
}
.help-pager-item {
  display: block;
  padding: 18px 20px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r);
  transition: border-color .16s, box-shadow .16s;
}
.help-pager-item:hover { border-color: var(--brand); box-shadow: var(--shadow-sm, 0 10px 24px -18px rgba(7, 13, 27, .3)); }
.help-pager-item .dir { display: block; font-size: 13px; color: var(--ink-3); }
.help-pager-item .t { display: block; margin-top: 6px; font-size: 15px; line-height: 1.6; color: var(--ink); }
.help-pager-item:hover .t { color: var(--brand); }
.help-pager-item.is-next { text-align: right; }
/* 只有一篇时不留半个空格子 */
.help-pager-item.is-empty { visibility: hidden; }
.help-back { margin-top: 26px; }
.help-back a { font-size: 15px; color: var(--ink-3); }
.help-back a:hover { color: var(--brand); }

/* ---- 16.6 详情页的矮页头 ---------------------------------------------- */
.page-hero-compact { padding: calc(var(--header-h) + 34px) 0 38px; }
.page-hero-compact h1 { font-size: 36px; max-width: 820px; }
.page-hero-compact .page-hero-sub { margin-top: 14px; font-size: 17px; }

/* ---- 16.7 详情页「当前文章」标题条（常驻 · 不吸顶）--------------------- */
/*
   【它解决什么】（2026-10-09，用户三次反馈的同一件事）
     左菜单有 18 条，用户滚到列表底部点某一条 → 跨页跳转 → 页面回到顶部。
     此时"我刚才点的到底是哪一篇"不好确认。所以在**正文列的最上面**
     再放一份标题（分类 + 文章标题）。

   ★ 2026-10-09 第三轮修正：**取消吸顶**（原来是 position: sticky）。
     用户原话：「这个悬浮标题会遮挡正文」。
     这是 sticky 的固有代价，不是没调好 —— 它冻结在视口里，正文滚上来
     必然从它底下穿过，被它盖掉一截，滚多久盖多久；`z-index` 只能保证
     它盖住正文，不能保证正文不被盖。

     而"进门那一刻不知道自己点的是哪篇"这件事，**已经由跨页锚点定位解决**
     （落点 = 正文列顶端 = 这个地方，见 16.8）：点左菜单 / 首页卡片进来，
     第一眼就在视口里看到它 —— 不需要再靠吸顶来"保证看得见"。
     所以让它做回普通块：随正文一起滚走，谁也不挡。

   ⚠️ **别再改回 sticky。** 如果将来又想"滚到文章深处还能看到在读哪篇"，
      正确做法是在**顶栏**里加一条（顶栏本来就是 sticky 的，不额外占正文列
      空间、也不覆盖正文），而不是让标题条吸在正文上。

   【为什么还留着】页头还露着时，它和 <h1> 是同一句话的两处显示 —— 这是**要的**，
     不是冗余：一处给"这是什么页面"，一处给"当前这一篇"。
*/
.article-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  max-width: 780px;                     /* 与 .article 正文同宽 */
  margin: 0 0 30px;
  padding: 10px 14px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: 0 10px 24px -22px rgba(7, 13, 27, .5);
}
/* 分类胶囊：把"这一篇属于哪一类"也一并给出来，
   比只重复一个标题信息量更大（也解释了它为什么不是单纯的一行文字）。 */
.article-bar-cat {
  flex: none;
  padding: 3px 9px;
  font-size: 12px;
  font-weight: 600;
  line-height: 1.6;
  color: var(--brand);
  background: var(--brand-light);
  border-radius: 999px;
  white-space: nowrap;
}
.article-bar-title {
  min-width: 0;
  font-size: 15px;
  font-weight: 600;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ---- 16.8 锚点落点（单一来源）---------------------------------------- */
/*
   【为什么要集中管】site.css 的 `html { scroll-padding-top: calc(var(--header-h) + 18px) }`
   已经替**所有**锚点目标让出了顶栏那一条（90px）。
   本文件里需要"再多让一点"的目标，只许用 `scroll-margin-top` 各自声明。

   ⚠️ 历史欠账：`.help-cat` 与 `.article h2` 曾经各自再叠一份接近整条顶栏的值，
      而 scroll-padding 与 scroll-margin 是**相加**关系 —— 实际落点
      = 90 + 92 = 182px（详情页那条更写到 84px，合计 248px），
      离目标标题差着大半屏。已全部收口到这里。

   ★ 跨页锚点（`#article`）：左菜单 / 首页卡片 / 上下篇点进来时，
     "整页回到顶部、再从页头开始读"正是用户第三次提的同一个问题（原话：
     「点击左边底部菜单名内容就会跳到顶部 HEAD 区域开始看，是否可以锚点定位一下」）。
     落点 = **正文列顶端**，也就是那条常驻标题条所在的位置（见 16.7）。
     90 + 6 = 96px —— 页头那一段（整条顶栏 + 页头）被干净地跨过，
     进门第一眼就是"这一篇的标题 + 正文开头"。

   ⚠️ 历史：详情页的页内小标题曾经让 60px（+ 顶栏那 90 = 落点 150px），
      那是为了躲**吸顶**的标题条。2026-10-09 标题条取消吸顶（见 16.7），
      这条让位就失去了前提 ⇒ 收回到 8px，与首页分类锚点一致。
      判据的前提消失了就改写判据，别留一个没有理由在的魔法数。
*/
.help-cat { scroll-margin-top: 8px; }                  /* 首页分类锚点：顶栏下 98px */
.article :is(h2, h3, h4) { scroll-margin-top: 8px; }   /* 页内小标题：顶栏下 98px（同左） */
#article { scroll-margin-top: 6px; }                   /* 跨页锚点：落点 = 正文列顶端 = 那行标题条 */

/* ---- 16.9 响应式 ------------------------------------------------------ */
@media (max-width: 1023px) {
  /* 窄屏：菜单不再"贴左"，回到正文上方（横向滚动条式的侧栏在手机上没人用）。
     平铺的 18 条在手机上会很长 —— 但那是**进来之前**的事，
     用户点进来第一眼看到的就是正文列顶部的标题条，不会"不知道自己点了哪篇"。 */
  .help-layout { grid-template-columns: minmax(0, 1fr); gap: 24px; }
  .help-nav {
    position: static;
    max-height: none;
    overflow: visible;
    padding: 16px 18px;
  }
  .help-nav-group + .help-nav-group { margin-top: 16px; }
  /* 窄屏同样不吸顶（理由见 16.7）：进门第一眼看到它，滚下去就随正文滚走。
     窄屏没有"左菜单高亮"这一路信号，滚深了确实就不知道在读哪篇 ——
     但那是"再往上滚一下就看得见"的代价，比"一路盖着正文"划算。 */
  .article-bar {
    gap: 8px;
    margin-bottom: 22px;
    padding: 8px 12px;
  }
  .article-bar-cat { font-size: 11px; padding: 2px 8px; }
  .article-bar-title { font-size: 14px; }
}
@media (max-width: 760px) {
  .page-hero-compact { padding: calc(var(--header-h) + 24px) 0 30px; }
  .page-hero-compact h1 { font-size: 26px; }
  .page-hero-compact .page-hero-sub { font-size: 15px; }
  .help-cat-head h2 { font-size: 22px; }
  a.help-card-link,
  .help-card-body { padding: 18px 18px; }
  .help-card h3 { font-size: 17px; }
  .article h2 { margin-top: 34px; font-size: 21px; }
  .article h3 { font-size: 18px; }
  /* 上下篇在窄屏改为一列：并排两列时每条只剩 ~45% 宽，
     「上一篇：注册要多久？需要审核吗？」这类长标题会折成 3~4 行。 */
  .help-pager { grid-template-columns: minmax(0, 1fr); }
  .help-pager-item.is-next { text-align: left; }
}

