/* ============================================================
 * v6 扩展样式：Win3.1/3.2 原版字体 · Win95 指针 · CRT 自定义 ·
 *              全能编辑器 · 聊天 · 网盘 · 控制台
 * ============================================================ */
/* ---------- 原版风格字体 ---------- */
@font-face {
  font-family: 'MSSansPixel';
  src: url('../assets/fonts/ms_sans_serif.woff2') format('woff2'),
       url('../assets/fonts/ms_sans_serif.woff') format('woff');
  font-weight: 400; font-display: swap;
}
@font-face {
  font-family: 'MSSansPixel';
  src: url('../assets/fonts/ms_sans_serif_bold.woff2') format('woff2');
  font-weight: 700; font-display: swap;
}
@font-face {
  font-family: 'ZpixCJK';
  src: url('../assets/fonts/zpix-zpix.ttf') format('truetype');
  font-display: swap;
}
/* Windows 3.1 的原版系统字体（用户提供）：全局默认字体。
   注意：该字体只有 204 个字形，仅覆盖 Latin / Latin-1 / 西里尔与少数
   排版符号，**完全没有 CJK**。所以它必须排在最前、后面接中文点阵字体，
   中文才会自动回退（见 --font-31）。 */
@font-face {
  font-family: 'Win31System';
  src: url('../assets/fonts/win31-system.otf') format('opentype');
  font-weight: 400; font-display: swap;
}

:root {
  --font-31: 'SimSun31', 'Win31System', 'MSSansPixel', 'ZpixCJK', 'F31Hans', 'F31Hant', monospace;
  --crt-w: 2px;
  --crt-gap: 4px;
  --crt-speed: 45s;
  --crt-shade: .16;
  --crt-corner: 42px;
  --crt-vignette: .38;
  --wallpaper: none;
  --res-scale: 1;
  --ui-scale: 1;
  /* p53：抖动网点的**唯一尺寸来源**。必须除掉 zoom（body{zoom:var(--ui-scale)}）：
     写死的 2px 在 zoom 1.2 下会被放大成 2.4 设备像素 ⇒ 网点单元格 = zoom 个设备像素
     （100%→周期 2、200%→4、300%→6、120% 干脆不重复），大面积看就是「网格状重复纹路」= 摩尔纹。
     除以 zoom 后 tile 恒为 4 设备像素 ⇒ 每格恰好 1 设备像素，任何缩放下周期都是 2。
     ⚠️ p58 追加除以 --res-scale：`#desktop` 上还有一条 `transform:scale(var(--res-scale))`
     （分辨率设置，见下方 #desktop 规则），它同样会把网点贴图整体放大。
     只除 --ui-scale 时，分辨率设成 105% 会让 tile 变成 4.2 设备像素 ⇒ 每 ~5 格就错开一个像素，
     屏幕上出现密集的「方格边界」。两个缩放因子都除掉后，tile 恒为 4 设备像素。 */
  --dither-tile: calc(4px / (var(--ui-scale, 1) * var(--res-scale, 1)));
}
body, .win, .btn31, .input31, select, textarea, .menu-bar, .titlebar, .cp-root, .cp-root * {
  font-family: var(--font-31);
}
body { font-size: 12px; }

/* 整站缩放（分辨率调整） */
#desktop {
  background-image: var(--wallpaper);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  width: calc(100% / var(--res-scale));
  height: calc(100% / var(--res-scale));
  transform: scale(var(--res-scale));
  transform-origin: top left;
}

/* ---------- Windows 95 像素指针 ---------- */
body { cursor: var(--cur-arrow, default); }
button, .btn31, .clickable, .menu-item, .tb-btn, .tray-icon, .calc-btn, .pt-tool, label { cursor: var(--cur-hand, pointer); }
input, textarea, [contenteditable="true"] { cursor: var(--cur-text, text); }
body.tool-move, body.tool-move * { cursor: var(--cur-move, move); }
body.tool-cross, body.tool-cross * { cursor: var(--cur-cross, crosshair); }
body.tool-drag, body.tool-drag * { cursor: var(--cur-no, not-allowed); }
body.busy, body.busy * { cursor: var(--cur-wait, wait) !important; }
.resize-n, .resize-s { cursor: var(--cur-ns, ns-resize) !important; }
.resize-e, .resize-w { cursor: var(--cur-ew, ew-resize) !important; }
.resize-ne, .resize-sw { cursor: var(--cur-nesw, nesw-resize) !important; }
.resize-nw, .resize-se { cursor: var(--cur-nwse, nwse-resize) !important; }

/* ---------- 按钮：点击绝不放大 ---------- */
button, .btn31, .calc-btn, .cp-cat, .tb-btn, .pt-tool, .ck-cell, .cm-cell {
  transform: none !important; transition: none !important;
}
button:active, .btn31:active, .calc-btn:active { transform: none !important; }
button:focus, .btn31:focus { outline: 1px dotted #000; outline-offset: -3px; }

/* ---------- CRT 滤镜：等宽扫描线 + 慢速滚动 + 明显四角畸变 ---------- */
#crt-overlay {
  position: fixed; inset: 0; pointer-events: none; z-index: 99996;
  border-radius: var(--crt-corner);
  background-image: repeating-linear-gradient(to bottom,
    rgba(0, 0, 0, var(--crt-shade)) 0 var(--crt-w),
    rgba(0, 0, 0, 0) var(--crt-w) var(--crt-gap));
  background-size: 100% var(--crt-gap);
  animation: crt-scroll var(--crt-speed) linear infinite, crt-jitter 9s steps(1) infinite;
  box-shadow: inset 0 0 150px rgba(0, 0, 0, var(--crt-vignette));
}
#crt-overlay::after {
  content: ''; position: absolute; inset: 0; border-radius: var(--crt-corner);
  background:
    radial-gradient(130% 130% at 50% 50%, rgba(0,0,0,0) 52%, rgba(0,0,0,.42) 100%),
    radial-gradient(60% 60% at 50% 50%, rgba(255,255,255,.05) 0%, rgba(255,255,255,0) 70%);
}
@keyframes crt-scroll { 0% { background-position-y: 0; } 100% { background-position-y: var(--crt-gap); } }
@keyframes crt-jitter {
  0%, 92% { transform: none; opacity: .96; }
  93% { transform: translateY(1px); opacity: 1; }
  94% { transform: translateX(-1px); }
  95% { transform: translateY(-1px); opacity: .94; }
  96%, 100% { transform: none; opacity: .96; }
}
body.crt-flicker-off #crt-overlay { animation: crt-scroll var(--crt-speed) linear infinite; }
/* ⚠️ p58：这里原来写的是 `scale(calc(var(--res-scale) * 1.004))` —— 那个 1.004 是
   「CRT 弧面」的遗留凑数，没有任何视觉收益，却会让 #desktop 的抖动网点被重采样
   （每累计 1/0.004 = 250 设备像素错开一个像素 ⇒ 可见的方格边界）。
   真正的曲度由 js/effects2.js 的 applyWarp() 给 #crt-overlay 加四角圆弧表达。
   顺便：`body.crt-warp` 这个类名全站没有任何地方加过（开关用的是 `pf-warp`），
   这条规则本来也是死代码，保留只是为了不让老存档里的样式意外生效。 */
body.crt-warp #desktop {
  border-radius: calc(var(--crt-corner) - 8px);
  transform: scale(var(--res-scale));
  box-shadow: inset 0 0 60px rgba(0,0,0,.35);
}

