/* ==========================================================================
   ★★★ **登录页的黑白漫画风**（2026-10-06 用户要求）
   ==========================================================================
   用户原话：
   > 把登录界面换成黑白漫画风格

   ## 🚨 为什么单独开一个文件（而不是写进 `manga.css`）

   ```
   · `manga.css` 已经 800 行、而且里面全是"聊天/主页/通讯录"那些屏的覆盖
   · 这一块是【登录页专属】—— 单独一个文件 ⇒ 想回退就把 <link> 删掉，
     一行不用改（用户明确说过"现在的可以留一套，如果效果不行就回退"）
   ```

   ## 🚨🚨 真正的根因不是"样式没写"，是**登录页压根没进漫画主题**

   ⚠️ 我一开始以为"给登录页补样式"就行了 —— 查完发现更根本的问题：
   ```js
   // 修之前：applyUiStyle() 只在 refreshIdentity() 里调
   boot() → 本地有口令 ? enterChat() + refreshIdentity()
                       : showLogin()          ← 没登录时永远走这条
   ```
   ⇒ **`applyUiStyle()` 从来没被调用过** ⇒ `<html>` 上没有 `data-ui="manga"`
   ⇒ `manga.css` 里那几十条规则**一条都不匹配**（它们全挂在
   `html[data-ui='manga']` 下面）= 用户看到的就是极简那套。

   ✅ 已修：`boot()` 第一件事就是 `applyUiStyle('')`（在 `render()` 之前，
      不然会**闪一下旧样式**）。

   ## 漫画风的"语法"（照着 `manga.css` 那套来，别自己发明）

   ```
   · 三色：墨 #12151a / 纸 #ffffff / 蓝 #2f4f7f（变量在 manga.css 的 :root）
   · 边框：**3px 整数**实线墨色（⚠️ 别写 2.5px —— Chromium 会算成 2px）
   · 阴影：**硬投影** `4px 4px 0 rgba(18,21,26,.9)`（不是柔和模糊）
   · 圆角：大而硬（18px 那种）
   · 不要"柔和渐变"和"内外双阴影"（那是拟物那套的语法）
   ```

   ⚠️ 所以下面**每一条都要压过 `app.css` 的拟物样式**（`box-shadow: var(--sh-out)`
   那种）。登录页的元素都是单类名，所以 `html[data-ui='manga'] .xxx`（0,2,1）
   一定赢过 `.xxx`（0,1,0）—— **不需要 `!important`**。
   ========================================================================== */

/* ---------------------------------------------------------------- 整页底色 */
/**
 * ⚠️ **只写 `background-color`，不碰 `background-image`**。
 *    （`manga.css` 那边为这个坑写了一大段 —— `background` 简写会把
 *      用户设的那张屏幕背景图一起重置成 `none`，然后"背景看不见"。）
 */
/**
 * 🚨 **这里原来是 `.screen-login` —— 不存在的类**（2026-10-06 抓到）。
 *
 * ```html
 * <section id="screen-login" class="screen" aria-label="登录">
 * ```
 * ⚠️ **id 是 `screen-login`、class 只有 `screen`** ⇒ `.screen-login` **匹配不到东西**。
 * ⚠️ 这个项目所有屏都是 `<section id="screen-xxx" class="screen">` 这一条规矩 ⇒
 *    写选择器**用 `#screen-xxx`**（id），别写成 `.screen-xxx`（class）。
 * ⚠️ 这种错**不报错** —— 表现只是"样式没生效"，而代码读起来完全正常。
 */
html[data-ui='manga'] #screen-login,
html[data-ui='manga'] .login-wrap {
  color: var(--manga-ink);
}
html[data-ui='manga'] #screen-login {
  background-color: var(--manga-paper);
}

/* ==========================================================================
   ★★★ **登录页的黑白漫画背景图**（2026-10-06 用户要求）
   ==========================================================================
   用户原话：
   > 这个换成登录界面背景，调好尺寸

   ## ⚠️ 为什么用 `<img>` 不用 `background-image`
   和聊天背景那次踩的坑一个道理（`app.css` 里 `applyBg` 那段）：
   `background-attachment: fixed` + `cover` 在实机上会**因为视口伸缩算错缩放比**，
   而 `<img>` + `object-fit: cover` 行为确定。

   ## ★★ `object-position` 是**按屏幕分的**（这是"调好尺寸"的关键）
   ```
   手机 414×896（比例 0.46）→ 图（0.58）比屏幕【更宽】
                              ⇒ 只裁掉左右一点 ⇒ **顶部对齐**（三格都能看到）
   桌面 1440×900（比例 1.6）→ 图比屏幕【更瘦】
                              ⇒ 上下裁掉【约 64%】⇒ **居中对齐**
                                 （顶部对齐会裁掉人物下半身，看着像"半张脸"）
   ```
   ⚠️ 这两条是**真在浏览器里分别截图看过**才定的（`tools/probe-bg-fit.mjs`），
      不是凭想象 —— 桌面选错就是"一片空白或者半张脸"（那个脚本存了 10 张对照图）。
   ========================================================================== */
