/* 杀青梦境 —— v21：开头引导 + 纯白梦境空间（三只吉祥物预览） */
*{margin:0;padding:0;box-sizing:border-box;-webkit-tap-highlight-color:transparent;
  -webkit-user-select:none;user-select:none}
img{-webkit-touch-callout:none;-webkit-user-drag:none}
/* 角色名专用宋体子集（3.4KB），保证手机和电脑一致 */
@font-face{font-family:"HLR Name";
  src:url("../assets/fonts/name-serif.woff2?v=46") format("woff2");
  font-weight:700;font-display:swap}
:root{
  /* 画面基准比例 = 16:9，跟原作一致（iPad 铺满宽度上下留边、
     超宽手机铺满高度左右留边）。--u = 画面高度的 1%，两处数字要一起改。 */
  --R:1.7778;
  --u:min(1dvh, 1vw / 1.7778);
}
html{background:#0b0d12;-webkit-text-size-adjust:100%}
/* body 比视口高出一截，给「上滑收地址栏」留真实滚动空间；
   盖在上面的 #gate-fs 高度必须与此绑死（坑 37 号） */
body{min-height:calc(100lvh + 45vh);overflow-x:hidden;background:#0b0d12;
  font-family:-apple-system,BlinkMacSystemFont,"PingFang SC","Microsoft YaHei",sans-serif;
  -webkit-tap-highlight-color:transparent}

/* ---------- 舞台：纯白梦境空间 ---------- */
/* #stage = 整个视口：毛玻璃补边、白空间氛围、点击区、整屏震动都在这层 */
#stage{position:fixed;left:0;right:0;top:0;height:100dvh;overflow:hidden;cursor:pointer;
  background:
    radial-gradient(120% 90% at 50% 110%, #ced3e4 0%, rgba(206,211,228,0) 58%),
    radial-gradient(90% 70% at 50% -12%, #ffffff 0%, rgba(255,255,255,0) 60%),
    linear-gradient(180deg, #ffffff 0%, #f8f9fc 48%, #e7eaf4 100%)}
/* 背景图层（毛玻璃补边 + 清晰主图）：白空间阶段为空，进场景后由 JS 填图 */
#bgblur{position:absolute;inset:calc(var(--u) * -8);background-size:cover;background-position:center;
  filter:blur(40px) saturate(1.08);transform:scale(1.08)}
#bgmain{position:absolute;inset:0;background-size:auto 100%;
  background-position:center;background-repeat:no-repeat}
#vig{position:absolute;inset:0;pointer-events:none;
  box-shadow:inset 0 0 22vmin 4vmin rgba(30,40,60,.18)}

/* 顶部柔光晕 */
#bloom{position:absolute;left:50%;top:-28%;width:120vmin;height:80vmin;
  transform:translateX(-50%);border-radius:50%;
  background:radial-gradient(closest-side, rgba(255,255,252,.95), rgba(255,255,252,0) 70%);
  filter:blur(6px)}
/* 斜向光带，压平面感 */
#ray{position:absolute;inset:-20%;
  background:linear-gradient(112deg,
    rgba(255,255,255,0) 30%, rgba(252,253,255,.5) 44%,
    rgba(255,255,255,0) 55%, rgba(250,251,255,.3) 66%, rgba(255,255,255,0) 78%);
  mix-blend-mode:screen}

/* 场景层（全视口：毛玻璃补边 + 白空间氛围） */
#scene{position:absolute;inset:0}
/* #view = 画面盒：锁死 16:9（原作基准），按短边等比缩放居中、尽量占满。
   立绘/对话框/选项/浮字全部锚在它上面，所以 iPad 这种方屏版式也不会变形；
   画面盒之外露出的部分由底下的 #bgblur 毛玻璃补满（横竖都补）。 */
#view{position:absolute;left:50%;top:50%;
  height:calc(var(--u) * 100);width:calc(var(--u) * 100 * var(--R));
  margin-top:calc(var(--u) * -50);margin-left:calc(var(--u) * -50 * var(--R));
  overflow:hidden}
/* 震动加在 #stage 上（整屏，背景一起动）；
   平移会露屏幕边，所以震动期间整体微放大兜住边缘 */
