/* ===== 咕咕团，GO！ ===== */
/* 强调色（--acc）固定为琥珀：文字/按钮/边框等强调元素用色 */
/* 窗体底色（--panel）固定：#12101c，不再提供换色（主题色功能已移除，仅保留背景图） */
/* 卡片底色（--card / --card-hi）：窗体内部卡/输入框，比窗体底色略亮以保留层次 */
:root {
  --acc: #d4a53c;
  --panel: #12101c;
  --card: color-mix(in srgb, var(--panel) 72%, #2b2645);
  --card-hi: color-mix(in srgb, var(--panel) 55%, #3f3968);
}
* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; }
body {
  font-family: "PingFang SC", "Microsoft YaHei", system-ui, sans-serif;
  background: #0d0c14; color: #e8e6f2;
  -webkit-font-smoothing: antialiased;
}
.hidden { display: none !important; }
button { font-family: inherit; }

/* 窗体背景层（本地设置，见「🎨 主题」面板；不影响中央舞台场景） */
#frameBg {
  position: fixed; inset: 0; z-index: 0; display: none;
  background-size: cover; background-position: center; background-repeat: no-repeat;
}
body.has-framebg #frameBg { display: block; }
#lobby, #app { position: relative; z-index: 1; }

/* 细滚动条 */
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: rgba(255,255,255,.13); border-radius: 4px; }
::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,.26); }

