/* ============================================================
   鸿鹄棋弈 · v2 华丽增强层样式（css/enhance.css）
   ------------------------------------------------------------
   · 本文件为 v2 增强层专用样式，与 v1 的 css/style.css 完全解耦：
     可整体移除而不影响 v1 可用性（仅损失增强效果）。
   · 设计令牌与 v1 一致：浅 #f5f5f7 / 深 #0a0a0c / 黑 #000 /
     金 #c9a96e / 灰 #86868b；系统字体栈。
   · 纪律：动画仅 transform/opacity（60fps 目标）；全部增强元素
     均为 aria-hidden 纯装饰，不承载任何信息；不引入横向滚动条。
   · 降级铁律：本文件内不做任何"内容预隐藏"——唯一的覆盖性元素
      .preloader 默认 display:none，且仅由 JS 激活（.is-active），
      禁 JS / 脚本失败 / reduced-motion 三路径下永不显示。
   ============================================================ */

/* ============================================================
   禁裁切契约（C8 修订 / FR-043 / plan.md D33，v4 起生效并固化）
   ------------------------------------------------------------
   全站 assets\ 图（9 张 1434×2955 手机竖屏截图 + 1 张 1024×1024
   方形应用图标）一律「等比完整呈现」：
   · 合法路径：等比缩放——.shot-img 通用规则（width:auto /
     height:auto / max-width:100% / max-height 约束 /
     aspect-ratio 占位）及各版块同型 max-height 覆盖；
   · 非法路径：裁切式排版零容忍——object-fit:cover、固定窗高
     截取局部等一律禁止（截取局部不可接受，褚赢嘲讽等截图的
     对话内容必须完整可辨）；
   · 边界说明：v2 图标 border-radius:0 覆盖（圆角取消）为形状
     修饰非裁切，不在此列；
   · 履历：v4 已随趣味卡回退（D32）清除全站唯一违规处
     （v3 媒体窗 cover 裁切），此后 object-fit/object-position
     全站零声明；新增截图排布必须遵守本契约，验证阶段执行
     10 图裁切审计（SC-018）为验收关卡。
   ============================================================ */


/* ============================================================
   Preloader 品牌开场（T044）
   ------------------------------------------------------------
   状态机（D8）：inactive（默认隐藏）→ active（.is-active，JS 激活）
   → done（.is-leave 淡出 0.5s 后移除）。
   降级铁律：覆盖层默认 display:none，仅 JS 双闸门通过后激活——
   禁 JS / 脚本加载失败 / reduced-motion 下永不遮挡内容。
   ============================================================ */

/* —— 默认态：display:none（禁 JS 时永不显示——降级铁律） —— */
.preloader {
  display: none;
}

/* —— 激活态：fixed 全屏覆盖、最高 z-index、深色底、居中构图 —— */
.preloader.is-active {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #0a0a0c;
  opacity: 1;
  visibility: visible;
  /* 淡出过渡（opacity + visibility，约 0.5s ease）：
     退场时 JS 添加 .is-leave 触发 */
  transition: opacity 0.5s ease, visibility 0.5s ease;
}

/* —— 退场态：时间线完成后由 preloader.js 添加，0.5s 优雅淡出；
     pointer-events:none 确保淡出期间不拦截点击 —— */
