/* ==========================================================================
   一脉出海 H5 · ambient.css —— 开场层（幕布）+ 七屏背景
   —— 来源：tools/proto-opening.html（原型本体）与 docs/第四轮-开场与背景原型说明.md
      §三 时序 / §七 反衬口径（三处背景压暗值**逐字照抄原型**，不许自行重定亮度）。
   —— 色值只许 var(--…)（契约 §4）；原型用 color-mix 推导的档位已按文档 §六.3 的
      落码要求改为 tokens.css 里的 rgba 定值（--lane-40 / --deep-55 / --deep-72）。
   —— 时钟纪律：开场交接挂 animationend；背景只碰 transform / opacity；
      循环动画按屏 .is-live 只让可见屏跑（js/ambient.js 的 IntersectionObserver 切换）。
   —— 层序：幕布 z:5（盖住 s01 的线/内容/装饰，chrome z:30 之上）；背景 z:-1
      （在符号画布 z:0 之下、进流内容之下 —— 衬底永远托着主脉与文字）。
   ========================================================================== */

/* ---------------------------------------------------------------------------
   一、开场层（幕布）—— 时序 ≈2.4s（原型 §三）：
   0–900 线自行绘出（--dur-draw/--ease）→ 520 展会全称 / 620 起点读数 →
   720/830/940/1050 展名逐字（各 480ms，步进 110）→ 1780–2420 整屏「落」
   （scale .88 + 下坠 4% + 渐隐，origin 26% 18%）→ animationend 交接。
   基样式即终态：reduced / 跳过只摘播放类即落定（零补丁）。
   --------------------------------------------------------------------------- */
.op-veil{position:absolute;inset:0;z-index:5;display:none;pointer-events:none;background:var(--ink)}
html.op-on .op-veil{display:block}
html.op-done .op-veil{display:none !important}
/* S8 兜底（审计账 #1，2026-10-16 收尾刀）：opening.js 加载失败时，退场逻辑（动态）缺席、
   幕布（静态在 index.html）永盖 01 屏 —— 此处给幕布一条**纯 CSS 兜底**：3.6s 后自行淡出 +
   visibility:hidden（零 JS 零时钟）。选择器 :not(.op-play)：正常路径 JS 活着 → boot() 先加
   .op-play，本动画被整段取消，正常时序仍由 JS 完全掌控（零拖慢）；仅当脚本没跑起来、
   .op-play 永不出现时兜底唯一生效。 */
html.op-on .op-veil:not(.op-play){animation:opFailsafe 480ms var(--ease) 3600ms both}
@keyframes opFailsafe{to{opacity:0;visibility:hidden}}
.op-veil-bg{position:absolute;inset:0;background:var(--ink)}
.op-veil-bg::before{ /* 经纬网格：与 body::before 同图（90px 方格 / lane-12） */
  content:'';position:absolute;inset:0;background-image:var(--img-grid)}
.op-veil-bg::after{ /* 等深线：与 s01 的 .deco-isobath 同图 —— 落定揭幕时零跳变 */
  content:'';position:absolute;inset:0;background-image:var(--img-isobath)}
.op-veil-svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible}
.op-seg{fill:none;stroke:var(--pulse);stroke-width:var(--sw-line);stroke-linecap:round;stroke-linejoin:round;
  vector-effect:non-scaling-stroke;stroke-dasharray:var(--dl,1px) calc(var(--dl,1px) * 2);stroke-dashoffset:0}
.op-glow{fill:none;stroke:var(--pulse);stroke-width:18px;stroke-linecap:round;vector-effect:non-scaling-stroke;
  opacity:.14;stroke-dasharray:var(--dl,1px) calc(var(--dl,1px) * 2);stroke-dashoffset:0}
.op-branch{fill:none;stroke:var(--pulse);stroke-width:var(--sw-dash);stroke-linecap:round;vector-effect:non-scaling-stroke;
  opacity:.5;stroke-dasharray:var(--dl,1px) calc(var(--dl,1px) * 2);stroke-dashoffset:0}
.op-head{position:absolute;left:62%;top:2%;width:14px;height:14px;border-radius:50%;
  transform:translate(-50%,-50%);background:var(--ink);border:var(--sw-icon) solid var(--pulse)}
