/**
 * ===== 深圳数字人才就业创业实战基地 · 官方网站样式 =====
 *
 * 独立于教务系统的样式表，不共享 css/style.css，避免互相污染。
 * 品牌色为基地既定色板（v1.39.0 起）：
 *   主蓝 #226CE1 · 橙 #FF791B · 浅蓝 #BADFFC · 深藏蓝 #062052
 * 图腾为 LOGO 中的鹿（龙马）头侧影 —— LOGO 本身不受单一颜色限制，
 * 按底色选用即可（白底用主蓝/深藏蓝，深底用白）。
 *
 * 设计取向：面向外部访客，克制、干净、可信；移动端优先适配。
 */

:root {
  /* ===== 品牌色板（四色，勿引入色板外的颜色）=====
   * 主蓝 #226CE1 · 橙 #FF791B · 浅蓝 #BADFFC · 深藏蓝 #062052
   *
   * 关于深紫 #48005B：它是 LOGO 源文件的原始色，v1.41.0 曾短暂升为品牌色，
   * 但实测与全站蓝橙体系不协调（且与深藏蓝对比度仅 1.07:1，深底不可用），
   * v1.43.0 起**移出色板**，LOGO 统一改用主蓝。色板回归四色。
   */
  --brand: #226ce1;          /* 主蓝：主色，按钮/链接/高亮 */
  --brand-dark: #1a56b8;     /* 主蓝加深（hover），同色系 */
  --brand-deep: #062052;     /* 深藏蓝：深色区块底、正文强调、渐变收尾 */
  --brand-light: #badffc;    /* 浅蓝：浅底块、弱化背景 */
  --brand-tint: #eaf4fe;     /* 浅蓝再淡化，用于大面积极浅底 */
  --accent: #ff791b;         /* 橙：强调色，数字/CTA/高亮标记 */

  --ink: #111827;
  --ink-2: #374151;
  --ink-3: #6b7280;
  --ink-4: #9ca3af;

  --line: #e5e7eb;
  --line-2: #f3f4f6;
  --bg: #ffffff;
  --bg-soft: #f7fbff;        /* 极浅蓝白，比纯灰更贴合色板 */
  --bg-dark: #062052;        /* 深藏蓝 */

  --ok: #22c55e;
  --warn: #ff791b;           /* 警告沿用色板橙，避免引入第五种颜色 */

  --radius: 12px;
  --radius-lg: 20px;
  --shadow-sm: 0 1px 2px rgba(6, 32, 82, .05);
  --shadow: 0 4px 16px rgba(6, 32, 82, .07);
  --shadow-lg: 0 16px 48px rgba(6, 32, 82, .12);

  /* ===== v1.62.0 科技感增强层 =====
   * 用户反馈「整体风格没有很出色的地方」，故补充一套「深度 + 光泽 + 光晕」令牌。
   * 全部基于既有四色色板推导，不引入新色。
   */
  --shadow-xl: 0 24px 70px rgba(6, 32, 82, .18), 0 4px 12px rgba(6, 32, 82, .06);
  --glow-brand: 0 0 0 1px rgba(34,108,225,.16), 0 8px 30px rgba(34,108,225,.22);
  --glow-accent: 0 8px 26px rgba(255,121,27,.30);
  --ring-brand: rgba(34,108,225,.35);
  --glass-bg: rgba(255,255,255,.72);
  --glass-line: rgba(255,255,255,.65);
  --ink-deep: #0a1430;       /* 比 --brand-deep 更深的「舞台黑蓝」，用于首屏大底 */
  --ease-out: cubic-bezier(.16,1,.3,1);
  --ease-spring: cubic-bezier(.34,1.56,.64,1);

  --maxw: 1200px;
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC",
          "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Arial, sans-serif;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html { scroll-behavior: smooth; }

body {
  font-family: var(--font);
  color: var(--ink);
  background: var(--bg);
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

a { color: inherit; text-decoration: none; }
img { max-width: 100%; display: block; }

.wrap {
  width: 100%;
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0 24px;
}

/* ================= 顶部导航 ================= */
/* v1.62.0：页眉改为「深色玻璃」，与深色首屏融为一体。
   此前是白底毛玻璃，浮在深色首屏上会出现一道突兀的浅色横带。
   未滚动时透明（完全融入首屏），滚动后加深并显影分隔线。 */
.site-header {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 100;
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background .3s var(--ease-out), border-color .3s, box-shadow .3s, backdrop-filter .3s;
}
.site-header.scrolled {
  background: rgba(8, 20, 48, .78);
  backdrop-filter: saturate(180%) blur(16px);
  -webkit-backdrop-filter: saturate(180%) blur(16px);
  border-bottom-color: rgba(186,223,252,.14);
  box-shadow: 0 8px 32px rgba(3, 10, 28, .30);
}

/* 滚过首屏、进入浅色板块后：页眉切回白底毛玻璃 + 深色 LOGO/文字。
   否则深色页眉会压出一条突兀的暗带，且白字在白底上不可读。
   （LOGO 图片的明暗切换由 site.js 同步，此处只管文字与配色） */
.site-header.light {
  background: rgba(255, 255, 255, .86);
  border-bottom-color: var(--line);
  box-shadow: 0 1px 3px rgba(6,32,82,.05), 0 10px 30px -18px rgba(6,32,82,.18);
}
.site-header.light .nav-links a { color: var(--ink-2); }
.site-header.light .nav-links a:hover { color: var(--brand); }
.site-header.light .nav-links a.active { color: var(--brand); }
.site-header.light .nav-links a.active::after {
  background: var(--brand);
  box-shadow: none;
}
.site-header.light .nav-toggle span { background: var(--ink); }
.site-header.light .nav-toggle {
  border-color: var(--line);
  background: transparent;
}
.site-header.light .nav-actions .btn-ghost {
  background: transparent;
  border-color: var(--line);
  color: var(--ink-2);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
.site-header.light .nav-actions .btn-ghost:hover {
  border-color: var(--brand);
  color: var(--brand);
  background: var(--brand-tint);
}
.site-header.light .nav-actions .btn-primary {
  box-shadow: 0 6px 18px rgba(34,108,225,.30), inset 0 1px 0 rgba(255,255,255,.22);
}

/* 页眉内的文字/图标在深底上统一为浅色 */
/* ★ v1.64.0 动效补齐：深色舞台上加「文字发光 + 渐变光条」，
   否则白 76% → 白 100% 的变化太微弱，用户感觉「没有动效」。 */
.site-header .nav-links a { color: rgba(255,255,255,.76); }
@media (hover: hover) {
  .site-header .nav-links a:hover {
    color: #fff;
    text-shadow: 0 0 14px rgba(127,192,255,.85);
  }
}
.site-header .nav-links a::before {
  background: linear-gradient(90deg, #7fc0ff, #ffb066);
  box-shadow: 0 0 10px rgba(127,192,255,.7);
}
.site-header .nav-links a.active { color: #fff; }
.site-header .nav-links a.active::after {
  background: linear-gradient(90deg, #7fc0ff, #ffb066);
  box-shadow: 0 0 12px rgba(127,192,255,.65);
}
/* 浅色态（滚过首屏后）回到品牌蓝→橙渐变，光晕收敛 */
.site-header.light .nav-links a::before {
  background: linear-gradient(90deg, var(--brand), var(--accent));
  box-shadow: none;
}
@media (hover: hover) {
  .site-header.light .nav-links a:hover { text-shadow: none; }
}
.site-header .nav-toggle span { background: #fff; }
.site-header .nav-toggle {
  border-color: rgba(186,223,252,.30);
  background: rgba(255,255,255,.08);
}
/* 页眉「合作洽谈」幽灵按钮：深底玻璃描边 */
.site-header .nav-actions .btn-ghost {
  background: rgba(255,255,255,.07);
  border-color: rgba(186,223,252,.30);
  color: #fff;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
.site-header .nav-actions .btn-ghost:hover {
  background: rgba(255,255,255,.15);
  border-color: rgba(186,223,252,.55);
}
/* 在线报名：深底上让橙色描边/辉光更亮，突出主 CTA */
.site-header .nav-actions .btn-primary {
  box-shadow: 0 6px 22px rgba(34,108,225,.45), inset 0 1px 0 rgba(255,255,255,.22);
}

.nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 84px;
}

/* 品牌区：整块锁标。锁标图本身已含全部文字，页面上不再另写机构名。
   v1.42.0 用户反馈原 38px 小徽章 + 两行小字「太淡、太小、不大气」，
   故改为锁标整体呈现，高度给到 52px。
   v1.44.0 用户反馈「页脚 LOGO 比页眉还大，不合理」：
   原先页眉 46px、页脚 76px，页脚反比页眉大 1.65 倍，主次颠倒。
   现调整为页眉 56px（主导）、页脚 52px（次要），页眉不再小于页脚。
   v1.61.0 用户反馈「整体尺寸偏小」，页眉 56 → 64px（导航高 84px）。
   v1.62.0 短暂改为竖排锁标。
   ★ v1.63.0 用户反馈「LOGO的比例不行哦，还是换成横版的吧」——
   竖排锁标宽高比仅 1.58:1，页眉 76px 高时横向只占约 120px，
   在横向很长的页眉里像一根又高又窄的柱子，比例失衡。
   现改回横版锁标 brand_nav2_*（徽章在左 + 右侧三行文字左对齐），
   宽高比约 4.52:1，页眉 76px 高时横向约 343px，视觉重量与导航相称；
   导航高度从 96px 回落到 84px（横版不需要竖排那样的纵向空间）。 */
.nav-brand { display: flex; align-items: center; flex: none; }
.nav-brand img {
  height: 64px;   /* 横版锁标：徽章 + 右侧中文全称 + 英文全称两行 */
  width: auto;
  display: block;
  /* ★ v1.68.0：`.nav-brand` 是 flex 子项，默认 flex-shrink:1。
     当页眉横向空间不足（窄屏 / 菜单变长）时，浏览器会连图片一起压缩，
     锁标被挤成 102px 宽（正常 289px）—— 文字糊成一团。
     锁标是品牌的固定资产，不该参与空间争夺：设为不可收缩。
     真正的空间不足由 @media (max-width:1080px) 收 gap + 760px 切汉堡菜单解决。 */
  flex: none;
}

.nav-links {
  display: flex;
  align-items: center;
  gap: 30px;
  list-style: none;
}
/* ★ v1.64.0 用户反馈「鼠标平移到其他菜单上没有动效」——
   原实现只有 `transition: color .2s`，鼠标移上去仅颜色渐变，
   放在深色舞台上（白 76% → 白 100%）肉眼几乎看不出变化。
   现补齐与全站一致的动效语言：底部渐变光条滑入 + 轻微上浮 + 文字发光。
   用 ::before 做下划线（与 .active 的 ::after 分开，避免互相覆盖），
   默认 transform: scaleX(0) 收起，hover 时展开到 1，配 var(--ease-out) 缓动。 */
.nav-links a {
  font-size: 14.5px;
  color: var(--ink-2);
  font-weight: 500;
  position: relative;
  padding: 6px 2px;
  /* ★ v1.68.0：菜单项是中文短语，flex 容器宽度不足时浏览器会逐字断行，
     出现「基地介 / 绍」「课程体 / 系」这种竖排两行的破版。
     菜单文字永远不该换行 —— 空间不够时应该由下方的中间档位收窄 gap，
     再不够才切移动端汉堡菜单。 */
  white-space: nowrap;
  transition: color .28s var(--ease-out), transform .28s var(--ease-out);
}
/* hover 下划线：从中心向两侧展开 */
.nav-links a::before {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 2px;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--brand), var(--accent));
  transform: scaleX(0);
  transform-origin: center;
  transition: transform .34s var(--ease-out);
}
@media (hover: hover) {
  .nav-links a:hover { color: var(--brand); transform: translateY(-1.5px); }
  .nav-links a:hover::before { transform: scaleX(1); }
}
/* v1.51.0：当前板块的导航项高亮（scrollspy / 点击） */
.nav-links a.active { color: var(--brand); font-weight: 700; }
.nav-links a.active::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 2.5px;
  border-radius: 2px;
  background: var(--brand);
}
/* 当前项不重复显示 hover 下划线 */
.nav-links a.active::before { display: none; }

.nav-actions { display: flex; align-items: center; gap: 10px; }

/* 移动端菜单按钮 */
/* 移动端菜单遮罩（v1.59.0）：展开菜单时盖住页面内容，点遮罩关闭 */
.nav-mask {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(6, 32, 82, .45);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  z-index: 90;
  opacity: 0;
  transition: opacity .25s;
}
.nav-mask.show { display: block; opacity: 1; }

.nav-toggle {
  display: none;
  width: 42px; height: 42px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: #fff;
  cursor: pointer;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
}
.nav-toggle span {
  display: block;
  width: 17px; height: 1.8px;
  background: var(--ink-2);
  border-radius: 2px;
  transition: transform .25s, opacity .2s;
}
.nav-toggle.open span:nth-child(1) { transform: translateY(5.8px) rotate(45deg); }
.nav-toggle.open span:nth-child(2) { opacity: 0; }
.nav-toggle.open span:nth-child(3) { transform: translateY(-5.8px) rotate(-45deg); }

/* ================= 按钮 ================= */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  padding: 11px 22px;
  border-radius: 10px;
  font-size: 14.5px;
  font-weight: 600;
  cursor: pointer;
  border: 1px solid transparent;
  transition: transform .26s var(--ease-out), box-shadow .26s var(--ease-out),
              background .26s, border-color .26s, color .26s;
  white-space: nowrap;
  font-family: inherit;
}
.btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(34,108,225,.35);
}
.btn-primary {
  background: linear-gradient(135deg, #2f7ff0 0%, var(--brand) 48%, #1a56c8 100%);
  color: #fff;
  box-shadow: 0 6px 18px rgba(34, 108, 225, .30), inset 0 1px 0 rgba(255,255,255,.22);
  position: relative;
  overflow: hidden;
}
/* 光泽扫过（hover 时一条高光从左滑到右） */
.btn-primary::after {
  content: '';
  position: absolute;
  top: 0; left: -75%;
  width: 45%; height: 100%;
  background: linear-gradient(100deg, transparent, rgba(255, 255, 255, .42), transparent);
  transform: skewX(-20deg);
  transition: left .62s var(--ease-out);
  pointer-events: none;
}
.btn-primary:hover::after { left: 125%; }
.btn-primary:hover {
  background: linear-gradient(135deg, #3a8af5 0%, var(--brand-dark) 55%, #1649a8 100%);
  transform: translateY(-2px);
  box-shadow: 0 14px 34px rgba(34, 108, 225, .48), inset 0 1px 0 rgba(255,255,255,.28);
}
/* v1.62.0：主 CTA 加一圈常驻柔光，页面上更"抓眼" */
.btn-primary.btn-lg {
  box-shadow: 0 8px 24px rgba(34,108,225,.38), 0 0 0 1px rgba(34,108,225,.10),
              inset 0 1px 0 rgba(255,255,255,.24);
}
.btn-primary.btn-lg:hover {
  box-shadow: 0 18px 46px rgba(34,108,225,.52), 0 0 0 4px rgba(34,108,225,.13),
              inset 0 1px 0 rgba(255,255,255,.30);
}
.btn-ghost {
  background: transparent;
  color: var(--ink-2);
  border-color: var(--line);
}
.btn-ghost:hover { border-color: var(--brand); color: var(--brand); background: var(--brand-tint); }
.btn:active { transform: translateY(1px) scale(.985); }
.btn-light {
  background: rgba(255,255,255,.14);
  color: #fff;
  border-color: rgba(255,255,255,.28);
  backdrop-filter: blur(6px);
}
.btn-light:hover { background: rgba(255,255,255,.24); transform: translateY(-1px); }
.btn-lg { padding: 14px 30px; font-size: 15.5px; border-radius: 12px; }

/* ================= 首屏 ================= */
/* v1.62.0 视觉升级：由「浅底 + 淡光斑」改为「深色舞台 + 聚光 + 细网格」。
   深底让品牌蓝和橙色真正跳出来，中间调层次更多，观感更"贵"。
   深色区在首屏内做渐隐收边，下方板块仍是浅色，不会全站变暗。 */
.hero {
  position: relative;
  /* ★ v1.69.3：下留白 96 → 56（用户「底部白色为达到一屏」）。
     白底地址条已删除，首屏底部只剩深色渐变，留白可以收得更紧。
     页眉 84px 仍完整让出，标题不会被遮。
     ⚠️ 改这里必须同步改 @media (max-height: 720px) 里的 .hero padding。 */
  /* ★ v1.69.3：下留白 96 → 32（分两步：96→56 去白条，56→32 补一屏）。
     白底地址条已删除，首屏底部只剩深色渐变；
     且桌面端图片卡现在由 .hero-inner 的 min-height 撑满，
     下留白纯粹是"呼吸空间"，收到 32 就够（图片卡自身的圆角与投影
     已经提供了视觉边界，不需要更多空白）。
     ⚠️ 改这里必须同步改两处：
        ① .hero-inner 的 min-height 公式（− 32px 那一项）
        ② @media (max-height: 720px) 里的 .hero padding 与对应公式 */
  /* ★ v1.69.10：下留白 32 → 74（用户「不是一屏。下面有白色」）。
     这次不是"想留更多白"，而是修一个**首屏高度算重的错误**：
     .hero-inner 的公式里减了一项「页眉 84px」，但 .site-header 是
     position: fixed —— 它浮在文档流上、不占任何高度，.hero 从 y=0 起算，
     其 padding-top: 152px **已经把页眉完整让开了**。再减 84 就是重复扣除。
     结果首屏总高恰好 = 100vh − 84，底部露出 84px 白边（实测三档全差 84）：
       1536×816 → hero bottom 732（差 84）
       1366×768 → hero bottom 684（差 84）
       1440×900 → hero bottom 816（差 84）
     修法：公式去掉那个 84，并把省下的空间**按用户选择「图片与底部留白均分」**
     处理 —— 下留白 32 → 74（多 42px 呼吸空间），其余 42px 归图片卡。
     这样仍然精确一屏：152 + (100vh − 152 − 74) + 74 = 100vh ✓
     ⚠️ 这里的 152 / 74 必须与 .hero-inner 的公式严格同步（见其注释）。 */
  padding: 152px 0 74px;
  background:
    radial-gradient(1200px 640px at 78% -14%, rgba(34,108,225,.42), transparent 62%),
    radial-gradient(900px 520px at 6% 108%, rgba(255,121,27,.16), transparent 62%),
    linear-gradient(168deg, #0a1430 0%, var(--ink-deep) 32%, #08193f 68%, #061634 100%);
  overflow: hidden;
  color: #fff;
  isolation: isolate;
}
/* 深色区底部保留一道柔和光带，衔接下方浅色板块 */
.hero .hero-fade {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 90px;
  background: linear-gradient(180deg, rgba(6,22,52,0) 0%, rgba(34,108,225,.16) 70%, rgba(34,108,225,.22) 100%);
  pointer-events: none;
  z-index: 3;
}
/* 聚光：缓慢漂移的光晕，制造"舞台呼吸感" */
.hero::before {
  content: '';
  position: absolute;
  width: 780px; height: 780px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(34,108,225,.46), rgba(34,108,225,.10) 46%, transparent 70%);
  top: -300px; right: -160px;
  filter: blur(6px);
  animation: heroFloat 18s ease-in-out infinite alternate;
  pointer-events: none;
  z-index: 1;
}
@keyframes heroFloat {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(-90px, 60px, 0) scale(1.16); }
}
/* 细网格：科技感的"坐标纸"底层，径向遮罩聚焦中部 */
.hero::after {
  content: '';
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(186,223,252,.09) 1px, transparent 1px),
    linear-gradient(90deg, rgba(186,223,252,.09) 1px, transparent 1px);
  background-size: 52px 52px;
  mask-image: radial-gradient(ellipse 76% 64% at 50% 38%, #000 34%, transparent 100%);
  -webkit-mask-image: radial-gradient(ellipse 76% 64% at 50% 38%, #000 34%, transparent 100%);
  pointer-events: none;
  z-index: 1;
}
.hero .wrap { position: relative; z-index: 4; }

/* ★ v1.69.3 用户要求「右侧撑满整个首屏高度」。
   —— 第一次尝试只写 align-items: stretch，结果卡片高度 = 行高，
      而行高由**左栏文案**决定（447px），图片卡只有 531px，
      视口 768px 下底部仍空出 85px（实测 cardBottom 683 / 视口 768）。
      stretch 只能让卡片等于"这一行的高度"，管不了"这一行有多高"。

   正确做法：把行高**显式钉到首屏可用高度**。
     可用高度 = 100vh - 上留白(152) - 下留白(74)
     ⚠️ 公式里**不该再减页眉高度**！.site-header 是 position: fixed，
        浮在文档流上、不占高度，.hero 从 y=0 起算，
        其 padding-top: 152px 已经完整让开了页眉。
        v1.69.3 起这里一直多减了 84px，导致首屏总高恰好 = 100vh − 84，
        底部露出 84px 白边（用户「不是一屏。下面有白色」）。
     v1.69.10 修正：去掉那个 84，并按用户选择「图片与底部留白均分」
        把省下的空间分给下留白（32 → 74）与图片卡各 42px。
     ⚠️ 这里的 152 / 74 必须与 .hero 的 padding 严格同步（两处）。
   ⚠️ min-height: 0 —— grid 行的 min-height 默认是 auto，
      内容（6 行 + 展开详情约 449px）会把行顶高，导致图片卡比
      可用高度还高、首屏反而溢出。给 0 才能让行高被 100vh 算法说了算，
      超出部分由 .hero-visual 的 min-height 与页面滚动承接。 */
.hero-inner {
  display: grid;
  grid-template-columns: 1.15fr .85fr;
  grid-template-rows: minmax(0, auto);
  gap: 56px;
  /* 行高 = 首屏可用高度。用 minmax 兜一个 400px 下限：
     极矮视口（如 1024×600）下 calc 可能算出很小的值，
     那时让页面滚动，而不是把图片卡压成一条缝。 */
  min-height: clamp(400px, calc(100vh - 152px - 74px), 900px);
  align-items: stretch;
}
.hero-inner > div:first-child {
  /* 左栏文案：在拉伸出来的行高里垂直居中 + 自身不拉伸 */
  align-self: center;
}
.hero-inner > .hero-card {
  align-self: stretch;
}

.badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 15px 7px 9px;
  background: rgba(255,255,255,.08);
  border: 1px solid rgba(186,223,252,.26);
  border-radius: 999px;
  font-size: 13px;
  color: rgba(255,255,255,.88);
  font-weight: 500;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.10);
  margin-bottom: 24px;
}
.badge-dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: #6ee7a8;
  box-shadow: 0 0 0 3px rgba(110,231,168,.22), 0 0 10px rgba(110,231,168,.75);
  margin-left: 6px;
  animation: dotPulse 2.6s ease-in-out infinite;
}
@keyframes dotPulse {
  0%, 100% { box-shadow: 0 0 0 3px rgba(110,231,168,.20), 0 0 8px rgba(110,231,168,.60); }
  50%      { box-shadow: 0 0 0 5px rgba(110,231,168,.10), 0 0 16px rgba(110,231,168,.95); }
}

.hero h1 {
  font-size: clamp(31px, 4.5vw, 53px);
  line-height: 1.16;
  letter-spacing: -1.3px;
  font-weight: 800;
  margin-bottom: 22px;
  color: #fff;
  text-wrap: balance;
}
.hero h1 em {
  font-style: normal;
  background: linear-gradient(104deg, #7fc0ff 0%, #badffc 42%, #ffb066 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 2px 14px rgba(127,192,255,.28));
}

.hero-sub {
  font-size: 17px;
  color: rgba(255,255,255,.76);
  max-width: 560px;
  margin-bottom: 32px;
  line-height: 1.82;
}

.hero-cta { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 36px; }

.hero-note {
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: 13.5px;
  color: rgba(255,255,255,.52);
}

/* 深底上的次要按钮：玻璃描边 */
.hero .btn-ghost {
  background: rgba(255,255,255,.07);
  border-color: rgba(186,223,252,.30);
  color: #fff;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
.hero .btn-ghost:hover {
  background: rgba(255,255,255,.14);
  border-color: rgba(186,223,252,.55);
}

/* ★ v1.69.3：白底 → 透明。
   原来 .hero-card 是白底白卡（v1.57.1 的设计化面板），做成图片型之后
   白底只在圆角外露出一圈边，反而像"图片没对齐卡片"，且底部白条
   （.hero-card-foot）是首屏填不满一屏的直接原因。
   现在整个卡片透明，只保留圆角裁切与投影，让图片自己说话。

   ★ v1.69.8 层级精简（用户「这里的层级太多了」）：
   实测问题 —— 首屏右侧从上到下叠了 **四层同心圆角**：
       .hero-card 18→20px  →  .hero-visual 20px  →  .hv-majors 13px  →  .hv-major 9px
   每一层都往内缩几个像素、每一层都描一道边。390px 窄屏下放大到极致：
   卡片圆角外一圈、玻璃层缩进 8px 再一圈、选中行再缩一圈、数据格再一圈，
   四道弧线挤在 340px 宽里，观感就是"糊"和"碎"。

   减层方案：**卡片层不再参与视觉，只做布局容器。**
     · 去掉 border-radius 与 box-shadow —— 圆角与投影改由 .hero-visual
       单独承担（它是真正贴着图的那一层，只有它需要被"裁"）。
     · 去掉 overflow: hidden —— 原先它是为圆角裁切服务的；现在圆角在
       .hero-visual 上，而 .hero-visual 用 .hv-img 的 border-radius: inherit
       自己裁图，不需要外层再裁一次。
     · 保留 min-width: 0（它是防水平滚动条的，与视觉无关）。
   ⚠️ 为什么保留 .hero-card 这个容器本身而不直接把类合并到 .hero-visual：
       它是 grid item，承担 align-self: stretch（撑满首屏可用高度）。
       把它和一个"以内容决定高度的 flex 列"合并会让 stretch 语义打架，
       删层要删视觉层，不是删布局层。 */
.hero-card {
  background: transparent;
  border: none;
  padding: 0;
  position: relative;
  min-width: 0;
}

/* ★ v1.68.0 图片型首屏视觉（用户要求「右侧换成图片型」）
   —— 科技感场景图铺满，底部叠加玻璃信息层。
   图片为 AI 生成的抽象科技场景，**刻意不含人物**（写实人物会穿帮，见坑 31）。

   ★ v1.68.2 重大修正：原用固定 `aspect-ratio: 1024/1336` 让整块高度锁定在
   桌面约 605px，加上首屏上下留白 292px，首屏总高固定 946px ——
   结果在 1366×768（最常见笔记本）超出视口 289px、1440×900 超出 157px，
   用户反馈「在一个页面不能完整显示」。
   现改为**由视口高度反推图片高度**，让首屏始终收在一屏内：
     可用高度 = 100vh - 页眉(84) - 上下留白(164+128) - 余量(24)
   再用 min() 兜一个上限 620px（超宽屏时不让图片无限长高），
   用 clamp() 兜一个下限 380px（极矮视口时保证图片不消失）。
   图片本身仍用 object-fit: cover 裁切，不会变形。 */
/* ★ v1.69.2 关键结构调整：
   原先把「图片 + 玻璃层」当成一个固定高度的盒子，玻璃层 absolute 贴在底部。
   现在玻璃层要能随展开变高，如果还 absolute，详情会被图片下边缘裁掉。
   → 改成「两层」：
      · .hero-visual  = 外层，负责【最小高度】和背景图铺满
      · .hv-majors    = 普通流子元素，负责撑高整个盒子

   实现方式：图片改为绝对定位铺底（不参与高度计算），
   再放一个占位块 .hv-spacer 保证图片区的最小可视高度。
   这样折叠时盒子 = 最小高度，展开时 = 最小高度 + 详情高度，图片始终铺满。 */
/* ★ v1.69.3 关键结构调整（用户四项需求）：
   ① 「底部白色为达到一屏」→ 删掉白底地址条，图片卡下沿顶到首屏底部
   ② 「右侧还是没达到我的效果」→ .hero-card 主动作区不再参与"居中"，
      改用 align-items: stretch 让图片卡天然撑满整个可用高度
   ③ 「点击课程底图显示相关大图」→ 6 张专属底图叠层，改 opacity 交叉渐变
   ④ 「内容更丰富、动效更强」→ 内容分层错峰入场 + 底图微缩放

   为什么不用 `.hero-visual` 继续 `calc(100vh - ...)` 硬算高度：
   之前一直这么算，留白值一改就要同步改四五处，而且左栏文案高度是估的、永远会偏。
   现在把"可用高度"这个概念收敛到 `.hero-inner` 的 min-height 一处，
   `.hero-card` 用 stretch 铺满该高度，两者天然等高，零维护。
   （详见 .hero-inner 的注释）
   为什么改用 opacity 叠层做底图切换，见下方 .hv-img。 */
.hero-visual {
  position: relative;
  aspect-ratio: auto;
  /* ★ v1.69.3：高度不再硬算，改为「铺满 .hero-card 给的高度」。
     .hero-card 是 grid item + align-self: stretch → 高度 = 行高 = 首屏可用高度。
     文本区（左侧）的天然高度通常小于这个值，所以撑满的总是图片卡。
     ⚠️ 仍需一个下限：极矮视口（如 1024×600）下 grid 行高可能小于
        展开态详情所需，那时靠 min-height 兜底并由页面滚动承接。 */
  height: 100%;
  min-height: 400px;
  /* ⚠️ 这里不能用 overflow: hidden —— 展开详情要把盒子顶高。
     见下方 .hv-img 的圆角裁切方案。
     ★ v1.69.8：圆角与投影从 .hero-card 接管过来 —— 它是真正贴着
     底图的那一层，只有它需要被裁切。半径沿用 --radius-lg(20px)，
     比原来的 18px 略大一点，在扁宽比例下弧线更松、更"一整块"。 */
  border-radius: var(--radius-lg, 20px);
  box-shadow: 0 26px 60px -22px rgba(2, 10, 30, .72);
  /* ★ v1.69.8 关键：一次性把「底图 + 玻璃层」按圆角轮廓裁掉。
     为什么不用 overflow: hidden —— 上面刚说过它会阻止盒子变高，
     展开详情时会被裁掉。clip-path 只裁**绘制**，不影响布局与高度，
     正好同时满足"要圆角"和"要能变高"两个需求。
     ⚠️ 必须与 border-radius 用同一个值，否则两者轮廓不重合，
        会在弧线上露出一条底色缝。改动半径时两处必须同改。 */
  clip-path: inset(0 round var(--radius-lg, 20px));
  background: linear-gradient(158deg, #0a1c46, var(--brand-deep));
  display: flex;
  flex-direction: column;
  /* 玻璃层贴底、图片区占上方剩余空间 */
  justify-content: flex-end;
  /* 为叠层底图建立包含块，同时隔离混合模式 */
  isolation: isolate;
}
/* ---------- 叠层底图（★ v1.69.3 新增）----------
   6 张图各自一张 <img>，全部绝对定位铺满、叠在一起，
   靠 .is-active 切 opacity 做交叉渐变。

   为什么不用「换 src」：
     <img src="b.jpg"> 换源后浏览器要重新解码，解码完成前会显示旧的或空白，
     慢网下能明显看到闪一下。叠层方案是纯 GPU 合成，切换零延迟、零闪烁。

   为什么不用 CSS background-image 换 URL：
     同理 —— background 换 URL 也要重新解码，且失去 srcset 响应式能力
     （无法让浏览器按视口宽度自动选 480/720/960 档）。
     用 <img srcset> 才能既响应式又平滑。 */
.hv-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  /* ★ v1.69.6：object-position 从 `center 42%` 改为 `center 30%`。
     原因：底图已换成用户提供的 6 张新图，且我先把它们统一裁成了 16:9
     （见 images/hero/majors 的处理说明）—— 新图构图的特征是
     **上半部是画面主体、下半部是留白渐变**（留白正好落在玻璃层所在位置）。
     42% 的取值是针对上一批「竖版、主体居中偏上」的图调的；
     换图后要重新对：图片区在 1512×982 上是 1.70、1920×1080 上是 1.94，
     图是 1.78，所以 1920 上会纵向裁掉约 8%。
     此时取 30% 意味着「从上往下 30% 处对齐容器上沿」——
     裁掉的 8% 主要落在**最底部**（也就是留白区），
     画面主体（还在上半部）完整保留。
     ⚠️ 换底图必须重核这个值：它跟"图的比例 + 构图重心"两者绑定，
        不是可以沿用的常量。 */
  object-position: center 30%;
  filter: saturate(1.06);
  border-radius: inherit;
  opacity: 0;
  /* ★ 动效④之一：底图切换时轻微放大 → 1，
     让"换了一张图"这件事有可感知的运动，而不只是淡入淡出。 */
  transform: scale(1.045);
  transition: opacity .62s var(--ease-out), transform 1.1s var(--ease-out);
  will-change: opacity, transform;
}
.hv-img.is-active {
  opacity: 1;
  transform: scale(1);
}
/* 占位块：撑开图片区 —— 既要"保证最小可视高度"，又要"吃掉剩余空间"。
   ★ v1.69.3 关键修正：flex: 0 0 auto → flex: 1 0 auto。
     原来写 flex: 0 0 auto（不长大不缩小），配合 min-height 只能保证下限；
     但卡片被 .hero-inner 的 min-height 撑到 714px 时，
     多出来的 207px 没地方去，全部变成 justify-content: flex-end 的空白间隙
     —— 因为底图是 position: absolute 铺满整盒，视觉上"看不出"有间隙，
     实际效果是图片可见区只有 spacer 的 88px，图被玻璃层压成一条。
     这正是用户反复说的「右侧还是没达到我的效果」。

     flex: 1 0 auto 的语义正是这里需要的：
       · grow  = 1 → 允许长大，把剩余空间全部吃下来（给图片）
       · shrink= 0 → 绝不被压缩
     ⚠️ shrink 必须是 0！手册坑 42 记录过：写 flex: 1 1 auto 时
        min-height 会被内容突破 —— shrink 允许收缩，而 min-height 与
        内容高度冲突时浏览器优先满足内容，于是图片区被压到几十像素。
        这里 shrink=0 就彻底堵住了那条路径。 */
.hv-spacer { flex: 1 0 auto; min-height: clamp(80px, 15vh, 240px); }
/* 底部渐隐。
   ★ v1.68.0 实测结论：原设计想用遮罩「压暗下半部分让玻璃层可读」，
   但这张图本身下半部分就是深色负空间，遮罩的渐变起点反而在图中
   显出一条隐约的水平分界线（像图层没对齐）。
   改为极轻的一层（峰值仅 .30、且从 62% 才起步），只负责把底部压向
   --brand-deep 统一色温。
   ⚠️ z-index: 1 —— 必须在图片之上、玻璃层之下，否则会把玻璃层也压暗。 */
.hero-visual::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 40%;
  z-index: 1;
  background: linear-gradient(180deg, rgba(6, 16, 40, 0) 0%,
                                      rgba(6, 16, 40, .16) 62%,
                                      rgba(6, 16, 40, .30) 100%);
  pointer-events: none;
  border-radius: inherit;
}
/* ★ v1.69.3 动效④之三：底图上方一道极淡的「高光扫过」。
   切换专业时重新触发，让底图变化被注意到（否则只是背景色微微变了）。
   用独立伪元素而不是加在 ::after 上 —— ::after 已承担底部渐隐。 */
.hero-visual::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  background: radial-gradient(120% 62% at 18% 8%, rgba(186, 223, 252, .20), transparent 58%);
  opacity: .55;
  pointer-events: none;
  border-radius: inherit;
  transition: opacity .5s var(--ease-out);
}
/* 切换瞬间提亮一档，0.9s 后回落 —— 由 JS 加 .is-switching 类驱动 */
.hero-visual.is-switching::before { opacity: 1; }

/* 顶部：招生进行中胶囊 */
.hv-top {
  position: absolute;
  top: 18px; left: 18px; right: 18px;
  z-index: 2;
  display: flex;
}
.hv-pill {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 14px;
  border-radius: 999px;
  font-size: 12.5px;
  font-weight: 600;
  color: #fff;
  background: rgba(9, 24, 58, .55);
  border: 1px solid rgba(186, 223, 252, .32);
  backdrop-filter: blur(10px) saturate(160%);
  -webkit-backdrop-filter: blur(10px) saturate(160%);
  box-shadow: 0 4px 18px rgba(3, 12, 34, .35);
}

/* ★ v1.69.3：≤980 时布局改为单列（左文案在上、图片卡在下）。
   首屏必然是「文案高 + 图片高」，不可能整个塞进一屏。
   这一档的目标不是「塞进一屏」，而是：
     ① 让**文案区 + 完整图片卡**一屏可见（用户不用滚动就能看到图和按钮）
     ② 图片按内容自然撑高，不再硬算视口高度

   ⚠️ v1.69.2 时这里有两段 `calc(100vh - 84 - ... - 470/400)`，
      为了"减数取多少"反复调了三轮（470 是按手机窄屏文案折行估的，
      在 768~980 单列时明显估大 → 图片永远取下限只剩 29px）。
      v1.69.3 把硬算彻底删掉：单列时没有"左右等高"的需求，
      图片卡按自身内容（图片区 + 折叠态玻璃层）自然高就好，
      多出来的部分由页面滚动承接 —— 手机端本来就习惯滚动。
      少一个需要维护的魔数，就少一类只在某个宽度才复现的 bug。 */
@media (max-width: 980px) {
  /* ★ v1.69.3：单列时取消"撑满一屏"—— 文案在上、图片在下，
     强撑 100vh 会把图片压扁（文案拿走一部分后剩不下多少）。
     改为各按内容自然高，首屏装不下就滚动（手机用户本来就习惯）。 */
  .hero-inner {
    min-height: 0;
    grid-template-rows: auto auto;
    align-items: start;
  }
  .hero-inner > div:first-child { align-self: start; }
  .hero-inner > .hero-card { align-self: start; }
  .hero-visual {
    aspect-ratio: auto;
    height: auto;
    /* 单列时给一个像样的最小高度，让图片有足够存在感 */
    min-height: 340px;
  }
  .hero-visual::after { height: 34%; }
  .hv-top { top: 14px; left: 14px; right: 14px; }
  /* ★ v1.69.8：取消四边内缩后，玻璃层的左右留白改由 padding 提供。
     窄屏用 12px（原内缩 10px + padding 8px ≈ 18px 合计），略收一点
     让 6 行标题在两栏对齐上更整齐。 */
  .hv-majors { margin: 0; padding: 7px 12px 10px; }
  .hv-major-head { font-size: 12.5px; padding: 6px 7px; }
  .hv-major-head small { font-size: 10.5px; }
  .hv-facts > div { padding: 0 8px; }
  .hv-facts dd { font-size: 11.5px; }
}

/* ===== 底部：热门专业玻璃层（★ v1.69.2 改回竖排 + 就地展开）=====
   用户澄清：「是竖排。点击一个课程的时候自动向上展开，不弹出新的页面」。
   —— v1.69.0 我做成了「底部抽屉 + 遮罩浮层」，理解错了，这里全部改掉。

   结构：竖排单列 6 行，每行 = 标题行(button) + 详情区(可折叠)。
   点击标题行 → 详情区从 height:0 撑到 auto，玻璃层随之变高，
   把首屏图往上顶（视觉上正是用户说的「向上展开」），不加遮罩、不弹浮层。

   ⚠️ 玻璃层用 absolute 定位在图片底部，高度变化不会改图片高度 ——
      展开后详情会被图片下边缘裁掉。故改为 position: relative 的普通流，
      由内容自然撑高，图片用 height: 100% 跟随（见 .hero-visual 的说明）。 */
.hv-majors {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  gap: 1px;
  /* ★ v1.69.8 层级精简（用户「这里的层级太多了」）：
     原来是 `margin: 0 12px 12px`—— 玻璃层四边内缩，自己又是一个圆角块，
     于是图片区下沿能看到"卡片圆角 → 图 → 玻璃层圆角"三段弧线。
     现在取消内缩，玻璃层**贴底通栏**：左右下三边与图片区边缘重合。
     这样"卡片 → 玻璃层"之间不再有第二道圆角边界，
     两者读作"一张图上叠了一条底栏"，而不是"卡里嵌了一个卡"。
     ⚠️ 圆角只在**上边两角**保留，下方两角必须贴住外层弧线。
        写死 20px 会在窄屏档（半径变小）穿帮，写 inherit 又拿不到外层值。
        解法：让 .hero-visual 用 clip-path 把整块内容（含玻璃层）按同一个
        圆角轮廓裁一次 —— 见 .hero-visual 的 clip-path 说明。
        即"圆角这层职责从 .hero-card 下移到了 .hero-visual"，
        而不是在 .hv-majors 上再画一遍。 */
  margin: 0;
  padding: 7px 14px 12px;
  border-radius: 16px 16px 0 0;
  /* ★ v1.68.0：原 .52 不透明度 + 深蓝底，在本来就暗的图上等于一块实心补丁，
     backdrop-filter 的磨砂感完全看不出来。降到 .38 并叠一层浅蓝高光，
     让下方的光带与立方体仍能透出来，玻璃才有「玻璃」的样子。

     ★ v1.69.8：底色从 rgba(9,24,58,.62) 提到 .74，并为**下沿**加厚。
     原因：取消内缩后玻璃层直接贴着卡片的圆角下沿，
     底图在最下面那一小段是最亮的地方（留白渐变刚好结束），
     原来的 .62 压不住，最后一行"AI 交付工程师"会浮在亮底上。
     加厚只影响底部约 40%，上沿保持通透，磨砂玻璃的观感不变。 */
  background:
    linear-gradient(180deg, rgba(186, 223, 252, .10), rgba(186, 223, 252, 0) 42%),
    linear-gradient(180deg, rgba(9, 24, 58, .60) 0%, rgba(9, 24, 58, .74) 100%);
  /* ★ v1.69.8：描边只留上沿一道。原来四边都有 1px 描边，
     与外层卡片圆角形成"双层轮廓"；现在左右下三边与图片区重合，
     再描边会在边缘出现一条与卡片弧线不重合的线，反而更乱。 */
  border-top: 1px solid rgba(186, 223, 252, .22);
  backdrop-filter: blur(14px) saturate(170%);
  -webkit-backdrop-filter: blur(14px) saturate(170%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .10);
}

/* ★ v1.69.3：玻璃层上边缘的柔化过渡。
   实测问题（1512×982）：底图是「上亮下暗」的构图时，
   玻璃层 1px 的半透明边框会在图上切出一条**一眼可辨的水平硬边**
   —— 看起来像两个图层没对齐，而不是"玻璃浮在图上"。

   做法：在玻璃层上方叠一条 40px 高的向上渐隐带，
   从 transparent 渐变到玻璃层底色，让"图 → 玻璃"的过渡发生在一段距离内
   而不是一条线上。视觉上玻璃层就像从图里"长出来"的。

   ⚠️ 用伪元素 + pointer-events: none —— 不能挡住 6 个专业标题行的点击。
   ⚠️ 必须 absolute 到玻璃层**外侧上方**（bottom: 100%），
      若放内侧会盖住第一行"AI 视觉创作"的文字。 */
.hv-majors::before {
  content: '';
  position: absolute;
  left: 0; right: 0;
  bottom: 100%;
  height: 40px;
  pointer-events: none;
  background: linear-gradient(180deg,
    rgba(9, 24, 58, 0) 0%,
    rgba(9, 24, 58, .30) 62%,
    rgba(9, 24, 58, .62) 100%);
}

/* ---------- 每个专业：标题行 + 详情区 ----------
   ★ v1.69.4：选中态与悬停态彻底拉开层级（用户「选中展示的时候要和别的区别开，
   一点不突出，阅读力太差了」）。

   上一版的问题（实测复看）：选中项只有 `rgba(143,212,255,.10)` 的极淡蓝底
   和 2px 光带 —— 两者都是"加一点颜色"，而 6 行文字本身颜色一模一样，
   扫视时看到的是"六行一样的字，其中一行的底色略亮一丁点"。
   这不是"不突出"，是**根本没有可被扫视捕捉的形状差异**。

   这一版改用四层可叠加的强信号，让选中项在"余光扫过"时就能被认出：
     ① 实心底 + 描边   —— 从 10% 淡色改为 24% 实色 + 1px 亮边，形成明确色块
     ② 左侧 3px 光带   —— 从 2px 长到 3px，并加上外发光溢出到行外
     ③ 行内文字提亮    —— 未选中项的主体文字压暗到 .78，选中项纯白
     ④ 右侧状态点填充  —— 未选中是空心环，选中变实心 + 光晕（形状差异）
   形状差异（②④）比纯颜色差异（①③）重要得多：颜色在暗玻璃上会被背景吃掉，
   形状不会。这也是为什么"已开课/即将开班"用实心点/空心环区分。

   ⚠️ 未选中项**不设底色**，让选中项的色块从"无"里跳出来，
      而不是从"浅灰"里跳到"浅蓝"——后者差距太小。

   ★ v1.69.8 层级精简：这一层**保留圆角**（它是"行卡片"，
   是全页唯一有资格长成一个小块的元素），但把它从嵌套里"抬"出来 ——
   取消玻璃层的四边内缩后，行两侧的留白由 .hv-majors 的 padding 统一提供，
   不再需要 .hv-major 自己再撑一圈。见 .hv-majors 的说明。 */
.hv-major {
  position: relative;
  border-radius: 9px;
  overflow: hidden;
  /* 底色 / 描边一起过渡，避免只变一样显得突兀 */
  transition: background .26s var(--ease-out), box-shadow .26s var(--ease-out);
}

/* 选中态：强背景 + 亮描边 + 外发光（发光让选中行"浮"起来） */
.hv-major.is-open {
  background:
    linear-gradient(90deg, rgba(143, 212, 255, .26), rgba(143, 212, 255, .12) 62%, rgba(143, 212, 255, .06));
  box-shadow:
    inset 0 0 0 1px rgba(143, 212, 255, .38),
    0 4px 16px -4px rgba(6, 20, 48, .55),
    0 0 0 1px rgba(143, 212, 255, .10);
}

/* ★ v1.69.4 新增：选中项的整行色块（铺在标题行之下、占满整行宽度）。
   为什么不用背景色而用伪元素：背景色在 .hv-major 上，
   详情区展开时色块会跟着长高，视觉重心跑偏；
   用伪元素钉在标题行高度上，色块始终"只包住标题行"。 */
.hv-major.is-open > .hv-major-head { color: #fff; }

/* 悬停态（仅真鼠标设备）：给一层中性提示色，
   **强度刻意低于选中态** —— 鼠标只是"路过"，要让人看得出
   "现在悬停的是这行"但不会误以为"已经选中了"。 */
@media (hover: hover) {
  .hv-major:not(.is-open) > .hv-major-head:hover {
    background: rgba(186, 223, 252, .12);
  }
  .hv-major:not(.is-open) > .hv-major-head:hover .hv-major-name { color: #fff; }
}

/* 标题行：整行可点，用 button 保证键盘可达 */
.hv-major-head {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  /* v1.69.2：行高直接决定玻璃层总高 —— 6 行每行省 4px 就是 24px，
     这些像素最终都变成图片的可视高度。故 padding 收到 5px。 */
  padding: 5px 8px;
  border: none;
  border-radius: 9px;
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 600;
  /* ★ v1.69.4：未选中项整体压暗，让选中项的纯白有对比空间。
     原来是「全部 #fff，选中项也是 #fff」—— 文字层面完全没有层级。
     压到 .78 在深色玻璃上仍然清晰可读，但一眼能看出"哪行被点亮了"。 */
  color: rgba(255, 255, 255, .78);
  text-align: left;
  background: transparent;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  transition: background .26s var(--ease-out), color .26s var(--ease-out);
}
.hv-major-head:focus-visible { outline: 2px solid #8FD4FF; outline-offset: -1px; }

/* ★ v1.69.4：专业名单独一个元素才能单独提亮（上面在 :hover 里也用到）。
   选中项回到纯白 + 轻微发光，是"这一行被点亮"最强的文字信号。 */
.hv-major-name {
  white-space: nowrap;
  transition: color .26s var(--ease-out), text-shadow .26s var(--ease-out);
}
.hv-major.is-open .hv-major-name {
  color: #fff;
  text-shadow: 0 0 12px rgba(143, 212, 255, .55);
}
.hv-major-head small {
  margin-left: auto;
  font-size: 11px;
  font-weight: 500;
  /* ★ v1.68.0：原为 #7CE2A8（偏黄绿），在整片品牌蓝橙画面里跳色、
     且比专业名本身更抢眼。改用「淡青蓝」——与主蓝同色系、只提亮不提饱和。 */
  color: #8FD4FF;
  white-space: nowrap;
  transition: color .26s var(--ease-out);
}
.hv-major-head small.soon { color: rgba(186, 223, 252, .72); }
/* ★ v1.69.4：选中行的状态文字提亮 —— 与左侧光带、右侧实心点同属"选中行"信号。
   注意是**提亮而非变色**：状态语义（已开课/即将开班）必须保持可区分，
   选了"即将开班"的行其标签仍是弱色，只是比未选中时更清楚。 */
.hv-major.is-open .hv-major-head small { color: #A9E0FF; }

/* 展开箭头：默认朝下，展开时旋转 180° 朝上。
   用 transform 而不是换图标，动画才连贯。 */
.hv-caret {
  flex: none;
  margin-left: 2px;
  color: rgba(186, 223, 252, .62);
  transition: transform .3s var(--ease-out), color .24s var(--ease-out);
}
.hv-major.is-open .hv-caret {
  transform: rotate(180deg);
  color: #A9E0FF;
  filter: drop-shadow(0 0 6px rgba(143, 212, 255, .8));
}

.hv-major i {
  width: 6px; height: 6px;
  border-radius: 50%;
  flex: none;
  transition: background .26s var(--ease-out), border-color .26s var(--ease-out),
              box-shadow .26s var(--ease-out), transform .26s var(--ease-out);
}
/* 状态点与文字同色系，避免两个颜色打架 */
.hv-major i.ok {
  background: #8FD4FF;
  box-shadow: 0 0 0 3px rgba(143, 212, 255, .16), 0 0 8px rgba(143, 212, 255, .55);
}
/* 未开班：圆点是空心环，和「已开课」的实心点形成一眼可辨的区别，
   比单纯改文字颜色更直观（颜色在玻璃底上本来就不容易分辨）。 */
.hv-major i.soon {
  background: transparent;
  border: 1.5px solid rgba(143, 212, 255, .62);
  box-shadow: none;
}

/* ★ v1.69.4：**选中的那一行，两个状态点都统一变成"实心 + 光晕 + 放大"。**
   理由：状态点原本承载的是「是否开班」的信息，与「是否选中」是两件事，
   两者抢同一个视觉通道 → 选中行如果刚好是"即将开班"，反而是个空心环，
   看上去比未选中的"已开课"更弱，选中感被抵消掉了。
   现在把"选中"提升为更上层的视觉状态：形状（空→实）、尺寸（放大 22%）、
   光晕（.55 → .95）三重加强，使选中感稳定压过状态差异。 */
.hv-major.is-open i {
  background: #A9E0FF;
  border-color: #A9E0FF;
  transform: scale(1.22);
  box-shadow: 0 0 0 4px rgba(143, 212, 255, .22), 0 0 12px rgba(143, 212, 255, .95);
}

/* ---------- 就地展开的详情区 ----------
   ⚠️ 折叠动画为什么用 max-height 而不是 height:auto：
      height:auto 无法参与 transition（浏览器不知道终值）。
      用 max-height 给一个够大的上限即可。
   ★ v1.69.3：上限 170 → 260px。
      内容从"3 行精简"扩到"标语+介绍+三格数据+标签+课程/就业两行"，
      实测展开态内容约 232px，170px 会把最后一行"就业方向"裁掉。
      260px = 232 + 余量，同时不至于大到让动画前段空跑。 */
.hv-major-body {
  max-height: 0;
  overflow: hidden;
  opacity: 0;
  transition: max-height .38s var(--ease-out), opacity .28s var(--ease-out),
              padding .38s var(--ease-out);
  padding: 0 6px;
}
.hv-major.is-open .hv-major-body {
  max-height: 260px;
  opacity: 1;
  padding: 1px 6px 8px;
}
.hv-slogan {
  margin: 0 0 5px;
  font-size: 11px;
  line-height: 1.5;
  font-weight: 600;
  color: #CFE6FF;
}
/* ★ v1.69.3 新增：完整一句话介绍（用户「课程相关内容显示更丰富些」）。
   与 slogan 的分工：slogan 是"一句话卖点"（加粗、亮），
   desc 是"这是什么"的完整说明（常规字重、略暗）。
   字号刻意压到 10.5px —— 详情区整体高度直接决定首屏能不能装下，
   每多 10px 就从图片区拿走 10px（见 .hv-spacer 的说明）。
   ★ v1.69.4：字号 10.5 → 11px，颜色 .80 → .88。
   用户「阅读力太差了」是双重问题：既指选中项不突出（结构层），
   也指正文在深玻璃上发灰、读起来费劲（可读性层）。
   11px/1.62 在 1366 宽的左栏（约 420px）上每行约 38 个汉字，
   仍是最舒适的行长区间；只多用 ~4px 高度，换明显更轻的阅读负担。 */
.hv-desc {
  margin: 0 0 5px;
  font-size: 11px;
  line-height: 1.62;
  color: rgba(208, 226, 248, .88);
}
/* 周期 / 课时 / 学费 三格横排。
   ★ v1.69.3：内边距与行距收紧（padding 4→3、gap 5→4）。
     这三格是"一眼扫过"的信息，不需要呼吸感，省下的像素全给图片。

   ★ v1.69.8 层级精简（用户「这里的层级太多了」）：
   原来三格各是一个独立的**圆角小方块**（radius 6px + 底色 + 描边），
   与"玻璃层(13px) → 选中行(9px)"再叠一层，在 390px 窄屏上
   光这一行就是三个并排的小圆角卡 —— 四层圆角里最碎的一层。

   改为**去掉格子容器，用竖线分隔**：分隔线是纯几何，不产生新的轮廓。
   代价是三格失去"独立卡片"的实体感，但这里本来就是同一组数据
   （周期/课时/学费），读作"三个并列字段"比"三张小卡"更准确。
   ⚠️ 分隔线用 border-left on :nth-child(n+2) 而不是 :not(:first-child)，
      前者在 grid 里更明确，且不受子元素顺序影响。 */
.hv-facts {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0;
  margin: 0 0 6px;
  padding: 0;
}
.hv-facts > div {
  padding: 0 10px;
  border-left: 1px solid rgba(186, 223, 252, .18);
}
.hv-facts > div:first-child { padding-left: 0; border-left: none; }
.hv-facts dt {
  font-size: 9px;
  font-weight: 500;
  color: rgba(186, 223, 252, .70);
}
.hv-facts dd {
  margin: 1px 0 0;
  font-size: 12px;
  font-weight: 700;
  color: #fff;
  letter-spacing: -.01em;
  white-space: nowrap;
}
/* 学费是本块最关键的决策信息，单独提色。
   ★ v1.69.8：原来靠"橙底 + 橙描边"提色，现在格子没有底色了，
   改用**文字色 + 一道橙色分隔线**承担 —— 信息层级不减，
   但不再多画一个橙色方块。 */
.hv-facts > div:last-child {
  border-left-color: rgba(255, 121, 27, .45);
}
.hv-facts > div:last-child dt { color: rgba(255, 187, 138, .90); }
.hv-facts > div:last-child dd { color: #FFC08A; }

.hv-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.hv-tags li {
  padding: 1px 7px;
  border-radius: 999px;
  font-size: 10px;
  font-weight: 500;
  color: rgba(214, 232, 255, .92);
  background: rgba(143, 212, 255, .12);
  border: 1px solid rgba(143, 212, 255, .22);
  white-space: nowrap;
}

/* ---------- ★ v1.69.3 新增：核心课程 / 就业方向 ----------
   用 dl 而不是 ul：这是"术语—说明"对，dl 语义正确，
   读屏会念成"核心课程：……"，而不是孤立的 li 列表。

   ★ 为什么改成两列并排（而不是竖着两行）：
     实测「核心课程」+「就业方向」两行竖排共 75px。首屏的可用高度
     是被视口定死的（1366×768 上只有 476px），而这 75px 会直接从
     图片可视区里扣走 —— 竖排时图片区只剩 69px，几乎看不见图。
     改两列后同样信息只占 ~44px，省下 31px 全给图片。
     两列也是这一块更合适的排法：两条本来就是并列关系，不是递进。 */
.hv-more {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 3px 10px;
  margin: 6px 0 0;
  padding: 5px 0 0;
  border-top: 1px dashed rgba(186, 223, 252, .16);
}
.hv-more > div { min-width: 0; }
.hv-more dt {
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: .04em;
  color: rgba(143, 212, 255, .92);
  margin-bottom: 1px;
}
.hv-more dd {
  margin: 0;
  font-size: 10px;
  line-height: 1.52;
  color: rgba(208, 226, 248, .82);
}

/* ---------- ★ v1.69.4 新增：玻璃层与底图之间的清晰分隔 ----------
   用户「阅读力太差了」的结构性一半：玻璃层 6 行文字压在一张
   明暗不均的实拍图上，文字与背景的对比度随图片内容浮动
   （图亮的地方那行字就"陷"进去）。加一层从下往上的暗化渐变，
   把玻璃层所在的下半区整体压暗，让 6 行文字始终落在深色底上。
   40px 起渐隐，不给"半屏黑罩"的压迫感，只在文字区生效。 */
.hv-majors::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 100%;
  pointer-events: none;
  z-index: -1;
  border-radius: inherit;
  background: linear-gradient(180deg,
    rgba(6, 16, 40, .18) 0%,
    rgba(6, 16, 40, .50) 100%);
}

/* ---------- ★ v1.69.3 新增：玻璃层里的地址行 ----------
   替代原白底 .hero-card-foot。弱化处理（不给背景块），
   它在这里是"顺带一提"的信息，不该和 6 个专业抢注意力。 */
.hv-addr {
  display: flex;
  align-items: center;
  gap: 5px;
  margin-top: 2px;
  padding: 6px 8px 2px;
  border-top: 1px solid rgba(186, 223, 252, .14);
  font-size: 10.5px;
  color: rgba(200, 220, 246, .76);
}
.hv-addr svg { flex: none; color: #8FD4FF; }
.hv-addr span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ==========================================================================
   ★ v1.69.3 展开动效（用户「动效更强」）
   —— 详情区里的每一层内容依次入场，而不是整块淡入。
   为什么用"依次"而不是"整块"：整块淡入只是一个静态块从透明变不透明，
   眼睛几乎捕捉不到"内容变多了"这件事；分层入场有明确的先后顺序，
   视线会被自然引导着从上往下读完，信息吸收率明显更高。

   实现：给详情区的直接子元素按顺序给 transition-delay（0/60/120/180ms）。
   折叠时用同一组 delay 的反向（从上往下消失），刻意不做"逆序"——
   逆序会让收起过程看起来拖沓。
   ========================================================================== */
.hv-major-body > * {
  opacity: 0;
  transform: translateY(6px);
  transition: opacity .3s var(--ease-out), transform .34s var(--ease-out);
}
.hv-major.is-open .hv-major-body > * {
  opacity: 1;
  transform: translateY(0);
}
.hv-major.is-open .hv-major-body > *:nth-child(1) { transition-delay: .06s; }
.hv-major.is-open .hv-major-body > *:nth-child(2) { transition-delay: .10s; }
.hv-major.is-open .hv-major-body > *:nth-child(3) { transition-delay: .14s; }
.hv-major.is-open .hv-major-body > *:nth-child(4) { transition-delay: .18s; }
.hv-major.is-open .hv-major-body > *:nth-child(5) { transition-delay: .22s; }

/* 展开时，标题行左侧亮起一道竖向光带 —— 明确指示"展开的是哪一条"。
   用 ::before 绝对定位，不占布局空间。

   ★ v1.69.4：2px → 3px，并加外发光。
   2px 在高分屏上只有 4 物理像素，且深色玻璃会把它的亮度吃掉，
   实测扫视时基本注意不到。3px + 发光后它成了这一行**最显眼的几何特征**，
   与右侧状态点形成"首尾两点高亮"的框定效果，视线自然落在这行上。 */
.hv-major-head { position: relative; }
.hv-major-head::before {
  content: '';
  position: absolute;
  left: 0; top: 50%;
  width: 3px;
  height: 0;
  border-radius: 2px;
  background: linear-gradient(180deg, #A9E0FF, #4E9BFF);
  box-shadow: 0 0 12px rgba(143, 212, 255, .95);
  transform: translateY(-50%);
  opacity: 0;
  transition: height .32s var(--ease-out), opacity .24s var(--ease-out);
}
.hv-major.is-open .hv-major-head::before { height: 68%; opacity: 1; }

.hero-panel {
  position: relative;
  padding: 24px 24px 22px;
  background:
    radial-gradient(560px 320px at 88% -10%, rgba(255, 121, 27, .28), transparent 62%),
    radial-gradient(620px 420px at -12% 108%, rgba(34, 108, 225, .5), transparent 60%),
    linear-gradient(158deg, #0a1c46 0%, var(--brand-deep) 56%, #0a1c46 100%);
  color: #fff;
  overflow: hidden;
}
.hp-badge {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 13px;
  background: rgba(255, 255, 255, .1);
  border: 1px solid rgba(255, 255, 255, .22);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border-radius: 999px;
  font-size: 12.5px;
  font-weight: 600;
  color: #fff;
}
.hp-group {
  margin-top: 13px;
  padding: 12px 16px;
  background: rgba(255, 255, 255, .06);
  border: 1px solid rgba(255, 255, 255, .14);
  border-radius: 14px;
}
.hp-group-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 4px;
}
.hp-tag {
  font-size: 14.5px;
  font-weight: 700;
  letter-spacing: .5px;
}
.hp-open {
  font-size: 11.5px;
  font-weight: 600;
  color: #7CE2A8;
  background: rgba(124, 226, 168, .12);
  border: 1px solid rgba(124, 226, 168, .3);
  border-radius: 999px;
  padding: 3px 10px;
}
.hp-major {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 5px 0;
  font-size: 13.5px;
  color: rgba(255, 255, 255, .92);
}
.hp-major + .hp-major { border-top: 1px dashed rgba(255, 255, 255, .1); }
.hp-major small {
  margin-left: auto;
  font-size: 12px;
  color: rgba(255, 255, 255, .55);
}
.hp-major i, .hp-legend i {
  width: 8px; height: 8px;
  border-radius: 50%;
  flex: 0 0 auto;
}
.hp-major i.ok, .hp-legend i.ok { background: #7CE2A8; }
.hp-major i.soon, .hp-legend i.soon { background: var(--accent); }
.hp-legend {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 11px;
  font-size: 12.5px;
  color: rgba(255, 255, 255, .6);
}
.hp-legend i.soon { margin-left: 14px; }

/* v1.69.3：基础 .metric-num / .metric-label 保留 ——
   .result-card .metric-num（第 1788 行附近）与 .metric-label 仍在首页
   「就业数据」板块使用，删掉会让那两块回落到默认字号。 */
.metric-num span { font-size: 14px; font-weight: 600; color: var(--ink-3); margin-left: 2px; }
.metric-label { font-size: 12.5px; color: var(--ink-3); margin-top: 5px; }

/* ★ v1.69.3：`.hero-card .hero-card-foot` 的白底样式已删除 ——
   用户要求「底部白色为达到一屏」，那条白底地址条是首屏填不满的原因之一，
   已整体移除，地址移入玻璃层（见 .hv-addr）。
   这里保留 `.hero-card-foot` 的通用样式（无白底），以防其他页面复用。 */
.hero-card-foot {
  margin-top: 18px;
  padding-top: 15px;
  border-top: 1px solid var(--line-2);
  font-size: 12.5px;
  color: var(--ink-4);
  line-height: 1.6;
}

/* ================= 通用区块 ================= */
.section { padding: 100px 0; }
/* v1.46.0：浅色板块从纯色升级为「白→浅蓝→白」柔和渐变，避免整页死白、背景单一 */
/* v1.62.0：叠加顶部细光带 + 极淡网格，让每个板块都有"高级底纹"而非平铺白 */
.section-soft {
  position: relative;
  background: linear-gradient(180deg, #ffffff 0%, var(--bg-soft) 22%, var(--bg-soft) 78%, #ffffff 100%);
  overflow: hidden;
}
.section-soft::after {
  content: '';
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(34,108,225,.035) 1px, transparent 1px),
    linear-gradient(90deg, rgba(34,108,225,.035) 1px, transparent 1px);
  background-size: 44px 44px;
  mask-image: radial-gradient(ellipse 70% 60% at 50% 50%, #000 30%, transparent 100%);
  -webkit-mask-image: radial-gradient(ellipse 70% 60% at 50% 50%, #000 30%, transparent 100%);
  pointer-events: none;
}
.section-soft .wrap { position: relative; z-index: 2; }

/* 淡橙 tint 板块：用于需要强调的板块（就业挑战），与浅蓝 soft 形成冷暖节奏 */
.section-tint {
  position: relative;
  background: linear-gradient(180deg, #ffffff 0%, #fff8f1 26%, #fff4e8 74%, #ffffff 100%);
}
.section-tint::before {
  content: '';
  position: absolute;
  width: 420px; height: 420px;
  border-radius: 50%;
  background: rgba(255, 121, 27, .10);
  filter: blur(90px);
  top: -80px; right: -100px;
  pointer-events: none;
}
.section-tint .wrap { position: relative; z-index: 2; }
/* v1.62.0：深色板块升级为「舞台蓝」——加聚光与细网格，与首屏同一套语言 */
.section-dark {
  position: relative;
  color: #fff;
  background:
    radial-gradient(1000px 560px at 84% -10%, rgba(34,108,225,.34), transparent 62%),
    radial-gradient(760px 440px at 4% 108%, rgba(255,121,27,.13), transparent 62%),
    linear-gradient(166deg, #0a1430 0%, var(--ink-deep) 40%, #071a40 100%);
  overflow: hidden;
}
.section-dark::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(186,223,252,.07) 1px, transparent 1px),
    linear-gradient(90deg, rgba(186,223,252,.07) 1px, transparent 1px);
  background-size: 48px 48px;
  mask-image: radial-gradient(ellipse 74% 60% at 50% 44%, #000 30%, transparent 100%);
  -webkit-mask-image: radial-gradient(ellipse 74% 60% at 50% 44%, #000 30%, transparent 100%);
  pointer-events: none;
}
.section-dark .wrap { position: relative; z-index: 2; }

/* ================= 章节标题：加「编号 + 短横线」装饰，提升设计感 ================= */
.section-head { margin-bottom: 50px; max-width: 680px; }
.section-head.center { margin-left: auto; margin-right: auto; text-align: center; }

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 1.8px;
  text-transform: uppercase;
  color: var(--brand);
  margin-bottom: 14px;
}
.eyebrow::before {
  content: '';
  width: 22px; height: 2px;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--brand), var(--accent));
}
.section-head.center .eyebrow::after {
  content: '';
  width: 22px; height: 2px;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--accent), var(--brand));
}
.section-dark .eyebrow { color: var(--accent); }
.section-dark .eyebrow::before,
.section-dark .eyebrow::after { background: linear-gradient(90deg, var(--accent), #ffb066); }

.section h2 {
  font-size: clamp(24px, 3vw, 34px);
  line-height: 1.28;
  letter-spacing: -.7px;
  font-weight: 800;
  margin-bottom: 14px;
}
.section-head p { color: var(--ink-3); font-size: 16px; }
.section-dark .section-head p { color: rgba(255,255,255,.66); }

/* ================= 课程体系：两大方向 · 六大专业 ================= */
/* 一个「方向」包住 3 张专业卡片，方向之间留出更大的间距，
   让「两大方向」的层级一眼可见（v1.45.0）。 */
.track + .track { margin-top: 34px; }

.track-head {
  display: flex;
  align-items: baseline;
  gap: 14px;
  flex-wrap: wrap;
  margin-bottom: 18px;
  padding-bottom: 12px;
  border-bottom: 2px solid var(--brand-light);
}
.track-title {
  font-size: 21px;
  font-weight: 800;
  color: var(--brand-deep);
  letter-spacing: .5px;
  position: relative;
  padding-left: 14px;
}
.track-title::before {
  content: '';
  position: absolute;
  left: 0; top: 50%;
  transform: translateY(-50%);
  width: 5px; height: 19px;
  border-radius: 3px;
  background: var(--brand);
}
.track-slogan { font-size: 14.5px; color: var(--ink-3); }

/* 专业卡片副标题（如「AI 生成视觉内容」） */
.major-sub {
  font-size: 13px;
  color: var(--brand);
  font-weight: 600;
  margin: -6px 0 10px;
  letter-spacing: .3px;
}

/* ================= 实训方向卡片 ================= */
.major-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 22px;
}

.major-card {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 30px 26px;
  transition: transform .34s var(--ease-out), box-shadow .34s var(--ease-out), border-color .34s;
  position: relative;
  overflow: hidden;
  /* v1.62.0：卡片默认带一层「浮起感」，不再是一张平贴的白纸 */
  box-shadow: 0 1px 2px rgba(6,32,82,.04), 0 10px 30px -12px rgba(6,32,82,.10);
}

/* 未开课专业：配图灰度 + 即将开班角标（v1.50.0） */
.major-soon .major-media img { filter: grayscale(1); opacity: .92; }
.major-soon-badge {
  position: absolute;
  top: 12px; right: 12px;
  z-index: 2;
  background: rgba(6, 32, 82, .85);
  color: #fff;
  font-size: 12px;
  font-weight: 600;
  padding: 5px 13px;
  border-radius: 999px;
  backdrop-filter: blur(4px);
  letter-spacing: 1px;
}
.major-soon .major-tags { opacity: .75; }

/* 专业卡片配图（v1.46.0）：顶部全宽出血，hover 轻微放大 */
.major-media {
  margin: -30px -26px 20px;
  height: 185px;
  position: relative;
  overflow: hidden;
}
.major-media img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  transition: transform .4s;
}
.major-card:hover .major-media img { transform: scale(1.05); }
.major-media::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, transparent 58%, rgba(6, 32, 82, .16));
}
.major-card::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 3px;
  background: linear-gradient(90deg, var(--brand), var(--accent));
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .42s var(--ease-out);
  z-index: 3;
}
/* 悬停时右上角渗出一团品牌色光晕 */
.major-card::after {
  content: '';
  position: absolute;
  width: 260px; height: 260px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(34,108,225,.13), transparent 68%);
  top: -140px; right: -110px;
  opacity: 0;
  transition: opacity .42s var(--ease-out);
  pointer-events: none;
}
.major-card:hover {
  transform: translateY(-7px);
  box-shadow: 0 26px 60px -16px rgba(6, 32, 82, .28), 0 0 0 1px rgba(34,108,225,.10);
  border-color: transparent;
}
.major-card:hover::before { transform: scaleX(1); }
.major-card:hover::after { opacity: 1; }

.major-icon {
  width: 52px; height: 52px;
  border-radius: 14px;
  background: var(--brand-light);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 24px;
  margin-bottom: 18px;
}
.major-card h3 {
  font-size: 19px;
  font-weight: 700;
  margin-bottom: 9px;
  letter-spacing: -.3px;
}
.major-card p { color: var(--ink-3); font-size: 14.5px; }

/* 方向卡片里的周期/收费条 —— 数据来自招生简章，用「标签:值」结构保证可扫读 */
.major-spec {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 16px;
  padding: 13px 15px;
  background: var(--bg-soft);
  border-radius: 10px;
  border: 1px solid var(--line-2);
}
.major-spec span {
  font-size: 13px;
  color: var(--ink-3);
  display: flex;
  align-items: baseline;
  gap: 6px;
  flex-wrap: wrap;
}
.major-spec b {
  color: var(--ink);
  font-weight: 700;
  font-size: 13.5px;
}

/* 「查看完整招生简章」引导条 */
.majors-more {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  flex-wrap: wrap;
  margin-top: 38px;
}
.majors-more span { font-size: 13.5px; color: var(--ink-4); }

.major-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  margin-top: 18px;
  padding-top: 17px;
  border-top: 1px solid var(--line-2);
}
.tag {
  font-size: 12px;
  padding: 4px 10px;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: 6px;
  color: var(--ink-3);
  font-weight: 500;
}

/* ================= 优势（深色区）================= */
.adv-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 30px;
}
.adv-item { padding-top: 22px; border-top: 1px solid rgba(255,255,255,.14); }
.adv-num {
  font-size: 12.5px;
  font-weight: 700;
  color: var(--accent);
  letter-spacing: 1.4px;
  margin-bottom: 12px;
}
.adv-item h3 { font-size: 17.5px; font-weight: 700; margin-bottom: 9px; }
.adv-item p { color: rgba(255,255,255,.66); font-size: 14.5px; }

/* ================= 人才成长路径 6 步（v1.45.0）================= */
.path-wrap { margin-top: 40px; }
.path-title {
  font-size: 16px;
  font-weight: 700;
  color: var(--brand-deep);
  margin-bottom: 18px;
  padding-left: 14px;
  position: relative;
}
.path-title::before {
  content: '';
  position: absolute;
  left: 0; top: 50%; transform: translateY(-50%);
  width: 5px; height: 17px; border-radius: 3px; background: var(--brand);
}
.path-row {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-wrap: wrap;
}
.path-step {
  flex: 1 1 120px;
  text-align: center;
  padding: 16px 8px;
  background: var(--bg-soft);
  border: 1px solid var(--line-2);
  border-radius: var(--radius);
}
.path-no {
  width: 34px; height: 34px;
  margin: 0 auto 9px;
  border-radius: 50%;
  background: var(--brand);
  color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-size: 13.5px;
  font-weight: 800;
}
.path-step h4 { font-size: 14.5px; font-weight: 700; color: var(--ink); margin-bottom: 3px; }
.path-step p { font-size: 12.5px; color: var(--ink-3); }
.path-sep { color: var(--brand-light); font-size: 18px; font-weight: 700; flex: 0 0 auto; }
.path-note { text-align: center; font-size: 13px; color: var(--ink-3); margin-top: 16px; }

/* ================= 学习保障 / 就业服务网格（v1.45.0）================= */
.svc-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}
.svc-grid-8 { grid-template-columns: repeat(4, 1fr); }
.svc-item {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 22px 20px;
  transition: transform .3s var(--ease-out), box-shadow .3s var(--ease-out), border-color .3s;
  box-shadow: 0 1px 2px rgba(6,32,82,.04), 0 8px 24px -12px rgba(6,32,82,.10);
  position: relative;
  overflow: hidden;
}
.svc-item::before {
  content: '';
  position: absolute; inset: 0;
  background: radial-gradient(300px 180px at 100% 0%, rgba(34,108,225,.09), transparent 70%);
  opacity: 0;
  transition: opacity .3s var(--ease-out);
  pointer-events: none;
}
.svc-item:hover {
  transform: translateY(-5px);
  box-shadow: 0 22px 50px -16px rgba(6, 32, 82, .26);
  border-color: transparent;
}
.svc-item:hover::before { opacity: 1; }
.svc-ic {
  width: 40px; height: 40px;
  border-radius: var(--radius);
  background: var(--brand-tint);
  color: var(--brand);
  display: flex; align-items: center; justify-content: center;
  margin-bottom: 12px;
}
.svc-item h3 { font-size: 15.5px; font-weight: 700; margin-bottom: 5px; }
.svc-item p { font-size: 12.5px; color: var(--ink-3); line-height: 1.6; }