.preloader.is-active.is-leave {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

/* —— 居中构图容器 —— */
.preloader-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* —— App 图标：落子意象（约 96-120px 取 108px）；静态无光晕（现状保持） ——
      图标自带圆角，无需 CSS 裁切（用户确认 2026-09-07）；
      v5 起开场金圈涟漪为独立描边环元素（.preloader-ripple-ring，由
      preloader.js 惰性创建，形态见「v5 图标光晕贴合」分区）——原
      box-shadow 扩散模拟及基座声明已随 T096 重构清退。 */
.preloader-icon {
  display: block;
  width: 108px;
  height: 108px;
}

/* —— App 图标圆角覆盖（2026-09-07 用户确认：图标自带圆角，无需 CSS 裁切） ——
   style.css 冻结不改，此处以加载顺序覆盖（同特异性、后文件优先），
   同时压掉 style.css 基础规则与 <768px 媒体查询内的圆角（28/24px、18/16px）。
   柔和弥散阴影仍保留：大模糊半径下矩形光晕边缘不可感知。 */
.hero-icon,
.download-icon {
  border-radius: 0;
}

/* —— 品牌名：大字、浅墨色、字距微放 —— */
.preloader-brand {
  margin: 26px 0 0;
  color: #f5f5f7;
  font-size: clamp(30px, 5vw, 42px);
  font-weight: 700;
  letter-spacing: 0.14em;
  line-height: 1.2;
}

/* —— 品牌名逐字 span（T045 由 preloader.js 运行时拆分创建）：
     行内块保证 GSAP 可施加 transform；父级 letter-spacing 对行内块
     依然生效，字符间距与原文视觉一致，无布局跳动 —— */
.preloader-char {
  display: inline-block;
  will-change: transform, opacity;
}

/* —— 金色进度细线：宽 160-240px 取 200px、高 2px，内条 scaleX 填充 —— */
.preloader-bar {
  display: block;
  width: 200px;
  height: 2px;
  margin: 20px 0 0;
  background: rgba(201, 169, 110, 0.18);
  border-radius: 1px;
  overflow: hidden;
}

/* 内条：CSS 静止态即 scaleX(0)（覆盖层仅在 JS 激活态可见，无"禁 JS 空线"问题）；
   scaleX 0→1 充满由 T045 时间线驱动，transform-origin 左起 */
.preloader-bar-fill {
  display: block;
  width: 100%;
  height: 100%;
  background: #c9a96e;
  border-radius: 1px;
  transform: scaleX(0);
  transform-origin: left center;
  will-change: transform;
}

/* —— reduced-motion 双保险：JS 闸门已保证不激活，此处 CSS 侧再钉死
     「永不显示」（D2 降级矩阵的样式侧兜底） —— */
@media (prefers-reduced-motion: reduce) {
  .preloader {
    display: none !important;
  }
}


/* ============================================================
   背景层（T046 / T048：固定全屏背景渐变层）
   ============================================================ */

/* —— 固定全屏背景层：置于内容之下（z-index:-1，负 z 参与根堆叠上下文，
      绘制于 body 画布背景之上、版块内容之下）、不拦截交互；默认无背景色
      ——由 js/enhance.js 双闸门通过后逐帧驱动填充。禁 JS / 脚本加载失败 /
      reduced-motion 三路径下完全透明不可见，各版块回退 v1 静态分段背景。 —— */
.backdrop {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
}

/* —— 渐变启用态（html.has-backdrop 由 enhance.js 双闸门通过后添加）：
      仅顶层版块（main > section 直接子级）背景透明化，让固定层色彩透出。
      限定直接子级是关键——.growth-panel.theme-dark 等复用主题类的子面板与
      各类卡片底色是设计构成，不随背景层透明（误伤会击穿深色卡片/面板）。
      pin-spacer 分支：GSAP pin（v1 棋类 / v2 题库·成长）把版块包进
      main > div.pin-spacer 后脱离直接子级——无此分支时被钉版块静态
      底色全程遮挡背景层，其边界退化为 v1 式硬切换（v3 修复）。 —— */
html.has-backdrop main > section.theme-light,
html.has-backdrop main > .pin-spacer > section.theme-light,
html.has-backdrop main > section.theme-dark,
html.has-backdrop main > .pin-spacer > section.theme-dark,
html.has-backdrop main > section.theme-black,
html.has-backdrop main > .pin-spacer > section.theme-black {
  background-color: transparent;
}


/* ============================================================
   大标题逐字入场（T047 / T048：行内遮罩 + 字符 span）
   ------------------------------------------------------------
   拆分结构由 js/enhance.js 双闸门通过后运行时创建（降级路径 DOM 中
   不存在以下任何节点）：
     <h2 data-split="chars" aria-label="原文">
       <span class="split-mask" aria-hidden="true">
         <span class="split-char">鸿</span>…（<br> 等元素节点原位保留）
       </span>
     </h2>
   ============================================================ */

/* —— 溢出遮罩容器（整段单遮罩策略）：overflow:hidden 防字符上浮途中
      溢出标题区（否则 y 偏移中的字符会压到下方描述文字）；上下各扩
      0.15em 裁切余量并以负 margin 抵消——净布局零变化（防 CLS），兼防
      中文 ascender/descender 被遮罩误裁。display:block 保持标题原盒模型
      （宽度、居中、行高均继承，换行位置与原文一致）。 —— */
.split-mask {
  display: block;
  overflow: hidden;
  padding-block: 0.15em;
  margin-block: -0.15em;
}

/* —— 逐字 span：行内块使 GSAP 可施加 transform；父级 letter-spacing
      对行内块依然生效，字符间距与原文视觉一致（-0.03em/-0.02em 各标题
      原值直接继承）。will-change 不在此常驻（约 70 个常驻合成层不可取），
      由 JS 仅在动画期间注入、结束 clearProps 清除。 —— */
.split-char {
  display: inline-block;
}


/* ============================================================
   金色粒子氛围（T049：单一固定 canvas 层）
   ------------------------------------------------------------
   canvas 由 js/enhance.js 双闸门通过后动态创建并插入 body 末尾
   （禁 JS / 脚本加载失败 / reduced-motion 三路径下 DOM 中不存在
   本节点）：固定全屏、不拦截交互；z-index:1 绘制于全部内容之上
   （装饰带）、固定导航（v1 z-index:1000）之下。粒子为纯装饰，
   aria-hidden，不承载任何信息。
   ============================================================ */

.particles-canvas {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
}


/* ============================================================
   光束 / 辉光扫掠（T050：斜切渐变条带 + 低频呼吸）
   ------------------------------------------------------------
   光束结构由 js/enhance.js 双闸门通过后动态创建（降级零残留）：
     <host class="has-beam">…
       <span class="beam-clip" aria-hidden="true">
         <span class="beam"></span>
       </span>
     </host>
   ============================================================ */

/* —— 宿主补丁：静态定位的宿主补 position:relative（最小侵入、零布局影响；
       已是定位元素的宿主加此类无副作用） —— */
.has-beam {
  position: relative;
}

/* —— 裁切层：光束起点/终点均在宿主外侧、全程被裁切——杜绝横向滚动条；
       border-radius:inherit 贴合卡片圆角，扫掠光不越出圆角 —— */
.beam-clip {
  position: absolute;
  inset: 0;
  overflow: hidden;
  border-radius: inherit;
  pointer-events: none;
}

/* —— 光束条带：斜切（rotate -22°）金色线性渐变、两端大透明度衰减；
       rotate/xPercent 由 GSAP 统一接管（创建即置于裁切区外，触发前
       不可见），will-change 常驻于数量有限的扫掠元素上（≤12 个） —— */
.beam {
  position: absolute;
  top: -12%;
  left: 0;
  width: 34%;
  height: 124%;
  background: linear-gradient(90deg,
    rgba(201, 169, 110, 0) 0%,
    rgba(201, 169, 110, 0.10) 30%,
    rgba(232, 210, 166, 0.38) 50%,
    rgba(201, 169, 110, 0.10) 70%,
    rgba(201, 169, 110, 0) 100%);
  will-change: transform;
}

/* —— 低频周期辉光呼吸：仅 Hero 与收尾两处（元素由 JS 创建并插入对应
       section——两版块均为 overflow:hidden 定位容器，辉光零外溢；
       循环动画由 keyframes 承担，微 opacity/scale 呼吸 7s 低频） —— */
.glow-breathe {
  position: absolute;
  left: 50%;
  top: 50%;
  width: clamp(280px, 42vw, 560px);
  height: clamp(280px, 42vw, 560px);
  border-radius: 50%;
  background: radial-gradient(circle,
    rgba(201, 169, 110, 0.14) 0%,
    rgba(201, 169, 110, 0.05) 46%,
    rgba(201, 169, 110, 0) 72%);
  pointer-events: none;
  animation: glow-breathe 7s ease-in-out infinite;
  will-change: transform, opacity;
}

@keyframes glow-breathe {
  0%, 100% {
    transform: translate(-50%, -50%) scale(1);
    opacity: 0.55;
  }

  50% {
    transform: translate(-50%, -50%) scale(1.07);
    opacity: 1;
  }
}


/* ============================================================
   侧边滚动进度指示器（T051：右侧金线轨道 + 8 版块节点）
   ------------------------------------------------------------
   轨道整体由 js/enhance.js 动态创建并插入 body 末尾（降级零残留）。
   z-index:900 置于内容与粒子层之上、固定导航（1000）之下；
   容器 pointer-events:none、仅节点恢复交互——右侧边缘不产生
   大面积点击死区。
   ============================================================ */

/* —— 轨道容器：右侧固定、垂直居中带 —— */
.scroll-progress {
  position: fixed;
  right: clamp(16px, 2vw, 26px);
  top: 50%;
  transform: translateY(-50%);
  z-index: 900;
  width: 14px;
  height: min(44vh, 340px);
  pointer-events: none;
}

/* —— 细灰底线（深浅版块通吃的中性灰，2px） —— */
.scroll-progress-track {
  position: absolute;
  left: 50%;
  top: 0;
  bottom: 0;
  width: 2px;
  margin-left: -1px;
  background: rgba(134, 134, 139, 0.35);
  border-radius: 1px;
}

/* —— 金色进度线：scaleY 0→1 由整页滚动 scrub 驱动（transform-only） —— */
.scroll-progress-fill {
  position: absolute;
  inset: 0;
  background: #c9a96e;
  border-radius: 1px;
  transform: scaleY(0);
  transform-origin: top center;
  will-change: transform;
}

/* —— 版块节点：14px 点击热区，视觉圆点在 ::before（6px，居中）；
       top 由 JS 按版块位置百分比注入 —— */
.scroll-progress-dot {
  position: absolute;
  left: 50%;
  width: 14px;
  height: 14px;
  margin: -7px 0 0 -7px;    /* 以 top 百分位点为中心 */
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
  pointer-events: auto;
}

.scroll-progress-dot::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 6px;
  height: 6px;
  margin: -3px 0 0 -3px;
  border-radius: 50%;
  background: rgba(134, 134, 139, 0.6);
  transition: transform 0.3s ease, background-color 0.3s ease,
    box-shadow 0.3s ease;
}

/* —— hover 态：金点亮起 + 微放大 —— */
.scroll-progress-dot:hover::before {
  background: #c9a96e;
  transform: scale(1.35);
}

/* —— 当前版块：放大高亮 + 金框光环 —— */
.scroll-progress-dot.is-active::before {
  background: #c9a96e;
  box-shadow: 0 0 0 3px rgba(201, 169, 110, 0.22);
  transform: scale(1.4);
}

/* —— 可访问性：键盘焦点可见（focus-visible） —— */
.scroll-progress-dot:focus-visible {
  outline: 2px solid #c9a96e;
  outline-offset: 2px;
  border-radius: 50%;
}

/* —— <768px 隐藏：移动端保持版面干净；已创建后缩回窄视口同样隐藏
       （与 JS 侧 matchMedia 动态创建构成双路径显隐） —— */
@media (max-width: 767.98px) {
  .scroll-progress {
    display: none;
  }
}


/* ============================================================
   题库 / 成长 pin 连续镜头（T052 / T053）
   ------------------------------------------------------------
   仅桌面（≥1280px）且版块挂 .is-pinned 状态类时生效（类由
   js\enhance.js 在 GSAP + 非 reduced-motion 双闸门内的
   gsap.matchMedia 回调中添加，断点退出自动移除）——其余一切场景
   （<1280px / 禁 JS / CDN 失败 / reduced-motion）下两版块保持
   css\style.css 的 v1 默认版式，降级零残留。
   版式总纲（沿用 v1 #chess-types.is-horizontal 的 100svh 舞台范式）：
     · 版块整体 100svh 纵向承载：版块头在上（pin 期间仍在视口内），
       双栏布局撑满余下空间；
     · 文案栏（.puzzle-copy / .growth-copy）成为 overflow:hidden 的
       「取景窗」：内容条（练习网格 + 解答行 / 统计分组 + 回放面板）
       总高超出窗口的部分，由 pin 时间线随滚动上移「依次掠过」；
     · 截图栏钉在窗侧：题库单图垂直居中（pin 期间 scale 1→1.06 推近，
       max-height 预留 2vh 上下呼吸位防放大出血）；成长双图列垂直居中
       错落（pin 期间近/远景交错位移成纵深，位移在 JS）；
     · 布局由 grid 切换为 flex：文案栏 flex:1 + min-height:0 取得确定
       高度（grid 自动行内百分比 max-height 存在循环依赖），截图栏为
       定宽比例列。
   ============================================================ */
