/* ============================================================
   天工引擎 v2 原生客户端 · 宣纸宋版（Track A M10 改版）
   视觉/布局系统移植自 ui-redesign-proposals/shells-src/game-b/index.html
   （设计母本，方案B预览图 1:1 实装版）；数据面走 v2 原生协议，
   消息类型总表见 docs/PROTOCOL-MESSAGES.md。铁律：输入框只发聊天。
   ============================================================ */
*{margin:0;padding:0;box-sizing:border-box}
html,body{height:100%;overflow:hidden}
body{background:var(--paper);color:var(--ink);
  font-family:var(--font-body);
  font-size:var(--fs-15);-webkit-font-smoothing:antialiased}
/* ===== OPT-351 界面主题（浅色/黑夜/护眼）=====
   色板收敛为 body 级变量：本块=浅色（宣纸默认，与收敛前逐值等价）；body.theme-dark /
   body.theme-eyecare（文件尾）只覆写变量 + 少量补钉。主题选择存 localStorage（ng_theme，
   同 ng_drawer_* 本地先例）：纯客户端消费、登录前即生效，不入服务端白名单。
   sealink/priink/onbar（印章白字、条上文字）三主题恒亮不覆写；阴影与条带高光渐变恒值。 */
body{
  --paper:#f6f4ee; --card:#fcfbf7; --cardrgb:252,251,247; --field:#fff; --wht:255,255,255;
  --knob:#fcfbf7;
  --ink:#2f2c26; --ink2:#4a463e; --ink3:#5a564c; --mut:#8f887a; --faint:#b8b2a4;
  --inkrow:#4a4238; --inksub:#5a5346; --inkdeep:#3b362d; --innfoot:#8a8172;
  --setval:#8a7a5c; --hkink:#6b5c40; --hkline:#b3a488;
  --ln:47,44,38; --sep:120,100,70; --track:#efece2;
  --seal:#a84842; --seal-deep:#96403a; --sealacc:168,72,66;
  --sealink:#f8f4ec; --priink:#f6f2e8; --onbar:#f6f4ee;
  --gold:#9c6d1c; --gold2:#a8783c; --gold3:#c49a4a; --goldacc:156,109,28; --goldln:168,120,60;
  --teal:#2e7464; --tealacc:46,116,100;
  --good:#2e7d4f; --goodacc:46,125,79; --bad:#b03d35; --badacc:176,61,53;
  --loot:#8a6a1c;
  --mapbtn:#e6e2d2; --mapbtnh:#dcd7c4; --mapbtna:#cfc9b4; --curbg:#5a564c;
  --swtrack:#d8d2c2;
  --adminbg:#faf8f2; --adink:#3f3b34; --admut:#8a8378; --thead:#f7f4ec;
  --ok:#3a7a3a; --ok2:#5a7a4a;  /* 管理台在线/启用绿、成功回执绿（admin JS 内联引用） */
  /* 2026-11 颜色令牌化收尾：JS 内联色单源（见 docs/DESIGN-TOKENS.md §3） */
  --okink:#6f9a6d; --mutcool:#8a849c; --statink:#7a6a3a; --affix-blue:#5b7fae; --affix-purple:#8e6fae;
  /* 品级色 0~6：灰绿蓝黄紫橙红，三主题同色（设计如此，主题块勿覆写） */
  --grade-0:#9aa0a6; --grade-1:#5cb85c; --grade-2:#4d9de0; --grade-3:#e8b339; --grade-4:#b07de0; --grade-5:#e0862c; --grade-6:#e05a4e;
  --msg-fs:12px; /* 2026-10-11 用户令：日志字号默认 12px（原 14px），设置→界面页签五档可调 */
  --nav-sc:1; --map-sc:1; --top-sc:1; --draw-sc:1; --room-sc:1; /* 2026-10-11 用户令：五大区域尺寸系数（设置→界面各五档），缺省 1=当日调整值 */
}
/* ===== 设计令牌·非主题色，三主题共用（清单与规范见 docs/DESIGN-TOKENS.md）=====
   字体族 / 圆角 / 阴影 / 动效 / 字号阶梯。值与令牌化前的字面量逐值等价（回代比对证明）；
   主题层 body.theme-* 不覆写本块。阴影里的 rgba(47,44,38,…)/rgba(30,27,22,…) 属主题文档「恒量区」
   恒值，三主题共用。字号阶梯为等价映射（每个现存 px 值一个令牌），带「待并档」的半像素档留待视觉焕新收敛。
   calc() 内的尺寸系数字面量（--*-sc 链路）与被测试钉住的字面量不令牌化。 */
body{
  --font-body:"Songti SC",STSong,SimSun,"Noto Serif SC","Source Han Serif SC",serif;
  --font-kai:KaiTi,STKaiti,serif;  /* 楷体标题/印章/按钮 */
  --font-kai-cjk:KaiTi,STKaiti,"Noto Serif SC",serif;  /* .kai 工具类（含思源宋回落） */
  --r-0:0; --r-1:1px; --r-2:2px; --r-3:3px; --r-4:4px; --r-8:8px; --r-10:10px; --r-12:12px;
  --r-pill:999px; --r-round:50%;
  --sh-inset-track:inset 0 0 0 1px rgba(47,44,38,.12);  /* 条带凹槽描边（气血/NPC/灵药条） */
  --sh-inset-cur:inset 0 0 0 1px rgba(47,44,38,.3);  /* 舆图当前格 */
  --sh-inset-switch:inset 0 1px 3px rgba(47,44,38,.28);  /* 开关轨道 */
  --sh-knob:0 1px 3px rgba(47,44,38,.45);  /* 开关圆钮 */
  --sh-login:0 2px 14px rgba(47,44,38,.07);  /* 登录框 */
  --sh-panel:0 4px 18px rgba(47,44,38,.14);  /* 面板 */
  --sh-ticker:0 6px 18px rgba(47,44,38,.18);  /* 播报浮动条 */
  --sh-pop:0 6px 18px rgba(47,44,38,.22);  /* BUFF 浮层 */
  --sh-dialog:0 4px 18px rgba(30,27,22,.25);  /* 页内对话框 */
  --sh-text-onbar:0 1px 2px rgba(47,44,38,.9),0 0 3px rgba(47,44,38,.7);  /* 条上数字描影 */
  --dur-160:.16s; --dur-200:.2s; --dur-250:.25s; --dur-350:.35s; --dur-550:.55s; --dur-800:.8s;
  --ease-out:ease-out; --ease-out-expo:cubic-bezier(.22,1,.36,1);
  --fs-8:8px; --fs-9:9px; --fs-9-5:9.5px; /* 待并档 */ --fs-10:10px; --fs-10-5:10.5px; /* 待并档 */
  --fs-11:11px; --fs-11-5:11.5px; /* 待并档 */ --fs-12:12px; --fs-12-5:12.5px; /* 待并档 */
  --fs-13:13px; --fs-14:14px; --fs-15:15px; --fs-16:16px; --fs-17:17px; --fs-20:20px; --fs-24:24px;
}
.kai{font-family:var(--font-kai-cjk)}
button{font:inherit;color:inherit;background:none;border:none;cursor:pointer}
input{font:inherit;color:inherit}
::-webkit-scrollbar{width:0;height:0}

#scr-login{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;
  background:
   radial-gradient(300px 180px at 88% -4%,rgba(var(--sealacc),.045),transparent 60%),
   radial-gradient(360px 220px at 0% 104%,rgba(var(--tealacc),.05),transparent 60%),var(--paper)}
.loginbox{position:relative;margin-top:14vh;width:min(340px,86%);background:var(--card);border:1px solid rgba(var(--ln),.16);
  border-radius:var(--r-2);padding:26px 22px 22px;box-shadow:var(--sh-login)}
.loginbox .seal{position:absolute;top:14px;right:14px;width:30px;height:30px;background:var(--seal);color:var(--sealink);
  border-radius:var(--r-2);display:flex;align-items:center;justify-content:center;font-size:var(--fs-16);font-family:var(--font-kai)}
.loginbox .seal::after{content:"";position:absolute;inset:2px;border:1px solid rgba(248,244,236,.55);border-radius:var(--r-1)}
.h-title{font-family:var(--font-kai);font-size:var(--fs-24);letter-spacing:8px;margin-bottom:4px;text-align:center}
.hairline{display:flex;align-items:center;gap:8px;margin:10px 0 16px}
.hairline i{flex:1;height:1px;background:rgba(var(--ln),.14)}
.hairline span{font-size:var(--fs-10);letter-spacing:3px;color:var(--mut)}
.lfield{margin-bottom:10px}
.lfield input{width:100%;background:var(--field);border:1px solid rgba(var(--ln),.2);border-radius:var(--r-2);padding:10px 12px;outline:none}
#btn-login{width:100%;margin-top:6px;padding:11px 0;background:var(--seal);color:var(--sealink);border:none;border-radius:var(--r-2);
  font-family:var(--font-kai);font-size:var(--fs-17);letter-spacing:10px;cursor:pointer}
#login-msg{margin-top:10px;font-size:var(--fs-12);color:var(--bad);text-align:center;min-height:16px}
/* OPT-164 本设备历史账号：一键回填 chips（登录成功才记录，最多 5 条按最近排序） */
.saved-accounts{display:flex;flex-wrap:wrap;gap:4px;justify-content:center;margin-top:8px}
.saved-accounts:empty{display:none}
.saved-chip{font-size:var(--fs-12);border:1px solid rgba(var(--ln),.25);border-radius:var(--r-2);padding:3px 9px;background:rgba(var(--cardrgb),.9);color:var(--ink3);max-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.saved-chip:hover{color:var(--seal);border-color:var(--seal)}
.saved-chip .x{margin-left:6px;color:var(--mut);padding:0 2px}
.saved-chip .x:hover{color:var(--seal)}
/* 取名屏（账号≠侠名：新号首登先取名再进世界，OPT-103） */
#scr-naming{background:
   radial-gradient(300px 180px at 88% -4%,rgba(var(--sealacc),.045),transparent 60%),
   radial-gradient(360px 220px at 0% 104%,rgba(var(--tealacc),.05),transparent 60%),var(--paper)}