#stage.shake{animation:cam-shake .5s linear}
@keyframes cam-shake{
  0%{transform:translate(0,0) scale(1)}
  12%{transform:translate(calc(var(--u) * -1.8),calc(var(--u) * 1)) scale(1.035)}
  28%{transform:translate(calc(var(--u) * 1.6),calc(var(--u) * -1.3)) scale(1.035)}
  44%{transform:translate(calc(var(--u) * -1.3),calc(var(--u) * -.8)) scale(1.03)}
  60%{transform:translate(calc(var(--u) * 1.1),calc(var(--u) * .9)) scale(1.03)}
  76%{transform:translate(calc(var(--u) * -.6),calc(var(--u) * .4)) scale(1.02)}
  90%{transform:translate(calc(var(--u) * .3),calc(var(--u) * -.2)) scale(1.01)}
  100%{transform:translate(0,0) scale(1)}
}

/* 睁眼动画：中央一个椭圆「瞳孔洞」用 scaleY 撑开（中间先开、两侧后开），
   洞外的黑由超大 box-shadow 铺满，边缘用 shadow 模糊羽化。
   纯 transform + box-shadow，iOS 安全（mask 方案会翻车，两片眼睑方向会反）。 */
#lid{position:absolute;inset:0;z-index:14;pointer-events:none;overflow:hidden;
  background:#000}
/* 注意：不能用 scaleY——transform 会连 box-shadow 的覆盖范围一起缩，
   缝隙小时上下露白（真机踩过）。直接动画 height，阴影恒定铺满。 */
#lid .iris{position:absolute;left:50%;top:50%;width:164%;height:.4%;
  border-radius:50%;
  transform:translate(-50%,-50%);
  box-shadow:inset 0 0 calc(var(--u) * 9) calc(var(--u) * 3) rgba(0,0,0,.85), 0 0 calc(var(--u) * 7) 200vmax #000}
#lid.open{background:transparent}
#lid.open .iris{animation:iris 3.8s ease-in-out forwards}
@keyframes iris{
  0%{height:.4%}
  28%{height:46%}
  46%{height:8%}
  58%{height:11%}
  100%{height:300%}
}
#lid.off{display:none}

/* 异界感：漂浮光尘，六粒，模糊小圆点慢慢上飘 */
#fx{position:absolute;inset:0;overflow:hidden;pointer-events:none}
#fx i{position:absolute;display:block;border-radius:50%;
  background:radial-gradient(closest-side, rgba(255,255,255,.95), rgba(214,219,240,.4) 60%,
    rgba(255,255,255,0) 100%);
  filter:blur(1px);bottom:calc(var(--u) * -6);
  animation:drift linear infinite}
#fx i:nth-child(1){left:12%;width:calc(var(--u) * 2.2);height:calc(var(--u) * 2.2);animation-duration:19s}
#fx i:nth-child(2){left:28%;width:calc(var(--u) * 1.3);height:calc(var(--u) * 1.3);animation-duration:26s;animation-delay:-9s}
#fx i:nth-child(3){left:45%;width:calc(var(--u) * 1.8);height:calc(var(--u) * 1.8);animation-duration:22s;animation-delay:-15s}
#fx i:nth-child(4){left:62%;width:calc(var(--u) * 1.1);height:calc(var(--u) * 1.1);animation-duration:29s;animation-delay:-4s}
#fx i:nth-child(5){left:78%;width:calc(var(--u) * 2);height:calc(var(--u) * 2);animation-duration:21s;animation-delay:-12s}
#fx i:nth-child(6){left:90%;width:calc(var(--u) * 1.4);height:calc(var(--u) * 1.4);animation-duration:25s;animation-delay:-20s}
@keyframes drift{
  0%{transform:translateY(0);opacity:0}
  12%{opacity:.8}
  85%{opacity:.5}
  100%{transform:translateY(calc(var(--u) * -118));opacity:0}
}

/* 异界感：底部白雾，抹掉地平线，空间无边界 */
#mist{position:absolute;left:-5%;right:-5%;bottom:calc(var(--u) * -4);height:calc(var(--u) * 34);
  background:linear-gradient(180deg, rgba(255,255,255,0) 0%, rgba(255,255,255,.55) 46%,
    rgba(250,251,255,.9) 100%);
  filter:blur(8px)}

/* ---------- 三只吉祥物 ---------- */
/* 高度 = 裁切高/1640 × K，K=1.0；同源画布保画师体型比 */
/* 悬浮在画面中层（对话框之上），静止，不落地不投影——对齐原作吉祥物演出
   站位由 JS 写 left/bottom（slot 系统），带过渡以支持「排好队」滑移 */
