/* ember.css v2 — Ember 章节页（推翻重构版）。
   版式观：满幅是叙事资源不是默认值——扉页(纯排印)→厅(装裱框)→她面前(满幅硬切链)→
   打量(策展画廊)→驻停/竖联/反拉(沉浸段)。前半版式化、后半沉浸化=「越走越近」。
   叙事骨架出自 _build/research/ 幕表（E0..E7）；四幕硬切链语法：cut on action，
   切点两侧速度非零同向；滚动契约全页只切一次（叙事段连续 sticky 链→档案幕文档流）。
   规则同 portal.css：只消费 vendor 语义变量，不碰 vendor 文件，不造 vx- 类。 */

/* ── 通用（占位/导航/连续染色氛围） ── */

.ph { color: var(--text-low); font-size: calc(12px * var(--ratio, 1)); letter-spacing: .04em; }
.ph::before { content: "〔待品牌方：" attr(data-ph) "〕"; }
/* i18n 接上后由 applyLang 写 data-ph-label（前缀跟语言走，占位项名保持中文——
   读者是品牌方）。没有 JS 时上面那条就是终态，两者中文写法刻意一致，不会闪一下 */
.ph[data-ph-label]::before { content: "〔" attr(data-ph-label) "〕"; }

/* 导航保底压暗（2026-07-30 全站 26 点对比度实测后加）：
   vendor 的 .vx-nav 默认全透明，滚动后也只加一层很淡的毛玻璃，链接色是 --text-mid。
   导航压在亮画面上时对比度实测掉到 1.08–1.13（玄关双门那扇天光窗、
   胶片横廊的白瓷浴缸、partner 的亮底幅）——那三个字在截图里根本认不出来。
   用渐变而非实底色：保留「悬浮在画面上」的观感，往下多铺 30px 淡出，不留硬边；
   底色取 --bg-base，跟着分区主题走（亮色模式下自然变成亮 scrim，方向仍然正确）。
   ::before 必须 position:absolute —— .vx-nav 是 flex 容器，
   静态定位的伪元素会变成 flex item，把品牌与链接挤开。 */
.vx-nav::before {
  content: "";
  position: absolute;
  /* 往下多铺 46px 而不是 30px：盒子越高，尾巴越长，亮画面上才不会看出一条硬边的黑带。
     链接行落在盒子 15%–41% 处（导航高约 71px），所以 44% 之前必须还是满强度。 */
  inset: 0 0 -46px 0;
  z-index: -1;
  pointer-events: none;
  background: linear-gradient(180deg,
    color-mix(in oklab, var(--bg-base) 92%, transparent) 0%,
    color-mix(in oklab, var(--bg-base) 84%, transparent) 44%,
    color-mix(in oklab, var(--bg-base) 34%, transparent) 72%,
    transparent 100%);
}

.world-nav-links { display: flex; gap: clamp(18px, 3vw, 40px); }
.world-nav-links a {
  color: var(--text-mid);
  text-decoration: none;
  font-size: calc(12.5px * var(--ratio, 1));
  letter-spacing: .22em;
  transition: color var(--dur-base, .3s);
}
.world-nav-links a:hover { color: var(--text-hi); }

body { --sync-mix: color-mix(in oklab, var(--sync-from, var(--accent)), var(--sync-to, var(--accent)) calc(var(--sync-p, 0) * 100%)); }

.world-tint {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: radial-gradient(ellipse 90% 62% at 50% -6%,
    color-mix(in oklab, var(--sync-mix) 16%, transparent),
    transparent 74%);
}
/* .vx-nav 不进这条：vendor 导航是 position:fixed（z-index:var(--z-nav)），写 relative 会打回文档流 */
main, .vx-footer { position: relative; z-index: 1; }

.world-nav .vx-nav__brand img { width: 34px; display: block; }

/* ── 钉住舞台通用（--pin-p 由 world.js 写入；叙事段 section 全部 --flush 零间隙，
   幕与幕靠 sticky 对滑相接，一格滚动买镜头不买平移） ── */

/* 滚动语法配额（对齐 plum「每幕一种滚法」）：钉住只留给叙事链的三件（硬切/驻停/反拉）
   加洗刷视频；E0 是 dolly 暗场、E1 是文档流路过、E4 是横向——七幕七种动词，不复读。 */
