/* ============================================================
   探索 · EXPLORER-01
   一套仪器(HUD)和一批粒子贯穿全程，穿过每个世界时不消失、只换画法。
   ============================================================ */

:root{
  /* 字体：中文用宋体系做editorial大字，HUD用 Bahnschrift 窄体，代码用等宽 */
  --f-serif:"Source Han Serif SC","Noto Serif SC","Songti SC","STSong","SimSun",serif;
  --f-sans:"PingFang SC","Microsoft YaHei","Hiragino Sans GB","Noto Sans SC",sans-serif;
  --f-mono:"Cascadia Mono","JetBrains Mono","SFMono-Regular","Consolas","Menlo",monospace;
  --f-disp:"Bahnschrift","DIN Alternate","Oswald","Haettenschweiler",sans-serif;

  /* 这三个变量由 JS 每帧插值写入 —— 颜色永远在流动，没有一次硬切 */
  --bg:#05060B;
  --ink:#E8E6E0;
  --accent:#8FA6C9;

  --hud-w:1px;          /* HUD 线宽，按层变化 */
  --hud-r:0px;          /* HUD 圆角，按层变化 */
  --hud-f:var(--f-mono);
  --gutter:clamp(18px,4vw,56px);
  --ease:cubic-bezier(.16,.84,.34,1);
}

*{margin:0;padding:0;box-sizing:border-box}
/* Lenis 接管滚动时必须关掉原生平滑滚动，否则两套动画会打架 */
html.lenis,html.lenis body{height:auto}
html.lenis-smooth{scroll-behavior:auto!important}
body{
  background:var(--bg);
  color:var(--ink);
  font-family:var(--f-sans);
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
  cursor:none;
}
@media (hover:none){body{cursor:auto}}

/* ---------- 固定层 ---------- */
#bg{position:fixed;inset:0;background:var(--bg);z-index:-2;transition:background .35s linear}
#field{position:fixed;inset:0;width:100%;height:100%;z-index:-1;display:block}

#vignette{position:fixed;inset:0;z-index:1;pointer-events:none;
  background:radial-gradient(120% 90% at 50% 45%,transparent 35%,rgba(0,0,0,.42) 100%);
  opacity:var(--vig,1);transition:opacity .5s linear}

#grain{position:fixed;inset:-50%;z-index:2;pointer-events:none;opacity:.28;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.55'/%3E%3C/svg%3E");
  animation:grainShift 700ms steps(2) infinite}
@keyframes grainShift{0%{transform:translate(0,0)}50%{transform:translate(-2%,1.5%)}100%{transform:translate(1%,-1%)}}

/* CRT 扫描线：只在像素纪出现，靠 --scan 连续淡入淡出 */
#scan{position:fixed;inset:0;z-index:2;pointer-events:none;opacity:var(--scan,0);
  background:repeating-linear-gradient(to bottom,rgba(0,0,0,.34) 0 1px,transparent 1px 3px);
  transition:opacity .4s linear}

/* 自定义光标：跟着走完全程，只是形状随层变化 */
#cursor{position:fixed;top:0;left:0;z-index:60;pointer-events:none;
  width:22px;height:22px;margin:-11px 0 0 -11px;
  border:1.5px solid var(--accent);border-radius:50%;
  color:var(--accent);
  transition:width .3s,height .3s,border-radius .3s,opacity .3s,border-width .3s;mix-blend-mode:difference}
#cursor::before,#cursor::after{content:"";position:absolute;left:50%;top:50%;
  background:currentColor;opacity:0;transition:opacity .3s}
#cursor::before{width:14px;height:1px;transform:translate(-50%,-50%)}
#cursor::after{width:1px;height:14px;transform:translate(-50%,-50%)}
/* 深空层只允许白核信号使用圆形脉冲；鼠标退成测量十字，避免被读成第二颗目标。 */
html[data-ch="2"] #cursor{width:16px;height:16px;margin:-8px 0 0 -8px;
  border-width:0;border-radius:0;opacity:.42;mix-blend-mode:normal}
html[data-ch="2"] #cursor::before,html[data-ch="2"] #cursor::after{opacity:1}
@media (hover:none){#cursor{display:none}}

/* ---------- 探测器：唯一贯穿七层的形象 ---------- */
#probe{position:fixed;z-index:8;pointer-events:none;overflow:visible;
  width:var(--pw,120px);height:var(--pw,120px);
  left:var(--px,50%);top:var(--py,50%);margin:calc(var(--pw,120px) / -2) 0 0 calc(var(--pw,120px) / -2);
  transition:left 1.1s var(--ease),top 1.1s var(--ease),width 1.1s var(--ease),
             margin 1.1s var(--ease),opacity .6s linear}
.pb-hull{fill:var(--bg);stroke:var(--ink);stroke-width:2}
.pb-panel{fill:none;stroke:var(--accent);stroke-width:1.6}
.pb-eye{fill:var(--accent);opacity:.22;stroke:var(--accent);stroke-width:1.4}
.pb-pupil{fill:var(--ink)}
.pb-ant{stroke:var(--ink);stroke-width:1.6}
.pb-tip{fill:var(--accent);animation:blink 1.7s steps(2) infinite}
.pb-ring{fill:none;stroke:var(--accent);stroke-width:.9;opacity:.34}
.pb-rings{animation:spin 26s linear infinite;transform-origin:0 0}
/* 每层给它一个位置：序里居中当主角，途中退到边上当旁观者，终章再回到中间 */
html[data-ch="0"]{--px:50%;--py:56%;--pw:112px}
html[data-ch="1"]{--px:88%;--py:74%;--pw:78px}
html[data-ch="2"]{--px:82%;--py:76%;--pw:58px}
html[data-ch="3"]{--px:82%;--py:20%;--pw:84px}
html[data-ch="4"]{--px:89%;--py:78%;--pw:72px}
html[data-ch="5"]{--px:14%;--py:22%;--pw:80px}
html[data-ch="6"]{--px:39%;--py:25%;--pw:84px}
/* 神经纪那屏中间是字，让它躲开 */
html[data-ch="4"] #probe{opacity:.22}
/* 深空纪里探测器只是远处的监听端，不再与信号争夺主角位置。 */
html[data-ch="2"] #probe{opacity:.16}
html[data-ch="2"] #probe .pb-rings{opacity:0}

/* ---------- HUD ---------- */
.hud{position:fixed;z-index:50;font-family:var(--hud-f);font-size:11px;letter-spacing:.16em;
  color:var(--ink);text-transform:uppercase;opacity:.82;
  transition:color .35s linear,font-family .2s,opacity 1.45s var(--ease)}
.hud-tl{top:var(--gutter);left:var(--gutter);display:flex;gap:.6em;align-items:baseline}
.hud-id{color:var(--accent)}
.hud-sep{opacity:.4}
.hud-now{font-family:var(--f-sans);letter-spacing:.3em;font-size:10px}
.hud-tr{top:var(--gutter);right:var(--gutter);display:flex;gap:.45em;align-items:baseline}
.hud-tr .hud-k{opacity:.5}
.hud-tr .hud-v{font-family:var(--f-disp);font-size:19px;letter-spacing:.06em;
  font-variant-numeric:tabular-nums;color:var(--accent)}
.hud-tr .hud-u{opacity:.5;font-size:9px}
/* SIG / 记录：全程只减 / 只增的那条曲线 */
.hud-sig{top:calc(var(--gutter) + 34px);right:var(--gutter);
  display:flex;flex-direction:column;gap:7px;align-items:flex-end}
.sig-row{display:flex;gap:.6em;align-items:center}
.sig-bar{width:74px;height:4px;border:var(--hud-w) solid color-mix(in srgb,var(--ink) 40%,transparent);
  position:relative;border-radius:var(--hud-r)}
.sig-bar b{position:absolute;left:0;top:0;bottom:0;display:block;background:var(--accent);
  width:var(--sig,100%);transition:width .25s linear}
.sig-n{font-family:var(--f-disp);font-size:12px;letter-spacing:.06em;
  font-variant-numeric:tabular-nums;color:var(--accent)}
.sig-dots{display:flex;gap:4px}
.sig-dots i{width:6px;height:6px;border:1px solid color-mix(in srgb,var(--ink) 50%,transparent);
  border-radius:var(--hud-r);display:block;transition:background .4s,border-color .4s}
.sig-dots i.on{background:var(--accent);border-color:var(--accent)}
@media (max-width:860px){.hud-sig{display:none}}

.hud-br{bottom:var(--gutter);right:var(--gutter);display:flex;gap:.7em;align-items:center}
.hud-arrow{animation:bob 1.9s var(--ease) infinite}
@keyframes bob{0%,100%{transform:translateY(-3px);opacity:.4}50%{transform:translateY(3px);opacity:1}}

/* 左侧章节轨：七个刻度 = 七层世界 */
.hud-rail{left:var(--gutter);top:50%;transform:translateY(-50%);
  display:flex;flex-direction:column;gap:5px}
/* 看着是一根 1px 的刻度，但按钮本身有 16px 高的透明点击区，
   否则这个目标小到几乎点不中 */
.rail-t{width:40px;height:16px;background:none;border:0;padding:0;cursor:none;
  position:relative;display:flex;align-items:center;opacity:.28;transition:opacity .3s}