/* ---------- DOS 终端：可滚动但无滚动条 ---------- */
#dos-screen { overflow-y: auto; overflow-x: hidden; scrollbar-width: none; -ms-overflow-style: none; }
#dos-screen::-webkit-scrollbar { width: 0 !important; height: 0 !important; display: none !important; }
/* p113/p116：DOS 字符屏里「Type WIN to start Windows」那几行 = 可点区域（触屏点它进 Windows）。
   ⚠️⚠️ p116 真机修复 —— 真正的命中盒**在伪元素上，不在 span 自己的 padding 上**。
   p113 当初给 span 加上下 padding 是想「撑大可点范围又不改行盒高度」，理论上没错
   （inline 元素的上下 padding 确实不参与行盒高度，CSS 2.1 §10.6.1 ⇒ 截图逐像素不变），
   但那只是「不改变排版」，**不等于「真的扩了命中区」**：实测（elementFromPoint 逐像素扫）
   span 外接矩形高 48 viewport px，真实可点带只有 37，而且**偏在上半**、下缘差 13px。
   于是：鼠标能精确命中那条窄带 ⇒ 电脑端正常；手指按精确落点命中（WebKit 没有 Blink 的
   「触摸吸附」）⇒ 真 iPad 上点不动。根因就是这个。
   ⇒ 改用伪元素当命中盒：它是**块级盒**，各引擎命中测试行为一致；绝对定位 ⇒ **完全脱流**，
     既不参与行盒高度、也不参与任何布局 ⇒ 排版与像素零影响（比 padding 那条路更干净）。
   ⚠️ ±7px 是上限：行距 16px ⇒ 命中盒半高 15px < 相邻行中心 16px，不会吃掉邻行正中。
   ⚠️ 右边用「+200px padding / −200px margin」把可点区域铺满整行宽 —— inline 元素的
   margin 盒总宽不变（两者相消）⇒ 排版零影响；超出 640px 的部分被 overflow-x:hidden 裁掉，
   正好停在字符屏右边界。
   ⚠️ `touch-action:manipulation` 免掉双击缩放与 300ms 点击延迟；
   tap-highlight 置透明，点下去不闪高亮框（字符屏保持原样）。 */
.dos-winlink {
  position: relative;
  padding-right: 200px; margin-right: -200px;
  touch-action: manipulation; -webkit-tap-highlight-color: transparent;
}
.dos-winlink::after {
  content: ''; position: absolute; left: 0; right: 0; top: -7px; bottom: -7px;
}

