/* ============================================================================
   KICKBACK（飞人对决）· 外壳样式 v3（入场动画 + 电影感主菜单）
   设计权威：/Users/fengzeyuan/Documents/小球对决视频/DESIGN-FRONTEND.md
   判定口径：~/.dsh/AGENTS.md SHARED:UI-DESIGN（零可见描边 / 填充层级 / 4 倍数间距）
   本文件口径：
     1. 全文只有一条描边清零声明（WebKit 表单控件与对话框的 UA 默认边框），
        见下方「唯一清零声明」；其余任何可见线、分隔线、卡片外框一律没有。
     2. 层级只由填充明度 + 留白表达：--bg → --surface → --fill → --fill-hover。
     3. 字号只用 11/13/16/22；品牌 wordmark（#intro-title / home 态 #overlay-title）
        是唯一例外，允许 clamp() 大字号（CONTRACT §7.5.1）。
     4. :root 之外不写字面颜色，一律 var()/color-mix()。
   v3 编排：
     - #intro：fixed 纯黑黑幕 + KICKBACK 字标砸落（JS 加 .is-slam/.is-settle/.is-fading）；
     - #overlay.home-mode：菜单期 fixed 全屏遮罩，左侧 linear-gradient 暗化；
     - .overlay-card 默认仍是居中共用卡片（difficulty/volume/pause/round/match）；
     - #overlay.home-mode.start-mode .overlay-card：全屏电影感菜单（无卡片背景）；
     - body.menu-open：隐藏顶栏/HUD/底部提示，画布重度失焦；
     - 难度/音量等子页保持居中卡片与 v2 文案。
   ============================================================================ */

/* ---------- 1. 令牌（CONTRACT §9 / 设计文档 §3，唯一权威） ---------- */
:root{
  --bg:#0b0b0d;
  --surface:#121214;
  --fill:rgba(255,255,255,.06);
  --fill-strong:rgba(255,255,255,.10);
  --fill-hover:rgba(255,255,255,.14);
  --float:#1c1c1f;
  --text:#f5f5f7;
  --text-2:#a1a1a6;
  --text-3:#8c8c90;
  --accent:#f5f5f7;
  --accent-ink:#131315;
  --focus:#4c9dff;
  --danger:#ff6b6b;
  --p1:#ff6b5a;
  --p2:#4cc3ff;
  --p3:#ffd60a;
  --campaign-gold:#ffd36a;
  --p4:#b07cff;
  --font:"KICKBACK Smiley",-apple-system,BlinkMacSystemFont,"PingFang SC","Microsoft YaHei",sans-serif;
  --brand-font:-apple-system,BlinkMacSystemFont,"PingFang SC","Microsoft YaHei",sans-serif;
  --topbar-h:56px;
  --hud-h:40px;
  --footer-h:32px;
  /* 一屏收纳：顶栏 56 + 主体上下内边距 32 + HUD 40 + 行间 16 + 舞台内边距 16 + 页脚 32 + 余量 4。
     舞台宽度 = 剩余高度按 16:9 反推，再与主体可用宽度取小值。 */
  --stage-width:min(100%,calc((100dvh - 196px) * 16 / 9 + 16px));
  font-family:var(--font);
  font-size:13px;
  line-height:1.5;
  background:var(--bg);
  color:var(--text);
  color-scheme:dark;
  -webkit-font-smoothing:antialiased;
}
:root:lang(en){--font:"KICKBACK Space","KICKBACK Smiley",-apple-system,BlinkMacSystemFont,"PingFang SC","Microsoft YaHei",sans-serif}

/* ---------- 2. 基础 ---------- */
*{box-sizing:border-box}
html{height:100%}
body{
  height:100vh;
  height:100dvh;
  margin:0;
  display:flex;
  flex-direction:column;
  overflow:hidden;
  background:var(--bg);
  color:var(--text);
  font-family:var(--font);
  font-size:13px;
  line-height:1.5;
  -webkit-font-smoothing:antialiased;
}
h1,h2,p{margin:0}
button{
  -webkit-appearance:none;
  appearance:none;
  margin:0;
  padding:0;
  border-radius:8px;
  background:none;
  color:inherit;
  font:inherit;
  cursor:pointer;
}
[hidden]{display:none!important}
.sr-only{
  position:absolute;
  width:1px;
  height:1px;
  overflow:hidden;
  clip-path:inset(50%);
  white-space:nowrap;
}

/* ── 全文唯一一条描边声明（SHARED:UI-DESIGN 第 1 条 / 设计文档 §3.2）──
   WebKit 的 UA 样式给 input/select/button/dialog 带真实边框，appearance:none
   清不掉；只此一条，没有颜色与状态语义，仅做清零。 */
input,select,button,dialog{border:0}

/* 聚焦指示只用 box-shadow 焦点环（3px 展开）；这里同时清掉 UA 默认轮廓，
   避免焦点态出现第二条线。outline 仅出现在 :focus-visible 内。 */
button:focus-visible,input:focus-visible{
  outline:none;
  box-shadow:none;
  filter:brightness(1.12);
}

/* ---------- 2a. 回合耍帅文字（斩杀时刻 / 庆祝演出） ---------- */
.celebration{
  position:fixed;
  left:50%;
  top:58%;
  transform:translate(-50%,-50%);
  z-index:8;
  max-width:min(720px,calc(100% - 64px));
  padding:0;
  font-size:22px;
  font-weight:600;
  line-height:1.5;
  color:var(--text);
  text-align:center;
  text-shadow:0 2px 18px color-mix(in srgb,var(--bg) 80%,transparent);
  pointer-events:none;
}
.celebration.is-shown{animation:taunt-pop 320ms cubic-bezier(.2,.8,.2,1) both, taunt-shake 900ms ease-in-out 320ms 1}
@keyframes taunt-pop{
  0%{opacity:0;transform:translate(-50%,-50%) scale(.9)}
  100%{opacity:1;transform:translate(-50%,-50%) scale(1)}
}
/* 局中赛点回合的双方狠话：场内字幕，自动逐字显示；不挡操作。 */
.exchange{
  position:fixed;
  left:50%;
  top:46%;
  transform:translate(-50%,-50%);
  z-index:9;
  width:min(520px,calc(100% - 32px));
  text-align:center;
  overflow-wrap:anywhere;
  pointer-events:none;
  color:var(--text);
  opacity:0;
  transition:opacity 180ms ease;
  text-shadow:0 2px 18px color-mix(in srgb,var(--bg) 80%,transparent);
}
.exchange.is-visible{opacity:1}
.ghost-exchange{
  position:fixed;
  inset:0;
  z-index:9;
  pointer-events:none;
}
.ghost-exchange[hidden]{display:none}
.ghost-line{
  position:absolute;
  transform:translate(-50%,-100%);
  width:min(260px,calc(100vw - 32px));
  text-align:center;
  overflow-wrap:anywhere;
  color:var(--text);
  opacity:0;
  transition:opacity 180ms ease;
  text-shadow:0 2px 18px color-mix(in srgb,var(--bg) 80%,transparent);
}
.ghost-line.is-visible{opacity:1}
.ghost-speaker{
  margin:0 0 4px;
  color:var(--text-2);
  font-size:13px;
  font-weight:600;
  line-height:1.5;
}
.ghost-text{
  margin:0;
  font-size:16px;
  font-weight:600;
  line-height:1.5;
}

.exchange[hidden]{display:none}
.exchange-speaker{
  margin:0 0 4px;
  color:var(--text-2);
  font-size:13px;
  font-weight:600;
  line-height:1.5;
}
.exchange-text{
  margin:0;
  font-size:22px;
  font-weight:600;
  line-height:1.5;
  white-space:pre-wrap;
}
@media (max-width:520px){
  .exchange{width:calc(100% - 32px)}
  .exchange-text{font-size:16px}
}