.rail-t::before{content:"";display:block;width:26px;height:var(--hud-w);
  background:currentColor;transition:width .3s,background .3s}
.rail-t::after{content:attr(data-n);position:absolute;left:34px;top:1px;font-size:9px;opacity:0;
  transition:opacity .3s;white-space:nowrap;letter-spacing:.2em}
.rail-t:hover{opacity:.7}
.rail-t:hover::before{width:34px}
.rail-t:hover::after{opacity:.7}
.rail-t[aria-current="true"]{opacity:1}
.rail-t[aria-current="true"]::before{width:40px;background:var(--accent)}
.rail-t[aria-current="true"]::after{opacity:1;color:var(--accent)}

/* 四角框：一直在，线宽/圆角按层变 */
.frame{position:fixed;inset:calc(var(--gutter) - 12px);z-index:49;pointer-events:none;
  opacity:1;transition:opacity 1.45s var(--ease)}
.frame i{position:absolute;width:20px;height:20px;border:var(--hud-w) solid var(--ink);opacity:.3;
  border-radius:var(--hud-r);transition:border-width .35s,border-radius .35s,border-color .35s linear}
.frame i:nth-child(1){top:0;left:0;border-right:0;border-bottom:0}
.frame i:nth-child(2){top:0;right:0;border-left:0;border-bottom:0}
.frame i:nth-child(3){bottom:0;left:0;border-right:0;border-top:0}
.frame i:nth-child(4){bottom:0;right:0;border-left:0;border-top:0}

/* HUD 按层"重绘"自己 —— 同一套仪器，七种画法 */
html[data-ch="1"]{--hud-w:3px;--hud-r:0px}
html[data-ch="1"] .hud{font-size:10px;letter-spacing:.22em}
html[data-ch="2"]{--hud-w:1px;--hud-r:0px}
html[data-ch="3"]{--hud-w:1.5px;--hud-r:10px;--hud-f:var(--f-serif)}
html[data-ch="3"] .hud{letter-spacing:.2em;opacity:.7}
html[data-ch="4"]{--hud-w:1px;--hud-r:2px}
html[data-ch="5"]{--hud-w:.5px;--hud-r:0px;--hud-f:var(--f-serif)}
html[data-ch="5"] .hud{letter-spacing:.34em;opacity:.62}
html[data-ch="6"]{--hud-w:1px;--hud-r:50%}

/* ---------- 版面骨架 ---------- */
main{position:relative;z-index:10}
.ch{height:calc(var(--h) * 1vh);position:relative}
.stage{position:sticky;top:0;height:100vh;width:100%;
  padding:calc(var(--gutter) * 2.4) calc(var(--gutter) * 1.9);
  display:flex;flex-direction:column;
  /* 文字在本层末尾退场，好让世界安静地morph过去。
     退场晚、下一层进场早 —— 两段重叠，屏幕上不会出现空白的死区 */
  opacity:calc(1 - max(0, var(--t,0) - .86) * 7.2);
}
.stage-center{align-items:center;justify-content:center;text-align:center}

.stage-split{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);
  gap:clamp(24px,5vw,80px);align-items:center}
.col-l{display:flex;flex-direction:column;align-items:flex-start;gap:22px}
.col-r{display:flex;align-items:center;justify-content:center}

/* 进场：错峰上浮 */
.r{opacity:0;transform:translateY(26px)}
.is-live .r{animation:rise .95s var(--ease) both;animation-delay:calc(var(--d,0) * 110ms)}
@keyframes rise{to{opacity:1;transform:none}}

/* ---------- 通用文本 ---------- */
.eyebrow{font-family:var(--f-mono);font-size:11px;letter-spacing:.42em;text-transform:uppercase;
  opacity:.55}
.ch-tag{font-family:var(--f-mono);font-size:11px;letter-spacing:.26em;display:flex;gap:.8em;
  align-items:baseline;opacity:.8}
.ch-tag b{font-family:var(--f-disp);font-size:26px;letter-spacing:.02em;color:var(--accent)}
.ch-tag em{font-style:normal;opacity:.45;font-size:10px;letter-spacing:.3em}
/* "看法"标签：全站内核在版面上的落点 */
.body{font-size:clamp(14px,1.15vw,17px);line-height:2.05;opacity:.78;letter-spacing:.05em;max-width:34ch}
.body-wide{max-width:40ch}
.aside{font-family:var(--f-serif);font-size:13px;letter-spacing:.1em;opacity:.5;
  border-left:1px solid currentColor;padding-left:16px;line-height:1.9}

/* ---------- 00 虚空 ----------
   首屏的主事件发生在空间里：白核发出三次脉冲，粒子先组成“探”，
   轨迹再连接成“索”。DOM 文字只在最后成为一层极淡的稳定骨架。 */
.stage-void{gap:clamp(15px,2.2vh,24px);padding-top:clamp(74px,10vh,112px)}
.title-void{font-family:var(--f-serif);font-weight:400;line-height:1;margin:0 0 clamp(4px,1vh,10px);
  font-size:clamp(72px,11.8vw,156px);display:flex;justify-content:center;
  gap:clamp(18px,3.5vw,56px);isolation:isolate}
.title-void .void-glyph{display:block;color:transparent;opacity:0;
  -webkit-background-clip:text;background-clip:text;
  -webkit-text-stroke:.55px rgba(232,230,224,.18);
  filter:blur(8px);will-change:opacity,filter,background-position}
.void-glyph-probe{background-image:
  radial-gradient(circle,rgba(238,242,248,.72) 0 1px,transparent 1.35px),
  linear-gradient(120deg,rgba(143,166,201,.08),rgba(232,230,224,.22),rgba(143,166,201,.06));
  background-size:7px 7px,220% 100%;
  animation:voidGlyphResolve 1.65s 4.55s var(--ease) forwards,voidDustFlow 12s 6.2s linear infinite}
.void-glyph-trace{background-image:
  repeating-linear-gradient(164deg,rgba(232,230,224,.24) 0 1px,transparent 1px 8px),
  linear-gradient(100deg,rgba(143,166,201,.05),rgba(232,230,224,.18),rgba(143,166,201,.05));
  background-size:100% 100%,240% 100%;
  animation:voidGlyphResolve 1.65s 5.35s var(--ease) forwards,voidTraceFlow 10s 7s linear infinite}
@keyframes voidGlyphResolve{
  0%{opacity:0;filter:blur(9px);-webkit-text-stroke-color:rgba(232,230,224,0)}
  55%{opacity:.3;filter:blur(2px)}
  100%{opacity:.48;filter:blur(0);-webkit-text-stroke-color:rgba(232,230,224,.2)}}
@keyframes voidDustFlow{to{background-position:19px -13px,100% 0}}
@keyframes voidTraceFlow{to{background-position:0 0,100% 0}}
.stage-void .void-intro-copy{opacity:0;transform:translateY(8px);filter:blur(4px)}
.stage-void .eyebrow.void-intro-copy{--intro-opacity:.55}
.stage-void .lede.void-intro-copy{--intro-opacity:.72}
.stage-void .coord.void-intro-copy{--intro-opacity:.5}
.is-live .void-intro-copy{animation:voidCopyIn 1.05s var(--ease) var(--intro-delay) forwards}
@keyframes voidCopyIn{to{opacity:var(--intro-opacity,1);transform:none;filter:blur(0)}}
.lede{font-family:var(--f-serif);font-size:clamp(15px,1.5vw,20px);line-height:2.1;opacity:.72;
  letter-spacing:.12em}
html[data-ch="0"] .hud,html[data-ch="0"] .frame{animation:voidHudIn 1.2s 6.4s var(--ease) both}
html[data-ch="0"] #probe{animation:voidProbeIn 1.35s 7.05s var(--ease) both}
@keyframes voidHudIn{from{opacity:0}to{opacity:.82}}
@keyframes voidProbeIn{from{opacity:0;filter:blur(8px)}to{opacity:1;filter:blur(0)}}

/* ---------- 01 像素纪 ---------- */
.stage-pixel{justify-content:flex-start;align-items:flex-start;
  padding-top:clamp(118px,15vh,190px);padding-bottom:0;pointer-events:none}
.pixel-copy{width:min(520px,38vw);display:flex;flex-direction:column;align-items:flex-start;
  gap:clamp(10px,1.35vh,18px);position:relative;z-index:4}
.px-title{image-rendering:pixelated;width:100%;height:auto;overflow:visible;
  filter:drop-shadow(4px 4px 0 rgba(0,0,0,.55))}
.body-pixel{font-family:var(--f-mono);font-size:clamp(12px,.92vw,15px);letter-spacing:.03em;
  line-height:1.75;max-width:36ch;opacity:.66}
