/* server/qjxs/src/web/style.css —— 销售中台的样式（自足，不引外部字体/CDN） */
:root {
  --bg: #f5f6f8;
  --card: #fff;
  --line: #e3e6ea;
  --text: #24292f;
  --muted: #6b7280;
  --brand: #1f6feb;
  --ok: #1a7f37;
  --err: #b42318;
}
* { box-sizing: border-box; }
/**
 * ★★ 2026-10-13 **真实线上事故的修复**（产品当场撞上：
 *   「进来就是把「」挂到我们的商品这个框，压根没法往下操作」）：
 *
 *   HTML 里写的是 `<div id="mapModal" class="modal" hidden>`，靠 `hidden` 属性决定"先不显示"。
 *   浏览器给 `[hidden]` 的默认样式是 `display: none`，**优先级 = 属性选择器（0,1,0）**；
 *   而下面那条 `.modal { display: flex }` 是**类选择器（0,1,0）** —— 同级、**后写的赢** ⇒ `hidden` 被盖掉。
 *   ⇒ 那个"挂到我们的商品"弹层**一进页面就铺满全屏**（`.modal` 是 `position: fixed; inset: 0`），
 *     把整个界面挡住。
 *
 *   ★ 为什么用 `!important`：这条要压过本文件里**所有** `display: flex/grid/block` 的规则
 *     （`.modal` / `.page` / `.subcard` / `.msg` …）。漏一个就出现"某个弹层/分页/提示关不掉"的同类 bug。
 *   ★ 为什么守测试没抓住它：`test/qjxs-shell.test.mjs` 查的是**源码性质**（有没有外部资源、
 *     有没有拼 innerHTML…），它**不看渲染结果**。抓这类"页面行为"缺陷得用真浏览器
 *     （本仓库已有先例：`_probe/verify-release-gc-ui.mjs` 用真 Chrome + CDP 抓到过 4 处界面缺陷）。
 */
[hidden] { display: none !important; }
body {
  margin: 0; background: var(--bg); color: var(--text);
  font: 14px/1.6 -apple-system, "Segoe UI", "Microsoft YaHei", sans-serif;
}
h1, h2, h3 { margin: 0 0 8px; font-weight: 600; }
h2 { font-size: 18px; }
h3 { font-size: 15px; }
.muted { color: var(--muted); }
.small { font-size: 12px; }
.grow { flex: 1; }

/* ---------------------------------------------------------------- 登录页 */
.login-body { display: flex; align-items: center; justify-content: center; min-height: 100vh; }
.login-card { width: 380px; background: var(--card); border: 1px solid var(--line); border-radius: 10px; padding: 28px; }
.login-card h1 { font-size: 22px; }
.login-card form { display: flex; flex-direction: column; gap: 12px; margin-top: 16px; }
.login-card label { display: flex; flex-direction: column; gap: 4px; font-size: 13px; color: var(--muted); }