html[data-ui='manga'] .login-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  /** ⚠️ `cover` 保证铺满；`object-position` 决定裁哪一边 */
  object-fit: cover;
  object-position: center top;
  /** ⚠️ 别让它被选中/拖动（它是背景，不是内容） */
  user-select: none;
  -webkit-user-drag: none;
  pointer-events: none;
  z-index: 0;
}
/**
 * ⚠️ **宽屏改成居中**（见上面那段的分屏理由）。
 *    断点 900px 是"从竖屏切到横屏"那个感觉的分界 ——
 *    比它窄的一律按手机处理（顶部对齐）。
 */
@media (min-width: 900px) {
  html[data-ui='manga'] .login-bg {
    object-position: center center;
  }
}

/**
 * ★★ **表单底下垫一层"柔光"** —— 让字看得清。
 *
 * ## ⚠️ 为什么必须有
 *
 * 背景是**黑白高对比的漫画**（大片纯白 + 硬黑线）—— 表单直接压上去时：
 * ```
 * · 输入框是白底 + 墨框 ⇒ 白底落在白底上、**框线落在黑线上** ⇒ 边界糊掉
 * · 而"用户名/密码"那些占位符是浅灰的 ⇒ 压在黑线上**根本看不见**
 * ```
 * ⇒ 垫一层**中心白、四周透明**的径向渐变：
 *   中间那块（表单所在）足够实，能读；四周还看得见漫画。
 *
 * ⚠️ **不能用纯色蒙层** —— 那等于"把背景盖掉"，用户要的就是能看到漫画。
 *
 * ## 🚨 为什么是 `#login-veil`（真元素）而不是 `.screen-login::after`
 *
 * ⚠️ 我第一版用伪元素写的 —— 规则在样式表里、选择器也对，
 *    但 `getComputedStyle(el, '::after')` **一直报 `content: none`**，
 *    也就是说**我没有任何可靠办法确认它到底生效没有**。
 *    ⇒ 换成真元素之后：`getComputedStyle(veil)` 直接读得到，
 *      验收脚本能把它钉死（`tools/probe-login-bg.mjs` 第 ④ 条）。
 * ⚠️ 教训：**能用真元素就别用伪元素** —— 伪元素的样式在自动化里很难验。
 */
html[data-ui='manga'] .login-veil {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 1;
  background: radial-gradient(
    72% 58% at 50% 46%,
    rgba(255, 255, 255, 0.94) 0%,
    rgba(255, 255, 255, 0.88) 44%,
    rgba(255, 255, 255, 0.38) 74%,
    rgba(255, 255, 255, 0) 100%
  );
}
/** ⚠️ 表单本身要**压在两层之上**（背景图 z0 → 柔光 z1 → 表单 z2） */
/**
 * 🚨🚨 **这里原来写的是 `.screen-login` —— 那是【不存在的类】**（2026-10-06 抓到的）。
 *
 * ## 出了什么事
 *
 * ```html
 * <section id="screen-login" class="screen" aria-label="登录">
 * ```
 * ⚠️ 它有的是 **id `screen-login`**，**class 是 `screen`** ——
 *    **没有 `screen-login` 这个类**。所以我写的 `.screen-login` **匹配不到任何元素**。
 *
 * ## 代价：查了好几轮
 * ```
 * · 规则在样式表里（CSSOM 读得到、字符码也对）
 * · 选择器"看起来"和上面那条一模一样
 * · getComputedStyle 却永远是 static / auto
 * ⇒ 最后靠 `el.matches()` 一行问出来：`.screen-login .login-wrap` → false
 * ```
 * ⚠️ **教训**：`#xxx` 是 **id**、`.xxx` 是 **class** —— 这个项目的屏都是
 *    `<section id="screen-xxx" class="screen">` 这种**一条规矩**，
 *    写选择器时**先看一眼那个元素上到底有什么**，别照名字猜。
 * ⚠️ 而且这种错**不报错、不警告**：`manga.css` 里也因此踩过一次
 *    （那边有一段注释写着"选择器写错、从来没生效过"）。
 */
