@charset "utf-8";
/* ==========================================================================
   Windows Classic (Y2K / Windows 3.1 - Windows 2000) 主题样式表  v3
   --------------------------------------------------------------------------
   兼容目标：EdgeHTML 18（Edge 18 / Windows 10 1809）及以上
             同时兼容 Chromium Edge / Chrome / Firefox / Safari 现代版本

   v3 变更：
     · 桌面背景支持壁纸图片（cover / contain / 平铺三种适配模式）
     · 新增记事本窗口（#winNp）与 Markdown 排版命名空间（.md）
     · 多窗口并存：窗口宽度由各自的 --window-w 覆写
     · 移动端自适应细化（720px / 420px 断点 + 矮视口处理）

   可用能力（Edge 18 已支持）：
     · CSS 自定义属性 var()  —— Edge 15+
     · Flexbox / CSS Grid    —— Grid 自 Edge 16+ 起无需前缀（含 gap）
     · calc() / vh / 渐变 / 变换 / 过渡 / 关键帧动画
     · position:sticky / object-fit —— Edge 16+
     · 多重背景 + background-size: cover/contain —— 均早于 Edge 18

   注意：EdgeHTML 18 **不支持** ::-webkit-scrollbar（该伪元素自 Edge 79 /
   Chromium 内核起才可用）。本表仍保留相关规则，供 Chromium Edge 等内核生效；
   EdgeHTML 下会自动回退为系统原生滚动条，属预期降级，不影响功能。

   刻意规避（EdgeHTML 18 不支持）：
     · Flex 容器的 gap          —— 需 Edge 84+
       替代方案：容器负外边距 + 子项外边距（换行场景），
                 或相邻兄弟选择器 `> * + *` 加 margin-left（单行场景）。
                 注意：CSS Grid 的 gap 自 Edge 16+ 起即支持，无需规避。
     · inset 简写               —— 需 Edge 87+，改用 top/right/bottom/left
     · :focus-visible / :is()   —— 需 Edge 86+
     · backdrop-filter          —— 本主题为不透明实心界面，无需该特性
     · aspect-ratio             —— 需 Edge 88+
     · gap 之外的 Grid 新特性（如 subgrid）同样不使用

   Windows 系统色（ButtonFace 等）：
     FACE #c0c0c0  HILIGHT #ffffff  LIGHT #dfdfdf
     SHADOW #808080  DARK #000000  ActiveTitle #000080 → #1084d0
   ========================================================================== */

/* ==========================================================================
   1. 设计令牌
   ========================================================================== */
:root {
  /* 系统面板色 */
  --face:      #c0c0c0;
  --hilight:   #ffffff;
  --light:     #dfdfdf;
  --shadow:    #808080;
  --dark:      #000000;

  /* 标题栏 */
  --title-from:     #000080;
  --title-to:       #1084d0;
  --title-off-from: #808080;
  --title-off-to:   #b5b5b5;

  /* 选中项 */
  --hl-bg: #000080;
  --hl-fg: #ffffff;

  /* 桌面（默认经典灰，可切换） */
  --desktop: #c0c0c0;

  /* 壁纸图片路径（可被 .wall-img 覆写；集中在此便于替换） */
  --wallpaper: url("img/wallpaper.jpg");

  /* 文本 */
  --text:      #000000;
  --text-dim:  #404040;
  --text-mute: #606060;
  --link:      #0000c0;
  --link-vis:  #551a8b;

  /* 字体 */
  --font: Tahoma, "MS Sans Serif", "Microsoft Sans Serif",
          "SimSun", "宋体", "Microsoft YaHei", sans-serif;
  --mono: "Courier New", Courier, monospace;

  /* 尺寸 */
  --taskbar-h: 32px;
  /* 桌面底边留给任务栏的净空。
     .taskbar 是 position:fixed; bottom:0; height:var(--taskbar-h)，
     也就是任务栏上沿恒好在「视口底 - taskbar-h」处。
     因此最大化窗口想让底边贴住任务栏上沿，只需让出 taskbar-h，
     再加 0px 都嫌多 —— 之前这里多加了 14px，窗口就被顶到任务栏上方
     14px 处，屏幕上于是出现一条裸露的壁纸缝。

     注意：--desk-gap 仍保留「+ 间距」的语义供别处（如桌面底边留白）使用，
     最大化窗口专用值单独用 --max-gap 表达，二者互不牵连。 */
  --desk-gap:  calc(var(--taskbar-h) + 14px);
  --max-gap:   var(--taskbar-h);
  --window-w:  1020px;
  --side-w:    316px;
}

/* ==========================================================================
   2. 基础重置
   ========================================================================== */
*,
*::before,
*::after { box-sizing: border-box; }

html { height: 100%; }

body {
  margin: 0;
  min-height: 100%;
  background: var(--face);
  color: var(--text);
  font: 12px/1.55 var(--font);
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

h1, h2, h3, h4, h5, h6, p, ul, ol, dl, dd, figure { margin: 0; }
ul, ol { padding: 0; list-style: none; }
img { display: block; max-width: 100%; border: 0; }
table { border-collapse: collapse; border-spacing: 0; }
hr {
  height: 0;
  border: 0;
  border-top: 1px solid var(--shadow);
  border-bottom: 1px solid var(--hilight);
}
a { color: var(--link); text-decoration: none; }
a:hover { text-decoration: underline; }
a:visited { color: var(--link-vis); }
code, pre, .mono { font-family: var(--mono); }

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  border: 0;
}

/* ==========================================================================
   3. 立体边框基元
   --------------------------------------------------------------------------
   凸起 raised：外层 上/左 light、下/右 dark；内层 上/左 hilight、下/右 shadow
   凹陷 sunken：外层 上/左 shadow、下/右 hilight；内层 上/左 dark、下/右 light
   ========================================================================== */
.bevel-out {
  border: 1px solid;
  border-color: var(--light) var(--dark) var(--dark) var(--light);
  box-shadow: inset 1px 1px 0 var(--hilight), inset -1px -1px 0 var(--shadow);
}
.bevel-in {
  border: 1px solid;
  border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow);
  box-shadow: inset 1px 1px 0 var(--dark), inset -1px -1px 0 var(--light);
}
.bevel-thin-out {
  border: 1px solid;
  border-color: var(--hilight) var(--shadow) var(--shadow) var(--hilight);
}
.bevel-thin-in {
  border: 1px solid;
  border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow);
}
.bevel-groove {
  border: 1px solid;
  border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow);
  box-shadow: inset 1px 1px 0 var(--hilight), inset -1px -1px 0 var(--shadow);
}

/* ==========================================================================
   4. 通用控件
   ========================================================================== */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 75px;
  height: 23px;
  padding: 0 10px;
  background: var(--face);
  border: 1px solid;
  border-color: var(--light) var(--dark) var(--dark) var(--light);
  box-shadow: inset 1px 1px 0 var(--hilight), inset -1px -1px 0 var(--shadow);
  color: var(--text);
  font: 12px/1 var(--font);
  text-align: center;
  text-decoration: none;
  white-space: nowrap;
  cursor: default;
  user-select: none;
}
.btn:hover { text-decoration: none; }
.btn:active,
.btn.is-pressed {
  border-color: var(--dark) var(--light) var(--light) var(--dark);
  box-shadow: inset 1px 1px 0 var(--shadow), inset -1px -1px 0 var(--hilight);
  padding-top: 1px;
}
.btn:focus { outline: 1px dotted var(--dark); outline-offset: -4px; }
.btn--default { outline: 1px solid var(--dark); outline-offset: 0; }
.btn--sm {
  min-width: 0;
  height: 21px;
  padding: 0 8px;
  font-size: 11px;
}
.btn[disabled],
.btn.is-disabled {
  color: var(--shadow);
  text-shadow: 1px 1px 0 var(--hilight);
}

.field {
  display: inline-block;
  height: 21px;
  padding: 0 4px;
  background: #fff;
  border: 1px solid;
  border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow);
  box-shadow: inset 1px 1px 0 var(--dark), inset -1px -1px 0 var(--light);
  color: var(--text);
  font: 12px/19px var(--font);
  vertical-align: middle;
}
.field:focus { outline: none; }

.check {
  width: 13px;
  height: 13px;
  margin: 0 6px 0 0;
  vertical-align: -2px;
}
.check-label {
  display: flex;
  align-items: center;
  padding: 2px 0;
  cursor: default;
  user-select: none;
}

/* ==========================================================================
   5. 桌面层
   --------------------------------------------------------------------------
   壁纸方案（class）与图片适配（class）分离，可自由组合：
     .wall-img  → 使用 assets/img/wallpaper.jpg
     .wallfit-cover   → background-size: cover   （填充，保持比例，裁切溢出）
     .wallfit-contain → background-size: contain （适应，保持比例，留边不裁切）
     .wallfit-tile    → background-repeat: repeat（平铺，原始尺寸重复）
   注：EdgeHTML 18 支持 cover / contain / calc / 多重背景，无兼容性风险。
   ========================================================================== */
.desktop {
  position: relative;
  min-height: 100vh;
  padding-bottom: var(--desk-gap);
  background-color: var(--desktop);
  background-repeat: no-repeat;
  background-position: center center;
  overflow: hidden;
}

