/* ==========================================================================
   Hilly 产品页（hilly.html）—— 页面级样式
   --------------------------------------------------------------------------
   本文件只承载这一页需要的版式，不改动 styles.css 里的任何既有规则。
   所有颜色、圆角、间距、过渡都取自 styles.css 的设计令牌
   （--base-accent-rgb / --glass-border / --radius-* / --space-* / --transition-smooth），
   以保证本页与首页是同一套视觉体系，而不是另起一套。
   ========================================================================== */

/* --------------------------------------------------------------------------
   面包屑：与页头 BreadcrumbList 结构化数据一一对应。
   导航栏是 position:fixed（--nav-height=72px），所以第一个元素要自己让开。
   -------------------------------------------------------------------------- */
.hilly-breadcrumb {
  position: relative;
  z-index: 1;
  padding: calc(var(--nav-height) + 22px) 0 0;
}

.hilly-breadcrumb ol {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  list-style: none;
  font-size: 0.82rem;
  color: var(--text-muted);
}

.hilly-breadcrumb li {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.hilly-breadcrumb li+li::before {
  content: '/';
  opacity: 0.5;
}

.hilly-breadcrumb a {
  transition: var(--transition-smooth);
}

.hilly-breadcrumb a:hover {
  color: var(--cyan-primary);
}

/* --------------------------------------------------------------------------
   Hero
   刻意不做满屏高度：这是二级总览页，首屏就该看见定义与出口，
   而不是先看过一屏留白。
   -------------------------------------------------------------------------- */
.hilly-hero {
  position: relative;
  z-index: 1;
  /* 下内边距对齐首页 .hero 的 var(--space-2xl)：
     紧接着的 .section 自己还有 96px 上内边距，两段相加才是首页一贯的留白节奏。
     这里若用 --space-3xl，hero 与首个板块之间会多出 190px 空白，明显发空。 */
  padding: var(--space-2xl) 0 var(--space-2xl);
}

.hilly-hero .container {
  max-width: 940px;
  text-align: center;
}

.hilly-h1 {
  font-size: clamp(2.1rem, 4.6vw, 3.4rem);
  font-weight: 900;
  line-height: 1.18;
  letter-spacing: -1px;
  margin-bottom: var(--space-lg);
  color: var(--text-primary);
}

/* 主标题语（资料里的「（首屏）主标题」）。
   它排在 H1 之后单独成行 —— H1 让给实体类别词，标题语保留原有的排版分量。 */
.hilly-slogan {
  margin: calc(-1 * var(--space-sm)) 0 var(--space-lg);
  font-size: clamp(1.2rem, 2.2vw, 1.6rem);
  font-weight: 700;
  letter-spacing: 0.01em;
  color: var(--text-primary);
}

/* 核心标签：四个关键词做成胶囊，既是视觉锚点也是可被引用的短句 */
.hilly-tags {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  list-style: none;
  margin-top: var(--space-lg);
}

.hilly-tags li {
  padding: 7px 16px;
  border-radius: var(--radius-full);
  border: 1px solid var(--glass-border);
  background: rgba(var(--base-accent-rgb), 0.06);
  font-size: 0.84rem;
  font-weight: 600;
  color: var(--text-secondary);
}

.hilly-lead {
  font-size: clamp(1rem, 1.5vw, 1.12rem);
  line-height: 1.95;
  color: var(--text-secondary);
}

.hilly-lead strong {
  font-weight: 700;
  color: var(--text-primary);
}

.hilly-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-sm);
  margin-top: var(--space-xl);
}

/* 首屏行动按钮：桌面「扫码体验」／手机「看看它能做什么」。
   ★ 手机上没有「扫码」这个动作 —— 他不能扫自己这块屏幕，点开弹窗只会
     看到一张没法处理的黑白方块。所以窄屏换成往下走的锚点。
   ★ 两个元素同时只有一个显示，所以视觉上永远是一个按钮；
     特异度 (0,2,0) 压得住 .hilly-btn 的 inline-flex，不必用 !important。 */
.hilly-actions .hilly-hero-more {
  display: none;
}

/* ★ 别继承「两个按钮并排」时代的 flex:1 1 100%：
   那会把单个主按钮拉成通栏 —— 窄屏直接顶到右侧固定的「联系我们」浮标下面，
   桌面上则显得比大标题弱一大截。这里是 (0,2,0)，压得住窄屏那条 (0,1,0)。 */
.hilly-actions .hilly-btn {
  flex: 0 1 auto;
  min-width: 176px;
}

@media (max-width: 620px) {
  .hilly-actions .hilly-hero-qr {
    display: none;
  }

  .hilly-actions .hilly-hero-more {
    display: inline-flex;
  }
}

.hilly-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 46px;
  padding: 0 24px;
  border-radius: var(--radius-full);
  border: 1px solid var(--glass-border);
  background-color: var(--bg-card);
  color: var(--text-primary);
  font-size: 0.92rem;
  font-weight: 600;
  transition: var(--transition-smooth);
}

/* hover 只改「颜色层」，绝不碰 background-image。
   这里若写成 background: 简写，会把 .hilly-btn-primary 的渐变一起重置为 none，
   而主按钮的文字是 #fff —— 结果就是白字白底（实测 hover 对比度只有 1.01）。
   站点既有的 .corner-btn / .send-btn 也是同一套做法：渐变按钮的 hover 只动
   background-position 与阴影，从不改 background。 */
.hilly-btn:hover {
  background-color: var(--bg-card-hover);
  border-color: var(--glass-border-glow);
}

.hilly-btn-primary {
  color: #fff;
  border-color: transparent;
  background-color: transparent;
  background-image: var(--btn-grad);
  background-size: 200% auto;
  background-position: left center;
  box-shadow: 0 0 16px rgba(var(--btn-glow-rgb), 0.45), 0 0 30px rgba(var(--btn-glow2-rgb), 0.28);
}

.hilly-btn-primary:hover {
  color: #fff;
  background-color: transparent;
  background-position: right center;
  box-shadow: 0 0 22px rgba(var(--btn-glow-rgb), 0.7), 0 0 38px rgba(var(--btn-glow2-rgb), 0.42);
}

/* --------------------------------------------------------------------------
   可引用定义块 —— 本页最重要的一段正文。
   左侧留一道品牌色竖线，视觉上把它和普通卡片区分开（它就是要被整段引用的话）。
   -------------------------------------------------------------------------- */
.hilly-def {
  position: relative;
  max-width: 940px;
  margin: 0 auto;
  padding: 32px 36px;
  border-radius: var(--radius-lg);
  background: var(--bg-card);
  border: 1px solid var(--glass-border);
  box-shadow: var(--shadow-card);
}

