/* ============================================================================
 * zzerfu-about.css — 「关于」页：一叠素描纸，跟着滚动连贯地翻
 * ----------------------------------------------------------------------------
 *   · 单页。没有左半张、没有书脊、没有垫页 —— 一屏只摊一张纸；
 *   · 一页 = 一章。字不是一次铺满：一支羽毛笔顺着正文把字一个一个写上去；
 *   · 换页发生在章与章之间：一块橡皮从上往下把这一页擦干净，下一页接着写；
 *   · 纸张是素描质感：米白纸、铅笔灰线、手绘双层框、斜向排线、纸纹颗粒。
 *
 * 结构（class 与 about.php 对齐）：
 *   .abn-track  滚动轨道，高度 = (时间线 + 1) × 一屏
 *   .abn-stage  粘在顶上一屏不动
 *   .abn-book   纸堆的托盘（透视容器）
 *   .abn-sheet  一张纸（封面 / 章 / 结尾），按 DOM 顺序叠放
 *   .abn-pad    纸面内容
 *   .abn-seg    一段话，--w（写到第几个字）驱动段内逐字显影
 *   .abn-ink    一个字，--i 是它在段里的序号
 *   .abn-eraser 擦页的块状胶擦，沿文字逐行往返
 *   .abn-quill  羽毛笔，笔尖钉在正在写的那个字后面
 *
 * 这里的动画几乎都不写 keyframes：进度由 zzerfu-about.js 按 scrollTop
 * 逐帧写进 transform / --w / --e，所以来回滚是同一段动画的正放与倒放。
 *
 * 降级：没有 JS 时不会挂 html.abn-live，全部纸张按普通长页依次排开，
 *       段落默认就是可见的 —— 内容永远读得到。
 * ========================================================================== */

/* ---------------------------------------------------------------------------
 * 1. 令牌
 * ------------------------------------------------------------------------- */
.abn {
    --abn-nav: 4rem;
    --abn-header-h: 64px;
    --abn-intro-offset: 340px;                      /* JS 按公共插画的真实底边校准 */

    /* 书：一个固定宽高比，任何设备、开合状态下都只等比缩放
       1.2679 = 710 / 560，改比例只改这一个数（height 算式里同步） */
    --abn-ratio: 1.2679;
    --abn-book-max: 620px;                          /* 打开后书宽的封顶 */
    --abn-book-mini: 310px;                         /* 闭合时书宽的封顶 */
    /* 闭合状态下舞台要给插画让多高：让位量取「插画底边」与「刚好放得下闭合书」
       的较小值 —— 笔记本上插画很高，硬让会把书压成一个小牌子，
       宁可让它往上飘一点、轻轻压在插画底边上。 */
    --abn-intro-pad: clamp(
        140px,
        calc(var(--abn-intro-offset) + 20px),
        calc(var(--abn-h) - 24px - var(--abn-book-mini) * 1.267857)
    );

    /* 纸：奶油白里带一点玫瑰与鸢尾紫，不再模仿真实旧书 */
    --abn-paper: #fffaf9;
    --abn-paper-2: #faf5fc;

    /* 铅笔 */
    --abn-ink: #3c3039;
    --abn-ink-2: rgba(60, 48, 57, 0.68);
    --abn-ink-3: rgba(60, 48, 57, 0.42);
    --abn-line: rgba(86, 61, 76, 0.4);
    --abn-line-soft: rgba(86, 61, 76, 0.15);
    --abn-hatch: rgba(86, 61, 76, 0.16);

    /* 玫瑰色笔触 */
    --abn-pen: #aa5573;
    --abn-pen-soft: rgba(196, 113, 145, 0.14);
    --abn-cover-1: #f5dce8;
    --abn-cover-2: #e9e2f7;
    --abn-cover-3: #dcefe9;
    --abn-cover-ink: #59374e;
    --abn-cover-line: rgba(120, 72, 105, 0.34);
    --abn-star: #fff9dc;

    --abn-on-pen: #ffffff;

    /* 擦除：橡皮压过纸留下的那点影（屑的颗粒走 .abn-eraser i 里的那张噪点） */
    --abn-dust-1: rgba(60, 48, 57, 0.13);

    /* 羽毛笔：羽片、羽轴、笔尖 */
    --abn-quill-ink: rgba(94, 70, 88, 0.82);
    --abn-quill-vein: rgba(255, 250, 249, 0.62);

    --abn-grain: 0.26;
    --abn-shadow: 0 34px 64px -36px rgba(20, 38, 33, 0.55), 0 3px 12px -8px rgba(20, 38, 33, 0.22);
}

[data-theme="dark"] .abn {
    --abn-paper: #28212c;
    --abn-paper-2: #211d2a;

    --abn-ink: #f1e6ee;
    --abn-ink-2: rgba(234, 216, 230, 0.68);
    --abn-ink-3: rgba(234, 216, 230, 0.4);
    --abn-line: rgba(225, 186, 213, 0.32);
    --abn-line-soft: rgba(225, 186, 213, 0.12);
    --abn-hatch: rgba(225, 186, 213, 0.14);

    --abn-pen: #efa6bf;
    --abn-pen-soft: rgba(239, 166, 191, 0.13);
    --abn-on-pen: #442234;
    --abn-cover-1: #49344f;
    --abn-cover-2: #303552;
    --abn-cover-3: #294947;
    --abn-cover-ink: #fae5f0;
    --abn-cover-line: rgba(244, 197, 222, 0.32);
    --abn-star: #ffe8ad;

    --abn-dust-1: rgba(0, 0, 0, 0.4);

    --abn-quill-ink: rgba(250, 232, 243, 0.88);
    --abn-quill-vein: rgba(40, 33, 44, 0.55);

    --abn-grain: 0.34;
    --abn-shadow: 0 34px 64px -36px rgba(0, 0, 0, 0.8), 0 3px 12px -8px rgba(0, 0, 0, 0.5);
}

/* ---------------------------------------------------------------------------
 * 2. 底座：轨道 / 舞台 / 吸附点
 * ------------------------------------------------------------------------- */
.abn,
.abn * {
    box-sizing: border-box;
}

.abn {
    position: relative;
    /* 阅读器从固定页眉下方开始；JS 会写入实际像素，避免手机地址栏误差 */
    --abn-h: calc(100svh - var(--abn-header-h));
}

/* 书本是从屏幕右缘外飞进来的：还没进翻页模式的那一瞬间（脚本挂类之前），
   这层还不是滚动容器，横向飞过的书会把整页撑出一条横向滚动条。
   clip 不建立滚动容器，只把溢出裁掉，随后的 sticky / fixed 都不受影响。 */
html:not(.abn-live) .abn {
    overflow-x: clip;
}

/* 轨道高度 = (时间线长度 + 1) 屏。JS 也会写一次像素值，
   这里留着算式是为了脚本挂上之前也不至于把高度算错。
   多出来的那 1 屏，让时间线的终点正好落在「滚到底」。 */
.abn-track {
    position: relative;
    height: calc((var(--abn-total, 1) + 1) * var(--abn-h));
}