@keyframes taunt-shake{
  0%,100%{transform:translate(-50%,-50%) rotate(0deg)}
  12%{transform:translate(calc(-50% - 1.2px),calc(-50% + 0.6px)) rotate(-.35deg)}
  26%{transform:translate(calc(-50% + 1.2px),calc(-50% - 0.6px)) rotate(.35deg)}
  40%{transform:translate(calc(-50% - 0.9px),calc(-50%)) rotate(-.25deg)}
  58%{transform:translate(calc(-50% + 0.9px),calc(-50%)) rotate(.25deg)}
  76%{transform:translate(-50%,-50%) rotate(0deg)}
}

/* ---------- 2b. 界面切换过渡层（渐暗 → 新界面淡入，各 1000ms） ---------- */
.screen-fade{
  position:fixed;
  inset:0;
  z-index:90;
  background:var(--bg);
  opacity:0;
  pointer-events:none;
  transition:opacity 1000ms ease;
}
.screen-fade.is-dark{opacity:1;pointer-events:auto}
.screen-fade.is-quick{transition-duration:300ms}

/* ---------- 3. 入场动画（v4.3）：纯黑 → 空屏 → 砸落 → 落地（bang+灰尘）→ 渐暗 → 主菜单淡入 ---------- */
#intro{
  position:fixed;
  inset:0;
  z-index:100;
  display:grid;
  place-items:center;
  overflow:hidden;
  background:var(--bg);
  opacity:1;
  transition:opacity 520ms ease, background 520ms ease;
}
#intro{--intro-size:clamp(64px,16vw,220px)}
#intro.is-fading{opacity:0;transition:opacity 1000ms ease}
/* 落地灰尘：标题底部中线的锚点；圆点为 color-mix 淡色、无描边，扩散后渐隐。 */
.intro-dust{
  position:absolute;
  left:50%;
  top:calc(50% + var(--intro-size) * .4);
  width:0;
  height:0;
  pointer-events:none;
}
.intro-dust-puff{
  position:absolute;
  left:0;
  top:0;
  width:var(--s);
  height:var(--s);
  margin-left:calc(var(--s) * -.5);
  margin-top:calc(var(--s) * -.5);
  border-radius:50%;
  background:color-mix(in srgb,var(--text) 26%,transparent);
  filter:blur(5px);
  opacity:0;
  animation:intro-dust 1100ms ease-out forwards;
}
@keyframes intro-dust{
  0%{opacity:0;transform:translate(calc(var(--x) * var(--intro-size)),0) scale(.6)}
  18%{opacity:.75}
  100%{opacity:0;transform:translate(calc((var(--x) + var(--dx)) * var(--intro-size)),var(--dy)) scale(2.4)}
}
/* 衔接阶段：黑幕淡出，菜单标题从画面中心“飞”到左侧 wordmark 位置（JS 测量 morph）。 */
#intro-title{
  opacity:0;
  transform:none;
  font-family:var(--brand-font);
  font-size:var(--intro-size);
  font-weight:700;
  line-height:1.5;
  letter-spacing:-.04em;
  color:var(--text);
  white-space:nowrap;
  will-change:transform,opacity,filter;
}
/* 空屏阶段：屏幕全黑、什么都不出现。 */
#intro.is-empty #intro-title{opacity:0}
/* 砸落段：标题从斜上方快速砸到画面正中（750ms，结束瞬间落地）。 */
#intro.is-slam #intro-title{opacity:1;animation:intro-slam 750ms cubic-bezier(.45,0,.8,.35) both}
/* 砸落回弹/停留期间必须保持可见；震动以字标底部为支点，像砸在地上后的回弹。 */
#intro.is-impact #intro-title{opacity:1;transform-origin:50% 100%;animation:intro-impact 220ms cubic-bezier(.2,.8,.2,1) both}
/* 渐暗阶段：字标淡出，整屏暗下来（落地 1s 后，1000ms）。 */
#intro.is-dim #intro-title{opacity:0;transition:opacity 1000ms ease}
@keyframes intro-slam{
  0%{opacity:0;transform:translate(-58%,-138%) rotate(-14deg) scale(1.45);filter:blur(6px)}
  14%{opacity:1}
  /* 100% 才是真正触地帧：不再在 74% 提前压到地面又回弹，否则视觉触地会比
     animationend / 落地音早约 195ms（用户口径：声音和震动对，和砸落不对）。 */
  100%{transform:translate(0,0) rotate(0deg) scale(1);filter:blur(0)}
}
@keyframes intro-impact{
  0%{transform:translate(0,0) rotate(0deg) scale(1)}
  /* 先向下压一下（scaleY < 1），再左右回摆；比原来的 3.5% 缩放更明显。 */
  10%{transform:translate(-1.6%,1.4%) rotate(-1.2deg) scaleX(1.035) scaleY(.965)}
  28%{transform:translate(1.5%,-1.8%) rotate(1deg) scale(1.045)}
  46%{transform:translate(-1.1%,.9%) rotate(-.7deg) scale(.985)}
  64%{transform:translate(.7%,-.6%) rotate(.45deg) scale(1.015)}
  80%{transform:translate(-.35%,.25%) rotate(-.2deg) scale(.995)}
  92%{transform:translate(.12%,-.08%) rotate(.08deg) scale(1.002)}
  100%{transform:translate(0,0) rotate(0deg) scale(1)}
}

/* ---------- 4. 顶栏：已删除；只保留悬浮暂停按钮 ---------- */
#topbar{
  position:fixed;
  inset:0 0 auto 0;
  height:0;
  padding:0;
  background:none;
  -webkit-backdrop-filter:none;
  backdrop-filter:none;
  pointer-events:none;
  z-index:40;
}
#brand{display:none}
.topbar-actions{
  position:fixed;
  right:max(16px,env(safe-area-inset-right));
  bottom:max(16px,env(safe-area-inset-bottom));
  display:flex;
  align-items:center;
  gap:12px;
  pointer-events:auto;
  z-index:41;
}
.topbar-actions .button{min-height:32px;padding:0 12px;font-size:11px}
.config-badge{
  display:inline-flex;
  align-items:center;
  height:24px;
  padding:0 12px;
  border-radius:10px;
  background:var(--fill);
  color:var(--text-2);
  font-size:11px;
  font-weight:500;
  white-space:nowrap;
}

/* 菜单期隐藏 chrome：顶栏 / HUD / 底部提示（CONTRACT §7.5.3，body.menu-open）。
   用 opacity + visibility 而非 display，避免布局跳动；进入对局后淡入恢复。 */
#topbar,#hud,#hints{
  transition:opacity 450ms ease,visibility 450ms;
}
body.menu-open #topbar,body.menu-open #hud,body.menu-open #hints{
  opacity:0;
  visibility:hidden;
}

