/* ============================================================
   Lightbox UI 预览样式 (组件化版)
   规范: .claude/skills/lightbox-ui-design/SKILL.md
   约束(设备内): 300x400 / 1bpp 纯黑白 / 无灰阶无阴影无圆角 / 焦点整行反色
   结构: 上半 = 预览页外壳(纸上图鉴风, 设备外) · 下半 = 设备屏幕本体(严格 ink/paper)
   ============================================================ */

:root {
  --ink: #000; --paper: #fff;
  /* 8px 基线网格; 左右安全边 16px (原 12px 偏挤 —— 反射屏上"从容"比"多装内容"值钱) */
  --gap: 8px; --edge: 16px;
  --statusbar: 24px; --footer: 24px; --content: 352px;  /* 400-24-24 */

  /* 外壳 token (仅目录页 chrome, 绝不进设备像素) */
  --c-paper: #f3efe6;   /* 暖纸底 */
  --c-ink:   #1c1a17;   /* 章墨 */
  --c-soft:  #756f61;   /* 弱墨 */
  --c-hair:  #d9d2c2;   /* 发丝线 */
  --c-seal:  #c0371c;   /* 印章朱砂红 (激活/强调) */
  --wrap: 1368px;
  --serif: "Songti SC", "Noto Serif CJK SC", "Source Han Serif SC", "SimSun", Georgia, serif;
  --mono: "Noto Sans Mono CJK SC", "Sarasa Mono SC", "WenQuanYi Micro Hei Mono", "Microsoft YaHei", monospace;
}
* { margin: 0; padding: 0; box-sizing: border-box; }

/* ============================================================
   预览页外壳 (设备外, 非设备像素) — 纸上图鉴
   ============================================================ */
