:root {
  --bg: #f4f7fa;
  --panel: #ffffff;
  --ink: #1f2d3d;
  --muted: #6b7a8d;
  --line: #e2e8f0;
  --primary: #0e7c86;
  --primary-d: #0a5f67;
  --danger: #d9534f;
  --shadow: 0 2px 10px rgba(20, 40, 60, 0.06);
  --radius: 12px;
  /* 🆕 v429（用户：表头遮挡内容仍透底）：--card 被引用 10 处却从未定义 ⇒ background 全部落空成透明。
     定义为不透明白，sticky 表头/assess 输入等一次性修好。 */
  --card: #ffffff;
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
  background: var(--bg);
  color: var(--ink);
  font-size: 15px;
  line-height: 1.5;
  -webkit-text-size-adjust: 100%;
}

/* Header
   🆕 v278：页签上移到顶行 —— 🩺 图标 + 页签 + 夜间按钮共处一条 header，
   去掉「脉谱健康」标题文字（按需求），让页签成为顶行的主角。
   🆕 v499（用户第 3 项）：页眉改**两行**（`.hdr-top` + `.hdr-sub`）。
   ⚠️ 父层由 flex 行改成 block：行内对齐（align-items / gap）**整体下移到 `.hdr-top`**，
      父层只负责纵向堆叠。`.brand` 已在 v423 退役，父层不再需要任何行内参数。
      漏搬这两条的话，页签与主题按钮会立刻失去垂直居中（本次最易漏的一处）。 */
.app-header {
  display: block;
  /* P1 适配：顶部 padding 叠加刘海屏/灵动岛安全区，避免吸顶 header 被摄像头遮挡 */
  padding: calc(8px + env(safe-area-inset-top, 0px)) 12px 8px;
  background: linear-gradient(120deg, #0e7c86, #14a0a8);
  color: #fff; position: sticky; top: 0; z-index: 20;
}
/* row1：7 个主页签 + 主题按钮（原 `.app-header` 的 flex 行内参数原样搬来） */
.hdr-top { display: flex; align-items: center; gap: 8px; }
/* 🆕 v578（用户 2026-11-01 第 3 项）：首页的页签行**右对齐** ——
   品牌行（logo + 名称 + 主题按钮）占了上面一行的左半边，页签整行推到右侧，
   正好落在「标题图标和 logo 图案的右侧下方」（用户原话）。
   ⚠️ 光写 `justify-content: flex-end` **没用**：`.tabs` 是 `flex: 1 1 auto`（撑满剩余宽度），
      撑满的盒子里再靠右对齐也没有位移。必须同时把它改成 `flex: 0 1 auto`（宽度=内容宽），
      再 `margin-left: auto` 把剩余空间全推到左边。第一版就是漏了这条，截图里页签仍贴左。
   ⚠️ 只在首页生效：其余 5 个页签没有品牌行，页签必须仍从左边起，否则整条页眉会突然右移。 */
/* 🆕 v580：首页页签改回**左对齐** —— 标题要落在页签之下并与「首页」按钮左缘对齐，
   页签若仍右推（v578 口径），标题就得跟着漂到屏幕中间，与用户「居左排列」相悖。 */
.tabs { flex: 1 1 auto; }
body[data-tab="home"] .hdr-top > .tabs { margin-left: 0; }
/* 🆕 v579（用户 2026-11-01 第 4 项）：页眉在**桌面档**并成一排 ——
   [logo + 脉谱健康 + 🌙] ……… [7 个页签] [头像]。
   用户原话：「网页版的这个页签向上提一行，与脉谱健康的标题行的自动按钮对齐。」
   ── 做法 ──
     新增一层 `.hdr-row` 把品牌行与页签行包起来（HTML 已改），它接管原来三行各自那套
     `max-width:1100px; margin:auto; padding:0 16px`：
       · 外层 `.app-header` 仍是 block + 全宽背景（渐变不能跟着缩到 1100，否则页眉会变成一条窄带）；
       · `.hdr-row` 只负责「居中容器 + 一行 flex」，`gap:14px` 给品牌与页签之间留一口气；
       · `.hdr-top` 由 block 变成 `flex:1 1 auto`（吃掉剩余宽度），页签靠它内部的
         `.tabs{margin-left:auto}` 继续右对齐 —— v578 那条右对齐规则因此原样有效。
   ⚠️ 内边距**只能由 `.hdr-row` 一层给**：原来 `.hdr-top` / `.hdr-brand` 各自还有 16px，
      两层一叠页签会整体缩进 32px，与下方卡片盒错位（v520/v578 都在这条上栽过）。
   ⚠️ 非首页没有品牌行，`.hdr-row` 里只剩 `.hdr-top` 一个子项 —— flex 下它自己撑满，
      页签仍从左边起，与改造前逐像素一致。 */
/* 🆕 v580（用户 2026-11-01 第 1 项）：「这个页眉太窄，把高度调整成和后面 6 个页签的高度一样，
   上面的页眉还是居左排列，脉谱健康的标题在页签之下，和首页按钮对齐。」
   —— 已与用户确认走「页签在上、标题在下」：
        第 1 行：[首页按钮][指标筛查]…[会员中心] ……… [头像]
        第 2 行：[logo][脉谱健康 / 检验趋势与用药追踪][自动]
   ── 为什么用 grid 而不是再套一层 flex ──
     两行要「等高」（用户要求的「和 6 个页签的高度一样」）+ 头像要钉在第 1 行右端，
     `grid-template-areas` 一行写清最省事：
        "tabs ava" / "brand brand"
     两行的行高统一吃 `--hdr-h` ⇒ 以后只改一个变量就能整体加高/压扁。
   ⚠️ 页签不再右对齐（v578 那条 `margin-left:auto` 的右推不再需要）：标题要落在页签之下
      且与「首页」按钮左缘对齐，页签若仍右推，标题就会跟着漂到屏幕中间，与「居左」相悖。
   ⚠️ avatar 在 DOM 里排在 `.hdr-top` 之后、`.hdr-brand` 之前（index.html 已改）——
      grid 布局下 DOM 顺序只影响读屏，位置由 grid-area 决定；手机档回 flex 时才靠 order 复位。 */
.hdr-row {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas:
    "tabs ava"
    "brand brand";
  align-items: center;
  column-gap: 14px; row-gap: 0;
  --hdr-h: 42px;                 /* 两行共用的行高 = 用户要的「和页签一样高」 */
  max-width: 1100px; margin-left: auto; margin-right: auto;
  padding-left: 16px; padding-right: 16px;
}
/* 第 1 行：页签（左起，首页按钮即容器左缘）+ 头像（行尾） */
.hdr-row > .hdr-top { grid-area: tabs; min-width: 0; min-height: var(--hdr-h); }
.hdr-row > .hh-ava { grid-area: ava; flex: 0 0 auto; margin-left: 0; }
/* 第 2 行：品牌（左缘与「首页」按钮左缘同一条竖线） */
.hdr-row > .hdr-brand { grid-area: brand; justify-self: start; min-height: var(--hdr-h); }
body:not([data-tab="home"]) .hh-ava { display: none; }
/* ⚠️ 头像的**圆形外观**（34×34 / 50% / 白描边）仍写在文件下部「品牌行」那一节里，
   选择器已并成 `.hdr-brand .hh-ava, .hdr-row > .hh-ava` 两支 —— 见 v579 注释。 */
/* 上下文行 `.hdr-sub` 仍是独立一行，沿用 v520/v578 的对齐口径 */
.app-header .hdr-sub {
  max-width: 1100px; margin-left: auto; margin-right: auto; padding-left: 16px; padding-right: 16px;
}

/* ══════════════════════════════════════════════════════════════════════════════
   🆕 v578（用户 2026-11-01 第 3 项）：页眉「品牌行」—— 与页签行合并成**一块**页眉

   ── 背景（为什么要有这一行）──
     用户原话：「网页版和 exe 版本的页眉 [两个色块] 合并在一起，仍然保持居中，左边是
     [脉谱健康] 加一个 logo 图案，[日夜模式切换] 的按钮放到 logo 的右方，[切换页面的按钮]
     向右移动，放到标题图标和 logo 图案的右侧下方。」
     改造前是**两块**：上面一条深青绿的页签带，下面一张浅一号的 `.home-hero` 卡片，
     中间还有 14px 页边距 ⇒ 看着像「两个色块叠着」。现在把 hero 的内容整体搬进页眉，
     与页签行共用 `.app-header` 那一道渐变，只剩一块。

   ── 版式（一行 flex，顺序即视觉顺序）──
     [logo 砖 30] [脉谱健康 / 检验趋势与用药追踪] [🌙 按钮] ………… [患者头像 34]
      · 主题按钮紧贴标题右侧（`flex: 0 0 auto`，不参与撑满）= 用户要的「logo 的右方」；
      · 头像用 `margin-left:auto` 独占最右，与改造前位置一致。

   ── 为什么 logo 要包一枚「白底圆角砖」──
     `assets/brand/icon-mark.png` 是**白底**的 3D「MP」图标（不是抠图，四角带白）。
     直接贴到青绿渐变上会露出一块白方块的硬边（v560 抠图那次踩过同样的坑）。
     包进 30×30、圆角 8px 的白砖后它读作一枚 App 图标 —— 与手机桌面图标同源，也不必另做资源。

   ── 白字是刻意的 ──
     底色是页眉的青绿渐变（永远深于白字）⇒ 标题 / 副标题一律 #fff / rgba(255,255,255,.86)，
     **不设** `html[data-theme="dark"]` 下的文字反转；暗色只让渐变整体压深（.app-header 自带）。

   ── 显隐 ──
     只有首页有品牌行（`body:not([data-tab="home"])` 隐藏）⇒ 其余页签的页眉逐像素不变。
     ⚠️ 手机版首页**也要显示**（见文件后部 640px 媒体查询）：原先手机版首页是靠隐藏整条页眉 +
        页面里的 `.home-hero` 来省竖向空间，hero 搬走后品牌行必须顶上，否则首页没有标题、
        也没有主题切换入口。高度 30px + 上下文行归零，比原来的 hero 卡片更省。

   ── ⚠️ 窄屏中文断行（坑 89）──
     `.hb-txt` 是 flex 子项且含中文 ⇒ 必须 `min-width: 0`，否则 `min-width:auto` 会解析为
     1 个汉字宽，把右侧按钮挤出容器。副标题再加单行省略号，避免窄屏折成两行把页眉顶高。 */
.hdr-brand { display: flex; align-items: center; gap: 10px; padding: 0; }
body:not([data-tab="home"]) .hdr-brand { display: none; }
.hdr-brand .hb-logo {
  flex: 0 0 auto; width: 30px; height: 30px; border-radius: 8px; overflow: hidden;
  background: #fff; box-shadow: 0 1px 4px rgba(0, 0, 0, .18);
  display: flex; align-items: center; justify-content: center;
}
.hdr-brand .hb-logo img { width: 100%; height: 100%; object-fit: contain; display: block; }
.hdr-brand .hb-txt { flex: 0 1 auto; min-width: 0; }
.hdr-brand .hh-title {
  margin: 0; font-size: 19px; font-weight: 700; letter-spacing: .5px; line-height: 1.2; color: #fff;
}
.hdr-brand .hh-sub {
  margin: 1px 0 0; font-size: 12px; line-height: 1.35; color: rgba(255, 255, 255, .86);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* 主题按钮：与标题同高（26px）的玻璃胶囊，紧贴标题右侧。
   ⚠️ `min-height` 必须显式钉住：文件中部 `@media (max-width:640px) .btn { min-height:40px }`
      （触控目标加强）会在手机版把它顶到 40px，比整行品牌文字还高，页眉会突然变厚。
      本选择器 (0,4,0) 压过那条 (0,1,0) ⇒ 显式写死即可，不必改那条全局规则。 */
.hdr-brand .btn.ghost.hb-theme {
  flex: 0 0 auto; height: 26px; min-height: 26px; padding: 0 10px; border-radius: 999px;
  display: inline-flex; align-items: center; font-size: 12.5px; line-height: 1; white-space: nowrap;
}
.hdr-brand .hh-ava,
.hdr-row > .hh-ava {
  /* ⚠️ v579：`margin-left:auto` 只在「头像在品牌行内」时才是撑到行尾的手段；
     搬进行内后 `.hdr-top{flex:1}` 已经把剩余宽度吃干净，auto 退化为 0。
     这里显式写 0，避免以后有人把 `.hdr-top` 改回 `flex:0 1 auto` 时页签又被顶开。 */
  flex: 0 0 auto; margin-left: 0;
  width: 34px; height: 34px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: rgba(255, 255, 255, .22); border: 1px solid rgba(255, 255, 255, .5);
  font-size: 15px; font-weight: 700; color: #fff; overflow: hidden;
}
.brand { display: flex; align-items: center; gap: 0; flex: 0 0 auto; }
.brand .logo {
  display:inline-flex; align-items:center; justify-content:center; width:28px; height:28px; color:#fff;
  /* 🆕 v352：由 <span> 改为 <button> 后必须重置默认外观（否则出现灰底/边框/内边距，顶栏会歪）。
     并用「content-box + 6px padding + 四向负 margin」把点击区从 28px 撑到 40px，
     同时让顶栏尺寸与间距**完全不变**。
     ⚠️ 全局是 `* { box-sizing: border-box }`，不显式改回 content-box 的话，
        padding 会从 28px 里扣，SVG 被挤成 16px。 */
  box-sizing: content-box; padding: 6px; margin: -6px;
  background: none; border: 0; border-radius: 8px;
  -webkit-appearance: none; appearance: none; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.brand .logo:active { background: rgba(255,255,255,.18); }
.brand .logo:focus-visible { outline: 2px solid #fff; outline-offset: 1px; }
.brand .logo svg { width:100%; height:100%; stroke:#fff; }
.brand h1 { margin: 0; font-size: 19px; }

/* 🆕 v352：左上角图标的下拉面板（版本号 + 服务端联调配置）。
   全部颜色走 CSS 变量 ⇒ 夜间**自动**生效（夜间是覆盖 :root 变量实现的），
   不写 `html[data-theme="dark"]` 覆盖块 —— 硬编码白底/深字是本项目夜间问题的老根因。
   z-index 2100 > .app-header 的 20，确保浮层盖在吸顶顶栏之上。 */
.brand-menu {
  position: fixed; top: 52px; left: 12px; z-index: 2100;
  width: min(320px, calc(100vw - 24px));
  display: none; flex-direction: column; gap: 8px;
  padding: 12px 14px 14px;
  background: var(--panel); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow);
  font-size: 13px; line-height: 1.5;
  max-height: calc(100vh - 76px); overflow: auto;
}
.brand-menu.show { display: flex; }
.bm-head { display:flex; align-items:center; justify-content:space-between; gap:8px; }
.bm-head b { font-size: 14px; }
.bm-badge { flex: 0 0 auto; font-size: 11px; padding: 1px 7px; border-radius: 9px;
  background: var(--bg); color: var(--muted); border: 1px solid var(--line); white-space: nowrap; }
.bm-badge.on { color: #fff; background: var(--primary); border-color: var(--primary); }
.bm-row { display:flex; align-items:baseline; justify-content:space-between; gap:10px; }
.bm-row > span { flex: 0 0 auto; color: var(--muted); }
.bm-row > b { font-weight: 600; text-align: right; word-break: break-all;
  font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 12px; }
/* 🆕 v448：官网链接（「关于脉谱健康」里的官方网站地址）。
   父级 <b> 是 text-align:right + 等宽字体，这里只补「可点」的视觉：主题色 + 下划线 +
   触摸反馈。用 currentColor 之外的主题变量是为了在浅/深色主题下都保持对比度。 */
.bm-link { color: var(--primary); text-decoration: underline; text-underline-offset: 2px; }
.bm-link:active { opacity: .65; }
/* 🆕 v536（项4）：「本机轻量数据」值旁的文件位置链接（#bm-bak-loc 由按钮改为链接） */
.bm-val-group { display: inline-flex; align-items: center; gap: 6px; }
.bm-file-loc { cursor: pointer; font-size: 12px; }
.bm-sep { height:1px; background: var(--line); margin: 2px 0; }
.bm-bar { height: 6px; border-radius: 4px; background: var(--bg); border: 1px solid var(--line); overflow: hidden; }
.bm-bar-fill { height: 100%; width: 0; border-radius: 3px; background: var(--primary); transition: width .2s ease; }
.bm-bar-fill[data-lvl="ok"] { background: #27ae60; }
.bm-bar-fill[data-lvl="warn"] { background: #e67e22; }
.bm-bar-fill[data-lvl="crit"] { background: #e74c3c; }
.bm-sub { color: var(--muted); font-size: 12px; }
.bm-lab { color: var(--muted); font-size: 12px; }
.bm-input { width:100%; padding: 7px 9px; border-radius: 8px;
  border: 1px solid var(--line); background: var(--bg); color: var(--ink);
  font-size: 12px; font-family: ui-monospace, Menlo, Consolas, monospace; }
.bm-input:focus { outline: none; border-color: var(--primary); }
.bm-tip { color: var(--muted); font-size: 11.5px; line-height: 1.55; }
.bm-tip code { background: var(--bg); border: 1px solid var(--line); border-radius: 4px;
  padding: 0 3px; font-size: 11px;
  /* ⚠️ 用 overflow-wrap 而不是 word-break:break-all —— 后者会在任意字符处断行，
     把 `adb reverse tcp:8787 tcp:8787` 折成 `…tcp:87` / `87`，命令读起来就断了。
     break-word 优先在空格断行，只有单个超长词才硬断。 */
  overflow-wrap: break-word; word-break: normal; }
.bm-acts { display:flex; gap:8px; }
.bm-btn { flex: 1 1 0; padding: 8px 10px; border-radius: 8px; cursor: pointer;
  border: 1px solid var(--line); background: var(--bg); color: var(--ink); font-size: 12.5px; }
.bm-btn.primary { background: var(--primary); border-color: var(--primary); color: #fff; }
.bm-btn:active { transform: translateY(1px); }
.bm-msg { font-size: 12px; }
.bm-msg.ok { color: var(--primary); }
.bm-msg.err { color: var(--danger); }
.subtitle { margin: 0; font-size: 12px; opacity: 0.85; }
.header-actions { display: flex; gap: 8px; flex: 0 0 auto; }

/* 🆕 v499（用户第 6 项）：日夜切换按钮**只在首页**显示，其余页签不再需要。
   ⚠️ 选择器刻意带 `[data-tab]` 前缀（写成 `body[data-tab]:not([data-tab="home"])`）——
   只写 `body:not([data-tab="home"])` 时，JS 尚未写入 data-tab 的那一瞬也会命中；
   万一脚本异常，按钮会**永久消失**，用户就再也切不了主题。带前缀可安全回退为「显示」。 */
body[data-tab]:not([data-tab="home"]) #btn-theme { display: none; }

/* ══════════════════════════════════════════════════════════════════════════════
   🆕 v499（用户第 3 项）：页眉第二行 —— 「返回键 + 子页签 / 页名」 `.hdr-sub`

   设计口径（对应用户原话「指标趋势、检验记录页上的页签上移到绿色的页眉上……绿色页眉
   显示页签名字：用药记录等和返回键，点击退出页签时返回首页」）：
     · 指标趋势页 → 本行放**分类子页签**（原 #chart-tabs，从图表方框上方整体上移）
     · 检验记录页 → 本行放**图片识别 / 文件识别**（原 #lab-entry-pair，同样上移）
     · 用药记录 / 日常记录 / 个人档案 / 会员中心 → 本行放**页名**
     · 首页 → 整行隐藏（首页本身已是 6 个入口窗口，不需要页名，也避免一条绿色空带）
   ✅ 显隐**只由 `body[data-tab="…"]` 驱动**。该属性由 js/app.js 的 `initTabs()` 与 `.panel`
      的 class 切换**同帧写入** ⇒ 只有一套状态，不存在「页签切了、子页签没跟着切」。
   ✅ 行高固定（min-height）⇒ 每个页面正文的起始 y 完全一致，满足用户
      「其他几个页面上移保持相同的页边距」。
   ⚠️ 子页签在顶栏里的配色必须**显式**覆盖（含深色主题）：`.chart-tab` 在深色块里被改成
      `#243140` 深底，而顶栏底色是不随主题变的青绿渐变，深底 pill 会糊在青绿上看不清。
      且 `html[data-theme="dark"] .chart-tab` 是 (0,2,1)、`.app-header .chart-tab` 只有 (0,2,0)
      —— 不写成 `html[data-theme="dark"] .app-header .chart-tab` 就会**被深色块抢走**。
      （本文件 `.app-header .btn.ghost` 处踩过同一个坑，注释在 L198 附近。） */
.hdr-sub {
  display: flex; align-items: center; gap: 8px; flex-wrap: nowrap; overflow: hidden;
  margin-top: 6px; min-height: 34px;
}
body[data-tab="home"] .hdr-sub { display: none; }

/* 🆕 v514（用户第 2 条，含 2026-10-14 口径修正）：**手机版首页隐藏整条青绿页眉**。
   ── 用户原话（初版）：「主页的上面的蓝色部分不要了……其他页签上面的页眉还保持不变。」
   ── 用户原话（口径修正）：「网页版的不改，手机版的超出手机屏幕，所以要把上面空白的位置
      压缩掉，所以要改的是手机版的，不是网页版的。」
   ⇒ 本规则**只在手机版（≤640px，本项目既有的手机断点）生效**。
      网页版 / 桌面便携版（宽 > 640px）的首页**保持 v513 原样**（页眉 + 7 个页签 +
      右上角 🌙 夜间按钮），本次改造对它零影响。
   ── 为什么手机版可以整条不要：首页本身就是 6 个入口窗口（`.home-grid` 的 `data-goto` 覆盖
      trend / lab / med / vitals / profile / member 全部页签）⇒ 页眉那 7 个页签在首页是纯冗余；
      而这条页眉（含顶部 `env(safe-area-inset-top)` 安全区）在 390×844 手机上约 100px，
      正是用户说的「上面空白的位置」—— 去掉后首屏直接是 hero 卡。
   ⚠️ 只按 `data-tab` + 视口宽度隐藏，**不改任何 JS**：`syncHeaderOffset()` 量到 0 高度也只是把
      `--cm-header-h` 置为 0px，`.hdr-sub` 在首页本来就 hidden，两者都不会留空带。
   ⚠️ 刻意**不**对 `.hdr-top` 单独动手（不写 `body[data-tab="home"] .hdr-top{display:none}`）：
      那会留下一条仍有背景渐变的 `.app-header` 空壳，反而是一条比现在更窄的蓝带。
   ⚠️ 断点选 640px 而不是按 UA 判定：本项目手机断点一直是 640（见下方各处 @media），
      与「网页版 / 手机版」的分界线一致，且桌面端窗口拖窄到 640 以下时也自然收益。 */
@media (max-width: 640px) {
  /* 🆕 v533（用户需求 6）：首页也要保住底部页签栏。
     ── 原实现：`body[data-tab="home"] .app-header { display: none }` —— 但 #tabs（底栏）
        v278 起挂在 .app-header **内部**，祖先 display:none 会连 fixed 定位的底栏一起藏掉
        ⇒ 切到首页后底部切换栏消失、用户「找不到切换栏」。
     ── v533 的修法：首页**不再隐藏整个页眉**，改为把页眉壳掏空（背景/内边距/高度全清零），
        只藏里面的 .hdr-top / .hdr-sub 两行内容；#tabs 因此保留渲染，fixed 底栏照常显示。
     ── 🆕 v578（用户 2026-11-01 第 3 项）**再次改口径**：品牌行搬进页眉后，页眉**不能再掏空**
        —— 掏空的话手机版首页就没有产品名、也没有主题切换入口了（原先是页面里的
        `.home-hero` 在顶这个位置，hero 已删）。现在手机版首页的页眉 = 一条**紧凑品牌行**
        （logo 28 + 名称 17px + 按钮 24px + 头像 30，总高约 44px），比原来那张 hero 卡片
        （上下 padding 13/12 + 标题两行 ≈ 70px）还矮，用户的「压缩上面空白」口径仍然成立。
     ⚠️ `.hdr-top` 仍要保留渲染（`#tabs` 是它的子节点、手机端 position:fixed 做底栏），
        只把它的内容高度归零：`min-height:0; height:auto` 即可（fixed 子节点不占流内高度）。 */
  body[data-tab="home"] .hdr-top { display: block; min-height: 0; height: auto; }
  body[data-tab="home"] .hdr-sub { display: none; }
  /* 🆕 v578：文件前部给页眉三行补的 16px 内边距**只在桌面档有意义**（那是为了与 .content 的
     16px 对齐）。手机档 `.content` 的内边距是 8px，页眉外层本身又有 12px ⇒ 再叠 16px 会让
     标题离屏幕边缘 28px，比卡片（8px）缩进太多。这里清零，回到改造前的 12px 口径。
     🆕 v579：内边距已统一收到 `.hdr-row` 一层，这里连它一起清零。 */
  .app-header .hdr-row,
  .app-header .hdr-top, .app-header .hdr-sub, .app-header .hdr-brand { padding-left: 0; padding-right: 0; }
  /* 🆕 v579：手机档页签是 position:fixed 底栏，`.hdr-top` 在行内是 0 宽的空壳 ——
     `.hdr-row` 保持 flex（品牌 + 空壳 + 头像一线排开），头像仍落在最右端。 */
  /* 🆕 v580：桌面档 `.hdr-row` 是两行 grid，手机档必须**回到 flex 单行** ——
     手机档页签是 position:fixed 底栏（不占流内位置），品牌与头像要同一行排开。
     DOM 顺序是 [页签壳][头像][品牌]（为桌面 grid 服务）⇒ 这里用 order 复位成 [品牌][页签壳][头像]。 */
  .hdr-row { display: flex; align-items: center; gap: 10px; }
  .hdr-row > .hdr-brand { order: 1; flex: 1 1 auto; min-width: 0; min-height: 0; }
  .hdr-row > .hdr-top { order: 2; flex: 0 0 auto; min-height: 0; }
  .hdr-row > .hh-ava { order: 3; }
  /* 品牌行紧凑档：换行风险最高的组合（iPhone SE 375px）也要一行放得下 */
  .hdr-brand { gap: 8px; padding: 0 0 3px; }
  .hdr-brand .hb-logo { width: 28px; height: 28px; border-radius: 7px; }
  .hdr-brand .hh-title { font-size: 17px; letter-spacing: .3px; }
  .hdr-brand .hh-sub { font-size: 11px; }
  .hdr-brand .btn.ghost.hb-theme { height: 24px; min-height: 24px; padding: 0 8px; font-size: 11.5px; }
  /* 🆕 v579：头像已不在 .hdr-brand 内，手机档尺寸改挂到 .hdr-row 上 */
  .hdr-row > .hh-ava { width: 30px; height: 30px; font-size: 14px; }
}

/* 返回键：非首页出现，点击回首页（绑定见 js/app.js 的 initHeaderNav）。
   ⚠️ 用内联 SVG 折角，不用 `‹` 字符 —— 同用户第 1 项（`↻` 在安卓 WebView 渲染成空白）的成因。 */
.hdr-back {
  display: none; flex: 0 0 auto;
  width: 28px; height: 28px; padding: 0; border-radius: 50%;
  border: 1px solid rgba(255,255,255,.42); background: rgba(255,255,255,.14);
  color: #fff; cursor: pointer; align-items: center; justify-content: center;
  -webkit-appearance: none; appearance: none; -webkit-tap-highlight-color: transparent;
}
body[data-tab]:not([data-tab="home"]) .hdr-back { display: inline-flex; }
.hdr-back:hover { background: rgba(255,255,255,.28); }
.hdr-back:active { background: rgba(255,255,255,.42); }
.hdr-back svg { display: block; }

/* 页名：只出现在「没有子页签」的四个页签上 */
.hdr-sub-name {
  display: none; color: #fff; font-size: 15px; font-weight: 600;
  letter-spacing: .3px; white-space: nowrap;
}
body[data-tab="med"] .hdr-sub-name,
body[data-tab="vitals"] .hdr-sub-name,
body[data-tab="profile"] .hdr-sub-name,
body[data-tab="member"] .hdr-sub-name { display: block; }

/* 🆕 v536（项2）：登录后账户名显示在会员中心页签页眉右侧（#hdr-sub-user）。
   :not(:empty) —— 未登录时 JS 置空，不占位；有昵称才显示并推到行尾。 */
.hdr-sub-user {
  display: none; margin-left: auto; color: #fff; font-size: 13.5px; font-weight: 600;
  white-space: nowrap; max-width: 42%; overflow: hidden; text-overflow: ellipsis;
}
body[data-tab="member"] .hdr-sub-user:not(:empty) { display: block; }

/* 两个子页签条：默认隐藏（在别的页不占位、不影响行高），只在各自所属页出现 */
#chart-tabs, #lab-entry-pair { display: none; }
body[data-tab="trend"] #chart-tabs { display: flex; }
body[data-tab="lab"] #lab-entry-pair { display: flex; }
#lab-entry-pair { margin: 0; }
/* 顶栏内布局：子页签吃满剩余宽度、绝不换行（换行会把固定行高顶开） */
.app-header .chart-tabs { flex: 1 1 auto; min-width: 0; margin: 0; flex-wrap: nowrap; overflow: hidden; }
.app-header .chart-tabs-pager { flex: 1 1 100%; min-width: 0; max-width: 100%; }
.app-header .chart-tabs-row { max-width: 100%; }
.app-header #lab-entry-pair { flex: 0 1 auto; min-width: 0; flex-wrap: nowrap; overflow: hidden; }
/* 高度归一：让「页名行」与「子页签行」的行高严格相等（桌面 34px / ≤640 手机 34px） */
.app-header .chart-tab, .app-header .lab-tab {
  display: inline-flex; align-items: center; height: 28px; padding: 0 12px;
}
.app-header .lab-tab { padding: 0 16px; }
.app-header .chart-tab-nav { width: 28px; height: 28px; font-size: 15px; }

/* 顶栏内子页签配色：深青底 ⇒ 半透明白 + 白字；选中态反过来（白底 + 主色字） */
.app-header .chart-tab, .app-header .lab-tab,
html[data-theme="dark"] .app-header .chart-tab, html[data-theme="dark"] .app-header .lab-tab {
  background: rgba(255,255,255,.14); border-color: rgba(255,255,255,.42); color: #fff;
}
.app-header .chart-tab:hover, .app-header .lab-tab:hover,
html[data-theme="dark"] .app-header .chart-tab:hover, html[data-theme="dark"] .app-header .lab-tab:hover {
  background: rgba(255,255,255,.28); border-color: #fff; color: #fff;
}
.app-header .chart-tab.active, .app-header .lab-tab.on,
html[data-theme="dark"] .app-header .chart-tab.active, html[data-theme="dark"] .app-header .lab-tab.on {
  background: #fff; border-color: #fff; color: var(--primary); box-shadow: none;
}
.app-header .chart-tab-nav, html[data-theme="dark"] .app-header .chart-tab-nav {
  background: rgba(255,255,255,.14); border-color: rgba(255,255,255,.42); color: #fff;
}
.app-header .chart-tab-nav:hover:not(.disabled) { background: rgba(255,255,255,.28); border-color: #fff; color: #fff; }
.app-header .chart-tab-page, html[data-theme="dark"] .app-header .chart-tab-page { color: rgba(255,255,255,.82); }
.app-header .chart-tabs-empty { color: rgba(255,255,255,.85); padding: 0; font-size: 13px; }

/* Tabs
   🆕 v278：改挂在 .app-header 内部，随 header 一起吸顶（不再单独 sticky/top）。
   页签数量多 → 横向滚动；选中态改成白底高亮（原 var(--primary) 在青色 header 上看不清）。
   🆕 v315：左右边缘加渐变蒙层，提示两边还有更多页签。 */
.tabs {
  flex: 1 1 auto; min-width: 0; display: flex; gap: 2px; padding: 0;
  background: transparent; border-bottom: none;
  overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none;
}
.tabs::-webkit-scrollbar { display: none; }
.tabs.tabs-overflow {
  -webkit-mask-image: linear-gradient(to right, transparent 0, rgba(0,0,0,.15) 8px, black 14px, black calc(100% - 14px), rgba(0,0,0,.15) calc(100% - 8px), transparent 100%);
  mask-image: linear-gradient(to right, transparent 0, rgba(0,0,0,.15) 8px, black 14px, black calc(100% - 14px), rgba(0,0,0,.15) calc(100% - 8px), transparent 100%);
}
.tab { border: none; background: transparent; padding: 7px 10px; font-size: 14.5px;
  color: rgba(255, 255, 255, .82); cursor: pointer; border-radius: 8px;
  border-bottom: 2px solid transparent; white-space: nowrap; }
.tab.active { color: #fff; border-bottom-color: #fff; font-weight: 600; background: rgba(255, 255, 255, .16); }

/* 🆕 v499（用户第 4 项）：网页版 / 电脑版的页签也加上图标。
   · 手机端一直有图标（文末 640px 块的 `#tabs.tabs .tab::before`），桌面端此前是纯文字 ⇒ 现在补齐。
   · 图标沿用与「首页六宫格」（📈 指标趋势 / 🧪 检验记录 / 💊 用药记录 / 🩺 日常测量 / 🗂️ 个人档案 / 👑 会员中心）
     完全同一套 emoji，避免混用两套图标风格。
   · ⚠️ 必须只写在 `min-width:641px` 里：手机端 tab 是纵向 flex 卡片，多一个 margin-right 会把图标挤歪。
   · 首页是纯图标按钮（自带 .home-grid-ico）⇒ 用 :not([data-tab="home"]) 排除，避免多出 5px 空档。 */
@media (min-width: 641px) {
  .tab:not([data-tab="home"])::before { content: ""; margin-right: 5px; font-size: 14.5px; line-height: 1; }
  .tab[data-tab="trend"]::before   { content: "📈"; }
  .tab[data-tab="lab"]::before     { content: "🧪"; }
  .tab[data-tab="med"]::before     { content: "💊"; }
  .tab[data-tab="vitals"]::before  { content: "🩺"; }
  .tab[data-tab="profile"]::before { content: "🗂️"; }
  .tab[data-tab="member"]::before  { content: "👑"; }
}

/* Content */
.content { padding: 16px; max-width: 1100px; margin: 0 auto; }
.panel { display: none; animation: fade .25s ease; }
.panel.active { display: block; }
@keyframes fade { from { opacity: 0; transform: translateY(4px);} to {opacity:1; transform:none;} }

/* Buttons */
/* 🆕 v513（用户第 7 项 · UISKILL Critical Rule 9）：原为 `transition: .15s` ——
   只写时长等于 `transition-property: all`，是货真价实的 `transition: all`
   （UISKILL 明令「never use transition: all」）。改用具名属性表。
   ⚠️ 为什么这一条属于「弹窗 / 下拉窗口」范围：`.btn` 正是弹窗族的按钮类
      （.def-popup-content .btn / .ind-add-pop .btn / .scan-add-menu .btn / .ind-abn-btn）。
   属性表取全部「本项目 .btn 各变体真的会变」的属性，避免漏掉某个态导致动画突然消失：
     背景 / 边框 / 文字（:hover / .primary ）、阴影、透明度、滤镜（v513 新增的 :active 按压）、
     变换（scale 类按压）。 */
.btn { border: 1px solid var(--line); background: #fff; color: var(--ink);
  padding: 8px 14px; border-radius: 8px; cursor: pointer; font-size: 14px;
  transition: border-color .15s, background-color .15s, color .15s, box-shadow .15s, opacity .15s, filter .15s, transform .15s; }
.btn:hover { border-color: var(--primary); }
.btn.primary { background: var(--primary); color: #fff; border-color: var(--primary); }
.btn.primary:hover { background: var(--primary-d); }
/* 🆕 v373：`.btn.ghost` 的**默认外观**改为「浅色安全款」，玻璃款显式限定给顶栏。
   ----------------------------------------------------------------------------
   问题（第 4 次踩，前三次都是在使用处打局部补丁）：
     `.btn.ghost { color:#fff; background:rgba(255,255,255,.15) }` 是给**深色/彩色背板**设计的，
     而本 App 的绝大多数面板底色是 `var(--panel)`＝#ffffff ⇒ **白字白底、事实隐形**。
     v373 实测（探针按「文字色 vs 实际合成背板」算 WCAG 对比度）浅色主题下 **9 处 ghost 对比度＝1.00**：
       同意弹窗「不同意」(consent-decline) / 协议弹层 ✕ (legal-close) / 服务弹层 ✕ (service-close) /
       指标设置 ✕ (btn-chart-settings-close) / 指标新增 ✕ (btn-ind-add-close) /
       文件导入「清空」「✕」(btn-file-clear / btn-file-close) / 用药「取消」(btn-med-select-none) /
       档案表单「收起」(btn-profile-edit-close)。
     动态生成的还有 3 处（记录行内编辑「取消」×2 = rec-inline-actions、会员面板「退出」= bv-logout）。
     真机截图已证实：同意弹窗左下角**空着**，本该是「不同意」。
   为什么不再逐个打补丁：
     `css/scan.css` 里已为 `.gal-head`(v269 相册栏) 与 `.md-actions`(v283 合并弹窗) 各打过一次，
     注释自己都写着「⚠️ .btn.ghost 是白字…在浅色对话框里会隐形（已命中 3 次）」。成类问题 ⇒ 改默认值。
   与暗色主题的**对称关系**（这才是不改会越来越乱的原因）：
     `html[data-theme="dark"] .btn`（特异性 0,2,1）本来就压过 `.btn.ghost`（0,2,0）⇒
     **暗色下 ghost 早已是普通按钮外观**（实测 15/15 全部 ≥10.5，无一处隐形）。
     所以「浅色侧反而不安全」是纯粹的疏漏，本轮只是把浅色侧补齐、并把玻璃款收回到真正需要它的地方。
   ⚠️ 顶栏 `.app-header` 用的是 `linear-gradient(...)` 青绿渐变（background-image，不是 background-color）
      ⇒ 那里的 ghost 必须**保持白字玻璃款**，故下面显式声明为特例。
   ⚠️ 判「背景是深是浅」不能只看 `background-color`：渐变只写在 `background-image` 里，
      只看 background-color 会一路穿透到 body 的 `#f4f7fa`，把顶栏按钮误判成「白字白底」。 */
.btn.ghost { background: #eef3f8; color: #2c3e50; border-color: #c8d5e2; }
.btn.ghost:hover { background: #dde7f1; }
/* 特例：深色/渐变顶栏上的玻璃款（唯一真正需要它的地方） */
.app-header .btn.ghost { background: rgba(255,255,255,0.15); color: #fff; border-color: rgba(255,255,255,0.4); }
.app-header .btn.ghost:hover { background: rgba(255,255,255,0.28); }
/* 暗色主题下顶栏按钮**维持改动前的外观**（普通按钮款）——显式写出来，
   否则上面那条 `.app-header .btn.ghost`(0,3,0) 会压过 `html[data-theme="dark"] .btn`(0,2,1)，
   把暗色顶栏按钮也变成白玻璃，属于未经要求的视觉改动。 */
html[data-theme="dark"] .app-header .btn.ghost { background: #243140; color: var(--ink); border-color: var(--line); }
/* ⚠️ `.btn.ghost.danger` 仍是玻璃/红色款（为深色背板设计）。当前全仓库**无任何使用处**
   （index.html 与 js/app.js 都没有 `ghost danger`）⇒ 保留原型不动，但若要新增，请先确认背板是深色。 */
.btn.ghost.danger { background: rgba(217,83,79,0.25); border-color: rgba(255,255,255,0.5); }
.btn.tiny { padding: 4px 10px; font-size: 12px; }
.btn.danger { background: var(--danger); border-color: var(--danger); color: #fff; }
.btn.danger:hover { filter: brightness(0.93); }
.btn.danger:disabled { background: rgba(217,83,79,0.4); border-color: rgba(217,83,79,0.4); color: rgba(255,255,255,0.7); cursor: not-allowed; }
/* 🆕 v295：删/复/改 用同样的边框（原来删按钮 border 透明，与复/改不一致——用户要求统一） */
.btn.danger-text { color: var(--danger); background: transparent; }
.btn.danger-text:hover { background: #fdecea; }

/* 检验记录批量操作工具栏 */
.rec-bulk { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 10px 0; }
/* 🆕 v221：「按天全选」下拉已移除（与日期区间筛选重复），.rec-bulk-day 规则同步删除 */
.sel-col { width: 30px; text-align: center; }
.sel-col input[type="checkbox"] { width: 16px; height: 16px; cursor: pointer; }

/* Cards */
.card { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 16px; margin-bottom: 16px; box-shadow: var(--shadow); }
.card h2 { margin: 0 0 12px; font-size: 16px; }

/* Forms */
.form-inline { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; align-items: center; }
.form-inline input, .form-inline select { padding: 8px 10px; border: 1px solid var(--line);
  border-radius: 8px; font-size: 14px; min-width: 120px; }
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 8px; }
.form-grid label { display: flex; flex-direction: column; font-size: 13px; color: var(--muted); gap: 4px; }
.form-grid input, .form-grid select, .form-grid textarea { padding: 8px 10px; border: 1px solid var(--line);
  border-radius: 8px; font-size: 14px; color: var(--ink); }
.form-grid .span2 { grid-column: 1 / -1; }
/* ── 🆕 v514（用户第 3 条）：添加用药表单「一个字段只占一行」──
   改前：每个字段 = `<label>文字 + 控件</label>` 两行（`.form-grid label` 是 column 布局），
   9 个字段在 2 列网格里 = 5 行 × 2 行高 ⇒ 弹窗必然下拉。用户要求
   「编辑栏之外的文字要放到编辑栏中，这样弹窗不会下拉的很长」。
   改后：`.mf-box` 自身就是**输入框本体**（行内 flex：左侧字段名 + 右侧控件），
   字段名从「框外的标签」变成「框内的前缀」⇒ 每个字段只剩 1 行。
   ⚠️ 只作用于 `.med-form`：`.form-grid` 还被 #form-appointment / #form-profile / 指标编辑等
      6 个表单复用，改全局 label 布局会连带改掉那些窗口（属于未经要求的改动）。 */
.med-form .mf-box {
  display: flex; flex-direction: row; align-items: center; gap: 8px;
  padding: 0 10px; border: 1px solid var(--line); border-radius: 8px;
  background: var(--panel); font-size: 13px;
}
/* 聚焦时整框描边（而不是只描内部控件）—— 控件本身已无边框，没有这条就看不出焦点在哪一格 */
.med-form .mf-box:focus-within { border-color: var(--primary); }
.med-form .mf-lb { flex: 0 0 auto; white-space: nowrap; color: var(--muted); }
.med-form .mf-box > input, .med-form .mf-box > select {
  flex: 1 1 auto; min-width: 0; padding: 8px 0;
  border: 0; border-radius: 0; background: none; font-size: 14px; color: var(--ink);
}
.med-form .mf-box > input:focus, .med-form .mf-box > select:focus {
  outline: none; border-color: transparent; box-shadow: none;
}
/* 窄屏：2 列时每列仅 ~140px，「开始日期(4 字) + 日期控件」会把控件挤到截断
   ⇒ 改单列。总行数与改前的「2 列 × 2 行」持平，不会变得更长。 */
@media (max-width: 640px) { .med-form { grid-template-columns: 1fr; } }
input[type="color"] { padding: 2px; height: 38px; cursor: pointer; }

/* Tables */
.table-wrap { overflow-x: auto; }
/* 🆕 v535（用户需求 5）：「用药记录表的列表部分做成滚动窗口，高度和其他滚动窗口一致」——
   v516 的「高=宽（正方形）」口径退役：JS 侧改调 indScrollPx()（与指标库 / 检验历史记录同一函数），
   这里给一条**同值 CSS 兜底**。兜底的意义（v535 取证实锤的竞态）：renderMedTable 在容器
   display:none（如先进别页签/首屏）时跑，clientWidth=0 ⇒ 旧 setSquareScroll 直接不设 ⇒
   切到用药页后无人补算 ⇒ 列表整块全展开（实测 344px 宽内容铺到 756px 高），与下方
   「用药前后指标对比」窗粘连 —— 即用户截图的「下拉窗口与已有窗口重叠」。
   45vh 与 indScrollPx() 的 max(190, round(45vh)) 同源，JS 跑不到时也保持同一高度口径。 */
#med-list { max-height: 45vh; overflow-y: auto; -webkit-overflow-scrolling: touch; overscroll-behavior: contain; }
table { width: 100%; border-collapse: collapse; font-size: 14px; }
th, td { text-align: left; padding: 9px 10px; border-bottom: 1px solid var(--line); white-space: nowrap; }
th { color: var(--muted); font-weight: 600; font-size: 13px; }
tr:hover td { background: #fafcff; }
.swatch { display: inline-block; width: 12px; height: 12px; border-radius: 3px; margin-right: 6px; vertical-align: middle; }
/* 🆕 v302：检验记录行内编辑 */
.rec-editing { background: #e7f6f7 !important; border-color: #0e7c86 !important; }
html[data-theme="dark"] .rec-editing { background: #0f2f32 !important; border-color: #14a0a8 !important; }
.rec-inline-edit { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; padding: 4px 0; }
.rec-inline-edit input,
.rec-inline-edit select { padding: 6px 8px; border: 1px solid var(--line); border-radius: 6px; font-size: 14px; min-height: 34px; background: #fff; color: var(--ink); }
.rec-inline-edit .rec-edit-date { width: 132px; }
.rec-inline-edit .rec-edit-ind { flex: 1 1 160px; min-width: 120px; max-width: 260px; }
.rec-inline-edit .rec-edit-val { width: 96px; }
.rec-inline-edit .rec-edit-note { flex: 1 1 140px; min-width: 120px; max-width: 260px; }
.rec-inline-actions { display: flex; gap: 6px; margin-left: auto; }
.rec-inline-actions .btn { min-height: 32px; }

.row-actions { display: flex; gap: 6px; }

/* 卡片标题行：标题居左、操作按钮（如指标库「全部/折叠」）居右 */
.card-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin: 0 0 12px; }
.card-head h2 { margin: 0; font-size: 16px; white-space: nowrap; flex-shrink: 0; }
.card-head-actions { display: inline-flex; gap: 6px; flex-wrap: nowrap; flex-shrink: 0; }

/* 指标库「全部/折叠」窗口：默认固定为**视口高的 45%（约半屏）**可上下滚动；展开后不限高。
   🆕 v495（用户）：「手机版指标库按照之前的固定高度来，要留出空间给上下滑动页签用」——
   原来是 `.ind-scroll{max-height:190px}`（v420 起 JS 改按「10 × 实测行高」动态设值），
   但手机上指标库行是卡片式（单行 80~100px），10 行会把窗口顶到 800~1000px、比视口还高，
   页签被顶出屏幕。这里把 CSS 兜底与 JS（applyIndScroll → indScrollPx）统一到 45vh。 */
.ind-scroll { max-height: 45vh; overflow-y: auto; transition: max-height .2s ease; }
.ind-scroll.expanded { max-height: none; }

/* 🆕 v520（用户第 6 条）：网页版「历史记录」窗口 10 列表格在宽屏下被 nowrap 撑到 1253px、
   超出卡片宽度。桌面端改 fixed 布局按容器宽收缩，指标名 / 备注两列允许换行，
   关键列（复选框 / 参考范围 / 操作按钮）钉住宽度，其余列均分剩余空间 ⇒ 不再横向溢出。
   手机端（≤640px）该表已是 flex 卡片，本块用 min-width:641px 隔离、零影响。 */
@media (min-width: 641px) {
  #record-list table { table-layout: fixed; width: 100%; min-width: 0; }
  #record-list th, #record-list td { white-space: normal; }
  #record-list th.wrap-col, #record-list td.wrap-col { word-break: break-word; }
  #record-list th.sel-col, #record-list td.sel-col { width: 34px; }
  #record-list th.rr-col, #record-list td.rr-col { width: 150px; }
  #record-list th.actions-col, #record-list td.actions-col { width: 116px; }
}


/* 识别结果行：可点击跳转指标趋势（链接规则，与检验记录行同源）；输入框/按钮不触发跳转 */
.scan-row { cursor: pointer; }
.scan-row:hover { background: #f3f9fb; }
.scan-row input, .scan-row select, .scan-row label { cursor: auto; }

/* 🆕 v191：缺失项空行（OCR 漏识别，模板应有）—— 供用户补录的卡片
   🆕 v379（用户第 2/3 条「两张卡合并，应该都是按照 OCR 漏检行卡片的样式来做」）：
     底色从**淡红**改为与「待填行」`tr.scan-empty` 完全相同的**淡黄**。
     ── 为什么要统一：这两类卡本质是同一件事 —— 都是「OCR 没读出来，请你手填」，
        却一个红底一个黄底，用户看到的是两种不同的东西（他要求合并成一种卡片样式）。
     ── 为什么统一成黄而不是红：
        ① 黄在本项目里已经是「待补 / 待填」的语义色（v195 起的待填行）；
        ② 淡红已被 `.rec-abn`（#fdecea，检验值异常行）占用 —— 漏检行用红底会让用户
           以为「这行有问题/值异常」，而漏检与值是否异常**毫无关系**，纯属颜色语义撞车。
     ── `.scan-missing-hint`（表格上方那条提示横幅）保持原样：它是横幅不是卡片，配色本就独立。 */
/* 🆕 v379 订正：**两类手填卡共用同一底色/边框**（用户第 2/3 条「两张卡合并，都按 OCR 漏检行的
   样式来做」）。原写法 `.scan-missing { background:#fffbe8 }` 只有 (0,1,0)，实测 CSSOM 取证发现
   它**在手机端和夜间都不生效** —— 又一条"grep 得到、浏览器里不生效"的僵尸规则（v337 同款顽疾）：
     · 手机端：css/scan.css `@media (max-width:640px)` 里的 `.scan-table tr` (0,1,1) 压过它。
       漏检行只是"侥幸"被容器规则 `.entry-result .scan-missing-body tr` (0,2,1) 救了；
     · 夜间：`html[data-theme="dark"] .scan-missing` (0,2,0) 又被同一条容器规则 (0,2,1) 压过
       ⇒ **夜间漏检行仍是浅黄底**（浅底 + 夜间浅色字 ⇒ 可读性直接坏掉）。
   修法：一条 **(0,4,1)** 的并列选择器（4 个类 + 1 个元素）同时压过以上全部竞争者，
   并且**桌面/手机 × 日/夜四象限通吃**。
   ⚠️ hover 必须比它更高一级 **(0,5,1)** —— 否则会被这条常态规则压掉、hover 效果整个消失。
   ⚠️ 特异性数字是**实测**出来的（`node --require ./_e2e_consent_preload.js _probe_css_winner.js`），
      不是手算的 —— 我第一版手算写成 (0,3,2)/(0,4,2)，工具当场报出真值 (0,4,1)/(0,5,1)。
      「谁在生效」这类问题一律用那个工具查，别靠数点数。 */
.entry-result .scan-table tr.scan-row.scan-missing,
.entry-result .scan-table tr.scan-row.scan-empty { background: #fffbe8; border-color: #f0c36e; }
.entry-result .scan-table tr.scan-row.scan-missing:hover,
.entry-result .scan-table tr.scan-row.scan-empty:hover { background: #fff3c4; }
.scan-missing-hint { margin: 8px 0 6px; padding: 8px 12px; background: #fdf3dc; border: 1px solid #f0e0b0; border-radius: 6px; color: #5d4a18; font-size: 13px; }
.scan-missing-hint b { color: #b14b3b; }
.scan-miss-val { width: 110px; padding: 3px 6px; border: 1px solid #d5b9b9; border-radius: 4px; background: #fff; }
.scan-miss-unit { width: 60px; padding: 3px 6px; border: 1px solid var(--line); border-radius: 4px; }
.scan-miss-low, .scan-miss-high { width: 70px; padding: 3px 6px; border: 1px solid var(--line); border-radius: 4px; }
html[data-theme="dark"] .entry-result .scan-table tr.scan-row.scan-missing,
html[data-theme="dark"] .entry-result .scan-table tr.scan-row.scan-empty { background: #2a2518; border-color: #574317; }
html[data-theme="dark"] .scan-missing-hint { background: #2a2419; border-color: #574317; color: #d6c0a0; }

/* 🆕 v195：OCR 识别失败行（(未识别)）→ 待填行，淡黄底 + 输入框
   🆕 v379：底色/边框/hover **已上移**到 `.scan-missing` 那一组并列选择器统一承担 ——
     原来的 `.scan-empty { background:#fffbe8 }` 是 (0,1,0)，被 css/scan.css 手机端
     `@media (max-width:640px) .scan-table tr` (0,1,1) 压死 ⇒ **桌面端淡黄、手机端纯白**，
     从未在手机端生效过（实测确认，已删；别再把它加回来）。 */
.scan-empty-name { padding: 4px 6px; border: 1px solid #e0c860; border-radius: 4px; background: #fff; }
html[data-theme="dark"] .scan-empty-name { background: #243140; color: #d6dde6; border-color: #574317; }

/* 🆕 v379：两类手填卡的「名称 + 英文名」在**桌面端**也要纵向两格（各占一行）。
   ⚠️ 这里修的是一个 **v357 就留下的桌面端缺陷**，不是本轮新引入的：
      v357 给待填行加了英文名框（`.scan-empty-en`）后，只在 ≤640px 的媒体查询里写了
      「纵向两格」（见 css/scan.css 那一大段），桌面端没有对应规则 ⇒ 两个框都是
      `width:100%` 的 inline 元素 ⇒ **并排挤压**：名称框撑满整格、英文名框被挤到格子外，
      只露出半个字（本轮给漏检行补英文名框时，在桌面截图里实测看到了这个形态）。
      两类卡既然要合并，就一起修，别只修我这次碰的那一类。
   ⚠️ 只加 `display:block` 让它换行 —— 宽度已经由 `width:100%`（模板内联 or ≤640px 那条）给出。 */
.entry-result .scan-table tr.scan-row.scan-empty > td:nth-child(2) > input,
.entry-result .scan-table tr.scan-row.scan-missing > td:nth-child(2) > input { display: block; width: 100%; }

/* 🆕 v195：手动补录按钮行
   ⚠️ v355 起 `.scan-add-row` 已**从 DOM 中彻底移除**：用户要求把「＋ 补录缺失指标」移到
      「指标识别结果」标题栏（问号左边、只留一个加号，点开才下拉），说明文字也收进问号弹窗。
      本规则保留仅为回溯（新代码不要再用 .scan-add-row）；js/app.js 里已无任何产出它的模板。 */
.scan-add-row { margin: 8px 0 4px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* 检验记录表异常行整行高亮（偏高/偏低）：让长列表中的超标项「一眼可见」，
   与状态徽标互补（徽标给标签、整行给扫描度），对标 MyChart「flags indicating values outside the norm」 */
/* 🆕 v337：原来第二条选择器写成裸的 `.rec-abn > td`（不限定容器），于是「图片识别结果表」的行
   （app.js 也给它加了 rec-abn 类）被连带逐格涂粉。因为该表在手机端是 flex 卡片、td 为带 gap 的
   inline-block，视觉上就变成「一排分离色块」——用户反复报障十几次的那个现象。
   此处把「背景」类规则统一收进 #record-list 作用域，杜绝外溢；（左红条 box-shadow 见下一行，保持不变） */
#record-list tr.rec-abn td, #record-list .rec-abn > td { background: #fdecea; }
#record-list tr.rec-abn td:first-child, .rec-abn > td:first-child { box-shadow: inset 3px 0 0 #c0392b; }
html[data-theme="dark"] #record-list tr.rec-abn td, html[data-theme="dark"] #record-list .rec-abn > td { background: #2a1c1c; }
html[data-theme="dark"] #record-list tr.rec-abn td:first-child, html[data-theme="dark"] .rec-abn > td:first-child { box-shadow: inset 3px 0 0 #e5736f; }
/* 🆕 v258：检验记录表「数值」单元格按参考范围着色（对标 MyChart/Quest 把超标值标红惯例）。
   偏高=红 / 偏低=蓝（与指标趋势异常点配色一致）/ 正常=沿用默认文字 / 无参考范围=灰；纯展示。 */
.rec-val-high { color: #c0392b; font-weight: 600; }
.rec-val-low { color: #2471a3; font-weight: 600; }
.rec-val-ok { color: inherit; }
.rec-val-na { color: #7a8794; }
html[data-theme="dark"] .rec-val-high { color: #ff7a6b; }
html[data-theme="dark"] .rec-val-low { color: #6db3f2; }
html[data-theme="dark"] .rec-val-na { color: #9aa6b2; }

/* 🆕 v374：检验记录表「个人目标达标」标记（与参考范围状态互补，仅在有个人目标时显示） */
.rec-target { font-size: 11px; font-weight: 600; margin-left: 6px; white-space: nowrap; padding: 1px 5px; border-radius: 8px; vertical-align: middle; }
.rec-target-ok { color: #1e8449; background: #e8f6ee; }
.rec-target-miss { color: #b9770e; background: #fdf3e2; }
html[data-theme="dark"] .rec-target-ok { color: #6fe0a0; background: #16331f; }
html[data-theme="dark"] .rec-target-miss { color: #e0b15a; background: #332a14; }
/* 🆕 v376：检验记录表「连续异常」徽标 —— 同一指标连续 ≥2 次异常时，在状态徽标后提示「连续N次」，
   琥珀色与状态徽标（红/蓝/绿）区分，强调「长期不在参考范围内」。浅+暗主题兼容。 */
.rec-streak { font-size: 11px; font-weight: 600; margin-left: 6px; white-space: nowrap; padding: 1px 6px; border-radius: 8px; vertical-align: middle; color: #b9770e; background: #fdf3e2; border: 1px solid #f0d9a8; }
html[data-theme="dark"] .rec-streak { color: #e9b85a; background: #332a14; border-color: #5a4a1f; }
/* 🆕 v363 检验记录「严重度」列（暗色主题覆盖） */
html[data-theme="dark"] .sev-na { color: #8593a3; }
html[data-theme="dark"] .sev-ok { color: #52d98a; }
html[data-theme="dark"] .sev-high { color: #ff7b6b; }
html[data-theme="dark"] .sev-low { color: #5aa9e6; }
/* 🆕 v360：检验记录日期相对时间后缀（今天/昨天/N天前…），浅+暗主题兼容 */
.rec-ago { color: var(--muted); font-size: 11px; margin-left: 4px; white-space: nowrap; }
html[data-theme="dark"] .rec-ago { color: #8b98a5; }
/* 🆕 v363 检验记录「严重度」列（超出参考范围幅度百分比）：浅+暗主题兼容 */
.sev { font-size: 11px; font-weight: 600; white-space: nowrap; }
.sev-na { color: #9aa6b2; font-weight: 400; }
.sev-ok { color: #2e9e6b; }
.sev-high { color: #e4572e; }
.sev-low { color: #2f7fd1; }

/* 检验记录状态筛选（对标竞品「异常指标一键筛选 / 一眼可见」） */
.rec-filter { display: flex; align-items: center; gap: 8px; margin: 12px 0 0; flex-wrap: wrap; }
.rec-filter label { font-size: 13px; color: var(--muted); }
.rec-filter select { padding: 8px 10px; border: 1px solid var(--line); border-radius: 8px; font-size: 14px; color: var(--ink); min-width: 180px; }
/* 🆕 检验记录表筛选摘要条：在表格上方显示结果计数 + 已生效筛选 chip + 一键清除（纯只读、不写数据） */
.rec-summary { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 10px 0 6px; font-size: 13px; color: var(--muted); }
.rec-summary[hidden] { display: none; }
.rec-summary .rec-count { font-weight: 600; color: var(--ink); }
.rec-summary .rec-chip { display: inline-flex; align-items: center; gap: 4px; padding: 2px 9px; border: 1px solid var(--line); border-radius: 999px; background: rgba(46,204,113,0.10); color: var(--ink); font-size: 12px; }
.rec-summary .rec-clear-btn { margin-left: auto; padding: 4px 11px; border: 1px solid var(--line); border-radius: 8px; background: transparent; color: var(--muted); cursor: pointer; font-size: 12px; }
.rec-summary .rec-clear-btn:hover { color: #c0392b; border-color: #c0392b; }
html[data-theme="dark"] .rec-summary .rec-chip { background: rgba(46,204,113,0.14); }
html[data-theme="dark"] .rec-summary .rec-clear-btn:hover { color: #e5736f; border-color: #e5736f; }
/* 🆕 v386：检验记录「异常概览」计数条——对标 MyChart / CareClinic / 检验单解读 App 2026「一眼看出哪些结果不正常」。
   配色与全库异常语义一致：异常=红、正常=绿、无参考=灰。纯展示，不写数据。 */
.rec-summary .rec-ov { display: inline-flex; align-items: center; gap: 6px; padding: 2px 10px; border: 1px solid var(--line); border-radius: 999px; background: rgba(0,0,0,0.03); }
.rec-summary .rec-ov-item { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; color: var(--muted); }
.rec-summary .rec-ov-item b { font-size: 13px; font-weight: 700; }
.rec-summary .rec-ov-abn { color: #c0392b; }
.rec-summary .rec-ov-abn b { color: #c0392b; }
/* 🆕 v513：「改善」从原 .rec-ov-abn 里拆出来单列一档（仍是超范围，但方向已好转）⇒ 用琥珀色区分于
   恶化（红）。三档颜色语义：恶化红 → 改善琥珀 → 恢复正常青绿 → 原有正常绿。 */
.rec-summary .rec-ov-better,
.rec-summary .rec-ov-better b { color: #b06a00; }
.rec-summary .rec-ov-ok { color: #2e8b57; }
.rec-summary .rec-ov-ok b { color: #2e8b57; }
.rec-summary .rec-ov-na { color: var(--muted); }
.rec-summary .rec-ov-na b { color: var(--muted); }
/* 🆕 v513（用户第 1/5 项）：趋势概览计数条新增「恢复正常」档（历史曾超范围、最新一次已回到范围内）——
   用主题青绿与「原有正常」的绿色（#2e8b57）区分开，深浅两色各一份。 */
.rec-summary .rec-ov-back,
.rec-summary .rec-ov-back b { color: #0e7c86; }
.rec-summary .rec-ov-sub { font-size: 12px; font-weight: 700; color: #c0392b; background: rgba(192,57,43,0.10); padding: 1px 7px; border-radius: 999px; }
html[data-theme="dark"] .rec-summary .rec-ov { background: rgba(255,255,255,0.05); }
html[data-theme="dark"] .rec-summary .rec-ov-abn, html[data-theme="dark"] .rec-summary .rec-ov-abn b { color: #e5736f; }
html[data-theme="dark"] .rec-summary .rec-ov-better, html[data-theme="dark"] .rec-summary .rec-ov-better b { color: #e0a44a; }
html[data-theme="dark"] .rec-summary .rec-ov-ok, html[data-theme="dark"] .rec-summary .rec-ov-ok b { color: #4ec98b; }
html[data-theme="dark"] .rec-summary .rec-ov-back, html[data-theme="dark"] .rec-summary .rec-ov-back b { color: #1aa7b1; }
html[data-theme="dark"] .rec-summary .rec-ov-sub { color: #e5736f; background: rgba(229,115,111,0.14); }

/* ── 🆕 v513（用户第 6 项）：「恶化 / 改善 / 恢复正常」三档改成**可点按钮**（共用筛选态）──
   用户口径：「共N项、"数值a"恶化、"数值b"改善、"数值c恢复正常、"数值d其他 共5个；
             其中恶化+改善+恢复正常 3 个做按钮图标，做指标库和趋势图的筛选，其他两个文本显示。」
   点击 = 把该档作为筛选态（再点同钮 = 取消），趋势概览计数条 / 指标库计数条 / 搜索弹窗三处共用。
   外观：默认与 .rec-ov-item 同族（纯文字），选中态浅底 + 主题色描边 + 数字变色，与 .seg-btn 同一套语言。 */
.rec-summary .rec-ov-btn {
  appearance: none; margin: -2px -3px; padding: 1px 7px;
  border: 1px solid transparent; border-radius: 999px; background: transparent;
  font: inherit; cursor: pointer;
  transition: background .15s ease, border-color .15s ease, box-shadow .15s ease;
}
.rec-summary .rec-ov-btn:hover { background: rgba(14, 124, 134, .09); border-color: var(--line); }
.rec-summary .rec-ov-btn[aria-pressed="true"] {
  background: rgba(14, 124, 134, .14); border-color: var(--primary);
  box-shadow: inset 0 0 0 1px var(--primary);
}
.rec-summary .rec-ov-btn[aria-pressed="true"] b { color: var(--primary); }
.rec-summary .rec-ov-btn:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
html[data-theme="dark"] .rec-summary .rec-ov-btn:hover { background: rgba(26, 167, 177, .16); }
html[data-theme="dark"] .rec-summary .rec-ov-btn[aria-pressed="true"] { background: rgba(26, 167, 177, .22); }
html[data-theme="dark"] .rec-summary .rec-ov-btn[aria-pressed="true"] b { color: #1aa7b1; }
/* 检验记录表「日期范围」筛选（对标 MyChart 查看近期/历史结果）：与指标趋势日期范围控件一致 */
#rec-date-start, #rec-date-end { padding: 7px 10px; border: 1px solid var(--line); border-radius: 8px; font-size: 13px; color: var(--ink); background: #fff; }
.rec-date-presets { display: inline-flex; gap: 6px; }
/* 🆕 v221：日期区间分组容器。桌面用 display:contents 透明化（不改变原有 flex 排列），
   手机端由 media query 切成一个独立的一行分组。 */
.rec-date-range { display: contents; }

/* 检验记录状态徽标（正常/偏高/偏低 一眼可见） */
.badge { display: inline-block; padding: 2px 9px; border-radius: 12px; font-size: 12px; font-weight: 600; line-height: 1.6; white-space: nowrap; }
.badge-ok { background: #eef7ee; color: #2e7d32; }
.badge-high, .badge-low { background: #fdecea; color: #c0392b; }
.badge-na { background: #f1f4f8; color: #8593a3; }
/* 用药记录表「状态」徽标（用药中 / 已停，一眼可见，对标 Medisafe/MyTherapy 用药进行中态） */
.badge-active { background: #e6f4ea; color: #1e7d3a; }
.badge-stopped { background: #f1f4f8; color: #8593a3; }
.med-days { color: var(--muted); font-size: 12px; }
/* 🆕 v219：用药记录表补给预警（与「今日用药清单」tm-refill 同源）——把 Medisafe 2026 的
   Rx refill / Low-stock alerts 带到管理清单：某条在服用药剩余天数 ≤ 14 时，直接在该行标出
   🔔 仅剩 N 天补给，扫一眼全表即发现临期药，无需切到今日视图。纯展示，不写任何用药数据。 */
.med-refill { display: inline-block; margin-left: 6px; font-size: 11px; font-weight: 600; color: #8a4b00; background: #fff3cd; border: 1px solid #ffe08a; border-radius: 6px; padding: 1px 6px; white-space: nowrap; }
html[data-theme="dark"] .med-refill { color: #ffcf80; background: #3a2e12; border-color: #5a4413; }
/* 🆕 v292：用药记录表「库存余量」低库存预警（与 med-refill 同源派生，纯展示） */
.med-stock { display: inline-block; margin-left: 6px; font-size: 11px; font-weight: 600; color: #8a4b00; background: #fff3cd; border: 1px solid #ffe08a; border-radius: 6px; padding: 1px 6px; white-space: nowrap; }
.med-stock.urgent { color: #8a1f1f; background: #fde8e8; border-color: #f5b5b5; }
html[data-theme="dark"] .med-stock { color: #ffcf80; background: #3a2e12; border-color: #5a4413; }
html[data-theme="dark"] .med-stock.urgent { color: #ff9b9b; background: #3a1717; border-color: #5a2222; }
/* 🆕 v229：用药「疑似重复用药（同名且时段重叠）」常驻警示 —— 与 med-refill 同源派生，纯展示。
   红系配色区分于补给预警的琥珀色，便于一眼区分「快用完了」vs「可能吃重了」。 */
.med-dup { display: inline-block; margin-left: 6px; font-size: 11px; font-weight: 600; color: #8a1f1f; background: #fde8e8; border: 1px solid #f5b5b5; border-radius: 6px; padding: 1px 6px; white-space: nowrap; }
html[data-theme="dark"] .med-dup { color: #ff9b9b; background: #3a1717; border-color: #5a2222; }
.med-dup-banner { margin: 0 0 8px; padding: 7px 10px; font-size: 12px; font-weight: 600; color: #8a1f1f; background: #fde8e8; border: 1px solid #f5b5b5; border-left: 3px solid #d9534f; border-radius: 6px; }
html[data-theme="dark"] .med-dup-banner { color: #ff9b9b; background: #3a1717; border-color: #5a2222; }
.med-meal { display: inline-block; margin-left: 6px; font-size: 11px; font-weight: 600; border-radius: 6px; padding: 1px 6px; white-space: nowrap; }
.med-meal.meal-before { color: #0b6b3a; background: #e3f6ea; border: 1px solid #abe3c4; }
.med-meal.meal-after { color: #8a4b00; background: #fff3cd; border: 1px solid #ffe08a; }
html[data-theme="dark"] .med-meal.meal-before { color: #7ee0a8; background: #143226; border-color: #1f4d39; }
html[data-theme="dark"] .med-meal.meal-after { color: #ffcf80; background: #3a2e12; border-color: #5a4413; }
/* 🆕 v364：给药途径徽标（route badge）——口服💊 / 注射💉 / 外用🧴 / 吸入🫁 / 含服👅 / 其他，
   与 med-meal chip 同构的 glanceable 色块，让「这药怎么吃」一眼可见（对标 MyTherapy/Medisafe 给药途径可视化）。 */
.med-route { display: inline-block; margin-left: 6px; font-size: 11px; font-weight: 600; color: #5a4b8a; background: #efeaff; border: 1px solid #d4c4f5; border-radius: 6px; padding: 1px 6px; white-space: nowrap; }
.med-route[title*="注射"] { color: #8a1f1f; background: #fde8e8; border-color: #f5b5b5; }
.med-route[title*="外用"] { color: #0b6b3a; background: #e3f6ea; border-color: #abe3c4; }
.med-route[title*="吸入"] { color: #0b5b8a; background: #e3f1f8; border-color: #abd4ea; }
.med-route[title*="含服"] { color: #8a4b00; background: #fff3cd; border-color: #ffe08a; }
html[data-theme="dark"] .med-route { color: #c9b8ff; background: #241d3a; border-color: #3a2f5a; }
html[data-theme="dark"] .med-route[title*="注射"] { color: #ff9b9b; background: #3a1717; border-color: #5a2222; }
html[data-theme="dark"] .med-route[title*="外用"] { color: #7ee0a8; background: #143226; border-color: #1f4d39; }
html[data-theme="dark"] .med-route[title*="吸入"] { color: #8fd0f0; background: #14242e; border-color: #1f3d4d; }
html[data-theme="dark"] .med-route[title*="含服"] { color: #ffcf80; background: #3a2e12; border-color: #5a4413; }
.med-expiry { display: inline-block; margin-left: 6px; font-size: 11px; font-weight: 600; color: #8a4b00; background: #fff3cd; border: 1px solid #ffe08a; border-radius: 6px; padding: 1px 6px; white-space: nowrap; }
.med-expiry.soon { color: #8a4b00; background: #fff3cd; border-color: #ffe08a; }
.med-expiry.expired { color: #8a1f1f; background: #fde8e8; border-color: #f5b5b5; }
html[data-theme="dark"] .med-expiry { color: #ffcf80; background: #3a2e12; border-color: #5a4413; }
html[data-theme="dark"] .med-expiry.expired { color: #ff9b9b; background: #3a1717; border-color: #5a2222; }
/* 🆕 v297：逐药「潜在相互作用」徽标——高危红 / 中危黄，对标 Medisafe 2026 作用在药本身的相互作用提示 */
.med-intx-badge { display: inline-block; margin-left: 6px; font-size: 11px; font-weight: 600; color: #8a5a00; background: #fff3cd; border: 1px solid #ffe08a; border-radius: 6px; padding: 1px 6px; white-space: nowrap; }
.med-intx-badge.high { color: #8a1f1f; background: #fde8e8; border-color: #f5b5b5; }
html[data-theme="dark"] .med-intx-badge { color: #ffcf80; background: #3a2e12; border-color: #5a4413; }
html[data-theme="dark"] .med-intx-badge.high { color: #ff9b9b; background: #3a1717; border-color: #5a2222; }
/* 🆕 v310：用药效果自评星标（用药记录表「效果自评」列）——纯展示 + 点击评分；颜色随等级区分 */
.med-ef-cell { white-space: nowrap; }
.med-ef { display: inline-flex; align-items: center; gap: 2px; font-size: 12px; cursor: default; }
.med-ef-star { cursor: pointer; font-size: 14px; line-height: 1; color: #c8ccd2; transition: color .12s, transform .12s; user-select: none; }
.med-ef-star:hover { transform: scale(1.18); }
.med-ef-star.on { color: #f0a020; }
.med-ef-label { margin-left: 4px; font-size: 11px; font-weight: 600; color: #8a94a6; }
.med-ef.ef-excellent .med-ef-label { color: #1e9e5a; }
.med-ef.ef-good .med-ef-label { color: #2fa56a; }
.med-ef.ef-mid .med-ef-label { color: #2f7fd0; }
.med-ef.ef-weak .med-ef-label { color: #c8841a; }
.med-ef.ef-poor .med-ef-label { color: #d23b3b; }
.med-ef.ef-none .med-ef-star { color: #d4d8de; }
/* 今日用药卡片只读徽标 */
.today-med .tm-ef { display: inline-block; margin-top: 4px; font-size: 11px; font-weight: 600; border-radius: 6px; padding: 1px 6px; white-space: nowrap; }
.today-med .tm-ef.ef-excellent { color: #1e9e5a; background: #e6f7ee; border: 1px solid #b6e6cd; }
.today-med .tm-ef.ef-good { color: #2fa56a; background: #e9f6ee; border: 1px solid #bce6cd; }
.today-med .tm-ef.ef-mid { color: #2f7fd0; background: #e8f1fb; border: 1px solid #bcdaef; }
.today-med .tm-ef.ef-weak { color: #c8841a; background: #fdf3e3; border: 1px solid #f3d9a8; }
.today-med .tm-ef.ef-poor { color: #d23b3b; background: #fdecec; border: 1px solid #f5bcbc; }
html[data-theme="dark"] .med-ef-star { color: #5a6470; }
html[data-theme="dark"] .med-ef-star.on { color: #f0a020; }
html[data-theme="dark"] .med-ef-label { color: #8a94a6; }
/* 🆕 注射部位轮换（对标 DoneDose 2026「injection site rotation」）：用药记录表「注射轮换」列 */
.inj-cell { position: relative; vertical-align: top; min-width: 116px; }
.inj-cur { font-size: 11px; color: #4a5568; margin-bottom: 3px; line-height: 1.3; }
.inj-rec { font-size: 11px; padding: 2px 7px; }
.inj-next { margin-top: 3px; font-size: 11px; font-weight: 600; color: #2f7fd0; background: #eaf2fc; border: 1px solid #cfe0f7; border-radius: 6px; padding: 1px 6px; }
.inj-picker { position: absolute; z-index: 30; top: 100%; left: 0; margin-top: 2px; display: flex; flex-wrap: wrap; gap: 4px; padding: 6px; background: #fff; border: 1px solid #cdd5e0; border-radius: 8px; box-shadow: 0 6px 18px rgba(20,30,50,.18); max-width: 200px; }
.inj-site { font-size: 11px; padding: 3px 8px; }
html[data-theme="dark"] .inj-cur { color: #aab3c2; }
html[data-theme="dark"] .inj-next { color: #79b6ef; background: #16304a; border-color: #1f4d72; }
html[data-theme="dark"] .inj-picker { background: #1c2230; border-color: #38415a; box-shadow: 0 6px 18px rgba(0,0,0,.45); }
html[data-theme="dark"] .today-med .tm-ef.ef-excellent { color: #6fe0a0; background: #14342a; border-color: #1f5a46; }
html[data-theme="dark"] .today-med .tm-ef.ef-good { color: #6fdc9a; background: #16362c; border-color: #1f5a46; }
html[data-theme="dark"] .today-med .tm-ef.ef-mid { color: #79b6ef; background: #16304a; border-color: #1f4d72; }
html[data-theme="dark"] .today-med .tm-ef.ef-weak { color: #e6b257; background: #3a2e12; border-color: #5a4413; }
html[data-theme="dark"] .today-med .tm-ef.ef-poor { color: #ff9b9b; background: #3a1717; border-color: #5a2222; }
/* 🆕 v248：跨药物「潜在相互作用」常驻预警 —— 与 med-dup-banner 同层，纯展示派生，不写任何用药数据。
   高危(high)用红系、中危(moderate)用琥珀系，与竞品「相互作用预警」语义一致；暗色主题覆盖在下方。 */
.med-interaction-banner { margin: 0 0 8px; padding: 8px 12px; font-size: 12px; color: #7a4d00; background: #fff4e5; border: 1px solid #f0a500; border-left: 4px solid #e0a106; border-radius: 6px; }
.med-interaction-banner.sev-high { color: #8a1f1a; background: #fdecea; border-color: #d9534f; border-left-color: #d9534f; }
.med-interaction-banner ul { margin: 6px 0 0; padding-left: 18px; }
.med-interaction-banner li { margin: 2px 0; }
.med-interaction-banner b { font-weight: 700; }
html[data-theme="dark"] .med-interaction-banner { color: #ffd98a; background: #3a2e12; border-color: #b9860a; }
html[data-theme="dark"] .med-interaction-banner.sev-high { color: #ff9b8e; background: #3a1c1a; border-color: #c0392b; }
/* 今日用药清单（对标竞品 Today / 每日任务 / 药丸柜）：把进行中的用药收敛为每日待关注卡片 */
.today-meds .tm-count { font-weight: 600; color: var(--ink); margin-bottom: 8px; }
/* 🆕 v349：今日用药环形进度（纯展示） */
.today-meds .tm-ring { display: flex; align-items: center; gap: 12px; margin: 2px 0 10px; padding: 8px 10px; border: 1px solid var(--border); border-radius: 12px; background: var(--card-soft); }
.today-meds .tm-ring svg { width: 54px; height: 54px; flex: 0 0 54px; }
.today-meds .tm-ring-bg { stroke: #e3e8ef; }
.today-meds .tm-ring-fg { transition: stroke-dashoffset .4s ease; }
.today-meds .tm-ring-meta { display: flex; flex-direction: column; gap: 1px; line-height: 1.3; }
.today-meds .tm-ring-num { font-size: 19px; font-weight: 800; color: #1f2d3d; }
.today-meds .tm-ring-cap { font-size: 12px; color: #6b7785; }
.today-meds .tm-ring-cap b { color: #1f2d3d; }
html[data-theme="dark"] .today-meds .tm-ring-bg { stroke: #2a3340; }
html[data-theme="dark"] .today-meds .tm-ring-num { color: #e6edf3; }
html[data-theme="dark"] .today-meds .tm-ring-cap { color: #9aa7b4; }
html[data-theme="dark"] .today-meds .tm-ring-cap b { color: #e6edf3; }
.today-meds .tm-takeall-btn { margin-left: 8px; height: 24px; border-radius: 12px; border: 1px solid #2e9e5b; background: #eafaf0; color: #1f7a45; font-size: 12px; font-weight: 700; line-height: 1; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; padding: 0 11px; transition: all .15s; vertical-align: middle; }
.today-meds .tm-takeall-btn:hover { background: #2e9e5b; color: #fff; }
.today-meds .tm-streak { color: #c8881a; font-weight: 600; }
.today-meds .tm-adh { color: #1f8a70; font-weight: 600; }
/* 🆕 距下次用药倒计时（对标 NutriNow「clear countdown timer」/ Medisafe「Next dose」） */
.today-meds .tm-nextdose { margin-bottom: 8px; color: #155a91; font-weight: 600; background: #eaf4fb; border: 1px solid #cfe6f5; border-radius: 8px; padding: 6px 10px; }
.today-meds .tm-nextdose b { color: #155a91; }
.dark .today-meds .tm-nextdose { color: #8fc7ee; background: #16334a; border-color: #1f4d6b; }
.dark .today-meds .tm-nextdose b { color: #8fc7ee; }
/* 🆕 v257：近10周用药依从趋势柱状图 */
.tm-adh-weekly { margin-top: 10px; }
.tm-adh-weekly .tm-adh-svg { width: 100%; max-width: 360px; height: auto; display: block; }
.tm-adh-weekly .tm-adh-axis { stroke: var(--line, #d8dee6); stroke-width: 1; }
.tm-adh-weekly .tm-adh-val { fill: var(--ink, #243240); font-size: 9px; font-weight: 600; }
.tm-adh-weekly .tm-adh-xl { fill: var(--muted, #6b7785); font-size: 9px; }
.tm-adh-weekly .tm-adh-wk-foot { margin-top: 6px; font-size: 12px; color: var(--muted, #6b7785); line-height: 1.5; }
.tm-adh-weekly .tm-adh-wk-foot b { font-weight: 700; }
.med-adh-daily { margin-top: 10px; }
.med-adh-daily .tm-adh-daily-svg { width: 100%; max-width: 360px; height: auto; display: block; }
.med-adh-daily .tm-adh-daily-ref { stroke: var(--muted, #9aa7b5); stroke-width: 1; stroke-dasharray: 3 3; }
.med-adh-daily .tm-adh-daily-foot { margin-top: 6px; font-size: 12px; color: var(--muted, #6b7785); line-height: 1.5; }
.med-adh-daily .tm-adh-daily-foot b { font-weight: 700; }
.today-meds .tm-list { display: flex; flex-wrap: wrap; gap: 10px; }
/* 🆕 v198：今日用药按时段分组（晨/午/晚/睡前/其他）的小标题与计数徽标 */
.today-meds .tm-group { width: 100%; }
.today-meds .tm-group-title { font-size: 12px; font-weight: 700; color: var(--muted); margin: 12px 0 5px; display: flex; align-items: center; gap: 6px; border-bottom: 1px dashed var(--line); padding-bottom: 4px; }
.today-meds .tm-group:first-of-type .tm-group-title { margin-top: 0; }
.today-meds .tm-group-n { display: inline-block; min-width: 18px; text-align: center; background: var(--line); color: var(--ink); border-radius: 9px; padding: 0 6px; font-size: 11px; font-weight: 600; }
/* 🆕 v202：当前用药时段高亮 + 各时段待服计数（对标 Round Health 用药窗口 / NutriNow 下一次该吃什么 / MyTherapy Today） */
.today-meds .tm-now-tip.pending { color: #c0392b; font-weight: 600; }
.today-meds .tm-now-tip.done { color: #2e9e5b; font-weight: 600; }
.today-meds .tm-group.now { border-left: 3px solid var(--primary); background: rgba(14, 124, 134, .045); border-radius: 8px; padding: 6px 10px 8px; margin: 10px 0; }
.today-meds .tm-group.now .tm-group-title { color: var(--primary); border-bottom-color: rgba(14, 124, 134, .35); margin-top: 0; }
.today-meds .tm-now-badge { background: var(--primary); color: #fff; border-radius: 9px; padding: 1px 7px; font-size: 10px; font-weight: 700; letter-spacing: .5px; }
.today-meds .tm-pend { margin-left: auto; background: #fdecea; color: #c0392b; border-radius: 9px; padding: 1px 7px; font-size: 10px; font-weight: 600; }
.today-meds .tm-pend.done { background: #e8f6ee; color: #2e9e5b; }
/* 🆕 今日漏服语义：已过时段的未打卡药 → 「已错过」醒目提示 */
.today-meds .tm-pend.missed { background: #fdecea; color: #c0392b; border: 1px solid #f1b0a8; }
.tm-missed-banner { margin: 8px 0 4px; padding: 8px 12px; background: #fff4f3; border: 1px solid #f1b0a8; border-left: 3px solid #c0392b; border-radius: 8px; color: #a93226; font-size: 13px; font-weight: 600; line-height: 1.5; }
.tm-missed-banner b { font-size: 15px; }
.today-meds .tm-group.past { opacity: .92; }
.today-meds .tm-group.past .tm-group-title { color: #b06a4a; }
html[data-theme="dark"] .today-meds .tm-now-tip.pending { color: #f0857c; }
html[data-theme="dark"] .today-meds .tm-now-tip.done { color: #6fd39a; }
html[data-theme="dark"] .today-meds .tm-group.now { background: rgba(20, 160, 168, .1); }
html[data-theme="dark"] .today-meds .tm-pend { background: #3a2320; color: #f0857c; }
html[data-theme="dark"] .today-meds .tm-pend.done { background: #1e3328; color: #6fd39a; }
html[data-theme="dark"] .today-meds .tm-pend.missed { background: #3a2320; color: #ff8a7a; border-color: #6e3a34; }
html[data-theme="dark"] .tm-missed-banner { background: #2a1c1c; border-color: #5a2a2a; border-left-color: #e5736f; color: #ff9b8e; }
html[data-theme="dark"] .today-meds .tm-group.past .tm-group-title { color: #d99c92; }
.today-med { display: flex; align-items: center; gap: 10px; background: var(--panel); border: 1px solid var(--line); border-radius: 10px; padding: 8px 12px; min-width: 210px; }
.today-med .dot { width: 12px; height: 12px; border-radius: 50%; flex: 0 0 auto; box-shadow: 0 0 0 3px rgba(0,0,0,.06); }
.today-med .tm-body { display: flex; flex-direction: column; line-height: 1.3; }
.today-med .tm-name { font-weight: 600; }
.today-med .tm-meta { color: var(--muted); font-size: 12px; }
.today-med .tm-start { margin-left: auto; color: var(--muted); font-size: 12px; white-space: nowrap; padding-left: 8px; }
/* 🆕 今日用药卡片「用途 / 怎么吃」：复用 MED_EDU 知识库，取药瞬间给出用药上下文；仅命中知识库时显示 */
.today-med .tm-edu { color: var(--primary); font-size: 12px; margin-top: 2px; }
.today-med .tm-stock { display: inline-block; margin-top: 4px; font-size: 11px; font-weight: 600; color: #8a4b00; background: #fff3cd; border: 1px solid #ffe08a; border-radius: 6px; padding: 1px 6px; }
.today-med .tm-stock.urgent { color: #8a1f1f; background: #fde8e8; border-color: #f5b5b5; }
/* 用药补给预警（对标 Medisafe 2026 Rx refill / Low-stock alerts）：剩余天数 ≤ 14 时提示提前续方 */
.today-med .tm-refill { display: inline-block; margin-top: 4px; font-size: 11px; font-weight: 600; color: #8a4b00; background: #fff3cd; border: 1px solid #ffe08a; border-radius: 6px; padding: 1px 6px; }
/* 补给余量进度条（对标 Medisafe 2026 Rx refill / Low-stock alerts）：把「还够吃多久」做成 glanceable 视觉。
   按 剩余天数 / 疗程总天数 填充，越接近停药日越短；≤14天红(urgent)、≤30天橙(warn)、其余绿(ok)。纯展示。 */
.today-med .tm-refillbar { margin-top: 5px; height: 6px; width: 100%; max-width: 190px; border-radius: 4px; background: var(--line); overflow: hidden; }
.today-med .tm-refillbar-fill { height: 100%; border-radius: 4px; transition: width .2s; }
.today-med .tm-rf-ok { background: #2e9e5b; }
.today-med .tm-rf-warn { background: #e0a106; }
.today-med .tm-rf-urgent { background: #d9534f; }
/* 今日用药「已服打卡」（对标 CareClinic/Medisafe/MyTherapy 用药依从性 / 今日视图）：纯本机 localStorage 记录，不影响病历数据 */
.today-med .tm-take-btn { width: 26px; height: 26px; border-radius: 50%; border: 1.5px solid #cfd8e3; background: #fff; color: #9aa7b4; font-size: 14px; line-height: 1; cursor: pointer; flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; padding: 0; transition: all .15s; }
.today-med .tm-take-btn:hover { border-color: #0e7c86; }
.today-med .tm-take-btn.on { background: #2e9e5b; border-color: #2e9e5b; color: #fff; }
/* 🆕 v317：主动跳过按钮（仅非按需药）——标记「今天这一顿有意不吃」，不再计入漏服提醒 */
.today-med .tm-skip-btn { margin-left: 6px; height: 24px; border-radius: 12px; border: 1px solid #cfd8e3; background: #fff; color: #8a93a0; font-size: 11px; font-weight: 600; line-height: 1; cursor: pointer; flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; padding: 0 9px; transition: all .15s; }
.today-med .tm-skip-btn:hover { border-color: #b9892f; color: #b9892f; }
.today-med .tm-skip-btn.on { background: #fff7e6; border-color: #e0a106; color: #b9892f; }
.today-med .tm-take-btn.skipped { border-color: #e0a106; color: #b9892f; }   /* 已跳过：服药按钮显示「⊘」态 */
.today-med.skipped { opacity: .72; border-style: dashed; }                    /* 已跳过卡片：弱化显示 */
.tm-skipped-note { margin: 6px 0 2px; padding: 6px 12px; background: #fff7e6; border: 1px solid #ffe08a; border-left: 3px solid #e0a106; border-radius: 8px; color: #8a5a00; font-size: 12px; font-weight: 600; }
.today-med .tm-prn-btn { width: auto; min-width: 46px; height: 26px; border-radius: 13px; border: 1.5px solid #0e7c86; background: #e6f6f7; color: #0e7c86; font-size: 12px; font-weight: 600; line-height: 1; cursor: pointer; flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; padding: 0 9px; transition: all .15s; }
.today-med .tm-prn-btn:hover { background: #0e7c86; color: #fff; }
.today-med .tm-prn-btn.on { background: #0e7c86; color: #fff; }
.today-med .tm-prn-line { margin-top: 4px; }
.today-med .tm-prn-cd { display: inline-block; font-size: 11px; font-weight: 600; border-radius: 6px; padding: 1px 7px; }
.today-med .tm-prn-cd.none { color: #555; background: #f0f0f0; }
.today-med .tm-prn-cd.safe { color: #1d7a3e; background: #e3f6ea; }
.today-med .tm-prn-cd.wait { color: #9a5b00; background: #fff3cd; }
.tm-pend.prn { color: #0e7c86; background: #e6f6f7; border: 1px solid #bfe6e9; border-radius: 6px; padding: 1px 6px; font-size: 11px; font-weight: 600; }
.today-med.taken { opacity: .7; }
.today-med.taken .tm-name { text-decoration: line-through; text-decoration-color: #9aa7b4; }
/* 🆕 v488：漏服项高亮（已过时段的计划内药、未服未跳过）——红色边框 + 红色药名 + 「⚠ 漏服」徽标，与顶部漏服汇总呼应 */
.today-med.missed { border-color: #f1b0a8; background: #fff8f7; }
.today-med.missed .tm-name { color: #a93226; }
.today-med .tm-missed-chip { display: inline-block; margin-top: 4px; font-size: 11px; font-weight: 700; color: #a93226; background: #fdecea; border: 1px solid #f1b0a8; border-radius: 6px; padding: 1px 6px; white-space: nowrap; }
.today-med .tm-taken-time { display: inline-block; margin-top: 2px; font-size: 11px; font-weight: 600; color: #1f7a45; background: #eafaf0; border: 1px solid #bfe9cf; border-radius: 6px; padding: 1px 6px; white-space: nowrap; }
/* 用药前后检验指标对比（疗效速览）：聚焦某条用药后，展示各指标 用药前 → 期间 →（停药后）均值变化 */
.med-effect { margin-top: 12px; }
.med-effect .me-empty { margin: 0; padding: 10px 12px; background: var(--panel); border: 1px dashed var(--line);
  border-radius: 10px; color: var(--muted); font-size: 13px; line-height: 1.7; }
.med-effect .me-head { font-weight: 600; color: var(--ink); margin: 0 0 8px; display: flex; align-items: baseline;
  gap: 10px; flex-wrap: wrap; }
.med-effect .me-span { color: var(--muted); font-size: 12px; font-weight: 400; }
.med-effect .me-list { display: flex; flex-direction: column; gap: 8px; }
.me-item { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; background: var(--panel);
  border: 1px solid var(--line); border-radius: 10px; padding: 8px 12px; }
.me-item .me-dot { width: 10px; height: 10px; border-radius: 3px; flex: 0 0 auto; }
.me-item .me-name { font-weight: 600; min-width: 110px; }
.me-item .me-unit { color: var(--muted); font-size: 12px; font-weight: 400; margin-left: 4px; }
.me-item .me-flow { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; font-size: 13px; color: var(--muted); }
.me-item .me-val b { color: var(--ink); font-size: 14px; }
.me-item .me-val i { font-style: normal; color: var(--muted); font-size: 11px; margin-left: 3px; }
.me-item .me-arrow { color: #b3bcc9; }
.me-item .delta { margin-left: auto; }
.med-effect .me-note { margin: 10px 0 0; color: var(--muted); font-size: 12px; line-height: 1.7; }
/* ══════════════════════════════════════════════════════════════════════════
   🆕 v526（需求 5）：用药前后指标对比 ——「有框 + 内滚」，只显示恶化/改善/恢复
   ── 用户原话：「用药记录表中点击药品时，下拉窗口和原有窗口一部分重叠了，调整一下。……
      下拉区域用滚动窗口，apk中高度等于宽度，网页版的高度和指标库高度一致。」
   ── 改前实测（_probe_v526_probe2 / 现场）：`#med-effect` 只有 `margin-top:12px`，
      **没有边框、没有背景、没有高度上限** ⇒ 那一串 `.me-item` 小卡片裸铺在
      「用药记录表」与「用药依从日历」之间，既看不出是「点出来的一个窗口」，
      行数一多又会把下面的窗口顶下去、与表格下沿糊在一起（用户说的「一部分重叠」）。
   ── 改后：.on 态自带窗口框（与同页其它窗口同款 border/radius/bg）；
      `.me-list` 变成**固定高度内滚**（高度由 js 的 applyMedEffectScroll() 写内联，
      apk=自身宽度、网页=indScrollPx()=指标库高），并 `overscroll-behavior:contain`
      防止滑到底后把整页一起带着滚（这也是「重叠/粘连」观感的一半来源）。
   ══════════════════════════════════════════════════════════════════════════ */
.med-effect.on {
  /* 🆕 v535（用户需求 5）：与上方 #med-list 滚动窗拉开明确分隔（12→16px），列表窗自身
     已有圆角卡片边界，这里再把对比窗的边界加重一档，消除「两个窗口长在一起」的观感。 */
  margin-top: 16px; padding: 12px 14px;
  border: 1px solid var(--line); border-radius: 12px; background: var(--bg);
  box-shadow: 0 2px 8px rgba(15, 30, 45, .05);
}
html[data-theme="dark"] .med-effect.on { background: #161e26; border-color: #2d3946; }
.med-effect .me-list {
  max-height: 45vh;               /* CSS 兜底：js 未跑到/容器不可见时也不至于无限长 */
  overflow-y: auto; overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  padding-right: 4px;
}
/* 三类走势标签（只显示这三类；「正常」的项 js 侧已过滤掉，不会出现在列表里） */
.me-item .me-verdict {
  flex: 0 0 auto; font-size: 11.5px; font-weight: 700;
  padding: 1px 8px; border-radius: 999px; white-space: nowrap;
}
.me-item .me-verdict.v-worse { color: #a02718; background: #fdecea; }
.me-item .me-verdict.v-better { color: #1b6b3a; background: #e8f6ee; }
.me-item .me-verdict.v-recovered { color: #1b5e8f; background: #e6f1fa; }
html[data-theme="dark"] .me-item .me-verdict.v-worse { color: #ff9b8e; background: #3a1f1c; }
html[data-theme="dark"] .me-item .me-verdict.v-better { color: #7fd18a; background: #17301f; }
html[data-theme="dark"] .me-item .me-verdict.v-recovered { color: #8fd0ee; background: #12303d; }
/* 🆕 v526（需求 4）：点用药行跳到「今日用药」后，该药卡片闪一下（用户要能立刻认出是哪一条） */
@keyframes mcFlashPulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(240, 169, 59, 0); }
  18%, 62% { box-shadow: 0 0 0 3px rgba(240, 169, 59, .55); }
}
.today-med.mc-flash { animation: mcFlashPulse 1.6s ease both; border-color: #f0a93b; }
html[data-theme="dark"] .today-med.mc-flash { border-color: #f0a93b; }
@media (prefers-reduced-motion: reduce) {
  .today-med.mc-flash { animation: none; border-color: #f0a93b; }
}
.me-symp { margin-top: 10px; padding: 10px 12px; background: var(--panel); border: 1px solid var(--line); border-radius: 10px; }
.me-symp-head { font-weight: 600; color: var(--ink); margin-bottom: 6px; }
.me-symp-flow { display: flex; align-items: stretch; gap: 8px; flex-wrap: wrap; }
.me-symp-col { display: flex; flex-direction: column; gap: 2px; background: var(--bg); border: 1px solid var(--line); border-radius: 8px; padding: 6px 10px; min-width: 96px; }
.me-symp-col b { color: var(--ink); font-size: 13px; }
.me-symp-col i { font-style: normal; color: var(--muted); font-size: 11px; }
.me-symp-sev { color: var(--muted); font-size: 11px; }
.me-symp-trend { margin-top: 8px; font-size: 13px; color: var(--ink); }
.me-symp-w { color: var(--muted); font-weight: 400; }
@media (max-width: 640px) {
  .me-item .me-name { min-width: 0; }
  .me-item .delta { margin-left: 0; }
}

/* 用药记录表：点击某行聚焦指标趋势对应色带时，该行高亮（与图例/色带呼应） */
#med-list tr.focus { background: #fff7e6; box-shadow: inset 3px 0 0 #f0a93b; }
#med-list tr.focus .swatch { box-shadow: 0 0 0 2px #f0a93b; }

/* 检验记录「较上次」环比变化：
   方向色（升=琥珀 / 降=蓝 / 平·无=灰）保留给迷你走势图复用；
   语义色（趋好=绿 / 趋坏=红）用于检验记录表「较上次」列——直接回答「变好还是变坏」。 */
.delta { font-size: 12px; font-weight: 600; white-space: nowrap; }
.delta-up { color: #b9770e; }
.delta-down { color: #1f618d; }
.delta-flat { color: #8593a3; font-weight: 500; }
.delta-na { color: #b3bcc9; font-weight: 500; }
.delta-good { color: #1e8449; }   /* 朝参考范围方向改善 */
.delta-bad { color: #c0392b; }    /* 偏离参考范围（趋坏） */
html[data-theme="dark"] .delta-good { color: #4cd07d; }
html[data-theme="dark"] .delta-bad { color: #ff7a6b; }

/* 指标库「近期趋势」迷你走势图（sparkline）：行内直接呈现最近最多 8 次检验的走向，
   淡绿底带为参考范围，末点按状态着色，右侧给最新值 + 较上次变化（复用 .delta 配色）。 */
.spark-col { padding-top: 4px; padding-bottom: 4px; }
.spark-cell { display: inline-flex; align-items: center; gap: 6px; }
.spark-svg { display: block; border-radius: 4px; background: rgba(120, 140, 165, 0.07); }
.spark-val { font-size: 12px; font-weight: 700; }
.spark-na { color: var(--muted); font-size: 12px; }
/* 🆕 v371：定性指标在迷你趋势列里的占位 —— 「定性」而非「暂无数据」（它确实有结果，只是没有数字） */
.spark-qual { border: 1px dashed var(--line); border-radius: 6px; padding: 1px 6px;
  color: var(--primary); cursor: help; }
html[data-theme="dark"] .spark-svg { background: rgba(255, 255, 255, 0.05); }
html[data-theme="dark"] .spark-na { color: #8896a8; }
html[data-theme="dark"] .spark-qual { color: #5fd3dd; }

/* 检验记录表头排序（点击「日期/数值/状态/较上次」切换升/降，与状态徽标/环比/筛选互补） */
th.sortable { cursor: pointer; user-select: none; white-space: nowrap; }
th.sortable:hover { color: var(--primary); }
th.sortable .sort-ind { color: var(--primary); font-size: 11px; margin-left: 2px; }

/* Chart */
.chart-toolbar { display: flex; flex-wrap: wrap; gap: 16px; align-items: center; margin-bottom: 12px; }
.chart-toolbar.chart-toolbar-bottom { margin-bottom: 0; margin-top: 10px; }
.chart-toolbar .ctrl { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.chart-toolbar label { color: var(--muted); font-size: 13px; }
.chart-toolbar-bottom { border-top: 1px solid var(--line); padding-top: 10px; }
.chart-toolbar-bottom .chart-type-ctrl { margin-left: auto; }
.chip-group { display: flex; flex-wrap: wrap; gap: 6px; }
/* 🆕 v170：指标趋势指标按「报告分类」分组（血常规/凝血分析/生化/肿标 等），空分类不显示 */
.ind-group { margin-bottom: 12px; }
.ind-group-title { display: flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600;
  color: var(--muted, #6b7a8d); margin-bottom: 6px; text-transform: none; letter-spacing: .2px; }
.ind-group-title::after { content: ''; flex: 1; height: 1px; background: var(--line, #e3e8ee); }
.ind-group-count { background: var(--line, #e3e8ee); border-radius: 8px; padding: 0 7px;
  font-size: 11px; font-weight: 600; color: var(--muted, #6b7a8d); }
html[data-theme="dark"] .ind-group-title { color: #9fb0c3; }
html[data-theme="dark"] .ind-group-count { background: #2c3a4c; color: #9fb0c3; }
/* 🆕 v171：指标趋势分页窗口（每张检验单一个页签）；默认显示最早 entry；可换行 */
.chart-tabs { display: flex; align-items: center; gap: 6px; margin: 8px 0 4px; }
.chart-tabs-pager { display: flex; align-items: center; gap: 6px; flex-wrap: nowrap; }
.chart-tabs-row { display: flex; gap: 6px; flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
.chart-tabs-row::-webkit-scrollbar { display: none; }
.chart-tabs-row.tabs-overflow {
  -webkit-mask-image: linear-gradient(to right, transparent 0, rgba(0,0,0,.15) 8px, black 14px, black calc(100% - 14px), rgba(0,0,0,.15) calc(100% - 8px), transparent 100%);
  mask-image: linear-gradient(to right, transparent 0, rgba(0,0,0,.15) 8px, black 14px, black calc(100% - 14px), rgba(0,0,0,.15) calc(100% - 8px), transparent 100%);
}
/* 🆕 v315：指标趋势设置悬浮弹窗——点 ⚙️ 浮在图表方框右上角，关闭按钮 / 阴影 / 移动端可滚动 */
.chart-box { position: relative; }

/* ══════════════════════════════════════════════════════════════════════════════
   🆕 v568（用户第 7 项）：时间缩放拉伸条的悬浮提示
     用户原话：「悬浮的时候要有个左右箭头的浮窗提示可左右拉伸」。
   ── 为什么是 DOM 而不是 ECharts 的 tooltip ──
     ECharts 的 tooltip 只挂在**坐标系**上（跟着数据点走），dataZoom 的 slider 组件
     不产生 tooltip，官方也没有「slider hover 提示」这个配置项。
   ── 定位交给 JS ──
     `bottom` 由 dzHintShow() 按 L.sliderBottom + L.sliderH + 10 现算（见 js/app.js 的 dzHint*），
     这里只管长相；全屏 / 旋屏 / 窗口缩放后 JS 会重新同步，CSS 不写死像素。
   ── 配色 ──
     深青实心胶囊 + 亮青描边 + 外发光，与趋势线上的亮点、缩放条手柄是同一套语言；
     浅底上足够醒目，又不至于像一颗 UI 按钮抢走图表的注意力。
   ══════════════════════════════════════════════════════════════════════════════ */
.dz-hint {
  position: absolute; left: 50%; bottom: 36px; z-index: 6;
  display: inline-flex; align-items: center; gap: 7px;
  padding: 5px 11px; border-radius: 999px;
  font-size: 11.5px; line-height: 1; white-space: nowrap;
  color: #eafcfd;
  background: linear-gradient(180deg, rgba(16, 133, 144, .95), rgba(9, 84, 92, .95));
  border: 1px solid rgba(127, 221, 228, .58);
  box-shadow: 0 5px 16px rgba(9, 60, 66, .30), 0 0 0 1px rgba(255, 255, 255, .06) inset;
  opacity: 0; visibility: hidden; pointer-events: none;
  transform: translate(-50%, 6px);
  transition: opacity .18s ease, transform .18s ease, visibility .18s linear;
}
.dz-hint.on { opacity: 1; visibility: visible; transform: translate(-50%, 0); }
.dz-hint .dz-arw { display: inline-flex; color: #7fdde4; }
.dz-hint .dz-arw svg { display: block; }
.dz-hint .dz-arw.dz-l { animation: dzArwL 1.6s ease-in-out infinite; }
.dz-hint .dz-arw.dz-r { animation: dzArwR 1.6s ease-in-out infinite; }
@keyframes dzArwL { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(-2.5px); } }
@keyframes dzArwR { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(2.5px); } }
html[data-theme="dark"] .dz-hint {
  color: #d8fbfd;
  background: linear-gradient(180deg, rgba(18, 60, 68, .96), rgba(10, 36, 42, .96));
  border-color: rgba(127, 221, 228, .5);
  box-shadow: 0 5px 18px rgba(0, 0, 0, .45), 0 0 12px rgba(127, 221, 228, .18);
}
@media (max-width: 640px) {
  .dz-hint { font-size: 10.8px; padding: 4px 9px; gap: 5px; }
}
@media (prefers-reduced-motion: reduce) {
  .dz-hint { transition: opacity .12s linear; transform: translate(-50%, 0); }
  .dz-hint .dz-arw.dz-l, .dz-hint .dz-arw.dz-r { animation: none; }
}

/* 🆕 v371：定性（文本）指标提示 —— 用户口径「文本指标不上趋势图，提示本指标为定性分析无定量分析」。
   背景：检验单里尿蛋白 / 尿潜血 / 粪隐血 / 颜色 / 性状这类项目**根本没有数字**，只有「阴性 / 1+ / 淡黄色」
   这类文字结果，画不出可比大小的曲线。用户勾上它们后图上是一片空白，此前没有任何解释 ——
   看起来像软件坏了或数据没导进来，所以必须显式说明。
   两种形态（由 renderChart 二选一，互斥）：
     ① .chart-qual-empty —— 勾选项**全是**定性项：图内居中覆盖层，直接给出结论；
     ② .chart-qual-note  —— 只有**部分**是定性项：图下正常文档流提示条（此时图上有真数据，覆盖层会遮挡）。 */
.chart-qual-empty {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  z-index: 3;                        /* 高于图表 canvas，低于设置弹窗(z-index:50) */
  width: min(88%, 430px); text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 16px 18px; box-sizing: border-box;
  border: 1px dashed var(--line); border-radius: 14px;
  background: var(--panel); box-shadow: var(--shadow);
  /* ⚠️ 必须让点击穿透 —— 它盖在图表中央，否则会吃掉 ⚙️ / ＋ / 底部缩放条的交互。
     注意这里是 `pointer-events` 而不是 `display:none`：要的是「看得见但点不到」。 */
  pointer-events: none;
}
.chart-qual-empty .cqe-title { font-size: 14px; color: var(--ink); }
.chart-qual-empty .cqe-sub { font-size: 12px; color: var(--muted); line-height: 1.65; }
.chart-qual-note {
  margin: 8px 0 0; padding: 8px 12px; box-sizing: border-box;
  border: 1px dashed var(--line); border-radius: 10px;
  background: var(--bg); color: var(--muted); font-size: 12px; line-height: 1.65;
}
.chart-qual-note b { color: var(--ink); }
/* ⚠️ 不给这两条写 `[hidden] { display: … }` —— UA 样式表里的
   `[hidden] { display: none !important }` 自带 !important，作者 CSS 压不过它；
   写了只会在「显示态」被同一选择器误伤（v337「整卡规则被布局规则压死」的同一类坑）。 */
.chart-settings-pop {
  position: absolute; top: 44px; right: 8px; z-index: 50;
  width: min(320px, calc(100vw - 24px));
  max-height: min(70vh, 520px); overflow: auto;
  background: var(--panel, #fff); color: var(--ink);
  border: 1px solid var(--line, #e3e8ee); border-radius: 12px;
  box-shadow: 0 8px 24px rgba(20, 40, 60, .16);
  padding: 10px 12px;
}
.chart-settings-pop .chart-settings-head {
  display: flex; align-items: center; justify-content: space-between;
  padding-bottom: 6px; margin-bottom: 6px;
  border-bottom: 1px solid var(--line, #e3e8ee);
}
.chart-settings-pop .chart-settings-body { display: flex; flex-direction: column; gap: 8px; }
.chart-settings-pop .ctrl { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.chart-settings-pop .ctrl label { color: var(--ink, #1f2d3d); font-size: 13px; }
.chart-settings-pop .chart-actions-ctrl { gap: 6px; }
.chart-settings-pop .chart-range-ctrl { flex-wrap: wrap; }
.chart-settings-pop input[type="date"] { padding: 6px 8px; border: 1px solid var(--line, #e3e8ee); border-radius: 8px; font-size: 13px; }
.chart-settings-pop select { padding: 6px 8px; border: 1px solid var(--line, #e3e8ee); border-radius: 8px; font-size: 13px; color: var(--ink); background: #fff; }
.chart-settings-pop .range-presets { display: inline-flex; gap: 4px; flex-wrap: wrap; }
.chart-gear.is-on { background: var(--primary); color: #fff; border-color: var(--primary); }
/* 🆕 v315：指标库「添加指标」悬浮弹窗——以 .card 为定位锚点浮在卡片内右上角 */
.ind-add-pop {
  position: absolute; top: 48px; right: 16px; z-index: 40;
  width: min(360px, calc(100vw - 32px));
  background: var(--panel, #fff); color: var(--ink);
  border: 1px solid var(--line, #e3e8ee); border-radius: 12px;
  box-shadow: 0 8px 24px rgba(20, 40, 60, .16);
  padding: 10px 12px;
}
.ind-add-pop .ind-add-head {
  display: flex; align-items: center; justify-content: space-between;
  padding-bottom: 6px; margin-bottom: 6px;
  border-bottom: 1px solid var(--line, #e3e8ee);
}
.ind-add-pop #form-indicator { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 0; }
.ind-add-pop #form-indicator > input[placeholder="指标名称，如 白细胞"] { grid-column: 1 / -1; }
.ind-add-pop #form-indicator > input[type="color"] { grid-column: 1 / 2; height: 38px; }
.ind-add-pop #form-indicator > button { grid-column: 2 / -1; }
.ind-add-pop .form-inline input { width: 100%; }
/* 🆕 v513（用户第 5 项）：窗内说明复用弹窗族的 `.med-edit-note`，只把外边距 / 内边距 / 字号收小 ——
   这个浮层只有 360px 宽（弹窗族是 560px），照搬会把录入区挤到屏外。
   ⚠️ 选择器带 `.ind-add-pop` 前缀 ⇒ 权重 (0,2,0) 高于 `.med-edit-note` (0,1,0)，与声明顺序无关。 */
.ind-add-pop .ind-add-note { margin: 0 0 8px; padding: 7px 10px; font-size: 11.5px; line-height: 1.55; }
#btn-ind-add.is-on { background: var(--primary); color: #fff; border-color: var(--primary); }
.chart-tab-nav { flex-shrink: 0; width: 30px; height: 30px; border: 1px solid var(--line, #e3e8ee); border-radius: 50%;
  background: #fff; color: var(--ink); font-size: 16px; line-height: 1; cursor: pointer; display: flex; align-items: center; justify-content: center; }
.chart-tab-nav:hover:not(.disabled) { border-color: var(--primary); color: var(--primary); }
.chart-tab-nav.disabled { opacity: .35; cursor: default; }
.chart-tab-page { flex-shrink: 0; font-size: 12px; color: var(--muted, #6b7a8d); min-width: 34px; text-align: center; }
html[data-theme="dark"] .chart-tab-nav { background: #243140; border-color: #2c3a4c; color: #d6dde6; }
.chart-tab { padding: 6px 12px; border: 1px solid var(--line, #e3e8ee); border-radius: 16px; background: #fff;
  font-size: 13px; cursor: pointer; user-select: none; color: var(--ink); transition: all .15s ease; white-space: nowrap; }
.chart-tab:hover { border-color: var(--primary); color: var(--primary); }
.chart-tab.active { background: var(--primary); color: #fff; border-color: var(--primary); font-weight: 600; }
.chart-tabs-empty { color: var(--muted, #6b7a8d); font-size: 13px; padding: 8px 0; }
html[data-theme="dark"] .chart-tab { background: #243140; border-color: #2c3a4c; color: #d6dde6; }
html[data-theme="dark"] .chart-tab:hover { border-color: var(--primary); }
.chip { display: inline-flex; align-items: center; gap: 5px; padding: 4px 10px; border: 1px solid var(--line);
  border-radius: 20px; cursor: pointer; font-size: 13px; user-select: none; background: #fff; }
.chip input { display: none; }
.chip.on { background: var(--primary); color: #fff; border-color: var(--primary); }
/* 指标趋势「显示指标」星标收藏（★ 置顶排序，对标竞品「一键收藏 / 一眼可见」） */
.chip .star { cursor: pointer; user-select: none; font-size: 14px; line-height: 1; color: #c4cbd4; margin-right: 3px; }
.chip .star.on { color: #f0a93b; }
.chip.fav { border-color: #f0a93b; }
/* 🆕 v348：指标趋势勾选列表的「多读数趋势方向」小标签（对标 Apple Health / Samsung Health / CareClinic 2026「trending」一眼可见）。
   与检验记录表「较上次」单点环比互补：这里看最近若干次测量的整体走向。方向仅表走势，不判临床好坏。 */
.ind-trend { display: inline-block; margin-left: 4px; font-size: 11px; line-height: 1; padding: 1px 6px; border-radius: 9px; white-space: nowrap; vertical-align: middle; border: 1px solid transparent; }
.ind-trend-up   { color: #b5611f; background: #fbeede; border-color: #ecc8a3; }
.ind-trend-down { color: #2f6f9f; background: #e6f1f8; border-color: #b3d6ea; }
.ind-trend-flat { color: #7a8a99; background: #eef1f4; border-color: #d4dae0; }
.chart-toolbar input[type="date"] { padding: 6px 8px; border: 1px solid var(--line); border-radius: 8px; font-size: 13px; }
.ind-search { padding: 6px 10px; border: 1px solid var(--line); border-radius: 8px; font-size: 13px; min-width: 200px; color: var(--ink); background: #fff; }
.ind-search:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 2px rgba(14,124,134,.15); }
.ind-search-count { color: var(--muted); font-size: 12px; }
.ind-checks-actions { display: inline-flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.ind-default-hint { color: var(--muted); font-size: 12px; }
/* 🆕 v192：指标名称 chips 块（分类页签下方）—— 搜索框/按钮/标题 + 当前分类 chips */
.ind-checks-block { margin: 8px 0 12px; padding: 8px 10px; border: 1px solid var(--line); border-radius: 8px; background: #fafbfc; }
.ind-checks-toolbar { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-bottom: 6px; }
.ind-checks-toolbar label { color: var(--muted); font-size: 13px; }
html[data-theme="dark"] .ind-checks-block { background: #1a232e; border-color: #2c3a4c; }
/* 检验记录表自由文本搜索（对标 Guava universal search / MyChart 搜索栏），与状态筛选互补 */
.rec-search { padding: 8px 10px; border: 1px solid var(--line); border-radius: 8px; font-size: 14px; min-width: 220px; color: var(--ink); background: #fff; }
.rec-search:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 2px rgba(14,124,134,.15); }
/* 用药记录表自由文本搜索（对标 MyChart 2026「medications search made easier」），与检验记录表搜索互补 */
.med-search { padding: 8px 10px; border: 1px solid var(--line); border-radius: 8px; font-size: 14px; min-width: 220px; color: var(--ink); background: #fff; }
.med-search:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 2px rgba(14,124,134,.15); }
/* 检验录入「录入即解读」实时提示：选指标 + 输入数值即显示参考范围与正常/超标判定 */
.rec-entry-hint { font-size: 12px; color: var(--muted); margin: 8px 0 0; padding: 7px 10px; border-radius: 8px; background: #f6f8fa; border: 1px solid var(--line); }
.rec-entry-hint.muted { color: var(--muted); }
.rec-entry-hint b { font-weight: 600; }
.rec-entry-hint.hi-ok { background: #eef7ee; border-color: #cfe6cf; }
.rec-entry-hint.hi-ok b { color: #2e7d32; }
.rec-entry-hint.hi-high, .rec-entry-hint.hi-low { background: #fdecea; border-color: #f3c9c4; }
.rec-entry-hint.hi-high b, .rec-entry-hint.hi-low b { color: #c0392b; }
.rec-entry-hint.hi-na { background: #f1f4f8; border-color: #e0e6ee; }
.rec-entry-hint.hi-na b { color: #8593a3; }
.chart-toolbar select { padding: 6px 8px; border: 1px solid var(--line); border-radius: 8px; font-size: 13px; color: var(--ink); background: #fff; cursor: pointer; }
.range-presets { display: inline-flex; gap: 6px; }
/* 🆕 v429（用户）：白底窗口上移到 .chart-box —— 标题/三行图例/指标图例/趋势图全部在同一张白底里。
   .chart 自身改透明（canvas backgroundColor 本就 transparent，圆角由 .chart-box 的 background
   原生裁切，不需要 overflow:hidden，不会剪掉浮层）。 */
.chart { width: 100%; height: 480px; }

/* 🆕 v499（用户第 1 项）：工具按钮改用内联 SVG 图标后，让图标跟随 .chart-gear 的 font-size 缩放
   （桌面 16px / 手机 14px），并去掉 inline 元素的基线空隙，保证圆圈内垂直居中。 */
.chart-gear > svg { display: block; }

/* 🆕 v501（用户第 3 项）：指标趋势「全屏」重构为**单卡弹窗式横屏**
   ── 用户原话 ──
     「指标趋势图上全屏的时候只有指标趋势窗口是弹窗式横屏，本页面其他窗口和其他页面不要横屏；
       而且横屏以后，有一半看不到。指标趋势图全屏后不要遮盖屏幕下方页签，原有全屏按钮变成关闭窗口的
       叉号，大小和其他按钮一致。点击叉号、横扫屏幕边缘的返回操作、点击页面下方页签的其他窗口时退出弹窗。」
   ── v499 旧做法（已退役，别再改回去）──
     把**整个 `#panel-trend`** 设成 `position:fixed; inset:0` 再整体 `rotate(90deg)`。
     实测（MuMu 1080×1920，`_mumu_shots/full1.png`）三个缺陷同时出现：
       ① 本页的「趋势概览 / 指标分析 / 指标库」被他一起卷进横屏（用户要的只是指标趋势那张卡）；
       ② 容器按视口长短边对调后，**内部内容仍按老逻辑算高**（`#chart{height:calc(100vw−120px)}`）
          ⇒ 图表只占上半部、下半部大片空白 = 用户说的「有一半看不到」；
       ③ 没有减掉底部页签的高度 ⇒ 旋转后的可读区压到页签上。
     ⚠️ 另外「时间压缩到一个点」（用户第 2 项）就是 ② 的同一个根因：canvas 宽度与新容器不匹配，
        时间轴被挤成一条窄带 —— 两项一起修的。
   ── 新做法 ──
     只把**指标趋势这张卡 `.chart-box`** 变成弹窗容器（其余窗口 `display:none` 不参与）；
     容器尺寸与位置由 JS 按「视口去掉底部页签」实测后写成 3 个 CSS 变量（见 setChartFullscreen），
     手机端再整体 rotate(90deg) 得到伪横屏 ⇒ 旋转后的占位**恰好等于可用区域**，不再有空白、不压页签。
     卡内改 flex 纵向布局、`#chart` 吃剩余高度 ⇒ 图表自动铺满，无需再猜像素高度。 */
body.chart-fullscreen { overflow: hidden; }
/* 弹窗态只留指标趋势卡：本页其他窗口既不显示、也不横屏；其他页面因面板整块隐藏本来就不受影响 */
body.chart-fullscreen #panel-trend > :not(.chart-box) { display: none !important; }
body.chart-fullscreen .chart-box {
  position: fixed; inset: 0; z-index: 1200;
  /* ⚠️ `!important` 不能省（_probe_v502_fullscreen.js 1.3 实测栽过）：
     css/styles.css 末尾有 `.panel > * + *:not(.hint-q) { margin-top: 14px !important; }`，
     `.chart-box` 正是 `#panel-trend > * + *` ⇒ 普通 `margin:0` 被它压掉，
     弹窗外接框整体下移 14px（t=14..596 而非 0..582）、底部压住页签。 */
  margin: 0 !important; border-radius: 0;
  display: flex; flex-direction: column;
  overflow: hidden;
  background: var(--bg);
  /* 四边叠加安全区，避免被刘海 / Home Indicator 遮挡 */
  padding: calc(10px + env(safe-area-inset-top, 0px)) calc(10px + env(safe-area-inset-right, 0px)) calc(10px + env(safe-area-inset-bottom, 0px)) calc(10px + env(safe-area-inset-left, 0px));
}
html[data-theme="dark"] body.chart-fullscreen .chart-box { background: #0d1117; }
/* 图表吃掉卡片剩余高度（头部标题 / 时间范围条 / 三行图例浮窗都是固定高） */
body.chart-fullscreen .chart-box #chart { flex: 1 1 auto; height: auto; min-height: 0; border-width: 0; }
/* 弹窗内不再需要那行「时间范围」（手机端本来也隐藏），给图表让位 */
body.chart-fullscreen .chart-box .chart-range-bar { display: none; }
/* 全屏按钮在弹窗态显示为 ✕（两个 SVG 常驻按钮内，只切显隐 ⇒ 不改 innerHTML、按钮尺寸不变） */
#btn-chart-full .ico-close { display: none; }
body.chart-fullscreen #btn-chart-full .ico-expand { display: none; }
body.chart-fullscreen #btn-chart-full .ico-close { display: block; }
body.chart-fullscreen #btn-chart-full { background: #0e7c86; color: #fff; border-color: #0e7c86; }

/* 🆕 v501：手机端伪横屏。容器长短边对调（宽 = 可用高、高 = 视口宽）后 rotate(90deg)；
   旋转后的屏幕占位：横 = 容器高 = 视口宽，纵 = 容器宽 = 可用高 ⇒ 正好填满「去掉页签」的区域。 */
@media (max-width: 640px) {
  body.chart-fullscreen .chart-box {
    inset: auto;
    top: var(--cm-fs-top, 50%);
    left: 50%;
    width: var(--cm-fs-w, 100vh);
    height: var(--cm-fs-h, 100vw);
    padding: 8px;
    transform: translate(-50%, -50%) rotate(90deg);
    transform-origin: center center;
  }
}

.med-legend { margin-top: 14px; }
.med-legend h3 { font-size: 14px; margin: 0 0 8px; color: var(--ink); }
.legend-items { display: flex; flex-wrap: wrap; gap: 8px; }
.legend-item { display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px; border-radius: 8px;
  border: 1px solid var(--line); cursor: pointer; font-size: 13px; background: #fff; }
.legend-item.off { opacity: 0.4; text-decoration: line-through; }
.legend-item .sw { width: 14px; height: 14px; border-radius: 4px; }
.legend-item .dates { color: var(--muted); font-size: 12px; }
/* 点击指标趋势用药色带后，用药图例对应项短暂高亮（与表格行 .flash 同一视觉语言，构成图表↔图例联动反馈） */
.legend-item.flash { box-shadow: inset 0 0 0 2px var(--primary); background: #e3f6f7; transition: background .25s ease; }
html[data-theme="dark"] .legend-item.flash { background: #15393d; box-shadow: inset 0 0 0 2px var(--primary); }



.hint { color: var(--muted); font-size: 12px; margin-top: 10px; }

/* 异常预警汇总 */
.anomaly-summary { margin: 10px 0 0; padding: 8px 12px; border-radius: 8px; font-size: 13px;
  background: #eef7ee; color: #2e7d32; border: 1px solid #d6ebd6; }
.anomaly-summary.warn { background: #fdecea; color: #c0392b; border-color: #f5c6c2; }

/* 数据新鲜度提示（最近一次检验距今天数 + 久未复查提醒） */
.data-freshness { margin: 8px 0 0; padding: 8px 12px; border-radius: 8px; font-size: 13px;
  background: #eef4fb; color: #2c5d8a; border: 1px solid #d6e4f0; }
.data-freshness.stale { background: #fff7e6; color: #b9770e; border-color: #f5e0b0; }

/* 异常趋势智能预警清单（连续超范围次数 + 恶化/好转方向） */
.anomaly-alerts { margin-top: 8px; display: flex; flex-direction: column; gap: 6px; }
.alert-head { font-size: 13px; padding: 6px 2px; }
.alert-head.warn { color: #c0392b; }
.alert-head.ok { color: #2e7d32; }
.alert-item { display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
  padding: 8px 12px; border-radius: 8px; font-size: 13px;
  border: 1px solid var(--line); background: #fff; border-left-width: 4px; }
.alert-item.sev-worse { background: #fdecea; border-color: #f5c6c2; border-left-color: #c0392b; }
.alert-item.sev-better { background: #fff8e8; border-color: #f3e2bd; border-left-color: #b9770e; }
.alert-item.sev-flat { background: #f7f9fc; border-left-color: #8593a3; }
.alert-dot { width: 10px; height: 10px; border-radius: 3px; flex: 0 0 auto; }
.alert-name { font-weight: 600; }

/* 🆕 v218：本期检验自然语言小结（可读的一句话概览，对标 2026 Ada/K Health/Babylon/MyChart 的 AI 式总结） */
.period-summary { margin-top: 8px; padding: 10px 14px; border-radius: 10px; font-size: 13.5px; line-height: 1.7;
  background: #f3f7fb; color: #243b53; border: 1px solid #dce6f0; }
.period-summary .ps-title { font-weight: 700; color: #0e7c86; margin-right: 4px; }
.period-summary .ps-worse { color: #c0392b; font-weight: 600; }
.period-summary .ps-better { color: #2e7d32; font-weight: 600; }
.period-summary .ps-flat { color: #6b7785; }
.period-summary .ps-empty { color: #6b7785; }
.alert-streak { color: var(--ink); }
.alert-dur { color: var(--muted); font-size: 12px; white-space: nowrap; }
.alert-tag { font-size: 12px; font-weight: 600; padding: 1px 8px; border-radius: 10px; white-space: nowrap; }
.alert-tag.bad { background: #f9d7d3; color: #a5251f; }
.alert-tag.good { background: #fdefd0; color: #8a5a06; }
.alert-tag.flat { background: #eceff4; color: #6b7a8d; font-weight: 500; }
.alert-meta { color: var(--muted); font-size: 12px; margin-left: auto; }
/* 异常预警下钻入口：预警条目可点击 → 单独聚焦该指标趋势（对标 MyChart 2026「点击异常即看结果」） */
.alert-item[data-ind] { cursor: pointer; }
.alert-item[data-ind]:hover { box-shadow: 0 0 0 1px rgba(14,124,134,.45); }
.alert-item[data-ind]:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
.alert-go { margin-left: 10px; color: var(--primary); font-weight: 600; font-size: 12px; white-space: nowrap; }
@media (max-width: 640px) {
  .alert-meta { margin-left: 0; flex: 1 1 100%; }
  .alert-go { margin-left: 0; }
}

/* Toast */
.toast { position: fixed; left: 50%; bottom: 30px; transform: translateX(-50%) translateY(20px);
  background: #1f2d3d; color: #fff; padding: 10px 18px; border-radius: 24px; font-size: 14px;
  opacity: 0; pointer-events: none; transition: .25s; z-index: 50; }
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
.toast.toast-warn { background: #b9770e; box-shadow: 0 4px 16px rgba(185,119,14,.4); }

.empty { color: var(--muted); font-size: 13px; padding: 10px 0; }

/* 🆕 v221：右下角浮动「回到顶部」按钮
   默认隐藏（透明 + 不吃点击），滚动超过一屏后加 .show 淡入；44×44 满足触摸目标下限。 */
.scroll-top-fab {
  position: fixed; right: 16px; bottom: 20px; z-index: 60;
  width: 44px; height: 44px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid rgba(255, 255, 255, .28); border-radius: 50%;
  background: linear-gradient(135deg, #0e7c86, #14a0a8); color: #fff;
  box-shadow: 0 4px 14px rgba(14, 124, 134, .38);
  cursor: pointer; -webkit-tap-highlight-color: transparent;
  opacity: 0; visibility: hidden; pointer-events: none;
  transform: translateY(8px) scale(.92);
  transition: opacity .18s ease, transform .18s ease, visibility .18s;
}
.scroll-top-fab.show { opacity: 1; visibility: visible; pointer-events: auto; transform: none; }
.scroll-top-fab:active { transform: scale(.92); }
html[data-theme="dark"] .scroll-top-fab {
  background: linear-gradient(135deg, #147f8a, #0e6b74); border-color: rgba(255, 255, 255, .16);
}

/* Mobile */
@media (max-width: 640px) {
  /* P1 适配：移动端媒体查询会覆盖基础规则，此处必须同样叠加安全区 */
  .app-header { padding: calc(10px + env(safe-area-inset-top, 0px)) 12px 10px; align-items: center; }
  .brand h1 { font-size: 17px; }
  .subtitle { display: none; }
  .content { padding: 8px; }
  .card { padding: 12px; border-radius: 12px; margin-bottom: 12px; }
  .card h2 { margin: 0 0 8px; font-size: 15px; }
  .card-head { margin: 0 0 8px; }
  .form-grid { grid-template-columns: 1fr; }
  .chart { height: 360px; }

  /* 页眉只保留夜间模式按钮 */
  .header-actions { gap: 6px; }
  .header-actions .btn { padding: 5px 10px; font-size: 12px; white-space: nowrap; }

  /* 🆕 v278：页签已移入 .app-header，随 header 一起吸顶（--cm-header-h 不再需要用于 tabs）。 */
  .tabs { position: static; padding: 0; background: transparent; box-shadow: none; }
  .tab { padding: 6px 9px; font-size: 13.5px; }

  .form-inline input, .form-inline select { min-width: 0; flex: 1 1 120px; }
  th, td { padding: 7px 8px; font-size: 13px; white-space: normal; word-break: break-word; vertical-align: top; }

  /* 关键长文本列明确允许换行；勾选列、区间条列保持不换行 */
  th.wrap-col, td.wrap-col { white-space: normal; word-break: break-word; }
  .sel-col, .rr-col { white-space: nowrap; }
  .actions-col { width: 1%; min-width: 56px; }
  .row-actions { flex-wrap: wrap; gap: 4px; }
  .row-actions .btn { padding: 3px 7px; font-size: 11px; }

  /* 页面级操作按钮栏 */
  .page-actions-bar { display: flex; flex-wrap: wrap; gap: 8px; }
  .page-actions-bar .btn { padding: 6px 12px; font-size: 13px; }

  /* 检验/用药筛选区更紧凑 */
  .rec-filter { gap: 6px; }
  .rec-filter select, .rec-filter input { min-width: 0; flex: 1 1 120px; }
  .rec-search, .med-search { min-width: 0; flex: 1 1 140px; }

  /* 🆕 v221：日期区间合并成一行 —— 「日期： 起始 ～ 结束」同排，快捷档位换到下一行 */
  .rec-date-range { display: flex; flex: 1 1 100%; flex-wrap: wrap; align-items: center; gap: 6px; }
  .rec-date-range label { flex: 0 0 auto; }
  .rec-date-range input[type="date"] { flex: 1 1 0; min-width: 0; font-size: 12px; }
  .rec-date-range > span { flex: 0 0 auto; color: var(--muted); }
  .rec-date-presets { flex: 1 1 100%; justify-content: flex-end; }

  /* 表格能换行后，取消横向滚动（否则看起来仍然像被截断） */
  .table-wrap { overflow-x: visible; }

  /* ⚠️ v221 修复：#med-list（用药记录表）是三者中唯一**没有卡片化**的表格
     （#indicator-list / #record-list 已改 flex 卡片），仍是 6+ 列真表格，
     手机端宽度必然超过视口 → 必须保留横向滚动。
     上面那条 .table-wrap 规则本为卡片化表格而写，却正好砸在唯一需要滚动的这张表上，
     导致用药页整页横向溢出（实测 docW 453 > innerW 390）。 */
  #med-list.table-wrap { overflow-x: auto; }

  /* 今日用药卡片更紧凑 */
  .today-med { min-width: 0; flex: 1 1 100%; }
  .today-med .tm-refillbar { max-width: none; }

  /* 指标趋势分类页签分页器换行 */
  .chart-tabs { flex-wrap: wrap; }
  .chart-tabs-pager { flex: 1 1 100%; max-width: 100%; }
  .chart-tabs-row { max-width: 100%; }

  /* 健康概览：手机端每个指标单独一行 */
  .ho-grid { flex-direction: column; gap: 8px; }
  .ho-item { flex: 1 1 100%; width: 100%; padding: 10px 12px; border-radius: 10px; background: rgba(255,255,255,0.55); }
  .ho-item .ho-main { display: flex; align-items: baseline; gap: 8px; }
  .ho-item .ho-sub { display: block; margin-top: 2px; }

  /* 🆕 v221：时间范围已下移到图表下方（.chart-toolbar-bottom 内），
     手机上「时间范围 + 起 ~ 止」压成一行，清空与快捷档位换到第二行。 */
  .chart-toolbar-bottom .chart-range-ctrl { flex: 1 1 100%; flex-wrap: wrap; gap: 6px;
    margin-top: 6px; padding-top: 8px; border-top: 1px dashed var(--line); }
  .chart-toolbar-bottom .chart-range-ctrl > label { order: 1; flex: 0 0 auto; }
  .chart-toolbar-bottom #range-start { order: 2; }
  .chart-toolbar-bottom #range-end { order: 4; }
  .chart-toolbar-bottom .chart-range-ctrl input[type="date"] { min-width: 0; flex: 1 1 0; font-size: 12px; }
  .chart-toolbar-bottom .chart-range-ctrl > span:not(.range-presets) { order: 3; flex: 0 0 auto; }
  .chart-toolbar-bottom .chart-range-ctrl #btn-range-clear { order: 5; flex: 0 0 auto; }
  .chart-toolbar-bottom .chart-range-ctrl .range-presets { order: 6; margin-left: auto; }

  /* 指标趋势选项放到图表下方后，手机端竖排 */
  .chart-toolbar-bottom { margin-top: 10px; margin-bottom: 4px; gap: 8px 12px; }
  .chart-toolbar-bottom .ctrl { flex: 1 1 100%; }
  .chart-toolbar-bottom .chart-type-ctrl { justify-content: flex-start; flex-wrap: wrap; }
  .chart-toolbar-bottom label.check { font-size: 13px; }

  /* 用药前后指标对比：防止 .me-flow 作为 flex item 被内容撑开而溢出 */
  .me-item { gap: 6px; }
  .me-item .me-name { flex: 0 0 auto; max-width: 45%; }
  .me-item .me-flow { flex: 1 1 100%; min-width: 0; }
  .me-item .delta { margin-left: 0; }

  /* 事件表单 */
  .event-form input[type="date"] { min-width: 0; }
  .event-form input[type="text"] { flex: 1 1 100%; }

  /* 指标库表格：手机端卡片化，更紧凑 */
  #indicator-list table,
  #indicator-list thead,
  #indicator-list tbody,
  #indicator-list th,
  #indicator-list td,
  #indicator-list tr { display: block; }
  #indicator-list thead { display: none; }
  /* 🆕 v221：指标库卡片按内容自适应 —— 从「6 个 td 各占一行」压缩成 2 行：
     第一行 = 指标名 ………… 释义/改/删；第二行 = 参考范围 · 单位 · 目标 ………… 迷你趋势。 */
  #indicator-list tr { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 8px;
    margin-bottom: 6px; padding: 8px 10px; border: 1px solid var(--line); border-radius: 10px; background: rgba(255,255,255,0.45); }
  /* 🆕 v344：夜间模式补底色覆盖。上面那条 rgba(255,255,255,.45) 是「往浅色上加白」的写法，
     日间在白色卡片上合成为纯白（无感），夜间却在深色卡片上合成出 rgb(128,133,141) 的灰块，
     压上 --muted(#9aa6b2) 次要文字后对比度只有 1.50 —— 远低于 WCAG AA 的 4.5，基本读不出（用户报障）。
     改为极轻微提亮（0.06）：合成后 rgb(38,47,60)，次要文字对比度回到 5.45，正文 12.4。
     ⚠️ 顺序：必须排在下面 tr.ind-row.on / tr.rec-abn 的夜间规则**之前**（那两条特异性更高，仍会赢）。 */
  html[data-theme="dark"] #indicator-list tr { background: rgba(255,255,255,0.06); }
  #indicator-list td { display: inline-block; padding: 0; border: none; font-size: 13px; white-space: nowrap; }
  /* 第一行：指标名（吃掉剩余空间） + 操作按钮组（钉右） */
  #indicator-list td.wrap-col { order: 10; flex: 1 1 auto; min-width: 0; font-weight: 600; font-size: 14px;
    white-space: normal; word-break: break-word; }
  #indicator-list td.actions-col { order: 20; width: auto; margin: 0 0 0 auto; }
  /* 换行伪元素：把次要信息压到第二行 */
  #indicator-list tr::before { content: ''; order: 30; flex: 1 1 100%; height: 0; }
  /* 🆕 v521（需求18）：第二行 = 最新值 → 单位 → 参考范围 → 目标 → 迷你趋势。
     修正 v518 加「最新值」列后 nth-child 未同步导致的错位（参考/目标标签错挂、顺序错乱）。 */
  #indicator-list td:nth-child(2) { order: 40; flex: 0 0 auto; }
  #indicator-list td:nth-child(3) { order: 50; flex: 0 0 auto; }
  #indicator-list td:nth-child(4) { order: 60; flex: 0 0 auto; color: var(--muted); font-size: 12px; }
  #indicator-list td:nth-child(4)::before { content: '参考 '; color: var(--muted); font-size: 11.5px; }
  #indicator-list td:nth-child(5) { order: 70; flex: 0 0 auto; color: var(--muted); font-size: 12px; }
  #indicator-list td:nth-child(5)::before { content: '目标 '; font-size: 11.5px; }
  #indicator-list td.spark-col { order: 80; padding: 0; margin-left: auto; }
  /* 🆕 v221：迷你趋势在手机上收窄（原 104px + 数值 + 涨跌文字 ≈154px，会把卡片撑出第三行）；
     只保留折线本身，数值/涨跌仍可通过 title 悬浮与点击该行看指标趋势获得。 */
  #indicator-list .spark-svg { width: 72px; height: 20px; }
  #indicator-list .spark-val, #indicator-list .spark-col .delta { display: none; }
  #indicator-list .row-actions { gap: 4px; }
  #indicator-list .row-actions .btn { padding: 2px 7px; font-size: 11px; min-height: 26px; }
  /* 选中态：整行统一底色，不要每个 td 独立色块，不要左侧竖条 */
  #indicator-list tr.ind-row.on td { background: transparent !important; }
  #indicator-list tr.ind-row.on { background: #bfeacd; }
  #indicator-list tr.ind-row.on td.wrap-col { box-shadow: none !important; }
  html[data-theme="dark"] #indicator-list tr.ind-row.on td { background: transparent !important; }
  html[data-theme="dark"] #indicator-list tr.ind-row.on { background: rgba(47, 191, 131, .32); }
  html[data-theme="dark"] #indicator-list tr.ind-row.on { background: rgba(47, 191, 131, .32); }
  html[data-theme="dark"] #indicator-list tr.ind-row.on td.wrap-col { box-shadow: none !important; }

  /* 检验记录表格：手机端卡片化 + 类检验单紧凑布局 */
  #record-list table,
  #record-list thead,
  #record-list tbody,
  #record-list th,
  #record-list td,
  #record-list tr { display: block; }
  #record-list thead { display: none; }
  #record-list tr { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; padding: 8px 10px; margin-bottom: 6px; border: 1px solid var(--line); border-radius: 10px; background: rgba(255,255,255,0.45); }
  /* 🆕 v344：同 #indicator-list —— 夜间把这层「加白」换成极轻微提亮，否则深底上出现灰块、字读不出。 */
  html[data-theme="dark"] #record-list tr { background: rgba(255,255,255,0.06); }
  /* 🆕 v497（性能修复）：检验记录卡片「不在滚动视口里就不排版」。
     ── 报障（用户原话）──「apk每次在检验记录页要卡很久是为什么」。
     ── 根因（实测 headless Edge + CDP Performance/LayoutDuration，非推断）──
        ① 7 个页签面板的 DOM **全部常驻文档**，隐藏只靠 display:none ⇒ 离开时该面板布局被丢弃，
           每次切回都要把整块从头排一次；
        ② `initTabs` 的 click 处理器切完 class **紧接着同步读几何**（`syncHeaderOffset()` 读
           `.app-header.offsetHeight`，app.js:1627/1575），把这次重排**钉死在点击那一帧**里。
        ③ 重排耗时 ∝ 记录条数 ≈ **0.11ms/条**：N=600 → layout 0.080s、点页签 193ms；
           N=1200 → layout 0.082s、点页签 192ms（桌面同规模分别为 0.074s / 152ms）。
     ── 改法 ──
        给滚动视口外的卡片跳过 style/layout/paint（`content-visibility:auto`）。
        **实测手机视口 412×915：layout 0.080s → 0.002s（34×），点页签 193ms → 49ms（3.9×）。**
     ── 为什么只写在这个 ≤640px 块里 ──
        仅当 `#record-list tr` 是 flex 卡片（即本块）时 CV 才生效。桌面端它是真 table-row，
        实测 CV **对 table 内部元素无效**（0.132s → 0.125s，落在噪声内）；
        横屏手机同理走 table-row ⇒ 写全局也不会有额外收益，索性只写在真正生效处，
        避免在其它内核上对表格行产生未预期影响。
     ── 为什么安全（这是医疗记录，不能藏行）──
        行**一个不少仍在 DOM 里**（行数 / 文本 / querySelector / 勾选 / 导出 / 行内编辑全部不变），
        只是屏幕外的不参与排版；行高先按 `contain-intrinsic-size` 估算，滚到即实体化。
        Chromium < 85 不认这条 ⇒ 整条声明被丢弃、自动退回原行为，属**优雅降级**而非报错。
     ⚠️ `90px` 是「手机卡片实测高 ≈97px（含 6px margin）」的近似：估小了滚动条会把列表算短、
        滚动时逐行补正（轻微「长高」）。**改卡片 padding / 字号 / margin 后必须回来复核这个值。**
     ⚠️ 两行 `contain-intrinsic-size` 是**故意的**：老内核（Chromium 85~97）不认 `auto` 关键字，
        若只写 `auto 90px` 会被整条丢弃 ⇒ 被跳过的行按 **0 高**参与布局、列表塌成一条线。
        先给无 `auto` 的兜底，再给带 `auto` 的增强（记住每行上次实测高度，越滚越准）。 */
  #record-list tbody tr {
    content-visibility: auto;
    contain-intrinsic-size: 90px;
    contain-intrinsic-size: auto 90px;
  }
  /* 🆕 v221：异常整卡标色（不再只给数值打标记），左侧加深色条强化层级 */
  #record-list tr.rec-abn { background: #fdecea; border-color: #f3c3bd; border-left: 3px solid #c0392b; }
  html[data-theme="dark"] #record-list tr.rec-abn { background: #2a1c1c; border-color: #4a2f2f; border-left-color: #e5736f; }
  #record-list td { padding: 0; font-size: 13px; border: none; }
  #record-list td.sel-col { flex: 0 0 auto; display: inline-flex; align-items: center; }
  #record-list td.sel-col input { width: 16px; height: 16px; }
  /* 🆕 v295：日期列换到指标前 → 指标为第 3 列，与日期同行（日期在前）。
     🆕 v366（用户第 7 条②）订正：这里原写 `flex: 1 1 100%`（指标名独占整行），
        但 ≤767px 块里给它的兄弟列都配了 order ⇒ 100% 会把日期挤到指标名**下面**，
        与用户要求「原有指标名称是在日期后的」正好相反。改为 `1 1 auto`（吃剩余宽度、
        超长用 ellipsis 收），与 ≤767px 块的取值保持一致，避免两处再打架。 */
  #record-list td:nth-child(3) { flex: 1 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-weight: 600; font-size: 14px; }
  #record-list td:nth-child(2) { flex: 0 0 auto; color: var(--muted); font-size: 12.5px; }
  #record-list td:nth-child(4),
  #record-list td:nth-child(5),
  #record-list td:nth-child(6),
  #record-list td:nth-child(7) { flex: 0 0 auto; }
  /* 🆕 v366（用户第 7 条③）：这里的 `nth-child(8)` 原本是**备注**列。
     ⚠️ v363 在「较上次」之后插入了新的「严重度」列（第 8 列），备注被挤到第 9 列 ——
        这条按序号写的规则从此**打在了严重度上**，备注丢掉了自己的样式；
        更要命的是下面 @media(max-width:767px) 里同一处 `nth-child(8)` 是给备注配 `order:9`（第 3 行）的，
        序号一错，备注（内容常是「图片导入」）就掉回 order:0 ⇒ 浮到卡片**第一行**、
        夹在日期与指标名之间（用户原话：「原有图片导入是在左下角的」）。
     修法：改成第 9 列（备注）。严重度（第 8 列）改由 ≤767px 块统一给 order，见那边注释。 */
  #record-list td:nth-child(9) { flex: 1 1 100%; font-size: 12px; color: var(--muted); margin-top: 2px; padding-top: 4px; border-top: 1px dashed var(--line); }
  #record-list td.actions-col { flex: 1 1 auto; text-align: right; margin-left: auto; }
  #record-list .rr-bar { width: 48px; height: 5px; }
  #record-list .badge { font-size: 11px; padding: 2px 6px; }
  #record-list .delta { font-size: 12px; }
  #record-list .row-actions { gap: 4px; }
  #record-list .row-actions .btn { padding: 3px 8px; font-size: 11px; }

  /* 添加记录表单移到表格底部后，与上方列表用分隔线区分 */
  #form-record { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line); }
  #form-record .btn[type="submit"] { flex: 1 1 100%; min-height: 42px; }
  #rec-entry-hint { margin: 6px 0 0; font-size: 12px; }
  .rec-bulk { margin: 8px 0; gap: 6px; }

  /* 检验记录大图：手机端自适应宽度 */
  .entry-img-wrap { height: auto; max-height: none; overflow: visible; }
  .entry-img-wrap .entry-img { width: 100%; height: auto; max-width: 100%; transform: none !important; }
}

/* ===== 夜间模式（暗色主题）：仅重定义变量 + 覆盖少量写死的浅色背景，不改动任何现有规则 =====
   对标 MyChart / Medisafe / MyTherapy 等 2026 主流应用的暗色模式，改善夜间 / 弱光与移动端体验。 */
html[data-theme="dark"] { color-scheme: dark; }
html[data-theme="dark"] {
  --bg: #0f141a;
  --panel: #182230;
  --card: #161b22;
  --ink: #e6ebf1;
  --muted: #9aa6b2;
  --line: #2c3744;
  --primary: #1aa7b1;
  --primary-d: #138089;
  --danger: #e5736f;
  --shadow: 0 2px 10px rgba(0, 0, 0, 0.45);
}
/* 表单控件：补上深色背景（默认透明会露出卡片深色，但这里统一确保可读） */
html[data-theme="dark"] .form-inline input,
html[data-theme="dark"] .form-inline select,
html[data-theme="dark"] .form-grid input,
html[data-theme="dark"] .form-grid select,
html[data-theme="dark"] .form-grid textarea,
html[data-theme="dark"] .rec-filter select {
  background: #243140; color: var(--ink); border-color: var(--line);
}
html[data-theme="dark"] #rec-date-start, html[data-theme="dark"] #rec-date-end { background: #243140; color: var(--ink); border-color: var(--line); }
/* 写死的浅色表面 → 暗色 */
html[data-theme="dark"] .btn { background: #243140; color: var(--ink); border-color: var(--line); }
html[data-theme="dark"] .chart-box { background: #161b22; border-color: #2c3744; }
html[data-theme="dark"] tr:hover td { background: #202a36; }
html[data-theme="dark"] .chip { background: #243140; }
html[data-theme="dark"] .chip .star { color: #4a5663; }
html[data-theme="dark"] .chip .star.on { color: #f0a93b; }
html[data-theme="dark"] .chip.fav { border-color: #5c4a2a; }
html[data-theme="dark"] .ind-trend-up   { color: #f4b07a; background: #3a2a18; border-color: #5a4220; }
html[data-theme="dark"] .ind-trend-down { color: #8fc4e8; background: #16293a; border-color: #244a66; }
html[data-theme="dark"] .ind-trend-flat { color: #9aa6b2; background: #232a31; border-color: #36404a; }
html[data-theme="dark"] .ind-search { background: #243140; }
html[data-theme="dark"] .rec-search { background: #243140; }
html[data-theme="dark"] .med-search { background: #243140; }
html[data-theme="dark"] .rec-entry-hint { background: #1f2c38; border-color: #324454; color: #a9b6c2; }
html[data-theme="dark"] .rec-entry-hint.hi-ok { background: #14301f; border-color: #244a33; }
html[data-theme="dark"] .rec-entry-hint.hi-ok b { color: #6fcf97; }
html[data-theme="dark"] .rec-entry-hint.hi-high, html[data-theme="dark"] .rec-entry-hint.hi-low { background: #371c1c; border-color: #5a2a2a; }
html[data-theme="dark"] .rec-entry-hint.hi-high b, html[data-theme="dark"] .rec-entry-hint.hi-low b { color: #ff8a80; }
html[data-theme="dark"] .rec-entry-hint.hi-na { background: #212c38; border-color: #33414f; }
html[data-theme="dark"] .rec-entry-hint.hi-na b { color: #9aa7b4; }
html[data-theme="dark"] .chart-toolbar select { background: #243140; }
html[data-theme="dark"] .legend-item { background: #243140; }
html[data-theme="dark"] .today-med { background: #1b2530; border-color: #2a3744; }
html[data-theme="dark"] .today-med .tm-refill { color: #ffcf80; background: #3a2e12; border-color: #5a4413; }
html[data-theme="dark"] .today-med .tm-stock { color: #ffcf80; background: #3a2e12; border-color: #5a4413; }
html[data-theme="dark"] .today-med .tm-stock.urgent { color: #ff9b9b; background: #3a1717; border-color: #5a2222; }
html[data-theme="dark"] .today-med .tm-edu { color: #57c7cf; }
html[data-theme="dark"] .today-med .tm-refillbar { background: #33414f; }
html[data-theme="dark"] .today-med .tm-rf-ok { background: #3fb56f; }
html[data-theme="dark"] .today-med .tm-rf-warn { background: #d9a93a; }
html[data-theme="dark"] .today-med .tm-rf-urgent { background: #e96b67; }
html[data-theme="dark"] .today-med .tm-takeall-btn { background: #163024; border-color: #2e9e5b; color: #7ee0a7; }
html[data-theme="dark"] .today-med .tm-takeall-btn:hover { background: #2e9e5b; color: #06231a; }
html[data-theme="dark"] .today-med .tm-take-btn { background: #1d2733; border-color: #33414f; color: #9aa7b4; }
html[data-theme="dark"] .today-med .tm-take-btn.on { background: #2e9e5b; border-color: #2e9e5b; color: #fff; }
/* 🆕 v317：暗色主题下的跳过按钮 / 已跳过态 */
html[data-theme="dark"] .today-med .tm-skip-btn { background: #1d2733; border-color: #33414f; color: #9aa7b4; }
html[data-theme="dark"] .today-med .tm-skip-btn:hover { border-color: #c79a3a; color: #e0b85a; }
html[data-theme="dark"] .today-med .tm-skip-btn.on { background: #3a2f15; border-color: #c79a3a; color: #e0b85a; }
html[data-theme="dark"] .today-med .tm-take-btn.skipped { border-color: #c79a3a; color: #e0b85a; }
html[data-theme="dark"] .today-med.skipped { border-color: #4a3f22; }
html[data-theme="dark"] .tm-skipped-note { background: #2a2415; border-color: #4a3f22; border-left-color: #c79a3a; color: #e0b85a; }
html[data-theme="dark"] .today-med .tm-prn-btn { background: #14323a; border-color: #2a6b73; color: #6fd3dc; }
html[data-theme="dark"] .today-med .tm-prn-btn:hover { background: #2a6b73; color: #fff; }
html[data-theme="dark"] .today-med .tm-prn-btn.on { background: #2a6b73; color: #fff; }
html[data-theme="dark"] .today-med .tm-prn-cd.none { color: #b9c2cc; background: #2a313a; }
html[data-theme="dark"] .today-med .tm-prn-cd.safe { color: #7fe0a3; background: #16331f; }
html[data-theme="dark"] .today-med .tm-prn-cd.wait { color: #ffcf80; background: #3a2e12; }
html[data-theme="dark"] .tm-pend.prn { color: #6fd3dc; background: #14323a; border-color: #2a6b73; }
html[data-theme="dark"] .today-med .tm-taken-time { color: #7ee0a7; background: #15352a; border-color: #1f5a46; }
html[data-theme="dark"] .today-med.taken { opacity: .55; }
html[data-theme="dark"] .today-med.missed { border-color: #6e3a34; background: #2a1c1c; }
html[data-theme="dark"] .today-med.missed .tm-name { color: #ff9b8e; }
html[data-theme="dark"] .today-med .tm-missed-chip { color: #ff9b8e; background: #3a2320; border-color: #6e3a34; }
html[data-theme="dark"] .today-meds .tm-streak { color: #f0c24d; }
html[data-theme="dark"] .today-meds .tm-adh { color: #4fd1b5; }
html[data-theme="dark"] .tm-adh-weekly .tm-adh-axis { stroke: #2a3744; }
html[data-theme="dark"] .tm-adh-weekly .tm-adh-val { fill: #e6edf3; }
html[data-theme="dark"] .tm-adh-weekly .tm-adh-xl { fill: #8b98a5; }
html[data-theme="dark"] .med-adh-daily .tm-adh-daily-ref { stroke: #5b6675; }
html[data-theme="dark"] .med-adh-daily .tm-adh-daily-foot { color: #8b98a5; }
html[data-theme="dark"] .tm-adh-weekly .tm-adh-wk-foot { color: #8b98a5; }
html[data-theme="dark"] .me-item { background: #1b2530; border-color: #2a3744; }
html[data-theme="dark"] .med-effect .me-empty { background: #1b2530; border-color: #33414f; }
html[data-theme="dark"] .me-item .me-arrow { color: #4a5663; }
html[data-theme="dark"] .me-symp { background: #18222d; border-color: #2a3744; }
html[data-theme="dark"] .me-symp-col { background: #1b2530; border-color: #2a3744; }
html[data-theme="dark"] .alert-item { background: #1b2530; }
html[data-theme="dark"] .alert-item.sev-worse { background: #2a1c1c; border-color: #5c2a2a; border-left-color: #e5736f; }
html[data-theme="dark"] .alert-item.sev-better { background: #2a2417; border-color: #5c4e2a; border-left-color: #caa14b; }
html[data-theme="dark"] .alert-item.sev-flat { background: #1f2730; border-left-color: #9aa6b2; }
html[data-theme="dark"] .alert-tag.bad { background: #3a2220; color: #f0a39c; }
html[data-theme="dark"] .alert-tag.good { background: #3a3217; color: #e3c274; }
html[data-theme="dark"] .alert-tag.flat { background: #2a323c; color: #9aa6b2; }
html[data-theme="dark"] .period-summary { background: #18222e; color: #c7d0db; border-color: #2a3744; }
html[data-theme="dark"] .period-summary .ps-title { color: #4fd0d8; }
html[data-theme="dark"] .period-summary .ps-worse { color: #f0a39c; }
html[data-theme="dark"] .period-summary .ps-better { color: #7fd18a; }
html[data-theme="dark"] .period-summary .ps-flat { color: #9aa6b2; }
html[data-theme="dark"] .period-summary .ps-empty { color: #9aa6b2; }
html[data-theme="dark"] .alert-go { color: #5fd0db; }
html[data-theme="dark"] .anomaly-summary { background: #1c2a1c; color: #7fd18a; border-color: #2f4a2f; }
html[data-theme="dark"] .anomaly-summary.warn { background: #2a1c1c; color: #f0a39c; border-color: #5c2a2a; }
html[data-theme="dark"] .data-freshness { background: #142233; color: #8fc6f0; border-color: #24405c; }
html[data-theme="dark"] .data-freshness.stale { background: #2a2415; color: #e0b566; border-color: #4a3c1e; }
html[data-theme="dark"] .btn.danger-text:hover { background: #3a2220; }
/* 拍照识别卡片（scan.css 在 styles.css 之后加载，用更高优先级覆盖其浅色面） */
html[data-theme="dark"] .scan-drop,
html[data-theme="dark"] .scan-preview-wrap,
html[data-theme="dark"] .scan-result,
html[data-theme="dark"] .scan-actions { background: var(--panel); color: var(--ink); }

/* 指标趋势点击检验点 → 检验记录表对应行高亮（图表↔记录 反向联动，对标竞品关联视图）。短暂提示后自动消失 */
#record-list tr.flash td {
  background: #e3f6f7 !important;
  box-shadow: inset 3px 0 0 var(--primary);
  transition: background .25s ease;
}
html[data-theme="dark"] #record-list tr.flash td {
  background: #15393d !important;
  box-shadow: inset 3px 0 0 var(--primary);
}
/* 🆕 v367（用户第 2 条）：从指标趋势弹窗的「铅笔」跳到来源照片时，把那张**缩略图**高亮一下。
   与上一条 `tr.flash` 同一套视觉语言（青底 + 主色描边），因为二者是同一件事的两端：
   `tr.flash` = 跳到检验记录表的行；`.scan-thumb.flash` = 跳到该值的来源图片。
   没有它的话，用户面对一长条缩略图根本不知道刚定位到哪张。 */
.scan-thumb.flash {
  background: #e3f6f7;
  box-shadow: 0 0 0 3px var(--primary);
  border-radius: 8px;
  transition: background .25s ease;
}
html[data-theme="dark"] .scan-thumb.flash { background: #15393d; }

/* ========== 指标释义弹窗（DeepSeek 风格词条解释） ========== */
.def-modal {
  position: fixed; inset: 0; z-index: 2000;
  background: rgba(0,0,0,.45);
  display: none; align-items: center; justify-content: center;
  padding: 16px; backdrop-filter: blur(2px);
}
.def-modal.show { display: flex; }
.def-popup-content {
  background: #fff; border-radius: 14px; width: min(620px, 94vw);
  max-height: min(86vh, 640px); overflow: hidden;
  box-shadow: 0 20px 60px rgba(0,0,0,.22);
  display: flex; flex-direction: column; animation: defFadeIn .18s ease;
}
@keyframes defFadeIn {
  from { opacity: 0; transform: translateY(14px) scale(.98); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}
.def-popup-content header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 18px 14px; border-bottom: 1px solid #e5ebf3;
  background: #f8fbff;
}
.def-popup-content header h3 { margin: 0; font-size: 17px; color: #1f2937; }
.def-popup-content header h3 .def-unit { font-size: 13px; color: #6b7a8f; font-weight: 500; }
.def-close {
  width: 30px; height: 30px; border: none; border-radius: 50%; background: #e8eef5;
  color: #55677a; font-size: 20px; line-height: 1; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.def-close:hover { background: #dde5ee; color: #1f2937; }
.def-body {
  padding: 16px 20px 14px; overflow-y: auto; line-height: 1.65; color: #334155;
  font-size: 14px;
}
.def-body section { margin-bottom: 14px; }
.def-body section:last-child { margin-bottom: 6px; }
.def-body h4 {
  margin: 0 0 6px; font-size: 13px; color: #0e7c86; text-transform: uppercase;
  letter-spacing: .4px; font-weight: 700;
}
.def-body p { margin: 0 0 8px; }
.def-body p b { color: #1f2937; }
.def-note { background: #fff9e6; border-left: 3px solid #f0b429; padding: 10px 12px !important; border-radius: 0 8px 8px 0; }
.def-note h4 { color: #b07d1f; }
.def-tip { color: #6b7a8f; font-size: 13px; }
.def-footer {
  padding: 10px 18px; font-size: 12px; color: #8896a8;
  border-top: 1px solid #e5ebf3; background: #f8fbff; text-align: center;
}

/* 暗色主题 */
html[data-theme="dark"] .def-popup-content { background: #1c242c; box-shadow: 0 20px 60px rgba(0,0,0,.5); }
html[data-theme="dark"] .def-popup-content header { background: #161d24; border-color: #2d3946; }
html[data-theme="dark"] .def-popup-content header h3 { color: #e6edf3; }
html[data-theme="dark"] .def-popup-content header h3 .def-unit { color: #9aa6b2; }
html[data-theme="dark"] .def-close { background: #2a333d; color: #9aa6b2; }
html[data-theme="dark"] .def-close:hover { background: #33414f; color: #e6edf3; }
html[data-theme="dark"] .def-body { color: #c2ccd6; }
html[data-theme="dark"] .def-body h4 { color: #2bb6c4; }
html[data-theme="dark"] .def-body p b { color: #e6edf3; }
html[data-theme="dark"] .def-note { background: #2a281a; border-color: #b07d1f; }
html[data-theme="dark"] .def-note h4 { color: #f0c24d; }
html[data-theme="dark"] .def-tip { color: #8896a8; }
html[data-theme="dark"] .def-footer { background: #161d24; border-color: #2d3946; color: #6b7a8f; }

/* 时间轴事件标记（指标趋势竖线 + 列表） */
.event-marker { margin-top: 14px; margin-bottom: 16px; padding: 12px 14px; border: 1px solid var(--line, #e5ebf3); border-radius: 10px; background: #fbfdff; }
.event-marker h3 { margin: 0 0 6px; font-size: 15px; color: #1f2d3d; }
.event-form { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 8px 0; }
.event-form input[type="date"] { min-width: 140px; }
.event-form input[type="text"] { flex: 1 1 220px; }
.event-form input[type="color"] { width: 38px; height: 34px; padding: 0; border: 1px solid #d4dce6; border-radius: 6px; background: none; cursor: pointer; }
.event-list { margin-top: 6px; display: flex; flex-direction: column; gap: 6px; }
.event-empty { margin: 4px 0; color: #8896a8; font-size: 13px; }
.event-item { display: flex; align-items: center; gap: 8px; padding: 6px 8px; border: 1px solid #e5ebf3; border-radius: 8px; background: #fff; }
.event-bar { width: 4px; align-self: stretch; border-radius: 2px; }
.event-date { font-variant-numeric: tabular-nums; color: #6b7a8f; font-size: 13px; min-width: 92px; }
.event-label { flex: 1; color: #1f2d3d; font-size: 14px; }
/* ⚠️ v526（需求 2）：`.event-del`（淡紫底 #f3f0f7 + 紫字 #8e44ad + 圆钮）已**退役**。
   用户原话「事件记录页中的症状记录的编辑和删除按钮和其他窗口不一致，统一调整」。
   js 侧 renderEvents 的删除钮已换成 btnDel() ⇒ 类名变成 `.btn.tiny.danger-text.act-ico.act-del`
   （红底白叉 rgba(192,57,43,.92)，与指标库 / 检验记录 / 用药表逐字同款）。
   下面两条保留为**注释留档**，不要再复活：它们就是「同一功能两套外观」的来源。
   .event-del { border: none; background: #f3f0f7; color: #8e44ad; border-radius: 50%; … }
   .event-del:hover { background: #e8def4; } */
/* 症状严重程度徽标（事件列表内）：绿=轻 橙=中 红=重 */
.event-sev { font-size: 12px; font-weight: 700; padding: 1px 7px; border-radius: 8px; color: #fff; }
.event-sev.sev-mild { background: #27ae60; }
.event-sev.sev-mod { background: #e67e22; }
.event-sev.sev-sev { background: #c0392b; }
/* 事件备注（触发因素/上下文）：与 label 同行、超长省略，浅+暗主题 */
.event-note { flex: 0 1 auto; max-width: 38%; margin-left: 6px; color: #6b7a8f; font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

html[data-theme="dark"] .event-marker { background: #1a222a; border-color: #2d3946; }
html[data-theme="dark"] .event-marker h3 { color: #e6edf3; }
html[data-theme="dark"] .event-item { background: #1f2832; border-color: #2d3946; }
html[data-theme="dark"] .event-date { color: #9aa6b2; }
html[data-theme="dark"] .event-label { color: #e6edf3; }
html[data-theme="dark"] .event-empty { color: #6b7a8f; }
/* v526（需求 2）：`.event-del` 的夜间专用色已随该类退役（.act-del 自带夜间红底规则，见文件后段）。 */

/* ============================================================================
   🆕 v499（用户第 10 项）：时间轴事件标记的行内编辑
   ── 用户原话：「时间轴事件标记窗口中，编辑按钮要和其他窗口一致，编辑的时候本地事件窗口
      改为可编辑的，而不是在「时间轴事件标记」标题之下去改。」
   ── 落地（配合 js/app.js 的 evEditingId / eventEditRowHtml）：
        · 行内 ✏️ 改成与「指标库 / 检验记录 / 用药表」完全同款的 `.act-ico.act-edit`
          （26px 描边圆 + 内联 SVG 铅笔，由 btnEdit() 生成）⇒ 所以这里只补齐**删除圆钮的几何尺寸**
          （原 22px），让两颗钮并排时等宽等高。
        · 点 ✏️ 后该行原地换成「日期 / 说明 / 严重程度 / 部位 / 备注」输入控件 + ✓ ×，
          不再展开标题下方那份表单，也不再把视线滚到卡片顶部。
   ⚠️ `.ev-in` 一律走 CSS 变量取色 ⇒ 夜间模式自动跟随，不写 html[data-theme="dark"] 覆盖块
      （硬编码浅色是本项目夜间缺陷的老根因）。 */
/* 🆕 v526（需求 2）：两颗钮的**几何形状**统一为圆钮。
   实测改前（390×844）：编辑钮是 `.btn.tiny.act-ico.act-edit`，手机段 `.btn.tiny{border-radius:9px}`
   是 (0,2,0)，而 `.act-ico{border-radius:50%}` 只有 (0,1,0) ⇒ **方角**（测量值 9px）；
   同一页的用药表 / 指标库 / 检验记录行内钮因为各自带 ID 的复位规则而仍是 50% 圆钮。
   ⇒ 这里用 `.btn.act-ico`（(0,3,0)）把半径钉回 50%：既压过 `.btn.tiny` 的 9px，
      又不依赖书写顺序（这几条在 1973 行的手机段**之前**，靠特异性而非源序取胜）。
   尺寸仍交给原有规则（手机 32px / 桌面 26px），本段只改「圆的还是方的」。 */
.event-item .btn.act-ico,
.event-item .btn.act-del { border-radius: 50%; }
.event-item .btn.act-ico { width: 26px; height: 26px; min-width: 26px; min-height: 26px; padding: 0; font-size: 17px; line-height: 1; }
.event-item.editing { flex-wrap: wrap; gap: 6px; }
.event-item.editing .ev-in {
  min-width: 0; flex: 1 1 110px;
  padding: 6px 8px; font-size: 13px;
  border: 1px solid var(--line); border-radius: 8px;
  background: var(--panel); color: var(--ink);
}
.event-item.editing .ev-in-date { flex: 0 0 auto; }
.event-item.editing .ev-in-label { flex: 1 1 180px; }
.event-item.editing .ev-in-note { flex: 1 1 140px; }
/* ✓ 保存：与行内其它圆钮同款，配色走「完成态」绿（同 .act-edit.is-done 的口径） */
.act-ico.act-ok { color: #2f9d6a; }
.act-ico.act-ok:hover { background: rgba(47, 157, 106, .12); }
html[data-theme="dark"] .act-ico.act-ok { color: #5fd39a; }
html[data-theme="dark"] .event-sev.sev-mild { background: #1e8449; }
html[data-theme="dark"] .event-sev.sev-mod { background: #ca6f1e; }
html[data-theme="dark"] .event-sev.sev-sev { background: #a93226; }
html[data-theme="dark"] .event-note { color: #8593a3; }

/* 症状日历热力图（对标 CareClinic「症状频率/严重度热力图」与 MyTherapy「症状日记」）：近 13 周按天最重严重度铺色 */
.symptom-heatmap { margin-top: 12px; padding-top: 10px; border-top: 1px dashed #e5ebf3; }
.symptom-heatmap h3 { margin: 0 0 4px; font-size: 15px; color: #1f2d3d; }
.sh-sub { font-size: 12px; font-weight: 400; color: #7a8794; }
.sh-grid { display: flex; gap: 3px; flex-wrap: nowrap; overflow-x: auto; padding: 4px 0 6px; }
.sh-col { display: flex; flex-direction: column; gap: 3px; }
.sh-cell { width: 13px; height: 13px; border-radius: 3px; background: #eef2f6; flex: 0 0 auto; }
.sh-cell.sh-none { background: #eef2f6; }
.sh-cell.sev-mild { background: #27ae60; }
.sh-cell.sev-mod { background: #e67e22; }
.sh-cell.sev-sev { background: #c0392b; }
.sh-foot { display: flex; align-items: center; gap: 14px; margin-top: 2px; flex-wrap: wrap; }
.sh-legend { display: inline-flex; align-items: center; gap: 10px; }
.sh-leg { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; color: #6b7785; }
.sh-leg .sh-cell { width: 12px; height: 12px; }
html[data-theme="dark"] .symptom-heatmap { border-top-color: #2d3946; }
html[data-theme="dark"] .symptom-heatmap h3 { color: #e6edf3; }
html[data-theme="dark"] .sh-cell, html[data-theme="dark"] .sh-cell.sh-none { background: #2a333d; }
html[data-theme="dark"] .sh-cell.sev-mild { background: #1e8449; }
html[data-theme="dark"] .sh-cell.sev-mod { background: #ca6f1e; }
html[data-theme="dark"] .sh-cell.sev-sev { background: #a93226; }
html[data-theme="dark"] .sh-leg { color: #9aa6b2; }

/* 🆕 v215：症状整体趋势判定条（对标 CareClinic/MyTherapy 症状日记「趋势结论」）—— 一眼看出症状是缓解还是加重 */
.sh-verdict { margin: 0 0 8px; padding: 7px 12px; border-radius: 8px; font-size: 13px; line-height: 1.5; border: 1px solid var(--line); background: #f7f9fc; color: var(--ink); }
.sh-verdict b { font-size: 14px; }
.sh-verdict.good { background: #eef7ee; border-color: #cfe6cf; color: #1e7d3a; }
.sh-verdict.good b { color: #1e8449; }
.sh-verdict.bad { background: #fdecea; border-color: #f5c6c2; color: #a5251f; }
.sh-verdict.bad b { color: #c0392b; }
.sh-verdict.flat { background: #f1f4f8; border-color: #e0e6ee; color: #5b6675; }
.sh-verdict.flat b { color: #6b7a8d; }
.sh-trend { margin: 2px 0 6px; }
.sh-trend svg { display: block; width: 100%; height: 54px; }
.sh-trend-grid { stroke: var(--line); stroke-width: 1; stroke-dasharray: 3 3; }
html[data-theme="dark"] .sh-trend-grid { stroke: #3a4654; }
html[data-theme="dark"] .sh-verdict { background: #1f2730; border-color: #2d3946; color: #c7d0db; }
html[data-theme="dark"] .sh-verdict.good { background: #14301f; border-color: #244a33; color: #6fcf97; }
html[data-theme="dark"] .sh-verdict.good b { color: #52d98a; }
html[data-theme="dark"] .sh-verdict.bad { background: #371c1c; border-color: #5a2a2a; color: #f0a39c; }
html[data-theme="dark"] .sh-verdict.bad b { color: #ff7b6b; }
html[data-theme="dark"] .sh-verdict.flat { background: #212c38; border-color: #33414f; color: #9aa7b4; }
html[data-theme="dark"] .sh-verdict.flat b { color: #9aa7b4; }

/* 🆕 v397 检验异常日历热力图（与症状日历热力图 v215 同构，红色强度＝当天异常条数；纯只读派生，不影响任何数据） */
.lab-heatmap { margin-top: 12px; padding-top: 10px; border-top: 1px dashed #e5ebf3; }
.lah-grid { display: flex; gap: 3px; flex-wrap: nowrap; overflow-x: auto; padding: 4px 0 6px; }
.lah-col { display: flex; flex-direction: column; gap: 3px; }
.lah-cell { width: 13px; height: 13px; border-radius: 3px; background: #eef2f6; flex: 0 0 auto; }
.lah-cell.lah-0 { background: #eef2f6; }
.lah-cell.lah-1 { background: #f6b6ad; }
.lah-cell.lah-2 { background: #e8625a; }
.lah-cell.lah-3 { background: #c0392b; }
.lah-foot { display: flex; align-items: center; gap: 14px; margin-top: 2px; flex-wrap: wrap; }
.lah-legend { display: inline-flex; align-items: center; gap: 10px; }
.lah-leg { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; color: #6b7785; }
.lah-leg .lah-cell { width: 12px; height: 12px; }
html[data-theme="dark"] .lab-heatmap { border-top-color: #2d3946; }
html[data-theme="dark"] .lah-cell, html[data-theme="dark"] .lah-cell.lah-0 { background: #2a333d; }
html[data-theme="dark"] .lah-cell.lah-1 { background: #7d3b35; }
html[data-theme="dark"] .lah-cell.lah-2 { background: #b5473f; }
html[data-theme="dark"] .lah-cell.lah-3 { background: #a93226; }
html[data-theme="dark"] .lah-leg { color: #9aa6b2; }

/* 健康概览（v273）：移到 app-header 下方，做成横向滚动摘要条 */
.health-overview { display: flex; align-items: center; gap: 0; padding: 8px 12px; margin: 0; background: linear-gradient(90deg, #f4fbff, #eef6ff); border-bottom: 1px solid #dceaf6; overflow: hidden; }
.ho-grid { display: flex; flex-wrap: nowrap; align-items: center; gap: 6px 10px; flex: 1 1 auto; overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none; scroll-snap-type: x mandatory; padding-bottom: 4px; }
.ho-grid::-webkit-scrollbar { display: none; }
.ho-item { display: inline-flex; flex-direction: column; flex: 0 0 auto; line-height: 1.18; padding: 6px 10px; scroll-snap-align: start; border-radius: 8px; }
.ho-main { display: inline-flex; flex-direction: column; }
/* 🆕 健康概览下钻：概览项可点击跳到对应视图（纯只读导航） */
.health-overview .ho-item { cursor: pointer; transition: background .15s, box-shadow .15s; }

.ho-val { font-size: 18px; font-weight: 700; color: #1f2d3d; font-variant-numeric: tabular-nums; }
.ho-label { font-size: 12px; color: #6b7a8f; }
.ho-sub { font-size: 11px; color: #9aa6b2; }
.ho-item.ho-warn .ho-val { color: #c0392b; }
.ho-item.ho-ok .ho-val { color: #27ae60; }
.ho-item.ho-med .ho-val { color: #8e44ad; }
.ho-item.ho-stale .ho-val { color: #d9822b; }
.health-overview.ho-stale { border-color: #f0d3ad; background: linear-gradient(90deg, #fff8ef, #fdf0e0); }
.health-overview .ho-item:hover { background: rgba(14,124,134,.10); box-shadow: 0 1px 0 rgba(14,124,134,.18); }
.health-overview .ho-item:focus-visible { outline: 2px solid #0e7c86; outline-offset: 1px; }

/* 🆕 待办 / 需关注中心（对标 MyChart 2026「For You / care gaps / daily tasks」个性化待办首页）：把散落的需关注事项收敛成一条 glanceable 待办清单，每项可下钻 */
.action-center { margin: 0 0 14px; padding: 12px 16px; background: #fffdf6; border: 1px solid #f0e3c0; border-radius: 12px; }
.action-center .ac-head { font-weight: 700; color: #b3791b; font-size: 15px; margin-bottom: 8px; display: flex; align-items: center; gap: 8px; }
.action-center .ac-count { display: inline-flex; align-items: center; justify-content: center; min-width: 20px; height: 20px; padding: 0 6px; border-radius: 10px; background: #b3791b; color: #fff; font-size: 12px; font-weight: 700; }
.ac-item { display: flex; align-items: center; gap: 10px; padding: 8px 10px; margin-top: 6px; border-radius: 9px; cursor: pointer; background: rgba(255,255,255,.6); border: 1px solid transparent; transition: background .15s, box-shadow .15s; }
.ac-item:hover { background: rgba(179,121,27,.10); box-shadow: 0 1px 0 rgba(179,121,27,.18); }
.ac-item:focus-visible { outline: 2px solid #b3791b; outline-offset: 1px; }
.ac-icon { font-size: 16px; flex: 0 0 auto; }
.ac-text { flex: 1 1 auto; font-size: 13px; color: #1f2d3d; }
.ac-go { flex: 0 0 auto; font-size: 12px; color: #9aa6b2; }
.ac-item.ac-high { background: #fdecec; border-color: #f3c4c4; }
.ac-item.ac-high .ac-text { color: #c0392b; }
.ac-item.ac-mod { background: #fff6e9; border-color: #f3dcbd; }
.ac-item.ac-mod .ac-text { color: #a9650f; }
.ac-note { margin-top: 8px; font-size: 11px; color: #9aa6b2; }

html[data-theme="dark"] .health-overview { background: linear-gradient(90deg, #10212b, #16242f); border-color: #28414f; }
html[data-theme="dark"] .health-overview .ho-title { color: #5fd0db; }
html[data-theme="dark"] .ho-val { color: #e6edf3; }
html[data-theme="dark"] .ho-label { color: #9aa6b2; }
html[data-theme="dark"] .ho-sub { color: #6b7a8f; }
html[data-theme="dark"] .ho-item.ho-warn .ho-val { color: #ff7b6b; }
html[data-theme="dark"] .ho-item.ho-ok .ho-val { color: #52d98a; }
html[data-theme="dark"] .ho-item.ho-med .ho-val { color: #c79be8; }
html[data-theme="dark"] .ho-item.ho-stale .ho-val { color: #f0b267; }
html[data-theme="dark"] .health-overview.ho-stale { background: linear-gradient(90deg, #2a2113, #2a1c12); border-color: #5a4326; }
html[data-theme="dark"] .health-overview .ho-item:hover { background: rgba(95,208,219,.12); box-shadow: 0 1px 0 rgba(95,208,219,.22); }
html[data-theme="dark"] .health-overview .ho-item:focus-visible { outline-color: #5fd0db; }

html[data-theme="dark"] .action-center { background: #1c1810; border-color: #4a3a1c; }
html[data-theme="dark"] .action-center .ac-head { color: #e6b35c; }
html[data-theme="dark"] .action-center .ac-count { background: #e6b35c; color: #1c1810; }
html[data-theme="dark"] .ac-text { color: #e6ebf1; }
html[data-theme="dark"] .ac-go { color: #6b7a8f; }
html[data-theme="dark"] .ac-item { background: rgba(255,255,255,.04); }
html[data-theme="dark"] .ac-item:hover { background: rgba(230,179,92,.12); box-shadow: 0 1px 0 rgba(230,179,92,.22); }
html[data-theme="dark"] .ac-item.ac-high { background: #2a1717; border-color: #5a2a2a; }
html[data-theme="dark"] .ac-item.ac-high .ac-text { color: #ff7b6b; }
html[data-theme="dark"] .ac-item.ac-mod { background: #2a2113; border-color: #5a4326; }
html[data-theme="dark"] .ac-item.ac-mod .ac-text { color: #f0b267; }

@media (max-width: 640px) {
  .health-overview { padding: 6px 10px; }
  .health-overview .ho-val { font-size: 16px; }
  .ho-grid { gap: 4px 8px; }
  .ho-item { padding: 5px 8px; }
}

/* 检验记录表「参考范围 + 区间位置条」（对标 Apple Health / MyChart 2026 / Guava
   「结果落在参考区间中的位置一眼可见」）：淡绿带＝参考区间（居中 25%~75%），
   游标＝本次结果相对位置（正常绿 / 偏高红 / 偏低蓝），超出显示域则贴边并以箭头示意。 */
.rr-col { white-space: nowrap; }
.rr { display: inline-flex; flex-direction: column; gap: 3px; line-height: 1.1; }
.rr-bar { position: relative; display: block; width: 78px; height: 6px; border-radius: 4px; background: #eef2f6; }
.rr-band { position: absolute; left: 25%; width: 50%; top: 0; bottom: 0; border-radius: 4px; background: #d7f0dd; }
.rr-mark { position: absolute; top: 50%; width: 8px; height: 8px; margin: -4px 0 0 -4px; border-radius: 50%; box-shadow: 0 0 0 1.5px #fff; }
.rr-mark.rr-ok { background: #27ae60; }
.rr-mark.rr-high { background: #d9534f; }
.rr-mark.rr-low { background: #2980b9; }
.rr-mark.rr-over::after { content: '›'; position: absolute; left: 8px; top: -7px; font-size: 12px; font-weight: 700; color: #d9534f; }
.rr-mark.rr-under::after { content: '‹'; position: absolute; right: 8px; top: -7px; font-size: 12px; font-weight: 700; color: #2980b9; }
.rr-txt { font-size: 11px; color: #7a8794; font-variant-numeric: tabular-nums; }
.rr-na { color: #b3bcc9; }

html[data-theme="dark"] .rr-bar { background: #2a333d; }
html[data-theme="dark"] .rr-band { background: #1f4a30; }
html[data-theme="dark"] .rr-mark { box-shadow: 0 0 0 1.5px #161b22; }
html[data-theme="dark"] .rr-mark.rr-ok { background: #52d98a; }
html[data-theme="dark"] .rr-mark.rr-high { background: #ff7b6b; }
html[data-theme="dark"] .rr-mark.rr-low { background: #5aa9e6; }
html[data-theme="dark"] .rr-mark.rr-over::after { color: #ff7b6b; }
html[data-theme="dark"] .rr-mark.rr-under::after { color: #5aa9e6; }
html[data-theme="dark"] .rr-txt { color: #9aa6b2; }
html[data-theme="dark"] .rr-na { color: #6b7a8f; }

@media (max-width: 640px) {
  .rr-bar { width: 56px; }
  .rr-txt { font-size: 10px; }
}

/* 🆕 v196：用药依从日历 */
.med-adherence { margin-top: 4px; }
.adh-head { display: flex; align-items: center; justify-content: center; gap: 12px; margin-bottom: 8px; }
.adh-title { font-weight: 600; font-size: 14px; min-width: 96px; text-align: center; color: #1f2d3d; }
.adh-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; max-width: 288px; margin: 0 auto; }
.adh-wd { text-align: center; font-size: 11px; color: #8a97a6; padding-bottom: 2px; }
.adh-cell { text-align: center; font-size: 12px; padding: 6px 0; border-radius: 6px; background: #f1f4f8; color: #4a5563; }
.adh-cell.empty { background: transparent; }
.adh-cell.taken { background: #2e9e5b; color: #fff; font-weight: 600; }
.adh-cell.missed { background: #fbe9e7; color: #b06a63; }
.adh-cell.future { background: transparent; color: #c4ccd6; }
.adh-cell.today { outline: 2px solid #0e7c86; outline-offset: -2px; }
.adh-cell[data-adh-date] { cursor: pointer; }
.adh-cell.sel { outline: 2px solid #1565c0; outline-offset: -2px; }
.adh-detail { margin-top: 8px; font-size: 12.5px; line-height: 1.5; color: #33414f; background: #eef6fb; border: 1px solid #cfe3ef; border-radius: 8px; padding: 7px 9px; }
.adh-detail b { color: #0e7c86; }
.adh-sum { text-align: center; font-size: 13px; margin-top: 8px; color: #33414f; }
.adh-sum b { color: #2e9e5b; font-size: 15px; }
/* 🆕 v318：连续打卡统计（当前连续 / 最长连续 / 上次中断），对标 Mango Health 2026 gamification */
.adh-streak { text-align: center; font-size: 13px; margin-top: 7px; font-weight: 600; color: #b8690c; background: #fff6e9; border: 1px solid #f3d9a8; border-radius: 8px; padding: 5px 8px; }
.adh-streak b { color: #d98318; font-size: 15px; }
.adh-legend { display: flex; gap: 14px; justify-content: center; margin-top: 6px; font-size: 11px; color: #6b7a8d; }
.adh-dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; margin-right: 4px; vertical-align: middle; }
.adh-dot.taken { background: #2e9e5b; }
.adh-dot.missed { background: #fbe9e7; border: 1px solid #e7b9b3; }
.adh-dot.future { background: #c4ccd6; }
.adh-mom { text-align: center; font-size: 12.5px; margin-top: 6px; font-weight: 600; color: #33414f; }
.adh-mom.up { color: #2e9e5b; }
.adh-mom.down { color: #d9534f; }
.adh-mom.flat { color: #6b7a8d; }
html[data-theme="dark"] .adh-title { color: #d6dde6; }
html[data-theme="dark"] .adh-wd { color: #7c8a99; }
html[data-theme="dark"] .adh-cell { background: #222b35; color: #c7d0db; }
html[data-theme="dark"] .adh-cell.taken { background: #2e9e5b; color: #fff; }
html[data-theme="dark"] .adh-cell.missed { background: #3a2622; color: #d99c92; }
html[data-theme="dark"] .adh-cell.future { background: transparent; color: #5b6675; }
html[data-theme="dark"] .adh-cell.sel { outline: 2px solid #4dabf7; }
html[data-theme="dark"] .adh-detail { color: #c7d0db; background: #1b2630; border-color: #2c3a47; }
html[data-theme="dark"] .adh-detail b { color: #4dabf7; }
html[data-theme="dark"] .adh-sum { color: #c7d0db; }
html[data-theme="dark"] .adh-legend { color: #9aa7b5; }
html[data-theme="dark"] .adh-streak { color: #e9b873; background: #3a2e1c; border-color: #5a4528; }
html[data-theme="dark"] .adh-streak b { color: #f0b35a; }
/* 🆕 v315：星期几依从热力图 */
.adh-weekday { margin-top: 10px; }
.adh-wd-row { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; max-width: 288px; margin: 0 auto; }
.adh-wd-cell { text-align: center; border-radius: 6px; padding: 7px 0 6px; color: #fff; }
.adh-wd-cell .adh-wd-l { display: block; font-size: 11px; opacity: .92; }
.adh-wd-cell .adh-wd-p { display: block; font-size: 13px; font-weight: 700; }
.adh-wd-cell.hot { background: #2e9e5b; }
.adh-wd-cell.warm { background: #7bc043; color: #1c2e0c; }
.adh-wd-cell.mild { background: #e8b339; color: #3a2e00; }
.adh-wd-cell.cool { background: #e8821e; }
.adh-wd-cell.cold { background: #d9534f; }
.adh-wd-cap { text-align: center; font-size: 11.5px; margin-top: 6px; color: #6b7a8d; }
.adh-wd-cap b { color: #d9534f; }
.adh-risk { margin-top: 8px; text-align: center; font-size: 12.5px; font-weight: 600; color: #7a3fbf; background: #f6efff; border: 1px solid #e0cff7; border-radius: 8px; padding: 6px 8px; }
.adh-risk b { color: #8e44ad; font-size: 14px; }
html[data-theme="dark"] .adh-weekday .adh-wd-cell { color: #fff; }
html[data-theme="dark"] .adh-wd-cell.warm { color: #16240d; }
html[data-theme="dark"] .adh-wd-cell.mild { color: #2e2400; }
html[data-theme="dark"] .adh-wd-cap { color: #9aa7b5; }
html[data-theme="dark"] .adh-risk { color: #c9a6f0; background: #2e2342; border-color: #463261; }
html[data-theme="dark"] .adh-risk b { color: #d7b3f5; }
html[data-theme="dark"] .adh-mom { color: #c7d0db; }
html[data-theme="dark"] .adh-mom.up { color: #5ad08a; }
html[data-theme="dark"] .adh-mom.down { color: #ef9a9a; }
html[data-theme="dark"] .adh-mom.flat { color: #9aa7b5; }

/* 🆕 v203：指标库行可点击 → 跳到该指标趋势（纯导航，对标 MyChart「view trends over time」） */
.ind-row { cursor: pointer; transition: background .12s ease; }
.ind-row:hover { background: #eef6f8; }
html[data-theme="dark"] .ind-row:hover { background: #253039; }

/* ===== v216：手机端 UI 精修（impeccable 设计原则：4pt 基距 / 文字层级 / 触控目标 ≥40px / 留白呼吸感） =====
   全部改动只在 max-width:640px 内生效，桌面版零影响。
   医疗场景选「克制的极简风」：统一 14-16px 圆角、卡片间 14px 间距、按钮与输入框触控加大、
   卡片标题带 emoji 图标（HTML 侧已加）、辅助文字统一 12-12.5px muted 层级。 */
@media (max-width: 640px) {
  /* ① 卡片系统：更大圆角 + 更舒展的间隔（4pt 基距 14/16） */
  .card { border-radius: 16px; padding: 14px 14px 16px; margin-bottom: 14px; }
  .card h2 { font-size: 15.5px; letter-spacing: .2px; }
  .card-head h2 { font-size: 15.5px; }
  .card .hint, .card > p.hint { font-size: 12.5px; line-height: 1.65; color: var(--muted); margin: 6px 0 10px; }

  /* ② 按钮：触控目标 ≥ 40px（impeccable 44px 建议，工具类场景取 40px 平衡密度），圆角统一 */
  .btn { min-height: 40px; display: inline-flex; align-items: center; justify-content: center; padding: 8px 16px; border-radius: 10px; font-size: 14px; }
  .btn.tiny { min-height: 36px; padding: 5px 12px; font-size: 12.5px; border-radius: 9px; }
  .btn.primary { font-weight: 600; }

  /* ③ 表单/搜索/下拉/日期：触控加大（min-height 42px + 15px 字号，避免 iOS 聚焦缩放） */
  .form-inline input, .form-inline select,
  .form-grid input, .form-grid select, .form-grid textarea,
  .rec-filter select, .rec-search, .med-search, .ind-search,
  #rec-date-start, #rec-date-end,
  .chart-toolbar input[type="date"], .chart-toolbar select {
    min-height: 42px; font-size: 15px; border-radius: 10px;
  }
  .form-grid label { gap: 5px; font-size: 13.5px; }
  .form-inline input::placeholder, .form-grid input::placeholder, .ind-search::placeholder,
  .rec-search::placeholder, .med-search::placeholder { color: #9aa6b2; }

  /* ④ 页眉与页签：更紧凑、层次更分明（🆕 v278 页签在顶行，字号/内边距相应收紧） */
  /* P1 适配：最紧凑断点同样叠加安全区（避免覆盖基础规则的 safe-area） */
  .app-header { padding: calc(7px + env(safe-area-inset-top, 0px)) 10px 7px; gap: 6px; }
  .brand .logo { font-size: 22px; }
  .tab { padding: 6px 10px 7px; font-weight: 500; font-size: 13.5px; }

  /* ⑤ 指标趋势页 */
  .health-overview { border-radius: 16px; padding: 12px 14px; margin-bottom: 12px; }
  .health-overview .ho-title { font-size: 14px; }
  .ho-item { border-radius: 12px; }
  .ho-item .ho-val { font-size: 19px; }
  .chart-box { border-radius: 16px; }
  .chart-tabs { margin: 10px 0 6px; }
  .chart-tab { padding: 8px 14px; font-size: 13.5px; }
  .chart-tab-nav { width: 34px; height: 34px; font-size: 17px; }
  .ind-checks-block { padding: 10px 12px; border-radius: 12px; }
  .chip { padding: 7px 12px; font-size: 13.5px; min-height: 36px; border-radius: 999px; }
  .chip .star { font-size: 15px; }
  .anomaly-summary, .data-freshness { border-radius: 12px; padding: 10px 14px; font-size: 13.5px; }
  .alert-item { border-radius: 12px; padding: 10px 14px; }
  .alert-tag { font-size: 12.5px; padding: 2px 9px; }
  .legend-item { padding: 8px 12px; border-radius: 10px; }
  .event-marker { border-radius: 12px; padding: 12px 14px; margin-bottom: 14px; }
  .event-marker h3 { font-size: 14.5px; }
  .event-item { padding: 8px 10px; border-radius: 10px; }

  /* ⑦ 时间轴事件列表（🆕 v508，用户第 2 项）：窄屏改「卡片式」两行布局，不再按表格排。
     ── 症状（用户截图：说明文字逐字竖排）：
        原 `.event-item` 是**单行 flex**，`.event-label` 用 `flex: 1`（= `flex: 1 1 0%`）
        且**没设 `min-width`**；而 flex 项默认 `min-width: auto`，在中文上解析为
        **一个汉字宽**（CJK 任意两字之间都能断行 ⇒ min-content = 1 字）。
        于是它与「日期(固定 92px) / 严重度徽标 / 备注(≤38%) / 两颗 26px 操作钮」抢宽度时，
        被压到 1 字宽 ⇒ 6 个字的「激素冲击开始」就排成了 6 行。
     ── 修法：窄屏让**说明独占一整行**（`flex-basis: 100%`，想抢也抢不到宽度），
        备注退到第三行；第一行只留「日期 + 严重度 + 操作钮」。
        用 `order` 实现，**不改 app.js 的渲染顺序**（DOM 顺序保持原样，桌面端一行不受影响）。 */
  .event-item { flex-wrap: wrap; row-gap: 4px; }
  .event-item .event-label {
    order: 1; flex: 1 1 100%; min-width: 0;
    font-size: 14.5px; font-weight: 600; line-height: 1.45; overflow-wrap: anywhere;
  }
  .event-item .event-note {
    order: 2; flex: 1 1 100%; max-width: 100%; margin-left: 0;
    white-space: normal; overflow: visible; text-overflow: clip; line-height: 1.5;
  }
  /* 日期不再吃 92px：独占行内它无需为「对齐成表格」而保留固定宽度 */
  .event-item .event-date { min-width: 0; }
  /* 两颗操作钮推到第一行右端，并统一到同一尺寸
     🆕 v526（需求 2）：删除钮类名 `.event-del` → `.act-del`（统一 btnDel 后），本段随之改名。
     🆕 v533（用户需求 2）：32px → **26px**（用户原话「列表窗口中按钮太大，要和其他按钮保持一致」
        —— 全站行内钮 `.act-ico` 桌面/手机都是 26px，此处此前放大到 32px 反而成了异类）。 */
  .event-item > .act-ico.act-edit { margin-left: auto; }
  .event-item > .btn.act-ico.act-edit,
  .event-item > .btn.act-ico.act-del {
    width: 26px; height: 26px; min-width: 26px; min-height: 26px; padding: 0; line-height: 1;
  }
  .sh-cell { width: 14px; height: 14px; border-radius: 4px; }
  .sh-verdict { border-radius: 10px; padding: 8px 12px; }
  .range-presets .btn, .rec-date-presets .btn { padding: 5px 12px; }

  /* ⑥ 检验记录页 */
  .scan-drop { padding: 16px; border-radius: 12px; }
  .scan-drop .btn { flex: 1 1 100%; }
  .scan-entry { border-radius: 14px; }
  .page-actions-bar { gap: 8px; }
  .page-actions-bar .btn { flex: 1 1 calc(50% - 4px); min-width: 0; }
  .rec-bulk .btn { min-height: 34px; }
  .rec-filter { row-gap: 8px; }
  .rec-summary { font-size: 12.5px; }
  .badge { font-size: 11.5px; padding: 3px 10px; }
  .rec-entry-hint { font-size: 12.5px; border-radius: 10px; }

  /* ⑦ 用药记录页 */
  .today-med { border-radius: 12px; padding: 10px 12px; }
  /* 🆕 v530（需求 3）：今日用药「打卡圆圈」（○ 已服钮）与窗口右上角 🌰（.hint-q 26×26）统一大小。
     原来 ≤640px 放大到 32×32，与 🌰 的 26×26 不一致（用户报「打卡圆圈与 🌰 大小不统一」）。 */
  .today-med .tm-take-btn { width: 26px; height: 26px; font-size: 14px; }
  .adh-cell { padding: 8px 0; font-size: 13px; border-radius: 8px; }
  .adh-grid { gap: 5px; max-width: 300px; }
  .me-item { border-radius: 12px; }
  .me-symp-col { border-radius: 10px; }
  .med-effect .me-empty { border-radius: 12px; }

  /* ⑧ 档案页 */
  .patient-window { border-radius: 14px; padding: 12px 14px; }
  .patient-window .pw-name { font-size: 16px; }
  .patient-windows { gap: 8px; }
  .patient-window .pw-chips { display:flex; flex-wrap:wrap; gap:5px; margin-top:8px; }
  .patient-window .pw-chip { font-size:12px; line-height:1.4; padding:2px 8px; border-radius:999px; background:#eef1f6; color:#46505f; }
  .patient-window .pw-abn { background:#fdecec; color:#c0392b; }
  .patient-window .pw-ok { background:#e9f7ef; color:#1e8449; }
  html[data-theme="dark"] .patient-window .pw-chip { background:#243140; color:#c7d0db; }
  html[data-theme="dark"] .patient-window .pw-abn { background:#3a1c1a; color:#ff9b8e; }
  html[data-theme="dark"] .patient-window .pw-ok { background:#1e3328; color:#6fd39a; }

  /* ⑨ 会员中心（手机端） */
  .billing-mode-chip { font-size: 10.5px; padding: 2px 9px; }
  .bv-login-tab { padding: 11px 0; font-size: 14.5px; }
  .bv-user-head { gap: 10px; }
  .bv-avatar { width: 42px; height: 42px; font-size: 18px; }
  .bv-plan { padding: 12px; border-radius: 14px; }
  .bv-price-now { font-size: 20px; }
  .bv-actions .btn { flex: 1 1 100%; }
}

/* ===== v216：会员中心（档案页「账号与订阅」收费管理模块）=====
   前端演示版样式：登录/注册、7 天试用状态、¥18/¥8 价格、邀请码、模拟支付弹窗。
   所有颜色走主题变量（--panel/--ink/--muted/--line/--primary），少量浅色底补暗色覆盖。 */
.billing-mode-chip { display: inline-block; font-size: 11px; font-weight: 600; color: #0e7c86;
  background: #e8f5f6; border: 1px solid #b8e0e3; border-radius: 999px; padding: 2px 10px; white-space: nowrap; }
html[data-theme="dark"] .billing-mode-chip { color: #5fd0db; background: #15393d; border-color: #28414f; }

/* 登录/注册 */
.bv-login-tabs { display: flex; gap: 6px; margin: 4px 0 12px; }
.bv-login-tab { flex: 1 1 50%; padding: 10px 0; border: 1px solid var(--line); border-radius: 10px;
  background: #fff; color: var(--muted); font-size: 14px; cursor: pointer; transition: all .15s; text-align: center; }
.bv-login-tab.on { background: var(--primary); color: #fff; border-color: var(--primary); font-weight: 600; }
.bv-field { display: flex; flex-direction: column; gap: 5px; margin-bottom: 12px; }
.bv-field label { font-size: 13px; color: var(--muted); }
.bv-field input { padding: 11px 12px; border: 1px solid var(--line); border-radius: 10px;
  font-size: 15px; color: var(--ink); background: #fff; min-height: 44px; }
.bv-field input:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 2px rgba(14,124,134,.15); }
.bv-submit { width: 100%; min-height: 46px; font-size: 15px; font-weight: 600; border-radius: 12px; }
.bv-switch { text-align: center; margin-top: 10px; font-size: 13px; color: var(--muted); }
.bv-switch a { color: var(--primary); cursor: pointer; font-weight: 600; }
.bv-err { margin: 0 0 10px; padding: 8px 12px; border-radius: 10px; font-size: 13px;
  background: #fdecea; color: #c0392b; border: 1px solid #f5c6c2; }
html[data-theme="dark"] .bv-login-tab { background: #243140; }
html[data-theme="dark"] .bv-login-tab.on { background: var(--primary); color: #fff; }
html[data-theme="dark"] .bv-field input { background: #243140; }
html[data-theme="dark"] .bv-err { background: #371c1c; border-color: #5a2a2a; color: #f0a39c; }
/* 🆕 v511：本地演示模式的说明条 + 一键切到云端账号（.bv-mode-tip / #bv-to-server）。
   配色取「提示」语义（琥珀），与 .bv-err 的红色错误区分开 —— 它不是报错，
   而是一句「你现在在哪个模式」的说明。 */
.bv-mode-tip { margin: 0 0 10px; padding: 8px 12px; border-radius: 10px; font-size: 13px;
  background: #fff8e6; color: #8a5a00; border: 1px solid #f0d9a0; line-height: 1.55; }
.bv-mode-tip a { color: #0e7c86; font-weight: 700; text-decoration: underline; cursor: pointer; }
html[data-theme="dark"] .bv-mode-tip { background: #3a2f16; border-color: #5d4a1d; color: #f0cf8a; }
html[data-theme="dark"] .bv-mode-tip a { color: #4fd0d8; }

/* 已登录：账号信息 + 订阅状态 + 价格 */
.bv-user-head { display: flex; align-items: center; gap: 12px; padding: 10px 0 12px; border-bottom: 1px dashed var(--line); margin-bottom: 12px; }
.bv-avatar { width: 46px; height: 46px; border-radius: 50%; background: linear-gradient(135deg, #0e7c86, #14a0a8);
  color: #fff; font-size: 20px; font-weight: 700; display: flex; align-items: center; justify-content: center; flex: 0 0 auto; }
.bv-user-name { font-weight: 700; font-size: 16px; }
.bv-user-meta { color: var(--muted); font-size: 12.5px; margin-top: 2px; }
.bv-logout { margin-left: auto; }
.bv-plan { display: flex; align-items: center; gap: 12px; padding: 12px 14px; border-radius: 14px;
  margin-bottom: 12px; border: 1px solid var(--line); background: #f7fafc; }
.bv-plan-icon { font-size: 28px; flex: 0 0 auto; }
.bv-plan-body { flex: 1 1 auto; min-width: 0; }
.bv-plan-status { font-weight: 700; font-size: 15px; }
.bv-plan-sub { color: var(--muted); font-size: 12.5px; margin-top: 2px; line-height: 1.5; }
.bv-plan-status.ok { color: #1e8449; }
.bv-plan-status.trial { color: #0e7c86; }
.bv-plan-status.warn { color: #b9770e; }
.bv-plan-status.expired { color: #c0392b; }
.bv-price { text-align: right; flex: 0 0 auto; }
.bv-price-now { font-size: 22px; font-weight: 800; color: #c0392b; font-variant-numeric: tabular-nums; }
.bv-price-now small { font-size: 12px; font-weight: 600; }
.bv-price-old { font-size: 12px; color: var(--muted); text-decoration: line-through; }
.bv-price-tag { display: inline-block; margin-top: 3px; font-size: 10px; font-weight: 700; color: #8a4b00;
  background: #fff3cd; border: 1px solid #ffe08a; border-radius: 6px; padding: 1px 6px; white-space: nowrap; }
.bv-actions { display: flex; gap: 8px; margin-bottom: 12px; }
.bv-actions .btn { flex: 1 1 50%; min-width: 0; }
.bv-actions .btn.primary { font-weight: 600; }
html[data-theme="dark"] .bv-plan { background: #1b2530; }
html[data-theme="dark"] .bv-price-now { color: #ff7b6b; }
html[data-theme="dark"] .bv-price-tag { color: #ffcf80; background: #3a2e12; border-color: #5a4413; }

/* 邀请码 */
.bv-invite { border: 1px dashed #b8d8e8; background: #f4f9fc; border-radius: 12px; padding: 12px 14px; }
/* 🆕 v525（需求10①）：用户「我的邀请码窗口要改成从左到右排列，不要一列文本竖着排」。
   实测（390×844，真页面量的）：本行宽 314px，而 🎁(约25)+标题(约75)+邀请码(约108)+
   复制(39)+推荐给好友(87)+间距(40) ≈ 374px ⇒ flex 默认允许收缩，标题 span 被压成
   **w=16 / h=113**（逐字竖排）；复制按钮也被压到 39px 折成两行。
   修法：开 `flex-wrap` 让即使不够宽也只换行、不拆字；子项 `flex:0 0 auto` + `nowrap` 锁住自然宽度。
   桌面端宽度足够时仍为一行，行为不变。 */
.bv-invite-code-row { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; row-gap: 8px; }
.bv-invite-code-row > * { flex: 0 0 auto; white-space: nowrap; }
/* 🆕 v537（项8）：邀请码字号 18→16、字距 2→1px —— 与同行的「复制 / 推荐给好友」按钮视觉比重更均衡，
   不再让 6 位邀请码在整行里过分突出。 */
.bv-invite-code { font-size: 16px; font-weight: 800; letter-spacing: 1px; color: var(--primary); font-variant-numeric: tabular-nums; }
.bv-invite-tip { color: var(--muted); font-size: 12.5px; line-height: 1.6; margin-top: 6px; }
/* 🆕 v536（项2）：邀请码说明由一段话改为 4 行（首句「好友使用我的邀请码注册享…」），
   末行为邀请使用状态（rankHtml）。行间距与「会员权益」的 bf-rows 观感对齐。 */
.bv-invite-lines { margin-top: 8px; display: flex; flex-direction: column; gap: 6px; }
.bv-invite-line { color: var(--muted); font-size: 12.5px; line-height: 1.55; }
.bv-invite-line b { color: var(--ink); }
.bv-invite-line .bv-invite-tip,
.bv-invite-line .bv-invite-ok { margin-top: 0; display: inline; }
.bv-invite-ok { display: inline-flex; align-items: center; gap: 4px; margin-top: 6px; font-size: 12px; font-weight: 600; color: #1e8449; }
html[data-theme="dark"] .bv-invite { border-color: #28414f; background: #142028; }
html[data-theme="dark"] .bv-invite-ok { color: #4cd07d; }

/* 订阅记录 */
.bv-history { margin-top: 12px; }
.bv-history h4 { font-size: 13px; color: var(--muted); margin: 0 0 6px; font-weight: 600; }
.bv-his-item { display: flex; align-items: center; gap: 8px; padding: 8px 10px; border-radius: 10px;
  background: #f7f9fc; margin-bottom: 6px; font-size: 13px; }
.bv-his-item .bh-date { color: var(--muted); font-variant-numeric: tabular-nums; font-size: 12px; flex: 0 0 auto; }
.bv-his-item .bh-desc { flex: 1 1 auto; min-width: 0; word-break: break-word; }
.bv-his-item .bh-amt { font-weight: 700; color: #c0392b; flex: 0 0 auto; }
.bv-his-item .bh-tag { font-size: 11px; font-weight: 600; padding: 1px 7px; border-radius: 8px;
  background: #eef7ee; color: #1e8449; white-space: nowrap; flex: 0 0 auto; }
html[data-theme="dark"] .bv-his-item { background: #1f2730; }
html[data-theme="dark"] .bv-his-item .bh-amt { color: #ff7b6b; }
html[data-theme="dark"] .bv-his-item .bh-tag { background: #14301f; color: #6fcf97; }

/* 模拟支付弹窗（微信支付演示） */
.bv-paymask { position: fixed; inset: 0; z-index: 3000; background: rgba(0,0,0,.45);
  display: none; align-items: center; justify-content: center; padding: 20px; backdrop-filter: blur(2px); }
.bv-paymask.show { display: flex; }
.bv-paycard { background: var(--panel); border-radius: 18px; width: min(360px, 92vw); padding: 20px 18px 16px;
  box-shadow: 0 20px 60px rgba(0,0,0,.25); animation: defFadeIn .18s ease; }
.bv-pay-title { font-size: 16px; font-weight: 700; text-align: center; margin-bottom: 4px; }
.bv-pay-amt { text-align: center; font-size: 30px; font-weight: 800; color: #c0392b; margin: 8px 0 2px; font-variant-numeric: tabular-nums; }
.bv-pay-amt small { font-size: 14px; font-weight: 600; }
.bv-pay-desc { text-align: center; font-size: 12.5px; color: var(--muted); margin-bottom: 14px; }
.bv-pay-methods { display: flex; flex-direction: column; gap: 8px; margin-bottom: 14px; }
/* 🆕 v511（遗留待办 ⑮）：无可用通道时的占位块（替代原先把「微信支付 · 真实收银台」假显示出来） */
.bv-pay-empty { border: 1.5px dashed #e0b34a; background: #fff8e6; border-radius: 12px;
  padding: 12px 14px; font-size: 13px; color: #8a5a00; line-height: 1.6; }
.bv-pay-empty .pm-sub { font-size: 11.5px; color: #a07a2a; margin-top: 2px; }
html[data-theme="dark"] .bv-pay-empty { background: #3a2f16; border-color: #5d4a1d; color: #f0cf8a; }
html[data-theme="dark"] .bv-pay-empty .pm-sub { color: #cbb072; }
.bv-pay-method { display: flex; align-items: center; gap: 10px; border: 1.5px solid var(--line); background: transparent;
  border-radius: 12px; padding: 12px 14px; cursor: pointer; transition: border-color .15s, background .15s; }
.bv-pay-method.selected { border: 1.5px solid #25c26a; background: #f2fbf5; }
.bv-pay-method .pm-icon { font-size: 22px; }
.bv-pay-method .pm-name { font-weight: 700; font-size: 14px; }
.bv-pay-method .pm-sub { font-size: 11.5px; color: var(--muted); }
.bv-pay-method .pm-check { margin-left: auto; color: #25c26a; font-size: 20px; font-weight: 800; opacity: 0; }
.bv-pay-method.selected .pm-check { opacity: 1; }
.bv-pay-actions { display: flex; gap: 8px; }
.bv-pay-actions .btn { flex: 1 1 50%; min-height: 46px; }
.bv-pay-note { margin-top: 10px; text-align: center; font-size: 11.5px; color: var(--muted); }
html[data-theme="dark"] .bv-paycard { background: #182230; }
html[data-theme="dark"] .bv-pay-method.selected { background: #14301f; border-color: #2e9e5b; }
html[data-theme="dark"] .bv-pay-amt { color: #ff7b6b; }

/* ===== v217：前面 3 页手机端 UI 再美化（impeccable：层级/留白/触控/信息密度） =====
   只作用于 max-width:640px，桌面零影响。重点解决：大段说明文字霸占首屏、
   健康概览纵向堆叠过高、时间范围控件紧凑度不足、数据管理按钮缺图标语义、
   上传区不够突出、用药时段徽标不醒目。 */
@media (max-width: 640px) {
  /* —— 1. 超长说明文字默认折叠（两行），点击展开 —— */
  .card > p.hint.hint-collapsed,
  .panel > p.hint.hint-collapsed,
  .event-marker > p.hint.hint-collapsed,
  .symptom-heatmap > p.hint.hint-collapsed {
    position: relative; max-height: 3.6em; overflow: hidden;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    margin-bottom: 4px; padding-bottom: 0; }
  .hint-collapsed::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 1.4em;
    background: linear-gradient(transparent, var(--panel)); pointer-events: none; }
  .hint-open { max-height: none !important; -webkit-line-clamp: unset !important; overflow: visible !important; }
  .hint-open::after { display: none; }
  .hint-toggle { display: inline-flex; align-items: center; gap: 3px; margin: 2px 0 10px; padding: 5px 12px;
    min-height: 32px; border: 1px solid var(--line); border-radius: 999px; background: transparent;
    color: var(--primary); font-size: 12.5px; font-weight: 600; cursor: pointer; transition: all .15s; }
  .hint-toggle:hover { background: rgba(14,124,134,.08); border-color: var(--primary); }
  html[data-theme="dark"] .hint-collapsed::after { background: linear-gradient(transparent, var(--panel)); }

  /* —— 2. 健康概览：2 列紧凑网格卡片 —— */
  .health-overview { padding: 12px; }
  .ho-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; }
  .ho-item { padding: 10px 10px 8px; border-radius: 12px; background: rgba(255,255,255,.6);
    border: 1px solid var(--line); box-shadow: 0 1px 0 rgba(0,0,0,.02); }
  .ho-item .ho-main { flex-direction: column; gap: 2px; align-items: flex-start; }
  .ho-item .ho-val { font-size: 21px; line-height: 1.15; }
  .ho-item .ho-label { font-size: 12.5px; color: var(--muted); }
  .ho-item .ho-sub { font-size: 11px; color: var(--muted); margin-top: 3px; }
  html[data-theme="dark"] .ho-item { background: rgba(255,255,255,.05); border-color: #2c3a4c; }

  /* —— 3. 指标趋势时间范围控件：已下移到图表下方，与图表选项同区（v221）——
     第一行：时间范围 + 起始 ~ 结束（两个日期压在一行）；第二行：清空 + pill 快捷档位。 */
  .chart-toolbar-bottom .chart-range-ctrl { gap: 6px; align-items: center; flex-wrap: wrap;
    margin-top: 8px; padding-top: 10px; border-top: 1px dashed var(--line); }
  .chart-toolbar-bottom .chart-range-ctrl > label {
    order: 1; flex: 0 0 auto; font-size: 13px; font-weight: 600; color: var(--ink); }
  .chart-toolbar-bottom .chart-range-ctrl input[type="date"] { order: 2; flex: 1 1 0; min-width: 0; font-size: 12px; }
  .chart-toolbar-bottom #range-end { order: 4; }
  .chart-toolbar-bottom .chart-range-ctrl > span:not(.range-presets) { order: 3; flex: 0 0 auto; color: var(--muted); }
  .chart-toolbar-bottom #btn-range-clear { order: 5; flex: 0 0 auto; padding: 6px 12px; }
  .chart-toolbar-bottom .chart-range-ctrl .range-presets { order: 6; display: flex; flex: 1 1 auto; gap: 6px; margin: 0; justify-content: flex-end; }
  .chart-toolbar-bottom .chart-range-ctrl .range-presets .btn { border-radius: 999px; padding: 6px 10px; font-size: 12.5px; }

  /* —— 4. 指标趋势选项：复选框胶囊卡片 —— */
  .chart-toolbar-bottom { gap: 8px; padding: 10px 12px; border-radius: 14px;
    border: 1px solid var(--line); background: var(--panel); }
  .chart-toolbar-bottom .ctrl { flex: 1 1 100%; margin: 0; }
  .chart-toolbar-bottom label.check { display: flex; align-items: center; gap: 8px; padding: 9px 12px;
    min-height: 40px; border: 1px solid var(--line); border-radius: 10px; background: #fff;
    font-size: 13.5px; color: var(--ink); }
  .chart-toolbar-bottom label.check input { width: 17px; height: 17px; accent-color: var(--primary); }
  .chart-toolbar-bottom .chart-type-ctrl { gap: 8px; align-items: center; margin-top: 4px; }
  .chart-toolbar-bottom .chart-type-ctrl label { font-size: 13px; font-weight: 600; color: var(--ink); }
  .chart-toolbar-bottom .chart-type-ctrl select { flex: 1 1 auto; }
  html[data-theme="dark"] .chart-toolbar-bottom label.check { background: #1a232e; border-color: #2c3a4c; }

  /* —— 5. 异常预警：更醒目的左侧色条 + 胶囊状态 —— */
  .alert-item { padding: 10px 12px; border-radius: 12px; gap: 8px; align-items: center; }
  .alert-tag { font-size: 11.5px; padding: 2px 8px; }
  .alert-name { font-size: 13.5px; }
  .alert-streak { font-size: 12.5px; color: var(--muted); }

  /* —— 6. 检验页数据管理按钮：emoji 图标与紧凑网格 —— */
  .page-actions-bar { gap: 8px; }
  .page-actions-bar .btn { flex: 1 1 calc(50% - 4px); gap: 5px; font-size: 13.5px; padding: 8px 10px; border-radius: 10px; }
  .page-actions-bar .btn.danger { order: 4; opacity: .95; }

  /* —— 7. 检验结果导入区：更突出的大点击区 —— */
  .scan-drop { display: flex; flex-direction: column; align-items: center; gap: 10px; text-align: center;
    padding: 24px 16px; border: 1.5px dashed #9bcbd0; border-radius: 16px;
    background: rgba(14,124,134,.04); }
  .scan-drop-icon { font-size: 32px; line-height: 1; filter: grayscale(.2); }
  .scan-drop .btn { width: 100%; min-height: 44px; font-size: 14.5px; border-radius: 12px; }
  .scan-drop .hint { margin: 0; font-size: 12px; color: var(--muted); }

  /* —— 8. 指标库/检验记录表：说明折叠后卡片更清爽 —— */
  .card > p.hint { font-size: 12.5px; line-height: 1.65; }
  .card .form-inline { gap: 8px; margin-bottom: 10px; }
  .card .form-inline input, .card .form-inline select { flex: 1 1 120px; }
  .rec-filter { padding: 10px 12px; border-radius: 12px; background: rgba(14,124,134,.03); border: 1px solid var(--line); }
  .rec-filter > label { font-size: 12.5px; color: var(--muted); }
  .rec-filter select, .rec-filter input { font-size: 14px; }
  .rec-date-presets { display: flex; flex: 1 1 100%; gap: 6px; margin-top: 4px; }
  .rec-date-presets .btn { flex: 1 1 auto; border-radius: 999px; }

  /* —— 9. 用药页：今日用药时段徽标胶囊化、卡片更清晰 —— */
  .today-med { gap: 10px; padding: 12px 14px; border-radius: 14px; align-items: flex-start; }
  .today-med .tm-body { flex: 1 1 auto; min-width: 0; }
  .today-med .tm-name { font-size: 15px; font-weight: 700; }
  .today-med .tm-meta { display: block; font-size: 12px; color: var(--muted); margin-top: 3px; }
  .today-med .tm-refill { display: inline-block; font-size: 11px; font-weight: 600; margin-top: 5px;
    padding: 2px 8px; border-radius: 6px; background: #fff7e6; color: #b9770e; }
  .today-med .tm-refillbar { height: 6px; border-radius: 4px; margin-top: 6px; }
  .today-med .tm-start { flex: 0 0 auto; font-size: 11px; color: var(--muted); white-space: nowrap; align-self: center; }
  .tm-group { margin-bottom: 10px; }
  .tm-group-title { display: flex; align-items: center; gap: 6px; margin: 12px 0 8px;
    font-weight: 700; font-size: 14px; color: var(--ink); }
  .tm-group-title .tm-group-n { margin-left: auto; font-size: 11px; font-weight: 600;
    padding: 3px 10px; border-radius: 999px; background: var(--line); color: var(--muted); }
  .tm-group.now .tm-group-title { color: var(--primary); }
  .tm-group.now .tm-group-title .tm-group-n { background: var(--primary); color: #fff; }
  .tm-group-title .tm-now-badge { font-size: 10px; font-weight: 700; letter-spacing: .5px;
    padding: 2px 7px; border-radius: 999px; background: var(--primary); color: #fff; }
  .tm-group-title .tm-pend { font-size: 11px; padding: 2px 8px; border-radius: 999px;
    background: #fff; border: 1px solid var(--line); color: var(--muted); }
  .tm-group-title .tm-pend.done { background: #eef7ee; color: #1e8449; border-color: #cfe6cf; }
  .tm-count { font-size: 14px; margin-bottom: 8px; padding: 8px 10px; border-radius: 10px;
    background: rgba(14,124,134,.06); color: var(--ink); font-weight: 500; }
  .tm-count .tm-now-tip.pending { color: var(--primary); font-weight: 600; }
  .tm-count .tm-now-tip.done { color: #1e8449; }

  /* —— 10. 用药依从日历：更圆润 —— */
  .med-adherence { padding: 10px 8px; border-radius: 12px; border: 1px solid var(--line); background: var(--panel); }
  .adh-head { margin-bottom: 10px; }
  .adh-title { font-size: 15px; }
  .adh-grid { gap: 6px; max-width: none; padding: 0 6px; }
  .adh-cell { padding: 10px 0; font-size: 13.5px; border-radius: 10px; }
  .adh-sum { font-size: 13px; }

  /* —— 11. 事件标记 & 症状热力图：说明折叠、表单紧凑 —— */
  .event-marker { padding: 12px; border-radius: 14px; }
  .event-marker h3 { font-size: 15px; margin-bottom: 8px; }
  .event-form { gap: 8px; }
  .event-form input, .event-form select { flex: 1 1 100%; }
  .event-form #btn-ev-add { flex: 1 1 100%; }
  .symptom-heatmap { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line); }
}

/* 🆕 v220 日常测量（生命体征追踪） */
/* 🆕 v512（用户第 7 项）：「日常记录页的窗口宽度和其他页签不一样，改成一致的。」
   ── 实测（_v512_probe_width.js，视口 1200）──
     · 其它页签：.content(max-width:1100, padding:16) 里 .panel 宽 **1068px**（left=94），卡直接是 .panel 子元素；
     · 本页：.panel-vitals 同样 1068px，但其下多套了一层 .vitals-wrap{max-width:760px; margin:0 auto; padding:8px 4px 40px}
       ⇒ 里面所有卡片被压到 **752px**（left=252），左右各缩进 158px，与其它页签对不齐。
   ⇒ 去掉 760px 居中约束与左右 4px 内边距（保留 40px 页脚留白，不影响宽度计算），
     卡片左/右边界随 .panel 撑满，与「指标趋势 / 检验记录 / 用药记录 / 档案 / 会员中心」完全一致。
   ⚠️ 只改宽度约束：间距仍由 .card{margin-bottom:16px} 提供，垂直节奏不变。 */
.vitals-wrap { max-width: none; margin: 0; padding: 0 0 40px; }
.vitals-wrap h2 { font-size: 18px; margin: 10px 0 4px; }
.vitals-hint { color: #6b7785; font-size: 12px; line-height: 1.5; margin: 0 0 12px; }
.vitals-form { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; background: #f5f7fa; border: 1px solid #e3e8ee; border-radius: 10px; padding: 10px; margin-bottom: 16px; }
.vitals-form input, .vitals-form select { padding: 7px 9px; border: 1px solid #cfd6df; border-radius: 7px; font-size: 14px; background: #fff; color: #1f2d3d; }
.vitals-form #vitals-value { width: 92px; }
.vitals-form #vitals-note { flex: 1; min-width: 120px; }
.vitals-form .btn { background: #2d7ff9; color: #fff; border: none; border-radius: 7px; padding: 8px 16px; font-size: 14px; cursor: pointer; }
.vitals-form .btn:hover { filter: brightness(1.05); }
.vitals-empty { color: #6b7785; font-size: 13px; background: #f5f7fa; border: 1px dashed #cfd6df; border-radius: 10px; padding: 18px; text-align: center; }
.vitals-card { background: #fff; border: 1px solid #e3e8ee; border-radius: 10px; padding: 10px 12px; margin-bottom: 12px; box-shadow: 0 1px 2px rgba(20, 40, 80, .04); }
.vc-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 6px; }
.vc-name { font-weight: 600; font-size: 15px; }
.vc-latest { color: #44505f; font-size: 13px; }
.vc-count { color: #8a96a3; font-size: 12px; margin-left: auto; }
.v-chip { font-size: 11px; font-weight: 600; border-radius: 6px; padding: 1px 7px; white-space: nowrap; }
.v-chip.v-ok { color: #1e7e45; background: #e6f6ec; border: 1px solid #b6e3c6; }
.v-chip.v-high { color: #b3261e; background: #fdecea; border: 1px solid #f3c2bd; }
.v-chip.v-low { color: #1559b0; background: #e8f1fc; border: 1px solid #bcd6f5; }
.vitals-spark { display: block; width: 100%; height: 48px; background: #fafbfc; border-radius: 6px; margin: 4px 0 8px; }
.vitals-spark .v-band { fill: rgba(39, 174, 96, .12); }
/* ══════════════════════════════════════════════════════════════════════════════
   🆕 v512（用户第 5 项）：下面从 `#bmi-board` 起、直到本页 `.bp-insight` 段为止的一批
   「体征监测看板」样式（#bmi-board / #weight-board / #temp-board / #glucose-board /
   #spo2-board / #hr-board / #waist-board / #bp-board 及其 .bmi-* / .temp-* / .glu-* / .spo2-* /
   .hr-* / .waist-* / .bp-board-* 子规则与暗色覆盖）**已随 DOM 与 JS 一起下线**，属死样式。
   ── 为什么保留而不删 ──
     ① 选择器全部是 `#id` 私有前缀，没有 DOM 时**零副作用**（不影响任何其它窗口的渲染）；
     ② 其中夹杂着仍然在用的规则（如上方的 `.vitals-spark`，被 #vitals-list 的迷你走势使用）与
        **共享选择器组**（`.bp-insight:empty` 与 `.med-monitor:empty` / `.med-edu:empty` 同组，
        见本段后文注释），逐行切除极易误伤；
     ③ 本仓库无 git，删除不可回溯 ⇒ 采用「保留 + 显式标注」的稳妥处置。
   ⚠️ 后续若要做样式瘦身，请按 `#id` 逐个确认无同名复用后再删。
   ══════════════════════════════════════════════════════════════════════════════ */
/* 🆕 自动优化 v468：BMI 看板（日常测量卡片底部，纯派生只读） */
#bmi-board { border: 1px solid #e3e8ee; border-left: 4px solid #5b8def; border-radius: 10px; background: #fff; padding: 10px 12px; margin-bottom: 14px; box-shadow: 0 1px 2px rgba(20,40,80,.04); }
.bmi-head { font-weight: 600; font-size: 15px; margin-bottom: 6px; }
.bmi-main { display: flex; align-items: baseline; gap: 10px; margin-bottom: 4px; }
.bmi-value { font-size: 28px; font-weight: 700; color: #1f2d3d; }
.bmi-unit { font-size: 13px; font-weight: 500; color: #8a96a3; }
.bmi-chip { font-size: 12px; font-weight: 600; border-radius: 6px; padding: 2px 9px; }
.bmi-chip.bmi-ok { color: #1e7e45; background: #e6f6ec; border: 1px solid #b6e3c6; }
.bmi-chip.bmi-low { color: #1559b0; background: #e8f1fc; border: 1px solid #bcd6f5; }
.bmi-chip.bmi-high { color: #b3261e; background: #fdecea; border: 1px solid #f3c2bd; }
.bmi-chip.bmi-obese { color: #fff; background: #c0392b; border: 1px solid #a93226; }
.bmi-sub { color: #44505f; font-size: 13px; margin-bottom: 4px; }
.bmi-trend-label { font-size: 12px; margin-top: 2px; }
.bmi-hint, .bmi-empty { color: #6b7785; font-size: 13px; line-height: 1.6; background: #f5f7fa; border: 1px dashed #dfe4ea; border-radius: 8px; padding: 8px 10px; }
.bmi-foot { font-size: 11.5px; margin-top: 6px; }
/* 🆕 自动优化 v480：体重趋势监测看板（对标 BMI 看板样式，左色条区分） */
#weight-board { border: 1px solid #e3e8ee; border-left: 4px solid #7a5cc9; border-radius: 10px; background: #fff; padding: 10px 12px; margin-bottom: 14px; box-shadow: 0 1px 2px rgba(20,40,80,.04); }
.wt-head { font-weight: 600; font-size: 15px; margin-bottom: 6px; }
.wt-main { display: flex; align-items: baseline; gap: 10px; margin-bottom: 4px; flex-wrap: wrap; }
.wt-value { font-size: 28px; font-weight: 700; color: #1f2d3d; }
.wt-unit { font-size: 14px; font-weight: 600; color: #6b7785; }
.wt-sub { color: #44505f; font-size: 13px; margin-bottom: 4px; }
.wt-trend-label { font-size: 12px; margin-top: 2px; }
.wt-stat { font-size: 12px; margin-top: 4px; }
.wt-foot { font-size: 11.5px; margin-top: 6px; }
.wt-flag { font-size: 12px; font-weight: 600; border-radius: 6px; padding: 2px 9px; }
.wt-flag-up { color: #b3261e; background: #fdecea; border: 1px solid #f3c2bd; }
.wt-flag-down { color: #1e7e45; background: #e6f6ec; border: 1px solid #b6e3c6; }
.wt-flag-flat { color: #1559b0; background: #e8f1fc; border: 1px solid #bcd6f5; }
.wt-empty { color: #6b7785; font-size: 13px; line-height: 1.6; background: #f5f7fa; border: 1px dashed #dfe4ea; border-radius: 8px; padding: 8px 10px; }
/* 🆕 自动优化 v471：体温发热分级看板（对标 BMI 看板样式，左色条区分） */
#temp-board { border: 1px solid #e3e8ee; border-left: 4px solid #e67e22; border-radius: 10px; background: #fff; padding: 10px 12px; margin-bottom: 14px; box-shadow: 0 1px 2px rgba(20,40,80,.04); }
.tp-head { font-weight: 600; font-size: 15px; margin-bottom: 6px; }
.tp-main { display: flex; align-items: baseline; gap: 10px; margin-bottom: 4px; flex-wrap: wrap; }
.tp-value { font-size: 28px; font-weight: 700; color: #1f2d3d; }
.tp-chip { font-size: 12px; font-weight: 600; border-radius: 6px; padding: 2px 9px; }
.tp-chip.tp-ok { color: #1e7e45; background: #e6f6ec; border: 1px solid #b6e3c6; }
.tp-chip.tp-low { color: #1559b0; background: #e8f1fc; border: 1px solid #bcd6f5; }
.tp-chip.tp-lowfever { color: #b3670e; background: #fdf0e3; border: 1px solid #f0d3ad; }
.tp-chip.tp-midfever { color: #b3500e; background: #fde8da; border: 1px solid #f0c2a3; }
.tp-chip.tp-highfever { color: #b3261e; background: #fdecea; border: 1px solid #f3c2bd; }
.tp-chip.tp-cri { color: #fff; background: #c0392b; border: 1px solid #a93226; }
.tp-sub { color: #44505f; font-size: 13px; margin-bottom: 4px; }
.tp-trend-label { font-size: 12px; margin-top: 2px; }
.tp-flag { font-size: 12px; font-weight: 600; border-radius: 6px; padding: 2px 9px; }
.tp-flag-ok { color: #1e7e45; background: #e6f6ec; border: 1px solid #b6e3c6; }
.tp-flag-cold { color: #1559b0; background: #e8f1fc; border: 1px solid #bcd6f5; }
.tp-flag-hot { color: #fff; background: #e67e22; border: 1px solid #cf6d12; }
.tp-empty { color: #6b7785; font-size: 13px; line-height: 1.6; background: #f5f7fa; border: 1px dashed #dfe4ea; border-radius: 8px; padding: 8px 10px; }
.tp-foot { font-size: 11.5px; margin-top: 6px; }
/* 🆕 自动优化 v472：血糖自我管理看板 */
/* 🆕 v503（项 9）：补卡片容器 —— 原先只写了内层 .glu-* 样式，容器本身无边框/背景，
   在「日常测量」卡片里显示成一块**无边界文本区**，与 bmi/temp/spo2/hr/weight 五个看板风格不统一。
   配色取玫红 #d81b60（呼应「🩸 血糖」，且与 hr 的大红 #e74c3c 可区分）。
   以下容器模板与既有 5 个看板逐字一致，只为风格统一，不改内层任何规则。 */
#glucose-board { border: 1px solid #e3e8ee; border-left: 4px solid #d81b60; border-radius: 10px; background: #fff; padding: 10px 12px; margin-bottom: 14px; box-shadow: 0 1px 2px rgba(20,40,80,.04); }
.glu-head { font-weight: 600; font-size: 15px; margin-bottom: 6px; }
.glu-main { display: flex; align-items: baseline; gap: 10px; margin-bottom: 4px; flex-wrap: wrap; }
.glu-value { font-size: 28px; font-weight: 700; color: #1f2d3d; }
.glu-chip { font-size: 12px; font-weight: 600; border-radius: 6px; padding: 2px 9px; }
.glu-chip.glu-ok { color: #1e7e45; background: #e6f6ec; border: 1px solid #b6e3c6; }
.glu-chip.glu-high { color: #b3670e; background: #fdf0e3; border: 1px solid #f0d3ad; }
.glu-chip.glu-cri { color: #fff; background: #c0392b; border: 1px solid #a93226; }
.glu-meal { font-size: 12px; font-weight: 600; border-radius: 6px; padding: 2px 9px; color: #1559b0; background: #e8f1fc; border: 1px solid #bcd6f5; }
.glu-sub { color: #44505f; font-size: 13px; margin-bottom: 4px; }
.glu-trend-label { font-size: 12px; margin-top: 2px; }
.glu-stat { font-size: 12px; margin-top: 4px; }
.glu-foot { font-size: 11.5px; margin-top: 6px; }
.glu-empty { color: #6b7785; font-size: 13px; line-height: 1.6; background: #f5f7fa; border: 1px dashed #dfe4ea; border-radius: 8px; padding: 8px 10px; }
/* 🆕 自动优化 v474：血氧（SpO₂）监测看板（对标血糖/体温看板样式，左色条区分） */
#spo2-board { border: 1px solid #e3e8ee; border-left: 4px solid #16a085; border-radius: 10px; background: #fff; padding: 10px 12px; margin-bottom: 14px; box-shadow: 0 1px 2px rgba(20,40,80,.04); }
.spo2-head { font-weight: 600; font-size: 15px; margin-bottom: 6px; }
.spo2-main { display: flex; align-items: baseline; gap: 10px; margin-bottom: 4px; flex-wrap: wrap; }
.spo2-value { font-size: 28px; font-weight: 700; color: #1f2d3d; }
.spo2-chip { font-size: 12px; font-weight: 600; border-radius: 6px; padding: 2px 9px; }
.spo2-chip.spo2-ok { color: #1e7e45; background: #e6f6ec; border: 1px solid #b6e3c6; }
.spo2-chip.spo2-mild { color: #b3670e; background: #fdf0e3; border: 1px solid #f0d3ad; }
.spo2-chip.spo2-mod { color: #b3500e; background: #fde8da; border: 1px solid #f0c2a3; }
.spo2-chip.spo2-cri { color: #fff; background: #c0392b; border: 1px solid #a93226; }
.spo2-flag { font-size: 12px; font-weight: 600; border-radius: 6px; padding: 2px 9px; }
.spo2-flag-ok { color: #1e7e45; background: #e6f6ec; border: 1px solid #b6e3c6; }
.spo2-flag-low { color: #fff; background: #e67e22; border: 1px solid #cf6d12; }
.spo2-sub { color: #44505f; font-size: 13px; margin-bottom: 4px; }
.spo2-trend-label { font-size: 12px; margin-top: 2px; }
.spo2-stat { font-size: 12px; margin-top: 4px; }
.spo2-foot { font-size: 11.5px; margin-top: 6px; }
.spo2-empty { color: #6b7785; font-size: 13px; line-height: 1.6; background: #f5f7fa; border: 1px dashed #dfe4ea; border-radius: 8px; padding: 8px 10px; }
/* 🆕 自动优化 v475：心率（HR）监测看板样式（临床分级：正常/心动过缓/心动过速/显著），置于日常测量卡片最底部，红色左边框与血氧(border-left teal)区分 */
#hr-board { border: 1px solid #e3e8ee; border-left: 4px solid #e74c3c; border-radius: 10px; background: #fff; padding: 10px 12px; margin-bottom: 14px; box-shadow: 0 1px 2px rgba(20,40,80,.04); }
.hr-head { font-weight: 600; font-size: 15px; margin-bottom: 6px; }
.hr-main { display: flex; align-items: baseline; gap: 10px; margin-bottom: 4px; flex-wrap: wrap; }
.hr-value { font-size: 28px; font-weight: 700; color: #1f2d3d; }
.hr-chip { font-size: 12px; font-weight: 600; border-radius: 6px; padding: 2px 9px; }
.hr-chip.hr-ok { color: #1e7e45; background: #e6f6ec; border: 1px solid #b6e3c6; }
.hr-chip.hr-low { color: #b3670e; background: #fdf0e3; border: 1px solid #f0d3ad; }
.hr-chip.hr-high { color: #b3500e; background: #fde8da; border: 1px solid #f0c2a3; }
.hr-chip.hr-cri { color: #fff; background: #c0392b; border: 1px solid #a93226; }
.hr-flag { font-size: 12px; font-weight: 600; border-radius: 6px; padding: 2px 9px; }
.hr-flag-ok { color: #1e7e45; background: #e6f6ec; border: 1px solid #b6e3c6; }
.hr-flag-warn { color: #fff; background: #e67e22; border: 1px solid #cf6d12; }
.hr-sub { color: #44505f; font-size: 13px; margin-bottom: 4px; }
.hr-trend-label { font-size: 12px; margin-top: 2px; }
.hr-stat { font-size: 12px; margin-top: 4px; }
.hr-foot { font-size: 11.5px; margin-top: 6px; }
.hr-empty { color: #6b7785; font-size: 13px; line-height: 1.6; background: #f5f7fa; border: 1px dashed #dfe4ea; border-radius: 8px; padding: 8px 10px; }
/* 🆕 v503（项 9）：腰围看板补卡片容器（原因同 #glucose-board）。左色条取棕 #795548，
   与 weight 紫 #7a5cc9 / temp 橙 #e67e22 均不相近。 */
#waist-board { border: 1px solid #e3e8ee; border-left: 4px solid #795548; border-radius: 10px; background: #fff; padding: 10px 12px; margin-bottom: 14px; box-shadow: 0 1px 2px rgba(20,40,80,.04); }
.waist-head { font-weight: 600; font-size: 15px; margin-bottom: 6px; }
.waist-main { display: flex; align-items: baseline; gap: 10px; margin-bottom: 4px; flex-wrap: wrap; }
.waist-value { font-size: 28px; font-weight: 700; color: #1f2d3d; }
.waist-chip { font-size: 12px; font-weight: 600; border-radius: 6px; padding: 2px 9px; }
.waist-chip.waist-ok { color: #1e7e45; background: #e6f6ec; border: 1px solid #b6e3c6; }
.waist-chip.waist-pre { color: #b3670e; background: #fdf0e3; border: 1px solid #f0d3ad; }
.waist-chip.waist-obese { color: #fff; background: #c0392b; border: 1px solid #a93226; }
.waist-flag { font-size: 12px; font-weight: 600; border-radius: 6px; padding: 2px 9px; }
.waist-flag-ok { color: #1e7e45; background: #e6f6ec; border: 1px solid #b6e3c6; }
.waist-flag-warn { color: #fff; background: #e67e22; border: 1px solid #cf6d12; }
.waist-sub { color: #44505f; font-size: 13px; margin-bottom: 4px; }
.waist-trend-label { font-size: 12px; margin-top: 2px; }
.waist-stat { font-size: 12px; margin-top: 4px; }
.waist-foot { font-size: 11.5px; margin-top: 6px; }
.waist-empty { color: #6b7785; font-size: 13px; line-height: 1.6; background: #f5f7fa; border: 1px dashed #dfe4ea; border-radius: 8px; padding: 8px 10px; }
/* 🆕 自动优化 v479：血压（高血压分级）监测看板样式（对标 waist-board 同构） */
/* 🆕 v503（项 9）：血压看板补卡片容器（原因同 #glucose-board）。左色条取深蓝 #0277bd，
   与 bmi 的浅蓝 #5b8def 拉开明度差；注意与 v226 的 #bp-insight（灰色动态竖条）是两个不同窗口。 */
#bp-board { border: 1px solid #e3e8ee; border-left: 4px solid #0277bd; border-radius: 10px; background: #fff; padding: 10px 12px; margin-bottom: 14px; box-shadow: 0 1px 2px rgba(20,40,80,.04); }
.bp-board-head { font-weight: 600; font-size: 15px; margin-bottom: 6px; }
.bp-board-main { display: flex; align-items: baseline; gap: 10px; margin-bottom: 4px; flex-wrap: wrap; }
.bp-board-value { font-size: 28px; font-weight: 700; color: #1f2d3d; }
.bp-board-unit { font-size: 13px; font-weight: 600; color: #6b7785; }
.bp-board-chip { font-size: 12px; font-weight: 600; border-radius: 6px; padding: 2px 9px; }
.bp-board-chip.bp-normal { color: #1e7e45; background: #e6f6ec; border: 1px solid #b6e3c6; }
.bp-board-chip.bp-hn { color: #8a6100; background: #fff6e0; border: 1px solid #f0d799; }
.bp-board-chip.bp-g1 { color: #9c4a00; background: #fff0e0; border: 1px solid #f5cfa8; }
.bp-board-chip.bp-g2 { color: #b3261e; background: #fdecea; border: 1px solid #f3c2bd; }
.bp-board-chip.bp-g3 { color: #fff; background: #b3261e; border: 1px solid #8e1c15; }
.bp-board-chip.bp-low { color: #1559b0; background: #e8f1fc; border: 1px solid #bcd6f5; }
.bp-board-flag { font-size: 12px; font-weight: 600; border-radius: 6px; padding: 2px 9px; }
.bp-board-flag-ok { color: #1e7e45; background: #e6f6ec; border: 1px solid #b6e3c6; }
.bp-board-flag-warn { color: #fff; background: #e67e22; border: 1px solid #cf6d12; }
.bp-board-flag-caution { color: #8a6100; background: #fff6e0; border: 1px solid #f0d799; }
.bp-board-sub { color: #44505f; font-size: 13px; margin-bottom: 4px; }
.bp-board-trend-label { font-size: 12px; margin-top: 4px; }
.bp-board-trend { margin-bottom: 4px; }
.bp-board-trend-row { display: flex; align-items: center; gap: 8px; margin-top: 2px; }
.bp-board-tl { width: 44px; font-size: 12px; color: #6b7785; flex: none; }
.bp-board-ts { flex: 1; min-width: 0; }
.bp-board-avg { font-size: 12.5px; margin-top: 4px; }
.bp-board-stat { font-size: 12px; margin-top: 4px; }
.bp-board-foot { font-size: 11.5px; margin-top: 6px; }
.bp-board-empty { color: #6b7785; font-size: 13px; line-height: 1.6; background: #f5f7fa; border: 1px dashed #dfe4ea; border-radius: 8px; padding: 8px 10px; }
.vitals-rows { list-style: none; margin: 0; padding: 0; }
.vitals-rows li { display: flex; align-items: center; gap: 8px; padding: 4px 0; border-top: 1px solid #f0f2f5; font-size: 13px; }
.v-date { color: #6b7785; width: 88px; }
.v-val { font-weight: 600; }
.v-note { color: #8a96a3; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v-del { margin-left: auto; border: none; background: transparent; color: #b0b8c1; font-size: 16px; cursor: pointer; line-height: 1; padding: 2px 6px; border-radius: 6px; }
.v-del:hover { color: #e74c3c; background: #fdecea; }
/* 🆕 v282：自定义健康追踪项（睡眠/步数/疼痛/心情…），对标 CareClinic 2026「customizable monitoring… and more」个性化追踪 */
.custom-trackers { margin-top: 16px; }
.ct-hint { color: #6b7785; font-size: 13px; margin: 4px 0 10px; }
.ct-add { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; }
.ct-add input { flex: 1; min-width: 120px; padding: 8px 10px; border: 1px solid #d7dee7; border-radius: 8px; font-size: 14px; background: #fff; color: #1f2a36; }
.ct-empty { color: #8a96a3; font-size: 13px; padding: 10px 12px; background: #fafbfc; border: 1px dashed #e1e7ee; border-radius: 8px; }
.ct-empty.sm { padding: 6px 10px; margin-top: 6px; }
.ct-item { background: #fff; border: 1px solid #e3e8ee; border-radius: 10px; padding: 10px 12px; margin-bottom: 12px; box-shadow: 0 1px 2px rgba(20, 40, 80, .04); }
.ct-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.ct-name { font-weight: 600; color: #1f2a36; }
.ct-unit { color: #6b7785; font-size: 12px; background: #eef2f7; border-radius: 6px; padding: 1px 7px; }
.ct-latest { color: #3a4a5a; font-size: 13px; }
.ct-latest.muted { color: #9aa6b2; }
.ct-count { color: #8a96a3; font-size: 12px; }
.ct-del-track { margin-left: auto; border: none; background: transparent; color: #b0b8c1; font-size: 18px; cursor: pointer; line-height: 1; padding: 2px 8px; border-radius: 6px; }
.ct-del-track:hover { color: #e74c3c; background: #fdecea; }
.ct-spark { display: block; width: 100%; height: 48px; background: #fafbfc; border-radius: 6px; margin: 6px 0 8px; }
.ct-entry-form { display: flex; gap: 8px; margin: 6px 0; flex-wrap: wrap; }
.ct-entry-form input { padding: 7px 9px; border: 1px solid #d7dee7; border-radius: 8px; font-size: 13px; background: #fff; color: #1f2a36; }
.ct-entry-form .ct-date-in { flex: 0 0 150px; }
.ct-entry-form .ct-val-in { flex: 1; min-width: 80px; }
.ct-entries { list-style: none; margin: 0; padding: 0; }
.ct-entries li { display: flex; align-items: center; gap: 8px; padding: 4px 0; border-top: 1px solid #f0f2f5; font-size: 13px; }
.ct-del-entry { margin-left: auto; border: none; background: transparent; color: #b0b8c1; font-size: 16px; cursor: pointer; line-height: 1; padding: 2px 6px; border-radius: 6px; }
.ct-del-entry:hover { color: #e74c3c; background: #fdecea; }
.ct-rep-item { margin-bottom: 12px; }
.ct-rep-item h3 { font-size: 14px; margin: 0 0 6px; color: #1f2a36; }
html[data-theme="dark"] .ct-hint { color: #9fb0c3; }
html[data-theme="dark"] .ct-add input { background: #243140; color: var(--ink); border-color: #2c3a4c; }
html[data-theme="dark"] .ct-empty { background: #1a232e; border-color: #2c3a4c; color: #9fb0c3; }
html[data-theme="dark"] .ct-item { background: #161b22; border-color: #2c3a4c; }
html[data-theme="dark"] .ct-name { color: #e6edf3; }
html[data-theme="dark"] .ct-unit { color: #9fb0c3; background: #243140; }
html[data-theme="dark"] .ct-latest { color: #c4cdd8; }
html[data-theme="dark"] .ct-latest.muted { color: #8593a3; }
html[data-theme="dark"] .ct-count { color: #8593a3; }
html[data-theme="dark"] .ct-spark { background: #0f141b; }
html[data-theme="dark"] .ct-entry-form input { background: #243140; color: var(--ink); border-color: #2c3a4c; }
html[data-theme="dark"] .ct-entries li { border-top-color: #232c38; }
html[data-theme="dark"] .ct-rep-item h3 { color: #e6edf3; }
html[data-theme="dark"] .vitals-form { background: #1a232e; border-color: #2c3a4c; }
html[data-theme="dark"] .vitals-form input, html[data-theme="dark"] .vitals-form select { background: #243140; color: var(--ink); border-color: #2c3a4c; }
html[data-theme="dark"] .vitals-empty { background: #1a232e; border-color: #2c3a4c; color: #9fb0c3; }
html[data-theme="dark"] .vitals-card { background: #161b22; border-color: #2c3a4c; }
html[data-theme="dark"] .vc-latest { color: #c4cdd8; }
html[data-theme="dark"] .vitals-spark { background: #0f141b; }
/* 🆕 v504（项 9 回归修复）：8 个「日常测量」看板的空态隐藏。
   背景：v489 起各看板的空数据分支就写的是 `box.innerHTML = ''`，注释原文即「空态说明窗口隐藏」，
        也就是**意图就是隐藏**；但那 5 个看板当时有容器样式，空盒子仍会把「边框 + 左侧色条 + 内边距」画出来。
   v503（项 9）给 glucose/waist/bp 补上同构容器后，空壳从 5 个变成 8 个 —— MuMu 真机实测：
        无任何测量记录的患者，在「日常测量」卡片里会看到 8 个彩色圆角空壳（蓝/橙/品红/青/红/棕/深蓝/紫），
        里面一个字都没有，看着就是渲染坏了。
   修法：`:empty` 只在这些看板的 innerHTML 被置空时命中（`innerHTML=''` ⇒ 真无子节点，连空白都没有），
        即「置空 = 真隐藏」，与 v489 的注释意图一致；有数据时（innerHTML 有内容）**完全不受影响**。
   与全项目既有写法一致：`.bp-insight:empty` / `.med-monitor:empty` / `.med-edu:empty` / `.hw-badge:empty` / `.rn-redeem-err:empty` / `#reminder-list:empty` 都是这套。 */
#bmi-board:empty, #weight-board:empty, #temp-board:empty, #glucose-board:empty,
#spo2-board:empty, #hr-board:empty, #waist-board:empty, #bp-board:empty { display: none; }
html[data-theme="dark"] #bmi-board { background: #161b22; border-color: #2c3a4c; border-left-color: #5b8def; }
html[data-theme="dark"] .bmi-head { color: #e6edf3; }
html[data-theme="dark"] .bmi-value { color: #e6edf3; }
html[data-theme="dark"] .bmi-sub { color: #c4cdd8; }
html[data-theme="dark"] .bmi-hint, html[data-theme="dark"] .bmi-empty { background: #0f141b; border-color: #2c3a4c; color: #9aa7b4; }
html[data-theme="dark"] #weight-board { background: #161b22; border-color: #2c3a4c; border-left-color: #7a5cc9; }
html[data-theme="dark"] .wt-head { color: #e6edf3; }
html[data-theme="dark"] .wt-value { color: #e6edf3; }
html[data-theme="dark"] .wt-unit { color: #9aa7b4; }
html[data-theme="dark"] .wt-sub { color: #c4cdd8; }
html[data-theme="dark"] .wt-empty { background: #0f141b; border-color: #2c3a4c; color: #9aa7b4; }
html[data-theme="dark"] #temp-board { background: #161b22; border-color: #2c3a4c; border-left-color: #e67e22; }
html[data-theme="dark"] .tp-head { color: #e6edf3; }
html[data-theme="dark"] .tp-value { color: #e6edf3; }
html[data-theme="dark"] .tp-sub { color: #c4cdd8; }
html[data-theme="dark"] .tp-empty { background: #0f141b; border-color: #2c3a4c; color: #9aa7b4; }
html[data-theme="dark"] #glucose-board { background: #161b22; border-color: #2c3a4c; border-left-color: #d81b60; }
html[data-theme="dark"] .glu-head { color: #e6edf3; }
html[data-theme="dark"] .glu-value { color: #e6edf3; }
html[data-theme="dark"] .glu-sub { color: #c4cdd8; }
html[data-theme="dark"] .glu-empty { background: #0f141b; border-color: #2c3a4c; color: #9aa7b4; }
/* 🆕 v503（项 9）：腰围 / 血压看板的深色覆盖 —— 原先这两块整段缺失，
   深色模式下容器仍是 #fff 白底、与周围深色卡片割裂。 */
html[data-theme="dark"] #waist-board { background: #161b22; border-color: #2c3a4c; border-left-color: #795548; }
html[data-theme="dark"] .waist-head { color: #e6edf3; }
html[data-theme="dark"] .waist-value { color: #e6edf3; }
html[data-theme="dark"] .waist-sub { color: #c4cdd8; }
html[data-theme="dark"] #bp-board { background: #161b22; border-color: #2c3a4c; border-left-color: #0277bd; }
html[data-theme="dark"] .bp-board-head { color: #e6edf3; }
html[data-theme="dark"] .bp-board-sub { color: #c4cdd8; }
html[data-theme="dark"] #spo2-board { background: #161b22; border-color: #2c3a4c; border-left-color: #16a085; }
html[data-theme="dark"] .spo2-head { color: #e6edf3; }
html[data-theme="dark"] .spo2-value { color: #e6edf3; }
html[data-theme="dark"] .spo2-sub { color: #c4cdd8; }
html[data-theme="dark"] .spo2-empty { background: #0f141b; border-color: #2c3a4c; color: #9aa7b4; }
html[data-theme="dark"] #hr-board { background: #161b22; border-color: #2c3a4c; border-left-color: #e74c3c; }
html[data-theme="dark"] .hr-head { color: #e6edf3; }
html[data-theme="dark"] .hr-value { color: #e6edf3; }
html[data-theme="dark"] .hr-sub { color: #c4cdd8; }
html[data-theme="dark"] .hr-empty { background: #0f141b; border-color: #2c3a4c; color: #9aa7b4; }
html[data-theme="dark"] .vitals-rows li { border-top-color: #232c38; }

/* 🆕 v226：血压成对分级卡（按《中国高血压防治指南》诊室分级；不同级别取较高者）
   左侧竖条与 chip 底色随分级变化：正常绿 / 正常高值黄 / 1 级橙 / 2 级红 / 3 级深红 / 偏低蓝
   ⚠️ 🆕 v512（用户第 5 项）：本卡（#bp-insight）已整块下线（与 #bp-board 功能重复），
      下列 `.bp-insight` / `.bpi-*` 规则同步成为死样式，保留理由见上方 v512 段说明。 */
.bp-insight { border: 1px solid #e3e8ee; border-left: 4px solid #b0b8c1; border-radius: 10px; background: #fff; padding: 10px 12px; margin-bottom: 14px; }
.bp-insight:empty { display: none; }
.bp-insight-hint { color: #6b7785; font-size: 12.5px; line-height: 1.6; background: #f5f7fa; border-style: dashed; border-left-style: solid; }
.bpi-head { display: flex; align-items: center; gap: 8px; }
.bpi-title { font-weight: 600; font-size: 14px; }
.bpi-date { color: #8a96a3; font-size: 12px; margin-left: auto; }
.bpi-main { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin: 6px 0 4px; }
.bpi-val { font-size: 22px; font-weight: 700; letter-spacing: .5px; }
.bpi-val i { font-size: 12px; font-weight: 400; font-style: normal; color: #8a96a3; margin-left: 4px; }
.bpi-chip { font-size: 12px; font-weight: 700; border-radius: 6px; padding: 2px 9px; white-space: nowrap; border: 1px solid transparent; }
.bpi-chip-sub { font-weight: 600; opacity: .85; }
.bpi-stats { color: #44505f; font-size: 12.5px; line-height: 1.5; }
.bpi-avg { margin: 6px 0 2px; font-size: 12.5px; line-height: 1.5; color: #2d3742; }
.bpi-avg b { font-size: 14px; }
.bpi-ok { color: #1e7e45; font-weight: 700; }
.bpi-bad { color: #c0392b; font-weight: 700; }
.bpi-note { color: #8a96a3; font-size: 11.5px; line-height: 1.5; margin-top: 4px; }
.bp-insight.bp-normal { border-left-color: #27ae60; }
.bp-insight.bp-normal .bpi-chip { color: #1e7e45; background: #e6f6ec; border-color: #b6e3c6; }
.bp-insight.bp-hn { border-left-color: #e0a800; }
.bp-insight.bp-hn .bpi-chip { color: #8a6100; background: #fff6e0; border-color: #f0d799; }
.bp-insight.bp-g1 { border-left-color: #f0932b; }
.bp-insight.bp-g1 .bpi-chip { color: #9c4a00; background: #fff0e0; border-color: #f5cfa8; }
.bp-insight.bp-g2 { border-left-color: #e74c3c; }
.bp-insight.bp-g2 .bpi-chip { color: #b3261e; background: #fdecea; border-color: #f3c2bd; }
.bp-insight.bp-g3 { border-left-color: #a32217; }
.bp-insight.bp-g3 .bpi-chip { color: #fff; background: #b3261e; border-color: #8e1c15; }
.bp-insight.bp-low { border-left-color: #2980b9; }
.bp-insight.bp-low .bpi-chip { color: #1559b0; background: #e8f1fc; border-color: #bcd6f5; }
html[data-theme="dark"] .bp-insight { background: #161b22; border-color: #2c3a4c; }
html[data-theme="dark"] .bp-insight-hint { background: #1a232e; color: #9fb0c3; }
html[data-theme="dark"] .bpi-stats { color: #c4cdd8; }
html[data-theme="dark"] .bpi-avg { color: #d6dee8; }
html[data-theme="dark"] .bpi-ok { color: #7ee2a8; }
html[data-theme="dark"] .bpi-bad { color: #ff9d92; }
html[data-theme="dark"] .bpi-note, html[data-theme="dark"] .bpi-date, html[data-theme="dark"] .bpi-val i { color: #8b97a5; }
html[data-theme="dark"] .bp-insight.bp-normal .bpi-chip { color: #7ee2a8; background: rgba(39, 174, 96, .16); border-color: rgba(39, 174, 96, .45); }
html[data-theme="dark"] .bp-insight.bp-hn .bpi-chip { color: #ffd979; background: rgba(224, 168, 0, .16); border-color: rgba(224, 168, 0, .45); }
html[data-theme="dark"] .bp-insight.bp-g1 .bpi-chip { color: #ffbe7a; background: rgba(240, 147, 43, .16); border-color: rgba(240, 147, 43, .45); }
html[data-theme="dark"] .bp-insight.bp-g2 .bpi-chip { color: #ff9d92; background: rgba(231, 76, 60, .16); border-color: rgba(231, 76, 60, .45); }
html[data-theme="dark"] .bp-insight.bp-g3 .bpi-chip { color: #fff; background: #a32217; border-color: #7d1a11; }
html[data-theme="dark"] .bp-insight.bp-low .bpi-chip { color: #8dc0f5; background: rgba(41, 128, 185, .16); border-color: rgba(41, 128, 185, .45); }
/* 🆕 自动优化 v479：血压看板暗色主题（对齐 bp-insight 暗色色板） */
html[data-theme="dark"] .bp-board-value { color: #e7eef6; }
html[data-theme="dark"] .bp-board-chip.bp-normal { color: #7ee2a8; background: rgba(39, 174, 96, .16); border-color: rgba(39, 174, 96, .45); }
html[data-theme="dark"] .bp-board-chip.bp-hn { color: #ffd979; background: rgba(224, 168, 0, .16); border-color: rgba(224, 168, 0, .45); }
html[data-theme="dark"] .bp-board-chip.bp-g1 { color: #ffbe7a; background: rgba(240, 147, 43, .16); border-color: rgba(240, 147, 43, .45); }
html[data-theme="dark"] .bp-board-chip.bp-g2 { color: #ff9d92; background: rgba(231, 76, 60, .16); border-color: rgba(231, 76, 60, .45); }
html[data-theme="dark"] .bp-board-chip.bp-g3 { color: #fff; background: #a32217; border-color: #7d1a11; }
html[data-theme="dark"] .bp-board-chip.bp-low { color: #8dc0f5; background: rgba(41, 128, 185, .16); border-color: rgba(41, 128, 185, .45); }
html[data-theme="dark"] .bp-board-flag-ok { color: #7ee2a8; background: rgba(39, 174, 96, .16); border-color: rgba(39, 174, 96, .45); }
html[data-theme="dark"] .bp-board-flag-warn { color: #fff; background: #b3670e; border-color: #8a5008; }
html[data-theme="dark"] .bp-board-flag-caution { color: #ffd979; background: rgba(224, 168, 0, .16); border-color: rgba(224, 168, 0, .45); }
html[data-theme="dark"] .bp-board-empty { background: #1a232e; border-color: #2c3a4c; color: #9fb0c3; }

/* 🆕 治疗目标达标看板（对标 MyChart 2026 治疗目标 / CareClinic 目标追踪；纯只读派生） */
.goal-board { display: none; margin-top: 8px; padding: 10px 14px; border: 1px solid #d6e4ea; border-radius: 10px; background: #f3fafc; font-size: 13px; }
.goal-board .gb-head { font-weight: 700; color: #0e7c86; margin-bottom: 6px; }
.goal-board .gb-row { display: grid; grid-template-columns: 1.4fr 1fr 1.7fr; grid-template-areas: "name now tgt" "bar bar rate"; align-items: center; gap: 2px 8px; padding: 5px 0; border-top: 1px dashed #dce6ea; }
.goal-board .gb-row:first-of-type { border-top: none; }
.goal-board .gb-name { grid-area: name; font-weight: 600; }
.goal-board .gb-now { grid-area: now; font-weight: 700; }
.goal-board .gb-tgt { grid-area: tgt; color: #6b7785; font-size: 12px; }
.goal-board .gb-bar { grid-area: bar; height: 6px; border-radius: 4px; background: #e3ebef; overflow: hidden; margin-top: 3px; }
.goal-board .gb-fill { display: block; height: 100%; border-radius: 4px; }
.goal-board .gb-fill.gb-ok { background: #2e9e57; }
.goal-board .gb-fill.gb-bad { background: #d9534f; }
.goal-board .gb-rate { grid-area: rate; font-size: 12px; font-weight: 600; text-align: right; }
.goal-board .gb-ok { color: #1e8e4e; }
.goal-board .gb-bad { color: #c0392b; }
.goal-board .gb-note { margin-top: 6px; font-size: 11px; color: #8593a3; line-height: 1.5; }
html[data-theme="dark"] .goal-board { background: #14202b; border-color: #2a3744; color: #c7d0db; }
html[data-theme="dark"] .goal-board .gb-head { color: #5fd0db; }
html[data-theme="dark"] .goal-board .gb-tgt { color: #9aa6b2; }
html[data-theme="dark"] .goal-board .gb-row { border-top-color: #2a3744; }
html[data-theme="dark"] .goal-board .gb-bar { background: #243240; }
html[data-theme="dark"] .goal-board .gb-note { color: #8593a3; }
html[data-theme="dark"] .goal-board .gb-ok { color: #7fd18a; }
html[data-theme="dark"] .goal-board .gb-bad { color: #f0a39c; }

/* 🆕 个人基线（对标 Guava 2026「what's normal for YOU」）—— 只读派生，不写任何用户数据 */
.ind-analysis { display: none; margin-top: 8px; padding: 10px 14px; border: 1px solid #d6e4ea; border-radius: 10px; background: #f6f4fb; font-size: 13px; }
.ind-trend { display: none; margin-top: 8px; padding: 10px 14px; border: 1px solid #e0dcef; border-radius: 10px; background: #f3f1fb; font-size: 13px; }
/* 🆕 v351：修掉一处**类名冲突**导致的手机端整页横向溢出（实测 390px 下文档被撑到 506px）。
   冲突双方：
     · 第 540 行 `.ind-trend` 是「趋势方向**小徽标**」的规则，带 `white-space: nowrap`；
     · 本行 `.ind-trend` 是「趋势方向洞察**卡片**」的规则。
   而卡片 DOM 是 `<div id="ind-trend" class="ind-trend">`，**同时命中这两条**。
   两条同权重 (0,1,0)、本行在后，多数属性被本行覆盖，但**本行没有重置 white-space**
   ⇒ 卡片继承了徽标的 `nowrap` ⇒ 卡片内 `.it-sub` 那行「近 N 次（日期→日期）：从 X 到 Y · …」
   无法换行（实测 scrollWidth 479 vs clientWidth 340）⇒ 整个文档横向可滚 116px。
   ⚠️ 修法**必须用 id 选择器**，不能在上一行加 `white-space: normal`：
     那两条同权重、后者覆盖前者，会把徽标的 nowrap 一起干掉（徽标文案会被折行）。
     id 权重 (1,0,0) 只作用于卡片；徽标元素自身的 `white-space: nowrap` 声明
     也会压过「从卡片继承来的 normal」，双向都不受影响。
   受控验证：_probe_v351_indtrend_wrap.js（390/360 均回落视口宽、1280 桌面无变化、日夜一致）；
             _probe_v351_badge_guard.js（徽标渲染不受影响）。 */
#ind-trend { white-space: normal; }
.ind-trend .it-head { font-weight: 700; color: #6c4bb6; margin-bottom: 6px; }
.ind-trend .it-row { display: flex; align-items: center; gap: 8px; padding: 4px 0 2px; flex-wrap: wrap; }
.ind-trend .it-name { font-weight: 600; color: #1f2d3d; }
.ind-trend .it-dir { font-weight: 700; padding: 1px 8px; border-radius: 10px; font-size: 12px; }
.ind-trend .it-up { color: #c0392b; background: #fbe3e1; }
.ind-trend .it-down { color: #1b6b8f; background: #e2f1f7; }
.ind-trend .it-flat { color: #6b7785; background: #eceff2; }
.ind-trend .it-chg { color: #4a3a7a; font-weight: 600; }
.ind-trend .it-sub { color: #5a6573; font-size: 12.5px; line-height: 1.5; }
.ind-trend .it-note { margin-top: 6px; font-size: 11px; color: #8593a3; line-height: 1.5; }
.personal-baseline { display: none; margin-top: 8px; padding: 10px 14px; border: 1px solid #d6e4ea; border-radius: 10px; background: #f6f4fb; font-size: 13px; }
:is(.personal-baseline, .ind-analysis) .pb-head { font-weight: 700; color: #6c4bb6; margin-bottom: 6px; }
:is(.personal-baseline, .ind-analysis) .pb-row { padding: 5px 0; border-top: 1px dashed #e2dcf0; }
:is(.personal-baseline, .ind-analysis) .pb-row:first-of-type { border-top: none; }
:is(.personal-baseline, .ind-analysis) .pb-name { font-weight: 600; color: #1f2d3d; }
:is(.personal-baseline, .ind-analysis) .pb-base { color: #5a6573; font-size: 12.5px; }
:is(.personal-baseline, .ind-analysis) .pb-base b { color: #4a3a7a; }
:is(.personal-baseline, .ind-analysis) .pb-now { margin: 2px 0; }
:is(.personal-baseline, .ind-analysis) .pb-chip { display: inline-block; padding: 1px 8px; border-radius: 10px; font-size: 12px; font-weight: 600; }
:is(.personal-baseline, .ind-analysis) .pb-ok { color: #1e8e4e; }
:is(.personal-baseline, .ind-analysis) .pb-ok.pb-chip { background: #e3f6ea; }
:is(.personal-baseline, .ind-analysis) .pb-bad { color: #c0392b; }
:is(.personal-baseline, .ind-analysis) .pb-bad.pb-chip { background: #fbe3e1; }
:is(.personal-baseline, .ind-analysis) .pb-stab { color: #6b7785; font-size: 12px; }
:is(.personal-baseline, .ind-analysis) .pb-vari { color: #6b7785; font-size: 12px; margin-top: 1px; }
:is(.personal-baseline, .ind-analysis) .pb-vari b { color: #4a3a7a; }
.personal-baseline .pb-ref { color: #7a6aa8; font-size: 12px; margin-top: 1px; }
:is(.personal-baseline, .ind-analysis) .pb-note { margin-top: 6px; font-size: 11px; color: #8593a3; line-height: 1.5; }
/* 🆕 v518（用户第 3 项）：指标分析「数值统计」分段条 —— 与指标库五段计数条同款分段外观，
   但为**只读 span**（无 data-ind-abn、不可点）。配色语义沿用计数条：正常绿 / 偏高红 / 偏低蓝 / 达标率青。 */
:is(.personal-baseline, .ind-analysis) .pb-stat {
  display: inline-flex; flex-wrap: wrap; align-items: center; gap: 3px 6px;
  margin-top: 4px;
}
:is(.personal-baseline, .ind-analysis) .pb-seg {
  display: inline-flex; align-items: center; gap: 3px;
  padding: 1px 8px; border-radius: 999px;
  font-size: 11.5px; line-height: 1.6; white-space: nowrap;
  border: 1px solid transparent;
}
:is(.personal-baseline, .ind-analysis) .pb-seg b { font-size: 12px; font-weight: 700; }
:is(.personal-baseline, .ind-analysis) .pb-seg-ok { color: #2e7d32; background: #eef7ee; }
:is(.personal-baseline, .ind-analysis) .pb-seg-hi { color: #c0392b; background: #fdecea; }
:is(.personal-baseline, .ind-analysis) .pb-seg-lo { color: #1b6b8f; background: #e8f2f8; }
:is(.personal-baseline, .ind-analysis) .pb-seg-rate { color: #0e7c86; background: #dceff0; }
html[data-theme="dark"] :is(.personal-baseline, .ind-analysis) .pb-seg-ok { color: #4ec98b; background: #143226; }
html[data-theme="dark"] :is(.personal-baseline, .ind-analysis) .pb-seg-hi { color: #ef7d72; background: #3a2220; }
html[data-theme="dark"] :is(.personal-baseline, .ind-analysis) .pb-seg-lo { color: #7cc4e6; background: #15202a; }
html[data-theme="dark"] :is(.personal-baseline, .ind-analysis) .pb-seg-rate { color: #3fc1cb; background: #16282a; }
/* 🆕 v367（用户第 3 条）：「指标分析」行内的「升高 / 降低 · 常见原因」。
   内容来自本地词库的 def.high / def.low（原来只藏在「?」释义弹窗的「临床意义」段），
   只在最新值**超出参考范围**时按方向显示一条；正常值不显示（见 js/app.js renderIndAnalysis 的 causeRow 注释）。
   配色沿用全软件语义：偏高=琥珀、偏低=蓝（不引入新色，避免与「指标趋势」折线色打架）。 */
:is(.personal-baseline, .ind-analysis) .pb-cause { margin-top: 3px; padding: 4px 8px; border-radius: 8px; font-size: 12px; line-height: 1.55; color: #5a4a3a; background: #fdf6ec; border-left: 3px solid #e8a33d; }
:is(.personal-baseline, .ind-analysis) .pb-cause b { display: block; font-size: 11.5px; color: #a06818; margin-bottom: 1px; font-weight: 700; }
:is(.personal-baseline, .ind-analysis) .pb-cause-lo { background: #eef4fd; border-left-color: #5b8def; color: #3a4a5a; }
:is(.personal-baseline, .ind-analysis) .pb-cause-lo b { color: #2d5fa8; }
html[data-theme="dark"] .ind-analysis { background: #1b1726; border-color: #2e2740; color: #c7d0db; }
html[data-theme="dark"] .ind-trend { background: #1b1726; border-color: #2e2740; color: #c7d0db; }
html[data-theme="dark"] .ind-trend .it-head { color: #b79be8; }
html[data-theme="dark"] .ind-trend .it-name { color: #e6edf3; }
html[data-theme="dark"] .ind-trend .it-chg { color: #c9b6f0; }
html[data-theme="dark"] .ind-trend .it-up { color: #ef7d72; background: #3a2220; }
html[data-theme="dark"] .ind-trend .it-down { color: #7cc4e6; background: #15202a; }
html[data-theme="dark"] .ind-trend .it-flat { color: #9aa6b2; background: #2a2a33; }
html[data-theme="dark"] .ind-trend .it-sub { color: #9aa6b2; }
html[data-theme="dark"] .ind-trend .it-note { color: #8593a3; }
html[data-theme="dark"] .personal-baseline { background: #1b1726; border-color: #2e2740; color: #c7d0db; }
html[data-theme="dark"] :is(.personal-baseline, .ind-analysis) .pb-head { color: #b79be8; }
html[data-theme="dark"] :is(.personal-baseline, .ind-analysis) .pb-name { color: #e6edf3; }
html[data-theme="dark"] :is(.personal-baseline, .ind-analysis) .pb-base { color: #9aa6b2; }
html[data-theme="dark"] :is(.personal-baseline, .ind-analysis) .pb-base b { color: #c9b6f0; }
html[data-theme="dark"] :is(.personal-baseline, .ind-analysis) .pb-row { border-top-color: #2e2740; }
html[data-theme="dark"] :is(.personal-baseline, .ind-analysis) .pb-stab { color: #9aa6b2; }
html[data-theme="dark"] :is(.personal-baseline, .ind-analysis) .pb-vari { color: #9aa6b2; }
html[data-theme="dark"] :is(.personal-baseline, .ind-analysis) .pb-vari b { color: #c9b6f0; }
html[data-theme="dark"] .personal-baseline .pb-ref { color: #b79be8; }
html[data-theme="dark"] :is(.personal-baseline, .ind-analysis) .pb-note { color: #8593a3; }
/* 🆕 v367：夜间模式下的 .pb-cause（用户在夜间模式下看的截图，暗色必须一并给，别只给日间） */
html[data-theme="dark"] :is(.personal-baseline, .ind-analysis) .pb-cause { background: #2a2418; border-left-color: #d09442; color: #d8cdbd; }
html[data-theme="dark"] :is(.personal-baseline, .ind-analysis) .pb-cause b { color: #e8b45f; }
html[data-theme="dark"] :is(.personal-baseline, .ind-analysis) .pb-cause-lo { background: #1b2536; border-left-color: #4a7fd4; color: #c2cddb; }
html[data-theme="dark"] :is(.personal-baseline, .ind-analysis) .pb-cause-lo b { color: #7fb0ef; }
html[data-theme="dark"] :is(.personal-baseline, .ind-analysis) .pb-ok { background: #1f3a2a; }
html[data-theme="dark"] :is(.personal-baseline, .ind-analysis) .pb-bad { background: #3a2220; }

/* 🆕 指标达标率（Time in Range，对标 MyChart / Glooko / mySugr 2026） */
.time-in-range { background: #f4f1fb; border: 1px solid #e2dcf0; border-radius: 10px; padding: 10px 12px; margin: 8px 0; }
:is(.time-in-range, .ind-analysis) .tir-head { font-weight: 700; color: #6c4bb6; margin-bottom: 6px; }
:is(.time-in-range, .ind-analysis) .tir-row { padding: 6px 0; border-top: 1px dashed #e2dcf0; }
:is(.time-in-range, .ind-analysis) .tir-row:first-of-type { border-top: none; }
:is(.time-in-range, .ind-analysis) .tir-name { font-weight: 600; color: #1f2d3d; font-size: 13px; }
:is(.time-in-range, .ind-analysis) .tir-rate { font-weight: 700; }
:is(.time-in-range, .ind-analysis) .tir-rate.tir-ok { color: #1e8e4e; }
:is(.time-in-range, .ind-analysis) .tir-rate.tir-bad { color: #c0392b; }
:is(.time-in-range, .ind-analysis) .tir-bar { display: flex; height: 10px; border-radius: 6px; overflow: hidden; margin: 4px 0 3px; background: #eee; }
:is(.time-in-range, .ind-analysis) .tir-seg { display: block; height: 100%; }
:is(.time-in-range, .ind-analysis) .tir-seg.tir-in { background: #2e9e5b; }
:is(.time-in-range, .ind-analysis) .tir-seg.tir-hi { background: #d9534f; }
:is(.time-in-range, .ind-analysis) .tir-seg.tir-lo { background: #3d8bcd; }
:is(.time-in-range, .ind-analysis) .tir-detail { color: #6b7785; font-size: 12px; }
:is(.time-in-range, .ind-analysis) .tir-note { margin-top: 6px; font-size: 11px; color: #8593a3; line-height: 1.5; }
html[data-theme="dark"] .time-in-range { background: #1b1726; border-color: #2e2740; color: #c7d0db; }
html[data-theme="dark"] :is(.time-in-range, .ind-analysis) .tir-head { color: #b79be8; }
html[data-theme="dark"] :is(.time-in-range, .ind-analysis) .tir-name { color: #e6edf3; }
html[data-theme="dark"] :is(.time-in-range, .ind-analysis) .tir-row { border-top-color: #2e2740; }
html[data-theme="dark"] :is(.time-in-range, .ind-analysis) .tir-rate.tir-ok { color: #5fd089; }
html[data-theme="dark"] :is(.time-in-range, .ind-analysis) .tir-rate.tir-bad { color: #ef7d72; }
html[data-theme="dark"] :is(.time-in-range, .ind-analysis) .tir-detail { color: #9aa6b2; }
html[data-theme="dark"] :is(.time-in-range, .ind-analysis) .tir-bar { background: #2a2a33; }
html[data-theme="dark"] :is(.time-in-range, .ind-analysis) .tir-note { color: #8593a3; }

/* 🆕 v276 指标科普卡（对标 MyChart 2026「About This Test / Understand Your Results」） */
.lab-edu { display: none; margin-top: 8px; padding: 10px 14px; border: 1px solid #cfe3ea; border-radius: 10px; background: #f3f9fb; font-size: 13px; }
.lab-edu .le-head { font-weight: 700; color: #1f7a8c; margin-bottom: 6px; }
.lab-edu .le-row { display: flex; gap: 8px; padding: 5px 0; border-top: 1px dashed #dce9ee; }
.lab-edu .le-row:first-of-type { border-top: none; }
.lab-edu .le-k { flex: 0 0 64px; font-weight: 600; color: #1f2d3d; }
.lab-edu .le-v { color: #5a6573; line-height: 1.55; }
.lab-edu .le-hi { color: #c0392b; }
.lab-edu .le-lo { color: #1e6fb0; }
.lab-edu .le-note { margin-top: 6px; font-size: 11px; color: #8593a3; line-height: 1.5; }
html[data-theme="dark"] .lab-edu { background: #16222a; border-color: #24414d; color: #c7d0db; }
html[data-theme="dark"] .lab-edu .le-head { color: #6fd0e6; }
html[data-theme="dark"] .lab-edu .le-k { color: #e6edf3; }
html[data-theme="dark"] .lab-edu .le-v { color: #9aa6b2; }
html[data-theme="dark"] .lab-edu .le-hi { color: #ef8a7d; }
html[data-theme="dark"] .lab-edu .le-lo { color: #7fb8e6; }
html[data-theme="dark"] .lab-edu .le-row { border-top-color: #24414d; }
html[data-theme="dark"] .lab-edu .le-note { color: #8593a3; }
/* 🆕 v443：最近检验通俗解读卡 */
.lab-plain .lp-row { padding: 8px 0 8px 10px; border-top: 1px dashed #dce9ee; border-left: 3px solid transparent; }
.lab-plain .lp-row:first-of-type { border-top: none; }
.lab-plain .lp-top { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.lab-plain .lp-name { font-weight: 700; color: #1f2d3d; }
.lab-plain .lp-val { color: #5a6573; }
.lab-plain .lp-tag { font-size: 11px; font-weight: 700; padding: 1px 7px; border-radius: 10px; }
.lab-plain .lp-hi { border-left-color: #c0392b; }
.lab-plain .lp-hi .lp-tag { color: #fff; background: #c0392b; }
.lab-plain .lp-lo { border-left-color: #1e6fb0; }
.lab-plain .lp-lo .lp-tag { color: #fff; background: #1e6fb0; }
.lab-plain .lp-ok .lp-tag { color: #2e7d32; background: #e3f1e4; }
.lab-plain .lp-meaning { color: #5a6573; line-height: 1.55; margin-top: 3px; }
.lab-plain .lp-note { margin-top: 8px; font-size: 11px; color: #8593a3; line-height: 1.5; }
html[data-theme="dark"] .lab-plain .lp-row { border-top-color: #24414d; }
html[data-theme="dark"] .lab-plain .lp-name { color: #e6edf3; }
html[data-theme="dark"] .lab-plain .lp-val, html[data-theme="dark"] .lab-plain .lp-meaning { color: #9aa6b2; }
html[data-theme="dark"] .lab-plain .lp-hi { border-left-color: #ef8a7d; }
html[data-theme="dark"] .lab-plain .lp-lo { border-left-color: #7fb8e6; }
html[data-theme="dark"] .lab-plain .lp-ok .lp-tag { color: #8fd99a; background: #1d3326; }
html[data-theme="dark"] .lab-plain .lp-note { color: #8593a3; }

/* 🆕 指标联动洞察（对标 Guava 2026「Insights：变量之间的相关性」/ Bearable correlation）—— 只读派生，不写任何用户数据 */
.ind-correlation { display: none; margin-top: 8px; padding: 10px 14px; border: 1px solid #d6e4ea; border-radius: 10px; background: #f2f8fb; font-size: 13px; }
.ind-correlation .ic-head { font-weight: 700; color: #1b6b8f; margin-bottom: 6px; }
.ind-correlation .ic-row { padding: 5px 0; border-top: 1px dashed #d8e6ee; }
.ind-correlation .ic-row:first-of-type { border-top: none; }
/* 🆕 v513（用户第 8 项）：「指标联动洞察的每一行要可以点击，跳转至趋势图中显示选择的两个指标。」
   ⚠️ 只有 `#ind-correlation`（指标联动洞察）里那 5 行带 `.ic-row-go` 类 ——
      指标-体征 / 症状-指标 / 症状-体征 / 睡眠-症状 四处用的仍是 `.ic-row`，外观与只读行为**完全不变**。
   负 margin 让 hover 底色铺满卡片内宽（而不是只包住文字），点击热区更大、更像一个可点条目。 */
.ind-correlation .ic-row-go {
  cursor: pointer; border-radius: 8px; padding-left: 8px; padding-right: 8px; margin: 0 -8px;
  transition: background .15s;
}
.ind-correlation .ic-row-go:hover { background: rgba(14, 124, 134, .07); }
.ind-correlation .ic-row-go:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
html[data-theme="dark"] .ind-correlation .ic-row-go:hover { background: rgba(127, 221, 228, .10); }
.ind-correlation .ic-pair { font-weight: 600; color: #1f2d3d; }
.ind-correlation .ic-bar { height: 6px; border-radius: 4px; background: #e2ebf1; overflow: hidden; margin: 3px 0; max-width: 420px; }
.ind-correlation .ic-bar i { display: block; height: 100%; border-radius: 4px; }
.ind-correlation .ic-chip { display: inline-block; padding: 1px 8px; border-radius: 10px; font-size: 12px; font-weight: 600; }
.ind-correlation .ic-pos { color: #1b6b8f; background: #dceef7; }
.ind-correlation .ic-neg { color: #a35a10; background: #fbeedd; }
.ind-correlation .ic-flat { color: #6b7785; background: #eef2f6; }
.ind-correlation .ic-n { color: #6b7785; font-size: 12px; margin-left: 4px; }
.ind-correlation .ic-skip { margin-top: 5px; font-size: 12px; color: #7a8794; }
.ind-correlation .ic-note { margin-top: 6px; font-size: 11px; color: #8593a3; line-height: 1.5; }

/* 🆕 v513（用户第 9 项）：「🩺 综合健康时间轴」整卡下线 ⇒ 本段样式退役。
   原来这里有 7 条规则：.health-timeline（容器）/ .ht-head / .ht-legend / .ht-legend i /
   .health-timeline svg / .ht-caption / .dark .health-timeline —— 全部删除。
   另有第二处（后段「字体与其他窗口统一」3+1 条）与第三处（「卡头 ＋」4 条）也一并退役。 */

/* 🆕 v252 缓慢漂移预警（「正常范围内却持续向异常侧漂移」） */
.creep-watch { display: none; margin-top: 8px; padding: 10px 14px; border: 1px solid #f0d9b5; border-radius: 10px; background: #fff8ee; font-size: 13px; }
.creep-watch .cw-head { font-weight: 700; color: #9a6b1f; margin-bottom: 6px; }
.creep-watch .cw-item { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; padding: 6px 0; border-top: 1px dashed #ecd9b0; }
.creep-watch .cw-item:first-of-type { border-top: none; }
.creep-watch .cw-dot { display: inline-block; width: 10px; height: 10px; border-radius: 50%; }
.creep-watch .cw-name { font-weight: 600; color: #34495e; }
.creep-watch .cw-bar { position: relative; display: inline-block; width: 90px; height: 8px; background: #e8eef3; border-radius: 4px; overflow: hidden; vertical-align: middle; }
.creep-watch .cw-fill { position: absolute; left: 0; top: 0; height: 100%; border-radius: 4px; }
.creep-watch .cw-fill.cw-high { background: linear-gradient(90deg,#f6c453,#e74c3c); }
.creep-watch .cw-fill.cw-low { background: linear-gradient(90deg,#5dade2,#2e86c1); }
.creep-watch .cw-pos { color: #7a6a4f; font-size: 12px; }
.creep-watch .cw-side { font-weight: 700; }
.creep-watch .cw-up { color: #e67e22; }
.creep-watch .cw-down { color: #2e86c1; }
.creep-watch .cw-meta { flex-basis: 100%; color: #8593a3; font-size: 12px; }
.creep-watch .cw-cap { margin: 8px 0 0; font-size: 11px; color: #9a8a6f; line-height: 1.5; }
.dark .creep-watch { background: #2a2418; border-color: #6b5a2f; }
.dark .creep-watch .cw-head { color: #f0c674; }
.dark .creep-watch .cw-name { color: #e6edf3; }
.dark .creep-watch .cw-pos { color: #c9bd9f; }
.dark .creep-watch .cw-meta { color: #9aa6b2; }
.dark .creep-watch .cw-cap { color: #b3a784; }
.dark .creep-watch .cw-bar { background: #3a3a3a; }
html[data-theme="dark"] .ind-correlation { background: #15202a; border-color: #27343f; color: #c7d0db; }
html[data-theme="dark"] .ind-correlation .ic-head { color: #7cc4e6; }
html[data-theme="dark"] .ind-correlation .ic-row { border-top-color: #27343f; }
html[data-theme="dark"] .ind-correlation .ic-pair { color: #e6edf3; }
html[data-theme="dark"] .ind-correlation .ic-bar { background: #22303a; }
html[data-theme="dark"] .ind-correlation .ic-pos { color: #8fd0ee; background: #12303d; }
html[data-theme="dark"] .ind-correlation .ic-neg { color: #f0bd7f; background: #3a2c16; }
html[data-theme="dark"] .ind-correlation .ic-flat { color: #9aa6b2; background: #232b33; }
html[data-theme="dark"] .ind-correlation .ic-n,
html[data-theme="dark"] .ind-correlation .ic-skip { color: #9aa6b2; }
html[data-theme="dark"] .ind-correlation .ic-note { color: #8593a3; }

/* 🆕 就诊与复查预约（对标 MyChart 2026「Today's Visits」与 CareClinic 就诊管理） */
.appt-list { margin-top: 10px; display: flex; flex-direction: column; gap: 8px; }
.appt-empty { color: #8593a3; font-size: 13px; margin: 4px 0; }
.appt-item { display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 10px 12px; border: 1px solid #e2e8f0; border-radius: 10px; background: #f7fafc; }
.appt-item.up { border-left: 4px solid #0e7c86; background: #e8f6f7; }
.appt-item .appt-main { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; font-size: 14px; }
.appt-date { font-weight: 600; color: #1f2d3d; }
.appt-badge { font-size: 12px; font-weight: 700; padding: 1px 8px; border-radius: 10px; }
.appt-badge.up { color: #0a5f67; background: #c7ebee; }
.appt-badge.past { color: #8593a3; background: #eef2f6; }
.appt-title { color: #1f2d3d; }
.appt-meta { color: #6b7a8d; font-size: 12px; }
.appt-del { border: none; background: transparent; color: #c0392b; font-size: 18px; cursor: pointer; line-height: 1; padding: 0 6px; }
.appt-del:hover { color: #a93226; }
.ho-muted { opacity: .72; }
html[data-theme="dark"] .appt-item { background: #1b2128; border-color: #2c3742; }
html[data-theme="dark"] .appt-item.up { background: #10242a; border-left-color: #1aa3b0; }
html[data-theme="dark"] .appt-date, html[data-theme="dark"] .appt-title { color: #e6edf3; }
html[data-theme="dark"] .appt-meta { color: #9aa6b2; }
html[data-theme="dark"] .appt-empty { color: #8593a3; }
/* 🆕 v421：就诊与复查「导出日历(.ics)」操作条 */
.appt-export-bar { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; margin-top: 12px; padding-top: 12px; border-top: 1px dashed var(--line); }
.appt-export-bar .hint.inline { margin: 0; font-size: 12px; color: var(--muted); }
html[data-theme="dark"] .appt-export-bar { border-top-color: #2c3742; }

/* 🆕 v256：变更记录（审计轨迹）——复用 --ink/--muted/--line 变量，明暗主题自动适配 */
.change-history { list-style: none; margin: 6px 0 0; padding: 0; max-height: 340px; overflow-y: auto; }
.change-history .ch-empty { color: var(--muted); font-size: 13px; margin: 4px 0; }
.ch-item { display: flex; align-items: baseline; gap: 8px; padding: 7px 4px; border-bottom: 1px dashed var(--line); font-size: 13px; }
.ch-item:last-child { border-bottom: none; }
.ch-ic { flex: 0 0 auto; }
.ch-text { flex: 1 1 auto; color: var(--ink); word-break: break-word; }
.ch-ts { flex: 0 0 auto; color: var(--muted); font-variant-numeric: tabular-nums; font-size: 12px; white-space: nowrap; }

/* 🆕 v249 用药相关检验复查提醒（对标 LTRL 2026「see it's due for retest」/ Function Health 复测节律 / MedM 测量提醒） */
.med-monitor { margin: 14px 0; padding: 12px 14px; border: 1px solid #dbe6ea; border-left: 4px solid #0e7c86;
  border-radius: 12px; background: #f4fafb; font-size: 13px; }
.med-monitor:empty { display: none; }
.med-monitor .mm-head { font-weight: 700; color: #0e7c86; margin-bottom: 8px; }
.med-monitor .mm-t-due { color: #c0392b; }
.med-monitor .mm-t-none { color: #9c6b00; }
.med-monitor .mm-t-ok { color: #1e8e4e; }
.med-monitor .mm-row { padding: 7px 0; border-top: 1px dashed #dce6ea; }
.med-monitor .mm-row:first-of-type { border-top: none; }
.med-monitor .mm-med { font-weight: 600; color: #1f2d3d; }
.med-monitor .mm-lab { color: #43596e; margin-top: 1px; }
.med-monitor .mm-every { color: #8593a3; font-size: 12px; }
.med-monitor .mm-state { margin-top: 4px; }
.med-monitor .mm-chip { display: inline-block; font-size: 12px; font-weight: 600; padding: 2px 8px;
  border-radius: 10px; border: 1px solid transparent; }
.med-monitor .mm-c-due .mm-chip { color: #b3261e; background: #fdecea; border-color: #f3c2bd; }
.med-monitor .mm-c-none .mm-chip { color: #8a6100; background: #fff6e0; border-color: #f0d799; }
.med-monitor .mm-c-ok .mm-chip { color: #1e7e45; background: #e6f6ec; border-color: #b6e3c6; }
.med-monitor .mm-why { margin-top: 3px; font-size: 12px; color: #6b7785; line-height: 1.55; }
.med-monitor .mm-note { margin-top: 8px; font-size: 11px; color: #8593a3; line-height: 1.5; }
html[data-theme="dark"] .med-monitor { background: #14202b; border-color: #2a3744; border-left-color: #1aa3b0; color: #c7d0db; }
html[data-theme="dark"] .med-monitor .mm-head { color: #5fd0db; }
html[data-theme="dark"] .med-monitor .mm-row { border-top-color: #2a3744; }
html[data-theme="dark"] .med-monitor .mm-med { color: #e6edf3; }
html[data-theme="dark"] .med-monitor .mm-lab { color: #b8c4d0; }
html[data-theme="dark"] .med-monitor .mm-why, html[data-theme="dark"] .med-monitor .mm-note,
html[data-theme="dark"] .med-monitor .mm-every { color: #8fa0b3; }
html[data-theme="dark"] .med-monitor .mm-t-due { color: #f0a39c; }
html[data-theme="dark"] .med-monitor .mm-t-none { color: #e3c07a; }
html[data-theme="dark"] .med-monitor .mm-t-ok { color: #7fd18a; }
html[data-theme="dark"] .med-monitor .mm-c-due .mm-chip { color: #ffb4ab; background: #3a1b18; border-color: #5c2a24; }
html[data-theme="dark"] .med-monitor .mm-c-none .mm-chip { color: #f0cd8a; background: #33290f; border-color: #56451c; }
html[data-theme="dark"] .med-monitor .mm-c-ok .mm-chip { color: #9be0ab; background: #142a1c; border-color: #244630; }

/* 🆕 v254：用药须知 / 用药患者教育卡（对标 2026 竞品「educational content / 用药信息」） */
.med-edu { margin: 14px 0; padding: 12px 14px; border: 1px solid #dbe6ea; border-left: 4px solid #2b8a9e; }
.med-edu:empty { display: none; }
.med-edu .me-head { font-weight: 700; color: #0e7c86; margin-bottom: 8px; }
.med-edu .me-item { padding: 8px 0; border-top: 1px dashed #dce6ea; }
.med-edu .me-item:first-of-type { border-top: none; }
.med-edu .me-med { font-weight: 600; color: #1f2d3d; margin-bottom: 4px; }
.med-edu .me-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 4px 14px; }
.med-edu .me-cell { font-size: 13px; color: #43596e; line-height: 1.5; }
.med-edu .me-k { display: inline-block; min-width: 34px; margin-right: 6px; padding: 0 6px; font-size: 11px; font-weight: 700; color: #2b8a9e; background: #e7f3f5; border-radius: 6px; }
.med-edu .me-note { margin-top: 8px; font-size: 11px; color: #8593a3; line-height: 1.5; }
@media (max-width: 520px) { .med-edu .me-grid { grid-template-columns: 1fr; } }
html[data-theme="dark"] .med-edu { background: #14202b; border-color: #2a3744; border-left-color: #1aa3b0; color: #c7d0db; }
html[data-theme="dark"] .med-edu .me-head { color: #5fd0db; }
html[data-theme="dark"] .med-edu .me-item { border-top-color: #2a3744; }
html[data-theme="dark"] .med-edu .me-med { color: #e6edf3; }
html[data-theme="dark"] .med-edu .me-cell { color: #b8c4d0; }
html[data-theme="dark"] .med-edu .me-k { color: #6fd6e0; background: #16323a; }
html[data-theme="dark"] .med-edu .me-note { color: #8fa0b3; }

/* 🆕 v250 症状-用药关联洞察（对标 Guava 2026「症状与因素相关性」）浅色主题 */
.symptom-med-assoc { margin-top: 12px; padding: 12px 14px; border: 1px solid #dbe6ea; border-left: 4px solid #8e44ad; border-radius: 10px; background: #f7f3fb; font-size: 13px; line-height: 1.5; }
/* 🆕 v533（用户需求 2）：症状关联四个窗口改**固定高度滚动窗**（用户原话：要做成固定高度的
   滚动窗口，和其他滚动窗口一样，不要太长，增加了整个页签的长度）。
   高度口径沿用 #event-list 的 260px（styles.css v531 段）；条目少时不超过自然高度。 */
.symptom-med-assoc,
.symptom-ind-correlation,
.symptom-vital-correlation,
.checkin-symptom-correlation {
  max-height: 260px;
  overflow-y: auto;
  overscroll-behavior: contain;
}
.symptom-med-assoc .sma-empty { color: #6b7785; }
.symptom-med-assoc .sma-tip { display: block; margin-top: 3px; font-size: 12px; color: #8593a3; }
.symptom-med-assoc .sma-head { font-weight: 700; color: #6c3483; margin-bottom: 8px; }
.symptom-med-assoc .sma-sub { font-weight: 400; font-size: 12px; color: #8593a3; }
.symptom-med-assoc .sma-list { list-style: none; margin: 0; padding: 0; }
.symptom-med-assoc .sma-row { padding: 8px 0; border-top: 1px dashed #e3d9ee; }
.symptom-med-assoc .sma-row:first-child { border-top: none; }
.symptom-med-assoc .sma-main { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; }
.symptom-med-assoc .sma-symp { font-weight: 700; color: #1f2d3d; }
.symptom-med-assoc .sma-med { color: #43596e; font-weight: 600; }
.symptom-med-assoc .sma-verdict { margin: 2px 0; font-weight: 600; }
.symptom-med-assoc .sma-row.sma-worse .sma-verdict { color: #c0392b; }
.symptom-med-assoc .sma-row.sma-better .sma-verdict { color: #1e8e4e; }
.symptom-med-assoc .sma-detail { font-size: 12px; }
.symptom-med-assoc .sma-bar { height: 6px; border-radius: 4px; background: #ece3f4; overflow: hidden; margin-top: 5px; max-width: 420px; }
.symptom-med-assoc .sma-bar-fill { display: block; height: 100%; border-radius: 4px; }
.symptom-med-assoc .sma-bar-fill.sma-worse { background: #d9534f; }
.symptom-med-assoc .sma-bar-fill.sma-better { background: #27ae60; }
.symptom-med-assoc .sma-foot { margin-top: 8px; font-size: 11px; color: #8593a3; line-height: 1.5; }
/* 🆕 v250 暗色主题覆盖 */
html[data-theme="dark"] .symptom-med-assoc { background: #1d1726; border-color: #342a44; border-left-color: #a86fd0; color: #c7d0db; }
html[data-theme="dark"] .symptom-med-assoc .sma-empty { color: #9aa6b2; }
html[data-theme="dark"] .symptom-med-assoc .sma-tip { color: #8593a3; }
html[data-theme="dark"] .symptom-med-assoc .sma-head { color: #c79bf0; }
html[data-theme="dark"] .symptom-med-assoc .sma-sub { color: #8593a3; }
html[data-theme="dark"] .symptom-med-assoc .sma-row { border-top-color: #342a44; }
html[data-theme="dark"] .symptom-med-assoc .sma-symp { color: #e6edf3; }
html[data-theme="dark"] .symptom-med-assoc .sma-med { color: #b8c4d0; }
html[data-theme="dark"] .symptom-med-assoc .sma-row.sma-worse .sma-verdict { color: #ff9b8e; }
html[data-theme="dark"] .symptom-med-assoc .sma-row.sma-better .sma-verdict { color: #7fd18a; }
html[data-theme="dark"] .symptom-med-assoc .sma-bar { background: #2a2238; }
html[data-theme="dark"] .symptom-med-assoc .sma-bar-fill.sma-worse { background: #e57368; }
html[data-theme="dark"] .symptom-med-assoc .sma-bar-fill.sma-better { background: #52d98a; }
html[data-theme="dark"] .symptom-med-assoc .sma-foot { color: #8593a3; }

/* 🆕 v526（需求 3②）：四个症状关联窗口**各用一套色系**。
   ── 用户原话：「下面4个症状关联窗口的颜色要有区别。」
   ── 实测证据（390×844，_probe_v526_probe2.js 逐窗取 computed style）：
        v521 需求 26 把后三个窗统一成了「症状-用药关联」的紫色配置，
        于是四窗实测**完全相同**：bg 全 rgb(247,243,251)、border-left 全 rgb(142,68,173)、
        ic-head 全 rgb(108,52,131) ⇒ 视觉上四块糊成一片，分不出哪块回答哪个问题。
   ── 本段改回「一窗一色」，颜色按**语义**分配（不是随便取色）：
        ① 症状-用药  紫 #8e44ad（原基准，代表药物）
        ② 症状-指标  蓝 #1b6b8f（与「指标↔指标」同族蓝，回到基类口径）
        ③ 症状-体征  橙 #c2610a（与日常测量/体温的暖色一致）
        ④ 打卡-症状  绿 #1e8449（与「每日健康打卡」的绿一致）
      四色的文字色对各自淡底对比度均 ≥ 5.5:1（WCAG AA 正文 4.5:1 之上），暗色模式另配。
   ⚠️ 必须写在 `.ind-correlation` 基类（2902 行）**之后**：基类同为 (0,1,0)，
      靠源序只为这几个容器生效，不误伤指标↔指标 / 指标↔体征两处仍用蓝底的同族窗口。 */
/* ② 症状-指标关联 */
.symptom-ind-correlation {
  border: 1px solid #d6e4ea; border-left: 4px solid #1b6b8f; background: #f2f8fb;
}
.symptom-ind-correlation .ic-head { color: #1b6b8f; }
.symptom-ind-correlation .ic-row { border-top-color: #d8e6ee; }
.symptom-ind-correlation .ic-bar { background: #e2ebf1; }
/* ③ 症状-生命体征关联 */
.symptom-vital-correlation {
  border: 1px solid #f0ddc8; border-left: 4px solid #c2610a; background: #fdf6ee;
}
.symptom-vital-correlation .ic-head { color: #9a4a06; }
.symptom-vital-correlation .ic-row { border-top-color: #f2e2d2; }
.symptom-vital-correlation .ic-bar { background: #f4e6d7; }
/* ④ 打卡因素-症状关联 */
.checkin-symptom-correlation {
  border: 1px solid #cfe8d8; border-left: 4px solid #1e8449; background: #f0f9f3;
}
.checkin-symptom-correlation .ic-head { color: #14663a; }
.checkin-symptom-correlation .ic-row { border-top-color: #d9ecdf; }
.checkin-symptom-correlation .ic-bar { background: #e2f1e8; }

/* 夜间模式：同色相降饱和 + 提亮文字，保持四窗可区分 */
html[data-theme="dark"] .symptom-ind-correlation { background: #14212a; border-color: #27343f; border-left-color: #3d93b8; }
html[data-theme="dark"] .symptom-ind-correlation .ic-head { color: #7cc4e6; }
html[data-theme="dark"] .symptom-ind-correlation .ic-row { border-top-color: #27343f; }
html[data-theme="dark"] .symptom-ind-correlation .ic-bar { background: #22303a; }
html[data-theme="dark"] .symptom-vital-correlation { background: #241b12; border-color: #3d2f20; border-left-color: #c2792f; }
html[data-theme="dark"] .symptom-vital-correlation .ic-head { color: #f0b072; }
html[data-theme="dark"] .symptom-vital-correlation .ic-row { border-top-color: #3d2f20; }
html[data-theme="dark"] .symptom-vital-correlation .ic-bar { background: #332618; }
html[data-theme="dark"] .checkin-symptom-correlation { background: #13221a; border-color: #22392c; border-left-color: #34a06b; }
html[data-theme="dark"] .checkin-symptom-correlation .ic-head { color: #7fd6a2; }
html[data-theme="dark"] .checkin-symptom-correlation .ic-row { border-top-color: #22392c; }
html[data-theme="dark"] .checkin-symptom-correlation .ic-bar { background: #1c3026; }

/* 🆕 v260 指标复测提醒（adaptive per-indicator retest due，对标 LTRL/Function Health「due for retest」） */
.ind-retest { display: none; margin-top: 8px; padding: 10px 14px; border: 1px solid #d6e4ea; border-radius: 10px; background: #eef7f4; font-size: 13px; }
.ind-retest .ir-head { font-weight: 700; color: #1b7a5a; margin-bottom: 6px; }
.ind-retest .ir-count { font-weight: 600; color: #c0392b; margin-left: 6px; font-size: 12px; }
.ind-retest .ir-list { margin: 4px 0 0; padding-left: 18px; }
.ind-retest .ir-row { padding: 3px 0; }
.ind-retest .ir-name { font-weight: 600; color: #1f2d3d; margin-right: 6px; }
.ind-retest .ir-msg b { color: #1b7a5a; }
.ind-retest .ir-foot { margin: 6px 0 0; font-size: 11px; color: #8593a3; line-height: 1.5; }
html[data-theme="dark"] .ind-retest { background: #16241f; border-color: #234038; color: #c7d0db; }
html[data-theme="dark"] .ind-retest .ir-head { color: #6fd6ad; }
html[data-theme="dark"] .ind-retest .ir-count { color: #ff8a7a; }
html[data-theme="dark"] .ind-retest .ir-name { color: #e6edf3; }
html[data-theme="dark"] .ind-retest .ir-msg b { color: #6fd6ad; }
html[data-theme="dark"] .ind-retest .ir-foot { color: #8593a3; }

/* 🆕 v263 检验记录行内编辑提示条（对标 MyChart 2026 易修正记录） */
.rec-edit-banner { display: flex; align-items: center; gap: 10px; margin-top: 10px; padding: 9px 14px; border: 1px solid #bcd4e6; border-radius: 10px; background: #eaf3fb; font-size: 13px; color: #1f2d3d; }
.rec-edit-banner[hidden] { display: none; }
.rec-edit-banner b { color: #1565c0; }
html[data-theme="dark"] .rec-edit-banner { background: #16202e; border-color: #2a3b50; color: #c7d0db; }
html[data-theme="dark"] .rec-edit-banner b { color: #7fb6e8; }

/* ============================================================================
   v270 ①首页 6 窗口（2 列 × 3 行）+ 每个窗口的「使用动图」（纯 CSS 循环演示）
   ②会员中心独立页签 ③电脑端页签悬浮小窗预览 ④提示说明收进窗口角落 ❓
   说明：动图只做示意，不读取任何用户数据；prefers-reduced-motion 下停止动画。
   ========================================================================== */

/* ---------- ① 首页 ---------- */
.home-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin: 0 0 12px; }
.home-title { margin: 0; font-size: 18px; }
.home-sub { margin: 0; font-size: 12.5px; color: var(--muted); }
/* 🆕 v578（用户 2026-11-01 第 3 项）：原 `.home-hero`（首页那块独立的青绿渐变卡片）整段退役。
   它的内容（标题 / 副标题 / 头像 / 主题按钮）已整体搬进页眉的 `.hdr-brand` 行，
   与页签行共用 `.app-header` 的一道渐变 ⇒ 「两个色块」变成「一块」。
   新规则见文件前部「页眉品牌行」那一节（.hdr-brand / .hb-logo / .hb-txt / .hb-theme / .hh-ava）。
   ⚠️ 别把这段恢复回来：DOM 里已经没有 `.home-hero` 这个 class，留着只会让人误以为还能用；
      而 `.hh-title` / `.hh-sub` / `.hh-ava` 三个**类名**仍在（id 也仍是 #hh-title 等），
      只是改由 `.hdr-brand` 前缀选择器接管 —— js 的 renderHomeHero() 一个字都不用改。 */

.home-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.home-win {
  position: relative; display: flex; flex-direction: column; gap: 7px; text-align: left;
  background: var(--panel); border: 1px solid var(--line); border-radius: 14px; padding: 10px 10px 9px;
  cursor: pointer; color: var(--ink); font: inherit;
  transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease;
  -webkit-tap-highlight-color: transparent;
  height: 100%;
}
.home-win .hw-demo { flex: 1 1 auto; display: flex; flex-direction: column; justify-content: flex-end; min-height: 0; }
.home-win:hover { border-color: var(--primary); box-shadow: 0 6px 18px rgba(20, 40, 60, .12); transform: translateY(-2px); }
.home-win:active { transform: translateY(0) scale(.99); }
/* 🆕 v278：允许换行 —— 窄屏下「日常测量」要挂 2 个徽标，挤不下时徽标整体落到第二行右对齐，
   而不是把窗口撑破（老 WebView 没有 aspect-ratio，父级宽度必须始终可控）。 */
.hw-head { display: flex; align-items: center; gap: 6px; row-gap: 3px; flex-wrap: wrap; font-size: 14px; font-weight: 600; }
.hw-ico { font-style: normal; font-size: 16px; }
/* 🆕 v278：首页窗口标题旁的数字徽标 —— 原「健康概览」的 5 个数字改挂到对应窗口标题右侧：
   指标趋势=偏高/偏低，检验记录=已记录指标，用药记录=今日在用药物，日常测量=最近检验 + 下次复查。 */
.hw-badge {
  display: inline-flex; align-items: baseline; gap: 3px; flex: 0 0 auto; margin-left: auto;
  padding: 1px 6px; border-radius: 999px; font-style: normal; font-weight: 700; font-size: 10.5px;
  line-height: 1.6; white-space: nowrap;
  color: #0e7c86; background: rgba(14, 124, 134, .10); border: 1px solid rgba(14, 124, 134, .22);
}
.hw-badge + .hw-badge { margin-left: 0; }
.hw-badge .hb-lb { font-style: normal; font-weight: 500; font-size: 9.5px; opacity: .78; }
.hw-badge.is-warn { color: #b3471f; background: rgba(214, 108, 45, .13); border-color: rgba(214, 108, 45, .32); }
.hw-badge.is-ok { color: #1d7a4c; background: rgba(38, 148, 96, .12); border-color: rgba(38, 148, 96, .3); }
.hw-badge.is-muted { color: var(--muted); background: rgba(120, 130, 140, .10); border-color: rgba(120, 130, 140, .22); }
.hw-badge:empty { display: none; }
html[data-theme="dark"] .hw-badge { color: #5fd0db; background: rgba(95, 208, 219, .12); border-color: rgba(95, 208, 219, .28); }
html[data-theme="dark"] .hw-badge.is-warn { color: #ffb27a; background: rgba(255, 150, 90, .14); border-color: rgba(255, 150, 90, .34); }
html[data-theme="dark"] .hw-badge.is-ok { color: #7bd6a4; background: rgba(90, 200, 140, .14); border-color: rgba(90, 200, 140, .32); }
html[data-theme="dark"] .hw-badge.is-muted { color: #93a3b1; background: rgba(255, 255, 255, .06); border-color: rgba(255, 255, 255, .16); }
.hw-foot { font-size: 11.5px; color: var(--muted); }
/* ⚠️ 必须显式 width:100%：.hw-mock 用 padding-bottom 百分比撑高度，老 WebView（雷电 Chrome/91）
   在「父级宽度未定」时会把百分比解析成 0 → 演示区塌成 2×3px（v270 实测）。 */
.hw-demo { display: block; width: 100%; }
/* 🆕 v557（用户 2026-10-28 第 1 项）：首页 6 个窗口改用 mastergo 视频。
   `has-vid` = 该窗口已挂视频 ⇒ 原来的 CSS 示意动画整体隐藏（否则两层叠在一起）。
   视频用绝对定位铺满 .hw-mock（它已经是这个窗口里的定位盒，圆角/尺寸都由它决定），
   `object-fit: cover` 保证不同比例下不变形、不留黑边。
   ⚠️ 视频加载失败时 JS 会摘掉 has-vid ⇒ 自动退回原来的 CSS 动画，不会留下空白框。 */
.hw-mock.has-vid > *:not(.hw-vid) { display: none !important; }
.hw-mock.has-vid { background: #eef3f8; }
.hw-vid {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; display: block; border-radius: inherit;
  pointer-events: none;
}
html[data-theme="dark"] .hw-mock.has-vid { background: #1c2733; }
.hw-mock {
  position: relative; display: block; width: 100%; height: 0; padding-bottom: 58%;
  border-radius: 10px; overflow: hidden; border: 1px solid var(--line);
  background: linear-gradient(180deg, rgba(14, 124, 134, .06), rgba(14, 124, 134, .015));
}
html[data-theme="dark"] .hw-mock { background: linear-gradient(180deg, rgba(255, 255, 255, .05), rgba(255, 255, 255, .01)); }
.hw-mock > * { position: absolute; }

/* 1 指标趋势：折线绘制 + 红点沿折线走 */
.hw-mock-trend .hw-grid { inset: 0; background-image: linear-gradient(var(--line) 1px, transparent 1px); background-size: 100% 33.33%; opacity: .55; }
.hw-mock-trend .hw-svg { inset: 0; width: 100%; height: 100%; }
.hw-pl { fill: none; stroke: var(--primary); stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 170; animation: hwDraw 3.6s ease-in-out infinite; }
@keyframes hwDraw { 0% { stroke-dashoffset: 170; } 60%, 100% { stroke-dashoffset: 0; } }
.hw-mock-trend .hw-dot {
  width: 7px; height: 7px; margin: -3.5px 0 0 -3.5px; border-radius: 50%; background: #e05252;
  box-shadow: 0 0 0 3px rgba(224, 82, 82, .18); animation: hwRun 3.6s ease-in-out infinite;
}
@keyframes hwRun {
  0% { left: 5%; top: 75%; opacity: 0; } 10% { opacity: 1; }
  16% { left: 20%; top: 61%; } 32% { left: 35%; top: 68%; } 48% { left: 50%; top: 39%; }
  64% { left: 65%; top: 50%; } 80% { left: 80%; top: 21%; } 94% { left: 95%; top: 32%; }
  100% { left: 95%; top: 32%; opacity: 0; }
}
.hw-mock-trend .hw-tag {
  right: 5%; top: 8%; padding: 1px 5px; border-radius: 999px; font-size: 9.5px; font-style: normal;
  color: #fff; background: var(--primary); animation: hwFade 3.6s ease-in-out infinite;
}
@keyframes hwFade { 0%, 55% { opacity: 0; } 75%, 92% { opacity: 1; } 100% { opacity: 0; } }

/* 2 检验记录：拍照框 + 记录行滚动 + 导入成功打勾 */
.hw-mock-lab .hw-shot { left: 6%; top: 14%; width: 24%; height: 34%; border-radius: 4px; border: 2px dashed #9fb0c4; background: #dde5ee; }
.hw-mock-lab .hw-list { left: 36%; right: 5%; top: 8%; bottom: 8%; overflow: hidden; animation: hwScroll 4.8s ease-in-out infinite; }
@keyframes hwScroll { 0%, 18% { transform: translateY(0); } 46%, 66% { transform: translateY(-42%); } 94%, 100% { transform: translateY(0); } }
.hw-row { position: relative; display: block; height: 16%; margin-bottom: 6%; border-radius: 4px; background: rgba(127, 140, 158, .1); }
.hw-row b { position: absolute; left: 6%; top: 28%; width: 32%; height: 44%; border-radius: 3px; background: #c9d6e4; }
.hw-row s { position: absolute; left: 44%; top: 28%; width: 20%; height: 44%; border-radius: 3px; background: #dbe4ee; text-decoration: none; }
.hw-row u { position: absolute; right: 6%; top: 28%; width: 15%; height: 44%; border-radius: 3px; background: #2e9e5b; text-decoration: none; }
.hw-row u.hi { background: #e05252; }
.hw-mock-lab .hw-ok {
  right: 7%; bottom: 7%; width: 17px; height: 17px; border-radius: 50%; background: #2e9e5b; color: #fff;
  font-size: 11px; font-style: normal; line-height: 17px; text-align: center; animation: hwPop 4.8s ease-in-out infinite;
}
@keyframes hwPop { 0%, 42% { opacity: 0; transform: scale(.5); } 56%, 74% { opacity: 1; transform: scale(1); } 88%, 100% { opacity: 0; transform: scale(.5); } }

/* 3 用药记录：药卡滑入 + 打勾 + 依从柱 */
.hw-pill {
  left: 8%; right: 8%; height: 28%; display: flex; align-items: center; gap: 6px; padding: 0 8px;
  border-radius: 8px; background: var(--panel); border: 1px solid var(--line); animation: hwSlide 4s ease-in-out infinite;
}
.hw-pill.p1 { top: 9%; }
.hw-pill.p2 { top: 44%; animation-delay: .7s; }
.hw-pill.p2 .hw-cir { animation-delay: .7s; }
@keyframes hwSlide { 0% { transform: translateX(72%); opacity: 0; } 18%, 68% { transform: translateX(0); opacity: 1; } 88%, 100% { transform: translateX(72%); opacity: 0; } }
.hw-cir {
  flex: none; width: 15px; height: 15px; border-radius: 50%; background: #e8eef5; color: transparent;
  font-size: 10px; font-style: normal; line-height: 15px; text-align: center; animation: hwCheck 4s ease-in-out infinite;
}
@keyframes hwCheck { 0%, 26% { background: #e8eef5; color: transparent; } 40%, 72% { background: #2e9e5b; color: #fff; } 86%, 100% { background: #e8eef5; color: transparent; } }
.hw-pill s { display: block; flex: 1; height: 6px; border-radius: 3px; background: #d3dde8; text-decoration: none; }
.hw-pill s.short { flex: 0 0 22%; }
.hw-adh { left: 8%; right: 8%; bottom: 6%; height: 20%; display: flex; align-items: flex-end; gap: 4px; }
.hw-adh i { flex: 1; height: var(--h); border-radius: 2px 2px 0 0; background: rgba(46, 158, 91, .8); transform-origin: bottom; animation: hwBar 2.6s ease-in-out infinite; }
.hw-adh i:nth-child(2) { animation-delay: .25s; } .hw-adh i:nth-child(3) { animation-delay: .5s; }
.hw-adh i:nth-child(4) { animation-delay: .75s; } .hw-adh i:nth-child(5) { animation-delay: 1s; }
@keyframes hwBar { 0%, 100% { transform: scaleY(.5); } 50% { transform: scaleY(1); } }

/* 4 日常测量：血压数字切换 + 心跳 + 柱状 */
.hw-mock-vitals .hw-bp { left: 7%; top: 12%; width: 52%; }
.hw-bp em { display: block; font-style: normal; font-size: 16px; font-weight: 700; line-height: 1.2; }
.hw-bp em.n2 { position: absolute; left: 0; top: 0; opacity: 0; animation: hwFlipB 3.2s steps(1, end) infinite; }
.hw-bp em.n1 { animation: hwFlipA 3.2s steps(1, end) infinite; }
@keyframes hwFlipA { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }
@keyframes hwFlipB { 0%, 49% { opacity: 0; } 50%, 100% { opacity: 1; } }
.hw-bp span { display: block; margin-top: 22px; font-size: 10px; color: var(--muted); }
.hw-mock-vitals .hw-heart { right: 11%; top: 14%; font-size: 20px; font-style: normal; color: #e05252; animation: hwBeat 1.3s ease-in-out infinite; }
@keyframes hwBeat { 0%, 100% { transform: scale(1); } 14% { transform: scale(1.28); } 28% { transform: scale(1); } 42% { transform: scale(1.16); } 56% { transform: scale(1); } }
.hw-vbars { left: 7%; right: 7%; bottom: 7%; height: 28%; display: flex; align-items: flex-end; gap: 5px; }
.hw-vbars i { flex: 1; height: var(--h); border-radius: 3px 3px 0 0; background: linear-gradient(180deg, var(--primary), rgba(14, 124, 134, .3)); transform-origin: bottom; animation: hwBar 2.8s ease-in-out infinite; }
.hw-vbars i:nth-child(2) { animation-delay: .3s; } .hw-vbars i:nth-child(3) { animation-delay: .6s; } .hw-vbars i:nth-child(4) { animation-delay: .9s; }

/* 5 患者档案：三张卡片轮流高亮（模拟切换患者） */
.hw-pcard {
  left: 9%; right: 9%; height: 26%; display: flex; align-items: center; gap: 7px; padding: 0 8px;
  border-radius: 8px; background: var(--panel); border: 1px solid var(--line); animation: hwSel 4.5s ease-in-out infinite;
}
.hw-pcard.c1 { top: 8%; } .hw-pcard.c2 { top: 37%; animation-delay: 1.5s; } .hw-pcard.c3 { top: 66%; animation-delay: 3s; }
@keyframes hwSel {
  0%, 26% { border-color: var(--primary); box-shadow: 0 2px 8px rgba(14, 124, 134, .2); transform: translateX(2px); }
  34%, 100% { border-color: var(--line); box-shadow: none; transform: translateX(0); }
}
.hw-ava { flex: none; width: 16px; height: 16px; border-radius: 50%; background: #cfd8e3; }
.hw-pcard s { display: block; flex: 1; height: 6px; border-radius: 3px; background: #d3dde8; text-decoration: none; }
.hw-pcard s.short { flex: 0 0 26%; }

/* 6 会员中心：会员卡流光 + 续费按钮脉冲 */
.hw-vcard {
  left: 7%; top: 12%; width: 54%; height: 54%; border-radius: 10px; overflow: hidden; padding: 8px 9px;
  background: linear-gradient(135deg, #2b3a55, #3d5a80); color: #fff;
}
.hw-vcard::after {
  content: ''; position: absolute; top: 0; left: -60%; width: 42%; height: 100%;
  background: linear-gradient(100deg, transparent, rgba(255, 255, 255, .38), transparent);
  animation: hwShine 2.8s ease-in-out infinite;
}
@keyframes hwShine { 0%, 26% { left: -60%; } 68%, 100% { left: 118%; } }
.hw-crown { display: block; font-style: normal; font-size: 15px; }
.hw-vcard s { display: block; height: 5px; margin-top: 7px; border-radius: 3px; background: rgba(255, 255, 255, .45); text-decoration: none; }
.hw-vcard s.short { width: 58%; }
.hw-vcard em { position: absolute; left: 9px; bottom: 8px; font-style: normal; font-size: 11px; font-weight: 700; color: #ffd479; }
.hw-subbtn {
  right: 8%; top: 30%; padding: 5px 10px; border-radius: 999px; background: var(--primary); color: #fff;
  font-size: 11px; white-space: nowrap; animation: hwPulse 2.1s ease-in-out infinite;
}
@keyframes hwPulse {
  0%, 100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(14, 124, 134, .35); }
  50% { transform: scale(1.06); box-shadow: 0 0 0 7px rgba(14, 124, 134, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .hw-mock * , .hw-mock { animation: none !important; }
}

/* ---------- ③ 电脑端页签悬浮小窗预览（Windows 风格） ---------- */
.tabprev {
  position: fixed; z-index: 220; width: 320px; border-radius: 10px; overflow: hidden;
  background: var(--panel); border: 1px solid var(--line); box-shadow: 0 14px 34px rgba(20, 40, 60, .22);
  opacity: 0; transform: translateY(-6px); transition: opacity .14s ease, transform .14s ease; pointer-events: none;
}
.tabprev.show { opacity: 1; transform: translateY(0); }
.tp-bar {
  display: flex; align-items: center; gap: 8px; padding: 6px 8px;
  background: linear-gradient(180deg, #f2f5f9, #e6ebf1); border-bottom: 1px solid var(--line);
}
html[data-theme="dark"] .tp-bar { background: linear-gradient(180deg, #1e2833, #18212b); }
.tp-dots { display: flex; gap: 5px; }
.tp-dots i { display: block; width: 10px; height: 10px; border-radius: 50%; }
.tp-dots i:nth-child(1) { background: #ff5f57; } .tp-dots i:nth-child(2) { background: #febc2e; } .tp-dots i:nth-child(3) { background: #28c840; }
.tp-name { flex: 1; text-align: center; font-size: 12px; font-weight: 600; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tp-winbtns { display: flex; gap: 7px; color: var(--muted); font-size: 11px; }
.tp-winbtns span { width: 12px; text-align: center; }
.tp-body { padding: 10px 12px; font-size: 12.5px; max-height: 264px; overflow: hidden; }
.tp-row { display: flex; justify-content: space-between; gap: 10px; padding: 3.5px 0; border-bottom: 1px dashed var(--line); }
.tp-row:last-child { border-bottom: none; }
.tp-row b { font-weight: 600; }
.tp-k { color: var(--muted); white-space: nowrap; }
.tp-v { text-align: right; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 🆕 v537（项9）：最近登录等长值显示不下时换行（不再截断成省略号） */
.tp-v.wrap { white-space: normal; word-break: break-word; overflow: visible; text-overflow: clip; }
.tp-note { margin-top: 8px; font-size: 11.5px; color: var(--muted); }
.tp-empty { color: var(--muted); font-size: 12px; padding: 6px 0; }
.tp-spark { display: block; width: 100%; height: 44px; margin-top: 8px; }
.tp-badge { display: inline-block; padding: 1px 6px; border-radius: 999px; font-size: 10.5px; color: #fff; background: var(--primary); }
.tp-badge.warn { background: #e0a106; } .tp-badge.bad { background: #d9534f; } .tp-badge.ok { background: #2e9e5b; }
@media (max-width: 900px) { .tabprev { display: none !important; } }

/* ---------- ④ 窗口角落 ❓ 使用说明 ---------- */
.card, .event-marker, .symptom-heatmap, .panel { position: relative; }
.hint-q {
  position: absolute; top: 8px; right: 8px; z-index: 4; width: 26px; height: 26px; padding: 0;
  border: 1px solid var(--line); border-radius: 50%; background: var(--panel); color: var(--muted);
  font-size: 14px; line-height: 24px; text-align: center; cursor: pointer; opacity: .85; transition: .15s;
}
.hint-q:hover, .hint-q:focus { opacity: 1; color: var(--primary); border-color: var(--primary); outline: none; }
html[data-theme="dark"] .hint-q { background: #1a2431; }
.hint-src { display: none !important; }
/* 🆕 v388（用户第 8 条）：说明「原全文备份」容器。备份在 index.html #hint-archive 里，
   平时不显示，仅存档供后续做使用动画时复用（取回入口 window.__cmHintFull(key)）。
   ⚠️ 不参与 hintsToCorner 的选择器（它选的是 p.hint，本类是 hint-full 另一个 class token）。 */
.hint-full { display: none !important; }
/* 🆕 v388：同一容器多段说明合并进同一枚 ❓ 时的段间分隔线。 */
.hintpop .hint-sep { height: 1px; background: var(--line); margin: 9px 0; }
.hintpop {
  position: fixed; z-index: 320; max-width: 340px; padding: 12px 30px 12px 14px; border-radius: 10px;
  background: var(--panel); border: 1px solid var(--line); box-shadow: 0 12px 30px rgba(20, 40, 60, .22);
  font-size: 12.5px; line-height: 1.75; color: var(--muted);
}
.hintpop[hidden] { display: none; }
.hintpop b { color: var(--ink); }
.hintpop .hp-x {
  position: absolute; top: 4px; right: 6px; border: none; background: transparent; cursor: pointer;
  color: var(--muted); font-size: 15px; line-height: 1; padding: 4px 6px;
}
@media (max-width: 640px) { .hintpop { max-width: calc(100vw - 28px); } .home-grid { gap: 10px; } }

/* ---------- v270 会员中心：安全管理 / 续费管理 ---------- */
.sec-rows { margin-bottom: 6px; }
.sec-block { margin: 12px 0; padding-top: 10px; border-top: 1px dashed var(--line); }
.sec-block h4 { margin: 0 0 8px; font-size: 13.5px; color: var(--ink); }
/* 🆕 v511：绑定邮箱块里的一句说明（为什么值得绑） */
.sec-note { margin: 0 0 8px; font-size: 12.5px; color: var(--muted); line-height: 1.55; }
.sec-form { display: flex; flex-wrap: wrap; gap: 8px; }
.sec-form input, .sec-form select {
  flex: 1 1 140px; min-height: 38px; padding: 6px 10px; border: 1px solid var(--line);
  border-radius: 8px; background: var(--panel); color: var(--ink); font-size: 14px;
}
.sec-form .btn { flex: none; min-height: 38px; }
/* 🆕 v537（项9）：提醒邮箱 —— 展示态 = 邮箱值 + 「编辑/删除」按钮同排（按钮在文本右边），
   文字样式与上方「最近登录」一致（不加粗）。 */
.sec-email-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap; }
.sec-email-val { font-size: 14px; color: var(--ink); word-break: break-all; }
.sec-email-acts { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.sec-email-acts .btn, .sec-email-edit .btn { min-height: 36px; }
.sec-email-edit { align-items: center; }
.sec-email-edit input { flex: 1 1 180px; }
/* 🆕 v536（项3）：弹窗内表单竖排（输入框 / 选择器 / 按钮各占一行，视觉更整） */
.sec-form-col { flex-direction: column; align-items: stretch; }
.sec-form-col input, .sec-form-col select { flex: none; width: 100%; }
.sec-modal-pop { width: min(360px, 92vw); }
.sec-modal-pop .def-body { padding: 14px 16px; }
.sec-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 12px; }
/* 🆕 v537（项9）：四个按钮（修改密码/忘记密码/退出登录/注销账号）2×2 网格，左右各 2 个；
   注销确认区跨两列。 */
.sec-actions-grid { display: grid; grid-template-columns: 1fr 1fr; }
.sec-actions-grid .btn { flex: none; width: 100%; }
.sec-actions-grid .sec-danger-zone { grid-column: 1 / -1; }
/* 🆕 v537（项9）：登录账号行内联的「编辑」小按钮 */
.sec-inline-btn { flex: none; min-height: 0; padding: 2px 10px; font-size: 12px; border-radius: 6px; }
/* 🆕 v537（项9）：忘记密码弹窗说明 */
.sec-forgot-note { margin: 0 0 8px; font-size: 12.5px; color: var(--muted); line-height: 1.55; }
/* 🆕 v564（用户第 4 项）：忘记密码第一步的行内错误提示（channel:'none' 那条长指引）。
   不用 toast 是因为它含「会员中心 → 提醒邮箱」的操作路径，漂浮提示会被截断。
   ⚠️ 只用 :root 里已有的变量（--bg / --line / --ink）—— 本文件没有 --warn，
      也不能用 color-mix（Android WebView 老版本不支持，且全文件此前一次都没用过）。 */
.sec-forgot-err {
  margin: 2px 0 0; padding: 8px 10px; border-radius: 8px;
  background: var(--bg); border: 1px solid var(--line);
  color: var(--ink); font-size: 12.5px; line-height: 1.6;
}
.sec-danger-zone { display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 12.5px; color: var(--danger); }
.sec-state, .renew-state { font-size: 11.5px; color: var(--muted); }
/* 🆕 v508（用户第 3 项）：「💳 续费管理」卡并入「👑 账号与订阅」后，
   本块与上方的「账号 / 方案 / 邀请码」同处一张卡 ⇒ 需要一个分节标题 + 分隔线划清层次。
   （原 .rn-plan / .rn-his 已随合并删除：状态与月费由 .bv-plan 显示，账单由 .bv-history 显示。） */
.rn-head {
  margin: 16px 0 10px; padding-top: 12px;
  border-top: 1px dashed var(--line, #e5ebf3);
  font-size: 13.5px; color: var(--ink);
}
.rn-plan { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.rn-price { font-size: 13px; font-weight: 600; }
.rn-tiers { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.rn-tier {
  display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 10px 4px;
  border: 1px solid var(--line); border-radius: 10px; background: var(--panel); cursor: pointer;
  color: var(--ink); font: inherit; transition: .15s; -webkit-tap-highlight-color: transparent;
}
.rn-tier:hover { border-color: var(--primary); box-shadow: 0 3px 10px rgba(20, 40, 60, .1); }
.rn-tier:active { transform: scale(.98); }
.rn-tier b { font-size: 13px; }
.rn-tier span { font-size: 15px; font-weight: 700; color: var(--primary); }
.rn-tier em { font-style: normal; font-size: 10.5px; color: var(--muted); }
/* 🆕 v509（用户第 4 项）：档位卡上标出「本单用到几次邀请优惠（¥8 月）」，
   否则用户看不出 ¥8 是从哪来的、还剩几次。 */
.rn-tier i.rn-credit {
  font-style: normal; font-size: 10px; font-weight: 600; line-height: 1.4; margin-top: 1px;
  padding: 1px 6px; border-radius: 999px; color: #1e8449;
  background: rgba(30, 132, 73, .1); border: 1px solid rgba(30, 132, 73, .25);
}
html[data-theme="dark"] .rn-tier i.rn-credit { color: #4cd07d; background: rgba(76, 208, 125, .12); border-color: rgba(76, 208, 125, .3); }
/* 🆕 v512（用户第 9 项）：会员中心「📤 推荐给微信好友」—— 紧跟在 1 / 6 / 12 档位按钮下面。
   做成整行「虚线描边 + 浅底」的次级按钮：与上面三个实心档位卡在视觉上**分层**
   （档位 = 付费主路径，推荐 = 分享），又比裸 `.btn` 更容易被看见
   —— 默认按钮在这张卡里跟周围的说明文字几乎分不开，而用户要的是一个显式的「转发入口」。 */
.rn-share {
  display: flex; align-items: center; justify-content: center;
  width: 100%; margin-top: 10px; padding: 9px 12px;
  font-size: 13px; font-weight: 600;
  color: var(--primary); background: rgba(14, 124, 134, .06);
  border: 1px dashed var(--primary); border-radius: 10px;
}
.rn-share:hover { background: rgba(14, 124, 134, .13); }
.rn-share:active { transform: scale(.995); }
html[data-theme="dark"] .rn-share { color: #7fdde4; background: rgba(26, 167, 177, .14); border-color: #2f8e97; }
html[data-theme="dark"] .rn-share:hover { background: rgba(26, 167, 177, .24); }
.rn-auto { display: flex; align-items: center; gap: 6px; margin: 12px 0 0; font-size: 12.5px; color: var(--muted); cursor: pointer; }
.rn-his { margin-top: 14px; }
.rn-his h4 { margin: 0 0 6px; font-size: 13.5px; color: var(--ink); }
/* 🆕 v365：激活码兑换（线下收款 → 转账后凭码自助开通）。
   输入框统一大写显示：码体本身用 32 字母表、剔除了 I/O/0/1，大写显示能减少抄写歧义；
   真实值不受影响（服务端自己归一化，前端不改写用户输入）。 */
.rn-redeem { margin: 14px 0 0; padding: 12px; border: 1px solid var(--line); border-radius: 10px; background: var(--panel); }
.rn-redeem h4 { margin: 0 0 4px; font-size: 13.5px; color: var(--ink); }
.rn-redeem-tip { margin: 0 0 8px; font-size: 11.5px; line-height: 1.6; color: var(--muted); }
.rn-redeem-row { display: flex; gap: 8px; align-items: stretch; }
.rn-redeem-row input {
  flex: 1 1 auto; min-width: 0; padding: 8px 10px; border: 1px solid var(--line); border-radius: 8px;
  background: var(--bg); color: var(--ink); font: inherit; font-size: 14px;
  letter-spacing: .06em; text-transform: uppercase;
}
.rn-redeem-row input:focus { outline: none; border-color: var(--primary); }
.rn-redeem-row .btn { flex: 0 0 auto; }
.rn-redeem-err { margin: 8px 0 0; font-size: 12px; line-height: 1.5; color: var(--danger); }
.rn-redeem-err:empty { display: none; }
/* 🆕 v525（需求10②）：用户「续费窗口的 3 个按月数付费窗口要压缩宽度，一排装下」。
   原手机段降为 2 列 ⇒ 1/6/12 三档被折成两行（用户截图里看到的就是这个）。
   现固定 3 列，并同步压缩内距与字号 —— 390px 视口下每档约 110px，
   「12 个月 / ¥216 / ¥18·月」三行都能完整显示；邀请优惠小徽标允许换行不溢出。 */
@media (max-width: 640px) {
  .rn-tiers { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
  .rn-tier { padding: 8px 2px; gap: 1px; }
  .rn-tier b { font-size: 12px; }
  .rn-tier span { font-size: 13.5px; }
  .rn-tier em { font-size: 9.5px; text-align: center; line-height: 1.35; }
  .rn-tier i.rn-credit { font-size: 9px; padding: 1px 4px; max-width: 100%; text-align: center; }
}
/* ❓ 落在 .card-head 里时改为流式排布，避免绝对定位压住右侧状态文字 */
.hint-q-inline { position: static; flex: none; opacity: .7; }   /* 🆕 v423：margin-left 取消 —— .card-head gap:6px 已提供统一间距，双份导致图标间距不一 */

/* ============================================================
   🆕 v271：APK UI 调整
   ① 指标趋势设置收进「⚙️ 设置」按钮（移动端折叠，桌面端常显）
   ② OCR 导入详情识别指标表 = 固定 2 行滚动窗口
   ③ 指标库 = 固定 5 行滚动窗口（JS 已按行高设 maxHeight）
   ④ 检验记录：筛选收进「筛选」按钮（移动端折叠）；记录卡片压缩为 3 行
   ============================================================ */

/* ② 识别指标表滚动窗口（JS 将 maxHeight 精确设为 2 行高，其余滚动） */
.entry-ind-win { overflow-y: auto; border-radius: 8px; }
.entry-ind-win > table { margin: 0; }

/* ① 设置按钮：桌面端隐藏（设置面板常显），移动端出现 */
.chart-settings-row { display: none; margin: 8px 0; }
/* ④ 「筛选按钮」已取消（v391 用户第 3 项：筛选控件整体收进卡片头的 🔍 下拉面板），
    原来那条「桌面端隐藏 / 移动端显示」的规则随按钮一并删除。 */

@media (max-width: 767px) {
  /* ① 指标趋势设置：默认收起，点「⚙️ 设置」展开 */
  .chart-settings-row { display: block; }
  .chart-toolbar { display: none; }
  .chart-toolbar.open { display: flex; }
  .chart-toolbar-bottom { display: none; }
  .chart-toolbar-bottom.open { display: flex; }

  /* ④ 筛选折叠规则已迁走（v391）：历史记录改由卡片头 🔍 的 `#rec-filter-menu` 控制开合，
     规则写在文件末尾的 v391 段。⚠️ 这里**不能**再留 `.rec-filter { display: none }`：
     `.rec-filter` 是「历史记录」与「用药记录表」共用的类，留在这里会把用药记录表的
     状态筛选 + 搜索一起永久隐藏（v271~v390 的实际缺陷，手机上无法展开）。 */

  /* ④ 检验记录卡片压缩为 3 行（v273 更紧凑）：
     行1：[✓] 日期 指标名 ........ [状态]
     行2：数值 参考范围 [较上次][严重度]
     行3：备注 [复][改][删]

     ⚠️⚠️ 本块所有 `nth-child(N)` 都按**当前列序**写死，列序是：
        1=全选 2=日期 3=指标 4=数值 5=参考范围 6=状态 7=较上次 8=严重度 9=备注 10=操作
     —— v363 插入「严重度」列时没有同步本块，导致 8/9 两列整体错位：
        备注（内容常为「图片导入」）拿到 order:0 ⇒ 浮到第一行、夹在日期与指标名之间；
        严重度反而拿到 order:9（本该是备注的位置）。用户第 7 条③「原有图片导入是在左下角的」即此。
     ⇒ 以后**再插入/删除列**时，必须把本块 + 上面 @media(max-width:640px) 的同类规则一并数一遍。 */
  #record-list tr { gap: 2px 6px; padding: 6px 10px; align-items: baseline; position: relative; }
  #record-list tr::before { content: ''; flex: 1 1 100%; order: 4; }
  #record-list tr::after { content: ''; flex: 1 1 100%; order: 8; }
  #record-list td { font-size: 13px; }
  #record-list td.sel-col { flex: 0 0 auto; order: 0; align-self: flex-start; }
  /* 🆕 v366（用户第 7 条②）：行 1 =「日期 → 指标名」。用户要求「原有指标名称是在日期后的」，
     故显式给两列各自 order（此前是靠「指标有 order、日期没有」的默认值 0 偶然成立，
     一旦有人给日期补上 order 就会翻转；写死更稳）。 */
  #record-list td:nth-child(2) { flex: 0 0 auto; order: 1; font-size: 12px; color: var(--muted); } /* 日期 */
  /* ⚠️⚠️ 这里**不能**写 `td.wrap-col:first-of-type`（v366 首版就是这么写的，实测**一条都没匹配上**）：
     `:first-of-type` 是相对**元素类型** `td` 而言的 —— 本行第一个 `td` 是「全选」格（`.sel-col`），
     它不是 `.wrap-col` ⇒ 复合选择器永远不成立。
     实测（_probe_v366_recorder_dump.js，390×844）指标格拿到的是：
       order=0（与 .sel-col 同值）、flex-basis=100%（来自下面 ≤640px 块的 `flex: 1 1 100%`）
     ⇒ 指标名被挤成「独占一行」且排在全选格之后，而日期是 order:1 ⇒ 日期反而掉到指标名**下面**。
     用户看到的就是这个（「原有指标名称是在日期后的」）。
     改按**列序号**选中，并补回 flex 简写覆盖 ≤640px 的 100%。 */
  #record-list td:nth-child(3) { flex: 1 1 auto; order: 2; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } /* 指标名 */
  #record-list td:nth-child(6) { flex: 0 0 auto; order: 3; margin-left: auto; }   /* 状态 */
  #record-list td:nth-child(4) { flex: 1 1 auto; order: 5; }                      /* 数值 */
  #record-list td:nth-child(5) { flex: 0 0 auto; order: 6; font-size: 11px; }     /* 参考范围 */
  #record-list td:nth-child(7) { flex: 0 0 auto; order: 7; font-size: 11px; margin-left: auto; } /* 较上次 */
  /* 🆕 v366：严重度（第 8 列）跟在「较上次」之后，仍在行 2；`tr::after` 的断行在 order:8，
     而伪元素在 DOM 上排在所有子元素之后 ⇒ 同 order 时严重度在前、断行在后，行 2 不会被拆开。 */
  #record-list td:nth-child(8) { flex: 0 0 auto; order: 7; font-size: 11px; }     /* 严重度 */
  #record-list td:nth-child(9) { flex: 1 1 auto; order: 9; font-size: 11px; color: var(--muted); margin-top: 0; padding-top: 0; border-top: none; } /* 备注（左下角） */
  #record-list td.actions-col { flex: 0 0 auto; order: 10; margin-left: auto; width: auto; min-width: auto; display: inline-flex; flex-wrap: nowrap; align-items: center; gap: 4px; } /* 复/改/删一行 */
}

/* 🆕 v275：心理量表自评（PHQ-9 抑郁 / GAD-7 焦虑）——对标 CareClinic 2026「standardized assessments」 */
.assess-card .assess-toolbar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 8px; }
.assess-card .assess-lbl { font-size: 13px; color: var(--muted); }
.assess-card .assess-select { padding: 4px 8px; border-radius: 6px; border: 1px solid var(--line); background: var(--card); color: var(--ink); }
.assess-card .assess-new { margin-left: auto; padding: 5px 12px; border-radius: 6px; border: 1px solid var(--line); background: var(--accent, #5b8def); color: #fff; cursor: pointer; font-size: 13px; }
.assess-card .assess-empty { font-size: 13px; }
.assess-card .assess-history { margin: 6px 0 4px; }
.assess-card .assess-hist-head { font-size: 12px; color: var(--muted); margin-bottom: 4px; }
.assess-card .assess-row { display: flex; align-items: center; gap: 10px; padding: 4px 0; border-bottom: 1px dashed var(--line); font-size: 13px; }
.assess-card .assess-date { color: var(--muted); min-width: 92px; }
.assess-card .assess-score { font-variant-numeric: tabular-nums; font-weight: 600; }
.assess-card .assess-sev { padding: 1px 8px; border-radius: 999px; font-size: 12px; color: #fff; }
.assess-card .assess-sev.asc-min { background: #27ae60; }
.assess-card .assess-sev.asc-mild { background: #c9a227; }
.assess-card .assess-sev.asc-mod { background: #e67e22; }
.assess-card .assess-sev.asc-modsev { background: #e74c3c; }
.assess-card .assess-sev.asc-sev { background: #c0392b; }
.assess-card .assess-flag { color: #e74c3c; font-size: 12px; font-weight: 600; }
.assess-card .assess-trend { display: block; margin: 6px 0; }
.assess-card .assess-trend-val { font-size: 9px; fill: var(--ink); text-anchor: middle; }
.assess-card .assess-trend-date { font-size: 9px; fill: var(--muted); text-anchor: middle; }
.assess-card .assess-tip { font-size: 12px; margin: 4px 0; }
.assess-card .assess-form { margin-top: 8px; border: 1px solid var(--line); border-radius: 8px; padding: 10px; background: var(--card); }
.assess-card .assess-form-head { font-size: 13px; font-weight: 600; margin-bottom: 6px; }
.assess-card .assess-date-row { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; font-size: 13px; }
.assess-card .assess-date-row input { padding: 4px 6px; border-radius: 6px; border: 1px solid var(--line); background: var(--card); color: var(--ink); }
.assess-card .assess-q { padding: 6px 0; border-bottom: 1px dashed var(--line); }
.assess-card .assess-qn { font-size: 13px; margin-bottom: 4px; }
.assess-card .assess-opts { display: flex; flex-wrap: wrap; gap: 6px 14px; }
.assess-card .assess-opt { font-size: 12px; display: inline-flex; align-items: center; gap: 3px; cursor: pointer; }
.assess-card .assess-actions { display: flex; gap: 8px; margin-top: 10px; }
.assess-card .assess-save { padding: 6px 16px; border-radius: 6px; border: none; background: var(--accent, #5b8def); color: #fff; cursor: pointer; font-size: 13px; }
.assess-card .assess-cancel { padding: 6px 14px; border-radius: 6px; border: 1px solid var(--line); background: transparent; color: var(--ink); cursor: pointer; font-size: 13px; }
.assess-card .assess-safety { margin-top: 8px; padding: 8px 10px; border-radius: 8px; background: rgba(231,76,60,0.12); border: 1px solid #e74c3c; color: #e74c3c; font-size: 13px; line-height: 1.5; }

/* 🆕 v286 检验危急值提示（置顶红色卡片；无命中时 JS 置 display:none 整块隐藏） */
.critical-alert { display: none; margin: 0 0 10px; padding: 10px 12px; border-radius: 10px;
  background: #fff1f0; border: 1px solid #ffb3ad; border-left: 4px solid #d93025; }
.critical-alert .ca-head { font-weight: 700; color: #b3261e; font-size: 15px; margin-bottom: 6px; }
.critical-alert .ca-sub { font-weight: 400; font-size: 12px; color: #8a3b34; margin-left: 8px; }
.critical-alert .ca-item { padding: 7px 8px; border-radius: 8px; background: #fff; border: 1px solid #ffd6d2;
  margin-bottom: 6px; cursor: pointer; }
.critical-alert .ca-item:hover { border-color: #ff8a80; box-shadow: 0 1px 4px rgba(217, 48, 37, .18); }
.critical-alert .ca-line { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; }
.critical-alert .ca-name { font-weight: 600; color: #202124; }
.critical-alert .ca-val { font-weight: 700; color: #d93025; font-size: 15px; }
.critical-alert .ca-lim { font-size: 12px; color: #b3261e; background: #ffe9e7; border-radius: 4px; padding: 1px 6px; }
.critical-alert .ca-date { font-size: 12px; color: #70757a; margin-left: auto; }
.critical-alert .ca-msg { font-size: 12.5px; color: #5f3a36; margin-top: 3px; line-height: 1.5; }
.critical-alert .ca-note { font-size: 11.5px; color: #8a3b34; line-height: 1.5; margin-top: 4px; }
html[data-theme="dark"] .critical-alert { background: #3a1f1d; border-color: #7a2f28; border-left-color: #ff6b5e; }
html[data-theme="dark"] .critical-alert .ca-head { color: #ff9d94; }
html[data-theme="dark"] .critical-alert .ca-sub { color: #d9a5a0; }
html[data-theme="dark"] .critical-alert .ca-item { background: #2b1917; border-color: #6b2b25; }
html[data-theme="dark"] .critical-alert .ca-item:hover { border-color: #ff6b5e; box-shadow: none; }
html[data-theme="dark"] .critical-alert .ca-name { color: #ececec; }
html[data-theme="dark"] .critical-alert .ca-val { color: #ff8a7d; }
html[data-theme="dark"] .critical-alert .ca-lim { color: #ffb3ab; background: #4a2420; }
html[data-theme="dark"] .critical-alert .ca-date { color: #b0a3a1; }
html[data-theme="dark"] .critical-alert .ca-msg { color: #e0c9c6; }
html[data-theme="dark"] .critical-alert .ca-note { color: #c9a6a2; }

/* 🆕 v315 指标趋势设置悬浮弹窗：移动端默认 hidden，齿轮点击展开；桌面端始终显示（替换旧 .chart-toolbar-bottom） */
.chart-settings-pop {
  position: absolute; top: 8px; right: 50px; z-index: 5;
  min-width: 280px; max-width: calc(100% - 70px);
  background: #fff; border: 1px solid var(--line); border-radius: 10px;
  box-shadow: 0 6px 20px rgba(0,0,0,.14);
  padding: 10px 12px;
  display: flex; flex-direction: column; gap: 8px;
}
html[data-theme="dark"] .chart-settings-pop { background: #1c2733; border-color: #3b4a5c; box-shadow: 0 6px 20px rgba(0,0,0,.5); }
.chart-settings-pop[hidden] { display: none; }
.chart-settings-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.chart-settings-head b { font-size: 14px; color: var(--ink); }
.chart-settings-body { display: flex; flex-direction: column; gap: 6px; }
.chart-settings-body .ctrl { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.chart-settings-body .ctrl label { color: var(--muted); font-size: 13px; }
.chart-settings-body .chart-type-ctrl { gap: 8px; }
.chart-settings-body .chart-range-ctrl { flex: 1 1 100%; flex-wrap: wrap; gap: 6px; }
.chart-settings-body .chart-range-ctrl > label { order: 1; flex: 0 0 auto; }
.chart-settings-body .chart-range-ctrl #range-start { order: 2; }
.chart-settings-body .chart-range-ctrl #range-end { order: 4; }
.chart-settings-body .chart-range-ctrl input[type="date"] { min-width: 0; flex: 1 1 0; font-size: 12px; padding: 6px 8px; border: 1px solid var(--line); border-radius: 8px; }
.chart-settings-body .chart-range-ctrl > span:not(.range-presets) { order: 3; flex: 0 0 auto; }
.chart-settings-body .chart-range-ctrl #btn-range-clear { order: 5; flex: 0 0 auto; }
.chart-settings-body .chart-range-ctrl .range-presets { display: inline-flex; gap: 4px; order: 6; flex: 1 1 100%; justify-content: flex-end; }
.chart-settings-body select { padding: 6px 8px; border: 1px solid var(--line); border-radius: 8px; font-size: 13px; color: var(--ink); background: #fff; cursor: pointer; }
/* 桌面端弹窗改为「齿轮下拉」（🆕 v366 用户第 4 条①）─────────────────────────
   用户原话：「网页版的脉谱健康没有同步修改，需要把设置项隐藏到指标趋势图方框内的设置图标内」，
   并给了截图（设置项以 320px 宽竖条常驻在图表左上方）。
   ── 历史（为什么原来是「常显工具条」）──
   v315 起注释宣称「桌面端常显」，v340 用 JS 摘 `hidden` 属性把它**真的**实现了（此前一直是空话），
   代价就是图片里那个形态：齿轮被 `display:none` 藏掉、面板 `position:static` 常驻占位。
   _probe_v366_chartui.js 实测（1280×900）：gear display=none / pop position=static x=106 y=120 w=320 h=304。
   ── 现在 ──
   与手机端统一为「图标 + 下拉」：绝对定位在 `.chart-box` 内、紧贴工具组下方、右对齐。
   ⚠️ **默认收起不能靠 CSS**：`<div id="chart-settings-pop" hidden>` 的 `hidden` 在 UA 样式表里是
      `display:none !important`，任何作者规则都压不过（v340 已实测三次）。所以这里只写「展开时」的样式，
      收起态由 JS 保持 `hidden` 属性 —— 见 js/app.js 的 syncChartSettingsVisibility()。 */
@media (min-width: 901px) {
  .chart-settings-pop {
    top: 50px; right: 8px; left: auto;
    min-width: 300px; max-width: 460px;
    box-shadow: 0 8px 24px rgba(0,0,0,.16);
    border: 1px solid var(--line);
  }
  html[data-theme="dark"] .chart-settings-pop { box-shadow: 0 8px 24px rgba(0,0,0,.55); }
  /* 头部（「指标趋势设置」+ ✕）在桌面端**保留**：下拉形态下它是唯一的关闭按钮，
     被隐藏会让用户只能靠点空白处关闭（v340 曾把头部整个藏掉，那是为「工具条」形态服务的）。 */
}
/* 小屏（如 901 以下）弹窗显示时占据主视觉位置（紧贴齿轮下方），不要溢出右侧 */
@media (max-width: 900px) {
  .chart-settings-pop { left: 8px; right: 8px; max-width: none; }
}

/* 🆕 v315 指标库「添加指标」悬浮弹窗：移动端默认 hidden，点击「＋ 添加指标」展开；桌面端可视为弹窗亦常显 */
.ind-add-pop {
  margin-top: 10px; padding: 12px 14px;
  background: #f6fbf7; border: 1px solid #bfeacd; border-radius: 10px;
  display: flex; flex-direction: column; gap: 8px;
}
html[data-theme="dark"] .ind-add-pop { background: rgba(47,191,131,.1); border-color: rgba(47,191,131,.3); }
.ind-add-pop[hidden] { display: none; }
.ind-add-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.ind-add-head b { font-size: 14px; color: var(--ink); }
.ind-add-pop .form-inline { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.ind-add-pop input[type="text"], .ind-add-pop input[type="number"] {
  padding: 6px 8px; border: 1px solid var(--line); border-radius: 8px; font-size: 13px;
  background: #fff; color: var(--ink);
}
html[data-theme="dark"] .ind-add-pop input[type="text"],
html[data-theme="dark"] .ind-add-pop input[type="number"] { background: #161b22; color: #e6edf3; }
.ind-add-pop input[type="color"] {
  width: 36px; height: 32px; border: 1px solid var(--line); border-radius: 8px;
  background: #fff; padding: 2px; cursor: pointer;
}

/* ══════ 🆕 v287 指标趋势置顶重构 ══════ */
/* 图表方框：包住 #chart；齿轮设置按钮悬浮在方框内右上角（仅图标，用户要求去掉「设置」两字） */
.chart-box { position: relative; }
.chart-gear {
  position: absolute; top: 8px; right: 8px; z-index: 6;
  width: 34px; height: 34px; border-radius: 50%;
  border: 1px solid var(--line); background: rgba(255,255,255,.92);
  font-size: 16px; line-height: 1; cursor: pointer; color: var(--ink);
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 1px 4px rgba(0,0,0,.12);
}
.chart-gear:hover { border-color: var(--primary); }
/* 🆕 v449（用户请求 D 第 3 条）：全屏按钮（⛶）激活态 —— 与设置按钮 is-on 同款 */
.chart-gear.is-on { border-color: var(--primary); color: var(--primary); background: rgba(52,120,246,.12); }
html[data-theme="dark"] .chart-gear { background: rgba(36,49,64,.92); color: #e6edf3; border-color: #3b4a5c; }
html[data-theme="dark"] .chart-gear.is-on { color: #7aa2ff; border-color: #7aa2ff; background: rgba(90,140,255,.18); }
/* ── 🆕 v366（用户第 4 条① + 第 5 条）：图表方框右上角工具组「＋ | ⚙️」 ──────────
   ① 齿轮**不再在桌面端隐藏**。历史上这里有一条 `@media (min-width:901px){ .chart-gear{display:none} }`，
      理由（v271~v340）是「桌面端设置面板常显、不需要齿轮」。用户第 4 条明确要求
      「把设置项隐藏到指标趋势图方框内的设置图标内」⇒ 桌面端也必须**有**这个图标，故整条删除。
      ⚠️ 顺带说明：删掉它之后桌面端并不会「两个入口」，因为 v366 已同步把 JS 的
         「桌面端常显（摘 hidden）」逻辑去掉（见 js/app.js 的 syncChartSettingsVisibility）。
   ② 新增 ＋（添加指标）按钮，位置在设置齿轮**左边**（用户第 5 条）。
      用 flex 容器统一承载两者，避免手写 right 偏移在不同断点（齿轮 34px / ≤640px 时 20px）下错位。
      ＋ 直接用 .chart-gear 的外观（同尺寸同圆形），语义上仍是按钮，故保留 aria-haspopup。 */
/* 🆕 v388（用户第 1 项①）：工具组的 top/right 由 8px 改为 23px / 15px，与「📊 指标库」窗口
   标题行右侧的问号对齐（两处标题行到窗口边缘的距离由此一致）。
   ── 15px 怎么来的（_probe_v388_align.js 实测，不是估的）──
     #card-ind-lib .hint-q 右缘 407，卡片右缘 422 ⇒ 指标库标题行右侧元素距窗口 15px；
     .card 的 padding-right 14 + 边框 1 = 15，即「与卡片内容右缘齐平」。
   ── 23px 怎么来的 ──
     指标库 .card-head 高 36、自卡片顶 15px 起 ⇒ 组内图标垂直中心 = 卡片顶 + 33；
     .chart-tools 高 26（🆕 v417 统一口径）⇒ top = 33 - 13 = 20。（ECharts 标题 top 同步 21，见 js/app.js） */
.chart-tools { position: absolute; top: 20px; right: 15px; z-index: 6; display: flex; align-items: center; gap: 6px; }
/* 🆕 v388：两端基准不同 ⇒ 必须各给一套（实测数据见 js/app.js 的 title 配置注释）。
     手机（≤640px）：.card 内边距 14(+1 边框) ⇒ 右距 15；.card-head 高 36、自卡片顶 15px 起
                     ⇒ 标题行中心在卡片顶 +33，图标高 20 ⇒ top 23。
     桌面（≥641px）：内边距 16(+1) ⇒ 右距 17；.card-head 高 26、自卡片顶 17px 起
                     ⇒ 中心在卡片顶 +30 ⇒ top 20。
   ⚠️ 断点必须用 640/641（与 .card 的 padding 媒体查询同一条），不要写成 900/901。 */
@media (min-width: 641px) { .chart-tools { top: 17px; right: 17px; } }   /* 🆕 v417：中心 30 − 13 */
/* 组内按钮取消各自的绝对定位，交给 .chart-tools 排版（其后的 body.chart-fullscreen 规则也要一并覆盖） */
.chart-tools .chart-gear { position: static; top: auto; right: auto; }
/* ＋ 的下拉菜单直接复用 css/scan.css 的 .scan-add-menu（本就是 position:absolute + top:100%+6 + right:0），
   挂在 .chart-tools 这个绝对定位容器下即可对齐，不重复写一份定位。 */
/* 全屏查看模式下整组工具悬浮到视口右上角（#panel-trend 已 position:fixed） */
body.chart-fullscreen .chart-tools { position: fixed; top: 10px; right: 10px; }
body.chart-fullscreen .chart-tools .chart-gear { position: static; top: auto; right: auto; }

/* 🆕 v449（用户请求 D 第 3 条）：时间范围从设置弹窗移到曲线图上沿左端 */
.chart-range-bar {
  display: flex; align-items: center; flex-wrap: wrap; gap: 6px;
  margin: 0 0 6px; padding: 2px 2px 0;
  font-size: 12px; color: var(--muted);
}
.chart-range-bar > label { flex: 0 0 auto; white-space: nowrap; }
.chart-range-bar input[type="date"] {
  flex: 0 1 auto; min-width: 0; font-size: 12px; padding: 4px 6px;
  border: 1px solid var(--line); border-radius: 8px; background: #fff; color: var(--ink);
}
.chart-range-bar > span:not(.range-presets) { flex: 0 0 auto; }
.chart-range-bar .range-presets { display: inline-flex; gap: 4px; margin-left: auto; }
html[data-theme="dark"] .chart-range-bar input[type="date"] { background: #1c2733; color: #e6edf3; border-color: #3b4a5c; }

/* 🆕 v449（用户请求 D 第 1 条）：图例浮窗（点右上角 🩺💊📌 圆钮弹出），三行图例 + 各行 ✏️ 编辑按钮 */
.tl-legend-pop {
  position: absolute; top: 54px; right: 8px; z-index: 6;
  min-width: 248px; max-width: calc(100% - 16px);
  background: #fff; border: 1px solid var(--line); border-radius: 10px;
  box-shadow: 0 6px 20px rgba(0,0,0,.14);
  padding: 10px 12px;
}
.tl-legend-pop[hidden] { display: none; }
html[data-theme="dark"] .tl-legend-pop { background: #1c2733; border-color: #3b4a5c; box-shadow: 0 6px 20px rgba(0,0,0,.5); }
.tl-legend-pop .tl-legend-groups { margin: 0; }
/* 🆕 v483：浮窗内「📷 导入检验报告」入口（＋ 的原跳转功能收进这里），整行宽、与图例行留一档间距 */
.tl-import-btn { width: 100%; margin-top: 8px; }

/* 图例三圆钮（🩺💊📌）与工具图标之间的分隔线 */
.chart-tools-sep { width: 1px; height: 20px; background: var(--line); flex: 0 0 auto; margin: 0 2px; }

/* 图例三圆钮的激活态（浮窗展开时）—— 与全屏/设置按钮 is-on 同款 */
.chart-gear.tl-toggle.is-on { border-color: var(--primary); color: var(--primary); background: rgba(52,120,246,.12); }
html[data-theme="dark"] .chart-gear.tl-toggle.is-on { color: #7aa2ff; border-color: #7aa2ff; background: rgba(90,140,255,.18); }

/* ══════ 🆕 v453（用户请求 3）：手机版把「图例三圆钮 + 时间范围」收进 ⚙️ 设置弹窗 ══════
   用户原话：「手机版的指标趋势右上角的图标和时间设置还放回设置按钮，大屏版的保留。」
   DOM 由 js/app.js 的 syncTrendMobileDock() 按 640px 断点移动（appendChild，id 与监听不变）；
   这里只负责：①手机版藏掉三圆钮与其后的分隔线（设置弹窗里已有图例与时间范围的常驻入口）；
   ②弹窗内承载两个外来块的分隔样式；③弹窗内容变高后限高滚动（手机版弹窗是全宽浮层）。 */
@media (max-width: 640px) {
  .chart-tools .tl-toggle,
  .chart-tools .chart-tools-sep { display: none; }
}
#chart-settings-pop .chart-range-bar {
  margin: 2px 0 0; padding: 8px 2px 0;
  border-top: 1px dashed var(--line);
}
#chart-settings-pop .tl-legend-groups {
  margin: 2px 0 0; padding: 8px 0 0;
  border-top: 1px dashed var(--line);
}
#chart-settings-pop { max-height: calc(100vh - 110px); overflow-y: auto; }

/* 🆕 v457：图片识别标题旁的数量徽标（当前患者检验单图片张数，去重后；var 自适应深浅色） */
.scan-count {
  margin-left: 4px; padding: 1px 8px;
  border-radius: 10px; border: 1px solid var(--line, #e3e8ee);
  font-size: 12px; font-weight: 600; line-height: 1.6;
  color: var(--muted, #8593a3); background: var(--panel, #f1f4f8);
  white-space: nowrap;
}

/* 🆕 v557（用户 2026-10-28 第 3 项）：「图片识别窗口中的数值放到标题行之下吧，
   留下刷新、搜索和栗子按钮」⇒ 「共N张 / N/M指标」两枚徽标从 .card-head 移入本行。
   卡头现在只放 标题 + ↻ + 🔍 + 🌰（🌰 由 hintsToCorner 追加在末尾），
   徽标单独成行 ⇒ 窄屏（390px）也不会因为多两枚胶囊把 🌰 挤到第二行。 */
.scan-stats-row {
  display: flex; align-items: center; gap: 8px;
  flex-wrap: wrap; margin: 0 0 6px;
}
.scan-stats-row .scan-count { margin-left: 0; }

/* 指标趋势「显示指标」窗口：改为检验记录「指标库式」固定高度滚动窗口（高≈宽，窗口内滚动），chips 变整行 */
.ind-lib-scroll { display: block; overflow-y: auto; overscroll-behavior: contain;
  border: 1px solid var(--line); border-radius: var(--radius); background: #fff; padding: 6px; max-height: 260px; }
html[data-theme="dark"] .ind-lib-scroll { background: #1c2733; }
.ind-lib-scroll .ind-group { margin: 0 0 6px; }
.ind-lib-scroll .ind-group:last-child { margin-bottom: 0; }
.ind-lib-scroll .ind-group-title { font-size: 12px; color: var(--muted); margin: 2px 2px 4px; display: flex; align-items: center; gap: 6px; }
.ind-lib-scroll .chip { display: flex; width: 100%; border-radius: 10px; padding: 8px 10px; font-size: 13.5px; min-height: 38px; margin-bottom: 4px; }
.ind-lib-scroll .chip:last-child { margin-bottom: 0; }
.ind-lib-scroll .chip .swatch { width: 14px; height: 14px; border-radius: 4px; flex-shrink: 0; }

/* 个人基线：正方形滚动窗口（JS 按宽度设 max-height，此处给 CSS 兜底） */
.personal-baseline { overflow-y: auto; overscroll-behavior: contain; }

/* ── 🆕 v379（用户第 2 条）：**已删除**「指标趋势数据点操作弹窗」这一整组样式 ──────────
   用户原话「指标趋势页的指标趋势图中点击指标的时候，不需要这个弹窗了」，
   追问答复「什么都不做」+「删除 / 查看检验记录两个入口一并取消」
   ⇒ 逻辑侧（showRecActionModal / linkChartToRecord / _recActionEsc）已随本轮整体拆除，
     样式侧必须**同轮一起删**：留着就是「僵尸 CSS」—— 下次有人看到 `.ra-pen` 还在，
     会以为功能还在、甚至照着它去写新代码（本仓库有过这种教训）。
   ⚠️ 弹窗原来承担的「拿原图校对」能力没有丢，改由 `#trend-float` 悬浮窗右上角的 ✏️ 承担
      （样式见本文件末尾 `.trend-float` 一段；`gotoLabImage` / `findRecordSourceEntry` 全部保留）。
   ⚠️ 顺带作废的还有 v290 那条「tooltip z-index 要低于遮罩 1600」的相互约束 ——
      遮罩没了，约束自然消失（tooltip 现在只留一个空盒子，见 js/app.js 的 extraCssText）。 */

/* ── 🆕 v290：指标库窗口选中态改「绿色标亮」 ─────────────────────────
   用户要求：初次用绿色标亮 2 个指标（默认勾选当前分类前 2 个，配合绿色选中态一眼可辨）。
   只作用于 .ind-lib-scroll 指标库窗口（指标趋势页），不影响检验记录页表格与其他 chip。 */
.ind-lib-scroll .chip.on {
  background: #e9f9f0; color: #0f7a4d; border-color: #2fbf83;
  box-shadow: inset 0 0 0 1px #2fbf83;
}
.ind-lib-scroll .chip.on .star { color: #0f7a4d; }
html[data-theme="dark"] .ind-lib-scroll .chip.on {
  background: rgba(47, 191, 131, .16); color: #7ee2b8; border-color: #2f9d76;
  box-shadow: inset 0 0 0 1px #2f9d76;
}

/* ── 🆕 v293：指标库窗口（挪入指标趋势页）行勾选态 = 绿色标亮 ─────────
   点击行 = 勾选/取消画进指标趋势；绿色 = 已勾选。⭐️ 收藏金色。
   🆕 v300（用户反馈）：恢复 per-indicator 彩色 swatch 方块（与指标趋势同色）。
   选中时不再只染名称，而是给整行卡片加绿色底色（像检验记录 OCR 卡片）；
   名称文字保持深色，swatch/星星在绿色底上可见。
   释义/改/删三个按钮统一纯色绿、无边框（删不再红字）。 */
#indicator-list tr.ind-row.on td { background: #bfeacd; }
#indicator-list tr.ind-row.on td.wrap-col { color: var(--ink); font-weight: 600; box-shadow: inset 3px 0 0 #2fbf83; }
#indicator-list tr.ind-row.on .ind-name { background: transparent; color: var(--ink); padding: 0; }
#indicator-list .star { cursor: pointer; user-select: none; margin-right: 6px; color: #c4cbd4; font-size: 14px; }
#indicator-list .star.on { color: #f0a93b; }
/* ── 🆕 v366（用户第 6 条）：指标库恢复「指标名前的彩色色块」 ──────────────────
   用户原话：「指标库中的指标之前原有的色块需要恢复，全是文字在阅读时会视觉疲劳。」
   尺寸/圆角/间距直接沿用通用 .swatch（css/styles.css 178 行：12×12 / r3 / margin-right 6 / inline-block），
   这里只补两点：
     ① flex-shrink:0 —— 行内是 flex 布局（.ind-lib-scroll 起就是），窄屏下色块不许被压扁；
     ② 描边 —— 色块色值取自 ind.color（浅色如 #f1c40f 在白底/绿底上会「糊」掉，加一层 8% 黑描边定型；
        深色主题反过来用 22% 白色描边）。
   ⚠️ 需求史：v287 有 → v295 删 → v300 恢复（只加了注释）→ v303 删元素 → v366 按用户要求恢复。
      下次若要再删，请连同 _e2e_v287 的 C1 断言一起改，别只删这一处（v303 就漏了断言改法）。 */
#indicator-list .swatch { flex-shrink: 0; box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .08); }
html[data-theme="dark"] #indicator-list .swatch { box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .22); }
html[data-theme="dark"] #indicator-list tr.ind-row.on td { background: rgba(47, 191, 131, .32); }
html[data-theme="dark"] #indicator-list tr.ind-row.on td.wrap-col { color: var(--ink); box-shadow: inset 3px 0 0 #2f9d76; }
/* ── ⛔ v301~v356 的「释义/改/删纯色绿底白字」规则已于 v357 **整组撤除** ─────────────
   ⚠️ 这里只留注释、不留规则：v357 的图标系统（见文件末尾「v357 全软件行内图标统一」段）
      以 `.row-actions .btn.act-ico` 系列承载。若把旧绿底规则留着，它们带 ID 选择器
      （`#indicator-list .row-actions .btn` = (1,2,0)）会**压过**新规则（(0,4,0)）
      ⇒ 图标仍是绿底方块。这就是「新旧两套样式并存必然翻车」的典型，必须整段删除。
   历史：v301 起 释义/改/删 = 绿底白字；v299 起 检验记录 复/改/删 同款。
   用户 2026-09-17：「不要青绿色了，改也不要底色了，直接改成一个笔的图标」「删 = 红底白叉」。 */

/* ── 🆕 v295：用药照片（缩略图 / 放大灯箱，对标 Medisafe 2026 药丸照片） ──────── */
.med-photo-thumb, .tm-photo-thumb {
  width: 30px; height: 30px; object-fit: cover; border-radius: 6px;
  border: 1px solid #d6dbe2; cursor: pointer; vertical-align: middle; margin-left: 6px;
  background: #f0f2f5;
}
.tm-photo-thumb { margin-left: 8px; }
.med-photo-thumb:hover, .tm-photo-thumb:hover { border-color: #2f9d76; box-shadow: 0 0 0 2px rgba(47,157,118,.25); }
.med-photo-lightbox {
  position: fixed; inset: 0; z-index: 1700; display: flex;
  align-items: center; justify-content: center;
}
.med-photo-lightbox[hidden] { display: none; }
.med-photo-lightbox .mpl-backdrop { position: absolute; inset: 0; background: rgba(20,24,28,.72); }
.med-photo-lightbox .mpl-box {
  position: relative; z-index: 1; background: #fff; border-radius: 12px;
  padding: 14px; max-width: min(92vw, 460px); box-shadow: 0 18px 48px rgba(0,0,0,.35);
}
.med-photo-lightbox .mpl-box img { display: block; width: 100%; height: auto; border-radius: 8px; }
.med-photo-lightbox .mpl-actions { display: flex; gap: 8px; justify-content: flex-end; margin-top: 10px; }
html[data-theme="dark"] .med-photo-lightbox .mpl-box { background: #1f242b; }
html[data-theme="dark"] .med-photo-thumb, html[data-theme="dark"] .tm-photo-thumb { border-color: #3a4250; background: #232a32; }

/* 🆕 v305 多指标归一化叠加对比图 */
.ind-overlay { margin-top: 8px; padding: 10px 14px; border: 1px solid #dfe6ef; border-radius: 10px; background: #f6f9fc; font-size: 13px; }
.ind-overlay h3 { margin: 0 0 4px; font-size: 14px; color: #1f2d3d; }
.ind-overlay .ov-sub { color: #5a6573; font-size: 12.5px; line-height: 1.5; margin-bottom: 8px; }
.ind-overlay .ov-chart { width: 100%; height: 300px; }
html[data-theme="dark"] .ind-overlay { background: #161b22; border-color: #2a323c; color: #c7d0db; }
html[data-theme="dark"] .ind-overlay h3 { color: #e6edf3; }
html[data-theme="dark"] .ind-overlay .ov-sub { color: #9aa6b2; }

/* 🆕 v308 紧急医疗卡 */
.emergency-card { border: 1px solid #f3c0bd; border-left: 4px solid var(--danger); border-radius: 10px; background: #fff6f5; padding: 12px 14px; font-size: 13.5px; }
.ec-head { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.ec-name { font-size: 17px; font-weight: 700; color: #b03a36; }
.ec-tags { display: inline-flex; gap: 6px; flex-wrap: wrap; }
.ec-tag { display: inline-block; padding: 2px 8px; border-radius: 999px; background: #fdeceb; color: #b03a36; border: 1px solid #f3c0bd; font-size: 12px; }
.ec-tag.ec-blood { background: #fdeccf; color: #9a6b12; border-color: #f0d89a; }
.ec-note { background: #fff3cd; border: 1px solid #f0d89a; color: #7a5b10; border-radius: 6px; padding: 6px 10px; margin-bottom: 8px; font-size: 12.5px; }
.ec-sec { margin-top: 8px; }
.ec-sec-title { font-weight: 600; color: #1f2d3d; margin-bottom: 4px; font-size: 13px; }
.ec-list { margin: 0; padding-left: 18px; }
.ec-list li { margin: 2px 0; color: #2a3a4a; }
.ec-muted { color: #6b7a8d; font-size: 12px; }
.ec-none { color: #9aa6b2; list-style: none; margin-left: -18px; }
.ec-abn-high { color: #c0392b; }
.ec-abn-low { color: #1f6fb0; }
.ec-edit { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; margin-top: 12px; }
.ec-edit .ec-contact-label { flex: 1 1 240px; display: flex; flex-direction: column; gap: 4px; font-size: 12.5px; color: #5a6573; }
.ec-edit .ec-contact-label input { padding: 7px 10px; border: 1px solid var(--line); border-radius: 8px; font-size: 14px; background: #fff; color: var(--ink); }
html[data-theme="dark"] .emergency-card { background: #2a1c1c; border-color: #5a2a2a; border-left-color: #e5736f; }
html[data-theme="dark"] .emergency-card .ec-name { color: #ff9b8e; }
html[data-theme="dark"] .ec-tag { background: #3a2320; color: #ff9b8e; border-color: #5a2a2a; }
html[data-theme="dark"] .ec-tag.ec-blood { background: #3a2e12; color: #ffcf80; border-color: #5a4413; }
html[data-theme="dark"] .ec-note { background: #3a2e12; border-color: #5a4413; color: #ffcf80; }
html[data-theme="dark"] .ec-sec-title { color: #e6edf3; }
html[data-theme="dark"] .ec-list li { color: #c7d0db; }
html[data-theme="dark"] .ec-muted { color: #9aa6b2; }
html[data-theme="dark"] .ec-none { color: #6b7682; }
html[data-theme="dark"] .ec-abn-high { color: #ff7a6b; }
html[data-theme="dark"] .ec-abn-low { color: #6db3f2; }
html[data-theme="dark"] .ec-edit .ec-contact-label { color: #9aa6b2; }
html[data-theme="dark"] .ec-edit .ec-contact-label input { background: #1f242b; border-color: #3a4250; color: #e6edf3; }

/* 🆕 v320 系统健康概览卡片（按器官系统汇总最新检验状态） */
.sys-overview { margin: 14px 0; padding: 14px 16px; border: 1px solid var(--line); border-radius: 12px; background: #fff; }
.sys-overview .so-head { font-size: 15px; font-weight: 600; color: var(--ink); margin-bottom: 10px; }
.sys-overview .so-head .muted { font-weight: 400; font-size: 12.5px; margin-left: 6px; }
.sys-overview .so-chip { display: inline-flex; align-items: center; gap: 7px; margin: 0 8px 8px 0; padding: 7px 11px; border-radius: 999px; border: 1px solid var(--line); background: #f7f9fb; font-size: 13px; }
.sys-overview .so-ico { font-size: 14px; }
.sys-overview .so-title { font-weight: 600; color: var(--ink); }
.sys-overview .so-stat { color: #5a6573; }
.sys-overview .so-ok { border-color: #bfe3c8; background: #ecfaf0; }
.sys-overview .so-ok .so-stat { color: #2e8b57; }
.sys-overview .so-warn { border-color: #f1c9a5; background: #fff5ec; }
.sys-overview .so-warn .so-stat { color: #c8761a; }
html[data-theme="dark"] .sys-overview { background: #1f242b; border-color: #3a4250; }
html[data-theme="dark"] .sys-overview .so-head { color: #e6edf3; }
html[data-theme="dark"] .sys-overview .so-chip { background: #262d35; border-color: #3a4250; }
html[data-theme="dark"] .sys-overview .so-title { color: #e6edf3; }
html[data-theme="dark"] .sys-overview .so-stat { color: #9aa6b2; }
html[data-theme="dark"] .sys-overview .so-ok { background: #1c2e22; border-color: #2f5a3f; }
html[data-theme="dark"] .sys-overview .so-ok .so-stat { color: #7fd6a0; }
html[data-theme="dark"] .sys-overview .so-warn { background: #2e2418; border-color: #5a4413; }
html[data-theme="dark"] .sys-overview .so-warn .so-stat { color: #ffcf80; }

/* 🆕 v330 每日健康打卡（Daily Check-in）卡片 */
.daily-checkin { font-size: 13.5px; }
.dc-row { display: flex; align-items: center; gap: 10px; margin: 7px 0; }
.dc-label { width: 72px; color: #5a6573; font-size: 13px; flex: none; }
.dc-stars { display: inline-flex; gap: 2px; }
.dc-star { background: none; border: none; cursor: pointer; font-size: 20px; line-height: 1; color: #c4ccd6; padding: 0 1px; transition: color .12s; }
.dc-star:hover { color: #f0a020; }
.dc-star.on { color: #f0a020; }
.dc-note { flex: 1; min-width: 0; padding: 7px 10px; border: 1px solid var(--line); border-radius: 8px; font-size: 14px; background: #fff; color: var(--ink); }
.dc-actions { margin: 8px 0; display: flex; align-items: center; gap: 10px; }
.dc-saved { color: #2e9e5b; font-size: 12.5px; }
.dc-heat-head { margin-top: 12px; font-weight: 600; color: #1f2d3d; font-size: 13px; }
.dc-heat { display: flex; flex-wrap: wrap; gap: 3px; margin: 8px 0; max-width: 100%; }
.dc-cell { width: 13px; height: 13px; border-radius: 3px; background: #eef1f5; display: inline-block; }
.dc-cell.dc-low { background: #f3b0a8; }
.dc-cell.dc-mid { background: #f6d58a; }
.dc-cell.dc-good { background: #a9d8a0; }
.dc-cell.dc-great { background: #6fc08a; }
.dc-legend { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; font-size: 12px; color: #6b7a8d; margin-top: 4px; }
.dc-legend .dc-cell { width: 12px; height: 12px; }
html[data-theme="dark"] .daily-checkin { color: #c7d0db; }
html[data-theme="dark"] .dc-label { color: #9aa6b2; }
html[data-theme="dark"] .dc-star { color: #5a6470; }
html[data-theme="dark"] .dc-star:hover { color: #f0a020; }
html[data-theme="dark"] .dc-star.on { color: #f0a020; }
html[data-theme="dark"] .dc-note { background: #1f242b; border-color: #3a4250; color: #e6edf3; }
html[data-theme="dark"] .dc-heat-head { color: #e6edf3; }
html[data-theme="dark"] .dc-cell { background: #2c3744; }
html[data-theme="dark"] .dc-cell.dc-low { background: #7a3b34; }
html[data-theme="dark"] .dc-cell.dc-mid { background: #6a5523; }
html[data-theme="dark"] .dc-cell.dc-good { background: #3a5a32; }
html[data-theme="dark"] .dc-cell.dc-great { background: #2f6b48; }
html[data-theme="dark"] .dc-legend { color: #9aa6b2; }

/* 🆕 v331 每日打卡趋势迷你折线 */
.dc-trend-head { margin-top: 14px; font-weight: 600; color: #1f2d3d; font-size: 13px; }
.dc-trend { display: flex; flex-direction: column; gap: 7px; margin-top: 6px; }
.dc-trend-row { display: flex; align-items: center; gap: 8px; }
.dc-trend-label { width: 72px; flex: none; font-size: 13px; color: #5a6573; }
.dc-spark { flex: 1 1 auto; min-width: 0; display: block; }
.dc-spark-svg { display: block; }
.dc-spark-svg polyline { stroke: #3b82c4; }
.dc-spark-svg circle { fill: #3b82c4; }
.dc-trend-last { width: 40px; flex: none; text-align: right; font-size: 13px; color: #6b7a8d; }
.dc-spark-empty { font-size: 12px; color: #9aa6b2; }
html[data-theme="dark"] .dc-trend-head { color: #e6edf3; }
html[data-theme="dark"] .dc-trend-label { color: #9aa6b2; }
html[data-theme="dark"] .dc-spark-svg polyline { stroke: #6fb3e0; }
html[data-theme="dark"] .dc-spark-svg circle { fill: #6fb3e0; }
html[data-theme="dark"] .dc-trend-last { color: #9aa6b2; }
html[data-theme="dark"] .dc-spark-empty { color: #6b7a8d; }

/* 🆕 v333 症状严重度趋势迷你折线 */
.symptom-trend-card { margin-top: 12px; padding-top: 10px; border-top: 1px dashed #e5ebf3; }
.symptom-trend-card h3 { margin: 0 0 4px; font-size: 15px; color: #1f2d3d; }
.st-spark-wrap { margin-top: 8px; }
.st-spark-svg { display: block; }
.st-spark-svg polyline { stroke: #c0392b; }
.st-spark-svg circle { fill: #c0392b; }
.st-spark-empty { font-size: 12px; color: #9aa6b2; }
.st-latest { margin-top: 6px; font-size: 13px; color: #5a6573; }
.st-better { color: #27ae60; font-weight: 600; }
.st-worse { color: #c0392b; font-weight: 600; }
.st-flat { color: #6b7a8d; }
html[data-theme="dark"] .symptom-trend-card { border-top-color: #2d3946; }
html[data-theme="dark"] .symptom-trend-card h3 { color: #e6edf3; }
html[data-theme="dark"] .st-spark-svg polyline { stroke: #e07a6f; }
html[data-theme="dark"] .st-spark-svg circle { fill: #e07a6f; }
html[data-theme="dark"] .st-latest { color: #9aa6b2; }
html[data-theme="dark"] .st-spark-empty { color: #6b7a8d; }

/* ============================================================
   🆕 v341「示例患者」只读预览模式
   ------------------------------------------------------------
   用户需求：点「示例」后各页面显示示例患者数据；软件边框做「窄边渐变磨砂纸」覆盖效果
   示意这不是原患者数据；上沿加悬浮按钮显示「示例患者」；可返回原患者与原页面。

   ⚠️ 为什么用 4 条细边而不是 `mask-composite: exclude` 挖空整块：
      老 WebView（雷电 = Chrome/91）对 `mask-composite` 支持不齐，
      一旦 mask 不生效，`backdrop-filter` 会**把整个视口糊成毛玻璃**、应用直接不可用。
      四条细边没有这个风险，且四角颜色能衔接成环。
   ⚠️ 显隐一律由 JS 摘/加 `hidden` 属性控制（UA 的 `[hidden]{display:none !important}` 压过作者样式，
      所以下面 `.demo-banner[hidden]` 只是给老 WebView 的保险，别指望它来「显示」元素）。 */

/* 「示例」按钮挪到卡片右上角、❓ 的左边。
   ❓（.hint-q）是 JS 生成、绝对定位于 right:8px / 宽 20px ⇒ 本按钮 right = 8 + 20 + 6 = 34px。
   🆕 v357：❓ 统一放大到 26×26（用户「软件中的问号都统一大小」）⇒ right 同步改为 8 + 26 + 6 = 40px，
      否则 26px 的问号会向右溢出 6px、与「示例」按钮叠在一起。 */
.card-corner-btn {
  position: static; z-index: 4;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* ⚠️ v391 订正：本类原先写死 `position:absolute; top:8px; right:40px`（right 还是按"❓ 宽 26 + 间距 6"
   反推的魔法值），而它所在卡片**没有 .card-head** ⇒ 既有的「右上角按钮与标题同高」（本文件「需求 3②」）
   覆盖不到它：实测 ❓ 中心 19px vs 标题中心 26.5px（**高 7.5px**，用户 2026-09-22 报的"不齐"）。
   现在该卡片改用具名 `.card-head`，本按钮与 🔍 / ❓ 一起回到普通流、由 flex 居中 ⇒ 没有魔法像素值。 */

/* ── v391（用户第 2 项）：「🧪 示例 / 🔍 / ❓」与左侧标题**同高**，并排在卡片右上角 ──
   为什么 .card-head 就够：它是 flex + align-items:center（227 行），标题与三个控件自动共中线；
   这也是 #card-ind-lib / #card-med-list / #panel-lab 的既有做法，不新造机制。
   为什么还要 justify-content:flex-start + h2 margin-right:auto：
     .card-head 默认 space-between，本头有 4 个子元素（h2 / 示例 / 🔍包裹 / ❓）时中间的会被摊到正中，
     右上角按钮组就散开了 —— 与「需求 2①」修指标库时踩到的是同一个坑。 */
#lab-entry-image > .card > .card-head { justify-content: flex-start; gap: 6px; }
#lab-entry-image > .card > .card-head > h2 { margin-right: auto; }
#lab-entry-image > .card > .card-head > .btn,
#lab-entry-image > .card > .card-head > .scan-add-wrap,
#lab-entry-image > .card > .card-head > .hint-q { flex: 0 0 auto; }
/* 🔍 与角落 ❓ 同尺寸（20×20 圆形图标钮，见本文件 3676 行「问号 / 齿轮同尺寸」那组规则），
   两者靠 `.hint-q-inline` 自带的 margin-left:6px 并排。
   ⚠️ `min-height:20px` 不能省：手机段（max-width:640px）里 `.btn.tiny{min-height:36px}`（1578 行）
     会把只写了 `height:20px` 的按钮撑成 **20×36 的椭圆**（首版实测就是 20×36，
     `_probe_v391_item2.js` 的 findSize 抓到的）。宁可显式压掉，也不赌 base 规则。
     问号本身（.hint-q）也是 20×20 —— 两者严格同尺寸才符合用户「问号统一大小」的要求。 */
#lab-entry-image #btn-scan-find {
  width: 26px; height: 26px; min-width: 26px; min-height: 26px; padding: 0; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 13px; line-height: 1;
}
.card-corner-btn.is-on { color: #fff; background: #0e7c86; border-color: #0e7c86; }

/* 上沿悬浮条：显示「示例患者」，点击也返回。
   演示模式下给 header 加 padding-top，把这条「挂」在 header 上沿的空白里，
   否则它会压住页眉里的 🩺 图标与页签（页签是页面主入口，绝不能被挡）。 */
.demo-banner {
  position: fixed; top: 0; left: 50%; transform: translateX(-50%); z-index: 381;
  display: inline-flex; align-items: center; gap: 6px;
  max-width: calc(100vw - 20px); padding: 5px 14px 6px;
  border: 1px solid rgba(255, 255, 255, .38); border-top: 0; border-radius: 0 0 12px 12px;
  font-size: 12.5px; font-weight: 700; line-height: 1.4; white-space: nowrap;
  color: #fff; background: linear-gradient(90deg, #0e7c86, #7a5ac8 55%, #d66c2d);
  box-shadow: 0 6px 18px rgba(20, 40, 60, .28); cursor: pointer;
}
.demo-banner[hidden] { display: none; }
.demo-banner:active { transform: translateX(-50%) translateY(1px); }
body.demo-patient-mode .app-header { padding-top: 30px; }
/* 🆕 v533（用户需求 6）：手机版首页的页眉壳高度必须归 0（见文件前部 v533 段）——
   本条 (0,3,1) 压过上行 (0,2,1)，否则示例模式下首页会残留一条 30px 蓝带。 */
body.demo-patient-mode[data-tab="home"] .app-header { padding-top: 0; }

/* 窄边渐变磨砂边框。
   backdrop-filter 让边框覆盖住的那几像素产生「磨砂纸」的毛玻璃质感；
   ::after 再叠一层极淡横向细纹，强化「纸」的观感（纯渐变会像普通描边）。 */
.demo-frame { position: fixed; inset: 0; z-index: 380; pointer-events: none; }
.demo-frame[hidden] { display: none; }
.demo-frame > i {
  position: absolute; display: block;
  -webkit-backdrop-filter: blur(3px) saturate(1.3);
  backdrop-filter: blur(3px) saturate(1.3);
}
.df-top    { left: 0; right: 0; top: 0;    height: 6px; background: linear-gradient(90deg,  rgba(14, 124, 134, .78), rgba(122, 90, 200, .78)); }
.df-right  { top: 0; bottom: 0; right: 0;  width: 6px;  background: linear-gradient(180deg, rgba(122, 90, 200, .78), rgba(214, 108, 45, .78)); }
.df-bottom { left: 0; right: 0; bottom: 0; height: 6px; background: linear-gradient(90deg,  rgba(22, 163, 163, .78), rgba(214, 108, 45, .78)); }
.df-left   { top: 0; bottom: 0; left: 0;   width: 6px;  background: linear-gradient(180deg, rgba(14, 124, 134, .78), rgba(22, 163, 163, .78)); }
/* 细纸纹只铺在**四条窄边内部**（挂在 i 上、而非挂在 .demo-frame 上）。
   ⚠️ 不能把这条纹路挂在 .demo-frame 上再 inset:0 —— 那会**整屏**铺一层极淡白纱，
   深色主题下肉眼可见地发灰（内容被整体冲淡），而用户要的是「窄边」磨砂纸效果。 */
.demo-frame > i::after {
  content: ''; position: absolute; inset: 0; pointer-events: none; opacity: .55;
  background: repeating-linear-gradient(0deg,
    rgba(255, 255, 255, .10) 0 1px, rgba(255, 255, 255, 0) 1px 3px);
}

/* ---------- 🆕 v341：「文件识别」页签里的 CSV 导入行 ---------- */
.file-csv-row {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  margin-top: 14px; padding-top: 14px; border-top: 1px dashed var(--line);
}
.file-csv-row .hint { flex: 1 1 200px; font-size: 12px; }

/* =====================================================================================
   🆕 v343：布局改版
     ① 档案页：患者列表提到最上方，「患者档案」折叠进患者窗口右上角 ✎（「当前」徽标左边）
     ② 日常测量页：底部收留「每日健康打卡」
     ③ 用药记录页：卡片头按钮（＋添加用药 / 📤导出用药记录 / ?）、表单下拉、
                    用药记录表手机端卡片化（对齐 #record-list）
     ④ 检验记录页：工具栏压成一排、卡片头按钮右聚、「指标」筛选换行
   全部只动布局与显隐，不碰任何数据口径（导出列、参考范围判定、依赖统计一律原样）。
   ===================================================================================== */

/* ---------- ① 患者档案弹窗（🆕 v512 用户第 6 项：「要像其他弹窗一样做美化，文字放到编辑窗口内」） ----------
   ── 改前：这里是「患者列表卡片内的行内折叠区」—— `.profile-edit` 自带 `margin-top:12px` +
       `padding-top:12px` + `border-top:1px dashed`，另有一条 `@keyframes peDrop` 下拉动效和
       `.pe-head` 标题行（「🪪 患者档案 + [收起 ▴]」）；表单说明文字写在窗口**外**的卡片 `p.hint` 里。
   ── 改后：`#profile-edit` 本身就是 `.modal.def-modal`（见 index.html），外观全部由既有的
       `.def-popup-content` / `.def-close` / `.def-body` / `.med-edit-note` 承担 ——
       与 `#med-add-modal`（添加用药）、`#med-edit-modal`（修改用药）逐项同族，暗色主题零新增规则。
   ⚠️ 那套卡内样式必须**整段删掉而不是留着**：一旦 `.profile-edit{margin-top/padding-top/border-top}`
      还挂着，它会作用在弹窗最外层 `.modal` 上 —— 圆角卡外面多出一圈虚线、并与遮罩边缘错位。
   ⚠️ `@keyframes peDrop` 与 `.profile-edit[hidden]{display:none}` 一并删除：
      · 弹窗自带 `defFadeIn`（`.def-popup-content` 上），再来一层下拉动效是重复动效；
      · 显隐由 UA 的 `[hidden]{display:none!important}` + `.def-modal{display:none}` 共同保证，
        不需要作者再补一条（补了也是死代码）。
   ⚠️ 只改「容器」这一层：字段 id、`#form-profile`（含 `.form-grid` 类）、`#btn-delete-profile`
      一律原样 ⇒ `.form-grid` 的两列栅格、`.span2` 跨列、输入框外观全部沿用旧观感。 */
.profile-edit-pop { width: min(520px, 94vw); }
.profile-edit-pop .def-body { overflow-y: auto; padding: 14px 18px 16px; }
/* 表单在卡片里时靠 margin-top 与上方提示分隔，进弹窗后上方已是 .med-edit-note，不需要再留 */
.profile-edit-pop #form-profile { margin-top: 0; }
/* 底部按钮行右聚：与 `.med-add-pop .def-foot`（取消 / 确定添加）同一处排布规范 */
.profile-edit-pop #form-profile > .span2:last-child { display: flex; justify-content: flex-end; gap: 8px; }

/* ---------- ③ 用药录入表单：默认收起，点「＋ 添加用药」下拉 ---------- */
/* ⚠️ 收起态走的是 **HTML 的 hidden 属性**（JS 摘/加），不是这里的一条 CSS ——
   `[hidden]` 是 UA 的 `display:none !important`，作者样式压不过它，
   写 `.med-form[hidden]{display:grid}` 是**死代码**（v340 已栽过一次）。
   这里只负责「展开那一刻」的下拉动效。 */
.med-form { animation: medDrop .2s ease-out; }
@keyframes medDrop {
  from { opacity: 0; transform: translateY(-8px); }
  to   { opacity: 1; transform: none; }
}

/* ---------- ③④ 卡片头里有多枚按钮时：h2 吃掉剩余空间，按钮右聚 ---------- */
/* .card-head 默认 justify-content: space-between —— 一旦子元素 ≥3 个（h2 + 2 按钮 + ?）
   就会把按钮**摊开**（中间的跑到居中位置），而用户要的是「导出用药记录紧挨在问号左边」。
   改法：改成 flex-start + 给 h2 一个 margin-right:auto，让 h2 之后的元素整体挤到右侧。 */
#card-med-list > .card-head,
#panel-lab > .card > .card-head { justify-content: flex-start; }
#card-med-list > .card-head > h2,
#panel-lab > .card > .card-head > h2 { margin-right: auto; }
#card-med-list > .card-head .btn,
#panel-lab > .card > .card-head .btn { flex: 0 0 auto; }

/* ---------- ④ 检验记录表工具栏的 640px 压缩规则已删除（v391 用户第 3 项）----------
   检验记录卡的那条 .rec-bulk 工具条已整条取消（导出 → 卡片头 🖨；全选 / 删除 → 🔍 下拉面板底部），
   「禁止换行 + 收紧字号」是为了把 5 枚按钮压成一排，现在没有那一排了。
   ⚠️ 用药记录表（#panel-med）仍在用 .rec-bulk，其通用规则见 183 / 1111 / 1628 行，均保留。 */

/* ④「指标」筛选独立成行（用户要求换行） */
.rec-ind-group { display: inline-flex; align-items: center; gap: 8px; flex: 1 1 100%; }
@media (max-width: 640px) {
  /* 手机上让「指标 + 下拉」整组换行，不再和「状态」挤一行（下拉本身给足宽度便于点选） */
  .rec-ind-group { flex-wrap: nowrap; }
  .rec-ind-group select { flex: 1 1 auto; min-width: 0; }
}

/* ---------- ③ 用药记录表：手机端卡片化（对齐 #record-list 的既有做法） ---------- */
@media (max-width: 640px) {
  /* ⚠️ 这条必须写在 v221 那条 `#med-list.table-wrap { overflow-x: auto; }` **之后**：
     两者同为 id 选择器、特异性相同，靠**书写顺序**取胜。写在前面会被压回去（表还是真表格、
     手机端依旧横向溢出）。改这里的顺序 = 改行为，别随手挪。 */
  #med-list.table-wrap { overflow-x: visible; }
  #med-list table,
  #med-list thead,
  #med-list tbody,
  #med-list th,
  #med-list td,
  #med-list tr { display: block; }
  #med-list thead { display: none; }   /* 去表头：语义改由每格 ::before 标签承载 */
  #med-list tr {
    display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px;
    padding: 8px 10px; margin-bottom: 6px;
    border: 1px solid var(--line); border-radius: 10px;
    background: rgba(255,255,255,0.45);
    /* 🆕 v526（需求 1）：「改 / 删」改成绝对定位到卡片**右上角** ⇒ 卡片必须是定位上下文 */
    position: relative;
  }
  #med-list tr.focus { border-color: #f0a93b; border-left: 3px solid #f0a93b; background: #fff7e6; }
  html[data-theme="dark"] #med-list tr { background: rgba(255,255,255,0.04); }
  html[data-theme="dark"] #med-list tr.focus { background: #33291a; border-color: #5c4a2a; border-left-color: #f0a93b; }
  #med-list td { padding: 0; font-size: 13px; border: none; min-width: 0; }
  #med-list td.sel-col { flex: 0 0 auto; display: inline-flex; align-items: center; }
  #med-list td.sel-col input { width: 16px; height: 16px; }
  #med-list .swatch { flex: 0 0 auto; }
  /* 药名（含色块 / 照片缩略图）与复选框同行、吃掉剩余宽度 */
  #med-list td.med-c-name {
    flex: 1 1 100%; display: flex; align-items: center; gap: 6px;
    font-weight: 600; font-size: 14px;
    /* 🆕 v526（需求 1）：给右上角绝对定位的「改 / 删」让位（26+26+5+8 ≈ 65px），
       否则长药名会压到按钮底下。 */
    padding-right: 66px;
  }
  /* 状态徽标 + 补给/重复/库存/相互作用 chip 独占一行 */
  #med-list td.med-c-status {
    flex: 1 1 100%; display: flex; flex-wrap: wrap; align-items: center; gap: 4px;
    margin: 2px 0;
  }
  /* 日期与剂量/频次：用 ::before 补回被去掉的表头语义 */
  #med-list td.med-c-start,
  #med-list td.med-c-end,
  #med-list td.med-c-dose,
  #med-list td.med-c-freq { flex: 0 0 auto; color: var(--muted); font-size: 12.5px; }
  #med-list td.med-c-start::before { content: '开始 '; }
  #med-list td.med-c-end::before   { content: '停药 '; }
  #med-list td.med-c-dose::before  { content: '剂量 '; }
  #med-list td.med-c-freq::before  { content: '频次 '; }
  #med-list td.med-c-note {
    flex: 1 1 100%; font-size: 12px; color: var(--muted);
    margin-top: 2px; padding-top: 4px; border-top: 1px dashed var(--line);
  }
  #med-list td.inj-cell { flex: 1 1 100%; font-size: 12px; }
  #med-list td.med-ef-cell { flex: 0 0 auto; }
  /* 🆕 v526（需求 1）：空单元格整格收掉 —— 用户原话「把『-』和下面的空白行去掉」。
     · `td.med-c-note:empty`  = 备注/餐次/途径/有效期全为空时的那条虚线 + 下面 5px 空白行；
     · `td.inj-cell:empty`    = 非注射类药原先那格「—」（js 侧 v526 已改为输出空 td，见 injCell）。
     ⚠️ 用 `:empty` 而不是给类名做开关：`:empty` 认的就是「真的一个子节点都没有」，
        将来往这两个格里加任何徽标/chip，隐藏会自动失效、无需同步改判断。 */
  #med-list td.med-c-note:empty,
  #med-list td.inj-cell:empty { display: none; }
  /* 🆕 v526（需求 1）：「改 / 删」从卡片**右下角**移到**右上角**（用户原话「放到药品窗口右上角去」）。
     改前实测（390×844，丁二磺酸腺苷蛋氨酸那张卡）：actions-col 独占整行、y=1566 落在卡片最底部，
     另外还带着一条 border-top 虚线 —— 与上方那条空备注的虚线叠加，就是用户说的
     「一条虚线 + 一个『—』+ 下面一个空白行」。
     改后：脱离文档流绝对定位到右上角，同时**去掉虚线分隔与上下外边距**，卡片不再多出那一行高度。 */
  #med-list td.actions-col {
    position: absolute; top: 6px; right: 8px;
    display: flex; align-items: center; gap: 5px;
    margin: 0; padding: 0; border-top: none;
    /* ⚠️ 必须显式复位宽度：手机段 1290 行 `.actions-col { width:1%; min-width:56px }` 是 (0,1,0)，
       但对**绝对定位**元素 `width:1%` 会按包含块（tr，344px）解析成 **3.44px** ⇒ 实测两颗钮被
       挤成 3px 宽、竖向堆叠（首轮改完实测 w=3/h=40）。这里用 id 选择器压掉它。 */
    width: auto; min-width: 0; flex-wrap: nowrap;
  }
  #med-list .row-actions .btn { padding: 3px 9px; font-size: 11.5px; }
  #med-list .badge { font-size: 11px; padding: 2px 6px; }
}

/* ---------- ③ v343：「用药相关复查提醒」窗口里的药品用途（从「今日用药清单」搬来） ---------- */
.mm-use {
  display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap;
  margin: 2px 0 4px; font-size: 12.5px; color: var(--ink);
}
.mm-use .mm-use-k {
  flex: 0 0 auto; font-size: 11px; color: var(--muted);
  border: 1px solid var(--line); border-radius: 6px; padding: 0 5px; line-height: 1.5;
}

/* ---------- ③④ 卡片头内容必须**放得下**（v343 实测修正） ----------
   实测（390px 视口）：用药记录表卡片头可用 344px，而
   h2(104) + gap(10) + ＋添加用药(92) + gap(10) + 📤导出用药记录(122) + gap(10) + ?(20) = 368px
   ⇒ 溢出 24px，问号被挤出卡片外（视觉上「不见了」）。
   检验记录表卡片头刚好放得下（over=0），但两边一起收紧以保持视觉一致与余量。
   做法：这些卡片头里的按钮再小一档（11px / padding 3px 6px）、间距收到 6px，
   并给 h2 留 `flex: 0 1 auto; min-width: 0` 作为安全网（真放不下时 h2 先让位，而不是按钮被挤出去）。 */
#card-med-list > .card-head,
#panel-lab > .card > .card-head { gap: 6px; }
#card-med-list > .card-head > h2,
#panel-lab > .card > .card-head > h2 { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
#card-med-list > .card-head .btn,
#panel-lab > .card > .card-head .btn {
  flex: 0 0 auto; padding: 3px 6px; font-size: 11px; line-height: 1.25; white-space: nowrap;
}
@media (max-width: 400px) {
  /* 更窄的机型再收一档 */
  #card-med-list > .card-head .btn,
  #panel-lab > .card > .card-head .btn { padding: 3px 5px; font-size: 10.5px; }
  /* 🆕 v361（用户需求 3）：「软件内各个窗口的标题字体要和指标库窗口字体大小统一」
     ⇒ 原来这里把「🧪 历史记录 / 📋 用药记录表」的窗口标题单独压到 14px（v343 为放得下而做），
       是全部 18 个窗口标题里仅有的两个离群值（实测清单见本文件 v361 段）。
       现按用户要求统一为 15.5px。
       ⚠️ 空间风险已核：同一个选择器上仍保留 `flex: 0 1 auto; min-width: 0; overflow: hidden;
          text-overflow: ellipsis`（见上方 v343 段）——真放不下时是**标题先省略号**，
          不会把 ＋ / ? 挤出卡片（这正是 v343 当年加那条安全网的目的，不是靠缩字号硬扛）。 */
  /* 原 `font-size: 14px;` 已删除（v361）。 */
}

/* ══════════ 🆕 v344：指标趋势窗口美化（本页 v344 起由旧页名更名而来） ══════════
   设计口径（frontend-design 原则裁剪到本项目的既有设计语言，不照搬其 GitHub 深色配色）：
     · 间距取 8 的倍数（8 / 16），不引入零散数值；
     · 圆角沿用全局 --radius（12px），与其它卡片保持同一套圆角语言；
     · 层级只用一层「近距硬投影 + 远距负溢价大投影」，避免每张卡都飘起来；
     · 配色不动品牌色（--primary #0e7c86），夜间沿用既有面板变量；
     · 过渡统一 0.2s，老 WebView 也不掉帧。
   ⚠️ 只改「壳」：**不动 .chart 的 width/height**（480 / 手机 360 是 e2e 与真机共用的几何），
     也不动任何选择器结构，避免影响 v343 已锁定的布局断言。 */

/* ① 图表窗口本体：纯白平涂 → 极轻的纵向渐变 + 柔和投影，让它从背景里「浮」起来一档 */
.chart {
  background: linear-gradient(180deg, #ffffff 0%, #fbfdfe 100%);
  box-shadow: 0 1px 2px rgba(20, 40, 60, .04), 0 12px 28px -18px rgba(20, 40, 60, .22);
}
html[data-theme="dark"] .chart {
  background: linear-gradient(180deg, #161b22 0%, #121820 100%);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .35), 0 12px 28px -18px rgba(0, 0, 0, .65);
}

/* ② 分类页签与图表之间留出呼吸位（原 8px 上 / 4px 下，页签贴图表太紧） */
.chart-tabs { margin: 10px 0 8px; }

/* ③ 设置齿轮：与其它卡片头按钮统一到同一套视觉（过渡 + 悬停轻抬 1px） */
.chart-gear { transition: background-color .2s ease, border-color .2s ease, transform .2s ease; }
.chart-gear:hover { transform: translateY(-1px); }
@media (prefers-reduced-motion: reduce) {
  .chart-gear { transition: none; }
  .chart-gear:hover { transform: none; }
}

/* ══════════ 🆕 v344：文件识别 —— 导入按钮行 / 文档缩略图条 / 查看器 ══════════ */
/* v303 就把这套 DOM（#file-thumbs / #file-viewer / .file-thumb …）写进了 index.html，
   但当时标为「留待下一版启用的隐藏资产」，**一行 CSS 都没写**。v344 启用它们，故在此补齐：
   不补的话缩略图会以无样式 div 逐行堆叠，图片撑满整行、完全没法用。
   ⚠️ 不给 .file-viewer 设 display（哪怕 display:flex 更好排版）—— 它靠 [hidden] 的
      UA display:none 来隐藏，作者侧的 display 会把它压掉，导致「一开页就常显」。
      这也是 memory 里记过的老坑（[hidden] 是 UA 的 display:none !important）。 */

.file-import-actions {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  margin-top: 12px;
}

.file-thumbs { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 12px; }
.file-thumb {
  position: relative; width: 116px; cursor: pointer;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--panel); overflow: hidden;
  transition: border-color .18s ease, transform .18s ease;
}
.file-thumb:hover { border-color: var(--primary); transform: translateY(-1px); }
.file-thumb.active { border-color: var(--primary); box-shadow: 0 0 0 2px rgba(14, 124, 134, .18); }
.file-thumb img { display: block; width: 100%; height: 82px; object-fit: cover; background: var(--bg); }
.file-thumb > div:first-child { height: 82px; }
.file-thumb-name {
  padding: 4px 7px 0; font-size: 11px; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.file-thumb-kind { padding: 1px 7px 5px; font-size: 11px; color: var(--muted); }

.file-import-hint { margin-top: 10px; font-size: 12px; color: var(--muted); }

.file-viewer {
  margin-top: 12px; border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--panel); overflow: hidden;
}
.file-viewer-head {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  padding: 8px 12px; border-bottom: 1px solid var(--line); background: var(--bg);
}
.file-viewer-name {
  font-size: 13px; font-weight: 500; color: var(--ink); max-width: 42%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.file-viewer-meta { font-size: 12px; color: var(--muted); }
.file-viewer-tools { margin-left: auto; display: flex; align-items: center; gap: 6px; }
.file-viewer-zoom { font-size: 12px; color: var(--muted); min-width: 44px; text-align: center; }
.file-viewer-stage {
  max-height: 60vh; overflow: auto; padding: 12px; background: var(--bg);
  display: flex; align-items: flex-start; justify-content: center;
}
.file-viewer-canvas { width: 100%; max-width: 100%; }
.file-viewer-canvas img { display: block; max-width: 100%; }

/* 文档解析出的文本行预览（docx / xlsx / csv / txt 点缩略图时展示，供导入前核对） */
.file-viewer-text {
  margin: 0; padding: 14px; width: 100%;
  white-space: pre-wrap; word-break: break-all;
  font-size: 12px; line-height: 1.65; color: var(--ink);
  background: var(--panel); border-radius: 8px;
}
.file-viewer-text-note { padding: 0 14px 14px; font-size: 12px; color: var(--muted); width: 100%; }
.file-viewer-unsupported { padding: 20px; text-align: center; color: var(--muted); width: 100%; }

@media (max-width: 640px) {
  .file-thumb { width: 96px; }
  .file-thumb img, .file-thumb > div:first-child { height: 68px; }
  .file-viewer-name { max-width: 100%; }
  .file-import-actions .btn { flex: 1 1 auto; }
  .file-viewer-stage { max-height: 52vh; padding: 8px; }
}

/* ============================================================================
   🆕 v357：全软件「改 / 删」行内图标统一 + 问号统一大小（用户 2026-09-17 需求）
   ----------------------------------------------------------------------------
   用户原话（第 7 条）：
     「所有"改""删"按钮都改成笔的图形和❌，其中❌图形和图片识别窗口中小图右上角的❌保持一致。」
   用户追问后的定稿口径：
     「按照第7条，红底白叉，不要青绿色了，改也不要底色了，直接改成一个笔的图标。
       另外，软件中的问号都统一大小。」
   ⇒ ① 「改」= **纯笔形图标，无底色无边框**（旧版是绿底白字「改」）；
      ② 「删」= **红底白叉圆形**，与 `.scan-thumb-del`（图片缩略图右上角 ❌）同形同色；
      ③ 全软件问号统一 26×26 圆形、字号 14px（旧版角落 ❓ 是 20px/12px、
         标题栏 `?` 是 34×30 圆角矩形，两处肉眼可见不一样大）；
      ④ 第 6 条「指标库改/删颜色改成与"添加指标"一致」被本口径**取代**
         （用户明确说「不要青绿色了」）——不要再去把指标库按钮染成 primary。

   ★ 为什么删除按钮仍保留 `.danger-text` 类名：
     已有 e2e / 事件委托用 `.danger-text` 圈定"删除语义"。保留类名 = 不破坏任何既有选择器，
     只把**配色**交给 `.act-del` 承担（`.btn.danger-text` 的 (0,2,0) 低于本段 (1,3,0)/(0,4,0)）。
   ★ 为什么下面的铅笔用内联 SVG 而不是 ✎ / ✏️ 字形：
     老 WebView（雷电 = Chrome/91）与部分精简 ROM 缺 Dingbats 字形会渲染成豆腐块；
     ✏️ 是 emoji，颜色写死在字体里、不跟主题变（用户要求「不要底色」，形状必须跟文字同色）。
     SVG 走 `currentColor` + `stroke`，双主题、任意字号都清晰，零字形风险。
   ★ 尺寸为什么是 26×26：老版行内按钮 min-height 24~26px，新按钮取 26px 与之一致，
     且在 360px 视口下两个图标 + 6px 间隔 + 右边距仍能放进 `.actions-col`。
   ============================================================================ */
.act-ico {
  box-sizing: border-box;
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; min-width: 26px; min-height: 26px;
  padding: 0; border: none; border-radius: 50%;
  background: transparent; color: var(--ink);
  font-size: 15px; line-height: 1; font-weight: 400;
  cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.act-ico svg { display: block; width: 15px; height: 15px; }
.act-ico:hover { background: rgba(31, 45, 61, .10); }
/* 「改」：纯笔形，无底色 */
.act-ico.act-edit { color: var(--primary); }
.act-ico.act-edit:hover { background: rgba(14, 124, 134, .12); }
/* 「删」：红底白叉圆钮 —— 与 css/scan.css 的 `.scan-thumb-del` 完全同色同形 */
.act-ico.act-del { background: rgba(192, 57, 43, .92); color: #fff; font-size: 16px; }
.act-ico.act-del:hover { background: #a93226; }
html[data-theme="dark"] .act-ico { color: #e6edf3; }
html[data-theme="dark"] .act-ico:hover { background: rgba(255, 255, 255, .13); }
html[data-theme="dark"] .act-ico.act-edit { color: #7fdde4; }
html[data-theme="dark"] .act-ico.act-del,
html[data-theme="dark"] .act-ico.act-del:hover { color: #fff; }
html[data-theme="dark"] .act-ico.act-del { background: rgba(222, 82, 72, .95); }
html[data-theme="dark"] .act-ico.act-del:hover { background: #e0564a; }

/* 三个表格 + 指标识别结果窗口：行内图标**尺寸与间隔完全一致**（用户第 5 条：
   「右下角的复改删的图标大小和间隔改成与指标识别结果窗口中的一样」）。
   ⚠️ 必须带各自 ID 写：v221/v295 的 `.row-actions{gap:4px}` / `.btn{padding:3px 8px;font-size:11px}`
      是带 ID 的 (1,2,0)/(1,3,0) 规则，通用类选择器压不动。
   ⚠️ 本段位于文件**最末** ⇒ 与同特异性的旧规则相比靠后必胜，无需 !important。 */
#indicator-list .row-actions .btn.act-ico,
#record-list .row-actions .btn.act-ico,
#med-list .row-actions .btn.act-ico,
.entry-result .scan-table .scan-actions .btn.act-ico,
.scan-actions .btn.act-ico {
  width: 26px; height: 26px; min-width: 26px; min-height: 26px;
  padding: 0; font-size: 15px; border-radius: 50%;
}
#indicator-list .row-actions .btn.act-ico.act-del,
#record-list .row-actions .btn.act-ico.act-del,
#med-list .row-actions .btn.act-ico.act-del,
.entry-result .scan-table .scan-actions .btn.act-ico.act-del,
.scan-actions .btn.act-ico.act-del { background: rgba(192, 57, 43, .92); color: #fff; font-size: 16px; }
html[data-theme="dark"] #indicator-list .row-actions .btn.act-ico.act-del,
html[data-theme="dark"] #record-list .row-actions .btn.act-ico.act-del,
html[data-theme="dark"] #med-list .row-actions .btn.act-ico.act-del,
html[data-theme="dark"] .entry-result .scan-table .scan-actions .btn.act-ico.act-del,
html[data-theme="dark"] .scan-actions .btn.act-ico.act-del { background: rgba(222, 82, 72, .95); color: #fff; }

/* 🆕 v357（用户第 5/6 条）：行内图标的**尺寸与间隔四处统一**。
   ⚠️ 这里踩了两个坑，别再改回去：
     ① `gap` 只对 flex/grid 容器生效，而 `.row-actions` / `.scan-actions` 是 `<td>`。
        指标识别表那个单元格是 `table-cell` ⇒ `gap` 完全不生效（实测间距 0，两个按钮贴在一起）。
     ② 检验记录/用药页的 `td.actions-col` 本来就是 `inline-flex`，**各自带着老 gap**
        （`#record-list td.actions-col{gap:4px}` / `#med-list td.actions-col{gap:5px}`）。
        若只加 margin，就会变成 4+6=10 / 5+6=11 —— 四处反而更不一致。
   做法：把这几处的 gap 显式归零（用同等特异性的 `td.actions-col` 写法保证压得住老规则、
   且本文件更靠后），再由相邻兄弟 margin 统一给 6px。这样无论宿主是 table-cell 还是 flex，
   四处都是同一个 6px。 */

/* 🆕 v357（用户第 5/6 条）：行内图标的**尺寸与间隔四处统一**。
   ⚠️ 这里踩了两个坑，别再改回去：
     ① `gap` 只对 flex/grid 容器生效，而 `.row-actions` / `.scan-actions` 是 `<td>`。
        指标识别表那个单元格是 `table-cell` ⇒ `gap` 完全不生效（实测间距 0）。
     ② 检验记录/用药页的 `td.actions-col` 本来就是 `inline-flex`，**各自带着老 gap**
        （`#record-list td.actions-col{gap:4px}` / `#med-list td.actions-col{gap:5px}`）。
        若只加 margin，就会变成 4+6=10 / 5+6=11 —— 四处反而更不一致。
   做法：把这几处的 gap 显式归零（用同等特异性的 `td.actions-col` 写法保证压得住老规则、
   且本文件更靠后），再由相邻兄弟 margin 统一给 6px。这样无论宿主是 table-cell 还是 flex，
   四处都是同一个 6px。 */
#indicator-list td.actions-col,
#record-list td.actions-col,
#med-list td.actions-col,
.entry-result .scan-table td.scan-actions,
td.scan-actions { gap: 0; }

#indicator-list .row-actions .act-ico + .act-ico,
#record-list .row-actions .act-ico + .act-ico,
#med-list .row-actions .act-ico + .act-ico,
.entry-result .scan-table .scan-actions .act-ico + .act-ico,
.scan-actions .act-ico + .act-ico { margin-left: 6px; }

/* 问号统一 26×26（角落 ❓ / 标题栏 ? / 指标分析释义 ? 三处同尺寸） */
.hint-q,
.entry-bar-tools .raw-ocr-help,
.raw-ocr-help,
.ind-def-q {
  box-sizing: border-box;
  width: 26px; height: 26px; min-width: 26px; min-height: 26px;
  padding: 0; border-radius: 50%;
  font-size: 14px; font-weight: 700; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center;
}
/* `.hint-q` 原本是 padding:0 的绝对定位圆钮，改成 flex 后基线会跑，这里把行高钉死 */
.hint-q { line-height: 1; }
/* 🆕 v526（需求 3①）：卡头内的 🌰 一律用 `margin-left:auto` 钉到**最右端**。
   ── 用户原话：「症状日历热力图右上角的粒子图标的位置和其他窗口的不一致，统一调整。」
      （「粒子」= 栗子 🌰，v417 起由「?」换成板栗 SVG）
   ── 实测证据（390×844，scripts/_probe_v526_probe2.js）：
        其它 10 个窗口的 🌰 都紧贴卡头右端（gapToHeadRight = 0，x=341/343/367）；
        只有「症状日历热力图」那枚在 x=268、**gapToHeadRight = 75px**，明显左移。
      根因：它的卡头 `.card-head.sh-head` 里 h3 带一个 `.sh-sub` 副标题（`white-space:nowrap`
      + `flex-shrink:0`），h3 宽度顶住后剩余空间没被「推」到 🌰 左侧 —— 也就是说该头部实际按
      左对齐排，而不是其余窗口那种两端对齐。
   ── 为什么用 auto 外边距而不是再依赖 justify-content：
      同一份样式在 3 处被 `.card-head{gap}` / 分节块特化规则反复覆盖过（3551 / 4588 / 5452），
      靠 justify 只能照顾「两个子元素」的情形；auto 外边距在**任何** justify 取值下都把该元素
      推到行尾，且对已经贴右的 10 枚图标是**零位移**（它们的自由空间本来就是 0）。
   ── ⚠️ 不要恢复 v423 的 `margin-left: 取消` 注释里那条：那条的前提是「容器 gap 已提供统一间距」，
      而 gap 只能保证**图标与前一个元素**之间 6px，保证不了「图标贴右端」。 */
/* 🆕 v530（需求 1）：去掉 margin-left:auto —— 它与各卡片头 h2 的 margin-right:auto
   （#panel-med/#panel-vitals/#panel-lab/… 见下方各段）构成**双 auto 边距**：自由空间被平分 ⇒
   「＋」等操作按钮被顶到行中间，与 🌰 之间隔出一段空白（用户报「添加按钮要和 🌰 相邻」）。
   改后由 h2 的 margin-right:auto 单独把「按钮 + 🌰」整组推到右端，🌰 紧挨按钮；
   仅 h3 分节头（.sh-head，无 h2 auto 边距）仍需 🌰 自带 auto 边距钉右端，见下一条。 */
.hint-q-inline { position: static; flex: none; }
.sh-head > .hint-q-inline { margin-left: auto; }
/* 指标分析窗口名称行右侧的释义问号：流式排布、贴行尾，不抢名称空间 */
.ind-def-q {
  margin-left: auto; flex: 0 0 auto;
  border: 1px solid var(--line); background: var(--panel); color: var(--muted);
  opacity: .85; cursor: pointer;
}
.ind-def-q:hover { opacity: 1; color: var(--primary); border-color: var(--primary); }
html[data-theme="dark"] .ind-def-q { background: #1a2431; }

/* 🆕 v357（用户第 5 条）：「＋ 添加记录」按钮拆成「＋」图标 + 下拉菜单。
   下面是本处专有的两条外观（下拉菜单本体复用 css/scan.css 的 .scan-add-menu，见 index.html 注释）。 */
.rec-add-wrap .rec-add-plus {
  min-width: 34px; padding-left: 0; padding-right: 0;
  font-size: 15px; font-weight: 700; line-height: 1;
}
.rec-add-wrap .scan-add-menu { top: calc(100% + 4px); }
.rec-add-wrap .scan-add-menu .btn { white-space: nowrap; }

/* 🆕 v357（用户第 7 条）：「指标分析」窗口的指标名称行 —— 名称居左，「?」释义按钮贴最右。
   ⚠️ 必须把 `.pb-name` 改成 flex：它原来是块级、只放文字，`margin-left:auto` 在块级里不起作用
      （按钮会紧贴名称后面而不是贴行尾）。选择器照抄上面 v295 的 `:is(...)` 写法以保持同特异性。 */
:is(.personal-baseline, .ind-analysis) .pb-name {
  display: flex; align-items: center; gap: 6px;
}

/* 🆕 v357：「改」按钮的第二种状态（点开后变「完成」）—— 只换字形（✓），仍然不加底色，
   与用户「改也不要底色了」的口径一致；状态本身由整行的 .editing 青色描边表达。 */
.act-ico.act-edit.is-done { color: #2f9d6a; }
.act-ico.act-edit.is-done:hover { background: rgba(47, 157, 106, .12); }
html[data-theme="dark"] .act-ico.act-edit.is-done { color: #5fd39a; }

/* ══════════════════════════════════════════════════════════════════════════════
   🆕 v359（用户需求 8 条；e2e = _e2e_v359_ui.js）
   ⚠️ 本段位于文件**最末** ⇒ 与同特异性规则相比靠后必胜（沿用 v357 段做法，全程不写 !important）。
   ══════════════════════════════════════════════════════════════════════════════ */

/* ① 「指标趋势窗口也做成和指标库一样的圆角窗口」
   实测（_v359_evidence/geo_v358_before.json）：手机端 `.card` 圆角 = 16px（本文件 1404 行的 640px 断点），
   而 `.chart` 圆角 = 14px（1437 行同断点）⇒ 同一屏上下两个窗口的圆角肉眼可见不一致。
   桌面端两者都取 var(--radius)=12px，本来就一致 ⇒ 只在手机断点内对齐。 */
@media (max-width: 640px) {
  .chart { border-radius: 16px; }
}

/* ② 行内图标族统一 20×20
   用户原话：「软件中的❌太大，和缩略图上的❌要尺寸一致」「铅笔图标换一个写实的✏️，也要外加一个
            圆圈，尺寸也要一致」「还有设置、问号都要改成一样的大小」。
   ── 尺寸基准 = css/scan.css 的 `.scan-thumb-del`（用户点名的对照物）：20×20 圆钮 + × 字形 15px。
   ⚠️ 下面两组 ID 选择器必须**逐字照抄 v357 段**（本文件 3284 / 3292 行）：它们分别是 (1,3,0) 与 (1,4,0)，
      通用类选择器压不动 —— 漏掉任何一处的尺寸，就会出现「四处又不一致」的老毛病。 */
.act-ico { width: 20px; height: 20px; min-width: 20px; min-height: 20px; font-size: 15px; }
/* 🆕 v513（用户第 6 项）：「指标库窗口中指标行的右边的图标高度不一致」。
   ── 实测根因（_v513_icons.js，浏览器里量的，不是读代码猜的）──
      三个按钮的**盒子**全是 20×20（本节 4441/4443 两条规则生效，4443 行那条晚于 4330 行的
      `.btn.act-ico{26px}` ⇒ 最终 20×20），但**墨迹**不齐：
        · ⫽ 铅笔（`.act-edit` 内的 svg）被下面这条钉死 12×12 ⇒ 墨迹只有 12×12；
        · 删除的 `×` 与释义的 `?` 是**文字字形**，font-size:15px ⇒ 墨迹约 15~17px 高。
      肉眼看到的就是「铅笔小一圈」。⇒ 把铅笔墨迹提到与字形同高（15px），盒齐 + 墨迹也齐。
   ⚠️ 与 4447 行的 20×20 盒子规则是一对，改这里别动那里（盒子必须三家一致）。 */
.act-ico svg { width: 15px; height: 15px; }
/* 🆕 v521（用户需求 27）：「症状记录中的编辑按钮不显示图案」根因（浏览器实测，非推断）：
   `.btn.tiny{padding:4px 10px}` 特异性 (0,2,0) 压过 `.act-ico{padding:0}` (0,1,0)，
   凡未挂 ID/上下文复位的行内编辑圆钮（事件行 / 疫苗行 / 过敏行）内容区被 10px 横向
   padding 挤成负值 ⇒ 铅笔 SVG 被 flex 压缩成宽 0（getComputedStyle width=0px），
   界面上只剩一颗空心描边圆。用 (0,3,0) 组合选择器统一复位，一次修好所有 `.btn.tiny.act-ico`；
   已有专有复位（row-actions / tm-acts / tl-row-edit）语义相同，不受影响。

   🆕 v568（用户第 1 项）：「会员中心的提醒邮箱的两个按钮要按其他窗口中的编辑和删除用一样的样式」。
   ── 实测（探针在 390×844 与 1280 宽两档逐属性读 getComputedStyle，不是读代码猜的）──
      那两个钮的类名是 `.btn.tiny.act-ico.act-edit` / `.btn.tiny.danger-text.act-ico.act-del`
      （由 `btnEdit()` / `btnDel()` 产出，见 js/app.js 27169 / 27173）。v521 那条只复位了 padding，
      另外三个几何属性仍被 `.btn.tiny`(0,2,0) 按着：
        · `min-height: 36px`（手机段 2073 行）—— 而 `.act-ico{min-height:26px}` 只有 (0,1,0)；
        · `border-radius: 9px`（同上）—— 压过 `.act-ico{border-radius:50%}`；
        · `font-size: 12.5px`（同上）—— 压过 `.act-ico{font-size:15px}`，红叉缩成一个小点。
      ⇒ 结果就是用户截图里那颗「高大圆角矩形 + 一圈青色描边」（描边本身是对的，是 `.act-ico.act-edit`
        的 1px 环，只是盒子被撑成 36px/9px 就不再是圆钮）。指标库 / 检验记录 / 用药表那几处因为
        各自带 ID 选择器（下一条 4901 行，(1,3,0)）而幸免，所以看起来「别的窗口是对的」。
   ⇒ 本条继续用 (0,3,0) 把几何一次钉回 26px 圆钮（与 `.event-item .btn.act-ico` 的 26px 口径一致）。
     只动 width / height / min-width / min-height / padding / border-radius / font-size，
     **不碰 background / border / color**：
     那三个属性本来就由 `.act-ico`(0,1,0) 与 `.act-ico.act-del`(0,2,0) 正确接管，
     在这里覆写反而会把删除钮的红底和编辑钮的青环一起抹掉。
   ⚠️⚠️ 本段曾写成「min-」紧跟一个星号 —— 那个星号与后面的斜杠正好拼成**注释结束符**，
      把整段注释提前闭合，于是紧接着的那条规则被浏览器当作非法内容丢弃
      （实测 document.styleSheets 里根本查不到它，computed 仍是 .btn.tiny 的 36px / 9px）。
      **CSS 注释里同样不能出现注释结束符**，这与 JS 模板字符串里不能出现反引号是同一类坑。 */
.btn.tiny.act-ico {
  padding: 0;
  box-sizing: border-box;
  width: 26px; height: 26px; min-width: 26px; min-height: 26px;
  border-radius: 50%;
  font-size: 16px; line-height: 1;
}
/* ⚠️ 上面这条是 (0,3,0)，会连带影响**所有** `.btn.tiny.act-ico`。逐处核对后，只有一类
   不是「图标钮」而必须保住原样：检验记录批量识别表右侧的「复」（`data-copy-rec`，
   见 js/app.js 的 buildEntryTableHTML）。它是**文字钮**，一直是
   `.act-ico` 的 20×20 盒子 + `.row-actions .btn` 的 11px 字形 + `.btn.tiny` 的 9px 圆角，
   在 20px 盒子里正好放得下一个字；被撑成 26px 圆钮会与同排的编辑/删除小钮不齐。
   带 ID 的那几处（指标库 / 检验记录 / 用药表）本来就是 (1,3,0) 的 20×20，ID 优先级更高，
   不受上面那条影响，所以这里只需要处理「无 ID 的 .row-actions」。
   用 :not(.act-edit):not(.act-del) 把真正的图标钮排除在外 —— 它们应当跟着变圆。 */
.row-actions .btn.tiny.act-ico:not(.act-edit):not(.act-del) {
  width: 20px; height: 20px; min-width: 20px; min-height: 20px;
  padding: 0; font-size: 11px; border-radius: 9px;
}
/* 事件行（记录 / 症状 / 疫苗…）的 ✓ × 一直是 17px 字形 —— 那是 v526 段特意写的
   （`.event-item .btn.act-ico{font-size:17px}`，(0,3,0)），本段 (0,3,0) 在后面会盖掉它。
   这里按原值补回来：本轮的诉求只是「圆钮尺寸统一」，不涉及行内字形大小。 */
.event-item .btn.tiny.act-ico { font-size: 17px; }
#indicator-list .row-actions .btn.act-ico,
#record-list .row-actions .btn.act-ico,
#med-list .row-actions .btn.act-ico,
.entry-result .scan-table .scan-actions .btn.act-ico,
.scan-actions .btn.act-ico { width: 20px; height: 20px; min-width: 20px; min-height: 20px; font-size: 15px; }
#indicator-list .row-actions .btn.act-ico.act-del,
#record-list .row-actions .btn.act-ico.act-del,
#med-list .row-actions .btn.act-ico.act-del,
.entry-result .scan-table .scan-actions .btn.act-ico.act-del,
.scan-actions .btn.act-ico.act-del { font-size: 15px; }
/* 「改」按钮加外圈（用户：「也要外加一个圆圈」）。边框色由主题决定，不用 currentColor 是因为
   `.act-edit` 的 color 同时被 `.is-done` 改成绿色，用固定色更可控。
   ⚠️ `.act-ico` 已 box-sizing:border-box ⇒ 加 1px 边框不会把按钮撑成 22×22（有 e2e 断言守着）。 */
.act-ico.act-edit { border: 1px solid rgba(14, 124, 134, .45); }
.act-ico.act-edit:hover { border-color: var(--primary); }
html[data-theme="dark"] .act-ico.act-edit { border-color: rgba(127, 221, 228, .45); }
html[data-theme="dark"] .act-ico.act-edit:hover { border-color: #7fdde4; }
/* 「完成」态（✓）边框随字色转绿，避免「字绿框青」的割裂 */
.act-ico.act-edit.is-done { border-color: rgba(47, 157, 106, .5); }
html[data-theme="dark"] .act-ico.act-edit.is-done { border-color: rgba(95, 211, 154, .5); }

/* ③ 问号 / 齿轮 → 与上面同尺寸（🆕 v417：全软件右上角图标统一 26×26，用户 2026-09-25
   「整个 app 和网页版软件的窗口右上角图标都要统一大小间距、与窗口标题等高」——
   v359 曾把 v357 的 26 收回到 20，本轮按新的统一口径（26）再改回来，齿轮一并）。 */
.hint-q,
.entry-bar-tools .raw-ocr-help,
.raw-ocr-help,
.ind-def-q {
  width: 26px; height: 26px; min-width: 26px; min-height: 26px;
  font-size: 14px; font-weight: 700; line-height: 1;
}
/* 齿轮 34×34 → 26×26。字形 13px（⚙️ 笔画更密，同字号会显得更小）。 */
.chart-gear { width: 26px; height: 26px; font-size: 14px; }
/* 齿轮缩小后，设置面板原来留的 44px 顶距会空出 20px 的缝 ⇒ 同步收到 34px（齿轮底边 28 + 6 间隙） */
.chart-settings-pop { top: 34px; }

/* ④ 删除确认弹窗（用户：「点击以后要有弹出对话框用以再次确认删除，软件内弹窗风格要统一」）
   JS 侧结构（js/app.js 的 appConfirm）：
     <div class="def-popup-content confirm-pop">
       <header><h3>标题</h3></header>
       <div class="def-body"><p>正文</p><p class="def-tip">备注</p></div>
       <div class="confirm-foot">[取消] [删除]</div>
     </div>
   ⚠️ `.def-body` 是 `overflow-y:auto` 的中间层，页脚必须自带背景+上边框，否则内容滚动时会「穿」到页脚下面。
   ⚠️ 弹窗宽度收窄到 430px：这是「确认」而不是长文阅读，800+ 字宽的释义弹窗宽度（620px）在手机上手感很空。 */
.confirm-pop { width: min(430px, 92vw); }
.confirm-pop .def-body { padding: 16px 20px 6px; }
.confirm-pop .def-body p { margin: 0 0 6px; }
.confirm-foot {
  display: flex; justify-content: flex-end; gap: 10px;
  padding: 12px 18px 16px; border-top: 1px solid #e5ebf3; background: #f8fbff;
}
.confirm-foot .btn { min-height: 38px; padding: 0 18px; border-radius: 10px; font-size: 14px; }
html[data-theme="dark"] .confirm-foot { background: #161d24; border-color: #2d3946; }
/* 🆕 v560（用户第 1 项）：多选项弹窗（「重新识别」= 2 个选项 + 取消 = 3 颗钮）在 430px 宽的弹窗里
   被挤成「取 消」「从缩略图识别（更 快）」两行折行 —— 中文按钮折行会断在词中间，很难看。
   处理：① 允许整行换行并把每颗钮撑到均分宽度；② 文案不允许折行（white-space:nowrap）；
        ③ 置灰的选项要有**明显不同于可用项**的外观（只靠 disabled 属性是看不见的）。 */
.confirm-foot { flex-wrap: wrap; }
.confirm-foot .btn { flex: 1 1 auto; min-width: 92px; white-space: nowrap; }
/* 多选项钮（data-choice）左右内边距收窄到 12px、字号 13.5px：
   实测 430px 弹窗内「从原图识别（无原图）」+「从缩略图识别」+「取消」按 18px 内边距会超出 394px 的
   可用宽度 ⇒ 取消被挤到第二行并拉成整行宽，视觉重心全压在取消上。收窄后三颗钮可同排。
   「取消」不参与均分（flex:0 0 auto），避免被拉成长条。 */
.confirm-foot .btn[data-choice] { padding: 0 12px; font-size: 13.5px; }
.confirm-foot .btn[data-cf="0"] { flex: 0 0 auto; min-width: 72px; }
.confirm-foot .btn[disabled], .confirm-foot .btn[aria-disabled="true"] {
  opacity: .48; cursor: not-allowed; box-shadow: none; filter: grayscale(.35);
}
.confirm-foot .btn[disabled]:hover, .confirm-foot .btn[aria-disabled="true"]:hover {
  border-color: inherit; color: inherit; background: inherit;
}

/* ④-1 🆕 v368：历史错值预览清单（关于面板 →「检查并修正历史错值」）
   ⚠️ 最多 45 行，必须自己滚动（.def-body 虽然 overflow-y:auto，但清单在里面会把它撑成整屏，
      页脚被顶出视口 ⇒ 在这里给清单自己的 max-height，页脚始终可见）。
   窄屏（≤430px 的 confirm-pop）下「日期 指标：旧 → 新 + 原因」一行放不下 ⇒ 原因另起一行小字。 */
.confirm-pop .fx-sum { margin: 0 0 8px; }
.fix-list {
  list-style: none; margin: 0; padding: 0;
  max-height: min(46vh, 340px); overflow-y: auto; -webkit-overflow-scrolling: touch;
}
.fix-list li {
  padding: 7px 0; border-bottom: 1px dashed #e3eaf3;
  font-size: 13.5px; line-height: 1.5; color: #26313d;
}
.fix-list li:last-child { border-bottom: 0; }
.fix-list .fx-d { color: #6b7a8f; font-variant-numeric: tabular-nums; margin-right: 4px; }
.fix-list .fx-ar { color: #b23b30; font-weight: 700; margin: 0 2px; }
.fix-list .fx-why { display: block; color: #7b8798; font-size: 12.5px; margin-top: 2px; }
.fix-list .fx-note { color: #6b7a8f; font-size: 12.5px; border-bottom: 0; }
html[data-theme="dark"] .fix-list li { color: #c2ccd6; border-color: #2d3946; }
html[data-theme="dark"] .fix-list .fx-d { color: #8896a8; }
html[data-theme="dark"] .fix-list .fx-ar { color: #ef7d72; }
html[data-theme="dark"] .fix-list .fx-why { color: #8896a8; }
html[data-theme="dark"] .fix-list .fx-note { color: #8896a8; }

/* ⑤ 「指标分析」吸收「方向洞察」后的行样式
   ⚠️ 旧 `.it-*` 全挂在 `.ind-trend` 下（本文件 1899-1907 / 1930-1933 行），而 v359 把方向内容并进了
      `#ind-analysis`（根类 `.ind-analysis`）⇒ 不补这一段，方向行会退化成无样式的裸文字。
      旧的 `.ind-trend .it-*` 规则保留不动：`#ind-trend` 节点本轮才刚退役，留着不占任何渲染成本，
      也让「改回去」这件事只是一行 HTML 的距离。 */
.ind-analysis .it-row { display: flex; align-items: center; gap: 8px; padding: 4px 0 2px; flex-wrap: wrap; }
.ind-analysis .it-dir { font-weight: 700; padding: 1px 8px; border-radius: 10px; font-size: 12px; }
/* 🆕 v503（项 10）：方向胶囊已合并成一个、并挂进指标名同一行（.pb-name）。
   ① 允许 .pb-name 换行 —— 窄屏下胶囊换行而不是把指标名挤出容器（不写 !important，
      也**不碰**共享的 `:is(.personal-baseline, .ind-analysis) .pb-name` 规则，避免连带改个人基线窗口）。
   ② 胶囊内的变化幅度比方向词弱一档，但仍同属一个胶囊。 */
.ind-analysis .pb-name { flex-wrap: wrap; }
.ind-analysis .it-dir .it-dir-chg { font-weight: 600; opacity: .9; margin-left: 2px; }
.ind-analysis .it-up { color: #c0392b; background: #fbe3e1; }
.ind-analysis .it-down { color: #1b6b8f; background: #e2f1f7; }
.ind-analysis .it-flat { color: #6b7785; background: #eceff2; }
.ind-analysis .it-chg { color: #4a3a7a; font-weight: 600; }
.ind-analysis .it-sub-inline { color: #5a6573; font-size: 12.5px; line-height: 1.5; }
html[data-theme="dark"] .ind-analysis .it-up { color: #ef7d72; background: #3a2220; }
html[data-theme="dark"] .ind-analysis .it-down { color: #7cc4e6; background: #15202a; }
html[data-theme="dark"] .ind-analysis .it-flat { color: #9aa6b2; background: #2a2a33; }
html[data-theme="dark"] .ind-analysis .it-chg { color: #c9b6f0; }
html[data-theme="dark"] .ind-analysis .it-sub-inline { color: #9aa6b2; }

/* ⑥ 「时间轴事件标记」与「就诊与复查」（v359 从用药页移到日常测量页）两个卡片头
   `.card-head` 默认 `justify-content: space-between`，一旦子元素 ≥3 个（h2 + 按钮 + 由
   hintsToCorner 追加的 ?）就会把中间那个「摊」到正中。v357 已在 #card-med-list / #panel-lab 上踩过
   同一个坑并修正（本文件 3002-3009 行），这里把两处**新增**的卡片头补齐同样的写法。 */
#card-appointments > .card-head,
.event-marker > .card-head { justify-content: flex-start; }
#card-appointments > .card-head > h2,
.event-marker > .card-head > h2 { margin-right: auto; }
#card-appointments > .card-head > .btn,
.event-marker > .card-head > .btn { flex: 0 0 auto; }

/* 🆕 v359（用户第 2 条）：「设置 / 问号 / ❌ / ✏️ / ＋」必须**同一个尺寸**（已定 20×20，基准 = 缩略图 ❌）。
   ⚠️ 上面这些圆形按钮除了自己的类（.act-ico / .rec-add-plus）还都带 `.btn.tiny`，
      而本文件移动端段（max-width:640px）里有 `.btn.tiny { min-height:36px; padding:5px 12px; }`
      —— 它会把尺寸顶回 26×36 / 34×36（实测 #btn-event-form-toggle = 26×36，正是 e2e B1 抓到的那条）。
   ⚠️ 所以这里必须**连 min-height / padding 一起复位**：只写 width/height 会被 min-height 压过。
   选择器统一取 (0,3,0) 特异性：`.card-head > .btn.act-ico` 压 `.btn.tiny`(0,2,0)；
   ＋ 按钮用**后代**选择器 `.card-head .rec-add-wrap > .rec-add-plus` —— 因为指标库那枚 ＋ 外面还套了一层
   `.card-head-actions`（index.html:248），写成 `>` 直接子代就漏掉它，又回到「四处不一致」的老毛病。
   ⚠️ 覆盖全部 4 枚 ＋：#btn-ind-add(指标库) / #btn-rec-add-inline(历史记录) / #btn-med-add(用药记录表)
      / #btn-appt-add(就诊与复查)，它们都是 `.card-head` 内的 `.rec-add-wrap > .rec-add-plus`。 */
.card-head > .btn.act-ico,
.card-head .rec-add-wrap > .rec-add-plus {
  width: 20px; height: 20px; min-width: 20px; min-height: 20px;
  padding: 0; box-sizing: border-box; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  line-height: 1; font-size: 15px; font-weight: 700;
}
/* ❌ 的底色是纯色圆点，＋ 沿用 v357 的 primary 底色（只改形状与尺寸，不动配色基因）；
   齿轮是 emoji 字形，下面按同尺寸收字号。 */
.card-head .rec-add-wrap > .rec-add-plus,
.card-head > .btn.act-ico { border-radius: 50%; }

/* ══════════════════════════════════════════════════════════════════════════
   🆕 v361（用户 2026-09-17 需求 2①② / 3 / 4）
   ⚠️ 本段必须放在文件**最末尾**：下面多数是「改现状」而不是「新增控件」——
      要压过上面那些**同特异性**但更靠前的规则（.card h2 783 行、.card-head h2 1409 行、
      .vitals-wrap h2 1738 行、.card-head-actions 197 行）。
      同特异性下只按**源码顺序**决胜，放错位置就是静默失效（本仓库老坑，见 scan.css 尾部同类注释）。
   ══════════════════════════════════════════════════════════════════════════ */

/* ── 需求 3①：窗口标题字号统一 = 基准「📊 指标库」的 15.5px（桌面 16px）──
   实测清单（_probe_v361_titles2.js，390×844 手机端，共 18 个窗口标题）：
     15.5px × 11  ✅ 基准（📊 指标库 / 📸 图片识别 / 💊 今日用药清单 / 👑 账号与订阅 …）
     14px   × 2   ⚠️ 🧪 历史记录、📋 用药记录表   ← 本文件 3126 行的移动端压缩规则
     15px   × 1   ⚠️ 📝 心理量表自评 PHQ-9
     17.55px × 1  ⚠️ 📊 自定义追踪项             ← 该 h3 无任何规则，落在 UA 默认 1.17em，连 margin 都是 1em
     18px   × 2   ⚠️ 😊 每日健康打卡、📅 就诊与复查 ← 本文件 1738 行 `.vitals-wrap h2{font-size:18px}`
   ⚠️ 为什么用 `.card > h2:first-child` 而不是 `.card h2`：很多窗口没有 .card-head，标题就是卡片第一个
      直接子元素；用 :first-child 把范围钉死在「窗口标题」上，**不会误伤卡片内部的次级 h3**
      （如「用药图例」14px、「症状日历热力图」15px —— 它们是窗口内的分节标题，本就该小于窗口标题）。 */
.card-head > h1, .card-head > h2, .card-head > h3,
.card > h1:first-child, .card > h2:first-child, .card > h3:first-child {
  font-size: 15.5px; letter-spacing: .2px;
}
@media (min-width: 641px) {
  /* 桌面端基准 16px —— 与本文件 159 行 `.card h2` / 196 行 `.card-head h2` 的桌面取值一致 */
  .card-head > h1, .card-head > h2, .card-head > h3,
  .card > h1:first-child, .card > h2:first-child, .card > h3:first-child { font-size: 16px; }
}
/* `.card > h3:first-child` 还要清掉 UA 的 `margin: 1em 0`（那是 17.55px 的另一半来源）；
   顺带把 `.card > h2:first-child` 的外边距也归一（`.vitals-wrap h2` 给过 10px 0 4px）。 */
.card > h1:first-child, .card > h2:first-child, .card > h3:first-child { margin: 0 0 8px; }
@media (min-width: 641px) {
  .card > h1:first-child, .card > h2:first-child, .card > h3:first-child { margin: 0 0 12px; }
}

/* ── 需求 3②：窗口右上角的按钮要和左侧标题**在相同高度** ──
   实测根因两条（390×844，Δ = 按钮中心Y − 标题中心Y，同高应为 0）：
     ① 标题被顶高 4px。`.card-head` 是 flex + `align-items:center`，但 783 行 `.card h2{margin:0 0 8px}`
        与 1738 行 `.vitals-wrap h2{margin:10px 0 4px}` 在卡片头里**依然生效** ⇒
        flex 居中的是「含下外边距的外框」⇒ 文字框整体上移 4px（实测「指标库」Δ=+4；
        「就诊与复查」上下边距 10/4 ⇒ 净 +6 ⇒ 上移 3px，与实测 Δ=-3 吻合）。
     ② ＋ 在按钮组里被顶到组顶。`.card-head-actions`（197 行）只写了 `display:inline-flex`，
        **没写 align-items** ⇒ 默认 `stretch`。组内 36px 高的「全部勾选」撑起组高，
        20×20 的 ＋ 又不能拉伸，于是被对齐到**顶部**（实测 ＋ Δ=-4，而同组的「全部勾选」Δ=+4）。 */
.card-head > h1, .card-head > h2, .card-head > h3 { margin: 0; }
.card-head-actions { align-items: center; }

/* ── 需求 2①：指标库窗口的「＋」跑到老远，要贴到问号旁边 ──
   根因：`.card-head`（195 行）是 `justify-content: space-between`，而窗口右上角的「?」是
   hintsToCorner() **追加到卡片头末尾**的 ⇒ 卡片头有 3 个子元素（h2 / .card-head-actions / ?），
   space-between 会把中间那个按钮组摊到正中，＋ 与右侧问号之间就空出一大段。
   修法与 v357 给 #card-med-list / #panel-lab 的完全一致：flex-start + 给 h2 `margin-right:auto`，
   把按钮组顶到右侧、紧邻问号。顺带把 gap 收到 6px（与那两处一致）。
   ⚠️ `margin-right:auto` 用 id 选择器写，才能压过本段上面的 `.card-head > h2{margin:0}`（简写会重置 margin-right）。 */
#card-ind-lib > .card-head { justify-content: flex-start; gap: 6px; }
#card-ind-lib > .card-head > h2 { margin-right: auto; }
#card-ind-lib > .card-head > .btn,
#card-ind-lib > .card-head .card-head-actions { flex: 0 0 auto; }

/* ── 需求 2②：指标分析窗口的「📊 指标分析」标题**冻结**，只让下面的指标行与说明滚动 ──
   现状：#ind-analysis 是 JS 设的正方形滚动窗口（maxHeight = 宽度、overflowY:auto），
        标题是它的第一个子元素 ⇒ 跟着一起滚走。
   做法：标题改 sticky 吸顶。
     · 容器上内边距挪给标题（10px 14px → 0 14px 10px）：sticky 的吸附线是滚动口顶部，
       若容器仍有 10px 上内边距，滚动内容会从标题上方那条缝里穿过去。
     · 标题背景必须与容器同色（浅色 #f6f4fb / 夜间 #1b1726），否则滚动内容透出来。 */
.ind-analysis { position: relative; padding: 0 14px 10px; }
.ind-analysis > .pb-head {
  position: sticky; top: 0; z-index: 3;
  margin: 0; padding: 10px 0 6px;
  background: #f6f4fb;
}
html[data-theme="dark"] .ind-analysis > .pb-head { background: #1b1726; }

/* ── 需求 4：日常测量页「添加区域」窗口化 ──
   结构见 index.html（#card-vitals 卡片头 + ＋；#vitals-form 收进下拉）。
   ⚠️ `[hidden]` 在本项目里压不住作者样式的情况必须显式兜底：`.vitals-form` 作者规则带
      `display:flex`，而 `[hidden]` 只是 UA 的 `display:none`。这里用 `#vitals-form[hidden]`
      （0,1,1,0）确保「隐藏」永远生效，不赌 UA 表的优先级（同 index.html 其它弹窗的既有做法）。 */
#vitals-form[hidden] { display: none; }
#card-vitals .vitals-hint { margin: 0 0 12px; }
#card-vitals #vitals-list { margin-top: 0; }   /* 🆕 v530：列表窗与曲线窗同一节奏（.vitals-charts margin-bottom 12px 已提供间距） */
/* 表单不再贴着卡片底：原来它后面还有列表，现在是卡片内的最后一块之一，收一点下外边距 */
#card-vitals .vitals-form { margin-bottom: 12px; }

/* ═══════════════════════════════════════════════════════════════════════════
   🆕 v371：合规三件套 —— 协议页 / 首启同意弹窗 / 退款与客服（用户需求 ②，纯前端）
   ───────────────────────────────────────────────────────────────────────────
   z-index 取 900（同意弹窗 950）：必须压过 .demo-frame(380)、相机/相册弹层、toast 等
   一切既有覆盖层 —— 否则「未同意前不能使用」会被别的浮层顶开一个口子。

   ⚠️ 三层遮罩的显隐一律由 JS 摘/加 `hidden` 属性控制，这里**不写** `.legal-mask[hidden]{…}`：
      UA 样式表里的 `[hidden] { display: none !important }` 自带 !important，作者规则压不过它，
      写了也不会生效（v337「规则写了但从没生效」的同一类坑），只会让后来人以为显隐由 CSS 管。
   ⚠️ `.legal-panel` 是 `display:flex + overflow:hidden`，正文区自己滚（.legal-body overflow:auto）——
      不要改成整块滚动：长协议滚动时标题栏会跟着滚走，用户看不到自己在读哪一篇。
   ═══════════════════════════════════════════════════════════════════════════ */
.legal-mask { position: fixed; inset: 0; z-index: 900; display: flex; align-items: center; justify-content: center;
  padding: 16px; box-sizing: border-box; background: rgba(10, 20, 32, .58); }
.consent-mask { z-index: 950; }
body.legal-locked { overflow: hidden; }

.legal-panel { display: flex; flex-direction: column; width: min(720px, 100%);
  max-height: min(86vh, 780px); background: var(--panel); color: var(--ink);
  border: 1px solid var(--line); border-radius: 14px;
  box-shadow: 0 18px 48px rgba(8, 20, 34, .30); overflow: hidden; }
.legal-head { display: flex; align-items: center; gap: 8px; padding: 12px 14px; border-bottom: 1px solid var(--line); }
.legal-head > b { font-size: 15px; }
.legal-ver { margin-left: auto; color: var(--muted); font-size: 12px; }
.legal-foot { display: flex; justify-content: flex-end; gap: 8px; padding: 10px 14px; border-top: 1px solid var(--line); }
.legal-body { flex: 1 1 auto; overflow: auto; padding: 14px 16px; font-size: 13.5px; line-height: 1.78;
  -webkit-overflow-scrolling: touch; }

/* 渲染出来的 Markdown */
.legal-body h1 { font-size: 18px; margin: 2px 0 10px; }
.legal-body h2 { font-size: 15.5px; margin: 18px 0 8px; }
.legal-body h3 { font-size: 14px; margin: 14px 0 6px; }
.legal-body p { margin: 8px 0; }
.legal-body ul, .legal-body ol { margin: 8px 0; padding-left: 22px; }
.legal-body li { margin: 4px 0; }
.legal-body hr { border: none; border-top: 1px solid var(--line); margin: 16px 0; }
.legal-body blockquote { margin: 10px 0; padding: 10px 12px; border-left: 3px solid #e0a106;
  background: var(--bg); border-radius: 0 8px 8px 0; color: var(--ink); }
.legal-body blockquote p { margin: 4px 0; }
.legal-body code { background: var(--bg); border: 1px solid var(--line); border-radius: 4px;
  padding: 0 4px; font-size: 12.5px; }
.legal-body a { color: var(--primary); }
/* ⚠️ 表格必须显式 white-space:normal —— 全局 `th, td { white-space: nowrap }` 是给检验记录表写的，
   套在协议条款上会让每一格强行不换行、整张表横向溢出（协议里动辄三四十字的长句子）。 */
.legal-table { width: 100%; border-collapse: collapse; margin: 10px 0; font-size: 13px; table-layout: fixed; }
.legal-table th, .legal-table td { border: 1px solid var(--line); padding: 7px 9px;
  white-space: normal; word-break: break-word; vertical-align: top; text-align: left; }
.legal-table thead th, .svc-sec .legal-table th { background: var(--bg); font-weight: 600; }
.svc-sec .legal-table th { width: 92px; }
.legal-draft { margin: 0 0 12px; padding: 9px 12px; border: 1px dashed #e0a106; border-radius: 8px;
  background: rgba(224, 161, 6, .10); color: #8a6400; font-size: 12.5px; line-height: 1.65; }
.legal-fail { color: var(--danger); font-weight: 600; }
html[data-theme="dark"] .legal-draft { color: #e6b566; border-color: #8a6400; background: rgba(230, 181, 102, .10); }
html[data-theme="dark"] .legal-body a { color: #5fd3dd; }

/* 退款与客服 */
.svc-sec { margin: 0 0 16px; }
.svc-h { display: block; font-size: 14px; margin: 0 0 6px; }
.svc-tip { color: var(--muted); font-size: 12.5px; line-height: 1.72; margin: 6px 0 0; }
/* 「待填」必须看得见 —— 运营主体/客服渠道只能由运营方提供，标红是为了不让它被当成已填好就发布 */
.svc-todo { color: #b23a2e; background: rgba(178, 58, 46, .08); border: 1px dashed #d9534f;
  border-radius: 4px; padding: 0 4px; }
html[data-theme="dark"] .svc-todo { color: #ff8f83; border-color: #a3453c; background: rgba(255, 143, 131, .10); }

/* 首启同意弹窗 */
.consent-panel { width: min(560px, 100%); padding: 18px 20px 16px; gap: 10px; }
.consent-title { font-size: 17px; }

/* ⚠️⚠️ 手机视口下的**发布阻塞**修复（v371 真机实测 2026-09-19，桌面 e2e 抓不到）
   ───────────────────────────────────────────────────────────────────────────
   现象：360×640 真机上同意弹窗底部**看不到按钮、也滚不动** ⇒ 首启闸门过不去，App 完全不可用。
   根因：`.legal-panel` 是 `max-height: min(86vh, 780px)` + `overflow: hidden`，它靠**内部
        `.legal-body` 自己滚**（协议页就是这么做的）。而同意弹窗当初把正文直接写成 panel 的
        子元素、**没有那一层可滚动区** ⇒ 内容一旦超过 86vh 就被 overflow:hidden 裁掉，
        且整块没有 scrollport ⇒ 被裁的内容**永远不可达**。
       桌面 e2e 跑 1280×900，弹窗装得下，所以 47 条断言全绿；只有真机 640px 高才暴露
       —— 与「v352 桥对象写成 Java 类名」同属**桌面全绿 ≠ 真机可用**那一类。
   修法：照 .legal-panel 自己的既有设计分三段 —— 标题固定 / 正文滚 / 按钮固定。
   ⚠️ 承重的是三件事：① 它是 `.consent-panel`（`display:flex`）的子项 ② `flex: 1 1 auto`
      ③ `overflow-y: auto`（滚动容器）。三者缺一按钮就回到「被裁掉且滚不到」。
   ⚠️ 关于 `min-height: 0`（这里刻意留一句**实测订正**，免得下一个人把它当成承重点去"优化"）：
      它在本规则里**功能上是冗余的** —— Flexbox 的「自动最小尺寸」只在 flex 子项的
      `overflow` 为 `visible` 时才取内容高度；本元素 `overflow-y:auto` ⇒ 该值已经是 0。
      证据：受控实验把 `min-height` 改回 `auto` 后，E 段的几何**一模一样**
      （按钮 top=528 / 极端视口 maxScroll=349 / E2·E5·E6·E7·E8 全绿），只有「计算值必须为
      0px」那条形式断言会红。留着它只是显式化意图 + 万一以后有人把 overflow 改回 visible
      时它才真正承重。⇒ **不要**据此写「不加 min-height:0 就不生效」这类结论（我先前就是这么
      写错的，被自己的受控实验打回）。 */
.consent-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch;
  display: flex; flex-direction: column; gap: 10px; }
.consent-panel > .consent-title,
.consent-panel > .consent-acts,
.consent-panel > .consent-note { flex: 0 0 auto; }   /* 标题与按钮行不参与收缩 ⇒ 永远可见 */
.consent-lede { margin: 0; font-size: 13.5px; line-height: 1.78; color: var(--ink); }
.consent-points { margin: 0; padding-left: 18px; font-size: 13px; line-height: 1.72; color: var(--ink); }
.consent-points li { margin: 5px 0; }
.consent-links { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; font-size: 13px; }
.consent-link { border: none; background: none; padding: 0; color: var(--primary); font-size: 13px;
  text-decoration: underline; cursor: pointer; font-family: inherit; }
html[data-theme="dark"] .consent-link { color: #5fd3dd; }
.consent-acts { display: flex; justify-content: flex-end; gap: 10px; margin-top: 4px; }
.consent-note { font-size: 12.5px; line-height: 1.72; color: var(--muted); }
.consent-note.warn { color: #b23a2e; background: rgba(178, 58, 46, .07);
  border: 1px dashed #d9534f; border-radius: 8px; padding: 9px 11px; }
html[data-theme="dark"] .consent-note.warn { color: #ff8f83; border-color: #a3453c; background: rgba(255, 143, 131, .10); }

/* ==========================================================================
   🆕 v379（用户第 3 条）：指标趋势「当日信息悬浮窗」——**可操作**版
   --------------------------------------------------------------------------
   为什么不再用 ECharts 自带 tooltip：
     · 它天生**不可交互** —— 鼠标一移进去就消失，窗内没有任何东西点得动；
     · 它**贴着光标**弹出 ⇒ 用户实测「不可操作，会遮挡操作时光标的位置，容易误触」。
   本窗口改为**固定贴图表右上角**（`.chart-box` 已有 `position: relative`，见 L621/L2843），
   从根上消除「遮挡光标」这个成因；再给出 `pointer-events: auto`、窗内可点选的指标行、
   右上角 ✏️ 编辑 + 白色 ✕ 关闭。
   ⚠️ 全部颜色走 CSS 变量 ⇒ 夜间**自动**生效（夜间在 L1100 覆盖了 :root 变量）。
      不写 `html[data-theme="dark"]` 硬编码覆盖块 —— 硬编码白底/深字是本项目夜间问题的老根因。
   ⚠️ 不用 `display:none` 来做显隐：`[hidden]` 是 UA 的 `display:none !important`，作者样式压不过它，
      显隐一律由 JS 摘/挂 `hidden` 属性（本项目已有定论）。
   ⚠️ 宽度用 `min(340px, 100% - 16px)`：桌面端别铺满整个图，窄屏（≤640px）则自动占满可用宽度。
   ========================================================================== */
.trend-float {
  position: absolute; top: 8px; right: 8px; z-index: 30;
  width: min(340px, calc(100% - 16px));
  max-height: calc(100% - 16px);
  overflow: auto; -webkit-overflow-scrolling: touch;
  pointer-events: auto;            /* ★ 与 ECharts tooltip 的关键差别：窗内可操作 */
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: 0 6px 22px rgba(15, 23, 42, .16);
  padding: 8px 10px 9px;
  font-size: 12.5px; line-height: 1.62; color: var(--ink);
  text-align: left;
}
/* 🆕 v514（用户第 1 条）：指针在趋势图右半边时窗口翻到左边（见 js/app.js 的 tfApplySide）。
   只换锚边，其余尺寸/内边距/dark 覆盖全部沿用基类。 */
.trend-float.tf-left { left: 8px; right: auto; }
.tf-head { display: flex; align-items: center; gap: 8px; margin-bottom: 5px; }
.tf-head .tf-date { flex: 1 1 auto; font-weight: 700; font-size: 13px; }
.tf-head .tf-acts { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 5px; }
/* 右上角两个按钮：✏️ 编辑（纯笔形，与全软件行内图标同族）/ ✕ 关闭（灰底白叉，两种主题下都看得见） */
.tf-btn {
  border: 1px solid var(--line); background: none; color: var(--ink);
  width: 24px; height: 24px; padding: 0; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 13px; line-height: 1; cursor: pointer; font-family: inherit;
  -webkit-appearance: none; appearance: none;
}
.tf-btn svg { display: block; width: 14px; height: 14px; }
.tf-btn:hover { border-color: var(--primary); }
.tf-btn.tf-edit { color: var(--primary); }
.tf-btn.tf-edit:hover { background: rgba(14, 124, 134, .12); }
/* ★ 用户明确要求「白色的 ×」⇒ 深底 + 白字（`--muted` 那种浅字在白底上其实几乎看不见） */
.tf-btn.tf-close { background: #94a3b8; border-color: #94a3b8; color: #fff; font-size: 15px; }
.tf-btn.tf-close:hover { background: #64748b; border-color: #64748b; }
html[data-theme="dark"] .tf-btn.tf-close { background: #55657a; border-color: #55657a; color: #fff; }
html[data-theme="dark"] .tf-btn.tf-close:hover { background: #6b7d94; border-color: #6b7d94; }
/* 可点选的指标行：点一下即选中（高亮 + aria-pressed），选中项才是 ✏️ 编辑的目标 */
.tf-rows { display: flex; flex-direction: column; gap: 2px; }
.tf-row {
  display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap;
  padding: 3px 5px; border-radius: 6px; cursor: pointer;
  border: 1px solid transparent;
}
.tf-row:hover { background: rgba(14, 124, 134, .07); }
.tf-row[aria-pressed="true"] {
  background: rgba(14, 124, 134, .12); border-color: var(--primary);
}
html[data-theme="dark"] .tf-row:hover { background: rgba(95, 211, 221, .10); }
html[data-theme="dark"] .tf-row[aria-pressed="true"] { background: rgba(95, 211, 221, .16); border-color: #5fd3dd; }
.tf-dot { display: inline-block; width: 9px; height: 9px; border-radius: 2px; flex: 0 0 auto; }
.tf-name { font-weight: 600; }
.tf-val { font-weight: 700; }
.tf-tag-hi { color: #c0392b; font-weight: 600; }
.tf-tag-ok { color: #2e7d32; }
/* 🆕 v381：悬浮窗异常「偏离参考边界幅度」量化标注（偏高红 / 偏低蓝，与趋势图异常点配色一致） */
.tf-dev-hi { color: #d9534f; font-weight: 600; font-size: 11px; }
.tf-dev-lo { color: #2980b9; font-weight: 600; font-size: 11px; }
html[data-theme="dark"] .tf-dev-hi { color: #ff6b6b; }
html[data-theme="dark"] .tf-dev-lo { color: #5aa9e6; }
.tf-ref, .tf-tgt, .tf-base { color: #8593a3; font-size: 11px; }
.tf-basedev { color: #2980b9; font-weight: 600; font-size: 11px; }
/* 🆕 v385：悬浮窗「较上次测量变化」标注（对标 MyChart/Apple Health/Clinic 2026「change since last result」）；
   用中性灰、靠 ▲/▼ 箭头表达方向，不抢异常红 / 偏低蓝的语义 */
.tf-delta { color: #6b7a8d; font-size: 11px; font-weight: 500; }
html[data-theme="dark"] .tf-tag-hi { color: #ff8f83; }
html[data-theme="dark"] .tf-tag-ok { color: #4cc38a; }
html[data-theme="dark"] .tf-ref, html[data-theme="dark"] .tf-tgt,
html[data-theme="dark"] .tf-base { color: #9fb0c2; }
html[data-theme="dark"] .tf-basedev { color: #5aa9e6; }
html[data-theme="dark"] .tf-delta { color: #9fb0c2; }
/* 🆕 v439：悬浮窗「距目标偏离」量化标注（达标方向绿 / 偏离方向红，复用 goalDirection 同口径；
   与记录表 rec-target-ok / rec-target-miss 配色呼应），暗色态同步 */
.tf-tgtdev-ok { color: #2e7d32; font-weight: 600; font-size: 11px; }
.tf-tgtdev-miss { color: #c0392b; font-weight: 600; font-size: 11px; }
html[data-theme="dark"] .tf-tgtdev-ok { color: #4cc38a; }
html[data-theme="dark"] .tf-tgtdev-miss { color: #ff8f83; }
.tf-meds { margin-top: 6px; padding-top: 5px; border-top: 1px solid var(--line); font-size: 12px; }
.tf-meds .tf-meds-lb { color: #6b7a8d; }
html[data-theme="dark"] .tf-meds .tf-meds-lb { color: #9fb0c2; }
.tf-meds .tf-med { margin-top: 2px; }
.tf-meds .tf-med-dose { color: #6b7a8d; }
.tf-meds .tf-med-freq { color: #8593a3; }
html[data-theme="dark"] .tf-meds .tf-med-dose { color: #9fb0c2; }
html[data-theme="dark"] .tf-meds .tf-med-freq { color: #8593a3; }
.tf-hint { margin-top: 5px; font-size: 11px; color: var(--muted); line-height: 1.5; }
/* 窄屏：贴满可用宽度，别在小屏上只剩一条缝 */
@media (max-width: 640px) {
  .trend-float { top: 6px; right: 6px; width: calc(100% - 12px); max-height: calc(100% - 12px); font-size: 12px; }
  .trend-float.tf-left { left: 6px; }
}

/* ══════════ 🆕 v388（用户第 1 项②）：所有窗口之间的垂直间距统一为 14px ══════════
   缺陷形态（_probe_v388_layout.js 实测 #panel-trend 相邻块间距，改造前）：
     8 / **0** / 14 / 14 / 8 / 8 / 9.9 / 8 / 14 / 14 / 8 / 13.9 / 14 —— 8、0、14 三种值混用。
     其中「指标趋势图框(.chart-box) → 指标库窗口(#card-ind-lib)」为 **0**，
     正是用户原话「指标趋势窗口和下面的指标库窗口之间要有一定的宽度」指的那一处。
   做法：
     · 先把面板内所有直接子元素的 margin-bottom 归零 —— 不归零的话，会与后一个元素自己的
       margin-top 叠加成 14+8=22 之类的新乱值（.card 就有 margin-bottom:14px）；
     · 再用「相邻兄弟 + margin-top」统一给 14px。
   ⚠️ 两个必须保留的细节，改动前请先读：
     ① `!important` 是**必要的**，不是偷懒：指标分析 / 相关性 / 用药图例等窗口历史上各自写了
        `margin-top: 8px`，而它们是 ID 选择器（#ind-analysis 等），特异性高于本组类选择器
        ⇒ 不加 !important 时「归零」与「统一」会**静默失效**，间距看起来还是三种值。
     ② 排除 `.hint-q`：它是 hintsToCorner() 追加到面板上的问号按钮，`position:absolute`，
        若被加上 margin-top:14px，会连同 left/top 一起把问号**整体推走**（实测前 mt=0px）。
     ③ 用 `+` 相邻选择器而不是给 .panel 加 `display:flex; gap:14px`：面板里有 JS 生成的
        绝对定位子元素（#trend-float 等挂在 .chart-box 内、以及面板级的 .hint-q），
        改 flex 容器会改变它们的定位基准。display:none 的 .hint-src 仍参与选择器匹配但不占高度，
        所以它两侧的间距仍恰好是 14px。 */
.panel > *:not(.hint-q) { margin-bottom: 0 !important; }
.panel > * + *:not(.hint-q) { margin-top: 14px !important; }


/* ══════════════════════════════════════════════════════════════════════════════
   🆕 v391（用户第 3 项）：检验记录卡工具栏重排 = [🖨 导出][🔍 搜索(下拉)][＋ 添加记录][❓]
   用户原话「历史记录：『筛选』『全选』收进搜索按钮（放右上角加号左边，向下弹出）；UI skill
   美化并统一输入框样式；全选+删除放进下拉框；导出换打印图标放搜索左边，点击弹文件夹路径并
   跳转手机文件管理器」。
   ⚠️ 本段位于文件**最末**，与同特异性规则相比靠后必胜（沿用 v357/v359/v361/v388 段做法，全程不写 !important）。
   ══════════════════════════════════════════════════════════════════════════════ */

/* ── 卡片头：把 [🖨][🔍][＋][❓] 顶到右侧、与左侧标题同高 ──
   与 v391 给「📸 图片识别」的写法完全同构（见 #lab-entry-image 那组规则），根因也一样：
   `.card-head`（227 行）是 `justify-content: space-between`，本头有 4 个子元素时中间那几个
   会被摊到正中，＋ 与右侧问号之间就空出一大段。
   ⚠️ 必须用 id 选择器写 `margin-right: auto`：3855 行 `.card-head > h1/h2/h3 { margin: 0 }` 是简写，
      会重置 margin-right，类选择器压不过它。 */
/* ⚠️ `position: relative` 是 v391 第二轮补上的**必需项**：它是下面 #rec-filter-menu 的定位基准。
   为什么不能用 `.rec-find-wrap`（🔍 自己的包裹）当基准：`right: 0` 会对齐到 **🔍 的右缘**，
   而 🔍 右边还有「＋」与「❓」（20 + 6 + 26 = 52px），390px 视口下 🔍 右缘只到 x=309，
   366px 宽的面板于是 left = −57 ⇒ 整条面板有 57px 落在视口外、里面的按钮点不到（探针实测）。
   改用卡片头当基准后 `right: 0` 落在卡片右内缘（x=374），再配合收窄的宽度 ⇒ left ≥ 8px。 */
#card-rec-history > .card-head { position: relative; justify-content: flex-start; gap: 6px; }
#card-rec-history > .card-head > h2 { margin-right: auto; }
#card-rec-history > .card-head > .btn,
#card-rec-history > .card-head > .rec-find-wrap,
#card-rec-history > .card-head > .scan-add-wrap,
#card-rec-history > .card-head > .hint-q { flex: 0 0 auto; }

/* ── 🖨 / 🔍 两枚圆钮统一 20×20（与图片识别页的 🔍 同尺寸）──
   ⚠️ 必须连 min-height 一起复位：手机上 `.btn.tiny { min-height: 36px; padding: 5px 12px }`（1578 行）
      会把只写了 height 的按钮撑成 20×36 的椭圆（v391 第 2 项实测踩过同一个坑）。 */
#card-rec-history > .card-head > #btn-export-csv,
#card-rec-history > .card-head > .rec-find-wrap > #btn-rec-search {
  width: 26px; height: 26px; min-width: 26px; min-height: 26px;
  padding: 0; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 13px; line-height: 1;
}

/* ── 🔍 的下拉面板 ──
   用户原话「收进搜索按钮（放右上角加号左边，**向下弹出**）」⇒ 绝对定位在按钮下沿，
   定位基准是**卡片头**（`#card-rec-history > .card-head { position: relative }`），
   不是 `.rec-find-wrap` —— 原因见上方 C5 那条注释（锚在 🔍 上会左溢出 57px）。
   ⚠️ 用 `display: grid` 而**不是** flex，是刻意的：本面板控件与 `.rec-filter`（历史记录 + 用药记录
      共用的类）那批老规则挂在同一批元素上，其中 953/954 行有
      `.rec-filter select, .rec-filter input { flex: 1 1 120px }`、3299 行有
      `.rec-ind-group { flex: 1 1 100% }`。若本面板是 flex 容器，这些 flex 值会把控件拉成 120px 高
      / 满高；改成 grid 单列后 **flex 属性对 grid 子项一律无效**，那些老规则自动失效，不必去删它们
      （删了会连带影响用药记录表那一处同名的 .rec-filter）。
   ⚠️ `[hidden]` 必须显式压回（本项目老坑：作者 CSS 的 display 会盖掉 UA 的 [hidden]），
      且写在 `.open` **之后** —— 万一两个状态同时存在，以「隐藏」为准。 */
/* ⚠️ 这里**刻意不写** `position: relative`（与 css/scan.css 的 `.scan-add-wrap` 写法相反）——
   一旦它是 positioned，就会抢走下面 #rec-filter-menu 的定位基准，面板又会左溢出。
   定位基准改为卡片头（见上一条规则），本处只需要「并排」这一个语义。 */
.rec-find-wrap { display: inline-flex; }
#rec-filter-menu {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 40;
  display: none; grid-template-columns: 1fr; gap: 8px;
  /* ⚠️ 不用 `width: max-content`：内容（日期行 标签+两个日期框）的 max-content ≈ 366px，
     比卡片头右缘能给的空间还宽 ⇒ 左溢出。改成定宽 + 视口上限，两端都实测过 left ≥ 8px。 */
  width: min(360px, calc(100vw - 24px));
  margin: 0; padding: 10px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 8px 20px rgba(15, 30, 45, .18);
}
#rec-filter-menu.open { display: grid; }
#rec-filter-menu[hidden] { display: none; }
html[data-theme="dark"] #rec-filter-menu { background: #22303c; border-color: #3a4a5c; box-shadow: 0 8px 20px rgba(0, 0, 0, .45); }

/* 面板内的每一行：标签在左、控件在右并吃满剩余宽度。
   （原 347/348 行的 `.rec-filter` 规则只管到 flex 容器本身，「一行 = 一组」的语义在这里补回。） */
#rec-filter-menu .rec-f-row { display: flex; align-items: center; gap: 8px; flex-wrap: nowrap; }
#rec-filter-menu .rec-ind-group,
#rec-filter-menu .rec-date-range { display: flex; flex: 0 0 auto; flex-wrap: nowrap; }
#rec-filter-menu .rec-f-row > select,
#rec-filter-menu .rec-f-row > .rec-ind-group > select { flex: 1 1 auto; min-width: 0; }
#rec-filter-menu .rec-f-row > input[type="date"] { flex: 1 1 0; min-width: 0; }
/* ⚠️ 复位两条为「平铺在卡片里」写的规则：962 行 `.rec-date-presets { flex: 1 1 100%;
   justify-content: flex-end }` 与 1854 行 `margin-top: 4px`。进了面板要回到左对齐、贴紧上一行。 */
#rec-filter-menu .rec-date-presets {
  display: flex; gap: 6px; margin-top: 0; justify-content: flex-start; flex: 0 0 auto;
}
#rec-filter-menu .rec-search { width: 100%; min-width: 0; }

/* 面板底部的「全选 / 删除」—— 用户原话「全选+删除放进下拉框」。
   加一条上虚线分隔，把「筛选区」与「批量操作区」在视觉上分开，降低误点删除的概率。 */
#rec-filter-menu .rec-f-bulk {
  display: flex; align-items: center; gap: 8px;
  padding-top: 8px; border-top: 1px dashed var(--line);
}
#rec-filter-menu .rec-f-bulk .btn { flex: 1 1 auto; min-width: 0; }

/* ── 用户第 3 项原话「UI skill 美化并统一输入框样式」在这里落地 ──
   实测**改造前**同一个面板里三种控件三种规格：搜索框 14px / 下拉 14px / 日期框 15px。
   根因（读源码得，非推测）：1584-1588 行（≤640px）给 `.rec-search` 定的是 15px（(0,1,0)），
   但 1853 行 `.rec-filter select, .rec-filter input { font-size: 14px }` 是 (0,1,1) ⇒ 压过它；
   而日期框走的是 id 选择器 `#rec-date-start / #rec-date-end`（(1,0,0)）⇒ 不受 1853 影响，留在 15px。
   ⇒ 修法：用 id 作用域一次钉死三者，两端各一套值（桌面 36px/14px/8px，手机 42px/15px/10px，
      手机那套沿用 1581 行「触控加大 + 避免 iOS 聚焦缩放」的既有口径）。
   ⚠️ 不去改 1853 行：用药记录表的筛选区同样挂 `.rec-filter` 类，但那边只有「状态 + 搜索」，
     本来就内部一致；动了会连带改变那一处的观感。 */
#rec-filter-menu .rec-search,
#rec-filter-menu .rec-f-row > select,
#rec-filter-menu .rec-date-range > input[type="date"] {
  font-size: 14px; border-radius: 8px; min-height: 36px; padding: 7px 10px;
}
@media (max-width: 640px) {
  #rec-filter-menu { width: min(320px, calc(100vw - 24px)); }
  #rec-filter-menu .rec-search,
  #rec-filter-menu .rec-f-row > select,
  #rec-filter-menu .rec-date-range > input[type="date"] {
    font-size: 15px; border-radius: 10px; min-height: 42px;
  }
}
/* ---------- 🆕 v391（用户第 9 条）：「举个栗子」🌰 示例按钮 ----------
   🌰 = 举个「栗子」（示例）。窗口无数据时，按钮**骑在该窗口卡片的上边框右端**。
   为什么 right:34px —— 卡片右上角已被 ❓（.hint-q）占用，而它有两种形态：
     · 绝对定位形态（多数卡片）：position:absolute; top:8px; right:8px; 宽 20 ⇒ 占右缘 8~28px；
     · 流式形态（#lab-entry-image / #card-rec-history / #card-med-list，见本文件 3174/4134 行一带）：
       作为 .card-head 的 flex 子项 ⇒ 贴着卡片内容右缘，宽 20 ⇒ 大致占右缘 15~37px。
   取 34px 让**两种形态都不与 ❓ 相撞**，且所有卡片的 🌰 落点一致（用户只需记一次位置）。
   骑边框靠 top:0 + translateY(-50%)：卡片已 position:relative（2583 行）、且全项目**没有**
   任何给 .card 设 overflow 的规则（已核）⇒ 探出卡片上半枚不会被裁。
   刻意**不挂 .btn 类**：那样会吃下手机端 `.btn.tiny{min-height:36px}`（1578 行）被撑成椭圆；
   本类自己钉死 min-height，免受断点规则波及。 */
.cm-demo-badge {
  /* 🆕 v417：❓→🌰 统一 26px 后让位宽度 8+26+6=40（原 34 按 ❓20px 反推） */
  position: absolute; top: 0; right: 40px; transform: translateY(-50%);
  z-index: 5; margin: 0; padding: 0; box-sizing: border-box;
  width: 28px; height: 28px; min-width: 28px; min-height: 28px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 15px; line-height: 1; cursor: pointer;
  background: var(--panel); border: 1px solid var(--line); border-radius: 50%;
  box-shadow: 0 2px 8px rgba(20, 40, 60, .18); transition: .15s;
  -webkit-appearance: none; appearance: none;
}
.cm-demo-badge:hover, .cm-demo-badge:focus {
  border-color: var(--primary); outline: none; box-shadow: 0 3px 10px rgba(20, 40, 60, .26);
}
html[data-theme="dark"] .cm-demo-badge { background: #1a2431; }
@media (max-width: 640px) { .cm-demo-badge { right: 40px; } }

/* ═══════════ 🆕 v415（2026-09-24）：用药编辑弹窗 / 三页变更记录拆分 / 用药搜索下拉 / 图例压缩 ═══════════ */

/* ── ① 用药记录表 🔍 下拉面板（与 #rec-filter-menu 完全同构）──
   定位基准 = 卡片头：锚在 🔍 自己的包裹上会左溢出（v391 在 #rec-filter-menu 上实测过的坑，见 4156 行）。
   ⚠️ position:relative 加在 .card-head 上会把 hintsToCorner 追加的 ❓（absolute top:8 right:8）
      的锚从 .card 挪到 .card-head —— 两者都在卡片右上角，视觉不变，无回归。 */
#card-med-list > .card-head { position: relative; }
#med-filter-menu {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 40;
  display: none; grid-template-columns: 1fr; gap: 8px;
  width: min(300px, calc(100vw - 24px));
  margin: 0; padding: 10px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 8px 20px rgba(15, 30, 45, .18);
}
/* ⚠️ [hidden] 必须显式压回且写在 .open 之后（本项目老坑：作者 display 盖掉 UA 的 [hidden]） */
#med-filter-menu.open { display: grid; }
#med-filter-menu[hidden] { display: none; }
html[data-theme="dark"] #med-filter-menu { background: #22303c; border-color: #3a4a5c; box-shadow: 0 8px 20px rgba(0, 0, 0, .45); }
#med-filter-menu .rec-f-row { display: flex; align-items: center; gap: 8px; flex-wrap: nowrap; }
#med-filter-menu .rec-f-row > select { flex: 1 1 auto; min-width: 0; }
#med-filter-menu .rec-search { width: 100%; min-width: 0; }
html[data-theme="dark"] #med-filter-menu .rec-search,
html[data-theme="dark"] #med-filter-menu .rec-f-row > select { background: #161d24; border-color: #2d3946; color: #e6edf3; }
/* 🔍 圆钮 20×20：必须连 min-height 一起复位（手机 .btn.tiny{min-height:36px} 会撑成椭圆，见 4168 行注释） */
#card-med-list .med-find-wrap > #btn-med-search {
  width: 26px; height: 26px; min-width: 26px; min-height: 26px;
  padding: 0; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 13px; line-height: 1;
}

/* ── ② 用药图例压缩成紧凑小条（用户确认方案）──
   原 v221 的整行大块（padding 6px 12px + 日期列）占地太高；压缩为胶囊小条：
   色块 10px 圆点 + 药名 12px，起止日期挪进悬浮 title（renderMedLegend 同步改）。
   ⚠️ 本段在源码顺序上晚于 1641 行 @media 里的 .legend-item 覆盖 ⇒ 同特异性下后者被本段压住（预期）。 */
.med-legend { margin-top: 10px; }
.med-legend h3 { font-size: 12px; margin: 0 0 6px; color: var(--muted); font-weight: 600; }
.legend-items { display: flex; flex-wrap: wrap; gap: 6px; }
.legend-item { display: inline-flex; align-items: center; gap: 5px; padding: 2px 9px; border-radius: 999px; font-size: 12px; cursor: pointer; }
.legend-item .sw { width: 10px; height: 10px; border-radius: 50%; flex: 0 0 auto; }

/* ── ③ 用药编辑弹窗（#med-edit-modal，内容由 openMedEdit() 动态填充）──
   .def-popup-content 已带 width:min(620px,94vw) + max-height:min(86vh,640px) ⇒ 天然不超屏；
   这里收窄一档并让表单区内部滚动。 */
.med-edit-pop { width: min(560px, 94vw); }
.med-edit-pop .def-body { overflow-y: auto; padding: 14px 18px 6px; }
.med-edit-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 12px; }
.med-edit-grid label { display: flex; flex-direction: column; gap: 4px; font-size: 12.5px; color: var(--ink); min-width: 0; }
.med-edit-grid label.span2 { grid-column: 1 / -1; }
.med-edit-grid input, .med-edit-grid select, .med-edit-grid textarea {
  font: inherit; padding: 7px 9px; border: 1px solid var(--line); border-radius: 8px;
  background: var(--panel); color: var(--ink); min-width: 0; width: 100%;
  box-sizing: border-box;
}
.med-edit-grid textarea { resize: vertical; min-height: 68px; line-height: 1.5; }
html[data-theme="dark"] .med-edit-grid input,
html[data-theme="dark"] .med-edit-grid select,
html[data-theme="dark"] .med-edit-grid textarea { background: #161d24; border-color: #2d3946; color: #e6edf3; }
.med-edit-foot { display: flex; justify-content: flex-end; gap: 8px; padding: 12px 18px 16px; border-top: 1px solid var(--line); flex: 0 0 auto; }
@media (max-width: 480px) { .med-edit-grid { grid-template-columns: 1fr; } }

/* ============================================================================
   🆕 v499（用户第 10 项）：用药「添加」弹窗 + 编辑弹窗的窗口内说明文字
   ── 用户原话：
        · 「点添加的时候不要跳转到用药记录表了，直接在今日用药清单下拉打开」
        · 「所有编辑窗口外面的说明文字放到编辑窗口里面去」
        · 「添加窗口右上角加一个关闭窗口的按钮」
        · 「用药记录表中的编辑按钮弹窗也是一样，所有说明文字放到编辑窗口里面」
   ── 落地：
        · 录入表单 `#form-med` 从「📋 用药记录表」卡片内搬进新的 `#med-add-modal`
          （见 index.html）⇒ 点「＋ → ＋ 添加用药」就地弹窗，不再跳到 / 滚到用药记录表。
        · 说明文字统一由 `.med-edit-note` 承载，**写在弹窗内部**（添加窗 + 编辑窗同一套样式）。
        · 右上角关闭键复用既有的 `.def-close`（定义弹窗同款 30px 圆钮），
          编辑弹窗由 js/app.js 的 openMedEdit() 在 header 里追加同一颗。
   ============================================================================ */
.med-add-pop { width: min(560px, 94vw); }
.med-add-pop .def-body { overflow-y: auto; padding: 14px 18px 18px; }
/* 表单本身不再需要上外边距（旧版在卡片里靠 margin-top 与提示分隔） */
.med-add-pop #form-med { margin-top: 0; }
/* 弹窗内底部按钮行：与 .med-edit-foot 同构（右对齐、按钮间 8px），但不带顶部分隔线 */
.med-add-pop .def-foot { display: flex; justify-content: flex-end; gap: 8px; margin-top: 4px; }

.med-edit-note {
  margin: 0 0 12px; padding: 9px 12px;
  font-size: 12.5px; line-height: 1.6;
  color: #2b5560; background: #eef8f9;
  border: 1px solid #cfe9ec; border-left: 3px solid var(--primary);
  border-radius: 8px;
}
.med-edit-note b { color: #0e5a63; }
html[data-theme="dark"] .med-edit-note { color: #b9d6da; background: #12303a; border-color: #1f4d57; border-left-color: var(--primary); }
html[data-theme="dark"] .med-edit-note b { color: #7fdde4; }
/* 两个用药弹窗的 header 都是 flex + space-between ⇒ h3 靠左、关闭键天然靠右；
   这里只保证它不被 h3 挤扁。 */
.def-popup-content header .def-close { flex: 0 0 auto; margin-left: auto; }

/* ============================================================================
   🆕 v499（用户第 10 项）：「编辑按钮左边的三个按钮都统一按圆形图案设计」
   ── 行内图标钮的规格本来就是 `.act-ico`（26×26 正圆），但只有 `.act-edit`（铅笔）
      带一圈描边，`.act-del`（红底白叉）是实心圆，剩下三颗（复 / 📦 / 📷）以及
      指标识别表里的 ↑↓ 都是**没有轮廓的孤立字形**，看上去不像按钮、也不统一。
   ── 做法：给**除删除外**的所有行内图标钮补上同一圈描边 ⇒ 全站行内按钮统一为
      「空心圆（带描边）」+「实心红圆（删除）」两种形态。
   ⚠️ 本段位于文件靠后位置：与 `.act-ico.act-edit{border:…}`(0,2,0) 特异性相同，
      靠源序取胜、不写 !important；而 `.act-ico.act-edit.is-done`(0,3,0) 的绿色描边
      特异性更高，仍会正确压过本段（「改」进入完成态时该显示绿圈）。
   ⚠️ `.act-del` 用 :not() 排除 —— 它是实心红圆，加描边会变成红圈套红底、发糊。
   ============================================================================ */
.act-ico:not(.act-del) { border: 1px solid rgba(14, 124, 134, .45); }
.act-ico:not(.act-del):hover { border-color: var(--primary); }
html[data-theme="dark"] .act-ico:not(.act-del) { border-color: rgba(127, 221, 228, .42); }
html[data-theme="dark"] .act-ico:not(.act-del):hover { border-color: #7fdde4; }

/* ============================================================================
   🆕 v499（用户第 10 项）：今日用药卡片改「横向紧凑」布局
   ── 用户原话（配 @image#2）：「今日用药的留白太多了，勾选和日期放在一行，
      药品的其他信息水平排开。」
   ── 原布局：`.today-med` 是一行 flex，中间 `.tm-body` 是**竖排**（药名一行 / 剂量·频次一行 /
      各种 chips 再各占一行、每个都带 margin-top:4px），右侧「始于 …」用 margin-left:auto 顶到最右。
      结果：药名与「始于」之间是一大片空白，卡片还很高。
   ── 新布局：卡片与 `.tm-body` 都改成**可换行横向流**（flex-wrap），所有 chips 的
      上下外边距归零；并用 `order` 把「始于 …」提到 `.tm-body` 之前、`.tm-body` 用
      `flex:1 1 100%` 独占后续行 ⇒ 勾选（✓ 圆钮）与日期（始于 …）落在同一行，
      其余信息自第二行起横向排开、一行放不下才换行。补给余量条保持独占一行。
   ⚠️ 本段放在文件靠后位置：≤380px 块里有 `.tm-meta{display:block;margin-top:3px}`、
      `.today-med{align-items:flex-start}` 等**同名特异性**的规则，靠源序才能压过它们。
   ⚠️ `.tm-body` 的 `flex:1 1 100%` 必须保留：既让「始于 …」的 margin-left:auto 在同一行
      正确吃掉剩余空间，也保证 body 一定换到下一行（auto 外边距需要容器先吃到剩余空间）。
   ============================================================================ */
.today-med { flex-wrap: wrap; align-items: center; row-gap: 4px; }
.today-med .tm-body {
  display: flex; flex-direction: row; flex-wrap: wrap; align-items: center;
  gap: 3px 8px; flex: 1 1 100%; order: 3; min-width: 0; line-height: 1.35;
}
/* 横向排开后，这些 chip 不再需要各自的 margin-top（那是竖排时代的产物） */
.today-med .tm-body > .tm-meta,
.today-med .tm-body > .tm-stock,
.today-med .tm-body > .tm-refill,
.today-med .tm-body > .tm-ef,
.today-med .tm-body > .tm-taken-time,
.today-med .tm-body > .tm-missed-chip,
.today-med .tm-body > .tm-prn-line { margin-top: 0; }
/* 「始于 …」= 用户第 10 项说的「日期」。用 order 把它**提到 .tm-body 之前**（take/skip/dot 之后），
   而 .tm-body 用 `flex:1 1 100%` 强制独占后续行 ⇒ 首行 = [勾选][跳过][色点] …… [日期]，
   第二行起 = 药名/规格/频次/口服/过期/已用 …（.tm-body 内部横向排开、放不下才换行）。
   ⚠️ 不能只靠 DOM 顺序：DOM 里 .tm-body 在 .tm-start 之前，而 .tm-body 因内容过长**必然**换行，
      会把日期一并挤到末行（v499 首次实测：take@373 / name@409 / meta@432 / start@455 —— 日期与勾选不同行）。 */
.today-med .tm-start { order: 2; margin-left: auto; padding-left: 8px; align-self: center; }
/* 补给余量条独占一行，横向拉满（旧版 max-width:190px 在横排里会显得很小） */
.today-med .tm-body > .tm-refillbar { flex: 1 1 100%; max-width: none; margin-top: 2px; }

/* ── ④ 备注多行换行显示（用户需求 1「有多条备注的时候换行记录」）──
   备注里的换行符原样存在 m.note（
），表格 .med-c-note 用 pre-line 渲染成多行，
   不用 <br> 注入（esc() 之后仍是纯文本，安全面最小）。 */
#med-list td.med-c-note { white-space: pre-line; }

/* ── ⑤ 🆕 v416：各药依从率（按药物拆分的用药依从，对标 Medisafe/MyTherapy/CareClinic 2026「per-medication adherence」）──
   纯只读派生 localStorage(cm-taken-detail) + state.meds，不写任何病历/用药数据；无打卡数据时整卡由 JS 隐藏。 */
.med-adh-drug { margin-top: 4px; }
.mad-list { display: flex; flex-direction: column; gap: 9px; }
.mad-row { display: grid; grid-template-columns: minmax(88px, 1.2fr) minmax(90px, 2fr) 52px auto; align-items: center; gap: 10px; font-size: 13px; }
.mad-name { color: var(--ink); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mad-bar { position: relative; height: 9px; border-radius: 6px; background: var(--line); overflow: hidden; }
.mad-fill { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 6px; transition: width .25s ease; }
.mad-fill-ok { background: #2e9e5b; }
.mad-fill-warn { background: #e08a1e; }
.mad-fill-bad { background: #d64545; }
.mad-rate { font-weight: 700; text-align: right; font-variant-numeric: tabular-nums; }
.mad-rate-ok { color: #2e9e5b; }
.mad-rate-warn { color: #e08a1e; }
.mad-rate-bad { color: #d64545; }
.mad-rate-na { color: var(--muted); }
.mad-sub { color: var(--muted); font-size: 11.5px; white-space: nowrap; }
.mad-na .mad-name { color: var(--muted); font-weight: 500; }
.mad-foot { margin-top: 10px; color: var(--muted); font-size: 11.5px; }
@media (max-width: 480px) {
  .mad-row { grid-template-columns: 1fr 64px; grid-template-areas: "name rate" "bar sub"; row-gap: 3px; }
  .mad-name { grid-area: name; }
  .mad-rate { grid-area: rate; }
  .mad-bar { grid-area: bar; }
  .mad-sub { grid-area: sub; text-align: right; }
}
html[data-theme="dark"] .med-adh-drug .mad-bar { background: #2d3946; }
html[data-theme="dark"] .mad-fill-ok { background: #35b86b; }
html[data-theme="dark"] .mad-fill-warn { background: #f0a23a; }
html[data-theme="dark"] .mad-fill-bad { background: #ec5b5b; }

/* ── 🆕 v521（需求13/15a）：合并后的「用药依从分析」「用药安全预警」卡内子分区 ── */
.adh-sub + .adh-sub { margin-top: 14px; padding-top: 12px; border-top: 1px dashed var(--line); }
.adh-sub-h { margin: 0 0 6px; font-size: 13.5px; font-weight: 600; color: var(--ink); }
html[data-theme="dark"] .mad-rate-ok { color: #35b86b; }
html[data-theme="dark"] .mad-rate-warn { color: #f0a23a; }
html[data-theme="dark"] .mad-rate-bad { color: #ec5b5b; }
/* ═══════════ 🆕 v417（2026-09-25）：卡片头右上角图标统一规格（用户需求 2） ═══════════
   统一口径：卡片头内右上角图标钮一律 26×26 圆形、间距 6px（.card-head gap）、
   与 h2 由 flex align-items:center 天然共中线（「与窗口标题等高」）。
   ⚠️ 上面各处特化规则（🔍/🖨/❓）已同步改成 26×26 —— 这里只收拢「还没被特化规则管到的」
      卡片头文字/图标按钮（如 ⚙️、＋、关闭钮等 .btn.tiny）。行内表格按钮（.act-ico）不受影响。 */
.card-head { gap: 6px; }
.card-head > .btn.tiny,
.card-head .scan-add-wrap > .btn.tiny {
  width: 26px; height: 26px; min-width: 26px; min-height: 26px;
  padding: 0; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 14px; line-height: 1;
}
/* 🌰 字形在 26px 圆内的基线微调（emoji 各平台略沉） */
.hint-q.hint-nut { font-size: 14px; line-height: 24px; opacity: .9; }
/* ⛔ 已退役（v560）：这里原有一条 v556 的 `#lab-entry-image .card-head > #btn-thumbs-refresh`
   文字胶囊钮声明（width:auto + padding 0 10px + border-radius:999px）。
   退役原因：v560 起该键改成了**纯 SVG 图标圆钮**（`.btn.tiny.ico-refresh`，样式在 scan.css 尾部），
   而本段的 id 特异度 (1,0,1) 高于 `.card-head > .btn.tiny`(0,3,1) 和
   `.card-head .btn.tiny.ico-refresh`(0,4,0) ⇒ 会把圆钮压回 999px 胶囊（v560 实测 r=999px）。
   ⚠️ 不要再把文字胶囊的几何写回来；要改尺寸/形状请改 scan.css 的 `.ico-refresh` 那一段。 */

/* ── 🆕 v417：药名中缀补全下拉（#med-name / #me-name 共用）── */
.med-name-ac {
  position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 60;
  background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
  box-shadow: 0 8px 20px rgba(15, 30, 45, .18);
  max-height: 220px; overflow-y: auto;
}
.med-name-ac-item { padding: 8px 12px; font-size: 13px; color: var(--ink); cursor: pointer; }
.med-name-ac-item:hover, .med-name-ac-item:focus { background: rgba(14, 124, 134, .1); outline: none; }
html[data-theme="dark"] .med-name-ac { background: #22303c; border-color: #3a4a5c; }
html[data-theme="dark"] .med-name-ac-item { color: #e6edf3; }

/* ── 🆕 v417（用户需求 5）：图片识别 / 文件识别改为页签 ── */
.lab-tabs {
  display: flex; gap: 8px; margin: 2px 0 12px;
}
.lab-tab {
  appearance: none; border: 1px solid var(--line); background: var(--panel); color: var(--muted);
  padding: 8px 18px; border-radius: 999px; font: inherit; font-size: 13.5px; font-weight: 600;
  cursor: pointer; transition: background .15s, color .15s, border-color .15s;
}
.lab-tab:hover { border-color: var(--primary); color: var(--primary); }
.lab-tab.on {
  background: var(--primary); border-color: var(--primary); color: #fff;
  box-shadow: 0 2px 8px rgba(14, 124, 134, .28);
}

/* ── 🆕 v419：指标库 🔍 下拉面板（与 #med-filter-menu 完全同构）──
   用户 2026-09-26：「指标库中的搜索框靠窗口右侧栗子的左边摆放，全部勾选放到搜索窗口下拉打开」。
   定位基准 = 卡片头（锚在 🔍 包裹上会左溢出，v391 在 #rec-filter-menu 实测过的坑）。 */
#card-ind-lib > .card-head { position: relative; justify-content: flex-start; }
#card-ind-lib > .card-head > h2 { margin-right: auto; }
#card-ind-lib > .card-head .btn,
#card-ind-lib > .card-head .rec-find-wrap { flex: 0 0 auto; }
#card-ind-lib > .card-head .card-head-actions { display: inline-flex; align-items: center; gap: 6px; }
#ind-filter-menu {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 40;
  display: none; grid-template-columns: 1fr; gap: 8px;
  width: min(300px, calc(100vw - 24px));
  margin: 0; padding: 10px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 8px 20px rgba(15, 30, 45, .18);
}
#ind-filter-menu.open { display: grid; }
#ind-filter-menu[hidden] { display: none; }
html[data-theme="dark"] #ind-filter-menu { background: #22303c; border-color: #3a4a5c; box-shadow: 0 8px 20px rgba(0, 0, 0, .45); }
#ind-filter-menu .rec-search { width: 100%; min-width: 0; padding-right: 28px; }
#ind-filter-menu #btn-ind-toggle { justify-self: start; }
/* ── 🆕 v513（用户第 6 项）：搜索弹窗三处修正 ──
   ① 「排列参差不齐」的根因：本面板是 `display:grid; grid-template-columns:1fr`（5279 行），
      而此前**只有** `#btn-ind-toggle` 写了 `justify-self:start`，`#btn-ind-abn` 没写 ⇒
      后者被拉伸成整列宽（右边与前者不对齐）。⇒ 新增的每一颗按钮都显式 `justify-self:start`。
   ② 用户：「异常拆成恶化、改善、恢复正常三种」⇒ 原单颗 `#btn-ind-abn` 拆成三颗（.ind-abn-btn），
      放在一个可换行的行容器里（窄屏自动折行，不再是纵向三条长短不一的整行按钮）。
   ③ 用户：「退出弹窗增加个叉号」⇒ 面板右上角一颗 ✕（绝对定位，搜索框已留 28px 右内边距避让）。 */
#ind-filter-menu .ind-abn-row { display: flex; flex-wrap: wrap; gap: 6px; justify-content: flex-start; }
#ind-filter-menu .ind-abn-row > .btn { justify-self: start; flex: 0 0 auto; }
#ind-filter-menu #btn-ind-filter-close {
  position: absolute; top: 5px; right: 5px; z-index: 2;
  width: 22px; height: 22px; min-width: 22px; min-height: 22px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%; border: 1px solid transparent; background: transparent;
  color: var(--muted); font-size: 15px; line-height: 1; cursor: pointer;
}
#ind-filter-menu #btn-ind-filter-close:hover {
  color: #c0392b; border-color: var(--line); background: rgba(192, 57, 43, .10);
}
html[data-theme="dark"] #ind-filter-menu #btn-ind-filter-close:hover { color: #e5736f; }
/* 三档按钮的选中态（弹窗内是 .btn.tiny，不是 .rec-ov-btn ⇒ 单独给一条实底样式） */
#ind-filter-menu .ind-abn-btn[aria-pressed="true"],
#ind-filter-menu .ind-abn-btn[aria-pressed="true"]:hover {
  background: var(--primary); border-color: var(--primary); color: #fff; font-weight: 600;
}
/* 🆕 v513：档位筛选后的空态说明（#alerts-inline 里）—— 不能静默隐藏，否则用户以为软件坏了 */
.ac-detail .ac-empty-note {
  padding: 10px 12px; font-size: 12.5px; line-height: 1.65; color: var(--muted);
  background: rgba(0, 0, 0, .03); border: 1px dashed var(--line); border-radius: 10px;
}
html[data-theme="dark"] .ac-detail .ac-empty-note { background: rgba(255, 255, 255, .05); }
/* 🆕 v513：指标库空态里的「清除筛选」行内按钮 */
.link-btn {
  appearance: none; border: 0; background: transparent; padding: 0 2px;
  font: inherit; color: var(--primary); cursor: pointer; text-decoration: underline;
}


/* ═══════════ 🆕 v420（2026-09-26 用户 11 条需求）样式段 ═══════════ */

/* ── 1. 趋势卡图例组：四组各一行、靠左 ── */
/* 🆕 v434：gap 6→9 —— 第 4 行（echarts 自带指标图例，画布绘制）的中心距实测 37px，
   三行自定义图例行 28px 高 + gap 9 = 同一节奏，四行行距视觉统一 */
.tl-legend-groups { margin: 8px 0 4px; display: flex; flex-direction: column; gap: 9px; }
.tl-row { display: flex; align-items: center; gap: 8px; min-height: 28px; flex-wrap: nowrap; overflow-x: auto; }
.tl-row-name { flex: 0 0 auto; font-size: 12.5px; font-weight: 700; color: var(--muted); white-space: nowrap; }
.tl-row-body { flex: 1 1 auto; display: flex; align-items: center; gap: 6px; flex-wrap: nowrap; overflow-x: auto; padding: 2px 0; }
.tl-row-body::-webkit-scrollbar { height: 4px; }
.tl-chip { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 5px; font-size: 12px;
  color: var(--ink); background: var(--panel); border: 1px solid var(--line); border-radius: 999px; padding: 2px 9px; white-space: nowrap; cursor: pointer; }
.tl-chip .sw { width: 10px; height: 10px; border-radius: 50%; display: inline-block; }
.tl-chip.off { opacity: .38; }
.tl-empty { font-size: 12px; color: var(--muted); }
.tl-row-edit { flex: 0 0 auto; width: 22px; height: 22px; min-width: 22px; min-height: 22px; padding: 0;
  border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-size: 12px; }

/* ── 2. 趋势概览合并卡（原散卡分节） ── */
.trend-summary { margin-top: 10px; }
.trend-summary .critical-alert { margin: 0 0 8px; }
.trend-summary .ts-section { padding: 6px 0; border-top: 1px dashed var(--line); }
.trend-summary .ts-section:first-of-type { border-top: 0; }

/* ── 3. 指标库 🔍 与图片识别同规格（26×26 圆钮）── */
#card-ind-lib > .card-head .rec-find-wrap > #btn-ind-search {
  width: 26px; height: 26px; min-width: 26px; min-height: 26px; padding: 0; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center; font-size: 13px; line-height: 1;
}
#card-ind-lib > .card-head { justify-content: flex-start; }
#card-ind-lib > .card-head > h2 { margin-right: auto; }
#card-ind-lib .card-head .hint { display: none; }

/* ── 🆕 v513（用户第 6 项）：指标库「五段计数条」（替换 v500 的只读「12/38」钮）──
   用户口径（第 3 轮追认）：「指标库里标题行的数值按钮按照任务中要求的来」
   ⇒ 与趋势概览同一套五段条「共 N 项 · 恶化 a · 改善 b · 恢复正常 c · 原有正常 d」，
     其中 恶化 / 改善 / 恢复正常 三颗可点（筛选指标库 + 趋势图），另两段纯文本；**两处共用同一筛选态**。
   ⚠️ 位置：它是 `.card > #ind-count-bar`（卡头的**兄弟**、独立占一行），**不是**卡头里的元素 ——
      原因见 index.html 那段注释（放进卡头会让标题行折行 ⇒ 撞 `_e2e_v357_icons.js` G7 的 ≤36px 头部带）。
   ⚠️ 因此这里**不要**给 `#card-ind-lib > .card-head` 加 flex-wrap / order 之类 —— 卡头必须保持单行。 */
#ind-count-bar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 2px 0 8px; font-size: 12.5px; }
#ind-count-bar .rec-ov { padding: 1px 8px; gap: 4px; }
#ind-count-bar .rec-ov-item { font-size: 11.5px; gap: 3px; }
#ind-count-bar .rec-ov-item b { font-size: 12.5px; }

/* ── 4. 文件识别卡头 4 钮统一 26×26 圆（与图片识别一致）── */
#lab-entry-file > .card-head { justify-content: flex-start; gap: 6px; position: relative; }
#lab-entry-file > .card-head > h2 { margin-right: auto; }
#lab-entry-file > .card-head > .btn {
  width: 26px; height: 26px; min-width: 26px; min-height: 26px; padding: 0; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center; font-size: 13px; line-height: 1;
  background: var(--panel); border: 1px solid var(--line); color: var(--ink); flex: 0 0 auto;
}
#lab-entry-file > .card-head .hint { display: none; }

/* ── 5. 卡头圆钮统一外观（今日用药/日常测量等：＋ 不再 teal 实心，与同排图标同族）── */
.card-head { gap: 6px; }
.card-head > .btn.rec-add-plus, .card-head .rec-add-wrap > .rec-add-plus {
  width: 26px; height: 26px; min-width: 26px; min-height: 26px; padding: 0; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center; font-size: 15px; line-height: 1;
  background: var(--panel); border: 1px solid var(--line); color: var(--ink);
  box-shadow: none; flex: 0 0 auto;
}
#panel-vitals .card-head, #panel-med .card-head { justify-content: flex-start; }
#panel-vitals .card-head > h2, #panel-med .card-head > h2 { margin-right: auto; }

/* ── 6. 圆头板栗 SVG / 趋势卡 🌰 ── */
.hint-nut-btn .nut-ico, .hint-q .nut-ico { display: block; }
.hint-nut-btn { font-size: 13px; }
.cm-demo-badge .nut-ico { width: 18px; height: 18px; }

/* ── 7. 首页页签四宫格图标 ── */
.home-grid-ico { display: inline-grid; grid-template-columns: 1fr 1fr; gap: 2.5px; width: 15px; height: 15px; }
.home-grid-ico i { background: currentColor; border-radius: 2.5px; opacity: .95; }

/* ── 8. 会员窗口「关于」卡（原下拉弹窗内容） ── */
.member-about-inner { position: static !important; display: block; box-shadow: none; border: 0; padding: 0; width: auto; }
#member-about .bm-row, #about-inner .bm-row { display: flex; justify-content: space-between; gap: 10px; padding: 6px 0; border-bottom: 1px dashed var(--line); font-size: 13px; }

/* ── 9. 左侧彩虹页签 rail（需求 9：铺满左边框，分段对应本页窗口，滚动跟随） ── */
/* 🆕 v423（用户）：rail 改 fixed 一屏压缩条 —— 不再跟随页面总高（原来是 absolute 铺满整个
   panel，页面一长下面的段全在屏幕外）；现在全部段压缩在一屏内，当前窗口段 flex-grow 拉开最长。 */
.rainbow-rail { position: fixed; left: 0; width: 10px; z-index: 30;
  display: flex; flex-direction: column; opacity: .5; pointer-events: none; }
.rainbow-rail .rr-seg { flex: 1 1 0; min-height: 6px; cursor: pointer; pointer-events: auto;
  border-left: 3px solid transparent; }   /* 不加 transition（e2e 实测滚动过程高亮切换会让 Playwright 判 not-stable） */
.rainbow-rail .rr-seg.on { flex-grow: 8; border-left-color: rgba(255,255,255,.9); opacity: 1; }   /* 🆕 v423：当前段显著拉长，其余段压缩 */
.panel { position: relative; }

/* ── 10. 页面左右滑动切页签动画（需求 11） ── */
@keyframes slideInFromRight { from { transform: translateX(28px); opacity: .4; } to { transform: none; opacity: 1; } }
@keyframes slideInFromLeft { from { transform: translateX(-28px); opacity: .4; } to { transform: none; opacity: 1; } }
.panel.active.slide-from-right { animation: slideInFromRight .28s ease; }
.panel.active.slide-from-left { animation: slideInFromLeft .28s ease; }

/* ── v420 补丁：事件卡头「＋」与图例组行 ✏️ 连 min-height 一起复位（防 .btn.tiny{min-height:36px} 撑成椭圆）── */
.card-head .event-add-plus, .tl-row-edit {
  width: 26px; height: 26px; min-width: 26px; min-height: 26px; padding: 0; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center; font-size: 15px; line-height: 1;
  background: var(--panel); border: 1px solid var(--line); color: var(--ink); flex: 0 0 auto;
}
.btn.tiny.tl-row-edit { width: 22px !important; height: 22px !important; min-width: 22px !important; min-height: 22px !important; padding: 0 !important; font-size: 12px; }


/* ══════════ 🆕 v423（2026-09-27 用户批次） ══════════ */

/* 趋势概览：字号压缩到与其他窗口相当（原继承 body 15px 偏大） */
.trend-summary { font-size: 13px; }
.trend-summary .ts-section { font-size: 13px; line-height: 1.55; }
.trend-summary .so-head, .trend-summary .ps-title { font-size: 13px; font-weight: 600; }
.trend-summary .card-head h2 { font-size: 15.5px; }

/* 图例组：已移进 chart-box 内（图上方），间距收紧 */
.chart-box .tl-legend-groups { margin: 0 0 8px; }

/* 心理量表自评：卡头＋钮（新建类功能统一为加号、放 🌰 左手边），与相邻窗口统一间距 */
.assess-head { margin-bottom: 10px; }
.assess-head h2 { font-size: 15.5px; }
.assess-card { margin-top: 16px; }
.assess-add-btn { width: 26px; height: 26px; min-width: 26px; min-height: 26px; padding: 0;
  border-radius: 50%; font-size: 15px; line-height: 1; display: inline-flex; align-items: center; justify-content: center; }
/* 🆕 v429（用户：＋ 与 🌰 重叠）：本卡 🌰 当初是绝对定位（right:8）⇒ ＋ 右侧留出 30px 定位区。
   🆕 v506 已**废止**这条补丁：根因是 index.html 把 <p class="hint"> 写在了 .card-head **内部**，
   hintsToCorner() 在宿主（= .card-head）里找不到嵌套的 .card-head ⇒ 走兜底分支、🌰 拿不到 .hint-q-inline
   ⇒ 保持 position:absolute 压在 ＋ 上。现把 p.hint 移到 .card 下（与「日常测量 / 就诊与复查」同构）后，
   🌰 变成**内联**排在 ＋ 右侧，不再需要 30px 让位。保留本行注释作历史记录，规则本体已删除。 */

/* 🆕 v424：今日用药卡内「跳过原因」下拉——仅在该药已跳过时显示，紧凑内联 */
.tm-skip-reason { margin-left: 6px; font-size: 12px; padding: 2px 4px; border-radius: 6px;
  border: 1px solid var(--border, #d6dbe3); background: var(--bg-soft, #f4f6fa); color: var(--text, #2a2f3a);
  max-width: 110px; }
.today-med.prn .tm-skip-reason { display: none; }

/* 🆕 v424：跳过 / 漏服原因分布面板 */
.skip-reason-stats { margin-top: 4px; }
.skip-reason-list { display: flex; flex-direction: column; gap: 8px; margin: 6px 0 4px; }
.skip-reason-row { display: flex; align-items: center; gap: 10px; font-size: 13px; }
.skip-reason-row .sr-label { flex: 0 0 72px; color: var(--text, #2a2f3a); }
.skip-reason-row .sr-bar-wrap { flex: 1 1 auto; height: 14px; background: var(--bg-soft, #eef1f6);
  border-radius: 7px; overflow: hidden; }
.skip-reason-row .sr-bar { display: block; height: 100%; border-radius: 7px;
  background: linear-gradient(90deg, #4f8cff, #6fb1ff); }
.skip-reason-row .sr-count { flex: 0 0 auto; color: var(--text-dim, #6b7280); font-variant-numeric: tabular-nums; }
.skip-reason-foot { margin: 8px 0 0; font-size: 12.5px; color: var(--text-dim, #6b7280); line-height: 1.5; }

/* 🆕 v427 疫苗接种记录（档案页最下方卡片） */
.vaccine-form { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 12px; margin: 10px 0; }
.vaccine-form label { display: flex; flex-direction: column; font-size: 12.5px; color: var(--text-dim, #6b7280); gap: 4px; }
.vaccine-form input { padding: 7px 9px; border: 1px solid var(--border, #d8dde6); border-radius: 8px; font-size: 13px; background: var(--bg, #fff); color: var(--text, #2a2f3a); }
.vaccine-form .span2 { grid-column: 1 / -1; }
.vaccine-form-actions { display: flex; gap: 8px; }
#btn-add-vaccine { margin: 8px 0 2px; }
.vaccines-box { margin-top: 8px; }
.vaccine-empty { margin: 6px 0 0; }

/* 🆕 v441 用药补给与临期预警汇总（用药页最下方卡片） */
.med-supply-box { margin-top: 4px; }
.msu-list { list-style: none; margin: 8px 0 4px; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.msu-item { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; padding: 8px 10px; border: 1px solid var(--border, #d8dde6); border-radius: 10px; background: var(--bg-soft, #f5f7fa); }
.msu-name { font-weight: 600; color: var(--text, #2a2f3a); }
.msu-dose { font-weight: 400; color: var(--text-dim, #6b7280); font-size: 12.5px; margin-left: 2px; }
.msu-badge { display: inline-flex; align-items: center; padding: 2px 9px; border-radius: 999px; font-size: 12.5px; line-height: 1.6; white-space: nowrap; }
.msu-badge.soon { background: #fff4e0; color: #b76e00; border: 1px solid #f3d8a8; }
.msu-badge.expired { background: #fde8e8; color: #c0392b; border: 1px solid #f3b4b0; }
.msu-badge.low { background: #eaf3ff; color: #1f6fd6; border: 1px solid #bcd6f7; }
.msu-ok { margin: 8px 0 0; color: #2e9e5b; font-weight: 600; }
.msu-foot { margin: 8px 0 0; font-size: 12.5px; color: var(--text-dim, #6b7280); line-height: 1.5; }
html[data-theme="dark"] .msu-item { background: #1f2937; border-color: #2d3a4a; }
html[data-theme="dark"] .msu-name { color: #e8edf3; }
html[data-theme="dark"] .msu-badge.soon { background: #4a3a17; color: #f0b860; border-color: #5e4a20; }
html[data-theme="dark"] .msu-badge.expired { background: #4a1f1f; color: #ff9a8f; border-color: #5e2a28; }
html[data-theme="dark"] .msu-badge.low { background: #18304d; color: #7fb6ff; border-color: #244a73; }
html[data-theme="dark"] .msu-ok { color: #4fd08a; }

/* 🆕 v442：药物所致营养素缺乏预警卡片（对标 Pillo / Medisafe 2026 nutrient depletion warnings） */
.med-nutrient-box { margin-top: 4px; }
.ntr-list { list-style: none; margin: 8px 0 4px; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.ntr-item { border: 1px solid var(--border, #d8dde6); border-radius: 10px; padding: 10px 12px; background: var(--bg-soft, #f5f7fa); }
.ntr-item.ntr-attn { border-color: #f3c2c2; background: #fff7f7; }
.ntr-item.ntr-info { border-color: #cfe6f5; background: #f5fbff; }
.ntr-head { font-weight: 600; margin-bottom: 4px; color: var(--text, #2a2f3a); }
.ntr-nut { color: #1f6feb; }
.ntr-attn .ntr-nut { color: #c0392b; }
.ntr-info .ntr-nut { color: #1f6feb; }
.ntr-meds { font-weight: 400; color: var(--text-dim, #6b7280); font-size: 12.5px; }
.ntr-med { display: inline-block; background: #eef3f8; border-radius: 6px; padding: 1px 7px; margin: 0 2px; font-size: .9em; color: #374151; }
.ntr-why { color: var(--text-dim, #555); font-size: 13px; line-height: 1.5; margin: 2px 0; }
.ntr-advice { color: #2f7d32; font-size: 13px; line-height: 1.5; }
html[data-theme="dark"] .ntr-item { background: #1f2937; border-color: #2d3a4a; }
html[data-theme="dark"] .ntr-item.ntr-attn { background: #2e1f22; border-color: #5e2a28; }
html[data-theme="dark"] .ntr-item.ntr-info { background: #18283a; border-color: #244a73; }
html[data-theme="dark"] .ntr-head { color: #e8edf3; }
html[data-theme="dark"] .ntr-nut { color: #7fb6ff; }
html[data-theme="dark"] .ntr-attn .ntr-nut { color: #ff9a8f; }
html[data-theme="dark"] .ntr-meds { color: #9aa6b2; }
html[data-theme="dark"] .ntr-med { background: #2a3441; color: #cdd7e2; }
html[data-theme="dark"] .ntr-why { color: #b3bcc7; }

/* 🆕 v446：用药-食物相互作用提醒卡（沿用 .ntr-med / .msu-ok / .msu-foot / .hint 等既有类，仅新增 food-* 容器与条目样式） */
.med-food-box { margin-top: 4px; }
.food-list { list-style: none; margin: 8px 0 4px; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.food-item { border: 1px solid var(--border, #d8dde6); border-radius: 10px; padding: 10px 12px; background: var(--bg-soft, #f5f7fa); }
.food-item.food-high { border-color: #f3c2c2; background: #fff7f7; }
.food-item.food-mod { border-color: #f0d9b5; background: #fffaf0; }
.food-head { font-weight: 600; margin-bottom: 4px; color: var(--text, #2a2f3a); }
.food-food { color: #c0392b; }
.food-mod .food-food { color: #b9770e; }
.food-meds { font-weight: 400; color: var(--text-dim, #6b7280); font-size: 12.5px; }
.food-why { color: var(--text-dim, #555); font-size: 13px; line-height: 1.5; margin: 2px 0; }
.food-advice { color: #2f7d32; font-size: 13px; line-height: 1.5; }
html[data-theme="dark"] .food-item { background: #1f2937; border-color: #2d3a4a; }
html[data-theme="dark"] .food-item.food-high { background: #2e1f22; border-color: #5e2a28; }
html[data-theme="dark"] .food-item.food-mod { background: #2a241a; border-color: #5e4a28; }
html[data-theme="dark"] .food-head { color: #e8edf3; }
html[data-theme="dark"] .food-food { color: #ff9a8f; }
html[data-theme="dark"] .food-mod .food-food { color: #f0b860; }
html[data-theme="dark"] .food-meds { color: #9aa6b2; }
html[data-theme="dark"] .food-why { color: #b3bcc7; }
html[data-theme="dark"] .ntr-advice { color: #6fcf97; }
.vaccine-list { list-style: none; margin: 4px 0 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.vaccine-row { position: relative; border: 1px solid var(--border, #d8dde6); border-radius: 10px; padding: 10px 34px 10px 12px; background: var(--bg-soft, #f7f9fc); }
.vaccine-row .vx-main { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.vaccine-row .vx-name { font-weight: 600; font-size: 14px; color: var(--text, #2a2f3a); }
.vaccine-row .vx-meta { display: flex; flex-wrap: wrap; gap: 4px 14px; margin-top: 5px; font-size: 12.5px; color: var(--text-dim, #6b7280); }
.vaccine-row .vx-note { font-style: italic; }
.vx-badge { font-size: 11.5px; padding: 2px 8px; border-radius: 999px; font-weight: 600; }
.vx-badge.vx-ok { background: #e6f6ec; color: #1f8a4c; }
.vx-badge.vx-soon { background: #fff3d6; color: #b7791f; }
.vx-badge.vx-overdue { background: #fde8e8; color: #c0392b; }

/* 🆕 v429：过敏 / 不良反应记录卡片 */
.allergy-form { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 12px; margin: 10px 0; }
.allergy-form label { display: flex; flex-direction: column; font-size: 12.5px; color: var(--text-dim, #6b7280); gap: 4px; }
.allergy-form input, .allergy-form select { padding: 7px 9px; border: 1px solid var(--border, #d8dde6); border-radius: 8px; font-size: 13px; background: var(--bg, #fff); color: var(--text, #2a2f3a); }
.allergy-form .span2 { grid-column: 1 / -1; }
.allergy-form-actions { display: flex; gap: 8px; }
.allergy-empty { margin: 6px 0 0; }
.allergy-list { list-style: none; margin: 4px 0 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.allergy-row { display: flex; align-items: flex-start; gap: 10px; padding: 10px 12px; border: 1px solid var(--border, #d8dde6); border-radius: 10px; background: var(--card, #fff); }
.al-sev { flex: 0 0 auto; min-width: 30px; text-align: center; font-size: 12px; font-weight: 700; padding: 3px 8px; border-radius: 999px; color: #fff; }
.al-sev.sev-low { background: #1f8a4c; }
.al-sev.sev-mid { background: #d98324; }
.al-sev.sev-high { background: #c0392b; }
.al-main { flex: 1 1 auto; min-width: 0; }
.al-top { display: flex; align-items: center; gap: 8px; }
.al-name { font-weight: 600; font-size: 14.5px; color: var(--text, #1f2d3d); }
.al-type { font-size: 11.5px; padding: 1px 8px; border-radius: 999px; background: #eef2f6; color: #5b6776; }
html[data-theme="dark"] .al-type { background: #2a3543; color: #9fb0c0; }
.al-meta { display: flex; flex-wrap: wrap; gap: 4px 12px; margin-top: 4px; font-size: 12.5px; color: var(--text-dim, #6b7280); }
.al-note { color: var(--text-dim, #6b7280); }
.al-del { flex: 0 0 auto; align-self: center; border: none; background: transparent; color: #c0392b; font-size: 15px; cursor: pointer; padding: 4px 6px; border-radius: 8px; }
.al-del:hover { background: #fde8e8; }
@media (max-width: 480px) {
  .allergy-form { grid-template-columns: 1fr; }
}
html[data-theme="dark"] .allergy-row { background: #1b2530; border-color: #2c3744; }
html[data-theme="dark"] .al-name { color: #e8eef3; }
html[data-theme="dark"] .al-sev.sev-low { background: #1f7a44; }
html[data-theme="dark"] .al-sev.sev-mid { background: #b9761f; }
html[data-theme="dark"] .al-sev.sev-high { background: #a83227; }
html[data-theme="dark"] .al-del:hover { background: #3a2222; }
.vx-del { position: absolute; top: 8px; right: 8px; border: none; background: transparent; color: var(--text-dim, #9aa3b2); cursor: pointer; font-size: 14px; line-height: 1; padding: 4px; border-radius: 6px; }
.vx-del:hover { background: #fde8e8; color: #c0392b; }
html[data-theme="dark"] .tm-skip-reason { background: #232a36; border-color: #36404f; color: #e6ebf2; }
html[data-theme="dark"] .skip-reason-row .sr-bar-wrap { background: #232a36; }
html[data-theme="dark"] .skip-reason-row .sr-label,
html[data-theme="dark"] .skip-reason-row .sr-count { color: #c3ccd8; }

/* 🆕 v431：用药自费成本估算卡片 */
.medcost-form { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 12px; margin: 10px 0; }
.medcost-form label { display: flex; flex-direction: column; font-size: 12.5px; color: var(--text-dim, #6b7280); gap: 4px; }
.medcost-form input { padding: 7px 9px; border: 1px solid var(--border, #d8dde6); border-radius: 8px; font-size: 13px; background: var(--bg, #fff); color: var(--text, #2a2f3a); }
.medcost-form .span2 { grid-column: 1 / -1; }
.medcost-form-actions { display: flex; gap: 8px; }
.medcost-empty { margin: 6px 0 0; }
.medcost-summary { margin: 8px 0 4px; padding: 8px 12px; border-radius: 10px; background: #eef7f0; border: 1px solid #cfe9d6; font-size: 13.5px; color: #1f6b3a; }
.medcost-summary b { font-size: 15px; }
.medcost-list { list-style: none; margin: 4px 0 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.medcost-row { position: relative; border: 1px solid var(--border, #d8dde6); border-radius: 10px; padding: 10px 34px 10px 12px; background: var(--bg-soft, #f7f9fc); }
.medcost-row .mc-main { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.medcost-row .mc-name { font-weight: 600; font-size: 14px; color: var(--text, #2a2f3a); }
.medcost-row .mc-price { font-size: 12.5px; color: var(--text-dim, #6b7280); }
.medcost-row .mc-meta { display: flex; flex-wrap: wrap; gap: 4px 14px; margin-top: 5px; font-size: 12.5px; color: var(--text-dim, #6b7280); }
.medcost-row .mc-monthly { font-weight: 700; color: #b7791f; }
.medcost-row .mc-note { font-style: italic; }
.medcost-row .mc-warn { color: #c0392b; }
.mc-del { position: absolute; top: 8px; right: 8px; border: none; background: transparent; color: var(--text-dim, #9aa3b2); cursor: pointer; font-size: 14px; line-height: 1; padding: 4px; border-radius: 6px; }
.mc-del:hover { background: #fde8e8; color: #c0392b; }
@media (max-width: 480px) {
  .medcost-form { grid-template-columns: 1fr; }
}
html[data-theme="dark"] .medcost-summary { background: #16301f; border-color: #2c5236; color: #8fd6a6; }
html[data-theme="dark"] .medcost-row { background: #1b2530; border-color: #2c3744; }
html[data-theme="dark"] .medcost-row .mc-name { color: #e8eef3; }
html[data-theme="dark"] .medcost-row .mc-monthly { color: #e0a64a; }
html[data-theme="dark"] .mc-del:hover { background: #3a2222; }


/* ══════════ 🆕 v423 第二批（文字收编/时间轴字体/creep 注入） ══════════ */
/* 说明收进栗子的容器：🌰 绝对定位右上，需要 relative 锚 */
.ind-correlation, .ind-vital-correlation, .symptom-ind-correlation, .symptom-vital-correlation,
.checkin-symptom-correlation, .symptom-med-assoc, .symptom-trend-card { position: relative; }

/* 🆕 v513（用户第 9 项）：原「综合健康时间轴字体与其他窗口统一」4 条规则（.health-timeline
   font-size 13.5px / .card-head h2 15.5px 蓝标题 / 暗色版）随整卡下线一并退役。 */

/* 指标分析窗口内的「需关注恶化」注入区 */
.creep-inline-wrap { margin-top: 10px; }
.creep-inline-wrap .creep-watch { margin: 0; }


/* ══════════ 🆕 v426 UI 补丁（表头冻结/注入子块/本期小结展开/✏️趋势窗定位/重复图弹框/刷新条） ══════════ */
/* ① 指标库（10 行滚动窗）滚动时标题行冻结 */
.ind-scroll thead th { position: sticky; top: 0; z-index: 3; background: var(--card); }
html[data-theme="dark"] .ind-scroll thead th { background: var(--card); }

/* ② 趋势概览移到图下方后的间距 */
.chart-box .trend-summary { margin-top: 10px; }
.ac-inline { margin-top: 10px; }
.ac-inline-title { font-weight: 700; font-size: 13.5px; margin: 0 0 6px; color: var(--ink); }
.ac-inline .ac-item, .alerts-inline .alert-item { margin-bottom: 6px; }
.alerts-inline { margin-top: 10px; }

/* ③ 本期小结「展开」详情 */
.ps-toggle { margin-left: 6px; vertical-align: middle; }
.ps-detail { display: block; margin-top: 6px; padding: 8px 10px; border: 1px dashed var(--border, #d7dee6);
  border-radius: 8px; background: var(--card-soft, rgba(0,0,0,.02)); font-size: 12.5px; line-height: 1.7; }

/* ④ 趋势窗内 ✏️（对齐指标图例行右端；top 由 JS 按 #chart 偏移实测写入） */
.hint-q-trendedit { position: absolute; z-index: 7; }

/* ⑤ 重复图片三选一弹框 */
.dup-ask-overlay { position: fixed; inset: 0; background: rgba(0, 0, 0, .45); z-index: 1200;
  display: flex; align-items: center; justify-content: center; }
.dup-ask-box { background: var(--card, #fff); color: var(--ink, #222); border-radius: 12px;
  padding: 16px 18px; max-width: 340px; width: calc(100% - 40px);
  box-shadow: 0 12px 40px rgba(0, 0, 0, .25); }
.dup-ask-title { font-weight: 700; font-size: 15px; margin-bottom: 8px; }
.dup-ask-body { font-size: 12.5px; line-height: 1.7; color: var(--ink-soft, #555); }
.dup-ask-btns { display: flex; gap: 8px; justify-content: flex-end; margin-top: 14px; flex-wrap: wrap; }

/* ⑥ 缩略图刷新条（v556 退役）：↻ 刷新 + 全局比值徽标已移入图片识别卡头（用户需求），
   原 .scan-thumbs-bar / 右对齐布局不再有宿主元素，规则随之改写为卡头内的新样式。 */
/* 🆕 v556（用户）：全局比值徽标改按「指标库计数徽标」同款**细边框胶囊**样式
   （原为红/白实底徽标）。颜色语义保留：
   · 未全部确认（a≠b 或有需核对）= 红字 + 红边（.warn，默认态）；
   · 全部确认 = 中性灰字 + 常规边（.ok）。可点击跳转对应缩略图与大图。 */
.scan-total-ratio {
  position: relative;
  display: inline-flex; align-items: center;
  padding: 1px 8px; border-radius: 10px;
  border: 1px solid rgba(192, 57, 43, .5);
  font-size: 12px; font-weight: 600; line-height: 1.6;
  font-variant-numeric: tabular-nums;
  color: #c0392b; background: var(--panel, #f1f4f8);
  cursor: pointer; white-space: nowrap; flex: 0 0 auto;
}
/* UISKILL：小控件命中区 ≥40px 高。卡头是横向单行、上下无邻居 ⇒ 只上下外扩；
   左右各 -2px < 卡头 gap 6px，与相邻按钮命中区不重叠。 */
.scan-total-ratio::after { content: ''; position: absolute; inset: -8px -2px; }
.scan-total-ratio.ok {
  border-color: var(--line, #e3e8ee);
  color: var(--muted, #8593a3);
  background: var(--panel, #f1f4f8);
  box-shadow: none;
}
html[data-theme="dark"] .scan-total-ratio { color: #ef7d72; border-color: rgba(239, 125, 114, .45); background: #1c2733; }
html[data-theme="dark"] .scan-total-ratio.ok { color: #9aa6b2; border-color: #3b4a5c; background: #1c2733; }
/* 手机断点：卡头一行要装下 标题+共x张+a/b指标+刷新+🔍+❓，徽标字号微降防折行（坑 89：中文逐字竖排）。 */
@media (max-width: 640px) {
  .scan-total-ratio { font-size: 11px; padding: 1px 6px; }
  /* ⛔ v560：这里原有两条针对刷新键的窄屏补丁（隐藏 .rt-txt 文字 + 收 padding）。
     刷新键已改纯 SVG 图标钮（无文字、30×30 定宽），窄屏无需再特殊处理 ⇒ 两条一并退役。
     ⚠️ 若将来又要放文字，请改 scan.css 的 .ico-refresh，不要在这里加 id 规则。 */
}


/* 🆕 v429（用户）：趋势窗 = 一张完整白底卡（标题+图例+图都在里面） */
.chart-box { background: #fff; border: 1px solid var(--line); border-radius: var(--radius); }

/* 🆕 v428 UI（表头冻结修正 / 趋势窗边距对齐 .card / 批量勾选 / 指标编辑弹窗） */
/* ① 指标库冻结表头：border-collapse:collapse 会让 sticky 表头漏出底下的行（截图实测）
      ⇒ 改 separate + 表头底边线，行内容滚动到表头下时被完全盖住、不再「穿帮」 */
.ind-scroll table { border-collapse: separate; border-spacing: 0; }
.ind-scroll thead th { box-shadow: inset 0 -1px 0 var(--border, #d7dee6); }

/* ② 趋势窗口边距与其他窗口一致（.card 同源：base 16px / ≤640 14px 14px 16px） */
.chart-box { padding: 16px; }
.chart-head { margin: 0 0 8px; }
.chart-head h2 { margin: 0; font-size: 15.5px; }
.chart-box .tl-legend-groups { margin: 0 0 10px; }
.chart-tools { top: 16px; right: 16px; }
@media (max-width: 640px) {
  .chart-box { padding: 14px 14px 16px; }
  .chart-tools { top: 14px; right: 14px; }
}

/* ③ 覆盖弹框「本次剩余同此」勾选：40px 级触控、虚线框内联在说明下 */
.confirm-batch { display: flex; align-items: center; gap: 8px; margin-top: 10px;
  padding: 9px 10px; min-height: 40px; border: 1px dashed var(--border, #d7dee6);
  border-radius: 8px; font-size: 12.5px; cursor: pointer; user-select: none; }
.confirm-batch input { width: 16px; height: 16px; flex: 0 0 auto; accent-color: #0e7c86; }

/* ④ 指标整行编辑弹窗（对齐 v415 用药弹窗同族样式） */
.ind-edit-form { display: flex; flex-direction: column; gap: 10px; }
.ind-edit-form label { display: flex; flex-direction: column; gap: 4px;
  font-size: 12.5px; color: var(--muted, #667); }
.ind-edit-form input { padding: 9px 10px; border: 1px solid var(--line, #cfd8e0);
  border-radius: 8px; background: var(--card); color: var(--ink); font-size: 14px;
  font-variant-numeric: tabular-nums;
  transition: border-color 150ms ease-out, box-shadow 150ms ease-out; }
.ind-edit-form input:focus { outline: none; border-color: #0e7c86;
  box-shadow: 0 0 0 3px rgba(14, 124, 134, .15); }
.ie-row { display: flex; gap: 8px; }
.ie-row label { flex: 1; min-width: 0; }
.ie-cat { margin: 0; font-size: 12px; color: var(--muted, #889); }

/* 🆕 v429：≤640px 时趋势窗圆角与 .card 同为 16px（本段在文件尾，压过前面基础规则的 12px） */
@media (max-width: 640px) {
  .chart-box { border-radius: 16px; }
}

/* ══════════ 🆕 v430 UI（识别表操作列平放/移动钮/文件窗按钮簇） ══════════ */
/* ① 指标识别表操作列：4 钮（改/删/↑/↓）强制单行平放 + 列最小宽。
   （用户：编辑/删除上下太挤；≤640 的 .row-actions flex-wrap:wrap 在窄列上把按钮摞成了两行） */
.entry-ind-win td.scan-actions { flex-wrap: nowrap; white-space: nowrap; min-width: 128px; vertical-align: middle; }
/* ③ 文件识别窗按钮簇顶右上（.card-head 是 space-between，中间子元素会被摊开到行中） */
.card-head-actions { margin-left: auto; }
/* ② ↑↓ 移动钮：与改/删同规格圆钮（26px），中性灰底、hover 提亮，禁用半透明 */
.scan-actions .btn.act-ico.act-move { background: var(--panel); color: var(--muted); font-size: 13px; }
.scan-actions .btn.act-ico.act-move:hover:not(:disabled) { color: var(--primary); }
.scan-actions .btn.act-ico.act-move:disabled { opacity: .32; cursor: default; pointer-events: none; }
html[data-theme="dark"] .scan-actions .btn.act-ico.act-move { background: #1a2431; }

/* ══════════ 🆕 v451 指标值分布直方图 ══════════ */
.ind-hist .card-head { flex-wrap: wrap; }
.ind-hist .hist-ind-select { margin-left: auto; max-width: 240px; min-width: 120px; padding: 5px 8px;
  border: 1px solid var(--line); border-radius: 8px; background: var(--card); color: var(--ink); font-size: 13px; }
.hist-chart { width: 100%; height: 300px; }
.hist-stats { display: flex; flex-wrap: wrap; gap: 8px 18px; margin-top: 10px; font-size: 12.5px; color: var(--muted); }
.hist-stats .hs-item b { color: var(--ink); font-variant-numeric: tabular-nums; }
html[data-theme="dark"] .ind-hist .hist-ind-select { background: #16202c; }
html[data-theme="dark"] .hist-stats { color: #8b98a5; }
html[data-theme="dark"] .hist-stats .hs-item b { color: #d6dde6; }

/* ============================================================ v453 升级推送提示
   用在 appConfirm 的 html 里（弹窗正文的第二段说明）。刻意做小、做灰：
   它是补充信息，不该和「发现新版本 vXXX」这句主信息抢注意力。 */
.cm-upd-note{display:inline-block;margin-top:8px;font-size:12.5px;line-height:1.7;color:var(--muted)}

/* ═══════════ 🆕 v466 用药与复查提醒卡 · 实时待提醒清单 ══════════ */
#reminder-list { margin-top: 10px; }
#reminder-list:empty { display: none; }
.rm-sec { margin-top: 8px; border: 1px solid var(--line); border-radius: 10px; overflow: hidden; background: var(--bg); }
.rm-sec-h { padding: 6px 10px; font-size: 12.5px; font-weight: 600; color: var(--muted); background: var(--card); border-bottom: 1px solid var(--line); }
.rm-item { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 7px 10px; border-bottom: 1px solid var(--line); }
.rm-item:last-child { border-bottom: 0; }
.rm-name { flex: 1 1 auto; font-size: 13px; color: var(--ink); word-break: break-all; }
.rm-btns { flex: 0 0 auto; display: flex; gap: 6px; }
.rm-btns .btn.mini { padding: 3px 9px; font-size: 12px; line-height: 1.6; }
.rm-take { border-color: var(--accent, #2f80ed); color: var(--accent, #2f80ed); }
.rm-empty { margin-top: 8px; padding: 8px 10px; font-size: 12.5px; color: var(--muted); background: var(--bg); border: 1px dashed var(--line); border-radius: 8px; }
html[data-theme="dark"] .rm-sec { background: #16202c; }
html[data-theme="dark"] .rm-sec-h { background: #1b2735; color: #8b98a5; }
html[data-theme="dark"] .rm-name { color: #d6dde6; }
html[data-theme="dark"] .rm-empty { background: #16202c; color: #8b98a5; }
html[data-theme="dark"] .rm-take { color: #6db3f2; border-color: #6db3f2; }

/* 🆕 v469 症状部位热力图（对标 Guava 2026 症状部位热力图 / Body Heat Map） */
.symptom-bodymap .bodymap-body { margin-top: 6px; }
.bm-wrap { display: flex; gap: 18px; flex-wrap: wrap; align-items: flex-start; }
.bm-svg { width: 180px; height: auto; flex: 0 0 auto; max-width: 46%; }
.bm-region { cursor: pointer; outline: none; }
/* 🆕 v533（用户需求 2）：人形图案美化 —— **无边线、仅填充色**（用户原话：用无边线颜色、
   仅填充色的方式修改）。原版每块都有 #5b6b73/#1b2a31 描边 + 空部位深蓝灰填充，看起来
   又重又硬；改为：空部位 = 浅蓝灰填充（无描边），有症状部位 = 严重度色填充（无描边），
   选中不再用描边圈（v533 起描边全废），改用亮度/饱和度提亮。 */
.bm-region .bm-shape-wrap ellipse,
.bm-region .bm-shape-wrap rect { stroke: none; transition: fill .2s, filter .2s; }
.bm-region.bm-empty .bm-shape-wrap ellipse,
.bm-region.bm-empty .bm-shape-wrap rect { fill: #c9d5df; }
.bm-region.bm-has .bm-shape-wrap ellipse,
.bm-region.bm-has .bm-shape-wrap rect { stroke: none; }
.bm-region.bm-mild .bm-shape-wrap ellipse,
.bm-region.bm-mild .bm-shape-wrap rect { fill: #27ae60; }
.bm-region.bm-mod .bm-shape-wrap ellipse,
.bm-region.bm-mod .bm-shape-wrap rect { fill: #e67e22; }
.bm-region.bm-sev .bm-shape-wrap ellipse,
.bm-region.bm-sev .bm-shape-wrap rect { fill: #c0392b; }
.bm-region.bm-sel .bm-shape-wrap ellipse,
.bm-region.bm-sel .bm-shape-wrap rect { filter: brightness(1.18) saturate(1.25); }
.bm-label { fill: #fff; font-size: 13px; font-weight: 600; pointer-events: none; user-select: none; }
.bm-region.bm-empty .bm-label { fill: #55677a; }   /* 空部位浅填充 ⇒ 标签换深色，白字会看不清 */
.bm-badge { fill: #fff; font-size: 12px; font-weight: 700; pointer-events: none; }
/* 🆕 v533：右侧部位列表在手机端（≈330px 可用宽）必须能并排站 —— 原 min-width:180px
   + svg 46% 会把列表挤到人形**下方**（用户原话：人形图案右侧是空的，浪费页面空间）。
   min-width 放开到 0（flex-basis 200px 仍保证桌面端宽度），svg 上限同步收到 42%。 */
.bm-list { flex: 1 1 200px; min-width: 0; }
.bm-li-empty { color: #6b7785; font-size: 12.5px; line-height: 1.6; cursor: default; background: transparent; }
.bm-li-empty:hover { background: transparent; }
@media (max-width: 640px) {
  .bm-svg { max-width: 42%; width: 150px; }
}
html[data-theme="dark"] .bm-region.bm-empty .bm-shape-wrap ellipse,
html[data-theme="dark"] .bm-region.bm-empty .bm-shape-wrap rect { fill: #2a3a42; }
html[data-theme="dark"] .bm-region.bm-empty .bm-label { fill: #9aa6b2; }
html[data-theme="dark"] .bm-li-empty { color: #9aa6b2; }
.bm-li { padding: 6px 8px; border-radius: 8px; margin-bottom: 4px; cursor: pointer; }
.bm-li:hover { background: rgba(255,255,255,.05); }
.bm-li-sel { background: rgba(255,213,74,.12); }
.bm-li-head { display: flex; align-items: center; gap: 6px; font-size: 14px; }
.bm-li-head .muted { margin-left: auto; font-size: 12px; }
.bm-dot { display: inline-block; width: 10px; height: 10px; border-radius: 50%; flex: 0 0 auto; }
.bm-dot.bm-mild { background: #27ae60; }
.bm-dot.bm-mod { background: #e67e22; }
.bm-dot.bm-sev { background: #c0392b; }
.bm-detail { margin: 4px 0 0 16px; padding: 0; list-style: none; font-size: 13px; }
.bm-detail li { margin: 2px 0; color: #d7e2e8; }
.bm-legend { display: flex; gap: 14px; align-items: center; margin-top: 8px; font-size: 13px; flex-wrap: wrap; }
.bm-legend .bm-dot { margin-right: 4px; vertical-align: middle; }

/* 🆕 v470：异常结果速览（检验记录页底部一键 glanceable 异常清单） */
.lab-abn-list { display: block; }
.lab-abn-head { font-size: 14px; color: #c0392b; margin: 2px 0 8px; font-weight: 600; }
.lab-abn-head b { font-size: 16px; }
.lab-abn-row { display: flex; align-items: center; gap: 12px; padding: 7px 10px; border-radius: 8px; margin-bottom: 6px; background: #fafafa; border-left: 4px solid #bbb; flex-wrap: wrap; }
.lab-abn-row.abn-high { border-left-color: #e15759; background: #fdf1f1; }
.lab-abn-row.abn-low { border-left-color: #f0a020; background: #fdf6ec; }
.lab-abn-name { font-weight: 600; flex: 1 1 140px; min-width: 120px; }
.lab-abn-val { font-weight: 700; font-size: 15px; }
.lab-abn-row.abn-high .lab-abn-val { color: #c0392b; }
.lab-abn-row.abn-low .lab-abn-val { color: #c8791a; }
.lab-abn-range { color: #888; font-size: 12px; }
.lab-abn-date { color: #999; font-size: 12px; margin-left: auto; }
.lab-abn-none { color: #2e9e5b; font-weight: 600; padding: 8px 4px; }
.lab-abn-foot { color: #999; font-size: 12px; margin: 8px 0 0; line-height: 1.5; }

/* 🆕 自动优化 v482：检验指标近期变化榜（检验记录页底部，对标 MyTherapy/CareClinic 2026「follow measurements over time / results by trend」） */
.lab-movers { display: block; }
.lab-movers-head { font-size: 14px; color: #2c7be5; margin: 2px 0 8px; font-weight: 600; }
.lab-movers-head b { font-size: 16px; }
.lab-movers-row { display: flex; align-items: center; gap: 10px; padding: 7px 10px; border-radius: 8px; margin-bottom: 6px; background: #fafafa; border-left: 4px solid #bbb; flex-wrap: wrap; }
.lab-movers-row.mv-good { border-left-color: #2e9e5b; background: #f1faf4; }
.lab-movers-row.mv-bad { border-left-color: #e15759; background: #fdf1f1; }
.lab-movers-name { font-weight: 600; flex: 1 1 140px; min-width: 120px; }
.lab-movers-val { font-weight: 700; font-size: 15px; }
.lab-movers-row.mv-good .lab-movers-val { color: #1f8a4d; }
.lab-movers-row.mv-bad .lab-movers-val { color: #c0392b; }
.lab-movers-delta { color: #555; font-size: 13px; font-variant-numeric: tabular-nums; }
.lab-movers-row.mv-good .lab-movers-delta { color: #1f8a4d; }
.lab-movers-row.mv-bad .lab-movers-delta { color: #c0392b; }
.lab-movers-tag { font-size: 11px; padding: 1px 7px; border-radius: 10px; font-weight: 600; }
.lab-movers-tag.good { color: #1f8a4d; background: #e3f5ea; }
.lab-movers-tag.bad { color: #c0392b; background: #fbe3e3; }
.lab-movers-when { color: #999; font-size: 12px; margin-left: auto; }
.lab-movers-none { color: #2e9e5b; font-weight: 600; padding: 8px 4px; }
.lab-movers-foot { color: #999; font-size: 12px; margin: 8px 0 0; line-height: 1.5; }

html[data-theme="dark"] .lab-abn-row { background: #1c2730; border-left-color: #444; }
html[data-theme="dark"] .lab-abn-row.abn-high { border-left-color: #e15759; background: #2a1c1f; }
html[data-theme="dark"] .lab-abn-row.abn-low { border-left-color: #f0a020; background: #2a241a; }
html[data-theme="dark"] .lab-abn-range { color: #7d8b95; }
html[data-theme="dark"] .lab-abn-date { color: #6b7782; }
html[data-theme="dark"] .lab-abn-none { color: #2ecc71; }
html[data-theme="dark"] .lab-abn-foot { color: #6b7782; }
html[data-theme="dark"] .lab-movers-head { color: #5fa8ef; }
html[data-theme="dark"] .lab-movers-row { background: #1c2730; border-left-color: #444; }
html[data-theme="dark"] .lab-movers-row.mv-good { border-left-color: #2e9e5b; background: #16291f; }
html[data-theme="dark"] .lab-movers-row.mv-bad { border-left-color: #e15759; background: #2a1c1f; }
html[data-theme="dark"] .lab-movers-row.mv-good .lab-movers-val,
html[data-theme="dark"] .lab-movers-row.mv-good .lab-movers-delta { color: #52d98a; }
html[data-theme="dark"] .lab-movers-row.mv-bad .lab-movers-val,
html[data-theme="dark"] .lab-movers-row.mv-bad .lab-movers-delta { color: #ff7a6b; }
html[data-theme="dark"] .lab-movers-tag.good { color: #52d98a; background: #16331f; }
html[data-theme="dark"] .lab-movers-tag.bad { color: #ff7a6b; background: #3a2220; }
html[data-theme="dark"] .lab-movers-when { color: #6b7782; }
html[data-theme="dark"] .lab-movers-none { color: #2ecc71; }
html[data-theme="dark"] .lab-movers-foot { color: #6b7782; }

/* 🆕 自动优化 v473：今日用药时间轴（用药页底部，对标 Medisafe / MyTherapy 2026「daily schedule」） */
.med-day-timeline { margin-top: 4px; }
.dt-wrap { padding: 4px 2px 0; }
.dt-axis { position: relative; margin: 6px 0 22px; border-left: 1px solid var(--line); border-bottom: 1px solid var(--line); border-radius: 0 0 0 6px; }
.dt-tick { position: absolute; top: 0; bottom: 0; border-left: 1px dashed var(--line); transform: translateX(-0.5px); }
.dt-tick span { position: absolute; bottom: -18px; left: 2px; font-size: 11px; color: var(--muted); white-space: nowrap; }
.dt-now { position: absolute; top: -4px; bottom: 0; width: 2px; background: #e15759; }
.dt-now::after { content: '现在'; position: absolute; top: -16px; left: 50%; transform: translateX(-50%); font-size: 10px; color: #e15759; white-space: nowrap; }
.dt-mark { position: absolute; transform: translateX(-50%); text-align: center; pointer-events: auto; }
.dt-dot { display: inline-block; width: 14px; height: 14px; border-radius: 50%; border: 2px solid var(--bg); box-shadow: 0 0 0 1px rgba(0,0,0,.18); vertical-align: middle; }
.dt-name { display: block; font-size: 11px; line-height: 1.2; max-width: 70px; margin: 2px auto 0; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dt-state { display: block; font-size: 11px; font-weight: 700; }
.dt-mark.taken .dt-state { color: #2e9e5b; }
.dt-mark.skipped .dt-state { color: #e08a1e; }
.dt-mark.pending .dt-state { color: var(--muted); }
.dt-mark.taken .dt-dot { box-shadow: 0 0 0 1px #2e9e5b; }
.dt-mark.skipped .dt-dot { box-shadow: 0 0 0 1px #e08a1e; }
.dt-unfixed { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 2px 0 6px; }
.dt-uf-label { font-size: 12px; color: var(--muted); }
.dt-uf-chip { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; padding: 3px 8px; border: 1px solid var(--line); border-radius: 999px; background: var(--bg); color: var(--ink); }
.dt-uf-chip .dt-dot { width: 10px; height: 10px; border-width: 1px; }
.dt-uf-chip.taken { border-color: #2e9e5b; }
.dt-uf-chip.skipped { border-color: #e08a1e; }
.dt-legend { display: flex; gap: 14px; align-items: center; flex-wrap: wrap; font-size: 12px; color: var(--muted); margin-top: 6px; }
.dt-lg.now { color: #e15759; font-weight: 600; }
.dt-lg.go { color: #2f7fd1; text-decoration: none; border: 1px solid var(--line); border-radius: 999px; padding: 2px 8px; }
.dt-lg.go:hover { background: var(--bg); }

html[data-theme="dark"] .dt-axis { border-color: #3a4654; }
html[data-theme="dark"] .dt-tick { border-left-color: #3a4654; }
html[data-theme="dark"] .dt-now { background: #ff6b6b; }
html[data-theme="dark"] .dt-now::after { color: #ff6b6b; }

/* 🆕 自动优化 v484：注射部位轮换总看板（#inj-board）样式 —— 复用全局主题变量 --ink/--muted/--line/--bg/--brand */
.inj-board { display: block; }
.inj-empty { color: var(--muted); font-size: 13px; padding: 6px 2px; }
.inj-overview { display: flex; flex-wrap: wrap; gap: 10px; margin: 6px 0 10px; }
.inj-kpi { display: flex; flex-direction: column; gap: 2px; padding: 8px 12px; border: 1px solid var(--line); border-radius: 10px; background: var(--bg); min-width: 120px; }
.inj-kpi-label { font-size: 12px; color: var(--muted); }
.inj-kpi-val { font-size: 15px; font-weight: 600; color: var(--ink); }
.inj-kpi-val.inj-next { color: #1aa7b1; }
.inj-bars { margin: 4px 0 10px; }
.inj-bar-row { display: flex; align-items: center; gap: 8px; margin: 4px 0; font-size: 13px; color: var(--ink); }
.inj-bar-row.inj-bar-next { font-weight: 600; }
.inj-bar-name { width: 72px; flex: 0 0 auto; color: var(--muted); }
.inj-bar-track { flex: 1; height: 10px; border-radius: 6px; background: var(--bg); border: 1px solid var(--line); overflow: hidden; }
.inj-bar-fill { display: block; height: 100%; background: #1aa7b1; border-radius: 6px; }
.inj-bar-row.inj-bar-next .inj-bar-fill { background: #16a085; }
.inj-bar-cnt { width: 46px; flex: 0 0 auto; text-align: right; color: var(--muted); }
.inj-meds { display: flex; flex-direction: column; gap: 6px; margin: 4px 0 10px; }
.inj-med-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 6px 10px; border: 1px solid var(--line); border-radius: 10px; background: var(--bg); }
.inj-med-name { font-weight: 600; color: var(--ink); }
.inj-med-cur { font-size: 12px; color: var(--muted); }
.inj-med-next { font-size: 12px; color: #1aa7b1; margin-left: auto; }
.inj-picker { display: inline-flex; gap: 6px; flex-wrap: wrap; margin-left: 4px; }
.inj-recent { list-style: none; margin: 4px 0 8px; padding: 0; display: flex; flex-direction: column; gap: 3px; }
.inj-recent li { display: flex; gap: 10px; font-size: 13px; color: var(--ink); }
.inj-r-site { font-weight: 600; min-width: 64px; }
.inj-r-date { color: var(--muted); }
.inj-r-med { color: var(--muted); }
.inj-foot { margin-top: 4px; }

html[data-theme="dark"] .inj-kpi,
html[data-theme="dark"] .inj-med-row { background: #1b2530; }
html[data-theme="dark"] .inj-bar-track { background: #14202b; }
html[data-theme="dark"] .inj-kpi-val.inj-next,
html[data-theme="dark"] .inj-med-next { color: #6fd39a; }
html[data-theme="dark"] .inj-bar-fill { background: #1aa7b1; }
html[data-theme="dark"] .inj-bar-row.inj-bar-next .inj-bar-fill { background: #2ecc8a; }

/* ══════════ 🆕 v489（用户 15 项需求）UI 样式 ══════════ */

/* ── 需求 3：指标分析窗口 —— 名称行色块 + 词条解释 + 统计条 + 折叠展开 ──
   色块与指标库 #indicator-list 同款（12×12 由通用 .swatch 提供，这里补 flex-shrink + 描边）；
   因 .pb-name 已是 flex(gap:6px)，把 swatch 的 margin-right 归零，避免「6px gap + 6px margin」双重间距。 */
:is(.personal-baseline, .ind-analysis) .pb-name .swatch {
  flex-shrink: 0; margin-right: 0;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .08);
}
/* 指标名字体与指标库一致（指标库表格 14px） */
:is(.personal-baseline, .ind-analysis) .pb-name .ind-name { font-size: 14px; font-weight: 600; }
/* 问号里的「词条解释」直接贴到指标名第一行 */
:is(.personal-baseline, .ind-analysis) .pb-def {
  margin: 2px 0 3px; font-size: 12px; line-height: 1.55; color: #8593a3;
}
/* 顶部「选择指标统计」条（复用 .rec-summary 徽标，这里补卡片内首屏边距） */
.ind-analysis .ia-stats { margin: 0 0 8px; }
/* 「展开 ▾ / 收起 ▴」与折叠内容（个人稳定区间以下折叠到这里） */
:is(.personal-baseline, .ind-analysis) .ia-toggle {
  margin-top: 6px; padding: 2px 10px; font-size: 12px;
  color: var(--primary); border: 1px dashed var(--line); background: transparent;
}
:is(.personal-baseline, .ind-analysis) .ia-more { margin-top: 4px; }

/* ── 需求 4：指标库释义问号（放到删除叉号右边）+ 指标数量按钮 ──
   覆盖 .ind-def-q 的 margin-left:auto（它会把 ? 推到行尾），改为贴删除按钮右侧。 */
#indicator-list .row-actions .ind-def-q-lib { margin-left: 6px; }
#btn-ind-count {
  min-width: 0; padding: 2px 10px; font-size: 12px; color: var(--muted);
  border: 1px solid var(--line); background: transparent; cursor: default;
}

/* ── 需求 6：手机版设置弹窗里时间区间不拆两行（预设按钮整体换到第二行） ── */
@media (max-width: 640px) {
  #chart-settings-pop .chart-range-bar { flex-wrap: wrap; row-gap: 8px; }
  #chart-settings-pop .chart-range-bar .range-presets { flex-basis: 100%; margin-left: 0; }
  #chart-settings-pop .chart-range-bar > label,
  #chart-settings-pop .chart-range-bar > span:not(.range-presets),
  #chart-settings-pop .chart-range-bar > #btn-range-clear { flex: 0 0 auto; white-space: nowrap; }
  #chart-settings-pop .chart-range-bar input[type="date"] { flex: 1 1 0; min-width: 0; }
}

/* 🆕 v513（用户第 9 项）：原「需求 7：综合健康时间轴卡头 ＋（与指标趋势加号同款、靠右）」
   4 条规则（.ht-head-wrap h2 / .hint-q-inline order / .ht-add-btn order / .ht-add-btn 尺寸）
   随整卡下线一并退役。 */

/* ── 需求 12：趋势概览「仅标注数字」条 + 明细 ── */
.ac-count-bar {
  display: flex; align-items: center; gap: 6px; padding: 7px 12px;
  border: 1px solid var(--line); border-radius: 10px;
  background: var(--panel, #f1f4f8); font-size: 13px; color: var(--ink);
  cursor: pointer; user-select: none;
}
.ac-count-bar b { font-size: 15px; }
.ac-count-bar:hover { border-color: var(--primary); }
/* 🆕 v494（用户）：「待办和关注窗口不用自动收起来，正常展示，只是需要设置最高高度，和指标库一样。」
   ⇒ ① app.js 渲染时不再给 .ac-detail 加 hidden ⇒ 默认展开、正常展示；
      ② 高度上限 340px 与指标库同口径（#indicator-list 运行时高 = 10 行 × ~34px ≈ 340px）：
         内容少时不撑高、不出现滚动条，超出才在框内滚动，避免趋势概览被几十条待办撑成超长卡片；
      ③ [hidden] 规则**必须保留**：数字条的手动「点击收起」仍靠它生效（默认态不再是 hidden 而已）。 */
.ac-detail {
  margin-top: 8px; max-height: 340px; overflow-y: auto; overscroll-behavior: contain;
}
.ac-detail[hidden] { display: none; }

/* ── 需求 11：异常结果速览 / 指标近期变化榜 迁到指标趋势页 —— 高度与指标库一致、不足自适应 ──
   指标库 #indicator-list 运行时高 = 10 行 × ~34px ≈ 340px；这里用 max-height（内容少时不撑高、不滚动），
   超出才滚动，实现「高度与指标库一致 + 不足自适应」。 */
#card-lab-abn-list .lab-abn-list,
#card-lab-movers .lab-movers {
  max-height: 340px; overflow-y: auto; overscroll-behavior: contain;
}

/* ── 暗色主题覆盖 ── */
html[data-theme="dark"] :is(.personal-baseline, .ind-analysis) .pb-name .swatch {
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .22);
}
html[data-theme="dark"] :is(.personal-baseline, .ind-analysis) .pb-def { color: #9aa6b2; }
html[data-theme="dark"] :is(.personal-baseline, .ind-analysis) .ia-toggle { color: #7aa2ff; border-color: #3b4a5c; }
html[data-theme="dark"] .ac-count-bar { background: #1c2733; border-color: #3b4a5c; }
html[data-theme="dark"] #btn-ind-count { color: #9aa6b2; border-color: #3b4a5c; }

/* 🆕 自动优化 v490：首页「今日健康完成度」卡 */
/* 🆕 v513（用户第 3 项）：「📊 今日健康完成度」卡整卡下线 ⇒ 下列 13 条规则退役
   （原 .today-completion / .tc-grid / .tc-item(+hover/:focus-visible) / .tc-top / .tc-label /
     .tc-frac / .tc-muted / .tc-track / .tc-fill / .tc-full / .tc-zero / .tc-sum / .tc-foot /
     .tc-streak 与两条暗色覆盖）。 */

/* 🆕 自动优化 v491：睡眠时长记录卡 */
.sleep-log { display: flex; flex-direction: column; gap: 10px; }
.sl-input-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.sl-input { width: 90px; padding: 6px 8px; border: 1px solid var(--line, #d6dde6); border-radius: 8px; font-size: 14px; background: var(--panel); color: var(--ink); }
.sl-unit { color: var(--muted); font-size: 13px; }
.sl-demo-note { font-size: 12px; color: #b8740e; background: rgba(232,138,46,0.12); border: 1px solid rgba(232,138,46,0.3); border-radius: 999px; padding: 2px 10px; }
.sl-stats { display: flex; gap: 16px; flex-wrap: wrap; font-size: 13px; color: var(--muted); }
.sl-stat b { color: var(--ink); font-size: 15px; }
.sl-chart { display: flex; align-items: flex-end; gap: 4px; height: 130px; padding: 6px 2px 0; border-bottom: 1px solid var(--line, #d6dde6); }
.sl-bar-wrap { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; height: 100%; min-width: 0; }
.sl-bar { width: 70%; max-width: 26px; border-radius: 4px 4px 0 0; position: relative; transition: height .2s ease; }
.sl-bar.sl-today { outline: 2px solid var(--accent, #3b82f6); outline-offset: 1px; }
.sl-bar-val { position: absolute; top: -16px; left: 50%; transform: translateX(-50%); font-size: 10px; color: var(--muted); white-space: nowrap; }
.sl-bar-date { font-size: 9px; color: var(--muted); margin-top: 3px; }
.sl-ref { font-size: 12px; color: var(--muted); }
html[data-theme="dark"] .sl-bar-val,
html[data-theme="dark"] .sl-bar-date,
html[data-theme="dark"] .sl-ref,
html[data-theme="dark"] .sl-stats,
html[data-theme="dark"] .sl-unit { color: #9fb0c3; }
html[data-theme="dark"] .sl-input { border-color: #2f3a47; }
html[data-theme="dark"] .sl-chart { border-bottom-color: #2f3a47; }

/* 🆕 自动优化 v492：虚拟药柜（用药卡片墙）——对标 Medisafe 2026「Visual virtual pill cabinet」 */
.pill-cabinet { display: grid; grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)); gap: 12px; padding: 2px; }
.pill-card { position: relative; background: var(--card, #fff); border: 1px solid var(--line, #d6dde6); border-left: 6px solid #888; border-radius: 12px; padding: 12px 12px 10px; cursor: pointer; transition: transform .12s ease, box-shadow .12s ease; min-height: 96px; }
.pill-card:hover { transform: translateY(-2px); box-shadow: 0 6px 16px rgba(0,0,0,.12); }
.pill-card.focused { outline: 2px solid var(--accent, #3b82f6); outline-offset: 1px; }
.pill-card.stopped { opacity: .55; filter: grayscale(.35); }
.pc-top { display: flex; align-items: center; gap: 8px; }
.pc-icon { flex: 0 0 auto; width: 30px; height: 30px; border-radius: 8px; background: var(--line, #eef2f7); display: flex; align-items: center; justify-content: center; font-size: 17px; }
.pc-name { font-weight: 700; font-size: 14px; color: var(--ink); line-height: 1.25; word-break: break-all; }
.pc-sub { margin-top: 6px; font-size: 12px; color: var(--muted); }
.pc-foot { margin-top: 8px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.pc-dot { width: 9px; height: 9px; border-radius: 50%; display: inline-block; }
.pc-bucket { font-size: 11px; color: var(--muted); }
.pc-photo { position: absolute; top: 8px; right: 8px; width: 28px; height: 28px; border-radius: 6px; object-fit: cover; border: 1px solid var(--line, #d6dde6); }

/* 🆕 自动优化 v495：首页「今日健康洞察」卡 */
/* 🆕 v513（用户第 3 项）：「💡 今日健康洞察」卡整卡下线 ⇒ 下列 8 条规则退役
   （原 .daily-insight / .di-list / .di-item / .di-item.di-warn / .di-item.di-info /
     .di-ico / .di-txt / .di-txt b / .di-empty）。 */

/* ══════════════════════════════════════════════════════════════════════════════
   🆕 v495（用户第 2 条）：「指标右侧的问号大小格式间距要和其他图标一致。」
   ── 现状（v417 遗留的不一致）──
      `.ind-def-q` 在 v417 被统一进「窗口右上角图标族」= **26×26**（见本文件 4034-4040 行），
      但指标库操作列里的 改/删 是 v359 的**行内图标族** = **20×20**（4010-4014 行）
      ⇒ 同一行里 `?` 比 ✎/× 大整整一圈，且格式也不同（`?` 是 panel 实心圆 + line 灰描边，
        ✎ 是透明底 primary 描边圆、× 是红底白叉）。
   ── 做法 ──
      只把**指标库操作列里**那个 `?`（HTML 里带 `.ind-def-q-lib` 的那个，见 js/app.js 指标库行渲染）
      拉回行内图标族口径：20×20 圆钮、1px 主色描边、透明底、主色字形、与相邻图标同 6px 间距。
      ⚠️ 不动 `.ind-def-q` 的通用规则 —— 「指标分析」窗口名称行那个 `?` 仍属右上角图标族 26×26。
   ── 特异性 ──
      v417 的 `.ind-def-q` 是 (0,1,0)、v423 的 `#indicator-list .row-actions .ind-def-q-lib` 是 (1,2,0)；
      本段 `#indicator-list .row-actions .ind-def-q.ind-def-q-lib` = (1,3,0) 且位于文件**最末** ⇒ 必胜，无需 !important。
   ══════════════════════════════════════════════════════════════════════════════ */
#indicator-list .row-actions .ind-def-q.ind-def-q-lib {
  box-sizing: border-box;
  display: inline-flex; align-items: center; justify-content: center;
  /* 🆕 v513（用户第 6 项）：「指标库窗口中指标行的右边的图标高度不一致。」
     ── 实测（`_v513_icons.js` 在真页面上量的，不是读代码猜的）──
        盒子尺寸三个都是 **20×20**（改/删走 4443 行 `.btn.act-ico` 的 20×20，
        `?` 走本段 20×20 —— 4443 与 6037 同为「行内图标族」口径），**盒子并不不齐**；
        真正不齐的是**墨迹**：删 `×` 与 `?` 是 15px 字号文本（Range 实测高 17px），
        而改按钮 v513 第 7 项起换成内联 SVG，被 `.act-ico svg{width:12px;height:12px}`（4442 行）
        压成 **12×12** ⇒ 铅笔比另两个小一圈。
     ── 处置 ──
        ① 本按钮**保持 20×20**（与兄弟一致，不再单独放大 —— v513 中途试过 26×26，
           实测反而把 `?` 顶成比另两个大一圈，已回退）；
        ② 铅笔墨迹高度另行对齐，见 4442 行附近的 `.act-ico svg` 新口径。 */
  width: 20px; height: 20px; min-width: 20px; min-height: 20px;
  margin-left: 6px;                 /* 与 `.act-ico + .act-ico` 的 6px 对齐（gap 已在 3936 行归零） */
  padding: 0; border-radius: 50%;
  border: 1px solid rgba(14, 124, 134, .45);   /* 与 v359 的 `.act-ico.act-edit` 同款描边 */
  background: transparent; color: var(--primary);
  font-size: 15px; font-weight: 700; line-height: 1; opacity: 1;
  cursor: pointer; -webkit-tap-highlight-color: transparent;
}
#indicator-list .row-actions .ind-def-q.ind-def-q-lib:hover {
  border-color: var(--primary); background: rgba(14, 124, 134, .12);
}
html[data-theme="dark"] #indicator-list .row-actions .ind-def-q.ind-def-q-lib {
  border-color: rgba(127, 221, 228, .45); background: transparent; color: #7fdde4;
}
html[data-theme="dark"] #indicator-list .row-actions .ind-def-q.ind-def-q-lib:hover {
  border-color: #7fdde4; background: rgba(127, 221, 228, .12);
}

/* ══════════════════════════════════════════════════════════════════════════════
   🆕 v495（用户第 3 条）：趋势概览「标题下方统计条」（.ts-stats / .rec-summary）
   🆕 v513（用户第 5 项）：同批下线的卡头按钮 `.ts-ac-btn`（#btn-ac-toggle）整套 CSS 已删 ——
      该按钮整只下线（数字统一收进统计条），下方 #ts-body 明细随之常显、不再可收起，
      故 `#ts-body[hidden]{display:none}` 也不再需要。
      历史教训（留档，别再踩）：那个按钮必须写 `.card-head > .btn.tiny.ts-ac-btn`（4 个类），
      因为全局 `.card-head > .btn.tiny{width:26px;height:26px;padding:0;border-radius:50%}`
      会把它压成 26×26 圆形、文字溢出成两行并压住 🌰。
   ══════════════════════════════════════════════════════════════════════════════ */

/* 标题下方「最近一次指标统计」条：沿用 .rec-summary 徽标，只把外边距贴合卡头下方 */
.ts-stats { margin: 0 0 10px; }

/* 🆕 v495（用户第 4 条）：重复图片弹框的「后续都按相同的方式处理」勾选框 */
.dup-ask-apply {
  display: flex; align-items: center; gap: 6px;
  margin-top: 12px; font-size: 12.5px; color: var(--ink-soft, #555);
  cursor: pointer; user-select: none;
}
.dup-ask-apply input { width: 15px; height: 15px; margin: 0; flex: 0 0 auto; accent-color: var(--primary); }

/* 🆕 自动优化 v496：本周用药计划表（周历网格） */
.mw-grid-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.mw-grid { border-collapse: separate; border-spacing: 0; width: 100%; min-width: 560px; font-size: 13px; }
.mw-grid th, .mw-grid td { border: 1px solid #e3e9f0; padding: 6px 6px; text-align: center; vertical-align: middle; }
.mw-corner { background: transparent; border: none; }
.mw-grid thead th { background: #eef4f8; color: #34495e; font-weight: 600; position: relative; line-height: 1.3; }
.mw-grid thead th .mw-date { display: block; font-size: 11px; color: #8a99a8; font-weight: 400; }
.mw-grid thead th.today { background: #0e7c86; color: #fff; }
.mw-grid thead th.today .mw-date { color: #d6f0f2; }
.mw-today-flag { display: block; font-size: 10px; background: #ffd34d; color: #5b4b00; border-radius: 6px; margin-top: 2px; padding: 0 2px; }
.mw-rowhead { background: #f7fafc; color: #34495e; font-weight: 600; white-space: nowrap; text-align: left; padding-left: 8px; }
.mw-cell.today { background: #f1fbfb; }
.mw-none { color: #c2ccd6; }
.mw-chip { display: inline-block; color: #fff; border-radius: 6px; padding: 2px 6px; margin: 2px; font-size: 12px; max-width: 130px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: middle; }
.mw-chip.taken { box-shadow: inset 0 0 0 2px #fff; }
.mw-chip.skipped { opacity: .5; text-decoration: line-through; }
.mw-legend { margin-top: 8px; font-size: 12px; color: #6b7a8d; }
.mw-legend .mw-lg { margin-right: 12px; }

/* ============================================================
   🆕 v496（用户第 2 条）：数据管理按钮按用途分 3 组（8 → 6 个按钮）
   —— 组标签把「备份与恢复 / 就诊报告·给医生 / 健康摘要·给家人」三类用途一眼分开，
      消除原先「两个按钮都叫系统分享」的歧义。组标签是纯展示元素，不参与 tab 顺序。
   ============================================================ */
.pa-group + .pa-group { margin-top: 14px; }
.pa-group-lab {
  display: block;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--muted);
  margin: 0 0 7px;
  line-height: 1.3;
}
/* 左侧色条：与卡片主色一致，弱化但可辨 */
.pa-group-lab::before {
  content: "";
  display: inline-block;
  width: 3px; height: 12px;
  border-radius: 2px;
  background: var(--primary);
  margin-right: 6px;
  vertical-align: -1px;
}
/* 组内按钮行沿用既有 .page-actions-bar（含各断点规则），这里只补组内第一行的上边距归零 */
.pa-group .page-actions-bar:first-of-type { margin-top: 0; }
/* 卡片底部那句 hint 与最后一组留出距离 */
.pa-group + .hint { margin-top: 4px; }

/* ============================================================================
   🆕 v496（用户第 4 项 · MasterGo「tab-bar」节点 6:903）：手机端页签改为**底部导航**
   ── 设计口径（MasterGo tab-bar 6:903 实测）：
        白底 + 顶部 1px #E2E8F0 分隔线；padding 8/6/12；
        每项 flex:1、纵向居中、gap 4px；图标 16px；标签 10px/14px；
        选中 #0E7C86（font-weight 500），未选中 #8A98A8。
   ── 落地约束（⚠️ 只在 ≤640px 生效）：
        · 桌面端 / Electron 窗口保持原来的**顶部横向页签**，一行都不动。
        · 术语按 App 现行口径映射：设计里的「化验记录」→ 检验记录、「档案」→ 个人档案、
          「日常测量」→ 日常记录（不反过来改 App 的术语）。
        · 图标用 emoji（与全站既有 emoji 风格一致，零新增图片资源）；首页沿用它的 .home-grid-ico。
        · 底栏 position:fixed；.content 补 padding-bottom 避让；
          .toast 与「回到顶部」FAB 原本都在 bottom 20–30px，会被底栏压住 ⇒ 一并上移。
        · z-index:30 —— 高于 .app-header(20)，低于所有弹层（.legal-mask 900 / .consent-mask 950 /
          .dup-ask-overlay 1200 / .bv-paymask 3000 …），弹层打开时正常盖住底栏。
        · 不写任何 inline top —— syncHeaderOffset() 只写 --cm-header-h 变量，不会干扰本块。
   ============================================================================ */
@media (max-width: 640px) {
  /* 顶部 header 里只剩「🌙 夜间」按钮（页签被移到下面），靠右对齐更顺眼。
     🆕 v499：`.app-header` 已改为 block、行内对齐搬到 `.hdr-top` ⇒ 这条对齐目标跟着改。
     （漏改的话主题按钮会掉到左边，而它本来一直贴右。） */
  .hdr-top { justify-content: flex-end; }

  /* 🆕 v499（用户第 3 项）：手机端页眉第二行 —— 触控尺寸放大到 32px，但**行高仍固定 34px**
     （`.hdr-sub` 的 min-height），保证「页名行」与「子页签行」高度相同。 */
  .hdr-sub { gap: 6px; }
  .hdr-back { width: 32px; height: 32px; }
  .hdr-sub-name { font-size: 15.5px; }
  .app-header .chart-tab, .app-header .lab-tab { height: 30px; padding: 0 12px; font-size: 13px; }
  .app-header .lab-tab { padding: 0 14px; }
  .app-header .chart-tab-nav { width: 30px; height: 30px; font-size: 16px; }

  /* 🆕 v499（用户第 9 项）：手机端「照片识别结果」大图窗口改成**正方形**（高 = 宽）。
     用户原话：「图片识别结果、指标识别结果和都改成高宽相等」——下方「指标识别结果」
     （.entry-ind-win）在手机端已由 js/app.js 的 applyEntryIndWindow 按 clientWidth 取方，
     两块窗口因此同尺寸、上下沿对齐。桌面端不适用（卡片宽 ≈1040px，取方等于 1040px 高）。
     ⚠️ 必须写在 ≤640 块里（源序在 ≤767 块之后）才能压过上面 ≤767 的
        `height:auto; max-height:none; overflow:visible` —— 两条选择器特异性相同 (0,1,0)，
        只靠先后顺序决胜。
     ⚠️ `overflow` 要留 `auto`（不能跟 ≤767 一样用 visible）：窗口变方后竖图必然超出，
        必须在窗口内滚动查看，否则下半张照片直接跑出窗口、看起来像被裁掉了。 */
  .entry-img-wrap { aspect-ratio: 1 / 1; height: auto; max-height: none; overflow: auto; }

  #tabs.tabs {
    position: fixed; left: 0; right: 0; bottom: 0;
    z-index: 30;
    display: flex; flex-wrap: nowrap; align-items: stretch; gap: 0;
    /* 🆕 v535（用户需求 2）：恢复每枚图标的 2 字标签（v534 纯图标化被用户否掉）⇒
       上下 padding 4→6px 回调给两行内容留高；其余 v534 改进（七等分、不横滚）保留。 */
    padding: 6px 4px calc(6px + env(safe-area-inset-bottom, 0px));
    background: #fff;
    border-top: 1px solid #e2e8f0;
    border-bottom: 0;
    box-shadow: 0 -6px 20px rgba(15, 30, 45, .07);
    overflow: visible;
    -webkit-mask-image: none; mask-image: none;   /* 底栏不横向滚动，取消溢出蒙层 */
  }
  #tabs.tabs .tab {
    flex: 1 1 0; min-width: 0;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    /* 🆕 v535：图标与文字之间留 2px 呼吸（v534 的 gap:0 是纯图标栏的口径） */
    gap: 2px;
    padding: 5px 2px;
    border: 0; border-radius: 8px;
    background: transparent;
    color: #8a98a8;
    /* 🆕 v533：font-size:0 隐藏按钮里的原始文字节点 —— 网页版（>640px）顶部页签全称不受影响。
       🆕 v535（用户需求 2）：文字标签由 ::after 恢复（v534 删除被用户否掉）——
       原始文字节点仍保持 font-size:0（避免整段全称撑破七等分），只显示 2 字短标签。 */
    font-size: 0; font-weight: 400; line-height: 1;
    white-space: nowrap; overflow: hidden;
    -webkit-tap-highlight-color: transparent;
  }
  /* 图标：用 ::before 生成，不动按钮 innerHTML（JS 里按 data-tab 取按钮，无需改） */
  #tabs.tabs .tab::before { content: ""; display: block; font-size: 19px; line-height: 1; }
  #tabs.tabs .tab[data-tab="trend"]::before   { content: "📈"; }
  #tabs.tabs .tab[data-tab="lab"]::before     { content: "🧪"; }
  #tabs.tabs .tab[data-tab="med"]::before     { content: "💊"; }
  #tabs.tabs .tab[data-tab="vitals"]::before  { content: "🩺"; }
  #tabs.tabs .tab[data-tab="profile"]::before { content: "🗂️"; }
  #tabs.tabs .tab[data-tab="member"]::before  { content: "👑"; }
  /* 🆕 v535（用户需求 2）：恢复 2 字短标签（v533-6 口径 + 首页补「首页」，用户原话
     「之前每个图标的2个文字要恢复」⇒ 七枚页签每枚都有字）。 */
  #tabs.tabs .tab::after { content: ""; display: block; font-size: 10.5px; line-height: 1; letter-spacing: .5px; }
  #tabs.tabs .tab[data-tab="home"]::after    { content: "首页"; }
  #tabs.tabs .tab[data-tab="trend"]::after   { content: "趋势"; }
  #tabs.tabs .tab[data-tab="lab"]::after     { content: "检验"; }
  #tabs.tabs .tab[data-tab="med"]::after     { content: "用药"; }
  #tabs.tabs .tab[data-tab="vitals"]::after  { content: "事件"; }
  #tabs.tabs .tab[data-tab="profile"]::after { content: "档案"; }
  #tabs.tabs .tab[data-tab="member"]::after  { content: "会员"; }
  /* 首页：桌面态是纯图标按钮（自带 .home-grid-ico 小网格）⇒ 网格当图标，与其余六枚同大 */
  #tabs.tabs .tab[data-tab="home"] .home-grid-ico { width: 19px; height: 19px; }
  /* 选中态：青绿文字、无白底、无下边框 */
  #tabs.tabs .tab.active,
  #tabs.tabs .tab[data-tab="home"].active {
    color: var(--primary, #0e7c86);
    font-weight: 500;
    background: transparent;
    border-bottom-color: transparent;
  }

  /* 内容区底部避让（🆕 v535：底栏恢复两字标签 ≈52px + 安全区），避免最后一张卡被遮 */
  .content { padding-bottom: calc(64px + env(safe-area-inset-bottom, 0px)); }
  /* 悬浮提示 / 回顶按钮上移到底栏之上 */
  .toast { bottom: calc(70px + env(safe-area-inset-bottom, 0px)); }
  .scroll-top-fab { bottom: calc(68px + env(safe-area-inset-bottom, 0px)); }

  /* 夜间模式：底栏跟随面板色 + 深色分隔线；选中色用夜间强调色 */
  html[data-theme="dark"] #tabs.tabs {
    background: var(--panel, #182230);
    border-top-color: var(--line, #2c3744);
    box-shadow: 0 -6px 20px rgba(0, 0, 0, .38);
  }
  html[data-theme="dark"] #tabs.tabs .tab { color: var(--muted, #9aa6b2); }
  html[data-theme="dark"] #tabs.tabs .tab.active,
  html[data-theme="dark"] #tabs.tabs .tab[data-tab="home"].active { color: var(--primary, #1aa7b1); }
}

/* 🆕 v512（用户第 2 项）：.abn-glance 样式随首页「⚠️ 当前异常指标速览」卡整卡下线一并删除。 */

/* ═══ 🆕 v506：【日常记录】页整页统一（用户：「整页统一按照 uiskill 策略来美化」）═══
   本页 13 个窗口/分节块原先有三种卡头形态，🌰 落位因此出现「内联」与「绝对定位」两套：
     A. `.card > .card-head > h2` + `.card > p.hint`   → 🌰 内联在标题行右端
        （时间轴事件标记 / 日常测量 / 就诊与复查 —— 只有 3 个）
     B. `.card > h2`（裸标题）+ `.card > p.hint`       → 🌰 绝对定位 top:8 right:8
        （自定义追踪项 / 每日健康打卡 / 睡眠时长记录 / 疫苗接种 / 过敏记录 / 事件记录变更）
     C. `.card > .card-head > p.hint`（hint 写进了卡头里）→ 🌰 落进卡头但**没拿到 .hint-q-inline**
        ⇒ 仍绝对定位，压在卡头右侧的「＋」上（心理量表自评；当时靠 margin-right:30px 硬让位）
   index.html 已把 A/B/C 全部改成 A；另把 `.symptom-heatmap` 这个**分节块**也套上 .card-head。
   本段只补两条「保字号」兜底规则，其余全部由既有 `.card-head` 规则接管。 */

/* ① 分节块「症状日历热力图」的标题**故意保持 15px**（小于窗口标题 15.5/16px）——
      按 4419-4421 行既有约定：窗口内的分节标题本就该小于窗口标题（「用药图例」14px 同理）。
      ⚠️ 必须放在 4447 行 `.card-head > h3 { margin: 0 }` 之后，且带 `.symptom-heatmap` 前缀（(0,2,1) 压过 (0,1,1)），
         否则会被 `.card-head > h3 { font-size: 15.5px }` 顶掉。 */
.symptom-heatmap > .card-head > h3 { font-size: 15px; margin: 0; color: #1f2d3d; }
html[data-theme="dark"] .symptom-heatmap > .card-head > h3 { color: #e6edf3; }

/* ② 分节块的卡头底边距比窗口卡头更紧（原 `.symptom-heatmap h3 { margin: 0 0 4px }` 的等效值），
      避免 12px 底边距把热力图推得比原来低。 */
.symptom-heatmap > .card-head { margin: 0 0 4px; }

/* ══════════ 🆕 v509：微信指引弹层按入口分流（用户第 1/2 项） ══════════ */
/* 同一个 #wechat-help-modal 供两个入口共用 —— 图片识别页的 💬 微信 与 文件识别页的 💬 微信。
   用户要求：照片入口的弹窗「仅展示从微信聊天中导入照片的方法」，文件入口的弹窗
   「仅展示从微信中导入文件的方法」。做法是 openWechatHelp('photo'|'file') 给弹层打
   .wh-photo / .wh-file（见 js/app.js），这里只负责显隐。
   ⚠️ DOM 顺序刻意不动：若改成「按入口删/插节点」，任何按 DOM 位置查节点的 e2e 断言都会
      随入口漂移；用类切换则 DOM 恒定、可断言。
   ⚠️ 只写 display，不动 margin/布局 —— .def-body section{margin-bottom:14px}（见本文件 1515 行）
      等既有规则原样生效，两个模式的段间距完全一致。 */
#wechat-help-modal .wh-photo-only,
#wechat-help-modal .wh-file-only { display: none; }
#wechat-help-modal.wh-photo .wh-photo-only,
#wechat-help-modal.wh-file .wh-file-only { display: block; }
/* 标题里的两个候选 <span> 必须按**行内**显示，否则会各占一行、把 17px 的标题撑成两行。 */
#wechat-help-modal.wh-photo .wh-photo-only.wh-inline,
#wechat-help-modal.wh-file .wh-file-only.wh-inline { display: inline; }

/* ══════════ 🆕 v509：文件识别窗主按钮行（用户第 1 项） ══════════ */
/* 📁 文件夹 / 💬 微信 已从卡头搬到这里，并复用「📸 图片识别」窗的
   `.scan-actions-row` + `.btn.scan-act-btn`（定义在 css/scan.css 1386~1403 行），
   因此**尺寸、圆角、间距、≤480px 压缩规则与图片识别窗逐字节同源**，不需要在这里复制一份。
   仅补一条：本行处于 p.hint 之下、紧邻卡头，上外边距比图片识别窗（其上还有一行 .scan-filehint
   空段）略收，避免与 hint 之间出现双份间距。 */
#lab-entry-file > .card > .file-actions-row { margin: 8px 0 10px; }

/* ══════════════════════════════════════════════════════════════════════════════
   🆕 v512（用户第 1 项）：「今日用药清单要可修改，网页上每条记录一行，右侧增加修改、删除按钮。」
   ── 为什么要「每条记录一行」──
     现状：`.today-meds .tm-list` 是 `display:flex; flex-wrap:wrap`、`.today-med{min-width:210px}`
     ⇒ 宽屏下多条记录**并排挤在一行**（一屏塞 4~5 张小卡），行尾没有可操作的地方；
     改为纵向单列后，每条药独占一行、右端留有稳定的操作位（与「用药记录表」逐行操作的观感一致）。
   ── 行尾按钮的落位 ──
     `.today-med` 的可视顺序由 `order` 决定（见本文件 5049/5067 行的 v499 段）：
       order 0 = 勾选/跳过/跳过原因/色点/照片
       order 2 = 「始于 …」（margin-left:auto 顶到右端）→ 本段的 `.tm-acts`
       order 3 = `.tm-body`（flex:1 1 100% 独占第二行）
     ⇒ 给 `.tm-acts` 同样取 `order:2` 且 DOM 排在 `.tm-start` 之后，两枚按钮必然落在**首行最右端**。
   ── ⚠️ 尺寸必须自己兜住 ──
     `.btn.tiny` 在本文件手机断点里写了 `min-height:36px; padding:5px 12px`，特异性 (0,2,0)；
     而 `.act-ico` 的通用尺寸规则只有 (0,1,0) ⇒ **只写 width/height 会被 min-height 顶回去**
     （v359 实测过：按钮仍是 26×36）。故这里用 `.today-meds .tm-acts > .btn.act-ico`（(0,4,0)）
     连同 min-height/padding 一起复位，尺寸与「指标库 / 检验记录 / 用药记录表」行内的改/删**完全一致**（20×20）。
   ============================================================================ */
.today-meds .tm-list { flex-direction: column; gap: 8px; }
.today-meds .tm-list > .today-med { width: 100%; min-width: 0; }
/* 🆕 v535（用户需求 3）：「用药记录列表的编辑和删除按钮要统一放到右上角去」——
   v512 的落位是「首行右端」（跟随文字流、与「始于…」同行），而「用药记录表」行卡
   自 v526 起已是**绝对定位到卡片右上角**（#med-list td.actions-col）。两处形态不一，
   用户要求统一 ⇒ 今日清单每条也改成绝对定位右上角，口径与 #med-list 逐字对齐
   （top:6px right:8px），「始于 …」恢复 margin-left:auto 顶到右端。
   ⚠️ 按钮仍 20×20（视觉），点击命中区由 ::after 外扩到 ≥40×40（UISKILL Critical Rule 10）。 */
.today-meds .tm-list > .today-med { position: relative; padding-right: 56px; }
.today-meds .tm-acts {
  position: absolute; top: 6px; right: 8px;
  order: 0; margin: 0; flex: none;
  display: inline-flex; align-items: center; gap: 6px;
}
.today-meds .tm-acts > .btn.act-ico {
  width: 20px; height: 20px; min-width: 20px; min-height: 20px;
  padding: 0; box-sizing: border-box; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  position: relative;   /* ::after 命中区外扩的定位上下文 */
}
.today-meds .tm-acts > .btn.act-ico svg { width: 12px; height: 12px; }
/* UISKILL 命中区：可见 20px 圆钮、可点 40×40（向外扩 10px，两钮间隙 6px 不重叠） */
.today-meds .tm-acts > .btn.act-ico::after {
  content: ""; position: absolute; left: 50%; top: 50%;
  width: 40px; height: 40px; transform: translate(-50%, -50%);
}
/* ≤640px：绝对定位后行尾间距规则作废，仅保留两钮间隙。 */
@media (max-width: 640px) {
  .today-meds .tm-acts { gap: 4px; }
}

/* ══════════════════════════════════════════════════════════════════════════════
   🆕 v513（用户第 4 项）：设置弹窗「勾选按钮 / 时间 / 图形选择」按 mastergo 改造。
   参考：mastergo 两行分段控件（近7天｜近30天｜全部 ／ 折线图｜面积图｜柱状图），
        选中项 = 青绿实底 + 白字 + 圆角块；图形选择项带图形图标。
   ⚠️ 结构不变量（门禁依赖，禁改）：
      · `.range-presets` 容器类名 + 每个按钮的 `data-range` 属性
        （_e2e_v453_dock_tiles.js B6 用 `#chart-range-bar .range-presets [data-range="7"]` 定位并点击）；
      · `<select id="chart-type">` 仍须是 #chart-settings-pop 内的 <select>
        （_e2e_v315.js A4 断言 `pop.querySelector('#chart-type')` 存在）。
        ⇒ 只把它「视觉隐藏」，它仍作为图表类型的唯一事实来源（JS 读写全走它）。
   ══════════════════════════════════════════════════════════════════════════════ */

/* —— 1. 分段控件本体（时间范围 / 图形选择共用）—— */
.seg-group {
  display: inline-flex; align-items: center; gap: 2px;
  padding: 3px; border-radius: 10px;
  background: var(--bg); border: 1px solid var(--line);
}
.seg-btn {
  display: inline-flex; align-items: center; gap: 4px;
  margin: 0; padding: 5px 12px; border: 0; border-radius: 8px;
  background: transparent; color: var(--muted);
  font: inherit; font-size: 12.5px; line-height: 1.45; font-weight: 500;
  cursor: pointer; white-space: nowrap;
  transition: background .15s ease, color .15s ease;
}
.seg-btn:hover { color: var(--ink); background: rgba(14, 124, 134, .09); }
.seg-btn.on { background: var(--primary); color: #fff; font-weight: 600; }
.seg-btn.on:hover { background: var(--primary-d); color: #fff; }
.seg-btn:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
.seg-ico { display: inline-flex; align-items: center; flex: 0 0 auto; }
.seg-ico svg { width: 14px; height: 14px; display: block; }

/* —— 2. 时间范围预设：保持右对齐（不动 .chart-range-bar 既有布局）。
   特异性 (0,3,0) > 既有 `.chart-range-bar .range-presets`(0,2,0)，故 gap/padding 覆盖生效。 —— */
.chart-range-bar .range-presets.seg-group { display: inline-flex; margin-left: auto; gap: 2px; padding: 3px; }
.chart-settings-body .chart-range-ctrl .range-presets.seg-group { justify-content: flex-end; }

/* —— 3. 勾选按钮：浅底胶囊卡片（与 mastergo 分段控件同一套视觉语言；
        取值与旧 .chart-toolbar-bottom label.check 对齐，避免「两代控件长得不一样」）—— */
#chart-settings-pop .chart-settings-body label.check {
  display: flex; align-items: center; gap: 8px; padding: 9px 12px;
  min-height: 40px; border: 1px solid var(--line); border-radius: 10px;
  background: #fff; font-size: 13.5px; color: var(--ink);
}
#chart-settings-pop .chart-settings-body label.check input { width: 17px; height: 17px; flex: 0 0 auto; accent-color: var(--primary); }

/* —— 4. 图形选择：可见交互 = 分段控件；<select id="chart-type"> 视觉隐藏但仍是唯一事实来源 —— */
#chart-settings-pop .chart-type-ctrl > label { flex: 0 0 auto; font-weight: 600; color: var(--ink); }
#chart-settings-pop .chart-type-ctrl .seg-group { flex: 1 1 auto; }
/* ⚠️ 特异性必须压过既有 `.chart-settings-body select { padding:6px 8px; border:1px }`(0,1,1)：
   否则 border-box 下 1×1 会被 padding+border 撑成 ~18×14（v513 首轮实测踩到）。 */
.chart-type-native,
#chart-settings-pop .chart-settings-body select.chart-type-native {
  position: absolute; width: 1px; height: 1px; min-width: 0; max-width: 1px;
  margin: -1px; padding: 0; border: 0; border-radius: 0;
  opacity: 0; pointer-events: none; overflow: hidden;
}

/* —— 5. 暗色覆盖 —— */
html[data-theme="dark"] .seg-group { background: rgba(255, 255, 255, .06); border-color: #3b4a5c; }
html[data-theme="dark"] .seg-btn:hover { background: rgba(26, 167, 177, .16); }
html[data-theme="dark"] #chart-settings-pop .chart-settings-body label.check { background: #1a232e; border-color: #2c3a4c; }

/* ══════════════════════════════════════════════════════════════════════════════
   🆕 v513（用户第 7 项）：「所有弹窗和下拉窗口都要用UISKILL做一致性检查」
   ---------------------------------------------------------------------------
   检查工具 = UISKILL `zxh-make-interfaces-feel-better`（7 条 Core Principles + 10 条 Critical Rules）。

   ── 被检查的 6 族（都是「浮在页面之上的表面」）──
     ① .def-modal + .def-popup-content   7 个 .modal 的遮罩 + 圆角卡
     ② .hintpop                          🌰/❓ 说明气泡
     ③ #ind-filter-menu / #rec-filter-menu / #med-filter-menu   三个 .rec-filter 下拉（**已**统一 12px）
     ④ .scan-add-menu（含 .scan-find-menu） ＋ 下拉（规则在 css/scan.css）
     ⑤ .ind-add-pop                      指标库「添加指标」内联弹窗
     ⑥ .modal 语义类                     族 ① 的 DOM 契约（已补 #wechat-help-modal，见 index.html）

   ── 本段落 5 组修正 ──
   A. 命中区 ≥40×40（Critical Rule 10「Hit areas are physical」）
      三颗**孤立**的角落关闭钮原本都小于 40：.def-close 30×30、.hintpop .hp-x ≈27×23、
      #ind-filter-menu #btn-ind-filter-close 22×22。
      用 `::after` 外扩命中区而**不动视觉尺寸** ⇒ 盒子尺寸/computedStyle 一字未改，
      既有几何断言（v357 那批 20×20 / 26×26 的）零影响；且三颗周围没有其它可点元素，
      不会出现 UISKILL 明令禁止的「命中区互相重叠」。
      ⚠️ 纵向堆叠的菜单项（.scan-add-menu .btn）**不能**用这招 —— 外扩必与相邻项重叠，
         只能真调高度，改在 css/scan.css（34/32 → 40）。
   B. 动态数字 tabular-nums（Critical Rule 5）
      计数条「共 N 项 / 恶化 N / 改善 N / 恢复正常 N」在筛选前后**位数会变**
      （1 → 2 位），非等宽会横向抖动 ⇒ 对 .rec-summary 整棵子树生效。
   C. 按压反馈（Critical Rule 8「tactile active states」）
      全站 .btn 只有 :hover、**没有 :active**（255-257 行）。弹窗族里补两档：
      角落关闭钮用 scale(.96)（UISKILL 推荐的按压缩放上限），大按钮用 brightness 下压
      （不改几何，避免整宽按钮缩放看起来在抖）。
   D. 圆角一致性（Core Principle 1「optical coherence over formula」）
      同为「浮层表面」，圆角原本散成 4 个值（14 / 12 / 10 / 10）⇒ 统一为 **12px**
      （族 ③ 与 ④ 早已是 12，把它们对齐到既有口径而不是另发明一个值）。
   E. 短标题换行（Critical Rule 4）
      .def-popup-content header h3 ⇒ text-wrap: balance（弹窗标题短，避免末行掉孤字）。

   ── 已核对、本次**不改**（逐条给理由，交用户定夺）──
   · `transition: all`（Critical Rule 9）：6 族内**一处都没有**。全站仅 7 处，
     全在弹窗族**之外**（.today-med 的 4 颗小钮、.chart-tab、.bv-login-tab、.hint-toggle）。
     用户第 7 项的范围口径是「所有弹窗和下拉窗口」⇒ 不越界改，另列审计表。
   · 入场 / 退场动画分离（Critical Rule 7）：.def-popup-content 只有入场 keyframe
     `defFadeIn`，退场是瞬时隐藏。加退场动画必须让 hide 延迟 ≥1 帧，
     会改掉「点 ✕ 立即关闭」的既有节奏与多处 e2e 的时序假设 ⇒ 列为待议项，不擅自改。
   · #ind-filter-menu 内 .rec-search 圆角 8 对面板 12（同心式应为 12-10=2）：
     UISKILL 允许「padding 较大时把两层当**独立表面**处理」——面板内边距 10px 相对
     300px 面板已属大；强行取 2px 会让搜索框近乎方角，观感反而更差 ⇒ 保持独立表面。
   · 图片描边（Critical Rule 6）、字体平滑（macOS）：本项目图片走 .scan-thumb 自有边框，
     且目标是 Android WebView（非 macOS）⇒ 不适用。 */

/* ── A-1 指标库搜索弹窗的 ✕（22×22 → 命中区 40×40） ──
   ⚠️ 这里**绝对不能**再写 `position: relative`：基线规则（5334 行）已经把它设成
      `position: absolute`（钉在面板右上角 top:5 right:5）。同特异度的后置规则一旦改成
      relative，它就掉回 grid 文档流、位置全变，而且 `::after` 会被**后绘制的兄弟元素**
      （搜索框等）盖住 ⇒ 实测命中区退回 22×22（_v513_uiskill.js U4 抓到的就是这个）。
      按钮本来就已是定位元素，`::after` 直接以它为包含块，无需任何 position 覆盖。 */
/* ⚠️ 外扩 11px（**不是** 9px）：本钮有 1px 透明边框，`::after` 的 inset 以 **padding box**
   为基准（22 - 2 = 20）⇒ 20 + 11×2 = 42 才稳达标；写 9px 只有 38px（_v513_u4dbg.js 实测），
   写 10px 实测 39px（亚像素取整吃掉 1px）⇒ 最终取 11px。
   代价是命中区比面板右/上缘多出 6px（钮在面板内 top:5 right:5）—— 面板 overflow:visible
   且自成层叠上下文（z-index:40），那 6px 里 `::after` 仍是最上层，点它等于点 ✕，属可接受行为。 */
#ind-filter-menu #btn-ind-filter-close::after { content: ''; position: absolute; inset: -11px; }

/* ── A-2 🌰/❓ 说明气泡的 ✕（≈27×23 → 命中区 ≥40×40） ── */
.hintpop .hp-x::after { content: ''; position: absolute; inset: -10px; }

/* ── A-3 弹窗族的 ✕（30×30 → 命中区 40×40） ──
   ⚠️ 外扩 6px（不是 5px）：本钮 `border:none`，但实测 rect 会落在 29.x（分数宽度），
   写 5px 时实测命中区只有 38×38（_v513_uiskill.js U2 红），加到 6px 后 ≥40。 */
.def-close { position: relative; }
.def-close::after { content: ''; position: absolute; inset: -6px; }

/* ── B 计数条数字等宽 ── */
.rec-summary { font-variant-numeric: tabular-nums; }

/* ── C 按压反馈 ── */
.def-close:active,
.hintpop .hp-x:active,
#ind-filter-menu #btn-ind-filter-close:active { transform: scale(.96); }
.def-popup-content .btn:active,
.ind-add-pop .btn:active { filter: brightness(.96); }

/* ── D 浮层表面圆角统一 12px（族 ③/④ 本已是 12） ── */
.def-popup-content { border-radius: 12px; }
.hintpop { border-radius: 12px; }
.ind-add-pop { border-radius: 12px; }

/* ── E 弹窗标题不掉孤字 ── */
.def-popup-content header h3 { text-wrap: balance; }

/* ════════════════════════════════════════════════════════════════════════════
   🆕 v513（用户第 3 项）：指标库 →「🗂 按分类选择指标」弹窗 #ind-cat-picker
   本体沿用 `.modal.def-modal` + `.def-popup-content`（与释义 / 确认 / 添加用药 / 患者档案同族），
   这里只补「页签条 + 清单 + 底部」三块的自有排版：
     · 页签条：与指标趋势页的分类页签**同视觉语言**（当前项青绿实底白字），但独立类名，
       不复用 .chart-tab —— 那边带分页箭头与 .chart-tabs-pager 的尺寸约束，混用会互相带坏。
     · 清单：两列网格（手机上单列），整行可点 → 命中区 ≥40px（UISKILL：Hit areas are physical）。
     · 已勾选行：绿色左边条 + 浅绿底 + 右侧 ✓，与指标库 `.ind-row.on` 同语义、同色系。
   ⚠️ 数字一律 tabular-nums（UISKILL Critical Rule 5）：切页签时计数不该左右跳。
   ════════════════════════════════════════════════════════════════════════════ */
.ind-cat-pop { width: min(620px, 94vw); }
.ind-cat-note { margin: 0 0 12px; }
.ind-cat-tabs {
  display: flex; flex-wrap: wrap; gap: 6px;
  padding-bottom: 10px; margin-bottom: 10px;
  border-bottom: 1px solid var(--line, #e2e8f0);
}
.ind-cat-tab {
  font: inherit; font-size: 12.5px; font-weight: 600;
  font-variant-numeric: tabular-nums;
  padding: 7px 11px; min-height: 34px; cursor: pointer;
  color: var(--ink, #1f2937); background: #fff;
  border: 1px solid var(--line, #d7dee6); border-radius: 999px;
  transition: background-color .15s ease-out, border-color .15s ease-out, color .15s ease-out;
}
.ind-cat-tab:hover { border-color: var(--primary, #0e7c86); }
.ind-cat-tab.active { background: var(--primary, #0e7c86); border-color: var(--primary, #0e7c86); color: #fff; }
.ind-cat-tab:active { transform: scale(.96); }
.ind-cat-list {
  display: grid; grid-template-columns: 1fr 1fr; gap: 6px;
  max-height: min(46vh, 380px); overflow: auto;
  padding: 2px; margin: 0 0 12px;
}
.ind-cat-item {
  display: flex; align-items: center; gap: 8px;
  font: inherit; font-size: 13px; text-align: left;
  min-height: 40px; padding: 0 10px; cursor: pointer;
  color: var(--ink, #1f2937); background: #fff;
  border: 1px solid var(--line, #e2e8f0); border-radius: 8px;
  transition: background-color .15s ease-out, border-color .15s ease-out;
}
.ind-cat-item:hover { border-color: var(--primary, #0e7c86); }
.ind-cat-item:active { transform: scale(.98); }
.ind-cat-item.on { background: #eef9fa; border-color: var(--primary, #0e7c86); box-shadow: inset 3px 0 0 var(--primary, #0e7c86); }
.ind-cat-item .swatch { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto; }
.ind-cat-item .ind-cat-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ind-cat-item .ind-cat-unit { color: var(--muted, #6b7a8f); font-size: 11.5px; flex: 0 0 auto; }
.ind-cat-item .ind-cat-tick { width: 14px; flex: 0 0 auto; color: var(--primary, #0e7c86); font-weight: 700; }
.ind-cat-foot { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
.ind-cat-sel { margin-right: auto; font-size: 12.5px; color: var(--muted, #6b7a8f);
  font-variant-numeric: tabular-nums; }
.ind-cat-sel.is-empty { opacity: .75; }
html[data-theme="dark"] .ind-cat-tabs { border-color: #2d3946; }
html[data-theme="dark"] .ind-cat-tab { background: #22303c; border-color: #3a4a5c; color: #e6edf3; }
html[data-theme="dark"] .ind-cat-tab.active { background: #2bb6c4; border-color: #2bb6c4; color: #0f1a20; }
html[data-theme="dark"] .ind-cat-item { background: #22303c; border-color: #3a4a5c; color: #e6edf3; }
html[data-theme="dark"] .ind-cat-item.on { background: #14313a; border-color: #2bb6c4; box-shadow: inset 3px 0 0 #2bb6c4; }
html[data-theme="dark"] .ind-cat-item .ind-cat-unit { color: #9aa6b2; }
@media (max-width: 640px) {
  .ind-cat-list { grid-template-columns: 1fr; max-height: min(42vh, 300px); }
}

/* ════════════════════════════════════════════════════════════════════════════
   🆕 v513（用户第 5 项 d）：卡片内部的「无数据」空态
   用户原话：「用药记录和日常记录中的窗口中没有数据的都把无数据的UI保留在窗口内，
             至少能看到有数据后的展示预期。」
   ⇒ 这两个页面里 7 处「无数据就 display:none」整块/整卡消失的地方，改为窗内渲染 .card-empty。
   ── 视觉 ──
     与既有 `.ct-empty`（自定义追踪项空态）/ `.sma-empty`（关联洞察空态）同一语言：
     浅底 + 虚线边 + 次要文字色，只是补了「描述 + 提示」两层结构。
   ⚠️ 数字一律 tabular-nums（UISKILL Critical Rule 5）—— 空态文案里带计数时会用到。
   ════════════════════════════════════════════════════════════════════════════ */
.card-empty {
  color: #6b7785; font-size: 13px; line-height: 1.65;
  font-variant-numeric: tabular-nums;
  padding: 12px 14px;
  background: #fafbfc; border: 1px dashed #e1e7ee; border-radius: 8px;
}
.card-empty .ce-desc { color: #4a5764; }
.card-empty .ce-desc b { color: #1f2d3d; }
.card-empty .ce-tip { display: block; margin-top: 5px; font-size: 12px; color: #8593a3; }
html[data-theme="dark"] .card-empty { background: #1a232e; border-color: #2c3a4c; color: #9fb0c3; }
html[data-theme="dark"] .card-empty .ce-desc { color: #b8c4d0; }
html[data-theme="dark"] .card-empty .ce-desc b { color: #e6edf3; }
html[data-theme="dark"] .card-empty .ce-tip { color: #8593a3; }

/* ════════════════════════════════════════════════════════════════════════════
   🆕 v516（用户 2026-10-15 十条 UI 改造）：用药周期带 / 常驻曲线 / 依从补打卡 /
   症状弹窗 / 添加测量弹窗 / 用药弹窗「颗数·频次」选择器 / 疫苗·过敏编辑 / 会员中心模式注记
   ════════════════════════════════════════════════════════════════════════════ */

/* ── ① 用药周期带图例（#med-cycles，第 4 条）── */
.mc-legend {
  display: flex; flex-wrap: wrap; gap: 6px 14px; align-items: center;
  margin: 0 0 8px; font-size: 12px; color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.mc-legend span { display: inline-flex; align-items: center; gap: 5px; }
.mc-legend i { display: inline-block; width: 10px; height: 10px; flex: 0 0 auto; }
#med-cycles { margin-top: 4px; }
#med-cycles svg { display: block; }

/* ── ② 今日用药 xxx 示例（第 4 条）── */
/* 🆕 v548（问题②）：示例行的 `.tm-acts` 是 position:absolute（top:6 right:8），
   原本只对 `.tm-list > .today-med` 那条才配套 `position:relative`（见 6839 行）；
   而「修改示例」这条示例行**不在** .tm-list 里 ⇒ 它的 .tm-acts 会一路逃到 .card
   右上角，正好压住卡头的 🌰 帮助图标（APK 示例模式实拍：🌰 下方叠着「修改示例」钮）。
   修法：给示例行补 position:relative + 右侧留白，让「修改示例」锚回示例行本行。 */
.today-med.med-example { border-style: dashed; position: relative; padding-right: 88px; }
.today-med.med-example .tm-name,
.today-med.med-example .tm-meta,
.today-med.med-example .tm-start { color: #8a97a6; }
.med-example-edit {
  min-height: 30px; padding: 4px 12px; font-size: 12.5px;
  border: 1px solid var(--line); border-radius: 999px;
  background: var(--panel); color: var(--primary); cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.med-example-edit:active { transform: scale(.96); }
.med-example-note { color: #8593a3; }
html[data-theme="dark"] .today-med.med-example .tm-name,
html[data-theme="dark"] .today-med.med-example .tm-meta,
html[data-theme="dark"] .today-med.med-example .tm-start { color: #7c8a99; }

/* ── ③ 依从日历补打卡（第 6 条）── */
.adh-view-toggle { display: inline-flex; gap: 4px; margin-bottom: 8px; }
.adh-vt {
  min-height: 30px; padding: 4px 14px; font-size: 12.5px; cursor: pointer;
  border: 1px solid var(--line); background: var(--panel); color: var(--muted);
}
.adh-vt:first-child { border-radius: 999px 0 0 999px; }
.adh-vt:last-child { border-radius: 0 999px 999px 0; }
.adh-vt.on { background: var(--primary); border-color: var(--primary); color: #fff; }
.adh-edit-tip {
  margin: 0 0 8px; padding: 7px 10px; font-size: 12px; line-height: 1.5;
  color: #2b5560; background: #eef8f9; border: 1px solid #cfe9ec; border-radius: 8px;
}
html[data-theme="dark"] .adh-edit-tip { color: #b9d6da; background: #12303a; border-color: #1f4d57; }
.adh-cell.picked { outline: 2px solid #1565c0; outline-offset: -2px; background: #e3edfb; }
html[data-theme="dark"] .adh-cell.picked { outline-color: #4dabf7; background: #1b2a40; }
/* 周视图：7 天 × 5 时段格子 */
.adh-week-grid { display: grid; grid-template-columns: 40px repeat(7, 1fr); gap: 3px; max-width: 420px; margin: 0 auto; }
.adh-week-corner { font-size: 10.5px; color: #8a97a6; align-self: center; text-align: center; }
.adh-week-d { text-align: center; font-size: 11px; color: #4a5563; padding: 2px 0; }
.adh-week-d.today { color: var(--primary); font-weight: 700; }
.adh-week-slotname { font-size: 11px; color: #8a97a6; align-self: center; text-align: center; }
.adh-slot-cell {
  min-height: 20px; border-radius: 4px; background: #f1f4f8; cursor: default;
}
.adh-slot-cell.taken { background: #2e9e5b; }
.adh-slot-cell.future { background: transparent; opacity: .45; }
.adh-slot-cell.picked { outline: 2px solid #1565c0; outline-offset: -2px; background: #e3edfb; }
.adh-slot-cell[data-adh-slot] { cursor: pointer; }
html[data-theme="dark"] .adh-week-d { color: #c7d0db; }
html[data-theme="dark"] .adh-week-d.today { color: #2bb6c4; }
html[data-theme="dark"] .adh-slot-cell { background: #222b35; }
html[data-theme="dark"] .adh-slot-cell.taken { background: #2e9e5b; }
html[data-theme="dark"] .adh-slot-cell.picked { outline-color: #4dabf7; background: #1b2a40; }
/* 补打卡操作区：药品多选 + 打卡按钮 */
.adh-actions { margin-top: 10px; padding-top: 10px; border-top: 1px dashed var(--line); }
.adh-drug-pick { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 10px; }
.adh-drug-btn {
  min-height: 40px; padding: 8px 10px; font-size: 13px; text-align: center;
  border: 1px solid var(--line); border-radius: 10px; background: var(--panel); color: var(--ink);
  cursor: pointer; -webkit-tap-highlight-color: transparent; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap;
}
.adh-drug-btn.on { background: #e6f3f5; border-color: var(--primary); color: var(--primary-d); font-weight: 600; }
.adh-drug-btn:active { transform: scale(.96); }
.adh-checkin-btn { width: 100%; min-height: 44px; }
html[data-theme="dark"] .adh-drug-btn { background: #1c242c; color: #e6edf3; }
html[data-theme="dark"] .adh-drug-btn.on { background: #14313a; border-color: #2bb6c4; color: #7fdde4; }
/* 提醒开关迁入依从日历（原 #card-med-reminder 无独立样式，此处补上） */
.reminder-toggle.adh-reminder {
  display: flex; align-items: center; gap: 8px; margin-top: 12px;
  padding: 9px 12px; font-size: 13px; color: var(--ink);
  background: var(--panel); border: 1px solid var(--line); border-radius: 10px; cursor: pointer;
}
.reminder-toggle.adh-reminder input[type="checkbox"] { width: 18px; height: 18px; cursor: pointer; accent-color: var(--primary); }

/* ── ④ 症状记录弹窗（第 8 条）── */
.symptom-pop { width: min(720px, 94vw); }
.symptom-pop .def-body { padding: 0; overflow: hidden; }
.symptom-body { display: flex; min-height: 0; }
.sym-left { flex: 1 1 52%; display: flex; flex-direction: column; gap: 10px; padding: 16px 18px 18px; overflow-y: auto; max-height: min(60vh, 480px); }
.sym-left .mf-box { display: flex; flex-direction: row; align-items: center; gap: 8px; padding: 0 10px; border: 1px solid var(--line); border-radius: 8px; background: var(--panel); }
.sym-left .mf-lb { flex: 0 0 auto; white-space: nowrap; color: var(--muted); font-size: 13px; }
.sym-left .mf-box > input, .sym-left .mf-box > select { flex: 1 1 auto; min-width: 0; padding: 8px 0; border: 0; background: none; font-size: 14px; color: var(--ink); }
.sym-left .mf-box:focus-within { border-color: var(--primary); }
.sym-left .mf-star { color: var(--danger); font-style: normal; }
.sym-save { min-height: 44px; }
.sym-right { flex: 1 1 48%; display: flex; flex-direction: column; border-left: 1px solid var(--line); background: #f8fafc; }
.sym-right-h { padding: 12px 14px 8px; font-size: 12px; color: var(--muted); border-bottom: 1px solid var(--line); }
.sym-cats { display: flex; flex-wrap: wrap; gap: 6px; padding: 10px 12px 6px; }
.sym-cat {
  min-height: 30px; padding: 4px 11px; font-size: 12px; cursor: pointer;
  border: 1px solid var(--line); border-radius: 999px; background: var(--panel); color: var(--muted);
}
.sym-cat.on { background: var(--primary); border-color: var(--primary); color: #fff; }
/* 🆕 v537（项7a）：常见症状列表默认收起（只显示部位页签），点部位后上滑展开成滚动窗；
   收起态 max-height:0 + overflow:hidden 让「保存症状」按钮不再被挤下屏（APK 小屏实测）。 */
.sym-list { display: flex; flex-wrap: wrap; align-content: flex-start; gap: 6px; padding: 0 12px; overflow: hidden; max-height: 0; opacity: 0; transition: max-height .24s ease, padding .24s ease, opacity .18s ease; }
.sym-list.open { max-height: 210px; overflow-y: auto; padding: 4px 12px 14px; opacity: 1; }
.sym-item {
  min-height: 32px; padding: 5px 12px; font-size: 13px; cursor: pointer;
  border: 1px solid var(--line); border-radius: 8px; background: var(--panel); color: var(--ink);
}
.sym-item:active { transform: scale(.96); }
html[data-theme="dark"] .sym-left .mf-box { background: #1c242c; }
html[data-theme="dark"] .sym-right { background: #161d24; border-left-color: #2d3946; }
html[data-theme="dark"] .sym-cat, html[data-theme="dark"] .sym-item { background: #1c242c; color: #c2ccd6; }
html[data-theme="dark"] .sym-cat.on { background: #2bb6c4; color: #0f1a20; }
@media (max-width: 640px) {
  .symptom-body { flex-direction: column; }
  .sym-right { border-left: 0; border-top: 1px solid var(--line); max-height: 44vh; overflow-y: auto; }
  .sym-left { max-height: none; }
}

/* ── ⑤ 添加测量弹窗（第 9 条）── */
.vitals-pop { width: min(480px, 94vw); }
.vitals-pop .def-body { padding: 16px 18px 18px; }
.vitals-pop .vitals-form { display: flex; flex-direction: column; gap: 10px; }
.vitals-pop .vitals-form .mf-box { display: flex; flex-direction: row; align-items: center; gap: 8px; padding: 0 10px; border: 1px solid var(--line); border-radius: 8px; background: var(--panel); }
.vitals-pop .vitals-form .mf-lb { flex: 0 0 auto; white-space: nowrap; color: var(--muted); font-size: 13px; }
.vitals-pop .vitals-form .mf-box > input, .vitals-pop .vitals-form .mf-box > select { flex: 1 1 auto; min-width: 0; padding: 8px 0; border: 0; background: none; font-size: 14px; color: var(--ink); }
.vitals-pop .vitals-form .mf-box:focus-within { border-color: var(--primary); }
.vitals-pop .vitals-form .mf-star { color: var(--danger); font-style: normal; }
.vitals-pop #vitals-add { min-height: 44px; }
html[data-theme="dark"] .vitals-pop .vitals-form .mf-box { background: #1c242c; }

/* ── ⑥ 日常测量常驻曲线（第 9 条，#vitals-charts）── */
.vitals-charts { display: flex; flex-direction: column; gap: 12px; margin: 4px 0 12px; }
.vc-block { background: var(--panel); border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px 8px; }
.vc-title { font-size: 13.5px; font-weight: 600; color: var(--ink); margin-bottom: 4px; display: flex; align-items: baseline; gap: 8px; }
.vc-last { font-size: 12.5px; font-weight: 700; color: var(--primary); font-variant-numeric: tabular-nums; }
.vc-none { font-size: 12px; font-weight: 400; color: var(--muted); }
.vc-empty { font-size: 12.5px; color: var(--muted); padding: 10px 0 6px; }
.vc-block svg { display: block; }
html[data-theme="dark"] .vc-block { background: #1c242c; }
html[data-theme="dark"] .vc-title { color: #e6edf3; }

/* ── 🆕 v530（需求 4 二次修正 → 四项新需求再改）：日常测量各窗口标题行操作钮 ──
   血压/心率/体温（#vitals-charts）与 血氧/体重/腰围/血糖（#vitals-list，v530 起常驻）
   七个窗口同一套 .vc-block 规格：标题行右端 ＋（查看明细弹窗）+ ❌（删除/隐藏窗口）；
   行内历史下拉（✏ + .vc-hist）已随四项新需求退役 —— 逐条修改/删除改由「测量明细」
   正方形滚动弹窗承载（.vc-hist-row 系列样式被该弹窗复用，见下方「四项新需求」段）。 */
.vc-title { align-items: center; }
.vc-name { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 🆕 v536（项6）：gap 6→14 —— ＋/❌ 的命中区经 ::after 外扩 7px（26→40px，UISKILL 最低命中标准），
   14px 间距恰好让两个 40px 命中区相切不重叠，杜绝「想点＋点到❌（误删窗口）」的误触。 */
.vc-acts { margin-left: auto; display: inline-flex; align-items: center; gap: 14px; flex: none; }
.vc-acts .btn.vc-add,
.vc-acts .btn.act-ico {
  width: 26px; height: 26px; min-width: 26px; min-height: 26px; padding: 0; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center; font-size: 15px; line-height: 1;
  position: relative;
}
/* 🆕 v536（项6）：视觉 26px 圆钮、命中区 40×40（inset -7px）——
   用户实测「心率窗的历史数据（查看明细）按钮点击没反应」：26px 命中区在手机上极易点偏，
   点空白 = 没反应、点偏到相邻 ❌ = 窗口被藏。UISKILL：命中区最低 40×40。 */
.vc-acts .btn.vc-add::after,
.vc-acts .btn.act-ico::after { content: ''; position: absolute; inset: -7px; border-radius: 50%; }
.vc-acts .btn.act-ico svg { width: 13px; height: 13px; }
.vc-count { flex: none; font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }
.vc-hist { margin-top: 8px; border-top: 1px dashed var(--line); padding-top: 4px; }
.vc-hist[hidden] { display: none; }
.vc-hist-list { max-height: 240px; overflow-y: auto; }
.vc-hist-row { display: flex; align-items: center; gap: 8px; padding: 5px 0; border-bottom: 1px dashed var(--line); font-size: 12.5px; }
.vc-hist-row:last-child { border-bottom: 0; }
.vh-date { flex: none; color: var(--muted); font-variant-numeric: tabular-nums; }
.vh-name { flex: none; color: var(--muted); }
.vh-val { flex: none; font-weight: 600; }
.vh-note { flex: 1 1 auto; min-width: 0; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.vc-hist-row .btn.act-ico { width: 22px; height: 22px; min-width: 22px; min-height: 22px; }
.vc-hist-row .btn.act-ico svg { width: 12px; height: 12px; }
.vh-del {
  flex: none; width: 22px; height: 22px; min-width: 22px; min-height: 22px; padding: 0;
  border: 1px solid var(--line); border-radius: 50%; background: var(--panel); color: var(--muted);
  font-size: 14px; line-height: 1; cursor: pointer; display: inline-flex; align-items: center; justify-content: center;
}
.vh-del:hover { color: #c0392b; border-color: rgba(192, 57, 43, .5); background: rgba(192, 57, 43, .08); }
html[data-theme="dark"] .vh-del { background: #1a2431; }
html[data-theme="dark"] .vh-del:hover { color: #e5736f; background: rgba(222, 82, 72, .12); }
.vc-hist-empty { color: var(--muted); font-size: 12.5px; padding: 6px 0 2px; }
/* 曲线窗三窗间距由 .vitals-charts 的 flex gap 提供；常驻列表窗相邻间距对齐同一节奏 */
#vitals-list .vc-block + .vc-block { margin-top: 12px; }

/* ── 🆕 v530（四项新需求）：日常测量对比窗 + 子窗 ❌/＋ + 明细弹窗 + 症状窗滚动 ── */
/* 子窗口标题行 ❌（删除窗口）：圆钮 ×，悬停转红，与 .vh-del 同款 */
.vc-acts .vc-del-win {
  width: 26px; height: 26px; min-width: 26px; min-height: 26px; padding: 0; border-radius: 50%;
  border: 1px solid var(--line); background: var(--panel); color: var(--muted);
  font-size: 15px; line-height: 1; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  position: relative;   /* 🆕 v536（项6）：::after 命中区外扩的定位锚 */
}
/* 🆕 v536（项6）：❌ 同样扩到 40×40 命中区（与 ＋ 一致，见上方 vc-add 注释） */
.vc-acts .vc-del-win::after { content: ''; position: absolute; inset: -7px; border-radius: 50%; }
.vc-acts .vc-del-win:hover { color: #c0392b; border-color: rgba(192, 57, 43, .5); background: rgba(192, 57, 43, .08); }
html[data-theme="dark"] .vc-acts .vc-del-win { background: #1a2431; }
html[data-theme="dark"] .vc-acts .vc-del-win:hover { color: #e5736f; background: rgba(222, 82, 72, .12); }

/* 全部测量对比窗口：图表高度固定，空态居中提示 */
.vitals-compare { margin: 2px 0 12px; }
.vitals-compare .vc-title { margin-bottom: 6px; }
.vc-compare-chart { height: 240px; }
.vc-compare-empty { height: 240px; display: flex; align-items: center; justify-content: center; color: var(--muted); font-size: 12.5px; }

/* 测量明细弹窗：高 = 宽（正方形滚动窗），右上 ❌ 复用 .def-close */
.vc-detail-pop { width: min(420px, 92vw); aspect-ratio: 1 / 1; max-height: min(86vh, 640px); }
.vc-detail-pop .def-body { padding: 12px 14px; overflow-y: auto; }
.vc-detail-body .vc-hist-list { max-height: none; }
.vc-detail-body .vc-hist-empty { color: var(--muted); font-size: 12.5px; padding: 6px 0 2px; }

/* ── 🆕 v532（用户需求 4）：曲线窗 ECharts 容器 + 明细内联编辑区 + 复选窗口 ── */
/* 曲线窗（血压/心率/体温）由 SVG polyline 改 ECharts smooth 弧形曲线（与指标趋势主图同款），高 150px */
.vc-echart { width: 100%; height: 150px; }

/* 测量明细弹窗内的「内联编辑区」—— 直接铺在历史记录之上（v532 起不再设独立「＋ 添加测量」按钮） */
.vc-edit-form {
  display: flex; flex-direction: column; gap: 8px;
  padding: 10px; margin: 2px 0 10px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
}
.vde-row { display: flex; align-items: center; gap: 8px; }
.vde-row label { flex: 0 0 42px; font-size: 12.5px; color: var(--muted); white-space: nowrap; }
.vde-row input, .vde-row select {
  flex: 1 1 auto; min-width: 0; padding: 7px 9px; font-size: 14px; color: var(--ink);
  border: 1px solid var(--line); border-radius: 8px; background: var(--panel);
}
.vde-row input:focus, .vde-row select:focus { outline: none; border-color: var(--primary); }
.vde-type-fixed { flex: 1 1 auto; min-width: 0; font-size: 13.5px; font-weight: 600; color: var(--ink); }
/* 🆕 v537（项6b）：血压明细弹窗 —— 数值拆左右两个输入框（收缩压 / 舒张压），中间「/」分隔 */
.vde-bp-pair { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 6px; }
.vde-bp-pair input { flex: 1 1 0; min-width: 0; }
.vde-bp-sep { flex: none; font-size: 14px; color: var(--muted); font-weight: 600; }
.vde-actions { display: flex; align-items: center; gap: 10px; }
.vde-actions #vitals-detail-save { min-height: 34px; padding: 0 16px; }
.vde-mode { font-size: 12px; color: var(--muted); }
#vde-cancel { font-size: 12.5px; color: var(--muted); text-decoration: underline; text-underline-offset: 2px; cursor: pointer; }
#vde-cancel:hover { color: var(--primary); }
html[data-theme="dark"] .vc-edit-form { background: #1c242c; }

/* 明细弹窗内「历史记录」分节标题 */
.vc-hist-head { font-size: 13px; font-weight: 700; color: var(--ink); margin: 8px 0 6px; }
html[data-theme="dark"] .vc-hist-head { color: #e6edf3; }

/* 「添加测量窗口」复选弹窗：7 个测量窗口作复选按钮（已显示 = 勾选） */
.vc-win-pop { width: min(360px, 90vw); }
.vc-win-pop .def-body { padding: 14px 16px 16px; }
.vw-body { display: flex; flex-direction: column; gap: 8px; }
.vw-item {
  display: flex; align-items: center; gap: 10px; padding: 10px 12px;
  border: 1px solid var(--line); border-radius: 10px; background: var(--panel); cursor: pointer;
  transition: border-color .15s ease;
}
.vw-item:hover { border-color: var(--primary); }
.vw-cb { flex: none; width: 18px; height: 18px; accent-color: var(--primary); cursor: pointer; }
.vw-name { font-size: 14px; color: var(--ink); }
.vw-actions { padding: 12px 0 0; }
.vw-actions .btn { width: 100%; min-height: 42px; }
html[data-theme="dark"] .vw-item { background: #1c242c; }
html[data-theme="dark"] .vw-name { color: #e6edf3; }

/* 🆕 v531（用户需求 1）：v530 把「事件列表+热力图+部位图+关联洞察」整体收进 .event-scroll 固定高
   滚动容器，用户要求**窗口恢复原高度**、只把「加号添加的症状条目」（#event-list）做成滚动窗口
   ⇒ 外层包裹已在 index.html 拆除，滚动改挂在 #event-list 自身（高度沿用原 260px 口径）。 */
#event-list { max-height: 260px; overflow-y: auto; overscroll-behavior: contain; padding-right: 2px; }

/* ── ⑦ 用药弹窗「颗数·频次」选择器 + 必填标注（第 4 条）── */
.med-form .mf-box.mf-req .mf-lb { color: var(--ink); font-weight: 500; }
.med-form .mf-star { color: var(--danger); font-style: normal; margin-left: 2px; }
.med-form .mf-half-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; grid-column: 1 / -1; }
.med-form .mf-picker {
  flex: 1 1 auto; min-width: 0; min-height: 32px; padding: 6px 10px; text-align: left;
  font-size: 14px; color: var(--ink); background: none; border: 0; border-radius: 0; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.med-form .mf-picker .mf-picker-txt { color: var(--muted); }
.med-form .mf-picker .mf-picker-txt:not(:empty) { color: var(--ink); }
.mf-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.mf-req-note { font-size: 12px; color: var(--muted); margin-right: auto; }
.mf-req-note .mf-star { color: var(--danger); font-style: normal; }
.mf-foot-btns { display: flex; gap: 8px; }
/* 颗数 / 频次弹窗 */
.med-picker-pop { width: min(340px, 90vw); }
.med-picker-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; padding: 16px 18px 20px; }
.mf-pill {
  min-height: 44px; padding: 8px 6px; font-size: 14px; text-align: center;
  border: 1px solid var(--line); border-radius: 10px; background: var(--panel); color: var(--ink);
  cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.mf-pill:active { transform: scale(.96); }
html[data-theme="dark"] .med-form .mf-picker { color: #e6edf3; }
html[data-theme="dark"] .mf-pill { background: #1c242c; color: #e6edf3; }
@media (max-width: 640px) { .med-form .mf-half-row { grid-template-columns: 1fr; } .med-picker-grid { grid-template-columns: repeat(2, 1fr); } }

/* ── ⑧ 疫苗 / 过敏记录：行内编辑 + 删除（第 10 条）── */
.vx-acts, .al-acts { display: inline-flex; gap: 6px; align-items: center; flex: 0 0 auto; }
.vaccine-row, .allergy-row { display: flex; align-items: flex-start; gap: 8px; }

/* ── ⑨ 会员中心模式注记（第 2 条）── */
.billing-mode-note { color: var(--muted); font-size: 12.5px; }
.billing-mode-note::before { content: ''; }
html[data-theme="dark"] .billing-mode-note { color: #9aa6b2; }

/* ════════════════════════════════════════════════════════════════════════════
   🆕 v517（用户 2026-10-15 六条 UI 改造）：趋势概览「恢复正常」入需关注 + 较上次前小曲线 /
   指标库五段计数条可点重选（共N项同行）+ APK 隐藏目标列 + 「新增」标注 / 页眉「添加指标·按分类选择」按钮 /
   症状部位热力图迁入症状记录窗口 / 指标分析「恢复正常」与常见原因排版 / 用药周期图 y 轴分类名+总数
   ════════════════════════════════════════════════════════════════════════════ */

/* ── ① 趋势概览「恢复正常」行 + 「较上次」前迷你曲线（需求 1）── */
.alert-item.sev-back { background: #eaf6f7; border-color: #bfe3e5; border-left-color: #0e7c86; }
html[data-theme="dark"] .alert-item.sev-back { background: #16282a; border-color: #2a5053; border-left-color: #1aa7b1; }
.alert-tag.back { background: #dceff0; color: #0e7c86; }
html[data-theme="dark"] .alert-tag.back { background: #16282a; color: #3fc1cb; }
.alert-spark { display: inline-flex; align-items: center; flex: 0 0 auto; }
.alert-spark .spark-svg { display: block; }
.alert-spark .spark-na { font-size: 11px; }

/* ── ② 指标库五段计数条：共N项与四档同行，窄屏允许换行不横向溢出（需求 1/2）── */
.ind-abn-pill { flex-wrap: wrap; row-gap: 2px; }

/* ── ③ 指标库：APK 隐藏「目标」列（数据不删，网页/exe 不变，需求 2）──
      🆕 v518（用户第 6 项）：列序加「最新值」后，目标列从第 4 列变**第 5 列**。 */
.apk-no-target th:nth-child(5),
.apk-no-target td:nth-child(5) { display: none; }

/* ── ④ 指标库「新增」标注（跨分类勾选后追加到当前清单，需求 3）── */
.ind-new-badge {
  display: inline-block; margin-left: 6px; padding: 0 6px;
  font-size: 10.5px; font-weight: 600; line-height: 16px;
  color: #0e7c86; background: #dceff0; border-radius: 999px;
  vertical-align: middle; white-space: nowrap;
}
html[data-theme="dark"] .ind-new-badge { color: #3fc1cb; background: #16282a; }

/* ── ⑥ 症状部位热力图：迁入「症状记录」窗口后的分节块样式（需求 4）── */
.symptom-bodymap { margin-top: 12px; padding-top: 10px; border-top: 1px dashed #e5ebf3; }
.symptom-bodymap > .card-head { margin: 0 0 4px; }
.symptom-bodymap > .card-head > h3 { font-size: 15px; margin: 0; color: #1f2d3d; }
html[data-theme="dark"] .symptom-bodymap { border-top-color: #2d3946; }
html[data-theme="dark"] .symptom-bodymap > .card-head > h3 { color: #e6edf3; }
/* 迁入后正文文字按主题配色（v469 把 .bm-detail li 写死浅灰 #d7e2e8，日间主题下不可读） */
.bm-detail li { color: #2a3542; }
html[data-theme="dark"] .bm-detail li { color: #d7e2e8; }
.bm-li:hover { background: rgba(0,0,0,0.04); }
html[data-theme="dark"] .bm-li:hover { background: rgba(255,255,255,.05); }

/* ════════════════════════════════════════════════════════════════
   🆕 v525（需求11）：用户「指标库中指标窗口的编辑按钮比旁边两个按钮都高，要调整成一致」。
   实测（390×844，真页面）：三个按钮盒子都是 20×20（不是尺寸差），但 top 坐标分别为
     `.act-edit` 602 （y→下一行 671.5）
     `.act-del`  604（→ 673.5）、`.ind-def-q-lib` 604（→ 673.5）
   ⇒ **铅笔整体上浮 2px**。根因：三个都是 `display:inline-flex` 且 `vertical-align:baseline`，
   而 inline-flex 的基线取「第一个 flex 子项的基线」——铅笔里是 `.act-ico svg{display:block}`
   （块级元素没有文本基线 ⇒ 用其**底边**当基线），而 × / ? 是 15~16px 字形（基线在字面内偏下）
   ⇒ 同一条基线上，铅笔的 20px 盒子自然比另两个高 2px。
   修法：该行三个图标统一 `vertical-align: middle`（按**行盒中线**对齐，不再受基线差异影响）。
   ℹ️ 只限 `#indicator-list`（用户只报了这一处，不擅自改其他表格）。
   ════════════════════════════════════════════════════════════════ */
#indicator-list .row-actions > * { vertical-align: middle; }
/* 🆕 v537（需求4）：指标识别结果窗口的 ❌（文字字形基线）比铅笔/上下移动（SVG、块级基线）低 2px。
   根因与 v525 指标库同一处：inline-flex 基线取「首个 flex 子项基线」，文字 × 取字面内偏下基线、
   SVG 块级取底边基线 ⇒ 同一条基线 × 整体下沉。修法同 v525：该行四钮统一按行盒中线对齐。 */
.entry-result .scan-table .scan-actions > *,
.entry-ind-win .scan-actions > * { vertical-align: middle; }

/* ════════════════════════════════════════════════════════════════
   🆕 v531（2026-10-21 用户 5 项需求）样式段
   ────────────────────────────────────────────────────────────────
   ① 事件与症状记录恢复原高度（滚动只挂 #event-list —— 已写在 .event-scroll 原位）；
   ② 测量值趋势（原全部测量对比）双 y 轴 + 日期粒度（ECharts option 在 JS 内，无 CSS）；
   ③ 测量明细弹窗「＋ 添加测量」操作条；
   ④ 每日健康打卡热力格可点击（.dc-cur 编辑中高亮 + .dc-edit-bar 日期条）；
   ⑤ 会员中心按 mastergo「CaseManager-Member」画布：渐变订阅卡 .bv-sub-card /
      会员权益卡 .bf-* / 自动续费自绘开关 .rn-switch / 滚动高亮 .bv-flash。
   ⚠️ 暗色主题全部单独覆盖（html[data-theme="dark"]，本仓库铁律）。
   ════════════════════════════════════════════════════════════════ */

/* ── ③ 测量明细弹窗：添加操作条 ── */
.vc-detail-add { margin: 2px 0 8px; padding-bottom: 8px; border-bottom: 1px dashed #e5ebf3; }
.vc-detail-add .btn { min-width: 96px; }
html[data-theme="dark"] .vc-detail-add { border-bottom-color: #2d3946; }

/* ── ④ 每日健康打卡：热力格可点击 ── */
.dc-heat .dc-cell { cursor: pointer; }
.dc-heat .dc-cell:hover { transform: scale(1.25); box-shadow: 0 0 0 1px rgba(14,124,134,.5); }
.dc-heat .dc-cell.dc-cur { box-shadow: 0 0 0 2px #0e7c86; }
html[data-theme="dark"] .dc-heat .dc-cell.dc-cur { box-shadow: 0 0 0 2px #3fc1cb; }
.dc-edit-bar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; background: #fdf6e7;
  border: 1px solid #f0e0bb; border-radius: 8px; padding: 6px 10px; margin: 0 0 8px; font-size: 12px; color: #7a5b16; }
.dc-edit-bar a { color: #0e7c86; font-weight: 600; text-decoration: none; }
html[data-theme="dark"] .dc-edit-bar { background: #2b2416; border-color: #4a3d1f; color: #e8c877; }
html[data-theme="dark"] .dc-edit-bar a { color: #3fc1cb; }

/* ── ⑤a 渐变订阅卡（mastergo card-subscription）── */
.bv-sub-card { display: flex; flex-direction: column; gap: 12px; padding: 16px 18px; margin: 12px 0;
  background: linear-gradient(111deg, #0E7C86 0%, #1AA7B1 100%); border-radius: 14px;
  box-shadow: 0 10px 28px rgba(14,124,134,.28); color: #fff; }
.bv-sub-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 8px; }
.bv-sub-plan { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.bv-sub-label { font-size: 11px; color: rgba(255,255,255,.8); }
.bv-sub-name { font-size: 22px; font-weight: 700; line-height: 28px; color: #fff; }
.bv-auto-pill { flex: 0 0 auto; font-size: 10px; line-height: 14px; padding: 3px 9px;
  background: rgba(255,255,255,.18); border-radius: 999px; color: #fff; white-space: nowrap; }
.bv-sub-price-row { display: flex; align-items: flex-end; justify-content: space-between; gap: 8px; flex-wrap: wrap; }
.bv-sub-amount { font-size: 26px; font-weight: 700; line-height: 32px; color: #fff; }
.bv-sub-amount small { font-size: 12px; font-weight: 400; color: rgba(255,255,255,.8); }
.bv-sub-old { color: rgba(255,255,255,.65); font-size: 12px; }
.bv-sub-tag { background: rgba(255,255,255,.2); color: #fff; font-size: 10px; padding: 2px 8px; border-radius: 999px; }
.bv-sub-invite { color: rgba(255,255,255,.85); font-size: 10.5px; }
.bv-sub-valid { display: flex; align-items: center; gap: 6px; background: rgba(255,255,255,.12);
  border-radius: 10px; padding: 8px 12px; font-size: 11.5px; line-height: 16px; color: #fff; }
.bv-sub-actions { display: flex; gap: 10px; }
.bv-btn-white { flex: 1 1 0; min-width: 0; background: #fff; color: #0E7C86; border: none;
  border-radius: 10px; padding: 10px 0; font-size: 12.5px; font-weight: 700; cursor: pointer; }
.bv-btn-ghost { flex: 1 1 0; min-width: 0; background: rgba(255,255,255,.12); color: #fff;
  border: 1px solid rgba(255,255,255,.4); border-radius: 10px; padding: 10px 0; font-size: 12.5px; cursor: pointer; }
.bv-btn-white:active { transform: translateY(1px); }
.bv-btn-ghost:active { transform: translateY(1px); }
/* 「立即续费 / 管理订阅」滚动定位后的目标高亮 */
@keyframes bv-flash-kf { 0%,100% { box-shadow: 0 0 0 0 rgba(14,124,134,0); } 40% { box-shadow: 0 0 0 4px rgba(14,124,134,.45); } }
.bv-flash { animation: bv-flash-kf 1.3s ease 1; border-radius: 10px; }

/* ── ⑤b 会员权益卡（mastergo card-benefits）── */
.bf-count { color: #8a98a8; font-size: 11px; }
.bf-rows { display: flex; flex-direction: column; gap: 12px; margin-top: 10px; }
.bf-row { display: flex; align-items: center; gap: 10px; }
.bf-ico { flex: 0 0 auto; width: 30px; height: 30px; display: flex; align-items: center; justify-content: center;
  font-size: 14px; border-radius: 30px; }
.bf-i1 { background: #e3f1f3; } .bf-i2 { background: #e7f0fa; } .bf-i3 { background: #fcf2de; } .bf-i4 { background: #eaf3ec; }
.bf-txt { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.bf-txt b { font-size: 12.5px; line-height: 17px; color: var(--ink, #1f2d3d); font-weight: 600; }
.bf-txt span { font-size: 10.5px; line-height: 15px; color: #8a98a8; }
.bf-check { flex: 0 0 auto; color: #2e9e62; font-size: 13px; font-weight: 700; }
html[data-theme="dark"] .bf-i1 { background: #16303a; }
html[data-theme="dark"] .bf-i2 { background: #16283a; }
html[data-theme="dark"] .bf-i3 { background: #33270f; }
html[data-theme="dark"] .bf-i4 { background: #14291b; }
html[data-theme="dark"] .bf-txt b { color: #e6edf3; }
html[data-theme="dark"] .bf-txt span { color: #8a98a8; }
html[data-theme="dark"] .bf-check { color: #46b97c; }

/* ── ⑤c 自动续费行（mastergo renew-auto-row + 自绘开关）── */
.rn-auto-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin: 12px 0 0; }
.rn-auto-info { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.rn-auto-info b { font-size: 12.5px; line-height: 17px; color: var(--ink, #1f2d3d); font-weight: 600; }
.rn-auto-info span { font-size: 10.5px; line-height: 15px; color: var(--muted, #8a98a8); }
.rn-switch { position: relative; flex: 0 0 auto; width: 46px; height: 26px; display: inline-block; cursor: pointer; }
.rn-switch input { position: absolute; z-index: 2; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.rn-knob { position: absolute; inset: 0; background: #c3cdd8; border-radius: 999px; transition: background .2s; }
.rn-knob::after { content: ''; position: absolute; top: 3px; left: 3px; width: 20px; height: 20px;
  background: #fff; border-radius: 50%; box-shadow: 0 1px 3px rgba(0,0,0,.2); transition: left .2s; }
.rn-switch input:checked + .rn-knob { background: #0e7c86; }
.rn-switch input:checked + .rn-knob::after { left: 23px; }
html[data-theme="dark"] .rn-knob { background: #3a4757; }
html[data-theme="dark"] .rn-switch input:checked + .rn-knob { background: #1aa7b1; }
html[data-theme="dark"] .rn-auto-info b { color: #e6edf3; }

/* ══════════ 🆕 v534（2026-10-22 用户 8 组需求） ══════════ */

/* ── 需求 3①：「会员权益」从独立卡搬进「账号与订阅」卡内（#billing-view 下方）—— 卡中卡嵌套样式 ── */
.benef-nest {
  margin-top: 12px;
  padding: 12px 14px 14px;
  border: 1px solid var(--line, #dfe6ee);
  border-radius: 12px;
  background: var(--card-soft, rgba(26, 167, 177, .045));
}
.benef-nest .card-head { margin-bottom: 2px; }
.benef-nest .card-head h2 { font-size: 14.5px; }
.benef-nest .bf-count { font-size: 11.5px; color: var(--muted, #8593a3); margin-left: 6px; }
.benef-nest .bf-rows { margin-top: 8px; }
.benef-nest .bf-row .bf-ico { width: 30px; height: 30px; font-size: 15px; }
.benef-nest .bf-row .bf-txt b { font-size: 13px; }
.benef-nest .bf-row .bf-txt span { font-size: 11.5px; }
html[data-theme="dark"] .benef-nest { background: rgba(26, 167, 177, .07); border-color: #2c3744; }

/* ── 需求 3②：「订阅 / 邀请记录」改固定高度滚动窗（与其他滚动窗口同高 260px 口径） ── */
.bv-history {
  margin-top: 12px;
  max-height: 260px; overflow-y: auto; overscroll-behavior: contain;
  padding-right: 2px;
}

/* ── 需求 3④：备份文件位置按钮行（复用 .bm-btn；行上边距与 bm-tip 拉开） ── */
.bm-bak-acts { margin-top: 8px; }

/* ── 需求 4②：「添加测量窗口」弹窗底部的「其他（自定义类型）」可编辑块 ── */
.vw-custom-block {
  border-top: 1px dashed var(--line, #dfe6ee);
  padding-top: 8px; margin-top: 2px;
  display: flex; flex-direction: column; gap: 6px;
}
.vw-custom-item .vw-name { color: var(--primary, #0e7c86); font-weight: 600; }
.vw-custom-row { display: flex; gap: 8px; padding-left: 30px; }
.vw-custom-row input {
  flex: 1 1 50%; min-width: 0;
  padding: 8px 10px; border: 1px solid var(--line, #dfe6ee); border-radius: 8px;
  font-size: 13px; background: var(--card, #fff); color: var(--ink, #1f2d3d);
}
.vw-custom-row input:focus { outline: none; border-color: var(--primary); }
html[data-theme="dark"] .vw-custom-row input { background: #1c242c; border-color: #2c3744; color: #e6edf3; }

/* ── 需求 6：症状关联等 4 个洞察窗 —— 标题（.ic-head）冻结在滚动区顶部，内容从标题下滚过 ──
   （窗体本身 v533 起就是 max-height:260px + overflow-y:auto；sticky 让标题不随内容滚走） */
.symptom-med-assoc > .ic-head,
.symptom-ind-correlation > .ic-head,
.symptom-vital-correlation > .ic-head,
.checkin-symptom-correlation > .ic-head {
  position: sticky; top: 0; z-index: 2;
  background: inherit;            /* 继承窗体底色（含暗色主题各配色），滚动内容从其下穿过 */
  margin: 0; padding: 4px 0 6px;
}
html[data-theme="dark"] .symptom-med-assoc > .ic-head,
html[data-theme="dark"] .symptom-ind-correlation > .ic-head,
html[data-theme="dark"] .symptom-vital-correlation > .ic-head,
html[data-theme="dark"] .checkin-symptom-correlation > .ic-head { background: inherit; }

/* ── 需求 7②：患者窗口右上角「编辑 + 当前」行 —— 此前 .pw-top/.pw-badge 完全无 CSS（裸元素）；
      编辑钮已挂 .act-ico.act-edit（全站同款笔形钮），这里只补两件套的排布与「当前」徽标样式。
      ⚠️ .pw-top 是绝对定位 ⇒ .patient-window 必须是定位祖先（补 relative，双端生效）。 */
.patient-window { position: relative; }
.pw-top { display: flex; align-items: center; gap: 6px; position: absolute; top: 8px; right: 10px; }
.pw-badge {
  font-size: 11px; line-height: 1; padding: 4px 8px; border-radius: 999px;
  background: var(--primary, #0e7c86); color: #fff; font-weight: 600;
}
html[data-theme="dark"] .pw-badge { background: #1aa7b1; }
.pw-edit.is-on { background: rgba(14, 124, 134, .14); }
html[data-theme="dark"] .pw-edit.is-on { background: rgba(26, 167, 177, .2); }

/* ── 需求 8：「检查更新升级版本 + 检查并修正历史错值」左右排列（等分一行） ── */
.bm-acts-duo .bm-btn { flex: 1 1 0; min-width: 0; white-space: nowrap; }

/* ── 🆕 v536（项5）：合规按钮列（用户服务协议 / 隐私政策 / 退款与客服 / 重新查看同意弹窗）。
     🆕 v537（项10）：用户要求「一行 2 个按钮、行间距一致」—— 由竖排改 2×2 网格，
     与上方 .bm-acts-duo 同一行距（gap 8px），按钮左对齐。 ── */
.bm-acts-col { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.bm-acts-col .bm-btn { flex: 1 1 auto; text-align: left; }

/* ══════════════════════════════════════════════════════════════════════════════
   🆕 v560（用户 2026-10-28 第 2 项）：首页「功能介绍」
   —— 六张卡取代原来的六个「页面样子」窗口：视频 + 定位句（高度）+ 说明（深度）+ 一句对人的理解（温度）。
   ── 版式 ──
     · 窄屏：单列，卡内自上而下 [标题][视频 16:9][定位句][正文][进入 ›]；
     · ≥720px：每张卡内部左右两栏 [视频 300px | 文字]，标题横跨整行（grid-template-areas 实现，
       不额外加包裹节点 —— 卡片结构必须与 js 的 click 委托 / 徽标写入保持一致）。
   ── 反模式自查（UISKILL）──
     · 无霓虹色、无 AI 紫粉渐变、无 emoji 当唯一语义（emoji 只做点缀，标题始终有文字）；
     · 正文对比度：--muted 在浅底约 4.9:1、深底约 5.4:1（≥4.5:1）；
     · 正文不做截断（弹性文本）：不用 -webkit-line-clamp，窄屏自然换行；
     · 动效只做 transform/opacity，且尊重 prefers-reduced-motion。 */
.hf-title {
  margin: 18px 2px 4px; font-size: 17px; font-weight: 700; letter-spacing: .3px; color: var(--ink);
}
.hf-sub { margin: 0 2px 14px; font-size: 12.5px; line-height: 1.7; color: var(--muted); }
.hf-demo {
  margin: 14px 2px 2px; padding: 10px 12px; font-size: 12px; line-height: 1.7; color: var(--muted);
  background: rgba(14, 124, 134, .06); border: 1px dashed rgba(14, 124, 134, .28); border-radius: 10px;
}
.hf-demo b { color: var(--ink); font-weight: 600; }
html[data-theme="dark"] .hf-demo { background: rgba(95, 208, 219, .07); border-color: rgba(95, 208, 219, .26); }

/* 六张介绍卡：**单列**（原来 .home-grid 是 2 列，介绍文案在 2 列里会挤成窄条） */
.hf-grid { grid-template-columns: 1fr; gap: 14px; }
.hf-card {
  display: grid; grid-template-columns: 1fr;
  grid-template-areas: "head" "vid" "lead" "body" "foot";
  row-gap: 8px; padding: 12px 13px 13px;
}
.hf-card .hw-head { grid-area: head; font-size: 15px; }
.hf-card .hf-vid  { grid-area: vid; }
.hf-card .hf-lead { grid-area: lead; }
.hf-card .hf-body { grid-area: body; }
.hf-card .hw-foot { grid-area: foot; padding-top: 2px; font-weight: 600; color: var(--primary); }
@media (min-width: 720px) {
  .hf-card {
    grid-template-columns: 300px minmax(0, 1fr); column-gap: 16px; row-gap: 6px;
    grid-template-areas: "head head" "vid lead" "vid body" "vid foot";
    align-items: start;
  }
  .hf-card .hf-lead { padding-top: 2px; }
}
/* 视频盒：老 WebView（雷电 Chrome/91）没有 aspect-ratio ⇒ 一律用 padding-bottom 撑比例盒 */
.hf-vid {
  position: relative; display: block; width: 100%; height: 0; padding-bottom: 56.25%;
  border-radius: 10px; overflow: hidden; border: 1px solid var(--line);
  background: linear-gradient(135deg, rgba(14, 124, 134, .12), rgba(51, 188, 196, .05));
}
.hf-vid > video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
/* 视频缺失 / 加载失败（JS 摘掉 .has-vid）时的兜底：不留白框，改显品牌图标水印 */
.hf-vid:not(.has-vid) > video { display: none; }
.hf-vidmark {
  position: absolute; inset: 0; display: block; background: url(../assets/brand/icon-mark.png) center/34% no-repeat;
  opacity: .38; pointer-events: none;
}
/* 视频开播后它自然被盖住（video 在 DOM 里更靠前 ⇒ 这里靠 z-index 保证「视频在上、水印在下」） */
.hf-vid > video { z-index: 1; }
.hf-vid:not(.has-vid) > .hf-vidmark { opacity: .55; }
.hf-lead { font-size: 14.5px; font-weight: 700; line-height: 1.5; color: var(--ink); }
.hf-body { font-size: 13px; line-height: 1.78; color: var(--muted); }
.hf-body b { color: var(--ink); font-weight: 600; }
html[data-theme="dark"] .hf-body b { color: #e6edf3; }
@media (prefers-reduced-motion: reduce) {
  .home-win.hf-card, .home-win.hf-card:hover, .home-win.hf-card:active { transform: none; }
}

/* ══════════════════════════════════════════════════════════════════════════════
   🆕 v578（用户 2026-11-01 第 2 项）：首页「商标背景墙」整层删除
   —— 用户原话：「网页版的商标背景墙删掉，看不到全貌而且显得凌乱。」
   ── 删的是什么 ──
     v560 那层 `#panel-home::before`：把 `icon-mark-soft.png` 按 160px（窄屏 126px）**平铺**
     出来的品牌水印底纹。问题正是用户说的「看不到全貌」——首页能被看见的只有几条窄缝
     （标题带、卡片间距、页脚），每一枚标记都被卡片切掉大半，露出的那一截读起来是「残图」，
     不像底纹。v560 当时是靠「缩小格子」缓解的，没有解决「被卡片切割」这个根因。
   ── 保留什么 ──
     `#panel-home::after` 的两团径向柔光**保留**：它不是图案、没有硬边，只给浅底加一点深度，
     暗色主题下同样淡。哪天也嫌它多余，删这一段即可，不影响任何布局（纯装饰层）。
   ⚠️ `assets/brand/icon-mark-soft.png` 文件保留但**不再被引用**（`icon-mark.png` 仍供
      `.hf-vidmark` 视频兜底水印与页眉 logo 使用，别一起删）。
   ⚠️ 只作用于首页：`#panel-home` 这个 id 在其余 5 个页签上不存在。
   ══════════════════════════════════════════════════════════════════════════════ */
#panel-home { position: relative; isolation: isolate; }
#panel-home::after {
  content: ''; position: absolute; inset: -8px -4px 0; z-index: -1; pointer-events: none;
  background:
    radial-gradient(680px 340px at 12% -6%, rgba(14, 124, 134, .12), transparent 70%),
    radial-gradient(520px 300px at 92% 4%, rgba(51, 188, 196, .12), transparent 72%);
}
html[data-theme="dark"] #panel-home::after {
  background:
    radial-gradient(680px 340px at 12% -6%, rgba(18, 160, 170, .20), transparent 70%),
    radial-gradient(520px 300px at 92% 4%, rgba(51, 188, 196, .14), transparent 72%);
}

/* ══════════════════════════════════════════════════════════════════════════════
   🆕 v561（用户 2026-10-28）：手机版首页 = 上一版「2 列 × 3 行 = 6 个视频窗口」
   —— 用户原话：「手机版用上一版 2列*3行=6个视频窗口的那一版，不用另外加文字提示。」
   ── 做法 ──
     · 桌面（≥641px）保持 v560 的单列长卡（视频在左、定位句+正文在右），文案完整；
     · 窄屏恢复 `.home-grid` 原本的 2 列，6 张卡正好排成 2×3；
     · 窄屏**只留「标题 + 视频窗」**，`.hf-lead`（定位句）/ `.hf-body`（正文）/ `.hw-foot`
       （进入…›）全部 `display:none` —— 这就是「不用另外加文字提示」。
       卡本身是 `<button data-goto>`，文字隐掉不影响点击跳转，也不会掉无障碍名称
       （`aria-label` 仍在）。
   ⚠️ 必须放在文件末尾：`.home-grid`(3386 行) 与 `.hf-grid`(7741 行) 特异度相同，
      靠先后顺序决出赢家；媒体查询里的 `.hf-grid` 也要在两者之后才压得住。
   ⚠️ 不要用 `grid-template-columns: repeat(2, ...)` 写在 `.hf-grid` 主规则里 ——
      那会把桌面版也变成 2 列，正文立刻挤成窄条（v560 就是这么改掉的）。
   ══════════════════════════════════════════════════════════════════════════════ */
@media (max-width: 640px) {
  .hf-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .hf-card { padding: 8px 8px 9px; row-gap: 6px; }
  .hf-card .hw-head { font-size: 12.5px; gap: 4px; }
  .hf-card .hw-ico { font-size: 13px; }
  .hf-card .hw-badge { font-size: 9.5px; padding: 0 5px; }
  .hf-card .hw-badge .hb-lb { font-size: 9px; }
  .hf-card .hf-body,
  .hf-card .hw-foot { display: none; }
  /* 🆕 v564（用户第 9 项）：「原来每个窗口下面的小字介绍要恢复」——
     恢复一行定位句（.hf-lead），正文 .hf-body 仍收起：2 列窄卡里正文会挤成一堵字墙。
     最多两行，超出截断，保证 6 张卡高度整齐。 */
  .hf-card .hf-lead {
    display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
    overflow: hidden; font-size: 11.5px; font-weight: 600; line-height: 1.45;
    color: var(--muted); padding: 0 1px;
  }
  /* 面板上的说明文字也一并收起（用户：「不用另外加文字提示」）——
     手机上只剩「功能介绍」标题 + 6 个视频窗口，点哪张进哪页。 */
  .hf-sub,
  .hf-demo,
  .hf-grid ~ .hint { display: none; }
  /* 只剩标题条 + 视频窗，视频窗贴满卡片下沿，圆角跟卡片内缘对齐 */
  .hf-card .hf-vid { border-radius: 9px; }
}


/* ══════════════════════════════════════════════════════════════════════════════
   🆕 v564（用户第 6 / 9 项）
   ── 会员中心按钮 ──
     用户：「这几个按钮间距调整成一样的」。病根不是 gap（两组都是 8px），而是两组之间
     插了一条 .bm-sep（1px 线 + 2px 上下边距）把行距撑开。分隔线已删，这里把第二组
     的上边距钉成同一个 8px，并统一居中（原来第二组左对齐、第一组居中，看着也像两套）。
   ── 提醒邮箱 ──
     改成与「最近登录」同款 .tp-row：字体走 .tp-k，邮箱与标题同一行，两个操作钮换成
     与其它窗口一致的图标按钮（.btn.tiny.act-ico）。
   ══════════════════════════════════════════════════════════════════════════════ */
.bm-acts-col { margin-top: 8px; }
.bm-acts-col .bm-btn { text-align: center; }
.bm-msg:empty { margin: 0; padding: 0; }

.sec-email-line { display: inline-flex; align-items: center; justify-content: flex-end; gap: 6px; flex-wrap: wrap; white-space: normal; }
.sec-email-line .sec-email-val { font-size: inherit; color: var(--ink); word-break: break-all; }
.sec-email-input { flex: 0 1 150px; min-width: 96px; max-width: 150px; padding: 5px 8px; font-size: 13px;
  border: 1px solid var(--line); border-radius: 8px; background: var(--panel); color: var(--ink); }

/* ══════════════════════════════════════════════════════════════════════════════
   🆕 v578（用户 2026-11-01 第 1 项）：EXE 首页改为「照网页版的样子」做
   —— 用户原话：「桌面 exe 文件打开后的首页中的页面按照网页版的首页来做，不要右边大量留白。」
   ── 病根（不是宽度问题，是网格行被拉伸）──
     v564 把 `.hf-body`（卡内正文）在 EXE 上收掉以后，卡的 grid 变成
       "head" / "vid lead" / "vid body"(空) / "vid foot"
     而 `vid` 要跨 3 行 ⇒ 它 169px 的高度被平摊给 lead / body / foot 三行，
     lead 贴行顶、foot 贴行底 ⇒ 右侧那列中间空出约 90~120px 的「大洞」。
     网页版没有这个问题，只因为正文有 4~6 行把行高填满了。
   ── 改法 ──
     把 `.hf-body` 在 EXE 上**放回来**（撤销 v564 的 `display:none`）⇒ 版式与网页版一致，
     右列由「定位句 + 正文 + 进入」自然填满，不再有洞。
     这一步直接推翻了 v564「首页的功能介绍这些文字删掉」的口径 —— 以**本次**口径为准：
     用户要的是「照网页版做」，而网页版就是带正文的。若以后又想去掉正文，
     请连同 `.hf-card` 的行分配一起改（例如把 vid 单独一行），否则大洞会立刻回来。
   ── 其余仍是 EXE 专属 ──
     背景两团径向柔光撤掉、底色改纯色 ⇒ EXE 首页比网页版更「素」，这是 v564 保留的口径。
   ══════════════════════════════════════════════════════════════════════════════ */
html.is-desktop #panel-home .hf-card { align-content: start; }
html.is-desktop #panel-home::after { display: none; }
html.is-desktop #panel-home { background: var(--bg); }

/* ══ v581（用户 2026-11-01）示例患者只读：写操作控件视觉灰化 ═══════════════════════
   用户要求「示例患者的各页面不支持删改」。拦截有三层（见 app.v581.js 里 DEMO_WRITE_SEL
   那段注释）：capture 阶段吃 click / save() 回滚 / toast 提示。
   这里只做**视觉**那一层：如果按钮长得跟平时一模一样、点了却没反应，用户会当成 bug。
   故意**不设** pointer-events:none —— 点击必须能传到 capture 监听器，才弹得出提示。 */
body.demo-patient-mode #btn-ind-add,
body.demo-patient-mode #btn-chart-add,
body.demo-patient-mode .tl-row-edit,
body.demo-patient-mode #YxYqk6fXNVvIYD5g2GdyCD,
body.demo-patient-mode #btn-scan-gallery,
body.demo-patient-mode #btn-scan-camera,
body.demo-patient-mode #btn-scan-wechat,
body.demo-patient-mode #gal-import,
body.demo-patient-mode #btn-import-csv,
body.demo-patient-mode #btn-file-folder,
body.demo-patient-mode #btn-file-wechat,
body.demo-patient-mode #btn-file-clear,
body.demo-patient-mode #btn-rec-delete-sel,
body.demo-patient-mode #btn-rec-add-inline,
body.demo-patient-mode #btn-rec-add-go,
body.demo-patient-mode #btn-thumbs-refresh,
body.demo-patient-mode .scan-thumb-del,
body.demo-patient-mode #btn-med-add,
body.demo-patient-mode #btn-med-add-go,
body.demo-patient-mode #btn-med-delete-sel,
body.demo-patient-mode #btn-adh-checkin,
body.demo-patient-mode #btn-adh-edit,
body.demo-patient-mode #mpl-remove,
body.demo-patient-mode #btn-add-medcost,
body.demo-patient-mode #btn-save-medcost,
body.demo-patient-mode #btn-add-vaccine,
body.demo-patient-mode #btn-save-vaccine,
body.demo-patient-mode [data-goto-med-add],
body.demo-patient-mode #btn-vitals-add,
body.demo-patient-mode #btn-event-form-toggle,
body.demo-patient-mode #btn-ev-add,
body.demo-patient-mode #vitals-add,
body.demo-patient-mode #btn-delete-profile,
body.demo-patient-mode #md-new,
body.demo-patient-mode #md-merge,
body.demo-patient-mode #dup-merge,
body.demo-patient-mode #dup-keep,
body.demo-patient-mode #bm-audit,
body.demo-patient-mode #bm-consent-reset {
  opacity: .5;
  cursor: not-allowed;
  filter: grayscale(.4);
}
/* 灰化状态下不要保留按压/悬停的位移与高亮，否则像「点了有效」 */
body.demo-patient-mode #btn-ind-add,
body.demo-patient-mode #btn-chart-add,
body.demo-patient-mode .tl-row-edit,
body.demo-patient-mode #YxYqk6fXNVvIYD5g2GdyCD,
body.demo-patient-mode #btn-scan-gallery,
body.demo-patient-mode #btn-scan-camera,
body.demo-patient-mode #btn-scan-wechat,
body.demo-patient-mode #gal-import,
body.demo-patient-mode #btn-import-csv,
body.demo-patient-mode #btn-file-folder,
body.demo-patient-mode #btn-file-wechat,
body.demo-patient-mode #btn-file-clear,
body.demo-patient-mode #btn-rec-delete-sel,
body.demo-patient-mode #btn-rec-add-inline,
body.demo-patient-mode #btn-rec-add-go,
body.demo-patient-mode #btn-thumbs-refresh,
body.demo-patient-mode .scan-thumb-del,
body.demo-patient-mode #btn-med-add,
body.demo-patient-mode #btn-med-add-go,
body.demo-patient-mode #btn-med-delete-sel,
body.demo-patient-mode #btn-adh-checkin,
body.demo-patient-mode #btn-adh-edit,
body.demo-patient-mode #mpl-remove,
body.demo-patient-mode #btn-add-medcost,
body.demo-patient-mode #btn-save-medcost,
body.demo-patient-mode #btn-add-vaccine,
body.demo-patient-mode #btn-save-vaccine,
body.demo-patient-mode [data-goto-med-add],
body.demo-patient-mode #btn-vitals-add,
body.demo-patient-mode #btn-event-form-toggle,
body.demo-patient-mode #btn-ev-add,
body.demo-patient-mode #vitals-add,
body.demo-patient-mode #btn-delete-profile,
body.demo-patient-mode #md-new,
body.demo-patient-mode #md-merge,
body.demo-patient-mode #dup-merge,
body.demo-patient-mode #dup-keep,
body.demo-patient-mode #bm-audit,
body.demo-patient-mode #bm-consent-reset {
  transform: none !important;
  box-shadow: none !important;
}

/* ══════════════════════════════════════════════════════════════════════════
   🆕 v588（用户 2026-11-05 第 1 项）周历热力图顶部的「月份刻度」
   ── 覆盖三块 ──
     .sh-*  症状日历热力图（13 周）
     .lah-* 检验异常日历热力图（13 周）
     .dc-*  最近 12 周打卡（v588 起改成周列结构）
   ── 几何硬绑 13px / 3px ──
     一列 = 13px 格 + 3px gap = 16px，与 .sh-cell / .lah-cell / .dc-cell 完全一致。
     刻度行必须与下面格子行**逐列对齐**，所以这里不许改成 em / % / fr。
   ── 文字绝对定位向右溢出 ──
     若让「10月」参与布局，它会比 13px 宽，把后面十几列整体推歪；
     绝对定位 + nowrap 后，月份只是「贴在那一列头上」的标注，零布局影响。
     （尾巴可能压到相邻列的字上，所以 JS 里强制「至少隔 3 列才许再标」。）
   ══════════════════════════════════════════════════════════════════════════ */
.sh-months, .lah-months, .dc-months {
  display: flex; gap: 3px; margin: 0 0 4px; padding: 0; line-height: 1;
}
.sh-months > .sh-mon,
.lah-months > .lah-mon,
.dc-months > .dc-mon {
  position: relative; flex: 0 0 13px; width: 13px; height: 12px; display: block;
}
.sh-months b, .lah-months b, .dc-months b {
  position: absolute; left: 0; top: 0;
  font-size: 10px; font-weight: 500; line-height: 12px; letter-spacing: .2px;
  white-space: nowrap; color: #8a94a6;
}
html[data-theme="dark"] .sh-months b,
html[data-theme="dark"] .lah-months b,
html[data-theme="dark"] .dc-months b { color: #9aa6b2; }

/* 🆕 v588：打卡热力图 = 12 列 × 7 行（列 = 周） */
.dc-col { display: flex; flex-direction: column; gap: 3px; }
/* 「今天之后」的格子：只有描边、不填色、点不动（JS 里不给它 data-date） */
.dc-heat .dc-cell.dc-future {
  background: transparent;
  box-shadow: inset 0 0 0 1px rgba(140, 152, 168, .4);
  cursor: default;
}
html[data-theme="dark"] .dc-heat .dc-cell.dc-future {
  background: transparent;
  box-shadow: inset 0 0 0 1px rgba(120, 135, 152, .35);
}

/* ═══════════════════════════════════════════════════════════════════════════
   🆕 v595（2026-11-08）：触屏设备的**触控目标放大** —— 纯增量，桌面/鼠标环境一字不动。

   为什么现在加：平板 / 折叠屏（鸿蒙 HAP）跑的是与 exe 同一套 www，但尺寸是按鼠标设计的。
   实测 1280×800 触屏语境（pointer:coarse + hover:none，等价 2560×1600 平板）：
     .tab 103×38 · .btn.ghost.hb-theme 68×26 · .btn.tiny.act-ico 20×20 ·
     .rec-sel 16×16 · .seg-btn 56×28 · .chart-gear 26×26 …
   参考阈值：苹果 HIG 44×44、Material 48dp。这里分两档，而不是一律 44：
     · 导航与主操作（页签 / 返回 / 设置 / 分段选择 / 主按钮）→ ≥44
     · 密集表格里的行内图标钮（一个单元格并排两个）→ ≥36
       再大就把表格撑散、一屏少放 5 行，反而更难用。

   断点用 `(pointer: coarse) and (hover: none)`，**不用** any-pointer:coarse：
   后者在「触屏 + 鼠标」的 Windows 笔记本上也为真，会把桌面 exe 一起改掉（桌面不许动）。

   ⚠️ 这里的 !important 是**故意**的：这些尺寸被几十条上下文规则分散定义
   （`.chart-tools .btn.tiny`、`.event-item .btn.act-ico`、`.member .tab` …），逐条覆盖会写成一堵墙，
   而且以后新增一处就漏一次。本块已由媒体查询圈在触屏设备内，不外溢。
   ═══════════════════════════════════════════════════════════════════════════ */
@media (pointer: coarse) and (hover: none) {
  /* 顶部 / 底部页签 */
  /* 页签（.tab）**不在这里改** —— 手机上它是底部导航条，必须能被压缩才放得下 7 个；
     放大会把「会员中心」挤出屏幕。改见文件末尾 `min-width:641px` 的两个块。 */

  /* 页头返回 / 图表工具 / 帮助圆钮 / 卡片角钮 / 缩略图删除 / 刷新 */
  .hdr-back, .chart-gear, .hint-q, .card-corner-btn, .ind-def-q,
  .scan-thumb-del, .ico-refresh, .entry-ico {
    width: 44px !important; height: 44px !important;
    min-width: 44px !important; min-height: 44px !important;
  }

  /* 分段选择 / 图表页签 / 检验页签 / 指标分析开关 / 超限覆盖层按钮 */
  .seg-btn, .chart-tab, .lab-tab, .ia-toggle, .rec-ov-btn {
    min-height: 44px !important; padding-top: 9px !important; padding-bottom: 9px !important;
  }
  .chart-tab-nav { width: 44px !important; height: 44px !important; min-width: 44px !important; min-height: 44px !important; }

  /* 主按钮（排除 .tiny 行内钮，否则表格会被撑散） */
  .btn:not(.tiny) { min-height: 44px !important; }

  /* 表格行内图标钮（✏️ / 🗑 / ＋）：36，兼顾可点与密度 */
  .btn.tiny { min-width: 36px !important; min-height: 36px !important; }
  .btn.tiny.act-ico { width: 36px !important; height: 36px !important; font-size: 18px !important; }

  /* 图例 chip / 图例项：加高可点区（勾选整行更稳） */
  .tl-chip, .legend-item {
    min-height: 36px !important; padding-top: 6px !important; padding-bottom: 6px !important;
  }

  /* 表格行首勾选框：16px 手指点不中 */
  .rec-sel { width: 24px !important; height: 24px !important; }


  /* 用药页的「日 / 周 / 月」视图切换钮 + 表单勾选框：同属手指常点区 */
  .adh-vt { min-height: 44px !important; min-width: 44px !important; }
  input[type="checkbox"], input[type="radio"] { width: 24px !important; height: 24px !important; }

  /* 第二批（实测漏网的）：今日视图用药勾选、事件卡收藏星、窗口删除、档案编辑、关于面板按钮与链接 */
  .tm-skip-btn, .tm-take-btn, .tm-takeall-btn { min-height: 36px !important; min-width: 36px !important; }
  .dc-star { width: 32px !important; height: 32px !important; }
  .vc-del-win { width: 36px !important; height: 36px !important; min-width: 36px !important; min-height: 36px !important; }
  .pw-edit { width: 36px !important; height: 36px !important; min-width: 36px !important; min-height: 36px !important; }
  .med-sel { width: 26px !important; height: 26px !important; }
  .bm-btn { min-height: 44px !important; }
  .bm-link { display: inline-block !important; padding: 8px 2px !important; }
  /* 拍照 / 文件导入主按钮 */
  .scan-act-btn { min-height: 44px !important; }
}

/* ── 宽屏（≥641）才放大的顶部页签 ─────────────────────────────────────────────
   为什么要分段：
   · ≤640：页签是**底部导航条**，7 个挤在 388/346 里，必须允许压缩 ⇒ 一律不动（原本就 67 高，够指头点）。
   · 641~900：折叠屏展开 712 / 三折叠 718 —— 高度给足 44，但横向必须收紧，
     否则 7 个页签放不下、「会员中心」被推到滚动区外（实测溢出 102px）。
   · ≥901：平板/2in1，页签给 44×44 且 flex:0 0 auto（不压缩 ⇒ 不会把字裁成「会员中」）。 */
@media (pointer: coarse) and (hover: none) and (min-width: 641px) {
  .tab { min-height: 44px !important; min-width: 44px !important; flex: 0 0 auto !important;
         padding: 10px 12px !important; font-size: 15px !important; }
}
@media (pointer: coarse) and (hover: none) and (min-width: 641px) and (max-width: 900px) {
  .tab { padding: 10px 6px !important; font-size: 13.5px !important; }
}
