/* ============================================================================
   public/css/mobile-fix.css —— 手机端可用性重构层
   ----------------------------------------------------------------------------
   🔴 用户反馈（原话，两次）：
      「现在手机页面就是PC自适应的，但是很多按钮和电脑上的效果，
        在手机上并不能好好的操作，就比如看图的那个弹窗，
        在手机上弹开就找不到关闭的地方，所以手机版有必要全部重构页面。」
      「等于手机端，你要重构页面，使他更适合手机界面操作，
        毕竟PC端自适应手机端，还是不等于手机端，操作起来不顺手。」

   ★★ 设计原则（这条线必须守住）
   ------------------------------------------------------------
   ⚠️ 用户明确要求：「只改手机端，不要动电脑端。」
   ⇒ 本文件里【所有】规则都必须包在 @media (max-width: 860px) 里，
      唯一的例外是"默认隐藏"类规则（新元素在桌面端本来就不该出现）。
   ⇒ tools/mobile-probe.mjs 里有一条断言专门守这个：
      无保护的规则只能有 .mb-close{display:none} 一条。

   ★ "PC 自适应"和"手机端"到底差在哪（这是重构的依据，不是审美）
   ------------------------------------------------------------
   ① 手指 vs 鼠标：触控目标要 ≥44px，且要有间距。"小一点好看"在手机上=点不中。
   ② 视口会变：手机地址栏伸缩 ⇒ 100vh 按最大高度算，底部内容被截。
      必须用 dvh；并且要避让刘海（safe-area-inset-*）。
   ③ 键盘会顶上来：点输入框时软键盘占掉半屏，且 iOS 在字号<16px 时会自动放大页面。
   ④ 没有 hover：所有"悬停才出现"的操作（编辑/删除/下载）在手机上等于不存在。
   ⑤ 滚动方向单一：横向滚动条/宽表格在手机上很难操作。
   ⑥ 底栏是常驻的：任何贴底的东西（提示/抽屉/悬浮按钮）都会被它压住。

   下面每一节对应上面一条，不是零散补丁。
   ============================================================================ */

/* ★★ v2.677：手机专用关闭按钮（.mb-close）在【桌面端必须隐藏】
   ------------------------------------------------------------
   ⚠️ 这条不能漏：它是 DOM 里真实存在的按钮（不是 JS 动态加的），
      不给 display:none 的话，桌面端图片左上/右上角会多出一个黑圆 ✕，
      而桌面那个 ✕ 本来就在右栏标题行、位置是对的 ⇒ 变成两个关闭按钮。
   ⚠️ 放在 @media 外面（无保护）：保证任何屏宽下默认都是隐藏的，
      再由手机断点显式打开。反过来写（默认显示、手机才隐藏）
      一旦断点没命中就会露出多余按钮。
   ⚠️ 这条【不是】改桌面端：桌面端本来就没有这个元素，
      把默认态钉成 none ⇒ 桌面端渲染结果与改动前完全一致。 */
.mb-close { display: none; }

/* ============================================================================
   一、★ 触控目标（原则①：手指 vs 鼠标）
   ----------------------------------------------------------------------------
   🔴 问题：电脑上"小一点更精致"的做法，在手机上是"点不中"。
      Apple HIG 要求 ≥44×44pt，Material 要求 ≥48dp。
      现有代码里 30~34px 的按钮不少（关闭、图标按钮、表格操作）。
   ⚠️ 为什么用 min-height/min-width 而不是 height/width：
      有些按钮是"文字 + padding"撑出来的，写死 height 会把文字挤掉。
      min-* 只在不够大时才生效，本来就大的不受影响。
   ⚠️ 用 :where() 把优先级压到 0：
      这样页面自己的 .btn / .icon-btn 规则仍然能覆盖它
      （我们只兜底，不抢页面的控制权）。
   ⚠️ 不碰 input/textarea —— 它们有字号规则（见第三节）。
   ============================================================================ */
@media (max-width: 860px) {
  :where(.btn, .icon-btn, .btn-ghost, .btn-primary, button, [role="button"], a.tag, .tag) {
    min-height: 44px;
  }
  :where(.icon-btn) {
    /* 只有图标没文字的按钮，宽度也要够 */
    min-width: 44px;
  }
  /* ⚠️ 表格里的行内小按钮（编辑/删除）不强制 44 —— 
     一行里塞不下会撑破表格、反而更难点。
     改成给它们更大的【上下内边距】+ 行高，靠行高凑够触控面积。 */
  :where(table) :where(.btn, button) {
    min-height: 36px;
    padding-top: .35rem;
    padding-bottom: .35rem;
  }

  /* ★★ v2.680：数字步进器（▲▼）必须【豁免】上面那条 44px ——
     ------------------------------------------------------------
     🔴 用户反馈（原话）：「滑动条后面的上下翻的三角，变形了」
     ★ 根因：这两个步进器是【上下两格拼成和输入框等高】的设计：
        · .count-steps / .dur-steps 是 flex-direction:column，宽只有 1.15rem（18px）
        · 每格 height: 1.025rem（16.4px），两格 = 32.8px = 输入框高度
        上面那条 min-height:44px 把【每一格】拉到 44px
        ⇒ 两格 88px，比整行（32.8px）还高 ⇒ 被挤压
        ⇒ 18px 宽 × 88px 高的格子里，▲ 就被拉成细长条 = 变形。
     ★ 修法：
        ① 显式 min-height:0 把兜底那条请掉。
           ⚠️ 兜底那条是用 :where() 写的，优先级为 0 ——
              这里只需写【同一条 @media 内、优先级更高】的规则就能压过，
              不需要 !important（用了它以后会被更强的 !important 顶掉，
              而且会盖住页面自己的意图）。
        ② 顺手把格子做到手指能点：22px 一格 × 2 = 44px，
           输入框同步提到 44px ⇒ 既好点，又不变形。
     ⚠️ 只改手机端（用户要求）；桌面端这些尺寸一个都不动。 */
  :where(.count-step, .dur-step) {
    min-height: 0;      /* 请掉上面那条 44px 兜底 */
    height: 22px;       /* 一格 22 ⇒ 两格 44，正好是触控下限 */
    font-size: .62rem;  /* 原来 .5rem 太小，手机上几乎看不见三角 */
  }
  :where(.dur-num, .count-num) {
    height: 44px;       /* 和两格拼起来等高，不然拼不齐会错位 */
  }
}

/* ============================================================================
   二、★ 底栏冲突 + 安全区（原则⑥：底栏常驻）
   ----------------------------------------------------------------------------
   🔴 问题：
      · #toast-host 是 position:fixed; bottom:2rem ——
        手机底栏高 56px + 安全区 ⇒ 提示被底栏压住看不见（实测存在）。
      · 抽屉（.drawer）贴底，也会被底栏压住。
      · 悬浮按钮（回到顶部）同理。
   ★ 修法：手机端把提示【抬到底栏上方】，抽屉底部留出底栏高度。
   ⚠️ 为什么提示不改成"显示在顶部"：
      顶部有页面自己的吸顶栏，会打架；抬到底栏上方最稳，
      而且用户视线本来就在下方（刚点完按钮）。
   ============================================================================ */