/* 画布：菜单期全屏铺满视口 + 中等虚化（CONTRACT §7.5.3，能看清双方 AI 对打）；进入对局后解焦。 */
#arena-canvas{
  display:block;
  width:100vw;
  height:100dvh;
  /* 逻辑世界仍是 16:9；显式 100vw×100dvh 优先，渲染器按 16:9 等比居中。 */
  aspect-ratio:16 / 9;
  border-radius:0;
  background:var(--bg);
  transition:filter 450ms ease,transform 450ms ease;
}
/* 菜单期：去掉 #app-main 的 padding 与 #stage 的圆角/边距，对战铺满整个窗口。 */
body.menu-open #app-main{
  padding:0;
  gap:0;
}
body.menu-open .stage{
  position:fixed;
  inset:0;
  width:auto;
  height:auto;
  padding:0;
  border-radius:0;
  background:none;
  box-shadow:none;
  display:grid;
  place-items:center;
  overflow:hidden;
}
body.menu-open .stage-media{
  width:100%;
  height:100%;
  display:grid;
  place-items:center;
  border-radius:0;
}
/* 16:9 画布按「铺满视口」尺寸（max(100vw, 100dvh×16/9)），由舞台裁切多余部分，不变形。 */
body.menu-open #arena-canvas{
  /* 菜单期背景必须全屏且两个 AI 都可见：直接铺满视口（重度失焦下不显拉伸）。 */
  width:100vw;
  height:100dvh;
  aspect-ratio:auto;
  border-radius:0;
  filter:blur(6px) saturate(1.05) brightness(1.2);
  transform:scale(1.015);
}

/* ---------- 5. 按钮：一种主操作 + 填充/文字层级；按下是变暗，不是位移 ---------- */
.button{
  min-height:36px;
  padding:0 24px;
  border-radius:10px;
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:8px;
  background:var(--fill);
  color:var(--text);
  font-size:13px;
  font-weight:500;
  line-height:1.5;
  white-space:nowrap;
  transition:background .16s,filter .16s,color .16s;
}
.button:hover{background:var(--fill-hover)}
.button:active{background:var(--fill-hover);filter:brightness(.92)}
.button.primary{background:var(--accent);color:var(--accent-ink)}
.button.primary:hover{background:var(--accent);filter:brightness(.96)}
.button.primary:active{background:var(--accent);filter:brightness(.88)}
/* 难度/音量等子页行：整行填充、圆角 10、无外框（v2 口径不变）。 */
.menu-rows{
  width:100%;
  display:flex;
  flex-direction:column;
  gap:4px;
}
.menu-row{
  width:100%;
  padding:0 16px;
  justify-content:center;
}
/* 文字按钮（返回主菜单 / 返回）：无填充，hover 出 --fill；不是第二个主按钮。 */
.text-button{
  min-height:32px;
  padding:0 12px;
  border-radius:8px;
  display:inline-flex;
  align-items:center;
  justify-content:center;
  background:none;
  color:var(--text-2);
  font-size:13px;
  font-weight:500;
  line-height:1.5;
  white-space:nowrap;
  transition:background .16s,color .16s,filter .16s;
}
.text-button:hover{background:var(--fill);color:var(--text)}
.text-button:active{background:var(--fill-hover);filter:brightness(.92)}

/* ---------- 音色试听（设置子页，角色行无外框） ---------- */
.voice-list{
  margin-top:12px;
  max-height:min(52vh,420px);
  overflow:auto;
  display:grid;
  grid-template-columns:repeat(2,minmax(0,1fr));
  gap:4px;
}
.voice-row{
  display:grid;
  grid-template-columns:minmax(0,1fr) auto;
  grid-template-rows:auto auto;
  column-gap:8px;
  row-gap:4px;
  align-items:center;
  width:100%;
  padding:12px;
  border-radius:10px;
  background:transparent;
  color:var(--text);
  text-align:left;
}
.voice-row:hover{background:var(--fill)}
.voice-row:active{filter:brightness(.92)}
.voice-name{font-size:13px;font-weight:500;line-height:1.5;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.voice-desc{grid-column:1 / 2;color:var(--text-3);font-size:11px;line-height:1.5;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.voice-tag{grid-column:2 / 3;grid-row:1 / 3;color:var(--text-2);font-size:11px;font-weight:500;line-height:1.5}
.voice-actions{margin-top:16px;display:flex;justify-content:flex-end;gap:8px}
@media (max-width:520px){
  .voice-list{grid-template-columns:1fr;max-height:min(46vh,360px)}
}

/* ---------- 战役剧情对白（全屏字幕层，无卡片/无描边） ---------- */
.dialogue{
  position:fixed;
  inset:0;
  z-index:60;
  display:flex;
  align-items:flex-end;
  justify-content:center;
  padding:0 24px max(24px,6vh);
  cursor:pointer;
  background:linear-gradient(180deg,
    color-mix(in srgb, var(--bg) 8%, transparent) 0%,
    color-mix(in srgb, var(--bg) 72%, transparent) 48%,
    var(--bg) 100%);
}
.dialogue[hidden]{display:none}
.dialogue-panel{
  width:min(980px,100%);
  color:var(--text);
  opacity:0;
  transition:opacity 180ms ease;
}
.dialogue-panel.is-visible{opacity:1}
.dialogue-panel.is-line-in .dialogue-text,
.dialogue-panel.is-line-in .dialogue-speaker,
.dialogue-panel.is-line-in .dialogue-label{
  animation:subtitle-in 180ms ease-out both;
}
@keyframes subtitle-in{
  from{opacity:0;transform:translateY(4px)}
  to{opacity:1;transform:none}
}
.dialogue-title{
  margin:0 0 4px;
  color:var(--text-3);
  font-size:11px;
  font-weight:500;
  line-height:1.5;
}
.dialogue-scene{
  margin:0 0 4px;
  color:var(--text-3);
  font-size:11px;
  font-style:italic;
  line-height:1.5;
}
.dialogue-label{
  margin:0;
  color:var(--text-2);
  font-size:11px;
  font-weight:600;
  line-height:1.5;
}
.dialogue-speaker{
  margin:16px 0 4px;
  color:var(--text);
  font-size:13px;
  font-weight:600;
  line-height:1.5;
}
.dialogue-text{
  margin:0;
  max-width:900px;
  color:var(--text);
  font-size:16px;
  font-weight:400;
  line-height:1.7;
}
.dialogue-loading{
  margin:8px 0 0;
  color:var(--text-3);
  font-size:11px;
  line-height:1.5;
  animation:dialogue-loading-pulse 1.2s ease-in-out infinite;
}
.dialogue-loading[hidden]{display:none}
@keyframes dialogue-loading-pulse{
  0%,100%{opacity:.45}
  50%{opacity:1}
}

/* ---------- 教程结束黑幕：全屏黑、居中、按标点换行 ---------- */
.blackout{
  position:fixed;
  inset:0;
  z-index:95;
  display:flex;
  align-items:center;
  justify-content:center;
  padding:0 24px;
  background:var(--bg);
  cursor:pointer;
  opacity:0;
  pointer-events:none;
  transition:opacity 300ms ease;
}
.blackout.is-visible{opacity:1;pointer-events:auto}
.blackout[hidden]{display:none}
.blackout-hint{
  position:absolute;
  right:16px;
  bottom:16px;
  margin:0;
  max-width:calc(100vw - 32px);
  color:var(--text-2);
  font-size:11px;
  font-weight:400;
  line-height:1.5;
  text-align:right;
}
.blackout-text{
  margin:0;
  max-width:760px;
  color:var(--text);
  font-size:16px;
  font-weight:500;
  line-height:1.8;
  text-align:center;
  white-space:pre-line;
}
@media (max-width:520px){
  .blackout{padding:0 16px}
  .blackout-text{font-size:13px;line-height:1.8}
}

.dialogue-text.is-narration{
  color:var(--text-2);
  font-size:13px;
  font-style:italic;
}
.dialogue-actions{
  margin-top:16px;
  display:flex;
  justify-content:flex-end;
  gap:8px;
}
.dialogue-skip[hidden]{display:none}
body.dialogue-open #topbar,
body.dialogue-open #hud,
body.dialogue-open #hints,
body.dialogue-open #pause-button{
  opacity:0;
  pointer-events:none;
}
body.final-ending #topbar,
body.final-ending #hud,
body.final-ending #hints,
body.final-ending #pause-button{
  opacity:0;
  pointer-events:none;
}
@media (max-width:520px){
  .dialogue{padding:0 16px max(20px,4vh)}
  .dialogue-text{font-size:13px;line-height:1.7}
  .dialogue-speaker{margin-top:16px}
}
.icon-button{
  width:32px;
  height:32px;
  border-radius:8px;
  display:inline-grid;
  place-items:center;
  background:var(--fill);
  color:var(--text-2);
  transition:background .16s,color .16s,filter .16s;
}
.icon-button:hover{background:var(--fill-hover);color:var(--text)}
.icon-button:active{background:var(--fill-hover);filter:brightness(.92)}
.icon-button svg{display:block;width:16px;height:16px}
#mute-button .mute-slash{display:none}
#mute-button[aria-pressed="true"]{background:var(--fill-hover);color:var(--text-3)}
#mute-button[aria-pressed="true"] .mute-waves{display:none}
#mute-button[aria-pressed="true"] .mute-slash{display:block}

