/* =====================================================================================
 * 词境 · Editorial B（12 栏文化杂志）—— 首页 + 故事页
 * 依据：design/EDITORIAL-B-SPEC.md v1.2（青砚）· concept/editorial/B/src/*.html · b.css
 * 只作用于 body[data-page="home"] / body[data-page="story"]；其余页面保持现状。
 * 不改 style.css / v2-theme.css / motion.css / app.js / motion.js，全部用本层覆盖。
 * 用户裁定（优先于规范）：中文一律 400；font-synthesis 保持全站 weight（规范 §1/D2 写 none，冲突已在 B-IMPL-NOTES 标注）。
 * v1.2b：线型四条各一 token；顶栏 59px 整数高 + .tabs 拉伸压线；无写死色（hex 只在 token 块）。
 * v1.2c：参与对齐的高度 / 位置一律整数 px；小数字号的容器用整数 line-height 或定高。
 * v1.2d：非正文块「块高 + 上下 margin」= 16 的整数倍（定高的块在 CSS 里凑；高度随内容变的块由 js/wv-editorial-b.js snap16 补 padding-bottom）；
 *        浅底 --tint #EBF3EF；引文（.wv-b-pq，B 脚本插入，aria-hidden、无 id、不可点）；段落朗读按钮常显（知微裁定）；footer-fontsize 在 B 隐藏；底栏常显，「本篇词表」（#footer-vocab，与 aria-label 一致；知微 01:05 由「生词本」更名）「收藏」为常显纯文字链接（知微 00:24）。
 * v1.2e：Inter 只剩 400 一个 face（600 文件已删），B 范围内不再请求 Inter 600。
 * 断点：≥1200 固定 12×72 栅格（1128 居中）；768–1199 流体 12 栏；≤767 = 390 版式。
 * ===================================================================================== */

/* ---------- 0. token（线型四条全部 token 化，改一处即可） ---------- */
:root {
  --wvb-ln: 32px;
  --wv-divider: 1px solid var(--wv-line);                 /* ① 分隔线 */
  --wv-accent-rule: 1px solid var(--wv-text-1);           /* ② 强调墨线：署名顶线 / 引文顶线 / 选中态（待鉴心定，暂 1px t1） */
  --wv-control-border: var(--wv-text-3);                  /* ③ 控件边界色：亮 #686D6A 5.27:1 / 暗 #8C918E 5.99:1 */
  --wv-focus-ring: 2px solid var(--wv-text-1);            /* ④ 焦点环：只用于 :focus-visible */
  --wv-focus-offset: 3px;
  --tint: #EBF3EF;                                        /* v1.2d 更正（= V2U --wv-green-tint 亮）；v1.2b 生词悬停 / 当前词浅底（亮）；全文件唯一允许写 hex 的地方 = 本 token 块 */
  --wvb-top-h: 59px;                                      /* v1.2b 顶栏整数高（border-box，含 1px 分隔线） */
  --wvb-disp: "WV Instrument Serif", "WV Instrument Serif FB", "WV Noto Serif SC", "WV Noto Serif SC FB", serif;
  --wvb-serif: "WV Newsreader", "WV Newsreader FB", "WV Noto Serif SC", "WV Noto Serif SC FB", serif;
  --wvb-sans: "WV Inter", "WV Inter FB", "WV Noto Sans SC", "WV Noto Sans SC FB", sans-serif;
  /* 动态中文（译文 / 释义 / 提示 / toast）：不用 WV 子集，避免同一行内子集字与系统字混排 */
  --wvb-zh-serif: "Noto Serif CJK SC", "Source Han Serif SC", "Songti SC", "STSong", "SimSun", serif;
  --wvb-sans-sys: "WV Inter", "WV Inter FB", "Noto Sans CJK SC", "Source Han Sans SC", "PingFang SC", "Microsoft YaHei", sans-serif;
}