@media (max-width: 860px) {
  /* 提示：抬到底栏 + 安全区之上 */
  #toast-host {
    bottom: calc(72px + env(safe-area-inset-bottom));
    /* ⚠️ 窄屏上提示别贴边（原来只有 padding，长文案会顶到屏幕边） */
    left: 1rem;
    right: 1rem;
    transform: none;
    align-items: center;
  }
  .toast {
    /* 长文案要能换行，不能横向溢出 */
    max-width: 100%;
    word-break: break-word;
  }

  /* 抽屉：底部留出底栏，否则最下面那个按钮点不到 */
  .drawer {
    padding-bottom: calc(56px + env(safe-area-inset-bottom));
  }

  /* 回到顶部 / 悬浮按钮：抬到底栏上方 */
  .back-top,
  .fab {
    bottom: calc(72px + env(safe-area-inset-bottom)) !important;
  }
}

/* ============================================================================
   三、★ 输入框与键盘（原则③：键盘会顶上来）
   ----------------------------------------------------------------------------
   🔴 问题（两个，都是手机上最烦的）：
      ① iOS Safari 在【输入框字号 < 16px】时，聚焦会自动放大整个页面，
         而且放大后不会自动缩回来 —— 用户只能手动捏合。
         现有代码大量用 .8rem / .85rem（≈12.8~13.6px）⇒ 必触发。
      ② 软键盘弹起占掉半屏，输入框被挡住，而页面不滚动 ⇒
         用户在"看不见自己打字"的状态下输入。
   ★ 修法：
      ① 手机端把输入类元素字号统一提到 16px（只为不触发缩放，
         视觉上大一点点是可接受的代价）。
      ② 键盘问题 CSS 解决不了（要 JS），见 mobile-ux.js 的
         "输入框聚焦时滚进可视区"。
   ⚠️ 只改 font-size，不动 padding（动 padding 会改布局高度，连锁反应大）。
   ============================================================================ */
@media (max-width: 860px) {
  /* ⚠️ 必须带 !important —— 这里踩过一个坑：
     我第一版用 :where(input, textarea, select) 兜底，而 :where() 优先级是 0，
     于是【页面自己写的 font-size】全都把它压掉了
     （例：brand.html 的 .bd-f input { font-size: .86rem }）。
     ⇒ 结果是"兜底写了但没用"：手机上点输入框照样触发 iOS 放大整页。
     ⚠️ 这条是全文件唯一必须用 !important 的【兜底】场景：
        目标是"任何输入框都不能小于 16px"，而页面各自写了字号，
        不 !important 就压不过它们。这不是抢控制权，是纠一个手机上的硬性限制。
     ⚠️ 16px 是分界值：15.9px 也会触发 iOS 缩放。 */
  input, textarea, select {
    font-size: 16px !important;
  }
  /* ⚠️ 例外：勾选框/单选框不是文本输入，不需要 16px，
     给它们 16px 反而会撑歪一排。 */
  :where(input[type="checkbox"], input[type="radio"]) {
    font-size: inherit !important;
    min-width: 22px;
    min-height: 22px;
  }
}

/* ============================================================================
   十二、品牌资产页（/brand）：窄屏会横向溢出
   ----------------------------------------------------------------------------
   🔴 问题（读代码发现，不靠猜）：
      public/brand.html 里
        .bd-grid { grid-template-columns: repeat(auto-fill, minmax(21rem, 1fr)); }
      21rem = 336px —— 这是"卡片最小宽度"。
      ⚠️ 窄屏（320px 机型）内容区只有约 290px，
         minmax 的最小值比容器还宽 ⇒ 网格被迫顶宽页面
         ⇒ 整页能左右拖（手机上最难受的一种表现）。
      ⚠️ 就算 390px 屏，内容区约 358px，也只放得下 1 列 ——
         那 minmax 这个写法在手机上没有任何好处，只会带来溢出风险。
   ★ 修法：手机端强制 1 列（minmax 的最小值去掉）。
   ⚠️ 只改手机端；电脑端那个"自动填充多列"不变。
   ============================================================================ */
@media (max-width: 860px) {
  .bd-grid {
    /* ⚠️ 用 1fr 而不是 minmax(0, 1fr)：这里只要一列，
        写 minmax 反而多一层心算，不如直白 */
    grid-template-columns: 1fr;
  }
}

/* ============================================================================
   四、★ 没有 hover（原则④：悬停才出现的操作等于不存在）
   ----------------------------------------------------------------------------
   🔴 问题：不少地方把"编辑/删除/下载"做成 hover 才显示
      （典型写法：.card .ops { opacity:0 } .card:hover .ops { opacity:1 }）。
      手机上【永远没有 hover】⇒ 那些按钮用户根本看不到，以为没这功能。
   ★ 修法：手机端强制把这类操作显示出来。
   ⚠️ 这里用"类名匹配"而不是逐个列：因为这类写法散落多处，
      逐个列一定会漏。匹配 ops/actions/tools/hover- 这些常见命名。
   ⚠️ 只把 opacity/visibility/transform 归位，不动 display ——
      有些元素是 display:none 的（那是真的不该显示），
      强行 display 出来会露出一堆不该有的东西。
   ============================================================================ */
@media (max-width: 860px) {
  :where([class*="ops"], [class*="actions"], [class*="hover-"]) {
    opacity: 1 !important;
    visibility: visible !important;
    transform: none !important;
  }
}

/* ============================================================================
   五、★ 横向溢出（原则⑤：滚动方向单一）
   ----------------------------------------------------------------------------
   🔴 问题：宽表格 / 固定宽度的卡片在手机上会把【整个页面】顶宽，
      于是整页可以左右拖 —— 这是"不顺手"最直观的来源。
   ★ 修法：
      · 页面级禁止横向滚动（兜底，防止某一处溢出毁掉整页）
      · 表格自己横向滚动（宽表在手机上就该横滚，而不是压缩）
   ⚠️ 为什么给 img/video 加 max-width:100%：
      忘了设宽度的图片会把容器顶宽，这是最常见的溢出源。
   ⚠️ 不用 overflow-x:hidden 一刀切在 body 上：
      那会把"本该能横滚的表格"也锁死。所以分开处理。
   ============================================================================ */
@media (max-width: 860px) {
  html, body {
    max-width: 100%;
    overflow-x: hidden;
  }
  :where(img, video, canvas, iframe) {
    max-width: 100%;
  }
  /* 表格：自己横滚，不顶宽页面 */
  :where(table) {
    display: block;
    width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    white-space: nowrap;
  }
  /* 长英文/链接不换行会顶宽（中文会自动换，英文不会） */
  :where(p, div, span, td, li) {
    overflow-wrap: break-word;
  }
}

/* ============================================================================
   六、看图弹窗（v2.675 起，修的是"根本没法用"的硬伤）
   ----------------------------------------------------------------------------
   ⚠️ 断点用 860px：和 style.css 里"侧栏变底部抽屉"的断点【一致】——
      不一致会出现"抽屉已经形成、但规则还没生效"的错位区间。
   ============================================================================ */