/* ---------- 6. 主体：全屏战场；HUD 悬浮在战场上方 ---------- */
.app-main{
  position:fixed;
  inset:0;
  display:block;
  min-height:0;
  padding:0;
  margin:0;
  overflow:hidden;
}
#hud{
  position:fixed;
  top:0;
  left:0;
  right:0;
  z-index:15;
  display:grid;
  grid-template-columns:repeat(2,minmax(0,1fr));
  gap:16px 28px;
  padding:max(16px,env(safe-area-inset-top)) clamp(16px,2.6vw,40px) 32px;
  pointer-events:none;
  transition:opacity 450ms ease,visibility 450ms;
}
#hud.is-three{grid-template-columns:repeat(3,minmax(0,1fr))}
#hud.is-four{grid-template-columns:repeat(4,minmax(0,1fr))}
#hud.is-single{grid-template-columns:minmax(0,1fr)}
#hud.is-single .pips{display:none}
.hud-side{display:flex;flex-direction:column;gap:4px;min-width:0;width:100%}
.hud-p1{--fighter:var(--p1);align-items:flex-start}
.hud-p2{--fighter:var(--p2);align-items:flex-start}
.hud-p3{--fighter:var(--p3);align-items:flex-start}
.hud-p4{--fighter:var(--p4);align-items:flex-start}
/* 2P：P2 贴右；3/4P 全部左对齐，保持 P1→P4 顺序。 */
#hud:not(.is-three):not(.is-four) .hud-p2{align-items:flex-end}
.hud-line{display:flex;align-items:center;gap:8px;width:100%;min-width:0;justify-content:flex-start}
.hud-name{
  display:inline-flex;
  align-items:center;
  gap:4px;
  min-width:0;
  overflow:hidden;
  text-overflow:ellipsis;
  font-size:13px;
  font-weight:500;
  line-height:1.5;
  color:var(--text);
  white-space:nowrap;
  text-shadow:0 1px 2px color-mix(in srgb,var(--bg) 88%,transparent);
}
.hud-name::before{
  content:"";
  width:6px;
  height:6px;
  border-radius:50%;
  background:var(--fighter);
  flex:none;
}
#hud:not(.is-three):not(.is-four) .hud-p2 .hud-line{flex-direction:row-reverse}
/* 职业文字已删除；后续用角色皮肤区分职业。 */
.hud-class{display:none;font-size:11px;font-weight:400;line-height:1.5;color:var(--text-3);white-space:nowrap;flex:none}
.hud-round{
  position:fixed;
  left:50%;
  bottom:max(12px,env(safe-area-inset-bottom));
  transform:translateX(-50%);
  z-index:16;
  display:flex;
  align-items:center;
  justify-content:center;
  padding:0;
  border-radius:8px;
  pointer-events:none;
}
#round-label{
  font-size:11px;
  font-weight:500;
  line-height:1.5;
  font-variant-numeric:tabular-nums;
  color:var(--text-2);
  white-space:nowrap;
  text-shadow:0 1px 2px color-mix(in srgb,var(--bg) 88%,transparent);
}
.hp-track{
  display:block;
  width:100%;
  height:5px;
  border-radius:8px;
  background:var(--fill-strong);
  overflow:hidden;
}
.hp-fill{
  display:block;
  height:100%;
  width:100%;
  background:var(--fighter);
  transition:width .12s linear;
  border-radius:8px;
}
#hud:not(.is-three):not(.is-four) .hud-p2 .hp-fill{margin-left:auto}
/* 耐力 = 弹药胶囊：一格 = 一次射击的耐力消耗；15 消耗 7 格、20 消耗 5 格。 */
.stamina-track{
  display:block;
  width:100%;
  height:16px;
  margin-top:4px;
  background:none;
  overflow:visible;
}
.ammo-row{display:flex;align-items:flex-end;gap:4px;height:16px;min-width:0}
#hud:not(.is-three):not(.is-four) .hud-p2 .ammo-row{justify-content:flex-start;flex-direction:row-reverse}
.ammo-slot{
  position:relative;
  flex:none;
  width:7px;
  height:16px;
  border-radius:8px;
  background:var(--fill-strong);
  overflow:hidden;
  transition:opacity .16s;
}
.ammo-slot[hidden]{display:none}
.ammo-fill{
  position:absolute;
  left:0;
  right:0;
  bottom:0;
  height:0;
  border-radius:8px;
  background:linear-gradient(to bottom,
    color-mix(in srgb,var(--fighter) 88%,var(--text)) 0%,
    color-mix(in srgb,var(--fighter) 62%,var(--bg)) 100%);
  transition:height .1s linear,opacity .16s;
}
.stamina-track.is-staggered .ammo-fill{opacity:.35}
/* 冰法师命中：耐力恢复被拖慢，整排弹药降低透明度提示“回得很慢” */
.stamina-track.is-slowed .ammo-fill{opacity:.5}
.stamina-track.is-staggered.is-slowed .ammo-fill{opacity:.3}
.pips{display:inline-flex;align-items:center;gap:4px;flex:none}
.pip{
  width:8px;
  height:8px;
  border-radius:50%;
  background:var(--fill-strong);
  flex:none;
  transition:background .16s;
}
.pip.is-filled{background:var(--fighter)}

/* ---------- 7. 舞台：全屏铺满；HUD 悬浮 ---------- */
.stage-media{
  position:absolute;
  inset:0;
  border-radius:0;
  overflow:hidden;
  display:grid;
  place-items:center;
}
.stage{
  position:fixed;
  inset:0;
  width:auto;
  height:auto;
  padding:0;
  background:var(--bg);
  border-radius:0;
  box-shadow:none;
  overflow:hidden;
}

/* ---------- 8. 遮罩：菜单期为视口级电影感遮罩；对局期回到舞台内毛玻璃卡片 ---------- */
#overlay{
  position:absolute;
  inset:0;
  z-index:30;
  display:grid;
  place-items:center;
  border-radius:0;
  /* 对局内遮罩：半透明填充 + 毛玻璃，让冻结中的战场保持可读。 */
  background:color-mix(in srgb,var(--bg) 60%,transparent);
  -webkit-backdrop-filter:blur(10px);
  backdrop-filter:blur(10px);
}
/* 菜单态（home/difficulty/volume）：fixed 全屏、无卡片背景、无边框；
   左侧 linear-gradient 暗化（令牌 + color-mix，不新增描边）。 */
