
  * { margin:0; padding:0; box-sizing:border-box; -webkit-tap-highlight-color:transparent; }
  html, body { width:100%; height:100%; overflow:hidden; background:#05070d; touch-action:none;
    user-select:none; -webkit-user-select:none; font-family:"Courier New",Consolas,monospace; color:#d8e6ff; }
  /* 触屏滚动：body 上的 touch-action:none 会沿祖先链取交集，把子元素的原生滚动手势
   * 也一起禁掉——图鉴/商店/公告/免责声明这些面板在手机上全都滚不动。
   * 这里给滚动容器单独放开纵向手势（画布与拖动画布仍保持 none，不影响摇杆和树形拖动）。 */
  .overlay, .csNoBar, #discToc, #boot {
    touch-action: pan-y;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
  }
  /* 树形视图是自定义拖动画布，不能被浏览器当成滚动抢走 */
  #treeStage, #treeGraph { touch-action: none; }
  /* 注意：不能用 inset:0（Chrome 87+ 才有）。OPPO R9s Plus 等老 WebView（约 Chrome 50）
     会整条丢弃该声明，容器失去尺寸约束塌缩到左上角，表现为「游戏缩在左上角、周围全黑」。
     一律写成 top/left/right/bottom + width/height 的老写法，全版本兼容。 */
  #wrap { position:fixed; top:0; left:0; right:0; bottom:0; width:100%; height:100%; }
  canvas { display:block; width:100%; height:100%; touch-action:none; }
  /* 扫描线：像素科幻风 */
  #wrap::after { content:''; position:absolute; top:0; left:0; right:0; bottom:0; width:100%; height:100%; pointer-events:none; z-index:30;
    background:repeating-linear-gradient(180deg, rgba(255,255,255,.035) 0 1px, rgba(0,0,0,0) 1px 3px); }
  /* 面板容器。注意这里【不能】用 justify-content:center：
   * flex 列布局里内容一旦超出容器高度，center 会让内容同时向上下两侧溢出，
   * 而上溢出的部分滚动条永远滚不到（scrollTop 不能为负）——
   * 表现就是小屏上「顶部几项设置看不到、只能勉强够到按钮」。
   * 解决办法：改成 flex-start，再用 ::before / ::after 两个零高度弹性项
   * 各带一个 auto 外边距来吃剩余空间：空间够时自动居中（与原来视觉一致），
   * 空间不够时 auto 归零、内容从顶部排布，全部可滚动到。
   * 用伪元素而非 :first-child/:last-child，是因为首尾元素可能被 .hidden 隐藏，
   * 那样选择器仍会命中但 margin 不生效，居中就失效了。 */
  .overlay { position:absolute; top:0; left:0; right:0; bottom:0; width:100%; height:100%;
    display:flex; flex-direction:column; align-items:center; justify-content:flex-start;
    gap:12px; background:rgba(5,7,13,.94); z-index:10; padding:16px; overflow-y:auto;
    -webkit-overflow-scrolling:touch; }
  .overlay::before { content:''; display:block; height:0; margin-top:auto; }
  .overlay::after { content:''; display:block; height:0; margin-bottom:auto; }
  .hidden { display:none !important; }

  /* ===== 自定义滚动条 =====
   * 需求：把浏览器原生滚动条全部换掉，用一套自己的。
   * 老内核（Chrome 50 左右）不认 scrollbar-width，但 ::-webkit-scrollbar 从 Chrome 4 就有，
   * 所以这里用 webkit 伪元素把原生条压成 0 宽即可，不用任何新语法。
   * 注意：这个 class 由 JS 在成功绑定自定义滚动条之后才加上——
   * 万一自定义条初始化失败，原生条会留着兜底，不会出现「滚不动」。 */
  .csNoBar::-webkit-scrollbar { width:0 !important; height:0 !important; }
  .csNoBar::-webkit-scrollbar-thumb { background:transparent !important; }
  .csNoBar::-webkit-scrollbar-track { background:transparent !important; }
  /* 轨道：贴容器右内侧的细长条，固定定位，由 JS 每次按容器实际位置摆放 */
  .csTrack { position:fixed; z-index:60; width:6px; border-radius:3px;
    background:rgba(127,232,255,.10); opacity:0; pointer-events:none;
    transition:opacity .18s linear; }
  .csTrack.csOn { opacity:1; pointer-events:auto; }
  /* 滑块：可拖动。加大 hit 区域（左右各扩 7px）方便手指按住 */
  .csThumb { position:absolute; left:-1px; width:8px; border-radius:4px;
    background:#4fd7ff; box-shadow:0 0 8px rgba(79,215,255,.45); cursor:pointer;
    -webkit-user-select:none; user-select:none; touch-action:none; }
  .csThumb::before { content:''; position:absolute; left:-7px; right:-7px; top:0; bottom:0; }
  .csTrack.csDrag .csThumb { background:#7fe8ff; }
  /* 老机型：去掉阴影与圆角，减少绘制开销 */
  .q-low .csThumb { box-shadow:none; border-radius:2px; }
  .q-low .csTrack { border-radius:2px; }
  h1 { font-size:26px; letter-spacing:3px; color:#7fe8ff; text-shadow:0 0 14px rgba(127,232,255,.55), 2px 2px 0 #123; }
  h2 { font-size:20px; letter-spacing:2px; color:#ffd24a; text-shadow:2px 2px 0 #231a00; }
  h3 { font-size:15px; letter-spacing:1px; color:#9fd0ff; }
  .tip { font-size:12px; color:#8fa2c4; line-height:1.9; text-align:center; }
  .btn { padding:11px 26px; font-size:15px; font-family:inherit; font-weight:700; letter-spacing:2px;
    border:2px solid #7fe8ff; background:#0d1526; color:#7fe8ff; cursor:pointer;
    box-shadow:3px 3px 0 #0a2540, 0 0 12px rgba(127,232,255,.18) inset; }
  .btn:active { transform:translate(2px,2px); box-shadow:1px 1px 0 #0a2540; }
  .btn.primary { border-color:#ffd24a; color:#ffe08f; box-shadow:3px 3px 0 #3a2a00; }
  .btn.small { padding:7px 14px; font-size:12px; letter-spacing:1px; }
  .btn:disabled { border-color:#39415c; color:#5b6684; box-shadow:none; cursor:default; }
  .row { display:flex; gap:10px; flex-wrap:wrap; justify-content:center; }
  .coins { font-size:14px; color:#ffd24a; letter-spacing:1px; }
  #menuBtns { display:flex; flex-direction:column; gap:10px; width:230px; flex:0 0 auto; }
  #menuBtns .btn { width:100%; }
  /* 设置面板：分组 + 档位按钮 */
  .setGroup { width:100%; max-width:430px; border:2px solid #223052; background:#0b1220;
    padding:10px 12px; }
  /* 存档码面板：极高内容（两个输入框）在矮屏会把返回按钮顶出视口。
   * 做法与免责声明一致——禁用 overlay 的 auto margin 居中（它会优先吃掉 flex 剩余空间），
   * 让内容区自己滚动，返回按钮就始终留在底部可见。 */
  #panelSaveCode::before, #panelSaveCode::after { display:none; }
  #scBody { flex:1 1 auto; min-height:0; overflow-y:auto; align-self:stretch; }
  .scBox { width:100%; box-sizing:border-box; background:#070c16; color:#dcebff;
    border:2px solid #223052; padding:8px 10px; font-size:12px; line-height:1.6;
    font-family:ui-monospace, Menlo, Consolas, monospace; word-break:break-all;
    resize:vertical; -webkit-user-select:text; user-select:text; }
  .setTitle { font-size:13px; color:#cfe6ff; font-weight:700; letter-spacing:1px; }
  .setGroup .tip { text-align:left; margin:2px 0 8px; }
  .setGroup .row { gap:8px; }
  .seg { border:2px solid #2b3550; background:#0b1220; color:#8fa2c4;
    padding:6px 14px; font-family:inherit; font-size:12px; cursor:pointer; letter-spacing:1px; }
  .seg.on { border-color:#ffd24a; color:#ffd24a; box-shadow:0 0 10px rgba(255,210,74,.22); }
  .seg:active { border-color:#7fe8ff; }
  /* 天赋行 —— 双列紧凑卡片（原来是一整行一条，6 项要滚很久） */
  #upList { display:flex; flex-wrap:wrap; gap:8px; justify-content:center;
    width:100%; max-width:520px; }
  .talent { width:calc(50% - 4px); max-width:250px; box-sizing:border-box;
    display:flex; flex-direction:column; align-items:stretch; gap:3px;
    border:2px solid #223052; background:#0b1220; padding:5px 6px; }
  .talent .info { min-width:0; }
  .talent .nm { font-size:11px; color:#cfe6ff; font-weight:700; line-height:1.3; }
  .talent .nm .lv { color:#ffd24a; }
  .talent .nm .val { color:#8fff9f; font-weight:400; }
  .talent .ds { font-size:9.5px; color:#8fa2c4; line-height:1.4; margin-top:1px; }
  .talent .pips { display:flex; flex-wrap:wrap; gap:1.5px; margin-top:3px; }
  .talent .pip { width:7px; height:6px; background:#223052; }
  .talent .pip.on { background:#ffd24a; box-shadow:0 0 4px rgba(255,210,74,.6); }
  .talent .buy { width:100%; padding:4px 3px; font-size:10.5px; letter-spacing:0; }
  @media (max-width:359px) {
    /* 极窄屏放两列会挤成一团，退回单列 */
    .talent { width:100%; max-width:300px; }
    .no-gap .talent { width:calc(100% - 12px); max-width:none; }
  }
  /* 角色 / 章节卡片 */
  .grid { display:flex; gap:10px; flex-wrap:wrap; justify-content:center; width:100%; max-width:520px; }
  .pick { width:100%; max-width:230px; border:2px solid #223052; background:#0b1220; padding:10px; cursor:pointer; text-align:left; }
  .pick.sel { border-color:#ffd24a; box-shadow:0 0 14px rgba(255,210,74,.25); }
  .pick.lock { opacity:.62; }
  .pick .pt { font-size:14px; font-weight:700; margin-bottom:4px; }
  .pick .pd { font-size:11px; color:#8fa2c4; line-height:1.6; }
  .pick .ps { font-size:11px; color:#ffd24a; margin-top:6px; }
  /* 章节剧情：仿视觉小说，居中大字，一页一句 */
  #storyBody { width:100%; max-width:460px; min-height:120px; padding:18px 16px;
    border:2px solid #223052; background:#0b1220; text-align:center;
    display:flex; flex-direction:column; justify-content:center; }
  #storyWho { font-size:12px; color:#ffd24a; letter-spacing:2px; margin-bottom:10px; min-height:16px; }
  #storyWho:empty { margin-bottom:0; min-height:0; }
  #storyText { font-size:15px; color:#dbe6ff; line-height:1.9; white-space:pre-wrap; }
  #storyPage { font-size:11px; color:#5f6d8c; letter-spacing:1px; }
  /* 挑战面板：2 列排布（用 flex-wrap + calc，不用 grid/gap，兼容老 WebView） */
  #chalBody { display:flex; flex-wrap:wrap; width:100%; max-width:520px; }
  #chalBody > .pick { flex:1 1 calc(50% - 10px); width:auto; min-width:138px; max-width:250px;
    margin:0 5px 10px; }
  @media (max-width:420px) {
    #chalBody { max-width:100%; }
    #chalBody > .pick { min-width:130px; }
  }
  /* 顶级智斗 · 选武器：多列排布（15 把武器竖着排会有 1500px 高，
   * 「出发」按钮被埋在屏幕外 1600px 处，玩家根本看不到 —— 已实测踩到）。
   * 用 flex-wrap + calc，不用 grid/gap，兼容老 WebView。 */
  #wpBody { display:flex; flex-wrap:wrap; width:100%; max-width:560px; }
  #wpBody > .pick { flex:1 1 calc(50% - 10px); width:auto; max-width:none; margin:0 5px 10px; }
  /* 底部操作栏吸底：无论滚到哪都能看见「出发」，不再被武器卡片埋掉 */
  #panelWeaponPick > .row.wpBar {
    position:sticky; bottom:-16px; width:100%; max-width:560px; margin:0 auto;
    background:rgba(8,12,22,.97); border-top:2px solid #223052;
    padding:10px 0 12px; z-index:5;
  }
  /* 选满时的「出发」按钮：高亮成金色，明确告诉玩家可以点了 */
  #btnWpGo.ready { background:#7a5a12; border-color:#ffd24a; color:#fff6cf;
    box-shadow:0 0 14px rgba(255,210,74,.3); }
  /* 360 及以上仍保持两列（卡片再窄就读不清了，356 以下才退回单列） */
  @media (max-width:356px) {
    #wpBody { max-width:100%; }
    #wpBody > .pick { flex:1 1 100%; margin:0 0 10px; }
  }
  @media (max-width:420px) {
    #panelWeaponPick > .row.wpBar { max-width:100%; }
  }
  #cards, #evoCards { display:flex; gap:10px; flex-wrap:wrap; justify-content:center; width:100%; max-width:800px; }
  .card { flex:1 1 190px; min-width:150px; max-width:250px; background:#0b1220; border:2px solid #223052;
    padding:12px; cursor:pointer; text-align:left; }
  .card .t { font-size:15px; font-weight:700; margin-bottom:5px; }
  .card .d { font-size:11px; color:#8fa2c4; line-height:1.6; min-height:38px; }
  .card .lv { font-size:11px; color:#ffd24a; margin-top:7px; }
  .btn.danger { background:#7a1f2b; border-color:#ff5b5b; color:#ffd7d7; }
  /* 天赋树卡片：flex-wrap 网格，不用 CSS Grid（老内核不支持） */
  /* .setGroup 不写宽度的话会按内容算（实测只有 430px，body 有 780px），
     整个分组贴左边、右边空一大片 —— 这就是「板块向左偏移」。 */
  /* 必须连 max-width 一起清掉：.setGroup 自带 max-width:430px（设置面板用的窄分组），
     只写 width:100% 会被它卡住，宽屏上分组仍是 430、右边空一大片。 */
  #treeBody .setGroup { width:100%; max-width:none; }
  /* 最后一行不满 3 个时居中，否则会孤零零贴在最左边 */
  .skillRow { display:flex; flex-wrap:wrap; width:100%; justify-content:center; }
  .skillCard { flex:1 1 calc(33.33% - 10px); min-width:118px; max-width:240px; margin:0 5px 10px;
    background:#0b1220; border:2px solid #223052; border-radius:9px; padding:10px;
    cursor:pointer; text-align:left; font-family:inherit; color:#cfe6ff; }
  .skillCard:active { border-color:#ffd24a; }
  .skillCard.locked { opacity:0.5; cursor:default; }
  .skillCard.maxed { border-color:#7a5f1f; }
  .skillCard .sn { font-size:13px; font-weight:700; margin-bottom:4px; display:flex;
    justify-content:space-between; align-items:center; }
  .skillCard .sl { font-size:10px; color:#ffd24a; font-weight:400; }
  .skillCard .sd { font-size:10px; color:#8fa2c4; line-height:1.55; min-height:32px; }
  .skillCard .sf { font-size:11px; margin-top:6px; font-weight:700; }
  .skillCard .sdots { display:flex; gap:3px; margin-top:6px; }
  .skillCard .sdots i { width:100%; height:4px; border-radius:2px; background:#1b2846; display:block; }
  .skillCard .sdots i.on { background:#ffd24a; }
  #treeSp { text-align:center; margin:4px 0 2px; }

  /* ===== 天赋树：视图切换按钮（圆角胶囊）=====
   * 两种视图：板块（旧版列表）/ 树形（可拖动连线图）。 */
  #treeViewBar { display:flex; gap:8px; justify-content:center; margin:6px 0 10px; }
  .seg.rnd { border-radius:999px; padding:6px 18px; }
  .no-gap #treeViewBar > * { margin-right:8px; }
  .no-gap #treeViewBar > *:last-child { margin-right:0; }

  /* ===== 树形视图：可拖动 / 可缩放的连线图 =====
   * 结构：#treeStage（固定视口，overflow:hidden）
   *        └ #treeWorld（内容层，transform 平移+缩放）
   *            ├ svg#treeLines（连线，铺满内容层，pointer-events:none）
   *            └ .skillNode（绝对定位的节点卡片）
   * 拖动用 transform 而非 scroll：缩放后 scrollWidth 会失真，且
   * transform 在老内核上也更稳。 */
  /* 注意：overlay 是 flex column + align-items:center，子元素宽度默认按内容算，
   * 不写 width:100% 的话 stage 会被压成很窄一条（实测只有 190px）。 */
  #treeStage { position:relative; overflow:hidden; background:
      radial-gradient(circle at 50% 42%, #101a30 0%, #070b14 72%);
    border:2px solid #1c2740; border-radius:10px; margin:0 auto 8px;
    width:100%; touch-action:none; cursor:grab;
    /* 高度由 layoutTreeStage() 按面板剩余空间实测后写入，
       不用 vh 死值 —— 不同屏幕上方元素占高不同，写死会留一大片空白。 */
    height:520px; min-height:150px; }
  #treeBody { width:100%; }
  /* 树形视图：让画布吃掉面板剩余高度，做到「全屏」。
   * 只有切到树形时才给 panel 加 .tree-fill —— 板块视图要正常滚动，不能被撑开。
   * min-height:0 是必须的：flex 子项默认 min-height:auto，
   * 内容高过容器时会拒绝收缩，反而把面板顶出滚动条。 */
  /* 关键：overlay 的 ::before/::after 用 margin-top/bottom:auto 做垂直居中。
     按 CSS 规范，auto margin 会【优先】吃掉剩余自由空间，之后才轮到 flex-grow，
     所以不禁用它的话 #treeGraph 的 flex:1 一点空间都分不到（实测完全没变大）。 */
  #panelTree.tree-fill::before, #panelTree.tree-fill::after { margin:0; }
  /* 树形视图下藏掉顶部那句说明：它在画布上方白占一行（小屏上尤其明显）。
     信息不丢 —— 切回「板块」视图就在，而且点数下面那行仍然写着折算比例。 */
  #panelTree.tree-fill #treeTip { display:none; }
  #panelTree.tree-fill #treeGraph { flex:1 1 auto; min-height:0;
    display:flex; flex-direction:column; }
  #panelTree.tree-fill #treeStage { flex:1 1 auto; width:100%;
    height:auto; min-height:200px; }
  #treeZoomRow { position:absolute; right:8px; bottom:6px; z-index:3; gap:6px; }
  #treeZoomRow button { background:rgba(11,18,32,.88); }
  /* 缩放按钮浮进画布右下角，省掉单独一行（多给画布约 50px）。
     半透明底 + 不吃指针事件以外的区域，避免挡住节点。 */
  #panelTree.tree-fill #treeZoomRow { position:absolute; right:8px; bottom:6px;
    z-index:3; gap:6px; }
  /* 提示移到左下角，给缩放按钮让位 */
  #panelTree.tree-fill #treeHint { right:auto; left:8px; }
  /* 父容器也要撑满：#treeGraph 本身也是 flex 子元素，
   * 它不写 width:100% 的话，stage 的 100% 就只有 190px。 */
  #treeGraph { width:100%; }
  #treeStage.grabbing { cursor:grabbing; }
  #treeWorld { position:absolute; left:0; top:0; transform-origin:0 0; will-change:transform; }
  #treeLines { position:absolute; left:0; top:0; overflow:visible; pointer-events:none; }
  #treeHint { position:absolute; right:8px; bottom:6px; font-size:10px; color:#4d5a78;
    pointer-events:none; }
  .skillNode { position:absolute; width:132px; padding:7px 8px;
    background:#0b1220; border:2px solid #223052; border-radius:9px;
    cursor:pointer; text-align:left; font-family:inherit; color:#cfe6ff;
    box-sizing:border-box; }
  .skillNode:active { border-color:#ffd24a; }
  .skillNode.locked { opacity:.5; cursor:default; }
  .skillNode.maxed { border-color:#7a5f1f; box-shadow:0 0 12px rgba(255,210,74,.20); }
  .skillNode.ready { border-color:#7fe8ff; box-shadow:0 0 12px rgba(127,232,255,.22); }
  .skillNode .sn { font-size:12px; font-weight:700; display:flex;
    justify-content:space-between; align-items:center; line-height:1.3; }
  .skillNode .sl { font-size:9px; color:#ffd24a; font-weight:400; }
  .skillNode .sd { font-size:9px; color:#8fa2c4; line-height:1.5; margin-top:3px; }
  .skillNode .sf { font-size:10px; margin-top:4px; font-weight:700; }
  .skillNode .sdots { display:flex; gap:2px; margin-top:5px; }
  .skillNode .sdots i { width:100%; height:3px; border-radius:2px; background:#1b2846; display:block; }
  .skillNode .sdots i.on { background:#ffd24a; }
  .no-gap .skillNode .sdots > * { margin-right:2px; }
  .no-gap .skillNode .sdots > *:last-child { margin-right:0; }
  #treeZoomRow { justify-content:center; gap:8px; }
  .no-gap #treeZoomRow > * { margin-right:8px; }
  .no-gap #treeZoomRow > *:last-child { margin-right:0; }
  .card.evo { box-shadow:0 0 20px rgba(255,210,74,.28); }
  #overStats { display:flex; gap:20px; margin:2px 0; flex-wrap:wrap; justify-content:center; }
  .stat { text-align:center; min-width:70px; }
  .stat b { display:block; font-size:22px; color:#ffd24a; }
  .stat span { font-size:11px; color:#8fa2c4; }
  #overExtra { font-size:11px; color:#8fa2c4; text-align:center; line-height:1.9; max-width:340px; }
  .sub { font-size:11px; color:#5f6d8c; letter-spacing:1px; }
  /* 用户信息条（B站 Toy SDK 头像昵称） */
  /* 主菜单区：按钮竖列保持屏幕正中；设置小图标绝对定位到它左侧，不占布局流 */
  #menuMain { position:relative; display:flex; align-items:center; justify-content:center;
    margin-top:4px; width:100%; }
  /* right = 按钮列半宽 115px + 间距 14px，元素向左展开，因此不会把按钮列推偏 */
  /* 左栏竖排三个：商店在最上，成就居中，设置在下（都是绝对定位，不占布局流，按钮列仍严格居中） */
  #menuSetCol { position:absolute; top:50%; right:calc(50% + 129px); transform:translateY(-50%);
    display:flex; flex-direction:column; align-items:center; gap:16px; }
  #menuShopWrap, #menuAchWrap, #menuSetWrap, #menuGuideWrap, #menuTreeWrap { display:flex; flex-direction:column; align-items:center; gap:7px; }
  #menuDiscWrap { display:flex; flex-direction:column; align-items:center; gap:7px; }
  /* 免责声明：全屏铺开（内容区吃掉全部剩余空间并独立滚动），返回放在顶部条 */
  #panelDisclaimer { padding:0; overflow:hidden; }
  /* overlay 用 ::before/::after 的 auto margin 做垂直居中，会优先吃掉剩余空间，
     这里必须清零，否则内容区的 flex-grow 一点都分不到（树形视图踩过同样的坑） */
  #panelDisclaimer::before, #panelDisclaimer::after { margin:0; height:0; display:none; }
  #discTop { flex:0 0 auto; align-self:stretch; display:flex; align-items:center;
    justify-content:space-between; gap:10px; padding:10px 14px;
    background:#0a1020; border-bottom:2px solid #223052; }
  #discTop h2 { margin:0; font-size:18px; white-space:nowrap; }
  #discTip { flex:0 0 auto; align-self:stretch; padding:8px 14px 6px; text-align:center; }
  #discBody { flex:1 1 auto; align-self:stretch; width:100%; max-width:none;
    border:0; background:transparent; padding:2px 16px 24px; text-align:left;
    overflow-y:auto; -webkit-overflow-scrolling:touch; }
  /* 正文字号：不跟随全局 .tip 在小屏上的压缩。
     小屏可见宽度窄、本来就更费眼，字反而不能更小，这里统一提到 14px 并加行高。 */
  #discBody .tip { font-size:14px; line-height:1.85; margin:3px 0 !important;
    color:#a8bcd8; text-align:left; }
  #discBody .setTitle { font-size:15px; }
  /* 目录：浮在内容区上方，不挤压正文空间；默认收起 */
  #discToc, #discDocs { position:absolute; z-index:70; left:12px; right:12px;
    max-height:58%; overflow-y:auto; -webkit-overflow-scrolling:touch;
    background:#0d1730; border:2px solid #2b3f6b; border-radius:12px;
    padding:8px; box-shadow:0 10px 28px rgba(0,0,0,.6);
    display:grid; grid-template-columns:repeat(auto-fill,minmax(150px,1fr)); gap:6px; }
  #discToc.hidden, #discDocs.hidden { display:none; }
  /* 文件切换：单列，条目带性质说明；当前文件高亮 */
  #discDocs { max-height:46%; display:grid; grid-template-columns:1fr; gap:6px; }
  #discDocs .docItem { text-align:left; padding:8px 10px; background:#16223c;
    border:1px solid #2b3f6b; border-radius:8px; color:#a8bcd8; cursor:pointer; line-height:1.45; }
  #discDocs .docItem:active { background:#22315a; color:#e6f0ff; }
  #discDocs .docItem.on { border-color:#ffd24a; color:#ffe08a; background:#1d2c50; }
  #discDocs .docItem .docName { font-size:13.5px; font-weight:600; display:block; }
  #discDocs .docItem .docSub { font-size:11.5px; color:#5f6d8c; display:block; margin-top:2px; }
  #discDocs .docItem.on .docSub { color:#8fa2c4; }
  #discToc .tocItem { text-align:left; font-size:12.5px; padding:6px 9px;
    background:#16223c; border:1px solid #2b3f6b; border-radius:8px;
    color:#a8bcd8; cursor:pointer; line-height:1.4; }
  #discToc .tocItem:active { background:#22315a; color:#e6f0ff; }
  /* 跳转后短暂高亮，让人看清落点 */
  #discBody .setTitle.tocHit { color:#ffe08a; }
  @media (max-width: 359px) {
    #discToc { grid-template-columns:1fr; }
    #discDocs .docItem .docName { font-size:13px; }
    #discToc .tocItem { font-size:13px; padding:7px 10px; }
  }
  @media (max-height: 460px) {
    #discToc { max-height:64%; }
  }
  /* 字号三档：小屏可见宽度窄、更费眼，玩家可以自己调大。 */
  #panelDisclaimer.fsA #discBody .tip { font-size:12.5px; line-height:1.7; }
  #panelDisclaimer.fsA #discBody .setTitle { font-size:13.5px; }
  #panelDisclaimer.fsC #discBody .tip { font-size:16.5px; line-height:1.9; }
  #panelDisclaimer.fsC #discBody .setTitle { font-size:17px; }
  #discFontBar { display:flex; gap:4px; flex:0 0 auto; }
  #discFontBar .seg { padding:2px 7px; font-size:12px; min-width:0; }
  #discTop h2 { flex:0 1 auto; overflow:hidden; text-overflow:ellipsis; }
  #discTip { font-size:12.5px !important; }
  @media (max-width: 359px) {
    #discBody .tip { font-size:13.5px; line-height:1.8; }
    #discBody .setTitle { font-size:14px; }
  }
  @media (max-height: 460px) {
    #discBody .tip { font-size:13px; line-height:1.7; }
    #discBody .setTitle { font-size:14px; }
    #discTip { font-size:11.5px !important; }
  }
  @media (max-height: 460px) {
    #discTop { padding:6px 12px; }
    #discTop h2 { font-size:16px; }
    #discTip { padding:4px 12px 3px; }
    #discBody { padding:2px 12px 16px; }
  }
  #menuDiscWrap > * { margin-bottom:7px; }
  #menuDiscWrap > *:last-child { margin-bottom:0; }
  /* 免责声明图标：与设置、图鉴同一套外壳（底色 + 2px 亮边 + 圆角） */
  #btnDiscIcon { width:42px; height:42px; padding:0; display:flex; align-items:center; justify-content:center;
    background:#1b2846; border:2px solid #40568a; border-radius:9px; cursor:pointer; }
  #btnDiscIcon:active { border-color:#7fe8ff; background:#24365e; }
  #btnDiscIcon svg { display:block; }
  #menuDiscState { font-size:11px; color:#8fa2c8; text-align:center; line-height:1.2; }
  /* 主菜单四个小图标：底色与描边整体提亮，避免和深色面板糊成一团 */
  #btnAchIcon { position:relative; width:42px; height:42px; padding:0; display:flex; align-items:center;
    justify-content:center; background:#1b2846; border:2px solid #40568a; border-radius:9px; cursor:pointer; }
  #btnAchIcon:active { border-color:#ffd24a; background:#24365e; }
  #btnAchIcon svg { display:block; }
  /* 成就小红点：有新解锁且未查看时亮起 */
  #achDot { position:absolute; top:-3px; right:-3px; width:10px; height:10px; border-radius:50%;
    background:#ff3b3b; border:2px solid #fff0f0; display:none; }
  #btnSetIcon { width:42px; height:42px; padding:0; display:flex; align-items:center; justify-content:center;
    background:#1b2846; border:2px solid #40568a; border-radius:9px; cursor:pointer; }
  #btnSetIcon:active { border-color:#7fe8ff; background:#24365e; }
  #btnSetIcon svg { display:block; }
  /* 天赋树：与其余图标同一套外壳（底色 + 2px 亮边 + 圆角） */
  #btnTreeIcon { position:relative; width:42px; height:42px; padding:0; display:flex; align-items:center; justify-content:center;
    background:#1b2846; border:2px solid #40568a; border-radius:9px; cursor:pointer; }
  #btnTreeIcon:active { border-color:#ffd24a; background:#24365e; }
  #btnTreeIcon svg { display:block; }
  #menuTreeWrap { display:flex; flex-direction:column; align-items:center; gap:7px; }
  #menuTreeState { font-size:10px; color:#5f6d8c; letter-spacing:1px; text-align:center; white-space:nowrap; }
  /* 天赋树小红点：有可用天赋点未花时亮起 */
  #treeDot { position:absolute; top:-3px; right:-3px; width:11px; height:11px; border-radius:50%;
    background:#ffd24a; border:2px solid #1b2846; opacity:0; }
  #treeDot.on { opacity:1; }
  /* 介绍：与其余图标同一套外壳（底色 + 2px 亮边 + 圆角）。
     此前只给了 svg、漏配外壳样式，于是这个按钮没有边框和底色，和旁边几个明显不一样。 */
  #btnGuideIcon { width:42px; height:42px; padding:0; display:flex; align-items:center; justify-content:center;
    background:#1b2846; border:2px solid #40568a; border-radius:9px; cursor:pointer; }
  #btnGuideIcon:active { border-color:#7fe8ff; background:#24365e; }
  #btnGuideIcon svg { display:block; }
  #menuGuideWrap { display:flex; flex-direction:column; align-items:center; gap:7px; }
  #menuGuideState { font-size:10px; color:#5f6d8c; letter-spacing:1px; text-align:center; white-space:nowrap; }
  /* 商店：与其余图标同一套画法（提亮底色 + 亮色符号），符号为购物车 */
  #btnShopIcon { width:42px; height:42px; padding:0; display:flex; align-items:center; justify-content:center;
    background:#1b2846; border:2px solid #40568a; border-radius:9px; cursor:pointer; }
  #btnShopIcon:active { border-color:#ffd24a; background:#24365e; }
  #btnShopIcon svg { display:block; }
  #menuShopState { font-size:10px; color:#5f6d8c; letter-spacing:1px; text-align:center; white-space:nowrap; }
  /* 状态文字：竖排在图标下方，两行，避免横向挤压按钮列 */
  #menuSetState { font-size:10px; color:#5f6d8c; letter-spacing:1px; text-align:center;
    line-height:1.6; white-space:nowrap; }
  #menuAchState { font-size:10px; color:#5f6d8c; letter-spacing:1px; text-align:center; white-space:nowrap; }
  /* 右侧栏：与左侧设置对称，绝对定位在按钮列右侧，不占布局流；图鉴在上、公告在下 */
  #menuNewsCol { position:absolute; top:50%; left:calc(50% + 129px); transform:translateY(-50%);
    display:flex; flex-direction:column; align-items:center; gap:16px; }
  #menuDexWrap, #menuNewsWrap { display:flex; flex-direction:column; align-items:center; gap:7px; }
  #btnDexIcon, #btnNewsIcon, #btnChalIcon { width:42px; height:42px; padding:0; display:flex; align-items:center; justify-content:center;
    background:#1b2846; border:2px solid #40568a; border-radius:9px; cursor:pointer; }
  #btnDexIcon:active { border-color:#7fe8ff; background:#24365e; }
  #btnNewsIcon:active { border-color:#ffd24a; background:#24365e; }
  #btnChalIcon:active { border-color:#ff6b6b; background:#24365e; }
  #btnDexIcon svg, #btnNewsIcon svg, #btnChalIcon svg { display:block; }
  #menuDexState, #menuNewsState, #menuChalState { font-size:10px; color:#5f6d8c; letter-spacing:1px; text-align:center; white-space:nowrap; }
  #menuChalWrap { display:flex; flex-direction:column; align-items:center; gap:7px; }
  #menuTuneWrap { display:flex; flex-direction:column; align-items:center; gap:7px; }
  /* 时装：与其它图标同一套外壳（底色 + 2px 亮边 + 圆角），不单独造样式 */
  #menuSkinWrap { display:flex; flex-direction:column; align-items:center; gap:7px; }
  #btnSkinIcon { width:42px; height:42px; padding:0; display:flex; align-items:center; justify-content:center;
    background:#1b2846; border:2px solid #40568a; border-radius:9px; cursor:pointer; }
  #btnSkinIcon:active { border-color:#ff9ad5; background:#24365e; }
  #btnSkinIcon svg { display:block; }
  #menuSkinState { font-size:10px; color:#5f6d8c; letter-spacing:1px; text-align:center; white-space:nowrap; }
  /* 时装面板 */
  #skinPreview { display:flex; align-items:center; justify-content:center; gap:14px;
    padding:10px; border:2px solid #223052; background:#0b1220; width:100%; max-width:460px;
    box-sizing:border-box; }
  #skinPreviewCv { width:76px; height:76px; flex:0 0 auto; border:2px solid #2b3550; border-radius:8px; background:#070a12; }
  #skinPreviewInfo { flex:1 1 auto; min-width:0; }
  #skinPreviewName { font-size:14px; font-weight:700; color:#cfe6ff; }
  #skinPreviewTip { font-size:11px; color:#8fa2c4; line-height:1.6; margin-top:3px; }
  #skinBody { width:100%; max-width:460px; max-height:52vh; overflow-y:auto;
    border:2px solid #223052; background:#0b1220; }
  .skinGrid { display:flex; flex-wrap:wrap; gap:8px; padding:9px 12px; }
  .skinCell { width:calc(33.333% - 6px); min-width:88px; box-sizing:border-box;
    border:2px solid #223052; background:#0e1526; border-radius:9px; padding:7px 6px;
    text-align:center; cursor:pointer; }
  .skinCell.sel { border-color:#ffd24a; box-shadow:0 0 12px rgba(255,210,74,.22); }
  .skinCell.lock { opacity:.62; }
  .skinSw { width:100%; height:26px; border-radius:6px; border:1px solid rgba(255,255,255,.18); }
  .skinNm { font-size:11px; color:#cfe6ff; font-weight:700; margin-top:5px; line-height:1.3; }
  .skinSt { font-size:10px; color:#8fa2c4; margin-top:2px; }
  .skinSt.own { color:#7fe8ff; }
  .skinSt.cost { color:#ffd24a; }
  .skinSt.no { color:#ff8f8f; }
  .no-gap .skinGrid > * { margin:0 8px 8px 0; }
  .no-gap .skinGrid > *:last-child { margin-right:0; }
  #btnTuneIcon { width:42px; height:42px; padding:0; display:flex; align-items:center; justify-content:center;
    background:#1b2846; border:2px solid #40568a; border-radius:9px; cursor:pointer; }
  #btnTuneIcon:active { border-color:#7fe8ff; background:#24365e; }
  #btnTuneIcon svg { display:block; }
  #menuTuneState { font-size:10px; color:#5f6d8c; letter-spacing:1px; text-align:center; white-space:nowrap; }
  /* 其他：九宫格图标，与其它图标同一套外壳（42px / 2px 亮边 / 圆角 9px） */
  #menuOthersWrap { display:flex; flex-direction:column; align-items:center; gap:7px; }
  #btnOthersIcon { position:relative; width:42px; height:42px; padding:0; display:flex; align-items:center; justify-content:center;
    background:#1b2846; border:2px solid #40568a; border-radius:9px; cursor:pointer; }
  #btnOthersIcon:active { border-color:#a8ffe8; background:#24365e; }
  #btnOthersIcon svg { display:block; }
  #menuOthersState { font-size:10px; color:#5f6d8c; letter-spacing:1px; text-align:center; white-space:nowrap; }
  /* 其他面板：一堆格子，点格子才进对应功能；空位只是占位，点了没反应 */
  #othersBody, #modesBody, #labBody { display:flex; flex-wrap:wrap; width:100%; max-width:520px; max-height:52vh; overflow-y:auto;
    border:2px solid #223052; background:#0b1220; padding:10px; box-sizing:border-box; }
  #othersBody > .oslot, #modesBody > .oslot, #labBody > .oslot { flex:1 1 calc(33.333% - 14px); min-width:104px; max-width:230px; margin:0 5px 10px;
    box-sizing:border-box; border:2px solid #223052; background:#0b1220; padding:10px; text-align:left; position:relative; }
  /* 每周挑战小红点：换了一周的新挑战、且还没点开看过时亮起。
     只有点进每周挑战面板才算「看过」，挂机多久都不会自己灭。 */
  #weekDot { position:absolute; top:-3px; right:-3px; width:11px; height:11px; border-radius:50%;
    background:#ff3b3b; border:2px solid #fff0f0; opacity:0; pointer-events:none; }
  #weekDot.on { opacity:1; }
  .wkdot { position:absolute; top:5px; right:5px; width:9px; height:9px; border-radius:50%;
    background:#ff3b3b; border:1.5px solid #fff0f0; pointer-events:none; }
  /* 公告小红点：原来太小太淡，玩家根本注意不到 —— 尤其小屏会隐藏「公告 N」文字，
     只剩这一个点，很多人因此完全不知道有更新。
     现在加大、改亮红、加脉冲缩放与外发光，让「有更新」一眼看得见。 */
  #newsDot { transform-box: fill-box; transform-origin: center; }
  #newsDot.on { animation: newsPulse 1.15s ease-in-out infinite;
    filter: drop-shadow(0 0 2.5px rgba(255,40,40,0.95)); }
  @keyframes newsPulse {
    0%, 100% { transform: scale(1);   opacity: 1; }
    50%      { transform: scale(1.5); opacity: .72; }
  }
  /* 章节按钮小红点：通关解锁了新章节、玩家还没点进章节面板看过时亮起。
     新玩家最容易卡在这里 —— 通关第一章后根本不知道还能换章节，
     于是永远停在第一章，后面五章等于白做。
     红点做得和公告红点一样醒目（亮红 + 白边 + 脉冲 + 发光）。 */
  #btnChap { position:relative; }
  #chapDot { position:absolute; top:-5px; right:-5px; width:12px; height:12px; border-radius:50%;
    background:#ff2020; border:2px solid #ffffff; opacity:0; pointer-events:none;
    box-sizing:border-box; }
  #chapDot.on { opacity:1; animation: chapPulse 1.15s ease-in-out infinite;
    box-shadow:0 0 6px 2px rgba(255,40,40,.9); }
  @keyframes chapPulse {
    0%, 100% { transform: scale(1);   opacity: 1; }
    50%      { transform: scale(1.5); opacity: .72; }
  }
  #othersBody > .oslot.has, #modesBody > .oslot.has, #labBody > .oslot.has { cursor:pointer; }
  #othersBody > .oslot.has:active, #modesBody > .oslot.has:active, #labBody > .oslot.has:active { border-color:#ffd24a; background:#1a1608; }
  #othersBody > .oslot.empty, #modesBody > .oslot.empty, #labBody > .oslot.empty { border-style:dashed; border-color:#1c2740; background:#080d18;
    opacity:.5; cursor:default; }
  /* 测试面板：已开启的实验项整格亮起，一眼看出哪几个是开着的 */
  #labBody > .oslot.on { border-color:#6b5518; background:#161206; }
  #labBody > .oslot.on .ot { color:#ffe08f; }
  .oslot .ot { font-size:14px; font-weight:700; margin-bottom:4px; color:#cfe6ff; }
  .oslot.empty .ot { color:#3d4a66; }
  .oslot .od { font-size:11px; color:#8fa2c4; line-height:1.6; }
  .oslot.empty .od { color:#33405c; }
  /* 格子里的角标（Beta 等）。
     注意：.tag 的样式原本只写在 .nw（公告）作用域下，玩法面板里套用 .tag 时
     拿不到任何样式，会渲染成一行光秃秃的纯文本 —— 这就是「空位/角标很难看」的根因。
     这里补一条 .oslot 作用域下的样式，和公告角标保持一致，且角标与标题同一行。 */
  .oslot .oth { display:flex; align-items:center; gap:6px; flex-wrap:wrap; margin-bottom:4px; }
  .oslot .ot { margin-bottom:0; }
  .oslot .tag { font-size:10px; padding:1px 6px; border:1px solid #ffd24a; color:#ffe08f;
    letter-spacing:1px; border-radius:3px; white-space:nowrap; flex:none; }
  .oslot .tag.hot { border-color:#ff6b6b; color:#ff9b9b; }
  .oslot .tag.off { border-color:#33405c; color:#5f6d8c; }
  @media (max-width: 520px) {
    #othersBody > .oslot, #modesBody > .oslot, #labBody > .oslot { flex:1 1 calc(50% - 14px); }
  }
  @media (max-width: 340px) {
    #othersBody > .oslot, #modesBody > .oslot, #labBody > .oslot { flex:1 1 100%; margin:0 0 10px; }
  }
  /* 原创小说：目录列表 + 阅读区。
     目录用一列一章的列表（不是九宫格）：章节有先后顺序，格子会看不出顺序。
     阅读区的正文必须能滚 —— 一章十几段，不滚的话矮屏（横条屏）会直接顶出屏幕。 */
  #novelBody { display:flex; flex-direction:column; width:100%; max-width:520px; max-height:52vh; overflow-y:auto;
    border:2px solid #223052; background:#0b1220; padding:10px; box-sizing:border-box; }
  #novelBody > .nrow { display:flex; align-items:baseline; gap:8px; box-sizing:border-box; width:100%;
    border:2px solid #223052; background:#0b1220; padding:9px 10px; margin:0 0 8px; text-align:left; cursor:pointer;
    flex-wrap:wrap; }
  #novelBody > .nrow:last-child { margin-bottom:0; }
  #novelBody > .nrow:active { border-color:#ffd24a; background:#1a1608; }
  #novelBody > .nrow.read { border-color:#1c2c4a; background:#080d18; }
  #novelBody .nn { font-size:14px; font-weight:700; color:#cfe6ff; flex:none; }
  #novelBody > .nrow.read .nn { color:#7e8fae; }
  #novelBody .nsub { font-size:11px; color:#8fa2c4; line-height:1.5; flex:1 1 auto; min-width:0; }
  #novelBody > .nrow.read .nsub { color:#5f6d8c; }
  #novelBody .nmark { font-size:10px; color:#5f6d8c; flex:none; letter-spacing:1px; }
  #novelBody > .nrow.read .nmark { color:#3d4a66; }
  /* 阅读区 */
  #novelText { width:100%; max-width:560px; max-height:54vh; overflow-y:auto; text-align:left;
    border:2px solid #223052; background:#0b1220; padding:14px; box-sizing:border-box; }
  #novelText p { margin:0 0 11px; font-size:13px; line-height:2; color:#dbe6f7; }
  #novelText p:last-child { margin-bottom:0; }
  #novelText p.q { color:#cfe6ff; font-weight:700; }
  #novelText .nend { margin-top:16px; text-align:center; font-size:16px; letter-spacing:8px;
    color:#ffd24a; font-weight:700; }
  #novelText .nnote { margin-top:10px; text-align:center; font-size:11px; color:#8fa2c4; line-height:1.8; }
  /* 作者水印段落（正文里以 % 开头的段落）：比正文暗一档，看得出是水印又不抢戏。 */
  #novelText p.wm { color:#6f7f9e; font-size:11px; line-height:1.7; text-align:center;
    margin:14px 0; padding:6px 0; border-top:1px dashed #223052; border-bottom:1px dashed #223052; }
  /* 版权保护：小说区禁止选中 / 长按弹出菜单 / 拖拽。
     注意只作用于小说两个容器，别误伤其它面板（那会让人没法复制存档码）。 */
  #novelBody, #novelText { -webkit-user-select:none; -moz-user-select:none; -ms-user-select:none;
    user-select:none; -webkit-touch-callout:none; }
  #novelReadWrap { position:relative; width:100%; max-width:560px; flex:none; }
  /* 浮层水印：铺在阅读区上方，指针穿透（不影响滚动与点按）。
     系统级截屏拦不住，但截出去的图一定带着作者署名，盗用可被追溯。 */
  #novelWatermark { position:absolute; left:0; top:0; right:0; bottom:0; overflow:hidden;
    pointer-events:none; z-index:5; display:none; }
  #novelWatermark > span { position:absolute; font-size:12px; color:#ffffff; opacity:0.07;
    font-weight:700; white-space:nowrap; transform:rotate(-24deg); }
  /* 打印 / 另存为 PDF 时不输出正文，避免整篇被一键导出。 */
  @media print {
    #novelText, #novelWatermark { display:none !important; }
  }
  /* 保卫城堡 · 难度选择：与「其他 / 玩法」共用同一套格子版面。
     注意：这个容器的 id 是 cdiffBody，以前没写进上面的选择器列表，
     四张难度卡因此是没有任何样式的裸 div（无边框、无底色、无间距），挤成一团。
     难度只有四项，这里用两列而不是三列，看起来更稳。 */
  #cdiffBody { display:flex; flex-wrap:wrap; width:100%; max-width:520px; max-height:52vh; overflow-y:auto;
    border:2px solid #223052; background:#0b1220; padding:10px; box-sizing:border-box; }
  #cdiffBody > .oslot { flex:1 1 calc(50% - 14px); min-width:150px; max-width:230px; margin:0 5px 10px;
    box-sizing:border-box; border:2px solid #223052; background:#0b1220; padding:10px; text-align:left; }
  #cdiffBody > .oslot.has { cursor:pointer; }
  #cdiffBody > .oslot.has:hover { border-color:#40568a; background:#101a30; }
  #cdiffBody > .oslot.has:active { border-color:#ffd24a; background:#1a1608; }
  @media (max-width: 340px) {
    #cdiffBody > .oslot { flex:1 1 100%; margin:0 0 10px; }
  }
  /* 图鉴 */
  #dexTabs { gap:6px; margin:2px 0; }
  #dexTabs .btn.small.on { border-color:#ffd24a; color:#ffe08f; background:#1a1608; }
  #dexBody { width:100%; max-width:460px; max-height:48vh; overflow-y:auto; border:2px solid #223052;
    background:#0b1220; }
  .dx { padding:9px 12px; border-bottom:1px solid #17203a; }
  .dx:last-child { border-bottom:none; }
  .dx .dh { display:flex; align-items:center; gap:8px; }
  .dx .sw { width:12px; height:12px; border:1px solid rgba(255,255,255,.35); flex:0 0 auto; }
  .dx .dn { font-size:13px; font-weight:700; color:#cfe6ff; }
  .dx .dl { font-size:10px; color:#5f6d8c; border:1px solid #2b3550; padding:0 5px; flex:0 0 auto; }
  .dx .dd { font-size:11px; color:#8fa2c4; line-height:1.75; margin-top:4px; }
  .dx .dv { font-size:11px; color:#ffd24a; margin-top:3px; }
  .dx .de { font-size:11px; color:#7fffd4; margin-top:3px; }
  /* 商店列表 */
  #shopBody { width:100%; max-width:460px; max-height:52vh; overflow-y:auto; border:2px solid #223052;
    background:#0b1220; }
  .shSec { font-size:12px; font-weight:700; color:#ffd24a; letter-spacing:2px;
    padding:9px 12px 4px; border-bottom:1px solid #17203a; }
  .shTip2 { font-size:10px; color:#5f6d8c; padding:5px 12px 7px; border-bottom:1px solid #17203a; }
  .shItem { padding:9px 12px; border-bottom:1px solid #17203a; }
  .shItem:last-child { border-bottom:none; }
  .shItem.maxed .shName { color:#7fffd4; }
  .shRow { display:flex; align-items:center; justify-content:space-between; gap:8px; }
  .shName { font-size:13px; font-weight:700; color:#cfe6ff; }
  .shLv { font-size:11px; color:#8fa2c4; flex:0 0 auto; }
  .shDots { display:flex; gap:4px; margin-top:5px; }
  .shDot { width:14px; height:5px; border:1px solid #2b3550; background:#0e1628; }
  .shDot.on { background:#ffd24a; border-color:#ffd24a; }
  .shDesc { font-size:11px; color:#8fa2c4; line-height:1.7; margin-top:4px; }
  .shBuy { margin-top:6px; }
  .shBuy .btn.small { padding:6px 10px; font-size:12px; }
  .shBuy .btn.small.disabled { opacity:.42; }
  .shDone { font-size:12px; color:#7fffd4; letter-spacing:1px; }
  /* 公告列表 */
  #newsTabs { display:flex; gap:8px; }
  #newsBody { width:100%; max-width:440px; max-height:46vh; overflow-y:auto; border:2px solid #223052;
    background:#0b1220; }
  .nw { padding:9px 12px; border-bottom:1px solid #17203a; cursor:pointer; }
  .nw:last-child { border-bottom:none; }
  .nw:active { background:#111c33; }
  .nw .nh { display:flex; align-items:center; gap:7px; }
  .nw .tag { font-size:10px; padding:1px 6px; border:1px solid #7fe8ff; color:#7fe8ff; letter-spacing:1px; }
  .nw .tag.hot { border-color:#ff6b6b; color:#ff9b9b; }
  .nw .tag.new { border-color:#ffd24a; color:#ffe08f; }
  .nw .nt { flex:1; min-width:0; font-size:13px; color:#cfe6ff; font-weight:700;
    overflow:hidden; white-space:nowrap; text-overflow:ellipsis; }
  .nw .nd { font-size:10px; color:#5f6d8c; }
  .nw .nb { font-size:12px; color:#8fa2c4; line-height:1.8; margin-top:5px; white-space:pre-wrap; }
  .nw .nwgift { margin-top:8px; display:block; }
  .nw .nwgift .btn.small { font-size:12px; padding:6px 12px; }
  .nw .nwginfo { font-size:11px; color:#7f8db0; margin-top:5px; line-height:1.6; }
  .nwEmpty { padding:26px 12px; text-align:center; font-size:12px; color:#5f6d8c; line-height:2; }
  /* 窄屏：缩小按钮列与图标，保证设置图标不会顶出屏幕左边 */
  @media (max-width: 400px) {
    #menuBtns { width:200px; }
    #menuSetCol { right:calc(50% + 114px); }
    #menuNewsCol { left:calc(50% + 114px); }
    #btnAchIcon { width:38px; height:38px; }
    #btnSetIcon { width:38px; height:38px; }
    #btnShopIcon { width:38px; height:38px; }
    #btnDexIcon { width:38px; height:38px; }
    #btnNewsIcon { width:38px; height:38px; }
    #btnChalIcon { width:38px; height:38px; }
    #btnGuideIcon { width:38px; height:38px; }
    #btnTreeIcon { width:38px; height:38px; }
    #btnDiscIcon { width:38px; height:38px; }
    #btnOthersIcon { width:38px; height:38px; }
    /* 时装 / 调节原先漏了这条窄屏规则，一直比旁边一整圈大（42 vs 38）。
       右侧栏加了第 6 个「其他」图标后列更长，这里统一到 38，避免出现参差与溢出。 */
    #btnSkinIcon, #btnTuneIcon { width:38px; height:38px; }
    #menuSetCol, #menuNewsCol { gap:12px; }
  }
  /* 极矮屏（如横屏 640×300）：四个小图标竖排会超出屏幕上下边界，
     这里整体缩小图标并收紧间距，文字标签藏掉，保证按钮列仍在屏内。 */
  @media (max-height: 460px) {
    /* 矮屏（如横屏 640×300）下主菜单面板内容比视口还高，两列图标用 top:50% 是
       相对【面板】居中，结果整列被推到屏幕下方看不见（实测 top 到 286 / 视口 300）。
       这里改成 fixed 相对视口居中，图标始终落在屏幕里；面板滚动时图标也不跟着跑。 */
    #menuSetCol, #menuNewsCol { position:fixed; top:50%; transform:translateY(-50%); gap:7px; }
    #btnShopIcon, #btnAchIcon, #btnSetIcon, #btnGuideIcon, #btnTreeIcon { width:34px; height:34px; }
    #btnDiscIcon { width:34px; height:34px; }
    #btnGuideIcon, #btnDexIcon, #btnNewsIcon, #btnChalIcon, #btnTuneIcon, #btnSkinIcon { width:34px; height:34px; }
    #btnShopIcon svg, #btnAchIcon svg, #btnSetIcon svg, #btnGuideIcon svg, #btnTreeIcon svg { width:19px; height:19px; }
    #btnDiscIcon svg { width:19px; height:19px; }
    #btnDexIcon svg, #btnNewsIcon svg, #btnChalIcon svg, #btnTuneIcon svg, #btnSkinIcon svg { width:19px; height:19px; }
    #btnOthersIcon { width:34px; height:34px; }
    #btnOthersIcon svg { width:19px; height:19px; }
    #menuGuideState, #menuShopState, #menuAchState, #menuSetState, #menuTreeState, #menuDiscState { display:none; }
    #menuDexState, #menuNewsState, #menuChalState, #menuTuneState, #menuSkinState { display:none; }
    #menuOthersState { display:none; }
  }
  @media (max-width: 340px) {
    #menuDiscState { display:none; }
    #menuSkinState { display:none; }
    #menuTuneState { display:none; }
    #menuTreeState { display:none; }
    #menuGuideState { display:none; }
    #menuAchState { display:none; }
    #menuSetState { display:none; }
    #menuShopState { display:none; }
    #menuDexState { display:none; }
    #menuNewsState { display:none; }
    #menuOthersState { display:none; }
  }
  #userBar { display:flex; align-items:center; gap:9px; border:2px solid #223052; background:#0b1220;
    padding:6px 12px 6px 6px; cursor:pointer; }
  #userBar:active { border-color:#7fe8ff; }
  #userBar img { width:34px; height:34px; border:2px solid #7fe8ff; display:block; object-fit:cover; }
  #userBar .un { font-size:13px; color:#cfe6ff; font-weight:700; }
  #userBar .ut { font-size:10px; color:#5f6d8c; }
  /* 排行榜 */
  #rankTabs { display:flex; gap:8px; }
  /* 设置面板：板块切换条（与排行榜 / 公告同一套分栏样式） */
  #setTabs { display:flex; gap:8px; flex-wrap:wrap; justify-content:center; }
  #setBody { width:100%; max-width:460px; }
  #rankBody { width:100%; max-width:420px; max-height:46vh; overflow-y:auto; border:2px solid #223052;
    background:#0b1220; }
  .rk { display:flex; align-items:center; gap:9px; padding:6px 10px; border-bottom:1px solid #17203a; }
  .rk:last-child { border-bottom:none; }
  .rk .no { width:28px; font-size:12px; color:#8fa2c4; text-align:right; }
  .rk .no.top { color:#ffd24a; font-weight:700; }
  .rk img { width:26px; height:26px; border:1px solid #2b3550; display:block; object-fit:cover; }
  .rk .nm { flex:1; min-width:0; font-size:12px; color:#cfe6ff; overflow:hidden; white-space:nowrap; text-overflow:ellipsis; }
  .rk .sc { font-size:13px; color:#ffd24a; font-weight:700; }
  .rk.me { background:rgba(127,232,255,.10); }
  .rkEmpty { padding:20px; text-align:center; font-size:12px; color:#5f6d8c; }
  /* 互动解锁列表 */
  #interactList { width:100%; max-width:430px; max-height:48vh; overflow-y:auto; border:2px solid #223052;
    background:#0b1220; }
  .ia { display:flex; align-items:center; gap:10px; padding:9px 12px; border-bottom:1px solid #17203a; }
  .ia:last-child { border-bottom:none; }
  .ia .ic { width:26px; font-size:15px; text-align:center; }
  .ia .bd { flex:1; min-width:0; }
  .ia .nm { font-size:12px; color:#cfe6ff; font-weight:700; }
  .ia .rw { font-size:11px; color:#8fa2c4; line-height:1.5; }
  .ia .st { font-size:11px; padding:3px 8px; border:2px solid #2b3550; color:#8fa2c4; white-space:nowrap; }
  .ia .st.done { border-color:#8fff9f; color:#8fff9f; }
  .ia .st.no { border-color:#ffd24a; color:#ffd24a; }   /* 纯状态展示，不可点，故不给手型光标 */
  .ia.done { background:rgba(143,255,159,.06); }
  /* 升级面板刷新按钮 */
  #btnReroll { min-width:170px; }
  #btnReroll:disabled { opacity:.45; cursor:default; }
  /* 署名 */
  /* 局内暂停按钮：右上角，避开手机左半屏摇杆区域 */
  /* 局内暂停按钮：默认半透明，避免压住画面（玩家反馈遮挡视野）。
     可长按拖动到任意位置，位置记进存档；拖过之后就不再遮挡原来那块区域。 */
  #btnPause { position:absolute; z-index:11; width:46px; height:46px; padding:0;
    display:none; align-items:center; justify-content:center; border:2px solid #7fe8ff;
    background:rgba(13,21,38,.88); border-radius:10px; cursor:pointer;
    box-shadow:0 0 12px rgba(127,232,255,.25) inset;
    opacity:.46; transition:opacity .18s ease, transform .12s ease;
    touch-action:none; -webkit-user-select:none; user-select:none; }
  #btnPause.show { display:flex; }
  #btnPause:hover, #btnPause:active, #btnPause.dragging { opacity:1; }
  #btnPause:active { background:#16273f; border-color:#ffe08f; }
  #btnPause.dragging { transform:scale(1.08); border-color:#ffe08f; }
  #btnPause svg { display:block; pointer-events:none; }
  /* 局内「解封技能」按钮：与暂停键同一套外壳，绿色区分。
     默认排在暂停键正下方，只有「反客为主」挑战里才显示。 */
  #btnSeal { position:absolute; z-index:11; width:46px; height:46px; padding:0;
    display:none; align-items:center; justify-content:center; border:2px solid #7dffb0;
    background:rgba(13,21,38,.88); border-radius:10px; cursor:pointer;
    box-shadow:0 0 12px rgba(125,255,176,.25) inset;
    opacity:.72; transition:opacity .18s ease, transform .12s ease;
    touch-action:none; -webkit-user-select:none; user-select:none; }
  #btnSeal.show { display:flex; }
  #btnSeal:hover, #btnSeal:active { opacity:1; }
  #btnSeal:active { background:#16273f; border-color:#ffe08f; }
  #btnSeal svg { display:block; pointer-events:none; }
  /* 右上角未解封数量角标 */
  #sealBadge { position:absolute; top:-7px; right:-7px; min-width:18px; height:18px;
    padding:0 4px; border-radius:9px; background:#ffd24a; color:#241a00;
    font-size:11px; font-weight:700; line-height:18px; text-align:center;
    border:1px solid #0b0d14; pointer-events:none; }
  #sealBadge.zero { display:none; }
  /* 局内「炮台强化」按钮：保卫城堡专属，配色用炮台的金色。
     与解封键同一套外壳，排在暂停键正下方 —— 城堡和解封不会同时出现，位置不打架。 */
  #btnCastleTurret { position:absolute; z-index:11; width:46px; height:46px; padding:0;
    display:none; align-items:center; justify-content:center; border:2px solid #ffd76b;
    background:rgba(13,21,38,.88); border-radius:10px; cursor:pointer;
    box-shadow:0 0 12px rgba(255,215,107,.25) inset;
    opacity:.82; transition:opacity .18s ease, transform .12s ease;
    touch-action:none; -webkit-user-select:none; user-select:none; }
  #btnCastleTurret.show { display:flex; }
  #btnCastleTurret:hover, #btnCastleTurret:active { opacity:1; }
  #btnCastleTurret:active { background:#2a2415; border-color:#fff0b8; }
  #btnCastleTurret svg { display:block; pointer-events:none; }
  /* 局内「射门」按钮：踢足球玩法专属，固定右下角。
     城门按钮在左下角、解封按钮在右上角，三个互不打架，所以这里不必跟着暂停键拖动。 */
  #btnFootKick { position:fixed; right:8px; bottom:8px; z-index:70; display:none;
    align-items:center; justify-content:center; gap:6px; width:auto; min-width:88px; height:52px;
    padding:0 14px; border:2px solid #7dffb0; background:rgba(11,32,22,.92); color:#d8ffe6;
    font-size:15px; font-weight:700; border-radius:14px; cursor:pointer;
    box-shadow:0 0 12px rgba(125,255,176,.22) inset; opacity:.9;
    touch-action:none; -webkit-user-select:none; user-select:none; }
  #btnFootKick.show { display:flex; }
  #btnFootKick:hover, #btnFootKick:active { opacity:1; }
  #btnFootKick:active { background:#16301f; border-color:#ffffff; }
  #btnFootKick svg { display:block; pointer-events:none; }
  #btnFootKick span { pointer-events:none; }
  /* 局内「冲刺」按钮：踢足球专属，排在射门键左边。
     冷却中压暗并直接显示剩余秒数，玩家一眼知道什么时候能用。 */
  #btnFootDash { position:fixed; right:104px; bottom:8px; z-index:70; display:none;
    align-items:center; justify-content:center; gap:6px; width:auto; min-width:78px; height:52px;
    padding:0 12px; border:2px solid #7fd8ff; background:rgba(10,26,40,.92); color:#d8f2ff;
    font-size:15px; font-weight:700; border-radius:14px; cursor:pointer;
    box-shadow:0 0 12px rgba(127,216,255,.20) inset; opacity:.9;
    transition:opacity .18s ease; touch-action:none;
    -webkit-user-select:none; user-select:none; }
  #btnFootDash.show { display:flex; }
  #btnFootDash:hover, #btnFootDash:active { opacity:1; }
  #btnFootDash:active { background:#132f45; border-color:#ffffff; }
  #btnFootDash.cool { border-color:#2b4258; color:#7d93ab; box-shadow:none; opacity:.62; }
  #btnFootDash svg { display:block; pointer-events:none; }
  #btnFootDash span { pointer-events:none; }
  /* 局内推币子按钮：投币 + 汉堡菜单，竖排在右下角偏上，
     刻意避开右下角的暂停键（暂停键可拖动，默认就在那一带），
     也避开左下角的虚拟摇杆 —— 竖排只占一条窄边，320 窄屏也放得下。
     原来「敌人」「技能」是两个独立按钮，现在一并收进汉堡菜单，
     以后再加调试开关也往里放，不再把右下角越堆越高。 */
  #btnCoinInsert, #btnCoinMenu { position:fixed; right:8px; z-index:70;
    display:none; align-items:center; justify-content:center; gap:5px; width:auto;
    min-width:74px; max-width:120px; height:48px; padding:0 10px; border:2px solid #ffd24a;
    background:rgba(38,30,10,.92); color:#fff3cd; font-size:14px; font-weight:700;
    border-radius:13px; cursor:pointer; box-shadow:0 0 12px rgba(255,210,74,.20) inset;
    opacity:.9; touch-action:none; -webkit-user-select:none; user-select:none; }
  /* 默认位置整体下移：原来在 bottom:70 / 124，正好压在画面中下部，
     挡金币也挡敌人。现在贴着右下角（8 / 62），占的地方最小；
     而且两个键都可以拖动，挡到哪儿就自己挪开，位置会记住。 */
  #btnCoinInsert { bottom:8px; }
  #btnCoinMenu { bottom:62px; }
  #btnCoinInsert.show, #btnCoinMenu.show { display:flex; }
  #btnCoinInsert:hover, #btnCoinInsert:active,
  #btnCoinMenu:hover, #btnCoinMenu:active { opacity:1; }
  #btnCoinInsert:active, #btnCoinMenu:active { background:#4a3a12; border-color:#fff; }
  /* 开关处于「关」的状态：压暗 + 灰边，一眼看出是关着的 */
  #btnCoinInsert.off, #btnCoinMenu.off { border-color:#3a4a63; color:#8fa3bd;
    background:rgba(14,20,32,.9); box-shadow:none; opacity:.72; }
  #btnCoinInsert svg, #btnCoinMenu svg { display:block; pointer-events:none; }
  #btnCoinInsert span, #btnCoinMenu span { pointer-events:none; }
  /* 推币子调试菜单（点汉堡展开）：竖排在按钮上方，窄屏用 min() 限宽不出界 */
  /* 躲猫猫：右下角唯一的动作键 —— 躲的人显示「屏息」，鬼显示「扑抓」。
     和射门键同位（bottom:8px），暂停键默认在右上角，不冲突。 */
  #btnHideAct { position:fixed; right:8px; bottom:8px; z-index:70; display:none;
    align-items:center; justify-content:center; gap:6px; width:auto; min-width:88px; height:52px;
    padding:0 14px; border:2px solid #7dffb0; background:rgba(11,32,22,.92); color:#d8ffe6;
    font-size:15px; font-weight:700; border-radius:14px; cursor:pointer;
    box-shadow:0 0 12px rgba(125,255,176,.22) inset; opacity:.9;
    touch-action:none; -webkit-user-select:none; user-select:none; }
  #btnHideAct.show { display:flex; }
  #btnHideAct:hover, #btnHideAct:active { opacity:1; }
  #btnHideAct:active { background:#16301f; border-color:#ffffff; }
  #btnHideAct.cool { border-color:#2b4258; color:#7d93ab; box-shadow:none; opacity:.62; }
  #btnHideAct svg { display:block; pointer-events:none; }
  #btnHideAct span { pointer-events:none; }
  #btnFarmAct, #btnFarmWater, #btnFarmShop { position:fixed; right:8px; z-index:70;
    display:none; align-items:center; gap:6px; padding:9px 12px; min-height:44px;
    border-radius:12px; border:2px solid #7dffb0; background:#12281c; color:#7dffb0;
    font-size:13px; font-weight:700; cursor:pointer; opacity:.92; touch-action:none;
    left:auto; top:auto; }
  /* 播种/收获必须给 bottom：三个键里只有它有 left/top:auto，
     少了这一行它就按文档流停在画布下方，1280x800 下 y=800 —— 整颗按钮在屏幕外，
     手机上等于「种地压根没法下种」。 */
  #btnFarmAct { bottom:8px; }
  #btnFarmWater { bottom:62px; }
  #btnFarmShop { bottom:116px; }
  #btnFarmAct.show, #btnFarmWater.show, #btnFarmShop.show { display:flex; }
  #btnFarmAct:hover, #btnFarmWater:hover, #btnFarmShop:hover { opacity:1; }
  #btnFarmAct:active, #btnFarmWater:active, #btnFarmShop:active { background:#1d3a28; border-color:#fff; }
  #btnFarmAct.off, #btnFarmWater.off, #btnFarmShop.off { border-color:#3a4a63; color:#8fa3bd; background:#0e1522; }
  #btnFarmAct svg, #btnFarmWater svg, #btnFarmShop svg { display:block; pointer-events:none; }
  #btnFarmAct span, #btnFarmWater span, #btnFarmShop span { pointer-events:none; }
  #coinDebugMenu { position:fixed; right:8px; bottom:118px; z-index:71; display:none;
    flex-direction:column; gap:6px; width:min(216px, calc(100vw - 24px)); padding:10px;
    border:2px solid #2b4472; border-radius:12px; background:rgba(10,16,30,.97);
    box-shadow:0 8px 24px rgba(0,0,0,.5); box-sizing:border-box;
    /* 矮屏（如 640×300 的横条）下菜单会顶出屏幕上方，标题和第一行直接看不见。
       这里限高并允许内部滚动，保证整块始终落在可视区域内。 */
    max-height:calc(100vh - 190px); overflow-y:auto; -webkit-overflow-scrolling:touch;
    -webkit-user-select:none; user-select:none; }
  #coinDebugMenu.show { display:flex; }
  #coinDebugMenu .cdmTitle { font-size:12px; font-weight:700; color:#8fa0c4;
    text-align:left; padding:0 2px 6px; border-bottom:1px solid #22304f; }
  #coinDebugMenu .cdmRow { display:flex; align-items:center; gap:8px; width:100%;
    padding:9px 8px; border:1px solid #2b3a5c; border-radius:9px; background:rgba(20,30,52,.7);
    color:#dce8ff; font-size:13px; cursor:pointer; text-align:left; box-sizing:border-box; }
  #coinDebugMenu .cdmRow:active { background:#1b2942; }
  #coinDebugMenu .cdmRow .cdmName { flex:1; min-width:0; font-weight:700; }
  #coinDebugMenu .cdmRow .cdmDesc { display:block; font-size:11px; font-weight:400;
    color:#7f90b4; line-height:1.45; margin-top:2px; }
  #coinDebugMenu .cdmRow .cdmState { flex:none; font-size:12px; font-weight:700;
    padding:3px 9px; border-radius:999px; border:1px solid #2b4472; color:#9aa6c0; }
  #coinDebugMenu .cdmRow.on .cdmState { color:#08121f; background:#7dffb0; border-color:#7dffb0; }
  #coinDebugMenu .cdmTip { font-size:11px; color:#6b7c9c; line-height:1.5; padding:2px; }
  /* 金币上限调节块：滑块 + 快捷档位 */
  #coinDebugMenu .cdmCap { display:flex; flex-direction:column; gap:7px; width:100%;
    padding:8px; border:1px solid #2b3a5c; border-radius:9px; background:rgba(20,30,52,.7);
    box-sizing:border-box; }
  #coinDebugMenu .cdmCapHead { display:flex; align-items:center; justify-content:space-between;
    font-size:13px; font-weight:700; color:#dce8ff; }
  #coinDebugMenu .cdmCapHead b { color:#ffd24a; font-size:15px; }
  #coinDebugMenu .cdmCap input[type="range"] { width:100%; height:26px; margin:0;
    accent-color:#ffd24a; touch-action:none; }
  #coinDebugMenu .cdmRow.cap { justify-content:center; font-size:12px; color:#9aa6c0; }
  #turretList { display:flex; flex-direction:column; gap:10px; width:100%; }
  #sealList { display:flex; flex-direction:column; gap:10px; width:100%; }
  .sealItem { display:flex; align-items:center; gap:10px; padding:10px 12px;
    border:1px solid #2b3a5c; border-radius:10px; background:rgba(20,30,52,.6); }
  .sealItem.can { border-color:#7dffb0; }
  .sealItem .siMain { flex:1; min-width:0; text-align:left; }
  .sealItem .siName { font-size:14px; font-weight:700; }
  .sealItem .siDesc { font-size:11px; color:#8fa0c4; line-height:1.5; margin-top:3px; }
  .sealItem .siBuy { flex:none; padding:8px 12px; border-radius:8px; font-size:13px;
    border:1px solid #40568a; background:#1b2846; color:#c9d6ee; cursor:pointer; }
  .sealItem.can .siBuy { border-color:#7dffb0; background:#16382a; color:#7dffb0; }
  .sealItem .siBuy:disabled { opacity:.45; cursor:not-allowed; }
  #sealEmpty { font-size:12px; color:#8fa0c4; text-align:center; padding:18px 0; }
  #pauseStats { display:flex; gap:18px; flex-wrap:wrap; justify-content:center; }
  #footer { position:absolute; left:0; right:0; bottom:8px; text-align:center; z-index:5;
    font-size:11px; color:#4d5a78; letter-spacing:1px; pointer-events:none; }
  /* 启动遮罩：主脚本跑起来前先占位，避免白屏；出错时变成提示页 */
  /* 与 .overlay 同样的问题：错误文案很长时（bootD 会塞完整报错），
     justify-content:center 会把顶部标题推出可视区且滚不到。这里用同一套伪元素方案。 */
  #boot { position:fixed; top:0; left:0; right:0; bottom:0; width:100%; height:100%; z-index:999; display:flex; flex-direction:column;
    align-items:center; justify-content:flex-start; gap:14px; background:#05070d;
    padding:24px; text-align:center; overflow-y:auto; }
  #boot::before { content:''; display:block; height:0; margin-top:auto; }
  #boot::after { content:''; display:block; height:0; margin-bottom:auto; }
  #boot .bootT { font-size:22px; letter-spacing:3px; color:#7fe8ff; }
  #boot .bootD { font-size:13px; color:#8fa2c4; line-height:1.8; max-width:420px;
    word-break:break-all; }
  #boot .bootBtn { margin-top:8px; padding:9px 22px; font-family:inherit; font-size:13px;
    letter-spacing:2px; cursor:pointer; color:#ffd24a; background:#0b1220; border:2px solid #ffd24a; }
  #boot.bootErr .bootT { color:#ff5b5b; }
  /* 加载转圈：用纯 CSS，不依赖任何图片资源 */
  #boot .spin { width:26px; height:26px; border:3px solid #223052; border-top-color:#7fe8ff;
    border-radius:50%; animation:sp 0.9s linear infinite; }
  @keyframes sp { to { transform:rotate(360deg); } }
  /* 检测诊断框：显示 SDK 原始返回，便于排查「明明点过却检测不到」 */
  #diagBox { width:100%; max-width:470px; background:#070b14; border:2px solid #223052;
    padding:10px 12px; text-align:left; max-height:290px; overflow-y:auto; }
  #diagBox .dg { font-size:11px; color:#8fa2c4; line-height:1.75; margin-bottom:6px;
    word-break:break-all; white-space:pre-wrap; }
  #diagBox .dg b { color:#ffd24a; }
  #diagBox .dg .ok { color:#7fffd4; }
  #diagBox .dg .no { color:#ff6b6b; }
  /* 流畅模式（body.q-low）：去掉发光/阴影/圆角计算等纯装饰开销，
     只保留能点、能看的界面 */
  .q-low h1, .q-low h2 { text-shadow:none; }
  .q-low .btn, .q-low .card, .q-low .talent, .q-low .chr, .q-low .chap { box-shadow:none; }
  .q-low .overlay { backdrop-filter:none; -webkit-backdrop-filter:none; }
  /* 平滑字体：关掉时改用像素化渲染（边缘变硬、复古颗粒感）。
   * 只关字体平滑，不碰 -webkit-text-stroke 之类，避免小字糊成一团。 */
  body.no-font-smooth, body.no-font-smooth * {
    -webkit-font-smoothing: none;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: geometricPrecision;
  }
  .q-low #rankBody, .q-low #interactList, .q-low #upList, .q-low #charList, .q-low #chapList {
    -webkit-overflow-scrolling:auto;
  }
  .q-low img { image-rendering:auto; }

  /* ===== 布局适配：界面元素整体大小 =====
     auto（默认，不挂 class）不做任何缩放；compact 收紧、loose 放大。
     只改菜单/面板的排版尺寸，不改画布逻辑分辨率，因此不影响手感。 */
  body.fit-compact .btn { padding:9px 12px; font-size:13px; letter-spacing:1px; }
  body.fit-compact .btn.primary { padding:12px; font-size:15px; }
  body.fit-compact .overlay h2 { font-size:17px; }
  body.fit-compact .setGroup { padding:9px 10px; }
  body.fit-compact .setTitle { font-size:13px; }
  body.fit-compact .seg { padding:6px 8px; font-size:12px; }
  body.fit-compact .tip { font-size:11px; }
  body.fit-compact #menuBtns { gap:7px; }
  body.fit-loose .btn { padding:13px 16px; font-size:17px; letter-spacing:2px; }
  body.fit-loose .btn.primary { padding:17px; font-size:20px; }
  body.fit-loose .overlay h2 { font-size:23px; }
  body.fit-loose .setGroup { padding:14px 16px; }
  body.fit-loose .setTitle { font-size:17px; }
  body.fit-loose .seg { padding:9px 13px; font-size:15px; }
  body.fit-loose .tip { font-size:13px; }
  body.fit-loose #menuBtns { gap:13px; }

  /* ===== 小屏自适应（body.auto-s1 / auto-s2 / auto-s3）=====
     自动检测屏幕尺寸：屏幅过小时逐级缩小界面，让游戏画面显示得更全。
     三档由 JS 自动挂载，玩家可在设置里关掉这项自动行为回到常规布局。
     只改排版尺寸，不改画布逻辑分辨率，因此不影响操作手感。 */
  body.auto-s1 .btn { padding:10px 13px; font-size:14px; letter-spacing:1px; }
  body.auto-s1 .btn.primary { padding:13px; font-size:16px; }
  body.auto-s1 .overlay h2 { font-size:18px; }
  body.auto-s1 .overlay { padding:16px 16px 20px; }
  body.auto-s1 .btnPause, body.auto-s1 #btnPause { width:42px; height:42px; }
  body.auto-s1 #btnSeal { width:42px; height:42px; }
  body.auto-s1 #menuBtns { gap:9px; }

  body.auto-s2 .btn { padding:9px 11px; font-size:13px; letter-spacing:1px; }
  body.auto-s2 .btn.primary { padding:11px; font-size:15px; }
  body.auto-s2 .overlay h2 { font-size:17px; }
  body.auto-s2 .overlay { padding:14px 13px 18px; }
  body.auto-s2 .setGroup { padding:9px 10px; }
  body.auto-s2 .seg { padding:6px 8px; font-size:12px; }
  body.auto-s2 .tip { font-size:11px; }
  body.auto-s2 .btnPause, body.auto-s2 #btnPause { width:38px; height:38px; }
  body.auto-s2 #btnSeal { width:38px; height:38px; }
  body.auto-s2 #menuBtns { gap:7px; }

  body.auto-s3 .btn { padding:8px 10px; font-size:12px; letter-spacing:0; }
  body.auto-s3 .btn.primary { padding:10px; font-size:14px; }
  body.auto-s3 .overlay h2 { font-size:16px; }
  body.auto-s3 .overlay { padding:12px 11px 16px; }
  body.auto-s3 .setGroup { padding:8px 9px; }
  body.auto-s3 .setTitle { font-size:13px; }
  body.auto-s3 .seg { padding:5px 7px; font-size:11px; }
  body.auto-s3 .tip { font-size:10.5px; }
  /* 小屏设置面板很「高」（9 个分组），进一步压缩行高与间距，
     减少需要滚动的距离。tip 行高默认 1.9，在窄屏上会拉开很多。 */
  body.auto-s2 .setGroup .tip { line-height:1.55; }
  body.auto-s3 .setGroup .tip { line-height:1.45; margin:1px 0 6px; }
  body.auto-s3 .setGroup { padding:7px 8px; }
  body.auto-s3 .setGroup .row { gap:6px; }
  body.auto-s3 .seg { padding:5px 9px; }
  body.auto-s3 .btnPause, body.auto-s3 #btnPause { width:36px; height:36px; }
  body.auto-s3 #btnSeal { width:36px; height:36px; }
  body.auto-s3 #menuBtns { gap:6px; }

  /* ===== 老机型设置（body.old-device）：在流畅模式之上再砍一刀 =====
     目标不是好看，是「能显示、能点、能动」。用最保守的 CSS：
     去掉所有阴影/模糊/渐变/圆角/动画，避免旧内核在这些属性上直接不渲染。 */
  body.old-device * { text-shadow:none !important; box-shadow:none !important;
    animation:none !important; transition:none !important; }
  body.old-device .overlay { backdrop-filter:none !important; -webkit-backdrop-filter:none !important;
    border-radius:0 !important; }
  body.old-device .btn, body.old-device .card, body.old-device .talent,
  body.old-device .chr, body.old-device .chap, body.old-device .seg,
  body.old-device .nw, body.old-device .rk, body.old-device .dex {
    border-radius:0 !important; background:#11182a !important; }
  body.old-device #starfield, body.old-device #scanline, body.old-device .glowfx { display:none !important; }

  /* ===== 成就弹窗（仿我的世界进度提示，总时长 5 秒）=====
     从右侧滑入 → 停留 → 从左侧滑出，位移由 JS 逐帧写入 transform（与游戏同一套 deltaTime）。
     长方形卡片，左侧奖杯图标 + 右侧标题/名称/描述三行文字。 */
  /* width:min(330px,78vw) 是 Chrome 79+ 语法，老内核整条丢弃导致宽度失控；
     改用 width + max-width（全版本支持），效果等价。 */
  /* top 由 JS 动态写入：菜单时 14px（贴顶，同 MC 进度提示），
     对局中下移到 82px 避开右上角的暂停按钮（12~58px）与 HUD 右上四行
     （击杀/金币/敌人/复活，约 26~74px），避免弹窗压住可交互元素。 */
  #achToast { position:fixed; top:14px; right:12px; z-index:60; width:330px; max-width:78vw;
    display:flex; align-items:center; gap:11px; padding:10px 14px 10px 11px;
    border:2px solid #40568a; border-radius:10px; background:#111a2e;
    box-shadow:0 6px 22px rgba(0,0,0,.55); will-change:transform; pointer-events:none; }
  #achToast.hide { display:none; }
  #achToastIco { width:34px; height:34px; flex:0 0 34px; display:flex; align-items:center; justify-content:center;
    border:2px solid currentColor; border-radius:8px; background:rgba(0,0,0,.35); }
  #achToastIco svg { width:22px; height:22px; display:block; }
  #achToastBody { flex:1; min-width:0; }
  #achToastTitle { font-size:11px; font-weight:700; letter-spacing:2px; line-height:1.5; }
  #achToastName { font-size:15px; font-weight:700; color:#e8ecf5; line-height:1.4;
    overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  #achToastDesc { font-size:11px; color:#8fa2c4; line-height:1.5; margin-top:2px; }
  /* 四种稀有度：普通青 / 金色 / 紫色 / 传说彩虹 */
  #achToast.tNormal    { border-color:#4fd7ff; }
  #achToast.tNormal    #achToastTitle { color:#7fe8ff; }
  #achToast.tNormal    #achToastIco { color:#7fe8ff; }
  #achToast.tGold      { border-color:#ffd24a; background:#1d1808; }
  #achToast.tGold      #achToastTitle { color:#ffd24a; }
  #achToast.tGold      #achToastIco { color:#ffd24a; }
  #achToast.tChallenge { border-color:#c07bff; background:#1a1029; }
  #achToast.tChallenge #achToastTitle { color:#c07bff; }
  #achToast.tChallenge #achToastIco { color:#c07bff; }
  /* 传说级：彩虹渐变边框 + 标题流光 */
  #achToast.tLegend    { border-color:transparent; background:#1b1026;
    background-image:linear-gradient(#1b1026,#1b1026),
      linear-gradient(90deg,#ff4d6d,#ffd24a,#4dff9b,#4fd7ff,#c07bff,#ff4d6d);
    background-origin:border-box; background-clip:padding-box,border-box;
    border-width:2px; border-style:solid; }
  #achToast.tLegend    #achToastTitle { background-image:linear-gradient(90deg,#ff4d6d,#ffd24a,#4dff9b,#4fd7ff,#c07bff);
    -webkit-background-clip:text; background-clip:text; color:transparent;
    background-size:300% 100%; animation:achHue 2.6s linear infinite; }
  #achToast.tLegend    #achToastIco { color:#ff7bd5; }
  @keyframes achHue { from { background-position:0% 50%; } to { background-position:300% 50%; } }

  /* ===== 成就面板列表 ===== */
  #achBody { width:100%; max-width:430px; max-height:52vh; overflow-y:auto; border:2px solid #223052;
    background:#080c16; }
  .acGroup { padding:7px 12px; font-size:11px; font-weight:700; letter-spacing:2px;
    background:#0d1526; border-bottom:1px solid #17203a; border-top:1px solid #17203a; }
  .ac { display:flex; align-items:center; gap:10px; padding:8px 12px; border-bottom:1px solid #17203a; }
  .ac .ai { width:26px; flex:0 0 26px; height:26px; display:flex; align-items:center; justify-content:center;
    border:2px solid currentColor; border-radius:6px; background:rgba(0,0,0,.3); }
  .ac .ai svg { width:17px; height:17px; display:block; }
  .ac .ab { flex:1; min-width:0; }
  .ac .an { font-size:12px; font-weight:700; color:#cfe6ff; }
  .ac .ad { font-size:11px; color:#8fa2c4; line-height:1.5; }
  .ac .pg { margin-top:3px; height:5px; background:#141c30; border-radius:3px; overflow:hidden; }
  .ac .pg i { display:block; height:100%; background:#4fd7ff; border-radius:3px; }
  .ac .av { font-size:10px; color:#5f6d8c; margin-top:2px; }
  .ac .as { font-size:11px; padding:3px 8px; border:2px solid #2b3550; color:#8fa2c4; white-space:nowrap; }
  .ac.done .as { border-color:#8fff9f; color:#8fff9f; }
  .ac.done .an { color:#e8ecf5; }
  .ac.tGold .ai, .ac.tGold .pg i { color:#ffd24a; }
  .ac.tGold .pg i { background:#ffd24a; }
  .ac.tChallenge .ai, .ac.tChallenge .pg i { color:#c07bff; }
  .ac.tChallenge .pg i { background:#c07bff; }
  .ac.tLegend .ai { color:#ff7bd5; }
  .ac.tLegend .pg i { background:linear-gradient(90deg,#ff4d6d,#ffd24a,#4dff9b,#4fd7ff,#c07bff); }
  .ac.tLegend .an { background-image:linear-gradient(90deg,#ff4d6d,#ffd24a,#4dff9b,#4fd7ff,#c07bff);
    -webkit-background-clip:text; background-clip:text; color:transparent; }
  .ac.tNormal .ai { color:#7fe8ff; }

  
  /* ===== 老 WebView 兼容兜底 =====
     仅在 JS 检测到不支持 flex gap 时生效（<html class="no-gap">）。
     gap 的 flex 支持要 Chrome 84，老内核整条忽略 → 元素全挤在一起。
     以下由脚本按容器方向自动生成等价 margin（已剥离注释解析）。 */
  .no-gap .overlay > * { margin-bottom:12px; }
  .no-gap .overlay > *:last-child { margin-bottom:0; }
  .no-gap .row > * { margin-right:10px; }
  .no-gap .row > *:last-child { margin-right:0; }
  .no-gap #menuBtns > * { margin-bottom:10px; }
  .no-gap #menuBtns > *:last-child { margin-bottom:0; }
  .no-gap .setGroup .row > * { margin-right:8px; }
  .no-gap .setGroup .row > *:last-child { margin-right:0; }
  .no-gap #upList > * { margin-right:8px; margin-bottom:8px; }
  /* no-gap 下间距靠 margin 撑出来，卡片宽度要相应让出这 8px，否则会被挤成单列。
   * max-width 也要一并放开，否则 250px 的上限会盖掉 calc 结果。 */
  .no-gap .talent { width:calc(50% - 12px); max-width:none; }
  .no-gap .talent .pips > * { margin-right:1.5px; margin-bottom:1.5px; }
  /* 极窄屏（<360px）两列会挤成一团，退回单列 —— 要写在 no-gap 区块内，
   * 否则会被上面这条同特异性的规则盖掉。 */
  @media (max-width:359px) {
    .no-gap .talent { width:calc(100% - 12px); }
  }
  .no-gap .grid > * { margin-right:10px; }
  .no-gap .grid > *:last-child { margin-right:0; }
  .no-gap #cards > * { margin-right:10px; }
  .no-gap #cards > *:last-child { margin-right:0; }
  .no-gap #evoCards > * { margin-right:10px; }
  .no-gap #evoCards > *:last-child { margin-right:0; }
  .no-gap #overStats > * { margin-right:20px; }
  .no-gap #overStats > *:last-child { margin-right:0; }
  .no-gap #menuSetCol > * { margin-bottom:16px; }
  .no-gap #menuSetCol > *:last-child { margin-bottom:0; }
  .no-gap #menuTreeWrap > * { margin-bottom:7px; }
  .no-gap #menuTreeWrap > *:last-child { margin-bottom:0; }
  .no-gap #menuGuideWrap > * { margin-bottom:7px; }
  .no-gap #menuGuideWrap > *:last-child { margin-bottom:0; }
  .no-gap #menuAchWrap > * { margin-bottom:7px; }
  .no-gap #menuAchWrap > *:last-child { margin-bottom:0; }
  .no-gap #menuShopWrap > * { margin-bottom:7px; }
  .no-gap #menuShopWrap > *:last-child { margin-bottom:0; }
  .no-gap #menuSetWrap > * { margin-bottom:7px; }
  .no-gap #menuSetWrap > *:last-child { margin-bottom:0; }
  .no-gap #menuNewsCol > * { margin-bottom:16px; }
  .no-gap #menuNewsCol > *:last-child { margin-bottom:0; }
  .no-gap #menuDexWrap > * { margin-bottom:7px; }
  .no-gap #menuDexWrap > *:last-child { margin-bottom:0; }
  .no-gap #menuNewsWrap > * { margin-bottom:7px; }
  .no-gap #menuNewsWrap > *:last-child { margin-bottom:0; }
  .no-gap #menuOthersWrap > * { margin-bottom:7px; }
  .no-gap #menuOthersWrap > *:last-child { margin-bottom:0; }
  .no-gap #menuChalWrap > * { margin-bottom:7px; }
  .no-gap #menuTuneWrap > * { margin-bottom:7px; }
  .no-gap #menuTuneWrap > *:last-child { margin-bottom:0; }
  .no-gap #menuChalWrap > *:last-child { margin-bottom:0; }
  .no-gap #dexTabs > * { margin-right:6px; }
  .no-gap #dexTabs > *:last-child { margin-right:0; }
  .no-gap .dx .dh > * { margin-right:8px; }
  .no-gap .dx .dh > *:last-child { margin-right:0; }
  .no-gap .nw .nh > * { margin-right:7px; }
  .no-gap .nw .nh > *:last-child { margin-right:0; }
  .no-gap #userBar > * { margin-right:9px; }
  .no-gap #userBar > *:last-child { margin-right:0; }
  .no-gap #rankTabs > * { margin-right:8px; }
  .no-gap #rankTabs > *:last-child { margin-right:0; }
  .no-gap #setTabs > * { margin-right:8px; margin-bottom:6px; }
  .no-gap #setTabs > *:last-child { margin-right:0; }
  .no-gap #newsTabs > * { margin-right:8px; }
  .no-gap #newsTabs > *:last-child { margin-right:0; }
  .no-gap .rk > * { margin-right:9px; }
  .no-gap .rk > *:last-child { margin-right:0; }
  .no-gap .ia > * { margin-right:10px; }
  .no-gap .ia > *:last-child { margin-right:0; }
  .no-gap #pauseStats > * { margin-right:18px; }
  .no-gap #pauseStats > *:last-child { margin-right:0; }
  .no-gap #boot > * { margin-bottom:14px; }
  .no-gap #boot > *:last-child { margin-bottom:0; }
  .no-gap body.fit-compact #menuBtns > * { margin-right:7px; }
  .no-gap body.fit-compact #menuBtns > *:last-child { margin-right:0; }
  .no-gap body.fit-loose #menuBtns > * { margin-right:13px; }
  .no-gap body.fit-loose #menuBtns > *:last-child { margin-right:0; }
  .no-gap body.auto-s1 #menuBtns > * { margin-right:9px; }
  .no-gap body.auto-s1 #menuBtns > *:last-child { margin-right:0; }
  .no-gap body.auto-s2 #menuBtns > * { margin-right:7px; }
  .no-gap body.auto-s2 #menuBtns > *:last-child { margin-right:0; }
  .no-gap body.auto-s3 #menuBtns > * { margin-right:6px; }
  .no-gap body.auto-s3 #menuBtns > *:last-child { margin-right:0; }
  .no-gap #achToast > * { margin-right:11px; }
  .no-gap #achToast > *:last-child { margin-right:0; }
  .no-gap .ac > * { margin-right:10px; }
  .no-gap .ac > *:last-child { margin-right:0; }
  /* .row 会换行，纵向也要留间距 */
  .no-gap .row > * { margin-bottom:10px; }