.mascots{position:absolute;left:0;right:0;bottom:0;top:0;pointer-events:none}
.m{position:absolute;transform:translateX(-50%);
  transition:left .8s cubic-bezier(.5,1.4,.5,1), bottom .8s ease, opacity .85s ease}
.m img{display:block;height:100%}
.m.hid{opacity:0}
#m-bajiu{left:50%;height:calc(var(--u) * 70);bottom:calc(var(--u) * 24)}
#m-feiyi{left:25%;height:calc(var(--u) * 34);bottom:calc(var(--u) * 36)}
#m-zuozuo{left:75%;height:calc(var(--u) * 34.5);bottom:calc(var(--u) * 35)}
/* 三人线：单人居中，半身立绘贴底（中央交替模式的位子） */
#m-npc{left:50%;height:calc(var(--u) * 100);bottom:0}
/* 说话起头轻跳一下（参考立绘跳动.mov） */
.m.hop img{animation:hop .32s ease-out}
@keyframes hop{0%{transform:translateY(0)}45%{transform:translateY(calc(var(--u) * -2.4))}100%{transform:translateY(0)}}
/* 被撞（向右弹）：先向右歪再回正的挣扎 */
.m.knock img{animation:knock .7s ease-out}
@keyframes knock{
  0%{transform:rotate(0)}
  25%{transform:rotate(14deg)}
  55%{transform:rotate(-9deg)}
  80%{transform:rotate(4deg)}
  100%{transform:rotate(0)}
}
/* 入场：纯淡入（.hid 的 opacity 过渡），不加位移 */
/* 撞入：从左侧冲进来带一点回弹（浮现要快，不吃慢淡入） */
.m.slam-in{transition:left .8s cubic-bezier(.5,1.4,.5,1), bottom .8s ease, opacity .22s ease}
.m.slam-in img{animation:slam-in .5s cubic-bezier(.3,1.5,.55,1)}
@keyframes slam-in{0%{transform:translateX(calc(var(--u) * -16))}100%{transform:translateX(0)}}
/* 非说话人压暗蒙层：只作用于立绘 */
.m.dim img{filter:brightness(.62) saturate(.92);transition:filter .35s ease}
.m img{transition:filter .35s ease}

/* ---------- 对话框（v20 原样保留：整屏手绘素材 + 百分比锚点） ---------- */
/* 对话框素材按「画面盒高度」贴合，不是按宽度——16:9 比素材自身的 2.1679 窄，
   按宽度缩会矮 18%。横向溢出的部分由 #view 裁掉，素材左右各 10% 是透明淡出区
   （墨迹只在 10.4%~89.8%），可见窗口是中间 82%，一点画都不会切到。 */
#box{position:absolute;left:50%;bottom:0;transform:translateX(-50%);
  height:100%;width:calc(var(--u) * 216.79);pointer-events:none;
  opacity:0;transition:opacity .45s ease .15s}
#box.in{opacity:1}
#frame{display:block;width:100%;height:auto;pointer-events:none}
#name-t{position:absolute;left:20%;top:73.5%;width:19%;
  transform:translateY(-50%) skewX(-8deg);
  text-align:center;line-height:1;
  color:#453e37;font-size:calc(var(--u) * 3.95);letter-spacing:.06em;
  font-family:"HLR Name","Songti SC",serif;font-weight:700;
  -webkit-font-smoothing:antialiased;
  text-shadow:0 1px 2px rgba(255,255,255,.8),0 0 8px rgba(255,255,255,.6)}
#line{position:absolute;left:22%;right:19%;top:79.2%;
  color:#4a3f38;font-size:calc(var(--u) * 3.56);line-height:1.62;letter-spacing:.02em;
  font-family:-apple-system,"PingFang SC","Noto Sans CJK SC",sans-serif;font-weight:400;
  -webkit-font-smoothing:antialiased;
  text-shadow:0 1px 2px rgba(255,255,255,.85)}
#line.big{font-size:calc(var(--u) * 4.9);line-height:1.5}   /* 单句加大：t 节点带 big:true */
#tip{position:absolute;right:14%;top:90.5%;width:1.7em;height:.9em;
  font-size:calc(var(--u) * 3.56);color:#6b4136;
  opacity:0;animation:tip-bob 2.2s ease-in-out infinite}