/* 进了阅读器模式，这一屏占满视口、自己滚自己：
   手势只作用在这层里，不会把整页的滚动条带着走，
   也不会因为外面的内容多出半屏而错位。
   这里不再有 scroll-snap —— 滚动是连续的，翻到哪一页由 JS 按 scrollTop 算。 */
html.abn-live .abn {
    position: fixed;
    top: var(--abn-header-h);
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 41;
    overflow-y: auto;
    overflow-x: hidden;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    /* 闭合时保持透明，公共页眉下的双人插画才会继续露出；
       打开时由 .abn-desk 那层背景接住，不整页闪白 */
    background: transparent;
}

html.abn-live body {
    overflow: hidden;
}

/* 第 0 步：舞台让出公共插画的实际高度，自己保持透明；
   轨道高度仍按完整阅读区计算，所以开书不会改变任何吸附点。

   这个留白写在「基础样式」里而不是只写在 html.abn-live 下 ——
   脚本挂类之前的那一帧也要是最终位置。否则首帧按长页版式排在正中，
   挂类时再一路过渡下去，就成了「先摊开、再往下滑」。 */
.abn-stage {
    position: sticky;
    top: 0;
    height: var(--abn-h);
    display: grid;
    place-items: center;
    /* --abn-pad-top 由 JS 按「书开了多少」逐帧写：闭合时给插画让位，
       打开时收到 20px。留一个 CSS 兜底值给脚本挂上之前那一帧。 */
    padding: var(--abn-pad-top, var(--abn-intro-pad)) 20px 24px;
    z-index: 1;
}

/* 纸底下的桌面：一层页面底色 + 一圈很淡的暗角。
   底色不直接在 stage 上写死，而是放在这层里用 opacity 跟着开书进度淡入，
   这样插画是「被光慢慢盖住」的，而不是某一帧突然消失。 */
.abn-desk {
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    opacity: 0;
    background:
        radial-gradient(58% 46% at 50% 52%, rgba(15, 60, 52, 0.10), transparent 72%),
        var(--bg);
}

[data-theme="dark"] .abn-desk {
    background:
        radial-gradient(58% 46% at 50% 52%, rgba(0, 0, 0, 0.42), transparent 74%),
        var(--bg);
}

/* ---------------------------------------------------------------------------
 * 3. 纸堆
 * ------------------------------------------------------------------------- */
.abn-book {
    position: relative;
    /* 只有「书宽」在做三选一：书宽上限 / 屏宽 / 视口高度换算过来的宽度。
       高度 = 书宽 × 固定比例，所以任何设备上都只等比缩放。
       两个魔数是一对倒数：0.788732 = 560/710，1.267857 = 710/560，
       改比例时两个一起改，别只改一个。 */
    --abn-w: max(
        232px,
        min(var(--abn-book-max), 92vw, calc((var(--abn-h) - 60px) * 0.788732))
    );
    /* 阅读器模式下 JS 逐帧写 --abn-bw（闭合 310 → 打开 620），
       这里留 --abn-w 作为脚本接管前的兜底宽度 */
    width: var(--abn-bw, var(--abn-w));
    height: calc(var(--abn-bw, var(--abn-w)) * 1.267857);
    z-index: 2;
}

/* 闭合是一本小巧的、浮在插画下方的魔法书；打开时才长成阅读纸面。
   宽高都从 --abn-w 推出来，两端又成同一比例，插值途中也一路等比，
   不会出现「宽度先到位、高度还在追」的拉扯。
   只动书本自身，不动 --abn-h，因而不会出现开书后吸附点漂移。

   这里同样不挂 html.abn-live：脚本接管前的那一帧就得是这本小书。
   以前挂在 abn-live 下，首帧吃到的是「无 JS 长页」的 width: 100%，
   挂类时再过渡回 310px —— 宽屏上就是从 1390px 横向压回来，
   看起来像被拉成了一块宽饼（手机屏窄，压回来的幅度小，才不显眼）。 */
.abn:not(.is-open) .abn-book {
    --abn-w: max(
        180px,
        min(var(--abn-book-mini), 78vw, calc((var(--abn-h) - var(--abn-intro-pad) - 24px) * 0.788732))
    );
}

.abn-book {
    /* 让纸张内部可以按「纸有多宽」排版（容器查询），比例锁死后手机上的字才有得收 */
    container-type: inline-size;
    container-name: abnbook;
}

/* 开书那一下：宽高由 JS 按滚动进度逐帧写进 --abn-bw，比例全程不变。
   这里不再用 transition —— 过渡会滞后于手指，就不是「连贯滑动」了。 */

/* 出场：书本从右侧飞进来。
   只动 opacity / transform —— 这两个属性不参与布局，
   所以它绕开了宽高过渡，任何屏幕上都不会出现横向拉伸的那一帧。

   起点：屏幕右缘之外（50vw + 半本书 + 20px 余量）。宽屏给个 620px 的上限，
   不然 2560 的屏上要横穿 1400px，同样时长就变成「甩」进来了。
   缓动刻意不用 ease-out：那种曲线 10% 的时间就飞掉 36% 的路程，
   看着像被弹过来的。这里起手轻、中段匀、尾巴长，1.4s 走完全程。
   最后 28% 只走几像素 —— 那一下是「落」：先过头 9px 再回摆 3px，
   纸才像有重量，而不是停在一个坐标上。 */
.abn-book {
    --abn-fly: min(calc(50vw + var(--abn-w) * 0.5 + 20px), 620px);
    animation: abn-book-in 1400ms cubic-bezier(0.34, 0.14, 0.26, 1) backwards;
}

@keyframes abn-book-in {
    0% {
        opacity: 0;
        /* 起手略微仰起、缩一点：像被从右上角递过来 */
        transform: translate3d(var(--abn-fly), -20px, 0) rotate(6deg) scale(0.94);
    }

    15% {
        opacity: 1;
    }

    72% {
        transform: translate3d(-9px, 3px, 0) rotate(-1.5deg) scale(1.008);
    }

    88% {
        transform: translate3d(3px, -1.5px, 0) rotate(0.6deg) scale(0.998);
    }

    100% {
        opacity: 1;
        transform: none;
    }
}

/* 动画放完就把自己摘掉。出场是从 opacity: 0 起步的，
   万一某个环境里 CSS 动画根本没走（被节流、被停掉），
   书就会一直停在透明的那一帧上 —— JS 到点挂上这个类，书一定看得见。 */
.abn-book.is-entered {
    animation: none;
}


.abn-sheets {
    position: absolute;
    inset: 0;
    perspective: 1400px;
    transform-style: preserve-3d;
}

.abn-sheet {
    position: absolute;
    inset: 0;
    margin: 0;
    /* 手画的方圆：四个角不重样，才不像 CSS 画出来的 */
    border-radius: 24px 28px 22px 30px / 28px 22px 30px 24px;
    background: linear-gradient(177deg, var(--abn-paper) 0%, var(--abn-paper-2) 100%);
    box-shadow:
        0 0 0 1.5px var(--abn-line),
        var(--abn-shadow);
    overflow: hidden;
}

