/* 山海寻踪 · v1 · 新中式水墨底 */
* { margin:0; padding:0; box-sizing:border-box; -webkit-tap-highlight-color:transparent; }
html,body { height:100%; overflow:hidden; background:#14141f;
  font-family:"PingFang SC","Microsoft YaHei","Noto Sans SC",sans-serif;
  color:#e8e2d5; user-select:none; touch-action:manipulation; }

/* v304 移动端适配：布局基准高度 720，宽度由 js/core/fit.js 按屏幕宽高比推算（--gw）。
 * 缩放系数 k = 视口高 / 720 → 高度永远铺满、左右不留黑边（手机横屏 2.2:1 时布局宽约 1600）。
 * ⚠ 别改回 inset:0 —— 那样 .screen 会跟着真实视口走，手机横屏 UI 相对放大 2 倍多，
 *   头像/摇杆/对话框全糊在画面上挡住背景（用户实测反馈）。
 * ⚠ 这个文件里的 vh/vw 已全部换算成设计稿像素（1vw=12.8px / 1vh=7.2px），
 *   因为 vh/vw 永远按真实视口算，不认父容器 —— 会让技能切屏立绘从 460px 缩到 138px。
 *   以后新写样式请直接用 px，别再用 vh/vw。 */
.screen {
  position:fixed; left:0; top:0;
  width:var(--gw, 1280px); height:720px;
  transform-origin:0 0;
  transform:scale(var(--gs,1));
  display:none;
}
/* v304b：激活态提升为合成层。.screen 现在带 transform 缩放，若不留合成层，
 * 手机每帧都要把 1600×720 的整屏重新栅格化一遍，实测移动时掉帧。 */
.screen.active { display:block; will-change:transform; backface-visibility:hidden; }
.hidden { display:none !important; }

/* ---------- 标题画面 ---------- */
#screen-title {
  background:
    radial-gradient(ellipse 120% 60% at 50% -10%, #2c2c44 0%, transparent 60%),
    radial-gradient(ellipse 100% 50% at 50% 110%, #24303a 0%, transparent 55%),
    #14141f;
}
.title-wrap { height:100%; display:flex; flex-direction:column; align-items:center;
  justify-content:center; gap:26px; padding:32px 20px 44px; position:relative; }
.title-glyphs {
  font-size:min(243.2px,92px); font-weight:700; letter-spacing:.14em;
  color:#f0ead9; text-shadow:0 0 22px rgba(122,160,255,.35), 0 4px 14px rgba(0,0,0,.6);
}
.title-glyphs span { color:#9fb8ff; }
.title-sub { font-size:15px; letter-spacing:.42em; text-indent:.42em; color:#8d93a8; }
.title-seal {
  width:46px;height:46px;border-radius:9px;background:#b23a3a;color:#fff;
  display:flex;align-items:center;justify-content:center;font-size:24px;font-weight:700;
  box-shadow:0 3px 12px rgba(178,58,58,.45); transform:rotate(-6deg);
}
.title-menu { display:flex; flex-direction:column; gap:14px; width:min(998.4px,320px); margin-top:8px; }
.t-btn {
  min-height:52px; border:1.5px solid #565b70; border-radius:14px;
  background:rgba(38,40,60,.75); color:#e8e2d5; font-size:17px; letter-spacing:.18em;
  transition:transform .08s, background .15s;
}
.t-btn.primary { background:linear-gradient(135deg,#39406b,#2a3057); border-color:#7f8cff; }
.t-btn:active:not(:disabled) { transform:scale(.96); background:#39406b; }
.t-btn:disabled { opacity:.45; }
.title-foot { position:absolute; bottom:max(18px, env(safe-area-inset-bottom));
  font-size:12px; color:#565b70; letter-spacing:.2em; }

.overlay { position:fixed; inset:0; background:rgba(10,10,16,.72);
  display:flex; align-items:center; justify-content:center; z-index:50; }
.overlay-card { background:#1e2032; border:1px solid #565b70; border-radius:18px;
  padding:26px 24px; width:min(1075.2px,340px); font-size:15px; line-height:1.75; }
.overlay-card h3 { margin-bottom:12px; letter-spacing:.3em; color:#9fb8ff; }
.overlay-card .t-btn { width:100%; margin-top:14px; }

/* ---------- v313：手感调试面板（连点版本号 5 下） ---------- */
#tune-overlay { z-index:92; }   /* 压在菜单层/物品层之上，避免被遮 */
.tune-card { width:min(1075.2px,392px); }
.tune-sub { font-size:12px; color:#7d84a0; margin:-6px 0 20px; line-height:1.5; letter-spacing:.04em; }
.tune-row { display:grid; grid-template-columns:78px 1fr 56px; align-items:center; gap:10px; margin-bottom:18px; }
.tune-lb { font-size:15px; color:#cfd6f0; letter-spacing:.06em; line-height:1.25; }
.tune-lb em { display:block; font-style:normal; font-size:11px; color:#6f7694; letter-spacing:0; margin-top:2px; }
.tune-val { font-size:18px; color:#9fb8ff; text-align:right; font-variant-numeric:tabular-nums; }
#tune-overlay input[type=range] { -webkit-appearance:none; appearance:none;
  width:100%; height:36px; background:transparent; touch-action:none; }
#tune-overlay input[type=range]::-webkit-slider-runnable-track {
  height:6px; border-radius:3px;
  background:linear-gradient(90deg,#7d9dff 0%,#7d9dff var(--p,50%),#2a2e44 var(--p,50%),#2a2e44 100%); }
#tune-overlay input[type=range]::-webkit-slider-thumb { -webkit-appearance:none;
  width:28px; height:28px; margin-top:-11px; border-radius:50%;
  background:#9fb8ff; border:3px solid #1e2032; box-shadow:0 0 12px rgba(159,184,255,.55); }
#tune-overlay input[type=range]::-moz-range-track {
  height:6px; border-radius:3px;
  background:linear-gradient(90deg,#7d9dff 0%,#7d9dff var(--p,50%),#2a2e44 var(--p,50%),#2a2e44 100%); }
#tune-overlay input[type=range]::-moz-range-thumb {
  width:24px; height:24px; border-radius:50%; background:#9fb8ff; border:3px solid #1e2032; }
.tune-live { font-size:12px; color:#8d94b2; line-height:1.95; padding:12px 14px;
  border-radius:10px; background:rgba(255,255,255,.035); border:1px solid rgba(120,132,180,.22); }
.tune-live b { color:#cfd6f0; font-weight:600; }
.tune-tag { padding:1px 7px; border-radius:5px; font-size:11px; letter-spacing:.05em; }
.tune-tag.big { background:rgba(120,170,255,.18); color:#9fc0ff; }
.tune-tag.small { background:rgba(255,190,120,.16); color:#ffc98a; }
.tune-btns { display:flex; gap:10px; margin-top:16px; }
.tune-btns .t-btn { flex:1; width:auto; margin-top:0; }

/* ---------- 游戏画面 ---------- */
#screen-game { background:#241c12; }   /* 世界外的画框色：暖木深色，不再出现黑边 */
.hud { position:absolute; top:0; left:0; right:0; z-index:10;
  display:flex; justify-content:flex-end; align-items:center;   /* v101 ⚠08：场景名/版本移右上（左上让位属性卡） */
  padding:calc(env(safe-area-inset-top) + 8px) 14px 8px;
  background:linear-gradient(#14141fd9, transparent); pointer-events:none; }
.hud-loc { font-size:15px; letter-spacing:.25em; color:#cbc3ae; }
.hud-ver { font-size:11px; color:#565b70; }

#map-view { position:absolute; inset:0; overflow:hidden; }
#map-world { position:absolute; top:0; left:0; will-change:transform; transform-origin:0 0; }

.tile { position:absolute; width:var(--ts); height:var(--ts); }
/* 方案A/C：有整幅背景时 tile 全部隐形，仅承担碰撞逻辑 */
#map-world.has-bg .tile { visibility:hidden; }

#map-bg { position:absolute; inset:0; width:100%; height:100%; object-fit:fill; pointer-events:none; }

/* v136 实31：背景预栅格化 canvas（#map-view 首子节点，#map-world 之下；相机增量 drawImage） */
#map-bg-canvas { position:absolute; top:-12px; left:-12px; width:calc(100% + 24px); height:calc(100% + 24px); pointer-events:none; }   /* v173：外扩 12px 容纳屏震，目标绘入缓冲中央 */
#map-camera { position:absolute; inset:0; transform-origin:50% 50%; }   /* v173：镜头演出层（震屏/推镜/Boss 聚焦），罩住背景+实体保持对齐 */
#map-bg-canvas.world-ruin { filter: saturate(.5) hue-rotate(215deg) brightness(.85) contrast(1.05); }   /* 崩坏态与 #map-world 同款染背景 */

/* v195 任务目标标记：改成"地上的一滩光"——不再是硬边金环（用户：箭头指引的东西放在这很唐突）。
   主角=暖金光池（恒亮，当前目标必须一眼看见）；支线=小而淡的紫光（近距才显）。

   v276【必读 · 亮反光地面上的可见性，别回退】
     实测（幻境长巷 · 720 视口）：主线金圈落在屏 y646–723，本来就贴屏幕下缘；而长巷地面是
     一整片反光水面，暖金 #ffe096 与亮水面明度撞车——`tools/_BEFORE_v275_bottom.png` 里
     150px 光柱只剩两条几乎认不出的浅痕，金圈整个消失（用户"指引圈一点都不明显"的根因在此，
     不是没生成）。v276 三处改动，**任何一处都不要单独回退**：
       ① 金圈：饱和琥珀芯 + 内亮唇 + 最外一圈**窄暗线**（约 3px）。
          暗线给亮底一个确定边界，琥珀芯给暗底一个亮度差——两头都压得住。
       ② qm-pulse 的 opacity 谷底从 .55 提到 .88（.55 就是"一半时间等于不存在"的主因）。
       ③ 光柱补一根不透明实心内芯（::after，4px 窄柱 + 外发光），远看是一条"柱"，
          而不是一片会在反光面上化开的雾辉。
     三条踩过的坑（都试过、都不行，别再走一遍）：
       · 不能靠"把芯调亮"取胜——书院廊下暖石板本身就到 (230,205,160) 这一档，
         奶白芯扑上去等于没画（`tools/_shot_v276_shuyuan_main13.png` 早期版本）。
       · 不能把暗衬加宽到 70% 起步——那会变成一口"盆"，用户要的是"一滩光"。
       · 不能用 1px 实线 border 代替最外暗线——边框挂在 border-radius 上，
         会跑到光晕外面变成"画上去的椭圆"，很唐突。
     另注：径向渐变必须写 `ellipse 50% 50%`——不写就是 farthest-corner，
     实际半径是内切椭圆的 √2 倍，所有色标位置整体错位（v276 第一次改就栽在这）。
     支线（.soft）不受影响：紫色与任何底色都不同色相，本来就不糊；::before/::after 一律 display:none。 */
#quest-markers { position:absolute; left:0; top:0; width:100%; height:100%; pointer-events:none; }
.quest-marker {
  position:absolute; width:84px; height:46px;
  border:none; border-radius:50%;
  background:
    /* 上层 · 池芯：饱和琥珀金。
       教训（v276 三次试错）：**别指望靠"更亮"取胜**——周伯铺子的木地板、书院廊下的暖石板
       本身就是 (230,205,160) 这一档，奶白芯扑上去等于没画。要靠饱和度把色相拉开。 */
    radial-gradient(ellipse 50% 50% at 50% 50%,
      rgba(255,206,104,.90) 0%,
      rgba(255,190,72,.80) 40%,
      rgba(255,170,44,.46) 72%,
      rgba(255,164,36,.20) 88%,
      rgba(255,160,32,0) 100%),
    /* 下层 · 池沿：内亮唇 + 最外一圈**窄暗线**。
       暗线只有 96%→100%（约 2px），作用是"给亮池一个确定的边界"——亮背景上靠它、暗背景上靠
       琥珀芯，两头都压得住。⚠ 别把暗线加宽到 70% 起步：那会变成一口"盆"，用户要的是"一滩光"。
       v279：原 93% 起步（≈5 屏幕px @1.68×）**站在圈里看是脚下一圈黑影**，
         改为 96% + 降 alpha，边界还在但不读作影子——远看的可见性已交给柱顶菱形针。 */
    radial-gradient(ellipse 50% 50% at 50% 50%,
      rgba(0,0,0,0) 0%,
      rgba(0,0,0,0) 78%,
      rgba(255,242,192,.54) 84%,
      rgba(255,248,214,.72) 92%,
      rgba(58,30,4,.30) 96%,
      rgba(52,26,3,.34) 100%);
  box-shadow:
    0 3px 7px 0 rgba(34,18,4,.28),        /* 贴地暗影：让光池"陷"在地面，而不是浮贴片 */
    0 0 18px 5px rgba(255,196,92,.55),    /* 近辉 */
    0 0 50px 16px rgba(255,146,36,.30);   /* 远辉：橙尾把暖金和冷水面在色相上拉开 */
  animation:qm-pulse 2.2s ease-in-out infinite;
}
@keyframes qm-pulse {
  /* v276：谷底 .88（原 .55 会让圈有一半时间"看不见"）；仍在呼吸，但不会消失 */
  0%,100% { transform:scale(.92); opacity:.88; }
  50% { transform:scale(1.08); opacity:1; }
}
/* v274 主线目标光柱：金圈贴地且贴屏幕下缘（实测 y410 的圈在 720 视口里被裁掉一半、
 *   开对话时又被对话框压住——用户站在引灯人旁根本看不见信的金圈）。
 *   竖向光束从圈心升起，越过对话框顶缘；远处也能一眼锁定（MMO 指路柱惯例）。
 *   仅主线有柱（.soft 支线圈不出柱）；随圈呼吸动画同缩放。
 *   v276：外层柔光降低一点（原来 .80 起点太"糊"），对比度交给下面的实心内芯。
 *
 * —— v279：用户实机"我没看见金光啊"。量出来的结论（别再调第四次颜色了）——
 *   ① 长巷 world 2603×428，camera.js 是 **cover** 缩放：720/428 = 1.68 →
 *      y=410 的标记全部被顶到屏幕 y≈685/720 这一条里，只在最下沿 30px 内活动；
 *   ② 光柱中段 ΔL 其实有 +59，**缺的不是亮度是"边"**：13 屏幕px 宽的奶白渐变色
 *      在暖雾+灯笼光斑的底图上，和底图自己的光斑是同一类东西，眼睛没有边界可依；
 *   ③ 主角 z=410 > 标记 z=409 —— 站上去之后池芯与柱底**全被自己挡住**，
 *      头顶只剩一条淡痕；
 *   ④ 屏幕右下的「探」按钮 (right:22 宽高110) 会整块压住标记——玩家 x∈[1608,1677]
 *      时金圈正好落在按钮底下，而那正是沿路走过来的位置。
 *   对照证据：同屏的紫色「裂口门」一眼能看见——因为它是 3px 硬边拱形、175 屏幕px 高、
 *   越过了主角头顶。所以修法照抄它：**给柱加实边 + 在柱顶加一颗浮起的菱形指针**，
 *   指到主角头顶与「探」键之上。造型语义仍是"地上的一滩光"，不与门混。 */
.quest-marker::before {
  content:''; position:absolute; left:50%; bottom:12px;
  width:10px; height:150px; transform:translateX(-50%);
  /* 横向三段：1.5px 深褐边 / 7px 饱和金芯 / 1.5px 深褐边。
     ⚠ 这两条深边是"看得见"的全部理由。别为了"更通透"把它们调淡——
     v276 就是把芯做成奶白 (255,250,228)，在奶白暖雾上等于没画。
     宽度 10（不是 16）：再宽就读成"一根杆子"而不是"一道光"，但不能再窄，
     1.68× 缩放下 10px ≈ 17 屏幕px，比原先 13px 的淡色带更细也更容易锁定。 */
  background:linear-gradient(to right,
    rgba(72,36,4,.84) 0 1.5px,
    rgba(255,196,54,.92) 1.5px 8.5px,
    rgba(72,36,4,.84) 8.5px 100%);
  /* 纵向淡出必须用 mask，不能叠第二层 to-top 渐变——那会把上面的边一起盖掉 */
  -webkit-mask-image:linear-gradient(to top, #000 0%, #000 50%, rgba(0,0,0,.50) 80%, transparent 100%);
  mask-image:linear-gradient(to top, #000 0%, #000 50%, rgba(0,0,0,.50) 80%, transparent 100%);
  border-radius:2px;
  box-shadow:0 0 10px rgba(255,190,60,.55);
}
/* v279 柱顶菱形指针：浮在光柱顶端，上下浮动。
 *   存在的理由有三个，缺一不可：
 *   ① 几何硬边——写意画底图里，多边形是唯一能一眼分离出来的形状；
 *   ② 位置够高——1.68× 缩放下落在屏幕 y≈440，越过主角头顶(≈616)与「探」键(≈586)；
 *   ③ 上下浮动比放大缩小更容易被余光抓到（原 qm-pulse 只动 scale，在 1.68× 下太轻微）。
 *   ⚠ 动画里必须把 translateX(-50%) 和 rotate(45deg) 一起写回：transform 会整体覆盖，
 *     漏一个指针就会跳位/不转。 */
.quest-marker::after {
  content:''; position:absolute; left:50%; bottom:152px;
  width:14px; height:14px; transform:translateX(-50%) rotate(45deg);
  background:linear-gradient(135deg, #ffe9a8 0%, #ffc02e 45%, #e8901a 100%);
  border:2px solid rgba(64,30,2,.94);       /* 深褐描边：亮/暗背景都能读出轮廓 */
  border-radius:3px;
  box-shadow:0 0 0 1.5px rgba(255,238,180,.55),   /* 描边外加一圈亮唇，免得深边发死 */
             0 0 16px 4px rgba(255,170,36,.60);
  animation:qm-pin 1.5s ease-in-out infinite;
  pointer-events:none;
}
@keyframes qm-pin {
  0%,100% { transform:translateX(-50%) translateY(0)    rotate(45deg); }
  50%     { transform:translateX(-50%) translateY(-8px) rotate(45deg); }
}
/* v279：目标挂在 NPC 身上（.at-npc）→ 不出柱、不出针，退回纯光池。
 *   原因见 map.js 处注释：菱形针会正好压在 NPC 名牌上（周伯铺子实测）。 */
.quest-marker.at-npc::before,
.quest-marker.at-npc::after { display:none; }
.quest-marker.soft:not(.gate)::before,
.quest-marker.soft:not(.gate)::after { display:none; }
/* v276 走近再提一档：主线标永远带 qm-near（map.js 里对 !side 无条件 add），
   所以这条实际等于"主线常态"——呼吸快一档 + 光晕更亮，
   站着不动时余光也能抓到它。支线的提亮在下面 .soft.qm-near 里单独管。
   注意：这里只动 box-shadow / animation，不要再加 border（见上面"池沿"那条注释）。 */
.quest-marker:not(.soft).qm-near {
  animation-duration:1.6s;
  box-shadow:
    0 2px 8px 1px rgba(28,16,4,.42),
    0 0 26px 8px rgba(255,214,134,.72),
    0 0 68px 22px rgba(255,160,48,.38);
}

/* v293 大 BOSS 刷新点：**暗红余烬**（用户拍板："BOSS 点该和捡东西的金圈区分开"）
 *   语义：金池 = 这儿有东西可以捡/可以探；暗红余烬 = 这儿有东西在等你，进去就是一场硬仗。
 *   和 v277 给门换造型是同一个教训——**同一个形状不该承担两种意思**：
 *     玩家照着金光走过去按「探」，本以为是拾取，结果"穷奇，醒了"直接开战。
 *
 *   造型不动（还是"地上的一滩光 + 光柱 + 柱顶菱形针"），只换色相 —— 玩家已经认得这套指路语言，
 *   换形状反而要重新学。三处一起换：池芯/池沿、光柱、菱形针，缺一处就会"金身子红脑袋"。
 *
 *   ⚠ 选择器必须写 `.quest-marker.boss` **和** `.quest-marker.boss.qm-near` 两条：
 *     主线标永远带 qm-near，而 `.quest-marker:not(.soft).qm-near` 的 box-shadow 是 0,3,0，
 *     权重比单写 `.quest-marker.boss`（0,2,0）高，会被盖回金光。gate 那条注释踩过同一个坑。 */
.quest-marker.boss,
.quest-marker.boss.qm-near {
  background:
    /* 上层 · 池芯：余光里的炭火红，比金池更暗、更沉 */
    radial-gradient(ellipse 50% 50% at 50% 50%,
      rgba(255,142,86,.92) 0%,
      rgba(228,76,42,.82) 40%,
      rgba(172,38,22,.48) 72%,
      rgba(124,26,14,.20) 88%,
      rgba(110,20,10,0) 100%),
    /* 下层 · 池沿：暖橙亮唇 + 窄暗线（与金池同构，只换色） */
    radial-gradient(ellipse 50% 50% at 50% 50%,
      rgba(0,0,0,0) 0%,
      rgba(0,0,0,0) 78%,
      rgba(255,180,124,.50) 84%,
      rgba(255,152,96,.66) 92%,
      rgba(46,8,2,.34) 96%,
      rgba(38,6,2,.38) 100%);
  box-shadow:
    0 3px 7px 0 rgba(26,6,2,.34),
    0 0 18px 5px rgba(255,98,50,.52),
    0 0 50px 16px rgba(186,32,16,.34);
}
.quest-marker.boss::before {
  background:linear-gradient(to right,
    rgba(56,8,2,.88) 0 1.5px,
    rgba(255,122,66,.94) 1.5px 8.5px,
    rgba(56,8,2,.88) 8.5px 100%);
  box-shadow:0 0 12px rgba(226,62,28,.62);
}
.quest-marker.boss::after {
  background:linear-gradient(135deg, #ffc99e 0%, #f2603a 45%, #a02118 100%);
  border-color:rgba(46,6,2,.94);
  box-shadow:0 0 0 1.5px rgba(255,192,152,.52),
             0 0 16px 4px rgba(224,70,34,.62);
}

/* v277 门类目标（探查点带 exit）：**不画"地上的一滩光"**。
   原因不是好看难看，是语义：地面光池读作"这儿有东西可以捡/可以探"，而门要读作"这是一条路"。
   用户实机就是这么被坑的——看见地上金光走过去按「探」，离图词一播完直接被送进另一张图。
   现在改成门口立起一道**光门**（拱形光框 + 门内柔光），一眼能分出"路"和"东西"。

   v278：门色由 `--gate`（三个空格分隔的通道值）决定——主线金 / 支线紫。
     同一个造型承担两种语义：金门 = 主线的路，紫门 = 支线的路。
     裂口（支线）就是紫门；它以前挂在主线目标表里，穿的是金圈。

   ⚠ 三条选择器都要写全：
     · 单独 `.quest-marker.gate` 会被 `.quest-marker:not(.soft).qm-near` 的 box-shadow 盖回来
       （同权重、后写者胜；门类主线永远带 qm-near）；
     · `.quest-marker.gate.soft` 必须显式写，否则被 `.quest-marker.soft` 的紫光池背景盖回来。 */
.quest-marker.gate,
.quest-marker.gate.qm-near,
.quest-marker.gate.soft {
  background:none;
  /* 只有门口一小片光把门"按"在地上（不是光池，是门槛的光） */
  box-shadow:0 5px 14px -5px rgb(var(--gate) / .75);
}
.quest-marker.gate      { --gate: 255 206 110; }   /* 主线金 */
.quest-marker.gate.soft { --gate: 196 160 255; }   /* 支线紫（与 .soft 同色系） */
/* ⚠ v302【必读 · 别删下面那几条 reset】
 *   `::before`/`::after` 是 `.quest-marker` 的**共用伪元素**：前者是"光柱"，后者是"柱顶菱形针"。
 *   门类只覆盖了尺寸/填充，**没覆盖的每一条都会从光柱/菱形针那里继承过来**。v277 起漏了三条：
 *
 *     ① `border`   —— 菱形针的 `2px solid rgba(64,30,2,.94)` 深褐硬边，被门内柔光(::after)继承，
 *                     于是门外多出一圈**深棕色粗框**；
 *     ② `animation`—— 菱形针的 `qm-pin`（`rotate(45deg)` + 上下浮 8px）也被继承，
 *                     于是那个深褐框被**整体转了 45°** 还上下飘 —— 就是用户两次报的"黑色斜的东西"；
 *     ③ `mask-image`—— 光柱的 `to top` 渐隐对伪元素**不区分用途**，把门框上半截一起淡掉。
 *
 *   实测（tools/_probe_riftmark5.js 打到屏幕上量 computed style）：
 *     `::after` 的 transform = matrix(0.707107,0.707107,-0.707107,0.707107,-26,0) = rotate(45deg)，
 *     borderTopColor = rgba(64,30,2,.94)。与用户截图里那个"上圆下尖、倾斜、深棕描边"逐项吻合。
 *   所以不是设计问题，是**继承没清干净**——三条 reset 缺一不可。 */
.quest-marker.gate::before {
  left:50%; bottom:16px; width:54px; height:104px;
  transform:translateX(-50%);
  border:3px solid rgb(var(--gate) / .92);
  border-bottom:none;                      /* 门框不封底——门是立在地上的一道口子 */
  border-radius:27px 27px 0 0;
  background:linear-gradient(to top, rgb(var(--gate) / .52) 0%, rgb(var(--gate) / .26) 55%, rgb(var(--gate) / .08) 100%);
  box-shadow:0 0 18px rgb(var(--gate) / .80), inset 0 0 24px rgb(var(--gate) / .45);
  -webkit-mask-image:none;                 /* ① 清光柱渐隐：门要整扇都看得见 */
  mask-image:none;
}
.quest-marker.gate::after {
  left:50%; bottom:16px; width:48px; height:98px;
  transform:translateX(-50%);
  background:linear-gradient(to top, rgb(var(--gate) / .34) 0%, rgb(var(--gate) / .15) 70%, rgb(var(--gate) / 0) 100%);
  border-radius:24px 24px 0 0;
  box-shadow:none;
  border:none;                             /* ★ 清菱形针的 2px 深褐硬边 —— "黑色斜的东西"的深色来源 */
  animation:none;                          /* ★ 清 qm-pin 的 rotate(45deg)+浮动 —— "斜"的全部来源 */
  -webkit-mask-image:none;                 /* ★ 清光柱渐隐 */
  mask-image:none;
}
/* v194 支线目标光圈（紫，与主线金色区分）——v263 重调：旧版 38×24 且"靠近才显"（默认 opacity:0），
   玩家在房间另一头根本看不到（实机反馈"指引光圈一点都不明显"）。
   现在：尺寸接近主线、恒常可见、带外发光；靠近只再提亮一档，不再当可见性开关。
   ⚠ 动画只动 transform：若在 @keyframes 里动 opacity，会压掉 .qm-near 的提亮 */
.quest-marker.soft {
  width:68px; height:40px; border:none; border-radius:50%;
  background:radial-gradient(ellipse at center, rgba(230,208,255,.96) 0%, rgba(178,136,255,.60) 44%, rgba(126,84,226,0) 78%);
  box-shadow:0 0 16px 4px rgba(178,136,255,.55), 0 0 36px 12px rgba(126,84,226,.30);
  animation:qm-soft 2.4s ease-in-out infinite;
  opacity:.95;
  transition:opacity .2s ease, box-shadow .2s ease;
}
@keyframes qm-soft {
  0%,100% { transform:scale(.86); }
  50%     { transform:scale(1.12); }
}
/* 靠近时提亮一档（不再是显隐开关——远看也必须看得见） */
.quest-marker.soft.qm-near {
  opacity:1;
  box-shadow:0 0 22px 6px rgba(178,136,255,.72), 0 0 52px 18px rgba(126,84,226,.40);
}
/* v194 近距显影：NPC 名字牌默认隐去，靠近才浮现（消除头顶"图标"堆叠感） */
#map-world.npc-prox .npc-name { opacity:0; transition:opacity .18s ease; }
#map-world.npc-prox .npc-name.np-near { opacity:1; }
/* v195：跟随精灵（珂儿）右向镜像——她的行走帧只有一套侧向（朝左），右向翻转 */
.fol-keer img.mirror { transform:translateX(-50%) scaleX(-1); }
/* v213 [N13]：珂儿脚下椭圆接触影——"落地感"的视觉锚（轮廓 drop-shadow 撑不起接地感） */
.fol-keer::after { content:''; position:absolute; left:50%; bottom:-3%; transform:translateX(-50%);
  width:56%; height:9%; border-radius:50%; z-index:0;
  background:radial-gradient(ellipse at center, rgba(0,0,0,.38) 0%, rgba(0,0,0,.2) 45%, transparent 72%); }
.fol-keer img { z-index:1; }

/* 场景小物件 sprite（世界座标内绝对定位） */
.decor { position:absolute; z-index:3; pointer-events:none; }
/* v203 [08]：第四章入口贴图——灰化态（未开启）；main≥20 时 map.js 给 #map-world 挂 .ch4-open 褪灰 */
.decor.ch4-gate { filter:grayscale(1) brightness(.85) opacity(.8); transition:filter .8s ease, opacity .8s ease; }
#map-world.ch4-open .decor.ch4-gate { filter:grayscale(0) brightness(1) opacity(1) drop-shadow(0 0 10px rgba(255,214,150,.7)); }
/* v203 [07]：三画框改挂轴形态（暖纸暗角，去贴纸感）；玉牌压投影 + 极轻漂浮（translateY 单参） */
.decor.hj-paint { filter:sepia(.12) brightness(.97) drop-shadow(0 3px 5px rgba(40,30,18,.38));
  animation:paint-breath 3.4s ease-in-out infinite; transform-origin:50% 100%; }
@keyframes paint-breath { 0%,100% { transform:scale(1); } 50% { transform:scale(1.035); } }
.decor.hj-jade { filter:drop-shadow(0 3px 5px rgba(24,52,36,.55)); animation:jade-bob 3.6s ease-in-out infinite; }
@keyframes jade-bob { 0%,100% { transform:translateY(0); } 50% { transform:translateY(-2px); } }
.decor.flicker { animation:flicker 1.9s infinite ease-in-out; }
/* v216：书院东端「再入梦」空间裂缝——黑底转 alpha 素材 + 提饱和/紫金辉光投影 + 微呼吸 */
.decor.sy-dream-rift { animation:rift-breath 3.2s ease-in-out infinite; }
@keyframes rift-breath {
  0%,100% { filter:brightness(1.05) saturate(1.35) drop-shadow(0 0 10px rgba(150,110,255,.75)); }
  50%     { filter:brightness(1.25) saturate(1.35) drop-shadow(0 0 15px rgba(190,150,255,.9)); }
}
@keyframes flicker {
  0%,100% { filter:brightness(1) drop-shadow(0 0 3px rgba(255,200,100,.6)); transform:scale(1); }
  25%     { filter:brightness(1.15) drop-shadow(0 0 6px rgba(255,180,80,.8)); transform:scale(1.02); }
  50%     { filter:brightness(.9) drop-shadow(0 0 2px rgba(255,220,120,.5)); transform:scale(.98); }
  75%     { filter:brightness(1.1) drop-shadow(0 0 5px rgba(255,190,90,.7)); transform:scale(1.01); }
}
.decor.flame { animation:flame 1.2s infinite ease-in-out; }
@keyframes flame {
  0%,100% { transform:scaleY(1) rotate(-2deg); filter:brightness(1); }
  50% { transform:scaleY(1.15) rotate(2deg); filter:brightness(1.2); }
}
.decor.floaty { animation:floaty 3.6s infinite ease-in-out; }
@keyframes floaty { 50% { transform:translateY(-4px); } }
/* v20：信物贴片光晕 + 落点光圈 */
.decor.halo { filter:drop-shadow(0 0 7px rgba(150,200,255,.9)) drop-shadow(0 0 2px rgba(200,230,255,.8)); }
.glow-ellipse { position:absolute; z-index:3; pointer-events:none; border-radius:50%;
  background:radial-gradient(ellipse at center, rgba(150,200,255,.55), rgba(150,200,255,0) 72%);
  animation:glow-pulse 2.6s infinite ease-in-out; }
/* v205 [N7]：梦境裂口光晕——紫金色贴底图裂口色系，高不透明度 + 双层脉冲，弱感淡蓝退役 */
.glow-ellipse.hj-lie-glow { z-index:2; border-radius:24%;
  background:radial-gradient(ellipse at center, rgba(196,150,255,.85) 0%, rgba(150,110,255,.45) 46%, rgba(120,90,220,0) 74%);
  box-shadow:0 0 26px 8px rgba(170,120,255,.5); animation:lie-glow-pulse 2.2s infinite ease-in-out; }
@keyframes lie-glow-pulse { 0%,100% { opacity:1; } 50% { opacity:.55; } }
@keyframes glow-pulse { 50% { opacity:.5; } }
/* v284【用户："这两个传送门做成这个图片的这种 / 能做那种动态的吗"】
 * v285【用户："动态我是满意的，但是这两个传送门我感觉不协调，在整个构图里给人很生硬的感觉"】
 *   三处根因，逐条修（改之前先把贴图按真实座标合进 jiuwei_bg 出静帧看过，不是拍脑袋）：
 *
 *   ① **素材里带着星云和地面反光**。v284 把原图整块键了出来，环外那圈云气一起打包，
 *      贴到巷子里就是一团"紫色圆角方块"糊在石头上——这才是"贴上去"的真正来源。
 *      v285 的管线（tools/make_portal_v285.js）在 1.12× 光环半径处**硬切 + 羽化**，
 *      只留环本身；顺带做了内深外暗的纵深衰减、珠环压 8%、亮部转奶油暖。
 *   ② **z-index:4 让光门盖在牌坊前面**，珠子压在石头上，没有"装在门洞里"的遮挡感。
 *      降到 2（低于 `.decor` 的 3）——牌坊的石框压住环的外沿，门才像开在墙上。
 *   ③ **两扇是同一枚印章、同一亮度**。现在按远近分两档（远处吃空气雾、近处更实更暗）；
 *      近处那扇把珠环错开 17°，再补一圈 `::before` 落地光和 `::after` 接触影，让它站得住。
 *
 *   三层：.p-bloom 柔光（最底）→ .p-base 环（只做呼吸）→ .p-swirl 内涡流（26s 慢转）。
 *   ⚠ 整张一起转 = 贴纸打转；只有内圈转、环钉住才对。
 *   ⚠ 三层必须像素对齐：由同一条管线、同一个裁切框切出来，换图必须重跑，不能只换一张。
 *   ⚠ 外层不能 overflow:hidden —— 柔光要往框外溢，裁了会切出一圈硬边。 */
.decor.portal { z-index:2; }          /* v285：压到牌坊(3)之下 —— 门要"装在"门洞里 */
.decor.portal img { position:absolute; left:0; top:0; width:100%; height:100%; pointer-events:none; }
.decor.portal .p-bloom { left:-22.5%; top:-22.5%; width:145%; height:145%; }
.decor.portal .p-base { animation:portal-breath 3.6s ease-in-out infinite; }
.decor.portal .p-swirl { animation:portal-spin 26s linear infinite; will-change:transform; }
@keyframes portal-spin { to { transform:rotate(360deg); } }
@keyframes portal-breath {
  0%,100% { filter:drop-shadow(0 0 5px rgba(150,200,255,.50)); }
  50%     { filter:drop-shadow(0 0 13px rgba(186,150,255,.90)); }
}
/* v285：远近两档 —— 远处的门吃一层空气雾（对比降、亮度提、饱和降），近处的门更实更暗。
 *   两扇调成一样的亮度，眼睛就会觉得它们是两枚贴纸，而不是"一近一远的两扇门"。 */
.decor.portal.far  { filter:saturate(.92) contrast(.96) brightness(1.03); }
.decor.portal.near { filter:saturate(1.02) contrast(1.03) brightness(.93); }
/* 两扇不能是同一枚印章：近处这扇把珠环错开 17°（圆形素材转起来不会露出方角） */
.decor.portal.near .p-base { transform:rotate(17deg); }
/* 巷口那扇没有建筑框，得给它"站住"的两样东西（都压在贴图下面，z-index:-1） */
.decor.portal.near::before,
.decor.portal.near::after { content:""; position:absolute; z-index:-1; pointer-events:none; }
.decor.portal.near::before {          /* 落地光：横铺在地上，比门宽 */
  left:-52%; right:-52%; bottom:-16%; height:46%;
  background:radial-gradient(ellipse at 50% 50%, rgba(186,150,255,.30), rgba(186,150,255,0) 72%);
  filter:blur(7px);
}
.decor.portal.near::after {           /* 接触影：贴着门底的一条暗影 */
  left:2%; right:2%; bottom:-8%; height:26%;
  background:radial-gradient(ellipse at 50% 50%, rgba(26,14,36,.55), rgba(26,14,36,0) 70%);
  filter:blur(3px);
}
/* 系统省电模式：停转停呼吸，留一张静态光门（低端机别为了个门把风扇拉满） */
@media (prefers-reduced-motion: reduce) {
  .decor.portal .p-base, .decor.portal .p-swirl { animation:none; }
}
.tile.floor { background:#2a2419; box-shadow:inset 0 0 0 1px #221d13; }
.tile.wall  { background:#1b1c28; box-shadow:inset 0 0 0 1px #12131c; }
.tile.bookshelf { background:repeating-linear-gradient(180deg,#4a3620 0 30%,#3a2a18 30% 34%);
  box-shadow:inset 0 0 0 2px #2a1d0f; }
.tile.bookshelf::after { content:"书"; position:absolute; inset:0; display:flex;
  align-items:center; justify-content:center; font-size:calc(var(--ts)*.36); color:#caa46a; opacity:.8; }
.tile.desk { background:#5a4526; box-shadow:inset 0 0 0 2px #3a2c16; }
.tile.desk::after { content:"案"; position:absolute; inset:0; display:flex;
  align-items:center; justify-content:center; font-size:calc(var(--ts)*.36); color:#f0dcae; }
.tile.door { background:#20263a; box-shadow:inset 0 0 0 2px #39406b; }
.tile.door::after { content:"门"; position:absolute; inset:0; display:flex;
  align-items:center; justify-content:center; font-size:calc(var(--ts)*.34); color:#8fa0ff; }

#player { position:absolute; width:var(--ts); height:var(--ts); z-index:5;
  pointer-events:none; }   /* v20：像素级连续移动，逐帧直写 transform，不加过渡 */
#player img {
  position:absolute; left:50%; bottom:-8%;
  height:220%;                         /* 仙剑考据硬标准：站姿≈屏高22-25%（2.2格） */
  width:auto;                          /* v164 显式等比：宽度按源图比例推导，禁止被拉伸 */
  object-fit:contain;                  /* v164 防御：素材宽高比与预期不符时也等比显示 */
  transform:translateX(-50%);
  transform-origin:50% 100%;           /* v151 行走挤压绕脚底（translateX 居中/镜像不受影响） */
  filter:drop-shadow(0 6px 7px rgba(0,0,0,.5));
}
#player.mirror img { transform:translateX(-50%) scaleX(-1); }
/* 凑近交互：朝目标探身小半格 */
#player.lean-left  { margin-left:-16px; }
#player.lean-right { margin-left:16px; }
#player.lean-up    { margin-bottom:10px; }
#player.lean-down  { margin-bottom:-8px; }
/* v152：行走改为真正的 4 帧序列图（map.js 按 FRAME_MS 切 walk_front/back_*），
   不再对单帧立绘做挤压/上下 bob——单帧图做不出迈步，挤压只会像橡皮。 */

/* v76：街面 NPC（脚底锚点与玩家同规；名字牌挂脚边，按 y 排序遮挡） */
.npc { position:absolute; width:var(--ts); height:var(--ts); pointer-events:none; }
.npc img {
  position:absolute; left:50%; bottom:-8%;
  height:220%; width:auto;             /* v164 显式等比（同 #player img） */
  object-fit:contain;                  /* v164 防御性等比约束 */
  transform:translateX(-50%);
  filter:drop-shadow(0 6px 7px rgba(0,0,0,.5));
}
.npc-name {
  position:absolute; left:50%; top:-138%; transform:translateX(-50%);
  white-space:nowrap; font-size:calc(var(--ts)*.20); letter-spacing:.1em;
  color:#f5d98a;
  text-shadow:0 0 3px rgba(20,14,4,.95), 0 1px 3px rgba(20,14,4,.95), 0 0 7px rgba(20,14,4,.6);
}

/* v98：裂隙残响改温和穷奇迷你立绘（实机反馈#2：紫光太淡）——wrapper=定位+脚底暗影，img=白狮残影轻浮动
   v101 ⚠02：定位改由 map.js 按地图数据 rift 锚点直写（立绘脚底=触发圆心），CSS 不再写死坐标 */
.jq-rift { position:absolute; width:62px; height:72px; z-index:2; pointer-events:none; }
.jq-rift::before { content:''; position:absolute; left:50%; bottom:2px; transform:translateX(-50%);
  width:54px; height:12px; border-radius:50%;
  background:radial-gradient(ellipse at center, rgba(20,16,40,.4), transparent 70%); }
.jq-rift-echo { position:relative; display:block; width:100%; height:100%;
  opacity:.88; filter:saturate(.82) brightness(.94);
  animation:rift-bob 3.2s ease-in-out infinite; }
@keyframes rift-bob {
  0%,100% { transform:translateY(0); }
  50% { transform:translateY(-4px); }
}

/* v96 #7：三档选槽弹层 + 存档页行 */
.slot-card { border:1px solid #6b5a35; border-radius:8px; padding:10px 12px; margin:8px 6px;
  background:rgba(28,24,16,.55); text-align:left; }
.slot-card.has { border-color:#a5854a; }
.slot-head { color:#f0d68a; font-size:14px; letter-spacing:.2em; margin-bottom:4px; }
.slot-body { color:#d8cfb8; font-size:12px; line-height:1.6; min-height:1.6em; }
.slot-empty { color:#8a7c5e; }
.slot-ops { margin-top:6px; display:flex; gap:8px; }
.slot-btn { flex:none; padding:4px 14px; border-radius:6px; border:1px solid #8a7343;
  background:rgba(60,48,22,.75); color:#f0e2c0; font-size:13px; letter-spacing:.1em; cursor:pointer; }
.slot-btn.danger { border-color:#8a4343; color:#e8b0a0; }
/* v275：备份/导入/网址提示 */
.slot-btn.bak { border-color:#5f7a86; color:#bcd7e2; }
.slot-bak { margin-top:4px; color:#9db0b8; font-size:11px; letter-spacing:.04em; }
.slot-hint { margin:10px 6px 4px; padding:9px 11px; border:1px solid #8a6b33; border-radius:8px;
  background:rgba(70,52,20,.55); color:#f0dfae; font-size:12px; line-height:1.75; text-align:left; }
.slot-hint b { color:#ffd98a; }
.slot-io { margin:10px 6px 0; display:flex; flex-wrap:wrap; gap:8px; align-items:center; justify-content:center; }
.slot-io.hidden { display:none; }
.slot-import-title { flex:1 0 100%; color:#d8cfb8; font-size:12px; line-height:1.7; text-align:left;
  margin-bottom:2px; }
.save-row { display:flex; align-items:center; gap:8px; border:1px solid #6b5a35; border-radius:8px;
  padding:8px 10px; margin:6px 4px; background:rgba(28,24,16,.45); }
.save-info { flex:1; text-align:left; color:#d8cfb8; font-size:12px; line-height:1.6; }
.save-info b { color:#f0d68a; margin-right:6px; letter-spacing:.1em; }
.save-ops { display:flex; gap:6px; }
.s-btn { padding:3px 12px; border-radius:6px; border:1px solid #8a7343;
  background:rgba(60,48,22,.75); color:#f0e2c0; font-size:12px; cursor:pointer; }

/* v99 装备页：六槽格（locked=二期灰格）+ 行囊装备行（穿/售）+ 稀有金名 */
.gear-slots { display:grid; grid-template-columns:repeat(3,1fr); gap:6px; margin:8px 4px; }
.gear-slot { display:flex; flex-direction:column; align-items:center; gap:2px;
  border:1px solid #6b5a35; border-radius:8px; padding:8px 6px;
  background:rgba(28,24,16,.55); cursor:pointer; }
.gear-slot.has { border-color:#a5854a; }
.gear-slot.locked { opacity:.45; cursor:default; }
.gear-slot[disabled] { cursor:default; }
.gear-k { color:#f0d68a; font-size:12px; letter-spacing:.2em; }
.gear-v { color:#e8ddc0; font-size:12px; }
.gear-v.dim { color:#8a7c5e; }
.gear-v.rare, .inv-name.rare { color:#ffca5f; text-shadow:0 0 6px rgba(255,180,60,.45); }
.gear-ops { display:flex; flex-direction:column; gap:4px; flex:none; }
.s-btn.danger { border-color:#8a4343; color:#e8b0a0; }
/* v182：存档导出/导入——当前槽高亮 + 「当前」角标（导入目标提示） */
.save-row.cur { border-color:#c9a35c; box-shadow:0 0 0 1px rgba(201,163,92,.35), inset 0 0 12px rgba(201,163,92,.08); }
.slot-cur { display:inline-block; margin-left:6px; padding:0 6px; font-size:10px; line-height:15px;
  color:#2a2113; background:linear-gradient(180deg,#e9c987,#cda85f); border-radius:8px;
  vertical-align:1px; letter-spacing:0; font-weight:600; }
/* v101 ⚠05：装备槽图标 + 属性浮层 */
.gear-ico { width:42px; height:42px; object-fit:contain;
  border:1px solid #565b70; border-radius:8px; background:rgba(20,22,36,.7); padding:2px; }
.gear-ico.ph { background:rgba(20,22,36,.45); }
.gear-info { border:1px solid #8a7343; border-radius:10px; background:rgba(60,48,22,.55);
  padding:9px 12px; font-size:12px; color:#f0e2c0; line-height:1.75; margin:6px 0 2px; text-align:left; }
.gear-info b { color:#f0d68a; }

/* ---------- v101 ⚠07：背包（两页签 + 游戏金币风铜钱栏） ---------- */
.bag-tabs { display:flex; gap:8px; margin-bottom:10px; }
.bag-tab { flex:1; min-height:40px; border:1px solid #565b70; border-radius:10px;
  background:rgba(38,40,60,.6); color:#8d93a8; font-size:14px; letter-spacing:.25em; cursor:pointer; }
.bag-tab.on { color:#f0d68a; border-color:#a5854a; background:rgba(60,48,22,.6); }
.bag-tab:not(.on):active { background:#39406b; }
.bag-coins { display:flex; align-items:center; justify-content:center; gap:8px;
  padding:9px 0 2px; border-top:1px dashed #3a3d52; margin-top:8px; }
.coin-ico { position:relative; width:22px; height:22px; border-radius:50%; flex:none;
  background:radial-gradient(circle at 38% 32%, #f6e2a0, #d4ad55 60%, #a37c2e);
  border:2px solid #8a6d2f; box-shadow:0 0 8px rgba(233,196,124,.45); }
.coin-ico::after { content:''; position:absolute; left:50%; top:50%; width:7px; height:7px;
  transform:translate(-50%,-50%); background:#1e2032; border-radius:1.5px; box-shadow:inset 0 0 2px #000; }
.bag-coins b { color:#f0d68a; font-size:17px; letter-spacing:.05em; }
.bag-coins span { color:#8d93a8; font-size:12px; }

/* ---------- v101 ⚠09：技能页（图标/介绍/单群疗标） ---------- */
.sk-tag { display:inline-block; font-size:11px; margin-left:6px; padding:1px 8px;
  border-radius:8px; letter-spacing:.15em; vertical-align:1px; }
.sk-tag.aoe { color:#e9c47c; border:1px solid #8a6d3b; }
.sk-tag.single { color:#9fb8ff; border:1px solid #4a5a8a; }
.sk-tag.heal { color:#8fd6a8; border:1px solid #3d7a5e; }
#page-skills .inv-list { max-height:403.2px; }

/* 电影感特效层：光柱/浮尘/暗角（盖在地图上，不拦触摸） */
.fx-layer { position:absolute; inset:0; pointer-events:none; z-index:7; overflow:hidden; }
.light-shaft { position:absolute; top:-10%; left:46%; width:40%; height:74%;
  transform:rotate(13deg); filter:blur(6px);
  background:linear-gradient(168deg, rgba(255,226,158,.15), rgba(255,226,158,.03) 68%, transparent); }
/* v29：浮尘(.mote/mote-drift)已按用户拍板整体移除 */
.vignette { position:absolute; inset:0;
  background:radial-gradient(ellipse 140% 108% at 50% 42%, transparent 52%, rgba(6,6,14,.46) 100%); }
/* v175 P1-7：氛围粒子画布（屏幕空间，不随相机移动；由 particles.js 创建挂载） */
#fx-particles { position:absolute; inset:0; width:100%; height:100%; pointer-events:none; }

/* 虚拟按键：触控目标 ≥48dp（移动端规范）——v101 ⚠08：下移贴底、摇杆/探键加大 */
.touch-ui { position:absolute; inset:0; pointer-events:none; z-index:20; }
.pad { pointer-events:auto; position:absolute;
  bottom:calc(24px + env(safe-area-inset-bottom)); }

/* 虚拟摇杆 —— v311：用户实拍"手机上太小、不好操作"，168→196（横屏 150→180），推杆同步放大 */
.joystick { left:18px; width:196px; height:196px; z-index:21; }
.joystick-base { position:absolute; inset:0; border-radius:50%;
  background:rgba(40,44,65,.85);
  border:2px solid rgba(120,130,170,.3); }
.joystick-stick { position:absolute; width:72px; height:72px; border-radius:50%;
  background:rgba(80,90,120,.9);
  border:2px solid rgba(160,170,200,.4);
  left:50%; top:50%; transform:translate(-50%, -50%);
  pointer-events:none; }
/* 圆形动作键（右侧）：水墨描边 + 微光，按下收缩反馈 —— v116 ⚠17：88→110px（热区=按钮本体同步）
 * v310【用户实机：手机版探索键"太小了、位置也太靠下，参照摇杆键设置"】
 *   竖屏值时 110×110，横屏又被摇杆的 150 反衬得更小，且 110 的高度让圆心比摇杆低一截，
 *   看着像贴在屏幕下沿。现在**与摇杆同尺寸同底距**（横屏 150、竖屏 168），两者左右对称。 */
.action { right:22px; width:196px; height:196px; border-radius:50%;
  border:2px solid #b89b5e; color:#f0ead9; font-size:58px; font-weight:700; letter-spacing:.08em;
  background:radial-gradient(circle at 35% 28%, #4a5182, #23263e 72%);
  box-shadow:0 6px 18px rgba(0,0,0,.55), inset 0 0 0 1.5px rgba(184,155,94,.35),
             0 0 16px rgba(184,155,94,.22);
  transition:transform .08s, box-shadow .15s; }
.action b { font-weight:700; }
.action:active { transform:scale(.92);
  box-shadow:0 3px 10px rgba(0,0,0,.5), 0 0 24px rgba(233,196,124,.55); }
/* 摇杆手感：底盘上禁掉浏览器手势 */
.joystick { touch-action:none; }

#toast { position:absolute; left:50%; bottom:150px; transform:translateX(-50%);
  max-width:1024px; z-index:60; background:rgba(18,20,32,.94);   /* v87 R2：40→60，原被菜单层(.overlay z50)盖住，图鉴指引 toast 不可见 */
  border:1px solid #565b70; border-radius:14px; padding:12px 18px;
  font-size:15px; line-height:1.7; text-align:center; white-space:pre-line;
  box-shadow:0 6px 20px rgba(0,0,0,.5); animation:toast-in .18s ease-out; }
@keyframes toast-in { from { opacity:0; transform:translateX(-50%) translateY(8px);} }

/* ---------- v281：学会新技能的屏幕提示（body 级浮层，战斗内外共用） ----------
 * 位置取**屏幕正中**而不是顶部：升级习得发生在战斗收口那一瞬，而战利牌 `#battle-loot`
 *   就挂在 top:14%，顶部条会正好压在它身上；敌人这时已经散尽，画面中央是空的。
 * `pointer-events:none` 是刻意为之——它可能盖在战斗指令区上方，绝不能吃掉一次点击。 */
.skill-learn { position:fixed; left:50%; top:46%; transform:translate(-50%,-50%);
  z-index:120; pointer-events:none; width:min(1126.4px,440px); padding:16px 18px 12px;
  background:linear-gradient(160deg, rgba(52,42,22,.97), rgba(20,20,32,.98));
  border:2px solid #c9a35c; border-radius:16px; text-align:left;
  box-shadow:0 14px 38px rgba(0,0,0,.66), inset 0 0 0 1px rgba(255,214,150,.16),
             0 0 26px rgba(255,196,54,.30);
  animation:sl-in .34s cubic-bezier(.2,.9,.3,1.3) both; }
.skill-learn.out { animation:sl-out .34s ease-in both; }
@keyframes sl-in {
  from { opacity:0; transform:translate(-50%,-50%) translateY(-16px) scale(.94); }
  to   { opacity:1; transform:translate(-50%,-50%) translateY(0)     scale(1); } }
@keyframes sl-out {
  to   { opacity:0; transform:translate(-50%,-50%) translateY(-10px) scale(.97); } }

.sl-tag { position:absolute; top:-13px; left:50%; transform:translateX(-50%);
  padding:2px 14px; border-radius:999px; background:#c9a35c; color:#241c08;
  font-size:12px; font-weight:700; letter-spacing:.42em; text-indent:.42em;
  box-shadow:0 2px 10px rgba(0,0,0,.5); }
.sl-body { display:flex; align-items:center; gap:12px; }
.sl-ico { flex:none; width:52px; height:52px; border-radius:12px; object-fit:cover;
  border:1px solid #8a7343; background:rgba(0,0,0,.35); }
.sl-txt { min-width:0; }
.sl-name { font-size:19px; font-weight:700; letter-spacing:.08em; color:#ffe6b0; }
.sl-desc { margin-top:3px; font-size:12.5px; line-height:1.55; color:#cfc6ad; letter-spacing:.02em; }
.sl-tip { margin-top:9px; padding-top:8px; border-top:1px dashed rgba(201,163,92,.36);
  font-size:11.5px; letter-spacing:.06em; color:#9fb8ff; }

/* ---------- v87 R5：NPC 交互选框（经典 RPG 式：交谈/功能项/离开） ---------- */
.npc-menu { position:fixed; left:50%; bottom:140px; transform:translateX(-50%);
  z-index:45; min-width:220px; max-width:1100.8px; background:rgba(18,20,32,.96);
  border:1px solid #565b70; border-radius:14px; padding:10px 12px 12px;
  box-shadow:0 6px 20px rgba(0,0,0,.5); animation:toast-in .18s ease-out; }
.npc-menu-name { text-align:center; font-size:13px; color:#9fb8ff;
  letter-spacing:.3em; margin-bottom:4px; }
.npc-menu-item { display:block; width:100%; margin-top:8px; padding:10px 18px;
  background:#242741; border:1px solid #565b70; border-radius:10px;
  color:#e8dcc2; font-size:15px; text-align:left; }
.npc-menu-item:active { transform:scale(.97); border-color:#b89b5e; }
.npc-menu-item.gold { color:#e9c47c; border-color:#8a6d3b; }   /* v87 R8-1：任务项金字 */
/* v277：离图确认框里的"单程"警示行——不可逆的事必须写在按钮上方，玩家点之前就看得到 */
.npc-menu-warn { margin:6px 0 2px; padding:7px 9px; border:1px solid #8a5a2b; border-radius:8px;
  background:rgba(70,38,14,.6); color:#f2c88a; font-size:12px; line-height:1.65; text-align:left; }

/* ---------- 获得反馈（v78）：图标弹层 + 飞入行囊 ---------- */
#gain-layer { position:fixed; left:50%; top:calc(13% + env(safe-area-inset-top));
  transform:translateX(-50%); z-index:60; display:flex; flex-direction:column; align-items:center;
  gap:8px; pointer-events:none; }
.gain-pop { display:flex; align-items:center; gap:8px; padding:6px 12px 6px 6px;
  background:rgba(18,20,32,.94); border:1px solid #b89b5e; border-radius:12px;
  box-shadow:0 6px 18px rgba(0,0,0,.5); animation:gain-in .3s ease-out;
  transition:transform .6s cubic-bezier(.5,-0.2,.7,.4), opacity .6s; }
.gain-pop.fly { transform:translate(var(--fx,0), var(--fy,0)) scale(.2); opacity:0; }
@keyframes gain-in { from { opacity:0; transform:translateY(-26px); } }
.gain-ico { width:36px; height:36px; object-fit:contain; }
.gain-coin { width:22px; height:22px; flex:0 0 22px; border-radius:50%;
  background:radial-gradient(circle at 40% 35%, #f2d98a, #c9a24f 70%);
  border:2px solid #8a6d2f; }
.gain-label { font-size:13px; color:#f0ead9; letter-spacing:.05em; white-space:nowrap; }

/* ---------- 横屏适配（场景全屏横版） ---------- */
@media (orientation:landscape) {
  .avatar { width:52px; height:52px; }
  .fold-btn { width:44px; height:44px; font-size:21px; }
  .fold-round { width:40px; height:40px; font-size:13px; }
  .pad { bottom:calc(20px + env(safe-area-inset-bottom)); }
  .joystick { left:calc(18px + env(safe-area-inset-left)); width:180px; height:180px; }
  .action { right:calc(22px + env(safe-area-inset-right)); width:180px; height:180px; font-size:52px; }
  .joystick-stick { width:66px; height:66px; }
  .dlg  { bottom:calc(60px + env(safe-area-inset-bottom)); min-height:66px; }
  .dlg-text { font-size:15px; line-height:1.7; min-height:46px; }
  .dlg-portrait { width:46px; height:70px; }
  .dlg-name { font-size:12px; top:-13px; padding:2px 12px 3px; }
  #toast { bottom:118px; }
}

/* ---------- 仙剑式底部对话框（v171：NPC 立绘头像 + 名字牌；旁白时两者隐藏，布局不变） ---------- */
.dlg { position:absolute; left:50%; bottom:calc(76px + env(safe-area-inset-bottom));
  transform:translateX(-50%); width:min(1177.6px,560px); z-index:35;
  display:flex; align-items:flex-end; gap:12px;
  background:rgba(10,10,18,.93); border:2px solid #b89b5e; border-radius:12px;
  padding:14px 18px 18px; min-height:84px;
  box-shadow:0 8px 24px rgba(0,0,0,.55), inset 0 0 0 1px #00000066; }
.dlg-portrait { flex:none; width:62px; height:94px; object-fit:contain; object-position:bottom;
  filter:drop-shadow(0 3px 6px rgba(0,0,0,.5)); }
.dlg-main { flex:1; min-width:0; }
.dlg-name { position:absolute; top:-15px; left:16px; padding:3px 16px 4px;
  background:linear-gradient(180deg,#2a2018,#1a140e); border:1.5px solid #b89b5e; border-radius:999px;
  color:#ffe9b0; font-size:13px; letter-spacing:2px;
  box-shadow:0 3px 8px rgba(0,0,0,.45); }
.dlg-text { font-size:16px; line-height:1.85; color:#f0ead9; min-height:58px; }
.dlg-next { position:absolute; right:14px; bottom:8px; color:#e8c987;
  font-size:13px; animation:next-blink 1s infinite; }
@keyframes next-blink { 50% { opacity:.15; } }

/* ---------- v101 ⚠08：左上属性卡（原底部状态栏迁址；半透明托底防遮挡场景） ---------- */
.hud-top { position:absolute; top:calc(env(safe-area-inset-top) + 8px); left:10px; z-index:30;
  display:flex; align-items:center; gap:10px; pointer-events:none; }
/* v112 回退定稿（⚠12 关闭）：属性卡保留 v106 原版扁排样式 */
.hud-top .stat { width:min(300px, 486.4px); background:rgba(10,8,4,.52);
  border:1px solid rgba(184,155,94,.4); border-radius:12px; padding:7px 10px 8px;
  box-shadow:0 2px 10px rgba(0,0,0,.4); }
/* v114 ⚠13-R2：折叠组（＋+任务栏）移到属性卡正下方（用户定稿）；列序=背/技/菜 */
.hud-fold { position:absolute; top:calc(env(safe-area-inset-top) + 104px); left:10px; z-index:30;
  display:flex; align-items:flex-start; pointer-events:auto; }
.fold-btn { flex:none; width:50px; height:50px; border-radius:50%; border:1.5px solid #a5854a;
  color:#ffe9b0; font-size:24px; line-height:1; cursor:pointer; position:relative; padding:0;
  background:linear-gradient(180deg,#4a3a14,#2a1f08);
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.5), inset 0 0 10px rgba(0,0,0,.45), 0 2px 10px rgba(0,0,0,.55); }
.fold-btn::before { content:''; position:absolute; inset:3px; border-radius:50%;
  border:1px solid rgba(217,180,95,.4); pointer-events:none; }
.fold-btn:active { filter:brightness(1.25); }
.fold-col { position:absolute; top:58px; left:0; display:flex; flex-direction:column; gap:8px; z-index:36; }
.fold-col.hidden { display:none; }
.fold-round { flex:none; width:46px; height:46px; border-radius:50%; border:1.5px solid #a5854a;
  color:#f0e2c0; font-size:15px; cursor:pointer; padding:0;
  background:linear-gradient(180deg,#5a2320,#3f1613);
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.5), inset 0 0 10px rgba(0,0,0,.45), 0 2px 10px rgba(0,0,0,.55); }
.fold-round:active { filter:brightness(1.25); }
/* v112 回退：头像环恢复 v106 原版（2.5px 金环 + 暗金托环 + 暗金内细环） */
.avatar-switch { position:relative; flex:none; width:96px; align-self:stretch; }
/* v205 [N2]：杨宇 58px 垂直居中对齐血条/蓝条中线；珂儿叠其右上（青绿环区分），布局经用户确认（示意 v2） */
.avatar-switch .avatar { position:absolute; left:0; top:50%; transform:translateY(-50%); }
/* v224 [M7]：两头像**不再折叠**——容器 80→96；杨宇 58px 占 0~58，珂儿缩到 32px 移到 64~96（右斜上），
 *   环间净距 6px（杨宇外扩阴影 3px 后仍有 3px 视觉间隙）。旧 38px@left42 与杨宇重叠 18px 退役。 */
.avatar-switch #avatar-keer { width:32px; height:32px; left:64px; top:2px; transform:none; border-color:#7FCAB2; }
.avatar { width:58px; height:58px; border-radius:50%; overflow:hidden; flex:none;
  border:2.5px solid #d9b45f; background:#1e2032; position:relative; cursor:pointer; pointer-events:auto;
  box-shadow:0 0 0 1.5px #6b5426, 0 0 0 3px rgba(30,24,10,.6), 0 3px 12px rgba(0,0,0,.6); }
/* 双环内线：暗金细环 */
.avatar::after { content:''; position:absolute; inset:2px; border-radius:50%;
  border:1px solid rgba(184,155,94,.55); pointer-events:none; }
/* 裁剪对准脸部：脸在精灵高度约27%处，放大3倍并上移对准圆心
   v164：显式 width:auto + object-fit:contain，素材比例异常时也不会被拉伸 */
.avatar img { position:absolute; height:300%; width:auto; max-width:none; left:50%; top:-31%;
  object-fit:contain; transform:translateX(-50%); }
/* v116 ⚠11：人物面板宽卡（点头像）——左属性/装备/状态，右技能；Buff 区暂显"暂无" */
.menu-card.hero-card { width:min(1177.6px, 700px); max-height:576px; overflow-y:auto; }
.hero-wrap { display:flex; gap:14px; align-items:flex-start; text-align:left; }
.hero-left { flex:1.15; min-width:0; }
.hero-right { flex:1; min-width:0; border-left:1px solid rgba(184,155,94,.35); padding-left:14px; }
.hero-sub { margin:10px 0 6px; font-size:14px; color:#e8c987; letter-spacing:.25em; }
.hero-card .st-row { font-size:13px; }
@media (max-width:640px) {
  .hero-wrap { flex-direction:column; }
  .hero-right { border-left:none; padding-left:0; width:100%; }
}
/* v116 ⚠14②：列表显形翻页钮（▲▼，触屏友好） */
.inv-with-pager { display:flex; gap:6px; align-items:stretch; }
.inv-with-pager .inv-list { flex:1; min-width:0; }
.inv-pager { display:flex; flex-direction:column; gap:6px; justify-content:center; }
.pg-btn { width:30px; height:34px; border-radius:8px; border:1px solid #8a7343; color:#f0dfb0;
  background:rgba(60,48,22,.75); font-size:13px; cursor:pointer; padding:0; }
.pg-btn:active { filter:brightness(1.3); }
.name-row { font-size:20px; margin-bottom:5px; display:flex; align-items:center; gap:8px;
  text-shadow:0 1px 3px rgba(0,0,0,.85); }
/* v93 #6 名字提亮：亮金实色替代低对比渐变（小字号下渐变发灰看不清） */
.name-row .pname { font-weight:700; letter-spacing:.14em; font-size:21px; color:#ffe9b0;
  text-shadow:0 1px 2px #000, 0 0 8px rgba(255,222,140,.35); }
/* Lv 胶囊徽章 */
.name-row .lv { font-size:12px; color:#f0dfb0; padding:2px 8px; border-radius:8px;
  border:1px solid #8a7343; background:rgba(60,48,22,.75); letter-spacing:.08em; }
/* v93 #7：HUD 迷你经验条（v112 恢复：名字行内嵌；升级所需 = 30×当前等级） */
.xpbar { position:relative; flex:1; min-width:72px; max-width:150px; height:11px;
  border-radius:6px; overflow:hidden; margin-left:2px;
  background:linear-gradient(180deg,#15161e,#262837);
  box-shadow:inset 0 2px 3px rgba(0,0,0,.75), 0 1px 4px rgba(0,0,0,.5); }
.xpbar i { display:block; height:100%; border-radius:6px; transition:width .35s ease;
  color:#e8c987; background:linear-gradient(90deg,#8a6a2f,#c9a24f 55%,#f0d68a); }
.bar { height:11px; border-radius:6px; background:linear-gradient(180deg,#15161e,#262837);
  overflow:hidden; position:relative; margin-top:4px;
  box-shadow:inset 0 2px 3px rgba(0,0,0,.75), 0 1px 4px rgba(0,0,0,.5); }
.bar i { display:block; height:100%; border-radius:6px; position:relative;
  transition:width .35s ease; }
/* 珠光顶高光 */
.bar i::before { content:''; position:absolute; left:0; right:0; top:0; height:45%;
  border-radius:6px 6px 40% 40%;
  background:linear-gradient(180deg, rgba(255,255,255,.38), rgba(255,255,255,0)); }
/* 末端微光点 */
.bar i::after { content:''; position:absolute; right:0; top:50%; width:5px; height:5px;
  border-radius:50%; transform:translate(2px,-50%);
  box-shadow:0 0 6px 1px currentColor; background:currentColor; }
.bar.hp { width:100%; }
.bar.mp { width:72%; }
.bar.hp i { color:#e88a5f; background:linear-gradient(90deg,#8f2f2f,#c04a4a 55%,#e0895a); }
.bar.mp i { color:#7fa8e8; background:linear-gradient(90deg,#2f4a8f,#3f5fbf 55%,#7fa3e0); }
/* v93 #2/#6：条内数值文字（HUD 与战斗单位条通用） */
.bar-num { position:absolute; left:0; right:0; top:50%; transform:translateY(-50%);
  font-style:normal; font-size:9px; line-height:1; text-align:center; color:#fff;
  letter-spacing:.05em; pointer-events:none;
  text-shadow:0 1px 2px #000, 0 0 3px rgba(0,0,0,.9); }
/* 印章式菜单钮：暗红底描金边 + 内环细线 */
.menu-btn { flex:none; width:60px; height:60px; border-radius:10px;
  border:1.5px solid #a5854a; color:#f0e2c0; font-size:15px; line-height:1.25;
  letter-spacing:.1em; display:flex; flex-direction:column;
  align-items:center; justify-content:center;
  background:linear-gradient(180deg,#5a2320,#3f1613);
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.5), inset 0 0 10px rgba(0,0,0,.45), 0 2px 10px rgba(0,0,0,.55);
  position:relative; }
.menu-btn::before { content:''; position:absolute; inset:3px; border-radius:7px;
  border:1px solid rgba(217,180,95,.4); pointer-events:none; }
.menu-btn:active { filter:brightness(1.25); }

/* ---------- ESC式竖排菜单 ---------- */
.menu-card { background:#1e2032; border:2px solid #b89b5e; border-radius:16px;
  padding:22px 20px; width:min(947.2px,300px); display:flex; flex-direction:column; gap:10px; }
.menu-card h3 { text-align:center; letter-spacing:.5em; text-indent:.5em;
  color:#e8c987; margin-bottom:6px; font-size:17px; }
.m-item { min-height:46px; border:1px solid #565b70; border-radius:10px;
  background:rgba(38,40,60,.6); color:#e8e2d5; font-size:15px; letter-spacing:.2em; }
.m-item small { letter-spacing:0; color:#8d93a8; font-size:11px; }
.m-item:disabled { opacity:.45; }
.m-item:not(:disabled):active { background:#39406b; }
.menu-ver { text-align:center; font-size:11px; color:#565b70; margin-top:8px; letter-spacing:.15em; }

/* ---------- 竖屏提示层（问题10/11：手机未横屏/旋转锁死时显示） ---------- */
#rotate-hint { position:fixed; inset:0; z-index:60; background:#14141f;
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:18px; text-align:center; }
.rotate-icon { font-size:64px; color:#9fb8ff; animation:rotate-swing 1.6s ease-in-out infinite; }
@keyframes rotate-swing { 0%,100% { transform:rotate(0deg); } 50% { transform:rotate(90deg); } }
#rotate-hint p { font-size:18px; letter-spacing:.2em; color:#e8e2d5; }
#rotate-hint .rotate-sub { font-size:13px; color:#8d93a8; letter-spacing:.1em; }
/* v33/F2：内置浏览器引导 + 诊断行 + 重试按钮 */
#rotate-hint #rh-guide { max-width:1075.2px; font-size:14px; color:#ffd98a; line-height:1.75; letter-spacing:.02em; }
#rotate-hint #rh-diag { font-size:11px; color:#8d93a8; letter-spacing:.05em; font-family:monospace; margin-top:6px; }
#rotate-hint #rh-retry { margin-top:14px; min-height:44px; padding:0 26px; border:1.5px solid #b89b5e;
  border-radius:10px; background:rgba(38,40,60,.85); color:#e8e2d5; font-size:14px; letter-spacing:.15em; }
#rotate-hint #rh-retry:active { background:#39406b; }

/* ---------- M2 菜单页面（状态/物品/存档，v32） ---------- */
.st-grid { display:flex; flex-direction:column; gap:6px; margin-bottom:10px; }
.st-row { display:flex; justify-content:space-between; font-size:14px;
  border-bottom:1px dashed #3a3d52; padding-bottom:4px; }
.st-row span { color:#8d93a8; letter-spacing:.2em; }
.st-row b { color:#f0ead9; font-weight:normal; }
.st-skills { font-size:12px; color:#9fb8ff; margin-bottom:8px; letter-spacing:.08em; }
.st-goal { font-size:12px; color:#e8c987; line-height:1.6; margin-bottom:10px; letter-spacing:.05em; }
.inv-list { display:flex; flex-direction:column; gap:8px; max-height:331.2px;
  overflow-y:auto; margin-bottom:10px; min-width:0; }
.inv-empty { color:#8d93a8; font-size:13px; text-align:center; padding:18px 0; }
.inv-row { display:flex; flex-direction:row; align-items:center; gap:10px; text-align:left;
  border:1px solid #565b70; border-radius:10px; background:rgba(38,40,60,.6);
  padding:8px 12px; color:#e8e2d5;
  /* v299【用户："陈姨小铺里面的商品文字看不全"】——
   *   `.inv-list` 是 `display:flex; flex-direction:column; max-height:331.2px; overflow-y:auto`，
   *   而下面那条 `.inv-row{overflow:hidden}` 把 flex 子项的 `min-height:auto` 变成了 0
   *   → 行被压扁（内容上下同时被裁），容器反而不出滚动条。
   *   实测 7 行：行高 35~48px，内容却要 70~110px，每行裁掉 35~62px。
   *   `flex:0 0 auto` 让行按内容撑开，装不下就交给容器滚动 —— 这才是列表该有的行为。 */
  flex:0 0 auto; }
.inv-ico { width:44px; height:44px; flex:0 0 44px; object-fit:contain;
  border:1px solid #565b70; border-radius:8px; background:rgba(20,22,36,.7); padding:3px; }
.inv-ico.ph { background:rgba(20,22,36,.45); }
.inv-txt { display:flex; flex-direction:column; gap:2px; min-width:0; }
.inv-row .inv-name { font-size:14px; letter-spacing:.1em; }
.inv-row .inv-name small { color:#8d93a8; }
.inv-row .inv-desc { font-size:11px; color:#8d93a8; line-height:1.5; }
.inv-row.dim { opacity:.6; }
.inv-row:active { background:#39406b; }
.save-note { font-size:12px; color:#8d93a8; text-align:center; margin-bottom:8px; line-height:1.6; }

/* ---------- v92 图鉴页滚动容器（三层内容整体滚，标题/返回恒在屏内）+ 陈姨小铺 ---------- */
#page-collection { max-height:676.8px; }
.col-scroll { flex:1 1 auto; min-height:0; overflow-y:auto; }
#page-collection .inv-list { max-height:none; margin-bottom:6px; }
.inv-price { margin-left:auto; flex:none; color:#e8c34e; font-size:13px; letter-spacing:.05em; }
.inv-row.sold { opacity:.45; }
/* v295：批量购买入口。⚠ 只能放 <span>——.inv-row 本身是 <button>，HTML 不允许按钮嵌按钮 */
.inv-more { flex:none; margin-left:8px; padding:5px 10px; border-radius:9px; cursor:pointer;
  border:1px solid #8a7343; background:rgba(60,48,22,.78); color:#e8c98a;
  font-size:11px; letter-spacing:.08em; white-space:nowrap;
  box-shadow:0 2px 6px rgba(0,0,0,.35); }
.inv-more:active { filter:brightness(1.3); transform:scale(.94); }
/* v299：小铺右侧竖排一列（价格在上、「批量」在下）——见 menu.js renderShop 里的注释。
 *   横排时这两块在窄卡片里要吃掉 ~100px，竖排后文字列能拿回 50px 左右。 */
.inv-side { flex:none; margin-left:auto; display:flex; flex-direction:column;
  align-items:flex-end; gap:5px; }
.inv-side .inv-price { margin-left:0; line-height:1.2; }
.inv-side .inv-more { margin-left:0; }
/* v299：小铺页单独加宽。默认卡片是 min(947.2px,300px)，扣掉内边距和图标，
 *   文字列只剩 60px 上下（约 5 个汉字/行），描述必然折成 4~7 行。 */
#page-shop { width:min(1177.6px, 380px); }
/* v299：小铺列表多留一点可见高度（默认 331.2px 只放得下 4 行半，七件货要翻两次）。 */
#page-shop .inv-list { max-height:403.2px; }
.qz-calm { position:absolute; z-index:55; pointer-events:none; opacity:0;
  filter:drop-shadow(0 0 18px rgba(255,225,150,.75)) drop-shadow(0 0 6px rgba(255,255,255,.5)) brightness(1.06);
  animation:calm-in 2.4s ease-out forwards; }
@keyframes calm-in { from { opacity:0; } to { opacity:.92; } }
.qz-calm.out { transition:opacity 1.1s ease-in; opacity:0 !important; animation:none; }

/* ---------- 章节结算过场（M2 批③；v289 方案 B：从"独立一屏"改成"盖在游戏画面上的浮层"）
 *   z-index 80：压住 HUD(10/30)、菜单浮层(50)、toast(60)，仍在相册(95)/升级光(90)/转场(300) 之下。
 *   底下的游戏画面不换屏、不清空——只压暗 + 轻模糊，像一层蒙在眼前的雾。 ---------- */
#screen-ending { z-index:80;
  background:radial-gradient(ellipse 95% 75% at 50% 46%, rgba(10,12,20,.80) 0%, rgba(7,8,14,.94) 100%);
  backdrop-filter:blur(2.5px) saturate(.85); -webkit-backdrop-filter:blur(2.5px) saturate(.85); }
#screen-ending.active { animation:end-in .7s ease both; }
#screen-ending.closing { animation:end-out .55s ease both; }
@keyframes end-in { from { opacity:0 } to { opacity:1 } }
@keyframes end-out { from { opacity:1 } to { opacity:0 } }
.ending-wrap { display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:12px; height:100%; text-align:center; padding:0 24px; }
/* 逐行浮现：依次落位，读起来像字幕，不像一张表 */
#screen-ending.active .ending-title,
#screen-ending.active .ending-sub,
#screen-ending.active .ending-gains,
#screen-ending.active .ending-foot,
#screen-ending.active .ending-next,
#screen-ending.active .ending-bar,
#screen-ending.active .ending-acts { animation:end-rise .8s ease both; }
#screen-ending.active .ending-title { animation-delay:.08s }
#screen-ending.active .ending-sub   { animation-delay:.22s }
#screen-ending.active .ending-gains { animation-delay:.42s }
#screen-ending.active .ending-foot  { animation-delay:.74s }
#screen-ending.active .ending-next  { animation-delay:.96s }
#screen-ending.active .ending-bar   { animation-delay:1.06s }
#screen-ending.active .ending-acts  { animation-delay:1.22s }
@keyframes end-rise { from { opacity:0; transform:translateY(9px) } to { opacity:1; transform:none } }
.ending-title { font-size:34px; letter-spacing:.4em; text-indent:.4em; color:#e8c987;
  text-shadow:0 2px 12px rgba(232,201,135,.25); }
.ending-sub { font-size:14px; color:#9aa2b8; letter-spacing:.3em; }
.ending-gains { margin:10px 0 4px; padding:14px 22px; border:1px solid #6a708a;
  border-radius:12px; background:rgba(26,28,42,.82); font-size:14px; color:#f4efe2;
  line-height:2; min-width:min(896px,320px); }
/* v292：整层的字都提亮一档 —— 第一版压暗 0.80~0.94 之后，灰字（#8d93a8 / #6f768c）压在暗底上
 *   对比不足，实机截图里"回忆相册 / 回到标题"几乎看不见。底景不用再压（已经够暗），字提亮就行。 */
.ending-foot { font-size:12px; color:#aeb5c8; letter-spacing:.18em; line-height:1.9;
  max-width:min(1075.2px,480px); }
/* 下一章宣告 / 待续（v289 新增：这一行替掉了原来那个必须点的按钮） */
.ending-next { margin-top:4px; font-size:15px; letter-spacing:.32em; text-indent:.32em; color:#f4efe2;
  text-shadow:0 0 16px rgba(159,184,255,.35); }
.ending-next.done { color:#9ba3ba; text-shadow:none; }   /* 待续：不用"要进"的语气，改灰 */
/* 自动推进进度线：时长由 JS 写进 --end-wait，纯装饰、不参与任何判定 */
.ending-bar { width:min(640px,220px); height:1px; margin-top:12px; overflow:hidden;
  background:rgba(150,158,180,.28); }
.ending-bar i { display:block; height:100%; transform:scaleX(0); transform-origin:left center;
  background:linear-gradient(90deg, rgba(232,201,135,0), #f0cf8a);
  animation:end-bar var(--end-wait, 4600ms) linear both; }
@keyframes end-bar { from { transform:scaleX(0) } to { transform:scaleX(1) } }
/* 三个小字入口（即刻推门 / 回忆相册 / 回到标题）——过场不需要它们，想跳过或想留步才用得上 */
.ending-acts { display:flex; align-items:center; justify-content:center; gap:20px; margin-top:6px; }
.ending-link { background:none; border:0; padding:8px 4px; cursor:pointer; font-family:inherit;
  font-size:12px; letter-spacing:.22em; text-indent:.22em; color:#8f97ad; }
.ending-link:hover { color:#f0d69a; }
.ending-link:active { color:#fdf6e3; }

/* ---------- M2.5 战斗画面（v36） ---------- */
#screen-battle {
  background:
    linear-gradient(180deg, rgba(10,14,22,.38) 0%, rgba(10,14,22,.55) 100%),
    url('../assets/scenes/battle_bg.png') center / cover no-repeat,
    linear-gradient(180deg, #1e2630 0%, #0f141d 50%, #0a0e12 100%);
  overflow:hidden;
}
/* 屏显 display 只在 active 时给 flex（id 特异性会压过 .screen 的 display:none，勿写回基础规则） */
#screen-battle.active {
  display:flex; flex-direction:column; align-items:center; justify-content:center;
}
/* v122 实18：第二章战斗背景两态（书院调子，随剧情崩坏切换；默认不挂类=第一章巷战 battle_bg.png） */
#screen-battle.ch2-gold {
  background:
    linear-gradient(180deg, rgba(10,14,22,.38) 0%, rgba(10,14,22,.55) 100%),
    url('../assets/scenes/battle_bg_ch2_gold.jpg') center / cover no-repeat,
    linear-gradient(180deg, #1e2630 0%, #0f141d 50%, #0a0e12 100%);
}
#screen-battle.ch2-ruin {
  background:
    linear-gradient(180deg, rgba(10,14,22,.38) 0%, rgba(10,14,22,.55) 100%),
    url('../assets/scenes/battle_bg_ch2_ruin.jpg') center / cover no-repeat,
    linear-gradient(180deg, #1e2630 0%, #0f141d 50%, #0a0e12 100%);
}
/* v194 第三章·梦境裂口战斗背景（暗紫虚空+发光裂隙——蚀影的战场；裂口外沿不挂此类=默认巷战图） */
#screen-battle.ch3-crack {
  background:
    linear-gradient(180deg, rgba(10,14,22,.38) 0%, rgba(10,14,22,.55) 100%),
    url('../assets/scenes/battle_bg_ch3_crack.jpg') center / cover no-repeat,
    linear-gradient(180deg, #1e2630 0%, #0f141d 50%, #0a0e12 100%);
}
/* 左右站位（仙剑原版我方左、敌方右）：中部空区给攻击位移 */
#battle-stage {
  flex:1; display:flex; flex-direction:row; align-items:flex-end; justify-content:space-between;
  padding:16px 0 max(72px, 72px); width:100%; max-width:972.8px;   /* v81：地面线下压踩近景路 + 两翼内收避门阶 */
}
#battle-ally { order:0; }
#battle-arena { order:1; }
#battle-foes { order:2; }
/* v81：多怪沿街面透视斜列（右上远→左下近），单怪不偏移；margin 不用 transform 防与攻击位移打架 */
#battle-foes {
  flex:0 1 auto; display:flex; gap:14px; justify-content:center; align-items:flex-end;
  flex-direction:row; min-width:150px;
}
/* v102 ⚠01复验：多怪沿右侧墙脚透视线斜列——每级落差 ≈72/144px（用户实测：14/28 太平，要贴着墙的方向排） */
#battle-foes .bunit.foe:nth-last-child(2) { margin-bottom:72px; }
#battle-foes .bunit.foe:nth-last-child(3) { margin-bottom:144px; }
/* v201：三新怪立绘 200px 比杂兵宽，三只同场时最右一只会超出视口被裁
 * 根因：三只各 200px（合计 600px）> 舞台可用宽（972.8px ≈ 608px，且左侧还占着我方两名）
 * 处理：① 收紧间距 gap:0；② 三只全为原生怪时立绘降到 168px、斜列落差减半，
 *       让三只"贴墙脚往左上叠"而不是横排铺开。 */
#battle-foes:has(.bunit[data-eid="lingyu"]),
#battle-foes:has(.bunit[data-eid="suimeng"]),
#battle-foes:has(.bunit[data-eid="yingcan"]) {
  gap:0;
}
#battle-foes:has(.bunit[data-eid="suimeng"]):has(.bunit[data-eid="yingcan"]):has(.bunit[data-eid="lingyu"]) {
  max-width:665.6px;
  /* 斜列必然让最右一只向右错开 → 敌阵整体左移 30px 留出右边距 */
  margin-right:30px;
}
#battle-foes:has(.bunit[data-eid="suimeng"]):has(.bunit[data-eid="yingcan"]):has(.bunit[data-eid="lingyu"]) .bunit-art {
  width:168px; height:168px;
}
#battle-foes:has(.bunit[data-eid="suimeng"]):has(.bunit[data-eid="yingcan"]):has(.bunit[data-eid="lingyu"]) .bunit.foe:nth-last-child(2) { margin-bottom:52px; }
#battle-foes:has(.bunit[data-eid="suimeng"]):has(.bunit[data-eid="yingcan"]):has(.bunit[data-eid="lingyu"]) .bunit.foe:nth-last-child(3) { margin-bottom:104px; }
#battle-arena {
  flex:1; display:flex; align-items:center; justify-content:center; width:100%;
}
#battle-ally {
  flex:0 0 auto; display:flex; gap:12px; justify-content:center; align-items:flex-end;
  min-width:150px;
}
/* v80 问题23（A档）：立绘放大 + 脚底对齐地面线 + 去卡片框 + 接触影 + 待机呼吸 */
.bunit {
  position:relative; display:flex; flex-direction:column; align-items:center; justify-content:flex-end;
  transform-origin:50% 100%;   /* 脚底为轴：倒下/蓄力压缩都绕脚 */
}
.bunit-art {
  position:relative; width:170px; height:170px;   /* 小怪基准 ~170px */
  animation:idle-breath 2.8s ease-in-out infinite;
  transform-origin:50% 100%;
}
.bunit.foe[data-eid="qiongqi"] .bunit-art { width:280px; height:280px; }   /* 穷奇 BOSS ~280px */
.bunit.foe[data-eid="bifang"]  .bunit-art { width:280px; height:280px; }   /* v166 毕方同为 BOSS，此前漏了尺寸规则被当小怪显示 */
.bunit.foe[data-eid="jiuwei"]  .bunit-art { width:280px; height:280px; }   /* v228 第三章九尾 BOSS（同规格） */
/* v201：第三章原生三怪——比第一/二章杂兵壮，但不超过 Boss
 * 实测（三只同场）：230px 时灵羽妖血条顶到 107px，被顶部战斗讯息栏挤压 → 收至 200px。
 * 层级仍成立：170 杂兵 < 190 主角 < 200 三新怪 < 280 Boss */
.bunit.foe[data-eid="lingyu"]  .bunit-art,
.bunit.foe[data-eid="suimeng"] .bunit-art,
.bunit.foe[data-eid="yingcan"] .bunit-art { width:200px; height:200px; }
/* 尺寸变大后血条/名牌随之上抬，避免被立绘顶头（基准 -74/-24） */
.bunit.foe[data-eid="lingyu"]  .bunit-bar,
.bunit.foe[data-eid="suimeng"] .bunit-bar,
.bunit.foe[data-eid="yingcan"] .bunit-bar { top:-84px; }
.bunit.foe[data-eid="lingyu"]  .bunit-name,
.bunit.foe[data-eid="suimeng"] .bunit-name,
.bunit.foe[data-eid="yingcan"] .bunit-name { top:-28px; }
.bunit.ally .bunit-art { width:190px; height:190px; }                       /* 杨宇 ~190px */
/* v201：新立绘为全身写实比例（水彩），源图 381×467 内容几乎满幅；
 *   旧 156px 框 + contain 会让她比杨宇高 → 收到 172px，视觉高度与杨宇持平略低。
 *   站位：往杨宇身后叠（-26px），不向画面中央挤，避免名牌被敌方立绘压住 */
/* v203：伙伴与杨宇**上下并列**（与对面怪物斜列同一套排法）。
 *   旧版 margin-bottom:2px + align-items:center → 两人肩并肩横排，
 *   用户多次要求「跟杨宇上下并列，就跟对面怪物那种并列方式」。
 *   改法：容器 align-items:flex-end（底对齐），珂儿再抬 62px —— 站位更远＝画面更高，
 *   与 #battle-foes 的 margin-bottom:72px 斜列呼应。 */
.bunit.ally.partner { margin-left:-26px; margin-bottom:62px; }
.bunit.ally.partner .bunit-art { width:172px; height:172px; }
/* 伙伴在杨宇右侧且略后 → 抬高层级让她的名牌压在杨宇之上一层，不被挡 */
.bunit.ally.partner .bunit-name { z-index:3; }
.bunit.ally .bunit-name { z-index:2; }
.bunit.ally.partner .bunit-status { top:-44px; }
.bunit.ally.partner .bunit-name { color:#f2dcc6; }
.bunit.ally.partner .bunit-art::before {
  content:''; position:absolute; inset:-6% -8% 2%; z-index:0; border-radius:50%;
  background:radial-gradient(ellipse at 50% 62%, rgba(255,226,180,.24) 0%, rgba(255,214,150,.08) 46%, transparent 70%);
  pointer-events:none;
}
.bunit-img { position:absolute; bottom:0; left:50%; transform:translateX(-50%);
  max-width:96%; max-height:100%; width:auto; height:auto; object-fit:contain;
  filter:drop-shadow(0 4px 6px rgba(0,0,0,.5)); }
/* 脚下椭圆接触影 */
.bunit-art::after {
  content:''; position:absolute; left:50%; bottom:1%; transform:translateX(-50%);
  width:72%; height:9%; border-radius:50%; z-index:0;
  background:radial-gradient(ellipse at center, rgba(0,0,0,.42) 0%, rgba(0,0,0,.22) 45%, transparent 72%);
}
.bunit-img { z-index:1; }
/* 名牌/血条/状态点浮到头顶（脚底锚地面线后，牌面下方不再排流） */
.bunit-name {
  position:absolute; top:-24px; left:50%; transform:translateX(-50%);
  font-size:13px; color:#e8c987; letter-spacing:.1em; white-space:nowrap;
  text-shadow:0 1px 3px rgba(0,0,0,.85);
}
.bunit-bar {
  position:absolute; top:-74px; left:50%; transform:translateX(-50%);
  display:flex; flex-direction:column; gap:4px; width:86%;
}
.bunit-status { position:absolute; left:50%; transform:translateX(-50%);
  top:-44px; white-space:nowrap; min-height:0; margin:0; }
.bunit.ally .bunit-status { top:-96px; }
@keyframes idle-breath {
  0%,100% { transform:scale(1); }
  50% { transform:scale(1.008); }      /* v164 等比呼吸：原 scale(1.015,.985) 纵向压缩会让立绘轻微变形 */
}
/* v94 #5：选目标阶段提示字（不可点，纯指示） */
.cmd-tip { display:block; text-align:center; color:#e8c987; font-size:14px;
  letter-spacing:.15em; padding:9px 0; }
/* v94 #11：胜利战利小结浮牌 */
#battle-loot { position:absolute; top:14%; left:50%; transform:translateX(-50%);
  min-width:180px; padding:12px 26px; text-align:center; z-index:20;
  background:linear-gradient(180deg,rgba(24,22,38,.96),rgba(34,30,52,.96));
  border:1.5px solid #b89b5e; border-radius:10px;
  box-shadow:0 6px 22px rgba(0,0,0,.6); animation:loot-in .3s ease-out; }
#battle-loot .loot-title { color:#f0d68a; font-size:15px; letter-spacing:.5em;
  margin-bottom:6px; text-indent:.5em; }
#battle-loot .loot-row { color:#e8e2d0; font-size:14px; line-height:1.7; }
@keyframes loot-in { from { opacity:0; transform:translate(-50%,-8px); }
  to { opacity:1; transform:translate(-50%,0); } }
/* v236 实机反馈批：死亡=原地溶解消失（淡出+轻微下沉），不再保留倒地灰影虚影；
 *   死亡帧（playFrames hold）在 .dead 生效前先有一拍可读，随后整只溶掉 */
.bunit.dead {
  opacity:0; transform:translateY(10px);
  transition:opacity .5s ease-in .2s, transform .5s ease-in .2s;
  pointer-events:none;
}
/* v93 #6：选目标金框停用（.targeting 不再挂样式与类，目标提示仅留"请点选目标"文字） */
.st-dot {
  display:inline-block; width:10px; height:10px; border-radius:50%;
  margin-right:4px; vertical-align:middle;
}
.st-dot.poison { background:#7fd67f; box-shadow:0 0 6px rgba(127,214,127,.6); }
.st-dot.hitdown { background:#7fa8ff; }
.bunit.hitflash {
  animation:hit-flash .38s ease-in-out;
}
/* v151 受击后仰（打击感）：命中者朝 --rx/--rr 方向后仰+抬升+砸压，与闪白同时播（filter/transform 互不冲突）
   v164 根治非等比：原 scale(1.1,.88) 纵向压扁 12%，等于让角色瞬间"变矮变胖"（用户反感橡皮变形）。
   改为等比缩放 + 旋转/位移表达"后仰砸地"，视觉冲击不减，比例不变形。 */
.bunit.hitreact { animation: hit-flash .38s ease-in-out, hit-recoil .36s ease-out; }
/* v165 受击帧配套：父级只做**纯位移**（不旋转/不缩放）。
   受击姿态已由 *_hit 帧素材表达，父级再叠加强旋转会变成"双重动作打架"。 */
.bunit.hitnudge { animation: hit-nudge .30s ease-out; }
@keyframes hit-nudge {
  0%   { transform: translate(0,0); }
  30%  { transform: translate(var(--rx,0px), 0); }
  100% { transform: translate(0,0); }
}
@keyframes hit-recoil {
  0%   { transform: translate(0,0) rotate(0deg) scale(1); }
  22%  { transform: translate(var(--rx,0px), 7px) rotate(var(--rr,0deg)) scale(1.1); }
  55%  { transform: translate(calc(var(--rx,0px) * .35), 0px) rotate(calc(var(--rr,0deg) * .3)) scale(.97); }
  100% { transform: translate(0,0) rotate(0deg) scale(1); }
}
.bdmg {
  position:absolute; top:-10px; left:50%; transform:translateX(-50%);
  font-size:20px; font-weight:700; color:#fff;
  text-shadow:2px 2px 0 #000, -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000;
  pointer-events:none; white-space:nowrap;
  animation:bdmg-float .9s ease-out forwards;
}
.bdmg.white { color:#fff; }
.bdmg.gold { color:#ffd98a; }
.bdmg.green { color:#7fd67f; }
.bdmg.gray { color:#99a2b0; }
.bdmg.blue { color:#7fa8ff; }
.bdmg.purple { color:#c88ae0; }
/* v175 P1-6 飘字美术：会心放大染金（渐变+光晕+弹入）/ MISS 斜体灰 / 治疗绿字高浮 / 连击徽章 */
.bdmg.crit {
  font-size:32px; font-weight:800; letter-spacing:.02em;
  background:linear-gradient(180deg,#fff7cf 6%,#ffd94e 42%,#f5a81b 72%,#c07808 100%);
  -webkit-background-clip:text; background-clip:text;
  color:transparent; -webkit-text-fill-color:transparent;
  filter:drop-shadow(0 0 10px rgba(255,190,40,.85)) drop-shadow(0 2px 2px rgba(0,0,0,.85));
  animation:bdmg-crit .95s cubic-bezier(.16,.8,.3,1) forwards;
}
@keyframes bdmg-crit {
  0%   { opacity:0; transform:translateX(-50%) scale(.35); }
  16%  { opacity:1; transform:translateX(-50%) scale(1.28); }
  30%  { transform:translateX(-50%) scale(1); }
  100% { opacity:0; transform:translateX(-50%) translateY(-48px) scale(1); }
}
.bdmg.miss { font-style:italic; letter-spacing:.14em; opacity:.92; animation:bdmg-miss .8s ease-out forwards; }
@keyframes bdmg-miss {
  0%   { opacity:0; transform:translateX(-50%) scale(.8); }
  25%  { opacity:.92; transform:translateX(-50%) scale(1); }
  100% { opacity:0; transform:translateX(-50%) translateY(-30px); }
}
.bdmg.heal { font-size:23px; animation:bdmg-heal .95s ease-out forwards; }
@keyframes bdmg-heal {
  0%   { opacity:0; transform:translateX(-50%) translateY(12px) scale(.8); }
  22%  { opacity:1; transform:translateX(-50%) translateY(0) scale(1); }
  100% { opacity:0; transform:translateX(-50%) translateY(-56px) scale(1); }
}
/* 连击徽章：数字 span 的子元素，贴在数字右侧，同生共灭 */
.bdmg-combo {
  position:absolute; left:100%; top:50%; margin-left:5px;
  transform:translateY(-50%);
  font-size:15px; font-weight:800; color:#ffd98a; white-space:nowrap;
  text-shadow:0 0 8px rgba(255,180,50,.95), 1px 1px 0 #000, -1px -1px 0 #000;
  pointer-events:none;
  animation:bdmg-combo .9s cubic-bezier(.2,.8,.3,1) forwards;
}
@keyframes bdmg-combo {
  0%   { opacity:0; transform:translateY(-50%) scale(.4); }
  22%  { opacity:1; transform:translateY(-50%) scale(1.22); }
  38%  { transform:translateY(-50%) scale(1); }
  100% { opacity:0; transform:translateY(-50%) translateY(-34px); }
}
#battle-flash {
  position:fixed; inset:0; background:#fff; opacity:0; pointer-events:none;
  z-index:100; transition:opacity .1s;
}
#battle-flash.on {
  animation:flash-in .6s forwards;
}
/* v248：攻击白闪柔和档——暖色低峰值（用户实测"太刺眼"），开场/K.O. 仍走全白 */
#battle-flash.soft { background:#ffe9c4; }
#battle-flash.on.soft {
  animation:flash-in-soft .38s ease-out forwards;
}
@keyframes flash-in-soft {
  0% { opacity:0; }
  34% { opacity:.32; }
  100% { opacity:0; }
}
#battle-msg {
  position:absolute; bottom:calc(24px + env(safe-area-inset-bottom));
  left:50%; transform:translateX(-50%);
  min-height:44px; padding:10px 20px;
  background:rgba(30,32,50,.92); border:2px solid #b89b5e; border-radius:12px;
  font-size:14px; color:#e8c987; letter-spacing:.1em; text-align:center;
  max-width:1177.6px; line-height:1.6; box-shadow:0 6px 20px rgba(0,0,0,.6);
}
#battle-cmds {
  position:absolute; bottom:calc(16px + env(safe-area-inset-bottom));
  left:50%; transform:translateX(-50%);
  min-width:340px; max-width:1203.2px; padding:10px;
  background:rgba(30,32,50,.92); border:2px solid #b89b5e; border-radius:14px;
  display:flex; flex-wrap:wrap; justify-content:center; gap:8px;
}
.cmd-empty { color:#8d93a8; font-size:13px; text-align:center; padding:10px 4px; }
.cmd-btn {
  min-height:46px; min-width:72px; padding:0 16px;
  border:1.5px solid #b89b5e; border-radius:10px;
  background:rgba(38,40,60,.85); color:#e8c987; font-size:15px; letter-spacing:.15em;
  cursor:pointer; transition:background .15s, transform .08s;
}
.cmd-btn small { font-size:11px; color:#8d93a8; letter-spacing:0; }
/* v101 ⚠04：法术菜单介绍小字（对齐物品菜单功效小字做法） */
.cmd-sub .cmd-btn { text-align:left; }
.cmd-btn .sk-desc { display:block; margin-top:3px; font-size:11px; line-height:1.5;
  color:#8d93a8; letter-spacing:0; white-space:normal; }
.cmd-btn:not(:disabled):active { background:#39406b; transform:scale(.96); }
.cmd-btn.on { background:#39406b; }
.cmd-btn:disabled { opacity:.45; }
.cmd-sub {
  display:flex; flex-direction:column; gap:8px; max-height:288px; overflow-y:auto;
  margin-top:8px;
}
#battle-stop {
  position:absolute; top:calc(env(safe-area-inset-top) + 12px);
  right:12px; width:44px; height:44px; border:1.5px solid #b89b5e; border-radius:50%;
  background:rgba(30,32,50,.92); color:#e8c987; font-size:16px; font-weight:700;
  letter-spacing:.1em; cursor:pointer; transition:background .15s;
  z-index:90;
}
#battle-stop:active { background:#39406b; }
@keyframes bdmg-float {
  0% { opacity:1; transform:translateX(-50%) translateY(0); }
  100% { opacity:0; transform:translateX(-50%) translateY(-36px); }
}
.bunit.cast {
  animation:cast-glow .5s ease-in-out;
}
@keyframes cast-glow {
  0%,100% { filter:none; }
  50% { filter:brightness(1.8) drop-shadow(0 0 10px #ffd98a); }
}
/* ---------- 攻击特效层（.fx 节点由 JS 打在受击单位上，动画完自删） ---------- */
.bunit .fx { position:absolute; left:50%; top:50%; pointer-events:none; z-index:6; }   /* v103-01：特效锚点=单位正中心（原22%在头顶） */
/* 普攻：斜切斩光 */
.fx-slash {
  width:72px; height:6px; margin-left:-36px; margin-top:-3px;
  background:linear-gradient(90deg, transparent, #fff 45%, #fff 55%, transparent);
  border-radius:3px;
  animation:fx-slash .35s ease-out forwards;
}
@keyframes fx-slash {
  0% { opacity:0; transform:rotate(-40deg) scaleX(.2); }
  35% { opacity:1; transform:rotate(-40deg) scaleX(1.15); }
  100% { opacity:0; transform:rotate(-40deg) scaleX(1.3); }
}
/* ---------- v102 四法术 8帧雪碧图特效 ----------
 * 资产=assets/icons/skills/{id}_fx.png（2列×4行，帧1=左上，帧序从左到右、从上到下）
 * 节奏 v235 提速=112.5ms/帧 × 8 = 0.9s（原 150ms/帧×8=1.2s；打击段先行，steps(1,end) 逐帧硬切）
 * 节点存活由 spawnFx 控制（法术 1000ms） */
.fx-shiyizhan, .fx-nimengpo, .fx-jinyuzhan {
  width:124px; height:124px; margin-left:-62px; margin-top:-62px;
}
.fx-huxinzhou {
  width:108px; height:108px; margin-left:-54px; margin-top:-54px;
}
.fx-yichaoyong, .fx-liuhuoyin {
  width:148px; height:148px; margin-left:-74px; margin-top:-74px;
}
.fx-shiyizhan, .fx-nimengpo, .fx-huxinzhou, .fx-yichaoyong, .fx-jinyuzhan, .fx-liuhuoyin {
  background-repeat:no-repeat; background-size:200% 400%;
  animation:fx-frames8 0.9s steps(1,end) forwards;
}
.fx-shiyizhan  { background-image:url('../assets/icons/skills/shiyizhan_fx.png'); }
.fx-nimengpo   { background-image:url('../assets/icons/skills/nimengpo_fx.png'); }
.fx-huxinzhou  { background-image:url('../assets/icons/skills/huxinzhou_fx.png'); }
.fx-yichaoyong { background-image:url('../assets/icons/skills/yichaoyong_fx.png'); }
.fx-jinyuzhan  { background-image:url('../assets/icons/skills/jinyuzhan_fx.png'); }   /* v117 第二章 */
.fx-liuhuoyin  { background-image:url('../assets/icons/skills/liuhuoyin_fx.png'); }   /* v117 第二章 */
@keyframes fx-frames8 {
  0%    { background-position:0% 0%; opacity:1; }
  12.5% { background-position:100% 0%; }
  25%   { background-position:0% 33.333%; }
  37.5% { background-position:100% 33.333%; }
  50%   { background-position:0% 66.667%; }
  62.5% { background-position:100% 66.667%; }
  75%   { background-position:0% 100%; }
  87.5% { background-position:100% 100%; }
  100%  { background-position:100% 100%; opacity:0; }
}
/* v104/v106：技能名飘字（受击者血条正上方，自下而上）
 *
 * v295【用户实机："拾忆斩技能在第一次切屏以后，在释放就是显示文字，在技能文字消失的一瞬间，
 *   屏幕中间有一个明显的白条，别的技能也这样"】——**白条就是这个元素，不是大招大字**。
 *   原因：原先用 `background-clip:text` 从渐变里抠字，字本身透明；淡出时合成层重建，
 *   那一帧 clip 失效 → 整块渐变当普通背景铺出来 → 88×30 的金白横条（复现图
 *   tools/_shots_v295/callout_white_bar_broken.png，跟用户截图一模一样）。
 *   23px 的小字本来就看不出渐变，索性**不再用 clip**：纯金 + 双层 text-shadow 描边，
 *   结构上不可能再露出白块。同时把 filter 换成 text-shadow，少一层合成。 */
.bunit .skill-callout {
  position:absolute; left:50%; top:-80px; transform:translateX(-50%);
  font-family:"STKaiti","KaiTi","华文楷体","楷体","STZhongsong",serif;
  font-size:23px; font-weight:700; letter-spacing:.28em; white-space:nowrap;
  color:#ffd94e; -webkit-text-fill-color:#ffd94e;
  text-shadow:
    0 -1px 0 #fff7cf,
    0 1px 0 #c07808,
    0 0 8px rgba(255,190,40,.9),
    0 1px 2px rgba(0,0,0,.85);
  pointer-events:none; z-index:9;
  animation:skill-callout 1.05s ease-out forwards;
  will-change:opacity, transform;
}
@keyframes skill-callout {
  0%   { opacity:0; transform:translateX(-50%) translateY(18px); }
  25%  { opacity:1; }
  100% { opacity:0; transform:translateX(-50%) translateY(-30px); }
}
/* 命中火花（v44）：applyHit 法术命中时迸 6 粒星火（普攻不迸） */
.bunit .fx-spark {
  position:absolute; left:50%; top:42%;
  width:5px; height:5px; margin:-2px 0 0 -2px;
  border-radius:50%; background:#eef8ff;
  box-shadow:0 0 6px #9fd8ff, 0 0 12px #6fb8ff;
  animation:spark-fly .5s ease-out forwards;
}
@keyframes spark-fly {
  0%   { opacity:1; transform:translate(0,0) scale(1); }
  100% { opacity:0; transform:translate(var(--dx,18px), var(--dy,-14px)) scale(.3); }
}
/* 法术命中震屏（v42）：applyHit 里 fx!=slash 时触发
 * v247：幅度改 CSS 变量（--shk/--shk-h）——demo.html 试验场实时可调 */
#battle-stage.shake { animation:stage-shake .26s linear; }
@keyframes stage-shake {
  0%,100% { transform:none; }
  20% { transform:translate(calc(var(--shk,4px) * -1), calc(var(--shk,4px) * .5)); }
  40% { transform:translate(var(--shk,4px), calc(var(--shk,4px) * -.5)); }
  60% { transform:translate(calc(var(--shk,4px) * -.75), calc(var(--shk,4px) * -.25)); }
  80% { transform:translate(calc(var(--shk,4px) * .75), calc(var(--shk,4px) * .25)); }
}
/* ---------- 战斗留档浮层（v45，借鉴 hayao Workshop 思想） ---------- */
.log-overlay { position:fixed; inset:0; z-index:210; background:rgba(10,12,24,.74); display:flex; align-items:center; justify-content:center; padding:18px; }
.log-card { width:100%; max-width:540px; background:#1d2542; border:2px solid #303a63; border-radius:14px; padding:18px; color:#eef1f9; }
.log-card h3 { margin:0 0 8px; font-size:17px; color:#e59500; }
.log-hint { margin:0 0 10px; font-size:13px; color:#b3bbd4; }
.log-card textarea { width:100%; box-sizing:border-box; height:104px; background:#141a30; color:#b3bbd4; border:1px solid #303a63; border-radius:8px; padding:8px; font-size:12px; word-break:break-all; resize:none; }
.log-card .close-log { margin-top:12px; }
@keyframes hit-flash {
  0%,100% { filter:none; }
  15%,55% { filter:brightness(2.8); }
  35%,75% { filter:brightness(.55); }
}
@keyframes flash-in {
  0% { opacity:0; }
  50% { opacity:.85; }
  100% { opacity:0; }
}

/* ---------- v84 支线A：图鉴异闻小节 + 找猫小演出 ---------- */
.col-sub { font-size:14px; letter-spacing:.2em; color:#c8b06a; margin:14px 0 6px; text-align:center; }
.col-sub .save-note { display:inline; margin:0 0 0 6px; }

/* ---------- v141 实39：信物图鉴章节翻页头（‹ 章节名+本章进度 ›，一章一页） ---------- */
.col-pager { display:flex; align-items:center; justify-content:center; gap:14px; margin:2px 0 8px; }
.col-pager-btn { width:40px; height:34px; border:1px solid #6a6f85; border-radius:8px; background:rgba(30,32,44,.75);
  color:#e8c66a; font-size:20px; line-height:1; cursor:pointer; padding:0 0 3px; }
.col-pager-btn:hover:not(:disabled) { background:rgba(60,63,82,.9); }
.col-pager-btn:disabled { opacity:.32; cursor:default; }
.col-pager-title { font-size:15px; letter-spacing:.12em; color:#c8b06a; min-width:170px; text-align:center; }
.cat-curtain { position:absolute; width:46px; height:auto; z-index:60; pointer-events:none;
  animation: cat-run 2.3s cubic-bezier(.45,.05,.65,1) forwards; }
@keyframes cat-run {
  0%   { left:366px; top:400px; opacity:0; }
  12%  { opacity:1; }
  70%  { opacity:1; }
  100% { left:336px; top:466px; opacity:0; }
}

/* ---------- v86 #4：左上常驻任务栏（默认收起，点开详情） ---------- */
/* v113 ⚠13②：任务栏固定在「＋」右侧（随折叠组排布，不再绝对定位） */
.qhud { position:relative; margin:2px 0 0 12px; z-index:40; text-align:left; }
.qhud-tab { display:inline-flex; align-items:center; gap:4px; padding:6px 14px; font-size:13px; letter-spacing:.2em;
  color:#d8c48a; background:rgba(16,18,34,.72); border:1px solid #6a5a2e; border-radius:14px;
  box-shadow:0 2px 8px rgba(0,0,0,.35); }
.qhud-dot { font-size:11px; color:#1a1408; background:#e8c34e; border-radius:50%;
  width:16px; height:16px; line-height:16px; text-align:center; letter-spacing:0; }
.qhud-dot.hidden { display:none; }
.qhud-body { margin-top:6px; padding:10px 12px; max-width:921.6px;
  background:rgba(14,16,30,.82); border:1px solid #6a5a2e; border-radius:10px;
  box-shadow:0 4px 14px rgba(0,0,0,.4); }
.qhud-row { display:flex; align-items:flex-start; gap:8px; font-size:12px; color:#e6e2d4;
  line-height:1.6; margin:4px 0; }
.qhud-tag { flex:none; font-size:10px; padding:1px 7px; border-radius:8px; margin-top:2px; letter-spacing:.15em; }
.qhud-tag.main { color:#e8c34e; border:1px solid #8a7434; }
.qhud-tag.side { color:#7ecfc0; border:1px solid #3d7a6e; }

/* ---------- v91 Boss 二阶段侵蚀暴走 + 彩蛋「巷口的白影」 ---------- */
/* 穷奇二阶段：红黑滤镜 + 抖动（引擎 phase 事件挂 .rage，UI 播放） */
.bunit.foe.rage .bunit-img {
  filter:drop-shadow(0 4px 6px rgba(0,0,0,.5)) saturate(1.7) hue-rotate(-25deg) brightness(.82) contrast(1.15); }
.bunit.foe.rage { animation: rage-shake .5s ease-in-out 2; }
@keyframes rage-shake {
  0%,100% { transform:translateX(0); }
  20% { transform:translateX(-5px) rotate(-.6deg); }
  40% { transform:translateX(5px) rotate(.6deg); }
  60% { transform:translateX(-4px); }
  80% { transform:translateX(4px); }
}
/* 巷口白影（沈珂儿远望虚影）：半透明呼吸 + 淡蓝辉光，纯演出不参与交互 */
.ker-ghost { position:absolute; z-index:55; pointer-events:none; opacity:0;
  filter:drop-shadow(0 0 14px rgba(150,205,255,.85)) drop-shadow(0 0 4px rgba(255,255,255,.6)) brightness(1.12);
  animation: ghost-breathe 2.6s ease-in-out infinite; }
@keyframes ghost-breathe {
  0%,100% { opacity:.34; }
  45% { opacity:.6; }
}

/* 毕方战后·珂儿正面一瞬（v146 方案A）：暖金辉光光尘里立现，1.2s 缓入，.out 化光散去；
 * 崩坏滤镜对她豁免——灰紫废墟里唯一的暖色，即"她守着的记忆"本体 */
.keer-front { position:absolute; z-index:55; pointer-events:none; opacity:0;
  filter:drop-shadow(0 0 16px rgba(255,225,150,.8)) drop-shadow(0 0 5px rgba(255,255,255,.55)) brightness(1.08);
  animation:keer-in 1.2s ease-out forwards; }
@keyframes keer-in { from { opacity:0; } to { opacity:.96; } }
.keer-front.out { transition:opacity 1.1s ease-in; opacity:0 !important; animation:none; }
#map-world.world-ruin > .keer-front { filter:drop-shadow(0 0 18px rgba(255,225,150,.9)) drop-shadow(0 0 6px rgba(255,255,255,.6)); }

/* ---------- v117 第二章崩坏态滤镜（map.js 按 ch2_state 挂 #map-world；暖金→灰紫） ---------- */
#map-world.world-ruin > :not(#player) { filter: saturate(.5) hue-rotate(215deg) brightness(.85) contrast(1.05); }   /* v135 C案：崩坏褪色只染场景，杨子立绘保留彩色 */

/* ---------- v148 音频设置页 ---------- */
.set-row { display:flex; align-items:center; justify-content:space-between; gap:12px;
  padding:12px 6px; border-bottom:1px dashed rgba(230,200,140,.16); }
.set-row:last-of-type { border-bottom:none; }
.set-row > span { color:#e8e2d5; font-size:15px; letter-spacing:2px; flex-shrink:0; }
.set-row input[type="range"] { flex:1; max-width:190px; accent-color:#c9a35c; height:26px; }
#set-mute { min-width:88px; padding:9px 0; }
#set-mute.on { color:#ffd98a; border-color:#c9a35c; }

/* ========== v174 背包重做：仓库式格子 + 稀有度分层 + 物品详情弹窗 ========== */
/* —— 仓库网格 —— */
.bag-grid { display:grid; grid-template-columns:repeat(5,1fr); gap:8px;
  max-height:374.4px; overflow-y:auto; padding:6px 4px 10px; align-content:start;
  scrollbar-width:thin; scrollbar-color:#5a5f78 transparent; }
.bag-grid::-webkit-scrollbar { width:6px; }
.bag-grid::-webkit-scrollbar-thumb { background:#5a5f78; border-radius:3px; }
@media (max-width:640px) { .bag-grid { grid-template-columns:repeat(4,1fr); } }
/* —— 单格 —— */
.bag-cell { position:relative; aspect-ratio:1/1; border-radius:13px; cursor:pointer;
  display:flex; align-items:center; justify-content:center; overflow:hidden;
  border:1px solid #4a4f66; background:linear-gradient(160deg, rgba(46,50,74,.92), rgba(22,24,38,.96));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.04), 0 2px 6px rgba(0,0,0,.35);
  transition:transform .08s, box-shadow .15s, border-color .15s; }
.bag-cell:active { transform:scale(.93); }
.bag-cell img { width:80%; height:80%; object-fit:contain; filter:drop-shadow(0 2px 3px rgba(0,0,0,.5)); pointer-events:none; }
.bag-cell .qty { position:absolute; right:3px; bottom:3px; min-width:17px; height:16px; line-height:16px;
  padding:0 4px; font-size:11px; text-align:center; color:#fff; font-weight:700;
  background:rgba(0,0,0,.62); border-radius:8px; box-shadow:0 1px 2px rgba(0,0,0,.5); pointer-events:none; }
.bag-cell.empty { border-style:dashed; border-color:#363a50; background:rgba(18,20,32,.45); cursor:default;
  box-shadow:none; }
.bag-cell.empty:active { transform:none; }
.bag-cell.sel { border-color:#f0d68a !important; box-shadow:0 0 0 2px rgba(240,214,138,.7), 0 0 14px rgba(240,214,138,.3); }
/* —— 稀有度分层（普通/精良/稀有/传说）—— */
.bag-cell::before { content:''; position:absolute; left:0; right:0; top:0; height:3px; background:var(--rc,#6b5a35); opacity:.92; }
.bag-cell.r0 { --rc:#7c8197; border-color:#4a4f66; }
.bag-cell.r1 { --rc:#5fb37a; border-color:#3f7a52; box-shadow:inset 0 0 0 1px rgba(95,179,122,.4), 0 2px 6px rgba(0,0,0,.35); }
.bag-cell.r2 { --rc:#5b8fd6; border-color:#3d5e9e; box-shadow:inset 0 0 0 1px rgba(91,143,214,.5), 0 2px 6px rgba(0,0,0,.35); }
.bag-cell.r3 { --rc:#ffb04d; border-color:#b9822f; box-shadow:inset 0 0 0 1px rgba(255,176,77,.6), 0 0 12px rgba(255,176,77,.3); }

/* —— 物品详情弹窗 —— */
.item-detail { position:fixed; inset:0; z-index:70; display:flex; align-items:center; justify-content:center;
  background:rgba(8,9,16,.7); padding:18px; }
.item-detail.hidden { display:none; }
.id-card { width:min(1100.8px,360px); max-height:604.8px; overflow-y:auto; text-align:left;
  background:linear-gradient(180deg,#252845,#191b2b); border:2px solid #b89b5e; border-radius:18px;
  padding:18px 18px 16px; box-shadow:0 22px 56px rgba(0,0,0,.62), inset 0 0 0 1px rgba(184,155,94,.18);
  animation:id-in .16s ease-out; }
@keyframes id-in { from { opacity:0; transform:translateY(10px) scale(.97); } }
.id-head { display:flex; align-items:center; gap:14px; margin-bottom:12px; }
.id-ico { width:84px; height:84px; flex:none; border-radius:14px; display:flex; align-items:center; justify-content:center;
  background:radial-gradient(circle at 38% 32%, rgba(255,255,255,.08), rgba(0,0,0,.28));
  border:2px solid var(--rc,#6b5a35); box-shadow:inset 0 0 0 1px rgba(255,255,255,.06), 0 0 12px var(--rcg,rgba(0,0,0,0)); }
.id-ico img { width:84%; height:84%; object-fit:contain; filter:drop-shadow(0 2px 3px rgba(0,0,0,.5)); }
.id-titles { min-width:0; }
.id-name { font-size:19px; font-weight:700; letter-spacing:.06em; color:var(--rc,#f0e2c0);
  text-shadow:0 1px 2px #000, 0 0 10px var(--rcg,rgba(0,0,0,0)); }
.id-tag { display:inline-block; margin-top:6px; font-size:11px; letter-spacing:.18em; padding:2px 10px; border-radius:9px;
  color:#0d0f1a; background:var(--rc,#9aa0b5); font-weight:700; }
.id-type { font-size:12px; color:#8d93a8; margin:2px 0 10px; letter-spacing:.06em; }
.id-desc { font-size:13px; line-height:1.75; color:#ddd4bd; margin-bottom:10px; }
.id-stat { display:inline-block; font-size:13px; font-weight:600; letter-spacing:.04em; color:var(--rc,#f0d68a);
  background:rgba(255,255,255,.05); border:1px solid var(--rc,#6b5a35); border-radius:10px; padding:4px 10px; margin-bottom:10px; }
.id-qty { font-size:12px; color:#8d93a8; margin-bottom:14px; letter-spacing:.04em; }
.id-acts { display:flex; flex-wrap:wrap; gap:8px; }
.id-btn { flex:1; min-width:84px; min-height:42px; border-radius:11px; border:1px solid #8a7343;
  background:rgba(60,48,22,.8); color:#f0e2c0; font-size:14px; letter-spacing:.1em; cursor:pointer;
  box-shadow:0 2px 8px rgba(0,0,0,.4); transition:filter .12s, transform .08s; }
.id-btn:active { transform:scale(.96); filter:brightness(1.2); }
.id-btn.primary { border-color:#c9a35c; background:linear-gradient(180deg,#6a4a1f,#4a3315); color:#ffe6b0; }
.id-btn.danger { border-color:#8a4343; color:#e8b0a0; }
.id-btn:disabled { opacity:.4; cursor:default; }
.id-close { width:100%; margin-top:10px; }

/* ========== v295 数量浮层（买 / 卖共用，复用 #item-detail 容器） ==========
 * 用户要求："带拉条的那种，能一次性卖好多个，而不是一个一个卖"。
 * 买卖两侧只有"上限来源"和"按钮文案"不同，样式完全共用。 */
.qty-card { width:min(1126.4px,380px); }
.qty-head { display:flex; align-items:center; gap:14px; margin-bottom:16px; }
.qty-ico { width:56px; height:56px; flex:none; object-fit:contain; border-radius:12px; padding:4px;
  background:radial-gradient(circle at 38% 32%, rgba(255,255,255,.08), rgba(0,0,0,.28));
  border:1px solid #6b5a35; }
.qty-titles { min-width:0; }
.qty-name { font-size:17px; font-weight:700; letter-spacing:.06em; color:#f0e2c0; text-shadow:0 1px 2px #000; }
.qty-unit { margin-top:5px; font-size:12px; color:#8d93a8; letter-spacing:.04em; }

.qty-slider { padding:8px 2px 2px; }
.qty-slider input[type="range"] {
  -webkit-appearance:none; appearance:none; display:block; width:100%; height:6px; margin:0;
  border-radius:3px; outline:none; cursor:pointer;
  background:linear-gradient(90deg, #c9a35c var(--qty-p,0%), #3a3f60 var(--qty-p,0%));
}
.qty-slider input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance:none; width:22px; height:22px; border-radius:50%; cursor:pointer;
  background:radial-gradient(circle at 36% 32%, #ffeec0, #c9a35c 62%, #8a6a2c);
  border:2px solid #4a3a18; box-shadow:0 2px 8px rgba(0,0,0,.55);
}
.qty-slider input[type="range"]::-moz-range-thumb {
  width:20px; height:20px; border-radius:50%; cursor:pointer; background:#c9a35c; border:2px solid #4a3a18;
}

.qty-row { display:flex; align-items:center; gap:10px; margin:12px 0 16px; }
.qty-num { font-size:15px; color:#ffe6b0; letter-spacing:.06em; }
.qty-num b { font-size:20px; color:#ffd46a; margin-left:2px; }
.qty-all { margin-left:auto; padding:5px 12px; border-radius:9px; cursor:pointer;
  border:1px solid #8a7343; background:rgba(60,48,22,.8); color:#e8c98a;
  font-size:12px; letter-spacing:.1em; }
.qty-all:active { filter:brightness(1.25); }
.qty-total { min-width:88px; text-align:right; font-size:16px; font-weight:700; color:#ffd46a; letter-spacing:.04em; }
.qty-total.spent { color:#ff9d5c; text-shadow:0 0 10px rgba(255,150,60,.75); }

/* ========== v280 空装备槽 → 行囊同槽选装弹窗（复用 #item-detail 容器） ==========
 * 结构：.id-card.gp-card > .gp-head / .gp-sub / .gp-list > .gp-row*
 * 每行左图标、中名称+属性、右一个「穿」字。点整行即穿，不做二次确认——
 * 这个操作可逆（穿上后回归行囊，详情里能卸），加确认只会多一次点击。 */
.gp-card { width:min(1152px,420px); }
.gp-head { font-size:17px; font-weight:700; letter-spacing:.1em; color:#f0d68a; margin-bottom:4px; }
.gp-sub  { font-size:12px; color:#8d93a8; letter-spacing:.04em; margin-bottom:12px; }
.gp-list { display:flex; flex-direction:column; gap:8px; max-height:374.4px; overflow-y:auto; }
.gp-row { display:flex; align-items:center; gap:10px; width:100%; text-align:left; cursor:pointer;
  padding:8px 10px; border-radius:11px;
  border:1px solid var(--rc,#6b5a35);
  background:linear-gradient(160deg, rgba(46,50,74,.92), rgba(22,24,38,.96));
  box-shadow:inset 0 0 0 1px var(--rcg,rgba(0,0,0,0)); transition:filter .12s, transform .08s; }
.gp-row:active { transform:scale(.98); filter:brightness(1.18); }
.gp-row:hover { filter:brightness(1.12); }
.gp-ico { width:44px; height:44px; flex:none; object-fit:contain; border-radius:9px;
  border:1px solid #565b70; background:rgba(20,22,36,.7); padding:2px; }
.gp-txt { display:flex; flex-direction:column; gap:3px; flex:1; min-width:0; }
.gp-name { font-size:14px; color:#e8ddc0; letter-spacing:.04em; }
.gp-name small { color:#8d93a8; font-size:11px; }
.gp-fx { font-size:11px; color:var(--rc,#a5854a); letter-spacing:.03em; }
.gp-go { flex:none; font-size:12px; letter-spacing:.16em; color:#ffe6b0;
  border:1px solid #8a7343; border-radius:9px; padding:6px 10px; background:rgba(60,48,22,.8); }

/* —— 人物面板：六装备槽升级为装备井 —— */
.gear-slot { position:relative; display:flex; flex-direction:column; align-items:center; gap:3px;
  border:1px solid #6b5a35; border-radius:13px; padding:9px 4px 7px; cursor:pointer; overflow:hidden;
  background:linear-gradient(160deg, rgba(46,50,74,.92), rgba(22,24,38,.96));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.04), 0 2px 6px rgba(0,0,0,.35); }
.gear-slot::before { content:''; position:absolute; left:0; right:0; top:0; height:3px; background:var(--rc,#6b5a35); opacity:.9; }
.gear-slot.has { border-color:var(--rc,#a5854a); box-shadow:inset 0 0 0 1px var(--rcg,rgba(165,133,74,.5)), 0 0 10px var(--rcg,rgba(0,0,0,0)); }
.gear-slot.has.r1 { border-color:#3f7a52; }
.gear-slot.has.r2 { border-color:#3d5e9e; }
.gear-slot.has.r3 { border-color:#b9822f; box-shadow:inset 0 0 0 1px rgba(255,176,77,.6), 0 0 14px rgba(255,176,77,.32); }
.gear-slot.locked { opacity:.5; cursor:default; }
.gear-slot[disabled] { cursor:default; }
/* v280：空槽可点了（去掉了 disabled 属性），必须给一个"这儿能点"的视觉信号，
 *   否则和原来那六个死格子长得一模一样。左上角一个小 "+"、底色比已穿槽淡一档、
 *   hover 时描边亮起来。 */
.gear-slot.empty { border-style:dashed; border-color:#5a4d31; }
.gear-slot.empty:hover, .gear-slot.empty:focus-visible {
  border-color:#c9a35c; box-shadow:inset 0 0 0 1px rgba(201,163,92,.35), 0 0 12px rgba(201,163,92,.22); }
.gear-slot.empty::before { opacity:.35; }
.gear-ico { width:46px; height:46px; object-fit:contain; border:1px solid #565b70; border-radius:10px;
  background:rgba(20,22,36,.7); padding:3px; filter:drop-shadow(0 2px 2px rgba(0,0,0,.4)); }
.gear-ico.ph { background:rgba(20,22,36,.4); border-style:dashed; }
.gear-ico.ph { display:flex; align-items:center; justify-content:center; }
.gear-ico.ph i { font-style:normal; font-size:20px; line-height:1; color:#7a6a48; }
.gear-slot.empty:hover .gear-ico.ph i { color:#e8c77a; }
.gear-k { color:#f0d68a; font-size:12px; letter-spacing:.18em; }
.gear-v { color:#e8ddc0; font-size:12px; }
.gear-v.dim { color:#8a7c5e; }

/* ========== v175 P1-5 场景转场：水墨晕开(ink) / 圆形扩散(circle) / 擦除(wipe) ==========
 * 全屏覆盖层由 js/core/transition.js 创建；cover=盖住(340ms)→hold 换屏(90ms)→open=揭开(360ms)。
 * 演出期间吞点击防误触；z300 高于一切层级（战斗闪白 z100/详情 z70/菜单 z50）。 */
#scene-transition {
  position:fixed; inset:0; z-index:300; display:none; pointer-events:auto;
  background:radial-gradient(120% 90% at 50% 38%, rgba(38,44,72,.94) 0%, rgba(13,16,24,.98) 62%, rgba(9,11,18,1) 100%);
}
#scene-transition::after {                    /* 纸纹颗粒（极淡，增加"墨纸"质感） */
  content:''; position:absolute; inset:0; opacity:.55;
  background:repeating-linear-gradient(0deg, rgba(255,255,255,.022) 0 1px, transparent 1px 3px);
}
#scene-transition.cover, #scene-transition.open { display:block; }
#scene-transition.cover { animation:tr-cover 340ms cubic-bezier(.45,.05,.55,.95) forwards; }
#scene-transition.open  { animation:tr-open 360ms cubic-bezier(.45,.05,.55,.95) forwards; }
#scene-transition.ink.cover    { animation-name:tr-ink-cover; }
#scene-transition.ink.open     { animation-name:tr-ink-open; }
#scene-transition.circle.cover { animation-name:tr-circle-cover; }
#scene-transition.circle.open  { animation-name:tr-circle-open; }
#scene-transition.wipe.cover   { animation-name:tr-wipe-cover; }
#scene-transition.wipe.open    { animation-name:tr-wipe-open; }
@keyframes tr-ink-cover    { from { clip-path:circle(0% at 50% 50%); }    to { clip-path:circle(150% at 50% 50%); } }
@keyframes tr-ink-open     { from { clip-path:circle(150% at 50% 50%); }  to { clip-path:circle(0% at 50% 50%); } }
@keyframes tr-circle-cover { from { clip-path:circle(0% at 50% 108%); }   to { clip-path:circle(155% at 50% 108%); } }
@keyframes tr-circle-open  { from { clip-path:circle(155% at 50% 108%); } to { clip-path:circle(0% at 50% -8%); } }
@keyframes tr-wipe-cover   { from { clip-path:inset(0 100% 0 0); }        to { clip-path:inset(0 0 0 0); } }
@keyframes tr-wipe-open    { from { clip-path:inset(0 0 0 0); }           to { clip-path:inset(0 100% 0 0); } }
/* 中央「墨」印：盖住时淡入放大，揭开时淡出（章节级转场的仪式感锚点） */
#scene-transition .tr-seal {
  position:absolute; left:50%; top:50%; transform:translate(-50%,-50%) scale(.72);
  width:76px; height:76px; border-radius:50%;
  border:2px solid rgba(232,201,135,.85);
  box-shadow:0 0 24px rgba(232,201,135,.25), inset 0 0 18px rgba(232,201,135,.18);
  display:flex; align-items:center; justify-content:center;
  font-family:"STKaiti","KaiTi","华文楷体","楷体",serif; font-size:38px; color:#e9c987;
  text-shadow:0 0 12px rgba(232,201,135,.6); opacity:0;
}
#scene-transition.cover .tr-seal { animation:tr-seal-in 340ms ease-out forwards; }
#scene-transition.open  .tr-seal { animation:tr-seal-out 360ms ease-in forwards; }
@keyframes tr-seal-in  { from { opacity:0; transform:translate(-50%,-50%) scale(.72); } to { opacity:1; transform:translate(-50%,-50%) scale(1); } }
@keyframes tr-seal-out { from { opacity:1; transform:translate(-50%,-50%) scale(1); }  to { opacity:0; transform:translate(-50%,-50%) scale(1.12); } }

/* ============================================================
 * v177 P2-8：加载屏（进游戏时遮住转场，水墨印章 + 平滑进度）
 * ============================================================ */
.loading-screen {
  position: fixed; inset: 0; z-index: 310;                 /* 高于转场 z300，盖住全程 */
  display: flex; align-items: center; justify-content: center;
  background:
    radial-gradient(120% 90% at 50% 18%, #20203a 0%, #14141f 55%, #0d0d16 100%);
  opacity: 0; transition: opacity .4s ease;
}
.loading-screen.hidden { display: none; }
.loading-screen.on { opacity: 1; }
.loading-ink {                                            /* 缓慢漂移的水墨晕 */
  position: absolute; inset: -20%;
  background: radial-gradient(40% 40% at 30% 35%, rgba(80,90,140,.30), transparent 70%),
              radial-gradient(45% 45% at 72% 68%, rgba(120,96,60,.22), transparent 70%);
  filter: blur(8px); animation: ldg-drift 9s ease-in-out infinite alternate;
}
@keyframes ldg-drift { from { transform: translate(-2%, -1%) scale(1.02); } to { transform: translate(3%, 2%) scale(1.06); } }
.loading-core { position: relative; text-align: center; color: #f3e9d2; }
.loading-seal {                                          /* 壹 印章：呼吸 + 金晕 */
  width: 78px; height: 78px; margin: 0 auto 18px; border-radius: 50%;
  border: 2px solid rgba(232,201,135,.85);
  box-shadow: 0 0 26px rgba(232,201,135,.28), inset 0 0 18px rgba(232,201,135,.18);
  display: flex; align-items: center; justify-content: center;
  font-family: "STKaiti","KaiTi","华文楷体","楷体",serif; font-size: 40px; color: #e9c987;
  text-shadow: 0 0 12px rgba(232,201,135,.6);
  animation: ldg-seal 2.6s ease-in-out infinite;
}
@keyframes ldg-seal { 0%,100% { transform: scale(1); opacity:.9; } 50% { transform: scale(1.07); opacity:1; } }
.loading-title { font-family: "STKaiti","KaiTi","华文楷体","楷体",serif; font-size: 40px; letter-spacing: .32em; color: #f3e9d2; text-indent: .32em; }
.loading-sub { margin-top: 8px; font-size: 13px; letter-spacing: .18em; color: #b9ad8e; }
.loading-bar { margin: 26px auto 10px; width: 220px; height: 4px; border-radius: 4px; background: rgba(232,201,135,.18); overflow: hidden; }
.loading-bar i { display: block; height: 100%; width: 0%; border-radius: 4px;
  background: linear-gradient(90deg, #e9c987, #f3e9d2); box-shadow: 0 0 10px rgba(232,201,135,.5); transition: width .12s linear; }
.loading-pct { font-size: 13px; color: #cdbd95; font-variant-numeric: tabular-nums; }
.loading-tip { margin-top: 14px; font-size: 13px; letter-spacing: .12em; color: #9a9076; min-height: 18px; }

/* ============================================================
 * v177 P2-9：新手渐进引导（聚光环 + 文案气泡，用完即焚）
 * ============================================================ */
.coach-mark { position: fixed; inset: 0; z-index: 250; pointer-events: none; }   /* 点击穿透到游戏 */
.coach-ring {
  position: fixed; border: 2px solid #e9c987;
  box-shadow: 0 0 0 9999px rgba(10,10,18,.62), inset 0 0 14px rgba(232,201,135,.45);
  pointer-events: none; animation: coach-pulse 1.8s ease-in-out infinite;
}
@keyframes coach-pulse { 0%,100% { box-shadow: 0 0 0 9999px rgba(10,10,18,.62), inset 0 0 14px rgba(232,201,135,.45); }
  50% { box-shadow: 0 0 0 9999px rgba(10,10,18,.62), inset 0 0 22px rgba(232,201,135,.7); } }
.coach-bubble {
  position: fixed; max-width: 262px; pointer-events: auto;        /* 气泡可点 */
  background: rgba(20,20,31,.96); color: #f3e9d2; border: 1px solid rgba(232,201,135,.6);
  border-radius: 12px; padding: 12px 14px; box-shadow: 0 10px 34px rgba(0,0,0,.55);
  font-size: 14px; line-height: 1.55;
}
.coach-bubble p { margin: 0 0 10px; }
.coach-ok {
  display: inline-block; padding: 5px 16px; border-radius: 18px; cursor: pointer;
  background: linear-gradient(180deg, #e9c987, #cda85f); color: #2a2113; border: none;
  font-size: 13px; font-weight: 600; letter-spacing: .1em;
}
.coach-ok:active { transform: translateY(1px); }

/* v275：选槽弹层内容变多（备份行/找回/导入/网址提示），矮窗口下要能滚，不能把"取消"顶出屏幕 */
#slot-picker .menu-card { max-height: 633.6px; overflow-y: auto; scrollbar-width: thin;
  scrollbar-color: rgba(184,155,94,.55) rgba(20,22,34,.6); }
#slot-picker .menu-card::-webkit-scrollbar { width: 7px; }
#slot-picker .menu-card::-webkit-scrollbar-track { background: rgba(20,22,34,.6); border-radius: 3px; }
#slot-picker .menu-card::-webkit-scrollbar-thumb { background: rgba(184,155,94,.55); border-radius: 3px; }
#slot-picker .menu-card::-webkit-scrollbar-thumb:hover { background: rgba(210,178,110,.75); }

/* ========== v181 菜单 / 信物图鉴 精致化（分层渐变 + 金色高光轨 + 稀有度标签） ========== */
/* —— 面板：分层渐变 + 内高光 + 深投影 —— */
.menu-card {
  background: linear-gradient(165deg, #262a40 0%, #1c1f33 55%, #171930 100%);
  border: 1.5px solid rgba(184,155,94,.6);
  box-shadow: 0 20px 54px rgba(0,0,0,.6), 0 0 0 1px rgba(0,0,0,.35),
              inset 0 1px 0 rgba(255,226,168,.10), inset 0 0 34px rgba(0,0,0,.35);
}
/* —— 面板标题：两侧金色饰线 —— */
.menu-card h3 { color: #f0d68a; text-shadow: 0 1px 2px rgba(0,0,0,.5); }
.menu-card h3::before, .menu-card h3::after {
  content: ''; display: inline-block; width: 22px; height: 1px; vertical-align: middle;
  background: linear-gradient(90deg, transparent, #c9a35c); margin: 0 9px 4px;
}
.menu-card h3::after { background: linear-gradient(90deg, #c9a35c, transparent); }
/* —— 菜单项：左金色高光轨 + 按压反馈 + 导航右箭头 —— */
.m-item { position: relative; overflow: hidden;
  background: linear-gradient(180deg, rgba(48,51,76,.5), rgba(30,33,52,.5));
  border: 1px solid rgba(122,128,152,.32); border-radius: 10px;
  transition: background .12s, border-color .12s; }
.m-item::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: linear-gradient(180deg, #f0d68a, #b8893f); opacity: 0; transition: opacity .12s; }
.m-item:not(:disabled):active { background: linear-gradient(180deg, #3c4166, #2b2f4d); border-color: rgba(201,163,92,.5); }
.m-item:not(:disabled):active::before { opacity: 1; }
.m-item[data-page]:not([data-page="menu-root"]) { padding-right: 36px; }
.m-item[data-page]:not([data-page="menu-root"])::after {
  content: '›'; position: absolute; right: 14px; top: 50%; transform: translateY(-52%);
  color: #9aa0b5; font-size: 20px; line-height: 1; }
/* —— 信物/图鉴行：稀有度左轨 + 渐变卡 + 图标框 —— */
.inv-row { position: relative; overflow: hidden;
  background: linear-gradient(160deg, rgba(46,49,73,.55), rgba(27,29,46,.55));
  border: 1px solid rgba(122,128,152,.26); border-radius: 12px;
  transition: background .12s, border-color .12s; }
.inv-row::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: var(--rc, #6b5a35); }
.inv-row.r0 { --rc:#9aa0b5; } .inv-row.r1 { --rc:#5fb37a; }
.inv-row.r2 { --rc:#5b8fd6; } .inv-row.r3 { --rc:#ffb04d; }
.inv-row:not(.dim):active { border-color: rgba(201,163,92,.5); background: linear-gradient(160deg, #3a3f63, #2b2f4d); }
.inv-row.dim { opacity: .55; }
.inv-row.dim::before { opacity: .35; }
.inv-ico { border-radius: 10px;
  background: radial-gradient(circle at 50% 38%, rgba(64,68,98,.95), rgba(17,19,31,.95));
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.05); }
.inv-row.r2 .inv-ico { border-color: rgba(91,143,214,.5); box-shadow: inset 0 0 0 1px rgba(91,143,214,.4), 0 0 8px rgba(91,143,214,.18); }
.inv-row.r3 .inv-ico { border-color: rgba(255,176,77,.55); box-shadow: inset 0 0 0 1px rgba(255,176,77,.5), 0 0 10px rgba(255,176,77,.28); }
/* —— 稀有度标签 chip —— */
.inv-tag { display: inline-block; margin-left: 8px; padding: 1px 7px; font-size: 10px; line-height: 15px;
  letter-spacing: .08em; border-radius: 8px; vertical-align: 2px; font-weight: 600;
  color: #cfd4e2; background: rgba(255,255,255,.05); border: 1px solid rgba(154,160,181,.4); }
.inv-tag.rt1 { color: #a4e2ba; background: rgba(95,179,122,.12); border-color: rgba(95,179,122,.45); }
.inv-tag.rt2 { color: #aecdf2; background: rgba(91,143,214,.14); border-color: rgba(91,143,214,.5); }
.inv-tag.rt3 { color: #ffd79a; background: rgba(255,176,77,.16); border-color: rgba(255,176,77,.6);
  box-shadow: 0 0 8px rgba(255,176,77,.25); }
/* —— 背包页签：激活下划金线 —— */
.bag-tab { position: relative; overflow: hidden; transition: color .12s, border-color .12s; }
.bag-tab.on { color: #f0d68a; border-color: rgba(201,163,92,.6);
  background: linear-gradient(180deg, rgba(64,52,26,.55), rgba(40,34,20,.55)); }
.bag-tab.on::after { content: ''; position: absolute; left: 22%; right: 22%; bottom: 0; height: 2px;
  background: linear-gradient(90deg, transparent, #f0d68a, transparent); border-radius: 2px; }
/* —— 章节翻页：标题下饰线 + 按钮精致化 —— */
.col-pager-title { position: relative; padding-bottom: 5px; }
.col-pager-title::after { content: ''; position: absolute; left: 12%; right: 12%; bottom: 0; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(201,163,92,.65), transparent); }
.col-pager-btn { transition: background .12s, border-color .12s; color: #d9c9a0; }
.col-pager-btn:not(:disabled):active { background: rgba(201,163,92,.28); border-color: #c9a35c; }
/* —— 小节标题（异闻/隐藏）：两侧菱石 —— */
.col-sub::before, .col-sub::after { content: '◆'; font-size: 8px; color: #9a7c46; margin: 0 9px; vertical-align: 2px; }
/* —— 设置 toggle：精致化（状态文字仍由 JS 驱动） —— */
.set-row .t-btn { min-width: 84px; padding: 8px 0; border-radius: 18px;
  background: linear-gradient(180deg, rgba(48,51,76,.7), rgba(30,33,52,.7)); border: 1px solid rgba(122,128,152,.4); }
/* —— 传说格：呼吸微光（尊重减动效偏好） —— */
@keyframes cell-legend { 0%,100% { box-shadow: inset 0 0 0 1px rgba(255,176,77,.55), 0 0 12px rgba(255,176,77,.28); }
  50% { box-shadow: inset 0 0 0 1px rgba(255,176,77,.8), 0 0 20px rgba(255,176,77,.45); } }
.bag-cell.r3 { animation: cell-legend 2.6s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) { .bag-cell.r3 { animation: none; } }

/* ========== v183 P2-10/P2-11：HUD 动效 + 升级微光 ========== */
/* 掉血/掉蓝 红闪：fill 提亮饱和 + 外郭红光（.46s 自动收） */
.bar.hurt i { animation: hud-hurt-fill .46s ease; }
.bar.hurt { animation: hud-hurt-glow .46s ease; }
@keyframes hud-hurt-fill { 0%,100% { filter:none; } 30% { filter:brightness(1.7) saturate(2.4); } }
@keyframes hud-hurt-glow {
  0%,100% { box-shadow: inset 0 2px 3px rgba(0,0,0,.75), 0 1px 4px rgba(0,0,0,.5); }
  30% { box-shadow: inset 0 0 0 2px rgba(255,70,50,.95), 0 0 16px rgba(255,60,40,.75); }
}
/* 升级全屏微光：暖金径向晕开（低端机降级时不创建该层） */
.level-glow { position:fixed; inset:0; z-index:90; pointer-events:none;
  background: radial-gradient(circle at 50% 42%, rgba(255,230,150,.5), rgba(255,200,90,.16) 45%, transparent 70%);
  animation: level-glow-in 1.5s ease-out forwards; }
@keyframes level-glow-in { 0% { opacity:0; } 16% { opacity:1; } 100% { opacity:0; } }
@media (prefers-reduced-motion: reduce) {
  .level-glow { display:none; } .bar.hurt, .bar.hurt i { animation:none; }
}

/* v187 第三章：九尾虚影（jiuwei 地图）——大立绘覆盖 + 渐显入场；
 * wrapper 62x72 是迷你残影规格，九尾用 ch3-fox 放大（立绘脚底仍贴 rift 锚点） */
.ch3-fox { width:62px; height:72px; overflow:visible; }
.ch3-fox .jq-rift-echo { position:absolute; left:50%; bottom:6px; transform:translateX(-50%);
  width:300px; height:auto; max-height:340px; opacity:0; filter:saturate(.85) brightness(1.06);
  animation:ch3-fox-in 2.4s ease-out forwards; }
.ch3-fox-in .jq-rift-echo { animation:ch3-fox-in 2.4s ease-out forwards; }
@keyframes ch3-fox-in {
  0%   { opacity:0; transform:translateX(-50%) translateY(10px); }
  100% { opacity:.9; transform:translateX(-50%) translateY(0); }
}

/* v188 第三章·幻境巷氛围滤镜：底图与第一章同源（jiqu 定稿原样），梦幻感只走这一层——
 * 轻微提亮 + 金色柔光罩（径向渐变叠加，不碰底图色彩）；换图即摘（map.js load toggle） */
#map-camera.hj-dream::after { content:''; position:absolute; inset:0; pointer-events:none; z-index:5;
  background:radial-gradient(ellipse 70% 55% at 50% 42%, rgba(255,214,140,.16), rgba(255,190,110,.05) 55%, transparent 78%);
  mix-blend-mode:screen; }
#map-camera.hj-dream { filter:brightness(1.045) saturate(1.04); }

/* ========== v225 [T3]：成就徽章 + 章节回忆相册 ========== */
.ach-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(118px,1fr)); gap:8px; margin:6px 0 4px; }
.ach-chip { border:1px solid rgba(184,155,94,.28); border-radius:10px; padding:7px 8px;
  background:rgba(20,16,10,.42); display:flex; flex-direction:column; gap:2px; opacity:.5; }
.ach-chip b { font-size:13px; color:#cbbf9e; letter-spacing:.06em; }
.ach-chip i { font-style:normal; font-size:11px; color:#8d8264; }
.ach-chip.got { opacity:1; border-color:rgba(217,180,95,.75);
  background:linear-gradient(180deg, rgba(90,70,26,.55), rgba(30,24,12,.55));
  box-shadow:inset 0 0 0 1px rgba(255,220,140,.12), 0 2px 10px rgba(0,0,0,.35); }
.ach-chip.got b { color:#ffe9b0; }
.ach-chip.got i { color:#b9a878; }

/* 回忆相册浮层（章节结算屏“回忆相册”按钮） */
.album-overlay { position:fixed; inset:0; z-index:95; display:flex; align-items:center; justify-content:center;
  background:rgba(6,5,3,.74); }
.album-card { width:min(760px, 1177.6px); max-height:619.2px; overflow:auto; border-radius:14px; padding:18px 18px 14px;
  background:linear-gradient(180deg,#241c10,#14100a); border:1px solid rgba(184,155,94,.5);
  box-shadow:0 18px 50px rgba(0,0,0,.6); }
.album-card h3 { margin:0 0 12px; font-size:17px; color:#ffe9b0; letter-spacing:.2em; text-align:center; }
.album-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(180px,1fr)); gap:12px; }
.album-item { border:1px solid rgba(184,155,94,.3); border-radius:10px; overflow:hidden; background:#0f0c07; }
.album-item img { display:block; width:100%; height:170px; object-fit:contain;
  background:radial-gradient(circle at 50% 45%, #2a2314, #0d0b06); }
.album-item span { display:block; padding:6px 8px; font-size:12px; color:#c9bd9c; letter-spacing:.06em; }
.album-close { margin:14px auto 0; display:block; }

/* ========== v226：九尾战胜利 · 凝实白光 ========== */
/* 珂儿跟随精灵挂 .solidifying 一次：亮度上行 + 白光外溢（filter 不涉 transform，合"动效只用 rotate/translate"铁律） */
@keyframes keer-solid {
  0%   { filter:brightness(1); }
  28%  { filter:brightness(1.9) drop-shadow(0 0 16px rgba(255,247,222,.95)); }
  100% { filter:brightness(1); }
}
.fol-keer.solidifying { animation:keer-solid 1.2s ease-out; }
@media (prefers-reduced-motion: reduce) { .fol-keer.solidifying { animation:none; } }

/* ========== v235 必杀切屏演出（scenes/battle_cutin.js 驱动；街机式大招定格） ==========
 * 压暗 → 立绘切入（solo 单人 / duo 双人）→ 技能名书法大字 → 白闪收场。
 * 铁律遵守：动效只用 rotate/translate/单值 scale + filter/opacity；
 * 层挂 #screen-battle 内、pointer-events:none（不挡选目标委托）；
 * 低端机/减动效/?nocut=1 由 JS 整体跳过，不落到本层。 */
#battle-cutin { position:fixed; inset:0; z-index:150; pointer-events:none; display:none; overflow:hidden; }   /* v236：overflow 裁切滑入越界，根治"人物超出屏幕"观感 */
#battle-cutin.on { display:block; }
/* v309 蓄势态：情景动图还没 decode 完时，先只亮压暗幕 + 技能名。
 *   为什么要有这个态：语音必须和动画同一刻起跑（用户要求"跟语音同步"），
 *   而 6~7MB 的动图在手机上要几秒，干等就是黑屏、先跑动画又是一闪就没。
 *   这里给出"大招已经来了"的确定反馈，动画等图到位再整段开始。 */
#battle-cutin.wait, #battle-cutin.out { display:block; }
#battle-cutin.wait .cutin-dim { opacity:.92; }
#battle-cutin.wait .cutin-name { opacity:1; transform:translate(-50%,-50%); filter:drop-shadow(0 0 18px rgba(255,190,40,.6)) drop-shadow(0 3px 3px rgba(0,0,0,.9)); }
/* 压暗幕：中心稍亮的舞台感黑幕 */
.cutin-dim { position:absolute; inset:0; opacity:0;
  background:radial-gradient(ellipse 120% 100% at 50% 46%, rgba(8,10,20,.68) 0%, rgba(4,5,12,.92) 100%); }
#battle-cutin.on .cutin-dim { animation:cutin-dim-in .26s ease-out forwards; }
#battle-cutin.out .cutin-dim { animation:cutin-dim-out .18s ease-in forwards; }
@keyframes cutin-dim-in  { from { opacity:0; } to { opacity:1; } }
@keyframes cutin-dim-out { from { opacity:1; } to { opacity:0; } }
/* 速度线：斜向流光（repeating 渐变整体平移，亮→暗过渡） */
.cutin-speed { position:absolute; inset:-12%; opacity:0;
  background:repeating-linear-gradient(104deg,
    transparent 0 54px, rgba(255,240,205,.15) 54px 58px, transparent 58px 128px,
    rgba(205,228,255,.10) 128px 133px, transparent 133px 212px); }
#battle-cutin.on .cutin-speed { animation:cutin-speed .6s ease-out forwards; }
#battle-cutin.out .cutin-speed { animation:cutin-dim-out .18s ease-in forwards; }
@keyframes cutin-speed {
  0%   { opacity:0; transform:translateX(-7%); }
  22%  { opacity:1; }
  100% { opacity:.45; transform:translateX(7%); }
}
/* 立绘：底部锚定等比，入场=大幅斜切滑入+微旋转（duo 双人从左右两翼入画）
 * v237 实机截图批：负边距出血式构图翻车（样张手臂撑满画幅，贴边=断臂）——
 *   改为正边距内收 25.6px + 高度 74→460.8px，保证全身完整可见 */
.cutin-art { position:absolute; bottom:0; height:min(460.8px,1433.6px); max-width:768px; object-fit:contain;
  opacity:0; filter:drop-shadow(0 10px 28px rgba(0,0,0,.72)) drop-shadow(0 0 18px rgba(255,222,150,.18)); }
.cutin-art.art-l { left:38.4px; }
.cutin-art.art-r { right:44.8px; }
#battle-cutin.on .cutin-art.art-l { animation:cutin-in-l .34s cubic-bezier(.18,.75,.28,1) forwards; }
#battle-cutin.on .cutin-art.art-r { animation:cutin-in-r .34s cubic-bezier(.18,.75,.28,1) forwards; }
#battle-cutin.out .cutin-art { animation:cutin-dim-out .18s ease-in forwards; }
@keyframes cutin-in-l { from { opacity:0; transform:translateX(-588.8px) rotate(-7deg); } to { opacity:1; transform:none; } }
@keyframes cutin-in-r { from { opacity:0; transform:translateX(588.8px) rotate(7deg); } to { opacity:1; transform:none; } }
/* 单人构图：立绘收进左 1/3，与居中技能名错位（v236 高度再收一档） */
#battle-cutin.solo .cutin-art.art-l { left:64px; }
#battle-cutin.solo .cutin-art { height:min(460.8px,1382.4px); }
/* 技能名书法大字：全屏版金字楷体（词汇源自 .skill-callout），弹入+驻留辉光呼吸 */
.cutin-name {
  position:absolute; left:50%; top:34%; transform:translate(-50%,-50%);
  font-family:"STKaiti","KaiTi","华文楷体","楷体","STZhongsong",serif;
  font-size:min(204.8px,104px); font-weight:700; letter-spacing:.22em; text-indent:.22em; white-space:nowrap;
  background:linear-gradient(180deg,#fffbe8 10%,#ffe28a 40%,#f5a81b 68%,#b06a04 100%);
  -webkit-background-clip:text; background-clip:text;
  color:transparent; -webkit-text-fill-color:transparent;
  filter:drop-shadow(0 0 22px rgba(255,190,40,.75)) drop-shadow(0 3px 3px rgba(0,0,0,.9));
  opacity:0;
  /* v294【用户实机："技能文字消失的一瞬间，屏幕中间有个明显的白条"】
   *   根因：金色字靠 `background-clip:text` 抠出来，字本身是透明的。
   *   淡出（.out）时同一条 animation 属性被 cutin-dim-out 覆盖，
   *   第二行的 cutin-name-glow 随之被撤 → 合成层重建 → 那一帧 background-clip:text
   *   失效，整块 linear-gradient 当普通背景铺出来 = 一条近白(#fffbe8)的横条。
   *   will-change 让合成层提前建好、不在动画切换时重建；
   *   真正的兜底在下面 .out 那条：淡出期间直接掐掉背景、退回纯金色。 */
  will-change:opacity, transform; }
#battle-cutin.on .cutin-name {
  animation:cutin-name-in .5s .16s cubic-bezier(.2,.9,.3,1.2) forwards,
            cutin-name-glow 1.1s .6s ease-in-out infinite alternate;
}
/* v294：淡出这 0.18s 里**不许再有渐变背景**——背景-clip 一旦掉帧就是一条白条。
 *   掐掉 background 换纯金实色 + 固定 filter（冻结 glow 呼吸，免得动画被撤时亮度跳一档）。
 *   肉眼只看到"金字淡出"，和原来几乎没差；但结构上已经不可能再露出白块。 */
#battle-cutin.out .cutin-name {
  animation:cutin-dim-out .18s ease-in forwards;
  background-image:none;
  color:#ffe28a; -webkit-text-fill-color:#ffe28a;
  filter:drop-shadow(0 0 14px rgba(255,190,40,.5)) drop-shadow(0 3px 3px rgba(0,0,0,.9));
}
@keyframes cutin-name-in {
  0%   { opacity:0; transform:translate(-50%,-50%) scale(.42); }
  62%  { opacity:1; transform:translate(-50%,-50%) scale(1.12); }
  100% { opacity:1; transform:translate(-50%,-50%) scale(1); }
}
@keyframes cutin-name-glow {
  from { filter:drop-shadow(0 0 14px rgba(255,190,40,.5)) drop-shadow(0 3px 3px rgba(0,0,0,.9)); }
  to   { filter:drop-shadow(0 0 30px rgba(255,205,70,.95)) drop-shadow(0 3px 3px rgba(0,0,0,.9)); }
}
/* 白闪收场（爆闪后随整层淡出；与 #battle-flash 战斗开场白闪呼应） */
.cutin-flash { position:absolute; inset:0; background:#fff; opacity:0; }
#battle-cutin.out .cutin-flash { animation:cutin-flash-out .22s ease-out forwards; }
@keyframes cutin-flash-out { 0% { opacity:.92; } 100% { opacity:0; } }
/* ===== v257 街机版（.cine）：情景动图打底，不再叠立绘 =====
 * 硬切 → 集中线爆散 → 镜头急推 → 冲击波环 → 震屏 → 白闪反色 → 字劈开 → 顿帧 → 收
 * 总时长由 JS 注入 --cutin-dur（= 该技能喊招配音实测时长），动图与配音同起同收 */
.cutin-box { position:absolute; inset:0; }
#battle-cutin.cine .cutin-speed,
#battle-cutin.cine .cutin-art { display:none; }   /* 立绘退出：情景图本身就是主角 */

/* 情景动图：镜头急推 1.55→1.0（80ms hard stop），驻留期极缓续推到 1.045 防"死图" */
.cutin-scene { position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
  opacity:0; transform:scale(1.55); display:none;
  filter:contrast(1.26) brightness(.84) saturate(1.1); will-change:opacity, transform; }
#battle-cutin.cine .cutin-scene { display:block; }
#battle-cutin.cine.on .cutin-scene {
  animation:cutin-scene-punch 80ms cubic-bezier(.12,.9,.2,1) forwards,
            cutin-scene-drift var(--cutin-dur,2400ms) 80ms linear forwards; }
#battle-cutin.cine.out .cutin-scene { animation:cutin-dim-out .18s ease-in forwards; }
@keyframes cutin-scene-punch { from{ opacity:0; transform:scale(1.55); } to{ opacity:1; transform:scale(1); } }
@keyframes cutin-scene-drift { from{ transform:scale(1); } to{ transform:scale(1.045); } }

/* 压暗改暗角：中心留亮给动图，四周压到近黑。
 * 原 .92 平铺会把情景图整片压成黑片（预览实测需降到 0.12/0.52 这一档才看得见画面） */
#battle-cutin.cine .cutin-dim {
  background:radial-gradient(ellipse 74% 70% at 50% 46%,
    rgba(4,6,12,.12) 0%, rgba(3,4,10,.52) 62%, rgba(1,1,4,.95) 100%); }

/* 集中线：径向速度线双层错位爆散（矢量，任何分辨率都锐） */
#battle-cutin.cine .cutin-lines,
#battle-cutin.cine .cutin-lines2 { position:absolute; inset:-25%; opacity:0; transform:scale(.35); display:none; }
#battle-cutin.cine .cutin-lines, #battle-cutin.cine .cutin-lines2 { display:block; }
#battle-cutin.cine .cutin-lines {
  background:repeating-conic-gradient(from 0deg at 50% 46%,
    rgba(255,246,220,0) 0deg 1.05deg, rgba(255,246,220,.30) 1.05deg 1.85deg,
    rgba(255,246,220,0) 1.85deg 3.4deg);
  -webkit-mask-image:radial-gradient(circle at 50% 46%, transparent 9%, #000 36%, #000 68%, transparent 92%);
          mask-image:radial-gradient(circle at 50% 46%, transparent 9%, #000 36%, #000 68%, transparent 92%); }
#battle-cutin.cine .cutin-lines2 {
  background:repeating-conic-gradient(from 0deg at 50% 46%,
    rgba(255,176,64,0) 0deg 2.4deg, rgba(255,176,64,.20) 2.4deg 3.1deg,
    rgba(255,176,64,0) 3.1deg 6.2deg);
  -webkit-mask-image:radial-gradient(circle at 50% 46%, transparent 14%, #000 42%, transparent 88%);
          mask-image:radial-gradient(circle at 50% 46%, transparent 14%, #000 42%, transparent 88%); }
/* v310：集中线只做"爆散"，不许一直糊在画面上。
 *   用户实测"切屏好像被什么东西盖住了"——旧版 90ms 冲到 opacity:1 之后一直 forwards 挂着，
 *   整段 2~6 秒都有 30% 白条压在情景图上，图再清楚也看不出来。
 *   现在 12%/14% 处到峰值（≈原来的 90/120ms），随后 0.8s 内降到 10% 以下，只留一点余韵。 */
#battle-cutin.cine.on .cutin-lines  { animation:cutin-lines-in 800ms cubic-bezier(.15,.95,.25,1) forwards; }
#battle-cutin.cine.on .cutin-lines2 { animation:cutin-lines-in2 900ms cubic-bezier(.15,.95,.25,1) forwards; }
#battle-cutin.cine.out .cutin-lines,
#battle-cutin.cine.out .cutin-lines2 { animation:cutin-dim-out .16s ease-in forwards; }
@keyframes cutin-lines-in  { 0%{ opacity:0; transform:scale(.35) rotate(-7deg); }
                             12%{ opacity:1; transform:scale(1) rotate(0); }
                             100%{ opacity:.10; transform:scale(1.04) rotate(0); } }
@keyframes cutin-lines-in2 { 0%{ opacity:0; transform:scale(.5) rotate(9deg); }
                             14%{ opacity:.9; transform:scale(1) rotate(3deg); }
                             100%{ opacity:.07; transform:scale(1.05) rotate(3deg); } }

/* 冲击波环：起手炸开一圈 */
#battle-cutin.cine .cutin-ring { display:block; }
.cutin-ring { position:absolute; left:50%; top:46%; width:78%; aspect-ratio:1;
  margin:-39% 0 0 -39%; border-radius:50%; opacity:0; display:none;
  border:2px solid rgba(255,238,196,.85);
  box-shadow:0 0 26px rgba(255,214,130,.7), inset 0 0 26px rgba(255,214,130,.45); }
#battle-cutin.cine.on .cutin-ring { animation:cutin-ring 300ms 24ms cubic-bezier(.1,.85,.2,1) forwards; }
@keyframes cutin-ring {
  0%  { opacity:0; transform:scale(.12); }
  14% { opacity:.95; }
  100%{ opacity:0; transform:scale(1.7); } }

/* 震屏：只动 translate/rotate（守项目铁律），带 1.03 底缩放避免露出边缘 */
#battle-cutin.cine.on .cutin-box { animation:cutin-shake 170ms 30ms linear; }
@keyframes cutin-shake {
  0%  { transform:translate(0,0) scale(1.03); }
  10% { transform:translate(-10px,7px) scale(1.03) rotate(-.55deg); }
  24% { transform:translate(8px,-6px) scale(1.03) rotate(.45deg); }
  40% { transform:translate(-6px,3px) scale(1.03); }
  56% { transform:translate(4px,-2px) scale(1.03); }
  72% { transform:translate(-2px,1px) scale(1.03); }
  100%{ transform:translate(0,0) scale(1.03); } }

/* 反色闪（difference 伪负片，1~2 帧）——与收场白闪分开两个层 */
.cutin-invert { position:absolute; inset:0; background:#fff; opacity:0; display:none;
  mix-blend-mode:difference; pointer-events:none; }
#battle-cutin.cine .cutin-invert { display:block; }
#battle-cutin.cine.on .cutin-invert { animation:cutin-invert 80ms 104ms linear; }
@keyframes cutin-invert { 0%{ opacity:0; } 18%{ opacity:.6; } 34%{ opacity:.6; } 100%{ opacity:0; } }

/* 技能名：横向劈开 + 斜切回正 + 红青色散残影（覆盖默认的 scale 弹入） */
#battle-cutin.cine .cutin-name { top:30%; font-size:min(204.8px,140px); letter-spacing:.16em; text-indent:.16em; }
#battle-cutin.cine.on .cutin-name {
  animation:cutin-name-slam 120ms 118ms cubic-bezier(.5,0,.15,1) forwards,
            cutin-name-glow2 1.1s 340ms ease-in-out infinite alternate; }
@keyframes cutin-name-slam {
  0%  { opacity:0; transform:translate(-50%,-50%) scaleX(.18) skewX(-18deg); }
  26% { opacity:1; transform:translate(-50%,-50%) scaleX(1.14) skewX(3deg); }
  52% { opacity:1; transform:translate(-50%,-50%) scaleX(.985) skewX(-1deg); }
  100%{ opacity:1; transform:translate(-50%,-50%) scaleX(1) skewX(0); } }
@keyframes cutin-name-glow2 {
  from{ filter:drop-shadow(-2px 0 rgba(255,64,64,.45)) drop-shadow(2px 0 rgba(64,196,255,.45))
                  drop-shadow(0 0 18px rgba(255,190,40,.65)) drop-shadow(0 3px 3px rgba(0,0,0,.9)); }
  to  { filter:drop-shadow(-3px 0 rgba(255,64,64,.6)) drop-shadow(3px 0 rgba(64,196,255,.6))
                  drop-shadow(0 0 34px rgba(255,210,80,.95)) drop-shadow(0 3px 3px rgba(0,0,0,.9)); } }

/* 短版（同技能重复施放）：仅名字+白闪 ≈0.6s——防疲劳 */
#battle-cutin.short .cutin-speed, #battle-cutin.short .cutin-art { display:none; }
#battle-cutin.short .cutin-dim { background:rgba(4,5,12,.74); }
#battle-cutin.short.on .cutin-name { animation-delay:.04s; }
/* Boss 开场（.boss）：无速度线、立绘居中缓推（scale 1.16→1）、名号赤金——威压构图 */
#battle-cutin.boss .cutin-speed { display:none; }
#battle-cutin.boss .cutin-art.art-r { display:none; }
#battle-cutin.boss .cutin-art { left:50%; right:auto; height:min(504px,1408px);
  filter:drop-shadow(0 14px 34px rgba(0,0,0,.82)) drop-shadow(0 0 26px rgba(255,120,60,.22)); }
#battle-cutin.boss.on .cutin-art { animation:cutin-in-boss .55s cubic-bezier(.16,.7,.3,1) forwards; }
@keyframes cutin-in-boss {
  from { opacity:0; transform:translate(-50%,21.6px) scale(1.16); }
  to   { opacity:1; transform:translate(-50%,0) scale(1); }
}
#battle-cutin.boss .cutin-name { top:30%;
  background:linear-gradient(180deg,#fff6ee 8%,#ffc27a 38%,#ee5a1e 66%,#7c2604 100%);
  -webkit-background-clip:text; background-clip:text; }

/* ---- v235 打击感：重档震屏 / 顿帧 / Boss 二阶段暗角 ---- */
#battle-stage.shake-heavy { animation:stage-shake-heavy .38s linear; }
@keyframes stage-shake-heavy {
  0%,100% { transform:none; }
  12% { transform:translate(calc(var(--shk-h,9px) * -1), calc(var(--shk-h,9px) * .44)); }
  28% { transform:translate(calc(var(--shk-h,9px) * .89), calc(var(--shk-h,9px) * -.55)); }
  44% { transform:translate(calc(var(--shk-h,9px) * -.78), calc(var(--shk-h,9px) * .33)); }
  60% { transform:translate(calc(var(--shk-h,9px) * .67), calc(var(--shk-h,9px) * -.33)); }
  78% { transform:translate(calc(var(--shk-h,9px) * -.44), calc(var(--shk-h,9px) * .22)); }
  92% { transform:translate(calc(var(--shk-h,9px) * .33), calc(var(--shk-h,9px) * .11)); }
}
/* 顿帧（hit-stop）：命中瞬间全场动画冻结一拍（JS 挂 .hitstop 80~110ms） */
#battle-stage.hitstop, #battle-stage.hitstop * { animation-play-state:paused !important; }
/* v236 镜头推冲（zoom punch）：必杀命中舞台等比猛推再弹回（单值 scale 铁律；--punch 可调；v248 快照 1.041） */
#battle-stage.punch { animation:stage-punch .3s cubic-bezier(.2,.8,.3,1); }
@keyframes stage-punch {
  0%   { transform:scale(1); }
  28%  { transform:scale(var(--punch,1.041)); }
  100% { transform:scale(1); }
}
/* Boss 二阶段红暗角脉冲（body 级固定层，bossVignette() 追加，自删） */
.boss-vignette { position:fixed; inset:0; z-index:120; pointer-events:none; opacity:0;
  background:radial-gradient(ellipse at 50% 50%, transparent 42%, rgba(140,12,26,.5) 100%);
  animation:vignette-pulse .95s ease-out forwards; }
@keyframes vignette-pulse { 0% { opacity:0; } 22% { opacity:1; } 100% { opacity:0; } }

/* ---- v235/v236 合击特效（CSS 合成 v1；后续可换 8 帧雪碧图，类名不变零改代码） ----
 * v236 实机反馈批：斩光从 7px 加粗到 13px + 光晕翻倍（原版在震屏白闪里弱到"啥也没有"） */
/* 斩梦：两道交叉斩光（X 轨迹）——双人交错的视觉落款；.fx-echo=第二击镜像延迟版 */
.fx-heji-zhanmeng { width:150px; height:150px; margin-left:-75px; margin-top:-75px; }
.fx-heji-zhanmeng::before, .fx-heji-zhanmeng::after {
  content:''; position:absolute; left:50%; top:50%; width:130%; height:13px; margin:-6.5px 0 0 -65%;
  background:linear-gradient(90deg, transparent, #fff 26%, #ffe9a8 50%, #fff 74%, transparent);
  border-radius:6px; filter:drop-shadow(0 0 14px rgba(255,220,140,.95)) drop-shadow(0 0 4px #fff);
  transform-origin:50% 50%; opacity:0;
}
.fx-heji-zhanmeng::before { animation:heji-slash-a .5s cubic-bezier(.15,.8,.3,1) forwards; }
.fx-heji-zhanmeng::after  { animation:heji-slash-b .5s .07s cubic-bezier(.15,.8,.3,1) forwards; }
.fx-heji-zhanmeng.fx-echo::before { animation:heji-slash-b .5s .06s cubic-bezier(.15,.8,.3,1) forwards; }   /* 镜像第二击 */
.fx-heji-zhanmeng.fx-echo::after  { animation:heji-slash-a .5s .14s cubic-bezier(.15,.8,.3,1) forwards; }
@keyframes heji-slash-a {
  0%   { opacity:0; transform:rotate(-34deg) scaleX(.1); }
  30%  { opacity:1; transform:rotate(-34deg) scaleX(1.08); }
  100% { opacity:0; transform:rotate(-34deg) scaleX(1.22); }
}
@keyframes heji-slash-b {
  0%   { opacity:0; transform:rotate(30deg) scaleX(.1); }
  30%  { opacity:1; transform:rotate(30deg) scaleX(1.08); }
  100% { opacity:0; transform:rotate(30deg) scaleX(1.22); }
}
/* 镇魂：钟声波纹逐圈扩散（v236 边框 3→5px+内外双辉光；舞台级大波纹见 .zhenhun-wave） */
.fx-heji-zhenhun { width:170px; height:170px; margin-left:-85px; margin-top:-85px; }
.fx-heji-zhenhun::before, .fx-heji-zhenhun::after {
  content:''; position:absolute; inset:0; border-radius:50%;
  border:5px solid rgba(255,232,170,.95);
  box-shadow:0 0 18px rgba(255,220,140,.85), inset 0 0 18px rgba(255,220,140,.55);
  opacity:0; transform:scale(.2);
}
.fx-heji-zhenhun::before { animation:heji-ring .8s cubic-bezier(.2,.7,.35,1) forwards; }
.fx-heji-zhenhun::after  { animation:heji-ring .8s .22s cubic-bezier(.2,.7,.35,1) forwards; }
@keyframes heji-ring {
  0%   { opacity:0; transform:scale(.2); }
  18%  { opacity:1; }
  100% { opacity:0; transform:scale(1.65); }
}
/* 镇魂·舞台级全屏金波纹（comboWave 挂 #battle-stage，三圈逐圈扫场） */
.zhenhun-wave { position:absolute; inset:0; z-index:8; pointer-events:none; }
.zhenhun-wave i { position:absolute; left:50%; top:58%; width:70px; height:70px; margin:-35px 0 0 -35px;
  border-radius:50%; border:4px solid rgba(255,232,170,.9);
  box-shadow:0 0 20px rgba(255,220,140,.85), inset 0 0 20px rgba(255,220,140,.5);
  opacity:0; animation:zhenhun-ring 1.15s cubic-bezier(.15,.7,.3,1) forwards; }
.zhenhun-wave i:nth-child(2) { animation-delay:.18s; }
.zhenhun-wave i:nth-child(3) { animation-delay:.36s; }
@keyframes zhenhun-ring {
  0%   { opacity:0; transform:scale(.3); }
  12%  { opacity:1; }
  100% { opacity:0; transform:scale(17); }   /* 70px → 1190px，波纹盖过全场 */
}
/* 回梦：暖光晕（光雨丝由 battle_ui.spawnRain 逐条生成 .fx-rain） */
.fx-heji-huimeng { width:190px; height:190px; margin-left:-95px; margin-top:-95px; border-radius:50%;
  background:radial-gradient(circle at 50% 46%, rgba(255,246,214,.95) 0%, rgba(255,226,160,.5) 34%, transparent 68%);
  animation:heji-glow .95s ease-out forwards; }
@keyframes heji-glow { 0% { opacity:0; transform:scale(.4); } 26% { opacity:1; } 100% { opacity:0; transform:scale(1.3); } }
/* 光雨丝：自上而下坠落淡出（--dx/--dy/--dd 由 JS 随机化） */
.bunit .fx-rain { position:absolute; top:-120px; width:3px; height:26px; border-radius:2px;
  background:linear-gradient(180deg, transparent, #fff6d8);
  box-shadow:0 0 6px rgba(255,235,170,.85); opacity:0; pointer-events:none;
  animation:fx-rainfall var(--dd,.8s) ease-in forwards; }
@keyframes fx-rainfall {
  0%   { opacity:0; transform:translate(0,0); }
  15%  { opacity:1; }
  100% { opacity:0; transform:translate(var(--dx,0px), var(--dy,180px)); }
}
/* 减动效兜底（enabled() 已拦，此处为 CSS 层双保险：切屏只留淡入淡出） */
@media (prefers-reduced-motion: reduce) {
  #battle-cutin.on .cutin-art, #battle-cutin.boss.on .cutin-art,
  #battle-cutin.on .cutin-name { animation:cutin-dim-in .3s forwards; }
}

/* ========== v246 街机三件套：开场"战！" / K.O."胜"字 / 连击演出 ========== */
/* 开场"战！"：小怪局首包砸屏（0.78s）——Boss 局走 .boss 威压开场，两者形成反差节奏 */
#battle-cutin.war .cutin-speed, #battle-cutin.war .cutin-art { display:none; }
#battle-cutin.war .cutin-name {
  top:44%; font-size:min(384px,210px); letter-spacing:.06em; text-indent:.06em;
  background:linear-gradient(180deg,#fff6ee 6%,#ffd27a 38%,#e85520 68%,#7c2604 100%);
  -webkit-background-clip:text; background-clip:text;
}
#battle-cutin.war.on .cutin-name { animation:war-slam .78s cubic-bezier(.2,.9,.25,1) forwards; }
@keyframes war-slam {
  0%   { opacity:0; transform:translate(-50%,-50%) scale(2.2) rotate(-5deg); }
  22%  { opacity:1; transform:translate(-50%,-50%) scale(1) rotate(-2deg); }
  75%  { opacity:1; }
  100% { opacity:0; transform:translate(-50%,-50%) scale(1.08) rotate(-2deg); }
}
/* K.O. 终结一击："胜"字大字砸屏（body 级，不受 #battle-stage.hitstop 冻结） */
.ko-overlay { position:fixed; inset:0; z-index:140; pointer-events:none;
  display:flex; align-items:center; justify-content:center; }
.ko-overlay span {
  font-family:"STKaiti","KaiTi","华文楷体","楷体",serif;
  font-size:min(460.8px,260px); font-weight:700; letter-spacing:.05em;
  background:linear-gradient(180deg,#fffbe8 10%,#ffe28a 40%,#f5a81b 68%,#b06a04 100%);
  -webkit-background-clip:text; background-clip:text;
  color:transparent; -webkit-text-fill-color:transparent;
  filter:drop-shadow(0 0 26px rgba(255,190,40,.8)) drop-shadow(0 4px 4px rgba(0,0,0,.9));
  opacity:0; animation:ko-in 1.15s cubic-bezier(.2,.9,.25,1) forwards;
}
@keyframes ko-in {
  0%   { opacity:0; transform:scale(2.4) rotate(-6deg); }
  16%  { opacity:1; transform:scale(1) rotate(-3deg); }
  72%  { opacity:1; }
  100% { opacity:0; transform:scale(1.07) rotate(-3deg); }
}
/* 连击里程碑闪字：×5/×10… 屏幕上沿闪现 */
.combo-flash { position:fixed; top:16%; left:50%; transform:translateX(-50%); z-index:130;
  pointer-events:none; opacity:0;
  font-family:"STKaiti","KaiTi","华文楷体","楷体",serif;
  font-size:min(115.2px,54px); font-weight:700; letter-spacing:.18em;
  background:linear-gradient(180deg,#fff7cf 8%,#ffd94e 44%,#f5821b 100%);
  -webkit-background-clip:text; background-clip:text;
  color:transparent; -webkit-text-fill-color:transparent;
  filter:drop-shadow(0 0 12px rgba(255,180,50,.9)) drop-shadow(0 2px 2px rgba(0,0,0,.85));
  animation:combo-flash-in .85s cubic-bezier(.2,.9,.3,1) forwards; }
@keyframes combo-flash-in {
  0%   { opacity:0; transform:translateX(-50%) scale(.5); }
  22%  { opacity:1; transform:translateX(-50%) scale(1.12); }
  38%  { transform:translateX(-50%) scale(1); }
  100% { opacity:0; transform:translateX(-50%) translateY(-18px) scale(1); }
}
/* 连击徽章 ≥5 层：烈金泛红（字号由 JS 随层数放大） */
.bdmg-combo.hot {
  color:#ffab52;
  text-shadow:0 0 10px rgba(255,140,40,.95), 0 0 22px rgba(255,90,20,.6), 1px 1px 0 #000, -1px -1px 0 #000;
}

/* ---------- v317：首次打开资源下载进度条（标题页，SW 预缓存进度） ----------
 * 挂在 #screen-title 内、title-foot 上方；JS 收到 SW 的 PRECACHE_PROGRESS 时移除 .hidden，
 * 装完（done==total）再隐藏。风格沿用 .loading-bar 的金色渐变。 */
.dl-progress {
  position:absolute; left:50%; transform:translateX(-50%);
  bottom:56px; z-index:5;
  display:flex; flex-direction:column; align-items:center; gap:8px;
  width:min(896px, 300px);
}
.dl-progress-txt { font-size:13px; letter-spacing:.18em; color:#b9ad8e; }
.dl-progress-bar { width:100%; height:4px; border-radius:4px; background:rgba(232,201,135,.18); overflow:hidden; }
.dl-progress-bar i { display:block; height:100%; width:0%; border-radius:4px;
  background:linear-gradient(90deg,#e9c987,#f3e9d2); box-shadow:0 0 10px rgba(232,201,135,.5); transition:width .15s linear; }
.dl-progress-pct { font-size:12px; color:#cdbd95; font-variant-numeric:tabular-nums; }
