/* ==========================================================================
   MathPad —— Mathcad 15 经典 Windows 应用外壳
   ========================================================================== */
/* ★★ 主题变量（2026-10-08 用户："做几个主题风格…现在的作为经典…浅色、深色…不超过 7 个"）。
   规矩：**界面里所有配色只准写 `var(--mp-…)`，不许再往规则里写死颜色** ——
   否则新主题一切换就会出现"某一块没跟着变"的花脸。
   这里的默认值 = 「经典」（Mathcad 15 那种灰蓝外壳，也就是加主题之前的外观）。
   各主题只覆盖下面这些变量（见文件末尾 `html[data-theme="…"]`），不重复写规则。
   `--mp-font/size/color/weight/style/deco/align/bg` 是**区域的格式设置**（工具栏 B/I/U/颜色那套，
   JS 写在元素上），不在这里定义 —— 它们是用户数据，不是主题。 */
:root {
  /* ── 表面 ── */
  --mp-shell: #7c8896;          /* 应用之外露出来的底（几乎看不到） */
  --mp-paper: #fff;             /* 画布那张"纸" */
  --mp-field: #fff;             /* 输入框 / 弹层 / 面板里的浅色面 */
  --mp-field-alt: #fbfcfd;      /* 比 field 再浅一档的面 */
  --mp-face: #f0f0f0;           /* 工具栏 / 菜单栏 / 状态栏 / 对话框的底 */
  --mp-hover: #eef4fd;          /* 悬停底色（浅） */
  --mp-hover-2: #dce8f8;        /* 悬停底色（深一档） */
  --mp-sel: #dbe7f6;            /* 选中 / 高亮底色 */
  --mp-sel-2: #cfdff2;          /* 选中底色（深一档，按钮按下等） */
  --mp-sel-bd: #a8c0e0;         /* 选中边框 */
  --mp-tint: rgba(74,134,207,.10);    /* 框选 / 选区那层淡淡的蓝 */
  --mp-tint-2: rgba(74,134,207,.13);
  --mp-sel-tint: rgba(74,134,207,.28);   /* MathLive 鼠标拖选的底色 */
  --mp-veil: rgba(0,0,0,.06);   /* 对话框背后的压暗 */
  --mp-track: #e2e6eb;          /* 滑块轨道（没走过的一段） */
  --mp-track-bg: rgba(0,0,0,.08);     /* 性能条底槽 */
  --mp-swatch-bd: rgba(0,0,0,.15);    /* 颜色小方块的外框 */
  --mp-sep: #dde3e9;            /* 细分隔线 */
  --mp-hairline: #c8cdd3;       /* 工具栏里的小竖线（比 sep 深一档，原本就是两个色） */
  --mp-tab-on-bd: #8ba8c9;      /* 当前标签的边框 */
  --mp-tab-x: #7a8794;          /* 标签上那个 ✕ */
  --mp-rule: #7d858e;           /* 单位构造器里的分数线 */
  --mp-grip: #9aa7b4;           /* 拖拽手柄的斜纹 */
  --mp-ph: #b9c2cb;             /* 占位符（"文本…"、公式里的空位） */

  /* ── 文字 ── */
  --mp-ink: #1a1a1a;            /* 正文 */
  --mp-ink-2: #26303a;          /* 次要正文 */
  --mp-ink-3: #5a636c;          /* 说明文字 */
  --mp-dim: #6b7480;            /* 灰掉的说明 */
  --mp-dim-2: #8b949e;          /* 更灰的（禁用、尺寸提示） */
  --mp-on-accent: #fff;         /* 压在强调色上的文字 */
  --mp-on-accent-dim: #dbe7f6;
  --mp-title-ink: #17263a;      /* 标题栏文字 */
  --mp-winbtn-ink: #2b3a4b;     /* 标题栏上那三个窗口按钮的字 */
  --mp-tool-ink: #2f4a68;       /* 工具栏图标 */
  --mp-sym-ink: #24384e;        /* 符号按钮（工具条第 3 行 + 右侧符号面板） */
  --mp-author: #4a5764;         /* 菜单栏右上角的作者署名 */
  --mp-tab-ink: #46525f;        /* 标签页文字 */

  /* ── 线条 ── */
  --mp-edge-3: #8d949b;         /* 最粗的框（对话框 / 输入框外框） */
  --mp-edge-2: #c6ccd3;         /* 中等的框 */
  --mp-edge: #b7bcc2;           /* 默认框线 */
  --mp-edge-lt: #dfe3e7;        /* 最淡的分隔线 */
  --mp-title-edge: #b3bfd0;     /* 标题栏下沿 */

  /* ── 强调色（蓝） ── */
  --mp-accent: #2b62a8;
  --mp-accent-strong: #316ac5;  /* 菜单高亮那一格 */
  --mp-accent-ink: #1f4e79;     /* 强调色的"文字版"（深一档） */
  --mp-accent-bd: #6d8cb5;      /* 强调色的框线 */
  --mp-accent-lt: #cfe0f7;      /* 强调色的淡底（标签、小节线） */
  --mp-caret: #1a73c8;          /* 插入光标 */

  /* ── 语义色 ── */
  --mp-err: #b02418;  --mp-err-bg: #fdecea;
  --mp-warn: #8a5a00; --mp-warn-2: #b4761a;  --mp-warn-bg: #fff7e6;  --mp-warn-bd: #e0a83a;
  --mp-ok: #3d8b40;   --mp-ok-bg: #e5f0e0;
  --mp-plus: #e03b2c;           /* 空区域那个红色 + */
  --mp-paused: #7b8794;         /* 暂停时的灰方块 */

  /* ── 控件渐变（现代主题把两头设成同色就是"扁平"） ── */
  --mp-title-a: #f8fbff;  --mp-title-b: #e6eefa;
  --mp-tabbar-a: #dde6f1; --mp-tabbar-b: #ccd8e7;
  --mp-tab-a: #e8eef6;    --mp-tab-b: #f3f7fc;
  --mp-cap-a: #f8fbff;    --mp-cap-b: #e6ebf0;
  --mp-btn-a: #fff;       --mp-btn-b: #eef1f5;
  --mp-btn-main-a: #dfeeff; --mp-btn-main-b: #c3ddfb;
  --mp-close-a: #ffdddd;  --mp-close-b: #e8a0a0;  --mp-close-bg: #c0392b;

  /* ── 状态栏小图（性能条、闪电） ── */
  --mp-spark: #e8890c; --mp-spark2: #f0a020;
  --mp-bar-eng-a: #6fa8f5; --mp-bar-eng-b: #3d7fd6;
  --mp-bar-fe-a: #ffd08a;  --mp-bar-fe-b: #f0a020;

  /* ── 绘图默认色（JS 读这些值当 Plotly 的默认样式，见 themePlotVals()） ──
     ⚠️ 用户在「图形选项」里改过就听用户的（r.style 里存着），这里只管"没改过"的图。 */
  --mp-plot-paper: #ffffff; --mp-plot-bg: #ffffff;
  --mp-plot-grid: #e8ebee;  --mp-plot-axis: #b9c0c7;
  --mp-plot-tick: #3a4550;  --mp-plot-ink: #1a1a1a;
  --mp-plot-origin: #000000;    /* Origin 风格坐标轴的箭头（深色主题下要变浅） */
  /* 图例的底与框：⚠️ 以前是写死的浅色（rgba(255,255,255,.78)）—— 深色主题下
     就成了"浅色字压在白色半透明框上"，图例完全读不出来。 */
  --mp-plot-legend-bg: rgba(255,255,255,.78);  --mp-plot-legend-bd: #d7dce2;
}
* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }
/* ★ 界面字体走变量：现代主题（浅色 / 深色）用 Segoe UI Variable，经典主题保持雅黑。
   ⚠️ 必须**写在这里**（下面紧跟的 `body.lang-*` 才是各语言的字体栈），
      否则放在文件末尾的主题块会把日语/阿语的字体栈盖掉。 */
body {
  font-size: 12.5px; font-weight: 400;
  font-family: var(--mp-ui-font, "Microsoft YaHei", Tahoma, sans-serif);
  color: var(--mp-ink);
  background: var(--mp-shell); display: flex; overflow: hidden;
}

/* ==========================================================================
   多语言：按语言换字体栈 + 阿拉伯语 RTL（2026-10-03 加了 11 种语言）
   · 各语言的系统字体不一样，硬用雅黑会让日文汉字写错（"直"/"骨"这种字形不同）、
     阿拉伯语更是必须换字体，否则字形挤在一起。
   · RTL **只镜像界面**：菜单栏、工具栏、对话框、浮层、状态栏；工作区里的公式区
     和文本区保持 LTR —— 数学式子里 x² 的书写方向不跟着语言翻。
   ========================================================================== */
body.lang-ja   { font-family: "Yu Gothic UI", "Meiryo", "MS PGothic", "Hiragino Kaku Gothic ProN", "Microsoft YaHei", sans-serif; }
body.lang-ko   { font-family: "Malgun Gothic", "Apple SD Gothic Neo", "NanumGothic", "Microsoft YaHei", sans-serif; }
body.lang-zh-TW{ font-family: "Microsoft JhengHei", "PingFang TC", "Noto Sans TC", "Microsoft YaHei", sans-serif; }
body.lang-ar   { font-family: "Segoe UI", Tahoma, "Noto Naskh Arabic", "Arial", sans-serif; }
body.lang-ru   { font-family: "Segoe UI", "PT Sans", Tahoma, "Microsoft YaHei", sans-serif; }
body.lang-tr   { font-family: "Segoe UI", Tahoma, "Microsoft YaHei", sans-serif; }
body.rtl { direction: rtl; }
body.rtl .menubar, body.rtl .toolbars, body.rtl .statusbar, body.rtl .modal,
body.rtl .dropdown, body.rtl #toast, body.rtl .palwin, body.rtl .plinkmenu,
body.rtl .titlebar { direction: rtl; text-align: right; }
body.rtl .wb-r, body.rtl .wb-r math-field, body.rtl .wb-r .wb-text { direction: ltr; text-align: left; }
body.rtl .menubar .mi, body.rtl .tbtn { direction: rtl; }

/* ---------- 应用窗口 ---------- */
.app { flex: 1; display: flex; flex-direction: column; background: var(--mp-face); min-width: 0; }

/* 标题栏 */
.titlebar {
  height: 30px; flex: none; display: flex; align-items: center; padding: 0 5px;
  background: linear-gradient(to bottom, var(--mp-title-a), var(--mp-title-b));
  border-bottom: 1px solid var(--mp-title-edge);
}
/* 标题栏左上角的应用图标（2026-10-07）：与浏览器标签页 favicon **同一个文件**
   （`mathpad.ico` 是多规格图标组，浏览器按 17px 这个尺寸自己挑 16/24 那两帧）。
   ⚠️ 别再用 `linear-gradient + 白字 M` 那套 —— 用户定稿了正式图标，两处必须一致。 */
.appicon {
  width: 17px; height: 17px; margin-right: 6px; border-radius: 3px; flex: none;
  background: url("mathpad.ico") center / contain no-repeat;
}
/* ⚠️ 标题现在是**固定的品牌语**（2026-10-07 起不跟文件名走），比原来长得多 ——
   必须 nowrap + 省略号，否则窄窗口下会折行、把 30px 高的标题栏撑破。
   `min-width:0` 是 flex 子项能收缩（进而出省略号）的前提。 */