/* ---------- 壁纸图片 ---------- */
.desktop.wall-img { --desktop: #3a6ea5; }
.desktop.wall-img {
  background-image: var(--wallpaper);
  background-color: #3a6ea5;
}
/* 网格纹理叠加（可选，与壁纸共存时使用多重背景） */
.desktop.wall-img[data-texture="1"] {
  background-image:
    radial-gradient(rgba(255, 255, 255, .10) 1px, transparent 1px),
    var(--wallpaper);
  background-size: 6px 6px, auto;
  background-repeat: repeat, no-repeat;
}

/* ---------- 图片适配模式 ---------- */
.desktop.wallfit-cover   { background-size: cover;   background-repeat: no-repeat; }
.desktop.wallfit-contain { background-size: contain; background-repeat: no-repeat; }
/* 平铺：以原始像素尺寸重复，透明区域露出底色 */
.desktop.wallfit-tile {
  background-size: auto;
  background-repeat: repeat;
  background-position: left top;
}

/* ---------- 纯色壁纸变体 ---------- */
.desktop.wall-teal { --desktop: #008080; background-image: none; }
.desktop.wall-navy { --desktop: #000080; background-image: none; }
.desktop.wall-gray {
  --desktop: #c0c0c0;
  background-image: radial-gradient(#d4d4d4 1px, transparent 1px);
  background-size: 6px 6px;
  background-repeat: repeat;
}

/* ---------- 桌面图标 ---------- */
.desk-icons {
  position: absolute;
  top: 10px;
  left: 10px;
  width: 92px;
  z-index: 1;
}
.desk-icon {
  display: block;
  width: 88px;
  padding: 4px 2px 6px;
  margin-bottom: 6px;
  text-align: center;
  text-decoration: none;
  cursor: default;
  color: #fff;
  text-shadow:
     1px  1px 0 #000, -1px  1px 0 #000,
     1px -1px 0 #000, -1px -1px 0 #000;
}
.desk-icon:hover { text-decoration: none; }
.desk-icon__glyph {
  display: block;
  width: 32px;
  height: 32px;
  margin: 0 auto 4px;
}
.desk-icon__label {
  display: block;
  padding: 1px 2px;
  font-size: 11px;
  line-height: 1.3;
  overflow-wrap: break-word;
}
.desk-icon.is-selected .desk-icon__label,
.desk-icon:focus .desk-icon__label {
  background: var(--hl-bg);
  color: var(--hl-fg);
  outline: 1px dotted #fff;
  outline-offset: -2px;
  text-shadow: none;
}
/* 灰色桌面下改用黑字保证对比度 */
.desktop.wall-gray .desk-icon {
  color: #000;
  text-shadow: 1px 1px 0 #fff;
}

/* ==========================================================================
   6. 窗口
   --------------------------------------------------------------------------
   页面上同时存在多个 .window（主窗口 #win、记事本 #winNp）。
   各窗口的宽度通过自身的 --window-w 覆写，互不影响。
   ========================================================================== */
.window {
  position: relative;
  width: var(--window-w);
  max-width: 100%;
  margin: 26px auto;
  padding: 3px;
  background: var(--face);
  border: 1px solid;
  border-color: var(--light) var(--dark) var(--dark) var(--light);
  box-shadow: inset 1px 1px 0 var(--hilight), inset -1px -1px 0 var(--shadow);
  z-index: 5;
  /* 最小化/关闭/恢复动画的真实载体：
     之前 JS 只改 inline transform/opacity 却没有任何 transition，
     导致缩放是「瞬变 + 240ms 后 display:none」，观感生硬。
     这里补齐过渡，JS 的 240ms 延时与 transition 时长对应。 */
  transition: transform .24s ease, opacity .24s ease;
}
/* 拖动中禁用过渡，否则窗口会「追着鼠标飘」，产生延迟感 */
.window.is-dragging { cursor: move; transition: none; }
.window.is-maxed     { margin: 0; }
.window.is-hidden    { display: none; }
.window.is-inactive .title-bar {
  background: linear-gradient(90deg, var(--title-off-from), var(--title-off-to));
}

/* --------------------------------------------------------------------------
   最大化：用「弹性填充」替代「魔法常量」
   --------------------------------------------------------------------------
   旧实现给 .workspace 写死 height: calc(100vh - 196px)，其中 196 是把
   标题栏/菜单栏/工具栏/状态栏/内边距全部估算进去的一个常量。问题是：

     · 工具栏高度并非固定 —— 窄屏下工具按钮换行会从 47px 涨到 90px+；
     · 任务栏高度会在 ≤720px 断点从 32px 变为 30px；
     · 两个常量互不知情，于是任何一处变化都会在窗口底部漏出一条空隙。

   正确做法是让浏览器自己算：把窗口变成纵向 flex 容器，
   固定部件（标题栏/菜单栏/工具栏/状态栏）用 flex:none 保持自身高度，
   唯一可伸缩的 .workspace 用 flex:1 + min-height:0 吃掉剩余空间。
   这样无论有多少固定部件、它们多高，工作区都恰好填满，
   不需要、也不可能出现任何魔法数字。

   高度基准用 100vh 减 --max-gap（即任务栏高度）：任务栏 fixed 贴在视口底，
   上沿就在 100vh - taskbar-h，窗口让出这一段后底边正好压住任务栏上沿，
   中间不留任何缝隙。仍然遵守「标题栏 + 各部件最小高度」的自然下限
   （min-height 兜底，避免极矮视口下工作区被压成负尺寸）。
   -------------------------------------------------------------------------- */
.window.is-maxed {
  display: flex;
  flex-direction: column;
  height: calc(100vh - var(--max-gap));
  min-height: 320px;
}
.window.is-maxed > .title-bar  { flex: none; }
.window.is-maxed > .menubar    { flex: none; }
.window.is-maxed > .toolbar,
.window.is-maxed > .np-toolbar { flex: none; }
.window.is-maxed > .statusbar  { flex: none; }

/* 最大化时的唯一伸缩项：吃掉全部剩余高度，且允许被压缩到 0 以上 */
.window.is-maxed > .workspace {
  flex: 1 1 auto;
  height: auto;
  min-height: 0;
  max-height: none;
}

/* 记事本最大化：同上，只是基类名不同 */
.window--np.is-maxed > .np-workspace {
  flex: 1 1 auto;
  height: auto;
  min-height: 0;
  max-height: none;
}

/* 播放器最大化：工作区同样是唯一伸缩项 */
.window--mp.is-maxed > .mp-workspace {
  flex: 1 1 auto;
  height: auto;
  min-height: 0;
  max-height: none;
}

/* ---------- 记事本窗口尺寸 ---------- */
.window--np {
  --window-w: 900px;
  margin: 46px auto 26px;
}
/* 注：记事本最大化时的尺寸由上方「最大化：用弹性填充替代魔法常量」统一处理 */

/* ---------- 标题栏 ---------- */
.title-bar {
  display: flex;
  align-items: center;
  height: 20px;
  padding: 0 2px 0 3px;
  background: linear-gradient(90deg, var(--title-from), var(--title-to));
  color: #fff;
  cursor: default;
  user-select: none;
}
.title-bar__icon {
  flex: none;
  width: 16px;
  height: 16px;
  margin-right: 5px;
}
.title-bar__text {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 12px;
  font-weight: bold;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.title-bar__btns {
  flex: none;
  display: flex;
  align-items: center;
  margin-left: 8px;
}

/* 标题栏按钮 16x14 */
.title-btn {
  position: relative;
  display: block;
  width: 16px;
  height: 14px;
  margin-left: 2px;
  padding: 0;
  background: var(--face);
  border: 1px solid;
  border-color: var(--light) var(--dark) var(--dark) var(--light);
  box-shadow: inset 1px 1px 0 var(--hilight), inset -1px -1px 0 var(--shadow);
  color: var(--dark);
  font: bold 12px/12px Tahoma, var(--font);
  text-align: center;
  cursor: default;
}
.title-btn:active {
  border-color: var(--dark) var(--light) var(--light) var(--dark);
  box-shadow: inset 1px 1px 0 var(--shadow), inset -1px -1px 0 var(--hilight);
}
.title-btn:focus { outline: 1px dotted var(--dark); outline-offset: -3px; }
.title-btn--close { margin-left: 3px; }
.title-btn__glyph { position: absolute; top: 0; right: 0; bottom: 0; left: 0; }

/* 三个字形用 CSS 绘制，规避字体差异 */
.glyph-min::after {
  content: "";
  position: absolute;
  left: 4px;
  bottom: 3px;
  width: 6px;
  height: 2px;
  background: var(--dark);
}
.glyph-max::before {
  content: "";
  position: absolute;
  left: 4px;
  top: 3px;
  width: 7px;
  height: 6px;
  border: 1px solid var(--dark);
  border-top-width: 2px;
}
/* 还原态：两个错位方框 */
.glyph-max.glyph-restore::before {
  left: 5px;
  top: 4px;
  width: 5px;
  height: 5px;
  border-top-width: 1px;
}
.glyph-max.glyph-restore::after {
  content: "";
  position: absolute;
  left: 3px;
  top: 2px;
  width: 5px;
  height: 5px;
  border: 1px solid var(--dark);
  border-top-width: 2px;
  background: var(--face);
}

/* ---------- 菜单栏 ---------- */
.menubar {
  position: relative;
  display: flex;
  align-items: center;
  height: 20px;
  padding: 0 1px;
  background: var(--face);
  z-index: 40;
}
.menu-item {
  position: relative;
  display: block;
  height: 19px;
  padding: 0 7px;
  font-size: 12px;
  line-height: 19px;
  cursor: default;
  user-select: none;
}
.menu-item:hover,
.menu-item.is-open { background: var(--hl-bg); color: var(--hl-fg); }
.menu-item u { text-decoration: underline; }

.menu-pop {
  position: absolute;
  top: 19px;
  left: 0;
  display: none;
  min-width: 178px;
  padding: 2px;
  background: var(--face);
  border: 1px solid;
  border-color: var(--light) var(--dark) var(--dark) var(--light);
  box-shadow:
    inset 1px 1px 0 var(--hilight),
    inset -1px -1px 0 var(--shadow),
    2px 2px 0 rgba(0, 0, 0, .35);
  z-index: 60;
}
.menu-item.is-open .menu-pop { display: block; }
.menu-pop__item {
  display: block;
  position: relative;
  padding: 3px 20px 3px 24px;
  font-size: 12px;
  line-height: 16px;
  color: var(--text);
  white-space: nowrap;
  cursor: default;
}
.menu-pop__item:hover {
  background: var(--hl-bg);
  color: var(--hl-fg);
  text-decoration: none;
}
.menu-pop__key {
  float: right;
  margin-left: 24px;
  color: var(--shadow);
}
.menu-pop__item:hover .menu-pop__key { color: var(--hl-fg); }
.menu-pop__item.is-checked::before {
  content: "\2713";
  position: absolute;
  left: 8px;
  top: 3px;
  font-size: 11px;
}
.menu-pop__sep {
  height: 0;
  margin: 3px 2px;
  border-top: 1px solid var(--shadow);
  border-bottom: 1px solid var(--hilight);
}

/* ---------- 工具栏 ---------- */
.toolbar {
  display: flex;
  align-items: flex-start;
  padding: 2px 3px;
  background: var(--face);
  border-top: 1px solid var(--hilight);
  border-bottom: 1px solid var(--shadow);
  overflow: hidden;
}
.tb-btn {
  flex: none;
  min-width: 46px;
  padding: 3px 6px 4px;
  background: transparent;
  border: 1px solid transparent;
  color: var(--text);
  font: 11px/1.25 var(--font);
  text-align: center;
  cursor: default;
  user-select: none;
}
.tb-btn:hover { border-color: var(--hilight) var(--shadow) var(--shadow) var(--hilight); }
.tb-btn:active,
.tb-btn.is-pressed {
  border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow);
  padding: 4px 5px 3px 7px;
}
.tb-btn:focus { outline: 1px dotted var(--dark); outline-offset: -3px; }
.tb-btn__ico {
  display: block;
  width: 16px;
  height: 16px;
  margin: 0 auto 2px;
}
.tb-btn__label { display: block; white-space: nowrap; }
.tb-sep {
  flex: none;
  width: 2px;
  height: 34px;
  margin: 2px 4px 0;
  border-left: 1px solid var(--shadow);
  border-right: 1px solid var(--hilight);
}

/* ---------- 地址栏 ---------- */
.addrbar {
  display: flex;
  align-items: center;
  padding: 3px;
  background: var(--face);
  border-bottom: 1px solid var(--shadow);
}
.addrbar__label {
  flex: none;
  width: 58px;
  padding-left: 2px;
}
.addrbar__field {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  min-width: 0;
  height: 21px;
  padding: 0 3px;
  background: #fff;
  border: 1px solid;
  border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow);
  box-shadow: inset 1px 1px 0 var(--dark), inset -1px -1px 0 var(--light);
  overflow: hidden;
}
.addrbar__ico {
  flex: none;
  width: 16px;
  height: 16px;
  margin-right: 5px;
}
.addrbar__url {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 12px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.addrbar .btn {
  flex: none;
  height: 21px;
  margin-left: 4px;
}

/* ---------- 工作区（凹陷滚动区） ---------- */
.workspace {
  position: relative;
  height: 520px;
  max-height: calc(100vh - 150px);
  padding: 6px;
  background: var(--face);
  border: 1px solid;
  border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow);
  box-shadow: inset 1px 1px 0 var(--dark), inset -1px -1px 0 var(--light);
  overflow-y: scroll;
  overflow-x: hidden;
}
/* 注：.window.is-maxed .workspace 的弹性尺寸见上方第 6 节「最大化」区块 */

/* 两栏：Grid 布局 */
.ws-inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--side-w);
  gap: 10px;
  align-items: start;
}
.col-main,
.col-side { min-width: 0; }
.col-side { display: grid; gap: 10px; }

/* ---------- 分组框（GroupBox） ---------- */
.group {
  position: relative;
  margin: 12px 0 10px;
  padding: 12px 10px 10px;
  border: 1px solid;
  border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow);
  box-shadow: inset 1px 1px 0 var(--hilight), inset -1px -1px 0 var(--shadow);
}
.group:first-child { margin-top: 4px; }
.group__legend {
  position: absolute;
  top: -8px;
  left: 8px;
  padding: 0 4px;
  background: var(--face);
  font-size: 12px;
  font-weight: bold;
  line-height: 16px;
}
.group__legend .tag {
  display: inline-block;
  margin-left: 6px;
  padding: 0 5px;
  background: var(--hl-bg);
  color: var(--hl-fg);
  font-size: 10px;
  font-weight: normal;
  line-height: 14px;
  vertical-align: 1px;
}