.naming-row{display:flex;gap:8px;margin-top:6px}
.naming-row button{flex:1;padding:11px 0;border-radius:var(--r-2);font-family:var(--font-kai);font-size:var(--fs-16);letter-spacing:4px}
#btn-naming{background:var(--seal);color:var(--sealink);border:none}
#btn-rollname{border:1px solid rgba(var(--ln),.25);color:var(--ink3);background:var(--card)}
#naming-msg{margin-top:10px;font-size:var(--fs-12);color:var(--bad);text-align:center;min-height:16px}
/* OPT-233 先天四维分配（随取名一次定死） */
.innate-box{margin-top:10px;border:1px solid rgba(var(--ln),.16);border-radius:var(--r-2);padding:8px 10px;background:rgba(var(--ln),.03)}
.innate-head{display:flex;justify-content:space-between;align-items:center;font-size:var(--fs-12);color:var(--inksub);margin-bottom:4px}
.innate-head span:first-child{letter-spacing:2px}
.innate-row{display:flex;align-items:center;margin:3px 0;font-size:var(--fs-13)}
.innate-label{width:44px;color:var(--inkdeep);font-family:var(--font-kai)}
.innate-row button{width:32px;height:26px;line-height:1;padding:0;background:var(--field);border:1px solid rgba(var(--ln),.25);border-radius:var(--r-2);font-size:var(--fs-15);color:var(--inkdeep)}
.innate-val{flex:1;text-align:center;font-size:var(--fs-15);color:var(--seal);font-weight:600}
.innate-foot{display:flex;justify-content:space-between;align-items:center;gap:8px;margin-top:6px;font-size:var(--fs-11);color:var(--innfoot)}
.innate-foot button{flex:none;padding:5px 10px;background:var(--field);border:1px solid rgba(var(--ln),.25);border-radius:var(--r-2);font-size:var(--fs-12);color:var(--inkdeep)}

.screen{position:absolute;inset:0;display:none;flex-direction:column}
.screen.on{display:flex}
#scr-game{background:
  radial-gradient(300px 180px at 88% -4%,rgba(var(--sealacc),.045),transparent 60%),
  radial-gradient(360px 220px at 0% 104%,rgba(var(--tealacc),.05),transparent 60%),var(--paper)}

.topbar{display:flex;align-items:center;gap:9px;padding:10px 14px 9px;border-bottom:1px solid rgba(var(--ln),.14);flex:0 0 auto;background:var(--card)}
.seal{width:26px;height:26px;border-radius:var(--r-2);background:var(--seal);color:var(--sealink);display:flex;align-items:center;justify-content:center;
  font-family:var(--font-kai);font-size:var(--fs-15);flex:0 0 auto;position:relative}
.seal::after{content:"";position:absolute;inset:2px;border:1px solid rgba(248,244,236,.55);border-radius:var(--r-1)}
.brand{font-family:var(--font-kai);font-size:var(--fs-16);letter-spacing:4px;color:var(--ink)}
.brand small{color:var(--mut);letter-spacing:1px;margin-left:8px;font-size:var(--fs-11)}
/* OPT-172 顶栏佩戴称号：印章红描边字，随名字同行 */
.tb-title{color:var(--seal);font-size:var(--fs-12);letter-spacing:1px;margin-right:6px;font-weight:normal}

.vitals{display:flex;align-items:center;gap:10px;padding:7px 14px;border-bottom:1px solid rgba(var(--ln),.1);flex:0 0 auto;background:var(--card)}
.vit-row{display:flex;align-items:center;gap:7px;flex:1}
.vit-label{font-size:var(--fs-10);letter-spacing:2px;color:var(--mut)}
.vit-track{flex:1;height:18px;background:var(--track);border-radius:var(--r-2);position:relative;overflow:hidden;box-shadow:var(--sh-inset-track)}
.vit-ghost{position:absolute;left:0;top:0;bottom:0;width:0%;border-radius:var(--r-2);
  transition:width var(--dur-800) var(--ease-out-expo) var(--dur-350)} /* 残影：延迟跟随主条，掉血时露出亮色残段 */