.hilly-def::before {
  content: '';
  position: absolute;
  left: 0;
  top: 26px;
  bottom: 26px;
  width: 3px;
  border-radius: var(--radius-full);
  background: var(--grad-cyan-blue);
}

.hilly-def-text {
  font-size: 1.05rem;
  line-height: 2;
  color: var(--text-secondary);
}

/* --------------------------------------------------------------------------
   三个要点（复用首页的 .key-points-list / .key-point-item / .point-icon）
   -------------------------------------------------------------------------- */
.hilly-points {
  max-width: 940px;
  margin: var(--space-2xl) auto 0;
  display: grid;
  gap: var(--space-lg);
}

.hilly-points .point-icon {
  flex: 0 0 auto;
  width: 46px;
  height: 46px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1.25rem;
  line-height: 1;
}

.hilly-point-title {
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--text-primary);
  margin-bottom: 6px;
}

.hilly-point-text {
  font-size: 0.95rem;
  line-height: 1.85;
  color: var(--text-secondary);
}

/* --------------------------------------------------------------------------
   长句标题（本页有两个「板块标题」是整句话）避免出现只剩一两个词的孤行。
   .section-title 属于全站类，但 hilly.css 只在 hilly.html 上加载，
   所以这条只对本页生效，不会波及其他页面。
   text-wrap: balance 在旧浏览器上会被整条忽略，退化为原来的断行，不会出错。
   -------------------------------------------------------------------------- */
.section-title {
  text-wrap: balance;
}

/* --------------------------------------------------------------------------
   我们解决的问题：3 张卡，窄屏自动降列
   -------------------------------------------------------------------------- */
/* minmax 的 min 写成 min(300px, 100%)：容器本身比 300px 还窄时（如 320px 视口）
   轨道不会撑破容器 —— 直接写 300px 会产生隐式横向溢出。 */
.hilly-problems {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
  gap: 18px;
}

.hilly-problem {
  padding: 28px 26px;
  border-radius: var(--radius-md);
  background: var(--bg-card);
  border: 1px solid var(--glass-border);
  transition: var(--transition-smooth);
}

/* 序号做渐变字：与首页 .gradient-text 同一套写法（background-clip: text） */
.hilly-problem-no {
  display: block;
  margin-bottom: 16px;
  font-size: 1.7rem;
  font-weight: 900;
  line-height: 1;
  letter-spacing: 0.02em;
  background: var(--grad-cyan-blue);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

.hilly-problem-title {
  font-size: 1.08rem;
  font-weight: 800;
  line-height: 1.5;
  color: var(--text-primary);
  margin-bottom: 10px;
}

.hilly-problem-text {
  font-size: 0.9rem;
  line-height: 1.85;
  color: var(--text-secondary);
}

/* --------------------------------------------------------------------------
   核心功能：6 组，改成「互斥手风琴」（原生 <details name>）。

   为什么不再用卡片网格：6 张卡每张都是「一句定位 + 一段引语 + 3~4 条子项」，
   1440 下整整 2600px 全是密排正文 —— 用户的反馈就是「文字太多太密」。
   手风琴把**看得见的面积**压到六分之一，而**一个字的正文都没删**：
   折叠的内容仍完整留在 HTML 源码里，爬虫不执行 JS 也照读全文。

   ⚠️ 不要再加回多列。手风琴是纵向列表，一旦按列排布，
   展开某一项会把同行邻居顶成高低不齐，比原来更乱。
   -------------------------------------------------------------------------- */
.hilly-mods {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 12px;
}

.hilly-mod {
  position: relative;
  display: block;          /* 由 flex column 改回块级：<details> 的内容模型是
                              「一个 summary + 其后任意流内容」，布局交给 head / body */
  padding: 0;              /* 内边距下放到 .hilly-mod-head 与 .hilly-mod-body */
  border-radius: var(--radius-lg);
  background: var(--bg-card);
  border: 1px solid var(--glass-border);
  transition: var(--transition-smooth);
}

/* 头行 = 可点击的 summary。用 grid 摆四个区，
   这样 DOM 顺序（图标 → 序号 → 标题 → 副标题）不必为视觉顺序让路。 */
.hilly-mod-head {
  display: grid;
  grid-template-columns: 42px minmax(0, 1fr) auto 22px;
  grid-template-areas:
    "icon title no  cue"
    "icon sub   no  cue";
  align-items: center;
  column-gap: 14px;
  row-gap: 3px;
  padding: 20px 26px;
  cursor: pointer;
  list-style: none;        /* 去掉原生三角（Firefox 认这条） */
  border-radius: inherit;
}

.hilly-mod-head::-webkit-details-marker {
  display: none;
}

/* summary 原生可聚焦，但默认焦点环在浅色卡上几乎看不见 */
.hilly-mod-head:focus-visible {
  outline: 2px solid var(--cyan-primary);
  outline-offset: -2px;
}

.hilly-mod-icon {
  grid-area: icon;
  display: block;
  width: 42px;
  height: 42px;
  color: var(--ring-icon);
  filter: drop-shadow(0 0 5px rgba(var(--ring-glow-rgb), 0.4));
}

.hilly-mod-icon svg {
  width: 100%;
  height: 100%;
}

/* 序号改成网格项，不再绝对定位：头行现在是两行，绝对定位会和标题
   抢同一块右上角；跨两行居中的网格项最稳，也不占标题的行宽。 */
.hilly-mod-no {
  grid-area: no;
  align-self: center;
  font-size: 0.76rem;
  font-weight: 800;
  letter-spacing: 0.14em;
  color: var(--cyan-primary);
  opacity: 0.6;
}

.hilly-mod-title {
  grid-area: title;
  font-size: 1.1rem;
  font-weight: 800;
  line-height: 1.4;
  color: var(--text-primary);
}

.hilly-mod-sub {
  grid-area: sub;
  font-size: 0.86rem;
  font-weight: 600;
  line-height: 1.6;
  color: var(--cyan-primary);
}

/* 展开指示：一个 V 形。
   ⚠️ 旋转只能写在 ::before 上 —— 按 CSS Overflow 规范，带 transform 的盒子
   会计入祖先的 scrollWidth，在元素自身写 transform 会污染宽度适配审计
   （上一轮 .pulse-dot 用 transform: scale() 做过扩散环，被误判 20 处溢出）。 */
.hilly-mod-cue {
  grid-area: cue;
  position: relative;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: rgba(30, 94, 255, 0.08);
  border: 1px solid rgba(30, 94, 255, 0.2);
  transition: var(--transition-smooth);
}

.hilly-mod-cue::before {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  width: 6px;
  height: 6px;
  margin-left: -3px;
  margin-top: -4px;
  border-right: 1.6px solid var(--cyan-primary);
  border-bottom: 1.6px solid var(--cyan-primary);
  transform: rotate(45deg);
  transition: transform 0.3s var(--ease-tactile);
}

.hilly-mod[open] .hilly-mod-cue {
  background: var(--cyan-primary);
  border-color: var(--cyan-primary);
}

.hilly-mod[open] .hilly-mod-cue::before {
  border-color: #fff;
  transform: rotate(-135deg);
}

/* 展开体：引语在左、子项在右。
   两条窄栏比「引语整行 + 列表整行」矮近一半；1440 下容器 1160px，
   两栏各约 560px，中文行宽仍落在 30 字上下，没有失控。 */
.hilly-mod-body {
  padding: 18px 26px 24px;
  border-top: 1px solid var(--glass-border);
}

.hilly-mod-lead {
  padding-bottom: 16px;
  margin-bottom: 16px;
  border-bottom: 1px solid var(--glass-border);
  font-size: 0.9rem;
  line-height: 1.85;
  color: var(--text-secondary);
}

.hilly-mod-list {
  display: grid;
  gap: 12px;
  list-style: none;
}

.hilly-mod-list li {
  position: relative;
  padding-left: 18px;
  font-size: 0.86rem;
  line-height: 1.8;
  color: var(--text-secondary);
}

.hilly-mod-list li::before {
  content: '';
  position: absolute;
  left: 1px;
  top: 0.74em;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--cyan-primary);
  opacity: 0.7;
}