/* 纸纹颗粒：叠一层极淡的噪点，近看才有 */
.abn-sheet::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    opacity: var(--abn-grain);
    mix-blend-mode: multiply;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.2'/%3E%3C/svg%3E");
}

[data-theme="dark"] .abn-sheet::after {
    mix-blend-mode: screen;
}

/* 左下角一片交叉排线：铅笔打底的手感。
   章短的时候纸面下半截是空的，全靠这层让它像「画过的纸」，
   而不是没写完的卡片 */
.abn-sheet::before {
    content: "";
    position: absolute;
    left: -6%;
    bottom: -8%;
    width: 64%;
    height: 48%;
    z-index: 0;
    pointer-events: none;
    opacity: 0.85;
    background-image:
        repeating-linear-gradient(48deg, var(--abn-hatch) 0 1px, transparent 1px 8px),
        repeating-linear-gradient(-41deg, var(--abn-hatch) 0 1px, transparent 1px 13px);
    -webkit-mask-image: radial-gradient(98% 94% at 6% 100%, #000 3%, transparent 64%);
    mask-image: radial-gradient(98% 94% at 6% 100%, #000 3%, transparent 64%);
}

.abn-pad {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    height: 100%;
    padding: clamp(30px, 6.4%, 54px) clamp(26px, 7.4%, 60px) clamp(22px, 4%, 34px);
}

/* 内层那道「描了两遍」的线，手绘感主要靠它：
   一条实线 + 一条偏出去 2px 的浅线，像铅笔来回描了两下 */
.abn-pad::before {
    content: "";
    position: absolute;
    inset: 9px;
    border: 1px solid var(--abn-line);
    border-radius: 20px 24px 18px 26px / 24px 18px 26px 20px;
    outline: 1px solid var(--abn-line-soft);
    outline-offset: 2px;
    opacity: 0.42;
    pointer-events: none;
    transform: rotate(-0.09deg);
}

/* 右上角一片斜排线，像铅笔打过的底：单向线太规整，交叉一道才像手推的 */
.abn-pad::after {
    content: "";
    position: absolute;
    top: 0;
    right: 0;
    width: 52%;
    height: 34%;
    pointer-events: none;
    opacity: 0.72;
    background-image:
        repeating-linear-gradient(46deg, var(--abn-hatch) 0 1px, transparent 1px 7px),
        repeating-linear-gradient(-38deg, var(--abn-hatch) 0 1px, transparent 1px 14px);
    -webkit-mask-image: radial-gradient(128% 118% at 100% 0%, #000 6%, transparent 68%);
    mask-image: radial-gradient(128% 118% at 100% 0%, #000 6%, transparent 68%);
}

/* ---------------------------------------------------------------------------
 * 4. 章内排版
 * ------------------------------------------------------------------------- */
.abn-ch {
    display: flex;
    align-items: center;
    gap: 11px;
    flex: none;
    margin-bottom: clamp(26px, 5%, 44px);
    font-size: 11px;
    letter-spacing: 0.26em;
    color: var(--abn-ink-3);
}

.abn-ch b {
    font-weight: 600;
    color: var(--abn-pen);
    letter-spacing: 0.1em;
    font-variant-numeric: tabular-nums;
}

/* 章号后面那道手画的短横 */
.abn-ch i {
    width: 26px;
    height: 1px;
    background: var(--abn-line);
    transform: rotate(-1.4deg);
}

.abn-ch span {
    padding-left: 0.1em;
    letter-spacing: 0.34em;
}

.abn-body {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
    /* 从上往下写：没点亮的段落虽然透明，但仍占着位置，
       所以字是从章名下方开始、一段段往下长的，位置不会跳 */
    justify-content: flex-start;
    gap: clamp(16px, 3.4%, 30px);
    overflow: hidden;
}

/* 一段话：默认可见（无 JS 时读得到），进翻页模式才压成 0 */
.abn-seg {
    margin: 0;
    font-family: "Noto Serif SC", "Songti SC", "SimSun", var(--font);
    font-size: clamp(15.2px, min(1.26vw, 1.8vh), 18.4px);
    line-height: 2;
    letter-spacing: 0.012em;
    color: var(--abn-ink);
    text-wrap: pretty;
}

.abn-seg strong {
    font-weight: 700;
    color: var(--abn-ink);
    background: linear-gradient(transparent 64%, var(--abn-pen-soft) 64%);
}

/* 正文里的图片：夹在素描本里的一张相片 —— 白边、微斜、一点点投影。
   源图多大就多大（不硬拉，拉了只会糊），只在超过一屏时按高度收住 */
.abn-img {
    display: block;
    width: auto;
    height: auto;
    max-width: 100%;
    max-height: min(32vh, 210px);
    margin: 8px auto;
    border: 5px solid #fffdf8;
    border-bottom-width: 18px;
    border-radius: 1px;
    background: #fffdf8;
    object-fit: contain;
    transform: rotate(-0.9deg);
    box-shadow:
        0 0 0 1px rgba(43, 50, 46, 0.14),
        0 10px 22px -14px rgba(20, 38, 33, 0.6);
}

[data-theme="dark"] .abn-img {
    border-color: #e8e2d4;
    background: #e8e2d4;
}

/* 段落不再整块浮出来：字是一个一个写上去的（见第 7 节 .abn-ink）。
   所以这里不给 .abn-seg 加 opacity / transform —— 整段一起淡会盖掉单字的
   笔迹，等于又变回「一块一块地出现」。 */

/* 页脚：页码 + 章内小格 */
.abn-foot {
    flex: none;
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-top: clamp(18px, 3.4%, 30px);
}

.abn-no {
    font-size: 11px;
    letter-spacing: 0.2em;
    color: var(--abn-ink-3);
    font-variant-numeric: tabular-nums;
    padding-bottom: 3px;
    background-image: linear-gradient(var(--abn-line-soft), var(--abn-line-soft));
    background-repeat: no-repeat;
    background-size: 100% 1px;
    background-position: 0 100%;
}

.abn-dots {
    display: flex;
    gap: 6px;
}

.abn-dots i {
    width: 13px;
    height: 2px;
    background: var(--abn-line-soft);
    transform: rotate(-1.6deg);
    transition: background-color 0.4s ease;
}

.abn-dots i:nth-child(even) {
    transform: rotate(1.8deg);
}

.abn-dots i.is-on {
    background: var(--abn-pen);
}

/* ---------------------------------------------------------------------------
 * 5. 封面
 * ------------------------------------------------------------------------- */
.abn-sheet--cover {
    min-height: 360px;
    overflow: visible;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
}

.abn-sheet--cover::before,
.abn-sheet--cover::after {
    content: none;
}

html.abn-live .abn-sheet--cover {
    min-height: 0;
}

/* 不是皮革、书脊或厚纸仿真，而是一块带星轨与爱心封印的浪漫魔法封面。 */
.abn-cover {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 100%;
    padding: 30px 26px 62px;
    overflow: visible;
    border: 1px solid rgba(255, 255, 255, 0.72);
    border-radius: 34px 28px 36px 30px / 30px 36px 28px 34px;
    color: var(--abn-cover-ink);
    background:
        radial-gradient(80% 64% at 10% 0%, rgba(255, 255, 255, 0.68), transparent 70%),
        linear-gradient(145deg, var(--abn-cover-1), var(--abn-cover-2) 54%, var(--abn-cover-3));
    box-shadow:
        0 0 0 1px var(--abn-cover-line),
        0 24px 52px -24px rgba(103, 65, 99, 0.42),
        0 0 46px rgba(238, 183, 214, 0.24);
    transform-origin: 8% 50%;
    will-change: transform, opacity;
    animation: abn-float 5.2s ease-in-out infinite;
}

/* 阅读器模式下，封面的 transform 要留给 JS 逐帧写（掀开进度），
   不能再让浮动动画抢走 —— 把「呼吸」挪到整张纸上，幅度一样，
   看起来仍是那本浮着的小书。 */
html.abn-live .abn-cover {
    animation: none;
}

html.abn-live .abn-sheet--cover {
    animation: abn-float 5.2s ease-in-out infinite;
}

/* 封面上第二道不完全重合的描边，像围绕封印的光圈 */
.abn-cover::before {
    content: "";
    position: absolute;
    inset: 10px;
    border: 1px solid var(--abn-cover-line);
    border-radius: 26px 22px 30px 24px / 24px 30px 22px 26px;
    outline: 1px solid rgba(255, 255, 255, 0.34);
    outline-offset: 3px;
    pointer-events: none;
}

.abn-cover::after {
    content: "";
    position: absolute;
    left: 18%;
    right: 18%;
    bottom: -42px;
    height: 28px;
    border-radius: 50%;
    background: rgba(112, 73, 108, 0.2);
    filter: blur(14px);
    transform: translateZ(-1px);
    pointer-events: none;
    animation: abn-float-shadow 5.2s ease-in-out infinite;
}

.abn-cover__sigil {
    position: relative;
    z-index: 2;
    width: 80px;
    height: 80px;
    margin-bottom: 12px;
    color: var(--abn-cover-ink);
}

.abn-cover__sigil svg {
    display: block;
    width: 100%;
    height: 100%;
    overflow: visible;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.3;
}

.abn-cover__sigil path:not(.abn-cover__star) {
    fill: rgba(255, 255, 255, 0.2);
}

.abn-cover__sigil .abn-cover__star {
    fill: var(--abn-star);
    stroke: none;
    filter: drop-shadow(0 0 5px var(--abn-star));
}

.abn-cover__orbit {
    position: absolute;
    top: 70px;
    left: 50%;
    z-index: 1;
    width: 158px;
    height: 72px;
    margin: -36px 0 0 -79px;
    border: 1px solid var(--abn-cover-line);
    border-radius: 50%;
    pointer-events: none;
    animation: abn-orbit 14s linear infinite;
}

.abn-cover__orbit i {
    position: absolute;
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--abn-star);
    box-shadow: 0 0 8px var(--abn-star);
}

.abn-cover__orbit i:nth-child(1) { top: 8px; left: 22px; }
.abn-cover__orbit i:nth-child(2) { right: -2px; top: 32px; width: 7px; height: 7px; }
.abn-cover__orbit i:nth-child(3) { left: 50px; bottom: -2px; width: 4px; height: 4px; }

.abn-cover__eye {
    position: relative;
    z-index: 2;
    margin: 0 0 9px;
    font-size: 10px;
    letter-spacing: 0.36em;
    color: currentColor;
    opacity: 0.68;
}

.abn-cover__title {
    position: relative;
    z-index: 2;
    margin: 0;
    font-family: "Noto Serif SC", "Songti SC", "SimSun", var(--font);
    font-size: clamp(25px, 6.4vw, 34px);
    font-weight: 700;
    line-height: 1.3;
    letter-spacing: 0.04em;
    text-align: center;
    color: currentColor;
}

.abn-cover__rule {
    position: relative;
    z-index: 2;
    width: 52%;
    height: 1px;
    margin-top: 16px;
    background: currentColor;
    opacity: 0.36;
    transform: rotate(-1deg);
}

.abn-cover__rule::after {
    content: "";
    position: absolute;
    top: 4px;
    left: 18%;
    width: 64%;
    height: 1px;
    background: currentColor;
    opacity: 0.5;
    transform: rotate(1.6deg);
}

.abn-cover__meta {
    position: relative;
    z-index: 2;
    margin: 14px 0 0;
    font-size: 11px;
    letter-spacing: 0.1em;
    color: currentColor;
    opacity: 0.7;
    font-variant-numeric: tabular-nums;
}

.abn-cover__hint {
    position: absolute;
    bottom: 22px;
    left: 0;
    right: 0;
    z-index: 2;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    margin: 0;
    font-size: 10px;
    letter-spacing: 0.16em;
    color: currentColor;
    opacity: 0.66;
}

.abn-cover__hint i {
    display: block;
    width: 1px;
    height: 16px;
    background: linear-gradient(currentColor, transparent);
    animation: abn-hint 2.4s ease-in-out infinite;
    transform-origin: top center;
}

/* 封面内外的四角星：只画少量，不把页面撒满亮片 */
.abn-spark {
    position: absolute;
    z-index: 3;
    width: 12px;
    height: 12px;
    pointer-events: none;
    animation: abn-twinkle 2.8s ease-in-out infinite;
}

.abn-spark::before,
.abn-spark::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    border-radius: 50%;
    background: var(--abn-star);
    box-shadow: 0 0 7px var(--abn-star);
    transform: translate(-50%, -50%);
}

.abn-spark::before { width: 2px; height: 100%; }
.abn-spark::after { width: 100%; height: 2px; }
.abn-spark--1 { top: 14%; left: -22px; animation-delay: -0.8s; }
.abn-spark--2 { top: 6%; right: 12%; transform: scale(0.62); animation-delay: -1.9s; }
.abn-spark--3 { top: 46%; right: -25px; animation-delay: -0.2s; }
.abn-spark--4 { bottom: 19%; left: 8%; transform: scale(0.54); animation-delay: -2.2s; }
.abn-spark--5 { bottom: -18px; right: 20%; transform: scale(0.72); animation-delay: -1.2s; }

@keyframes abn-float {
    0%, 100% { transform: translate3d(0, 0, 0) rotateZ(-1deg); }
    50% { transform: translate3d(0, -13px, 0) rotateZ(1.2deg); }
}

@keyframes abn-float-shadow {
    0%, 100% { opacity: 0.52; transform: scaleX(1); }
    50% { opacity: 0.28; transform: scaleX(0.78); }
}

@keyframes abn-orbit {
    from { transform: rotate(-12deg); }
    to { transform: rotate(348deg); }
}

@keyframes abn-twinkle {
    0%, 100% { opacity: 0.28; }
    50% { opacity: 1; }
}

@keyframes abn-hint {
    0%, 100% { transform: scaleY(0.5); opacity: 0.4; }
    50% { transform: scaleY(1); opacity: 1; }
}

/* 开书不再是一段定时动画：封面绕左掀开的角度、章节纸从光里浮起的
   透明度与缩放，全在 zzerfu-about.js 的 paintOpen() 里按滚动进度写。
   这里只留一句备忘 —— 想改开书的姿态，去改那边，不要在这里加 keyframes。 */

/* ---------------------------------------------------------------------------
 * 6. 结尾页
 * ------------------------------------------------------------------------- */
.abn-body--end {
    justify-content: center;
    gap: 26px;
    text-align: center;
}

.abn-say--end {
    font-size: clamp(19px, 2vw, 26px);
    letter-spacing: 0.04em;
}

.abn-acts {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    justify-content: center;
}

.abn-btn {
    display: inline-flex;
    align-items: center;
    height: 44px;
    padding: 0 22px;
    border-radius: 14px 18px 12px 16px / 16px 12px 18px 14px;
    border: 1.5px solid var(--abn-line);
    background: transparent;
    color: var(--abn-ink) !important;
    font-size: 14px;
    letter-spacing: 0.04em;
    text-decoration: none;
    transition: background-color 0.24s ease, transform 0.24s ease;
}

.abn-btn:hover {
    background: var(--abn-pen-soft);
    transform: translateY(-1px) rotate(-0.4deg);
}

.abn-btn--solid {
    border-color: transparent;
    background: var(--abn-pen);
    color: var(--abn-on-pen) !important;
}

.abn-btn--solid:hover {
    background: var(--abn-pen);
    filter: brightness(1.06);
}

/* ---------------------------------------------------------------------------
 * 7. 换页：橡皮把旧字擦掉，羽毛笔把新字写上去
 * ---------------------------------------------------------------------------
 * 纸不翻、不飞、不位移。这一页读完了，一块橡皮从上往下把字擦掉；擦过的地方
 * 露出的是下一张纸 —— 同样的纸纹、同样的框线，所以看上去只是「这一页被擦干净
 * 了」，纸本身没换。
 *
 * 擦除是一块沿文字逐行往返的橡皮：JS 给每个字写 --e，橡皮经过后才透明。
 * 只擦字迹与图片，纸面、纸边、颗粒、排线都保持不动。
 *
 * 一个字一个字地写：JS 把每段拆成 .abn-ink 单字，每帧只往段落上写一个 --w
 * （写到第几个字），单字的 opacity 由 --i（第几个字）和 --w 算 ——
 * 所以正着滚是一笔一笔写出来，倒着滚就是一笔一笔退回去，没有第二套状态。
 * ------------------------------------------------------------------------- */
/* 擦除不再用整页横切遮罩：JS 将橡皮的位置与每个字的 --e 对齐，
   字迹只在橡皮实际经过时消失，未接触的行保持原样。 */
/* 一块真正的大橡皮：动漫里那种整只手按住、上下使劲蹭的大块头。
   原点在橡皮中心，JS 只写 translate + rotate。 */
.abn-eraser {
    position: absolute;
    left: 0;
    top: 0;
    z-index: 4;
    width: 150px;
    height: 66px;
    margin: -33px 0 0 -75px;
    pointer-events: none;
    opacity: 0;
    border: 1px solid rgba(102, 68, 88, 0.28);
    border-radius: 10px 12px 11px 9px;
    background:
        linear-gradient(180deg, rgba(255, 255, 255, 0.58), transparent 42%),
        linear-gradient(90deg, #efb4c8 0%, #f7c9d8 29%, #e9a8bf 30%, #e9a8bf 34%, transparent 34%),
        linear-gradient(90deg, transparent 0%, transparent 72%, #e7dce3 72%, #f6eff3 100%),
        #fffaf5;
    box-shadow:
        0 2px 0 rgba(255, 255, 255, 0.72) inset,
        0 -3px 0 rgba(107, 70, 89, 0.09) inset,
        0 6px 11px -3px rgba(38, 24, 34, 0.44),
        0 14px 22px -12px rgba(38, 24, 34, 0.36);
}

/* 中间的纸套：一个小标签，远看也能认出是文具而不是装饰线。 */
.abn-eraser::after {
    content: "ERASER";
    position: absolute;
    left: 36%;
    right: 25%;
    top: 18px;
    color: #9b7387;
    font: 600 10px/1.2 Arial, sans-serif;
    letter-spacing: 0.12em;
    text-align: center;
    transform: rotate(-2deg);
}

/* 胶擦下沿那道吃灰的边，贴着字迹过去。 */
.abn-eraser::before {
    content: "";
    position: absolute;
    left: 5px;
    right: 5px;
    bottom: 2px;
    height: 3px;
    border-radius: 2px;
    background: rgba(91, 64, 80, 0.2);
}

[data-theme="dark"] .abn-eraser {
    border-color: rgba(255, 244, 250, 0.42);
    box-shadow:
        0 2px 0 rgba(255, 255, 255, 0.7) inset,
        0 -3px 0 rgba(107, 70, 89, 0.09) inset,
        0 6px 12px -3px rgba(0, 0, 0, 0.65),
        0 0 0 1px rgba(255, 228, 240, 0.12);
}

/* 拖尾擦痕已按要求去掉：只留橡皮本体，擦没擦干净看字本身。 */
.abn-eraser i {
    display: none;
}

/* 羽毛笔：一支斜向的笔，笔尖就是元素的原点。
   JS 每帧只改 translate —— 位置由它写，手腕的抖、笔身的倾角交给 CSS 动画，
   两下不打架（一个在 transform 里，一个在内层 <i> 上）。
   SVG 的 viewBox 是 56×56，笔锋尖落在 (5.8, 52.4)，所以负 margin 把笔尖挪到原点。
   120px 的 box 换算下来就是 -112.3px / -12.43px。 */
.abn-quill {
    position: absolute;
    left: 0;
    top: 0;
    z-index: 6;
    width: 120px;
    height: 120px;
    margin: -112.3px 0 0 -12.43px;
    pointer-events: none;
    opacity: 0;
    transition: opacity 200ms ease;
    transform-origin: 12.43px 112.3px;
    will-change: transform, opacity;
}

.abn-quill.is-on {
    opacity: 1;
}

.abn-quill i {
    display: block;
    width: 100%;
    height: 100%;
    transform-origin: 12.43px 112.3px;
    animation: abn-quill-write 560ms ease-in-out infinite alternate;
}

.abn-quill svg {
    display: block;
    width: 100%;
    height: 100%;
    overflow: visible;
    filter: drop-shadow(0 3px 4px rgba(20, 38, 33, 0.18));
}

/* 笔杆与羽片同一个颜色，叠在一起才是一支整笔 */
.abn-quill .q-shaft,
.abn-quill .q-vane {
    fill: var(--abn-quill-ink);
}

/* 羽枝：几道纸色的斜线，横着切过羽片 —— 没有它们，羽片就是一块色块 */
.abn-quill .q-barb {
    fill: none;
    stroke: var(--abn-quill-vein);
    stroke-width: 0.85;
    stroke-linecap: round;
    opacity: 0.55;
}

/* 羽轴：一道纸色的细线。不要它是「一片黑叶子」，有了才看得出是羽毛 */
.abn-quill .q-spine {
    fill: none;
    stroke: var(--abn-quill-vein);
    stroke-width: 1.0;
    stroke-linecap: round;
    opacity: 0.7;
}

/* 手腕：写字时笔尖不动、笔身轻轻压着走 */
@keyframes abn-quill-write {
    from {
        transform: rotate(-1.8deg) translate3d(0, 0.6px, 0);
    }

    to {
        transform: rotate(2.2deg) translate3d(0, -0.6px, 0);
    }
}

@media (max-width: 900px) {
    .abn-eraser {
        width: 116px;
        height: 52px;
        margin: -26px 0 0 -58px;
        border-radius: 8px;
    }

    .abn-eraser::after {
        top: 14px;
        font-size: 8px;
    }

    .abn-quill {
        width: 84px;
        height: 84px;
        margin: -78.6px 0 0 -8.7px;
        transform-origin: 8.7px 78.6px;
    }

    .abn-quill i {
        transform-origin: 8.7px 78.6px;
    }
}

/* 画在纸上的字：--i 是它在这一段里的序号（初始化时写死一次），
   --w 是「已经写到第几个」。两数一减就是这个字写了多少 ——
   clamp 把负的压成 0、超过 1 的压成 1，一段四十字也只写一个变量。 */
html.abn-live .abn-ink {
    opacity: clamp(0, calc((var(--w, 0) - var(--i)) * 2.6 * var(--e, 1)), 1);
}

/* 还没轮到写字的那点「家具」，跟着 --pa 一起长出来：
   章号后面那道短横是「划」出来的，页脚是「印」上去的 */
html.abn-live .abn-ch i {
    transform: rotate(-1.4deg) scaleX(var(--pa, 1));
    transform-origin: 0 50%;
}

/* 页脚是「印」上去的：跟着这一页的进度 --pa 一起出现，不参与逐字书写 */
html.abn-live .abn-foot {
    opacity: var(--pa, 1);
}

/* 段里的相片、结尾页那两颗按钮：写不出来，跟着所在单元的 --a 淡上来 */
html.abn-live .abn-img,
html.abn-live .abn-acts {
    opacity: calc(var(--a, 1) * var(--e, 1));
}

html.abn-live .abn-acts {
    transform: translateY(calc((1 - var(--a, 1)) * 10px));
}

/* 已经擦干净的 / 还在下面排队的纸：不画、不可点 */
.abn-sheet.is-gone,
.abn-sheet.is-under {
    visibility: hidden;
    pointer-events: none;
}

/* ---------------------------------------------------------------------------
 * 8. 章节刻度 / 页码计数 / 进度
 * ------------------------------------------------------------------------- */
/* 左侧章节刻度：桌面才出现 */
.abn-rail {
    position: absolute;
    left: max(22px, calc(50% - 280px - 104px));
    top: 50%;
    transform: translateY(-50%);
    z-index: 3;
    opacity: 0;
    transition: opacity 0.5s ease 0.1s;
}

.abn-rail.is-in {
    opacity: 1;
}

.abn-rail__line {
    position: absolute;
    left: 5px;
    top: 6px;
    bottom: 6px;
    width: 1px;
    background: var(--line-strong);
}

.abn-rail__line i {
    display: block;
    width: 100%;
    height: 100%;
    background: var(--accent);
    transform-origin: top center;
    transform: scaleY(0);
}

.abn-rail__list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 22px;
}

.abn-rail__item a {
    display: flex;
    align-items: center;
    gap: 10px;
    text-decoration: none;
    color: var(--faint) !important;
    font-size: 11px;
    letter-spacing: 0.18em;
    transition: color 0.3s ease;
}

.abn-rail__item a::before {
    content: "";
    width: 11px;
    height: 11px;
    flex: none;
    border-radius: 50%;
    border: 1px solid var(--line-strong);
    background: var(--bg);
    transition: border-color 0.3s ease, background-color 0.3s ease, transform 0.3s ease;
}

.abn-rail__item b {
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    opacity: 0.72;
}

.abn-rail__item span {
    max-width: 0;
    overflow: hidden;
    white-space: nowrap;
    opacity: 0;
    transition: max-width 0.4s ease, opacity 0.3s ease;
}

.abn-rail__item.is-on a {
    color: var(--accent-deep) !important;
}

.abn-rail__item.is-on a::before {
    border-color: var(--accent);
    background: var(--accent);
    transform: scale(1.12);
}

.abn-rail__item.is-on span,
.abn-rail:hover .abn-rail__item span {
    max-width: 6em;
    opacity: 1;
}

.abn-count {
    position: absolute;
    right: max(22px, calc(50% - 280px - 74px));
    bottom: 26px;
    display: flex;
    align-items: baseline;
    gap: 4px;
    font-size: 11px;
    letter-spacing: 0.16em;
    color: var(--faint);
    font-variant-numeric: tabular-nums;
    z-index: 3;
}

html.abn-live .abn-count {
    opacity: 0;
    transition: opacity 0.3s linear;
}

html.abn-live .abn.is-open .abn-count {
    opacity: 1;
}

.abn-count b {
    color: var(--text);
    font-weight: 600;
}

.abn-count em {
    font-style: normal;
    opacity: 0.5;
}

.abn-progress {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 2px;
    background: var(--line);
    z-index: 3;
}

.abn-progress i {
    display: block;
    height: 100%;
    background: var(--accent);
    transform-origin: left center;
    transform: scaleX(0);
}

/* ---------------------------------------------------------------------------
 * 8b. 返回主页：开书之后化成一张便签，飞到书上沿贴住
 * ---------------------------------------------------------------------------
 * 书还闭合的时候，按钮留在原来那一行（公共插画下面），仍是那枚胶囊；
 * 书一打开，它就变作一张手写便签，打着旋儿落到扉页左上角 ——
 * 「返回」这件事因此有了一点手账的味道，而不是一个系统控件。
 *
 * 飞行是抛物线：横向先快后慢地被吸过去，纵向先抛起再落下
 * （弧线在 JS 的 arcFrames 里采样成关键帧），落地时压一下、再轻晃一点。
 * 落定后留一个极慢的呼吸和一粒闪烁的星 —— 像有生命。
 *
 * 位移用 transform 不用 left/top：只在合成层里改，跟手且不触发重排；
 * 呼吸走 translate / rotate 两个独立属性，跟 hover 的 transform 互不打架。
 * ------------------------------------------------------------------------- */
html.abn-live .page-back-row.is-docked {
    position: fixed;
    top: 0;
    left: 0;
    right: auto;
    bottom: auto;
    width: 0;
    height: 0;
    margin: 0;
    padding: 0;
    /* 位移全交给 transform；顺手把「灵动岛」态的水平居中位移清零 */
    --zf-back-shift: 0px !important;
    transform: translate3d(var(--abn-back-x, 0px), var(--abn-back-y, 0px), 0);
    will-change: transform;
}

/* 一张便签：奶油纸底、玫瑰与鸢尾的渐变、极淡的便签横格 */
html.abn-live .page-back-row.is-docked .page-back {
    /* 便签的颜色都收在这一组令牌里，暗色只换这一组 */
    --note-1: #fff4e4;
    --note-2: #ffdfeb;
    --note-3: #e7dcff;
    --note-ink: #74384f;
    --note-rule: rgba(176, 88, 126, 0.2);
    --note-line: rgba(160, 72, 108, 0.28);
    --note-tape: rgba(255, 255, 255, 0.62);
    --note-star: #d98cb0;
    --note-glow: rgba(196, 113, 145, 0.3);

    /* 顶掉 .is-stuck 的收缩（那时它已经滑到顶栏下了）：
       贴在书上要留住文字，才认得出是「返回主页」 */
    flex: none;
    height: auto;
    min-width: 0;
    min-height: 42px;
    padding: 8px 14px 7px 12px;
    gap: 0.42rem;
    /* 手撕便签：四角弧度各不相同 */
    border-radius: 3px 11px 4px 10px / 10px 4px 11px 3px;
    border: 1px solid var(--note-line);
    background:
        radial-gradient(108% 122% at 12% -8%, rgba(255, 255, 255, 0.6), transparent 52%),
        repeating-linear-gradient(180deg, transparent 0 10px, var(--note-rule) 10px 11px),
        linear-gradient(155deg, var(--note-1) 0%, var(--note-2) 48%, var(--note-3) 100%);
    color: var(--note-ink) !important;
    font-family: "Kaiti SC", "STKaiti", "KaiTi", "Songti SC", Georgia, serif;
    font-size: 0.92rem !important;
    letter-spacing: 0.04em;
    /* 纸片是斜着贴上去的 */
    transform: rotate(-2.6deg);
    box-shadow:
        0 12px 20px -12px rgba(112, 52, 82, 0.52),
        0 3px 7px -3px rgba(112, 52, 82, 0.32),
        inset 0 -6px 10px -8px rgba(112, 52, 82, 0.35),
        inset 0 0 0 1px rgba(255, 255, 255, 0.46);
    /* 胶带和星要露到纸外，不能再裁 */
    overflow: visible;
    /* 尺寸不做过渡：落地那一下要准，别让 padding 走动画量出中间值 */
    transition: color 0.3s ease,
        transform 0.32s cubic-bezier(0.34, 1.4, 0.64, 1),
        box-shadow 0.3s ease, filter 0.3s ease;
    /* 呼吸：只用独立的 translate / rotate，hover 的 transform 仍然有效 */
    animation: abn-note-float 7.6s ease-in-out infinite;
}

/* 顶上那道半透明胶带 */
html.abn-live .page-back-row.is-docked .page-back::before {
    content: "";
    position: absolute;
    top: -8px;
    left: 50%;
    width: 44px;
    height: 13px;
    margin-left: -18px;
    border-radius: 1px;
    background: linear-gradient(102deg,
        rgba(255, 255, 255, 0.26), var(--note-tape) 44%, rgba(255, 240, 246, 0.5));
    box-shadow: 0 1px 3px -1px rgba(110, 55, 82, 0.3),
        inset 0 0 0 1px rgba(255, 255, 255, 0.45);
    transform: rotate(-3.4deg);
    pointer-events: none;
}

/* 右上角那粒星：慢慢闪，像纸自己在发光 */
html.abn-live .page-back-row.is-docked .page-back::after {
    content: "✦";
    position: absolute;
    top: -10px;
    right: -8px;
    font-size: 12px;
    line-height: 1;
    color: var(--note-star);
    text-shadow: 0 0 8px var(--note-glow);
    animation: abn-note-twinkle 3.6s ease-in-out infinite;
    pointer-events: none;
}

/* 贴着纸时的呼吸：极小，只在安静时看得见 */
@keyframes abn-note-float {
    0%,
    100% {
        rotate: 0deg;
        translate: 0 0;
    }

    50% {
        rotate: 1.1deg;
        translate: 0 -2.4px;
    }
}

@keyframes abn-note-twinkle {
    0%,
    100% {
        opacity: 0.34;
        transform: scale(0.76) rotate(-10deg);
    }

    42% {
        opacity: 1;
        transform: scale(1.16) rotate(14deg);
    }

    68% {
        opacity: 0.5;
        transform: scale(0.92) rotate(1deg);
    }
}

/* 飞行途中：纸边泛起一点暖光，像被风吹着走 */
html.abn-live .page-back-row.is-docked .page-back.is-gliding {
    filter: drop-shadow(0 10px 16px rgba(196, 113, 145, 0.42));
}

/* 指头按上来：便签被掀起一角 */
html.abn-live .page-back-row.is-docked .page-back:hover {
    transform: rotate(-0.8deg) translateY(-1px) scale(1.05);
    box-shadow:
        0 14px 22px -12px rgba(120, 62, 90, 0.52),
        0 2px 6px -3px rgba(120, 62, 90, 0.3),
        inset 0 0 0 1px rgba(255, 255, 255, 0.58);
}

html.abn-live .page-back-row.is-docked .page-back:active {
    transform: rotate(-2.6deg) scale(0.955);
}

html.abn-live .page-back-row.is-docked .page-back__text {
    max-width: 96px;
    opacity: 1;
}

html.abn-live .page-back-row.is-docked .page-back__icon--arrow {
    opacity: 1;
    transform: none;
}

html.abn-live .page-back-row.is-docked .page-back__icon--home {
    opacity: 0;
    transform: scale(0.3) rotate(-40deg);
}

/* 选择器要带上 html，否则会被上面那条（多一个类型选择器）压过去 */
html[data-theme="dark"] .page-back-row.is-docked .page-back {
    --note-1: #3d3040;
    --note-2: #352c40;
    --note-3: #2b2d47;
    --note-ink: #fbe4ef;
    --note-rule: rgba(239, 166, 191, 0.09);
    --note-line: rgba(239, 166, 191, 0.26);
    --note-tape: rgba(255, 255, 255, 0.15);
    --note-star: #ffd9ea;
    --note-glow: rgba(239, 166, 191, 0.55);
    background:
        radial-gradient(120% 130% at 8% 0%, rgba(255, 255, 255, 0.13), transparent 58%),
        repeating-linear-gradient(180deg, transparent 0 10px, var(--note-rule) 10px 11px),
        linear-gradient(155deg, var(--note-1) 0%, var(--note-2) 48%, var(--note-3) 100%);
    box-shadow:
        0 10px 20px -12px rgba(0, 0, 0, 0.8),
        0 2px 5px -3px rgba(0, 0, 0, 0.6),
        inset 0 0 0 1px rgba(255, 255, 255, 0.06);
}

/* ---------------------------------------------------------------------------
 * 9. 窄屏：一屏一张纸，刻度收起
 * ------------------------------------------------------------------------- */
@media (max-width: 900px) {
    .abn-book {
        /* 窄屏不再单独给一组宽高（那正是平板被拉长的原因），
           只把书宽上限稍微收一点，比例仍由上面的算式锁死 */
        --abn-book-max: 520px;
    }

    /* 窄屏的左右留白比桌面小一点；上边距由 JS 写的 --abn-pad-top 管 */
    .abn-stage {
        padding-left: 14px;
        padding-right: 14px;
        padding-bottom: 20px;
    }

    .abn-rail {
        display: none;
    }

    .abn-count {
        /* 右边那列悬浮按钮是 fixed 的，计数躲开它 */
        right: 84px;
        bottom: 14px;
    }

    .abn-pad {
        padding: 26px 22px 18px;
    }

    .abn-seg {
        font-size: 15.4px;
        line-height: 1.95;
    }

    .abn-ch {
        margin-bottom: 20px;
    }
}

/* 极矮的横屏：比例不变，由上面的高度算式自动收窄；这里只把封面装饰收掉 */
@media (max-height: 560px) {
    .abn-cover__sigil,
    .abn-cover__orbit,
    .abn-cover__meta {
        display: none;
    }

    .abn-ch {
        margin-bottom: 14px;
    }

    .abn-body {
        gap: 10px;
    }
}

/* ---------------------------------------------------------------------------
 * 9b. 小书：字随纸缩
 * ---------------------------------------------------------------------------
 * 比例锁死以后，手机上这张纸只有 359×455 那么点地方；
 * 六段话的章节按桌面字号排会溢出纸面（overflow: hidden 会把尾巴切掉）。
 * 这里按「纸的实际宽度」用容器查询收字号、行距与留白 ——
 * 比例一点不动，让字自己给纸让位。
 * ------------------------------------------------------------------------- */
@container abnbook (max-width: 470px) {
    .abn-seg {
        font-size: 13.8px;
        line-height: 1.74;
        letter-spacing: 0;
    }

    .abn-body {
        gap: 10px;
    }

    .abn-pad {
        padding: 22px 18px 15px;
    }

    .abn-pad::before {
        inset: 7px;
    }

    .abn-ch {
        margin-bottom: 13px;
        font-size: 10px;
    }

    .abn-foot {
        margin-top: 11px;
    }

    .abn-say--end {
        font-size: 18px;
    }

    .abn-img {
        max-height: min(24vh, 150px);
        border-width: 4px;
        border-bottom-width: 14px;
    }
}

/* 更小的纸（小屏手机、分屏）再收一档，六段的长章也压得进一页 */
@container abnbook (max-width: 360px) {
    .abn-seg {
        font-size: 13.2px;
        line-height: 1.7;
    }

    .abn-body {
        gap: 8px;
    }

    .abn-pad {
        padding: 20px 16px 13px;
    }

    .abn-ch {
        margin-bottom: 10px;
    }

    .abn-foot {
        margin-top: 9px;
    }
}

/* 再小一档（320 宽的老手机）：字不能再小，改收留白 */
@container abnbook (max-width: 310px) {
    .abn-seg {
        font-size: 12.4px;
        line-height: 1.62;
    }

    .abn-body {
        gap: 5px;
    }

    .abn-pad {
        padding: 16px 13px 10px;
    }

    .abn-ch {
        margin-bottom: 7px;
    }

    .abn-foot {
        margin-top: 6px;
    }
}

/* 阅读器是整屏 fixed 的，站脚（.footer-warp，在 #pjax-container 之外）
   会永远卡在它下沿透出来 —— 闭合时 .abn 还是透明的，那段备案号就露在
   书下面，还滚不走。开书期间先把它收起来，降级成长页时照常出现。 */
html.abn-live .footer-warp {
    display: none;
}

/* ---------------------------------------------------------------------------
 * 10. 降级：没有 JS / 减少动效 —— 排成一条正常长页
 * ------------------------------------------------------------------------- */
html:not(.abn-live) .abn-track {
    height: auto;
    padding: calc(var(--abn-nav) + 26px) 18px 60px;
}

html:not(.abn-live) .abn-eraser,
html:not(.abn-live) .abn-quill,
html:not(.abn-live) .abn-desk,
html:not(.abn-live) .abn-rail,
html:not(.abn-live) .abn-count,
html:not(.abn-live) .abn-progress {
    display: none;
}

/* 舞台原本是 grid + place-items: center 的一屏高容器。
   降级成长页后必须回到普通块级流：只把 position/height 改掉还不够，
   grid 仍会把比容器高一倍多的纸堆「居中」到容器外面去
   （实测书的 top 跑到 -237px，第一屏只剩半张空白）。 */
html:not(.abn-live) .abn-stage {
    display: block;
    position: static;
    height: auto;
    min-height: 0;
    padding: 0;
}

html:not(.abn-live) .abn-book {
    width: 100%;
    max-width: 640px;
    height: auto;
    margin: 0 auto;
    perspective: none;
    /* 长页里不需要「从右侧飞进来」那一手：整整一页内容横着滑进来太怪 */
    animation: none;
}

html:not(.abn-live) .abn-sheets {
    position: static;
    transform-style: flat;
}

html:not(.abn-live) .abn-sheet {
    position: static;
    visibility: visible !important;
    margin-bottom: 22px;
    min-height: 0;
    transform: none !important;
    box-shadow: 0 0 0 1.5px var(--abn-line), 0 12px 26px -22px rgba(20, 38, 33, 0.4);
}

/* 封面靠 height: 100% 铺满整张纸，而降级后纸的高度是 auto。
   百分比撞上 auto 会解析成一个循环出来的天文数字（实测 1980+px），
   第一屏于是变成一大片空紫。这里改成按书的比例自己定高，
   窄一点居中摆，读起来仍然是一本书的封面。 */
html:not(.abn-live) .abn-cover {
    height: auto;
    width: 100%;
    max-width: 430px;
    margin: 0 auto;
    aspect-ratio: 560 / 710;
}

/* 封面这张纸本来就是透明的，降级时别再给它补一圈纸张描边，
   否则覆盖的封面外面会多出一个方框 */
html:not(.abn-live) .abn-sheet--cover {
    box-shadow: none;
    background: transparent;
}

/* 降级成长页后没有「下滑翻页」这回事，那句提示连同它的小竖线一起收掉，
   否则会跟「4 章 · 18 段」挤在一起 */
html:not(.abn-live) .abn-cover__hint {
    display: none;
}

html:not(.abn-live) .abn-pad {
    height: auto;
    padding: 30px 26px;
}

html:not(.abn-live) .abn-body {
    overflow: visible;
    justify-content: flex-start;
}

@media (prefers-reduced-motion: reduce) {
    .abn-book,
    .abn-cover,
    .abn-cover::after,
    .abn-cover__orbit,
    .abn-cover__hint i,
    .abn-spark,
    .page-back-row.is-docked .page-back,
    .page-back-row.is-docked .page-back::after {
        animation: none;
    }
}