[data-theme="dark"] { --tint: #1B2A24; }                 /* v1.2b 生词浅底（暗） */

/* ---------- 1. 通用：白底、0 圆角、无阴影、无动效、中文 400、焦点环 ---------- */
body:is([data-page="home"], [data-page="story"]) {
  background: var(--wv-bg); color: var(--wv-text-1);
  font-family: var(--wvb-sans-sys); font-weight: 400;
}
body:is([data-page="home"], [data-page="story"]) :is(#page-home, #page-story, .nav, .tabbar, .reader-toolbar) * {
  border-radius: 0 !important; box-shadow: none !important; text-shadow: none !important;
}
/* s16c 衡舟 06:14：动效清零不再覆盖生成中的「…」与进度条（§5.9 状态反馈）。原「animation/transition: revert !important」例外是 bug：
   作者样式里 revert 退回 UA 的 none，等于仍清零。改为清零规则本身用 :where(:not(…)) 排除这两项（特异性与原 * 相同）；
   它们的关闭只交给 prefers-reduced-motion（style.css @media reduce：.wv-dots span / .wv-progress-bar::after animation:none；motion.css M19）。 */
body:is([data-page="home"], [data-page="story"]) :is(#page-home, #page-story, .nav, .tabbar, .reader-toolbar) :where(:not(#generate-btn .wv-dots span, #casting-fill)) {
  transition: none !important; animation: none !important;
}
/* v1.2c：B 范围内所有容器默认整数 line-height，未单独设行高的文字也不会撑出小数高度 */
body:is([data-page="home"], [data-page="story"]) :is(#page-home, #page-story, .nav, .tabbar, .reader-toolbar) { line-height: 24px; }
body:is([data-page="home"], [data-page="story"]) :is(.nav, .tabbar, .reader-toolbar) {
  -webkit-backdrop-filter: none !important; backdrop-filter: none !important; box-shadow: none !important;
}
/* 无图标：B 页内所有 svg 图标隐藏；纯图标按钮用 aria-label 文字显示（见 §6） */
body:is([data-page="home"], [data-page="story"]) :is(#page-home, #page-story, .nav, .tabbar) .wv-icon { display: none !important; }
/* v1.2g：段落朗读改为文字按钮，取消图标例外（app 渲染的 svg 随上一条一起隐藏），见 §5 .para-read-btn */
/* 焦点环（④）：全站统一 2px t1 偏移 3px，只在 :focus-visible；取代 s14 的 .input-wrapper::after 环与 --wv-ring 双层 box-shadow 环 */
body:is([data-page="home"], [data-page="story"]) :focus-visible {
  outline: var(--wv-focus-ring) !important; outline-offset: var(--wv-focus-offset) !important; box-shadow: none !important;
}
body:is([data-page="home"], [data-page="story"]) :focus:not(:focus-visible) { outline: none !important; }

/* ---------- 2. 顶栏（.nav）：品牌 1–2 栏 / tab 3–9 栏 / 日期 + 设置 10–12 栏 ---------- */
/* s16b v1.2s §5.8-9（G3-03）：style.css L1257/L1258 把 .nav / .tabbar 容器的 font-family 设成 var(--wv-font-ui) = "Inter", …；
   容器自己的行盒（strut / first available font 要找含 U+0020 的字体）会让浏览器请求 v2-theme.css L250 的旧 'Inter' face（描述符 font-weight: 400 600，
   G3 报的「Inter 400 600 normal」就是它）。B 的子元素各自都设了 WV 字族，所以只要把容器改回 B 的栈，B 页就不再引用旧 'Inter'。特异性 0-2-1 = L1257，靠后生效。 */
body:is([data-page="home"], [data-page="story"]) :is(.nav, .tabbar) { --wv-font-ui: var(--wvb-sans-sys); font-family: var(--wvb-sans-sys); }
body:is([data-page="home"], [data-page="story"]) .nav {
  position: sticky; top: 0; height: var(--wvb-top-h); box-sizing: border-box; background: var(--wv-bg) !important;
  border-bottom: var(--wv-divider) !important; transform: none !important;
}
body:is([data-page="home"], [data-page="story"]) .nav .nav-inner {
  display: grid; grid-template-columns: repeat(12, 72px); column-gap: 24px; width: 1128px; max-width: none;
  margin: 0 auto; padding: 16px 0; height: 58px; box-sizing: border-box; align-items: baseline; gap: 0 24px;   /* 58 = 59 − 1px 分隔线；内容区 26 */
  font-family: var(--wvb-sans); font-size: 12px; letter-spacing: .12em; color: var(--wv-text-3);
}
body:is([data-page="home"], [data-page="story"]) .nav .nav-brand {
  grid-column: 1 / 3; min-height: 0; height: auto; padding: 0; gap: 0; background: none;
  font-family: var(--wvb-disp); font-size: 25.6px; line-height: 26px; font-weight: 400; letter-spacing: -.01em; color: var(--wv-text-1);
}
body:is([data-page="home"], [data-page="story"]) .nav .nav-links { grid-column: 3 / 10; display: flex; gap: 40px; align-items: stretch; align-self: stretch; margin-bottom: -17px; }   /* v1.2b：17 = padding-bottom 16 + border 1；.tabs 底边 = .nav 边框盒底边 */
body:is([data-page="home"], [data-page="story"]) .nav .nav-tab {
  height: auto; padding: 7px 0 0; margin: 0; box-sizing: border-box; background: none;   /* v1.2b：padding-top 7 → 文字 y=23 */
  font-family: var(--wvb-sans); font-size: 12px; line-height: 18px; letter-spacing: .12em; font-weight: 400; color: var(--wv-text-2);
}
body:is([data-page="home"], [data-page="story"]) .nav .nav-tab.active { color: var(--wv-text-1); font-weight: 400; border-bottom: var(--wv-accent-rule); }   /* 墨线落在 y 58–59，与分隔线同一 CSS 像素 */
body:is([data-page="home"], [data-page="story"]) .nav .nav-tab.active::after { display: none; }
body:is([data-page="home"], [data-page="story"]) .nav .nav-due-badge {
  height: auto; min-width: 0; padding: 0; margin-left: 4px; background: none; color: var(--wv-text-3);
  font-size: 12px; font-weight: 400; font-variant-numeric: tabular-nums;
}
body:is([data-page="home"], [data-page="story"]) .nav .nav-more {
  grid-column: 10 / 13; display: flex; justify-content: flex-end; align-items: baseline; gap: 24px; margin: 0;
}
body:is([data-page="home"], [data-page="story"]) .nav .wv-b-date { line-height: 18px; font-variant-numeric: tabular-nums; color: var(--wv-text-3); white-space: nowrap; }
/* s16b G4：首页日期节点首帧（JS 填值前）就占住最终尺寸与基线：宽 = YYYY.MM.DD tabular 实测 83.11 → 84；空时放一个零宽字符撑出行盒（基线），填值后 :empty 失效。只限首页，故事页（示例故事日期留空）不变。 */
body[data-page="home"] .nav .wv-b-date { min-width: 84px; text-align: right; }
body[data-page="home"] .nav .wv-b-date:empty::before { content: "\200b"; }
body:is([data-page="home"], [data-page="story"]) .nav :is(.wv-b-set, .nav-more-btn) {
  width: auto; height: auto; min-height: 0; padding: 0; background: none !important; border: 0;
  font-family: var(--wvb-sans); font-size: 12px; line-height: 18px; letter-spacing: .08em; font-weight: 400; color: var(--wv-text-1);
}
body:is([data-page="home"], [data-page="story"]) .nav .nav-more-btn::after { content: attr(aria-label); }
/* .wv-b-set（#wv-b-set「阅读设置」）的显示 / 隐藏：白名单，见下方 #read-btn 处（s16c 衡舟 15:53） */
/* v1.2n §5.7：顶栏 #more-btn 去掉（入口已分到首页页脚 / 书库操作 / 阅读设置）。JS 无引用，但按裁定 id 保留在 DOM → 只在 B 两页 display:none；
 * #more-menu 本来就 [hidden]。别的页面（书库 / 词库等，非 B）不受影响。 */
body:is([data-page="home"], [data-page="story"]) .nav #more-btn { display: none !important; }
/* v1.2r §5.7：故事页不显示 4 个导航 tab（DOM / id / onclick 保留）。≥768 顶栏 .nav-links display:none；≤767 本来就由 :112 / style.css:312 收起，底栏 .off。
 * 离开故事页：品牌名 button.nav-brand → goPage('home')；「返回」#story-back-btn → storyGoBack()（书库）。其他页不受影响。 */
@media (min-width: 768px) { body[data-page="story"] .nav .nav-links { display: none !important; } }
/* 品牌「词境」只在首页做纯文本：首页隐藏可点的 button.nav-brand，显示同样式的 span.wv-b-brand-txt；故事页反过来（品牌仍可点回首页）。 */
.nav .wv-b-brand-txt { display: none; }
body[data-page="home"] .nav button.nav-brand { display: none !important; }
body[data-page="home"] .nav .wv-b-brand-txt { display: flex; align-items: center; cursor: default; }
body:is([data-page="home"], [data-page="story"]) .nav .menu { border: var(--wv-divider); background: var(--wv-bg); right: 0; }

/* ---------- 3. 390 底部 tab（#wv-tabbar 复用为 .btab） ---------- */
@media (max-width: 767px) {
  body:is([data-page="home"], [data-page="story"]) .nav { height: auto; }   /* v1.2b：390 .top{height:auto}；内容全是整数 line-height → 20+24+15+1 = 60 */
  body:is([data-page="home"], [data-page="story"]) .nav .nav-inner {
    display: flex; justify-content: space-between; width: auto; height: auto; padding: 20px 20px 15px; gap: 16px;
  }
  body:is([data-page="home"], [data-page="story"]) .nav .nav-brand { font-size: 20.48px; line-height: 24px; }
  body:is([data-page="home"], [data-page="story"]) .nav .nav-links { display: none; }
  body:is([data-page="home"], [data-page="story"]) .nav .nav-more { gap: 16px; }
  body[data-page="story"] .nav .nav-more { gap: 24px; }   /* s16b v1.2s §5.8-10（G3-10）：故事页所有宽度 24；首页 ≤767 仍 16 */
  body:is([data-page="home"], [data-page="story"]) .tabbar {
    display: grid !important; grid-template-columns: repeat(4, 1fr); position: fixed; left: 0; right: 0; bottom: 0; z-index: 50;
    height: calc(56px + env(safe-area-inset-bottom, 0px)); box-sizing: border-box; padding: 0 0 env(safe-area-inset-bottom, 0px); background: var(--wv-bg) !important; border-top: var(--wv-divider) !important;
    transform: none;
  }
  body:is([data-page="home"], [data-page="story"]) .tabbar.off { transform: translateY(100%); visibility: hidden; }
  body:is([data-page="home"], [data-page="story"]) .tabbar .tabbar-item {
    display: flex; align-items: center; justify-content: center; height: 55px; box-sizing: border-box; padding: 0; gap: 0; background: none;
    font-family: var(--wvb-sans); font-size: 16.384px; line-height: 24px; letter-spacing: .04em; font-weight: 400; color: var(--wv-text-2);
  }
  /* v1.2n §5.7：选中项墨线改用 ::before 绝对定位（压在栏顶 1px 分隔线上，top:-1px），不占布局、不进 surface；
   * 每个按钮固定预留尺寸（grid 4 等分宽 × 高 55，nowrap，字形宽度不影响盒子）→ 载入和 Tab 切换 CLS=0，回退字体也一样。
   * ⚠ s15b 也在修这一处（tabbar），合并时两边要对齐（见 B-IMPL-NOTES §28）。 */
  body:is([data-page="home"], [data-page="story"]) .tabbar .tabbar-item { position: relative; width: 100%; min-width: 0; white-space: nowrap; margin: 0; border: 0; }
  body:is([data-page="home"], [data-page="story"]) .tabbar .tabbar-item.active { color: var(--wv-text-1); font-weight: 400; margin-top: 0; border-top: 0; }
  body:is([data-page="home"], [data-page="story"]) .tabbar .tabbar-item.active::before {
    content: ""; display: block; position: absolute; left: 0; right: 0; top: -1px; height: 0; border-top: var(--wv-accent-rule); background: none; transform: none; opacity: 1;
  }
  body:is([data-page="home"], [data-page="story"]) .tabbar .tabbar-item.active::after { display: none; }
  body:is([data-page="home"], [data-page="story"]) .tabbar .tab-dot-badge { display: none; }
  body[data-page="home"] { padding-bottom: 56px; }
  /* s16 合并（s15b G4 × B 墨线）：style.css G4 的 `body[data-page] #wv-tabbar > .tabbar-item {height:56px; overflow:hidden}`（特异性 1,2,1）
   * 高于上面 B 的 `.tabbar .tabbar-item`（0,3,1），会把 B 的 55px 改成 56（栏 56 = 55 + 1px 顶线，溢出 1px）并裁掉 top:-1px 的 ::before 墨线。
   * 这里用同特异性、后加载覆盖回 B 的值：高 55、overflow 可见；G4 的其余预留（flex 1 1 0 / min-width 0 / nowrap / .v2u-tab-ind 绝对定位不进 grid）保留。
   * 每格尺寸仍然固定（grid 4 等分 × 55，nowrap），墨线绝对定位不占布局 → 两边都不引起位移。 */
  body:is([data-page="home"], [data-page="story"]) #wv-tabbar > .tabbar-item { height: 55px; overflow: visible; }
}

/* ---------- 4. 首页 ---------- */
body[data-page="home"] #page-home { font-family: var(--wvb-sans-sys); background: transparent; }   /* v1.2n §5.7：底色交给 body（--wv-bg），与 .nav 并成同一 surface 键 */
body[data-page="home"] #page-home .v2-hero {
  display: grid; grid-template-columns: repeat(12, 72px); column-gap: 24px; width: 1128px; max-width: none;
  margin: 0 auto; padding: 0 0 calc(var(--wvb-ln) * 2); text-align: left;
  min-height: calc(100vh - var(--wvb-top-h)); align-content: center; contain: none; gap: 0 24px;
  min-height: round(down, calc(100vh - var(--wvb-top-h)), var(--wvb-ln));   /* s16b v1.2s §5.8-1（G3-01）：取整到 32 → 居中余量为偶数、kick 不带 .5；不支持 round() 的浏览器保留上一行 */
  /* s16c 托盘 CLS（青砚 05:31 定：顶对齐）：不再 align-content:center 重新居中；顶部偏移 = 空态居中位置，按 32 向下取整，与上面 G3-01 的 round(down) 一起算。
   * --wvb-hero-c = 空态内容组等效高（含 padding-bottom），取自 evidence/s16b-0415/browser/cls-locate.json：1440 hero 59/841、kick 136 → 841−2×77 = 688；1024/768 → 624。
   * 托盘多出的行只往下长（上面的块不动）；不预留高度。不支持 round() 的浏览器用 calc 行（不取整，仍顶对齐、仍不随托盘动）。 */
  --wvb-hero-c: 688px; align-content: start;
  padding-top: 64px;   /* s16c 05:41 整数基线（≥1200，代表视口 1440×900 实算 64）；支持 round() 时由文件末尾 @supports 用公式覆盖 → 任何浏览器都不出 .5 */
}
body[data-page="home"] #page-home .v2-hero > * { grid-column: 1 / 13; }
body[data-page="home"] #page-home .wv-b-kick {   /* 00:13 更正：「开篇」是中文 → Noto Sans SC 400 / 12px / t3，无字距、无大写；行高 16 = 16 的整数倍（v1.2d） */
  margin: 0; font-family: "WV Noto Sans SC", "WV Noto Sans SC FB", sans-serif; font-size: 12px; line-height: 16px; letter-spacing: 0; text-transform: none; font-weight: 400; color: var(--wv-text-3);
}
body[data-page="home"] #page-home .home-title {
  margin: calc(var(--wvb-ln) * .5) 0 0; padding: 0; max-width: none;
  font-family: var(--wvb-disp); font-weight: 400; font-size: 152.59px; line-height: 152px; letter-spacing: -.03em; color: var(--wv-text-1);
  text-align: left; background: none; -webkit-text-fill-color: currentColor;
}
body[data-page="home"] #page-home .home-title .l1,
body[data-page="home"] #page-home .home-title .l2 { display: block; }
body[data-page="home"] #page-home .home-title .l2 { padding-left: 192px; }
body[data-page="home"] #page-home .wv-b-act { grid-column: 6 / 13; margin-top: var(--wvb-ln); }
/* s16c-d4（衡舟 15:06/15:08，青砚 SPEC v1.2z §5.8-15）：1440 首屏留白改布局，只改 ≥1200 档。L165 基础值 688 不动（避免影响 767–768 之间的小数视口）；
   同选择器、同特异性、位置在后 → 覆盖 L165；768–1199（文件末尾 624）、≤767（576）、≤389（640）的覆盖不受影响。 */
@media (min-width: 1200px) {
  body[data-page="home"] #page-home .v2-hero { --wvb-hero-c: 704px; }
  body[data-page="home"] #page-home .wv-b-act { margin-top: calc(var(--wvb-ln) * 1.5); }
}
body[data-page="home"] #page-home .home-sub {
  margin: 0 0 var(--wvb-ln); max-width: none; text-align: left;
  font-family: var(--wvb-serif); font-size: 20.48px; line-height: 38px; font-weight: 400; letter-spacing: .02em; color: var(--wv-text-2);   /* v1.2c：1.875 → 38.4 小数，改整数 38（1.855） */
}
/* 表单：552×56；输入框 1px 控件边界（③），右边与按钮相接不画线 */
body[data-page="home"] #page-home .home-input-form {
  display: block; width: 552px; max-width: 100%; padding: 0; margin: 0; background: none; border: 0;
}
body[data-page="home"] #page-home .wv-b-form { display: flex; align-items: stretch; width: 100%; min-height: 56px; }   /* v1.2c：56 = 1+15+24+15+1 */
body[data-page="home"] #page-home .input-wrapper {
  position: relative; flex: 1 1 auto; min-width: 0; min-height: 56px; box-sizing: border-box; display: flex; align-items: center;
  padding: 0 80px 0 20px; background: var(--wv-bg);
  border: 1px solid var(--wv-control-border); border-right: 0; box-sizing: border-box;
}
/* s14 的 ::after 聚焦细边 + 外光环在 B 里停用：焦点环只剩 .wv-b-form 外的一圈 outline（同心、单层） */
body[data-page="home"] #page-home .input-wrapper::after,
body[data-page="home"] #page-home .input-wrapper::before { content: none !important; display: none !important; }
body[data-page="home"] #page-home #word-input.home-input {
  width: 100%; min-height: 24px; height: auto; padding: 15px 0; margin: 0; box-sizing: content-box; border: 0 !important; background: none;
  font-family: var(--wvb-sans-sys); font-size: 16.384px; line-height: 24px; font-weight: 400; color: var(--wv-text-1); resize: none;
}
body[data-page="home"] #page-home #word-input.home-input::placeholder { color: var(--wv-text-3); opacity: 1; font-family: var(--wvb-sans); }
/* textarea 自身不画环（会落在边框内侧形成双框）；改由外层画一圈，偏移 3px 包住「输入框 + 生成按钮」整行 */
body[data-page="home"] #page-home #word-input.home-input:focus-visible,
body[data-page="home"] #page-home #word-input.home-input:focus { outline: none !important; box-shadow: none !important; }
body[data-page="home"] #page-home .wv-b-form:has(#word-input:focus-visible) { outline: var(--wv-focus-ring); outline-offset: var(--wv-focus-offset); }
body[data-page="home"] #page-home .wv-input-caret { display: none !important; }
body[data-page="home"] #page-home .input-clear {
  position: absolute; right: 8px; top: 50%; width: 28px; height: 28px; margin-top: -14px; padding: 0; background: none;
  font-family: var(--wvb-sans-sys); font-size: 16.384px; line-height: 28px; color: var(--wv-text-3);
}
body[data-page="home"] #page-home .input-clear { width: auto; font-size: 12px; letter-spacing: .04em; }
body[data-page="home"] #page-home .input-clear::after { content: attr(aria-label); }   /* 无图标：清除按钮显示 aria-label 文字 */
body[data-page="home"] #page-home #generate-btn {
  flex: 0 0 auto; position: relative; height: auto; min-height: 56px; width: auto; margin: 0; padding: 0 28px;
  display: flex; align-items: center; justify-content: center; align-self: stretch; transform: none;
  background: var(--wv-btn); color: var(--wv-on-btn); border: 0;
  font-family: var(--wvb-sans); font-size: 20.48px; line-height: 24px; font-weight: 400; letter-spacing: .02em; box-sizing: border-box;
}
body[data-page="home"] #page-home #generate-btn::before { display: none; }
body[data-page="home"] #page-home #generate-btn:focus-visible { outline-offset: var(--wv-focus-offset) !important; }
body[data-page="home"] #page-home #generate-btn .btn-label,
body[data-page="home"] #page-home #generate-btn .btn-busy { font-weight: 400; }
/* 计数行保持 sr-only（app.js 仍写入） */
body[data-page="home"] #page-home .v2u-input-foot {
  display: flex; flex-direction: column; align-items: flex-start; gap: 0; margin: calc(var(--wvb-ln) * .5) 0 0; padding: 0; text-align: left;
}
/* s16b v1.2s §5.8-13：style.css `#page-home #v2u-input-foot{align-items:center}`（L1057，特异性 2-0-0）压过上一条（1-2-1），B 首页的左对齐没生效。
   这里用 id 选择器（2-1-1）只覆盖横向对齐；justify-content:center（L1311，纵向居中「随机来一组」于 44 高）不动。style.css 不改。 */