@media (min-width: 1280px) {

  /* —— 公共舞台：版块 100svh 纵向承载（v1 #chess-types 同款） —— */
  #puzzles.is-pinned,
  #growth.is-pinned {
    display: flex;
    flex-direction: column;
    height: 100vh;                        /* 旧浏览器回退 */
    height: 100svh;                       /* 小视口单位 */
    padding-block: 0;
    padding-top: var(--nav-height);       /* 固定导航让位，pin 期间版块头不被遮 */
    overflow: clip;                       /* 裁切镜头内溢出（clip 不产生滚动容器，不影响 pin） */
  }

  #puzzles.is-pinned > .container,
  #growth.is-pinned > .container {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;                       /* 撑满导航以下的全部舞台 */
    min-height: 0;
  }

  #puzzles.is-pinned .section-head,
  #growth.is-pinned .section-head {
    flex-shrink: 0;                       /* 矮视口下版块头优先保住 */
    margin-bottom: clamp(1.5rem, 4vh, 3rem);
  }

  /* —— 布局切换 grid → flex：文案栏成为可裁切的取景窗 —— */
  #puzzles.is-pinned .puzzle-layout,
  #growth.is-pinned .growth-layout {
    display: flex;
    flex: 1 1 auto;
    min-height: 0;
    align-items: stretch;
    gap: clamp(48px, 6vw, 88px);
  }

  #puzzles.is-pinned .puzzle-copy,
  #growth.is-pinned .growth-copy {
    flex: 1 1 0;                          /* 弹性占据余下宽度 */
    min-height: 0;                        /* flex 高度钳制：overflow 裁切生效前提 */
    overflow: hidden;                     /* 取景窗：内容条上移时在此裁切 */
  }

  /* —— T052 · 题库截图栏：钉在窗侧，垂直居中 —— */
  #puzzles.is-pinned .puzzle-shot {
    flex: 0 0 38%;
    align-items: center;                  /* 截图列内垂直居中 */
    min-height: 0;
  }

  #puzzles.is-pinned .puzzle-shot .shot-img {
    max-height: calc(100% - 4vh);         /* 上下各留 2vh：scale 1.06 推近的出血不触舞台边缘 */
  }

  /* —— T053 · 成长双截图列：垂直居中错落（交错位移由 JS 编排） —— */
  #growth.is-pinned .growth-shots {
    flex: 0 0 40%;
    min-height: 0;
    align-content: center;                /* 两行整体垂直居中 */
    padding-top: clamp(16px, 3vh, 32px);  /* 近景 -48px 上移的顶部余量保险 */
  }

  #growth.is-pinned .growth-shot--keymove {
    margin-top: clamp(20px, 4vh, 44px);   /* 收窄 v1 下错量，适配取景舞台 */
  }

  #growth.is-pinned .growth-shot .shot-img {
    max-height: min(56vh, 520px);         /* 双图列高约束：两图 + 错落在舞台内完整可见 */
  }
}


/* ============================================================
   桌面交互增强（T054：指针柔光 + 卡片 3D 倾斜）
   ------------------------------------------------------------
   硬闸门与 JS 侧一致：(pointer:fine) 且 (hover:hover)——柔光元素与
   .v2-tilt 类均由 js/enhance.js 过闸后创建/添加，触摸设备 DOM 零
   残留；文末反向媒询为 CSS 侧双保险（任何异常残留强制隐藏）。
   ============================================================ */

/* —— 指针柔光：固定低透明度金色径向光晕（380px，峰值 alpha 约 0.07）；
       位置由 JS 以 translate3d 每帧施加（left/top 锚定原点、偏移半宽
       居中于指针）；opacity 由 JS 淡入淡出（入窗跟随 / 离窗淡出）；
       z-index:800——内容与粒子层(1)之上、进度轨道(900)与固定导航
       (1000)之下 —— */
.cursor-glow {
  position: fixed;
  left: 0;
  top: 0;
  width: 380px;
  height: 380px;
  border-radius: 50%;
  background: radial-gradient(circle,
    rgba(201, 169, 110, 0.07) 0%,
    rgba(201, 169, 110, 0.035) 38%,
    rgba(201, 169, 110, 0) 68%);
  pointer-events: none;
  z-index: 800;
  opacity: 0;
  will-change: transform, opacity;
}

/* —— 卡片 3D 倾斜：.v2-tilt 由 JS 过闸后添加于棋类卡/模式卡/趣味卡
       （不改 v1 类定义本身）。透视（1000px，契约区间 800-1200）由
       GSAP transformPerspective 注入卡片自身 transform——CSS
       perspective 属性无法作用于元素自身的旋转，故此处不设
       perspective；本类承载合成层提示，并裁剪 v1 卡片 transition
       中的 transform 项（JS 每帧直写 transform，CSS transform 过渡
       会叠加出双重平滑迟滞；box-shadow / border-color 悬停过渡
       原样保留，v1 :hover translateY(-4px) 微升由 JS 同等补偿） —— */
@media (hover: hover) and (pointer: fine) {
  .v2-tilt {
    will-change: transform;
  }

  .v2-tilt.mode-card {
    transition: box-shadow 0.35s ease;
  }

  .v2-tilt.fun-card {
    transition: border-color 0.35s ease, box-shadow 0.35s ease;
  }
}

/* —— 双保险：不可悬停或非精确指针设备强制隐藏（柔光本就只会在
       fine+hover 双媒询下由 JS 创建，此处兜底任何异常残留；
       与 JS matchMedia 闸门双侧一致） —— */
@media (hover: none), (pointer: coarse) {
  .cursor-glow {
    display: none !important;
  }
}


/* ============================================================
   收尾粒子汇聚（T055：复用 T049 粒子层，此区无新增样式）
   ------------------------------------------------------------
   「万子归一」汇聚粒子、落子圆点与金圈涟漪全部绘制于既有
   .particles-canvas（draw hook 叠加进 T049 渲染循环，复用其 sprite
   与密度分级，不建第二套渲染系统、无新增 DOM 节点）；CTA 接力
   复用 T047/T048 既有 .split-mask / .split-char 逐字样式，按钮辉光
   脉冲为 v1 既有编排——本区无需任何新增规则。
   ============================================================ */


/* ============================================================
   降级与响应式收口
   （prefers-reduced-motion：全部增强停用；各断点退化规则）
   ============================================================ */

/* —— reduced-motion 双保险：JS 闸门已保证 enhance.js 全部模块不注册
       （背景层无色、无开关类、不拆分、DOM 无 .split-mask/.split-char），
       CSS 侧再钉死——背景层永不显示；即便开关类异常残留（正常路径不可能），
       顶层版块静态分段背景也强制还原，v1 视觉兜底。
        逐字相关无需覆盖规则：reduce 下拆分 DOM 不存在，标题即原文。
        T049~T051 氛围层元素（粒子 canvas / 光束 / 辉光呼吸 / 进度轨道）
        与 T054 指针柔光同理：reduce 下本就不创建，此处对任何异常残留
        强制不可见且停用动画。 —— */