#tip.on{opacity:.75}
@keyframes tip-bob{0%,100%{transform:translateX(0)}50%{transform:translateX(3px)}}
#ava{position:absolute;left:12.5%;bottom:5%;height:27%;display:none;
  filter:drop-shadow(0 1px 6px rgba(20,28,44,.3));
  -webkit-mask-image:linear-gradient(180deg,#000 76%,transparent 98%);
  mask-image:linear-gradient(180deg,#000 76%,transparent 98%)}
#stage.listen #ava{display:block}

/* ---------- 选项 ---------- */
/* 选项浮层：容器铺满「画面顶部→对话框上沿」区域（素材实测上沿在 76%），
   内部 flex 居中——任意条数都自动在该区域垂直居中（对齐原作） */
#choices{position:absolute;left:50%;top:0;height:calc(var(--u) * 76);transform:translateX(-50%);
  display:none;flex-direction:column;gap:calc(var(--u) * 2.6);align-items:center;justify-content:center;
  z-index:10;min-width:44%}
#choices.on{display:flex}
/* 没有对话框时（浮现文字段落里的选项），容器改成铺满整屏再居中，
   否则还按「顶部→名牌线 calc(var(--u) * 72)」算会整体偏上 */
#choices.nobox{height:calc(var(--u) * 100)}
#choices button{font:inherit;font-size:calc(var(--u) * 3.2);letter-spacing:.14em;text-indent:.14em;
  color:#3d4152;background:rgba(255,255,255,.66);
  border:1px solid rgba(120,128,160,.45);border-radius:2.2em;
  padding:.72em 3em;min-width:100%;cursor:pointer;
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
  box-shadow:0 2px 14px rgba(120,128,168,.18);
  animation:choice-in .4s ease-out backwards}
#choices button:nth-child(2){animation-delay:.08s}
#choices button:nth-child(3){animation-delay:.16s}
#choices button:nth-child(4){animation-delay:.24s}
#choices button:active{background:rgba(255,255,255,.92)}
@keyframes choice-in{0%{opacity:0;transform:translateY(calc(var(--u) * 1.6))}100%{opacity:1;transform:translateY(0)}}

/* ---------- HUD：◇ 按钮（仿原作：旋转 45° 的圆角方块里放图标） ---------- */
#hud-r{position:absolute;right:2%;top:4.2%;z-index:12;
  display:flex;gap:calc(var(--u) * 4.4)}
.hud{position:relative;width:calc(var(--u) * 7);height:calc(var(--u) * 7);
  background:none;border:none;padding:0;cursor:pointer;color:#5a5468}
.hud::before{content:'';position:absolute;inset:9%;
  transform:rotate(45deg);border-radius:26%;
  background:rgba(252,252,255,.82);
  border:1px solid rgba(112,106,140,.5);
  box-shadow:0 calc(var(--u) * .4) calc(var(--u) * 1.6) rgba(50,44,80,.25),
    inset 0 1px 0 rgba(255,255,255,.9)}
.hud svg{position:absolute;left:50%;top:50%;width:56%;height:56%;
  transform:translate(-50%,-50%);fill:currentColor}
.hud:active::before{background:#fff}
.hud.lock{color:#b0adbc;cursor:default}
.hud.lock::before{background:rgba(235,235,240,.55);
  border-color:rgba(140,136,160,.3);box-shadow:none}
/* 喇叭：静音时藏声波、出叉 */
#hud-snd .x{display:none}
#hud-snd.off .w{display:none}
#hud-snd.off .x{display:block}
/* 左上：留言板 + 操作说明 */
#hud-l{position:absolute;left:2%;top:4.2%;z-index:12;
  display:flex;gap:calc(var(--u) * 4.4)}

/* ---------- 确认对话框 ---------- */
#dlg{position:absolute;inset:0;z-index:13;display:none;
  align-items:center;justify-content:center;
  background:rgba(14,10,26,.32)}
#dlg.on{display:flex;animation:choice-in .3s ease-out}
#dlg-in{min-width:38%;max-width:70%;padding:calc(var(--u) * 5) calc(var(--u) * 7);
  border-radius:calc(var(--u) * 2.4);text-align:center;
  background:rgba(252,252,255,.9);border:1px solid rgba(120,114,150,.4);
  box-shadow:0 calc(var(--u) * 1.5) calc(var(--u) * 6) rgba(30,24,60,.35);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px)}