.pin { position: relative; }
.pin-e23 { height: 380svh; }  /* 背身→对视：单舞台硬切，切点 p=.5 */
.pin-e5 { height: 300svh; }   /* 驻停：时间密度峰 */
.pin-e7 { height: 180svh; }   /* 收束：唯一反拉 */

.stage {
  position: sticky;
  top: 0;
  height: 100svh;
  overflow: clip;
  isolation: isolate;
  background: var(--bg-base);
}

/* 运镜属性一律不挂 transition：滚动每帧都在给新目标值，过渡只会追不上 */
.stage img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}

/* ── 幕间交接工艺（plum night→detail 的原机制，不是它的装饰）──
   生硬拼接的根因不在缝的样式，在交接区间里两幕都是死的：
   前幕行程走完钉在终值，后幕 p=0 等着被平推上来——中间只有位移没有运动。
   plum 的解法是让两件事同时发生：
   ①下一幕负 margin 提前入场，趁前幕行程未走完（画面还在推近）就从底下盖上来；
   ②盖上来的舞台顶缘用 mask 挖透明，前幕的活画面从透明区透出来，
     被实边逐渐「吞掉」而不是先沉暗再换块。切点两侧速度非零同向，页面级 cut on action。
   钉住期 mask 顶缘透出的是分区底色，退化为电影暗角，与旧羽化视觉连续。
   同舞台的图像切换（E2→E3）仍是瞬切——溶解被研究实测否过。 */
/* 图不贴图：满幅图像幕的上一段永远是深底（E1 段尾 30svh 暗场、画廊 38svh 展墙缓冲、
   竖联自带深底负空间）。盖入只发生在「图盖深底」或「深底盖图」，直线边界无处可见。 */
.ember-hall, .ember-e23, .ember-gal, .ember-e5, .ember-zip, .ember-e7, .ember-file {
  position: relative;
}
.ember-hall { z-index: 2; }
.ember-e23  { margin-top: -26svh; z-index: 3; }
.ember-gal  { margin-top: -34svh; z-index: 4; }
.ember-e5   { margin-top: -26svh; z-index: 5; }
.ember-zip  { margin-top: -28svh; z-index: 6; }
.ember-e7   { margin-top: -26svh; z-index: 7; }
.ember-file { margin-top: -12svh; z-index: 8; }

/* 盖入图像的顶缘吞口：22svh 透明渐变——10svh 实测在深底上读作直线切（用户真机截图），
   要让画面「沉入/浮出暗场」渐变必须占到近四分之一屏。
   蒙版挂图片容器（focal）而非 stage：plum night 同款——挂 stage 会把 beat-line
   一起吃掉（sticky 钉住期 mask 恒在，top 9svh 的字会永久减淡 ~60%）。
   stage 底色照旧：它对着的前一段永远是深底，深底对深底，边界隐形。 */
