/* ============================================================
   天脑 Tino · H5 互动科幻大片
   主色：深空蓝 #0A1A3A / 星云紫 #6C3CE0 / 青蓝 #00C8D7 / 星光金 #F5C542
   ============================================================ */

:root{
  --deep:#0A1A3A;
  --deep-2:#061029;
  --nebula:#6C3CE0;
  --cyan:#00C8D7;
  --gold:#F5C542;
  --ink:#EAF2FF;
  --ink-dim:#9FB3D9;
  --vh-w: 62vw;                     /* 主角改为全息大脑 → 正方形 */
  --vh-h: 62vw;
  --hud-b: calc(76px + var(--safe-b));
  --safe-t: env(safe-area-inset-top, 0px);
  --safe-b: env(safe-area-inset-bottom, 0px);
  --ease-out: cubic-bezier(.16,.84,.34,1);
}

*,*::before,*::after{ box-sizing:border-box; }

html,body{
  margin:0; padding:0;
  background:var(--deep-2);
  color:var(--ink);
  font-family:-apple-system,BlinkMacSystemFont,"PingFang SC","HarmonyOS Sans SC","Source Han Sans SC","Noto Sans SC","Microsoft YaHei",sans-serif;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
  overflow-x:hidden;
  -webkit-tap-highlight-color:transparent;
}
body{ overscroll-behavior-y:none; }
body.loading{ overflow:hidden; }

img,canvas{ display:block; max-width:100%; }
button{ font:inherit; color:inherit; background:none; border:0; cursor:pointer; }
a{ color:inherit; text-decoration:none; }
/* ★ 必须放在 display 规则之后：否则 .qr-page/.overlay-tip 的 display:flex 会盖掉 hidden */
[hidden]{ display:none !important; }

/* 滚动容器：逐幕推进 */
#stage{
  position:relative; z-index:5;
  scroll-snap-type:y proximity;
  overflow-y:auto;
  height:100vh; height:100dvh;
  -webkit-overflow-scrolling:touch;
}
.act{
  position:relative;
  min-height:100vh; min-height:100dvh;
  scroll-snap-align:start;
  display:flex; align-items:center; justify-content:center;
  padding:calc(64px + var(--safe-t)) 22px calc(72px + var(--safe-b));
  overflow:hidden;
}
.act-inner{ position:relative; width:100%; max-width:520px; margin:0 auto; }

/* ═════════ v8 · 滚动驱动电影（真 scrub） ═════════
   .act-long：section 本身拉长（4 屏），内部一屏 sticky 钉住 ——
   不依赖 ScrollTrigger 的 pin，纯 CSS sticky 更稳，也不会和 scroll-snap 打架。
   ★ 注意：sticky 的祖先链上不能有 overflow:hidden，否则会变成滚动容器、sticky 失效，
     所以 .act-long 必须 overflow:visible，把裁剪交给内层 .act-stick。 */
.act-long{
  min-height:400vh; min-height:400dvh;
  scroll-snap-align:none;          /* 长幕内部不断点，交给相邻幕的 snap 收尾 */
  display:block; padding:0;
  overflow:visible;                /* ★ 关键：给 .act-stick 让出 sticky 条件 */
}
.act-long .act-stick{
  position:sticky; top:0;
  height:100vh; height:100dvh;
  overflow:hidden;
  display:flex; align-items:center; justify-content:center;
  padding:calc(64px + var(--safe-t)) 22px calc(72px + var(--safe-b));
}

/* ── 长按交互（第四幕「按住召唤下载」）── */
.hold-gate{
  position:absolute; left:50%; bottom:calc(96px + var(--safe-b));
  transform:translateX(-50%);
  display:flex; flex-direction:column; align-items:center; gap:10px;
  padding:14px 22px 16px;
  border-radius:18px;
  background:rgba(6,12,20,.52);
  border:1px solid rgba(140,225,240,.24);
  backdrop-filter:blur(8px); -webkit-backdrop-filter:blur(8px);
  z-index:12; opacity:0; pointer-events:none;
}
/* .show = 「门」准备好了（acts.js 挂上长按门时加）—— 必须能点、必须看得见，
   否则鸡生蛋问题：.on 只在按下后才生效，而 pointer-events:none 让手指永远按不到它。
   .on = 正在按住（hold.js 加），用来做高亮/放大。 */
.hold-gate.show{ opacity:1; pointer-events:auto; }
.hold-gate.on{ opacity:1; pointer-events:auto; }
.hold-gate.on{ transform:translateX(-50%) scale(1.06); }
.hold-ring{ position:relative; width:54px; height:54px; }
.hold-ring svg{ width:54px; height:54px; transform:rotate(-90deg); }
.hold-ring circle{ fill:none; stroke-width:3.5; }
.hold-ring .bg{ stroke:rgba(150,220,235,.20); }
.hold-ring .fg{
  stroke:#5fe3f0; stroke-linecap:round;
  stroke-dasharray:157; stroke-dashoffset:157;   /* 2πr = 2π×25 ≈ 157 */
  transition:stroke-dashoffset .06s linear;
}
.hold-ring .core{
  position:absolute; inset:16px; border-radius:50%;
  background:rgba(95,227,240,.16);
  box-shadow:0 0 0 0 rgba(95,227,240,0);
}
.hold-txt{ font-size:13px; letter-spacing:.06em; color:rgba(226,244,248,.9); }
.hold-txt b{ color:#5fe3f0; font-weight:600; }
.hold-gate.armed .hold-ring .core{ box-shadow:0 0 22px 6px rgba(95,227,240,.55); }

/* ══════════ v9 · 第一幕「长按唤醒天脑」══════════
   .a1-wake 覆盖整屏，不是一个小方块 —— 用户的心智是「长按屏幕」，
   如果只有底部那块 UI 能按到，一半人根本按不中。
   但 **必须** 留 touch-action:pan-y：手指一滑 = 放弃长按继续滚，
   全屏拦截触摸会把不会按的人直接堵死在门口。 */
.hold-gate.a1-wake{
  inset:0; left:0; bottom:0; right:0; top:0;
  transform:none; gap:0;
  padding:0; border:0; border-radius:0;
  background:
    radial-gradient(120% 70% at 50% 42%, rgba(2,6,16,.30) 0%, rgba(1,3,10,.80) 72%),
    rgba(3,7,16,.34);
  backdrop-filter:none; -webkit-backdrop-filter:none;
  z-index:11;
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  cursor:pointer;
  touch-action:pan-y;                 /* ★ 纵向滚动必须还能用，见上 */
}
.hold-gate.a1-wake.show{ opacity:1; pointer-events:auto; animation:wake-breathe 2.6s ease-in-out infinite; }
@keyframes wake-breathe{ 0%,100%{ background-color:rgba(3,7,16,.30) } 50%{ background-color:rgba(3,7,16,.52) } }
.hold-gate.a1-wake.on{ transform:none; }
.hold-gate.a1-wake.on .hold-txt{ transform:scale(1.04); }
.hold-gate.a1-wake .hold-ring{ width:66px; height:66px; }
.hold-gate.a1-wake .hold-ring svg{ width:66px; height:66px; }
.hold-gate.a1-wake .hold-txt{
  margin-top:20px; text-align:center; line-height:1.9;
  font-size:14px; letter-spacing:.2em; color:rgba(214,236,246,.92);
  text-shadow:0 0 18px rgba(0,200,215,.55);
  transition:transform .2s ease;
}
.hold-gate.a1-wake .hold-txt b{ font-size:17px; letter-spacing:.26em; }
.hold-gate.a1-wake .hold-ring .core{ inset:19px; }

/* 能量汇聚层（z-index 4 —— 压在谈判桌 z-index 1 之上、暖光 5 之下） */
.a1-converge{
  position:absolute; inset:0; z-index:4;
  pointer-events:none; overflow:hidden;
  opacity:0;
}
.a1-converge.on{ opacity:1; }   /* 由 js/wake.js mount/clear 开合，别用 tl 去管它 */
/* 光点：从屏幕四角收向中心。translate 由 js/wake.js 每帧写，CSS 只管长相 */
.a1-converge .mote{
  position:absolute; left:50%; top:50%; margin:-2px 0 0 -2px;
  border-radius:50%; opacity:0; will-change:transform,opacity;
  background:radial-gradient(circle,rgba(214,250,255,.95) 0%,rgba(95,227,240,.55) 38%,rgba(95,227,240,0) 72%);
  box-shadow:0 0 12px rgba(95,227,240,.9);
}
.a1-converge .conv-core{
  position:absolute; left:50%; top:50%;
  width:150px; height:150px; border-radius:50%; opacity:0;
  transform:translate(-50%,-50%) scale(.34);
  background:radial-gradient(circle,rgba(220,252,255,.92) 0%,rgba(108,60,224,.42) 38%,rgba(95,227,240,0) 72%);
  box-shadow:0 0 calc(20px + 40px * var(--glow,0)) rgba(95,227,240,.75);
}
.a1-converge .conv-rings i{
  position:absolute; left:50%; top:50%;
  width:170px; height:170px; border-radius:50%; opacity:0;
  border:1.5px solid rgba(140,235,248,.55);
}

/* ══════════ 顶部进度条 ══════════ */
#progress{
  position:fixed; left:0; top:0; z-index:60;
  width:100%; height:2px;
  background:rgba(255,255,255,.07);
}
#progress i{
  display:block; height:100%; width:0%;
  background:linear-gradient(90deg,var(--cyan),var(--nebula) 60%,var(--gold));
  box-shadow:0 0 12px rgba(0,200,215,.85),0 0 26px rgba(108,60,224,.6);
  transition:width .18s linear;
}

