/* ============================================================================
   仕途·登峰 · 手机版适配层  mobile.css
   ----------------------------------------------------------------------------
   设计原则：
     1. 本文件必须在 assets/styles.css **之后**加载。
        原 CSS 里有 17 处断点规则被更靠后的全局规则静默覆盖（同优先级后者胜），
        把手机规则放在最后，天然赢过它们 —— 不需要去改 styles.css 一个字。
     2. **所有规则都收在 `body.mob-game` 或 max-width 断点内**，桌面端（≥901px）零影响。
     3. 只用原项目已有的 CSS 变量（--paper/--card/--ink/--ink2/--ink3/--line/--seal/--gold…），
        昼夜两套主题自动跟随，不新增硬编码颜色。
     4. 结构改动（抽屉、汇总条）由 src/mobile.js 负责搬 DOM，本文件只管"长什么样"。
     5. ⚠️ 把节点搬出 `.layout` 会**同时丢掉** `.layout > aside …` 这一族后代选择器，
        所以抽屉里必须把关键布局重新声明一遍（见 §8）—— 这是本方案唯一的"代价"，
        换来的是完全不碰原 DOM 结构、不碰 styles.css。
   ========================================================================== */

/* ===================== 0. 视口与滚动基础 ===================== */
html {
  /* 手机地址栏伸缩会让 100vh 跳动；配合 dvh 使用 */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

/* ---------- 0b. 挡掉「一拖就刷新」与「双击缩放」两类误触 ----------
   ★ 2026-10-17 修「网页打开容易误触，然后刷新网页就被迫退出游戏」。
   实测（tools/_probe-mob-bugs.js，390×844）：overscroll-behavior-y 原先只写在
   `body.mob-game` 上，而**根滚动器是 <html>** —— 对手机 Chrome 的下拉刷新
   毫无约束力，玩家在正文顶端顺势一拖，整页刷新、回到主菜单。
   根滚动器必须写在 html 上（body 那份保留，双保险）。
   另外给按钮类元素上 touch-action:manipulation：关掉双击缩放的 300ms 等待，
   连点按钮时不再触发整页缩放 —— 那正是"误触"最常见的形式。
   pinch 缩放不受影响（manipulation 仍允许双指缩放）。 */
@media (max-width: 900px) {
  html { overscroll-behavior-y: none; }
  body.mob-game { overscroll-behavior-y: none; }
  body.mob-game button,
  body.mob-game .chip,
  body.mob-game .actbtn,
  body.mob-game .mtb,
  body.mob-game a[href] { touch-action: manipulation; }
}

/* 手机版不再需要"返回启动器"和作者烙印（占位又挡手） */
@media (max-width: 900px) {
  .backlauncher { display: none !important; }
  .author-brand { display: none !important; }
}

/* 底部标签栏留出高度 + 刘海屏安全区（只在手机版生效，桌面端不动 body） */
@media (max-width: 900px) {
  body.mob-game {
    padding-bottom: calc(58px + env(safe-area-inset-bottom, 0px)) !important;
    overscroll-behavior-y: none;
  }
  /* 兜底：任何图片都不许撑破视口（原项目有 1024px 的裸图，一旦脱离
     `.layout > aside .side-ic{width:20px}` 那条规则就会炸开） */
  body.mob-game img { max-width: 100%; }

  /* 右下角常驻浮动按钮（sd-link.js 内联样式注入）会被底部标签栏压住，抬起来。
     并且默认收成一颗「⋯」—— 三条常驻胶囊叠在正文右侧会挡触摸，手机上没有它的位置。 */
  body.mob-game #sdLinkDock {
    bottom: calc(68px + env(safe-area-inset-bottom, 0px)) !important;
    right: 10px !important;
    opacity: .92 !important;   /* 触屏没有 hover 提亮，直接给足对比 */
    z-index: 55 !important;    /* 低于标签栏(60)，不与它抢触摸区 */
    gap: 6px !important;
  }
  body.mob-game #sdLinkDock button {
    min-height: 40px; padding: 8px 13px !important; font-size: 12.5px !important;
  }
  #sdLinkToggle { display: none; }
  body.mob-game #sdLinkToggle {
    display: inline-flex; align-items: center; justify-content: center;
    width: 40px; height: 40px; padding: 0 !important;
    border-radius: 50% !important;
    background: rgba(28,22,18,.9) !important; color: #e8c56a !important;
    border: 1px solid #6b5a3a !important;
    font-size: 18px !important; line-height: 1 !important; cursor: pointer;
    opacity: .75;
  }
  body.mob-game #sdLinkDock.mob-dock-open #sdLinkToggle { opacity: 1; }
  body.mob-game #sdLinkDock:not(.mob-dock-open) button:not(#sdLinkToggle) { display: none !important; }

  /* toast 同理，别被标签栏吃掉 */
  .toast { bottom: calc(76px + env(safe-area-inset-bottom, 0px)) !important; max-width: 88vw; }
}

/* ===================== 1. 顶栏紧凑化 ===================== */
/* 顶栏原始结构是「左(年份+AP) | 中(职位铭牌) | 右(胶囊+按钮)」三列横排。
   390px 下实测 .top 高 522px（占 800px 视口的 65%），拆解：
     .t-left 153（.t-ymeta 三行 93）· .t-mid 152（.t-tags 换行占 70）· .t-right 176（两行胶囊 73 + 两行按钮 96）
   手机版逐块压到约 300px。 */
@media (max-width: 900px) {
  .screen { padding: 8px 10px 8px; max-width: 100%; }

  .top { padding: 10px 12px !important; }
  .top-c {
    display: flex !important;
    flex-direction: column !important;
    align-items: stretch !important;
    gap: 8px !important;
  }
  .t-left, .t-mid, .t-right {
    flex: 1 1 auto !important;
    min-width: 0 !important;
    width: 100% !important;
  }

  /* 左段：年份徽章与纪元标签同排，下面接一行元信息（不再竖着堆三行） */
  .t-left { flex-direction: row !important; flex-wrap: wrap !important; align-items: center !important; gap: 6px 10px !important; }
  .t-year-wrap { flex: 0 0 auto !important; flex-direction: row !important; align-items: center !important; gap: 8px !important; }
  .t-ymeta { flex: 1 1 100% !important; flex-direction: row !important; flex-wrap: wrap !important; align-items: center !important; gap: 2px 12px !important; }
  .t-line { font-size: 13px !important; letter-spacing: 1px !important; }
  .t-age { font-size: 14px !important; letter-spacing: 2px !important; }
  .t-ap { gap: 6px !important; }
  .ap-dots { flex-wrap: nowrap !important; gap: 3px !important; }
  .ap-dot { width: 7px !important; height: 7px !important; }
  .ap-txt { font-size: 12px !important; }
  .ap-txt b { font-size: 14px !important; }

  .t-year-seal { width: 52px !important; height: 52px !important; border-radius: 10px !important; }
  .t-year-seal .y { font-size: 21px !important; letter-spacing: 1px !important; }
  .t-year-seal .yl { font-size: 8px !important; letter-spacing: 2px !important; margin-top: 1px !important; }
  .era-tag-box { font-size: 11px !important; padding: 3px 8px !important; margin-top: 0 !important; white-space: nowrap !important; }

  /* 中段：单位 + 职位，标签改横向滑动一行 */
  .t-mid { padding: 2px 0 !important; gap: 4px !important; }
  .t-org { font-size: 11.5px !important; letter-spacing: 3px !important; padding: 2px 14px !important; }
  /* 覆盖全局 30px */
  .t-job { font-size: 23px !important; letter-spacing: 2px !important; padding-bottom: 5px !important; }
  /* ★ 2026-09-26 修「显示不完整」缺陷 A
   * 旧版这里写的是 overflow-x:auto + scrollbar-width:none（隐藏滚动条的横滑）。
   * 手机上没有任何「可以横滑」的视觉提示，玩家看到的只是**被切掉一半的徽章**：
   * 实测 320px 下 4 个徽章被切 2 个（其中「🔑 已激活」完全在可视区外），
   * 360/390px 下「🔑 已激活」仍被藏 26~56px。
   * 徽章是「条线 / 职级 / 激活状态」这类关键状态信息 ⇒ 改为换行，保证全部可见。
   * 保留 nowrap 在**单个徽章内部**（避免「承办综合文字」被拆成两行），
   * 徽章与徽章之间靠 flex-wrap 换行。 */
  .t-tags {
    flex-wrap: wrap !important;
    justify-content: center !important;
    overflow-x: visible;
    max-width: 100%;
    gap: 4px 3px !important;
    padding-bottom: 0;
  }
  .t-tags .tag { flex: 0 0 auto !important; font-size: 11px !important; padding: 2px 6px !important; white-space: nowrap; letter-spacing: 0 !important; }

  /* 右段：胶囊横向滑动一行，四个按钮并成一行 */
  .t-right { align-items: stretch !important; text-align: left !important; margin-left: 0 !important; gap: 6px !important; }
  /* ★ 2026-09-26 修「显示不完整」缺陷 A（同 .t-tags）
   * 「存款 8000元 / 临海省榆林县」这类胶囊同样被切：390px 下地区名被藏 15px、
   * 320px 下被藏 85px。地区是玩家的基本信息 ⇒ 改为换行全部可见。 */
  .t-chip-row {
    max-width: 100% !important;
    justify-content: center !important;
    flex-wrap: wrap !important;
    overflow-x: visible;
    gap: 4px 5px !important;
    padding-bottom: 0;
  }
  .tl-chip { flex: 0 0 auto !important; font-size: 11px !important; padding: 2px 7px !important; white-space: nowrap; letter-spacing: 0 !important; }

  /* ★ 2026-09-26 超窄屏（≤340px）再收一档：
   * 320×568 这类小屏上，徽章/胶囊按 11px 换行会把顶栏顶到 435px（占屏 77%）。
   * 收字号到 10px、内边距与间距各让 1~2px，即可回到**一行**，
   * 顶栏反而比修复前（383px）更矮，且信息一个不少。 */
  @media (max-width: 340px) {
    .t-tags { gap: 3px 2px !important; }
    .t-tags .tag { font-size: 10px !important; padding: 2px 4px !important; }
    .t-chip-row { gap: 3px 3px !important; }
    .tl-chip { font-size: 10px !important; padding: 2px 5px !important; }
  }
  .t-btns { display: grid !important; grid-template-columns: repeat(4, 1fr) !important; gap: 6px !important; }
  .t-btns .btn {
    width: 100% !important;
    padding: 9px 4px !important;
    font-size: 12.5px !important;
    letter-spacing: 0 !important;
    white-space: nowrap;
  }

  /* 触屏没有 hover：激活徽章的悬浮提示永远弹不出来，收成静态小标签 */
  .act-tip { display: none !important; }
  .t-badge-l { position: static !important; top: auto !important; left: auto !important; }

  /* 开始菜单大标题：覆盖全局 92px（原断点想收到 52px） */
  .mhead { padding: 16px 12px 8px !important; }
  .mhead h1 { font-size: 40px !important; letter-spacing: 6px !important; margin: 6px 0 8px !important; }
  .mhead h1::before, .mhead h1::after { display: none !important; }
  .mhead .sub { font-size: 14px !important; letter-spacing: 1px !important; }
  .mhead .byline { font-size: 12.5px !important; letter-spacing: 3px !important; }
}

/* ---------- 1c. 顶栏滚动收缩成迷你条 ---------- */
/* 完整顶栏约 383px ≈ 844px 视口的 45%。往下滚之后只留
   「年份徽章 + 职位名 + 结束本季」，其余收起，顶栏吸顶。
   由 mobile.js 给 body 加 .mob-topmini；折叠阈值 284 = 顶栏高度差(283)+1，
   必须大于滚动锚定的补偿量，否则折叠/展开会互相触发、无限弹跳
   （2026-10-19 实测归档，详见 src/mobile.js onScroll 的长注释③）。 */
@media (max-width: 900px) {
  /* 汇总条不再吸顶，避免和吸顶顶栏抢同一个 top:0（待办数由底部标签栏角标兜底） */
  body.mob-game #mobTodoBar { position: static !important; }

  body.mob-game.mob-topmini .top {
    position: sticky;
    top: 0;
    z-index: 50;
    padding: 6px 54px 6px 10px !important;   /* 右侧让出 #themeBtn（fixed right:14px） */
    background: var(--paper);
    box-shadow: 0 2px 12px rgba(0, 0, 0, .10);
  }
  body.mob-game.mob-topmini .top::after { display: none !important; }
  body.mob-game.mob-topmini .top-c {
    flex-direction: row !important;
    align-items: center !important;
    gap: 8px !important;
  }
  body.mob-game.mob-topmini .t-left {
    width: auto !important; flex: 0 0 auto !important;
    flex-direction: row !important; gap: 0 !important;
  }
  body.mob-game.mob-topmini .t-ymeta,
  body.mob-game.mob-topmini .t-badge-l,
  body.mob-game.mob-topmini .era-tag-box { display: none !important; }
  body.mob-game.mob-topmini .t-year-seal {
    width: 40px !important; height: 40px !important; border-radius: 8px !important;
  }
  body.mob-game.mob-topmini .t-year-seal .y { font-size: 17px !important; letter-spacing: 0 !important; }
  body.mob-game.mob-topmini .t-year-seal .yl { display: none !important; }

  body.mob-game.mob-topmini .t-mid {
    width: auto !important; flex: 1 1 auto !important;
    padding: 0 !important; gap: 0 !important;
  }
  body.mob-game.mob-topmini .t-org,
  body.mob-game.mob-topmini .t-tags { display: none !important; }
  body.mob-game.mob-topmini .t-job {
    font-size: 17px !important; letter-spacing: 1px !important;
    border-bottom: none !important; padding-bottom: 0 !important;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%;
  }

  body.mob-game.mob-topmini .t-right { width: auto !important; flex: 0 0 auto !important; gap: 0 !important; }
  body.mob-game.mob-topmini .t-chip-row { display: none !important; }
  body.mob-game.mob-topmini .t-btns { display: block !important; }
  body.mob-game.mob-topmini .t-btns .btn:not(.primary) { display: none !important; }
  body.mob-game.mob-topmini .t-btns .btn.primary {
    width: auto !important; padding: 8px 12px !important; font-size: 13px !important;
  }
}