/* ---------------------------------------------------------------- 布局 */
.topbar {
  display: flex; align-items: center; gap: 16px; padding: 10px 18px;
  background: var(--card); border-bottom: 1px solid var(--line); position: sticky; top: 0; z-index: 5;
}
.brand { font-weight: 600; }
.tabs { display: flex; gap: 4px; }
.tab {
  border: 1px solid transparent; background: none; padding: 6px 12px; border-radius: 6px;
  cursor: pointer; font-size: 14px; color: var(--text);
}
.tab:hover:not(:disabled) { background: #eef1f4; }
.tab.on { background: var(--brand); color: #fff; }
.tab:disabled { color: #b9bec5; cursor: not-allowed; }
/* ★★★ 2026-10-14（`M-PROC-62`）：二级页签**仍在顶栏**（产品第二轮口径「**二级导航还是横向**」）——
   本卡第一版曾把它搬进左栏竖排并在这里加"左对齐"，**那一版已作废**（规则随之删除）；
   现在两块二级导航靠 `proc.css` 的 `.topbar{flex-wrap:wrap}` + `flex-basis:100%` 排到**顶栏第二行**。 */
.who { margin-left: auto; display: flex; align-items: center; gap: 10px; }
/* ★★ 2026-10-13 产品要求（原话）：「宽屏铺得更开 · 销售页也要调整 · 自适应就行了」。
   ⇒ 内容区**不再有像素上限**（原 `max-width: 1180px` 是为"表单页别太宽"设的，
     但它在 1920/2560 的屏上把可操作区域压到 46%/37%，产品实测后要求改成流体）。
   ★ 为什么直接 `none` 而不是调大到一个数：**2560 屏上再大的固定值也会再次变成"两边留白"**；
     自适应的意思就是"有多少用多少"，只靠 `padding` 留边。
   ★ 窄屏行为不变：各页的栏数仍由下面的 `@media`（1400 / 1200 / 1000px）逐级退让。 */
main { padding: 18px; max-width: none; margin: 0 auto; }
/* ★★ 2026-10-13 产品要求：录价台**竖向三栏**（左=批量导入 / 中=手动单条 / 右=已录的单）。
   ★★ 同日第 1 条追加：「① 批量导入 宽度减少2/3」⇒ 左栏收成原来的 1/3（**320px 固定宽**）。
      ★ 为什么用固定宽而不是 `0.33fr`：这一栏里是**一整片粘贴文字**与两张窄表，
        宽度可预期比"永远占 1/3"更好用（中栏的药名、右栏的单据列更需要空间）。
   ★★ 同日第 2 条追加：「③ 已录的单 宽度改小1/4」⇒ 右栏在剩余空间里只拿 3 份、中栏拿 4 份。
      即 `320px | 4fr | 3fr` —— 中栏 : 右栏 = 4 : 3 ⇒ 右栏比"两栏平分"时**小 1/4**。
      ★ 为什么用比例而不是给右栏一个像素宽：中/右两栏都是**列数不定的表格**
        （中栏＝药名+单价+用量；右栏＝日期/门店/味数/合计/总价/状态），比例能随屏幕一起退让。
   ★ 三档断点逐级退让，免得挤成三条细缝：
     >1400px 左栏 320px · 1000~1400px 左栏 260px · <1000px 落成单栏上下排
   ★ `minmax(0,1fr)` 而不是 `1fr`：`1fr` 的最小值是 auto，长文本（品名/药名）会把格子撑破。 */
/* ★ 2026-10-13：这一条（原 `max-width: 1600px`）按产品要求解掉 —— 录价台在 2560 屏上只用到 62.5%，
   现在与其它页一样"有多少用多少"。★ 保留选择器是为了留住上面那段三栏口径的注释锚点。 */
main:has(#page-record:not([hidden])) { max-width: none; }
.cols3 { display: grid; grid-template-columns: 320px minmax(0, 4fr) minmax(0, 3fr); gap: 14px; align-items: start; }
@media (max-width: 1400px) { .cols3 { grid-template-columns: 260px minmax(0, 4fr) minmax(0, 3fr); } }
@media (max-width: 1000px) { .cols3 { grid-template-columns: minmax(0, 1fr); } }

/* ★★ 2026-10-13 产品要求：「对照台 升级 查价并入对照台 放到右边」⇒ 对照台一页两栏。
   ★★ 2026-10-14（`M-PROC-59`）：那一页改名**市场价工作台**，并从"左对照 / 右查价**宽表**"
      改成 **左索引 / 右详情**（形状见 `index.html` 里 `#page-map` 那段注释）。
      ⇒ 两栏改**各占一半**：左=「我们的商品」清单（4 列）· 右=选中那一味的比价详情（4 列）——
        两边列数一样，**没有哪一边天然更宽**（原写"右栏要摆我们 + 每个门店一列"，
        那种"门店占列"的宽表已经不存在了）。
      ★ 为什么用 grid 的 `minmax(0, 1fr) × 2` 而不是 `flex: 1 1 0`：先例 `M-PROC-57` 真 Chrome 实测——
        两个盒子 padding/border 不一样时 flex **不等宽**（量到 578 / 600），grid 恒等分。
   ★ 窄屏（<1200px）落成上下排 —— 与录价台三栏同一套退让策略。 */
/* ★ 2026-10-13：同录价台，原 `max-width: 1600px` 解掉（产品：宽屏铺开）。 */
main:has(#page-map:not([hidden])) { max-width: none; }
.cols2 { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 14px; align-items: start; }
@media (max-width: 1200px) { .cols2 { grid-template-columns: minmax(0, 1fr); } }
.col { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.col-card { display: flex; flex-direction: column; gap: 8px; }
.col-card h3 { margin: 0 0 2px; }
.col-card h4 { margin: 6px 0 2px; font-size: 14px; }
label.stack { display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: var(--muted); }
/* 三栏里表格会横向溢出 ⇒ 每张表自己可横滚，不撑破栏 */
.tablewrap { overflow-x: auto; }
.tablewrap > table.grid { min-width: 100%; }
.page { display: flex; flex-direction: column; gap: 12px; }
.card { background: var(--card); border: 1px solid var(--line); border-radius: 10px; padding: 16px; }
.subcard { background: #fafbfc; border: 1px dashed var(--line); border-radius: 8px; padding: 12px; margin: 10px 0; }
.row { display: flex; align-items: flex-end; gap: 12px; flex-wrap: wrap; margin: 8px 0; }
.row label { display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: var(--muted); }
.row label.inline { flex-direction: row; align-items: center; gap: 6px; }
input, select, button { font: inherit; }
input, select { padding: 6px 8px; border: 1px solid var(--line); border-radius: 6px; background: #fff; min-width: 120px; }
button { cursor: pointer; }
button.primary { background: var(--brand); color: #fff; border: 1px solid var(--brand); border-radius: 6px; padding: 7px 14px; }
button.primary:disabled { opacity: .6; cursor: not-allowed; }
button.link { background: none; border: none; color: var(--brand); padding: 4px 6px; }
button.link.danger { color: var(--err); }
.msg { margin: 8px 0 0; padding: 8px 10px; border-radius: 6px; font-size: 13px; }
.msg.ok { background: #e8f5ec; color: var(--ok); }
.msg.err { background: #fdecea; color: var(--err); }

/**
 * ★★ 模块顶部的**操作工具条**（2026-10-13 产品要求：
 *   「操作按钮放到模块顶部，不要随着增加一行而跟着跑」）。
 *
 * 解决的是两个具体痛点（都是员工真会遇到的）：
 *   · 「＋ 加一味 / 保存这张单」原来在**明细表下面** —— 录到第 20 味时要滚到最底才够得着「保存」，
 *     而且每点一次「加一味」，按钮就往下跑一格；
 *   · 「解析预览」原来在粘贴框下面 —— 粘一大片字之后按钮被推下去；
 *     「直接导入并保存」原来在**坏行表下面** —— 坏行一多就要滚很久。
 *
 * ★ `position: sticky` 的理由：这些卡片在**页面滚动**时，工具条会吸附在顶部不跑掉；
 *   于是"无论在模块里滚到哪，按钮都在眼前"。`z-index` 要高于表格里的输入框，否则会被盖住。
 * ★ `background` 必须给：sticky 元素滚动时下面的内容会从它身下穿过，透明的话会糊成一片。
 */
.col-toolbar {
  position: sticky;
  top: 0;
  z-index: 3;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0 0 8px;
  padding: 8px 0;
  background: var(--card);
  border-bottom: 1px solid var(--line);
}
.col-toolbar label.inline { display: flex; flex-direction: row; align-items: center; gap: 6px; font-size: 12px; color: var(--muted); }
/* 预览摘要：原来是 `<h4>`（占一整行），现在挤进工具条里当一句说明 */
.toolbar-note { font-size: 12px; color: var(--muted); line-height: 1.5; }

/* ★ 警告（**不拦**的那种）：表格导入里"看着像 KG 价"用这个色 —— 与"错"必须一眼分开 */
.msg.warn { background: #fff6e5; color: #8a5a00; }
/* 表格导入弹层比挂靠弹层宽（要放下三列表 + 坏行表） */
.modal-card.wide { width: min(94vw, 860px); }
#impText {
  width: 100%; padding: 8px; border: 1px solid var(--line); border-radius: 6px; resize: vertical;
  font: 13px/1.5 ui-monospace, Consolas, "Microsoft YaHei", monospace;
  /* ★ 左栏收窄到 320px 后，粘贴框跟着变窄；两行高度够看清"粘进来了没有" */
  min-height: 110px;
}
#impText::placeholder { color: #b9bec5; }
#impResult { margin-top: 10px; }
#impResult h4 { font-size: 14px; margin: 10px 0 4px; }

/* ---------------------------------------------------------------- 表格 */
table.grid { width: 100%; border-collapse: collapse; margin-top: 8px; }
table.grid th, table.grid td { text-align: left; padding: 6px 8px; border-bottom: 1px solid var(--line); vertical-align: middle; }
table.grid th { font-size: 12px; color: var(--muted); font-weight: 500; }
table.grid input { width: 100%; }

/* ---------------------------------------------------------------- 其它 */
.chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.chip { background: #eef1f4; border-radius: 999px; padding: 2px 10px; font-size: 12px; }
/* 自动对照的候选按钮（挤在 chip 里，要比普通 link 小一号） */
button.link.tiny { font-size: 12px; padding: 1px 6px; margin-left: 4px; border-left: 1px solid var(--line); }
.modal { position: fixed; inset: 0; background: rgba(20, 24, 28, .45); display: flex; align-items: center; justify-content: center; z-index: 20; }
.modal-card { background: var(--card); border-radius: 10px; padding: 18px; width: min(92vw, 560px); max-height: 80vh; overflow: auto; }
.modal-card label { display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: var(--muted); margin: 8px 0; }
.picklist { display: flex; flex-direction: column; gap: 2px; max-height: 40vh; overflow: auto; margin-top: 6px; }
.pick { text-align: left; background: none; border: 1px solid transparent; border-radius: 6px; padding: 6px 8px; }
.pick:hover { background: #eef1f4; border-color: var(--line); }
/* 查价页：最便宜那一格加个底色（★ 只是视觉提示，判据在服务端算好放进 cheapestStoreId） */
td.cheap { background: #e8f5ec; font-weight: 600; }

/* ------------------------------------------------ 市场价工作台（`#page-map` · `M-PROC-59` / `M-PROC-61`）
   ★★ 2026-10-14 产品口径（三轮，逐字）：
      第一轮「对照台 查价这个升级为 **市场价工作台**」+「升级界面 UI 布局 以及数据布局」
      第二轮「**没有模块容器化吗？还是不断的平铺出来？你可以做分栏 左右分栏**」
      ★★ 第三轮（`M-PROC-61`）「**市场价工作台 做成三栏的结构吧**」
      ⇒ ① 页内 = **三个模块容器各占一栏**（我们的商品 / 对照 / 比价详情；`M-PROC-59` 是"左栏两格 + 右栏一格"）；
        ② 每个模块 = `.mw-pane` = **标题条 `.mw-pane-head` + 框内滚的 `.mw-pane-body`** ——
           ★ 这就是采购工作台那一套「**页面不滚、框内滚**」（与 `proc.css` 里 `.pi-left` / `.pi-items`
             以及 `M-PROC-60` 的框架锁一屏是同一套语言）；
        ③ ★★ **不再"卡片一张张往下平铺"**：≥1201px 时本页**夹在视口内**
           （`height: calc(100vh - --mw-top)`），三栏各自占满高度、超出在各自框内滚。

   ★★ 这三条规则**全部带 `#page-map` 作用域**：新类名只属于这一页，**不许漏到录价台 / 采购各页**
      （先例 `M-PROC-57` 的 CSS 作用域纪律 —— 守测试 `test/qjxs-market-workbench.test.mjs` ④ 现算这一条：
      "凡本卡新增的类，规则行里必须出现 `#page-map`"）。
   ★ 为什么"选中"要有底色 + 商品名加粗：右栏只显示**一条**，左栏一眼看不出"现在看的是哪一味"
      就只能靠猜 —— 这是主从布局最常被漏掉的一环。 */
#page-map { --mw-top: 93px; }   /* 顶栏 57px + `main` 上下 padding 18+18px —— 见下面 ≥1201px 那条 */
#page-map tr.mw-row { cursor: pointer; }
#page-map tr.mw-row:hover > td { background: #f2f5f8; }
#page-map tr.mw-row.is-active > td { background: #e8f0fe; }
#page-map tr.mw-row.is-active > td:first-child { font-weight: 600; }
/* 我们自己那一行（商品档案的价）—— 压暗一档：它是**基准**，不是"又一个同行" */
#page-map tr.mw-our > td { color: var(--muted); }
#page-map .mw-detail-title { font-size: 15px; font-weight: 600; margin-bottom: 2px; }

/* ★ 模块容器：标题条 + 框内滚的正文（两块的分工就是"标题条不滚、正文滚"） */
#page-map .mw-pane { display: flex; flex-direction: column; min-height: 0; }
#page-map .mw-pane-head {
  display: flex; flex-direction: column; gap: 6px;
  flex: 0 0 auto; padding-bottom: 8px; border-bottom: 1px solid var(--line);
}
#page-map .mw-pane-head h3 { margin: 0; }
/* ★ 标题条的第一行 = **标题在左、工具在右**（同一行）—— 省下一整行高度给正文。
   `.row` 原本是「标签在上、控件在下 + `align-items: flex-end`」的表单行，这里当**标题行**用 ⇒ 居中、去边距。 */
#page-map .mw-pane-head .mw-head-row { align-items: center; margin: 0; }
#page-map .mw-pane-head .mw-head-row label { flex-direction: row; align-items: center; gap: 6px; }
#page-map .mw-pane-head .row { margin: 4px 0 0; }
#page-map .mw-pane-head .msg { margin: 4px 0 0; }
/**
 * ★★ `.mw-pane-body` = **框内滚的那一块**：
 *   · `overflow: auto` + `min-height: 0`（flex 子项默认不肯收缩，少了它滚不起来）；
 *   · ★ **窄屏（≤1200px 落成上下排）每个容器自己封顶** `max-height: 60vh` —— 仍然是"框内滚"，
 *     不又变成"不断往下平铺"（产品第二轮就是要这件事）；
 *   · ≥1201px 那一档再把 `max-height` 交还给 flex（`max-height: none`），由**容器高度**决定。
 */
#page-map .mw-pane-body { overflow: auto; min-height: 0; max-height: 60vh; padding-top: 8px; }
#page-map .mw-pane-body > .subcard { margin: 0 0 10px; }

/* ★★ ≥1201px：**本页夹在视口内**（页面不滚、框内滚）—— 横向两栏各自占满高度
   ★★★ 这里**必须是 `height`（确定高度），不能是 `max-height`** —— 本卡第一版写的是 `max-height`，
     真 Chrome 一量就露馅：`max-height` 给不出**确定高度** ⇒ 两栏里的 `flex: 1 1 0` 子项
     塌成 **8px**（读数 `goods {h:8, sh:1110}`）⇒ "框内滚"变成"框内什么都没有"。
     ★ 这是 flexbox 的经典陷阱：`flex-basis: 0` + `min-height: 0` 的项**不向容器贡献固有高度**，
       所以从 `#page-map` 到 `.mw-pane-body` 这条链上**每一级都得是确定高度**。
     ⇒ `height: calc(100vh - var(--mw-top))`；`min-height` 只当"视口太矮时的下限"（那时页面会滚，如实接受）。
   ★ `--mw-top` = **顶栏 57px + `main` 上下 padding 18+18 = 93px**（真 Chrome 现取的三个数）：
     少 1px 就会让整页多出一条 1px 的纵向滚动条（`pageOverflowY` 会从 0 变 1）。 */
@media (min-width: 1201px) {
  #page-map { height: calc(100vh - var(--mw-top)); min-height: 460px; }
  /**
   * ★★★ 2026-10-14（`M-PROC-61`）**三栏**（产品逐字：「**市场价工作台 做成三栏的结构吧**」）。
   *
   * 三个模块容器**各占一栏**（原来是"左栏上下两格 + 右栏一格"）：
   *   栏 1 `#mwPaneGoods`（我们的商品）· 栏 2 `#mwPaneMap`（对照）· 栏 3 `#mwPaneDetail`（比价详情）。
   *
   * ★★ 怎么让"左栏那两个 pane"直接当**网格项**（DOM 一个字节都不用动）：
   *   `#colMap { display: contents }` —— 它这一层**不再生成盒子**，它的两个孩子于是**上浮**
   *   成为 `.cols2` 的网格项（`#colCompare` 仍是第 3 项）。★ 为什么不动 DOM：`#colMap` / `#colCompare`
   *   这两个 id 被 `app.js` 与守测试 `test/qjxs-market-workbench.test.mjs` ② 钉着
   *   （"清单住 `#colMap`、详情住 `#colCompare`"）⇒ 改结构等于**顺手改判据锚点**，而 CSS 这一招零成本。
   * ★ 三条轨道**等分**（与 `.cols2` 原本"各占一半"同一条口径：先例 `M-PROC-57` 的 `minmax(0,1fr)`×N）；
   *   每栏内容超长时**在各自的 `.mw-pane-body` 框里滚**（下面那条 `max-height: none; flex: 1 1 auto`）。
   */
  #page-map > .cols2 {
    /* ★ 写法用 `repeat(3, …)` —— 与全局 `.cols2` 的 `minmax(0, 1fr) minmax(0, 1fr)` **不构成子串包含**
       （`M-PROC-59` 的守测试 ④ 有一处反例把那个两轨道串当"恰好 1 处"的锚点；写成三条平铺会让它
        在自己的"前提校验"上就失败 —— 那不是它的判据错，是锚点撞了。等价写法各取所需，见该文件 §2 ②）。 */
    grid-template-columns: repeat(3, minmax(0, 1fr));
    flex: 1 1 auto; min-height: 0; align-items: stretch;
  }
  #page-map .mw-pane-col { height: 100%; min-height: 0; }
  #page-map .mw-pane-body { max-height: none; flex: 1 1 auto; }
  /* ★★ 下面这三条是 `M-PROC-59` 的"左栏上格 : 下格 = 1.5 : 1"——**已被三栏口径取代**（同一个 `#colMap`
     里再没有"上格/下格"，两个 pane 现在是**并列的两栏**）。留在这里会误导"比例还在生效"（`K-24`）⇒ 删掉，
     改由上面那条三轨道承担。★ 留痕：那条口径与它踩过的"被更具体的选择器覆盖"的坑记在
     `docs/procurement/tasks/M-PROC-59-市场价工作台.md` §2 `L-6`（本卡只加指针，不改它的原文）。
     #page-map #colMap > .mw-pane { flex: 1 1 0; }
     #page-map #colMap > #mwPaneGoods { flex-grow: 1.5; }
     #page-map #colMap > #mwPaneMap { min-height: 200px; } */
}

/**
 * ★★ `#colMap { display: contents }` **不分档位**（≥1201 与 ≤1200 都要）：
 *   · 宽屏 ⇒ 它的两个孩子成为第 1/2 栏（见上）；
 *   · 窄屏（≤1200px 落一条轨道）⇒ 三个 pane 依次上下排，各自 `.mw-pane-body { max-height: 60vh }`
 *     框内滚 —— 与 `M-PROC-59` 的窄屏口径**逐字不变**。
 * ★ 为什么必须写在媒体查询**外面**：写在 `@media (min-width:1201px)` 里的话，窄屏下 `#colMap`
 *   又变回一个有盒子的 flex 列，两个 pane 会被它**裹在一起**、与"三块上下排"不是一回事。
 */
#page-map > .cols2 > #colMap { display: contents; }

/* ★★ 右栏详情表的**列宽与折行**（`M-PROC-59` **出图后**才定的，不是拍脑袋）：
   第一版只写了表头的百分比（门店 38% / 价 20% / 采集日 20% / 单号 auto），真 Chrome 一渲染就露馅 ——
   36 字符的**单号抢宽**，把「价」挤成 `0.28 元/` + `克`、把「采集日」挤成两行（`2026-10-` + `12`）。
   ⇒ 三列**不许折行**（`nowrap`）、单号**允许折**（`break-all` + 等宽小字，UUID 折两行不难看），
     并把列宽改成 30 / 18 / 18 / 34（`index.html` 那边）。★ 静态判据对"折没折行"是零鉴别力。 */
#page-map #cmpDetail td, #page-map #cmpDetail th { vertical-align: top; }
#page-map #cmpDetail td:nth-child(1),
#page-map #cmpDetail td:nth-child(2),
#page-map #cmpDetail td:nth-child(3),
#page-map #cmpDetail th { white-space: nowrap; }
#page-map #cmpDetail td:nth-child(4) {
  word-break: break-all;
  font: 12px/1.5 ui-monospace, Consolas, "Microsoft YaHei", monospace;
  color: var(--muted);
}