body[data-page="home"] #page-home #v2u-input-foot { align-items: flex-start; text-align: left; }
body[data-page="home"] #page-home .v2u-input-hint {
  order: 2; margin: 0; min-height: 0; font-family: var(--wvb-sans-sys); font-size: 12px; line-height: 2; color: var(--wv-text-3);
}
body[data-page="home"] #page-home .v2u-input-hint:empty { display: none; }
/* s16 B1(a)（衡舟 02:13 裁定）：提示行（s15b G8「正在准备词库…」等）绝对定位在 #v2u-input-foot 下沿，不占布局空间。
   定位上下文沿用已有的 #v2u-input-foot { position: relative }（style.css:1297 / v2-theme.css:226），没有新加 position。
   foot = min-height 44、「随机来一组」24 行高垂直居中（上下各 10）；下面 16 是 #word-crystals-tray 的 margin-top（词标签从这里开始）。
   提示行行高 16，放在 foot 底边上 5px → 与「随机来一组」行框、词标签托盘顶边各留 5px，两边都不压。
   字号 / 行高 / 字重 / 颜色 = 12px / 16px / 400 / --wv-text-3，与 .wv-b-kick 同一组合，不新增。单行，过长省略（读屏仍读全文）。
   出现 / 消失只换 opacity：v2-smart-input.js 用 [hidden] 和清空文字来隐藏，style.css 的 [hidden] 是 display:none !important。
   这里用 !important 把它留成 display:block + opacity:0，live region 一直在无障碍树里，写字时才能播报；元素是绝对定位，不引起位移。 */
body[data-page="home"] #page-home #v2u-input-foot > .v2u-input-hint {
  position: absolute; top: calc(100% - 5px); left: 0; right: 0; margin: 0; min-height: 0;
  display: block; line-height: 16px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-align: left;   /* s16b v1.2s §5.8-13：center → left，与 foot 左对齐 */
  pointer-events: none; opacity: 1;
}
body[data-page="home"] #page-home #v2u-input-foot > .v2u-input-hint:is(:empty, [hidden]) { display: block !important; opacity: 0; }
/* 鉴心 r5-nogo D1：sr-only 计数脚注仍占字号档；style.css 15/13 → 统一 12/400（覆盖 #words-counter-bar + #words-counter-text） */
body[data-page="home"] #page-home #words-counter-bar,
body[data-page="home"] #page-home #words-counter-text {
  font-size: 12px; font-weight: 400;
}
@media (max-width: 767px) {
  body[data-page="home"] #page-home #words-counter-text { font-size: 12px; }
}
/* 「随机来一组」：纯文字链（16.384 / 400 / t2），命中区 98×44 不改布局 */
body[data-page="home"] #page-home #wv-random-set.v2u-random {
  order: 1; position: relative; display: block; width: fit-content; height: auto; min-height: 0; padding: 0; margin: 0;
  background: none; border: 0; text-decoration: none; white-space: nowrap;
  font-family: var(--wvb-sans); font-size: 16.384px; line-height: 24px; font-weight: 400; letter-spacing: .02em; color: var(--wv-text-3);   /* v1.2n 8.C 豁免：--t3 = --wv-text-3 */
}
body[data-page="home"] #page-home #wv-random-set.v2u-random:hover { color: var(--wv-text-1); }
body[data-page="home"] #page-home #wv-random-set.v2u-random::after { content: ""; position: absolute; inset: -10px -8px; }
body[data-page="home"] #page-home #wv-random-set.v2u-random::before { display: none; }
body[data-page="home"] #page-home #cancel-btn { order: 3; padding: 0; line-height: 24px; background: none; font-family: var(--wvb-sans-sys); font-size: 16.384px; color: var(--wv-text-2); }
body[data-page="home"] #page-home .word-crystals-tray,
body[data-page="home"] #page-home .hint-slot { margin-top: calc(var(--wvb-ln) * .5); }
body[data-page="home"] #page-home .casting-bar { margin-top: calc(var(--wvb-ln) * .5); background: none; border: 0; padding: 0; text-align: left; }
body[data-page="home"] #page-home .casting-bar :is(.loading-text, .casting-tip) { font-family: var(--wvb-sans-sys); font-size: 12px; line-height: 2; color: var(--wv-text-3); text-align: left; }
body[data-page="home"] #page-home #casting-fill { background: var(--wv-text-1); }
/* s16c genfb（衡舟 06:22 / 青砚 SPEC v1.2w §5.9-3；行为在 js/wv-genfb.js）——只在 html[data-wv-layout="b"] 下：
   ① #casting-tip 生成中恢复显示：style.css:1322 `#page-home #casting-tip { display:none !important }` 特异性 (2,0,0)；
      这里 html[data-wv-layout="b"] body[data-page="home"] #page-home #casting-bar.show:not(.error):not([data-wv-genfb]) #casting-tip
      = 3 个 id（#page-home #casting-bar #casting-tip）+ 5 个类/属性（[data-wv-layout] [data-page] .show .error [data-wv-genfb]，:not() 取参数特异性）+ 2 个类型（html body）= (3,5,2)，同为 !important → 这条胜出。
      .show:not(.error) = 只在生成中（app.js 报错时是 .show.error，那时提示是旧文案，不显示）。style.css 不改。
      状态行在 #casting-bar 里，#casting-bar 是 position:absolute（v2-theme.css:233），不占文档流 → 多一行 / 换字不推动版面，CLS 0。
   ② 慢 / 失败态（js 设 #casting-bar[data-wv-genfb="slow"|"fail"]）：#loading-text 让位给 #wv-genfb-line（app.js 仍每 3.5s 写 #loading-text，看不到即可，不抢写）；失败态 tip 也收起。
   ③ 「重试」：行末文字按钮 12px / 400 / --wv-text-1，无底色、无边框、无图标，hover 下划线（瞬时，无过渡）；::after 把命中区扩到 ≥44 高。
   ④ 生成中主按钮：js 加了原生 disabled，style.css:178 `.btn-primary:disabled { opacity:.4 }` 会变灰 → 这里保持实色（--wv-btn / --wv-on-btn，与非生成态同色），只把光标改 progress。 */
html[data-wv-layout="b"] body[data-page="home"] #page-home #casting-bar.show:not(.error):not([data-wv-genfb]) #casting-tip,
html[data-wv-layout="b"] body[data-page="home"] #page-home #casting-bar.show[data-wv-genfb="slow"] #casting-tip { display: block !important; }
html[data-wv-layout="b"] body[data-page="home"] #page-home #casting-bar[data-wv-genfb] #loading-text { display: none !important; }
html[data-wv-layout="b"] body[data-page="home"] #page-home #casting-bar[data-wv-genfb="fail"] #casting-tip { display: none !important; }
html[data-wv-layout="b"] body[data-page="home"] #page-home #casting-bar #wv-genfb-line {
  margin: 0; font-family: var(--wvb-sans-sys); font-size: 12px; line-height: 2; font-weight: 400; color: var(--wv-text-3); text-align: left;
}
html[data-wv-layout="b"] body[data-page="home"] #page-home #casting-bar #wv-genfb-line .wv-genfb-retry {
  position: relative; display: inline; margin: 0; padding: 0; min-height: 0; width: auto; height: auto;
  background: none; border: 0; border-radius: 0; box-shadow: none;
  font-family: var(--wvb-sans-sys); font-size: 12px; line-height: inherit; font-weight: 400; color: var(--wv-text-1); text-decoration: none; cursor: pointer;
}
html[data-wv-layout="b"] body[data-page="home"] #page-home #casting-bar #wv-genfb-line .wv-genfb-retry:hover { text-decoration: underline; }
html[data-wv-layout="b"] body[data-page="home"] #page-home #casting-bar #wv-genfb-line .wv-genfb-retry::after { content: ""; position: absolute; inset: -12px -10px 0; }   /* s16c-notes ⑦（衡舟 15:30 批准；r5 N2 衡舟 18:0x 定下 0）：上 12 / 左右 10 / 下 0。<button> 即使 display:inline 也按 inline-block 排，盒高 = line-height 24、与行框重合 → 热区 = 24+12 = 36 高，下沿 = 本行行下缘，390 行下缘最大 788（底栏顶）时也不伸进底栏。原 -10px -8px → -12px -10px -4px（下沿 = 行下缘 + 4，边界时伸进底栏 4px） */
html[data-wv-layout="b"] body[data-page="home"] #page-home #generate-btn.loading:disabled { opacity: 1; background: var(--wv-btn); color: var(--wv-on-btn); cursor: progress; }
/* 示例卡（V33–V50）不在 B 规范里：B 首页隐藏（见 Q） */
body[data-page="home"] #page-home .v2-preview { display: none !important; }
body[data-page="home"] #page-home .letter-card { grid-column: 6 / 13; margin-bottom: var(--wvb-ln); border: var(--wv-divider); background: var(--wv-bg); }
/* 续读 / 今日复习 / 页脚：首屏以下，落在第 6–12 栏，分隔线 ① */
body[data-page="home"] #page-home :is(.home-continue, .home-review-card) {
  width: 1128px; max-width: calc(100% - 64px); margin: 0 auto var(--wvb-ln); padding: calc(var(--wvb-ln) * .5) 0 0 456px;
  background: var(--wv-bg); border: 0; border-top: var(--wv-divider); box-sizing: border-box; font-family: var(--wvb-sans-sys);   /* v1.2n §5.7：与 390 tab 栏同一 surface 键 */
}
body[data-page="home"] #page-home .site-footer {
  width: 1128px; max-width: calc(100% - 64px); margin: 0 auto; padding: calc(var(--wvb-ln) * .5) 0 var(--wvb-ln);
  display: flex; flex-wrap: wrap; gap: 8px 24px; justify-content: flex-start; border-top: var(--wv-divider); background: var(--wv-bg);
}
body[data-page="home"] #page-home .site-footer .footer-link {
  padding: 0; min-height: 24px; line-height: 24px; background: none; font-family: var(--wvb-sans-sys); font-size: 12px; letter-spacing: .04em; font-weight: 400; color: var(--wv-text-3);
}
/* 首页去绿（品牌渐变 / 强调色） */
body[data-page="home"] #page-home .v2-grad { background: none; color: inherit; -webkit-text-fill-color: currentColor; }