/* ---------- 1d. 弹窗全屏化时顶栏迷你条不该吸在上层 ---------- */
body.mob-drawer-open.mob-topmini .top { z-index: 10; }
/* ---------- 1e. 晋升进度面板：手机上默认折叠 ---------- */
/* 实测 .promo-wide 高 514px（含 132px 配图），比顶栏还高。
   它是"信息"不是"动作"，默认折成一行摘要，点一下展开。
   折叠状态由 mobile.js 切换 .mob-open（点标题行）。 */
@media (max-width: 900px) {
  .main > .promo-wide { padding: 0 !important; overflow: hidden; }
  .main > .promo-wide .promo-art { display: none !important; }
  .main > .promo-wide .promo-body { padding: 0 !important; }
  .main > .promo-wide .promo-wide-h {
    display: flex !important;
    align-items: center;
    gap: 8px;
    min-height: 48px;
    padding: 10px 14px !important;
    margin: 0 !important;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
  }
  .main > .promo-wide .promo-wide-h::after {
    content: '展开 ›';
    flex: 0 0 auto;
    margin-left: auto;
    font-size: 12.5px;
    color: var(--seal);
    font-weight: 700;
  }
  .main > .promo-wide.mob-open .promo-wide-h::after { content: '收起 ⌃'; }
  .main > .promo-wide .promo-wide-h > span:first-child { flex: 0 0 auto; }
  .main > .promo-wide .promo-wide-h > .muted { flex: 1 1 auto; min-width: 0; text-align: right; }
  /* 折叠时只留标题行 */
  .main > .promo-wide:not(.mob-open) .promo-body > *:not(.promo-wide-h) { display: none !important; }
  .main > .promo-wide.mob-open .promo-art {
    display: block !important; width: 100%; height: 110px; object-fit: cover;
  }
  .main > .promo-wide.mob-open .promo-body { padding: 10px 12px !important; }
  /* 展开时也要纵向单列：原样式是 flex 横排 + 内部 auto/1fr 双栅格，390px 下挤成一团 */
  .main > .promo-wide.mob-open { display: block !important; }
  .main > .promo-wide.mob-open .promo {
    display: block !important;
    grid-template-columns: none !important;
    grid-auto-flow: row !important;
  }
  .main > .promo-wide.mob-open .promo-head,
  .main > .promo-wide.mob-open .promo-bar,
  .main > .promo-wide.mob-open .checks,
  .main > .promo-wide.mob-open .promo-acts,
  .main > .promo-wide.mob-open .promo-miss,
  .main > .promo-wide.mob-open .promo-hint {
    grid-column: auto !important; grid-row: auto !important;
    width: 100% !important; min-width: 0 !important; margin-bottom: 6px !important;
  }
  .main > .promo-wide.mob-open .checks { grid-template-columns: 1fr !important; }
}

/* ===================== 2. 三栏 → 单栏 ===================== */
@media (max-width: 900px) {
  .layout {
    display: block !important;      /* 彻底放弃 grid，避免任何列定义残留 */
    gap: 0 !important;
    overflow: visible !important;   /* 保证 #mobTodoBar 的 sticky 生效 */
  }
  .layout > .main { width: 100% !important; overflow: visible !important; }
  /* 左栏与右栏都被 mobile.js 搬进抽屉，这里只兜底：万一没搬走也不占位 */
  .layout > nav.rail,
  .layout > .rail.acts-col { display: none !important; }
  .layout > aside { display: none !important; }
}

/* ===================== 3. 剧情正文强制单栏（修死断点） ===================== */
/* 原 CSS：@media(max-width:960px){.story-pair{grid-template-columns:1fr}}
           被更靠后的全局 .story-pair{…1.15fr .85fr} 覆盖 ⇒ 手机上是双栏。
   这里明确拿回单栏。 */
@media (max-width: 900px) {
  .story-pair {
    display: block !important;
    grid-template-columns: none !important;
  }
  .story-pair .story-col { width: 100% !important; margin-bottom: 12px; }
  /* 插画在单栏下不再需要固定高度裁切，恢复等比 */
  .story-pair .scene-illus img {
    height: auto !important;
    max-height: 260px !important;
    object-fit: cover;
  }
  .story-pair .story-col > .panel { height: auto !important; }
}

/* ===================== 4. 表格横向滚动 ===================== */
/* mobile.js 只在手机下给每个 table 外套 .mob-table-wrap，桌面不套 */
@media (max-width: 900px) {
  .mob-table-wrap {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    margin: 8px 0;
    border-radius: 8px;
    /* 右侧留一点渐变压暗提示"可以横滑"，纯 CSS 无图片 */
    background-image: linear-gradient(to left, var(--card) 0%, transparent 24px);
    background-repeat: no-repeat;
    background-position: right center;
    background-size: 24px 100%;
  }
  .mob-table-wrap > table { min-width: 100%; }
}

/* ===================== 4b. 弹窗内自带横滑容器：补视觉提示 ===================== */
/* 2026-10-15：电脑版有些面板自己写了 overflow-x:auto 的 div（如 showNationIntl
   的国家列表，8 列 grid 固定轨共 618px）。手机上确实能横滑，但**没有任何
   「可以滑」的提示**，玩家只会看到最后一列操作按钮在屏幕外。
   mobile.js 用计算样式找出这类「真的溢出且可横滑」的容器，加这个 class。
   只加渐变压暗，不动布局、不改 overflow（原本的滚动行为保持原样）。 */
@media (max-width: 900px) {
  .mob-hscroll {
    background-image: linear-gradient(to left, var(--card) 0%, transparent 24px);
    background-repeat: no-repeat;
    background-position: right center;
    background-size: 24px 100%;
  }
}

/* ===================== 4c. 本次电脑版更新带入的触控偏小元素 ===================== */
/* 2026-10-15 全量 495 面板体检（390px，31 个职级档位）查出：99 个「触控 <44px」
   里，**94 个是 .chip.tiny 在 §10 被有意设计的 34px**（密集列表要紧凑），
   不是缺陷。真正低于项目自身 34px 地板的只有 4 个 —— 全部来自本次电脑版
   新增/改动的模块（govplan / village-ui / reality-pack / org-chart-redesign），
   所以是**这次更新新带上手机的**。统一抬到 34px（项目最紧凑可点元素的地板），
   不强行抬到 44px，免得把密集列表撑变形。

   ★ 判定标准沿用 §15 注释里那条：**写了具体数值 / 写了 !important ⇒ 有意，不碰**。
     典型的反例就是 showPortfolio 的「🗣 向一把手汇报」chip —— 它 27px，
     但 portfoliomatch.js 给 `.narr.scport .chip` 显式写了 `min-height:0 !important`
     （§15 注释里点名「本适配层碰不动也不该碰」）⇒ 这里**不**为它加规则，
     加了也会被 !important 压掉，白白留一条死代码。 */
@media (max-width: 900px) {
  /* ① 庭议会消息行右上角「💬 单独谈谈」圆钮：原 21×21 绝对定位，手机上基本点不中 */
  .govp-m-chat {
    width: 32px !important; height: 32px !important;
    line-height: 30px !important; font-size: 14px !important;
  }
  /* ② 庭议会消息主体行（头像+姓名+勾选框）：裸 <button> 没写任何高度，只有 30px */
  .govp-m-tick { min-height: 34px; }
  /* ③ 组织架构页签：12px 字 + 6px 上下内边距 = 26px */
  .og2-tab { min-height: 34px; display: inline-flex; align-items: center; }
  /* ④ 办公室卡片的折叠头（可点）：31px，抬到地板 */
  .ofc-card-h[data-act] { min-height: 34px; }
  /* ⑤ 村民/国别档案的名字文本链接：文字行高只有 20px。
        用 padding + 等量负 margin 把点击区撑到约 30px，布局完全不变
        （负 margin 抵消了 padding 占位，不会推挤相邻文字）。 */
  .link[data-act] { padding: 5px 2px; margin: -5px -2px; }
}

/* ===================== 5. 待办横幅：汇总条 + 抽屉 ===================== */
/* mobile.js 把 .crisis-banner / .talk-banner / .rival-wide / .orders-wide 搬进
   #mobTodoDrawer，并在 .main 顶部插入 #mobTodoBar 汇总条。 */

#mobTodoBar {
  position: sticky;
  top: 0;
  z-index: 45;
  display: none;                 /* 默认不显示，仅手机+游戏内+有待办时显示 */
  align-items: center;
  gap: 10px;
  width: 100%;
  margin: 8px 0 10px;
  padding: 11px 14px;
  border: 1px solid var(--seal);
  border-left: 4px solid var(--seal);
  border-radius: 10px;
  background: var(--card);
  box-shadow: var(--shadow);
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  /* 沿用原项目 crisis-banner 的呼吸动画 keyframes（cpl），
     把压力从"空间堆叠"转成"数字压迫" */
  animation: cpl 1.6s ease-in-out infinite;
}
/* ★ 只有手机版游戏内才亮出来 */
body.mob-game #mobTodoBar { display: flex; }

#mobTodoBar .mtb-ic { font-size: 20px; line-height: 1; }
#mobTodoBar .mtb-t { flex: 1; display: flex; flex-direction: column; gap: 2px; text-align: left; }
#mobTodoBar .mtb-n { font-size: 14px; font-weight: 700; color: var(--seal); }
#mobTodoBar .mtb-s { font-size: 11.5px; color: var(--ink2); }
#mobTodoBar .mtb-hot {
  flex: 0 0 auto; min-width: 26px; height: 26px; padding: 0 8px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 13px; background: #c03a2c; color: #fff;
  font-size: 13px; font-weight: 700;
}
#mobTodoBar .mtb-caret { color: var(--ink3); font-size: 13px; white-space: nowrap; }

/* 抽屉内：待办按紧急度分组 */
.mob-todo-group { margin-bottom: 16px; }
.mob-todo-group > h4 {
  margin: 0 0 8px; padding-bottom: 6px;
  font-size: 13px; font-weight: 700; letter-spacing: 1px;
  color: var(--ink2);
  border-bottom: 1px dashed var(--line);
}
.mob-todo-group.hot > h4 { color: #c03a2c; }
/* 抽屉里的横幅改纵向排布，不再挤成一行 */
#mobTodoDrawer .crisis-banner,
#mobTodoDrawer .talk-banner,
#mobTodoDrawer .rival-wide,
#mobTodoDrawer .orders-wide {
  display: block !important;
  margin-bottom: 10px;
  animation: none;               /* 抽屉内关掉呼吸动画，避免几十个一起闪 */
}
#mobTodoDrawer .crisis-ic {
  display: inline-block; margin-right: 6px; font-size: 20px; vertical-align: -2px;
}
#mobTodoDrawer .cb-t { display: block !important; }
#mobTodoDrawer .cb-t b { display: inline; font-size: 14px; }
#mobTodoDrawer .cb-t .muted { display: block; margin-top: 3px; }
#mobTodoDrawer .crisis-banner .chip,
#mobTodoDrawer .talk-banner .chip {
  display: block !important;
  width: 100%;
  margin-top: 9px;
  min-height: 44px;
  line-height: 44px;
  padding: 0 12px;
  text-align: center;
  font-size: 14px;
}
/* 抽屉里的暗斗/军令状面板也要纵向铺满 */
#mobTodoDrawer .rival-wide .acts .chip,
#mobTodoDrawer .orders-wide .chip { min-height: 40px; line-height: 40px; }

/* ★ 2026-09-26 修「显示不完整」缺陷 B：待办卡标题被挤成竖排
 *
 * 症状：「🎯 军令状」渲染成「军令」/「状」两行、「📄 成绩单」被撑成 90px 高的白框。
 * 根因：`.promo-wide-h` 是 `display:flex` 三子元素（标题 / 成绩单按钮 / 长说明）。
 *   中文 flex 子项的 min-content 只有**一个字宽**，为了给第三段长说明让位，
 *   前两个子项被压缩到最窄 ⇒ 逐字换行。
 *   桌面端面板宽 ~1100px 一行放得下，所以只有手机侧（抽屉宽 ~362px）会触发。
 * 修法：抽屉内改「可换行 + 标题/按钮不参与收缩 + 长说明独占一行」。
 *   标题与按钮各占自然宽度，说明文字换到第二行左对齐，不再互相挤压。 */