body {
  background: var(--c-paper); color: var(--c-ink);
  font-family: var(--mono);
  -webkit-font-smoothing: antialiased;
}
/* 纸纹颗粒 (极淡, 仅氛围) */
body::after {
  content: ""; position: fixed; inset: 0; z-index: 99; pointer-events: none;
  opacity: .045; mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ── 顶部固定操作条 ── */
.topbar {
  position: fixed; top: 0; left: 0; right: 0; z-index: 50; height: 46px;
  display: flex; align-items: center; gap: 22px; padding: 0 26px;
  background: rgba(243, 239, 230, .92); backdrop-filter: blur(6px);
  border-bottom: 1px solid var(--c-ink); font-size: 12px;
}
.topbar .brand { display: flex; align-items: center; gap: 12px; white-space: nowrap; }
.topbar .mark { font-weight: 700; letter-spacing: 3px; font-size: 12px; }
.topbar .mark::before {
  content: ""; display: inline-block; width: 9px; height: 9px;
  background: var(--c-seal); margin-right: 9px; vertical-align: 0;
}
.topbar .brand-cn {
  font-family: var(--serif); font-size: 14px; letter-spacing: 4px;
  border-left: 1px solid var(--c-hair); padding-left: 12px;
}
.topbar .hints { color: var(--c-soft); white-space: nowrap; }
.topbar kbd {
  font-family: var(--mono); font-size: 11px; color: var(--c-ink);
  border: 1px solid var(--c-ink); border-bottom-width: 2px;
  background: #fff; padding: 1px 5px; margin: 0 1px;
}
.topbar .spacer { margin-left: auto; }
.topbar .now { white-space: nowrap; color: var(--c-soft); }
.topbar .now b { font-family: var(--serif); color: var(--c-seal); letter-spacing: 1px; margin-left: 4px; }
.toggle { display: flex; align-items: center; gap: 7px; cursor: pointer; user-select: none; white-space: nowrap; }
.toggle input { position: absolute; opacity: 0; }
.toggle i { width: 13px; height: 13px; border: 1px solid var(--c-ink); background: #fff; flex: none; }
.toggle input:checked + i { background: var(--c-seal); border-color: var(--c-seal); box-shadow: inset 0 0 0 2px #fff; }
@media (max-width: 1080px) { .topbar .hints { display: none; } }

/* ── 题头 ── */
.hero { max-width: var(--wrap); margin: 0 auto; padding: 110px 24px 0; }
.eyebrow { font-size: 11px; letter-spacing: 4px; color: var(--c-seal); }
.hero h1 {
  font-family: var(--serif); font-weight: 700;
  font-size: clamp(34px, 4.6vw, 52px); letter-spacing: 7px;
  margin-top: 14px; display: flex; align-items: center; gap: 20px;
}
.hero .seal {
  writing-mode: vertical-rl; background: var(--c-seal); color: #fdfaf3;
  font-size: 15px; font-weight: 400; letter-spacing: 3px; padding: 7px 5px;
  transform: rotate(-2.5deg) translateY(-3px); user-select: none; flex: none;
}
.hero .lede { margin-top: 14px; font-size: 13px; color: var(--c-soft); letter-spacing: 1px; }
.specs { list-style: none; display: flex; flex-wrap: wrap; margin-top: 22px; font-size: 12px; row-gap: 8px; }
.specs li { padding: 0 16px; border-left: 1px solid var(--c-hair); }
.specs li:first-child { padding-left: 0; border-left: 0; }
.rule-double { margin-top: 28px; height: 7px; border-top: 2px solid var(--c-ink); border-bottom: 1px solid var(--c-ink); }

/* ── 章节 ── */
.chapter { max-width: var(--wrap); margin: 54px auto 0; padding: 0 24px; }
.chap-head { display: flex; align-items: baseline; gap: 14px; margin-bottom: 30px; }
.chap-no { font-family: var(--serif); font-size: 13px; color: var(--c-seal); border: 1px solid currentColor; padding: 1px 7px 2px; flex: none; }
.chap-head h2 { font-family: var(--serif); font-size: 24px; font-weight: 700; letter-spacing: 3px; white-space: nowrap; }
.chap-count { font-size: 12px; color: var(--c-soft); white-space: nowrap; }
.chap-head .rule { flex: 1; border-bottom: 1px solid var(--c-hair); transform: translateY(-4px); }

/* ── 图版画廊 ── */
.gallery { display: grid; grid-template-columns: repeat(auto-fill, 302px); gap: 54px 26px; }
.cell {
  width: 302px;
  animation: plate-in .55s cubic-bezier(.2, .7, .3, 1) both;
  animation-delay: calc(var(--i, 0) * 32ms);
}
@keyframes plate-in { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .cell { animation: none; } }

/* 设备相框: 1px 墨线 + 纸上投影; 内部 .screen 严格 300×400 纯黑白 */
.frame {
  position: relative; width: 300px; height: 400px; box-sizing: content-box;
  border: 1px solid var(--c-ink); background: var(--paper); cursor: pointer;
  box-shadow: 0 16px 30px -22px rgba(28, 26, 23, .55);
  transition: box-shadow .15s ease, transform .15s ease;
}
.frame:hover { box-shadow: 0 22px 36px -22px rgba(28, 26, 23, .62); transform: translateY(-2px); }
.frame.active { outline: 2px solid var(--c-seal); outline-offset: 3px; }
.frame.active::after {
  content: "● 操作中"; position: absolute; top: -10px; right: -3px; transform: translateY(-100%);
  background: var(--c-seal); color: #fff; font: 11px/1 var(--mono);
  letter-spacing: 1px; padding: 5px 8px; white-space: nowrap;
}

/* 图版题签 (框下, 博物馆式) */
.plate { display: flex; gap: 12px; margin-top: 14px; align-items: baseline; }
.plate .no { font-family: var(--serif); font-size: 13px; color: var(--c-seal); letter-spacing: 1px; flex: none; }
.plate .cap { display: block; font-family: var(--serif); font-size: 16px; font-weight: 700; letter-spacing: .5px; }
.plate .sub { display: block; font-size: 11px; color: var(--c-soft); margin-top: 4px; line-height: 1.55; }
.cell:has(.frame.active) .cap { color: var(--c-seal); }

/* ── 页脚题跋 ── */
.colophon {
  max-width: var(--wrap); margin: 76px auto 0; padding: 18px 24px 44px;
  border-top: 1px solid var(--c-ink); font-size: 12px; color: var(--c-soft); line-height: 2.1;
}
.colophon code { font-family: var(--mono); color: var(--c-ink); border-bottom: 1px solid var(--c-hair); padding-bottom: 1px; }
.dashed-note { outline: 1px dashed #9a9a9a; padding: 0 4px; }

/* ============================================================
   设备屏幕本体 (以下严格只用 ink/paper)
   ============================================================ */
.screen {
  width: 100%; height: 100%; background: var(--paper); color: var(--ink);
  position: relative; overflow: hidden;
  font-family: "Noto Sans Mono CJK SC", "Sarasa Mono SC", "WenQuanYi Micro Hei Mono", "Microsoft YaHei", monospace;
  font-weight: 400 !important;
}
.screen * { font-weight: 400 !important; }

/* 字号阶梯 (严格三档) */
.t24 { font-size: 24px; line-height: 32px; }
.t16 { font-size: 16px; line-height: 22px; }
.t12 { font-size: 12px; line-height: 16px; }

/* 状态栏 */
.statusbar {
  position: absolute; top: 0; left: 0; right: 0; height: var(--statusbar);
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 var(--edge); border-bottom: 1px solid var(--ink); font-size: 12px;
}
.statusbar .sb-c { flex: 1; text-align: center; }
.statusbar .right { display: flex; align-items: center; gap: 6px; }
.statusbar svg { display: block; }
.batt { display: inline-flex; align-items: center; gap: 3px; }

/* 内容区 */
.content { position: absolute; top: var(--statusbar); left: 0; right: 0; height: var(--content); overflow: hidden; }
.content.full { top: 0; height: 100%; }
.pad { padding: var(--gap) var(--edge); }
.center {
  position: absolute; inset: var(--statusbar) 0 var(--footer) 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 8px; text-align: center; padding: 0 20px;
}

/* 底栏: 系统状态行 (左 SRAM% / 右 构建标记) */
.footer {
  position: absolute; bottom: 0; left: 0; right: 0; height: var(--footer);
  display: flex; align-items: center; justify-content: space-between; padding: 0 var(--edge);
  border-top: 1px solid var(--ink); font-size: 12px;
}

/* 列表 */
.list { list-style: none; }
.list li {
  height: 44px; display: flex; align-items: center; gap: 10px;
  padding: 0 var(--edge); border-bottom: 1px dashed var(--ink);
}
.list li .main { flex: 1; font-size: 16px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.list li .meta { font-size: 12px; white-space: nowrap; }
.list li .col { flex: 1; min-width: 0; }
.list li.tall { height: 52px; }
/* 出血竖条行 (消息中心未读标记): li 自身让出内边距, 竖条 + 内容各自绝对定位到
   真正的 x=0/x=16, 竖条焦点时须手动翻白 —— 不能指望 .focus * (它只认 color 不认 background). */
.list li.flagrow { padding: 0; position: relative; }
/* 高度 20 < 行高 40 且垂直居中: 满高旗标在"整屏都是未读"时会首尾相接并成一条通栏竖轨,
   读起来是屏幕左边框而不是逐行标记 (真机实测 27 未读, 与 alarm_screen 同一结论)。 */
.flagbar { position: absolute; left: 0; top: 50%; transform: translateY(-50%); height: 20px; width: 3px; background: var(--ink); }
.focus .flagbar { background: var(--paper); }

/* 应用管理双行行 (与固件 app_list_screen.cc 同坐标): 图标 x=16 / 文字 x=48 / 例外词右轴 284。
   四个子元素**绝对定位而非 flex**: flex 会让"有例外词"和"没例外词"的行内容高度不一致,
   名称基线逐行上下抖 (§12.9 轴线纪律)。 */
/* 应用管理行 (2026-08-07 双行 44 → 单行 40): 图标 16 / 名称 48..208 / 右列 token 216..284。
   .ab (12px 体积) 与 .as (16px 例外词) 共用同一条右轴, 二选一出现 —— 见 applist.js。 */
.list li.approw { display: block; position: relative; padding: 0; height: 40px; }
.approw .ai { position: absolute; left: 16px; top: 8px; line-height: 0; }
.approw .an { position: absolute; left: 48px; top: 12px; width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.approw .as { position: absolute; left: 216px; top: 12px; width: 68px; text-align: right; }
.approw .ab { position: absolute; left: 216px; top: 13px; width: 68px; text-align: right; }

/* 焦点: 整行反色 (核心决定); 图标用 currentColor 自动反白 */
.focus { background: var(--ink) !important; color: var(--paper) !important; }
.focus * { color: var(--paper) !important; }

/* 保守焦点 (验收切换): 左 8px 黑条 + 2px 黑框, 不整行反色 */
body.conservative .focus { background: var(--paper) !important; color: var(--ink) !important;
  box-shadow: inset 8px 0 0 var(--ink), inset 0 0 0 2px var(--ink); }
body.conservative .focus * { color: var(--ink) !important; }
body.conservative .g.focus { box-shadow: inset 0 0 0 3px var(--ink); }

/* 图标尺寸 */
.ico { width: 24px; height: 24px; flex: none; }
.ico-12 { width: 12px; height: 12px; } .ico-16 { width: 16px; height: 16px; }
.ico-24 { width: 24px; height: 24px; } .ico-32 { width: 32px; height: 32px; }
.ico-batt { width: 20px; height: 12px; }

/* 单色屏进度条 (离散分段进度已迁 segbar, 见"精致化层") */
/* 细条比例进度 (与固件 ui_widgets MakeProgressBar 同一套几何):
   1px 外框 + **1px 白缝** + 实心内填。白缝不是留白洁癖 —— 1bpp 下内填与外框都是黑,
   不留缝的话 90% 和 100% 长得一模一样 (100% 时内填直接顶到框上并成一块实心)。
   高度 8 = 1框 + 1缝 + 4内填 + 1缝 + 1框, 内填 4px 在反射屏上认得出来。
   颜色走 currentColor: 放进 .focus 焦点行会自动翻白 (对应固件 RepaintProgressBar)。 */
.prog {
  display: inline-block; height: 8px; box-sizing: border-box;
  border: 1px solid currentColor; padding: 1px; vertical-align: middle;
}
.prog i { display: block; height: 100%; background: currentColor; }

/* 网格 (launcher) —— 格 75×70, 三条绝对基线, 无格线 (与固件 launcher_screen.cc 同版式) */
.grid { display: grid; gap: 0; }
.grid .g { height: 70px; position: relative; }
.grid .g .gi { position: absolute; top: 12px; left: 0; width: 100%; text-align: center; line-height: 0; }
.grid .g .gi svg { display: inline-block; }
/* 名称 16px (中文一律 ≥16px) + 固定宽 69 + 省略号, 长名字不再压邻格 */
.grid .g .gl {
  position: absolute; top: 44px; left: 3px; width: 69px; font-size: 16px; line-height: 20px;
  text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* 未读条数徽标 (右上, 反色小块): 焦点格上必须再反一次, 否则黑底黑徽标直接消失 */
.grid .g .gb {
  position: absolute; top: 3px; right: 3px; padding: 1px 3px; font-style: normal;
  background: var(--ink); color: var(--paper);
}
.focus .gb { background: var(--paper) !important; color: var(--ink) !important; }
/* 装机状态角标 (左上 16px 剪影): 失败/下载中/有更新, 三者互斥只画一个 */
.grid .g .gs { position: absolute; top: 3px; left: 3px; line-height: 0; }
.dot { position: absolute; width: 8px; height: 8px; background: var(--ink); }
.dot-r { top: 5px; right: 4px; } .dot-l { top: 5px; left: 4px; }
.focus .dot { background: var(--paper); }

/* 设置: 左图标轨 + 右二级 (2026-08-07 第五轮, 与固件 settings_screen.cc 同版式)
   旧版 .two-col 的两道 **1px dashed** (左右栏竖分隔 + 每行底部横分隔) 已删 —— CSS
   dashed 在 1bpp 阈值化后整条消失, 真机从来没显示过, 却在预览里制造了"表格感"。
   行与行仍然只靠 38px 行高留白。左右分栏 2026-08-07 补回一条**虚轨**, 但不是
   border-dashed, 而是**画出来的实心点**: 2px 宽 / 6 实 6 空 (占空比 50%)。
   1bpp 没有灰阶, 低密度点线不是"细"是"没有" —— 同一条教训早就砍掉过 MakeSegBar 的
   逐格短横。它落在 80..96 白缝正中 (x=87), 与左右两侧的焦点反色块都不接触。 */
.set-wrap { position: relative; height: 100%; }
.set-rail { position: absolute; left: 0; top: 0; width: 80px; height: 100%; }
.set-rail .rw { position: absolute; left: 0; width: 80px; height: 48px; }
.set-rail .rw .ri { position: absolute; left: 16px; top: 12px; line-height: 0; }
.set-rail .rw .rn { position: absolute; left: 44px; top: 16px; font-size: 16px; line-height: 16px; }
/* 当前组旗标: 3px 实心竖条贴左边缘, 进二级后**不撤** —— 它才是"我在哪一组"的常驻锚点 */
.set-flag { position: absolute; left: 0; width: 3px; height: 32px; background: var(--ink); }
.set-col { position: absolute; left: 96px; top: 0; width: 188px; height: 100%; }
.set-row { position: relative; height: 38px; }
.set-row .sn { position: absolute; left: 0; top: 4px; width: 110px; font-size: 16px; line-height: 16px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.set-row .sv { position: absolute; left: 112px; top: 4px; width: 76px; text-align: right;
  font-size: 16px; line-height: 16px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.set-row .sb { position: absolute; left: 0; top: 21px; width: 188px; font-size: 12px; line-height: 16px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.set-row .sb16 { top: 19px; font-size: 16px; line-height: 16px; }   /* WiFi 的 SSID 可能含中文 */
.set-row .sc { position: absolute; right: 0; top: 11px; }           /* 复选框 */
.set-row .sg { position: absolute; right: 0; top: 7px; }            /* 音量细条进度 */
/* 左右分栏虚轨: 与固件 kDashX/kDashW/kDashY0/kDashY1/kDashOn/kDashOff 同一套常量。
   用 repeating-linear-gradient 而不是 border-dashed —— 后者的实/空比例由浏览器定,
   与固件逐块 MakeRect 出来的点阵对不上。 */
.set-dash {
  position: absolute; left: 87px; top: 24px; width: 2px; height: 320px;
  background: repeating-linear-gradient(to bottom, currentColor 0 6px, transparent 6px 12px);
}
.set-row .sx { position: absolute; right: 0; top: 4px; line-height: 0; }  /* chevron 剪影 */

/* 电池/电源 (2026-08-07 第五轮, 与固件 battery_screen.cc 同一批 y 常量)
   仪表区全绝对定位 (报眼 22 / 电量条 54 / 派生行 78 / CPU 柱 116 / 分区线 146),
   控制行 30px 一行; 非长续航档的两行由 JS 直接不渲染 (固件用 HIDDEN 自动塌陷)。 */
.bat { position: relative; height: 100%; }
/* CPU 主频柱状图: 27 根 × 8px + 26 缝 × 2px = 268 (= 27 秒历史铺满内容宽)。
   每根至少 1px 地板 —— "睡着了"该是一条贴地的连续基线, 不是一片空白。 */
.bat .cpu { position: absolute; left: 16px; width: 268px; height: 20px; }
.bat .cpu i { position: absolute; bottom: 0; width: 8px; background: currentColor; }
.bat-row { position: relative; height: 30px; }
.bat-row .bn { position: absolute; left: 16px; top: 7px; font-size: 16px; line-height: 16px; }
.bat-row .bv { position: absolute; right: 16px; top: 7px; width: 150px; text-align: right;
  font-size: 16px; line-height: 16px; }
.bat-row .bc { position: absolute; right: 16px; top: 7px; }   /* 开关复选框 */

/* 关于设备 (2026-08-07 第五轮, 与固件 about_screen.cc 同一批常量)
   两条轴: 标签左轴 16 / 值右轴 284。**不居中** —— 规格表居中会让每行的值从不同 x
   起跳, 眼睛没有可扫的竖直边。四条占用条把"已用 vs 总量"画成同一个形状 (§12.7)。 */
.ab { position: relative; height: 100%; }
.ab-bar { position: absolute; left: 16px; width: 268px; height: 20px; }
.ab-bar .bl { position: absolute; left: 0; top: 0; font-size: 16px; line-height: 16px; }
.ab-bar .bs { position: absolute; left: 60px; top: 3px; }              /* 条 76..183 */
.ab-bar .bn { position: absolute; left: 175px; top: 2px; width: 93px; text-align: right; }
.ab-row { position: absolute; left: 16px; width: 268px; height: 20px; }
.ab-row .rl { position: absolute; left: 0; top: 0; font-size: 16px; line-height: 16px; }
.ab-row .rv { position: absolute; left: 104px; top: 3px; width: 164px; text-align: right; }

/* 复选框 (闹钟) */
.cbx { width: 16px; height: 16px; border: 1px solid currentColor; flex: none; display: inline-flex; align-items: center; justify-content: center; }
.cbx svg { width: 14px; height: 14px; }

/* 大字时钟占位 (示意需新增 1bpp 位图字体) */
.note-font { outline: 1px dashed #9a9a9a; outline-offset: 2px; }
.bignum { font-size: 72px; line-height: 1; letter-spacing: 1px; }

/* ============================================================
   精致化层 (2026-08 重设计): 像素图标 / 图表 / 纹理 / 版面构件
   —— 详见 .claude/skills/lightbox-ui-design/SKILL.md §12
   ============================================================ */

/* 像素图标 (core/glyphs.js): 实心剪影, 1:1 像素栅格, 随 .focus 反色 */
.px { display: block; flex: none; }
.chart { display: block; }
.chart text { font-family: inherit; }

/* 大数字: 固件已有 lv_font_dclock_72 (Montserrat-Medium, 仅 0-9 与 ":"),
   故 .dnum 不加"需新增字体"虚线框; 其它超 24px 字仍须 .note-font 标注。 */
.dnum {
  font-family: "Montserrat", "DIN Alternate", "Helvetica Neue", Arial, sans-serif;
  line-height: 1; letter-spacing: 0; font-variant-numeric: tabular-nums;
}
.dnum-72 { font-size: 72px; }
.dnum-40 { font-size: 40px; }        /* 需新增 lv_font_dnum_40 (仅 0-9 . - ℃), 见 SKILL §12.6 */
.unit { font-size: 24px; line-height: 1; }

/* 眉标 (kicker): 报纸式小标, 字距拉开。**只放英文/数字/短标签**,
   12px 中文笔画仅 1px, 在反射屏上是"寡淡"的技术根因 — 中文正文一律 ≥16px。 */
.kicker { font-size: 12px; line-height: 16px; letter-spacing: 2px; }
/* 眉标位上放**数据串**(而非 ABOUT/POWER 这类标识词)时叠这个类撤掉字距:
   2px 字距落在 15~21 字符的数据串上凭空多出 30~40px, 固件那侧的定宽标签会直接折行
   (对应 ui_widgets.cc 的 KickerAsData)。 */
.kdata { letter-spacing: 0; }

/* 规矩线 —— 少即是多。细线数量是"调试感"的第一来源, 每屏 ≤3 条。
   跨区块优先用 16px 留白 (不画线); 必须强分区时用 3px 粗线, 而不是两条细线。 */
.rule3 { height: 3px; background: var(--ink); }
.rule1 { height: 1px; background: var(--ink); }

/* 旗标 (flag): 中文位图字没有字重, 用「3px 实心竖条 + 8px 间隙」代替粗体。
   必须 3px —— 1px 会消失, 2px 显弱。 */
.flag { display: flex; align-items: center; gap: 8px; }
.flag::before { content: ""; width: 3px; align-self: stretch; background: var(--ink); flex: none; }

/* 出血反色条 (bleed): 每屏唯一的"强调重锤", 左右出血到 0/299 不留边距。
   黑面积须 < 屏高 15% (=60px), 否则反射屏发脏。 */
.bleed { display: flex; align-items: center; gap: 8px; background: var(--ink); color: var(--paper); padding: 0 var(--edge); }
.bleed * { color: var(--paper); }

/* 抖动纹理 = 1bpp 的"第三种色"。纪律: 只三档密度; 只填**面**(≥24×24), 线/文字/小图标一律实心;
   相位按 (x+y)%2 全局统一, 相邻块不得错相; 带抖动的元素移动必须 2px 量化, 否则满屏闪。
   ≤12.5% 密度在这个 ppi 下是脏点, 不提供。 */
.tex25, .tex50, .tex75 { image-rendering: pixelated; }
.tex25 { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='2' height='2' shape-rendering='crispEdges'%3E%3Crect width='1' height='1'/%3E%3C/svg%3E"); background-size: 2px 2px; }
.tex50 { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='2' height='2' shape-rendering='crispEdges'%3E%3Crect width='1' height='1'/%3E%3Crect x='1' y='1' width='1' height='1'/%3E%3C/svg%3E"); background-size: 2px 2px; }
.tex75 { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='2' height='2' shape-rendering='crispEdges'%3E%3Crect width='2' height='2'/%3E%3Crect x='1' fill='%23fff' width='1' height='1'/%3E%3C/svg%3E"); background-size: 2px 2px; }
/* 无分隔线列表: 靠行高留白分组。每屏细线 ≤3 条是"精致"最省力的一条纪律 */
.list.plain > li { border-bottom: 0; }

/* 水平线纹: 竖向滚动按 2px 走不闪、横向滚动完全不闪 —— 斑马纹优先用它而非棋盘 */
.stripe { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1' height='2' shape-rendering='crispEdges'%3E%3Crect width='1' height='1'/%3E%3C/svg%3E"); background-size: 1px 2px; image-rendering: pixelated; }

/* 反色标签 (chip): 比"整行反色"更小的强调单位, 用于报头刊名/编号/预警级别。
   黑面积小, 不触发反射屏残影, 可与列表焦点共存。 */
.chip { display: inline-block; background: var(--ink); color: var(--paper); padding: 1px 5px; font-size: 12px; line-height: 16px; }
.chip .px { color: var(--paper); }
.chip-24 { font-size: 16px; line-height: 22px; padding: 1px 7px; }

/* 数据格组: 2~4 个等宽格, 竖细线分隔 (表格感, 比逗号连排的文字体面) */
.cells { display: flex; align-items: stretch; }
.cells > div { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; border-left: 1px solid var(--ink); }
.cells > div:first-child { border-left: 0; }
/* 值 24 / 标签 16 —— 标签是中文, 不能降到 12px (1px 笔画在反射屏上等于没有) */
.cells .cv { font-size: 24px; line-height: 28px; }
.cells .cl { font-size: 16px; line-height: 20px; }

/* 分段条 (segbar): 离散进度的统一基元 (EXP / 旅程进度 / NPC 好感共用一套)。
   未填充段 = 一条通长 2px 底轨而非空心框: 空心框会让"细线数量"这个精致度杀手直接失控 (§12.3)。
   底部对齐让实心段与底轨共用一根基线, 眼睛沿基线一扫就读出比例, 不必逐格数。
   底轨必须**通长** (::after), 不能是逐格短横 —— 短横之间留着 gap 宽的白缝, 低填充率下
   (1/20) 整条读作虚线噪点而不是轨道, 真机实测。与固件 MakeSegBar 同一实现。
   背景取 currentColor —— 进 .bleed / .focus 反色区自动翻白, 与 §11.2 同一条纪律。 */
.segbar { display: inline-flex; align-items: flex-end; flex: none; vertical-align: bottom; position: relative; }
.segbar::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 2px; background: currentColor; }
.segbar i { display: block; flex: none; background: currentColor; }

/* 报头 (masthead): 刊名 + 日期/期号, 双线收口 —— 新闻/资讯类的身份标识 */
.mast { display: flex; align-items: baseline; gap: 6px; padding: 0 var(--edge); height: 20px; }
.mast .name { font-size: 16px; letter-spacing: 4px; }
.mast .meta { margin-left: auto; font-size: 12px; }

/* 序号: 报纸式条目编号 (反色方块), 24px 见方 */
.ord { width: 20px; height: 20px; background: var(--ink); color: var(--paper); font-size: 12px; display: flex; align-items: center; justify-content: center; flex: none; }
.ord.o-hollow { background: var(--paper); color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink); }

/* 页码刻度: 用刻度代替滚动条, 当前页加长加粗 */
.pagerule { display: flex; align-items: flex-end; gap: 3px; height: 8px; }
.pagerule i { width: 2px; height: 3px; background: var(--ink); display: block; }
.pagerule i.on { height: 8px; width: 3px; }

/* 当前天气行 */
.wrow { display: flex; align-items: center; justify-content: center; gap: 6px; margin-top: 4px; }

/* 键盘网格 */
.kbd { display: grid; grid-template-columns: repeat(8, 1fr); }
.kbd .key2 {
  height: 30px; display: flex; align-items: center; justify-content: center;
  border-right: 1px dashed var(--ink); border-bottom: 1px dashed var(--ink); font-size: 14px;
}
.kbd .key2:nth-child(8n) { border-right: none; }

/* 滚动位置点 (替代滚动条) */
.scrolldot { position: absolute; right: 3px; top: 50%; transform: translateY(-50%); display: flex; flex-direction: column; gap: 4px; }
.scrolldot i { width: 4px; height: 4px; background: var(--ink); display: block; }
.scrolldot i.off { background: var(--paper); border: 1px solid var(--ink); }

/* 二维码点阵占位 (实机由 OverlayQR 写主 buffer) */
.qr {
  background-image:
    repeating-linear-gradient(90deg, var(--ink) 0 4px, var(--paper) 4px 8px),
    repeating-linear-gradient(0deg, var(--ink) 0 4px, var(--paper) 4px 8px);
  background-blend-mode: difference; border: 4px solid var(--paper); outline: 1px solid var(--ink);
}

/* Toast 底部提示条 (2026-08-07): 左轴 x=16 + 铃铛剪影 + 16px 正文 + 3px 粗上线。
   旧版 justify-content:center + 12px 是手机 toast 语言, 与全机左轴打架且中文笔画只剩 1px;
   1px 上边框在反射屏对比不足, 改一条 3px 实心线 (§12.3)。不做满幅出血反色 —— 底层页
   内容区底部本来就有出血条, 再叠一条就是两块相邻黑带 (§12.4)。 */
.toast {
  position: absolute; left: 0; right: 0; bottom: 0; height: 32px;
  display: flex; align-items: center; gap: 8px; padding: 0 var(--edge);
  border-top: 3px solid var(--ink); background: var(--paper); font-size: 16px;
}

/* AI 浮层 (2026-08-07): 屏幕下部 176px 满宽**不透明**白底, 无描边。
   不透明是硬要求 —— 它要压住底层页自己的底部出血条, 否则一屏两块黑;
   1px dashed 描边框既不是本机版面语言 (全机只此一处), 在反射屏上对比也不足。
   内部结构由 c.aiOverlay 给: 顶部 .bleed 出血状态条 + 眉标消息块。 */
.overlay {
  position: absolute; left: 0; right: 0; bottom: 0; height: 176px;
  background: var(--paper); display: flex; flex-direction: column;
}

/* 弹窗卡片 */
.card {
  position: absolute; left: 24px; right: 24px; top: 50%; transform: translateY(-50%);
  border: 1px solid var(--ink); background: var(--paper); padding: 12px;
}
.card .btns { display: flex; gap: 10px; margin-top: 12px; }
.card .btn { flex: 1; text-align: center; border: 1px solid var(--ink); padding: 4px 0; font-size: 16px; }
.card .btn.focus { border-width: 2px; }