@media (min-width: 768px) and (max-width: 1199px) {
  body:is([data-page="home"], [data-page="story"]) .nav .nav-inner { grid-template-columns: repeat(12, minmax(0, 1fr)); width: auto; padding-left: 32px; padding-right: 32px; }
  body[data-page="home"] #page-home .v2-hero { grid-template-columns: repeat(12, minmax(0, 1fr)); width: auto; padding-left: 32px; padding-right: 32px; }
  body[data-page="home"] #page-home .home-title { font-size: 100px; line-height: 100px; }
  body[data-page="home"] #page-home .home-title .l2 { padding-left: 16.67%; }
  body[data-page="home"] #page-home .wv-b-act { grid-column: 5 / 13; }
  body[data-page="home"] #page-home :is(.home-continue, .home-review-card) { padding-left: 0; }
}
@media (max-width: 767px) {
  body[data-page="home"] #page-home .v2-hero {
    grid-template-columns: repeat(4, minmax(0, 1fr)); column-gap: 16px; gap: 0 16px; width: auto; padding: 0 20px;
    min-height: calc(100svh - 60px - 56px);
    min-height: round(down, calc(100svh - 60px - 56px), var(--wvb-ln));   /* s16b v1.2s §5.8-1 */
    /* s16c 托盘 CLS 顶对齐（≤767）：本档 .wv-b-kick 自带 margin-top 32（下方 L297 左右），内容组含它。390×844 hero 82/728、kick 190 → 居中余量 190−82−32 = 76 → 内容高 728−2×76 = 576（标题 2 行）；
       <390 标题 3 行：375×667 hero 82/640（高于 min-height，内容撑开、无余量）、kick 114 = 82+32 → 内容高 640。05:41 更正（05:35 版误把 margin 算进余量，得 512/576）。 */
    --wvb-hero-c: 576px; align-content: start;
    padding-top: 64px;   /* s16c 05:41 整数基线（≤767，代表 390×844 实算 rounddown((704−576)/2, 32) = 64）；@supports 覆盖 */
  }
  body[data-page="home"] #page-home .v2-hero > * { grid-column: 1 / 5; }
  body[data-page="home"] #page-home .wv-b-kick { margin-top: var(--wvb-ln); }
  body[data-page="home"] #page-home .home-title { font-size: 62.5px; line-height: 62px; }
  body[data-page="home"] #page-home .home-title .l2 { padding-left: 0; }
  body[data-page="home"] #page-home .wv-b-act { grid-column: 1 / 5; }
  body[data-page="home"] #page-home .home-sub { font-size: 16.384px; line-height: 32px; padding-right: 56px; }
  body[data-page="home"] #page-home .home-input-form { width: 100%; }
  body[data-page="home"] #page-home .wv-b-form { flex-direction: column; min-height: 104px; }   /* 52 + 52 */
  body[data-page="home"] #page-home .input-wrapper { min-height: 52px; padding-left: 16px; border-right: 1px solid var(--wv-control-border); }
  body[data-page="home"] #page-home #word-input.home-input { padding: 13px 0; }
  body[data-page="home"] #page-home #generate-btn { min-height: 52px; height: 52px; }
  body[data-page="home"] #page-home :is(.home-continue, .home-review-card, .site-footer) { width: auto; max-width: none; margin-left: 20px; margin-right: 20px; padding-left: 0; }
  /* s16b G4：≤767 顶栏实测 82（非 60）→ hero 止于 810，页脚首帧有 34px 落在视口内（被底栏盖住，但 CLS 照算）；wv-shell 在 DOMContentLoaded 插入
   * 「先读一篇示例 / 继续阅读」后页脚被推到 1075 → 390 CLS 0.0098。只在两张卡都还 [hidden]（= 渲染前）时给页脚多 56px 上边距，首帧就把它放到视口外；
   * 卡片一出现本规则即失效，页脚回到原位（仍在视口外，不计 CLS）。hero 与首屏内容位置不变。回退：删本规则。 */
  body[data-page="home"] #page-home .home-continue[hidden] + .home-review-card[hidden] + .site-footer { margin-top: 56px; }
}

/* ---------- 5. 故事页 ---------- */
body[data-page="story"] #page-story { font-family: var(--wvb-sans-sys); }
body[data-page="story"] #read-progress { background: var(--wv-text-1); height: 1px; }
body[data-page="story"] .story-container {
  max-width: none; width: 1128px; margin: 0 auto; padding: 0; font-size: 20.48px; --story-measure: none;   /* v1.2o：下边距交给 #story-main 末块的 48（到页脚分隔线） */
}
body[data-page="story"] .story-back-row { margin: calc(var(--wvb-ln) * .5) 0 0; }
body[data-page="story"] .story-back-row .story-back {
  padding: 0; min-height: 24px; line-height: 24px; background: none; font-family: var(--wvb-sans); font-size: 12px; letter-spacing: .12em; font-weight: 400; color: var(--wv-text-2);
}
body[data-page="story"] #story-main {
  display: grid; grid-template-columns: repeat(12, 72px); column-gap: 24px; align-items: start;
  font-size: 20.48px; margin-top: var(--wvb-ln);
}
body[data-page="story"] #story-main > * { grid-column: 3 / 9; min-width: 0; }
body[data-page="story"] #story-main > :last-child:not(.wv-b-endrow) { margin-bottom: 48px; }   /* v1.2o：末块（章末区等）到页脚分隔线 48 */
body[data-page="story"] #story-main > .story-head { display: contents; }
body[data-page="story"] #story-main .wv-b-meta2 { grid-column: 1 / 3; grid-row: 1; align-self: end; padding: 0; }
body[data-page="story"] #story-main .wv-b-kick {
  font-family: var(--wvb-sans); font-size: 12px; line-height: 18px; letter-spacing: .16em; text-transform: uppercase; font-weight: 400;   /* v1.2e：600 → 400（Inter 600 face 已删） */
  font-variant-numeric: tabular-nums; color: var(--wv-text-3);
}
body[data-page="story"] #story-main .wv-b-no { margin-top: calc(var(--wvb-ln) * .5); font-family: var(--wvb-disp); font-size: 25.6px; line-height: 32px;   /* s16b v1.2s §5.8-5：32/1 → 25.6/32（盒高仍 32），并入 25.6×400 */ font-variant-numeric: tabular-nums; color: var(--wv-text-1); }
body[data-page="story"] #story-main .story-title {
  grid-column: 3 / 13; grid-row: 1; align-self: end; margin: 0; max-width: none;
  font-family: var(--wvb-disp); font-weight: 400; font-size: 78.125px; line-height: 78px; letter-spacing: -.03em; text-wrap: balance; color: var(--wv-text-1);
}
body[data-page="story"] #story-main .story-subtitle {
  grid-column: 3 / 11; margin: calc(var(--wvb-ln) * .5) 0 0; max-width: none;
  font-family: var(--wvb-serif); font-style: italic; font-weight: 400; font-size: 25.6px; line-height: 35px; text-wrap: balance; color: var(--wv-text-2);
}
body[data-page="story"] #story-main .story-subtitle:not(:lang(en)) { font-style: normal; font-family: var(--wvb-zh-serif); font-size: 20.48px; line-height: 38px; }   /* 中文不用斜体 */
body[data-page="story"] #story-main .story-meta { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; font-size: 12px; font-weight: 400; }   /* 鉴心 r5-nogo D1：即便 sr-only 也钉 12/400，避免占字号档；中文元信息保留给读屏 */
body[data-page="story"] #story-main .wv-b-by {
  grid-column: 3 / 13; margin-top: calc(var(--wvb-ln) * .5); padding: 14px 0; display: flex;   /* v1.2d：1+14+18+14+1 = 48（原 10px = 40，不是 16 的倍数） */ gap: 10px; align-items: baseline; white-space: nowrap;
  border-top: var(--wv-accent-rule); border-bottom: var(--wv-divider);
  font-family: var(--wvb-sans); font-size: 12px; line-height: 18px; letter-spacing: .14em; text-transform: uppercase; font-weight: 400;
  font-variant-numeric: tabular-nums lining-nums; color: var(--wv-text-2);
}
body[data-page="story"] #story-main .wv-b-by .sep { color: var(--wv-text-3); }
body[data-page="story"] #story-main .story-details { grid-column: 3 / 13; margin-top: calc(var(--wvb-ln) * .5); font-family: var(--wvb-sans-sys); font-size: 12px; line-height: 24px; color: var(--wv-text-3); }
body[data-page="story"] #story-main .story-details summary { cursor: pointer; font-weight: 400; }   /* 鉴心 r5-nogo D1：SUMMARY「用词详情」12×500 → 12×400 */
body[data-page="story"] #story-main .chapter-nav { grid-column: 3 / 13; margin-top: calc(var(--wvb-ln) * .5); background: none; border: 0; padding: 0; gap: 16px;
  display: flex; flex-wrap: nowrap; white-space: nowrap; border-radius: 0; box-shadow: none; }   /* s16b v1.2u ③：一行不折行；display:flex 让 ≤767（#story-main 为 block）时宽度 = 栏宽，才能横向滑窗 */
body[data-page="story"] #story-main .chapter-nav .seg-item { background: none; padding: 0; min-height: 24px; line-height: 24px; font-family: var(--wvb-sans); font-size: 12px; letter-spacing: .12em; font-weight: 400; color: var(--wv-text-2);
  box-sizing: border-box; height: 32px; min-height: 32px; padding: 7px 0 0; border: 0; border-bottom: 1px solid transparent; border-radius: 0; box-shadow: none; flex: none; }   /* s16b v1.2s §5.8-2（G3-06/07）：盒高 32（原 24 + active 墨线 1 = 25）；16 + 32 + .chapter-seg 下 32 = 80 */
body[data-page="story"] #story-main .chapter-nav .seg-item.active { color: var(--wv-text-1); border-bottom: var(--wv-accent-rule); }   /* 当前章只换色 + 墨线（v1.2u ②），不再加高 */
/* s16b v1.2u ①：章数 <2 不显示（app.js chapterNavHTML 本就返回空串；这里兜底，不改 app.js） */
body[data-page="story"] #story-main .chapter-nav:not(:has(> .seg-item ~ .seg-item)) { display: none; }
body[data-page="story"] #story-main .chapter-nav .seg-item::before, body[data-page="story"] #story-main .chapter-nav .seg-item::after { content: none; }   /* v1.2u ②：无图标 */
/* s16b v1.2s §5.8-2（G3-06/07）：B 接管 .story-hint（原 style.css 13px + p{line-height:1.7} = 22.1）→ 12/32，上 16，共 48 */
body[data-page="story"] #story-main .story-hint { margin: calc(var(--wvb-ln) * .5) 0 0; padding: 0; font-family: var(--wvb-sans-sys); font-size: 12px; line-height: 32px; font-weight: 400; color: var(--wv-text-3); }
/* 正文：第 3–8 栏，Newsreader 20.48/32 · 400 · onum · −.01em（鉴心 r5-nogo D1：450→400，消 20.48×450 并列） */
body[data-page="story"] #story-main .story-paragraph {
  grid-column: 3 / 9; position: relative; margin: 0 0 calc(var(--wvb-ln) * .5); padding: 0; background: none; border: 0; cursor: auto;
}
body[data-page="story"] #story-main .story-paragraph.wv-b-lead { margin-top: var(--wvb-ln); }
body[data-page="story"] #story-main .para-en {
  display: block; font-family: var(--wvb-serif); font-size: 20.48px; font-weight: 400; line-height: 32px; letter-spacing: -.01em; color: var(--wv-text-1);
  font-variant-numeric: oldstyle-nums proportional-nums; font-feature-settings: "kern" 1, "liga" 1, "onum" 1; hyphens: manual; text-wrap: pretty;
}
body[data-page="story"] #story-main .story-paragraph.wv-b-first .para-en::first-letter {
  float: left; font-family: var(--wvb-serif); font-weight: 500; font-size: 116px; line-height: 71px; margin: 22px 8px 0 0;   /* s16b v1.2s §5.8-4：公式值 116/71/22（原 106.4/72/21 作废）；须与 G3-04 量法同版上线 */ color: var(--wv-text-1);
}
/* 段落朗读（SPEC v1.2g/h/i §5.5）：文字按钮「朗读」/「停止」，Noto Sans SC 400 12px（= 元信息档，不新增组合）；
 * 待机 t3，hover / 朗读中 t1；无底色、无边框、无下划线、无动效；焦点环沿用 §1 的 ④。
 * 文案用 ::before content（data-wvb-label 驱动），不进 .para-en 的 textContent —— app.js getContextSentence()
 * 用 paraEn.textContent 取语境句，按钮若带真实文本节点会混进生词本例句。读屏名来自 aria-label。
 * DOM：B 脚本把按钮移进 .para-en 末尾，并与最后一个词一起包进 span.wvb-tail（nowrap），不改 app.js。
 * 行高：按钮 line-height 17px、vertical-align baseline → 在 32px 行框里占 baseline −13.7 … +3.3（行框 0…32 之内），
 *       不撑高行框（有/无按钮的行等高，🌐 浏览器验）。 */