#mobTodoDrawer .orders-wide .promo-wide-h,
#mobTodoDrawer .rival-wide .promo-wide-h {
  display: flex !important;
  flex-wrap: wrap !important;
  align-items: center !important;
  justify-content: flex-start !important;
  gap: 6px 8px !important;
}
#mobTodoDrawer .orders-wide .promo-wide-h > span:first-child,
#mobTodoDrawer .rival-wide .promo-wide-h > span:first-child {
  flex: 0 0 auto !important;
  white-space: nowrap;
}
#mobTodoDrawer .orders-wide .promo-wide-h > .chip,
#mobTodoDrawer .rival-wide .promo-wide-h > .chip { flex: 0 0 auto !important; }
#mobTodoDrawer .orders-wide .promo-wide-h > .muted,
#mobTodoDrawer .rival-wide .promo-wide-h > .muted {
  flex: 1 1 100% !important;
  text-align: left !important;
  white-space: normal;
}

@media (max-width: 900px) {
  /* 手机正文里最多留 3 条紧急横幅（带 .mob-inline），其余全部隐藏（它们在待办抽屉里） */
  .main > .crisis-banner,
  .main > .talk-banner { display: none !important; }

  /* 内联的紧急横幅改成一行的紧凑条：
     [图标] [标题] [按钮]，描述收进抽屉。
     原来竖着排（图标行 + 标题 + 描述 + 通栏按钮）实测每条约 240px，
     3 条就把正文顶到 1.5 屏；紧凑条每条约 56px。 */
  .main > .crisis-banner.mob-inline,
  .main > .talk-banner.mob-inline {
    display: grid !important;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
    gap: 9px;
    min-height: 0 !important;
    padding: 8px 10px !important;
    margin-bottom: 8px !important;
    animation: none;
    border-left-width: 4px;
  }
  .main > .crisis-banner.mob-inline .crisis-ic {
    grid-column: 1; font-size: 19px; line-height: 1; margin: 0;
  }
  .main > .crisis-banner.mob-inline .cb-t {
    grid-column: 2; display: block !important; min-width: 0;
  }
  .main > .crisis-banner.mob-inline .cb-t b { display: block; font-size: 13.5px; line-height: 1.4; }
  /* 描述隐藏 —— 完整文案在待办抽屉里，这里只负责"提醒 + 一键入口" */
  .main > .crisis-banner.mob-inline .cb-t .muted { display: none !important; }
  .main > .crisis-banner.mob-inline .chip {
    grid-column: 3;
    width: auto !important;
    margin: 0 !important;
    min-height: 40px; line-height: 40px;
    padding: 0 12px !important;
    font-size: 13px;
    white-space: nowrap;
  }
  .main > .crisis-banner.mob-inline .cb-t + .chip,
  .main > .crisis-banner.mob-inline > .chip:only-of-type { align-self: center; }

  /* 宽幅面板同样纵向排布 */
  .main > .promo-wide, .main > .rival-wide, .main > .orders-wide { margin-bottom: 10px; }
  .order-row { margin-bottom: 8px; }
}

/* ===================== 6. 抽屉（通用） ===================== */
#mobOverlay {
  position: fixed; inset: 0; z-index: 190;
  background: rgba(0,0,0,.45);
  display: none;
  opacity: 0;
  transition: opacity .2s ease;
}
body.mob-drawer-open #mobOverlay { display: block; opacity: 1; }

.mob-drawer {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 200;
  max-height: 82dvh;
  max-height: 82vh;
  display: none;                     /* 非手机版彻底不参与布局 */
  flex-direction: column;
  background: var(--paper);
  border-top: 2px solid var(--seal);
  border-radius: 16px 16px 0 0;
  box-shadow: 0 -8px 32px rgba(0,0,0,.28);
  transform: translateY(102%);
  transition: transform .26s cubic-bezier(.22,.8,.3,1);
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
body.mob-game .mob-drawer { display: flex; }
.mob-drawer.mob-open { transform: translateY(0); }

.mob-drawer-hd {
  flex: 0 0 auto;
  display: flex; align-items: center; gap: 10px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--line);
  background: var(--card);
  border-radius: 16px 16px 0 0;
}
.mob-drawer-hd b { flex: 1; font-size: 15px; font-weight: 700; color: var(--ink); }
.mob-drawer-hd .mob-x {
  flex: 0 0 auto;
  width: 36px; height: 36px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--line); border-radius: 50%;
  background: transparent; color: var(--ink2);
  font-size: 17px; font-family: inherit; cursor: pointer;
}
.mob-drawer-bd {
  flex: 1 1 auto;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  padding: 14px;
}

/* ---------- 7a. 官身气象浮层：手机版改成居中浮层，永不被抽屉裁掉 ----------
   ★ 2026-10-17 修「有时候显示异常，看不到健康和压力」。
   桌面上 .hero-gs-pop 是 absolute 到立绘**左侧** 232px（styles.css:4594）。
   手机版立绘住在 #mobSideBody（.mob-drawer-bd，overflow-y:auto）里，
   right:calc(100%+8px) 把浮层整个甩到抽屉外：实测 390px 视口下 left:-226，
   六个属性格（含健康 80 / 压力 20）全部在视口外（tools/_probe-mob-bugs.js）。
   改法：position:fixed 居中。fixed 的包含块是带 transform 的 .mob-drawer
   （translateY(0)），因此**不受** .mob-drawer-bd 的 overflow 裁剪；
   再给 max-height + 自身 overflow-y，属性多也不会超出屏幕。
   表格/弹窗之外的一切 z-index 都低于 .mob-drawer(200)，盖得住正文。 */
@media (max-width: 900px) {
  .mob-drawer .hero-gs-pop,
  .mob-drawer .hero-card .hero-gs-pop,
  .mob-drawer .hsr-portrait .hero-gs-pop,
  .mob-drawer .ap-plate-hero .hero-gs-pop {
    position: fixed;
    left: 50%;
    right: auto;
    top: 50%;
    bottom: auto;
    transform: translate(-50%, -50%);
    width: min(320px, calc(100vw - 32px));
    max-height: 72vh;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
    z-index: 260;                 /* 在抽屉(200)内部置顶，盖过遮罩(190) */
    padding: 14px 15px;
  }
}

/* ===================== 7. 左栏（自由行动）→ 主界面内嵌区块 ===================== */
/* ★ 2026-09-27 重做：这一块原先被搬进 #mobActionDrawer（底部「行动」抽屉）。
   用户反馈「玩法折叠的太深，不方便游玩」—— 实测抽屉里是 16 个入口 +
   6 个折叠组（政务42 / 岗位8 / 人际17 / 成长7 / 生活11 / 档案12）共 97 项，
   每做一件事要"点标签 → 等抽屉 → 找入口 → 点"四步。
   现在整块搬进 .main，成为主界面的一部分（mobile.js 给它打上 .mob-rail-inline）。

   选择器随之从 `#mobActionDrawer .x` 换成 `.mob-rail-inline .x`：
   规则不再绑死"在哪个容器里"，将来搬去哪都成立。
   注意 nav 仍保留 .acts-col 类名，所以 styles.css:384-396 那族原生规则照样命中，
   这里只覆盖手机上必须改的部分。 */
.mob-rail-inline {
  /* 原生 .rail 是 `position:sticky; top:14px; max-height:calc(100vh-28px); overflow-y:auto`
     （styles.css:375）—— 在正文里会变成"跟着滚的小窗"，必须全部摘掉。 */
  position: static !important;
  max-height: none !important;
  overflow: visible !important;
  width: 100% !important;
  top: auto !important;
  display: block !important;
  margin: 0 0 12px !important;
}
.mob-rail-inline .acts-rail { gap: 6px; }
.mob-rail-inline .actbtn { min-height: 52px; padding: 9px 12px; }
.mob-rail-inline .act-nm { font-size: 15px; }
.mob-rail-inline .act-sub { font-size: 12px; }
.mob-rail-inline .acts.vertical .chip,
.mob-rail-inline .acts-grid .chip {
  min-height: 44px; line-height: 44px; padding: 0 12px; font-size: 14px;
}
/* 动作网格：原生 `.acts-col .acts-grid{grid-template-columns:1fr}` 是竖排单列，
   390px 全宽下会把 42 项政务动作拖成很长一条 ⇒ 改 2 列。320px 以下退回单列。 */
.mob-rail-inline .acts-col .acts-grid,
.mob-rail-inline .acts-grid {
  grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
  gap: 8px !important;
}
@media (max-width: 340px) {
  .mob-rail-inline .acts-col .acts-grid,
  .mob-rail-inline .acts-grid { grid-template-columns: 1fr !important; }
}
.mob-rail-inline .tool-row { display: grid !important; grid-template-columns: 1fr 1fr; gap: 8px; }
.mob-rail-inline .tool-row .actbtn { min-height: 56px; }
/* 分组标签：窄列原本竖排单列（styles.css:385），手机上改成可换行的横向标签条 */
.mob-rail-inline .acts-col .grp-tabs,
.mob-rail-inline .grp-tabs {
  flex-direction: row !important;
  flex-wrap: wrap !important;
  align-items: stretch !important;
  gap: 8px !important;
}
.mob-rail-inline .acts-col .grp-tab,
.mob-rail-inline .grp-tab {
  /* ★ 每行 3 个（flex-basis 30%）而不是 2 个：6 个签从 3 行压到 2 行。
     这一块原来占 148px，压缩后约 100px —— rail 总高直接少 48px。 */
  flex: 1 1 30% !important;
  width: auto !important;
  display: inline-flex !important;
  min-height: 40px !important;
  padding: 0 8px !important;
  font-size: 13px !important;
  gap: 3px !important;
  text-align: center !important;
  justify-content: center !important;
}
.mob-rail-inline .grp-tab .gt-ic-img { width: 14px !important; height: 14px !important; }
.mob-rail-inline .grp-tab .gt-n { font-size: 11px !important; }
.mob-rail-inline .grp-tab .gt-caret { font-size: 11px !important; }
.mob-rail-inline .grp-body { flex: 1 0 100%; margin-top: 4px; }

/* ★★ 锁定按钮：名称 + 门槛小字恢复「上下两行」（2026-10 修，别删这段注释）
   病根（_dbg-locked.js 实测，320/360/390 三档全中）：
     `.acts-rail .grp-body .actbtn.locked`（styles.css:5322-5326）把它改成
     **横排** `flex-direction:row; align-items:center; gap:8px`，
     而 `.act-nm{flex:1}` + `.lock-tag`（无 flex 约束、`white-space` 默认 normal
     但内容短不换行）同在一条 129px（320）／144px（390）的按钮里：
     门槛小字先占 57~68px，名字只剩 0~19px ⇒ 中文没有空格可断，
     **逐字竖排**成一根细柱（实测「揣摩上意」.act-nm 宽 8px、
     「申请党校/中青班培训」宽 0px、文字直接溢出按钮叠在门槛tag上）。
     这就是玩家说的「很多地方文字溢出」。
   修法：手机上让这两行字**纵向堆叠**，各占满整行、允许正常换行。
   ⚠️ 必须 `!important`：styles.css:5322 那条是 4 类选择器（.acts-rail .grp-body
      .actbtn .locked），比这里的 3 类更特化，不加 !important 压不住。 */
.mob-rail-inline .actbtn.locked {
  flex-direction: column !important;
  align-items: stretch !important;
  gap: 4px !important;
}
.mob-rail-inline .actbtn.locked .act-nm {
  flex: 0 0 auto !important;
  width: 100% !important;
  min-width: 0 !important;
  overflow-wrap: anywhere;      /* 长名字（「露一手（稿子里留自己的印）」）正常断行 */
  line-height: 1.35 !important;
}
.mob-rail-inline .actbtn.locked .lock-tag {
  flex: 0 0 auto !important;
  max-width: 100% !important;
  margin-top: 0 !important;
  white-space: normal !important;   /* 长门槛「🔒 需副科以上」也能换行，不再横向顶出去 */
  line-height: 1.3 !important;
}

/* ★★ 分组内普通按钮：2 列网格下按钮只有 ~144px，而按钮里塞了一整排装饰 chrome
   —— 朱印 24px + AP 金徽 31px + 两个 8px 间距 + 18px 内边距 = 89px，
   名称只剩 ~51px（_dbg-actnm3.js：实测「陪伴家人（早点回家）」.act-nm 宽 50.8px）。
   长名字被折成 3 行，最后一行「点回家）」宽 54px **溢出 3.2px**，
   被 `.actbtn{overflow:hidden}` 整颗切掉 —— 全角右括号「）」按 UAX#14 不许出现在
   行首，所以「家）」粘成一坨断不开，光靠缩小字号救不回来。
   同类受害者还有「灰色操作（不推荐）」（360px 下名称仅 36px）。
   修法两条并行：
     ① 把装饰性 chrome 收一收，把宽度还给文字（朱印 24→20、间距 8→6）；
     ② 名称加 `overflow-wrap:anywhere` —— 它是唯一能在「家）」前开口子的属性
        （`break-word` 不行，它只在词放不下时才断）。 */
.mob-rail-inline .grp-body .actbtn { gap: 6px !important; padding: 6px 7px !important; }
.mob-rail-inline .grp-body .actbtn::before {
  width: 20px !important; height: 20px !important; font-size: 11px !important;
}
.mob-rail-inline .grp-body .actbtn .act-ap { font-size: 10px !important; padding: 1px 4px !important; }
.mob-rail-inline .grp-body .actbtn .act-ap i { font-size: 7px !important; }
.mob-rail-inline .grp-body .actbtn .act-nm { overflow-wrap: anywhere; }