.op-title{position:absolute;left:calc(var(--pad-x) + var(--sal));
  top:max(var(--safe-top),calc(var(--sat) + var(--clear-chrome)));
  display:flex;flex-direction:column;gap:var(--gap-block)}
.op-ch{display:inline-block}
/* 播放类（js/opening.js 在非 reduced 启动时加）：全 CSS 延迟时间轴，无 JS 时钟 */
.op-veil.op-play .op-glow,.op-veil.op-play .op-seg{animation:opDraw var(--dur-draw) var(--ease) both}
.op-veil.op-play .op-branch{animation:opDraw var(--dur-draw) var(--ease) both}
.op-veil.op-play .op-branch:nth-of-type(3){animation-delay:640ms}
.op-veil.op-play .op-branch:nth-of-type(4){animation-delay:760ms}
.op-veil.op-play .op-branch:nth-of-type(5){animation-delay:880ms}
.op-veil.op-play .op-head{animation:opIn var(--dur-in) var(--ease) 620ms both}
.op-veil.op-play .op-vk{animation:opIn var(--dur-in) var(--ease) 520ms both}
.op-veil.op-play .op-ch{animation:opIn var(--dur-in) var(--ease) both}
.op-veil.op-play .op-ch:nth-of-type(1){animation-delay:720ms}
.op-veil.op-play .op-ch:nth-of-type(2){animation-delay:830ms}
.op-veil.op-play .op-ch:nth-of-type(3){animation-delay:940ms}
.op-veil.op-play .op-ch:nth-of-type(4){animation-delay:1050ms}
.op-veil.op-play{animation:opFall 640ms var(--ease) 1780ms both;transform-origin:26% 18%}
@keyframes opDraw{from{stroke-dashoffset:var(--dl,1px)}to{stroke-dashoffset:0}}
@keyframes opIn{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}}
@keyframes opFall{to{opacity:0;transform:scale(.88) translateY(4%)}}

/* 交接 =「续画」（老爹 2026-10-16 拍板）：kicker / 标题已在幕布上现过 —— 交接后不重播
   （同原型 entered 态：animation:none 的口径，此处用 !important 一票置终态）。
   :not(.op-vk) 把幕布上的副本挡住，只钉真件。 */
html.op-entered #s01 .cover-kicker:not(.op-vk),html.op-entered #s01-title{opacity:1 !important;transform:none !important}
/* 二段跳过：落终态（= 原型 settle 的「animation:none 即终态」——一票置 s01 入场项终态） */
html.op-settle #s01 .cover-kicker:not(.op-vk),html.op-settle #s01-title,
html.op-settle #s01-word-1,html.op-settle #s01-word-2,html.op-settle #s01-word-3,
html.op-settle #s01-zones .zone-chip,html.op-settle #s01-cta{opacity:1 !important;transform:none !important}

/* ---------------------------------------------------------------------------
   二、七屏背景（按屏挂内容）：星 → 01/10；电子元件流光 → 03/07/08；城市火光 → 06/09。
   压暗值逐字照抄原型 §七（7.1 表）：星 far .13 / near .28 / 核 .5 / 环 lane-22 / 航路 lane-40@.5；
   电路 dot .34 / halo .12 / node .28 / 03 竖列总线只画一条；火光 窗 .32（次排 .22）/
   环境光 stop .10 / 呼吸 .58–.82（基态 .82 = 峰值，reduced 关动画不反超）。
   入场为一次性错峰（.enter 首见时永久加上）；循环动画只挂可见屏（.is-live）。
   --------------------------------------------------------------------------- */
.bgwrap{position:absolute;inset:0;z-index:-1;pointer-events:none}
/* 底部暗收（120px 门帘）：页脚文字带里的背景沉回基色 —— 口径 §七 的意图（老爹：「背景的
   暗度应该反衬我们要宣传的」）。来历：页脚小字（碳读数等）在该带实测衬底 P90 0.0353 →
   对比 3.85 < 4.5（tools/ambient-check.mjs 首跑红态）；压暗三族的值已冻结（不许重定亮度），
   故只在**背景层自身**收一个门帘，内容侧一字未动。峰值带（火光暖窗等）在门帘上沿之上，
   不受影响（1a 读数不变 —— 见落码报告「底部暗收」节）。 */
.bgwrap::after{content:'';position:absolute;left:0;right:0;bottom:0;height:120px;
  background:linear-gradient(to bottom, transparent, var(--ink) 55%);pointer-events:none}
