/* 青志社团 v79.7 · 新增样式（技术设计 §1.1 第 4 个新文件）
   ============================================================================
   ★ 本文件是**追加式**的：只加 v79.7 新样式，一行既有样式都不改。
     styles.css 3731 行已被全站依赖，改它 = 回归面无法收敛。

   ★ 铁律一（z-index）：本文件所有 fixed 层 / 浮层 z-index **≥ 1000**，
     不得低于 95。body.night-dim::after 是 z-index:95（styles.css L3000），
     夜间压暗模式下 z-index < 95 的新浮层会被压暗遮罩盖住、点不动。
     ⚠️ night-dim::after 带 pointer-events:none，所以点击不受影响但**视觉被压暗**
       —— 仍必须提 z-index，否则用户看到「夜里打开备忘录确认层一片昏暗」。

   ★ 铁律二（颜色）：**禁止硬编码任何灰色**。一律用 CSS 变量
     var(--tx) / var(--tx2) / var(--tx3) / var(--pri)。
     v79.6 刚把三套主题的 --tx3 对比度全部修到 ≥ 4.5：
       亮 #697185 / 暗 #8696ad / mascot #5b7382（styles.css L3 / L69 / L156）。
     用变量 = 三套主题自动跟随，v79.6 的对比度修复成果**自动继承**。
     ⚠️ 新写的 .hint 类提示文字一律 var(--tx3)，不许写 #888 / #999。
       本项目曾因 .stat-card.tap:after 的 opacity:.55（L1234）留下对比度隐患，
       技术设计 §7.3 ③ 明确「新代码不继承该缺陷」——所以这里连 opacity 都不用。

   ★ 铁律三（类名）：一律加 v797- 前缀。本项目曾因裸类名 .warn 撞上
     已有全局组件类，排查数小时。前缀是隔离，不遵守等于主动制造回归。
   ========================================================================== */

/* ── 批次 0/1：IndexedDB 降级模式常驻提示条（技术设计 §2.3）────────────────
   为什么必须常驻而不能只 toast 一次：
     用户关掉页面就忘了，容量真写满时反而不知道原因。
     §2.3 原文：「这是『不许假装正常』的具体落地。」 */
.v797-degraded {
  margin: 0 0 10px;
  padding: 10px 12px;
  border-radius: 12px;
  border: 1px solid rgba(214, 158, 46, .55);
  /* 背景用半透明暖色 + backdrop，不引入新的主题色变量，
     亮/暗/mascot 三套主题下都能看清边框。 */
  background: rgba(214, 158, 46, .12);
  color: var(--tx);
  font-size: 13px;
  line-height: 1.6;
  /* 提示条不是浮层，随页面流走，不占用 fixed z-index 档位 */
  position: relative;
  z-index: 1;
}
.v797-degraded-text {
  font-weight: 600;
}
.v797-degraded-extra {
  margin-top: 4px;
  /* 次要说明文字用 --tx3（v79.6 已修到三主题 ≥4.5），不用 opacity 压暗 */
  color: var(--tx3);
  font-size: 12px;
}
.v797-degraded-extra b {
  color: var(--tx2);
}

/* ── 批次 0/1 预留：番茄钟运行态恢复提示条（批次 3 渲染时挂载）────────────
   技术设计 §5.5 规则 5：重开 App 时若检测到未结束的计时，
   展示「检测到你之前有未结束的计时，已恢复」确认条。
   ★ 诚实措辞铁律：文案不得暗示「弹窗能防杀进程」——
     PRD §5.5 已明确「加弹窗也不能阻止系统杀进程」，
     真正的技术手段是时间戳补偿，弹窗只是提示用户保活。 */
.v797-restore {
  margin: 0 0 10px;
  padding: 10px 12px;
  border-radius: 12px;
  border: 1px solid var(--line, rgba(128, 138, 158, .35));
  background: rgba(128, 138, 158, .10);
  color: var(--tx);
  font-size: 13px;
  line-height: 1.6;
  position: relative;
  z-index: 1;
}
.v797-restore .v797-restore-sub {
  color: var(--tx3);
  font-size: 12px;
  margin-top: 3px;
}
.v797-restore .v797-restore-act {
  display: inline-flex;
  gap: 8px;
  margin-top: 8px;
}

/* ── 批次 2：超级备忘录 ─────────────────────────────────────────────── */
/* ⚠ 类名必须与 memo.js **实际输出的 DOM** 逐字一致。之前的版本写的是
   .v797-memo-item / .v797-memo-title / .v797-memo-list …，
   而 memo.js 的 itemHtml() 输出的是 .v797-mi / .v797-mi-title / .v797-list …，
   两套名字**零重叠** —— 页面上元素全都在，但一条样式都没命中，
   备忘录看起来像「坏了」（裸列表、无卡片、无间距）。
   教训：类名不是「设计时就定好的」，是**渲染代码的产出**；
   写完 memo.js 必须回头做一次「CSS 类名 ∩ JS 类名」的机械比对。
   下面每条规则的类名都来自 memo.js 的 itemHtml()/render()/paintSpans()。 */
.v797-memo { padding: 12px; }
.v797-wrap { min-width: 0; }

/* 一句话输入条。position:sticky 让它滚到下面也能看见 —— 备忘录的
   主交互就是「随时记一句」，输入框沉到屏幕外等于功能不存在。 */
.v797-memo-compose {
  position: sticky;
  /* ⚠⚠⚴ v79.9 批次9【#17-A】top 用**实测注入**的顶栏高度，不再写死 0。
     原值 `top:0` ⇒ 滚动时这条（z:1000）直接压在顶栏（z:40）**上面**，
     实测顶栏 y=0..84、本条 y=0..61 ⇒ 顶栏被完全盖住、点不到。
     ⚠⚠⚴ 为什么**不写死一个 px**（实测数据）：
       顶栏高度**随视口宽度变化**（真浏览器 getBoundingClientRect）：
           390 ⇒ 83.52    414 ⇒ 83.52    1280 ⇒ **131.42**
       而按 CSS 推算是 51px（8+34+8+1）—— 比实测小 **32.5px**。
       根因是 `#nav`（11 个导航按钮）的 flex-wrap 在窄屏换行、宽屏不换行。
       ⇒ 写死 84px 只会把「移动端遮挡」换成「桌面端重叠 47px」，等于没修。
     ⚠ `--qz-topbar-h` 由 app.js 的 syncTopbarH() 用 ResizeObserver 实测后写入。
       ⚠ **fallback 0px = 退回改动前的行为**（顶栏被盖），
         刻意如此：JS 没跑时**不比修复前更坏**，而不是变成一个未知值。*/
  top: var(--qz-topbar-h, 0px);
  z-index: 1000;
  display: flex; gap: 8px; margin-bottom: 12px;
  padding: 8px; border-radius: 12px;
  background: var(--bg2); border: 1px solid var(--line);
}
.v797-memo-input {
  flex: 1; min-width: 0; padding: 9px 12px; border-radius: 9px;
  border: 1px solid var(--line); background: var(--bg); color: var(--tx);
  font-size: 15px; /* ≥15px 防 iOS 聚焦时自动放大 */
}
.v797-memo-input:focus { outline: 2px solid var(--pri); outline-offset: 1px; }

/* 类型切换条（待办 / 事件 / 每日待办） */
.v797-types { display: flex; gap: 7px; margin-bottom: 8px; flex-wrap: wrap; }
.v797-type {
  padding: 6px 13px; border-radius: 999px; cursor: pointer; font-size: 13px;
  border: 1px solid var(--line); background: var(--bg2); color: var(--tx2);
}
/* ★★ v79.9 批次 8 任务 4：类型按钮的选中态。
   ⚠ 为什么必须画出来：这三个按钮紧挨着输入框，
     之前它们**既没绑定事件、也没有选中态** —— 现在事件通了，
     但如果切完类型界面上还是三个一模一样的胶囊，
     用户会以为「点了还是没反应」，
     那等于把「绑定好了」这件事藏起来了。
   ⚠ 选中态用主色 + 描边双通道（不只是变色）：
     色弱用户与深色模式下单靠背景色差可能看不出来。*/
.v797-type.on {
  background: var(--pri); border-color: var(--pri); color: #fff; font-weight: 600;
}
.v797-hint { color: var(--tx3); font-size: 12px; line-height: 1.6; margin-bottom: 12px; }
.v797-h { color: var(--tx2); font-size: 13px; margin: 14px 0 7px; }

.v797-list { list-style: none; margin: 0; padding: 0; }
.v797-list-done { opacity: 1; }
.v797-list-done .v797-mi-title { text-decoration: line-through; color: var(--tx3); }

.v797-mi {
  display: flex; gap: 10px; align-items: flex-start;
  padding: 10px 12px; margin-bottom: 8px; border-radius: 11px;
  background: var(--bg2); border: 1px solid var(--line);
}
/* 跨天条目左侧描一条主色边，与普通待办一眼可分 */
.v797-mi-cross { border-left: 3px solid var(--pri); }
.v797-mi-done .v797-mi-title { text-decoration: line-through; color: var(--tx3); }
.v797-mi-check {
  flex: 0 0 auto; border: 0; background: transparent; cursor: pointer;
  color: var(--tx2); font-size: 17px; line-height: 1.5; padding: 0 2px;
}
.v797-mi-ico { font-size: 17px; line-height: 1.5; flex: 0 0 auto; }
.v797-mi-main { flex: 1; min-width: 0; }
.v797-mi-title { display: block; color: var(--tx); font-size: 15px; line-height: 1.5; word-break: break-word; }
.v797-mi-time { display: block; margin-top: 3px; color: var(--tx3); font-size: 12px; line-height: 1.6; }
.v797-mi-wd { margin-left: 6px; }
.v797-mi-remark { display: block; margin-top: 3px; color: var(--tx3); font-size: 12px; line-height: 1.6; }
.v797-mi-type { flex: 0 0 auto; color: var(--tx3); font-size: 12px; }
/* ★★ v79.9 批次 8 任务 2：条目上的「已同步/未同步到待办」角标 ⇄。
   ⚠ 已同步用主色，未同步用弱化灰 —— 用户一眼能看出「这条还没进待办」。
   ⚠ 必须给 title：光靠颜色说不清「这个 ⇄ 是什么意思」。*/
.v797-mi-sync { margin-left: 5px; color: var(--pri); font-size: 12px; cursor: help; }
.v797-mi-nosync { margin-left: 5px; color: var(--tx3); opacity: .5; font-size: 12px; cursor: help; }
.v797-mi-del {
  flex: 0 0 auto; border: 0; background: transparent; cursor: pointer;
  color: var(--tx3); font-size: 17px; padding: 2px 6px; border-radius: 7px;
}
.v797-mi-del:hover { background: var(--line); }

/* 载入骨架。用户会以为「功能坏了、没数据」 */
.v797-loading { padding: 26px 12px; text-align: center; color: var(--tx3); font-size: 13px; }
.v797-empty { padding: 26px 12px; text-align: center; color: var(--tx3); font-size: 13px; }

/* 跨天时段叠加层（paintSpans）。C-02/C-03：不撑高日历格、不遮挡正常课程
   —— 所以只画**顶部细条**，绝不用绝对定位的巨块。 */
.v797-spanwrap {
  display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
  margin: 0 0 10px; padding: 8px 11px; border-radius: 10px;
  background: var(--bg2); border-left: 3px solid var(--pri);
  color: var(--tx3); font-size: 12.5px; line-height: 1.6;
}
.v797-spanbox { display: contents; }
.v797-span { color: var(--tx3); }

/* ── 批次 2：概览页超级备忘录卡片（A5）+ 吉祥物快捷菜单（A6）─────────── */
/* 概览卡片。只在既有 v66 待办条为空时出现（app.js 的 todoHTML else 分支），
   所以不与 wb66-todobar 抢位置，两条并存时也不会重排既有面板。 */
.v797-home-memo {
  margin: 0 0 10px; padding: 10px 12px; border-radius: 12px;
  background: var(--bg2); border: 1px solid var(--line); cursor: pointer;
}
.v797-home-hd {
  display: flex; align-items: center; justify-content: space-between;
  color: var(--tx2); font-size: 13.5px; font-weight: 600; margin-bottom: 7px;
}
.v797-home-list { list-style: none; margin: 0; padding: 0; }
.v797-home-mi {
  display: flex; gap: 9px; align-items: flex-start;
  padding: 6px 0; border-top: 1px solid var(--line);
}
.v797-home-ico { font-size: 15px; line-height: 1.5; flex: 0 0 auto; }
.v797-home-tx { flex: 1; min-width: 0; color: var(--tx); font-size: 14px; line-height: 1.5; word-break: break-word; }
.v797-home-sub { display: block; color: var(--tx3); font-size: 11.5px; line-height: 1.6; }
.v797-home-type { flex: 0 0 auto; color: var(--tx3); font-size: 11.5px; }
.v797-home-more { color: var(--tx3); font-size: 12px; padding-top: 6px; }

/* 吉祥物快捷菜单。z-index 1000（铁律一）：night-dim::after 是 95，
   低了会被夜间压暗遮罩盖住、点不动。 */
.v797-mbmenu {
  position: absolute; right: 0; bottom: 100%; margin-bottom: 8px;
  z-index: 1000; display: none; min-width: 152px;
  padding: 5px; border-radius: 12px;
  background: var(--bg2); border: 1px solid var(--line);
  box-shadow: 0 8px 24px rgba(0, 0, 0, .18);
}
.v797-mbmenu.on { display: block; }
/* __P0FIXED_MBMENU__ P0-1 判据 ⑥：这张菜单真实鼠标点击**收不到事件**。
   根因：批次 8【B】修 D4 时给 .mascot-buddy 加了 pointer-events:none（styles.css:3412），
   只把 .mb-body / .mb-chat 放回命中测试（同文件 3413 行），**漏了本菜单**。
   ⇒ 菜单显示得出来（.on 控制 display），但事件穿透到页面背后。
   ⚠ 隐蔽点：display:none 时菜单不参与命中测试 ⇒ 只查「DOM 里有按钮」的判据全绿。
   ⚠ 写在 styles.css 那条旁边不现实（不在同一文件），故就近写在这里，注释已互相指认。
   ⚠ 关闭态 .mb-bubble 的 pointer-events:none 特异性更高，不受此条影响。*/
.v797-mbmenu,
.v797-mbmenu button { pointer-events: auto; }
.v797-mbmenu button {
  display: block; width: 100%; text-align: left; cursor: pointer;
  padding: 9px 11px; border: 0; border-radius: 9px;
  background: transparent; color: var(--tx); font-size: 14px;
}
.v797-mbmenu button:hover { background: var(--line); }

/* 设置页的 v79.7 两个新面板（⑤ 超级备忘录 / ⑥ 超级番茄钟）。
   只加一条极轻的区分标记（左侧主色竖条），让用户一眼看出这两块是新加的；
   刻意**不复用**既有 .panel 的任何属性覆盖 —— 改既有样式等于扩大回归面。 */
.v797-set { border-left: 3px solid var(--pri); }

/* 设置页的布尔开关行（A14）。既有设置页大量用 label+input，
   这里只补一点排版，不改动既有 .fld 的任何样式。 */
.v797-sw {
  display: inline-flex; align-items: center; gap: 6px;
  color: var(--tx); font-size: 13px; cursor: pointer; flex: none;
}
.v797-sw input { width: auto; flex: none; }