#dlg-t{font-size:calc(var(--u) * 3.4);letter-spacing:.12em;line-height:1.9;color:#3d3850}
#dlg-b{display:flex;gap:calc(var(--u) * 3);justify-content:center;
  margin-top:calc(var(--u) * 4)}
#dlg-b button{font:inherit;font-size:calc(var(--u) * 3);letter-spacing:.18em;text-indent:.18em;
  border-radius:2.2em;padding:.5em 2.2em;cursor:pointer;
  color:#4a4456;background:rgba(255,255,255,.8);
  border:1px solid rgba(120,128,160,.5)}
#dlg-b button.pri{color:#fff;background:linear-gradient(180deg,#a39ddc,#8a84c8);
  border-color:rgba(255,255,255,.5)}
#stage.dark #dlg-in{background:rgba(30,24,56,.88);border-color:rgba(214,208,255,.35)}
#stage.dark #dlg-t{color:#ece9f6}
#stage.dark #dlg-b button{color:#ece9f6;background:rgba(26,20,48,.6);
  border-color:rgba(214,208,255,.4)}
#stage.dark #dlg-b button.pri{color:#fff;background:linear-gradient(180deg,#8a84c8,#6f68b0)}

/* ---------- 浮现文字（*…*：无对话框、画面中央） ---------- */
#float-t{position:absolute;left:50%;top:42%;transform:translate(-50%,-50%);
  z-index:9;width:80%;text-align:center;color:#565b6e;
  font-size:calc(var(--u) * 3);line-height:2.1;letter-spacing:.14em;
  text-shadow:0 0 12px rgba(255,255,255,.9);
  opacity:0;transition:opacity .8s ease;pointer-events:none}
#float-t.on{opacity:1}

/* ---------- 三扇门：白乎乎发光的漩涡 ---------- */
#doors{position:absolute;inset:0;pointer-events:none;opacity:0;transition:opacity 1s ease}
#doors.on{opacity:1}
.dv{position:absolute;top:40%;width:calc(var(--u) * 32);height:calc(var(--u) * 32);
  transform:translate(-50%,-50%);
  /* 外圈光环，随呼吸微微起伏 */
  background:radial-gradient(closest-side, rgba(255,255,255,0) 46%,
    rgba(168,177,222,.52) 58%, rgba(255,255,255,0) 70%);
  animation:dv-breathe 5.2s ease-in-out infinite}
#d1{left:25%} #d2{left:50%;animation-delay:-1.7s} #d3{left:75%;animation-delay:-3.4s}
/* 亮核心：白洞的光 */
.dv::before{content:'';position:absolute;inset:-14%;border-radius:50%;
  background:radial-gradient(closest-side, #fff 0%, rgba(250,251,255,.96) 20%,
    rgba(208,214,242,.5) 46%, rgba(255,255,255,0) 74%)}
/* 旋转的柔雾：大模糊双瓣光晕，看不出形状只看得出在流动 */
.dv::after{content:'';position:absolute;inset:2%;border-radius:50%;
  background:conic-gradient(from 0deg,
    rgba(146,156,210,.46) 0deg, rgba(146,156,210,.07) 100deg,
    rgba(157,167,216,.4) 180deg, rgba(146,156,210,.07) 275deg,
    rgba(146,156,210,.46) 360deg);
  filter:blur(11px);
  animation:dv-spin 11s linear infinite}
#d2::after{animation-duration:8.5s;animation-direction:reverse}
#d3::after{animation-duration:13s}
@keyframes dv-spin{to{transform:rotate(360deg)}}
@keyframes dv-breathe{0%,100%{opacity:.8}50%{opacity:1}}

/* ---------- 顶部提示条 ---------- */
#swipe{position:fixed;left:50%;top:8px;transform:translateX(-50%);z-index:8;
  background:rgba(20,24,32,.72);color:#e6ebf2;font-size:11.5px;letter-spacing:.04em;
  padding:5px 12px;border-radius:14px;transition:opacity .6s ease;pointer-events:none;opacity:0}
#swipe.on{opacity:1} #swipe.gone{opacity:0}

/* ---------- 门/遮罩通用 ---------- */
.gate{position:fixed;inset:0;height:100dvh;z-index:20;display:none;
  flex-direction:column;align-items:center;justify-content:center;gap:1.2em;
  background:#0e1118;color:#cbd3e1;text-align:center;padding:2em;
  font-size:15px;line-height:2}