/* --- rail 高度压缩（★ 这一组是"别把剧情挤下去"的关键，删之前先看数） ---
   390px 实测 rail 原始总高 1071px，逐块：ap-line 27 / 急务 108 / 办公室 64 /
   **今年要紧 352** / 工具行 120 / 深造 54 / 分组签 148 / 纪检 50 / 间距 56。
   「今年要紧」一个就占 1/3 —— 因为按钮里的 `.tip-why`（"升迁差政绩：政绩 14/50"）
   在 2 列布局下每列只有约 170px 宽，硬生生换行成 3~4 行。
   ⇒ 按钮去掉 min-height 撑高、tip-why 限 2 行并缩字号。 */
.mob-rail-inline .tip-panel { padding: 9px 10px !important; margin-bottom: 6px !important; }
.mob-rail-inline .tip-panel h3 { font-size: 12.5px !important; margin-bottom: 5px !important; letter-spacing: .5px !important; }
/* ★ 反直觉但实测正确：这一组**改成单列**反而更矮（352 → 约 200px）。
   两列时每列只有约 170px 宽，`.tip-why`（"升迁差政绩：政绩 14/50"）被挤成 3~4 行，
   三个按钮撑到 352px；单列后整行 322px 可用，名称 + 原因 + AP 一行放得下。
   —— 所以这里**故意**覆盖上面那条 `.acts-grid` 的 2 列规则。 */
.mob-rail-inline .tip-panel .acts-grid { grid-template-columns: 1fr !important; gap: 6px !important; }
.mob-rail-inline .tip-panel .actbtn,
.mob-rail-inline .tip-panel .actbtn.withwhy { min-height: 0 !important; padding: 7px 9px !important; }
/* ★★ 真正的元凶在这里（别删这段注释，否则下次又会去改字号、白费功夫）：
   `.actbtn` 是 `display:flex`，`.act-nm` 是 `flex:1`，而 `.tip-why` **既没有
   flex 也没有 min-width:0** ⇒ 它作为 flex 子项被压到极窄，中文又没有空格可断，
   于是**逐字换行**成 3~4 行，把按钮撑到 117px 高（3 个 = 352px）。
   实测证据：只改字号（10.5px）和 `-webkit-line-clamp:2` 都**无效**，高度纹丝不动。
   修法：名称按内容宽度不参与分配，原因占满剩余空间且**单行省略**。 */
.mob-rail-inline .tip-panel .actbtn .act-nm { flex: 0 0 auto !important; font-size: 14px !important; }
.mob-rail-inline .tip-panel .tip-why {
  flex: 1 1 auto !important;
  min-width: 0 !important;
  font-size: 10.5px !important;
  line-height: 1.25 !important;
  margin-top: 0 !important;
  display: block !important;
  white-space: nowrap !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
}
.mob-rail-inline .tip-panel .act-ap { font-size: 10px !important; padding: 2px 7px !important; }
/* 急务组：竖排 chip 单列 44px 起，压到 40px */
.mob-rail-inline .qgrp { margin-top: 6px; }
.mob-rail-inline .qgrp-t { font-size: 12px !important; padding: 3px 2px 4px !important; margin-bottom: 4px !important; }
.mob-rail-inline .acts.vertical .chip { min-height: 40px !important; line-height: 40px !important; }

/* --- 「🎓 在职深造」按钮（mobile.js 注入到工具行之后） ---
   把埋在「人事档案」弹窗里的一整个主动玩法提到明面。整行宽度、金色描边，比工具按钮醒目一档。 */
.mob-rail-inline .mob-edu-btn {
  width: 100%;
  margin: 2px 0 2px;
  border-color: #c8a45c !important;
  background: linear-gradient(180deg, #fffdf5, #fdf6e6) !important;
}

/* ★ 本块**必须**收在 body.mob-game 下：mobile.js 只在 ≤900px 才给 body 挂 mob-game，
   桌面态没有这个类 ⇒ 注入的按钮自动隐身。写在裸 .mob-rail-inline 上会漏到桌面端
   （实测 1600 宽时按钮仍显示、宽 138px）。 */
/* --- 「🏛 今日会议」常驻入口（mobile.js 注入到自由行动区最前） ---
   玩家原话「找不到召开这个会的地方」：入口本身在，但藏在「政务 → 主政施政」
   第 14 项、以及右栏组织架构框（手机上被推到第 8 屏）。
   这里把它提到最顶，朱红描边 + 印色标题，跟「在职深造」的金色区分开：
   · is-urgent（有议程待表决 / 本季必须开的会）用实心印色，一眼就看见；
   · 平常态是浅印底，不抢戏。
   宽度 100%、与 rail 内其它 actbtn 同高（44px），不破坏既有的点击区尺寸。 */
body.mob-game .mob-rail-inline .mob-meet-btn {
  width: 100%;
  margin: 0 0 6px;
  border-color: var(--seal) !important;
  background: rgba(164, 52, 43, .06) !important;
}
body.mob-game .mob-rail-inline .mob-meet-btn .act-nm {
  color: var(--seal) !important;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
body.mob-game .mob-rail-inline .mob-meet-btn.is-urgent {
  background: var(--seal) !important;
  border-color: var(--seal) !important;
}
body.mob-game .mob-rail-inline .mob-meet-btn.is-urgent .act-nm,
body.mob-game .mob-rail-inline .mob-meet-btn.is-urgent .act-sub {
  color: #fdf6e6 !important;
}
body.mob-game .mob-meet-dot {
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
  padding: 2px 6px;
  border-radius: 8px;
  background: #fdf6e6;
  color: var(--seal);
}

/* 会议清单弹层：一行一个会，左侧印记、中间名称+说明、右侧「进入」 */
body.mob-game .mob-meet-list { gap: 8px !important; }
body.mob-game .mob-meet-row.chip {
  display: flex !important;
  align-items: center !important;
  gap: 10px !important;
  width: 100%;
  min-height: 56px !important;
  padding: 10px 12px !important;
  text-align: left;
  line-height: 1.35 !important;
}
body.mob-game .mob-meet-row .mmr-ic {
  flex: 0 0 auto;
  width: 34px; height: 34px;
  display: grid; place-items: center;
  font-size: 18px;
  border-radius: 8px;
  background: rgba(164, 52, 43, .08);
  border: 1px solid rgba(164, 52, 43, .25);
}
body.mob-game .mob-meet-row .mmr-t {
  flex: 1 1 auto;
  min-width: 0;
  display: flex; flex-direction: column; gap: 2px;
}
body.mob-game .mob-meet-row .mmr-t b {
  font-size: 15px; font-weight: 700;
  overflow-wrap: anywhere;
}
body.mob-game .mob-meet-row .mmr-t i {
  font-style: normal;
  font-size: 12px;
  color: var(--ink3);
  overflow-wrap: anywhere;
}
body.mob-game .mob-meet-row .mmr-go {
  flex: 0 0 auto;
  font-size: 12px;
  color: var(--seal);
  font-weight: 700;
}

/* --- 档案弹窗：教育块折叠条 ---
   从「档案」入口进来时，教育块默认折起（信息一条不丢，点标题行展开）；
   档案因此回归"看履历"的定位。 */
.mob-edu-fold {
  margin: 10px 0 2px;
  border: 1px solid var(--line);
  border-radius: 8px;
  overflow: hidden;
  background: var(--card);
}
.mob-edu-fold-h {
  width: 100%;
  display: flex; align-items: center; gap: 8px;
  flex-wrap: wrap;                  /* 说明那行放不下时换到第二行，别把「展开」挤掉 */
  padding: 11px 12px;
  border: 0; background: transparent;
  font-family: inherit; text-align: left; cursor: pointer;
}
.mob-edu-fold-h .mef-t { font-size: 14px; font-weight: 700; color: var(--ink); flex: 0 0 auto; }
/* 说明单独占满第二行（order 让它排到 caret 之后）——390px 实测三个元素挤一行时
   会断成「学业履 / 历」这种，很难看。 */
.mob-edu-fold-h .mef-s {
  font-size: 11.5px; color: var(--ink3);
  flex: 1 1 100%; order: 3; min-width: 0; margin-top: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.mob-edu-fold-h .mef-c { font-size: 12.5px; color: var(--seal); flex: 0 0 auto; white-space: nowrap; margin-left: auto; }
.mob-edu-fold-bd { display: none; padding: 0 12px 12px; }
.mob-edu-fold.on { border-color: var(--seal); }
.mob-edu-fold.on .mob-edu-fold-bd { display: block; }

/* 从「🎓 在职深造」入口进来时，弹窗里只剩教育块：
   把那段 105 字的长说明收成小字，别一进门就是一大坨灰字。 */
.mob-edu-only h4.mob-edu-h4 { font-size: 12.5px; line-height: 1.5; color: var(--ink2); font-weight: 600; }

/* ===================== 8. 右栏（属性/立绘/家宅/政务）→ 抽屉 ===================== */
/* ⚠️ <aside> 被搬出 .layout 后，`.layout > aside …` 这一族选择器（40 多条）会全部失配。
   解法见 src/mobile.js：给 #mobSideBody 加上 `layout` 类，让祖先链原样保留。
   这里只做「把它压成一列」这件事。 */
#mobSideBody.layout {
  display: block !important;
  grid-template-columns: none !important;
  gap: 0 !important;
  align-items: stretch !important;
  overflow-x: hidden !important;
}
#mobSideBody > aside {
  display: block !important;
  grid-template-columns: none !important;
  gap: 0 !important;
  width: 100% !important;
}
#mobSideBody > aside > * {
  grid-column: auto !important;
  grid-row: auto !important;
  width: 100% !important;
  min-width: 0 !important;
  min-height: 0 !important;
  margin-left: 0 !important;
  margin-right: 0 !important;
  margin-bottom: 12px !important;
}
#mobSideBody > aside .side-main,
#mobSideBody > aside .side-sub,
#mobSideBody > aside .side-pair {
  display: flex !important;
  flex-direction: column !important;
  gap: 12px !important;
  margin-bottom: 12px !important;
}
#mobSideBody > aside .panel,
#mobSideBody > aside .side-hl,
#mobSideBody > aside > .hl-fair {
  border-width: 2px !important;   /* 3px 描边在手机上太抢 */
  min-height: 0 !important;
}
/* 覆盖被后置全局规则吃掉的 420px 栅格 */
#mobSideBody .city-side-grid,
#mobSideBody .city-side-col { grid-template-columns: 1fr !important; }
/* ⚠️ `.chief-wrap` 的处理**统一挪到 §8b**（见下）——
   原来这里只写了 `#mobSideBody .chief-wrap`，把主区 .main 里那份漏掉了，
   于是「面板乱」在手机上一直没修好。别再往这里加 .chief-wrap 规则。 */
/* 立绘/图标一律不许超出抽屉宽度 —— 原图有 1024px 的，靠这一条兜住 */
#mobSideBody img,
#mobSideDrawer img { max-width: 100% !important; height: auto !important; }
#mobSideBody .side-ic { width: 20px !important; height: 20px !important; }
#mobSideBody .hsr-portrait img,
#mobSideBody .hero-portrait img { width: auto !important; }
/* 侧栏内 hover 才显示的信息，触屏上直接常显 */
#mobSideBody .hsr-portrait .hsr-up,
#mobSideBody .hero-up { opacity: 1 !important; }

/* ===================== 8c. 「🤝 人脉」抽屉（上级·班底四框）→ 单栏 ===================== */
/* 背景：作者要求把「赴上级对接 / 两办联络 / 名单风声 / 班底与表态」从「📊 属性」
   抽屉里拆出来，单独做一个贴底抽屉，按钮放「✋ 行动」旁边。搬移逻辑见
   src/mobile.js 的 moveUpper()。

   ⚠️ 这一段**必须**重写一遍 §8 那套规则，不能靠 §8 顺带生效：
      §8 的「压成一列」全部写在 `#mobSideBody` 这个 **id** 上
      （`#mobSideBody > aside > *{grid-column:auto !important; …}`），
      搬到新容器（id 变成 mobUpperBody）后这些选择器**一条都不命中**，
      而且因为全是 !important，桌面样式也盖不住 ⇒ 静默失配、面板照旧乱。
      ⇒ 用 `.mob-flat` 这个标记类做等价的一份（坑 15 的正解：换容器必带标记类）。
      标记类由 src/mobile.js:buildShell() 挂在 #mobUpperBody 上。

   为什么是"标记类"而不是再写一遍 #mobUpperBody：以后再拆第 6 个抽屉时，
   只要给容器加 class="mob-flat" 就自动获得同一套扁平化，不用再抄第三遍。 */
.mob-flat {
  display: block !important;
  grid-template-columns: none !important;
  gap: 0 !important;
  align-items: stretch !important;
  overflow-x: hidden !important;
}
.mob-flat > aside {
  display: block !important;
  grid-template-columns: none !important;
  gap: 0 !important;
  width: 100% !important;
}
.mob-flat > aside > * {
  grid-column: auto !important;
  grid-row: auto !important;      /* 清掉 ui.js:7926-7945 写上的内联 grid-row */
  width: 100% !important;
  min-width: 0 !important;
  min-height: 0 !important;
  margin-left: 0 !important;
  margin-right: 0 !important;
  margin-bottom: 12px !important;
}
.mob-flat > aside .panel,
.mob-flat > aside .side-hl,
.mob-flat > aside > .hl-fair {
  border-width: 2px !important;
  min-height: 0 !important;
}
/* 主政档搬过来的是 section.ap-zone：原样式 .ap-zone{margin-bottom:22px} 是独立选择器，
   不受祖先影响，这里只压掉它的下边距，避免和上面 12px 叠成 34px。 */