.e2-focal, .e3-focal, .e5-focal, .e7-focal {
  mask-image: linear-gradient(180deg, transparent 0, #000 22svh, #000 100%);
}

/* 装裱件公共工艺：圆角、暖描边、深晕——图像被展出，不是被平铺 */
.hall-frame, .gal-mat, .zip-frame {
  border-radius: var(--radius-lg, 16px);
  overflow: clip;
  isolation: isolate;
  border: 1px solid color-mix(in oklab, var(--accent) 20%, transparent);
  box-shadow: 0 30px 90px rgb(0 0 0 / .55);
  background: var(--bg-inset, #111);
}

/* 满幅幕的字（沉浸段短句） */
.beat-line {
  position: absolute;
  z-index: 1;
  margin: 0;
  font-weight: 300;
  font-size: clamp(22px, 2.6vw, 40px);
  letter-spacing: .28em;
  color: #fff;
  text-shadow: 0 2px 24px rgb(0 0 0 / .72);
}

/* ── E0 · 扉页（纯排印：天黑在字面上发生，炉火在深处亮起来。
   plum 雾镜同构：hero + dolly，首屏载入时 progress≈0.5，0.5→0.92 的滚动区间入夜。
   挂 vx-dolly 只为拿进度，不要它的媒体框 ── */

.ember-leaf {
  display: grid;
  place-items: center;
  text-align: center;
  aspect-ratio: auto;
  /* 入夜进度：滚出扉页的过程 = 天黑透 */
  --leaf-t: clamp(0, (var(--dolly-progress, .5) - .5) / .42, 1);
}

.leaf-glow {
  position: absolute; inset: 0;
  pointer-events: none;
  /* 上层：入夜（暮蓝沉到近黑）；下层：炉火光斑随走近变亮变大 */
  background:
    linear-gradient(180deg,
      rgb(14 18 34 / calc(.12 + .5 * var(--leaf-t))),
      rgb(5 4 7 / calc(.22 + .62 * var(--leaf-t)))),
    radial-gradient(ellipse calc(46% + 22% * var(--leaf-t)) calc(30% + 14% * var(--leaf-t)) at 50% 96%,
      rgb(255 122 58 / calc(.12 + .3 * var(--leaf-t))),
      rgb(120 34 18 / calc(.05 + .12 * var(--leaf-t))) 55%,
      transparent 78%);
}

.leaf-body {
  position: absolute; inset: 0;
  z-index: 1;
  display: grid;
  place-content: center;
  justify-items: center;
  text-align: center;
  gap: clamp(22px, 4svh, 44px);
}

.leaf-kicker {
  font-size: clamp(13px, 1.4vw, 17px);
  letter-spacing: .9em;
  text-indent: .9em;
  color: var(--text-mid);
}
.leaf-kicker .ph { display: block; margin-top: 10px; letter-spacing: .06em; text-indent: 0; }

/* 章题：炉火色渐变字（模板 sunset 渐变），随入夜从灰烬里亮起来 */
.leaf-title {
  --vx-text-gradient: var(--gradient-sunset);
  font-weight: 250;
  font-size: clamp(40px, 6.4vw, 96px);
  letter-spacing: .16em;
  filter: brightness(calc(.72 + .5 * var(--leaf-t)));
}

.leaf-hint {
  font-size: calc(13px * var(--ratio, 1));
  letter-spacing: .5em;
  text-indent: .5em;
  color: var(--text-mid);
  opacity: calc(.4 + .6 * var(--leaf-t));
}

/* 引路线：一根竖直金线从章题脚下往画面底生长——「往屋里走」的方向本身 */
.leaf-wire {
  position: absolute;
  left: 50%;
  bottom: 0;
  width: 1px;
  height: calc(var(--leaf-t) * 16svh);
  background: linear-gradient(180deg, transparent, var(--accent));
  opacity: .8;
}

/* ── E1 · 厅（文档流版式段：左竖排字、右装裱框；点灯由穿屏进度驱动。
   挂 vx-dolly 在 section 上（plum turn 同款），全段共用 --dolly-progress。
   段尾 30svh 深底：E23 从这片暗场里浮现，满幅图不与亮框相贴 ── */

.ember-hall {
  aspect-ratio: auto;
  padding-block: clamp(48px, 9svh, 120px);
  padding-bottom: 30svh;
  background: linear-gradient(180deg, transparent, var(--bg-base) 14svh);
}

.hall-grid {
  display: grid;
  grid-template-columns: minmax(180px, 30%) 1fr;
  align-items: center;
  gap: clamp(18px, 3vw, 48px);
  padding-inline: clamp(20px, 5vw, 84px);
}

.hall-vline {
  justify-self: center;
  margin: 0;
  writing-mode: vertical-rl;
  font-weight: 300;
  font-size: clamp(20px, 2.1vw, 32px);
  letter-spacing: .42em;
  line-height: 2.4;
  color: var(--text-hi);
  /* 竖排字随点灯反向微浮（plum 夜幕的 DNA，换了用处） */
  transform: translateY(calc(var(--dolly-progress, 0) * -3svh));
  opacity: calc(min(1, .25 + var(--dolly-progress, 0) * 2.2));
}
.hall-vline .hv-b {
  display: block;
  margin-top: 1.2em;
  font-size: .62em;
  color: var(--text-mid);
  letter-spacing: .5em;
}

.hall-frame {
  position: relative;
  height: min(82svh, 860px);
}
.hall-focal {
  position: absolute; inset: 0; display: block;
  --focal: 50% var(--fy, 26%);
}
.hall-img {
  /* 不再住在 .stage 里，满铺规则自己带 */
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  transform: scale(calc(1.02 + .1 * var(--dolly-progress, 0)));
  transform-origin: 50% 30%;
  filter: brightness(calc(.64 + .42 * var(--dolly-progress, 0)));
}
/* 暮色纱：进门时屋里是暗的，滚动=灯亮，纱从框里退掉 */
.hall-veil {
  position: absolute; inset: 0;
  pointer-events: none;
  background: linear-gradient(168deg,
    rgb(18 24 40 / .5),
    rgb(30 20 14 / .3) 52%,
    rgb(8 6 10 / .55));
  opacity: calc(min(1, (1 - var(--dolly-progress, 0)) * 1.4));
}

/* ── E2+E3 · 背身→对视（满幅第一次；单舞台硬切链，p=.5 瞬切）
   溶解被研究实测推翻过两次（重影压不住），所以是瞬切不是渐变。 ── */

.e2-focal {
  position: absolute; inset: 0; display: block;
  /* 纵摇：脸(24%)→背脊→腰际金链(47%)。窗到 p=.55，在 .5 被切时仍在运动 */
  --focal: 50% calc(24% + min(var(--pin-p, 0), .55) / .55 * 23%);
  opacity: clamp(0, (.5 - var(--pin-p, 0)) * 1000, 1);
}
.e2-img {
  transform: scale(calc(1.02 + .07 * min(var(--pin-p, 0), .55) / .55));
  transform-origin: 50% 30%;
  filter: brightness(calc(.9 + .09 * min(var(--pin-p, 0), .55) / .55));
}

.e3-focal {
  position: absolute; inset: 0; display: block;
  /* 入场即动：切点接手时已带 5% 推近量，继续推到 1.18、焦点 21%→15% 锁脸 */
  --focal: 50% calc(21% - max(0, var(--pin-p, 0) - .5) * 2 * 6%);
  opacity: clamp(0, (var(--pin-p, 0) - .5) * 1000, 1);
}
.e3-img {
  transform: scale(calc(1.05 + .13 * max(0, var(--pin-p, 0) - .5) * 2));
  transform-origin: 50% 24%;
  filter: brightness(calc(.95 + .05 * max(0, var(--pin-p, 0) - .5) * 2));
}

/* 两条字卡钉同一坐标：换行的瞬间就是换画面的瞬间 */
.e2-line,
.e3-line {
  top: clamp(26px, 9svh, 110px);
  right: clamp(20px, 6vw, 96px);
}
.e2-line {
  opacity: clamp(0, min((var(--pin-p, 0) - .04) * 9, (.5 - var(--pin-p, 0)) * 1000), 1);
}
.e3-line {
  opacity: clamp(0, (var(--pin-p, 0) - .5) * 1000, 1);
}

/* ── E4 · 打量（策展画廊：一屏一幅拍板不动；每幅是装裱件，负空间是展墙） ── */

/* 背景用 transparent→bg-base 渐变（plum detail 的交接配方）：
   渐变深度必须 ≥ 负 margin 吞入深度(34svh)，否则实底边会在交接中期硬压到 E3 脸上。
   kicker 落在渐变半途，字下透着还在推近的对视画面进场（plum kicker 同款）。
   底部 padding 加回 26svh：E5 提前盖入吃掉的空间，别让它压住拖动提示 */
.ember-gal {
  padding-block: clamp(26px, 4.5svh, 60px);
  /* 顶部让渡整个渐变深度：渐变区(34svh)里只有 kicker 一行字压在 E3 的画面上进场，
     图卡等渐变完成、背景落成实底后才出现——实体压实体，不压脸（用户真机截图实测过压脸） */
  padding-top: 38svh;
  padding-bottom: calc(clamp(26px, 4.5svh, 60px) + 26svh);
  background: linear-gradient(180deg, transparent, var(--bg-base) 34svh);
}

/* kicker 提回渐变半途（14svh 档）：字先压在 E3 渐隐的画面上进场（plum kicker 语义），
   图卡则等实底落成再出现。必须 absolute 脱流——负 margin 会把图卡一起拉进渐变区，
   实测图卡压在 E3 半透画面上（图贴图复发） */
.gal-head { position: absolute; top: 14svh; left: 0; right: 0; }
.gal-kicker {
  font-size: clamp(15px, 1.7vw, 20px);
  letter-spacing: .5em;
  text-indent: .5em;
  color: var(--text-hi);
  text-shadow: 0 1px 18px rgb(0 0 0 / .8);
  margin-bottom: clamp(20px, 3.5svh, 40px);
}

.gal-item {
  position: relative;
  margin: 0;
  height: min(86svh, 760px);
  display: grid;
  grid-template-rows: 1fr auto;
  justify-items: center;
  row-gap: clamp(14px, 2.5svh, 26px);
  aspect-ratio: auto;
  border-radius: 0;
  overflow: visible;
}

/* 相邻装裱件负边距重叠：当前件居中时，下一件的卡边永远在视口缘探出 ~5vw——
   不点提示也知道旁边还有；探出条被 --h-visible 入场暗化压着，不抢主画。
   重叠量必须随垫的实际缩进走：垫宽有 1180px 上限，宽屏下缩进(92vw-垫)/2 会变大，
   固定重叠会把邻垫推出视口外（1900px 宽实测消失过）。
   目标恒等式：4vw(item自然露出) + 重叠 - 缩进 = 5vw peek ⇒ 重叠 = 缩进 + 1vw */
.gal-item { margin-inline: calc(-1 * ((92vw - min(78vw, 1180px)) / 4 + .5vw)); }
.gal-item:first-child { margin-inline-start: 0; }
.gal-item:last-child { margin-inline-end: 0; }

/* 装裱垫：图不再怼满 item——78vw 居中，展墙(同色负空间)从两侧透进来；
   相邻件的图彼此隔着 14vw 展墙，同屏永远只有一幅完整画面 */
.gal-mat {
  position: relative;
  width: min(78vw, 1180px);
  height: 100%;
  min-height: 0;
}
.gal-focal {
  position: absolute; inset: 0; display: block;
  --focal: 50% var(--fy, 45%);
}
.gal-mat img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  filter: brightness(calc(.7 + .32 * var(--h-visible, 1)));
}

.gal-item figcaption {
  display: flex;
  align-items: baseline;
  gap: clamp(12px, 1.6vw, 22px);
  width: min(78vw, 1180px);
}
.gal-item figcaption i {
  font-style: normal;
  font-weight: 200;
  font-size: clamp(40px, 5vw, 72px);
  line-height: 1;
  letter-spacing: .04em;
  color: color-mix(in oklab, var(--text-low) 55%, transparent);
}
.gal-item figcaption b {
  font-weight: 400;
  font-size: clamp(15px, 1.7vw, 21px);
  letter-spacing: .5em;
  color: var(--text-hi);
}
.gal-item figcaption u {
  flex: 0 0 clamp(40px, 5vw, 80px);
  height: 1px;
  align-self: center;
  background: linear-gradient(90deg, var(--accent), transparent);
  opacity: .7;
}

.gal-hint {
  margin-top: clamp(14px, 2.5svh, 26px);
  text-align: center;
  font-size: calc(13px * var(--ratio, 1));
  letter-spacing: .4em;
  text-indent: .4em;
  color: var(--text-mid);
}

/* 鼠标拖拽横滚（world.js 在拖拽中挂 is-grabbing）：
   不暂停 mandatory snap 的话，拖动中每帧 scrollLeft 都会被吸附点拉回去=根本拖不动 */
.gal-track { cursor: grab; }
.gal-track.is-grabbing {
  cursor: grabbing;
  scroll-snap-type: none;
  user-select: none;
}

/* ── E5 · 嘘（满幅驻停：长行程极小推近；小字在中段浮现，字距缓缓张开） ── */

.e5-focal {
  position: absolute; inset: 0; display: block;
  --focal: 50% var(--fy, 42%);
}
.e5-img {
  /* 研究定死的推近上限 S≤1.13：300svh 里只推这么多，时间被拉到最稠 */
  transform: scale(calc(1 + .13 * var(--pin-p, 0)));
  transform-origin: 46% 38%;
  /* 尾程熄灯（p>.85 亮度 1→.49）：画面走向 E6 的暗场调子，竖联的亮框从暗里立起来
     才不扎眼——白 poster 直角压在亮画面上实测刺目。仍在变暗=仍是活的，不是先死后切 */
  filter: brightness(calc(1 - max(0, var(--pin-p, 0) - .85) * 3.4));
}

.hush-word {
  position: absolute;
  z-index: 1;
  left: 50%;
  top: 62%;
  transform: translateX(-50%);
  margin: 0;
  font-size: clamp(14px, 1.2vw, 18px);
  letter-spacing: calc(.9em + var(--pin-p, 0) * .4em);
  text-indent: calc(.9em + var(--pin-p, 0) * .4em);
  color: rgb(255 255 255 / .92);
  text-shadow: 0 1px 14px rgb(0 0 0 / .85);
  opacity: calc(min(1, max(0, (var(--pin-p, 0) - .35) * 9)) * min(1, max(0, (.7 - var(--pin-p, 0)) * 9)));
}

/* ── E6 · 拉链（竖联装裱：竖源不硬塞满幅——居中竖框保画质，文案竖排在负空间） ── */

.zip-stage {
  display: grid;
  place-items: center;
  /* 顶部 22svh 透明吞口：盖入时 E5 的满幅从深底渐隐段里沉下去，竖联装裱件先立起来 */
  background:
    radial-gradient(ellipse 70% 55% at 50% 60%, rgb(120 40 20 / .16), transparent 72%),
    linear-gradient(180deg, transparent, var(--bg-base) 22svh);
}

.zip-frame {
  position: relative;
  margin: 0;
  aspect-ratio: 9 / 16;
  height: min(88svh, 92%);
}
.zip-frame .vx-scrub__media {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}

.zip-vline {
  position: absolute;
  left: clamp(24px, 9vw, 150px);
  top: 50%;
  translate: 0 -50%;
  margin: 0;
  writing-mode: vertical-rl;
  font-weight: 300;
  font-size: clamp(18px, 1.9vw, 28px);
  letter-spacing: .5em;
  color: var(--text-hi);
}

.zip-hint {
  position: absolute;
  right: clamp(20px, 6vw, 96px);
  bottom: clamp(22px, 7svh, 84px);
  margin: 0;
  font-size: calc(13px * var(--ratio, 1));
  letter-spacing: .5em;
  color: var(--text-mid);
}

/* ── E7 · 扣未解（满幅收束：全站唯一反拉，(1-p)² 末端落定） ── */

.e7-focal {
  position: absolute; inset: 0; display: block;
  --focal: 50% var(--fy, 50%);
}
.e7-img {
  transform: scale(calc(1 + .22 * (1 - var(--pin-p, 0)) * (1 - var(--pin-p, 0))));
  transform-origin: 50% 46%;
  filter: brightness(calc(1 - .1 * var(--pin-p, 0)));
}

.e7-line {
  left: clamp(20px, 6vw, 96px);
  bottom: clamp(26px, 9svh, 110px);
  opacity: calc(min(1, var(--pin-p, 0) * 2.2));
  /* 未完成句跟着镜头一起退：微沉微缩，和反拉同呼吸 */
  transform: translateY(calc(var(--pin-p, 0) * 1.6svh)) scale(calc(1 - var(--pin-p, 0) * .05));
  transform-origin: left bottom;
}

/* ── 档案铭牌（滚动契约切换点之后：文档流） ── */

.ember-file {
  padding-block: clamp(56px, 9svh, 120px);
  padding-top: clamp(80px, 16svh, 170px);
  background: linear-gradient(180deg, transparent, var(--bg-base) 16svh);
}

/* .dossier* 已移入 echo.css（2026-08-08）——两章共用同一块 DOM，样式却只写在这里，
   于是 plum 页那张档案铭牌一直是**无样式的裸 <dl>**（dt 独占一行、无栏无线）。
   之前每一格都只是一条短占位，看不太出来；这次把数据填进去，五行长文本一摊，
   缺样式当场显形。⇒ 同一块 DOM 的样式必须落在两章都加载的文件里。 */

/* ── 出口 ── */

.ember-exit { padding-block: clamp(120px, 22svh, 260px); }

.exit-wrap { text-align: center; display: grid; gap: clamp(30px, 5svh, 52px); }

.exit-line {
  font-weight: 250;
  font-size: clamp(22px, 3vw, 44px);
  letter-spacing: .22em;
  color: var(--text-hi);
}

.exit-links { display: flex; justify-content: center; gap: clamp(34px, 6vw, 90px); }

.exit-links a {
  color: var(--text-mid);
  text-decoration: none;
  font-size: calc(14px * var(--ratio, 1));
  letter-spacing: .3em;
  padding-bottom: 6px;
  border-bottom: 1px solid color-mix(in oklab, var(--accent) 30%, transparent);
  transition: color var(--dur-base, .3s), border-color var(--dur-base, .3s);
}
.exit-links a:hover {
  color: var(--text-hi);
  border-color: var(--accent);
}

/* ── 退化 ── */

/* 减弱动效：钉住舞台退成普通块；E2+E3 取「对视」为静态主帧；扉页取炉火亮起的终态 */
@media (prefers-reduced-motion: reduce) {
  .pin { height: auto; }
  .stage { position: static; height: clamp(420px, 88svh, 88svh); }
  /* 无滚动运镜就没有「活着被吞」，负 margin 交叠一并撤掉（plum 同款） */
  .ember-e23, .ember-gal, .ember-e5, .ember-zip, .ember-e7, .ember-file { margin-top: 0; }
  .ember-gal { padding-bottom: clamp(26px, 4.5svh, 60px); padding-top: clamp(60px, 12svh, 130px); }
  .gal-head { margin-top: 0; }
  .ember-hall { padding-bottom: clamp(48px, 9svh, 120px); }
  /* dolly 不跑（--dolly-progress 恒 0），别让扉页停在天没黑、厅里灯没亮的起点 */
  .ember-leaf { --leaf-t: 1; }
  .hall-img, .e2-img, .e3-img, .e5-img, .e7-img { transform: none; filter: brightness(1); }
  .hall-veil { opacity: 0; }
  .hall-vline { opacity: 1; transform: none; }
  .e2-focal, .e2-line { opacity: 0; }
  .e3-focal, .e3-line { opacity: 1; }
  .e2-focal, .e3-focal, .e5-focal, .e7-focal { mask-image: none; }
  .e7-line, .hush-word { opacity: 1; transform: none; }
  .gal-mat img { filter: brightness(1); }
}

@media (max-width: 700px) {
  .beat-line { font-size: clamp(18px, 5.4vw, 24px); }
  .hall-grid { grid-template-columns: 1fr; gap: clamp(20px, 5svh, 40px); }
  .hall-vline { writing-mode: horizontal-tb; transform: none; justify-self: start; line-height: 1.9; }
  .hall-vline .hv-b { margin-top: .4em; }
  .hall-frame { height: min(64svh, 560px); }
  .gal-mat, .gal-item figcaption { width: 86vw; }
  /* 露边量是照装裱垫宽算的，垫子在这里从 78vw 变成 86vw，公式必须跟着改口径，
     否则按旧口径多拉 8px，两张图会贴上 */
  .gal-item { margin-inline: calc(-1 * ((92vw - 86vw) / 4 + .5vw)); }
  .gal-item:first-child { margin-inline-start: 0; }
  .gal-item:last-child { margin-inline-end: 0; }

  /* 竖联的意思就是「不满幅」。高度驱动的 9:16 在 390 宽算出 465px——比视口还宽，
     装裱变成满幅贴片：负空间没了、竖排文案被挤没了，上一幕的满幅还会直接怼上来
     变成硬拼接。窄屏改由宽度驱动，把负空间要回来 */
  .zip-frame { height: auto; width: min(74vw, 330px); }
  .zip-vline { left: 8px; translate: 0 -50%; }
  .leaf-title { font-size: clamp(34px, 10vw, 56px); }
}

/* 长语种下导航容易换行：窄屏先收紧间距，实在放不下再换行——
   换行本身不再是 bug（顶距已跟着 --nav-h 走），只是尽量别发生 */
@media (max-width: 620px) {
  .world-nav-links { gap: clamp(10px, 3vw, 18px); row-gap: 4px; flex-wrap: wrap; justify-content: flex-end; }
  .world-nav-links a { font-size: calc(11.5px * var(--ratio, 1)); letter-spacing: .14em; }
}