#overlay.home-mode{
  position:fixed;
  inset:0;
  z-index:30;
  border-radius:0;
  background:linear-gradient(90deg,color-mix(in srgb,var(--bg) 72%,transparent) 0%,transparent 64%);
  -webkit-backdrop-filter:none;
  backdrop-filter:none;
}

/* 共用卡片：难度/音量/暂停/局结算/比赛结算都在这里；home 态由 start-mode 覆盖为全屏菜单。 */
.overlay-card{
  width:min(440px,calc(100% - 32px));
  max-height:100%;
  overflow-y:auto;
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:8px;
  padding:28px;
  border-radius:22px;
  background:var(--float);
  box-shadow:0 40px 120px color-mix(in srgb,var(--bg) 70%,transparent);
  text-align:center;
  opacity:1;
  transition:opacity 600ms ease;
}
/* 入场期：主菜单先隐藏，intro 淡出时同步淡入（CONTRACT §7.5.2）；重载快速跳过用 250ms。 */
#overlay.intro-pending .overlay-card{opacity:0;transition:none}
#overlay.intro-fast .overlay-card{transition-duration:250ms}

.overlay-head{
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:8px;
}
#overlay-title{
  font-size:22px;
  font-weight:700;
  line-height:1.5;
  color:var(--text);
}
#overlay-copy{
  font-size:13px;
  font-weight:400;
  line-height:1.5;
  color:var(--text-2);
}
#overlay-score{
  font-size:16px;
  font-weight:600;
  line-height:1.5;
  font-variant-numeric:tabular-nums;
  color:var(--text);
}
#overlay-hint{
  font-size:11px;
  font-weight:400;
  line-height:1.5;
  color:var(--text-3);
}
/* 面板：一屏一种主操作（面板内可同时存在主按钮 + 填充行 + 文字按钮，但 primary 唯一）。 */
.overlay-panel{
  width:100%;
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:8px;
  margin-top:8px;
}
.overlay-panel .button{width:100%}

/* ---------- 9. 电影感主菜单（#overlay.home-mode.start-mode） ---------- */
#overlay.home-mode.start-mode{
  place-items:stretch;
}
#overlay.home-mode.start-mode .overlay-card{
  width:100%;
  max-width:none;
  max-height:none;
  height:100%;
  padding:0 48px;
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  justify-content:center;
  gap:24px;
  background:none;
  box-shadow:none;
  border-radius:0;
  overflow:visible;
  text-align:left;
}
#overlay.home-mode.start-mode .overlay-head{
  align-items:flex-start;
  gap:8px;
}
/* 品牌 wordmark：允许超过 11/13/16/22 字号白名单（CONTRACT §7.5.1 唯一例外）。 */
#overlay.home-mode.start-mode #overlay-title{
  font-family:var(--brand-font);
  font-size:clamp(64px,14vw,180px);
  font-weight:700;
  line-height:1.5;
  letter-spacing:-.04em;
  color:var(--text);
  white-space:nowrap;
  opacity:0;
  transform-origin:left center;
  will-change:transform,opacity;
  animation:wordmark-float 9s ease-in-out infinite;
}
#overlay.home-mode.start-mode.menu-in #overlay-title{opacity:1;transition:opacity 1000ms ease}
@keyframes wordmark-float{
  0%,100%{translate:0 0;rotate:0deg}
  50%{translate:0 -6px;rotate:-.5deg}
}
#overlay.home-mode.start-mode #overlay-copy{
  font-size:11px;
  font-weight:400;
  line-height:1.5;
  color:var(--text-3);
}
#overlay.home-mode.start-mode #overlay-hint{
  font-size:11px;
  font-weight:400;
  line-height:1.5;
  color:var(--text-3);
  text-align:left;
}

/* 四个无框浮动选项：真实 button、透明底、无边框/无填充/无下划线、左对齐、22px。 */
.menu-options{
  width:auto;
  align-items:flex-start;
  gap:8px;
  margin-top:0;
}
.menu-option{
  display:inline-flex;
  align-items:center;
  justify-content:flex-start;
  padding:8px 0;
  border-radius:8px;
  background:none;
  color:var(--text-2);
  font-size:clamp(24px,2.6vw,34px);
  font-weight:500;
  line-height:1.5;
  text-align:left;
  white-space:nowrap;
  transform-origin:left center;
  opacity:0;
  transform:translateY(12px);
  transition:color .2s ease,transform .2s ease,filter .2s ease;
  animation:menu-float 6.4s ease-in-out infinite;
}
/* 菜单淡入时四个选项逐个上浮出现（衔接动画的一部分）。 */
#overlay.menu-in .menu-option{
  opacity:1;
  transform:none;
  transition:opacity 1000ms ease,transform 1000ms cubic-bezier(.2,.8,.2,1);
}
#overlay.menu-in .menu-option:nth-child(1){transition-delay:140ms}
#overlay.menu-in .menu-option:nth-child(2){transition-delay:280ms}
#overlay.menu-in .menu-option:nth-child(3){transition-delay:420ms}
#overlay.menu-in .menu-option:nth-child(4){transition-delay:560ms}
/* 每个选项 0 ±5px + 轻微旋转的 6–8s 错峰浮动；hover/focus 时放大 1.06 + 左移 4px。 */
.menu-option:nth-child(1){animation-duration:6.2s;animation-delay:-.3s}
.menu-option:nth-child(2){animation-duration:7.4s;animation-delay:-1.8s;animation-name:menu-float-alt}
.menu-option:nth-child(3){animation-duration:8s;animation-delay:-3.4s}
.menu-option:nth-child(4){animation-duration:6.8s;animation-delay:-4.8s;animation-name:menu-float-alt}
.menu-option:hover,.menu-option:focus{
  color:var(--text);
  transform:translateX(-5px) scale(1.07);
}
.menu-option:active{filter:brightness(.85)}
@keyframes menu-float{
  0%,100%{translate:0 0;rotate:0deg}
  50%{translate:0 -5px;rotate:-1.3deg}
}
@keyframes menu-float-alt{
  0%,100%{translate:0 0;rotate:0deg}
  50%{translate:0 4px;rotate:1.5deg}
}

