/*
 * 阅读器的样式。**两个进程共用同一份**：
 *   · 后台的预览（`/preview/`，reader/index.html）
 *   · 公开前台的阅读页（`modules/epaper/src/reader/`，SSR 外壳 <link> 它）
 *
 * 2026-09-12 从 `index.html` 的 `<style>` 里抽出来，一个字节都没改。
 * 抽它的理由不是整洁：公开前台要 SSR 出自己的外壳（要 og: 标签、要三语、
 * 要地区面包屑），而外壳里再拷一份阅读器 CSS 就意味着**改一处坏另一处**，
 * 而且坏法是静默的 —— 比如 `.page.show-hot .hot` 与 `.hot.lit` 的优先级那条
 * （2026-09-04 那个"开着显示全部热区时 hover 一点反应都没有"的 bug），
 * 只会在被遗忘的那一份里复活。
 */
:root{
  --bg:#f4f4f2; --panel:#fff; --ink:#1a1a1a; --muted:#6b6b6b; --line:#dcdcd8;
  --accent:#8c1515; --hot:rgba(140,21,21,.10); --hot-on:rgba(140,21,21,.26);
  --hot-lead:rgba(140,21,21,.07); --hit:rgba(255,196,0,.42);
  --shadow:0 1px 3px rgba(0,0,0,.10),0 8px 24px rgba(0,0,0,.06);
}
@media (prefers-color-scheme:dark){:root:not([data-theme=light]){
  --bg:#141414; --panel:#1d1d1d; --ink:#e8e8e6; --muted:#9a9a96; --line:#333;
  --accent:#e07a7a; --hot:rgba(224,122,122,.12); --hot-on:rgba(224,122,122,.30);
  --hot-lead:rgba(224,122,122,.09); --hit:rgba(255,196,0,.34);
  --shadow:0 1px 3px rgba(0,0,0,.5);
}}
:root[data-theme=dark]{
  --bg:#141414; --panel:#1d1d1d; --ink:#e8e8e6; --muted:#9a9a96; --line:#333;
  --accent:#e07a7a; --hot:rgba(224,122,122,.12); --hot-on:rgba(224,122,122,.30);
  --hot-lead:rgba(224,122,122,.09); --hit:rgba(255,196,0,.34);
  --shadow:0 1px 3px rgba(0,0,0,.5);
}
*{box-sizing:border-box}
body{margin:0;background:var(--bg);color:var(--ink);
  font:16px/1.6 Georgia,"Songti SC","Noto Serif CJK SC",serif}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
a{color:var(--accent)}
.skip{position:absolute;left:-9999px}
.skip:focus{left:8px;top:8px;z-index:99;background:var(--panel);padding:8px 12px;box-shadow:var(--shadow)}

/* ★★ `flex-wrap:wrap` **不设断点**。
   2026-09-13 实测：390px 视口下整个文档被撑到 566px，横向能滑动 ——
   顶栏是 flex 但不换行，站名 + 搜索 + 字号 + 视图切换 + 三个语言键 + 主题键
   硬挤成一排。窄屏上"整页能左右滑"是最招人烦的一类毛病，而且它**不报错**。
   加断点只能挡住已知的那几个宽度；不换行这件事本身才是根因。 */
header{position:sticky;top:0;z-index:20;display:flex;gap:12px;align-items:center;
  flex-wrap:wrap;row-gap:8px;
  padding:10px 16px;background:var(--panel);border-bottom:1px solid var(--line)}
header h1{margin:0;font-size:17px;letter-spacing:.02em}
header .sp{flex:1}
header input{padding:7px 11px;border:1px solid var(--line);border-radius:6px;
  background:var(--bg);color:inherit;width:min(46vw,300px);font-size:14px}
.btn{padding:6px 11px;border:1px solid var(--line);border-radius:6px;font-size:14px}
.btn:hover{background:var(--bg)}
/* ★ `<a class="btn">` 要真的长得像按钮。`a{color:var(--accent)}` 与默认下划线
   会赢过 .btn（.btn 没管这两个属性），于是「整期 PDF」「本版」一直是**红色下划线文字**
   —— 有边框、但读起来是链接不是按钮。2026-09-04 从截图里看出来的。 */
