/* ============================================================
 * 设计令牌（唯一来源）：「夜读残卷」——墨纸黑 + 烛光金 + 黛青远山
 * 详见 docs/art-direction.md
 * ============================================================ */
:root {
  /* 底色：墨黑微暖（不是科技冷灰蓝） */
  --bg: #0c0a08;
  --bg-panel: #16120d;
  --bg-panel-2: #1e1913;
  --paper: rgba(22, 18, 13, 0.90);          /* 浮于场景上的墨纸面板 */
  --paper-solid: #171310;
  --border: #3a322a;
  --border-soft: rgba(140, 120, 90, 0.22);

  /* 文字 */
  --ink: #d8d2c6;
  --ink-dim: #9a917f;
  --ink-faint: #6b6354;

  /* 主色 */
  --jade: #6fae93;
  --jade-bright: #8fd6b4;
  --gold: #c9a96a;
  --gold-bright: #ecd9a8;
  --cinnabar: #b5483d;          /* 朱砂：危险/印章/心魔 */
  --red: #c25c50;
  --purple: #9a7fd4;
  --blue: #7a9cc0;

  /* 五行 */
  --wx-jin: #d8c690;
  --wx-mu: #7eb98e;
  --wx-shui: #6f9fc8;
  --wx-huo: #c96f5f;
  --wx-tu: #c2a36b;

  --shadow: rgba(0, 0, 0, 0.55);
  --radius: 4px;                 /* 硬朗边角 */
  --radius-lg: 6px;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

/* hidden 属性必须始终生效（修复：类选择器的 display 会覆盖 UA 的 [hidden]） */
[hidden] { display: none !important; }

html, body {
  height: 100%;
  background: var(--bg);
  color: var(--ink);
  font-family: "Noto Serif SC", "Songti SC", "STSong", "SimSun", serif;
  font-size: 15px;
  line-height: 1.7;
}
b, strong, .num { font-variant-numeric: tabular-nums; }

#app { height: 100vh; overflow: hidden; position: relative; }

/* ===== 桌面手机框（S6·宽屏 UI 错位根治）：宽窗口=居中 430×932 舞台 =====
 * 游戏在 iframe 内以手机视口渲染（全部 ≤640/760px 手机样式原样命中，与真机逐像素一致）；
 * 框外是水墨装饰底。缩放由 main._buildDeskShell 按窗口尺寸注入 transform。 */
body.desk-shell {
  margin: 0; height: 100vh; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  background:
    radial-gradient(1100px 650px at 50% 36%, rgba(58, 48, 38, .55), transparent 70%),
    radial-gradient(ellipse at 50% 115%, rgba(90, 70, 44, .18), transparent 60%),
    linear-gradient(180deg, #16120e, #0b0908);
}
body.desk-shell .shell-stage {
  width: 430px; height: 932px; flex: none;
  transform-origin: center center;
  border-radius: 24px; overflow: hidden;
  border: 1px solid rgba(201, 169, 106, .38);
  box-shadow: 0 0 0 7px rgba(22, 17, 12, .92), 0 34px 90px rgba(0, 0, 0, .78), 0 0 46px rgba(201, 169, 106, .07);
  background: #000;
}
body.desk-shell .shell-frame { width: 100%; height: 100%; border: 0; display: block; }
body.desk-shell .shell-hint {
  position: fixed; left: 0; right: 0; bottom: 10px; text-align: center;
  font-family: var(--font-title, serif); font-size: 12px; letter-spacing: 3px;
  color: rgba(214, 196, 160, .38); pointer-events: none;
}

/* 全局纸纹颗粒（极淡，盖在一切之上但不挡操作） */
#app::after {
  content: ""; position: fixed; inset: 0; z-index: 9999; pointer-events: none;
  opacity: .05; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.55'/%3E%3C/svg%3E");
}

.screen { display: none; height: 100vh; }
.screen.active { display: flex; flex-direction: column; }

/* ===== 角色创建：山门为底，竖排题字 ===== */
#screen-create {
  position: relative;
  align-items: center;
  justify-content: center;
  gap: clamp(20px, 6vw, 90px);
  background: var(--bg);
  overflow: hidden;
}
#screen-create.active { display: flex; flex-direction: row; }
.create-bg {
  position: absolute; inset: -2%;
  background: url("../assets/scenes/shanmen.png?v=9") center 30% / cover no-repeat;
  filter: brightness(.5) saturate(.82);
  animation: sceneDrift 50s ease-in-out infinite alternate;
}
.create-veil {
  position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(ellipse at 50% 45%, transparent 40%, rgba(8,6,4,.72) 100%),
    linear-gradient(180deg, rgba(8,6,4,.5), rgba(8,6,4,.18) 30%, rgba(8,6,4,.62) 100%);
}

.create-title-block {
  position: relative; z-index: 2;
  display: flex; flex-direction: column; align-items: center; gap: 16px;
}
.game-title.vertical {
  writing-mode: vertical-rl; text-orientation: upright;
  font-size: clamp(40px, 6.2vw, 64px); letter-spacing: 18px;
  color: #f0e9d8; font-weight: 700;
  text-shadow: 0 4px 30px rgba(0, 0, 0, .85), 0 0 60px rgba(201, 169, 106, .18);
  padding: 18px 14px;
  border-left: 1px solid rgba(201,169,106,.4); border-right: 1px solid rgba(201,169,106,.4);
}
/* 题字入场（审美审计 jank#2）：逐字水墨浮现——墨迹自雾中凝出、微沉落定，一字一拍 */
.game-title.vertical .tc {
  display: inline-block;
  opacity: 0;
  animation: inkChar 1s cubic-bezier(.22, 1, .36, 1) forwards;
}
.game-title.vertical .tc:nth-child(1) { animation-delay: .25s; }
.game-title.vertical .tc:nth-child(2) { animation-delay: .5s; }
.game-title.vertical .tc:nth-child(3) { animation-delay: .75s; }
.game-title.vertical .tc:nth-child(4) { animation-delay: 1s; }
.game-title.vertical .tc:nth-child(5) { animation-delay: 1.25s; }
@keyframes inkChar {
  0%   { opacity: 0; filter: blur(7px); transform: translateY(-8px) scale(1.12); }
  55%  { opacity: 1; filter: blur(0.5px); }
  100% { opacity: 1; filter: blur(0); transform: translateY(0) scale(1); }
}
body.motion-off .game-title.vertical .tc { animation-duration: .01s; animation-delay: 0s; }
.title-seal {
  writing-mode: vertical-rl; text-orientation: upright;
  background: var(--cinnabar); color: #f5e8dc;
  font-size: 14px; letter-spacing: 4px; padding: 8px 5px;
  border-radius: 2px; box-shadow: 0 3px 12px rgba(0,0,0,.55);
  /* 印章落款：题字写完后"钤印"一拍（微过冲落定） */
  opacity: 0; animation: sealStamp .45s cubic-bezier(.34, 1.56, .64, 1) 1.7s forwards;
}
@keyframes sealStamp {
  0%   { opacity: 0; transform: scale(1.6) rotate(-6deg); }
  70%  { opacity: 1; transform: scale(.96) rotate(1deg); }
  100% { opacity: 1; transform: scale(1) rotate(0); }
}
.create-title-block .subtitle { opacity: 0; animation: fadein .8s ease 2.1s forwards; }
body.motion-off .title-seal, body.motion-off .create-title-block .subtitle { animation-duration: .01s; animation-delay: 0s; }
.create-title-block .subtitle { margin: 0; }

.create-box {
  position: relative; z-index: 2;
  width: 400px;
  max-width: 92vw;
  background: var(--paper);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  padding: 30px 30px 24px;
  box-shadow: 0 24px 70px rgba(0,0,0,.6);
  text-align: center;
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
}

.game-title {
  font-size: 38px;
  letter-spacing: 8px;
  color: #f0e9d8;
  font-weight: 700;
}

.subtitle { color: var(--ink-dim); letter-spacing: 4px; margin: 10px 0 28px; font-size: 13px; }
.build-tag { margin-top: 12px; color: var(--ink-faint); font-size: 11px; letter-spacing: 1px; }
/* 工程信息退到屏角（审美审计 jank#2）：不进玩家视线主路径 */
.build-tag.corner {
  position: absolute; right: 10px; bottom: calc(8px + env(safe-area-inset-bottom, 0px));
  margin: 0; z-index: 3; opacity: .5; font-size: 10px;
}

.field { text-align: left; margin-bottom: 22px; }
.field label { display: block; color: var(--gold); margin-bottom: 8px; letter-spacing: 2px; font-size: 14px; }
.field input {
  width: 100%; padding: 10px 14px; background: var(--bg-panel-2);
  border: 1px solid var(--border); border-radius: 6px; color: var(--ink);
  font-family: inherit; font-size: 16px; letter-spacing: 2px;
}
.field input:focus { outline: none; border-color: var(--jade); }

.spirit-root-panel {
  background: var(--bg-panel-2); border: 1px solid var(--border);
  border-radius: 8px; padding: 18px; margin-bottom: 18px;
}
.sr-display { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; }
.sr-label { color: var(--ink-dim); letter-spacing: 2px; }
.sr-result { font-size: 20px; font-weight: 700; letter-spacing: 2px; }
.sr-result.untested { color: var(--ink-dim); }
.sr-desc { color: var(--ink-dim); font-size: 13px; min-height: 40px; text-align: left; margin-bottom: 14px; line-height: 1.6; }

.hint { color: var(--ink-dim); font-size: 12px; line-height: 1.7; margin: 18px 0 22px; text-align: left; opacity: 0.8; }

/* ===== 按钮：墨底细线，烛色点睛 ===== */
.btn {
  font-family: inherit; cursor: pointer; border: 1px solid var(--border);
  border-radius: var(--radius); padding: 11px 18px; font-size: 15px; letter-spacing: 2px;
  background: linear-gradient(180deg, rgba(255, 250, 240, 0.04), rgba(0,0,0,.12)), var(--bg-panel-2);
  color: var(--ink); transition: all 0.15s ease;
}
.btn:hover { border-color: var(--jade); color: var(--jade-bright); }
/* 按压态（审美审计 jank#5）：每次点按有"被按下去"的物理反馈——全局统一 */
.btn:active:not(:disabled), .choice:active, .spell-btn:active:not(:disabled), .scene-hotspot:active {
  transform: translateY(1px) scale(.985);
  filter: brightness(1.12);
  transition: transform .06s ease, filter .06s ease;
}
.btn:disabled { opacity: 0.4; cursor: not-allowed; }
.btn:disabled:hover { border-color: var(--border); color: var(--ink); }

.btn-primary {
  width: 100%; margin-top: 6px; background: linear-gradient(180deg, #2c5d4a, #1d4336);
  border-color: var(--jade); color: var(--jade-bright); font-size: 17px; padding: 13px;
}
.btn-primary:hover:not(:disabled) { background: linear-gradient(180deg, #357059, #234f40); }
.btn-secondary { width: 100%; color: var(--gold); border-color: rgba(201, 169, 106, .6); }
.btn-secondary:hover { background: rgba(201, 169, 106, 0.12); color: var(--gold-bright); }
.btn-ghost { width: 100%; margin-top: 10px; background: transparent; color: var(--ink-dim); }
.btn-mini { padding: 6px 12px; font-size: 13px; letter-spacing: 1px; }

/* ===== 顶栏：浮于场景上的一条墨带 ===== */
.topbar {
  position: relative; z-index: 12;
  display: flex; align-items: center; justify-content: space-between; flex-shrink: 0;
  padding: 9px 18px;
  background: linear-gradient(180deg, rgba(10, 8, 6, 0.88), rgba(10, 8, 6, 0.55) 75%, transparent);
  border-bottom: none;
}
.char-brief { display: flex; align-items: baseline; gap: 12px; }
.game-logo { font-size: 18px; color: var(--gold-bright); letter-spacing: 5px; font-weight: 700; text-shadow: 0 1px 10px rgba(0,0,0,.8); white-space: nowrap; }
.t-name { font-size: 18px; color: var(--jade-bright); letter-spacing: 2px; }
.t-realm { color: var(--ink); font-size: 13px; letter-spacing: 1px; text-shadow: 0 1px 4px rgba(0,0,0,.8); white-space: nowrap; }
.time-brief { color: var(--ink-dim); font-size: 14px; }
.time-brief .dot { margin: 0 6px; }
.topbar-actions { display: flex; gap: 7px; }
.topbar-actions .btn-mini {
  padding: 7px 12px; font-size: 13px; letter-spacing: 1px;
  background: rgba(16, 13, 10, 0.62); backdrop-filter: blur(3px);
  border-color: rgba(140, 120, 90, 0.35);
}
.topbar-actions .btn-mini:hover { background: rgba(111,174,147,.16); border-color: var(--jade); color: var(--jade-bright); }
/* 桌面隐藏 ☰（按钮齐全）；手机只留 ☰ */
.btn-more { display: none; }

/* ===== 沉浸式布局：场景全屏做底，HUD 浮于其上 ===== */
#screen-game.active { display: block; position: relative; height: 100vh; height: 100dvh; overflow: hidden; }
#screen-game .topbar { position: absolute; top: 0; left: 0; right: 0; }

/* ===== 地图主界面（地图即主界面：全屏可缩放，连续缩放不换图） ===== */
.worldmap-canvas {
  position: absolute; inset: 0; z-index: 1;
  overflow: hidden;
  background: radial-gradient(ellipse at 50% 40%, #1a2230 0%, #0e1219 70%, #080a0f 100%);
}
/* 连续缩放变换层：bg/svg/pins/labels/avatar 同步缩放=同一张图放大看细节（不翻图）。
 * transform-origin 由 JS 按聚焦点动态设定；transition 让 Z3↔Z4 平滑过渡。 */
.wm-world {
  position: absolute; inset: 0;
  transform-origin: 50% 50%;
  transition: transform 0.6s cubic-bezier(.4,0,.2,1);
  will-change: transform;
}
.worldmap-bg {
  position: absolute; inset: 0;
  background-size: cover; background-position: center;
  opacity: 0.55;
}
/* 第二张底图（跨级换图时交叉淡入：人界↔天南↔胥国）。默认透明，切图时淡入再交换。 */
.wm-bg2 { opacity: 0; transition: opacity 0.5s ease; }
.worldmap-svg {
  position: absolute; inset: 0; width: 100%; height: 100%;
}
.worldmap-pins, .worldmap-labels {
  position: absolute; inset: 0; pointer-events: none;
}
.worldmap-pins { z-index: 3; }
.worldmap-labels { z-index: 4; }

/* 地图据点 pin */
.wm-pin {
  position: absolute; transform: translate(-50%, -50%);
  pointer-events: auto; cursor: pointer;
  /* 锚点=圆点中心（与 avatar-pin 同心）：圆点绝对居中于地理坐标，名字浮在下方不挤占锚点。
   * pin 在缩放层外，文字图标按原生分辨率渲染——放大永不糊。 */
  width: 0; height: 0;
}
.wm-pin-dot {
  position: absolute; top: 0; left: 0; transform: translate(-50%, -50%);
  width: 10px; height: 10px; border-radius: 50%;
  background: var(--gold); border: 2px solid rgba(255,255,255,.3);
  box-shadow: 0 0 8px rgba(201,169,106,.5);
  transition: box-shadow 0.2s, background 0.2s, border-color 0.2s;
}
.wm-pin.here .wm-pin-dot {
  background: var(--jade-bright); border-color: var(--jade);
  box-shadow: 0 0 12px rgba(95,184,154,.7);
  width: 14px; height: 14px;
}
.wm-pin.gated .wm-pin-dot {
  background: #555; border-color: rgba(255,255,255,.15);
  box-shadow: none;
}
.wm-pin.silhouette .wm-pin-dot {
  background: transparent; border-style: dashed; border-color: rgba(255,255,255,.2);
}
.wm-pin:hover .wm-pin-dot {
  transform: translate(-50%, -50%) scale(1.3);
  box-shadow: 0 0 16px rgba(201,169,106,.8);
}
/* 据点名/副信息（v313 与 wm-label 同步换「墨字+纸晕」——浅色水墨底图上一律可读） */
.wm-pin-label {
  position: absolute; top: 10px; left: 50%; transform: translateX(-50%);
  margin-top: 2px; font-weight: 600;
  font-size: 11px; color: #33281a; white-space: nowrap;
  text-shadow: 0 0 3px rgba(246, 238, 216, .95), 0 0 6px rgba(246, 238, 216, .85), 0 1px 2px rgba(246, 238, 216, .9);
  letter-spacing: 1px;
}
.wm-pin.here .wm-pin-label { color: #1c6a4a; }
.wm-pin.gated .wm-pin-label { color: #6f604a; }
/* pin 副信息行（舆图显示更多：凶险/行程/状态）——浮在名字下方 */
.wm-pin-meta {
  position: absolute; top: 28px; left: 50%; transform: translateX(-50%);
  white-space: nowrap; font-size: 9.5px; letter-spacing: .5px;
  color: #5c4c36; text-shadow: 0 0 3px rgba(246, 238, 216, .95), 0 0 6px rgba(246, 238, 216, .8);
}
.wm-pin-meta.here { color: #1c6a4a; }
.wm-pin-meta.lock { color: #7c6c54; }
/* 天命指引（playtest 2026-07-12）：主线去处的 pin——金圈呼吸+「★ 天命所指」标，舆图一眼知去处 */
.wm-pin.fate .wm-pin-dot {
  background: #d8a53c; border-color: #b8862a;
  width: 14px; height: 14px;
  animation: fatePulse 1.8s ease-in-out infinite;
}
.wm-pin.fate .wm-pin-label { color: #7a5410; font-weight: 700; }
.wm-pin-meta.fate { color: #a06f14; font-weight: 700; top: 40px; }
@keyframes fatePulse {
  0%, 100% { box-shadow: 0 0 6px rgba(216,165,60,.55), 0 0 0 0 rgba(216,165,60,.45); }
  50% { box-shadow: 0 0 14px rgba(216,165,60,.85), 0 0 0 9px rgba(216,165,60,0); }
}
.wm-danger { font-style: normal; margin-right: 4px; padding: 0 4px; border-radius: 4px; }
.wm-danger.d-lo { color: #256e44; }
.wm-danger.d-mid { color: #96660e; }
.wm-danger.d-hi { color: #ad3f2a; }

/* 地图标签（州名/区块名）——v313 用户实锤"看不清"：
 * 旧版金字+黑影在米黄/淡青水墨底上全糊。改「浓墨题字+纸色光晕」：
 * 深墨色是宣纸舆图的天然正字色，四向纸色 halo 保证压在任何山水纹理上都读得出 */
.wm-label {
  position: absolute; transform: translate(-50%, -50%);
  font-family: var(--font-title, serif); font-weight: 700;
  font-size: 13.5px; color: #3a2d1a; letter-spacing: 3px;
  text-shadow:
    0 0 3px rgba(246, 238, 216, .98), 0 0 7px rgba(246, 238, 216, .9),
    -1px 0 2px rgba(246, 238, 216, .9), 1px 0 2px rgba(246, 238, 216, .9),
    0 -1px 2px rgba(246, 238, 216, .9), 0 1px 2px rgba(246, 238, 216, .9);
  pointer-events: auto; cursor: pointer;
  opacity: 0.95; transition: opacity 0.2s;
}
.wm-label:hover { opacity: 1; }
.wm-label.sel { color: #8a4d16; opacity: 1; }

/* SVG 路线 */
.wm-route {
  stroke: rgba(201,169,106,.25); stroke-width: 0.3;
  stroke-dasharray: 1.5 1; fill: none;
}
.wm-route.trod {
  stroke: rgba(201,169,106,.5); stroke-dasharray: none;
  stroke-width: 0.4;
}
/* 旅途当前路线：墨金流动虚线（P3——头像脚下这条路被点亮）。
 * 底图为米色宣纸——线色须深于纸面才可见；深墨描边+金芯双重投影提可读性。 */
.wm-route.journey {
  stroke: #7a5a24; stroke-width: 3;
  stroke-dasharray: 7 5; stroke-linecap: round;
  animation: route-flow 1.6s linear infinite;
  filter: drop-shadow(0 0 2px rgba(236,217,168,.9)) drop-shadow(0 1px 2px rgba(0,0,0,.45));
}
@keyframes route-flow {
  to { stroke-dashoffset: -12; }
}

/* avatar pin（韩立头像在地图上"走"——比纯光圈更像"人在地图上"） */
.avatar-pin {
  position: absolute; transform: translate(-50%, -50%);
  z-index: 6; pointer-events: none;
  transition: left 1.4s ease, top 1.4s ease;
}
.avatar-pin-portrait {
  width: 38px; height: 38px; border-radius: 50%;
  background-size: cover; background-position: center 18%;
  border: 2px solid var(--jade-bright);
  box-shadow: 0 0 10px rgba(95,184,154,.7), 0 3px 8px rgba(0,0,0,.6);
  background-color: #1a2a24;
}
.avatar-pin-ring {
  position: absolute; top: 50%; left: 50%;
  width: 42px; height: 42px; border-radius: 50%;
  border: 2px solid rgba(95,184,154,.45);
  transform: translate(-50%, -50%);
  animation: avatar-pulse 2.2s ease-out infinite;
}
@keyframes avatar-pulse {
  0% { transform: translate(-50%, -50%) scale(.9); opacity: 0.6; }
  100% { transform: translate(-50%, -50%) scale(1.9); opacity: 0; }
}

.avatar-pin.traveling .avatar-pin-ring {
  animation: avatar-travel 1.1s ease-in-out infinite;
}
@keyframes avatar-travel {
  0%, 100% { transform: translate(-50%, -50%) scale(.95); opacity: 0.7; }
  50% { transform: translate(-50%, -50%) scale(1.15); opacity: 1; }
}

/* 缩放控制 */
.zoom-controls {
  position: absolute; right: 14px; bottom: 80px;
  z-index: 10; display: flex; flex-direction: column; gap: 6px;
}
.zoom-btn {
  width: 38px; height: 38px; border-radius: 50%;
  background: rgba(14,11,8,.85); color: var(--gold);
  border: 1px solid var(--border); font-size: 18px;
  cursor: pointer; display: flex; align-items: center; justify-content: center;
  transition: all 0.2s;
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
}
.zoom-btn:hover { background: rgba(201,169,106,.15); border-color: var(--gold); }
.zoom-btn:active { transform: scale(0.92); }

/* 地图提示文字 */
.worldmap-hint {
  position: absolute; left: 50%; bottom: 16px; transform: translateX(-50%);
  z-index: 10; font-size: 12px; color: var(--ink-dim);
  background: rgba(14,11,8,.7); padding: 6px 14px; border-radius: 16px;
  border: 1px solid var(--border-soft);
  white-space: nowrap; pointer-events: none;
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
}

/* 地图模式下的 HUD 调整 */
.worldmap-canvas:not([hidden]) ~ .layout { z-index: 8; }
.worldmap-canvas:not([hidden]) ~ .topbar { z-index: 14; }
.worldmap-canvas:not([hidden]) ~ .objective-bar { display: none; }

/* ===== Z4↔Z5 交叉淡入淡出（P2：场景图与地图间的平滑过渡） ===== */
#scene-stage {
  transition: opacity 0.5s ease;
}
.worldmap-canvas {
  transition: opacity 0.5s ease;
}
.worldmap-canvas.fade-out { opacity: 0; pointer-events: none; }
#scene-stage.fade-out { opacity: 0; pointer-events: none; }

/* ===== 据点级行动 sheet（地图主界面：底部统一面板=行动+见闻合一） ===== */
.action-dock {
  position: absolute; left: 50%; bottom: 14px;
  transform: translateX(-50%) translateY(100%);
  z-index: 12; width: min(560px, 92vw);
  background: rgba(14,11,8,.88);
  border: 1px solid var(--border);
  border-radius: 14px 14px 10px 10px;
  padding: 6px 14px 14px;
  box-shadow: 0 -4px 24px rgba(0,0,0,.5);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  transition: transform 0.4s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.3s ease;
  opacity: 0;
}
.action-dock.show {
  transform: translateX(-50%) translateY(0);
  opacity: 1;
}
.action-dock-grip {
  width: 40px; height: 4px; border-radius: 2px;
  background: var(--border); margin: 2px auto 8px; cursor: pointer;
}
.action-dock-grip:hover { background: var(--gold); }
/* 头部：地点名 + 天命一行 */
.dock-head {
  display: flex; align-items: baseline; gap: 10px; margin-bottom: 8px;
  padding-bottom: 6px; border-bottom: 1px solid var(--border-soft);
}
.dock-loc { color: var(--gold-bright); font-size: 16px; letter-spacing: 2px; font-weight: 600; }
.dock-obj { color: var(--jade); font-size: 12px; letter-spacing: 1px; opacity: .9; }
/* 段切换标签：行动 / 见闻 */
.dock-tabs { display: flex; gap: 6px; margin-bottom: 10px; }
.dock-tab {
  flex: 1; padding: 7px 0; background: none; border: 1px solid var(--border-soft);
  border-radius: 8px; color: var(--ink-dim); font-family: inherit; font-size: 13px;
  letter-spacing: 3px; cursor: pointer; transition: all .15s;
}
.dock-tab.active { color: var(--gold-bright); border-color: var(--gold); background: rgba(201,169,106,.1); }
.dock-body { max-height: 42vh; overflow-y: auto; }
.dock-actions {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 8px;
}
.dock-actions .btn-action {
  flex: 0 1 auto; width: auto; min-width: 100px;
  padding: 10px 16px; font-size: 14px; letter-spacing: 2px;
}
.dock-actions .act-hint { width: 100%; text-align: center; }
/* 见闻段：在场人物 + 最近见闻条 */
.dock-news { display: flex; flex-direction: column; gap: 6px; }
.dn-npcs { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 6px; }
.dn-npc {
  background: rgba(95,184,154,.1); border: 1px solid var(--jade);
  border-radius: 8px; padding: 6px 12px; color: var(--jade-bright);
  font-family: inherit; font-size: 13px; cursor: pointer;
}
.dn-npc i { color: var(--ink-dim); font-style: normal; font-size: 11px; margin-left: 5px; }
.dn-row { display: flex; gap: 8px; font-size: 12.5px; line-height: 1.5; padding: 3px 0; border-bottom: 1px solid var(--border-soft); }
.dn-row:last-of-type { border-bottom: none; }
.dn-tag { color: var(--gold); flex-shrink: 0; font-size: 11px; }
.dn-txt { color: var(--ink); }
.dn-more { background: none; border: none; color: var(--jade); font-family: inherit; font-size: 12px; cursor: pointer; padding: 6px 0; text-align: left; }
/* 完整见闻浮层 */
.log-sheet { display: flex; flex-direction: column; gap: 10px; }
.log-sheet .ls-row { border-bottom: 1px solid var(--border-soft); padding-bottom: 8px; }
.log-sheet .ls-tag { color: var(--gold); font-size: 11px; }
.log-sheet .ls-body { color: var(--ink); font-size: 13px; line-height: 1.6; margin-top: 3px; }
/* 月份分隔线（审美审计 jank#11）：同月归组，长卷有日历的骨架 */
.log-sheet .ls-month {
  display: flex; align-items: center; gap: 10px; margin-top: 6px;
  color: var(--gold); font-size: 11.5px; letter-spacing: 2px;
}
.log-sheet .ls-month::before, .log-sheet .ls-month::after {
  content: ""; flex: 1; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(201, 169, 106, .3), transparent);
}
.log-sheet .ls-month:first-child { margin-top: 0; }

/* ===== P4: 地图模式下的 HUD 浮窗化 ===== */
/* 地图可见时：layout 变为浮在地图上的半透明面板 */
.worldmap-canvas:not([hidden]) ~ .layout {
  position: absolute; inset: auto; z-index: 9;
  display: grid;
  grid-template-columns: 282px minmax(0, 1fr) 372px;
  grid-template-rows: minmax(0, 1fr) auto;
  gap: 12px; padding: 56px 14px calc(80px + env(safe-area-inset-bottom, 0px));
  pointer-events: none;
  background: transparent;
}
.worldmap-canvas:not([hidden]) ~ .layout > * {
  pointer-events: auto;
  background: rgba(14,11,8,.82);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
}
/* 地图模式：侧栏可折叠（默认展开，加 .collapsed 收起） */
.worldmap-canvas:not([hidden]) ~ .layout .side-rail.collapsed {
  width: 0; overflow: hidden; opacity: 0; pointer-events: none; padding: 0; margin: 0; border: 0;
}
.worldmap-canvas:not([hidden]) ~ .layout .stage-col.collapsed {
  width: 0; overflow: hidden; opacity: 0; pointer-events: none; padding: 0; margin: 0; border: 0;
}
/* 地图模式：mid-col 只在 Z5 时需要（dock 已替代），Z1~Z4 时隐藏行动栏 */
.worldmap-canvas:not([hidden]) ~ .layout .mid-col {
  display: none;
}
/* Z5 dock 模式：dock 可见时也隐藏 mid-col（worldmap 已淡出但 dock 仍在） */
body.dock-active .layout .mid-col {
  display: none;
}
/* 有热点的地点：mid-col 空面板会遮挡场景热点，直接隐藏让热点可点 */
.layout.has-hotspots .mid-col {
  display: none !important;
}

/* HUD 切换按钮（P4：地图模式时显示/隐藏侧栏） */
.hud-toggle {
  position: absolute; left: 14px; bottom: 14px; z-index: 13;
  width: 36px; height: 36px; border-radius: 8px;
  background: rgba(14,11,8,.85); border: 1px solid var(--border);
  color: var(--ink); font-size: 16px; cursor: pointer;
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  display: none;
}
.worldmap-canvas:not([hidden]) .hud-toggle { display: block; }
.hud-toggle:hover { color: var(--gold-bright); border-color: var(--gold); }

/* 旅途状态浮标（P3：地图上显示旅途进度） */
.journey-status {
  position: absolute; top: 60px; left: 50%; transform: translateX(-50%);
  z-index: 11; padding: 6px 16px; border-radius: 20px;
  background: rgba(14,11,8,.85); border: 1px solid var(--gold);
  color: var(--gold-bright); font-size: 13px; letter-spacing: 1px;
  white-space: nowrap; pointer-events: none;
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  box-shadow: 0 2px 12px rgba(0,0,0,.4);
  animation: journeyPulse 2s ease-in-out infinite;
}
@keyframes journeyPulse {
  0%, 100% { box-shadow: 0 2px 12px rgba(0,0,0,.4); }
  50% { box-shadow: 0 2px 16px rgba(212,176,106,.4); }
}

.layout {
  position: absolute; inset: 0; z-index: 8;
  display: grid;
  grid-template-columns: 282px minmax(0, 1fr) 372px;
  grid-template-rows: minmax(0, 1fr) auto;
  gap: 12px; padding: 56px 14px 14px;
  pointer-events: none;            /* 间隙处可点到场景图钉 */
}
.layout > * { pointer-events: auto; }
.side-rail  { grid-column: 1; grid-row: 1 / 3; }
.mid-col    { grid-column: 2; grid-row: 2; align-self: end; }
.stage-col  { grid-column: 3; grid-row: 1 / 3; }

.mid-col { display: flex; flex-direction: column; gap: 8px; max-height: 44vh; }
.stage-col { display: flex; flex-direction: column; min-height: 0; }

/* 面板：浮在纸上的墨块，细线收角 */
.panel {
  position: relative;
  background: var(--paper);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg); padding: 14px; overflow-y: auto;
  box-shadow: 0 10px 36px rgba(0, 0, 0, 0.45);
  backdrop-filter: blur(7px); -webkit-backdrop-filter: blur(7px);
}
/* 四角"角花"细线 */
.panel::before {
  content: ""; position: absolute; inset: 4px; pointer-events: none;
  border-radius: 2px;
  background:
    linear-gradient(var(--border-soft), var(--border-soft)) top left    / 14px 1px,
    linear-gradient(var(--border-soft), var(--border-soft)) top left    / 1px 14px,
    linear-gradient(var(--border-soft), var(--border-soft)) top right   / 14px 1px,
    linear-gradient(var(--border-soft), var(--border-soft)) top right   / 1px 14px,
    linear-gradient(var(--border-soft), var(--border-soft)) bottom left / 14px 1px,
    linear-gradient(var(--border-soft), var(--border-soft)) bottom left / 1px 14px,
    linear-gradient(var(--border-soft), var(--border-soft)) bottom right/ 14px 1px,
    linear-gradient(var(--border-soft), var(--border-soft)) bottom right/ 1px 14px;
  background-repeat: no-repeat;
}
.main-stage { display: flex; flex-direction: column; min-height: 0; }

.panel-title {
  color: var(--gold); font-size: 12px; letter-spacing: 4px; font-weight: 600;
  margin: 14px 0 10px; padding-bottom: 7px; border-bottom: 1px solid var(--border-soft);
  display: flex; align-items: center; gap: 8px;
}
.panel-title::before {
  content: ""; width: 3px; height: 12px;
  background: linear-gradient(180deg, var(--gold-bright), var(--gold)); flex-shrink: 0;
}
.panel > .panel-title:first-child { margin-top: 0; }

/* ===== 角色卡（左上：韩立）===== */
.hero-card {
  display: flex; gap: 12px; align-items: center; margin-bottom: 14px;
  padding: 12px; border-radius: 10px;
  background: radial-gradient(circle at 18% 30%, rgba(127,227,192,.10), transparent 60%), var(--bg-panel-2);
  border: 1px solid var(--border);
}
.hero-portrait {
  width: 54px; height: 54px; border-radius: 50%; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center; font-size: 30px;
  background: radial-gradient(circle at 50% 35%, rgba(127,227,192,.25), #11171d 72%);
  border: 2px solid var(--jade); box-shadow: 0 0 12px rgba(95,184,154,.3);
}
.hero-meta { min-width: 0; }
.hero-name { font-size: 18px; color: var(--jade-bright); letter-spacing: 2px; }
.hero-realm { font-size: 13px; color: var(--gold); margin-top: 2px; }
.hero-age { font-size: 12px; color: var(--ink-dim); margin-top: 2px; }

/* 属性网格 */
.attr-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; margin: 12px 0; }
.attr-cell {
  display: flex; justify-content: space-between; align-items: center;
  padding: 6px 9px; border-radius: 7px; font-size: 13px;
  background: var(--bg-panel-2); border: 1px solid var(--border);
}
.attr-cell span { color: var(--ink-dim); }
.attr-cell b { color: var(--ink); }

.bar-group { margin-bottom: 9px; }
.bar-label { display: flex; justify-content: space-between; font-size: 12px; color: var(--ink-dim); margin-bottom: 3px; }
.bar { height: 10px; background: var(--bg-panel-2); border-radius: 5px; overflow: hidden; border: 1px solid var(--border); position: relative; }
.bar-fill { height: 100%; width: 0%; border-radius: 5px; transition: width 0.4s ease; position: relative; }
.bar-fill::after { content: ""; position: absolute; inset: 0; border-radius: 5px; background: linear-gradient(180deg, rgba(255,255,255,.22), transparent 55%); }
.bar-fill.cul { background: linear-gradient(90deg, #2a6b57, var(--jade-bright)); }
.bar-fill.sp { background: linear-gradient(90deg, #3a6a9a, var(--blue)); }
.bar-fill.hp { background: linear-gradient(90deg, #8a3a3a, var(--red)); }
.bar-fill.mood { background: linear-gradient(90deg, #7a5aa8, var(--purple)); }
.bar-fill.demon { background: linear-gradient(90deg, #4a1a1a, #c93838); }

/* 数值跳动 + 浮动增益（L1a 体验升级） */
.bar-label .num-pop { animation: numPop .5s ease; }
@keyframes numPop {
  0% { transform: scale(1); color: var(--ink-dim); }
  30% { transform: scale(1.25); color: var(--gold-bright); }
  100% { transform: scale(1); color: var(--ink-dim); }
}
.float-gain-toast {
  position: fixed; top: 30%; left: 50%; transform: translateX(-50%);
  color: var(--jade-bright); font-size: 18px; font-weight: 700;
  text-shadow: 0 0 8px rgba(0,0,0,.6); pointer-events: none; z-index: 200;
  animation: floatUpToast 1.4s ease-out forwards;
}
.float-gain-toast.fg-bad { color: var(--red); }
@keyframes floatUpToast {
  0% { opacity: 0; transform: translate(-50%, 10px) scale(.9); }
  15% { opacity: 1; transform: translate(-50%, 0) scale(1.1); }
  30% { transform: translate(-50%, -4px) scale(1); }
  100% { opacity: 0; transform: translate(-50%, -40px) scale(1); }
}

/* ===== L3 行动反馈：点击 ripple + 过程动画 ===== */
.btn-action, .btn-secondary, .btn-primary {
  position: relative; overflow: hidden;
}
.ripple {
  position: absolute; border-radius: 50%; pointer-events: none;
  background: rgba(255,255,255,.3);
  transform: scale(0); animation: rippleSpread .5s ease-out;
}
@keyframes rippleSpread {
  to { transform: scale(3); opacity: 0; }
}

/* 行动过程叠层（修炼打坐/采药绿光/探索迷雾） */
.action-overlay {
  position: absolute; inset: 0; z-index: 3; pointer-events: none;
  display: flex; align-items: center; justify-content: center;
  animation: actOverlay .9s ease-in-out forwards;
}
.action-overlay.meditate {
  background: radial-gradient(circle at 50% 70%, rgba(126,185,142,.15), transparent 60%);
}
.action-overlay.meditate::after {
  content: "🧘"; font-size: 48px; opacity: 0;
  animation: actIcon .9s ease-in-out forwards;
}
.action-overlay.gather {
  background: radial-gradient(circle at 50% 70%, rgba(100,200,100,.2), transparent 50%);
}
.action-overlay.gather::after {
  content: "🌿"; font-size: 36px; opacity: 0;
  animation: actIcon .8s ease-in-out forwards;
}
.action-overlay.explore {
  background: radial-gradient(circle at 50% 50%, rgba(180,200,220,.15), transparent 70%);
}
.action-overlay.explore::after {
  content: "🌫"; font-size: 42px; opacity: 0;
  animation: actIcon 1s ease-in-out forwards;
}
@keyframes actOverlay {
  0% { opacity: 0; }
  20% { opacity: 1; }
  80% { opacity: 1; }
  100% { opacity: 0; }
}
@keyframes actIcon {
  0% { opacity: 0; transform: scale(.5) translateY(10px); }
  30% { opacity: .8; transform: scale(1.2) translateY(0); }
  70% { opacity: .8; transform: scale(1) translateY(-4px); }
  100% { opacity: 0; transform: scale(1) translateY(-12px); }
}

/* ===== L2 场景热点：可点击热区替代行动按钮 ===== */
.scene-hotspots-layer {
  position: absolute; z-index: 4; pointer-events: none;
  left: 306px; right: 396px; top: 110px; bottom: 27vh;
}
.scene-hotspots-layer .scene-hotspot { pointer-events: auto; }
.scene-hotspot {
  position: absolute; transform: translate(-50%, -50%);
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  background: rgba(20,20,30,.55); border: 1px solid rgba(255,255,255,.15);
  border-radius: 50%; width: 44px; height: 44px;
  cursor: pointer; z-index: 4; padding: 0; overflow: hidden;
  transition: transform .2s ease, box-shadow .2s ease;
  animation: hotspotPulse 2.5s ease-in-out infinite;
}
.scene-hotspot:hover, .scene-hotspot:active {
  transform: translate(-50%, -50%) scale(1.15);
  box-shadow: 0 0 12px rgba(126,185,142,.5);
}
.scene-hotspot .sh-icon { font-size: 18px; line-height: 1; }
.scene-hotspot .sh-label {
  font-size: 9px; color: var(--ink-dim); white-space: nowrap;
  position: absolute; bottom: -16px; left: 50%; transform: translateX(-50%);
  text-shadow: 0 1px 3px rgba(0,0,0,.8);
}
@keyframes hotspotPulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(126,185,142,.3); }
  50% { box-shadow: 0 0 0 6px rgba(126,185,142,0); }
}
/* L2 氛围地标（看一眼）：比行动热点更低调——不脉冲、暗金边、半透明，鼠标近了才亮
 * （行动=玉青脉冲抢眼；看一眼=可发现不打扰，"点场景里的东西有反应"的松弛感） */
.scene-hotspot.scene-look {
  width: 34px; height: 34px; animation: none;
  background: rgba(18,14,10,.4); border-color: rgba(201,169,106,.28);
  opacity: .55;
}
.scene-hotspot.scene-look:hover, .scene-hotspot.scene-look:active {
  opacity: 1; border-color: rgba(201,169,106,.7);
  box-shadow: 0 0 12px rgba(201,169,106,.4);
}
.scene-hotspot.scene-look .sh-icon { font-size: 15px; filter: saturate(.7); }
.scene-hotspot.scene-look .sh-label { color: var(--gold); }

/* ===== 底部 sheet（L1b：轻量信息面板，不遮挡场景） ===== */

/* ===== 月历条 + 季节染色（L4：时间流逝可感知） ===== */
/* 月轮转一拍（审美审计 jank#7/D5）：日期翻动微动效——时间被"看见" */
.time-tick { display: inline-block; animation: timeTick .5s cubic-bezier(.22, 1, .36, 1); }
@keyframes timeTick {
  0%   { opacity: .2; transform: translateY(-6px); color: var(--gold-bright); }
  60%  { opacity: 1; transform: translateY(1px); }
  100% { opacity: 1; transform: translateY(0); }
}
.month-bar {
  display: flex; gap: 2px; margin-top: 4px; height: 16px;
}
.month-cell {
  width: 14px; height: 6px; border-radius: 2px;
  background: var(--bg-panel-2); border: 1px solid var(--border-soft);
  transition: background .3s ease, transform .3s ease;
}
.month-cell.active {
  background: var(--gold); border-color: var(--gold-bright);
  transform: scaleY(1.6);
}
.month-cell.spring { border-color: rgba(126,185,142,.4); }
.month-cell.summer { border-color: rgba(201,111,95,.4); }
.month-cell.autumn { border-color: rgba(212,176,106,.4); }
.month-cell.winter { border-color: rgba(111,159,200,.4); }

/* 修为进度·顶栏常驻条（全 tab 可见·锚住闭关核心循环的即时反馈） */
.top-cul {
  display: flex; align-items: center; gap: 6px; white-space: nowrap;
}
.top-cul .tc-realm { font-size: 12px; color: var(--jade-bright); letter-spacing: 1px; text-shadow: 0 1px 4px rgba(0,0,0,.8); }
.top-cul .tc-track {
  width: 90px; height: 5px; border-radius: 3px; overflow: hidden;
  background: var(--bg-panel-2); border: 1px solid var(--border-soft);
}
.top-cul .tc-fill {
  height: 100%; border-radius: 3px;
  background: linear-gradient(90deg, var(--jade), var(--jade-bright));
  transition: width .8s cubic-bezier(.22,.61,.36,1);
}
.top-cul .tc-text { font-size: 11px; color: var(--ink-dim); }

/* 季节染色：叠在 scene-tint 之上（z-index:2.5）*/
.scene-season {
  position: absolute; inset: 0; z-index: 2; pointer-events: none;
  opacity: 0; transition: opacity 1.5s ease;
}
.scene-stage[data-season="spring"] .scene-season {
  opacity: 1;
  background: linear-gradient(180deg, rgba(126,185,142,.06) 0%, rgba(100,160,120,.04) 100%);
}
.scene-stage[data-season="summer"] .scene-season {
  opacity: 1;
  background: linear-gradient(180deg, rgba(201,159,95,.05) 0%, rgba(180,140,80,.03) 100%);
}
.scene-stage[data-season="autumn"] .scene-season {
  opacity: 1;
  background: linear-gradient(180deg, rgba(212,176,106,.08) 0%, rgba(180,140,70,.05) 100%);
}
.scene-stage[data-season="winter"] .scene-season {
  opacity: 1;
  background: linear-gradient(180deg, rgba(111,139,180,.07) 0%, rgba(90,120,160,.05) 100%);
}

/* ===== 底部 sheet（L1b：轻量信息面板，不遮挡场景） ===== */
.sheet-overlay {
  position: fixed; inset: 0; z-index: 90;
  background: rgba(0,0,0,0.25);
  display: flex; align-items: flex-end; justify-content: center;
  animation: fadein 0.2s ease;
}
/* 锁定 sheet（旅途行动面板）：不压暗上半屏、地图可透过遮罩交互——头像移动全程可见 */
.sheet-overlay.sheet-lock { background: transparent; pointer-events: none; }
.sheet-overlay.sheet-lock .bottom-sheet { pointer-events: auto; box-shadow: 0 -10px 36px rgba(0,0,0,.65); }
.bottom-sheet {
  position: relative; /* 锚定 .sheet-close——缺它时 × 逃逸到视口右上角被顶栏遮死 */
  width: 460px; max-width: 94vw; max-height: 65vh; overflow-y: auto;
  background: var(--bg-panel); border: 1px solid var(--border-soft);
  border-bottom: none; border-radius: 12px 12px 0 0;
  padding: 20px 22px calc(16px + env(safe-area-inset-bottom, 0px));
  box-shadow: 0 -8px 32px rgba(0,0,0,.5);
  animation: sheetUp 0.3s cubic-bezier(0.22, 1, 0.36, 1);
}
@keyframes sheetUp {
  from { transform: translateY(100%); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}
.bottom-sheet h2 {
  color: var(--gold-bright); font-size: 18px; letter-spacing: 2px;
  margin-bottom: 10px; padding-right: 28px;
}
.bottom-sheet .sheet-close {
  /* sticky+float：长内容（见闻全录）滚动时 × 始终可点；absolute 会随内容滚出视野 */
  position: sticky; top: 0; float: right; z-index: 2;
  margin: -6px -6px 0 0; padding: 6px 10px;
  color: var(--ink-faint); font-size: 20px; cursor: pointer;
  line-height: 1; transition: color .15s;
}
.bottom-sheet .sheet-close:hover { color: var(--gold); }
.bottom-sheet .market-item {
  display: flex; justify-content: space-between; align-items: center;
  padding: 8px 0; border-bottom: 1px solid var(--border-soft);
}
.bottom-sheet .market-item:last-child { border-bottom: none; }
.bottom-sheet .modal-actions {
  display: flex; flex-direction: column; gap: 8px; margin-top: 14px;
}
.bottom-sheet .choices { margin-top: 10px; display: flex; flex-direction: column; gap: 8px; }
.bottom-sheet .prep-list {
  background: var(--bg-panel-2); border-radius: 8px; padding: 10px 12px; margin: 8px 0;
}
.bottom-sheet .prep-item {
  display: flex; justify-content: space-between; padding: 3px 0; font-size: 13px;
}

/* ===== 界面区（所在 + 地图 + 人物 + 行动）===== */
.stage-place {
  flex-shrink: 0; margin-bottom: 12px; padding: 12px;
  background: var(--bg-panel-2); border: 1px solid var(--border); border-radius: 10px;
}
.place-head { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.place-head .loc-name { font-size: 17px; color: var(--jade-bright); letter-spacing: 1px; flex: 1; }
.map-toggle { flex-shrink: 0; color: var(--gold); border-color: rgba(212,176,106,.5); }
.map-toggle.on { background: rgba(212,176,106,.15); color: var(--gold-bright); }
.stage-place .loc-desc { color: var(--ink-dim); font-size: 12px; line-height: 1.6; margin-bottom: 8px; }

/* 界面区里的叙事区：占满剩余高度、独立滚动 */
.stage-col .narrative { flex: 1; min-height: 80px; overflow-y: auto; padding-right: 6px; }
/* 底部行动栏：横排大按钮，像一排"打出的牌" */
.mid-col .action-buttons {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 9px;
}
.mid-col .btn-action {
  flex: 0 1 auto; width: auto; min-width: 116px;
  padding: 13px 20px; font-size: 15px; letter-spacing: 3px;
}

/* ===== 叙事区 ===== */
.narrative .entry { margin-bottom: 14px; }
/* 早前之事折叠行（审美审计 jank#4：读档不糊文字墙） */
.narrative .entry-fold {
  margin: 2px 0 14px; padding: 8px 12px; cursor: pointer;
  color: var(--ink-faint); font-size: 12px; letter-spacing: 1px;
  border: 1px dashed rgba(140, 120, 90, .35); border-radius: 8px;
  background: rgba(255, 250, 240, .02); text-align: center;
  transition: color .15s ease, border-color .15s ease;
}
.narrative .entry-fold:hover { color: var(--gold); border-color: rgba(201, 169, 106, .5); }
.narrative .entry.latest { animation: fadein 0.4s ease; }
.narrative .entry .time-stamp { color: var(--gold); font-size: 12px; letter-spacing: 1px; opacity: 0.7; }
.narrative .entry .time-stamp .ek-icon { margin-right: 5px; opacity: .8; }
.narrative .entry.good .time-stamp .ek-icon { color: var(--jade-bright); }
.narrative .entry.bad .time-stamp .ek-icon { color: var(--red); }
.narrative .entry .body { color: var(--ink); margin-top: 2px; }
.narrative .entry.event { border-left: 2px solid var(--jade); padding-left: 12px; }
.narrative .entry.story {
  border-left: 2px solid var(--gold); padding-left: 12px;
  background: rgba(212, 176, 106, 0.05); border-radius: 0 6px 6px 0; padding: 10px 12px;
  animation: storyArrive 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}
@keyframes storyArrive {
  from { opacity: 0; transform: translateX(-10px); box-shadow: -4px 0 16px rgba(212,176,106,0.4); }
  to { opacity: 1; transform: translateX(0); box-shadow: none; }
}
.narrative .entry.story .title { color: var(--gold-bright); font-size: 16px; letter-spacing: 1px; margin-bottom: 4px; }
.narrative .entry.sys .body { color: var(--ink-dim); font-size: 13px; }
.narrative .entry.good .body { color: var(--jade-bright); }
.narrative .entry.bad .body { color: var(--red); }

.choices { margin-top: 12px; display: flex; flex-direction: column; gap: 8px; }
.choices .choice { animation: choiceIn 0.3s ease backwards; }
.choices .choice:nth-child(2) { animation-delay: 0.06s; }
.choices .choice:nth-child(3) { animation-delay: 0.12s; }
.choices .choice:nth-child(4) { animation-delay: 0.18s; }
@keyframes choiceIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
.choices .choice {
  text-align: left; padding: 12px 16px; background: var(--bg-panel-2);
  border: 1px solid var(--border); border-radius: 8px; cursor: pointer;
  color: var(--ink); transition: all 0.15s; font-family: inherit; font-size: 15px;
}
.choices .choice:hover { border-color: var(--jade); background: rgba(95, 184, 154, 0.08); }
.choices .choice .c-hint { display: block; color: var(--ink-dim); font-size: 12px; margin-top: 4px; }

/* ===== 行动面板 ===== */
.mid-col.story-pending .action-buttons,
.mid-col.story-pending .locals { opacity: .4; pointer-events: none; }
.loc-tag { display: inline-block; font-size: 11px; letter-spacing: 2px; color: var(--ink-dim); background: var(--bg); padding: 1px 8px; border-radius: 10px; }
.act-hint { color: var(--ink-dim); font-size: 13px; text-align: center; padding: 10px; font-style: italic; }
.action-buttons { display: flex; flex-direction: column; gap: 8px; }
.btn-action { width: 100%; text-align: center; }
.btn-action[data-action="breakthrough"] { color: var(--gold); border-color: rgba(212,176,106,0.5); }
.btn-action[data-action="breakthrough"]:hover { background: rgba(212,176,106,0.12); color: var(--gold-bright); }

/* ===== 背包 ===== */
.inventory { display: flex; flex-direction: column; gap: 6px; }
.inv-item {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 9px; background: rgba(255, 250, 240, 0.025); border: 1px solid var(--border);
  border-radius: var(--radius); font-size: 14px; cursor: pointer; transition: all 0.15s;
}
.inv-item:hover { border-color: var(--jade); }
.inv-item .iname { color: var(--ink); flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.inv-item .iname.rare { color: var(--gold); }
.inv-item .iname.epic { color: var(--purple); }
.inv-item .icount { color: var(--ink-dim); }
.inv-empty { color: var(--ink-dim); font-size: 13px; text-align: center; padding: 10px; }

/* 背包分类页签（A4：道具/材料/丹药/法宝）*/
.inv-cats { display: flex; gap: 4px; margin: 0 0 8px; }
.inv-cat {
  flex: 1 1 0; min-width: 0; padding: 5px 2px; cursor: pointer;
  background: var(--bg-panel-2); border: 1px solid var(--border-soft);
  border-radius: var(--radius); color: var(--ink-dim);
  font-family: inherit; font-size: 12.5px; letter-spacing: 1px; white-space: nowrap;
  transition: color .12s, border-color .12s, background .12s;
}
.inv-cat.active { color: var(--gold-bright); border-color: var(--gold); background: rgba(201, 169, 106, .08); }
.inv-cat .ic-n { color: var(--ink-faint); font-size: 11px; margin-left: 3px; }
.inv-cat.active .ic-n { color: var(--gold); }

/* ===== 弹窗 ===== */
.modal-overlay {
  position: fixed; inset: 0; background: rgba(0,0,0,0.7);
  display: flex; align-items: center; justify-content: center; z-index: 100; animation: fadein 0.2s;
}
.modal {
  width: 460px; max-width: 92vw; max-height: 86vh; overflow-y: auto;
  background: var(--bg-panel); border: 1px solid var(--jade);
  border-radius: 12px; padding: 26px; box-shadow: 0 20px 60px var(--shadow);
  animation: modalpop 0.22s cubic-bezier(0.22, 1, 0.36, 1);
}
@keyframes modalpop {
  from { opacity: 0; transform: translateY(14px) scale(0.96); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}
.modal h2 { color: var(--gold-bright); letter-spacing: 2px; margin-bottom: 14px; font-size: 20px; }
.modal p { color: var(--ink); margin-bottom: 14px; }
.modal .modal-actions { display: flex; flex-direction: column; gap: 8px; margin-top: 18px; }
.modal .modal-row { display: flex; gap: 10px; }
.modal .modal-row .btn { flex: 1; }
.prep-list { background: var(--bg-panel-2); border-radius: 8px; padding: 14px; margin-bottom: 16px; }
.prep-row { display: flex; justify-content: space-between; padding: 5px 0; font-size: 14px; }
.prep-row .ok { color: var(--jade-bright); }
.prep-row .no { color: var(--red); }
.rate-display { text-align: center; font-size: 28px; letter-spacing: 2px; margin: 10px 0 4px; }
.rate-display.high { color: var(--jade-bright); }
.rate-display.mid { color: var(--gold); }
.rate-display.low { color: var(--red); }
.rate-label { text-align: center; color: var(--ink-dim); font-size: 13px; margin-bottom: 6px; }

/* ===== 小瓶 ===== */
.bottle-plots { display: flex; flex-direction: column; gap: 8px; margin: 14px 0; }
.plot {
  display: flex; justify-content: space-between; align-items: center;
  padding: 10px 12px; background: var(--bg-panel-2); border: 1px solid var(--border); border-radius: 8px;
}
.plot .pinfo { font-size: 14px; }
.plot .pinfo .pname { color: var(--jade-bright); }
.plot .pinfo .pstat { color: var(--ink-dim); font-size: 12px; }

/* ===== Toast ===== */
.toast {
  position: fixed; bottom: 30px; left: 50%; transform: translateX(-50%);
  background: var(--bg-panel); border: 1px solid var(--jade); color: var(--jade-bright);
  padding: 12px 24px; border-radius: 8px; z-index: 260; box-shadow: 0 10px 30px var(--shadow);
  letter-spacing: 1px; animation: toastin 0.3s ease;
  max-width: 90vw; text-align: center; line-height: 1.5;
}
.toast.bad { border-color: var(--red); color: var(--red); }

/* 观阵按钮激活态（全景观阵中）*/
#combat-survey.on { border-color: var(--gold); color: var(--gold-bright); background: rgba(201,169,106,.12); }

/* 剧情演出中：toast 移到顶部，避免压住底部的剧情抉择按钮（结识新人物等提示）。 */
body.story-on .toast {
  bottom: auto; top: calc(16px + env(safe-area-inset-top, 0px));
  animation: toastin-top 0.3s ease;
}
@keyframes toastin-top { from { opacity: 0; transform: translate(-50%, -10px); } to { opacity: 1; transform: translate(-50%, 0); } }

@keyframes fadein { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }
@keyframes toastin { from { opacity: 0; transform: translate(-50%, 10px); } to { opacity: 1; transform: translate(-50%, 0); } }

/* 滚动条 */
::-webkit-scrollbar { width: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 4px; }
::-webkit-scrollbar-thumb:hover { background: var(--jade); }

/* ===== 所在地 ===== */
.loc-box { background: var(--bg-panel-2); border: 1px solid var(--border); border-radius: 8px; padding: 12px; margin-bottom: 6px; }
.loc-name { color: var(--jade-bright); font-size: 16px; letter-spacing: 1px; margin-bottom: 4px; }
.loc-desc { color: var(--ink-dim); font-size: 12px; line-height: 1.6; margin-bottom: 10px; }
.btn-travel { color: var(--gold); border-color: rgba(212,176,106,0.5); }
.btn-travel:hover { background: rgba(212,176,106,0.12); color: var(--gold-bright); }

.travel-list { display: flex; flex-direction: column; gap: 8px; margin: 14px 0; }
.travel-item { text-align: left; padding: 12px 14px; background: var(--bg-panel-2); border: 1px solid var(--border); border-radius: 8px; cursor: pointer; color: var(--ink); font-family: inherit; transition: all .15s; }
.travel-item:hover { border-color: var(--jade); background: rgba(95,184,154,.08); }
.travel-item.here { opacity: .5; cursor: default; }
.travel-item .tname { color: var(--jade-bright); }
.travel-item .tcost { color: var(--ink-dim); font-size: 12px; float: right; }
.travel-item .tdesc { display: block; color: var(--ink-dim); font-size: 12px; margin-top: 4px; }

.market-item { display: flex; justify-content: space-between; align-items: center; padding: 10px 12px; background: var(--bg-panel-2); border: 1px solid var(--border); border-radius: 8px; margin-bottom: 8px; }
.market-item .mprice { color: var(--gold); }

/* ===== 战斗界面：场景做底，立绘对峙，五行灵气珠池 ===== */
.combat-overlay {
  position: fixed; inset: 0; background: #080604; z-index: 150;
  display: flex; align-items: stretch; justify-content: center; animation: fadein .25s;
  overflow: hidden;
}
/* 战斗背景：人站在地图里（觅长生式）——场景与探索同一份"真"（不虚化、不重压暗，
 * 用户裁决：开战不该把天地糊掉）；可读性交给 veil 的上下渐变，不动场景本身 */
/* 战斗底图：只铺到战场下沿（bottom 由 JS 按 axis-field 实际位置注入）——
 * 底图下 1/3 的"近地台面"必须落在单位脚下，而不是被操作台吞掉（v86 踩地对齐） */
.combat-bg {
  position: absolute; top: -2%; left: -2%; right: -2%; bottom: var(--bg-cut, 0px);
  /* v115 裁剪不拉伸（用户裁决：手机上"强行拉高→背景图案变形"明显，须改裁剪）：
   * 改回 cover，但锚定 center bottom——底图"地面带"在图片底部，cover+底锚把图片底边
   * 钉在容器底边(=--bg-cut 战场地面线)，地平线恒定贴地。手机竖屏容器比横图更"高瘦"，
   * cover 按高缩放→纵向比例与当年 100%/100% 硬拉伸完全一致(脚位 cqh 不漂移)，只把
   * 横向溢出两侧裁掉、消除压扁形变。这正解了 v91 当年为规避"脚位漂移"才用硬拉伸、
   * 却引入"图案变形"的两难；底锚也不复现"换屏人上天"。 */
  background-size: cover; background-position: center bottom;
  opacity: 0; transition: opacity .6s ease, transform 1.1s cubic-bezier(.4, .05, .3, 1);
  transform-origin: 50% 88%;
  filter: brightness(.84) saturate(.98);
}
.combat-bg.on { opacity: 1; }
/* 中景物件层（三层分级制 v88）：透明实物条带叠在远景之上、人物之后——
 * 独立视差速率（比远景快），人飞到"树前"成立：树真的在更远的层、以不同速度退行。
 * ⚠ 层逻辑铁律（v88 验收教训）：中景基线必须抬到最深僚位排之后（约地线上方 96px）、
 * 尺寸缩一档、亮度压暗——基线若与战位排同线，物件就会怼在人物脚下"穿模"（南宫婉站石头上） */
.combat-bgmid {
  position: absolute; top: -2%; left: -3%; right: -3%; bottom: var(--bg-cut, 0px);
  /* "远"三件齐：透视缩（远处路牌只剩几十像素高）+ 抬到中景地带（地平线下沿）+ 雾化压暗 */
  background-size: auto 28%; background-position: center calc(100% - 124px); background-repeat: repeat-x;
  opacity: 0; transition: opacity .6s ease, transform 1.1s cubic-bezier(.4, .05, .3, 1);
  transform-origin: 50% 88%; pointer-events: none;
  filter: brightness(.62) saturate(.8) blur(.4px);
}
.combat-bgmid.on { opacity: .92; }
@media (max-width: 640px) {
  .combat-bgmid { background-size: auto 25%; background-position: center calc(100% - 96px); }
}
/* 前景遮挡层（v90 用户点名：最前面的草石加强景深）——离镜头最近的一层：
 * 失焦+压暗（近景虚）、压在全部单位之上、贴战场下沿；镜头平移时以最快速率退行
 * （近景动得快=视差的第一线索）；升空时下沉+淡出（脚边的草最先滑出镜头）。
 * transform 由 JS 与统一相机同帧派发（fgY/fgX），同曲线同时长 */
/* 前景=贴底一线小草（v90 定稿：用户裁决回归平铺版）——
 * space 平铺降密度（丛与丛之间留空），失焦微暗，绝不遮战场 */
.combat-fg {
  position: absolute; left: -4%; right: -4%; bottom: calc(var(--bg-cut, 0px) - 6px);
  height: 11%; pointer-events: none; z-index: 6;
  background-size: auto 100%; background-position: center bottom; background-repeat: space;
  opacity: 0; transition: opacity .6s ease, transform 1.15s cubic-bezier(.22, .82, .26, 1);
  transform-origin: 50% 100%;
  filter: blur(1px) brightness(.74) saturate(.95);
}
.combat-fg.on { opacity: .9; }
/* 升空：前景草石淡去（人离地了，脚边遮挡物不再挡视野——高度感的负空间） */
.combat-overlay.sky .combat-fg.on { opacity: .25; }
@media (max-width: 640px) { .combat-fg { height: 9%; } }
/* 环境色反光（v90）：接触影外圈晕一层底图地面色——脚与地的色彩咬合
 * （人物色调与场景"各画各的"是浮贴感的来源之一，脚下反光是最便宜的融合笔） */
.combat-overlay.bg-forest .axis-unit::before { box-shadow: 0 2px 16px 3px rgba(98,126,58,.30); }
.combat-overlay.bg-road .axis-unit::before { box-shadow: 0 2px 16px 3px rgba(170,136,74,.32); }
.combat-overlay.bg-night .axis-unit::before { box-shadow: 0 2px 16px 3px rgba(72,102,152,.28); }
.combat-veil {
  position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(ellipse at 50% 36%, transparent 46%, rgba(8,6,4,.5) 100%),
    linear-gradient(180deg, rgba(8,6,4,.58) 0%, rgba(8,6,4,.14) 20%, rgba(8,6,4,.1) 48%, rgba(8,6,4,.84) 84%);
}
/* ===== §9-5 危局氛围：血线告危时屏幕"边缘暗红脉动"=====
 * 玩家气血 ≤28%(.peril) 起、≤12%(.brink) 更急更浓。纯屏幕边框血晕(inset box-shadow 集中在四缘
 * + 极淡 radial 收口)，中央战场与操作台留白不糊——pointer-events:none 不挡任何点击。
 * 配合 audio.js Sfx.peril() 的心跳低鼓＝绝境感。尊重 reduced-motion：去脉动、留静态血框。 */
.combat-overlay.peril::after {
  content: ""; position: absolute; inset: 0; z-index: 8; pointer-events: none;
  box-shadow: inset 0 0 88px 16px rgba(122,8,8,.42), inset 0 0 220px 56px rgba(78,0,0,.26);
  background: radial-gradient(ellipse at 50% 50%, transparent 58%, rgba(86,0,0,.22) 100%);
  animation: peril-pulse 1.5s ease-in-out infinite;
}
.combat-overlay.brink::after {
  box-shadow: inset 0 0 108px 24px rgba(152,6,6,.56), inset 0 0 248px 78px rgba(96,0,0,.36);
  background: radial-gradient(ellipse at 50% 50%, transparent 50%, rgba(112,0,0,.32) 100%);
  animation-duration: .85s;
}
@keyframes peril-pulse { 0%,100% { opacity: .42; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .combat-overlay.peril::after, .combat-overlay.brink::after { animation: none; opacity: .82; }
}
/* ===== 升空天幕（v110「真有飞在天上的感觉」核心）=====
 * 用户痛点：升空时画面只是人物略微抬起，文案说"天地倏然开阔"，画面却几乎没开阔——远景底图
 * 超采样(farScale 1.10+)只下沉 ~1%，顶部根本没让出"天"。这里补上那片缺席的天：一张只盖场景区
 * (top:0→bottom:--bg-cut，绝不漫进下方操作台)的高空大气层，平时全透明（贴地战斗完全不显），
 * 升空(.sky)时 .9s 淡入——顶端最亮、向地平线散开，人物(box z:2)正飞进这片天的前方。
 * 层序 z:1：压在背景(0)/中景/帷幕之上、人物(2)之下；仍在 v109 统一调色(grade z:7)身后——
 * 天与地同吃一套色温＝不破"融为一体"。色板与 .combat-grade 同源，随场景色温走。
 * 性能：纯渐变、无 blur/无 backdrop、仅 opacity 过渡——升空才显，零常驻开销。 */
.combat-sky {
  position: absolute; left: 0; right: 0; top: 0; bottom: var(--bg-cut, 0px);
  z-index: 1; pointer-events: none; opacity: 0;
  transition: opacity .9s cubic-bezier(.3, .7, .3, 1);
  background:
    radial-gradient(135% 86% at 50% -16%, rgba(212,228,234,.46), rgba(196,214,224,.18) 36%, transparent 62%),
    linear-gradient(180deg, rgba(190,210,222,.34) 0%, rgba(178,198,212,.13) 42%, transparent 72%);
}
.combat-overlay.sky .combat-sky { opacity: 1; }
/* 地平线霞光：天地交界一线提亮＝"开阔"的视觉锚（soft-light 只染中间调，不糊景物轮廓） */
.combat-sky::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 30%; height: 24%; pointer-events: none;
  mix-blend-mode: soft-light;
  background: linear-gradient(180deg, transparent, rgba(224,234,238,.2) 58%, transparent);
}
/* 天色随场景色温（与 v109 融合层同源：森林冷青／官道暖沙／夜战幽蓝／心战墨紫） */
.combat-overlay.bg-forest .combat-sky {
  background:
    radial-gradient(135% 86% at 50% -16%, rgba(200,224,220,.46), rgba(180,210,204,.18) 36%, transparent 62%),
    linear-gradient(180deg, rgba(176,206,196,.32) 0%, rgba(166,196,188,.12) 42%, transparent 72%);
}
.combat-overlay.bg-road .combat-sky {
  background:
    radial-gradient(135% 86% at 50% -16%, rgba(228,216,188,.46), rgba(214,200,168,.18) 36%, transparent 62%),
    linear-gradient(180deg, rgba(216,200,166,.32) 0%, rgba(204,188,156,.12) 42%, transparent 72%);
}
.combat-overlay.bg-night .combat-sky {
  background:
    radial-gradient(135% 86% at 50% -14%, rgba(150,176,222,.42), rgba(120,148,196,.18) 38%, transparent 64%),
    linear-gradient(180deg, rgba(96,124,176,.34) 0%, rgba(78,104,156,.13) 44%, transparent 74%);
}
.combat-overlay.mind .combat-sky {
  background:
    radial-gradient(135% 86% at 50% -14%, rgba(176,150,210,.42), rgba(150,124,188,.18) 38%, transparent 64%),
    linear-gradient(180deg, rgba(140,112,178,.32) 0%, rgba(120,94,160,.13) 44%, transparent 74%);
}
/* ===== 场景融合层（v109「融为一体」核心）=====
 * 用户痛点：人物比水墨背景过亮过饱、边缘过锐，像贴纸贴在画上（手机尤甚）。觅长生那种
 * "自然融为一体"靠的是一套作用于"整幅画面"的统一后处理——不是把人物搬进引擎。
 * 这里钉一张只盖场景区(top:0→bottom:--bg-cut，绝不盖下方操作台)的 backdrop 层，对其身后
 * 的一切（背景+中景+前景+人物+特效）统一去饱和/压亮/提对比——一笔把过曝过饱的人物拉回
 * 背景的水墨色域。⚠ 红线：绝不给 .au-img/.au-swords 加 filter（会冲掉既有
 * drop-shadow/受击/蓄力/魔化滤镜、建堆叠上下文坏剑层级）——只在 overlay 级合成层做。
 * 性能：只用色彩矩阵（saturate/brightness/contrast）、不含 blur（最贵那项），单合成层手机可担。
 * 层序：z:7 在前景(6)之上、招式名(165)之下——背景与人物一同入调，招式大字与操作台不受影响。 */
.combat-grade {
  position: absolute; left: 0; right: 0; top: 0; bottom: var(--bg-cut, 0px);
  z-index: 7; pointer-events: none;
  -webkit-backdrop-filter: saturate(.84) brightness(.95) contrast(1.05);
  backdrop-filter: saturate(.84) brightness(.95) contrast(1.05);
}
/* v114 手机优先流畅：backdrop-filter 会在每帧重采样它身后那张「正在动」的特效身后层画布(z:1)，
 * 这是 iOS Safari 著名的性能悬崖（背景每帧变→整块重栅格化+重过滤），也是 14PM 也卡顿的主因之一。
 * 触摸端改用一张「静态」色罩近似「压暗+微冷」的融合观感——纯叠加层、不读取动态背景、零每帧重合成；
 * 雾层(::after, soft-light)保留维持空气透视（普通混合，远比 backdrop-filter 便宜）。桌面不受影响、保持满质量。 */
@media (hover: none), (pointer: coarse) {
  .combat-grade {
    -webkit-backdrop-filter: none; backdrop-filter: none;
    background: linear-gradient(180deg, rgba(18,22,28,.16) 0%, rgba(16,20,26,.10) 48%, rgba(14,18,24,.18) 100%);
  }
}
/* 大气景深雾：地平线一带最浓、近脚处散开（远虚近实的空气透视）——把人物往雾里"退"半步，
 * 灭"边缘硬切贴在画上"。soft-light=薄空气光，只染中间调、不糊高光暗部，雾色随场景色温走。 */
.combat-grade::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; mix-blend-mode: soft-light;
  background: linear-gradient(180deg, rgba(150,160,166,.16) 0%, rgba(140,150,156,.08) 34%, transparent 66%);
}
.combat-overlay.bg-forest .combat-grade::after { background: linear-gradient(180deg, rgba(96,126,82,.18) 0%, rgba(96,126,82,.08) 36%, transparent 66%); }
.combat-overlay.bg-road .combat-grade::after { background: linear-gradient(180deg, rgba(150,124,76,.18) 0%, rgba(150,124,76,.08) 36%, transparent 66%); }
.combat-overlay.bg-night .combat-grade::after { background: linear-gradient(180deg, rgba(70,92,140,.20) 0%, rgba(70,92,140,.09) 38%, transparent 66%); }
.combat-overlay.mind .combat-grade::after { background: linear-gradient(180deg, rgba(108,74,150,.20) 0%, rgba(108,74,150,.09) 38%, transparent 66%); }
/* 心战（突破/心魔劫）：墨紫色调 */
.combat-overlay.mind { background: #0a0710; }
.combat-overlay.mind .combat-veil {
  background:
    radial-gradient(ellipse at 50% 30%, rgba(90, 60, 140, .16), transparent 55%),
    linear-gradient(180deg, rgba(8,5,14,.6) 0%, transparent 30%, rgba(8,5,14,.9) 90%);
}

/* 招式名横幅：出招时大字一闪 */
.combat-cast {
  position: absolute; left: 50%; top: 30%; transform: translate(-50%, -50%);
  z-index: 165; pointer-events: none;
}
.combat-cast .cc-name {
  display: block; font-size: clamp(30px, 6vw, 50px); font-weight: 800; letter-spacing: 14px;
  text-shadow: 0 4px 26px rgba(0,0,0,.85);
  animation: castIn .7s cubic-bezier(.16,.9,.2,1) forwards;
}
@keyframes castIn {
  0% { opacity: 0; transform: scale(1.35); letter-spacing: 26px; }
  22% { opacity: 1; transform: scale(1); }
  80% { opacity: 1; }
  100% { opacity: 0; transform: scale(.97) translateY(-6px); }
}
.cc-name.wx-jin { color: var(--wx-jin); } .cc-name.wx-mu { color: var(--wx-mu); }
.cc-name.wx-shui { color: var(--wx-shui); } .cc-name.wx-huo { color: var(--wx-huo); }
.cc-name.wx-tu { color: var(--wx-tu); }
/* 法宝催动横幅：更大的字+鎏金光爆——"催动"得看着像回事 */
.cc-name.cc-treasure {
  font-size: 1.35em; letter-spacing: 6px;
  text-shadow: 0 0 22px rgba(226, 194, 119, .95), 0 0 50px rgba(226, 194, 119, .5), 0 3px 14px rgba(0, 0, 0, .9);
}

/* 战场锁死（v107 根治“手机一拖人物飘到中景”）：背景层(combat-bg/中景/前景)钉在
 * 视口(overlay 是 fixed)，但场景 axis-field 在 combat-box 里——盒子一旦能滚，场景就与
 * 钉死的背景脱节、人物滑到中景线。故 combat-box 自身绝不滚(overflow:hidden)，
 * 场景区(tophud+axis-field+intent)恒定钉死；内容溢出只许操作台 combat-console 内部滚。 */
.combat-box {
  position: relative; z-index: 2; width: min(860px, 100vw);
  display: flex; flex-direction: column;
  padding: 14px 18px 16px; height: 100vh; height: 100dvh; max-height: 100vh; max-height: 100dvh; overflow: hidden;
}
.combat-title {
  text-align: center; color: #e8c9b0; font-size: 20px; letter-spacing: 8px; margin: 4px 0 10px;
  text-shadow: 0 2px 12px rgba(0,0,0,.8);
}
.combat-overlay.mind .combat-title { color: #cbb4ec; }

/* 对峙区：敌左 我右 */
.combat-field {
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: end; gap: 10px;
  margin-bottom: 12px; min-height: 200px; flex-shrink: 0;
}
.combat-vs {
  color: var(--ink-faint); font-size: 17px; text-align: center; letter-spacing: 0;
  width: 34px; height: 34px; line-height: 32px; border: 1px solid var(--border-soft);
  border-radius: 50%; align-self: center; background: rgba(10,8,6,.5);
}
.combatant {
  position: relative; display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 8px; margin-bottom: 6px; border-radius: var(--radius-lg);
  background: transparent; border: 1px solid transparent; transition: all .15s;
}
.combatant .cfigure {
  height: clamp(120px, 23vh, 220px); line-height: 0;
  filter: drop-shadow(0 12px 20px rgba(0,0,0,.6));
}
.combatant .cfigure img { height: 100%; width: auto; animation: portraitIn .4s ease; }
.combat-enemies .cfigure img { transform: scaleX(-1); }   /* 敌人面朝右（朝向韩立）*/
.cfigure.glyph {
  height: auto; width: clamp(76px, 12vh, 110px); aspect-ratio: 1;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%; border: 1.5px solid rgba(194, 92, 80, .55);
  background: radial-gradient(circle at 50% 36%, rgba(194,92,80,.22), rgba(14,10,8,.85) 75%);
  box-shadow: 0 0 24px rgba(194,92,80,.2), inset 0 0 18px rgba(0,0,0,.6);
}
.cfigure.glyph span { font-size: clamp(34px, 6vh, 52px); color: #e0a294; text-shadow: 0 2px 10px rgba(0,0,0,.8); }
/* 心魔化：黑化剪影 + 紫光 */
.cfigure.demonized img {
  filter: brightness(.1) saturate(.2) drop-shadow(0 0 18px rgba(154,127,212,.55));
}
.combatant .cinfo { width: 100%; max-width: 230px; }
.combatant.dead { opacity: .4; filter: grayscale(1); }
.combatant.dead .cfigure { filter: grayscale(1) brightness(.4); }
.combatant.enemy { cursor: default; }
.combatant.enemy[onclick] { cursor: pointer; }
.combatant.enemy[onclick]:hover { background: rgba(201,95,95,.06); border-color: rgba(194,92,80,.4); }
.combatant.target { border-color: rgba(194,92,80,.55); background: rgba(194,92,80,.05); }
.target-tag { position: absolute; top: 6px; right: 8px; font-size: 11px; color: var(--red); letter-spacing: 1px; }

.combatant .cname { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; margin-bottom: 4px; }
.combatant .cname b { color: #efe8da; text-shadow: 0 1px 4px rgba(0,0,0,.8); }
.combatant .cname .ctag { color: var(--gold); font-size: 11px; }
.cbar { position: relative; height: 7px; background: rgba(8,6,4,.72); border-radius: 3px; overflow: hidden; border: 1px solid rgba(140,120,90,.3); margin-bottom: 3px; }
.cbar-fill { height: 100%; background: linear-gradient(90deg,#7c3a32,var(--red)); transition: width .3s ease; }
.cbar-fill.self { background: linear-gradient(90deg,#2c5d4a,var(--jade-bright)); }
.cbar-fill.shield { position: absolute; top: 0; left: 0; opacity: .5; background: linear-gradient(90deg,#3a5a7a,var(--blue)); }
.cbar-num { font-size: 12px; color: #cfc6b4; text-shadow: 0 1px 3px rgba(0,0,0,.9); }
.cstatus { font-size: 11px; color: #93d67f; text-shadow: 0 1px 3px rgba(0,0,0,.9); }

/* 道基行徽（情报门控：打过/买过底细才显示对方根脚）——五行字徽 */
.elem-badge {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: 50%; font-size: 11px; font-weight: 700;
  border: 1px solid currentColor; margin-right: 4px; vertical-align: -3px;
  text-shadow: none; box-shadow: 0 0 6px rgba(0,0,0,.5) inset;
}
.elem-badge.elem-jin  { color: #e8c66a; background: rgba(120,95,30,.35); }
.elem-badge.elem-mu   { color: #8fd67f; background: rgba(40,90,40,.35); }
.elem-badge.elem-shui { color: #7fb8e8; background: rgba(30,70,110,.35); }
.elem-badge.elem-huo  { color: #e88a6a; background: rgba(120,45,25,.35); }
.elem-badge.elem-tu   { color: #cfa97a; background: rgba(95,70,35,.35); }

/* 侧位单位（尸傀/灵宠/傀儡）：主人身侧的窄卡 */
.combatant.side-unit {
  margin-top: 6px; padding: 6px 9px; max-width: 210px;
  background: rgba(14,12,9,.55); border: 1px solid rgba(120,100,70,.35); border-radius: 8px;
}
.combatant.side-unit .cname b { font-size: 12.5px; color: #cfc2a8; }
.combatant.side-unit .cname .ctag { color: var(--ink-dim); }
.combatant.side-unit.dead { opacity: .45; filter: grayscale(.8); }
.combatant.side-unit .cfigure.side-fig { width: 46px; height: 46px; border-radius: 50%; overflow: hidden; flex: none; border: 1px solid rgba(140,120,90,.4); }
.combatant.side-unit .cfigure.side-fig img { width: 100%; height: 100%; object-fit: cover; object-position: top; }
.combatant.side-unit { display: flex; gap: 8px; align-items: center; }
.cbar-fill.side { background: linear-gradient(90deg,#4a4338,#8a7c62); }

/* 侧位随行条（行动页）：尸傀状态一目了然 */
.side-strip {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 4px 0 6px; margin-bottom: 4px; border-bottom: 1px dashed rgba(120,100,70,.25);
  font-size: 12px;
}
.side-strip { cursor: pointer; }
.side-strip .ss-name { color: #b8a98c; font-weight: 600; }
.side-strip .ss-st { color: var(--ink-dim); flex: 1; }
.side-strip .ss-lv { color: var(--jade-bright); font-size: 11px; border: 1px solid rgba(111,174,147,.4); border-radius: 3px; padding: 0 4px; }

/* 侧位·驭物：强化面板 */
.side-enh { background: rgba(0,0,0,.22); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 10px 12px; margin: 10px 0; }
.side-enh.maxed { border-style: dashed; opacity: .85; }
.side-enh .se-row { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 6px; }
.side-enh .se-row b { color: var(--gold-bright); }
.side-enh .se-gain { color: var(--jade); font-size: 13px; margin-bottom: 4px; }
.side-enh .se-cost { color: var(--ink-faint); font-size: 12px; margin-bottom: 8px; }
.side-enh .se-cost .lack { color: var(--red); }
.side-enh .btn { width: 100%; }

/* ===== 对话演出：立绘的"活"（震动/弹跳/呼吸顶起）===== */
.story-portrait.quake { animation: portraitQuake .42s cubic-bezier(.36,.07,.19,.97); }
@keyframes portraitQuake {
  0%, 100% { transform: translateX(0); }
  15% { transform: translateX(-7px) rotate(-0.6deg); }
  30% { transform: translateX(6px) rotate(0.5deg); }
  45% { transform: translateX(-5px); }
  60% { transform: translateX(4px); }
  75% { transform: translateX(-2px); }
}
.story-portrait.speak-bump { animation: speakBump .34s ease-out; }
@keyframes speakBump {
  0% { transform: translateY(0); }
  35% { transform: translateY(-5px); }
  100% { transform: translateY(0); }
}
/* 左侧 NPC 立绘镜像（scaleX(-1) 面朝主角）：震/呼吸顶起动画须保留镜像，
   否则发言瞬间立绘会翻回默认朝向、落幕又翻回——朝向闪跳。与 portrait-out 同法（左侧专用关键帧）。 */
.story-portrait.left.quake { animation-name: portraitQuakeL; }
@keyframes portraitQuakeL {
  0%, 100% { transform: scaleX(-1) translateX(0); }
  15% { transform: scaleX(-1) translateX(-7px) rotate(-0.6deg); }
  30% { transform: scaleX(-1) translateX(6px) rotate(0.5deg); }
  45% { transform: scaleX(-1) translateX(-5px); }
  60% { transform: scaleX(-1) translateX(4px); }
  75% { transform: scaleX(-1) translateX(-2px); }
}
.story-portrait.left.speak-bump { animation-name: speakBumpL; }
@keyframes speakBumpL {
  0% { transform: scaleX(-1) translateY(0); }
  35% { transform: scaleX(-1) translateY(-5px); }
  100% { transform: scaleX(-1) translateY(0); }
}
.story-portrait.emo-pop img { animation: emoPop .4s cubic-bezier(.34,1.56,.64,1); }
@keyframes emoPop {
  0% { transform: scale(.96); filter: brightness(1.25); }
  100% { transform: scale(1); filter: brightness(1); }
}

/* 远惦记剪影：迷雾深处的兽踪（看得见、到不了——惦记本体） */
.ex-cell.fog .ex-icon.far-mark {
  opacity: .35; filter: grayscale(.7) blur(.5px);
  animation: farPulse 2.8s ease-in-out infinite;
}
@keyframes farPulse { 0%,100% { opacity: .22; } 50% { opacity: .45; } }

.cintent {
  font-size: 11.5px; color: var(--gold-bright); margin-top: 5px; padding: 5px 8px; max-width: 250px;
  background: rgba(14,11,8,.82); border: 1px solid rgba(201,169,106,.4); border-radius: var(--radius);
  line-height: 1.55; backdrop-filter: blur(2px);
}

/* ===== 对阵轴战场（combat-axis-rules.md §11：觅长生式立绘战场）===== */
.combat-tophud { display: flex; align-items: baseline; justify-content: center; gap: 14px; flex-shrink: 0; }
.combat-roundnum { color: var(--ink-dim); font-size: 12.5px; letter-spacing: 2px; }

/* ===== 战场带：格是法术现象，不是棋盘（UI MVP 2026-06-11 用户拍板）=====
 * 地面只有一条淡墨地平线+步位墨点；可走=青涟漪、锁格=红雾柱、范围=红雾带、阵法=阵纹。 */
.axis-field {
  position: relative; flex-shrink: 0;
  height: clamp(252px, 43vh, 412px);
  margin-bottom: 6px;
  /* ⚓ 相对坐标系（v91 架构修正——用户实锤"缩放页面人物跑天上"）：
   * 战场内所有纵深参数（地线/排距/脚位/飞高/立绘高）一律用 cqh（战场高度百分比），
   * 底图同步 100%/100% 贴合——人物与底图地面带的位置关系从此恒定，
   * 与屏幕尺寸/缩放/宽高比彻底解耦。⚠ 洞窟（cave-track）无此容器，
   * 走 var() 默认 px 值，互不干扰 */
  container-type: size;
  --ground0: 9.3cqh;     /* 战位排地线（离画底）：战场高的 9.3% */
  /* v108 战场加高（用户：战场要明显浩大）：scene 高一档=天地撑得更开；
   * 人物按 cqh 走，加高后同 cqh 占屏更克制，天空/地面留白都更足 */
  --lane-gap: 12cqh;     /* 排距：每深一排地线抬高一档（34px@283 → 12%） */
  --feet: 14.3cqh;       /* 单位脚底距容器底 */
  --lanes: 2;            /* 排数（JS 注入：场景定 2~4） */
}
/* 透视地台：向远处收窄的"地面"——脚下有地，排才有处可站。
 * v89 统一相机：地台挂在 axis-units（世界层，z 低于格刻度）——镜头 zoom 时与
 * 单位/格子一体缩放，地线与脚永不脱开（挂 axis-field 上则世界缩、地不缩=撕裂） */
.axis-units::before {
  content: ""; position: absolute; left: 0; right: 0; bottom: -24px;
  height: calc(var(--ground0) + (var(--lanes) - 1) * var(--lane-gap) + 18px);
  pointer-events: none; z-index: -1;
  background:
    /* 排地线（v90 三改：一眼可见）：脚的落点是纵深的第一读数——排距拉大后，
     * 地线必须亮到能在底图地面纹理上读出来；越深的排向中央收得越狠（透视消失点） */
    linear-gradient(90deg, transparent 2%, rgba(214,192,156,.44) 12%, rgba(214,192,156,.44) 88%, transparent 98%) 0 calc(100% - var(--ground0)) / 100% 2px no-repeat,
    linear-gradient(90deg, transparent 10%, rgba(214,192,156,.36) 21%, rgba(214,192,156,.36) 79%, transparent 90%) 0 calc(100% - var(--ground0) - var(--lane-gap)) / 100% 1.6px no-repeat,
    linear-gradient(90deg, transparent 18%, rgba(214,192,156,.24) 29%, rgba(214,192,156,.24) 71%, transparent 82%) 0 calc(100% - var(--ground0) - 2 * var(--lane-gap)) / 100% 1.3px no-repeat,
    linear-gradient(90deg, transparent 26%, rgba(214,192,156,.15) 36%, rgba(214,192,156,.15) 64%, transparent 74%) 0 calc(100% - var(--ground0) - 3 * var(--lane-gap)) / 100% 1px no-repeat,
    /* 排间雾带（v90 二改提浓）：排与排之间隔一层看得见的空气——"后排隔着雾"的层间呼吸感 */
    linear-gradient(180deg, transparent, rgba(196,206,214,.13) 55%, transparent) 0 calc(100% - var(--ground0) - var(--lane-gap) + 10px) / 100% 16px no-repeat,
    linear-gradient(180deg, transparent, rgba(196,206,214,.09) 55%, transparent) 0 calc(100% - var(--ground0) - 2 * var(--lane-gap) + 8px) / 100% 13px no-repeat,
    /* 地面明暗（v90 二改方向反转）：近亮远暗才是地面的透视明暗——
     * 上沿（深处）压暗、脚前（下沿）不压——之前底部最暗是反的 */
    linear-gradient(180deg, rgba(8,6,4,.34) 0%, rgba(14,11,8,.14) 52%, rgba(8,6,4,0) 100%);
  clip-path: polygon(10% 0, 90% 0, 100% 100%, 0 100%);
  filter: drop-shadow(0 0 1px rgba(190,170,140,.18));
}
.axis-field::before {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 88px;
  background: linear-gradient(180deg, transparent, rgba(8,6,4,.3) 55%, rgba(8,6,4,.46));
  pointer-events: none;
}
/* 燃点推近（teamfight-camera-design B4）：终结一击/大招/驰援落点——视口极轻一推再松，给"这一下"
 * 分量感。纯视觉叠加（transform 不改布局、不动 cqh 容器尺寸），动画自复位；origin 偏下贴近地面战团。 */
@keyframes camPunch { 0% { transform: scale(1); } 26% { transform: scale(1.055); } 100% { transform: scale(1); } }
.axis-field.cam-punch { transform-origin: 50% 78%; animation: camPunch .62s cubic-bezier(.22,.9,.27,1); }
@media (prefers-reduced-motion: reduce) { .axis-field.cam-punch { animation: none; } }
/* 步位刻度层（贴地，透明无框）——浮于立绘上层（雾柱半透明可罩单位=被锁定感），
 * 非可走格不拦点击 */
.axis-lane {
  position: absolute; left: 0; right: 0; bottom: 0; height: 52px;
  display: flex; padding: 0 2px; z-index: 3; pointer-events: none;
}
.axis-cell { flex: 1; position: relative; border: none; background: none; pointer-events: none; }
.axis-cell.can-move { pointer-events: auto; }
/* 步位墨点（平时几乎隐形） */
.axis-cell .dot {
  position: absolute; left: 50%; bottom: 22px; width: 5px; height: 5px; margin-left: -2.5px;
  border-radius: 50%; background: rgba(200,182,150,.28);
}
.axis-cell.edge-home .dot { background: rgba(126,185,142,.5); }
.axis-cell.edge-far .dot { background: rgba(194,92,80,.4); }
/* 撤离点：蓝色光门标记（护送逃脱型 survive 战） */
.axis-cell.escape-cell .dot {
  width: 12px; height: 12px; margin-left: -6px; bottom: 18px;
  background: rgba(100,180,255,.7); box-shadow: 0 0 8px 2px rgba(100,180,255,.4);
  animation: escape-pulse 1.5s ease-in-out infinite;
}
@keyframes escape-pulse { 0%,100% { opacity: .5; } 50% { opacity: 1; } }
/* 可走：青色涟漪圈（点击移动） */
.axis-cell.can-move { cursor: pointer; }
.axis-cell.can-move .dot {
  width: 9px; height: 9px; margin-left: -4.5px; bottom: 20px;
  background: rgba(126,205,152,.85); box-shadow: 0 0 10px rgba(126,205,152,.5);
}
.axis-cell.can-move::before {
  content: ""; position: absolute; left: 50%; bottom: 12px; width: 34px; height: 13px;
  transform: translateX(-50%); border-radius: 50%;
  border: 1.5px solid rgba(126,205,152,.55);
  animation: rippleOut 1.7s ease-out infinite;
}
.axis-cell.can-move:hover .dot { background: #b8f0c8; box-shadow: 0 0 16px rgba(150,230,170,.8); }
@keyframes rippleOut {
  0% { opacity: .8; transform: translateX(-50%) scale(.45); }
  75% { opacity: 0; transform: translateX(-50%) scale(1.25); }
  100% { opacity: 0; transform: translateX(-50%) scale(1.25); }
}
/* 杀气锁格：红雾柱从地面升起 */
.axis-cell .mist-pillar {
  position: absolute; left: 50%; bottom: 16px; width: 64%; height: 96px;
  transform: translateX(-50%);
  background: linear-gradient(180deg, transparent 0%, rgba(201,80,62,.07) 30%, rgba(201,80,62,.3) 78%, rgba(220,95,70,.42) 100%);
  border-radius: 40% 40% 22% 22%; filter: blur(2.5px);
  animation: mistBreath 1.15s ease-in-out infinite; pointer-events: none;
}
.axis-cell .mist-pillar::after {
  content: ""; position: absolute; left: 50%; bottom: -4px; width: 120%; height: 14px;
  transform: translateX(-50%); border-radius: 50%;
  background: radial-gradient(ellipse, rgba(220,95,70,.5), transparent 70%);
}
@keyframes mistBreath { 0%,100% { opacity: .55; } 50% { opacity: 1; } }
/* 范围预告（方阵）：默认"罩"全排=高雾带；.zone-front"扫"战位排=低矮雾带（僚位无虞） */
.axis-cell .mist-band {
  position: absolute; left: -2px; right: -2px; bottom: 14px; height: 64px;
  background: linear-gradient(180deg, transparent, rgba(201,80,62,.18) 45%, rgba(201,80,62,.36));
  filter: blur(2px); animation: mistBreath 1.3s ease-in-out infinite; pointer-events: none;
}
.axis-cell.zone-front .mist-band {
  height: 28px;
  background: linear-gradient(180deg, transparent, rgba(201,80,62,.24) 65%, rgba(201,80,62,.36));
}
/* 阵法：地面阵纹光圈（困足金 / 聚灵蓝 / 迷踪紫） */
.axis-cell .zone-ring {
  position: absolute; left: 50%; bottom: 13px; width: 78%; height: 17px;
  transform: translateX(-50%); border-radius: 50%; pointer-events: none;
  border: 1.5px solid rgba(194,163,107,.65);
  box-shadow: 0 0 12px rgba(194,163,107,.3), inset 0 0 10px rgba(194,163,107,.22);
  animation: zonePulse 2.4s ease-in-out infinite;
}
.axis-cell.zone-juling .zone-ring { border-color: rgba(111,159,200,.65); box-shadow: 0 0 12px rgba(111,159,200,.32), inset 0 0 10px rgba(111,159,200,.22); }
.axis-cell.zone-mizong .zone-ring { border-color: rgba(154,127,212,.6); box-shadow: 0 0 12px rgba(154,127,212,.3), inset 0 0 10px rgba(154,127,212,.2); }
@keyframes zonePulse { 0%,100% { opacity: .55; } 50% { opacity: 1; } }

/* 出手身法·三拍制（S1 动作手感 v1）：预备后撤微沉 → 突进 → 收势缓归。
 * 方向由 JS 注入 --atk（1=向右，-1=向左）——翻面立绘 scaleX(-1) 不会翻 translate，必须显式给向。 */
.axis-unit.strike-melee .au-img, .axis-unit.strike-melee .au-glyph { animation: strikeMelee .56s cubic-bezier(.2,.9,.3,1); }
@keyframes strikeMelee {
  0% { translate: 0 0; }
  18% { translate: calc(var(--atk, 1) * -10px) 3px; rotate: calc(var(--atk, 1) * -1.6deg); }
  40% { translate: calc(var(--atk, 1) * 30px) -7px; rotate: calc(var(--atk, 1) * 2.8deg); }
  62% { translate: calc(var(--atk, 1) * 18px) -2px; }
  100% { translate: 0 0; rotate: 0deg; }
}
.axis-unit.strike-cast .au-img, .axis-unit.strike-cast .au-glyph { animation: strikeCast .5s ease; }
@keyframes strikeCast {
  0% { translate: 0 0; }
  20% { translate: calc(var(--atk, 1) * -6px) 2px; }
  44% { translate: calc(var(--atk, 1) * 11px) -4px; rotate: calc(var(--atk, 1) * 1.4deg); }
  100% { translate: 0 0; rotate: 0deg; }
}
/* 命中白闪：挨打的那一下看得见 */
.axis-unit.hitflash .au-img, .axis-unit.hitflash .au-glyph {
  filter: brightness(2.1) saturate(.6) drop-shadow(0 0 14px rgba(255,220,180,.8)) !important;
  transition: filter .06s;
}
/* 海战（S5）：怒涛之上无立锥之地——全员踏浪凌空。浮沉呼吸位移错相荡摆（nth 错开不齐浮）。
 * ⚠ .axis-unit 的 translate 承载 --lx/--ly/--ax/--ay 排位/飞高——关键帧必须原样保留这组变量，
 * 只在 Y 上叠浮沉量（否则升空/排深全被动画打回原点）。死亡单位不浮（deadFade 接管）。 */
.sea-field .axis-unit:not(.dead) { animation: seaBob 3.4s ease-in-out infinite; }
.sea-field .axis-unit:nth-child(2n):not(.dead) { animation-duration: 3.9s; animation-delay: -1.3s; }
.sea-field .axis-unit:nth-child(3n):not(.dead) { animation-duration: 4.3s; animation-delay: -2.1s; }
@keyframes seaBob {
  0%, 100% { translate: calc(var(--lx, 0px) + var(--ax, 0px)) calc(var(--ly, 0px) + var(--ay, 0px)); }
  50% { translate: calc(var(--lx, 0px) + var(--ax, 0px)) calc(var(--ly, 0px) + var(--ay, 0px) - 7px); }
}
/* S9 身后挂件（通用·风雷翅首例）：特殊道具素材挂单位身后——
 * z-1 钻到立绘身后（同 au-swords 后半弧法）；wingSurge=双翼翻涌呼吸（缩放+亮度脉动，
 * transform-origin 在翼根），配合 _startWingFx 的特效层窜雷=「左风右雷」活起来 */
.axis-unit .au-wings {
  position: absolute; left: 50%; bottom: calc(var(--feet, 40px) * .96);
  width: 185%; translate: -50% 0; z-index: -1; pointer-events: none;
}
.axis-unit .au-wings img {
  width: 100%; display: block;
  animation: wingSurge 3s ease-in-out infinite;
  transform-origin: 50% 82%;
  filter: drop-shadow(0 0 14px rgba(150, 200, 255, .22));
}
@keyframes wingSurge {
  0%, 100% { transform: scale(1, 1) rotate(0deg); filter: brightness(.96) drop-shadow(0 0 10px rgba(150, 200, 255, .16)); }
  50% { transform: scale(1.05, .965) rotate(.4deg); filter: brightness(1.15) drop-shadow(0 0 20px rgba(255, 220, 120, .3)); }
}

/* 六极真魔功·祭魔（S4）：六魔蒙纱待现 → 自魔雾中降世显形（模糊沉降+暗到亮） */
.au-fig.mo-veil .au-img { opacity: 0; }
.au-fig.mo-descend .au-img { animation: moDescend .78s cubic-bezier(.2, .8, .3, 1) both; }
@keyframes moDescend {
  0% { opacity: 0; translate: 0 -30px; filter: blur(7px) brightness(.45); }
  55% { opacity: 1; filter: blur(1.5px) brightness(.8) drop-shadow(0 0 18px rgba(140, 110, 190, .55)); }
  100% { opacity: 1; translate: 0 0; filter: none; }
}
/* 受击反作用（S1）：方向化击退+倾斜+回弹——方向 --kb（1=向右弹）与力度 --kbAmp 由 JS 按攻守相对位注入。
 * ⚠ 只动 .au-img/.au-glyph/.au-shade 的 translate，不碰外壳 left/transform（reconcile 红线） */
.axis-unit.shake .au-img, .axis-unit.shake .au-glyph, .axis-unit.shake .au-shade {
  animation: hitKnock .42s cubic-bezier(.16, .84, .32, 1);
}
@keyframes hitKnock {
  0% { translate: 0 0; rotate: 0deg; }
  22% { translate: calc(var(--kb, 1) * var(--kbAmp, 13px)) -2px; rotate: calc(var(--kb, 1) * -3.2deg); }
  58% { translate: calc(var(--kb, 1) * var(--kbAmp, 13px) * .34) 0; rotate: calc(var(--kb, 1) * -1deg); }
  100% { translate: 0 0; rotate: 0deg; }
}

/* 脚下血量数字（用户裁决：数值必须可见） */
.axis-unit .au-hpnum {
  font-size: 10.5px; color: #e8dcc4; letter-spacing: 0; line-height: 1.1; margin-top: 1px;
  text-shadow: 0 1px 4px rgba(0,0,0,.95), 0 0 8px rgba(0,0,0,.7); white-space: nowrap;
}
.au-hpnum .au-shnum { font-style: normal; color: #8fc4ec; margin-left: 3px; }

/* 战斗结算卡：胜负与每个敌人的下场，看清楚再收功 */
.combat-outro {
  position: absolute; inset: 0; z-index: 40;
  display: flex; align-items: center; justify-content: center;
  background: rgba(6,4,3,.6); backdrop-filter: blur(3px);
  animation: fxgIn .3s ease;
}
.co-card {
  min-width: min(340px, 86vw); max-width: 90vw; padding: 26px 30px 22px;
  background: linear-gradient(160deg, rgba(26,20,14,.97), rgba(16,12,9,.97));
  border: 1px solid rgba(201,169,106,.45); border-radius: 14px;
  box-shadow: 0 18px 60px rgba(0,0,0,.7), inset 0 0 40px rgba(201,169,106,.05);
  text-align: center; animation: coCardIn .45s cubic-bezier(.2,1.2,.4,1);
}
@keyframes coCardIn { from { transform: translateY(18px) scale(.96); opacity: 0; } to { transform: none; opacity: 1; } }
.co-result {
  font-family: var(--font-title, serif); font-size: 56px; font-weight: 700; line-height: 1.2;
  letter-spacing: 8px; margin-bottom: 8px;
}
.co-result.co-win { color: var(--gold-bright); text-shadow: 0 0 30px rgba(236,217,168,.55); }
.co-result.co-flee { color: #a8c4b8; text-shadow: 0 0 24px rgba(140,190,160,.4); }
.co-result.co-lose { color: #c98a7a; text-shadow: 0 0 24px rgba(194,92,80,.45); }
.co-foes { margin-bottom: 10px; }
.co-foe { font-size: 14px; color: #d8cdb8; padding: 2px 0; letter-spacing: 1px; }
.co-foe .cf-slain { color: var(--red); }
.co-foe .cf-fled { color: #b8d6a8; }
.co-foe .cf-stand { color: var(--ink-dim); }
.co-detail { font-size: 12.5px; color: var(--ink-dim); line-height: 1.8; margin-bottom: 10px; border-top: 1px dashed rgba(140,120,90,.3); padding-top: 8px; }
.co-loot { font-size: 13px; color: var(--gold-bright); margin-bottom: 14px; min-height: 18px; }
.combat-outro .btn { min-width: 160px; letter-spacing: 6px; }

/* 战录角标：战场右上角小印 */
.logbtn-corner {
  position: absolute; top: 6px; right: 8px; z-index: 9;
  width: 30px; height: 30px; border-radius: 8px; cursor: pointer;
  font-size: 13px; color: var(--ink-dim); letter-spacing: 0;
  background: rgba(14,11,8,.72); border: 1px solid rgba(140,120,90,.4);
  backdrop-filter: blur(2px);
}
.logbtn-corner:hover { color: var(--gold-bright); border-color: rgba(201,169,106,.6); }

/* 弹幕战报：挪到战场最上沿（用户裁决——下沿持久弹幕挡操作/挡点选） */
.combat-floats {
  position: absolute; left: 4%; right: 4%; top: 4px; z-index: 7;
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  pointer-events: none;
}
.log-float {
  max-width: 92%; padding: 3px 12px; border-radius: 12px;
  font-size: 11.5px; color: #d4c8b2; letter-spacing: .4px; text-align: center;
  background: rgba(12,9,7,.62); border: 1px solid rgba(140,120,90,.22);
  backdrop-filter: blur(2px);
  animation: logFloat 3.2s ease forwards;   /* 单行瞬时：速来速走，不挡视野（正源在战录框） */
}
.log-float.lf-hit { color: #e8d8b0; border-color: rgba(201,169,106,.35); }
.log-float.lf-hurt { color: #e8b0a0; border-color: rgba(194,92,80,.35); }
@keyframes logFloat {
  0% { opacity: 0; transform: translateY(-8px); }
  8%, 78% { opacity: .96; transform: translateY(0); }
  100% { opacity: 0; transform: translateY(6px); }
}

/* 单位层：立绘锚地平线，left 过渡=滑步 */
.axis-units { position: absolute; inset: 0 0 24px 0; pointer-events: none; z-index: 2; }
.axis-unit {
  position: absolute; bottom: 0; transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center;
  /* 丝滑三过渡（v88 reconcile 后生效）：走位滑步 / 升空换排浮移（translate）/ 排深缩放 */
  transition: left .42s cubic-bezier(.3,.9,.35,1),
              translate .5s cubic-bezier(.3,.85,.3,1),
              scale .45s ease;
  /* v95 大战场小人物：容器随人缩（名牌血条同缩——人小牌不能大）；
   * 下限 62px 守住触控热区红线（44px 可点区+边距） */
  pointer-events: auto; width: clamp(62px, 11vw, 108px);
}
.axis-unit .au-fig { display: contents; }   /* 立绘容器不参与布局（img 仍是 flex 子项） */
.axis-unit .au-extra { display: contents; }
/* v89 统一相机：人物尺寸恢复定值——所有"变小"都走世界 zoom（人/格/地台/血条一体缩），
 * 杜绝"只缩立绘、血条名牌不缩"的比例撕裂（--uscale 已废） */
.axis-unit .au-img {
  height: clamp(120px, 22vh, 200px); width: auto; max-width: none;
  filter: drop-shadow(0 12px 18px rgba(0,0,0,.66));
  transform-origin: 50% 97%;   /* 脚底轴心：站姿动作绕脚摇，脚尖钉死在地（踩地感的动作面） */
  animation: portraitIn .4s ease, idleRock 3.8s ease-in-out 1s infinite;
  /* 镜头缩放渐变 + 转身过渡（reconcile 后 img 持久——只在真变向时翻面，不再闪回） */
  transition: height .45s ease, transform .24s ease;
}
.axis-unit .au-img.battler { height: clamp(104px, 21vh, 180px); }
/* v91 相对坐标系（仅战斗轴）：身高=战场高的百分比（cqh）——任何屏幕/缩放下与
 * 底图地面带比例恒定。⚠ 只限 #axis-field（size 容器）内：洞窟 cave-track 无容器，
 * cqh 会回退视口单位把人放成巨人——洞窟沿用上面的 clamp 默认。
 * v95 大战场小人物（用户审美总纲）：人物 52→42cqh——气势来自天地大，不来自人物大。
 * v108 再降一档（45/42→35/33cqh）：用户实锤“明显太大”——人更小、天地更浩大、
 *   多人同屏自然不挤；战场同步加高，留白更足 */
#axis-field .axis-unit .au-img { height: 35cqh; }
#axis-field .axis-unit .au-img.battler { height: 33cqh; }
/* 站位错落：奇数格整体退后半步（上移+微缩+微暗）——同一条轴读出"路有宽度" */
/* —— 2.5 排制：纵深=真实单位站位（lane 偏移）× 高度（alt 偏移）——CSS 变量叠加合成。
 * 排偏移统一吃 --lane-gap（脚锚到自己那排的地线上=踩地）；off-row=半档深度。
 * --lx=排横向错位（透视斜移）：同格异排不再叠成一团（血条/立绘自然岔开） —— */
/* v90：缩放围绕脚底（origin 贴地）——排深缩放脚位不漂，--ly 与排地线的数学完全对齐；
 * idleRock 呼吸也因此天然"脚钉地、头肩动" */
.axis-unit { translate: calc(var(--lx, 0px) + var(--ax, 0px)) calc(var(--ly, 0px) + var(--ay, 0px)); scale: var(--ls, 1); transform-origin: 50% 100%; z-index: 10; }
/* 玩家=最近景（主角微放大一档——镜头离你最近；v95 收敛：人小天地大） */
.axis-unit.self { --ls: 1.04; }
.axis-unit.off-row { --ly: calc(-.5 * var(--lane-gap, 20px)); --lx: 9px; --ls: .94; z-index: 9; }
.axis-unit.off-row .au-img { filter: drop-shadow(0 12px 18px rgba(0,0,0,.66)) brightness(.94); }
/* 僚位排（v90 档差加大：近大远小一眼可辨）：每深一排 上移一档+右斜一档+
 * 缩一大档+空气透视一档（暗+灰+微失焦——远处色淡形虚，画师的标准空气透视）。
 * ⚠ z 序铁律：战位排(10) > off-row(9) > lane-1(8) > lane-2(6) > lane-3(4)——
 * 后排永远画在前排身后（v90 修：之前战位排无 z，深排灵狼的尾巴盖在狼王脸上） */
.axis-unit.lane-1 { --ly: calc(-1 * var(--lane-gap, 20px)); --lx: 30px; --ls: .84; z-index: 8; }
.axis-unit.lane-2 { --ly: calc(-2 * var(--lane-gap, 20px)); --lx: 54px; --ls: .72; z-index: 6; }
.axis-unit.lane-3 { --ly: calc(-3 * var(--lane-gap, 20px)); --lx: 74px; --ls: .63; z-index: 4; }
.axis-unit.lane-1 .au-img { filter: drop-shadow(0 10px 15px rgba(0,0,0,.6)) brightness(.93) saturate(.88); }
.axis-unit.lane-2 .au-img { filter: drop-shadow(0 8px 12px rgba(0,0,0,.55)) brightness(.88) saturate(.8) blur(.3px); }
.axis-unit.lane-3 .au-img { filter: drop-shadow(0 7px 10px rgba(0,0,0,.5)) brightness(.84) saturate(.74) blur(.4px); }
/* （接触影统一走 .axis-unit::before；::after 槽位留给 target/self 脚圈——伪元素各司其职） */
/* 朝向不再用静态镜像：所有单位按"面向自己的对手"动态翻转（.flipped/.flipped-img，见 _axisSprite） */
/* 站姿待机=呼吸式（v87 二改：钟摆摇被否——脚底钉死、躯干随呼吸微微起伏拉伸，
 * 头肩动、脚不动=活人站在地上；上下整体浮动是飞行单位的专利 hoverFloat） */
@keyframes idleRock {
  0%, 100% { scale: 1 1; }
  50% { scale: 1.006 1.014; }
}
.axis-unit .au-glyph {
  width: clamp(56px, 9vw, 88px); aspect-ratio: 1; display: flex; align-items: center; justify-content: center;
  border-radius: 50%; border: 1.5px solid rgba(194,92,80,.55);
  background: radial-gradient(circle at 50% 36%, rgba(194,92,80,.22), rgba(14,10,8,.85) 75%);
  box-shadow: 0 0 22px rgba(194,92,80,.2), inset 0 0 16px rgba(0,0,0,.6);
}
.axis-unit.self .au-glyph { border-color: rgba(126,185,142,.55); background: radial-gradient(circle at 50% 36%, rgba(96,150,110,.22), rgba(10,12,8,.85) 75%); }
.axis-unit .au-glyph span { font-size: clamp(26px, 4.4vw, 40px); color: #e0c9a4; text-shadow: 0 2px 10px rgba(0,0,0,.85); }
/* S5 粒子化身占位盒（虫群等 swarmFx 单位）：透明几何——撑出单位身位（血条/名牌/锚点对齐），
 * "身体"由 fx.js swarm 粒子群绘制（canvas front 层），DOM 里没有立绘 */
.axis-unit .au-swarmbox { width: clamp(52px, 9vw, 80px); height: clamp(70px, 14vh, 120px); }
#axis-field .axis-unit .au-swarmbox { height: 22cqh; }
/* D2 元神/残魂占位：人形黑色剪影。mask 取人形 alpha，暗色底填出剪影；
 * 滤镜/绕身光都做在本 .au-shade 层（非 .au-img），不触"绝不给 .au-img 加 filter"红线。 */
.axis-unit .au-shade {
  height: clamp(104px, 21vh, 180px); aspect-ratio: 1 / 2;
  -webkit-mask-size: contain; mask-size: contain;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center bottom; mask-position: center bottom;
  background: linear-gradient(180deg, rgba(40,44,66,.94) 0%, rgba(10,11,18,.99) 72%);
  filter: drop-shadow(0 0 13px rgba(150,162,228,.5)) drop-shadow(0 6px 10px rgba(0,0,0,.6));
  animation: ghostShadeFloat 3.4s ease-in-out infinite;
}
#axis-field .axis-unit .au-shade { height: 33cqh; }
@keyframes ghostShadeFloat { 0%, 100% { opacity: .8; } 50% { opacity: .98; } }
.axis-unit.strike-melee .au-shade { animation: strikeMelee .48s cubic-bezier(.2,.9,.3,1); }
.axis-unit.strike-cast .au-shade { animation: strikeCast .42s ease; }
.axis-unit.hitflash .au-shade { filter: brightness(2.4) drop-shadow(0 0 14px rgba(210,220,255,.85)) !important; }
/* 阵亡退场（v87）：水墨溅散演出（~0.9s）放完后彻底淡出——尸体不再半透明赖在场上
 * （引擎侧 _deadShown 保证只渲染"咽气那一拍"，之后不再入 DOM） */
.axis-unit.dead { opacity: .35; filter: grayscale(1); pointer-events: none; animation: deadFade 1.2s ease .9s forwards; }
.axis-unit.dead .au-img { animation: none; }
@keyframes deadFade { to { opacity: 0; visibility: hidden; } }
.axis-unit.enemy { cursor: pointer; }
.axis-unit.target .au-name { color: #e8b8a8; }
/* 接触阴影：踩实地面的关键一笔——所有单位脚下都有椭圆投影。
 * --feet=脚底距容器底（信息条区高度）；--ay 补偿=凌空时影子留在地线上（影在地、人在天） */
.axis-unit::before {
  content: ""; position: absolute; bottom: var(--feet, 40px); left: 50%; transform: translateX(-50%);
  width: 96%; height: 19px; border-radius: 50%; z-index: -1;
  /* v107 踩地加强：影心更实、外圈更柔——脚下“压实”一团暗才看得出人站在地上而非悬浮 */
  background: radial-gradient(ellipse, rgba(0,0,0,.6) 0%, rgba(0,0,0,.34) 40%, rgba(0,0,0,.13) 64%, transparent 78%);
  animation: shadowBreath 3.2s ease-in-out 1s infinite;
}
/* 凌空投影=高度计：飞得越高，地上的影子越小越淡（+ay 反向补偿=影子永远钉在地线，
 * 影与人的距离就是高度读数） */
/* 升空影：影留地线（::before 吃 +--ay 自动归地），并随高度"越高越散越淡"——
 * v110 加微弱 blur + 再收窄/降透：高空俯看自己的影只是地上一团淡晕＝真飞在天上的距离感 */
.axis-unit.airborne::before { bottom: calc(var(--feet, 40px) + var(--ay, 0px)); width: 44%; opacity: .5; filter: blur(1px); }
.axis-unit.airborne.air-2::before { width: 36%; opacity: .38; filter: blur(2px); }
.axis-unit.airborne.air-3::before { width: 28%; opacity: .28; filter: blur(3px); }
@keyframes shadowBreath { 0%,100% { transform: translateX(-50%) scale(1); opacity: 1; } 50% { transform: translateX(-50%) scale(.94); opacity: .85; } }
.axis-unit.dead::before { opacity: .25; animation: none; }
/* 锁定/我方的脚下色圈：贴着接触影、正在脚底（觅长生式选中圈——圈即站位） */
.axis-unit.target::after {
  content: ""; position: absolute; bottom: calc(var(--feet, 40px) + var(--ay, 0px) - 3px); left: 50%; transform: translateX(-50%);
  width: 88%; height: 19px; border-radius: 50%;
  border: 1.5px solid rgba(222,118,98,.8);
  background: radial-gradient(ellipse, rgba(194,92,80,.30) 30%, rgba(194,92,80,.12) 58%, transparent 74%);
  box-shadow: 0 0 10px rgba(214,112,96,.3), inset 0 0 8px rgba(214,112,96,.25);
  animation: selRing 1.6s ease-in-out infinite;
}
.axis-unit.self::after {
  content: ""; position: absolute; bottom: calc(var(--feet, 40px) + var(--ay, 0px) - 3px); left: 50%; transform: translateX(-50%);
  width: 88%; height: 19px; border-radius: 50%;
  border: 1.5px solid rgba(136,200,156,.66);
  background: radial-gradient(ellipse, rgba(126,185,142,.22) 30%, rgba(126,185,142,.08) 58%, transparent 74%);
  box-shadow: 0 0 9px rgba(126,185,142,.25), inset 0 0 8px rgba(126,185,142,.2);
}
@keyframes selRing { 0%,100% { opacity: 1; } 50% { opacity: .62; } }
.axis-unit.charging .au-img, .axis-unit.charging .au-glyph {
  filter: drop-shadow(0 0 18px rgba(232,198,106,.7));
  animation: chargePulse .9s ease-in-out infinite;
}
@keyframes chargePulse { 0%,100% { scale: 1; } 50% { scale: 1.04; } }
.axis-unit .demonized { filter: brightness(.12) saturate(.2) drop-shadow(0 0 18px rgba(154,127,212,.55)) !important; }

/* 主攻法宝伴身（正典考据：金蚨子母刃=一母八子，动画官设**青绿色冷光小刃**）——
 * 八柄子刃绕身浮游、母刃居手侧；刃形=刃身渐变收锋+刃尖高光+寒芒辉（不是色块）；
 * 各自相位差浮动；催动时 .launch 整阵射向目标（以后青竹蜂云剑=剑阵绕身复用） */
.axis-unit .au-blades { position: absolute; inset: 0; pointer-events: none; z-index: 3; }
.au-blades .bld {
  position: absolute; width: 6px; height: 19px;
  /* 小刀形：上窄锋下圆柄（clip 出刃形），青绿冷光渐变+刃脊高光 */
  clip-path: polygon(50% 0%, 88% 22%, 78% 86%, 62% 100%, 38% 100%, 22% 86%, 12% 22%);
  background: linear-gradient(185deg, #eafff0 0%, #9fe8b4 26%, #4fbf7e 58%, #1e6e4a 100%);
  box-shadow: 0 0 8px rgba(110, 230, 160, .75), 0 0 3px rgba(220, 255, 235, .9);
  animation: bladeBob 2.8s ease-in-out infinite;
}
/* 母刃：手侧大一号（驭刃之主），辉更盛 */
.au-blades .bld:nth-child(1) { width: 8px; height: 28px; right: 3px; top: 48%; rotate: 10deg; box-shadow: 0 0 12px rgba(130,240,175,.95), 0 0 4px rgba(230,255,240,1); animation-delay: 0s; }
/* 八子刃：左右两弧各四，错相位浮动（绕身分袭的阵势） */
.au-blades .bld:nth-child(2) { left: -16px; top: 24%; rotate: -16deg; animation-delay: -.3s; }
.au-blades .bld:nth-child(3) { left: -8px;  top: 36%; rotate: -10deg; animation-delay: -.9s; }
.au-blades .bld:nth-child(4) { left: -19px; top: 48%; rotate: -20deg; animation-delay: -1.5s; }
.au-blades .bld:nth-child(5) { left: -5px;  top: 60%; rotate: -6deg;  animation-delay: -2.1s; }
.au-blades .bld:nth-child(6) { right: -14px; top: 22%; rotate: 14deg; animation-delay: -.6s; }
.au-blades .bld:nth-child(7) { right: -6px;  top: 34%; rotate: 8deg;  animation-delay: -1.2s; }
.au-blades .bld:nth-child(8) { right: -18px; top: 46%; rotate: 18deg; animation-delay: -1.8s; }
.au-blades .bld:nth-child(9) { right: -10px; top: 58%; rotate: 6deg;  animation-delay: -2.4s; }
/* 朝向镜像（持刃者面向左侧之敌时）：左右互换（left↔right）、rotate 取反——整阵随转身翻面。
 * 用 left/right:auto 显式解除原约束，避免 left+right 双设导致的过约束。 */
.au-blades.flipped .bld:nth-child(1) { right: auto; left: 3px;   rotate: -10deg; }
.au-blades.flipped .bld:nth-child(2) { left: auto;  right: -16px; rotate: 16deg; }
.au-blades.flipped .bld:nth-child(3) { left: auto;  right: -8px;  rotate: 10deg; }
.au-blades.flipped .bld:nth-child(4) { left: auto;  right: -19px; rotate: 20deg; }
.au-blades.flipped .bld:nth-child(5) { left: auto;  right: -5px;  rotate: 6deg; }
.au-blades.flipped .bld:nth-child(6) { right: auto; left: -14px;  rotate: -14deg; }
.au-blades.flipped .bld:nth-child(7) { right: auto; left: -6px;   rotate: -8deg; }
.au-blades.flipped .bld:nth-child(8) { right: auto; left: -18px;  rotate: -18deg; }
.au-blades.flipped .bld:nth-child(9) { right: auto; left: -10px;  rotate: -6deg; }
@keyframes bladeBob { 0%,100% { translate: 0 0; opacity: .95; } 50% { translate: 0 -6px; opacity: .75; } }
/* 催刃出袭闭环（复用通用协议 --strike-x/y）：八子刃各自从绕身位汇聚射向目标 → 命中 → 归位
 * （不再飞出 270px 消失）。刃保留各自静态朝向飞行（不改 rotate，避免与 nth-child 写死值跳变） */
.au-blades.launch .bld { animation: bldStrike .88s cubic-bezier(.36,0,.3,1) forwards; z-index: 9; }
.au-blades.launch .bld:nth-child(2n) { animation-delay: .05s; }
.au-blades.launch .bld:nth-child(3n) { animation-delay: .1s; }
@keyframes bldStrike {
  0%   { translate: 0 0; opacity: 1; }
  13%  { translate: calc(var(--strike-x,0px) * -.07) calc(var(--strike-y,0px) * -.07); }   /* 反向收势 */
  40%  { translate: var(--strike-x,0px) var(--strike-y,0px); scale: 1.18; }   /* 射达·汇聚 */
  50%  { translate: var(--strike-x,0px) var(--strike-y,0px); scale: .92; }    /* 命中·顿 */
  /* 命中后同样兜一道弧返回（弧顶=回程中点+垂直偏移），不原路退——与青竹剑闭环一致 */
  72%  { translate: calc(var(--strike-x,0px) * .52 - var(--strike-y,0px) * .3) calc(var(--strike-y,0px) * .52 + var(--strike-x,0px) * .3); }
  100% { translate: 0 0; opacity: 1; }   /* 归位 */
}

/* 青竹蜂云剑·持续剑阵（v98 用户裁决：本命法宝=12 把剑绕身常驻；附"附剑"=剑身缠金雷）——
 * 剑形：细长青玉剑刃（clip 出剑尖+剑脊+护手+短柄），绕身错相浮游 */
/* au-swords 不设 z-index（不建堆叠上下文）——让每把剑的 z-index 直接与立绘 au-img
 * 较量：上半环的剑钻到身后被遮挡、下半环的剑压在身前=真正"环绕人身"而非整层悬浮 */
.axis-unit .au-swords { position: absolute; inset: 0; pointer-events: none; }
.au-swords .sw {
  position: absolute; margin: -33px 0 0 -10px;
  width: 20px; height: 66px;
  transform-origin: 50% 50%;
  animation: swHover var(--hd, 5.5s) ease-in-out var(--hdelay, 0s) infinite;
}
/* 剑本体（::before）：clip 出剑形 + 玉剑渐变；光晕/描边用 drop-shadow（box-shadow 会被 clip 裁掉！）。
 * 剑尖在底、护手（22~30%）+短柄在顶；剑身加粗刃面饱满 */
.au-swords .sw::before {
  content: ""; position: absolute; inset: 0;
  clip-path: polygon(50% 100%, 62% 87%, 58% 34%, 76% 30%, 76% 22%, 56% 21%, 55% 4%, 50% 0%, 45% 4%, 44% 21%, 24% 22%, 24% 30%, 42% 34%, 38% 87%);
  background:
    linear-gradient(180deg, transparent 22%, rgba(255,233,160,.5) 25%, rgba(255,243,205,.62) 27%, transparent 29.5%),
    linear-gradient(90deg, transparent 44%, rgba(236,255,245,.9) 50%, transparent 56%),
    linear-gradient(90deg, #103f2a 0%, #1d6e46 20%, #34a067 40%, #7ce0a6 50%, #34a067 60%, #1d6e46 80%, #103f2a 100%);
  filter: drop-shadow(.7px 0 0 #04200f) drop-shadow(-.7px 0 0 #04200f) drop-shadow(0 .7px 0 #04200f) drop-shadow(0 -.7px 0 #04200f) drop-shadow(0 0 5px rgba(82,222,150,.75)) drop-shadow(0 0 10px rgba(58,195,128,.45));
}
/* 云雾拖尾（::after，脱离 clip 才能溢出剑形）：从剑柄(顶)向剑后(上)拉出的青绿光雾——
 * blur 柔化成雾 + 纵向渐变渐淡 + swMist 伸缩明灭=流动感；随 .sw 旋转自动甩到剑柄正后方 */
.au-swords .sw::after {
  content: ""; position: absolute;
  left: 3px; width: 14px; top: -50px; height: 96px;
  background: linear-gradient(to top,
    rgba(150,255,200,.08) 0%, rgba(165,255,208,.8) 15%, rgba(82,228,160,.5) 42%, rgba(60,200,138,.2) 70%, transparent 90%);
  filter: blur(4.5px); border-radius: 50%;
  transform-origin: 50% 100%; pointer-events: none; z-index: -1;
  animation: swMist var(--hd, 5.5s) ease-in-out var(--hdelay, 0s) infinite;
}
/* 蓄势-前冲同步：剑朝剑尖猛探(72%)时拖尾向剑尾暴长=速度残影；蓄势/回弹时收短 */
@keyframes swMist {
  0%   { opacity: .42; transform: scaleY(.78); }
  55%  { opacity: .38; transform: scaleY(.7);  }
  72%  { opacity: .96; transform: scaleY(1.6); }
  85%  { opacity: .66; transform: scaleY(1.12); }
  100% { opacity: .42; transform: scaleY(.78); }
}
/* 蓄势待发（备战核心）：剑沿自身剑轴"后撤蓄力 → 朝剑尖猛探前冲 → 过冲回弹"，像箭在弦上跃跃欲射。
 * rotate 在前、translate 在后=位移走剑轴局部坐标（+y=剑尖方向）；各柄 hd/hdelay 全不同→
 * 群剑此起彼伏地蓄势前探、永不同步=活的备战气场。与 swMist 同相位（72% 前冲峰=拖尾暴长） */
@keyframes swHover {
  0%   { transform: rotate(var(--r, 0deg)) translate(0, -2px); }
  55%  { transform: rotate(calc(var(--r, 0deg) - 1deg)) translate(0, -4px); }
  72%  { transform: rotate(var(--r, 0deg)) translate(0, 9px); }
  85%  { transform: rotate(calc(var(--r, 0deg) + 1deg)) translate(0, 2px); }
  100% { transform: rotate(var(--r, 0deg)) translate(0, -2px); }
}
/* 常态（arc）：剑本体描边+光晕柔和明灭（闪光淡），作用 ::before */
.au-swords.arc .sw::before {
  animation: swArc 3.6s ease-in-out var(--hdelay, 0s) infinite;
}
/* 描边（4 向零模糊深墨绿勾实体轮廓）+ 绿光晕，柔和明灭（闪光淡）；拖尾已独立为 ::after */
@keyframes swArc {
  0%,100% { filter: drop-shadow(.7px 0 0 #04200f) drop-shadow(-.7px 0 0 #04200f) drop-shadow(0 .7px 0 #04200f) drop-shadow(0 -.7px 0 #04200f) drop-shadow(0 0 5px rgba(82,222,150,.72)) drop-shadow(0 0 10px rgba(58,195,128,.42)) brightness(1); }
  50%     { filter: drop-shadow(.7px 0 0 #04200f) drop-shadow(-.7px 0 0 #04200f) drop-shadow(0 .7px 0 #04200f) drop-shadow(0 -.7px 0 #04200f) drop-shadow(0 0 6px rgba(92,232,160,.9)) drop-shadow(0 0 12px rgba(64,205,135,.55)) brightness(1.1); }
}
.au-swords.arc .lei-aura {
  position: absolute; left: 50%; top: 46%; width: 64px; height: 84px; margin: -42px 0 0 -32px;
  border-radius: 50%; pointer-events: none;
  background: radial-gradient(ellipse at 50% 50%, rgba(120,180,255,.08), transparent 70%);
  animation: leiAuraPulse 1.4s ease-in-out infinite;
}
/* 神雷附剑态（金雷缠剑·problem 2）：剑身仍以青竹绿为主(只略提亮)，金色靠周身电弧/环境雷/光环
 * 环绕为辅——绝不把整把剑刷成金。横向白炽芯线=被电流贯穿的高温感。 */
.au-swords.lei .sw::before {
  background:
    linear-gradient(180deg, transparent 22%, rgba(255,243,205,.5) 25%, rgba(255,247,214,.66) 27%, transparent 29.5%),
    linear-gradient(90deg, transparent 42%, rgba(240,255,248,.96) 50%, transparent 58%),
    linear-gradient(90deg, #0d3a26 0%, #1d6e46 20%, #3fb074 42%, #9bf0c0 50%, #3fb074 58%, #1d6e46 80%, #0d3a26 100%);
  animation: swLei 0.5s steps(2) infinite;
}
/* 金雷态拖尾：仍是青绿雾（略亮于常态），不转金 */
.au-swords.lei .sw::after {
  background: linear-gradient(to top, rgba(160,255,205,.1) 0%, rgba(185,255,218,.86) 15%, rgba(94,238,168,.55) 42%, rgba(64,205,138,.22) 70%, transparent 90%);
}
/* 金雷态描边：青绿实体勾边(保本色) + 绿光晕间歇闪金(绿底闪金=金电缠身，而非整把金) */
@keyframes swLei {
  0%,100% { filter: drop-shadow(.7px 0 0 #04200f) drop-shadow(-.7px 0 0 #04200f) drop-shadow(0 .7px 0 #04200f) drop-shadow(0 -.7px 0 #04200f) drop-shadow(0 0 5px rgba(82,222,150,.82)) drop-shadow(0 0 10px rgba(58,195,128,.5)) brightness(1.05); }
  50%     { filter: drop-shadow(.7px 0 0 #04200f) drop-shadow(-.7px 0 0 #04200f) drop-shadow(0 .7px 0 #04200f) drop-shadow(0 -.7px 0 #04200f) drop-shadow(0 0 6px rgba(92,232,160,.95)) drop-shadow(0 0 9px rgba(255,210,90,.7)) brightness(1.28); }
}
.au-swords.lei .lei-aura {
  position: absolute; left: 50%; top: 44%; width: 96px; height: 120px; margin: -60px 0 0 -48px;
  border-radius: 50%; pointer-events: none;
  background: radial-gradient(ellipse at 50% 50%, rgba(255,214,90,.2), transparent 66%);
  box-shadow: 0 0 26px rgba(255,196,40,.5) inset;
  animation: leiAuraPulse 0.8s ease-in-out infinite;
}
@keyframes leiAuraPulse { 0%,100% { opacity: .5; scale: .96; } 50% { opacity: 1; scale: 1.05; } }

/* ===== R4 神雷附剑·周身环绕雷弧（lei-orbit，参考图1 蓝金雷电缠身）=====
 * conic 渐变切出一段亮电弧，radial 遮罩抠成绕身环带；亮弧沿环周巡游
 * （椭圆本体固定不翻滚=真"绕身旋掠"，而非整体打转）。两道错相、一前(z7)一后(z-2)=缠身纵深；
 * 主道金、辅道蓝白（金为主·蓝白点缀=神雷金色身份不破）。无 RAF、不触性能红线。 */
/* 性能优化(v104)：环带本体(::before)画**静态** conic 亮弧 + radial 遮罩抠成环，只用
 * transform:rotate 让亮弧绕圈巡游——旋转走合成器层(GPU)，不再每帧在主线程重绘整张 conic 渐变，
 * 手机帧率大幅回升而视觉不变。外层 .lei-orbit 用静态 scaleY 把圆环拉成纵向椭圆=绕身缠绕感。
 * ⚠ transform 只加在 .lei-orbit / 其 ::before 这种叶子上(自带 z-index)，绝不上 .au-swords 容器。 */
.au-swords.lei .lei-orbit {
  position: absolute; left: 50%; top: 44%;
  width: 108px; height: 108px; margin: -54px 0 0 -54px;
  transform: scaleY(1.22); pointer-events: none; z-index: 7;
}
.au-swords.lei .lei-orbit::before {
  content: ""; position: absolute; inset: 0; border-radius: 50%; pointer-events: none;
  background: conic-gradient(from 0deg,
    transparent 0deg, transparent 232deg,
    rgba(255,247,214,0) 252deg, #fff7d6 286deg, #fff 300deg, #ffd970 312deg,
    rgba(255,176,30,0) 336deg, transparent 360deg);
  -webkit-mask: radial-gradient(closest-side at 50% 50%, transparent 58%, #000 64%, #000 74%, transparent 81%);
          mask: radial-gradient(closest-side at 50% 50%, transparent 58%, #000 64%, #000 74%, transparent 81%);
  filter: drop-shadow(0 0 4px #ffe39a) drop-shadow(0 0 9px rgba(255,176,30,.6));
  will-change: transform;
  animation: leiOrbitSpin 1.05s linear infinite;
}
/* 辅道：更瘦高(纵向缠绕错位)、藏身后(z-2)、逆向慢转、冷蓝白点缀 */
.au-swords.lei .lei-orbit.lo2 {
  width: 86px; height: 86px; margin: -43px 0 0 -43px; z-index: -2;
  transform: scaleY(1.77);
}
.au-swords.lei .lei-orbit.lo2::before {
  animation-duration: 1.5s; animation-direction: reverse;
  filter: drop-shadow(0 0 3px #bfe0ff) drop-shadow(0 0 8px rgba(120,180,255,.55));
  background: conic-gradient(from 0deg,
    transparent 0deg, transparent 232deg,
    rgba(223,240,255,0) 252deg, #eaf4ff 288deg, #fff 302deg, #86b4ff 314deg,
    rgba(120,180,255,0) 338deg, transparent 360deg);
}
@keyframes leiOrbitSpin { to { transform: rotate(360deg); } }

/* ===== 剑身缠雷（电弧层 <b>）：沿剑身游走跳动的之字闪电 =====
 * 伪元素已被剑身(::before)+拖尾(::after)占满，故缠雷另起真实子层 <b>。
 * clip-path 切出闪电折线带，drop-shadow 令电弧发光；swBolt 以 steps 瞬跳=电流"窜动"的真实
 * 跳变（绝非平滑滑动）。常态=淡蓝小电流缠身；神雷附剑态=金白大电弧暴缠（更粗·更急·更亮）。 */
.au-swords .sw b {
  position: absolute; left: 50%; top: 11%; width: 15px; height: 74%; margin-left: -7.5px;
  clip-path: polygon(42% 0%, 56% 14%, 36% 30%, 62% 46%, 38% 60%, 60% 76%, 44% 100%, 58% 100%, 72% 76%, 50% 60%, 76% 46%, 50% 30%, 70% 14%, 56% 0%);
  pointer-events: none; z-index: 2;
  animation: swBolt .22s steps(1) var(--boltd, 0s) infinite;
}
.au-swords.arc .sw b {
  width: 9px; margin-left: -4.5px; top: 24%; height: 54%;   /* 常态=细·短·淡的普通小蓝电 */
  background: linear-gradient(180deg, #eaf4ff, #aed6ff 50%, #8fc4ff);
  filter: drop-shadow(0 0 2px #bfe0ff) drop-shadow(0 0 3px rgba(106,168,255,.7));
  animation-name: swBoltSmall; animation-duration: .3s;   /* 轻微小幅窜动，远比附魔态克制 */
}
.au-swords.lei .sw b {
  /* 白炽芯+金外焰（横向截面）=高温电弧质感 */
  background: linear-gradient(90deg, #ffb01e, #fff7d6 34%, #fff 50%, #fff7d6 66%, #ffb01e);
  filter: drop-shadow(0 0 3px #fff3c4) drop-shadow(0 0 6px #ffb01e) drop-shadow(0 0 11px rgba(255,176,30,.65));
  width: 17px; margin-left: -8.5px; animation-duration: .16s;
}
/* 电弧窜动：每帧瞬跳（翻转折线朝向+上下窜+明灭）=电流在剑身上游走的跳变 */
@keyframes swBolt {
  0%   { transform: scaleX(1)  translateY(0);     opacity: .95; }
  20%  { transform: scaleX(-1) translateY(-2px);  opacity: .35; }
  40%  { transform: scaleX(1)  translateY(2px);   opacity: 1;   }
  60%  { transform: scaleX(-1) translateY(-1px);  opacity: .5;  }
  80%  { transform: scaleX(1)  translateY(1.5px); opacity: .88; }
  100% { transform: scaleX(-1) translateY(0);     opacity: .4;  }
}
/* 常态小蓝电：轻微细小的窜动（普通小电流，幅度远比附魔态克制） */
@keyframes swBoltSmall {
  0%,100% { transform: scaleX(1)  translateY(0);     opacity: .4;  }
  50%     { transform: scaleX(-1) translateY(-.8px); opacity: .72; }
}

/* ===== 附魔·周身环境雷（lei-bolt）：神雷附剑后人物周身此起彼伏窜现金雷弧 =====
 * 4 道分布肩/腰两侧，大部分时间隐，错相轮流窜现一道急促金弧=周身不时炸雷的临场感。 */
.au-swords.lei .lei-bolt {
  position: absolute; width: 13px; pointer-events: none; z-index: 5; opacity: 0;
  background: linear-gradient(180deg, #fff, #fff3c4 45%, #ffd970);
  clip-path: polygon(44% 0%, 60% 18%, 34% 38%, 64% 56%, 36% 74%, 58% 100%, 70% 100%, 46% 74%, 76% 56%, 48% 38%, 72% 18%, 56% 0%);
  filter: drop-shadow(0 0 4px #ffe39a) drop-shadow(0 0 9px #ffb01e);
  animation: leiBolt .9s steps(1) var(--bdelay, 0s) infinite;
}
.au-swords.lei .lei-bolt:nth-child(12) { left: 17%; top: 28%; height: 26%; --bdelay: 0s;    }
.au-swords.lei .lei-bolt:nth-child(13) { left: 79%; top: 31%; height: 24%; --bdelay: -.24s; }
.au-swords.lei .lei-bolt:nth-child(14) { left: 25%; top: 55%; height: 30%; --bdelay: -.46s; }
.au-swords.lei .lei-bolt:nth-child(15) { left: 71%; top: 56%; height: 30%; --bdelay: -.68s; }
.au-swords.lei .lei-bolt:nth-child(16) { left: 45%; top: 15%; height: 22%; --bdelay: -.12s; }
.au-swords.lei .lei-bolt:nth-child(17) { left: 53%; top: 71%; height: 28%; --bdelay: -.56s; }
/* 环境雷：大部分时间隐，每周期窜现一道急促金弧（错相=周身此起彼伏） */
@keyframes leiBolt {
  0%, 64%, 100% { opacity: 0;  transform: scaleX(1)  scaleY(1);    }
  68%           { opacity: .9; transform: scaleX(1)  scaleY(1);    }
  74%           { opacity: .3; transform: scaleX(-1) scaleY(1.12); }
  80%           { opacity: .85;transform: scaleX(1)  scaleY(.96);  }
  86%           { opacity: 0;  transform: scaleX(-1) scaleY(1);    }
}

/* ===== 应雷仪式（lei-cast）：神雷附剑施放、剑阵转金那一刻的入场高光 =====
 * 群剑应雷齐震（scale 脉冲张缩）+ 金雷光环暴胀涌现。⚠ 只作用单剑/光环，绝不给 .au-swords
 * 容器加 transform/filter——那会建堆叠上下文、毁掉剑与立绘的 z 较量纵深（容器注释红线）。 */
/* problem 1：柔和单峰涌现（不再 1.4→.8 暴张暴缩="竖一下"硬跳），始终带 --r 旋转(绝不转竖)，
 * 首尾都落在 swHover 0%(translate(0,-2px))=与常态浮游无缝衔接。配合 _reconcileSwords 不重建剑阵。 */
.au-swords.lei.lei-cast .sw { animation: leiCastPulse .55s ease-out forwards; }
@keyframes leiCastPulse {
  0%   { transform: rotate(var(--r,0deg)) translate(0,-2px) scale(1);    }
  35%  { transform: rotate(var(--r,0deg)) translate(0,-5px) scale(1.12); }   /* 应雷柔涌 */
  100% { transform: rotate(var(--r,0deg)) translate(0,-2px) scale(1);    }   /* 衔接 swHover 0% */
}
.au-swords.lei.lei-cast .lei-aura { animation: leiAuraBurst .6s ease-out; }
@keyframes leiAuraBurst {
  0%   { opacity: 0; scale: .3;  }
  25%  { opacity: 1; scale: 1.5; }
  100% { opacity: .5; scale: 1;  }   /* 衔接 leiAuraPulse 常态 */
}
/* 斜侧 2.5D 透视（problem 3）：人物在最前、斜侧身；剑阵纵深锚定"水平方向"——
 * 左侧剑=身前(大·亮·z6，压在立绘前)、右侧剑=身后(小·暗·z-1，钻到立绘后)，
 * 而非旧版上小下大的俯视椭圆。10 柄仍均布成环绕人身的椭圆，剑锋统一朝敌(右·--r≈-90)。 */
/* 身前·左半 5 柄（近：大·亮·z6） */
/* R1：全阵共用同一 --hd/--hdelay=0 → 十柄呼吸(swHover/swMist/swArc)完全同步、齐起齐落；
 * 缠雷电弧(swBolt)另走 --boltd 错相，保留电流游走的活气(呼吸同步≠电弧也齐闪)。 */
.au-swords .sw:nth-child(1)  { left: 12%; top: 42%; --r: -90deg; scale: 1.18; opacity: 1;   --hd: 5.5s; --hdelay: 0s; --boltd: 0s;    z-index: 6; }
.au-swords .sw:nth-child(2)  { left: 20%; top: 17%; --r: -92deg; scale: 1.04; opacity: .95; --hd: 5.5s; --hdelay: 0s; --boltd: -.05s; z-index: 6; }
.au-swords .sw:nth-child(3)  { left: 23%; top: 67%; --r: -88deg; scale: 1.08; opacity: .96; --hd: 5.5s; --hdelay: 0s; --boltd: -.1s;  z-index: 6; }
.au-swords .sw:nth-child(4)  { left: 35%; top: 6%;  --r: -91deg; scale: .96;  opacity: .9;  --hd: 5.5s; --hdelay: 0s; --boltd: -.15s; z-index: 6; }
.au-swords .sw:nth-child(5)  { left: 37%; top: 89%; --r: -89deg; scale: .98;  opacity: .9;  --hd: 5.5s; --hdelay: 0s; --boltd: -.08s; z-index: 6; }
/* 身后·右半 5 柄（远：小·暗·z-1） */
.au-swords .sw:nth-child(6)  { left: 65%; top: 7%;  --r: -91deg; scale: .8;   opacity: .82; --hd: 5.5s; --hdelay: 0s; --boltd: -.12s; z-index: -1; }
.au-swords .sw:nth-child(7)  { left: 63%; top: 90%; --r: -89deg; scale: .82;  opacity: .82; --hd: 5.5s; --hdelay: 0s; --boltd: -.03s; z-index: -1; }
.au-swords .sw:nth-child(8)  { left: 80%; top: 20%; --r: -91deg; scale: .68;  opacity: .76; --hd: 5.5s; --hdelay: 0s; --boltd: -.18s; z-index: -1; }
.au-swords .sw:nth-child(9)  { left: 82%; top: 64%; --r: -89deg; scale: .7;   opacity: .78; --hd: 5.5s; --hdelay: 0s; --boltd: -.07s; z-index: -1; }
.au-swords .sw:nth-child(10) { left: 90%; top: 42%; --r: -91deg; scale: .62;  opacity: .72; --hd: 5.5s; --hdelay: 0s; --boltd: -.14s; z-index: -1; }
/* 朝向镜像（韩立面向左侧之敌时）：水平翻转整阵=每柄 left→100%-left、--r 取反（剑尖随之指向左侧）。
 * ⚠ 不给 .au-swords 容器加 transform（会建堆叠上下文、毁掉剑与立绘的 z 较量），只逐柄改 left/--r。
 * 其余 scale/z-index/opacity/--hd… 沿用上面基准规则（本组特异性更高，只覆写 left 与 --r）。 */
.au-swords.flipped .sw:nth-child(1)  { left: 88%; --r: 90deg; }
.au-swords.flipped .sw:nth-child(2)  { left: 80%; --r: 92deg; }
.au-swords.flipped .sw:nth-child(3)  { left: 77%; --r: 88deg; }
.au-swords.flipped .sw:nth-child(4)  { left: 65%; --r: 91deg; }
.au-swords.flipped .sw:nth-child(5)  { left: 63%; --r: 89deg; }
.au-swords.flipped .sw:nth-child(6)  { left: 35%; --r: 91deg; }
.au-swords.flipped .sw:nth-child(7)  { left: 37%; --r: 89deg; }
.au-swords.flipped .sw:nth-child(8)  { left: 20%; --r: 91deg; }
.au-swords.flipped .sw:nth-child(9)  { left: 18%; --r: 89deg; }
.au-swords.flipped .sw:nth-child(10) { left: 10%; --r: 91deg; }

/* ===== 剑刃乱舞·劈砍闭环（problem 4）：每把剑沿"各自的弧线"穿透敌身→过冲到敌后→划大弧绕回 =====
 * JS _launchOrbit 给每把剑注入：--strike-x/y（自身中心→各自穿透点的位移，撒在敌身各处）、
 * --strike-r（剑尖朝穿透点的角度）、--strike-delay（错相·乱舞不齐射）、--bow（±兜弧方向·交叉乱舞）。
 * backwards 填充=错相延迟期间保持朝敌姿态(不竖)。任何绕身阵列复用这套协议变量即可。 */
.au-swords.launch .sw { animation: swStrike .92s cubic-bezier(.34,0,.28,1) var(--strike-delay,0s) both; z-index: 9; }
.au-swords.launch .sw::after { animation: swTrailStrike .92s ease-out var(--strike-delay,0s) both; }
@keyframes swStrike {
  0%   { transform: translate(0,-2px) rotate(var(--r,0deg)); }
  12%  { transform: translate(calc(var(--strike-x,0px) * -.08), calc(var(--strike-y,0px) * -.08)) rotate(var(--strike-r,-90deg)); }   /* 蓄势·后撤 */
  44%  { transform: translate(calc(var(--strike-x,0px) * 1.18), calc(var(--strike-y,0px) * 1.18)) rotate(var(--strike-r,-90deg)) scale(1.06); }   /* 穿透敌身·过冲到敌后 */
  /* 不原路退：朝 --bow 侧划一道大弧绕回（弧顶=回程中点±垂直偏移）=乱舞交叉 */
  74%  { transform: translate(calc(var(--strike-x,0px) * .5 - var(--strike-y,0px) * var(--bow,.5)), calc(var(--strike-y,0px) * .5 + var(--strike-x,0px) * var(--bow,.5))) rotate(calc(var(--strike-r,-90deg) + 196deg)); }
  100% { transform: translate(0,-2px) rotate(var(--r,0deg)); }   /* 归位·复浮游朝向 */
}
/* 拖尾双程暴涨：穿透一波 + 兜弧返回再一波（scaleY 拉满=速度残影），过冲/归位时收 */
@keyframes swTrailStrike {
  0%   { opacity: .5;  transform: scaleY(.8);  }
  12%  { opacity: .8;  transform: scaleY(1.3); }
  40%  { opacity: 1;   transform: scaleY(3.0); }   /* 穿透·暴涨 */
  56%  { opacity: .8;  transform: scaleY(1.3); }   /* 过冲·收 */
  74%  { opacity: .95; transform: scaleY(2.4); }   /* 兜弧返回·再涨残影 */
  100% { opacity: .5;  transform: scaleY(.8);  }
}
/* 手机端缩小剑阵：**只**改剑本体内禀尺寸(width/height/margin/拖尾/电弧)，绝不在 .au-swords
 * 容器上加 scale/transform——那会在容器建堆叠上下文，把十柄剑压成一层、毁掉身前(z6)/身后(z-1)
 * 的前后纵深(桌面正常、手机"全跑到身后"正是此坑)。光环/周身环绕(锚定身体)保持原尺寸不缩。 */
@media (max-width: 640px) {
  .au-swords .sw { width: 16px; height: 54px; margin: -27px 0 0 -8px; }
  .au-swords .sw::after { left: 2px; width: 11px; top: -41px; height: 79px; }
  .au-swords .sw b { width: 12px; margin-left: -6px; }
  .au-swords.arc .sw b { width: 7px; margin-left: -3.5px; }
  .au-swords.lei .sw b { width: 14px; margin-left: -7px; }
}

/* 身侧悬浮法器（拥有感）：装备化作灵光绕身 */
.axis-unit .au-orbit { position: absolute; inset: 0; pointer-events: none; z-index: 3; }
.au-orbit .orb {
  position: absolute; width: 24px; height: 24px;
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 700; border-radius: 6px; rotate: 45deg;
  background: rgba(18,14,10,.86); border: 1px solid rgba(216,198,144,.6);
  color: var(--wx-jin); box-shadow: 0 0 10px rgba(216,198,144,.35);
}
.au-orbit .orb > * { rotate: -45deg; }
.au-orbit .orb-w { left: -14px; top: 32%; animation: orbFloatA 3.4s ease-in-out infinite; }
.au-orbit .orb-a { right: -14px; top: 46%; color: var(--blue); border-color: rgba(111,159,200,.6); box-shadow: 0 0 10px rgba(111,159,200,.3); animation: orbFloatB 3.9s ease-in-out infinite; }
@keyframes orbFloatA { 0%,100% { translate: 0 0; } 50% { translate: -3px -7px; } }
@keyframes orbFloatB { 0%,100% { translate: 0 0; } 50% { translate: 3px -6px; } }

/* 悬浮法宝绕身（祭出位 v98）：祭起的法宝化作宝光绕躯干公转、自行运转——
 * 经典 rotate→translateX→rotate 公转法（绕身一周且自身始终竖直）；椭圆压扁=俯视透视 */
/* au-floats 用 display:contents 不建堆叠上下文——让每个 fl-orb 的 z-index 直接与立绘(au-img)较量，
 * 才能"绕到身后被遮挡"（前半弧压住立绘、后半弧钻到立绘身后） */
.axis-unit .au-floats { display: contents; }
.au-floats .fl-orb {
  position: absolute; left: 50%; top: 34%; margin: -11px 0 0 -11px;
  width: 22px; height: 22px; pointer-events: none; font-style: normal;
  animation: flOrbit 4.6s linear infinite;
}
.au-floats .fl-1 { animation-delay: -1.15s; }
.au-floats .fl-2 { animation-delay: -2.3s; }
.au-floats .fl-3 { animation-delay: -3.45s; }
/* 通用驭物宝器=无字灵光宝珠（菱形宝光，不再用印文凑数） */
.fl-orb.fl-gem::before {
  content: ""; position: absolute; inset: 4px; rotate: 45deg; border-radius: 5px;
  background: radial-gradient(circle at 50% 36%, #fff3c4, #e2c277 72%);
  box-shadow: 0 0 12px rgba(226,194,119,.7), inset 0 0 5px rgba(255,255,255,.6);
}
.fl-orb.fl-gem.wx-mu::before { background: radial-gradient(circle at 50% 36%, #eafff0, #6fc88c 72%); box-shadow: 0 0 12px rgba(111,200,140,.7), inset 0 0 5px rgba(220,255,230,.6); }
/* 如意花篮：竹篾小篮（梯形篮身+提梁+横纹）+彩花自篮中泉涌（绕身公转） */
.fl-orb.fl-basket .bk {
  position: absolute; left: 50%; bottom: 2px; transform: translateX(-50%);
  width: 17px; height: 11px;
  background: linear-gradient(180deg, #d8af52, #7a5320);
  clip-path: polygon(10% 0, 90% 0, 100% 100%, 0 100%);
  border-radius: 0 0 3px 3px; box-shadow: 0 0 8px rgba(226,194,119,.55);
}
.fl-orb.fl-basket .bk::after {
  content: ""; position: absolute; inset: 0;
  clip-path: polygon(10% 0, 90% 0, 100% 100%, 0 100%);
  background: repeating-linear-gradient(90deg, transparent 0 2.5px, rgba(60,40,15,.45) 2.5px 3.5px);
}
.fl-orb.fl-basket .bk::before {
  content: ""; position: absolute; left: 50%; top: -5px; transform: translateX(-50%);
  width: 13px; height: 8px; border: 1.5px solid #d8af52; border-bottom: none; border-radius: 7px 7px 0 0;
}
.fl-orb.fl-basket .pet { position: absolute; width: 4.5px; height: 4.5px; border-radius: 50%; animation: petBob 1.7s ease-in-out infinite; }
.fl-orb.fl-basket .p1 { left: 3px; top: 2px; background: #ff9ec4; box-shadow: 0 0 5px #ff9ec4; }
.fl-orb.fl-basket .p2 { left: 8.5px; top: -3px; background: #ffe07a; box-shadow: 0 0 5px #ffe07a; animation-delay: -.55s; }
.fl-orb.fl-basket .p3 { left: 14px; top: 2px; background: #9ed8ff; box-shadow: 0 0 5px #9ed8ff; animation-delay: -1.1s; }
@keyframes petBob { 0%,100% { transform: translateY(0); opacity: .82; } 50% { transform: translateY(-3px); opacity: 1; } }
/* 公转一周（绕躯干，半径 36px）；token 反向自转保持竖直（经典轨道法）。
 * z-index 分段：前半弧(0~50%，右→下→左)在身前 z8；后半弧(50~100%，左→上→右)钻到立绘身后 z-1=遮挡 */
@keyframes flOrbit {
  0%   { transform: rotate(0deg) translateX(36px) rotate(0deg); z-index: 8; }
  50%  { transform: rotate(180deg) translateX(36px) rotate(-180deg); z-index: 8; }
  50.01% { z-index: -1; }
  100% { transform: rotate(360deg) translateX(36px) rotate(-360deg); z-index: -1; }
}

/* 终结一击：慢放灰化 + 水墨溅散 */
.axis-unit.slaying .au-img, .axis-unit.slaying .au-glyph {
  animation: slayFade 1.2s ease forwards !important;
}
@keyframes slayFade {
  0% { filter: grayscale(0) brightness(1.3); transform: scale(1.05); }
  35% { filter: grayscale(.6) brightness(1.05); transform: scale(1.01); }
  /* S1 死亡演出：身形一沉一倾——"倒下去"而不只是"变灰"（水墨溅散叠其上） */
  70% { filter: grayscale(.85) brightness(.7); transform: translateY(5px) rotate(2.5deg) scale(.98); }
  100% { filter: grayscale(1) brightness(.4) blur(1.5px); transform: translateY(11px) rotate(5deg) scale(.94); opacity: .3; }
}
.ink-burst { position: absolute; left: 50%; top: 40%; pointer-events: none; z-index: 8; }
.ink-burst i {
  position: absolute; width: 9px; height: 9px; border-radius: 50% 60% 50% 65%;
  background: rgba(20,14,10,.85); box-shadow: 0 0 6px rgba(0,0,0,.6);
  animation: inkFly 1.1s cubic-bezier(.2,.7,.4,1) forwards;
}
.ink-burst i:nth-child(1) { --dx: -46px; --dy: -38px; }
.ink-burst i:nth-child(2) { --dx: 42px;  --dy: -52px; animation-delay: .04s; }
.ink-burst i:nth-child(3) { --dx: -60px; --dy: 6px;  animation-delay: .08s; }
.ink-burst i:nth-child(4) { --dx: 56px;  --dy: -8px; animation-delay: .05s; }
.ink-burst i:nth-child(5) { --dx: -24px; --dy: -64px; animation-delay: .1s; }
.ink-burst i:nth-child(6) { --dx: 20px;  --dy: 30px; animation-delay: .07s; }
@keyframes inkFly {
  0% { transform: translate(0, 0) scale(1); opacity: .95; }
  100% { transform: translate(var(--dx), var(--dy)) scale(.3); opacity: 0; }
}

/* 全局重演出：趁虚时停金字 / 蓄势释放大字压屏 */
.fx-global {
  position: absolute; inset: 0; z-index: 30; pointer-events: none;
  display: flex; align-items: center; justify-content: center;
}
.fx-global.fxg-exploit { background: rgba(8,5,3,.42); animation: fxgIn .12s ease; }
.fx-global.fxg-exploit .fxg-text {
  font-family: var(--font-title, serif); font-size: clamp(34px, 7vw, 60px); font-weight: 700;
  color: var(--gold-bright); letter-spacing: 10px; text-shadow: 0 0 28px rgba(236,217,168,.8), 0 3px 10px rgba(0,0,0,.9);
  animation: exploitPop .85s cubic-bezier(.2,1.4,.4,1) forwards;
}
@keyframes exploitPop {
  0% { transform: scale(2.2); opacity: 0; }
  18% { transform: scale(1); opacity: 1; }
  80% { transform: scale(1.02); opacity: 1; }
  100% { transform: scale(1.05); opacity: 0; }
}
.fx-global.fxg-ult { background: rgba(4,3,2,.7); animation: ultFlash 1.2s ease forwards; }
.fx-global.fxg-ult .fxg-text {
  writing-mode: vertical-rl; font-family: var(--font-title, serif);
  font-size: clamp(44px, 9vw, 80px); font-weight: 700; color: #f4e8cc;
  letter-spacing: 18px; text-shadow: 0 0 36px rgba(236,217,168,.9), 0 0 80px rgba(201,169,106,.5);
  animation: ultText 1.2s ease forwards;
}
@keyframes ultFlash { 0% { background: rgba(244,238,224,.85); } 12% { background: rgba(4,3,2,.7); } 100% { background: rgba(4,3,2,.62); } }
@keyframes ultText {
  0% { transform: scale(1.3); opacity: 0; filter: blur(5px); }
  16% { transform: scale(1); opacity: 1; filter: blur(0); }
  85% { opacity: 1; }
  100% { opacity: 0; }
}
@keyframes fxgIn { from { opacity: 0; } to { opacity: 1; } }

/* 瞬发牌横滑排（手机原生手势，不挤不收纳） */
.quick-row {
  display: flex; align-items: stretch; gap: 5px; margin-bottom: 5px;
  overflow-x: auto; padding: 4px 1px 2px; -webkit-overflow-scrolling: touch;
  border-top: 1px dashed rgba(181, 72, 61, .4);
  scrollbar-width: none;   /* 划得动但不见滚条（手机手势原生） */
}
.quick-row::-webkit-scrollbar { display: none; }
.quick-row:empty { display: none; }
.quick-row .spell-btn { flex: 0 0 116px; min-width: 116px; padding: 1px 3px; gap: 3px; font-size: 11px; border-radius: 6px; }
.quick-row .seal { width: 19px; height: 19px; font-size: 11px; border-width: 1px; border-radius: 2px; }
.quick-row .sname { font-size: 11px; letter-spacing: .3px; }
.quick-row .scost { font-size: 9px; gap: 2px; }
.quick-row .cost-dot { padding: 0 3px; font-size: 9px; line-height: 13px; border-radius: 2px; }
.quick-row .trump-tag { flex-shrink: 0; }
/* 灵傀卡：侧位单位的随身牌（血/简令）——点一下换简令：随→攻→守→撤 */
.pet-card {
  flex: 0 0 112px; min-width: 112px; display: flex; align-items: center; gap: 4px;
  padding: 2px 4px; border-radius: 6px; cursor: pointer; font-family: inherit;
  background: rgba(150, 190, 160, .05); border: 1px solid rgba(150, 190, 160, .3); color: var(--ink);
}
.pet-card:hover { border-color: var(--jade); }
.pet-card .seal { width: 20px; height: 20px; font-size: 11.5px; border-width: 1px; color: #a9c7b2; border-color: rgba(150,190,160,.5); position: relative; }
/* 堆叠章（傀儡×2×3）：同类侧位聚合一张卡，数量挂印章右下角 */
.pet-card .pc-stack {
  position: absolute; right: -7px; bottom: -5px; font-style: normal; font-size: 9px;
  padding: 0 3px; border-radius: 5px; background: #2c2317; border: 1px solid rgba(214,178,108,.55);
  color: var(--gold); line-height: 1.3;
}
/* 形态章（灵虫：化枪/附体/分身——点击轮换） */
.pet-card .pc-form {
  flex-shrink: 0; font-size: 10px; padding: 1px 5px; border-radius: 4px; cursor: pointer;
  background: rgba(160, 130, 220, .12); border: 1px solid rgba(160, 130, 220, .4); color: #c9b8ea;
}
.pet-card .pc-form:hover { border-color: #c9b8ea; }
/* 助战独立栏（v96 用户裁决）：与瞬发分行——后面傀儡灵虫都进这一栏 */
.pet-row { border-top: 1px dashed rgba(150, 190, 160, .2); padding-top: 3px; }
/* 悬浮法宝卡（三位制·祭出位）：运转中=金边呼吸 */
.spell-btn.floating {
  border-color: rgba(214, 178, 108, .75);
  animation: floatGlow 2.2s ease-in-out infinite;
}
@keyframes floatGlow {
  0%, 100% { box-shadow: 0 0 4px rgba(214,178,108,.25), inset 0 0 10px rgba(214,178,108,.08); }
  50% { box-shadow: 0 0 12px rgba(214,178,108,.5), inset 0 0 16px rgba(214,178,108,.16); }
}
.role-tag.rt-float { background: #4a3a18; color: #ecd9a4; border-color: rgba(214,178,108,.6); }
/* 法术 6 格满员提示（出战上限 6——洞府编排取舍） */
.zone-overflow {
  align-self: center; font-size: 10px; color: var(--ink-dim); padding: 0 6px;
  border: 1px dashed rgba(150,150,150,.3); border-radius: 4px; white-space: nowrap;
}
/* 特色资源章（神雷等）：雷紫描边——打一道少一道 */
.act-chip.charge { border-color: rgba(168, 142, 230, .55); color: #c9b8ea; }
.act-chip.charge.used { opacity: .45; }
/* 伴身法宝印鉴（三类法宝制：被动件）——窄条小印，效果常驻不可点 */
.side-seal {
  display: inline-flex; flex-direction: column; align-items: center; gap: 1px;
  padding: 2px 4px; border-radius: 5px; align-self: center;
  background: rgba(214, 178, 108, .05); border: 1px solid rgba(214, 178, 108, .26);
}
.side-seal .seal {
  width: 18px; height: 18px; font-size: 10.5px; font-style: normal;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid rgba(214,178,108,.45); border-radius: 4px; color: #e3cf9b;
}
.side-seal b { font-size: 8.5px; font-weight: 400; color: var(--ink-dim); white-space: nowrap; letter-spacing: 0; }
.pet-card .pc-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.pet-card .pc-name { font-size: 11px; color: #cfe0d2; letter-spacing: .3px; white-space: nowrap; overflow: hidden; }
.pet-card .pc-hp { height: 4px; border-radius: 2px; background: rgba(0,0,0,.5); overflow: hidden; }
.pet-card .pc-hp i { display: block; height: 100%; background: linear-gradient(90deg, #5e9e7c, #8fc7a5); }
/* 同道灵力微条（同规则可读性：她也有池、也会被耗蓝——消耗战看得见） */
.pet-card .pc-mp { height: 3px; border-radius: 2px; background: rgba(0,0,0,.5); overflow: hidden; margin-top: 1px; }
.pet-card .pc-mp i { display: block; height: 100%; background: linear-gradient(90deg, #3f6c96, #6f9fc8); }
.pet-card .pc-st {
  flex-shrink: 0; font-size: 11px; font-weight: 700; width: 22px; height: 22px; line-height: 20px;
  text-align: center; border-radius: 50%; border: 1px solid rgba(150,190,160,.5); color: #a9c7b2;
  background: rgba(10,8,6,.5);
}
.pet-card.down { opacity: .45; filter: grayscale(.7); cursor: default; }

/* 脚下血条/法力微条 + 名牌 */
.axis-unit .au-bars { width: 86%; margin-top: 2px; }
.au-hp, .au-mp { position: relative; height: 5px; border-radius: 3px; overflow: hidden; background: rgba(8,6,4,.78); border: 1px solid rgba(140,120,90,.35); margin-bottom: 2px; }
.au-hp i { display: block; height: 100%; background: linear-gradient(90deg,#7c3a32,var(--red)); transition: width .3s; }
.axis-unit.self .au-hp i, .axis-unit.side .au-hp i { background: linear-gradient(90deg,#2c5d4a,var(--jade-bright)); }
.au-hp i.sh { position: absolute; top: 0; left: 0; opacity: .55; background: linear-gradient(90deg,#3a5a7a,var(--blue)); }
.au-mp { height: 4px; }
.au-mp i { display: block; height: 100%; background: linear-gradient(90deg,#3a5a8a,#7fb8e8); transition: width .3s; }
.axis-unit .au-name {
  font-size: 11px; color: #d8cdb8; margin-top: 2px; white-space: nowrap;
  text-shadow: 0 1px 4px rgba(0,0,0,.9); letter-spacing: .5px;
}
.au-lock { color: var(--red); margin-left: 2px; }

/* 头顶徽记：意图气泡 + 状态标 */
.axis-unit .au-badges {
  position: absolute; top: -22px; left: 50%; transform: translateX(-50%);
  display: flex; gap: 4px; white-space: nowrap; z-index: 3;
}
.au-intent {
  width: 22px; height: 22px; border-radius: 50% 50% 50% 4px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 700; color: #f0e2c8;
  background: rgba(26,18,12,.92); border: 1px solid rgba(201,169,106,.55);
  box-shadow: 0 2px 8px rgba(0,0,0,.6);
  animation: intentBob 1.4s ease-in-out infinite;
}
@keyframes intentBob { 0%,100% { translate: 0 0; } 50% { translate: 0 -3px; } }
.au-intent.ik-charge, .au-intent.ik-release { border-color: rgba(232,150,90,.8); color: #f0c090; }
.au-intent.ik-flee { border-color: rgba(160,200,150,.7); color: #b8e0a8; }
.au-intent.ik-guard { border-color: rgba(111,159,200,.8); color: #a8cce8; }
.au-mark {
  font-size: 10px; padding: 1px 5px; border-radius: 4px; letter-spacing: 1px;
  background: rgba(26,18,12,.9); border: 1px solid rgba(140,120,90,.5); color: #cfc2a8;
}
.au-mark.mk-whiff { border-color: rgba(236,217,168,.8); color: var(--gold-bright); animation: whiffFlash .5s ease-in-out infinite alternate; }
@keyframes whiffFlash { from { box-shadow: 0 0 4px rgba(236,217,168,.3); } to { box-shadow: 0 0 12px rgba(236,217,168,.7); } }
.au-mark.mk-expose { border-color: rgba(201,95,80,.7); color: #e8a090; }
.au-mark.mk-charge { border-color: rgba(232,198,106,.7); color: #e8c66a; }
.au-mark.mk-poison { border-color: rgba(126,185,100,.6); color: #93d67f; }
.au-mark.mk-hold { border-color: rgba(111,159,200,.7); color: #a8cce8; }
/* 同道简令章（A2 v0）：头顶一字令——点章即换令（与灵傀卡同源） */
.au-mark.mk-stance { border-color: rgba(150,190,160,.65); color: #a9c7b2; cursor: pointer; pointer-events: auto; }
.au-mark.mk-stance:hover { box-shadow: 0 0 8px rgba(150,190,160,.45); }

/* 御使飞行印：法器划过战场 */
.fly-seal {
  position: absolute; z-index: 6; width: 30px; height: 30px; margin: -15px 0 0 -15px;
  display: flex; align-items: center; justify-content: center;
  font-size: 15px; font-weight: 700; border-radius: 6px; rotate: 45deg;
  background: rgba(20,15,10,.9); border: 1px solid currentColor;
  box-shadow: 0 0 14px currentColor; pointer-events: none;
  transition: left .42s cubic-bezier(.5,0,.8,.4), top .42s cubic-bezier(.5,0,.8,.4), opacity .42s;
}
.fly-seal.wx-jin { color: var(--wx-jin); } .fly-seal.wx-mu { color: var(--wx-mu); }
.fly-seal.wx-shui { color: var(--wx-shui); } .fly-seal.wx-huo { color: var(--wx-huo); }
.fly-seal.wx-tu { color: var(--wx-tu); }
.fly-seal.gone { opacity: .15; }

/* 神识料敌提示条 */
.combat-intent {
  flex-shrink: 0; margin-bottom: 8px; padding: 7px 12px;
  font-size: 12px; line-height: 1.6; color: var(--gold-bright);
  background: rgba(14,11,8,.85); border: 1px solid rgba(201,169,106,.4); border-radius: var(--radius);
  backdrop-filter: blur(3px);
}

/* 真颠倒五行阵·手动相位选择条 */
.combat-fieldcycle {
  flex-shrink: 0; margin-bottom: 8px; padding: 6px 10px;
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  background: rgba(14,11,8,.85); border: 1px solid rgba(100,180,120,.35); border-radius: var(--radius);
  backdrop-filter: blur(3px);
}
.combat-fieldcycle .zt-field { color: #6bb878; border-color: rgba(100,180,120,.3); }
.fc-phase {
  display: inline-flex; align-items: center; gap: 4px; padding: 4px 8px;
  font-size: 11px; color: #c8e0d0; background: rgba(20,40,28,.7);
  border: 1px solid rgba(100,180,120,.3); border-radius: 4px; cursor: pointer; transition: all .2s;
}
.fc-phase:hover:not(:disabled) { background: rgba(40,80,50,.8); border-color: rgba(100,200,130,.6); box-shadow: 0 0 6px rgba(100,200,130,.3); }
.fc-phase:disabled { opacity: .4; cursor: default; }
.fc-phase.used { opacity: .25; text-decoration: line-through; }
.fc-phase.dim { opacity: .5; }
.fc-seal { font-style: normal; font-size: 14px; color: #8fcaa0; }
.fc-name { white-space: nowrap; }
.fc-tag { font-style: normal; font-size: 10px; opacity: .6; }

/* 法力池行：横条 + 行动经济筹码 */
.combat-mprow { display: flex; align-items: center; gap: 12px; margin-bottom: 6px; flex-wrap: wrap; }
.mp-pool { display: flex; align-items: center; gap: 8px; flex: 1; min-width: 200px; }
.mp-label { font-size: 12px; color: #9fb8d8; letter-spacing: 2px; }
.mp-bar {
  flex: 1; height: 12px; border-radius: 6px; overflow: hidden;
  background: rgba(8,6,4,.8); border: 1px solid rgba(90,110,140,.4);
  box-shadow: inset 0 1px 4px rgba(0,0,0,.6);
}
.mp-bar i { display: block; height: 100%; background: linear-gradient(90deg,#2a4a72,#6f9fc8); transition: width .35s ease; box-shadow: 0 0 8px rgba(111,159,200,.5); }
.mp-num { font-size: 12.5px; color: #a8c4e0; min-width: 56px; text-align: right; }
.act-chips { display: flex; gap: 6px; flex-wrap: wrap; }
.act-chip {
  font-size: 11px; padding: 3px 8px; border-radius: 10px; letter-spacing: 1px;
  color: var(--gold-bright); background: rgba(36,28,18,.7); border: 1px solid rgba(201,169,106,.4);
}
.act-chip.used { opacity: .35; }
.act-chip.momentum { color: #f0d8a0; border-color: rgba(236,217,168,.7); box-shadow: 0 0 8px rgba(236,217,168,.25); }

/* 技能射程 badge / 法力耗标 */
.sname .srange {
  font-size: 10px; color: var(--ink-dim); border: 1px solid rgba(140,120,90,.35);
  padding: 0 4px; border-radius: 4px; margin-left: 5px; vertical-align: 1px; letter-spacing: 0;
}
.cost-dot.mp-dot { color: #a8c4e0; border-color: rgba(111,159,200,.45); background: rgba(30,46,66,.4); }

/* 操作台：半透明墨底（v103 L5：上下极紧凑——回合结束与手牌同屏不滚动）。
 * v107：场景锁死后，操作台是战斗里唯一允许的滚动区——内容超高时只在它内部滚，
 * 场景与背景永不脱节；overscroll-behavior:contain 防滚动链传到外层。 */
.combat-console {
  background: var(--paper); border: 1px solid var(--border-soft); border-radius: var(--radius-lg);
  padding: 9px 10px; backdrop-filter: blur(6px);
  flex: 0 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; scrollbar-width: none;
}
.combat-console::-webkit-scrollbar { width: 0; height: 0; }

/* 五行灵气珠池 */
.combat-qi { display: flex; gap: 12px; justify-content: center; margin-bottom: 12px; flex-wrap: wrap; }
.qi-orb {
  position: relative; width: 46px; height: 46px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--border); transition: all .25s ease;
  background: radial-gradient(circle at 38% 30%, rgba(255,255,255,.14), rgba(12,10,8,.92) 72%);
}
.qi-orb .qo-char { font-size: 17px; font-weight: 700; line-height: 1; }
.qi-orb .qo-n {
  position: absolute; right: -4px; bottom: -4px; min-width: 18px; height: 18px;
  display: flex; align-items: center; justify-content: center;
  font-size: 11.5px; border-radius: 9px; padding: 0 4px;
  background: rgba(10,8,6,.92); border: 1px solid var(--border);
}
.qi-orb.zero { opacity: .32; }
.qi-orb.zero .qo-char { color: var(--ink-faint); }
.qi-orb.lit.jin  { border-color: var(--wx-jin);  box-shadow: 0 0 13px rgba(216,198,144,.4); }
.qi-orb.lit.jin .qo-char { color: var(--wx-jin); }
.qi-orb.lit.mu   { border-color: var(--wx-mu);   box-shadow: 0 0 13px rgba(126,185,142,.4); }
.qi-orb.lit.mu .qo-char { color: var(--wx-mu); }
.qi-orb.lit.shui { border-color: var(--wx-shui); box-shadow: 0 0 13px rgba(111,159,200,.4); }
.qi-orb.lit.shui .qo-char { color: var(--wx-shui); }
.qi-orb.lit.huo  { border-color: var(--wx-huo);  box-shadow: 0 0 13px rgba(201,111,95,.4); }
.qi-orb.lit.huo .qo-char { color: var(--wx-huo); }
.qi-orb.lit.tu   { border-color: var(--wx-tu);   box-shadow: 0 0 13px rgba(194,163,107,.4); }
.qi-orb.lit.tu .qo-char { color: var(--wx-tu); }
.qi-orb.momentum { border-color: var(--gold-bright); box-shadow: 0 0 15px rgba(236,217,168,.5); }
.qi-orb.momentum .qo-char { color: var(--gold-bright); }

/* 招式按钮：印章 + 名 + 消耗 */
/* 手牌：紧凑双排同滑网格（一次手势两排齐动）——四区制：法宝法器｜法术｜瞬发｜灵傀。
 * 单屏铁律：格子小而密、字贴框，划的是排内，页面永不竖涨 */
.combat-spells { display: flex; flex-direction: column; gap: 4px; margin-bottom: 4px; }
.spell-grid {
  display: grid; grid-auto-flow: column; grid-template-rows: repeat(2, minmax(0, 1fr));
  gap: 3px 4px; overflow-x: auto; padding: 1px 1px 2px;
  -webkit-overflow-scrolling: touch; scrollbar-width: none;
  align-items: center;
}
/* 法宝行/法术行列对齐（v98 用户裁决"法术和法宝行对齐"）：同 padding-left、
 * zone-tag 同宽——两行的首格从同一条竖线起步，视觉成"列" */
.spell-grid .zone-tag { width: 14px; min-width: 14px; }
.spell-grid::-webkit-scrollbar { display: none; }
/* 硬紧凑（用户两次催）：字贴框、章贴字——一屏摆下更多牌 */
.spell-grid .spell-btn { width: 110px; min-width: 110px; padding: 1px 3px; gap: 3px; font-size: 11px; border-radius: 6px; }
.spell-grid .seal { width: 19px; height: 19px; font-size: 11px; border-width: 1px; border-radius: 2px; }
.spell-grid .sname { font-size: 11px; line-height: 1.15; letter-spacing: .3px; }
.spell-grid .scost { font-size: 9px; line-height: 1.2; gap: 2px; }
.spell-grid .cost-dot { padding: 0 3px; font-size: 9px; line-height: 13px; border-radius: 2px; }
.spell-grid .sname .srange { font-size: 9px; padding: 0 2px; margin-left: 2px; border-radius: 3px; }
.spell-grid .sp-body { gap: 0; }
/* 法宝牌大一号：以后战斗的重点是法宝区（用户裁决）——physically 比法术牌醒目 */
.spell-grid .spell-btn.treasure { width: 126px; min-width: 126px; padding: 2px 4px; }
.spell-grid .spell-btn.treasure .seal { width: 23px; height: 23px; font-size: 12.5px; }
/* 法宝行独排（v97 用户裁决：法宝一排、法术正下方一排）——单行横滑 */
.spell-grid.treasure-row { grid-template-rows: repeat(1, minmax(0, 1fr)); }
/* 本命法宝列（v98）：神雷条 + 主攻卡竖向堆叠成一格——整体占位等同一张法宝卡。
 * 神雷=青竹蜂云剑所蕴的手段，故贴在本命卡头顶；主攻卡 .compact 内排缩一档让出条位 */
.treasure-main { display: flex; flex-direction: column; gap: 2px; align-self: stretch; justify-content: center; }
.treasure-main .spell-btn.treasure.compact { width: 132px; min-width: 132px; padding: 1px 4px; }
.treasure-main .spell-btn.treasure.compact .seal { width: 20px; height: 20px; font-size: 11px; }
.treasure-main .spell-btn.treasure.compact .sname { font-size: 11px; }
.treasure-main .spell-btn.treasure.compact .scost { font-size: 8.5px; }
/* 辟邪神雷三选条（金雷紫纹·点选生效：劈/附/遁——不占格，贴本命卡头顶） */
.shenlei-strip {
  display: flex; align-items: center; gap: 3px; width: 132px; min-width: 132px;
  padding: 1px 4px; border-radius: 5px; cursor: default;
  background: linear-gradient(135deg, rgba(214,178,108,.16), rgba(120,90,40,.08));
  border: 1px solid rgba(226,194,119,.55);
}
.shenlei-strip.off { opacity: .42; }
.shenlei-strip .sl-name { font-size: 9px; color: #ecd9a4; white-space: nowrap; line-height: 1.1; flex: 1; min-width: 0; overflow: hidden; }
.shenlei-strip .sl-name b { color: #ffd970; font-weight: 700; }
.shenlei-strip .sl-opt {
  width: 18px; height: 18px; border-radius: 4px; font-style: normal; font-size: 11px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center; cursor: pointer;
  background: rgba(226,194,119,.16); border: 1px solid rgba(226,194,119,.6); color: #f2dfae;
  transition: all .15s;
}
.shenlei-strip .sl-opt:hover { background: rgba(226,194,119,.34); box-shadow: 0 0 8px rgba(226,194,119,.55); }
.shenlei-strip .sl-opt.off { opacity: .3; cursor: not-allowed; }
.spell-grid .spell-btn.treasure .sname { font-size: 12px; }


/* ===== 法宝排版（v103 用户裁决 L1/L2）：左详细(主攻/主防) + 右图标(特效型/悬浮，两排) ===== */
.arsenal { display: flex; align-items: stretch; gap: 6px; }
.arsenal-main { display: flex; align-items: stretch; gap: 4px; flex: 0 0 auto; }
.arsenal-main .tre-col { display: flex; flex-direction: column; gap: 3px; justify-content: center; }
/* 右侧法宝图标：定两排、按列铺开（数量多则排内横滑，绝不竖涨撑爆 UI——L2"分两排平均分布"） */
.arsenal-side {
  flex: 1 1 auto; min-width: 0; display: grid;
  grid-auto-flow: column; grid-template-rows: repeat(2, 1fr);
  gap: 4px; align-content: center; justify-content: start;
  overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none; padding: 1px;
}
.arsenal-side::-webkit-scrollbar { display: none; }
.tre-icon {
  position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center;
  width: 52px; min-width: 52px; height: 37px; gap: 1px; padding: 2px 3px;
  border-radius: 6px; cursor: pointer; font-family: inherit; color: #f2dfae;
  border: 1px solid rgba(226,194,119,.5);
  background: linear-gradient(180deg, rgba(226,194,119,.1), rgba(226,194,119,.03));
  box-shadow: inset 0 0 10px rgba(226,194,119,.06); transition: all .15s;
}
.tre-icon .seal { width: 19px; height: 19px; font-size: 11px; border-width: 1px; border-radius: 2px; box-shadow: 0 0 8px rgba(226,194,119,.45); font-style: normal; }
.tre-icon .ti-name { font-size: 8.5px; line-height: 1; max-width: 48px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; letter-spacing: 0; }
.tre-icon .ti-tag {
  position: absolute; top: -4px; right: -3px; z-index: 2; font-style: normal;
  width: 13px; height: 13px; line-height: 13px; text-align: center; font-size: 8.5px; font-weight: 700; border-radius: 3px; rotate: 6deg;
}
.tre-icon .ti-tag.atk { color: #2a1f10; background: linear-gradient(160deg, #f0dca0, #cfae62); }
.tre-icon .ti-tag.def { color: #cfe2f0; background: linear-gradient(160deg, #2c4a66, #1b2e42); border: 1px solid rgba(111,159,200,.55); }
.tre-icon .ti-tag.float { color: #2a1f10; background: linear-gradient(160deg, #bfe0ff, #79a8e0); }
.tre-icon:hover:not(:disabled) { border-color: #e2c277; box-shadow: 0 0 12px rgba(226,194,119,.3); }
.tre-icon.off { filter: grayscale(.6); opacity: .5; cursor: not-allowed; }
.tre-icon.armed { border-color: var(--gold-bright); box-shadow: 0 0 13px rgba(236,217,168,.6); }
.tre-icon.floating { border-color: var(--gold-bright); box-shadow: 0 0 11px rgba(236,217,168,.5); animation: floatGlow 2.2s ease-in-out infinite; }
/* 法术锁死 8（L4）：4 列 × 2 排定格对齐——列宽均分、绝不横滑 */
.spell-grid.spell8 { grid-template-columns: 14px repeat(4, minmax(0, 1fr)); grid-auto-flow: column; overflow-x: visible; }
.spell-grid.spell8 .spell-btn { width: auto; min-width: 0; }
.zone-tag {
  writing-mode: vertical-rl; text-orientation: upright; flex-shrink: 0;
  font-size: 10px; letter-spacing: 1px; color: var(--ink-faint);
  display: flex; align-items: center; padding: 0;
}
/* 网格内分区标签：竖排两行通占——同一条滑轨里把"法宝/法术"切开 */
.spell-grid .zone-tag { grid-row: 1 / span 2; align-self: stretch; justify-content: center; }
.zone-tag.zt-treasure { color: #e2c277; }
.zone-tag.zt-quick { color: var(--cinnabar); }
.zone-tag.zt-pet { color: #a9c7b2; }
/* 法宝牌：鎏金缘+内灼灵光——催动的是"物"，战斗的重心所在（用户裁决：法宝区为重） */
.spell-btn.treasure {
  border-color: rgba(226, 194, 119, .55);
  background: linear-gradient(180deg, rgba(226, 194, 119, .1), rgba(226, 194, 119, .03));
  box-shadow: inset 0 0 14px rgba(226, 194, 119, .08), 0 0 6px rgba(226, 194, 119, .12);
}
.spell-btn.treasure:hover:not(:disabled) { border-color: #e2c277; background: rgba(226, 194, 119, .14); box-shadow: 0 0 14px rgba(226, 194, 119, .28); }
.spell-btn.treasure .seal { box-shadow: 0 0 10px rgba(226, 194, 119, .55); border-color: rgba(226, 194, 119, .7); }
.spell-btn.treasure .sname { color: #f2dfae; }
.spell-btn {
  position: relative;
  display: flex; align-items: center; gap: 9px; text-align: left; padding: 8px 10px;
  background: rgba(255, 250, 240, 0.03); border: 1px solid var(--border); border-radius: var(--radius-lg);
  cursor: pointer; color: var(--ink); font-family: inherit; font-size: 13px; transition: all .15s;
}
/* 主攻/防御角章（法宝区主次之分）：主=鎏金，御=玄青 */
.spell-btn .role-tag {
  position: absolute; top: -5px; right: -4px; z-index: 2;
  width: 15px; height: 15px; line-height: 15px; text-align: center;
  font-size: 9.5px; font-weight: 700; border-radius: 3px; rotate: 6deg;
}
.spell-btn .role-tag.rt-main { color: #2a1f10; background: linear-gradient(160deg, #f0dca0, #cfae62); box-shadow: 0 0 7px rgba(226,194,119,.7); }
.spell-btn .role-tag.rt-def { color: #cfe2f0; background: linear-gradient(160deg, #2c4a66, #1b2e42); border: 1px solid rgba(111,159,200,.55); }
/* 客随统帅卡（mastery≥2 同道）：金边压字——她不受令，她点将 */
.pet-card.lead { border-color: rgba(226,194,119,.55); background: rgba(226,194,119,.06); cursor: help; }
.pet-card.lead .pc-st { color: #f0dca0; border-color: rgba(226,194,119,.7); box-shadow: 0 0 7px rgba(226,194,119,.4); }
.au-mark.mk-lead { border-color: rgba(226,194,119,.75); color: #f0dca0; cursor: default; box-shadow: 0 0 7px rgba(226,194,119,.35); }
.spell-btn:hover:not(:disabled) { border-color: var(--jade); background: rgba(111,174,147,.08); }
.spell-btn:disabled { opacity: .35; cursor: not-allowed; }
.spell-btn.off { filter: grayscale(.6); }
.spell-btn .sp-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.spell-btn .sname { color: #e6dfcf; letter-spacing: 1px; }
.spell-btn .scost { display: flex; align-items: center; flex-wrap: wrap; gap: 4px; color: var(--ink-dim); font-size: 11px; }
.cost-dot {
  display: inline-block; padding: 0 5px; border-radius: 3px; font-size: 10.5px; line-height: 16px;
  border: 1px solid var(--border); background: rgba(10,8,6,.55);
}
.cost-dot.wx-jin { color: var(--wx-jin); border-color: rgba(216,198,144,.45); }
.cost-dot.wx-mu { color: var(--wx-mu); border-color: rgba(126,185,142,.45); }
.cost-dot.wx-shui { color: var(--wx-shui); border-color: rgba(111,159,200,.45); }
.cost-dot.wx-huo { color: var(--wx-huo); border-color: rgba(201,111,95,.45); }
.cost-dot.wx-tu { color: var(--wx-tu); border-color: rgba(194,163,107,.45); }
.cost-dot.free { color: var(--ink-faint); }
.spell-btn .spouch { color: var(--jade-bright); }
.spell-btn .spouch.empty { color: var(--red); font-size: 9px; white-space: nowrap; }

/* 底牌/瞬发行：消耗性手段独立分区（符/丹/阵旗——与灵技体系分离，多牌自动换行） */
.trump-row {
  grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: stretch; gap: 8px;
  padding-top: 8px; border-top: 1px dashed rgba(181, 72, 61, .4);
}
.trump-row .spell-btn { flex: 1 1 150px; min-width: 150px; max-width: 100%; }
.trump-tag {
  writing-mode: vertical-rl; text-orientation: upright; flex-shrink: 0;
  font-size: 11px; letter-spacing: 2px; color: var(--cinnabar);
  display: flex; align-items: center; padding: 0 1px;
}
.spell-btn.trump { flex: 1 1 150px; min-width: 150px; max-width: 100%; border-color: rgba(181, 72, 61, .35); background: rgba(181, 72, 61, .05); }
.spell-btn.trump:hover:not(:disabled) { border-color: var(--cinnabar); background: rgba(181,72,61,.12); }

/* 战录框：占位加大+排版（用户裁决）——行有呼吸、新旧有别、色有语义 */
.combat-log {
  height: 152px; overflow-y: auto; background: rgba(8,6,4,.56); border: 1px solid var(--border-soft);
  border-radius: var(--radius); padding: 10px 13px; font-size: 13px; color: var(--ink-dim);
  line-height: 1.7; margin-bottom: 10px; scrollbar-width: thin;
}
.combat-log > div { padding: 1.5px 0; border-bottom: 1px dashed rgba(140, 120, 90, .1); }
.combat-log > div:last-child { border-bottom: none; }
.combat-log .cl-hit { color: var(--jade-bright); }
.combat-log .cl-hurt { color: var(--red); }
.combat-log .cl-new { color: var(--ink); }
/* 行动排：定高一行排齐——次按钮收紧、主按钮吃满余宽（多按钮并存也不爆版） */
.combat-actions { display: flex; justify-content: center; align-items: center; gap: 8px; }
.combat-actions .btn { width: auto; min-width: 0; margin-top: 0; height: 46px; padding: 0 18px; }
.combat-actions .btn-primary { flex: 1 1 auto; max-width: 380px; }
.combat-actions .btn-mini { flex: 0 0 auto; font-size: 13px; }

/* 受击/施法时的轻微震动反馈 */
@keyframes hitshake { 0%,100%{transform:translateX(0)} 25%{transform:translateX(-3px)} 75%{transform:translateX(3px)} }
.combatant.shake { animation: hitshake .25s; }

/* 印章图标：方章 + 单字（功法/法术/物品统一图标语言）*/
.seal {
  flex-shrink: 0; width: 34px; height: 34px; border-radius: 3px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 18px; font-weight: 700; line-height: 1;
  background: rgba(10,8,6,.6); border: 1.5px solid var(--border);
  box-shadow: inset 0 0 8px rgba(0,0,0,.5);
}
.seal.wx-jin { color: var(--wx-jin); border-color: rgba(216,198,144,.6); }
.seal.wx-mu { color: var(--wx-mu); border-color: rgba(126,185,142,.6); }
.seal.wx-shui { color: var(--wx-shui); border-color: rgba(111,159,200,.6); }
.seal.wx-huo { color: var(--wx-huo); border-color: rgba(201,111,95,.6); }
.seal.wx-tu { color: var(--wx-tu); border-color: rgba(194,163,107,.6); }
.seal.cinnabar { color: #eac8bb; border-color: var(--cinnabar); background: rgba(181,72,61,.2); }
.seal.sm { width: 26px; height: 26px; font-size: 14px; border-width: 1px; }

/* ===== 属性悬浮说明 ===== */
.stat-row { position: relative; cursor: default; }
.stat-row[data-tip]:hover::after {
  content: attr(data-tip);
  position: absolute; left: 0; top: 100%; z-index: 50;
  width: 210px; padding: 8px 10px; margin-top: 2px;
  background: #11151c; border: 1px solid var(--jade); border-radius: 6px;
  color: var(--ink); font-size: 12px; line-height: 1.5; letter-spacing: 0;
  box-shadow: 0 8px 24px var(--shadow); pointer-events: none;
}

/* ===== 开场创建 · 打磨 ===== */
.sr-result { transition: color .2s, text-shadow .2s; }
.sr-result.rolling { animation: srpulse .5s infinite; }
@keyframes srpulse { 0%,100%{ opacity: 1 } 50%{ opacity: .5 } }
/* 测灵根·揭示仪式（审美审计 jank#3）：定数落下的那一拍——放大定格+金芒扫过 */
.sr-result.revealed { animation: srReveal .65s cubic-bezier(.22, 1, .36, 1); }
@keyframes srReveal {
  0%   { transform: scale(1.7); filter: blur(4px) brightness(2.2); opacity: 0; }
  45%  { transform: scale(1.12); filter: blur(0) brightness(1.5); opacity: 1; }
  100% { transform: scale(1); filter: none; opacity: 1; }
}
/* 「踏入此界」就绪脉冲：测完灵根，下一步会呼吸（一次性引导，不常驻打扰） */
.btn-primary.ready-pulse { animation: readyPulse 1.6s ease-in-out 2; }
@keyframes readyPulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(201, 169, 106, 0); }
  50%      { box-shadow: 0 0 18px 2px rgba(201, 169, 106, .45); }
}
.create-box { animation: fadein .5s ease; }
.create-title-block { animation: fadein .8s ease; }

/* ===== 奇遇弹窗 ===== */
.fortune-tag {
  display: inline-block; padding: 3px 12px; margin-bottom: 8px;
  background: linear-gradient(90deg, rgba(154,127,212,.2), rgba(212,176,106,.2));
  border: 1px solid var(--purple); border-radius: 14px;
  color: var(--purple); font-size: 12px; letter-spacing: 4px;
}
.modal .choices .choice:disabled { opacity: .4; cursor: not-allowed; }

/* ===== 突破大典：黑场二字题 + 收益清单（"丹成"模板）===== */
.ceremony-overlay {
  position: fixed; inset: 0; z-index: 300;
  display: flex; align-items: center; justify-content: center;
  /* A2：必须是真·黑场——暖芒只作覆层叠在不透明底色上，否则弹层文字会与下方
   * 场景标题/地点名/见闻文字透叠相撞（半透明 radial 中心曾漏底）。 */
  background:
    radial-gradient(ellipse at 50% 38%, rgba(70, 56, 30, .55) 0%, rgba(70, 56, 30, 0) 60%),
    #070504;
  opacity: 0; pointer-events: none; transition: opacity .6s ease;
}
.ceremony-overlay.show { opacity: 1; pointer-events: auto; }
.cer-inner { width: min(560px, 92vw); text-align: center; padding: 20px; }
.cer-title {
  font-size: clamp(44px, 11vw, 72px); font-weight: 800; letter-spacing: 22px;
  color: #f3e8cd; text-shadow: 0 0 40px rgba(236, 217, 168, .45), 0 4px 30px rgba(0,0,0,.8);
  animation: tcIn 1.2s cubic-bezier(.2,.8,.2,1) both;
}
.cer-realm {
  margin-top: 8px; font-size: 19px; letter-spacing: 8px; color: var(--gold-bright);
  animation: fadein 1s ease .4s both;
}
.cer-text {
  margin: 18px auto 14px; max-width: 420px; color: var(--ink); font-size: 14px; line-height: 1.9;
  animation: fadein 1s ease .7s both;
}
.cer-gains { display: flex; flex-direction: column; gap: 4px; align-items: center; animation: fadein 1s ease 1s both; }
.cer-gain { color: var(--jade-bright); font-size: 13.5px; letter-spacing: 1px; }
.cer-actions { display: flex; gap: 10px; justify-content: center; margin-top: 22px; animation: fadein 1s ease 1.4s both; }
.cer-actions .btn { width: auto; margin: 0; }
.cer-note { margin-top: 12px; color: var(--ink-faint); font-size: 11.5px; animation: fadein 1s ease 1.6s both; }
/* 破境帖留影（L4 传播素材）：低调金字小钮——不抢藏拙抉择的戏，想留念的人找得到 */
.cer-share {
  margin-top: 16px; padding: 7px 18px; cursor: pointer;
  background: transparent; border: 1px solid rgba(201,169,106,.35); border-radius: 16px;
  color: rgba(212,175,106,.8); font-family: inherit; font-size: 12.5px; letter-spacing: 2px;
  animation: fadein 1s ease 1.9s both; transition: border-color .2s ease, color .2s ease;
}
.cer-share:hover { border-color: rgba(212,175,106,.75); color: var(--gold-bright); }
/* 受挫变奏：同一演出语言、冷色调（失败也要被"看见"，但不给它庆典的暖光） */
.cer-inner.cer-fail .cer-title { color: #c9b8b4; text-shadow: 0 0 34px rgba(160, 80, 70, .35), 0 4px 30px rgba(0,0,0,.8); }
.cer-inner.cer-fail .cer-gain { color: var(--ink-dim); }

/* ===== 弹窗内状态摘要条（闭关/服药数值可见）===== */
.status-strip {
  display: flex; flex-wrap: wrap; gap: 6px 14px; align-items: baseline;
  padding: 8px 11px; margin-bottom: 12px; border-radius: var(--radius);
  background: rgba(255, 250, 240, 0.035); border: 1px solid var(--border-soft);
  font-size: 12px; color: var(--ink-dim);
}
.status-strip b { color: var(--ink); font-size: 13px; margin-left: 2px; }
.status-strip b.warn { color: var(--red); }

/* ===== 行动页"刚刚发生"反馈条（桌面隐藏：右栏见闻常驻可见）===== */
/* 刚刚发生：最近三条见闻（最新一条加亮、旧两条收灰）——一眼看清"做了什么"  */
.recent-log {
  display: none; flex-direction: column; gap: 5px; cursor: pointer;
  padding: 10px 12px; margin-bottom: 8px; border-radius: var(--radius);
  background: rgba(255, 250, 240, 0.03); border: 1px solid var(--border-soft);
  border-left: 2px solid var(--gold); font-size: 13px; line-height: 1.55;
}
.recent-log .rl-row { display: flex; align-items: baseline; gap: 7px; opacity: .62; }
.recent-log .rl-row.rl-latest { opacity: 1; font-size: 13.5px; }
.recent-log .rl-tag { color: var(--gold); font-size: 11px; flex-shrink: 0; }
.recent-log .rl-txt {
  color: var(--ink); flex: 1; min-width: 0;
  display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.recent-log .rl-row.rl-latest .rl-txt { -webkit-line-clamp: 3; line-clamp: 3; }
.recent-log .rl-txt.entry-good { color: var(--jade-bright); }
.recent-log .rl-more { align-self: flex-end; color: var(--ink-faint); font-size: 11px; }
.recent-log .rl-txt.entry-bad { color: var(--red); }

/* 双击缩放锁死修复：游戏型 UI 禁用双击缩放手势 */
html, body { touch-action: manipulation; }

/* ===== 际遇 / 任务指引条（天命=必须做的 / 机缘=可以做的）===== */
/* 独立于 tab 面板——桌面端浮于 topbar 下方，手机端 fixed 常驻 */
.objective-bar {
  position: absolute; top: 52px; z-index: 9; pointer-events: auto;
  left: calc(282px + 14px + 12px); right: calc(372px + 14px + 12px);
  display: flex; flex-direction: column; gap: 6px;
  max-height: 120px; overflow-y: auto;
}
.objective-bar:empty { display: none; }
.obj-sect { display: flex; flex-direction: column; gap: 6px; }
.obj-sect.fate { padding-left: 0; }
.obj-sect.luck {
  position: relative; padding: 20px 0 0; margin-top: 2px;
  border-top: 1px dashed rgba(140,120,90,.28);
}
.obj-sect-tag {
  position: absolute; top: 4px; left: 8px; padding: 0 8px; z-index: 1;
  font-size: 10.5px; letter-spacing: 2px; color: var(--ink-faint);
  background: var(--bg-panel-2);
}
.obj-main, .obj-task {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 7px 10px; border-radius: 6px; font-size: 13px;
  background: var(--bg-panel-2); border: 1px solid var(--border);
}
.obj-main { border-left: 2px solid var(--gold); }
.obj-task { border-left: 2px solid var(--jade); }
.obj-task.urgent { border-left-color: var(--red); }
.obj-key {
  font-size: 11px; letter-spacing: 1px; padding: 1px 7px; border-radius: 10px;
  background: var(--bg); color: var(--ink-dim);
}
.obj-main b { color: var(--gold-bright); }
.obj-task b { color: var(--jade-bright); }
.obj-hint { color: var(--ink-dim); }
.obj-prog { color: var(--ink-dim); }
.obj-left { margin-left: auto; color: var(--gold); }
.obj-task.urgent .obj-left { color: var(--red); }

/* ===== 战斗飘字 ===== */
.float-fx {
  position: absolute; left: 50%; top: 6px; transform: translateX(-50%);
  font-size: 20px; font-weight: 700; letter-spacing: 1px; pointer-events: none;
  z-index: 30; animation: floatup 1.1s ease-out forwards;
  text-shadow: 0 2px 6px rgba(0,0,0,.6);
}
.fx-dmg { color: #f5d27a; }
.fx-crit { color: #ff7a5c; font-size: 26px; }
.fx-pierce { color: #7fb8e3; }
.fx-poison { color: #8fe37f; }
.fx-soul { color: #c39bf0; }
.fx-hurt { color: #e35c5c; }
.fx-miss { color: var(--ink-dim); font-size: 16px; }
@keyframes floatup {
  0% { opacity: 0; transform: translate(-50%, 6px) scale(.7); }
  20% { opacity: 1; transform: translate(-50%, -4px) scale(1.1); }
  100% { opacity: 0; transform: translate(-50%, -38px) scale(1); }
}

/* ===== 功法阁 ===== */
.tech-item { background: var(--bg-panel-2); border: 1px solid var(--border); border-radius: 8px; padding: 12px; margin-bottom: 10px; }
.tech-item.current { border-color: var(--jade); }
.tech-item.locked { opacity: .72; }
.tech-head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 6px; }
.tech-head b { color: var(--jade-bright); font-size: 16px; }
.tech-cur { color: var(--jade); font-size: 12px; }
.tech-lock { color: var(--gold); font-size: 12px; }
.tech-desc { color: var(--ink); font-size: 13px; line-height: 1.6; margin-bottom: 4px; }
.tech-origin { color: var(--ink-dim); font-size: 12px; line-height: 1.5; }

.qi-chip.momentum { color: var(--gold-bright); border-color: var(--gold); }

/* ===== 风云录 ===== */
.roster { display: flex; flex-direction: column; gap: 4px; margin-bottom: 10px; }
.roster-row { display: flex; justify-content: space-between; padding: 6px 10px; background: var(--bg-panel-2); border: 1px solid var(--border); border-radius: 6px; font-size: 13px; }
.roster-row b { color: var(--ink); }
.roster-row.dead { opacity: .5; }
.roster-row.dead b { text-decoration: line-through; }
.chronicle { display: flex; flex-direction: column; gap: 6px; max-height: 240px; overflow-y: auto; }
.chron-item { padding: 7px 10px; border-radius: 6px; font-size: 13px; background: var(--bg-panel-2); border-left: 2px solid var(--border); line-height: 1.6; }
.chron-item .chron-t { color: var(--gold); font-size: 11px; margin-right: 8px; }
.chron-item.death { border-left-color: var(--red); color: var(--ink-dim); }
.chron-item.ascend { border-left-color: var(--gold); }
.chron-item.breakthrough { border-left-color: var(--jade); }
.chron-item.desperate { border-left-color: var(--purple); }
.chron-item.fortune { border-left-color: var(--blue); }

/* 心性基调（名场面态度累计 → 一句"你是谁"·我的修仙人生呼应） */
.temperament-echo { padding: 11px 13px; border-radius: 8px; font-size: 13px; line-height: 1.75; background: var(--bg-panel-2); border-left: 3px solid var(--gold); color: var(--ink); }
.temperament-echo.temperament-stoic { border-left-color: var(--blue); }
.temperament-echo.temperament-sentiment { border-left-color: var(--red); }
.temperament-echo.temperament-balanced { border-left-color: var(--jade); }

/* ===== 我的修仙人生·终章墓志（gameOver 总结）===== */
.ending-epitaph { margin-top: 12px; padding: 12px 14px; border-radius: 8px; background: var(--bg-panel-2);
  border: 1px solid var(--border); border-top: 2px solid var(--gold); }
.ending-line { display: flex; justify-content: space-between; align-items: baseline; padding: 4px 0;
  font-size: 14px; line-height: 1.5; }
.ending-line + .ending-line { border-top: 1px dashed var(--border); }
.ending-line span { color: var(--ink-dim); font-size: 12px; letter-spacing: 2px; }
.ending-line b { color: var(--ink); }

/* ===== §9-6 名场面回廊（风云录里重温关键演出）===== */
.scene-gallery { display: flex; flex-direction: column; gap: 6px; max-height: 220px; overflow-y: auto; }
.scene-row {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  padding: 8px 10px; border-radius: 6px; font: inherit; color: var(--ink);
  background: var(--bg-panel-2); border: 1px solid var(--border); border-left: 2px solid var(--gold);
  cursor: pointer; transition: background .15s ease, border-color .15s ease, transform .08s ease;
}
.scene-row:hover { background: rgba(166, 77, 58, 0.10); border-left-color: var(--gold-bright, var(--gold)); }
.scene-row:active { transform: translateY(1px); }
.scene-play { color: var(--gold); font-size: 12px; flex: none; }
.scene-name { flex: 1 1 auto; font-size: 13px; line-height: 1.5; }
.scene-row .chron-t { color: var(--ink-dim); font-size: 11px; flex: none; }
/* 重温落幕条 */
.replay-end { text-align: center; color: var(--gold); font-size: 13px; letter-spacing: 2px; margin-bottom: 8px; }

/* ===== §9 体验设置（演出速度 / 动效强度 / 震动）===== */
.settings { display: flex; flex-direction: column; gap: 14px; margin: 6px 0 14px; }
.set-row { display: flex; flex-direction: column; gap: 7px; }
.set-label { font-size: 14px; color: var(--ink); font-weight: 600; }
.set-hint { display: block; font-size: 11px; color: var(--ink-dim); font-weight: 400; margin-top: 2px; }
.set-opts { display: flex; gap: 6px; flex-wrap: wrap; }
.set-opt {
  flex: 1 1 0; min-width: 56px; padding: 8px 6px; border-radius: 6px; font: inherit; font-size: 13px;
  color: var(--ink-dim); background: var(--bg-panel-2); border: 1px solid var(--border);
  cursor: pointer; transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.set-opt:hover { color: var(--ink); border-color: var(--gold); }
.set-opt.on {
  color: var(--bg, #1a1410); background: var(--gold); border-color: var(--gold);
  font-weight: 600; box-shadow: 0 0 0 1px var(--gold) inset;
}

/* §9 动效强度=关：把各处 idle/装饰动画静态化（与 @media prefers-reduced-motion 并列的手动闸）。
 * 与上文各 reduced-motion 块逐条对应；JS 侧的震屏/顿帧/常驻氛围粒已由 Settings.reduceMotion() 拦截。 */
body.motion-off .combat-overlay.peril::after,
body.motion-off .combat-overlay.brink::after { animation: none; opacity: .82; }
body.motion-off .axis-field.cam-punch { animation: none; }
body.motion-off .cloud-shroud .fog-drift { animation: none !important; }
body.motion-off .story-portrait .pb { animation: none; }
body.motion-off .scene-stage[data-weather] .scene-weather { animation: none !important; }
body.motion-off .scene-stage[data-depth="on"] .scene-far,
body.motion-off .scene-stage[data-depth="on"] .scene-fg,
body.motion-off .scene-stage[data-depth="on"] .scene-fg::after { animation: none !important; }

/* ===== 人物图鉴 ===== */
.codex { display: flex; flex-direction: column; gap: 8px; }
.codex-card { background: var(--bg-panel-2); border: 1px solid var(--border); border-radius: 8px; padding: 11px 13px; }
.codex-card.locked { opacity: .5; }
.codex-head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 5px; }
.codex-head b { color: var(--jade-bright); font-size: 15px; }
.codex-role { color: var(--gold); font-size: 12px; }
.codex-bio { color: var(--ink); font-size: 13px; line-height: 1.6; }
.codex-rel { color: var(--ink-dim); font-size: 12px; margin-top: 4px; }

/* 图鉴页签：人物 | 大件 */
.comp-tabs { display: flex; gap: 6px; margin: -2px 0 10px; }
.comp-tab {
  flex: 1; padding: 8px 10px; border-radius: 8px; cursor: pointer;
  background: var(--bg-panel-2); border: 1px solid var(--border);
  color: var(--ink-dim); font-size: 14px; font-family: inherit;
}
.comp-tab.on { background: var(--jade); border-color: var(--jade); color: #08140f; font-weight: 600; }

/* ===== 大件图鉴 ===== */
.bigitems { display: flex; flex-direction: column; gap: 4px; }
.bigitems .panel-title { margin: 12px 0 6px; }
.bi-list { display: flex; flex-direction: column; gap: 8px; }
.bi-card {
  background: var(--bg-panel-2); border: 1px solid var(--border);
  border-left: 3px solid var(--border); border-radius: 8px; padding: 10px 12px;
}
.bi-card.bi-got { border-left-color: var(--jade-bright); }
.bi-card.bi-track { border-left-color: var(--gold); }
.bi-card.bi-unheard { border-left-color: var(--ink-faint); }
.bi-card.bi-far { opacity: .6; }
.bi-head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 4px; }
.bi-head b { color: var(--jade-bright); font-size: 15px; }
.bi-far .bi-head b { color: var(--ink-dim); }
.bi-badge {
  flex-shrink: 0; font-size: 11px; padding: 1px 8px; border-radius: 10px;
  background: rgba(0,0,0,.25); color: var(--ink-dim);
}
.bi-got .bi-badge { background: rgba(80,180,120,.22); color: var(--jade-bright); }
.bi-track .bi-badge { background: rgba(200,165,90,.22); color: var(--gold); }
.bi-blurb { color: var(--ink); font-size: 13px; line-height: 1.6; }
.bi-prog { display: flex; align-items: center; gap: 8px; margin: 6px 0 2px; }
.bi-prog-bar { flex: 1; height: 6px; border-radius: 3px; background: rgba(0,0,0,.3); overflow: hidden; }
.bi-prog-bar i { display: block; height: 100%; background: var(--gold); border-radius: 3px; }
.bi-prog span { flex-shrink: 0; font-size: 11px; color: var(--ink-dim); }
.bi-note { color: var(--ink-dim); font-size: 12px; margin-top: 4px; }
.bi-guide {
  margin-top: 7px; padding-top: 7px; border-top: 1px dashed var(--border);
  color: var(--ink-dim); font-size: 12px; line-height: 1.55;
}
.bi-guide-key {
  display: inline-block; background: var(--gold); color: #1a1208;
  font-size: 11px; padding: 0 6px; border-radius: 4px; margin-right: 6px; vertical-align: 1px;
}

/* ===== 剧情演出 ===== */
.seg-narr { margin-bottom: 9px; line-height: 1.85; color: var(--ink); }
.seg-aside { margin-bottom: 9px; line-height: 1.8; color: var(--ink-dim); font-style: italic; padding-left: 12px; border-left: 2px solid var(--border); }
.seg-scene { text-align: center; color: var(--gold); letter-spacing: 3px; font-size: 13px; margin: 12px 0; opacity: .9; position: relative; }
.seg-scene::before, .seg-scene::after { content: ""; display: inline-block; width: 28px; height: 1px; background: var(--gold); vertical-align: middle; margin: 0 8px; opacity: .5; }
.seg-beat { text-align: center; color: var(--ink-dim); letter-spacing: 4px; margin: 6px 0; opacity: .6; }

/* 对话：左右肖像演出（visual-novel 风） */
.dlg-row { display: flex; align-items: flex-start; gap: 10px; margin: 10px 0; animation: dlgIn .32s cubic-bezier(.22,1,.36,1) backwards; }
.dlg-row.right { flex-direction: row-reverse; }
@keyframes dlgIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
.dlg-portrait {
  flex-shrink: 0; width: 40px; height: 40px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; font-size: 22px;
  background: radial-gradient(circle at 50% 38%, color-mix(in srgb, var(--pc) 28%, transparent), #1a2028 72%);
  border: 1.5px solid var(--pc); box-shadow: 0 0 10px color-mix(in srgb, var(--pc) 35%, transparent);
}
.dlg-bubble {
  max-width: 78%; padding: 8px 12px; border-radius: 12px; line-height: 1.7;
  background: rgba(255,255,255,.035); border: 1px solid var(--border);
}
.dlg-row.left .dlg-bubble { border-top-left-radius: 3px; }
.dlg-row.right .dlg-bubble { border-top-right-radius: 3px; background: rgba(127,227,192,.07); }
.dlg-row.hl .dlg-bubble { border-color: var(--red); background: rgba(201,95,95,.07); }
.dlg-who { display: flex; align-items: baseline; gap: 6px; margin-bottom: 2px; }
.dlg-row.right .dlg-who { flex-direction: row-reverse; }
.dlg-name { font-weight: 600; font-size: 13px; }
.dlg-tone { color: var(--ink-dim); font-size: 11px; font-style: italic; }
.dlg-text { color: var(--ink); }
.dlg-row.right .dlg-text, .dlg-row.right .dlg-who { text-align: right; }
.story .body { animation: fadein .5s ease; }

/* 临战准备一览（战斗类抉择前提示，避免"没头没尾"） */
.fight-prep {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  padding: 8px 12px; border-radius: 8px; margin-bottom: 8px; font-size: 13px;
  background: rgba(255,255,255,.03); border: 1px solid var(--border); border-left: 3px solid var(--gold);
}
.fight-prep.ok { border-left-color: var(--jade); background: rgba(95,184,154,.08); }
.fight-prep.bad { border-left-color: var(--red); background: rgba(201,95,95,.08); }
.fight-prep .fp-tag { font-size: 11px; letter-spacing: 2px; color: var(--gold); background: var(--bg); padding: 1px 8px; border-radius: 10px; }
.fight-prep .fp-item { color: var(--ink); font-weight: 600; }
.fight-prep .fp-note { color: var(--ink-dim); font-size: 12px; width: 100%; }
.fight-prep.ok .fp-note { color: var(--jade-bright); }
.fight-prep.bad .fp-note { color: var(--red); }
.choice.choice-fight { border-color: rgba(201,95,95,.5); background: rgba(201,95,95,.06); }
.choice.choice-fight:hover { border-color: var(--red); background: rgba(201,95,95,.12); }

/* ============================================================
 * 响应式：平板 / 手机
 * ============================================================ */

/* 中等屏幕（平板、窄窗口）：缩窄两侧卷轴 */
@media (max-width: 1180px) {
  .layout { grid-template-columns: 244px minmax(0, 1fr) 300px; gap: 10px; padding: 52px 10px 10px; }
  .objective-bar { left: calc(244px + 10px + 10px); right: calc(300px + 10px + 10px); }
  html, body { font-size: 14px; }
  .wm-pin-label { font-size: 10px; }
  .wm-label { font-size: 11px; }
}

/* 桌面：底部分页栏隐藏 */
.mobile-tabs { display: none; }

/* 窄屏（手机）：场景常驻顶部 36vh + 底部 Tab 分页 */
@media (max-width: 760px) {
  html, body { font-size: 15px; }
  #app { height: 100vh; height: 100dvh; overflow: hidden; }
  #screen-game.active { display: flex; flex-direction: column; height: 100vh; height: 100dvh; overflow: hidden; }

  /* 顶栏：覆于场景带之上，只留 时间 + ☰（其余收进系统菜单）*/
  #screen-game .topbar { position: absolute; top: 0; left: 0; right: 0; z-index: 14; }
  .topbar { gap: 6px; padding: 7px 10px; }

  /* 际遇栏：fixed 常驻于顶栏下方，不随 tab 切换隐藏 */
  .objective-bar {
    position: fixed; top: 48px; left: 8px; right: 8px; z-index: 13;
    max-height: min(32vh, 132px); overflow-y: auto;
    -webkit-overflow-scrolling: touch;
  }
  .char-brief { gap: 8px; }
  .game-logo { font-size: 14px; letter-spacing: 2px; }
  .t-name { font-size: 16px; }
  /* 手机端顶栏紧凑：月历条收窄、修为条只留细轨（境界名/数值在「状态」页看），两者一行并存 */
  .month-bar { gap: 1px; }
  .month-cell { width: 9px; }
  .top-cul .tc-realm, .top-cul .tc-text { display: none; }
  .top-cul .tc-track { width: 56px; }
  .top-cul { gap: 0; }
  .topbar-actions { gap: 5px; }
  .btn-mini { padding: 5px 9px; font-size: 12px; }
  .topbar-actions .tb-full { display: none; }
  .btn-more { display: inline-block; font-size: 15px; padding: 5px 12px; }

  /* （场景带/在场人物的手机覆盖规则在文件末尾——必须晚于桌面定义） */

  /* 地图主界面·手机端：全屏地图 + 底部缩放控制 */
  .worldmap-canvas { position: absolute; inset: 0; padding-top: 52px; }
  .zoom-controls { right: 10px; bottom: 70px; }
  .zoom-btn { width: 34px; height: 34px; font-size: 16px; }
  .wm-pin-label { font-size: 10px; letter-spacing: 0; }
  .wm-label { font-size: 11px; letter-spacing: 2px; }
  .worldmap-hint { font-size: 11px; bottom: 12px; }

  /* 手机端隐藏 HUD 切换按钮（用底栏 tab 代替） */
  .hud-toggle { display: none !important; }
  /* 旅途进度浮标：下移到天命栏（fixed top48 高~80）之下，不被遮 */
  .journey-status { top: 136px; font-size: 11px; padding: 4px 12px; }

  /* 行动 dock·手机端：底部 sheet 风格 */
  .action-dock {
    width: 100vw; left: 0; bottom: 0;
    border-radius: 14px 14px 0 0;
    padding: 6px 10px calc(10px + env(safe-area-inset-bottom, 0px));
  }
  .dock-actions .btn-action { min-width: 90px; min-height: 44px; padding: 11px 14px; font-size: 13px; }

  /* 地图模式·手机端：全屏地图，HUD 隐藏（用底栏 tab 切换查看） */
  .worldmap-canvas:not([hidden]) ~ .layout {
    display: none !important;
  }
  .worldmap-canvas:not([hidden]) ~ .scene-stage {
    display: none !important;
  }
  /* 行动 sheet·手机端：底部 sheet，位于底栏之上 */
  .action-dock.show { bottom: calc(50px + env(safe-area-inset-bottom, 0px)); }
  .action-dock { width: 100vw; left: 0; transform: translateX(0) translateY(100%); border-radius: 16px 16px 0 0; padding: 6px 14px 14px; }
  .action-dock.show { transform: translateX(0) translateY(0); }
  /* 全展开态：sheet 拉高占大半屏（行动+见闻都看得全） */
  .action-dock.expanded .dock-body { max-height: 64vh; }

  /* HUD：场景带下方，分页滚动 */
  .layout {
    position: relative; inset: auto; flex: 1; min-height: 0; z-index: 2;
    display: block; padding: 13px 8px calc(64px + env(safe-area-inset-bottom, 0px));
    overflow-y: auto; pointer-events: auto;
  }
  .panel { overflow: visible; margin-bottom: 0; backdrop-filter: none; -webkit-backdrop-filter: none; background: var(--paper-solid); }
  .mid-col { max-height: none; }
  /* 地图主界面化：行动页(act)=场景做底+底部行动 sheet，layout 三栏隐藏；
   * 韩立页(hero)=角色卡+储物全屏；舆图页(map)=全屏地图（layout 已被上面隐藏） */
  .layout .side-rail, .layout .mid-col, .layout .stage-col { display: none; }
  /* 行动页：场景常驻、layout 不占位（行动走 sheet） */
  #screen-game[data-mtab="act"] .layout { display: none; }
  #screen-game[data-mtab="act"] .scene-stage { display: block; flex: 1; }
  /* 韩立页：隐藏场景，显示角色卡+储物 */
  #screen-game[data-mtab="hero"] .layout { display: block; }
  .layout[data-mtab="hero"] .side-rail { display: block; }

  /* 舆图页：全屏地图，隐藏场景与三栏（底栏「舆图」tab 专用） */
  #screen-game[data-mtab="map"] .scene-stage { display: none !important; }
  #screen-game[data-mtab="map"] .layout { display: none !important; }
  #screen-game[data-mtab="map"] .objective-bar { display: flex; }

  .stage-col .narrative { max-height: none; flex: none; }
  .stage-col > .panel-title { display: none; }   /* 页签已标明"见闻"，免重复 */
  /* 行动按钮在手机上竖排大按钮 */
  .mid-col .action-buttons { flex-direction: column; }
  .mid-col .btn-action { width: 100%; padding: 14px 16px; }
  /* 手机上显示"刚刚发生"反馈条（治行动/见闻割裂） */
  .recent-log { display: flex; }

  .stage-col .narrative { max-height: none; flex: none; }
  .stage-col > .panel-title { display: none; }   /* 页签已标明"见闻"，免重复 */
  /* 行动按钮在手机上竖排大按钮 */
  .mid-col .action-buttons { flex-direction: column; }
  .mid-col .btn-action { width: 100%; padding: 14px 16px; }
  /* 手机上显示"刚刚发生"反馈条（治行动/见闻割裂） */
  .recent-log { display: flex; }

  /* 底部 Tab 栏 */
  .mobile-tabs {
    display: flex; position: fixed; left: 0; right: 0; bottom: 0; z-index: 45;
    background: rgba(14, 11, 8, .96); border-top: 1px solid var(--border);
    box-shadow: 0 -4px 16px rgba(0,0,0,.4);
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }
  .mobile-tabs .mtab {
    flex: 1; padding: 13px 0; background: none; border: none; cursor: pointer;
    color: var(--ink-dim); font-family: inherit; font-size: 15px; letter-spacing: 3px;
    border-top: 2px solid transparent;
  }
  .mobile-tabs .mtab.active { color: var(--gold-bright); border-top-color: var(--gold); background: rgba(201,169,106,.07); }

  /* Toast 避开底部 Tab 栏 */
  .toast { bottom: 64px; }
  /* 剧情演出中 toast 顶部显示（覆盖上面的 64px，避免压住抉择按钮）*/
  body.story-on .toast { bottom: auto; top: calc(16px + env(safe-area-inset-top, 0px)); }

  /* 弹窗几乎占满屏宽 */
  .modal { width: 94vw; padding: 20px 16px; max-height: 88vh; }

  /* 创建界面：竖排题字与卡片上下排布 */
  #screen-create.active { flex-direction: column; gap: 12px; padding: 16px 0 20px; overflow-y: auto; justify-content: flex-start; }
  .create-title-block { flex-direction: row; align-items: center; gap: 10px; flex-shrink: 0; }
  .game-title.vertical { font-size: 26px; letter-spacing: 6px; padding: 8px 8px; }
  .title-seal { font-size: 11px; letter-spacing: 2px; padding: 6px 4px; }
  .create-title-block .subtitle { writing-mode: vertical-rl; letter-spacing: 4px; font-size: 11px; }
  .create-box { width: 92vw; padding: 20px 16px 16px; flex-shrink: 0; }

  /* 战斗界面（对阵轴竖屏）：立绘不缩气势优先、格距压缩、手牌大拇指区 */
  .combat-box { width: 100vw; padding: 8px 8px 12px; }
  .combat-title { font-size: 16px; letter-spacing: 5px; margin: 2px 0 4px; }
  .combat-tophud { gap: 8px; }
  /* 竖屏满屏分配：战场占据中段并撑开（不再挤在上半屏、下半屏留黑），手牌操作台贴底=拇指区。
   * 战场 flex 撑高，cqh 相对参数随之等比放大——气势更足。 */
  .axis-field { height: auto; flex: 1 1 auto; min-height: 300px; margin-bottom: 4px; }
  .combat-console { margin-top: auto; }
  .axis-lane { height: 44px; }
  .axis-cell .dot { bottom: 17px; }
  .axis-cell.can-move::before { bottom: 9px; width: 26px; height: 10px; }
  .axis-cell .mist-pillar { height: 68px; bottom: 12px; }
  .axis-cell .mist-band { bottom: 11px; height: 22px; }
  .axis-cell .zone-ring { bottom: 10px; height: 13px; }
  .axis-units { inset: 0 0 18px 0; }
  .axis-unit { width: clamp(52px, 12vw, 86px); }
  /* v91 相对坐标系：立绘高/地线/排距/飞高全部 cqh（随战场自适应）——
   * 移动端不再需要 px 覆盖（曾经的"改了等于没改"高发区），只留横向斜移微调 */
  .axis-unit.off-row { --lx: 7px; }
  .axis-unit.lane-1 { --lx: 22px; }
  .axis-unit.lane-2 { --lx: 40px; }
  .axis-unit.lane-3 { --lx: 56px; }
  .au-blades { scale: .8; }
  .axis-unit .au-glyph { width: clamp(44px, 11vw, 64px); }
  .axis-unit .au-name { font-size: 10px; }
  .au-intent { width: 20px; height: 20px; font-size: 11px; }
  .au-mark { font-size: 9px; padding: 0 4px; }
  .au-orbit .orb { width: 19px; height: 19px; font-size: 10px; }
  .au-orbit .orb-w { left: -9px; }
  .au-orbit .orb-a { right: -9px; }
  .combat-floats { top: 2px; }
  .log-float { font-size: 11.5px; padding: 3px 10px; backdrop-filter: none; -webkit-backdrop-filter: none; background: rgba(12,9,7,.9); }
  .fx-global.fxg-exploit .fxg-text { letter-spacing: 6px; }
  .combat-intent { font-size: 11px; padding: 6px 9px; margin-bottom: 6px; backdrop-filter: none; -webkit-backdrop-filter: none; background: rgba(14,11,8,.95); }
  .combat-mprow { gap: 8px; margin-bottom: 8px; }
  .mp-pool { min-width: 150px; }
  .mp-num { font-size: 11.5px; min-width: 48px; }
  .act-chip { font-size: 10px; padding: 2px 6px; }
  /* 手机性能：战斗期常驻面板不走 backdrop-filter（每帧重模糊背景=特效卡顿主因之一），
   * 改不透明底，视觉近乎不变。 */
  .combat-console { padding: 9px; backdrop-filter: none; -webkit-backdrop-filter: none; background: var(--paper-solid); }
  /* 手机档：手牌沿用桌面紧凑值（勿在此放大——曾因此“紧凑改了等于没改”） */
  .sname .srange { font-size: 9px; }
  .combat-log { height: 118px; font-size: 12.5px; }
  .combat-actions { gap: 6px; }
  .combat-actions .btn { height: 44px; padding: 0 12px; }
  /* v115 回合结束恒在同屏（用户硬指标：保证所有画面都在同一页）：操作台(combat-console)是
   * 战斗里唯一可滚区，结束回合作为其末行曾被挤进滚动区→划走才见。改用 sticky 底吸——
   * 法宝/法术/瞬发列表在它上方滚动，升空/结束回合这一行永远吸附在操作台底部可见。
   * 桌面操作台不溢出→sticky 等同普通流，零影响。底吸行铺不透明纸底+顶部柔分隔，
   * 滚动内容从其后穿过不糊叠。 */
  .combat-actions {
    position: sticky; bottom: 0; z-index: 3;
    background: var(--paper-solid); margin: 0 -9px -9px; padding: 7px 9px calc(9px + env(safe-area-inset-bottom, 0px));
    box-shadow: 0 -10px 12px -8px rgba(8,6,4,.55);
  }

  /* 触摸目标更大 */
  .btn { padding: 12px 16px; }
  .choices .choice { padding: 14px 16px; }
  .inv-item { padding: 11px 12px; }

  /* 对话肖像在手机上略小 */
  .dlg-portrait { width: 34px; height: 34px; font-size: 18px; }
  .dlg-bubble { max-width: 80%; }
}

/* 极窄屏（小手机）：进一步压缩 */
@media (max-width: 400px) {
  .action-buttons { grid-template-columns: 1fr; }
  .combat-spells { grid-template-columns: 1fr; }
  .game-title { font-size: 26px; letter-spacing: 3px; }
}

/* 触摸设备：去掉 hover 依赖的 tooltip，避免点不出来（改为常显小字） */
@media (hover: none) {
  .stat-row[data-tip]:hover::after { display: none; }
}

/* ============================================================
 * 箱庭探索界面（走格子副本/秘境）：水墨地形
 * ============================================================ */
.explore-overlay {
  position: fixed; inset: 0; z-index: 60;
  background: rgba(8, 6, 4, 0.94);
  display: flex; align-items: center; justify-content: center;
}
.explore-box {
  width: min(880px, 96vw); max-height: 96vh;
  display: flex; flex-direction: column;
  background: var(--paper-solid); border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg); padding: 14px; box-shadow: 0 24px 60px var(--shadow);
}
.explore-head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; flex-shrink: 0; }
.explore-title { font-size: 18px; font-weight: 700; color: var(--gold); letter-spacing: 2px; }
.explore-info { font-size: 12px; color: var(--ink-dim); flex: 1; }
.explore-main { display: flex; gap: 12px; align-items: flex-start; flex-shrink: 0; }
.explore-grid {
  display: grid; gap: 2px; flex: 1;
  background: rgba(0,0,0,0.3); padding: 4px; border-radius: var(--radius);
  aspect-ratio: 1 / 1; min-width: 0;
}
.ex-cell {
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(145deg, #1c1812, #16130e);
  border-radius: 2px; aspect-ratio: 1 / 1;
  font-size: clamp(12px, 2.4vw, 20px); user-select: none; position: relative;
  transition: background .12s;
}
/* 迷雾：未探明之地如浓墨未干 */
.ex-cell.fog {
  background:
    radial-gradient(circle at 30% 30%, rgba(30,25,19,.5), transparent 60%),
    #0a0806;
}
.ex-cell.seen { background: linear-gradient(145deg, #221c14, #1a1610); }
.ex-cell.blocked { background: linear-gradient(145deg, #14110c, #0e0c08); }
.ex-cell.reach { cursor: pointer; box-shadow: inset 0 0 0 2px rgba(111,174,147,.75); }
.ex-cell.reach:hover { background: linear-gradient(145deg, #2a3328, #1d2419); }
.ex-cell.player { box-shadow: inset 0 0 0 2px var(--gold), 0 0 14px rgba(201,169,106,.35); }
.ex-cell.player .ex-icon.you { animation: youBob 1.4s ease-in-out infinite; }
@keyframes youBob { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-2px); } }
.ex-cell.collected { animation: collectFlash 0.5s ease; }
@keyframes collectFlash {
  0% { background: var(--jade); box-shadow: 0 0 12px var(--jade); }
  100% { background: #18222b; box-shadow: none; }
}
.ex-icon.you { filter: drop-shadow(0 0 4px var(--gold)); }
.ex-icon.comp { filter: drop-shadow(0 0 3px var(--blue)); }
.ex-icon.dim { opacity: 0.5; }
.ex-icon.boss { filter: drop-shadow(0 0 6px var(--cinnabar)); animation: pinPulse 1.6s ease-in-out infinite; }

.explore-side { width: 180px; flex-shrink: 0; display: flex; flex-direction: column; gap: 10px; }
.minimap-label { font-size: 11px; color: var(--ink-dim); margin-bottom: 4px; }
.explore-minimap { display: grid; gap: 1px; background: rgba(0,0,0,0.3); padding: 3px; border-radius: 6px; cursor: pointer; }
.explore-minimap:hover { outline: 1px solid var(--jade); }
.mini-cell { aspect-ratio: 1/1; border-radius: 1px; background: #1a1610; }
.mini-cell.m-fog { background: #0a0806; }
.mini-cell.m-floor { background: #262017; }
.mini-cell.m-block { background: #100d09; }
.mini-cell.m-res { background: var(--jade); }
.mini-cell.m-beast { background: var(--red); }
.mini-cell.m-comp { background: var(--blue); }
.mini-cell.m-exit { background: var(--gold); }
.mini-cell.m-entry { background: var(--purple); }
.mini-cell.m-you { background: #ff3b3b; box-shadow: 0 0 5px #ff3b3b; border-radius: 50%; }

/* 全图弹窗 */
.fullmap {
  display: grid; gap: 2px; background: rgba(0,0,0,0.3);
  padding: 6px; border-radius: 8px; margin: 10px 0;
  width: min(70vh, 100%); aspect-ratio: 1/1; margin-inline: auto;
}
.fullmap .mini-cell { border-radius: 2px; }
.fullmap .mini-cell.m-you { border-radius: 50%; }
.map-legend { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; font-size: 12px; color: var(--ink-dim); }
.map-legend span { display: inline-flex; align-items: center; gap: 4px; }
.map-legend .lg { width: 12px; height: 12px; border-radius: 2px; display: inline-block; }
.map-legend .lg.m-you { border-radius: 50%; background: #ff3b3b; }
.map-legend .lg.m-comp { background: var(--blue); }
.map-legend .lg.m-res { background: var(--jade); }
.map-legend .lg.m-beast { background: var(--red); }
.map-legend .lg.m-exit { background: var(--gold); }
.map-legend .lg.m-entry { background: var(--purple); }
.map-legend .lg.m-fog { background: #0a0d10; border: 1px solid var(--border); }

.explore-bag { background: rgba(0,0,0,0.2); border-radius: 6px; padding: 8px; }
.exbag-title { font-size: 11px; color: var(--ink-dim); margin-bottom: 6px; }
.exbag-item { display: flex; justify-content: space-between; font-size: 13px; padding: 2px 0; }
.exbag-item b { color: var(--jade-bright); }
.exbag-empty { font-size: 12px; color: var(--ink-dim); }

.explore-log {
  margin-top: 10px; background: rgba(0,0,0,0.25); border-radius: 6px;
  padding: 8px 10px; font-size: 12px; color: var(--ink-dim);
  flex: 1 1 auto; min-height: 48px; max-height: 90px; overflow-y: auto; line-height: 1.6;
}
.explore-dpad {
  margin: 12px auto 0; display: grid; grid-template-columns: repeat(3, 52px);
  grid-template-rows: repeat(3, 52px); gap: 6px; justify-content: center; flex-shrink: 0;
}
.dpad-btn {
  background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-lg);
  color: var(--ink); font-size: 20px; cursor: pointer;
}
.dpad-btn:hover { background: #242c22; border-color: var(--jade); }
.dpad-center { color: var(--ink-dim); font-size: 14px; cursor: default; }
.explore-dpad > div { width: 52px; height: 52px; }

@media (max-width: 560px) {
  .explore-box { max-height: 100dvh; padding: 10px; }
  .explore-main { flex-direction: column; }
  .explore-side { width: 100%; flex-direction: row; }
  .explore-minimap-wrap { flex: 1; }
  .explore-bag { flex: 1; }
  .explore-log { min-height: 36px; max-height: 56px; margin-top: 8px; }
  .explore-dpad { margin: 8px auto 0; grid-template-columns: repeat(3, 46px); grid-template-rows: repeat(3, 46px); gap: 5px; }
  .explore-dpad > div { width: 46px; height: 46px; }
}

/* ============================================================
 * 点击反馈 + 图鉴/风云录优化
 * ============================================================ */
/* 通用按钮按下反馈 */
.btn:active, .choice:active, .dpad-btn:active,
.travel-item:active, .market-item .btn:active, .spell-btn:active,
.inv-item:active, .codex-card.tappable:active, .combatant.target:active {
  transform: scale(0.96);
  filter: brightness(1.12);
}
.btn, .choice, .dpad-btn, .inv-item, .codex-card.tappable, .travel-item {
  transition: transform .08s ease, filter .08s ease, background .12s ease;
}
.tappable { cursor: pointer; }

.codex-count {
  font-size: 13px; color: var(--gold); font-weight: 600;
  border: 1px solid var(--gold); border-radius: 10px; padding: 1px 8px; margin-left: 6px;
}
.codex-rel.rel-deep { color: var(--gold-bright); }
.codex-rel.rel-warm { color: var(--jade-bright); }
.codex-rel.rel-cold { color: var(--red); }

/* 羁绊信物：故人所赠的唯一之物（金线底衬，留痕图鉴） */
.codex-keepsake {
  margin: 6px 0 2px; padding: 4px 9px; border-radius: var(--radius);
  background: rgba(201, 169, 106, 0.08); border: 1px solid rgba(201, 169, 106, 0.4);
  color: var(--gold-bright); font-size: 12px; line-height: 1.5;
}
.codex-keepsake .ks-from { color: var(--ink-dim); font-size: 11px; }

/* 情报面纱：图鉴内的逐层底细 */
.codex-intel {
  margin: 7px 0 4px; padding: 7px 9px; border-radius: var(--radius);
  background: rgba(255, 250, 240, 0.03); border: 1px solid var(--border-soft);
  font-size: 12px; line-height: 1.6;
}
.codex-intel .iv-row { display: flex; gap: 6px; align-items: baseline; margin: 2px 0; color: var(--ink-dim); }
.codex-intel .iv-tag {
  flex-shrink: 0; font-size: 10.5px; letter-spacing: 2px; color: var(--gold);
  border: 1px solid rgba(201,169,106,.4); border-radius: 3px; padding: 0 5px;
}
.codex-intel .iv-move {
  display: inline-block; margin: 1px 3px 1px 0; padding: 0 6px; border-radius: 3px;
  background: rgba(10,8,6,.5); border: 1px solid var(--border); color: var(--ink-faint); font-size: 11px;
}
.codex-intel .iv-move.known { color: var(--wx-jin); border-color: rgba(216,198,144,.45); }

/* 风云榜石碑：拓印感——深底、刻字、朱砂标自己 */
.fame-stone {
  background: linear-gradient(165deg, rgba(16, 13, 10, 0.92), rgba(10, 8, 6, 0.96));
  border: 1px solid var(--border); border-radius: var(--radius);
  padding: 8px 10px; margin: 4px 0 8px;
  box-shadow: inset 0 0 24px rgba(0, 0, 0, 0.5);
}
.fame-row {
  display: flex; align-items: baseline; gap: 8px;
  padding: 5px 4px; border-bottom: 1px dashed rgba(255, 250, 240, 0.06);
  font-size: 13px; color: var(--ink-dim);
}
.fame-row:last-child { border-bottom: none; }
.fame-rank {
  flex-shrink: 0; width: 22px; height: 22px; line-height: 22px; text-align: center;
  border: 1px solid rgba(201, 169, 106, 0.35); border-radius: 3px;
  font-size: 11.5px; color: var(--gold); background: rgba(201, 169, 106, 0.06);
}
.fame-name { color: var(--ink); font-weight: 700; letter-spacing: 1px; }
.fame-title { font-size: 11.5px; color: var(--ink-faint); }
.fame-val { margin-left: auto; font-size: 12px; color: var(--gold); font-variant-numeric: tabular-nums; }
.fame-row.me { background: rgba(166, 77, 58, 0.10); border-radius: 4px; }
.fame-row.me .fame-name { color: var(--cinnabar-bright, #d4836a); }
.fame-row.dead .fame-name { text-decoration: line-through; opacity: 0.55; }
/* 夺名比斗：座次上的「战」钮——挑战即内容（手机可点 28px 高） */
.fame-duel-btn {
  flex-shrink: 0; margin-left: 6px; padding: 3px 9px; min-height: 24px;
  font-size: 11.5px; letter-spacing: 1px;
  color: var(--cinnabar-bright, #d4836a); border-color: rgba(178, 58, 50, 0.45);
}
.fame-dead {
  margin-left: 4px; font-size: 10px; color: var(--red);
  border: 1px solid rgba(178, 58, 50, 0.5); border-radius: 2px; padding: 0 3px; text-decoration: none;
  display: inline-block;
}

/* 涟漪窗口行动按钮：朱砂描边，限时机会的紧迫感 */
.btn-window {
  border-color: rgba(166, 77, 58, 0.65) !important;
  color: var(--cinnabar-bright, #d4836a) !important;
  animation: windowPulse 2.2s ease-in-out infinite;
}
.btn-window .win-left { font-size: 10.5px; opacity: 0.75; margin-left: 4px; }
@keyframes windowPulse {
  0%, 100% { box-shadow: 0 0 0 rgba(166, 77, 58, 0); }
  50% { box-shadow: 0 0 10px rgba(166, 77, 58, 0.35); }
}

/* 结识提示飘条（沿用 toast，无需额外） */

/* ============================================================
 * 云游 · 可视化大地图
 * ============================================================ */
.worldmap {
  position: relative; width: 100%; aspect-ratio: 4 / 3;
  background:
    radial-gradient(circle at 70% 25%, rgba(106,160,212,0.10), transparent 40%),
    radial-gradient(circle at 28% 78%, rgba(154,127,212,0.10), transparent 38%),
    linear-gradient(160deg, #141d24, #0e151a);
  border: 1px solid var(--border); border-radius: 10px;
  margin: 10px 0; overflow: hidden;
}
.map-lines { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.map-line { stroke: rgba(127,227,192,0.25); stroke-width: 0.4; stroke-dasharray: 1.5 1.5; }
.map-pin {
  position: absolute; transform: translate(-50%, -50%);
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  cursor: pointer; z-index: 2;
}
.map-pin .pin-dot {
  width: 14px; height: 14px; border-radius: 50%;
  background: var(--jade); box-shadow: 0 0 8px var(--jade);
  border: 2px solid #0e151a; transition: transform .1s;
}
.map-pin:hover .pin-dot { transform: scale(1.35); }
.map-pin.here .pin-dot { background: var(--gold); box-shadow: 0 0 10px var(--gold); }
.map-pin .pin-label {
  font-size: 11px; color: var(--ink); white-space: nowrap;
  background: rgba(8,12,16,0.72); padding: 1px 6px; border-radius: 6px;
}
.map-pin.here .pin-label { color: var(--gold); }
.pin-cost { color: var(--ink-dim); }
.map-pin:active .pin-dot { transform: scale(1.1); }
.map-detail {
  font-size: 13px; color: var(--ink-dim); line-height: 1.6;
  min-height: 40px; padding: 8px 10px; background: rgba(0,0,0,0.2); border-radius: 8px;
}
.map-detail b { color: var(--ink); }
/* 远行直达（E2）：新解锁的大陆节点在云游里一跳直达 */
.far-jump { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 8px; }
.far-jump-key { font-size: 12px; color: var(--gold); letter-spacing: 1px; margin-right: 2px; }
.far-jump .btn-mini { border-color: var(--gold); color: var(--gold); }

/* —— L4 宗门城·局部图（map-redesign-design.md §10.5）——
 * 云游=城/宗内据点点状图：复用据点场景作氛围底（saturate/暗压），墨 veil 罩压保钉清晰；
 * 据点 pin 点状（不加 poly，与 L3 块状/L5 单屏区分）。题头作 胥国 ▸ 七玄门 面包屑。 */
.travel-crumb { font-size: 12px; color: var(--ink-dim); letter-spacing: 1px; margin: 8px 0 -2px; }
.travel-crumb .tc-here { color: var(--gold); font-weight: 600; }
.travel-crumb .tc-tag { color: var(--ink-faint); margin-left: 8px; letter-spacing: 0; }
.worldmap.localmap { background: #0e151a; }
.worldmap.localmap .localmap-bg {
  position: absolute; inset: 0; z-index: 0;
  background-size: cover; background-position: center;
  filter: saturate(.68) brightness(.6) contrast(1.02);
}
.worldmap.localmap .localmap-veil {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    radial-gradient(circle at 50% 42%, rgba(10,14,18,.16), rgba(8,12,16,.62) 78%),
    linear-gradient(180deg, rgba(8,12,16,.30), rgba(8,12,16,.5));
}
.worldmap.localmap .map-lines { z-index: 1; }
.worldmap.localmap .map-line { stroke: rgba(232,224,205,.34); }
.worldmap.localmap .map-pin { z-index: 2; }

/* 大陆层（天南舆图）：全图早见——远方是惦记，不是迷雾 */
.worldmap.continent {
  background:
    radial-gradient(circle at 88% 38%, rgba(106,160,212,0.16), transparent 30%),
    radial-gradient(circle at 30% 30%, rgba(127,227,192,0.07), transparent 45%),
    radial-gradient(circle at 55% 80%, rgba(212,180,131,0.06), transparent 40%),
    linear-gradient(150deg, #11181f, #0c1217);
}
/* 水墨舆图模式：宣纸底图 + 云雾视差 + 墨痕 */
.worldmap.continent.inked {
  background-size: cover; background-position: center;
  aspect-ratio: 1 / 1;
  box-shadow: inset 0 0 60px rgba(60,42,20,.35), 0 2px 14px rgba(0,0,0,.5);
  border-color: rgba(120,95,60,.55);
}
.map-mist { display: none; }
.worldmap.continent.inked .map-mist {
  display: block; position: absolute; inset: -20%; pointer-events: none; z-index: 1;
  background:
    radial-gradient(ellipse 38% 16% at 24% 26%, rgba(255,255,255,.34), transparent 70%),
    radial-gradient(ellipse 46% 14% at 72% 16%, rgba(255,255,255,.26), transparent 70%),
    radial-gradient(ellipse 40% 15% at 55% 64%, rgba(255,255,255,.18), transparent 70%);
  animation: mistDrift 46s linear infinite alternate;
  filter: blur(6px);
}
.worldmap.continent.inked .map-mist.far {
  background:
    radial-gradient(ellipse 50% 18% at 80% 48%, rgba(255,255,255,.22), transparent 70%),
    radial-gradient(ellipse 36% 12% at 12% 60%, rgba(255,255,255,.20), transparent 70%);
  animation-duration: 64s; animation-direction: alternate-reverse;
}
@keyframes mistDrift {
  from { transform: translate(-3%, -1.5%); }
  to   { transform: translate(3%, 1.5%); }
}
/* 浅宣纸底上的线与钉：墨色系 */
.worldmap.continent.inked .map-line { stroke: rgba(70,55,35,.38); stroke-width: 0.5; stroke-dasharray: 1.6 1.8; }
.worldmap.continent.inked .map-line.trod {
  stroke: rgba(46,32,18,.72); stroke-width: 0.8; stroke-dasharray: none;
}
.worldmap.continent.inked .map-pin { z-index: 2; }
.worldmap.continent.inked .pin-dot {
  background: radial-gradient(circle at 35% 35%, #6e5232, #2e2012);
  border-color: rgba(244,232,208,.85);
  box-shadow: 0 0 7px rgba(46,32,18,.55);
  animation: pinBreath 3.4s ease-in-out infinite;
}
.worldmap.continent.inked .map-pin.here .pin-dot {
  background: radial-gradient(circle at 35% 35%, var(--gold-bright, #e8c66a), #7a5b1e);
  box-shadow: 0 0 12px rgba(212,170,80,.9);
}
@keyframes pinBreath { 0%,100% { box-shadow: 0 0 5px rgba(46,32,18,.4); } 50% { box-shadow: 0 0 11px rgba(46,32,18,.75); } }
.map-pin.cont.gated .pin-dot { background: #4a5560; box-shadow: 0 0 4px rgba(70,85,95,.6); animation: none; }
.map-pin.cont.gated .pin-label { color: var(--ink-faint); }
.worldmap.continent.inked .map-pin.cont.gated .pin-dot {
  background: radial-gradient(circle at 35% 35%, #9a8e7c, #5e564a); opacity: .75;
}
.map-pin.cont.silhouette .pin-dot {
  background: transparent; border: 2px dashed rgba(106,160,212,.5); box-shadow: none;
  animation: farPulse 3.2s ease-in-out infinite;
}
.map-pin.cont.silhouette .pin-label { color: rgba(106,160,212,.65); font-style: italic; }
.worldmap.continent.inked .map-pin.cont.silhouette .pin-dot { border-color: rgba(70,90,120,.55); background: transparent; }
.worldmap.continent.inked .map-pin.cont.silhouette .pin-label { color: rgba(70,90,120,.8); }
.cont-gate { margin-top: 8px; font-size: 12px; color: var(--ink-faint); }

/* ============================================================
   L3 州（v147 §10.4 → v148 去格子）：州只作分组，不再叠几何州块/州界。
   地图＝干净的城·宗点状 + 水墨底 + 州名轻量楷体题字（点题字列本州城·宗）；势力 toggle 独立（钉承势力色）。
   ============================================================ */
.pref-label {
  position: absolute; transform: translate(-50%,-50%); z-index: 4;
  font-family: "KaiTi","STKaiti","\6977\4f53",serif;
  font-size: 16px; font-weight: 600; letter-spacing: 3px;
  color: rgba(54,38,18,.82); cursor: pointer; user-select: none; pointer-events: auto;
  text-shadow: 0 1px 0 rgba(247,238,214,.92), 0 0 7px rgba(247,238,214,.8), 0 2px 5px rgba(70,48,12,.4);
  transition: color .15s, text-shadow .15s;
}
.pref-label:hover { color: rgba(40,28,12,.96); }
.pref-label.sel {
  color: #8a5f00; font-weight: 700;
  text-shadow: 0 1px 0 rgba(255,246,205,.95), 0 0 9px rgba(255,222,96,.9), 0 2px 5px rgba(95,60,0,.5);
}
/* 州志里的城宗清单按钮 */
.pref-cities { margin-top: 7px; font-size: 12px; color: var(--ink-faint); display: flex; flex-wrap: wrap; align-items: center; gap: 5px; }
.pref-city {
  background: rgba(127,180,150,.12); border: 1px solid rgba(111,174,147,.4); color: var(--jade);
  padding: 2px 8px; border-radius: 10px; cursor: pointer; font-family: inherit; font-size: 12px; transition: all .12s;
}
.pref-city:hover { background: rgba(127,180,150,.24); color: var(--jade-bright); border-color: var(--jade-bright); }

/* 舆图面包屑：人界 ▸ 天南 ▸ 越国 —— 点上一级即可上卷 */
.atlas-crumbs { display: flex; flex-wrap: wrap; align-items: center; gap: 3px; margin: -2px 0 4px; }
.atlas-crumbs .crumb {
  background: transparent; border: none; color: var(--jade); cursor: pointer;
  padding: 2px 5px; font-size: 13px; border-radius: 5px; line-height: 1.4;
}
.atlas-crumbs .crumb:hover { background: rgba(111,174,147,.16); color: var(--jade-bright); }
.atlas-crumbs .crumb.active { color: var(--gold); font-weight: 600; cursor: default; }
.atlas-crumbs .crumb-sep { color: var(--ink-faint); font-size: 11px; }
.atlas-title { margin: 2px 0; }

/* 上层舆图（人界 / 大区）：水墨云水底——暖光天际 + 云青海色 + 内阴影聚焦，远方=惦记 */
.worldmap.continent.atlas-world,
.worldmap.continent.atlas-region {
  aspect-ratio: 4 / 3;
  background:
    radial-gradient(ellipse 64% 42% at 50% 116%, rgba(212,180,131,0.11), transparent 60%),
    radial-gradient(circle at 50% 15%, rgba(106,160,212,0.17), transparent 46%),
    radial-gradient(circle at 20% 76%, rgba(127,227,192,0.09), transparent 46%),
    radial-gradient(circle at 82% 66%, rgba(154,127,212,0.10), transparent 42%),
    linear-gradient(155deg, #0f1d27, #0a1015);
  box-shadow: inset 0 0 70px rgba(0,0,0,0.5);
}
.worldmap.continent.atlas-painted {
  aspect-ratio: 3 / 2;
  background-size: cover; background-position: center;
  border-color: rgba(202,176,96,.62);
  box-shadow: inset 0 0 34px rgba(28,64,80,.24), inset 0 0 68px rgba(255,245,190,.16), 0 2px 18px rgba(0,0,0,.42);
}
.worldmap.continent.atlas-painted::before {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 0;
  background:
    radial-gradient(ellipse 36% 22% at 88% 30%, rgba(255,236,165,.18), transparent 68%),
    radial-gradient(ellipse 40% 24% at 50% 76%, rgba(35,82,91,.16), transparent 72%),
    linear-gradient(180deg, rgba(255,255,255,.04), rgba(30,80,95,.08));
}
.worldmap.continent.atlas-world .map-mist,
.worldmap.continent.atlas-region .map-mist {
  display: block; position: absolute; inset: -20%; pointer-events: none; z-index: 1;
  background:
    radial-gradient(ellipse 40% 16% at 28% 30%, rgba(180,210,235,.20), transparent 70%),
    radial-gradient(ellipse 46% 14% at 70% 22%, rgba(180,210,235,.16), transparent 70%),
    radial-gradient(ellipse 40% 15% at 55% 70%, rgba(180,210,235,.12), transparent 70%);
  animation: mistDrift 46s linear infinite alternate; filter: blur(7px);
}
.worldmap.continent.atlas-world .map-mist.far,
.worldmap.continent.atlas-region .map-mist.far {
  background:
    radial-gradient(ellipse 50% 18% at 82% 52%, rgba(160,195,225,.16), transparent 70%),
    radial-gradient(ellipse 36% 12% at 12% 62%, rgba(160,195,225,.14), transparent 70%);
  animation-duration: 64s; animation-direction: alternate-reverse;
}
/* 上层可达节点（天南 / 越国）：青玉钉，醒目可点 */
.worldmap.continent.atlas-world .map-pin:not(.silhouette):not(.gated) .pin-dot,
.worldmap.continent.atlas-region .map-pin:not(.silhouette):not(.gated) .pin-dot {
  background: radial-gradient(circle at 35% 35%, var(--jade-bright), var(--jade));
  border-color: rgba(8,16,12,.85); box-shadow: 0 0 10px rgba(127,227,192,.7);
  animation: pinBreath 3.4s ease-in-out infinite;
}

/* —— v143 区块化舆图：占位多边形 + 解锁三态（map-redesign-design.md §3）—— */
.worldmap .region-blocks {
  position: absolute; inset: 0; width: 100%; height: 100%;
  z-index: 3; pointer-events: none; overflow: visible;
}
.region-block {
  pointer-events: auto; cursor: pointer;
  vector-effect: non-scaling-stroke; stroke-width: 1.1; stroke-linejoin: round;
  transition: fill .5s ease, stroke .5s ease, filter .4s ease, opacity .4s ease;
}
/* 暗/雾：道途未通——远岛沉雾，淡而虚，自然隐退（去叠压感）*/
.region-block.locked {
  fill: rgba(150,170,185,0.045); stroke: rgba(150,170,185,0.22);
  stroke-dasharray: 1.4 2.2; opacity: .68;
}
.region-block.locked:hover { fill: rgba(160,180,195,0.10); stroke: rgba(175,195,210,0.42); opacity: .92; }
/* 亮起：已点亮·可下钻——青玉陆域，温润透光 */
.region-block.lit {
  fill: rgba(127,227,192,0.13); stroke: rgba(127,227,192,0.62); stroke-dasharray: none;
  filter: drop-shadow(0 0 3px rgba(127,227,192,0.35));
}
.region-block.lit:hover { fill: rgba(127,227,192,0.22); stroke: var(--jade-bright); }
/* 当前·在此：金陆，描金海岸 + 呼吸光晕 */
.region-block.here {
  fill: rgba(212,175,84,0.16); stroke: var(--gold); stroke-width: 1.5; stroke-dasharray: none;
  filter: drop-shadow(0 0 5px rgba(212,175,84,0.75));
  animation: blockBreath 3.6s ease-in-out infinite;
}
.worldmap.atlas-painted .region-block { stroke-width: 1.35; }
/* 未解锁：整体压暗成剪影，只透出轮廓（其上再覆一层漂浮薄雾，见 .cloud-shroud）*/
.worldmap.atlas-painted .region-block.locked {
  fill: rgba(7,12,20,.82); stroke: rgba(176,200,221,.62); opacity: 1;
  stroke-dasharray: none; filter: none;
}
.worldmap.atlas-painted .region-block.locked:hover {
  fill: rgba(16,38,55,.46); stroke: rgba(124,182,216,.95);
}
.worldmap.atlas-painted .region-block.lit {
  fill: rgba(61,215,178,.16); stroke: rgba(28,188,145,.90);
  filter: drop-shadow(0 0 7px rgba(38,212,170,.55)) drop-shadow(0 2px 5px rgba(0,70,85,.22));
}
.worldmap.atlas-painted .region-block.lit:hover { fill: rgba(61,215,178,.24); stroke: #4af0c4; }
.worldmap.atlas-painted .region-block.here {
  fill: rgba(255,215,80,.20); stroke: #ffe79c; stroke-width: 1.75;
  filter: drop-shadow(0 0 8px rgba(255,217,74,.92)) drop-shadow(0 4px 8px rgba(88,58,0,.32));
}
@keyframes blockBreath {
  0%,100% { filter: drop-shadow(0 0 4px rgba(212,175,84,0.58)); }
  50%     { filter: drop-shadow(0 0 12px rgba(255,219,86,1)); }
}
/* 题字：块中心锚点，退化系统楷体（§4；v144 接 webfont）*/
.block-label {
  position: absolute; transform: translate(-50%,-50%); z-index: 3;
  cursor: pointer; white-space: nowrap; font-size: 14px; letter-spacing: 1px;
  font-family: "KaiTi","STKaiti","\6977\4f53",serif;
  text-shadow: 0 1px 3px rgba(0,0,0,0.85), 0 0 6px rgba(0,0,0,0.7);
  pointer-events: auto; user-select: none;
}
.block-label.locked { color: rgba(176,192,205,0.55); font-style: italic; font-size: 13px; }
.block-label.lit    { color: var(--ink); }
.block-label.here   { color: var(--gold-bright); font-weight: 600; }
.worldmap.atlas-painted .block-label {
  z-index: 5; font-size: 15px; color: rgba(31,63,78,.82);
  text-shadow: 0 1px 0 rgba(255,255,255,.9), 0 0 6px rgba(255,255,255,.78), 0 2px 5px rgba(18,58,75,.45);
}
.worldmap.atlas-painted .block-label.locked {
  color: rgba(198,212,228,.5); font-size: 13px;
  text-shadow: 0 1px 3px rgba(0,0,0,.85), 0 0 5px rgba(0,0,0,.7);
}
.worldmap.atlas-painted .block-label.here {
  color: #8a5f00; font-weight: 700;
  text-shadow: 0 1px 0 rgba(255,246,205,.95), 0 0 8px rgba(255,226,96,.92), 0 2px 5px rgba(95,60,0,.5);
}
.block-label .here-tag { color: var(--gold); font-size: 12px; }

/* ============================================================
   v146 势力叠加层（§9）：贯穿 L1/L2/L3 的可开关「政治概览」染色层。
   低饱和水墨六色——既作 L2 区块填充，也作 L3 宗门钉与图例色样。
   红线：动态/纪元驱动（class 由 UI.factionAt(node,epoch) 投影），不留虚影。
   ============================================================ */
:root {
  --fac-qipai:    #4f9a7c;  /* 七派·青绿 */
  --fac-zhengdao: #b89a52;  /* 正道盟·金 */
  --fac-modao:    #944f80;  /* 魔道·绛紫 */
  --fac-jiuguo:   #a86838;  /* 九国盟·赭橙 */
  --fac-tiandao:  #4f7c9c;  /* 天道盟·天青 */
  --fac-mulan:    #8a925a;  /* 慕兰·草黄绿 */
}
/* 开启政治概览：薄雾/云罩让位于色块，未解锁块也显色（看清「谁控制哪」）*/
.worldmap.show-factions .cloud-shroud { display: none; }
.worldmap.show-factions .map-mist { opacity: .3; }
/* 中性化三态填充——让势力色主导；无归属（原色）国显出地形（原色），不再压暗成剪影。
   注：须叠 .atlas-painted 以盖过 .worldmap.atlas-painted .region-block.locked/.lit/.here（同 (0,4,0)，靠后取胜）。*/
.worldmap.atlas-painted.show-factions .region-block,
.worldmap.show-factions .region-block {
  fill: rgba(150,165,180,.05); stroke: rgba(184,200,214,.34);
  stroke-dasharray: none; opacity: 1; filter: none;
}
.worldmap.atlas-painted.show-factions .region-block.faction-qipai,
.worldmap.show-factions .region-block.faction-qipai    { fill: rgba(79,154,124,.34); stroke: var(--fac-qipai); }
.worldmap.atlas-painted.show-factions .region-block.faction-zhengdao,
.worldmap.show-factions .region-block.faction-zhengdao { fill: rgba(184,154,82,.42); stroke: var(--fac-zhengdao); }
.worldmap.atlas-painted.show-factions .region-block.faction-modao,
.worldmap.show-factions .region-block.faction-modao    { fill: rgba(148,79,128,.34); stroke: var(--fac-modao); }
.worldmap.atlas-painted.show-factions .region-block.faction-jiuguo,
.worldmap.show-factions .region-block.faction-jiuguo   { fill: rgba(168,104,56,.42); stroke: var(--fac-jiuguo); }
.worldmap.atlas-painted.show-factions .region-block.faction-tiandao,
.worldmap.show-factions .region-block.faction-tiandao  { fill: rgba(79,124,156,.36); stroke: var(--fac-tiandao); }
.worldmap.atlas-painted.show-factions .region-block.faction-mulan,
.worldmap.show-factions .region-block.faction-mulan    { fill: rgba(138,146,90,.42); stroke: var(--fac-mulan); }
/* 势力块都加粗色描边，在低饱和水墨填充上仍能清晰划出领地界线 */
.worldmap.atlas-painted.show-factions .region-block[class*="faction-"],
.worldmap.show-factions .region-block[class*="faction-"] { stroke-width: 1.9; }
.worldmap.show-factions .region-block:hover { filter: drop-shadow(0 0 4px rgba(255,255,255,.35)); }
/* 仍标出「我在此」：金描边覆于势力色之上（置于势力规则之后，同 (0,5,0) 靠后取胜）*/
.worldmap.atlas-painted.show-factions .region-block.here,
.worldmap.show-factions .region-block.here {
  stroke: var(--gold); stroke-width: 1.8;
  filter: drop-shadow(0 0 6px rgba(212,175,84,.7));
}

/* —— L3 宗门级：水墨钉染色（宗门=可访问/远观节点，按七派六宗归属着色）——
   须达 (0,8,0) 以盖过 .worldmap.continent.inked .map-pin.cont.silhouette/.gated .pin-dot (0,7,0)；
   填实色钉 + 实描边（覆盖 silhouette 的虚线），开关关闭即恢复远观虚钉。*/
.worldmap.continent.inked.show-factions .map-pin.cont.faction-qipai    .pin-dot { background: var(--fac-qipai);    box-shadow: 0 0 8px var(--fac-qipai);    border: 2px solid rgba(244,232,208,.85); opacity: 1; animation: none; }
.worldmap.continent.inked.show-factions .map-pin.cont.faction-zhengdao .pin-dot { background: var(--fac-zhengdao); box-shadow: 0 0 8px var(--fac-zhengdao); border: 2px solid rgba(244,232,208,.85); opacity: 1; animation: none; }
.worldmap.continent.inked.show-factions .map-pin.cont.faction-modao    .pin-dot { background: var(--fac-modao);    box-shadow: 0 0 8px var(--fac-modao);    border: 2px solid rgba(244,232,208,.85); opacity: 1; animation: none; }
.worldmap.continent.inked.show-factions .map-pin.cont.faction-jiuguo   .pin-dot { background: var(--fac-jiuguo);   box-shadow: 0 0 8px var(--fac-jiuguo);   border: 2px solid rgba(244,232,208,.85); opacity: 1; animation: none; }
.worldmap.continent.inked.show-factions .map-pin.cont.faction-tiandao  .pin-dot { background: var(--fac-tiandao);  box-shadow: 0 0 8px var(--fac-tiandao);  border: 2px solid rgba(244,232,208,.85); opacity: 1; animation: none; }
.worldmap.continent.inked.show-factions .map-pin.cont.faction-mulan    .pin-dot { background: var(--fac-mulan);    box-shadow: 0 0 8px var(--fac-mulan);    border: 2px solid rgba(244,232,208,.85); opacity: 1; animation: none; }
/* 旧址/废墟态（黄枫谷旧址等）：灰白虚框、删除线，盖过势力色 */
.map-pin.cont.ruin .pin-dot {
  background: transparent !important; border: 2px dotted rgba(176,166,154,.75) !important;
  box-shadow: none !important; animation: none !important;
}
.map-pin.cont.ruin .pin-label { color: rgba(176,166,154,.85); font-style: italic; text-decoration: line-through; }

/* —— 势力图例（图下方）—— */
.faction-legend {
  margin: 8px 0 4px; padding: 8px 11px; font-size: 12px;
  background: rgba(0,0,0,.24); border: 1px solid var(--border); border-radius: 8px;
}
.fac-epoch { color: var(--gold); letter-spacing: 1px; margin-bottom: 6px; }
.fac-items { display: flex; flex-wrap: wrap; gap: 6px 12px; }
.fac-item { display: inline-flex; align-items: center; gap: 5px; color: var(--ink); }
.fac-swatch {
  display: inline-block; width: 12px; height: 12px; border-radius: 3px;
  border: 1px solid rgba(255,255,255,.25);
}
.fac-swatch.faction-qipai    { background: var(--fac-qipai); }
.fac-swatch.faction-zhengdao { background: var(--fac-zhengdao); }
.fac-swatch.faction-modao    { background: var(--fac-modao); }
.fac-swatch.faction-jiuguo   { background: var(--fac-jiuguo); }
.fac-swatch.faction-tiandao  { background: var(--fac-tiandao); }
.fac-swatch.faction-mulan    { background: var(--fac-mulan); }
.fac-note { margin-top: 6px; color: var(--ink-dim); line-height: 1.55; }
/* 「势力」开关按钮（开=金高亮）*/
.btn.fac-toggle.on { color: var(--gold); border-color: var(--gold); box-shadow: 0 0 6px rgba(212,175,84,.4); }

/* —— v145 未解锁薄雾：两层分形噪声雾裁进未解锁块并集，缓缓反向漂移（动效）—— */
.cloud-shroud { pointer-events: none; }
.cloud-shroud .fog-drift { will-change: transform; transform-box: view-box; }
.cloud-shroud .fog-drift.a { animation: atlasFogDriftA 42s ease-in-out infinite; opacity: .85; }
.cloud-shroud .fog-drift.b { animation: atlasFogDriftB 60s ease-in-out infinite; opacity: .62; }
@keyframes atlasFogDriftA {
  0%,100% { transform: translate(-6px, 2px); }
  50%     { transform: translate(6px, -3px); }
}
@keyframes atlasFogDriftB {
  0%,100% { transform: translate(5px, -2px); }
  50%     { transform: translate(-7px, 3px); }
}
@media (prefers-reduced-motion: reduce) {
  .cloud-shroud .fog-drift { animation: none !important; }
}

/* 宽幅弹窗（舆图）*/
.modal.modal-wide { max-width: 720px; width: 94vw; }

/* ============================================================
 * 功法配装界面
 * ============================================================ */
.tech-aux { font-size: 11px; color: var(--blue); border: 1px solid var(--blue); border-radius: 8px; padding: 0 6px; margin-left: 6px; }
.tech-grade { font-size: 11px; color: var(--gold); margin-left: auto; }
.tech-skills { font-size: 12px; color: var(--ink-dim); margin-top: 4px; }
.tech-btns { display: flex; gap: 6px; margin-top: 8px; flex-wrap: wrap; }
.btn-mini.ghost { background: transparent; border: 1px solid var(--border); }

.skill-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap: 8px; margin: 8px 0; }
.skill-chip {
  background: rgba(0,0,0,0.22); border: 1px solid var(--border); border-radius: 8px;
  padding: 8px; cursor: pointer; transition: transform .08s, border-color .12s, background .12s;
}
.skill-chip:hover { border-color: var(--jade); }
.skill-chip:active { transform: scale(0.96); }
.skill-chip.on { border-color: var(--gold); background: rgba(212,170,90,0.12); }
.sk-top { display: flex; align-items: center; gap: 4px; font-size: 13px; }
.sk-aux { font-size: 10px; color: var(--blue); border: 1px solid var(--blue); border-radius: 6px; padding: 0 3px; }
.sk-on { font-size: 10px; color: var(--gold); margin-left: auto; }
.sk-meta { font-size: 11px; color: var(--ink-dim); margin-top: 4px; }

/* 研习功法（闭关）按钮组 */
.study-list { display: flex; flex-direction: column; gap: 8px; margin: 8px 0; }
.study-item { display: flex; align-items: center; justify-content: space-between; gap: 8px;
  background: rgba(0,0,0,0.2); border: 1px solid var(--border); border-radius: 8px; padding: 8px 10px; }
.study-item .si-name { font-weight: 600; }
.study-item .si-meta { font-size: 12px; color: var(--ink-dim); }

/* ============================================================
 * 移动速度条（云游）
 * ============================================================ */
.speed-bar { display: flex; align-items: center; gap: 8px; margin: 8px 0 12px; font-size: 13px; }
.speed-key { color: var(--ink-dim); }
.speed-val { color: var(--gold-bright); font-weight: 700; font-size: 16px; }
.speed-mount { margin-left: auto; color: var(--blue); border: 1px solid var(--blue); border-radius: 10px; padding: 1px 10px; font-size: 12px; }
.speed-breakdown { color: var(--ink-dim); font-size: 11px; }

/* ============================================================
 * 据点 · 在场人物：透明底立绘"站"在场景下沿（点击开交互轮盘）
 * ============================================================ */
.locals {
  position: absolute; z-index: 5; pointer-events: none;
  left: 306px; right: 396px; bottom: 25vh;
  display: flex; align-items: flex-end; justify-content: center; gap: 26px;
}
.locals-title { display: none; }
.local-npc {
  pointer-events: auto; cursor: pointer; position: relative;
  display: flex; flex-direction: column; align-items: center;
  transition: transform .18s ease, filter .18s ease;
  filter: drop-shadow(0 10px 16px rgba(0,0,0,.55));
}
.local-npc:hover { transform: translateY(-5px); }
.local-npc:active { transform: translateY(-2px) scale(.98); }
.ln-figure { display: block; height: clamp(110px, 19vh, 180px); line-height: 0; }
.ln-figure img {
  height: 100%; width: auto; display: block;
  -webkit-user-drag: none; user-select: none;
}
.local-npc.unmet .ln-figure img { filter: brightness(.12) saturate(0); opacity: .85; }
.ln-figure.no-img {
  height: auto; width: 52px; aspect-ratio: 1; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; font-size: 26px; line-height: 1;
  background: radial-gradient(circle at 50% 35%, rgba(143,214,180,.18), var(--bg-panel) 75%);
  border: 1px solid var(--border-soft); margin-bottom: 4px;
}
.ln-plate {
  margin-top: 3px; padding: 2px 10px; border-radius: 3px;
  background: rgba(10, 8, 6, .68); border: 1px solid var(--border-soft);
  color: #ece5d6; font-size: 12.5px; letter-spacing: 1px; white-space: nowrap;
  text-shadow: 0 1px 3px rgba(0,0,0,.9); backdrop-filter: blur(2px);
}
.ln-plate .lr { color: var(--gold); font-size: 10.5px; margin-left: 5px; }
.local-npc:hover .ln-plate { border-color: var(--jade); color: var(--jade-bright); }

/* 兼容旧列表样式引用（弹窗等处）*/
.local-avatar {
  width: 30px; height: 30px; border-radius: 50%; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center; font-size: 16px;
  background: linear-gradient(135deg, var(--bg-panel-2), var(--bg-panel)); border: 1px solid var(--border);
}
.local-info { flex: 1; min-width: 0; }
.local-name { color: var(--jade-bright); font-size: 14px; }
.local-name .lr { color: var(--gold); font-size: 11px; margin-left: 6px; }
.local-line { color: var(--ink-dim); font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.local-talk { color: var(--ink-dim); font-size: 18px; }

/* ============================================================
 * 内嵌大地图（所在面板）
 * ============================================================ */
.loc-map { margin-top: 10px; }
.loc-map-head { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.map-tag { font-size: 11px; letter-spacing: 2px; color: var(--gold); background: var(--bg); padding: 1px 8px; border-radius: 10px; }
.map-speed { font-size: 11px; color: var(--ink-dim); }
.worldmap.inline {
  position: relative; width: 100%; aspect-ratio: 5 / 2; max-height: 190px;
  background:
    radial-gradient(circle at 70% 25%, rgba(106,160,212,0.10), transparent 42%),
    radial-gradient(circle at 28% 78%, rgba(154,127,212,0.10), transparent 40%),
    linear-gradient(160deg, #141d24, #0e151a);
  border: 1px solid var(--border); border-radius: 10px; overflow: hidden;
}
.worldmap.inline .pin-label { font-size: 10px; }
.worldmap.inline .map-pin .pin-dot { width: 13px; height: 13px; }
.worldmap.inline .map-pin.home .pin-dot { background: var(--gold); box-shadow: 0 0 8px var(--gold); }
.worldmap.inline .map-pin.here .pin-dot { background: #ff3b3b; box-shadow: 0 0 8px #ff3b3b; }
.worldmap.inline .map-pin.here .pin-label { color: #ff8a8a; }
.worldmap.inline .map-pin.selected .pin-dot { transform: scale(1.5); box-shadow: 0 0 12px var(--jade-bright); outline: 2px solid var(--jade-bright); }
.worldmap.inline .map-pin.selected .pin-label { color: var(--jade-bright); font-weight: 600; }
.map-confirm {
  display: flex; align-items: center; gap: 10px; margin-top: 8px;
  padding: 10px 12px; background: rgba(95,184,154,.08); border: 1px solid var(--jade); border-radius: 8px;
  animation: fadein .2s ease;
}
.map-confirm .mc-info { flex: 1 1 auto; min-width: 0; }
.map-confirm .mc-info b { color: var(--jade-bright); display: block; font-size: 14px; }
.map-confirm .mc-info span { color: var(--ink-dim); font-size: 12px; display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.map-confirm .btn { flex: 0 0 auto; white-space: nowrap; }

/* ============================================================
 * 开战横幅（遭遇/决战/渡劫的醒目起始提示）
 * ============================================================ */
.combat-banner {
  position: absolute; left: 50%; top: 38%;
  transform: translate(-50%, -50%); z-index: 160; text-align: center;
  pointer-events: none; opacity: 0;
}
.combat-banner.show { animation: cbIn 1.6s cubic-bezier(.2,.8,.2,1) forwards; }
.combat-banner .cb-title {
  font-size: clamp(28px, 7vw, 52px); font-weight: 800; letter-spacing: 10px;
  text-shadow: 0 4px 24px rgba(0,0,0,.7);
}
.combat-banner .cb-sub { margin-top: 8px; font-size: 14px; letter-spacing: 3px; color: var(--ink); opacity: .9; }
.combat-banner.b-red .cb-title { color: #ff6b6b; }
.combat-banner.b-purple .cb-title { color: #c39bf0; }
.combat-banner.b-gold .cb-title { color: var(--gold-bright); }
.combat-banner.b-jade .cb-title { color: var(--jade-bright); }
@keyframes cbIn {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(1.3); letter-spacing: 24px; }
  18% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
  78% { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, -56%) scale(.98); }
}

/* ============================================================
 * 实时对话（活世界）
 * ============================================================ */
.talk-convo {
  max-height: 42vh; overflow-y: auto; margin: 10px 0; padding: 4px 2px;
  border-top: 1px solid var(--border); border-bottom: 1px solid var(--border);
}
.talk-convo .dlg-row { margin: 8px 0; }
.talk-options { display: flex; flex-direction: column; gap: 8px; margin-top: 6px; }
.talk-options .choice { animation: choiceIn .25s ease backwards; }
.talk-thinking {
  color: var(--ink-dim); font-size: 13px; text-align: center; padding: 12px;
  letter-spacing: 2px; animation: pulse 1.2s ease-in-out infinite;
}
@keyframes pulse { 0%,100% { opacity: .5; } 50% { opacity: 1; } }

/* 对谈机制结果提示横幅 */
.talk-effect {
  margin: 8px 0 4px; padding: 8px 12px;
  background: rgba(212,175,110,.12); border-left: 3px solid var(--gold);
  border-radius: 4px; color: var(--gold); font-size: 13px; line-height: 1.5;
  animation: choiceIn .3s ease backwards;
}
/* 际遇栏：交付按钮 */
.obj-deliver {
  margin-left: 8px; padding: 2px 10px; font-size: 12px; cursor: pointer;
  background: var(--gold); color: #1a1208; border: none; border-radius: 4px;
  font-family: inherit;
}
.obj-deliver:hover { filter: brightness(1.1); }

/* ============================================================
 * 配图层（art.js）：立绘 / 场景图样式
 * ============================================================ */
/* 韩立角色卡立绘 */
.hero-portrait { overflow: hidden; cursor: pointer; }
.hero-portrait img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* —— v213 韩立换装窗口 —— */
.skin-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px;
  margin: 6px 0 4px; max-height: 64vh; overflow-y: auto;
}
.skin-card {
  background: var(--bg-panel-2); border: 1px solid var(--border); border-radius: 10px;
  padding: 8px 6px 9px; cursor: pointer; text-align: center;
  transition: transform .08s ease, border-color .12s ease, box-shadow .12s ease;
}
.skin-card:active { transform: scale(0.96); }
.skin-card:hover { border-color: var(--jade); }
.skin-card.selected { border-color: var(--jade-bright); box-shadow: 0 0 10px rgba(95,184,154,.4); }
.skin-pic {
  position: relative; width: 100%; aspect-ratio: 3 / 4; border-radius: 8px; overflow: hidden;
  display: flex; align-items: center; justify-content: center; font-size: 32px;
  background: radial-gradient(circle at 50% 30%, rgba(127,227,192,.18), #11171d 74%);
}
.skin-pic img { width: 100%; height: 100%; object-fit: cover; object-position: top center; display: block; }
.skin-auto .skin-pic { font-size: 30px; }
.skin-cur {
  position: absolute; top: 4px; right: 4px; font-size: 10px; line-height: 1;
  padding: 2px 5px; border-radius: 6px; color: #11171d;
  background: var(--jade-bright); font-weight: 700;
}
.skin-name { margin-top: 6px; font-size: 12px; color: var(--ink); }
.skin-card.selected .skin-name { color: var(--jade-bright); }
@media (max-width: 520px) { .skin-grid { grid-template-columns: repeat(2, 1fr); } }

/* 在场人物头像 */
.local-avatar { overflow: hidden; }
.local-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* 对话肖像（有图时去掉文字底色，铺满圆形） */
.dlg-portrait { overflow: hidden; }
.dlg-portrait.has-img { background: none; }
.dlg-portrait img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* 场景配图：所在地点头图 */
.loc-scene {
  width: 100%; border-radius: 8px; overflow: hidden; margin-bottom: 10px;
  border: 1px solid var(--border); position: relative; line-height: 0;
  animation: sceneFade .32s ease;
}
.loc-scene img {
  width: 100%; height: 130px; object-fit: cover; object-position: center 35%;
  display: block; background: #0c0a08; filter: saturate(.95);
}
.loc-scene::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, transparent 55%, rgba(20,16,12,.45) 100%);
  pointer-events: none;
}
@keyframes sceneFade { from { opacity: 0; } to { opacity: 1; } }

/* ============================================================
 * 剧情演出（视觉小说式：大立绘 + 逐句推进）
 * ============================================================ */
.story-overlay {
  position: fixed; inset: 0; z-index: 200;
  display: flex; flex-direction: column; justify-content: flex-end;
  background: #0c0a08; overflow: hidden;
  animation: storyFadeIn .4s ease;
}
@keyframes storyFadeIn { from { opacity: 0; } to { opacity: 1; } }

/* 演出远景视差面（B1·演出态多平面）：与背景同图但"推远"——更糊更暗更大；
 * 镜头 pan/zoom 时由 cutscene._cam 以更小幅度位移/缩放（背景全幅、远景减幅），
 * 于背景层移动时在边缘"露出"＝一次推镜里的纵深差速视差（aerial perspective）。
 * 静止态被不透明的背景层完全盖住＝零观感变化；仅演出态(.on)点亮，旁白单层零回归。
 * inset 略负 + 基准放大 1.08：pan 时不露黑边。真·切图分层就位后可在其上叠 layers。 */
.story-far {
  position: absolute; inset: -7%; background-size: cover; background-position: center;
  opacity: 0; transition: opacity .5s ease;
  /* v314：血泪修——3px 轻虚化在竖屏信箱边带上像"同图叠三份"（山叠山极出戏）。
     重虚化+重压暗+提饱和降度：边带读作氛围底色，不再与主图抢内容。桌面横屏被主图全盖=零回归。 */
  filter: saturate(.5) brightness(.32) blur(16px);
  transform: scale(1.12);
  will-change: transform; backface-visibility: hidden; pointer-events: none;
  z-index: 0;
}
.story-far.on { opacity: 1; }
/* 场景背景（虚化压暗，做氛围）*/
.story-bg {
  position: absolute; inset: 0; background-size: cover; background-position: center;
  /* v314：no-repeat 必写——竖屏信箱式 contain 下缺省 repeat 会把同图在上下边带平铺成"三座山叠罗汉" */
  background-repeat: no-repeat;
  opacity: 0; transition: opacity .4s ease;
  filter: saturate(.9) brightness(.62);
  will-change: transform; backface-visibility: hidden;
  z-index: 1;
}
/* kenBurns 收敛到 1.04→1.0：保留推镜电影感，终态回到原始分辨率（不糊） */
.story-bg.on { opacity: 1; animation: kenBurns 14s ease-out forwards; }
@keyframes kenBurns { from { transform: scale(1.04); } to { transform: scale(1.0); } }
/* 手机/竖屏·CG 信箱式呈现：完整图 contain 不裁，story-far（同图·模糊压暗版）填满边带。
   根因：批量 _p「竖版」多为方图 1024²，超窄竖屏（如 430×932）用 cover 居中会裁掉近半宽度、主体常被切；
   contain＋自身模糊填充＝全貌保留、无黑条、留白氛围。仅竖屏生效，桌面横屏 cover 不变（far 被全盖＝零回归）。 */
@media (orientation: portrait) {
  .story-bg { background-size: contain; }
}
/* 近 9:16 的竖版 CG 仍走 cover 全出血（JS 测图比后挂 .cg-fill）——裁切极小、沉浸感更强；
   方图/横图无此类＝保持 contain 信箱式不裁主体。桌面横屏 .story-bg 本就 cover，此类无害。 */
.story-bg.cg-fill { background-size: cover; }
.story-scrim {
  position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(12,10,8,.55) 0%, rgba(12,10,8,.1) 35%, rgba(12,10,8,.4) 70%, rgba(12,10,8,.92) 100%);
}

/* 阶段标题：左上角小字 */
.story-stage-name {
  position: absolute; top: 22px; left: 26px; z-index: 3;
  color: var(--gold); font-size: 15px; letter-spacing: 3px;
  text-shadow: 0 2px 8px rgba(0,0,0,.8);
  border-left: 3px solid var(--gold); padding-left: 10px;
}

/* 转场题字卡：黑场大字 + 朱砂印（番剧分集卡）*/
.story-titlecard {
  position: absolute; inset: 0; z-index: 10;
  display: flex; align-items: center; justify-content: center;
  background: #070605; cursor: pointer;
  opacity: 0; pointer-events: none; transition: opacity .5s ease;
}
.story-titlecard.show { opacity: 1; pointer-events: auto; }
.story-titlecard .tc-frame {
  position: relative; padding: 26px 54px;
  border-top: 1px solid rgba(201,169,106,.5); border-bottom: 1px solid rgba(201,169,106,.5);
  animation: tcIn 1.1s cubic-bezier(.2,.8,.2,1) both;
}
@keyframes tcIn {
  from { opacity: 0; letter-spacing: 18px; transform: scale(1.04); }
  to   { opacity: 1; transform: scale(1); }
}
.story-titlecard .tc-title {
  color: #efe7d2; font-size: clamp(26px, 5.6vw, 44px); font-weight: 700;
  letter-spacing: 12px; text-shadow: 0 4px 28px rgba(0,0,0,.8); text-align: center;
}
.story-titlecard .tc-seal {
  position: absolute; right: 8px; bottom: 6px;
  width: 30px; height: 30px; line-height: 1.05;
  background: var(--cinnabar); color: #f3e4d8;
  font-size: 12px; letter-spacing: 0; padding: 3px 4px 0;
  border-radius: 2px; writing-mode: vertical-rl; text-orientation: upright;
  box-shadow: 0 2px 8px rgba(0,0,0,.5); opacity: .92;
}

/* 大立绘：双人相对而立，半身像从底部升起；说话者亮、另一人暗淡 */
.story-portrait {
  position: absolute; bottom: 0; z-index: 2;
  height: 78%; max-height: 620px; pointer-events: none;
  opacity: 0; transition: opacity .3s ease, filter .3s ease, transform .3s ease;
}
/* 注意：动画不用 both/backwards 填充——若动画因时序未启动，元素须回落到自然可见态
   （修复"第二次进入剧情/战斗立绘不显示"：卡在 from 的 opacity:0） */
.story-portrait img { height: 100%; width: auto; object-fit: contain; display: block;
  filter: drop-shadow(0 6px 24px rgba(0,0,0,.6));
  animation: portraitIn .36s cubic-bezier(.22,1,.36,1); }
.story-portrait.left img { animation-name: portraitInL; }
@keyframes portraitIn  { from { opacity: 0; transform: translateX(26px) translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes portraitInL { from { opacity: 0; transform: translateX(-26px) translateY(8px); } to { opacity: 1; transform: none; } }
.story-portrait.on { opacity: 1; }
/* 暗淡：未说话的一方→压暗去饱和退后（不虚化——立绘必须清晰）*/
.story-portrait.dim { opacity: .96; }
.story-portrait.dim img { filter: brightness(.55) saturate(.65) drop-shadow(0 4px 16px rgba(0,0,0,.5)); }
.story-portrait.left  { left: -7%;  transform: scaleX(-1); }   /* 左侧人物镜像，面朝右（朝向主角）；负值抵销抠图透明边 */
.story-portrait.right { right: -7%; }
.story-portrait.left.dim  { transform: scaleX(-1) scale(.97); }
.story-portrait.right.dim { transform: scale(.97); }
/* 立绘 idle 微动（§9-2 立绘微动）：在 .story-portrait（外层＝进退/震/scaleX 镜像）与 img（entrance/emoPop）
 * 之间插一层 .pb 作"呼吸"——慢循环、微幅、transform-origin 落在脚底（脚不动＝活人站在地上）。
 * 三者动画分属不同元素，transform 各管各、自然叠加、互不覆盖：外层震屏/进退、.pb 呼吸、img 入场/表情。
 * 守 IP 红线：只微幅起伏（≤1.2% 缩放、≤0.55% 位移、≤0.22° 摆），不碰大幅人物动作；
 * 左右错速避免双人"同呼吸"的诡异同步；prefers-reduced-motion 时停（无障碍）。 */
.story-portrait .pb {
  height: 100%; display: inline-block; vertical-align: bottom;
  transform-origin: 50% 100%; will-change: transform;
}
.story-portrait.on .pb { animation: portraitBreath 3.8s ease-in-out infinite; }
.story-portrait.right.on .pb { animation-duration: 4.3s; }
@keyframes portraitBreath {
  0%, 100% { transform: translateY(0) scaleY(1) rotate(0deg); }
  50%      { transform: translateY(-0.55%) scaleY(1.012) rotate(.22deg); }
}
@media (prefers-reduced-motion: reduce) { .story-portrait .pb { animation: none; } }

/* 对话框：底部一条，轻触推进 */
.story-dialog {
  position: relative; z-index: 4; margin: 0 auto; width: min(860px, 94%);
  background: rgba(14, 11, 9, .96); border: 1px solid rgba(212,176,106,.35);
  border-radius: 6px 6px 0 0; border-bottom: none;
  padding: 20px 26px 30px; cursor: pointer;
  box-shadow: 0 -8px 40px rgba(0,0,0,.55); backdrop-filter: blur(4px);
}
.story-speaker { min-height: 22px; margin-bottom: 6px; }
.story-speaker .sp-name {
  color: var(--gold-bright); font-size: 18px; letter-spacing: 2px; font-weight: 600;
}
.story-speaker .sp-name.aside { color: var(--blue); }
.story-text { color: var(--ink); font-size: 17px; line-height: 1.9; min-height: 56px; }
.story-line { animation: storyLineIn .35s ease backwards; display: inline-block; }
@keyframes storyLineIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }
.story-line.narr { color: var(--ink-dim); }
.story-line.aside { color: #9fc8e8; font-style: italic; }
/* 因果有报·远雷呈现：金句先声夺人（沉浸式呈现 settleLedger 的兑现，不再埋日志） */
.story-line.story-echo {
  color: var(--gold); font-weight: 600; line-height: 1.85;
  padding-left: 11px; border-left: 3px solid var(--gold);
  text-shadow: 0 0 8px rgba(212,175,120,.25);
}
.story-cue {
  position: absolute; right: 22px; bottom: 8px; color: var(--gold);
  font-size: 12px; letter-spacing: 1px; opacity: .7;
  animation: cueBlink 1.4s ease-in-out infinite;
}
@keyframes cueBlink { 0%,100% { opacity: .35; } 50% { opacity: .85; } }

/* 场景过场节拍：居中大字 */
.story-dialog.scene-beat { text-align: center; background: rgba(16,13,10,.7); }
.story-dialog.scene-beat .scene-line {
  color: var(--gold); font-size: 19px; letter-spacing: 6px;
  animation: storyLineIn .5s ease backwards;
}

/* 选项：盖在对话框上方 */
.story-choices {
  position: relative; z-index: 5; margin: 0 auto 0; width: min(860px, 94%);
  display: flex; flex-direction: column; gap: 10px;
  padding: 0 26px 22px; background: rgba(16,13,10,.9);
}
.story-choices:empty { display: none; }
.story-choices .choice { animation: choiceIn .3s ease backwards; }
/* 剧情选项的提示语：与正文分行、灰色小字（否则正文与 hint 黏成一句，读起来费劲）*/
.story-choices .choice .c-hint { display: block; color: var(--ink-dim); font-size: 12px; margin-top: 5px; font-weight: 400; }

/* ---- 演出层（cutscene.js 阶段1）---- */
/* 含演出原语时关掉 kenBurns，改由镜头 op 的 inline transform 驱动 */
.story-bg.story-cam { animation: none !important; }
/* 立绘进退场（cutscene _actor）：在既有立绘位上做一次性入/出场 */
.story-portrait.portrait-in img  { animation: portraitIn .42s cubic-bezier(.22,1,.36,1); }
.story-portrait.left.portrait-in img { animation-name: portraitInL; }
.story-portrait.portrait-out { opacity: 0; transform: translateY(10px); transition: opacity .34s ease, transform .34s ease; }
.story-portrait.left.portrait-out { transform: scaleX(-1) translateY(10px); }
/* 随时可跳：右上角常驻跳过键 */
.story-skip {
  position: absolute; top: 18px; right: 18px; z-index: 8;
  color: var(--ink-dim); font-size: 12px; letter-spacing: 1px;
  min-width: 44px; min-height: 44px;
  display: inline-flex; align-items: center; justify-content: center;
  padding: 8px 14px; border: 1px solid rgba(212,176,106,.32); border-radius: 14px;
  background: rgba(14,11,9,.7); cursor: pointer; user-select: none;
}
.story-overlay { cursor: pointer; }
.story-skip:hover { color: var(--gold); border-color: rgba(212,176,106,.6); }
/* 交互 beat：把"操作"嵌进演出（伺机出手 / 限信息抉择）*/
.story-choices.cut-beat-on { background: transparent; }
.cut-prompt { color: var(--ink); font-size: 15px; line-height: 1.7; margin-bottom: 6px; text-align: center; }
.cut-strike { position: relative; overflow: hidden; }
.cut-gauge { position: absolute; left: 0; bottom: 0; width: 100%; height: 3px; background: rgba(255,255,255,.12); }
.cut-gauge i { display: block; height: 100%; width: 100%; background: var(--gold-bright); }
.cut-choice { animation: choiceIn .3s ease backwards; }

/* 演出即引导：落幕指路卡（切章/切图时顺势告诉玩家"下一步去干嘛"）*/
.cut-guide { text-align: center; animation: choiceIn .3s ease backwards; padding: 2px 4px; }
.cut-guide .cg-tag { display: inline-block; font-size: 12px; letter-spacing: .14em; color: var(--gold-bright);
  border: 1px solid rgba(212,176,106,.5); border-radius: 999px; padding: 2px 12px; margin-bottom: 8px; }
.cut-guide .cg-title { color: var(--gold); font-size: 16px; font-weight: 600; margin-bottom: 6px; }
.cut-guide .cg-hint { color: var(--ink); font-size: 14px; line-height: 1.75; margin: 0 auto 10px; max-width: 30em; }
.cut-guide .cut-guide-go { display: inline-block; min-width: 8em; }
/* 落幕后地点屏：被指路的行动按钮脉冲一下，指明"该点这个"（脉冲数次后停） */
.btn-guide-focus { animation: guideFocus 1.4s ease-in-out 3; position: relative; }
@keyframes guideFocus {
  0%, 100% { box-shadow: 0 0 0 0 rgba(212,176,106,0); }
  50% { box-shadow: 0 0 0 3px rgba(212,176,106,.55), 0 0 14px 2px rgba(212,176,106,.35); border-color: var(--gold-bright); }
}

@media (max-width: 760px) {
  /* 手机：整屏可滚动，对话框与抉择按钮始终能点到（不被浏览器栏/底部安全区盖住）*/
  .story-overlay {
    justify-content: flex-end; overflow-y: auto;
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }
  /* 手机：只显示当前说话者一人，立绘立于对话框之后（VN 式：下半身没入文本框，头胸完整露出）；
     旁白时无立绘，对话干净 */
  .story-portrait { display: none; }
  .story-portrait.on:not(.dim) {
    display: block; height: 42vh; max-height: 400px;
    left: 50%; right: auto; transform: translateX(-50%);
    bottom: 268px;   /* 立绘下缘没入对话框后方一截，头胸完整露出（心声框不再遮脸）*/
    z-index: 3;
  }
  .story-portrait.left.on:not(.dim) { transform: translateX(-50%) scaleX(-1); }
  .story-text { font-size: 16px; line-height: 1.85; min-height: 36px; }
  .story-dialog {
    padding: 14px 16px 16px; max-height: 42vh; overflow-y: auto; cursor: pointer;
  }
  .story-cue { position: static; display: block; text-align: right; margin-top: 6px; }
  /* 抉择区：底部留足安全间距，按钮加大易点 */
  .story-choices {
    padding: 12px 16px calc(20px + env(safe-area-inset-bottom, 14px));
  }
  .story-choices .choice { padding: 14px 16px; font-size: 16px; }
}

/* 场景配图：完整显示（不裁剪），尺寸克制，详见上方 .loc-scene img */

/* ============================================================
 * 场景舞台：全屏铺底，可去之处=图上发光按钮，人物立绘站在场景里
 * ============================================================ */
.scene-stage {
  position: absolute; inset: 0; z-index: 1;
  overflow: hidden;
  /* 无场景图时的优雅兜底：水墨径向渐变（而非纯黑大片空洞）——缺图地点也像"夜色/雾中"而非 bug */
  background:
    radial-gradient(ellipse at 50% 32%, #1c1812 0%, #14110b 55%, #0b0907 100%);
}
.scene-bg {
  position: absolute; inset: -2.5%; background-size: cover; background-position: center 38%;
  transition: opacity .8s ease; opacity: 0;
  filter: saturate(.92) brightness(.94);
  will-change: transform; backface-visibility: hidden;
}
/* 漂移只平移不缩放：transform scale 会直接放大位图导致发糊（手机竖屏尤甚） */
.scene-bg.has-img { opacity: 1; animation: sceneDrift 46s ease-in-out infinite alternate; }
@keyframes sceneDrift {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-0.6%, -0.8%, 0); }
}
/* 上下压暗 + 四角暗角，文字清晰、画面聚焦 */
.scene-veil {
  position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(ellipse at 50% 42%, transparent 52%, rgba(8, 6, 4, 0.5) 100%),
    linear-gradient(180deg, rgba(8,6,4,.62) 0%, rgba(8,6,4,.06) 22%, rgba(8,6,4,.04) 60%, rgba(8,6,4,.66) 100%);
}

/* —— 昼夜·天气骨架：地点级氛围层（时辰染色 tint + 天气氛围粒子）。
 *    压在背景/暗角之上、题字/图钉之下（z-index:2）；不挡点击（pointer-events:none）。
 *    未打 env 的地点解析为 昼·晴 → 两层全透明，零观感变化（零回归）。—— */
.scene-tint, .scene-weather {
  position: absolute; inset: 0; z-index: 2; pointer-events: none;
}
/* 时辰染色：墨黑烛金里的冷暖偏移，缓慢渐变（氛围流转，非交互动效）*/
.scene-tint { opacity: 0; transition: opacity 1.2s ease, background 1.2s ease; }
.scene-stage[data-phase="night"] .scene-tint {
  opacity: 1;
  background:
    radial-gradient(ellipse at 50% 28%, rgba(74,100,156,.16) 0%, transparent 60%),
    linear-gradient(180deg, rgba(13,20,44,.42) 0%, rgba(9,15,36,.30) 100%);
}
.scene-stage[data-phase="dusk"] .scene-tint {
  opacity: 1;
  background: linear-gradient(180deg, rgba(122,66,30,.32) 0%, rgba(58,30,28,.28) 100%);
}
.scene-stage[data-phase="dawn"] .scene-tint {
  opacity: 1;
  background: linear-gradient(180deg, rgba(150,140,120,.20) 0%, rgba(90,110,140,.18) 100%);
}
/* 昼 = 透明（默认 opacity:0），不染色。 */

/* 天气：氛围粒子（雨丝/飞雪，纯 CSS 背景动画零额外资源）+ 雾的低反差灰罩。*/
.scene-weather { opacity: 0; transition: opacity 1s ease; }
.scene-stage[data-weather="rain"] .scene-weather,
.scene-stage[data-weather="snow"] .scene-weather,
.scene-stage[data-weather="fog"]  .scene-weather { opacity: 1; }

/* 雨丝：两层细斜线下落（错速更自然）*/
.scene-stage[data-weather="rain"] .scene-weather {
  background-image:
    repeating-linear-gradient(101deg, rgba(182,202,226,0) 0 7px, rgba(182,202,226,.16) 7px 8px),
    repeating-linear-gradient(99deg, rgba(168,190,220,0) 0 11px, rgba(168,190,220,.10) 11px 12px);
  background-size: 90px 120px, 140px 180px;
  animation: rainfall .7s linear infinite, rainfall2 1.1s linear infinite;
}
@keyframes rainfall  { to { background-position: -36px 120px, 0 0; } }
@keyframes rainfall2 { to { background-position: 0 0, -28px 180px; } }

/* 飞雪：两层圆点缓落、轻微横移 */
.scene-stage[data-weather="snow"] .scene-weather {
  background-image:
    radial-gradient(2px 2px at 20px 30px, rgba(255,255,255,.9), transparent),
    radial-gradient(2px 2px at 80px 70px, rgba(255,255,255,.7), transparent),
    radial-gradient(1.5px 1.5px at 130px 22px, rgba(255,255,255,.8), transparent),
    radial-gradient(1.5px 1.5px at 50px 110px, rgba(255,255,255,.6), transparent);
  background-size: 160px 160px, 200px 200px, 160px 160px, 200px 200px;
  animation: snowfall 9s linear infinite, snowfall2 14s linear infinite;
}
@keyframes snowfall  { to { background-position: 14px 160px, -10px 200px, 0 0, 0 0; } }
@keyframes snowfall2 { to { background-position: 0 0, 0 0, -12px 160px, 10px 200px; } }

/* 雾：低反差灰罩缓缓漂移（无颗粒，轻、不挡字）*/
.scene-stage[data-weather="fog"] .scene-weather {
  background:
    radial-gradient(ellipse at 30% 60%, rgba(150,158,170,.20) 0%, transparent 55%),
    radial-gradient(ellipse at 70% 40%, rgba(140,150,165,.16) 0%, transparent 55%);
  animation: fogdrift 22s ease-in-out infinite alternate;
}
@keyframes fogdrift { from { transform: translate3d(-2%, 0, 0); } to { transform: translate3d(2%, 0, 0); } }

/* 性能/无障碍：减少动效偏好 → 粒子静止（保留染色，去运动）*/
@media (prefers-reduced-motion: reduce) {
  .scene-stage[data-weather] .scene-weather { animation: none !important; }
}

/* ============================================================
 * 2.5D 纵深（前景分层）—— §3 B1 / §10 R1：把"全屏滤镜"升级成有纵深的多层。
 *   远景气层(scene-far) → 背景图(scene-bg) → 染色/天气 → 前景框层(scene-fg)
 *   三层同向同时长(.46s 漂移)按 depth 差速位移＝视差；染色限中远景、前景层不被染。
 *   仅 data-depth="on" 的地点点亮（密室/后山先行）；未配置者两层透明＝单层零回归。
 * ============================================================ */
.scene-far, .scene-fg {
  position: absolute; inset: 0; pointer-events: none;
  opacity: 0; transition: opacity 1s ease;
  will-change: transform; backface-visibility: hidden;
}
.scene-far { z-index: 1; }          /* 空气透视：压在背景之上、染色之下 */
.scene-fg  { z-index: 2; }          /* 近景遮挡：压在染色之上＝不被天气/时辰染 */
.scene-stage[data-depth="on"] .scene-far,
.scene-stage[data-depth="on"] .scene-fg { opacity: 1; }

/* 差速漂移：远景慢、背景中、前景快——同向同时长，读作一次缓慢推镜里的纵深视差 */
.scene-stage[data-depth="on"] .scene-far { animation: sceneDriftFar 46s ease-in-out infinite alternate; }
.scene-stage[data-depth="on"] .scene-fg  { animation: sceneDriftFg  46s ease-in-out infinite alternate; }
@keyframes sceneDriftFar { from { transform: translate3d(0,0,0); } to { transform: translate3d(-0.22%, -0.3%, 0); } }
@keyframes sceneDriftFg  { from { transform: translate3d(0,0,0); } to { transform: translate3d(-1.9%,  -2.4%,  0); } }

/* 远景气层：顶部一抹随时辰染色的雾带＝空气透视（远处虚），强度由 --scene-far(地点 far) 调浓淡 */
.scene-far { --far: var(--scene-far, .5); }
.scene-stage[data-depth="on"] .scene-far {
  background: linear-gradient(180deg,
    rgba(150,166,192, calc(.22 * var(--far))) 0%,
    rgba(150,166,192, calc(.08 * var(--far))) 26%,
    transparent 48%);
}
.scene-stage[data-depth="on"][data-phase="night"] .scene-far {
  background: linear-gradient(180deg,
    rgba(74,104,164, calc(.32 * var(--far))) 0%,
    rgba(44,66,122, calc(.13 * var(--far))) 30%,
    transparent 54%);
}
.scene-stage[data-depth="on"][data-phase="dusk"] .scene-far {
  background: linear-gradient(180deg,
    rgba(150,92,52, calc(.27 * var(--far))) 0%,
    rgba(96,56,40, calc(.11 * var(--far))) 30%,
    transparent 54%);
}

/* 染色限中远景：纵深地点的时辰染色按上浓下淡遮罩——近处(底部)不压暗＝"近处实" */
.scene-stage[data-depth="on"] .scene-tint {
  -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 50%, rgba(0,0,0,.28) 84%, transparent 100%);
          mask-image: linear-gradient(180deg, #000 0%, #000 50%, rgba(0,0,0,.28) 84%, transparent 100%);
}

/* —— 前景框层（data-fg 驱动，纯 CSS 零资源；近景遮挡＝纵深线索）——
 *    v183 改：去掉 .scene-fg 的 filter:blur（对纯渐变框无效、且会糊掉本身有层次的图）；
 *    暗带整体收窄、减重——只压最外缘，中景/主体保持清晰＝"框景增强"而非"盖滤镜"。 */
/* 洞口岩壁框：密室"从洞里往外看"——左右上压暗收口、中央透出，冷黑近景 */
.scene-stage[data-fg="cave"] .scene-fg {
  background:
    radial-gradient(132% 104% at 50% 44%, transparent 38%, rgba(8,9,17,.3) 64%, rgba(2,3,8,.8) 100%),
    linear-gradient(90deg, rgba(3,4,10,.9) 0%, rgba(6,7,14,.46) 10%, transparent 26%, transparent 74%, rgba(6,7,14,.46) 90%, rgba(3,4,10,.9) 100%),
    linear-gradient(180deg, rgba(4,5,12,.66) 0%, transparent 17%, transparent 66%, rgba(2,3,9,.74) 100%);
}
/* 近景枝叶框：后山——上两角深绿枝叶垂下、底缘近草，把场景"框"进林子里 */
.scene-stage[data-fg="forest"] .scene-fg {
  background:
    radial-gradient(58% 52% at -5% -9%, rgba(17,29,14,.82) 0%, rgba(17,29,14,.4) 42%, transparent 64%),
    radial-gradient(58% 52% at 105% -9%, rgba(14,26,12,.8) 0%, rgba(14,26,12,.38) 42%, transparent 64%),
    radial-gradient(74% 30% at 50% 111%, rgba(10,20,8,.58) 0%, transparent 72%),
    linear-gradient(180deg, transparent 62%, rgba(8,16,7,.36) 100%);
}
/* 室内/洞府框：药庐——上梁压顶、左右墙体收口、底缘近台暗，暖黑（烛火）；"隔着屋子往里看" */
.scene-stage[data-fg="interior"] .scene-fg {
  background:
    linear-gradient(180deg, rgba(18,11,4,.72) 0%, rgba(20,12,5,.26) 8%, transparent 19%, transparent 79%, rgba(12,7,3,.5) 100%),
    linear-gradient(90deg, rgba(12,7,3,.6) 0%, rgba(16,9,4,.22) 9%, transparent 20%, transparent 80%, rgba(16,9,4,.22) 91%, rgba(12,7,3,.6) 100%);
}
/* 殿堂框：演武厅·大殿——上檐压顶 + 左右石柱（内收两道竖暗带），冷石灰，框出庄重纵深 */
.scene-stage[data-fg="hall"] .scene-fg {
  background:
    linear-gradient(90deg, rgba(10,11,15,.74) 0%, rgba(14,15,20,.38) 4%, transparent 9.5%, transparent 16%, rgba(20,22,28,.26) 19.5%, transparent 24%, transparent 76%, rgba(20,22,28,.26) 80.5%, transparent 84%, transparent 90.5%, rgba(14,15,20,.38) 96%, rgba(10,11,15,.74) 100%),
    linear-gradient(180deg, rgba(11,12,17,.7) 0%, rgba(13,14,19,.28) 12%, transparent 25%, transparent 84%, rgba(9,10,13,.44) 100%);
}
/* 坊市框：集镇·坊市——上沿两盏暖灯晕 + 檐影，左右轻收，底缘人潮暗；暖红橙、市井活气 */
.scene-stage[data-fg="market"] .scene-fg {
  background:
    radial-gradient(40px 26px at 21% 10%, rgba(255,176,98,.4) 0%, transparent 72%),
    radial-gradient(44px 28px at 80% 7%, rgba(255,152,74,.36) 0%, transparent 72%),
    linear-gradient(180deg, rgba(34,16,5,.58) 0%, rgba(40,19,7,.2) 9%, transparent 22%, transparent 79%, rgba(18,9,3,.44) 100%),
    linear-gradient(90deg, rgba(20,10,4,.5) 0%, transparent 13%, transparent 87%, rgba(20,10,4,.5) 100%);
}
/* 山野框：户外山坡/崖——底两角近岩压上、底缘暗，顶部留白交远景气层渲染空气透视；冷青灰、开阔 */
.scene-stage[data-fg="mountain"] .scene-fg {
  background:
    radial-gradient(62% 48% at -8% 116%, rgba(26,28,34,.74) 0%, rgba(26,28,34,.32) 44%, transparent 70%),
    radial-gradient(62% 48% at 108% 114%, rgba(22,25,31,.72) 0%, rgba(22,25,31,.3) 44%, transparent 70%),
    linear-gradient(180deg, transparent 66%, rgba(16,18,24,.38) 100%);
}
/* 水景框：湖/海/星海——底缘水汀近暗 + 两角岸影；近岸实、远水虚（不蒙满屏水气，保住远景层次）*/
.scene-stage[data-fg="water"] .scene-fg {
  background:
    radial-gradient(50% 36% at 10% 118%, rgba(9,26,24,.7) 0%, transparent 64%),
    radial-gradient(46% 34% at 91% 120%, rgba(7,22,22,.66) 0%, transparent 64%),
    linear-gradient(180deg, transparent 66%, rgba(7,18,22,.4) 88%, rgba(4,12,16,.62) 100%);
}
/* 纯雾框：秘境/深谷——仅四缘极淡冷雾向内收，中央全透明、不模糊；保住图本身的雾谷层次（v183 去满屏灰罩+blur）*/
.scene-stage[data-fg="mist"] .scene-fg {
  background:
    radial-gradient(138% 116% at 50% 48%, transparent 66%, rgba(150,160,175,.1) 83%, rgba(132,144,160,.24) 100%);
}

/* 粒子近大远小：纵深地点在快漂的前景层叠一层"大而快"的近景粒子（远景仍走 .scene-weather 的小粒子）*/
.scene-stage[data-depth="on"][data-weather="snow"] .scene-fg::after,
.scene-stage[data-depth="on"][data-weather="rain"] .scene-fg::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
}
.scene-stage[data-depth="on"][data-weather="snow"] .scene-fg::after {
  background-image:
    radial-gradient(3px 3px at 30px 40px, rgba(255,255,255,.95), transparent),
    radial-gradient(3.5px 3.5px at 120px 92px, rgba(255,255,255,.85), transparent),
    radial-gradient(2.5px 2.5px at 78px 158px, rgba(255,255,255,.8), transparent);
  background-size: 180px 200px, 224px 244px, 200px 220px;
  animation: snowfallNear 6s linear infinite;
}
@keyframes snowfallNear { to { background-position: 20px 200px, -16px 244px, 10px 220px; } }
.scene-stage[data-depth="on"][data-weather="rain"] .scene-fg::after {
  background-image: repeating-linear-gradient(100deg, rgba(190,210,235,0) 0 9px, rgba(190,210,235,.22) 9px 11px);
  background-size: 130px 170px;
  animation: rainfallNear .55s linear infinite;
}
@keyframes rainfallNear { to { background-position: -42px 170px; } }

@media (prefers-reduced-motion: reduce) {
  .scene-stage[data-depth="on"] .scene-far,
  .scene-stage[data-depth="on"] .scene-fg,
  .scene-stage[data-depth="on"] .scene-fg::after { animation: none !important; }
}

.scene-head {
  position: absolute; top: 54px; left: 308px; z-index: 3;
  display: flex; align-items: center; gap: 9px; flex-wrap: wrap; max-width: 40%;
}
.scene-head .loc-name {
  font-size: 21px; color: #f4efe4; letter-spacing: 4px; margin: 0; font-weight: 600;
  text-shadow: 0 2px 10px rgba(0,0,0,.9);
}
.scene-head .loc-desc-inline {
  flex-basis: 100%; color: #cfc6b4; font-size: 12px; line-height: 1.5; letter-spacing: .5px;
  text-shadow: 0 1px 5px rgba(0,0,0,.95);
}
.scene-head .loc-tag { background: rgba(10,8,6,.55); color: var(--gold); border: 1px solid rgba(201,169,106,.4); }

/* 图上发光"前往"按钮（容器约束在两侧面板之间的空区，保证可点）*/
.scene-pins {
  position: absolute; z-index: 4; pointer-events: none;
  left: 306px; right: 396px; top: 110px; bottom: 27vh;
}
.scene-pin {
  position: absolute; transform: translate(-50%, -50%); pointer-events: auto;
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  background: none; border: none; cursor: pointer; font-family: inherit;
  padding: 4px; transition: transform .15s;
}
.scene-pin:hover { transform: translate(-50%, -50%) scale(1.08); }
.scene-pin .sp-dot {
  width: 14px; height: 14px; border-radius: 50%;
  background: radial-gradient(circle, #fff 0%, var(--jade-bright) 45%, rgba(95,184,154,.2) 100%);
  box-shadow: 0 0 10px 2px rgba(127,227,192,.7); animation: pinPulse 1.8s ease-in-out infinite;
}
.scene-pin.home .sp-dot {
  background: radial-gradient(circle, #fff 0%, var(--gold) 45%, rgba(212,176,106,.2) 100%);
  box-shadow: 0 0 10px 2px rgba(212,176,106,.7);
}
.scene-pin.selected .sp-dot { box-shadow: 0 0 14px 4px rgba(127,227,192,.95); }
@keyframes pinPulse { 0%,100% { transform: scale(1); } 50% { transform: scale(1.25); } }
.scene-pin .sp-name {
  color: #fff; font-size: 13px; letter-spacing: 1px;
  background: rgba(8,6,4,.6); padding: 1px 8px; border-radius: 10px;
  text-shadow: 0 1px 3px rgba(0,0,0,.9); white-space: nowrap;
}
.scene-pin .sp-cost { color: var(--gold-bright); font-size: 11px; text-shadow: 0 1px 3px rgba(0,0,0,.9); }
.scene-pin.selected .sp-name { background: var(--jade); color: #08140f; }

/* 确认前往条：浮在中部空区下沿 */
.scene-confirm:empty { display: none; }
.scene-confirm {
  position: absolute; z-index: 9;
  left: calc(50% - 45px); transform: translateX(-50%);
  bottom: calc(27vh + 12px); width: min(480px, 44vw);
  display: flex; align-items: center; gap: 10px;
  background: rgba(14, 11, 8, .9); border: 1px solid rgba(201,169,106,.55);
  border-radius: var(--radius-lg); padding: 9px 13px; backdrop-filter: blur(5px);
  box-shadow: 0 12px 36px rgba(0,0,0,.5);
  animation: fadein .2s ease;
}
.scene-confirm .sc-info { flex: 1 1 auto; min-width: 0; }
.scene-confirm .sc-info b { color: var(--gold-bright); letter-spacing: 1px; white-space: nowrap; }
.scene-confirm .sc-info span { display: block; color: var(--ink-dim); font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.scene-confirm .btn { width: auto; margin: 0; flex: 0 0 auto; white-space: nowrap; padding: 8px 14px; font-size: 14px; }

/* ============================================================
 * NPC 交互轮盘（立绘居中，左绿善意 / 右红敌对）
 * ============================================================ */
.modal.modal-wheel { width: 560px; max-width: 94vw; }
.npc-wheel {
  display: grid; grid-template-columns: 1fr 1.2fr 1fr; gap: 8px; align-items: center;
  min-height: 300px;
}
.nw-side { display: flex; flex-direction: column; gap: 10px; }
.nw-act {
  display: flex; align-items: center; gap: 8px; cursor: pointer; font-family: inherit;
  padding: 10px 12px; border-radius: 10px; font-size: 15px; letter-spacing: 1px;
  border: 1px solid var(--border); background: var(--bg-panel-2); color: var(--ink);
  transition: all .15s; animation: choiceIn .3s ease backwards;
}
.nw-act .nw-ic { font-size: 18px; }
.nw-act.good { border-left: 3px solid var(--jade); }
.nw-act.good:hover { background: rgba(95,184,154,.14); border-color: var(--jade); color: var(--jade-bright); }
.nw-act.bad { border-left: 3px solid var(--red); flex-direction: row-reverse; text-align: right; }
.nw-act.bad:hover { background: rgba(201,95,95,.14); border-color: var(--red); color: #f0a0a0; }
.nw-act.disabled { opacity: .42; cursor: default; filter: grayscale(.5); }
.nw-act.disabled:hover { background: var(--bg-panel-2); border-color: var(--border); color: var(--ink); }
.nw-act .nw-cd { display: block; font-size: 10px; letter-spacing: 0; color: var(--ink-faint); margin-top: 1px; font-style: normal; }
.nw-center { display: flex; flex-direction: column; align-items: center; gap: 4px; }
.nw-portrait {
  width: 130px; height: 130px; border-radius: 50%; overflow: hidden;
  border: 2px solid var(--gold); box-shadow: 0 0 22px rgba(212,176,106,.35);
  display: flex; align-items: center; justify-content: center;
  background: radial-gradient(circle at 50% 35%, rgba(127,227,192,.15), #11171d 72%);
}
.nw-portrait img { width: 100%; height: 100%; object-fit: cover; object-position: center 20%; }
.nw-portrait .nw-emoji { font-size: 56px; }
.nw-name { font-size: 19px; color: var(--jade-bright); letter-spacing: 2px; margin-top: 4px; }
.nw-role { font-size: 12px; color: var(--gold); }
.nw-rel { font-size: 12px; color: var(--ink-dim); margin-top: 2px; }
.nw-rel.good { color: var(--jade-bright); }
.nw-rel.bad { color: var(--red); }

@media (max-width: 760px) {
  .npc-wheel { grid-template-columns: 1fr 1fr; grid-auto-flow: row; min-height: 0; }
  .nw-center { grid-column: 1 / -1; order: -1; margin-bottom: 6px; }
  .nw-portrait { width: 96px; height: 96px; }
  .nw-act.bad { flex-direction: row; text-align: left; }
}

/* ============================================================
 * 箱庭探索 v3 · L1 舆图（水墨节点图）+ L3 横版深窟
 * ============================================================ */
.exmap-overlay { position: fixed; inset: 0; z-index: 60; background: #0c0a09; }
.exmap-bg {
  position: absolute; inset: 0; background-size: cover; background-position: center;
  filter: brightness(.5) saturate(.75) sepia(.18) hue-rotate(-12deg);
}
.exmap-veil {
  position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(ellipse at 50% 42%, transparent 32%, rgba(10, 6, 6, .62) 100%),
    linear-gradient(180deg, rgba(26, 8, 8, .55), transparent 22%, transparent 70%, rgba(8, 5, 5, .8));
}
.exmap-field { position: absolute; inset: 0; }
.exmap-head {
  position: absolute; top: 0; left: 0; right: 0; z-index: 5;
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 16px; pointer-events: none;
}
.exmap-title {
  font-family: var(--font-title, serif); font-size: 20px; letter-spacing: 6px;
  color: #e8d9c0; text-shadow: 0 0 14px rgba(160, 30, 30, .55), 0 2px 6px #000;
}
.exmap-clock { display: flex; align-items: center; gap: 10px; font-size: 12px; color: #cdb89a; text-shadow: 0 1px 3px #000; }
.exclk-day { font-size: 15px; color: #e8d9c0; letter-spacing: 2px; }
.exclk-ticks { color: #c9544a; letter-spacing: 2px; font-size: 10px; }
.exclk-left { opacity: .75; }
.exclk-warn { color: #e0707a; animation: exwarn-pulse 2.2s ease-in-out infinite; }
@keyframes exwarn-pulse { 0%, 100% { opacity: .65; } 50% { opacity: 1; } }
/* 据点（和平）副标：无灾厄钟，市井风物一行 */
.exclk-peace { font-size: 13px; color: #d8c39a; letter-spacing: 2px; opacity: .9; }
/* 后山·远距感知梯度（钟盘位）：兽吼/血腥气方位强弱——越逼近越烈 */
.exclk-sense { font-size: 13px; color: #e0a9a0; letter-spacing: 1px; text-shadow: 0 0 8px rgba(180, 60, 50, .5); }
.exclk-sense.strong { color: #f0908a; animation: exwarn-pulse 1.8s ease-in-out infinite; }

.exmap-edges { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 1; pointer-events: none; }
.exedge { stroke: rgba(214, 196, 168, .28); stroke-width: .35; stroke-dasharray: 1.4 1.6; }
.exedge.reach { stroke: rgba(240, 214, 165, .66); stroke-width: .5; stroke-dasharray: none; }

.exmap-nodes { position: absolute; inset: 0; z-index: 2; }
.exnode {
  position: absolute; transform: translate(-50%, -50%);
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  min-width: 54px; padding: 6px 8px; border-radius: 10px; cursor: default;
  background: rgba(16, 11, 10, .55); border: 1px solid rgba(200, 176, 140, .22);
  backdrop-filter: blur(2px); transition: border-color .25s, box-shadow .25s, opacity .25s;
}
.exnode .exicon { font-size: 17px; line-height: 1; filter: drop-shadow(0 2px 3px #000); }
.exnode .exname { font-size: 11px; color: #ddcbac; letter-spacing: 1px; text-shadow: 0 1px 3px #000; white-space: nowrap; }
.exnode .excost { font-size: 10px; color: #a8946f; }
.exnode.reach { cursor: pointer; border-color: rgba(240, 214, 165, .6); box-shadow: 0 0 14px rgba(240, 200, 130, .18); animation: exnode-breath 2.6s ease-in-out infinite; }
.exnode.reach:hover { border-color: #f0d6a5; box-shadow: 0 0 20px rgba(240, 200, 130, .4); }
@keyframes exnode-breath { 0%, 100% { box-shadow: 0 0 10px rgba(240, 200, 130, .12); } 50% { box-shadow: 0 0 20px rgba(240, 200, 130, .3); } }
.exnode.here { border-color: #e8c87e; background: rgba(40, 28, 16, .72); box-shadow: 0 0 18px rgba(232, 200, 126, .35); }
/* 据点地标：城里都认得，灯火暖调（与险境节点区分） */
.exnode.peace { border-color: rgba(214, 188, 140, .42); background: rgba(26, 18, 12, .58); }
.exnode.peace .exname { color: #ecd9b4; }
.exnode.ghost { opacity: .55; border-style: dashed; }
.exnode.cleared .exicon { filter: grayscale(.8) brightness(.7); }
.exnode.cleared .exname { color: #8d7f68; }
.exnode.closed { opacity: .42; border-color: rgba(160, 50, 50, .5); background: rgba(40, 10, 10, .6); pointer-events: none; }
.exnode.closed::after {
  content: "封"; position: absolute; inset: 0; display: grid; place-items: center;
  font-size: 18px; color: #c9544a; text-shadow: 0 0 8px rgba(180, 40, 40, .8); letter-spacing: 0;
}
.exrisk {
  position: absolute; top: -7px; right: -7px; width: 18px; height: 18px; border-radius: 50%;
  display: grid; place-items: center; font-size: 10px; color: #ffe9e2;
  border: 1px solid rgba(255, 120, 100, .6); background: rgba(120, 22, 18, .92);
  box-shadow: 0 0 10px rgba(200, 50, 40, .55); animation: exwarn-pulse 1.8s ease-in-out infinite;
}
.exrisk.shadow { background: rgba(120, 70, 18, .92); border-color: rgba(255, 180, 100, .55); box-shadow: 0 0 10px rgba(200, 130, 40, .5); }
.exrisk.lair { animation: none; opacity: .92; }
.exrisk.boss { background: rgba(70, 14, 40, .95); border-color: rgba(220, 100, 160, .55); animation: none; }
/* 后山·风闻（异闻预亮的栖踪/巢穴）：紫调标记，与「凶」区分（信息≠现实） */
.exrisk.sense { background: rgba(86, 44, 120, .92); border-color: rgba(186, 146, 232, .6); box-shadow: 0 0 10px rgba(130, 90, 210, .5); animation: none; }
/* 后山·风闻节点：标出（知其所在），虚线紫边——尚未亲至，故非实线 */
.exnode.rumored { opacity: .85; border-style: dashed; border-color: rgba(168, 134, 224, .6); }
.exnode.rumored .exname { color: #d2c2ec; }

.expawn {
  position: absolute; z-index: 3; width: 40px; height: 40px; border-radius: 50%;
  transform: translate(-50%, -120%);
  border: 2px solid #e8c87e; overflow: hidden; background: #1c130c;
  box-shadow: 0 0 14px rgba(232, 200, 126, .45), 0 4px 10px rgba(0, 0, 0, .6);
  transition: left 1.1s cubic-bezier(.45, .05, .35, 1), top 1.1s cubic-bezier(.45, .05, .35, 1);
  pointer-events: none;
}
.expawn img { width: 100%; height: 100%; object-fit: cover; object-position: top; }
.expawn.foe { border-color: #c9544a; box-shadow: 0 0 16px rgba(200, 60, 50, .6); transform: translate(-50%, -120%) scale(.92); }

.exmap-notes {
  position: absolute; left: 50%; bottom: 86px; transform: translateX(-50%); z-index: 6;
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  width: min(620px, 88vw); pointer-events: none;
}
/* L3 洞窟时字幕浮在舞台下沿（面板之上）——远声与观战见闻都看得见 */
.exmap-overlay:has(.exmap-scene:not([hidden])) .exmap-notes { bottom: calc(42% + 14px); }
.exmap-note {
  padding: 7px 16px; border-radius: 18px; font-size: 13px; line-height: 1.55;
  color: #e6d8c2; background: rgba(14, 10, 9, .82); border: 1px solid rgba(200, 176, 140, .25);
  text-shadow: 0 1px 2px #000; animation: exnote-in .5s ease both; transition: opacity .9s;
}
.exmap-note.warn { color: #f0b9ad; border-color: rgba(220, 110, 90, .5); background: rgba(40, 12, 10, .88); }
.exmap-note.good { color: #cfe6c0; border-color: rgba(140, 200, 120, .4); }
.exmap-note.desc { color: #d8c5a5; font-size: 12.5px; opacity: .95; }
.exmap-note.fade { opacity: 0; }
@keyframes exnote-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

.exmap-actions {
  position: absolute; left: 50%; bottom: 18px; transform: translateX(-50%); z-index: 6;
  display: flex; gap: 10px; flex-wrap: wrap; justify-content: center; max-width: 94vw;
}
.exmap-actions .btn { box-shadow: 0 4px 14px rgba(0, 0, 0, .5); }

/* ===== 箱庭前景雾（B3 天象·DOM 雾层）=====
 * 三条大雾带（上岚/中霭/贴地霾）双倍宽横向慢漂——柔渐变成片、无发光混合、有厚度。
 * ⚠ 教训（2026-07-11 用户实锤）：光斑粒子（lighter 辉光 mote）画雾=一屏光球，"太蠢"——
 * 雾必须是"片"不是"点"。z:4=飘在节点连线之上、按钮字幕(z:5/6)之下；pointer-events 穿透。
 * 性能：纯 transform 位移动画 + 预柔渐变（不用 filter:blur 大层实滤——手机会卡）。 */
.exmap-fog { position: absolute; inset: 0; z-index: 4; pointer-events: none; overflow: hidden; opacity: var(--fog-o, .7); }
.exmap-fog i {
  position: absolute; left: -55%; width: 210%; display: block;
  will-change: transform;
}
.exmap-fog i:nth-child(1) {
  top: -6%; height: 46%;
  background:
    radial-gradient(58% 88% at 18% 52%, rgba(var(--fog-c), .30), transparent 70%),
    radial-gradient(46% 74% at 55% 38%, rgba(var(--fog-c), .22), transparent 72%),
    radial-gradient(52% 90% at 86% 60%, rgba(var(--fog-c), .27), transparent 70%);
  animation: fogDrift 46s ease-in-out infinite alternate;
}
.exmap-fog i:nth-child(2) {
  top: 30%; height: 42%;
  background:
    radial-gradient(50% 80% at 30% 50%, rgba(var(--fog-c), .20), transparent 72%),
    radial-gradient(60% 92% at 72% 44%, rgba(var(--fog-c), .24), transparent 70%);
  animation: fogDrift 62s ease-in-out infinite alternate-reverse;
}
.exmap-fog i:nth-child(3) {
  bottom: -4%; height: 44%;
  background:
    radial-gradient(64% 92% at 24% 62%, rgba(var(--fog-c), .34), transparent 68%),
    radial-gradient(50% 78% at 60% 74%, rgba(var(--fog-c), .26), transparent 70%),
    radial-gradient(58% 90% at 90% 58%, rgba(var(--fog-c), .30), transparent 68%);
  animation: fogDrift 38s ease-in-out infinite alternate;
}
@keyframes fogDrift {
  from { transform: translateX(-4%); }
  to   { transform: translateX(4%); }
}

/* ---------- L3 轴式洞窟：探索格=战斗格（镜头跟随的长轴） ---------- */
.exmap-scene { position: absolute; inset: 0; z-index: 4; display: flex; flex-direction: column; }
.exmap-scene[hidden] { display: none; }
.exmap-scene-stage { position: relative; flex: 1 1 58%; min-height: 0; overflow: hidden; }
.exmap-scene-stage::after {
  /* 潭岸地面：水光与雾气压住立绘脚跟（踩实地面） */
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 92px; pointer-events: none; z-index: 2;
  background: linear-gradient(180deg, transparent, rgba(28, 12, 12, .5) 45%, rgba(16, 7, 7, .85));
}
.exmap-scene-stage::before {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 1;
  background: radial-gradient(ellipse at 50% 30%, transparent 40%, rgba(10, 5, 5, .5) 100%);
}
.cave-track {
  position: absolute; left: 0; bottom: 0; top: 0; z-index: 3;
  transition: transform 1s cubic-bezier(.42, .05, .3, 1);
  will-change: transform;
}
/* 长卷背景：跟着镜头退行（比脚下慢半拍的视差=纵深）——背景在动，证明人在走 */
.cave-pano {
  position: absolute; top: 0; bottom: 0; left: 0; width: 150%;
  background-size: cover; background-position: center bottom;
  transition: left 1s cubic-bezier(.42, .05, .3, 1);
  z-index: 0; pointer-events: none;
  filter: brightness(.82) saturate(.95);
}
/* 远光：战团在镜头外时画框右缘的微光——先见其光，后见其人 */
.cave-far-glow {
  position: absolute; right: 0; top: 12%; bottom: 18%; width: 86px; z-index: 4;
  display: flex; align-items: center; justify-content: flex-end; pointer-events: none;
}
.cave-far-glow i {
  position: absolute; inset: 0;
  background: linear-gradient(270deg, rgba(196, 120, 224, .26), rgba(196, 120, 224, .07) 55%, transparent 85%);
  animation: farglow-pulse 2.8s ease-in-out infinite;
}
.cave-far-glow span {
  writing-mode: vertical-rl; font-size: 11px; color: #e0c8ee; letter-spacing: 4px;
  margin-right: 12px; text-shadow: 0 0 10px rgba(190, 120, 230, .9), 0 1px 3px #000; opacity: .9;
}
@keyframes farglow-pulse { 0%, 100% { opacity: .3; } 50% { opacity: 1; } }
.cave-track .axis-lane { position: absolute; left: 0; right: 0; bottom: 14px; display: flex; height: 46px; z-index: 3; }
.cave-track .axis-units { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
.cave-track .axis-units .axis-unit { pointer-events: none; }
/* 走格是"走出来"的：洞窟内单位左右滑步比战斗内更沉（一步一步踏过去） */
.cave-track .axis-unit { bottom: 52px; transition: left .95s cubic-bezier(.5, .08, .35, 1); }
.cave-u .au-img { max-height: 17vh; }
.cave-beast .au-img { max-height: 22vh; filter: drop-shadow(0 0 22px rgba(160, 40, 40, .45)) drop-shadow(0 10px 14px rgba(0, 0, 0, .7)); }
.cave-u.fighting { animation: exsc-fight 1.8s ease-in-out infinite; }
@keyframes exsc-fight { 0%, 100% { margin-left: 0; } 30% { margin-left: 8px; } 60% { margin-left: -5px; } }
/* 洞窟轴格：暗水墨刻度，比战斗格更沉 */
.cave-lane .axis-cell .dot { background: rgba(214, 196, 168, .22); }
.cave-lane .axis-cell.can-move .dot { background: rgba(150, 220, 170, .55); }
/* 朝向镜像：素材朝向与"面向对手"不符时翻转 */
.au-img.flipped-img, .au-img.flipped { transform: scaleX(-1); }

/* ===== 空层（2.5D）：凌空单位与飞天镜头 ===== */
/* 凌空（纵深语言 v3——depth-design D2）：高度=境界档（airGrade），与"远"（排）彻底分家。
 * 三件套：遁光踏足 + 影子留在地线上（基础 ::after 吃 --ay 自动归地）+ 垂直光柱（高度的脐带）。
 * "韩立飞得比南陇侯高"——档位差同屏可见，高度即境界的俯视 */
/* 高度档（v91 相对坐标系+抬高；v110 再抬一档）：飞高=战场高的百分比（cqh）——任何屏幕下高度感恒定。
 * v110 配合新增「升空天幕」(.combat-sky)把天让出来，抬升幅度同步加大（30/40/50→36/48/60cqh），
 * 让"飞在天上"一眼读出而非"站她头顶"；air-1 在 zoom 后拉配合下头顶仍不出画框（已在演武场实测）。 */
.axis-unit.airborne { --ay: -36cqh; z-index: 11; }
.axis-unit.airborne.air-2 { --ay: -48cqh; }
.axis-unit.airborne.air-3 { --ay: -60cqh; }
/* ⚠ z 序铁律（v92 修，用户实锤"她升空盖住我"）：升空不改变排深主序——
 * 深排单位飞上天也仍在前排身后（各排内 +1 压过本排地面单位即可）。
 * 同时升空横向错位（--ax）：深排飞行单位再斜退一步，"她在我斜后上方"而非正上叠脸 */
.axis-unit.lane-1.airborne { z-index: 9; --ax: 13px; }
.axis-unit.lane-2.airborne { z-index: 7; --ax: 22px; }
.axis-unit.lane-3.airborne { z-index: 5; --ax: 30px; }
.axis-unit.airborne .au-img {
  /* v110：升空高空灵光描边略增（.22→.3）——飞入天幕后人物"吃到天光"，与 .combat-sky 呼应 */
  filter: drop-shadow(0 4px 8px rgba(0,0,0,.3)) drop-shadow(0 0 18px rgba(150,214,252,.3));
  animation: portraitIn .4s ease, hoverFloat 2.6s ease-in-out .4s infinite;
}
/* 升空不丢空气透视（v92 修——airborne 滤镜曾整条覆盖排深暗化，深排单位一升空
 * 反而变亮"贴脸"）：深排飞行单位仍带本排的暗化与降饱和 */
.axis-unit.lane-1.airborne .au-img {
  filter: drop-shadow(0 4px 8px rgba(0,0,0,.3)) drop-shadow(0 0 16px rgba(140,210,250,.22)) brightness(.93) saturate(.88);
}
.axis-unit.lane-2.airborne .au-img {
  filter: drop-shadow(0 4px 8px rgba(0,0,0,.3)) drop-shadow(0 0 14px rgba(140,210,250,.2)) brightness(.88) saturate(.8);
}
.axis-unit.lane-3.airborne .au-img {
  filter: drop-shadow(0 4px 8px rgba(0,0,0,.3)) drop-shadow(0 0 12px rgba(140,210,250,.18)) brightness(.84) saturate(.74);
}
/* 垂直光柱（元素自带两枚伪元素：柱体+遁光踏足）——从脚下遁光垂到地面影子，
 * 人与影一线相连，"悬在何处的上空"一眼即知（::before 槽位还给接触影）。
 * 常驻 DOM、靠 opacity 过渡现隐——升空时遁光渐亮而非突现（丝滑） */
.axis-unit .air-pillar {
  display: block; position: absolute; left: 50%; width: 2px;
  bottom: calc(var(--feet, 40px) + var(--ay, 0px) + 8px);
  height: calc(-1 * var(--ay, 0px) - 12px);
  translate: -50% 0; pointer-events: none; z-index: -1;
  background: linear-gradient(180deg, rgba(160,225,252,.15), rgba(160,225,252,.02));
  opacity: 0; transition: opacity .45s ease .12s;
}
/* v308 用户裁决（"光球还是没删除，太丑了"）：遁光光柱/光台整个撤——
 * 悬空感交给高度差+接触影+浮沉呼吸，不再画任何发光体 */
.axis-unit .air-pillar { display: none !important; }
@keyframes dunGlow { 0%, 100% { opacity: .45; scale: .95 1; } 50% { opacity: .8; scale: 1.05 1; } }
/* v308 海战修正（用户实锤两处）：
 * ① 灰色"阵型"（透视地台的排地线+雾带）在海面上是穿帮——海上无地，整层撤；
 * ② 凌空高度收敛：海战里 alt=1 是常态（踏浪）不是冲天——飞高从 -36/-48/-60cqh
 *   收到贴浪一档，人物不再钉在画框顶上（开场构图回到海天线） */
.sea-field .axis-units::before { display: none; }
.sea-field .axis-unit.airborne { --ay: -7cqh; }
.sea-field .axis-unit.airborne.air-2 { --ay: -10cqh; }
.sea-field .axis-unit.airborne.air-3 { --ay: -13cqh; }
@keyframes hoverFloat { 0%, 100% { translate: 0 0; } 50% { translate: 0 -9px; } }
/* 统一相机（v89）：世界层（axis-lane+axis-units+地台）吃同一个 scale(zoom)，
 * origin 贴地（50% 100%）——镜头后拉时人/格/地/影一体变小、脚位不漂；
 * far/mid 各按层深系数缩（近缩多远缩少=真透视）。axis-field 本体不再变换 */
.axis-lane, .axis-units { transform-origin: 50% 100%; }
#axis-field.sky-view .axis-unit .au-img { filter: drop-shadow(0 10px 14px rgba(0,0,0,.5)); }

/* ===== 二次确认（群战择敌/择地）：法术先上膛，再点目标 ===== */
.spell-btn.armed {
  border-color: var(--gold-bright, #ecd9a8) !important;
  box-shadow: 0 0 12px rgba(236,217,168,.5), inset 0 0 10px rgba(236,217,168,.12);
  animation: armedPulse 1s ease-in-out infinite alternate;
}
@keyframes armedPulse { from { box-shadow: 0 0 6px rgba(236,217,168,.35); } to { box-shadow: 0 0 16px rgba(236,217,168,.7); } }
/* 择敌：可选目标灵光勾边脉动（点立绘即放） */
.axis-unit.targetable { cursor: pointer; min-width: 56px; }
.axis-unit.targetable .au-img {
  filter: drop-shadow(0 12px 18px rgba(0,0,0,.66)) drop-shadow(0 0 14px rgba(236,217,168,.75));
  animation: targetGlow .9s ease-in-out infinite alternate;
}
@keyframes targetGlow {
  from { filter: drop-shadow(0 12px 18px rgba(0,0,0,.66)) drop-shadow(0 0 8px rgba(236,217,168,.45)); }
  to   { filter: drop-shadow(0 12px 18px rgba(0,0,0,.66)) drop-shadow(0 0 18px rgba(236,217,168,.95)); }
}
/* 择地：射程内步位亮金圈（点格布阵） */
.axis-cell.cast-cell { pointer-events: auto; cursor: pointer; }
.axis-cell .cast-mark {
  position: absolute; left: 50%; bottom: 12px; width: 34px; height: 13px;
  translate: -50% 0; border-radius: 50%; pointer-events: none;
  border: 1.5px solid rgba(236,217,168,.75);
  background: radial-gradient(ellipse, rgba(236,217,168,.28), transparent 72%);
  animation: armedPulse 1.1s ease-in-out infinite alternate;
}

/* ===== 特效画布（fx.js）：铺满战场、永不挡点击 ===== */
/* v111 身后/身前双层：单块 z:26 会让护体光环/地纹也"飘在表面"。拆成——
 *   .fx-canvas-back  z:1  画在 .axis-units(z:2) 之下＝贴着所有人物身后（护体/光环/地纹/吐纳）
 *   .fx-canvas-front z:26 仍盖在所有人物之上＝命中火花/冲击/剑出袭/天雷
 * z 铁律不破：身后层只在"人物整体之下、场景背景之上"，不介入人物之间的深排序。 */
.fx-canvas {
  position: absolute; inset: 0; width: 100%; height: 100%;
  pointer-events: none;
}
.fx-canvas-back  { z-index: 1; }
.fx-canvas-front { z-index: 26; }
/* S2 预兆·战场压暗层：大招前天光骤暗（opacity 由 Fx.dimField 注入，雷幕(z26)仍在其上炸亮） */
.fx-dim {
  position: absolute; inset: 0; z-index: 25; pointer-events: none;
  background: radial-gradient(ellipse at 50% 118%, rgba(6, 4, 2, .5) 0%, rgba(4, 3, 2, .96) 120%);
  opacity: 0; transition: opacity .5s ease;
}
/* S2 余韵·焦痕 decal：命中点地面残留（z1=踩在人物脚下，慢慢淡去——世界记住这一击） */
.fx-scorch {
  position: absolute; z-index: 1; width: 68px; height: 20px; pointer-events: none;
  border-radius: 50%;
  background: radial-gradient(ellipse, rgba(16, 10, 4, .8), rgba(28, 17, 6, .4) 55%, transparent 72%);
  box-shadow: inset 0 0 16px rgba(255, 176, 30, .22);
  opacity: 0; transition: opacity .6s ease;
}
.fx-scorch.on { opacity: .85; }
/* 震屏：天雷/重击的物理反馈（位移量由 --fx-shake 注入） */
@keyframes fxShake {
  0%, 100% { translate: 0 0; }
  18% { translate: calc(var(--fx-shake, 8px) * -1) 2px; }
  38% { translate: var(--fx-shake, 8px) -2px; }
  58% { translate: calc(var(--fx-shake, 8px) * -.55) 1px; }
  78% { translate: calc(var(--fx-shake, 8px) * .3) -1px; }
}
.fx-shaking { animation: fxShake .4s ease-out; }
/* hit-stop 顿帧（B3）：决定性一击的 60–90ms"全帧冻结"。
 * 宿主自身＋所有子层（背景/远景/立绘呼吸/震屏）的 CSS 动画一并暂停＝画面凝住；
 * 配合 fx.js 把粒子 dt 置 0，整幕"咔"地定格。常先一记 shake 再 hitStop——抖到一半被冻＝打击感翻倍。
 * 只暂停 animation（不动 transition），避免在途镜头过渡被强行收尾而跳变。 */
.fx-hitstop, .fx-hitstop *, .fx-hitstop *::before, .fx-hitstop *::after {
  animation-play-state: paused !important;
}
/* 镜头轨道（战斗宽轴通用）——v90 镜头是"追"不是"绑"：
 * 人物 left 过渡 .42s（人先动），镜头 1.15s 长尾缓动慢半拍跟上——
 * "韩立在画面里走、镜头随后缓缓追"，而不是"世界跟着脚底滑"（用户实锤的体感翻转）。
 * 全部背景层仍同曲线同时长（层间不脱节） */
.cam-track { transition: transform 1.15s cubic-bezier(.22, .82, .26, 1), width .4s; }
.combat-bg, .combat-bgmid { transition: opacity .6s ease, transform 1.15s cubic-bezier(.22, .82, .26, 1); }
/* 洞窟热点（轴格上的采集物）：灵光底座，走近才亮 */
.cave-hot {
  position: absolute; bottom: 40px; left: 50%; transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  font-size: 21px; opacity: .65; pointer-events: none;
  filter: drop-shadow(0 2px 4px #000) saturate(.7);
}
.cave-hot::after {
  content: ""; position: absolute; bottom: -7px; left: 50%; transform: translateX(-50%);
  width: 30px; height: 9px; border-radius: 50%;
  background: radial-gradient(ellipse, rgba(200, 230, 170, .28), transparent 70%);
}
.cave-hot i { font-style: normal; font-size: 10px; color: #cdb89a; white-space: nowrap; text-shadow: 0 1px 3px #000; letter-spacing: .5px; }
.cave-hot.near { opacity: 1; pointer-events: auto; cursor: pointer; filter: drop-shadow(0 2px 4px #000) drop-shadow(0 0 10px rgba(190, 240, 170, .5)); animation: cavehot-bob 2.2s ease-in-out infinite; }
.cave-hot.near i { color: #dff0c8; }
.cave-hot.near::after { background: radial-gradient(ellipse, rgba(200, 240, 170, .55), transparent 70%); }
.cave-hot.near:hover { transform: translateX(-50%) scale(1.18); }
@keyframes cavehot-bob { 0%, 100% { margin-bottom: 0; } 50% { margin-bottom: 4px; } }
.cave-prep-mark {
  position: absolute; bottom: 30px; left: 50%; transform: translateX(-50%);
  width: 20px; height: 20px; border-radius: 50%; display: grid; place-items: center;
  font-size: 10.5px; color: #cfe2f0; background: rgba(30, 46, 60, .9);
  border: 1px solid rgba(140, 190, 220, .55); box-shadow: 0 0 10px rgba(110, 170, 210, .4);
}
.axis-cell.can-place { pointer-events: auto; cursor: pointer; }
.axis-cell.can-place .dot { background: #9fc8e8; box-shadow: 0 0 12px rgba(140, 190, 230, .7); animation: exnode-breath 1.6s ease-in-out infinite; }
.exsc-sub { display: block; font-size: 11px; color: #a89a82; letter-spacing: 0; margin-top: 3px; }
.exsc-hot.selecting { border-color: #9fc8e8; background: rgba(28, 44, 58, .75); box-shadow: 0 0 12px rgba(140, 190, 230, .35); }
.exmap-scene-panel {
  flex: 0 0 auto; max-height: 46%; overflow-y: auto; z-index: 5; position: relative;
  background:
    linear-gradient(180deg, rgba(232, 200, 126, .07), transparent 3px),
    linear-gradient(180deg, rgba(14, 10, 9, .92), rgba(9, 6, 5, .97));
  border-top: 1px solid rgba(232, 200, 126, .35);
  box-shadow: 0 -12px 30px rgba(0, 0, 0, .55);
  padding: 12px 18px 14px;
}
.exmap-scene-panel::before {
  content: ""; position: absolute; top: 0; left: 50%; transform: translateX(-50%);
  width: 120px; height: 2px; border-radius: 2px;
  background: linear-gradient(90deg, transparent, #e8c87e, transparent);
  box-shadow: 0 0 12px rgba(232, 200, 126, .5);
}
.exsc-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; margin-bottom: 9px; }
.exsc-title { font-family: var(--font-title, serif); font-size: 17px; letter-spacing: 4px; color: #e8c87e; text-shadow: 0 0 14px rgba(232, 200, 126, .25); }
.exsc-sub { display: block; font-size: 11px; color: #a08f74; letter-spacing: .5px; margin-top: 4px; }
.exsc-p { font-size: 13.5px; line-height: 1.78; color: #d9cab0; margin: 0 0 7px; }
.exsc-say { font-size: 13.5px; line-height: 1.7; color: #bcd6ef; margin: 4px 0 7px; }
.exsc-say.blood { color: #f0a9a0; }
.exsc-aside { font-size: 12.5px; line-height: 1.7; color: #a89a82; font-style: italic; margin: 2px 0 8px; }
/* 惊动仪表：竖匾式（贪与稳的脉搏） */
.exsc-expose {
  flex: 0 0 auto; display: flex; align-items: center; gap: 7px;
  padding: 6px 10px; border-radius: 9px;
  background: rgba(30, 16, 13, .6); border: 1px solid rgba(190, 110, 90, .3);
}
.exsc-expose.danger { border-color: rgba(230, 100, 80, .65); animation: exwarn-pulse 1.8s ease-in-out infinite; }
.exsc-explabel { font-size: 10px; line-height: 1.15; color: #cf9d8e; letter-spacing: 0; }
.exsc-expbar { width: 110px; height: 8px; border-radius: 5px; background: rgba(255, 255, 255, .07); overflow: hidden; box-shadow: inset 0 1px 3px rgba(0, 0, 0, .5); }
.exsc-expbar i { display: block; height: 100%; border-radius: 5px; background: linear-gradient(90deg, #7a4029, #c9544a, #f0734f); transition: width .45s cubic-bezier(.3, .8, .4, 1); box-shadow: 0 0 8px rgba(220, 90, 60, .55); }
.exsc-expnum { font-size: 14px; color: #eba78f; font-variant-numeric: tabular-nums; font-family: var(--font-title, serif); }
.exsc-expnum i { font-style: normal; font-size: 10px; color: #97705f; }
/* 布置符牌：印章+名目+落点（韩立的家底，一张一张摆出来） */
/* 布置符牌：一排横滑（单屏铁律——页面不竖涨，划的是排内） */
.exsc-preps {
  display: flex; gap: 8px; margin: 4px 0;
  overflow-x: auto; padding-bottom: 3px; -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.exsc-preps::-webkit-scrollbar { display: none; }
.exsc-preps .prep-card { flex: 0 0 228px; min-width: 228px; }
.prep-card {
  display: flex; align-items: center; gap: 10px; text-align: left;
  padding: 8px 10px; border-radius: 10px; cursor: pointer;
  color: #e3d2b4; border: 1px solid rgba(150, 180, 205, .28);
  background: linear-gradient(135deg, rgba(26, 36, 46, .55), rgba(16, 20, 26, .65));
  transition: border-color .22s, box-shadow .22s, transform .15s;
}
.prep-card:hover:not(:disabled) { border-color: #9fc8e8; box-shadow: 0 0 14px rgba(130, 180, 220, .25); transform: translateY(-1px); }
.prep-card:disabled { cursor: default; }
.prep-card.lack { opacity: .42; filter: saturate(.4); }
.prep-card.placed { border-color: rgba(140, 200, 150, .5); background: linear-gradient(135deg, rgba(22, 38, 28, .55), rgba(14, 22, 17, .65)); }
.prep-card.selecting { border-color: #cfe6f8; box-shadow: 0 0 18px rgba(150, 200, 240, .45); animation: exnode-breath 1.6s ease-in-out infinite; }
.prep-seal {
  flex: 0 0 34px; width: 34px; height: 34px; border-radius: 8px;
  display: grid; place-items: center;
  font-family: var(--font-title, serif); font-size: 17px; color: #dceaf5;
  background: radial-gradient(circle at 35% 30%, rgba(90, 130, 165, .55), rgba(34, 50, 66, .8));
  border: 1px solid rgba(160, 200, 230, .4);
  box-shadow: inset 0 1px 4px rgba(255, 255, 255, .12), 0 2px 6px rgba(0, 0, 0, .45);
  text-shadow: 0 1px 3px rgba(0, 0, 0, .6);
}
.prep-card.placed .prep-seal { color: #d8f0dd; background: radial-gradient(circle at 35% 30%, rgba(90, 150, 105, .5), rgba(30, 52, 36, .8)); border-color: rgba(150, 210, 160, .45); }
.prep-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.prep-name { font-size: 13px; letter-spacing: 1px; color: #e9dcc2; }
.prep-where { font-style: normal; margin-left: 7px; font-size: 10.5px; color: #9fd0aa; letter-spacing: 0; }
.prep-eff { font-size: 10.5px; color: #92aabb; line-height: 1.45; white-space: normal; }
.prep-card.placed .prep-eff { color: #8fae95; }
.prep-tag { flex: 0 0 auto; font-size: 11px; color: #b9a886; font-variant-numeric: tabular-nums; }
.prep-card.placed .prep-tag { color: #9fd0aa; font-size: 14px; }
/* 出手即开战手牌：射程够才亮——攻击常驻，第一招就是宣战 */
.exsc-hand { margin: 6px 0 0; }
.exsc-hand-head { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 5px; }
.eh-title { font-size: 12px; letter-spacing: 2px; color: #d8b88a; }
.eh-dist { font-size: 11px; color: #9fd0aa; letter-spacing: .5px; }
.eh-dist.alert { color: #e8a08e; }
.exsc-hand-row {
  display: flex; gap: 7px; overflow-x: auto; padding-bottom: 3px;
  -webkit-overflow-scrolling: touch; scrollbar-width: none;
}
.exsc-hand-row::-webkit-scrollbar { display: none; }
.hand-card {
  flex: 0 0 auto; min-width: 92px; padding: 7px 11px; border-radius: 9px; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  color: #ffe3cf; font-family: inherit;
  background: linear-gradient(135deg, rgba(110, 38, 26, .8), rgba(64, 20, 14, .9));
  border: 1px solid rgba(235, 130, 100, .5);
  box-shadow: 0 0 12px rgba(200, 70, 45, .22), inset 0 1px 3px rgba(255, 200, 170, .15);
  transition: box-shadow .2s, transform .12s;
}
.hand-card b { font-size: 13px; letter-spacing: 1px; font-weight: 600; white-space: nowrap; }
.hand-card i { font-style: normal; font-size: 10px; color: #f0bfa6; opacity: .85; }
.hand-card u { text-decoration: none; font-size: 9.5px; color: #c9a08e; white-space: nowrap; }
.hand-card:hover:not(:disabled) { box-shadow: 0 0 20px rgba(220, 90, 55, .45); transform: translateY(-1px); }
.hand-card.off {
  cursor: not-allowed; color: #9a8a7a; opacity: .62;
  background: rgba(30, 22, 18, .6); border-color: rgba(150, 120, 100, .25); box-shadow: none;
}
.hand-card.off b { font-weight: 400; }
.hand-card.treasure { border-color: rgba(226, 194, 119, .55); background: linear-gradient(135deg, rgba(96, 74, 26, .8), rgba(56, 42, 14, .9)); }
.hand-card.treasure:hover:not(:disabled) { box-shadow: 0 0 20px rgba(226, 194, 119, .45); }

/* 动手钮：战书规格（最重的一颗按钮） */
.exsc-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 8px; align-items: stretch; }
.cave-fight-btn {
  flex: 1 1 auto; display: flex; align-items: center; justify-content: center; gap: 10px;
  padding: 11px 18px; border-radius: 11px; cursor: pointer;
  font-size: 14.5px; letter-spacing: 1.5px; color: #ffe9d8;
  background: linear-gradient(135deg, rgba(120, 36, 26, .85), rgba(70, 18, 14, .92));
  border: 1px solid rgba(235, 130, 100, .55);
  box-shadow: 0 0 18px rgba(200, 70, 45, .3), inset 0 1px 4px rgba(255, 200, 170, .18);
  transition: box-shadow .25s, transform .15s;
}
.cave-fight-btn:hover { box-shadow: 0 0 28px rgba(220, 90, 55, .5), inset 0 1px 4px rgba(255, 200, 170, .25); transform: translateY(-1px); }
/* 偷袭态：未被察觉时的攻击常驻——潜行绿，与"迎战红"一眼分明 */
.cave-fight-btn.sneak {
  background: linear-gradient(135deg, rgba(26, 74, 48, .88), rgba(12, 40, 26, .94));
  border-color: rgba(120, 220, 160, .5);
  box-shadow: 0 0 18px rgba(70, 190, 120, .28), inset 0 1px 4px rgba(190, 255, 215, .15);
}
.cave-fight-btn.sneak:hover { box-shadow: 0 0 28px rgba(80, 210, 130, .45), inset 0 1px 4px rgba(190, 255, 215, .22); }
.cave-fight-btn.sneak .cfb-seal {
  background: radial-gradient(circle at 35% 30%, rgba(80, 200, 130, .9), rgba(20, 80, 45, .95));
  border-color: rgba(160, 255, 200, .6); box-shadow: 0 0 10px rgba(80, 210, 130, .6);
}
/* 洞窟无缝开战：镜头一沉（探索拉远→战斗推近）——是镜头在动，不是换场景 */
.combat-overlay.seamless-in .axis-field { animation: seamless-zoom .8s cubic-bezier(.3, .7, .25, 1) both; }
@keyframes seamless-zoom { from { transform: scale(.88); } to { transform: none; } }
/* 战斗版远端点名：锁定目标在镜头外——画框边缘亮名字，它在那头没丢 */
.fight-far-cue {
  position: absolute; right: 8px; top: 38%; z-index: 5; pointer-events: none;
  padding: 5px 9px; border-radius: 9px; font-size: 11.5px; letter-spacing: 1px;
  color: #f0c8b8; background: rgba(40, 12, 10, .78); border: 1px solid rgba(220, 110, 90, .45);
  text-shadow: 0 1px 3px #000; animation: farglow-pulse 2.2s ease-in-out infinite;
}
.fight-far-cue.left { right: auto; left: 8px; }
/* 多战线摘要徽标（teamfight-camera-design B5）：镜头外各战区在画框边缘列名+血量/状态，
 * 点一下镜头巡过去（不夺操作、不耗回合）。左右两栏竖叠，按战区位置贴边。 */
.front-cues { position: absolute; inset: 0; pointer-events: none; z-index: 6; }
.fc-col { position: absolute; top: 28%; display: flex; flex-direction: column; gap: 6px; }
.fc-col.left { left: 8px; align-items: flex-start; }
.fc-col.right { right: 8px; align-items: flex-end; }
.front-cue {
  pointer-events: auto; cursor: pointer;
  padding: 4px 8px; border-radius: 9px; font-size: 11px; letter-spacing: .6px;
  color: #e8d2b6; background: rgba(28, 20, 12, .82); border: 1px solid rgba(220, 180, 110, .5);
  text-shadow: 0 1px 3px #000; white-space: nowrap; transition: all .15s;
}
.front-cue:hover { background: rgba(60, 44, 22, .92); box-shadow: 0 0 10px rgba(226, 194, 119, .55); transform: scale(1.04); }
.front-cue.danger { color: #f4b3a4; border-color: rgba(225, 110, 90, .7); animation: farglow-pulse 1.6s ease-in-out infinite; }
.front-cue.cleared { color: #9fd0a8; border-color: rgba(120, 200, 130, .5); opacity: .8; }
.cfb-seal {
  width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center;
  font-family: var(--font-title, serif); font-size: 14px; color: #fff0e0;
  background: radial-gradient(circle at 35% 30%, rgba(220, 90, 55, .9), rgba(120, 30, 20, .95));
  border: 1px solid rgba(255, 170, 130, .6); box-shadow: 0 0 10px rgba(220, 90, 55, .6);
}
.cave-leave { flex: 0 0 auto; }

@media (max-width: 760px) {
  .exmap-title { font-size: 16px; letter-spacing: 3px; }
  .exmap-clock { flex-wrap: wrap; gap: 6px; font-size: 11px; max-width: 60vw; justify-content: flex-end; }
  .exnode { min-width: 44px; padding: 4px 6px; }
  .exnode .exname { font-size: 10px; }
  .expawn { width: 32px; height: 32px; }
  .exmap-notes { bottom: 96px; }
  .exmap-note { font-size: 12px; }
  .exmap-scene-stage { flex-basis: 44%; }
  .exmap-scene-panel { max-height: 58%; padding: 10px 12px 12px; }
  .exsc-p { font-size: 12.5px; }
}

/* ============================================================
 * 手机端覆盖（必须位于文件末尾，晚于上方桌面定义生效）
 * ============================================================ */
@media (max-width: 1180px) and (min-width: 761px) {
  .scene-head { left: 264px; }
  .scene-pins { left: 262px; right: 318px; }
  .scene-hotspots-layer { left: 262px; right: 318px; }
  .locals { left: 262px; right: 318px; }
}
@media (max-width: 760px) {
  /* 场景：顶部常驻横带（保留空间感与图钉导航）*/
  .scene-stage { position: relative; inset: auto; flex: 0 0 37vh; min-height: 218px; z-index: 1; }
  /* A1 渐隐过渡：场景带底缘溶入下方内容色，消除场景图与文字区的"硬切"接缝。
   * z-index:2 只压在背景图(z1)/受光层之上，仍低于 地点名(z3)/图钉(z4)/在场立绘(z5)——
   * 故底衬变暗、前景人物与导航依旧清晰。 */
  .scene-stage::after {
    content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 82px;
    pointer-events: none; z-index: 2;
    background: linear-gradient(180deg,
      rgba(12,10,8,0) 0%, rgba(12,10,8,.34) 44%, rgba(12,10,8,.8) 78%, var(--bg) 100%);
  }
  /* 地名归位顶部（避开天命栏：--obj-h 由 renderObjective 实测写入——天命栏几条就让几条的位，
     不再按定值 134px 猜、被多条目的天命栏压边·审美审计 jank#10）：
     据点铭牌——名号+风物小字，填充上半空旷、点明"此地何处" */
  #screen-game[data-mtab="act"] .scene-head {
    left: 12px; right: 12px; top: calc(52px + var(--obj-h, 82px) + 6px); bottom: auto; max-width: none;
    /* 可读性衬底：场景图亮部（山门天空）下，暗金文字会糊——加一层左起深色软渐变托住文字 */
    background: linear-gradient(180deg, rgba(8,6,4,.62) 0%, rgba(8,6,4,.40) 60%, rgba(8,6,4,0) 100%);
    padding: 10px 14px 16px; border-radius: 10px;
    -webkit-backdrop-filter: blur(1.5px); backdrop-filter: blur(1.5px);
  }
  .scene-head { left: 12px; top: 50px; bottom: auto; max-width: 62%; }
  .scene-head .loc-name { font-size: 19px; letter-spacing: 3px; }
  /* 据点风物小字：act 页显示（点明此地是什么地方，填上半空旷）*/
  #screen-game[data-mtab="act"] .loc-desc-inline {
    display: block; margin-top: 4px; font-size: 12.5px; line-height: 1.6;
    color: #d2c9b7; max-width: 92%; text-shadow: 0 1px 5px rgba(0,0,0,.95);
  }
  .scene-head .loc-desc-inline { display: none; }
  .scene-pins { left: 4%; right: 4%; top: 24%; bottom: 18%; }
  .scene-hotspots-layer { left: 4%; right: 4%; top: 24%; bottom: 18%; }
  /* 地图主界面化：行动页(act)场景做全屏底，旅行改走「舆图」tab——隐藏场景内旧 travel 图钉 */
  #screen-game[data-mtab="act"] .scene-stage { flex: 1 1 auto; min-height: 0; }
  #screen-game[data-mtab="act"] .scene-pins { display: none; }
  #screen-game[data-mtab="act"] .scene-confirm { display: none; }
  /* 行动已收进底部 sheet——场景上的悬浮"行动"图标圈是冗余，隐藏让场景干净沉浸；
   * 但 L2 氛围地标（.scene-look）保留——"点场景里的东西有反应"正是场景可交互的本体（v303） */
  #screen-game[data-mtab="act"] .scene-hotspots-layer .scene-hotspot:not(.scene-look) { display: none; }
  /* 在场人物立绘：站在场景里、浮在底部 sheet 之上（不被边框盖住）。
   * sheet 收起态约占底部 210px，立绘抬到其上方 */
  #screen-game[data-mtab="act"] .locals { bottom: 222px; }
  /* 立绘居中铺底，按人数自适应缩放（--ln-n 由 renderLocals 写入），挤而不溢出视口 */
  .locals { left: 3%; right: 3%; bottom: 4px; gap: 6px; justify-content: center; flex-wrap: nowrap; overflow: hidden; }
  .ln-figure { height: clamp(46px, calc(64vw / var(--ln-n, 4)), 92px); }
  /* 行动页：立绘站得更高更大，填充据点空旷（人物是据点的"活气"），浮在 sheet 之上 */
  #screen-game[data-mtab="act"] .locals { bottom: 210px; align-items: flex-end; }
  #screen-game[data-mtab="act"] .ln-figure { height: clamp(120px, calc(150vw / var(--ln-n, 3)), 240px); }
  .ln-plate { font-size: 10px; padding: 1px 5px; letter-spacing: 0; }
  .ln-plate .lr { display: none; }
  .scene-confirm { left: 50%; transform: translateX(-50%); width: 92vw; bottom: 8px; }

  /* A3/A4 韩立页：道具界面不显示地图（隐藏场景带），状态与储物袋左右并排。
   * 场景带隐去后顶栏(absolute)浮于 .layout 之上，故补足上留白避开顶栏。*/
  #screen-game[data-mtab="hero"] .scene-stage { display: none; }
  /* 韩立页=角色档案，不显示"天命/限时"世界际遇栏（那是行动页的事）——避免 fixed 栏压住角色卡 */
  #screen-game[data-mtab="hero"] .objective-bar { display: none; }
  #screen-game[data-mtab="hero"] .layout { padding-top: calc(48px + 12px); }
  .layout[data-mtab="hero"] .side-rail { display: flex; gap: 10px; align-items: flex-start; }
  /* 左：人物状态（粘顶——浏览/取用道具时数值始终在侧）*/
  .side-rail .sr-status { flex: 0 0 43%; min-width: 0; position: sticky; top: 0; align-self: flex-start; }
  .side-rail .sr-status .hero-card { padding: 9px 10px; gap: 8px; }
  .side-rail .sr-status .hero-portrait { width: 46px; height: 46px; font-size: 22px; }
  .side-rail .sr-status .hero-name { font-size: 16px; }
  .side-rail .sr-status .bar-group { margin-bottom: 6px; }
  .side-rail .sr-status .attr-grid { grid-template-columns: 1fr 1fr; gap: 5px; }
  .side-rail .sr-status .attr-cell { padding: 5px 7px; font-size: 12px; }
  /* 右：储物袋（分类页签 + 条目）*/
  .side-rail .sr-bag { flex: 1; min-width: 0; }
}

/* ============================================================
 * 箱庭舞台（Stage Scene）：横版轴 + 单位 + 对话气泡
 * 复用 L3 轴渲染管线的 DOM 结构与动画
 * ============================================================ */
.stage-overlay {
  position: fixed; inset: 0; z-index: 210;
  background: #0c0a08; overflow: hidden;
  transition: opacity .35s ease;
}
.stage-bg {
  position: absolute; inset: 0; background-size: cover; background-position: center;
  filter: saturate(.9) brightness(.62);
  will-change: transform; backface-visibility: hidden;
}
.stage-track {
  position: absolute; left: 0; right: 0; top: 0; bottom: 0;
  display: flex; align-items: flex-end;
  will-change: transform; transition: transform .6s ease;
}
.stage-lane {
  flex: 1; display: flex; align-items: flex-end; height: 42%;
}
.stage-lane .axis-cell {
  flex: 1; height: 100%; position: relative; cursor: default;
  transition: background .2s;
}
.stage-lane .axis-cell.can-move { cursor: pointer; }
.stage-lane .axis-cell.can-move:hover { background: rgba(200,176,140,.08); }
.stage-lane .axis-cell .dot {
  position: absolute; bottom: 6px; left: 50%; transform: translateX(-50%);
  width: 4px; height: 4px; border-radius: 50%; background: rgba(200,176,140,.2);
}
.stage-lane .axis-cell.can-move .dot { background: rgba(200,176,140,.5); }
.stage-lane .cave-hot { font-size: 10px; }
.stage-lane .cave-prep-mark { font-size: 10px; }

/* 舞台单位（复用 axis-unit 样式，补充 stage 专属） */
.stage-u { transition: left .6s ease; }
.stage-u.dim { opacity: .35; filter: grayscale(.6); }

/* 对话气泡 */
.stage-bubble {
  position: absolute; inset: 0; pointer-events: none; z-index: 5;
  opacity: 0; transition: opacity .25s ease;
}
.stage-bubble.on { opacity: 1; }
.stage-bubble-box {
  position: absolute; top: 18%; max-width: 70%;
  padding: 10px 16px; border-radius: 14px;
  background: rgba(14,10,9,.88); border: 1px solid rgba(200,176,140,.3);
  color: #e6d8c2; font-size: 14px; line-height: 1.6;
  box-shadow: 0 4px 18px rgba(0,0,0,.5);
  animation: bubblePop .3s ease;
}
.stage-bubble-box.right { transform: translateX(-50%); }
.stage-bubble-box.left { transform: translateX(-50%); }
.stage-bubble-name {
  font-size: 11px; color: #c8a868; margin-bottom: 4px; letter-spacing: 1px;
}
.stage-bubble-text { white-space: pre-wrap; word-break: break-word; }
.stage-bubble-tail {
  position: absolute; bottom: -7px; left: 50%; transform: translateX(-50%);
  width: 0; height: 0; border-left: 7px solid transparent; border-right: 7px solid transparent;
  border-top: 7px solid rgba(200,176,140,.3);
}
@keyframes bubblePop { from { opacity: 0; transform: translateX(-50%) translateY(8px); } to { opacity: 1; transform: translateX(-50%) translateY(0); } }

/* 旁白/提示/轻触继续 */
.stage-note {
  position: absolute; left: 0; right: 0; bottom: 44%;
  text-align: center; z-index: 4; pointer-events: none;
  opacity: 0; transition: opacity .3s ease;
}
.stage-note.on { opacity: 1; }
.stage-narr {
  display: inline-block; max-width: 80%; padding: 8px 18px;
  border-radius: 12px; background: rgba(14,10,9,.75);
  color: #b8a888; font-size: 13px; line-height: 1.6; font-style: italic;
}
.stage-hint {
  display: inline-block; padding: 6px 16px; border-radius: 10px;
  background: rgba(14,10,9,.7); color: #8a7a6a; font-size: 12px;
}
.stage-cue {
  display: inline-block; color: #8a7a6a; font-size: 11px;
  animation: cuePulse 2s ease infinite;
}
@keyframes cuePulse { 0%,100% { opacity: .5; } 50% { opacity: 1; } }

/* 抉择 */
.stage-choice {
  position: absolute; left: 0; right: 0; bottom: 38%;
  text-align: center; z-index: 6; pointer-events: none;
  opacity: 0; transition: opacity .25s ease;
}
.stage-choice.on { opacity: 1; pointer-events: auto; }
.stage-choice-prompt {
  margin-bottom: 8px; color: #c8a868; font-size: 13px;
}
.stage-choice .stage-choice {
  display: block; margin: 4px auto; max-width: 80%;
}

@media (max-width: 760px) {
  .stage-bubble-box { font-size: 13px; max-width: 76%; }
  .stage-narr { font-size: 12px; max-width: 88%; }
}