/* 四大核心能力（展板 A9，v1.52.0） */
.ability-wrap { margin-top: 34px; }
.mech-item.ability { padding: 20px 14px; background: #fff; }
.ability-ic {
  width: 44px; height: 44px;
  margin: 0 auto 10px;
  border-radius: 50%;
  background: var(--brand-tint);
  color: var(--brand);
  display: flex; align-items: center; justify-content: center;
}

/* 内容卡图标（v1.57.0）：给纯文字卡补视觉元素 */
.adv-ic {
  width: 46px; height: 46px;
  border-radius: 12px;
  background: var(--brand-tint);
  color: var(--brand);
  display: flex; align-items: center; justify-content: center;
  margin-bottom: 14px;
}
.adv-ic-dark {
  background: rgba(255, 255, 255, .1);
  color: var(--brand-light);
  border: 1px solid rgba(255, 255, 255, .16);
}

/* ================= 长期成长（v1.45.0）================= */
.upgrade-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  max-width: 900px;
  margin: 0 auto;
}
.up-item {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 26px 22px;
  text-align: center;
  transition: transform .3s var(--ease-out), box-shadow .3s var(--ease-out), border-color .3s;
  box-shadow: 0 1px 2px rgba(6,32,82,.04), 0 8px 24px -12px rgba(6,32,82,.10);
}
.up-item:hover {
  transform: translateY(-5px);
  box-shadow: 0 22px 50px -16px rgba(6,32,82,.26);
  border-color: transparent;
}
.up-ic {
  width: 52px; height: 52px;
  margin: 0 auto 12px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--brand) 0%, var(--brand-deep) 100%);
  color: #fff;
  display: flex; align-items: center; justify-content: center;
}
.up-item h3 { font-size: 16.5px; font-weight: 700; margin-bottom: 6px; }
.up-item p { font-size: 13px; color: var(--ink-3); }