@media (max-width: 860px) {

  /* ---- 6.0 ★★ 控件层级：必须压过图片 ----
     ⚠️ 图片是 z-index:30，而 .lb-float（工具条）/.lb-arrow（箭头）
        【压根没设】、.lb-close 只设了 2 ⇒ 三个都压不过图片。
        桌面端图片周围有留白、控件露在外面 ⇒ 鼠标点得到，所以看不出来；
        手机端图片贴满 ⇒ 全被盖住 ⇒ 「找不到关闭按钮」。
     ★ 这就是用户反馈的根因。
     ⚠️ 只在手机断点里修（用户要求不动电脑端）。 */
  .lb-close,
  .lb-float,
  .lb-arrow {
    z-index: 40;
  }
  .img-lb .lb-close { z-index: 41; }

  /* ---- 6.1 铺满视口，用 dvh 而不是 vh（原则②）----
     ⚠️ 手机浏览器地址栏会伸缩：100vh 按【最大高度】算，
        地址栏显示时底部会被截掉一截 —— 正好是工具栏那个位置。
        dvh 跟着实际可视高度变 ⇒ 不再被截。 */
  .img-lb {
    width: 100vw;
    height: 100vh;      /* 老浏览器兜底 */
    height: 100dvh;     /* 现代浏览器：按实际可视高度 */
    border-radius: 0;
    overscroll-behavior: none;
  }

  /* ---- 6.2 ★★ 手机专用关闭按钮（.mb-close）----
     ------------------------------------------------------------
     🔴 v2.675 那版把桌面 .lb-close 改成 position:fixed 想浮到视口右上，
        结果【没生效】—— 因为 .modal-mask 上有 backdrop-filter: blur(4px)，
        它会给后代创建【包含块】，里面 position:fixed 就不再相对视口了。
        （表现：用户手机上还是看不到关闭按钮。）
     ★ v2.677 换成：在图片容器【内部】放一个真实按钮（.mb-close），
        用 position:absolute 相对 .img-lb-stage —— 这个舞台本来就是
        position:relative，不用依赖任何"巧妙"的东西。
     ⚠️ 样式要"不可能看不见"：
        原来是 background:#f6f7fb + color:#6b7280 的浅色小圆，
        压在浅色图片上几乎看不出来。改成【深色实底 + 白 ✕ + 阴影】——
        这是所有看图器的常规做法（微信/淘宝都这样）。
     ⚠️ 52px 比 44 下限再大一点：这是唯一的出口，不能再小。
     ⚠️ z-index 45 > 图片的 30 ⇒ 图放大也不盖它。 */
  .mb-close {
    display: flex;
    position: absolute;
    top: max(0.5rem, env(safe-area-inset-top));
    right: max(0.5rem, env(safe-area-inset-right));
    z-index: 45;
    width: 52px;
    height: 52px;
    align-items: center;
    justify-content: center;
    font-size: 1.45rem;
    font-weight: 700;
    line-height: 1;
    color: #fff;
    background: rgba(17, 24, 39, .82);
    border: 2px solid rgba(255, 255, 255, .9);
    border-radius: 50%;
    box-shadow: 0 6px 22px rgba(0, 0, 0, .38);
    cursor: pointer;
    padding: 0;
    -webkit-tap-highlight-color: transparent;
  }
  .mb-close:active { transform: scale(.94); background: rgba(17, 24, 39, .95); }

  /* ---- 6.3 ★★ 图不能再"占满剩余高度"----
     ------------------------------------------------------------
     🔴 用户反馈（原话）：「这个页面的这个图，就太大」
     ★ 原因：.img-lb-stage 是 flex:1 1 auto —— 图会把【抽屉之外的
        全部高度】占满（手机上接近整屏），而抽屉还要吃 46vh，
        两个加起来超过 100dvh ⇒ 一起被压/被截。
     ★ 修法：给舞台一个明确的高度上限，让"图 + 抽屉"必定装得下。
     ⚠️ min-height:0 是关键：flex 子项默认 min-height:auto，
        不压到 0 的话它会撑破容器（图仍然溢出）。
     ⚠️ 图必须 contain（不是 cover）—— cover 会把画面裁掉，
        看图器裁图是硬伤。 */
  .img-lb-stage {
    flex: 1 1 auto;
    min-height: 0;
    max-height: 54dvh;
    overflow: hidden;
    padding: .3rem .4rem .5rem;
  }
  .img-lb-stage > img {
    max-width: 100%;
    max-height: 100%;
    width: auto;
    height: auto;
    object-fit: contain;
  }

  /* ---- 6.4 底部抽屉：给安全区留位置 ---- */
  .lbm-side {
    max-height: 46vh;
    padding-bottom: env(safe-area-inset-bottom);
    -webkit-overflow-scrolling: touch;      /* iOS 惯性滚动 */
  }
  /* ⚠️ 桌面那个 .lb-close 在手机上【藏掉】——
     它原来在侧栏标题行里，现在有了 .mb-close 压在图右上角，
     两个 ✕ 会让人不知道该点哪个。 */
  .img-lb .lb-close { display: none; }
  .lbm-side-head { padding-right: 1rem; }

  /* ---- 6.5 工具条：别贴到抽屉边缘 ----
     ⚠️ 原来的 .lb-float 是 bottom:.9rem，手机上台面变矮后
        它离抽屉很近，拇指容易误触到"旋转"而不是"关闭"。 */
  .lb-float {
    bottom: .7rem;
    flex-wrap: wrap;
    justify-content: center;
    max-width: calc(100vw - 1.6rem);
  }
  .lb-tool { min-width: 40px; min-height: 40px; }

  /* ---- 6.6 左右箭头：别压住图片正中 ----
     ⚠️ 手机上 44px 的圆按钮占的画面比例很大，往里收一点。 */
  .lb-arrow { width: 40px; height: 40px; font-size: 1.2rem; }
  .lb-arrow.prev { left: .35rem; }
  .lb-arrow.next { right: .35rem; }
}

/* ============================================================================
   九、★★★ 电商专区的工具格子（「错位」的那一处）
   ----------------------------------------------------------------------------
   🔴 用户反馈（原话）：「电商专区，还有错位。」

   ★ 定位过程（我查了 15 处都不是，最后靠"渲染模板 + CSS 双向对"才找到）：
      渲染：public/ecommerce.html  render() 里
            '<button class="z-chip">'
              （缩略图容器 + 名称两个 span）
            '</button>'
      CSS ：public/ecommerce.html
            .zone-chips {
              display: grid !important;
              grid-template-columns: repeat(6, minmax(0, 1fr)) !important;
            }
      ⚠️ 以上是【定位当时】的结构与列数（v2.681 修的时候是 6 列）。
         v2.699 改成卡片式后：列数变 5、缩略图容器叫 .zc-thumb。
         ⇒ 这段留作"当初为什么会错位"的档案，不要拿它当现状。

   ★ 根因（两条叠加）：
      ① 那个 6 列 grid 是给【桌面端左栏】算的 ——
         作者注释里明写「chip 固定 6 列 ⇒ 每列约 96px」，
         并且它【没有 @media 保护】（所有屏宽都生效）。
      ② 手机上 .zone-split 变成一列 ⇒ .zone-chips 跟着【变成整页宽】，
         但列数还是 6 ⇒ 每列被拉到整页宽的 1/6。
      ⇒ 手机上：390 ÷ 6 = 65px 一列，
         减去 padding（约 10px）+ 图标（约 17px）+ gap
         ⇒ 文字只剩【约 34px】，而「商品白底图」5 个字 ≈ 56px
         ⇒ 放不下就换行、被裁 ⇒ 看起来就是"错位"。

   ★ 修法：手机端把 chip 从「6 列窄格子」改成
      「2 列表格式」——图标在左、文字在右（手机原生的列表样式）。
      ⚠️ 2 列而不是 1 列：22 个工具排 1 列要滚 22 行，2 列 11 行更省事，
         而且 2 列时每个 chip 仍有约 150px 宽、文字可用约 110px
         ⇒ 6 个字的「一键细节特写」也放得下。
      ⚠️ 用 !important 覆盖：页面那条写了 !important，不跟一层压不过去。
         这是【唯一】必须用 !important 的地方（对方也是 !important）。
      ⚠️ 只在手机端生效（用户要求不动电脑端）。
   ============================================================================ */
