/* ============================================================
   Phase Book 共用样式（基于 Element Plus 主题加深定制）
   ============================================================ */

:root {
  --brand: #2e6fff;
  --brand-deep: #1f55d6;
  --brand-soft: #eef3ff;
  --accent: #f59e0b;
  --ink: #1f2a3c;
  --ink-2: #4a5b76;
  --muted: #8b97ad;
  --line: #e3e8f1;
  --bg:  #f5f7fb;
  --bg-2: #ffffff;
  --danger: #ef4444;
  --ok: #10b981;
  --warn: #f59e0b;
  --shadow-sm: 0 1px 2px rgba(15, 23, 42, .06);
  --shadow-md: 0 6px 16px rgba(15, 23, 42, .08);
  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 14px;
}

html, body, #app, #login-app, #register-app, #admin-app {
  height: 100%;
}
body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Microsoft YaHei", sans-serif;
  background: var(--bg);
  color: var(--ink);
  font-size: 14px;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--brand); text-decoration: none; }
a:hover { color: var(--brand-deep); }

/* ——— 登录 / 注册 页面壳 ——— */
.shell {
  min-height: 100%;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, #e9efff 0%, #f9faff 50%, #fff9f1 100%);
  padding: 32px 12px;
  box-sizing: border-box;
}
.shell-card {
  width: 100%; max-width: 440px;
  background: var(--bg-2);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  padding: 28px 30px 22px;
}
.shell-card.wide { max-width: 720px; }

/* 注册/登录表单的标签对齐（2026-09-05）：
   英文标签长（Confirm Password / Company Invitation Code），100px 宽放不下会折行。
   Element Plus 默认把标签锁死 height:32px + line-height:32px，折行第二行直接溢出、
   压到下一个表单项上（视觉上行距巨大）；且 label 内文字是顶部对齐（flex-start），
   单行标签的文字会比右侧输入框中心整体偏高约 6px。这里一并修正：
   放开高度、收紧行距、文字在框内垂直居中，让标签文字与右侧输入框水平居中对齐，
   两行/三行折行时也保持右对齐。中文单行标签视觉不变。 */
.shell-card .el-form-item { align-items: center; }
.shell-card .el-form-item__label {
  height: auto;
  min-height: 32px;
  line-height: 1.4;
  text-align: right;
  align-items: center;   /* label 自身是 flex，EP 默认 flex-start，改居中 */
}