/* ---------- 控制面板 / 管理面板：Win3.1 像素风侧栏 ---------- */
.cp-root, .cp-root * { font-family: var(--font-31) !important; font-size: 12px; }
.cp-side {
  background: #c0c0c0 !important;
  border-right: 1px solid #808080 !important;
  padding: 4px !important; gap: 0 !important;
}
.cp-cat {
  text-align: left; padding: 3px 6px;
  background: #c0c0c0; border: none;
  box-shadow: inset 1px 1px 0 #fff, inset -1px -1px 0 #808080, 0 0 0 1px #000;
  margin-bottom: 3px;
}
.cp-cat:hover { background: #d0d0d0; }
.cp-cat.active { background: #dfdfdf; box-shadow: inset 1px 1px 0 #808080, inset -1px -1px 0 #fff, 0 0 0 1px #000; font-weight: bold; }
.cp-cat .cp-ic { color: #000080; font-family: var(--font-31); }
.cp-main { background: #dfdfdf !important; border-left: 1px solid #808080; }
.cp-head { background: #000080; color: #fff; padding: 2px 6px; font-weight: bold; }
.cp-set-group { margin: 8px 0 3px; background: #c0c0c0; border: 1px solid #808080; padding: 2px 6px; color: #000080; font-weight: bold; }
.cp-set-item { border-bottom: 1px dotted #a0a0a0; }
.cp-note { color: #404040; }

/* ---------- 聊天（私信 / 群聊）：Win3.1 风格全能聊天框 ---------- */
.ct-root { display: flex; height: 100%; background: #c0c0c0; font-family: var(--font-31); }
.ct-side { width: 168px; min-width: 168px; border-right: 1px solid #808080; overflow-y: auto; background: #c0c0c0; }
.ct-side-head { background: #000080; color: #fff; padding: 2px 5px; font-weight: bold; }
.ct-conv { display: flex; gap: 4px; align-items: center; padding: 3px 4px; border-bottom: 1px solid #d0d0d0; cursor: var(--cur-hand, pointer); }
.ct-conv:hover { background: #d8d8ff; }
.ct-conv.active { background: #0000a8; color: #fff; }
.ct-conv .ct-on { width: 6px; height: 6px; background: #00a800; border: 1px solid #000; }
.ct-conv .ct-on.off { background: #808080; }
.ct-main { flex: 1; min-width: 0; display: flex; flex-direction: column; background: #dfdfdf; }
.ct-head { display: flex; align-items: center; gap: 6px; padding: 3px 6px; border-bottom: 1px solid #808080; background: #c0c0c0; }
.ct-log { flex: 1; overflow-y: auto; padding: 6px; background: #fff; }
.ct-daysep { text-align: center; color: #808080; font-size: 11px; margin: 6px 0 3px; }
.ct-msg { display: flex; gap: 5px; margin-bottom: 6px; align-items: flex-start; }
.ct-msg.mine { flex-direction: row-reverse; }
.ct-msg .ct-av { width: 24px; height: 24px; border: 1px solid #000; image-rendering: pixelated; }
.ct-bubble { border: 1px solid #808080; padding: 3px 6px; max-width: 74%; background: #ffffe1; word-break: break-word; }
.ct-msg.mine .ct-bubble { background: #dfffdf; }
.ct-name { font-size: 11px; color: #000080; }
.ct-time { font-size: 11px; color: #808080; margin-left: 5px; }
.ct-poke { background: #ffffd0; color: #a80000; border-color: #a80000; }
.ct-sys { text-align: center; color: #000080; font-size: 11px; margin: 4px 0; }
.ct-composer { border-top: 1px solid #808080; background: #c0c0c0; }
.ct-tools { display: flex; flex-wrap: wrap; gap: 2px; padding: 3px; border-bottom: 1px solid #dfdfdf; }
.ct-tools .btn31 { min-width: 0; padding: 1px 5px; font-size: 12px; }
.ct-edit { min-height: 44px; max-height: 150px; overflow-y: auto; outline: none; background: #fff; border: 2px inset #fff; padding: 4px; margin: 3px; }
.ct-edit:empty::before { content: attr(data-ph); color: #999; }
.ct-bar { display: flex; gap: 4px; align-items: center; padding: 3px; }
.ct-bar .input31 { flex: 1; min-width: 0; }
.ct-kao, .ct-share, .ct-poll { position: fixed; z-index: 100001; background: #ffffe1; border: 2px outset #fff; box-shadow: 2px 2px 5px rgba(0,0,0,.4); padding: 5px; max-height: 260px; overflow-y: auto; }
.ct-kao { width: 300px; }
.ct-kao-cat { font-weight: bold; color: #000080; margin: 3px 0 1px; background: #dfdfdf; padding: 0 4px; }
.ct-kao-row { display: flex; flex-wrap: wrap; gap: 3px; }
.ct-kao-btn { background: none; border: 1px solid transparent; padding: 1px 3px; font-size: 12px; }
.ct-kao-btn:hover { border-color: #000080; background: #fff; }
.ct-flame { color: #c04000; font-weight: bold; }
.ct-streak { border: 1px solid #808080; background: #fff; padding: 3px 5px; margin: 4px 2px; }
.ct-poll-box { border: 1px solid #000080; background: #fff; padding: 6px; margin: 4px 0; }
.ct-poll-opt { display: block; margin: 3px 0; }
.ct-poll-bar { height: 12px; border: 1px solid #808080; background: #dfdfdf; margin-top: 2px; }
.ct-poll-in { height: 100%; background: #000080; }
.ct-group-panel { border-left: 1px solid #808080; width: 180px; min-width: 180px; background: #c0c0c0; overflow-y: auto; }
.ct-member { display: flex; gap: 4px; align-items: center; padding: 2px 4px; border-bottom: 1px dotted #b0b0b0; }
.ct-member .btn31 { margin-left: auto; padding: 0 4px; }
.ct-share-card { border: 1px solid #0000a8; background: #f0f0ff; padding: 4px 6px; }
.ct-wave { display: flex; align-items: flex-end; gap: 2px; height: 22px; }
.ct-wave i { display: block; width: 2px; background: #000080; }
.ct-voice { border: 1px solid #000080; background: #fff; padding: 2px 6px; }
.ct-online { font-size: 11px; color: #008000; }
.ct-online.off { color: #808080; }

/* ---------- 全能编辑器（Word 风格） ---------- */
.wd-root { display: flex; flex-direction: column; height: 100%; background: #c0c0c0; }
.wd-bars { flex: none; background: #c0c0c0; border-bottom: 1px solid #808080; }
.wd-bar { display: flex; flex-wrap: wrap; gap: 2px; align-items: center; padding: 2px 3px; justify-content: flex-start; }
.wd-bar > .cp-note { flex: 0 0 100px; white-space: nowrap; text-align: left; }
.wd-bar-btns { display: flex; flex-wrap: wrap; gap: 2px; flex: 1; align-items: center; justify-content: flex-start; min-width: 0; }
.wd-bar-btns .wd-b { flex: 0 0 auto; }
.wd-bar + .wd-bar { border-top: 1px solid #dfdfdf; }
.wd-sep { width: 1px; height: 16px; background: #808080; margin: 0 3px; }
.wd-b { min-width: 22px; padding: 1px 4px; font-size: 12px; }
.wd-b.sel { background: #d0d0d0; box-shadow: inset 1px 1px 0 #808080, inset -1px -1px 0 #fff, 0 0 0 1px #000; }
.wd-sel { height: 20px; font-size: 12px; }
.wd-ruler { height: 18px; background: #dfdfdf; border-bottom: 1px solid #808080; position: relative; background-image: repeating-linear-gradient(90deg, #808080 0 1px, transparent 1px 10px); }
.wd-canvas-wrap { flex: 1; overflow: auto; background: #808080; padding: 14px; }
.wd-page {
  background: #fff; color: #000; margin: 0 auto; padding: 48px 56px;
  box-shadow: 2px 2px 0 rgba(0,0,0,.4); min-height: 420px; outline: none;
  font-family: 'SimSun31', 'ZpixCJK', 'MSSansPixel', monospace; font-size: 13px; line-height: 1.7;
  position: relative;
}
.wd-page.watermark::before {
  content: attr(data-wm); position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-size: 46px; color: rgba(0,0,0,.10); transform: rotate(-24deg); pointer-events: none;
}
.wd-page table { border-collapse: collapse; }
.wd-page table td, .wd-page table th { border: 1px solid #808080; padding: 3px 5px; min-width: 40px; }
.wd-page img { max-width: 100%; }
.wd-page .wd-cap { font-size: 11px; color: #404040; text-align: center; }
.wd-status { flex: none; display: flex; gap: 8px; border-top: 1px solid #fff; background: #c0c0c0; padding: 2px 6px; font-size: 11px; }
.wd-status .wd-st { border: 1px solid #808080; border-top: none; padding: 0 6px; min-width: 60px; }
.wd-nav { width: 168px; min-width: 168px; border-right: 1px solid #808080; background: #dfdfdf; overflow-y: auto; padding: 4px; }
.wd-nav-item { padding: 1px 4px; cursor: var(--cur-hand, pointer); }
.wd-nav-item:hover { background: #000080; color: #fff; }
.wd-dlg { position: fixed; z-index: 100002; background: #c0c0c0; border: 1px solid #000; box-shadow: 3px 3px 0 rgba(0,0,0,.45); padding: 0; min-width: 300px; }
.wd-dlg .wd-dlg-t { background: #000080; color: #fff; padding: 2px 6px; font-weight: bold; }
.wd-dlg .wd-dlg-b { padding: 8px; display: flex; flex-direction: column; gap: 5px; }
.wd-dlg .wd-dlg-f { padding: 6px 8px; display: flex; gap: 5px; justify-content: flex-end; border-top: 1px solid #808080; }
.wd-row { display: flex; align-items: center; gap: 6px; }
.wd-row label { width: 92px; }
.wd-find-hit { background: #ffff00; }
.wd-cmt { background: #ffffd0; border-bottom: 1px dotted #a80000; }
.wd-ins { color: #0000a8; text-decoration: underline; }
.wd-del { color: #a80000; text-decoration: line-through; }
.wd-ai-out { border: 1px solid #000080; background: #ffffe1; padding: 5px; max-height: 150px; overflow-y: auto; white-space: pre-wrap; }

/* ---------- 网盘（文件管理） ---------- */
.nd-root { display: flex; flex-direction: column; height: 100%; background: #c0c0c0; }
.nd-toolbar { display: flex; flex-wrap: wrap; gap: 2px; padding: 3px; border-bottom: 1px solid #808080; }
.nd-crumb { display: flex; align-items: center; gap: 2px; padding: 2px 4px; background: #fff; border: 2px inset #fff; margin: 3px; font-size: 12px; }
.nd-crumb .nd-c { padding: 0 3px; cursor: var(--cur-hand, pointer); }
.nd-crumb .nd-c:hover { background: #000080; color: #fff; }
.nd-body { flex: 1; display: flex; min-height: 0; }
.nd-tree { width: 168px; min-width: 168px; border-right: 1px solid #808080; overflow-y: auto; background: #dfdfdf; padding: 3px; }
.nd-tree .nd-tn { padding: 1px 3px; cursor: var(--cur-hand, pointer); }
.nd-tree .nd-tn:hover { background: #000080; color: #fff; }
.nd-tree .nd-tn.active { background: #000080; color: #fff; }
.nd-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.nd-files { flex: 1; overflow-y: auto; background: #fff; border: 2px inset #fff; margin: 3px; padding: 4px; }
.nd-grid { display: flex; flex-wrap: wrap; gap: 10px; align-content: flex-start; }
.nd-item { width: 96px; padding: 4px; text-align: center; border: 1px solid transparent; cursor: var(--cur-hand, pointer); }
.nd-item:hover { background: #e8e8ff; border-color: #808080; }
.nd-item.sel { background: #000080; color: #fff; }
.nd-item .nd-ico { width: 32px; height: 32px; margin: 0 auto 2px; image-rendering: pixelated; display: block; }
.nd-item .nd-nm { font-size: 11px; word-break: break-all; line-height: 1.25; }
.nd-list { width: 100%; border-collapse: collapse; font-size: 12px; }
.nd-list th { background: #c0c0c0; border: 1px solid #808080; padding: 2px 5px; text-align: left; cursor: var(--cur-hand, pointer); }
.nd-list td { border-bottom: 1px dotted #c0c0c0; padding: 2px 5px; }
.nd-list tr.sel td { background: #000080; color: #fff; }
.nd-list tr:hover td { background: #e8e8ff; }
.nd-list tr.sel:hover td { background: #000080; }
.nd-compact { display: flex; flex-wrap: wrap; gap: 4px; }
.nd-compact .nd-c-item { border: 1px solid #d0d0d0; padding: 1px 5px; font-size: 12px; cursor: var(--cur-hand, pointer); }
.nd-compact .nd-c-item:hover { background: #000080; color: #fff; }
.nd-side { width: 210px; min-width: 210px; border-left: 1px solid #808080; background: #dfdfdf; overflow-y: auto; padding: 5px; }
.nd-side h4 { background: #000080; color: #fff; padding: 1px 5px; margin: 5px 0 3px; font-size: 12px; }
.nd-stat { border: 1px solid #808080; background: #fff; padding: 4px; margin-bottom: 5px; font-size: 11px; }
.nd-bar { height: 12px; border: 1px solid #808080; background: #dfdfdf; margin: 3px 0; }
.nd-bar-in { height: 100%; background: repeating-linear-gradient(90deg, #000080 0 6px, #1084d0 6px 10px); }
.nd-up { border: 1px solid #808080; background: #fff; padding: 4px; margin: 3px; max-height: 120px; overflow-y: auto; }
.nd-up-row { display: flex; gap: 5px; align-items: center; font-size: 11px; }
.nd-up-row .nd-prog { flex: 1; height: 10px; border: 1px solid #808080; background: #dfdfdf; }
.nd-up-row .nd-prog i { display: block; height: 100%; background: #000080; }
.nd-tag { display: inline-block; border: 1px solid #000080; background: #e8e8ff; padding: 0 4px; margin: 1px; font-size: 11px; }
.nd-menu { position: fixed; z-index: 100003; background: #c0c0c0; border: 1px solid #000; box-shadow: 2px 2px 0 rgba(0,0,0,.4); padding: 1px; min-width: 150px; }
.nd-menu .mi { padding: 2px 14px 2px 20px; font-size: 12px; }
.nd-menu .mi:hover { background: #000080; color: #fff; }
.nd-menu .sep { height: 1px; background: #808080; margin: 2px 0; }
.nd-preview { border: 2px inset #fff; background: #fff; padding: 6px; text-align: center; }
.nd-preview img { max-width: 100%; image-rendering: pixelated; }
.nd-preview pre { text-align: left; font-size: 12px; white-space: pre-wrap; max-height: 220px; overflow-y: auto; }
.nd-drop { position: fixed; inset: 0; background: rgba(0,0,128,.18); border: 3px dashed #000080; z-index: 100000; display: flex; align-items: center; justify-content: center; color: #000080; font-weight: bold; pointer-events: none; /* p118⑨：这层只是「松开鼠标即可上传」的文案浮层，**绝不能吃指针** —— 它是 position:fixed/inset:0 的全屏层，一旦可命中就会变成 drop 的落点：Chrome 在 dragover 后重算落点为 .nd-drop，而层上没人 preventDefault ⇒ drop 事件**根本不派发**（实测 events 里只有 dragenter/dragover/dragleave、没有 drop）⇒ 「从桌面拖文件进网盘」全程静默失败。加 pointer-events:none 后 drop 正常落到 .nd-files，上传成功。 */ }
.nd-share { position: fixed; z-index: 100004; background: #c0c0c0; border: 1px solid #000; box-shadow: 3px 3px 0 rgba(0,0,0,.4); }


/* 标题栏字号与图标比例 */
.titlebar .tb-title{font-size:var(--tb-fs,13px)}
.icon-img img{width:var(--icon-size,32px);height:var(--icon-size,32px);image-rendering:pixelated}
.icon-tray .icon-img img{width:var(--tray-size,32px);height:var(--tray-size,32px)}
.win{border-width:var(--win-bw,1px)}

/* ---------- 聊天页不再显示头像（统一隐藏） ---------- */
.ct-av, .ct-head img, .ct-msg img.ct-av, .ct-conv img { display: none !important; }
.ct-root { display: flex; height: 100%; min-height: 0; background: #c0c0c0; }
.ct-side { width: 168px; min-width: 168px; border-right: 1px solid #808080; display: flex; flex-direction: column; background: #c0c0c0; }
.ct-side-bar { display: flex; gap: 3px; padding: 3px; border-bottom: 1px solid #fff; }
.ct-side-bar .input31 { flex: 1; min-width: 0; }
.ct-list { flex: 1; overflow-y: auto; background: #fff; border: 1px solid #808080; margin: 3px; }
.ct-conv { display: flex; align-items: center; gap: 4px; padding: 4px 5px; border-bottom: 1px dotted #c0c0c0; font-size: 12px; }
.ct-conv:hover { background: #e8e8ff; }
.ct-conv.active { background: #000080; color: #fff; }
.ct-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.ct-msg { gap: 0; }
.ct-nick { cursor: pointer; color: #0000c0; }
.ct-bubble { border: 1px solid #808080; background: #ffffe1; padding: 3px 6px; max-width: 78%; }

/* ---------- 聊天：打卡卡片 / 选文面板 / 录音按钮 ---------- */
.ct-punch-card { border: 1px dashed #808080; background: #ffffe1; padding: 4px 6px; margin-top: 3px; cursor: pointer; }
.ct-audio { display: block; margin-top: 3px; }
.ct-pick { position: fixed; z-index: 100020; width: 250px; max-height: 260px; background: #c0c0c0;
  border: 2px outset #fff; box-shadow: 2px 2px 0 rgba(0,0,0,.4); display: flex; flex-direction: column; }
.ct-pick-h { background: #0000a6; color: #fff; padding: 2px 6px; font-weight: bold; }
.ct-pick-list { flex: 1; overflow-y: auto; background: #fff; }
.ct-pick-row { padding: 3px 6px; border-bottom: 1px dotted #c0c0c0; }
.ct-pick-row:hover { background: #e8e8ff; }
.btn31.active { box-shadow: inset 1px 1px 0 #404040, inset -1px -1px 0 #fff; background: #d0d0d0; }

/* ---------- 大指针 / 系统状态条 ---------- */
body.pf-bigpointer, body.pf-bigpointer * {
  cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='34' height='34' viewBox='0 0 34 34'%3E%3Cpath d='M3 2 L3 26 L9 21 L13 30 L17 28 L13 19 L22 19 Z' fill='%23fff' stroke='%23000' stroke-width='2'/%3E%3C/svg%3E") 2 2, auto !important;
}
.sys-strip { font-size: 11px; box-shadow: 1px 1px 0 #000; }

/* ---------- 评论树（楼中楼） ---------- */
.cm-row { border-left: 1px dotted #a0a0a0; padding: 2px 0 2px 5px; margin-top: 3px; }
.cm-child { background: #fbfbfb; }
.cm-line { color: #808080; margin-right: 3px; font-family: monospace; }
.cm-floor { background: #000080; color: #fff; padding: 0 3px; margin-right: 4px; font-size: 11px; }
.cm-user { color: #0000c0; }
.cm-title { color: #808080; font-size: 11px; }
.cm-time { color: #808080; font-size: 11px; margin-left: 4px; }
.cm-body { margin: 2px 0; line-height: 1.5; word-break: break-word; }
.cm-bar { display: flex; gap: 3px; flex-wrap: wrap; }
.cm-bar .btn31 { padding: 0 4px; }
.cm-input { border: 1px solid #808080; background: #fff; padding: 4px; margin: 4px 0; }
.cm-input textarea { width: 100%; box-sizing: border-box; resize: vertical; }
.cm-total { color: #808080; font-size: 11px; margin-top: 4px; }
.nw-views { color: #808080; font-size: 11px; }

/* ---------- p21: 对齐修复 ---------- */
.cp-main .login-row label { width: 118px; white-space: nowrap; }
.nw-editrow { text-align: right; padding: 4px 12px 4px 0; }
/* 文件管理器目录树图标 */
.nd-tico { display: inline-block; width: 16px; height: 16px; vertical-align: -3px; margin-right: 3px; }
.nd-tico svg { width: 16px; height: 16px; display: block; }
.nd-ico svg { width: 100%; height: 100%; display: block; }

/* ---------- p22：原生 Win3.1 对话框 ---------- */
.nd31-overlay { position: fixed; inset: 0; z-index: 9000; display: flex; align-items: center; justify-content: center; }
.nd31-box { min-width: 300px; max-width: 460px; background: var(--face); border: 2px outset var(--face); box-shadow: 3px 3px 0 rgba(0,0,0,.35); }
.nd31-tb { display: flex; align-items: center; justify-content: space-between; height: 19px; background: var(--title-bg, var(--title-active,#0000a8)); color: #fff; font-weight: bold; font-size: 12px; padding: 0 3px; }
.nd31-tb-x { width: 15px; height: 15px; line-height: 13px; text-align: center; background: var(--face); color: #000; border: 1px solid #000; box-shadow: inset 1px 1px 0 var(--face-light,#dfdfdf), inset -1px -1px 0 var(--face-shadow,#808080); cursor: var(--cur-hand,pointer); }
.nd31-bd { display: flex; gap: 10px; padding: 12px 12px 6px; align-items: flex-start; }
.nd31-ic { flex: none; }
.nd31-msg { font-size: 12px; line-height: 1.6; white-space: pre-wrap; word-break: break-word; }
.nd31-inrow { padding: 6px 12px 0; }
.nd31-in { width: 100%; box-sizing: border-box; }
.nd31-frow { display: flex; align-items: center; gap: 6px; padding: 3px 12px; }
.nd31-frow label { flex: 0 0 72px; text-align: right; font-size: 12px; }
.nd31-frow .input31 { flex: 1; min-width: 0; }
.nd31-swbox { display: flex; flex-wrap: wrap; gap: 3px; padding: 6px 12px; max-width: 320px; }
.nd31-sw { width: 22px; height: 22px; border: 1px solid #000; box-shadow: inset 1px 1px 0 #fff; cursor: var(--cur-hand,pointer); }
.nd31-sw.sel { outline: 2px solid #000; outline-offset: 1px; }
.nd31-ft { display: flex; justify-content: flex-end; gap: 5px; padding: 10px 12px 12px; }
.nd31-ft .btn31 { min-width: 66px; }

/* ---------- p22：万能文档阅读器 DocView ---------- */
.dv-root { display: flex; flex-direction: column; height: 100%; background: var(--face); }
.dv-toolbar { display: flex; flex-wrap: wrap; gap: 2px; align-items: center; justify-content: flex-start; padding: 3px; border-bottom: 1px solid #808080; }
.dv-toolbar .btn31 { min-width: 0; }
.dv-side { display: none; }
/* 竖排：仍然保持纵向堆叠 ⇒ 目录/笔记/统计面板落到「页面下方」，
   而不是像以前那样在右侧占掉一整列。（旧的 row 会让 info 变右栏） */
.dv-vert { flex-direction: column; }
.dv-vert .dv-toolbar { display: none; }
.dv-vert .dv-side { display: flex; flex-direction: column; gap: 2px; width: 140px; min-width: 140px; padding: 4px; border-left: 1px solid #808080; overflow-y: auto; background: var(--face); }
.dv-side .btn31, .dv-side select { width: 100%; }
.dv-content { flex: 1; min-width: 0; min-height: 0; overflow: auto; background: #fff; padding: 16px 20px; font-size: 14px; line-height: 1.9; color: #000; }
.dv-content.dv-reader { font-size: 14px; }
.dv-content.dv-v { writing-mode: vertical-rl; text-align: left; padding: 16px; }
.dv-a4 { width: 640px; min-height: 990px; box-sizing: border-box; background: #fff; margin: 0 auto 14px; padding: 56px 48px; box-shadow: 2px 2px 0 rgba(0,0,0,.35); }
.dv-pages-n { text-align: center; color: #808080; font-size: 11px; padding: 6px; }
.dv-frame { width: 100%; height: 100%; min-height: 420px; border: 0; }
.dv-table { border-collapse: collapse; width: 100%; font-size: 12px; }
.dv-table td { border: 1px solid #808080; padding: 2px 5px; }
.dv-slide { position: relative; border: 2px inset #fff; background: #fff; padding: 12px; margin-bottom: 10px; }
.dv-slide-n { position: absolute; right: 5px; top: 3px; color: #808080; font-size: 11px; }
/* p118⑪：PDF 每页的位图 —— 吃满正文宽度、按页面自身比例一页一行排下去。 */
.dv-pdfpage { margin: 0 auto 12px; max-width: 100%; background: #fff; box-shadow: 1px 1px 0 rgba(0,0,0,.28); }
.dv-pdfpage img { display: block; width: 100%; height: auto; }
.dv-chapter { border-bottom: 1px dashed #c0c0c0; padding-bottom: 10px; margin-bottom: 10px; }
.dv-mdsrc { white-space: pre-wrap; font-family: 'F31Latin', monospace; font-size: 12px; line-height: 1.7; }
.dv-font { height: 20px; font-size: 12px; max-width: 168px; }

/* ---------- p22：Ruby 注音 / LaTeX 公式 ---------- */
ruby { ruby-position: over; }
ruby rt { font-size: 9px; line-height: 1; color: #404040; }
.lx { font-family: Georgia, 'Times New Roman', serif; font-style: normal; }
.lx i { font-style: italic; }
.lx-frac { display: inline-flex; flex-direction: column; vertical-align: middle; text-align: center; margin: 0 2px; line-height: 1.15; }
.lx-num { border-bottom: 1px solid #000; padding: 0 3px; }
.lx-den { padding: 0 3px; }
.lx-sqrt { border-top: 1px solid #000; padding: 0 2px; }
.lx-op { font-size: 1.45em; vertical-align: -0.22em; }
.lx-sup, .lx-sub { font-size: .72em; }
.lx-fn { font-style: normal; margin-right: 1px; }
.lx-acc { position: relative; display: inline-block; }
.lx-mark { position: absolute; left: 0; top: -0.55em; font-size: .7em; }
.lx-block { display: block; text-align: center; margin: 10px 0; }
.lx-wrap { text-align: center; margin: 10px 0; font-size: 1.1em; }
.lx-tex { background: #f4f4ff; padding: 0 2px; }

/* ---------- p22：文章头图 / 背景 / 分隔线 ---------- */
.art-cover { display: block; width: 100%; max-height: 260px; object-fit: cover; image-rendering: pixelated; border: 1px solid #808080; margin-bottom: 8px; }
.art-hasbg { position: relative; }
.art-bglayer { position: absolute; inset: 0; pointer-events: none; background-size: cover !important; background-position: center !important; background-repeat: no-repeat !important; }
.art-hasbg > *:not(.art-bglayer) { position: relative; z-index: 1; }
hr.art-sep { border: 0; border-top: 2px solid #808080; box-shadow: 0 1px 0 #fff; margin: 12px 0; }

/* ---------- p22：网盘工具栏对齐 / 分页 ---------- */
.nd-toolbar { justify-content: flex-start; align-items: center; }
.nd-toolbar .btn31 { min-width: 76px; text-align: center; }
.nd-pages { display: flex; gap: 6px; align-items: center; justify-content: center; padding: 5px; }
.nd-pages .btn31 { min-width: 34px; }

/* ---------- p22：配色方案桌面 ---------- */
/* 桌面**取消一切渐变**：默认铺「实色 + 50% 棋盘抖动层」；
   用户上传壁纸时（body.has-wp）壁纸优先。 */
#desktop {
  background-color: var(--desktop) !important;
  background-image: var(--desk-dither, none) !important;
  background-size: var(--dither-tile) var(--dither-tile) !important;
  background-position: center !important;
  background-repeat: repeat !important;
}
body.has-wp #desktop {
  background-image: var(--wp-image) !important;
  background-size: cover !important;
  background-position: center !important;
  background-repeat: no-repeat !important;
}
/* A4 分页块始终保持横排（竖排模式只作用于正文流式阅读） */
.dv-a4, .dv-pages-n { writing-mode: horizontal-tb !important; }

/* ---------- p23：控制面板搜索 / 密码区间距 ---------- */
.cp-srow { padding: 4px 5px 2px; }
.cp-search { width: 100%; box-sizing: border-box; }
.cp-gap { height: 12px; }
#control .cp-line, .cp-line { display: flex; align-items: center; gap: 6px; padding: 3px 2px; }

/* ---------- p23：个人页标题与左边栏留白 ---------- */
.nw-profile .nw-head { margin: 6px 10px 3px; padding-left: 2px; }

/* ---------- p23：图片查看器 ---------- */
.iv-root { display: flex; flex-direction: column; height: 100%; background: var(--face); }
.iv-bar { display: flex; flex-wrap: wrap; gap: 2px; align-items: center; padding: 3px; border-bottom: 1px solid #808080; }
.iv-bar .btn31 { min-width: 0; }
.iv-sw { width: 18px; height: 18px; border: 1px solid #000; box-shadow: inset 1px 1px 0 #fff; cursor: var(--cur-hand, pointer); }
.iv-sw.sel { outline: 2px solid #000; outline-offset: 1px; }
.iv-w { height: 20px; font-size: 12px; }
.iv-stage { flex: 1; overflow: auto; background: #808080; display: flex; align-items: flex-start; justify-content: center; padding: 12px; }
.iv-canvas { image-rendering: pixelated; background: #fff; box-shadow: 2px 2px 0 rgba(0,0,0,.4); touch-action: none; }
.iv-canvas.pen { cursor: var(--cur-cross, crosshair); }

/* ---------- p23：时钟使用像素字体 ---------- */
.ck-clockbar { font-family: 'SimSun31', 'Win31System', 'F31Latin', 'F31Hans', monospace !important; letter-spacing: 1px; }
.ck-root, .ck-root * { font-family: 'SimSun31', 'Win31System', 'F31Latin', 'F31Hans', sans-serif; }

/* ---------- p23：网盘驱动器按钮 ---------- */
.nd-drive { font-weight: bold; }

/* ---------- p24：编辑器对话框统一 / 折叠栏目 / 比例拖拽条 / 列表封面 ---------- */
.nd31-form .nd31-fbd { flex-direction: column; align-items: stretch; gap: 4px; max-height: 62vh; overflow-y: auto; padding: 12px 12px 4px; }
.nd31-frow label { flex: 0 0 96px; }
.nd31-fcol { flex-direction: column; align-items: stretch; }
.nd31-fcol label { flex: none; text-align: left; }
.nd31-ta { width: 100%; box-sizing: border-box; font-family: 'SimSun31', 'Win31System', 'F31Latin', 'F31Hans', monospace; font-size: 12px; }

.wd-glab { cursor: var(--cur-hand, pointer); user-select: none; }
.wd-glab:hover { color: #0000a8; text-decoration: underline; }
.wd-bar.collapsed { padding: 1px 3px; }
.wd-bar.collapsed .wd-bar-btns { display: none; }
.wd-bars { max-height: 72%; overflow-y: auto; }
.wd-split { flex: none; height: 6px; background: var(--face, #c0c0c0); border-top: 1px solid #ffffff; border-bottom: 1px solid #808080; cursor: var(--cur-ns, ns-resize); }
.wd-split:hover { background: #d8d8d8; }
body.wd-dragging { cursor: var(--cur-ns, ns-resize) !important; user-select: none; }

.tile-card .tile-img.tile-cover { width: 100%; height: 84px; object-fit: cover; image-rendering: pixelated; display: block; border: 1px solid #808080; margin-bottom: 3px; }
.blog-item .bi-thumb { flex: none; width: 36px; height: 26px; object-fit: cover; image-rendering: pixelated; border: 1px solid #808080; margin-right: 5px; }

/* ---------- p25：文章阅读器（横竖排 / 字体 / A4 / 双栏 / 页面色 / 水印） ---------- */
.rd-bar { display: flex; flex-wrap: wrap; gap: 3px; align-items: center; padding: 3px 4px; background: var(--face, #c0c0c0); border-bottom: 1px solid #808080; }
.rd-bar .btn31 { min-width: 0; }
.rd-font { height: 20px; font-size: 12px; max-width: 150px; }
.bbs-content.art-v { writing-mode: vertical-rl; text-align: left; max-height: 100%; }
.bbs-content.art-2col { column-count: 2; column-gap: 26px; column-rule: 1px solid #c0c0c0; }
.bbs-content.art-v.art-2col { column-count: 1; }
.bbs-content.art-a4 { background: #808080; padding: 10px; }
.bbs-content.art-haspagebg, .article-view.art-haspagebg { box-shadow: inset 0 0 0 1px #b0b0b0; }
.bbs-content.watermark { position: relative; }
.bbs-content.watermark::before {
  content: attr(data-wm); position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-size: 52px; color: var(--wm-color, #000000); opacity: .12; transform: rotate(-24deg);
  pointer-events: none; white-space: nowrap; z-index: 0;
}
.bbs-content.watermark > * { position: relative; z-index: 1; }
/* p26：万能阅读器双栏 */
.dv-content.dv-2col { column-count: 2; column-gap: 28px; column-rule: 1px solid #c0c0c0; }
.dv-content.dv-2col .dv-a4 { column-count: 1; }

/* ---------- p27：设置实装（沙漏指针 / 抖动 / 软驱 / 仙人掌 / 幽灵 / 行号 / 已读） ---------- */
body.pf-busy, body.pf-busy * { cursor: var(--cur-wait, wait) !important; }
.busy-badge { position: fixed; right: 10px; bottom: 10px; z-index: 9500; background: var(--face,#c0c0c0);
  border: 2px outset var(--face,#c0c0c0); padding: 2px 8px; font-size: 12px; box-shadow: 2px 2px 0 rgba(0,0,0,.3); }
/* CRT 电压不稳：轻微且缓慢（原先 0.16s 抖动过快，且会顶掉扫描线滚动动画） */
@keyframes crt-jit {
  0%, 84% { transform: translate(0, 0); }
  86% { transform: translate(-1px, 1px); }
  88% { transform: translate(1px, -1px); }
  90% { transform: translate(-1px, 0); }
  92%, 100% { transform: translate(0, 0); }
}
body.pf-jitter #crt-overlay { animation: crt-scroll var(--crt-speed) linear infinite, crt-jit 3.6s steps(2, end) infinite; }
body.pf-jitter.crt-warp-off #crt-overlay { animation: crt-scroll var(--crt-speed) linear infinite, crt-jit 4.2s steps(2, end) infinite; }
.floppy-b { display: flex; flex-direction: column; align-items: center; gap: 2px; width: 62px; font-size: 11px;
  padding: 4px 2px; border: 1px dotted #808080; cursor: var(--cur-hand,pointer); }
.floppy-b svg { width: 32px; height: 32px; }
.desk-cactus { position: absolute; z-index: 3; cursor: var(--cur-hand,pointer); filter: drop-shadow(2px 2px 0 rgba(0,0,0,.35)); }
.ghost-win { position: absolute; z-index: 4; width: 190px; padding: 8px 10px; font-size: 11px; color: #e8f0ff;
  background: rgba(0,0,40,.35); border: 1px solid rgba(255,255,255,.35); pointer-events: none;
  transition: opacity 1.2s linear; opacity: .5; }
.ghost-win.fade { opacity: 0; }
.wd-lineno { flex: none; width: 34px; padding: 52px 4px 0 0; text-align: right; font-size: 11px; color: #808080;
  font-family: 'SimSun31', 'F31Latin', monospace; user-select: none; overflow: hidden; }
.wd-lineno span { display: block; line-height: 1.7em; }
.ct-read { color: #008000; font-size: 11px; }

/* ============================================================
 * p34：色彩滤镜（16 色 / 单色 / 绿色 / 琥珀 / 示波器）
 *  - filter 必须作用在 body 的直接子元素上：写在 body 上会让 body 变成包含块，
 *    导致 #desktop 等 absolute/fixed 层塌成 0 高度（整屏黑）。
 *  - #crt-overlay 排除在外（它本身就是一层黑网，不需要再滤一遍，省性能）
 * ============================================================ */
/* ⚠️ p66：原来这里还有一条 `… > *:not(#crt-overlay) { will-change: filter }`。
   实测在跑起来的站点上它给 body 的**每一个**直接子元素都挂了提示，共 **86 个** ——
   其中 79 个是 <script>/<svg style="width:0"> 这种既不绘制也不占位的节点。
   两个害处：① 白白创建几十个合成层；② 滤镜一旦走合成，剪辑矩形就由合成器负责，
      「内容被画到窗口外」这类图层失效 bug 正是从这里来的（本批用户报的那条 bug）。
   ⇒ ① 整条 will-change 删掉（filter 本身就会让元素独立成层，不需要提示）；
     ② 顺手把 script/svg/style 从选择器里剔掉，让规则只落在真正会画的节点上。 */
body.f-c16 > *:not(#crt-overlay):not(script):not(svg):not(style) { filter: url(#f-blit16); }
body.f-mono > *:not(#crt-overlay):not(script):not(svg):not(style) { filter: url(#f-mono); }
body.f-green > *:not(#crt-overlay):not(script):not(svg):not(style) { filter: url(#f-green); }
body.f-amber > *:not(#crt-overlay):not(script):not(svg):not(style) { filter: url(#f-amber); }
body.f-scope > *:not(#crt-overlay):not(script):not(svg):not(style) { filter: url(#f-scope); }
/* p91 CGA **Mode 4**：整屏压到 4 色（黑 / 白 / 青 / 洋红）+ 4×4 Bayer 有序抖动。
   滤镜本体在 index.html 的 #f-cga；文字为何天然不被抖动见那里的注释。 */
body.f-cga > *:not(#crt-overlay):not(script):not(svg):not(style) { filter: url(#f-cga); }

/* 磷光屏底色（p63 按参考图重定）：
   绿色磷光与示波器的输出都是**只有两色**（纯黑 + 纯绿/薄荷）的画面 ⇒ 桌面底色必须是**纯黑**，
   否则 #061a08 这类「半亮黑」会被抖动滤镜打成一片稀稀拉拉的绿点。
   EL 屏幕保留一点点色偏（#0a0806），模拟熄屏时的暗场余晖。 */
body.f-c16 { background: #000 !important; }
body.f-mono { background: #0e0e0e !important; }
body.f-green { background: #000 !important; }
body.f-amber { background: #0a0806 !important; }
body.f-scope { background: #000 !important; }
/* CGA Mode 4 屏：底色用调色板里的**纯白**（白在滤镜里 Y=1 ⇒ 恒为纯白、零抖动）。
   ⚠️ body 自身的背景**不是** body 的子元素 ⇒ 那条 `body.f-cga > *` 滤镜管不到它，
   所以这里必须显式给一个已经在调色板里的颜色，否则屏边会露出一圈没量化过的原色。 */
body.f-cga { background: #ffffff !important; }
body.f-cga #desktop { background-color: #ffffff !important; }
/* ============================================================
 * p99：CRT 弧面开启时，**屏幕显示范围之外一律纯黑**
 * ------------------------------------------------------------
 * 用户口径：「將舊圖灰色的部分（即開啟 CRT 曲度之後屏幕顯示範圍之外的空隙）
 *            全部用黑色遮罩」。
 * 来龙去脉：feDisplacementMap 的采样点越界时返回**透明**（js/effects2.js 的 applyWarp
 * 上方有完整推导），露出来的是页面背景；而 `html, body { background: var(--desktop) }`
 * 默认是桌面灰 #C0C0C0 ⇒ 越界处看上去像「桌面底色漏出来」，也就是用户说的「灰色的部分」。
 * 实测（`_dev/p99live.js`，纯黑桌面 + 统计非黑像素）：
 *   · 静止状态已无空隙（1280×800 / 1440×900 / 1536×864 / 1920×1080 / 1366×768
 *     × DPR 1 / 1.25 / 1.5 —— 非黑像素全部 = 0，p82 的钳位确实生效了）；
 *   · 但「窗口先小后大」时（旧贴图尚未重算的 160ms 窗口内）实测非黑像素 **112167**
 *     ⇒ 那一刻屏幕上确有一圈灰色空隙（这就是用户说的「時有時無」）。
 * 所以这里把「屏幕之外」的底色钉成纯黑：**任何**越界/擦除/陈旧贴图露出的都是黑，
 * 视觉上读作「屏幕边框」而不是「桌面漏了」。
 * ⚠️ 只改 html/body 的背景，**不动** #desktop 自己的底色 —— 桌面色是配色方案的一部分。
 * ⚠️ 必须写在上面那组 `body.f-*` 背景之后：`html.crt-mask body` 与 `body.f-cga`
 *    特异性都是 0,1,1（且都带 !important）⇒ 只能靠书写顺序取胜。CGA 下屏外取纯黑
 *    也安全：黑本身就是 Mode 4 调色板里的一色，不会露出未量化的原色。
 * ⚠️ 类名由 js/effects2.js 的 applyWarp() 挂/摘（`setMask`），挂的是 <html>，
 *    避开 settings.js / prefs.js 对 body 上 pf-* 家族的频繁 toggle。
 * ============================================================ */
html.crt-mask, html.crt-mask body { background: #000 !important; }
/* p91 Mode 4：深底浅字的面统一翻成**彩色底 + 黑字**。
   滤镜只按亮度选档，深底会落进「黑/洋红」半区 ⇒ 白字可读、但黑字会看不见；
   青(#00FFFF) 与洋红(#FF00FF) 都是调色板本身的颜色 ⇒ 渲染出来是**实心、零抖动**，
   正好拿来当底色，且黑字对比度足够。 */
/* ---------- p95：**标题栏族**用洋红 ----------
   用户口径：「选中 CGA 滤镜 ⇒ 标题栏自动切洋红；不选则恢复」。
   只有三处属于「标题栏」：主窗口标题栏 / 网盘标题栏 / 对话框标题栏；
   选中高亮族（菜单展开、列表选中行…）**保持青色**，两种强调色成对使用。

   ⚠️ 颜色必须逐字写 #ff00ff（= Mode 4 调色板里的洋红档）：
      p98 起 #f-cga 是**逐通道按位抖动**，洋红只需源色的 R 位恒 1、G 位恒 0 即可实心：
      #ff00ff ⇒ rEff = max(1, (1−0)/3) = 1（R 位 16/16）、gEff = max(0, (1−1)/2) = 0（G 位 0/16）
      ⇒ **16/16 实心洋红、零抖动**（p98 实测落点只有 (255,0,255)）。
      ⚠️ p95 时代这里还有一道「洋红直通门」（⑥⑦⑧ 三个图元，条件 0.5R+0.5B−G ≥ 0.859375），
      p98 的按位抖动让洋红**天然实心** ⇒ 那道门连同 mg/mgT/lum3 三个图元已整体删除。
      仍建议写 #ff00ff 而不是暗洋红 #AA00AA：后者 rEff = 0.667 ⇒ R 位 11/16 ⇒
      洋红抖动 + 5/16 黑（p98 起**不再是黑底黑字**，但标题栏会变脏）。
   ⚠️ 恢复逻辑靠「整组声明只挂在 body.f-cga 下」：取消滤镜时这几条整体失效，
      用户自己设的 `--title-bg`（prefs 内联在 <html> 上）自然重新生效，**不需要任何 JS**。 */
body.f-cga .win.focused .titlebar,
body.f-cga .nd31-tb,
body.f-cga .wd-dlg .wd-dlg-t {
  background-color: #ff00ff !important;
  background-image: none !important;
  color: #000000 !important;
}
/* 标题栏配色变量也一起改：一切「派生自标题栏色」的面跟着走
   （msgbox31 的外框 = var(--title-active)，.wd-dlg-t、菜单展开项同理）。
   — `--title-fg` 一起压成黑，因为 v7.css 的 `.win.focused .titlebar{color:var(--title-fg)}`
     是**在标题栏元素上**解析的，只改子元素的 color 不足以覆盖它自己。 */
body.f-cga {
  --title-active: #ff00ff;
  --title-bg: #ff00ff;
  --title-fg: #000000;
  --title-dither: none;
}
/* ---------- 选中 / 高亮族：仍是青色（p91 原样） ---------- */
body.f-cga .menu-bar .menu-item.open,
body.f-cga .sysmenu .menu-entry:hover,
body.f-cga .s31.open .s31-val,
body.f-cga .s31-it.on,
body.f-cga .b31-trow.sel,
body.f-cga .b31-sysrow.active,
body.f-cga .nd-item.sel,
body.f-cga .nd-tree .nd-tn.active,
body.f-cga .nd-side h4,
body.f-cga .ct-pick-h,
body.f-cga .cp-head,
body.f-cga .ct-side-head,
body.f-cga .rdr-tn.active,
body.f-cga .nw-lvtip tr.me {
  background-color: #00ffff !important;
  background-image: none !important;
  color: #000000 !important;
}
/* 标题栏里的文字节点（`.tb-title`）不继承自 .titlebar 的颜色时要一起压 */
body.f-cga .win.focused .titlebar .tb-title,
body.f-cga .win.focused .titlebar * { color: #000000 !important; }
/* 选中行/列表项里的单元格也要跟着黑（.nd-list tr.sel td 一类） */
body.f-cga .nd-list tr.sel td,
body.f-cga .cm-floor { background-color: #00ffff !important; color: #000000 !important; }
body.f-mono #desktop { background-color: #1a1a1a !important; }
body.f-green #desktop { background-color: #000000 !important; }
body.f-amber #desktop { background-color: #0a0806 !important; }
/* 示波器滤镜把「墨迹」抽成细线、把空白压成黑 ⇒ 桌面底色必须是亮色才会产生墨迹（白 = 无墨） */
body.f-scope #desktop { background-color: #ffffff !important; }
body.f-scope #desktop::after { content: none; }
body.f-c16 #desktop { background-color: #000 !important; }
body.f-green #crt-overlay, body.f-amber #crt-overlay { opacity: .45; }
body.f-scope #crt-overlay { opacity: .22; }
body.f-mono #crt-overlay { opacity: .7; }

/* ---------- EL 屏幕：暗场呼吸 + 屏面余晖（p63）---------- */
/* 极缓慢的亮度起伏（EL 屏在刷新周期里的「呼吸」），叠加一层暖色泛光面纱做环境余辉。
   只动 opacity，不碰 transform/filter ⇒ 不会把 body 变成包含块。 */
@keyframes el-breath {
  0%   { opacity: .86; }
  38%  { opacity: 1; }
  55%  { opacity: .80; }
  63%  { opacity: .97; }
  100% { opacity: .86; }
}
body.f-amber::after {
  content: ''; position: fixed; inset: 0; pointer-events: none; z-index: 99997;
  background:
    radial-gradient(ellipse 118% 88% at 50% 44%, rgba(255, 196, 72, .10), rgba(150, 92, 0, .05) 58%, rgba(0, 0, 0, .28) 100%);
  mix-blend-mode: screen;
  animation: el-breath 8.5s ease-in-out infinite;
}

/* ---------- 示波器：绘制过程（光束逐段扫过 + 荧光拖影） ---------- */
@property --os-x { syntax: '<percentage>'; initial-value: 100%; inherits: true; }

body.f-scope { --os-x: 100%; }
body.f-scope.f-scope-draw { animation: os-sweep 1.9s steps(48, end) 1 both; }
@keyframes os-sweep { from { --os-x: 0%; } to { --os-x: 100%; } }

body.f-scope.f-scope-draw > *:not(#crt-overlay) {
  -webkit-mask-image: linear-gradient(90deg, #000 0, #000 var(--os-x), rgba(0, 0, 0, .45) var(--os-x), transparent calc(var(--os-x) + 1.6%));
  mask-image: linear-gradient(90deg, #000 0, #000 var(--os-x), rgba(0, 0, 0, .45) var(--os-x), transparent calc(var(--os-x) + 1.6%));
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-size: 100% 100%; mask-size: 100% 100%;
}

body.f-scope::after {
  content: ''; position: fixed; inset: 0; pointer-events: none; z-index: 99998; opacity: 0;
  background:
    linear-gradient(90deg,
      transparent 0,
      rgba(120, 255, 140, .10) calc(var(--os-x) - 15%),
      rgba(200, 255, 210, .32) calc(var(--os-x) - 5%),
      rgba(238, 255, 238, .90) var(--os-x),
      rgba(150, 255, 170, .22) calc(var(--os-x) + .7%),
      transparent calc(var(--os-x) + 2.6%)),
    radial-gradient(ellipse 36px 130% at var(--os-x) 50%,
      rgba(190, 255, 190, .5) 0%, rgba(90, 255, 120, .14) 45%, transparent 76%);
}
body.f-scope.f-scope-draw::after { opacity: 1; }

/* 长时间静止后轻微荧光呼吸，避免画面死板 */
@keyframes os-phos { 0%, 100% { opacity: 1; } 47% { opacity: .94; } 49% { opacity: .99; } }
body.f-scope:not(.f-scope-draw) { animation: os-phos 5.5s ease-in-out infinite; }

/* ============================================================
 * p37：工具栏按钮等长等宽 + 折叠栏目优先让位
 * ============================================================ */
/* 等宽按钮由 JS(__eqButtons) 设置固定 width；这里保证换行后左对齐成网格 */
.wd-bar-btns { justify-content: flex-start; }
.wd-bar-btns .wd-b { flex: 0 0 auto; white-space: nowrap; text-align: center; }
/* 分组标签列固定宽度，保证各行的按钮网格左右对齐 */
/* p82：11px 点阵字的**字面 metric 盒 = 14px > 行盒 11px**（`html,body{line-height:1}`
 *      + SimSun31 的 `size-adjust:116.6667%`）⇒ 带 overflow:hidden 的本元素在裁自己的行盒
 *      （实测 scrollHeight 12 > clientHeight 11）。
 *      修法 = p80 家族（`_dev/p82text2.js` 全站体检验出，`_dev/p82noop.js` 验「零像素差」）：
 *      对称 `padding:2px 0` + **等量减小**的 `margin:4px 0`（4+2 == 原来的 6）
 *      ⇒ 裁剪盒上下各外扩 2px，而 **margin 盒尺寸不变、文字绝对位置一个像素都不动**
 *      （.wd-bar 是 flex + align-items:center，居中看的是 margin 盒 ⇒ 居中结果不变）。
 *      ⚠️ 别改成只加 padding 不减 margin（外框会长高 4px，下面的东西全跟着动）。 */
.wd-bar > .cp-note.wd-glab { flex: 0 0 104px; width: 104px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding: 2px 0; margin: 4px 0; }
/* 工具栏被拖小后：折叠的栏目整行优先隐藏，露出未折叠的栏目 */
.wd-bars.wd-tight .wd-bar.collapsed { display: none; }

/* 文件管理器工具栏：等宽后换行行内对齐 */
.nd-toolbar { align-items: center; }
.nd-toolbar .btn31 { flex: 0 0 auto; white-space: nowrap; text-align: center; }

/* ---------- p37：视频统一交给「视频播放器」打开 ---------- */
.nw-vidcard { margin-top: 4px; display: flex; align-items: center; gap: 4px; }
.nw-vidbtn { display: inline-flex; align-items: center; gap: 4px; }
.nw-vidbtn svg, .nw-vidbtn img { width: 16px; height: 16px; }
.btn31.vid-open { margin: 3px 0; }

/* ============================================================
 * p120②：文章应用右栏的「原格式文档」区
 *   · PDF ⇒ .docpane-pdf 直接放 .dv-pdfpage 整页位图（样式沿用 v6.css 既有定义）
 *   · docx/pptx… ⇒ .docpane-paper 把正文包进一张 .dv-a4 纸
 * ⚠️ 右栏很窄（.blog-right）⇒ 必须把 .dv-a4 的固定宽 640px / 最小高 990px 压掉，
 *    否则整张纸会横向溢出把右栏撑破。
 * ============================================================ */
.docpane-note { font-size: 11px; color: #606060; padding: 2px 0 6px; }
.bbs-content .docpane { margin: 0 0 8px; }
.bbs-content .docpane .dv-pdfpage { margin: 0 auto 12px; max-width: 100%; }
.bbs-content .docpane-paper .dv-a4 {
  width: auto; max-width: 100%; min-height: 0; box-sizing: border-box;
  margin: 0 auto 12px; padding: 28px 22px;
}
.bbs-content .docpane img { max-width: 100%; height: auto; }