.hilly-mod-list li strong {
  margin-right: 6px;
  font-weight: 700;
  color: var(--text-primary);
}

@media (min-width: 900px) {
  .hilly-mod-body {
    display: grid;
    grid-template-columns: minmax(0, 4fr) minmax(0, 6fr);
    align-items: start;
    gap: 0 36px;
  }

  /* 两栏并排后，原来的「引语下分隔线」改成竖线 */
  .hilly-mod-lead {
    padding: 0 36px 0 0;
    margin-bottom: 0;
    border-bottom: 0;
    border-right: 1px solid var(--glass-border);
  }
}

/* 窄屏收起序号。390px 下实测：序号占掉约 34px 后，副标题被挤成两行，
   而序号跨两行居中，正好悬在「标题」与「换行后的副标题」中间，很别扭。
   序号只是视觉编号、不是信息（正文里没有它），窄屏直接收掉最干净。 */
@media (max-width: 560px) {
  .hilly-mod-no {
    display: none;
  }
}

/* 展开动画：<details> 的收起态内容不参与布局，没法用 transition，
   所以改为「打开时让展开体自己播一次入场」。整段结束在 transform: none，
   不会留下变换盒，也就不会污染祖先的滚动宽度。 */
@keyframes hilly-unfold {
  from {
    opacity: 0;
    transform: translateY(-6px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.hilly-mod[open] > .hilly-mod-body,
.hilly-qa[open] > .hilly-qa-a {
  animation: hilly-unfold 0.3s var(--ease-tactile) both;
}

/* --------------------------------------------------------------------------
   （已删除：产品矩阵 .hilly-matrix / .hilly-mrow*）
   --------------------------------------------------------------------------
   第 37 轮把「产品矩阵」整节从 hilly 页删掉了（hilly 页只讲 Hilly，不再横向罗列
   Hilly Report / Hilly Link 等其它产品），这批约 16 条规则从此没有任何元素命中。
   删掉而不是留着，是因为它和 .hilly-fact 的排版很像 —— 留着以后容易有人
   照着它改样式，改完发现页面没反应。
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   可引用事实
   -------------------------------------------------------------------------- */
.hilly-facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
  gap: 14px 22px;
  max-width: 1040px;
  margin: 0 auto;
}

.hilly-fact {
  padding: 18px 20px;
  border-radius: var(--radius-md);
  background: var(--bg-card);
  border: 1px solid var(--glass-border);
}

.hilly-fact dt {
  font-size: 0.76rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--cyan-primary);
  margin-bottom: 8px;
}

.hilly-fact dd {
  font-size: 0.92rem;
  line-height: 1.75;
  color: var(--text-secondary);
}

.hilly-fact a,
.hilly-qa-a a {
  color: var(--cyan-primary);
  transition: var(--transition-smooth);
}

.hilly-fact a:hover,
.hilly-qa-a a:hover {
  text-decoration: underline;
}

/* --------------------------------------------------------------------------
   FAQ：与页头 FAQPage 结构化数据一一对应。

   16 条全部摊开是 2778px 的密排问答，占整页近三成 —— 改成原生 <details> 手风琴。
   默认只展开第一条：进来的第一眼就看到一条完整问答，
   同时保证「结构化数据 vs 可见正文」的一致性在无 JS、零点击时依然成立。

   两列排布已废弃：手风琴在双列下展开会顶乱同行邻居，单列 880px 居中更稳。
   -------------------------------------------------------------------------- */
.hilly-faq {
  display: grid;
  gap: 10px;
  max-width: 880px;
  margin: 0 auto;
}

.hilly-qa {
  padding: 0;              /* 内边距下放到 head 与答案体 */
  border-radius: var(--radius-md);
  background: var(--bg-card);
  border: 1px solid var(--glass-border);
  transition: var(--transition-smooth);
}

.hilly-qa-head {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 17px 22px;
  cursor: pointer;
  list-style: none;
  border-radius: inherit;
}

.hilly-qa-head::-webkit-details-marker {
  display: none;
}

.hilly-qa-head:focus-visible {
  outline: 2px solid var(--cyan-primary);
  outline-offset: -2px;
}

.hilly-qa-q {
  flex: 1;
  min-width: 0;
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.5;
  color: var(--text-primary);
}

.hilly-qa-cue {
  position: relative;
  width: 20px;
  height: 20px;
  flex: none;
  border-radius: 50%;
  background: rgba(30, 94, 255, 0.08);
  border: 1px solid rgba(30, 94, 255, 0.2);
  transition: var(--transition-smooth);
}

.hilly-qa-cue::before {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  width: 5px;
  height: 5px;
  margin-left: -2.5px;
  margin-top: -3.5px;
  border-right: 1.5px solid var(--cyan-primary);
  border-bottom: 1.5px solid var(--cyan-primary);
  transform: rotate(45deg);
  transition: transform 0.3s var(--ease-tactile);
}

.hilly-qa[open] .hilly-qa-cue {
  background: var(--cyan-primary);
  border-color: var(--cyan-primary);
}

.hilly-qa[open] .hilly-qa-cue::before {
  border-color: #fff;
  transform: rotate(-135deg);
}

.hilly-qa-a {
  padding: 16px 22px 20px;
  border-top: 1px solid var(--glass-border);
  font-size: 0.93rem;
  line-height: 1.9;
  color: var(--text-secondary);
}

.hilly-qa-a p {
  margin: 0;               /* 答案现在是 <p>，清掉 section 的默认段间距 */
}

/* 答案块里唯一带链接的那条：「了解企业服务 →」独立成行放在正文之后。
   ★ 单独成行不是设计偏好，是为了让 .hilly-qa-a > p 的文本和 JSON-LD 的
     acceptedAnswer.text 一字不差 —— 链接夹在句尾会切断文本节点。
   ★ 必须 inline-block：<a> 是行内元素，光靠 line-height 会贴着正文基线，
     和上一段看起来像同一句话的尾巴。 */
.hilly-qa-a > a {
  display: inline-block;
  margin-top: 6px;
  font-weight: 600;
}

/* --------------------------------------------------------------------------
   适合人群：8 个胶囊，居中环绕
   -------------------------------------------------------------------------- */
.hilly-audience {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 12px;
  max-width: 880px;
  margin: 0 auto;
  list-style: none;
}

.hilly-persona {
  padding: 12px 22px;
  border-radius: var(--radius-full);
  background: var(--bg-card);
  border: 1px solid var(--glass-border);
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--text-secondary);
  transition: var(--transition-smooth);
}