.mech-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
}
.mech-item {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 16px;
  text-align: center;
}
.mech-item h4 {
  font-size: 14.5px;
  font-weight: 700;
  color: var(--brand-deep);
  margin-bottom: 4px;
}
.mech-item p { font-size: 12.5px; color: var(--ink-3); }


/* 合并板块内两个小节的间距（v1.51.0） */
.merge-gap { height: 40px; }

/* ================= 合作伙伴（v1.45.0 → v1.46.0 深底 LOGO 墙）================= */
/* 合作伙伴板块改为深色背景，企业以「LOGO 标识卡片」呈现，增强视觉冲击与品牌质感 */
.partner-sec { position: relative; overflow: hidden; }
.partner-sec::before,
.partner-sec::after {
  content: '';
  position: absolute;
  border-radius: 50%;
  filter: blur(90px);
  opacity: .5;
  pointer-events: none;
}
.partner-sec::before { width: 520px; height: 520px; background: var(--brand); top: -160px; right: -120px; opacity: .12; }
.partner-sec::after { width: 460px; height: 460px; background: var(--accent); bottom: -180px; left: -120px; opacity: .07; }
.partner-sec .wrap { position: relative; z-index: 2; }

.partner-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 18px;
  max-width: 760px;
  margin: 0 auto 34px;
}
.ps-item {
  text-align: center;
  padding: 22px 14px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: 0 1px 2px rgba(6,32,82,.04), 0 8px 24px -12px rgba(6,32,82,.10);
}
.ps-item b {
  display: block;
  font-size: 34px;
  font-weight: 800;
  color: var(--brand);
  line-height: 1.1;
  font-family: 'DIN Alternate', Impact, system-ui, sans-serif;
}
.ps-item b span { font-size: 19px; color: var(--accent); }
.ps-item > span { display: block; margin-top: 7px; font-size: 13.5px; color: var(--ink-3); }