.gate.on{display:flex}
.gate .sub{font-size:12.5px;color:#7d8595;line-height:1.8}
.gate button{font:inherit;font-size:14px;color:#e6ebf2;background:rgba(255,255,255,.08);
  border:1px solid rgba(255,255,255,.28);border-radius:2em;padding:.55em 2.2em;cursor:pointer}
.gate button:active{background:rgba(255,255,255,.18)}
.gate .skip{border-color:transparent;color:#6b7383;font-size:12.5px;padding:.4em 1.5em}

#rot{z-index:40}
@media(orientation:portrait){#rot.armed{display:flex}}

/* 上滑引导门不用 fixed：跟随文档滚动，手指一划门会真的动，
   iOS 才有跟手反馈、地址栏也才收得起来。
   高度必须盖满 body 的 min-height：iOS 会在脚本执行后异步恢复
   scrollY，门若只有一屏高就会被顶上去露出 body 背景（坑 37 号）。
   文字用 sticky 内层钉在视口居中，滚到哪都看得见。 */
#gate-fs{position:absolute;top:0;left:0;right:0;bottom:auto;
  height:calc(100lvh + 45vh);padding:0}
#gate-fs.on{display:block}
#fs-in{position:sticky;top:0;height:100dvh;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:1.2em;padding:2em;text-align:center}

/* 上滑手势动画：细长胶囊里一颗小点往上飘，只在 iPhone 引导文案时显示 */
#fs-hand{display:none;width:30px;height:64px;position:relative;
  border:1.5px solid rgba(255,255,255,.35);border-radius:15px}
#fs-hand.on{display:block}
#fs-hand::after{content:'';position:absolute;left:50%;width:7px;height:7px;
  margin-left:-3.5px;border-radius:50%;background:#e6ebf2;
  animation:fs-up 1.6s ease-in-out infinite}
@keyframes fs-up{
  0%{top:42px;opacity:0}
  25%{opacity:1}
  70%{top:11px;opacity:1}
  100%{top:11px;opacity:0}
}

#disc{gap:.4em;letter-spacing:.08em}
#disc .brand{color:#8d97ab;font-size:12.5px;margin-top:2.2em}
/* 声明读完后浮出的提示：浅浅的、缓缓闪动 */
#disc-hint{margin-top:1.6em;font-size:11.5px;letter-spacing:.22em;text-indent:.22em;
  color:#6b7383;opacity:0;transition:opacity 1.2s ease}
#disc-hint.on{animation:hint-pulse 2.6s ease-in-out .9s infinite;opacity:.2}
@keyframes hint-pulse{0%,100%{opacity:.2}50%{opacity:.62}}

/* ---------- 第二扇门：暗场景（背景图取代白空间） ---------- */
#bgblur,#bgmain{opacity:0;transition:opacity 1.1s ease}
/* .dark = 有背景图 + 暗色 UI（星空、夜房间）；.lit = 有背景图 + 亮色 UI（白天房间） */
#stage.dark #bgblur,#stage.dark #bgmain,
#stage.lit #bgblur,#stage.lit #bgmain{opacity:1}
#bloom,#ray,#mist,#fx{transition:opacity .9s ease}
#stage.dark #bloom,#stage.dark #ray,#stage.dark #mist,#stage.dark #fx,
#stage.lit #bloom,#stage.lit #ray,#stage.lit #mist,#stage.lit #fx{opacity:0}
#stage.dark{background:#0a0812}
#stage.lit{background:#cfd8e2}
/* 暗场景下的选项药丸：白药丸在星空上会糊成一片 */
#stage.dark #choices button{color:#ece9f6;background:rgba(26,20,48,.52);
  border-color:rgba(214,208,255,.42);box-shadow:0 2px 16px rgba(0,0,0,.4)}
#stage.dark #choices button:active{background:rgba(52,42,90,.8)}

/* 白光吞没：一次性全屏闪白 */
/* 场景之间的黑色交叉渐变 */
#fade{position:absolute;inset:0;z-index:19;background:#000;opacity:0;pointer-events:none;
  transition:opacity .75s ease}
#fade.on{opacity:1}
#flash{position:absolute;inset:0;z-index:20;background:#fff;opacity:0;pointer-events:none}
#flash.on{animation:flash-white 1.5s ease-out}
@keyframes flash-white{0%{opacity:0}18%{opacity:1}45%{opacity:1}100%{opacity:0}}