/* --------------------------------------------------------------------------
   下载与行动号召
   -------------------------------------------------------------------------- */
.hilly-cta-section .container {
  max-width: 940px;
}

.hilly-cta-inner {
  position: relative;
  overflow: hidden;
  padding: 56px 40px;
  border-radius: var(--radius-lg);
  background: var(--bg-card);
  border: 1px solid var(--glass-border);
  box-shadow: var(--shadow-card);
  text-align: center;
}

/* 品牌色柔光：给收尾板块一点重量，但只用一层极淡的径向渐变，不做花哨装饰 */
.hilly-cta-inner::before {
  content: '';
  position: absolute;
  top: -40%;
  left: 50%;
  width: 620px;
  height: 620px;
  transform: translateX(-50%);
  border-radius: 50%;
  background: radial-gradient(circle, rgba(var(--base-accent-rgb), 0.14) 0%, rgba(var(--base-accent-rgb), 0) 68%);
  pointer-events: none;
}

.hilly-cta-inner > * {
  position: relative;
  z-index: 1;
}

.hilly-cta-title {
  font-size: clamp(1.5rem, 3vw, 2.1rem);
  font-weight: 900;
  line-height: 1.35;
  letter-spacing: -0.5px;
  color: var(--text-primary);
  margin-bottom: 12px;
  /* 换行时均衡分配两行，避免窄屏把「身。」这种两字尾丢到第二行 */
  text-wrap: balance;
}

.hilly-cta-sub {
  font-size: clamp(1rem, 1.6vw, 1.1rem);
  color: var(--text-secondary);
}

.hilly-cta-inner .hilly-actions {
  margin-top: var(--space-xl);
}

/* 说明行收到与扫码面板同宽：不然一行 810px 的小字压在 460px 的方块下面，
   视线对不齐，整块看着发散 */
.hilly-cta-note {
  max-width: 460px;
  margin: var(--space-lg) auto 0;
  font-size: 0.82rem;
  line-height: 1.8;
  color: var(--text-muted);
  /* 窄屏折行时优先避免「渠道为准」这种孤行 */
  text-wrap: pretty;
}

/* ==========================================================================
   视觉加厚：底色分层 / 环境光 / 板块节奏 / 卡片材质
   --------------------------------------------------------------------------
   为什么「太白太空」：
   1) 站点亮色主题的页面底色是 --bg-dark:#f8fafc，卡片是 rgba(255,255,255,0.88)，
      合成后两者只差约 2% —— 卡片等于浮在同一片白上，没有「物件感」；
   2) 全页没有背景层：首页有一层滚动驱动的 LOGO 水印，首屏还有 three.js 龙卷风
      canvas，本页当初特意都没加载，所以底色一路平到底；
   3) 板块之间没有任何明暗变化，整页是一条均匀的白。

   以下全部只用 CSS，且只作用 .hilly-page：
   A. 底色分层 —— 本页底色压到 #f4f7fe（带一点品牌蓝的灰白），卡片提到纯白，
      对比拉到约 6%，卡片才立得住；
   B. 环境光 —— 固定贴视口的三处品牌色柔光，让任何位置都不会是死白；
   C. 板块节奏 —— 两组柔边底色带（首尾各自渐隐），形成明暗起伏；蓝→紫递进；
   D. 卡片材质 —— 统一一层偏蓝的柔和投影，替掉原来的中性灰。

   ⚠️ D 段必须排在本文件「交互态」之前：`.hilly-page .hilly-mod` 与
   `.hilly-mod:hover` 同为 (0,2,0)，后出现的那条获胜，排在后面会把 hover 的
   --shadow-glow 覆盖掉。
   ========================================================================== */

/* A. 底色分层。只改本页：--bg-card 提纯到 #ffffff，hover 态换成品牌浅蓝，
   底色压深一档。三者都只在本页生效，首页不受影响。 */
.hilly-page {
  background-color: #f4f7fe;
  --bg-card: #ffffff;
  --bg-card-hover: #eef3ff;
}

/* B. 环境光。position:fixed 贴视口、不随滚动，所以不会在某一屏突然断掉。
   三处光斑都压在极低透明度，只负责「不是死白」，不承担视觉主体。 */
.hilly-page::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(54% 40% at 50% -8%, rgba(30, 94, 255, 0.12) 0%, rgba(30, 94, 255, 0) 70%),
    radial-gradient(40% 32% at 0% 38%, rgba(143, 107, 255, 0.09) 0%, rgba(143, 107, 255, 0) 70%),
    radial-gradient(44% 36% at 100% 78%, rgba(30, 94, 255, 0.08) 0%, rgba(30, 94, 255, 0) 72%);
}

/* B2. 动态极光 —— 让「不是死白」这件事本身是活的。
   三层品牌色雾团缓慢游走，全页都在极缓的明暗呼吸里，但没有任何一处是「动效」。
   必须挂在 position:fixed 的整屏层（body 的伪元素）上，不能挂进任何一个板块：
   挂在板块里的动画会在板块边界拉出硬边 —— 上一轮柔光那条接缝就是这么来的。

   只动 transform 与 opacity（都能走合成层，不触发重排重绘）。雾团之间要「各自游走」
   而不是整体平移，靠的是在位移之外叠一点 rotate：雾团离中心不同距离，绕中心转
   同样的角度就会走出不同的弧线，看上去就是各走各的，成本却只有一个图层。 */