@media (max-width: 860px) {
  /* ============================================================================
     ★★★ v2.704：顶栏搜索框在手机上的处理
     ----------------------------------------------------------------------------
     🔴 手机上顶栏本来就挤（搜索框 + 积分 chip + 头像 + 主题按钮）。
        实测宽度账：375px 屏 − 汉堡 36 − 标题（可压） − 搜索 150
        − 积分 chip ~80 − 头像 ~36 − 主题 36 − 各 gap ≈ 已经超了。
     ★ 处理办法（两条，都不动电脑端）：
        ① 隐藏【主题切换按钮】—— 手机上有系统深色模式，
           那个按钮本来也是全站最不常用的（而且侧栏里也能切）
        ② 搜索框宽度放到 100~130px，并允许压缩（min-width:0 必须给，
           否则 flex 项不会收缩，会把头像挤出去）
     ⚠️ 为什么不做成"点图标才展开"：
        那要多一个"打开 → 输 → 关"的步骤，而手机上搜索本来就不方便
        （本项目在"藏起来的操作等于不存在"上踩过：hover-only 那批）。
     ⚠️ 结果面板要【铺满整屏宽】—— 搜索框只有 120px，
        面板跟着 120px 宽的话结果名一行只能放 3 个字，完全没法看。
     ============================================================================ */
  .theme-btn { display: none !important; }
  .tb-search {
    flex: 0 1 auto; width: 128px; min-width: 0; margin: 0 0.25rem;
  }
  .tb-search-input {
    height: 32px; font-size: 0.78rem;
    padding: 0 1.7rem 0 1.7rem;
    /* ⚠️ 16px 是防 iOS 聚焦缩放的阈值 —— 但搜索框只有 128px 宽，
       16px 字号会让可见字数少到没法用。
       ⇒ 这里【故意不遵守 16px】，代价是 iOS 上聚焦时页面会放大一下。
          权衡：搜索框是"看一眼结果就走"的控件，缩放一下能忍；
          而输入框小到看不见字是【用不了】。 */
  }
  .tb-search-ico { left: 0.55rem; font-size: 0.72rem; }
  .tb-sr {
    /* 铺满整屏宽：左边界从视口算，而不是跟着输入框 */
    left: auto; right: auto;
    width: calc(100vw - 1.6rem);
    /* 把面板推到屏幕中间（输入框位置不固定，用 fixed 定位更稳） */
    position: fixed;
    left: 0.8rem; right: 0.8rem;
    top: 56px;                     /* 顶栏高度 */
    max-height: 62vh;
  }

  /* ★★ v2.701：手机端 3 列 —— 但按钮还是【紧凑 chip】（不是卡片）
     ------------------------------------------------------------
     🔴 演变过程（写清楚，免得以后有人再改回去）：
        · v2.681 手机改成 2 列 —— 那时 chip 是"图标+文字"横排的，
          2 列能让文字有空间（6 列时每列 65px、文字只剩 34px ⇒ 错位）。
        · v2.699 我误把它改成"竖排卡片"（跟电脑端一起改错了）。
        · v2.701 电脑端退回紧凑 chip（6 列），手机端【保持 3 列】：
          横排 chip 在手机上 3 列时每列约 108px，
          emoji + 4~5 个中文刚好放得下，而且比 2 列少占一行高度。
     ⚠️ 这两条带 !important —— 电脑端那两条也是 !important，
        不加压不过（!important 之间比的是先后，电脑端那条在后面）。 */
  .zone-chips {
    display: grid !important;
    grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
    gap: .4rem !important;
  }
  .zone-chips .z-chip {
    /* ★★ v2.701：手机端也回到【横排紧凑 chip】
       ------------------------------------------------------------
       🔴 我上一轮把它改成了"竖排居中（卡片式）"——
          用户明确纠正：「你这个直接把下面的小按钮改大了，
          我还交代你，不要动按钮的高度。」
       ★ 现在改成横向（emoji 左、文字右）+ 左对齐，和电脑端形态一致。
       ⚠️ 手机上 min-height 保持 44px（触控下限）——
          这不是"把按钮改大"，而是手机端必要的可点面积；
          电脑端仍是 30px（那里是鼠标）。 */
    width: 100%;
    min-width: 0;
    min-height: 44px;                 /* 触控下限 */
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    padding: .45rem .5rem;
    gap: .35rem;
    font-size: .78rem;
    text-align: left;
  }
  /* ⚠️ v2.701：这里原来有一条 .zc-thumb 的尺寸规则。
       小按钮不再有缩略图（用户选的是"小按钮不要缩略图"），
       那条规则永远不会命中 ⇒ 删掉。
       ⚠️ 分类大卡的缩略图是 .zl-thumb（另一套类名），不受影响。 */
  /* ⚠️ 名字必须能换行 —— 原来是 white-space:nowrap + 省略号，
       手机窄格子里会变成「商品多视图...」（用户明确说过不要藏字）。 */
  .zone-chips .z-chip .zc-name {
    white-space: normal;              /* 允许换行 */
    overflow: hidden;
    text-overflow: clip;
    font-size: .74rem;
    line-height: 1.25;
    /* 最多两行，再长也不撑破格子 */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    /* ★ v2.701：左对齐（卡片式那版是居中，现在退回 chip 形态 ⇒ 也要左对齐）
       ⚠️ 不写 width:100% —— 横向 chip 里文字只需占剩余宽度，
          写 100% 会把 emoji 挤到换行或压扁。 */
    text-align: left;
  }
  /* ⚠️ 手机端【不跨列】—— 电脑端 v2.701 恢复了 [data-long] 跨 2 列
        （6 列时 ≥7 字放不下），但手机上只有 3 列：
        跨 2 列会占掉 2/3 行，一行只剩 1 个短按钮的位置，很难看。
        ⇒ 手机端让长名【折两行】而不是跨列（上面的 zc-name 已经允许两行）。
       ⚠️ 这条必须带 !important：电脑端那条是 [data-long]{span 2}，
          优先级算下来手机端这条要 !important 才压得住。 */
  .zone-chips .z-chip[data-long] {
    grid-column: auto !important;
  }
}