/* ---------- 10. 音量：填充轨道 + 常规滑块（WebKit）；颜色只走令牌，无描边无卡片框 ---------- */
.volume-line{
  width:100%;
  display:flex;
  align-items:center;
  gap:16px;
  padding:0 4px;
}
.volume-label{
  flex:0 0 32px;
  font-size:13px;
  font-weight:500;
  line-height:1.5;
  color:var(--text-2);
}
/* 设置页版本号：所有外壳都显示（Electron 内容版本 / WKWebView bundle 版本 / 浏览器 meta）；11px 次级灰，不用线分组（CONTRACT §7.5.1）。 */
.settings-version{
  margin-top:24px;
  font-size:11px;
  font-weight:400;
  line-height:1.5;
  color:var(--text-3);
  font-variant-numeric:tabular-nums;
  user-select:text;
}
/* ---------- 10.1 背景音乐试听：无框行列表；hover=--fill，播放中=--fill-hover ---------- */
.bgm-preview{
  width:100%;
  margin-top:24px;
  display:flex;
  flex-direction:column;
  gap:8px;
  text-align:left;
}
.bgm-heading{
  padding:0 4px;
  font-size:11px;
  font-weight:500;
  line-height:1.5;
  color:var(--text-3);
}
.bgm-list{
  list-style:none;
  margin:0;
  padding:0;
  display:flex;
  flex-direction:column;
  gap:4px;
  max-height:min(38vh,360px);
  overflow-y:auto;
  overscroll-behavior:contain;
}
.bgm-row-button{
  width:100%;
  display:flex;
  align-items:flex-end;
  justify-content:space-between;
  gap:12px;
  padding:8px 12px;
  border-radius:10px;
  background:transparent;
  color:var(--text);
  text-align:left;
  cursor:pointer;
  transition:background 160ms ease;
}
.bgm-row-button:hover{background:var(--fill)}
.bgm-row-button[aria-pressed="true"]{background:var(--fill-hover)}
.bgm-row-text{
  flex:1;
  min-width:0;
  display:flex;
  flex-direction:column;
}
.bgm-row-chapter{
  font-size:11px;
  font-weight:400;
  line-height:1.5;
  color:var(--text-2);
}
.bgm-row-title{
  font-size:13px;
  font-weight:400;
  line-height:1.5;
  color:var(--text);
  white-space:nowrap;
  overflow:hidden;
  text-overflow:ellipsis;
}
.bgm-row-action{
  flex:none;
  font-size:11px;
  font-weight:500;
  line-height:1.5;
  color:var(--text-2);
}
.bgm-row-button[aria-pressed="true"] .bgm-row-chapter,
.bgm-row-button[aria-pressed="true"] .bgm-row-action{color:var(--text)}
/* 更新提示：有更新时才出现的 11px 次级操作；不占菜单项、不打断进入游戏。 */
.update-hint{
  position:fixed;
  right:24px;
  bottom:24px;
  z-index:6;
  display:inline-flex;
  align-items:center;
  min-height:32px;
  padding:0 12px;
  border-radius:10px;
  background:var(--fill);
  color:var(--text-2);
  font-size:11px;
  font-weight:500;
  line-height:1.5;
  letter-spacing:.02em;
  transition:background .16s,color .16s,filter .16s;
}
.update-hint:hover{background:var(--fill-hover);color:var(--text)}
.update-hint:active{background:var(--fill-hover);filter:brightness(.92)}
.update-hint[hidden]{display:none}
/* 设置页更新状态与「检查更新」按钮：填充行、无描边，与版本号同字号。 */
#update-button{background:var(--fill);border-radius:10px;padding:0 16px}
#update-button:hover{background:var(--fill-hover)}
#update-button:active{background:var(--fill-hover)}
#update-button:disabled{opacity:.55}
.update-status{margin-top:0}
#update-button[hidden],#update-status[hidden]{display:none}
#sfx-volume-range,#music-volume-range{
  flex:1 1 auto;
  min-width:0;
  height:32px;
  margin:0;
  -webkit-appearance:none;
  appearance:none;
  background:transparent;
  cursor:pointer;
}
#sfx-volume-range::-webkit-slider-runnable-track,#music-volume-range::-webkit-slider-runnable-track{
  height:16px;
  border-radius:8px;
  background:linear-gradient(to right,var(--text-3) 0%,var(--text-3) var(--volume-percent,100%),var(--fill-strong) var(--volume-percent,100%),var(--fill-strong) 100%) center/100% 6px no-repeat;
}
#sfx-volume-range::-webkit-slider-thumb,#music-volume-range::-webkit-slider-thumb{
  -webkit-appearance:none;
  appearance:none;
  width:16px;
  height:16px;
  border-radius:50%;
  background:var(--text);
}
#sfx-volume-value,#music-volume-value{
  flex:none;
  min-width:48px;
  text-align:right;
  font-size:13px;
  font-weight:500;
  line-height:1.5;
  font-variant-numeric:tabular-nums;
  color:var(--text);
}

/* ---------- 10b. 选角界面（#overlay-loadout；多人 / 单人共用）
   无框：分组靠小标题 + 24/32 留白；选中用填充层级（--fill-hover），颜色按钮用内点表示选中。 */