.hilly-page::after {
  content: '';
  position: fixed;
  inset: -12%;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(38% 34% at 20% 26%, rgba(30, 94, 255, 0.3) 0%, rgba(30, 94, 255, 0) 64%),
    radial-gradient(34% 32% at 80% 20%, rgba(143, 107, 255, 0.27) 0%, rgba(143, 107, 255, 0) 66%),
    radial-gradient(40% 34% at 62% 84%, rgba(0, 168, 255, 0.22) 0%, rgba(0, 168, 255, 0) 68%);
  animation: hilly-aurora 30s linear infinite;
  will-change: transform, opacity;
}

@keyframes hilly-aurora {
  0% {
    transform: translate3d(-3.2%, -1.6%, 0) rotate(-2.8deg) scale(1);
    opacity: 0.8;
  }
  33% {
    transform: translate3d(1.9%, 2.6%, 0) rotate(1.8deg) scale(1.1);
    opacity: 1;
  }
  66% {
    transform: translate3d(3.4%, -2.1%, 0) rotate(3.8deg) scale(1.05);
    opacity: 0.87;
  }
  100% {
    transform: translate3d(-3.2%, -1.6%, 0) rotate(-2.8deg) scale(1);
    opacity: 0.8;
  }
}


/* C. 板块底色带。只给两组，且每组的首尾各带一段 160px 渐隐 ——
   这样两条带的四条边都是柔的，不会出现横平竖直的色块分界。
   中间留 #what / #audience / #faq 三段纯底色，节奏才是「起伏」而不是「均匀」。
   ★ 2026-10-17 删掉「产品矩阵」（#products）整节后，紫带只剩 #facts 一段：
     它原来是靠 #products 的底边（4.5%）接进来的，前面一变成纯底色的 #audience，
     矩形分界立刻显形 —— 所以 #facts 的顶边必须自带 160px 渐显。 */
.hilly-page #problems {
  background: linear-gradient(180deg,
      rgba(30, 94, 255, 0) 0%,
      rgba(30, 94, 255, 0.045) 160px,
      rgba(30, 94, 255, 0.045) 100%);
}

.hilly-page #capability {
  background: linear-gradient(180deg,
      rgba(30, 94, 255, 0.045) 0%,
      rgba(30, 94, 255, 0.045) calc(100% - 160px),
      rgba(30, 94, 255, 0) 100%);
}

.hilly-page #facts {
  background: linear-gradient(180deg,
      rgba(143, 107, 255, 0) 0%,
      rgba(143, 107, 255, 0.045) 160px,
      rgba(143, 107, 255, 0.045) calc(100% - 160px),
      rgba(143, 107, 255, 0) 100%);
}

/* E. 板块纵向节奏。
   styles.css:1069 的 .section 上下各留 --space-3xl(96px)，两个板块相接就是
   192px 纯空白。首页是满幅 bento 网格，撑得住这个留白；本页正文密度低，
   192px 会把每块内容割成孤岛 —— 实测 what→problems、facts→faq 等 8 处
   全是 192px。收到 --space-2xl(64px)，相接 128px，正好与本页首屏自己的
   下内边距（同为 64px）同一档，整页节奏一致。 */
.hilly-page .section {
  padding-top: var(--space-2xl);
  padding-bottom: var(--space-2xl);
}

/* #products 在 styles.css:1091/1095 有两条 ID 规则：padding-top:0、
   .section-header margin-bottom:0。首页里它紧跟在满宽区块之后就位，所以要贴上去；
   本页没有这个前提，那条 padding-top:0 会在 audience→products 之间只留 96px，
   与其余各处的 128px 不一致。ID 特异性(1,0,0)压得过 .hilly-page .section(0,2,0)，
   必须用同 ID 级别（1,1,0）才改得动。 */
.hilly-page #products {
  padding-top: var(--space-2xl);
}

/* 板块标题与它自己的内容之间同样偏松：全站 .section-header 的下边距是
   --space-2xl(64px)，收到 40px。注意 #what ≥1500px 与 #products 各有更
   特异的规则把它们压到 0，那两处不受本条影响。 */
.hilly-page .section-header {
  margin-bottom: 40px;
}

/* 首屏补一层品牌柔光 + 极淡点阵，顶替首页那层 3D canvas 缺位后的「平」。

   ⚠ 柔光的顶边必须越过 hero 自己（top:-172px），把面包屑和导航栏一起盖住。
   hero 的顶边落在 y=115，若柔光从 inset:0 起算，椭圆的边界就正好压在这条线上：
   实测同一列相邻两行 R 值从 236 掉到 211（Δ43），看着就是「导航栏和首屏有色差」。
   顶边外移之后整条渐变连续跨过 y=0..678，接缝不复存在。
   渐变中心写固定 200px 而不是百分比 —— 盒子被外移后高度变了，
   用百分比会让中心位置跟着漂。 */
.hilly-page .hilly-hero::before {
  content: '';
  position: absolute;
  top: -172px;
  right: 0;
  bottom: 0;
  left: 0;
  pointer-events: none;
  background: radial-gradient(62% 68% at 50% 200px, rgba(30, 94, 255, 0.15) 0%, rgba(30, 94, 255, 0) 68%);
}

/* 柔光外移后会盖到面包屑上。面包屑与 hero 同为 z-index:1，而 hero 在 DOM 里靠后，
   默认会被柔光压住；抬到 2 让正文始终在光晕之上，字口保持干净。 */
.hilly-page .hilly-breadcrumb {
  z-index: 2;
}

.hilly-page .hilly-hero::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  /* 点阵取 26px 网格 / 1.4px 点径 / 有效透明度约 18%：
     1px 点 + 12% 透明度在缩图里完全消失（等于没做），再深一档会在正文背后形成干扰。

     遮罩只用「垂直渐隐」，不用径向：
     径向遮罩的椭圆边界会露出**一条斜向硬边**（本机实测确实出现了，
     在首屏左侧空白处斜穿而过），因为点阵可见性有阈值，渐隐到中途就直接断掉。
     垂直渐隐在横向完全均匀，只在上方浓、往下淡，不会产生任何方向性边界。 */
  background-image: radial-gradient(rgba(30, 94, 255, 0.30) 1.4px, transparent 1.4px);
  background-size: 26px 26px;
  /* 顶端留 10% 由 0 渐入：点阵可见性有阈值，若一上来就是 0.85，
     它自己也会在 hero 顶边拉出一条横向硬边，和柔光的接缝叠在一起更显眼。 */
  -webkit-mask-image: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.85) 10%, rgba(0, 0, 0, 0.5) 48%, rgba(0, 0, 0, 0) 100%);
  mask-image: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.85) 10%, rgba(0, 0, 0, 0.5) 48%, rgba(0, 0, 0, 0) 100%);
  /* 上一轮点阵是唯一的主体，所以给到 0.6。现在主体换成了下面的协作网络画布，
     点阵退成「底纹」：压到 0.32，只提供一层工程图的颗粒感，不与连线抢读。 */
  opacity: 0.32;
}