.dlg{border:3px solid var(--ink);background:color-mix(in srgb,var(--bg) 78%,#000);
  padding:12px 16px 14px;width:min(460px,100%);position:relative;
  box-shadow:6px 6px 0 rgba(0,0,0,.5)}
.dlg-bar{font-family:var(--f-mono);font-size:10px;letter-spacing:.3em;color:var(--accent);
  margin-bottom:8px;display:flex;gap:.6em;align-items:center}
.dlg-line{font-family:var(--f-mono);font-size:12px;line-height:1.72;min-height:1.72em;letter-spacing:.03em}
.dlg-next{position:absolute;right:14px;bottom:8px;font-size:10px;color:var(--accent);
  animation:bob 1.1s steps(2) infinite}
.stat{list-style:none;display:flex;gap:34px;font-family:var(--f-mono)}
.stat b{display:block;font-size:20px;color:var(--accent);letter-spacing:.06em}
.stat span{font-size:9px;letter-spacing:.24em;opacity:.5}

/* ---------- 02 深空纪 ---------- */
#ch2 .stage-split{grid-template-columns:minmax(0,1.38fr) minmax(250px,.5fr);
  gap:clamp(28px,5vw,92px)}
#ch2 .col-l{max-width:min(760px,58vw)}
#ch2 .col-r{justify-content:flex-end;align-self:center}
.title-deep{font-family:var(--f-serif);font-weight:400;font-size:clamp(34px,4.6vw,68px);
  line-height:1.42;letter-spacing:.02em;text-wrap:balance}
.title-deep i{font-style:normal;color:var(--accent)}
.tele{border:1px solid color-mix(in srgb,var(--ink) 15%,transparent);padding:18px 20px;
  width:min(330px,100%);font-family:var(--f-mono);backdrop-filter:blur(2px);
  background:color-mix(in srgb,var(--bg) 34%,transparent);opacity:.76}
.tele-h{display:flex;justify-content:space-between;align-items:center;font-size:10px;
  letter-spacing:.3em;opacity:.5;margin-bottom:14px}
.blink{color:var(--accent);animation:blink 1.4s steps(2) infinite;font-style:normal}
@keyframes blink{50%{opacity:.15}}
.tele dl div{display:flex;justify-content:space-between;gap:16px;padding:8px 0;
  border-bottom:1px dashed color-mix(in srgb,var(--ink) 11%,transparent);font-size:11px}
.tele dt{opacity:.5;letter-spacing:.16em}
.tele dd{letter-spacing:.08em}
.tele dd.ok{color:var(--accent)}
.tele dd.hi{position:relative}
.tele dd.hi::after{content:"";position:absolute;inset:-3px -7px;border:1px solid var(--accent);
  animation:blink 2s steps(2) infinite}
.tele-f{margin-top:14px;font-size:9px;line-height:1.9;opacity:.36;letter-spacing:.04em}

/* ---------- 03 生长纪 ---------- */
.title-bloom{font-family:var(--f-serif);font-weight:400;font-size:clamp(32px,4.4vw,64px);
  line-height:1.46}
.title-bloom i{font-style:normal;color:var(--accent);position:relative;white-space:nowrap}
.title-bloom i::after{content:"";position:absolute;left:0;right:0;bottom:.08em;height:.42em;
  background:color-mix(in srgb,var(--accent) 16%,transparent);z-index:-1}
.stage-bloom{grid-template-columns:minmax(280px,.72fr) minmax(0,1.28fr)}
.stage-bloom .col-l{position:relative;z-index:10;max-width:32rem}
.bloom-state{display:flex;align-items:center;gap:16px;margin-top:4px;
  font-family:var(--f-mono);letter-spacing:.2em;text-transform:uppercase}