.brand-row {
  display: flex; align-items: center; gap: 12px;
  margin-bottom: 16px;
}
.brand-logo {
  width: 44px; height: 44px;
  border-radius: 12px;
  background: linear-gradient(135deg, var(--brand) 0%, #5b8fff 100%);
  display: grid; place-items: center;
  color: #fff; font-weight: 800; font-size: 22px;
  box-shadow: 0 6px 14px rgba(46,111,255,.35);
}
.brand-title { font-size: 18px; font-weight: 700; color: var(--ink); }
.brand-sub   { font-size: 12px; color: var(--muted); }
.tabs-row {
  margin: 8px 0 18px; display: flex; gap: 24px; padding-left: 0;
  list-style: none;
  border-bottom: 1px solid var(--line);
}
.tabs-row li {
  padding: 10px 2px; cursor: pointer; color: var(--muted);
  border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.tabs-row li.on { color: var(--brand); border-bottom-color: var(--brand); font-weight: 600; }

/* ——— 顶栏（主应用） ——— */
.app-header {
  height: 56px;
  background: linear-gradient(90deg, var(--brand-deep) 0%, var(--brand) 100%);
  color: #fff;
  display: flex; align-items: center; padding: 0 18px;
  box-shadow: var(--shadow-sm);
  position: relative; z-index: 10;
}
.app-header .left { display: flex; align-items: center; gap: 14px; }
.app-header .brand-mini {
  width: 32px; height: 32px; background: rgba(255,255,255,.15);
  display: grid; place-items: center; border-radius: 8px; font-size: 17px;
}
.app-header .title { font-weight: 700; font-size: 15px; }
.app-header .subtitle { font-size: 12px; opacity: .85; }
.app-header .right { margin-left: auto; display: flex; align-items: center; gap: 14px; font-size: 13px; }

/* 顶栏右侧 4 个按钮（系统设置 / 邀请注册 / 个人中心 / 退出）
   统一尺寸 — 高度 32px（EP small 默认）+ 宽度 88px + 居中文字。
   不同 type (plain / success / warning / danger) 默认背景色深浅不一，
   看起来高度不一样，统一 width + min-height 后视觉对齐到同一条上下边界。 */
.app-header .right > .el-button {
  min-width: 88px;
  width: auto;
  min-height: 32px;
  padding: 0 10px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
}
/* 顶栏语言切换（与登录/注册页外观统一；放在最右侧） */
.app-header .lang-switch { display: flex; gap: 6px; margin-left: 14px; }

/* 测试记录卡片底部 3 个按钮（保存数据 / 新建测试 / 删除记录）
   统一尺寸 — 以「新建测试」(plain 白底、size=large 默认 96×40) 为标准，
   三个按钮 box 像素级对齐到同一上下左右边界。
   不同 type(primary 实心 / default plain / danger plain) 默认色块感不一致，
   强制 width + height + padding 0 + 居中后视觉色块感统一。 */
.record-btns > .el-button {
  width: 96px;
  height: 40px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
/* 按钮行：与上方派生结果区第 1 格「二水石膏含量 DH (%)」同宽并 space-between 分布。
   .derived-grid 是 repeat(3, 1fr) + 2 个 12px gap → 单格宽 = (100% - 24px) / 3。
   行宽取单格宽后，space-between 会把「保存数据」顶到左边缘、
   「删除记录」右边缘正好落在 DH 区块右边缘，「新建测试」自动居中、两侧间距相等。 */
.record-btns {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  margin-top: 14px;
  width: calc((100% - 24px) / 3);
}
/* EP 默认给 .el-button+.el-button 加 margin-left: 12px，会让 space-between 的
   剩余空间分配混入固定 margin；这里清零，让间距完全由剩余空间均分、两侧严格相等。 */
.record-btns .el-button + .el-button {
  margin-left: 0;
}
.app-header .lang-btn {
  width: 40px; height: 22px; padding: 0; border: 1px solid rgba(255,255,255,.5); border-radius: 6px;
  background: rgba(255,255,255,.15); cursor: pointer; font-size: 12px; line-height: 1;
  display: flex; align-items: center; justify-content: center; opacity: .5; transition: .15s;
}
.app-header .lang-btn.active { opacity: 1; border-color: #fff; box-shadow: 0 0 0 2px rgba(255,255,255,.35); background: rgba(255,255,255,.3); }
.app-header .lang-btn:hover { opacity: .85; }
.trial-tag {
  background: var(--accent);
  color: #fff; font-size: 12px; font-weight: 600;
  padding: 4px 10px; border-radius: 999px;
}
.trial-tag.warn { background: var(--danger); }
/* 已付费：低调用品牌深蓝，与"试用中"区分开 */
.trial-tag.paid { background: var(--brand-deep); }
.user-pill {
  background: rgba(255,255,255,.15);
  padding: 5px 12px; border-radius: 999px;
}

/* ——— 主内容区 ——— */
.main-grid {
  display: grid;
  grid-template-columns: 1fr 320px;
  gap: 14px; padding: 14px;
}
.card-panel {
  background: var(--bg-2);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  padding: 16px 18px;
}
.card-title {
  font-size: 13px; font-weight: 700; color: var(--ink-2);
  text-transform: uppercase; letter-spacing: 0.5px;
  margin-bottom: 10px;
  display: flex; align-items: center; gap: 8px;
}
.card-title::before {
  content: ''; display: inline-block;
  width: 4px; height: 14px; background: var(--brand);
  border-radius: 2px;
}
/* 标题右侧的补充说明与操作按钮（如历史记录的「仅显示最近一周 / 查看数据」） */
.card-title .title-note {
  font-size: 12px; font-weight: 400; text-transform: none; letter-spacing: 0;
  color: var(--muted);
}
.card-title .title-action { margin-left: auto; align-self: flex-start; margin-top: 6px; }

/* ——— 查看数据抽屉 ——— */
.hist-wrap { display: flex; gap: 16px; height: 100%; min-height: 0; }
.hist-side {
  width: 180px; flex: none;
  border-right: 1px solid var(--line); padding-right: 14px;
  display: flex; flex-direction: column;
}
.hist-side-title {
  font-size: 12px; font-weight: 700; color: var(--ink-2);
  margin-bottom: 8px;
}
.hist-range { list-style: none; margin: 0; padding: 0; }
.hist-range li {
  padding: 8px 12px; margin-bottom: 4px;
  border-radius: 6px; cursor: pointer;
  font-size: 13px; color: var(--ink-2);
  transition: background .15s, color .15s;
}
.hist-range li:hover { background: var(--brand-soft); }
.hist-range li.on { background: var(--brand); color: #fff; font-weight: 600; }
.hist-custom { margin-top: 14px; padding-top: 12px; border-top: 1px dashed var(--line); }
.hist-side-foot {
  margin-top: auto; padding-top: 12px;
  font-size: 12px; line-height: 1.8;
}
.hist-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }

/* ——— 数据表格自动列宽：按表头/数据内容自适应，不使用固定像素宽度 ——— */
.auto-width-table.el-table .el-table__header,
.auto-width-table.el-table .el-table__body {
  width: auto !important;
  table-layout: fixed !important;
}
.auto-width-table.el-table .el-table__header th .cell,
.auto-width-table.el-table .el-table__body td .cell {
  white-space: nowrap;
}

/* ——— 上部统计条 ——— */
.stat-row {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px;
  /* 上/左右与顶栏对齐取 14/18；底部留 0，
     让「统计条」与下方区块的间距 = 仅 main-grid 的 14px 上内边距，
     与其余区块之间（margin-top:14px）完全一致，避免出现 28px 的双倍间距。 */
  padding: 14px 18px 0;
}
.stat-card {
  background: var(--bg-2); padding: 14px 16px;
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  display: flex; align-items: center; gap: 12px;
}
.stat-icon {
  width: 44px; height: 44px; border-radius: 12px;
  background: var(--brand-soft);
  color: var(--brand);
  display: grid; place-items: center; font-size: 22px;
}
.stat-icon.green { background: #e7f9f1; color: var(--ok); }
.stat-icon.amber { background: #fff8eb; color: var(--warn); }
.stat-icon.red   { background: #fde8e8; color: var(--danger); }
/* 统计卡里的 SVG 图标：描边用 currentColor 继承卡片语义色，
   换色只需改 .stat-icon 的 color，不必动 SVG 本身。 */
.stat-icon svg { width: 24px; height: 24px; display: block; }
.stat-label { font-size: 12px; color: var(--muted); }
.stat-value { font-size: 22px; font-weight: 700; color: var(--ink); }

/* ——— 邀请注册（系统设置 · 成员与邀请） ——— */
.invite-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 12px; margin-bottom: 12px;
  background: var(--brand-soft); border-radius: var(--radius-md);
  font-weight: 700; color: var(--ink);
}
.invite-code-row { display: flex; align-items: center; gap: 8px; width: 100%; }
.invite-code {
  flex: 1; padding: 6px 12px;
  background: #f6f9ff; border: 1px dashed var(--brand); border-radius: 6px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 18px; font-weight: 700; letter-spacing: 3px; color: var(--brand);
}

/* ——— 相分析表格 ——— */
.phase-table {
  width: 100%; border-collapse: separate; border-spacing: 0;
  font-size: 13px;
}
.phase-table th {
  text-align: left; background: #f6f9ff; color: var(--ink-2);
  font-weight: 700; padding: 10px 8px;
  border-bottom: 1px solid var(--line);
}
.phase-table td {
  padding: 8px;
  border-bottom: 1px solid var(--line);
  vertical-align: middle;
}
.phase-table td.col-no { width: 110px; text-align: left; }
.phase-table td.col-readonly { background: #fbfcfe; }
.phase-table td.result { color: var(--brand-deep); font-weight: 700; }
.phase-table td.result .result-num { font-size: 16px; }

/* 相名下方的小字注释 */
.phase-sub { font-size: 11px; font-weight: 400; color: var(--muted); margin-top: 2px; line-height: 1.3; }

/* 当前等待天平数据的格子 */
.phase-table td.cell-focus {
  background: #eef4ff;
  box-shadow: inset 0 0 0 2px var(--brand);
  border-radius: 4px;
}

/* ——— 全局聚焦高亮：任何输入框定位/聚焦后都给出与称重表格 cell-focus 一致的
       高亮反馈（浅蓝底 + 品牌色描边），覆盖普通输入框 / 数字框 / 下拉框 / 文本域 ——— */
.el-input__wrapper:focus-within,
.el-input-number .el-input__wrapper:focus-within,
.el-select__wrapper:focus-within,
.el-textarea__inner:focus {
  background-color: #eef4ff !important;
  box-shadow: 0 0 0 2px var(--brand) inset !important;
}
/* 相分析表格内仍由 td.cell-focus 统一高亮（只保留外边框），取消输入框内框的蓝色
   focus 描边，但保留 Element Plus 默认的 1px 浅灰细边框（不能直接 box-shadow:none，
   否则连默认细边都消失，输入框变成无边框空盒）。
   两个坑，缺一不可：
   1) 上面的全局高亮规则带了 !important —— !important 声明永远压过普通声明，
      与特异性无关，所以这里的压制也必须带 !important 才有效（带上后比特异性，
      .phase-table .el-input__wrapper 为 0-3-0，高于全局的 0-2-0，故胜出）。
   2) Element Plus 默认的 focus 描边挂在 .el-input__wrapper.is-focus 上（class 触发，
      不是 :focus-within），所以两条路径都要压制。
   实际效果：聚焦时 wrapper 显示 1px 浅灰 inset（默认细边），不再有蓝色；外框由
   td.cell-focus 画 2px 品牌色 inset。 */
.phase-table .el-input__wrapper:focus-within,
.phase-table .el-input__wrapper.is-focus {
  background-color: transparent !important;
  box-shadow: 0 0 0 1px #dcdfe6 inset !important;
}

/* ——— 派生结果区 ——— */
.derived-grid {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 12px; margin-top: 14px;
  padding-top: 14px; border-top: 1px dashed var(--line);
}
.derived-cell {
  background: #f8fbff; border: 1px solid var(--line);
  border-radius: 8px; padding: 12px 14px;
}
.derived-label {
  font-size: 12px; color: var(--ink-2); font-weight: 600; margin-bottom: 6px;
}
.derived-value {
  font-size: 26px; font-weight: 800; color: var(--brand-deep);
  font-variant-numeric: tabular-nums; line-height: 1.2;
}
.derived-note {
  font-size: 11px; color: var(--muted); margin-top: 6px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
@media (max-width: 1100px) {
  .derived-grid { grid-template-columns: 1fr; }
  /* 单列时第 1 格占满整行，按钮行随之占满，才能继续与 DH 区块右边缘对齐 */
  .record-btns { width: 100%; }
}

.input-strong :deep(.el-input__inner) {
  font-weight: 600; color: var(--brand-deep); font-size: 16px;
}

.reading-value {
  font-size: 36px; font-weight: 800;
  color: var(--brand-deep);
  letter-spacing: -1px;
  font-family: 'SF Mono', 'Menlo', monospace;
  text-align: center;
  padding: 12px 0;
}
.reading-tag {
  display: inline-block; padding: 2px 10px; border-radius: 999px;
  font-size: 12px; font-weight: 600;
}
.reading-tag.ok   { background: #e7f9f1; color: var(--ok); }
.reading-tag.warn { background: #fff8eb; color: var(--warn); }
.reading-tag.err  { background: #fde8e8; color: var(--danger); }
.reading-tag.off  { background: #eef0f4; color: var(--muted); }

.quick-row {
  display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px;
}
.quick-row .el-input { width: 100%; }

/* 小按钮 */
.btn-row {
  display: flex; flex-wrap: wrap; gap: 6px;
}

/* ——— 表单标签弱化 ——— */
.el-form-item__label { color: var(--ink-2) !important; font-weight: 500; }

/* ——— 个人中心弹层：英文标签左对齐 + 与输入框垂直居中（保持标签列/输入框宽度不变）——— */
html:lang(en) .pb-profile-dialog .el-form-item__label {
  /* label 自身不跟随 content 拉伸（下方有辅助文字时也不会被撑高），
     但 .el-form-item 保持默认 stretch，content 区仍撑满 32px，
     这样 20px 高的 el-tag（角色）也能在内容区里垂直居中。 */
  align-self: flex-start !important;
  height: auto !important;
  min-height: 32px !important;
  display: flex !important;
  align-items: center !important;         /* 文字在 label 盒内垂直居中 */
  justify-content: flex-start !important; /* 文字左对齐（不是右对齐） */
  /* 关键：行高取输入框高度的一半（32px / 2 = 16px）。
     单行时盒高 = min-height 32px，文字中心 = 16px；
     换行两行时盒高 = 2 × 16px = 32px，文字中心仍 = 16px。
     两种情况下文字中心都与 32px 高的输入框中心重合。 */
  line-height: 16px !important;
  padding: 0 12px 0 0 !important;
}

/* ——— 标签下带小字（如「结晶水 (%)」+「水份仪快速测试」）——— */
/* 间距对齐相分析表里「AIII」与其副标题（.phase-sub）的排版 */
.label-stack {
  display: flex; flex-direction: column; justify-content: center;
}
.label-stack > :first-child {
  /* 父级 .el-form-item__label 默认 line-height: 32px（用于垂直居中匹配 input 高度），
     会把大字标签撑到 32px 高，但文字本身只有 ~14px，导致字形底部到小字顶部
     有 ~16px 无字空白 + 2px margin = 视觉间距 ~18px，比蓝色框（AIII/HH 副标题）
     的 2px 视觉间距大很多。这里把首子（"大字"）line-height 设小、消除 box 留白。 */
  line-height: 1;
  margin: 0;
}
.label-sub {
  font-size: 11px; font-weight: 400; color: var(--muted);
  margin-top: 2px; line-height: 1.3;
  /* 与 .phase-sub（相分析表里 AIII/HH/AII/CW 副标题）完全一致的样式，保证视觉间距统一 */
}

/* ——— 短标签（2~3 字）用字间距均分撑满 4 汉字宽，两端与 4 字标签对齐 ——— */
/* 例：「取样点」→ 取　样　点（3 字均分 4 字宽）；「备注」→ 备　　注（2 字均分 4 字宽）
   这样首字贴左、末字贴右，与「测试编号」「样品编号」等 4 字标签两端对齐。
   用法：<el-form-item label-width="68px"><template #label>
           <span class="pb-label-4ch">{{ t('取样点') }}</span></template> …
   56px = 4 个 14px 汉字；容器 label-width 68px = 56px + EP 默认 padding-right 12px。 */
.pb-label-4ch {
  display: inline-block;
  width: 56px;
  text-align: justify;
  text-align-last: justify;
  -moz-text-align-last: justify;
}

/* 英文模式下 .pb-label-4ch（取样点/备注/波特率/数据位/停止位/奇偶校验）标签居中：
   .pb-label-4ch 把标签宽锁死成 56px（4 汉字宽），英文单词必然折成两行。
   而 .el-form-item__label 是 32px 高的 flex 容器、align-items: flex-start，
   两行文字按继承的 line-height:32px 排就是 64px —— 第二行整个掉出标签盒
   （实测「Baud Rate」溢出 32px、与输入框中心差 16px）。
   解法：行高取输入框高度的一半（32px / 2 = 16px），两行正好 32px；
   再用 align-self: center 让 span 在 32px 标签盒内垂直居中 ——
   这样单行（16px）和两行（32px）两种情况，文字中心都 == 输入框中心。
   另：取消汉字均分（justify），英文词间空格会被 justify 拉伸，改回左对齐。
   选择器带 html:lang(en)，中文界面完全不受影响。 */
html:lang(en) .pb-label-4ch {
  line-height: 16px;
  text-align: left;
  text-align-last: left;
  align-self: center;
}

/* 串口设置区（右侧「串口设置」面板 + 系统设置→串口参数）：
   4 个标签 label-width=68px + .pb-label-4ch 已经让 4 字宽度对齐，
   wrapper 100% 自然继承父容器同宽。
   格子内文本全部左对齐（覆盖 EP 默认）。
   - select 的 input/placeholder/selected-item：默认已经是 left，无需重写。
   - .el-input__inner 默认是 center，需显式覆盖为 left。
   - 波特率已从拨码器改为普通输入框：左右内边距交回 .el-input__wrapper 默认的
     0 11px，与同区 select 完全一致（之前为让开右侧拨码箭头而写的
     padding-left:15px / padding-right:32px 必须去掉，否则文本会整体偏左）。 */
.serial-config-item .el-input__inner {
  text-align: left;
}
/* EP 的 .el-input__wrapper 默认内边距是 11px，而同组 select 的 .el-select__wrapper
   默认是 12px —— 差 1px 会让「9600」比「8 / 1 / 无」左缩 1px，统一到 12px。 */
.serial-config-item .el-input__wrapper {
  padding-left: 12px;
  padding-right: 12px;
}

/* 串口按钮用：6 字宽度（84px = 6 × 14px 汉字宽）。
   把按钮里的文字包一层 span.pb-btn-6ch，文字按字间距均分，
   首字贴左、末字贴右，与按钮宽度无关——不同字数的"连接天平(4)/刷新串口列表(5)/断开(2)"
   在视觉上对齐到同一根左边界和右边界。 */
.pb-btn-6ch {
  display: inline-block;
  width: 84px;
  text-align: justify;
  text-align-last: justify;
  -moz-text-align-last: justify;
  /* 按钮内文字偏下，重置 baseline */
  vertical-align: middle;
}

/* ——— 状态指示灯 ——— */
.dot {
  display: inline-block; width: 8px; height: 8px; border-radius: 50%;
  margin-right: 5px; vertical-align: middle;
}
.dot.ok   { background: var(--ok); }
.dot.warn { background: var(--warn); }
.dot.err  { background: var(--danger); }
.dot.off  { background: var(--muted); }

/* ——— 关于页 ——— */
.about-page {
  background: var(--bg-2); border-radius: var(--radius-md); padding: 22px 26px;
  max-width: 720px; margin: 24px auto;
  box-shadow: var(--shadow-sm);
}
.about-page h2 { font-size: 18px; margin: 0 0 12px; }
.about-page .meta { color: var(--muted); font-size: 13px; }

/* Toast */
#toast {
  /* B 类（全局操作）：固定在浏览器窗口中心，多条垂直堆叠且整体居中 */
  position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);
  z-index: 9999;
  display: flex; flex-direction: column; align-items: center;
  pointer-events: none;   /* 容器本身不挡点击，toast-item 自行恢复 */
}
#toast .toast-item { pointer-events: auto; }
/* A 类（输入控件触发）：锚定到控件下方，独立 fixed 定位，坐标由 JS 计算 */
.toast-item.toast-anchored {
  position: fixed;
  z-index: 9999;
  margin-top: 0;
}
.toast-item {
  background: rgba(31, 42, 60, 0.92);
  color: #fff; padding: 9px 16px;
  border-radius: var(--radius-sm);
  margin-top: 8px; font-size: 13px;
  animation: toastIn 0.25s ease;
}
.toast-item.ok  { background: var(--ok); }
/* 错误提示停留更久（JS 侧 6~8s），文案可能是"自动保存失败：原因 + 怎么办"，
   必须允许换行、限宽，否则一条 toast 横穿整个屏幕。 */
.toast-item.err {
  background: var(--danger);
  max-width: 560px;
  line-height: 1.5;
  white-space: normal;
  cursor: pointer;
}
/* 软提醒：值已保存，但值得复核一眼（如试样净重偏离常规取样量） */
.toast-item.warn {
  background: var(--warn);
  color: #4a2c00;
  max-width: 520px;
  line-height: 1.5;
}
@keyframes toastIn {
  from { transform: translateY(8px); opacity: 0; }
  to   { transform: translateY(0);   opacity: 1; }
}

/* 模态浮层 */
.modal-mask {
  position: fixed; inset: 0; background: rgba(15, 23, 42, .45);
  display: flex; align-items: center; justify-content: center; z-index: 999;
}
.modal-card {
  background: var(--bg-2); border-radius: var(--radius-lg);
  padding: 22px 26px; min-width: 440px; max-width: 560px;
  box-shadow: 0 30px 60px rgba(15,23,42,.25);
}
.modal-title {
  font-weight: 700; font-size: 16px; color: var(--ink);
  margin-bottom: 14px;
}

.serial-table th, .serial-table td {
  padding: 6px 8px; font-size: 13px;
}

.text-muted { color: var(--muted); }
.text-brand { color: var(--brand); font-weight: 600; }
.text-ok    { color: var(--ok); font-weight: 600; }
.text-warn  { color: var(--warn); font-weight: 600; }
.text-err   { color: var(--danger); font-weight: 600; }

/* AIII 负值提示：更小、不加粗、保留警示色、文案按字数平均两行 */
.aiii-warn {
  font-size: 10px;
  font-weight: 400;
  color: var(--warn);
  line-height: 1.4;
  margin-top: 1px;
  white-space: pre-line;
  display: block;
}

/* 「未保存数据」统计卡：有 = 红色（需要注意），无 = 绿色（安心） */
.unsaved-yes { color: var(--danger); font-weight: 700; }
.unsaved-no  { color: var(--ok);     font-weight: 700; }

/* 右侧串口区：三个按钮统一与「连接天平」左对齐。
   Element Plus 默认给相邻按钮加 margin-left:12px，导致换行堆叠时整体缩进。 */
.serial-btns .el-button + .el-button { margin-left: 0; }

/* 串口设置里的「当前生效」来源标签 */
.serial-scope-tag { font-size: 12px; color: var(--muted); margin-bottom: 8px; }
.serial-scope-tag b { color: var(--brand); }

/* 报文解析自动分析器（系统设置 ▸ 串口参数 ▸ 报文解析） */
.parse-analyzer {
  margin: 6px 0 12px;
  padding: 12px;
  background: #fafbfc;
  border: 1px dashed #dcdfe6;
  border-radius: 6px;
}
.parse-analyzed {
  margin-top: 10px;
  padding: 8px 10px;
  background: #fff;
  border: 1px solid #ebeef5;
  border-radius: 4px;
}
.parse-preview { font-size: 12px; color: var(--muted); }
.parse-preview b { color: var(--brand); font-size: 14px; }
.parse-num {
  display: inline-block; margin: 2px 4px 2px 0; padding: 1px 7px;
  font-family: 'SF Mono','Menlo',monospace; font-size: 12px;
  background: #ecf5ff; color: #409eff; border-radius: 10px;
}
.parse-regex {
  font-family: 'SF Mono','Menlo',monospace; font-size: 12px;
  background: #f4f4f5; color: #c41d7f; padding: 1px 6px; border-radius: 3px;
}

.flex { display: flex; }
.flex-1 { flex: 1; }
.gap-8 { gap: 8px; }
.gap-12 { gap: 12px; }
.mt-8  { margin-top: 8px; }
.mt-12 { margin-top: 12px; }
.mt-16 { margin-top: 16px; }

/* 表格 zebra */
.el-table tr.el-table__row--striped td {
  background: #fafbfd !important;
}

/* 历史记录表格：点击选中蓝色高亮，鼠标经过浅蓝色 */
.el-table {
  --el-table-current-row-bg-color: #e6f2ff;
  --el-table-row-hover-bg-color: #f0f7ff;
}
.el-table .el-table__row.selected-row > td,
.el-table .el-table__row--striped.selected-row > td {
  background: #e6f2ff !important;
}

/* 后台「用户管理」表格：各列内容单行不换行，操作列按钮紧凑排列 */
#admin-app .el-table td.el-table__cell .cell {
  white-space: nowrap;
  overflow: visible;
}
#admin-app .el-table td.el-table__cell .cell .el-button + .el-button {
  margin-left: 6px;
}
#admin-app .el-table td.el-table__cell .cell .el-dropdown {
  margin-left: 6px;
  vertical-align: middle;
}

/* ============================================================
   全站弹窗居中
   ------------------------------------------------------------
   Element Plus 的 dialog 默认停在 top:15vh（水平居中但垂直偏上），
   屏幕越高越明显地"吊在半空"。这里把 dialog 与 MessageBox（确认/覆盖/
   清除/退出等所有弹窗）统一挪到视口正中。

   用 flex + margin:auto 而不是 align-items:center：
   内容比视口还高时，auto margin 会自动退成 0，顶部依然能滚动到，
   而 align-items:center 会把超出部分顶到视口外、上下都够不着。

   抽屉（.el-drawer）直接挂在 .el-overlay 下，不经过 .el-overlay-dialog，
   因此不受影响，仍贴右侧。
   ============================================================ */
.el-overlay-dialog {
  position: fixed;
  inset: 0;
  display: flex;
  overflow: auto;
}
.el-overlay-dialog > .el-dialog,
.el-overlay-dialog > .el-message-box {
  margin: auto !important;          /* 水平 + 垂直同时居中 */
  top: auto !important;
  transform: none !important;
  max-height: calc(100% - 48px);
}
/* 内容超高时让 dialog 自己滚，而不是把整个遮罩撑长 */
.el-overlay-dialog > .el-dialog {
  display: flex;
  flex-direction: column;
}
.el-overlay-dialog > .el-dialog > .el-dialog__body {
  overflow: auto;
  min-height: 0;
}
/* MessageBox（确认覆盖 / 确认清除 / 确认删除 / 退出等）走的是另一套容器
   .el-overlay-message-box，EP 自带 flex 居中；这里再显式写一遍，
   免得主题变量或后续升级把它挪回顶部。 */
.el-overlay-message-box {
  display: flex;
  align-items: flex-start;
  justify-content: center;
}
.el-overlay-message-box > .el-message-box {
  margin: auto !important;
}

/* ============ 主界面广告位 ============ */
.pb-ad {
  width: 100%;
}
.pb-ad-link {
  display: block;
  width: 100%;
}
/* 固定 8:3 长宽比；图片按宽缩放、cover 裁剪不留白 */
.pb-ad-img {
  display: block;
  width: 100%;
  aspect-ratio: 8 / 3;
  object-fit: cover;
  border-radius: 6px;
  cursor: pointer;
}
/* 图片失效时的占位文本：占用同样 8:3 区域，居中灰字 */
.pb-ad-fallback {
  width: 100%;
  aspect-ratio: 8 / 3;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #909399;
  font-size: 13px;
  background: #f5f7fa;
  border: 1px dashed #dcdfe6;
  border-radius: 6px;
  box-sizing: border-box;
}