.vit-ghost.ghp{background:linear-gradient(90deg,#e8c9a0,#f3e2c2)}
.vit-ghost.gmp{background:linear-gradient(90deg,#a9c4e8,#ccdcf2)}
.vit-fill{height:100%;position:relative;z-index:1;overflow:hidden;transition:width var(--dur-250) var(--ease-out)}
/* 2026-09-26 护盾覆层：常驻+战斗盾合计，盖在血条填充层上（同 z 后绘），最多占满整条（战斗盾可超上限封顶） */
.vit-shd{position:absolute;left:0;top:0;bottom:0;width:0%;z-index:1;border-radius:var(--r-2);pointer-events:none;overflow:hidden;
  background:linear-gradient(90deg,rgba(5,150,105,.92),rgba(52,211,153,.74));
  box-shadow:inset 0 0 0 1px rgba(167,243,208,.8);
  transition:width .55s var(--ease-out-expo);
  animation:shdBreath 2.2s ease-in-out infinite}
/* OPT-177 翠绿能量盾：呼吸明度 + 高光扫过（OPT-110 液态族），宽度过渡跟随每秒回盾生长 */
.vit-shd::after{content:"";position:absolute;top:0;bottom:0;left:0;width:42%;
  background:linear-gradient(100deg,transparent,rgba(236,254,255,.55) 45%,rgba(236,254,255,.18) 58%,transparent);
  animation:vitSheen 2.8s ease-in-out infinite}
@keyframes shdBreath{0%,100%{filter:brightness(1)}50%{filter:brightness(1.16)}}
/* OPT-110 常态流水感：①渐变摇曳（液面起伏，hp/mp 错拍）②高光斜带周期扫过（流水反光）③
   低血脉动改走 ::before 白罩层（与①②独立共存）。@media 降级尊重系统减动效设置。 */
@keyframes vitSway{from{background-position:0% 0}to{background-position:100% 0}}
@keyframes vitSheen{from{transform:translateX(-110%) skewX(-14deg)}to{transform:translateX(340%) skewX(-14deg)}}
@keyframes vitLow{0%,100%{opacity:0}50%{opacity:.45}}
.vitals .vit-hp{background-size:170% 100%;animation:vitSway 4.5s ease-in-out infinite alternate}
.vitals .vit-mp{background-size:170% 100%;animation:vitSway 6s ease-in-out infinite alternate}
.vitals .vit-fill::after{content:"";position:absolute;top:0;bottom:0;left:0;width:42%;
  background:linear-gradient(100deg,transparent,rgba(255,255,255,.32) 45%,rgba(255,255,255,.1) 58%,transparent);
  animation:vitSheen 3.4s ease-in-out infinite;pointer-events:none}
.vitals .vit-mp::after{animation-duration:4.6s;animation-delay:1.7s} /* 内力条错拍，不同步闪 */
.vit-fill::before{content:"";position:absolute;inset:0;background:#fff;opacity:0;pointer-events:none}
.vit-fill.low::before{animation:vitLow 1s ease-in-out infinite} /* 气血 ≤30% 呼吸警示 */
@media (prefers-reduced-motion: reduce){.vitals .vit-hp,.vitals .vit-mp,.vitals .vit-fill::after,.vit-fill.low::before,.vit-shd,.vit-shd::after{animation:none}}
.vit-hp{background:linear-gradient(90deg,#8f3a32,#b85c50)}
.vit-mp{background:linear-gradient(90deg,#3a5a8f,#5c7fb8)}
.vit-xp{background:linear-gradient(90deg,var(--gold),var(--gold3))}
.vit-num{position:absolute;inset:0;z-index:2;display:flex;align-items:center;justify-content:center;font-size:var(--fs-10);letter-spacing:1px;
  color:var(--onbar);text-shadow:var(--sh-text-onbar);pointer-events:none}
/* OPT-003：HUD 属性速览行已移除——属性详情在属性面板、银两在钱包/商店面板 */

.buffs{flex:0 0 auto;display:flex;flex-wrap:wrap;gap:5px;align-items:center;min-height:26px;padding:4px 14px;background:var(--card);border-bottom:1px dashed rgba(var(--ln),.08)}
.buffs-label{font-size:var(--fs-10);color:var(--mut);letter-spacing:3px}
.buffs-empty{font-size:var(--fs-11);color:var(--faint)}
/* OPT-155：状态栏「正在做什么」活动位（练功/打坐/修炼）——琥珀暖色呼应宣纸主题 */
.buff-doing{font-size:var(--fs-11);color:var(--gold);background:rgba(var(--goldacc),.09);border:1px solid rgba(var(--goldacc),.3);border-radius:var(--r-10);padding:1px 9px}
/* 2026-10-05 影化 V4：减益 chip（黑影侵蚀）——暗红警示色与 buff-doing 同构 */
.buff-debuff{font-size:var(--fs-11);color:var(--seal);background:rgba(var(--sealacc),.09);border:1px solid rgba(var(--sealacc),.35);border-radius:var(--r-10);padding:1px 9px}
/* OPT-291：增益 buff 绿 chip（与减益红 chip 区分；参悟机效姿态/反击势/战斗丹等） */
.buff-up{font-size:var(--fs-11);color:#4a7c46;background:rgba(74,124,70,.09);border:1px solid rgba(74,124,70,.4);border-radius:var(--r-10);padding:1px 9px}
/* OPT-324：chip 可点击（详情浮层）——手型指针提示可点，样式仍由 buff-up/buff-debuff 主导 */
.buff-chip{cursor:pointer}
/* OPT-324：BUFF 详情浮层——chip 点击弹出，fixed 定位在状态栏正下（JS 置 top/left），压过面板(z9) */
.buff-pop{position:fixed;z-index:30;max-width:min(430px,88vw);background:var(--card);border:1px solid rgba(var(--goldln),.55);border-radius:var(--r-8);padding:8px 12px;font-size:var(--fs-12);color:var(--ink);box-shadow:var(--sh-pop)}
.buff-pop .bp-head{font-weight:700;font-size:var(--fs-12-5);letter-spacing:1px}
.buff-pop .bp-left{float:right;font-weight:400;font-size:var(--fs-11);color:var(--mut);margin-left:10px}
.buff-pop .bp-desc{font-size:var(--fs-12);line-height:1.55;color:var(--ink3);margin-top:2px}
/* [死亡UI 2026-10-13]：死亡等待条（state.dead 显隐）——暗红警示与减益 chip 同色系，复活钮醒目 */
.death-bar{flex:0 0 auto;display:flex;flex-wrap:wrap;gap:8px;align-items:center;padding:5px 14px;background:rgba(var(--sealacc),.1);border-bottom:1px solid rgba(var(--sealacc),.4)}
.death-bar .death-text{font-size:var(--fs-11-5);color:var(--seal);letter-spacing:.5px}
.death-bar button{flex:0 0 auto;font-size:var(--fs-12);color:#fff;background:var(--seal);border:none;border-radius:var(--r-10);padding:2px 14px;cursor:pointer;letter-spacing:2px}
/* OPT-200 HUD 技能栏：可释放招式胶囊（气血与状态之间）；冷却/缺内力灰显 */
.mv-pill{display:inline-block;font-size:var(--fs-11);letter-spacing:1px;color:var(--ink3);border:1px solid rgba(var(--goldln),.5);border-radius:var(--r-pill);padding:1px 9px;background:var(--card);cursor:pointer;white-space:nowrap;position:relative;overflow:hidden}
.mv-pill.dim{color:var(--mut);border-color:rgba(var(--ln),.18);background:rgba(var(--cardrgb),.5)}
body.phone .mv-pill{padding:1px 7px}
/* OPT-290 冷却读条（2026-10-07 用户令「旧引擎那种读条」定型）：胶囊 DOM 常驻、JS 原地更新 width，
   transition 重定目标连续排空——重建式渲染下 transition 永不播放、keyframes 随帧重启（均致读条不动）。
   右缘 2px 亮边=排空刃口，随冷却左移。 */
.mv-pill .mv-cd{position:absolute;left:0;top:0;bottom:0;width:0;background:linear-gradient(90deg,rgba(var(--goldln),.3),rgba(var(--goldln),.5));box-shadow:inset -2px 0 0 rgba(150,100,40,.85);z-index:0;pointer-events:none;transition:width 1s linear}
.mv-pill .mv-lb{position:relative;z-index:1}
/* OPT-287 施放动画与 OPT-202 未贯通灰显态已于 2026-10-07 用户令删除（胶囊只剩就绪/灰显两态） */
/* OPT-289：页内输入/确认对话框（替代 window.prompt/confirm——APK WebView 壳未实现 onJsPrompt/onJsConfirm，
   原生弹窗静默返回 null/false=7 处输入点全灭）。z-index 压过 phone 面板(20)。 */
.ask-ov{position:fixed;inset:0;background:rgba(30,27,22,.45);z-index:60;display:flex;align-items:center;justify-content:center}
.ask-box{background:var(--card);border:1px solid rgba(var(--goldln),.5);border-radius:var(--r-4);padding:14px;min-width:240px;max-width:86vw;box-shadow:var(--sh-dialog)}
.ask-tt{font-size:var(--fs-12-5);color:var(--ink3);margin-bottom:8px;white-space:pre-wrap;line-height:1.5}
.ask-in{width:100%;box-sizing:border-box;background:var(--field);border:1px solid rgba(var(--ln),.2);border-radius:var(--r-2);padding:6px 10px;outline:none;font-size:var(--fs-12-5)}
.ask-btns{display:flex;gap:8px;justify-content:flex-end;margin-top:10px}
.ask-btns button{font-size:var(--fs-12);border:1px solid rgba(var(--ln),.2);border-radius:var(--r-2);padding:3px 14px;background:var(--card);color:var(--ink3)}
.ask-btns button.primary{color:var(--priink);background:var(--seal);border-color:var(--seal)}

/* OPT-004：功能入口栏放大 + 自适应换行——字号/内边距/最小宽度加大，行数随屏宽自适应 */
.icons{display:flex;flex-wrap:wrap;gap:4px 2px;padding:6px 10px;border-bottom:1px solid rgba(var(--ln),.1);background:var(--card);flex:0 0 auto}
.icons button{flex:0 0 auto;text-align:center;font-size:13px;letter-spacing:1px;color:var(--ink3);padding:6px 12px;min-width:50px;position:relative;border-radius:var(--r-2);white-space:nowrap}
.icons button::after{content:"";display:block;margin:3px auto 0;width:14px;height:1px;background:rgba(var(--ln),.2)}
/* OPT-158：未读小红点（邮件/公告钮右上角；::after 已被下划线装饰占用故走 ::before） */
.icons button.badge::before{content:"";position:absolute;top:-2px;right:-2px;width:8px;height:8px;border-radius:var(--r-round);background:var(--seal);box-shadow:0 0 0 2px var(--card)}
.icons button:active{color:var(--seal)}
.icons button:active::after{background:var(--seal)}

/* OPT-232 技能/功能栏抽屉：头行点击收起/展开（dr-fold 箭头随态翻转），localStorage 记忆偏好；
   展开态分隔线沿用 .buffs/.icons 各自的 border-bottom，收起态体隐藏后由头行补线 */
.drawer{flex:0 0 auto}
.drawer-head{display:flex;align-items:center;gap:8px;padding:5px 14px;background:var(--card);cursor:pointer;user-select:none;-webkit-user-select:none}
.drawer-head:active .buffs-label{color:var(--seal)}
.drawer-count{font-size:var(--fs-10);color:var(--mut)}
.dr-fold{margin-left:auto;font-size:var(--fs-10);color:var(--mut)}
.dr-fold::after{content:"▾"}
.drawer.folded .dr-fold::after{content:"▸"}
.drawer.folded .drawer-body,
.drawer.folded > .icons{display:none} /* .icons 不加 drawer-body 类：www-client 测试按 class 字面解析按钮，改属性会失配 */
.drawer.folded .drawer-head{border-bottom:1px dashed rgba(var(--ln),.08)}
#icons-drawer.folded .drawer-head{border-bottom:1px solid rgba(var(--ln),.1)}
/* OPT-232c：功能栏展开时头行是冗余一行（末尾已有「收起」钮）——只在收起态显示「功 能」细条作展开入口 */
#icons-drawer:not(.folded) .drawer-head{display:none}

.room{flex:0 0 auto;margin:10px 14px 0;padding:10px 12px 11px;background:var(--card);border:1px solid rgba(var(--ln),.1);
  border-radius:var(--r-2);position:relative;max-height:36%;overflow-y:auto}
.room::before{content:"";position:absolute;left:0;top:8px;bottom:8px;width:2px;background:var(--seal);opacity:.55}
.room-h{display:flex;align-items:center;gap:9px;justify-content:center}
.room-h .ln{flex:1;height:1px;background:linear-gradient(90deg,transparent,rgba(var(--ln),.16))}
.room-h .ln:last-child{background:linear-gradient(90deg,rgba(var(--ln),.16),transparent)}
.rn{font-family:var(--font-kai);font-size:var(--fs-17);letter-spacing:2px;color:var(--ink);white-space:nowrap}
.exits{display:flex;flex-wrap:wrap;gap:6px 16px;justify-content:center;margin-top:7px}
.exits button{font-size:var(--fs-12);color:var(--teal);border-bottom:1px dashed rgba(var(--tealacc),.5);padding-bottom:1px}
.desc{margin-top:8px;font-size:var(--fs-12-5);line-height:1.9;color:var(--ink3);text-indent:2em;word-break:break-all}
.ppl{margin-top:8px;border-top:1px dashed rgba(var(--ln),.12);padding-top:7px;display:flex;flex-direction:column;gap:4px}
.pr{display:flex;align-items:center;gap:8px;font-size:var(--fs-12-5);padding:2px 4px;cursor:pointer}
.pr .dot{width:5px;height:5px;border-radius:var(--r-round);flex:none;align-self:center;background:var(--gold)}
.pr.foe .dot{background:var(--seal)}
.pr.ground .dot{background:var(--mut)}
.pr .pn{width:88px;flex:0 0 auto;color:var(--ink);border-bottom:1px dashed rgba(var(--ln),.2);line-height:1.5}
.pr.foe .pn{color:var(--seal)}
.pr.ground .pn{color:var(--mut)}
.pr.loot .dot{background:var(--gold)}
.pr.loot .pn{color:var(--loot)}
.pbars{flex:1;min-width:0;display:flex;gap:5px}
.ptr{flex:1;min-width:0;height:18px;background:var(--track);border-radius:var(--r-2);position:relative;overflow:hidden;box-shadow:var(--sh-inset-track)}
.ptr i{display:block;height:100%;position:relative;z-index:1;overflow:hidden;
  background:linear-gradient(90deg,#8f3a32,#b85a50);background-size:170% 100%;
  transition:width var(--dur-250) var(--ease-out);animation:vitSway 5.2s ease-in-out infinite alternate}
.ptr i.mp{background:linear-gradient(90deg,#3a5a8f,#5c7fb8);animation-duration:6.4s}
.ptr i::after{content:"";position:absolute;top:0;bottom:0;left:0;width:42%;
  background:linear-gradient(100deg,transparent,rgba(255,255,255,.32) 45%,rgba(255,255,255,.1) 58%,transparent);
  animation:vitSheen 3.8s ease-in-out infinite;pointer-events:none}
.pnum{z-index:2}
.pnum{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:var(--fs-9);letter-spacing:.5px;
  color:var(--onbar);text-shadow:var(--sh-text-onbar);pointer-events:none;white-space:nowrap}

/* OPT-186 房间 NPC 卡片（2026-09-29 用户令）：一怪一卡入经脉同款 jmgrid 网格。.ptr 血条原是
   .pbars 横排行设计（flex:1），入卡（column flex）须改定高不生长——网格默认等高行，少一条的
   卡片余出的竖向空间会让 flex:1 的血条被拉伸变形。卡默认名色沿用主题朱红（红=强敌/首领） */
.jmgrid.npcgrid{margin:2px 0}
.jmcard.npccard{cursor:pointer}
.jmcard.forgecard{cursor:pointer}
.jmcard.forgecard:hover{border-color:rgba(var(--goldln),.5)} /* OPT-201：入口卡可点开专项子页 */
/* OPT-202：宝石孔位行——已镶实线金边/空孔虚线/未开灰置，点选朱红描边 */
.fslots{display:flex;gap:4px;flex-wrap:wrap;margin:2px 0 6px}
.fslot{width:70px;min-height:46px;border:1px dashed rgba(var(--ln),.25);border-radius:var(--r-3);padding:4px 3px;background:rgba(var(--cardrgb),.5);cursor:pointer;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:1px;font-size:var(--fs-11);color:var(--mut);min-width:0}
.fslot.occupied{border-style:solid;border-color:rgba(var(--goldln),.45);background:rgba(var(--cardrgb),.85);color:var(--ink3)}
.fslot.locked{opacity:.5}
.fslot.on{border-color:var(--seal);background:rgba(var(--sealacc),.06)}
.fslot .fn{font-size:var(--fs-8);color:var(--faint)}
.jmcard.npccard:hover{border-color:rgba(var(--sealacc),.5)}
.jmcard.npccard .jm-name{color:var(--seal)}
.jmcard.npccard .ptr{flex:0 0 auto}
/* OPT-215 VIP 三卡片枢纽：三列卡（≤759px 手机降一列，修饰类特异性须在媒体查询显式覆写）；整卡可点进子页 */
.jmgrid.vipgrid{grid-template-columns:repeat(3,1fr)}
.jmcard.vipcard{cursor:pointer}
.jmcard.vipcard:hover{border-color:rgba(var(--goldln),.5)}
.jmcard.vipcard .jm-name{color:var(--gold2)}
/* OPT-225 傀儡师五卡片：两列（≤759px 手机降一列，媒体查询显式覆写）；整卡可点开派遣选择子页 */
.jmgrid.ppgrid{grid-template-columns:repeat(2,1fr)}
.jmcard.ppcard{cursor:pointer}
.jmcard.ppcard:hover{border-color:rgba(var(--goldln),.5)}
.jmcard.ppcard .jm-name{color:var(--gold2)}
.jmcard.pplocked{opacity:.55}.jmcard.pplocked .jm-name{color:var(--mut)}
/* OPT-311 邮件两卡片枢纽（新邮件/已读邮件）：两列（≤759px 手机降一列，媒体查询显式覆写）；整卡可点切换清单 */
.jmgrid.mailgrid{grid-template-columns:repeat(2,1fr)}
.jmcard.mailcard{cursor:pointer}
.jmcard.mailcard:hover{border-color:rgba(var(--goldln),.5)}
.jmcard.mailcard .jm-name{color:var(--gold2)}
/* OPT-188（2026-09-29 用户令）：卡片整体缩至 ~75%——桌面 4→5 列（卡宽 ~80%），内距/字号/
   条高/间距同步缩（卡高 ~75%）。.jmgrid.npcgrid 修饰类特异性高于下方媒体查询的 .jmgrid，
   ≤759px 降 2 列须在媒体查询里对本类显式覆写（.wy5 同款坑） */
.jmgrid.npcgrid{grid-template-columns:repeat(5,1fr);gap:5px}
.jmcard.npccard{padding:4px 6px 3px;gap:2px;font-size:var(--fs-10-5)}
.jmcard.npccard .ptr{height:13px}
.jmcard.npccard .pnum{font-size:var(--fs-8)}
/* OPT-191（2026-09-29 用户令）：同房玩家一卡一格、与 NPC 卡分排——独立网格互不补位（各自
   从行首排，玩家卡永不回填 NPC 网格的尾行空位）。名色青绿=自己人。
   2026-11-08 用户令：卡片可点（lookPlayer→cha 详情子页），hover 同 npccard 手法但青绿描边 */
.jmgrid.allygrid{grid-template-columns:repeat(5,1fr);gap:5px;margin:2px 0}
.jmcard.allycard{padding:4px 6px 3px;font-size:var(--fs-10-5);cursor:pointer}
.jmcard.allycard:hover{border-color:rgba(var(--tealacc),.55)}
.jmcard.allycard .jm-name{color:var(--teal)}

/* OPT-340：播报浮动条——不常驻（默认 display:none 不占布局），sys/传闻播报时浮现
   OPT-340b（2026-10-09 用户令）：浮现位置改顶部玩家名称栏（覆盖 .topbar，top:0）；
   常驻形态整体退役=房间栏/信息栏相应上移。跑马灯滚动一圈后自动隐没（.show 移除） */
.ticker{position:absolute;left:14px;right:14px;top:0;z-index:7;display:none;align-items:center;gap:9px;padding:0 11px;height:30px;
  background:var(--card);border:1px solid rgba(var(--goldacc),.28);border-left:3px solid var(--gold);border-radius:var(--r-2);overflow:hidden;cursor:pointer;
  box-shadow:var(--sh-ticker)}
.ticker.show{display:flex}
.ticker-label{flex:0 0 auto;font-family:var(--font-kai);font-size:var(--fs-11);letter-spacing:4px;color:var(--gold)}
.ticker-view{flex:1;min-width:0;overflow:hidden;white-space:nowrap}
.ticker-text{display:inline-block;white-space:nowrap;font-size:var(--fs-12-5);line-height:30px;color:var(--ink3)}
.ticker-text.run{animation:ticker-run linear} /* OPT-340：跑马灯——时长 JS 按距离定速（约 60px/s） */
@keyframes ticker-run{from{transform:translateX(100vw)}to{transform:translateX(-100%)}}

.logwrap{flex:1;min-height:0;display:flex;flex-direction:row;position:relative}
/* 2026-10-11 用户令：撤宣纸横线笺纹背景（原 repeating-linear-gradient 金色细线，纯装饰） */
#log{flex:1;min-width:0;overflow-y:auto;padding:4px 16px 10px}
.msg{font-size:var(--msg-fs);line-height:2.1;color:var(--ink2);white-space:pre-wrap;word-break:break-all;position:relative;padding-left:9px}
.msg::before{content:"";position:absolute;left:0;top:8px;bottom:8px;width:2px;background:rgba(var(--ln),.1)}
.msg.good{color:var(--good)}.msg.good::before{background:rgba(var(--goodacc),.4)}
.msg.bad{color:var(--bad)}.msg.bad::before{background:rgba(var(--badacc),.45)}
.msg .cin{color:var(--mut)}
hic{color:#2e7d7a} hig{color:var(--good)} hir{color:var(--bad)} hiy{color:#8a6a14}
hiw{color:var(--ink2)} hio{color:#a85c28} him{color:#6d4396}
hij{color:var(--gold)} hik{color:var(--mut)} hib{color:#3a6a9e} red{color:var(--bad)} rep{color:var(--good)}
hiz{color:#6d4396} wht{color:var(--ink2)} blu{color:#3a6a9e} blk{color:#9a9484}

.mapcol{flex:0 0 auto;width:138px;display:flex;flex-direction:column;border-left:1px solid rgba(var(--ln),.12);background:rgba(var(--cardrgb),.72)}
@media (min-width:760px){ .mapcol{width:220px} }
.mc-head{display:flex;align-items:baseline;gap:5px;padding:4px 7px 3px;font-size:var(--fs-10);letter-spacing:1px;color:var(--mut);cursor:pointer;border-bottom:1px dashed rgba(var(--ln),.1)}
.mc-head b{font-family:var(--font-kai);font-weight:normal;font-size:var(--fs-11);letter-spacing:2px;color:var(--seal);flex:0 0 auto}
.mc-head .ms-room{flex:1;text-align:right;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
.mc-fold::after{content:"◂"}
.mc-body{flex:1;display:flex;overflow:auto;padding:3px 4px}
/* 舆图 3×3 方位网格：中央当前房，八方位有出口才渲染按钮（无出口不显示）；铺满舆图栏 */
.map3x3{display:grid;grid-template-columns:repeat(3,1fr);grid-template-rows:repeat(3,1fr);gap:4px;width:100%;min-height:100%}
.m3-empty{border:1px dashed rgba(var(--ln),.07);border-radius:var(--r-2)}
.m3-cur{display:flex;align-items:center;justify-content:center;background:var(--curbg);color:var(--onbar);border-radius:var(--r-2);font-size:var(--fs-12);padding:2px 3px;text-align:center;word-break:break-all;box-shadow:var(--sh-inset-cur)}
.m3-btn{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:1px;background:var(--mapbtn);border:1px solid rgba(var(--ln),.18);border-radius:var(--r-2);cursor:pointer;padding:2px 1px;min-width:0;min-height:0;overflow:hidden}
.m3-btn:hover{background:var(--mapbtnh)}
.m3-btn:active{background:var(--mapbtna)}
.m3-dir{font-size:var(--fs-9);color:var(--mut);letter-spacing:1px;flex:0 0 auto}
.m3-name{font-size:var(--fs-11);color:var(--ink);line-height:1.2;word-break:break-all;text-align:center}
/* 2026-10-13 用户令两连：挂机活动（修炼/练功/打坐/疗伤/学艺/读书）一律锁移动——方向钮整体
   置灰禁点（renderActionBar 按 state.activity 开关 map-body 容器类；类挂容器故房间帧重渲不丢，
   收功/活动位清除自动摘除） */
#map-body.idle-lock .m3-btn{opacity:.45;pointer-events:none}
#map-body.idle-lock .m3-btn:hover{background:var(--mapbtn)}
.mapcol.min{width:30px}
.mapcol.min .mc-head{flex-direction:column;align-items:center;gap:7px;padding:9px 2px}
.mapcol.min .mc-head .ms-room{display:none}
.mapcol.min .mc-fold::after{content:"▸"}
.mapcol.min .mc-body{display:none}
.mapcol.min .actions{display:none}
.mapcol.min .ms-word{display:none}
.ms-word{font-family:var(--font-kai);letter-spacing:2px;color:var(--seal);writing-mode:vertical-rl;font-size:var(--fs-12)}

.actions{flex:0 0 auto;display:flex;flex-direction:column;gap:4px;padding:6px 7px;border-top:1px dashed rgba(var(--ln),.14);max-height:44%;overflow-y:auto}
.actions:empty{display:none}
.actions button{font-size:var(--fs-11-5);letter-spacing:2px;color:var(--ink3);border:1px solid rgba(var(--ln),.18);border-radius:var(--r-2);padding:6px 8px;background:var(--card);text-align:center}
.actions button.primary{color:var(--priink);background:var(--seal);border-color:var(--seal)}
/* OPT-155：练功/打坐/修炼停止钮——朱红描边区别于普通房间动作 */
.actions button.stopbtn{color:var(--seal);border-color:rgba(var(--sealacc),.55)}
.actions button:disabled{opacity:.4;border-style:dashed;cursor:default;color:var(--mut)}

.nav{flex:0 0 auto;display:flex;border-top:1px solid rgba(var(--ln),.14);background:var(--card);padding:8px 8px calc(8px + env(safe-area-inset-bottom))}
.nav button{flex:1;text-align:center;font-size:var(--fs-13);letter-spacing:3px;color:var(--ink3);padding:7px 0;border-radius:var(--r-2);font-family:var(--font-kai)}
.nav button.on{color:var(--priink);background:var(--seal)}

.panel{position:fixed;inset:auto 10px 76px 10px;max-height:62vh;overflow-y:auto;z-index:9;display:none;
  background:var(--card);border:1px solid rgba(var(--ln),.18);border-radius:var(--r-2);padding:10px 12px;box-shadow:var(--sh-panel)}
/* 桌面（≥760px）：二级页面屏幕居中大面板（用户定夺 2026-09-21，原贴右 380px 小窗弃用）；
   宽屏触屏设备同时命中本断点与 body.phone，两规则同为居中 translate，无平移冲突 */
@media (min-width:760px){ .panel{left:50%;top:50%;right:auto;bottom:auto;width:min(720px,92vw);max-height:84vh;transform:translate(-50%,-50%)} }
.panel h3{font-family:var(--font-kai);font-weight:normal;font-size:var(--fs-14);letter-spacing:2px;color:var(--seal);
  border-bottom:1px dashed rgba(var(--ln),.14);padding-bottom:5px;margin-bottom:7px;display:flex;justify-content:space-between;align-items:center}
.panel h3 .x{cursor:pointer;color:var(--mut);font-size:var(--fs-13);letter-spacing:0}
/* OPT-195：背囊标题格数标注（占用格数/容量）——比标题小一号且间距收紧 */
.panel h3 .pdesc{letter-spacing:1px;margin-left:2px}
/* OPT-197：背囊搜索栏——关键字本地过滤免网络；输入中软刷新只刷结果行保焦点 */
.pack-search{margin:0 0 6px}
.pack-search input{width:100%;box-sizing:border-box;background:var(--field);border:1px solid rgba(var(--ln),.2);border-radius:var(--r-2);padding:6px 10px;outline:none;font-size:var(--fs-12-5)}
/* OPT-285：批量使用行内数量输入框——窄框与行按钮同排不挤行高 */
.pack-batch-in{width:64px;box-sizing:border-box;background:var(--field);border:1px solid rgba(var(--ln),.2);border-radius:var(--r-2);padding:2px 6px;outline:none;font-size:var(--fs-11-5)}
/* OPT-360：.prow 全局 flex-wrap 自适应兜底——短行（文字+按钮放得下）保持单行不变，
   放不下时按钮组自动换到第二行、文字独占整行（同 wchan 效果）；动态长度内容
   （活动描述/任务文本/材料清单）不再依赖逐行挂类。wchan 行为是本规则的超集，共存。 */
.prow{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:center;gap:8px;font-size:var(--fs-12-5);padding:4px 2px;border-bottom:1px dashed rgba(var(--ln),.08)}
.psec{font-size:var(--fs-12);letter-spacing:2px;color:var(--gold2);border-bottom:1px solid rgba(var(--ln),.16);padding:7px 2px 3px;margin-top:6px}
/* OPT-235b：傀儡师材料行按钮——按钮外观规则只挂在 .prow 族，「制造」在 .psec 行曾裸文本无样式（用户实测「看不见制造按钮」） */
.pphead{display:flex;justify-content:space-between;align-items:center;gap:8px;flex-wrap:wrap}
.pphead .ppmat{flex:1 1 auto;min-width:0}
.pphead .btns{display:flex;gap:4px;flex:0 0 auto}
.pphead .btns button{font-size:var(--fs-11-5);letter-spacing:normal;border:1px solid rgba(var(--ln),.2);border-radius:var(--r-2);padding:2px 8px;background:var(--card);color:var(--ink3);cursor:pointer}
.pphead .btns button.primary{color:var(--priink);background:var(--seal);border-color:var(--seal)}
/* 2026-10-29 批 A：天赋顶栏（天罡/地煞页签 + 放大/缩小/归中）在 .psec 行内——按钮外观规则此前只挂在
   .pphead/.prow 族（同 OPT-235b 傀儡师「看不见制造按钮」的家族），落到全局 button{background:none;border:none}
   → 实测 5 个按钮 border 0/padding 0/透明/24×24，且当前树的 class="primary" 无任何高亮（玩家看不出
   「这行字能点」「现在在哪棵树」）。用 inline-flex 保持与同行文字并排。
   ⚠ 本规则按「.psec 行内的 .btns」全域生效，另有两个既有面板同样受益（原为裸文本按钮，非破坏性变化）：
   welfare.js:179 赐福「刷新」、forge.js:439 神匠「返回总览」——如日后只想作用于天赋，给天赋行加专属类再收窄。 */
.psec .btns{display:inline-flex;gap:4px;flex-wrap:wrap;vertical-align:middle}
.psec .btns button{font-size:var(--fs-11-5);letter-spacing:normal;border:1px solid rgba(var(--ln),.2);border-radius:var(--r-2);padding:3px 9px;background:var(--card);color:var(--ink3);cursor:pointer}
.psec .btns button.primary{color:var(--priink);background:var(--seal);border-color:var(--seal)}
body.phone .psec .btns button{padding:6px 12px}
/* 手机端隐藏 ×100（2026-10-29 批 A 复核 P1）：375px 下「页签+缩放钮」本就占满一行，
   详情卡四档再挤会折行吃掉星盘高度；×10 与「一键到底」已覆盖手机场景。 */
body.phone .pc-only{display:none}
.score-sp-toggle{display:block;margin:10px auto 2px;font-size:var(--fs-12);letter-spacing:3px;border:1px solid rgba(var(--goldln),.45);border-radius:var(--r-2);padding:3px 22px;background:var(--card);color:var(--gold2);cursor:pointer}
.statrow{display:flex;align-items:stretch;gap:4px;border-bottom:1px dashed rgba(var(--ln),.08);padding:4px 2px}
.statrow .scell{flex:1;min-width:0;text-align:center;display:flex;flex-direction:column;line-height:1.5}
.statrow .scell .k{color:var(--mut);font-size:var(--fs-11);letter-spacing:1px}
.statrow .scell .v{font-size:var(--fs-12-5);color:var(--ink2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* 背囊左右分栏（OPT-010）：装备栏在左、背包在右；手机端上下堆叠且背包在上（高频列表优先） */
.packcols{display:flex;gap:12px;align-items:stretch}
.packcol-eq{flex:0 0 46%;min-width:0}
/* OPT-166：双列独立滚动——装备栏固定（15 槽全显不滚），仅道具列滚动（外层面板随之不滚） */
.packcol-items{flex:1;min-width:0;overflow-y:auto;max-height:calc(84vh - 110px)}
body.phone .packcol-items{max-height:calc(100vh - 180px)}
/* OPT-168：物品名可点开详情——虚线下划线提示可点，色随品级 */
.item-link{cursor:pointer;border-bottom:1px dashed rgba(var(--sep),.5)}
.item-link:hover{filter:brightness(1.25)}
/* OPT-154（2026-09-25 用户令）：手机端背囊同样左右分栏——原 body.phone 上下堆叠特例已删 */
/* 仓库双栏（OPT-206）：左仓库/右背包两列各自独立滚动；手机端同款左右分栏 */
.storecols .storecol{flex:1;min-width:0;overflow-y:auto;max-height:calc(84vh - 130px)}
body.phone .storecols .storecol{max-height:calc(100vh - 190px)}
/* OPT-360 三层防线的按钮组层收口（2026-10-11 用户令修溢出缺陷）：.prow 层 wrap 只保证
   描述与按钮组分行，按钮组自身 flex:0 0 auto 自然宽=最宽内容，多宝石档（4品 8 钮）窄幅
   视口溢出右缘——wrap+max-width:100% 让组钳到行宽后内部折行，宽屏按钮放得下时零变化 */
.prow .btns{display:flex;flex-wrap:wrap;gap:4px;flex:0 0 auto;max-width:100%}
.prow button{font-size:var(--fs-11-5);border:1px solid rgba(var(--ln),.2);border-radius:var(--r-2);padding:2px 8px;background:var(--card);color:var(--ink3)}
.prow button.primary{color:var(--priink);background:var(--seal);border-color:var(--seal)}
/* OPT-349 武韵注入通道行：文字 span 独占整行（flex-basis 100%）把按钮挤到第二行，手机端窄屏提示不再被挤成竖排；row-gap 补两行间距 */
.prow.wchan{flex-wrap:wrap;row-gap:4px}
.prow.wchan>span:first-child{flex:1 1 100%}
.prow.wchan .btns{flex-wrap:wrap}
.pempty{font-size:var(--fs-12);color:var(--faint);padding:4px 0}
.pdesc{font-size:var(--fs-11);color:var(--mut);line-height:1.5}
/* 经脉面板卡片网格：一脉一卡、桌面 4 列（≤759px 手机降 2 列）；活跃脉朱红描边，满级脉降透明度 */
.jmgrid{display:grid;grid-template-columns:repeat(4,1fr);gap:6px;margin:6px 0 2px}
/* 武韵加成卡 5 列变体（2026-09-29 用户令）；≤759px 仍降 2 列——修饰类特异性高于下方媒体查询，须显式覆写 */
.jmgrid.wy5{grid-template-columns:repeat(5,1fr)}
/* OPT-222d 灵药师五张永久丹卡同行（用户令）：5 列变体；≤759px 仍降 2 列（窄屏五列不可读，同 wy5 口径） */
.jmgrid.alc5{grid-template-columns:repeat(5,1fr)}
/* OPT-219 财神盲盒卡片：两列变体；OPT-221 +金票档改三列并列（手机降一列——余额大数/需确认长钮在半宽窄卡折行难读） */
.jmgrid.boxgrid{grid-template-columns:repeat(3,1fr)}
/* OPT-252 西施残页商店七卡导航：三列变体（桌面 3 列放 6 品卡+出售组；≤759px 手机降 1 列，媒体查询显式覆写） */
.jmgrid.xishigrid{grid-template-columns:repeat(3,1fr)}
/* 2026-11-09c 西施三级导航根：兑换商店/出售商店二选一两大卡（两列变体；≤759px 降 1 列同 xishigrid 口径） */
.jmgrid.xishiroot{grid-template-columns:repeat(2,1fr)}
/* 组首卡强制换行（2026-09-29 用户令）：不满五张的组独占一行，禁止下一组自动补位——
   grid 稀疏放置规则：定列起点 1 小于游标当前列时游标下移一行 */
.jmgrid .jmcard.gfirst{grid-column-start:1}
.jmcard{border:1px solid rgba(var(--ln),.16);border-radius:var(--r-3);padding:6px 7px 5px;background:rgba(var(--cardrgb),.65);display:flex;flex-direction:column;gap:3px;font-size:var(--fs-12);min-width:0}
.jmcard.active{border-color:rgba(var(--sealacc),.55);background:rgba(var(--sealacc),.05)}
.jmcard.maxed{opacity:.72}
.jm-top{display:flex;justify-content:space-between;align-items:baseline;gap:4px}
.jm-name{font-weight:bold;color:var(--ink3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.jm-prop{flex:0 0 auto;font-size:var(--fs-10-5);color:var(--gold2)}
.jm-lv{font-size:var(--fs-10-5);color:var(--mut)}
.jm-bar{height:3px;border-radius:var(--r-2);background:rgba(var(--ln),.1);overflow:hidden}
.jm-bar i{display:block;height:100%;background:linear-gradient(90deg,#c9a86a,var(--gold2))}
.jm-desc{font-size:var(--fs-10);color:var(--faint);line-height:1.4;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* T2（2026-10-28）：经脉卡「单脉加成 +N（下级 +M）」行（新帧 bonus/inc 才渲染，旧帧无此行）。
   只加本规则，不动 .jmgrid/.jmcard 既有规则与 ≤759px 媒体查询（桌面 4 列 / 手机 2 列不变） */
.jm-bonus{font-size:var(--fs-10-5);color:var(--gold2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* OPT-185 商城卡片简介两行截断：商品说明比经脉/拍卖一行更长，钳两行保留更多信息（title 悬停看全文） */
.jm-desc.clamp2{white-space:normal;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
.jm-btns{display:flex;flex-wrap:wrap;gap:3px;margin-top:1px} /* OPT-198：宝石卡镶/拆钮多，允许换行 */
.jm-btns button{flex:1 1 auto;font-size:var(--fs-10-5);border:1px solid rgba(var(--ln),.2);border-radius:var(--r-2);padding:2px 0;background:var(--card);color:var(--ink3);cursor:pointer}
.jm-btns button.primary{color:var(--priink);background:var(--seal);border-color:var(--seal)}
@media (max-width:759px){.jmgrid{grid-template-columns:repeat(2,1fr)}.jmgrid.wy5{grid-template-columns:repeat(2,1fr)}.jmgrid.alc5{grid-template-columns:repeat(2,1fr)}.jmgrid.npcgrid{grid-template-columns:repeat(2,1fr)}.jmgrid.allygrid{grid-template-columns:repeat(2,1fr)}.jmgrid.vipgrid{grid-template-columns:repeat(1,1fr)}.jmgrid.boxgrid{grid-template-columns:repeat(1,1fr)}.jmgrid.ppgrid{grid-template-columns:repeat(1,1fr)}.jmgrid.xishigrid{grid-template-columns:repeat(1,1fr)}.jmgrid.xishiroot{grid-template-columns:repeat(1,1fr)}.jmgrid.mailgrid{grid-template-columns:repeat(1,1fr)}}
/* OPT-182 拍卖卡片：复用 jmgrid/jmcard 骨架（与经脉同款）；倒计时条剩 <5 分钟转朱红示警；
   价格/属性短标签禁折行（手机 2 列窄卡「N 筹码」曾折两行，超宽由品级色名侧省略号让位） */
.jm-bar.hot i{background:linear-gradient(90deg,var(--seal),#c96a5a)}
.jm-top .jm-prop{white-space:nowrap}
/* OPT-011 技能分类页签 / OPT-012 江湖副本页签：紧凑标签行 */
.sktabs{display:flex;flex-wrap:wrap;gap:4px;margin:2px 0 6px}
.sktabs button{font-size:var(--fs-11);letter-spacing:1px;border:1px solid rgba(var(--ln),.2);border-radius:var(--r-2);padding:2px 8px;background:var(--card);color:var(--ink3)}
.sktabs button.on{color:var(--priink);background:var(--seal);border-color:var(--seal)}
/* OPT-203：背囊八页签缩小同排——字号/内边距收紧 + 不换行（全 2 字短签）；极窄屏横向滚动兜底。
   只限定背囊列（.packcol-items），任务/锻造/节庆等同 .sktabs 面板不受影响 */
.packcol-items .sktabs{flex-wrap:nowrap;gap:3px;overflow-x:auto}
.packcol-items .sktabs button{font-size:10px;letter-spacing:0;padding:2px 5px;white-space:nowrap}
/* OPT-196 自动连招面板：20 槽网格（桌面 5 列 / 手机 4 列）+ 槽位卡（空槽虚线、已设实线、失效灰显） */
.zsgrid{display:grid;grid-template-columns:repeat(5,1fr);gap:4px;margin:2px 0 6px}
.zs-slot{border:1px dashed rgba(var(--ln),.22);border-radius:var(--r-3);padding:4px 5px 3px;min-height:40px;background:rgba(var(--cardrgb),.5);cursor:pointer;display:flex;flex-direction:column;gap:1px;min-width:0}
.zs-slot.filled{border-style:solid;border-color:rgba(var(--goldln),.45);background:rgba(var(--cardrgb),.85)}
.zs-slot.lost{opacity:.55;border-color:rgba(var(--sealacc),.45)}
.zs-n{font-size:var(--fs-9);color:var(--faint)}
.zs-name{font-size:var(--fs-11);font-weight:bold;color:var(--ink3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.zs-skill{font-size:var(--fs-9-5);color:var(--gold2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.zs-empty{font-size:var(--fs-10-5);color:var(--faint)}
@media (max-width:759px){.zsgrid{grid-template-columns:repeat(4,1fr)}}
/* OPT-161 特殊武功类型抽屉：组头行（点击展开/收起，箭头指示态） */
.drawer-head{display:flex;align-items:center;gap:6px;margin-top:4px;padding:5px 9px;border:1px solid rgba(var(--ln),.2);border-radius:var(--r-2);background:var(--card);color:var(--ink3);font-size:var(--fs-13);letter-spacing:2px;cursor:pointer}
.drawer-head:hover{color:var(--seal);border-color:rgba(var(--sealacc),.5)}
.drawer-head .d-arrow{width:14px;text-align:center}
.drawer-head .d-cnt{margin-left:auto;color:var(--mut);font-size:var(--fs-11-5);letter-spacing:1px}
/* OPT-108 福利签到页 30 日格 */
.signgrid{display:grid;grid-template-columns:repeat(10,1fr);gap:3px;margin:2px 0 8px}
.signgrid i{font-style:normal;text-align:center;font-size:var(--fs-11);line-height:1;padding:4px 0 3px;border:1px solid rgba(var(--ln),.14);border-radius:var(--r-2);color:var(--mut);background:rgba(var(--wht),.5)}
.signgrid i .rw{display:block;margin-top:3px;font-weight:700;color:var(--gold)}
.signgrid i.done{background:var(--seal);border-color:var(--seal);color:var(--priink)}
.signgrid i.done .rw{color:#f2dca8}
.signgrid i.today{border-color:var(--seal);color:var(--seal);font-weight:700;background:rgba(var(--sealacc),.08)}
.signgrid i.today .rw{color:var(--seal)}
/* OPT-016 灵药池充能条 */
.lytrack{height:16px;background:var(--track);border-radius:var(--r-2);overflow:hidden;box-shadow:var(--sh-inset-track);margin:1px 0 5px;position:relative}
.lytrack i{display:block;height:100%;transition:width var(--dur-550) var(--ease-out-expo);position:relative;overflow:hidden}
.lytrack .lyhp{background:linear-gradient(90deg,#8f3a32,#b85c50);background-size:170% 100%;animation:vitSway 4.5s ease-in-out infinite alternate}
.lytrack .lymp{background:linear-gradient(90deg,#3a5a8f,#5c7fb8);background-size:170% 100%;animation:vitSway 5.8s ease-in-out infinite alternate}
/* OPT-181 灵药池能量条液态感：渐变摇曳（双池错拍）+ 高光扫过（复用 HUD vitSheen），条内叠充水百分比 */
.lytrack i::after{content:"";position:absolute;top:0;bottom:0;left:0;width:42%;
  background:linear-gradient(100deg,transparent,rgba(255,255,255,.32) 45%,rgba(255,255,255,.1) 58%,transparent);
  animation:vitSheen 3.4s ease-in-out infinite;pointer-events:none}
.lytrack .lymp::after{animation-duration:4.6s;animation-delay:1.7s}
.ly-pct{position:absolute;right:6px;top:50%;transform:translateY(-50%);font-size:var(--fs-11);font-weight:normal;color:var(--ink2);
  text-shadow:0 0 3px rgba(255,255,255,.85);z-index:1;letter-spacing:1px}
@media (prefers-reduced-motion: reduce){.lytrack .lyhp,.lytrack .lymp,.lytrack i::after{animation:none}}
.chatlog{max-height:34vh;overflow-y:auto;border:1px solid rgba(var(--ln),.12);background:rgba(var(--wht),.55);padding:6px 8px;margin-bottom:8px}
.chatline{font-size:var(--fs-13);line-height:1.9;padding:1px 0;word-break:break-all}
/* OPT-118：行内动作按钮（聊天行「参加」/正文「进入答题」）——全局 button 重置吃掉全部视觉，
   此前「参加」渲染成与正文同色的纯文字，玩家无从辨认可点 */
.chatline button,.msg button{font-size:var(--fs-11-5);border:1px solid var(--seal);border-radius:var(--r-2);padding:1px 9px;background:var(--seal);color:var(--priink);margin-left:6px;vertical-align:middle;letter-spacing:1px}
.chat-input-row{display:flex;gap:7px}
.chat-input-row input{flex:1;background:var(--field);border:1px solid rgba(var(--ln),.2);border-radius:var(--r-2);padding:8px 10px;outline:none}
.chat-input-row button{background:var(--seal);color:var(--sealink);border-radius:var(--r-2);padding:0 14px;font-family:var(--font-kai);letter-spacing:2px}
/* M11 捕获式面板体 + 增益三选一卡 */
.cap-body{font-size:var(--fs-13);line-height:2;color:var(--ink2);white-space:pre-wrap;word-break:break-all}
.cap-body .cin{color:var(--mut)}
.cap-actions{display:flex;flex-wrap:wrap;gap:5px;margin-top:8px}
/* M19 设置页：开关行（宣纸风——墨色边框虚线 + 印章红主按钮） */
.set-list{display:flex;flex-direction:column;gap:4px}
.set-row{display:flex;justify-content:space-between;align-items:center;gap:10px;padding:3px 2px;border-bottom:1px dashed rgba(var(--sep),.25)}
.set-row span:first-child{color:var(--inkrow)}
.set-val{color:var(--setval);font-size:.85rem}
/* OPT-209 快捷操作键帽：小键位牌样式 */
.hk-key{display:inline-block;min-width:26px;padding:1px 8px;border:1px solid var(--hkline);border-radius:var(--r-4);background:rgba(var(--sep),.08);color:var(--hkink);text-align:center;font-style:normal;letter-spacing:1px}
/* OPT-112：胶囊滑动开关——轨道 44×23 圆角满、knob 白圆随状态平移；on=主题红醒目 */
/* 2026-10-30 天赋面板重构：星盘（深色星空画布 + 拖拽缩放）整体退役，改为按阶折叠手风琴。
   原因：72 节点挤进一根 SVG 同心圆，手机端缩放系数 0.22 → 标签仅 2.42px、命中盒 11×11px，
   且旧分环按 id 每 12 个一环、与真实 12 阶完全不对齐（详见 memory 诊断报告 §4）。 */
.talent-acc{border:1px solid rgba(var(--ln),.3);border-radius:var(--r-4);margin:4px 0;overflow:hidden}
/* 阶头卡：整行可点，右对齐本阶进度；已展开时用金色左边条标示 */
.talent-tier{cursor:pointer;background:rgba(var(--cardrgb),.6);padding:7px 8px;border-bottom:1px solid rgba(var(--ln),.14);margin:0}
.talent-tier:hover{background:rgba(var(--cardrgb),.9)}
/* 节点行：缩进以示从属，行高够手指点（手机 375px 下 ≥36px） */
.talent-row{cursor:pointer;padding:8px 8px 8px 26px;border-bottom:1px dashed rgba(var(--ln),.10);margin:0;font-size:var(--fs-12-5)}
.talent-row:hover{background:rgba(var(--ln),.05)}
.talent-row-sel{background:rgba(var(--gold3),.13)}
body.phone .talent-tier{padding:10px 8px}
body.phone .talent-row{padding:11px 8px 11px 26px}
/* 2026-10-29 批 A：详情卡「升级」按钮被裁出可视区——level>0 后卡内容 248px 塞进 46% 视口（205px），
   按钮起点 208.5px → 每次升级都要先在卡里滚一下（玩家与系统的唯一主循环 ×1000 级）。
   两道保险：①可视高度 46%→60%（实测 267px ≥ 内容 248px，含新增 ×10/×100/一键到底 后靠 ②）；
   ②按钮行 sticky 常驻卡底，内容再长也够得着。
   2026-10-30 起详情卡改为手风琴下方**文档流内的卡片**（不再绝对定位浮在星盘上）：
   星盘没了，浮层没有依托对象，内联卡片也不会再遮住列表内容。 */
#talent-detail{border:1px solid rgba(var(--ln),.3);border-radius:var(--r-4);padding:6px 8px;margin:6px 0;
  background:rgba(var(--cardrgb),.97);max-height:60vh;overflow-y:auto}
#talent-detail:empty{display:none}
#talent-detail .prow:last-child{position:sticky;bottom:0;background:rgba(var(--cardrgb),.97);border-bottom:none;padding-top:4px}
.set-switch{position:relative;width:44px;height:23px;border-radius:var(--r-12);background:var(--swtrack);flex:0 0 auto;
  box-shadow:var(--sh-inset-switch);cursor:pointer;transition:background var(--dur-200)}
.set-switch::after{content:"";position:absolute;top:2px;left:2px;width:19px;height:19px;border-radius:var(--r-round);
  background:var(--knob);box-shadow:var(--sh-knob);transition:transform var(--dur-200) var(--ease-out)}
.set-switch.on{background:var(--seal)}
.set-switch.on::after{transform:translateX(21px)}
body.phone .set-switch{width:48px;height:26px}
body.phone .set-switch::after{width:22px;height:22px}
body.phone .set-switch.on::after{transform:translateX(22px)}
.cap-actions button{font-size:var(--fs-11-5);letter-spacing:1px;border:1px solid rgba(var(--ln),.2);border-radius:var(--r-2);padding:4px 9px;background:var(--card);color:var(--ink3)}
.cap-actions button.primary{color:var(--priink);background:var(--seal);border-color:var(--seal)}
.buffcards{display:flex;flex-wrap:wrap;gap:7px;margin:8px 0 4px}
.buffcard{flex:1;min-width:92px;text-align:center;border:1px solid rgba(var(--goldacc),.4);border-radius:var(--r-2);padding:8px 6px;background:rgba(var(--goldacc),.05);cursor:pointer;font-size:var(--fs-12);color:var(--ink3)}
.buffcard:hover{border-color:var(--seal);color:var(--seal)}
.buffcard .bg{font-family:var(--font-kai);font-size:var(--fs-13);color:var(--gold);letter-spacing:1px}
.buffcard .bn{display:block;margin:2px 0}

/* ============ OPT-005 手机端专用适配（body.phone 由设备感知挂载） ============ */
/* 双击缩放防护：manipulation 只禁双击缩放、保留双指捏合（承旧壳 viewport 语义） */
html{touch-action:manipulation}
/* 2026-10-11 用户令：顶部两段（名称栏/播报条+气血内力条）缩小一档；同日续令五档可调（--top-sc） */
body.phone .topbar{padding:calc(5px*var(--top-sc)) 10px calc(4px*var(--top-sc));gap:7px}
body.phone .brand{font-size:calc(13px*var(--top-sc));letter-spacing:2px}
body.phone .vitals{padding:calc(4px*var(--top-sc)) 10px}
body.phone .vit-track{height:calc(15px*var(--top-sc))}
body.phone .vit-num{font-size:calc(10px*var(--top-sc))} /* 数字号随档，防小档溢出条外 */
body.phone .buffs{padding:calc(2px*var(--draw-sc)) 10px;min-height:calc(18px*var(--draw-sc))} /* 2026-10-11 用户令缩小一档（原 22px）；同日续令五档可调（--draw-sc） */
body.phone .drawer-head{padding:calc(4px*var(--draw-sc)) 10px} /* OPT-232：抽屉头行随栏身压紧；热区 28→22px（2026-10-11 用户令）真机点按仍可用 */
/* OPT-072 功能栏压双行（18 钮 9/row）：纵向预算让给舆图移动网格；2026-10-11 用户令按钮再缩一档并五档可调 */
body.phone .icons{padding:calc(3px*var(--draw-sc)) 6px;gap:calc(2px*var(--draw-sc)) 2px}
body.phone .icons button{font-size:calc(11px*var(--draw-sc));letter-spacing:0;padding:calc(3px*var(--draw-sc)) 4px;min-width:38px}
body.phone .icons button::after{margin-top:calc(2px*var(--draw-sc))} /* 文字下装饰线随钮身收拢（基准 3px） */
body.phone .room{margin:calc(6px*var(--room-sc)) 10px 0;max-height:24%;padding:calc(5px*var(--room-sc)) 8px calc(6px*var(--room-sc))} /* 2026-10-11 用户令：房卡再缩并五档可调（--room-sc，横向恒定保布局） */
body.phone .rn{font-size:calc(15px*var(--room-sc))} /* 房名 17→15px 起步，随档缩放 */
body.phone .jmcard.npccard{padding:calc(3px*var(--room-sc)) 5px calc(2px*var(--room-sc))} /* NPC 卡随房卡收拢（基准 4px 6px 3px，横向恒定） */
body.phone .jmcard.npccard .ptr{height:calc(11px*var(--room-sc))} /* 血/内条 13→11px 起步，8px 数字号仍在条内居中 */
body.phone .ticker{left:10px;right:10px;height:calc(24px*var(--top-sc))} /* OPT-340b：浮动条随窄屏收紧（顶部名称栏）；2026-10-11 用户令 28→24px 并五档可调 */
body.phone .ticker-text{font-size:calc(12px*var(--top-sc));line-height:calc(24px*var(--top-sc))} /* 行高随条高对齐（基准 30px 行高会撑出裁切） */
/* 单列堆叠：舆图移到日志下方成横条（折叠态收成细条）；桌面布局零改动 */
body.phone .logwrap{flex-direction:column}
body.phone #log{flex:1;min-height:0}
/* OPT-072 舆图条内容定高（原 36% 残高分摊被房卡/功能栏挤压到 4~32px，3×3 网格
   行高不足 10px、小屏触发 renderMap 24px 保护整块不渲染=移动按钮消失）：
   网格 3 行触控热区恒可见，命令动作栏改单行横滑不再竖排堆叠；
   2026-10-11 用户令缩小一档：网格行 38→32px、动作栏钮 6→4px（矮视口 30px 降档线仍在其下） */
body.phone .mapcol{width:100%;height:auto;flex:0 0 auto;border-left:none;border-top:1px dashed rgba(var(--ln),.14);background:var(--card)}
body.phone .mapcol .ms-word{display:none}
body.phone .map3x3{grid-template-rows:repeat(3,minmax(calc(32px*var(--map-sc)),1fr));min-height:0}
body.phone .actions{flex-direction:row;flex-wrap:nowrap;overflow-x:auto;max-height:none;gap:4px;padding:calc(4px*var(--map-sc)) 5px}
body.phone .actions button{flex:0 0 auto;white-space:nowrap;padding:calc(4px*var(--map-sc)) 10px}
body.phone .mapcol.min{width:100%;height:auto}
body.phone .mapcol.min .mc-head{flex-direction:row;align-items:center;padding:6px 8px}
/* 矮视口（横屏等）：房卡再让位、网格行高降档，保移动网格可见 */
@media (max-height:600px){
  body.phone .room{max-height:18%}
  body.phone .map3x3{grid-template-rows:repeat(3,minmax(calc(30px*var(--map-sc)),1fr))}
  body.phone .actions button{padding:calc(4px*var(--map-sc)) 10px}
}
/* 手机端二级页面=居中卡片模态（2026-11-08 用户令：不再全屏盖脸，面板后方战斗日志保持可见）；
   基础规则 .panel 本身就是滚动容器，卡片继承 overflow-y:auto；宽/高上限目验后可调 */
body.phone .panel{left:50%;top:50%;right:auto;bottom:auto;width:min(560px,94vw);max-height:76vh;transform:translate(-50%,-50%);z-index:20;animation:panelPop var(--dur-160) var(--ease-out)}
@keyframes panelPop{from{transform:translate(-50%,-50%) scale(.96);opacity:0}to{transform:translate(-50%,-50%);opacity:1}}
/* 2026-11-08 续令：不加暗背景遮罩（用户实测后取消）——点卡片外空白关闭走全局点空白机制，
   点控件则控件自己响应（与桌面窄窗同行为）；卡片自身阴影保留用于与背景分层 */
/* 卡片内长内容滚动时标题栏（返回 ›/×）常驻可视区（手法同 #talent-detail 底部 sticky 钮先例） */
body.phone .panel h3{position:sticky;top:0;background:var(--card);z-index:1}
/* 底部导航：2026-10-11 用户令手机端三键缩小一档（原大热区 14px/15px 全键约 49px → 9px/14px 约 38px）；
   同日续令大小五档可调（--nav-sc 系数，设置→界面；横向 padding 恒 0 本就不涉，触控高随档） */
body.phone .nav{padding:0 10px calc(6px + env(safe-area-inset-bottom))}
body.phone .nav button{padding:calc(9px*var(--nav-sc)) 0;font-size:calc(14px*var(--nav-sc));letter-spacing:calc(4px*var(--nav-sc))}

/* OPT-328 天工管理面板：按钮仅管理员可见（login-ok admin 标记 → body.is-admin） */
#btn-admin{display:none}
body.is-admin #btn-admin{display:inline-block}

/* ===== OPT-329 天工管理台（管理员登录直进的全页控制台）===== */
#scr-admin{display:none;min-height:100vh;background:var(--adminbg)}
#scr-admin.on{display:block}
.adm-wrap{max-width:1080px;margin:0 auto;padding:20px 16px 48px}
.adm-head{display:flex;align-items:center;gap:14px;padding:10px 0 14px;border-bottom:2px solid rgba(var(--ln),.15)}
.adm-brand{font-size:var(--fs-20);letter-spacing:2px;color:var(--adink);font-weight:700}
.adm-head button{border:1px solid rgba(var(--ln),.25);background:var(--card);color:var(--ink3);border-radius:var(--r-2);padding:5px 14px;cursor:pointer}
.adm-head button:hover{border-color:var(--seal);color:var(--seal)}
.adm-flash{margin:10px 0;padding:8px 12px;border:1px solid rgba(var(--ln),.15);background:var(--card);border-radius:var(--r-2);font-size:var(--fs-13)}
.adm-tabs{display:flex;gap:4px;margin:14px 0 0;border-bottom:1px solid rgba(var(--ln),.15)}
.adm-tabs button{border:none;background:none;color:var(--ink3);font-size:var(--fs-14);letter-spacing:1px;padding:9px 18px;cursor:pointer;border-bottom:2px solid transparent}
.adm-tabs button.on{color:var(--seal);border-bottom-color:var(--seal);font-weight:700}
#adm-main{padding:16px 2px}
.adm-loading{color:var(--admut);padding:24px 0}
.adm-cards{display:flex;gap:12px;flex-wrap:wrap}
.adm-card{flex:1 1 180px;background:var(--card);border:1px solid rgba(var(--ln),.12);border-radius:var(--r-3);padding:14px 16px}
.adm-card-n{font-size:var(--fs-24);color:var(--adink);font-weight:700}
.adm-card-t{font-size:var(--fs-12);color:var(--admut);margin-top:4px;letter-spacing:1px}
.adm-sec{margin:22px 0 8px;font-size:var(--fs-14);color:var(--adink);letter-spacing:1px}
.adm-bar{display:flex;align-items:center;gap:8px;margin:10px 0 14px;flex-wrap:wrap}
/* 反馈页顶栏：标题与刷新钮不压缩，长说明文字允许换行（原先按钮被挤成一字一行，2026-11-09 实测） */
.adm-bar>b{flex:0 0 auto}
.adm-bar>button{flex:0 0 auto;white-space:nowrap}
.adm-table{width:100%;border-collapse:collapse;background:var(--card);border:1px solid rgba(var(--ln),.12)}
.adm-table th,.adm-table td{border-bottom:1px solid rgba(var(--ln),.08);padding:7px 10px;text-align:left;font-size:var(--fs-13)}
.adm-table th{color:var(--admut);font-weight:400;letter-spacing:1px;background:var(--thead)}
.adm-table a{color:var(--seal);text-decoration:none}
.adm-table button{border:1px solid rgba(var(--ln),.25);background:var(--card);color:var(--ink3);border-radius:var(--r-2);padding:3px 10px;cursor:pointer}
/* 2026-11-09 用户报障「反馈条数过多时下方看不见、没有滚动条」：管理台长表格通用滚动容器。
   #scr-admin 是 min-height:100vh 的整页滚动流，条目一多整页被撑长、页尾内容落到视口外；
   这里给列表加自身滚动区（限高 360px，矮视口降档），表头 sticky 常驻，题目栏固定在上。
   只影响套了 .adm-scroll 的表格，其余管理台表格维持原样。 */
.adm-scroll{max-height:360px;overflow-y:auto;overflow-x:auto;border:1px solid rgba(var(--ln),.12);border-radius:var(--r-2);background:var(--card);-webkit-overflow-scrolling:touch}
.adm-scroll .adm-table{border:none}
.adm-scroll .adm-table th{position:sticky;top:0;z-index:1;box-shadow:0 1px 0 rgba(var(--ln),.12)}
@media (max-height:600px){ .adm-scroll{max-height:240px} }
/* 折叠标题（可点击开合）：标题右侧显示条数与开合提示；默认展开，开合态记忆在 admState.fold。
   箭头是文字的一部分（"▾ 收起"/"▸ 已收起"），不做 rotate 变换。
   white-space:nowrap：flex 子项默认可被压缩到一字一行（"▸ 已收起" 曾竖排成三行，2026-11-09 实测）。 */
.adm-fold{display:flex;align-items:center;gap:8px;cursor:pointer;user-select:none;margin:22px 0 8px;font-size:var(--fs-14);color:var(--adink);letter-spacing:1px}
.adm-fold .adm-fold-hint{color:var(--admut);font-size:var(--fs-12);font-weight:400;letter-spacing:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.adm-fold .adm-fold-ar{margin-left:auto;flex:0 0 auto;white-space:nowrap;color:var(--admut);font-size:var(--fs-12)}
/* 不开 rotate：箭头是文字的一部分（"▾ 收起"/"▸ 已收起"），旋转会把整段文字竖过来（2026-11-09 实测） */
.adm-cols{display:flex;gap:26px;flex-wrap:wrap}
.adm-cols>div{flex:1 1 300px}
.adm-oprow{display:flex;align-items:center;gap:8px;margin:10px 0;flex-wrap:wrap}
.adm-oprow b{min-width:64px;color:var(--adink)}
.adm-oprow input,.adm-oprow select,textarea{border:1px solid rgba(var(--ln),.25);background:var(--field);color:var(--adink);border-radius:var(--r-2);padding:6px 8px;font-size:var(--fs-13)}
.adm-pri{background:var(--seal);color:var(--sealink);border:none;border-radius:var(--r-2);padding:6px 16px;cursor:pointer}
.adm-logpre{background:var(--card);border:1px solid rgba(var(--ln),.12);padding:12px;font-size:var(--fs-12);line-height:1.7;color:var(--ink3);max-height:420px;overflow:auto;white-space:pre-wrap}
#adm-main button{cursor:pointer}
#adm-main .adm-table button:hover,.adm-head button:hover{border-color:var(--seal)}
.adm-pri:hover{background:var(--seal-deep)}

/* OPT-330 兑换码奖励构建器：物品联想下拉 */
.adm-suggest{display:flex;flex-wrap:wrap;gap:4px;margin:2px 0 8px;min-height:0}
.adm-suggest:empty{display:none}
.adm-sug-item{border:1px solid rgba(var(--ln),.25);background:var(--field);color:var(--adink);border-radius:var(--r-2);padding:4px 10px;cursor:pointer;font-size:var(--fs-13)}
.adm-sug-item:hover{border-color:var(--seal);color:var(--seal)}
#adm-reward-list a{cursor:pointer}
/* ===== OPT-351 主题层：黑夜（墨夜宣纸）/ 护眼（豆青纸）——只覆写变量 + 少量补钉 ===== */
/* 黑夜：纸墨反转、线条转浅色低透明、强调色（印章红/金/青绿/增益绿/警示红）整体提亮保对比；
   sealink/priink/onbar 恒亮不覆写。hi* 消息色签与 buff-up 绿、ly-pct 白晕为非变量残段，在此补钉。 */
body.theme-dark{
  --paper:#262219; --card:#2e2a22; --cardrgb:46,42,34; --field:#211e17; --wht:40,36,29;
  --knob:#e6ddc8;
  --ink:#e6ddc8; --ink2:#d6ccb4; --ink3:#c3b89f; --mut:#97907e; --faint:#6e675a;
  --inkrow:#d6ccb4; --inksub:#c3b89f; --inkdeep:#d6ccb4; --innfoot:#97907e;
  --setval:#b3a684; --hkink:#c3b89f; --hkline:#6e675a;
  --ln:216,204,180; --sep:150,136,108; --track:#3b362b;
  --seal:#c9503f; --seal-deep:#d96a58; --sealacc:201,80,63;
  --gold:#c9a24a; --gold2:#c9a86a; --gold3:#e0c184; --goldacc:186,146,58; --goldln:172,142,86;
  --teal:#63aa96; --tealacc:99,170,150;
  --good:#63b386; --goodacc:99,179,134; --bad:#e06a5a; --badacc:224,106,90;
  --loot:#d4af5c;
  --mapbtn:#3b362b; --mapbtnh:#474134; --mapbtna:#544d3d; --curbg:#6a6350;
  --swtrack:#4a4436;
  --adminbg:#262219; --adink:#e6ddc8; --admut:#97907e; --thead:#332f26;
  --ok:#63b386; --ok2:#7fbf76;
  --okink:#7fbf76; --mutcool:#a49eb6; --statink:#c9b07a; --affix-blue:#7fa8d8; --affix-purple:#b08ae0;
}
body.theme-dark hic{color:#5fb3a8} body.theme-dark hig{color:#66b98a} body.theme-dark hir{color:#e2726a}
body.theme-dark hiy{color:#d4af5c} body.theme-dark hiw{color:#cfc5b2} body.theme-dark hio{color:#d98d55}
body.theme-dark him{color:#b08ae0} body.theme-dark hij{color:#c9a24a} body.theme-dark hik{color:#97907e}
body.theme-dark hib{color:#7fa8d8} body.theme-dark red{color:#e2726a} body.theme-dark rep{color:#66b98a}
body.theme-dark hiz{color:#b08ae0} body.theme-dark wht{color:#cfc5b2} body.theme-dark blu{color:#7fa8d8}
body.theme-dark blk{color:#8a8272}
body.theme-dark .buff-up{color:#7ab86f;background:rgba(122,184,111,.12);border-color:rgba(122,184,111,.4)}
body.theme-dark .ly-pct{text-shadow:0 0 3px rgba(20,17,12,.85)}
/* 护眼：豆青纸面与墨色加深调绿；印章红/金/青绿等强调色沿用浅色默认（豆青底上均协调）。 */
body.theme-eyecare{
  --paper:#dce8d3; --card:#e8f0de; --cardrgb:232,240,222; --field:#f3f8ec; --wht:243,248,236;
  --knob:#e8f0de;
  --ink:#2b332a; --ink2:#3c443a; --ink3:#4b5449; --mut:#74806b; --faint:#98a48f;
  --inkrow:#3c443a; --inksub:#4b5449; --inkdeep:#323a30; --innfoot:#74806b;
  --setval:#63735a; --hkink:#54604a; --hkline:#8fa07f;
  --ln:64,76,58; --sep:104,118,90; --track:#cfe0c1;
  --mapbtn:#d2e1c5; --mapbtnh:#c4d7b4; --mapbtna:#b4cca2; --curbg:#66755c;
  --swtrack:#bfd2b2;
  --adminbg:#dce8d3; --adink:#2b332a; --admut:#74806b; --thead:#d3e2c4;
  --okink:#4e7a4c; --mutcool:#6e6984; --affix-blue:#4a6e9c; --affix-purple:#7a5a9a;
}
/* OPT-351 设置页「界面」页签主题三选一（浅色/黑夜/护眼） */
.theme-btns{display:flex;gap:4px}
.theme-btns button{font-size:var(--fs-11);letter-spacing:1px;border:1px solid rgba(var(--ln),.2);border-radius:var(--r-2);padding:2px 8px;background:var(--card);color:var(--ink3)}
.theme-btns button.on{color:var(--priink);background:var(--seal);border-color:var(--seal)}
/* 2026-10-11 用户令：日志字号五档（设置→界面页签，localStorage ng_logfs；缺省/无效值=默认 12px）。
   .msg 行高 2.1 为无单位倍数随字号等比缩放；宣纸横线背景已撤（同日用户令），无背景节拍联动项 */
body.logfs-16{--msg-fs:16px}
body.logfs-14{--msg-fs:14px}
body.logfs-12{--msg-fs:12px}
body.logfs-10{--msg-fs:10px}
body.logfs-8{--msg-fs:8px}
/* 2026-10-11 用户令：五大区域尺寸五档（设置→界面页签，localStorage ng_area_sc 合一 JSON；缺省/无效=1 即当日调整值）。
   系数消费：nav=底部三键 / map=舆图栏 / top=名称播报+状态条 / draw=抽屉头+状态+功能钮 / room=房卡。
   档位：sc130=超大 1.3、sc115=大 1.15、sc100=默认 1、sc85=小 0.85、sc70=超小 0.7 */
body.nav-sc130{--nav-sc:1.3}body.nav-sc115{--nav-sc:1.15}body.nav-sc100{--nav-sc:1}body.nav-sc85{--nav-sc:.85}body.nav-sc70{--nav-sc:.7}
body.map-sc130{--map-sc:1.3}body.map-sc115{--map-sc:1.15}body.map-sc100{--map-sc:1}body.map-sc85{--map-sc:.85}body.map-sc70{--map-sc:.7}
body.top-sc130{--top-sc:1.3}body.top-sc115{--top-sc:1.15}body.top-sc100{--top-sc:1}body.top-sc85{--top-sc:.85}body.top-sc70{--top-sc:.7}
body.draw-sc130{--draw-sc:1.3}body.draw-sc115{--draw-sc:1.15}body.draw-sc100{--draw-sc:1}body.draw-sc85{--draw-sc:.85}body.draw-sc70{--draw-sc:.7}
body.room-sc130{--room-sc:1.3}body.room-sc115{--room-sc:1.15}body.room-sc100{--room-sc:1}body.room-sc85{--room-sc:.85}body.room-sc70{--room-sc:.7}