/* ══════════ 右下角静音 / 取消静音 ══════════
   放在下载条上方（--hud-b），避免第四幕下载条升起时被压住 */
.hud-btn{
  position:fixed; z-index:60;
  right:14px; bottom:var(--hud-b);
  width:44px; height:44px; border-radius:50%;
  display:grid; place-items:center;
  background:rgba(10,26,58,.55);
  border:1px solid rgba(0,200,215,.28);
  backdrop-filter:blur(8px); -webkit-backdrop-filter:blur(8px);
  box-shadow:0 0 18px rgba(0,200,215,.16);
}
.hud-btn svg{ width:20px; height:20px; fill:none; stroke:var(--cyan); stroke-width:1.7; stroke-linecap:round; stroke-linejoin:round; }
.hud-btn .spk{ fill:var(--cyan); stroke:none; }
.hud-btn .mute{ display:none; stroke:var(--gold); stroke-width:1.9; }
.hud-btn[data-on="1"] .wave{ opacity:1; }
.hud-btn[data-on="0"] .wave{ opacity:.2; }
.hud-btn[data-on="0"] .mute{ display:block; }

/* ══════════ 电影层：粒子 / 光效扫过 / 视线聚焦 / 压暗 ══════════ */
#fx{
  position:fixed; inset:0; z-index:55;
  pointer-events:none;
  mix-blend-mode:screen;
}
#sweep{
  position:fixed; top:-20%; bottom:-20%; left:0; z-index:56;
  width:46%; pointer-events:none;
  background:linear-gradient(100deg,
    rgba(0,200,215,0) 0%,
    rgba(150,240,255,.30) 38%,
    rgba(245,197,66,.34) 58%,
    rgba(245,197,66,0) 100%);
  filter:blur(14px);
  mix-blend-mode:screen;
}
#focus{
  position:fixed; inset:0; z-index:54; pointer-events:none;
  background:radial-gradient(46% 30% at 50% 46%,
    rgba(150,240,255,.22) 0%,
    rgba(108,60,224,.10) 45%,
    rgba(0,0,0,0) 72%);
  mix-blend-mode:screen;
}
#vignette{
  position:fixed; inset:0; z-index:53; pointer-events:none;
  opacity:0;
  background:radial-gradient(72% 46% at 50% 42%,
    rgba(0,0,0,0) 38%, rgba(2,6,18,.62) 100%);
}
/* 胶片颗粒：影片质感的最后一层（0.9s 内跳 9 次位置，模拟胶片噪点抖动） */
#grain{
  position:fixed; inset:-40px; z-index:57; pointer-events:none;
  opacity:.05; mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='240' height='240' filter='url(%23n)' opacity='0.6'/%3E%3C/svg%3E");
  animation:grainJump .9s steps(9) infinite;
}
@keyframes grainJump{
  0%{transform:translate(0,0)}
  11%{transform:translate(-14px,6px)}
  22%{transform:translate(8px,-12px)}
  33%{transform:translate(-6px,-8px)}
  44%{transform:translate(12px,10px)}
  55%{transform:translate(-10px,2px)}
  66%{transform:translate(4px,12px)}
  77%{transform:translate(10px,-6px)}
  88%{transform:translate(-12px,-4px)}
  100%{transform:translate(0,0)}
}
body.lowfx #grain{ display:none; }

/* 视差层（由 cinema.js 自动插入） */
.fg-par{
  position:absolute; inset:0; z-index:1; pointer-events:none;
  background:
    linear-gradient(180deg, rgba(6,14,34,0) 62%, rgba(6,14,34,.20) 100%),
    radial-gradient(60% 24% at 50% 108%, rgba(0,200,215,.14), rgba(0,0,0,0) 70%);
}
.glow-par{
  position:absolute; inset:-12%; z-index:0; pointer-events:none;
  background:
    radial-gradient(38% 26% at 22% 26%, rgba(0,200,215,.22), rgba(0,0,0,0) 70%),
    radial-gradient(34% 22% at 78% 68%, rgba(245,197,66,.18), rgba(0,0,0,0) 72%);
  filter:blur(18px);
  mix-blend-mode:screen;
}
body.lowfx .glow-par{ display:none; }

/* 进度条：发光能量线 */
#progress.is-lit i{
  box-shadow:0 0 14px rgba(0,200,215,.95),0 0 32px rgba(108,60,224,.7),0 0 48px rgba(245,197,66,.35);
}