/* 协作网络画布：铺满所属板块，本身不带任何可见边框 ——
   它的「边界」是在 canvas 内部按文字安全区算出来的（见 hilly.html 里的脚本），
   所以不会出现一个矩形。这里只负责定位与层级。

   层级（都在 .hilly-hero 自己的层叠上下文里）：
     ::before 柔光(auto)  <  ::after 点阵(auto)  <  canvas(1)  <  .container(2)
   正文必须最上，柔光与点阵都在画面之下，画布夹在中间。 */
.hilly-page .hilly-hero .hilly-net,
.hilly-page .hilly-cta-section .hilly-net {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: block;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* 正文抬到画布之上 */
.hilly-page .hilly-hero .container {
  position: relative;
  z-index: 2;
}

/* 网络上的实体标签（你 / 专家 / 分身 / 企业）。
   它们是真实 DOM 文本，爬虫读得到；画布会把每个标签当作枢纽，
   围绕它连线、向它汇聚流光 —— 首屏于是有了「谁在和谁协作」这层含义。
   位置刻意落在 .container 的左右之外，与正文互不干扰。
   窄屏两侧没有余量，整组隐藏，只留画布。 */
.hilly-page .hilly-arc {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
}

.hilly-page .hilly-arc span {
  position: absolute;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 13px;
  border-radius: var(--radius-full);
  background: rgba(255, 255, 255, 0.86);
  border: 1px solid rgba(30, 94, 255, 0.22);
  box-shadow: 0 4px 14px -8px rgba(30, 94, 255, 0.55);
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--text-secondary);
  white-space: nowrap;
}

.hilly-page .hilly-arc span::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--cyan-primary);
  box-shadow: 0 0 8px rgba(var(--btn-glow-rgb), 0.9);
}

.hilly-page .hilly-node-me {
  left: 6%;
  top: 23%;
}

.hilly-page .hilly-node-exp {
  left: 8%;
  top: 71%;
}

/* 分身是这张图的中心，给它最重的一档：品牌蓝字 + 更实的底 */
.hilly-page .hilly-node-agent {
  right: 6%;
  top: 23%;
  color: #1E5EFF;
  background: rgba(255, 255, 255, 0.95);
  border-color: rgba(30, 94, 255, 0.4);
}

.hilly-page .hilly-node-ent {
  right: 8%;
  top: 71%;
}

@media (max-width: 1100px) {
  .hilly-page .hilly-arc {
    display: none;
  }
}

/* 徽标里的状态点：站点原本只是一个静态圆点。加一次呼吸 + 一圈扩散，
   这是全页最省的「活着」信号。

   ⚠ 这里刻意全用 box-shadow、不用 transform ——
   按 CSS Overflow 规范，**变换后的盒子会计入祖先的 scrollWidth**：
   最初用 `transform: scale(3.4)` 画扩散环，实测 .pulse-dot 变成 scrollWidth 12 > clientWidth 5，
   在 21 个宽度里被适配审计判了 20 处「内容溢出自身」（其实是误报，但会长期盖住真问题）。
   box-shadow 不产生 scrollable overflow，同样的观感，零副作用。 */
.hilly-page .hero-badge .pulse-dot {
  position: relative;
  /* 徽标是 inline-flex，窄屏下文字撑满时这个点会被 flex 压扁（实测 320px 下只剩 5px）。
     状态点被压扁比不显示更糟，直接禁止收缩。 */
  flex: none;
  animation: hilly-pulse 2.6s ease-in-out infinite;
}

.hilly-page .hero-badge .pulse-dot::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  animation: hilly-ripple 2.6s ease-out infinite;
}

@keyframes hilly-pulse {

  0%,
  100% {
    box-shadow: 0 0 9px rgba(30, 94, 255, 0.95), 0 0 19px rgba(143, 107, 255, 0.62);
  }

  50% {
    box-shadow: 0 0 19px rgba(30, 94, 255, 1), 0 0 34px rgba(143, 107, 255, 0.95);
  }
}

@keyframes hilly-ripple {
  0% {
    box-shadow: 0 0 0 0 rgba(30, 94, 255, 0.72);
  }

  70%,
  100% {
    box-shadow: 0 0 0 12px rgba(30, 94, 255, 0);
  }
}

/* 减少动效：全部静态化。canvas 那一侧由脚本自己判断（直接不启动），
   这里处理纯 CSS 的部分。 */
@media (prefers-reduced-motion: reduce) {
  .hilly-page::after {
    animation: none;
    transform: none;
    opacity: 0.85;
  }

  .hilly-page .hero-badge .pulse-dot {
    animation: none;
  }

  .hilly-page .hero-badge .pulse-dot::after {
    display: none;
  }
}

/* 板块小标：从一行纯文字改成带品牌底色的胶囊，给每个板块一个视觉落点 */
.hilly-page .section-tag {
  display: inline-flex;
  align-items: center;
  padding: 6px 14px;
  border-radius: var(--radius-full);
  background: rgba(30, 94, 255, 0.09);
  border: 1px solid rgba(30, 94, 255, 0.18);
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  margin-bottom: 16px;
}

/* D. 卡片材质：统一一层偏蓝的柔和投影，替掉原来的中性灰。
   -22px 的负扩展让光晕收得很紧，只托起卡片边沿，不会糊成一片。 */
.hilly-page .hilly-def,
.hilly-page .hilly-mod,
.hilly-page .hilly-problem,
.hilly-page .hilly-fact,
.hilly-page .hilly-qa,
.hilly-page .hilly-cta-inner {
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04), 0 16px 32px -22px rgba(30, 94, 255, 0.45);
}

/* ==========================================================================
   交互态：hover 一律排在浮现态之后，确保浮起效果不被 .hilly-reveal 覆盖
   （两者同为 (0,1,0) 特异性时按源码顺序决胜）
   底色一律用 background-color 逐层覆盖，不用 background 简写 ——
   简写会把 background-image 一起重置，渐变元素在 hover 时会瞬间掉底。
   ========================================================================== */
.hilly-mod:hover {
  background-color: var(--bg-card-hover);
  border-color: var(--cyan-primary);
  box-shadow: var(--shadow-glow);
  transform: translateY(-4px);
}

.hilly-problem:hover {
  background-color: var(--bg-card-hover);
  border-color: var(--cyan-primary);
  box-shadow: var(--shadow-glow);
  transform: translateY(-4px);
}

.hilly-persona:hover {
  background-color: var(--bg-card-hover);
  border-color: var(--cyan-primary);
  color: var(--text-primary);
  transform: translateY(-3px);
}