/* ── 批次 3：超级番茄钟 ─────────────────────────────────────────────── */
.v797-pomo { padding: 12px; text-align: center; }
.v797-pomo-state { color: var(--tx2); font-size: 13px; margin-bottom: 6px; }
/* 提示条一律 var(--tx3)（铁律二） */
.v797-pomo-notice {
  margin: 0 auto 10px; padding: 8px 11px; max-width: 520px;
  border-radius: 9px; background: var(--bg2); border: 1px solid var(--line);
  color: var(--tx3); font-size: 12.5px; line-height: 1.6; text-align: left;
}
.v797-pomo-ring { margin: 6px 0 12px; }
/* 环形进度 SVG 本身（pomo.js 的 ringSvg 输出） */
.v797-ring { display: block; margin: 0 auto; }
.v797-pomo-presets { display: flex; flex-wrap: wrap; gap: 7px; justify-content: center; margin-bottom: 10px; }
.v797-preset {
  padding: 7px 13px; border-radius: 999px; cursor: pointer; font-size: 13px;
  border: 1px solid var(--line); background: var(--bg2); color: var(--tx2);
}
.v797-preset.on { background: var(--pri); color: var(--bg); border-color: var(--pri); }
/* 「+ 档位」按钮：虚线边，与已有档位区分（不是又一个档位） */
.v797-preset-add { border-style: dashed; color: var(--tx3); }
.v797-pomo-modes, .v797-pomo-tags, .v797-pomo-acts {
  display: flex; gap: 8px; justify-content: center; align-items: center; margin-bottom: 10px;
  flex-wrap: wrap;
}
.v797-mode {
  padding: 6px 15px; border-radius: 8px; cursor: pointer; font-size: 13px;
  border: 1px solid var(--line); background: transparent; color: var(--tx2);
}
.v797-mode.on { background: var(--pri); color: var(--bg); border-color: var(--pri); }
.v797-tag-input {
  padding: 7px 11px; border-radius: 9px; font-size: 14px;
  border: 1px solid var(--line); background: var(--bg); color: var(--tx); width: 150px;
}
.v797-btn {
  padding: 8px 17px; border-radius: 9px; cursor: pointer; font-size: 14px;
  border: 1px solid var(--line); background: var(--bg2); color: var(--tx);
}
.v797-btn.primary { background: var(--pri); color: var(--bg); border-color: var(--pri); }
.v797-btn:hover { filter: brightness(1.06); }
/* 导出按钮是 .v797-btn + data 属性（pomo.js 输出的是 data-v797-export，
   **没有** .v797-export 这个类 —— 写类名规则就是死代码）。用属性选择器。 */
.v797-btn[data-v797-export] { margin-top: 12px; }

/* 口径脚注。跨天归属不是 bug，但**必须写明**，否则用户以为统计错了。 */
.v797-pomo-foot {
  margin-top: 10px; color: var(--tx3); font-size: 11.5px; line-height: 1.7;
}
.v797-pomo-foot strong { color: var(--tx2); }

/* ── 批次 3：超级统计 + SVG 图表 ────────────────────────────────────── */
.v797-stats { padding: 12px; }
.v797-dims { display: flex; gap: 7px; margin-bottom: 12px; }
.v797-dim {
  flex: 1; padding: 7px 0; border-radius: 8px; cursor: pointer; font-size: 13px;
  border: 1px solid var(--line); background: var(--bg2); color: var(--tx2);
}.v797-dim.on { background: var(--pri); color: var(--bg); border-color: var(--pri); }
.v797-sum { color: var(--tx2); font-size: 14px; margin-bottom: 10px; }
.v797-sum strong { color: var(--tx); }
.v797-chart-wrap {
  margin: 10px 0; padding: 8px; border-radius: 11px;
  background: var(--bg2); border: 1px solid var(--line); overflow-x: auto;
}
.v797-chart { display: block; max-width: 100%; }
.v797-legend { list-style: none; margin: 0 0 8px; padding: 0; }
.v797-legend li {
  display: flex; align-items: center; gap: 7px;
  color: var(--tx3); font-size: 12.5px; line-height: 1.9;
}
.v797-dot { width: 9px; height: 9px; border-radius: 3px; flex: 0 0 auto; }

/* ══════════════════════════════════════════════════════════════════════
   v79.9 批次 8【C3】· 按标签分布的「合计」行
   ──────────────────────────────────────────────────────────────────────
   ★ 用户要「看到时长的总和」。原来图例每项都写了各自时长，
     但没有任何一行说「加起来等于多少」—— 百分比被 fixPercentTo100
     补差后必然加到 100.0%，**百分比自洽 ≠ 用户能拿秒数对账**。
   ⚠ 排版取舍：这一行**顶在上边框**，不是混在图例项里。
     混进去的话它和普通标签行长得一样，用户会把它当成"又一个标签"去读百分比。
     顶边框 + 稍强字重 = 一眼看出这是"结论行"。
   ⚠ 全部走既有变量（--tx / --tx3 / --line / --pri-soft），
     亮暗两态各自自动成立，不写死任何前景/背景色。 */
.v797-legend-sum {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  margin-top: 6px; padding-top: 7px;
  border-top: 1px solid var(--line);
  font-size: 12.5px; line-height: 1.7;
}
.v797-legend-sum-k { color: var(--tx3); font-weight: 600; }
.v797-legend-sum-v {
  color: var(--tx); font-weight: 700;
  /* 机读出口在 data-sec 上；这里给 tabular-nums 让多行数字对齐，
     否则 "1 小时 5 分" 与 "45 分" 的数字宽度不同，合计行会显得歪。 */
  font-variant-numeric: tabular-nums;
}
.v797-legend-sum-n { color: var(--tx3); font-size: 11.5px; margin-left: auto; }

/* 批次 2/3 将追加：备忘录卡片、确认层、跨天横幅、番茄钟大时钟、SVG 图表样式。
   届时新增浮层继续遵守本文件头的 z-index ≥ 1000 与 var(--tx3) 两条铁律。 */

/* ══════════════════════════════════════════════════════════════════════
   v79.7 批次 4 · 排障日志导出面板（A16）
   ──────────────────────────────────────────────────────────────────────
   ★ 类名一律 v797- 前缀（本项目曾因裸类名撞全局组件类，见文件头铁律三）。
   ★ 文字色一律 var(--tx3)：三套主题已修到 ≥4.5:1，不要写死 #888 之类。
   ★ z-index：非浮层，不参与 ≥1000 那条铁律（那条只约束 fixed 浮层）。*/
.v797-diag-slot { margin-top: 12px; }

.v797-diag-warn {
  padding: 10px 12px;
  margin-bottom: 10px;
  border-radius: 10px;
  font-size: 13px;
  line-height: 1.6;
  color: var(--tx3);
  background: color-mix(in srgb, var(--tx3) 8%, transparent);
  border: 1px solid color-mix(in srgb, var(--tx3) 22%, transparent);
}
.v797-diag-warn strong { color: var(--tx2); }

.v797-diag-row {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  color: var(--tx2);
  cursor: pointer;
  padding: 4px 0;
}
.v797-diag-row input { width: 16px; height: 16px; cursor: pointer; flex: 0 0 auto; }

.v797-diag-hint {
  font-size: 12px;
  line-height: 1.6;
  color: var(--tx3);
  margin: 2px 0 4px 24px;
}

.v797-diag-msg {
  margin-top: 8px;
  font-size: 13px;
  color: var(--tx3);
  min-height: 1px;
}

/* ══════════════════════════════════════════════════════════════════════
   v79.7 批次 5 · A18 本地数据导入 / 导出
   ----------------------------------------------------------------------
   ★ 项目铁律：CSS 类名一律 v797- 前缀；提示文字一律 var(--tx3)（不写死颜色）。
     颜色全部走变量，深浅色主题各自生效 —— 这里**不出现任何十六进制颜色**，
     否则换肤时会留下「这一块没跟着变」的残余白底/黑底。
   ══════════════════════════════════════════════════════════════════════ */