.mob-flat > aside > .ap-zone { margin-bottom: 12px !important; }
/* 覆盖被后置全局规则吃掉的 420px 栅格（同 §8） */
.mob-flat .city-side-grid,
.mob-flat .city-side-col { grid-template-columns: 1fr !important; }
/* 立绘/图标一律不许超出抽屉宽度 —— 原图有 1024px 的，靠这一条兜住 */
.mob-flat img,
#mobUpperDrawer img { max-width: 100% !important; height: auto !important; }
.mob-flat .side-ic { width: 20px !important; height: 20px !important; }
.mob-flat .hsr-portrait img,
.mob-flat .hero-portrait img { width: auto !important; }
/* 侧栏内 hover 才显示的信息，触屏上直接常显 */
.mob-flat .hsr-portrait .hsr-up,
.mob-flat .hero-up { opacity: 1 !important; }

/* 四框搬走后，属性抽屉里留一句提示，别让玩家以为东西丢了。
   文案由 src/mobile.js:moveUpper() 按**实际搬走的框**拼好写进 data-upper-hint
   （基层档只有「赴上级对接 / 名单风声」两个，写死四个会指向不存在的框）。 */
#mobSideBody[data-upper-hint]::before {
  content: attr(data-upper-hint);
  display: block;
  margin: 0 0 10px;
  padding: 7px 10px;
  border: 1px dashed var(--line);
  border-radius: 8px;
  font-size: 12px;
  line-height: 1.45;
  color: var(--ink2);
  background: rgba(0,0,0,.02);
}

/* ===================== 8b. 主政面板（一把手 .chief-wrap）→ 单栏 ===================== */
/* 为什么必须单独写这一段（别删，删了「面板乱」就复发）：
   styles.css:6029 躺着一条**无条件、无媒体查询**的规则
       .chief-wrap .city-side-grid { grid-template-columns: minmax(0, 1fr) 300px; }
   它在文件最末的「head-side rail (hsr-*)」压缩样式块里，同优先级 + 位置更晚 ⇒
   把 styles.css:4540（@media 900 的 320px）与 :4544（@media 620 的 240px）
   **两个手机断点全吃掉**。§8 那两条 `#mobSideBody .city-side-grid{1fr}` 只覆盖了
   「右栏抽屉」里的副本；而 ui.js:5244 / :7618 把 .chief-wrap 渲染进的是**主区 .main**
   —— 那一份此前无人覆盖。

   390×844 实测（修复前）：
     .chief-wrap            348px（@media 1240 的 1fr 已生效，骨架本身是单栏）
     .city-side-grid        316px → grid-template-columns 解析为 `2px 300px`
     .city-side-col         **2px 宽 / 3425px 高**（每个汉字独占一行）
     .city-attr-grid        解析为 `0px 0px`
     .city-side-foot-btns   解析为 `41.67px 41.67px` ⇒ 单按钮 42×138、文字渲染 7 行
   症状即用户截图：「下辖辖区 / 政务盘面 / 运行数据 / 定方针·细看 / 任期任务…」
   全部竖成一列，按钮文字挤成竖条，`💰库款 2.6` 被压扁。

   修法要点：**不加容器前缀**（不用 #mobSideBody），主区与抽屉一次都收干净。 */
@media (max-width: 900px) {
  /* 骨架：双栏 → 顺序块（.chief-gov 在上、.chief-right 在下） */
  body.mob-game .chief-wrap {
    display: block !important;
    grid-template-columns: none !important;
  }
  body.mob-game .chief-wrap > .chief-gov,
  body.mob-game .chief-wrap > .chief-right {
    width: 100% !important;
    min-width: 0 !important;
  }
  body.mob-game .chief-wrap > .chief-right {
    display: flex !important;
    flex-direction: column !important;
    gap: 12px !important;
  }

  /* 左内容 + 右大图：300px 定宽列在 316px 容器里没有生存空间。
     保留 grid 而不用 block —— 借它的 gap 给「按钮组 → 右栏首块」留出间距。 */
  body.mob-game .chief-wrap .city-side-grid {
    display: grid !important;
    grid-template-columns: minmax(0, 1fr) !important;
    gap: 12px !important;
  }
  body.mob-game .chief-wrap .city-side-grid > .city-side-col,
  body.mob-game .chief-wrap .city-side-grid > .city-side-right {
    width: 100% !important;
    min-width: 0 !important;
    grid-column: auto !important;   /* 顶掉 styles.css:4470 的 grid-column: 2（否则落进隐式第 2 列） */
  }
  /* styles.css:6019 给 .city-univ 留了 45px 上边距，本是桌面右栏与市区图的错位补偿；
     单栏后市区图被 `.chief-gov .city-hero{display:none}` 收起，这 45px 是纯空白 */
  body.mob-game .chief-wrap .city-side-right .city-univ { margin-top: 0 !important; min-height: 0 !important; }

  /* ⚠️ 顶掉引擎的**跨栏对齐补偿**（这一条不能删）：
     ui.js:7650 `_alignInvest()` 每次渲染都会把「招商引资」框的 inline margin-top 改成
         (当前值 + 左栏「六维气象」标题顶 − 右栏「招商引资」标题顶)
     本意是让两栏标题水平对齐 —— 那是**桌面双栏**才成立的假设。
     手机上两栏变上下堆叠：六维气象在左栏靠上（实测 y≈3015）、招商引资在右栏靠下
     （y≈3628），差值恒为负 ⇒ 实测写入 margin-top: -625.25px，把整个招商框
     （含 170px 插图）向上拽 613px，**正好压在左栏「数字政务 / 尚未定施政方针 /
     财政决算」这些文字上**，用户截图里那团「文字叠图片」就是这么来的。
     inline style 只可能被样式表里的 !important 覆盖 —— 本条即为此而设。
     （同文件 7692 那段改写 gridColumn/gridRow 的侧栏对称 hack，已被 §8 的
       `#mobSideBody > aside > * { grid-column: auto !important }` 顶掉，无需另写。） */
  body.mob-game .chief-wrap .city-side-right .city-invest { margin-top: 10px !important; }

  /* 六维气象：316px 容器两列各 ~150px，够放「名称 + 数值 + 迷你条」，
     与右栏抽屉里的观感保持一致（§8 也没把它压成单列） */
  body.mob-game .chief-wrap .city-attr-grid {
    grid-template-columns: 1fr 1fr !important;
    gap: 8px 14px !important;
  }

  /* 按钮组：保持两列，但**必须允许换行** —— styles.css:5594 给 .city-btn 钉了
     `white-space: nowrap`，320px 屏上「📋 定方针 / 细看」会直接顶出格子。 */
  body.mob-game .chief-wrap .city-side-foot-btns {
    display: grid !important;
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
    gap: 8px !important;
  }
  body.mob-game .chief-wrap .city-side-foot-btns .btn,
  body.mob-game .chief-wrap .city-side-foot-btns .city-btn {
    width: 100% !important;
    min-width: 0 !important;
    white-space: normal !important;
    overflow-wrap: anywhere;
    padding: 8px 6px !important;
    font-size: 13.5px !important;
  }

  /* 「禀赋：👥人口大县 / 🎏文旅名城」与三个小胶囊（公安口 · 纪检台账 · 举报箱）
     挤在同一行（ui.js:5104 那三个 chip 带 inline `display:inline-flex;margin-left:8px`）。
     390px 下每个胶囊只剩 ~62px，中文被折成两行。让按钮组独占一行并等分宽度。 */
  body.mob-game .chief-wrap .city-row2-btns {
    flex-direction: column !important;
    align-items: stretch !important;
    gap: 6px !important;
  }
  body.mob-game .chief-wrap .city-row2-btns > div[style*="inline-flex"] {
    margin-left: 0 !important;
    width: 100% !important;
    gap: 6px !important;
  }
  body.mob-game .chief-wrap .city-row2-btns > div[style*="inline-flex"] .chip {
    flex: 1 1 0;
    min-width: 0;
    min-height: 40px;
    padding: 6px 8px !important;
    font-size: 12.5px !important;
  }

  /* 右栏「组织架构 / 重点项目作战图」的按钮组：桌面**有意靠右**
     （styles.css:5312 `.chief-right .org-side .acts, .chief-right .proj .acts
       { justify-content: flex-end }`，因为面板本身待在窄右栏里）。
     单栏后整块缩到右侧、左边空出一大片，改成铺满并两列等分。 */
  body.mob-game .chief-wrap .chief-right .org-side .acts,
  body.mob-game .chief-wrap .chief-right .proj .acts {
    display: grid !important;
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
    justify-content: stretch !important;
    gap: 8px !important;
  }
  body.mob-game .chief-wrap .chief-right .org-side .acts > *,
  body.mob-game .chief-wrap .chief-right .proj .acts > * {
    width: 100% !important;
    min-width: 0 !important;
    white-space: normal !important;
    text-align: center !important;
  }
}

/* ===================== 9. 底部标签栏 ===================== */
#mobTabBar {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 60;                 /* 低于 .modal(80)，弹窗打开时会被盖住，符合预期 */
  display: none;
  padding: 0 0 env(safe-area-inset-bottom, 0px);
  background: var(--card);
  border-top: 1px solid var(--line);
  box-shadow: 0 -2px 12px rgba(0,0,0,.10);
}
body.mob-game #mobTabBar { display: flex; }

/* ---- 前置界面（建档 / 载入存档 / 传承兑换 / 世界观）----
   mobile.js 在这些界面上只挂 mob-game 不搬 DOM（没有 .main 可搬）。
   窄屏版式规则照样生效（作者浮动条收成 ⋯、面板内边距收紧、图片不许撑破视口），
   但下面这些「只有游戏内才有意义」的件要关掉：
     · 底部标签栏 —— 行动/属性/记事/待办此时全是空的，点了只会开出空抽屉
     · 待办汇总条 —— 没有待办
     · 底部留白   —— 是给标签栏让位的，标签栏没了就不该留 */
body.mob-pregame #mobTabBar,
body.mob-pregame #mobTodoBar { display: none !important; }
body.mob-pregame { padding-bottom: 0 !important; }
body.mob-pregame #sdLinkDock { bottom: calc(14px + env(safe-area-inset-bottom, 0px)) !important; }

/* ===================== 9b. 开局起点表单（#menuScreen）两处收窄 =====================
   作者 2026-09-27 的两条：
     ① 「展开传承兑换 / CDK 管理」的图标太大 —— 见下面 (1)
     ② 「把图中的按钮全部放在展开全部职级的里面去」—— 卡片搬移在
        assets/mobile-startlock.js 的 relocateLocked() 里做，这里只负责 (2) 的版式。

   ⚠️ 这两条都只跟「副本的开局表单」有关，全部收在 @media (max-width: 900px) 里，
      桌面端（≥901px）与开发版零影响。 */

/* (1) 传承点数条：手机上改「上下两行」+ 按钮各占一半。
   修之前（390×844 实测）：.legacybox 是 flex 单行，.lg-l 那串
   「传承点数 0 ｜ 已通结局 0/7 ｜ 历任职务 0 ｜ 已玩 0 世」挤成 3 行，
   .lg-r 只剩 109px ⇒ 两个按钮各 109×58，文字被迫折成「展开传 / 承兑换」「CDK 管 / 理」，
   那个 emoji 在折行文字旁边就显得特别大。
   改成竖排后按钮各约 148px，文字一行放得下，emoji 也就不抢眼了。 */
@media (max-width: 900px) {
  body.mob-game #menuScreen .legacybox {
    flex-direction: column; align-items: stretch; gap: 8px;
  }
  /* ★★ 2026-10 修：两个玉璋按钮必须**允许换行成两行**，不能并排挤出容器。
     实测（320/360/390，_dbg-legacy.js）：main.js:239-240 给每个 chip 写了**行内**
     `width:170px / width:160px` + `flex:none` ⇒ 上面那条 `.chip{flex:1 1 0}`
     （无 !important）被行内样式打败，两个 chip 仍按 170+8+160 = 338px 排，
     而 .lg-r 只有 232/272/302px ⇒ 分别溢出 106/66/36px，「🔑 CDK 管理」整个冲出视口。
     这两张是 1067×220 / 950×214 的玉璋按钮图（比例 4.85 / 4.44），并排缩小会把
     图上的字压扁 ⇒ 宁可换成两行、各自保持原尺寸。flex-wrap 一加，
     窄屏自动两行、430px 以上仍是一行（338 ≤ 342）。 */
  #menuScreen .legacybox .lg-r { display: flex; flex-wrap: wrap; gap: 8px; width: 100%; }
  #menuScreen .legacybox .lg-r .chip {
    flex: 0 0 auto !important;    /* 压掉行内 flex:none，按自身 width 排布 */
    min-width: 0;
    /* ⚠️ main.js:223-224 把 padding 写在**行内 style** 上（8px 16px），
       不加 !important 这条根本不生效（实测 computed 仍是 8px 16px）。
       收到 7px 10px 是为了 320px 视口下按钮里还有 107px 放得下 6 个汉字。 */
    padding: 7px 10px !important;
    font-size: 12.5px;
    white-space: nowrap;        /* 宁可缩字号也不折行 —— 折行是「看着大」的主因 */
    text-align: center;
  }
  /* ★ 图标做小：span 由 src/mobile.js 的 tidyLegacyBtns() 包上。
     ⚠️ 只调这一个 span 的 font-size，**不要**调 button 的 ——
        那会把「展开传承兑换」这几个字一起缩小。 */
  #menuScreen .legacybox .lg-r .mob-lg-ic {
    font-size: 11px;
    line-height: 1;
    margin-right: 1px;
  }
}