/* ==========================================================================
   7. UP 主名片
   ========================================================================== */
.profile {
  display: grid;
  grid-template-columns: 88px minmax(0, 1fr);
  gap: 12px;
}
.profile__avatar {
  width: 88px;
  height: 88px;
  padding: 2px;
  background: var(--face);
  border: 1px solid;
  border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow);
  box-shadow: inset 1px 1px 0 var(--dark), inset -1px -1px 0 var(--light);
  overflow: hidden;
}
.profile__avatar img {
  width: 82px;
  height: 82px;
  background: #fff;
}
.profile__name {
  font-size: 15px;
  font-weight: bold;
  line-height: 1.4;
}
.profile__uid {
  margin-left: 6px;
  font-size: 11px;
  font-weight: normal;
  color: var(--text-dim);
}
.profile__sign {
  max-height: 62px;
  margin-top: 4px;
  padding: 5px 7px;
  background: #fff;
  border: 1px solid;
  border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow);
  box-shadow: inset 1px 1px 0 var(--dark), inset -1px -1px 0 var(--light);
  font-size: 12px;
  line-height: 1.6;
  overflow: hidden;
  overflow-wrap: break-word;
}
.profile__badges { margin-top: 6px; }
.badge {
  display: inline-block;
  margin: 0 5px 4px 0;
  padding: 1px 6px;
  background: var(--face);
  border: 1px solid;
  border-color: var(--hilight) var(--shadow) var(--shadow) var(--hilight);
  font-size: 11px;
  line-height: 16px;
}
.badge--lv {
  background: var(--hl-bg);
  border-color: #6b6bff #000040 #000040 #6b6bff;
  color: var(--hl-fg);
  font-weight: bold;
}

/* 统计小格 */
.stats {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 6px;
  margin-top: 8px;
}
.stats__box {
  padding: 5px 4px;
  background: var(--face);
  border: 1px solid;
  border-color: var(--hilight) var(--shadow) var(--shadow) var(--hilight);
  text-align: center;
}
.stats__k {
  display: block;
  font-size: 10px;
  line-height: 1.4;
  color: var(--text-dim);
}
.stats__v {
  display: block;
  font-size: 14px;
  font-weight: bold;
  line-height: 1.4;
  color: var(--hl-bg);
}

/* 按钮行 */
.btnrow {
  display: flex;
  flex-wrap: wrap;
  /* EdgeHTML 18 的 Flexbox 不支持 gap（该特性 Edge 84+ 才加入），
     改用「容器负外边距 + 子项外边距」实现等距换行排列：
     容器 margin: 7px -3px -3px 抵消子项 3px 外边距后，
     上间距 = 7+3 = 10px，行列间距 = 3+3 = 6px，四边不溢出。 */
  margin: 7px -3px -3px;
}
.btnrow > * { margin: 3px; }

/* ==========================================================================
   8. 投稿列表
   ========================================================================== */
.viewbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 3px 0 6px;
}
/* 同上：用相邻兄弟外边距替代 flex gap。
   space-between 下 gap 的作用是「最小间距」，margin-left 与之等价：
   剩余空间充足时 visual gap = F，不足时 = 8px。 */
.viewbar > * + * { margin-left: 8px; }
.viewbar__info {
  min-width: 0;
  font-size: 11px;
  color: var(--text-dim);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.viewbar__tools {
  flex: none;
  display: flex;
}
.viewbar__tools > * + * { margin-left: 4px; }

.videolist {
  min-height: 120px;
  padding: 2px;
  background: #fff;
  border: 1px solid;
  border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow);
  box-shadow: inset 1px 1px 0 var(--dark), inset -1px -1px 0 var(--light);
}

.video {
  display: grid;
  grid-template-columns: 168px minmax(0, 1fr);
  gap: 10px;
  padding: 6px;
  border-bottom: 1px solid #e4e4e4;
  cursor: default;
}
.video:last-child { border-bottom: 0; }
.video:hover { background: var(--hl-bg); color: var(--hl-fg); }
.video:hover .video__title a,
.video:hover .video__title a:visited { color: var(--hl-fg); }
.video:hover .video__meta,
.video:hover .video__bvid { color: var(--light); }
.video:hover .video__thumb { border-color: #fff #000 #000 #fff; }

.video__thumb {
  display: block;
  width: 168px;
  height: 95px;
  padding: 1px;
  background: #000;
  border: 1px solid;
  border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow);
  overflow: hidden;
}
.video__thumb img,
.video__thumb .thumb-ph {
  width: 164px;
  height: 91px;
  background-color: #d8d8d8;
}
.video__thumb .thumb-ph {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  color: var(--text-mute);
  background-image: repeating-linear-gradient(
    45deg,
    #d8d8d8 0 4px,
    #cfcfcf 4px 8px
  );
}