a.btn{text-decoration:none;color:inherit;display:inline-block}
.btn[aria-pressed=true]{background:var(--accent);color:#fff;border-color:var(--accent)}

/* ── 期号列表 ── */
.grid{display:grid;gap:22px;padding:22px;
  grid-template-columns:repeat(auto-fill,minmax(168px,1fr))}
.card{background:var(--panel);box-shadow:var(--shadow);border-radius:3px;overflow:hidden;
  display:flex;flex-direction:column;text-align:left;transition:transform .12s}
.card:hover,.card:focus-visible{transform:translateY(-3px)}
.card img{width:100%;aspect-ratio:864/1548;object-fit:cover;background:var(--bg);display:block}
.card b{padding:9px 11px 2px;font-size:14px}
.card small{padding:0 11px 10px;color:var(--muted);font-size:12px}

/* ── 阅读器 ── */
.reader{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  height:calc(100dvh - 53px)}
.spread{position:relative;overflow:auto;padding:16px;background:var(--bg)}
/* background-size:100% 100% 是给 LQIP 的（缩略图垫底，等整版图到）——
   contain/cover 会让 17dpi 那张跑偏，而它与版面框是同一个比例 */
.page{position:relative;margin:0 auto;max-width:100%;box-shadow:var(--shadow);background:#fff;
  background-size:100% 100%;background-repeat:no-repeat}
/* 热区那一层：顶 role=grid，不挡版面上的点击 */
.hots{position:absolute;inset:0;pointer-events:none}
.hots .hot{pointer-events:auto}
/* 放大之后不要再被容器压回去 —— 由 JS 写 inline width / maxWidth */
.spread{scroll-behavior:auto}
.page img{width:100%;height:auto;display:block}
/* ── 热区 ──────────────────────────────────────────────────
   **默认不着色。** NYT TimesMachine（opacity 0）、PressReader（正文块隐形）、
   Twipe（空 div 只有 cursor:pointer）—— 三家全都默认不可见，
   没有一家把每个正文块都涂成色块。我们原来满版红色块是独一份。
   见 docs/research/epaper/05-reader-ux.md §1。 */
.hot{position:absolute;background:none;border:1px solid transparent;border-radius:2px;
  padding:0;transition:background .12s;overflow:hidden}
/* 热区的标题只给读屏软件，**不能画出来** —— 2026-08-11 实测：
   直接把标题当按钮文字，整版报纸会被几十行重复标题盖住，什么都看不见。
   用视觉隐藏而不是 display:none，后者读屏软件也读不到。 */
.sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}
/* 「显示全部热区」开关（PressReader 有同样的设置项）。默认关 */
.page.show-hot .hot{background:var(--hot);border-color:color-mix(in srgb,var(--accent) 35%,transparent)}
/* 触屏没有 hover，可发现性只能靠常驻着色 —— 但只给每篇最靠上的那个框，
   不是全部。整版涂色正是我们要改掉的那个样子 */
@media (hover:none){.hot[data-lead]{background:var(--hot-lead)}}
/* 搜索命中：直接打在版面图上。Veridian 的关键洞见 ——
   这**只需要词级坐标，不需要文章分栏**，所以没标注过的期也有。
   pointer-events:none，别挡住底下的热区 */
.wordhit{position:absolute;background:var(--hit);border-radius:1px;pointer-events:none;z-index:1}
/* ★ 交互态**必须排在上面两条之后、而且带 .page 前缀**。
   `.page.show-hot .hot` 是 (0,3,0)，光写 `.hot.lit` 只有 (0,2,0) ——
   开着「显示全部热区」时 hover 联动会被它压掉，一点反应都没有。
   （2026-09-04 从截图里看出来的：全部框一个色，指上去不变。）
   .lit = 同一篇的其它框跟着亮（Tecnavia：一篇的所有矩形同时高亮），
   否则读者只知道"这块能点"，不知道点开的是多大一篇。 */