/* ---------- 浮现文字序列（*…*：无对话框、画面中央、点击逐句推进） ----------
   取值照《文字浮现》参考图量：单行居中在画面 50% 高；长文左对齐、
   左右 16%/84%，整块垂直居中，逐句浮出后整段一起淡出。 */
/* 出字期间的黑蒙层：星空背景太花，白字压不住（一整段浮现流程里常驻，
   不随每条文字开关，否则连着好几条时会一闪一闪） */
#ftx-dim{position:absolute;inset:0;z-index:9;pointer-events:none;
  background:rgba(6,4,14,.58);opacity:0;transition:opacity .8s ease}
#ftx-dim.on{opacity:1}
#ftx{position:absolute;inset:0;z-index:11;pointer-events:none;display:none}
#ftx.on{display:block}
#ftx-in{position:absolute;left:50%;top:46%;transform:translate(-50%,-50%);
  width:80%;color:#f2f0ea;
  font-family:"HLR Name","Songti SC","Noto Serif SC",serif;
  font-size:calc(var(--u) * 4.6);line-height:1.95;letter-spacing:.08em;
  text-shadow:0 0 10px rgba(255,255,255,.26),0 2px 12px rgba(0,0,0,.55)}
/* 单行、多行一律居中：台本里的句子都短，左对齐两行很难看 */
#ftx-in{text-align:center;text-indent:.08em}
#ftx-in p{margin:0;opacity:0;transform:translateY(12px);
  transition:opacity .9s ease,transform .9s ease}
#ftx-in p.on{opacity:1;transform:translateY(0)}
#ftx-in p.snap{transition:none}                 /* 浮入途中点击=立刻到位 */
#ftx.out #ftx-in p{opacity:0;transition:opacity .45s ease}   /* 整段淡出 */
#ftx-in p.big-red{color:#c2452e;font-weight:700;font-size:1.5em;line-height:1.5}
#ftx-tip{position:absolute;left:50%;bottom:calc(var(--u) * 6);transform:translateX(-50%);
  color:#fff;font-size:calc(var(--u) * 2.2);letter-spacing:.18em;opacity:0}
#ftx-tip.on{animation:ftx-blink 2.2s ease-in-out infinite}
@keyframes ftx-blink{0%,100%{opacity:.72}50%{opacity:.28}}
/* 暗场景下的占位/结语浮字 */
#stage.dark #float-t{color:#ece9f6;text-shadow:0 0 14px rgba(0,0,0,.85)}

/* 结语/占位画面：浮字与按钮各让一块，否则按钮压在字上 */
#stage.fin #float-t{top:30%}
#stage.fin #choices{top:calc(var(--u) * 44);height:calc(var(--u) * 52)}

/* ---------- NPC 点名选择器 ---------- */
/* 点名时画面上没有对话框，面板按整屏垂直居中；
   纵向单列对称：标题→输入框→候选一行→见面按钮 */
#namer{position:absolute;left:50%;top:0;height:calc(var(--u) * 100);transform:translateX(-50%);
  width:calc(var(--u) * 92);display:none;flex-direction:column;align-items:center;
  justify-content:center;gap:calc(var(--u) * 4.6);z-index:11}
#namer.on{display:flex;animation:namer-in .45s ease-out}
/* Keep horizontal centering throughout the entrance animation. */
@keyframes namer-in{
  0%{opacity:0;transform:translate(-50%,calc(var(--u) * 1.6))}
  100%{opacity:1;transform:translate(-50%,0)}
}
.nm-prompt{font-family:"HLR Name","Songti SC",serif;font-weight:700;
  font-size:calc(var(--u) * 4.2);letter-spacing:.3em;text-indent:.3em;
  color:#4a4456;text-shadow:0 0 calc(var(--u) * 2) rgba(255,255,255,.8)}
#nm-input{width:calc(var(--u) * 58);
  font:inherit;font-size:max(16px, calc(var(--u) * 3.4));  /* 16px 底线防 iOS 聚焦自动放大 */
  letter-spacing:.1em;text-align:center;color:#3d4152;
  background:rgba(255,255,255,.7);border:1px solid rgba(120,128,160,.5);
  border-radius:2.2em;padding:.55em 1.4em;outline:none;caret-color:#8a84c8;
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
  box-shadow:0 2px 14px rgba(120,128,168,.18), inset 0 1px 0 rgba(255,255,255,.6);
  transition:border-color .25s ease, box-shadow .25s ease}