.titlebar .title {
  flex: 1; min-width: 0; font-size: 12.5px; color: var(--mp-title-ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.winbtns { display: flex; gap: 2px; }
.winbtns button {
  width: 32px; height: 21px; border: 1px solid var(--mp-title-edge); color: var(--mp-winbtn-ink);
  background: linear-gradient(var(--mp-btn-a), var(--mp-btn-b)); font-size: 11px; cursor: default;
}
.winbtns button:hover { background: linear-gradient(var(--mp-btn-a), var(--mp-hover-2)); }
.winbtns .close:hover { background: linear-gradient(var(--mp-close-a), var(--mp-close-b)); }

/* 菜单栏 */
.menubar { flex: none; display: flex; padding: 0 2px; background: var(--mp-face);
           border-bottom: 1px solid var(--mp-edge-lt); }
.menubar .mi { padding: 3px 9px; font-size: 12.5px; cursor: default; user-select: none;
               border: 1px solid transparent; white-space: nowrap; }
.menubar .mi:hover, .menubar .mi.open { background: var(--mp-sel); border-color: var(--mp-sel-bd); }
.menubar .mi u { text-decoration: underline; }
/* 右上角署名（作者）：order 让它排在所有菜单项之后，margin-inline-start 让它在
   LTR 贴右、RTL（阿拉伯语）贴左 —— 用 margin-left 的话阿语界面会跑到中间去 */
.menubar .author { order: 999; margin-inline-start: auto; padding: 3px 10px 3px 12px;
                   font-size: 12px; color: var(--mp-author); white-space: nowrap;
                   user-select: none; cursor: default; }
body.rtl .menubar .author { padding: 3px 12px 3px 10px; }

/* ---------- 文档标签栏（多文档，2026-10-04） ----------
   每个标签 = 一份独立文档（各自的白板内容 / 撤销历史 / 文件句柄 / 滚动位置）。
   当前标签白底加粗，改过没存挂 `*`（`.dirty`），绑定了磁盘文件的挂一个小圆点。
   ⚠️ 标签栏是**常驻**的（哪怕只有一个文档）—— 否则用户根本发现不了能开多个文档。
   ⚠️ 标签里除 ✕ 之外的区域一律走 mousedown 切换：click 会被 MathLive 抢焦点时序干扰，
      也吃不掉中键（中键 = 关闭标签）。 */
.tabbar { flex: none; display: flex; align-items: flex-end; gap: 2px; height: 25px;
          padding: 3px 4px 0 4px; background: linear-gradient(to bottom, var(--mp-tabbar-a), var(--mp-tabbar-b));
          border-bottom: 1px solid var(--mp-edge); overflow-x: auto; overflow-y: hidden; }
.tabbar::-webkit-scrollbar { height: 0; }
.tabbar .tab { display: flex; align-items: center; gap: 5px; height: 22px; flex: 0 0 auto;
               max-width: 220px; padding: 0 3px 0 9px; cursor: default; user-select: none;
               border: 1px solid var(--mp-edge); border-bottom: none; border-radius: 4px 4px 0 0;
               background: var(--mp-tab-a); color: var(--mp-tab-ink); font-size: 12px; }
.tabbar .tab:hover { background: var(--mp-tab-b); }
.tabbar .tab.on { background: var(--mp-paper); color: var(--mp-title-ink); font-weight: 700; border-color: var(--mp-tab-on-bd); }
.tabbar .tnm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tabbar .tab.dirty .tnm::after { content: ' *'; color: var(--mp-warn); }
.tabbar .tab .tbind { color: var(--mp-accent); font-size: 10px; line-height: 1; }
.tabbar .tab .tx { border: none; background: transparent; color: var(--mp-tab-x); padding: 0;
                   width: 16px; height: 16px; border-radius: 2px; cursor: pointer;
                   font: 11px/1 "Segoe UI", sans-serif; }
.tabbar .tab .tx:hover { background: var(--mp-hover-2); color: var(--mp-err); }
.tabbar .tadd { flex: 0 0 auto; width: 22px; height: 20px; margin-bottom: 1px; cursor: pointer;
                border: 1px solid var(--mp-edge); border-radius: 3px; background: var(--mp-field-alt);
                color: var(--mp-accent); font: 700 13px/1 "Segoe UI", sans-serif; padding: 0; }
.tabbar .tadd:hover { background: var(--mp-field); border-color: var(--mp-accent); }
.tabbar .tab.flash { background: var(--mp-ok-bg); border-color: var(--mp-ok); }
body.rtl .tabbar { direction: rtl; }

/* 「关于 MathPad」对话框：中文原文在前、当前语言译文在后 */
.aboutwrap { font-size: 12.5px; line-height: 1.8; color: var(--mp-ink-2); }
.aboutwrap p { margin: 0; }
.aboutwrap .aboutzh { color: var(--mp-title-ink); }
.aboutwrap .abouttr { margin-top: 10px; padding-top: 10px; border-top: 1px dashed var(--mp-edge-2);
                      color: var(--mp-ink-3); }
.aboutwrap .aboutowner { margin-top: 12px; text-align: end; color: var(--mp-ink-3); }
.aboutwrap .abouttr, .aboutwrap .aboutzh { text-align: start; }

/* ⚠️ RTL（阿拉伯语）界面下，函数窗口的签名是"代码 + 说明"混排：整页 RTL 会把
   `plot(v) ← 说明` 逆序成 "说明 ← plot(v)"。`unicode-bidi: plaintext` 让**每一段
   按自身方向**排版（首字符是拉丁就 LTR、是阿语就 RTL），比写死 direction 稳。 */
.modal .sig, .modal .desc { unicode-bidi: plaintext; }
/* 关于窗口里中文段与阿语段各自成段，同理 */
.aboutwrap p { unicode-bidi: plaintext; }

/* 下拉菜单 */
.dropdown { position: absolute; z-index: 100; min-width: 200px; padding: 2px;
            background: var(--mp-field); border: 1px solid var(--mp-edge-3); box-shadow: 2px 2px 5px rgba(0,0,0,.25); }
.dropdown .it { display: flex; align-items: center; gap: 8px; padding: 3px 10px 3px 6px;
                font-size: 12.5px; cursor: default; white-space: nowrap; }
.dropdown .it:hover { background: var(--mp-accent-strong); color: var(--mp-on-accent); }
.dropdown .it .ic { width: 16px; text-align: center; opacity: .85; }
.dropdown .it .k { margin-left: auto; color: var(--mp-dim); font-size: 11px; }
.dropdown .it:hover .k { color: var(--mp-on-accent-dim); }
.dropdown .hr { height: 1px; margin: 3px 2px; background: var(--mp-edge-lt); }

/* 浮动功能面板（矩阵 / 编程）：标题栏 + 关闭按钮 + 网格按钮
   ⚠️ 列宽必须是 minmax(0, 1fr) 而不是 1fr：
      1fr 的下限是 min-content，而按钮里的文字是 nowrap，
      于是一旦某一列出现「zeros(m,n) 零矩阵」这种长标签，
      整个网格就会被撑到 240px 以上、溢出固定宽度 236px 的窗口
      —— 右列的按钮和「插入」都会跑到窗口外面（用户看到的就是"窗口乱"）。 */
.palwin { position: absolute; z-index: 110; width: 292px; background: var(--mp-face);
          border: 1px solid var(--mp-edge-3); box-shadow: 3px 3px 8px rgba(0,0,0,.28); }
.palwin .paltitle { display: flex; align-items: center; height: 24px; padding: 0 2px 0 9px;
                    background: linear-gradient(var(--mp-cap-a), var(--mp-cap-b)); border-bottom: 1px solid var(--mp-edge-2);
                    font-size: 13px; font-weight: 600; color: var(--mp-accent-ink); user-select: none; }
.palwin .paltitle span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis;
                         white-space: nowrap; }
.palwin .palx { flex: none; width: 22px; height: 20px; padding: 0; border: 1px solid transparent;
                background: none; color: var(--mp-ink-3); font-size: 14px; line-height: 1; cursor: default; }
.palwin .palx:hover { background: var(--mp-close-bg); border-color: var(--mp-err); color: var(--mp-on-accent); }
.palwin .palbody { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
                   gap: 2px; padding: 5px; }
.palwin .palit { display: flex; align-items: center; justify-content: center; gap: 4px;
                 min-width: 0; min-height: 24px; padding: 3px 4px;
                 font-family: Consolas, 'Courier New', monospace;
                 font-size: 12px; color: var(--mp-accent-ink); background: var(--mp-field-alt); border: 1px solid var(--mp-edge-lt);
                 cursor: default; }
.palwin .palit > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.palwin .palit:hover { background: var(--mp-hover); border-color: var(--mp-accent-bd); }
.palwin .palit:active { background: var(--mp-sel-2); }
.palwin .palit.wide { grid-column: span 2; }
.palwin .palhr { grid-column: span 2; min-width: 0; height: 1px; margin: 3px 1px; background: var(--mp-edge-lt); }

/* 矩阵尺寸选择器（矩阵面板最上面那块）：手填行列数 + 网格拖选 */
.palwin .mgr { grid-column: 1 / -1; min-width: 0; padding: 2px 4px 6px; margin-bottom: 4px;
               border-bottom: 1px solid var(--mp-edge-lt); user-select: none; }
.palwin .mgr-top { display: flex; align-items: center; gap: 3px; margin-bottom: 5px;
                   min-width: 0; font-size: 12px; color: var(--mp-ink-2); white-space: nowrap; }
.palwin .mgr-num { flex: none; width: 34px; height: 19px; padding: 0 2px; font-size: 12px;
                   text-align: center; border: 1px solid var(--mp-edge); background: var(--mp-field); color: var(--mp-accent-ink); }
.palwin .mgr-go { flex: none; margin-left: auto; height: 20px; padding: 0 8px; font-size: 12px;
                  border: 1px solid var(--mp-accent-bd); background: linear-gradient(var(--mp-btn-a), var(--mp-btn-b));
                  color: var(--mp-accent-ink); cursor: default; }
.palwin .mgr-go:hover { background: linear-gradient(var(--mp-btn-a), var(--mp-hover-2)); border-color: var(--mp-accent-bd); }
.palwin .mgr-grid { display: grid; gap: 1px; justify-content: start; width: max-content; max-width: 100%; }
.palwin .mgr-cell { width: 15px; height: 13px; background: var(--mp-field); border: 1px solid var(--mp-edge-lt); }
.palwin .mgr-cell.on { background: var(--mp-sel-2); border-color: var(--mp-accent-bd); }
.palwin .mgr-hint { margin-top: 4px; font-size: 12px; color: var(--mp-ink-3); text-align: right; }

/* 工具栏 */
.toolbars { flex: none; background: var(--mp-face); border-bottom: 1px solid var(--mp-edge); }
.tb-row { display: flex; align-items: center; gap: 1px; padding: 2px 4px; min-height: 27px; }
.tb-row + .tb-row { border-top: 1px solid var(--mp-edge-lt); }
.tbtn { width: 23px; height: 22px; padding: 0; display: flex; align-items: center; justify-content: center;
        border: 1px solid transparent; background: none; color: var(--mp-tool-ink); cursor: default; }
.tbtn:hover { border-color: var(--mp-sel-bd); background: var(--mp-sel); }
.tbtn.on { border-color: var(--mp-accent-bd); background: var(--mp-sel-2); }
.tbtn b { font-size: 12px; }
.sep { width: 1px; height: 19px; margin: 0 3px; background: var(--mp-hairline); }
select.tb { height: 21px; font-size: 11.5px; border: 1px solid var(--mp-edge); background: var(--mp-field); }
input.tb[type=color] { width: 24px; height: 21px; padding: 0 1px; border: 1px solid var(--mp-edge);
                       background: var(--mp-field); cursor: pointer; }
.tb-row[data-bold="1"] .tbtn.fmtbold,
.tb-row[data-italic="1"] .tbtn.fmtitalic,
.tb-row[data-underline="1"] .tbtn.fmtunderline { background: var(--mp-sel); }
select.tb.style { width: 118px; }
select.tb.font { width: 132px; }
select.tb.size { width: 48px; }
.num { font-size: 11.5px; padding: 0 3px; color: var(--mp-ink-2); }
.zoom { width: 54px; }

/* 工作区 */
/* ★ 画布"四向无限"（2026-10-08 用户："窗口变化或移动端等场景下，画布右侧变为灰色，
   我希望这个画布是左右上下都无限的，不论窗口大小"）。
   根因：白纸 `.page` 只有**视口**那么宽（块级 width:auto = 父宽），而区域是绝对定位的，
   放在 x=1200 也不会把白纸撑宽 → 文档里靠右的内容一横向滚动，露出来的就是
   `.pagewrap` 的灰底 `#c2c8ce`。手机上视口只有 390px 而示例内容铺到 1000px 开外，
   所以几乎必现；桌面把窗口缩小 / 文档内容较宽时同样会露。
   三条一起做：① 工作区（滚动容器）整块白底 —— 灰底只属于界面外壳，不属于画布；
             ② `.page` 不再画"纸张右边线"（白底上是多余的一道竖线）；
             ③ 白板 `#board` 的 min-width / min-height 跟着内容长（见 reflow），
                窗口变大时仍自动铺满（所以用 min-* 而不是 width/height）。
   ⚠️ 左侧仍保留 13px 内边距（原来那条"纸边"）—— 现在它是**白**的，只是留白，
      区域坐标以白板左上角为原点，删掉它会让所有老文档看起来整体左移，故保留。 */
.workspace { flex: 1; display: flex; min-height: 0; background: var(--mp-paper); }
.pagewrap { flex: 1; overflow: auto; background: var(--mp-paper); padding-left: 13px; min-width: 0; }
.page { position: relative; background: var(--mp-paper); min-height: 100%; }
#board { position: relative; min-height: 1400px; background: var(--mp-paper); cursor: text; }

/* ---------- 公式区（纸面，无框） ---------- */
.wb-r { position: absolute; display: flex; align-items: baseline; flex-wrap: wrap; gap: 0;
        padding: 1px 2px; max-width: 820px; border: 1px solid transparent; border-radius: 1px;
        /* ★ 字体 / 字号 / 颜色 / 高亮 / B I U / 对齐：整块生效，文本区和公式区共用一套变量
           （工具栏改的是 r.fmt，JS 把变量写在区域元素上 —— 所以刷新、导出都留得住）*/
        font-family: var(--mp-font, inherit);
        font-size: var(--mp-size, 13px);
        color: var(--mp-color, inherit);
        font-weight: var(--mp-weight, normal);
        font-style: var(--mp-style, normal);
        text-decoration: var(--mp-deco, none);
        text-align: var(--mp-align, left); }
.wb-r[data-bg="1"] { background: var(--mp-bg); }   /* 高亮：设过才画底色 */
.wb-r:hover, .wb-r.focus { border-color: var(--mp-sel-bd); }
/* 区域右上角那排浮动工具（⠿ ⇄ ⚙ ×），矩阵控制条也住在这一排里。
   ★ 用户 2026-10-01："鼠标往上挪它就没了，隐藏显示的逻辑得和其他组件一致"。
   三条一起做，缺一条就会"断"：
     ① 横跨**整个区域宽度**（left:0;right:-1px + 内容右对齐）：原来只有 right 定位，
        行宽等于内容宽，鼠标在区域左半边往上挪时上面什么都没有 → hover 断掉；
     ② 贴着区域上边框：`top` 是硬编码的，行一高就留缝（缝里既不在区域上也不在工具上）；
        改用 `bottom:100%`（见 .hasmatctl），行不管多高都正好贴着；
     ③ 再加一层 JS 宽限（.toolhover，见 addRegion）：真被瞬时的缝/圆角打断也不闪。 */
.wb-r .tools { position: absolute; top: -15px; left: 0; right: -1px;
               display: none; justify-content: flex-end; gap: 1px; z-index: 5; }
.wb-r:hover .tools, .wb-r.focus .tools, .wb-r.toolhover .tools, .wb-r.matpin .tools { display: flex; }
.wb-r .tools button { border: 1px solid var(--mp-edge); background: var(--mp-field); color: var(--mp-dim-2);
                      font-size: 10px; line-height: 13px; padding: 0 4px; cursor: pointer; }
.wb-r .tools button:hover { color: var(--mp-accent); border-color: var(--mp-accent); }
.wb-r .grip { cursor: move; }
/* 复制 Word 公式按钮：svg 图标与文字按钮对齐；点击后闪一下表示复制成功 */
.wb-r .wcopy svg { display: block; }
.wb-r .wcopy.flash { background: var(--mp-ok-bg); border-color: var(--mp-ok) !important; color: var(--mp-ok) !important; }

/* 空区域：只显示红色 +（Mathcad 逻辑），开始输入才出现方框 */
.wb-r.empty, .wb-r.empty:hover, .wb-r.empty.focus { border-color: transparent !important; }
.wb-r.empty .tools { display: none !important; }
.wb-r.empty math-field { --caret-color: transparent; }

/* ★ 每块宽度（用户 2026-10-03："文本块没外框，文字到一定长度就自动折行，希望自行设置
   每个块的长度"）。
   · 默认无 `data-w` → 保持原来的自动宽度：`max-width:820px`，文字打到这儿就折行；
   · 设过宽度（拖右下角那条拖手 / 格式菜单里选）→ 区域宽度钉死成 inline width，
     `[data-w]` 顺手把 820 的上限摘掉，否则宽的设不上去。 */
.wb-r[data-w] { max-width: none; }
/* 右边缘的宽度拖手：悬停 / 编辑中 / 选中时出现，拖它改块宽，双击恢复自动宽度。
   ⚠️ 它是 absolute 的 —— 不参与 .wb-r 的收缩宽度计算（否则一悬停区域就变宽）。 */
.wb-r .rwgrip { position: absolute; top: 0; bottom: 0; right: -5px; width: 10px;
                cursor: ew-resize; display: none; z-index: 4; }
.wb-r .rwgrip::after { content: ''; position: absolute; top: 3px; bottom: 3px; left: 3px; width: 3px;
                       border-radius: 2px; background: var(--mp-grip); opacity: .5; transition: opacity .12s; }
.wb-r .rwgrip:hover::after { opacity: 1; background: var(--mp-accent); }
.wb-r:hover .rwgrip, .wb-r.focus .rwgrip, .wb-r.toolhover .rwgrip { display: block; }
body.rwresize .wb-r .rwgrip::after { opacity: 1; background: var(--mp-accent); }
body.rwresize { cursor: ew-resize; user-select: none; }
/* 有图形的块：宽度归图形自己的右下角手柄管（setVizSize 钉宽度），这里不显示宽度拖手 */
.wb-r.hasviz .rwgrip { display: none !important; }
/* 还没写内容的公式块：那排工具本来就是隐藏的，宽度拖手也一起藏起来（跟工具行同进同退） */
.wb-r.empty .rwgrip { display: none !important; }
/* 拖动时跟在鼠标旁边的宽度读数（fixed 定位，不占版面、不挡内容） */
.wtip { position: fixed; z-index: 9999; pointer-events: none; background: var(--mp-accent); color: var(--mp-on-accent);
        font: 11px/16px "Microsoft YaHei", Arial, sans-serif; padding: 0 6px; border-radius: 3px;
        box-shadow: 0 1px 4px rgba(0,0,0,.25); }
/* 「格式 › 块宽度 › 自定义…」对话框里的小表单 */
.wdlg { display: flex; flex-direction: column; gap: 6px; }
.wdlg label { font-size: 12px; color: var(--mp-ink-2); }
.wdlg input { font-size: 13px; padding: 3px 6px; border: 1px solid var(--mp-edge); border-radius: 3px; }
.wdlg .hint { font-size: 11px; color: var(--mp-dim-2); line-height: 1.5; }
/* 「编辑 › 复制到其他文档…」：一行一个目标文档 */
.docpick { display: flex; flex-direction: column; gap: 5px; }
.docpick .hint { font-size: 11.5px; color: var(--mp-dim); }
.docpick .docrow { text-align: start; padding: 5px 8px; font-size: 12.5px; cursor: pointer;
                   border: 1px solid var(--mp-edge); border-radius: 3px; background: var(--mp-field-alt); color: var(--mp-ink-2); }
.docpick .docrow:hover { background: var(--mp-sel); border-color: var(--mp-sel-bd); }

math-field {
  display: inline-block; width: auto; min-width: 10px;
  font-size: var(--mp-mathsize, 19px);   /* 字号设置：公式比正文大一号（默认 13 → 19）*/
  padding: 0 2px;
  border: none; background: transparent;
  --caret-color: var(--mp-ink);          /* 深色主题下公式里的光标也得是浅的 */
  --placeholder-color: var(--mp-ph);
}
math-field:focus { outline: none; }
math-field::part(menu-toggle),
math-field::part(virtual-keyboard-toggle) { display: none; }

.res { display: inline-flex; align-items: baseline; flex-wrap: wrap; }
.res math-field { font-size: var(--mp-mathsize, 19px); margin-left: 1px; padding: 0 1px; }
/* ★★ 2026-10-17（用户）：「在结果的右边点击，接着敲箭头」——
   结果框在**没进编辑**时不吃鼠标：点结果 / 结果右边 → 光标落到公式末尾（JS 里那条 .res 处理），
   于是按 Ctrl+. 就能给任何计算结果再挂一根符号运算箭头。
   进入编辑（.focus）后放开，那时结果里的文字要能选、能拖。 */
.wb-r:not(.focus) .res math-field { pointer-events: none; }
/* ★ 编辑这一块时，结果被**接在公式后面**显示（见 mathpad.js 的 resTail）——
   结果区就不要再画一份了，否则屏幕上会出现两个 1/3。 */
.wb-r.withtail .res { display: none; }
/* 空格逐级选中不再用 MathLive 的选区（它会顺手把输入光标藏起来），
   改由 JS 自己算区间 + 下面这个虚线框来画。
   原生高亮只留给鼠标拖选（淡淡的蓝），拖选仍然看得见。 */
math-field { --selection-background-color: var(--mp-sel-tint); --selection-color: inherit;
             --selection-text-color: inherit; }
/* 空格逐级选中时显示的虚线矩形（挂在区域里，跟着内容一起滚动） */
.selbox { position: absolute; z-index: 6; pointer-events: none; display: none;
          border: 1px dashed var(--mp-accent); background: var(--mp-tint); border-radius: 2px; }
/* 框选拖动过程中禁止浏览器原生选中文本（否则页面上会冒出一堆蓝色小方块） */
body.dragging, body.dragging * { user-select: none !important; }
body.dragging math-field::part(keyboard-sink) { user-select: none !important; }

/* MathLive 默认给 container 加 4px、content 加 1~3px 内边距。
   结果紧跟在等号后面时，输入框右侧死区 9px + 结果框左侧死区 6px，
   视觉上等号与结果之间会空出 19px（就是"等号右边一大片空白"）。
   这里把水平内边距收掉（保留上下，分数 / 矩阵不会被裁），实测 19px → 7px，
   刚好是 Mathcad 里一个自然空格。 */
math-field::part(container) { padding: 4px 0 !important; }
math-field::part(content)   { padding: 2px 0 !important; }
.res.def math-field { color: var(--mp-ink-3); }
.res .note { margin-left: 10px; font-size: 11.5px; color: var(--mp-dim); align-self: center; }
/* 结果带单位时可点击换算 */
.res.clickable { cursor: pointer; border-radius: 2px; }
.res.clickable:hover { background: var(--mp-hover); box-shadow: inset 0 -1px 0 #a8c0e0; }
/* 单位换算菜单 */
.unitmenu { min-width: 386px; max-width: 452px; padding: 6px 8px 8px; max-height: 76vh; overflow: auto; }
.unitmenu .uhd { font-size: 11.5px; color: var(--mp-ink-3); margin: 2px 0 5px; }
.unitmenu .uin { width: 100%; height: 23px; border: 1px solid var(--mp-edge-3); background: var(--mp-field);
                 font-size: 12.5px; padding: 0 6px; margin-bottom: 6px; }
.unitmenu .ugrid { display: flex; flex-wrap: wrap; gap: 3px; margin-bottom: 6px; }
.unitmenu .ubtn { min-width: 44px; height: 22px; padding: 0 8px; border: 1px solid var(--mp-edge);
                  background: linear-gradient(var(--mp-btn-a), var(--mp-btn-b)); font-size: 12.5px; cursor: default; }
.unitmenu .ubtn:hover { background: linear-gradient(var(--mp-btn-a), var(--mp-hover-2)); border-color: var(--mp-accent-bd); }
.unitmenu .ubtn.on { background: var(--mp-sel-2); border-color: var(--mp-accent-bd); font-weight: 600; }
/* —— 复合单位构造器：分子一排因子 + 分母一排因子（分式 / 乘积 / 混合都靠它）—— */
.unitmenu .ubuild { border-top: 1px solid var(--mp-edge-lt); padding-top: 6px; margin-bottom: 8px; }
.unitmenu .ubh { font-size: 11.5px; color: var(--mp-ink-3); margin-bottom: 5px; }
.unitmenu .ubrow { display: flex; align-items: center; gap: 4px; }
.unitmenu .uslots { display: flex; flex-wrap: wrap; gap: 4px; flex: 1; min-height: 22px; align-items: center; }
.unitmenu .ubar { height: 1px; background: var(--mp-rule); margin: 4px 0; }
.unitmenu .uslot { display: inline-flex; align-items: center; gap: 2px; }
.unitmenu .uslot select { height: 22px; border: 1px solid var(--mp-edge); background: var(--mp-field);
                          font-size: 12px; padding: 0 2px; max-width: 106px; }
.unitmenu .uslot .uexp { max-width: 48px; font-size: 11px; color: var(--mp-ink-3); }
.unitmenu .uslot .udel { width: 16px; height: 22px; padding: 0; border: none; background: none;
                         color: var(--mp-dim-2); font-size: 13px; line-height: 22px; cursor: default; }
.unitmenu .uslot .udel:hover { color: var(--mp-err); }
.unitmenu .uadd { width: 22px; height: 22px; flex: none; border: 1px dashed var(--mp-edge); background: var(--mp-field);
                  color: var(--mp-ink-3); font-size: 13px; line-height: 20px; padding: 0; cursor: default; }
.unitmenu .uadd:hover { border-color: var(--mp-accent-bd); color: var(--mp-accent-ink); background: var(--mp-hover); }
.unitmenu .uempty { font-size: 12px; color: var(--mp-dim-2); }
.unitmenu .ubout { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-top: 6px; }
.unitmenu .ucode { font-size: 13px; font-weight: 600; color: var(--mp-accent-ink); }
.unitmenu .uok { font-size: 11.5px; color: var(--mp-ok); }
.unitmenu .ubad { font-size: 11.5px; color: var(--mp-err); }
.unitmenu .ufac { font-size: 11.5px; color: var(--mp-ink-3); }
.unitmenu .uapply { margin-left: auto; height: 22px; padding: 0 10px; border: 1px solid var(--mp-accent-bd);
                    background: var(--mp-hover); font-size: 12px; cursor: default; }
.unitmenu .uapply:hover { background: var(--mp-hover-2); }
.wb-r .tools .uni { display: none; }
.wb-r.hasunit .tools .uni { display: block; }
/* ★★ 区域里的提示统一成同一种"横幅"样式（用户 2026-10-03 要求）：
   红字报错 与 琥珀色的「前面已经定义过」长得**完全一样** —— 同字号、同内边距、
   左边同一条竖线；**只有颜色不同**（红色还是红色、琥珀色还是琥珀色）。
   以后再加提示就往这两条上靠，别再各写一套。 */
.err, .redefnote {
  flex-basis: 100%; margin-top: 3px; font-size: 11.5px; line-height: 1.5;
  border-inline-start: 3px solid transparent; border-radius: 3px; padding: 3px 7px;
}
.err { color: var(--mp-err); background: var(--mp-err-bg); border-inline-start-color: var(--mp-err); }
.err:empty { display: none; }
/* 「同名函数被重新定义」的提示：琥珀色。不是错误（式子算得出来），但必须看得见 ——
   否则上面那些引用旧定义的式子突然坏掉，无从解释。 */
.redefnote { color: var(--mp-warn); background: var(--mp-warn-bg); border-inline-start-color: var(--mp-warn-bd); }
/* ★ 「视图 › 报错信息」关掉后：区域里的红字报错**和那条琥珀色提示**都不显示
   （用户 2026-10-03：截图给的正是 `⚠ f 前面已经定义过（1 处）` 这条 —— 在用户眼里
   它就是一条报错信息，必须跟着开关走）。
   只是**不看**，该记的账照记（作废下游 / 确认遍都不受影响），打开开关立刻回来。 */
body.errhide .err,
body.errhide .redefnote { display: none !important; }

.wb-text { font-size: inherit; line-height: 1.5; min-width: 90px; min-height: 19px;
           padding: 0 2px; outline: none; font-family: inherit; color: inherit; }
.wb-text code { font-family: Consolas, monospace; font-size: .94em; background: var(--mp-field-alt);
                border-radius: 2px; padding: 0 3px; }
.wb-text:empty::before { content: '文本…'; color: var(--mp-ph); }

/* 红色 + 插入光标（Mathcad 的标志性提示） */
.plusmark { position: absolute; color: var(--mp-plus); font: 700 17px/17px Arial, sans-serif;
            pointer-events: none; display: none; }

/* 右侧数学符号面板 */
.mathpal { flex: none; width: 70px; background: var(--mp-face); border-left: 1px solid var(--mp-edge);
           overflow-y: auto; padding: 2px 0; }
.mp-grp { display: flex; flex-wrap: wrap; gap: 1px; padding: 2px 3px; border-bottom: 1px solid var(--mp-edge-lt); }
.mp-grp button { width: 22px; height: 19px; padding: 0; border: 1px solid transparent; background: none;
                 font: 13px 'Cambria Math', 'Times New Roman', serif; color: var(--mp-sym-ink); cursor: default; }
.mp-grp button.wide { width: 44px; font: 9.5px 'Microsoft YaHei', Arial, sans-serif; }
.mp-grp button:hover { border-color: var(--mp-sel-bd); background: var(--mp-sel); }
/* 绘图按钮：彩色小图 + 短标签 */
.mp-plot { gap: 2px 2px; }
.mp-plot button.pbtn { width: 31px; height: 41px; display: flex; flex-direction: column;
                       align-items: center; justify-content: flex-start; gap: 1px; padding: 2px 0 0;
                       border: 1px solid transparent; background: none; cursor: default; }
.mp-plot button.pbtn span { font: 9px 'Microsoft YaHei', Arial, sans-serif; color: var(--mp-ink-2);
                            line-height: 10px; white-space: nowrap; }
.mp-plot button.pbtn:hover { border-color: var(--mp-sel-bd); background: var(--mp-sel); }
.mp-plot button.pbtn svg { display: block; }

/* 状态栏 */
.statusbar { flex: none; height: 22px; display: flex; align-items: center; gap: 10px;
             padding: 0 8px; background: var(--mp-face); border-top: 1px solid var(--mp-edge);
             font-size: 12px; color: var(--mp-ink-2); }
.statusbar .spacer { flex: 1; }
.statusbar .eng { color: var(--mp-dim); font-size: 11px; }

/* ★ 计算状态指示（2026-10-04）：以前是 forceRecalcAll 里一句定时 toast，
   算完 43ms 还挂 2.6s、真算 8s 又提前消失 —— 现在**状态驱动**（见 busyBegin/busyEnd），
   亮着的每一刻都真在算，熄灭的那一下就是算完。后面的秒数是实时刷新的。 */
#busy { display: inline-flex; align-items: center; gap: 5px;
        color: var(--mp-warn); font-size: 12px; white-space: nowrap; }
#busy[hidden] { display: none !important; }
#busy .bz-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--mp-spark);
                animation: bzpulse 1s ease-in-out infinite; }