.video__body {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  min-width: 0;
}
.video__go {
  order: -1;
  align-self: flex-end;
  margin-bottom: 2px;
}
.video__title {
  font-size: 13px;
  font-weight: bold;
  line-height: 1.45;
  overflow-wrap: break-word;
}
.video__title a { color: var(--hl-bg); }
.video__idx {
  display: inline-block;
  min-width: 18px;
  margin-right: 5px;
  padding: 0 3px;
  background: var(--face);
  border: 1px solid;
  border-color: var(--hilight) var(--shadow) var(--shadow) var(--hilight);
  color: var(--text);
  font-size: 10px;
  line-height: 15px;
  text-align: center;
  vertical-align: 1px;
}
.video:hover .video__idx {
  background: var(--title-to);
  border-color: #fff #000080 #000080 #fff;
  color: #fff;
}
.video__meta {
  margin-top: 5px;
  font-size: 11px;
  line-height: 1.6;
  color: var(--text-dim);
}
.video__meta span {
  display: inline-block;
  margin-right: 10px;
  white-space: nowrap;
}
.video__bvid {
  display: inline-block;
  margin-top: 5px;
  padding: 1px 5px;
  background: var(--face);
  border: 1px solid;
  border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow);
  font-family: var(--mono);
  font-size: 11px;
}
.video:hover .video__bvid { background: #fff; color: #000; }

/* 列表视图：隐藏封面，压成单行 */
.videolist.mode-list .video {
  grid-template-columns: minmax(0, 1fr);
  gap: 0;
  padding: 3px 6px;
}
.videolist.mode-list .video__thumb { display: none; }
.videolist.mode-list .video__body { display: block; }
.videolist.mode-list .video__go { display: none; }
.videolist.mode-list .video__title { display: inline; font-size: 12px; }
.videolist.mode-list .video__meta { display: inline; margin-left: 10px; }
.videolist.mode-list .video__bvid { margin: 0 0 0 8px; }

/* 关闭「显示视频封面」 */
.videolist.no-thumb .video { grid-template-columns: minmax(0, 1fr); }
.videolist.no-thumb .video__thumb { display: none; }

/* ==========================================================================
   9. 动态时间线
   ========================================================================== */
.feed { padding: 2px; background: #fff; }
.feed__item {
  display: grid;
  grid-template-columns: 9px minmax(0, 1fr);
  gap: 10px;
  padding: 6px 8px;
  border-bottom: 1px dotted #b4b4b4;
}
.feed__item:last-child { border-bottom: 0; }
.feed__dot {
  width: 9px;
  height: 9px;
  margin-top: 5px;
  background: var(--hl-bg);
  border: 1px solid #000040;
}
.feed__item--video   .feed__dot { background: #008000; border-color: #004000; }
.feed__item--profile .feed__dot { background: var(--shadow); border-color: var(--text-dim); }
.feed__text {
  font-size: 12px;
  line-height: 1.65;
  overflow-wrap: break-word;
}
.feed__text a { color: var(--hl-bg); }
.feed__time {
  font-size: 11px;
  color: var(--text-mute);
}
.feed__kind {
  display: inline-block;
  margin-right: 5px;
  padding: 0 5px;
  background: var(--face);
  border: 1px solid;
  border-color: var(--hilight) var(--shadow) var(--shadow) var(--hilight);
  font-size: 10px;
  line-height: 14px;
}

/* ==========================================================================
   10. 进度条 / 数据条
   ========================================================================== */
/* 不确定进度：一条滑块左右往复，纯 CSS 动画，无需 JS 驱动 */
.progress {
  position: relative;
  height: 18px;
  padding: 2px;
  background: #fff;
  border: 1px solid;
  border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow);
  box-shadow: inset 1px 1px 0 var(--dark), inset -1px -1px 0 var(--light);
  overflow: hidden;
}
.progress__bar {
  position: absolute;
  top: 2px;
  left: 0;
  width: 42%;
  height: 12px;
  background-image: linear-gradient(
    90deg,
    var(--hl-bg) 0 9px,
    transparent 9px 11px
  );
  background-size: 11px 12px;
  animation: prog-slide 1.7s linear infinite;
}
@keyframes prog-slide {
  from { transform: translateX(-110%); }
  to   { transform: translateX(250%); }
}
@media (prefers-reduced-motion: reduce) {
  .progress__bar { animation-duration: 6s; }
}

/* 数据条（分区分布） */
.bar-row {
  display: grid;
  grid-template-columns: 96px minmax(0, 1fr) 52px;
  gap: 6px;
  align-items: center;
  padding: 3px 0;
}
.bar-row__name {
  font-size: 11px;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.bar-row__num {
  font-size: 11px;
  color: var(--text-dim);
  text-align: right;
}
.bar {
  display: block;
  height: 16px;
  padding: 2px;
  background: #fff;
  border: 1px solid;
  border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow);
  box-shadow: inset 1px 1px 0 var(--dark), inset -1px -1px 0 var(--light);
  overflow: hidden;
}
.bar__fill {
  display: block;
  height: 10px;
  background: var(--hl-bg);
}

/* ==========================================================================
   11. 状态栏
   ========================================================================== */
.statusbar {
  display: flex;
  margin-top: 3px;
}
.statusbar > * + * { margin-left: 2px; }
.statusbar__pane {
  flex: none;
  height: 20px;
  padding: 0 7px;
  font-size: 11px;
  line-height: 20px;
  border: 1px solid;
  border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow);
  box-shadow: inset 1px 1px 0 var(--dark), inset -1px -1px 0 var(--light);
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.statusbar__pane--grow { flex: 1 1 auto; min-width: 0; }
.statusbar__pane--right { width: 62px; text-align: center; }
/* 播放器状态栏：时间格需完整容纳「01:58 / 05:37」（13 字符），
   默认 62px 会截断成「01:58 /…」。这里放宽到 100px 并用等宽小字号，
   同时让曲名格 min-width:0 以便在窄屏时优先压缩曲名而非截断时间。 */
.window--mp .statusbar__pane--right {
  flex: none;
  width: 100px;
  font-family: var(--mono);
  font-size: 10px;
  padding: 0 4px;
}
.window--mp .statusbar__pane--grow {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ==========================================================================
   12. 任务栏
   ========================================================================== */
.taskbar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  height: var(--taskbar-h);
  padding: 2px 3px;
  background: var(--face);
  border-top: 1px solid var(--hilight);
  box-shadow: 0 -1px 0 var(--shadow);
}
.start-btn {
  flex: none;
  display: flex;
  align-items: center;
  height: 26px;
  padding: 0 8px 0 5px;
  background: var(--face);
  border: 1px solid;
  border-color: var(--light) var(--dark) var(--dark) var(--light);
  box-shadow: inset 1px 1px 0 var(--hilight), inset -1px -1px 0 var(--shadow);
  color: var(--text);
  font: bold 12px/1 var(--font);
  cursor: default;
  user-select: none;
}
.start-btn:active,
.start-btn.is-open {
  border-color: var(--dark) var(--light) var(--light) var(--dark);
  box-shadow: inset 1px 1px 0 var(--shadow), inset -1px -1px 0 var(--hilight);
}
.start-btn__ico {
  width: 16px;
  height: 16px;
  margin-right: 4px;
}
/* flex 布局下裸文本会成为可换行的匿名 flex 项，需显式禁止换行 */
.start-btn__label { white-space: nowrap; }
.taskbar__sep {
  flex: none;
  width: 2px;
  height: 24px;
  margin: 0 4px;
  border-left: 1px solid var(--shadow);
  border-right: 1px solid var(--hilight);
}
.taskbar__tasks {
  flex: 0 1 620px;
  display: flex;
  min-width: 0;
  height: 26px;
  overflow: hidden;
}
.task-btn {
  flex: 0 1 190px;
  display: flex;
  align-items: center;
  min-width: 0;
  height: 26px;
  margin-right: 3px;
  padding: 0 8px;
  background: var(--face);
  border: 1px solid;
  border-color: var(--light) var(--dark) var(--dark) var(--light);
  box-shadow: inset 1px 1px 0 var(--hilight), inset -1px -1px 0 var(--shadow);
  color: var(--text);
  font: 12px/1 var(--font);
  text-align: left;
  cursor: default;
  overflow: hidden;
}
.task-btn.is-active {
  border-color: var(--dark) var(--light) var(--light) var(--dark);
  box-shadow: inset 1px 1px 0 var(--shadow), inset -1px -1px 0 var(--hilight);
  background: #d4d4d4;
  font-weight: bold;
}
/* 最小化（区别于「关闭」）：按钮保留在任务栏，但呈「未按下」的弱化态 —
   与 is-active 的凹陷高亮形成对比，也与「关闭后按钮消失」形成区分。
   注意：本类由 WinWM.syncTaskBtn 统一维护，勿在各模块手改。 */
.task-btn.is-minimized {
  color: #6b6b6b;
  font-style: italic;
}
.task-btn.is-minimized .task-btn__label::after {
  content: ' (已最小化)';
  font-style: normal;
  font-size: 11px;
}
.task-btn__ico {
  flex: none;
  width: 16px;
  height: 16px;
  margin-right: 5px;
}
.task-btn__label {
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.tray {
  flex: none;
  display: flex;
  align-items: center;
  height: 26px;
  margin-left: auto;
  padding: 0 6px;
  border: 1px solid;
  border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow);
  box-shadow: inset 1px 1px 0 var(--dark), inset -1px -1px 0 var(--light);
}
.tray__icons {
  display: flex;
  align-items: center;
  margin-right: 4px;
}
.tray__icons svg { margin-right: 3px; }
.tray__clock {
  display: flex;
  flex-direction: column;
  justify-content: center;
  text-align: center;
}
.tray__time {
  font-size: 11px;
  font-weight: bold;
  line-height: 13px;
}
.tray__date {
  font-size: 10px;
  line-height: 11px;
}

/* ---------- 开始菜单 ---------- */
.startmenu {
  position: fixed;
  left: 3px;
  bottom: calc(var(--taskbar-h) + 2px);
  z-index: 120;
  display: none;
  width: 240px;
  padding: 2px 2px 2px 26px;
  background: var(--face);
  border: 1px solid;
  border-color: var(--light) var(--dark) var(--dark) var(--light);
  box-shadow:
    inset 1px 1px 0 var(--hilight),
    inset -1px -1px 0 var(--shadow),
    2px 2px 0 rgba(0, 0, 0, .35);
}
.startmenu.is-open { display: block; }
.startmenu__rail {
  position: absolute;
  left: 2px;
  top: 2px;
  bottom: 2px;
  width: 22px;
  overflow: hidden;
  background: linear-gradient(0deg, var(--title-from), var(--title-to));
}
/* 竖排文字：以左上角为原点逆时针旋转 90°，自下而上阅读 */
.startmenu__rail span {
  position: absolute;
  left: 1px;
  bottom: 2px;
  width: 260px;
  color: #fff;
  font-size: 13px;
  font-weight: bold;
  letter-spacing: 1px;
  white-space: nowrap;
  transform-origin: 0 0;
  transform: rotate(-90deg);
}
.startmenu__item {
  display: block;
  position: relative;
  padding: 5px 8px 5px 34px;
  font-size: 12px;
  color: var(--text);
  cursor: default;
}
.startmenu__item:hover {
  background: var(--hl-bg);
  color: var(--hl-fg);
  text-decoration: none;
}
.startmenu__item i {
  position: absolute;
  left: 8px;
  top: 5px;
  width: 20px;
  height: 20px;
}
.startmenu__sep {
  height: 0;
  margin: 3px 2px;
  border-top: 1px solid var(--shadow);
  border-bottom: 1px solid var(--hilight);
}

/* ==========================================================================
   13. 消息框 / 提示条
   ========================================================================== */
.modal-mask {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 200;
  display: none;
  background: #000;
  opacity: .18;
}
.modal-mask.is-open { display: block; }

/* 模态对话框。
   默认居中：left:50% + margin-left:-W/2（W=400px 的一半）。
   首次打开时由 JS 把「居中结果」固化成像素 left/top，并清掉 margin-left，
   此后 left/top 即为拖拽的唯一真值来源（避免百分比定位与像素拖拽互相打架）。
   固化后 .dialog--placed 生效，margin-left 归零。 */
.dialog {
  position: fixed;
  left: 50%;
  top: 34%;
  z-index: 210;
  display: none;
  width: 400px;
  max-width: calc(100% - 24px);
  margin-left: -200px;
  padding: 3px;
  background: var(--face);
  border: 1px solid;
  border-color: var(--light) var(--dark) var(--dark) var(--light);
  box-shadow:
    inset 1px 1px 0 var(--hilight),
    inset -1px -1px 0 var(--shadow),
    3px 3px 0 rgba(0, 0, 0, .4);
}
.dialog--placed { margin-left: 0; }
.dialog.is-open { display: block; }
.dialog.is-dragging { cursor: move; }
/* 拖动中禁止选中正文（否则会拖出文本选区，观感像故障） */
.dialog.is-dragging .dialog__text { user-select: none; }
.dialog__title {
  height: 20px;
  padding: 0 3px;
  background: linear-gradient(90deg, var(--title-from), var(--title-to));
  color: #fff;
  font-size: 12px;
  font-weight: bold;
  line-height: 20px;
  /* 标题栏即拖拽把手 */
  cursor: move;
  user-select: none;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.dialog__body {
  display: grid;
  grid-template-columns: 32px minmax(0, 1fr);
  gap: 14px;
  padding: 16px 14px 10px;
}
.dialog__text {
  font-size: 12px;
  line-height: 1.7;
  overflow-wrap: break-word;
}
.dialog__text code {
  padding: 0 3px;
  background: #fff;
  border: 1px solid var(--shadow);
}
.dialog__text ul { padding-left: 18px; list-style: disc; }
.dialog__foot {
  display: flex;
  justify-content: center;
  padding: 4px 10px 12px;
}
.dialog__foot > * + * { margin-left: 10px; }

.toast {
  position: fixed;
  right: 8px;
  bottom: calc(var(--taskbar-h) + 6px);
  z-index: 130;
  display: none;
  width: 262px;
  padding: 3px;
  background: var(--face);
  border: 1px solid;
  border-color: var(--light) var(--dark) var(--dark) var(--light);
  box-shadow:
    inset 1px 1px 0 var(--hilight),
    inset -1px -1px 0 var(--shadow),
    2px 2px 0 rgba(0, 0, 0, .35);
}
.toast.is-open { display: block; }
.toast__title {
  height: 18px;
  padding: 0 3px;
  background: var(--hl-bg);
  color: #fff;
  font-size: 11px;
  font-weight: bold;
  line-height: 18px;
}
.toast__body {
  padding: 6px 7px;
  font-size: 11px;
  line-height: 1.6;
  overflow-wrap: break-word;
}

/* ==========================================================================
   14. 提示 / 空态 / 错误态
   ========================================================================== */
.notice {
  margin: 6px 0;
  padding: 6px 8px;
  background: #ffffe1;
  border: 1px solid var(--shadow);
  font-size: 11px;
  line-height: 1.6;
}
.notice--warn { background: #fff4d6; }

.empty {
  padding: 26px 12px;
  font-size: 12px;
  color: var(--text-dim);
  text-align: center;
}
.empty__big {
  display: block;
  margin-bottom: 6px;
  color: var(--hl-bg);
  font-size: 14px;
  font-weight: bold;
}

.errorbox {
  display: grid;
  grid-template-columns: 32px minmax(0, 1fr);
  gap: 12px;
  padding: 14px;
  background: #fff;
  border: 1px solid;
  border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow);
  box-shadow: inset 1px 1px 0 var(--dark), inset -1px -1px 0 var(--light);
}
.errorbox__title {
  margin-bottom: 5px;
  font-size: 13px;
  font-weight: bold;
}
.errorbox__desc {
  font-size: 12px;
  line-height: 1.7;
}
.errorbox__desc code,
.tips code,
.kv code {
  padding: 0 3px;
  background: #fff;
  border: 1px solid #c0c0c0;
}
.errorbox__foot {
  display: flex;
  flex-wrap: wrap;
  margin: 7px -3px -3px;
}
.errorbox__foot > * { margin: 3px; }

/* 键值表 */
.kv { font-size: 11px; line-height: 1.9; }
.kv dl {
  display: grid;
  grid-template-columns: 74px minmax(0, 1fr);
  gap: 0 4px;
}
.kv dt { color: var(--text-dim); }
.kv dd { overflow-wrap: break-word; }

.tips {
  font-size: 11px;
  line-height: 1.85;
  color: #303030;
}
.tips li {
  position: relative;
  padding-left: 12px;
}
.tips li::before {
  content: "\25AA";
  position: absolute;
  left: 2px;
  color: var(--hl-bg);
}

/* ==========================================================================
   15. 记事本窗口（Markdown 渲染 / 源码编辑）
   --------------------------------------------------------------------------
   面板切换完全由 CSS Grid 的列模板驱动，JS 只负责切换根节点 class：
     .np-split            → 单栏（仅渲染面板；源码面板 display:none）
     .np-split.is-source  → 单栏（仅源码面板）
     .np-split.is-split   → 双栏（源码 1fr | 渲染 1fr），窄屏自动降为上下两行
   这样避免 JS 参与布局计算，行为可预测且易扩展。
   ========================================================================== */
.np-workspace {
  /* 记事本工作区比主窗口略高，便于阅读长文档 */
  height: 560px;
  max-height: calc(100vh - 170px);
  background: var(--face);
}

.np-split {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0;
  height: 100%;
  min-height: 0;
}
.np-split.is-split { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.np-split.is-split .np-pane + .np-pane { border-left: 1px solid var(--shadow); }

.np-pane {
  min-width: 0;
  min-height: 0;
  overflow: hidden;
}
.np-pane--source { display: none; }
.np-split.is-source .np-pane--source,
.np-split.is-split  .np-pane--source { display: flex; }
.np-split.is-source .np-pane--preview { display: none; }

/* ---------- 源码编辑区 ---------- */
.np-pane--source { position: relative; background: #fff; }

/* 行号槽：与编辑区同一行高，随编辑区同步滚动 */
.np-lineno {
  flex: none;
  width: 38px;
  height: 100%;
  padding: 8px 6px 8px 0;
  background: var(--face);
  border-right: 1px solid;
  border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow);
  color: var(--text-dim);
  font: 12px/18px var(--mono);
  text-align: right;
  white-space: pre;
  overflow: hidden;
  user-select: none;
}
.np-split.no-lineno .np-lineno { display: none; }

.np-editor {
  flex: 1 1 auto;
  min-width: 0;
  height: 100%;
  padding: 8px 10px;
  border: 0;
  outline: none;
  resize: none;
  background: #fff;
  color: var(--text);
  font: 12px/18px var(--mono);
  white-space: pre;
  overflow: auto;
  tab-size: 2;
  /* 触摸滚动：显式声明纵向可平移，避免手势被外层拦截；
     pan-x 保留横向平移（wrap="off" 时长行需要横滚）。
     注：不使用 overscroll-behavior —— 需 Edge 63+ / Chromium 内核，
     本表基线 EdgeHTML 18 会整条丢弃；边界行为改由 touch-action
     与容器 overflow 收口，在旧内核下同样有效。 */
  touch-action: pan-x pan-y;
  -webkit-overflow-scrolling: touch;
}
.np-editor::placeholder { color: #909090; }

.np-pane--preview {
  padding: 8px 10px;
  background: #fff;
  overflow-y: auto;
  overflow-x: hidden;
  /* 触摸滚动：只声明 pan-y（本面板不横滚），并启用 iOS 风格惯性滚动。
     惯性在现代 Chromium / EdgeHTML 上默认就有，此处显式声明是给 Safari
     系内核的兼容开关（旧 iOS 需该属性才回弹/惯性）。 */
  touch-action: pan-y;
  -webkit-overflow-scrolling: touch;
}

/* ==========================================================================
   15b. Markdown 渲染排版（.md 作用域）
   --------------------------------------------------------------------------
   独立的排版命名空间，不污染主窗口既有元素；
   表格虽不在必需语法清单内，仍一并支持以提升实用性。
   ========================================================================== */
.md {
  color: var(--text);
  font: 13px/1.7 var(--font);
  overflow-wrap: break-word;
  word-wrap: break-word;
}

.md > *:first-child { margin-top: 0; }
.md > *:last-child  { margin-bottom: 0; }

/* ---------- 标题 ---------- */
.md h1, .md h2, .md h3,
.md h4, .md h5, .md h6 {
  margin: 16px 0 8px;
  font-weight: bold;
  line-height: 1.35;
}
.md h1 {
  padding-bottom: 5px;
  border-bottom: 2px solid var(--shadow);
  font-size: 22px;
}
.md h2 {
  padding-bottom: 4px;
  border-bottom: 1px solid var(--light);
  font-size: 18px;
}
.md h3 { font-size: 16px; }
.md h4 { font-size: 14px; }
.md h5 { font-size: 13px; color: var(--text-dim); }
.md h6 { font-size: 12px; color: var(--text-mute); }

/* ---------- 段落 / 分隔线 ---------- */
.md p { margin: 8px 0; }
.md hr {
  height: 0;
  margin: 16px 0;
  border: 0;
  border-top: 1px solid var(--shadow);
  border-bottom: 1px solid var(--hilight);
}

/* ---------- 列表 ---------- */
.md ul, .md ol { margin: 8px 0; padding-left: 26px; }
.md ul { list-style: disc; }
.md ol { list-style: decimal; }
.md li { margin: 3px 0; }
.md ul ul, .md ol ol, .md ul ol, .md ol ul { margin: 3px 0; }
.md ul ul     { list-style: circle; }
.md ul ul ul  { list-style: square; }
.md li > p    { margin: 3px 0; }

/* 段落内直接换行（非列表）保留视觉换行 */
.md .md-br { display: block; height: 0; }

/* ---------- 行内排版 ---------- */
.md strong { font-weight: bold; }
.md em     { font-style: italic; }
.md del    { color: var(--text-dim); }
.md a { color: var(--link); text-decoration: underline; }
.md a:visited { color: var(--link-vis); }
.md a:hover { background: var(--hl-bg); color: var(--hl-fg); text-decoration: none; }

/* ---------- 行内代码 ---------- */
.md code {
  padding: 1px 4px;
  background: #f2f2f2;
  border: 1px solid #d0d0d0;
  font-family: var(--mono);
  font-size: 12px;
  white-space: pre-wrap;
}

/* ---------- 代码块 ---------- */
.md pre {
  position: relative;
  margin: 10px 0;
  padding: 22px 10px 10px;
  background: #ffffff;
  border: 1px solid;
  border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow);
  box-shadow: inset 1px 1px 0 var(--dark), inset -1px -1px 0 var(--light);
  overflow-x: auto;
}
.md pre code {
  display: block;
  padding: 0;
  background: none;
  border: 0;
  font-size: 12px;
  line-height: 1.65;
  white-space: pre;
}
/* 语言标识：左上角小标签（Windows 标题栏配色） */
.md pre[data-lang]::before {
  content: attr(data-lang);
  position: absolute;
  top: 2px;
  left: 3px;
  padding: 0 5px;
  background: linear-gradient(90deg, var(--title-from), var(--title-to));
  color: #fff;
  font: 10px/14px var(--mono);
  text-transform: uppercase;
  letter-spacing: .5px;
}

/* ---------- 引用块 ---------- */
.md blockquote {
  margin: 10px 0;
  padding: 6px 10px;
  background: #ffffe1;
  border-left: 4px solid var(--hl-bg);
  border-top: 1px solid #e0e0b0;
  border-bottom: 1px solid #e0e0b0;
  color: #303030;
}
.md blockquote > *:first-child { margin-top: 0; }
.md blockquote > *:last-child  { margin-bottom: 0; }

/* ---------- 图片 ---------- */
.md img {
  display: block;
  max-width: 100%;
  height: auto;
  margin: 10px 0;
  padding: 2px;
  background: var(--face);
  border: 1px solid;
  border-color: var(--shadow) var(--hilight) var(--hilight) var(--shadow);
}
.md .md-imgfail {
  display: block;
  margin: 10px 0;
  padding: 14px 10px;
  background: #f7f7f7;
  border: 1px dashed var(--shadow);
  color: var(--text-mute);
  font-size: 12px;
  text-align: center;
}

/* ---------- 表格（附加支持） ---------- */
.md .md-tablewrap { margin: 10px 0; overflow-x: auto; }
.md table {
  width: 100%;
  background: #fff;
  border: 1px solid var(--shadow);
  font-size: 12px;
}
.md th, .md td {
  padding: 4px 8px;
  border: 1px solid #c8c8c8;
  text-align: left;
  vertical-align: top;
}
.md th {
  background: var(--face);
  font-weight: bold;
  white-space: nowrap;
}
.md tbody tr:nth-child(even) { background: #f7f7f7; }

/* ==========================================================================
   15c. 媒体播放机窗口（原生音频播放 + Windows 3.1 视觉）
   --------------------------------------------------------------------------
   与旧版（iframe 跨域 + 覆盖层）相比的根本变化：
     · 音源改为本站自有的 assets/audio/dreamy-noise.mp3，用 <audio> 播放；
     · 因此进度、时长、音量、播放状态全部是**真实值**，不再是「视觉意象」；
     · 不再需要跨域规避、同框对齐、点击穿透拦截等一整套 hack。

   视觉蓝本：原生「媒体播放机」（非 WMP9+），自上而下三行：
     ① 单行菜单栏          文件(F) 编辑(E) 设备(D) 刻度(S) 帮助(H)
     ② 主刻度条            细长进度轨道 + 两端三角微调 + 时间读数
     ③ 底部传输按钮排      ▶ ■ ⏸ | ⏮ ⏪ ▶▶ ⏩ | ⏏ ⏭

   字形一律用 border 三角形拼（禁用 clip-path —— Edge 79+ 才支持，
   在 EdgeHTML 18 会退化成实心方块）。
   ========================================================================== */
.window--mp {
  --window-w: 460px;
  margin: 78px auto 26px;
}
/* 注：播放器最大化时的尺寸由上方「最大化：用弹性填充替代魔法常量」统一处理 */

/* ---------- 舞台 ---------- */
.mp-workspace {
  background: var(--face);
  /* 正常态：容纳刻度条 + 读数 + 按钮排 + 可选面板 */
  height: 208px;
  max-height: calc(100vh - 190px);
  overflow: auto;
}
.mp-stage {
  position: relative;
  width: 100%;
  min-height: 100%;
  padding: 8px 10px 10px;
  background: var(--face);
  box-sizing: border-box;
}

/* ==========================================================================
   ① 主刻度条
   --------------------------------------------------------------------------
   轨道为「凹槽」外观（暗色 3D 边框 + 内阴影），条身是经典蓝渐变，
   右下角有可拖拽的旋钮（.mp-scale__knob）。
   ========================================================================== */
.mp-scalerow {
  display: flex;
  align-items: center;
}
.mp-scale {
  position: relative;
  flex: 1 1 auto;
  min-width: 0;
  height: 22px;
  margin: 0 4px;
  background: #ffffff;
  border: 1px solid;
  border-color: var(--dark) var(--light) var(--light) var(--dark);
  box-shadow: inset 1px 1px 0 var(--shadow);
  cursor: pointer;
  overflow: hidden;
}
/* 刻度纹理：每 8px 一根细竖线，靠 repeating-linear-gradient 生成（Edge 12+ 支持） */
.mp-scale__ticks {
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  height: 5px;
  background-image: repeating-linear-gradient(
    90deg,
    #808080 0, #808080 1px,
    transparent 1px, transparent 8px
  );
  pointer-events: none;
}
.mp-scale__bar {
  position: absolute;
  left: 1px;
  top: 1px;
  bottom: 1px;
  width: 0;
  background: linear-gradient(180deg, #000080 0%, #1084d0 55%, #000080 100%);
  pointer-events: none;
}
/* 旋钮：SVG 矢量握柄。
   定位策略 = 「left 按百分比驱动 + translateX(-50%) 自居中」：
     · left 由 JS 写成百分比（0–100%），随轨道长度线性伸缩；
     · translateX(-50%) 让旋钮**自身**在锚点处水平居中，与旋钮宽度无关
       —— 旧版用固定 -3px 的负 margin，旋钮宽度一变（或缩放）就会偏。
     · top/bottom 撑满轨道内容区，保证垂直方向始终与轨道对齐。
   注意：这里不能用 margin:auto 居中，因为 left 是百分比锚点，
   水平方向要的是「锚点居中」而非「容器居中」。

   垂直方向同理：不能让 top/bottom 同时拉伸（盒子高度由内容驱动时
   会过约束，导致元素贴顶、中心上移约 2.6px）。改为 top:50% +
   translateY(-50%)，由 transform 自身居中，**与轨道高度完全无关**。 */
.mp-scale__knob,
.mp-vol__knob {
  position: absolute;
  top: 50%;
  width: 7px;
  /* 7px 宽 × 12:22 设计比 = 12.83px 高；显式写出，避免 height:auto 塌缩 */
  height: 12.83px;
  left: 1px;
  transform: translate(-50%, -50%);
  fill: currentColor;
  color: var(--face);
  pointer-events: none;
}
.mp-scale:focus {
  outline: 1px dotted #000000;
  outline-offset: -3px;
}

/* 两端三角微调按钮 */
.mp-spin {
  flex: none;
  width: 17px;
  height: 17px;
  padding: 0;
  background: var(--face);
  border: 1px solid;
  border-color: var(--light) var(--dark) var(--dark) var(--light);
  box-shadow: inset 1px 1px 0 var(--hilight), inset -1px -1px 0 var(--shadow);
  position: relative;
  cursor: default;
}
.mp-spin:active,
.mp-spin.is-pressed {
  border-color: var(--dark) var(--light) var(--light) var(--dark);
  box-shadow: inset 1px 1px 0 var(--shadow);
}
/* 刻度条两端的微调箭头：同为 SVG，尺寸小于主按钮排，
   同样靠「绝对定位 + 四边归零 + margin:auto」居中。 */
.mp-spin > .mp-ico { --ico-size: 9px; }

/* ---------- 刻度读数 ---------- */
.mp-readout {
  display: flex;
  align-items: center;
  margin: 5px 2px 0;
  font: 10px/1.2 var(--mono);
  color: var(--text-dim);
  white-space: nowrap;
}
.mp-readout__elapsed { color: var(--text); font-weight: bold; }
.mp-readout__sep { margin: 0 3px; }
.mp-readout__spacer { flex: 1 1 auto; min-width: 8px; }
.mp-readout__track {
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  font-family: var(--font);
}

/* ==========================================================================
   ② 底部传输按钮排
   ========================================================================== */
.mp-pad {
  display: flex;
  align-items: center;
  margin: 9px 2px 0;
}
/* 按钮间距：用相邻兄弟选择器加左侧外边距，而不是容器 gap
   —— flex 容器的 gap 需要 Edge 84+，本项目基线是 EdgeHTML 18。
   规则拆成三条，各自只负责一件事：
   1. 按钮紧跟按钮      → 左外边距 3px（常规按钮间距）
   2. 按钮紧跟分隔符    → 左外边距 0  （分隔符自带左右 margin，不再叠加）
   3. 分隔符紧跟按钮    → 不动分隔符的 margin，保留它自己的左右 5px
   注意第 2、3 条必须分开写：`.mp-tbtn + .mp-pad__sep` 匹配的是分隔符本身，
   若把它与第 2 条并列写成同一个块，会把分隔符的 margin-left 也清零，
   导致「按钮—分隔符」之间塌成 0px（实测就是这个症状）。 */
.mp-tbtn + .mp-tbtn {
  margin-left: 3px;
}
.mp-pad__sep + .mp-tbtn {
  margin-left: 0;
}
/* ----------------------------------------------------------------------
   传输按钮：尺寸与图标缩放都由变量驱动
   ----------------------------------------------------------------------
   --tbtn-w / --tbtn-h   按钮外框尺寸
   --ico-scale           图标缩放系数（1 = 设计尺寸）

   图标本身是 SVG（见 index.html 顶部的 <defs> 精灵表），尺寸由
   `.mp-ico--xxx` 上的 --ico-size 固定声明；这里再用 --ico-scale 统一
   乘一个系数，好处是：

     1. 九个图标天然共享同一套缩放口径 → 视觉重量一致；
     2. 窄视口只改 --ico-scale 一个数字，所有图标**等比**缩放，
        不必为每个图标单独写媒体查询；
     3. 缩放不改变 viewBox 比例，也不改变居中方式 —— 图标永远在
        容器中心，只变大小。

   尺寸推导（27×22 的按钮，content 区 25×20）：
     最大图标 17px（双三角），上下各留 2.5px、左右各留 4px
     单三角 14px，明显小于双三角，主次分明
   ---------------------------------------------------------------------- */
.mp-tbtn {
  --tbtn-w: 27px;
  --tbtn-h: 22px;
  --ico-scale: 1;
  flex: none;
  width: var(--tbtn-w);
  height: var(--tbtn-h);
  margin: 0;
  padding: 0;
  background: var(--face);
  border: 1px solid;
  border-color: var(--light) var(--dark) var(--dark) var(--light);
  box-shadow: inset 1px 1px 0 var(--hilight), inset -1px -1px 0 var(--shadow);
  position: relative;
  cursor: default;
}
.mp-tbtn:active,
.mp-tbtn.is-pressed {
  border-color: var(--dark) var(--light) var(--light) var(--dark);
  box-shadow: inset 1px 1px 0 var(--shadow);
}
.mp-tbtn:focus {
  outline: 1px dotted #000000;
  outline-offset: -4px;
}
/* 激活态（循环 / 静音）：按钮保持「按下」外观 */
.mp-tbtn.is-on {
  border-color: var(--dark) var(--light) var(--light) var(--dark);
  box-shadow: inset 1px 1px 0 var(--shadow);
  background: #d4d0c8;
}
.mp-pad__sep {
  flex: none;
  width: 1px;
  height: 18px;
  /* 左右对称：分隔符与两侧按钮各留 5px，视觉上比按钮间距(3px)略宽，成组感更清晰 */
  margin: 0 5px;
  background: var(--shadow);
  box-shadow: 1px 0 0 var(--hilight);
}

/* ---------- 图标（SVG 矢量） ----------

   为什么用 SVG 而不是 border 三角形：
     border 三角形是「拿边框伪装成图形」的 hack —— 元素 border box 与可见墨迹
     不重合，多部件字形必须手推 --gx / --gw 才能居中，且 sub-pixel 取整会随
     容器尺寸漂移（旧版 ⏭ 因此被按钮右缘裁切、⏏ 整体右偏 5px）。
     SVG 有确定的 viewBox，`preserveAspectRatio` 默认为等比缩放，容器宽高
     怎么变都严格居中、比例恒定。图标定义集中在 index.html 顶部
     `<svg class="mp-sprite">` 的 <defs> 里，此处只负责「落位与缩放」。

   ── 居中原理 ──────────────────────────────────────────────────────────
   居中**不靠 CSS 偏移**，而是由图形自身的坐标系保证：
     · 所有图标共用 viewBox="0 0 24 24"，几何中心落在 (12,12)；
     · 每个 symbol 的图元画在以 (12,12) 为心的对称范围内；
     · 容器用「绝对定位 + 四边归零 + margin:auto」把 SVG 盒子居中。
   于是无论容器宽高如何变化，图形中心恒与容器中心重合，不存在需要手工
   补偿的偏移量 —— 从根上消掉了「偏移」这一整类缺陷。

   ── 缩放原理 ──────────────────────────────────────────────────────────
   图标尺寸由 --ico-size 驱动（默认 16px）。SVG 同时给 width/height 与
   viewBox，浏览器按 viewBox 等比映射，因此：
     · 改 --ico-size 只改大小，不改比例；
     · 容器收窄时无需改任何图标规则，它是固定尺寸的、天然居中，
       不会像百分比尺寸那样受容器宽高比影响而变形。

   尺寸自适应：`.mp-tbtn` 上的 --tbtn-w / --tbtn-h / --ico-size 三者
   协同即可，窄视口只改这几个变量，所有图标同步等比缩放。
   ─────────────────────────────────────────────────────────────────── */

/* 精灵表本身不参与布局（已在 HTML 内联兜底，此处再加一道保险） */
.mp-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

/* 图标基础落位：绝对定位 + 四边归零 + margin:auto = 严格居中。
   尺寸 = --ico-size（各图标的设计尺寸）× --ico-scale（容器给的缩放系数）。
   用 calc 相乘而不是改 width/height 常量，是为了让窄视口只调一个系数
   就能等比缩放全部图标。 */
.mp-ico {
  display: block;
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  margin: auto;
  width: calc(var(--ico-size) * var(--ico-scale, 1));
  height: calc(var(--ico-size) * var(--ico-scale, 1));
  fill: currentColor;
  color: #000000;
  pointer-events: none;
}

/* 播放按钮的 ▶ / ⏸ 切换：只换 <use> 的引用，不改盒子尺寸，
   因此切换时图标中心不动、不跳动。 */
.mp-ico--play  { --ico-size: 14px; }
.mp-ico--stop  { --ico-size: 13px; }
.mp-ico--pause { --ico-size: 14px; }

/* 复合箭头字形按视觉重量微调尺寸，保证九个图标「看起来一样大」。
   这是设计意图上的光学补偿，不是几何偏移 —— 中心始终在容器中心。 */
.mp-ico--first { --ico-size: 16px; }
.mp-ico--prev  { --ico-size: 17px; }
.mp-ico--fwd   { --ico-size: 17px; }
.mp-ico--last  { --ico-size: 16px; }
.mp-ico--eject { --ico-size: 16px; }
.mp-ico--loop  { --ico-size: 15px; }
.mp-ico--vol   { --ico-size: 16px; }

/* ==========================================================================
   ③ 面板：音量 / 播放列表（由工具栏开关切换显示）
   ========================================================================== */
.mp-panel {
  margin-top: 9px;
  padding: 6px 7px 7px;
  background: var(--face);
  border: 1px solid;
  border-color: var(--light) var(--dark) var(--dark) var(--light);
  box-shadow: inset 1px 1px 0 var(--hilight), inset -1px -1px 0 var(--shadow);
}
.mp-panel[hidden] { display: none; }
.mp-panel__title {
  font: bold 11px/1 var(--font);
  color: var(--text);
  margin-bottom: 6px;
}

/* 音量行 */
.mp-vol { display: flex; align-items: center; }
.mp-vol__mute {
  flex: none;
  width: 24px;
  height: 20px;
  margin-right: 7px;
  padding: 0;
  background: var(--face);
  border: 1px solid;
  border-color: var(--light) var(--dark) var(--dark) var(--light);
  box-shadow: inset 1px 1px 0 var(--hilight), inset -1px -1px 0 var(--shadow);
  position: relative;
  cursor: default;
}
.mp-vol__mute.is-on {
  border-color: var(--dark) var(--light) var(--light) var(--dark);
  box-shadow: inset 1px 1px 0 var(--shadow);
}
.mp-vol__slot {
  position: relative;
  flex: 1 1 auto;
  min-width: 0;
  height: 20px;
  background: #ffffff;
  border: 1px solid;
  border-color: var(--dark) var(--light) var(--light) var(--dark);
  box-shadow: inset 1px 1px 0 var(--shadow);
  cursor: pointer;
}
.mp-vol__bar {
  position: absolute;
  left: 1px;
  top: 1px;
  bottom: 1px;
  width: 80%;
  background: linear-gradient(180deg, #000080 0%, #1084d0 55%, #000080 100%);
  pointer-events: none;
}
/* 音量的旋钮与进度条旋钮共用同一套几何（见 ① 主刻度条处的说明） */

/* 音量面板的静音按钮：图标同为 SVG */
.mp-vol__mute > .mp-ico { --ico-size: 16px; }
.mp-vol__slot:focus { outline: 1px dotted #000000; outline-offset: -3px; }
.mp-vol__num {
  flex: none;
  width: 42px;
  margin-left: 7px;
  font: 10px/1 var(--mono);
  color: var(--text);
  text-align: right;
}

/* 播放列表 */
.mp-list {
  list-style: none;
  margin: 0;
  padding: 0;
  max-height: 92px;
  overflow: auto;
  background: #ffffff;
  border: 1px solid;
  border-color: var(--dark) var(--light) var(--light) var(--dark);
  box-shadow: inset 1px 1px 0 var(--shadow);
}
.mp-list__item {
  display: flex;
  align-items: center;
  padding: 3px 6px;
  font: 11px/1.3 var(--font);
  color: var(--text);
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
}
.mp-list__item + .mp-list__item { border-top: 1px solid #e4e0dc; }
.mp-list__item.is-current {
  background: #000080;
  color: #ffffff;
}
.mp-list__idx {
  flex: none;
  width: 20px;
  color: inherit;
  opacity: .75;
}
.mp-list__name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
.mp-list__dur {
  flex: none;
  margin-left: 8px;
  font-family: var(--mono);
  font-size: 10px;
  opacity: .8;
}

/* 工具栏开关的「已开启」态 */
.window--mp .tb-btn.is-on {
  border-color: var(--dark) var(--light) var(--light) var(--dark);
  box-shadow: inset 1px 1px 0 var(--shadow);
  background: #d4d0c8;
}

/* 播放中：读数与状态灯 */
.window--mp.is-playing .mp-readout__elapsed { color: #000080; }

/* ---------- 窄屏适配 ---------- */
@media (max-width: 480px) {
  .window--mp { --window-w: 100%; }
  .mp-workspace { height: 226px; }
  /* 按钮与图标一起收窄：改 --ico-scale 一个系数，所有图标**等比**缩小，
     彼此比例关系不变，居中方式也不变（仍是容器中心）。 */
  .mp-tbtn {
    --tbtn-w: 25px;
    --tbtn-h: 21px;
    --ico-scale: 0.9;
  }
  .mp-spin > .mp-ico { --ico-size: 8px; }
  .mp-readout__track { display: none; }
}
@media (max-height: 520px) {
  .mp-workspace { height: 196px; }
}

/* ==========================================================================
   16. 滚动条（渐进增强）
   --------------------------------------------------------------------------
   EdgeHTML 18 不支持自定义滚动条，回退为系统原生样式；
   Chromium Edge / Chrome / Safari 走 ::-webkit-scrollbar，
   Firefox 走 scrollbar-color。
   ========================================================================== */
.workspace,
.md-pane-scroll,
.np-editor,
.np-pane--preview,
.md pre,
.md .md-tablewrap {
  scrollbar-color: var(--face) #f0f0f0;
  scrollbar-width: thin;
}
.workspace::-webkit-scrollbar,
.np-editor::-webkit-scrollbar,
.np-pane--preview::-webkit-scrollbar { width: 16px; height: 16px; }
.workspace::-webkit-scrollbar-track,
.np-editor::-webkit-scrollbar-track,
.np-pane--preview::-webkit-scrollbar-track {
  background: #f0f0f0;
  background-image: repeating-conic-gradient(#ffffff 0 25%, #dfdfdf 0 50%);
  background-size: 4px 4px;
}
.workspace::-webkit-scrollbar-thumb,
.np-editor::-webkit-scrollbar-thumb,
.np-pane--preview::-webkit-scrollbar-thumb {
  background: var(--face);
  border: 1px solid;
  border-color: var(--hilight) var(--dark) var(--dark) var(--hilight);
  box-shadow: inset 1px 1px 0 var(--light), inset -1px -1px 0 var(--shadow);
}
.workspace::-webkit-scrollbar-thumb:hover,
.np-editor::-webkit-scrollbar-thumb:hover,
.np-pane--preview::-webkit-scrollbar-thumb:hover { background: #cacaca; }
.workspace::-webkit-scrollbar-button,
.np-editor::-webkit-scrollbar-button,
.np-pane--preview::-webkit-scrollbar-button {
  display: block;
  height: 16px;
  background: var(--face);
  border: 1px solid;
  border-color: var(--hilight) var(--dark) var(--dark) var(--hilight);
}

/* ==========================================================================
   17. 响应式（Grid 重排 + 移动端适配）
   ========================================================================== */

/* --- 桌面图标让位 --- */
@media (max-width: 1180px) {
  /* 窄屏隐藏桌面图标，避免与居中窗口重叠 */
  .desk-icons { display: none; }
}

/* --- 平板 / 小笔记本 --- */
@media (max-width: 1060px) {
  .window { width: 100%; margin-left: 0; margin-right: 0; }
  .ws-inner { grid-template-columns: minmax(0, 1fr); }
  .col-side { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  /* 记事本并排模式在窄屏下改为上下两行，避免每栏过窄无法阅读 */
  .np-split.is-split { grid-template-columns: minmax(0, 1fr); }
  .np-split.is-split .np-pane + .np-pane {
    border-left: 0;
    border-top: 1px solid var(--shadow);
  }
  .np-split.is-split .np-pane { height: 50%; }
  .np-split.is-split .np-pane--source { min-height: 140px; }
}

/* --- 手机 --- */
@media (max-width: 720px) {
  :root {
    /* 收窄任务栏与窗口边距，为内容让出横向空间 */
    --taskbar-h: 30px;
  }

  .col-side { grid-template-columns: minmax(0, 1fr); }
  .video { grid-template-columns: minmax(0, 1fr); }
  .video__thumb { width: 100%; height: 158px; }
  .video__thumb img,
  .video__thumb .thumb-ph { width: 100%; height: 154px; }
  .stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .addrbar__field { display: none; }
  .taskbar__tasks { flex: 1 1 auto; }
  .statusbar__pane--hide-sm { display: none; }

  /* 窗口：减小上下留白，贴近移动端全宽阅读 */
  .window { margin: 10px auto; }
  .window--np { margin: 12px auto 10px; }

  /* 工作区高度改为随视口自适应，避免固定高度在小屏上过高/过矮 */
  .workspace,
  .np-workspace {
    height: auto;
    max-height: none;
    min-height: 300px;
  }
  /* 播放器舞台在窄屏下自动收缩（刻度条 + 读数 + 按钮排约需 150px） */
  .mp-workspace {
    height: auto;
    max-height: none;
    min-height: 158px;
  }
  /* 记事本工作区必须有【有界高度】：若沿用 height:auto，工作区会随 Markdown
     内容无限撑高（实测 390px 视口下长到 2325px），内部预览/编辑面板因此
     永远不产生溢出（scrollHeight === clientHeight），滚动容器形同虚设；
     同时超高窗口会被外层 .desktop 的 overflow:hidden 裁掉，内容彻底不可达。
     这里以视口为基准给出上限，把「滚动」交还给内部面板（.np-pane--preview /
     .np-editor），这才是可触摸滚动、带惯性的真正滚动容器。

     两条 height 是**有意为之的渐进增强**（声明级回退，非笔误）：
       ① 先给 vh 版本 —— 所有浏览器都能解析，是安全基线；
       ② 再给 dvh 版本 —— 支持的浏览器（Chromium 108+ / Safari 15.4+）覆盖它，
          移动端地址栏收放时不会跳变；不支持者整条丢弃，自动退回 ①。
     注意横屏矮视口（如 844x390）会被后面的 @media (max-height:520px) 接管，
     那条规则在源序上更靠后、优先级更高，是本文件既有的既定行为。 */
  .np-workspace {
    height: calc(100vh - 190px);
    /* 上下界同时给：矮视口不塌陷，高视口不无限拉伸 */
    min-height: 220px;
    height: calc(100dvh - 190px);
  }
  /* 最大化时仍由弹性填充接管，不覆写高度（否则小屏会出现缺口） */
  .window--np.is-maxed > .np-workspace {
    height: auto;
    min-height: 0;
  }
  /* 最大化时不再覆写高度：弹性填充由基础规则负责，且 min-height 必须归零，
     否则小屏下 min-height:300px 会顶开容器、重新制造缺口。 */
  .window.is-maxed > .workspace,
  .window--np.is-maxed > .np-workspace,
  .window--mp.is-maxed > .mp-workspace {
    min-height: 0;
    height: auto;
  }

  /* 记事本：工具栏允许换行，行号槽收窄，代码块横向滚动 */
  .np-lineno { width: 26px; padding: 6px 4px 6px 0; font-size: 11px; }
  .np-editor  { padding: 6px 8px; font-size: 12px; }
  .np-pane--preview { padding: 8px; }
  .md { font-size: 13.5px; }
  .md h1 { font-size: 19px; }
  .md h2 { font-size: 16.5px; }
  .md h3 { font-size: 15px; }
  .md pre { padding: 20px 8px 8px; }
  .md pre code { font-size: 11.5px; }
  .md table { font-size: 11.5px; }
  .md th, .md td { padding: 3px 6px; }

  /* 标题栏按钮在触屏下增大点击热区 */
  .title-btn { width: 20px; height: 16px; }
  .title-bar { height: 22px; }

  /* 任务栏按钮更紧凑，保证两个窗口按钮都能显示 */
  .task-btn { flex: 0 1 140px; padding: 0 6px; font-size: 11px; }
  .start-btn { padding: 0 5px; }
  .tray__icons { display: none; }
}

/* --- 超窄屏（竖屏手机） --- */
@media (max-width: 420px) {
  .window { margin: 6px auto; }
  .window--np { margin: 8px auto 6px; }

  /* 标题栏文字过长时优先让位给按钮 */
  .title-bar__text { font-size: 11px; }

  /* 工具栏横向滚动而非换行，保持单行高度可预期 */
  .toolbar { overflow-x: auto; }
  .tb-btn { flex: none; }

  /* 状态栏只保留关键格 */
  .statusbar__pane--right { display: none; }

  /* 记事本并排模式下源码面板进一步压低 */
  .np-split.is-split .np-pane--source { min-height: 110px; }

  /* Markdown 内边距收紧 */
  .md ul, .md ol { padding-left: 20px; }
  .md h1 { font-size: 17.5px; }
}

/* --- 横屏矮视口：非最大化时限制工作区高度，避免窗口超出屏幕 ---
   最大化状态不在此处覆写：它由 flex 弹性填充 + 100vh 基准处理，
   在这里再写 min-height 反而会把容器顶开、重新产生缺口。 */
@media (max-height: 520px) {
  .workspace,
  .np-workspace {
    height: calc(100vh - 170px);
    min-height: 180px;
    max-height: none;
  }
  /* 播放器舞台在矮视口下给一个更小的下限（面板可滚动，不强行撑高） */
  .mp-workspace {
    height: auto;
    min-height: 150px;
    max-height: none;
  }
  .window.is-maxed > .workspace,
  .window--np.is-maxed > .np-workspace {
    height: auto;
    min-height: 0;
  }
  .window--mp.is-maxed > .mp-workspace {
    height: auto;
    min-height: 0;
  }
  /* 极矮视口下压缩最大化窗口自身的最小高度，避免内容被裁切 */
  .window.is-maxed { min-height: 220px; }
}

/* ==========================================================================
   18. 打印
   ========================================================================== */
@media print {
  .desk-icons, .taskbar, .startmenu, .toast,
  .toolbar, .addrbar { display: none !important; }
  .window {
    width: 100%;
    border: 0;
    box-shadow: none;
  }
  .workspace,
  .np-workspace {
    height: auto;
    max-height: none;
    overflow: visible;
  }
  /* 打印时始终以渲染视图输出，忽略源码面板 */
  .np-pane--source { display: none !important; }
}