/* ══════════ 微信提示 ══════════ */
.overlay-tip{
  position:fixed; inset:0; z-index:90;
  background:rgba(3,8,20,.88);
  backdrop-filter:blur(3px);
  display:flex; flex-direction:column; align-items:center;
  padding-top:calc(28px + var(--safe-t));
  animation:fade .3s var(--ease-out) both;
}
.overlay-tip .tip-arrow{
  align-self:flex-end; margin-right:26px;
  width:0; height:0;
  border-left:13px solid transparent; border-right:13px solid transparent;
  border-bottom:20px solid var(--gold);
  filter:drop-shadow(0 0 10px rgba(245,197,66,.8));
  animation:bob 1.1s ease-in-out infinite;
}
.overlay-tip p{ margin-top:26px; font-size:16px; line-height:1.9; text-align:center; color:#fff; }
.overlay-tip b{ color:var(--gold); font-size:18px; letter-spacing:2px; }
@keyframes bob{ 0%,100%{transform:translateY(0)} 50%{transform:translateY(-7px)} }
@keyframes fade{ from{opacity:0} to{opacity:1} }

/* ══════════ 全局背景 ══════════ */
#bg{ position:fixed; inset:0; z-index:0; overflow:hidden;
  background:
    radial-gradient(120% 80% at 50% 0%, #122a5c 0%, var(--deep) 38%, var(--deep-2) 100%);
}
#stars{ position:absolute; inset:0; width:100%; height:100%; }
.nebula{
  position:absolute; border-radius:50%; filter:blur(70px); opacity:.5;
  will-change:transform,opacity;
}
.nebula-a{
  width:78vw; height:78vw; left:-26vw; top:-12vh;
  background:radial-gradient(circle,rgba(108,60,224,.85),rgba(108,60,224,0) 68%);
  animation:drift-a 26s ease-in-out infinite;
}
.nebula-b{
  width:92vw; height:92vw; right:-38vw; bottom:-18vh;
  background:radial-gradient(circle,rgba(0,200,215,.6),rgba(0,200,215,0) 70%);
  animation:drift-b 34s ease-in-out infinite;
}
@keyframes drift-a{ 0%,100%{transform:translate3d(0,0,0) scale(1)} 50%{transform:translate3d(6vw,5vh,0) scale(1.12)} }
@keyframes drift-b{ 0%,100%{transform:translate3d(0,0,0) scale(1.05)} 50%{transform:translate3d(-7vw,-6vh,0) scale(1)} }
.grid{
  position:absolute; inset:-20% -20% -20% -20%; opacity:.13;
  background-image:
    linear-gradient(rgba(0,200,215,.5) 1px, transparent 1px),
    linear-gradient(90deg, rgba(0,200,215,.5) 1px, transparent 1px);
  background-size:54px 54px;
  transform:perspective(420px) rotateX(62deg);
  mask-image:radial-gradient(circle at 50% 40%, #000 0%, transparent 62%);
  -webkit-mask-image:radial-gradient(circle at 50% 40%, #000 0%, transparent 62%);
  animation:grid-run 12s linear infinite;
}
@keyframes grid-run{ from{background-position:0 0,0 0} to{background-position:0 54px,54px 0} }
.vignette{
  position:absolute; inset:0; pointer-events:none;
  background:radial-gradient(120% 78% at 50% 46%, transparent 46%, rgba(2,6,16,.40) 100%);
}

/* ══════════ 实拍场景底图 ══════════
   满屏图层（section.act 的直接子元素），透明度由各幕时间线控制；
   CSS 剪影（.figure / .neg / .iv-xxx / .fm-xxx 等）作为图片加载失败时的兜底，
   仅当图片真的加载成功（.act[data-scene-ok~="key"]）才隐藏。
   ⚠ 注释里不要出现「星号+斜杠」组合（例如写 .iv-* 后面紧跟 /），
     那会提前终止注释，导致紧随其后的规则被整条丢弃。 */
.scene{
  position:absolute; inset:0; z-index:0;
  overflow:hidden;
  opacity:0;
  background:#050b18;
  pointer-events:none;
}
/* ★ transform 已交给 cinema.js（ScrollTrigger scrub 1.5 驱动推镜 + 横移）；
   opacity 交给 scene.js 帧循环做交叉淡化（只过渡 opacity，不碰 transform/filter） */
.scene img{
  position:absolute; inset:0;
  width:100%; height:100%;
  object-fit:cover; object-position:50% 44%;
  transform-origin:50% 46%;
  backface-visibility:hidden;
  will-change:transform, opacity;
  filter:brightness(1.07) saturate(1.05);   /* 明亮基调：轻提亮不加噪 */
  transition:opacity .45s ease;             /* 帧间交叉淡化 */
}
/* ★ v7 真人视频（.sv）：与上面 .scene img 共用同一套尺寸/推镜参数，
   保证「视频↔图片」切换时镜头位移与裁切完全一致，不会跳一下 */
.scene video.sv{
  position:absolute; inset:0;
  width:100%; height:100%;
  object-fit:cover; object-position:50% 44%;
  transform-origin:50% 46%;
  backface-visibility:hidden;
  -webkit-backface-visibility:hidden;
  will-change:transform, opacity;
  filter:brightness(1.07) saturate(1.05);
  background:#050b18;   /* 首帧未解码前的底色，避免闪白 */
  opacity:1;
}
/* 视频优先时，兜底帧（若有）压在视频下面，不参与交叉淡化 */
.scene.has-video .fr2{ display:none; }

/* 曝光呼吸：整场极慢的亮度起伏（摄影机的自动曝光感） */
.scene{ animation:filmBreath 9s ease-in-out infinite; }
@keyframes filmBreath{
  0%,100%{ filter:brightness(1); }
  50%    { filter:brightness(1.035); }
}
body.lowfx .scene{ animation:none; }

/* 明亮版遮罩：只压一点点上下（保证叠字可读），整体保留通透感 */
.scene::after{
  content:""; position:absolute; inset:0; pointer-events:none;
  background:
    linear-gradient(180deg,
      rgba(6,14,34,.42) 0%,
      rgba(6,14,34,.10) 18%,
      rgba(6,14,34,.02) 42%,
      rgba(6,14,34,.16) 72%,
      rgba(6,14,34,.46) 100%),
    radial-gradient(120% 62% at 78% 52%, rgba(6,14,34,.22), rgba(6,14,34,0) 64%),
    radial-gradient(96% 62% at 6% 10%, rgba(0,200,215,.10), rgba(0,0,0,0) 72%);
}
/* 底边再垫一层，保证「继续」按钮与建议气泡始终读得清 */
.scene::before{
  content:""; position:absolute; left:0; right:0; bottom:0; height:28%;
  z-index:2; pointer-events:none;
  background:linear-gradient(180deg, rgba(3,7,18,0), rgba(4,9,22,.7));
}

/* —— 图片加载成功后，隐藏被它取代的剪影兜底层 ——
   ★ v10：这些选择器必须写死幕号（#act1/#act3），不能用 .act[data-scene-ok~=...]。
     原因 —— data-scene-ok 是打在 section.act 上的，第二幕复用第三幕的四个实拍
     素材（a3_*）后，它的 section 上同样会挂 a3_interview/a3_love/... 几个标记，
     裸 .act 选择器会把第二幕的剪影层一起撤掉、渐变底色也一起清掉，
     第二幕就变成"只有照片没有角色"的空场面。锁到幕号才互不干扰。 */
#act1[data-scene-ok~="a1_room"]  .figure,
#act1[data-scene-ok~="a1_city"]  .city,
#act1[data-scene-ok~="a2_nego"]  .neg,
#act3[data-scene-ok~="a3_interview"] #a3-s1 .sl-scene > span,
#act3[data-scene-ok~="a3_love"]      #a3-s2 .sl-scene > span,
#act3[data-scene-ok~="a3_global"]    #a3-s3 .sl-scene > span,
#act3[data-scene-ok~="a3_family"]    #a3-s4 .sl-scene > span{
  opacity:0 !important;
  transition:opacity .8s ease;
}
/* 剪影层的渐变底色也一并撤掉，避免在真实照片上叠出一层蓝雾 */
#act3[data-scene-ok~="a3_interview"] #a3-s1 .sl-scene,
#act3[data-scene-ok~="a3_love"]      #a3-s2 .sl-scene,
#act3[data-scene-ok~="a3_global"]    #a3-s3 .sl-scene,
#act3[data-scene-ok~="a3_family"]    #a3-s4 .sl-scene{ background:none; }
/* 第二幕复用同一批素材，同样撤掉剪影兜底（.sl-scene 不是 #act3 里的那几个 id，
   所以单列一条，不能并进上面那个 #act3 组里） */
#act2[data-scene-ok~="a3_interview_b"] #a2-s1 .sl-scene,
#act2[data-scene-ok~="a3_love_b"]      #a2-s2 .sl-scene,
#act2[data-scene-ok~="a3_global_b"]    #a2-s3 .sl-scene,
#act2[data-scene-ok~="a3_family_b"]    #a2-s4 .sl-scene{ background:none; }
#act2[data-scene-ok~="a3_interview_b"] #a2-s1 .sl-scene > span,
#act2[data-scene-ok~="a3_love_b"]      #a2-s2 .sl-scene > span,
#act2[data-scene-ok~="a3_global_b"]    #a2-s3 .sl-scene > span,
#act2[data-scene-ok~="a3_family_b"]    #a2-s4 .sl-scene > span{
  opacity:0 !important;
  transition:opacity .8s ease;
}

/* 低端机 / 用户偏好减少动效 → 关掉推镜 */
body.lowfx .scene img,
body.lowfx .scene.is-loaded img,
body.lowfx .scene video.sv{ transform:none; transition:none; }
@media (prefers-reduced-motion:reduce){
  .scene img,.scene.is-loaded img,.scene video.sv{ transform:none; transition:none; }
}

/* ══════════ 虚拟人层 ══════════ */
#vhLayer{
  position:fixed; z-index:20;
  left:0; top:0;
  width:var(--vh-w); height:var(--vh-h);
  pointer-events:none;
  will-change:transform,opacity;
  /* ★ 明亮版底图下不能用 screen 混合（亮底上会被冲白）——
     大脑自带透明通道 + 内部 lighter 叠加，直接普通合成即可 */
  opacity:0;
  transform:translate3d(50vw,0,0);
}
#vhLayer canvas{ width:100%; height:100%; }
.ai-tag{
  position:absolute; z-index:21; pointer-events:none;
  font-size:11px; letter-spacing:.14em; color:rgba(159,179,217,.85);
  text-shadow:0 0 10px rgba(0,0,0,.9);
}

/* ══════════ 字幕 / 旁白 ══════════ */
.caption{
  position:relative; z-index:6;
  text-align:center; margin:20px 0;
  opacity:0;
}
.caption .line{
  margin:.34em 0;
  font-size:clamp(17px,4.9vw,23px);
  font-weight:500; letter-spacing:.06em; line-height:1.7;
  color:#fff;
  text-shadow:0 2px 22px rgba(0,0,0,.85), 0 0 40px rgba(0,200,215,.24);
}
.caption.top{ position:absolute; left:0; right:0; top:0; }

/* ══════════ 第一幕 ══════════ */
#act1 .act-inner{
  height:62vh; display:flex; flex-direction:column;
  align-items:center; justify-content:center;
}

.city{
  position:absolute; left:50%; bottom:-6%; transform:translateX(-50%);
  width:190%; height:56%; opacity:0;
}