#busy .bz-t { font-variant-numeric: tabular-nums; }
@keyframes bzpulse { 0%, 100% { opacity: .25; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { #busy .bz-dot { animation: none; opacity: 1; } }
/* 正在算的时候，⚡ 那一格里的数字是**上一潮**的结果（本潮要跑完才结账）——
   压暗一点，免得跟旁边的"正在重新计算… 1.3 s"看着像同一件事、又互相矛盾。 */
#perfchip.stale { opacity: .45; }
/* ★ 「强制停止所有计算」的暂停态（2026-10-06）：状态栏那行换成**灰色静止方块**
   （不再跳），工具栏上的"停止"按钮点亮 —— 一眼看出"现在不算了，随便改"。 */
#busy .bz-dot.bz-pause { background: var(--mp-paused); border-radius: 2px;
                         animation: none; opacity: 1; }
body.paused #busy { color: var(--mp-ink-3); }
body.paused .tbtn[data-ic="stop"] { background: rgba(123,135,148,.20);
                                    box-shadow: inset 0 0 0 1px rgba(123,135,148,.55); }

/* 性能状态条（2026-10-03 改版）：总计 · 一根两段比例条 · 引擎 / 前端 · 块数。
   三个数字一起看才知道瓶颈在哪，单靠一根比例条或一堆数字都不好读。 */
#perfchip { display: inline-flex; align-items: center; gap: 6px; font-size: 11px;
            color: var(--mp-dim); cursor: default; user-select: none; }
#perfchip .pc-i { color: var(--mp-spark2); font-size: 12px; line-height: 1; }
#perfchip .pc-tot { color: var(--mp-ink-2); font-weight: 600; font-variant-numeric: tabular-nums; }
#perfchip .pc-bar { display: inline-flex; width: 52px; height: 7px; border-radius: 4px;
                    overflow: hidden; background: var(--mp-track-bg); box-shadow: inset 0 0 0 1px rgba(0,0,0,.05); }