body[data-page="story"] #story-main .para-read-btn {
  position: relative; left: auto; top: auto; float: none; display: inline-block; vertical-align: baseline; width: auto; height: auto; min-width: 0; min-height: 0;
  margin: 0; padding: 0; border: 0; border-radius: 0; background: none !important; box-shadow: none; text-decoration: none;
  font-family: "WV Noto Sans SC", "WV Noto Sans SC FB", sans-serif; font-size: 12px; font-weight: 400; font-style: normal;
  line-height: 17px; letter-spacing: 0; text-transform: none; text-indent: 0; white-space: nowrap;
  color: var(--wv-text-3); opacity: 1 !important; cursor: pointer; transition: none !important;
}
body[data-page="story"] #story-main .para-read-btn::before { content: attr(data-wvb-label); }
body[data-page="story"] #story-main .para-read-btn::after { content: ""; position: absolute; }   /* 热区，尺寸见下方 1440 / 390 */
body[data-page="story"] #story-main .para-read-btn:hover,
body[data-page="story"] #story-main .para-read-btn[aria-pressed="true"] { color: var(--wv-text-1); background: none !important; }
body[data-page="story"] #story-main .wvb-tail { white-space: nowrap; }
/* ≥768：移出行流，挂到正文与注释栏之间的空白栏。段落盒右边 = 正文栏右边（1440：x 900），+24 → 左边 x=924。
 * 首行基线对齐：Newsreader 20.48 / 32 的首行基线 = (32 − 1.0×20.48)/2 + 0.735×20.48 = 20.81；
 * Noto Sans SC 12 / 17 的基线距盒顶 = (17 − 1.448×12)/2 + 1.16×12 = 13.73 → top = 7.08，取整 7（残差 0.08px，🌐 浏览器实测）。
 * 热区以文字为中心 44×44（1440：x ≈ 914…958，落在 900–1020 空白栏内）。
 * v1.2j §5.6：只在 ≥1200 挂空白栏；768–1199 与 ≤767 同为行内段尾（见下方 max-width:1199 块）。 */
@media (min-width: 1200px) {
  body[data-page="story"] #story-main .para-read-btn { position: absolute; left: calc(100% + 24px); top: 7px; }
  body[data-page="story"] #story-main .para-read-btn::after { left: 50%; top: 50%; width: 44px; height: 44px; margin: -22px 0 0 -22px; }
}
/* ≤1199（v1.2i 390 + v1.2j §5.6 768–1199）：行内段尾标记，margin-left .5em（不用 NBSP，鉴心批准的 D4 例外），
 * 与最后一个词同在 nowrap 的 span.wvb-tail 里，永不单独换行。
 * 热区：上边 = 本行行框顶（按钮盒顶在行内 y≈7.08 → top:-7px，只进本行自己的 leading，不碰上一行词框）；
 * 高 44 = 32 + 12，向下伸进段距 16（到 y≈44.1 < 48，不碰下一段）；宽 44 只向右（left:0，不压本行最后一个词）。
 * 768–1199：按钮文字宽 24（2 × 12px），热区右缘 ≤ 段右缘 + 20；正文栏 2/9 与旁注栏 10/13 之间至少隔一个 column-gap 24
 * → 热区右缘距旁注文字 ≥4px，不会盖到旁注里的生词（🌐 b-selftest §5 用 elementFromPoint 验）。 */
@media (max-width: 1199px) {
  body[data-page="story"] #story-main .para-read-btn { margin-left: .5em; }
  body[data-page="story"] #story-main .para-read-btn::after { left: 0; top: -7px; width: 44px; height: 44px; }
}
/* 中文对照：双语开时紧跟英文段，16.384/1.85 · .03em · t2 */
body[data-page="story"] #story-main .para-zh {
  font-family: var(--wvb-zh-serif); font-size: 16.384px; font-weight: 400; line-height: 30px; letter-spacing: .03em;   /* v1.2c：1.85 → 30.31 小数，改 30（1.83，仍 ≥1.8） */ color: var(--wv-text-2);
  line-break: strict; text-align: justify; text-wrap: pretty; font-style: normal;
}
body[data-page="story"] #story-main:not(.bilingual-parallel) .story-paragraph:not(.expanded) .para-zh { display: none; }
body[data-page="story"] #story-main:is(.bilingual-parallel) .para-zh,
body[data-page="story"] #story-main .story-paragraph.expanded .para-zh { display: block; max-height: none; opacity: 1; transform: none; margin-top: calc(var(--wvb-ln) * .5); }
/* 引文（v1.2d §5.3；v1.3h：字号 32→25.6 并入 T3，line-height 36 / 墨线 / 悬挂引号不变）：第 6–12 栏，Instrument Serif 25.6/36，上边强调墨线，悬挂引号 −.36em。
 * B 脚本在渲染后插入：正文原句、无 id、无生词 span、aria-hidden、pointer-events:none（不影响点词 / 双语 / TTS）。
 * 高度：1 + 15 + 36n，snap16 再补到 16 的整数倍；上下 margin 32。
 * 自证档（story-1440）：12 / 16.384 / 20.48 / 25.6 / 78.125 / 116＝6（引文并入 25.6；去掉 32/T4；标题 78.125；首字 116）。≤767 仍 25.6/32，本条不动。 */
body[data-page="story"] #story-main .wv-b-pq {
  grid-column: 6 / 13; position: relative; margin: var(--wvb-ln) 0; padding: 15px 0 0; border: 0; border-top: var(--wv-accent-rule);
  font-family: var(--wvb-disp); font-style: normal; font-weight: 400; font-size: 25.6px; line-height: 36px; letter-spacing: -.01em;
  color: var(--wv-text-1); text-wrap: balance; pointer-events: none; user-select: none; -webkit-user-select: none; quotes: none;
}
body[data-page="story"] #story-main .wv-b-pq::before { content: "\201C"; position: absolute; left: -.36em; }   /* 悬挂引号 */
/* 生词标记：全站唯一彩色 = 1px 墨绿下划线；hover / 当前词只加浅底 */
body[data-page="story"] #story-main :is(.vocab-highlight, .phrase-highlight) {
  color: var(--wv-text-1); font-weight: inherit; text-decoration: underline; text-decoration-style: solid;
  text-decoration-color: var(--wv-green); text-decoration-thickness: 1px; text-underline-offset: .2em; background: none;
}
body[data-page="story"] #story-main :is(.vocab-highlight, .phrase-highlight):is(:hover, .active, .on) { background: var(--tint); }
body[data-page="story"] #story-main .phrase-highlight .vocab-highlight { text-decoration: none; }
body[data-page="story"] #story-main.hide-target-highlight :is(.vocab-highlight, .phrase-highlight) { text-decoration: none; }
/* 旁注：第 10–12 栏，基线对齐由 js/wv-editorial-b.js 计算（高度 0，不撑行） */
body[data-page="story"] #story-main .wv-b-note { grid-column: 10 / 13; align-self: start; height: 0; color: var(--wv-text-2); }
body[data-page="story"] #story-main .wv-b-note .nt { margin: 0; }
body[data-page="story"] #story-main .wv-b-note .nt + .nt { margin-top: calc(var(--wvb-ln) * .5); }
body[data-page="story"] #story-main .wv-b-note .k { font-family: var(--wvb-serif); font-size: 16.384px; line-height: 24px; color: var(--wv-text-1);
  text-decoration: underline; text-decoration-color: var(--wv-green); text-decoration-thickness: 1px; text-underline-offset: .2em; }
body[data-page="story"] #story-main .wv-b-note .ph { margin-left: 4px; font-family: var(--wvb-sans); font-size: 12px; line-height: 24px; color: var(--wv-text-3); }
body[data-page="story"] #story-main .wv-b-note .d {
  display: block; font-family: var(--wvb-zh-serif); font-size: 16.384px; line-height: 30px; letter-spacing: .03em; text-wrap: pretty; line-break: strict;
}
html:not([data-wvb-notes="ok"]) body[data-page="story"] #story-main .wv-b-note { visibility: hidden; }
/* s16c-notes（青砚 / 衡舟 15:30，15:44 定）：注的行高固定 24 只在对齐模式生效；≤767 注在段后正常流、不对齐 → 不动。
 * 媒体条件取 wv-editorial-b.js alignNotes 的 mobile 判断（matchMedia '(max-width: 767px)'）的补集，767–768 之间的小数宽度与 js 一致（min-width:768px 会漏掉）。
 * 偏离 > 64 / 压索引时 js 给整簇加 .is-tight：隐藏音标、释义并到同一行（≤767 js 不加且会清掉，规则照旧放外面） */
@media not all and (max-width: 767px) { body[data-page="story"] #story-main .wv-b-note .nt { line-height: 24px; } }
body[data-page="story"] #story-main .wv-b-note .nt.is-tight .ph { display: none; }
body[data-page="story"] #story-main .wv-b-note .nt.is-tight .d { display: inline; margin-left: 8px; }
/* 章节分隔、章末 */
body[data-page="story"] #story-main .chapter-break { margin: var(--wvb-ln) 0 calc(var(--wvb-ln) * .5); padding-top: 12px; border-top: var(--wv-divider); background: none; }
body[data-page="story"] #story-main .chapter-break-label { margin: 0; font-family: var(--wvb-sans-sys); font-size: 12px; line-height: 18px; letter-spacing: .14em; color: var(--wv-text-3); font-weight: 400; }
body[data-page="story"] #story-main .chapter-end {
  margin: calc(var(--wvb-ln) * .5) 0 0; padding: 12px 0 0; border: 0; border-top: var(--wv-divider); background: none; text-align: left;
  font-family: var(--wvb-sans-sys); color: var(--wv-text-2);
}
body[data-page="story"] #story-main .chapter-end :is(.chapter-end-label, .chapter-meta, .chapter-hook) { margin: 0 0 calc(var(--wvb-ln) * .5); font-size: 16.384px; line-height: 30px; font-weight: 400; color: var(--wv-text-2); }
body[data-page="story"] #story-main .chapter-end .chapter-meta { font-size: 12px; letter-spacing: .14em; color: var(--wv-text-3); }
body[data-page="story"] #story-main .continue-area { display: flex; width: 100%; margin-top: calc(var(--wvb-ln) * .5); }
body[data-page="story"] #story-main .continue-input {
  flex: 1 1 auto; min-width: 0; height: 56px; box-sizing: border-box; padding: 0 20px; background: var(--wv-bg); color: var(--wv-text-1);
  border: 1px solid var(--wv-control-border); border-right: 0; font-family: var(--wvb-sans-sys); font-size: 16.384px;
}
body[data-page="story"] #story-main .continue-input::placeholder { color: var(--wv-text-3); opacity: 1; }
body[data-page="story"] #story-main .continue-btn { height: 56px; box-sizing: border-box; line-height: 24px; padding: 0 28px; background: var(--wv-btn); color: var(--wv-on-btn); border: 0; font-family: var(--wvb-sans-sys); font-size: 20.48px; font-weight: 400; }
body[data-page="story"] #story-main .end-row .btn-text { padding: 0; background: none; font-family: var(--wvb-sans-sys); font-size: 16.384px; line-height: 24px; font-weight: 400; color: var(--wv-text-2); }
/* 「— 完 —　词境」+ 生词索引：同一行，同 .end 样式与 ① 顶线 */
body[data-page="story"] #story-main .wv-b-end {
  grid-column: 3 / 9; margin-top: calc(var(--wvb-ln) * .5); padding-top: 12px; border-top: var(--wv-divider);
  font-family: var(--wvb-sans); font-size: 12px; line-height: 18px; letter-spacing: .14em; text-transform: uppercase; font-variant-numeric: tabular-nums; color: var(--wv-text-3);
}
body[data-page="story"] #story-main .wv-b-end .wv-b-end-zh { font-family: "WV Noto Serif SC", "WV Noto Serif SC FB", serif; }
body[data-page="story"] #story-main .wv-b-end.ix { grid-column: 10 / 13; padding-top: 14px; text-wrap: balance; }
/* ---------- v1.2n/o/p §5.7 G3：浮动工具条 .reader-toolbar 去掉 ----------
 * 工具条整条 [hidden]（index.html），这里再 display:none 兜底。按衡舟裁定 id 一个不删：#footer-fontsize / #footer-copy / #copy-label /
 * #story-more-menu 留在条里（都已不可见）；#read-btn → 顶栏；#rcb-en/#rcb-bilingual（.tb-seg）+ #aa-menu → 顶栏「阅读设置」下；
 * 复制英文 / 复制双语 / #story-menu-pdf / #footer-regen / #reader-back-btn → 「完」下文字按钮行 #wv-b-endrow；#footer-vocab / #footer-fav → 故事页页脚。 */