.bg-svg{position:absolute;inset:0;width:100%;height:100%;display:block}
.bgi{opacity:1}
@keyframes bgiIn{from{opacity:0}to{opacity:1}}
.bgwrap.enter .bgi{animation:bgiIn var(--dur-in) var(--ease) var(--d,0ms) both}
.bgwrap.enter .bg-lamp-in{animation:bgiIn 700ms var(--ease) var(--d,0ms) both}
.bgwinwrap{opacity:.82}
.bg-glowwrap{opacity:.82}
@keyframes ember{0%,100%{opacity:.58}50%{opacity:.82}}

/* —— 星 · 01/10（夜航·海图）：两组星图缓慢视差横移 —— 星不闪，「船在走」 —— */
.bg-star{fill:var(--paper)}
.bg-star-f1{fill-opacity:.13}
.bg-star-n1{fill-opacity:.28}
@keyframes driftA{from{transform:translateX(0)}to{transform:translateX(-14px)}}
@keyframes driftB{from{transform:translateX(0)}to{transform:translateX(-26px)}}
.bgwrap.is-live .bg-drift-a{animation:driftA 170s ease-in-out infinite alternate}
.bgwrap.is-live .bg-drift-b{animation:driftB 230s ease-in-out infinite alternate}
.bg-star-ring{fill:none;stroke:var(--lane-22);stroke-width:1}
.bg-star-core{fill:var(--lane);fill-opacity:.5}
.bg-route{fill:none;stroke:var(--lane-40);stroke-width:var(--sw-dash);stroke-dasharray:var(--dash-route);opacity:.5}

/* —— 电子元件流光 · 03/07/08：直角走线 + 空心节点，光点沿走线走（电流在做事） —— */
.bg-trace{fill:none;stroke:var(--lane-22);stroke-width:var(--sw-grid);stroke-linejoin:miter}
.bg-node{fill:var(--ink);stroke:var(--pulse);stroke-opacity:.28;stroke-width:var(--sw-icon)}
.bg-dot{fill:var(--pulse);fill-opacity:.34}
.bg-dot-halo{fill:var(--pulse);fill-opacity:.12}
@keyframes flowX{0%{transform:translateX(0);opacity:0}6%{opacity:1}90%{opacity:1}100%{transform:translateX(var(--dx));opacity:0}}
@keyframes flowY{0%{transform:translateY(0);opacity:0}6%{opacity:1}90%{opacity:1}100%{transform:translateY(var(--dy));opacity:0}}
.bgwrap.is-live .bg-flow-x{animation:flowX var(--flow-dur,11s) linear infinite}
.bgwrap.is-live .bg-flow-y{animation:flowY var(--flow-dur,9s) linear infinite}

/* —— 城市火光 · 06/09：天际线剪影 + 暖窗；慢「呼吸」而非闪烁 —— */
.bg-sky{fill:var(--deep-55)}
.bg-sky-far{fill:var(--deep-72)}
.bg-win{fill:var(--sun);fill-opacity:.32}
.bgwrap.is-live .bgwinwrap{animation:ember 11s ease-in-out infinite}
.bgwrap.is-live .bg-glowwrap{animation:ember 9s ease-in-out infinite}

/* ---------------------------------------------------------------------------
   三、reduced-motion：开场落终态、背景定格（内容零损失）。
   —— 背景定格 = 动画某一帧的快照：光点按各自相位（--rx/--ry）静态散开 ——
      不叠在同一起点（叠点亮度 ×6，实测 0.540 越线，口径 §七 7.7-5）。
   —— 双保险：媒体查询 + body.is-reduced（body 类由 js/interact/index.js 按
      motion.js 的 isReduced() / motion:reduced 广播维护 —— 判定入口仍在 motion.js 一处）。
   --------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce){
  .op-veil{display:none !important}
  .op-veil *,.bgwrap *{animation:none !important}
  .bg-dot-g{transform:translate(var(--rx,0px),var(--ry,0px))}
}
body.is-reduced .op-veil{display:none !important}
body.is-reduced .op-veil *,body.is-reduced .bgwrap *{animation:none !important}
body.is-reduced .bg-dot-g{transform:translate(var(--rx,0px),var(--ry,0px))}