#perfchip .pc-bar i { display: block; height: 100%; }
#perfchip .pc-e { background: linear-gradient(180deg,var(--mp-bar-eng-a),var(--mp-bar-eng-b)); }
#perfchip .pc-f { background: linear-gradient(180deg,var(--mp-bar-fe-a),var(--mp-bar-fe-b)); }
#perfchip .pc-eng, #perfchip .pc-front, #perfchip .pc-blk { font-variant-numeric: tabular-nums; white-space: nowrap; }
#perfchip .pc-eng { color: var(--mp-accent); }
#perfchip .pc-front { color: var(--mp-warn-2); }
#perfchip .pc-blk::before { content: '·'; margin-right: 4px; color: var(--mp-edge); }
#perfchip .pc-dim { color: var(--mp-dim); }

/* 社区对话框（2026-10-03）：浏览 / 上传 / 我的分享 三个页签 */
.comwrap { display: flex; flex-direction: column; gap: 9px; font-size: 12.5px; color: var(--mp-ink-2); }
.comtabs { display: flex; gap: 2px; border-bottom: 1px solid var(--mp-edge); }
.comtab { padding: 5px 14px; cursor: default; border: 1px solid transparent; border-bottom: none;
          border-radius: 4px 4px 0 0; color: var(--mp-ink-3); margin-bottom: -1px; }
.comtab:hover { background: var(--mp-hover); }
.comtab.on { background: var(--mp-face); border-color: var(--mp-edge); border-bottom: 1px solid var(--mp-face);
             color: var(--mp-accent-ink); font-weight: 600; }
.companel { min-height: 180px; display: flex; flex-direction: column; gap: 8px; }
.comsearch { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.cominq, .comsel, .cominta { border: 1px solid var(--mp-edge-3); background: var(--mp-field); font-size: 12.5px;
                             height: 22px; padding: 0 6px; border-radius: 3px; min-width: 0; }
.cominq { flex: 1 1 200px; }
.comsel { height: 24px; }
.cominta { height: auto; padding: 4px 6px; font-family: inherit; resize: vertical; }
.combtn { border: 1px solid var(--mp-edge-3); background: linear-gradient(180deg,var(--mp-btn-a),var(--mp-btn-b));
          font-size: 12px; height: 23px; padding: 0 10px; border-radius: 3px; cursor: default; }
.combtn:hover { background: var(--mp-hover); border-color: var(--mp-accent-bd); }
.combtn.main { background: linear-gradient(180deg,var(--mp-btn-main-a),var(--mp-btn-main-b)); border-color: var(--mp-accent-bd); font-weight: 600; }
.combtn.danger:hover { background: var(--mp-err-bg); border-color: var(--mp-err); }
.comlist { border: 1px solid var(--mp-edge); border-radius: 4px; max-height: 320px; overflow: auto;
           padding: 6px; display: flex; flex-direction: column; gap: 6px; background: var(--mp-field-alt); }
.comitem { border: 1px solid var(--mp-edge); border-radius: 4px; background: var(--mp-field); padding: 7px 9px;
           display: flex; flex-direction: column; gap: 4px; }
.comitem:hover { border-color: var(--mp-accent-bd); }
.comhead { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.comtitle { font-size: 13px; }
.comtag { background: var(--mp-hover); border: 1px solid var(--mp-accent-lt); color: var(--mp-accent-ink); border-radius: 9px;
          padding: 0 7px; font-size: 11px; line-height: 16px; }
.comdesc { color: var(--mp-ink-3); }
.commeta { color: var(--mp-dim); font-size: 11.5px; }
.comacts { display: flex; gap: 6px; flex-wrap: wrap; }
.comfoot { color: var(--mp-dim); font-size: 11.5px; padding: 2px 4px; display: flex; align-items: center; gap: 8px; }
.comform { display: flex; flex-direction: column; gap: 6px; }
.comfld { display: flex; align-items: center; gap: 8px; }
.comfld > label { flex: 0 0 62px; color: var(--mp-ink-3); }
.comfld > .cominq, .comfld > .cominta { flex: 1 1 auto; }
.comcheck { display: flex; align-items: center; gap: 7px; }
.comnotice { border: 1px solid var(--mp-edge); border-radius: 4px; background: var(--mp-field-alt);
             padding: 8px 10px; color: var(--mp-ink-3); line-height: 1.65; }
.comnotice.warn { background: var(--mp-warn-bg); border-color: var(--mp-warn-bd); color: var(--mp-warn); }
.comnotice.ok { background: var(--mp-ok-bg); border-color: var(--mp-ok); color: var(--mp-ok); }
.comtip { line-height: 1.65; background: var(--mp-hover); border: 1px solid var(--mp-accent-lt); border-radius: 4px; padding: 8px 10px; }
.comtip b { color: var(--mp-accent-ink); }
.comnote { color: var(--mp-dim); font-size: 12px; line-height: 1.7; border-top: 1px dashed var(--mp-edge); padding-top: 7px; }
.comnote b { color: var(--mp-ink-2); }

/* ---------- 快捷键一览（帮助 › 快捷键一览，2026-10-08） ----------
   纯展示面板：两列网格，一组一块，组内一行「键帽 + 功能」。
   ⚠️ 不加 max-height —— 滚动交给 `.modal > .body`（那里已经有 overflow:auto），
      两层滚动条既难看又难滚。 */
.scgrid { display: grid; grid-template-columns: 1fr 1fr; gap: 4px 22px; align-items: start; }
.scgrp { margin-bottom: 8px; }
.sch { font-weight: 600; color: var(--mp-accent-ink); border-bottom: 1px solid var(--mp-accent-lt);
       padding: 0 0 2px; margin-bottom: 4px; font-size: 12.5px; }
.scrow { display: flex; align-items: baseline; gap: 8px; padding: 1px 0; line-height: 18px; }
/* 键帽列固定宽度 → 两列里功能文字自然对齐 */
.scrow .kk { flex: none; width: 150px; display: flex; flex-wrap: wrap; gap: 3px; }
.scrow kbd { font: 11px Consolas, "Courier New", monospace; background: var(--mp-field-alt);
             border: 1px solid var(--mp-edge-2); border-bottom-width: 2px; border-radius: 3px;
             padding: 0 4px; color: var(--mp-ink-2); white-space: nowrap; }
.scrow .dd { flex: 1; min-width: 0; color: var(--mp-ink-2); font-size: 12.5px; }
/* 窄屏（手机上对话框被压到视口宽）→ 收成一列，否则两列每列不到 150px、键帽全折行 */
@media (max-width: 860px) { .scgrid { grid-template-columns: 1fr; } }

@media print {
  /* ============================================================ 打印（2026-10-16 重做）
     用户原话："还是不一致，你自己模拟实测一下。并且打印预览有问题到，我原文本区块里面可能
     设置了字体颜色、背景颜色等，打印预览全都看不见了，都成黑白了，这不行。
     打印预览必须与原始文档完全相同"

     ★ 颜色：这版**一条都不覆盖**。上一版这里强制 `#fff` 底 + `#000` 字 —— 那会把用户在
       文本块里设的字体色、背景色（`--mp-color` / `--mp-bg`）全抹掉，用户看到的就是全黑白。
       背景要真能打出来还得靠下面那条 `print-color-adjust: exact`：Chrome 默认是
       `economy`，会把所有背景色悄悄丢掉。

     ★ 分页：屏幕白板的 (0,0) 就是纸上**内容区**左上角（实测：各层容器 margin/padding/
       border 全 0，`#board` 正好落在 (0,0)）。所以分页线不需要任何偏移，第 n 条横线
       在 y = n × cellH 处，cellH = paperH / z − 2·边距（见下面"缩放"那段 —— **边距不吃 zoom**，
       ⚠️ 老写法 `可用高 ÷ z` 是错的，实测每页上飘 2·mg·(1−z)/z）。

     ★ 版面宽：由 JS 写进 `--print-body-w`，而且**必须是纸的可用宽**（不是内容宽）。
       ⚠️ 2026-10-16 找到的病根：以前写的是 `m.LW`（= max(纸的可用宽, **内容右边界**)），
       实测 1592px，而 A4 只有 794px 宽 → body 比纸宽一倍 → Chrome 触发「整页缩小以适配宽度」，
       打印比例就不是 1:1 了，屏幕上的分页格无论怎么算都对不上。
     ★ 2026-10-16 同时**删掉 `html{zoom: var(--print-zoom)}`**：方案 A 之后缩放恒为 1，
       那条已经是死代码；而且 `zoom` 会把「页面盒子」变成 纸 ÷ 缩放 − 边距，
       又多一层可能和屏幕算不一致的换算。现在打印侧**不做任何缩放**：屏幕画什么、纸上就是什么。 */

  /* 界面 chrome 一律不出现（用户截图里那行就是漏掉的 `.tabbar`） */
  .titlebar, .menubar, .tabbar, .toolbars, .statusbar, .mathpal, .tools, .plusmark, .modal,
  .palwin, .selbox, #pagelines, #pagebadge { display: none !important; }

  /* 高度链全部放开成"按内容流分页"：
     ⚠️ 屏幕上 html/body 是 height:100%（视口高）、.app/.workspace/.pagewrap/.page 是 flex 链
        （高度塌成 0）—— 不放开的话整篇内容被压在"一屏"里，Chrome 会把溢出的块拆成一堆页。 */
  html, body { height: auto !important; min-height: 0 !important; margin: 0 !important;
    padding: 0 !important; border: 0 !important; overflow: visible !important; }
  .app, .workspace, .pagewrap, .page {
    height: auto !important; min-height: 0 !important; flex: none !important;
    overflow: visible !important; margin: 0 !important; padding: 0 !important; border: 0 !important; }

  /* ★★ 2026-10-17 实测定位：**文档宽度必须等于纸的可用宽**，否则 Chrome 整篇等比缩小。
    病根：以前这里写的是 `width: var(--print-body-w)` = 内容宽（实测 1077px，纸只有 718px），
    Chrome 就按 718/1077 = 0.667 把整页缩小 —— 于是**一页能装的内容从 1047px 变成 1570px**，
    屏幕分页线（按 1047 画）和打印预览（实际 1570 一页）当然对不上。
    实测证据：dev/tmp/print_sample.pdf 里 cm 是 2.0833（= 0.5pt/px，本该 0.75）、
    每页内容流第一句是 `0 0 1077 1570 re`（白底 1077×1570，而 cellH = 1047）。
    ★ 但**不能**把 body 压窄了就不管块 —— 用户明确要求"不折行、右边硬截断"：
    块的排版宽度由 #board 撑开（见下面 `#board{width:var(--print-body-w)}`），
    超出的部分由 .page 的 overflow:hidden 裁掉。两层分工，谁也不影响谁。 */
  /* ★★ 打印缩放（2026-10-17 方案 C「适应纸宽」）：默认 --print-zoom = 1（不缩放）。
     开了设置项时 z < 1，整篇等比缩小 → 内容比纸宽也不会被裁/不会被 Chrome 二次 shrink。
     ⚠️ 为什么边距不吃 zoom、格子却按 paperW/z − 2mg 算：Chrome 是拿「整张纸 ÷ 缩放」再
        **减去没缩放的边距**当页面盒子（实测 19 组 z 残差 ≤ 0.4pt，见 pageMetrics 的说明）。
       所以打印出来的实际边距 = 10mm × z，格子的 cellW/cellH 也必须按同一个 z 算 ——
        两边只要有一个不是这个 z，第 2 页就整体上飘 2·mg·(1−z)/z（z=0.542 时差 65px）。
     ⚠️ body/.page/#board 的宽度写的是 cellW（**缩放前**坐标），乘上 z 之后正好 = 纸宽 − 2mg·z，
        所以 Chrome 不会再来一次 shrink-to-fit；别再把它改成 LW。 */
  html { zoom: var(--print-zoom, 1) !important; }
  body { width: var(--print-cell-w, auto) !important; }
  /* ⚠️ .page 只裁**横向**，竖向必须留着让内容自己流到下一页：
     overflow:hidden 会把它变成滚动容器、块高被压成一页（实测 page1 塞满、page2–5 全空白）。
     overflow-x: clip + overflow-y: visible 是唯一既能横裁又不动竖排的组合
     （CSS 规定 visible/clip 这一对不互相降级成 auto）。合成实验 dev/tmp/shrink_test3.cjs
     四组对照：缩放都回到 3.125 = 0.75pt/px（不缩小）、页数正确。 */
  .page { width: var(--print-cell-w, auto) !important;
          overflow-x: clip !important; overflow-y: visible !important;
          /* ★★ 2026-10-17 真凶：`.page` 上带着用户界面的缩放（mathpad.js 的 setZoom → .page.style.zoom = z）。
             屏幕缩放到 150% 时，打印出来的内容也是 1.5 倍，Chrome 于是把整篇缩到 0.667 倍去适配
             → 一页能装 1570px 而不是 1047px，屏幕分页线和打印预览必然错位。
             打印必须按 board 坐标 1:1 出纸（方案 A 里分页线就是按未缩放坐标画的），所以这里强制归 1。 */
          zoom: 1 !important; }

  /* ⚠️ `#board` **故意不写 height:auto** —— 它的孩子全是绝对定位（撑不开父元素，高度算 0），
     真实高度由 JS（boardHeightSync）按内容算好、并收在整页边界上，写在 inline style 里。
     写 auto 会把那个高度冲掉 → board 变回 0 高 → Chrome 把每个块当溢出片段各占一页。 */
  /* ★ 2026-10-17 试：让 #board 自己就等于纸宽、并裁掉右边超出的块。
     理由：只要文档里还有任何元素比纸宽，Chrome 就整篇 shrink-to-fit（实测 0.7008 倍）。
     裁在 #board 上（而不是 .page）是因为 board 的 height 由 JS 写成整页边界，
     纵向裁不到内容；横向裁掉的部分正是屏幕上已经出纸的那部分，两边一致。 */
  #board { height: auto; min-height: 0 !important; min-width: 0 !important;
           width: var(--print-cell-w, auto) !important; max-width: none !important;
           overflow: hidden !important;
           /* ★★ 2026-10-17 最终定位（可靠度量：打印 PDF 首页内容流首个 cm ÷ 3.125，1=1:1）：
              #board 本身（不是某个块）就是 shrink-to-fit 的宽来源 —— 把 #board 的**所有子元素**
              都 display:none 之后，缩放依然是 0.84~0.67；只有加 contain:size 才回到 1:1。
              原因：contain:size 让 #board 对"自动尺寸"的计算当成空元素（内容不参与其固有尺寸），
              Chrome 就不再拿它内部的固有宽去做 fit 计算。实测：全文档 baseline rel=0.6667、
              4 页；加 contain:size 后 rel=1、6 页 = 屏幕分页行数，1:1 恢复。
              安全性：contain:size 需要显式尺寸，而 #board 的宽由上行给定（=纸可用宽）、
              高由 JS（boardHeightSync）写进 inline style（绝对定位的孩子撑不开父元素），
              所以这里不会塌成 0 高。⚠️ 不要给 #board 写 height:auto 之外的值覆盖 inline 高度。 */
           contain: size layout paint !important; }

  /* ★★ 页底 = 纸（含 10mm 打印边距那圈）；用 --mp-paper 而不是写死 #fff，
     这样**屏幕上看到什么样、打出来就是什么样**（深色主题也就是深色纸）。 */
  html, body, .app, .workspace, .pagewrap, .page, #board {
    background: var(--mp-paper) !important; display: block;
    -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  /* 用户设的字体色 / 背景色 / 高亮一律照打（Chrome 默认会把背景丢掉） */
  *, *::before, *::after {
    -webkit-print-color-adjust: exact !important; print-color-adjust: exact !important; }

  .pagewrap { padding: 0 !important; }
  /* 只去掉"编辑期"才该有的框线，**保留**用户设的底色（那由 .wb-r[data-bg] 给） */
  .wb-r { border-color: transparent !important; }
}

/* 分页线提示牌（2026-10-16）：只在「显示分页线」打开时出现，写清当前纸张 / 方向 /
   **打印缩放**（内容比纸宽时打印会整体等比缩小；不说清楚用户会以为格子画错了）。
   纯界面元素：不吃点击（pointer-events:none），打印时也隐藏（见上面那条）。 */
#pagebadge { position: fixed; right: 12px; bottom: 34px; z-index: 60; pointer-events: none;
  padding: 2px 8px; font-size: 11px; line-height: 16px; white-space: nowrap;
  color: var(--mp-dim); background: var(--mp-field);
  border: 1px solid var(--mp-edge-2); border-radius: 3px; }