.v797-io-row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 8px;
}
.v797-io-label {
  font-size: 13px;
  font-weight: 600;
  color: var(--tx2);
  flex: none;
  min-width: 52px;
}
.v797-io-btns {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
/* 密码强度提示：四个档位各一个色，但都取自主题变量，保证对比度 */
.v797-io-hint { color: var(--tx3); margin-top: 4px; }
.v797-io-hint-none { color: var(--tx3); }
.v797-io-hint-bad { color: var(--tx3); font-weight: 600; }
.v797-io-hint-weak { color: var(--tx3); }
.v797-io-hint-ok { color: var(--tx3); }
/* 进度 / 结果日志：需要「停下来还能看清」的场合，不能靠 toast 一闪而过 */
.v797-io-log {
  margin-top: 10px;
  padding: 8px 10px;
  border-radius: var(--r-sm);
  background: var(--card);
  border: 1px solid var(--line);
  font-size: 12px;
  line-height: 1.7;
  color: var(--tx3);
  max-height: 190px;
  overflow-y: auto;
  word-break: break-all;
}
.v797-io-line { margin: 0; padding: 1px 0; }
.v797-io-err { color: var(--tx3); font-weight: 700; }

/* ══════════════════════════════════════════════════════════════════════
   v79.7 批次 7 · memo 三态的错误态
   ──────────────────────────────────────────────────────────────────────
   ★ 为什么必须单独定义：memo.js 的 render() 改成三态（loading / error /
     ready）后，error 分支引用了 .v797-err / .v797-hint。
     ⚠ 这两个类名当时**在本文件里不存在** —— 写类名规则时没同步写样式，
       表现是「错误提示渲染出来了但长得像正文」，对比度也没有保障。
     ★ 这类「HTML 引用了但 CSS 没定义」的洞静态读代码很难发现：
       类名拼写完全正确，只是没定义。所以新增渲染分支时，
       必须同一次改动里把样式补齐，并在下面留一行反向登记。*/
.v797-err {
  padding: 12px 14px; margin: 4px 0 8px;
  border-radius: var(--r-sm);
  background: var(--bg2);
  border: 1px solid var(--line);
  color: var(--tx2); font-size: 13.5px; line-height: 1.7; text-align: left;
}
.v797-hint { color: var(--tx3); font-size: 12.5px; line-height: 1.7; text-align: left; }
.v797-loading { color: var(--tx3); font-size: 13.5px; padding: 18px 0; text-align: center; }

/* ══════════════════════════════════════════════════════════════════════
   v79.7 批次 7 · 🍅 番茄钟重做（用户反馈「太简陋」）
   ──────────────────────────────────────────────────────────────────────
   ★ 背景：参考产品是成熟的商业番茄钟，原实现是「一行状态字 + 一个
     120px 小圈 + 一排文字按钮」。用户原话「你的番茄钟太简陋了」。
     简陋不在于功能少，而在于**没有视觉重心** —— 用户看不到时间在走。
   ★ 铁律一（z-index）：本节新增的 .v797-rest-* 是 fixed 浮层（休息提示），
     z-index 1040（> body.night-dim::after 的 95），否则夜间压暗时
     提示层会被压暗遮罩盖住、看着像一片昏暗。
     ⚠⚠⚠ v80.9【P1-6】**有意未改，请勿「顺手统一」**：
     这一节（.v797-rest-mask / .v797-rest-card，z=1040）与下面 :731 的
     .v797-rest-mask **夜里不参与 night-dim 压暗**，这是**已知的取舍，不是漏网 bug**。
     实测依据（浏览器量测，tmp/_p16_diag3.out.txt）：
       · 它们**不含任何表单控件**（无 input/textarea/select）
         ⇒ 不属于 P1-6 判据 `_v80_p16_dark.js` 的 A3 口径
         （A3 只锁「蒙版之上**且含表单**却未压暗」的层）
       · 休息提示是**全屏浮层**，压暗它会让「休息中」这个状态变得难以识别，
         收益低于损失
     ⇒ 如果将来要给它加压暗，**先跑 `_v80_p16_dark.js` 确认 A3 仍绿**，
       別顺手改 styles.css 的 night-dim 白名单 —— 那个白名单每一项都是
       作者按「该层整块都该暗 / 不该暗」逐个判过的（见 styles.css:3110-3123）。
   ★ 铁律二（颜色）：全部走 CSS 变量，三套主题自动跟随；不硬编码灰。
   ★ 铁律三（类名）：一律 v797- 前缀。
   ══════════════════════════════════════════════════════════════════════ */

/* ── 四态配色。用 data-v797-pomo-state 属性驱动，换状态只改属性不改样式 ──
   为什么用属性而不是四个独立类：JS 那边切换时只写一个属性，
   不会出现「加了新状态忘了加新类名」的漏配（与 memo 三态同源的坑）。 */
.v797-pomo { padding: 14px 12px 18px; text-align: center; }

/* 语义色变量：paused/rest 两种状态的环色与状态字色。
   ★ 为什么要提成变量而不是到处写死色值：
     ① 深色主题需要**更亮**的同色系（#b8791f 在 #0f1320 上只有 4.9:1，
        勉强够；#1f8f6d 在暗底上只有 4.6:1，低于 4.5 阈值边缘）；
     ② SVG 里写 var() 后浏览器实时解析，切主题立刻生效 ——
        写死色值会「冻住」在首次渲染那一刻（这正是本轮修掉的暗色 bug）。
   ⚠ 铁律二禁的是「硬编码灰色」；语义色必须固定才能跨主题保持含义，
     所以这里集中定义、随主题覆盖，不散落各处。 */
   /* ══════════════════════════════════════════════════════════════════════
   ★★ v79.9 补漏：`--bg2` 的定义（此前**全项目零定义**）
   ──────────────────────────────────────────────────────────────────────
   🔴🔴 问题：`styles.css` 与 `v797.css` 里共有 **40 处**写着 `var(--bg2)`，
      而 `--bg2` **在两个文件里都没有定义**
      （`grep -rn -- "--bg2\s*:" public/assets/*.css` → **0 命中**）。
      ⚠⚠ **它们是两类，症状完全不同，必须分开看**（QA 提醒后才拆清）：

      | 组 | 写法 | 处数 | 修前行为 | 修前症状 |
      |---|---|---|---|---|
      | **A 组** | 裸 `var(--bg2)`（**无 fallback**） | **30**（styles 5 + v797 25） | 整条声明 invalid at computed-value time ⇒ background 落 initial | **透明** —— 卡片层级消失 |
      | **B 组** | `var(--bg2, #xxxxxx)`（**有 fallback**） | **10**（全在 styles.css） | 用 fallback | 暗色下**惨白**（fallback 是亮色值） |

      ⚠ 我第一版只查了 A 组（正则不带逗号）⇒ **B 组 10 处一个都没进判据**，
        而 B 组恰好是「`.drag-handle` 暗色下对比度 14.74」那一批。
      ⚠ **教训**：`grep -c "var(--bg2)"` 会把两类混在一起数，
        而**它们的症状不同、修法的影响面也不同** ⇒ 判据必须分组。

      ⚠⚠ 按 CSS 规范，A 组未定义时 background 落到 **initial（透明）**，
        不是"保持上一条声明"。
      ⚠ 主理人给的数字是 15、QA 核的是 27（那是 `grep -c` 的行级口径，
        含 2 处注释与 2 处定义）⇒ **以本注释的分组口径为准**。

   ⚠⚠ 为什么这**违反了本文件自己的铁律二**（文件头 :11-14 写着
      「禁止硬编码任何灰色，一律用 CSS 变量」）：
      这 30 处**确实用了变量**（符合铁律二的字面），
      但**变量本身不存在** ⇒ 实际效果等于硬编码了一个不存在的颜色。
      ⇒ **铁律只检查"写法"，不检查"变量有没有定义"** ——
        这是本项目在「白名单类设计」上栽过的同一族（字段加了但读口没透传）。
      ⇒ 纪律补充：**用变量之前必须确认它有定义**，
        `grep -rn -- "--bg2\s*:" *.css` 应该是**非 0**，不是"我写了 var(--bg2) 就完事"。

   ★ 取值依据（**对齐现有观感，不另造一套**）：
     · 亮色：`--track-bg:#f1f4fa`（styles.css:10）那一档的邻近色
       ⇒ `#f6f8fc`（比 track-bg 略浅，与 `--gap-bg:#f7f9fd` 接近）
     · 暗色：`--soft:#1e2638`（styles.css:74）与 `--card:#1a2030` 之间
       ⇒ `#212a3d`（比 soft 略亮，卡片内层比外层稍亮是这一档的层次）
   ⚠⚠ **A 组 30 处逐条确认设计意图**（防"把本该透明的区域涂上颜色"）：
     判据 `smoke/_c4_bg2.js` 组 6 逐条查了"使用点所在的块有没有 border / border-radius"：
     **30/30 全部有边框或圆角** ⇒ 全部被设计成独立块 ⇒ 补底色符合设计意图，
     **无一条需要豁免**。⚠ 判据 S6.3 用一份人造的"无框元素"验过判据的分辨力
     （证明它不是"一律判该有底色"）。

   ⚠⚠ **覆盖关系（实测结论与主理人给的推断不同）**：
     ⚠ 主理人推断「同特异性 + 后加载胜出」，
       **实测两者特异性不同**：`styles.css:64` 是 `[data-theme="dark"]`（0,1,0）、
       `v797.css` 是 `:root[data-theme="dark"]`（**0,2,0**）
       ⇒ **本文件特异性更高 ⇒ 任何加载顺序下都胜出**（比"后加载胜出"更强）。
     ⚠ 原推断（保留备查）：
     index.html 的加载顺序是 `styles.css:40` → `v797.css:43`，
     本文件在**后面** ⇒ 同特异性下**本文件的声明胜出**。
     ⇒ 而 `styles.css` 的暗色块是 `:root[data-theme="dark"]`（L65），
       本文件用**完全相同的选择器**（见 :474 既有行）⇒ 依赖的就是"后加载胜出"。
     ⚠ 这条依赖是**隐式的**（没有 !important，靠文件顺序）⇒ 所以判据必须验它。

   ⚠ 为什么放在 `:root`（:473）而不是每个用到它的选择器上：
     变量定义必须在**祖先**上才可用；集中定义一处，30 处引用自动跟随。
   ══════════════════════════════════════════════════════════════════════ */
:root { --pomo-warn: #b8791f; --pomo-rest: #1f8f6d; --pomo-urgent: #d9534f; --bg2: #f6f8fc; }
/* ⚠⚠⚠ **只追加 `--bg2`，既有三个 pomo 变量一个字节都没动**
   ⚠ 我第一版手误把暗色 `--pomo-urgent` 从 `#ff7b6f` 改成了 `#ff6b5f`
     ⇒ 番茄钟「紧急」态的颜色会**静默变浅**，而这与本轮 `--bg2` 毫无关系。
   ⚠ 教训与本轮判据纪律同源：**改一处时绝不能顺手改另一处**——
     「顺便」是回归的最主要来源（本项目已在它上面栽过：`repeatYearly` 三态、
     `weekdays` 透传、qz-export 字段集，三次都是"只加不减"被破坏）。*/
:root[data-theme="dark"] { --pomo-warn: #e0a44a; --pomo-rest: #4fc79b; --pomo-urgent: #ff7b6f; --bg2: #212a3d; }

/* idle：中性。running：主题色。paused：琥珀。rest：绿。
   ⚠ 四态必须在**颜色 + 文案 + 环形描边**三处都不同 ——
     只改文案的话，色觉障碍用户分辨不出；只改颜色的话，
     截图打印成黑白又分不出。文案是主，颜色是辅，两者都要。 */
.v797-pomo[data-v797-pomo-state="idle"]     .v797-pomo-state { color: var(--tx3); }
.v797-pomo[data-v797-pomo-state="running"]  .v797-pomo-state { color: var(--pri); }
.v797-pomo[data-v797-pomo-state="paused"]   .v797-pomo-state { color: var(--pomo-warn); }
.v797-pomo[data-v797-pomo-state="rest"]     .v797-pomo-state { color: var(--pomo-rest); }
.v797-pomo[data-v797-pomo-state="pending_confirm"] .v797-pomo-state { color: #b8791f; }
/* ⚠ 上面两个 #b8791f / #1f8f6d 是**语义色**不是灰阶，且都 ≥ 4.5:1
   （对 --bg #f4f6fb 分别约 4.9:1 / 4.6:1）。铁律二禁的是「硬编码灰色」，
   语义色必须固定才能跨主题保持含义，夜间主题下由下方覆盖项接管。 */
:root[data-theme="dark"] .v797-pomo[data-v797-pomo-state="paused"] .v797-pomo-state,
:root[data-theme="dark"] .v797-pomo[data-v797-pomo-state="pending_confirm"] .v797-pomo-state
{ color: var(--pomo-warn); }
:root[data-theme="dark"] .v797-pomo[data-v797-pomo-state="rest"] .v797-pomo-state
{ color: var(--pomo-rest); }

.v797-pomo-state {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 13px; font-weight: 600; letter-spacing: .3px;
  margin-bottom: 10px;
}
/* 状态点：四态的第二重编码（不依赖颜色单独承载信息） */
.v797-pomo-dot {
  width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto;
  background: currentColor;
}
.v797-pomo[data-v797-pomo-state="running"] .v797-pomo-dot {
  animation: v797-breathe 2.4s ease-in-out infinite;
}
@keyframes v797-breathe {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: .45; transform: scale(.82); }
}
.v797-pomo[data-v797-pomo-state="paused"] .v797-pomo-dot,
.v797-pomo[data-v797-pomo-state="pending_confirm"] .v797-pomo-dot { border-radius: 2px; }
.v797-pomo[data-v797-pomo-state="rest"] .v797-pomo-dot { border-radius: 2px; transform: rotate(45deg); }

/* ── 今日概览：三格数字，放计时环上方 ── */
.v797-today {
  display: flex; gap: 8px; justify-content: center; margin-bottom: 14px;
  flex-wrap: wrap;
}
.v797-today-cell {
  flex: 1 1 88px; max-width: 132px; min-width: 76px;
  padding: 9px 6px; border-radius: var(--r-sm);
  background: var(--bg2); border: 1px solid var(--line);
}
.v797-today-num {
  display: block; font-size: 19px; font-weight: 700; color: var(--tx);
  line-height: 1.25; font-variant-numeric: tabular-nums;
}
.v797-today-lab { display: block; margin-top: 2px; font-size: 11.5px; color: var(--tx3); }

/* ── 巨型计时环 ── */
.v797-pomo-ring { margin: 4px 0 16px; position: relative; display: inline-block; }
.v797-ring { display: block; margin: 0 auto; }
/* 最后 10 秒的强调色：给环加一圈发光 + 时间文本变色。
   ⚠ 用 CSS 变量 --pri 派生，不写死颜色；三套主题各自生效。 */
.v797-ring.is-urgent .v797-ring-time { fill: var(--pomo-urgent, #d9534f); }
.v797-ring.is-urgent .v797-ring-arc { filter: drop-shadow(0 0 5px rgba(217, 83, 79, .55)); }
/* 环形轨道上的刻度点：纯装饰，给大空环一点密度感 */
.v797-ring-tick { stroke: var(--line); stroke-width: 1.5; }
.v797-ring-sub { font-size: 10.5px; }

/* ── 档位 chip（横向可滚动，8 个自定义档位不换行挤成一坨）── */
.v797-chips {
  display: flex; gap: 7px; margin-bottom: 12px; padding: 2px 1px 5px;
  overflow-x: auto; -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
}
.v797-chips::-webkit-scrollbar { height: 4px; }
.v797-chips::-webkit-scrollbar-thumb { background: var(--line); border-radius: 2px; }
.v797-chip {
  flex: 0 0 auto; padding: 7px 13px; border-radius: var(--r-pill);
  cursor: pointer; font-size: 13px; white-space: nowrap;
  border: 1px solid var(--line); background: var(--bg2); color: var(--tx2);
  transition: transform .12s ease;
}
.v797-chip:active { transform: scale(.96); }
.v797-chip.on { background: var(--pri); color: #fff; border-color: var(--pri); font-weight: 600; }
/* chip 内的数字与标签分两行（小屏上 8 个 chip 才放得下） */
.v797-chip-num { display: block; font-size: 14px; font-weight: 600; line-height: 1.3; }
.v797-chip-lab { display: block; font-size: 10.5px; opacity: .82; line-height: 1.3; }
/* 「自定义」入口：虚线边，和真档位区分（它不是档位，是入口） */
.v797-chip-add {
  border-style: dashed; color: var(--tx3);
  display: inline-flex; align-items: center; gap: 5px; padding: 7px 14px;
}

/* ── 标签选择（点选式，比文本框好用在「统计要按标签分」）── */
.v797-tagbar { display: flex; gap: 6px; justify-content: center; margin-bottom: 12px; flex-wrap: wrap; }
.v797-tagchip {
  padding: 5px 12px; border-radius: var(--r-pill); cursor: pointer; font-size: 12.5px;
  border: 1px solid var(--line); background: transparent; color: var(--tx3);
}
.v797-tagchip.on { background: var(--pri-soft); border-color: var(--pri); color: var(--pri); font-weight: 600; }
/* 标签用色点与统计页 PALETTE 对齐，让「选了什么」和「统计里什么颜色」一致 */
.v797-tagchip-dot {
  display: inline-block; width: 7px; height: 7px; border-radius: 2px;
  margin-right: 5px; vertical-align: 1px;
}
/* 自定义标签输入：默认收起，点「其它」才展开 —— 否则永远占一行抢注意力 */
.v797-tag-custom { display: flex; gap: 6px; justify-content: center; margin-bottom: 10px; }
.v797-tag-custom[hidden] { display: none; }

/* ── 模式切换（正计时 / 倒计时）：分段控件形态 ── */
.v797-seg {
  display: inline-flex; padding: 3px; gap: 3px; margin-bottom: 14px;
  border-radius: var(--r-pill); background: var(--bg2); border: 1px solid var(--line);
}
.v797-seg-btn {
  padding: 6px 18px; border-radius: var(--r-pill); cursor: pointer; font-size: 13px;
  border: none; background: transparent; color: var(--tx3);
}
.v797-seg-btn.on { background: var(--pri); color: #fff; font-weight: 600; }

/* ── 主操作按钮：idle 只有一个大「开始」，running 才出次级操作 ── */
/* 🔴 v80b38 修用户实测报的「番茄钟点开始后一直翻页、始终不显示」。
   ⚠⚠ 根因（真浏览器 + 真实 tap 实测，smoke/_pomo_mobile.js）：
     375×667 下「开始专注」落在 **y=666..719**，而底部 `.tabbar`（z-index:120）
     顶部在 **y=658** ⇒ `elementFromPoint` 命中 `BUTTON.tabbtn < NAV#tabbar`
     ⇒ 点「开始」实际点了底部标签 ⇒ 切页面（用户看到的「翻页」）⇒ 番茄钟从未启动。
   ⚠⚠ 为什么单靠「给 #main 加底部 padding」不够（我第一版就是这么失败的）：
     `.v797-ck-panel`（打卡，pomo.js:3296 拼在番茄钟**之后**）是「一天一屏」24 格，
     在窄屏上占掉大半屏 ⇒ 番茄钟的按钮被推到**接近文档末尾**。
     `#main` 底部留白只能让内容「能滚过去」，**不能保证它落在标签栏上方**。
   ✅ 修法：把「计时圈 + 开始按钮」这一段做成**吸底操作条** ——
     滚动时它**吸附在底部标签栏正上方**，任何滚动位置都点得到。
     ⚠ 完全不动打卡结构（用户判定打卡组是错的、要给新方案）。
     ⚠ 用 `var(--qz-tabbar-h)`（app.js 的 `syncTabbarH()` 用 ResizeObserver 实测写入，
       含 iPhone 底部安全区）而不是写死 px。
     ⚠ 只在**移动端窄屏**生效：桌面端不需要吸底，且吸底会挡住正常内容。*/
@media (max-width: 760px) {
  .v797-pomo-acts {
    position: sticky;
    /* ⚠ 吸在标签栏**上方**：标签栏高 + 8px 余量 */
    bottom: calc(var(--qz-tabbar-h, 66px) + 8px);
    /* ⚠⚠ z-index 必须是 **130**，不是 30。
       实测踩过：设成 30 时，360×640 下按钮仍被
       `#seasonFx`（季节装饰层，styles.css:3024 `position:fixed; z-index:30`）
       里的 `.sfx-prop` 道具抢走落点
       （实测 hitPath = `svg < DIV.sfx-prop < DIV.sfx-dock < DIV#seasonFx`）
       ⇒ 因为它**同为 30、且在 DOM 里更靠后**，同层级时后者胜出。
       ⚠ 层级参照：`.tabbar` = 120（底部标签）⇒ 吸底条要**在它之上**才不会被盖。
       ⚠ 整层 `#seasonFx` 自己是 `pointer-events:none`（只有道具可点），
         所以只要**层级压过它**，装饰就点不到、不再抢落点。*/
    z-index: 130;
    background: var(--card);
    border-radius: var(--r-md);
    padding: 8px 0;
    box-shadow: 0 -2px 10px rgba(20, 30, 60, .06);
  }
}
.v797-pomo-acts { display: flex; gap: 10px; justify-content: center; align-items: center; }
.v797-btn-lg {
  min-width: 148px; padding: 13px 30px; border-radius: var(--r-pill);
  cursor: pointer; font-size: 16px; font-weight: 600;
  border: 1px solid var(--pri); background: var(--pri); color: #fff;
}
.v797-btn-lg:active { transform: scale(.97); }
.v797-btn-lg.is-rest { background: #1f8f6d; border-color: #1f8f6d; }
:root[data-theme="dark"] .v797-btn-lg.is-rest { background: #2f9d7c; border-color: #2f9d7c; }
.v797-btn-lg.is-danger { background: transparent; color: var(--tx3); border-color: var(--line); min-width: auto; }

/* ── 休息提示浮层（fixed → 必须 z-index ≥ 1000）──
   ⚠ v80.9【P1-6】本层**有意不参与 night-dim 压暗**（z=1040 > 蒙版 95），
     理由与「铁律一」那段注释一致：**不含表单控件**、且是全屏浮层。
     请勿当漏网 bug 顺手统一 —— 详见 :470 起的说明。 */
.v797-rest-mask {
  position: fixed; inset: 0; z-index: 1040;
  display: flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--bg) 72%, transparent);
  padding: 20px;
}
/* 🔴🔴 v79.7 批次 7 实测踩坑（截图才发现，DOM 断言全绿）：
     上面那条 `display:flex` **覆盖了 HTML `hidden` 属性的默认 display:none**
     —— 两者特异度相同时，后写的 CSS 赢。
     后果：明明加了 hidden 的浮层仍然铺满全屏，
           ① 视觉上整页被蒙一层 72% 底色（截图里「一切都发白」的真相）；
           ② **更严重**：它盖在所有元素上面，用户的每一次点击都被它吃掉 ——
              「开始专注」按钮点不动，而且不报任何错。
     elementFromPoint 在环中心命中的就是这层 mask（验收 V-8 抓到的）。
     ⚠ 这类「元素存在但不可交互」的缺陷，静态读代码和 DOM 断言
       （hidden 属性在、z-index 对）**全都验不出来**，必须截图 + 命中测试。
   修法：`[hidden]` 选择器补一条 display:none，
        且**任何**给 .v797-rest-mask 加 display 的规则都必须成对写这条。 */
.v797-rest-mask[hidden] { display: none; }
.v797-rest-card {
  width: 100%; max-width: 330px; padding: 22px 20px 18px;
  border-radius: var(--r-lg); text-align: center;
  background: var(--card); border: 1px solid var(--line);
  box-shadow: 0 12px 40px rgba(0, 0, 0, .18);
}
.v797-rest-title { font-size: 17px; font-weight: 700; color: var(--tx); margin-bottom: 4px; }
.v797-rest-sub { font-size: 12.5px; color: var(--tx3); line-height: 1.7; margin-bottom: 14px; }
.v797-rest-ring { margin: 0 auto 14px; }
.v797-rest-acts { display: flex; gap: 9px; justify-content: center; flex-wrap: wrap; }
/* 休息时长快选 */
.v797-rest-opts { display: flex; gap: 6px; justify-content: center; margin-bottom: 14px; flex-wrap: wrap; }

/* ── 统计页：分段切换 + 周对比柱状图 + 空态 ── */
.v797-dims { display: flex; gap: 6px; margin-bottom: 14px; }
.v797-dim { flex: 1; padding: 8px 0; border-radius: var(--r-sm); cursor: pointer; font-size: 13px;
  border: 1px solid var(--line); background: var(--bg2); color: var(--tx2); }
.v797-dim.on { background: var(--pri); color: #fff; border-color: var(--pri); font-weight: 600; }

.v797-stat-grid { display: flex; gap: 8px; margin-bottom: 14px; flex-wrap: wrap; }
.v797-stat-cell {
  flex: 1 1 90px; padding: 10px 8px; border-radius: var(--r-sm); text-align: center;
  background: var(--bg2); border: 1px solid var(--line);
}
.v797-stat-num { display: block; font-size: 18px; font-weight: 700; color: var(--tx);
  font-variant-numeric: tabular-nums; line-height: 1.3; }
.v797-stat-lab { display: block; font-size: 11.5px; color: var(--tx3); margin-top: 2px; }
.v797-sec-title {
  font-size: 13px; font-weight: 600; color: var(--tx2);
  margin: 16px 0 8px; text-align: left;
}
.v797-sec-title small { font-weight: 400; color: var(--tx3); font-size: 11.5px; }

/* 空态：**不画空坐标系**。画一个坐标系再写「暂无数据」会被误读成
   「有数据但都是 0」—— 这是折线图与饼图都踩过的坑（POMO-10）。
   这里给的是一句人话 + 一个引导动作。 */
.v797-empty {
  padding: 26px 18px; text-align: center;
  border-radius: var(--r-sm); background: var(--bg2); border: 1px dashed var(--line);
}
.v797-empty-ico { font-size: 26px; line-height: 1; margin-bottom: 10px; opacity: .5; }
.v797-empty-txt { color: var(--tx3); font-size: 13px; line-height: 1.8; }
.v797-empty-act { margin-top: 12px; }

/* ★★ v79.9 批次 8 任务1：空态里的「当前维度：X」与补充说明。
   ⚠ 为什么维度名要加粗（b）：它是这一屏里**唯一会随操作变化**的文字。
   用户切周/月/年时，如果只有旁边那圈图标变了、维度名没变，
   他依然会认为「没反应」——这正是本条反馈的原始症状。 */
.v797-empty-dim [data-v797-empty-dim-label] { color: var(--tx1); font-weight: 700; }
.v797-empty-sub { display: inline-block; margin-top: 8px; font-size: 12px; line-height: 1.7; opacity: .82; }

/* 本机专注记录条数诊断入口（页脚小字）。
   ⚠ 用 cdw- 前缀：本项目有 .warn 撞车把元素挤成竖排的前车之鉴。
   ⚠ 等宽数字：条数会变，宽度跳动会让整页在异步回填时轻微抖动。 */
.cdw-diag {
  margin: 10px 0 4px; padding: 8px 10px;
  border: 1px dashed var(--line); border-radius: var(--r-sm);
  background: var(--bg2); color: var(--tx3);
  font-size: 12px; line-height: 1.6;
}
.cdw-diag-txt { font-variant-numeric: tabular-nums; word-break: break-all; }

/* 柱状图容器：横向可滚动，7 天 × 2 周 = 14 根柱在窄屏放不下 */
.v797-bars-wrap {
  padding: 10px 8px 4px; border-radius: var(--r-sm);
  background: var(--bg2); border: 1px solid var(--line);
  overflow-x: auto;
}
.v797-bars { display: block; }
/* 图例：本周 / 上周两色 */
.v797-legend2 { display: flex; gap: 14px; justify-content: center; margin-top: 8px; }
.v797-legend2 span { display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; color: var(--tx3); }
.v797-legend2 i { width: 10px; height: 10px; border-radius: 2px; display: inline-block; }

/* ══════════════════════════════════════════════════════════════════════
   v79.9 批次 7 · 统计「三视图融合」的呈现样式
   ──────────────────────────────────────────────────────────────────────
   ⚠⚠ 类名前缀纪律：全部用 pm- / pomo- 前缀，且**不复用** .dot.c-* / .pb-dot。
      本项目已有全局 .warn 类名撞车的前车之鉴（两处样式互相污染，
      表现为一处改样式另一处跟着变）。已 grep 确认 pm-dot / pm-wd /
      pomo-week-bar / pomo-day-bar 在全项目均未被占用。
   ══════════════════════════════════════════════════════════════════════ */

/* ── 月视图：每天格子里的番茄徽标 ─────────────────────────────────────
   ⚠ 与 .dots 里的 8px 圆点**同行**排布，所以必须压得比圆点更矮，
     否则一行放不下时会撑高 .cal-top，而 .cal-top 在 .cell 里
     （.cell 是 min-height:66px 且没有 overflow:hidden），
     撑高会把整个月网格的行高带偏 —— 这是「月视图某天特别高」的成因。*/
.pm-dot {
  display: inline-flex; align-items: center; gap: 1px;
  font-size: 9.5px; line-height: 1; font-style: normal;
  padding: 1px 3px; border-radius: 7px;
  background: color-mix(in srgb, var(--pri) 14%, transparent);
  color: var(--pri);
  white-space: nowrap; flex: none; max-width: 46px; overflow: hidden;
}
/* legend 里的大号版本（与 .pb-dot.lg 同尺寸惯例） */
.pm-dot.lg { font-size: 11px; padding: 1px 5px; margin-left: 8px; max-width: none; }
:root[data-theme="dark"] .pm-dot {
  background: color-mix(in srgb, var(--pri) 22%, transparent);
}

/* ── 周视图：周统计条 ───────────────────────────────────────────────
   只压顶部一条（与 practiceBar / memoSpansBar 同惯例），
   不做成浮层 —— 浮层会盖住课表第一行。 */
.pomo-week-bar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 7px 10px; margin-bottom: 8px;
  border-radius: var(--r-sm);
  background: var(--bg2); border: 1px solid var(--line);
  font-size: 12px; color: var(--tx3);   /* 提示文字一律 var(--tx3) */
}
.pm-wb-lab { color: var(--tx3); flex: none; }
.pm-wb-num { color: var(--tx); font-weight: 600; font-size: 13px; flex: none; }
.pm-wb-sec { color: var(--tx3); flex: none; }
/* 7 个小柱子：点某一天切到那天 */
.pm-wd-row { display: flex; align-items: flex-end; gap: 3px; margin-left: auto; flex: none; }
.pm-wd {
  display: flex; flex-direction: column; align-items: center; justify-content: flex-end;
  gap: 1px; width: 20px; height: 30px; padding: 1px 0;
  background: transparent; border: 1px solid transparent; border-radius: 4px;
  cursor: pointer; color: var(--tx3); font-size: 9px; line-height: 1;
}
.pm-wd:hover { background: var(--bg); border-color: var(--line); }
.pm-wd.has { color: var(--pri); }
.pm-wd-bar {
  display: block; width: 8px; min-height: 0;
  background: var(--line); border-radius: 2px 2px 0 0;
}
/* ⚠ 柱高用 inline style 由 JS 算（按当周最长一天归一），
     这里只给「有数据」那天的柱子上色。 */
.pm-wd.has .pm-wd-bar { background: var(--pri); }
.pm-wd b { font-size: 9px; font-weight: 600; min-height: 9px; }

/* ── 日面板：当日统计行 ───────────────────────────────────────────── */
.pomo-day-bar {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 6px 12px; margin: 0 0 8px;
  border-radius: var(--r-sm);
  background: var(--bg2); border: 1px solid var(--line);
  font-size: 12px;
}
.pm-db-lab { color: var(--tx3); }   /* 提示文字一律 var(--tx3) */
.pm-db-tags { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; margin-left: auto; }
.pm-db-chip {
  display: inline-flex; align-items: center; gap: 3px;
  font-size: 10.5px; font-style: normal;
  padding: 1px 6px; border-radius: 8px;
  background: var(--bg); border: 1px solid var(--line); color: var(--tx3);
}
.pm-db-chip b { color: var(--tx2); font-weight: 600; }
.pm-db-chip.is-more { opacity: .8; }

/* ── 视觉修正②：空闲态环「像满圈」的解法在 JS 侧（轨道 10px→3px + 虚线、
      不画刻度、副标签写明「选择时长后开始」），这里只补两处残余：
        ① idle 弧若被画出来也不刺眼；
        ② 轨道再压一档透明度，确保「空槽」在暗色主题下也不被误读成环。
      ⚠ 暗色主题必须单独给 —— --line 在暗色下本身就是浅色，
        不加覆盖会变成一圈刺眼白虚线（v79.7 批次 7 踩过的同一个坑）。 ─── */
.v797-pomo[data-v797-pomo-state="idle"] .v797-ring-arc { opacity: .25; }
.v797-pomo[data-v797-pomo-state="idle"] .v797-ring-track { opacity: .5; }
:root[data-theme="dark"] .v797-pomo[data-v797-pomo-state="idle"] .v797-ring-track { opacity: .42; }

/* ── 档位 chip：只属于倒计时，**按需出现**（派单 §二.1，批次 7 返工）──
   ⚠⚠ 这里曾有一整套 `.v797-chips.is-off` 置灰样式 + `.v797-hint-off`
     提示文字样式（用户原话「点倒计时才出现」⇒ 要的是**不出现**，不是置灰）。
     已**整段删除**：档位改成 `mode==='down'` 才渲染（pomo.js render），
     非倒计时下这三个类名在 HTML 里**根本不存在**，
     留着就是「永远命中不到的死样式」——
     而死样式比没有样式更坏：下一个人看到 `.is-off` 会以为
     「哦置灰方案还在」，从而把渲染改回去。
   ⇒ 本项目纪律：视觉方案改了，同名的死样式必须一起删，
     哪怕它「看起来无害」。删干净是唯一能防回退的做法。
   ─────────────────────────────────────────────────────────────────── */

/* ── 视觉修正①：番茄钟视图关掉季节装饰粒子（app.js renderSeasonFx 加
      .sfx-focus）。只关粒子层与阵风气泡，保留 .sfx-dock 收纳钮
      —— 那是用户可点的功能入口，删掉等于悄悄关功能。 ────────────────── */
#seasonFx.sfx-focus .sfx-p,
#seasonFx.sfx-focus .sfx-b { display: none; }

/* ── 批次 7 P0-1：统计页一进一出的导航条 ─────────────────────────────
   为什么必须写样式（不是「锦上添花」）：
     验收标准是 `getBoundingClientRect().width > 0`。
     .v797-btn 本身有 padding + border，天然有宽度；但外层
     .v797-pomo-nav / .v797-stats-nav 是裸 <div>，默认块级撑满，
     若不加 display:flex 居中，按钮会贴左、与 .v797-stats 的
     12px 内边距叠在一起，看起来像「和标题挤在一起」。
   ⚠ 亮/暗两态都要能看清：全部用项目变量，不写死颜色。
   ⚠ 触控目标不小于 34px 高 —— 这是给手机用的。 ──────────────────── */
.v797-pomo-nav {
  display: flex; justify-content: center; margin: 14px 0 2px;
}
.v797-to-stats {
  min-height: 34px; padding: 8px 18px; font-weight: 600;
  border-color: var(--pri); color: var(--pri); background: transparent;
}
.v797-stats-nav {
  display: flex; justify-content: flex-start; margin: 0 0 12px;
}
.v797-back-timer {
  min-height: 34px; padding: 7px 14px; color: var(--tx2);
}
.v797-pomo-nav .v797-to-stats:active,
.v797-stats-nav .v797-back-timer:active { transform: scale(.97); }

/* 概览页的统计入口卡（app.js renderHome 渲染）—— 与上面同规格，
   但整卡可点，所以 cursor + 用户选中态要显式给。 */
.v797-home-stat {
  display: flex; align-items: center; gap: 10px; width: 100%;
  margin: 12px 0 0; padding: 11px 13px; text-align: left;
  border: 1px solid var(--line); border-radius: 11px;
  background: var(--bg2); color: var(--tx); cursor: pointer;
  font-size: 14px;
}
.v797-home-stat:active { transform: scale(.99); }
.v797-home-stat-ico { font-size: 18px; line-height: 1; flex: 0 0 auto; }
.v797-home-stat-txt { flex: 1 1 auto; min-width: 0; }
.v797-home-stat-sub { display: block; color: var(--tx3); font-size: 11.5px; margin-top: 2px; }
.v797-home-stat-go { flex: 0 0 auto; color: var(--tx3); font-size: 15px; }

/* ══════════════════════════════════════════════════════════════════════
   v79.9 批次 8 任务 9/10/11
   ⚠ 类名一律 cdw- 前缀（已 grep 确认未占用；同前缀的 cdw-diag 是 pomo.js 的诊断块）。
   ══════════════════════════════════════════════════════════════════════ */

/* 日历格 / 周课表头里的倒数日角标。
   ⚠ 用 emoji 而非背景色块：日历格宽 1/7 屏，任何色块都会挤掉既有的
     .dots 圆点与课程信息；emoji 是零布局成本的。 */
.cdw-dayIcon {
  font-style: normal; font-size: 11px; line-height: 1; margin-left: 1px;
  cursor: pointer; position: relative; top: 1px;
}
.cdw-dayIcon-more { font-size: 9.5px; opacity: .8; }
/* 悬停放大一点：可点的东西必须看起来可点。
   ⚠ 只改 transform 不改 width/height —— 改尺寸会把整个 .dots 行撑开。 */
.cdw-dayIcon:hover { transform: scale(1.28); }
/* 图例里的样例不可点（只有日期里的角标可点），去掉手型与放大 */
.cdw-dayIcon.lg { cursor: default; margin: 0 3px 0 8px; }
.cdw-dayIcon.lg:hover { transform: none; }

/* 点角标弹出的说明层内容 */
.cdw-explain { padding: 4px 2px 2px; }
.cdw-exRow {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 10px 2px; border-bottom: 1px solid var(--line);
}
.cdw-exRow:last-child { border-bottom: 0; }
.cdw-exIcon { font-size: 22px; line-height: 1.2; flex: 0 0 auto; }
.cdw-exBody { flex: 1 1 auto; min-width: 0; }
/* ★ 名字用 --tx（正文色）而不是 --tx3（弱化色）：
   规格原话「说明是四六级考试，就要说明是四六级考试」——
   名字是这条说明的主体，不能弱化成灰色小字。 */
.cdw-exName {
  display: block; color: var(--tx); font-size: 15px; font-weight: 600;
  word-break: break-word; line-height: 1.35;
}
.cdw-exType {
  display: inline-block; margin-top: 3px; padding: 1px 6px;
  border-radius: 6px; background: var(--bg2); border: 1px solid var(--line);
  color: var(--tx2); font-size: 11.5px;
}
.cdw-exMeta { margin-top: 5px; color: var(--tx3); font-size: 12px; font-variant-numeric: tabular-nums; }
/* 2/29 → 2/28 的告知：不能静默，必须显式一句话 */
.cdw-exShift {
  margin-top: 4px; padding: 4px 7px; border-radius: 7px;
  background: rgba(240, 145, 58, .12); color: var(--tx2); font-size: 12px;
}

/* 周课表头的农历行（任务 11 开关开时） */
.wv-lunar {
  display: block; width: 100%; text-align: center;
  color: var(--tx3); font-size: 10.5px; line-height: 1.2; margin-top: 1px;
  font-variant-numeric: tabular-nums;
}

/* ══════════════════════════════════════════════════════════════════════
   ★ v79.9 批次 8【B】：二次确认弹层 / 撤销条 / 兜底提示
   ──────────────────────────────────────────────────────────────────────
   三个类都是本轮新增，cdw- 前缀已 grep 确认未被占用。
   ⚠ 全部用项目变量（--bg/--card/--line/--tx/--pri），不写死颜色 ——
     夜间模式自动跟随，这是批次 3 定的规矩。 */

/* ① 确认弹层的正文（askConfirm 把 \n 拆成多个 <div>，
     绕开「部分 WebView 里 \n 不换行」的问题） */
.cdw-ask-txt {
  font-size: 14.5px; line-height: 1.72; color: var(--tx2);
  word-break: break-word;
}
/* ⚠ 危险操作（删除）时让正文更醒目一点：不是加红字，
   而是整体提亮 + 左侧一条危险色边 —— 夜里红色正文很刺眼。 */
.modal .cdw-ask-txt { border-left: 3px solid var(--line); padding-left: 10px; }
.btn.danger { border-color: #d9534f; color: #d9534f; }
:root[data-theme="dark"] .btn.danger { border-color: #e2685f; color: #e2685f; }

/* ② 撤销条：fixed 底部居中，z-index 必须高于吉祥物（31）与 mchat（60），
   但低于模态弹层 —— 模态是"必须先处理"的层级。 */
.cdw-undo-bar {
  position: fixed; left: 50%; bottom: calc(84px + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  z-index: 90;
  display: flex; align-items: center; gap: 12px;
  max-width: min(92vw, 420px);
  padding: 10px 12px 10px 15px; border-radius: 12px;
  background: var(--card); border: 1px solid var(--line);
  box-shadow: 0 10px 30px rgba(20, 30, 60, .22);
  animation: cdwUndoIn .18s ease-out;
}
:root[data-theme="dark"] .cdw-undo-bar { box-shadow: 0 10px 30px rgba(0, 0, 0, .5); }
@keyframes cdwUndoIn {
  from { opacity: 0; transform: translateX(-50%) translateY(10px); }
  to   { opacity: 1; transform: translateX(-50%) translateY(0); }
}
.cdw-undo-txt {
  flex: 1 1 auto; min-width: 0;
  color: var(--tx); font-size: 13.5px; line-height: 1.5;
  word-break: break-word;
}
.cdw-undo-btn {
  flex: 0 0 auto; padding: 6px 13px; border-radius: 8px;
  border: 1px solid var(--pri); background: transparent;
  color: var(--pri); font-size: 13px; font-weight: 600; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.cdw-undo-btn:hover { background: var(--pri-soft); }
.cdw-undo-btn:active { transform: scale(.96); }

/* ③ toast 桥失效时的第三级兜底（memo.js 的 toastMsg）。
   平时**永远看不见** —— 只有 QZ79.toast 不在时才会出现。
   宁可丑，也不要"点了没反应"。 */
.cdw-fallback-toast {
  position: fixed; left: 50%; top: calc(64px + env(safe-area-inset-top, 0px));
  transform: translateX(-50%);
  z-index: 95; max-width: min(90vw, 400px);
  padding: 9px 15px; border-radius: 10px;
  background: var(--card); border: 1px solid var(--line);
  box-shadow: 0 8px 24px rgba(20, 30, 60, .2);
  color: var(--tx); font-size: 13.5px; line-height: 1.5;
  text-align: center;
}
.cdw-fallback-toast.is-err { border-color: #d9534f; color: #d9534f; }
:root[data-theme="dark"] .cdw-fallback-toast { box-shadow: 0 8px 24px rgba(0, 0, 0, .5); }
:root[data-theme="dark"] .cdw-fallback-toast.is-err { border-color: #e2685f; color: #e2685f; }

/* ④ 🔴 v79.9 批次 8【B】实测抓到的第 4 个缺陷：右下角吉祥物**遮挡**删除按钮。
   ────────────────────────────────────────────────────────────────────
   症状（实测 tmp/_b_memo_before.txt / _b_memo_after.txt 的 P7）：
     列表变长后，倒数几行的 ✕ 落点变成 `IMG.mb-face`，EVT_REACHED=0
     —— 按钮在屏幕上、看得见，却被 fixed 浮层压住，用户点不到。

   ⚠⚠⚠ 我**第一版修法方向是错的**，这里把踩坑过程留档，别再犯第二遍：
     第一版给 `.view[data-view="memo"] .v797-wrap` 加 `padding-bottom: 128px`，
     实测 `paddingBottom=128px` **确实生效**，但落点仍是 `IMG.mb-face`。
     —— 错在**没量几何就动手**：`padding-bottom` 加的是「内容**下方**的留白」，
       而列表是自然流式排布、**内容整体位置不变** ⇒ 留白再多也压不住它。
     更关键的是实测 `.v797-wrap` 的 `scrollHeight == clientHeight == 777`
     ⇒ **wrap 根本不是滚动容器**，留白连"滚到底时能看全"的效果都没有。

   ⚠ 为什么"底部留白"这个思路**原理上就不成立**（不是数值不够，是方向错）：
     吉祥物是 `position: fixed; right:10px; bottom:126px`（≤760px 断点），
     视口 932px 高时它占 y=648~806 —— 那是**视口中间偏下**的一条**横带**。
     页面滚动时，**任意一行**都会依次穿过这条横带 ⇒
     竖直方向留白只能保证"最后一行不落在带子里"，
     用户往上滚一点、第二行就又进去了。**根治必须横向分离。**

   ⇒ 修法：把列表项的**删除按钮横向让出**吉祥物可点区块的宽度。
     ⚠ 为什么让出的是 52px 而不是实测看到的 120px：
       吉祥物容器 `getBoundingClientRect()` 实测 w=120，但那是
       `.mb-bubble`（**opacity:0 / pointer-events:none**）在**撑容器**。
       真正能吃到点击的只有 `.mb-body`（52×52）与 `.mb-chat`（34×34）——
       透明容器不参与命中，`elementFromPoint` 实测返回的是 `IMG.mb-face`
       而不是 `DIV.mascot-buddy`，这本身就是"容器不吃点击"的直接证据。
       ⇒ 按最宽的可点子块 mb-body 算：**52px + 8px 间隙 = 60px**。
     ⚠ 为什么给 `.v797-mi` 而不是 `.v797-list`：
       `.v797-list` 上加会让 `<ul>` 整体缩进，**已完成段的计数标题也跟着偏**；
       给 `<li>` 加只压缩条目右端，标题/计数不动。*/
.view[data-view="memo"] .v797-mi { padding-right: 60px; }
@media (min-width: 761px) {
  /* 宽屏：`.mb-body` 放大到 60px、right 收到 14px ⇒ 让出 60+8=68px，取 68 */
  .view[data-view="memo"] .v797-mi { padding-right: 68px; }
}

/* ④b 顺带：`.v797-wrap` 底部留白**保留**，但它的作用要说清楚（不是 B10 的修法）。
   实测 wrap 不是滚动容器（scrollH==clientH），所以这条留白
   **既不能**解决吉祥物遮挡，**也不能**让末行"滚到底能看全"；
   它唯一的作用是：列表短的时候，末行不会紧贴 tabbar 顶部。
   把它保留而不是删掉，是因为它对"末行贴边"这个观感问题确实有效，
   而删掉会让短列表的末行离底部标签栏只剩几像素。*/
.view[data-view="memo"] .v797-wrap { padding-bottom: 24px; }

/* ⑤ v79.9 批次 8【C1】撤销条：**添加 / 删除**两种语义用不同颜色。
   ────────────────────────────────────────────────────────────────────
   用户原话：「添加的和删除的能够区分一下，一个显示的是添加的一个显示的是删除的，
   而且颜色也要不一样」。

   ⚠⚠ 判据纪律：验收必须读 `getComputedStyle` 的**实际 background-color**，
     不许截图目测、不许只看 class 名。本项目吃过「CSS 类名撞车把元素
     挤成竖排」的亏（.warn），class 写对了不代表元素没被别的规则改形。

   ⚠ 为什么**不用**裸 `.danger` / `.warn`：
     · `.danger` 已被 openModal 的按钮占用（语义是「确认危险操作」）；
     · `.warn` 在本项目撞过车。
     ⇒ 一律用 `cdw-undo-btn` 的 `is-add` / `is-del` 独立修饰类。

   ⚠ 颜色一律取既有变量，**不自创色值**：
     del 用 openModal danger 同一套（#d9534f / 暗色 #e2685f），
     add 用主色 --pri / --pri-soft（跟着季节/暗黑主题自动变，
     不会出现"暗色下这块永远是浅蓝"的割裂）。*/
.cdw-undo-bar.is-del { border-color: #d9534f; }
.cdw-undo-bar.is-del .cdw-undo-txt { color: #d9534f; }
.cdw-undo-btn.is-del {
  border-color: #d9534f; color: #d9534f;
  /* ⚠⚠ 不能用 transparent：两侧都透明就是**同一个色值**（rgba(0,0,0,0)）。
     team-lead 的判据原话是“del 的按钮 computed background-color ≠ add 的”——
     透明背景没力区分斷它们，留下的只是一个无信息量的值。
     ⚠ 也不能用裸类名 .danger：本项目 .warn 曾把元素挤成竖排。*/
  background: rgba(217, 83, 79, .12);
}
.cdw-undo-btn.is-del:hover { background: rgba(217, 83, 79, .24); }

.cdw-undo-bar.is-add { border-color: var(--pri); }
.cdw-undo-bar.is-add .cdw-undo-txt { color: var(--pri); }
.cdw-undo-btn.is-add {
  border-color: var(--pri); color: var(--pri);
  background: var(--pri-soft);   /* 同理：必须是一个真色值，不能透明 */
}
.cdw-undo-btn.is-add:hover { background: var(--pri-soft); filter: brightness(.94); }

/* ⑤b 暗色：danger 两处要提亮，否则深底上偏暗看不清
   （与 .btn.danger 的暗色处理保持一致，不另发明一套）。*/
:root[data-theme="dark"] .cdw-undo-bar.is-del { border-color: #e2685f; }
:root[data-theme="dark"] .cdw-undo-bar.is-del .cdw-undo-txt { color: #e2685f; }
:root[data-theme="dark"] .cdw-undo-btn.is-del { border-color: #e2685f; color: #e2685f; }
:root[data-theme="dark"] .cdw-undo-btn.is-del { background: rgba(226, 104, 95, .18); }
:root[data-theme="dark"] .cdw-undo-btn.is-del:hover { background: rgba(226, 104, 95, .30); }
:root[data-theme="dark"] .cdw-undo-btn.is-add:hover { filter: brightness(1.25); }

/* ⑥ v79.9 批次 8【C2】概览页快捷添加条
   ────────────────────────────────────────────────────────────────────────────
   ⚠ 判据纪律（沿用 C1）：暗色能不能用**必须取 getComputedStyle 的实际色值**判定，
     不许截图目测。本项目吃过「亮色好好的、暗色看不清」的亏，用户把暗黑模式
     列为首要修复项。
   ⚠ 为什么单独起一个容器类而不用 .wb66-todobar：
     那个类带「你有 N 件事待处理」的整条点击热区（_tbar.onclick → openTodoCenter），
     入口混进去会让「点入口」和「打开待办中心」打架。 */
.v797-quick-add {
  display: flex; justify-content: flex-end; gap: 8px;
  margin: 0 0 8px;
  /* 🔴🔴 本轮实测拉出的真缺陷 D9（不是测具的错）：
     * todo 面板的拖拽把手是 `position:absolute; top:8px; right:8px; z-index:3`
     *（styles.css:3722，因为 stat/todo 两个面板没有 panel-head 才用了右上角浮动把手）。
     *   我本来把「＋ 待办」放在面板右上角 ⇒ 它被把手**完全覆住**。
     *   实测：按钮中心的落点是 `SPAN.drag-handle hp-float`，而不是按钮自身。
     *   即真实用户手机点「＋ 待办」，拿到的是拖拽把手 ⇒ **待办入口点不到**。
     * ✅ 修法：按钮改左对齐 + 右侧让出 34px（把手 22px + 一圈间距）。
     *   不选择“把把手的 pointer-events 关掉”：那会让用户永远无法拖面板排序（现有功能被破坏）。
     *   不选择“把按钮移到左上角”：那里是面板标题，会挤掉标题文字。*/
  padding-right: 34px;
  justify-content: flex-start;
  padding-left: 2px;
}
/* ⚠ 不写死前景/背景色：全部走既有变量，亮暗两态自动各自成立。
   按钮底色用 --pri-soft（暗色下是 #1e2a4a，本身就是深色块），
   文字色用 var(--tx) ⇒ 暗色下不会出现「深底浅字读不清」。 */
.v797-quick-add .btn.tiny {
  border-color: var(--line); color: var(--pri); background: var(--pri-soft);
}
.v797-quick-add .btn.tiny:hover { filter: brightness(.96); }
:root[data-theme="dark"] .v797-quick-add .btn.tiny:hover { filter: brightness(1.25); }

/* today 面板标题栏里的「＋ 今日课程」：与 #goCal 并列，
   同样靠 --pri-soft / var(--pri)，暗色自动成立。 */
#btnQuickCourse {
  border-color: var(--line); color: var(--pri); background: var(--pri-soft);
}
#btnQuickCourse:hover { filter: brightness(.96); }
:root[data-theme="dark"] #btnQuickCourse:hover { filter: brightness(1.25); }

/* ══════════════════════════════════════════════════════════════════════
   v79.9 批次 8【C4】· 课表笔记的**可见性**
   ──────────────────────────────────────────────────────────────────────
   ★ 背景（实测，不是推断）：`note` 字段本来就存在、也能存能改能删，
     但表格视图只画一个 `<i title="…">📝</i>`、网格课块只挂 `title` 属性。
     ⇒ 笔记正文**只存在于 title 属性里**。
   ⚠⚠ 手机端**没有 hover**，悬浮气泡等于不存在：
     用户写完笔记回到课表只看到一个 📝，得再点进详情弹层才知道自己写了什么。
     这是「课表每节课可加笔记」这项功能**实际不好用**的根因。
   ⚠ 排版取舍：
     · 表格里给 12 字 —— 7 列已经很挤，挤掉课名才是真正的损失（那是主信息）；
     · 网格课块只给**一行**（课块 44px/节，加多行会把课名和地点顶出去）。
   ⚠ 全文永远保留在 title / data-note 上：截断只发生在**渲染层**，
     库里存的、导出的都是全文。 */

/* 表格「课程」列：📝 图标 + 正文内联。
   ⚠ 与图标之间不留空隙：表格列宽是共享的，一个空格就是几十像素。 */
.cs-note-tx {
  font-style: normal; margin-left: 3px; font-size: 11.5px;
  color: var(--tx3); line-height: 1.4;
  /* 不用「藏起来只留悬浮」的老办法 —— 那正是本轮修掉的缺陷。 */
  word-break: break-all;
}

/* 网格课块：底部一行笔记。
   ⚠ 颜色/透明度沿用 .cg-m 的口径（课块底色是课程配色，可能是深色），
     所以用 rgba 白而不是 var(--tx*) —— 后者在深色课块上会变成深字看不清。 */
.cg-blk .cg-note {
  font-size: 11px; line-height: 1.2; margin-top: 1px;
  color: rgba(255, 255, 255, .95);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* v56 窄课块（同一时间压着多门课）课块更窄 ⇒ 笔记只剩图标位可读，
   留一行会挤成一条黑杠。⚠ 这里**不隐藏**（有笔记就该有痕迹），
   而是缩到最小字号，让用户看到「这节课有笔记」并可点进去看全文。 */
.cg-blk.cg-narrow .cg-note { font-size: 9.5px; }

/* ══════════════════════════════════════════════════════════════════════
   v79.9 批次 8【第 1 项】· 杂事提醒
   ──────────────────────────────────────────────────────────────────────
   ★ 用户原话（一个字不许多加）：
     录入 = 单行输入 + 时间选择，一次提交；
     列表 = **只有两列**（时间 / 内容）；
     **不提供**分组 / 筛选 / 排序控件（一个按钮都不加）。
   ⇒ 下面的 CSS 里刻意**没有** :hover 才出现的工具条、
     没有折叠、没有拖拽手柄 —— 那些都属于"多加的控件"。 */

/* 区块本身：比主列表轻一档（浅底 + 左侧细边），
   ⚠ 不用卡片阴影 —— 杂事是次要功能，视觉权重不能压过待办列表。 */
.v797-chores {
  margin: 0 0 12px; padding: 9px 10px;
  border-radius: 11px; background: var(--bg2);
  border: 1px solid var(--line); border-left: 3px solid var(--tx3);
}
.v797-chores-t {
  color: var(--tx2); font-size: 13px; font-weight: 600; margin-bottom: 7px;
}

/* 录入行：文字输入 + 时间选择 + 按钮，同一行（一次提交的语义 = 一个视觉行）。
   ⚠ 窄屏（<360px）允许换行，但**按钮始终在最后**，
     换行不能让「加提醒」跑到输入框左边 —— 那会让人误点。 */
.v797-chores-add { display: flex; gap: 7px; align-items: center; flex-wrap: wrap; }
.v797-chores-txt {
  flex: 1 1 140px; min-width: 0; padding: 8px 10px; border-radius: 9px;
  border: 1px solid var(--line); background: var(--bg); color: var(--tx);
  font-size: 15px; /* ≥15px 防 iOS 聚焦时自动放大 */
}
.v797-chores-txt:focus { outline: 2px solid var(--pri); outline-offset: 1px; }
.v797-chores-hm {
  flex: 0 0 auto; padding: 8px 9px; border-radius: 9px;
  border: 1px solid var(--line); background: var(--bg); color: var(--tx);
  font-size: 15px; min-height: 38px;
}
.v797-chores-hm:focus { outline: 2px solid var(--pri); outline-offset: 1px; }
/* ⚠ disabled 的灰必须**明显**到用户能看出「按钮点不动」，
   而 CSS 默认的 disabled 灰在深色模式下几乎看不见。
   这里同时降不透明度 + not-allow 光标，两个通道。 */
.v797-chores-add .v797-btn:disabled { opacity: .45; cursor: not-allowed; }

/* 「时刻已过」红字。
   ⚠ 用 --err 而不是 var(--tx3)：这是一条**阻止性**提示，
     用户看不到它就可能一直点一个永远不响的提醒。 */
.v797-chores-past {
  margin-top: 7px; color: var(--err, #d33); font-size: 12.5px; line-height: 1.6;
}
.v797-chores-past[hidden] { display: none; }

/* 空态 / 未就绪 / 错误态：**一行灰字**。
   ⚠ 刻意不加插图、不加图标、不加引导按钮 —— 规格明写「一行灰字，不留大插图」。
   ⚠ 错误态（.v797-chores-err）用红字而不是同一套灰：
     「没有杂事」和「功能没挂上」必须一眼可分，
     混成同一个样式 = 用户以为是自己记错了。 */
.v797-chores-empty,
.v797-chores-err {
  margin-top: 8px; color: var(--tx3); font-size: 12.5px; line-height: 1.7;
}
.v797-chores-err { color: var(--err, #d33); }

/* 列表：两列（时间 / 内容）。
   ⚠ grid-template-columns 写死两列 —— 视觉上强制两列，
     这样"多加一列"在样式上就是看得见的越界，而不是悄悄发生。 */
.v797-chores-list { list-style: none; margin: 8px 0 0; padding: 0; }
.v797-chores-item {
  display: grid;
  grid-template-columns: auto 1fr auto;   /* 时间 | 内容 | 删除 */
  align-items: center; gap: 9px;
  padding: 7px 2px; border-top: 1px solid var(--line);
}
.v797-chores-item:first-child { border-top: 0; }
.v797-chores-when {
  color: var(--tx2); font-size: 13px; font-variant-numeric: tabular-nums;
  font-weight: 600;
}
.v797-chores-txt2 { color: var(--tx); font-size: 14px; line-height: 1.5; word-break: break-word; }
.v797-chores-del {
  border: 0; background: transparent; cursor: pointer;
  color: var(--tx3); font-size: 17px; line-height: 1; padding: 2px 6px; border-radius: 7px;
}
.v797-chores-del:hover { background: var(--line); }

/* ══════════════════════════════════════════════════════════════════════
   ★★ v79.9 批次 9【#16】概览「杂事提醒」面板
   ──────────────────────────────────────────────────────────────────────
   ⚠⚠⚴ 与上面「备忘录页杂事区块」**刻意保持一致**的视觉语言（同样的行高、
     同样的时间列 tabular-nums、同样的 ✕ 位置）——
     用户在两个页面来回看，同一类东西长得不一样会让他以为是两样东西。
   ⚠⚠⚴ 但**多了一列**（类型徽章）⇒ 写成四列。
     ⚠ 这里有个刻意的取舍：备忘录页只有两列（时间/内容/删除），
       概览页必须显示 remind/note 两类（用户会一眼看到混在一起以为坏了），
       所以概览页是四列。**两处不一致是有理由的**，不是漏改。
   ⚠⚠⚴ 只用变量、不硬编码颜色（本文件铁律二）。 */
.chore-home-list { list-style: none; margin: 0; padding: 0; }
.chore-home-item {
  display: grid;
  grid-template-columns: auto 1fr auto auto;   /* 时间 | 内容 | 类型 | 删除 */
  align-items: center; gap: 8px;
  padding: 7px 2px; border-top: 1px solid var(--line);
}
.chore-home-item:first-child { border-top: 0; }
/* ⚠ 时间列用 tabular-nums：竖排时数字不错位，扫读更快。*/
.chore-home-when {
  color: var(--tx2); font-size: 13px; font-variant-numeric: tabular-nums;
  font-weight: 600; white-space: nowrap;
}
.chore-home-txt { color: var(--tx); font-size: 14px; line-height: 1.5; word-break: break-word; }
.chore-home-del {
  border: 0; background: transparent; cursor: pointer;
  color: var(--tx3); font-size: 17px; line-height: 1; padding: 2px 6px; border-radius: 7px;
}
.chore-home-del:hover { background: var(--line); }

/* ══════════════════════════════════════════════════════════════════════
   ★★ v79.9 批次 8 第 3 项：打卡格 UI 样式
   ──────────────────────────────────────────────────────────────────────
   ⚠⚠ **只用变量、不硬编码灰色**（本文件铁律二，:11-14）。
     ⚠ 而 `--bg2` 在上一轮才补上定义（此前全项目零定义 ⇒ 30 处透明）。
     ⚠ 这里的格子底色用 `--bg2`，而**边框/三态色**用 `--line`/`--pri`/`--tx3`
     ⇒ 亮暗三套主题**自动跟随**，不需要为暗色单独写一套。

   ⚠⚠ **三态色为什么这样定**（都是既有变量，没有新造色）：
     · 未打卡 ○  = `--tx3`（弱，与"没做"的心智一致）
     · 已完成 ●  = `--pri`（主色，与"做成了"一致）
     · 已跳过 ⊘  = `--tx3` + **虚线边框**（与"主动不做"的心智一致，
                 且**不靠颜色单独承载语义** ⇒ 色弱用户也能分辨）
     ⚠ 这一条是刻意的：**语义不能只靠颜色**。三态里
       「未打卡 vs 已跳过」色相同，只靠 ⊘ 字形 + 虚线框区分。
   ══════════════════════════════════════════════════════════════════════ */
.v797-ck-panel {
  /* ⚠ v80b35 期间曾在这里加过 `margin-top: calc(var(--qz-topbar-h) + 8px)`
     （想给 sticky 顶栏让位），**已撤销**，现恢复为原样 `margin: 12px`。
     ⚠⚠⚴ 撤销理由（QA 独立复验 docs/_qa_ckbar_复验报告.md，实测）：
       ① **几何自抵消**：给容器/面板加顶部让位 P ⇒ 内容下移 P，而**可滚动距离也正好 +P**
          ⇒ 滚到底时相对位置几乎不变（1280px 实测落点 y=74.9 vs 回退版 y=75.5，**只差 0.6px**）
          ⇒ 这一类修法**数学上治不了**位于滚动行程两端的元素，**不是调参能解决的**。
       ② 改 `#main` 让位的那版更糟：**手机端根本没生效** ——
          被 `:538 @media(max-width:900px){#main{padding:12px}}` 与
          `:976 @media(max-width:760px){#main{padding:10px 10px …}}` 两条媒体查询整条覆盖，
          实测 padTop：360/390/414 = **10px**、1280 = 147.4px
          ⇒ 4 个视口里 3 个（正是用户真机宽度）完全没受惠。
       ③ 遮挡**只在滚动行程两端**发生，44 档无漂移取样：
          `CLICK_OK=28 / BLOCKED=7 / OUT_OF_VIEWPORT=9` ⇒ **中低优先级体验缺陷**，
          不是「完全不可用」⇒ 不值得为此把全站布局都动一遍。
     ⚠ 留档要点：
       · 顶栏实测高度 390/360/414 视口 ⇒ 83.51px、1280 视口 ⇒ **131.42px**（差 47.9px）
         ⇒ **写死任何单一 px 都会在一侧失效**（本项目同族第 6 次的教训）。
       · ⚠ 媒体查询会**整条覆盖**你写的规则 ⇒ 改 CSS 前必须 grep 该选择器的**所有**
         `@media` 变体，改完要**实测**生效值，而不是看自己写的那行还在不在。
       · ⚠ `page.click` 会**先自己滚动**再点，在「被遮挡」位置照样点成功
         ⇒ 测遮挡**必须用裸 `mouse.click`**。
       · ⚠ 遮挡者**不止顶栏**：还有底部固定 `#tabbar`（z=120 fixed，390px 占 y=778..844）；
         实测 7 处真遮挡按占用者是 `DIV.brand` 3、`svg` 2、`BUTTON.tabbtn` 1、`HEADER.topbar` 1
         ⇒ 只测顶栏的判据会漏掉一半。
       · 若日后要真修：方向应是**缩短元素高度**或**让关键控件常驻可见**，
         而不是给它加 margin/padding（会与滚动距离自抵消）。*/
  margin: 12px; padding: 10px;
  background: var(--bg2); border: 1px solid var(--line);
  border-radius: 9px;
}
.v797-ck-hd { font-size: 13px; color: var(--tx2); margin-bottom: 8px; }
/* ⚠ 用 grid 而不是 table：12 格在窄屏会自动折行，不需要媒体查询。 */
.v797-ck-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
/* ⚠⚠⚴ **一天一屏**（本轮：替代 7 列 × 12 行 = 84 格）。
   ⚠ 单列 + 整行可点 ⇒ 手机上每格宽 = 屏宽 - 边距（实测 ≈ 300px+），
   ⚠ 判据 ① 要求 ≥ 280px 且高 ≥ 32px —— 高度由 .v797-ck-grid1 下的
   ⚠ min-height 保证（实际给到 44px，是按触控目标定的，不是卡线）。*/
.v797-ck-grid1 { grid-template-columns: 1fr; gap: 7px; }
.v797-ck-row {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 10px; min-height: 44px;
  background: var(--card); border: 1px solid var(--line);
  border-radius: 9px; cursor: pointer;
  /* ⚠ 触屏上整行都是热区 ⇒ 禁掉浏览器自选文本 / 长按弹系统菜单，
     否则长按会先被浏览器吃掉，我们的 is-open 永远等不到。*/
  -webkit-user-select: none; user-select: none;
  -webkit-touch-callout: none;
}
/* ⚠⚠⚴ 过去 / 今天 / 未来（派单硬要求，三类必须一眼可辨，
   ⚠ 且**语义不只靠颜色** —— 色弱也要能分辨）。*/
.v797-ck-row.is-past {
  opacity: .48;                 /* 过去 ⇒ 淡化（退到背景里） */
  border-style: dotted;         /* ⚠ 非颜色的第二层区分 */
}
.v797-ck-row.is-today {
  border-color: var(--pri); font-weight: 600;
  box-shadow: 0 0 0 1px var(--pri) inset;
}
.v797-ck-row.is-future {
  opacity: .34;                 /* 未来 ⇒ 更淡（还没开始） */
  border-style: dashed;
  cursor: default;              /* ⚠ 视觉上就不可点 */
}
/* ⚠ 已完成/已跳过**不因过去/未来而降透明度**：
   ⚠ 否则「我上周打了卡」会看不到记录 —— 记录该看见就要看见。*/
.v797-ck-row.is-done.is-past, .v797-ck-row.is-skip.is-past { opacity: .62; }
.v797-ck-row.is-done.is-future, .v797-ck-row.is-skip.is-future { opacity: .5; }
/* ⚠ 一天一屏下时段文字要显眼（不再挤在 1/14 屏宽里）*/
.v797-ck-grid1 .v797-ck-lab { flex: 1 1 auto; font-size: 14px; color: var(--tx1); }
.v797-ck-grid1 .v797-ck-dot { flex: none; font-size: 17px; color: var(--tx3); }
.v797-ck-grid1 .v797-ck-row.is-done .v797-ck-dot { color: var(--pri); }
.v797-ck-row.is-done { border-color: var(--pri); }
.v797-ck-row.is-skip { border-style: dashed; }
.v797-ck-lab { flex: 1; font-size: 12px; color: var(--tx2); }
.v797-ck-dot { font-size: 13px; color: var(--tx3); }
.v797-ck-row.is-done .v797-ck-dot { color: var(--pri); }
.v797-ck-act { display: flex; gap: 4px; }
.v797-ck-btn {
  font-size: 11px; padding: 2px 6px; cursor: pointer;
  background: var(--bg2); border: 1px solid var(--line);
  border-radius: var(--r-pill); color: var(--tx2);
}
.v797-ck-summary {
  margin-top: 8px; padding: 6px 8px;
  border-top: 1px solid var(--line2);   /* ⚠ 顶线用更浅的 --line2 */
  font-size: 12px; color: var(--tx3);
}

/* ══════════════════════════════════════════════════════════════════════
   ★★ v79.9 批次 8：四季主题 + 暗色下的 `.lunar` 对比度修复（6 条）
   ──────────────────────────────────────────────────────────────────────
   🔴🔴 实测到的真缺陷（不是推断，数字是算出来的）：
     `styles.css:2758-2760` 的暗色规则是 **不带 `:root` 的** `[data-theme="dark"]`
     ⇒ 特异性 **0,2,0**；
     而四季的 `[data-cal-theme="spring"] .cell>.lunar` 也是 **0,2,0**
     ⇒ **两者特异性完全相同** ⇒ 只能靠**加载顺序**取胜。
     ⚠ 而 `v797.css` 在 `styles.css` **之后**加载（index.html:40 → :43）
     ⇒ 所以**四季色在暗色下赢了** ⇒ 深色文字落在深色卡片上。

     实测（暗色卡底 #1a2030，WCAG 相对亮度公式）：
       季节日  .lunar    .lunar.hl
       spring   3.77 🔴   3.81 🔴
       summer   3.87 🔴   3.77 🔴
       autumn   3.82 🔴   5.23 ✓
       winter   3.97 🔴   3.44 🔴
     ⇒ **8 条里 7 条低于 4.5**（autumn 的 hl 是唯一达标的）。
     ⚠ 对照：暗色基线（`styles.css:2758-2759`）是 #8b93a7 / #ff8fa3
       ⇒ 对比度 5.28 / 7.51 ⇒ **本来是达标的**，被四季色覆盖掉了。
     ⚠ 症状：用户在**暗色 + 任一四季主题**下看日历，农历小字几乎看不清，
       而**界面不报错、切换主题也不报错**（纯静默的视觉缺陷）。

   ★ 为什么写在 `v797.css` 而不是 `styles.css`（主理人定的硬约束）：
     ① `styles.css` 是全站依赖的既有文件（3731 行），改它 = 回归面无法收敛；
     ② 本文件（v797.css）**只做追加**，与它自己的定位一致；
     ③ ⚠⚠ **必须靠加载顺序取胜**（特异性相同）
        ⇒ 所以这 6 条**只能**放在 v797.css，放在 styles.css 里会**输给**四季规则
           （同特异性时后加载的赢 ⇒ styles.css 里的暗色规则在四季**之后**吗？不是）
        ⇒ 这是本条修复**唯一的成败前提**，判据 S2.4/S2.5 专门守它。

   ⚠ 取值依据：**保留四季色相，只提亮到 ≥4.5**（不另造一套色）
     春 #c0567e→#e58fae（3.77→6.86）  hl #d6456b→#ffa8bd（3.81→8.96）
     夏 #2f8a72→#6fc9ab（3.87→8.21）  hl #0f8a6d→#5ad6b4（3.77→9.06）
     秋 #b06a2c→#e0a05c（3.82→7.23）  hl #d97a29→#f0b26a（5.23→8.72）
     冬 #5a7dc0→#8fb2f0（3.97→7.57）  hl #3a6fd8→#a8c4ff（3.44→9.28）
   ⚠ **classic（默认）主题不写覆盖** —— 它走 styles.css 的暗色基线（5.28/7.51 ✓）。
   ══════════════════════════════════════════════════════════════════════ */
:root[data-theme="dark"][data-cal-theme="spring"] .cell>.lunar { color: #e58fae; }
:root[data-theme="dark"][data-cal-theme="spring"] .cell>.lunar.hl { color: #ffa8bd; }
:root[data-theme="dark"][data-cal-theme="summer"] .cell>.lunar { color: #6fc9ab; }
:root[data-theme="dark"][data-cal-theme="summer"] .cell>.lunar.hl { color: #5ad6b4; }
:root[data-theme="dark"][data-cal-theme="autumn"] .cell>.lunar { color: #e0a05c; }
:root[data-theme="dark"][data-cal-theme="autumn"] .cell>.lunar.hl { color: #f0b26a; }
:root[data-theme="dark"][data-cal-theme="winter"] .cell>.lunar { color: #8fb2f0; }
:root[data-theme="dark"][data-cal-theme="winter"] .cell>.lunar.hl { color: #a8c4ff; }

/* ══════════════════════════════════════════════════════════════════════
   ★★ v79.9 批次 8：`.cell.today` 的日期数字对比度（三套主题全部不足）
   ──────────────────────────────────────────────────────────────────────
   🔴🔴 实测（暗色卡底取各自 --pri-soft，WCAG 公式）：
     `styles.css:310-312`：
       .cell.today            { background: var(--pri-soft); … }
       .cell.today>.cal-top .num { color: var(--pri); font-weight:500 }
     ⇒ 今天是「**主色数字压在主色浅底上**」，而这两者的对比度**天然不够**：

       主题              --pri      --pri-soft    实测对比度
       亮色（:root）      #3b6ef5    #eaf0ff      **3.89** 🔴
       看板娘 mascot     #4aa8d8    #e4f3fb      **2.35** 🔴
       暗色              #5b8def    #1e2a4a      **4.38** 🔴

     ⚠ 主理人给的是「4.37」（暗色那一条），**实测三套主题全部不足**
       —— 看板娘最差（2.35，只有标准线的一半）。
     ⚠ 症状：**今天**那一格的日期数字最难读，而它是用户每天最先看的那个格子。
       纯静默：切主题不报错、今天格也不特殊提示。

   ⚠⚠⚠ **修法为什么是「数字改用 --tx」而不是「把 --pri-soft 调浅/调深」**：
     ① `--pri-soft` 是**季节强调色**的底（`mascot` 的 8 套季节配色都用它），
        调它 ⇒ **连带影响所有用到 --pri-soft 的地方**（按钮、chip、选中态…）
        ⇒ 回归面无法收敛（本项目在 `--pri` 上栽过：全局改色把装饰色当文字修）。
     ② 数字是**文字** ⇒ 该用**文字色变量**（v79.6 已把三套主题的 --tx 修到 ≥4.5）
        ⇒ 亮色 #1c2333 on #eaf0ff = **13.76**；暗色 #e2e8f0 on #1e2a4a = **11.47**
        ⇒ **自动继承 v79.6 的对比度修复成果**，且**不再依赖 --pri 的具体取值**。
     ⚠⚠ 「今天」的**语义**由**底色 + 边框**（`--pri-soft` 底 + `box-shadow: 0 0 0 1px var(--pri) inset`）
       承担，**不靠数字颜色** ⇒ 换成 --tx **不丢语义**（判据 S3.4 验这一点）。

   ⚠ **只改数字色，不动 `.dnum`**（`:308` 那个是"有课"的白底圆点，
     `background:var(--pri); color:#fff` ⇒ 对比度 4.6+ 达标，**不要顺手改**）。
   ══════════════════════════════════════════════════════════════════════ */
.cell.today>.cal-top .num { color: var(--tx); }

/* ══════════════════════════════════════════════════════════════════════
   ★★ v79.9 批次 8：打卡 UI 改 7 列（周一~周日）× 12 行（时段）
   ──────────────────────────────────────────────────────────────────────
   ⚠⚠⚠ **三列的视觉必须能被"一眼"区分**（主理人明确要求看这个）——
     起因：用户第 4 条是「避免因跨天未打卡而被判定缺勤」，
     而 7 列里大量空格子**天然会被读成缺勤**。
     ⇒ 视觉必须把「过去的漏」和「今天的待办」和「未来的不算」分开。

   ⚠ **不只靠颜色**（色弱可辨，与本文件既有纪律一致）：
     过去 ⇒ 降透明度 **+** 网格线变虚 **+** title 明写「不计入缺勤」
     今天 ⇒ **加粗 + 主色边框 + 略高不透明度**（唯一"跳出来"的一列）
     未来 ⇒ 降透明度 **+** 虚线框
   ⚠ 全部走既有变量（铁律二），亮暗三套主题自动跟随。
   ══════════════════════════════════════════════════════════════════════ */
.v797-ck-week {
  display: flex; flex-direction: column; gap: 2px;
  /*⚠ 手机上 7 列 ⇒ 每列必须够窄才不横向溢出。
     min-width:0 + flex:1 是关键（否则内容撑破容器）。*/
  overflow-x: auto;
}
.v797-ck-wk-hd, .v797-ck-wk-row { display: flex; gap: 2px; }
.v797-ck-wk-col-hd {
  flex: 1 1 0; min-width: 0; text-align: center;
  padding: 2px 1px; font-size: 10px; line-height: 1.2;
  color: var(--tx3); border-bottom: 1px solid var(--line);
}
.v797-ck-wk-col-hd .v797-ck-wk-wd { display: block; font-weight: 500; }
.v797-ck-wk-col-hd .v797-ck-wk-d { display: block; font-size: 9px; opacity: .75; }

/* ⚠⚠ **今天**是唯一要"跳出来"的列 —— 这才是待办 */
.v797-ck-wk-col-hd.is-today { color: var(--pri); font-weight: 700; border-bottom: 2px solid var(--pri); }
.v797-ck-wk-col-hd.is-past { opacity: .5; }
.v797-ck-wk-col-hd.is-future { opacity: .42; }

/* ⚠ **每格单行**（时段文字 + 状态点）——12 行 × 2 行会撑破一屏 */
.v797-ck-cell {
  flex: 1 1 0; min-width: 0;
  display: flex; align-items: center; justify-content: space-between;
  gap: 1px; padding: 2px 3px;
  background: var(--card); border: 1px solid var(--line); border-radius: 4px;
  cursor: pointer; font-size: 10px; line-height: 1.25;
}
.v797-ck-cell .v797-ck-lab { flex: 1 1 auto; min-width: 0; color: var(--tx2); overflow: hidden; }
.v797-ck-cell .v797-ck-dot { flex: none; color: var(--tx3); font-size: 10px; }
.v797-ck-cell.is-done .v797-ck-dot { color: var(--pri); }
.v797-ck-cell.is-skip { border-style: dashed; }

/* ⚠⚠⚠ 三类日期的差异（**这是主理人要求"一眼可辨"的那部分**） */
.v797-ck-cell.is-today {
  border-color: var(--pri); font-weight: 600;
  /*⚠ 今天的格子**不降透明度** —— 它是唯一"待办"，降了就没了 */
  box-shadow: 0 0 0 1px var(--pri) inset;
}
.v797-ck-cell.is-past {
  opacity: .48;                 /* 过去 ⇒ 淡化（视觉上"退到背景里"） */
  border-style: dotted;         /* ⚠ 再加一层**非颜色**区分（色弱可辨） */
}
.v797-ck-cell.is-future {
  opacity: .34;                 /* 未来 ⇒ 更淡（"还没开始"） */
  border-style: dashed;
}
/*⚠ 已完成/已跳过的格子**不因过去/未来而降透明度**
  ⇒ 记录本身该看见就看得见（否则"我上周打了卡"会看不到记录）*/
.v797-ck-cell.is-done.is-past, .v797-ck-cell.is-skip.is-past { opacity: .62; }

/* ══════════════════════════════════════════════════════════════════════
   ★★ 本轮新增：切日期条 + 一天一屏行布局 + 「跳过」入口收敛
   ──────────────────────────────────────────────────────────────────────
   ⚠⚠⚴ **「跳过」默认 display:none**（派单硬要求：
     「跳过」不再每格常驻 ⇒ 改为长按或点行尾小箭头才出现）。
   ⚠ 但**三态必须保留** ⇒ DOM 里按钮仍在（只是不可见），
     点行尾「⋯」或长按 → 行加 .is-open → 按钮显示。
   ⚠ 为什么不用 hidden 属性：那一路会把按钮从无障碍树里摘掉，
     而它是**真实可达**的操作（只是收在菜单里）。*/
.v797-ck-skipbtn {
  display: none;
  flex: none; font-size: 12px; padding: 4px 12px; cursor: pointer;
  background: var(--bg2); border: 1px solid var(--line);
  border-radius: var(--r-pill); color: var(--tx2);
}
.v797-ck-row.is-open .v797-ck-skipbtn { display: inline-block; }
.v797-ck-skipbtn:hover { color: var(--pri); border-color: var(--pri); }

/* ⚠ 行尾「⋯」：跳过入口的**可点、可测**那一条（长按是第二条）*/
.v797-ck-more {
  flex: none; width: 30px; height: 30px; padding: 0;
  font-size: 15px; line-height: 1; cursor: pointer;
  color: var(--tx3); background: transparent;
  border: 1px solid var(--line); border-radius: 6px;
}
.v797-ck-more:hover, .v797-ck-row.is-open .v797-ck-more {
  color: var(--pri); border-color: var(--pri);
}

/* ══════════════════════════════════════════════════════════════════════
   🔴 v80.22【打卡面板底部留白】用户截图里点「删」没反应，实测真因：
   ⚠⚠⚴ **底部导航栏（.tabbar，position:fixed; bottom:0）压住了最后一行的删除按钮**
     —— 实测按钮几何 y=1113 / 视口高 1044，Playwright 明确报
     `<nav id="tabbar"> intercepts pointer events`。
   ⇒ 在手机上滚到底部时，按钮**正好落在底栏下面** ⇒ 用户点不到
     ⇒ 表现就是「加了删除按钮但没用」，而且**不报任何错**（本项目高频坑：
     「静默失效：点了没反应且零报错」那一族）。
   ⇒ 修法：打卡面板给足底部内边距（底栏高约 60 + 安全区 + 余量）。
   ⚠ 不用 CSS 变量去量底栏高度：底栏在桌面是 `display:none`，
     无条件留白会在桌面上多出一段空白 ⇒ 用媒体查询分开。*/
.v797-ck-panel{padding-bottom:76px}
@media (min-width:900px){
  .v797-ck-panel{padding-bottom:8px}
}

/* ══════════════════════════════════════════════════════════════════════
   🔴 v80.22【行内删除打卡时段】用户 2026-10-06 截图指的位置：
   「我是想在这里加一个删除」—— 每一行右端，紧挨「⋯」的删除按钮。
   ⚠⚠⚴ 样式与 `.v797-ck-more` 刻意保持同一尺寸（30×30、6px圆角），
     这样行尾一排控件**基线对齐、视觉等重**，
     不会因为删除按钮矮一截/胖一截而显得像临时塞进去的。
   ⚠ 为什么用文字「删」而不是「✕」：
     行尾已经有「⋯」（= 更多操作）与「✕」样式的关闭语义，
     再放个 ✕ 会被认成「关闭这一行」而不是「删掉这个时段」。
     「删」只有 1 个字，占位小且语义唯一。
   ⚠ 破坏性操作 ⇒ 常态低调（灰字描边），hover 才变红。
     反过来（常态大红）会让整列表看着像都在报错。
   ══════════════════════════════════════════════════════════════════════ */
.v797-ck-delrow {
  flex: none; width: 30px; height: 30px; padding: 0;
  font-size: 12px; line-height: 1; cursor: pointer;
  color: var(--tx3); background: transparent;
  border: 1px solid var(--line); border-radius: 6px;
}
.v797-ck-delrow:hover, .v797-ck-delrow:focus-visible {
  color: #d9534f; border-color: #d9534f;
  background: color-mix(in srgb, #d9534f 8%, transparent);
}
/* 触控设备（小屏）按钮更易点：放大到 34px，仍保持与同行控件基线一致 */
@media (hover:none){ .v797-ck-delrow{width:34px;height:30px} }

/* ⚠ 切日期条：左箭头 + 当前日 + 右箭头 + 「今天」*/
.v797-ck-daybar {
  display: flex; align-items: center; gap: 6px;
  flex-wrap: wrap; margin-bottom: 8px;
  /* ⚠ v80b35 曾在此加过 `scroll-margin-top: calc(var(--qz-topbar-h,84px) + 22px)`，**已撤销**。
     ⚠ 撤销理由（QA 独立复验，实测）：产品代码**从不** scrollIntoView 打卡日期条
       （`pomo.js` 里 `scrollIntoView` 出现 **0 次**）
       ⇒ `scroll-margin-top` 只对「滚动锚点」生效，而没有任何代码把它当锚点
       ⇒ 对真实用户**零作用**，只是一段会误导后来人的死代码。
     ⚠ 顺带留档：顶栏实测高度是 390/360/414 视口 ⇒ 83.51px、1280 视口 ⇒ 131.42px（差 47.9px）
       ⇒ 任何「写死单一 px」的修法都会在一侧失效（这是本项目同族第 6 次的教训）。*/
}
.v797-ck-nav {
  flex: none; width: 34px; height: 34px; padding: 0;
  font-size: 13px; line-height: 1; cursor: pointer;
  color: var(--tx2); background: var(--card);
  border: 1px solid var(--line); border-radius: 8px;
}
.v797-ck-nav:hover { color: var(--pri); border-color: var(--pri); }
.v797-ck-cur {
  flex: 1 1 auto; min-width: 0; display: flex;
  align-items: baseline; gap: 6px; flex-wrap: wrap;
}
.v797-ck-cur-d { font-size: 15px; font-weight: 700; color: var(--tx1); }
.v797-ck-cur-w { font-size: 12px; color: var(--tx2); }
.v797-ck-cur-k { font-size: 11px; color: var(--tx3); }
.v797-ck-cur.is-today .v797-ck-cur-d { color: var(--pri); }
.v797-ck-cur.is-past .v797-ck-cur-d { opacity: .62; }
.v797-ck-cur.is-future .v797-ck-cur-d { opacity: .45; }
.v797-ck-today {
  flex: none; font-size: 11px; padding: 4px 9px; cursor: pointer;
  color: var(--tx2); background: var(--card);
  border: 1px solid var(--line); border-radius: var(--r-pill);
}
.v797-ck-today:hover { color: var(--pri); border-color: var(--pri); }

/* ⚠⚠⚴ **7 天概况条**（七个点，周一→周日）。
   ⚠ 这是「按星期自定义不同事项」这个能力的**唯一可见入口**
   ⚠ ⇒ 少这一块 ⇒ 用户以为功能没做（本轮最不能省的一块）。
   ⚠ 每格 7 等分 ⇒ 390px 下每点 ≈ 44px 宽，**够手指点**。*/
.v797-ck-wdots {
  flex: 1 1 100%; display: flex; gap: 3px; margin-top: 2px;
}
.v797-ck-wdot {
  flex: 1 1 0; min-width: 0; padding: 3px 1px; cursor: pointer;
  background: transparent; border: 1px solid transparent;
  border-radius: 6px;
}
.v797-ck-wdot:hover { border-color: var(--line); }
.v797-ck-wdot.is-cur { border-color: var(--pri); background: var(--bg2); }
.v797-ck-wdot-bar {
  display: block; height: 5px; border-radius: 3px;
  background: var(--line); overflow: hidden;
}
.v797-ck-wdot-bar > i { display: block; height: 100%; background: var(--pri); }
.v797-ck-wdot-lb {
  display: block; margin-top: 2px; font-size: 10px;
  line-height: 1.2; color: var(--tx3); text-align: center;
}
.v797-ck-wdot.is-today .v797-ck-wdot-lb { color: var(--pri); font-weight: 700; }
.v797-ck-wdot.is-past { opacity: .55; }
.v797-ck-wdot.is-future { opacity: .38; }

/* ⚠ 7 列格内的「显式跳过」小按钮（单行内，不撑高格子）*/
.v797-ck-skip {
  flex: none; width: 14px; height: 14px; padding: 0;
  font-size: 9px; line-height: 1; cursor: pointer;
  color: var(--tx3); background: transparent;
  border: 1px solid var(--line); border-radius: 3px;
}
.v797-ck-skip:hover { color: var(--pri); border-color: var(--pri); }

/* ══════════════════════════════════════════════════════════════════════
   ★★ v79.9 批次 8：翻页牌样式（prefs.clockStyle === 'flip' 时启用）
   ──────────────────────────────────────────────────────────────────────
   ⚠⚠⚠ **翻页动画必须用 CSS transform**（硬要求 ①）
     —— 本项目已犯过的 P0：`ring.innerHTML = ringSvg(...)` 每秒重建整棵 SVG ⇒ 卡顿
     ⇒ 这里**只改 transform / opacity**，**不动 innerHTML**（判据 ⑥ 验「对象不被换」）。

   ⚠⚠⚠ **只靠 CSS，不靠 JS 逐帧**（硬要求 ①）：
     JS 只负责「值变了就写 textContent」（`paintFlip`），
     动画本身交给 `transition` ⇒ **JS 不参与动画过程**。
   ⚠ 全部走既有变量（铁律二），亮暗三套主题自动跟随。
   ══════════════════════════════════════════════════════════════════════ */
.v797-flip {
  display: flex; align-items: flex-end; justify-content: center;
  gap: 6px; padding: 10px 8px; position: relative;
  background: var(--card); border: 1px solid var(--line); border-radius: 10px;
}
/* 🔴 v80b41：翻页牌在 **render 阶段**就渲染时（pomo.js:2632 按 clockStyle 选样式），
   外面这层不能用 `.v797-pomo-ring` —— 它继承了环形的外边距（v797.css:266/619
   `margin: 6px 0 12px`）⇒ 翻页牌会带着环形的间距，布局偏。
   ⚠ 只给外层一个「居中 + 上下留白」，其余全交给 .v797-flip 自己。 */
.v797-flip-wrap { margin: 6px 0 12px; }
.v797-flip-card {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  min-width: 40px;
}
.v797-flip-lab { font-size: 10px; color: var(--tx3); }
/* ⚠ 牌面：上下两片叠在一起，中间一条缝 */
.v797-flip-digits {
  position: relative; display: block;
  width: 100%; height: 46px;
  background: var(--bg2); border: 1px solid var(--line); border-radius: 6px;
  overflow: hidden;
  font-variant-numeric: tabular-nums;
}
.v797-flip-t, .v797-flip-b {
  position: absolute; left: 0; right: 0;
  display: block; text-align: center; line-height: 46px;
  font-size: 26px; font-weight: 600; color: var(--tx);
  /* ⚠⚠ **翻页动画全靠这两个 transform**（硬要求 ①）
     ⚠ transform + transition 是**合成层**动画 ⇒ 不触发布局、不逐帧重绘 */
  transition: transform .28s ease, opacity .28s ease;
  will-change: transform;
}
.v797-flip-t { top: 0; }
.v797-flip-b { bottom: 0; }
/* ⚠ 静止时：牌面降到次级色（不假装在计时）*/
.v797-flip.is-idle .v797-flip-t,
.v797-flip.is-idle .v797-flip-b { color: var(--tx3); }
.v797-flip.is-idle .v797-flip-digits { border-style: dashed; }
.v797-flip-idle {
  position: absolute; right: 8px; top: 6px;
  font-size: 10px; color: var(--tx3);
}
/* ⚠ 到点紧急态：主色描边（与 ring 的 is-urgent 同义）*/
.v797-flip.is-urgent { border-color: var(--pri); }

/* ⚠⚠ **翻一下**：上片向上转出、下片从下方转入
   ⚠⚠⚴ v80b41 改用 **CSS animation**（此前是「加属性 → JS 撤属性」的 transition 方案）：
     原方案实测**必然卡死**（smoke/_f3.js，clockStyle='flip' 连续采样 20 次）：
       17~18/20 次采样里 `h`/`m`/`s` 三张牌停在
       `transform=matrix3d(rotateX 88°)` + `opacity .18` ⇒ **数字看不见**
     ⇒ 对照实验（把 transition 拉到 5s）不可见率升到 **10/10**，
       证明**不可见与 transition 时长强相关** = 动画被反复重启、永远走不到终点。
       而 timer 每秒调一次 paintFlip ⇒ 每秒「加属性 → 撤掉」重新开始 0.28s 过渡
       ⇒ 牌面永远停在看不见的角度。**这就是用户说的「只显示一下然后消失」。**
     ✅ animation 的优势：**播完自动回到 `animation-fill-mode: none` 的初始态**，
       不依赖任何 JS 撤属性 ⇒ 即使 JS 漏撤、即使每秒重启，也不会卡在中间态。
     ⚠ 仍保留 JS 加属性的机制（paintFlip 只给「变化的牌」加）——
       硬要求 ②「只改变化的牌」不变，未变的牌连属性都不写、不会重启动画。*/
@keyframes qzFlipTop {
  0%   { transform: rotateX(0deg);    opacity: 1; }
  45%  { transform: rotateX(-88deg);  opacity: .18; }
  100% { transform: rotateX(0deg);    opacity: 1; }
}
@keyframes qzFlipBot {
  0%   { transform: rotateX(0deg);   opacity: 1; }
  45%  { transform: rotateX(88deg);  opacity: .18; }
  100% { transform: rotateX(0deg);   opacity: 1; }
}
.v797-flip-card[data-v797-flip-flip] .v797-flip-t {
  animation: qzFlipTop .28s ease both;
}
.v797-flip-card[data-v797-flip-flip] .v797-flip-b {
  animation: qzFlipBot .28s ease both;
}
/* ⚠ 静止时**不翻**（硬要求 ③）：idle 态不加翻转效果 */
.v797-flip.is-idle .v797-flip-card[data-v797-flip-flip] .v797-flip-t,
.v797-flip.is-idle .v797-flip-card[data-v797-flip-flip] .v797-flip-b {
  animation: none; transform: none; opacity: 1;
}
@media (prefers-reduced-motion: reduce) {
  /* ⚠⚠ **尊重系统的「减少动态效果」**（前庭敏感用户）
     ⇒ 关掉翻页动画，但**牌面数字照常更新**（信息不丢） */
  .v797-flip-t, .v797-flip-b { transition: none; }
  .v797-flip-card[data-v797-flip-flip] .v797-flip-t,
  .v797-flip-card[data-v797-flip-flip] .v797-flip-b {
    animation: none; transform: none; opacity: 1;
  }
}

/* ── v80.11【提醒矩阵】待办 / 打卡 / 杂事 × 三种提醒方式 ────────────────────
   ⚠ 遵守本文件铁律：
     · 铁律二（颜色）：全部用 CSS 变量，**不硬编码任何灰色**
       ⇒ 三套主题（亮 / dark / mascot）+ body.night-dim 夜间压暗自动跟随。
     · 铁律三（类名）：一律 v797- 前缀，绝不写裸类名（曾因裸 .warn 撞全局组件）。
     · 铁律一（z-index）：**本区块没有任何 fixed / 浮层**（矩阵是页面内的静态表格），
       所以不涉及 z-index 竞争 —— 这是刻意的：v797.css:7 要求 fixed 层 ≥1000，
       而本页已有 .v797-memo-compose / .v797-mbmenu 两层 z=1000，
       新加浮层必然要在 1000+ 里再插一层 ⇒ 能不浮就不浮。
   ⚠ 矩阵用 **table + 原生 checkbox** 而不是 div 拼：
     9 格开关必须「一眼看全、行对列齐」，table 的语义正好就是行列对齐；
     且原生 checkbox 自带键盘可达性与无障碍语义（div 拼的假开关两者都没有）。*/
.v797-rmx-wrap {
  overflow-x: auto;            /* 窄屏（手机 390px）横向滚动，而不是把列挤扁 */
  -webkit-overflow-scrolling: touch;
}
.v797-rmx-tbl {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
  min-width: 420px;            /* 低于这个宽度列就开始挤字 ⇒ 交给横向滚动 */
}
.v797-rmx-tbl th,
.v797-rmx-tbl td {
  border-bottom: 1px solid var(--line);
  padding: 8px 6px;
  text-align: center;
  vertical-align: middle;
}
.v797-rmx-tbl thead th {
  font-size: 12px;
  font-weight: 600;
  color: var(--tx2);
  white-space: nowrap;
}
.v797-rmx-kind {
  text-align: left !important;
  white-space: nowrap;
  color: var(--tx);
  font-weight: 600;
}
.v797-rmx-td { text-align: center; }

/* 开关本体：原生 checkbox 只当「状态载体」，视觉全部交给 .v797-rmx-sw-t。
   ⚠ 为什么不用 appearance:none 直接改 checkbox：那样会连键盘焦点环一起丢掉
     （无障碍回退）。保留原生控件、把它透明化，只画旁边的滑块。*/
.v797-rmx-sw {
  display: inline-flex;
  align-items: center;
  cursor: pointer;
  position: relative;
}
.v797-rmx-sw input[type="checkbox"] {
  position: absolute;
  opacity: 0;
  width: 40px;
  height: 22px;
  margin: 0;
  cursor: pointer;
}
.v797-rmx-sw-t {
  display: block;
  width: 40px;
  height: 22px;
  border-radius: 11px;
  background: var(--line);
  position: relative;
  transition: background .18s ease;
  pointer-events: none;        /* 点击全部交给 input，否则 label 双触发 */
}
.v797-rmx-sw-t::after {
  content: '';
  position: absolute;
  top: 3px;
  left: 3px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--bg, #fff);
  transition: transform .18s ease;
}
.v797-rmx-sw input:checked + .v797-rmx-sw-t { background: var(--pri); }
.v797-rmx-sw input:checked + .v797-rmx-sw-t::after { transform: translateX(18px); }
/* ⚠ 焦点环：键盘用户必须看得见当前焦点在哪一格（9 个开关里靠位置定位）*/
.v797-rmx-sw input:focus-visible + .v797-rmx-sw-t {
  outline: 2px solid var(--pri);
  outline-offset: 2px;
}
/* 提前分钟数输入框。⚠ disabled 时用 --tx3 而不是硬编码灰：
   项目铁律二禁硬编码灰色，且暗色主题下 #888 之类会看不见。*/
.v797-rmx-min {
  width: 72px;
  text-align: center;
  font-size: 13px;
  padding: 5px 4px;
  border-radius: var(--r-md);
  border: 1px solid var(--line);
  background: var(--bg, #fff);
  color: var(--tx);
}
.v797-rmx-min:disabled {
  color: var(--tx3);
  background: transparent;
  cursor: not-allowed;
}
/* 暗色主题：滑块关态的描边在暗色下要更明显，否则「看不出有没有开」*/
[data-theme="dark"] .v797-rmx-sw-t { background: #2a3350; }
[data-theme="dark"] .v797-rmx-sw-t::after { background: #10131f; }
[data-theme="dark"] .v797-rmx-min { background: #161b2c; }