/* (2) 锁定职级卡片被搬进 <details> 之后，给它们一个标题与一列版式。
   ⚠️ 这里**不能**写成 `body.mob-game …`：relocateLocked() 不看视口宽度，
      窄屏/宽屏都会搬（副本本来就是手机版）。样式跟着无条件生效，
      免得宽屏下那几行字没有版式。 */
#menuScreen .mob-sl-allbox { margin-top: 10px; }
#menuScreen .mob-sl-allbox .mob-sl-allhint {
  margin: 0 0 8px;
  font-size: 12px;
  line-height: 1.5;
  font-weight: 600;
  color: var(--ink2);
}
@media (max-width: 900px) {
  /* 手机上一律单列 —— .start-post-grid 原先是 minmax(150px,1fr) 自适应，
     在 268px 宽里本来就只排得下 1 张，写死 1fr 是为了不随视口抖动 */
  #menuScreen .mob-sl-allbox .mob-sl-grid { grid-template-columns: 1fr; }
}

#mobTabBar .mtb {
  flex: 1 1 0;
  min-width: 0;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 2px;
  height: 56px;
  border: none; background: transparent;
  color: var(--ink2);
  font-family: inherit; font-size: 11px;
  cursor: pointer;
  position: relative;
}
#mobTabBar .mtb .mtb-ic { font-size: 19px; line-height: 1; }
#mobTabBar .mtb.on { color: var(--seal); font-weight: 700; }
#mobTabBar .mtb .mtb-badge {
  position: absolute; top: 6px; left: 50%; margin-left: 6px;
  min-width: 17px; height: 17px; padding: 0 4px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 9px; background: #c03a2c; color: #fff;
  font-size: 10px; font-weight: 700;
}

/* ===================== 10. 字号与触摸目标统一兜底 ===================== */
@media (max-width: 900px) {
  /* 面板内边距：桌面 .panel 是 18px 22px、.panel.event 是 24px 30px 26px。
     390px 屏上光左右内边距就吃掉 60px（15% 屏宽），正文被压成窄条。 */
  .panel { padding: 14px 14px 15px !important; margin-bottom: 12px !important; border-radius: 9px; }
  .panel.event { padding: 15px 14px 16px !important; }

  /* 正文可读性：把 11–12px 的密集小字抬到 12.5px 起 */
  .panel h3 { font-size: 16px !important; }
  .panel h3 .muted { font-size: 12px !important; }
  .muted.small { font-size: 12px !important; }
  .narr { font-size: 16px !important; line-height: 1.85 !important; }
  .narr.small { font-size: 12.5px !important; }
  .story-pair .event h3, .story-pair .ai-event h3 { font-size: 16px !important; }

  /* 可点元素统一 ≥44px */
  .chip, .btn, .actbtn, .grp-tab { min-height: 44px; }
  .chip.tiny { min-height: 34px; }
  input, select, textarea { min-height: 44px; font-size: 16px; }  /* 16px 防 iOS 自动缩放 */
}

/* ---------- 10b. 选项按钮：横排改竖排 ---------- */
/* 原结构是 flex 横排 [标签 ... 元信息]（元信息 white-space:nowrap）。
   390px 屏上实测：.opt 宽 283px，其中标签只分到 159px，
   「一、放下工作回去陪床」被挤成三行竖条 —— 这是全局点得最多的元素。
   改成上下两行：标签占满宽度，代价说明降到下一行。 */
@media (max-width: 900px) {
  .opt {
    display: flex !important;
    flex-direction: column !important;
    align-items: stretch !important;
    justify-content: flex-start !important;
    gap: 5px !important;
    padding: 13px 14px !important;
    min-height: 56px;
    font-size: 16px !important;
  }
  .opt-label { flex: 0 0 auto !important; font-size: 16.5px !important; line-height: 1.45; }
  .opt-meta {
    flex: 0 0 auto !important;
    font-size: 12.5px !important;
    white-space: normal !important;
    line-height: 1.45;
    word-break: break-word;
  }
  .opt-sub { font-size: 12.5px !important; }
  .opt-tag { align-self: flex-start; font-size: 11.5px !important; }
  /* 触屏没有 hover 位移，改成按下反馈，避免"点了没反应"的错觉 */
  .opt:hover { transform: none !important; }
  .opt:active { background: rgba(164,52,43,.10) !important; border-color: var(--seal) !important; }
  .opts { gap: 10px !important; }
}

/* ===================== 11. 弹窗全屏化 ===================== */
/* 原结构：.modal 是固定全屏遮罩（flex 居中），.modal-box 才是那个盒子。
   注意别把 width/max-width 加到 .modal 上 —— 那是遮罩层。 */
@media (max-width: 900px) {
  .modal { padding: 0 !important; align-items: flex-end !important; }
  .modal-box {
    max-width: 100% !important;
    width: 100% !important;
    max-height: 92dvh !important;
    max-height: 92vh !important;
    border-radius: 16px 16px 0 0 !important;
    border-top-width: 4px !important;
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }
  .modal-head { padding: 12px 16px !important; }
  .modal-head h3 { font-size: 16px !important; letter-spacing: 2px !important; }
  .modal-body { padding: 14px 16px !important; font-size: 16px !important; line-height: 1.9 !important; }
  /* 软键盘弹起时把聚焦的输入框滚进视野 */
  input:focus, select:focus, textarea:focus { scroll-margin-bottom: 140px; }
}

/* ===================== 12. 大屏兜底：确保不影响桌面 ===================== */
@media (min-width: 901px) {
  #mobTabBar, #mobOverlay, #mobTodoBar { display: none !important; }
  .mob-drawer { display: none !important; }
  /* 被 mobile.js 搬进抽屉的内容，桌面端由 resetDesktop() 放回原位 */
}

/* ===================== 13. 公告 / 更新日志 / 我的反馈（门户内容入口） ===================== */
/* 由 assets/mobile-feed.js 注入，对应开发版门户站 launcher.html 承载的三块内容。
   为什么单独写这一节而不是复用 .mob-drawer：
     .mob-drawer 被 `body.mob-game` 门控（只在 ≤900px 存在），而本面板在桌面宽度
     也要能用（≥901px 走居中模态）。两套形态差异太大，复用反而更绕。
   颜色全部走游戏主题变量（--paper/--card/--ink/--ink2/--ink3/--line/--seal/--gold/
   --ok/--danger），所以昼夜两版自动跟随，本节点**不需要**任何 [data-theme="dark"] 规则。 */

body.mfd-open { overflow: hidden; }

.mfd-ov {
  position: fixed; inset: 0; z-index: 319;
  background: rgba(0, 0, 0, .52);
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity .22s ease, visibility 0s linear .22s;
}
.mfd-ov.open {
  opacity: 1; visibility: visible; pointer-events: auto;
  transition: opacity .22s ease, visibility 0s;
}

.mfd {
  position: fixed; z-index: 320;
  left: 0; right: 0; bottom: 0; top: auto;
  max-height: 88dvh;
  max-height: 88vh;
  display: flex; flex-direction: column;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-base);
  border-top: 2px solid var(--seal);
  border-radius: 16px 16px 0 0;
  box-shadow: 0 -8px 32px rgba(0, 0, 0, .3);
  padding-bottom: env(safe-area-inset-bottom, 0px);
  opacity: 0; visibility: hidden; pointer-events: none;
  transform: translateY(102%);
  transition: transform .26s cubic-bezier(.22, .8, .3, 1), opacity .2s ease,
              visibility 0s linear .26s;
}
.mfd.open {
  opacity: 1; visibility: visible; pointer-events: auto;
  transform: translateY(0);
  transition: transform .26s cubic-bezier(.22, .8, .3, 1), opacity .2s ease,
              visibility 0s;
}

.mfd-hd {
  flex: 0 0 auto;
  display: flex; align-items: center; gap: 10px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--line);
  background: var(--card);
  border-radius: 16px 16px 0 0;
}
.mfd-hd b {
  flex: 1 1 auto; min-width: 0;
  font-size: 15.5px; font-weight: 700; color: var(--ink); letter-spacing: 1px;
}
.mfd-x {
  flex: 0 0 auto;
  width: 38px; height: 38px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--line); border-radius: 50%;
  background: transparent; color: var(--ink2);
  font-size: 17px; font-family: inherit; cursor: pointer;
}

.mfd-tabs {
  flex: 0 0 auto;
  display: flex; gap: 6px;
  padding: 10px 14px 0;
  border-bottom: 1px solid var(--line);
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
.mfd-t {
  flex: 0 0 auto;
  min-height: 40px; padding: 0 14px;
  margin-bottom: -1px;
  border: 1px solid transparent; border-bottom: none;
  border-radius: 8px 8px 0 0;
  background: transparent; color: var(--ink2);
  font-family: inherit; font-size: 13.5px; font-weight: 700;
  white-space: nowrap; cursor: pointer;
}
.mfd-t.on {
  color: var(--seal);
  border-color: var(--line);
  background: var(--card);
  border-bottom: 1px solid var(--card);
}

.mfd-bd {
  flex: 1 1 auto;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  padding: 14px;
}

/* ---------- 内容卡 ---------- */
.mfd-card {
  background: var(--card);
  border: 1px solid var(--line);
  border-left: 3px solid var(--line);
  border-radius: 10px;
  padding: 12px 14px;
  margin-bottom: 10px;
}
.mfd-card.pin { border-left-color: var(--seal); }
.mfd-card.imp { border-left-color: var(--gold); }

.mfd-ch {
  display: flex; align-items: center; flex-wrap: wrap; gap: 6px;
  margin-bottom: 8px;
}
.mfd-tag {
  flex: 0 0 auto;
  padding: 4px 8px;
  font-size: 11.5px; line-height: 1;
  color: var(--ink2);
  border: 1px solid var(--line); border-radius: 999px;
  background: transparent;
}
.mfd-tag.up   { color: var(--ok);     border-color: currentColor; }
.mfd-tag.ev   { color: var(--gold);   border-color: currentColor; }
.mfd-tag.warn { color: var(--danger); border-color: currentColor; }
.mfd-tag.pin  { color: var(--seal);   border-color: currentColor; }

.mfd-ct {
  flex: 1 1 auto; min-width: 0;
  font-size: 14.5px; font-weight: 700; color: var(--ink);
  overflow-wrap: anywhere;
}
.mfd-ct em { font-style: normal; color: var(--gold); }
.mfd-cd { flex: 0 0 auto; font-size: 11.5px; color: var(--ink3); }

.mfd-cb {
  font-size: 13.5px; line-height: 1.75; color: var(--ink2);
  overflow-wrap: anywhere;
}
.mfd-ul { margin: 0; padding-left: 18px; }
.mfd-ul li { margin: 3px 0; }

.mfd-dim { color: var(--ink3); font-size: 12.5px; }
.mfd-wait { margin-top: 8px; }

.mfd-reply {
  margin-top: 10px;
  padding: 9px 11px;
  border: 1px solid var(--gold);
  border-radius: 8px;
  background: rgba(160, 120, 50, .1);
  font-size: 13.5px; line-height: 1.7; color: var(--ink);
  overflow-wrap: anywhere;
}
.mfd-reply b { display: inline-block; margin-right: 6px; color: var(--gold); }
.mfd-reply > div { margin-top: 4px; }

/* ---------- 空态 / 按钮 ---------- */
.mfd-empty {
  padding: 44px 20px;
  text-align: center;
  font-size: 14px; line-height: 1.8; color: var(--ink2);
}
.mfd-empty-sub { margin-top: 6px; font-size: 12.5px; color: var(--ink3); }

.mfd-acts { display: flex; justify-content: center; gap: 10px; margin-top: 14px; }
.mfd-btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 40px; padding: 0 18px;
  border: 1px solid var(--seal); border-radius: 8px;
  background: transparent; color: var(--seal);
  font-family: inherit; font-size: 13.5px; font-weight: 700;
  text-decoration: none; cursor: pointer;
}

/* ---------- 未读小圆点 ---------- */
/* 手机端 dock 收起后只剩 ⋯（#sdLinkToggle）可见，圆点必须挂在它上面 ——
   挂在被 display:none 的兄弟按钮上等于白挂。见 mobile-feed.js dotHost()。 */
#sdLinkToggle { position: relative; }
#sdLinkFeed { position: relative; }
.mfd-dot {
  position: absolute; top: 3px; right: 3px;
  width: 9px; height: 9px;
  border-radius: 50%;
  background: #e0685c;
  box-shadow: 0 0 0 2px rgba(28, 22, 18, .94);
  pointer-events: none;
}
.mfd-dot[hidden] { display: none; }

/* ---------- ≥901px：居中模态，与底部抽屉形态解耦 ---------- */
@media (min-width: 901px) {
  .mfd {
    left: 50%; right: auto; bottom: auto; top: 50%;
    width: min(620px, 92vw);
    max-height: 78vh;
    border: 1px solid var(--line);
    border-top: 3px solid var(--seal);
    border-radius: 14px;
    padding-bottom: 0;
    transform: translate(-50%, -46%) scale(.98);
    box-shadow: 0 24px 70px rgba(0, 0, 0, .4);
  }
  .mfd.open { transform: translate(-50%, -50%) scale(1); }
  .mfd-hd { border-radius: 14px 14px 0 0; }
}