/* ============================================================================
   十、★★★ 生成页的「立即生成」按钮：改成真正的吸底操作条
   ----------------------------------------------------------------------------
   🔴 用户反馈（原话）：「等于手机端，你要重构页面，使他更适合手机界面操作，
                        毕竟PC端自适应手机端，还是不等于手机端，操作起来不顺手。」

   ★ 问题（我实测代码确认的）：
      style.css 里 .studio-side-foot 写的是 position: sticky; bottom: 0，
      注释说「按钮贴在屏幕底部，滚动时始终可点」——
      但它的祖先 .studio-side 是 overflow-y: auto（见 studio-split.css），
      而【祖先有 overflow 时 sticky 不再相对视口】，
      只在那个滚动容器内部生效 ⇒ 手机上是整页滚动 ⇒ 按钮跟着表单一起滚走。
      表现：填完表单还要往下滚很久才够得到「立即生成」。

   ★ 修法：手机端改成 position: fixed 贴底（手机 App 的标准做法：主操作永远在手边）。
      ⚠️ fixed 会脱离文档流 ⇒ 必须给表单留出等高的下边距，
         否则最后一个字段会被按钮压住（那时用户就填不完表单了）。
      ⚠️ 要躲开底部的 tab 栏（56px + 安全区）——
         否则「立即生成」和「首页/灵感/作图」叠在一起，两个都点不准。
      ⚠️ 用 --mob-vh（mobile-ux.js 写进 CSS 变量的真实可视高度）：
         软键盘弹起时底栏会被顶飞，用 fixed + bottom 会跑到键盘下面。
         ⚠️ 但 --mob-vh 在【键盘没弹起时】等于视口高度，
            用它算 bottom 反而会把按钮顶到屏幕中间 ⇒
            所以这里只用它做【上限保护】，不用它定位。
      ⚠️ 只用 max()/calc() 保证有安全区时不贴到系统手势条。
   ⚠️ 我第一版按 body[data-page="image"] 这种写法挑页面 —— 写错了：
      项目里根本没有 data-page="image"（图片创作页是 index.html，
      它的 body 上没有 data-page）。实际能查到的值是
      ad-open / ad / assets / brand / combo / earnings / ecommerce …
      ⇒ 按【页面名】挑会静默失效（选择器不匹配，什么都不发生）。
      ⇒ 改成按【元素】挑：谁有 .studio-side-foot 就吸谁的底。
         这样以后新加生成页也自动生效，不用回来改这里。
   ============================================================================ */
@media (max-width: 860px) {
  /* 生成类页面的底部操作区（各页类名不同，见 studio-split.css / combo.html / ad-open.html）
     ⚠️ .ao-bar 是开业物料页（ad-open.html）的 —— 它【没有】吸底，
        是一行普通 flex（.ao-bar { display:flex; margin-top:1.1rem }），
        手机上「开始生成」在表单最下面，要滚到底才够得到。 */
  .studio-side-foot,
  .pn-foot,
  .ao-bar {
    position: fixed;
    left: 0;
    right: 0;
    /* ⚠️ 56px 是 tab 栏高度（见 style.css 的 .tabbar 段）——
       写死是因为 tab 栏本身就是固定高度；它改了这里要跟着改。
       ⚠️ 没登录时没有 tab 栏（login 页不挂底栏），但登录页也没有生成表单。 */
    bottom: calc(56px + env(safe-area-inset-bottom));
    margin-top: 0;
    padding: .5rem .75rem;
    border-top: 1px solid var(--line);
    background: rgba(255, 255, 255, .97);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    box-shadow: 0 -4px 18px rgba(31, 38, 135, .08);
    z-index: 30;                      /* 高于内容、低于弹窗（弹窗是 80 / 3000） */
    /* ⚠️ 横向别溢出（fixed + left/right:0 已经铺满，这里防止内部元素顶出去） */
    box-sizing: border-box;
  }
  /* 主按钮撑满、够高（拇指容易点） */
  .studio-side-foot .btn,
  .pn-foot .btn,
  .ao-bar .btn {
    min-height: 48px;
    font-size: .95rem;
  }
  /* ⚠️ 给内容留出和吸底条等高的空间 ——
     不留的话最后一个字段会被它永久压住，用户填不完表单。 */
  .studio-side,
  .pn-body,
  .ao-wrap {
    padding-bottom: calc(84px + env(safe-area-inset-bottom));
  }
}

/* ============================================================================
   十一、作品广场（/assets）：卡片操作按钮太小
   ----------------------------------------------------------------------------
   🔴 用户要求：「重构页面，使他更适合手机界面操作」
   ★ 这一页的网格【本来就是响应式的】（Tailwind 的
      grid-cols-2 md:grid-cols-3 lg:grid-cols-4），手机上已经是 2 列 ——
      比生成页做得好，所以【不重排网格】。
   ★ 真正的手机端问题是卡片里的操作按钮：
      内联 padding:.26rem .58rem + font-size:.7rem ⇒ 约 22px 高、字约 11px。
      鼠标勉强能点，手指点不中；而且「下载 / 同款 / 删除」三个挨在一起
      ⇒ 很容易想点下载却点到删除（那是不可撤销的）。
   ★ 修法：加大到 34px + 拉开间距。
     ⚠️ 为什么不给 44px：卡片只有约 170px 宽，三个 44px 按钮会折成两行，
        卡片高度翻倍、一屏看不到几张 ⇒ 那反而更难用。
        34px 比 22px 好得多，加上间距后误触概率大幅下降。
     ⚠️ 也不改网格列数：2 列是手机上看图集最合适的密度（一屏 4~6 张）。
   ⚠️ 全部包在 @media 里，电脑端不动。
   ============================================================================ */
@media (max-width: 860px) {
  /* 卡片里的操作按钮（assets.js 用的是内联 padding/font-size，
     所以这里用 min-height 兜底高度） */
  #assets-grid .btn,
  #assets-loading .btn {
    min-height: 34px;
    padding: .34rem .6rem;
    font-size: .74rem;
    /* ⚠️ 原来是普通 button，行高会让文字在 34px 里偏上 ——
       用 flex 居中，和电脑端观感一致 */
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  /* 按钮组：拉开间距（原来约 5px，两个按钮几乎贴在一起） */
  #assets-grid .btn + .btn {
    margin-left: .12rem;
  }
  /* 卡片里的说明文字行高统一（原来是 height:2.4em + overflow:hidden，
     行高不一致时会露出半行字，看着像被切了） */
  #assets-grid p {
    line-height: 1.45;
  }
}

/* ============================================================================
   十二、★ 断点交叠兜底（我核对后发现的隐患）
   ----------------------------------------------------------------------------
   ⚠️ 重要事实：本项目【在 style.css 里已经有一套手机样式】，
      写在 @media (max-width: 768px)（L2433 起，约 127 行），包含
      横向滚动兜底 / 触控目标 42px / 输入框 16px / 表格可横滚 /
      媒体 max-width / 弹窗全屏 / 安全区 / 生成按钮吸底。
      ⇒ 那部分是作者写的、已经存在的，本文件不再重复。
      （我一开始重复了"横向滚动"和"媒体 max-width"两条 —— 无副作用，
        但属于多余，知情后不再往上加同类规则。）

   ⚠️ 隐患：断点不一致。
      底栏（.tabbar / body.has-tabbar）和上面那套手机样式都在 768px，
      而本文件在 860px。
      ⇒ 768~860px 区间会出现「本文件的手机样式生效了、但底栏还没出现」：
         我给内容留了 56px 底栏空间，而屏幕上根本没有底栏
         ⇒ 页面底部多出一块空白。

   ★ 兜底：底栏不存在时，就不要留那块空间、吸底条也贴到底。
      ⚠️ 用 :has() 判断（Chrome 105+/Safari 15.4+ 支持）。
         不支持的浏览器会保留那点空白 ——
         比"内容被底栏压住"好得多（压住是功能性问题，空白只是不好看）。
      ⚠️ 为什么本文件不干脆也改成 768px：
         860px 覆盖"大屏手机横屏 + 小平板"，那些设备同样需要这些修正
         （尤其输入框 16px 和主操作吸底）；
         而 768px 那套是【布局层面重排】，不该在横屏平板上触发。
         两者职责不同，断点不同是有意的。
   ============================================================================ */