.partner-wall {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 16px;
}
.pw-group {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 18px;
  box-shadow: var(--shadow-sm);
}
.pw-cat {
  font-size: 13px;
  font-weight: 700;
  color: var(--brand-deep);
  margin-bottom: 14px;
  padding-bottom: 10px;
  border-bottom: 1px dashed var(--line);
  letter-spacing: .5px;
}
.pw-logos {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
/* v1.47.1：去掉自制的「字母字标」（观感不对），改为简洁的企业名称卡片。
   待拿到企业真实 LOGO 图后再逐家替换。 */
.pw-logo {
  background: #fff;
  border: 1px solid var(--line-2);
  border-radius: 10px;
  padding: 10px 16px 10px 12px;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: flex-start;
  gap: 9px;
  transition: transform .2s;
  white-space: nowrap;
}
.pw-logo:hover { transform: translateY(-3px); box-shadow: var(--shadow); border-color: var(--brand-light); }
.pw-name { font-size: 13.5px; font-weight: 700; color: var(--ink); line-height: 1.3; }
.pw-logo-img {
  width: 34px; height: 34px;
  object-fit: contain;
  flex: 0 0 auto;
}
.pw-en {
  font-size: 9.5px;
  color: var(--ink-4);
  letter-spacing: .8px;
  text-transform: uppercase;
  font-family: 'DIN Alternate', Impact, system-ui, sans-serif;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.partner-services {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 12px;
  margin-top: 30px;
}
.partner-services span {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--brand-deep);
  border: 1px solid var(--brand-light);
  background: var(--brand-tint);
  border-radius: 999px;
  padding: 8px 18px;
}
.partner-note { text-align: center; color: var(--ink-3); font-size: 13.5px; margin-top: 16px; }

/* ================= 基地背书（v1.49.0 真实资质 + 牌匾配图）================= */
.cred-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 18px;
}
.cred-card2 {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  transition: transform .32s var(--ease-out), box-shadow .32s var(--ease-out);
  box-shadow: 0 1px 2px rgba(6,32,82,.04), 0 10px 28px -14px rgba(6,32,82,.12);
}
.cred-card2:hover { transform: translateY(-6px); box-shadow: 0 26px 58px -18px rgba(6,32,82,.30); }
.cred-media { height: 175px; overflow: hidden; }
.cred-media img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  transition: transform .4s;
}
.cred-card2:hover .cred-media img { transform: scale(1.06); }
.cred-body { padding: 18px 18px 20px; text-align: center; }
.cred-title { font-size: 13px; color: var(--ink-2); line-height: 1.55; }
.cred-org {
  margin-top: 6px;
  font-size: 16.5px;
  font-weight: 800;
  color: var(--brand-deep);
  line-height: 1.4;
}