/* ===================== 9c. 起始页（#menuScreen）背景美化 —— 宣纸 · 朱印 =====================
   作者 2026-09-27 晚：「手机版要怎么美化起始页面 现在的背景不太好看」

   ■ 先说清「不好看」的成因（全部实测，不是猜的）：
     1. body 铺的 side-red.webp 是给宽屏做的「两侧云纹装饰」，按视口 100% 宽拉伸。
        手机上 #menuScreen > .menuwrap 占了 370/390px ⇒ 两边各只剩 10px 露出来，
        看着像渲染错误或被裁掉的边。**这是「不好看」的最大来源。**
     2. .menuwrap 是 3777px 高的板，background-color: var(--paper) 不透明，
        把 body 那层 --tex 纸纹和 --mount 远山全挡了 ⇒ 中段是一块死平的 #f0e3c3。
     3. .menuwrap::before 的背景图 404 —— 它写的是 url('assets/deco/menu-art-bottom.webp')，
        而该文件就在 assets/ 里，于是被解析成 assets/assets/deco/…（实测 HTTP 404）。
        开发版注释里留了证据说「先不改，直接改对路径会更糟（那图顶部烤着标题，会重影）」，
        所以这里**不碰它**，改用自己的背景层。
     4. .cover 是 aspect-ratio: 100/36 ⇒ 手机上只有 132px 高（桌面 447px），水墨画被压扁。
     5. #menuScreen::before 那三层径向渐变也白写了（z-index: 0 在不透明的 .menuwrap 下面）。

   ■ 做法（全部只动「面板本身」：质感 + 边框 + 封面比例）：
     ① body：起始页去掉 side-red（只挂 body.mob-pregame ⇒ 游戏内和桌面端都不受影响）
     ② .menuwrap：真做出宣纸质感 —— 自建颗粒 + 帘纹 + 顶部暖光 + 上下压深
     ③ 朱线用**背景层**画，不用 ::after 伪元素
        ⚠️ #menuScreen > .menuwrap 有 position:relative; z-index:1（styles.css:3932），
           伪元素会盖在 .cover 上（.cover 也是 positioned，而 ::after 在 DOM 更后面 ⇒ 后画的在上）。
           背景层永远在所有内容之下 ⇒ 朱线在封面上自动被挡住，天然不打架。
     ④ 封面加高到 100/50 + 一条朱砂压边
     ⑤ 长页面分节：给三处「组首行」加小标题（锚点用 :has(#f_xxx)，见下面的注释）

   ⚠️ 全部收在 @media (max-width: 900px) 内 ⇒ 桌面端（≥901px）走开发版原样，零影响。
      这是本项目的既定约定（本文件第 8 行），别把规则挪到断点外面。
   ================================================================================== */

@media (max-width: 900px) {

  /* (1) 起始页去掉两侧被切碎的红云纹。
     ⚠️ 只挂 body.mob-pregame：这个类**只在起始页**有（src/mobile.js:665 加、:675 摘），
        游戏内只有 body.mob-game ⇒ 游戏里的红装饰一个像素没动。
     这里把 body 的背景栈从 6 层缩到 2 层（开发版是
     暗角 + 两个径向 + --mount 远山 + side-red + --tex）——
     --mount 定位在 bottom center / 100%×300px，而面板把视口盖满了，它本来也看不见。 */
  body.mob-pregame {
    background-image:
      radial-gradient(ellipse at center, transparent 52%, rgba(60,45,20,.10) 100%),
      var(--tex);
    background-size: auto, 180px 180px;
    background-repeat: no-repeat, repeat;
    background-position: center, center;
    background-attachment: fixed, fixed;
  }

  /* (2) 面板：宣纸质感。
     --mob-tex 是自建颗粒 —— 开发版的 --tex 只有 opacity .05，铺在 3700px 的长页面上
     几乎看不出颗粒，这里提到 .075 才压得住「死平」。
     --mob-lian 是「帘纹」：宣纸抄纸时竹帘留下的横向细纹，7px 一道、alpha .045。
     用 repeating-linear-gradient 画，**不需要新增任何图片素材**。
     顶部暖光用 background-size: 100% 1400px 按**文档顶部**定位，而不是
     background-attachment: fixed —— fixed 在 iOS Safari 上对超长滚动元素有已知的
     抖动/被忽略问题，而这层只需要「开头亮、越往下越匀」，静态定位的语义反而更对。 */
  #menuScreen .menuwrap {
    --mob-tex: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='p'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23p)' opacity='0.075'/%3E%3C/svg%3E");
    --mob-lian: repeating-linear-gradient(180deg,
        rgba(154,123,63,.045) 0 1px,
        rgba(154,123,63,0) 1px 7px);
    /* 左右各一条朱线，坐在面板内边距（18px）与表单框之间。
       渐变里一律用**硬停**（同一个位置写两个色标），别写透明→色的过渡 ——
       那会让浏览器按 rgba(0,0,0,0) 插值，朱砂会渗出一圈灰边。 */
    --mob-frame: linear-gradient(90deg,
        rgba(164,52,43,0) 0 9px,
        rgba(164,52,43,.22) 9px 10.5px,
        rgba(164,52,43,0) 10.5px calc(100% - 10.5px),
        rgba(164,52,43,.22) calc(100% - 10.5px) calc(100% - 9px),
        rgba(164,52,43,0) calc(100% - 9px));
    background-color: var(--paper);
    background-image:
      var(--mob-tex),
      var(--mob-lian),
      var(--mob-frame),
      radial-gradient(ellipse 120% 100% at 50% 0%, rgba(154,123,63,.15), rgba(154,123,63,0) 62%),
      linear-gradient(180deg, #f8efdb 0%, var(--paper) 4%, var(--paper) 96%, #e8d8b4 100%);
    background-size: 160px 160px, 100% 100%, 100% 100%, 100% 1400px, 100% 100%;
    background-repeat: repeat, repeat, no-repeat, no-repeat, no-repeat;
    background-position: 0 0, 0 0, 0 0, top center, 0 0;
    border: 1px solid rgba(164,52,43,.26);
    outline: 1px solid rgba(154,123,63,.22);
    outline-offset: 3px;
    box-shadow: 0 1px 3px rgba(60,45,20,.06), 0 14px 34px rgba(60,45,20,.13),
                inset 0 0 0 1px rgba(255,255,255,.5);
  }

  /* (3) 封面：加高 + 朱砂压边。
     .cover 是 aspect-ratio: 100/36（styles.css:193）⇒ 390px 下只有 132px 高，
     水墨画连标题一起被压扁。改成 100/50 ⇒ 约 185px，画面有呼吸。
     ⚠️ 必须写 #menuScreen .cover（1 个 id）才盖得住 .menuwrap .cover（2 个类）；
        而且 styles.css:7437 有一条 `#menuScreen .cover { border-bottom-color: transparent }`
        和本条同为 (1,1,0) —— 靠「本文件在 styles.css 之后加载」取胜，别把这段挪到前面去。 */
  #menuScreen .cover {
    aspect-ratio: 100 / 50;
    border-bottom: 2px solid rgba(164,52,43,.50);
  }

  /* (4) 长页面分节：给三处「组首行」加一个小标题。
     ★ 锚点用 :has(#f_xxx)，不用 :nth-child(n)。
       实测（2026-09-27，用 _probe-formrows2.js 把 .createform 里每个 select 的
       每个取值都走一遍）：当前版本这 15 行**不会增删**，所以 :nth-child 眼下也能用。
       但两个理由还是选 :has()：
       ① 语义是「这一行是哪个字段」，跟行的增删无关；:nth-child 是**位置耦合** ——
          上游哪天让某行条件渲染（比如「未婚」时不显示「配偶职业」），
          它后面所有序号会**静默**错位，分节标题跑到别的组头上，
          而且只在特定选项组合下才错，极难复现；
       ② 成本为零。:has() 在本项目是既有依赖（开发版 styles.css 的
          .modal-box:has(.ofc-card) 就在用），不是本轮新引入的兼容性要求。
     ⚠️ .row 是 display:flex / flex-direction:column（styles.css:161），
       所以 ::before 天然是「独占一行的 flex 子项」，不需要额外定宽。 */
  #menuScreen .createform > .row:has(#f_name)::before,
  #menuScreen .createform > .row:has(#f_track)::before,
  #menuScreen .createform > .row:has(#f_marry)::before {
    display: block;
    margin: 14px 0 0;
    padding: 5px 10px 5px 9px;
    border-left: 3px solid rgba(164,52,43,.55);
    border-radius: 2px;
    background: linear-gradient(90deg, rgba(164,52,43,.09), rgba(164,52,43,0) 62%);
    color: #8a2b23;
    font-size: 12.5px;
    font-weight: 800;
    letter-spacing: 2.5px;
    line-height: 1.5;
  }
  #menuScreen .createform > .row:has(#f_name)::before { content: '壹 · 人物'; }
  #menuScreen .createform > .row:has(#f_track)::before { content: '贰 · 出身与起点'; }
  #menuScreen .createform > .row:has(#f_marry)::before { content: '叁 · 家庭与开局'; }
}

/* ===================== 9d. 迷你顶栏里的账号药丸：收成圆头像 + 挪到主题按钮下方 =====================
   【问题】竖屏往下滚之后，迷你顶栏里的主按钮「结束本季 ▸」被右上角的账号药丸整块盖住。
           实测（390×844）：按钮 x=222..315, y=6..50；药丸 x=185..334, y=11..49
           ⇒ 重叠 93×38，而药丸 z-index:60 > 迷你栏 z-index:50
           ⇒ 按钮**完全不可见、也完全不可点**（不是「有点挡」，是整颗没了）。
           滚动扫描：390 宽下 37/40 个采样格都在遮，375 宽下 40/40 全遮。
   【成因】#acctBadge 是 position:fixed / z-index:60 的 **<body> 直接子元素**，不占位、浮在最上层；
           迷你栏 .top 是 position:sticky / z-index:50。
           开发版当初给迷你栏写了 padding: 6px 54px 6px 10px —— 右侧那 54px
           只让开了 36px 的 #themeBtn（fixed right:14px），**漏了这个宽 149px 的药丸**。
   【为什么不改用「给迷你栏加 padding-right 让位」】要让开药丸得加到 205px，
           会把「县政府办科」这类职位名挤到换行，**反而把迷你栏撑高**
           （实测 360/320 宽下迷你栏本来就是换行双行、高 105px）。放大 padding 是负收益。
   【本方案】迷你态把药丸收成 36px 圆头像（藏掉用户名），挪到 #themeBtn 正下方：
             right 与 #themeBtn 同为 14px ⇒ x=340..376，与主题按钮**逐像素对齐成一列**；
             尺寸也同为 36×36、同一根 border:1px solid var(--line)、同一个 var(--shadow)
             ⇒ 视觉上就是主题按钮的「下一个同族控件」，不是新造一个东西。
             top:58px 紧贴迷你栏下沿（390/375 实测栏高 57px），
             y=58..94 与按钮 y=6..50 **完全不相交**。
   【为什么 top 用硬编码 58px、不引 JS 测栏高】迷你栏高度随宽度变化：
             390/375 单行 = 57px；360/320 内容换行 = 105px。
             但 360/320 下按钮已经换到**第二行左侧**（x=31..124, y=54..98），
             本来就与药丸不相交、**本来就没有遮挡**；
             而 58px 恰好落在双行栏第二行的**右侧空白处**（实测该处无任何内容，
             第二行只有左侧那颗按钮），视觉上仍然成立。
             ⇒ 一个常量同时覆盖四种宽度，不必为它引入 JS 测高 + CSS 变量 + resize 监听。
   【为什么顺便挪 #acctPop】原设计面板 top:56px 是「紧贴徽章下沿」（原徽章底 49）。
             头像下移到 94 之后，面板 56px 会**反盖住头像** —— 点开面板反而看不见自己点的东西。
             挪到 100px（头像底 94 + 6px 间隙）恢复「面板挂在徽章下方」的原设计关系。
   ⚠️ 全部收在 body.mob-game.mob-topmini 下 ⇒ 只在「游戏内 + 已滚进迷你态」生效；
      起始页（body.mob-pregame，那时 #gameScreen 的 .top 根本不存在）与
      桌面端（≥901px）**零影响**。
   ⚠️ 样式必须落在这里，不能改 mobile.html —— mobile.html 是 sync-from-dev.js 的
      生成产物，里面的 .acctbadge / .acctpop 定义下次同步会被整段冲掉。
   ⚠️ .acctbadge 的 transition 只写了 border-color / color，不含 width/height/top/right
      ⇒ 尺寸与位置是**瞬时**切换，跟迷你栏本身的瞬时收起是一致的，不会「栏已经收了、
      头像还在飞」。刻意不加 transition。 */
@media (max-width: 900px) {
  body.mob-game.mob-topmini .acctbadge {
    right: 14px;            /* 与 #themeBtn 同列（both right:14px） */
    top: 58px;              /* 紧贴迷你栏下沿（390/375 实测栏高 57px） */
    width: 36px;            /* 与 #themeBtn 同尺寸，border-box 下内容区 34×34 */
    height: 36px;
    padding: 0;             /* 原为 0 12px 0 5px（药丸形态） */
    border-radius: 50%;     /* 原为 22px */
    max-width: none;        /* 原为 160px */
  }
  /* 只留头像。.abn 一 display:none，flex 的 gap:9px 也随之塌陷，不会留下 9px 空档 */
  body.mob-game.mob-topmini .acctbadge .abn { display: none !important; }
  body.mob-game.mob-topmini .acctbadge .abv {
    width: 34px; height: 34px; flex: 0 0 34px; font-size: 15px;
  }
  /* 面板回到「紧贴徽章下沿」：头像底 = 58 + 36 = 94 ⇒ 面板 100 */
  body.mob-game.mob-topmini #acctPop { top: 100px; }
}