.page .hot:hover,.page .hot:focus-visible,.page .hot.lit,
.page .hot[aria-current=true]{background:var(--hot-on);border-color:var(--accent);outline:none}

/* 正文字号跟着读者选的档走。报纸正文只有 8pt，字号不是加分项是必需品（§8 排第一） */
.article{overflow:auto;padding:26px clamp(18px,4vw,46px);background:var(--panel);
  border-left:1px solid var(--line);font-size:calc(1rem * var(--reader-fs,1))}
.fs{display:flex;gap:4px}
.fs .btn{padding:6px 9px;font-variant-numeric:tabular-nums}
.fs .btn:disabled{opacity:.45;cursor:not-allowed}
.article h2{font-size:clamp(21px,2.6vw,31px);line-height:1.22;margin:0 0 10px}
.article .by{color:var(--muted);font-size:14px;font-style:italic;margin:0 0 20px}
.article p{margin:0 0 1.05em;text-align:justify;hyphens:auto}
.article p.subhead{font-weight:700;font-style:normal;margin-top:1.5em;text-align:left}
.article p.pullquote{border-left:3px solid var(--accent);padding-left:14px;
  font-size:1.1em;font-style:italic;color:var(--muted);text-align:left}
.article figure{margin:1.4em 0}
/* 配图铺满正文栏。够不够清晰是**上游**的事（按 IDML 裁切框裁 Links 原图），
   显示层不为此牺牲版式 —— 缩小之后那一栏会东一块西一块。
   fitPhoto() 只挡一种：原生不到 400px 的图标/碎片，拉满是马赛克。 */
.article figure img{width:100%;max-width:100%;height:auto;box-shadow:var(--shadow)}
.article figure img.small{width:auto}
.article figure img.small{margin-right:auto}
.article figcaption{font-size:13px;color:var(--muted);padding-top:7px;line-height:1.45}
.empty{color:var(--muted);font-style:italic;padding-top:30px}
/* ── 整期目录 ──────────────────────────────────────────────
   它兜的是"这一期都有什么"，与「本版全部文章」（兜点不准）是两件事。 */
.toc{max-width:900px;margin:0 auto;padding:26px clamp(18px,4vw,40px) 60px}
.toc-head h2{margin:0 0 6px;font-size:clamp(22px,3vw,32px)}
.toc-head .by{color:var(--muted);font-size:14px;margin:0 0 12px}
.toc-pg{margin:26px 0 0;border-top:1px solid var(--line);padding-top:14px}
.toc-pg h3{margin:0 0 8px;font-size:15px;letter-spacing:.06em;text-transform:uppercase;color:var(--muted)}
.toc-pg h3 a{text-decoration:none;color:inherit}
.toc-pg h3 a:hover{color:var(--accent)}
.toc-pg ul{margin:0;padding-left:19px}
.toc-pg li{margin:.45em 0;line-height:1.5}
.toc-pg small{color:var(--muted)}
/* 短讯/导读标出来 —— 一期三十几条短讯，不标的话目录会被它们淹掉 */
.toc-pg .k{font-size:10.5px;letter-spacing:.05em;text-transform:uppercase;color:var(--muted);
  border:1px solid var(--line);border-radius:9px;padding:0 6px;margin-left:6px;white-space:nowrap}
/* 分享/复制的一句话确认 —— 没有确认就不知道到底做了没有 */
.flash{position:fixed;left:50%;bottom:76px;transform:translateX(-50%) translateY(8px);
  background:var(--ink);color:var(--bg);padding:9px 16px;border-radius:999px;font-size:14px;
  box-shadow:var(--shadow);opacity:0;pointer-events:none;transition:opacity .18s,transform .18s;z-index:50}
.flash.on{opacity:1;transform:translateX(-50%) translateY(0)}
/* 程序把焦点移到标题上（读屏软件从这儿往下念）。焦点环要留着 —— 用键盘的人靠它定位 */
.article h2:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
.article h2:focus:not(:focus-visible){outline:none}
.stories{padding-left:18px;margin:0}
.stories li{margin:.5em 0}
/* 文章视图下仍然留着「本版全部文章」—— 它兜住任何点不准的情况，
   也是 WCAG 2.5.8 "Equivalent" 例外的依据 */