.bloom-state span{font-size:9px;opacity:.46}
.bloom-state b{min-width:5em;font-family:var(--f-serif);font-size:14px;font-weight:400;
  letter-spacing:.28em;color:#a64f36}

/* ---------- 04 神经纪 ---------- */
.stage-latent{z-index:5;align-items:flex-start;justify-content:flex-start;gap:16px;
  padding-top:clamp(82px,12vh,132px);pointer-events:none;
  opacity:calc(1 - max(0, var(--t,0) - .64) * 7.5)}
.title-latent{font-family:var(--f-serif);font-weight:400;font-size:clamp(28px,3.7vw,54px);
  line-height:1.35;letter-spacing:.08em;max-width:12ch}
.latent-state{display:flex;align-items:center;gap:14px;font-family:var(--f-mono);letter-spacing:.18em}
.latent-state span{font-size:9px;opacity:.42}
.latent-state b{font-family:var(--f-serif);font-size:13px;font-weight:400;letter-spacing:.22em;
  color:var(--accent);min-width:7em}

/* ---------- 05 墨纪 ---------- */
.stage-ink{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:end;
  gap:clamp(20px,6vw,90px);padding-bottom:calc(var(--gutter) * 2.5);isolation:isolate}
.ink-l{display:flex;flex-direction:column;gap:26px;align-self:end;padding-bottom:14px;
  opacity:calc(1 - var(--ink-focus,0) * .55)}
.ink-r{display:flex;align-items:flex-end;gap:26px;opacity:calc(1 - var(--ink-focus,0) * .72)}
.title-ink{font-family:var(--f-serif);font-weight:400;
  font-size:clamp(30px,4.25vw,58px);line-height:1.45;letter-spacing:.18em;
  display:flex;flex-direction:row-reverse;gap:.5em;align-items:flex-start}
.title-ink>span{display:block;writing-mode:vertical-rl;text-orientation:upright}
.title-ink .ink-title-end{padding-top:.72em}
.ink-after{font-family:var(--f-serif);font-size:12px;line-height:1.9;letter-spacing:.12em;
  opacity:.48;border-left:1px solid color-mix(in srgb,var(--ink) 28%,transparent);padding-left:15px}
.seal{width:58px;height:58px;background:var(--accent);color:#F3EFE6;display:grid;place-items:center;
  font-family:var(--f-serif);font-size:15px;line-height:1.18;letter-spacing:.08em;
  border-radius:3px;transform:rotate(-3deg);align-self:flex-end;margin-bottom:6px;
  box-shadow:0 2px 14px color-mix(in srgb,var(--accent) 30%,transparent);
  opacity:.52;transition:opacity .6s var(--ease),transform .6s var(--ease),box-shadow .6s var(--ease)}
html[data-settled="1"] .seal{opacity:1;transform:rotate(-3deg) scale(1.04);
  box-shadow:0 3px 20px color-mix(in srgb,var(--accent) 42%,transparent)}
.ink-process{position:absolute;left:clamp(126px,17vw,290px);top:clamp(94px,14vh,148px);
  display:flex;align-items:center;gap:10px;font-family:var(--f-mono);color:var(--ink)}
.ink-process span{display:flex;flex-direction:column;gap:4px;min-width:76px;opacity:.2;
  transition:opacity .5s var(--ease),transform .5s var(--ease)}
.ink-process span i{font-style:normal;font-size:8px;letter-spacing:.2em}
.ink-process span b{font-family:var(--f-serif);font-size:11px;font-weight:400;letter-spacing:.14em;white-space:nowrap}
.ink-process em{display:block;width:clamp(18px,2.5vw,42px);height:1px;background:currentColor;opacity:.16;
  position:relative}
.ink-process em::after{content:"";position:absolute;right:-1px;top:-2px;width:4px;height:4px;
  border-top:1px solid currentColor;border-right:1px solid currentColor;transform:rotate(45deg)}
.ink-process span.is-past{opacity:.4}
.ink-process span.is-on{opacity:.9;transform:translateY(-2px);color:var(--accent)}
.ink-cause{position:absolute;left:clamp(126px,17vw,290px);top:clamp(156px,22vh,224px);
  display:flex;align-items:baseline;gap:15px;font-family:var(--f-mono);letter-spacing:.16em}
.ink-cause span{font-size:8px;opacity:.32}
.ink-cause b{font-family:var(--f-serif);font-size:12px;font-weight:400;letter-spacing:.13em;
  color:var(--accent);min-width:19em}
html[data-ink-phase="signal"] .ink-cause{opacity:1!important}
html[data-ink-phase="signal"] .ink-cause b{font-size:13px;color:#8d352b}
.ink-voyage{position:absolute;left:50%;bottom:clamp(34px,7vh,74px);transform:translateX(-50%);
  display:flex;align-items:center;gap:10px;font-family:var(--f-mono);font-size:8px;
  letter-spacing:.24em;opacity:.48;white-space:nowrap}
.ink-voyage i{display:block;width:5px;height:5px;border:1px solid var(--accent);border-radius:50%;
  box-shadow:0 0 0 0 color-mix(in srgb,var(--accent) 20%,transparent)}
html[data-ink-phase="signal"] .ink-voyage i{background:#fff;animation:inkVoyagePulse 1.6s ease-out infinite}
html[data-settled="1"] .ink-voyage{color:var(--accent);opacity:.82}
html[data-settled="1"] .ink-voyage i{background:var(--accent)}
@keyframes inkVoyagePulse{0%{box-shadow:0 0 0 0 color-mix(in srgb,var(--accent) 38%,transparent)}
  100%{box-shadow:0 0 0 12px transparent}}

/* ---------- 06 终章 ---------- */
.finale-scene{position:fixed;inset:0;z-index:7;pointer-events:none;opacity:0;
  transition:opacity .8s var(--ease)}
html[data-ch="6"] .finale-scene{opacity:1}

/* SIG-01 先落到最后一个坐标，再第一次停下来。 */
.final-signal{position:absolute;left:56%;top:25%;width:12px;height:12px;
  transform:translate(-50%,-50%) translateY(-28vh);opacity:0;
  transition:transform 1.35s cubic-bezier(.18,.82,.26,1),opacity .5s linear}
.final-signal b{position:absolute;inset:3px;border-radius:50%;background:#fff;
  box-shadow:0 0 8px #fff,0 0 23px rgba(240,198,116,.86)}
.final-signal i{position:absolute;inset:0;border:1px solid var(--accent);border-radius:50%;
  opacity:.24;animation:finalSignalBreath 2.8s ease-out infinite;
  animation-delay:calc(var(--pulse-order,0) * .82s)}
.final-signal i:nth-child(2){--pulse-order:1}
.final-signal i:nth-child(3){--pulse-order:2}
@keyframes finalSignalBreath{
  0%{transform:scale(.7);opacity:.45}
  75%,100%{transform:scale(4.6);opacity:0}}
html[data-ch="6"].finale-arrive .final-signal{transform:translate(-50%,-50%);opacity:1}

/* 两者并排后，这条细线只存在一瞬：它不是捕获框，是距离归零。 */
.signal-thread{position:absolute;left:48.2%;top:25%;width:7.8%;height:1px;
  background:linear-gradient(90deg,transparent,var(--ink) 22%,var(--accent) 78%,transparent);
  transform:scaleX(0);transform-origin:left;opacity:0;
  transition:transform 1.05s var(--ease),opacity .8s var(--ease)}
html[data-ch="6"].finale-together{--px:47%;--py:25%;--pw:84px}
html[data-ch="6"].finale-together .signal-thread{transform:scaleX(1);opacity:.24}

.last-pulse{position:absolute;left:56%;top:25%;width:10px;height:10px;margin:-5px 0 0 -5px;
  border:1px solid #fff;border-radius:50%;opacity:0}
html[data-ch="6"].finale-pulse .last-pulse{animation:lastPulse 1.6s var(--ease) both}
@keyframes lastPulse{
  0%{transform:scale(.5);opacity:.78;box-shadow:0 0 12px #fff}
  100%{transform:scale(28);opacity:0;box-shadow:0 0 0 transparent}}
html[data-ch="6"].finale-gone .final-signal{transform:translate(-50%,-50%) scale(.08);opacity:0;
  transition-duration:1.15s}
html[data-ch="6"].finale-gone .signal-thread{opacity:0}

/* 终章第一次让仪器退场。深度停住，HUD 也不再参与解释。 */
html[data-ch="6"].finale-quiet .hud,
html[data-ch="6"].finale-quiet .frame{opacity:0}
html[data-ch="6"].finale-quiet #cursor{opacity:.18}

.stage-final{justify-content:flex-start;gap:0;padding-top:clamp(270px,36vh,370px);
  opacity:1!important;pointer-events:none}
.stage-final .final-tag{opacity:0;transform:translateY(8px);
  transition:opacity 1s var(--ease),transform 1s var(--ease)}
html[data-ch="6"].finale-quiet .final-tag{opacity:.52;transform:none}

.final-log{width:min(760px,74vw);margin-top:18px;opacity:0;transform:translateY(10px);
  transition:opacity 1.2s var(--ease),transform 1.2s var(--ease)}
html[data-ch="6"].finale-log .final-log{opacity:1;transform:none}
/* 五段记录看完以后，界面主动把它们收走。这里没有下一条提示，
   只把探测器和已经停下的信号留在同一片黑暗里。 */
html[data-ch="6"].finale-empty .final-log{opacity:0;transform:translateY(-5px);
  transition-duration:1.55s}
html[data-ch="6"].finale-empty .final-tag{opacity:0;transform:translateY(-4px)}
html[data-ch="6"].finale-empty .signal-thread{opacity:0}
html[data-ch="6"].finale-empty .pb-rings{opacity:.1;animation-play-state:paused}
html[data-ch="6"].finale-empty .pb-tip{opacity:.28;animation-play-state:paused}
html[data-ch="6"].finale-empty .final-signal i{opacity:0;animation-play-state:paused}
.log-title{display:flex;align-items:baseline;justify-content:space-between;
  font-family:var(--f-mono);font-size:10px;letter-spacing:.34em;color:var(--accent);
  padding-bottom:10px;border-bottom:1px solid color-mix(in srgb,var(--ink) 13%,transparent)}
.log-title span{font-family:var(--f-sans);font-size:9px;letter-spacing:.24em;color:var(--ink);opacity:.32}

.recorder{position:relative;display:grid;grid-template-columns:repeat(5,minmax(0,1fr));
  gap:clamp(12px,2.4vw,32px);width:100%;margin:13px 0 0;list-style:none}
.rec-cell{position:relative;min-width:0;height:96px;display:grid;
  grid-template-rows:16px 58px 13px;justify-items:center;align-items:center;
  opacity:.08;transform:translateY(7px);transition:opacity .8s var(--ease),transform .8s var(--ease)}
.rec-cell::after{content:"";position:absolute;left:50%;top:11px;width:calc(100% + clamp(12px,2.4vw,32px));
  height:1px;background:color-mix(in srgb,var(--ink) 14%,transparent);z-index:-1}
.rec-cell:last-child::after{display:none}
.rec-index{position:relative;z-index:1;background:var(--bg);padding:0 7px;
  font-family:var(--f-disp);font-size:10px;letter-spacing:.15em;color:var(--ink);opacity:.45}
.rec-art{width:58px;height:52px;display:grid;place-items:center;position:relative;
  filter:saturate(.42);transition:filter .8s var(--ease),opacity .8s var(--ease),transform .8s var(--ease)}
.rec-art img{display:block;max-width:54px;max-height:48px;object-fit:contain}
.rec-cell[data-record="sprouted"] .rec-art img{max-width:36px;max-height:46px}
.rec-cell[data-record="rebuilt"] .rec-art img{max-width:52px;transform:rotate(-8deg)}
.rec-name{font-family:var(--f-mono);font-size:8px;letter-spacing:.2em;color:var(--ink);opacity:.32;
  white-space:nowrap}
.rec-cell.seen{opacity:.7;transform:none}
.rec-cell.on .rec-art{filter:saturate(.78) brightness(1.08);opacity:.9;transform:translateY(-2px)}
.rec-cell.on .rec-index{color:var(--accent);opacity:.9}
.rec-cell.on .rec-name{opacity:.5}
.rec-cell.missing{opacity:.24}
.rec-cell.missing .rec-art{filter:grayscale(1);opacity:.16}
.rec-cell.missing .rec-name::after{content:" · LOST";color:var(--accent)}

/* 第五段不造新图标，只留下墨纪那一笔山。 */
.rec-mountain i{position:absolute;bottom:10px;height:1px;background:var(--accent);
  transform-origin:left center;opacity:.72}
.rec-mountain i:first-child{left:5px;width:34px;transform:rotate(-34deg)}
.rec-mountain i:last-child{left:33px;width:23px;transform:rotate(38deg)}
.rec-mountain::after{content:"";position:absolute;left:11px;right:4px;bottom:9px;height:1px;
  background:linear-gradient(90deg,transparent,var(--ink),transparent);opacity:.3}

.empty-coordinate{margin-top:6px;display:flex;align-items:center;gap:13px;opacity:0;
  font-family:var(--f-mono);transition:opacity 1.25s var(--ease)}
.empty-coordinate span{font-size:8px;letter-spacing:.25em;color:var(--ink);opacity:.3}
.empty-coordinate b{font-size:12px;font-weight:400;letter-spacing:.35em;color:var(--accent);opacity:.72}
html[data-ch="6"].finale-gone .empty-coordinate{opacity:1}

.recdone{margin-top:16px;font-family:var(--f-serif);font-size:clamp(22px,2.2vw,31px);
  font-weight:400;letter-spacing:.18em;color:var(--ink);opacity:0;transform:translateY(8px);
  transition:opacity 1.4s var(--ease),transform 1.4s var(--ease)}
html[data-ch="6"].finale-after .recdone{opacity:.9;transform:none}

.again{margin-top:24px;background:none;border:1px solid color-mix(in srgb,var(--accent) 76%,transparent);
  color:var(--accent);font-family:var(--f-mono);font-size:11px;letter-spacing:.3em;padding:14px 30px;
  cursor:none;display:flex;gap:1em;align-items:center;border-radius:999px;pointer-events:auto;
  opacity:0;transform:translateY(8px);transition:background .35s var(--ease),color .35s var(--ease),
  gap .35s var(--ease),opacity 1.2s var(--ease),transform 1.2s var(--ease)}
html[data-ch="6"].finale-after .again{opacity:1;transform:none}
.again:hover{background:var(--accent);color:var(--bg);gap:1.7em}
.again:focus-visible{outline:2px solid var(--ink);outline-offset:5px}
.replay-reason{margin-top:10px;font-family:var(--f-serif);font-size:11px;letter-spacing:.16em;
  color:var(--ink);opacity:0;transition:opacity 1.2s .18s var(--ease)}
html[data-ch="6"].finale-after .replay-reason{opacity:.38}
.colophon{margin-top:24px;font-family:var(--f-mono);font-size:8px;letter-spacing:.3em;
  color:var(--ink);opacity:0;transition:opacity 1.2s .35s var(--ease)}
html[data-ch="6"].finale-after .colophon{opacity:.22}

/* ---------- 响应式 ---------- */
@media (max-width:860px){
  :root{--gutter:16px}
  .hud-rail{display:none}
  .stage{padding:calc(var(--gutter) * 4) var(--gutter) calc(var(--gutter) * 4)}
  .stage-split{grid-template-columns:1fr;gap:34px;align-content:center}
  .col-r{order:-1}
  .stage-bloom{grid-template-columns:1fr;align-content:center}
  .stage-pixel{padding-top:clamp(94px,13vh,126px)}
  .pixel-copy{width:min(88vw,500px)}
  .body-pixel{max-width:32ch}
  .dlg{display:none}
  .stage-bloom .col-r{display:none}
  .stage-bloom .col-l{padding:22px 18px;margin-left:-8px;
    background:linear-gradient(90deg,rgba(239,231,214,.9),rgba(239,231,214,.56) 74%,transparent)}
  .stage-ink{grid-template-columns:1fr;justify-items:start;align-content:end}
  .ink-r{order:-1}
  .title-ink{flex-direction:column;gap:.08em;letter-spacing:.1em;line-height:1.4}
  .title-ink>span{writing-mode:horizontal-tb}
  .title-ink .ink-title-end{padding-top:0}
  .ink-process{left:var(--gutter);right:var(--gutter);top:12vh;gap:6px}
  .ink-process span{min-width:0;flex:1}
  .ink-process em{width:12px}
  .ink-process span b{font-size:9px;letter-spacing:.08em}
  .ink-cause{left:var(--gutter);top:20vh;display:block}
  .ink-cause span{display:block;margin-bottom:8px}
  .ink-cause b{font-size:10px;min-width:0}
  .ink-voyage{bottom:26px}
  .seal{transform:rotate(-3deg) scale(.85)}
  .stat{gap:20px;flex-wrap:wrap}
  .hud-tr .hud-v{font-size:15px}
  html[data-ch="6"]{--px:34%;--py:22%;--pw:70px}
  html[data-ch="6"].finale-together{--px:42%;--py:22%;--pw:70px}
  .final-signal,.last-pulse{left:59%;top:22%}
  .signal-thread{left:43%;top:22%;width:16%}
  .stage-final{padding:clamp(190px,27vh,245px) 16px 30px}
  .final-log{width:min(94vw,620px);margin-top:13px}
  .recorder{gap:7px}
  .rec-cell{height:82px;grid-template-rows:15px 49px 12px}
  .rec-cell::after{width:calc(100% + 7px)}
  .rec-index{font-size:9px;padding:0 4px}
  .rec-art{width:44px;height:44px}
  .rec-art img{max-width:42px;max-height:39px}
  .rec-cell[data-record="sprouted"] .rec-art img{max-width:29px;max-height:38px}
  .rec-cell[data-record="rebuilt"] .rec-art img{max-width:42px}
  .rec-name{font-size:7px;letter-spacing:.12em}
  .log-title span{display:none}
  .empty-coordinate{margin-top:3px}
  .recdone{margin-top:12px;font-size:clamp(20px,6vw,25px);letter-spacing:.12em}
  .again{margin-top:18px;padding:12px 25px}
  .replay-reason{font-size:10px}
  .colophon{margin-top:18px}
}

/* ---------- 无障碍：尊重减弱动效 ---------- */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation:none!important;transition:none!important}
  .r{opacity:1;transform:none}
  /* 逐字动画被关掉后，字必须自己站住，不能停在 opacity:0 */
  [data-t].split .c{opacity:1!important;filter:none!important;transform:none!important}
  #grain{opacity:.16}
  .prop{opacity:.4!important}
  .constel{opacity:.16!important}
  .title-void .void-glyph,.void-intro-copy,html[data-ch="0"] #probe,
  html[data-ch="0"] .hud,html[data-ch="0"] .frame{opacity:1!important;transform:none!important;filter:none!important}
}


/* ============================================================
   逐字入场：七层各有各的出场方式
   JS 把每个字拆成 .c，并写入 --i(次序) 和 --dx/--dy(随机偏移)。
   只有拆过的元素才隐藏初始态 —— JS 没跑起来时文字照样可读。
   ============================================================ */
[data-t].split .c{display:inline-block;opacity:0;white-space:pre;
  will-change:transform,opacity,filter}
.is-live [data-t].split .c{
  animation-duration:var(--dur,.9s);
  animation-fill-mode:both;
  animation-delay:calc(var(--i,0) * var(--stag,32ms));
  animation-timing-function:var(--tf,var(--ease))}

/* 00 虚空 —— 从四散的位置聚拢、由虚到实 */
[data-rev="gather"]{--stag:34ms;--dur:1.5s}
.is-live [data-rev="gather"] .c,
[data-rev="gather"].is-live [data-t].split .c{animation-name:revGather}
@keyframes revGather{
  from{opacity:0;filter:blur(14px);transform:translate(var(--dx),var(--dy)) scale(.72)}
  to{opacity:1;filter:blur(0);transform:none}}

/* 01 像素纪 —— 一格一格蹦出来，带一下过曝的白闪，没有缓动 */
[data-rev="pixel"]{--stag:44ms;--dur:.44s;--tf:steps(3,end)}
[data-rev="pixel"].is-live [data-t].split .c{animation-name:revPixel}
@keyframes revPixel{
  0%{opacity:0;transform:translateY(-7px)}
  35%{opacity:1;transform:translateY(2px);color:#fff}
  70%{transform:translateY(0);color:#fff}
  100%{opacity:1;transform:none}}

/* 02 深空纪 —— 字沿着追踪进度逐个恢复，像远处数据被重新拼回。 */
[data-rev="tracking"].is-live [data-t].split .c{
  animation:none;opacity:0;transition:opacity .5s var(--ease)}
[data-rev="tracking"].is-live [data-t].split .c.lit{opacity:1;animation:trackPing .8s ease-out}
@keyframes trackPing{
  0%{text-shadow:0 0 14px var(--accent),0 0 3px var(--accent);color:var(--accent)}
  100%{text-shadow:none}}

/* 03 生长纪 —— 从基线往上长，先窜过头一点再落回来 */
[data-rev="grow"]{--stag:46ms;--dur:1.15s;--tf:cubic-bezier(.18,.9,.24,1.06)}
[data-rev="grow"].is-live [data-t].split .c{animation-name:revGrow;transform-origin:bottom center}
@keyframes revGrow{
  0%{opacity:0;transform:translateY(.5em) scaleY(.2);filter:blur(3px)}
  62%{opacity:1;transform:translateY(0) scaleY(1.1)}
  100%{opacity:1;transform:none;filter:blur(0)}}

/* 04 神经纪 —— 不是故障字效；像一段记忆从模糊处慢慢对焦。 */
[data-rev="echo"]{--stag:72ms;--dur:1.25s;--tf:cubic-bezier(.2,.78,.26,1)}
[data-rev="echo"].is-live [data-t].split .c{animation-name:revEcho}
@keyframes revEcho{
  0%{opacity:0;transform:translateY(.22em);filter:blur(9px)}
  60%{opacity:.82;filter:blur(2px)}
  100%{opacity:1;transform:none;filter:blur(0)}}

/* 05 墨纪 —— 像墨在纸上洇开：糊、涨、然后收住 */
[data-rev="ink"]{--stag:88ms;--dur:1.7s;--tf:cubic-bezier(.2,.7,.2,1)}
[data-rev="ink"].is-live [data-t].split .c{animation-name:revInk}
@keyframes revInk{
  0%{opacity:0;filter:blur(12px);transform:scale(1.22)}
  55%{opacity:.9;filter:blur(3px)}
  100%{opacity:1;filter:blur(0);transform:none}}

/* 06 终章 —— 一颗一颗亮起来 */
[data-rev="star"]{--stag:38ms;--dur:1s;--tf:cubic-bezier(.2,.8,.2,1)}
[data-rev="star"].is-live [data-t].split .c{animation-name:revStar}
@keyframes revStar{
  0%{opacity:0;transform:scale(.35);filter:brightness(3.4)}
  50%{opacity:1;transform:scale(1.14);filter:brightness(2.4)}
  100%{opacity:1;transform:none;filter:none}}


/* ============================================================
   每层的道具：固定定位、跟着 data-ch 淡入淡出，
   压在粒子场之上、文字之下
   ============================================================ */
.prop,.constel,.terrain,.sprites,.shan,.pulse,.pixgame{
  position:fixed;pointer-events:none;z-index:0;opacity:0;
  transition:opacity .75s var(--ease)}

/* — 03 生命场景：具象资产承载形态，滚动只推进它的一生 — */
.bloom-scene{position:fixed;inset:0;z-index:0;pointer-events:none;overflow:hidden;opacity:0;
  transition:opacity .7s var(--ease);isolation:isolate;
  --seed:0;--sprout:0;--young:0;--mature:0;--dead:0;--impact:0;--dusk:0;
  --leaf-o:0;--leaf-x:72vw;--leaf-y:32vh;--leaf-r:0deg;
  --signal-o:0;--signal-x:72vw;--signal-y:32vh;--signal-scale:1;
  --bloom-sat:1;--bloom-bright:1;--dusk-alpha:0;--impact-scale:.45;
  --seed-scale:1;--sprout-scale:1;--young-scale:1;--mature-scale:1;
  --dead-y:0px;--dead-rot:0deg;--dead-sepia:0;--dead-sat:1}
html[data-ch="3"] .bloom-scene{opacity:1}
.bloom-atmosphere{position:absolute;inset:0;z-index:0;
  background:
    radial-gradient(46% 48% at 74% 29%,rgba(255,244,196,.68),transparent 69%),
    linear-gradient(180deg,rgba(250,245,226,.38),rgba(194,201,156,.12) 58%,rgba(91,71,55,.08));
  filter:saturate(var(--bloom-sat)) brightness(var(--bloom-bright))}
.bloom-atmosphere::after{content:"";position:absolute;inset:0;background:#19221d;
  opacity:var(--dusk-alpha)}
.tree-cycle{position:absolute;inset:0;z-index:3;transform-origin:72.5% 77.5%;will-change:transform}
.tree-cycle.is-windy{animation:treeWind 1.45s cubic-bezier(.2,.8,.2,1)}
@keyframes treeWind{0%,100%{transform:none}18%{transform:rotate(1.3deg)}38%{transform:rotate(-.9deg)}60%{transform:rotate(.55deg)}82%{transform:rotate(-.25deg)}}
.tree-stage{position:absolute;right:0;bottom:17vh;width:55vw;height:78vh;object-fit:contain;
  object-position:center bottom;opacity:0;transform-origin:50% 92.8%;will-change:opacity,transform,filter;
  filter:saturate(var(--bloom-sat)) brightness(var(--bloom-bright))}
.tree-seed{opacity:var(--seed);transform:scale(var(--seed-scale))}
.tree-sprout{opacity:var(--sprout);transform:scaleY(var(--sprout-scale))}
.tree-young{opacity:var(--young);transform:scaleY(var(--young-scale))}
.tree-mature{opacity:var(--mature);transform:scale(var(--mature-scale))}
.tree-dead{opacity:var(--dead);transform:translateY(var(--dead-y)) rotate(var(--dead-rot));
  filter:sepia(var(--dead-sepia)) saturate(var(--dead-sat)) brightness(var(--bloom-bright))}
.bloom-soil{position:absolute;left:-1vw;bottom:-1px;z-index:6;width:102vw;height:24vh;
  object-fit:fill;filter:saturate(var(--bloom-sat)) brightness(var(--bloom-bright))}
.bloom-impact{position:absolute;left:72.5%;top:77.3%;z-index:8;width:220px;height:90px;
  opacity:var(--impact);transform:translate(-50%,-50%) scale(var(--impact-scale))}
.bloom-impact i{position:absolute;left:50%;top:52%;width:34px;height:18px;border-radius:52% 48% 55% 45%;
  background:#b99a6f;filter:blur(1.8px);opacity:.7}
.bloom-impact i:nth-child(1){transform:translate(-96px,-12px) rotate(-18deg)}
.bloom-impact i:nth-child(2){transform:translate(-54px,-31px) rotate(9deg) scale(1.25)}
.bloom-impact i:nth-child(3){transform:translate(-8px,-38px) rotate(-7deg) scale(.8)}
.bloom-impact i:nth-child(4){transform:translate(43px,-27px) rotate(18deg) scale(1.1)}
.bloom-impact i:nth-child(5){transform:translate(80px,-7px) rotate(-11deg) scale(.72)}
.bloom-shed,.bloom-wind{position:absolute;inset:0;z-index:7;overflow:hidden}
.bloom-shed img,.bloom-wind img{position:absolute;width:clamp(28px,3vw,48px);height:auto;
  transform-origin:50% 50%;will-change:transform,opacity}
.signal-leaf{position:absolute;left:0;top:0;z-index:9;width:clamp(72px,7vw,110px);height:auto;
  opacity:var(--leaf-o);transform:translate3d(var(--leaf-x),var(--leaf-y),0) translate(-50%,-50%) rotate(var(--leaf-r));
  filter:drop-shadow(0 12px 10px rgba(44,31,22,.2));will-change:transform,opacity}
.bloom-signal{position:absolute;left:0;top:0;z-index:10;width:1px;height:1px;opacity:var(--signal-o);
  transform:translate3d(var(--signal-x),var(--signal-y),0) scale(var(--signal-scale));
  color:#a64f36;will-change:transform,opacity}
.bloom-signal i,.bloom-signal b{position:absolute;left:0;top:0;border-radius:50%;transform:translate(-50%,-50%)}
.bloom-signal i{width:20px;height:20px;border:1px solid currentColor;opacity:0;
  animation:bloomPulse 2.4s ease-out infinite}
.bloom-signal i:nth-child(2){animation-delay:.8s}
.bloom-signal i:nth-child(3){animation-delay:1.6s}
.bloom-signal b{width:8px;height:8px;background:#fff;box-shadow:0 0 18px 5px rgba(255,255,255,.62)}
.bloom-signal span{position:absolute;left:17px;top:-19px;font-family:var(--f-mono);font-size:8px;
  letter-spacing:.18em;color:#5c3b2b;white-space:nowrap;opacity:.72}
@keyframes bloomPulse{0%{width:10px;height:10px;opacity:.75}100%{width:58px;height:58px;opacity:0}}

/* — 04 神经纪：同一片叶被放大，三个真实记忆依次形成，错误从对象内部发生 — */
.latent-scene{position:fixed;inset:0;z-index:0;pointer-events:none;overflow:hidden;opacity:0;
  transition:opacity .7s var(--ease);isolation:isolate;
  --leaf-x:72vw;--leaf-y:-8vh;--leaf-r:430deg;--leaf-scale:.68;--leaf-o:1;
  --vein-o:0;--vein-offset:185;--core-o:0;--core-inv:1.47;
  --star-show:0;--star-error:0;--orbit-show:0;--orbit-error:0;--tree-show:0;--tree-error:0;
  --memory-fade:1;--copy-fade:1;--overload:0}
html[data-ch="4"] .latent-scene{opacity:1}
.latent-scene::before{content:"";position:absolute;inset:0;z-index:-2;
  background:
    radial-gradient(70% 62% at 50% 46%,rgba(87,68,46,.16),transparent 70%),
    radial-gradient(42% 45% at 72% 0%,rgba(155,117,68,.08),transparent 75%)}
.latent-scene::after{content:"";position:absolute;inset:-10%;z-index:-1;opacity:calc(var(--vein-o) * .16);
  background:
    radial-gradient(ellipse at 50% 46%,transparent 0 18%,rgba(196,160,105,.13) 18.4% 18.8%,transparent 19.2% 100%),
    radial-gradient(ellipse at 18% 82%,transparent 0 28%,rgba(196,160,105,.08) 28.4% 28.7%,transparent 29.1% 100%);
  filter:blur(1px);transform:scale(1.2)}

.latent-leaf{position:absolute;left:0;top:0;z-index:4;width:clamp(104px,10.7vw,164px);height:auto;
  opacity:var(--leaf-o);transform-origin:50% 50%;will-change:transform,opacity;
  transform:translate3d(var(--leaf-x),var(--leaf-y),0) translate(-50%,-50%) rotate(var(--leaf-r)) scale(var(--leaf-scale));
  filter:drop-shadow(0 18px 24px rgba(0,0,0,.26))}
.latent-leaf svg{display:block;width:100%;height:auto;overflow:visible}
.latent-leaf-body{fill:url(#latentLeafFill)}
.latent-stem{fill:none;stroke:#6b4c34;stroke-width:5;stroke-linecap:round}
.latent-veins{fill:none;stroke:#f1d59f;stroke-width:2.2;stroke-linecap:round;opacity:var(--vein-o)}
.latent-veins path{stroke-dasharray:185;stroke-dashoffset:var(--vein-offset)}
.latent-core{position:absolute;left:50%;top:50%;width:1px;height:1px;color:#d9aa69;
  opacity:var(--core-o);transform:scale(var(--core-inv));will-change:transform,opacity}
.latent-core i,.latent-core b{position:absolute;left:0;top:0;border-radius:50%;transform:translate(-50%,-50%)}
.latent-core i{width:20px;height:20px;border:1px solid currentColor;opacity:0;
  animation:bloomPulse 2.4s ease-out infinite}
.latent-core i:nth-child(2){animation-delay:.8s}.latent-core i:nth-child(3){animation-delay:1.6s}
.latent-core b{width:8px;height:8px;background:#fff;box-shadow:0 0 19px 6px rgba(255,255,255,.68)}
.latent-core span{position:absolute;left:17px;top:-19px;font-family:var(--f-mono);font-size:8px;
  letter-spacing:.18em;color:#ead4af;white-space:nowrap;opacity:.78}

.latent-memories{position:absolute;left:7vw;right:7vw;top:27vh;bottom:10vh;z-index:3;
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(18px,4vw,72px);align-items:center}
.memory{position:relative;display:flex;min-width:0;height:min(51vh,480px);flex-direction:column;
  align-items:center;justify-content:center;opacity:calc(var(--show) * var(--memory-fade));
  transform:translateY(calc((1 - var(--show)) * 28px)) scale(calc(.93 + var(--show) * .07));
  will-change:opacity,transform}
.memory-star{--show:var(--star-show);--err:var(--star-error)}
.memory-orbit{--show:var(--orbit-show);--err:var(--orbit-error)}
.memory-tree{--show:var(--tree-show);--err:var(--tree-error)}
.memory-object{position:relative;width:100%;height:min(36vh,340px);display:grid;place-items:center}
.memory-object::after{content:"";position:absolute;left:14%;right:14%;bottom:5%;height:20%;
  background:radial-gradient(ellipse,rgba(226,195,146,.12),transparent 70%);filter:blur(12px)}
.memory-object img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;
  filter:drop-shadow(0 12px 22px rgba(0,0,0,.28));will-change:opacity,transform}
.memory-correct{opacity:calc(1 - var(--err));transform:scale(calc(1 - var(--err) * .018))}
.memory-error{opacity:var(--err);transform:scale(calc(.985 + var(--err) * .015))}
.memory-star .memory-object img{padding:clamp(36px,5vw,68px)}
.memory-orbit .memory-object img{padding:clamp(22px,2.6vw,38px) 0}
.memory-tree .memory-object img{padding-top:2%}
.memory figcaption{height:42px;display:grid;grid-template-columns:auto auto;gap:4px 12px;align-items:baseline;
  font-family:var(--f-mono);letter-spacing:.14em;color:var(--ink)}
.memory figcaption span{font-size:8px;opacity:.38}.memory figcaption b{font-family:var(--f-serif);
  font-size:13px;font-weight:400;letter-spacing:.16em;opacity:.78}
.memory figcaption em{display:none;grid-column:1/-1;font-style:normal;font-size:8px;letter-spacing:.2em;
  color:#cfa266;opacity:.72}

/* 缺失记录不是一个叉：形态只尝试长出几笔，随后停住。 */
.memory-attempt{display:none;position:absolute;inset:0}
.memory.is-missing .memory-correct,.memory.is-missing .memory-error{opacity:0}
.memory.is-missing .memory-attempt{display:block;opacity:calc(var(--show) * (1 - var(--err) * .68))}
.memory.is-missing figcaption b{display:none}.memory.is-missing figcaption em{display:block}
.memory-attempt i{position:absolute;width:18px;height:18px;background:#ffd166;opacity:.38;
  filter:blur(.3px);animation:attemptPixel 2.4s ease-in-out infinite}
.memory-attempt i:nth-child(1){left:42%;top:38%}.memory-attempt i:nth-child(2){left:50%;top:38%;animation-delay:.25s}
.memory-attempt i:nth-child(3){left:42%;top:47%;animation-delay:.5s}.memory-attempt i:nth-child(4){left:58%;top:47%;animation-delay:.75s}
@keyframes attemptPixel{0%,100%{opacity:.08}42%{opacity:.52}70%{opacity:.14}}
.memory-attempt-orbit i{left:50%;top:50%;width:62%;height:22%;background:none;border:1px solid #5fd3e8;
  border-radius:50%;transform:translate(-50%,-50%) rotate(-9deg);filter:none;animation:attemptOrbit 2.8s ease-in-out infinite}
.memory-attempt-orbit i:nth-child(2){width:38%;height:14%;animation-delay:.45s}
@keyframes attemptOrbit{0%,100%{clip-path:inset(0 100% 0 0);opacity:.08}48%{clip-path:inset(0 35% 0 0);opacity:.46}72%{clip-path:inset(0 72% 0 0);opacity:.16}}
.memory-attempt-tree i{left:49%;top:36%;width:7px;height:45%;background:#7c5b3e;border-radius:80% 20% 40% 60%;
  transform-origin:bottom;animation:attemptTree 3s ease-in-out infinite}
.memory-attempt-tree i:nth-child(2){left:50%;top:48%;width:28%;height:6px;transform:rotate(-31deg);animation-delay:.5s}
@keyframes attemptTree{0%,100%{transform:scaleY(.08);opacity:.08}48%{transform:scaleY(.62);opacity:.42}72%{transform:scaleY(.28);opacity:.15}}

/* 副本层只在过载阶段被 JS 逐个放开；每个副本仍然是星、轨道或树。 */
.latent-copies{position:absolute;inset:8vh 3vw 4vh;z-index:2;opacity:var(--copy-fade)}
.latent-copy{position:absolute;width:clamp(72px,9vw,150px);height:clamp(72px,9vw,150px);
  opacity:var(--copy-o,0);transform:translate(-50%,-50%) rotate(var(--copy-r,0deg)) scale(var(--copy-s,.7));
  filter:saturate(.72) brightness(.9);will-change:opacity,transform}
.latent-copy img{width:100%;height:100%;object-fit:contain;filter:drop-shadow(0 8px 15px rgba(0,0,0,.34))}
.latent-copy.is-missing{display:none}
.latent-fall{display:none}

/* — 00 星座线 + 坐标读数 — */
.constel{inset:0;width:100%;height:100%}
html[data-ch="0"] .constel{animation:voidConstelIn 2.2s 6.7s var(--ease) both}
@keyframes voidConstelIn{from{opacity:0}to{opacity:.16}}
/* 画线动画绑在 .is-live 上：每次进这一层都重画一遍，而不是加载时就画完了 */
.constel line{stroke:var(--accent);stroke-width:.6;opacity:.5;
  stroke-dasharray:var(--len);stroke-dashoffset:var(--len)}
.is-live .constel line{animation:drawIn 2.6s var(--ease) forwards;
  animation-delay:calc(var(--k) * 120ms)}
.constel circle{fill:var(--accent);opacity:0}
.is-live .constel circle{animation:popIn .8s var(--ease) forwards;
  animation-delay:calc(var(--k) * 120ms + 400ms)}
@keyframes drawIn{to{stroke-dashoffset:0}}
@keyframes popIn{to{opacity:.85}}
.coord{margin-top:30px;font-family:var(--f-mono);font-size:10px;letter-spacing:.22em;
  display:flex;gap:.7em;align-items:baseline;opacity:.5}
.coord span{opacity:.5}
.coord b{color:var(--accent);font-weight:400;font-variant-numeric:tabular-nums}
.coord .wk{animation:blink 2.2s steps(2) infinite}

/* — 01 像素地形（两层视差）+ 悬浮精灵 + 血条 — */
.terrain{left:0;bottom:-44px;width:100%;height:clamp(250px,30vh,430px);image-rendering:pixelated}
.terrain-b{opacity:0;transform:translateY(calc(var(--par,0) * 12px))}
.terrain-f{opacity:0;transform:translateY(calc(var(--par,0) * -18px))}
html[data-ch="1"] .terrain-b{opacity:.4}
html[data-ch="1"] .terrain-f{opacity:.75}
.sprites{inset:0}
html[data-ch="1"] .sprites{opacity:1}
.spr{position:absolute;left:var(--x);top:var(--y);image-rendering:pixelated;
  animation:bobSpr 3.4s ease-in-out infinite;animation-delay:calc(var(--s) * -.8s)}
@keyframes bobSpr{0%,100%{transform:translateY(-9px)}50%{transform:translateY(9px)}}
.hpwrap{display:flex;align-items:center;gap:14px;font-family:var(--f-mono);font-size:10px;
  letter-spacing:.22em}
.hp-k{opacity:.5}
.hearts{display:flex;gap:5px}
.hearts i{width:9px;height:9px;background:#FF6B8B;display:block;
  clip-path:polygon(50% 100%,0 45%,0 15%,25% 0,50% 18%,75% 0,100% 15%,100% 45%);
  animation:hb 1.6s steps(2) infinite}
.hearts i:nth-child(2){animation-delay:.2s}
.hearts i:nth-child(3){animation-delay:.4s}
@keyframes hb{50%{transform:scale(.82)}}
.hp-bar{width:110px;height:8px;border:2px solid var(--ink);position:relative}
.hp-bar b{position:absolute;inset:1px;width:72%;background:var(--accent);display:block;
  animation:hpPulse 2.4s steps(4) infinite}
@keyframes hpPulse{50%{width:76%}}
.hp-n{opacity:.4}

/* — 02 遥测波形。追踪路径本体由 field canvas 绘制。 — */
@keyframes spin{to{transform:translate(-50%,-50%) rotate(360deg)}}
.wave{width:100%;height:34px;display:block;margin-bottom:12px;opacity:.62}

/* — 05 山水：神经结构先损耗成线，线再成为山脊 — */
.shan{inset:0;width:100%;height:100%;
  --ink-moon:0;--ink-water:0;--ink-far:0;--ink-mid:0;--ink-near:0;--ink-front:0}
html[data-ch="5"] .shan{opacity:1}
.shan .moon{fill:none;stroke:#1a181e;stroke-width:1.2;opacity:calc(var(--ink-moon) * .2);
  mix-blend-mode:multiply}
.shan .ridge{stroke:none;filter:url(#inkblur);mix-blend-mode:multiply}
/* 远淡近浓 —— 墨分五色 */
.shan .far  {fill:rgba(26,24,30,.10);filter:url(#inkblur2);opacity:var(--ink-far)}
.shan .mid  {fill:rgba(26,24,30,.18);opacity:var(--ink-mid)}
.shan .near {fill:rgba(26,24,30,.30);opacity:var(--ink-near)}
.shan .front{fill:rgba(26,24,30,.49);opacity:var(--ink-front)}
.shan .ridge{transform:translateY(calc((1 - var(--ridge-rise,0)) * 54px));transform-origin:center bottom}
.shan .water{stroke:#1a181e;stroke-width:1.6;fill:none;opacity:calc(var(--ink-water) * .2);
  stroke-linecap:round;mix-blend-mode:multiply}
.shan .ink-collapse{fill:none;stroke:#2a282c;stroke-linecap:round;stroke-linejoin:round;
  mix-blend-mode:multiply}
.shan .ink-fragment{stroke-width:1.15;opacity:.32;vector-effect:non-scaling-stroke}
.shan .ink-fragment.accent{stroke:#9c4939;stroke-width:1.3}
.shan .ink-node{fill:#2a282c;opacity:.34}
.shan .ink-node.core{fill:#fff;stroke:#9c4939;stroke-width:1.2;opacity:.9}
.shan .ink-thread{fill:none;stroke:#9c4939;stroke-width:1.35;stroke-linecap:round;
  vector-effect:non-scaling-stroke;opacity:.78;mix-blend-mode:multiply}
.shan .ridge-echo{fill:none;stroke:#9c4939;stroke-width:1.55;stroke-linecap:round;
  vector-effect:non-scaling-stroke;opacity:0;mix-blend-mode:multiply}
/* 白核单独回到 normal：山水可以渗进纸里，SIG-01 不可以。 */
.shan .ink-signal{opacity:0;mix-blend-mode:normal}
.shan .ink-signal .sig-aura{fill:url(#signalAura);opacity:.96}
.shan .ink-signal .sig-halo{fill:#a33d31;opacity:.34}
.shan .ink-signal .sig-core{fill:#fff;stroke:#fff;stroke-width:1.5;
  filter:drop-shadow(0 0 4px #fff) drop-shadow(0 0 15px rgba(163,61,49,.92))}
.shan .ink-signal .sig-pulse{fill:none;stroke:#a33d31;stroke-width:1.7;opacity:0}
.shan .ink-signal .sig-lock{fill:none;stroke:#6f504a;stroke-width:1;opacity:.46;
  stroke-dasharray:3 6;vector-effect:non-scaling-stroke}
.shan .ink-signal .sig-tick{stroke:#6f504a;stroke-width:1.2;opacity:.6;
  vector-effect:non-scaling-stroke}
.shan .ink-signal .sig-reflection{fill:url(#signalReflection);opacity:.68}
.shan .ink-signal text{font-family:var(--f-mono);paint-order:stroke;stroke:#f0ece3;stroke-width:4px}
.shan .ink-signal .sig-id{font-size:12px;font-weight:700;letter-spacing:2.6px;fill:#6e211c;opacity:.96}
.shan .ink-signal .sig-last{font-size:7px;letter-spacing:1.8px;fill:#6f504a;opacity:.72}
.shan .boat-wake{fill:none;stroke:#1a181e;stroke-linecap:round;opacity:0}
.shan .boat-wake path:nth-child(1){stroke-width:1.5}
.shan .boat-wake path:nth-child(2){stroke-width:1.1;opacity:.6}
.shan .boat-wake path:nth-child(3){stroke-width:.8;opacity:.4}
.shan .boat .hull{fill:#1a181e;opacity:.82}
.shan .boat .canopy{fill:#1a181e;opacity:.72}
.shan .boat .rib{fill:none;stroke:#efeae0;stroke-width:.9;opacity:.5}
.shan .boat .figure{stroke:#1a181e;stroke-width:2.4;stroke-linecap:round}
.shan .boat .head{fill:#1a181e}
.shan .boat .pole{stroke:#1a181e;stroke-width:1.4;opacity:.75;stroke-linecap:round}
.shan .boat .signal-residue{fill:#fff;stroke:#9c4939;stroke-width:1;opacity:0;
  filter:drop-shadow(0 0 5px rgba(255,255,255,.9))}
.shan .boat{opacity:0}
.poem{font-family:var(--f-serif);writing-mode:vertical-rl;text-orientation:upright;
  font-size:13px;letter-spacing:.5em;opacity:.42;align-self:flex-start;margin-top:6px}

/* — 01 可操纵的小人 — */
.pixgame{inset:0;width:100%;height:100%;image-rendering:pixelated}
html[data-ch="1"] .pixgame{opacity:1}
.keyhint{position:fixed;left:70%;top:clamp(112px,13vh,178px);transform:translateX(-50%);
  z-index:40;width:min(560px,42vw);display:grid;
  grid-template-columns:auto minmax(0,1fr) auto;grid-template-areas:
    "pulse copy keys" "pulse touch touch";gap:7px 14px;align-items:center;
  border:3px solid var(--accent);background:color-mix(in srgb,var(--bg) 88%,#000);
  padding:14px 17px 13px;box-shadow:7px 7px 0 rgba(0,0,0,.54),0 0 32px color-mix(in srgb,var(--accent) 22%,transparent);
  font-family:var(--f-mono);color:var(--ink);pointer-events:none;opacity:0;
  transition:opacity .5s var(--ease),transform .5s var(--ease)}
html[data-ch="1"] .keyhint{opacity:1;animation:missionAttention 2.2s steps(2,end) 1}
.keyhint::after{content:"";position:absolute;left:50%;top:100%;height:34px;
  border-left:2px dashed var(--accent);opacity:.72}
.mission-pulse{grid-area:pulse;width:14px;height:14px;background:var(--accent);
  box-shadow:0 0 0 7px color-mix(in srgb,var(--accent) 16%,transparent);animation:missionPulse 1.25s steps(2) infinite}
.mission-copy{grid-area:copy;display:flex;flex-direction:column;gap:3px;min-width:0}
.mission-copy small{font-size:8px;letter-spacing:.3em;color:var(--accent)}
.mission-copy strong{font-size:15px;letter-spacing:.12em;font-weight:400;white-space:nowrap}
.mission-keys{grid-area:keys;display:flex;align-items:center;gap:5px;white-space:nowrap}
.mission-keys b{display:inline-block;border:2px solid currentColor;padding:3px 7px;font-weight:400;font-size:9px}
.mission-keys em{font-style:normal;font-size:8px;letter-spacing:.12em;opacity:.54;margin-right:3px}
.mission-touch{grid-area:touch;font-size:9px;letter-spacing:.12em;opacity:.58}
.keyhint.done{opacity:0!important;transform:translate(-50%,-8px)}
@keyframes missionAttention{0%,38%{box-shadow:7px 7px 0 rgba(0,0,0,.54),0 0 42px color-mix(in srgb,var(--accent) 42%,transparent)}100%{box-shadow:7px 7px 0 rgba(0,0,0,.54),0 0 32px color-mix(in srgb,var(--accent) 22%,transparent)}}
@keyframes missionPulse{50%{opacity:.36;transform:scale(.72)}}
@media (max-width:860px){
  .keyhint{left:50%;top:auto;bottom:clamp(210px,31vh,280px);width:min(92vw,520px);
    grid-template-columns:auto minmax(0,1fr);grid-template-areas:"pulse copy" "keys keys" "touch touch";
    padding:12px 14px}
  .mission-copy strong{font-size:13px;white-space:normal}
  .mission-keys{justify-content:flex-start}
}

@media (max-width:860px){
  #ch2 .stage-split{grid-template-columns:1fr;gap:22px;align-content:center}
  #ch2 .col-l{max-width:100%}
  #ch2 .col-r{order:2;justify-content:flex-end;width:100%}
  #ch2 .tele{width:min(300px,88vw)}
  .terrain{height:130px}
  .tree-stage{right:-14vw;bottom:18vh;width:112vw;height:64vh}
  .tree-cycle{transform-origin:64% 77.5%}
  .bloom-soil{height:24vh}
  .bloom-impact{left:64%}
  .signal-leaf{width:76px}
  .stage-latent{padding-top:76px;gap:10px}
  .title-latent{font-size:clamp(25px,8vw,38px)}
  .latent-state{gap:9px}.latent-state span{display:none}
  .latent-leaf{width:112px}
  .latent-memories{left:10px;right:10px;top:31vh;bottom:11vh;gap:5px}
  .memory{height:48vh;justify-content:center}
  .memory-object{height:31vh}
  .memory-star .memory-object img{padding:clamp(24px,7vw,38px)}
  .memory-orbit .memory-object img{padding:clamp(26px,7vw,38px) 0}
  .memory-tree .memory-object img{padding:6px 0 0}
  .memory figcaption{grid-template-columns:1fr;height:36px;text-align:center;gap:2px}
  .memory figcaption span{display:none}.memory figcaption b{font-size:10px;letter-spacing:.08em}
  .memory figcaption em{font-size:7px;letter-spacing:.1em}
  .latent-copies{inset:20vh 0 3vh}
  .latent-copy{width:82px;height:82px}
  .poem{display:none}
  .hpwrap{flex-wrap:wrap;gap:9px}
  .probs{height:32px}
}