@media (max-width: 860px) {
  body.has-tabbar:not(:has(#tabbar)) .studio-side,
  body.has-tabbar:not(:has(#tabbar)) .pn-body,
  body.has-tabbar:not(:has(#tabbar)) .ao-wrap {
    padding-bottom: 0;
  }
  body.has-tabbar:not(:has(#tabbar)) .studio-side-foot,
  body.has-tabbar:not(:has(#tabbar)) .pn-foot,
  body.has-tabbar:not(:has(#tabbar)) .ao-bar {
    bottom: env(safe-area-inset-bottom);
  }
}

/* ============================================================================
   十三、★★★ 手机端错位兜底（用户实测：「这个按钮到处飘，个人中心错位成啥样了」）
   ----------------------------------------------------------------------------
   🔴 用户给了三张 375px 截图，我写了浏览器探针在真机尺寸(375x812)上【量几何】，
      量出来的是这两类问题（都是硬数据，不是看出来的）：

     ① 吸底操作条（.pn-foot / .studio-side-foot / .ao-bar）和正文重叠
        实测：电商页 .pn-foot 和 textarea.fld 竖直重叠 46px
        ⚠️ 根因：这几条是 position:fixed（见上面第十节），会脱离文档流 ⇒
           必须靠【给内容留底边距】来避免压住最后一个字段。
           第十节给 .pn-body / .studio-side / .ao-wrap 留了 84px，
           但那只覆盖【那三个类名】—— 别的容器（比如各页自己的滚动区、
           或者类名不同的页面）就没留 ⇒ 照样被压住。
        ★ 兜底：直接给 body 留出"底栏 + 吸底条"的总高度。
          取 56px（底栏）+ 84px（吸底条）+ 安全区 ≈ 148px。
          ⚠️ 只在【真的挂了底栏】时留（:has 判断），否则没底栏的页面
             会白白多出一大块空白（第十一节记过这个隐患）。

     ② 个人中心（/me）横向能滑：文档宽 381 > 视口 375
        实测出界元素：span#mc-vip-badge「👑 会员」右边界 381（正好超 6px）
        ★ 修法：给这类页面的根容器加 overflow-x: clip 兜底 + 让徽标可收缩。
          ⚠️ 用 clip 而不是 hidden：hidden 会把横向滚动容器也一起锁死
             （有的页面靠它横滑，比如电商页的品类条）。
          ⚠️ 同时给 .mc-* 的头部行允许换行（flex-wrap），
             从源头避免"一行塞不下就顶出去"。

   ⚠️ 为什么写在这里而不是去改各页的自己样式：
      本次症状横跨【电商页 + 个人中心 + 配音页】三个页面，
      逐个页面改会漏（用户下次换一页又会遇到同样的问题）。
      这里是"手机端兜底"文件，职责就是兜这类共性问题。
   ============================================================================ */
@media (max-width: 860px) {
  /* ① 给正文留出底部空间：底栏(56) + 吸底操作条(84) + 安全区 */
  body.has-tabbar:has(#tabbar) {
    padding-bottom: calc(148px + env(safe-area-inset-bottom));
  }
  /* ⚠️ 只给【滚动容器】补，不给 body 里每个 div 补 ——
     补多了会把本来正常的间距撑开。 */
  body.has-tabbar:has(#tabbar) .pn-body,
  body.has-tabbar:has(#tabbar) .studio-side,
  body.has-tabbar:has(#tabbar) .ao-wrap {
    padding-bottom: calc(100px + env(safe-area-inset-bottom));
  }

  /* ② 横向溢出兜底（个人中心实测超 6px ⇒ 整页能横滑）
     ★★★ v2.902：还发现了一个【真正的根因】—— body 有 8px 默认外边距
     ----------------------------------------------------------------------------
     🔴 探针在 /me 页量到的硬数据：
          bodyRectTop = 8           ← body 距视口顶 8px（浏览器默认 margin）
          底栏 bottom  = 825 = 812(视口) + 13
        而电商页 bodyRectTop = 0（那边 body 的 margin 被正确重置了）⇒ 底栏正常(812)
        ⇒ **同一个底栏在两个页面上差 13px，根因是"body 的 margin 有没有被重置"**。
     ⚠️ 为什么会这样：项目里有两套 tailwind 精简版
        （tailwind-lite.css 有 `body{margin:0}`，而 me.html 引的是
          tailwind-subset.css），不同页面引的 CSS 不一样
        ⇒ body 的 margin 在部分页面上没被清掉。
        ⚠️ 这类"不同页面引不同 CSS 导致同一元素表现不一致"最难查 ——
           因为它不是"某个页面写错了"，而是"某个页面少引了一个重置"。
     ★ 兜底：在手机端直接把 html/body 的 margin 归零（!important）。
        这是"必须成立的事实"（body 不该有默认外边距），用 !important 合适。*/
  html, body {
    margin: 0 !important;
    padding-left: 0 !important;
    padding-right: 0 !important;
    overflow-x: clip;
  }
  /* 徽标/标签这类"一行里最后一个元素"最容易顶出去 ⇒ 允许收缩 + 不换行挤爆 */
  #mc-vip-badge,
  .mc-vip-badge,
  .mc-head,
  .mc-tabs {
    min-width: 0;
    max-width: 100%;
  }
  .mc-head { flex-wrap: wrap; }
  .mc-tabs { flex-wrap: wrap; }

  /* ③ 吸底操作条：压在底栏上面，且【不许超出视口右边】
     ----------------------------------------------------------------------------
     🔴 用户实测（图片创作页）原话：
          「生成按钮也跑到作品广场的最下面了，填完参数和设置后根本看不到生成按钮，
            要一直拉到页面的最底部才可以。」
     ★ 这是【主操作够不到】—— 比错位严重得多：用户完不成任务。
     ⚠️ 根因（项目注释里已经记过一次同类问题）：
        第十节把 .studio-side-foot 改成了 position:fixed，
        但它的祖先 .studio-side 是 overflow-y:auto ——
        **祖先有 overflow 时，fixed 的包含块会变成那个祖先**，
        于是"贴视口底"变成"贴那个滚动容器的底" ⇒ 按钮跟着内容一起滚走了。
        （style.css 里 .studio-side-foot 原本写 sticky 也是同一个原因失效的。）
     ★ 修法：双保险
        ① 把 .foot-actions 也纳入吸底（index.html 的按钮在它里面，
           而它原来是【不在】那批选择器里的 —— 少一个类名就少一处生效）
        ② 显式给祖先 .studio-side 关掉 overflow（手机端它本来就不该自己滚，
           整页滚动才是手机的正确交互）—— 这是让 fixed 真正相对视口的【关键一步】。
     ⚠️ 为什么敢关 .studio-side 的 overflow：
        手机端"面板内部滚动"是桌面思维（鼠标滚轮）；
        手指在嵌套滚动区里滑动，很容易变成滚动内层而不是整页，
        用户会觉得"页面卡住了滑不动"。整页滚动才是手机的标准做法。 */
  .studio-side-foot,
  .pn-foot,
  .ao-bar {
    position: fixed !important;
    left: 0 !important;
    right: auto !important;
    width: 100% !important;
    max-width: 100vw !important;
    bottom: calc(56px + env(safe-area-inset-bottom)) !important;
    box-sizing: border-box !important;
    z-index: 30 !important;
  }
  /* ★★★ v2.904：⚠️⚠️ 不要再把 .foot-actions 加进上面那条规则！
     ----------------------------------------------------------------------------
     🔴 我 v2.903 加了它，用户立刻实测到「提取文案按钮，还是压住了文本框」。
     ★ 原因：**电商页原本就做对了**，它自己写着：
          .pn-foot { flex: 0 0 auto; ... }   /* 注释：在 flex 列里固定占位，不滚动、不遮挡 */
          body.has-tabbar .pn-foot { margin-bottom: calc(56px + env(safe-area-inset-bottom)); }
        ⇒ 页面自己的方案是"操作条在 flex 列里占位 + 整条往上抬 56px"，
          【不需要】再变成 position:fixed。
        而我那条全局 `.foot-actions { position: fixed }` 把它从 .pn-foot 里
        【抬了出来】变成独立吸底条 ⇒ 覆盖在「核心卖点」那一行的按钮上 ⇒ 压住文本框。
     ⚠️ 教训：给"多个页面共用的类名"加全局规则，等于【替那些已经做对的页面改行为】。
        加之前必须先确认：别的页面是不是已经用【另一种方式】解决过同一个问题
        （这里是电商页用 flex 占位 + margin-bottom 解决的）。
     ⇒ 所以 .foot-actions 只在【它真的没被处理】的页面里生效 ——
        这里用 :not() 把它从已有吸底父容器里排除掉。 */
  .studio-side-foot .foot-actions,
  .pn-foot .foot-actions,
  .ao-bar .foot-actions {
    position: static !important;
    width: auto !important;
    bottom: auto !important;
    z-index: auto !important;
  }
  /* ★★★ 关键一步：让祖先不再创建"滚动包含块"，fixed 才会真正相对视口 */
  .studio-side,
  .pn-body,
  .ao-wrap {
    overflow: visible !important;
    max-height: none !important;
  }
  /* ⚠️ 原来的内层滚动容器也要放开（它是 .studio-side-scroll）——
     不放开的话内容依然被关在那个盒子里。 */
  .studio-side-scroll {
    overflow: visible !important;
    max-height: none !important;
  }

  /* ④ ★★★ 底栏：把位置和宽度【钉死】
     ----------------------------------------------------------------------------
     🔴 探针实测（375x812）：
          /me 页面 innerWidth = 381 > clientWidth = 375
          ⇒ 文档比视口宽 6px ⇒ 底栏（fixed，left:0;right:0）被撑到 381 宽
          ⇒ 它相对【那个更宽的包含块】定位 ⇒ 实测 bottom = 825 > 视口 812
          ⇒ **底栏有 13px 在屏幕外**（用户看到的"错位"就有它一份）。
     ⚠️ 为什么 html/body 上的 overflow-x: clip 救不了它（我试过，没用）：
         fixed 元素的包含块是【视口】而不是 html/body，
         所以给 html/body 加裁剪【影响不到 fixed 元素】。
         ⇒ 必须直接约束底栏自己。
     ⚠️ 为什么用 !important：
         底栏的 left/right/bottom 在 style.css 里定义，
         而本文件是【懒加载注入】的（挂到 head 末尾，本来靠顺序赢），
         但实测被别的规则盖过（18 张样式表里有 admin-fill.css 等）。
         这里的目的是"钉死一个必须成立的事实"（底栏永远贴视口底、永远不超宽），
         属于兜底性质 ⇒ 用 !important 是合适的，不是偷懒。 */
  #tabbar,
  .tabbar {
    left: 0 !important;
    right: auto !important;          /* ⚠️ 不用 right:0 —— 见下面的宽度说明 */
    bottom: 0 !important;
    /* ★★★ 关键：宽度写 100%【而不是靠 left:0;right:0 自动撑】
       ----------------------------------------------------------------------------
       🔴 探针实测（/me 页）：innerWidth = 381，clientWidth = 375
          ⇒ 视口布局宽度比可视宽度多 6px。
       而 left:0;right:0 是相对【包含块的 padding box】算的 ——
       包含块宽度用的是 innerWidth(381) ⇒ 底栏被撑到 381 宽
       ⇒ 多出来的 6px 跑到屏幕右边外 ⇒ 整页能横向滑。
       ⇒ 改成 width:100%（配合 max-width:100vw + box-sizing:border-box）。 */
    width: 100% !important;
    max-width: 100vw !important;
    box-sizing: border-box !important;
    /* ★★★ v2.904：高度【不能写死 56px】—— 这是 iPhone 上"菜单只剩一半"的真因
       ----------------------------------------------------------------------------
       🔴 用户实测（iPhone 12 Pro Max，原话）：
            「首页往下滚屏，菜单按钮只剩一半了。」
       ★ 根因：我 v2.902 写了
              height: 56px !important;
              padding-bottom: env(safe-area-inset-bottom) !important;
              box-sizing: border-box !important;
          ⇒ box-sizing:border-box 意味着 **56px 是【含内边距】的总高**，
            而 iPhone 的安全区（底部小横条）是 34px
          ⇒ 内容的可用高度被压到 56 − 34 = **22px**
          ⇒ 图标 + 文字塞不进 22px ⇒ **被裁掉一半**（用户看到的就是这个）。
       ✅ 正确做法：安全区必须【加在高度之外】——
            height: auto + padding-bottom: 安全区 ⇒
            内容 56px + 安全区 34px = 总高 90px，内容一点不被裁。
       ⚠️ 这也是为什么"iPhone 上底栏被裁"这类问题反复出现：
          桌面浏览器 env(safe-area-inset-bottom) = 0，
          所以在电脑上/我的模拟器里【永远看不出来】，只有真机会暴露。 */
    height: auto !important;
    min-height: 56px !important;
    padding-bottom: calc(6px + env(safe-area-inset-bottom)) !important;
    overflow: visible !important;
  }
  /* ⚠️ 底栏内的项要能收缩，否则文字长了会把整条顶宽  */
  #tabbar .tabbar-item,
  .tabbar .tabbar-item {
    min-width: 0 !important;
    overflow: hidden !important;
  }
}

/* ============================================================================
   七、媒体弹窗（视频/音乐预览）的关闭按钮
   ----------------------------------------------------------------------------
   ⚠️ 这个按钮在 JS 里是【内联】写死 30×30px 的。
      内联优先级最高，普通 CSS 规则压不住它。
   ⚠️ 用户要求「只改手机端，不要动电脑端」⇒
      内联值【保留不动】（删了会让桌面端尺寸变化），
      手机端改用 !important 覆盖（!important 能压过内联）。
   ⚠️ 为什么要加 .mm-close 这个类：原来只有 id，
      用 #media-modal-close 命中它也行，但类名更明确、也不受 id 改动影响。
   ============================================================================ */
@media (max-width: 860px) {
  .media-modal .mm-close,
  #media-modal-close {
    /* ⚠️ !important 是必需的：目标是压过元素上的内联 width/height */
    width: 44px !important;
    height: 44px !important;
    font-size: 1.1rem;
  }
}

/* ============================================================================
   八、超窄屏（≤420px，多数竖屏手机）
   ----------------------------------------------------------------------------
   ⚠️ 这里必须【同时】改抽屉和舞台的高度上限 ——
      只改一个会让两个上限加起来超过 100dvh：
        860 断点：舞台 54 + 抽屉 46 = 100 ✓
        只改抽屉成 44 ⇒ 54 + 44 = 98，看着"余了 2"，
        但两个都按 max 算时实际会互相挤（图被压扁/抽屉露不全）。
   ============================================================================ */
@media (max-width: 420px) {
  /* ★ 窄屏给图【更多】空间（48vh），抽屉收到 48vh —— 合计 96，留 4 给顶栏/安全区。
     ⚠️ 为什么窄屏反而把抽屉做大：
        窄屏意味着"更可能是普通手机"，而用户在这一屏最常做的是
        「看大图 + 下载」。抽屉里放的是下载/做同款按钮，
        太小的话按钮被压到需要滚动才能点到（那是更大的问题）。
        真正"看细节"靠的是点工具条的 ⛶ 铺满，不靠抽屉变小。 */
  .lbm-side { max-height: 48vh; }
  .img-lb-stage { max-height: 48dvh; }
  .lb-tool { min-width: 36px; min-height: 36px; }
}

/* ============================================================================
   十三、★★★ 管理后台的手机端
   ----------------------------------------------------------------------------
   🔴 为什么补这一节（读代码 + 结构判断，不靠猜）：
      查下来 mobile-fix.css 里【完全没有后台相关的选择器】（0 处）——
      但后台其实早就加载了这一层（admin.html 等 5 个页面都引了 common.js，
      而 common.js 会按需注入本文件）。
      ⇒ 结果是：后台在手机上【一点手机端处理都没有】。

   ★ 后台和前台的形态差别（决定不能照搬前台规则）：
      · 前台是内容页，后台是数据页 —— 主体是【表格】和【表单】
      · 21 个菜单项全渲染在 admin.html 一个页面里（不是 21 个页面）
      · 表格列多的有 8~10 列（用户/作品/财务）⇒ 手机上必然放不下，
        这是后台手机端最核心的问题。

   ★ 处理原则（后台能「用」就行，不追求「顺手」）：
      · 表格：横向滚动，不压缩列（压列会让数字折成两行，更难读）
      · 表单：输入占满一行（后台很多是标签+输入并排）
      · 统计卡/分页/工具条：允许折行
      · ⚠️ 不动后台的布局结构（21 个视图共用一个壳，改结构风险大于收益；
        而且本目标里后台是第 ⑤ 优先级）

   ⚠️⚠️ 作用域必须限定 body[data-menu="admin"]：
      前台的 .data-table 也在用（积分流水/作品列表/团队流水），
      不限定会把前台表格也改成横滑（那是另一件事，会互相干扰）。
      本文件只允许一条无保护规则（.mb-close），这里也全部包在 @media 里。
   ============================================================================ */
@media (max-width: 860px) {
  /* ---- 表格：能横滑，不压缩列 ---- */
  body[data-menu="admin"] .table-wrap {
    /* ⚠️ overflow-x:auto 必须配合 max-width:100% ——
       只写 overflow 而不限制宽度，内部宽表格会把【外层】顶宽，
       整页还是能左右拖（后台表格最容易出这个）。 */
    overflow-x: auto !important;
    -webkit-overflow-scrolling: touch;
    max-width: 100%;
  }
  body[data-menu="admin"] .data-table {
    /* ⚠️ 不写 width:100%：那会让列被压进容器宽度，数字折成两行。
       后台表格宁可横滑，也要保持「一行一条记录、一格一个值」可读。 */
    width: auto;
    min-width: 100%;
  }
  body[data-menu="admin"] .data-table th,
  body[data-menu="admin"] .data-table td {
    white-space: nowrap;
    padding: 0.5rem 0.55rem;
  }

  /* ---- 表单：标签 + 输入不再并排挤 ---- */
  body[data-menu="admin"] .field-label { margin-bottom: 0.2rem; }
  /* ⚠️ 后台大量用 grid + sm:grid-cols-N（如「一行三个输入」）——
     手机上必须落成一列，否则每个输入只有 100px 上下。
     用 [class*="sm:grid-cols-"] 匹配：类名就是这个形状，
     逐个列举会漏（21 个视图里到处在用）。 */
  body[data-menu="admin"] [class*="sm:grid-cols-"],
  body[data-menu="admin"] [class*="md:grid-cols-"],
  body[data-menu="admin"] [class*="lg:grid-cols-"] {
    grid-template-columns: 1fr !important;
  }

  /* ---- 工具条 / 分页：允许折行（否则会把页面顶宽） ---- */
  body[data-menu="admin"] .pagination { flex-wrap: wrap; }
  /* ---- 看板统计卡：手机上两列 ---- */
  body[data-menu="admin"] .stat-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ⚠️ 极窄屏（≤420px）：统计卡改一列 —— 两列时每个不到 150px，
   看板的数字都挺长，会挤到一起。 */
@media (max-width: 420px) {
  body[data-menu="admin"] .stat-grid { grid-template-columns: 1fr; }
}

/* ============================================================================
   二十三、★★★ v2.744：4 处「固定列数网格」在手机的兜底
   ----------------------------------------------------------------------------
   🔴 问题：这些网格写的是固定列数，而且【没有窄屏兜底】——
      所以在 390px 手机上被硬塞成 4 列，每格内部只有 60~68px：
        .gallery-loading  4 列 → 每格 84px（内部 60px）  占位卡里要放提示词
        .lbm-src-one      4 列 → 每格 90px（内部 66px）  参考图缩略图
        .ea-stats         4 列 → 每格 88px（内部 64px）  要放"¥12,345"这样的数字
        .quick-row        4 列 → 每格 92px（内部 68px）  首页最常点的入口
      ⚠️ 实测算过：390px 屏内容区约 378px，减 gap 后就是这个数。
      ⚠️ 这不是"溢出"（minmax(0,1fr) 能缩到 0，撑不破页面），
         是【挤】——所以 overflow-audit 查不出来，只有真机看得出。
   ★ 处理：窄屏降列。
      · .gallery-loading 跟着 .gallery-grid 的断点走（1200→3 / 880→2 / 560→1）
        —— 不然加载完从 2 列跳到 4 列，会闪一下
      · 其余 3 处在 <=560px 降到 2 列（.lbm-src-one 是查看器里的，保持小格）
   ⚠️ 只在 max-width 里 ⇒ 电脑端一个像素都不动（用户硬要求）。
   ============================================================================ */
@media (max-width: 1200px) {
  .gallery-loading { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 880px) {
  .gallery-loading { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 560px) {
  .gallery-loading { grid-template-columns: minmax(0, 1fr); }
  .ea-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .quick-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .lbm-src-one { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