.allon{margin-top:2em;border-top:1px solid var(--line);padding-top:14px}
.allon summary{cursor:pointer;color:var(--muted);font-size:14px}
.allon[open] summary{margin-bottom:10px}

/* ── 底栏：翻页 + 缩略图 + 下载 ── */
.bar{position:sticky;bottom:0;display:flex;gap:9px;align-items:center;flex-wrap:wrap;
  padding:9px 16px;background:var(--panel);border-top:1px solid var(--line);font-size:14px}
.thumbs{display:flex;gap:7px;overflow-x:auto;flex:1;padding:2px}
.thumbs button{flex:0 0 auto;border:2px solid transparent;border-radius:2px;line-height:0}
.thumbs img{height:52px;width:auto;display:block;background:var(--bg)}
.thumbs button[aria-current=true]{border-color:var(--accent)}
.thumbs label{display:flex;align-items:center;gap:4px}
/* 下载三个出口挨在一起，与翻页/缩略图分开 —— 原来它们混在一排，
   「Download selected」看着像唯一的下载入口 */
.dl{display:flex;gap:7px;align-items:center;flex-shrink:0}
.dl a.btn.primary{background:var(--accent);color:#fff;border-color:var(--accent)}
.dl a.btn.primary:hover{filter:brightness(1.08);background:var(--accent)}
.dl .btn:disabled{opacity:.5;cursor:not-allowed}
.dl .btn:disabled:hover{background:none}
.selall{display:flex;align-items:center;gap:4px;font-size:13px;color:var(--muted);flex-shrink:0}

/* 文章顶部的返回键。桌面双栏时也在（多一个明确出口），手机上它是主要出口 */
.article .back{margin:0 0 12px}
.btn.sm{padding:4px 10px;font-size:13px}

/* ── 手机：单栏，文章覆盖 ── */
@media (max-width:820px){
  .reader{grid-template-columns:1fr;height:auto}
  .article{border-left:0;border-top:1px solid var(--line)}
  .reader[data-view=page] .article{display:none}
  /*
   * ★★ `:not([data-solo="1"])` 是第二道防线。
   *
   *   单栏（未标注版）时右栏本来就 `display:none`，这一条再把版面也藏掉就是
   *   **整屏空白** —— 用户 2026-09-13：「点击 Text 之后没有任何内容显示」。
   *
   *   第一道防线是"单栏时把那个键收起来"（app.js 的 setSolo）。但那一道
   *   当天就被执行顺序绕过去过（showPage 里一行无条件 `hidden=false`），
   *   所以这里再钉一次：**不管哪条路把 data-view 设成了 text，
   *   单栏时版面都必须留着**。两栏全空是没有任何借口的状态。
   */
  .reader[data-view=text]:not([data-solo="1"]) .spread{display:none}
}

/* ── 手机：顶栏与底栏都分成多排 ──────────────────────────────
   断点取 700px（与 site.css 那一档对齐）。820 那一档管的是"单栏还是双栏"，
   是另一件事 —— 平板横放时版面该双栏，但顶栏还不需要拆行。 */
@media (max-width:700px){
  /*
   * 顶栏现在只有一排：报头 ……… 我的账户  语言  主题。
   *
   * ★ 这里原来有一条把 `.sp` 当换行符用的规则（`flex-basis:100%` + `order:4`），
   *   那是给"搜索 / A−A+ / 文字版面"也在顶栏时准备的。2026-10-02 那三个控件
   *   搬到了面包屑那一排（见 views.ts 的 readBody），顶栏放得下一排了，
   *   那条规则就成了死的 —— 而且 `order:4` 会把 `.sp` 挤到最后，
   *   它连换行都不换了。删掉，让桌面那条 `header .sp{flex:1}` 统一生效。
   */
  header{padding:8px 12px;gap:8px}
  header h1{flex:1;font-size:16px}

  /*
   * 底栏三排：
   *     ‹ 上一版   [第 N 版 ▾]   下一版 ›
   *     缩略图（换行铺满，不横滚）
   *     整期 PDF  本版  已选     ⛶ 🖨 ⌨
   *
   * ★ 缩略图原来是 `overflow-x:auto` 横滚 + `flex:1`。窄屏上它抢不到空间 ——
   *   实测 390px 下只剩 **71px 宽**，16 版一版都露不出来，而且"这里能横滑"
   *   没有任何视觉提示。改成换行铺满：一眼看得到整期有多少版、现在在第几版。
   */
  .bar{padding:8px 10px;gap:6px;row-gap:8px}
  /*
   * ★★ `order` 必须**每个直接子元素都给**。
   *
   *   没给的默认是 `0`，而 0 小于任何正数 —— 于是它们会排到所有设过 order
   *   的元素**前面**去。2026-09-13 第一版只给了 prev/jump/next，结果
   *   「目录」和「满宽」跑到了 `‹ ›` 前头，翻页键被挤到最右边。
   *   所以先用 `.bar > *` 兜一个底，再逐个覆盖。
   *
   * 排布（按手机上的使用频率）：
   *     ‹   第 N 版 ▾   ›   满宽        ← 最高频的翻页与缩放
   *     缩略图（换行铺满）                ← 一眼看到整期有几版、现在在哪
   *     目录  整期 PDF   ⛶ 🖨 ⌨          ← 低频
   */
  .bar > *{order:5}
  .bar #prev{order:1}
  /* 版号选择器包在一个 <label> 里（「第 N 版 / 共 16 版」），
     所以要挑那个 label，不是 #jump —— order 只对 flex 的**直接子元素**生效。
     `:not(.selall)` 是因为「全选」也是个 label */
  .bar > label:not(.selall){order:2;flex:1;min-width:0}
  .bar #next{order:3}
  .bar #pgZoom{order:4}
  /*
   * 缩略图：**独占一整行 + 横向滑动**（用户 2026-09-13：
   * 「底部现在显示两排的各版列表，能否改成一行，支持左右滑动的，
   * 内容区域有点被挤压了」）。
   *
   * ★ 与 2026-09-13 之前那个坏掉的状态**不是一回事**。那时它是
   *   `flex:1` 夹在下载按钮与工具键中间，实测只抢到 **71px** 宽 ——
   *   16 版一版都露不出来。现在它 `flex:1 1 100%` 独占一行，
   *   拿到整个 370px，横滑才是有意义的。
   *
   * ★ 原来没有任何"这里能横滑"的提示，所以补两样：
   *   · 右边缘一道渐隐（`mask-image`），暗示后面还有
   *   · `scroll-snap` 让滑动停在整版上，不会半截
   *   另外 app.js 会把当前版滚进视野 —— 没有那一步的话，翻到第 12 版时
   *   缩略图条还停在开头，"现在在哪"这个信息就没了。
   */
  .thumbs{order:6;flex:1 1 100%;flex-wrap:nowrap;overflow-x:auto;justify-content:flex-start;
    gap:6px;max-height:none;padding:2px 0;
    scroll-snap-type:x proximity;-webkit-overflow-scrolling:touch;
    /* 右边缘渐隐。两个前缀都写：Safari 到现在仍然只认带前缀的那个 */
    -webkit-mask-image:linear-gradient(to right,#000 calc(100% - 28px),transparent);
    mask-image:linear-gradient(to right,#000 calc(100% - 28px),transparent)}
  /* 滑到底时把渐隐去掉 —— 否则最后一版永远是半透明的，看着像坏了 */
  .thumbs.at-end{-webkit-mask-image:none;mask-image:none}
  .thumbs button{border-width:2px;border-radius:3px;scroll-snap-align:center}
  /* 单行之后高度不再是瓶颈，给大一点：58px 高约合 32px 宽，好按也看得清 */
  .thumbs img{height:58px}
  .selall{order:7}
  .bar > a.btn{order:8}
  .dl{order:9;flex:1 1 auto;flex-wrap:wrap}
  .tools{order:10}
  /* 触屏上按钮要够大按（WCAG 2.5.8 的下限是 24px，这里给 36） */
  .bar .btn,.dl .btn,.tools .btn{min-height:36px}
}