@media (prefers-reduced-motion: reduce) {
  .backdrop {
    display: none;
  }

  html.has-backdrop main > section.theme-light,
  html.has-backdrop main > .pin-spacer > section.theme-light {
    background-color: var(--bg-light, #f5f5f7);
  }

  html.has-backdrop main > section.theme-dark,
  html.has-backdrop main > .pin-spacer > section.theme-dark {
    background-color: var(--bg-dark, #0a0a0c);
  }

  html.has-backdrop main > section.theme-black,
  html.has-backdrop main > .pin-spacer > section.theme-black {
    background-color: var(--bg-black, #000000);
  }

  .particles-canvas,
  .beam-clip,
  .beam,
  .glow-breathe,
  .scroll-progress,
  .cursor-glow {
    display: none !important;
    animation: none !important;
  }
}


/* ============================================================
   v3 布局节奏令牌覆盖层（T063 / plan.md D19）
   ------------------------------------------------------------
   v1 style.css 冻结不改——布局节奏调优以「后加载文件同特异性覆盖」
   实施于本分区，整体摘除本分区即回到 v2 节奏。
   原理：enhance.css 晚于 style.css 加载，同特异性选择器后者胜——
   :root 令牌覆盖对 style.css 基础值（clamp(80px,12vh,160px) 等）
   与其 <768px 媒询值（clamp(64px,11vh,96px)）同时生效；故本分区
   自带 <768px 媒询再行收紧，构成完整三档节奏。
   幅度克制（约 +10%）：桌面版块留白呼吸感强化、移动端同步放大后
   收紧、卡片间距与版块头下间距微调；≥1280 pin 镜头版式（本文件
   上文 #puzzles.is-pinned 等）选择器特异性更高，不受本覆盖波及。
   ============================================================ */

/* —— 桌面基线：版块垂直留白 80~160px → 88~176px（呼吸感强化）；
        卡片网格间距 16~28px → 18~30px —— */
:root {
  --section-space: clamp(88px, 13vh, 176px);
  --gap-card: clamp(18px, 3vw, 30px);
}

/* —— 版块头下间距定向覆盖：2.5~4.5rem → 2.75~5rem
        （标题区与内容带略拉开；#chess-types.is-horizontal 与 pin 镜头
        舞台的 .section-head 特异性更高，保持既有专用值不波及） —— */
.section-head {
  margin-bottom: clamp(2.75rem, 6.5vh, 5rem);
}

/* —— <768px 同步收紧：留白 64~96px → 72~104px、版块头 2~3rem →
        2.25~3.25rem（移动端维持 v3 放大比例的紧凑档） —— */
@media (max-width: 767.98px) {
  :root {
    --section-space: clamp(72px, 12vh, 104px);
  }

  .section-head {
    margin-bottom: clamp(2.25rem, 5.5vh, 3.25rem);
  }
}


/* ============================================================
   v3 亮点三截图橱窗（T064 / plan.md D18）
   ------------------------------------------------------------
   #highlights 右侧 .highlight-shot 由 v2 单图升级三图橱窗：
   ≥768px 主图（首页）左列跨双行，排行榜/自定义外观双小图右列
   纵排、上小图下移错落（呼应成长双图构图语言）；<768px 退化
   横滑画廊（复用 v1 技术画廊手法：flex + overflow-x +
   scroll-snap，html overflow-x:clip 兜底无横向滚动条）。
   图片复用 .shot-img 通用规则（aspect-ratio 占位防 CLS），
   高度约束经 #highlights 前缀提特异性覆写（(1,2,0) > v1 的
   (0,2,0) <768 规则与 (0,1,0) 基础规则）；摘除本分区并还原
   index.html 橱窗 DOM 即回 v2 单图形态。
   ============================================================ */

/* —— 橱窗容器：接管 v1 .highlight-shot 的 flex 居中为版式网格 —— */
#highlights .highlight-shot {
  display: block;
}

#highlights .v3-showcase {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
  grid-template-rows: auto auto;
  gap: clamp(14px, 2vw, 22px);
  align-items: start;
}

/* —— 橱窗条目：主图左列跨双行；排行榜小图右列上格下移错落 —— */
#highlights .v3-showcase-item {
  margin: 0;                 /* reset 兜底（v1 * 已清零，防御性声明） */
  min-width: 0;
}

#highlights .v3-showcase-item--main {
  grid-column: 1;
  grid-row: 1 / 3;
}

#highlights .v3-showcase-item--lead {
  grid-column: 2;
  grid-row: 1;
  margin-top: clamp(18px, 4vh, 40px);   /* 上小图下移：双图错落纵排 */
}

#highlights .v3-showcase-item--sub {
  grid-column: 2;
  grid-row: 2;
}

/* —— 高度约束：主图 64vh/600px、小图 28vh/260px 封顶——等比缩放
        不裁切（.shot-img aspect-ratio + max-width:100% 天然同形） —— */
#highlights .v3-showcase .shot-img {
  max-height: min(64vh, 600px);
}

#highlights .v3-showcase-item--lead .shot-img,
#highlights .v3-showcase-item--sub .shot-img {
  max-height: min(28vh, 260px);
}

/* —— <768px：三图横滑画廊（v1 技术画廊同手法，触摸友好）—— */
@media (max-width: 767.98px) {
  /* US6-1 修复：.highlight-shot 为 .highlight-layout（grid）的 item，
     min-width:auto 会被橱窗 flex 子项（三图固定宽不收缩）的
     min-content 撑到 789px 超出视口——横滑失效且第三图被
     html overflow-x:clip 裁除不可见。约束回列宽后 overflow-x:auto
     正常接管横滑（SC-012）。 */
  #highlights .highlight-shot {
    min-width: 0;
  }

  #highlights .v3-showcase {
    display: flex;
    gap: clamp(12px, 3vw, 18px);
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scroll-snap-type: x mandatory;
    padding-bottom: 8px;     /* 滚动条/触摸滑动余量，不遮内容 */
  }

  #highlights .v3-showcase-item {
    flex: 0 0 auto;
    width: min(68vw, 300px);
    scroll-snap-align: center;
  }

  #highlights .v3-showcase-item--lead {
    margin-top: 0;           /* 画廊取消错落，横向等高排布 */
  }

  #highlights .v3-showcase .shot-img {
    max-height: min(60vh, 520px);   /* 覆写 v1 <768 的 .highlight-shot
                                       .shot-img 约束（特异性更高） */
  }
}


/* ============================================================
   v3 胜率曲线渐变填充与关键手标记（T066 / plan.md B3、D25）
   ------------------------------------------------------------
   #growth 对局回放面板内 SVG 胜率曲线的 v3 增强：
   · .winrate-fill：曲线下方金色纵向渐变填充（渐变定义于 index.html
     defs #v3-winrate-fill，金 → 透明）——CSS 静止态即 0.32 透明度，
     禁 JS / 脚本失败 / reduced-motion 三路径下静态完整呈现（降级
     铁律：本文件不预隐藏内容）；JS 接管路径下由 enhance.js 先归零、
     描边完成后淡入回此值；
   · .key-mark：关键手标记圆点（--brilliant 神之一手金色 /
     --blunder 恶手中性灰），默认静态全亮；点亮后加 .is-lit 进入
     低频呼吸 keyframes（仅 transform/opacity，transform-box:
     fill-box 使缩绕自身圆心；呼吸由 CSS 独占 transform——GSAP
     侧只动 opacity，无双重动画冲突）；
   · reduced-motion：呼吸关闭、填充保留（T066 明确口径）。
   摘除本分区并还原 index.html SVG 结构即回 v2 纯描边形态。
   ============================================================ */

/* —— 渐变填充：静止透明度（JS 接管路径的淡入终点同为该值） —— */
.winrate-fill {
  opacity: 0.32;
}

/* —— 关键手标记：默认静态全亮；缩放基准为自身圆心 —— */
.key-mark {
  transform-box: fill-box;
  transform-origin: 50% 50%;
}

.key-mark--brilliant {
  fill: #c9a96e;
}

.key-mark--blunder {
  fill: rgba(134, 134, 139, 0.95);
}

/* —— 点亮后低频呼吸：scale 1→1.15 / opacity 0.72→1，3.6s；
        神之一手负延迟错相，两标记呼吸波峰交错 —— */
.key-mark.is-lit {
  animation: v3-key-mark-breathe 3.6s ease-in-out infinite;
}

.key-mark--brilliant.is-lit {
  animation-delay: -0.9s;
}

@keyframes v3-key-mark-breathe {
  0%, 100% {
    transform: scale(1);
    opacity: 0.72;
  }

  50% {
    transform: scale(1.15);
    opacity: 1;
  }
}

/* —— reduced-motion：呼吸关闭（标记保持点亮静止态），填充保留 —— */
@media (prefers-reduced-motion: reduce) {
  .key-mark.is-lit {
    animation: none;
  }
}


/* ============================================================
   v3 棋盘翻转过场薄纱（T067 / plan.md D20）
   ------------------------------------------------------------
   深浅主题交界的 45° 金线网格薄纱（.v3-veil，由 enhance.js 按交界
   惰性创建——当前 10 版块序列共 9 处，scrub 掠过见 JS 编排）：
   · 全屏 fixed 层，上下各外扩 10vh（top -10% / height 120%——
     薄纱 yPercent ±6 漂移行程约 7.2vh 仍在覆盖余量内，掠过全程
     无裸边）；
   · 45° 双向斜纹由两组 repeating-linear-gradient（45° / 135°）
     构成——视觉等效旋转网格而元素本身不旋转，全覆盖无旋转几何
     裸角，且与 GSAP transform 互不干扰；
   · 默认 visibility:hidden + opacity:0（JS autoAlpha 接管：>0 即
     恢复可见；0 透明度下跳过绘制，9 层全屏装饰的性能护栏）；
   · z-index 850：内容与鼠标柔光（800）之上、进度轨道（900）与
     导航（1000）之下；pointer-events:none、aria-hidden 由 JS
     标注——纯装饰层不拦截交互、不入无障碍树。
   摘除本分区（或闸门不过）即无任何交界薄纱，回 v2 交付态。
   ============================================================ */

.v3-veil {
  position: fixed;
  top: -10%;
  left: 0;
  width: 100vw;
  height: 120vh;
  z-index: 850;
  pointer-events: none;
  visibility: hidden;
  opacity: 0;
  background-image:
    repeating-linear-gradient(45deg,
      rgba(201, 169, 110, 0.9) 0, rgba(201, 169, 110, 0.9) 1px,
      transparent 1px, transparent 48px),
    repeating-linear-gradient(135deg,
      rgba(201, 169, 110, 0.9) 0, rgba(201, 169, 110, 0.9) 1px,
      transparent 1px, transparent 48px);
}