/* ============================== 对话框（插入函数 / 希腊字母） ============================== */
.mask { position: fixed; inset: 0; background: var(--mp-veil); z-index: 400; }
.modal { position: fixed; z-index: 401; background: var(--mp-face); border: 1px solid var(--mp-edge-3);
         box-shadow: 3px 4px 14px rgba(0,0,0,.3); font-size: 12.5px;
         max-width: calc(100vw - 16px); max-height: calc(100vh - 16px);
         display: flex; flex-direction: column; }
.modal > .body { overflow: auto; padding: 10px; min-height: 0; }
.modal .cap { display: flex; align-items: center; height: 27px; padding: 0 4px 0 8px;
              background: linear-gradient(var(--mp-cap-a), var(--mp-cap-b)); border-bottom: 1px solid var(--mp-title-edge);
              color: var(--mp-title-ink); font-weight: 600; flex: none; overflow: hidden; }
.modal .cap span { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.modal .cap .x { margin-left: auto; width: 26px; height: 19px; border: 1px solid transparent;
                 background: none; color: var(--mp-ink-3); font-size: 12px; cursor: default; }
.modal .cap .x:hover { background: var(--mp-err-bg); border-color: var(--mp-err); }
.modal .body { padding: 10px 12px; overflow: auto; min-height: 0; }
.modal .cols { display: flex; gap: 12px; align-items: flex-start; }
.modal .fld { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.modal .fld > span { color: var(--mp-ink-2); }
/* 函数 / 单位对话框：左列固定、右列自适应，条目过长就省略号，绝不撑出窗口 */
.modal .cols .fld:first-child { flex: 0 0 132px; }
.modal .cols .fld:last-child { flex: 1 1 auto; }
.modal select { border: 1px solid var(--mp-edge-3); background: var(--mp-field); font-size: 12.5px; height: 20px; }
.modal .cat { width: 130px; }
.modal .fn { width: 168px; }
.modal .list { border: 1px solid var(--mp-edge-3); background: var(--mp-field); overflow: auto; min-width: 0; }
/* ★ 行高固定 20px：容器高度必须是它的**整数倍**，否则最后一行被切掉一半
   （用户看到的"列表乱了"就是这么来的）。.list.tall ＝ 20×13 + 上下 1px 边框 = 262px。 */
.modal .list .it { height: 20px; line-height: 18px; padding: 0 8px; cursor: default;
                   font-size: 12.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.modal .list.tall { height: 262px; }
/* 筛选框：占对话框最上面一整行。⚠️ 别塞进右列 —— 右列会整体下移，两列顶端就错开了。 */
.modal .fsearch { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.modal .fsearch input { flex: 1 1 auto; min-width: 0; height: 22px; padding: 0 6px;
                        border: 1px solid var(--mp-edge-3); background: var(--mp-field); font-size: 12.5px; color: var(--mp-title-ink); }
.modal .fsearch input:focus { outline: none; border-color: var(--mp-accent-bd); }
.modal .fsearch .fcnt { flex: none; font-size: 11.5px; color: var(--mp-ink-3); white-space: nowrap; }
.modal .list .it:hover { background: var(--mp-hover); }
.modal .list .it.sel { background: var(--mp-accent-strong); color: var(--mp-on-accent); }
.modal .sig { margin-top: 10px; padding: 4px 7px; border: 1px solid var(--mp-edge-2); background: var(--mp-field);
              font-family: Consolas, monospace; font-size: 12px; line-height: 1.55;
              white-space: pre-line; color: var(--mp-accent-ink);
              max-height: 132px; overflow: auto; }   /* 用法是一行一种写法，条数多的要能滚 */
.modal .desc { margin-top: 6px; padding: 5px 6px; border: 1px solid var(--mp-edge-2); background: var(--mp-field);
               height: 84px; overflow: auto; color: var(--mp-ink-2); line-height: 1.5; }
.modal .bar { display: flex; gap: 8px; margin-top: 10px; align-items: center; }
.modal .bar .sp { flex: 1; }
.modal .bar button { min-width: 76px; height: 23px; border: 1px solid var(--mp-edge-3); background: linear-gradient(var(--mp-btn-a),var(--mp-btn-b));
                     font-size: 12.5px; cursor: default; }
.modal .bar button:hover { background: linear-gradient(var(--mp-btn-a),var(--mp-hover-2)); border-color: var(--mp-accent-bd); }
.modal .bar button.help { min-width: 30px; }

/* 希腊字母：四列表格（输入 | 大写 | 小写 | 英文名） */
.gk-box { display: inline-block; }
.gk-head, .gk-row { display: grid; grid-template-columns: 56px 56px 56px 74px; align-items: center; }
.gk-head { border-bottom: 1px solid var(--mp-edge-2); padding-bottom: 3px; margin-bottom: 3px; }
.gk-head span { font-size: 11.5px; color: var(--mp-ink-3); text-align: center; }
.gk-table { max-height: 58vh; overflow: auto; }
.gk-row + .gk-row { border-top: 1px solid var(--mp-edge-lt); }
.gk-row button { height: 19px; border: 1px solid transparent; background: none; cursor: default;
                 font: 15px 'Cambria Math', 'Times New Roman', serif; color: var(--mp-accent-ink); }
.gk-row button:hover { background: var(--mp-sel); border-color: var(--mp-sel-bd); }
.gk-row button.key { font: 11px Arial, sans-serif; color: var(--mp-dim-2); }
.gk-row .name { font: 11.5px Arial, sans-serif; color: var(--mp-ink-3); text-align: center; }

/* 数学符号条上的按钮（:= ≤ ≥ 之类略宽一点） */
.tbtn.sym { width: 24px; }
.tbtn.sym b { font-size: 12.5px; font-weight: 400; color: var(--mp-sym-ink); }

/* 框选：橡皮筋 + 选中区域的高亮 */
#marquee { position: absolute; display: none; z-index: 9; border: 1px solid var(--mp-accent-bd);
           background: var(--mp-tint-2); pointer-events: none; }
/* ★ 粘贴落点光标（用户 2026-10-04："鼠标点击某处后按 Ctrl+V 在指定位置粘贴"）：
   点白板空白处 → 这里竖一条带横头的小插入光标，闪烁提示"待会儿会粘在这儿"。
   ⚠️ pointer-events:none 是关键：否则光标会挡住白板的空白点击，落点再也改不了。 */
#pastecaret { position: absolute; display: none; z-index: 8; pointer-events: none;
              width: 2px; height: 20px; margin-left: -1px; background: var(--mp-caret);
              animation: pcblink 1.1s steps(1, end) infinite; }
#pastecaret::before, #pastecaret::after { content: ''; position: absolute; left: -3px;
              width: 8px; height: 3px; background: var(--mp-caret); }
#pastecaret::before { top: 0; }
#pastecaret::after  { bottom: 0; }
@keyframes pcblink { 0%, 55% { opacity: 1; } 56%, 100% { opacity: .3; } }
/* 框选中的区域：用虚线框标出来（不要蓝色填充——几十个区域一起填充会变成"一堆蓝色小格子"） */
.wb-r.sel { background: transparent; border-color: var(--mp-accent-bd); border-style: dashed; }
.wb-r.sel .tools { display: flex; }
.assumerow { display: flex; gap: 6px; align-items: center; margin-bottom: 5px; }
.assumerow input, .assumerow select { border: 1px solid var(--mp-edge); background: var(--mp-field);
  height: 21px; font-size: 12px; }
.assumerow input.var { width: 62px; }
.assumerow input.var.free { width: 62px; }
/* ★ 变量改成下拉（2026-10-11）：宽一点，希腊字形（λ / ϕ）也要放得下 */
.assumerow select.var { width: 92px; max-width: 140px; }
.assumerow select.var option { font-size: 12px; }
.assumerow input.val { width: 84px; }
.assumerow button { width: 20px; height: 21px; border: 1px solid var(--mp-edge); background: var(--mp-field); cursor: default; }
.assumerow button:hover { background: var(--mp-hover); border-color: var(--mp-accent-bd); }
.assume-hint { font-size: 11.5px; color: var(--mp-ink-3); margin: 4px 0 6px; line-height: 1.5; }
/* 图形/图像外面套一层占满整行的容器。
   ⚠️ 为什么需要它：.wb-r 是 flex 行容器，早先用 `.plotbox{flex-basis:100%}` 让图"独占一行"，
      但 flex-basis 会**盖过 width**（computed width 一直是容器宽度，不是 560px），
      于是左右拖动改宽度完全无效 —— 用户报的"只能上下拉伸，不能左右拉伸"就是这个。
      套一层 flex-basis:100% 的 wrapper，里面的盒子就是普通块级元素，width 说了算。 */
.wb-r > .vizrow { flex-basis: 100%; width: 100%; min-width: 0; margin-top: 4px;
                  display: flex; flex-wrap: nowrap; align-items: flex-start; }
.plotbox { width: 560px; max-width: 100%; position: relative; flex: 0 0 auto; }
.plotbox .ph { font-size: 11.5px; color: var(--mp-dim-2); padding: 4px 2px; }

/* 绘图参数滑块框（2026-10-03 用户要求）：图形框**右侧**，按曲线分组，
   边框颜色跟曲线一致，框头是曲线名（f(x)），下面每个未定义参数一根滑块；
   右上角 ⚙ 设这一组参数的滑块范围。
   ★★ 竖排一列（用户 2026-10-03："三条、四条甚至更多曲线的时候最多只给了两个滑块区"）：
     原来是横向一排、每张卡 184px，曲线一多就把区域撑得比窗口还宽 —— 第 3 张往后直接
     跑到屏幕外面（区域宽 942→1326px 实测），看着就是"只给两个"。改成一列之后，
     不管多少条曲线占的都是同一个宽度，也不会再有谁被挤到看不见。 */
.pbox { display: flex; flex-direction: column; gap: 6px; margin-left: 8px;
        align-self: flex-start; flex: 0 0 auto; }
.pcard { --pc: #185FA5; border: 2px solid var(--pc); border-radius: 3px; background: var(--mp-field);
         width: 184px; padding: 6px 8px 8px 8px; box-sizing: border-box;
         display: flex; flex-direction: column; gap: 6px; }
.pcard .pch { display: flex; align-items: center; gap: 6px; }
.pcard .pcn { flex: 1; font-size: 12.5px; font-weight: 600; color: var(--pc);
              white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* ★ 卡头里的**真公式**（MathML，见 setMathLabel）：跟卡头同号字、垂直居中，太长照样裁掉。
   ⚠️ 不能用 text-overflow: ellipsis（MathML 是替换级盒子，省略号不生效）→ 靠 overflow 裁。
   卡高由 .pch 的 align-items:center 撑住，公式不会把卡片顶高。 */
.pcard .pcn.mml { white-space: nowrap; overflow: hidden; }
.pcard .pcn.mml math { font-size: 1em; vertical-align: middle; }
.pcard .pcn.mml math * { font-weight: 600; }
.pcard .pcs { width: 19px; height: 19px; padding: 0; border: 1px solid var(--mp-edge-2); background: var(--mp-field);
              color: var(--mp-ink-3); font-size: 12px; line-height: 17px; border-radius: 3px; cursor: default; }
.pcard .pcs:hover { background: var(--mp-hover); border-color: var(--mp-accent-bd); color: var(--mp-accent-ink); }
/* ★ 参数行 = [独立/共用 小按钮][参数名][滑块][数值]。
   ⚠️ 小按钮那列**永远占位**（没同名兄弟时按钮用 .none 隐藏但格子还在），
      否则同名/不同名的滑块左端会参差不齐 —— 用户一眼就看出"乱了"。 */
.pcard .prow { display: grid; grid-template-columns: 15px 13px 1fr 40px; align-items: center; gap: 5px; }
.pcard .plk { width: 15px; height: 15px; padding: 0; border: 1px solid transparent; background: none;
              color: var(--mp-dim-2); cursor: default; border-radius: 2px; line-height: 0; }
.pcard .plk:hover { background: var(--mp-hover); border-color: var(--mp-accent-bd); }
.pcard .plk.on { color: var(--pc); }                 /* 挂了靠：用目标曲线的颜色 + 实心链 */
.pcard .plk.none { visibility: hidden; }             /* 占位，不显示 */
.pcard .pn { font-size: 12px; color: var(--mp-ink-2); font-style: italic; text-align: right;
             white-space: nowrap; overflow: hidden; }
.pcard .pvnum { font-size: 11px; color: var(--mp-ink-3); text-align: right;
                font-variant-numeric: tabular-nums; }
/* ★ 「第三维」（2026-10-09）：这个参数是点云的第三根轴 —— 它不是一个"值"了，
   所以滑块整根撤掉，只留一个跟曲线同色的小徽章（范围在 ⚙ 里改）。
   格子也少一列：15px 链子 + 13px 名字 + 剩下的给徽章。 */
.pcard .prow.paxis { grid-template-columns: 15px 13px 1fr; }
.pcard .pax { font-size: 10.5px; line-height: 15px; text-align: center; white-space: nowrap;
              color: var(--pc); border: 1px solid var(--pc); border-radius: 8px;
              padding: 0 6px; background: var(--mp-field); justify-self: end; }
/* 「独立的 / 与某个同名参数共用」小浮层（点参数名前面的小链子按钮） */
.plinkmenu { position: fixed; z-index: 150; padding: 3px; background: var(--mp-face);
             border: 1px solid var(--mp-edge); box-shadow: 2px 3px 10px rgba(0,0,0,.28);
             min-width: 186px; font-size: 12.5px; user-select: none; }
.plinkmenu .lmh { padding: 2px 6px 5px; margin-bottom: 3px; color: var(--mp-ink-3); font-size: 11.5px;
                  border-bottom: 1px solid var(--mp-edge-lt); white-space: nowrap; }
.plinkmenu .lmi { display: flex; align-items: center; gap: 6px; padding: 3px 6px; border-radius: 2px;
                  white-space: nowrap; }
.plinkmenu .lmi:hover { background: var(--mp-sel); }
.plinkmenu .lmi .tic { flex: none; width: 10px; color: var(--mp-accent); }
.plinkmenu .lmi .sw { flex: none; width: 9px; height: 9px; border-radius: 2px;
                      border: 1px solid var(--mp-swatch-bd); }
/* ★ 滑块完全自绘（2026-10-03 用户："手柄用竖条，不要圆"+"有点错位"）。
   ⚠️ 用 native 的 `accent-color` 时，手柄是圆点、而且和自定义了高度的轨道**没对齐**
   （圆点被按 input 盒居中，轨道只有 4px，看着就是"手柄掉在轨道下面"）。
   全部自绘：轨道 = 4px 细条（走过的一段用曲线颜色），手柄 = **竖条**（5×15 圆角 1px），
   并用 margin-top 精确压到轨道中线上（(4−15)/2 = −5.5px）。
   `--fill` 由 JS 按当前值写百分比（渐变填充随值走，和手柄位置一致）。 */
.pcard input[type=range] { -webkit-appearance: none; appearance: none; width: 100%; height: 16px;
                           margin: 0; padding: 0; background: transparent; cursor: default;
                           --fill: 50%; }
.pcard input[type=range]:focus { outline: none; }
.pcard input[type=range]::-webkit-slider-runnable-track {
  height: 4px; border-radius: 2px; border: none;
  background: linear-gradient(to right, var(--pc) 0 var(--fill), var(--mp-track) var(--fill) 100%); }
.pcard input[type=range]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none; width: 5px; height: 15px; border-radius: 1px;
  background: var(--pc); border: none; margin-top: -5.5px; }
.pcard input[type=range]::-moz-range-track { height: 4px; border-radius: 2px; background: var(--mp-track); }
.pcard input[type=range]::-moz-range-progress { height: 4px; border-radius: 2px; background: var(--pc); }
.pcard input[type=range]::-moz-range-thumb { width: 5px; height: 15px; border-radius: 1px;
                                             background: var(--pc); border: none; }
.wb-r .tools .opt { display: none; }
.wb-r.hasplot .tools .opt { display: block; }
/* 求解块也要有 ⚙（求解选项：是否把结果定义给求解变量）—— 用户 2026-10-02 */
.wb-r.hassolve .tools .opt { display: block; }
/* 图形选项：统一的分节表格（数据系列 / 文字与坐标轴 / 坐标轴与网格 / 图型专属） */
.optwrap { display: flex; flex-direction: column; gap: 4px; }
.optsec { font-size: 11.5px; color: var(--mp-accent-ink); font-weight: 700; margin: 3px 0 1px;
          padding-bottom: 2px; border-bottom: 1px solid var(--mp-edge-lt); }
.oppanel { border: 1px solid var(--mp-edge-2); background: var(--mp-field); padding: 5px 7px 6px 7px;
           display: flex; flex-direction: column; gap: 3px; margin-bottom: 2px; }
.oppanel .ophd, .oppanel .oprow { display: grid; gap: 5px; align-items: center; }
.oppanel .ophd { font-size: 10.5px; color: var(--mp-ink-3); padding-bottom: 2px; }
.oppanel .oprow { font-size: 12px; color: var(--mp-ink-2); }
.oppanel .oplab { color: var(--mp-ink-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.oppanel input[type=color] { width: 32px; height: 20px; padding: 0; border: 1px solid var(--mp-edge-3);
                             background: var(--mp-field); cursor: default; }
.oppanel input[type=number], .oppanel input[type=text] {
  width: 100%; height: 21px; border: 1px solid var(--mp-edge); background: var(--mp-field); font-size: 12px; }
.oppanel input:disabled { background: var(--mp-field-alt); color: var(--mp-dim-2); }
.oppanel select { width: 100%; height: 21px; border: 1px solid var(--mp-edge); background: var(--mp-field); font-size: 11.5px; }
.oppanel .opchk { display: inline-flex; align-items: center; gap: 4px; font-size: 11.5px; color: var(--mp-ink-2); }
/* 「滑块范围 / 第三维」对话框：第三维那一列的单选 + 点云透明度（2026-10-09） */
.opttbl input[type=radio] { margin: 0 3px 0 0; vertical-align: middle; }
.optwrap .optnote .pcal { width: 132px; vertical-align: middle; margin: 0 7px; }
.optwrap .optnote b { color: var(--mp-accent-ink); font-variant-numeric: tabular-nums; }

/* 图形的拖拽改大小手柄（右下角），plot 与图片共用 */
.plotbox, .imgbox { position: relative; }
.imgbox { flex: 0 0 auto; }
.rzbox { position: absolute; right: 0; bottom: 0; width: 14px; height: 14px; z-index: 8;
         cursor: nwse-resize; background: linear-gradient(135deg, transparent 0 42%, var(--mp-grip) 42% 52%, transparent 52% 62%,
                           var(--mp-grip) 62% 72%, transparent 72% 82%, var(--mp-grip) 82% 92%, transparent 92%);
         opacity: .85; }
.rzbox:hover { opacity: 1; background-color: var(--mp-tint-2); }
body.resizing, body.resizing * { user-select: none !important; cursor: nwse-resize !important; }

/* 图像区域：位图 + 尺寸说明 */
.imgbox { width: 560px; max-width: 100%; border: 1px solid var(--mp-edge-lt);
          background: var(--mp-field-alt); display: flex; flex-direction: column; }
.imgbox .imgwrap { flex: 1; min-height: 0; overflow: hidden; display: flex;
                   align-items: center; justify-content: center; }
.imgbox img { display: block; }
.imgbox .imgcap { flex: none; padding: 2px 6px; font-size: 11.5px; color: var(--mp-ink-3);
                  border-top: 1px solid var(--mp-edge-lt); background: var(--mp-field-alt); }

/* 图像块（Ctrl+V 粘进来的图片，kind='image'）：只有一张图，没有公式行。
   ① ⚙ 要显出来（它管「图像选项」：宽度 / 通道 / 适配 / 插值）——
      默认规则是 `.wb-r .tools .opt { display: none }` + `hasplot` 才显示；
   ② 里面没有公式行，vizrow 的上边距去掉，图正好贴着区域边框；
   ③ ⇄ 换单位对图像没有意义，藏起来。 */
.wb-r.hasimg .tools .opt { display: block; }
.wb-r.imgreg > .vizrow { margin-top: 0; }
.wb-r.imgreg .tools .uni { display: none !important; }

/* ============================================================ 矩阵结果的控制条
   用户 2026-10-01：矩阵只保留一种界面（老式 pmatrix）；「显示多少×多少 / 第几页」
   这条控制要留着，但位置挪到**区域右上角那排工具里**（和 ⠿ ⇄ ⚙ × 同一行），
   并且**跟着那排按钮一起出现和隐藏** —— 平时看不见，鼠标移到这块 / 这块是当前块时才出来。
   ⚠️ 它不再是 .res 的子元素，所以不会再占掉一整行、把区域撑高。 */
.matslot { display: flex; align-items: center; }
.matslot[hidden] { display: none !important; }   /* 必须显式写：否则会盖掉 [hidden] 的 display:none */
.matctl { display: flex; align-items: center; gap: 4px; white-space: nowrap;
          height: 19px; padding: 0 5px; border: 1px solid var(--mp-edge); background: var(--mp-field);
          font-size: 11px; line-height: 1; color: var(--mp-ink-3); }
.matctl .mcnum { width: 40px; height: 15px; padding: 0 3px; font-size: 11px;
                 border: 1px solid var(--mp-edge-2); background: var(--mp-field); color: var(--mp-ink-2); }
.matctl .mcnum:focus { outline: 1px solid var(--mp-accent-bd); }
.matctl .mcsize { color: var(--mp-dim-2); }
.matctl .mclab, .matctl .mcunit, .matctl .mcx { color: var(--mp-dim-2); }
.matctl .mcsep { width: 1px; height: 11px; background: var(--mp-sep); margin: 0 2px; }
/* 控制条比那几个小按钮高，带控制条时整排往上抬到"刚好贴着区域上边框"。
   ⚠️ 不要写死 top（-25px 会留 5px 缝，鼠标经过缝的时候 hover 就断了 —— 就是用户报的
      "鼠标往上挪控制条就没了"）。`bottom:100%` = 整排的底边正好压在上边框上，零缝隙。 */
.wb-r.hasmatctl .tools { top: auto; bottom: 100%; }
/* 在控制条的输入框里打字时（鼠标可能已经移开）也要保持可见 */
.wb-r.matpin .tools { display: flex; }

/* ==========================================================================
   ★★ 主题（2026-10-08 用户："做几个主题风格…现在的作为经典，可以再来个浅色、深色
   （对应 Windows 11 现代一些的风格），你还可以添加其他好看简约清爽些的风格，
   全部总风格数不超过 7 个"）

   六套：**经典**（默认，= 加主题之前的外观）/ 浅色 / 深色 / 暖纸 / 青竹 / 墨蓝。
   切换挂 `<html data-theme="…">`（JS：`applyTheme()`，偏好存 `mp-prefs.theme`）。

   三条规矩（加第七套时照做）：
     ① 主题块里**只覆盖变量**，不写具体选择器 —— 例外是"现代风"那点结构微调（圆角），
        那种必须写在 `@media` 外面、且用 `:is()` 收拢；
     ② 缺哪个变量就往上面的 `:root` 里补一个，别在主题块里新造名字；
     ③ 现代风（浅色 / 深色）**靠"把渐变两头设成同色"实现扁平** —— 不用去改规则里的
        `linear-gradient`，把 `--mp-btn-a/b`、`--mp-cap-a/b` 这些设成一样就自动是平的了。
   ========================================================================== */

/* ---------- ① 经典：Mathcad 15 那个灰蓝外壳 ----------
   `:root` 里的默认值就是它；这里只是显式声明一下，让"切回经典"和"从没切过"完全一致。 */
html[data-theme="classic"] { color-scheme: light; }

/* ---------- ② 浅色：Windows 11 现代风（扁平 · 圆角 · 系统蓝 #0067C0） ---------- */
html[data-theme="light"] {
  color-scheme: light;
  --mp-ui-font: "Segoe UI Variable Text", "Segoe UI", system-ui, "Microsoft YaHei";
  --mp-shell: #d6d6d6;
  --mp-paper: #ffffff;  --mp-field: #ffffff;  --mp-field-alt: #f9f9f9;  --mp-face: #f3f3f3;
  --mp-hover: #f0f6fc;  --mp-hover-2: #e5f1fb;
  --mp-sel: #cce4f7;    --mp-sel-2: #bbddf5;    --mp-sel-bd: #7fb2e5;
  --mp-tint: rgba(0,103,192,.08);  --mp-tint-2: rgba(0,103,192,.12);
  --mp-sel-tint: rgba(0,103,192,.24);
  --mp-veil: rgba(0,0,0,.05);
  --mp-track: #e5e5e5;  --mp-track-bg: rgba(0,0,0,.06);  --mp-swatch-bd: rgba(0,0,0,.12);
  --mp-sep: #e0e0e0;    --mp-rule: #8a8a8a;   --mp-grip: #8a8a8a;   --mp-ph: #9a9a9a;
  --mp-hairline: #d6d6d6;  --mp-tab-on-bd: #a8a8a8;  --mp-tab-x: #6b6b6b;
  --mp-ink: #1b1b1b;    --mp-ink-2: #202020;  --mp-ink-3: #5c5c5c;
  --mp-dim: #767676;    --mp-dim-2: #9a9a9a;
  --mp-on-accent: #fff; --mp-on-accent-dim: #d6e9fa;
  --mp-title-ink: #1b1b1b;  --mp-tab-ink: #4a4a4a;
  --mp-winbtn-ink: #1f1f1f;  --mp-tool-ink: #2b2b2b;  --mp-sym-ink: #1f1f1f;  --mp-author: #5c5c5c;
  --mp-edge-3: #c8c8c8; --mp-edge-2: #dedede; --mp-edge: #d6d6d6; --mp-edge-lt: #e8e8e8;
  --mp-title-edge: #e0e0e0;
  --mp-accent: #0067c0; --mp-accent-strong: #005a9e; --mp-accent-ink: #004e8c;
  --mp-accent-bd: #7fb2e5; --mp-accent-lt: #d6e9fa; --mp-caret: #0067c0;
  --mp-err: #c42b1c;  --mp-err-bg: #fde7e9;
  --mp-warn: #9d5d00; --mp-warn-2: #b4761a; --mp-warn-bg: #fff4ce; --mp-warn-bd: #e8c56a;
  --mp-ok: #0f7b0f;   --mp-ok-bg: #dff6dd;
  --mp-plus: #d13438; --mp-paused: #8a8a8a;
  /* 扁平：渐变两头同色 */
  --mp-title-a: #fafafa;   --mp-title-b: #fafafa;
  --mp-tabbar-a: #f3f3f3;  --mp-tabbar-b: #f3f3f3;
  --mp-tab-a: #eaeaea;     --mp-tab-b: #f5f5f5;
  --mp-cap-a: #f7f7f7;     --mp-cap-b: #f7f7f7;
  --mp-btn-a: #fdfdfd;     --mp-btn-b: #f0f0f0;
  --mp-btn-main-a: #dff0ff; --mp-btn-main-b: #bfe1fb;
  --mp-close-a: #fff0f0;   --mp-close-b: #f5b7b7;  --mp-close-bg: #c42b1c;
  --mp-spark: #e8890c; --mp-spark2: #f7a600;
  --mp-bar-eng-a: #5aa9f0; --mp-bar-eng-b: #0f6cbd;
  --mp-bar-fe-a: #ffd08a;  --mp-bar-fe-b: #f0a020;
  --mp-plot-paper: #ffffff; --mp-plot-bg: #ffffff;
  --mp-plot-grid: #eaeaea;  --mp-plot-axis: #bdbdbd;
  --mp-plot-tick: #444444;  --mp-plot-ink: #1b1b1b;  --mp-plot-origin: #000000;
  --mp-plot-legend-bg: rgba(255,255,255,.88);  --mp-plot-legend-bd: #dcdcdc;
}

/* ---------- ③ 深色：Windows 11 深色（扁平 · 圆角 · 浅蓝 #60CDFF） ---------- */
html[data-theme="dark"] {
  color-scheme: dark;
  --mp-ui-font: "Segoe UI Variable Text", "Segoe UI", system-ui, "Microsoft YaHei";
  --mp-shell: #1a1a1a;
  --mp-paper: #1e1e1e;  --mp-field: #2b2b2b;  --mp-field-alt: #262626;  --mp-face: #202020;
  --mp-hover: #2a2a2a;  --mp-hover-2: #333333;
  --mp-sel: #264a63;    --mp-sel-2: #1f3d52;  --mp-sel-bd: #4a7fa5;
  --mp-tint: rgba(96,205,255,.10);  --mp-tint-2: rgba(96,205,255,.14);
  --mp-sel-tint: rgba(96,205,255,.28);
  --mp-veil: rgba(0,0,0,.40);
  --mp-track: #3f3f3f;  --mp-track-bg: rgba(255,255,255,.10);  --mp-swatch-bd: rgba(255,255,255,.18);
  --mp-sep: #3a3a3a;    --mp-rule: #5a5a5a;   --mp-grip: #6e6e6e;   --mp-ph: #6e6e6e;
  --mp-hairline: #3f3f3f;  --mp-tab-on-bd: #5a5a5a;  --mp-tab-x: #9a9a9a;
  --mp-ink: #f2f2f2;    --mp-ink-2: #e8e8e8;  --mp-ink-3: #c5c5c5;
  --mp-dim: #a0a0a0;    --mp-dim-2: #8a8a8a;
  /* ⚠️ 强调色是**浅蓝**，压在上面的字必须改成深色，否则"白字 + 浅蓝底"看不清 */
  --mp-on-accent: #10232e;  --mp-on-accent-dim: #24404f;
  --mp-title-ink: #f2f2f2;  --mp-tab-ink: #c5c5c5;
  --mp-winbtn-ink: #e8e8e8;  --mp-tool-ink: #d6d6d6;  --mp-sym-ink: #e8e8e8;  --mp-author: #b0b0b0;
  --mp-edge-3: #4a4a4a; --mp-edge-2: #3a3a3a; --mp-edge: #383838; --mp-edge-lt: #333333;
  --mp-title-edge: #3a3a3a;
  --mp-accent: #60cdff; --mp-accent-strong: #4cc2ff; --mp-accent-ink: #99ebff;
  --mp-accent-bd: #3a6a8a; --mp-accent-lt: #2a4a5e; --mp-caret: #f2f2f2;
  --mp-err: #ff99a4;  --mp-err-bg: #442726;
  --mp-warn: #e8c36a; --mp-warn-2: #d8a94a; --mp-warn-bg: #433519; --mp-warn-bd: #6e5a1e;
  --mp-ok: #6ccb5f;   --mp-ok-bg: #2a3a22;
  --mp-plus: #ff6b6b; --mp-paused: #9a9a9a;
  --mp-title-a: #2b2b2b;   --mp-title-b: #2b2b2b;
  --mp-tabbar-a: #262626;  --mp-tabbar-b: #262626;
  --mp-tab-a: #2e2e2e;     --mp-tab-b: #333333;
  --mp-cap-a: #2b2b2b;     --mp-cap-b: #2b2b2b;
  --mp-btn-a: #323232;     --mp-btn-b: #2a2a2a;
  --mp-btn-main-a: #1b4b6e; --mp-btn-main-b: #123a57;
  --mp-close-a: #4a2020;   --mp-close-b: #7a2e2e;  --mp-close-bg: #c42b1c;
  --mp-spark: #e8890c; --mp-spark2: #f0a020;
  --mp-bar-eng-a: #6fa8f5; --mp-bar-eng-b: #4cc2ff;
  --mp-bar-fe-a: #ffd08a;  --mp-bar-fe-b: #f0a020;
  --mp-plot-paper: #1e1e1e; --mp-plot-bg: #1e1e1e;
  --mp-plot-grid: #333333;  --mp-plot-axis: #555555;
  --mp-plot-tick: #c5c5c5;  --mp-plot-ink: #f2f2f2;
  --mp-plot-origin: #dcdcdc;    /* Origin 风格的黑箭头在深色底上要反过来 */
  --mp-plot-legend-bg: rgba(43,43,43,.88);  --mp-plot-legend-bd: #4a4a4a;
}

/* ---------- ④ 暖纸：米黄护眼（长时间看公式不刺眼） ---------- */
html[data-theme="paper"] {
  color-scheme: light;
  --mp-shell: #cbbfa4;
  --mp-paper: #fbf6e9;  --mp-field: #fffdf6;  --mp-field-alt: #f8f2e2;  --mp-face: #f2ead8;
  --mp-hover: #f7efe0;  --mp-hover-2: #efe3cd;
  --mp-sel: #ead9c2;    --mp-sel-2: #e0ccb0;  --mp-sel-bd: #c49a72;
  --mp-tint: rgba(156,90,46,.10);  --mp-tint-2: rgba(156,90,46,.14);
  --mp-sel-tint: rgba(156,90,46,.24);
  --mp-veil: rgba(60,48,30,.08);
  --mp-track: #e6dcc6;  --mp-track-bg: rgba(60,48,30,.10);  --mp-swatch-bd: rgba(60,48,30,.20);
  --mp-sep: #e6dcc6;    --mp-rule: #b3a68f;   --mp-grip: #b3a68f;   --mp-ph: #b3a68f;
  --mp-hairline: #d8cdb6;  --mp-tab-on-bd: #b9ac93;  --mp-tab-x: #8a8070;
  --mp-ink: #3b342a;    --mp-ink-2: #2f2a22;  --mp-ink-3: #6b6152;
  --mp-dim: #7d7364;    --mp-dim-2: #9c9284;
  --mp-on-accent: #fff8ec;  --mp-on-accent-dim: #f0e0cc;
  --mp-title-ink: #3b342a;  --mp-tab-ink: #5c5346;
  --mp-winbtn-ink: #4a4238;  --mp-tool-ink: #5a4a34;  --mp-sym-ink: #3b342a;  --mp-author: #6f6656;
  --mp-edge-3: #b9ac93; --mp-edge-2: #d8cdb6; --mp-edge: #cdc2a9; --mp-edge-lt: #e6dcc6;
  --mp-title-edge: #ddcfb4;
  --mp-accent: #9c5a2e; --mp-accent-strong: #8a4d24; --mp-accent-ink: #7a4520;
  --mp-accent-bd: #c49a72; --mp-accent-lt: #f0e0cc; --mp-caret: #9c5a2e;
  --mp-err: #a33a2a;  --mp-err-bg: #f7e3de;
  --mp-warn: #8a5a00; --mp-warn-2: #9c6a10; --mp-warn-bg: #fdf3dd; --mp-warn-bd: #d8b46a;
  --mp-ok: #4e7a3a;   --mp-ok-bg: #e6efe0;
  --mp-plus: #c0453a; --mp-paused: #96897a;
  --mp-title-a: #f6efdf;   --mp-title-b: #f2ead8;
  --mp-tabbar-a: #efe7d5;  --mp-tabbar-b: #e8dfc8;
  --mp-tab-a: #ece3d0;     --mp-tab-b: #f6f0e2;
  --mp-cap-a: #faf4e6;     --mp-cap-b: #f0e7d3;
  --mp-btn-a: #fffdf6;     --mp-btn-b: #f2ead8;
  --mp-btn-main-a: #f0e0cc; --mp-btn-main-b: #e0ccb0;
  --mp-close-a: #f7dede;   --mp-close-b: #dfa8a0;  --mp-close-bg: #a33a2a;
  --mp-spark: #cf7a10; --mp-spark2: #e0951c;
  --mp-bar-eng-a: #7fa7d8; --mp-bar-eng-b: #4a76ab;
  --mp-bar-fe-a: #e8c07a;  --mp-bar-fe-b: #c98f22;
  --mp-plot-paper: #fffdf6; --mp-plot-bg: #fffdf6;
  --mp-plot-grid: #eae0c9;  --mp-plot-axis: #c3b79c;
  --mp-plot-tick: #5a5245;  --mp-plot-ink: #3b342a;  --mp-plot-origin: #3b342a;
  --mp-plot-legend-bg: rgba(255,253,246,.90);  --mp-plot-legend-bd: #d8cdb6;
}

/* ---------- ⑤ 青竹：清爽浅绿（淡雅、护眼） ---------- */
html[data-theme="bamboo"] {
  color-scheme: light;
  --mp-shell: #b9c9b3;
  --mp-paper: #f7fbf5;  --mp-field: #ffffff;  --mp-field-alt: #f4faf0;  --mp-face: #eaf2e6;
  --mp-hover: #eef7ea;  --mp-hover-2: #dff0e2;
  --mp-sel: #d6ebdc;    --mp-sel-2: #c6e2cf;  --mp-sel-bd: #7fb794;
  --mp-tint: rgba(46,125,79,.10);  --mp-tint-2: rgba(46,125,79,.14);
  --mp-sel-tint: rgba(46,125,79,.24);
  --mp-veil: rgba(20,40,25,.06);
  --mp-track: #dde8d8;  --mp-track-bg: rgba(20,40,25,.08);  --mp-swatch-bd: rgba(20,40,25,.16);
  --mp-sep: #dde8d8;    --mp-rule: #a8b8a2;   --mp-grip: #a8b8a2;   --mp-ph: #a8b8a2;
  --mp-hairline: #cfdcc9;  --mp-tab-on-bd: #8fb098;  --mp-tab-x: #6b7c64;
  --mp-ink: #22301f;    --mp-ink-2: #1d2a1a;  --mp-ink-3: #4f5f4a;
  --mp-dim: #66765f;    --mp-dim-2: #8a9984;
  --mp-on-accent: #f4fbf2;  --mp-on-accent-dim: #d6ebdc;
  --mp-title-ink: #22301f;  --mp-tab-ink: #46563f;
  --mp-winbtn-ink: #2c3a28;  --mp-tool-ink: #37563f;  --mp-sym-ink: #22301f;  --mp-author: #5f7058;
  --mp-edge-3: #a9bda4; --mp-edge-2: #cfdcc9; --mp-edge: #c6d5c0; --mp-edge-lt: #dde8d8;
  --mp-title-edge: #ccdcc6;
  --mp-accent: #2e7d4f; --mp-accent-strong: #256b42; --mp-accent-ink: #1f5c39;
  --mp-accent-bd: #7fb794; --mp-accent-lt: #d6ebdc; --mp-caret: #2e7d4f;
  --mp-err: #a83a2c;  --mp-err-bg: #f7e5e1;
  --mp-warn: #7d5b00; --mp-warn-2: #8f6a08; --mp-warn-bg: #fdf5dc; --mp-warn-bd: #d8bd6a;
  --mp-ok: #2f7a3a;   --mp-ok-bg: #e0f0e0;
  --mp-plus: #c0453a; --mp-paused: #8a9a84;
  --mp-title-a: #f4faf0;   --mp-title-b: #eaf2e6;
  --mp-tabbar-a: #e6f0e0;  --mp-tabbar-b: #dcebd6;
  --mp-tab-a: #e2eedc;     --mp-tab-b: #f1f8ee;
  --mp-cap-a: #f4faf0;     --mp-cap-b: #e6f0e0;
  --mp-btn-a: #ffffff;     --mp-btn-b: #eaf2e6;
  --mp-btn-main-a: #d6ebdc; --mp-btn-main-b: #b8dcc4;
  --mp-close-a: #f7e0e0;   --mp-close-b: #dfa8a4;  --mp-close-bg: #a83a2c;
  --mp-spark: #d08a10; --mp-spark2: #e0a020;
  --mp-bar-eng-a: #7fbcae; --mp-bar-eng-b: #3f8f7c;
  --mp-bar-fe-a: #e8d08a;  --mp-bar-fe-b: #c9a022;
  --mp-plot-paper: #fbfdfa; --mp-plot-bg: #fbfdfa;
  --mp-plot-grid: #e2ebdd;  --mp-plot-axis: #b7c6b1;
  --mp-plot-tick: #4a5a45;  --mp-plot-ink: #22301f;  --mp-plot-origin: #22301f;
  --mp-plot-legend-bg: rgba(251,253,250,.90);  --mp-plot-legend-bd: #cfdcc9;
}

/* ---------- ⑥ 墨蓝：深夜蓝（比纯黑柔和，晚上看不刺眼） ---------- */
html[data-theme="navy"] {
  color-scheme: dark;
  --mp-shell: #101823;
  --mp-paper: #16212e;  --mp-field: #1c2836;  --mp-field-alt: #18242f;  --mp-face: #1b2734;
  --mp-hover: #22323f;  --mp-hover-2: #2a3d4d;
  --mp-sel: #24405a;    --mp-sel-2: #1e3750;  --mp-sel-bd: #4a7ba6;
  --mp-tint: rgba(111,179,232,.12);  --mp-tint-2: rgba(111,179,232,.16);
  --mp-sel-tint: rgba(111,179,232,.30);
  --mp-veil: rgba(0,0,0,.35);
  --mp-track: #2f4256;  --mp-track-bg: rgba(255,255,255,.10);  --mp-swatch-bd: rgba(255,255,255,.18);
  --mp-sep: #2b3d4f;    --mp-rule: #5b7185;   --mp-grip: #5b7185;   --mp-ph: #5c7185;
  --mp-hairline: #2e4053;  --mp-tab-on-bd: #46698a;  --mp-tab-x: #8fa0b2;
  --mp-ink: #e8eef6;    --mp-ink-2: #dde6f0;  --mp-ink-3: #b6c4d4;
  --mp-dim: #94a5b8;    --mp-dim-2: #7f92a6;
  --mp-on-accent: #0e1a26;  --mp-on-accent-dim: #1d3448;
  --mp-title-ink: #e8eef6;  --mp-tab-ink: #b6c4d4;
  --mp-winbtn-ink: #dde6f0;  --mp-tool-ink: #b6c4d4;  --mp-sym-ink: #dde6f0;  --mp-author: #9fb0c2;
  --mp-edge-3: #40556b; --mp-edge-2: #2e4053; --mp-edge: #2b3d4f; --mp-edge-lt: #24384a;
  --mp-title-edge: #2b3d4f;
  --mp-accent: #6fb3e8; --mp-accent-strong: #4f9fdc; --mp-accent-ink: #9fd0f2;
  --mp-accent-bd: #3f6d92; --mp-accent-lt: #22405a; --mp-caret: #9fd0f2;
  --mp-err: #ff9a92;  --mp-err-bg: #3a2622;
  --mp-warn: #e8c07a; --mp-warn-2: #d8ac62; --mp-warn-bg: #332a18; --mp-warn-bd: #6b552a;
  --mp-ok: #6ccb5f;   --mp-ok-bg: #22331f;
  --mp-plus: #ff7a6a; --mp-paused: #8fa0b2;
  --mp-title-a: #22303f;   --mp-title-b: #1e2b39;
  --mp-tabbar-a: #1e2b39;  --mp-tabbar-b: #1a2632;
  --mp-tab-a: #24323f;     --mp-tab-b: #2a3a49;
  --mp-cap-a: #22303f;     --mp-cap-b: #1d2a37;
  --mp-btn-a: #26343f;     --mp-btn-b: #1f2c38;
  --mp-btn-main-a: #1d3f5c; --mp-btn-main-b: #16324a;
  --mp-close-a: #43201f;   --mp-close-b: #6e2e2b;  --mp-close-bg: #c0392b;
  --mp-spark: #e8890c; --mp-spark2: #f0a020;
  --mp-bar-eng-a: #6fa8f5; --mp-bar-eng-b: #4f9fdc;
  --mp-bar-fe-a: #ffd08a;  --mp-bar-fe-b: #f0a020;
  --mp-plot-paper: #16212e; --mp-plot-bg: #16212e;
  --mp-plot-grid: #2b3d4f;  --mp-plot-axis: #4a6178;
  --mp-plot-tick: #b6c4d4;  --mp-plot-ink: #e8eef6;  --mp-plot-origin: #cfe0f0;
  --mp-plot-legend-bg: rgba(28,40,54,.90);  --mp-plot-legend-bd: #2e4053;
}

/* ---------- 现代风的结构微调：圆角 ----------
   ⚠️ 只给浅色 / 深色（用户点名"对应 Windows 11 现代一些的风格"）。
      用 `:is()` 收拢选择器，避免写两遍；放最后是为了盖过前面的规则（同优先级下后者胜）。 */
html[data-theme="light"] :is(.dropdown, .palwin, .modal, .comlist, .comitem, .imgbox,
  .plinkmenu, .unitmenu, .opttbl) { border-radius: 8px; }
html[data-theme="light"] :is(.dropdown, .palwin, .modal, .plinkmenu) { overflow: hidden; }
html[data-theme="light"] :is(.tabbar .tab, .tabbar .tadd, .comtab, .unitmenu .uslot select,
  .unitmenu .uin, .palwin .mgr-num, .palwin .mgr-go, .cominq, .comsel, .cominta, .combtn,
  .unitmenu .ubtn, .modal .bar button, .modal select, .modal .list, .modal .sig, .modal .desc,
  .modal .fsearch input, .palwin .palit, .oppanel input,
  .oppanel select, .oppanel input[type=color], .assumerow input, .assumerow select,
  .assumerow button, select.tb, input.tb, .matctl, .matctl .mcnum, .scrow kbd) { border-radius: 6px; }
html[data-theme="light"] :is(.tbtn, .menubar .mi, .wb-r .tools button, .wb-r .grip,
  .modal .list .it, .dropdown .it, .comtab, .palwin .palx, .pcard .pcs, .rzbox) { border-radius: 4px; }

html[data-theme="dark"] :is(.dropdown, .palwin, .modal, .comlist, .comitem, .imgbox,
  .plinkmenu, .unitmenu, .opttbl) { border-radius: 8px; }
html[data-theme="dark"] :is(.dropdown, .palwin, .modal, .plinkmenu) { overflow: hidden; }
html[data-theme="dark"] :is(.tabbar .tab, .tabbar .tadd, .comtab, .unitmenu .uslot select,
  .unitmenu .uin, .palwin .mgr-num, .palwin .mgr-go, .cominq, .comsel, .cominta, .combtn,
  .unitmenu .ubtn, .modal .bar button, .modal select, .modal .list, .modal .sig, .modal .desc,
  .modal .fsearch input, .palwin .palit, .oppanel input,
  .oppanel select, .oppanel input[type=color], .assumerow input, .assumerow select,
  .assumerow button, select.tb, input.tb, .matctl, .matctl .mcnum, .scrow kbd) { border-radius: 6px; }
html[data-theme="dark"] :is(.tbtn, .menubar .mi, .wb-r .tools button, .wb-r .grip,
  .modal .list .it, .dropdown .it, .comtab, .palwin .palx, .pcard .pcs, .rzbox) { border-radius: 4px; }

/* ---------- 查找条（Ctrl+F，2026-10-12） ----------
   以前是 window.prompt + 记住查询词：第二次按 Ctrl+F 不再弹框（用户反馈"搜索一次后就搜不了了"）。
   现在常驻这一条：输入框 + 第 n/m 处 + 上一个/下一个 + 关闭。
   ⚠️ 颜色一律走主题变量（切主题、深色模式都跟着变）。 */

/* ============================================================ Mathcad 转换器对话框（2026-10-15）
   配色只用 --mp-* 变量（六套主题自动跟随）。 */
.cadconv { display: flex; flex-direction: column; gap: 8px; }
.cadzone { border: 2px dashed var(--mp-edge-3); border-radius: 6px; background: var(--mp-field);
  padding: 16px 12px; text-align: center; cursor: pointer;
  transition: background .12s, border-color .12s; }
.cadzone:hover, .cadzone.over { background: var(--mp-hover); border-color: var(--mp-accent-bd); }
.cadzone.busy { opacity: .6; }
.cadico { font-size: 26px; line-height: 1.1; color: var(--mp-dim); }
.cadtip { margin-top: 4px; color: var(--mp-ink-2); }
.cadsub { margin-top: 2px; color: var(--mp-dim); font-size: 12px; }
.cadpick { align-self: flex-start; height: 23px; min-width: 96px; border: 1px solid var(--mp-edge-3);
  background: linear-gradient(var(--mp-btn-a),var(--mp-btn-b)); }
.cadpick:hover { background: linear-gradient(var(--mp-btn-a),var(--mp-hover-2)); border-color: var(--mp-accent-bd); }
.cadout { border: 1px solid var(--mp-edge-2); background: var(--mp-field); padding: 8px 10px;
  min-height: 92px; max-height: 260px; overflow: auto; color: var(--mp-ink-2);
  white-space: pre-wrap; unicode-bidi: plaintext; }
.cadout.bad { color: var(--mp-err); border-color: var(--mp-err); }
.cadln { padding: 1px 0; }
.cadln.bad { color: var(--mp-err); }
.cadgo { margin-top: 8px; height: 24px; padding: 0 12px; border: 1px solid var(--mp-edge-3);
  background: linear-gradient(var(--mp-btn-a),var(--mp-btn-b)); }
.cadgo:hover { background: linear-gradient(var(--mp-btn-a),var(--mp-hover-2)); border-color: var(--mp-accent-bd); }

/* ============================================================ 打印分页线（2026-10-15 用户要求）
   垫在 #board 最底层的一层参考网格：**一格 = 一张纸**，格子边界就是页边界，
   用户把内容排进格子，打印出来就是整页、不会被切在中间。
   线本身由 JS（pageLinesDraw）用 repeating-linear-gradient 画，颜色取 --mp-edge-2
   （只用 --mp-* 变量 → 六套主题自动跟随）。
   ⚠️ 纯视觉层：pointer-events:none 不吃点击；打印时隐藏（线不该被打出来）。 */
#pagelines { position: absolute; left: 0; top: 0; pointer-events: none; z-index: 0; }
@media print { #pagelines { display: none !important; } }