html[data-ui='manga'] #screen-login .login-wrap {
  position: relative;
  z-index: 2;
}

/**
 * ★★ **漫画的"网点"底纹**（halftone）—— 黑白漫画最标志性的质感。
 *
 * ⚠️ 用 `radial-gradient` 画点阵，**不用图片**（省一个请求，任何缩放都清晰）。
 * ⚠️ 点要**很淡**：它是**纸的质感**，不是图案（浓了会把输入框衬得看不清）。
 *
 * ## 🚨 两个坑都在这条上踩过（2026-10-06）
 * ```
 * ① 原来写的是 `.screen-login::before` ⇒ **从来没生效过**
 *    （那个元素只有 id `screen-login`，class 是 `screen`）
 * ② 我一度想改用 `.screen-login::after` —— 但**伪元素的样式在自动化里验不了**
 *    （`getComputedStyle(el, '::after')` 读不准，我为此白查了一轮）
 * ```
 * ✅ 所以最终是**真元素** `#login-paper`（`getComputedStyle` 直接读得到、
 *    验收脚本能钉死它）。
 */
html[data-ui='manga'] #login-paper {
  /** ⚠️ `content` 是给伪元素用的，真元素上用不着（留着无害，但容易让人以为是伪元素） */
  position: absolute;
  inset: 0;
  pointer-events: none;
  /** ⚠️ 它贴在背景图之上、柔光之下 ⇒ z-index 用 0（柔光是 1、表单是 2） */
  z-index: 0;
  background-image: radial-gradient(rgba(18, 21, 26, 0.14) 1px, transparent 1.2px);
  background-size: 7px 7px;
  /** ⚠️ 中间淡、四周浓一点 —— 让视线落在中间那块表单上 */
  mask-image: radial-gradient(120% 80% at 50% 42%, transparent 30%, #000 100%);
  -webkit-mask-image: radial-gradient(120% 80% at 50% 42%, transparent 30%, #000 100%);
}

/* ---------------------------------------------------------------- logo 方块 */
/**
 * ★ logo 那块：拟物是"凸起的软方块"，漫画改成**贴纸**（墨色描边 + 硬投影）。
 * ⚠️ `logo-kin.png` 本身是**白底 JPEG 裁的**（没有透明通道）——
 *    所以里面那层 `.brand-mark` 的白底要留着（不然会透出纸纹，看着脏）。
 */
html[data-ui='manga'] .brand {
  background: var(--manga-paper);
  border: 3px solid var(--manga-ink);
  border-radius: 20px;
  box-shadow: 5px 5px 0 rgba(18, 21, 26, 0.9);
}
html[data-ui='manga'] .brand-mark {
  /** ⚠️ 里面这层不要再描边了（双重边很难看）——只留白底 */
  border-radius: 14px;
  background: #fff;
}

/* ---------------------------------------------------------------- 标题 */
/**
 * ★ 标题 `Kin`：漫画的标题要**重、要压得住**。
 * ⚠️ 拟物那套是细体大字（`font-weight: 200` 那种）—— 在漫画风里会"飘"。
 * ⚠️ 硬投影用 `text-shadow` 的**实心偏移**（不是模糊光晕）。
 */
html[data-ui='manga'] .login-title {
  font-weight: 800;
  letter-spacing: 0.06em;
  color: var(--manga-ink);
  text-shadow: 3px 3px 0 rgba(18, 21, 26, 0.16);
}
html[data-ui='manga'] .login-sub {
  /**
   * ⚠️ **副标题要能压在漫画上看清**（2026-10-06 看截图发现的）。
   *
   * 它在柔光的边缘（那块不够白），底下是漫画的黑线/网点 ⇒
   * 原来的灰字**糊在背景里**。
   * ✅ 用 `text-shadow` 做一圈**白描边**（四个方向各一圈，再加一层模糊的）——
   *    这是"文字压在图上"最省事也最稳的做法（不改字号、不改版式）。
   */
  color: #3a3f47;
  font-weight: 700;
  text-shadow:
    0 1px 0 #fff, 0 -1px 0 #fff, 1px 0 0 #fff, -1px 0 0 #fff,
    0 0 6px rgba(255, 255, 255, 0.95), 0 0 12px rgba(255, 255, 255, 0.9);
}
/**
 * ⚠️ 页脚（最底下那条）也加白描边 —— 它底下正好是第三格漫画。
 *    ⚠️ 这条**只留一份**（文件末尾那份已经删了）——
 *      同特异性时后写的赢，留两份的话改一处会"看起来没生效"。
 */
html[data-ui='manga'] .login-foot {
  color: #4a4f57;
  font-weight: 600;
  text-shadow: 0 1px 0 #fff, 0 -1px 0 #fff, 1px 0 0 #fff, -1px 0 0 #fff;
}

/* ---------------------------------------------------------------- 输入框 */
/**
 * ★★ 输入框：漫画里"填格"就是**白底 + 墨框**（框内写字的格子）。
 * ⚠️ 一定要**盖掉拟物的那两层 `inset` 阴影** —— 不然"凹进去的软胶"和
 *    "硬描边的格子"会同时出现（那是两套语法混在一起，用户第 54 轮就骂过这个）。
 */
html[data-ui='manga'] .field {
  background: var(--manga-paper);
  color: var(--manga-ink);
  border: 3px solid var(--manga-ink);
  border-radius: 14px;
  box-shadow: 3px 3px 0 rgba(18, 21, 26, 0.85);
  font-weight: 500;
}
html[data-ui='manga'] .field::placeholder {
  color: #8b9099;
  font-weight: 400;
}
/** 聚焦：只**加粗投影**（漫画里"点到了"就是这一下），不换颜色 */
html[data-ui='manga'] .field:focus {
  box-shadow: 5px 5px 0 rgba(18, 21, 26, 0.95);
  outline: none;
}

/* ---------------------------------------------------------------- 进门的圆按钮 */
/**
 * ★ 那个圆形箭头钮：漫画里是**实心墨块 + 白箭头**（对比最强、最像分镜里的按钮）。
 */
html[data-ui='manga'] .round-btn {
  background: var(--manga-ink);
  color: var(--manga-paper);
  border: 3px solid var(--manga-ink);
  box-shadow: 4px 4px 0 rgba(18, 21, 26, 0.45);
}
html[data-ui='manga'] .round-btn:active {
  /** ⚠️ 按下去**投影收掉**（"压进纸里"）——比缩放更符合漫画质感 */
  box-shadow: 0 0 0 rgba(18, 21, 26, 0.45);
  transform: translate(2px, 2px);
}

/* ---------------------------------------------------------------- 发验证码那两行的小按钮 */
html[data-ui='manga'] .login-code-btn {
  background: var(--manga-paper);
  color: var(--manga-ink);
  border: 3px solid var(--manga-ink);
  border-radius: 12px;
  box-shadow: 3px 3px 0 rgba(18, 21, 26, 0.85);
  font-weight: 700;
}
html[data-ui='manga'] .login-code-btn:disabled {
  /** ⚠️ 禁用要**明确变淡**（不然用户以为能点） */
  opacity: 0.45;
  box-shadow: none;
}

/* ---------------------------------------------------------------- 切换那两行文字 */
html[data-ui='manga'] .login-link {
  color: var(--manga-ink);
  font-weight: 700;
  /** ⚠️ 漫画的"可点"靠**粗下划线**，不靠颜色 */
  text-decoration-thickness: 2px;
  text-underline-offset: 4px;
}
html[data-ui='manga'] .login-link:active {
  background: var(--manga-ink);
  color: var(--manga-paper);
  text-decoration-color: transparent;
}

/* ---------------------------------------------------------------- 提示 / 错误 / 页脚 */
html[data-ui='manga'] .login-code-hint {
  color: #4a4f57;
  font-weight: 500;
}
html[data-ui='manga'] .login-code-hint.is-ok {
  /** ⚠️ 成功/失败仍然要有颜色（那是**语义**，不是风格）——
   *    但在漫画风里要**更深、更实**，不要淡彩 */
  color: #1c6b3f;
  font-weight: 700;
}
html[data-ui='manga'] .login-code-hint.is-bad {
  color: #a11f1a;
  font-weight: 700;
}
/**
 * ★ 错误条：漫画里的"警告框"是**墨框 + 纸底 + 硬投影**。
 * ⚠️ `.login-error:on::before` 那个 `!` 前缀（拟物那套）在漫画里多余，
 *    但**留着也不冲突**（它是伪元素，不改盒子）—— 所以不动它。
 */
html[data-ui='manga'] .login-error.is-on {
  background: var(--manga-paper);
  color: #a11f1a;
  border: 3px solid var(--manga-ink);
  border-radius: 14px;
  box-shadow: 3px 3px 0 rgba(18, 21, 26, 0.85);
  font-weight: 600;
}