/* —— reduced-motion：薄纱隐藏（模块不注册，此为双保险） —— */
@media (prefers-reduced-motion: reduce) {
  .v3-veil {
    display: none;
  }
}


/* ============================================================
   v3 联机数据流脉冲（T069 / plan.md D22）
   ------------------------------------------------------------
   #connectivity 互联连线的数据流光点（.v3-pulse-dot，由 enhance.js
   于 ≥1280 断点内按连线惰性创建，沿连线方向循环位移）：
   · 与 .connect-line 同定位基准（.connect-grid）的独立绝对定位
     span（脱离 grid 项目流，零布局影响），纵向由 JS 实测对齐
     连线中线（top 内联设定），横向 x 行程经 GSAP 函数值自适应
     ——本分区只承担形态；
   · 金色圆点 + 静态辉光（box-shadow 不参与动画——位移与显隐由
     JS 仅以 transform / opacity 驱动）；
   · 默认 opacity:0（JS 起播渐显、离场渐隐；版块外停帧即静帧）；
   · z-index auto + DOM 序：置于 .connect-icon（z-index 1）之下，
     光点掠过节点呈「串珠间穿行」。
   摘除本分区（或 <1280 / 闸门不过）即回 v1 静态连线。
   ============================================================ */

.v3-pulse-dot {
  position: absolute;
  left: 0;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #c9a96e;
  box-shadow: 0 0 10px 2px rgba(201, 169, 110, 0.55);
  opacity: 0;
  pointer-events: none;
}

/* —— reduced-motion：光点隐藏（模块不注册，此为双保险） —— */
@media (prefers-reduced-motion: reduce) {
  .v3-pulse-dot {
    display: none;
  }
}


/* ============================================================
   v3 标题鎏金流光（T070 / plan.md D23）
   ------------------------------------------------------------
   逐字入场完成后由 js/enhance.js 为标题瞬时加 .v3-gilded：
   .split-char 逐字应用金色渐变背景 + background-clip:text +
   color:transparent，300% 宽渐变带经 background-position
   100% → 0% 自左向右扫过一次，字间错峰由 JS 注入 inline
   animation-delay（整题总长归一 0.8-1.2s 契约；本分区
   animation-duration 0.45s 须与 JS GILD_CHAR_SWEEP 同步），
   扫毕 JS 移除类恢复纯墨基色。
   · 中断安全：渐变首尾各约 38% 为纯 --ink——任何时刻中断
     （类提前移除 / 动画跳帧）字形仍完整可读，无半金半墨态；
   · 双 token 流光带：浅色语境深金（浅底可辨识），深色语境
     品牌金 + 浅香槟（深底上呈流光），随 --ink 同套主题下发；
   · 降级：@supports 兜底（JS 侧 CSS.supports 同判定为闸门）；
     禁 JS / reduced-motion：类永不存在，标题墨色原样。
   ============================================================ */

/* —— 流光带双色 token（随版块主题就近覆盖） —— */
:root {
  --v3-gild-a: #a8874f;
  --v3-gild-b: #d9bd85;
}

.theme-dark,
.theme-black {
  --v3-gild-a: #c9a96e;
  --v3-gild-b: #f4e6c0;
}

@supports ((-webkit-background-clip: text) or (background-clip: text)) {

  /* —— 鎏金态：字形由渐变背景裁切绘制（color 透明化）；105deg
          轻微斜切呼应 v2 光束姿态；background-position 静态值
          100% 即「带悬于字外左侧」的纯 ink 初始态 —— */
  .v3-gilded .split-char {
    color: transparent;
    -webkit-text-fill-color: transparent;
    background-image: linear-gradient(105deg,
      var(--ink) 0%, var(--ink) 38%,
      var(--v3-gild-a) 46%,
      var(--v3-gild-b) 50%,
      var(--v3-gild-a) 54%,
      var(--ink) 62%, var(--ink) 100%);
    background-size: 300% 100%;
    background-repeat: no-repeat;
    background-position: 100% 0;
    -webkit-background-clip: text;
    background-clip: text;
    animation: v3-gild-sweep 0.45s linear;
  }

  /* —— 流光带自左向右：100%（带在字外左侧）→ 0%（带离场至右侧）；
          linear + JS 字间错峰 = 波前匀速行进；两端均为纯 ink 基色 —— */
  @keyframes v3-gild-sweep {
    from { background-position: 100% 0; }
    to { background-position: 0% 0; }
  }
}


/* ============================================================
   v3 深色版块棋盘暗纹（T071 / plan.md D24）
   ------------------------------------------------------------
   4 处 theme-dark 版块（highlights/connectivity/puzzles/fun）的
   ::before 叠加双向细线网格（repeating-linear-gradient：1px 线、
   透明度 0.028 ≤ 0.03 契约、clamp(44px,6vw,64px) 格距呼应 #hero
   既有棋盘格语言）；纯 CSS 零 JS 零图片，禁 JS 路径照常呈现。
   · #download（theme-black）刻意不加：其 ::before 已被 v1 金色
     径向光晕占用，且收尾版块保持「纯黑 + 金」的极简基调（克制）；
    · 层序：v1 section 已设 position:relative（预留装饰挂点）；
      定位 ::before 取 z-index:0（负值会被版块自身不透明底色压
      不可见），配对将唯一内容子层 .container 提为 z-index:1——
      暗纹垫于全部内容之下、版块底色之上；pin 镜头固定态下版块
      自成层叠上下文，内部相对层序保持不变（.growth-panel
      .theme-dark 为非 section 子面板，天然不在选择器范围）；
      pin-spacer 分支（v3 修复）：#puzzles 被 v2 pin 包进
      div.pin-spacer 后脱离 main 直接子级，无此分支暗纹丢失；
   · 对比度：0.028 透明度 1px 细线对底色亮度扰动约 3%，
     18:1 级正文对比度余量远超 WCAG AA/AAA。
   ============================================================ */

main > section.theme-dark::before,
main > .pin-spacer > section.theme-dark::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image:
    repeating-linear-gradient(0deg,
      rgba(245, 245, 247, 0.028) 0,
      rgba(245, 245, 247, 0.028) 1px,
      transparent 1px,
      transparent clamp(44px, 6vw, 64px)),
    repeating-linear-gradient(90deg,
      rgba(245, 245, 247, 0.028) 0,
      rgba(245, 245, 247, 0.028) 1px,
      transparent 1px,
      transparent clamp(44px, 6vw, 64px));
}

/* —— 内容提层：暗纹垫底（4 处版块的内容均为唯一 .container 子层） —— */
main > section.theme-dark > .container,
main > .pin-spacer > section.theme-dark > .container {
  position: relative;
  z-index: 1;
}


/* ============================================================
   v3 下载点击涟漪（T072 / plan.md D26）
   ------------------------------------------------------------
   .v3-ripple-host 由 js/enhance.js 于绑定监听时加类（闸门不过则
   零类零监听零节点）：补 position:relative（涟漪定位基准）+
   overflow:hidden（涟漪裁切于按钮内，不越胶囊圆角）。
   涟漪圆片 .v3-ripple 点击时由 JS 创建（尺寸/落点按点击坐标内联
   设定），径向金色渐变，GSAP scale+opacity 扩散 0.6s 后 DOM 移除；
   静态 transform:scale(0)/opacity:0 为「创建 → 首帧补间」间的
   无闪现双保险。v1 .btn-download 既有 transform/box-shadow
   transition 不受波及（本分区不触碰 transition）。
   降级：禁 JS / reduced-motion：类与节点均不存在，点击照常跳转。
   ============================================================ */

.v3-ripple-host {
  position: relative;
  overflow: hidden;
}

.v3-ripple {
  position: absolute;
  border-radius: 50%;
  background: radial-gradient(circle,
    rgba(201, 169, 110, 0.5) 0%,
    rgba(201, 169, 110, 0.24) 45%,
    rgba(201, 169, 110, 0) 70%);
  pointer-events: none;
  transform: scale(0);
  opacity: 0;
}

/* —— reduced-motion：涟漪隐藏（模块不注册，此为双保险） —— */
@media (prefers-reduced-motion: reduce) {
  .v3-ripple {
    display: none;
  }
}