/* ================= 就业成果 ================= */
.result-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 18px;
}
.result-card {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 26px 22px;
  text-align: center;
}
.result-card .metric-num { font-size: 32px; }
.result-card .metric-label { font-size: 13px; margin-top: 7px; }

/* 企业 logo 墙 */
.logo-wall {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 14px;
  margin-top: 34px;
}
.logo-item {
  height: 74px;
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ink-4);
  font-size: 13.5px;
  background: #fff;
  transition: border-color .2s, color .2s;
}
.logo-item:hover { border-color: var(--brand); color: var(--brand); }

/* ================= 招生流程 ================= */
.steps { display: grid; grid-template-columns: repeat(auto-fit, minmax(215px, 1fr)); gap: 22px; }
/* v1.62.0：流程步骤改为「有卡片感的浮起块」，并加连接线暗示顺序 */
.step {
  position: relative;
  padding: 22px 20px 22px 62px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: 0 1px 2px rgba(6,32,82,.04), 0 8px 24px -14px rgba(6,32,82,.10);
  transition: transform .3s var(--ease-out), box-shadow .3s var(--ease-out), border-color .3s;
}
.step:hover {
  transform: translateY(-5px);
  box-shadow: 0 22px 50px -18px rgba(6,32,82,.26);
  border-color: transparent;
}
/* 步骤之间的箭头，暗示流程方向 */
.step + .step::before {
  content: '';
  position: absolute;
  left: -14px; top: 50%;
  width: 8px; height: 8px;
  border-top: 2px solid var(--brand-light);
  border-right: 2px solid var(--brand-light);
  transform: translateY(-50%) rotate(45deg);
}
.step-no {
  position: absolute;
  left: 20px; top: 22px;
  width: 30px; height: 30px;
  border-radius: 50%;
  background: linear-gradient(135deg, #2f7ff0, var(--brand-dark));
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 13.5px;
  font-weight: 700;
  box-shadow: 0 4px 14px rgba(34,108,225,.38), inset 0 1px 0 rgba(255,255,255,.28);
}
.step h3 { font-size: 16px; font-weight: 700; margin-bottom: 6px; }
.step p { color: var(--ink-3); font-size: 14px; }

/* ================= 报名 / 联系 ================= */
.cta-band {
  /* v1.62.0：与首屏同一套「舞台深蓝 + 聚光 + 网格」语言，收尾呼应 */
  background:
    radial-gradient(720px 420px at 88% -18%, rgba(34,108,225,.50), transparent 62%),
    radial-gradient(560px 340px at 6% 118%, rgba(255,121,27,.20), transparent 62%),
    linear-gradient(158deg, #0a1430 0%, var(--ink-deep) 46%, #08193f 100%);
  border-radius: var(--radius-lg);
  padding: 56px 46px;
  color: #fff;
  display: grid;
  grid-template-columns: 1.4fr .6fr;
  gap: 36px;
  align-items: center;
  position: relative;
  overflow: hidden;
  box-shadow: 0 30px 70px -26px rgba(6,20,52,.55);
}
.cta-band::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(186,223,252,.07) 1px, transparent 1px),
    linear-gradient(90deg, rgba(186,223,252,.07) 1px, transparent 1px);
  background-size: 46px 46px;
  mask-image: radial-gradient(ellipse 72% 76% at 30% 50%, #000 24%, transparent 100%);
  -webkit-mask-image: radial-gradient(ellipse 72% 76% at 30% 50%, #000 24%, transparent 100%);
  pointer-events: none;
}
.cta-band::after {
  content: '';
  position: absolute;
  right: -90px; top: -90px;
  width: 320px; height: 320px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(34,108,225,.55), transparent 68%);
  filter: blur(6px);
}
.cta-band > * { position: relative; z-index: 2; }
.cta-band h2 {
  font-size: clamp(23px, 2.8vw, 31px);
  font-weight: 800;
  margin-bottom: 12px;
  letter-spacing: -.6px;
  /* 与首屏标题同一款渐变字面，首尾一致 */
  background: linear-gradient(100deg, #ffffff 0%, #badffc 56%, #ffb066 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
.cta-band p { color: rgba(255,255,255,.80); font-size: 15.5px; }
.cta-actions { display: flex; flex-direction: column; gap: 11px; position: relative; z-index: 2; }

.contact-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 20px;
  margin-top: 42px;
}
.contact-item {
  padding: 24px 22px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: 0 1px 2px rgba(6,32,82,.04), 0 8px 24px -14px rgba(6,32,82,.10);
  transition: transform .3s var(--ease-out), box-shadow .3s var(--ease-out);
}
.contact-item:hover {
  transform: translateY(-4px);
  box-shadow: 0 20px 44px -18px rgba(6,32,82,.24);
}
.contact-item .ci-label {
  font-size: 12.5px;
  color: var(--ink-4);
  font-weight: 600;
  letter-spacing: .5px;
  margin-bottom: 8px;
}
.contact-item .ci-value { font-size: 15.5px; font-weight: 600; color: var(--ink); word-break: break-all; }
.contact-item .ci-value.placeholder { color: var(--ink-4); font-weight: 500; font-size: 14px; }

/* ================= 页脚 ================= */
.site-footer {
  background: var(--bg-dark);
  color: rgba(255,255,255,.6);
  padding: 56px 0 30px;
  font-size: 14px;
}
.footer-top {
  display: grid;
  grid-template-columns: 1.5fr 1fr 1fr;
  gap: 40px;
  padding-bottom: 34px;
  border-bottom: 1px solid rgba(255,255,255,.1);
}
/* 页脚品牌区：用完整版锁标（含中英文全称），故不再另写机构名。
   v1.44.0：由 76px 降到 52px —— 当时用户反馈「页脚 LOGO 比页眉还大，不合理」。
   ★ v1.65.0 用户在完整看过页面后再次要求「下面的 LOGO 保持和上面一样的大小」，
   现与页眉对齐为 64px。注意：页眉用的是 nav2（宽高比 4.52），
   页脚用的是 foot2（宽高比 3.30，徽章占比更大），
   故两者同为 64px 时「视觉重量」是接近而非完全相同 —— 这是有意为之，
   因为页脚徽章本身画得更大，强行等宽反而会让页脚锁标显得比页眉还重。 */
.footer-brand { margin-bottom: 16px; }
.footer-brand img { height: 64px; width: auto; display: block; }
/* 页脚标语。
   ★ v1.67.0：文案由长句简介改为短 slogan「数字赋能人才，实战成就未来」。
   12 个字的短句用 13.5px 会显得单薄且与左侧锁标失衡，
   故放大到 16px、加字距、提高不透明度，让它读起来像品牌标语而非补充说明。
   max-width 保留 330px 以兼容移动端换行。 */
.footer-about {
  font-size: 16px;
  line-height: 1.7;
  letter-spacing: .04em;
  color: rgba(255,255,255,.86);
  max-width: 330px;
}

.footer-col h4 {
  color: #fff;
  font-size: 14px;
  font-weight: 700;
  margin-bottom: 14px;
}
.footer-col ul { list-style: none; display: flex; flex-direction: column; gap: 9px; }
.footer-col a { font-size: 13.5px; transition: color .2s; }
.footer-col a:hover { color: #fff; }

.footer-bottom {
  padding-top: 22px;
  display: flex;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
  font-size: 12.5px;
  color: rgba(255,255,255,.42);
}

/* ICP 备案号链接：保持与底栏同色，悬停时提亮 + 下划线（工信部要求可点击跳转） */
.footer-bottom .icp-link {
  color: inherit;
  text-decoration: none;
  transition: color .2s ease;
}
.footer-bottom .icp-link:hover { color: rgba(255,255,255,.72); text-decoration: underline; }

/* ================= 滚动入场动画 ================= */
.reveal {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity .7s cubic-bezier(.16,1,.3,1), transform .7s cubic-bezier(.16,1,.3,1);
}
.reveal.in { opacity: 1; transform: none; }

/* ================= 响应式 ================= */
/* ★ v1.68.2：新增「矮视口」档位。
   背景：用户反馈「在一个页面不能完整显示」。
   实测 1366×768（最常见笔记本，视口仅 657px）时首屏高 695px，溢出 38px。
   排查发现撑高的不是图片（320px），而是**左栏文案 447px** ——
   1366 宽度下标题命中字号上限 53px，两行就占 123px；
   加上徽章(38) + 各段间距(24+22+…) + 正文 3 行 + 按钮(56) + 底注(23)。
   → 对策：只压「段间距」不动字号。
     字号缩小会直接损害可读性和气势，段间距收紧几乎无观感损失。
     这与坑 39 的原则一致：压缩空隙优先于缩小字号。

   ⚠️ 本档必须放在**所有宽度断点之后**（文件靠后位置），
   否则窄屏时 max-width:980 的 .hero padding 会把它覆盖掉。
   CSS 媒体查询之间没有优先级，同权重下**后定义者胜**。
   已挪到文件末尾（见「矮视口收尾档」）。 */

/* ★ v1.68.0：新增中间档位。760（汉堡菜单）～1080 之间，页眉里同时要放
   横版锁标 + 6 个中文菜单项 + 2 个按钮，原 gap:30px 在这个区间放不下，
   菜单文字会被逐字断成两行（980px 实测破版）。
   这里只收 gap，不动字号 —— 收 gap 是「压缩空隙」，缩字号是「牺牲可读性」，
   优先级不同。锁标同步降到 54px 让出横向空间。 */
@media (max-width: 1080px) {
  .nav-links { gap: 18px; }
  .nav-links a { font-size: 14px; }
  .nav-brand img { height: 54px; }
  .nav-actions { gap: 8px; }
  .nav-actions .btn { padding: 9px 15px; font-size: 13.5px; }
}

@media (max-width: 980px) {
  .hero-inner { grid-template-columns: 1fr; gap: 40px; }
  .hero { padding: 138px 0 70px; }
  .cta-band { grid-template-columns: 1fr; padding: 40px 30px; }
  .cta-actions { flex-direction: row; flex-wrap: wrap; }
  .footer-top { grid-template-columns: 1fr 1fr; gap: 30px; }
  /* 基地背书：窄屏两列 */
  .cred-grid { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 760px) {
  /* ★ v1.68.2：手机上首屏同样是单列，图片高度继续按视口自适应。
     与 ≤980 档的区别：文案区在手机上行数更多（标题换行 + 正文 4 行），
     故留给图片的空间更少，系数相应收小。
     下限 200px 保证极矮屏（横屏手机 ~400px 高）图片仍可见。

     v1.68.2 补充：手机上「首屏完全一屏装完」并不现实（单列必然要堆叠），
     所以这一档的目标定为「**按钮 + 完整图片卡**落在第一屏内」——
     用户不用滚动就能看到核心 CTA 和左侧视觉。
     实测 390×844 差 9px，靠压段间距补上（不动字号）。

     ⚠️ 注意：这里**不要**给 .hero-card 或 .hero-note 加 margin。
     .hero-note 本身就没有 margin-bottom（它已是文案区最后一行），
     .hero-card 与文案区的间距由 .hero-inner 的 grid gap 统一管理。
     第一次尝试时我多加了两处 margin，结果把卡片整体下推、
     超出量反而从 9px 涨到 29px —— 单列布局里重复加间距只会叠高。

     正确做法：压 .hero-inner 的 grid gap（文案区与图片卡的唯一间距来源）。 */
  .hero-inner { gap: 30px; }   /* 单列时的行间距，原 40px；压 10px 即可补上 390×844 的 9px 缺口 */
  /* ★ v1.69.3：手机端同样不再硬算视口高度。图片卡按内容自然高，
     首屏装不下的部分由滚动承接（手机用户本来就习惯滚动）。
     给一个 320px 的最小高度，保证图片在手机上仍有足够存在感。 */
  .hero-visual { height: auto; min-height: 320px; }
  /* ★ v1.69.2：手机上**不再隐藏**专业列表。
     原设计（v1.68.0）隐藏的理由是"专业条目在小屏已由课程体系板块承载"，
     当时它只是静态文字，隐藏损失不大。
     但 v1.69.2 起它是首屏的主交互（点击就地展开详情），
     手机上隐藏 = 整块功能在移动端消失，用户点不到。
     现改为保留，并给足高度（手机单列时首屏本来就要滚动，多 40px 可接受）。 */
  .hv-major-head { font-size: 12.5px; padding: 6px 7px; }
  .hv-major-head small { font-size: 10.5px; }
  .hv-facts > div { padding: 0 8px; }
  .hv-facts dd { font-size: 11px; }
  .nav-links {
    position: fixed;
    top: 84px; left: 0; right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background: #fff;
    border-bottom: 1px solid var(--line);
    padding: 8px 14px 16px;
    box-shadow: 0 18px 40px rgba(6, 32, 82, .18);
    border-radius: 0 0 18px 18px;
    transform: translateY(-12px);
    opacity: 0;
    visibility: hidden;
    transition: all .25s;    max-height: calc(100vh - 84px);
    overflow-y: auto;
    z-index: 95;
  }
  .nav-links.open { transform: none; opacity: 1; visibility: visible; }
  /* ★ v1.62.0 必读：移动端菜单是「白色圆角面板」，而页眉在深色首屏上
     会把 .site-header .nav-links a 设成白色。若不在此处显式覆盖，
     白底 + 白字 = 菜单项全部隐形（上一轮就踩过）。
     这里用 .nav-links.open a 提高优先级压过页眉的深底配色。 */
  .nav-links a,
  .nav-links.open a,
  .site-header .nav-links a,
  .site-header.light .nav-links a {
    display: block;
    padding: 15px 14px;
    font-size: 15.5px;
    color: var(--ink-2);
    border-bottom: 1px solid var(--line);
  }
  .nav-links.open a:hover,
  .site-header .nav-links.open a:hover { color: var(--brand); }
  /* ★ v1.64.0：移动端菜单是竖排列表，下划线装饰会与分隔线打架，
     且触屏没有 hover 概念，故一律隐藏底部长条（桌面端保留）。 */
  .nav-links a::before,
  .site-header .nav-links a::before { display: none; }
  /* 触屏无 hover，恢复默认字号与位移，避免触摸后残留上浮 */
  .nav-links a,
  .site-header .nav-links a { transform: none; }
  .nav-links li:last-child a { border-bottom: none; }
  /* 移动端高亮：左色条 + 浅蓝底（不用下划线，避免压到相邻项） */
  .nav-links.open a.active,
  .site-header .nav-links.open a.active,
  .site-header.light .nav-links.open a.active {
    color: var(--brand);
    background: var(--brand-tint);
    border-left: 3px solid var(--brand);
    border-radius: 8px;
  }
  .nav-links a.active::after { display: none; }
  .nav-toggle { display: flex; }
  .nav-actions .btn { display: none; }
  .nav-actions .btn.btn-mobile-show { display: inline-flex; }

  .section { padding: 60px 0; }
  .wrap { padding: 0 18px; }
  /* 移动端横版锁标：宽高比 4.52:1，58px 高时横向约 190px，窄屏放得下。
     v1.63.0 页眉改回横版，高度同步从 76 → 64（桌面）/ 58（移动）。 */
  .nav-brand img { height: 52px; }
  .nav-brand { max-width: calc(100% - 66px); overflow: hidden; }
  /* ★ v1.65.0：页脚锁标桌面端已与页眉对齐为 64px，
     移动端必须同步降到与页眉相同的 52px，
     否则页脚（64）反而比页眉（52）大 —— 正是 v1.44.0 被指出的「主次颠倒」。 */
  .footer-brand img { height: 52px; }
  .footer-top { grid-template-columns: 1fr; }
  .cta-band { padding: 34px 24px; border-radius: var(--radius); }
  .logo-wall { grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); }
  /* 就业挑战：移动端改为「痛点 → 方案」上下堆叠，箭头转 90° */
  .chal-cols { grid-template-columns: 1fr; gap: 8px; }
  .chal-cols .chal-col-head:last-child { text-align: left; }
  .chal-row { grid-template-columns: 1fr; gap: 8px; }
  .chal-arrow { transform: rotate(90deg); }
  .chal-item-top span { max-width: none; }
  /* 合作伙伴：三列数据在窄屏竖排 */
  /* 合作伙伴三数据：移动端横排三列紧凑呈现（原竖排太占屏） */
  .partner-stats { grid-template-columns: repeat(3, 1fr); gap: 10px; max-width: none; }
  .ps-item { padding: 16px 6px; }
  .ps-item b { font-size: 24px; }
  .ps-item b span { font-size: 14px; }
  .ps-item > span { font-size: 12px; margin-top: 5px; }
  .pw-mark { font-size: 9px; }
  /* 基地背书：窄屏单列 */
  .cred-grid { grid-template-columns: 1fr; }
  /* 人才成长路径：6 步在窄屏改为两列，去掉箭头 */
  .path-row { gap: 10px; }
  .path-step { flex: 1 1 calc(50% - 10px); }
  .path-sep { display: none; }
  /* 新板块网格：窄屏降列 */
  .svc-grid, .svc-grid-8 { grid-template-columns: 1fr 1fr; }
  .upgrade-grid { grid-template-columns: 1fr; }
  .mech-grid { grid-template-columns: 1fr 1fr; }
}

/* ==========================================================================
   ★ v1.68.2 矮视口收尾档（必须放在所有宽度断点之后）
   —— 用户反馈「在一个页面不能完整显示」。

   实测（Playwright，deviceScaleFactor=2）：
     1366×768（视口 657px）首屏 695px → 溢出 38px
     1440×900（视口 789px）首屏 734px → 已收进一屏
     1920×1080            首屏 914px → 已收进一屏

   排查结论：撑高的**不是图片**（320px），而是**左栏文案 447px**：
     徽章 38 + 间距 24 + 标题两行 123 + 间距 22 + 正文三行 ~86
     + 间距 36 + 按钮 56 + 间距 ~30 + 底注 23 ≈ 447
   1366 宽度下标题命中字号上限 53px，是最大的单项消耗。

   对策：**只压段间距，不动字号**。
     - 字号缩小直接损害可读性与首屏气势（标题是首屏主角）
     - 段间距收紧几乎无观感损失
   这与坑 39 的原则一致：压缩空隙优先于缩小字号。

   ⚠️ 为什么放在文件最末尾：
     CSS 媒体查询之间没有优先级，同权重下**后定义者胜**。
     若把 max-height:720px 写在 max-width:980px 之前，
     窄屏时后者会覆盖前者的 .hero padding，矮屏笔记本（1366×768）永远修不好。
     这个坑是实测发现的 —— 第一次放在中间时，1366 的溢出量纹丝不动。
   ========================================================================== */
@media (max-height: 720px) {
  /* ★ v1.69.10：下留白 48 → 78。同主页眉重复扣除的修正（见 .hero 注释），
     省下的 84px 按「图片与底部留白均分」——下留白 +30、图片 +54。
     总高仍精确一屏：136 + (100vh − 136 − 78) + 78 = 100vh ✓ */
  .hero { padding: 136px 0 78px; }
  .badge { margin-bottom: 16px; }
  .hero h1 { margin-bottom: 16px; }
  .hero-sub { margin-bottom: 24px; }
  .hero-cta { margin-bottom: 22px; }
  .hero-note { margin-bottom: 0; }

  /* ⚠️ 留白改了，.hero-inner 的"可用高度"公式必须跟着改（两处同步）。
     ⚠️ 公式里**不再减页眉 84px** —— .site-header 是 position: fixed，
        不占文档流，padding-top 已让开页眉。原来多减了 84，
        导致矮屏上首屏同样差 84px。
     ★ 下限保持 400：曾试过降到 330 想让 1024×600 也精确满屏，
       实测无效 —— 那个尺寸真正顶破行高的是**左栏文案**（1024 宽下
       文案折行多、实测 395px 高），不是这个下限。为它继续压数值
       只会伤害主流尺寸的质量，而 1024×600 是十余年前的上网本分辨率，
       少量溢出只需极轻滚动即可接受。 */
  .hero-inner { min-height: clamp(400px, calc(100vh - 136px - 78px), 900px); }
  /* ★ v1.69.3：桌面双栏下图片卡由 stretch 自动撑满行高，
     这里只需要守住一个下限 —— 矮屏时行高可能不够装下展开态详情，
     靠 min-height 兜底，内容超出部分由页面滚动承接，不会"图被盖住"。 */
  .hero-visual { height: 100%; min-height: 380px; }
}

/* 矮视口 + 窄屏（单列布局）：文案与图片上下叠加，图片按内容自然高 */
@media (max-height: 720px) and (max-width: 980px) {
  .hero { padding: 120px 0 48px; }
  .hero-inner { min-height: 0; }
  .hero-visual { height: auto; min-height: 320px; }
}

/* ==========================================================================
   ★ v1.69.3 玻璃层「紧凑档」—— 与「完整档」的取舍

   用户反复说「右侧还是没达到我的效果」，根因就是这个：

   实测各桌面视口能给图片的空间（卡片可用高度 − 展开态玻璃层）：
                    卡片可用   完整玻璃层419    → 图片   紧凑玻璃层~240 → 图片
     1366×768   →    500        81px（一条缝）      260px ✅
     1280×800   →    532       113px              292px ✅
     1440×900   →    632       213px              392px ✅
     1512×982   →    714       295px              474px ✅
     1920×1080  →    812       393px ✅           572px ✅
   即：**只有 1080 高才撑得起完整详情**；1366/1280 上玻璃层会吃掉
   80% 的卡片高度，图上只剩一条 —— 而用户看到的正是这两个尺寸。

   取舍：
     A. 矮屏不默认展开（用户明确要求"默认展示AI视觉创作"，否决）
     B. 除最高的那一档外，详情降级为紧凑形态（采用）

   紧凑档 = 收起「一句话介绍」与「核心课程/就业方向」，
            只留 标语 + 周期/课时/学费 + 标签。
   这三项正是访客"扫一眼就要知道"的决策信息（多少钱、学多久、什么门槛），
   被收起的两块是"想深入了解时才看"的内容 —— 完整版由招生简章页承载。

   ⚠️ 门槛定在 max-height: 1000px（只有 ≥1001px 高才显示完整详情）：
      1080 是最主流的高屏尺寸，让它用上完整内容；其余一律紧凑。
   ⚠️ 用 max-height 而不是 max-width：
      决定图片空间的是**视口高度**（卡片高度由 100vh 推导），
      与屏幕宽窄无关。1920×1080 宽但高，不触发；1366×768 窄但矮，触发。
   ⚠️ 必须放在文件后段 —— 与 ≤980 那档同权重时后定义者胜。 */
@media (min-width: 981px) and (max-height: 1000px) {
  .hv-desc,
  .hv-more { display: none; }
  /* 详情区变矮了，max-height 上限同步收紧，避免折叠动画空跑。
     紧凑态内容实测约 145px（标语17 + 三格45 + 标签21 + padding）。 */
  .hv-major.is-open .hv-major-body { max-height: 152px; }
  /* 行高再收 2px：6 行就是 12px，在小屏上直接变成图片的可视高度 */
  .hv-major-head { padding: 4px 8px; }
}
/* 更极端（≤700px 高，如 1024×600 的老设备）：进一步只留三格数据。
   ⚠️ 不在这里改 .hero-inner 下限 —— 该尺寸顶破行高的是左栏文案（395px），
      压下限没用（实测过）。详情区压到只留"标语 + 三格数据"即可，
      图片仍能留出约 104px。 */
@media (min-width: 981px) and (max-height: 700px) {
  .hv-tags { display: none; }
  .hv-major.is-open .hv-major-body { max-height: 98px; }
  .hv-major-head { padding: 3px 8px; }
}

@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
  html { scroll-behavior: auto; }
}

/* 打印 */
/* ==========================================================================
   招生简章页（admissions.html）
   —— 复用首页已建立的变量与组件；下列为简章页专有部分。
   色板仍严格只用 4 色（主蓝/橙/浅蓝/深藏蓝），派生色仅做明暗调整。
   ========================================================================== */

/* ---------- 页首 ---------- */
/* v1.62.0：简章页首屏与首页首屏统一为「深色舞台」，视觉语言一致。
   否则首页深色、简章页浅色，切页时观感断裂。 */
.page-hero {
  position: relative;
  padding: 156px 0 76px;   /* 上留白同步页眉 84px（v1.63.0） */
  /* ★ v1.69.11：让顶部深色区**至少铺满一屏**（用户「招生简章页有这个情况」）。
     问题：这里一直是"按内容自然高"（实测 1536×816 下只有 620px），
     视口 816px 时下方空出 196px，直接露出下面 .section-soft 的浅色底
     —— 看起来就是"首屏没铺满、下面一条白"。

     与首页 .hero 的差别：首页右栏有一张高图片卡把首屏撑起来了，
     而简章页只有文字 + 四格数据，天然就是 620px。
     故这里需要**显式给一个最小高度**。

     ⚠️ 为什么用 calc 而不是 min-height: 100vh：
        100vh 包含页眉那 84px，而 .site-header 是 position: fixed、
        不占文档流，.page-hero 从 y=0 起算 —— padding-top: 156px
        已经让开了页眉。用 100vh 会多出 84px（正是首页踩过的坑 50）。
        故写 100vh 即可（不减页眉），但要用 min-height 而非 height：
        内容比一屏高时（窄屏文案折行多）仍需能自然溢出让页面滚动。
     ⚠️ 用 min-height 而不是 height —— 窄屏下内容会超一屏，
        用 height 会把内容裁掉（本页 overflow: hidden）。
     ⚠️ 下限 560px：极矮视口（1024×600）下 calc 可能算出很小的值，
        那时让页面滚动，而不是把这一块压扁。
     ⚠️ **不要封上限**！首页 .hero-inner 封了 900px 是为了防
        "超宽屏上图片卡被拉得无限长"；简章页这一块没有图片，
        纯文字居中，视口多高就撑多高才正确。
        实测教训：照抄首页的 clamp(..., 980px) 后，1920×1080 下
        深色区只到 980px，底部又露出 100px —— 同一个问题换个尺寸复现。
        故这里用 min-height: max(560px, 100vh)，只兜下限、不封上限。 */
  min-height: max(560px, 100vh);
  color: #fff;
  background:
    radial-gradient(1100px 580px at 80% -14%, rgba(34,108,225,.40), transparent 62%),
    radial-gradient(820px 480px at 4% 112%, rgba(255,121,27,.15), transparent 62%),
    linear-gradient(168deg, #0a1430 0%, var(--ink-deep) 34%, #08193f 70%, #061634 100%);
  border-bottom: none;
  overflow: hidden;
  isolation: isolate;
}
.page-hero::before {
  content: '';
  position: absolute;
  width: 660px; height: 660px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(34,108,225,.40), transparent 68%);
  top: -240px; right: -140px;
  filter: blur(6px);
  animation: heroFloat 20s ease-in-out infinite alternate;
  pointer-events: none;
  z-index: 1;
}
.page-hero::after {
  content: '';
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(186,223,252,.08) 1px, transparent 1px),
    linear-gradient(90deg, rgba(186,223,252,.08) 1px, transparent 1px);
  background-size: 50px 50px;
  mask-image: radial-gradient(ellipse 74% 66% at 50% 40%, #000 30%, transparent 100%);
  -webkit-mask-image: radial-gradient(ellipse 74% 66% at 50% 40%, #000 30%, transparent 100%);
  pointer-events: none;
  z-index: 1;
}
.page-hero .wrap { position: relative; z-index: 4; }
/* ★ v1.69.11：.page-hero 现在有 min-height（≥ 一屏），
   内容需要在这块更高的空间里**垂直分布**，而不是全挤在顶部、
   把多出来的高度全留在底部（那样白边变成"深色空白"，观感一样差）。

   做法：把 .page-hero 变成 flex 列 + justify-content: center，
   .wrap 作为唯一子项被垂直居中。多出来的高度**均分到内容上下**，
   内容块整体落在视觉中心。
   ⚠️ 只对 ≥981px 的双栏桌面档生效 —— 窄屏下内容本身会超过一屏
      （文案折行多），居中会让首屏顶部被"截断感"，
      窄屏应保持顶对齐、自然滚动。 */
@media (min-width: 981px) {
  .page-hero {
    display: flex;
    flex-direction: column;
    justify-content: center;
  }
  .page-hero .wrap { width: 100%; }
}
.crumb {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: rgba(255,255,255,.50);
  margin-bottom: 20px;
}
.crumb a { color: rgba(255,255,255,.68); transition: color .2s; }
.crumb a:hover { color: #fff; }

.page-hero h1 {
  font-size: clamp(29px, 4.2vw, 46px);
  font-weight: 800;
  letter-spacing: 2px;
  line-height: 1.2;
  margin-bottom: 14px;
  color: #fff;
}
.page-hero-sub {
  font-size: clamp(15px, 1.8vw, 19px);
  font-weight: 700;
  /* 深底上的品牌蓝偏暗，改用浅蓝保证可读性 */
  color: var(--brand-light);
  letter-spacing: .5px;
  margin-bottom: 22px;
}
.page-hero-lead {
  font-size: 16px;
  color: rgba(255,255,255,.74);
  max-width: 780px;
  line-height: 1.9;
}

.page-hero-meta {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 16px;
  margin-top: 38px;
  max-width: 820px;
}
/* 深底上的指标卡改为玻璃质感，与首屏右侧面板同一套语言 */
.phm-item {
  background: rgba(255,255,255,.07);
  border: 1px solid rgba(186,223,252,.22);
  border-radius: var(--radius);
  padding: 18px 20px;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.10);
}
.phm-num {
  font-size: 25px;
  font-weight: 800;
  letter-spacing: -.8px;
  color: var(--brand-light);
  line-height: 1.15;
}
/* 首个指标用橙强调，与首页 hero 保持同一套视觉语言 */
.phm-item:first-child .phm-num { color: #ffb066; }
.phm-num span { font-size: 13.5px; font-weight: 600; color: rgba(255,255,255,.62); margin-left: 2px; letter-spacing: 0; }
.phm-label { font-size: 12.5px; color: rgba(255,255,255,.56); margin-top: 5px; }

/* ---------- 规格表（专业总览 / 薪资参考共用） ---------- */
.spec-table-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  border-radius: var(--radius-lg);
}
.spec-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  font-size: 14.5px;
  min-width: 640px;
}
.spec-table thead th {
  background: var(--brand-deep);
  color: #fff;
  font-size: 13.5px;
  font-weight: 700;
  letter-spacing: .5px;
  text-align: left;
  padding: 15px 20px;
  white-space: nowrap;
}
.spec-table tbody td {
  padding: 17px 20px;
  border-top: 1px solid var(--line-2);
  color: var(--ink-2);
  vertical-align: middle;
}
.spec-table tbody tr:nth-child(even) { background: var(--bg-soft); }
.spec-table tbody tr:hover { background: var(--brand-tint); }
.spec-table tbody td strong { color: var(--ink); font-weight: 700; font-size: 15px; }
.spec-table tbody td small {
  display: block;
  font-size: 12.5px;
  color: var(--ink-4);
  margin-top: 3px;
  font-weight: 500;
}
.spec-table .salary {
  color: var(--accent);
  font-weight: 800;
  font-size: 15.5px;
  letter-spacing: -.3px;
  white-space: nowrap;
}
.spec-table .salary small { color: var(--ink-4); font-weight: 500; font-size: 12px; }

/* 表格内的小标签 */
.chip {
  display: inline-block;
  font-size: 12.5px;
  font-weight: 600;
  padding: 4px 11px;
  border-radius: 999px;
  white-space: nowrap;
}
.chip-ok { background: var(--brand-tint); color: var(--brand); border: 1px solid var(--brand-light); }
.chip-req { background: #fff3e8; color: #b8500b; border: 1px solid #ffd7b0; }

.table-note {
  margin-top: 18px;
  font-size: 13px;
  color: var(--ink-4);
  line-height: 1.85;
}

/* ---------- 方向详情块 ---------- */
.prog { max-width: 980px; margin: 0 auto; }

.prog-head {
  display: flex;
  align-items: flex-start;
  gap: 20px;
  padding-bottom: 22px;
  margin-bottom: 26px;
  border-bottom: 2px solid var(--line-2);
}
.prog-no {
  flex: none;
  width: 54px; height: 54px;
  border-radius: 16px;
  background: linear-gradient(135deg, var(--brand) 0%, var(--brand-deep) 100%);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  font-weight: 800;
  letter-spacing: -.5px;
  box-shadow: 0 6px 18px rgba(34,108,225,.26);
}
.prog-head h2 {
  font-size: clamp(22px, 2.6vw, 29px);
  font-weight: 800;
  letter-spacing: -.6px;
  margin-bottom: 7px;
}
.prog-slogan {
  font-size: 14.5px;
  color: var(--brand);
  font-weight: 600;
}

.prog-desc {
  font-size: 15.5px;
  color: var(--ink-2);
  line-height: 1.95;
  margin-bottom: 30px;
}

/* 关键参数条 */
.prog-meta {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  margin-bottom: 34px;
}
.pm-item { background: #fff; padding: 18px 20px; }
.pm-label {
  font-size: 12px;
  color: var(--ink-4);
  font-weight: 600;
  letter-spacing: .6px;
  margin-bottom: 7px;
}
.pm-value { font-size: 16px; font-weight: 700; color: var(--ink); letter-spacing: -.2px; }
.pm-value span { display: block; font-size: 12.5px; font-weight: 500; color: var(--ink-4); margin-top: 2px; }

.prog-sub {
  font-size: 17px;
  font-weight: 700;
  margin-bottom: 16px;
  padding-left: 13px;
  border-left: 3px solid var(--accent);
  line-height: 1.4;
}
.prog-sub2 {
  font-size: 14.5px;
  font-weight: 700;
  color: var(--ink-3);
  margin: 32px 0 14px;
}
.prog .prog-sub + .hl-list,
.prog .prog-sub + .job-grid { margin-bottom: 34px; }
.prog .job-grid { margin-bottom: 0; }

/* 课程亮点 / 报名条件列表 */
.hl-list { list-style: none; display: flex; flex-direction: column; gap: 13px; }
.hl-list li {
  position: relative;
  padding-left: 26px;
  font-size: 14.8px;
  color: var(--ink-2);
  line-height: 1.85;
}
.hl-list li::before {
  content: '';
  position: absolute;
  left: 6px; top: 10px;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--brand);
}
.hl-list li strong { color: var(--ink); font-weight: 700; }

/* 就业方向双栏 */
.job-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 16px;
}
.job-item {
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 20px 22px;
}
.ji-label {
  font-size: 12px;
  font-weight: 700;
  color: var(--brand);
  letter-spacing: .8px;
  margin-bottom: 9px;
}
.job-item p { font-size: 14.5px; color: var(--ink-2); line-height: 1.8; }

/* 深色区块内的方向块适配（若将来套用） */
.section-dark .prog-head { border-bottom-color: rgba(255,255,255,.16); }
.section-dark .prog-desc,
.section-dark .hl-list li { color: rgba(255,255,255,.72); }
.section-dark .prog-desc strong,
.section-dark .hl-list li strong { color: #fff; }
.section-dark .prog-sub { border-left-color: var(--accent); }
.section-dark .job-item { background: rgba(255,255,255,.05); border-color: rgba(255,255,255,.12); }
.section-dark .job-item p { color: rgba(255,255,255,.72); }
.section-dark .pm-item { background: rgba(255,255,255,.05); border-color: rgba(255,255,255,.12); }
.section-dark .prog-meta { background: rgba(255,255,255,.12); border-color: rgba(255,255,255,.12); }
.section-dark .pm-value { color: #fff; }

/* ---------- 简章页响应式 ---------- */
@media (max-width: 980px) {
  .page-hero { padding: 132px 0 54px; }
}

@media (max-width: 760px) {
  .page-hero { padding: 120px 0 44px; }
  .page-hero-meta { grid-template-columns: 1fr 1fr; gap: 12px; }
  .phm-item { padding: 14px 16px; }
  .phm-num { font-size: 21px; }

  .prog-head { gap: 14px; padding-bottom: 18px; margin-bottom: 22px; }
  .prog-no { width: 44px; height: 44px; border-radius: 13px; font-size: 17px; }
  .prog-desc { font-size: 15px; }
  .pm-item { padding: 15px 17px; }

  /* 移动端：宽表改为纵向卡片，避免横向滚动的可用性问题。
     用 data-label 把表头搬到每行前面，信息不丢。 */
  .spec-table { min-width: 0; display: block; border: none; background: transparent; border-radius: 0; }
  .spec-table thead { display: none; }
  .spec-table tbody { display: block; }
  .spec-table tbody tr {
    display: block;
    background: #fff !important;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    margin-bottom: 12px;
    padding: 6px 0;
  }
  .spec-table tbody tr:hover { background: #fff !important; }
  .spec-table tbody td {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    padding: 10px 16px;
    border-top: none;
    font-size: 14px;
  }
  .spec-table tbody td + td { border-top: 1px dashed var(--line-2); }
  .spec-table tbody td::before {
    content: attr(data-label);
    flex: none;
    font-size: 12.5px;
    color: var(--ink-4);
    font-weight: 600;
    letter-spacing: .3px;
  }
  .spec-table tbody td strong { font-size: 14.5px; }
  .spec-table tbody td small { text-align: right; }
  .spec-table .salary { font-size: 15px; }

  .spec-table tbody td { text-align: right; }
  .spec-table tbody td > * { margin-left: auto; }

  /* 薪资单元格：金额与「元/月」并排，避免「元/月」被挤到单独一行 */
  .spec-table .salary {
    display: flex;
    align-items: baseline;
    justify-content: flex-end;
    gap: 4px;
    flex-wrap: wrap;
  }
  .spec-table .salary small { display: inline; margin-top: 0; text-align: right; }
}

/* ===== ★ v1.69.2 专业手风琴的响应式收尾 =====
   窄屏：三格「周期/课时/学费」太挤会换行，改为三格不变、只压字号；
   极窄屏（≤400）才降为 2 列（学费单独占行，仍一眼可见）。 */
@media (max-width: 620px) {
  /* ★ v1.69.8：玻璃层已贴底通栏，这里只调 padding。
     极窄屏左右各留 11px，与 6 行标题的首字符形成稳定对齐线。 */
  .hv-majors { margin: 0; padding: 6px 11px 9px; }
  .hv-major-head { font-size: 12px; gap: 7px; }
  .hv-major-head small { font-size: 10px; }
  .hv-facts { gap: 0; }
  .hv-facts > div { padding: 0 7px; }
  .hv-facts dt { font-size: 9px; }
  .hv-facts dd { font-size: 11px; }
  .hv-tags li { padding: 1px 7px; font-size: 10px; }
}

/* 尊重"减少动态效果"偏好：展开/收起不做高度动画，直接切换。
   无障碍要求 —— 前庭敏感用户对连续的尺寸变化动画会有不适。
   ★ v1.69.3：新增的底图交叉渐变、微缩放、内容错峰入场一并关掉。
      注意底图是"必须能切换"的功能，所以只关 transition，
      不能把 opacity 设成常量 —— 那会让 6 张图全叠在一起。 */
@media (prefers-reduced-motion: reduce) {
  .hv-major-body,
  .hv-caret,
  .hv-major-body > *,
  .hv-major-head::before,
  .hv-major i,
  .hv-major-name,
  .hv-major-head small { transition: none; }
  /* ★ v1.69.4：新增的选中态视觉不能用"过渡"表达，但**状态本身必须保留** ——
     减少动效是减少"运动"，不是减少"信息"。所以只关 transition，不动终态。 */
  .hv-img { transition: none; transform: none; }
  .hero-visual::before { transition: none; }
}

/* ==========================================================================
   ★ v1.90.17 大屏适配（1441px 起分档放开）
   --------------------------------------------------------------------------
   用户反馈：「各个分辨率的显示器下显示效果需要优化」。

   实测定位到的根因（改前）：
     ① `.wrap` 的 `--maxw` 固定 **1200px** —— 屏幕再宽也不会变宽，
        2560 下左右各空 680px，整页像一条居中的窄条；
     ② `.hero h1` 是 `clamp(31px, 4.5vw, 53px)` —— 4.5vw 在
        **1178px 宽就顶到 53px 上限**，此后无论多宽的屏标题都一样大；
        同理 `.hero-sub` 17px、`.section h2` 上限 34px、
        `.page-hero h1` 上限 46px、`.page-hero-lead` 固定 16px。
     → 结论：2560×1440 与 1366×768 看到的是**同一套尺寸**，
        大屏上"内容偏小、四周空荡"，正是用户看到的现象。

   实测数据（改前 → 改后）：
     2560×1440 → 容器 1200（两侧各空 680）、标题 53px
              → 容器 1800、标题 84px、首屏 1126 → 1246
     1920×1080 → 容器 1200（两侧各空 360）、标题 53px
              → 容器 1420、标题 69px（首屏仍精确一屏 1080）
     1366×768 / 1440×900 / 1024×768 → **完全不变**（无 min-width 档命中）

   做法（四条原则）：
     ① **不改任何既有断点** —— 只追加 min-width 档位覆盖。
        min-width 与既有的 max-width/height 断点互斥，不会互相打架，
        也因此 1366 / 1440 / 1024 这些已验证过的尺寸零风险。
     ② 每档换一个 vw 系数（4.5vw → 3.6vw → 3.4vw），
        保证"档内随屏平滑"，两端保留 clamp 上下限，避免极端尺寸失真。
     ③ 只放开三类量：**容器宽度 + 文字尺寸 + 区块呼吸空间**。
        版式结构（栅格比例、卡片形态、颜色、圆角）一律不动 ——
        大屏与中屏保持同一套视觉语言，不会变成两个网站。
     ④ 同时覆盖首页 `.hero` 与简章页 `.page-hero` 两套首屏
        （简章页那一套是最容易漏的：容器放宽后内容会显得更空）。

   ⚠️ 本块必须放在**文件末尾、@media print 之前**：
      `.page-hero h1` 等基础规则定义在文件后半段，
      同权重时"后定义者胜"，放在它们前面会被静默覆盖
      （这正是手册里记过的那类坑）。
   ========================================================================== */

@media (min-width: 1441px) {
  :root { --maxw: 1280px; }
  .hero h1 { font-size: clamp(53px, 3.6vw, 64px); }
  .hero-sub { font-size: 17.5px; }
  .hero-inner { gap: 64px; }
  .section { padding: 108px 0; }
  /* 简章页首屏：内容天然比首页少，容器一放宽就更容易显空，
     所以标题/导语/数据卡三处都要跟着放大，否则会"缩在左上角"。 */
  .page-hero h1 { font-size: clamp(46px, 3.6vw, 58px); letter-spacing: 3px; }
  .page-hero-sub { font-size: clamp(19px, 1.4vw, 22px); }
  .page-hero-lead { font-size: 17px; max-width: 900px; }
  .page-hero-meta { max-width: 980px; }
  .phm-num { font-size: 28px; }
}

@media (min-width: 1681px) {
  :root { --maxw: 1420px; }
  .hero h1 { font-size: clamp(56px, 3.6vw, 70px); }
  .hero-sub { font-size: 18px; max-width: 620px; }
  .hero-inner { gap: 68px; }
  .section { padding: 116px 0; }
  /* 板块标题同步放大：原上限 34px 在 1681 以上明显偏小 */
  .section h2 { font-size: clamp(34px, 2.2vw, 40px); }
  .cta-band h2 { font-size: clamp(31px, 2vw, 36px); }
  .page-hero h1 { font-size: clamp(50px, 3.4vw, 64px); }
  .page-hero-lead { font-size: 18px; max-width: 980px; }
  .page-hero-meta { max-width: 1060px; }
}

@media (min-width: 1921px) {
  :root { --maxw: 1600px; }
  .hero-inner { gap: 76px; }
  .page-hero h1 { font-size: clamp(56px, 3.3vw, 70px); }
  .page-hero-lead { font-size: 19px; max-width: 1060px; }
  /* 简章页首屏在超宽屏上只有"文字 + 四格数据"，纵向堆叠时
     右侧会空出一大片（1920 以上实测：容器 1600，正文只占 1060）。
     这里把四格数据卡挪到右栏，变成「左文右数」的双栏 ——
     与首页首屏「左文右图」的版式语言一致，也把宽度用满。
     ⚠️ 只对 ≥1921px 生效：1600~1920 档用堆叠版式仍然平衡，
        过早分栏会让正文被压窄、反而挤压可读性。 */
  .page-hero > .wrap {
    display: grid;
    grid-template-columns: minmax(0, 1.02fr) minmax(0, .98fr);
    column-gap: 80px;
    align-items: center;
  }
  .page-hero .crumb,
  .page-hero > .wrap > h1,
  .page-hero-sub,
  .page-hero-lead { grid-column: 1; }
  .page-hero-meta {
    grid-column: 2;
    grid-row: 1 / span 4;
    align-self: center;
    max-width: none;
    margin-top: 0;
  }
}

@media (min-width: 2401px) {
  /* 2560 宽屏与 4K（3840×2160）：容器放到 1800，标题再上一档 */
  :root { --maxw: 1800px; }
  .hero h1 { font-size: clamp(64px, 3.4vw, 84px); }
  .hero-sub { font-size: 19px; max-width: 680px; }
}

/* ==========================================================================
   ★ v1.90.20 首屏「行高按卡片宽度兜底」—— 修「窄而高的窗口下卡片被拉变形」
   --------------------------------------------------------------------------
   用户反馈：「图1 的显示比例明显变形了」。

   实测复现（1080×1920 这类**窄而高**的窗口）：
     视口      容器   首屏高   卡片尺寸      宽高比
     1080×1920 1065   1126px   408 × 900    0.45  ← 细长条，内容被挤变形
     1366×768  1152    768px   466 × 542    0.86  ← 正常
     1920×1080 1420   1080px   554 × 854    0.65  ← 正常

   根因：`.hero-inner` 的 min-height 只跟**视口高度**挂钩
        （clamp(400px, 100vh−226px, 900px)），完全没考虑**视口宽度**。
        窗口又窄又高时 → 行高被顶到 900px 上限，而卡片宽度只有 408px，
        于是图片卡拉成 0.45 的竖长条：底图被裁成竖条、玻璃层里的
        核心课程/就业方向标签挤成一团，看起来就是"比例变形"。

   修法：给行高再加一道**按宽度**的上限 ——
        行高 ≤ (容器宽 − 侧距与列间距) × 0.72
        0.72 / 0.425 ≈ 1.69 → 卡片宽高比被夹在 **≥ 0.59**，
        与 1920×1080 下的 0.65 同一档，视觉上不再"细长"。
        （0.425 = 宫格 1.15fr/.85fr 里右列所占比例；104px = 左右 padding 48 + 列间距 56）

   ⚠️ 只在 ≥981px 且 ≥721px 高时生效：
      · ≤980px 是单列布局，卡片本来就通栏（宽 600~840），不存在此问题；
      · ≤720px 高由 @media (max-height: 720px) 独立负责，别在这里抢。
   ⚠️ 两条规则必须**同时**保留整套公式（含 1020 那条），
      只改一处会让大屏档退回"无宽度兜底"的老问题。
   ⚠️ 已核验：1366 / 1440 / 1920 / 2560 四档的计算结果**与改动前完全一致**
      （这些尺寸下 min() 的另一支更小，兜底项不生效），只有窄高窗口被纠正。
   ========================================================================== */
@media (min-width: 981px) and (min-height: 721px) {
  .hero-inner {
    min-height: clamp(400px,
      min(calc(100vh - 152px - 74px), calc((min(100vw, var(--maxw)) - 104px) * .72)),
      900px);
  }
}

/* 大屏「首屏铺满」：把 .hero-inner 的高度上限从 900px 放开到 1020px。
   原因：.hero-inner 是 clamp(400px, 100vh−226px, **900px**)，
   2560×1440 的可用高度其实是 1214px，被 900 卡住 → 首屏只有 1126px，
   下方露出 314px 的下一板块，观感"没铺满一屏"。
   放开到 1020 后首屏 1246px，与视口只差 194px；同时不会把右侧图片卡
   拉成细长条（卡宽约 610px → 比例 0.60，与 1920 下的 0.55 接近）。
   ⚠️ 排除 ≤720px 高的矮屏 —— 那种尺寸由 max-height 档负责，
      见上方 @media (max-height: 720px)。
   ★ v1.90.20：同步加上"按宽度兜底"那一支，否则大屏档会退回没有宽度兜底的状态。 */
@media (min-width: 1441px) and (min-height: 721px) {
  .hero-inner {
    min-height: clamp(400px,
      min(calc(100vh - 152px - 74px), calc((min(100vw, var(--maxw)) - 104px) * .72)),
      1020px);
  }
}

/* ==========================================================================
   ★ v1.90.20 消除「末行只剩一项」的残缺栅格
   --------------------------------------------------------------------------
   实测（1366 / 1440 这两种最主流的笔记本尺寸）发现：

     栅格          项数  自动列数   结果        容器
     .major-grid    4     3 列      3 + 1 ✗     1152
     .adv-grid      4     3 列      3 + 1 ✗     1017（视口 ≈1080）
     （.partner-wall 8 项不在此列 —— logo 墙末行不满属常见且可接受）

   根因：`repeat(auto-fit, minmax(280px,1fr))` 在 1152px 内容区里
        最多只排得下 3 列（4×280 + 3×22 = 1186 > 1152），第 4 张被挤到第二行。
        `.adv-grid` 同理（4×240 + 3×30 = 1050 > 1017）。

   修法：**项数固定的小栅格不用 auto-fit，改按断点写死列数**，保证末行永远是满的。
        · 4 项 → 只能 2 列(2×2) 或 4 列(4×1)，中间不给 3 列的机会
        · 阈值取"卡片宽度不低于 ~255px"的位置，避免为了排满把卡片压太窄

   ⚠️ 为什么加 `-4` 修饰类而不是直接改 `.major-grid` / `.adv-grid`：
      这两个类各有两处实例、项数不同 ——
        .major-grid  = [2 项(AIGC 方向)、4 项(AI 大模型方向)]
        .adv-grid    = [4 项(About 四个问题)、3 项(优势深色区)]
      直接改类会把 2 项那组压在 4 列里、把 3 项那组排成 3+空，**反而更糟**。
      （命名沿用项目已有的 `.svc-grid-8` 风格。）
   ⚠️ 顺手把 `.adv-grid` 上残留的**行内 style** 移除了 —— 行内样式优先级高于样式表，
      留着它会让这里的断点规则完全失效（静默不生效，最难排查的一类坑）。
   ========================================================================== */
@media (min-width: 981px) {
  .adv-grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .major-grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1100px) {
  /* 容器 ≥1052px：四个优势卡各约 240px、四张专业卡各约 255px，都排得下。
     ⚠️ v1.90.22 关键修正：**两个 4 项栅格必须同档切换**。
        上一版把 .adv-grid-4 定在 1100、.major-grid-4 定在 1140，
        结果 1100~1139（用户实测窗口宽 1120px）出现
        「上面的"四个问题"排 4 列、下面的四门课程掉成 2×2」——
        同一屏里两种列数，课程卡被撑到 510px 宽却只有一半有内容，显得空荡，
        用户直接反馈「课程掉下去啦」。现统一在 1100 切 4 列，两者永远同步。 */
  .adv-grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .major-grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
/* 平板 / 窄窗口档（621~980px）：同样的 4 项栅格在 auto-fit 下会落到 3 列 → 3+1。
   实测 900×1600 下 `.steps`（4 步）与 `.contact-grid`（4 项）都是 3 列 → 末行只剩 1 项。
   这里统一压成 2 列（2×2），卡片宽 280~460px，比排 3 列更舒展。
   ⚠️ 下限卡在 621：≤620 是手机档，auto-fit 自然落到 1 列，不能在这里抢着改成 2 列。 */
@media (min-width: 621px) and (max-width: 980px) {
  .adv-grid-4,
  .steps,
  .contact-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media print {
  .site-header, .site-footer, .cta-actions, .nav-toggle { display: none; }
  /* 打印时把所有专业详情都展开，否则纸上只有 6 个标题 */
  .hv-major-body { max-height: none !important; opacity: 1 !important; padding: 2px 8px 10px !important; }
  /* ★ v1.69.3：详情里新增的分层内容也要显形，否则纸上是一片空白 */
  .hv-major-body > * { opacity: 1 !important; transform: none !important; }
  /* 打印只保留当前生效的那张底图 —— 否则 6 张叠印，纸上一团黑 */
  .hv-img { display: none; }
  .hv-img.is-active { display: block; opacity: 1 !important; }
  .hero, .section { padding: 20px 0; }
  .reveal { opacity: 1; transform: none; }
}