/* 选角界面：不要卡片外框——整屏暗底 + 内容直接铺在背景上（与零描边一致，只靠明度与留白分层）。 */
#overlay.loadout-mode{
  background:color-mix(in srgb,var(--bg) 92%,transparent);
  -webkit-backdrop-filter:blur(6px);
  backdrop-filter:blur(6px);
}
#overlay.loadout-mode .overlay-card{
  width:min(960px,calc(100% - 48px));
  max-height:100%;
  overflow-y:auto;
  padding:32px;
  gap:24px;
  align-items:stretch;
  text-align:left;
  background:none;
  box-shadow:none;
  border-radius:0;
}
/* 职业：每行 4 个的紧凑网格（角色再多也自动换行）；悬停/聚焦弹出简介。 */
.class-grid{
  display:grid;
  grid-template-columns:repeat(4,minmax(0,1fr));
  gap:8px;
}
.class-chip{
  position:relative;
  width:auto;
  min-height:40px;
  padding:8px 4px;
  align-items:center;
  justify-content:center;
  text-align:center;
}
/* 简介气泡：无描边、填充底，悬停或键盘聚焦时出现（不拦截鼠标）。 */
.class-chip::after{
  content:attr(data-desc);
  position:absolute;
  top:calc(100% + 8px);
  left:0;
  z-index:6;
  width:max-content;
  max-width:220px;
  padding:8px;
  border-radius:8px;
  background:var(--float);
  color:var(--text-2);
  font-size:11px;
  font-weight:400;
  line-height:1.5;
  text-align:left;
  white-space:normal;
  pointer-events:none;
  opacity:0;
  transition:opacity .16s ease;
  box-shadow:0 12px 28px color-mix(in srgb,var(--bg) 70%,transparent);
}
.class-chip:hover,.class-chip:focus-visible{z-index:2}
.class-chip:hover::after,
.class-chip:focus-visible::after{opacity:1}
/* 第二行卡片的气泡向上弹出，避免与下方祝福分组重叠。 */
.class-grid .class-chip:nth-child(n+5)::after{top:auto;bottom:calc(100% + 8px)}
#overlay.loadout-mode.is-four .overlay-card{width:min(1180px,calc(100% - 48px))}
#overlay.loadout-mode .overlay-head{align-items:flex-start}
#overlay.loadout-mode #overlay-title{font-size:22px}
#overlay-loadout{
  margin-top:0;
  align-items:stretch;
}
.loadout-body{
  display:flex;
  gap:32px;
  align-items:stretch;
  min-width:0;
}
.loadout-players{
  flex:1 1 auto;
  min-width:0;
  display:grid;
  grid-template-columns:repeat(2,minmax(0,1fr));
  gap:32px;
}
#overlay-loadout.is-solo .loadout-players{grid-template-columns:minmax(0,360px)}
/* 战役选角：左侧职业网格占满可用宽度，右侧固定 340px 放职业详情 + 开始/返回。 */
#overlay-loadout.is-campaign .loadout-players{grid-template-columns:minmax(0,1fr)}
#overlay-loadout.is-campaign .loadout-side{width:clamp(260px,38%,340px)}
/* 战役不再用悬停气泡：选中职业的信息只出现在右侧详情。 */
#overlay-loadout.is-campaign .class-chip::after{content:none;display:none}
#overlay-loadout.is-campaign #loadout-name-p1{display:none}
.loadout-player{
  min-width:0;
  display:flex;
  flex-direction:column;
  gap:24px;
}
.loadout-heading{
  font-size:16px;
  font-weight:600;
  line-height:1.5;
  color:var(--text);
}
.loadout-player-head{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:8px;
}
.loadout-group{
  min-width:0;
  display:flex;
  flex-direction:column;
  gap:8px;
}
.loadout-label{
  display:block;
  font-size:11px;
  font-weight:500;
  line-height:1.5;
  color:var(--text-3);
}
/* 战役职业详情：只靠填充面与留白分层，无描边。 */
.class-detail{
  gap:12px;
  padding:16px;
  border-radius:14px;
  background:var(--fill);
}
.class-detail-name{
  font-size:16px;
  font-weight:600;
  line-height:1.5;
  color:var(--text);
}
.class-detail-rows{
  display:flex;
  flex-direction:column;
  gap:12px;
}
.class-detail-row{
  display:grid;
  grid-template-columns:56px minmax(0,1fr);
  gap:12px;
  align-items:start;
}
.class-detail-key{
  font-size:11px;
  font-weight:500;
  line-height:1.6;
  color:var(--text-3);
}
.class-detail-value{
  font-size:13px;
  font-weight:400;
  line-height:1.6;
  color:var(--text-2);
}
.name-input{
  width:100%;
  height:36px;
  padding:0 12px;
  border-radius:10px;
  background:var(--fill);
  color:var(--text);
  font-family:var(--font);
  font-size:13px;
  font-weight:500;
  line-height:1.5;
  transition:background .16s;
}
.name-input:hover{background:var(--fill-hover)}
.name-input:focus{background:var(--fill-hover)}
.swatches{
  display:flex;
  flex-wrap:wrap;
  gap:8px;
}
.swatch{
  position:relative;
  width:32px;
  height:32px;
  padding:0;
  border-radius:50%;
  background-color:var(--text-3);
  transition:filter .16s,opacity .16s;
}
.swatch:hover{filter:brightness(1.12)}
.swatch:active{filter:brightness(.88)}
.swatch[aria-pressed="true"]::after{
  content:"";
  position:absolute;
  left:50%;
  top:50%;
  width:8px;
  height:8px;
  transform:translate(-50%,-50%);
  border-radius:50%;
  background:var(--accent-ink);
}
.swatch:disabled{opacity:.28;cursor:not-allowed;filter:none}
.choice-rows{
  display:flex;
  flex-direction:column;
  gap:4px;
}
.choice-row{
  width:100%;
  min-height:44px;
  padding:8px 12px;
  border-radius:10px;
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  justify-content:center;
  gap:4px;
  background:none;
  color:var(--text);
  text-align:left;
  transition:background .16s,filter .16s;
}
.choice-row:hover{background:var(--fill)}
.choice-row:active{filter:brightness(.92)}
.choice-row[aria-pressed="true"]{background:var(--fill-hover)}
.choice-title{
  font-size:13px;
  font-weight:500;
  line-height:1.5;
}
.choice-desc{
  font-size:11px;
  font-weight:400;
  line-height:1.5;
  color:var(--text-2);
}
/* 单人挑战：战役在上、训练场在下；训练场在第 0 章通关前锁定。 */
.solo-choice{width:100%}
.solo-choice .choice-row{flex-direction:row;align-items:center;justify-content:space-between}
.solo-lock{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:16px;
  height:16px;
  color:var(--text-2);
  pointer-events:none;
}
.solo-lock[hidden]{display:none}
.choice-row:disabled{cursor:not-allowed;filter:none}
.choice-row:disabled:hover{background:none}
.solo-choice .choice-row:disabled .choice-title{color:var(--text-3)}
/* 战役列表：2 列紧凑行，10 场一屏可见；未解锁行变暗并显示「锁」。 */
.campaign-difficulty{display:flex;justify-content:center;gap:8px;width:100%}
.campaign-difficulty .text-button{flex:1;max-width:120px;margin:0;padding:8px 12px;border-radius:10px;color:var(--text-2)}
.campaign-difficulty .text-button[aria-pressed="true"]{background:var(--fill-hover);color:var(--text)}
.campaign-hell-mark{position:absolute;top:8px;right:8px;width:8px;height:8px;border-radius:50%;background:var(--campaign-gold);box-shadow:0 0 20px var(--campaign-gold);pointer-events:none}
.campaign-hell-mark[hidden]{display:none}
.campaign-grid{
  width:100%;
  display:grid;
  grid-template-columns:repeat(2,minmax(0,1fr));
  gap:8px;
}
.campaign-card{
  position:relative;
  min-height:64px;
  padding-right:36px;
}
.campaign-card:disabled{
  cursor:not-allowed;
  filter:none;
}
.campaign-card:disabled:hover{background:none}
.campaign-card.is-locked .choice-title{color:var(--text-3)}
.campaign-status{
  font-size:11px;
  font-weight:400;
  line-height:1.5;
  color:var(--text-3);
}
.campaign-lock{
  position:absolute;
  top:50%;
  right:8px;
  transform:translateY(-50%);
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:16px;
  height:16px;
  color:var(--text-2);
  pointer-events:none;
}
/* .campaign-lock 有显式 display，UA 的 [hidden] 压不住，必须显式隐藏。 */
.campaign-lock[hidden]{display:none}
.campaign-lock svg,.class-lock svg{width:16px;height:16px;display:block}
.campaign-unlock-feedback{
  display:flex;
  align-items:center;
  justify-content:center;
  gap:12px;
  max-width:100%;
  padding:8px 0;
  color:var(--text);
  font-size:13px;
  font-weight:500;
  line-height:1.6;
}
.campaign-unlock-feedback[hidden]{display:none}
.campaign-unlock-icon{display:inline-flex;flex:0 0 32px;width:32px;height:32px}
.campaign-unlock-icon svg{display:block;width:32px;height:32px;overflow:visible}
.campaign-unlock-feedback .lock-shackle,.campaign-card .lock-shackle{
  transform-box:fill-box;
  transform-origin:0% 100%;
}
.campaign-unlock-feedback.is-open .lock-shackle,.campaign-card.is-open .lock-shackle{
  transform:translateY(-1px) rotate(-32deg);
}
.campaign-unlock-feedback.is-unlocking .lock-shackle,.campaign-card.is-unlocking .lock-shackle{
  animation:campaign-lock-open 900ms ease-out both;
}
@keyframes campaign-lock-open{
  0%,12%{transform:translateY(0) rotate(0deg)}
  36%{transform:translateY(-1px) rotate(0deg)}
  76%{transform:translateY(-2px) rotate(-36deg)}
  100%{transform:translateY(-1px) rotate(-32deg)}
}
@media(prefers-reduced-motion:reduce){
  .campaign-unlock-feedback.is-unlocking .lock-shackle,.campaign-card.is-unlocking .lock-shackle{animation:none}
}
/* 战役选角：BOSS 之前的职业可用；锁住的职业只显示锁图标，名称与简介都不显示。 */
.class-chip.is-locked{cursor:not-allowed}
.class-chip.is-locked:hover{background:none}
.class-chip.is-locked::after{content:none;display:none}
.class-lock{
  position:absolute;
  inset:0;
  display:flex;
  align-items:center;
  justify-content:center;
  color:var(--text-2);
  pointer-events:none;
}
.loadout-boss{
  min-height:36px;
  padding:8px 12px;
  border-radius:10px;
  background:var(--fill);
  color:var(--text);
  font-size:13px;
  font-weight:500;
  line-height:1.5;
}
/* .choice-row 的 padding 定义在 .class-chip 之后，会把职业格的 4px 内边距覆盖成 12px；
 * 窄屏下职业名会被挤成逐字竖排。这里用更高特异性恢复紧凑内边距。 */