/* ===== 通用控件 ===== */
.btn {
  background: #252238; color: #e8e6f2;
  border: 1px solid rgba(255,255,255,.12); border-radius: 8px;
  padding: 8px 14px; cursor: pointer; font-size: 14px;
  transition: background .15s, border-color .15s, color .15s;
}
.btn:hover { background: #2e2a45; border-color: rgba(255,255,255,.25); }
.btn { transform: translateY(0); }
.btn:active { transform: translateY(1px); }
.btn.primary {
  background: linear-gradient(135deg, color-mix(in srgb, var(--acc) 60%, #1c1405), var(--acc));
  color: #fff; border-color: transparent;
  box-shadow: 0 4px 16px color-mix(in srgb, var(--acc) 30%, transparent);
}
.btn.primary:hover { filter: brightness(1.1); }
.btn.small { padding: 5px 10px; font-size: 12px; }
.btn.tiny { padding: 2px 8px; font-size: 12px; border-radius: 6px; }
.btn.danger:hover { border-color: #ff5d5d; color: #ff5d5d; }
.btn.danger-solid { background: linear-gradient(135deg, #8a2626, #d63c3c); color: #fff; border-color: transparent; }
.btn.danger-solid:hover { filter: brightness(1.12); }
.btn.ghost { background: transparent; }
.btn.wide { width: 100%; }
.btn.big { font-size: 16px; padding: 11px; letter-spacing: .1em; }

input, textarea {
  background: #0b0a12; color: #e8e6f2;
  border: 1px solid rgba(255,255,255,.14); border-radius: 8px;
  padding: 8px 10px; font-size: 14px; font-family: inherit;
}
input:focus, textarea:focus { outline: none; border-color: var(--acc); box-shadow: 0 0 0 3px color-mix(in srgb, var(--acc) 20%, transparent); }
input::placeholder, textarea::placeholder { color: #5b5779; }
.num { width: 72px; }
.row { display: flex; gap: 8px; margin-bottom: 8px; align-items: center; }
.row.wrap { flex-wrap: wrap; }
.row:last-child { margin-bottom: 0; }
.grow { flex: 1; width: 0; min-width: 0; }
.hint { color: #77739a; font-size: 12px; }
.tag {
  font-size: 11px; color: var(--acc); border: 1px solid color-mix(in srgb, var(--acc) 40%, transparent);
  border-radius: 4px; padding: 1px 6px; vertical-align: 2px; margin-left: 4px;
}
.dot { width: 9px; height: 9px; border-radius: 50%; display: inline-block; }
.dot.on { background: #52c41a; box-shadow: 0 0 8px #52c41a; }
.dot.off { background: #66628a; }

/* ===== 大厅 ===== */
#lobby {
  min-height: 100vh; display: flex; align-items: center; justify-content: center;
  background: radial-gradient(ellipse at 30% 0%, color-mix(in srgb, var(--panel) 88%, #1d1934), #0d0c14 70%);
}
.lobby-card {
  position: relative;
  width: min(92vw, 380px);
  background: rgba(255,255,255,.04);
  border: 1px solid rgba(255,255,255,.1);
  border-radius: 18px; padding: 34px 30px; text-align: center;
  backdrop-filter: blur(8px);
  box-shadow: 0 24px 70px rgba(0,0,0,.55), inset 0 1px 0 rgba(255,255,255,.06);
}
.lobby-logo { font-size: 46px; line-height: 1; animation: logoFloat 3.2s ease-in-out infinite; display: inline-block; }
@keyframes logoFloat { 50% { transform: translateY(-7px) rotate(-6deg); } }
.lobby-card h1 {
  font-size: 27px; margin: 12px 0 18px; letter-spacing: .1em; font-weight: 800;
  background: linear-gradient(120deg, #fff 25%, var(--acc) 95%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
#btnThemeLobby {
  position: absolute; top: 12px; right: 12px; z-index: 2;
}
.sub { color: #8f8ba8; font-size: 12px; margin-bottom: 22px; }
.fld { display: block; text-align: left; font-size: 12px; color: #a5a1c4; margin-bottom: 14px; }
.fld input { width: 100%; margin-top: 6px; }
.lobby-actions { display: flex; flex-direction: column; gap: 10px; }
.join-row { display: flex; gap: 8px; }
.join-row input {
  flex: 1; width: 0; text-transform: uppercase; letter-spacing: .3em;
  text-align: center; font-size: 16px;
}
.msg { color: #ff8d8d; font-size: 12px; margin-top: 12px; min-height: 16px; }

/* 大厅身份选择器：玩家/主持人二选一，本机记住 */
.role-tabs {
  display: flex; gap: 6px; padding: 4px; margin-bottom: 14px;
  background: rgba(255,255,255,.05); border: 1px solid rgba(255,255,255,.08);
  border-radius: 12px;
}
.role-tab {
  flex: 1; padding: 8px 6px; border: 0; border-radius: 8px; cursor: pointer;
  background: transparent; color: #a5a1c4; font-size: 13px; font-weight: 600;
  transition: background .15s, color .15s, transform .1s;
}
.role-tab:hover { color: #fff; }
.role-tab.active {
  background: linear-gradient(180deg, var(--acc), color-mix(in srgb, var(--acc) 78%, #000));
  color: #fff; box-shadow: 0 4px 12px rgba(0,0,0,.35);
}
.role-tab:active { transform: translateY(1px); }

/* 大厅房间列表 */
.lobby-card { max-height: 92vh; overflow-y: auto; }
.rooms-sec { margin-top: 16px; text-align: left; }
.rooms-head { display: flex; align-items: center; justify-content: space-between; font-size: 12px; color: #a5a1c4; margin-bottom: 8px; }
.room-list { display: flex; flex-direction: column; gap: 8px; max-height: 260px; overflow-y: auto; }
.room-item {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  background: rgba(255,255,255,.05); border: 1px solid rgba(255,255,255,.1);
  border-radius: 10px; padding: 10px 12px;
}
.room-info { flex: 1; min-width: 0; }
.room-title { font-size: 14px; color: #fff; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.room-title .mono { font-size: 12px; color: var(--acc); margin-left: 6px; }
.room-sub { font-size: 11px; color: #8f8ba8; margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.room-sub i { font-style: normal; color: #6d6a85; }
.room-item.empty { opacity: .6; }
.room-btns .btn.ghost.danger { color: #ff7d7d; }
.room-btns .btn.ghost.danger:hover { border-color: #ff5d5d; color: #ff5d5d; }
.room-btns { display: flex; gap: 6px; flex-shrink: 0; }

/* ===== 主布局 ===== */
#app { display: flex; flex-direction: column; height: 100vh; }
header {
  display: flex; justify-content: space-between; align-items: center;
  padding: 10px 16px; background: color-mix(in srgb, var(--panel) 96%, rgba(255,255,255,.03));
  border-bottom: 1px solid rgba(255,255,255,.08); flex-shrink: 0;
}
.brand { font-size: 15px; color: #fff; font-weight: 600; letter-spacing: .05em; }
.hdr-right { display: flex; align-items: center; gap: 10px; font-size: 13px; color: #a5a1c4; }

main { flex: 1; display: flex; min-height: 0; overflow: hidden; }

/* 舞台 */
#stage {
  flex: 1; position: relative; background:
    radial-gradient(ellipse at center, #14121f 0%, #08070d 100%);
  overflow: hidden; min-width: 0;
}

/* 背景层（铺满整个画面） */
#bgLayer { position: absolute; inset: 0; }
/* 背景图/视频绝对定位铺满：渐变切换时新旧两层可以叠在一起交叉淡入淡出 */
#bgLayer img, #bgLayer video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
/* 背景渐变切换：新背景淡入盖住旧背景，旧背景淡出后被移除 */
#bgLayer img.bg-fade-in, #bgLayer video.bg-fade-in { opacity: 0; transition: opacity .6s ease; }
#bgLayer img.bg-fade-in.bg-on, #bgLayer video.bg-fade-in.bg-on { opacity: 1; }
#bgLayer img.bg-fade-out, #bgLayer video.bg-fade-out { opacity: 0 !important; transition: opacity .6s ease; }
#sceneEmpty {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  color: #57536f; font-size: 15px; letter-spacing: .1em; text-align: center;
}
#sceneEmpty .moon { display: block; font-size: 42px; margin-bottom: 12px; animation: float 3s ease-in-out infinite; }
@keyframes float { 50% { transform: translateY(8px); } }

/* 前景层（叠在背景之上，可多张，自由摆放/缩放） */
#ovLayer {
  position: absolute; inset: 0;
  padding: 56px 64px 90px; pointer-events: none;
}
.ov-item {
  position: absolute; transform: translate(-50%, -50%);
  display: flex; flex-direction: column; align-items: center;
  pointer-events: auto; user-select: none; touch-action: none;
}
.ov-item img, .ov-item video {
  width: 100%; max-width: 100%; height: auto;
  max-height: calc(100vh - 180px);
  object-fit: contain;
  border-radius: 10px; box-shadow: 0 12px 60px rgba(0,0,0,.7);
  pointer-events: auto;
}
.ov-item .ov-close {
  position: absolute; top: 6px; right: 6px; z-index: 8;
  width: 30px; height: 30px; border-radius: 50%; border: 1px solid rgba(255,255,255,.25);
  background: rgba(10,9,18,.75); color: #e8e6f2; font-size: 14px; cursor: pointer;
  pointer-events: auto;
}
.ov-item .ov-close:hover { border-color: #ff5d5d; color: #ff5d5d; }
/* 玩家：收藏前景图到自己的记录区 */
.ov-item .ov-keep {
  position: absolute; top: 6px; right: 6px; z-index: 8;
  width: 30px; height: 30px; border-radius: 50%; border: 1px solid rgba(255,255,255,.25);
  background: rgba(10,9,18,.75); color: #e8e6f2; font-size: 13px; cursor: pointer;
  pointer-events: auto; padding: 0;
}
.ov-item .ov-keep:hover { border-color: var(--acc); color: var(--acc); }
.ov-cap { font-size: 12px; color: #e8e6f2; text-shadow: 0 1px 6px #000; margin-top: 4px; text-align: center; pointer-events: none; }

/* 前景操控手柄（仅主持人可见） */
.ov-move, .ov-resize {
  position: absolute; z-index: 9; width: 28px; height: 28px;
  border: 1px solid rgba(255,255,255,.3); border-radius: 50%;
  background: rgba(10,9,18,.8); color: var(--acc); font-size: 15px; line-height: 1;
  cursor: move; display: flex; align-items: center; justify-content: center;
  pointer-events: auto;
}
.ov-move { top: 6px; left: 6px; }
.ov-resize {
  right: -4px; bottom: -4px; cursor: nwse-resize;
  border-radius: 50%; font-size: 13px;
}
.ov-move:hover, .ov-resize:hover { border-color: var(--acc); background: rgba(60,47,20,.9); }
.ov-item.dragging { outline: 1px dashed color-mix(in srgb, var(--acc) 70%, transparent); outline-offset: 2px; border-radius: 10px; }

#sceneCaption {
  position: absolute; left: 0; right: 0; text-align: center;
  font-size: 14px; color: #e8e6f2; text-shadow: 0 1px 8px #000, 0 0 20px #000;
  padding: 0 24px; pointer-events: none; z-index: 6; top: 12px;
}

/* 掷骰结果卡片行：多玩家同时掷骰时水平排列，超出舞台宽度自动换行 */
#diceRow {
  position: absolute; left: 0; right: 0; top: 50%; transform: translateY(-50%);
  display: flex; flex-wrap: wrap; justify-content: center; align-items: flex-start;
  gap: 14px; pointer-events: none; z-index: 1180; padding: 0 60px;
}
.da-card {
  background: rgba(10,9,18,.9); border: 1px solid color-mix(in srgb, var(--acc) 45%, transparent);
  border-radius: 16px; padding: 14px 22px; min-width: 220px; max-width: 340px;
  text-align: center; animation: cardPop .28s ease-out;
  transition: opacity .45s ease;
}
.da-card.out { opacity: 0; }
@keyframes cardPop { from { transform: scale(.7); opacity: 0; } }
.t-who { font-size: 13px; color: #cfcbe4; }
.t-val { font-size: 46px; font-weight: 800; color: #fff; font-family: Georgia, "Times New Roman", serif; line-height: 1.15; }
.t-lv { font-size: 15px; font-weight: 700; }

.da-who {
  font-size: 13px; color: #cfcbe4; text-shadow: 0 1px 8px #000;
  margin-bottom: 14px; letter-spacing: .02em;
}
.da-dice { display: flex; align-items: flex-start; justify-content: center; gap: 14px; }
.die-wrap { display: flex; flex-direction: column; align-items: center; gap: 6px; }
.die {
  position: relative; width: 62px; height: 62px;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(145deg, #2a2440, #171328);
  border: 2px solid color-mix(in srgb, var(--acc) 55%, transparent); border-radius: 14px;
  box-shadow: 0 8px 30px rgba(0,0,0,.6), inset 0 1px 0 rgba(255,255,255,.08);
}
.die-num {
  font-size: 26px; font-weight: 800; color: #fff;
  font-family: Georgia, "Times New Roman", serif; line-height: 1;
  letter-spacing: -0.02em; padding: 0 2px;
}
.die-label { font-size: 11px; color: #a5a1c4; text-shadow: 0 1px 6px #000; }
.die.rolling {
  filter: blur(.4px);
  animation: tumble .5s ease-in-out infinite;
}
@keyframes tumble {
  0%   { transform: rotateX(0) rotateZ(0) scale(1); }
  25%  { transform: rotateX(28deg) rotateZ(-10deg) scale(1.07); }
  50%  { transform: rotateX(-18deg) rotateZ(8deg) scale(.97); }
  75%  { transform: rotateX(14deg) rotateZ(-6deg) scale(1.05); }
  100% { transform: rotateX(0) rotateZ(0) scale(1); }
}
/* 奖励骰：选用的数值高亮 */
.die.chosen {
  border-color: #ffd700;
  box-shadow: 0 0 0 3px rgba(255,215,0,.3), 0 0 26px rgba(255,215,0,.55);
  animation: chosenPulse .8s ease-out;
}
.die.chosen .die-num { color: #ffd700; }
@keyframes chosenPulse {
  0%   { box-shadow: 0 0 0 10px rgba(255,215,0,.45), 0 0 40px rgba(255,215,0,.8); }
  100% { box-shadow: 0 0 0 3px rgba(255,215,0,.3), 0 0 26px rgba(255,215,0,.55); }
}
/* 惩罚骰：不被使用的骰子碎裂淡出 */
.die.shatter {
  animation: shake .26s ease-in-out;
  border-color: #ff5d5d;
}
.die.shatter .die-num { color: #ff5d5d; }
@keyframes shake {
  0%,100% { transform: translateX(0); }
  20% { transform: translateX(-5px); }
  40% { transform: translateX(5px); }
  60% { transform: translateX(-4px); }
  80% { transform: translateX(4px); }
}
.die.shatter::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  background:
    linear-gradient(18deg, transparent 46%, rgba(255,255,255,.85) 49%, transparent 51%),
    linear-gradient(-32deg, transparent 44%, rgba(255,255,255,.7) 47%, transparent 49%),
    linear-gradient(60deg, transparent 48%, rgba(255,255,255,.6) 50%, transparent 52%);
  animation: crackIn .18s ease-out forwards;
}
@keyframes crackIn { from { opacity: 0; } to { opacity: 1; } }
.die .frag {
  position: absolute; left: 30%; top: 30%; width: 40%; height: 40%;
  background: #3a2f6a; border-radius: 3px;
  animation: fragFly .55s ease-out forwards; animation-delay: .22s; opacity: 0;
}
@keyframes fragFly {
  0%   { opacity: 1; transform: translate(0,0) rotate(0) scale(1); }
  100% { opacity: 0; transform: translate(var(--dx), var(--dy)) rotate(var(--rot)) scale(.4); }
}
.die.fade-out { opacity: 0; transition: opacity .28s; }
/* 最终结果 */
.da-result { margin-top: 16px; }
.da-val {
  font-size: 62px; font-weight: 800; color: #fff;
  font-family: Georgia, "Times New Roman", serif; line-height: 1;
  text-shadow: 0 2px 20px rgba(0,0,0,.8);
  animation: popIn .4s ease-out;
}
.da-lv { font-size: 16px; font-weight: 700; margin-top: 6px; }
@keyframes popIn { from { transform: scale(.5); opacity: 0; } to { transform: scale(1); opacity: 1; } }

/* 第四十八批：孤注一掷定格后的骰点特效（挂在骰子卡片上的覆盖层，不挡交互） */
.da-card { position: relative; }
.push-aura {
  position: absolute; inset: 0; border-radius: inherit; overflow: hidden;
  pointer-events: none; z-index: 2;
}
/* 成功：金色光晕从骰点处绽开 + 缓慢旋转的光束 */
.push-aura-win .pa-glow {
  position: absolute; left: 50%; top: 42px; width: 200px; height: 130px;
  transform: translate(-50%, -50%);
  background: radial-gradient(ellipse at center,
    rgba(255,225,120,.55) 0%, rgba(255,200,60,.28) 38%, rgba(255,190,50,0) 70%);
  filter: blur(4px);
  animation: paGlow 2.6s ease-out forwards;
}
@keyframes paGlow {
  0%   { opacity: 0; transform: translate(-50%,-50%) scale(.4); }
  18%  { opacity: 1; transform: translate(-50%,-50%) scale(1.12); }
  100% { opacity: .35; transform: translate(-50%,-50%) scale(1); }
}
.push-aura-win .pa-rays {
  position: absolute; left: 50%; top: 42px; width: 240px; height: 240px;
  transform: translate(-50%, -50%);
  background: repeating-conic-gradient(from 0deg,
    rgba(255,230,140,.30) 0deg 7deg, rgba(255,230,140,0) 7deg 30deg);
  -webkit-mask-image: radial-gradient(circle, rgba(0,0,0,.9) 0%, transparent 62%);
  mask-image: radial-gradient(circle, rgba(0,0,0,.9) 0%, transparent 62%);
  animation: paRays 5s linear infinite, paRaysIn 2.6s ease-out forwards;
  mix-blend-mode: screen;
}
@keyframes paRays { from { transform: translate(-50%,-50%) rotate(0); } to { transform: translate(-50%,-50%) rotate(360deg); } }
@keyframes paRaysIn { 0% { opacity: 0; } 22% { opacity: 1; } 100% { opacity: .45; } }
/* 失败：乌云从上压下盖住骰点，云团缓慢翻滚 + 阴影下沉 */
.push-aura-lose .pa-cloud {
  position: absolute; border-radius: 50%;
  background: radial-gradient(ellipse at 40% 35%, #3d3a52 0%, #262338 45%, rgba(20,18,32,0) 72%);
  filter: blur(3px); opacity: 0;
  animation: paCloudIn .9s ease-out forwards, paCloudDrift 4s ease-in-out infinite alternate;
}
.push-aura-lose .c1 { left: 8%;  top: -26px; width: 120px; height: 74px; }
.push-aura-lose .c2 { left: 36%; top: -38px; width: 150px; height: 88px; animation-delay: .08s; }
.push-aura-lose .c3 { left: 62%; top: -22px; width: 110px; height: 66px; animation-delay: .16s; }
@keyframes paCloudIn { from { opacity: 0; transform: translateY(-26px); } to { opacity: .95; transform: translateY(0); } }
@keyframes paCloudDrift { from { margin-left: -5px; } to { margin-left: 5px; } }
.push-aura-lose .pa-rain {
  position: absolute; left: 22%; right: 22%; top: 34px; height: 46px;
  background: repeating-linear-gradient(102deg,
    rgba(160,170,220,.32) 0 1.5px, transparent 1.5px 9px);
  -webkit-mask-image: linear-gradient(to bottom, rgba(0,0,0,.9), transparent);
  mask-image: linear-gradient(to bottom, rgba(0,0,0,.9), transparent);
  opacity: 0; animation: paRain 1.1s ease-out .35s forwards, paRainFall 1.6s linear .35s infinite;
}
@keyframes paRain { from { opacity: 0; } to { opacity: .8; } }
@keyframes paRainFall { from { transform: translateY(0); } to { transform: translateY(14px); } }
/* 额外骰数量 */
.extra-count {
  min-width: 22px; text-align: center; font-size: 16px; font-weight: 700;
  color: var(--acc); font-family: Georgia, serif;
}

/* 文字卡 */
#textCard {
  position: absolute; left: 50%; bottom: 24px; transform: translateX(-50%);
  width: min(92%, 640px); max-height: 55%; overflow-y: auto;
  background: linear-gradient(160deg, #f7ecd4, #e9d8b4); color: #3a2f1b;
  border-radius: 10px; padding: 18px 22px;
  box-shadow: 0 8px 40px rgba(0,0,0,.65);
  font-family: "Kaiti SC", "KaiTi", "STKaiti", serif;
  z-index: 1180;   /* 高于帷幕(1080)：遮罩时文字框仍显示 */
}
#textCard h3 { font-size: 18px; border-bottom: 1px dashed #b39b6a; padding-bottom: 6px; margin-bottom: 8px; }
.tc-keep { margin-top: 10px; }
.tc-body { white-space: pre-wrap; font-size: 16px; line-height: 1.75; }

/* 侧栏：导航固定在顶部，只有各页签的内容区滚动（翻记录不会把页签导航滚走） */
#side {
  width: 400px; flex-shrink: 0; display: flex; flex-direction: column;
  border-left: 1px solid rgba(255,255,255,.08); overflow: hidden; background: var(--panel);
}
#tabs {
  display: flex; position: sticky; top: 0; z-index: 5;
  background: var(--panel); border-bottom: 1px solid rgba(255,255,255,.08);
}
#tabs button {
  flex: 1; padding: 11px 4px; background: none; border: none; cursor: pointer;
  color: #8f8ba8; font-size: 14px; border-bottom: 2px solid transparent;
}
#tabs button.active { color: var(--acc); border-bottom-color: var(--acc); }
.tab-body { flex: 1; min-height: 0; overflow-y: auto; }

/* 主持面板内部子页签（舞台 / 房间） */
.gm-subtabs {
  display: flex; gap: 6px; padding: 8px 12px 0;
  position: sticky; top: 0; z-index: 4; background: var(--panel);
  border-bottom: 1px solid rgba(255,255,255,.08);
}
.gm-subtab {
  flex: 1; padding: 9px 4px; background: none; border: none; cursor: pointer;
  color: #8f8ba8; font-size: 13px; letter-spacing: .03em;
  border-bottom: 2px solid transparent;
  transition: color .15s ease, border-color .15s ease;
}
.gm-subtab:hover { color: #d8d5ef; }
.gm-subtab.active { color: var(--acc); border-bottom-color: var(--acc); }

.panel { padding: 14px; border-bottom: 1px solid rgba(255,255,255,.06); }
.panel h4 { font-size: 14px; color: var(--acc); margin-bottom: 10px; letter-spacing: .05em; }
.sub-h { font-size: 12px; color: #a5a1c4; margin: 10px 0 4px; }
.mono { font-family: Consolas, monospace; font-size: 12px; color: #77739a; }

/* 素材缩略图 */
.thumbs {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(74px, 1fr));
  gap: 6px; margin-top: 8px; max-height: 260px; overflow-y: auto;
}
.thumb-wrap { position: relative; }
.thumb {
  width: 100%; height: 58px; object-fit: cover; border-radius: 6px;
  cursor: pointer; border: 2px solid transparent; background: var(--card); display: block;
}
.thumb:hover { border-color: var(--acc); }

.media-list { display: flex; flex-direction: column; gap: 4px; margin-top: 6px; max-height: 230px; overflow-y: auto; }
.mi-wrap { position: relative; display: flex; align-items: stretch; }
.mi {
  flex: 1; min-width: 0; text-align: left; background: var(--card); color: #cfcbe4;
  border: 1px solid rgba(255,255,255,.07); border-radius: 6px;
  padding: 7px 10px; cursor: pointer; font-size: 13px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.mi:hover { border-color: var(--acc); }
.mi.cur { border-color: var(--acc); color: var(--acc); }
/* 音频条目里的子类别小标签 */
.mi-sub {
  font-style: normal; font-size: 10px; color: #77739a;
  background: #252238; border-radius: 3px; padding: 1px 5px; margin-left: 7px;
}
.mi-sub.uncls { color: #55516f; background: #1e1c2e; }
/* 音量归一增益标签：×0.5 压低 / ×2 提升 */
.mi-gain {
  font-style: normal; font-size: 10px; font-weight: 600;
  color: #8fd3a8; background: #1d3327; border-radius: 3px; padding: 1px 5px; margin-left: 5px;
}
.mi-gain.down { color: #d9b06a; background: #362b1c; }

/* 删除素材按钮 */
.del-btn {
  position: absolute; top: -6px; right: -6px; z-index: 3;
  width: 20px; height: 20px; border-radius: 50%;
  border: 1px solid rgba(255,255,255,.3); background: var(--card); color: #a5a1c4;
  font-size: 11px; line-height: 1; cursor: pointer; padding: 0;
  display: none; align-items: center; justify-content: center;
}
.thumb-wrap:hover .del-btn, .mi-wrap:hover .del-btn { display: flex; }
.del-btn:hover { background: #ff5d5d; color: #fff; border-color: #ff5d5d; }

/* 人物卡 */
.char-card { padding: 12px 14px; border-bottom: 1px solid rgba(255,255,255,.06); }
.char-head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.portrait { width: 48px; height: 48px; border-radius: 10px; object-fit: cover; background: #252238; flex-shrink: 0; }
.portrait.ph { display: flex; align-items: center; justify-content: center; font-size: 20px; color: var(--acc); }
.char-meta { flex: 1; min-width: 0; }
.char-name { font-size: 16px; font-weight: 600; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.char-sub { font-size: 11px; color: #77739a; }
.char-gm { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.owner-sel {
  background: var(--card); color: #e8e6f2; border: 1px solid rgba(255,255,255,.14);
  border-radius: 6px; padding: 3px 6px; font-size: 12px; max-width: 110px;
}

/* 在线玩家列表 */
.online-list { display: flex; flex-wrap: wrap; gap: 6px; }
.online-chip {
  display: inline-flex; align-items: center; gap: 5px;
  background: var(--card); color: #cfcbe4; border: 1px solid rgba(255,255,255,.12);
  border-radius: 20px; padding: 3px 10px 3px 4px; font-size: 12px;
}
.online-chip img { width: 20px; height: 20px; border-radius: 50%; object-fit: cover; }
.online-chip .oc-ph {
  width: 20px; height: 20px; border-radius: 50%; background: var(--card-hi); color: var(--acc);
  font-size: 10px; font-weight: 700; display: inline-flex; align-items: center; justify-content: center;
}
.online-chip i { font-style: normal; font-size: 9px; color: #1b1929; background: var(--acc); border-radius: 3px; padding: 1px 4px; font-weight: 700; }
.online-chip.gm { border-color: color-mix(in srgb, var(--acc) 50%, transparent); }

/* 主持人高亮开关（在线列表内）：☆ 未高亮 / ★ 已高亮 */
.online-chip .hl-toggle {
  border: none; background: transparent; color: #9b95bd;
  cursor: pointer; font-size: 13px; line-height: 1; padding: 0 2px; border-radius: 4px;
  transition: color .12s, transform .12s;
}
.online-chip .hl-toggle:hover { color: var(--acc); transform: scale(1.15); }
.online-chip .hl-toggle.on { color: var(--acc); text-shadow: 0 0 6px color-mix(in srgb, var(--acc) 60%, transparent); }

/* 角色编辑弹窗 */
.char-edit-box { width: min(94vw, 520px); }
.ce-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.ce-field { display: flex; flex-direction: column; gap: 3px; background: var(--card); border-radius: 8px; padding: 7px; }
.ce-field span { font-size: 11px; color: #77739a; }
.ce-field input { width: 100%; padding: 6px 8px; text-align: center; }
.ce-skill-list { display: flex; flex-direction: column; gap: 6px; margin-bottom: 6px; }

/* .st 属性串导入 */
.st-text, .ce-st textarea { width: 100%; resize: vertical; font-size: 12px; font-family: inherit; }
.ce-st { background: var(--card); border-radius: 8px; padding: 8px 10px; margin-bottom: 8px; }
.ce-st summary { cursor: pointer; font-size: 12px; color: #a5a1c4; user-select: none; }
.ce-st textarea { margin-top: 8px; }
.st-row { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.st-row .owner-sel { max-width: 130px; }
.ce-skill-row { display: flex; align-items: center; gap: 6px; }
.ce-skill-row .ce-sk-name { flex: 1; min-width: 0; }
.ce-skill-row .ce-sk-val { width: 70px; text-align: center; }
.ce-sk-del { flex-shrink: 0; }

.stat { display: flex; align-items: center; gap: 8px; margin-top: 7px; }
.s-lb { width: 36px; font-size: 12px; color: #a5a1c4; flex-shrink: 0; }
.bar { flex: 1; height: 6px; background: rgba(255,255,255,.08); border-radius: 3px; overflow: hidden; }
.bar i { display: block; height: 100%; border-radius: 3px; transition: width .4s; }
.s-hp .bar i { background: #e05656; }
.s-san .bar i { background: #4db6ac; }
.s-luck .bar i { background: var(--acc); }
.s-mp .bar i { background: #7986cb; }
.s-ctl { display: flex; align-items: center; gap: 3px; flex-shrink: 0; }
.mini {
  background: #252238; color: #e8e6f2; border: none; border-radius: 5px;
  width: 22px; height: 22px; cursor: pointer; font-size: 13px; line-height: 1;
}
.mini:hover { background: #34304e; }
.snum { width: 50px; padding: 2px 4px; text-align: center; font-size: 13px; }
.sep { color: #5b5779; }
.ro { color: #cfcbe4; font-size: 13px; min-width: 44px; text-align: center; }

/* 人物卡：属性 & 技能 */
.sec-h { font-size: 12px; color: #a5a1c4; margin: 12px 0 6px; letter-spacing: .04em; }
/* 属性/技能标题可点击展开收起（默认收起） */
.sec-toggle { cursor: pointer; user-select: none; display: flex; align-items: center; gap: 5px; }
.sec-toggle:hover { color: #d8d5ef; }
.sec-arrow { font-style: normal; font-size: 11px; color: #77739a; display: inline-block; transition: transform .15s ease; }
.sec-arrow.open { transform: rotate(90deg); color: var(--acc); }
.attr-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.attr { display: flex; flex-direction: column; align-items: center; gap: 2px; background: var(--card); border-radius: 6px; padding: 6px 4px; }
.attr .a-lb { font-size: 11px; color: #77739a; }
.attr .a-num { width: 100%; }
.attr.ro-attr .a-v { font-size: 14px; color: #e8e6f2; }
.skill-list { display: flex; flex-direction: column; gap: 4px; margin-bottom: 6px; }
.skill-row { display: flex; align-items: center; gap: 6px; }
.skill-row .sk-n { flex: 1; min-width: 0; font-size: 13px; color: #cfcbe4; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.skill-row .a-v { font-size: 13px; color: var(--acc); }
.skill-add { display: flex; gap: 6px; margin-top: 6px; }

/* 角色检定快捷按钮 */
.roll-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; margin-top: 8px; }
/* 技能检索 + 初始值技能折叠开关 */
.sk-tools { display: flex; align-items: center; gap: 6px; margin-top: 6px; }
.sk-tools #btnSkBase { flex-shrink: 0; white-space: nowrap; }
.qroll {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  background: var(--card); color: #e8e6f2; border: 1px solid rgba(255,255,255,.1);
  border-radius: 8px; padding: 7px 4px; cursor: pointer; font-size: 13px;
  transition: border-color .15s, color .15s;
}
.qroll i { font-style: normal; font-size: 11px; color: var(--acc); }
.qroll:hover { border-color: var(--acc); color: var(--acc); }

/* 骰子面板 */
.seg { display: flex; }
.seg .mode {
  flex: 1; background: var(--card); color: #a5a1c4;
  border: 1px solid rgba(255,255,255,.1); padding: 7px 0;
  cursor: pointer; font-size: 13px;
}
.seg .mode:first-child { border-radius: 8px 0 0 8px; }
.seg .mode:last-child { border-radius: 0 8px 8px 0; }
.seg .mode.active { background: color-mix(in srgb, var(--acc) 16%, #171425); color: var(--acc); border-color: var(--acc); }
.dice-btn {
  background: var(--card); color: #e8e6f2; border: 1px solid rgba(255,255,255,.12);
  border-radius: 8px; padding: 9px 0; flex: 1; min-width: 54px;
  cursor: pointer; font-size: 14px; transition: border-color .15s, color .15s;
}
.dice-btn:hover { border-color: var(--acc); color: var(--acc); }
.dlabel { color: #77739a; }

/* 日志 */
.roll-item {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 14px; border-bottom: 1px solid rgba(255,255,255,.05);
}
.r-main .big {
  font-size: 22px; font-weight: 700; color: #fff;
  min-width: 46px; display: inline-block; text-align: right;
  font-family: Georgia, serif;
}
.r-sub { flex: 1; font-size: 12px; color: #a5a1c4; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.r-who { color: var(--acc); }
.r-dice { color: #66628a; }
.r-dice b { color: var(--acc); font-weight: 700; }
.r-time { font-size: 11px; color: #66628a; flex-shrink: 0; }
.lv { font-weight: 700; }
.lv-crit { color: #ffd700; }
.lv-extreme { color: #c09bff; }
.lv-hard { color: #5aadff; }
.lv-regular { color: #6fce6f; }
.lv-fail { color: #9a96b3; }
.lv-fumble { color: #ff5d5d; }
.lvb-crit { background: rgba(255,215,0,.07); }
.lvb-fumble { background: rgba(255,93,93,.09); }

/* BGM 栏 */
#bgmBar {
  display: flex; align-items: center; gap: 10px; padding: 8px 16px;
  border-top: 1px solid rgba(255,255,255,.08); background: var(--panel); flex-shrink: 0;
}
#bgmName { flex: 0 1 auto; max-width: 200px; font-size: 13px; color: #a5a1c4; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#bgmBtns { display: flex; gap: 6px; flex-shrink: 0; }
#bgmProgress { display: flex; align-items: center; gap: 8px; flex: 1; min-width: 0; }
.bgm-t { font-size: 11px; color: #77739a; font-variant-numeric: tabular-nums; flex-shrink: 0; }
#bgmSeek { flex: 1; min-width: 0; accent-color: var(--acc); cursor: pointer; }
#bgmSeek:disabled { cursor: default; opacity: .6; }

/* ===== 聊天区（左侧） ===== */
#chat {
  width: 272px; flex-shrink: 0; display: flex; flex-direction: column;
  border-right: 1px solid rgba(255,255,255,.08); background: var(--panel);
  transition: margin-left .28s ease; min-width: 0;
}
#chat.collapsed { margin-left: -272px; }
.chat-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 12px; border-bottom: 1px solid rgba(255,255,255,.08); flex-shrink: 0;
}
.chat-title { font-size: 14px; color: var(--acc); font-weight: 600; }
.chat-list { flex: 1; overflow-y: auto; padding: 10px; display: flex; flex-direction: column; gap: 6px; }
.chat-msg { display: flex; flex-direction: row; align-items: flex-start; gap: 7px; background: var(--card); border-radius: 8px; padding: 7px 10px; max-width: 92%; align-self: flex-start; }
.chat-msg .cm-main { display: flex; flex-direction: column; min-width: 0; }
.cm-avatar { width: 28px; height: 28px; border-radius: 50%; object-fit: cover; flex: 0 0 28px; background: var(--card-hi); }
.cm-avatar.ph { display: inline-flex; align-items: center; justify-content: center; font-size: 12px; color: var(--acc); font-weight: 700; }
.chat-msg .cm-who { font-size: 11px; color: var(--acc); font-weight: 600; }
.chat-msg .cm-text { font-size: 13px; color: #e8e6f2; word-break: break-word; white-space: pre-wrap; margin: 1px 0; }
.chat-msg .cm-time { font-size: 10px; color: #66628a; align-self: flex-end; }
.chat-msg.mine { align-self: flex-end; background: var(--card-hi); }
.chat-input { display: flex; gap: 6px; padding: 10px; border-top: 1px solid rgba(255,255,255,.08); flex-shrink: 0; }
.chat-input input { flex: 1; min-width: 0; }

/* 66：展开/收起聊天/工作区按钮改为 fixed 定位 + 高 z-index，确保战斗轮激活时不被 stage 容器或 combatBoard 挡住 */
#chatExpand {
  position: fixed; left: 0; top: 50%; transform: translateY(-50%);
  z-index: 1500; width: 26px; height: 56px; border: 1px solid rgba(255,255,255,.15);
  border-left: none; border-radius: 0 8px 8px 0; background: rgba(18,16,28,.94);
  color: var(--acc); font-size: 14px; cursor: pointer; pointer-events: auto;
  display: flex; align-items: center; justify-content: center;
}
#chatExpand .badge {
  position: absolute; top: -6px; right: -6px; min-width: 16px; height: 16px;
  border-radius: 8px; background: #ff5d5d; color: #fff; font-size: 10px; line-height: 16px;
  padding: 0 3px; text-align: center;
}
#chatExpand .badge:empty { display: none; }

/* 收起时新消息短暂悬浮的气泡（队列：最多 3 条，旧的被向上挤，超时渐隐） */
#chatPeekStack {
  position: absolute; left: 10px; bottom: 90px; z-index: 12;
  display: flex; flex-direction: column; gap: 6px; max-width: 270px;
  pointer-events: none;
}
.peek-bubble {
  background: rgba(20,18,32,.96); border: 1px solid color-mix(in srgb, var(--acc) 50%, transparent);
  border-radius: 10px; padding: 8px 12px;
  display: flex; align-items: flex-start; gap: 7px;
  animation: peekIn .28s ease-out;
  opacity: 1; transition: opacity .45s ease, transform .45s ease;
}
.peek-bubble.out { opacity: 0; transform: translateY(8px); }
.peek-bubble .cm-avatar { width: 22px; height: 22px; flex-basis: 22px; font-size: 10px; }
.peek-main { min-width: 0; }
@keyframes peekIn { from { transform: translateX(-16px); opacity: 0; } }
.peek-who { display: block; font-size: 11px; color: var(--acc); font-weight: 600; }
.peek-text { font-size: 13px; color: #e8e6f2; word-break: break-word; }
.cm-kp, .peek-kp {
  display: inline-block; font-size: 9px; line-height: 1; color: #1b1929; background: var(--acc);
  border-radius: 3px; padding: 2px 4px; margin-left: 4px; font-weight: 700; vertical-align: 1px;
}

/* 批量归类 */
.bulk-assign { display: flex; align-items: center; gap: 6px; margin: 8px 0; flex-wrap: wrap; }
.bulk-sel {
  background: var(--card); color: #e8e6f2; border: 1px solid rgba(255,255,255,.14);
  border-radius: 6px; padding: 4px 8px; font-size: 13px;
}

/* 素材分类 chips */
.cats-row { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.cat-chip {
  background: var(--card); color: #a5a1c4; border: 1px solid rgba(255,255,255,.12);
  border-radius: 20px; padding: 4px 12px; cursor: pointer; font-size: 12px;
}
.cat-chip.active { background: color-mix(in srgb, var(--acc) 16%, #171425); color: var(--acc); border-color: var(--acc); }
.cat-chip.cat-add { color: var(--acc); }
.cnt { color: #77739a; font-size: 11px; }

/* 归类按钮 */
.tag-btn {
  position: absolute; top: -6px; left: -6px; z-index: 3;
  width: 20px; height: 20px; border-radius: 50%;
  border: 1px solid rgba(255,255,255,.3); background: var(--card); color: #a5a1c4;
  font-size: 11px; line-height: 1; cursor: pointer; padding: 0;
  display: none; align-items: center; justify-content: center;
}
.thumb-wrap:hover .tag-btn, .mi-wrap:hover .tag-btn { display: flex; }
.tag-btn:hover { background: var(--acc); color: #1b1929; border-color: var(--acc); }

/* ===== 记录区（私人工作台页签：文本条目 + 收藏图片） ===== */
.note-toolbar {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 10px 14px; border-bottom: 1px solid rgba(255,255,255,.08);
  position: sticky; top: 0; background: var(--panel); z-index: 5;
}
.note-card {
  margin: 10px 14px; background: var(--card); border: 1px solid rgba(255,255,255,.08);
  border-radius: 10px; padding: 10px;
}
.note-card-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px; }
.note-img {
  width: 100%; max-height: 172px; object-fit: contain; display: block;
  border-radius: 8px; background: #0b0a12; cursor: zoom-in;
}
/* 第五十批：视频记录卡片（背景/前景视频收藏）——可播放，不做灯箱放大 */
.note-vid { cursor: default; max-height: 240px; }
.note-text, .note-caption {
  width: 100%; resize: vertical; font-size: 13px; line-height: 1.5;
  color: #e8e6f2; background: transparent; border: 1px solid transparent;
  min-height: 44px; border-radius: 6px; padding: 6px 8px;
  transition: background .15s, border-color .15s;
}
.note-caption { margin-top: 6px; min-height: 34px; }
/* 非编辑态：透明无边框，看起来像普通文字；鼠标悬停给轻微提示 */
.note-text:hover, .note-caption:hover { background: rgba(255,255,255,.04); }
/* 聚焦（编辑态）：才显示可编辑的深色输入框 */
.note-text:focus, .note-caption:focus {
  outline: none; background: #0b0a12; border-color: rgba(255,255,255,.2);
}

/* 文本线索卡片：正文是既定事实（只读），玩家在下方加注释 */
.note-clue { border-left: 3px solid var(--acc); }
.note-clue-text {
  white-space: pre-wrap; word-break: break-word;
  font-size: 14px; line-height: 1.7; color: #f0ecd8;
  background: rgba(255,255,255,.03); border: 1px solid rgba(255,255,255,.07);
  border-radius: 8px; padding: 9px 11px;
}
.note-note { margin-top: 6px; min-height: 34px; }

/* 第四十八批：线索卡下「＋添加我的注释」按钮（居中，虚线描边引导点击） */
.note-clue-add {
  display: block; margin: 10px auto 0; min-width: 150px;
  border: 1px dashed color-mix(in srgb, var(--acc) 55%, transparent);
  color: var(--acc); background: rgba(255,255,255,.02);
}
.note-clue-add:hover { background: color-mix(in srgb, var(--acc) 12%, transparent); }
/* 线索卡内各玩家的注释区（复用图片组的多人文本区布局） */
.note-clue .note-personas { margin-top: 8px; }

/* 收藏后定位到新记录时的高亮闪烁 */
@keyframes noteFlash {
  0%, 45% { box-shadow: 0 0 0 2px var(--acc); background: color-mix(in srgb, var(--acc) 12%, var(--card)); }
  100% { box-shadow: 0 0 0 2px transparent; }
}
.note-flash { animation: noteFlash 1.8s ease; }

/* ===== 角色库（大厅） ===== */
.hero-item {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  background: var(--card); border: 1px solid rgba(255,255,255,.1);
  border-radius: 8px; padding: 8px 10px; margin-bottom: 6px;
}
.hero-info { display: flex; flex-direction: column; min-width: 0; }
.hero-info b { font-size: 14px; color: #e8e6f2; }
.hero-info .hint { margin-top: 2px; }
.hero-btns { display: flex; gap: 6px; flex-shrink: 0; }
.pick-opt {
  display: flex; align-items: center; gap: 9px; padding: 9px 10px;
  background: var(--card); border: 1px solid rgba(255,255,255,.1);
  border-radius: 8px; margin-bottom: 6px; cursor: pointer; font-size: 14px;
}
.pick-opt:has(input:checked) { border-color: var(--acc); background: var(--card-hi); }
.pick-opt input { accent-color: var(--acc); flex-shrink: 0; }
.pick-opt span { min-width: 0; }
.pick-opt b { margin-right: 6px; }
.pick-opt i { font-style: normal; color: #77739a; font-size: 12px; }

/* 人物页：带入角色入口 / 待批准横幅 */
.hero-bring {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 10px 14px; border-bottom: 1px solid rgba(255,255,255,.06);
}
.hero-pending {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 10px 14px; font-size: 13px; color: var(--acc);
  background: color-mix(in srgb, var(--acc) 8%, transparent); border-bottom: 1px solid color-mix(in srgb, var(--acc) 25%, transparent);
}

/* GM 面板：入场申请 */
.pend-item {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  background: var(--card); border: 1px solid color-mix(in srgb, var(--acc) 35%, transparent);
  border-radius: 8px; padding: 8px 10px; margin-top: 6px;
}
.pend-info { display: flex; flex-direction: column; min-width: 0; }
.pend-info b { font-size: 13px; color: #e8e6f2; }
.pend-btns { display: flex; gap: 6px; flex-shrink: 0; }

/* 已展示前景列表 */
.ov-active { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.ov-active-item { display: flex; align-items: center; gap: 4px; background: var(--card); border-radius: 6px; padding: 3px 6px 3px 10px; font-size: 12px; color: #cfcbe4; }
.ov-active-item .oa-cap { max-width: 120px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* 归类弹窗选项 */
.cat-options { display: flex; flex-wrap: wrap; gap: 8px; }
.cat-opt {
  background: var(--card); color: #e8e6f2; border: 1px solid rgba(255,255,255,.14);
  border-radius: 8px; padding: 8px 14px; cursor: pointer; font-size: 13px;
}
.cat-opt.active { border-color: var(--acc); color: var(--acc); background: var(--card-hi); }
.cat-opt:hover { border-color: var(--acc); }

/* 弹窗 */
#pickerModal, #catModal, #confirmModal, #renameModal, #charEditModal,
#heroLibModal, #heroEditModal, #heroPickModal, #audioCatModal, #themeModal,
#createPassModal, #npcEditModal, #npcLibModal, #combatPickerModal {
  position: fixed; inset: 0; background: rgba(0,0,0,.65); z-index: 50;
  display: flex; align-items: center; justify-content: center;
}
/* 确认弹窗需要盖过其它弹窗（比如角色库），否则确认按钮点不到 */
#confirmModal { z-index: 85; }

/* 自定义音量滑块：纯 pointer 事件驱动（app.js），指针 / thumb / fill 共用 .vol-track 坐标系，
   保证滑块与鼠标指针严格对齐、速率一致；不叠加透明原生 range（其 thumb 行程与容器宽度不一致会导致错位） */
#volWrap {
  position: relative;
  width: 90px;
  height: 20px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  cursor: pointer;
  touch-action: none;      /* 触屏拖动不触发页面滚动 */
  border-radius: 10px;
  outline: none;
}
#volWrap:focus-visible { box-shadow: 0 0 0 2px var(--acc); }
#volWrap .vol-track {
  position: relative;      /* thumb / fill 的定位基准 */
  flex: 1;
  height: 4px;
  border-radius: 2px;
  background: rgba(255,255,255,.18);
}
#volWrap .vol-fill {
  position: absolute;
  left: 0; top: 0;
  height: 100%;
  width: calc(var(--v, 70) * 1%);
  max-width: 100%;
  background: var(--acc);
  border-radius: 2px;
}
#volWrap .vol-thumb {
  position: absolute;
  left: calc(var(--v, 70) * 1%);
  top: 50%;
  transform: translate(-50%, -50%);
  width: 12px; height: 12px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 4px rgba(0,0,0,.4);
  pointer-events: none;    /* 命中始终落到 wrap，避免 thumb 挡住点击 */
}
/* 音量数字输入（与滑轨等价，所见百分比 = 实际增益） */
#volNumWrap {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  gap: 2px;
  font-size: 11px;
  color: #9b95bd;
  margin-left: 4px;
}
#volNum {
  width: 38px;
  padding: 2px 3px;
  font-size: 11px;
  text-align: right;
  background: rgba(255,255,255,.07);
  border: 1px solid rgba(255,255,255,.14);
  border-radius: 6px;
  color: var(--fg);
  outline: none;
}
#volNum:focus { border-color: var(--acc); }
#volNum::-webkit-outer-spin-button, #volNum::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
#volNum[type="number"] { -moz-appearance: textfield; appearance: textfield; }
@media (max-width: 900px) {
  #volWrap { width: 64px; }
}

.modal-box {
  width: min(92vw, 560px); max-height: 80vh; overflow-y: auto;
  background: color-mix(in srgb, var(--panel) 90%, #161425); border: 1px solid rgba(255,255,255,.12);
  border-radius: 14px; padding: 18px;
}
.modal-box h4 { color: var(--acc); margin-bottom: 6px; font-size: 15px; }
.modal-box h4::before {
  content: ''; width: 3px; height: 14px; border-radius: 2px;
  margin-right: 7px;
  background: var(--acc); box-shadow: 0 0 8px color-mix(in srgb, var(--acc) 60%, transparent);
  display: inline-block; vertical-align: -2px;
}
.modal-box .thumbs { max-height: 55vh; }

/* 确认弹窗 */
.confirm-box { width: min(92vw, 380px); }
.cf-msg { color: #cfcbe4; font-size: 14px; line-height: 1.6; word-break: break-word; white-space: pre-wrap; }
.cf-check {
  display: flex; align-items: center; gap: 7px; margin-top: 12px;
  color: #a5a1c4; font-size: 13px; cursor: pointer; user-select: none;
}
.cf-check input { width: 16px; height: 16px; accent-color: var(--acc); cursor: pointer; }

/* 浮层提示 */
#flash {
  position: fixed; bottom: 64px; left: 50%; transform: translateX(-50%);
  background: rgba(20,18,32,.96); border: 1px solid color-mix(in srgb, var(--acc) 45%, transparent);
  color: #e8e6f2; padding: 8px 18px; border-radius: 20px; font-size: 13px;
  z-index: 99; opacity: 0; transition: opacity .25s; pointer-events: none;
}
#flash.show { opacity: 1; }

/* ===== 鼠标指针共享 ===== */
#btnPointer.active {
  background: color-mix(in srgb, var(--acc) 16%, #171425); border-color: var(--acc); color: var(--acc);
}
/* 其他玩家的指针层：盖在前景之上、控件之下，不拦截鼠标 */
#ptrLayer {
  position: absolute; inset: 0; z-index: 11; pointer-events: none;
}
.ptr {
  position: absolute; transform: translate(-50%, -50%);
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  opacity: .78;                       /* 半透明，避免遮挡场景 */
  pointer-events: none;
  filter: drop-shadow(0 2px 4px rgba(0,0,0,.55));
  transition: left .1s linear, top .1s linear;   /* 与 100ms 高频轮询衔接，指针补间顺滑跟手 */
}
.ptr-arrow { width: 22px; height: 22px; display: block; }
.ptr-name {
  font-size: 10px; line-height: 1; padding: 1px 7px; border-radius: 8px;
  background: rgba(12,10,20,.72); color: currentColor;
  border: 1px solid color-mix(in srgb, currentColor 45%, transparent);
  max-width: 96px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* 高亮玩家层：被主持人高亮的玩家头像+名称持续展示在画面中，主持人可拖动位置/缩放（默认约 100px） */
#highlightDock {
  position: absolute; inset: 0; z-index: 1150; pointer-events: none;  /* 高于帷幕(1080)：帷幕合拢时在场人物仍可见 */
  transition: opacity .35s ease;
}
/* 第五十三批：帷幕合拢期间在玩家端同步隐藏高亮玩家（与舞台一起被遮）；GM 端不受影响 */
#highlightDock.masked {
  opacity: 0;
  visibility: hidden;     /* 同时关掉交互与拖拽，避免舞台看不见却还能点 */
}
.hl-chip {
  position: absolute; transform: translate(-50%, -50%);
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  pointer-events: auto; user-select: none; touch-action: none;
  animation: hl-in .25s ease;
}
.hl-chip .cm-avatar {
  width: 100%; height: auto; aspect-ratio: 1 / 1; flex: 0 0 auto; border-radius: 50%;
  border: 3px solid var(--acc);
  box-shadow: 0 6px 20px rgba(0,0,0,.55);
  object-fit: cover;
}
.hl-chip .cm-avatar.ph {
  display: flex; align-items: center; justify-content: center;
  background: var(--card); color: var(--acc); font-size: 38px; font-weight: 700;
}
.hl-name {
  background: rgba(20,18,32,.9); border: 1px solid color-mix(in srgb, var(--acc) 40%, transparent);
  color: #e8e6f2; font-size: 13px; padding: 2px 12px; border-radius: 12px;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* 主持人操控手柄（仅主持人可见）：移动 + 缩放，悬停/拖拽时显示 */
.hl-chip .hl-ctl {
  position: absolute; z-index: 9; width: 26px; height: 26px;
  border: 1px solid rgba(255,255,255,.3); border-radius: 50%;
  background: rgba(10,9,18,.8); color: var(--acc); font-size: 14px; line-height: 1;
  cursor: move; display: flex; align-items: center; justify-content: center;
  pointer-events: auto; opacity: 0; visibility: hidden;
  transition: opacity .15s ease, visibility .15s ease;
}
.hl-chip .hl-move { top: -2px; left: -2px; }
.hl-chip .hl-resize { right: -6px; bottom: -6px; cursor: nwse-resize; font-size: 13px; }
/* 第六十批：右上角关闭按钮（取消高亮） */
.hl-chip .hl-close {
  top: -2px; right: -2px; cursor: pointer; font-size: 13px;
  background: rgba(212,66,66,.85); color: #fff; border-color: rgba(255,200,200,.5);
}
.hl-chip .hl-close:hover { background: rgba(232,90,90,1); border-color: #fff; }
.hl-chip:hover .hl-ctl, .hl-chip.dragging .hl-ctl, .hl-chip:focus-within .hl-ctl {
  opacity: 1; visibility: visible;
}
.hl-chip .hl-move:hover, .hl-chip .hl-resize:hover { border-color: var(--acc); background: rgba(60,47,20,.9); }
.hl-chip.dragging { outline: 1px dashed color-mix(in srgb, var(--acc) 70%, transparent); outline-offset: 2px; border-radius: 10px; }
/* 第六十批：NPC 高亮 vs 玩家高亮视觉区别
   玩家：青色边框（沿用默认 .cm-avatar 边框）
   NPC ：紫红边框 + 紫红渐变面板 + 三角角标（区别一目了然） */
.hl-chip.kind-npc .cm-avatar {
  border-color: #ff8d8d;
  box-shadow: 0 6px 20px rgba(212,66,66,.45), 0 0 0 2px rgba(255,141,141,.35);
}
.hl-chip.kind-npc .hl-name {
  background: linear-gradient(180deg, rgba(212,66,66,.85) 0%, rgba(120,30,30,.9) 100%);
  border-color: #ff8d8d; color: #fff;
  font-weight: 700; letter-spacing: .04em;
}
.hl-chip.kind-npc .hl-tag {
  font-size: 9px; font-weight: 900;
  background: #d44242; color: #fff;
  padding: 1px 6px; border-radius: 3px;
  border: 1px solid rgba(255,200,200,.5);
  box-shadow: 0 1px 4px rgba(0,0,0,.5);
}
@keyframes hl-in {
  from { transform: translate(-50%, -50%) scale(.9); opacity: 0; }
  to   { transform: translate(-50%, -50%) scale(1); opacity: 1; }
}

/* 场景收藏按钮（玩家把主持人展示的背景收入记录区） */
#sceneKeep {
  position: absolute; right: 14px; bottom: 14px; z-index: 12;
  background: rgba(20,18,32,.88); color: var(--acc);
  border: 1px solid color-mix(in srgb, var(--acc) 45%, transparent); border-radius: 20px;
  padding: 6px 14px; font-size: 12px; cursor: pointer;
  transition: background .15s, border-color .15s;
}
#sceneKeep:hover { background: color-mix(in srgb, var(--acc) 16%, #171425); border-color: var(--acc); }

/* ===== 聊天：表情面板 / 图片消息 / 大表情 ===== */
#emojiPanel {
  display: grid; grid-template-columns: repeat(8, 1fr); gap: 2px;
  padding: 8px; border-top: 1px solid rgba(255,255,255,.08);
  background: var(--panel);
}
.emoji-btn {
  background: transparent; border: none; border-radius: 6px;
  font-size: 20px; padding: 4px 2px; cursor: pointer; line-height: 1;
}
.emoji-btn:hover { background: #252238; }
.cm-img {
  max-width: 100px; max-height: 100px; border-radius: 8px;
  display: block; margin-top: 4px; cursor: zoom-in;
  border: 1px solid rgba(255,255,255,.1);
}
.cm-text.emoji { font-size: 30px; line-height: 1.25; letter-spacing: 2px; }

/* ===== 记录区：共享 + 子页签 ===== */
#noteTabs { padding: 8px 14px 0; }
.note-card.readonly { opacity: .92; }
.note-readonly {
  color: #cfcbe4; font-size: 13px; line-height: 1.6;
  white-space: pre-wrap; word-break: break-word; padding: 2px 0;
}

/* ===== 掷骰：加值修正 ===== */
.r-mod {
  color: #7ec8a9; font-size: 11px; font-style: normal;
  border: 1px solid rgba(126,200,169,.4); border-radius: 3px;
  padding: 1px 5px; margin-left: 4px;
}
.da-mod { color: #7ec8a9; font-size: 15px; margin-top: 2px; }
/* 玩家检定的自身能力值展示（主持人投掷不显示） */
.da-tgt { color: #8ab4d8; font-size: 14px; margin-top: 2px; }

/* ===== 第八批 ===== */
/* 同图合并记录：图下多玩家文本区 */
.note-group .note-img { margin-bottom: 4px; }
.note-personas { display: flex; flex-direction: column; gap: 8px; }
.note-persona { border-top: 1px dashed rgba(255,255,255,.12); padding-top: 6px; }
.note-persona:first-child { border-top: none; padding-top: 0; }
.note-persona .note-card-head { margin-bottom: 4px; }
.note-persona .note-caption { margin-top: 0; }

/* 图片放大预览（灯箱） */
#imgViewer {
  position: fixed; inset: 0; z-index: 80; background: rgba(4,3,8,.88);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 12px; cursor: zoom-out;
}
#imgViewer img { max-width: 92vw; max-height: 82vh; border-radius: 10px; box-shadow: 0 24px 90px rgba(0,0,0,.85); }
#imgViewer .iv-hint { color: #a5a1c4; font-size: 12px; letter-spacing: .08em; }
/* 灯箱顶部标题：显示该图的记录命名（无命名则隐藏） */
#imgViewerTitle {
  max-width: min(720px, 92vw); color: #f0d9a0; font-size: 15px; font-weight: 600;
  letter-spacing: .02em; text-align: center; padding: 6px 14px;
  background: rgba(18,16,28,.6); border: 1px solid rgba(255,255,255,.12); border-radius: 8px;
  cursor: default;
}
/* 灯箱带批注时：图缩小一点，下方滚动展示所有玩家的批注记录 */
#imgViewer.has-notes img { max-height: 54vh; }
#imgViewerNotes {
  max-width: min(720px, 92vw); max-height: 26vh; overflow-y: auto;
  display: flex; flex-direction: column; gap: 8px;
  background: rgba(18,16,28,.92); border: 1px solid rgba(255,255,255,.12);
  border-radius: 10px; padding: 10px 14px; cursor: default;
}
#imgViewer.has-notes #imgViewerNotes:empty { display: none; }
.iv-note b { color: var(--acc); font-size: 13px; margin-right: 8px; }
.iv-note .hint { font-size: 11px; }
.iv-note p { margin: 2px 0 0; color: #e6e3f5; font-size: 13px; line-height: 1.55; white-space: pre-wrap; word-break: break-word; }

/* 顶栏：当前在线（全员可见，可折叠） */
#onlineBar {
  display: flex; align-items: center; gap: 10px; flex-shrink: 0;
  padding: 5px 16px; background: var(--panel);
  border-bottom: 1px solid rgba(255,255,255,.08);
  min-height: 0; overflow: hidden;
}
#btnOnlineToggle {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 4px;
  background: none; border: none; color: #a5a1c4; font-size: 13px;
  cursor: pointer; padding: 2px 4px; white-space: nowrap;
}
#btnOnlineToggle:hover { color: var(--acc); }
#btnOnlineToggle i { font-style: normal; display: inline-block; transition: transform .2s; font-size: 11px; }
#onlineBar .online-list { display: flex; flex-wrap: wrap; gap: 6px; }
#onlineBar .online-list .hint { padding: 2px 0; }
#onlineBar.collapsed .online-list { display: none; }
#onlineBar.collapsed #btnOnlineToggle i { transform: rotate(-90deg); }

/* 暗骰标记 */
.r-dark, .da-dark {
  font-style: normal; font-size: 11px; color: #c9a7e8;
  border: 1px solid rgba(160,110,220,.45); border-radius: 3px;
  padding: 1px 5px; margin-left: 4px; background: rgba(120,70,190,.12);
}
.da-card.roll-dark .t-val, .roll-item.roll-dark .r-main { color: #c9a7e8; }

/* 聊天名字后的角色特殊状态后缀 */
.cm-st {
  font-size: 10px; color: #e88; margin-left: 4px;
  border: 1px solid rgba(230,110,110,.4); border-radius: 3px; padding: 0 4px;
  background: rgba(190,60,60,.12);
}
.peek-who .cm-st { margin-left: 2px; }

/* 未绑定人物的玩家（游客）后缀 */
.cm-guest {
  font-size: 10px; color: #9b95bd; margin-left: 3px;
}
.peek-who .cm-guest { margin-left: 2px; }

/* 聊天名字后的实时血量徽标（X/Y）：按剩余血量比例上色（绿→黄→红） */
.cm-hp {
  display: inline-block; font-size: 10px; line-height: 1; margin-left: 4px;
  border-radius: 3px; padding: 2px 5px; font-weight: 700; vertical-align: 1px;
  font-variant-numeric: tabular-nums;
}
.cm-hp.ok  { color: #7ddb8f; background: rgba(80,180,100,.14); border: 1px solid rgba(110,200,130,.35); }
.cm-hp.mid { color: #e6c86a; background: rgba(200,160,60,.14); border: 1px solid rgba(220,190,90,.38); }
.cm-hp.low { color: #ee8a8a; background: rgba(190,60,60,.16); border: 1px solid rgba(230,110,110,.45); }
.peek-who .cm-hp { margin-left: 2px; }

/* 右侧工作区收起 */
#side {
  position: relative;
  transition: width .28s ease, min-width .28s ease, border-color .28s ease;
}
#side.collapsed { width: 0; min-width: 0; border-left-color: transparent; overflow: hidden; }
#tabs #btnSideCollapse {
  flex: 0 0 auto; margin-left: auto; margin-right: 8px; align-self: center;
  width: 26px; height: 26px; background: none; border: 1px solid rgba(255,255,255,.15);
  border-radius: 6px; color: #77739a; font-size: 15px; line-height: 1; cursor: pointer;
  padding: 0; border-bottom: 2px solid transparent;
}
#tabs #btnSideCollapse:hover { color: var(--acc); border-color: color-mix(in srgb, var(--acc) 50%, transparent); }
#sideExpand {
  position: fixed; right: 0; top: 50%; transform: translateY(-50%);
  z-index: 1500; width: 30px; height: 64px; border: 1px solid rgba(255,255,255,.15);
  border-right: none; border-radius: 8px 0 0 8px; background: rgba(18,16,28,.94);
  color: var(--acc); font-size: 15px; cursor: pointer; pointer-events: auto;
  display: flex; align-items: center; justify-content: center;
}
#sideExpand:hover { background: color-mix(in srgb, var(--acc) 16%, #171425); border-color: color-mix(in srgb, var(--acc) 50%, transparent); }

/* 前景操控按钮（仅主持人）：鼠标未指向该前景时隐藏，悬停/拖拽时显示 */
.ov-item .ov-ctl {
  opacity: 0; visibility: hidden;
  transition: opacity .15s ease, visibility .15s ease;
}
.ov-item:hover .ov-ctl, .ov-item.dragging .ov-ctl, .ov-item:focus-within .ov-ctl {
  opacity: 1; visibility: visible;
}

/* 前景可见开关（左下角，仅主持人） */
.ov-item .ov-vis {
  position: absolute; left: 6px; bottom: 6px; z-index: 9;
  border: 1px solid rgba(126,200,169,.55); border-radius: 12px;
  background: rgba(10,9,18,.85); color: #7ec8a9; font-size: 11px;
  padding: 3px 10px; cursor: pointer; pointer-events: auto; white-space: nowrap;
}
.ov-item .ov-vis.off { border-color: rgba(255,120,120,.55); color: #ff9a9a; }
.ov-item .ov-vis:hover { background: rgba(60,47,20,.9); }

/* 仅主持人可见的前景：半透明 + 红色虚线框提示 */
.ov-item.ov-hidden img, .ov-item.ov-hidden video { opacity: .45; }
.ov-item.ov-hidden { outline: 1px dashed rgba(255,120,120,.55); outline-offset: 4px; border-radius: 10px; }

/* ===== 移动端 ===== */
@media (max-width: 900px) {
  main { flex-direction: column; overflow: visible; }
  #stage { min-height: 38vh; flex-shrink: 0; }
  #side { width: 100%; flex: 1; border-left: none; border-top: 1px solid rgba(255,255,255,.08); }
  .brand { font-size: 13px; }
  #playerCount { display: none; }
  #bgmName { max-width: 90px; }
  .t-val { font-size: 36px; }
  .die { width: 46px; height: 46px; border-radius: 10px; }
  .die-num { font-size: 19px; }
  .da-val { font-size: 44px; }
  .da-card { min-width: 150px; max-width: 260px; padding: 10px 14px; }
  #diceRow { padding: 0 12px; gap: 8px; }
  /* 聊天改为左侧抽屉 */
  #chat { position: fixed; left: 0; top: 0; bottom: 0; width: 85vw; max-width: 300px; z-index: 40; border-right: 1px solid rgba(255,255,255,.08); transition: transform .28s ease; }
  #chat.collapsed { margin-left: 0; transform: translateX(-100%); }
  #chatExpand { position: fixed; left: 0; top: 50%; z-index: 1030; }
  #chatPeekStack { position: fixed; left: 10px; bottom: 90px; z-index: 45; }
}

/* ===== 第九批 ===== */
/* 聊天系统消息（状态变化等）：居中一行 */
.cm-sys {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  margin: 8px 4px; font-size: 12.5px; color: color-mix(in srgb, var(--acc) 72%, #fff);
}
.cm-sys::before, .cm-sys::after {
  content: ''; flex: 1; height: 1px;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--acc) 35%, transparent), transparent);
}
.cm-sys i { font-style: normal; font-size: 11px; color: #6f6a8a; flex: 0 0 auto; }

/* 人物卡 COC 状态区 */
.status-row {
  display: flex; align-items: center; flex-wrap: wrap; gap: 6px;
  margin: 6px 0 2px; padding: 7px 10px;
  background: rgba(255,110,110,.06); border: 1px solid rgba(255,110,110,.16);
  border-radius: 10px;
}
.status-row .st-lb { font-size: 12px; color: #c9a7a7; flex: 0 0 auto; }
.status-row .st-list { display: flex; flex-wrap: wrap; gap: 5px; flex: 1; }
.st-pill {
  display: inline-flex; align-items: center; gap: 4px;
  background: rgba(255,110,110,.16); color: #ff9a9a;
  border: 1px solid rgba(255,110,110,.4); border-radius: 999px;
  font-size: 12px; font-weight: 600; padding: 2px 9px; line-height: 1.5;
}
.st-pill .st-x {
  border: none; background: none; color: #ff9a9a; font-size: 10px;
  cursor: pointer; padding: 0 0 0 2px; opacity: .7;
}
.st-pill .st-x:hover { opacity: 1; color: #fff; }
.st-add { display: inline-flex; align-items: center; gap: 5px; }
.st-add select, .st-add input.st-custom {
  background: rgba(255,255,255,.07); color: #e8e6f2;
  border: 1px solid rgba(255,255,255,.14); border-radius: 7px;
  font-size: 12px; padding: 3px 6px; max-width: 110px;
}
.st-add input.st-custom { max-width: 76px; }

/* 在线列表：玩家名（人物名） */
.online-chip .oc-char { font-style: normal; font-size: 11px; color: #9b95bd; margin-left: 2px; }

/* ===== 窗体背景 + 美化 ===== */
#themeModal .row { flex-wrap: wrap; }
#frameBgOpacity { flex: 1; min-width: 120px; accent-color: var(--acc); }
#frameBgOpacityVal { min-width: 44px; text-align: right; }
.theme-bg-row { display: flex; gap: 8px; flex-wrap: wrap; }

/* 窗体背景开启时：四周窗体改为半透明（仍带主题底色），透出本地背景图（中央舞台不受影响） */
body.has-framebg header { background: color-mix(in srgb, var(--panel) 78%, transparent); }
body.has-framebg #onlineBar,
body.has-framebg #chat,
body.has-framebg #tabs,
body.has-framebg #bgmBar,
body.has-framebg .note-toolbar,
body.has-framebg #emojiPanel { background: color-mix(in srgb, var(--panel) 84%, transparent); }
body.has-framebg #side { background: color-mix(in srgb, var(--panel) 84%, transparent); }
body.has-framebg .chat-msg { background: color-mix(in srgb, var(--card) 62%, transparent); }
body.has-framebg .chat-msg.mine { background: color-mix(in srgb, var(--card-hi) 66%, transparent); }
body.has-framebg .note-card { background: color-mix(in srgb, var(--card) 66%, transparent); }
body.has-framebg #lobby { background: color-mix(in srgb, var(--panel) 66%, transparent); }

/* 整体美化 */
.brand { text-shadow: 0 1px 10px rgba(0,0,0,.45); }
#tabs button { transition: color .15s ease, border-color .15s ease; }
#tabs button:hover { color: #d8d5ef; }
.panel h4 { display: flex; align-items: center; gap: 7px; }
.panel h4::before {
  content: ''; width: 3px; height: 14px; border-radius: 2px;
  background: var(--acc); box-shadow: 0 0 8px color-mix(in srgb, var(--acc) 60%, transparent);
}
.modal-box { box-shadow: 0 30px 90px rgba(0,0,0,.6); }
.btn.ghost:hover { background: rgba(255,255,255,.06); }
/* 第五十九批：克苏鲁风格切换按钮高亮态 */
.btn.small.active-curse {
  background: linear-gradient(180deg, #2a1340 0%, #3a1a55 100%);
  border-color: rgba(180, 110, 220, .55);
  color: rgba(220, 195, 240, .95);
  box-shadow: 0 0 10px rgba(160, 70, 200, .35);
}
/* 第六十一批：奈亚风格切换按钮高亮态（黑金火焰） */
.btn.small.active-nyar {
  background: linear-gradient(180deg, #2a1206 0%, #452008 100%);
  border-color: rgba(230, 150, 60, .55);
  color: rgba(255, 220, 170, .95);
  box-shadow: 0 0 10px rgba(230, 140, 50, .35);
}
.cat-chip, .qroll, .dice-btn, .mi { transition: border-color .15s ease, color .15s ease, background .15s ease; }
.online-chip { transition: border-color .15s ease; }
.online-chip:hover { border-color: color-mix(in srgb, var(--acc) 45%, transparent); }

/* ===== 第二十六批：我的角色页签 / 角色锁定 / 详情窗口 / 前景悬浮置顶 ===== */
/* 锁定标记 */
.lock-tag { font-size: 11px; color: #d9a94e; border: 1px solid rgba(217, 169, 78, .4); border-radius: 6px; padding: 2px 7px; }
.char-foot { display: flex; margin-top: 8px; }

/* 我的角色页签（复用 ce-grid / skill-row 等既有样式） */
.mine-panel .char-head { margin-bottom: 4px; }
.bio-grid { grid-template-columns: repeat(2, 1fr); }

/* 角色详情窗口：独立浮动窗，可拖右下角缩放、可关闭 */
#charDetailLayer { position: fixed; inset: 0; z-index: 70; pointer-events: none; }
.cd-win {
  position: absolute; left: 80px; top: 64px;
  width: min(560px, 90vw); height: min(640px, 84vh);
  min-width: 320px; min-height: 260px;
  background: var(--panel); border: 1px solid rgba(255,255,255,.14); border-radius: 12px;
  box-shadow: 0 18px 50px rgba(0,0,0,.55);
  display: flex; flex-direction: column;
  pointer-events: auto;
  resize: both; overflow: hidden;
}
.cd-win .cd-head {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 10px 12px; border-bottom: 1px solid rgba(255,255,255,.1);
  background: var(--card); border-radius: 12px 12px 0 0;
  cursor: move; user-select: none; touch-action: none;
}
.cd-win .cd-head .cd-title { font-weight: 600; font-size: 14px; flex: 1; }
.cd-win .cd-close { flex-shrink: 0; }
.cd-body { flex: 1; overflow-y: auto; padding: 12px; }
.cd-stats { font-size: 13px; color: var(--acc); }
.cd-skills { display: flex; flex-wrap: wrap; gap: 6px; margin: 4px 0; }
.cd-skill { background: var(--card); border: 1px solid rgba(255,255,255,.08); border-radius: 6px; padding: 3px 8px; font-size: 12px; color: #cfcbe4; }
.cd-skill b { color: var(--acc); margin-left: 2px; }
.cd-skill.dim { opacity: .5; }
.cd-base summary { cursor: pointer; font-size: 12px; color: #a5a1c4; margin: 6px 0 2px; user-select: none; }
.cd-info-row { display: flex; gap: 8px; margin: 4px 0; font-size: 13px; line-height: 1.5; }
.cd-il { color: #a5a1c4; flex-shrink: 0; }
.cd-iv { color: #cfcbe4; word-break: break-all; white-space: pre-wrap; }
/* 携带物品/法术两列并排；背景故事每两个字段一行（两列）——缩短窗口纵向长度 */
.cd-two-col, .cd-bio-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 4px 14px; }
.cd-cell { background: var(--card); border: 1px solid rgba(255,255,255,.06); border-radius: 8px; padding: 6px 8px; min-height: 40px; }
.cd-cell-lb { color: #a5a1c4; font-size: 12px; }
.cd-cell-v { color: #cfcbe4; white-space: pre-wrap; word-break: break-all; font-size: 13px; line-height: 1.5; margin-top: 2px; }

/* 前景素材：鼠标悬浮时临时置顶，便于观看与点击被遮挡的下层素材 */
#ovLayer .ov-item:hover { z-index: 900; }
/* 指针指向某前景操控按钮时选中的前景（被遮挡的下层按钮同样能命中）：
   层级须高于 :hover 的 900，否则与同时命中 :hover 的上层前景同为 900、仍被 DOM 靠后的它压住 */
#ovLayer .ov-item.ov-top { z-index: 950; }

/* ===== 第三十四批：角色编辑弹窗只能按钮关闭 / 带入申请提前 + 页签角标 ===== */
/* 角色编辑表单内容多，误点背景不应丢失输入：遮罩点击已移除，改用右上角关闭按钮 */
.modal-box { position: relative; }
.char-edit-box h4 { padding-right: 38px; }
.modal-x {
  position: absolute; top: 10px; right: 12px; z-index: 5;
  width: 30px; height: 30px; border-radius: 50%; padding: 0;
  border: 1px solid rgba(255,255,255,.25); background: rgba(10,9,18,.75);
  color: #e8e6f2; font-size: 13px; line-height: 1; cursor: pointer;
}
.modal-x:hover { border-color: var(--acc); color: var(--acc); }

/* 主持页签：有待处理的带入申请时高亮 + 数字角标（非当前页签时呼吸闪烁提醒） */
#tabs button.tab-alert { color: var(--acc); border-bottom-color: var(--acc); }
#tabs button.tab-alert:not(.active) { animation: tabPulse 1.8s ease-in-out infinite; }
@keyframes tabPulse { 50% { box-shadow: 0 -2px 12px color-mix(in srgb, var(--acc) 45%, transparent); } }
.tab-badge {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 16px; height: 16px; margin-left: 5px; padding: 0 4px;
  border-radius: 999px; background: var(--acc); color: #1b1929;
  font-size: 11px; font-weight: 700; line-height: 1; vertical-align: 1px;
}

/* ===== 第二十七批：确认弹窗层级 / 音量条 / 锁定样式 / 职业 / 货币单位 ===== */
/* 锁定后「我的角色」页签禁用态：变灰、无边框光晕 */
.mine-panel input:disabled,
.mine-panel textarea:disabled,
.mine-panel button:disabled {
  background: rgba(255,255,255,.04) !important;
  color: #7a7796 !important;
  border-color: rgba(255,255,255,.08) !important;
  cursor: not-allowed;
}
.mine-panel input:disabled::placeholder,
.mine-panel textarea:disabled::placeholder { color: #5d5a73; }
/* 货币单位后缀 */
.money-field { position: relative; }
.money-field input { padding-right: 38px; }
.money-field .money-unit {
  position: absolute; right: 8px; top: 50%; transform: translateY(-50%);
  font-size: 11px; color: #9b95bd; pointer-events: none; user-select: none;
}
/* 人物卡职业标签 */
/* 职业标签：跟随角色名称（名称行内），药丸形小一号 */
.char-name .job-tag {
  flex-shrink: 0;
  font-size: 11px;
  font-weight: 500;
  line-height: 1.5;
  padding: 0 8px;
  border-radius: 999px;
  letter-spacing: .5px;
  max-width: 110px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.job-tag {
  display: inline-block;
  background: color-mix(in srgb, var(--acc) 18%, transparent);
  color: var(--acc);
  border: 1px solid color-mix(in srgb, var(--acc) 35%, transparent);
  border-radius: 6px;
  padding: 1px 7px;
  font-size: 11px;
  vertical-align: middle;
}


/* ===== 第三十六批：麦克风说话检测（高亮头像闪烁绿光） ===== */
/* 被主持人高亮 + 麦克风检测到声音：头像边框绿光呼吸闪烁（仅本地音量检测，无语音传输） */
.hl-chip.speaking .cm-avatar {
  border-color: #35e07a;
  animation: hl-speak .8s ease-in-out infinite;
}
@keyframes hl-speak {
  0%, 100% { box-shadow: 0 0 0 0 rgba(53,224,122,0), 0 6px 20px rgba(0,0,0,.55); }
  50%      { box-shadow: 0 0 20px 7px rgba(53,224,122,.8), 0 6px 20px rgba(0,0,0,.55); }
}

/* ===== 第三十六批：孤注一掷 ===== */
/* 检定失败后的确认悬浮窗（场景内，约 10 秒；鼠标悬浮暂停倒计时） */
#pushOffer {
  position: absolute; left: 50%; bottom: 96px; transform: translateX(-50%);
  z-index: 960; width: min(400px, 88%);
  background: rgba(26,15,19,.97);
  border: 1px solid #a4324b; border-radius: 12px;
  padding: 12px 14px 10px;
  box-shadow: 0 10px 34px rgba(0,0,0,.65), 0 0 0 1px rgba(255,80,110,.12);
  animation: po-in .25s ease;
}
#pushOffer.out { opacity: 0; transform: translateX(-50%) translateY(10px); transition: opacity .3s ease, transform .3s ease; }
#pushOffer .po-title { font-weight: 700; color: #ff7d95; font-size: 14px; }
#pushOffer .po-info { color: #e8e6f2; font-size: 13px; margin-top: 3px; }
#pushOffer .po-hint { color: #a9a4c4; font-size: 11px; margin-top: 5px; line-height: 1.55; }
#pushOffer .po-bar { height: 4px; border-radius: 2px; background: rgba(255,255,255,.12); margin: 9px 0; overflow: hidden; }
#pushOffer .po-bar i { display: block; height: 100%; width: 100%; background: linear-gradient(90deg, #ff5d7e, #ffb14d); }
#pushOffer.paused { border-color: #3ecf82; }
#pushOffer.paused .po-bar i { background: #6fe0a0; }
#pushOffer .po-btns { display: flex; gap: 8px; }
#pushOffer .po-btns .btn { flex: 1; }
#pushOffer .po-tip { text-align: center; color: #77729c; font-size: 10px; margin-top: 7px; }
@keyframes po-in {
  from { opacity: 0; transform: translateX(-50%) translateY(12px); }
}

/* 孤注一掷全屏书法动画：四个大字 + 「！」逐个砸出（pointer-events:none 不挡操作） */
#pushFx {
  position: fixed; inset: 0; z-index: 300; pointer-events: none;
  display: flex; align-items: center; justify-content: center;
  background: rgba(10,4,8,.55);
}
#pushFx.out { opacity: 0; transition: opacity .45s ease; }
#pushFx .pf-row { display: flex; gap: 2.5vw; }
#pushFx .pf-g {
  font-family: "STKaiti", "KaiTi", "楷体", "LiSu", "SimSun", serif;
  font-size: clamp(64px, 13vw, 180px); font-weight: 900; line-height: 1;
  color: #f5efe6;
  text-shadow: 0 0 24px rgba(255,70,90,.55), 0 5px 12px rgba(0,0,0,.85);
  opacity: 0; transform: scale(2.6) rotate(-7deg);
}
#pushFx .pf-g:nth-child(5) { color: #ff4d5e; }
#pushFx .pf-g.in { animation: pf-in .32s cubic-bezier(.2, 1.5, .4, 1) forwards; }
@keyframes pf-in {
  from { opacity: 0; transform: scale(2.6) rotate(-7deg); }
  to   { opacity: 1; transform: scale(1) rotate(0deg); }
}

/* 掷骰记录 / 结果卡片中的孤注一掷标记与文案 */
.r-push {
  display: inline-block; margin-right: 2px; padding: 0 6px;
  border-radius: 999px; font-size: 10px; font-weight: 700;
  color: #ffb3c0; background: rgba(214,60,60,.22);
  border: 1px solid rgba(214,60,60,.55);
}
.da-push { text-align: center; font-size: 12px; font-weight: 700; color: #ff7d95; margin-top: 2px; }

/* 「我的角色」孤注一掷剩余次数提示 */
.mine-push {
  margin: 6px 0 2px; padding: 4px 10px; border-radius: 8px;
  background: rgba(214,60,60,.10); border: 1px solid rgba(214,60,60,.30);
  color: #ffb3c0; font-size: 11.5px;
}

/* ===== 第三十八批：记录命名 / 高亮悬停 / 游客限制 / 聊天动作 ===== */
/* 全局悬停提示框（记录命名 / 高亮人物 HP·SAN·MP）：跟随鼠标，不拦截鼠标事件 */
#nameTip {
  position: fixed; z-index: 999; pointer-events: none;
  max-width: 340px; padding: 6px 11px; border-radius: 8px;
  background: rgba(18,16,28,.94); border: 1px solid rgba(255,255,255,.18);
  color: #f0edfb; font-size: 12px; line-height: 1.5;
  box-shadow: 0 6px 20px rgba(0,0,0,.45);
}
/* 标题行：单行不换行（命名 / HP·SAN·MP） */
#nameTip .nt-title { white-space: nowrap; }
/* 注释副行（第四十一批）：在标题下方，可换行，带浅色上分隔 */
#nameTip .nt-sub {
  margin-top: 4px; padding-top: 4px; border-top: 1px dashed rgba(255,255,255,.18);
  color: #c7c2e2; white-space: normal; word-break: break-word;
}

/* 记录卡上的命名行（所有玩家可见、可编辑）：与下方记录之间留 3px 间隔 */
.note-name-row {
  display: flex; align-items: center;
  margin-top: 6px; margin-bottom: 3px; padding-top: 6px; border-top: 1px dashed rgba(255,255,255,.12);
}
/* 未编辑态：纯文本展示，命名后居中；暖金色标题字，灰色占位表示可点击命名 */
.note-name-view {
  flex: 1; min-width: 0; padding: 5px 8px;
  font-size: 13px; font-weight: 600; letter-spacing: .02em;
  text-align: center; cursor: pointer; border-radius: 6px;
  color: #f0d9a0; line-height: 1.4; transition: background .12s ease, color .12s ease;
}
.note-name-view:hover { background: rgba(255,255,255,.06); color: #ffe3b0; }
.note-name-view.empty { color: #7a748f; font-style: italic; font-weight: 400; }
/* 编辑态输入框（与展示区同宽、文字居中） */
.note-name {
  flex: 1; min-width: 0; padding: 5px 8px; font-size: 13px; font-weight: 600; letter-spacing: .02em;
  text-align: center; border-radius: 6px; background: #0b0a12;
  border: 1px solid rgba(255,255,255,.14); color: #f0d9a0;
}
.note-name:focus { border-color: var(--acc); }

/* 游客发言：文字颜色默认灰色 */
.chat-msg.guest .cm-text { color: #9b95bd; }

/* 动作消息：显示「名字 + 动作文案」，文案用斜体金色强调 */
.chat-msg.act .cm-act { color: #f2d689; font-style: italic; }
/* 第四十五批：动作消息附带的表情（比正文稍大，跟在名字后面、正文前面） */
.cm-act-emoji { margin-right: 4px; font-size: 1.18em; font-style: normal; }

/* 过滤游客按钮：激活态高亮 */
#btnFilterGuests .fg-label { font-size: 10px; margin-left: 2px; opacity: .8; }
#btnFilterGuests.active {
  color: #ffd27d; border-color: rgba(255,210,125,.6);
  background: rgba(255,210,125,.12);
}

/* 聊天动作面板：网格排列的常用动作按钮 */
#actPanel {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px;
  padding: 10px; border-top: 1px solid rgba(255,255,255,.08);
  background: var(--panel); max-height: 240px; overflow-y: auto;
}
.act-btn {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  background: rgba(255,255,255,.04); border: 1px solid rgba(255,255,255,.10);
  border-radius: 8px; padding: 7px 4px 6px; cursor: pointer;
  font-size: 20px; line-height: 1; color: #e8e6f2;
  transition: background .15s, border-color .15s, transform .1s;
}
.act-btn span { font-size: 11px; color: #cfcbe4; }
.act-btn:hover { background: #252238; border-color: rgba(255,255,255,.25); }
.act-btn:active { transform: translateY(1px); }
body.has-framebg #actPanel { background: color-mix(in srgb, var(--panel) 84%, transparent); }

/* ===== 第四十批：遮罩 + 界面特效 ===== */
/* 界面特效层：盖在背景/前景/高亮之上、文字框之下 */
#fxLayer {
  position: absolute; inset: 0; z-index: 1000; pointer-events: none; overflow: hidden;
}
#fxLayer .fx { position: absolute; inset: 0; pointer-events: none; }

/* 第四十五批：闪光特效（FPS 闪光弹式）——第四十六批改为只作用于舞台展示区：
   不再用 fixed 冲出舞台，跟随 #fxLayer（absolute inset:0）盖住展示区即可，
   瞬间全白后缓慢淡出（约 3.4s 恢复）。 */
#fxLayer .fx.fx-flash {
  background: radial-gradient(ellipse at center, #ffffff 0%, #f5f7ff 55%, #e9edff 100%);
  animation: fxFlash 3.4s ease-out forwards;
}
@keyframes fxFlash {
  0%   { opacity: 1; }
  15%  { opacity: 1; }   /* 全白保持约 0.5 秒 */
  100% { opacity: 0; }   /* 再慢慢恢复视野 */
}

/* 遮罩层：舞台帷幕。盖住一切视觉层、文字框之下；仅非主持人可见。
   打开（合拢）时左右幕布向中间展开，关闭时从中央向两边拉开。 */
#maskLayer {
  position: absolute; inset: 0; z-index: 1080; pointer-events: none;  /* 第五十九批：帷幕优先级高于战斗轮(990)，盖住整个舞台（包括战斗轮） */
  overflow: hidden;
  display: flex; align-items: center; justify-content: center;
}
/* 帷幕合拢时拦截鼠标：玩家指向幕后物件不会触发可记录信息的悬停展开 */
#maskLayer.on { pointer-events: auto; }
/* 左右两片幕布：深红剧院风，带褶皱与底部流苏 */
.mask-curtain {
  position: absolute; top: 0; bottom: 0; width: 50.6%;
  background:
    repeating-linear-gradient(90deg,
      rgba(0,0,0,.22) 0 12px, rgba(255,255,255,.06) 12px 18px,
      rgba(0,0,0,.14) 18px 30px, rgba(0,0,0,0) 30px 46px),
    linear-gradient(100deg, #5c0b10, #9c1a21 46%, #771016 100%);
  box-shadow: inset 0 0 90px rgba(0,0,0,.62);
  transition: transform .9s cubic-bezier(.55,.05,.35,.95);
}
.mask-curtain-l { left: 0; transform: translateX(-102%); border-right: 3px solid rgba(255,213,130,.5); }
.mask-curtain-r { right: 0; transform: translateX(102%); border-left: 3px solid rgba(255,213,130,.5); }
/* 底部流苏：一排下垂的锯齿 */
.mask-curtain::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: -1px; height: 24px;
  background:
    linear-gradient(45deg, transparent 68%, #8f161d 68%) 0 0/20px 20px repeat-x,
    linear-gradient(-45deg, transparent 68%, #8f161d 68%) 0 0/20px 20px repeat-x;
  opacity: .92;
}
#maskLayer.on .mask-curtain-l { transform: translateX(0); }
#maskLayer.on .mask-curtain-r { transform: translateX(0); }
/* 中央提示：幕布合拢后淡入 */
#maskLayer .mask-hint {
  position: relative; z-index: 2;
  font-size: 22px; letter-spacing: .12em; color: rgba(255,232,180,.85);
  text-shadow: 0 0 18px rgba(255,210,120,.28), 0 2px 6px rgba(0,0,0,.65);
  user-select: none; padding: 10px 28px; border-radius: 30px;
  background: rgba(22,8,8,.4); opacity: 0; transition: opacity .35s ease;
}
/* 第六十四批：切换文案时淡出，过渡结束后改文本再淡入（300ms/300ms） */
#maskLayer .mask-hint.hint-fading { opacity: 0 !important; transition: opacity .3s ease !important; }
#maskLayer.on .mask-hint { opacity: 1; transition-delay: .5s; }

/* ============================================================
   第五十九批：遮罩双模式 —— 默认剧院红幕 + 可切换克苏鲁风格
   .mode-curse 挂在 #maskLayer 上，整片舞台变成"召唤不可名状之物"的帷幕：
   - 颜色基调：深海蓝紫 → 血红夕照
   - 中央大眼（SVG）+ 触手剪影（径向渐变叠层）
   - 顶部旧印符 + 底部羊皮纸感的边缘
   - 入场动效改成"雾降"（fade + 微缩放），不再横移
   ============================================================ */
/* 中央克苏鲁大眼 SVG（始终渲染，闭合状态 opacity 0，开启淡入） */
#maskLayer .mask-eye {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  z-index: 3; opacity: 0; transition: opacity .8s ease .35s;
  pointer-events: none; user-select: none;
  width: 220px; height: 220px;
  display: none;  /* 默认剧院模式下隐藏；mode-curse 时显示 */
}
#maskLayer.mode-curse .mask-eye { display: block; }
#maskLayer .mask-eye svg { width: 100%; height: 100%; display: block; }
#maskLayer.on.mode-curse .mask-eye { opacity: .88; animation: eyePulse 6s ease-in-out infinite; }
@keyframes eyePulse {
  0%, 100% { transform: translate(-50%, -50%) scale(1);    filter: drop-shadow(0 0 16px rgba(220, 180, 80, .55)); }
  50%      { transform: translate(-50%, -50%) scale(1.04); filter: drop-shadow(0 0 28px rgba(220, 180, 80, .85)); }
}
#maskLayer .mask-tentacle {
  position: absolute; pointer-events: none; opacity: 0;
  transition: opacity .9s ease .2s;
  background-repeat: no-repeat;
}
/* 仅克苏鲁模式启用触手视觉 */
#maskLayer.mode-curse .mask-tentacle {
  display: block;
}
#maskLayer:not(.mode-curse) .mask-tentacle { display: none; }
/* 左侧触手：从左下角伸入 */
#maskLayer .mask-tentacle.t-l {
  left: -40px; bottom: -20px; width: 280px; height: 380px;
  background:
    radial-gradient(ellipse 60px 90px at 30% 90%, rgba(40, 12, 70, .8) 0%, rgba(20, 6, 35, 0) 70%),
    radial-gradient(ellipse 40px 110px at 55% 80%, rgba(40, 12, 70, .75) 0%, rgba(20, 6, 35, 0) 75%),
    radial-gradient(ellipse 32px 130px at 75% 75%, rgba(40, 12, 70, .7) 0%, rgba(20, 6, 35, 0) 78%);
  filter: drop-shadow(0 0 12px rgba(140, 60, 180, .35));
}
#maskLayer .mask-tentacle.t-r {
  right: -40px; top: -20px; width: 280px; height: 380px;
  background:
    radial-gradient(ellipse 60px 90px at 70% 10%, rgba(40, 12, 70, .8) 0%, rgba(20, 6, 35, 0) 70%),
    radial-gradient(ellipse 40px 110px at 45% 20%, rgba(40, 12, 70, .75) 0%, rgba(20, 6, 35, 0) 75%),
    radial-gradient(ellipse 32px 130px at 25% 25%, rgba(40, 12, 70, .7) 0%, rgba(20, 6, 35, 0) 78%);
  filter: drop-shadow(0 0 12px rgba(140, 60, 180, .35));
}
#maskLayer.on .mask-tentacle { opacity: .85; }
#maskLayer.on .mask-tentacle.t-l { animation: tentacleSwayL 9s ease-in-out infinite; }
#maskLayer.on .mask-tentacle.t-r { animation: tentacleSwayR 11s ease-in-out infinite; }
@keyframes tentacleSwayL {
  0%,100% { transform: translate(0, 0) rotate(0deg); }
  50%     { transform: translate(8px, -10px) rotate(2deg); }
}
@keyframes tentacleSwayR {
  0%,100% { transform: translate(0, 0) rotate(0deg); }
  50%     { transform: translate(-6px, 8px) rotate(-2deg); }
}
/* ---- 剧院红幕（默认）继续使用 .mask-curtain 既有样式，下面定义克苏鲁覆盖 ---- */

/* ---- 克苏鲁风格：深海蓝紫 + 大眼 + 触手（保留剧院滑入动效，仅替换视觉） ---- */
#maskLayer.mode-curse .mask-curtain {
  background:
    radial-gradient(circle at 12% 78%, rgba(140, 40, 180, .42) 0%, transparent 22%),
    radial-gradient(circle at 88% 24%, rgba(150, 50, 190, .42) 0%, transparent 22%),
    radial-gradient(circle at 8% 28%, rgba(110, 30, 150, .35) 0%, transparent 18%),
    radial-gradient(circle at 92% 76%, rgba(110, 30, 150, .35) 0%, transparent 18%),
    radial-gradient(ellipse at 50% 50%, rgba(20, 6, 38, .94) 0%, rgba(6, 2, 14, .98) 65%, rgba(2, 0, 6, 1) 100%),
    linear-gradient(180deg, #0a0418 0%, #1c0a2a 50%, #2a0518 100%);
  box-shadow:
    inset 0 0 130px rgba(80, 20, 120, .55),
    inset 0 0 250px rgba(0, 0, 0, .88);
}
/* 印符：顶部一条横向不规则符号链（伪克苏鲁印符） */
#maskLayer.mode-curse .mask-curtain::before {
  content: '𐰀 𐰁 𐰂 𐰃 𐰄 𐰅 𐰆 𐰇 𐰈 𐰉 𐰊 𐰋 𐰌 𐰍 𐰎 𐰏';
  position: absolute; left: 0; right: 0; top: 8%;
  display: block; text-align: center; pointer-events: none;
  font-family: serif; font-size: 22px; letter-spacing: 14px; line-height: 1;
  color: rgba(180, 110, 220, .35);
  text-shadow: 0 0 8px rgba(140, 60, 180, .45);
  opacity: .8;
}
#maskLayer.mode-curse .mask-curtain::after {
  /* 底部血红光带 —— 模拟"旧日支配者的注视透过裂缝" */
  background:
    linear-gradient(180deg,
      rgba(160, 30, 30, 0) 0%,
      rgba(160, 30, 30, .35) 35%,
      rgba(120, 20, 20, .5) 60%,
      rgba(80, 10, 10, .35) 100%),
    repeating-linear-gradient(90deg,
      transparent 0 18px, rgba(0,0,0,.4) 18px 22px);
  height: 38%;
  top: auto; bottom: 0;
  opacity: .55;
}
/* 中央文字：克苏鲁版本 */
#maskLayer.mode-curse .mask-hint {
  position: relative; z-index: 4;
  font-size: 18px; letter-spacing: .15em; color: rgba(220, 195, 240, .9);
  font-family: "Kaiti SC", "KaiTi", "STKaiti", serif;
  text-shadow:
    0 0 14px rgba(180, 80, 220, .55),
    0 0 24px rgba(120, 40, 160, .35),
    0 2px 6px rgba(0, 0, 0, .8);
  background: none;
  padding: 14px 36px;
  border-top: 1px solid rgba(180, 110, 220, .35);
  border-bottom: 1px solid rgba(180, 110, 220, .35);
  border-radius: 0;
  margin-top: 16px;
}
/* 主持人端「遮罩中」小徽标（主持人看不到遮罩，靠它提示） */
#maskGmHint {
  position: absolute; top: 12px; left: 50%; transform: translateX(-50%);
  z-index: 1190; padding: 4px 14px; border-radius: 14px;
  background: rgba(0,0,0,.6); border: 1px solid rgba(255,210,125,.5);
  color: #ffd27d; font-size: 12px; pointer-events: none;
}

/* ============================================================
   第六十一批：奈亚拉托提普主题帘幕（.mode-nyar 挂在 #maskLayer 上）
   视觉基调：漆黑帷幕 + 底部暗焰 + 金色法老符文 + 中央咧嘴大笑面具
   - 颜色：纯黑 → 暗红余烬（比克苏鲁更黑、更"狂乱"）
   - 中央装饰：千面之神的咧嘴面具 SVG（新月笑眼 + 齿排 + 法老双翼）
   - 两侧底部：暗焰舔动（flicker 摇曳）
   - 顶部：埃及圣书体金色符文行（黑法老）
   - 动效：面具 facePulse 脉动 + 火焰 flameFlicker
   ============================================================ */
/* 中央咧嘴面具（始终渲染，非奈亚模式隐藏） */
#maskLayer .mask-face {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  z-index: 3; opacity: 0; transition: opacity .8s ease .35s;
  pointer-events: none; user-select: none;
  width: 230px; height: 230px;
  display: none;  /* 默认隐藏；mode-nyar 时显示 */
}
#maskLayer.mode-nyar .mask-face { display: block; }
#maskLayer .mask-face svg { width: 100%; height: 100%; display: block; }
#maskLayer.on.mode-nyar .mask-face { opacity: .92; animation: facePulse 5s ease-in-out infinite; }
@keyframes facePulse {
  0%, 100% { transform: translate(-50%, -50%) scale(1)    rotate(0deg);  filter: drop-shadow(0 0 16px rgba(255, 140, 60, .5)); }
  50%      { transform: translate(-50%, -50%) scale(1.05) rotate(1.2deg); filter: drop-shadow(0 0 30px rgba(255, 150, 60, .85)); }
}
/* 两侧底部暗焰（非奈亚模式隐藏） */
#maskLayer .mask-flame {
  position: absolute; pointer-events: none; opacity: 0;
  transition: opacity .9s ease .2s;
  background-repeat: no-repeat;
  display: none;
}
#maskLayer.mode-nyar .mask-flame { display: block; }
#maskLayer .mask-flame.f-l {
  left: -30px; bottom: -30px; width: 320px; height: 420px;
  background:
    radial-gradient(ellipse 70px 200px at 25% 100%, rgba(200, 80, 20, .55) 0%, rgba(60, 15, 5, 0) 65%),
    radial-gradient(ellipse 44px 240px at 50% 95%, rgba(230, 110, 30, .5) 0%, rgba(60, 15, 5, 0) 70%),
    radial-gradient(ellipse 30px 160px at 72% 100%, rgba(160, 60, 15, .45) 0%, rgba(50, 12, 4, 0) 72%);
  filter: drop-shadow(0 0 14px rgba(230, 110, 40, .4));
}
#maskLayer .mask-flame.f-r {
  right: -30px; bottom: -30px; width: 320px; height: 420px;
  background:
    radial-gradient(ellipse 70px 200px at 75% 100%, rgba(200, 80, 20, .55) 0%, rgba(60, 15, 5, 0) 65%),
    radial-gradient(ellipse 44px 240px at 50% 95%, rgba(230, 110, 30, .5) 0%, rgba(60, 15, 5, 0) 70%),
    radial-gradient(ellipse 30px 160px at 28% 100%, rgba(160, 60, 15, .45) 0%, rgba(50, 12, 4, 0) 72%);
  filter: drop-shadow(0 0 14px rgba(230, 110, 40, .4));
}
#maskLayer.on .mask-flame { opacity: .9; }
#maskLayer.on .mask-flame.f-l { animation: flameFlickerL 2.6s ease-in-out infinite; }
#maskLayer.on .mask-flame.f-r { animation: flameFlickerR 3.1s ease-in-out infinite; }
@keyframes flameFlickerL {
  0%,100% { transform: scaleY(1)     skewX(0deg);  opacity: .9; }
  30%     { transform: scaleY(1.06)  skewX(-1.5deg); opacity: .75; }
  60%     { transform: scaleY(.95)   skewX(1deg);  opacity: .95; }
}
@keyframes flameFlickerR {
  0%,100% { transform: scaleY(1)     skewX(0deg);  opacity: .9; }
  35%     { transform: scaleY(1.05)  skewX(1.5deg); opacity: .8; }
  70%     { transform: scaleY(.94)   skewX(-1deg);  opacity: .95; }
}
/* 奈亚风格幕布本体：漆黑 + 底部余烬红光 */
#maskLayer.mode-nyar .mask-curtain {
  background:
    radial-gradient(circle at 15% 85%, rgba(180, 60, 15, .4) 0%, transparent 24%),
    radial-gradient(circle at 85% 85%, rgba(180, 60, 15, .4) 0%, transparent 24%),
    radial-gradient(circle at 50% 108%, rgba(230, 100, 30, .5) 0%, transparent 42%),
    radial-gradient(ellipse at 50% 50%, rgba(24, 6, 8, .95) 0%, rgba(8, 2, 4, .98) 60%, rgba(2, 0, 1, 1) 100%),
    linear-gradient(180deg, #050204 0%, #170608 55%, #2e0a08 100%);
  box-shadow:
    inset 0 0 130px rgba(140, 50, 15, .5),
    inset 0 0 260px rgba(0, 0, 0, .9);
  border-color: rgba(220, 140, 60, .5);
}
/* 顶部金色埃及圣书体符文行（黑法老） */
#maskLayer.mode-nyar .mask-curtain::before {
  content: '𓂀 𓄿 𓅓 𓊪 𓇋 𓈖 𓉐 𓏏 𓆑 𓋹 𓁹 𓎛 𓂀 𓄿 𓅓 𓊪 𓇋 𓈖 𓉐 𓏏';
  position: absolute; left: 0; right: 0; top: 7%;
  display: block; text-align: center; pointer-events: none;
  font-family: serif; font-size: 20px; letter-spacing: 12px; line-height: 1;
  color: rgba(230, 160, 70, .38);
  text-shadow: 0 0 10px rgba(220, 130, 40, .5);
  opacity: .85;
}
/* 底部余烬光带：暗焰从幕布底缘往上舔 */
#maskLayer.mode-nyar .mask-curtain::after {
  background:
    linear-gradient(180deg,
      rgba(200, 70, 20, 0) 0%,
      rgba(200, 70, 20, .3) 45%,
      rgba(230, 110, 35, .5) 78%,
      rgba(140, 40, 10, .65) 100%),
    repeating-linear-gradient(90deg,
      transparent 0 22px, rgba(0,0,0,.45) 22px 26px);
  height: 34%;
  top: auto; bottom: 0;
  opacity: .6;
}
/* 中央文字：奈亚版本（金橙 + 狂野衬线） */
#maskLayer.mode-nyar .mask-hint {
  position: relative; z-index: 4;
  font-size: 18px; letter-spacing: .16em; color: rgba(255, 216, 160, .92);
  font-family: "Kaiti SC", "KaiTi", "STKaiti", serif;
  text-shadow:
    0 0 14px rgba(235, 130, 45, .6),
    0 0 26px rgba(160, 60, 15, .4),
    0 2px 6px rgba(0, 0, 0, .85);
  background: none;
  padding: 14px 36px;
  border-top: 1px solid rgba(230, 150, 60, .4);
  border-bottom: 1px solid rgba(230, 150, 60, .4);
  border-radius: 0;
  margin-top: 20px;
}

/* —— 特效 a 红光：边缘循环淡入淡出的红光 —— */
.fx-redlight {
  box-shadow: inset 0 0 150px 46px rgba(255,30,30,.6);
  animation: fxRedlight 2.4s ease-in-out infinite;
}
@keyframes fxRedlight { 0%,100% { opacity: 0; } 50% { opacity: 1; } }

/* —— 特效 b 受伤：边缘不规则血迹（SVG），突然出现后慢慢消失 —— */
.fx-injured { animation: fxInjured 3.2s ease-out forwards; }
.fx-injured-svg { position: absolute; inset: 0; width: 100%; height: 100%; }
@keyframes fxInjured { 0% { opacity: 0; } 6% { opacity: 1; } 100% { opacity: 0; } }

/* —— 特效 c 屏幕振动：抖动幅度比上一版小 20%、速度慢 20% —— */
#stage.fx-shaking { animation: fxShake .2s linear infinite; }
@keyframes fxShake {
  0%   { transform: translate(0, 0); }
  20%  { transform: translate(-2.08%, 1.12%); }
  40%  { transform: translate(1.76%, -1.6%); }
  60%  { transform: translate(-1.28%, -0.96%); }
  80%  { transform: translate(1.12%, 1.44%); }
  100% { transform: translate(0, 0); }
}

/* —— 特效 d 中弹：更大的枪眼 + 更清晰的玻璃裂纹，出现后慢慢消失 —— */
.fx-shot { animation: fxShotLife 2.6s ease-out forwards; }
.fx-shot-hole {
  position: absolute; width: 96px; height: 96px; transform: translate(-50%, -50%);
  border-radius: 50%;
  background: radial-gradient(circle,
    rgba(8,8,10,.97) 0 24%, rgba(52,52,58,.92) 38%, rgba(190,195,205,.72) 47%, rgba(210,215,225,.25) 52%, transparent 60%);
  box-shadow: 0 3px 12px rgba(0,0,0,.6), inset 0 0 6px rgba(255,255,255,.28);
}
.fx-shot-crack { position: absolute; inset: 0; width: 100%; height: 100%; }
.fx-shot-crack path { fill: none; stroke: rgba(240,244,252,.95); stroke-width: 1.4; vector-effect: non-scaling-stroke; }
@keyframes fxShotLife { 0% { opacity: 0; } 8% { opacity: 1; } 72% { opacity: 1; } 100% { opacity: 0; } }

/* —— 特效 e 火焰：底部大范围燃烧 + 跳动的火苗舌头 —— */
.fx-fire {
  background:
    radial-gradient(ellipse 130% 62% at 50% 116%, rgba(255,120,18,.92), transparent 66%),
    radial-gradient(ellipse 92% 46% at 50% 110%, rgba(255,55,8,.96), transparent 70%),
    radial-gradient(ellipse 58% 30% at 50% 103%, rgba(255,205,70,.92), transparent 72%),
    radial-gradient(ellipse 44% 78% at -5% 82%, rgba(255,95,16,.78), transparent 70%),
    radial-gradient(ellipse 44% 78% at 105% 82%, rgba(255,95,16,.78), transparent 70%),
    radial-gradient(ellipse 30% 30% at 50% 100%, rgba(255,235,150,.95), transparent 70%);
  animation: fxFire .5s ease-in-out infinite alternate;
}
/* 底部跳动的火苗（模糊光斑，模拟火焰舌头） */
.fx-fire::before {
  content: ''; position: absolute; inset: 0;
  background:
    radial-gradient(ellipse 20% 18% at 28% 104%, rgba(255,150,40,.9), transparent 70%),
    radial-gradient(ellipse 24% 22% at 55% 110%, rgba(255,185,65,.85), transparent 70%),
    radial-gradient(ellipse 18% 16% at 80% 103%, rgba(255,150,40,.9), transparent 70%);
  animation: fxFireTongue .8s ease-in-out infinite alternate;
  filter: blur(2px);
}
@keyframes fxFire {
  from { filter: brightness(.85); transform: scaleY(1); }
  to   { filter: brightness(1.25); transform: scaleY(1.12); }
}
@keyframes fxFireTongue {
  from { transform: scaleY(.82) translateY(2%); opacity: .65; }
  to   { transform: scaleY(1.22) translateY(-1%); opacity: 1; }
}

/* —— 特效 f 鬼魂：半透明苍白的阴森幽灵（空洞黑眼 + 歪斜大口）漂浮动画 —— */
.fx-ghost-sprite {
  --s: 1;
  position: absolute; width: 88px; height: 112px; margin-left: -44px;
  animation: fxGhostFloat 3.2s ease-in-out infinite;
  filter: drop-shadow(0 0 14px rgba(150,190,235,.45));
}
.fx-ghost-sprite .g-body {
  position: absolute; left: 0; top: 0; right: 0; height: 88px;
  background: linear-gradient(180deg, rgba(214,226,240,.72), rgba(172,193,218,.48));
  border-radius: 52% 52% 6px 6px / 64% 64% 6px 6px;
  box-shadow: inset 0 -16px 26px rgba(118,150,192,.4);
}
.fx-ghost-sprite .g-body::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: -20px; height: 20px;
  background:
    radial-gradient(circle at 8px 0, rgba(198,216,236,.62) 8px, transparent 8px),
    radial-gradient(circle at 28px 3px, rgba(180,200,224,.5) 9px, transparent 9px);
  background-size: 24px 20px; background-repeat: repeat-x;
}
.fx-ghost-sprite .g-eye {
  position: absolute; top: 34px; width: 16px; height: 23px; border-radius: 46%; background: #0a0c12;
  box-shadow: 0 0 9px rgba(0,0,0,.85);
}
.fx-ghost-sprite .g-eye:first-of-type { left: 21px; transform: rotate(-9deg); }
.fx-ghost-sprite .g-eye:nth-of-type(2) { right: 21px; transform: rotate(9deg); }
.fx-ghost-sprite .g-mouth {
  position: absolute; top: 60px; left: 50%; transform: translateX(-50%) rotate(-7deg);
  width: 26px; height: 20px; border-radius: 46% 30% 52% 44%;
  background: #0a0c12; box-shadow: 0 0 9px rgba(0,0,0,.75);
}
@keyframes fxGhostFloat {
  0%, 100% { transform: translateY(0) scale(var(--s, 1)); }
  50%      { transform: translateY(-24px) scale(var(--s, 1)); }
}

/* 主持面板：特效按钮网格 */
.fx-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-top: 8px;
}
.fx-btn {
  padding: 9px 4px; font-size: 13px; border-radius: 8px;
  background: rgba(255,255,255,.04); border: 1px solid rgba(255,255,255,.12);
  color: #e8e6f2; cursor: pointer; transition: background .15s, border-color .15s;
}
.fx-btn:hover { background: #252238; border-color: var(--acc); }

/* ============ 第五十四批：NPC 库 + 战斗轮 ============ */
/* 战斗轮开启时原舞台元素的"暂停"状态：保留可见 + 半透明 + 不可交互 */
.combat-paused {
  opacity: 0.28 !important;
  pointer-events: none !important;
  filter: blur(1.5px) saturate(0.7);
  transition: opacity .35s ease, filter .35s ease;
}
/* 战斗轮期间不需要暂停的层（投掷动画/聊天提示/战斗轮本板）显式标注不被 .combat-paused 影响 */
.combat-paused.keep-active { opacity: 1 !important; pointer-events: auto !important; filter: none !important; }
/* 旧 .combat-hidden 保留别名兼容（防御性） */
.combat-hidden { display: none !important; }
/* NPC 列表项 */
.npc-item { display:flex; align-items:center; gap:10px; padding:8px 10px; border:1px solid var(--line); border-radius:8px; background:#1a1730; margin-bottom:6px; }
.npc-portrait { width:48px; height:48px; border-radius:6px; overflow:hidden; background:#0e0c1a; display:flex; align-items:center; justify-content:center; flex-shrink:0; }
.npc-portrait img { width:100%; height:100%; object-fit:cover; }
.npc-info { flex:1; min-width:0; }
.npc-info b { display:inline-block; margin-right:6px; }
.npc-job { font-size:12px; color:var(--acc); margin-right:6px; }
.npc-info .hint { display:block; margin-top:2px; }
.npc-btns { display:flex; gap:4px; }
/* 战斗轮选单位模态 */
.cp-row { display:flex; align-items:center; gap:8px; padding:6px 8px; border-bottom:1px dashed var(--line); }
.cp-row:last-child { border-bottom:none; }
.cp-row b { min-width:80px; }
.cp-row .hint { flex:1; min-width:0; }
/* 战斗轮主视图 */
/* 第六十批大改：grid 三列布局（玩家 / 中央 VS / NPC），VS 居中且独立、不与两侧粘连，加竖向分隔线 */
#combatBoard {
  position: absolute; inset: 0; z-index: 990;
  background:
    linear-gradient(180deg, rgba(26,23,56,.55) 0%, rgba(14,12,26,.66) 100%);
  display: grid;
  /* 66：中间列用 minmax(28px, auto) 让 divider 收缩到图标本身宽度（不再撑满 auto） */
  grid-template-columns: minmax(0, 1fr) minmax(28px, 44px) minmax(0, 1fr);
  grid-template-rows: 1fr;
  column-gap: 0; row-gap: 0;
  padding: 16px;
  color: #e8e6f2;
  overflow: hidden;
  animation: combatEnterIn .55s cubic-bezier(.16,1,.3,1) both;
}
#combatBoard.leave {
  animation: combatEnterOut .55s ease both !important;
}
@keyframes combatEnterIn {
  0%   { opacity: 0; transform: scale(.96); }
  60%  { opacity: 1; transform: scale(1.02); }
  100% { opacity: 1; transform: scale(1); }
}
@keyframes combatEnterOut {
  0%   { opacity: 1; transform: scale(1); }
  100% { opacity: 0; transform: scale(1.08); }
}

/* 第六十批：玩家 / 敌方两侧 grid 定位，加开场侧滑 */
#combatBoard .combat-side-players { grid-column: 1; min-height: 0; }
#combatBoard .combat-side-npcs    { grid-column: 3; min-height: 0; }
#combatBoard.enter .combat-side-players { animation: sideInLeft .85s cubic-bezier(.22,1,.36,1) both; }
#combatBoard.enter .combat-side-npcs    { animation: sideInRight .85s cubic-bezier(.22,1,.36,1) both; }
@keyframes sideInLeft  { from { transform: translateX(-60%); opacity: 0; } to { transform: translateX(0); opacity: 1; } }
@keyframes sideInRight { from { transform: translateX( 60%); opacity: 0; } to { transform: translateX(0); opacity: 1; } }

#combatBoard .combat-side { flex: 1; min-height: 0; display: flex; flex-direction: column; }
/* 两侧板块都圆角，并用更明显的紫色面板 + 顶部彩条增加对比 */
#combatBoard .combat-side-players .combat-side-inner,
#combatBoard .combat-side-npcs .combat-side-inner {
  border-radius: 12px; padding: 8px;
  background: rgba(20, 17, 40, .55);
  border: 1px solid rgba(255,255,255,.06);
  display: flex; flex-direction: column; min-height: 0; flex: 1;
}
#combatBoard .combat-side-players .combat-side-inner { border-top: 3px solid #7df0a0; }
#combatBoard .combat-side-npcs .combat-side-inner    { border-top: 3px solid #ff8d8d; }
#combatBoard .combat-side-title { text-align: center; font-size: 16px; font-weight: bold; margin-bottom: 8px; color: var(--acc); text-shadow: 0 1px 6px rgba(0,0,0,.6); }
#combatBoard .combat-side-players .combat-side-title { color: #7df0a0; }
#combatBoard .combat-side-npcs .combat-side-title    { color: #ff8d8d; }
/* 第六十五批：战斗轮网格固定 2×2 布局（每侧 2 列、多余自动换行）
>   - 每侧 .combat-units 用 repeat(2, minmax(0, 1fr))：每行 2 张、永远清晰
>   - 不强制占满屏、不收起左右侧栏（#chat / #side 保持可见）
>   - .many / .crowded 在 5+ 人时再缩字号以不遮挡 */
#combatBoard .combat-units {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
  overflow-y: auto;
  overflow-x: hidden;
  padding: 6px;
  align-content: start;
  flex: 1;
  min-height: 0;
}
#combatBoard .combat-units > p { grid-column: 1 / -1; margin: auto; }

#combatBoard .combat-units.many .combat-unit .cu-name { font-size: 13px; }
#combatBoard .combat-units.many .combat-unit .cu-job { font-size: 10px; }
#combatBoard .combat-units.many .combat-unit .cu-stat i { font-size: 10px; }
#combatBoard .combat-units.many .combat-unit .cs-btn { font-size: 10px; padding: 3px 5px; }
#combatBoard .combat-units.many .combat-unit .cu-portrait { width: 44px; height: 44px; }
#combatBoard .combat-units.crowded .combat-unit .cu-name { font-size: 12px; }
#combatBoard .combat-units.crowded .combat-unit .cu-portrait { width: 36px; height: 36px; }
#combatBoard .combat-units.crowded .combat-unit .cu-stat i { font-size: 9px; }

/* 第六十批：中央 VS 区域独占 grid 第 2 列
   66：精简为窄列 + 居中 ⚔️ 圆形图标（让两侧可用宽度变宽） */
#combatBoard .combat-divider {
  grid-column: 2;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  color: #ffc989;
  min-width: 28px; max-width: 36px; width: 36px;
  padding: 0; margin: 0 4px;
  background: transparent;
  border: none;
  box-shadow: none;
  position: relative;
  text-shadow: 0 0 10px rgba(255,201,137,.55);
  overflow: visible;
}
#combatBoard .combat-divider > span {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; border-radius: 50%;
  background: radial-gradient(circle, rgba(255,201,137,.15) 0%, rgba(20,17,40,.4) 70%);
  border: 1px solid rgba(255,201,137,.45);
  font-size: 18px; font-weight: 900;
  letter-spacing: 0;
  overflow: visible;
}
#combatBoard .combat-divider::before,
#combatBoard .combat-divider::after {
  display: none;
}
#combatBoard .combat-divider::before,
#combatBoard .combat-divider::after {
  content: '';
  position: absolute; top: 8%; height: 84%; width: 2px;
  background: linear-gradient(180deg, transparent 0%, rgba(255,201,137,.55) 30%, rgba(255,201,137,.55) 70%, transparent 100%);
  pointer-events: none;
}
#combatBoard .combat-divider::before { left: -10px; }
#combatBoard .combat-divider::after  { right: -10px; }
/* 进战斗时 VS 数字先放大再恢复：受 .enter 触发 */
#combatBoard.enter .combat-divider { animation: vsPop 1s ease both; }
@keyframes vsPop {
  0%   { transform: scale(.3); opacity: 0; letter-spacing: .05em; }
  40%  { transform: scale(1.35); opacity: 1; letter-spacing: .35em; }
  100% { transform: scale(1); opacity: 1; letter-spacing: .25em; }
}

/* 第六十批：「⚔ 进入战斗 ⚔」覆盖大字（一次性开场动画） */
#combatBoard.enter::before {
  content: '⚔  进 入 战 斗  ⚔';
  position: absolute; inset: 0; z-index: 50;
  display: flex; align-items: center; justify-content: center;
  font-size: 56px; font-weight: 900; color: #ffd76b;
  letter-spacing: .3em;
  text-shadow: 0 0 30px rgba(255,213,107,.85), 0 4px 22px rgba(0,0,0,.7);
  pointer-events: none;
  animation: enterBattlePop 1.25s ease both;
}
@keyframes enterBattlePop {
  0%   { opacity: 0; transform: scale(.4) rotateX(20deg); letter-spacing: .05em; }
  25%  { opacity: 1; transform: scale(1.2) rotateX(0);    letter-spacing: .35em; }
  65%  { opacity: 1; transform: scale(1)   rotateX(0);    letter-spacing: .3em; }
  100% { opacity: 0; transform: scale(1.1) rotateX(0);    letter-spacing: .3em; }
}

/* 单位卡 */
.combat-unit {
  min-width: 0; max-width: none;            /* 第六十五批：宽度交给 grid（4 列均分） */
  background: linear-gradient(160deg, rgba(36,32,68,.92) 0%, rgba(20,18,40,.95) 100%);
  border:1px solid var(--line); border-radius: 10px;
  display:flex; gap:6px; padding:6px;
  box-shadow: 0 6px 16px rgba(0,0,0,.45), inset 0 1px 0 rgba(255,255,255,.05);
  position: relative;
  transition: transform .15s ease, box-shadow .15s ease;
}

.combat-unit:hover { transform: translateY(-2px); box-shadow: 0 10px 22px rgba(0,0,0,.55), inset 0 1px 0 rgba(255,255,255,.08); }
.combat-unit.is-mine { border-color: #7df0a0; box-shadow: 0 0 0 2px rgba(125,240,160,.22), 0 6px 16px rgba(0,0,0,.5); }
.combat-unit.is-mine-npc { border-color: #ff8d8d; box-shadow: 0 0 0 2px rgba(255,141,141,.22), 0 6px 16px rgba(0,0,0,.5); }
/* DEX 回合顺序徽章 */
.combat-unit .cu-order {
  position: absolute; top: -8px; left: -8px;
  width: 30px; height: 30px; border-radius: 50%;
  background: linear-gradient(135deg, #ffd76b, #ff9a3c);
  color: #1a1730; font-weight: 900; font-size: 14px;
  display:flex; align-items:center; justify-content:center;
  box-shadow: 0 2px 8px rgba(255,154,60,.5);
  border: 2px solid #1a1730;
  z-index: 1;
}
.combat-unit.is-mine .cu-order      { background: linear-gradient(135deg, #6dfca8, #2cb56e); box-shadow: 0 2px 8px rgba(125,240,160,.5); }
.combat-unit.is-mine-npc .cu-order  { background: linear-gradient(135deg, #ffa3a3, #d44242); box-shadow: 0 2px 8px rgba(255,141,141,.5); }
/* 当前行动中的单位（外发光更强） */
.combat-unit.is-acting { animation: combatActingGlow 1.6s ease-in-out infinite; }
@keyframes combatActingGlow {
  0%, 100% { box-shadow: 0 0 0 2px rgba(255,213,107,.35), 0 6px 18px rgba(255,213,107,.25); }
  50%      { box-shadow: 0 0 0 4px rgba(255,213,107,.6),  0 8px 24px rgba(255,213,107,.4); }
}
/* NPC/玩家色彩 tint */
.combat-unit.kind-npc { background: linear-gradient(160deg, rgba(60,28,38,.85) 0%, rgba(28,16,22,.95) 100%); }
.combat-unit.kind-npc .cu-side-tag { background: #d44242; }
.combat-unit .cu-side-tag { position:absolute; top:8px; right:8px; font-size:9px; padding:1px 5px; border-radius:3px; background:#2cb56e; color:#fff; font-weight:700; letter-spacing:.04em; }
.combat-unit .cu-portrait { width:46px; height:46px; border-radius:6px; background:#0e0c1a; overflow:hidden; display:flex; align-items:center; justify-content:center; flex-shrink:0; border: 2px solid var(--line); }
.combat-unit .cu-portrait img { width:100%; height:100%; object-fit:cover; }
.combat-unit .cu-body { flex:1; min-width:0; display:flex; flex-direction:column; gap:3px; }
.combat-unit .cu-name { font-size:13px; font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.combat-unit .cu-job { font-size:10px; color:#c9c5e8; margin-left:4px; opacity:.8; }
.combat-unit .cu-stats { display:flex; flex-direction:column; gap:2px; }
.combat-unit .cu-stat { background:#0e0c1a; padding:1px 4px; border-radius:3px; font-size:10px; border: 1px solid rgba(255,255,255,.05); display:flex; align-items:center; gap:2px; min-width:0; }
.combat-unit .cu-stat i { color:#a09cb8; font-style:normal; font-weight:600; letter-spacing:0; flex-shrink:0; font-size:9px; min-width:14px; display:inline-block; text-align:left; }
/* 第六十五批：HP/SAN/MP 改成可编辑数字输入框（替代 ±1/±5 按钮）
   - 上下键调节：单步 1；Shift+上下键单步 5
   - 失焦 / Enter 提交绝对值到服务端
   - 视觉上保持紧凑，不破坏卡片 4×2 布局 */
.combat-unit .cu-stat-input {
  background: rgba(0,0,0,.35);
  border: 1px solid rgba(255,255,255,.12);
  color: var(--acc);
  font-weight: 700;
  font-size: 12px;
  width: 42px;
  padding: 1px 4px;
  border-radius: 3px;
  text-align: center;
  font-family: inherit;
  -moz-appearance: textfield;
}
.combat-unit .cu-stat-input:focus { outline: none; border-color: var(--acc); background: rgba(255,255,255,.08); }
.combat-unit .cu-stat-input::-webkit-outer-spin-button,
.combat-unit .cu-stat-input::-webkit-inner-spin-button { opacity: .55; height: 22px; }
.combat-unit .cu-stat-input.is-disabled { color: #5d5972; cursor: not-allowed; opacity: .65; }
.combat-unit .cu-stat-val { display:inline-flex; align-items:center; gap:2px; min-width:0; flex:1; justify-content:flex-end; }
.combat-unit .cu-stat-sep { color:#5d5972; margin: 0 1px; font-size:10px; }
.combat-unit .cu-stat-max { color:#5d5972; font-size:10px; font-style:normal; }
/* 第六十八批：玩家视角敌方 NPC 隐私遮罩 —— name/HP/SAN/MP 用「???」覆盖，视觉上明显但不让玩家推断数值 */
.combat-unit .cu-name-mask { color: #ff8d8d; letter-spacing: 1px; font-weight: 700; }
.combat-unit .cu-job-mask { color: #ff8d8d; opacity: .8; margin-left: 4px; }
.combat-unit .cu-stat-val-mask { color: #ff8d8d; letter-spacing: 1px; font-weight: 700; font-size: 10px; display:inline-flex; align-items:center; gap:2px; flex:1; justify-content:flex-end; min-width:0; }
/* 第六十批：基础属性数值（STR/CON/SIZ/DEX/APP/INT/POW/EDU）不再向玩家显示，仅在最终行动回合数 / DEX 顺序等关键用途上保留，
   整行 .cu-attrs 不渲染（见 combatUnitHTML） */

/* 战斗技能按钮 */
.combat-unit .cu-skills { display:flex; flex-wrap:wrap; gap:3px; margin-top:auto; padding-top:4px; border-top:1px dashed rgba(255,255,255,.1); }
.combat-unit .cs-btn { background:#252238; border:1px solid var(--line); color:#e8e6f2; padding:3px 5px; border-radius:5px; cursor:pointer; font-size:10px; display:flex; align-items:center; gap:3px; transition: all .12s ease; }
.combat-unit .cs-btn:hover:not(:disabled) { background:#352f55; border-color:var(--acc); transform: translateY(-1px); }
.combat-unit .cs-btn:active:not(:disabled) { transform: translateY(0); }
.combat-unit .cs-btn:disabled { opacity:.4; cursor:not-allowed; }
.combat-unit .cs-btn.cat-ranged { border-color:#5b8; }
.combat-unit .cs-btn.cat-melee  { border-color:#e75; }
.combat-unit .cs-btn.cat-dodge  { border-color:#8ad; }
.combat-unit .cs-btn .cs-cat { font-size:11px; }
.combat-unit .cs-btn .cs-name { max-width:46px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.combat-unit .cs-btn .cs-val { background:rgba(0,0,0,.3); padding:0 3px; border-radius:3px; color:var(--acc); font-weight:bold; min-width: 16px; text-align:center; font-size:10px; }
/* 第六十批：基础值兜底技能按钮（未设技能时用 STR/DEX 推导）样式明显（暗淡 + 斜体） */
.combat-unit .cs-btn.is-fallback { opacity:.78; border-style: dashed; }
.combat-unit .cs-btn.is-fallback .cs-name::after { content: ' (基础值)'; font-size: 9px; color: #a09cb8; margin-left: 2px; }
/* 第六十批：兜底说明小字（背景玩家能识别"虚框是按属性推的"） */
.combat-unit .cu-fb-note { font-size: 10px; color: #a09cb8; margin-top: 4px; padding-top: 4px; border-top: 1px dashed rgba(255,255,255,.06); }
/* 第六十八批：撤销第六十批的「隐藏 NPC 技能值」设计 —— 用户要求「技能可见」，所以 cs-val 不再隐藏
   （GM 端玩家自己操控 NPC 时本就一直可见，这里只动玩家端敌方 NPC） */
/* .combat-unit.kind-npc:not(.is-mine-npc) .cs-val { display: none; } */
/* .combat-unit.kind-npc:not(.is-mine-npc) .cs-btn::after { content: '?'; margin-left: 2px; color: #ff8d8d; font-weight: 700; } */