/* ============================================================
   v3 图标落子微交互（T073 / plan.md D27）
   ------------------------------------------------------------
   首屏 .hero-icon 与收尾 .download-icon 的 hover「沉一下」：
   translateY 0→3px 下沉 + 回弹曲线（cubic-bezier(0.34,1.56,0.64,1)
   ≈ back.out 的 CSS 等价），离悬停同曲线回弹归位。
   · 采用独立 translate 属性而非 transform——v1 入场
     （data-animate="scale"：GSAP transform + clearProps）与
     本效果属性通道正交，入场途中悬停零干涉；
   · 仅 (hover:hover) 且 (pointer:fine) 内启用（触摸零启用）；
     两图标在 v1/v2 层均无既有 transition（enhance.css 仅覆盖过
     border-radius），本 transition 无覆盖损失；
   · 旧浏览器不识别 translate 属性：整组声明自然失效——无微交互
     亦无副作用；
   · reduced-motion 双声明齐灭（后置压序，含 :hover 态）。
   ============================================================ */

@media (hover: hover) and (pointer: fine) {
  .hero-icon,
  .download-icon {
    transition: translate 0.45s cubic-bezier(0.34, 1.56, 0.64, 1);
  }

  .hero-icon:hover,
  .download-icon:hover {
    translate: 0 3px;
  }
}

/* —— reduced-motion：下沉与回弹均关闭（含 :hover 态一并压灭） —— */
@media (prefers-reduced-motion: reduce) {
  .hero-icon,
  .download-icon,
  .hero-icon:hover,
  .download-icon:hover {
    transition: none;
    translate: none;
  }
}


/* ============================================================
   v3 棋类卡棋纹点亮（T074 / plan.md D28）
   ------------------------------------------------------------
   棋类卡内既有 v1 纯 CSS 棋纹点缀（.chess-card::before/::after：
   六种棋纹 + 印章/手牌装饰）在卡片 :hover 时点亮：
   · filter: brightness(1.15)（契约 ≤1.15 量级）——纹样亮度抬升；
   · inset 金色柔光 box-shadow（内阴影不越卡片边界）；
   · transition 仅 filter/box-shadow——v2 .v2-tilt 作用于卡片本体
     transform，元素/属性双正交零冲突；
   · v1 基线 ::before/::after 无 filter/box-shadow/transition
     （.chess-card--skill::before 的 rotate 为 transform 通道，
     本效果不触碰），离卡熄灭即回基线，reduce 复位值与基线一致；
   · 仅 (hover:hover) 且 (pointer:fine) 内启用；reduced-motion
     后置压序关闭（含 :hover 态——hover 规则特异性更高，须以
     同特异性选择器压制）。
   ============================================================ */

@media (hover: hover) and (pointer: fine) {
  .chess-card::before,
  .chess-card::after {
    transition: filter 0.35s ease, box-shadow 0.35s ease;
  }

  .chess-card:hover::before,
  .chess-card:hover::after {
    filter: brightness(1.15);
    box-shadow: inset 0 0 44px rgba(201, 169, 110, 0.12);
  }
}

/* —— reduced-motion：点亮与过渡关闭（v1 基线即无 filter/阴影） —— */
@media (prefers-reduced-motion: reduce) {
  .chess-card::before,
  .chess-card::after,
  .chess-card:hover::before,
  .chess-card:hover::after {
    filter: none;
    box-shadow: none;
    transition: none;
  }
}


/* ============================================================
   v3 矮视口防护（T075 / plan.md E1、D29）
   ------------------------------------------------------------
   矮视口（视口高 <700px）双轨修复的 CSS 轨（JS 轨 = 题库/成长 pin
   的 matchMedia 条件扩展，见 js\enhance.js T052/T053——矮视口下
   .is-pinned 类不再添加，enhance.css 既有 ≥1280 舞台分区空挂，
   两版块整体退化为 v1 非 pin 布局）。
   v1 冻结的棋类横滚 pin（main.js T020 条件不可改）以本分区保安全，
   手法按 v1 卡结构（section-head 三行文 + 卡内 序号/名称/文案）定夺：
   · ① 节奏压缩：矮视口下收紧版块头下间距与卡内垂直节奏——
     600-700px 常规矮窗下「版块头 + 卡片轨道」天然容纳于 v1 的
     100svh 舞台（实测头块约 133-168px + 压缩后卡高约 210-235px，
     640px 高窗口余量 >130px），钳制值不触发、构图零变化；
   · ② 高度钳制：卡片 max-height = 100svh − 导航高 − 版块头预留
     176px − 余量 24px——轨道（align-items:stretch 等高）随卡封顶，
     舞台内容永不溢出，v1 舞台 overflow:clip 永不裁到卡片内容
     （舞台自身维持 100svh 承载与 pin 几何不变——若对舞台加低于
     100svh 的 max-height，pin 期间舞台下方会露出后景破版，故
     「舞台钳制」以内容钳制等价达成）；
   · ③ 可读兜底：仅极端矮窗（约 <500px 高）钳制生效时，卡内
     纵向可滚（overflow-y:auto）——正文文字无裁切始终可读；
     滚动链保持默认（滚至边界自然交还页面滚动，不设
     overscroll-behavior:contain 以免劫持 pin 推镜的页滚）；
     未溢出时无滚动条、无任何行为差异；棋纹装饰（::before/::after）
     仍被 overflow 裁切于圆角内。
   作用域：≥1280px 且 .is-horizontal 状态类存在（类由 main.js T020
   双闸门内添加）——纵向模式 / <1280px / 禁 JS / 脚本失败 /
   reduced-motion 下本分区空挂零影响。100vh 先行回退 + 100svh 后置
   覆盖（C5 兼容契约）。
   摘除本分区即回 v1 原始矮视口行为（JS 轨的 pin 退化不受影响）。
   ============================================================ */
@media (min-width: 1280px) and (max-height: 699.98px) {

  /* —— ① 节奏压缩：版块头下间距（v1 基线 clamp(2rem, 6vh, 3.5rem)） —— */
  #chess-types.is-horizontal .section-head {
    margin-bottom: clamp(1.25rem, 4vh, 2rem);
  }

  /* —— ① 节奏压缩：卡内纵向内边距（v1 基线 clamp(28px, 4vw, 44px)） —— */
  #chess-types.is-horizontal .chess-card {
    padding-block: clamp(20px, 3.4vh, 34px);
  }

  /* —— ① 节奏压缩：金色序号下间距（v1 基线 clamp(14px, 2vh, 20px)） —— */
  #chess-types.is-horizontal .chess-index {
    margin-bottom: clamp(10px, 1.8vh, 18px);
  }

  /* —— ② 高度钳制 + ③ 可读兜底（见分区头注） —— */
  #chess-types.is-horizontal .chess-card {
    max-height: calc(100vh - var(--nav-height) - 200px);   /* 旧浏览器回退 */
    max-height: calc(100svh - var(--nav-height) - 200px);  /* 小视口单位 */
    overflow-y: auto;
  }
}


/* ============================================================
   v4 图文聚焦区（T083 / T084 · plan.md D31）
   ------------------------------------------------------------
   #highlights 两幕式重构的第一幕「与褚赢对弈」图文聚焦区版式：
   左列焦点文字（褚赢语音包项自 v3 列表提升，文案逐字不变）+
   右列双图组（褚赢嘲讽完整竖图主视觉 + 对战界面衬托错落）。
   · 禁裁切契约（C8 修订 / FR-043）：双图均为 1434×2955 竖图，一律
     「max-height 等比缩放 + width:auto」完整呈现，严禁
     object-fit:cover 类裁切排版（褚赢语音对话内容完整可辨）；
   · 错落位移用 transform，落在衬托图 img 上而非挂 data-animate 的
     figure 本体——figure 的 transform 通道由 v1 通用入场钩子独占
     （fade-up 补间 + clearProps 交还），父级 CSS transform 会在
     入场结束 clearProps 瞬间突跳；子 img transform 与之正交零冲突
     （错落量 ≤ 两幕间距，图脚不侵入第二幕）；
   · 焦点文字复用 v1 卡语言类（.highlight-icon/-name/-desc），
     仅放大一档以匹配聚焦区分量，类定义不动 style.css；
   · 第二幕（.highlight-layout 三项列表 + .v3-showcase 橱窗）沿用
     v1/v3 既有样式，本分区仅以 .v4-spotlight 的 margin-bottom 控制
     两幕间距（桌面较分栏 gap 大一档使分幕可感、移动与 v1 堆叠 gap
     同档）；
   · 断点：<768 纵向堆叠（焦点文字 → 双图并排缩图，择优结论：双图
     横向可整容纳于 375px 视口，全量可见优于横滑的交互成本）；
     768-1279 双栏保留、图高收敛；≥1280 完整量级（56vh/520px 与
     40vh/380px，D31 契约）；
   · 降级：本分区零预隐藏、零 JS 依赖——禁 JS / 脚本失败 /
     reduced-motion 三路径下内容静态完整可读（错落 transform 为
     静态定位手段而非动效，三路径均保留）。
   摘除本分区（并还原 index.html 第一幕 DOM）即回 v3 单幕形态。
   ============================================================ */