body[data-page="story"] .reader-toolbar, body[data-page="story"] .reader-toolbar[hidden] { display: none !important; }
body[data-page="story"] .scroll-top { display: none !important; }
body[data-page="story"] #footer-fontsize { display: none !important; }

/* 顶栏「朗读全文 / 停止」#read-btn（知微 01:05 第九节 1 + v1.2p）：样式与段落朗读按钮同档 —— Noto Sans SC 12/400、t3，hover 和朗读中 t1；
 * v1.2r：文案直接写在 DOM 文本节点（wv-editorial-b.js 按全文朗读状态写 textContent「朗读全文」/「停止」+ aria-pressed + aria-label，可见文字 = 可访问名），不用 ::before content；
 * wv-shell setReadBtn 若短暂写进图标 + .read-label（子元素），在 B 隐藏，随即被改回纯文本。热区 ::after 撑到 ≥44×44、不占布局；与「阅读设置」间隔 24（.nav-more gap 24），基线对齐（align-items:baseline）。
 * 12×400 已是首屏现有组合（日期、tab、段落朗读按钮），不新增组合。首页不显示。 */
body:is([data-page="home"], [data-page="story"]) .nav #read-btn.wv-b-readall {
  position: relative; display: inline-block; width: auto; height: auto; min-width: 0; min-height: 0; margin: 0; padding: 0; border: 0;
  background: none !important; box-shadow: none; gap: 0; white-space: nowrap; cursor: pointer;
  font-family: "WV Noto Sans SC", "WV Noto Sans SC FB", sans-serif; font-size: 12px; line-height: 18px; font-weight: 400; letter-spacing: 0; color: var(--wv-text-3);
}
body:is([data-page="home"], [data-page="story"]) .nav #read-btn.wv-b-readall > * { display: none !important; }
body:is([data-page="home"], [data-page="story"]) .nav #read-btn.wv-b-readall::after { content: ""; position: absolute; left: 50%; top: 50%; width: 100%; min-width: 44px; height: 44px; transform: translate(-50%, -50%); padding: 0 6px; }
body:is([data-page="home"], [data-page="story"]) .nav #read-btn.wv-b-readall:hover,
body:is([data-page="home"], [data-page="story"]) .nav #read-btn.wv-b-readall[aria-pressed="true"] { color: var(--wv-text-1); }
/* s16c 衡舟 15:53：顶栏「朗读全文」#read-btn 与「阅读设置」#wv-b-set 改白名单 —— 只在 story 显示，其余页面（含以后新增的 data-page）一律隐藏。
 * 依据（只读核实）：body[data-page] 只由 app.js:1346 goPage 写入（值 = 存在的 #page-* id：home / story / history / reader / vocab / portal；review → goReview → goPage('history')，wv-shell.js:208–212），
 *   及 wv-editorial-b.js:35 initPage（同一来源，index.html:144 已给 home → 实际不触发）。
 *   toggleRead（app.js:4903）只朗读 currentPortalScene || currentStory；名著片段 randomPortal（app.js:1406）与粘贴阅读 startReader（app.js:5372）都 goPage('story') 在故事页呈现，
 *   离开 story 时 goPage 清 currentPortalScene（app.js:1353–1354）→ 其他页只会读残留故事。#aa-menu 的双语 / 高亮作用于 #story-main、字号作用于 .story-paragraph（style.css:547–548），
 *   外观在 #more-btn（index.html:233–236，只在 home / story 隐藏，editorial-b.css:107）与书库 #history-more-btn（index.html:511、518–520；复习视图下它被 wvSyncReviewChrome 隐藏，#more-btn 仍在）另有入口 → 隐藏不丢入口。
 * !important 必需：527 行 body:is(home, story) .nav #read-btn.wv-b-readall { display:inline-block } 特异度 (1,3,1) 高于本条 (1,2,1)，home 要靠 !important 才隐藏（同原 530 行做法）。
 * 不写恢复规则：story 上本条不匹配，两按钮沿用原有 display（#read-btn 527 行 inline-block；#wv-b-set 为 button UA 默认）。替换原 104 行与 15:45 的 home+history 列举规则。 */
body:not(:is([data-page="story"])) .nav :is(#read-btn, #wv-b-set) { display: none !important; }

/* 「阅读设置」#aa-menu：挂在顶栏「阅读设置」下面（.nav-more 是 position:relative），向下展开；只放 英文/双语、字号、高亮目标词、外观（v1.2p）。 */
body[data-page="story"] .nav #aa-menu { top: calc(100% + 16px); bottom: auto; right: 0; min-width: 256px; letter-spacing: 0; text-transform: none; font-family: var(--wvb-sans-sys); }   /* 面板内中文不在 WV 子集里 → 整块走系统中文栈，避免一行内字形混排（同原工具条） */
body[data-page="story"] .nav #aa-menu .tb-seg { display: flex; margin: 0 8px 8px; padding: 0; gap: 0; background: none; }
body[data-page="story"] .nav #aa-menu .tb-seg .tb-btn {
  flex: 1; height: auto; min-height: 32px; padding: 0 16px; background: none !important; box-shadow: none !important;
  font: inherit; font-weight: 400; color: var(--wv-text-2);
}
body[data-page="story"] .nav #aa-menu .tb-seg .tb-btn + .tb-btn { border-left: var(--wv-divider); }
body[data-page="story"] .nav #aa-menu .tb-seg .tb-btn[aria-pressed="true"] { color: var(--wv-text-1); }
body[data-page="story"] .nav #aa-menu .switch-item[aria-checked="true"] .switch { background: var(--wv-text-1); border-color: var(--wv-text-1); }   /* 绿只给生词：开关不用 --accent */

/* 「— 完 —」下的一行文字按钮 #wv-b-endrow（v1.2o）：
 * <button lang="zh-Hans">，Noto Sans SC 400 12 / 32，t2，hover t1；无下划线 / 框 / 底色 / 图标 / 动效；:focus-visible 走全局 2px t1 offset 3。
 * 距「完」32、距下方页脚分隔线 48；1440 与 768–1199 在正文栏（3/9、2/9）内居中，390 全宽居中；column-gap 24，390 折行 row-gap 12（32+12 = 44），每项 nowrap。
 * 热区 ::after：上下各 6、左右各 12（32+12 = 44 高；宽 = 文字宽 + 24 ≥ 44：最短「复制英文」4×12 = 48 → 72）。
 *   左右各 12 = column-gap 24 的一半 → 相邻两项热区正好相接；折行时上下各 6 = row-gap 12 的一半 → 上下两行热区正好相接，都不重叠。
 *   行容器不设 overflow，::after 不被裁；按钮 position:relative。
 * 块高 + 外边距：1 行 32 + 32 + 48 = 112 = 7×16；2 行 32+12+32 + 80 = 156 → snap16 补 4（js SNAP_STORY 覆盖 #story-main 直接子元素）。
 * 停放位：首屏前 / 骨架屏 / 传送门（无「完」）时本行留在 #story-main 之后的停放位；骨架屏时隐藏。 */
body[data-page="story"] .wv-b-endrow {
  grid-column: 3 / 9; display: flex; flex-wrap: wrap; justify-content: center; align-items: flex-start; column-gap: 24px; row-gap: 12px;
  margin: 32px 0 48px; padding: 0; text-align: center;
}
body[data-page="story"] #story-main .wv-b-end.ix { grid-row: span 2; }   /* 1440 / 768–1199：生词索引占「完」与本行两行，本行距离从「完」算起，不被索引高度推开 */
body[data-page="story"] #story-main .wv-b-endrow + .chapter-end { margin-top: 0; }   /* grid 里外边距不折叠：48 就是到章末分隔线的距离 */
body[data-page="story"] .story-main:has(.story-skeleton) + .wv-b-endrow { display: none; }
body[data-page="story"] .wv-b-endrow .wv-b-ea {
  position: relative; display: inline-block; width: auto; height: 32px; min-width: 0; min-height: 0; margin: 0; padding: 0; border: 0; border-radius: 0;
  background: none !important; box-shadow: none; text-decoration: none; text-transform: none; white-space: nowrap; cursor: pointer;
  font-family: "WV Noto Sans SC", "WV Noto Sans SC FB", sans-serif; font-size: 12px; line-height: 32px; font-weight: 400; letter-spacing: 0; color: var(--wv-text-2);
}
body[data-page="story"] .wv-b-endrow .wv-b-ea::after { content: ""; position: absolute; top: -6px; right: -12px; bottom: -6px; left: -12px; }
body[data-page="story"] .wv-b-endrow .wv-b-ea:hover { color: var(--wv-text-1); }
body[data-page="story"] .wv-b-endrow .wv-b-ea[hidden] { display: none !important; }

/* 故事页页脚 #wv-b-sfoot（v1.2p + 知微 01:05 第九节 3）：只有「本篇词表」#footer-vocab、「收藏」#footer-fav 两个文字链接；全局生词本走导航「词库」。
 * 12px 400 t2，hover t1，无下划线 / 底色 / 图标 / 动效；v1.2q：文案直接写在 DOM（span.wv-b-sfoot-t），不用 ::after content（#footer-vocab 与 aria-label「本篇词表」一致；
 * #footer-fav 的 aria-label 由 app.js updateFavoriteBtn 切换「收藏故事 / 取消收藏」，都包含可见文字「收藏」，WCAG 2.5.3）。
 * 顶边 = 分隔线 ①；1 + 15 + 24 + 40 = 80 = 5×16。链接落在正文栏起点（与 #story-main 同一 12 栏网格）。 */