.class-grid .class-chip{padding:8px 4px;align-items:center;justify-content:center;text-align:center}
/* 窄屏：战役卡收紧为单行标题，10 章与返回都能留在首屏内。 */
@media (max-width:520px){
  .campaign-grid{gap:4px}
  .campaign-card{min-height:56px;padding:4px 8px;padding-right:24px}
  .campaign-card .choice-title{font-size:11px}
  .campaign-lock{right:4px}
}
.loadout-side{
  width:200px;
  flex:none;
  display:flex;
  flex-direction:column;
  justify-content:space-between;
  gap:24px;
}
/* 战役右侧：详情在上、开始/返回贴底；宽度与布局见上文 is-campaign 规则。 */
/* hidden 的 loadout 分组（单人模式的 AI 难度 / 开火键行）必须真正隐藏：
   .loadout-group 是 display:flex，UA 的 [hidden]{display:none} 特异性打不过显式 display。 */
.loadout-group[hidden]{display:none}
.loadout-actions{
  display:flex;
  flex-direction:column;
  gap:8px;
}
.loadout-actions .button,.loadout-actions .text-button{width:100%}
/* 窄屏 / 矮屏：右侧操作区移到顶部，保证主按钮首屏可见；玩家面板改为单列。 */
@media (max-width:760px),(max-height:620px){
  #overlay.loadout-mode .overlay-card{padding:20px;gap:16px}
  .loadout-body{flex-direction:column;gap:16px}
  .loadout-side{
    order:-1;
    width:100%;
    flex-direction:row;
    flex-wrap:wrap;
    align-items:flex-end;
    gap:16px;
  }
  .loadout-side .loadout-group{flex:1 1 200px}
  #overlay-loadout.is-campaign .loadout-side{width:100%}
  #overlay-loadout.is-campaign .class-detail{flex:1 1 100%}
  .loadout-actions{flex:1 1 200px;flex-direction:row;gap:8px}
  .loadout-actions .button,.loadout-actions .text-button{width:auto;flex:1 1 0}
  .loadout-players{grid-template-columns:minmax(0,1fr);gap:24px}
  #overlay-loadout.is-solo .loadout-players{grid-template-columns:minmax(0,1fr)}
  .loadout-player{gap:16px}
}

/* 正式章节的短窗口先显示难度与开战操作；教学章没有难度控件，保持原排列。 */
@media (max-height:620px){
  #campaign-difficulty:not([hidden]) ~ .class-detail{order:1}
}

/* ---------- 10c. 整局获胜终局（透明遮罩：胜者特写在画面中央，狠话与按钮在下方） ---------- */
#overlay.finale-mode{
  background:none;
  -webkit-backdrop-filter:none;
  backdrop-filter:none;
  place-items:end center;
  padding:0 0 48px;
}
#overlay.finale-mode .overlay-card{
  background:none;
  box-shadow:none;
  border-radius:0;
  gap:16px;
  padding:0;
}
#overlay.finale-mode #overlay-title,
#overlay.finale-mode #overlay-copy,
#overlay.finale-mode #overlay-score{display:none}
#overlay.finale-mode .overlay-panel{display:none}
#overlay.finale-mode #overlay-match{display:flex;gap:16px;margin-top:0}
#overlay-taunt{
  max-width:min(720px,calc(100% - 48px));
  font-size:22px;
  font-weight:600;
  line-height:1.5;
  color:var(--text);
  text-align:center;
  text-shadow:0 2px 18px color-mix(in srgb,var(--bg) 80%,transparent);
}
#overlay.finale-mode .overlay-match-actions{
  display:flex;
  align-items:center;
  gap:16px;
  opacity:0;
  transition:opacity 400ms ease;
}
#overlay.finale-mode.finale-ready .overlay-match-actions{opacity:1}

/* ---------- 11. 底部提示行：11px --text-3，固定在页脚位置 ---------- */
#hints{
  position:fixed;
  left:max(16px,env(safe-area-inset-left));
  bottom:max(12px,env(safe-area-inset-bottom));
  z-index:16;
  display:flex;
  align-items:center;
  justify-content:flex-start;
  height:auto;
  padding:0;
  font-size:11px;
  font-weight:400;
  line-height:1.5;
  color:var(--text-3);
  text-align:left;
  background:none;
}

/* ---------- 12. 窄屏/矮屏：保留同一套层级语言，不产生横向滚动 ---------- */
@media (max-width:900px){
  /* 3/4 人回到 2×2；2 人仍是左右两列。 */
  #hud.is-three,#hud.is-four{grid-template-columns:repeat(2,minmax(0,1fr))}
  #hud{gap:12px 16px;padding-left:16px;padding-right:16px}
}
@media (max-width:520px),(max-height:620px){
  /* 3/4 人 HUD 在窄屏收紧：列间距减半，玩家名可截断，避免横向溢出。 */
  #hud.is-three,#hud.is-four{column-gap:8px;row-gap:8px}
  .hud-name{min-width:0;overflow:hidden;text-overflow:ellipsis}
  /* 菜单本来就是 fixed 全屏；对局内遮罩在窄屏也提升为视口级，保证关键操作首屏可见。 */
  #overlay{position:fixed;border-radius:0}
  #overlay.home-mode.start-mode .overlay-card{padding:0 24px;gap:16px}
  #overlay.home-mode.start-mode .overlay-head{gap:8px}
  #overlay.home-mode.start-mode #overlay-title{font-size:clamp(40px,13vw,64px)}
  .menu-options{gap:8px}
  .menu-option{font-size:16px;padding:4px 0}
}
@media (max-width:760px){
  #hud{padding-left:16px;padding-right:16px}
  #hints{left:16px}
}
@media (max-width:440px),(max-height:440px){
  .overlay-card{padding:12px;border-radius:16px;gap:4px}
  #overlay-title{font-size:16px;font-weight:600}
  .overlay-panel{margin-top:0;gap:4px}
  .overlay-panel .button{min-height:32px;padding:0 16px}
  .menu-rows{gap:4px}
  .text-button{min-height:32px;padding:0 12px}
  .volume-line{gap:12px;padding:0}
  #sfx-volume-value,#music-volume-value{min-width:44px;font-size:11px}
}

/* ---------- 13. 减少动态效果：关闭入场砸落/震屏/浮动与所有过渡（CONTRACT §7.5.2/§9） ---------- */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{transition:none!important;animation:none!important}
  #intro-title{opacity:1;transform:none}
  #overlay.home-mode.start-mode #overlay-title{opacity:1}
  .menu-option{opacity:1;transform:none}
}

/* 剧情操作提示独立于字幕，避免改变角色字幕锚点。 */
.story-speed-hint{
  position:fixed;
  right:16px;
  bottom:56px;
  z-index:65;
  margin:0;
  max-width:calc(100vw - 32px);
  padding:4px 8px;
  border-radius:8px;
  background:var(--bg);
  color:var(--text-2);
  font-size:11px;
  font-weight:400;
  line-height:1.5;
  pointer-events:none;
}
.story-speed-hint[hidden]{display:none}

/* 瞄准练习停滞时提供主动跳过，避开右下角暂停与剧情提示。 */
.tutorial-skip{position:fixed;left:16px;bottom:56px;z-index:65}
.tutorial-skip[hidden]{display:none}

.stamina-track.is-tutorial-focus{background:var(--fill-hover);border-radius:8px}

@media (max-width:440px),(max-height:440px){
  .exchange.is-tutorial .exchange-text{font-size:13px;line-height:1.5}
}

/* 第 0 关的主动教学入口与主操作固定在首屏，准备内容在上方滚动。 */
#overlay.campaign-ready-mode.campaign-tutorial-entry .loadout-actions{flex-direction:column;gap:8px}
#overlay.campaign-ready-mode.campaign-tutorial-entry .loadout-body{height:calc(100% - 100px)}
#overlay.campaign-ready-mode #loadout-tutorial{flex:none;width:100%;min-height:32px;color:var(--tower-muted);padding:4px 8px}
#loadout-tutorial[hidden]{display:none}