/* —— 基线（<768px，移动优先）：单列纵向堆叠——焦点文字在上、双图并排在下 —— */
.v4-spotlight {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(32px, 5vh, 44px);
  margin-bottom: clamp(40px, 7vh, 56px);   /* 两幕间距：与 v1 <768 布局堆叠 gap 同档 */
}

/* —— 焦点文字列：icon 在上、名称与描述纵排（复用 v1 卡文字语言） —— */
.v4-spotlight-copy {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.v4-spotlight-copy .highlight-icon {
  width: 60px;
  height: 60px;
  margin-bottom: clamp(16px, 2.5vh, 22px);
}

.v4-spotlight-copy .highlight-icon svg {
  width: 27px;
  height: 27px;
}

.v4-spotlight-copy .highlight-name {
  margin-bottom: 0.45em;
}

.v4-spotlight-copy .highlight-desc {
  max-width: 30em;
}

/* —— 双图组：<768 并排缩图（等比缩放天然不溢出，无横向滚动条） —— */
.v4-spotlight-shots {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  gap: clamp(12px, 3vw, 18px);
}

.v4-spotlight-shot {
  min-width: 0;                             /* flex 子项收缩许可，杜绝横向溢出 */
  margin: 0;                                /* figure 默认 margin reset 兜底 */
}

.v4-spotlight-shot--main .shot-img {
  max-height: min(46vh, 400px);             /* 等比完整呈现（禁裁切契约） */
}

.v4-spotlight-shot--echo .shot-img {
  max-height: min(36vh, 320px);
  transform: translateY(clamp(16px, 4vh, 32px));   /* 衬托错落（transform，见分区头注） */
}

/* —— ≥768px：第一幕双栏（焦点文字列 + 双图组列） —— */
@media (min-width: 768px) {
  .v4-spotlight {
    grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
    gap: clamp(48px, 6vw, 88px);            /* 与 v1 .highlight-layout 分栏 gap 同档 */
    align-items: center;
    margin-bottom: clamp(56px, 9vh, 104px); /* 两幕间距：大于栏内 gap 一档，分幕可感 */
  }

  .v4-spotlight-copy .highlight-name {
    font-size: clamp(1.5rem, 2.4vw, 2rem);  /* 焦点名称较列表卡放大一档 */
  }

  .v4-spotlight-copy .highlight-desc {
    font-size: 1.0625rem;
    line-height: 1.7;
  }

  .v4-spotlight-shots {
    gap: clamp(20px, 3vw, 36px);
  }

  .v4-spotlight-shot--main .shot-img {
    max-height: min(56vh, 520px);           /* D31 契约量级：褚赢主视觉 */
  }

  .v4-spotlight-shot--echo .shot-img {
    max-height: min(40vh, 380px);           /* D31 契约量级：对战衬托 */
    transform: translateY(clamp(28px, 6vh, 56px));
  }
}

/* —— 768-1279px 过渡档：双栏保留，图高收敛控两幕版块总长 —— */
@media (min-width: 768px) and (max-width: 1279.98px) {
  .v4-spotlight-shot--main .shot-img {
    max-height: min(48vh, 440px);
  }

  .v4-spotlight-shot--echo .shot-img {
    max-height: min(34vh, 320px);
    transform: translateY(clamp(20px, 5vh, 40px));
  }
}

/* ==========================================================================
   v4 布局精修（T088 · 定向覆盖层，可整体摘除回退）
   --------------------------------------------------------------------------
   依据 T087 headless 审计（375×812 / 768×1024 / 1440×900 / 1280×640），
   仅修复两类实测失衡项；style.css / main.js / enhance.js 零改动。

   F1 矮视口 hero 滚动提示压叠：
     视口高低于约 780px（各宽度实测推算的最坏阈值）时 hero 由内容撑高，
     绝对定位的 .hero-scroll-hint 随 bottom: clamp(24px,5vh,40px) 的 5vh
     收缩而沉入内容栈，与下载按钮重叠（1280×640 实测 -16.8px）。该提示为
     纯装饰（aria-hidden），短窗下已贴近首屏折叠线、失去向下引导意义，
     故按高度阈值直接隐藏——零布局影响的最小修复。

   F2 两幕间距节奏失守：
     第一幕 .v4-spotlight 的两幕间距 clamp(56px,9vh,104px) 在中矮视口取值
     （1440×900 实测 81px / 1280×640 实测 57.6px）小于其栏内 gap
     clamp(48px,6vw,88px)（实测 86.4px / 76.8px），“分幕间距大于栏内 gap
     一档”的节奏契约在矮视口失守。以 max() 引入地板值（栏 gap + 20px），
     保证任意 ≥768px 档位契约成立；原已达标档位（如 768×1024 的 92.2px）
     取值不变。
   ========================================================================== */

/* F1 · 矮视口（高 ≤779.98px）隐藏 hero 滚动提示（纯装饰，display:none 零布局影响） */
@media (max-height: 779.98px) {
  .hero-scroll-hint {
    display: none;
  }
}

/* F2 · 两幕间距地板值：≥768px 任意档位保证大于第一幕栏内 gap 一档（+20px） */
@media (min-width: 768px) {
  .v4-spotlight {
    margin-bottom: max(clamp(56px, 9vh, 104px), calc(clamp(48px, 6vw, 88px) + 20px));
  }
}


/* ============================================================
   v5 图标光晕贴合（T095 / plan.md D36）
   ------------------------------------------------------------
   .hero-icon 与 .download-icon 的 v1 冻结 box-shadow 阴影
   （style.css 基础层，冻结不改）在此以加载顺序覆盖置换为
   等质感的 drop-shadow 链——filter 链式叠加，逐层跟随 PNG
   alpha 轮廓投射，四角透明区零矩形光斑：
   · .hero-icon 三层配比逐项对齐 v1 原参量级：
     墨影 0 20px 48px α0.16 / 近影 0 6px 16px α0.08 /
     金晕 0 24px 64px α0.2；
   · .download-icon 对齐其自身 v1 双层原参（收尾黑底语境，
     阴影档位本与首屏不同）：黑影 0 12px 32px α0.5 /
     金晕 0 16px 48px α0.16；
   · box-shadow:none 必随行——压掉基础层阴影，杜绝
     「矩形阴影 + 轮廓投影」双影叠加（enhance.css 后于
     style.css 加载，同特异性下本声明稳赢）；
   · 已核查 style.css <768px 媒询内两图标仅覆盖
     width/border-radius、无任何阴影规则——本分区单档
     覆盖即全视口档生效，无需同档媒询复制；
   · 悬停沉降微交互走 translate 独立属性通道（v3 T073
     分区）、入场动画走 GSAP transform——均与 filter
     通道正交，零干涉；
   · 降级：本分区为纯 CSS 静态覆盖，禁 JS / 脚本失败 /
     reduced-motion 三路径下照常生效（静态光晕非动画）。
   摘除本分区即回 v4 交付态（box-shadow 原样回归）。
   ============================================================ */

.hero-icon {
  box-shadow: none;
  filter:
    drop-shadow(0 20px 48px rgba(29, 29, 31, 0.16))
    drop-shadow(0 6px 16px rgba(29, 29, 31, 0.08))
    drop-shadow(0 24px 64px rgba(201, 169, 110, 0.2));
}

.download-icon {
  box-shadow: none;
  filter:
    drop-shadow(0 12px 32px rgba(0, 0, 0, 0.5))
    drop-shadow(0 16px 48px rgba(201, 169, 110, 0.16));
}

/* —— Preloader 金色描边涟漪环（T096）：preloader.js 于双闸门通过、
        覆盖层激活后惰性创建（降级三路径永不创建）；left/top/width/
        height/border-radius 按图标布局位内联设定（覆盖层 fixed 定位
        为图标 offsetParent，天然对齐；transform 缩放不影响测量）；
        纯 transform/opacity 驱动（scale 0.9→1.4 + opacity 消散），
        环随覆盖层整体移除，零残留。Preloader 图标本体静态无光晕
        （现状保持），环为本分区唯一 Preloader 侧形态规则。 —— */
.preloader-ripple-ring {
  position: absolute;
  border: 2px solid rgba(201, 169, 110, 0.55);
  pointer-events: none;
}


/* ============================================================
   v5 金色华彩编排（T100 / plan.md D37）
   ------------------------------------------------------------
   initHeroOverture（js\enhance.js，T098）七元素分镜开场的
   样式承接分区：
   · 图标涟漪环 .v5-overture-ring：JS 于起播时惰性创建于
     .hero-inner（v1 已设 position:relative，为图标
     offsetParent）——left/top/width/height/border-radius 按
     图标布局位内联设定，本分区仅承担定位形态与金色描边；
     纯 transform/opacity 驱动（scale 0.9→1.4 + opacity
     消散），播毕 onComplete 移除，零残留；
   · 标题逐字鎏金 .v5-gilded / .v5-gild-ink：浮现期
     .v5-gilded 令 .split-char 以金色渐变（background-clip:
     text + color:transparent）呈现（渐变双色复用 v3 流光
     token --v3-gild-a/b，中段品牌金，浅色语境深金可辨）；
     落定后 .v5-gild-ink 经 color 色彩通道 transition（0.7s）
     平滑渐回墨色——不透明 --ink 填充淡入叠压于
     background-clip:text 渐变之上，金→墨为真交叉渐变而非
     硬切；transition 定义于「后置变化态」（.v5-gild-ink
     规则内），类添加即触发（after-change style 持有
     transition，规格保证生效）；播毕 JS 移除两类，字形
     回归纯墨基色零残留；
   · 按钮一次性金晕脉冲 .v5-gold-pulse：金色扩散环自按钮
     边缘消散一次（0.9s，JS 于分镜 1.15s 添加、2.2s 移除）——
     ⚠️ box-shadow 动画注释例外：全站仅此一处（C10 契约——
     Preloader 涟漪已环化、第一手落点涟漪已退役后，本处为
     唯一留存的 box-shadow 动画例外，口径沿用）；
   · 铁律：七元素初始态一律由 JS 注册期设置，本分区不预隐藏
     任何元素——禁 JS / 脚本失败 / reduced-motion 三路径下
     华彩零注册、类名零添加，七元素直接完整呈现；
     @supports 兜底与 reduced-motion 双保险同 v3 分区口径。
   摘除本分区即回「无华彩样式」基线（JS 侧类名空挂无视觉
   副作用；涟漪环/鎏金/金晕均失效但入场 transform/opacity
   动画不受影响）。
   ============================================================ */

/* —— 图标涟漪环：定位形态与金色描边（尺寸/圆角由 JS 内联设定） —— */
.v5-overture-ring {
  position: absolute;
  border: 2px solid rgba(201, 169, 110, 0.55);
  pointer-events: none;
}

@supports ((-webkit-background-clip: text) or (background-clip: text)) {

  /* —— 鎏金态：字形由金色渐变背景裁切绘制（浮现期应用；类添加时
          字符尚处隐藏态，snap 无闪变——transition:none 防墨→金
          意外拖尾） —— */
  .v5-gilded .split-char {
    color: transparent;
    -webkit-text-fill-color: transparent;
    background-image: linear-gradient(180deg,
      var(--v3-gild-b, #d9bd85) 0%,
      var(--gold, #c9a96e) 48%,
      var(--v3-gild-a, #a8874f) 100%);
    -webkit-background-clip: text;
    background-clip: text;
    transition: none;
  }

  /* —— 渐回墨色：不透明 --ink 填充淡入叠压鎏金渐变（真交叉渐变）；
          transition 落于本后置变化态，.v5-gild-ink 添加即触发 —— */
  .v5-gilded.v5-gild-ink .split-char {
    color: var(--ink);
    -webkit-text-fill-color: var(--ink);
    transition:
      color 0.7s ease,
      -webkit-text-fill-color 0.7s ease;
  }
}

/* —— 下载按钮一次性金晕脉冲：基座 0 6px 20px α0.2 与 style.css
        .btn-hero 静置投影逐参一致（style.css 冻结，值恒定），脉冲
        层播毕回归 CSS 计算值无跳变；animation 期间覆盖 hover 过渡，
        类移除后悬停通道完整还原。
        ⚠️ box-shadow 动画例外：全站仅此一处（C10） —— */
.v5-gold-pulse {
  animation: v5-gold-pulse 0.9s ease-out 1 both;
}

@keyframes v5-gold-pulse {
  0% {
    box-shadow:
      0 6px 20px rgba(201, 169, 110, 0.2),
      0 0 0 0 rgba(201, 169, 110, 0.5);
  }
  100% {
    box-shadow:
      0 6px 20px rgba(201, 169, 110, 0.2),
      0 0 0 30px rgba(201, 169, 110, 0);
  }
}

/* —— reduced-motion 双保险：模块不注册故类永不添加，此处再钉死
         （金晕脉冲与鎏金过渡一并压灭；涟漪环为 JS 惰性创建，
         该路径下本就不存在） —— */
@media (prefers-reduced-motion: reduce) {
  .v5-gold-pulse {
    animation: none;
  }

  .v5-gilded .split-char,
  .v5-gilded.v5-gild-ink .split-char {
    transition: none;
  }
}


/* ============================================================
   v5 导航宽度保障（T102 / plan.md D38）
   ------------------------------------------------------------
   导航 8 项标签自两字/三字扩为四字方案（T101，总字符 17→28，
   +11 字符）后，按 style.css 冻结令牌静态推算三档视口宽度
   完整性（系统字体栈 CJK 字形进宽恰为 1em、链接零字距，
   推算即实测口径；.nav-links a 为 white-space:nowrap 且
   flex 默认不换行，超宽后果是与右侧下载按钮压叠而非折行，
   故以「最窄档余量 ≥60px」为安全线）：

   · ≥1280px 桌面档（v1 原样，无需干预）：
     链接列 28×14px + 7×28px（gap clamp 2.2vw 于 1280px 端
     触顶 28px）= 588px；品牌 90px（4×18px 字 + 0.5em 金点
     与间距）；下载按钮 ≈74px（15px 字号×2 字 + 1.4em×2
     内距 + 2px 边框）；nav-inner 列间 gap 2×38.4px——
     合计 ≈829px；1280px 视口容器内容宽 1280−2×48 = 1184px，
     余量 ≈355px，宽裕。

   · 768-1279.98px 平板档（v1 原样在 768px 端濒临压叠）：
     链接列 28×13px + 7×16px = 476px，品牌 90px、按钮 74px、
     nav-inner gap 2×23.04px——合计 ≈686px；768px 容器内容
     宽 768−2×38.4 = 691.2px，余量仅 ≈5px，字体度量微差即
     触压叠 → 本分区收敛：768-1023.98px 子区间内链接字号
     13px→12px（0.75rem）、项间距 16px→12px——768px 端
     链接列收至 336+84 = 420px、余量恢复 ≈61px；
     1023.98px 端余量 ≈276px；1024-1279.98px 上段恢复 v1
     原值（1024px 端余量 ≈227px），断点两侧均安全。

   · <768px 手机档：桌面导航 display:none（汉堡折叠，v1
     断点行为零改动）；.nav-panel-links 为纵向列表，四字
     标签任意档宽度天然容纳，无需规则。

   · 进度指示器（.scroll-progress，右侧 fixed 轨道 ≥768px
     显示）核验零冲突：垂直向轨道为居中带（top 50% ±
     min(44vh,340px)/2），本档现实视口高下（≥640px）轨顶
     ≥179px，远居导航底缘 68px 之下；水平向轨道左缘
     （768px 档 768−16−14 = 738px）不侵入下载按钮右缘
     （容器右缘 729.6px）——无重叠、无点击死区。

   · 「下载」项不收窄：四字标签经中档字号/间距收敛后三档
     余量全部充足，无需图标化或缩距取舍（D38 备案：未启用
     下载项收窄策略）。

   降级：纯 CSS 静态规则，禁 JS / 脚本失败 / reduced-motion
   三路径照常生效；不触 <768 折叠断点、不改 style.css。
   摘除本分区即回 v1 平板档原始字号与间距（标签文本仍为
   T101 四字方案，仅宽度收敛失效）。
   ============================================================ */

/* —— 平板下段（768-1023.98px）：四字标签单行完整收敛 —— */
@media (min-width: 768px) and (max-width: 1023.98px) {

  .nav-links {
    gap: 12px;                    /* v1 平板档 16px → 12px（7 间隙共省 28px） */
  }

  .nav-links a {
    font-size: 0.75rem;           /* v1 平板档 0.8125rem(13px) → 12px（28 字符共省 28px） */
  }
}