.figure{
  position:absolute; left:50%; bottom:6%;
  transform:translateX(-50%);
  width:132px; height:176px;
  opacity:0;
}
.figure .body{
  position:absolute; left:50%; bottom:0; transform:translateX(-50%);
  width:118px; height:150px;
  background:linear-gradient(180deg,#0d1b34 0%,#050b18 78%);
  border-radius:58px 58px 22px 22px / 76px 76px 20px 20px;
  box-shadow:inset 0 0 30px rgba(0,0,0,.9);
}
.figure .body::after{ /* 头部 */
  content:""; position:absolute; left:50%; top:-30px; transform:translateX(-50%);
  width:52px; height:56px; border-radius:50%;
  background:linear-gradient(180deg,#0f1f3c,#050b18);
}
.figure .phone-glow{
  position:absolute; left:50%; top:-6px; transform:translateX(-50%);
  width:150px; height:120px; border-radius:50%;
  background:radial-gradient(circle,rgba(150,215,255,.62),rgba(120,180,255,.14) 45%,transparent 72%);
  filter:blur(6px);
  animation:phone-flicker 5.5s ease-in-out infinite;
}
@keyframes phone-flicker{
  0%,100%{ opacity:.85; }
  44%{ opacity:.95; }
  46%{ opacity:.45; }
  48%{ opacity:.9; }
  62%{ opacity:.6; }
  64%{ opacity:.92; }
}

.signal{
  position:absolute; inset:0; z-index:7;
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  opacity:0; pointer-events:none;
}
.signal p{
  position:relative; z-index:2; margin:0;
  font-size:clamp(20px,5.6vw,26px); font-weight:600; letter-spacing:.14em;
  color:#fff; text-shadow:0 0 26px var(--cyan),0 0 60px rgba(0,200,215,.7);
}
.signal-wave{
  position:absolute; width:150px; height:150px; border-radius:50%;
  border:2px solid rgba(0,200,215,.85);
}
.signal-wave::before,.signal-wave::after{
  content:""; position:absolute; inset:-2px; border-radius:50%;
  border:2px solid rgba(0,200,215,.6);
  animation:wave-out 1.9s var(--ease-out) infinite;
}
.signal-wave::after{ animation-delay:.95s; }
@keyframes wave-out{ from{transform:scale(.35);opacity:.9} to{transform:scale(3.4);opacity:0} }

.blackout{
  position:absolute; inset:0; z-index:9;      /* 整幕覆盖 */
  background:#000;
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  opacity:0;
  padding:0 24px;
  /* ★ v9：必须 pointer-events:none。
     .act-stick 是 sticky 容器，内部元素的 z-index（长按门 11）被关在里面出不来，
     整块盖在它上面的 .blackout（z-index 9）哪怕 opacity:0 也照样吃触摸事件 ——
     第一幕的长按门因此一次都按不响。里面没有任何可点东西，直接放过。 */
  pointer-events:none;
}
.blackout .big{
  margin:0; text-align:center;
  font-size:clamp(21px,6vw,29px); font-weight:600; letter-spacing:.1em; line-height:1.72;
  color:#fff;
  text-shadow:0 0 30px rgba(0,200,215,.75);
}
/* ══════════ v8.2 · 悬念钩子 ══════════
   .hook 是每幕结尾那一下「必须往下滑」的钉子：
   画面压到只剩一圈呼吸光点 + 一行问题，用户视线被钉住，只能往下找答案。
   .last 用于第三/四幕 —— 那里底图要真的暗下去（只剩光点），所以自带压暗层。 */
.hook{
  position:absolute; inset:0; z-index:8;
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  text-align:center; padding:0 30px;
  opacity:0; visibility:hidden; pointer-events:none;
}
.hook.last{
  background:radial-gradient(circle at 50% 42%, rgba(4,10,24,.55) 0%, rgba(2,5,14,.93) 62%, #01030a 100%);
}
/* 钩子上场时底图整体压暗（配合 acts.js 的亮度补间） */
.hook.on{ opacity:1; visibility:visible; }
.hook-q{
  position:relative; z-index:2; margin:0;
  font-size:clamp(20px,5.6vw,28px); font-weight:600; letter-spacing:.12em; line-height:1.78;
  color:#fff; text-shadow:0 0 30px rgba(0,200,215,.8), 0 0 70px rgba(0,200,215,.35);
}
.hook-sub{
  position:relative; z-index:2; margin:18px 0 0;
  font-size:clamp(13px,3.7vw,16px); letter-spacing:.18em; line-height:1.8;
  color:rgba(190,214,246,.72);
}
/* 呼吸光点：骤停之后画面唯一还在动的东西 */
.hook-dot{
  position:relative; z-index:2; width:9px; height:9px; border-radius:50%; margin-bottom:26px;
  background:var(--cyan); box-shadow:0 0 22px var(--cyan), 0 0 60px rgba(0,200,215,.6);
  animation:hook-pulse 2.6s ease-in-out infinite;
}
.hook-dot.big-dot{ width:13px; height:13px; margin-bottom:30px; }
@keyframes hook-pulse{ 0%,100%{ transform:scale(1); opacity:.55 } 50%{ transform:scale(1.5); opacity:1 } }

/* 第二幕：天脑「转头看向用户」的光斑 —— 让它有对象感，不是对着空气说话 */
.hook-you{
  position:absolute; z-index:1; top:-6%; left:50%; width:190px; height:190px; margin-left:-95px;
  border-radius:50%; opacity:0;
  background:radial-gradient(circle, rgba(0,200,215,.30) 0%, rgba(0,200,215,0) 68%);
  animation:hook-you 3.2s ease-in-out infinite;
}
@keyframes hook-you{ 0%,100%{ transform:scale(.9); opacity:.35 } 50%{ transform:scale(1.15); opacity:.85 } }

/* 第四幕：「但有一个问题……」炸开成光点（3 道光刃向外长出去）
   ★ 旋转写死在 i 上、关键帧只动 height/opacity —— 动画里若写 transform 会整条覆盖掉 rotate，
     光刃会跑成「不转的竖条」。 */
.hook-burst{ position:absolute; inset:0; z-index:1; pointer-events:none; }
.hook-burst i{
  position:absolute; left:50%; top:44%; width:2px; height:74px; margin-left:-1px;
  background:linear-gradient(rgba(0,200,215,0), rgba(0,200,215,.9));
  opacity:0;
}
.hook-burst i:nth-child(1){ transform:rotate(-38deg); transform-origin:50% 100%; }
.hook-burst i:nth-child(2){ transform:rotate(38deg);  transform-origin:50% 100%; }
.hook-burst i:nth-child(3){ transform:rotate(90deg);  transform-origin:50% 100%; }
.hook.on .hook-burst i{ animation:hook-burst .9s var(--ease-out) forwards; }
.hook.on .hook-burst i:nth-child(2){ animation-delay:.1s }
.hook.on .hook-burst i:nth-child(3){ animation-delay:.2s }
@keyframes hook-burst{
  from{ opacity:0; height:74px }
  25% { opacity:.95 }
  to  { opacity:0; height:330px }
}

.swipe-hint{
  margin-top:34px; width:22px; height:36px; border:1.5px solid rgba(234,242,255,.45); border-radius:12px;
  position:relative;
}
.swipe-hint i{
  position:absolute; left:50%; top:7px; width:4px; height:8px; margin-left:-2px;
  background:var(--cyan); border-radius:2px;
  animation:swipe 1.7s ease-in-out infinite;
}
@keyframes swipe{ 0%{transform:translateY(0);opacity:1} 70%{transform:translateY(14px);opacity:0} 71%{transform:translateY(0);opacity:0} 100%{opacity:1} }

/* ══════════ 第二幕 ══════════ */
.neg{ position:absolute; inset:-40px -22px; z-index:1; opacity:0; }
.neg-desk{
  position:absolute; left:-10%; right:-10%; bottom:16%; height:34%;
  background:linear-gradient(180deg,#13203c,#070d1c);
  border-top:1px solid rgba(0,200,215,.28);
  transform:perspective(300px) rotateX(46deg);
  transform-origin:bottom center;
  box-shadow:0 -14px 44px rgba(0,0,0,.7);
}
.neg-man{
  position:absolute; left:50%; top:24%; transform:translateX(-50%);
  width:96px; height:120px;
  background:linear-gradient(180deg,#101d38,#050a15);
  border-radius:44px 44px 16px 16px / 60px 60px 14px 14px;
  box-shadow:
    inset 3px 0 10px -4px rgba(0,200,215,.55),
    inset -3px 0 10px -4px rgba(108,60,224,.45),
    0 0 40px rgba(0,0,0,.85);
  opacity:.95;
}
.neg-man::after{
  content:""; position:absolute; left:50%; top:-24px; transform:translateX(-50%);
  width:42px; height:44px; border-radius:50%;
  background:linear-gradient(180deg,#12213e,#050a15);
  box-shadow:inset 0 -4px 10px -3px rgba(0,200,215,.5), 0 0 22px rgba(0,0,0,.9);
}
.neg-papers{
  position:absolute; left:50%; bottom:23%; transform:translateX(-50%) perspective(220px) rotateX(52deg) rotateZ(-3deg);
  width:104px; height:56px; border-radius:3px;
  background:linear-gradient(160deg,rgba(234,242,255,.10),rgba(234,242,255,.02));
  border:1px solid rgba(234,242,255,.10);
  box-shadow:0 6px 18px rgba(0,0,0,.55);
  opacity:.8;
}
/* 逆转时刻的暖光扫过 */
.warm-glow{
  position:absolute; inset:-40px -22px; z-index:5; pointer-events:none; opacity:0;
  background:radial-gradient(70% 46% at 50% 34%, rgba(245,197,66,.30), rgba(245,197,66,.08) 46%, transparent 72%);
}

.bubble{
  position:absolute; z-index:6; left:6%; right:6%; top:12%;
  opacity:0;
  padding:12px 15px; border-radius:14px;
  background:rgba(12,22,44,.82);
  border:1px solid rgba(234,242,255,.12);
  backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px);
}
.bubble .who{ font-size:11px; letter-spacing:.16em; color:var(--ink-dim); }
.bubble p{ margin:6px 0 0; font-size:15px; line-height:1.6; color:#fff; }

.vh-say{
  position:relative; z-index:8;
  max-width:290px; margin:26px auto 0;
  padding:13px 17px; border-radius:16px;
  background:linear-gradient(135deg,rgba(0,200,215,.16),rgba(108,60,224,.16));
  border:1px solid rgba(0,200,215,.42);
  box-shadow:0 0 34px rgba(0,200,215,.3), inset 0 0 26px rgba(0,200,215,.1);
  backdrop-filter:blur(7px); -webkit-backdrop-filter:blur(7px);
  opacity:0;
}
.vh-say p{
  margin:0; font-size:clamp(16px,4.6vw,19px); font-weight:500; letter-spacing:.05em;
  color:#fff; text-shadow:0 0 18px rgba(0,200,215,.7);
}
.vh-say::before{
  content:""; position:absolute; left:-1px; top:16%; bottom:16%; width:2px;
  background:linear-gradient(180deg,var(--cyan),var(--gold));
  border-radius:2px; box-shadow:0 0 12px var(--cyan);
}

.reveal-line{
  margin-top:34px; text-align:center;
  font-size:clamp(19px,5.4vw,25px); font-weight:700; letter-spacing:.2em;
  color:var(--gold);
  text-shadow:0 0 24px rgba(245,197,66,.85),0 0 60px rgba(245,197,66,.45);
  opacity:0;
}

/* ══════════ 继续按钮 ══════════ */
.continue{
  position:absolute; left:50%; bottom:calc(20px + var(--safe-b));
  transform:translateX(-50%);
  z-index:30;
  padding:11px 26px; border-radius:999px;
  font-size:14px; letter-spacing:.18em;
  color:#dff4ff;
  background:rgba(10,26,58,.5);
  border:1px solid rgba(0,200,215,.4);
  backdrop-filter:blur(8px); -webkit-backdrop-filter:blur(8px);
  box-shadow:0 0 24px rgba(0,200,215,.22);
  opacity:0;
  animation:breathe 2.8s ease-in-out infinite;
}
.continue span{ display:inline-block; transform:translateY(-1px); margin-left:2px; }
@keyframes breathe{ 0%,100%{ box-shadow:0 0 20px rgba(0,200,215,.18) } 50%{ box-shadow:0 0 36px rgba(0,200,215,.46) } }

/* ══════════ 第三幕 · 人生关键时刻（四切片） ══════════ */
.act-moments .act-inner{
  min-height:72vh; display:flex; flex-direction:column; justify-content:center;
}

.a3-head{
  position:absolute; left:0; right:0; top:-4%; z-index:8;
  text-align:center; opacity:0;
}
.a3-k{ font-size:11px; letter-spacing:.34em; color:var(--cyan); }
.a3-head h2{
  margin:12px 0 10px; font-size:clamp(20px,5.6vw,26px); font-weight:600; letter-spacing:.06em;
  text-shadow:0 0 30px rgba(0,200,215,.4);
}
.a3-head p{ margin:0; font-size:12px; letter-spacing:.14em; color:var(--ink-dim); }

/* ══════════ 第三幕 v10 · 四道门（选一个） ══════════
   跟第二幕的形态必须拉开：第二幕是满屏实拍轮播（你看），
   第三幕是 2×2 的小门阵（你选）—— 同一组素材，尺度反过来。 */
.act-choose .act-inner{
  /* z-index 必须高于底图 .scene：选中那扇门之后实拍底图会铺满整幕，
     不抬层级的话门阵和台词会被压在照片底下看不见 */
  position:relative; z-index:3;
  min-height:80vh; display:flex; flex-direction:column; justify-content:center;
}
/* 旧版 .a3-head 是 absolute 悬在顶部（为四切片让位）；四选一要它回到文档流里 */
.act-choose .a3-head{ position:relative; top:auto; left:auto; right:auto; }
.act-choose .a3-head h2{ margin:12px 0 0; }
.a3-hint{
  margin-top:10px; font-size:12.5px; letter-spacing:.12em; color:var(--ink-dim);
  animation:card-hint 1.7s ease-in-out infinite;
}
.a3-head.picked .a3-hint{ animation:none; opacity:0; transition:opacity .4s ease; }

.doors{
  display:grid; grid-template-columns:1fr 1fr; gap:11px; width:100%; margin-top:22px;
}
.door{
  position:relative; display:block; width:100%; height:118px; padding:0; border-radius:14px;
  overflow:hidden; border:1px solid rgba(120,205,230,.26); background:rgba(6,14,28,.5);
  color:inherit; font:inherit; text-align:left; cursor:pointer;
  -webkit-tap-highlight-color:transparent; touch-action:manipulation;
  /* ★ 坑：这里**绝对不能** transition opacity / transform —— 这两个属性是 GSAP 在管的
     （tl.set({opacity:0,y:18}) → tl.to({opacity:1,y:0})）。
     CSS 过渡会把 GSAP 写进去的值当成"目标值"再自己补间一遍，
     于是定格采样读到的永远是过渡中间值（实测 tl=7.2 时第四扇门读出来 0.445，
     看着像"门没出来"，其实 GSAP 早就把它设成 1 了）。
     规矩：一个属性只准有一个主人。GSAP 管的就别进 transition。 */
  transition:height .5s var(--ease-out), filter .5s ease,
    border-color .35s ease, box-shadow .35s ease;
}
.door .d-art{ position:absolute; inset:0; opacity:.92; }
.door .d-art::after{
  content:""; position:absolute; inset:0;
  background:radial-gradient(circle at 72% 20%, rgba(255,255,255,.18), rgba(255,255,255,0) 60%);
}
/* 四扇门各给一条色带，不加载任何图片 —— 选中那扇才去拉实拍底图 */
#a3-d1 .d-art{ background:linear-gradient(158deg,#22384f,#0d1626 74%); }
#a3-d2 .d-art{ background:linear-gradient(158deg,#41243f,#170f22 74%); }
#a3-d3 .d-art{ background:linear-gradient(158deg,#123d47,#0a1a22 74%); }
#a3-d4 .d-art{ background:linear-gradient(158deg,#41301a,#1a140c 74%); }
.door .d-lab{
  position:absolute; left:13px; bottom:28px; font-size:16px; font-weight:600; letter-spacing:.06em;
  text-shadow:0 2px 10px rgba(0,0,0,.6);
}
.door .d-sub{
  position:absolute; left:13px; bottom:11px; font-size:11.5px;
  letter-spacing:.03em; opacity:.72;
}
.door:active{ transform:scale(.984); }
/* 选完之后：门阵整体让位（缩一点），被选中的那扇点亮，其余压到 .25 */
.doors.picked .door{ height:94px; pointer-events:none; }
.door.is-pick{
  border-color:rgba(0,200,215,.9);
  box-shadow:0 0 42px rgba(0,200,215,.42), inset 0 0 26px rgba(0,200,215,.14);
}
/* ★ 坑（跟第二幕建议卡同一个）：.door 的 opacity 被 GSAP 内联占着
   （tl.set({opacity:0}) → tl.to({opacity:1})），内联永远压过 CSS 类，
   写 .dim{opacity:.25} 根本不生效（实测 computed 仍是 1）。
   所以"其余变暗"改用 filter —— 这个属性时间线不碰，两边不抢。 */
.door.dim{ filter:brightness(.34) saturate(.6); }

.a3-core{ position:relative; margin-top:24px; text-align:center; min-height:104px; }
.a3-line{
  margin:0; font-size:clamp(13px,3.7vw,15.5px); letter-spacing:.05em; opacity:0;
  color:var(--cyan); text-shadow:0 0 18px rgba(0,200,215,.45);
}
.a3-say{
  margin:14px 0 0; font-size:clamp(19px,5.4vw,25px); font-weight:600;
  letter-spacing:.05em; line-height:1.55; opacity:0;
  text-shadow:0 0 26px rgba(0,200,215,.5);
}
.a3-say2{
  margin:11px 0 0; font-size:clamp(12.5px,3.5vw,15px); letter-spacing:.04em;
  opacity:0; color:var(--ink-dim);
}

.moments{ position:relative; width:100%; height:64vh; }
.slice{ position:absolute; inset:0; opacity:0; }
.sl-scene{ position:absolute; inset:0; z-index:1; }

/* —— 对方台词（靠左，避开右侧虚拟人） —— */
.sl-them{
  position:absolute; z-index:6; left:2%; right:27%; top:6%;
  padding:12px 15px; border-radius:14px;
  background:rgba(12,22,44,.86);
  border:1px solid rgba(234,242,255,.13);
  box-shadow:0 10px 30px rgba(0,0,0,.5);
  backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px);
  opacity:0;
}
.sl-them .who{ font-size:11px; letter-spacing:.16em; color:var(--ink-dim); }
.sl-them p{ margin:6px 0 0; font-size:14.5px; line-height:1.55; color:#fff; }
.sl-them.en p{ letter-spacing:.01em; color:#dff0ff; }

/* —— 天脑建议（底部通栏） —— */
.sl-tino{
  position:absolute; z-index:8; left:2%; right:2%; bottom:9%;
  padding:12px 16px 12px 19px; border-radius:16px;
  background:linear-gradient(135deg,rgba(0,200,215,.18),rgba(108,60,224,.2));
  border:1px solid rgba(0,200,215,.45);
  box-shadow:0 0 34px rgba(0,200,215,.3), inset 0 0 26px rgba(0,200,215,.1);
  backdrop-filter:blur(7px); -webkit-backdrop-filter:blur(7px);
  opacity:0;
}
.sl-tino::before{
  content:""; position:absolute; left:-1px; top:16%; bottom:16%; width:2px; border-radius:2px;
  background:linear-gradient(180deg,var(--cyan),var(--gold));
  box-shadow:0 0 12px var(--cyan);
}
.sl-tino .who{
  display:flex; align-items:center; gap:6px;
  font-size:11px; letter-spacing:.16em; color:var(--cyan);
}
.sl-tino .who em{
  width:6px; height:6px; border-radius:50%;
  background:var(--cyan); box-shadow:0 0 10px var(--cyan);
  animation:ai-pulse 1.3s ease-in-out infinite;
}
@keyframes ai-pulse{ 0%,100%{opacity:.4;transform:scale(.82)} 50%{opacity:1;transform:scale(1.16)} }
.sl-tino p{
  margin:7px 0 0; font-size:clamp(15px,4.4vw,18px); font-weight:500; letter-spacing:.04em;
  color:#fff; text-shadow:0 0 18px rgba(0,200,215,.6);
}

/* —— 局面扭转（底部，与建议不同时出现） —— */
.sl-out{
  position:absolute; z-index:9; left:0; right:0; bottom:21%; margin:0;
  text-align:center;
  font-size:clamp(18px,5.2vw,24px); font-weight:700; letter-spacing:.2em;
  color:var(--gold);
  text-shadow:0 0 24px rgba(245,197,66,.85),0 0 60px rgba(245,197,66,.45);
  opacity:0;
}

/* ══════════ 第二幕 · 可点击的建议卡（v10 交互件） ══════════
   交互取舍：默认收起（内容要点开才看到，参与感才在），
   但 acts.js 里配了 1.2s 自动兜底（A2.AUTO）—— 不点也会自己展开，信息不丢。
   ★ 用 max-height 而不是 height：height:auto 没法做过渡；
     用 line-clamp 做"省略号截断"在 iOS 上换列会抽风，max-height 最稳。 */
.sl-card{
  display:block; width:100%; text-align:left;
  font:inherit; color:inherit; -webkit-appearance:none; appearance:none;
  max-height:56px; overflow:hidden;
  cursor:pointer;
  -webkit-tap-highlight-color:transparent;
  touch-action:manipulation;          /* 禁掉双击缩放，但保留纵向滚动，别把页面滚死 */
  transition:max-height .4s ease, border-color .3s ease, box-shadow .3s ease;
}
.sl-card.is-open{ max-height:220px; border-color:rgba(0,200,215,.85); }
.sl-card.is-open{ box-shadow:0 0 46px rgba(0,200,215,.5), inset 0 0 30px rgba(0,200,215,.16); }
.sl-card:active{ transform:scale(.988); }

.sl-card .sl-txt{
  display:block; max-height:0; overflow:hidden;
  transition:max-height .4s ease, margin .3s ease;
}
.sl-card.is-open .sl-txt{ max-height:170px; margin-top:9px; }

/* 收起态的呼吸提示：告诉用户"这张能点"，不点就一直呼吸 */
.sl-card .sl-more{
  display:flex; align-items:center; gap:6px; margin-top:9px;
  font-size:11px; letter-spacing:.2em; color:rgba(0,200,215,.9);
  animation:card-hint 1.7s ease-in-out infinite;
}
.sl-card .sl-more i{ display:inline-block; font-style:normal; transition:transform .3s ease; }
.sl-card.is-open .sl-more{ animation:none; opacity:.65; }
.sl-card.is-open .sl-more i{ transform:rotate(180deg); }
@keyframes card-hint{
  0%,100%{ opacity:.42; transform:translateY(0) }
  50%    { opacity:1;   transform:translateY(2px) }
}
/* 建议卡里的正文用 span 而不是 p（button 里塞 p 是非法嵌套），字号自己带 ——
   它不再挂在 .sl-tino p 那条规则上了 */
.sl-card .sl-txt{
  font-size:clamp(15px,4.4vw,18px); font-weight:500; letter-spacing:.04em;
  color:#fff; text-shadow:0 0 18px rgba(0,200,215,.6);
}

/* —— 第二幕容器：四张切片叠放（同 .moments 的做法，只换名字避免和第三幕混）—— */
.act-daily{ min-height:100vh; }
.act-daily .act-inner{
  min-height:78vh; display:flex; flex-direction:column; justify-content:center;
}
.daily{ position:relative; width:100%; height:62vh; }
.daily .sl{ position:absolute; inset:0; opacity:0; }
/* 四个场景的切场光点：角色化的「消散 / 凝聚」，不是硬切黑场 */
.daily .sl::after{
  content:""; position:absolute; inset:0; z-index:7; pointer-events:none;
  opacity:0; background:radial-gradient(circle at 50% 46%, rgba(0,200,215,.32), rgba(2,5,14,0) 62%);
}

/* —— 收尾旁白 —— */
.a3-coda{
  position:absolute; left:0; right:0; bottom:2%; z-index:9; margin:0;
  text-align:center;
  font-size:clamp(16px,4.6vw,20px); font-weight:500; letter-spacing:.16em; color:#fff;
  text-shadow:0 0 24px rgba(0,200,215,.65);
  opacity:0;
}

/* —— 切片转场：光效扫过 —— */
.sweep{
  position:absolute; left:-30%; top:-4%; bottom:-4%; width:44%; z-index:10;
  pointer-events:none; opacity:0;
  background:linear-gradient(100deg,transparent 0%,rgba(0,200,215,.26) 38%,
    rgba(255,255,255,.42) 50%,rgba(108,60,224,.26) 62%,transparent 100%);
  filter:blur(10px);
}

/* ── 切片场景 ① 求职面试：冷白办公 ── */
.sc-interview{ background:radial-gradient(82% 46% at 50% 6%, rgba(180,220,255,.16), transparent 68%); }
.iv-lamp{
  position:absolute; left:14%; right:14%; top:1%; height:3px; border-radius:3px;
  background:linear-gradient(90deg,transparent,rgba(214,236,255,.85),transparent);
  box-shadow:0 0 26px rgba(180,220,255,.6);
}
.iv-desk{
  position:absolute; left:-8%; right:-8%; bottom:20%; height:26%;
  background:linear-gradient(180deg,#14213d,#070d1c);
  border-top:1px solid rgba(0,200,215,.3);
  transform:perspective(320px) rotateX(48deg); transform-origin:bottom center;
  box-shadow:0 -14px 40px rgba(0,0,0,.7);
}
.iv-who{
  position:absolute; left:27%; bottom:33%; transform:translateX(-50%);
  width:72px; height:92px; border-radius:34px 34px 12px 12px / 48px 48px 10px 10px;
  background:linear-gradient(180deg,#16223f,#050a15);
  box-shadow:
    inset 5px 0 14px -7px rgba(180,220,255,.85),    /* 左轮廓光 */
    inset -5px 0 14px -7px rgba(108,60,224,.6),
    0 0 30px rgba(0,0,0,.85);
  opacity:.92;
}
.iv-who::after{
  content:""; position:absolute; left:50%; top:-20px; transform:translateX(-50%);
  width:33px; height:35px; border-radius:50%;
  background:linear-gradient(180deg,#1a2746,#050a15);
  box-shadow:inset 4px 0 12px -6px rgba(180,220,255,.8),
             inset -4px 0 12px -6px rgba(108,60,224,.55);
}
.iv-doc{
  position:absolute; width:70px; height:42px; border-radius:3px;
  background:linear-gradient(160deg,rgba(234,242,255,.12),rgba(234,242,255,.03));
  border:1px solid rgba(234,242,255,.12);
  transform:perspective(220px) rotateX(54deg) rotateZ(-6deg);
}
.iv-doc.d1{ left:8%; bottom:18%; }
.iv-doc.d2{ right:8%; bottom:17%; transform:perspective(220px) rotateX(54deg) rotateZ(7deg); }

/* ── 切片场景 ② 恋爱聊天：紫粉夜色 ── */
.sc-love{ background:radial-gradient(72% 46% at 44% 38%, rgba(108,60,224,.22), transparent 72%); }
.lv-glow{
  position:absolute; left:42%; top:48%; transform:translate(-50%,-50%);
  width:200px; height:200px; border-radius:50%;
  background:radial-gradient(circle,rgba(200,140,255,.26),transparent 68%);
  filter:blur(16px);
}
.lv-phone{
  position:absolute; left:38%; top:44%; transform:translate(-50%,-50%) rotate(-3deg);
  width:52%; max-width:212px; height:46%; border-radius:20px;
  background:linear-gradient(180deg,rgba(20,14,44,.94),rgba(10,10,26,.94));
  border:1px solid rgba(180,140,255,.28);
  box-shadow:0 20px 60px rgba(0,0,0,.65), inset 0 0 40px rgba(108,60,224,.16);
  overflow:hidden;
}
.lv-bar{ position:absolute; left:0; right:0; top:0; height:22px; background:rgba(255,255,255,.05); }
.lv-msg{ position:absolute; height:18px; border-radius:9px; }
.lv-msg.m1{ left:12px; right:34%; top:42px; background:rgba(234,242,255,.14); }
.lv-msg.m2{ left:12px; right:50%; top:70px; background:rgba(234,242,255,.14); }
.lv-msg.m3{ left:34%; right:12px; top:98px; background:linear-gradient(90deg,rgba(108,60,224,.55),rgba(0,200,215,.4)); }
.lv-input{
  position:absolute; left:12px; right:12px; bottom:12px; height:24px; border-radius:12px;
  background:rgba(255,255,255,.07); border:1px solid rgba(180,140,255,.2);
}

/* ── 切片场景 ③ 跨国谈判：视频会议网格 ── */
.sc-nego{ background:radial-gradient(76% 46% at 46% 28%, rgba(0,200,215,.16), transparent 70%); }
.ng-grid{
  position:absolute; left:38%; top:34%; transform:translate(-50%,-50%);
  display:grid; grid-template-columns:repeat(2,1fr); gap:3%; width:66%; max-width:272px;
}
.ng-grid i{
  position:relative; aspect-ratio:16/10; border-radius:8px;
  background:linear-gradient(160deg,rgba(18,28,54,.95),rgba(8,14,30,.95));
  border:1px solid rgba(0,200,215,.2); overflow:hidden;
}
.ng-grid i::after{
  content:""; position:absolute; left:50%; top:52%; transform:translate(-50%,-50%);
  width:24px; height:24px; border-radius:50%; background:rgba(160,190,235,.22);
}
.ng-grid i.on{
  border-color:rgba(0,200,215,.75);
  box-shadow:inset 0 0 22px rgba(0,200,215,.35), 0 0 18px rgba(0,200,215,.3);
}
.ng-grid i.on::after{ background:rgba(0,200,215,.4); box-shadow:0 0 18px rgba(0,200,215,.7); }
.ng-bar{
  position:absolute; left:38%; bottom:12%; transform:translateX(-50%);
  display:flex; align-items:center; gap:5px; height:26px;
}
.ng-bar i{ width:3px; border-radius:3px; background:var(--cyan); opacity:.75; }
.ng-bar i.w1{ height:8px;  animation:eq .72s ease-in-out infinite alternate; }
.ng-bar i.w2{ height:20px; animation:eq .52s ease-in-out infinite alternate; }
.ng-bar i.w3{ height:14px; animation:eq .62s ease-in-out infinite alternate; }
.ng-bar i.w4{ height:6px;  animation:eq .82s ease-in-out infinite alternate; }
@keyframes eq{ from{transform:scaleY(.35)} to{transform:scaleY(1.35)} }

/* ── 切片场景 ④ 家庭空间：暖色客厅 ── */
.sc-family{ background:radial-gradient(70% 48% at 30% 32%, rgba(245,197,66,.13), transparent 72%); }
.fm-sofa{
  position:absolute; left:4%; right:4%; bottom:8%; height:18%;
  border-radius:14px 14px 6px 6px;
  background:linear-gradient(180deg,#2b2015,#100a05);
  box-shadow:0 -10px 30px rgba(0,0,0,.65), inset 0 8px 22px rgba(245,197,66,.1);
}
.fm-sofa::before{                       /* 靠背 */
  content:""; position:absolute; left:5%; right:5%; top:-40%; height:44%;
  border-radius:12px 12px 4px 4px;
  background:linear-gradient(180deg,#33261a,#140d06);
  box-shadow:inset 0 10px 22px rgba(245,197,66,.12), 0 -6px 20px rgba(0,0,0,.55);
}
.fm-sofa::after{                        /* 坐垫缝 */
  content:""; position:absolute; left:9%; right:9%; top:36%; height:2px;
  background:linear-gradient(90deg,transparent,rgba(245,197,66,.3),transparent);
}
.fm-lamp{ position:absolute; right:13%; bottom:34%; width:2px; height:20%; background:rgba(245,197,66,.28); }
.fm-lamp::before{
  content:""; position:absolute; left:50%; top:-17px; transform:translateX(-50%);
  width:38px; height:18px; border-radius:50% 50% 6px 6px;
  background:linear-gradient(180deg,rgba(245,197,66,.55),rgba(245,197,66,.06));
  box-shadow:0 0 30px rgba(245,197,66,.5);
}
.fm-warm{
  position:absolute; right:0; top:0; bottom:0; width:58%;
  background:radial-gradient(54% 44% at 76% 32%, rgba(245,197,66,.2), transparent 72%);
  filter:blur(10px);
}

/* ── 低端机降级 ── */
body.lowfx .ng-bar i{ animation:none; height:12px; }
body.lowfx .lv-glow,
body.lowfx .fm-warm,
body.lowfx .sweep{ display:none; }

/* ══════════ 第四幕 · 融合 ══════════ */
.act-fusion .act-inner{
  min-height:72vh; display:flex; flex-direction:column; justify-content:flex-end;
}

/* 光柱增强层：从底图光柱的根部向上「长」出来（由时间线控制 scaleY）
   ★ 用 calc 居中而非 translateX(-50%)：GSAP 接管 transform 后百分比位移会丢失 */
.a4-beam{
  position:absolute; left:calc(50% - 17vw); bottom:16%; width:34vw; height:84%;
  transform:scaleY(0); transform-origin:bottom center;
  z-index:1; pointer-events:none; opacity:0;
  background:linear-gradient(180deg,
    rgba(0,200,215,.26) 0%, rgba(120,230,255,.20) 34%,
    rgba(190,245,255,.26) 70%, rgba(255,255,255,.30) 100%);
  filter:blur(16px);
  mix-blend-mode:screen;
}

/* 汇聚射线：极缓慢旋转的光针（低透明度，只做氛围） */
.a4-rays{
  position:absolute; left:50%; top:40%; z-index:1; pointer-events:none; opacity:0;
  width:160vmax; height:160vmax; margin:-80vmax 0 0 -80vmax;
  background:conic-gradient(from 0deg,
    rgba(0,200,215,.20) 0deg,  rgba(0,200,215,0) 9deg,
    rgba(108,60,224,.16) 22deg, rgba(108,60,224,0) 36deg,
    rgba(0,200,215,.14) 52deg, rgba(0,200,215,0) 66deg,
    rgba(245,197,66,.11) 82deg, rgba(245,197,66,0) 96deg);
  mask-image:radial-gradient(circle, #000 4%, rgba(0,0,0,.5) 30%, transparent 56%);
  -webkit-mask-image:radial-gradient(circle, #000 4%, rgba(0,0,0,.5) 30%, transparent 56%);
  animation:rays-spin 46s linear infinite;
}
@keyframes rays-spin{ from{transform:rotate(0)} to{transform:rotate(360deg)} }

/* 光环涟漪（三个 i 由时间线错开扩散） */
.a4-rings{ position:absolute; left:50%; top:42%; z-index:2; pointer-events:none; width:0; height:0; }
.a4-rings i{
  position:absolute; left:0; top:0; width:190px; height:190px; margin:-95px 0 0 -95px;
  border:1px solid rgba(150,235,255,.7); border-radius:50%;
  box-shadow:0 0 26px rgba(0,200,215,.55), inset 0 0 26px rgba(0,200,215,.35);
  opacity:0;
}

/* 幕标题 + 主台词 */
.a4-title{ position:relative; z-index:7; text-align:center; opacity:0; }
.a4-k{ font-size:11px; letter-spacing:.34em; color:var(--cyan); }
.a4-title h2{
  margin:12px 0 0;
  font-size:clamp(21px,6vw,29px); font-weight:600; letter-spacing:.08em; line-height:1.66;
  color:#fff;
  text-shadow:0 0 30px rgba(0,200,215,.8), 0 2px 22px rgba(0,0,0,.9);
}

/* 三句关键词：同位叠放，逐句替换 */
.a4-words{ position:relative; z-index:7; height:64px; margin-top:14px; }
.a4-words .w{
  position:absolute; inset:0; margin:0;
  display:flex; align-items:center; justify-content:center;
  font-size:clamp(15px,4.5vw,18px); font-weight:500; letter-spacing:.1em; color:#dff0ff;
  text-shadow:0 0 20px rgba(0,200,215,.6), 0 2px 16px rgba(0,0,0,.85);
  opacity:0;
}

/* 高潮召唤句 */
.a4-call{
  position:relative; z-index:8; margin:6px 0 0; text-align:center;
  font-size:clamp(19px,5.4vw,25px); font-weight:700; letter-spacing:.2em;
  color:var(--gold);
  text-shadow:0 0 24px rgba(245,197,66,.85), 0 0 60px rgba(245,197,66,.45);
  opacity:0;
}

/* 第四幕场景：中央压一层暗罩 —— 底图光柱很亮，不压的话虚拟人在上面会「糊」掉 */
.act[data-scene-ok~="a4_fusion"] #a4-scene::after{
  background:
    radial-gradient(56% 30% at 50% 34%, rgba(3,7,18,.56), rgba(3,7,18,0) 74%),
    linear-gradient(180deg,
      rgba(3,7,18,.82) 0%, rgba(3,7,18,.20) 22%, rgba(3,7,18,.10) 42%,
      rgba(3,7,18,.58) 72%, rgba(3,7,18,.90) 100%);
}

/* 高潮时下载条从底部升起 → 继续按钮自动上浮，避免被压住 */
#act4 .continue.raised{ bottom:calc(174px + var(--safe-b)); transition:bottom .6s var(--ease-out); }

/* ══════════ 第五幕 · 邀请 ══════════ */
.act-invite .act-inner{
  min-height:74vh; display:flex; flex-direction:column;
  justify-content:flex-end; align-items:center;
}

.a5-top{ text-align:center; opacity:0; }
/* v8.2：第五幕先兑现第四幕那一问（问题就是 / 你还没有拥有它），再转温暖收束 */
.a5-ans{
  margin:0 0 8px; font-size:clamp(13px,3.8vw,17px); font-weight:600; letter-spacing:.34em;
  color:var(--cyan); text-shadow:0 0 26px rgba(0,200,215,.75);
}
.a5-top h2{
  margin:0;
  font-size:clamp(22px,6.4vw,31px); font-weight:700; letter-spacing:.06em; line-height:1.6;
  color:#fff;
  text-shadow:0 0 34px rgba(0,200,215,.6), 0 2px 24px rgba(0,0,0,.9);
}
.a5-sub{
  margin:14px 0 0; font-size:clamp(13px,3.7vw,16px); font-weight:300; letter-spacing:.1em; line-height:1.9;
  color:rgba(200,220,248,.68);
}

/* —— 邀请人卡片（无 inviter 参数时显示通用文案） —— */
.a5-card{
  margin-top:20px; width:100%; max-width:340px;
  display:flex; align-items:center; gap:12px;
  padding:12px 16px; border-radius:16px;
  background:linear-gradient(135deg,rgba(12,22,44,.84),rgba(18,30,60,.72));
  border:1px solid rgba(0,200,215,.32);
  box-shadow:0 0 30px rgba(0,200,215,.18);
  backdrop-filter:blur(8px); -webkit-backdrop-filter:blur(8px);
  opacity:0;
}
.a5-ava{
  position:relative; flex:0 0 auto; width:38px; height:38px; border-radius:50%;
  background:radial-gradient(circle at 34% 30%, rgba(0,200,215,.95), rgba(108,60,224,.9) 62%, rgba(10,26,58,.92));
  box-shadow:0 0 18px rgba(0,200,215,.6), inset 0 0 12px rgba(255,255,255,.26);
}
.a5-ava::after{
  content:""; position:absolute; inset:0; border-radius:50%;
  background:
    radial-gradient(circle at 50% 34%, rgba(255,255,255,.5) 0 20%, rgba(255,255,255,0) 24%),
    radial-gradient(ellipse at 50% 84%, rgba(255,255,255,.42) 0 26%, rgba(255,255,255,0) 30%);
}
.a5-card-txt{ min-width:0; }
.a5-from{ margin:0; font-size:14.5px; letter-spacing:.05em; color:#fff; }
.a5-code{ margin:5px 0 0; font-size:11.5px; letter-spacing:.12em; color:var(--ink-dim); }
.a5-code b{ color:var(--gold); font-weight:600; letter-spacing:.16em; }

/* —— 主次 CTA —— */
.a5-cta{ margin-top:20px; width:100%; max-width:520px; opacity:0; }
.cta-sub{
  margin:11px auto 0; width:100%;
  display:flex; align-items:center; justify-content:center; gap:7px;
  padding:12px 18px; border-radius:14px;
  font-size:14px; letter-spacing:.12em; color:#dff4ff;
  background:rgba(10,26,58,.5);
  border:1px solid rgba(0,200,215,.4);
  backdrop-filter:blur(8px); -webkit-backdrop-filter:blur(8px);
  transition:transform .16s var(--ease-out);
}
.cta-sub svg{ width:16px; height:16px; fill:none; stroke:var(--cyan); stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round; }
.cta-sub:active{ transform:scale(.985); }

/* —— 底部：促销 + 合规 —— */
.a5-foot{ margin-top:22px; text-align:center; opacity:0; }
.a5-promo{ margin:0; font-size:12px; letter-spacing:.1em; color:var(--gold); }
.a5-promo b{ font-weight:700; }
.a5-foot .legal{ margin-top:12px; }

/* —— 第四 / 五幕降级 —— */
body.lowfx .a4-rays,
body.lowfx .a4-rings{ display:none; }
body.lowfx .a4-beam{ filter:blur(10px); }

/* ══════════ 占位幕 ══════════ */
.act.placeholder .ph{ text-align:center; }
.ph-k{ font-size:11px; letter-spacing:.34em; color:var(--cyan); }
.ph h2{
  margin:16px 0 12px; font-size:clamp(20px,5.6vw,26px); font-weight:600; letter-spacing:.06em;
  text-shadow:0 0 30px rgba(0,200,215,.4);
}
.ph p{ margin:0; font-size:13px; color:var(--ink-dim); letter-spacing:.1em; }

/* ══════════ 合规 · 底部链接 ══════════ */
.legal{
  margin-top:40px; display:flex; gap:10px; justify-content:center; align-items:center;
  font-size:12px; color:var(--ink-dim);
}
.legal a{ border-bottom:1px solid rgba(159,179,217,.32); padding-bottom:1px; }

/* ══════════ 下载条 ══════════ */
#dlBar{
  position:fixed; z-index:55; left:0; right:0; bottom:0;
  padding:16px 18px calc(16px + var(--safe-b));
  background:linear-gradient(180deg,rgba(6,16,41,0) 0%,rgba(6,16,41,.94) 34%,rgba(6,16,41,.99) 100%);
  transform:translateY(120%);
}
.dl-btn{
  position:relative; width:100%; max-width:520px; margin:0 auto;
  display:flex; align-items:center; gap:13px;
  padding:15px 18px; border-radius:16px;
  background:linear-gradient(120deg,var(--cyan),var(--nebula) 82%);
  box-shadow:0 8px 34px rgba(0,200,215,.42),0 0 0 1px rgba(255,255,255,.16) inset;
  overflow:hidden;
}
.dl-btn::after{
  content:""; position:absolute; top:0; left:-60%; width:45%; height:100%;
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.55),transparent);
  transform:skewX(-22deg);
  animation:sheen 3.2s ease-in-out infinite;
}
@keyframes sheen{ 0%{left:-60%} 55%,100%{left:135%} }
.dl-ico{ display:grid; place-items:center; width:34px; height:34px; border-radius:50%; background:rgba(255,255,255,.18); }
.dl-ico svg{ width:19px; height:19px; fill:none; stroke:#fff; stroke-width:2; stroke-linecap:round; stroke-linejoin:round; }
.dl-txt{ display:flex; flex-direction:column; align-items:flex-start; line-height:1.28; }
.dl-txt b{ font-size:16px; letter-spacing:.05em; color:#fff; }
.dl-txt i{ font-style:normal; font-size:11.5px; color:rgba(255,255,255,.86); letter-spacing:.06em; }
.dl-note{
  margin:9px auto 0; max-width:520px; text-align:center;
  font-size:10.5px; color:var(--ink-dim); letter-spacing:.04em;
}
.dl-note a{ color:#bcd4ff; border-bottom:1px solid rgba(188,212,255,.4); }

/* ══════════ 二维码中间页 ══════════ */
.qr-page{
  position:fixed; inset:0; z-index:95;
  background:rgba(3,8,20,.94);
  backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px);
  display:flex; align-items:center; justify-content:center; padding:24px;
  animation:fade .26s var(--ease-out) both;
}
.qr-box{
  width:100%; max-width:318px; padding:26px 22px 22px; border-radius:20px;
  text-align:center;
  background:linear-gradient(160deg,rgba(18,32,64,.96),rgba(8,16,36,.98));
  border:1px solid rgba(0,200,215,.28);
  box-shadow:0 20px 60px rgba(0,0,0,.7),0 0 40px rgba(0,200,215,.18);
}
.qr-box h3{ margin:0 0 16px; font-size:16px; font-weight:600; letter-spacing:.1em; }
.qr-img{ width:192px; height:192px; margin:0 auto; background:#fff; border-radius:12px; padding:8px; }
.qr-img canvas,.qr-img img{ width:100%; height:100%; }
.qr-sub{ margin:14px 0 18px; font-size:12px; color:var(--gold); letter-spacing:.1em; }
.qr-close{
  padding:10px 30px; border-radius:999px;
  border:1px solid rgba(0,200,215,.42); color:#dff4ff; font-size:13px; letter-spacing:.14em;
}

/* ══════════ 低端机降级 ══════════ */
body.lowfx .grid{ display:none; }
body.lowfx .nebula{ display:none; }
body.lowfx .vignette{ background:radial-gradient(120% 78% at 50% 46%, transparent 52%, rgba(2,6,16,.6) 100%); }
body.lowfx .signal-wave::before,
body.lowfx .signal-wave::after{ display:none; }
body.lowfx .dl-btn::after{ display:none; }

/* ══════════ 无障碍 / 减少动效 ══════════ */
@media (prefers-reduced-motion:reduce){
  .nebula,.grid,.signal-wave::before,.signal-wave::after,.dl-btn::after,.continue,.a4-rays{ animation:none !important; }
}

/* ══════════ 横屏提示优化 ══════════ */
@media (orientation:landscape) and (max-height:520px){
  :root{ --vh-w:40vw; --vh-h:60vw; }
  .act{ padding-top:calc(40px + var(--safe-t)); padding-bottom:calc(46px + var(--safe-b)); }
  .continue{ bottom:calc(8px + var(--safe-b)); padding:8px 20px; }
}