/* ==========================================================================
   进场浮现：渐进增强。
   只有脚本确认「有 IntersectionObserver + 用户未要求减少动效」时，
   才会给元素加上 .hilly-reveal；否则元素从头到尾都是静态可见的。
   只做透明度不做位移 —— 位移会和上面的 hover 位移抢 transform。
   ========================================================================== */
.hilly-reveal {
  opacity: 0;
  transition: opacity 0.6s var(--ease-tactile);
}

.hilly-reveal.is-in {
  opacity: 1;
  /* 浮现完成后把过渡权交还给元素自身。否则 .hilly-reveal 的
     「transition: opacity」会一直压着 .hilly-mod 的 --transition-smooth，
     hover 的抬升与描边就会变成硬跳。这里显式列出会变的属性。 */
  transition: opacity 0.6s var(--ease-tactile), background-color 0.3s var(--ease-tactile),
    border-color 0.3s var(--ease-tactile), box-shadow 0.3s var(--ease-tactile), transform 0.3s var(--ease-tactile);
}

@media (prefers-reduced-motion: reduce) {
  .hilly-reveal {
    opacity: 1;
    transition: none;
  }
}

/* 披露组件：去掉展开动画与箭头过渡。
   注意 V 形自身的 transform: rotate() 要留着 —— 那是形状，不是动画。 */
@media (prefers-reduced-motion: reduce) {
  .hilly-mod[open] > .hilly-mod-body,
  .hilly-qa[open] > .hilly-qa-a {
    animation: none;
  }

  .hilly-mod-cue,
  .hilly-qa-cue,
  .hilly-mod-cue::before,
  .hilly-qa-cue::before {
    transition: none;
  }
}

/* ==========================================================================
   响应式
   ========================================================================== */
@media (max-width: 900px) {
  .hilly-hero {
    padding: var(--space-xl) 0 var(--space-2xl);
  }
}

@media (max-width: 640px) {
  .hilly-hero {
    padding: var(--space-lg) 0 var(--space-2xl);
  }

  .hilly-h1 {
    letter-spacing: -0.5px;
  }

  .hilly-slogan {
    font-size: 1.15rem;
  }

  .hilly-def {
    padding: 24px 20px;
  }

  .hilly-def::before {
    top: 20px;
    bottom: 20px;
  }

  .hilly-def-text {
    font-size: 0.98rem;
    line-height: 1.9;
  }

  .hilly-mod-head {
    padding: 16px 20px;
    column-gap: 12px;
  }

  .hilly-mod-body {
    padding: 16px 20px 20px;
  }

  .hilly-problem {
    padding: 24px 20px;
  }

  .hilly-persona {
    padding: 10px 16px;
    font-size: 0.86rem;
  }

  .hilly-cta-inner {
    padding: 40px 22px;
  }

  .hilly-qa-head {
    padding: 15px 18px;
  }

  .hilly-qa-a {
    padding: 14px 18px 18px;
  }

  .hilly-btn {
    flex: 1 1 100%;
  }
}

/* ==========================================================================
   大屏适配（≥1500px）
   --------------------------------------------------------------------------
   问题：全站 .container 的上限是 1200px（styles.css 的「全站三档响应式规范」），
   而本页几个正文块又各自收在 940px 以内。1920px 视口下实际可见内容只有
   1152px，两侧各空 384px；2560px 下各空 704px —— 整页读起来就是中间一窄条。

   这里只解决 hilly.html，不动 styles.css 里的共享 .container：首页的 bento
   版式是按 1200px 排的，没有逐屏回归就不该连带改。作用域统一挂 body.hilly-page，
   页内导航与页脚用的是同一个 .container，所以按页放宽后页内各段宽度依然一致，
   不会出现「头尾 1200、正文 1320」的错层。

   两条原则：
   1) 加宽容器必须同时加列。只放宽容器会把 2 列卡撑成 600px+ 的超宽卡，正文
      行长失控 —— 那比留白更难看。
   2) 散文块（.hilly-def / .hilly-lead）保留可读行宽，不跟着容器一起放宽。
      中文正文超过 45 字/行就开始难读，容器多出来的宽度交给网格去承接。
   ========================================================================== */

/* FAQ 的「≥1200 转两列」已随手风琴改版一并删除：
   展开某一条会在双列网格里把同行邻居顶下去，高度参差比拉长条更难看。
   现在的做法是把纵向长度交给折叠本身 —— 16 条收起后总共不到 1000px。 */

@media (min-width: 1500px) {

  .hilly-page .container {
    max-width: 1320px;
  }

  /* 首屏：容器放宽到 1080，但正文段自己收在 820。
     标题短、正文长，两者的合适宽度本来就不是同一个数。 */
  .hilly-page .hilly-hero .container {
    max-width: 1080px;
  }

  .hilly-page .hilly-lead {
    max-width: 820px;
    margin-left: auto;
    margin-right: auto;
  }

  /* 1. 什么是 Hilly：定义块与三个要点左右并排，把原来 940px 的窄条铺满。
     定义块占 5/12（约 530px），中文行宽落在 30 字上下，正好最好读；
     要点占 7/12，比整行 940px 更聚拢。 */
  .hilly-page #what .container {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    align-items: start;
    gap: 56px 48px;
  }

  .hilly-page #what .section-header {
    grid-column: 1 / -1;
    margin-bottom: 0;
  }

  .hilly-page .hilly-def,
  .hilly-page .hilly-points {
    max-width: none;
    margin: 0;
  }

  /* 3. 核心功能：已改为互斥手风琴，纵向单列到底，不再随容器加列。
     它省下来的高度就是这一屏最实在的收益 —— 1440 下从 2600px 收到约 900px。 */

  /* 4. 可引用事实：9 项排 4 列。
     9 不是 4 的倍数，放任 auto-fit 会得到「4 / 4 / 1」的残行（最后一行只有
     一格有内容，另三格空着）。这里让首项（产品定位）与末两项（关联产品、
     联系邮箱）各占两格 —— 2+1+1+1+1+1+1+2+2 = 12 = 3 整行，不残行，
     顺带突出了最常被整段引用的那一条。
     ⚠️ 依赖 <dl> 里 .hilly-fact 的现有顺序；若增删或调序必须同步改这里的
     nth-child 序号，否则会出现对不齐的空格。 */
  .hilly-page .hilly-facts {
    max-width: none;
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }

  .hilly-page .hilly-fact:nth-child(1),
  .hilly-page .hilly-fact:nth-child(8),
  .hilly-page .hilly-fact:nth-child(9) {
    grid-column: span 2;
  }

  /* 5. 适合人群：去掉 880 上限，8 个胶囊铺满整行 */
  .hilly-page .hilly-audience {
    max-width: none;
  }

  /* 6. FAQ 的两列规则已在 ≥1200 生效，这里不再重复 */

  /* 收尾板块与首屏同宽，首尾对齐 */
  .hilly-page .hilly-cta-section .container {
    max-width: 1080px;
  }
}

