/* ============================== 字体 ============================== */
/* 单一可变字体（wght 100–900），210 字集子集 71KB —— 替代原先三个静态档 223KB。
   好处：总体积降 68%，且标题可上 900 超粗拉开层级。 */
@font-face {
  font-family: "Noto Sans SC";
  src: url("/fonts/NotoSansSC-Heavy.subset.woff2") format("woff2-variations");
  font-weight: 100 900;
  font-display: swap;
}

@font-face {
  font-family: "Noto Serif SC";
  src: url("/fonts/NotoSerifSC-Bold.subset.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Noto Serif SC";
  src: url("/fonts/NotoSerifSC-Black.subset.woff2") format("woff2");
  font-weight: 900;
  font-style: normal;
  font-display: swap;
}

:root {
  color-scheme: light;
  font-family: Inter, "Noto Sans SC", "PingFang SC", "Microsoft YaHei", sans-serif;
  --white: #ffffff;
  --ink: #071c34;
  --sky: #258dd0;
  --gold: #ffd58a;
  --ease-out: cubic-bezier(.16, 1, .3, 1);
  --ease-cine: cubic-bezier(.22, .61, .24, 1);
  /* 文字距边缘的安全边距（纯留白，不再配任何暗化层） */
  --copy-edge: clamp(28px, 6.2vw, 112px);
  /* 字重档位（2026-09-22 晚，清晰度方案 F）
     原 600/300 在杂色天空背景上"看不清"（用户反馈）。方案 F = 笔画加重 + 极细深色描边，
     内填充仍是纯白，因此观感依旧是"白字"；描边只负责在杂色边缘把字形从背景里拎出来 ——
     字幕行业标准做法，零色块、零投影、零渐变底。 */
  --w-title: 900;
  --w-sub: 600;
  --w-finale: 900;
}

* { box-sizing: border-box; }

html {
  min-width: 320px;
  background: var(--sky);
  scroll-behavior: auto;
  scrollbar-width: none;
}

html::-webkit-scrollbar { display: none; }

body {
  margin: 0;
  min-width: 320px;
  background: var(--sky);
  color: var(--white);
  overflow-x: hidden;
  overscroll-behavior-y: none;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

body.intro-running {
  /* v7.23：不在 Intro 结束时切换 overflow。长页面从首帧起就完成布局，
     滚动锁交给 JS 事件层，避免解锁 620vh 页面造成一次同步重排。 */
  overflow-x: hidden;
}

button, a { -webkit-tap-highlight-color: transparent; }

.experience {
  position: fixed;
  inset: 0;
  z-index: 1;
  overflow: hidden;
  isolation: isolate;
  background: var(--sky);
}

.fallback-frame,
.story-canvas {
  position: absolute;
  background: var(--sky);
}

.fallback-frame {
  inset: -1px;
  width: calc(100% + 2px);
  height: calc(100% + 2px);
  z-index: -3;
  background: var(--sky) url('./assets/jobmate-poster.webp') center / cover no-repeat;
}

/* v7.7：画布严格 100% 无缩放 —— 2880×1800 画布 ↔ 2880×1800 设备像素 1:1，
   旧的 inset:-1px + scale(1.001) 会让每一帧都过一次双线性重采样（全程轻微发虚）。
   细缝兜底交给 section 的 background: var(--sky)（与帧底色一致，不可见）。 */
.story-canvas {
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: -2;
  opacity: 0;
  transform: translateZ(0);
  backface-visibility: hidden;
  transition: opacity .28s ease;
}

.story-canvas.is-ready { opacity: 1; }

/* v7.16：主视觉直接进入浏览器的视频合成层。避免 canvas 每帧 5MP 搬运、
   自适应降分辨率和 intro→图片序列切源造成的模糊/停顿/闪现。 */
.story-video-live {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
  object-fit: cover;
  object-position: center;
  opacity: 0;
  pointer-events: none;
  background: var(--sky);
  transform: translateZ(0);
  backface-visibility: hidden;
  /* v7.18：两支不透明视频同步淡入淡出时，中点合成透明度只有 75%，肉眼就是暗闪。
     首尾内容连续，原子切层不会露出背景色。 */
  transition: none;
}

.story-video-live.is-ready.is-active { opacity: 1; }

/* v7.19: intro/forward are separate decoders. On the user's GPU the first
   composited forward frame can arrive in partially painted tiles. Keep an exact
   still of the shared boundary above both video layers until two forward frames
   have reached the compositor, then remove it atomically. */
.transition-hold {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  object-fit: cover;
  object-position: center;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  background: var(--sky);
  transition: none;
  transform: translateZ(0);
  backface-visibility: hidden;
}

.transition-hold.is-active {
  opacity: 1;
  visibility: visible;
}

.story-video-decoder {
  position: absolute;
  z-index: -3;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  pointer-events: none;
}

/* 2026-09-22：cinematic-shade（上下渐变 + 边缘暗角）整体移除。
   用户反馈文字背后的暗化"不好看"；PPT 参考稿是纯色底 + 纯白字、零装饰。
   白字直接压在天空视频上，可读性由画面本身的蓝色基调配比保证。 */

.nav {
  position: absolute;
  z-index: 50;
  top: 26px;
  left: 32px;
  right: 32px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  opacity: 1;
  transition: opacity .35s, transform .35s;
}

.logo {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--white);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .08em;
  text-shadow: none;
}

.logo-dot {
  width: 9px;
  height: 9px;
  border: 1.5px solid rgba(255,255,255,.95);
  border-radius: 50%;
  box-shadow: none;
}

.nav-cta {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translateY(-6px);
  transition: opacity .45s ease, transform .45s ease, visibility .45s;
  border: 1px solid rgba(255,255,255,.48);
  background: rgba(255,255,255,.14);
  color: #fff;
  border-radius: 999px;
  padding: 9px 15px;
  font-size: 12px;
  letter-spacing: .02em;
}

/* backdrop-filter 会让浏览器每帧对底下的视频做一次模糊采样——滚动时是纯白烧的 GPU 成本。
   只有确认是高性能设备（且用户没开省流/减动效）才开启，默认走半透明实底。 */
html.fx-rich .nav-cta {
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  background: rgba(255,255,255,.1);
}

.loading {
  position: absolute;
  inset: 0;
  z-index: 40;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 16px;
  background: rgba(37, 141, 208, .24);
  transition: opacity .45s ease, visibility .45s ease;
}

.loading.is-hidden { opacity: 0; visibility: hidden; }
.loading.is-failed { background: rgba(4, 23, 47, .32); cursor: pointer; }
.loading.is-failed .loading-label { font-size: 13px; text-shadow: 0 2px 12px rgba(0, 0, 0, .8); }

.loading-orbit {
  width: 34px;
  height: 34px;
  border: 1px solid rgba(255,255,255,.32);
  border-top-color: #fff;
  border-radius: 50%;
  animation: spin 1.1s linear infinite;
}

.loading-label {
  font-size: 10px;
  font-weight: 500;
  letter-spacing: .25em;
  opacity: .82;
}

@keyframes spin { to { transform: rotate(360deg); } }

.scroll-cue {
  position: fixed;
  left: var(--copy-edge);
  bottom: 26px;
  z-index: 10;
  opacity: 0;
  visibility: hidden;
  transition: opacity .35s, visibility .35s;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .2em;
  color: rgba(255,255,255,.86);
  pointer-events: none;
  display: flex;
  align-items: center;
  gap: 12px;
}

body.intro-complete:not(.exploring) .scroll-cue {
  opacity: 1;
  visibility: visible;
}
.scroll-cue { text-shadow: none; }

.scroll-cue::before {
  content: "";
  display: block;
  width: 34px;
  height: 1px;
  background: rgba(255,255,255,.6);
  animation: cue-slide 1.9s ease-in-out infinite;
}

@keyframes cue-slide {
  0%, 100% { transform: scaleX(.4); transform-origin: left; opacity: .4; }
  50% { transform: scaleX(1); opacity: 1; }
}

.story-copy {
  position: absolute;
  z-index: 12;
  inset: 0;
  pointer-events: none;
  text-align: left;
}

/* ==================== 四个位置体系（2026-09-22 晚 · 用户逐条规格定稿） ====================
   ① center  左下大标题 + 副标题；intro 播到一半进场；M4 遮罩擦入
   ② stack   顶部左对齐累积列表：「| 标题」+ 斜下方小字副标题；M2 逐字浮现、前句保留
   ③ br      右下角两行右对齐；M3 视差漂移（随滚动持续缓慢漂移）
   ④ finale  逐字波浪 + M4 遮罩擦入
   清晰度：全站统一方案 F（Heavy 900 + 极细深色描边，内填充纯白）。
   全程无阴影、无暗化、无背景块。
   ==================================================== */

.story-step {
  opacity: 0;
  visibility: hidden;
  isolation: isolate;
  transition: opacity .5s ease, visibility .5s;
}

/* 激活态基准：center / br 两个位置的容器显隐全靠它
   （stack-item 另有自己的 is-active 规则，不受此影响） */
.story-step.is-active {
  opacity: 1;
  visibility: visible;
}

/* —— ① 左下大标题（2026-09-22 晚：画面正中 → 左下角对齐，用户规格） ——
   与底部 SCROLL TO EXPLORE 提示留净空（提示底 26px，标题底边 ≈ copy-edge*0.95）。 */
.story-step[data-pos="center"] {
  position: absolute;
  left: var(--copy-edge);
  right: var(--copy-edge);
  bottom: calc(var(--copy-edge) * .95);
  display: block;
  padding: 0;
  text-align: left;
  /* 容器瞬显：进场完全交给 h2 / .center-sub 的遮罩擦入（淡入会把擦入冲淡） */
  transition: opacity .1s linear, visibility .1s;
}

.story-step[data-pos="center"] h2 {
  max-width: min(78vw, 860px);
}

/* 开场副标题（PPT 参考稿：标题下方一行小字「从JobMate开始」） */
.center-sub {
  margin: 18px 0 0;
  font-size: clamp(15px, 1.35vw, 20px);
  line-height: 1.6;
  font-weight: var(--w-sub);
  letter-spacing: .12em;
  color: rgba(255, 255, 255, .96);
  -webkit-text-stroke: .6px rgba(8, 16, 28, .5);
  paint-order: stroke fill;
}

/* —— ② 顶部左对齐累积列表（2026-09-22 晚：左侧垂直居中 → 顶部左对齐，用户规格） ——
   top 用 clamp 保证在任何窗口高度下都躲开左上角导航（nav top 26px + logo ≈ 44px）。 */
.stack {
  position: absolute;
  top: clamp(96px, 13.5vh, 168px);
  left: var(--copy-edge);
  width: min(60vw, 720px);
  display: flex;
  flex-direction: column;
  gap: clamp(16px, 1.9vw, 26px);
  opacity: 0;
  visibility: hidden;
  isolation: isolate;
  transition: opacity .52s ease, visibility .52s;
}

/* 累积出现：由 JS 给 #story-stack 加 .is-shown 控制整组淡出 */
.stack.is-shown {
  opacity: 1;
  visibility: visible;
}

.stack-item {
  position: relative;
  opacity: 0;
  visibility: hidden;
  /* 摘除（往回滚）时平滑淡出；进场效果由 h2/p 各自的动画接管 */
  transition: opacity .38s ease, visibility .38s;
}

.stack-item.is-active {
  opacity: 1;
  visibility: visible;
  transition: none;
}

/* PPT 参考稿：标题左侧一根白色竖条（随标题一起 blur 进场） */
.stack-item h2::before {
  content: "";
  display: inline-block;
  width: 3px;
  height: .92em;
  margin-right: 18px;
  vertical-align: -.08em;
  background: #fff;
  border-radius: 1px;
}

/* 序号（stack-index）已随 PPT 规格移除：参考稿里没有编号。 */

.stack-item h2 {
  margin: 0;
}

/* 副标题：斜下缩进（PPT 参考稿里副标题起点约在视口 22% 处，
   相对标题整体右移，形成"斜下方"层级） */
.stack-item p {
  margin: 8px 0 0 clamp(44px, 15.5vw, 240px);
  font-size: clamp(14px, 1.2vw, 18px);
  line-height: 1.6;
  font-weight: var(--w-sub);
  letter-spacing: .07em;
  color: rgba(255, 255, 255, .94);
  -webkit-text-stroke: .6px rgba(8, 16, 28, .5);
  paint-order: stroke fill;
}

/* —— ③ 右下角对齐（位置不变；新增 M3 视差漂移的容器位移） ——
   --br-p（0→1，由 JS 按滚动进度写入）驱动整体缓慢右移/上浮，形成"比画面慢半拍"的视差。 */
.story-step[data-pos="br"] {
  position: absolute;
  right: var(--copy-edge);
  bottom: calc(var(--copy-edge) * 0.72);
  text-align: right;
  max-width: min(46vw, 560px);
  transform: translate3d(calc(var(--br-p, 0) * 16px), calc(var(--br-p, 0) * -26px), 0);
  transition: opacity .3s ease, visibility .3s;
}

/* ==================== 排版 ====================
   字号/行距/字距保持 2026-09-22 版不变（用户要求"现样式字号排版"），
   只叠加清晰度方案 F：Heavy 900 + 极细深色描边。 */
.story-step h2 {
  margin: 0;
  font-family: "Noto Sans SC", "PingFang SC", "Microsoft YaHei", sans-serif;
  font-size: clamp(30px, 3.7vw, 56px);
  line-height: 1.22;
  letter-spacing: .015em;
  font-weight: var(--w-title); /* 900 */
  color: #fff; /* 内填充纯白，始终不变 */
  -webkit-text-stroke: 1px rgba(8, 16, 28, .52);
  paint-order: stroke fill;
  text-shadow: none;
}

.stack-item h2 {
  font-size: clamp(28px, 3.2vw, 48px);
  font-weight: var(--w-title);
}

/* ==================== 入场动效（2026-09-22 晚 · 按用户逐条规格重做） ====================
   ① center → M4 遮罩擦入（左→右 clip-path 揭开，像被"扫"出来）
   ② stack  → M2 逐字浮现（每字推迟 46ms；副标题整组再延 0.16s）
   ③ br     → M3 视差漂移（进场漂移 + 随滚动进度持续缓慢漂移，见 --br-p）
   ④ finale → M4 遮罩擦入
   实现纪律：animation fill-mode 一律 backwards —— 动画结束立即回到元素自然态
   （opacity:1、无 clip-path、无 filter、无 transform），静止态零重绘成本（Peakline 纪律）。
   逐字方案刻意不带 blur：每字一个 filter 会让整段文字逐帧重新栅格化（贵且没必要）。 */

/* ① 左下大标题：遮罩擦入 */
.story-step[data-pos="center"].is-active h2 {
  animation: wipe-in .92s var(--ease-cine) backwards;
}
.story-step[data-pos="center"].is-active .center-sub {
  animation: wipe-in .78s var(--ease-out) .24s backwards;
}

/* ② 顶部左对齐列表：逐字浮现（每个字一个 .ch，--i 为序号）
   ⚠️ .ch 自身不设 opacity:0 —— 父级 .stack-item 未激活时本就是 opacity:0/visibility:hidden，
   字的隐藏交给父级。若在这里写 opacity:0，animation(backwards) 结束后会回落到该自然态，
   所有字永久不可见（曾经的经典坑）。 */
.stack-item .ch {
  display: inline-block;
  white-space: pre;
}
.stack-item.is-active .ch {
  animation: char-rise .54s var(--ease-out) calc(var(--i, 0) * 46ms) backwards;
}
.stack-item.is-active p .ch {
  animation-delay: calc(.16s + var(--i, 0) * 38ms);
}
/* 标题左侧竖条随标题一起进（否则"条先到、字后到"会错拍） */
.stack-item.is-active h2::before {
  animation: fade-in .46s ease backwards;
}

/* ③ 右下两行：视差漂移（容器位移由 --br-p 驱动，进场脉冲挂在 h2 上，互不打架） */
.story-step[data-pos="br"].is-active h2 {
  animation: drift-in 1.05s var(--ease-cine) backwards;
}

/* ④ 收尾：遮罩擦入（容器只做 0.42s 淡入，擦入由 .final-inner 承担） */
.finale .final-inner {
  clip-path: inset(0 100% 0 0);
  transition: clip-path 1.1s var(--ease-cine) .08s;
}
.finale.is-visible .final-inner { clip-path: inset(0 0 0 0); }

@keyframes wipe-in {
  from { opacity: 0; clip-path: inset(0 100% 0 0); }
  to   { opacity: 1; clip-path: inset(0 0 0 0); }
}

@keyframes char-rise {
  from { opacity: 0; transform: translateY(.42em) rotate(3deg); }
  to   { opacity: 1; transform: none; }
}

@keyframes drift-in {
  from { opacity: 0; transform: translate3d(54px, 30px, 0); }
  to   { opacity: 1; transform: none; }
}

@keyframes blur-in {
  from { opacity: 0; filter: blur(14px); }
  to   { opacity: 1; filter: blur(0); }
}

@keyframes fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* —— ④ 收尾：画面正中 + 逐字波浪（用户已满意，原样保留） —— */
/* 注意：这里刻意不用 filter: blur()。blur + background-clip:text 会让每个字每帧
   重新栅格化渐变纹理，是整页最贵的一笔渲染开销（滚动时直接掉帧）。
   波浪只用 transform + opacity（纯合成属性），GPU 零重绘。 */
.finale .ch {
  display: inline-block;
  white-space: pre;
  opacity: 0;
  transform: translateY(.46em);
  transition: opacity .5s ease, transform .72s var(--ease-out);
}

/* 波浪：每字按序号递增延迟，形成从左到右的连续起伏 */
.finale .ch { transition-delay: calc(.12s + var(--i, 0) * 42ms); }

.finale.is-visible .ch {
  opacity: 1;
  transform: none;
}

/* 渐变字已移除（2026-09-22 晚）：实测 Blink 里 background-clip:text 的裁剪区
   包含描边几何，渐变会把 -webkit-text-stroke 整个盖掉 —— 描边完全不渲染，
   白字填充实色又融进收尾帧的亮部行星里。改回纯白实色 + 描边（= 用户选的方案 F），
   与全站其他标题的清晰度处理保持一致。 */

.finale {
  position: absolute;
  inset: 0;
  z-index: 18;
  display: flex;
  align-items: center;
  justify-content: center;   /* 画面正中 */
  text-align: center;
  padding: 0 var(--copy-edge);
  opacity: 0;
  transform: none;
  /* 容器只做短促淡入（0.42s）：进场观感交给 .final-inner 的遮罩擦入 */
  transition: opacity .42s ease;
  pointer-events: none;
}

/* 收尾页暗化底座已随整体"去暗化"一并移除（用户反馈 + PPT 零装饰规格）。
   逐字波浪、渐变字、按钮节奏全部保留。 */

.finale.is-visible {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}

.finale .brand,
.finale .start-button {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity .42s ease, transform .42s var(--ease-out);
}

.finale .brand { transition-delay: 0s; }
.finale .start-button { transition-delay: .5s; }

.finale.is-visible .brand,
.finale.is-visible .start-button { opacity: 1; transform: none; }

.final-inner {
  position: relative;
  padding: 0;
  /* 660px：保证 84px 字号的 8 字标题不折行（630px 需要，620px 会把末字挤下去成孤字） */
  max-width: min(78vw, 660px);
  isolation: isolate;
}

.brand {
  margin-bottom: 18px;
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .42em;
  text-indent: .42em; /* 补掉末字母的字距，视觉真正居中 */
  text-transform: uppercase;
  -webkit-text-stroke: .6px rgba(7, 15, 28, .6);
  paint-order: stroke fill;
  text-shadow: none;
}

.finale h1 {
  margin: 0;
  color: #fff;
  font-family: "Noto Sans SC", "PingFang SC", "Microsoft YaHei", sans-serif;
  font-size: clamp(40px, 5vw, 78px);
  font-weight: var(--w-finale); /* 900 */
  line-height: 1.08;
  letter-spacing: .015em;
  /* 收尾帧背景是全片最亮的一段（大行星占据正中），描边比其他位置略实一点 */
  -webkit-text-stroke: 2px rgba(7, 15, 28, .6);
  paint-order: stroke fill;
  text-shadow: none;
}

.start-button {
  position: relative;
  margin-top: 34px;
  /* 收尾帧背景极亮，原"半透明白胶囊 + 白字"完全隐形（2026-09-22 实测）。
     改为半透明白胶囊 + 深墨字（用户 2026-09-23 指定）：底色依旧半透明白、
     保留玻璃质感，深色字在亮底上有足够对比；万一背景压暗，胶囊本身仍是"白"的，
     对比不会反转。 */
  border: 1px solid rgba(255, 255, 255, .82);
  background: rgba(255, 255, 255, .55);
  color: #0a1a30;
  border-radius: 999px;
  padding: 15px 26px;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: .08em;
  cursor: pointer;
  text-shadow: none;
  box-shadow: none;
  transition: transform .28s ease, background .28s ease, color .28s ease, border-color .28s ease;
}

html.fx-rich .start-button {
  backdrop-filter: blur(16px) saturate(115%);
  -webkit-backdrop-filter: blur(16px) saturate(115%);
  background: rgba(255, 255, 255, .46);
}

.start-button:hover {
  background: rgba(255, 255, 255, .74);
  border-color: #fff;
}

.start-button:active { transform: translateY(0) scale(.97); }
.start-button:focus-visible { outline: 2px solid #fff; outline-offset: 5px; }

.playback-status {
  position: absolute;
  right: 24px;
  bottom: 22px;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 8px;
  opacity: 0;
  transform: translateY(5px);
  transition: opacity .25s ease, transform .25s ease;
  font-size: 9px;
  font-weight: 600;
  letter-spacing: .18em;
}

.playback-status.is-visible { opacity: .72; transform: translateY(0); }

.playback-status span {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--gold);
  box-shadow: 0 0 8px var(--gold);
}

.journey {
  position: relative;
  z-index: 0;
  height: 620vh;
  pointer-events: none;
}

.chapter { height: 200vh; }
.chapter-flight { height: 230vh; }
.chapter-arrival { height: 190vh; }

noscript {
  position: fixed;
  z-index: 100;
  inset: auto 20px 20px;
  padding: 14px 18px;
  border-radius: 12px;
  background: #fff;
  color: var(--ink);
}

@media (max-width: 700px) {
  :root { --copy-edge: 20px; }
  .nav { top: 18px; left: 18px; right: 18px; }
  .nav-cta { display: none; }

  /* ⚠️ 移动端必须按位置分别覆盖。旧写法 `.story-step { width: ...; left: ... }`
     会同时砸中 center / stack / br 三种定位，把正中与右下角一起拽到左边。 */
  .story-step h2 { font-size: clamp(28px, 7.4vw, 40px); }

  /* ① 左下大标题：与桌面同规格（左下对齐），底部抬高避开 SCROLL 提示 */
  .story-step[data-pos="center"] {
    left: var(--copy-edge);
    right: var(--copy-edge);
    bottom: calc(var(--copy-edge) * 4.6);
  }
  .story-step[data-pos="center"] h2 { max-width: 88vw; }
  .center-sub { font-size: clamp(14px, 3.6vw, 17px); }

  /* ② 顶部左对齐列表：撑宽到近满宽；斜下缩进在窄屏收敛 */
  .stack {
    top: clamp(84px, 12vh, 130px);
    left: var(--copy-edge);
    right: var(--copy-edge);
    width: auto;
    gap: clamp(12px, 3.4vw, 20px);
  }
  .stack-item h2 { font-size: clamp(26px, 6.6vw, 36px); }
  .stack-item h2::before { margin-right: 12px; }
  .stack-item p { margin-left: clamp(28px, 9vw, 80px); font-size: clamp(13px, 3.4vw, 16px); }

  /* ③ 右下角：贴右边，别继承左侧偏移 */
  .story-step[data-pos="br"] {
    left: auto;
    right: var(--copy-edge);
    bottom: calc(var(--copy-edge) * 2.4);
    max-width: 88vw;
  }

  /* ④ finale：正中 */
  .finale { justify-content: center; padding: 0 var(--copy-edge); }
  .final-inner { max-width: 88vw; }
  .finale h1 { font-size: clamp(34px, 10vw, 54px); }
  .brand { font-size: 11px; letter-spacing: .3em; text-indent: .3em; }
  .start-button { padding: 14px 22px; font-size: 13px; margin-top: 26px; }
  .scroll-cue { left: var(--copy-edge); bottom: 20px; }
  .scroll-cue::before { width: 24px; }
}

@media (max-width: 720px) {
  .playback-status { right: 18px; bottom: 16px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
  }
  .finale .ch { transition: none !important; transition-delay: 0s !important; }
  /* 遮罩擦入属"位移/揭示类"动画，减动效用户直接给终态 */
  .finale .final-inner { transition: none !important; clip-path: none !important; }
  .story-step .ch { animation-duration: .01ms !important; animation-delay: 0s !important; }
  .story-step.is-active h2,
  .story-step.is-active p,
  .story-step.is-active .center-sub,
  .finale.is-visible h1 { animation: none !important; clip-path: none !important; filter: none !important; }
}

.nav-cta.is-visible { opacity: 1; visibility: visible; pointer-events: auto; transform: none; }

/* ==================== v7.19 · 四屏文字规格 ==================== */
:root {
  --gold: #ffc46b;
  --shadow-c: 13, 18, 46;
}

.nav {
  top: 6.67vh;
  left: 6.25vw;
  right: 3.6vw;
}

.logo {
  gap: 14px;
  font: 500 clamp(13px, 1.56vw, 30px)/1 "Noto Sans SC", sans-serif;
  letter-spacing: .27em;
}

.logo-dot {
  width: clamp(8px, .65vw, 13px);
  height: clamp(8px, .65vw, 13px);
}

.nav-cta {
  padding: .8em 1.6em;
  border-color: rgba(255,255,255,.75);
  background: rgba(255,255,255,.15);
  font: 500 clamp(11px, 1.04vw, 20px)/1 "Noto Sans SC", sans-serif;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

.scroll-cue {
  left: 50%;
  bottom: 3.2vh;
  transform: translateX(-50%);
  font: 500 clamp(11px, 1.46vw, 28px)/1 "Noto Sans SC", sans-serif;
  letter-spacing: .29em;
  color: rgba(255,255,255,.75);
  white-space: nowrap;
}

.scroll-cue::before { display: none; }

.story-step[data-pos="center"] {
  left: 6.35vw;
  right: auto;
  bottom: 3.6vh;
}

.story-step[data-pos="center"]::before {
  content: "";
  position: fixed;
  inset: 50% 0 0;
  z-index: -1;
  background: linear-gradient(to bottom, rgba(11,16,38,0), rgba(11,16,38,.62));
  pointer-events: none;
}

.j1-eyebrow,
.j2-eyebrow {
  margin: 0 0 .5em;
  font: 500 clamp(13px, 1.56vw, 30px)/1.2 "Noto Sans SC", sans-serif;
  letter-spacing: .13em;
  color: var(--gold);
  text-shadow: 0 2px 10px rgba(var(--shadow-c), .55);
}

.story-step[data-pos="center"] h2 {
  max-width: none;
  margin: 0 0 .35em;
  font: 700 clamp(48px, 5.83vw, 112px)/1.1 "Noto Serif SC", serif;
  letter-spacing: .04em;
  color: #fff;
  -webkit-text-stroke: 0;
  text-shadow: 0 2px 10px rgba(var(--shadow-c), .55);
}

.center-sub {
  margin: 0;
  font: 500 clamp(14px, 1.56vw, 30px)/1.2 "Noto Sans SC", sans-serif;
  letter-spacing: 0;
  color: #fff;
  -webkit-text-stroke: 0;
  text-shadow: 0 2px 8px rgba(var(--shadow-c), .5);
}

.stack {
  top: auto;
  left: 6.6vw;
  right: 6.6vw;
  bottom: 3.2vh;
  width: auto;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: 7vw;
  row-gap: 3.2vh;
}

.j2-eyebrow {
  grid-column: 1 / -1;
  margin: 0 0 .2em;
  letter-spacing: .2em;
}

.stack-item,
.stack-item.is-active {
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: clamp(18px, 1.6em, 42px);
  align-items: start;
}

.stack-index {
  grid-row: span 2;
  font: 700 clamp(16px, 1.98vw, 38px)/1.2 "Noto Serif SC", serif;
  color: var(--gold);
  text-shadow: 0 2px 10px rgba(var(--shadow-c), .55);
}

.stack-item h2::before { display: none; }

.stack-item h2 {
  margin: 0;
  font: 700 clamp(22px, 2.6vw, 50px)/1.2 "Noto Serif SC", serif;
  letter-spacing: 0;
  color: #fff;
  -webkit-text-stroke: 0;
  text-shadow: 0 2px 8px rgba(var(--shadow-c), .5);
}

.stack-item p {
  margin: .4em 0 0;
  font: 300 clamp(13px, 1.56vw, 30px)/1.3 "Noto Sans SC", sans-serif;
  letter-spacing: 0;
  color: #fff;
  -webkit-text-stroke: 0;
  text-shadow: 0 2px 8px rgba(var(--shadow-c), .5);
}

.story-step[data-pos="br"] {
  right: 3.8vw;
  bottom: 7.7vh;
  max-width: none;
}

.story-step[data-pos="br"] h2 {
  font: 700 clamp(36px, 4.58vw, 88px)/1.42 "Noto Serif SC", serif;
  letter-spacing: .07em;
  color: #fff;
  -webkit-text-stroke: 0;
  text-shadow: 0 3px 14px rgba(var(--shadow-c), .4);
}

.finale::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background: rgba(11,16,38,.32);
}

.final-inner { z-index: 1; max-width: none; }

.brand {
  margin-bottom: .6em;
  font: 700 clamp(16px, 2.08vw, 40px)/1.2 "Noto Sans SC", sans-serif;
  letter-spacing: .4em;
  text-indent: .4em;
  color: var(--gold);
  -webkit-text-stroke: 0;
}

.finale h1 {
  margin: 0 0 1.6em;
  font: 700 clamp(48px, 6.04vw, 116px)/1.1 "Noto Serif SC", serif;
  letter-spacing: .05em;
  color: #fff;
  white-space: nowrap;
  -webkit-text-stroke: 0;
  text-shadow: 0 3px 14px rgba(var(--shadow-c), .4);
}

.start-button {
  padding: .87em 1.9em;
  border-color: rgba(255,255,255,.75);
  background: rgba(255,255,255,.15);
  font: 500 clamp(14px, 1.56vw, 30px)/1 "Noto Sans SC", sans-serif;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

@media (max-width: 760px) {
  .nav { top: 24px; left: 24px; right: 24px; }
  .story-step[data-pos="center"] { left: 24px; right: 24px; bottom: 72px; }
  .story-step[data-pos="center"] h2 { font-size: clamp(42px, 12vw, 64px); }
  .stack { left: 24px; right: 24px; bottom: 48px; grid-template-columns: 1fr; row-gap: 14px; }
  .j2-eyebrow { margin-bottom: 4px; }
  .stack-item h2 { font-size: clamp(22px, 7vw, 34px); }
  .story-step[data-pos="br"] { right: 24px; left: 24px; bottom: 64px; }
  .story-step[data-pos="br"] h2 { font-size: clamp(34px, 10vw, 54px); }
  .finale h1 { white-space: normal; font-size: clamp(44px, 13vw, 70px); }
}

/* ==================== v7.20 · 文字零动画切屏 ====================
   用户真机上逐字 span、clip-path 和持续视差会让文字自身掉帧。四屏现在只在
   对应画面节点进行一次合成层显隐，不做逐字、模糊、遮罩或滚动跟随位移。 */
.story-step,
.stack,
.stack-item,
.finale,
.finale .brand,
.finale .start-button,
.nav-cta {
  transition: none !important;
}

.story-step[data-pos="center"].is-active h2,
.story-step[data-pos="center"].is-active .center-sub,
.stack-item.is-active .ch,
.stack-item.is-active h2::before,
.story-step[data-pos="br"].is-active h2 {
  animation: none !important;
}

.story-step[data-pos="br"] {
  transform: none !important;
}

.finale .final-inner,
.finale.is-visible .final-inner {
  clip-path: none !important;
  transition: none !important;
}

/* ==================== v7.21 · 恢复原导航与终屏 ==================== */
.nav {
  top: 26px;
  left: 32px;
  right: 32px;
}

.logo {
  gap: 10px;
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  line-height: normal;
  letter-spacing: .08em;
}

.logo-dot {
  width: 9px;
  height: 9px;
}

.nav-cta,
.start-button {
  border: 1px solid rgba(255,255,255,.48);
  background: rgba(255,255,255,.14);
  color: #fff;
  border-radius: 999px;
  padding: 9px 15px;
  font-family: "Noto Sans SC", "PingFang SC", "Microsoft YaHei", sans-serif;
  font-size: 12px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: .08em;
  text-shadow: none;
  box-shadow: none;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  inline-size: 84px;
  block-size: 32px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.nav-cta:hover,
.start-button:hover {
  background: rgba(255,255,255,.28);
  border-color: rgba(255,255,255,.75);
  color: #fff;
}

.finale::before { display: none; }

.final-inner {
  max-width: min(78vw, 660px);
}

.brand {
  margin-bottom: 18px;
  color: #fff;
  font-family: "Noto Sans SC", "PingFang SC", "Microsoft YaHei", sans-serif;
  font-size: 12px;
  font-weight: 700;
  line-height: normal;
  letter-spacing: .42em;
  text-indent: .42em;
  -webkit-text-stroke: .6px rgba(7,15,28,.6);
}

.finale h1 {
  margin: 0;
  color: #fff;
  font-family: "Noto Sans SC", "PingFang SC", "Microsoft YaHei", sans-serif;
  font-size: clamp(40px, 5vw, 78px);
  font-weight: var(--w-finale);
  line-height: 1.08;
  letter-spacing: .015em;
  white-space: normal;
  -webkit-text-stroke: 2px rgba(7,15,28,.6);
  text-shadow: none;
}

.start-button {
  margin-top: 34px;
  cursor: pointer;
}

html.fx-rich .nav-cta,
html.fx-rich .start-button {
  background: rgba(255,255,255,.14);
  color: #fff;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

/* ==================== v7.23 · 四屏节拍与轻量文字动效 ====================
   所有动画都只作用于完整文本层，不拆逐字 DOM；主视频仍保持独立合成层。 */
@keyframes jm-mask-in {
  from { clip-path: inset(0 100% 0 0); }
  to   { clip-path: inset(0 0 0 0); }
}

@keyframes jm-type-reveal {
  from { clip-path: inset(0 100% 0 0); opacity: .55; }
  to   { clip-path: inset(0 0 0 0); opacity: 1; }
}

@keyframes jm-drift-in {
  from { opacity: 0; transform: translate3d(-24px, 18px, 0); }
  to   { opacity: 1; transform: translate3d(0, 0, 0); }
}

.story-step[data-pos="center"].is-active .j1-eyebrow,
.story-step[data-pos="center"].is-active h2,
.story-step[data-pos="center"].is-active .center-sub {
  animation: jm-mask-in .9s var(--ease-cine) backwards !important;
}

.story-step[data-pos="center"].is-active h2 { animation-delay: .06s !important; }
.story-step[data-pos="center"].is-active .center-sub { animation-delay: .12s !important; }

.stack.is-shown {
  animation: jm-type-reveal .9s steps(12, end) backwards !important;
}

.story-step[data-pos="br"] {
  transform: translate3d(calc(var(--br-p, 0) * 16px), calc(var(--br-p, 0) * -26px), 0) !important;
}

.story-step[data-pos="br"].is-active h2 {
  animation: jm-drift-in 1s var(--ease-cine) backwards !important;
}

.finale::before {
  display: none;
}

.finale .final-inner {
  max-width: none;
  clip-path: inset(0 100% 0 0) !important;
}

.finale.is-visible .final-inner {
  animation: jm-mask-in 1s var(--ease-cine) backwards !important;
  /* v8.6：负 inset 收尾——Playfair 的 J 字钩伸出字框（下伸+左凸），
     inset(0) 会把它裁掉；放宽到负值让字形完整呼吸
     v8.8：em 是按 .final-inner 的 16px 算的，-0.35em 只有 ~6px，
     根本盖不住 157px+ 字号下 J 钩伸出的 20–40px —— 改按视口宽给足余量 */
  clip-path: inset(-4vw -3vw -5vw -3vw) !important;
}

.brand {
  margin-bottom: .6em;
  color: var(--gold);
  font: 700 clamp(16px, 2.08vw, 40px)/1.2 "Noto Sans SC", sans-serif;
  letter-spacing: .4em;
  text-indent: .4em;
  -webkit-text-stroke: 0;
}

.finale h1 {
  margin: 0;
  color: #fff;
  font: 700 clamp(48px, 6.04vw, 116px)/1.1 "Noto Serif SC", serif;
  letter-spacing: .05em;
  white-space: nowrap;
  -webkit-text-stroke: 0;
  text-shadow: 0 3px 14px rgba(7,15,28,.4);
}

.start-button {
  margin-top: clamp(34px, 5vh, 58px);
}

@media (max-width: 760px) {
  .finale h1 { white-space: normal; font-size: clamp(44px, 13vw, 70px); }
}

@media (prefers-reduced-motion: reduce) {
  .story-step[data-pos="center"].is-active > *,
  .stack.is-shown,
  .story-step[data-pos="br"].is-active h2,
  .finale.is-visible .final-inner {
    animation: none !important;
    clip-path: none !important;
    transform: none !important;
  }
}

/* ==================== v7.25 · UHD 清晰度与文字节奏 ==================== */
.story-video-live {
  image-rendering: auto;
}

/* 第一屏在起飞后快速收掉，而不是瞬间断字。 */
.story-step[data-pos="center"] {
  transition: opacity .22s ease, visibility 0s linear .22s !important;
}

.story-step[data-pos="center"].is-active {
  transition: opacity .22s ease, visibility 0s linear 0s !important;
}

/* v7.23 的金色字号与字距保持不变；只把当时由整屏暗层提供的对比度局部还给文字，
   不再压暗或软化整张 UHD 背景。 */
.finale .brand {
  color: #ffd58a;
  text-shadow: 0 2px 12px rgba(7,15,28,.82);
}

/* “开始体验”沿用 v7.23 玻璃按钮质感；尺寸与“关于我们”由同一规则锁定。 */
.nav-cta,
.start-button {
  inline-size: 84px;
  block-size: 32px;
  font-size: 12px;
  border-color: rgba(255,255,255,.76);
  background: rgba(112,108,154,.38);
  color: #fff;
  backdrop-filter: blur(14px) saturate(120%);
  -webkit-backdrop-filter: blur(14px) saturate(120%);
}

/* ==================== v7.27 · 终屏浅色玻璃按钮 ==================== */
.nav-cta,
.start-button,
html.fx-rich .nav-cta,
html.fx-rich .start-button {
  background: rgba(238,238,238,.70);
  border-color: rgba(255,255,255,.88);
  color: #333;
  font-weight: 700;
  backdrop-filter: blur(14px) saturate(110%);
  -webkit-backdrop-filter: blur(14px) saturate(110%);
}

.nav-cta:hover,
.start-button:hover,
html.fx-rich .nav-cta:hover,
html.fx-rich .start-button:hover {
  background: rgba(246,246,246,.82);
  border-color: #fff;
  color: #222;
}

/* ==================== v7.28 · 灰白 40% + 白色高对比字 ==================== */
.nav-cta,
.start-button,
html.fx-rich .nav-cta,
html.fx-rich .start-button {
  background: rgba(238,238,238,.40);
  border-color: rgba(255,255,255,.72);
  color: #fff;
  font-weight: 700;
  text-shadow: 0 1px 3px rgba(20,24,34,.58);
  backdrop-filter: blur(14px) saturate(110%);
  -webkit-backdrop-filter: blur(14px) saturate(110%);
}

.nav-cta:hover,
.start-button:hover,
html.fx-rich .nav-cta:hover,
html.fx-rich .start-button:hover {
  background: rgba(246,246,246,.52);
  border-color: rgba(255,255,255,.90);
  color: #fff;
}

/* ==================== v7.29 · 主次按钮透明度层级 ==================== */
.nav-cta,
html.fx-rich .nav-cta {
  background: rgba(238,238,238,.30);
}

.start-button,
html.fx-rich .start-button {
  background: rgba(238,238,238,.50);
}

.nav-cta:hover,
html.fx-rich .nav-cta:hover {
  background: rgba(246,246,246,.42);
}

.start-button:hover,
html.fx-rich .start-button:hover {
  background: rgba(246,246,246,.62);
}

/* ==================== v7.30 · 终屏主按钮微放大 ==================== */
.nav-cta,
html.fx-rich .nav-cta {
  background: rgba(238,238,238,.20);
}

.start-button,
html.fx-rich .start-button {
  inline-size: 92px;
  block-size: 36px;
  font-size: 13px;
  background: rgba(238,238,238,.45);
}

.nav-cta:hover,
html.fx-rich .nav-cta:hover {
  background: rgba(246,246,246,.32);
}

.start-button:hover,
html.fx-rich .start-button:hover {
  background: rgba(246,246,246,.57);
}

/* ==================== v7.40 · 五屏文字重排（2026-09-28） ====================
   原四位置体系（center 左下大标题 / stack 底部 2×2 四句 / br 右下两行）改为五屏：
   每屏一句、各自定位（用户九宫格规格）。字体/字号/动效沿用各自承接的原位置样式：
   s1 ← 原 center 大标题（Noto Serif 5.83vw + jm-mask-in 遮罩擦入），页面左下角
   s2 ← 原 stack 句（Noto Serif 2.6vw + jm-type-reveal 打字浮现），右侧中间（第六格，v8.5 定稿）
   s3 ← 同上，左侧中间（第四格，v8.5 定稿）
   s4 ← 原 br 句（Noto Serif 4.58vw + jm-drift-in 漂移进场），右侧偏下（六格与九格之间）
   finale 文案改「JobMate」，居中（第五格），样式与动效不变。 */
.story-step[data-pos="s1"] {
  position: absolute;
  left: 6.35vw;
  right: auto;
  bottom: 3.6vh;
}

.story-step[data-pos="s1"] h2 {
  margin: 0;
  font: 700 clamp(48px, 5.83vw, 112px)/1.1 "Noto Serif SC", serif;
  letter-spacing: .04em;
  color: #fff;
  -webkit-text-stroke: 0;
  text-shadow: 0 2px 10px rgba(var(--shadow-c), .55);
}

.story-step[data-pos="s1"].is-active h2 {
  animation: jm-mask-in .9s var(--ease-cine) backwards !important;
}

/* 九宫格第六格：右侧垂直居中，右对齐（v8.5 定稿：s2 回到第六格） */
.story-step[data-pos="s2"] {
  position: absolute;
  right: 6.6vw;
  top: 50%;
  transform: translateY(-50%);
  text-align: right;
}

/* 九宫格第四格：左侧垂直居中，左对齐（v8.5 定稿：s3 回到第四格） */
.story-step[data-pos="s3"] {
  position: absolute;
  left: 6.6vw;
  top: 50%;
  transform: translateY(-50%);
}

.story-step[data-pos="s2"] h2,
.story-step[data-pos="s3"] h2 {
  margin: 0;
  font: 700 clamp(22px, 2.6vw, 50px)/1.2 "Noto Serif SC", serif;
  letter-spacing: 0;
  color: #fff;
  -webkit-text-stroke: 0;
  text-shadow: 0 2px 8px rgba(var(--shadow-c), .5);
}

.story-step[data-pos="s2"].is-active h2,
.story-step[data-pos="s3"].is-active h2 {
  animation: jm-type-reveal .9s steps(12, end) backwards !important;
}

/* 九宫格第六格与第九格之间：右侧偏下，右对齐 */
.story-step[data-pos="s4"] {
  position: absolute;
  right: 3.8vw;
  bottom: 26vh;
  text-align: right;
}

.story-step[data-pos="s4"] h2 {
  margin: 0;
  font: 700 clamp(36px, 4.58vw, 88px)/1.42 "Noto Serif SC", serif;
  letter-spacing: .07em;
  color: #fff;
  -webkit-text-stroke: 0;
  text-shadow: 0 3px 14px rgba(var(--shadow-c), .4);
}

.story-step[data-pos="s4"].is-active h2 {
  animation: jm-drift-in 1s var(--ease-cine) backwards !important;
}

@media (max-width: 760px) {
  .story-step[data-pos="s1"] { left: 24px; right: 24px; bottom: 72px; }
  .story-step[data-pos="s2"] { right: 24px; }
  .story-step[data-pos="s3"] { left: 24px; }
  .story-step[data-pos="s4"] { right: 24px; bottom: 20vh; }
}

@media (prefers-reduced-motion: reduce) {
  .story-step[data-pos="s1"].is-active h2,
  .story-step[data-pos="s2"].is-active h2,
  .story-step[data-pos="s3"].is-active h2,
  .story-step[data-pos="s4"].is-active h2 {
    animation: none !important;
    clip-path: none !important;
    transform: none !important;
  }
}

/* ==================== v7.41 · 字体规格统一（2026-09-28） ====================
   s1–s4 统一一套排版（用户规格）：Noto Serif SC Bold、字号统一
   clamp(40px, 4.6vw, 90px)（1440 ≈ 66px）、字距 .04em、白字、
   1px 描边（中文 66px 用 1.5px 会糊）、与 finale 同档投影。位置/动效不动。
   finale（第五屏）换 Playfair Display 700（自托管 woff2，不走 Google Fonts，
   国内加载不稳），clamp(48px, 10.9vw, 210px)（1440 ≈ 157px）、字距 .02em +
   text-indent .02em（补掉末字母字距，否则视觉不居中）、1.5px 描边 + 26px 投影，
   画面正中。 */
@font-face {
  font-family: "Playfair Display";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("assets/PlayfairDisplay-Bold-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

.story-step[data-pos="s1"] h2,
.story-step[data-pos="s2"] h2,
.story-step[data-pos="s3"] h2,
.story-step[data-pos="s4"] h2 {
  font-family: "Noto Serif SC", "Songti SC", "SimSun", serif;
  font-weight: 700;
  font-size: clamp(40px, 4.6vw, 90px);
  line-height: 1.2;
  letter-spacing: .04em;
  color: #fff;
  -webkit-text-stroke: 1px rgba(7, 15, 28, .5);
  paint-order: stroke fill;
  text-shadow: 0 4px 26px rgba(0, 0, 0, .35);
}

/* v8.4 · s1 加粗：Serif 子集只有 700，请求 900 由浏览器合成加粗
   v8.6 · 叠同色白描边再增重（等效"1500 级"），黑幕上对比更强 */
.story-step[data-pos="s1"] h2 {
  font-weight: 900;
  -webkit-text-stroke: 1.6px #ffffff;
  paint-order: stroke fill;
}

/* v8.6 · s1 黑幕：左下角局部暗化（电影感压光，沿用原版 ::before 手法） */
.story-step[data-pos="s1"] {
  isolation: isolate; /* 让 ::before 的 z-index:-1 只压在本组内，不跑到画布后面 */
}
.story-step[data-pos="s1"]::before {
  content: "";
  position: absolute;
  z-index: -1;
  left: -10%;
  right: -46%;
  top: -80%;
  bottom: -50%;
  background: radial-gradient(
    ellipse 62% 58% at 22% 68%,
    rgba(3, 21, 44, 0.6),
    rgba(3, 21, 44, 0.26) 55%,
    rgba(3, 21, 44, 0) 80%
  );
  pointer-events: none;
}

/* v8.6 · s2 字号减半：1440 ≈ 23px */
.story-step[data-pos="s2"] h2 {
  font-size: clamp(14px, 1.6vw, 30px);
}

/* 防折行坑：1920 视口下 10.9vw ≈ 209px 的 JobMate，660px 容器必折行 */
.finale .final-inner {
  max-width: 88vw;
}

.finale h1 {
  margin: 0;
  color: #fff;
  font-family: "Playfair Display", "Noto Serif SC", serif;
  font-weight: 700;
  font-size: clamp(48px, 10.9vw, 210px);
  line-height: 1.1;
  letter-spacing: .02em;
  text-indent: .02em;
  white-space: nowrap;
  /* v8.4：去掉深色描边；改用同色白描边做伪加粗（Serif Bold 之上再增重）
     v8.6：去掉深色投影——大字号下晕开一片黑影影响质感 */
  -webkit-text-stroke: 1.5px #ffffff;
  paint-order: stroke fill;
  text-shadow: none;
}

/* ==================== v8.7 · 字体重做：真 Black 字重（2026-09-28） ====================
   她拍板「字体不好看」。病因：Serif 子集只有 700，v8.4/v8.6 用 font-weight:900
   让浏览器伪加粗 + 1.6px 白描边充重量 —— 合成加粗把衬线笔画糊成一团（截图可证）。
   解法：自托管真字重 NotoSerifSC-Black.subset.woff2（可变字体 wght=900 实例化，
   首页五屏文案 115 字子集，36KB），撤掉全部描边与伪加粗，
   改双层软投影保亮背景可读性；字号/位置/动效一律不动。 */
.story-step[data-pos="s1"] h2,
.story-step[data-pos="s2"] h2,
.story-step[data-pos="s3"] h2,
.story-step[data-pos="s4"] h2 {
  font-weight: 900;
  letter-spacing: .05em;
  -webkit-text-stroke: 0;
  paint-order: normal;
}

/* v8.9：s1 保留双层投影；s2–s4 阴影砍掉 44px 大晕影层（发灰显脏），
   只留单层近影轻托对比 */
.story-step[data-pos="s1"] h2 {
  text-shadow:
    0 2px 10px rgba(7, 15, 28, .38),
    0 12px 44px rgba(7, 15, 28, .26);
}

.story-step[data-pos="s2"] h2,
.story-step[data-pos="s3"] h2,
.story-step[data-pos="s4"] h2 {
  text-shadow: 0 2px 8px rgba(7, 15, 28, .18);
}

/* 真 Black 自带分量，v8.6 的左下压光暗化层撤掉，画面回到亮调 */
.story-step[data-pos="s1"]::before {
  content: none;
}

/* finale 同步去伪加粗：Playfair 本身就是真 700，白描边只在字缘留脏边 */
.finale h1 {
  -webkit-text-stroke: 0;
  paint-order: normal;
  text-shadow:
    0 2px 14px rgba(7, 15, 28, .32),
    0 14px 60px rgba(7, 15, 28, .22);
}

/* ==================== v9.1 · s1 副题 + finale 眉题（2026-09-29） ====================
   她的定稿规格：
   ① s1 不要两行、不要眉题 —— 文案单行「下一份工作，会在哪里？」，下面一行小字「从 JobMate 开始」（参考老版三层结构的下半部分）；
   ② 金色眉题移到最后一屏 finale，压在 JobMate 上方（复用原 s1 眉题样式，居中）。
   保留的对比度修正：h2 1px 深色描边 + 文字块背板（亮花丛上必须的轮廓分离）。 */
.story-step[data-pos="s1"] h2 {
  line-height: 1.2;
  -webkit-text-stroke: 1px rgba(7, 15, 28, .42);
  paint-order: stroke fill;
}

/* s1 副题：老版「从 JobMate 开始」的位置与轻盈感（真 Bold，不假粗） */
.story-step[data-pos="s1"] .s1-sub {
  margin: 1.5vh 0 0 0.16em;
  font-family: "Noto Serif SC", "Songti SC", "SimSun", serif;
  font-weight: 700;
  font-size: clamp(16px, 1.5vw, 28px);
  line-height: 1.35;
  letter-spacing: .12em;
  color: rgba(255, 255, 255, .95);
  text-shadow:
    0 1px 3px rgba(7, 15, 28, .6),
    0 2px 12px rgba(7, 15, 28, .38);
  animation: jm-sub-in .8s .5s var(--ease-cine) backwards;
}

/* 文字块背板：跟随 s1 位置（v8.6 手法），只压左下一小块，星球不受影响 */
.story-step[data-pos="s1"]::before {
  content: "";
  position: absolute;
  z-index: -1;
  left: -18%;
  right: -30%;
  top: -46%;
  bottom: -26%;
  background: radial-gradient(
    ellipse 58% 56% at 26% 56%,
    rgba(3, 21, 44, .62) 0%,
    rgba(3, 21, 44, .28) 60%,
    rgba(3, 21, 44, 0) 84%
  );
  pointer-events: none;
}

/* finale 金色眉题：照老版 .brand 规格 —— 细 sans 金字、无描边、无暗晕、大字距。
   中文走系统 sans 栈（苹方/雅黑），不发字体、无掉字风险。 */
.finale .final-eyebrow {
  position: relative;
  margin: 0 0 2.8vh 0;
  font-family: "PingFang SC", "Microsoft YaHei", "Noto Sans SC", sans-serif;
  font-weight: 700;
  font-size: clamp(16px, 2.05vw, 38px);
  line-height: 1.2;
  letter-spacing: .4em;
  text-indent: .4em; /* 补掉末字字距，视觉真正居中 */
  color: #ffdd9a;
  -webkit-text-stroke: 0;
  paint-order: normal;
  /* 大模糊 + 低不透明度的柔影：观感只是「字更实」，不会读成阴影/暗晕 */
  text-shadow:
    0 1px 2px rgba(45, 17, 8, .55),
    0 2px 12px rgba(45, 17, 8, .38);
  animation: jm-sub-in .8s .45s var(--ease-cine) backwards;
}

@keyframes jm-sub-in {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}

@media (max-width: 760px) {
  .story-step[data-pos="s1"] h2 { line-height: 1.22; }
  .story-step[data-pos="s1"] .s1-sub,
  .finale .final-eyebrow { font-size: 13px; letter-spacing: .26em; }
  .finale .final-eyebrow { text-indent: .26em; margin-bottom: 1.8vh; }
  .story-step[data-pos="s1"]::before { top: -38%; bottom: -20%; }
}

/* 整组上移对齐老版构图：老版这组文字中心约在画面 40% 高度，
   上移后眉题正好落进星球上部较暗的紫红过渡带（她的参考图同款位置），
   金字不需要任何描边/暗晕也能读清 */
.finale .final-inner {
  transform: translateY(-10vh);
}

@media (prefers-reduced-motion: reduce) {
  .story-step[data-pos="s1"] .s1-sub,
  .finale .final-eyebrow { animation: none !important; }
}

/* v9.2 · 恢复老版 finale 全屏轻压暗（2026-09-29）
   历史 .finale::before（rgba(11,16,38,.32)）在 v8.x 被 display:none 关掉，
   导致金色眉题压在星球亮纹理上读不清。她拍板恢复老版做法：
   整屏统一深蓝压暗 = 电影收尾调色，无局部补丁感。 */
.finale::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  display: block;
  background: rgba(11, 16, 38, .32);
}