#nm-input:focus{border-color:rgba(138,132,200,.8);
  box-shadow:0 2px 18px rgba(138,132,200,.3), inset 0 1px 0 rgba(255,255,255,.6)}
#nm-input::placeholder{color:#a6abbc;letter-spacing:.14em}
#nm-go{font:inherit;font-size:max(15px, calc(var(--u) * 3.2));letter-spacing:.3em;text-indent:.3em;
  color:#fff;background:linear-gradient(180deg, #a39ddc, #8a84c8);
  border:1px solid rgba(255,255,255,.5);border-radius:2.2em;padding:.55em 3.4em;
  cursor:pointer;box-shadow:0 2px 14px rgba(138,132,200,.4);
  margin-top:calc(var(--u) * 1.6);
  transition:opacity .25s ease, filter .25s ease}
#nm-go:active{filter:brightness(1.12)}
#nm-go:disabled{background:rgba(150,153,165,.4);border-color:rgba(255,255,255,.3);
  color:rgba(255,255,255,.75);box-shadow:none;cursor:default}
/* 提示不占布局空间：高度 0、文字溢出到输入框和候选之间的间隙里，
   出现/消失都不会顶动别的元素 */
.nm-hint{height:0;overflow:visible;line-height:1;
  display:flex;justify-content:center;align-items:flex-start;
  transform:translateY(calc(var(--u) * -1.9));
  font-size:calc(var(--u) * 2.6);letter-spacing:.16em;color:#9a90a8;
  opacity:0;transition:opacity .3s ease}
.nm-hint.on{opacity:.9}
.nm-list{display:flex;flex-wrap:nowrap;justify-content:center;
  gap:calc(var(--u) * 2.6);width:100%;min-height:calc(var(--u) * 8)}
.nm-list button{font:inherit;font-size:calc(var(--u) * 3.2);letter-spacing:.18em;text-indent:.18em;
  font-family:"HLR Name","Songti SC",serif;font-weight:700;
  color:#4a4456;background:rgba(255,255,255,.62);
  border:1px solid rgba(120,128,160,.45);border-radius:2.2em;
  padding:.5em 1.8em;cursor:pointer;
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
  box-shadow:0 2px 12px rgba(120,128,168,.16);
  animation:choice-in .35s ease-out backwards;
  transition:background .25s ease, border-color .25s ease, box-shadow .25s ease}
.nm-list button:nth-child(2){animation-delay:.06s}
.nm-list button:nth-child(3){animation-delay:.12s}
.nm-list button:nth-child(4){animation-delay:.18s}
.nm-list button.sel{background:rgba(255,255,255,.95);border-color:#8a84c8;
  box-shadow:0 0 0 calc(var(--u) * .35) rgba(138,132,200,.35), 0 2px 16px rgba(138,132,200,.35)}

/* 暗色场景（星空）下的配色 */
#stage.dark .nm-prompt{color:#ece9f6;text-shadow:0 0 calc(var(--u) * 2.4) rgba(120,110,200,.6)}
#stage.dark #nm-input{color:#ece9f6;background:rgba(26,20,48,.55);
  border-color:rgba(214,208,255,.42);box-shadow:0 2px 16px rgba(0,0,0,.4)}
#stage.dark #nm-input::placeholder{color:#8d87a8}
#stage.dark .nm-hint{color:#b0a8cc}
#stage.dark .nm-list button{color:#ece9f6;background:rgba(26,20,48,.52);
  border-color:rgba(214,208,255,.42);box-shadow:0 2px 16px rgba(0,0,0,.4)}
#stage.dark .nm-list button.sel{background:rgba(70,58,120,.85);border-color:#cfc8ff;
  box-shadow:0 0 0 calc(var(--u) * .35) rgba(190,182,255,.4), 0 0 calc(var(--u) * 3) rgba(150,140,230,.5)}

/* 暗场景下 HUD 保持白钻（原作在暗景也是白色系按钮），只调阴影 */
#stage.dark .hud::before{box-shadow:0 calc(var(--u) * .4) calc(var(--u) * 2) rgba(0,0,0,.5),
  inset 0 1px 0 rgba(255,255,255,.9)}