body[data-page="story"] .wv-b-sfoot {
  display: grid; grid-template-columns: repeat(12, 72px); column-gap: 24px; width: 1128px; max-width: none; margin: 0 auto; box-sizing: border-box;
  padding: 15px 0 40px; border-top: var(--wv-divider); background: none;
}
body[data-page="story"] .wv-b-sfoot-in { grid-column: 3 / 9; display: flex; flex-wrap: wrap; gap: 0 24px; }
body[data-page="story"] .wv-b-sfoot :is(#footer-vocab, #footer-fav) {
  position: relative; width: auto; height: 24px; min-width: 0; min-height: 24px; padding: 0; margin: 0; border: 0; border-radius: 0; background: none !important; box-shadow: none; gap: 0;
  font-family: "WV Noto Sans SC", "WV Noto Sans SC FB", sans-serif; font-size: 12px; line-height: 24px; font-weight: 400; color: var(--wv-text-2);
  letter-spacing: 0; text-transform: none; text-decoration: none; cursor: pointer; transition: none !important;
}
body[data-page="story"] .wv-b-sfoot :is(#footer-vocab, #footer-fav) :is(svg, .wv-icon, .ico) { display: none !important; }
body[data-page="story"] .wv-b-sfoot :is(#footer-vocab, #footer-fav):hover,
body[data-page="story"] .wv-b-sfoot :is(#footer-vocab, #footer-fav):focus-visible { color: var(--wv-text-1); text-decoration: none; background: none !important; }
body[data-page="story"] .wv-b-sfoot #footer-fav:is([aria-pressed="true"], .active) { color: var(--wv-text-1); }
body[data-page="story"] .wv-b-sfoot :is(#footer-vocab, #footer-fav)[hidden] { display: none !important; }
body[data-page="story"] .wv-b-sfoot .wv-b-sfoot-t { display: inline; font: inherit; color: inherit; }

/* v1.2q §5.7：ICP 备案号全局常驻（#wv-b-icp 在 </main> 前，跟在当前 .page 之后）。12/400 --t3（= --wv-text-3），hover t1；
 * 热区 24px 高（守望真实点击 ≥24）；不计入首屏 ≤6、页脚链接 ≤3。字体沿用首页页脚原组合 --wvb-sans-sys 12/400，不新增组合。 */
.wv-b-icp { display: flex; justify-content: center; width: 1128px; max-width: calc(100% - 64px); margin: 0 auto; padding: 8px 0 24px; box-sizing: border-box; background: none; border: 0; }
.wv-b-icp .v2-footer-legal {
  display: inline-flex; align-items: center; min-height: 24px; height: 24px; padding: 0; margin: 0; border: 0; border-radius: 0; background: none; box-shadow: none;
  font-family: var(--wvb-sans-sys); font-size: 12px; line-height: 24px; font-weight: 400; letter-spacing: .04em; color: var(--wv-text-3); text-decoration: none; white-space: nowrap;
}
.wv-b-icp .v2-footer-legal:hover { color: var(--wv-text-1); text-decoration: none; background: none; }
.wv-b-icp .v2-footer-legal:focus-visible { outline: none; box-shadow: var(--wv-ring); color: var(--wv-text-1); }
/* v1.2r：7 个页面统一居中（首页也居中，不跟首页栅格左对齐）；在 </main> 最后 = 页面最底部 */
@media (max-width: 767px) {
  .wv-b-icp { width: auto; max-width: none; margin: 0 20px; }
}
@media print { .wv-b-icp { display: none !important; } }

@media (min-width: 768px) and (max-width: 1199px) {
  body[data-page="story"] .story-container { width: auto; padding-left: 32px; padding-right: 32px; }
  body[data-page="story"] #story-main { grid-template-columns: repeat(12, minmax(0, 1fr)); }
  body[data-page="story"] #story-main > *, body[data-page="story"] #story-main .story-paragraph, body[data-page="story"] #story-main .wv-b-end, body[data-page="story"] .wv-b-endrow { grid-column: 2 / 9; }
  body[data-page="story"] .wv-b-sfoot { grid-template-columns: repeat(12, minmax(0, 1fr)); width: auto; padding-left: 32px; padding-right: 32px; }
  body[data-page="story"] .wv-b-sfoot-in { grid-column: 2 / 9; }
  body[data-page="story"] #story-main .wv-b-meta2 { grid-column: 1 / 13; grid-row: auto; padding: 0 0 calc(var(--wvb-ln) * .5); }
  body[data-page="story"] #story-main :is(.story-title, .story-subtitle, .wv-b-by, .story-details, .chapter-nav) { grid-column: 1 / 13; grid-row: auto; }
  body[data-page="story"] #story-main .story-title { font-size: 62.5px; line-height: 62px; }
  body[data-page="story"] #story-main .wv-b-note, body[data-page="story"] #story-main .wv-b-end.ix { grid-column: 10 / 13; }
  body[data-page="story"] #story-main .wv-b-pq { grid-column: 6 / 13; }
}
@media (max-width: 767px) {
  body[data-page="story"] .story-container { width: auto; padding: 0 20px; }   /* v1.2o：底部 3 行挪到页脚 #wv-b-sfoot */
  body[data-page="story"] #story-main { display: block; margin-top: var(--wvb-ln); }
  body[data-page="story"] #story-main > .story-head { display: block; }
  body[data-page="story"] #story-main .wv-b-meta2 { padding: 0 0 calc(var(--wvb-ln) * .5); }
  body[data-page="story"] #story-main .wv-b-no { display: none; }
  body[data-page="story"] #story-main .story-title { font-size: 50px; line-height: 52px; }
  body[data-page="story"] #story-main .wv-b-by { gap: 6px; letter-spacing: .12em; }
  body[data-page="story"] #story-main .wv-b-note { height: auto !important; margin: 0 0 calc(var(--wvb-ln) * .5); visibility: visible !important; }
  body[data-page="story"] #story-main .wv-b-note .nt { margin-top: 0 !important; }
  body[data-page="story"] #story-main .wv-b-note .nt + .nt { margin-top: calc(var(--wvb-ln) * .5) !important; }
  body[data-page="story"] #story-main .wv-b-pq { margin: var(--wvb-ln) 0; font-size: 25.6px; line-height: 32px; }   /* Q18：满宽（随 20px 页边），上墨线 + padding-top 15、悬挂 −.36em 沿用基础规则；上下各 1 行 */
  body[data-page="story"] .story-container { padding-bottom: 0; }
  body[data-page="story"] .wv-b-sfoot { display: block; width: auto; margin: 0 20px; padding: 15px 0 24px; }   /* v1.2q：1+15+24+24 = 64 = 4×16；给 tab 栏的底部留白挪到下面的 #wv-b-icp（ICP 在页面最底，到底时 tab 栏会显示，不能盖住它） */
  body[data-page="story"] .wv-b-icp { padding-bottom: calc(56px + 24px + env(safe-area-inset-bottom, 0px)); }   /* 8+24+56+24 = 112 = 7×16（不含安全区） */
}
/* s16b v1.2u ③（知微 §10 / 青砚）：≤767 章节条放不下时做横向滑窗，不折行。
   隐藏滚动条但保留滚动（触摸 / 触控板 / 键盘 Tab 聚焦时浏览器自动滚入）；当前章用 scroll-snap-align + scroll-initial-target 在建条时就停在可视区内，
   不改 app.js（updateChapterNav 每次 outerHTML 重建整条，initial target 每次重新生效）。容器内滚动不改变任何盒的布局位置 → 不计 CLS。
   scroll-initial-target 只有 Chromium 133+；s16c 05:56 起其他浏览器由 js/wv-editorial-b.js chapNavReveal 兜底（只改条的 scrollLeft），不再只靠 chapterNavWindow。 */
@media (max-width: 767px) {
  /* s16c 衡舟 05:56 C2（知微 §10 并集）：章节条必须是单行滑窗，条自身在容器内横向滚动；页面不得横向滚动。
     容器链 min-width:0 / max-width:100%，条 width:100% + box-sizing → 宽度恒等于标题区，多出的章只在条内滚；
     overflow-x:auto 显式写在本条（特异性 1-2-1，> style.css .segmented 0-1-0），scrollbar 隐藏但保持可滚动（触摸 / 触控板 / Shift+滚轮），
     按钮仍是 <button>，Tab 聚焦时浏览器把它滚入条可视区（键盘可达）。当前章：scroll-snap + scroll-initial-target（Chromium 133+），
     其它浏览器由 js/wv-editorial-b.js chapNavReveal 只改条的 scrollLeft 兜底（不调 scrollIntoView，页面不滚）。纯文字，样式沿用 v1.2u（无填充 / 边框 / 图标，当前章只换色 + 下划线）。 */
  body[data-page="story"] .story-container, body[data-page="story"] #story-main, body[data-page="story"] #story-main > .story-head { min-width: 0; max-width: 100%; }
  body[data-page="story"] #story-main .chapter-nav {
    display: flex; flex-wrap: nowrap; white-space: nowrap; box-sizing: border-box; width: 100%; min-width: 0;
    max-width: 100%; overflow-x: auto; overflow-y: hidden; scrollbar-width: none; -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain; scroll-snap-type: x proximity; scroll-padding-inline: 0;
  }
  body[data-page="story"] #story-main .chapter-nav::-webkit-scrollbar { display: none; }
  body[data-page="story"] #story-main .chapter-nav .seg-item { scroll-snap-align: center; flex: 0 0 auto; }
  body[data-page="story"] #story-main .chapter-nav .seg-item.active { scroll-initial-target: nearest; }
}
/* s16c 托盘 CLS 顶对齐：分档等效内容高（见 .v2-hero 处注释；标题换行数变化时偏差只影响留白，不影响「托盘只往下长」） */
@media (min-width: 768px) and (max-width: 1199px) { body[data-page="home"] #page-home .v2-hero { --wvb-hero-c: 624px; padding-top: 32px; } }   /* 整数基线：横屏代表 1024×768 实算 32 */
@media (min-width: 768px) and (max-width: 1199px) and (orientation: portrait) { body[data-page="home"] #page-home .v2-hero { padding-top: 160px; } }   /* 竖屏代表 768×1024 实算 160 */
@media (max-width: 389px) { body[data-page="home"] #page-home .v2-hero { --wvb-hero-c: 640px; padding-top: 0; } }   /* 代表 375×667 实算 max(0, (544−640)/2) = 0（内容高于 hero 可用高）*/
/* s16c 05:41：支持 round() 的浏览器用公式覆盖上面的整数基线（结果恒为 32 的整数倍）；不支持的浏览器停在整数基线 → 都不出 .5。
   公式 = max(0, rounddown((rounddown(hero 可用高, 32) − --wvb-hero-c) / 2, 32))；推导与各档取值见 s15b-work/TRAY-CLS-OPTIONS.md §A。 */
@supports (padding-top: round(down, 1px, 1px)) {
  body[data-page="home"] #page-home .v2-hero { padding-top: max(0px, round(down, calc((round(down, calc(100vh - var(--wvb-top-h)), var(--wvb-ln)) - var(--wvb-hero-c)) / 2), var(--wvb-ln))); }
  @media (max-width: 767px) {
    body[data-page="home"] #page-home .v2-hero { padding-top: max(0px, round(down, calc((round(down, calc(100svh - 60px - 56px), var(--wvb-ln)) - var(--wvb-hero-c)) / 2), var(--wvb-ln))); }
  }
}

/* ---------- s16c NO-GO（墨川 07:47，V2U-VERIFY §13.11）：P7 焦点环 / G5 CLS / G6 热区 / G8 由 js/wv-genfb.js 处理 ---------- */
/* G5 首屏：见 index.html 内联 RO 注释；只在首轮 RO 回调前存在（同一渲染周期内撤销，不会被绘制出来） */
html.wv-b-snapwait body[data-page="home"] #page-home > * { visibility: hidden; }
/* G5 切页：首页 / 故事页各用自己的日期节点（js/wv-editorial-b.js .wv-b-date-s = 故事页），切页时日期是新出现的盒，不是移动 / 变宽的盒 */
body:is([data-page="home"], [data-page="story"]) .nav .wv-b-date-s { display: none; }
body[data-page="story"] .nav .wv-b-date-s:not([hidden]) { display: inline; }
body[data-page="story"] .nav .wv-b-date:not(.wv-b-date-s) { display: none; }
@media (max-width: 767px) {
  /* G5 切页 390：.nav-more 盒占满品牌右侧（内容仍靠右，justify-content:flex-end 不变），两页盒的左缘相同 → 子项不因盒宽变化而移动 */
  body:is([data-page="home"], [data-page="story"]) .nav .nav-more { flex: 1 1 auto; min-width: 0; }
}
/* P7：章节条是滚动容器（overflow 非 visible），焦点环 = 2px + offset 3px 伸出按钮 5px 被裁。
   条四周加 ring 余量 padding，再用等量负 margin 抵消 → 章名位置、条的占位（上 16 / 下 32）、条高不变，焦点环落在 padding 盒内不被裁。
   2px = --wv-focus-ring 的线宽（简写 token 无法拆出宽度，同 L21 一起改）。 */
body[data-page="story"] #story-main .chapter-nav {
  --wvb-rr: calc(var(--wv-focus-offset) + 2px);
  padding: var(--wvb-rr);
  /* ≥768（grid，不折叠）下 32px = style.css L539 .chapter-seg { margin: 0 0 32px }（冻结文件，无变量可引用）；上 = 本文件 L383 */
  margin: calc(var(--wvb-ln) * .5 - var(--wvb-rr)) calc(-1 * var(--wvb-rr)) calc(32px - var(--wvb-rr));
  scroll-padding-inline: var(--wvb-rr);
}
@media (max-width: 767px) {
  /* ≤767 #story-main 不是 grid，下 32 与下一段的 margin-top 32 折叠（max=32）→ 负 margin 参与折叠：32 + (-5) + padding 5 = 原 32。
     衡舟 08:5x 约束 1：折叠只在本外层规则处理，style.css（冻结）不改 */
  body[data-page="story"] #story-main .chapter-nav { width: calc(100% + 2 * var(--wvb-rr)); max-width: calc(100% + 2 * var(--wvb-rr)); margin-bottom: calc(-1 * var(--wvb-rr)); }
  /* s16c R3 取整候选（衡舟 10:15 ①，左右余量 5→6）已回退：衡舟 11:21 定为 6px 无收益、按最小改动原则改回原值 5（--wvb-rr-x: var(--wvb-rr)），
     R3 焦点环判定改为 0.5px 容差（390/320 环右缘 360.44 对裁剪边 360）。11:47 v4.1 R3 复核：scrollY=0 时条高 / 正文 / 章名位置与 6px 版一致，
     只差章节栏右缘 1px（见 evidence/s16c-g5/browser-qyfix41-r3-1147/R3-SUMMARY-qyfix41-1147.md）。下面规则保留 --wvb-rr-x 变量写法，值即原值 5。 */
  body[data-page="story"] #story-main .chapter-nav { --wvb-rr-x: var(--wvb-rr); padding-left: var(--wvb-rr-x); padding-right: var(--wvb-rr-x); width: calc(100% + 2 * var(--wvb-rr-x)); max-width: calc(100% + 2 * var(--wvb-rr-x)); margin-left: calc(-1 * var(--wvb-rr-x)); margin-right: calc(-1 * var(--wvb-rr-x)); scroll-padding-inline: var(--wvb-rr-x); }
}
/* G6：故事页品牌「词境」/「返回」/「阅读设置」只扩点击区（透明 ::after，居中，≥44×44），不改可见盒与排版（同 #read-btn.wv-b-readall::after） */
body[data-page="story"] .nav button.nav-brand,
body[data-page="story"] .story-back-row .story-back,
body[data-page="story"] .nav .wv-b-set { position: relative; }
body[data-page="story"] .nav button.nav-brand::after,
body[data-page="story"] .story-back-row .story-back::after,
body[data-page="story"] .nav .wv-b-set::after {
  content: ""; position: absolute; left: 50%; top: 50%; width: 100%; min-width: 44px; height: 44px; transform: translate(-50%, -50%);
}

/* ---------- s16c 青砚 09:43 B 备选②（衡舟 10:14 定稿合并）：失败行不被固定底栏挡住 ----------
   ≤767：html scroll-padding-bottom = 底栏高 56 + 8 + 安全区；只影响 scrollIntoView 的停靠位置，不参与布局（无 layout shift）。
   失败态出现时若失败行下缘在底栏顶之下，js/wv-genfb.js showFail 每个失败会话只做一次 scrollIntoView({block:'nearest', behavior:'instant'})，不移动焦点。 */
@media (max-width: 767px) {
  html[data-wv-layout="b"]:has(body[data-page="home"]) { scroll-padding-bottom: calc(56px + 8px + env(safe-area-inset-bottom, 0px)); }
}

/* ---------- s16c 衡舟 10:15 ③ G5 footer CLS（CLS 须为 0）----------
   首页卡片（继续阅读 / 先读一篇示例 / 今日复习）在 snapwait 撤销后才由 wvRenderHomeCards 插入，页脚被推下 209（390）/ 265（1440），首帧它有 2 / 9px 在视口内 → 记 layout-shift。
   B 首页页脚在 html[data-wvb-cards="done"] 之前 visibility:hidden（不改布局，不产生位移源）；js/wv-editorial-b.js 包 wvRenderHomeCards，渲染完（同一任务）置 done，1s 内未置则强制置 done + console.warn（衡舟 10:33）
   → 页脚在终位出现 = 新出现，不是位移。无 JS：index.html noscript 强制可见。L338 的 margin-top:56 规则保留。回滚：删本条 + JS 一段 + noscript 一行。 */
html[data-wv-layout="b"]:not([data-wvb-cards="done"]) body[data-page="home"] #page-home > .site-footer { visibility: hidden; }

/* ---------- s16c 青砚旧问题 b/c（≤359 顶栏 / 署名行；故事页难度行）---------- */
@media (max-width: 359px) {
  /* b-1 320 顶栏折行：.nav-more 为 flex 1 1 auto + min-width:0（L66x），子项可被压窄；#wv-b-set「阅读设置」没有 nowrap → 被压成两行（阅读 / 设置），顶栏变高。
     故事页 ≤767 内容 = 品牌 ≈41 + 16 + 日期 ≈84 + 24 + 朗读全文 48 + 24 + 阅读设置 ≈52 ≈ 289 > 320−40 = 280（静态估算，浏览器确认）。
     顶栏三项 nowrap；故事页仅 ≤359 的 .nav-more 间隔 24 → 16（≈273 ≤ 280）。G3-10「故事页 24」按 390 量，不受影响。 */
  body:is([data-page="home"], [data-page="story"]) .nav .nav-more > :is(.wv-b-date, #read-btn, .wv-b-set) { white-space: nowrap; }   /* #aa-menu 等弹层不受影响 */
  body[data-page="story"] .nav .nav-more { gap: 16px; }
  /* b-2 320 元信息（署名行 .wv-b-by：WORDS · NEW WORDS · MIN，大写 + nowrap + flex）比正文栏宽约 5px：flex 项不收缩 → 溢出栏右缘。
     ≤359 间隔 6 → 4、字距 .12em → .1em（约省 8 + 6 ≈ 14px），行高 / 盒高 48 不变。 */
  body[data-page="story"] #story-main .wv-b-by { gap: 4px; letter-spacing: .1em; }
}
/* c 故事页难度行「难度：探险者 · 换一个」（v2-smart-input.js renderStoryLine，#v2u-story-diff-slot）：v2-smart-input.css L15 font: 400 13px var(--font-ui)（= 旧 'Inter' 族），
   L16 .v2u-story-diff b { font-weight: 600 } → 「探险者」粗体，且整行要旧 'Inter' face（v2-theme.css L250 描述符 400 600 = G3-03「Inter 400 600 normal」的来源之一）。
   B 故事页内改回 B 栈 + 400；字号 / 颜色 / 间距不动；V2U（无 data-wv-layout="b"）不受影响。 */
html[data-wv-layout="b"] body[data-page="story"] #v2u-story-diff-slot .v2u-story-diff { font-family: var(--wvb-sans-sys); }
html[data-wv-layout="b"] body[data-page="story"] #v2u-story-diff-slot .v2u-story-diff b { font-weight: 400; }
/* s16c 衡舟 15:45（GATE-RESOLUTION-1324 旧 Inter；INTER-ELEMENTS #13–14）：故事页难度行「调整」摘要的 2 个文字元素 span.v2-more-label「调整」/ span.v2-more-meta
   原继承 style.css:1088 .v2-more-sum 的 var(--v2-label-font)（旧 'Inter'）→ 改 B 栈，同上一条难度行用 --wvb-sans-sys（中文不在 WV 子集，走系统中文栈）；字号 / 字重 / 颜色不动；v2-theme.css 不动。 */
html[data-wv-layout="b"] body[data-page="story"] #home-more-options > .v2-more-sum > :is(.v2-more-label, .v2-more-meta) { font-family: var(--wvb-sans-sys); }

/* ---------- s16c 青砚 / 衡舟 10:14 B 页颗粒 ---------- */
/* s16c 衡舟 10:14 ②：SPEC v1.2y（L2/L202）B 全页纯色底 #FFFFFF / #0E0F0F、无颗粒。颗粒只由 style.css:973–977 body[data-page="home"]::before 画（var(--v2-bg-grain)），
   v2-theme.css L90（:root）/ L193（[data-theme="dark"]）不改；本条 0-1-1 > 0-1-0（与位置无关），亮暗两套都被覆盖。只在 html[data-wv-layout="b"] 下，V2U 不受影响。 */
html[data-wv-layout="b"] { --v2-bg-grain: none; }

/* ---------- s16c 衡舟 11:22 genfb：生成中 disabled → aria-disabled（SPEC §5.9）----------
   js/wv-genfb.js 生成中不再加原生 disabled，改加 aria-disabled="true"（按钮不失焦）。外观与原 L286 `.loading:disabled` 一条完全相同：实色 --wv-btn / --wv-on-btn、opacity 1、光标 progress。
   (2,4,2) > v2-smart-input.css:44 `#page-home #generate-btn[aria-disabled="true"]:not(.v2u-si-blocked)`（2,2,0，那条光标是 pointer）。尺寸 / 布局属性一条不写（CLS 0）。L286 保留不动。 */
html[data-wv-layout="b"] body[data-page="home"] #page-home #generate-btn.loading[aria-disabled="true"] { opacity: 1; background: var(--wv-btn); color: var(--wv-on-btn); cursor: progress; }

/* r5 N1 Option A（衡舟 17:40 规则 1–4；js 见 wv-editorial-b.js 的 deferNotes / applyDefer）
 * ≥768：本段放不下又不能顺延一段（或顺延后偏离 > 64 / 下一段也放不下）的注不出旁注（data-wvb-off）；生词高亮与点开照旧。
 * ≤767：js 每次先还原（restoreNotes），这里也不生效，内联展开保持原样（规则 4）。
 * 可选：悬停 / 聚焦生词时其旁注转 t1（data-wvb-hot；--wv-text-1 亮 / 暗两套都已定义，不改冻结文件）。
 * data-wvb-tm：js 量收紧高时临时加的属性，样式同 .is-tight。 */
@media not all and (max-width: 767px) {
  body[data-page="story"] #story-main .wv-b-note .nt[data-wvb-off] { display: none !important; }
  body[data-page="story"] #story-main .wv-b-note .nt[data-wvb-hot] :is(.k, .ph, .d) { color: var(--wv-text-1); }
}
body[data-page="story"] #story-main .wv-b-note .nt[data-wvb-tm] .ph { display: none; }
body[data-page="story"] #story-main .wv-b-note .nt[data-wvb-tm] .d { display: inline; margin-left: 8px; }

/* ---------- s16c r5 N4：故事页页脚「本篇词表」#footer-vocab /「收藏」#footer-fav 点击区 ≥44×44 ----------
   同 G6（上方 .story-back::after）：透明 ::after 居中扩区，可见盒仍 24 高、文字 / 间距 / 栅格不变（无 layout shift）。
   本篇词表 ≈48 宽 → 扩区 48×44；收藏 ≈24 宽 → 44×44（左右各外扩 10，小于两按钮间距 24，不相互重叠）；
   上下各外扩 10，小于 .wv-b-sfoot 上内边距 15，不进分隔线以上。
   ≤767：故事页底部 tab 为 fixed（L117–152，滚到底时显示），html scroll-padding-bottom 同首页 L722 的值，键盘聚焦 / scrollIntoView 时页脚不停在 tab 下面；不参与布局。 */
body[data-page="story"] .wv-b-sfoot :is(#footer-vocab, #footer-fav)::after {
  content: ""; position: absolute; left: 50%; top: 50%; width: 100%; min-width: 44px; height: 44px; transform: translate(-50%, -50%);
}
@media (max-width: 767px) {
  html[data-wv-layout="b"]:has(body[data-page="story"]) { scroll-padding-bottom: calc(56px + 8px + env(safe-area-inset-bottom, 0px)); }
}

/* ---------- s16c r30 G2 / N3 方案 A（衡舟 13:28 重启：产品最小 diff；墨川 staged，未合并）：首页「清空输入」.btn-icon.input-clear 的焦点环 ----------
   R30 ring_js 读 .input-wrapper outline；L58 环在按钮自身 → 探针误判无环。方案 A：环画在 .input-wrapper（:has(> .input-clear:focus-visible)，同 token --wv-focus-ring / --wv-focus-offset），
   按钮自身环用 (1,4,1) !important 关掉（胜 L58 的 0,2,1 !important）→ 单层环。只写 outline / box-shadow，CLS 0。
   故事页 preset-row「清空」button.btn-text（index.html ~L411）不改：走 L58 全站 :focus-visible，editorial-b/style 无针对该按钮的 outline:none。 */
body[data-page="home"] #page-home .input-wrapper:has(> .input-clear:focus-visible) { outline: var(--wv-focus-ring); outline-offset: var(--wv-focus-offset); }
body[data-page="home"] #page-home .input-wrapper > .input-clear:focus-visible { outline: none !important; box-shadow: none !important; }