/* 更大屏：容器继续走，但停在 1520 —— 再宽中文正文的每行字数就压不住了。
   网格列数不再增加（3 列核心功能 / 4 列事实是内容数量决定的上限）。 */
@media (min-width: 1800px) {

  .hilly-page .container {
    max-width: 1420px;
  }

  .hilly-page .hilly-hero .container,
  .hilly-page .hilly-cta-section .container {
    max-width: 1160px;
  }

  /* 1920 下 4.6vw 已经到 88px，原上限 3.4rem(54px) 会显得标题偏小 */
  .hilly-page .hilly-h1 {
    font-size: clamp(2.1rem, 4.6vw, 4rem);
  }
}

@media (min-width: 2200px) {

  .hilly-page .container {
    max-width: 1520px;
  }

  .hilly-page .hilly-hero .container,
  .hilly-page .hilly-cta-section .container {
    max-width: 1240px;
  }

  .hilly-page .hilly-h1 {
    font-size: clamp(2.1rem, 4.6vw, 4.4rem);
  }
}

/* ==========================================================================
   页尾：扫码面板
   --------------------------------------------------------------------------
   形态统一优先于省事 —— 小程序码与 App 二维码做成一模一样的方块，
   只有底下那行提示字不同（一个点开看大图，一个直达下载页）。
   之前是「一个 ghost 按钮 + 一张横卡」：两种形态、两种交互，
   视觉重心全压在按钮上，二维码反而像个附件。

   ★ 为什么收成「一块面板」而不是两张卡：外层 .hilly-cta-inner 本身就是一张
     白卡（--bg-card + 圆角 + 投影），里面再套两张白卡就是卡套卡 ——
     两者只差 6% 的底色，边界全靠 1px 边框硬撑，看起来既平又碎。
     现在是一块极淡的品牌色面板 + 中间一根发丝线，一个物件、两个入口。
   ★ 底色用极淡的品牌色而不是灰：灰底在这个页面上会显脏，品牌色能带出「这里是
     扫码区」的语义，也让收尾板块多一层层次。
   ★ 图是 440×440 PNG（39×39 模块 / 纠错 H / 白边 44px），显示 108px。
     再小就贴到手机摄像头的解码边界了；窄屏才降到 88px（手机是贴着扫的）。
   ★ App 码中心放了吉祥物（从左侧小程序码里圆形抠出来的），所以两块都是
     「深色码点 + 彩色小狸」，视觉重量才对得上。码点用深海军蓝而不是品牌亮蓝：
     亮蓝底上吉祥物本身就糊进背景了，而且深色码点的扫描余量更大。
     改这张图之后必须用 Vision 回读 payload —— 中心挖洞对纠错 H 是有代价的。
   ========================================================================== */
.hilly-qr-row {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  max-width: 460px;
  margin: var(--space-xl) auto 0;
  padding: 22px 0;
  border-radius: 22px;
  border: 1px solid rgba(var(--base-accent-rgb), 0.11);
  background-image: linear-gradient(180deg,
      rgba(var(--base-accent-rgb), 0.05) 0%,
      rgba(var(--base-accent-rgb), 0.015) 100%);
}

.hilly-qr-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 4px 16px;
  border: 0;
  border-radius: 16px;
  background-color: transparent;
  /* button 默认不继承字体，不写这句标题会比旁边小一圈 */
  font: inherit;
  color: inherit;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: var(--transition-smooth);
}

/* 中间的分隔线落在第二格，长度只跟内容走，不贯穿整块面板。
   ★ 用渐隐而不是 border-left：硬切的一根线在浅底上会有两个突兀的端头，
     两端淡出 18% 之后才像「分隔」而不是「画了一条线」。 */
.hilly-qr-card + .hilly-qr-card {
  position: relative;
}

.hilly-qr-card + .hilly-qr-card::before {
  content: '';
  position: absolute;
  top: 10%;
  bottom: 10%;
  left: 0;
  width: 1px;
  background: linear-gradient(180deg,
      rgba(15, 23, 42, 0) 0%,
      rgba(15, 23, 42, 0.13) 18%,
      rgba(15, 23, 42, 0.13) 82%,
      rgba(15, 23, 42, 0) 100%);
  pointer-events: none;
}

.hilly-qr-card img {
  display: block;
  width: 108px;
  height: 108px;
  border-radius: 12px;
  background-color: #fff;
  transition: var(--transition-smooth);
}

.hilly-qr-name {
  margin-top: 14px;
  font-size: 0.94rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--text-primary);
  transition: var(--transition-smooth);
}

.hilly-qr-hint {
  margin-top: 5px;
  font-size: 0.76rem;
  line-height: 1.5;
  color: var(--text-muted);
}

/* 整块面板是一个物件，所以 hover 不再「浮起一张卡」，只让二维码亮一层、
   标题转到品牌色 —— 动静比抬卡片小，但方向是明确的 */
.hilly-qr-card:hover img {
  box-shadow: 0 10px 22px -12px rgba(15, 23, 42, 0.45);
  transform: translateY(-2px);
}

.hilly-qr-card:hover .hilly-qr-name {
  color: rgb(var(--base-accent-rgb));
}

.hilly-qr-card:focus-visible {
  outline: 2px solid rgba(var(--base-accent-rgb), 0.55);
  outline-offset: 2px;
}

@media (max-width: 620px) {
  /* 标题在窄屏必须降档：1.5rem 下 342px 宽一行只放得下 14 个字，
     配 balance 也会被挤成两行，降到 1.34rem 才能真正两行均衡 */
  .hilly-cta-title {
    font-size: 1.34rem;
  }

  /* ★ keep-all 把断行机会收回到标点与空格上。
     默认 CJK 任意两字之间都能断，于是「属于」被拆成「属」/「于」、
     说明行断在「渠」/「道」中间 —— 字都认识，但读起来是断的。 */
  .hilly-cta-title,
  .hilly-cta-note {
    word-break: keep-all;
  }

  .hilly-cta-note {
    font-size: 0.78rem;
  }

  .hilly-qr-row {
    padding: 16px 0;
    border-radius: 18px;
    margin-top: var(--space-lg);
  }

  .hilly-qr-card {
    padding: 2px 10px;
  }

  .hilly-qr-card img {
    width: 88px;
    height: 88px;
    border-radius: 10px;
  }

  .hilly-qr-name {
    margin-top: 10px;
    font-size: 0.86rem;
  }

  .hilly-qr-hint {
    margin-top: 4px;
    font-size: 0.7rem;
  }
}