/* ===================== 9e. 迷你态下「系统」按钮被收走 → 保留一个入口 =====================
   现象：scrollY>240 切进迷你顶栏后，顶栏里「系统」按钮（data-act=sysset，
        里面能进 AI 对话设置 / 音乐 / 主题）被 §1 里那条
        body.mob-game.mob-topmini .t-btns .btn:not(.primary){display:none}
        整颗收走 ⇒ 玩家在页面中部/下部滚动时就**够不着**系统设置（含 AI 大模型设置），
        得先滚回页面顶部才找得到那个按钮 —— 一个真实的入口缺口。
   做法：迷你态里把它「保留可见 + 收形态 + 让位」，做成 44×44 单字符圆钮，
        钉在右侧竖列「主题按钮 → 账号头像 → 系统按钮」的最下面一格，
        点它打开的系统设置浮层（同 z-index）浮在按钮之上，与右列互不遮挡。
   四宽度实测（滚动进迷你态后）：迷你栏 390/375 高 57、360/320 高 105。
     390/375：主题 top:0（36×36，底 36）· 头像 top:44（36×36，底 80）
               · 系统 top:84（44×44，底 128，正好收在 105px 下沿之内）
     360/320：顶栏换行双行高 105，右列空白处同 top 值仍成立。
   ★ 系统按钮定 **44×44**（不是 32）：:1090 的 `.btn{min-height:44px}`（iOS 触控下限，
     没带 !important）会把任何 <44px 的按钮顶到 44px。32px 圆钮在 iOS 上点不准，
     与其硬压不如顺应它 —— 44×44 本身也是 iOS 推荐的最小可点区。
   ★ 收形态时与右列邻居同族：#themeBtn 与 .acctbadge 都是 36px、1px 边框、
     box-sizing:border-box；系统按钮定 44px，border-radius:50%、同一根 border/shadow。
   ★ 账号头像从 §9d 的 top:58 顶到 **44**：给 44px 的系统按钮腾出 84..128 的第三格，
     且头像 44..80 与系统按钮 84..128 竖向错落 4px，视觉上是一列「圆钮堆」。
   ★ #acctPop 从 100 顺到 **134**：头像底 80 + 系统按钮底 128 ⇒ 面板 134，
     避开两格圆钮；134 在 105px 迷你栏外，点面板时页面已滚远，不影响。
   ★ 全部收在 body.mob-game.mob-topmini 下（≤900 块），桌面端与非迷你态零影响。
   ★ 320 命中 ≤340 专属块 :587（`.t-btns .btn{width:100%!important}` 把按钮撑满），
     但本条 position:fixed + right:14 + top:84 + width:44 全部 !important，
     在 ≤340 块里按**文件后段**优先级压住它（§9e 在 :587 之后）⇒ 一个 ≤900 块搞定四宽度。
   ===================================================================================== */
@media (max-width: 900px) {
  /* 覆盖 §1 的 .t-btns .btn:not(.primary){display:none}，只针对系统按钮。
     ★ position:fixed 让 right/top 生效（原 .btn 是 static，right 对它无效）；
       min/max-width + box-sizing:border-box 锁死 44×44，压住 :587 的 width:100%!important。 */
  body.mob-game.mob-topmini .t-btns .btn[data-act="sysset"] {
    display: inline-flex !important;
    position: fixed !important;
    box-sizing: border-box !important;
    right: 14px !important; top: 92px !important;
    width: 44px !important; height: 44px !important;
    min-width: 44px !important; max-width: 44px !important;
    padding: 0 !important; margin: 0 !important;
    border-radius: 50% !important;
    align-items: center !important; justify-content: center !important;
    font-size: 18px !important; line-height: 1 !important;
    overflow: hidden !important;
    background: var(--paper, #fff) !important;
    border: 1px solid var(--line, #d8cdb8) !important;
    box-shadow: var(--shadow, 0 2px 6px rgba(0,0,0,.12)) !important;
    z-index: 60 !important;
  }
  /* 原「系统」两字放不进 44px 圆钮，靠 ::after 出 ⚙ 表达含义 */
  body.mob-game.mob-topmini .t-btns .btn[data-act="sysset"]::after {
    content: "⚙" !important;
    display: block;
    font-size: 18px !important; line-height: 1 !important;
  }
  body.mob-game.mob-topmini .t-btns .btn[data-act="sysset"]::before {
    content: none !important;
  }
  /* 账号头像让位：主题 14..50，系统 92..136。
     top:56 ⇒ y=56..92：与主题间隙 6px、与系统正好相接 0px。
     390/375 迷你栏 57、360/320 迷你栏 105，头像 56..92 在两种栏高内都收得住。 */
  body.mob-game.mob-topmini .acctbadge { top: 56px !important; }
  /* 面板顺延：系统按钮底 136 ⇒ 面板 142 */
  body.mob-game.mob-topmini #acctPop { top: 142px !important; }
}

/* ===================== 14. AI 对话设置层的触控兜底（assets/mobile-ai.js） =====================
   背景（2026-09-30）：新增「玩家自备 API Key」设置弹窗后，做了一次**多档位**触控体检
   （tools/_probe-panels-multistate.js：37 个职级/岗位档 × 90 个面板）。本层自己产出的
   两个元素明显低于基准，已在此修掉：

     .mob-ai-keylink  「去哪里拿 Key」三个平台链接 —— 内联 `padding:2px 6px; font-size:12px`
                      （mobile-ai.js:105-107）⇒ 实测 **18px**。这三个链接恰恰是
                      「拿不到 Key 就玩不下去」的唯一出口，18px 在手机上点不准。
     .mob-ai-eye      Key 输入框右侧的 👁 显示/隐藏钮 —— 内联 `padding:2px 6px; font-size:16px`
                      ⇒ 实测 **29px**。它与输入框同排，而 §10 已把 input 抬到 44px ⇒ 同高即可。
   两者都写在**内联 style** 上，内联优先级高于外部样式表 ⇒ 这里必须用 !important 才压得住。

   ---------------------------------------------------------------------------
   ★★ 顺带查清的一件事（**没改，留证据**）：为什么全库面板里的 .chip 都只有 36px，
      而不是 §10 :1090 写的 44px ——

        styles.css  .modal-body .chip, .modal-body .btn, … { min-height: 36px }   ← 特异度 (0,2,0)
        mobile.css  §10 :1090  .chip, .btn, .actbtn, .grp-tab { min-height: 44px } ← 特异度 (0,1,0)

      **特异度高的赢，与文件先后无关**。所以 §10 那条「可点元素统一 ≥44px」在**所有弹窗内**
      都被 styles.css 的 .modal-body 规则静默盖掉了 —— 不是 .chip.tiny 的问题
      （.chip.tiny 的 34px 是 §10 :1091 的**明确设计**，另一回事）。

      为什么不顺手用 !important 把它抬到 44px：
        那会把**全部约 90 个面板**的按钮从 36px 抬到 44px，是全局版式变更，
        而这些面板的密集排版正是按 36px 调出来的；作者对 .chip.tiny 明确接受过 34px，
        说明「密集处宁可小一点」是有意取舍。⇒ 这是**产品决策**，不该由适配层单方面翻掉。
        留证据在此，等作者定性（要改就是 §10 :1090 加 !important，改完必须重跑
        _probe-panels-multistate.js 看 90 个面板有没有被撑破）。

   ⚠ 本节所有规则收在 @media (max-width: 900px) 内 ⇒ 桌面端零影响（本文件既定约定，见第 8 行）。 */
@media (max-width: 900px) {
  .mob-ai-keylink {
    min-height: 44px !important;
    padding: 0 10px !important;
    display: inline-flex !important;
    align-items: center !important;
    vertical-align: middle;
  }
  /* Key 输入框右侧的 👁 显示/隐藏钮：内联 `padding:2px 6px; font-size:16px` ⇒ 实测 29px。
     它和输入框同排，而 §10 已把 input 抬到 min-height:44px ⇒ 这里给同高即可对齐，不会撑破行。 */
  .mob-ai-eye {
    min-height: 44px !important;
    min-width: 44px !important;
    padding: 0 !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
  }
}

/* ==========================================================================
   §15. 把 §10 的「可点元素 ≥44px」在**弹窗内**抢回来（2026-09-30）
   ---------------------------------------------------------------------------
   起因：§14 的注释里留了个「没改，留证据」的问题 —— 全库弹窗里的 .chip 只有 36px。
        本轮把「门槛面板探针」（tools/_probe-panels-gated.js）写出来后，19 个
        **需要运行时状态才能打开**的新功能面板终于能量了，结果 12 个面板的主操作按钮
        低于 44px，且全部集中在**本轮新增的功能**上：
          省域调剂 39px · 省对中央 39px · 出口升级 39px · 转移支付 39px · 批复申请 39px
          纪委立案 36px · 分管口 30px · 国企党委会表决 34px · 纪委定档 34px
          供应链多元化 34px · 工程定址 34px · 对台谈判 34px
        这些恰恰是「点不准就玩不下去」的按钮。

   根因（层叠，不是笔误）：
        styles.css  :7526  .modal-body .chip, .modal-body .btn, .modal-body .opt,
                           .modal-body .actbtn { font-size:14.5px !important;
                                                 font-weight:700 !important;
                                                 min-height:36px }        ← 特异度 (0,2,0)
        mobile.css  §10     .chip, .btn, .actbtn, .grp-tab { min-height:44px } ← 特异度 (0,1,0)

      **特异度高者胜，与文件先后无关** ⇒ §10 那条在**所有弹窗内**被静默击穿。

   ★ 为什么现在改、而 §14 当时选择不改：
     §14 的判断是「这是产品决策，适配层不该单方面翻掉约 90 个面板的密集排版」——
     这个顾虑仍然成立，所以这里做了**两处收敛**：
       ① 用 `:not(.tiny)` 把作者**明确写死的** .chip.tiny（§10 :1091 的 34px）排除在外，
          密集小标签维持原样；
       ② 规则仍收在 @media (max-width: 900px) 内 ⇒ 桌面端零影响。
     改动只抬 .chip/.btn/.actbtn/.opt/.grp-tab 的 **min-height**（不改字号/内边距/字重），
     弹窗正文本身可滚动（.modal-body{overflow:auto}）⇒ 撑高只表现为多滚一点，
     不会截断内容。改完必须重跑：
       tools/_probe-panels-multistate.js（90 面板，看有没有被撑破）
       tools/_probe-panels-gated.js     （19 个门槛面板，看触控是否达标）
     要回退只需删掉本节。

   ---------------------------------------------------------------------------
   ★★ 改完复量（390px）：门槛面板 19/19 能开、**0 呈现问题**；
      90 面板多档位探针 **0 呈现问题**（撑破/出屏/横滚/页溢出全 0）；
      触控 <44px 的**可点**元素从 45 个面板降到 24 个。

   ★★★ 但**没有**、也**不应该**做到「全站 44px」—— 剩下的 <44px 全部能溯源到
        **作者显式写下的** min-height，一共三层（用 tools/_diag-btn-cascade.js
        逐条量出来的，不是读文件猜的）：

        ① mobile.css §10 :1091   .chip.tiny { min-height: 34px }
           作者明确要的「密集小标签」——本轮 24 个面板里绝大多数是这一类。
        ② styles.css :3784       .modal-box:has(.ofc-card) .acts .chip { min-height: 40px }
           特异度 (0,3,0)。含 .ofc-card 的弹窗里，.acts 内的 chip 定成 40px。
           实测 showPolbureau 的「➕ 临时加议题」= 40px，走的正是这条。
        ③ portfoliomatch.js :279 .narr.scport .chip { … min-height: 0 !important … }
           分管口面板（sc-desk 的 .narr.scport 扁平分区风）的紧凑按钮 —— 连
           `!important` 都写了，是本适配层**碰不动也不该碰**的。

       判定标准：**写了具体数值 / 写了 !important ⇒ 有意；没写数值、只是顺手带的
       默认值 ⇒ 意外**。本节的 36px 属于后者（同一块里字号/字重都写了 !important，
       唯独高度没写），所以修；上面三层属于前者，所以留。
       结论：改完后再量，**没有一个 <44px 是层叠事故**。

   ★ 复量工具（本次新增，都只读）：
       tools/_probe-panels-gated.js    19 个「需要运行时状态才开」的面板，逐个武装+量测
       tools/_diag-btn-cascade.js      查某个按钮的 min-height 到底是谁定的（带特异度）
     注意 _probe-* 量触控时的口径：**只量真的可点元素**（button / a[href] / [data-act] /
     [role=button] / 表单控件）。一开始把 `.chip` 全算进去，于是 showPolbureau 的
     「委员名单」纯标签（`<span class="chip tiny">姓名 职务 派系</span>`，无 data-act）
     也被算成触控目标，产出「45 个面板按钮偏小」这种吓人但无用的读数。
   ========================================================================== */
@media (max-width: 900px) {
  /* `:not(.tiny)` 让特异度升到 (0,3,0)，稳压 styles.css 的 (0,2,0)，
     同时把 .chip.tiny 留给 §10 :1091 的 34px。 */
  .modal-body .chip:not(.tiny),
  .modal-body .btn:not(.tiny),
  .modal-body .actbtn:not(.tiny),
  .modal-body .opt:not(.tiny),
  .modal-body .grp-tab:not(.tiny) {
    min-height: 44px;
  }
}
