@charset "UTF-8";
/**
 * EL9拼好题 — Twitter 版式 × Apple 规范
 *
 * 栅格：8pt。字号：11 / 13 / 15 / 17 / 20 / 23 / 28 / 34。
 * 动效：cubic-bezier(.4, 0, .2, 1)，时长 180ms。
 * 点击区：不小于 44×44（iOS HIG）。
 *
 * @package EL9拼好题
 * @author Ayiya
 * @version 0.10.20
 */

/* ==========================================================================
   1. Design Tokens
   ========================================================================== */

:root {
    /*
     * 告诉浏览器本站是浅色的 —— 深色模式下滚动条、<select>、自动填充底色、
     * textarea 右下角那个拖拽角才会跟着变。少了这一行它们永远是白的。
     */
    color-scheme: light;
    /* 强调色分三级，别只有一个蓝：
       accent        —— 图标、边框、进度条这类非文字元素（3:1 就够）
       accent-text   —— 正文里的链接、小字号强调（白底 5.01:1，AA 达标）
       accent-strong —— 实心按钮底色（配白字 5.01:1，AA 达标） */
    --el9-accent: #1d9bf0;
    --el9-accent-text: #1674b4;
    --el9-accent-strong: #1674b4;
    --el9-accent-soft: rgba(29, 155, 240, .1);
    --el9-accent-contrast: #fff;
    --el9-danger: #f4212e;
    --el9-danger-text: #c81e28;

    --el9-font-sans: -apple-system, BlinkMacSystemFont, "SF Pro SC", "SF Pro Text", "PingFang SC",
        "Segoe UI Variable Text", "Segoe UI", "Hiragino Sans GB", "Microsoft YaHei",
        "Noto Sans SC", sans-serif;
    --el9-font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
        "Liberation Mono", "Courier New", monospace;

    /* 8pt spacing scale */
    --el9-1: 4px;
    --el9-2: 8px;
    --el9-3: 12px;
    --el9-4: 16px;
    --el9-5: 20px;
    --el9-6: 24px;
    --el9-8: 32px;
    --el9-10: 40px;

    --el9-r-sm: 8px;
    --el9-r-md: 12px;
    --el9-r-lg: 16px;
    --el9-r-xl: 20px;
    --el9-r-full: 999px;

    --el9-ease: cubic-bezier(.4, 0, .2, 1);
    --el9-dur: 180ms;

    /*
     * 页面四周的留白（内容到窗口边）。
     *
     * 左右和顶部共用这一个值 —— 视觉上「四周一样宽」靠的就是它，
     * 以前左右是 shell 的 padding、顶部是 layout 的 padding，两个数各改各的，
     * 很容易一处 24 一处 12。导航条那条通栏背景也靠它算负边距，别单独写死数字。
     */
    --el9-bleed: 12px;

    /*
     * 右下角那两颗悬浮钮（手机「菜单」、电脑「返回顶部」）平时的透明度。
     *
     * 它们压在正文上，一直是实心的就显突兀 —— 尤其文章页正文是浅底的时候，
     * 两颗圆钮像贴了张膏药。0.7 是「看得见但不抢内容」的档；
     * 指针移上去回到 1，手感上就是「靠近才亮起来」。
     *
     * 两颗钮共用这一个值，别分开写，不然一个淡一个浓。
     */
    --el9-fab-alpha: .7;

    /* 侧栏盒宽（含靠内侧那 12px 内边距，卡片实际宽度要减掉它） */
    --el9-side-w: 280px;
    --el9-main-w: 720px;

    /*
     * 整页容器的宽度 = 侧栏 + 中间的缝 + 主栏 + 两侧留白。
     *
     * 以前这个值由 PHP 的 el9ShellWidth() 算好、内联写进 <head>，
     * 算的是「侧栏 296 + 内边距 24」，可 CSS 里侧栏实际只有 280 ——
     * 于是一直多让出 52px：后台设 720，主栏实际被撑到 772，
     * 右边空出一条谁也说不清的带子。
     *
     * 现在只在 CSS 里算一次，而且全部引用同一个变量：
     * 改侧栏宽、改缝宽、改断点，都不会再出现「PHP 和 CSS 各算一套」。
     */
    --el9-shell-w: calc(
        var(--el9-side-w) + var(--el9-side-gap) + var(--el9-main-w) + var(--el9-bleed) * 2
    );
    /*
     * 主栏左右内边距。
     *
     * ⚠️ 这里必须是 0，别再给 28。
     * 原因：信息流卡片靠负 margin（-main-pad）把自己撑到主栏盒边，
     * 但轮播、标签栏这些没有负 margin —— 一旦 main-pad 不是 0，
     * 它们就会比卡片两边各缩进 28px，「内容区右侧和侧栏对不齐」就是这么来的。
     * 归零之后，主栏里所有元素的宽度和左右边完全一致，缝也就恒定了。
     *
     * 留白交给 .el9-shell 的 padding 和卡片自己的 padding，文章页另有 .is-post 规则。
     */
    --el9-main-pad: 0;

    /*
     * 内容区和侧栏之间的缝，**总宽 25**，中间那条竖线把它劈成两半：
     * 12 + 1（线）+ 12。所以这里的 gap 只管线的左半边，右半边是下面的
     * --el9-side-pad —— 线两侧到内容、到侧栏卡片的距离一样，看着才是「居中」的。
     *
     * 所有断点共用这两个值，不再按宽度分档：
     * 缝在视觉上是否「大」，取决于主栏里的元素有没有对齐（见上面 --el9-main-pad），
     * 不是靠改 gap 能调出来的 —— 之前几版来回改的就是这个弯路。
     */
    --el9-side-gap: 12px;

    /* 竖线到侧栏卡片的那半边缝（另一半是上面的 gap） */
    --el9-side-pad: 12px;

    /* 顶部导航条的高度（内容 38 + 上下内边距 8×2）。
       侧栏和目录的 sticky 都要错开这个值，否则会被导航条盖住 */
    --el9-nav-h: 55px;

    /* Light */
    --el9-bg: #ffffff;
    --el9-bg-soft: #f7f9f9;
    --el9-bg-blur: rgba(255, 255, 255, .82);
    --el9-bg-hover: rgba(15, 20, 25, .055);
    --el9-bg-press: rgba(15, 20, 25, .1);
    --el9-text: #0f1419;
    --el9-text-2: #536471;
    /* 原 #8b98a5 在白底只有 2.94:1，达不到 WCAG AA（正文要 4.5:1）。
       这个色用在时间戳、简介、友链说明这些地方，读不清就是功能缺陷 */
    --el9-text-3: #68727d;
    --el9-border: #eff3f4;
    --el9-border-strong: #cfd9de;
    --el9-shadow: 0 1px 2px rgba(0, 0, 0, .04), 0 4px 16px rgba(0, 0, 0, .04);
    --el9-skeleton: rgba(15, 20, 25, .06);

    /*
     * 提示框的五个语义色。每个色给两份：
     *   -c-xxx      原色，只当装饰用（1px 描边、5% 淡底）
     *   -c-xxx-ink  文字色，压暗过，保证白底 4.5:1
     * 别把原色直接给文字：#ff9500 在白底只有 2.20:1，#2080F0 也只有 3.88:1，
     * 当色块可以，当正文色不达标。
     */
    --el9-c-note: #2080f0;
    --el9-c-note-ink: #175cad;
    --el9-c-tip: #18a058;
    --el9-c-tip-ink: #11733f;
    --el9-c-warning: #ff9500;
    --el9-c-warning-ink: #a35f00;
    --el9-c-caution: #d03050;
    --el9-c-caution-ink: #96233a;
}

/*
 * 本主题只有亮色。
 *
 * 深色模式在 0.7.x 下线之后，这里还留着两套没用的色板：
 * 一套 @media (prefers-color-scheme: dark) + [data-theme="auto"]，
 * 一套 [data-theme="dark"]。它们不但没用，还会跟首屏那段前置脚本
 * 串起来出 bug —— 系统是深色的访客先看到黑底，脚本再把它掰回白色。
 * 现在连脚本带两套色板一起删了，:root 的 color-scheme 固定 light。
 */

/* ==========================================================================
   2. Base
   ========================================================================== */

*,
*::before,
*::after {
    box-sizing: border-box;
}

html {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
    scroll-behavior: smooth;
    /* 页面高度变化时滚动条出现/消失会让整页左右晃，先把坑占住 */
    scrollbar-gutter: stable;
}

/* 不支持的浏览器（旧 Safari）用常驻滚动条兜底 */
@supports not (scrollbar-gutter: stable) {
    html {
        overflow-y: scroll;
    }
}

@media (prefers-reduced-motion: reduce) {
    html {
        scroll-behavior: auto;
    }
}

body {
    margin: 0;
    background: var(--el9-bg);
    color: var(--el9-text);
    font-family: var(--el9-font-sans);
    font-size: 15px;
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
}

a {
    color: inherit;
    text-decoration: none;
    -webkit-tap-highlight-color: transparent;
}

button {
    font: inherit;
    color: inherit;
    background: none;
    border: 0;
    padding: 0;
    cursor: pointer;
}

img,
svg {
    display: block;
    max-width: 100%;
}

ul,
ol {
    margin: 0;
    padding: 0;
    list-style: none;
}

h1, h2, h3, h4 {
    margin: 0;
    font-weight: 700;
    letter-spacing: -.01em;
}

p {
    margin: 0;
}

/* 手机点按时的灰色高亮块去掉，点击反馈交给各控件自己的 hover/active */
* {
    -webkit-tap-highlight-color: transparent;
}

/*
 * 防止 iOS 上拉到底部时的橡皮筋把整页弹动（连吸顶栏一起晃）。
 * contain 只拦纵向链式滚动，不影响内部横向图条。
 */
body {
    overscroll-behavior-y: contain;
}

/* 全站统一焦点环。用 accent-text 更深一点，在白底上也看得清；
   不写死圆角，让焦点环贴着元素本来的形状 */
:focus-visible {
    outline: 2px solid var(--el9-accent-text);
    outline-offset: 2px;
}


/* 老浏览器没有 :focus-visible 时，退回 :focus（键盘鼠标都显示，宁可啰嗦） */
@supports not selector(:focus-visible) {
    :focus {
        outline: 2px solid var(--el9-accent-text);
        outline-offset: 2px;
    }
}

::selection {
    background: var(--el9-accent);
    color: var(--el9-accent-contrast);
}

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

.el9-skip {
    position: absolute;
    top: -60px;
    left: var(--el9-3);
    z-index: 200;
    padding: 10px 16px;
    border-radius: var(--el9-r-full);
    background: var(--el9-accent);
    color: var(--el9-accent-contrast);
    font-size: 15px;
    font-weight: 600;
    transition: top var(--el9-dur) var(--el9-ease);
}

.el9-skip:focus {
    top: var(--el9-3);
}

/* ==========================================================================
   3. 通用组件
   ========================================================================== */

.el9-avatar {
    width: 40px;
    height: 40px;
    min-width: 40px;
    border-radius: var(--el9-r-full);
    object-fit: cover;
    background: var(--el9-bg-soft);
}

.el9-avatar--text {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(140deg, var(--el9-accent), color-mix(in srgb, var(--el9-accent) 60%, #7c4dff));
    color: #fff;
    font-size: 17px;
    font-weight: 700;
    letter-spacing: 0;
}

.el9-avatar--sm {
    width: 28px;
    height: 28px;
    min-width: 28px;
    font-size: 13px;
}

.el9-badge {
    display: inline-flex;
    align-items: center;
    height: 20px;
    padding: 0 var(--el9-2);
    border-radius: var(--el9-r-sm);
    background: var(--el9-accent-soft);
    color: var(--el9-accent);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .02em;
}

.el9-dot {
    color: var(--el9-text-3);
}

.el9-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--el9-2);
    height: 40px;
    padding: 0 var(--el9-5);
    border: 1px solid var(--el9-border-strong);
    border-radius: var(--el9-r-full);
    background: transparent;
    color: var(--el9-text);
    font-size: 15px;
    font-weight: 600;
    transition: background var(--el9-dur) var(--el9-ease), border-color var(--el9-dur) var(--el9-ease),
        transform var(--el9-dur) var(--el9-ease);
}

.el9-btn:hover {
    background: var(--el9-bg-hover);
}

.el9-btn:active {
    transform: scale(.98);
}

/*
 * 实心按钮用 accent 原色，不用 accent-strong（压暗过的那档）。
 *
 * 后者配白字对比度更高（5.01:1），但跟「发表评论」那种主按钮不是一个颜色，
 * 同一个主题色在一页里出现深浅两种蓝，看着就是没跟上后台设置。
 * 统一用原色：15px/600 按大文本算，3:1 达标。
 */
.el9-btn--primary {
    background: var(--el9-accent);
    border-color: transparent;
    color: var(--el9-accent-contrast);
}

.el9-btn--primary:hover {
    filter: brightness(1.1);
}

/*
 * 输入框：白底 + 一圈看得见的浅灰线边 + 大圆角。
 *
 * 参照 Apple 账号页 —— 它**是有边的**，只是很浅（#d2d2d7 那一档），
 * 配大圆角就成一个「淡淡的框」，不是完全无边框的填充块。
 *
 * 之前那版用的是 --el9-border（#eff3f4），浅到几乎看不见，
 * 于是整排输入框看着像没有边；这里换 --el9-border-strong，看得见但不抢戏。
 */
.el9-input,
.el9-textarea {
    width: 100%;
    padding: 12px 14px;
    border: 1px solid var(--el9-border-strong);
    border-radius: 12px;
    background: var(--el9-bg);
    color: var(--el9-text);
    font-family: inherit;
    font-size: 15px;
    transition: border-color var(--el9-dur) var(--el9-ease),
                box-shadow var(--el9-dur) var(--el9-ease);
}

/* 悬停时边线压深一档，给「这儿能点」一个最轻的提示 */
.el9-input:hover,
.el9-textarea:hover {
    border-color: color-mix(in srgb, var(--el9-text) 28%, var(--el9-border-strong));
}

.el9-input:focus,
.el9-textarea:focus {
    outline: none;
    border-color: var(--el9-accent);
    box-shadow: 0 0 0 3.5px color-mix(in srgb, var(--el9-accent) 16%, transparent);
}

.el9-icon {
    flex: none;
}

.el9-search {
    display: flex;
    align-items: center;
    gap: var(--el9-2);
    height: 44px;
    padding: 0 var(--el9-4);
    border: 1px solid transparent;
    border-radius: var(--el9-r-full);
    background: var(--el9-bg-soft);
    color: var(--el9-text-2);
    transition: background var(--el9-dur) var(--el9-ease), border-color var(--el9-dur) var(--el9-ease);
}

.el9-search:focus-within {
    background: var(--el9-bg);
    border-color: var(--el9-accent);
    color: var(--el9-accent);
}

.el9-search input {
    flex: 1;
    min-width: 0;
    border: 0;
    background: none;
    color: var(--el9-text);
    font: inherit;
    font-size: 15px;
}

.el9-search input:focus {
    outline: none;
}

.el9-search--wide {
    max-width: 420px;
    margin: var(--el9-5) auto var(--el9-4);
    gap: var(--el9-3);
}

/* ==========================================================================
   4. 布局
   ========================================================================== */

.el9-shell {
    /* 跟着「内容区宽度」设置走，不然主栏会被 flex 压回去，后台调了也白调 */
    max-width: var(--el9-shell-w, 1248px);
    margin: 0 auto;
    padding: 0 var(--el9-bleed);
}

.el9-layout {
    display: flex;
    align-items: flex-start;
    /*
     * 两栏之间这条缝由布局自己给（gap），不再靠侧栏的 padding 挤出来。
     *
     * 注意别按主栏的 padding 去「补差」：信息流卡片带着负 margin，
     * 会把主栏那 28px 内边距整个吃掉，卡片右边缘正好落在主栏的盒边上。
     * 所以 gap 是多少，内容就到侧栏多少，各断点都别再调。
     */
    gap: var(--el9-side-gap);

    /*
     * 顶部留白放在这里，而不是各给主栏和侧栏一份 ——
     * 两栏都从这条线开始，**顶部必然齐平**，不管第一块是轮播、搜索头还是公告条。
     * 之前分开写，主栏那块的上边距一变（`:first-child` 归零、或某个断点把
     * main 的 padding-top 归零），两边就差一截，靠 JS 补是治标。
     *
     * 和左右共用 --el9-bleed，四周同一个量。
     */
    padding-top: var(--el9-bleed);
}

/* 底部栏和抽屉遮罩默认不出：宽屏靠侧栏和顶部导航，用不上它们 */
.el9-tabbar,
.el9-drawer-backdrop {
    display: none;
}

/* ---- 搜索浮层（顶栏 / 横幅按钮唤出） ---- */

.el9-searchbox {
    position: fixed;
    inset: 0;
    z-index: 200;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 12vh var(--el9-4) var(--el9-4);
}

.el9-searchbox[hidden] {
    display: none;
}

/* ---- 发布说说弹层（顶部「发布」按钮唤起） ---- */
.el9-composerbox {
    position: fixed;
    inset: 0;
    z-index: 210;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 6vh var(--el9-4);
}

.el9-composerbox[hidden] {
    display: none;
}

.el9-composerbox-inner {
    position: relative;
    z-index: 1;
    width: 100%;
    max-width: 620px;
    max-height: 88vh;
    overflow-y: auto;
    border-radius: var(--el9-r-lg);
    background: var(--el9-bg);
    box-shadow: 0 24px 60px rgba(16, 24, 40, .18);
    -webkit-overflow-scrolling: touch;
}

.el9-composerbox-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(16, 24, 40, .42);
    -webkit-backdrop-filter: blur(2px);
    backdrop-filter: blur(2px);
}

.el9-composerbox-close {
    position: absolute;
    top: 8px;
    right: 8px;
    z-index: 2;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border: 0;
    border-radius: var(--el9-r-full);
    background: transparent;
    color: var(--el9-text-3);
    cursor: pointer;
}

.el9-composerbox-close:hover {
    background: var(--el9-bg-hover);
    color: var(--el9-text);
}

/* 弹层里的发布框去掉自己的卡片外观，外面那层已经是卡片了 */
.el9-composerbox .el9-composer {
    margin: 0;
    border: 0;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
}

/* 弹层打开时锁住页面滚动 */
body.is-composer-open {
    overflow: hidden;
}

/* 手机：从底部上滑 */
@media screen and (max-width: 699px) {
    .el9-composerbox {
        align-items: flex-end;
        padding: 0;
    }

    .el9-composerbox-inner {
        max-width: none;
        max-height: 92vh;
        border-radius: var(--el9-r-lg) var(--el9-r-lg) 0 0;
        padding-bottom: env(safe-area-inset-bottom, 0px);
    }
}

.el9-searchbox-inner {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: center;
    gap: var(--el9-3);
    width: min(620px, 100%);
    padding: 0 var(--el9-4);
    height: 58px;
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-full);
    background: var(--el9-bg-blur);
    backdrop-filter: saturate(180%) blur(20px);
    -webkit-backdrop-filter: saturate(180%) blur(20px);
    box-shadow: 0 18px 48px rgba(0, 0, 0, .18);
    animation: el9-search-in 180ms var(--el9-ease);
}

@keyframes el9-search-in {
    from {
        opacity: 0;
        transform: translateY(-8px) scale(.98);
    }
}

.el9-searchbox-inner > .el9-icon {
    flex: none;
    color: var(--el9-text-3);
}

.el9-searchbox-inner form {
    flex: 1;
    min-width: 0;
}

.el9-searchbox-inner input {
    width: 100%;
    height: 56px;
    border: 0;
    background: none;
    color: var(--el9-text);
    font-family: inherit;
    font-size: 16px;
    outline: none;
}

.el9-searchbox-inner input::placeholder {
    color: var(--el9-text-3);
}

.el9-searchbox-close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    flex: none;
    border: 0;
    border-radius: var(--el9-r-full);
    background: var(--el9-bg-hover);
    color: var(--el9-text-2);
    cursor: pointer;
    transition: background var(--el9-dur) var(--el9-ease), color var(--el9-dur) var(--el9-ease);
}

.el9-searchbox-close:hover {
    background: var(--el9-accent-soft);
    color: var(--el9-accent);
}

.el9-searchbox-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, .34);
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
    animation: el9-fade-in 180ms var(--el9-ease);
}

@keyframes el9-fade-in {
    from {
        opacity: 0;
    }
}

/* 浮层打开时锁滚动 */
body.is-search-open {
    overflow: hidden;
}

/* ---- 左栏（导航 + 挂件，合并为一条） ---- */

/* ---- 顶部轮播（首页 / 说说归档页）----
   用 transform 平移切换，不用 scroll-snap：
   scroll-snap 在末端往回拖一点就会被弹回去，而且跟 JS 改 scrollLeft 会打架 */
.el9-carousel {
    position: relative;
    margin: var(--el9-4) 0 0;
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-lg);
    overflow: hidden;
    background: var(--el9-bg-soft);
}

/*
 * 轮播是内容区第一块时（首页最常见），它上面的 16px 外边距是多余的 ——
 * 顶部留白只由 .el9-layout 那 12px 给，再叠 16 就是首页 / 说说比文章页
 * 多出一条缝。只有前面还有公告条 / 归档标题时，这 16px 才是呼吸，保留。
 *
 * ⚠️ 光写 :first-child 认不到轮播：app.js 的打印回退会在 .el9-main 最前面
 * 插一个 display:none 的 .el9-print-head（el9PrintFallback），轮播其实是
 * 第二个孩子。所以下面必须同时写相邻兄弟那条，否则归零规则一直是死的。
 */
.el9-main > .el9-carousel:first-child,
.el9-main > .el9-print-head + .el9-carousel,
.el9-feed > .el9-carousel:first-child {
    margin-top: 0;
}

/*
 * 轮播前面有公告条时，两者之间只需要一个间距（公告自己带 16px 上边距）。
 * 不加这条的话，公告 16px + 轮播 16px 会叠出 32px。
 */
.el9-notice + .el9-carousel {
    margin-top: var(--el9-3);
}

.el9-carousel-track {
    display: flex;
    /* 每张铺满整条，靠 translateX 整屏地推 */
    transition: transform 420ms var(--el9-ease);
    will-change: transform;
}

.el9-carousel-slide {
    flex: 0 0 100%;
    min-width: 0;
}

.el9-carousel-link {
    position: relative;
    display: block;
    aspect-ratio: 21 / 9;
    text-decoration: none;
    color: #fff;
}

.el9-carousel-img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* 封面加载失败（图床防盗链 / 外站 404）：复用下面没配图那块的渐变，
   破图隐掉但保留占位尺寸，标题照常压在底部，不留一张空白卡 */
.el9-carousel-link.is-img-broken {
    background: linear-gradient(120deg, var(--el9-accent) 0%, #8b5cf6 60%, #ec4899 100%);
}

.el9-carousel-link.is-img-broken .el9-carousel-img {
    visibility: hidden;
}

/* 没配图时的占位，跟网格卡片的空态一个路数 */
.el9-carousel-ph {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    background: linear-gradient(120deg, var(--el9-accent) 0%, #8b5cf6 60%, #ec4899 100%);
    color: rgba(255, 255, 255, .82);
}

/* 标题压在底部，加一层暗角保证白字读得清 */
.el9-carousel-cap {
    position: absolute;
    inset: auto 0 0 0;
    padding: var(--el9-10) var(--el9-5) var(--el9-4);
    background: linear-gradient(180deg, transparent 0%, rgba(0, 0, 0, .55) 100%);
    pointer-events: none;
}

.el9-carousel-title {
    display: block;
    font-size: 17px;
    font-weight: 700;
    line-height: 1.4;
    letter-spacing: -.01em;
    text-shadow: 0 1px 3px rgba(0, 0, 0, .4);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* 左右箭头：跟说说横滑条那两颗用同一套长相 —— 浅色半透明圆 + 深色尖角 + 一层轻阴影 */
.el9-carousel-btn {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border: 0;
    /*
     * 深色圆角块：压在封面上，白尖角比浅底深角更稳。
     * 浅底那版遇到白墙、天空这类浅封面时，按钮边界几乎看不出来。
     */
    border-radius: var(--el9-r-full);
    background: rgba(0, 0, 0, .5);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    color: #fff;
    cursor: pointer;
    box-shadow: 0 2px 10px rgba(0, 0, 0, .2);
    /*
     * .55 常显，指针移上来才实体。
     *
     * 跟 .el9-img-strip-next / -prev 一模一样的数字 —— 这两处都是「压在图上的翻张钮」，
     * 数字不统一就会出现一种感觉：说说里的轻，轮播里的闷。
     *
     * 之前轮播用深底白箭头，单看没问题，但跟说说摆在一个页面里就是两套配色。
     * 长箭头换成尖角之后，浅底这一版已经不吃图了 —— 当初觉得突兀是因为那是一根
     * 14px 的实心横线压在封面上。
     */
    opacity: .8;
    transition: opacity var(--el9-dur) var(--el9-ease), background var(--el9-dur) var(--el9-ease);
}

.el9-carousel-btn.is-prev {
    left: var(--el9-3);
}

.el9-carousel-btn.is-next {
    right: var(--el9-3);
}

/*
 * 视觉上是 44px 的圆，但触摸目标要够 48px。
 * 用一个透明伪元素把命中区撑开，外观不变。
 */
.el9-carousel-btn::after {
    content: '';
    position: absolute;
    inset: -2px;
    border-radius: inherit;
}

.el9-carousel-btn:hover,
.el9-carousel-btn:focus-visible {
    opacity: 1;
    background: rgba(0, 0, 0, .66);
}

/* ---- 底部那条控制带：圆点 + 进度条 + 播放键（照 Apple 产品页的做法） ---- */

.el9-carousel-hud {
    position: absolute;
    inset: auto 0 var(--el9-3) 0;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    z-index: 4;
}

/* 圆点和进度条装同一个胶囊里，看起来是一整件东西 */
.el9-carousel-dots {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 9px;
    /*
     * 高度跟右边那颗播放键一模一样（34px）—— 并排放的两块东西不等高，
     * 眼睛一眼就看出来歪。内部靠 align-items 居中，不再用上下 padding 撑。
     */
    height: 34px;
    padding: 0 15px;
    border-radius: var(--el9-r-full);
    background: rgba(18, 20, 24, .42);
    backdrop-filter: saturate(180%) blur(14px);
    -webkit-backdrop-filter: saturate(180%) blur(14px);
    box-shadow: 0 2px 14px rgba(0, 0, 0, .16);
}

.el9-carousel-dot {
    position: relative;
    width: 5px;
    height: 5px;
    padding: 0;
    border: 0;
    border-radius: var(--el9-r-full);
    background: rgba(255, 255, 255, .42);
    cursor: pointer;
    /*
     * 宽度也要过渡：当前页那颗会从 5px 长成一截小胶囊，
     * 切换时旧点缩回去、新点长出来 —— Apple 那几个产品页就是这么走的。
     */
    transition: background var(--el9-dur) var(--el9-ease), width .34s var(--el9-ease);
}

/*
 * 点本身 5px，指头点不准。用伪元素把命中区撑到 40px 高
 * （横向只留 7px，相邻的点不能互相压）。
 */
.el9-carousel-dot::after {
    content: '';
    position: absolute;
    inset: -16px -7px;
}

/*
 * 当前页：点变成一截胶囊，里面那道白就是「还剩多久」。
 *
 * 进度不再单独占一根条 —— 它就在当前这个点里长出来，
 * 比起「几个点 + 一根条」少一样东西，眼睛也只需盯一处。
 */
.el9-carousel-dot.is-active {
    width: 54px;
    background: rgba(255, 255, 255, .26);
    overflow: hidden;
}

.el9-carousel-dot.is-active::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: #fff;
    transform: scaleX(var(--el9-prog, 0));
    transform-origin: left center;
    will-change: transform;
}

/* 播放 / 暂停：胶囊右边单独一颗圆钮 */
.el9-carousel-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    padding: 0;
    border: 0;
    border-radius: var(--el9-r-full);
    background: rgba(18, 20, 24, .42);
    backdrop-filter: saturate(180%) blur(14px);
    -webkit-backdrop-filter: saturate(180%) blur(14px);
    color: #fff;
    cursor: pointer;
    box-shadow: 0 2px 14px rgba(0, 0, 0, .16);
    transition: background var(--el9-dur) var(--el9-ease), transform var(--el9-dur) var(--el9-ease);
}

.el9-carousel-toggle:hover {
    background: rgba(18, 20, 24, .62);
}

.el9-carousel-toggle:active {
    transform: scale(.94);
}

.el9-carousel-toggle .el9-ico-play {
    display: none;
}

.el9-carousel.is-paused .el9-carousel-toggle .el9-ico-pause {
    display: none;
}

.el9-carousel.is-paused .el9-carousel-toggle .el9-ico-play {
    display: block;
}

/* 有标题时整条控制带上移，别压在字上 */
.el9-carousel:has(.el9-carousel-cap) .el9-carousel-hud {
    bottom: var(--el9-2);
}

.el9-carousel.is-solo .el9-carousel-link {
    aspect-ratio: 16 / 7;
}

@media screen and (max-width: 999px) {

    /*
     * 窄屏没有顶部导航条，但顶部不能贴屏幕上沿 ——
     * 和左右一样留 12，四周才是同一个量。
     */
    .el9-layout {
        padding-top: var(--el9-bleed);
    }

    /*
     * 单栏：轮播图按宽度撑满、高度跟着原图走，不裁切。
     *
     * 原来固定 16/10 + object-fit: cover，图片比例一不对就把两侧切掉 ——
     * 手机上最常见的就是封面上的标题被切掉半截。
     *
     * ⚠️ 必须同时给 min-height。
     * 高度一旦完全交给图片，图没加载出来（地址失效、外链慢、断网）时
     * img 的高度是 0 —— 整条轮播会塌成一条线，看着像「轮播没了」。
     * 180px 是兜底值：正常图片按原比例撑开，远高于它，不影响观感。
     */
    .el9-carousel-link {
        aspect-ratio: auto;
        min-height: 180px;
    }

    .el9-carousel-img {
        height: auto;
        min-height: 180px;
    }

    /* 没有图时那层渐变占位同样要撑住（它的 height:100% 在自适应容器里算不出来） */
    .el9-carousel-ph {
        min-height: 180px;
    }

    /* 单栏不摆左右箭头：手指直接划，箭头只会挡住图 */
    .el9-carousel-btn {
        display: none;
    }

    /*
     * 手机上标题直接不要。
     *
     * 窄屏图本来就矮，白字压在底部既挡图、又得眯眼读；标题在卡片和详情页都有，
     * 不靠轮播这一条。连那层压暗的渐变一起去掉 —— 只藏字、留着一条
     * 没内容的黑影，比两种都不做还难看。
     */
    .el9-carousel-cap {
        display: none;
    }

    /* 标题没了，控制带回到底部默认位置。有标题时它是 --el9-2（往上让位），
       现在不藏回来会悬在半空。 */
    .el9-carousel:has(.el9-carousel-cap) .el9-carousel-hud {
        bottom: var(--el9-3);
    }
}

/* 系统开了减弱动效就不自动播、切换也不做位移动画 */
/*
 * 轮播是内容区第一块时（首页最常见），它上面的 16px 外边距是多余的 ——
 * 顶部那 12px 由 .el9-layout 给，两层叠起来就是一道大缝。
 * 只有前面还有公告条时，这 16px 才是它跟上一块的呼吸。
 *
 * ⚠️ 这两条原来被写在 `@media (prefers-reduced-motion: reduce)` 里面
 * （大概是某次改动把新增规则插进了媒体查询块中段），于是**只有开了
 * 「减弱动态效果」的系统才生效** —— 大多数设备上轮播首块照样带 16px。
 */
.el9-main > .el9-carousel:first-child,
.el9-main > .el9-print-head + .el9-carousel,
.el9-feed > .el9-carousel:first-child {
    margin-top: 0;
}

.el9-notice + .el9-carousel {
    margin-top: var(--el9-3);
}

/* 系统开了减弱动效就不做位移动画（只留这一条在这个媒体查询里） */
@media (prefers-reduced-motion: reduce) {
    .el9-carousel-track {
        transition: none;
    }
}

/* ---- 侧栏：最新评论 ---- */

.el9-panel-empty {
    margin: 0;
    font-size: 13px;
    color: var(--el9-text-3);
}

.el9-comment-list {
    margin: 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    /* 12px 时两条评论糊在一起，头像几乎挨着上一段正文 */
    gap: var(--el9-4);
}

.el9-comment-item {
    display: flex;
    gap: var(--el9-2);
    align-items: flex-start;
}

.el9-comment-avatar {
    flex: none;
    line-height: 0;
}

.el9-comment-main {
    min-width: 0;
    flex: 1;
}

.el9-comment-link {
    display: block;
    text-decoration: none;
    color: var(--el9-text);
}

.el9-comment-link:hover .el9-comment-text {
    color: var(--el9-text);
}

.el9-comment-author {
    display: block;
    font-size: 13px;
    font-weight: 700;
    color: var(--el9-text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* 名字和时间同一行，时间靠右（参考主流站点的评论列表） */
.el9-comment-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--el9-2);
}

/* 中间多了个身份标：auto 外边距吃掉剩余空间，时间还是贴右边，
   名字和标紧挨着 —— 光靠 space-between 会把标摆到正中间 */
.el9-comment-head .el9-comment-time {
    margin-left: auto;
}

/* 名字长了要能缩，不缩就把标和时间挤出侧栏 */
.el9-comment-head .el9-comment-author {
    min-width: 0;
    flex: 0 1 auto;
}

/* 侧栏比正文窄，标跟着小一号，否则「神秘人」三个字会顶掉时间 */
.el9-comment-head .el9-cmt-badge {
    flex: none;
    font-size: 10px;
    padding: 2px 6px;
    /* 基线对齐会让小标浮在名字上方，改成跟着字面走 */
    align-self: center;
}

.el9-comment-time {
    flex: none;
    font-size: 11px;
    color: var(--el9-text-3);
}

.el9-comment-text {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    line-clamp: 2;
    overflow: hidden;
    margin-top: 2px;
    font-size: 12.5px;
    line-height: 1.6;
    color: var(--el9-text-2);
    overflow-wrap: break-word;
    word-break: break-word;
}

/* 摘要里的表情：跟着 12.5px 的字走，别把两行的高度撑开 */
.el9-comment-text .el9-emoji {
    height: 1.15em;
    max-width: 2.2em;
    margin: 0 1px;
    vertical-align: -0.18em;
}


/* ---- 右下角滚动钮（前往底部 / 返回顶部）----
 *
 * 两颗装在一个 flex 容器里竖排，顺序是「回顶部在上、去底部在下」——
 * 也就是**先出现的那颗放最下面**：容器贴右下角往上长，先出现的永远不动，
 * 后出现的往上加。反过来的话，第二颗冒出来时会把第一颗整体顶上去，看着像跳了一下。
 *
 * 早先是各自 position:fixed + 写死 bottom（一颗 32、一颗 80），
 * 结果只显示一颗时，另一颗本来占的位置会空出一大块 —— 手机端最明显，
 * 去底部孤零零飘在高处，中间空一段，看着像少了东西。
 * 现在改用 display 控制显隐：不显示的按钮不占位，两颗自然贴在一起。
 */
.el9-fabs {
    position: fixed;
    right: var(--el9-5);
    bottom: var(--el9-8);
    z-index: 50;
    display: flex;
    flex-direction: column;
    gap: 8px;
    align-items: center;
    /* 容器透明区域不该挡住正文的点选，按钮自己再打开 */
    pointer-events: none;
}

.el9-fabs > button {
    pointer-events: auto;
}

/* 两颗共用的外观 */
.el9-backtop,
.el9-gobottom {
    /* 默认 display:none —— 这是「不占位」的关键 */
    display: none;
    position: relative;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-full);
    background: var(--el9-bg-blur);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    color: var(--el9-text-2);
    cursor: pointer;
    /* 显示时也只到「半透明」这一档，指针移上去才回到完全实心 */
    opacity: var(--el9-fab-alpha);
    transition: opacity var(--el9-dur) var(--el9-ease), background var(--el9-dur) var(--el9-ease);
}

.el9-backtop.is-show,
.el9-gobottom.is-show {
    display: inline-flex;
    /* display 切换没法过渡，用一段短动画补上淡入的手感 */
    animation: el9-fabs-in 200ms var(--el9-ease);
}

@keyframes el9-fabs-in {
    from {
        opacity: 0;
        transform: translateY(6px);
    }

    to {
        opacity: var(--el9-fab-alpha);
        transform: translateY(0);
    }
}

.el9-backtop:hover,
.el9-gobottom:hover {
    opacity: 1;
    background: var(--el9-bg);
    color: var(--el9-accent-text);
}

/* 视觉 40px，命中区撑到 44px */
.el9-backtop::after,
.el9-gobottom::after {
    content: '';
    position: absolute;
    inset: -2px;
    border-radius: inherit;
}

/* 箭头朝上：左 + 上两条边拼成 ┌，再转 45° */
.el9-backtop::before {
    content: '';
    width: 14px;
    height: 14px;
    border-left: 2px solid currentColor;
    border-top: 2px solid currentColor;
    transform: rotate(45deg) translate(2px, 2px);
}

/* 箭头朝下：左 + 下两条边拼成 └，再转 -45° */
.el9-gobottom::before {
    content: '';
    width: 14px;
    height: 14px;
    border-left: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    transform: rotate(-45deg) translate(2px, -2px);
}


/* ---- 手机端呼出菜单的悬浮钮 ----
   桌面端用不上（顶部有整条站点导航），只在 ≤999 出现；
   点它打开抽屉，抽屉里第一块是「导航菜单」配的那几项（见 header.php）。 */
.el9-fab {
    display: none;
}

@media screen and (max-width: 999px) {
    .el9-fab {
        position: fixed;
        /* 和返回顶部那颗右对齐，两颗钮排在同一条竖线上 */
        right: var(--el9-5);
        /* 底部栏 52 + iPhone 那条横条 + 一点呼吸 */
        bottom: calc(52px + env(safe-area-inset-bottom, 0px) + var(--el9-3));
        z-index: 50;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 44px;
        height: 44px;
        border: 1px solid var(--el9-border);
        border-radius: var(--el9-r-full);
        background: var(--el9-bg-blur);
        backdrop-filter: saturate(180%) blur(10px);
        -webkit-backdrop-filter: saturate(180%) blur(10px);
        color: var(--el9-text-2);
        box-shadow: var(--el9-shadow);
        cursor: pointer;
        /* 和返回顶部那颗同一个透明度档（见 :root 的 --el9-fab-alpha） */
        opacity: var(--el9-fab-alpha);
        transition: transform var(--el9-dur) var(--el9-ease),
            color var(--el9-dur) var(--el9-ease),
            opacity var(--el9-dur) var(--el9-ease);
    }

    .el9-fab:active {
        /* 触屏没有 hover，按下这一下就拉到实心，给个「点到了」的反馈 */
        opacity: 1;
        transform: scale(.96);
    }

    .el9-fab:hover {
        opacity: 1;
        color: var(--el9-text);
    }
}

/* ---- 抽屉里的站点导航 ----
   桌面端这条导航在页面顶部，抽屉里再摆一遍是重复的，所以默认不显示。 */
.el9-sidenav {
    display: none;
}

@media screen and (max-width: 999px) {
    /*
     * 抽屉里只放导航菜单。
     *
     * 侧栏那些挂件（名片、最新评论、热门标签、分类）在手机上没人滑开抽屉去看 ——
     * 底部栏和内容区已经够用，抽屉里塞一堆只会让人多点两下。
     */
    .el9-side .el9-rail {
        display: none;
    }

    .el9-sidenav {
        display: block;
    }

    /* 小标题：给这列东西一个名字，别让人以为是挂件 */
    .el9-sidenav-title {
        margin: 0 0 var(--el9-2);
        padding: 0 10px;
        font-size: 12px;
        font-weight: 600;
        letter-spacing: .08em;
        color: var(--el9-text-3);
    }

    .el9-sidenav-list {
        display: flex;
        flex-direction: column;
        gap: 2px;
        margin: 0;
        padding: 0;
        list-style: none;
    }

    .el9-sidenav-list a {
        display: flex;
        align-items: center;
        gap: var(--el9-3);
        padding: 12px 10px;
        border-radius: var(--el9-r-sm);
        color: var(--el9-text);
        font-size: 16px;
        text-decoration: none;
        transition: background var(--el9-dur) var(--el9-ease),
            color var(--el9-dur) var(--el9-ease);
    }

    .el9-sidenav-list a:hover,
    .el9-sidenav-list a:active {
        background: var(--el9-bg-hover);
    }

    /* 当前页：底色 + 强调色文字，扫一眼就知道自己在哪儿 */
    .el9-sidenav-list a.is-active {
        background: var(--el9-bg-hover);
        color: var(--el9-accent-text);
        font-weight: 600;
    }

    .el9-sidenav-list .el9-icon {
        flex: none;
        color: var(--el9-text-3);
    }

    .el9-sidenav-list a.is-active .el9-icon {
        color: var(--el9-accent-text);
    }
}

.el9-backtop:focus-visible {
    outline: 2px solid var(--el9-accent-text);
    outline-offset: 2px;
}

/* ---- 站点导航（顶部横条，原来在侧边栏）---- */

.el9-sitenav {
    position: sticky;
    top: 0;
    z-index: 60;
    display: flex;
    align-items: center;
    gap: var(--el9-4);
    margin: 0 calc(var(--el9-bleed) * -1);
    padding: var(--el9-2) var(--el9-bleed);
    border-bottom: 1px solid var(--el9-border);
    /* 浅色底 + 毛玻璃：滚起来时下面的内容会从底下透过去，不显脏 */
    background: var(--el9-bg-blur);
    backdrop-filter: saturate(180%) blur(12px);
    -webkit-backdrop-filter: saturate(180%) blur(12px);
}

/* el9Nav() 原本是给侧栏写的：.el9-nav-inner 是纵向 flex + 16px 间距，
   里面还挂着 .el9-nav-foot（主题切换 / RSS / 登录）。搬到顶部必须整个掰成横排，
   否则导航项和下面那排图标会竖着堆起来，导航条高度直接爆掉 */
.el9-sitenav .el9-nav {
    min-width: 0;
    flex: 1;
    padding: 0;
}

.el9-sitenav .el9-nav-inner {
    flex-direction: row;
    align-items: center;
    gap: 0;
    min-width: 0;
}

/* 侧栏里是竖排，顶部改成横排 */
.el9-sitenav .el9-nav-list {
    display: flex;
    /* 必须显式写 row：基础规则里 .el9-nav-list 自带 flex-direction: column，
       只写 display:flex 覆盖不掉它，导航项照样竖着排 */
    flex-direction: row;
    align-items: center;
    gap: var(--el9-1);
    flex: 1;
    min-width: 0;
    margin: 0;
    padding: 0;
    list-style: none;
    overflow-x: auto;
    scrollbar-width: none;
}

.el9-sitenav .el9-nav-list::-webkit-scrollbar {
    display: none;
}

/* 顶部右侧已经有自己的一排工具图标了，侧栏那套（带分隔线的）不再重复摆 */
.el9-sitenav .el9-nav-foot {
    display: none;
}

.el9-sitenav .el9-nav-item {
    flex: none;
    height: 38px;
    padding: 0 var(--el9-3);
    white-space: nowrap;
}

/* 横排时文字按内容宽度走，别撑开 */
.el9-sitenav .el9-nav-item span {
    flex: none;
}

.el9-sitenav-tools {
    flex: none;
    display: flex;
    align-items: center;
    gap: var(--el9-1);
}

.el9-sitenav-tool {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    border: 0;
    border-radius: var(--el9-r-full);
    background: transparent;
    color: var(--el9-text-2);
    cursor: pointer;
    transition: background var(--el9-dur) var(--el9-ease), color var(--el9-dur) var(--el9-ease);
}

.el9-sitenav-tool:hover {
    background: var(--el9-bg-hover);
    color: var(--el9-text);
}

/* 汉堡（头像按钮）：桌面端不需要，手机端导航走的是底部栏 —— 所以现在两头都不露，
   只在以后想把导航搬回顶部时才有用。别看到 display:none 就以为是 bug */
.el9-sitenav-tool--menu {
    display: none;
}

.el9-sitenav-tool:focus-visible {
    outline: 2px solid var(--el9-accent-text);
    outline-offset: 2px;
}

/*
 * 导航按钮里每个只放一个图标（图标是实心的，颜色跟着 color 走）。
 * 这里原来有一套「深浅两个图标只显示一个」的规则（.el9-icon:first-child / :last-child
 * 配 :root[data-theme=dark]），现在已经没有双图标的按钮了 —— 留着反而危险：
 * 哪天某个按钮里的图标不是首个子元素，就会被 display:none 吃掉，图标凭空消失。
 */

/* ---- 名片挪进侧边栏后的尺寸适配 ----
   原来在主栏（880px 宽），现在只有 296px，头像和横幅都得收 */
.el9-rail .el9-banner {
    /* 外边距归零：侧栏是 flex 列，兄弟之间本来就有 gap(16)。
       再给一个 margin-bottom 就是双份间距，名片和下面那块被撑开一大截 */
    margin-bottom: 0;
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-lg);
    overflow: hidden;
    background: var(--el9-bg);
}

/* 横幅按固定高度，不按比例：侧栏内宽只有 248px，3:1 换算出来才 83px 高，
   头像压上去几乎顶满，看着就错位。118px 比之前 96 再放宽一点，头像和文字都不那么挤 */
.el9-rail .el9-banner-cover {
    height: 118px;
}

/* 顶部导航条已经有搜索 / 邮件 / RSS 了，名片右上角这排按钮收起来，
   不然两个 36px 的圆按钮要挤掉窄横幅三分之一的宽度 */
.el9-rail .el9-banner-tools {
    display: none;
}

.el9-rail .el9-banner-body {
    /* 左右留 16；底部从 20 收到 12 —— 统计条下面空一大块，
       名片看着像没写完，标题下面就直接断在半空 */
    padding: 0 var(--el9-4) var(--el9-3);
    /* 居中排布：头像左对齐时右边空一大块，名片看着像没做完 */
    text-align: center;
}

/* 侧栏名片头像 76px，上移 41px ≈ 自身一半（含 3px 白边），正好骑在横幅下沿。
   原来是 64px，在 300px 宽的侧栏里只占两成，显得局促 */
.el9-rail .el9-banner-avatar {
    width: 76px;
    height: 76px;
    /* 上下照旧（骑在封面上），左右 auto 让它水平居中 */
    margin: -41px auto var(--el9-3);
    border-width: 3px;
}

.el9-rail .el9-banner-avatar-link {
    display: block;
    width: 100%;
    height: 100%;
    border-radius: var(--el9-r-full);
    text-decoration: none;
}

.el9-rail .el9-banner-avatar-link:focus-visible {
    outline: 2px solid var(--el9-accent-text);
    outline-offset: 2px;
}

.el9-rail .el9-banner-avatar.el9-avatar--text,
.el9-rail .el9-banner-avatar .el9-avatar--text {
    font-size: 22px;
}

.el9-rail .el9-banner-name strong {
    font-size: 17px;
}

.el9-rail .el9-banner-name span {
    font-size: 12.5px;
}

.el9-rail .el9-banner-bio {
    margin-top: var(--el9-3);
    font-size: 13px;
    line-height: 1.65;
}

/* 统计三列均分，用一条细线跟上面的签名隔开 —— 侧栏窄，靠间距分不开层次。
   上下各留 14，比之前宽松 */
.el9-rail .el9-banner-stat {
    gap: 0;
    margin: var(--el9-4) 0 0;
    padding-top: var(--el9-3);
    border-top: 1px solid var(--el9-border);
}

.el9-rail .el9-banner-stat li {
    flex: 1;
    padding: 0;
    justify-content: center;
    text-align: center;
}

.el9-rail .el9-banner-stat strong {
    font-size: 15px;
}

.el9-rail .el9-banner-stat span {
    font-size: 10.5px;
}

/* ---- 侧栏「我们的故事」入口 ----
   挂在名片下面，认得出访客才出现。按他的意思**不做成按钮**：
   名片下面再来一个带框的方块，整块侧栏就太"重"了，
   一行「👋 昵称 你好呀 →」读起来像招呼，点点就进去 */
.el9-myentry {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    /* 不加内边距，跟名片底部留出的那点气口对齐 */
    padding: 0;
    border: 0;
    background: none;
    color: var(--el9-text-2);
    font-size: 13px;
    font-weight: 400;
    text-decoration: none;
    transition: color .18s ease;
}

.el9-myentry:hover {
    color: var(--el9-accent-text);
}

.el9-myentry:focus-visible {
    outline: 2px solid var(--el9-accent-text);
    outline-offset: 3px;
    border-radius: var(--el9-r-sm);
}

/* 名字可能很长（有人昵称就是一串英文），截断别把箭头挤出去 */
.el9-myentry-text {
    min-width: 0;
    max-width: 13em;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 600;
}

.el9-myentry-hi {
    color: var(--el9-text-3);
}

/* 右边这个小箭头是「能点进去」的唯一暗示 —— 文字换成了名字，
   光看名字谁也想不到它是个入口 */
.el9-myentry-go {
    display: inline-flex;
    align-items: center;
    color: var(--el9-text-3);
    transition: transform .18s ease, color .18s ease;
}

.el9-myentry:hover .el9-myentry-go {
    color: var(--el9-accent-text);
    transform: translateX(2px);
}

/*
 * 挥手的 👋
 *
 * emoji 是字体字形，默认绕自身中心转 —— 看着像在原地打圈。
 * transform-origin 挪到右下角（手腕位置）才像在挥手。
 *
 * 节奏：前 1.3 秒摆几下，然后停到 2.8 秒再摆 —— 一直高频抖动很吵。
 * 侧栏入口和「我们的故事」页抬头共用这一个类。
 */
.el9-wave {
    display: inline-block;
    transform-origin: 70% 85%;
    animation: el9-wave 2.8s ease-in-out infinite;
}

.el9-myentry-wave {
    font-size: 15px;
    line-height: 1;
}

@keyframes el9-wave {
    0%   { transform: rotate(0deg); }
    8%   { transform: rotate(14deg); }
    16%  { transform: rotate(-6deg); }
    24%  { transform: rotate(12deg); }
    32%  { transform: rotate(-4deg); }
    40%  { transform: rotate(9deg); }
    48%  { transform: rotate(0deg); }
    100% { transform: rotate(0deg); }
}

/* 关了动效的机器（前庭功能敏感 / 省电模式）就别摆了 */
@media (prefers-reduced-motion: reduce) {
    .el9-wave {
        animation: none;
    }
}

.el9-side {
    flex: 0 0 var(--el9-side-w);
    width: var(--el9-side-w);
    /* 缝的左半边由 .el9-layout 的 gap 给，右半边在这里；竖线正好落在两半中间 */
    padding: 0 var(--el9-side-pad) var(--el9-8) 0;
    border-right: 1px solid var(--el9-border);
}

@media screen and (min-width: 1000px), print {
    /*
     * 侧栏：先跟随页面滚，内容全部露出后钉住。
     *
     * 关键在 top 值 = 视口高 − 侧栏高（侧栏高度由 JS 写进 --el9-side-h，
     * 只在尺寸变化时更新一次，滚动时不跑 JS）。
     * 侧栏比视口高时这个值是负数，sticky 允许元素顶边顶到视口上方那么多，
     * 于是滚过那段距离后它就停住 —— 正好是「露出底部后钉住」。
     *
     * 之前用 JS 在滚动里读 getBoundingClientRect + 写 transform，
     * 每帧强制同步布局，结果一滚就抖。交给原生 sticky 就不抖了。
     * 兜底：变量没值的时候 top = 0，退化成常规的顶部吸附。
     */
    .el9-side {
        position: sticky;
        /*
         * 钳在 0 以内：侧栏比视口**矮**时，100vh − 侧栏高会是正数，
         * sticky 会立刻把整列往下推那么多 —— 内容少的页面侧栏顶部就空一大块。
         * 取 min(0, …) 后矮侧栏老老实实贴着顶部（top: 0），
         * 高侧栏仍是负数，保留「内容全部露出后钉住」的原行为。
         */
        top: min(0px, calc(100vh - var(--el9-side-h, 100vh)));
    }
}

/* ---- 侧栏挪到右边（后台「侧栏位置」选了右边）----
   用 row-reverse 而不是改 DOM 顺序：源文件里侧栏在前面，
   键盘和读屏的浏览顺序还是「导航 → 正文」，这才是合理的顺序 */
@media screen and (min-width: 1000px), print {
    body.is-side-right .el9-layout {
        flex-direction: row-reverse;
    }

    /* 侧栏挪到右边时，竖线和内边距一起换到左边，缝的算法不变 */
    body.is-side-right .el9-side {
        padding: 0 0 var(--el9-8) var(--el9-side-pad);
        border-right: 0;
        border-left: 1px solid var(--el9-border);
    }
}

.el9-side::-webkit-scrollbar {
    width: 6px;
}

.el9-side::-webkit-scrollbar-thumb {
    background: var(--el9-border-strong);
    border-radius: 3px;
}

.el9-side::-webkit-scrollbar-track {
    background: transparent;
}

.el9-link {
    display: flex;
    align-items: center;
    gap: var(--el9-3);
    padding: var(--el9-2);
    border-radius: var(--el9-r-sm);
    color: var(--el9-text);
    text-decoration: none;
    transition: background var(--el9-dur) var(--el9-ease);
}

.el9-link:hover {
    background: var(--el9-bg-hover);
}

.el9-link-logo {
    flex: none;
    width: 36px;
    height: 36px;
    border-radius: var(--el9-r-sm);
    border: 1px solid var(--el9-border);
    background: var(--el9-bg-soft);
    overflow: hidden;
    line-height: 0;
}

.el9-link-logo img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* 拿不到 logo 时用站点名首字 */
.el9-link-logo b {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    font-size: 15px;
    font-weight: 700;
    color: var(--el9-text-3);
}

.el9-link-text {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;
}

.el9-link-text strong {
    font-size: 14px;
    font-weight: 600;
    color: var(--el9-text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.el9-link-text span {
    font-size: 12px;
    color: var(--el9-text-3);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.el9-link:hover .el9-link-text strong {
    color: var(--el9-accent);
}

/* ---- 友情链接独立页（page-links.php，版式参考 pix） ---- */

.el9-links-total {
    font-size: 13px;
    font-weight: 600;
    color: var(--el9-text-3);
    background: var(--el9-bg-soft);
    border-radius: var(--el9-r-full);
    padding: 3px 10px;
}

.el9-links-page {
    margin-top: var(--el9-4);
}

.el9-links-group + .el9-links-group {
    margin-top: var(--el9-6);
}

.el9-links-group-title {
    display: flex;
    align-items: center;
    gap: var(--el9-1);
    margin: 0 0 var(--el9-3);
    font-size: 14px;
    font-weight: 700;
    color: var(--el9-text-2);
}

.el9-links-group-title em {
    font-style: normal;
    font-size: 12px;
    font-weight: 600;
    color: var(--el9-text-3);
    background: var(--el9-bg-soft);
    border-radius: var(--el9-r-full);
    padding: 1px 8px;
}

/* 两列卡片，窄屏自动掉成一列 */
.el9-links-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--el9-2);
}

.el9-links-card {
    position: relative;
    display: flex;
    align-items: center;
    padding: var(--el9-2);
    border-radius: var(--el9-r-md);
    border: 1px solid var(--el9-border);
    background: var(--el9-bg);
    transition: border-color var(--el9-dur) var(--el9-ease),
                background var(--el9-dur) var(--el9-ease);
}

.el9-links-card:hover {
    border-color: var(--el9-border-strong);
    background: var(--el9-bg-soft);
}

.el9-links-card-main {
    display: flex;
    align-items: center;
    gap: var(--el9-3);
    min-width: 0;
    flex: 1 1 auto;
    color: var(--el9-text);
    text-decoration: none;
}

.el9-links-avatar {
    flex: none;
    position: relative;      /* 给右下角的在线状态点当定位参照 */
    width: 46px;
    height: 46px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--el9-r-sm);
    border: 1px solid var(--el9-border);
    background: var(--el9-bg);
    /*
     * 这里**不能** overflow: hidden —— 状态点故意压出头像边缘 2px，
     * 一裁就只剩个月牙。要裁的是里面的图，交给 img 自己的圆角。
     */
    overflow: visible;
    font-size: 18px;
    font-weight: 700;
    color: var(--el9-text-3);
}

/*
 * 在线状态点：绿 = 站点正常，红 = 已失效。
 * 数据来自 Links 插件的 state 字段（1 正常 / 2 失效），不用额外表。
 */
.el9-links-avatar::after {
    content: '';
    position: absolute;
    right: -3px;
    bottom: -3px;
    width: 11px;
    height: 11px;
    border-radius: var(--el9-r-full);
    border: 2px solid var(--el9-bg);
    background: #0cd07e;
    box-shadow: 0 0 0 1px rgba(12, 208, 126, .28);
}

.el9-links-card.is-off .el9-links-avatar::after {
    background: #ff5c77;
    box-shadow: 0 0 0 1px rgba(255, 92, 119, .28);
}

/* 失效的友链：整体压低，别跟正常站点抢注意力 */
.el9-links-card.is-off {
    background: var(--el9-bg-soft);
}

.el9-links-card.is-off .el9-links-card-main {
    cursor: default;
}

.el9-links-card.is-off .el9-links-avatar img,
.el9-links-card.is-off .el9-links-name {
    opacity: .55;
}

.el9-links-avatar img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* 父级改成 overflow: visible 之后，圆角得由图片自己裁 */
    border-radius: inherit;
}

.el9-links-info {
    display: grid;
    min-width: 0;
}

.el9-links-name {
    font-size: 14px;
    font-weight: 600;
    color: var(--el9-text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    transition: color var(--el9-dur) var(--el9-ease);
}

.el9-links-desc {
    font-size: 12px;
    color: var(--el9-text-3);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.el9-links-go {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    margin-left: var(--el9-1);
    border-radius: var(--el9-r-full);
    background: var(--el9-bg);
    color: var(--el9-text-3);
    opacity: 0;
    transform: translateX(-4px);
    transition: opacity var(--el9-dur) var(--el9-ease),
                transform var(--el9-dur) var(--el9-ease),
                color var(--el9-dur) var(--el9-ease);
}

.el9-links-card:hover .el9-links-go {
    opacity: 1;
    transform: translateX(0);
    color: var(--el9-text);
}

.el9-links-apply {
    display: flex;
    align-items: center;
    gap: var(--el9-2);
    margin: var(--el9-8) 0 0;
    font-size: 13px;
    color: var(--el9-text-3);
}

@media screen and (max-width: 640px) {
    .el9-links-grid {
        grid-template-columns: minmax(0, 1fr);
    }

    /* 触屏没有 hover，直接常显，免得看不出能点 */
    .el9-links-go {
        opacity: 1;
        transform: none;
    }
}

/*
 * 侧栏两块之间的间距 —— 这里**不能**用 `.el9-side > * + *` 那种写法。
 *
 * ⚠️ 结构选择器（`+`、`~`、`:first-child`）**不看 display**。
 * 侧栏第一个孩子是手机抽屉的导航 nav（桌面 display:none），
 * 但它照样算「前一个兄弟」，于是名片卡被凭空推下 20 —— 主栏顶部齐、侧栏低 20，
 * 就是「距离还是不对」的全部原因。改成 `+ .el9-rail` 也没用，一样会匹配。
 *
 * 手机上那个 nav 和名片卡本来就不会同时出现（≤999 时名片卡整块隐藏），
 * 这条间距没有存在的必要，删掉。
 */

/* ---- 主页横幅 ---- */

.el9-banner {
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-lg);
    background: var(--el9-bg-soft);
    overflow: hidden;
}

.el9-banner-cover {
    position: relative;
    height: 220px;
    background: var(--el9-skeleton);
}

.el9-banner-cover img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.el9-banner-cover.is-fallback {
    background: linear-gradient(120deg, var(--el9-accent) 0%, #8b5cf6 55%, #ec4899 100%);
}

.el9-banner-cover::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(0,0,0,.08) 0%, transparent 40%, rgba(0,0,0,.22) 100%);
    pointer-events: none;
}

.el9-banner-tools {
    position: absolute;
    top: var(--el9-3);
    right: var(--el9-3);
    z-index: 2;
    display: flex;
    gap: var(--el9-2);
}

.el9-banner-tool {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: var(--el9-r-full);
    border: 1px solid rgba(255, 255, 255, .35);
    background: rgba(255, 255, 255, .18);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    color: #fff;
    transition: background var(--el9-dur) var(--el9-ease);
}

.el9-banner-tool:hover {
    background: rgba(255, 255, 255, .32);
    color: #fff;
}

.el9-banner-body {
    position: relative;
    padding: 0 var(--el9-5) var(--el9-5);
}

/* 退出登录：名片主体右上角那颗小圆按钮（只有登录后才有）
   放这儿而不是 .el9-banner-tools —— 那个区块在侧栏是 display:none 的。 */
.el9-banner-out {
    position: absolute;
    top: 2px;
    right: 2px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    border: 1px solid var(--el9-border);
    background: var(--el9-bg);
    color: var(--el9-text-3);
    text-decoration: none;
    transition: color var(--el9-dur) var(--el9-ease),
                border-color var(--el9-dur) var(--el9-ease),
                background var(--el9-dur) var(--el9-ease);
}

.el9-banner-out:hover {
    color: var(--el9-c-caution-ink);
    border-color: color-mix(in srgb, var(--el9-c-caution) 45%, var(--el9-border));
    background: color-mix(in srgb, var(--el9-c-caution) 7%, var(--el9-bg));
}

.el9-banner-out .el9-icon {
    display: block;
    pointer-events: none;
}

/* 退出改成 POST 表单后，让提交按钮铺满整颗圆，点击区域跟原来的 <a> 一致 */
.el9-banner-out button {
    /*
     * 这里必须 flex 居中，不能是 block：
     * block 按钮里的 svg 贴在左上角（实测 offsetLeft=0，居中该是 4.5px），
     * 圆里看着箭头整个偏左，iOS / 安卓上尤其明显。
     * Safari 的 button 还带默认 appearance / 内边距 / 描边，一并归零。
     */
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    -webkit-appearance: none;
    appearance: none;
    cursor: pointer;
}

.el9-banner-avatar {
    position: relative;
    z-index: 3;
    width: 88px;
    height: 88px;
    margin-top: -44px;
    margin-bottom: var(--el9-3);
    border-radius: var(--el9-r-full);
    border: 4px solid var(--el9-bg);
    background: var(--el9-bg);
    /*
     * 这里**不能**用 overflow: hidden。
     * 它配 border-radius: 100% 等于给容器套了个圆形裁切，
     * 而右下角那个在线绿点是故意超出容器 3px 的（要压在头像边缘上），
     * 一裁就只剩个绿色小月牙。头像图自己已经有 border-radius 收圆了，
     * 文字头像在下面也单独补了，不需要容器再裁。
     */
    overflow: visible;
    line-height: 0;
    box-shadow: 0 4px 16px rgba(0, 0, 0, .08);
}

.el9-banner-avatar .el9-avatar {
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: var(--el9-r-full);
}


.el9-banner-avatar.el9-avatar--text,
.el9-banner-avatar .el9-avatar--text {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    /* 容器不再 overflow: hidden（要给在线绿点留出口），文字头像得自己收圆 */
    border-radius: var(--el9-r-full);
    font-size: 32px;
    font-weight: 700;
    color: #fff;
    background: var(--el9-accent);
    line-height: 1;
}

.el9-banner-name {
    display: flex;
    align-items: baseline;
    gap: var(--el9-2);
    color: inherit;
}

/* 侧栏名片里的站名也居中（它是 flex，光靠 text-align 管不到） */
.el9-rail .el9-banner-name {
    justify-content: center;
}

.el9-banner-name strong {
    font-size: 21px;
    font-weight: 700;
    letter-spacing: -.01em;
}

.el9-banner-name span {
    font-size: 14px;
    color: var(--el9-text-2);
}

.el9-banner-bio {
    margin: var(--el9-2) 0 0;
    font-size: 14px;
    line-height: 1.6;
    color: var(--el9-text-2);
}

.el9-banner-stat {
    display: flex;
    gap: var(--el9-6, 32px);
    margin: var(--el9-4) 0 0;
    padding: 0;
    list-style: none;
}

.el9-banner-stat li {
    display: flex;
    align-items: baseline;
    gap: 6px;
}

.el9-banner-stat strong {
    font-size: 19px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: var(--el9-text);
}

.el9-banner-stat span {
    font-size: 13px;
    color: var(--el9-text-2);
}

/* ---- 主页公告条 ---- */

/* 公告条：摆在内容页顶部、轮播上方。
   早先它在侧边栏里，做成胶囊形；现在横跨整个内容区，改回圆角矩形更顺眼 */
.el9-notice {
    display: flex;
    align-items: flex-start;
    gap: var(--el9-2);
    /*
     * 顶部不留外边距：这一条常常是列表页的第一块，
     * 上方那 12px 由 .el9-layout 统一给。原来这里还有 margin-top: 16，
     * 叠上去就是 28 —— 开了常驻公告，顶部就比别的页面宽一截。
     */
    margin: 0;
    padding: var(--el9-3) var(--el9-4);
    border-radius: var(--el9-r-md);
    border: 1px solid color-mix(in srgb, var(--el9-accent) 22%, transparent);
    background: color-mix(in srgb, var(--el9-accent) 8%, var(--el9-bg-soft));
    color: var(--el9-text);
}

.el9-notice p {
    margin: 0;
    font-size: 14px;
    line-height: 1.6;
    overflow-wrap: break-word;
    word-break: break-word;
}

.el9-notice .el9-icon {
    flex: 0 0 auto;
    color: var(--el9-accent);
}

/* ---- 站点标识与导航 ---- */

.el9-nav-inner {
    display: flex;
    flex-direction: column;
    gap: var(--el9-4);
}

.el9-nav-list {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.el9-nav-item {
    display: flex;
    align-items: center;
    gap: var(--el9-3);
    height: 40px;
    padding: 0 var(--el9-3);
    border-radius: var(--el9-r-sm);
    font-size: 15px;
    /* 菜单是导航主干，字重给够才有层级（500 在侧栏里跟正文混在一起） */
    font-weight: 700;
    letter-spacing: -.01em;
    color: var(--el9-text);
    transition: background var(--el9-dur) var(--el9-ease), color var(--el9-dur) var(--el9-ease);
}

.el9-nav-item > .el9-icon {
    color: var(--el9-text-2);
    transition: color var(--el9-dur) var(--el9-ease);
}

.el9-nav-item span {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.el9-nav-item:hover {
    background: var(--el9-bg-hover);
}

.el9-nav-item:hover > .el9-icon,
.el9-nav-item.is-active > .el9-icon {
    color: var(--el9-accent);
}

.el9-nav-item.is-active {
    background: var(--el9-accent-soft);
    color: var(--el9-accent);
    font-weight: 700;
}

.el9-nav-count {
    flex: none;
    font-size: 12px;
    font-weight: 500;
    color: var(--el9-text-3);
    font-variant-numeric: tabular-nums;
}

.el9-nav-item.is-active .el9-nav-count {
    color: var(--el9-accent);
}

.el9-compose {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--el9-2);
    height: 44px;
    border-radius: var(--el9-r-sm);
    background: var(--el9-accent);
    color: var(--el9-accent-contrast);
    font-size: 15px;
    font-weight: 600;
    box-shadow: 0 1px 2px rgba(0, 0, 0, .06);
    transition: filter var(--el9-dur) var(--el9-ease), transform var(--el9-dur) var(--el9-ease);
}

.el9-compose:hover {
    filter: brightness(1.06);
}

.el9-compose:active {
    transform: scale(.985);
}

/*
 * 抽屉底栏的小工具按钮（RSS）。
 * 原来和深浅色切换共用一组样式（.el9-theme-toggle, .el9-nav-mini），
 * 切换下线清理废弃样式时差点把这组一起带走 —— 这里单独留给它。
 */
.el9-nav-mini {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: var(--el9-r-sm);
    color: var(--el9-text-2);
    transition: background var(--el9-dur) var(--el9-ease), color var(--el9-dur) var(--el9-ease);
}

.el9-nav-mini:hover {
    background: var(--el9-bg-hover);
    color: var(--el9-accent);
}

.el9-nav-foot {
    display: flex;
    align-items: center;
    gap: var(--el9-1);
    margin-top: 0;
    padding-top: var(--el9-3);
    border-top: 1px solid var(--el9-border);
}

/* ---- 主栏 ---- */

.el9-main {
    flex: 1 1 var(--el9-main-w);
    min-width: 0;
    padding: 0 var(--el9-main-pad) var(--el9-8);
    min-height: 100vh;
}

/*
 * 主内容区不画焦点环。
 *
 * 它挂着 tabindex="-1"，只为让「跳到主内容」那个锚点能把焦点送过来，
 * 本身不是可交互元素 —— 给它画框没有意义。
 *
 * 而 Edge 在这里有个额外动作：点开图片看大图、再按 Esc 关闭时，
 * 焦点会甩到最近的带 tabindex 的元素上（就是这一块），
 * 又因为最后一下是键盘，:focus-visible 成立，于是整个内容区被一个
 * 2px 蓝框圈住，看着像「整页被选中了」。
 */
.el9-main:focus,
.el9-main:focus-visible {
    outline: none;
}

.is-post .el9-main,
.is-page .el9-main,
.is-404 .el9-main {
    /* 左右留白同样只认 shell 那一层 */
    padding-left: 0;
    padding-right: 0;
}

/* 文章页顶部留白给足：之前 24px，标题几乎是贴着页面顶的，
   进来没有「进入一篇长文」的准备感 */
.is-post .el9-main,
.is-page .el9-main {
    /*
     * 顶部留白同样只认 .el9-layout 那一层。
     * 这里原来是「补到 40」，结果文章页和个人中心是 40、首页是 12，
     * 一换页就跳一下 —— 统一之后所有页面顶部都是 12。
     */
    padding-top: 0;
}

/* ---- 左栏挂件 ---- */

.el9-rail-inner {
    display: flex;
    flex-direction: column;
    gap: var(--el9-4);
}

.el9-rail .el9-search {
    height: 40px;
    border-color: var(--el9-border);
    border-radius: var(--el9-r-sm);
    background: var(--el9-bg);
}

.el9-panel {
    padding: var(--el9-4);
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-md);
    background: var(--el9-bg-soft);
}

/* 不要外面那层框和底色，只留里面一个个标签（热门标签用） */
.el9-panel--plain {
    padding: 0;
    border: 0;
    border-radius: 0;
    background: transparent;
}

.el9-panel--plain .el9-panel-title {
    padding-left: var(--el9-1);
    /* 侧栏这堆面板全是 --plain，这条比下面那条更具体，会盖掉它的 margin。
       原来这里是 8px，标题和内容贴得太近 —— 密集感有一半来自这儿 */
    margin-bottom: var(--el9-3);
}

.el9-panel-title {
    display: flex;
    align-items: center;
    gap: var(--el9-2);
    margin-bottom: var(--el9-3);
    color: var(--el9-text-2);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .04em;
}

.el9-panel-title::before {
    content: "";
    width: 3px;
    height: 12px;
    border-radius: 2px;
    background: var(--el9-accent);
    opacity: .85;
}

.el9-tag-cloud {
    display: flex;
    flex-wrap: wrap;
    /* 6px 时上下两行几乎贴在一起，看着糊成一团 */
    gap: 8px;
}

.el9-tag-cloud a {
    display: inline-flex;
    align-items: center;
    height: 30px;
    padding: 0 12px;
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-full);
    background: var(--el9-bg);
    color: var(--el9-text-2);
    font-size: 13px;
    transition: color var(--el9-dur) var(--el9-ease), border-color var(--el9-dur) var(--el9-ease),
        background var(--el9-dur) var(--el9-ease);
}

.el9-tag-cloud a:hover {
    color: var(--el9-accent);
    border-color: var(--el9-accent);
    background: var(--el9-accent-soft);
}

.el9-list {
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin: 0 calc(-1 * var(--el9-2));
}

.el9-list a {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--el9-3);
    padding: 9px var(--el9-2);
    border-radius: var(--el9-r-sm);
    font-size: 14px;
    transition: background var(--el9-dur) var(--el9-ease), color var(--el9-dur) var(--el9-ease);
}

.el9-list a:hover {
    background: var(--el9-bg);
    color: var(--el9-accent);
}

.el9-count {
    flex: none;
    font-size: 12px;
    color: var(--el9-text-3);
    font-variant-numeric: tabular-nums;
}

.el9-rail-foot {
    padding-top: var(--el9-3);
    border-top: 1px solid var(--el9-border);
    color: var(--el9-text-3);
    font-size: 12px;
    line-height: 1.8;
}

.el9-rail-foot p {
    margin: 0;
}

.el9-rail-foot a {
    color: var(--el9-accent);
    text-decoration: none;
}

.el9-rail-foot a:hover {
    text-decoration: none;
}

.el9-rail-foot-extra {
    margin: 4px 0;
}

.el9-rail-foot-extra a {
    color: var(--el9-accent);
}

/* ==========================================================================
   5. 信息流
   ========================================================================== */

.el9-feedbar {
    position: sticky;
    top: 0;
    z-index: 30;
    display: flex;
    align-items: center;
    gap: var(--el9-2);
    margin: 0;
    padding: var(--el9-2) var(--el9-main-pad);
    background: var(--el9-bg-blur);
    backdrop-filter: saturate(180%) blur(12px);
    -webkit-backdrop-filter: saturate(180%) blur(12px);
    border-bottom: 1px solid var(--el9-border);
}

.el9-feedbar--flow {
    margin-top: var(--el9-5);
}

.el9-feedbar .el9-tab {
    position: relative;
    display: inline-flex;
    align-items: center;
    height: 44px;
    padding: 0 var(--el9-3);
    border-radius: var(--el9-r-sm);
    font-size: 15px;
    font-weight: 600;
    color: var(--el9-text-2);
    transition: color var(--el9-dur) var(--el9-ease), background var(--el9-dur) var(--el9-ease);
}

.el9-feedbar .el9-tab:hover {
    color: var(--el9-text);
    background: var(--el9-bg-hover);
}

.el9-feedbar .el9-tab.is-active {
    color: var(--el9-text);
    font-weight: 700;
}

.el9-feedbar .el9-tab.is-active::after {
    content: "";
    position: absolute;
    left: var(--el9-3);
    right: var(--el9-3);
    bottom: 4px;
    height: 2px;
    border-radius: 2px;
    background: var(--el9-accent);
}

.el9-feedbar-title {
    flex: 1;
    min-width: 0;
    font-size: 20px;
    font-weight: 800;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.el9-search--bar {
    display: none;
}

/* ---- 前台说说发布框 ---- */

.el9-composer {
    margin-top: var(--el9-5);
    padding: var(--el9-4) var(--el9-5);
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-lg);
    background: var(--el9-bg);
}

.el9-composer textarea {
    display: block;
    width: 100%;
    min-height: 72px;
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--el9-text);
    font: inherit;
    font-size: 16px;
    line-height: 1.65;
    resize: vertical;
}

.el9-composer textarea:focus {
    outline: none;
}

.el9-composer-previews {
    display: grid;
    grid-template-columns: repeat(auto-fill, 72px);
    gap: var(--el9-2);
    margin-top: var(--el9-3);
}

.el9-composer-preview {
    position: relative;
    width: 72px;
    height: 72px;
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-sm);
    overflow: hidden;
    /*
     * 预览图不许被选中、也不许被浏览器当图片拖走。
     *
     * 选完图之后焦点还在弹层里，鼠标残留的位置又正好压在缩略图上 —— 按 Esc 关弹层时
     * 很容易带出一个图片选区（浏览器给 img 画的那种蓝框），看着就像「整个框被选中了」。
     *
     * 排序走的是 app.js 里自己那套 pointer 拖拽，跟原生拖图是两回事：
     * touch-action 关掉这块区域的触屏滚动，pointermove 才收得到；
     * 原生 dragstart 在容器上被 preventDefault 掉了。
     */
    user-select: none;
    -webkit-user-select: none;
    cursor: grab;
    touch-action: none;
    transition: opacity .15s ease, transform .15s ease, border-color .15s ease;
}

.el9-composer-preview:hover {
    border-color: var(--el9-accent);
}

.el9-composer-preview.is-dragging {
    z-index: 2;
    opacity: .45;
    transform: scale(.92);
    border-color: var(--el9-accent);
    cursor: grabbing;
}

.el9-composer-preview img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* 图片本身不参与命中，拖动事件落在 .el9-composer-preview 上 */
    pointer-events: none;
    -webkit-user-drag: none;
}

/*
 * 编辑已有说说时，正文里那张图的地址可能被图床拒掉（防盗链 403）。
 * 与其留一个破图图标，不如把话说清楚 —— 图没丢，还在正文里，点 × 能删。
 */
.el9-composer-preview.is-broken {
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--el9-bg-soft, #f4f5f7);
    border-style: dashed;
}

.el9-composer-preview.is-broken::after {
    content: "图片打不开";
    font-size: 11px;
    line-height: 1.4;
    color: var(--el9-text-3, #8a939c);
    text-align: center;
    padding: 0 4px;
}

.el9-composer-preview.is-broken img {
    display: none;
}

.el9-composer-remove {
    position: absolute;
    top: 3px;
    right: 3px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    padding: 0;
    border: 0;
    border-radius: var(--el9-r-full);
    background: rgba(0, 0, 0, .55);
    color: #fff;
    font-size: 14px;
    line-height: 1;
    cursor: pointer;
}

.el9-composer-remove:hover {
    background: rgba(0, 0, 0, .75);
}

.el9-composer-error {
    margin-top: var(--el9-2);
    font-size: 13px;
    color: var(--el9-danger);
}

/* 提示而非报错（比如「没拿到定位权限，已按 IP 填了城市」）：位置其实填上了，别用红字吓人 */
.el9-composer-error.is-hint {
    color: var(--el9-text-3);
}

.el9-composer-foot {
    display: flex;
    flex-direction: column;
    gap: var(--el9-2);
    margin-top: var(--el9-3);
    padding-top: var(--el9-3);
    border-top: 1px solid var(--el9-border);
}

/* 第一行：图片 / 图片链接 + 发布（发布靠右） */
.el9-composer-tools {
    display: flex;
    align-items: center;
    gap: var(--el9-2);
}

.el9-composer-tools .el9-composer-submit {
    margin-left: auto;
}

/* 第二行：定位按钮 + 位置输入，整行铺开 */
.el9-composer-place {
    display: flex;
    align-items: center;
    gap: var(--el9-2);
}

.el9-composer-mood {
    flex: 0 1 34%;
    min-width: 96px;
    height: 36px;
    padding: 0 var(--el9-3);
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-full);
    background: var(--el9-bg);
    color: var(--el9-text);
    font: inherit;
    font-size: 13px;
}

.el9-composer-mood:focus {
    outline: 0;
    border-color: var(--el9-accent);
}

.el9-composer-place .el9-composer-location {
    flex: 1 1 auto;
    min-width: 0;
}

.el9-composer-add--url {
    /* 跟「上传图片」按钮同款方块，只是图标不同 */
    cursor: pointer;
}

.el9-composer-add {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 36px;
    height: 36px;
    margin: 0;
    border-radius: var(--el9-r-full);
    color: var(--el9-text-2);
    cursor: pointer;
    transition: color var(--el9-dur) var(--el9-ease), background var(--el9-dur) var(--el9-ease);
}

.el9-composer-add:hover {
    color: var(--el9-accent);
    background: var(--el9-accent-soft);
}

.el9-composer-locate {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    flex: none;
    height: 30px;
    padding: 0 10px 0 7px;
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-full);
    background: transparent;
    color: var(--el9-text-2);
    font-size: 13px;
    cursor: pointer;
    transition: color var(--el9-dur) var(--el9-ease),
                background var(--el9-dur) var(--el9-ease),
                border-color var(--el9-dur) var(--el9-ease);
}

.el9-composer-locate:hover {
    color: var(--el9-accent);
    background: var(--el9-accent-soft);
    border-color: var(--el9-accent);
}

.el9-composer-locate:disabled {
    opacity: .55;
    cursor: default;
}

.el9-composer-locate:disabled:hover {
    color: var(--el9-text-2);
    background: transparent;
    border-color: var(--el9-border);
}

.el9-composer-note {
    margin: 8px 2px 0;
    color: var(--el9-text-3);
    font-size: 12px;
    line-height: 1.6;
}

/*
 * 内容遮罩：一行开关 + 展开后的两个范围选项。
 * 高度跟 location/mood 那一行对齐（36px），视觉上是一条完整的工具带。
 */
.el9-composer-mask {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px 14px;
    margin-top: var(--el9-2);
    padding-top: var(--el9-2);
    border-top: 1px solid var(--el9-border);
}

.el9-composer-mask-on,
.el9-composer-maskopts label {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    color: var(--el9-text-3);
    cursor: pointer;
    user-select: none;
    transition: color var(--el9-dur) var(--el9-ease);
}

.el9-composer-mask-on:hover,
.el9-composer-maskopts label:hover {
    color: var(--el9-text-2);
}

.el9-composer-mask-on input,
.el9-composer-maskopts input {
    width: 15px;
    height: 15px;
    margin: 0;
    accent-color: var(--el9-accent);
    cursor: pointer;
}

.el9-composer-mask-on:has(input:checked) {
    color: var(--el9-accent-text);
}

.el9-composer-maskopts {
    display: inline-flex;
    align-items: center;
    gap: 12px;
}

.el9-composer-maskhint {
    font-size: 12px;
    color: var(--el9-text-3);
    opacity: .8;
}

/*
 * 编辑模式下不摆「加图」那几个按钮。
 * 编辑只动正文和位置/心情/遮罩，传上来的新图没人接（服务端 doEdit 不处理上传），
 * 摆着只会让人以为能换图，白传一趟。
 */
/*
 * 编辑模式跟发布共用同一排按钮：补图、贴链接、B 站、表情都能用。
 * 补的图由服务端追加到正文末尾，用户可以在正文框里再挪。
 */

/* 编辑时正文常带图床链接，一行放不下会缩成一格，给个台阶 */
.el9-composer[data-mode="edit"] textarea {
    min-height: 128px;
}

.el9-composer-location {
    flex: 1;
    min-width: 0;
    height: 36px;
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--el9-text);
    font-size: 13px;
}

.el9-composer-location:focus {
    outline: none;
}

.el9-composer-location::placeholder {
    color: var(--el9-text-3);
}

.el9-composer-submit {
    flex: none;
    height: 36px;
    padding: 0 20px;
    border: 0;
    border-radius: var(--el9-r-full);
    background: var(--el9-accent);
    color: var(--el9-accent-contrast);
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    transition: opacity var(--el9-dur) var(--el9-ease), transform var(--el9-dur) var(--el9-ease);
}

.el9-composer-submit:hover {
    opacity: .9;
}

.el9-composer-submit:active {
    transform: scale(.96);
}

.el9-composer-submit:disabled {
    opacity: .55;
    cursor: default;
}

.el9-feed {
    display: flex;
    flex-direction: column;
    gap: var(--el9-4);
    padding-top: var(--el9-4);
}

/*
 * 首页 / 分类 / 搜索：条目之间不留空隙，靠一条贯穿整栏的细线分隔 ——
 * 这样才是连续的时间线，跟手机端看到的是同一套版式。
 *
 * 为什么用负 margin：卡片的 padding 是 24px，分隔线只会画在 padding-box 里，
 * 两头会各短 24px。往左右各撑出一个主栏内边距的量（--el9-main-pad），
 * 线就顶到主栏边缘了；文字位置不变，因为卡片自己的 padding 还在。
 *
 * ⚠️ 说说时间线（.el9-feed--timeline）要排除：它有一条绝对定位的竖线（left: 39px），
 * 卡片一左移竖线就跟头像错开了。
 */
.el9-feed:not(.el9-feed--timeline) {
    gap: 0;
}

.el9-feed:not(.el9-feed--timeline) > .el9-card {
    margin-left: calc(-1 * var(--el9-main-pad));
    margin-right: calc(-1 * var(--el9-main-pad));
}

/* gap 归零后，顶部轮播会跟第一条贴在一起，补回原来的那段距离 */
.el9-feed:not(.el9-feed--timeline) > .el9-carousel {
    margin-bottom: var(--el9-4);
}

.el9-card {
    display: flex;
    gap: var(--el9-4);
    padding: var(--el9-5) var(--el9-6);
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-md);
    background: var(--el9-bg);
    transition: border-color var(--el9-dur) var(--el9-ease);
}

/* hover 只轻微加深描边，不再加投影 —— 卡片太重会压过内容 */
.el9-card:hover {
    border-color: var(--el9-border-strong);
}

/* ---- 信息流（首页 / 分类 / 说说 / 搜索）----
   不用框把每条围起来，靠一条细线分隔 —— 时间线本来就该是连续的，
   一格一格的框会把视线切碎。鼠标移上去时整条铺一层底色。

   ⚠️ 这条是信息流卡片 padding 的唯一生效来源（0,2,0）。
   下面几处媒体查询里的 `.el9-card { padding: … }` 是（0,1,0），权重压不过它，
   写了也不生效 —— 要调手机端的卡片间距，改这里或加同等以上权重。 */
.el9-feed .el9-card {
    padding: var(--el9-5) var(--el9-6);
    border: 0;
    border-bottom: 1px solid var(--el9-border);
    border-radius: 0;
    background: transparent;
}

/* 整块 hover 铺底色会把每条都染一遍，扫列表时很吵。
   改成只在真正能点的东西上给反馈：标题、时间这些链接自己变色 */
.el9-feed .el9-card:hover {
    box-shadow: none;
}

.el9-feed .el9-card a:hover {
    color: var(--el9-accent-text);
}

.el9-feed .el9-card:last-child {
    border-bottom: 0;
}

/* ---- 搜索结果：一屏要多看几条 ---- */
.el9-card.is-compact {
    gap: var(--el9-3);
    padding: var(--el9-3) var(--el9-6);
}

/* 头像和动作栏收掉，只留「标题 + 一行摘要 + 出处」 */
.el9-card.is-compact .el9-card-avatar,
.el9-card.is-compact .el9-card-actions {
    display: none;
}

.el9-card.is-compact .el9-card-title {
    margin-bottom: 2px;
    font-size: 16px;
    line-height: 1.45;
}

.el9-card.is-compact .el9-card-text {
    font-size: 14px;
    line-height: 1.6;
    /* 最多两行，超出的省略 */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    line-clamp: 2;
    overflow: hidden;
}

/* 出处（分类 / 说说标记 / 时间）挪到标题下面一行，比挤在头部更清楚 */
.el9-card.is-compact .el9-card-head {
    margin-bottom: 0;
    flex-wrap: wrap;
}

.el9-card.is-compact .el9-card-name,
.el9-card.is-compact .el9-card-handle,
.el9-card.is-compact .el9-card-place {
    display: none;
}

.el9-card-main {
    flex: 1;
    min-width: 0;
}

.el9-card-head {
    display: flex;
    align-items: baseline;
    /* 第一行只有名字和 @handle，一行放得下，不再 wrap */
    gap: var(--el9-1);
    min-width: 0;   /* 允许子元素收缩，名字过长时走省略号而不是撑破 */
    font-size: 15px;
    line-height: 20px;
}

/*
 * 卡片第二行：日期 + 说说徽章 + 位置。
 * 之前这些全挤在第一行，元素一多就乱换行。
 */
/* 第二行里的分类：小字 + 文件夹图标，跟说说徽章同等视觉重量 */
.el9-card-cat {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    color: var(--el9-text-2);
}

.el9-card-cat a {
    color: inherit;
    text-decoration: none;
}

.el9-card-cat a:hover {
    color: var(--el9-accent-text);
}

.el9-card-cat .el9-icon {
    flex: none;
    opacity: 0.75;
}

.el9-card-sub {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--el9-1);
    margin-top: 1px;
    color: var(--el9-text-2);
    font-size: 13px;
    line-height: 18px;
}

.el9-card-name {
    font-weight: 700;
    color: var(--el9-text);
    /* 名字过长时省略：第一行现在不 wrap，撑破容器就难看了 */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.el9-card-handle,
.el9-card-time {
    color: var(--el9-text-2);
    font-size: 15px;
}

.el9-card-time:hover {
    text-decoration: none;
}

.el9-card-place {
    display: inline-flex;
    align-items: center;
    gap: var(--el9-1);
    /* 紧跟前一个元素（说说徽章 / 日期），不推到行尾 —— PC 和手机表现一致 */
    margin-left: 0;
    color: var(--el9-text-3);
    font-size: 13px;
}

.el9-card-title {
    margin: var(--el9-2) 0 var(--el9-2);
    font-size: 19px;
    /* 列表标题 700 够分量；再粗就往正文里抢注意力了 */
    font-weight: 700;
    line-height: 1.45;
    letter-spacing: -.01em;
    text-wrap: pretty;
}

.el9-card-title a:hover {
    color: var(--el9-accent);
}

.el9-card-text {
    font-size: 15px;
    /* 摘要最多三行，行高压到 1.65 更紧凑，跟 19px 的标题拉开对比 */
    line-height: 1.65;
    color: var(--el9-text);
    overflow-wrap: break-word;
    word-break: break-word;
}

.el9-card:not(.is-talk) .el9-card-text {
    color: var(--el9-text-2);
}

.el9-card-text p {
    margin: 0;
}

.el9-card-text img,
.el9-card-text pre {
    margin: var(--el9-2) 0;
}

.is-talk .el9-card-text {
    font-size: 17px;
    line-height: 1.65;
}

.is-talk .el9-card-text p {
    margin: 0 0 var(--el9-2);
}

.is-talk .el9-card-text p:last-child {
    margin-bottom: 0;
}

.el9-card-media {
    display: block;
    margin-top: var(--el9-3);
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-md);
    overflow: hidden;
    aspect-ratio: 16 / 9;
    background: var(--el9-skeleton);
}

.el9-card-media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 320ms var(--el9-ease);
}

.el9-card-media:hover img {
    transform: scale(1.02);
}

/*
 * 大图下面紧跟动作栏时，给一点呼吸。
 *
 * 原来这里靠的是 0 —— 图标直接贴在图的下边框上。而说说卡片里，正文和动作栏
 * 之间还留着行高余下的那几 px，于是同一条时间线上：文章那条挤，说说那条松。
 *
 * 只用相邻选择器，不动 .el9-card-media 自己的 margin-bottom —— 搜索结果那种
 * 没有动作栏的卡片，下面多出来的空白会变成一条莫名其妙的空隙。
 */
.el9-card-media + .el9-card-actions {
    margin-top: var(--el9-2);
}

/*
 * 编辑那支笔：规格跟分享按钮完全对齐（32 宽、padding 0、左右 margin 0）。
 *
 * .el9-act 默认带 margin-left: -8px（那是给「图标+文字」那种按钮留的贴边补偿），
 * 纯图标按钮不吃这套 —— 不覆盖的话它跟隔壁只隔 4px，而别处是 12px，一眼就看出来歪。
 */
.el9-card-actions .el9-act--edit {
    flex: none;
    position: relative;
    justify-content: center;
    width: 32px;
    padding: 0;
    margin-left: 0;
    margin-right: 0;
}

/* 动作栏：去掉上方那条横线 —— 图片/文字下面直接跟动作图标，
   中间隔一条线会把一张卡片切成两截（推文的惯例就是不加这条线） */
.el9-card-actions,
.el9-article-actions {
    display: flex;
    align-items: center;
    gap: var(--el9-3);
    /*
     * 第一个按钮有 8px 左内边距（为了点击区够大），整行往左挪 8 抵消它，
     * 视觉上第一个图标才跟下面的标签左对齐。
     *
     * 这个负边距原来是写在每个 .el9-act 上的，结果纯图标按钮（分享 / 打印）
     * 没有那 8px 内边距、却也被推到左边，两者叠起来间距就不匀了 ——
     * 实测四个图标中心距是 48.9 / 65.8 / 44，第二段空了一大截。
     * 改成只在这里挪一次，按钮自己不带负边距。
     */
    margin-left: calc(-1 * var(--el9-2));
    /*
     * 标签已经独占一行了，换行间距交给 .el9-article-foot 的 gap，
     * 这里再加 20px 会空出一大条。
     */
    margin-top: 0;
}

.el9-act {
    display: inline-flex;
    align-items: center;
    position: relative;   /* 给下面的命中区伪元素当定位参照 */
    gap: 6px;
    height: 32px;
    padding: 0 var(--el9-2);
    /* 负边距交给容器统一处理（见 .el9-article-actions），按钮自己不加 */
    border-radius: var(--el9-r-sm);
    color: var(--el9-text-3);
    font-size: 13px;
    /* 「3 分钟」「阅读全文」这类短词组不许在中间断行 ——
       手机上一窄就会拆成「3 分 / 钟」，很难看 */
    white-space: nowrap;
    transition: color var(--el9-dur) var(--el9-ease), background var(--el9-dur) var(--el9-ease);
}

.el9-act:hover {
    color: var(--el9-accent);
    background: var(--el9-accent-soft);
}

.el9-act.is-static {
    cursor: default;
}

.el9-act.is-static:hover {
    color: var(--el9-text-3);
    background: none;
}

.el9-act--category {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.el9-act--more {
    margin-left: auto;
    /*
     * 左右留白对称：左 8px、右 8px，再用 -8px 的右外边距把盒子顶出去，
     * 箭头视觉上仍贴着内容区右边缘，但 hover 露出来的那块背景两边一样宽。
     *
     * 以前 padding-right 是 0，鼠标一上去就能看出右边比左边窄一截。
     * 这里写死 8px 不用 var —— 之前用 calc(-1 * var(--el9-2)) 在部分浏览器里
     * 算不出值，padding-right 直接退化成 0，白改一场。
     */
    margin-right: -8px;
    padding-right: 8px;
    color: var(--el9-accent);
    font-weight: 600;
}

/*
 * 分享按钮：只留图标，做成正方形点击区。
 * 复制成功的反馈用按钮上方飘出的小气泡，不占布局宽度。
 */
/*
 * 纯图标的按钮：分享、打印。
 *
 * 它们跟「评论数」「浏览量」那种「图标 + 数字」的按钮盒子模型不一样 ——
 * 那两个是 padding: 0 8px + margin-left: -8px（负边距是为了让第一个贴左），
 * 这两个得是定宽 32 居中、不留内边距。
 *
 * 之前只给 share 写了这套，后加的 print 用了默认的 padding + 负边距，
 * 结果打印图标比分享图标往左挤了一截，四个图标看着疏密不匀。
 * 现在两个共用一份规则，宽度、内边距、外边距完全一致。
 */
.el9-act--share,
.el9-act--print {
    flex: none;
    position: relative;
    justify-content: center;
    /*
     * 跟数字按钮用同一套内边距（左右各 8），图标才会落在同一条竖线上。
     * 之前写的是 width:32 + padding:0，图标靠 32px 盒子居中，
     * 跟数字按钮的 8px 内边距差 1px，四个图标看着疏密不匀。
     */
    padding: 0 var(--el9-2);
    /* 紧跟评论数（不再 auto 推到最右），让「阅读全文」独占右端 */
    margin-left: 0;
    margin-right: 0;
    color: var(--el9-text-3);
    background: none;
    border: 0;
    cursor: pointer;
    font: inherit;
}

/* 复制成功的气泡：绝对定位在按钮上方，不挤占动作栏 */
.el9-share-tip {
    position: absolute;
    bottom: calc(100% + 6px);
    left: 50%;
    transform: translateX(-50%) translateY(4px);
    padding: 3px 8px;
    border-radius: var(--el9-r-sm);
    background: var(--el9-text);
    color: var(--el9-bg);
    font-size: 12px;
    line-height: 1.4;
    white-space: nowrap;
    opacity: 0;
    pointer-events: none;
    transition: opacity 160ms var(--el9-ease), transform 160ms var(--el9-ease);
}

.el9-act--share.is-copied .el9-share-tip {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
}

.el9-act--share:hover,
.el9-act--print:hover {
    color: var(--el9-accent);
}

/* ---- 打印范围菜单 ----
 * 点打印机图标弹出来：只打印正文 / 连评论一起。
 * 从按钮上方弹出（按钮在页面靠下，往下弹会被视口切掉）。
 */
.el9-print-wrap {
    position: relative;
    display: flex;
}

.el9-print-menu {
    position: absolute;
    right: 0;
    bottom: calc(100% + 8px);
    z-index: 30;
    min-width: 136px;
    padding: 5px;
    display: flex;
    flex-direction: column;
    gap: 2px;
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-md);
    background: var(--el9-bg);
    box-shadow: var(--el9-shadow);
}

/* 它是 flex，[hidden] 的默认 display:none 会被压掉，得显式写一条 */
.el9-print-menu[hidden] {
    display: none;
}

.el9-print-menu button {
    padding: 8px 11px;
    border: 0;
    border-radius: var(--el9-r-sm);
    background: none;
    font-size: 13px;
    line-height: 1.4;
    color: var(--el9-text);
    text-align: left;
    white-space: nowrap;
    cursor: pointer;
}

.el9-print-menu button:hover {
    background: var(--el9-bg-soft);
    color: var(--el9-accent-text);
}

.el9-act--share.is-copied {
    color: var(--el9-accent);
}



.el9-act--more:hover {
    color: var(--el9-accent);
    background: var(--el9-accent-soft);
}

.el9-act--more .el9-icon {
    /*
     * 盒子上是居中的（量过：上下各 8px），但**看着**箭头往上跑。
     *
     * 原因是中西文混排的老毛病：汉字的字形占满整个字身、重心偏下，
     * 而箭头图形正好落在 svg 视框的正中 —— 两个「居中」不是一个视觉高度。
     * 往下压 1px 就对齐了。用 relative 不用 margin，免得影响行盒高度。
     */
    position: relative;
    top: 1px;
    align-self: center;
    transition: transform var(--el9-dur) var(--el9-ease);
}

.el9-act--more:hover .el9-icon {
    transform: translateX(2px);
}

/* ---- 说说时间线 ---- */

.el9-feed--timeline {
    position: relative;
    gap: var(--el9-1);
    padding-top: var(--el9-2);
}

.el9-feed--timeline::before {
    content: "";
    position: absolute;
    left: 39px;
    top: 20px;
    bottom: 20px;
    width: 2px;
    border-radius: 1px;
    background: var(--el9-border);
}

.el9-feed--timeline .el9-card {
    padding: var(--el9-3) var(--el9-3) var(--el9-3) var(--el9-5);
    border-color: transparent;
}

/* 说说时间线的卡片同样不整块变色（跟首页信息流一致） */
.el9-feed--timeline .el9-card:hover {
    border-color: transparent;
    box-shadow: none;
    background: transparent;
}

.el9-feed--timeline .el9-card-actions {
    border-top-color: var(--el9-border);
}

.el9-card-avatar {
    flex: none;
    position: relative;
    z-index: 1;
}

.el9-feed--timeline .el9-avatar {
    box-shadow: 0 0 0 4px var(--el9-bg);
}

.el9-timeline-sep {
    position: relative;
    display: flex;
    align-items: center;
    height: 48px;
    padding-left: 60px;
    color: var(--el9-text-2);
    font-size: 13px;
    font-weight: 700;
    letter-spacing: .02em;
}

.el9-timeline-sep::before {
    content: "";
    position: absolute;
    left: 34px;
    top: 50%;
    width: 12px;
    height: 12px;
    margin-top: -6px;
    border-radius: var(--el9-r-full);
    background: var(--el9-bg);
    border: 3px solid var(--el9-accent);
}

/* ---- 长文目录 ---- */

/* 窄屏：正文顶部一张折叠卡 */
.el9-toc-inline {
    /* 页头是卡片了，目录跟它之间要留出「两张卡」的距离，8px 会粘在一起 */
    margin: var(--el9-4) 0 var(--el9-4);
    padding: var(--el9-3) var(--el9-4);
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-md);
    background: var(--el9-bg-soft);
}

.el9-toc-inline[hidden],
.el9-toc-rail[hidden] {
    display: none;
}

.el9-toc-inline > summary {
    cursor: pointer;
    font-size: 14px;
    font-weight: 700;
    color: var(--el9-text-2);
    user-select: none;
}

.el9-toc-inline > summary:hover {
    color: var(--el9-accent);
}

.el9-toc-inline-list,
.el9-toc-rail-list {
    display: flex;
    flex-direction: column;
    margin-top: var(--el9-2);
}

.el9-toc-link {
    display: block;
    padding: 5px 10px;
    border-radius: var(--el9-r-sm);
    border-left: 2px solid transparent;
    color: var(--el9-text-2);
    font-size: 13px;
    line-height: 1.5;
    text-decoration: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    transition: color var(--el9-dur) var(--el9-ease), background var(--el9-dur) var(--el9-ease);
}

.el9-toc-link.is-h3 {
    font-size: 12.5px;
    color: var(--el9-text-3);
}

.el9-toc-link:hover {
    background: var(--el9-bg-hover);
    color: var(--el9-text);
}

.el9-toc-link.is-current {
    border-left-color: var(--el9-accent);
    background: var(--el9-accent-soft);
    color: var(--el9-accent);
    font-weight: 600;
}

/* 宽屏：右侧悬浮那一条（屏幕够宽才摆得下） */
.el9-toc-rail {
    display: none;
    position: fixed;
    top: calc(var(--el9-nav-h) + 40px);
    right: 20px;
    z-index: 40;
    width: 208px;
    max-height: calc(100vh - 180px);
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: var(--el9-3) var(--el9-2);
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-md);
    background: var(--el9-bg);
    box-shadow: var(--el9-shadow);
}

.el9-toc-title {
    margin: 0 0 var(--el9-2);
    padding: 0 var(--el9-2);
    font-size: 12px;
    font-weight: 700;
    color: var(--el9-text-3);
    letter-spacing: .04em;
}

/* 摆得下才显示右侧目录（JS 按实际宽度算，宽度设置改了也不会撞上正文） */
body.has-toc-rail .el9-toc-rail {
    display: block;
}

/* 右侧有目录了，顶部折叠卡就别重复摆 */
body.has-toc-rail .el9-toc-inline {
    display: none;
}

/* 侧栏在右边时，目录挂到内容的左侧，别跟侧栏打架 */
body.is-side-right .el9-toc-rail {
    left: 20px;
    right: auto;
}

/* 没有 JS 时的兜底：很宽的屏才摆悬浮目录，窄了就用折叠卡 */
@media screen and (min-width: 1600px), print {
}

/* ---- 网格卡片归档（资源仓库这类分类，后台「网格卡片分类」里挂） ---- */

.el9-grid-feed {
    display: flex;
    flex-wrap: wrap;
    margin: var(--el9-2) calc(var(--el9-2) * -1) 0;
}

.el9-grid-card {
    position: relative;
    width: calc(33.333% - var(--el9-4));
    margin: var(--el9-2);
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-md);
    background: var(--el9-bg);
    overflow: hidden;
    box-sizing: border-box;
    transition: border-color var(--el9-dur) var(--el9-ease),
        box-shadow var(--el9-dur) var(--el9-ease),
        transform var(--el9-dur) var(--el9-ease);
}

/* 整卡可点：把标题那根链接的命中区撑满卡片。
   这样语义上还是「标题链接」，但不占额外一行、鼠标点哪都进得去 */
.el9-grid-link::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 1;
    border-radius: var(--el9-r-md);
}

.el9-grid-card:hover {
    border-color: var(--el9-border-strong);
    box-shadow: var(--el9-shadow);
    transform: translateY(-2px);
}

/* 16:9 封面，图铺满 */
.el9-grid-cover {
    display: block;
    position: relative;
    width: 100%;
    padding-top: 56.25%;
    background: var(--el9-skeleton);
    overflow: hidden;
}

.el9-grid-cover img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    margin: 0;
    border: 0;
    border-radius: 0;
}

.el9-grid-cover-ph {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--el9-text-3);
    opacity: .5;
}

.el9-grid-body {
    padding: var(--el9-3) var(--el9-4) var(--el9-4);
}

.el9-grid-title {
    margin: 0;
    font-size: 15px;
    font-weight: 500;
    line-height: 1.55;
    /* 最多两行，多出来的省略 */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    line-clamp: 2;
    overflow: hidden;
    min-height: 2.9em;
}

.el9-grid-title a {
    color: var(--el9-text);
    text-decoration: none;
}

.el9-grid-card:hover .el9-grid-title a {
    color: var(--el9-accent);
}

/* 卡片右下角的小箭头，只在鼠标移上去时出现 ——
   没有那行「立即获取」了，得留一点「这里可以点」的暗示 */
.el9-grid-go {
    position: absolute;
    right: var(--el9-3);
    bottom: var(--el9-3);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    border-radius: var(--el9-r-full);
    background: var(--el9-bg-blur);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    color: var(--el9-text-2);
    font-size: 13px;
    line-height: 1;
    text-decoration: none;
    opacity: 0;
    transform: translateX(-4px);
    transition: opacity var(--el9-dur) var(--el9-ease), transform var(--el9-dur) var(--el9-ease);
    pointer-events: none;
}

.el9-grid-card:hover .el9-grid-go {
    opacity: 1;
    transform: translateX(0);
    color: var(--el9-accent-text);
}

@media screen and (max-width: 1200px) {
    .el9-grid-card {
        width: calc(50% - var(--el9-4));
    }
}

@media screen and (max-width: 640px) {
    /*
     * 手机上保持两列，不要退成一列。
     * 原来这里写的是 100%，所以 390px 屏幕上一行只放得下一张卡，
     * 单独一张大卡反而更占屏、翻起来更慢。
     */
    .el9-grid-card {
        width: calc(50% - var(--el9-4));
    }
}

/* ---- 分页 ---- */

.el9-pager {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: var(--el9-1);
    padding: var(--el9-5) var(--el9-4) var(--el9-8);
}

/* nav 包 li 时浏览器还会画圆点，关掉 */
.el9-pager li {
    list-style: none;
}

.el9-pager li a,
.el9-pager li span {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 36px;
    height: 36px;
    padding: 0 var(--el9-2);
    border: 0;
    border-radius: var(--el9-r-full);
    background: transparent;
    color: var(--el9-text-2);
    font-size: 15px;
    font-weight: 500;
    font-variant-numeric: tabular-nums;
    transition: background var(--el9-dur) var(--el9-ease),
        color var(--el9-dur) var(--el9-ease);
}

.el9-pager li a:hover {
    background: var(--el9-bg-hover);
    color: var(--el9-text);
}

.el9-pager li.is-current a,
.el9-pager li.is-current span {
    background: var(--el9-accent);
    color: var(--el9-accent-contrast);
    font-weight: 700;
}

.el9-pager li.is-prev a,
.el9-pager li.is-next a {
    min-width: 0;
    padding: 0 var(--el9-4);
    border: 1px solid var(--el9-border);
    background: var(--el9-bg);
    color: var(--el9-text);
    font-weight: 600;
}

.el9-pager li.is-prev a:hover,
.el9-pager li.is-next a:hover {
    border-color: var(--el9-border-strong);
    background: var(--el9-bg-soft);
    color: var(--el9-text);
}

/* 无限加载指示器 */

/*
 * 往下追加的两种模式都把分页条藏起来，列表底部只留一个入口：
 * 「加载更多」靠按钮、自动加载靠滚动。
 * JS 拿不到下一页地址时会自己把这两个类摘掉，分页条就亮回来了。
 */
.el9-pager.is-infinite,
.el9-pager.is-button {
    display: none;
}

.el9-pager.is-fallback {
    display: flex;
}

/* ---- 「加载更多」按钮：细线框、透明底，不抢内容的注意力 ---- */

.el9-loadmore {
    display: flex;
    justify-content: center;
    padding: var(--el9-5) 0 var(--el9-8);
}

.el9-loadmore[hidden] {
    display: none;
}

.el9-loadmore-btn {
    min-width: 140px;
    /* 44px 是触摸目标的下限，线框按钮这个高度在桌面上也不显笨 */
    height: 44px;
    padding: 0 var(--el9-5);
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-full);
    background: transparent;
    color: var(--el9-text-2);
    font-family: inherit;
    font-size: 14px;
    font-weight: 500;
    line-height: 1;
    cursor: pointer;
    transition: border-color var(--el9-dur) var(--el9-ease),
        background var(--el9-dur) var(--el9-ease),
        color var(--el9-dur) var(--el9-ease);
}

.el9-loadmore-btn:hover {
    border-color: var(--el9-border-strong);
    background: var(--el9-bg-soft);
    color: var(--el9-text);
}

/* 加载中 / 已经到底了 / 加载失败：都不可再点，只是文案不同。
   「已经到底了」这时候它已经不是按钮，只是一行状态文字 —— 去掉线框和外边距，
   别让人以为还能点 */
.el9-loadmore-btn[disabled] {
    min-width: 0;
    border-color: transparent;
    background: transparent;
    color: var(--el9-text-3);
    cursor: default;
}

/*
 * 「已经到底了，没有更多内容」。
 *
 * 这段是纯文本，不是按钮：到底了这个状态跟「列表加载方式」无关，
 * 自动加载和点击加载两种模式看到的应该是同一行字。
 * 样式跟 .el9-loadmore-btn[disabled] 对齐，视觉上跟「加载到最后一页」时
 * 按钮变灰的样子完全一致，不会跳一下。
 */
.el9-loadmore-end {
    margin: 0;
    color: var(--el9-text-3);
    font-size: 14px;
    font-weight: 500;
    line-height: 1.5;
    text-align: center;
}

@media screen and (max-width: 999px) {
    /*
     * 手机端不点按钮了 —— 继续往下滑就自动加载（见 app.js 里的 syncTrigger）。
     * 这里把那颗 44px 的线框按钮压成一行灰字，只当状态提示，尽量少占屏。
     * 底部要让开固定导航条（52px）+ 安全区，再多留 10px 呼吸。
     */
    .el9-loadmore {
        padding: 10px 0 calc(10px + 52px + env(safe-area-inset-bottom, 0px));
    }

    .el9-loadmore-btn,
    .el9-loadmore-btn:hover {
        min-width: 0;
        height: auto;
        padding: 0;
        border: 0;
        background: transparent;
        color: var(--el9-text-3);
        font-size: 12.5px;
        font-weight: 500;
        cursor: default;
    }

    /*
     * 已经滑到最底：提示加深一档，跟「还在往下滑的路上」区分开。
     * 这是「到底了」的唯一视觉信号，别再加重别的装饰。
     */
    .el9-loadmore.is-bottom .el9-loadmore-btn {
        color: var(--el9-text-2);
    }

    /* 到底那行字跟手机端按钮文案保持同样字号，两者不会一粗一细 */
    .el9-loadmore-end {
        font-size: 12.5px;
    }
}

.el9-loader {
    display: flex;
    justify-content: center;
    padding: var(--el9-5) 0 var(--el9-8);
}

.el9-loader[hidden] {
    display: none;
}

.el9-spinner {
    width: 22px;
    height: 22px;
    border-radius: var(--el9-r-full);
    border: 2px solid var(--el9-border);
    border-top-color: var(--el9-accent);
    animation: el9-spin .7s linear infinite;
}

@keyframes el9-spin {
    to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
    .el9-spinner {
        animation-duration: 1.6s;
    }
}

/* ==========================================================================
   6. 文章页
   ========================================================================== */

.el9-progress {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 90;
    height: 2px;
    background: transparent;
}

.el9-progress span {
    display: block;
    width: 0;
    height: 100%;
    background: var(--el9-accent);
    transition: width 80ms linear;
}

.el9-article {
    /* 左右留白交给 .el9-shell 的 --el9-bleed，这里不再叠一层 ——
       不然「内容到窗口」会变成 12 + 24 + 16 = 52，和首页对不上。
       顶部也不再留 8px：首块（页头卡片）要跟首页标签栏、独立页标题
       落在同一条线上 —— 那条线的位置由 .el9-layout 的 --el9-bleed 决定 */
    padding: 0 0 var(--el9-8);
}

/*
 * 页头卡片：标题 + 作者 + 日期收进一张卡里。
 *
 * 原来这些内容直接铺在白底上，标题和作者行之间靠一条通栏细线分隔，
 * 视觉上没有边界 —— 往下滚的时候也分不清「头部」到哪儿结束。
 * 现在给它自己的边界：底色、描边、圆角、一层很浅的投影。
 * 卡片顶部仍然落在 67px 那条线上（--el9-bleed 给的 12px），跟首页标签栏对齐。
 */
.el9-article-head {
    padding: var(--el9-5);
    border-radius: var(--el9-r-lg);
    /*
     * 白底上的白卡：只留一圈最浅的描边（--el9-border，跟信息流卡片同一条线），
     * 不加投影 —— 文章页这块面积大，一有影子就显得「浮起来」，反而抢标题。
     */
    background: var(--el9-bg);
    border: 1px solid var(--el9-border);
}

/* 文章大标题：字重从 800 降到 700 —— 中文笔画密，34px 上 800 会糊成一团。
   字号 34 → 32，配合 1.25 行高，标题更从容也不失分量 */
.el9-article-title {
    /* 上面那 12px 由 .el9-layout 统一给，这里再叠一层就比别的页高出一截 */
    margin: 0 0 var(--el9-5);
    font-size: 32px;
    line-height: 1.25;
    font-weight: 700;
    letter-spacing: -.02em;
    text-wrap: balance;
}

/* 说说详情页没有标题，卡片里只剩作者一行，上下留 20 会显得空 */
.is-talk-single .el9-article-head {
    padding-top: var(--el9-4);
    padding-bottom: var(--el9-4);
}

.el9-article-meta {
    display: flex;
    align-items: center;
    gap: var(--el9-3);
    /* 标题 → 作者信息：16。下面不再补通栏线 —— 卡片自己的边和投影
       已经把「头部到这儿结束」交代清楚了 */
    margin-top: var(--el9-4);
}

.el9-article-meta-text {
    display: flex;
    flex-direction: column;
}

.el9-article-meta-side {
    display: flex;
    align-items: center;
    gap: var(--el9-1);
    margin-left: auto;
    color: var(--el9-text-2);
    font-size: 13px;
    flex-wrap: wrap;
    justify-content: flex-end;
}

.el9-article-cover {
    margin: var(--el9-4) 0 0;
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-lg);
    overflow: hidden;
    background: var(--el9-skeleton);
}

/* 封面在卡片里时，外框已经有一层了，再描一圈会显脏 */
.el9-article-head .el9-article-cover {
    border: 0;
    border-radius: var(--el9-r-md);
}

.el9-article-cover img {
    display: block;
    width: 100%;
    aspect-ratio: 16 / 9;
    object-fit: cover;
}

.el9-article-foot {
    display: flex;
    align-items: center;
    gap: var(--el9-3);
    flex-wrap: wrap;
    padding-top: var(--el9-5);
    margin-top: var(--el9-6);
    border-top: 1px solid var(--el9-border);
}

/*
 * 分类 + 标签占一整行。
 * 原来标签和「评论数 / 浏览量 / 分享」这几个图标挤在同一条线上，
 * 图标那排看着像最后一个标签的附属物，读起来分不清哪块是分类哪块是操作。
 */
.el9-article-foot .el9-postmeta {
    flex: 0 0 100%;
}

.el9-postmeta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--el9-2);
}

.el9-catline {
    display: flex;
    flex-wrap: wrap;
    gap: var(--el9-2);
}

/*
 * 分类胶囊：跟标签同高，但用主题色描边——同一行里要能一眼分出
 * 「这是分类（可点进同类）」和「这是标签」。
 */
.el9-catline a {
    display: inline-flex;
    align-items: center;
    height: 28px;
    padding: 0 10px;
    border: 1px solid var(--el9-accent);
    border-radius: var(--el9-r-full);
    color: var(--el9-accent);
    font-size: 12.5px;
    font-weight: 600;
    transition: background var(--el9-dur) var(--el9-ease), color var(--el9-dur) var(--el9-ease);
}

.el9-catline a:hover {
    background: var(--el9-accent);
    color: #fff;
}

.el9-tags {
    display: flex;
    flex-wrap: wrap;
    gap: var(--el9-2);
}

/*
 * 标签：细描边的小胶囊，不再是实心浅蓝块。
 *
 * 实心块（accent-soft 底 + accent 字）在文章末尾太抢眼，跟旁边的评论数、
 * 浏览量、分享摆在一起时，颜色分量压过了那排操作按钮。
 * 改成描边版：默认是次要文字色，hover 才亮成主题色。
 */
.el9-tags a {
    display: inline-flex;
    align-items: center;
    height: 28px;
    padding: 0 10px;
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-full);
    background: transparent;
    color: var(--el9-text-2);
    font-size: 12.5px;
    font-weight: 500;
    transition: border-color var(--el9-dur) var(--el9-ease), color var(--el9-dur) var(--el9-ease);
}

.el9-tags a:hover {
    border-color: var(--el9-accent);
    color: var(--el9-accent);
}

.el9-edit {
    display: inline-flex;
    align-items: center;
    gap: var(--el9-1);
    margin-left: auto;
    color: var(--el9-text-2);
    font-size: 13px;
}

/* 说说的「编辑」是 <button>（走前台弹层），按钮默认样式要抹掉 */
button.el9-edit {
    padding: 0;
    border: 0;
    background: none;
    font: inherit;
    font-size: 13px;
    cursor: pointer;
}

.el9-edit:hover {
    color: var(--el9-accent);
}

.el9-near {
    padding: 0 0 var(--el9-6);
}

.el9-near-inner {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--el9-3);
}

.el9-near-item {
    padding: var(--el9-3) var(--el9-4);
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-md);
    font-size: 15px;
    transition: border-color var(--el9-dur) var(--el9-ease), background var(--el9-dur) var(--el9-ease);
}

.el9-near-item:hover {
    border-color: var(--el9-border-strong);
    background: var(--el9-bg-hover);
}

.el9-near-item.is-next {
    text-align: right;
}

.el9-near-label {
    display: block;
    margin-bottom: var(--el9-1);
    color: var(--el9-text-2);
    font-size: 13px;
}

.el9-page {
    /* 同 .el9-article：顶部留白只认 .el9-layout，页面里不再叠 8px。
       之前「关于 / 友链」的标题比首页、文章页低 16px，就是这 8px 加标题的 8px */
    padding: 0 0 var(--el9-6);
}

.el9-page-head {
    display: flex;
    align-items: baseline;
    gap: var(--el9-3);
}

.el9-page-title {
    margin: 0 0 var(--el9-4);
    font-size: 28px;
    font-weight: 800;
    letter-spacing: -.02em;
}

/*
 * 「我们的故事」不输出标题，正文直接从顶上开始 —— 所以不要 .el9-page 那 8px 顶内边距。
 *
 * 这里原来还有一条 `margin-top: calc(12px - 40px)` 的负 margin，本意是抵掉
 * 「主栏给文章页的 40px 顶留白」。可那条 40px 后来为了「所有页面顶部都是 12」
 * 被归零了（见 .is-page .el9-main），负 margin 却留在原地 —— 于是它把整块
 * 往上拽了 28px，实测导航底到说明框只剩 8px，比右栏名片的 12px 还高出一截，
 * 顶上那排东西是斜的。补偿值只对当初那个数有效，前提一变就得一起删。
 *
 * 现在不加任何补偿：顶留白全交给 .el9-layout 的 --el9-bleed（12px），
 * 和侧栏名片落在同一条线上。
 */
.el9-page--mycomments {
    padding-top: 0;
}

/*
 * 首块归零上边距，让三种分支（正常 / 认不出人 / 没评论）都从同一条线开始。
 *
 * 说明框本来吃 `.el9-content > *:first-child` 的归零，但 .el9-content 自己
 * 带着 24px 上边距（那是给「页面标题 → 正文」留的），没有标题时就成了凭空的 24px。
 * 只归零首块、不动 .el9-content 本体：这一页以后要加标题，把标题插到前面，
 * 正文和标题之间的 24px 还在。
 */
.el9-page--mycomments > :first-child {
    margin-top: 0;
}

/* ---- 黑名单公示页 ----
 *
 * 规则说明用浅底卡片放在最上面，下面是域名逐条列：
 * 域名 + 拉黑时间、理由、以及涉及的那几条评论（谁、什么时候留的）。
 */
.el9-blk-rule {
    padding: var(--el9-4);
    margin-bottom: var(--el9-5);
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-lg);
    background: var(--el9-bg-soft);
}

.el9-blk-rule-title {
    margin: 0 0 var(--el9-2);
    font-size: 14px;
    font-weight: 700;
    color: var(--el9-text);
}

.el9-blk-rule-text {
    margin: 0;
    font-size: 13.5px;
    line-height: 1.85;
    color: var(--el9-text-2);
}

/* 规则清单：一条一行，前面一个小圆点 —— 比一大段话好扫读 */
.el9-blk-rule-text .el9-rule {
    display: grid;
    gap: 6px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.el9-blk-rule-text .el9-rule li {
    position: relative;
    padding-left: 16px;
    line-height: 1.75;
}

.el9-blk-rule-text .el9-rule li::before {
    content: '';
    position: absolute;
    left: 2px;
    top: .62em;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--el9-accent);
    opacity: .55;
}

.el9-blk-rule-text .el9-rule-foot {
    margin: 11px 0 0;
    padding-top: 9px;
    border-top: 1px dashed var(--el9-border);
    font-size: 12.5px;
    color: var(--el9-text-3);
}

.el9-blk-rule-text b {
    color: var(--el9-text);
    font-weight: 600;
}

.el9-blk-count {
    margin: 0 0 var(--el9-3);
    font-size: 13px;
    color: var(--el9-text-3);
}

.el9-blk-count strong {
    color: var(--el9-text);
}

.el9-blk-list {
    margin: 0;
    padding: 0;
    list-style: none;
    display: grid;
    gap: var(--el9-3);
}

.el9-blk-item {
    padding: var(--el9-3) var(--el9-4);
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-lg);
    background: var(--el9-bg);
}

.el9-blk-top {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--el9-3);
}

.el9-blk-domain {
    font-family: ui-monospace, Menlo, Consolas, monospace;
    font-size: 14px;
    font-weight: 600;
    color: var(--el9-text);
    word-break: break-all;
}

.el9-blk-date {
    flex: none;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 12px;
    color: var(--el9-text-3);
    font-variant-numeric: tabular-nums;
}

.el9-blk-why {
    margin: 6px 0 0;
    font-size: 13px;
    line-height: 1.7;
    color: var(--el9-text-2);
}

.el9-blk-people {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 16px;
    margin: 9px 0 0;
    padding: 0;
    list-style: none;
    font-size: 12.5px;
    color: var(--el9-text-3);
}

.el9-blk-people li {
    display: inline-flex;
    align-items: baseline;
    gap: 6px;
}

.el9-blk-name {
    font-weight: 600;
    color: var(--el9-text-2);
}

.el9-blk-when {
    font-variant-numeric: tabular-nums;
}

.el9-talks-more {
    padding: var(--el9-5) 0;
    text-align: center;
}

/* ==========================================================================
   7. 正文排版
   ========================================================================== */

/* 正文与上方元信息之间留一段，别让正文贴着分隔线 */
.el9-content {
    margin-top: var(--el9-6);
    font-size: 17px;
    /* 行长收到 40em 左右之后，行高 1.8 刚好：长行需要更大的行高才不串行 */
    line-height: 1.8;
    color: var(--el9-text);
    /*
     * 换行规则（中英混排的关键）：
     * - word-break: normal —— 英文单词保持完整，不在词内随意断
     * - overflow-wrap: break-word —— 只有当单词长到一行放不下时才强制断开（兜底）
     * - line-break: strict —— 按中文标点规则断行，避免「（」「「」这类标点孤零零落在行尾/行首
     * - text-wrap: pretty —— 支持的浏览器会优化最后几行的断法，少出现孤字
     * 之前写的是 word-break: break-word，长英文词遇到行尾就整词跳到下一行，
     * 上一行留一大块白，每行长度参差不齐。
     */
    word-break: normal;
    overflow-wrap: break-word;
    line-break: strict;
    /* 中文正文：字距放开一点点，密排会糊 */
    letter-spacing: .01em;
}

.el9-content > *:first-child {
    margin-top: 0;
}

.el9-content p {
    margin: 0 0 1.1em;
}

/* ---- 正文宽度：跟着主栏走，不再单独收一道 ----
 *
 * 这里原来给正文所有子块加了 max-width: 680px。问题有两个：
 *   1. 主栏实际是 720/772，正文 680 —— 右边永远空出一条几十像素的死带，
 *      文字、图片、代码块一齐缩在左边，看着像「没铺满」；
 *   2. 注释写的是「只收文字，媒体照常铺开」，可选器里 pre / figure /
 *      表格 / 图片网格全在，媒体根本没铺开。代码和注释早就对不上了。
 *
 * 现在宽度只有一个来源：主栏宽度（后台「内容区宽度」，默认 720）。
 * 想窄一点就把后台那个值调小（600–1400 可调），别在 CSS 里再写死第二个数 ——
 * 两个数一打架，右边缘就永远对不齐。
 */

/* 标题：字重从 800 降到 700/600 —— 中文笔画密，800 会糊成一团黑。
   层级靠「字号 + 字重 + 上方留白」三重拉开，不靠加粗硬怼 */
/* 标题间距改用固定值：原来写 2em 是相对标题自己的字号，
   结果 h1 上方 60px、h4 上方 36px，节奏乱。现在按层级给固定的垂直节奏 */
.el9-content h1,
.el9-content h2,
.el9-content h3,
.el9-content h4 {
    text-wrap: balance;
}

/*
 * 标题层级：比例照 oyiso（正文的 1.50 / 1.25 / 1.06 / 1.00 倍），
 * 基准保持我们自己的正文 17px —— 于是 17×比例 = 26 / 21 / 18 / 17。
 *
 * 之前是 28 / 24 / 20 / 18（1.65 / 1.41 / 1.18 / 1.06），层级拉得太开，
 * 一篇文章里 h3 和 h4 看着像两个不相干的字号。收紧之后靠「字号 + 字重 +
 * 上方留白」三层区分，节奏反而更稳 —— 这也是 Apple 那套的做法。
 */
.el9-content h1 {
    margin: 44px 0 18px;
    font-size: 26px;
    font-weight: 700;
    line-height: 1.35;
    letter-spacing: -.015em;
}

.el9-content h2 {
    margin: 40px 0 16px;
    font-size: 21px;
    font-weight: 700;
    line-height: 1.4;
    letter-spacing: -.012em;
}

.el9-content h3 {
    margin: 32px 0 14px;
    font-size: 18px;
    font-weight: 600;
    line-height: 1.45;
    letter-spacing: -.01em;
}

.el9-content h4 {
    margin: 28px 0 12px;
    font-size: 17px;
    font-weight: 600;
    line-height: 1.5;
    letter-spacing: -.005em;
}

/* h5/h6 跟正文同字号，只靠字重区分（oyiso 也是这么处理的） */
.el9-content h5 {
    margin: 24px 0 10px;
    font-size: 17px;
    font-weight: 600;
    line-height: 1.55;
    letter-spacing: 0;
}

.el9-content h6 {
    margin: 22px 0 8px;
    font-size: 17px;
    font-weight: 400;
    line-height: 1.55;
    letter-spacing: 0;
    color: var(--el9-text-2);
}

/*
 * 标题左侧竖条：给层级一个「不靠字号也能一眼看见」的抓手。
 *
 * 之前层级全靠字号 + 字重 + 上方留白。字号收紧到 1.50/1.25/1.06 之后
 * （见上面那段注释），h2 和 h3 只差 3px，长文里翻着翻着就分不清哪是章节、
 * 哪是小节了。加一条竖线，扫一眼就知道层级在哪。
 *
 * 只挂 h2 / h3：h4 往下字号已经跟正文贴住，再加线，一段话里会全是竖条。
 *
 * 用 ::before 而不是 border-left —— border 的高度跟着整行盒子走（含行高留白），
 * 视觉上比字高一截，像贴了张标签；伪元素的上下各收 .16em，长短才跟字号对得上。
 */
.el9-content h2,
.el9-content h3 {
    position: relative;
    padding-left: 14px;
}

.el9-content h2::before,
.el9-content h3::before {
    content: "";
    position: absolute;
    left: 0;
    top: .16em;
    bottom: .16em;
    border-radius: 2px;
    background: var(--el9-accent);
}

.el9-content h2::before {
    width: 4px;
}

/* h3 细一档、淡一档：紧挨着 h2 的时候，一眼能看出「这是下一级」而不是又一个章节。
   淡到这个程度就够了，再淡白底上会像没加载出来的边框 */
.el9-content h3 {
    padding-left: 12px;
}

.el9-content h3::before {
    width: 3px;
    border-radius: 1.5px;
    opacity: .55;
}

/* 紧跟在标题后面的段落别再顶一大块留白 */
.el9-content h1 + p,
.el9-content h2 + p,
.el9-content h3 + p,
.el9-content h4 + p {
    margin-top: -4px;
}

/* 目录锚点跳转时，标题别贴着视口顶 */
.el9-content h2[id],
.el9-content h3[id] {
    scroll-margin-top: calc(var(--el9-nav-h) + 34px);
}

/*
 * 正文链接：下划线改成「从左展开、向右收起」
 *
 * 常显的 text-decoration 换成一层渐变背景线：收起时贴在右边、宽度 0（看不见），
 * 鼠标移上去位置瞬间跳到左边再展开 —— 看着是从左往右长出来；
 * 移开时位置瞬间回右边再收缩，看着是往右滑走。
 *
 * 三个细节：
 *   ① background-position 过渡写 0s —— 位置要「瞬移」。宽 100% 时左右端点重合，
 *      瞬移看不出来；真给它加过渡反而能看到线在横着滑动。
 *   ② box-decoration-break: clone —— 链接跨行时每行各画自己那一段，
 *      不然整条线只会出现在最后一行。
 *   ③ 排除图片链接（灯箱那种）：线画在图片底下很奇怪。
 */
.el9-content a:not(.el9-zoomable):not(:has(img)) {
    color: var(--el9-accent-text);
    text-decoration: none;
    padding-bottom: 2px;
    background-image: linear-gradient(currentColor, currentColor);
    background-repeat: no-repeat;
    background-position: right bottom;
    background-size: 0 1px;
    transition: background-size .28s var(--el9-ease), background-position 0s;
    -webkit-box-decoration-break: clone;
    box-decoration-break: clone;
}

.el9-content a:not(.el9-zoomable):not(:has(img)):hover,
.el9-content a:not(.el9-zoomable):not(:has(img)):focus-visible {
    background-position: left bottom;
    background-size: 100% 1px;
}

.el9-content a:hover {
    text-decoration-thickness: 2px;
}

/*
 * 站外链接的小箭头
 *
 * 用 mask 画而不是插一个 <svg> 或写个 ↗ 字符：
 *   - 字符在不同系统里字形差很多，而且会被一起复制走；
 *   - inline svg 每加一个链接就多一段标签，正文里几十个外链就多几十个节点。
 * mask 版的颜色取自 currentColor，深色模式不用另写一套。
 */
.el9-content a.el9-ext::after {
    content: "";
    display: inline-block;
    width: .58em;
    height: .58em;
    margin-left: .2em;
    vertical-align: .02em;
    background-color: currentColor;
    opacity: .5;
    -webkit-mask: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14 4h6v6'/%3E%3Cpath d='M20 4 10 14'/%3E%3Cpath d='M18 13v6a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h6'/%3E%3C/svg%3E") no-repeat center / contain;
    mask: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14 4h6v6'/%3E%3Cpath d='M20 4 10 14'/%3E%3Cpath d='M18 13v6a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h6'/%3E%3C/svg%3E") no-repeat center / contain;
}

.el9-content a.el9-ext:hover::after { opacity: .85; }

/* 打印时不画（纸上看不到「新窗口打开」这件事，箭头只会碍事） */
@media print {
    .el9-content a.el9-ext::after { display: none; }

    /*
     * 标题左边那道竖条，屏幕上是用 ::before + background 画的。
     *
     * 浏览器默认**不打印背景色/背景图**（打印对话框里那个「背景图形」是关着的），
     * 所以打出来竖条整条消失 —— 之前干脆连缩进一起归零了事，结果标题变成
     * 一个光秃秃的黑字，跟正文分不开。而边框（border）是会打印的。
     *
     * 所以纸上改用 border-left 画这条竖条：颜色、粗细跟屏幕一致，缩进也留着。
     * h3 原来靠 opacity 淡化，边框没法单独调透明度，用 color-mix 兑白；
     * 不支持 color-mix 的浏览器会忽略这行，退回上一行的实色 —— 只是没那么淡，不影响。
     */
    .el9-content h2,
    .el9-content h3 {
        padding-left: 12px;
        border-left: 4px solid var(--el9-accent);
    }

    .el9-content h3 {
        border-left-width: 3px;
        border-left-color: var(--el9-accent);
        border-left-color: color-mix(in srgb, var(--el9-accent) 55%, #fff);
    }

    /* 屏幕上那条 ::before 关掉，否则纸上会多出一条没颜色的空条 */
    .el9-content h2::before,
    .el9-content h3::before {
        display: none !important;
    }
}

.el9-content ul,
.el9-content ol {
    margin: 0 0 1.15em;
    padding-left: 1.5em;
    list-style: revert;
}

.el9-content li {
    margin: .45em 0;
    line-height: 1.75;
}

/* 列表项里的段落别再撑开间距 */
.el9-content li p {
    margin: 0 0 .4em;
}

.el9-content li > p:last-child {
    margin-bottom: 0;
}

.el9-content li > ul,
.el9-content li > ol {
    margin: .3em 0;
}

/* 引用：做成一张带左侧色条的卡片，不再是光秃秃一条竖线 */
.el9-content blockquote {
    margin: 1.6em 0;
    padding: var(--el9-3) var(--el9-4);
    border-left: 3px solid var(--el9-border-strong);
    border-radius: 0 var(--el9-r-md) var(--el9-r-md) 0;
    background: var(--el9-bg-soft);
    color: var(--el9-text-2);
}

.el9-content blockquote p:last-child {
    margin-bottom: 0;
}

/* ---- 提示框（callout）：> [!TIP] / [!NOTE] / [!WARNING] ---- */

/*
 * 提示框（方角卡）
 *
 * 版式照 oyiso 的 shortcode-tip：「图标 + 标签」占一行小标题，下面接正文，
 * 整体一张 10px 圆角的淡色卡 —— 1px 半透明描边 + 5% 淡底，不用左边那条粗彩条。
 *
 * 每个变体只定两个变量：--co（装饰原色）和 --co-ink（文字色）。
 * 描边、淡底都由 --co 派生，所以换语义只要改这两行。
 */
.el9-callout {
    --co: var(--el9-accent);
    --co-ink: var(--el9-accent-text);

    margin: 1.6em 0;
    padding: var(--el9-4);
    border: 1px solid color-mix(in srgb, var(--co) 45%, transparent);
    border-radius: 10px;
    background: color-mix(in srgb, var(--co) 5%, var(--el9-bg));
}

.el9-callout-label {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 0;
    font-size: 14px;
    font-weight: 600;
    line-height: 1.5;
    letter-spacing: 0;
    color: var(--co-ink);
}

.el9-callout-icon {
    display: inline-flex;
    flex: none;
    color: var(--co-ink);
}

.el9-callout-icon svg {
    display: block;
}

.el9-callout-body {
    margin-top: var(--el9-2);
    color: var(--el9-text);
    font-size: 14px;
    /* 卡里的正文比大正文紧凑一档，14px 配 1.65 刚好不挤 */
    line-height: 1.65;
}

.el9-callout-body p {
    margin: var(--el9-2) 0;
}

.el9-callout-body > *:first-child {
    margin-top: 0;
}

.el9-callout-body > *:last-child {
    margin-bottom: 0;
}

/* 五种语义只换变量 */
.el9-callout--note      { --co: var(--el9-c-note);    --co-ink: var(--el9-c-note-ink); }
.el9-callout--tip       { --co: var(--el9-c-tip);     --co-ink: var(--el9-c-tip-ink); }
.el9-callout--important { --co: var(--el9-accent);    --co-ink: var(--el9-accent-text); }
.el9-callout--warning   { --co: var(--el9-c-warning); --co-ink: var(--el9-c-warning-ink); }
.el9-callout--caution   { --co: var(--el9-c-caution); --co-ink: var(--el9-c-caution-ink); }

/* 旧浏览器没有 color-mix：退回中性底 + 左侧彩条，至少语义色还在 */
@supports not (background: color-mix(in srgb, red 10%, blue)) {
    .el9-callout {
        border-color: var(--el9-border);
        border-left: 3px solid var(--co);
        background: var(--el9-bg-soft);
    }
}

/*
 * 折叠面板：[details=标题] 内容 [/details]
 *
 * 结构由 el9RenderDetails() 输出，样式跟提示卡同一套规格（10px 圆角、
 * 主题色 45% 描边、5% 淡底），只是标题行可点、带一个会转的小箭头。
 */
.el9-fold {
    margin: 1.6em 0;
    padding: var(--el9-4);
    border: 1px solid color-mix(in srgb, var(--el9-accent) 45%, transparent);
    border-radius: 10px;
    background: color-mix(in srgb, var(--el9-accent) 5%, var(--el9-bg));
}

.el9-fold > summary {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 14px;
    font-weight: 600;
    line-height: 1.5;
    color: var(--el9-accent-text);
    cursor: pointer;
    user-select: none;
    list-style: none;
}

/* 去掉浏览器自带的小三角，换成自己的箭头 */
.el9-fold > summary::-webkit-details-marker {
    display: none;
}

.el9-fold > summary::before {
    content: '';
    flex: none;
    width: 7px;
    height: 7px;
    margin-right: 2px;
    border-right: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    transform: rotate(-45deg);
    transition: transform var(--el9-dur) var(--el9-ease);
}

.el9-fold[open] > summary::before {
    transform: rotate(45deg);
}

/* 标题为空时（作者只写了 [details]）兜一句默认文案 */
.el9-fold > summary:empty::after {
    content: '点击展开';
}

.el9-fold-body {
    margin-top: var(--el9-3);
}

.el9-fold-body > *:first-child {
    margin-top: 0;
}

.el9-fold-body > *:last-child {
    margin-bottom: 0;
}

@supports not (background: color-mix(in srgb, red 10%, blue)) {
    .el9-fold {
        border-color: var(--el9-border);
        background: var(--el9-bg-soft);
    }
}

.el9-content hr {
    height: 0;
    margin: 2em 0;
    border: 0;
    border-top: 1px solid var(--el9-border);
}

.el9-content img {
    max-width: 100%;
    height: auto;
    margin: 1.4em auto;
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-md);
}

/* ---- 脚注 ----
 *
 * 用的是 **Markdown 原生语法**，主题不写解析：
 *   正文里写 [^1]   → <sup class="footnote-ref"><a href="#fn-1">1</a></sup>
 *   末尾写 [^1]: 内容 → <div class="footnotes"><ol><li id="fn-1">…</li></ol></div>
 * Typecho 的 \Utils\Markdown 本来就会输出这套结构（实测过），
 * 所以这里只管长相，不碰解析 —— 少一层自己写的正则，就少一处出错的地方。
 *
 * 默认输出里 <hr> 和我们的上边框重复，隐藏掉。
 */
.el9-content .footnotes {
    margin-top: 2.6em;
    padding-top: 1.1em;
    border-top: 1px solid var(--el9-border-strong);
    font-size: .92em;
    color: var(--el9-text-2);
}

.el9-content .footnotes hr {
    display: none;
}

/* 「脚注」两个字：Markdown 不管这个标题，用伪元素补，不改 HTML */
.el9-content .footnotes::before {
    content: '脚注';
    display: block;
    margin-bottom: .7em;
    font-size: .78em;
    font-weight: 600;
    letter-spacing: .08em;
    color: var(--el9-text-3);
}

.el9-content .footnotes ol {
    margin: 0;
    padding-left: 1.5em;
}

.el9-content .footnotes li {
    margin: .55em 0;
    line-height: 1.85;
    /*
     * 点脚注编号跳到这里时，别让正文顶到吸顶导航底下。
     * 55 是导航高度，再加一点余量，看起来才像「跳到了这一条」。
     */
    scroll-margin-top: calc(var(--el9-nav-h, 55px) + 28px);
}

.el9-content .footnotes li p {
    margin: 0;
}

/*
 * 返回正文时要落到的位置是 <sup id="fnref-1">，不是里面那个 <a>。
 * 所以偏移得加在 sup 上 —— 之前只加在 .footnote-ref（a）上，
 * 点脚注末尾的 ↩ 跳回去时完全没有偏移，直接顶到吸顶导航底下，
 * 看着就像「没跳回去」（其实是跳了，但目标藏在导航条后面）。
 */
.el9-content sup[id^="fnref-"] {
    scroll-margin-top: calc(var(--el9-nav-h, 55px) + 28px);
}

/* 正文里的上标编号 */
.el9-content .footnote-ref {
    position: relative;
    padding: 0 .15em;
    font-size: .74em;
    font-weight: 600;
    line-height: 1;
    text-decoration: none;
    vertical-align: super;
    color: var(--el9-accent-text);
    /* 从脚注跳回正文时，同样别被吸顶导航挡住 */
    scroll-margin-top: calc(var(--el9-nav-h, 55px) + 28px);
}

/*
 * 悬停看脚注内容。
 *
 * 文字是 JS 从对应的 <li> 里抠出来、写进 data-fn-text 的 ——
 * CSS 的 attr() 只能读自己身上的属性，读不到别的元素。
 * 不用原生 title：它有一秒多的延迟，而且样式没法调。
 */
.el9-content .footnote-ref::after {
    content: attr(data-fn-text);
    position: absolute;
    left: 50%;
    bottom: calc(100% + 10px);
    transform: translateX(-50%) translateY(4px);
    z-index: 30;
    width: max-content;
    max-width: min(300px, 62vw);
    padding: 9px 12px;
    border-radius: 10px;
    /* 跟主题一致：浅色底 + 细边 + 淡阴影，不用深色反白 */
    background: var(--el9-bg);
    color: var(--el9-text);
    border: 1px solid var(--el9-border-strong);
    box-shadow: 0 8px 24px rgba(0, 0, 0, .1), 0 2px 6px rgba(0, 0, 0, .04);
    font-size: 12.5px;
    font-weight: 400;
    line-height: 1.65;
    letter-spacing: 0;
    text-align: left;
    white-space: normal;
    /* 上标字很小，不重置的话提示框会跟着缩成 9px */
    text-transform: none;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity var(--el9-dur) var(--el9-ease), transform var(--el9-dur) var(--el9-ease);
}

/* 没抓到内容（比如老内容里手写的空脚注）就不弹空框 */
.el9-content .footnote-ref:not([data-fn-text])::after {
    content: none;
}

.el9-content .footnote-ref:hover::after,
.el9-content .footnote-ref:focus::after {
    opacity: 1;
    visibility: visible;
    transform: translateX(-50%) translateY(0);
}

.el9-content .footnote-ref:hover {
    text-decoration: underline;
}

/* 每条脚注末尾那个 ↩ */
.el9-content .footnote-backref {
    margin-left: .4em;
    text-decoration: none;
    color: var(--el9-accent-text);
    opacity: .6;
    transition: opacity var(--el9-dur) var(--el9-ease);
}

.el9-content .footnote-backref:hover {
    opacity: 1;
    text-decoration: none;
}

/*
 * 行内代码：跟着主题色走。
 *
 * 原来是灰底黑字（--el9-bg-soft），在正文里跟普通文字几乎是同一个色调，
 * 一眼分不出来。现在底色用主题色的 10% 淡色、文字用深一档的主题色
 * （--el9-accent-text 是算过的，白底上对比度够），换强调色时两样一起跟着变。
 */
.el9-content code {
    padding: .12em .4em;
    border-radius: var(--el9-r-sm);
    background: var(--el9-accent-soft);
    color: var(--el9-accent-text);
    font-family: var(--el9-font-mono);
    font-size: .875em;
}

/* B 站视频：16:9 自适应，圆角跟图片一致 */
.el9-bili {
    position: relative;
    margin: 1.4em 0;
    padding-top: 56.25%;
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-md);
    overflow: hidden;
    background: #000;
}

.el9-bili iframe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
}

.el9-card-text .el9-bili {
    margin: var(--el9-2) 0 0;
}

.el9-content pre {
    position: relative;
    margin: 1.4em 0;
    /* 内边距挪进 .el9-code-body —— 行号列要顶到边框，不能跟着代码一起缩进 */
    padding: 0;
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-md);
    background: var(--el9-bg-soft);
    overflow: hidden;
    font-size: 14px;
    line-height: 1.7;
}

/* 有行号时的横向滚动容器：滚动发生在这里，行号列靠 sticky 跟着走 */
.el9-code-body {
    display: flex;
    align-items: stretch;
    overflow-x: auto;
    padding-top: 30px;
    scrollbar-width: thin;
}

/* 左上角的语言名 */
.el9-code-lang {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 2;
    padding: 7px 13px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--el9-text-3);
    pointer-events: none;
}

/* 行号列：固定在左边，横向滚动时不动 */
.el9-code-ln {
    position: sticky;
    left: 0;
    z-index: 1;
    flex: 0 0 auto;
    padding: 14px 10px 14px 14px;
    border-right: 1px solid var(--el9-border);
    background: var(--el9-bg-soft);
    color: var(--el9-text-3);
    opacity: .6;
    text-align: right;
    white-space: pre;
    user-select: none;
    -webkit-user-select: none;
    font-variant-numeric: tabular-nums;
}

.el9-content pre code {
    flex: 1 0 auto;
    padding: 14px;
    background: none;
    /*
     * 颜色必须还回去。
     * 上面 .el9-content code 现在带主题色，代码块里的 code 也会继承到 ——
     * 结果整块代码变蓝，只有被 highlight.js 标了 token 的部分才是原色，
     * 没标到的普通标识符、注释外文字全成了链接色。
     * 用 inherit 让它跟着 pre 的正文色走，配色仍由 hljs 的 token 规则决定。
     */
    color: inherit;
    font-size: inherit;
    /* 不折行：一折行，视觉行数就和左边那列数字对不上了 */
    white-space: pre;
}

/* ---- 代码高亮（highlight.js token 配色，跟随深浅色） ---- */

.hljs {
    color: var(--el9-text);
    background: transparent;
}

.hljs-comment,
.hljs-quote {
    color: var(--el9-text-3);
    font-style: italic;
}

.hljs-keyword,
.hljs-selector-tag,
.hljs-literal,
.hljs-doctag,
.hljs-name,
.hljs-strong {
    color: #d73a49;
}

.hljs-string,
.hljs-regexp,
.hljs-addition,
.hljs-meta .hljs-string {
    color: #0a7d34;
}

.hljs-number,
.hljs-variable,
.hljs-template-variable,
.hljs-selector-attr,
.hljs-selector-pseudo {
    color: #b8561f;
}

.hljs-title,
.hljs-title.class_,
.hljs-title.function_,
.hljs-section {
    color: #6f42c1;
    font-weight: 600;
}

.hljs-attr,
.hljs-attribute,
.hljs-symbol,
.hljs-bullet,
.hljs-link {
    color: #005cc5;
}

.hljs-built_in,
.hljs-type,
.hljs-class .hljs-title {
    color: #c2410c;
}

.hljs-deletion {
    color: #b31d28;
}

.hljs-emphasis {
    font-style: italic;
}

/* 表格：外壳负责圆角和横向滚动，表格本身只管格子 */
.el9-table-wrap {
    margin: 1.6em 0;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-md);
    background: var(--el9-bg);
    -webkit-overflow-scrolling: touch;
}

.el9-table-wrap:focus-visible {
    outline: 2px solid var(--el9-accent-text);
    outline-offset: 2px;
}

.el9-content table {
    width: 100%;
    margin: 0;
    border-collapse: collapse;
    border-spacing: 0;
    font-size: 15px;
}

.el9-content th,
.el9-content td {
    padding: 11px var(--el9-4);
    border-bottom: 1px solid var(--el9-border);
    text-align: left;
    vertical-align: top;
    line-height: 1.6;
}

/* 最后一排不留线，圆角才干净 */
.el9-content tbody tr:last-child td {
    border-bottom: 0;
}

.el9-content th {
    background: var(--el9-bg-soft);
    font-size: 13px;
    font-weight: 600;
    color: var(--el9-text-2);
    letter-spacing: .02em;
    white-space: nowrap;
    /* 表头下面的线加重一点，跟数据行区分开 */
    box-shadow: inset 0 -1px 0 var(--el9-border-strong);
}

.el9-content tbody tr:hover td {
    background: var(--el9-bg-hover);
}

/* 首列当行标题时稍微强调 */
.el9-content td:first-child {
    font-weight: 500;
}

.el9-content iframe,
.el9-content video {
    max-width: 100%;
    border-radius: var(--el9-r-md);
}

/* ---- 回复可见 [hide] ---- */

/* 锁住时：一张柔和的卡片，顶部一条提示条 + 下面糊掉的占位 */
.el9-secret {
    position: relative;
    margin: 1.6em 0;
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-md);
    background: var(--el9-bg-soft);
    overflow: hidden;
}

/* 解锁后：去掉底纹，只留一圈淡边框把这段框出来 */
.el9-secret.is-open {
    border-color: var(--el9-border);
    background: none;
    padding: 0 var(--el9-4) 2px;
}

.el9-secret.is-open > *:first-child {
    margin-top: 0;
}

.el9-secret.is-open > *:last-child {
    margin-bottom: 0;
}

.el9-secret-tip {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px var(--el9-4);
    border-bottom: 1px solid var(--el9-border);
    background: var(--el9-bg);
}

/* 锁图标：放进浅色圆底，跟提示框/标题图标一个路数 */
.el9-secret-tip .el9-icon {
    flex: none;
    width: 18px;
    height: 18px;
    padding: 5px;
    box-sizing: content-box;
    border-radius: var(--el9-r-full);
    background: var(--el9-accent-soft);
    color: var(--el9-accent-text);
}

.el9-secret-tip p {
    margin: 0;
    font-size: 14px;
    line-height: 1.6;
    color: var(--el9-text-2);
}

/* 「回复」做成小按钮，比光一个链接更像个动作 */
.el9-secret-tip a {
    display: inline-block;
    margin: 0 2px;
    padding: 1px 8px;
    border-radius: var(--el9-r-full);
    background: var(--el9-accent-soft);
    color: var(--el9-accent-text);
    font-weight: 600;
    text-decoration: none;
}

.el9-secret-tip a:hover {
    background: color-mix(in srgb, var(--el9-accent) 18%, transparent);
    text-decoration: none;
}

/* 管理员看到的判定依据：低调地贴在锁定框底部，不抢正文注意力 */
.el9-secret-hint {
    margin: 0;
    padding: var(--el9-2) var(--el9-4);
    border-top: 1px dashed var(--el9-border);
    font-size: 11.5px;
    line-height: 1.7;
    color: var(--el9-text-3);
}

.el9-secret-hint code {
    padding: 1px 5px;
    border-radius: 5px;
    background: var(--el9-bg-soft);
    border: 1px solid var(--el9-border);
    font-family: var(--el9-font-mono);
    font-size: 11px;
    color: var(--el9-text-2);
}

/* 未回复时把原文糊掉：只留一点存在感，不让内容被选中/复制 */
.el9-secret-fog {
    position: relative;
    max-height: 88px;
    overflow: hidden;
    user-select: none;
    -webkit-user-select: none;
    filter: blur(5px);
    opacity: .5;
    pointer-events: none;
}

.el9-secret-fog::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, transparent 0%, var(--el9-bg-soft) 92%);
}

.el9-secret-fog > *:first-child {
    margin-top: 0;
}

.el9-secret-fog > *:last-child {
    margin-bottom: 0;
}

.el9-secret-fog img {
    max-height: 88px;
    object-fit: cover;
}

/* 多图网格（由 JS 包装） */
.el9-img-grid {
    display: grid;
    gap: var(--el9-1);
    margin: 1.4em 0;
    border-radius: var(--el9-r-md);
    overflow: hidden;
}

.el9-img-grid[data-count="2"] { grid-template-columns: 1fr 1fr; }
.el9-img-grid[data-count="3"] { grid-template-columns: repeat(3, 1fr); }

/* 九宫格：9 张排 3×3，跟三列同一套列宽 */
.el9-img-grid[data-count="9"] {
    grid-template-columns: repeat(3, minmax(0, 1fr));
}
.el9-img-grid[data-count="4"] { grid-template-columns: 1fr 1fr; }

.el9-img-grid img {
    width: 100%;
    height: 100%;
    margin: 0;
    border: 0;
    border-radius: 0;
    object-fit: cover;
    aspect-ratio: 1 / 1;
}

.el9-img-grid[data-count="2"] img,
.el9-img-grid[data-count="3"] img {
    aspect-ratio: 3 / 4;
}

/* ---- 说说多图：横向滑动条 ---- */

.el9-img-strip {
    position: relative;
    margin: var(--el9-2) 0 var(--el9-1);
}

.el9-img-strip-track {
    position: relative;
    display: flex;
    gap: var(--el9-2);
    overflow-x: auto;
    /* 这里刻意不用 scroll-snap：吸附会在松手那一刻把位置拽回最近的图，
       从最右往回拖一点点就被弹回去，看着像「滑不回来了」；
       而且它跟 JS 直改 scrollLeft 也打架，手感一顿一顿。自由滑动最省心。 */
    scrollbar-width: none;
    padding-bottom: 2px;
    cursor: grab;
}

.el9-img-strip-track.is-dragging {
    cursor: grabbing;
    user-select: none;
    overscroll-behavior-x: contain;
}

/* 注意：拖拽时不要给 img 加 pointer-events:none ——
   is-dragging 是按下那一刻就加上的，一旦图片失去命中能力，
   mouseup 的落点会变成轨道，click 就被派发到图上做不到，灯箱打不开。
   防拖拽交给 img 上的 -webkit-user-drag:none 和 JS 的 draggable=false。 */
.el9-img-strip-track.is-dragging img {
    -webkit-user-drag: none;
}

.el9-img-strip-track::-webkit-scrollbar {
    display: none;
}

.el9-img-strip-track img {
    flex: 0 0 auto;
    /*
     * 宽度按原图比例走，但要给一个最小宽度：
     * 竖长截图（比如手机长截屏，宽高比 1:4）在固定高度下算出来的宽度只有 50 多像素，
     * 缩成一根细条很难看。min-width 兜底，超出的部分由 object-fit: cover 裁掉，
     * 想看全图点开灯箱。
     */
    width: auto;
    min-width: clamp(88px, 26vw, 132px);
    height: clamp(150px, 30vw, 216px);
    margin: 0;
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-md);
    object-fit: cover;
    cursor: zoom-in;
    user-select: none;
    -webkit-user-drag: none;
}

/* ---- 说说单图：限高裁切，点击看全图 ---- */

/*
 * 说说单图：高度跟「多图横滑条」里的图一个量（clamp 那串数字是一模一样的），
 * 宽度按各自比例走 —— 长图就窄、宽图就宽，不再一律撑满正文。
 *
 * 这样一条说说里无论一张还是九张，图的高度都是同一条线，
 * 上下滚的时候不会一张占半屏、下一张只有一小条。
 * 想看大的点开灯箱（高度 216 只是列表里的显示尺寸，原图没动）。
 */
.el9-card-text .el9-img-solo,
.is-talk-single .el9-content .el9-img-solo {
    display: block;
    width: auto;
    max-width: 100%;
    height: clamp(150px, 30vw, 216px);
    /*
     * 跟横滑条里那条一模一样的下限：长图按比例算出来可能只有 100 出头，
     * 缩成一根牙签就什么都看不出了。给个底，超出的部分由 cover 裁。
     */
    min-width: clamp(88px, 26vw, 132px);
    object-fit: cover;
    object-position: center top;
    margin: var(--el9-2) 0;
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-md);
    cursor: zoom-in;
    user-select: none;
    -webkit-user-drag: none;
}

/*
 * 说说单图里「原图本来就不宽」的那批：按原尺寸摆，不放大也不裁。
 *
 * 上面那条 width:100% + 限高裁切是给大图定的（横图撑满、竖图裁一截）。
 * 一张 300px 的图拉到 600 多再裁一刀，只是插值糊出来的残图，不如按原样放。
 * 这个 class 由 app.js 的 markSoloScale() 按 naturalWidth 判断后挂上。
 */
.el9-card-text .el9-img-solo.el9-img-solo-small,
.is-talk-single .el9-content .el9-img-solo.el9-img-solo-small {
    width: auto;
    max-width: 100%;
    height: auto;
    /* 高度照样封顶：原图本来就窄，再让它撑到五百多高，一条卡片就只剩图了 */
    max-height: min(340px, 45vh);
    object-fit: contain;
}

/* ---- 图片点击放大（文章正文 / 说说通用） ---- */

.el9-zoomable {
    cursor: zoom-in;
    -webkit-user-drag: none;
}

.el9-content img.el9-zoomable,
.el9-card-text img.el9-zoomable {
    border-radius: var(--el9-r-md);
    transition: box-shadow .18s ease, opacity .18s ease;
}

.el9-content img.el9-zoomable:hover,
.el9-card-text img.el9-zoomable:hover {
    box-shadow: 0 0 0 2px var(--el9-accent);
}

.el9-img-grid img.el9-zoomable:hover,
.el9-img-strip-track img.el9-zoomable:hover {
    box-shadow: none;
    opacity: .92;
}

.el9-img-strip-next {
    position: absolute;
    top: 50%;
    right: var(--el9-2);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    padding: 0;
    border: 0;
    border-radius: var(--el9-r-full);
    background: rgba(0, 0, 0, .5);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    color: #fff;
    cursor: pointer;
    box-shadow: 0 2px 10px rgba(0, 0, 0, .2);
    opacity: 0;
    pointer-events: none;
    transform: translateY(-50%);
    transition: opacity 200ms var(--el9-ease), transform 200ms var(--el9-ease);
}

.el9-img-strip.is-scrollable .el9-img-strip-next {
    /* 同上：半透明常显，指针移上来才实体 */
    opacity: .8;
    pointer-events: auto;
}

.el9-img-strip.is-scrollable.is-end .el9-img-strip-next {
    opacity: 0;
    pointer-events: none;
}

.el9-img-strip-next:hover,
.el9-img-strip-prev:hover {
    opacity: 1;
}

.el9-img-strip-next:hover {
    transform: translateY(-50%) scale(1.08);
}

/* 往左翻：跟右边那个对称，滑到开头就藏起来 */
.el9-img-strip-prev {
    position: absolute;
    top: 50%;
    left: var(--el9-2);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    padding: 0;
    border: 0;
    border-radius: var(--el9-r-full);
    background: rgba(0, 0, 0, .5);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    color: #fff;
    cursor: pointer;
    box-shadow: 0 2px 10px rgba(0, 0, 0, .2);
    opacity: 0;
    pointer-events: none;
    transform: translateY(-50%);
    transition: opacity 200ms var(--el9-ease), transform 200ms var(--el9-ease);
}

.el9-img-strip.is-scrollable .el9-img-strip-prev {
    opacity: .8;
    pointer-events: auto;
}

.el9-img-strip.is-scrollable.is-start .el9-img-strip-prev {
    opacity: 0;
    pointer-events: none;
}

.el9-img-strip-prev:hover {
    transform: translateY(-50%) scale(1.08);
}

/* 指示点：放不下才需要，全都能看见时就别摆一排点了 */
.el9-img-strip-dots {
    display: none;
    justify-content: center;
    align-items: center;
    gap: 6px;
    margin-top: var(--el9-2);
}

.el9-img-strip.is-scrollable .el9-img-strip-dots {
    display: flex;
}

.el9-img-strip-dots button {
    width: 6px;
    height: 6px;
    padding: 0;
    border: 0;
    border-radius: var(--el9-r-full);
    background: var(--el9-border);
    cursor: pointer;
    transition: background var(--el9-dur) var(--el9-ease), width var(--el9-dur) var(--el9-ease);
}

.el9-img-strip-dots button.is-active {
    width: 14px;
    background: var(--el9-accent);
}

/* ---- 灯箱 ---- */

.el9-lightbox {
    position: fixed;
    inset: 0;
    z-index: 200;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--el9-4);
    background: rgba(0, 0, 0, .9);
    cursor: zoom-out;
    opacity: 0;
    pointer-events: none;
    transition: opacity 200ms var(--el9-ease);
}

.el9-lightbox.is-open {
    opacity: 1;
    pointer-events: auto;
}

/*
 * 图片外面这层接手势（双指缩放、拖动、横滑切图）。
 *
 * touch-action: none 是必需的 —— 不关掉的话双指一捏，浏览器缩的是整个网页；
 * 手机上还会顺手触发下拉刷新。
 */
.el9-lightbox-stage {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    touch-action: none;
}

.el9-lightbox img {
    /* 边距由 .el9-lightbox 的 padding 给，这里跟着 stage 走 */
    max-width: 100%;
    max-height: 100%;
    border-radius: var(--el9-r-md);
    box-shadow: 0 12px 48px rgba(0, 0, 0, .5);
    transform-origin: center center;
    will-change: transform;
    user-select: none;
    -webkit-user-drag: none;
}

/*
 * 过渡只加在「松手回弹」「双击放大」这些需要看效果的时刻（JS 加 is-anim）。
 * 拖动过程中不能有过渡，否则图会慢半拍跟着手指。
 */
.el9-lightbox img.is-anim {
    transition: transform .22s var(--el9-ease);
}

.el9-lightbox-btn {
    position: absolute;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 0;
    /*
     * 形状、常显透明度跟轮播 / 说说横滑条那两处翻页钮统一。
     * 只有底色不一样 —— 灯箱底下是一整块黑，用同一套深色底等于没有按钮。
     */
    border-radius: var(--el9-r-full);
    background: rgba(255, 255, 255, .12);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    color: #fff;
    opacity: .8;
    cursor: pointer;
    transition: background var(--el9-dur) var(--el9-ease), transform var(--el9-dur) var(--el9-ease),
        opacity var(--el9-dur) var(--el9-ease);
}

.el9-lightbox-btn:hover {
    background: rgba(255, 255, 255, .24);
    opacity: 1;
}

.el9-lightbox-close {
    top: var(--el9-4);
    right: var(--el9-4);
}

.el9-lightbox-prev,
.el9-lightbox-next {
    top: 50%;
    transform: translateY(-50%);
}

.el9-lightbox-prev {
    left: var(--el9-4);
}

.el9-lightbox-next {
    right: var(--el9-4);
}

/* 放大看细节时，左右箭头挡在图中间纯属碍事 —— 先让开，缩回去再露面 */
.el9-lightbox.is-zoomed .el9-lightbox-prev,
.el9-lightbox.is-zoomed .el9-lightbox-next {
    opacity: 0;
    pointer-events: none;
}

.el9-lightbox.is-single .el9-lightbox-prev,
.el9-lightbox.is-single .el9-lightbox-next,
.el9-lightbox.is-single .el9-lightbox-count {
    display: none;
}

.el9-lightbox-count {
    position: absolute;
    left: 50%;
    bottom: var(--el9-5);
    transform: translateX(-50%);
    padding: 4px 12px;
    border-radius: var(--el9-r-full);
    background: rgba(255, 255, 255, .12);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    color: #fff;
    font-size: 13px;
    font-variant-numeric: tabular-nums;
}

@media screen and (max-width: 600px) {
    .el9-lightbox-prev {
        left: var(--el9-2);
    }

    .el9-lightbox-next {
        right: var(--el9-2);
    }
}

.el9-code-copy {
    position: absolute;
    top: var(--el9-2);
    right: var(--el9-2);
    height: 28px;
    padding: 0 var(--el9-3);
    border-radius: var(--el9-r-sm);
    background: var(--el9-bg);
    border: 1px solid var(--el9-border);
    color: var(--el9-text-2);
    font-size: 12px;
    font-weight: 600;
    opacity: 0;
    transition: opacity var(--el9-dur) var(--el9-ease), color var(--el9-dur) var(--el9-ease);
}

.el9-content pre:hover .el9-code-copy,
.el9-code-copy:focus-visible {
    opacity: 1;
}

.el9-code-copy:hover {
    color: var(--el9-accent);
}

/* ==========================================================================
   8. 评论
   ========================================================================== */

/*
 * 评论区的左右留白必须跟正文、上下篇一样（基础 16px，窄屏由下面媒体查询统一改小）。
 * 原来这里是 0 —— 评论框比正文多外突 16px，PC 上看就是「评论没跟正文对齐」。
 */
.el9-comments {
    padding: var(--el9-4) 0 var(--el9-2);
    border-top: 1px solid var(--el9-border);
}

/* ---- 被拿掉的链接（占位符）----
 *
 * 两类链接在评论区会被换成这块：
 *   1. 站长拉黑过的域名；
 *   2. 匿名访客（「神秘人」）留言里的所有外链。
 *
 * 为什么不保留原网址：网址本身就是那条评论想推的东西，留着等于半推半就；
 * 但也不能凭空消失，所以留一个占位符 —— 读者知道这儿原来有个链接，
 * 点一下能看为什么被拿走。
 */
.el9-link-ph {
    position: relative;
    display: inline-block;
    padding: 0 6px;
    border-radius: 5px;
    background: var(--el9-bg-soft);
    color: var(--el9-text-3);
    font-size: .92em;
    line-height: 1.6;
    white-space: nowrap;
    cursor: help;
}

.el9-link-ph--blocked {
    background: rgba(192, 57, 43, .08);
    color: #a13b30;
}

.el9-link-ph--anon {
    background: var(--el9-bg-soft);
    color: var(--el9-text-3);
}

/* 说明气泡：点它（获得焦点）或悬停时出来 */
.el9-link-ph::after {
    content: attr(data-why);
    position: absolute;
    left: 0;
    bottom: calc(100% + 9px);
    z-index: 30;
    width: max-content;
    max-width: min(270px, 72vw);
    padding: 9px 12px;
    border-radius: 10px;
    border: 1px solid var(--el9-border-strong);
    background: var(--el9-bg);
    color: var(--el9-text);
    box-shadow: 0 8px 24px rgba(0, 0, 0, .1);
    font-size: 12.5px;
    font-weight: 400;
    line-height: 1.65;
    text-align: left;
    text-decoration: none;
    white-space: normal;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity var(--el9-dur) var(--el9-ease);
}

.el9-link-ph:hover::after,
.el9-link-ph:focus::after {
    opacity: 1;
    visibility: visible;
}

/*
 * 带被拉链接的评论：头像转灰、名字加虚线 —— 一眼看出这条有问题。
 * 用 :has()，不支持它的老浏览器只是少了这层视觉提示，功能不受影响。
 */
/*
 * 注意类名：评论列表里是 el9-cmt-avatar，别跟侧栏的 el9-comment-avatar 混了。
 *
 * is-blocked 由 JS 加（见 app.js），:has() 留作无 JS 时的兜底 ——
 * 实测 headless 浏览器里 :has() 这条没生效，光靠它头像不会变灰。
 *
 * 只认「自己这一条」：子回复挂在父 <li> 里面（.el9-cmt-children > ol > li），
 * 早先写成后代选择器 .el9-cmt.is-blocked .el9-cmt-avatar，会把下面所有回复的
 * 头像一起灰掉；:has() 那条也会因为孙辈里有黑名单标记反过来把父评论带灰。
 * 所以头像用直接子级 >，标记只从自己的 .el9-cmt-main 里找。
 */
.el9-cmt.is-blocked > .el9-cmt-avatar,
.el9-cmt:has(> .el9-cmt-main .el9-link-ph--blocked) > .el9-cmt-avatar,
.el9-cmt:has(> .el9-cmt-main .el9-cmt-name[data-blocked]) > .el9-cmt-avatar {
    filter: grayscale(1);
    opacity: .45;
}

.el9-comments-head {
    display: flex;
    align-items: center;
    /* 排序控件推到最右，跟左边的「N 条评论」分两头 */
    justify-content: space-between;
    gap: var(--el9-2);
    margin-bottom: var(--el9-4);
}

/* ---- 评论排序：正序 / 倒序 ----
 * 分段按钮：浅灰底上浮一个白色药丸表示当前选中。
 * 默认是 hidden，评论少于两条时 JS 不会把它放出来。
 */
.el9-cmt-order {
    display: inline-flex;
    flex: none;
    padding: 3px;
    border-radius: var(--el9-r-full);
    background: var(--el9-bg-soft);
}

/* 它是 inline-flex，[hidden] 的 display:none 会被压掉，得显式写一条 */
.el9-cmt-order[hidden] {
    display: none;
}

.el9-cmt-order button {
    padding: 5px 13px;
    border: 0;
    border-radius: var(--el9-r-full);
    background: none;
    font-size: 12.5px;
    line-height: 1.4;
    color: var(--el9-text-3);
    cursor: pointer;
    transition: background var(--el9-dur) var(--el9-ease), color var(--el9-dur) var(--el9-ease);
}

.el9-cmt-order button:hover {
    color: var(--el9-text);
}

.el9-cmt-order button.is-on {
    background: var(--el9-bg);
    color: var(--el9-text);
    box-shadow: 0 1px 3px rgba(0, 0, 0, .08);
}

.el9-comments-head .el9-icon {
    color: var(--el9-text);
}

.el9-section-title {
    display: flex;
    align-items: center;
    gap: var(--el9-2);
    margin: 0;
    font-size: 20px;
    font-weight: 800;
}

.el9-comment-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    /* 卡片之间的间距 */
    gap: var(--el9-2);
}

/* 评论卡片 */

.el9-cmt {
    display: flex;
    /* 头像和内容一律顶部对齐，不被 stretch 拉伸，拍平后每条的头像都在同一列 */
    align-items: flex-start;
    /* 子回复换行到下一行占满整宽（见 .el9-cmt-children），必须允许 wrap */
    flex-wrap: wrap;
    gap: var(--el9-3);
    /*
     * 评论改成列表行：不再一条一个卡片。
     * 上下留 18px 让每条之间有呼吸，左右保持原样（头像不贴边），
     * 条目之间用一条很淡的横线分隔（见下面的相邻选择器）。
     */
    padding: 18px var(--el9-5);
}

.el9-cmt-avatar .el9-avatar {
    display: block;
    width: 44px;
    height: 44px;
    border-radius: var(--el9-r-full);
    object-fit: cover;
}

.el9-cmt-avatar .el9-avatar--text {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 18px;
    font-weight: 700;
    color: #fff;
    background: var(--el9-accent);
    line-height: 1;
}

.el9-cmt-main {
    flex: 1;
    min-width: 0;
}

/*
 * 评论头：两行两列。
 *
 *   昵称 + 身份标                      回复
 *   时间 · 回复 @某人
 *
 * 原来全挤在一行里靠 flex-wrap 换行 —— 名字一长就把时间挤到下一行，
 * 短名字又把「回复 @某人」拽上来，同一条评论列表里每条的断行位置都不一样。
 * 改成 grid 固定成两行，谁长谁短都在自己那格待着。
 */
.el9-cmt-head {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    column-gap: var(--el9-3);
    row-gap: 3px;
}

.el9-cmt-who,
.el9-cmt-sub {
    display: flex;
    align-items: center;
    gap: var(--el9-2);
    flex-wrap: wrap;
    min-width: 0;
}

.el9-cmt-who {
    grid-column: 1;
    grid-row: 1;
}

.el9-cmt-sub {
    grid-column: 1;
    grid-row: 2;
    gap: 6px;
}

/* 「回复」跟昵称同一水平线，靠右 —— 不再是压在底部标签行末尾 */
.el9-cmt-head .el9-cmt-act {
    grid-column: 2;
    grid-row: 1;
    align-self: center;
}

.el9-cmt-name {
    font-weight: 600;
    font-size: 15px;
    color: inherit;
    text-decoration: none;
}

/*
 * 休眠链接：这个人已经很久没来留言了，他以前留的网址不再往外跳。
 *
 * 颜色压到次要文字那一档，加一条虚点下划线（表示「本来是个链接」），
 * 鼠标显示帮助光标 —— 点下去不跳转，只弹一句提示。
 * 不做成禁用灰：那样看着像坏链，这里传达的是「暂时不跳」而不是「坏了」。
 */
.el9-cmt-name.is-dormant {
    color: var(--el9-text-3);
    text-decoration: underline dotted;
    text-underline-offset: 3px;
    cursor: help;
}

.el9-cmt-name.is-dormant:hover {
    color: var(--el9-text-2);
}

.el9-cmt-badge {
    font-size: 11px;
    line-height: 1;
    padding: 3px 8px;
    border-radius: var(--el9-r-full);
    border: 1px solid var(--el9-border);
    color: var(--el9-text-2);
}

/* 好友：邮箱命中友链邮箱的评论者。用橙色跟博主的蓝色区分开 */
.el9-cmt-badge--friend {
    border-color: color-mix(in srgb, #f59e0b 40%, transparent);
    color: #b45309;
    background: color-mix(in srgb, #f59e0b 10%, transparent);
}

.el9-cmt-badge--owner {
    border-color: color-mix(in srgb, var(--el9-accent) 40%, transparent);
    color: var(--el9-accent);
    background: color-mix(in srgb, var(--el9-accent) 8%, transparent);
}

/*
 * 神秘人：点匿名按钮发的、或者没填昵称的访客。
 * 用中性灰 —— 博主是蓝、好友是橙，这个要是再抢色，「博主」就不显眼了。
 */
.el9-cmt-badge--guest {
    border-color: var(--el9-border-strong);
    color: var(--el9-text-2);
    background: var(--el9-bg-soft);
}

.el9-cmt-time a {
    font-size: 12px;
    color: var(--el9-text-3);
    text-decoration: none;
}

.el9-cmt-time a:hover {
    color: var(--el9-accent);
}

/* 评论拍平后，这条「回复 @某人」是判断层级关系的唯一线索，
   给它一点主题色，扫一眼就能看出在回复谁 */
.el9-cmt-replyto {
    font-size: 12px;
    font-weight: 500;
    color: var(--el9-accent-text);
}

.el9-cmt-pending {
    margin: var(--el9-2) 0 0;
    font-size: 12px;
    color: #d97706;
}

/*
 * 正文和底部标签行都顶到「头像的左边缘」，昵称和时间留在头像右侧。
 *
 * 这是这套版式的关键：内容不能缩在头像后面。缩进去的话，每条评论的正文
 * 都从头像宽 + 栏间距那儿起笔，一屏看下来左边缘参差不齐，而且正文可用宽度
 * 白白少 56px —— 短句刚够换行的地方被挤成两行。
 *
 * 负 margin 的数值正好等于「头像 44 + 栏间距 12」，所以左边顶到 li 的内边缘为止，
 * 右边靠 width 同步加回来，不会溢出卡片。头像尺寸或间距改了，这里跟着走。
 */
.el9-cmt-text,
.el9-cmt-meta {
    margin-left: calc(-1 * (44px + var(--el9-3)));
    width: calc(100% + 44px + var(--el9-3));
}

.el9-cmt-text {
    margin-top: var(--el9-2);
    font-size: 14.5px;
    line-height: 1.7;
    color: var(--el9-text);
    overflow-wrap: break-word;
}

.el9-cmt-text p {
    margin: 0 0 var(--el9-2);
}

.el9-cmt-text p:last-child {
    margin-bottom: 0;
}

.el9-cmt-meta {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: var(--el9-3);
    flex-wrap: wrap;
    /* 左边顶到头像左边缘 —— 跟正文用同一条规则，见上面的 .el9-cmt-text 那段 */
}

.el9-cmt-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 11px;
    line-height: 1;
    padding: 4px 9px;
    border-radius: var(--el9-r-full);
    border: 1px solid var(--el9-border);
    color: var(--el9-text-3);
    background: var(--el9-bg);
}

.el9-cmt-chip .el9-icon {
    color: var(--el9-accent);
}

.el9-cmt-act {
    /* 位置交给 .el9-cmt-head 的 grid 定，这里不再自己顶到行尾 */
    white-space: nowrap;
}

.el9-cmt-act a {
    font-size: 12px;
    color: var(--el9-text-3);
    text-decoration: none;
}

.el9-cmt-act a:hover {
    color: var(--el9-accent);
}

/* 子评论：左竖线缩进 */

.el9-cmt-children {
    /*
     * 子回复：换行到评论下方、占满整宽，不再缩进。
     * 它在 <li> 的直接子级，父级 .el9-cmt 是 flex-wrap，
     * flex: 0 0 100% 让它独占一行，起点和顶层评论的头像对齐。
     * 层级关系只靠每条的「回复 @某人」表达。
     */
    flex: 0 0 100%;
    width: 100%;
    margin-top: 0;   /* 换行后的间距交给父级 .el9-cmt 的 gap，不然会翻倍 */
    margin-left: 0;
    padding-left: 0;
    border-left: 0;
    display: flex;
    flex-direction: column;
    gap: var(--el9-4);
}

.el9-cmt-children .el9-comment-list {
    gap: var(--el9-4);
}

/*
 * 一个顶层评论 + 它下面所有回复 = 一个对话 = 一张卡片。
 * 顶层评论不带 --child，回复都带 —— 所以这里只给顶层套卡片外观，
 * 回复在卡片内部保持透明（见下面的 --child 规则），靠缩进和留白分层。
 */
.el9-cmt:not(.el9-cmt--child) {
    background: var(--el9-bg);
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-lg);
    padding: 16px 18px;
}

/*
 * 子回复：去掉卡片外观和内边距，视觉上跟顶层完全同构。
 * 用双类提高权重 —— 只写 .el9-cmt--child 的话，
 * 后面 @media 里的 .el9-cmt { padding: ... } 会把它覆盖掉
 * （同一个 li 同时匹配这两个选择器，后写的赢），
 * 结果手机上子回复凭空多出一圈内边距，看着像缩进了。
 */
.el9-cmt.el9-cmt--child {
    /*
     * 子回复：同一个对话内部，不画分隔线，只靠上下留白把层次拉开。
     * 左右保持 0（它已经在父评论的内边距里，再给就缩进了）。
     */
    border: 0;
    padding: 14px 0 0;
    background: transparent;
}

/* 拍平后子评论和顶层完全同构，头像尺寸也跟着统一 */

/* 回复时被挪进评论里的发布框 */

.el9-cmt .el9-respond {
    /*
     * 必须独占一行。
     *
     * .el9-cmt 是 flex-wrap 容器，子元素依次是「头像 44px / 内容 / 子回复」。
     * 表单被挪进来时如果没有这条，它会被当成下一个 flex item 排到头像右边 ——
     * 结果就是输入框左边空出 56px（头像列 + gap），右边一路顶到卡片边缘，
     * 窄屏上看着就像「莫名其妙缩进了一大块」，底下的按钮也跟着被挤散。
     */
    flex: 0 0 100%;
    /* 上下间距交给 .el9-cmt 的 gap，别再叠一层 12px */
    margin: 0;
}

/* 评论表单 */

/*
 * 蜜罐字段：挪出视口，不要用 display:none ——
 * 有些脚本会跳过所有隐藏的输入框，那样就白设了。
 * 用「看得见但不在屏幕上」的写法，脚本照填不误。
 */
.el9-hp {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

/*
 * 评论框保持「输入框自己带边框」的样子，不做卡片化。
 *
 * 唯一动过的是字号：一律 16px —— iOS Safari 对 font-size < 16px 的输入框，
 * 聚焦时会强制放大整个页面。原来 .el9-respond-fields .el9-input 写 13.5px，
 * 权重比媒体查询里那条 16px 补丁高，补丁一直没生效。
 */
.el9-respond {
    margin: 0 0 var(--el9-5);
}

.el9-respond .el9-textarea {
    width: 100%;
    min-height: 120px;
    padding: var(--el9-3) var(--el9-4);
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-lg);
    background: var(--el9-bg-soft);
    font: inherit;
    font-size: 16px;
    line-height: 1.6;
    color: var(--el9-text);
    resize: vertical;
    transition: border-color var(--el9-dur) var(--el9-ease), box-shadow var(--el9-dur) var(--el9-ease);
}

.el9-respond .el9-textarea:focus {
    outline: none;
    border-color: var(--el9-accent);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--el9-accent) 18%, transparent);
}

.el9-respond-fields {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--el9-2);
    margin-top: var(--el9-2);
}

.el9-respond-fields .el9-input {
    width: 100%;
    padding: 9px var(--el9-3);
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-md);
    background: var(--el9-bg-soft);
    font: inherit;
    font-size: 16px;
    color: var(--el9-text);
    transition: border-color var(--el9-dur) var(--el9-ease);
}

.el9-respond-fields .el9-input:focus {
    outline: none;
    border-color: var(--el9-accent);
}

.el9-respond-fields[hidden] {
    display: none;
}

/* ---- 昵称/邮箱面板：手机从底部弹出，跟「发布说说」同一套手感 ---- */
.el9-fieldbox {
    position: fixed;
    inset: 0;
    z-index: 220;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 6vh var(--el9-4);
}

.el9-fieldbox[hidden] {
    display: none;
}

.el9-fieldbox-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(16, 24, 40, .42);
    -webkit-backdrop-filter: blur(2px);
    backdrop-filter: blur(2px);
}

.el9-fieldbox-inner {
    position: relative;
    z-index: 1;
    width: 100%;
    max-width: 420px;
    padding: var(--el9-4);
    border-radius: var(--el9-r-lg);
    background: var(--el9-bg);
    box-shadow: 0 24px 60px rgba(16, 24, 40, .18);
}

.el9-fieldbox-head {
    display: flex;
    align-items: center;
    gap: var(--el9-3);
    margin-bottom: var(--el9-2);
}

.el9-fieldbox-title {
    font-size: 15px;
    font-weight: 600;
    color: var(--el9-text);
}

.el9-fieldbox-close {
    margin-left: auto;
    padding: 4px 10px;
    border: 0;
    border-radius: var(--el9-r-full);
    background: transparent;
    color: var(--el9-text-2);
    font: inherit;
    font-size: 13px;
    cursor: pointer;
}

.el9-fieldbox-close:hover {
    background: var(--el9-bg-hover);
    color: var(--el9-text);
}

.el9-fieldbox-tip {
    margin: 0 0 var(--el9-3);
    font-size: 12.5px;
    line-height: 1.6;
    color: var(--el9-text-3);
}

/* 面板里三个字段一律竖排，别挤成三列 */
.el9-fieldbox .el9-respond-fields {
    grid-template-columns: 1fr;
}

.el9-fieldbox-done {
    width: 100%;
    margin-top: var(--el9-4);
}

/* 面板打开时锁住页面滚动 */
body.is-fieldbox-open {
    overflow: hidden;
}

/* 手机：从底部上滑 */
@media screen and (max-width: 699px) {
    .el9-fieldbox {
        align-items: flex-end;
        padding: 0;
    }

    .el9-fieldbox-inner {
        max-width: none;
        padding-bottom: calc(var(--el9-4) + env(safe-area-inset-bottom, 0px));
        border-radius: var(--el9-r-lg) var(--el9-r-lg) 0 0;
    }
}

/*
 * 宽屏：这个壳降级成透明容器 —— 桌面不为了三个输入框弹窗，
 * 字段照旧就地展开（显隐由按钮控制），三列并排。
 */
@media screen and (min-width: 700px), print {
    .el9-fieldbox {
        position: static;
        display: block;
        padding: 0;
    }

    .el9-fieldbox-backdrop,
    .el9-fieldbox-head,
    .el9-fieldbox-tip,
    .el9-fieldbox-done {
        display: none;
    }

    .el9-fieldbox-inner {
        max-width: none;
        padding: 0;
        border-radius: 0;
        background: transparent;
        box-shadow: none;
    }

    .el9-fieldbox .el9-respond-fields {
        grid-template-columns: repeat(3, 1fr);
    }
}

/*
 * 「填写昵称和邮箱」/「匿名」跟「发表评论」并排站一行，高度必须一样
 * （原来是 34 vs 40，看着像没对齐）。
 */
.el9-anon-btn {
    height: 40px;
    padding: 0 var(--el9-4);
    font-size: 13px;
    font-weight: 500;
    /*
     * 跟着后台主题色走。
     *
     * 原来这颗是灰字灰框，旁边「发表评论」是实心主题色 —— 一个彩色一个中性，
     * 后台改主题色时只有一半跟着变，看着像两套配色。
     *
     * 现在改成同色系的主次两级：实心 / 描边，而不是彩色 / 灰色。
     * 文字用 accent-text 而不是 accent —— 13px 属于正文级小字，要 4.5:1，
     * accent 原色在白底只有 3:1，压暗过的 accent-text 才够（5.01:1）。
     */
    border-color: color-mix(in srgb, var(--el9-accent) 42%, transparent);
    color: var(--el9-accent-text);
}

.el9-anon-btn:hover {
    border-color: var(--el9-accent);
    color: var(--el9-accent-text);
    background: color-mix(in srgb, var(--el9-accent) 8%, transparent);
}

/*
 * 身份行：压在输入框内部的右下角，跟左下角的表情 / 私密同一条底带。
 * 单独占一行摆在框外面，会让整个表单看着像「还差一块没填完」。
 */
.el9-respond-user {
    position: absolute;
    right: 12px;
    bottom: 10px;
    margin: 0;
    font-size: 12px;
    line-height: 1.4;
    color: var(--el9-text-3);
    z-index: 1;
}

.el9-respond-user a {
    color: var(--el9-accent);
    text-decoration: none;
}

/* 回复框里不再放头像（0.5.18），输入框直接占满整行 */
.el9-respond-main {
    display: flex;
    align-items: flex-start;
}

.el9-respond-main .el9-textarea {
    flex: 1;
    min-width: 0;
}

.el9-respond-foot {
    display: flex;
    align-items: center;
    /* 「取消回复」占满一行（flex-basis 100%），不允许 wrap 的话它会把旁边两颗挤扁 */
    flex-wrap: wrap;
    gap: var(--el9-3);
    margin-top: var(--el9-2);
}

/*
 * 发表评论按钮（纸飞机 + 文字）
 *
 * 这里原来挂着一整套 hover 动效：纸飞机往右上飞出去、转 45°、上下扇动，
 * 文字跟着滑出右边（靠 overflow: hidden 把飞出去的部分裁掉）。
 * 老卢 2026-10-25 要求取消 —— 这套主题整体走「去动效」路线，按钮抖一下反而跳。
 * 现在悬停只把底色压暗一档，没有任何位移和缩放，触摸设备也没有落差。
 */
.el9-submit {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    height: 40px;
    padding: 0 18px 0 15px;
    border: 0;
    border-radius: var(--el9-r-full);
    /*
     * 底色用 accent，不是 accent-strong —— 后者是压暗过的，跟后台设的主题色对不上。
     * 白字压在 accent 上是 3.1:1，但 15px/600 算「大文本」，门槛是 3:1，达标。
     */
    background: var(--el9-accent);
    color: var(--el9-accent-contrast);
    font-family: inherit;
    font-size: 15px;
    font-weight: 600;
    cursor: pointer;
    overflow: hidden;
    transition: filter var(--el9-dur) var(--el9-ease);
}

/* 悬停只压暗一档，不做任何位移 */
.el9-submit:hover {
    filter: brightness(.93);
}

.el9-submit-ico {
    display: flex;
    flex: none;
}

.el9-submit-ico svg {
    display: block;
}

/* 系统开了「减弱动态效果」：连底色变化也省掉 */
@media (prefers-reduced-motion: reduce) {
    .el9-submit {
        transition: none;
    }
}

.el9-respond-actions {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: var(--el9-3);
}

/* 「取消回复」只在回复某条评论时才露出来（app.js 里加 / 摘 is-on），
   平时没有回复对象，摆着只会让人以为按了会清空输入框 */
.el9-cancel-reply {
    display: none;
}

.el9-cancel-reply.is-on {
    display: flex;
    /* 独占一行：它是「退出回复」，跟「发表评论」挨着放太容易误点 */
    flex: 0 0 100%;
    margin: 0 0 2px;
}

.el9-cancel-reply a {
    font-size: 13px;
    color: var(--el9-text-3);
    text-decoration: none;
}

.el9-cancel-reply a:hover {
    color: var(--el9-accent);
}

.el9-comments-closed {
    padding: var(--el9-4) 0;
    color: var(--el9-text-2);
    font-size: 15px;
}

.el9-comment-pager {
    margin-top: var(--el9-4);
    font-size: 14px;
}

.el9-comment-pager a {
    color: var(--el9-accent);
    text-decoration: none;
    font-weight: 600;
}
/* ==========================================================================
   9. 空状态 / 404
   ========================================================================== */

/* ---- 搜索结果头部 ----
   只解决「我在搜什么、有多少条、怎么换词」这三件事，别再加装饰。
   样式跟列表卡片同源：同样的描边、圆角、底色。 */
/*
 * 搜索页头部：不做成卡片，就是一条细线 ——
 * 下面紧跟着结果列表，再套一层框会显得两块东西在抢。
 */
.el9-searchhead {
    display: flex;
    align-items: center;
    gap: var(--el9-3);
    position: relative;
    margin-bottom: var(--el9-2);
    padding: 0 0 var(--el9-3);
    border-bottom: 1px solid var(--el9-border);
}

.el9-searchhead-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    color: var(--el9-text-3);
}

/* 「搜索」两个字是给屏幕阅读器和老浏览器留的语义，视觉上不占位置 */
.el9-searchhead-label {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* min-width: 0 是必须的：flex 子项默认 min-width:auto，
   关键词很长时会把右边那一组挤出去，而不是自己省略 */
.el9-searchhead-main {
    flex: 1 1 auto;
    min-width: 0;
}

.el9-searchhead-label {
    margin: 0;
    color: var(--el9-text-3);
    font-size: 12px;
    line-height: 1.5;
}

.el9-searchhead-word {
    margin: 0;
    color: var(--el9-text);
    font-size: 18px;
    font-weight: 650;
    line-height: 1.45;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.el9-searchhead-side {
    display: flex;
    align-items: center;
    gap: var(--el9-3);
    flex: 0 0 auto;
}

.el9-searchhead-count {
    color: var(--el9-text-3);
    font-size: 13px;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.el9-searchhead-again {
    height: 32px;
    padding: 0 var(--el9-3);
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-full);
    background: transparent;
    color: var(--el9-text-2);
    font-family: inherit;
    font-size: 13px;
    white-space: nowrap;
    cursor: pointer;
    transition: border-color var(--el9-dur) var(--el9-ease),
        background var(--el9-dur) var(--el9-ease),
        color var(--el9-dur) var(--el9-ease);
}

.el9-searchhead-again:hover {
    border-color: var(--el9-border-strong);
    background: var(--el9-bg-soft);
    color: var(--el9-text);
}

/* ---- 搜索结果的版式：一律线条，不加框 ---- */

/* 搜索页那一行「包含关键字 X 的文章」和上面的头部重复，藏掉；搜索框留着 */
.is-search .el9-feedbar-title {
    display: none;
}

/* 命中的词标一下。底色克制，只做定位用，不做高亮块 */
.el9-hl {
    padding: 0 1px;
    border-radius: 2px;
    background: rgba(255, 205, 60, .42);
    color: inherit;
}


/*
 * 结果条目：一张张只有线条的卡片，条与条之间留缝。
 *
 * 和首页信息流刻意不一样 —— 那边是通栏细线（连续时间线），
 * 这边一条一个框（待挑选的清单）。全是线条，不加底色和阴影。
 */
.is-search .el9-feed {
    gap: var(--el9-3);
    padding-top: var(--el9-3);
}

.is-search .el9-feed .el9-card {
    padding: var(--el9-4) var(--el9-5);
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-md);
    background: var(--el9-bg);
    transition: border-color var(--el9-dur) var(--el9-ease);
}

.is-search .el9-feed .el9-card:last-child {
    border-bottom: 1px solid var(--el9-border);
}

.is-search .el9-feed .el9-card:hover {
    border-color: var(--el9-border-strong);
}

/* 出处那一行（分类 / 时间）：比正文小一号，颜色退到第三级 */
.is-search .el9-card-sub {
    font-size: 12px;
    color: var(--el9-text-3);
}

/* 结果标题比首页卡片略小一点，一屏能多一条 */
.is-search .el9-card.is-compact .el9-card-title {
    margin-bottom: 3px;
    font-size: 16px;
    font-weight: 600;
    line-height: 1.5;
}

.is-search .el9-card.is-compact .el9-card-text {
    color: var(--el9-text-2);
    line-height: 1.65;
}

.el9-empty {
    padding: 64px var(--el9-5);
    text-align: center;
}

.el9-empty--404 {
    padding-top: 96px;
}

.el9-404-code {
    font-size: 64px;
    font-weight: 800;
    letter-spacing: -.04em;
    color: var(--el9-accent);
    line-height: 1;
}

.el9-empty-title {
    margin-top: var(--el9-3);
    font-size: 23px;
    font-weight: 800;
}

.el9-empty-text {
    margin-top: var(--el9-2);
    color: var(--el9-text-2);
    font-size: 15px;
}

.el9-empty .el9-btn {
    margin-top: var(--el9-5);
}

/* ==========================================================================
   10. 响应式
   ========================================================================== */

@media screen and (max-width: 1200px) {
    /*
     * 信息流通栏列表：卡片占满整宽、去边框圆角、条目之间用细线分隔。
     * 放在 1200 而不是 999/699 —— 只要不是大屏桌面就一律通栏，
     * 免得设备实际视口落在两个断点之间时「怎么改都不生效」。
     */
    :root {
        --el9-main-pad: 0;
    }

    .el9-feed {
        gap: 0;
    }

    .el9-card {
        padding: 12px;
        border: 0;
        border-bottom: 1px solid var(--el9-border);
        border-radius: 0;
        background: transparent;
    }

    .el9-card:last-child {
        border-bottom: 0;
    }

    .el9-card:hover {
        border-color: transparent;
        border-bottom-color: var(--el9-border);
    }

    /*
     * 窄屏正文不限行宽：所有块级子元素统一铺满。
     * 之前只对 p/ul/ol 等一部分元素放开，漏了 h1（基础规则里它有 40em 上限），
     * 结果标题比正文窄一截，看着参差不齐。
     * 窄屏容器本来就不宽，一行 30~40 字，不需要再限宽。
     */
    /*
     * 解除正文行宽限制。
     * 必须用跟基础区完全一样的选择器列表，并且加 !important：
     * 基础区写的是 `.el9-content > p`（权重 0,1,1），
     * 之前这里图省事写成 `.el9-content > *`（0,1,0）——权重更低，根本没覆盖掉，
     * 所以手机上正文右侧一直空着一块，怎么调都没变化。
     */
    .el9-content > p,
    .el9-content > h1,
    .el9-content > h2,
    .el9-content > h3,
    .el9-content > h4,
    .el9-content > h5,
    .el9-content > h6,
    .el9-content > ul,
    .el9-content > ol,
    .el9-content > blockquote,
    .el9-content > .el9-callout,
    .el9-content > .el9-fold,
    .el9-content > pre,
    .el9-content > .el9-table-wrap,
    .el9-content > figure,
    .el9-content > .el9-img-grid,
    .el9-content > .el9-img-strip,
    .el9-content > .el9-secret {
        max-width: 100% !important;
    }

    /*
     * 说说时间线整套跟着左移，三个位置必须一起算，否则线、点、头像会各走各的：
     *   头像左边缘 = 4px 内边距，头像 44px → 中心 26px
     *   竖线 left   = 26 - 1（线宽 2px 的一半）= 25px
     *   蓝点 left   = 26 - 6（点直径 12px 的一半）= 20px
     *   日期文字    = 26 + 10 = 36px（在点右侧留 10px）
     * 上一版就是漏改了蓝点（还停在 34px），所以看着「有一点位移」。
     */
    .el9-feed--timeline .el9-card {
        padding-left: 4px;
    }

    .el9-feed--timeline::before {
        left: 25px;
    }

    .el9-timeline-sep::before {
        left: 20px;
    }

    .el9-timeline-sep {
        padding-left: 36px;
    }

    /*
     * 兜底强制贴边。
     * 前面已经按常规层叠把 padding 设成 0 / 4px，但如果还有别的规则
     * （不同断点、更高权重变体、第三方样式）在覆盖，视觉上就会「怎么改都不动」。
     * 这里用 !important 一次性压住，只针对左右，不影响上下间距。
     */
    .el9-main {
        padding-left: 0 !important;
        padding-right: 0 !important;
        /*
         * 顶部也归零：手机上没有顶部导航条，轮播/信息流应该直接顶到屏幕上沿。
         * 原来留了 8px，轮播上方看着就有一条白带。
         * 文章页不受影响 —— 正文容器的 .el9-article 自带 8px 上内边距。
         */
        padding-top: 0 !important;
    }

    .el9-card {
        padding-left: 4px !important;
        padding-right: 4px !important;
    }

    /*
     * 负 margin 要跟着卡片内边距一起收。
     * 动作按钮和侧栏列表原本用 -8px 负 margin 抵消自己的 8px 内边距，
     * 好让文字贴齐卡片边缘；但卡片左右现在只剩 4px，-8px 会顶出去 4px，
     * 于是整页多出一条横向滚动条。这里统一收到 -4px。
     */
    .el9-act {
        margin-left: -4px;
    }

    /*
     * 🔴 上面那条 `.el9-act`（0,1,0）写在 .el9-act--more 的 `margin-left: auto` 后面，
     * 权重相同 → 后写的赢，把「阅读全文」的靠右挤掉了，手机上它会贴着分享图标。
     * 下面两条必须留着，把语义还回去：分享是正方形按钮不吃负 margin，
     * 阅读全文靠 margin-left:auto 顶到右端。
     */
    .el9-act--share {
        margin-left: 0;
    }

    .el9-act--more {
        margin-left: auto;
        /* 跟宽屏同一套：左右留白对称，盒子再往右顶 8px 让箭头贴住右边缘 */
        margin-right: -8px;
        padding-right: 8px;
    }

    .el9-list {
        margin-left: -4px;
        margin-right: -4px;
    }

    /*
     * 这里原来有一条「正文里带背景的块（目录 / 提示框）通栏」的规则：
     * 负 margin 各 -16px，把背景铺到屏幕边、去掉圆角和左右描边。
     *
     * 现在不能这么干了 —— 所有块都跟正文同宽（max-width: 100%），
     * 负 margin 只会把卡片整体左移 16px：左边顶出容器、右边缩回 32px，
     * 右边缘就跟段落对不上。要保持「块和文字一条共同边界」，
     * 就让它们老老实实待在内容区里，靠圆角和描边区分。
     */

    /*
     * 网格卡片归档改成 CSS Grid。
     * 原来用 flex + margin：容器有 -8px 负 margin（卡片贴屏幕边），
     * 每张卡又各带 8px margin → 左右贴边、中间却空 16px，很难看。
     * Grid 用 gap 统一管间距，容器不再需要负 margin。
     */
    .el9-grid-feed {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: var(--el9-2);
        margin: var(--el9-2) 0 0;
    }

    .el9-grid-card {
        width: auto;
        margin: 0;
    }

    /*
     * 文章页三块（正文容器 / 上下篇 / 评论）共用同一层左右留白。
     *
     * 原来上下篇是「撑满不跟着正文留边」、评论压根没有左右 padding，
     * 结果手机上这两个块直接贴屏幕边（量出来 left=0），只有正文有 16px，
     * 三块参差、评论的输入框和按钮还紧贴着边。
     *
     * 留白只做在这一层：主栏（.el9-main）在窄屏归零，别叠两层。
     */
    .is-post .el9-article,
    .is-page .el9-article,
    .is-post .el9-near,
    .is-post .el9-comments,
    .is-page .el9-comments {
        padding-left: 0;
        padding-right: 0;
    }
/*
 * iOS Safari 对 font-size < 16px 的输入框，聚焦时会强制放大整个页面。
 * 这是移动端最烦人的体验问题之一（点一下评论框，页面「跳大」）。
 * 触屏设备统一 16px，桌面保持 15px 不动。
 */
.el9-textarea,
.el9-composer textarea,
.el9-respond .el9-textarea,
.el9-searchbox input,
.el9-respond input {
    font-size: 16px;
}

/*
 * 通栏列表的条目上下留白：12 → 14。
 * 条目之间只靠一条细线分隔，12px 会让相邻两条挤在一起。
 */
.el9-card {
    padding: 14px 4px;
}
}

@media screen and (max-width: 1149px) {
    .el9-shell {
        /* 跟桌面同一个量：四周留白不按断点分档，换设备才不会「一半 16 一半 12」 */
        padding: 0 var(--el9-bleed);
    }
}

@media screen and (max-width: 1099px) {
    :root {
        /* iPad 这一档（1000–1099）主栏左右 padding 归零，
           缝沿用 1200 断点那套「12 + 竖线 + 12」 */
        --el9-side-w: 264px;
        --el9-main-pad: 0;
    }

    /*
     * 文章页 / 独立页的左右留白只做一层，见上面 1200 断点里那段
     * （.el9-article / .el9-near / .el9-comments 统一 20px）。
     * 主栏必须归零，否则两层叠起来变成 36px，比桌面还宽。
     */
    .is-post .el9-main,
    .is-page .el9-main,
    .is-404 .el9-main {
        padding-left: 0;
        padding-right: 0;
    }
}

@media screen and (max-width: 999px) {
    /*
     * 窄屏：顶部那条站点导航整条收起，导航交给底部栏 + 抽屉。
     *
     * 所以「发布」入口不能只挂在站点导航里 —— 它在手机端会跟着一起消失。
     * 手机端的入口是底部栏那一项（footer.php 里的 #composer / 默认项「发布」），
     * 跟搜索一样唤起同一个弹层。改这块之前先想清楚移动端从哪里点得到。
     */

    /* 侧栏那个搜索框在窄屏收掉：顶部导航条上已经有搜索图标了，
       抽屉里再放一个既重复又占地方 */
    .el9-rail .el9-search,
    .el9-search--bar {
        display: none;
    }

    /*
     * 触摸目标补齐 44px：这些控件视觉上只有 32~40px，
     * 手指点不准。用透明伪元素把可点区域撑到 44，外观不变。
     */
    .el9-act::after,
    .el9-nav-mini::after,
    .el9-banner-tool::after,
    .el9-icon-btn::after {
        content: '';
        position: absolute;
        left: 50%;
        top: 50%;
        width: 44px;
        height: 44px;
        transform: translate(-50%, -50%);
    }

    /*
     * 手机上动作栏一行摆不下四个项，允许换行：
     * 配合 .el9-act 的 nowrap，永远不会出现「3 分 / 钟」这种断法。
     */
    .el9-card-actions {
        flex-wrap: wrap;
        row-gap: 2px;
        gap: var(--el9-2) var(--el9-3);
    }

    /*
     * 左右留白收紧：main-pad 之外卡片自己还有 24px 内边距，
     * 叠起来 40px，375px 的屏幕内容只剩 295px。
     * 卡片内边距收到 16，窄屏 main-pad 再降到 12，内容宽出约 30px。
     */

    /*
     * 评论表单的动作行手机上放不下四个元素，允许换行：
     * 「填写昵称邮箱」占一行，按钮组靠右到下一行。
     * 按钮本体锁 nowrap + flex:none，不然会被压成「匿 / 名」竖排。
     */
    /*
    /*
     * 文章页 / 独立页的左右边距要跟着一起收。
     * 这两页有自己的规则：主栏 24px + .el9-article 16px = 每侧 40px，
     * 之前只改了列表页的 main-pad 和卡片内边距，文章页一直没动，
     * 所以看文章时「怎么改都没变化」。现在跟列表页统一成 12px。
     */
    /*
     * 文章页 / 独立页要保住阅读边距：列表页通栏了，但长文贴边没法读。
     * 这里写死 12px，不跟 --el9-main-pad 走（那个已经是 0）。
     */
    /*
     * 文章页的左右留白只设一层：主栏归零，留白交给
     * .el9-article / .el9-near / .el9-comments 三个兄弟块（1200 断点里统一 20px）。
     * 之前是「主栏 16px + 文章容器 0」，而本文目录、引用块、图片这些
     * 都在文章容器里、边距算法不一样，视觉上就出现了「正文比别人窄」。
     */
    .is-post .el9-main,
    .is-page .el9-main,
    .is-404 .el9-main {
        padding-left: 0;
        padding-right: 0;
    }

    /*
     * 评论已经全端拍平了（见 .el9-cmt-children 的基础样式），
     * 这里不用再给缩进和头像做手机特调 —— 头像统一 44px 反而更整齐。
     */


    /*
     * 说说多图的左右箭头在手机上收掉：手指直接横滑就行，
     * 箭头挡在图上有 36px 的圆，反而遮内容。
     */
    .el9-img-strip-prev,
    .el9-img-strip-next {
        display: none;
    }

    /*
     * 回复框底部那排按钮：小一号、一行排开。
     *
     *   取消回复                            ← 自己占一行（见基础样式）
     *   填写昵称和邮箱 ……… 匿名 发表评论     ← 辅助的在左，两个主操作在右
     *
     * 40px 高、15px 字、满宽的蓝色大按钮在手机上像条横幅，比输入框还抢；
     * 这里统一压到 34px / 13px。昵称按钮靠 margin-right:auto 把右边那组顶过去，
     * 万一窄到换行（320 以下），右边那组也是从左边接着排，不会一边齐一边不齐。
     */
    .el9-respond-foot {
        flex-wrap: wrap;
        gap: 6px;
    }

    .el9-respond-foot > .el9-btn {
        flex: 0 0 auto;
        height: 34px;
        margin-right: auto;
        padding: 0 11px;
        font-size: 13px;
        white-space: nowrap;
    }

    .el9-cancel-reply a {
        font-size: 12.5px;
    }

    .el9-respond-actions {
        display: flex;
        align-items: center;
        gap: 6px;
        flex: 0 1 auto;
        margin-left: 0;
        min-width: 0;
    }

    /* 匿名：跟发表评论同款小尺寸，图标和文字之间留 5px */
    .el9-respond-actions .el9-btn {
        height: 34px;
        gap: 5px;
        padding: 0 10px;
        font-size: 13px;
    }

    /* 发表评论：小一号，图标和文字居中，别拉通栏 */
    .el9-respond-actions .el9-submit {
        flex: 0 0 auto;
        gap: 6px;
        height: 34px;
        padding: 0 12px 0 10px;
        font-size: 13px;
        justify-content: center;
    }

    /*
     * 手机上把层级拉开一点：
     * meta 行（名字 / 时间）降到 14，跟 15px 的正文区分开；
     * 卡片标题 19 → 18，手机上 19 有点抢。
     */
    .el9-card-head {
        font-size: 14px;
        line-height: 20px;
    }

    .el9-card-title {
        font-size: 18px;
    }

    .el9-carousel {
        margin-top: var(--el9-2);
    }

    /*
     * 位置标签的 margin-left:auto 是给「一行摆得下」时用的（推到最右）；
     * 手机上摆不下换到第二行，再右对齐就是孤零零挂在右边，改回靠左。
     */
    /*
     * 滚动钮（去底部 + 回顶部）的容器抬到底部导航之上。
     *
     * 底栏 z-index 60、最小高 52px（还要算安全区），不抬的话按钮压在导航底下点不到。
     * 数值跟原来「回顶部」那一格对齐：52 + 14 + 安全区 + 52。
     * 「菜单」悬浮钮在下面（bottom 只有 52+14），不会跟它撞。
     */
    .el9-fabs {
        bottom: calc(52px + 14px + env(safe-area-inset-bottom, 0px) + 52px);
        z-index: 55;
    }

    /*
     * 手机端顶部导航整条取消：导航走底部 tabbar 的「菜单」抽屉，
     * 顶部不再占一行，内容更早出现。
     * nav-h 归零，feedbar / 返回顶部这些吸顶位置跟着上移。
     */
    :root {
        --el9-nav-h: 0px;
    }

    /*
     * 留白收紧：桌面上 shell 左右各 24px + 主栏各 28px，手机上太占地方。
     * 这里 shell 收到 12、主栏由 --el9-main-pad 管（699 以下 12），
     * 375 的屏能多出约 24px 给内容。
     */
    /*
     * 手机端四周留白同样是 12（--el9-bleed），和桌面一个量。
     *
     * 这里原来写的是 `padding: 0` —— 那套的前提是「留白交给 main 的 padding」，
     * 但 --el9-main-pad 后来为了对齐问题被归成 0 了，两处一归零，
     * 卡片就只剩自己那 4px 内边距，看起来就是「四周的距离全没了」。
     */
    .el9-shell {
        padding: 0 var(--el9-bleed);
    }

    /*
     * 轮播通栏：占满屏幕宽（像 App 的 banner），圆角和左右描边去掉。
     *
     * 抵消的是 `.el9-shell` 那一层 12px（`--el9-bleed`），不是 `--el9-main-pad` ——
     * 后者早就是 0 了，负它等于没负，轮播两侧会各留 12，看着像「没撑满」。
     */
    .el9-carousel {
        margin-left: calc(-1 * var(--el9-bleed));
        margin-right: calc(-1 * var(--el9-bleed));
        border-left: 0;
        border-right: 0;
        border-radius: 0;
    }

    /*
     * 防横向滚动：用 clip 而不是 hidden ——
     * hidden 会让内部所有 position: sticky 失效（feedbar 就靠 sticky 吸顶）。
     * 老浏览器不认 clip 会退化成 visible，没有副作用。
     */
    body {
        overflow-x: clip;
    }

    /* 顶部站点导航在窄屏整体隐藏，里面那些针对窄屏的微调（汉堡按钮、
       邮件/RSS 收起、导航项高度）就没有意义了 —— 一并删掉，省得以后
       看着这些规则以为手机端顶部还有东西 */
    .el9-sitenav {
        display: none;
    }

    /*
     * 窄屏顶栏整条收起来了，`--el9-bleed` 那 12px 顶部留白就变成一条凭空的白边 ——
     * 轮播（或第一张卡片）本该直接顶到状态栏下面。左右留白不动。
     */
    .el9-layout {
        padding-top: 0;
    }

    .el9-icon-btn {
        position: relative;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 40px;
        height: 40px;
        border-radius: var(--el9-r-full);
        color: var(--el9-text);
        transition: background var(--el9-dur) var(--el9-ease);
    }

    .el9-icon-btn:hover {
        background: var(--el9-bg-hover);
    }

    .el9-side {
        /*
         * 手机上是抽屉：position: fixed 已经脱离文档流、不占布局位。
         * 再显式把 flex 相关尺寸归零：万一哪条规则把它留在 flex 流里，
         * 它就会顶着 300px 把主栏挤到右边，页面还能左右滑。
         */
        position: fixed;
        top: 0;
        left: 0;
        bottom: 0;
        z-index: 80;
        width: 300px;
        flex: 0 0 auto;
        min-width: 0;
        max-height: none;
        height: 100%;
        padding: var(--el9-4);
        background: var(--el9-bg);
        border-right: 1px solid var(--el9-border);
        overflow-y: auto;
        transform: translate3d(-100%, 0, 0);
        transition: transform 240ms var(--el9-ease);
        visibility: hidden;
    }

    body.is-drawer-open .el9-side {
        transform: translate3d(0, 0, 0);
        visibility: visible;
    }

    .el9-drawer-backdrop {
        display: block;
        position: fixed;
        inset: 0;
        z-index: 70;
        background: rgba(0, 0, 0, .4);
        opacity: 0;
        pointer-events: none;
        transition: opacity 240ms var(--el9-ease);
    }

    body.is-drawer-open .el9-drawer-backdrop {
        opacity: 1;
        pointer-events: auto;
    }

    .el9-tabbar {
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 60;
        display: flex;
        align-items: stretch;
        background: var(--el9-bg-blur);
        backdrop-filter: saturate(180%) blur(12px);
        -webkit-backdrop-filter: saturate(180%) blur(12px);
        border-top: 1px solid var(--el9-border);
        padding-bottom: env(safe-area-inset-bottom, 0);
    }

    .el9-tabbar-item {
        display: flex;
        flex: 1;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: 3px;
        min-height: 52px;
        color: var(--el9-text-2);
        font-size: 11px;
        font-weight: 600;
    }

    .el9-tabbar-item.is-active {
        color: var(--el9-accent);
    }

    /*
     * 左右两组各占一半（flex:1），中间那颗按钮 flex:0 0 auto ——
     * 所以不管左右各配了几项，发布按钮永远钉在正中。
     */
    .el9-tabbar-side {
        display: flex;
        flex: 1 1 0;
        min-width: 0;
    }

    /* 两组各自靠向中间，四项目时左右间距才显得均匀 */
    .el9-tabbar-side--left {
        justify-content: flex-end;
    }

    .el9-tabbar-side--right {
        justify-content: flex-start;
    }

    /*
     * 中间那颗发布按钮：圆形、凸出栏顶一截。
     *
     * margin-top 给负值把它顶上去；align-self: flex-start 是必须的 ——
     * 父级是 align-items: stretch，不写的话它会被拉成一条填满整栏。
     * 那圈边框取的是页面底色，等于在栏顶挖了个缺口，
     * 栏顶那条 1px 分隔线就不会横穿按钮。
     */
    .el9-tabbar-compose {
        position: relative;
        z-index: 1;
        display: inline-flex;
        flex: 0 0 auto;
        align-self: flex-start;
        align-items: center;
        justify-content: center;
        width: 54px;
        height: 54px;
        margin: -18px 4px 0;
        padding: 0;
        border: 3px solid var(--el9-bg);
        border-radius: var(--el9-r-full);
        /*
         * 渐变：底色是主题色，上面压一层「左上提亮 → 右下压暗」的柔光。
         *
         * 不用 --el9-accent / --el9-accent-strong 两个变量去拼渐变 ——
         * 深色模式里 strong 就等于 accent，那样渐变直接看不见了。
         * 用半透明遮罩既能保住层次，又永远跟着后台设的主题色走。
         *
         * 渐变是静态的，不动。底部常驻的东西自己在动会一直勾眼睛，
         * 之前那版 7 秒一个来回的流动就去掉了。
         */
        background-color: var(--el9-accent);
        background-image: linear-gradient(140deg,
            rgba(255, 255, 255, .26) 0%,
            rgba(255, 255, 255, 0) 46%,
            rgba(0, 0, 0, .18) 100%);
        color: #fff;
        /* 不投影：靠主题色和位置就够醒目了，底部常驻按钮带影子反而显脏 */
        cursor: pointer;
        transition: filter var(--el9-dur) var(--el9-ease);
    }

    .el9-tabbar-compose:hover {
        filter: brightness(1.08);
    }

    .el9-tabbar-compose:active {
        transform: translateY(0) scale(.96);
    }

    /* 入口关掉时的占位：宽度照占，什么都不画 */
    .el9-tabbar-compose--blank {
        background: transparent;
        border-color: transparent;
        box-shadow: none;
    }

    /*
     * 搜索头部：手机上省掉那圈图标，宽度全留给关键词和「换个词」。
     * 40px 的图标在窄屏是纯占地方，关键词反而被压成省略号。
     */
    .el9-searchhead {
        padding: var(--el9-3);
        gap: var(--el9-2);
        margin-bottom: var(--el9-2);
    }

    .el9-searchhead-icon {
        display: none;
    }

    .el9-searchhead-word {
        font-size: 16px;
    }

    .el9-searchhead-side {
        gap: var(--el9-2);
    }

    .el9-main {
        /* 顶部只留 8px（原来是 12px），轮播更靠近屏幕上沿 */
        /* 顶部留白只认 .el9-layout 那 12，这里再加 8 就成 20 了 */
        padding-top: 0;
        /*
         * 底部要给固定底栏让位：52px 是栏高，safe-area 是 iPhone 底部那条横条，
         * 再留 20px 呼吸。原来写死 72px —— 在带刘海的机型上 52+34=86 已经超过它，
         * 文章最后一屏会被底栏压住一截。
         */
        padding-bottom: calc(52px + env(safe-area-inset-bottom, 0px) + 20px);
    }

    /* feedbar 吸顶位置跟着新导航条的高度走（旧的 52px 是已删除顶栏的高度） */
    .el9-feedbar {
        top: var(--el9-nav-h);
        /*
         * 这里原来是负 margin（-12px），本来是为了抵消主栏顶部内边距让 feedbar 贴顶。
         * 但轮播挪到它上面之后，这 -12px 就把它顶到轮播底边上了，
         * 配合半透明磨砂背景，看起来就是「轮播被盖住一截」。
         * 改成正常间距，轮播和它之间留 8px。
         */
        margin-top: var(--el9-2);
    }

    /* 搜索框在窄屏隐藏（见上面 .el9-rail .el9-search 那条）——
       这里曾经有一条 display:flex 把它顶回来，是旧顶栏时代的遗留，已删 */

    /*
     * 窄屏标签栏：不再整条藏掉，改成横向滑动。
     *
     * 藏掉是旧做法 —— 手机上就没有「最新 / 说说 / 分类」这条了，只能靠菜单绕，
     * 实际上它是首页最主要的导航。分类多了放不下就让它自己滚，
     * 比「干脆不给」合理。
     *
     * 三件事缺一不可：
     *   flex-wrap: nowrap   —— 默认 flex 会换行，一换行就长成两排，滑不动
     *   overflow-x: auto    —— 真正负责滚的那句
     *   滚动条藏掉           —— 一条灰槽横在导航栏下面，比不滚还难看
     */
    .el9-feedbar--flow {
        flex-wrap: nowrap;
        overflow-x: auto;
        overflow-y: hidden;
        scrollbar-width: none;
        -webkit-overflow-scrolling: touch;
        /* 滑到头时别把整条撑出页面横向滚 */
        overscroll-behavior-x: contain;
    }

    .el9-feedbar--flow::-webkit-scrollbar {
        display: none;
    }

    /* 每个 tab 不许被压扁：默认 flex-shrink 是 1，六个字挤一挤就成竖排了 */
    .el9-feedbar .el9-tab {
        flex: 0 0 auto;
        white-space: nowrap;
    }

    /*
     * 手机端不要「最新」「说说」这两颗。
     *
     * 底部固定导航已经有「最新 / 说说 / 搜索 / 抽签」四个入口，顶部再来一遍是重复，
     * 而且它们占掉两个位置，把真正好用的分类挤出屏幕。
     * 剩下的位置全给分类，超出的横向滑。
     */
    .el9-feedbar .el9-tab--root,
    .el9-feedbar .el9-tab--talks {
        display: none;
    }

    /*
     * 分类一个都没配的话，去掉这两颗就整条空了 —— 空的导航条比不显示更难看，
     * 干脆整条收起来（桌面端不受影响，那边两颗还在）。
     */
    .el9-feedbar--flow:not(:has(.el9-tab:not(.el9-tab--root):not(.el9-tab--talks))) {
        display: none;
    }
}

@media screen and (max-width: 699px) {
    /*
     * 窄屏表格：4 列在 390 屏上每列只剩 50px 左右，「说明」「主题色」这种两字词
     * 就对半断开变竖排。真正把列吃光的是 td 左右各 16px 的内边距 —— 收到 8px，
     * 再给每列一个下限，撑不下就让 .el9-table-wrap 横向滚。
     *
     * ⚠️ 这段必须待在基础样式（.el9-content th/td）之后：同权重，后写的赢。
     */
    .el9-content table {
        font-size: 14px;
    }

    .el9-content th,
    .el9-content td {
        padding-left: var(--el9-2);
        padding-right: var(--el9-2);
        min-width: 4.2em;
    }

    :root {
        --el9-main-pad: 0;
    }

    .el9-cmt {
        padding: var(--el9-3);
        gap: var(--el9-2);
    }

    .el9-cmt-act {
        margin-left: 0;
    }

    .el9-banner-cover {
        height: 150px;
    }

    .el9-banner-avatar {
        width: 72px;
        height: 72px;
        margin-top: -36px;
    }

    .el9-banner-name strong {
        font-size: 18px;
    }

    .el9-banner-stat {
        gap: var(--el9-5);
    }

    .el9-shell {
        /* 同 ≤999 那档，四周留白不按屏幕尺寸缩水 */
        padding: 0 var(--el9-bleed);
    }

    .el9-article-title {
        font-size: 26px;
    }

    /* 窄屏卡片内边距收一档，正文能多出 8px 宽 */
    .el9-article-head {
        padding: var(--el9-4);
    }

    /*
     * 手机上的信息流改成通栏列表：卡片占满整宽、去掉圆角边框和卡片间距，
     * 条目之间只用一条细线分隔（类似 App 的列表样式）。
     * 内容左右留 12px，避免文字贴屏幕边。
     */
    .el9-feed {
        gap: 0;
    }

    .el9-card {
        /* 左右收到 8px：近乎贴边，又不会把圆头像切掉 */
        padding: 14px 4px;
        gap: var(--el9-2);
        border: 0;
        border-bottom: 1px solid var(--el9-border);
        border-radius: 0;
        background: transparent;
    }

    .el9-card:last-child {
        border-bottom: 0;
    }

    /* 触摸设备没有 hover，去掉悬停时的描边变化 */
    .el9-card:hover {
        border-color: transparent;
        border-bottom-color: var(--el9-border);
    }

    .el9-card-media {
        aspect-ratio: 4 / 3;
    }

    .el9-article-meta {
        flex-wrap: wrap;
    }

    /*
     * 手机上日期和评论数留在右侧（跟作者名同一行），不再单独换行。
     * 这样头部少一行、首屏能多露正文。
     */
    .el9-article-meta-side {
        margin-left: auto;
        flex-shrink: 0;
        font-size: 12px;
    }

    .el9-respond-fields {
        grid-template-columns: 1fr;
    }

    .el9-near-inner {
        grid-template-columns: 1fr;
    }

    .el9-near-item.is-next {
        text-align: left;
    }

    .el9-content {
        font-size: 16px;
    }

    .el9-search--wide {
        flex-direction: row;
    }
}

/* ==========================================================================
   11. 无障碍 / 打印
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
    html {
        scroll-behavior: auto;
    }

    *,
    *::before,
    *::after {
        transition-duration: .01ms !important;
        animation-duration: .01ms !important;
    }
}

@media print {
    .el9-side,
    .el9-topbar,
    .el9-tabbar,
    .el9-comments,
    .el9-feedbar,
    .el9-pager,
    .el9-loadmore,
    .el9-near {
        display: none !important;
    }

    .el9-main {
        max-width: 100%;
        border: 0;
    }

    body {
        background: #fff;
        color: #000;
    }
}


/* ==========================================================================
   表情
   ========================================================================== */

/*
 * 行内表情：跟着文字字号走。
 *
 * 写死 px 的话，正文（17px）和说说卡片（15px）里表情的大小关系是反的 ——
 * 小字配大表情，看着突兀。用 em 就是「文字多大，表情按比例多大」。
 *
 * 选择器要写到 img.el9-emoji 这个粒度：.el9-content img / .el9-card-text img
 * 那两条是给正文配图写的（margin: 1.4em auto、height: auto、还有边框和圆角），
 * 权重 (0,1,1) 比光秃秃的 .el9-emoji (0,1,0) 高 —— 不写具体点，
 * 表情会被套上 1.4em 的上下外边距，下方凭空多出一大块空白，还带个边框。
 */
.el9-emoji,
.el9-content img.el9-emoji,
.el9-card-text img.el9-emoji,
.el9-cmt-text img.el9-emoji {
    display: inline-block;
    width: auto;
    height: 1.2em;
    max-width: 2.4em;
    margin: 0 .08em;
    border: 0;
    border-radius: 0;
    vertical-align: -0.22em;
}

/* ---- 评论框左下角那颗按钮 ---- */
.el9-respond-main {
    position: relative;
}

.el9-emoji-btn {
    position: absolute;
    left: 6px;
    bottom: 6px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    border: 0;
    border-radius: var(--el9-r-full);
    background: transparent;
    color: var(--el9-text-3);
    cursor: pointer;
    transition: color var(--el9-dur) var(--el9-ease), background var(--el9-dur) var(--el9-ease);
}

.el9-emoji-btn:hover,
.el9-emoji-btn:focus-visible {
    background: var(--el9-bg-hover);
    color: var(--el9-accent);
}

/*
 * 给按钮腾出位置：不加这段，最后一行字会被那颗笑脸压住。
 * min-height 一并从 120 提到 136，内容区还是三行的样子。
 */
.el9-respond .el9-textarea {
    min-height: 136px;
    padding-bottom: 46px;
}

/* ---- 表情面板 ---- */
.el9-emojibox {
    position: fixed;
    inset: 0;
    z-index: 215;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 6vh var(--el9-4);
}

.el9-emojibox[hidden] {
    display: none;
}

.el9-emojibox-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(16, 24, 40, .42);
    -webkit-backdrop-filter: blur(2px);
    backdrop-filter: blur(2px);
}

.el9-emojibox-inner {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    width: 100%;
    max-width: 440px;
    max-height: 62vh;
    border-radius: var(--el9-r-lg);
    background: var(--el9-bg);
    box-shadow: 0 24px 60px rgba(16, 24, 40, .18);
}

.el9-emojibox-head {
    display: flex;
    align-items: center;
    gap: var(--el9-3);
    flex: none;
    padding: var(--el9-4) var(--el9-4) var(--el9-2);
}

.el9-emojibox-title {
    font-size: 15px;
    font-weight: 600;
    color: var(--el9-text);
}

.el9-emojibox-close {
    margin-left: auto;
    padding: 4px 10px;
    border: 0;
    border-radius: var(--el9-r-full);
    background: transparent;
    color: var(--el9-text-2);
    font: inherit;
    font-size: 13px;
    cursor: pointer;
}

.el9-emojibox-close:hover {
    background: var(--el9-bg-hover);
    color: var(--el9-text);
}

.el9-emojibox-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(44px, 1fr));
    gap: 2px;
    flex: 1 1 auto;
    min-height: 0;
    padding: 0 var(--el9-3) var(--el9-4);
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
}

.el9-emojibox-item {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 6px 0;
    border: 0;
    border-radius: var(--el9-r-md);
    background: transparent;
    cursor: pointer;
}

.el9-emojibox-item:hover,
.el9-emojibox-item:focus-visible {
    background: var(--el9-bg-hover);
}

.el9-emojibox-item img {
    display: block;
    width: auto;
    height: 28px;
}

/* 面板打开时锁住页面滚动 */
body.is-emojibox-open {
    overflow: hidden;
}

/* 手机：从底部滑上来，跟发布说说、昵称面板同一套手感 */
@media screen and (max-width: 699px) {
    .el9-emojibox {
        align-items: flex-end;
        padding: 0;
    }

    .el9-emojibox-inner {
        max-width: none;
        max-height: 56vh;
        border-radius: var(--el9-r-lg) var(--el9-r-lg) 0 0;
        padding-bottom: env(safe-area-inset-bottom, 0px);
    }

    .el9-emojibox-list {
        grid-template-columns: repeat(auto-fill, minmax(46px, 1fr));
    }
}

/* ==========================================================================
   「我们的故事」页面
   ========================================================================== */

/* 顶上那段招呼语：👋 + 首次相遇 + 相遇天数，再跟一个小节标题 */
.el9-myc-hi {
    margin: 0 0 var(--el9-4);
}

.el9-myc-hi-text {
    margin: 0;
    font-size: 15px;
    line-height: 1.75;
    color: var(--el9-text);
}

.el9-myc-hi strong { font-weight: 600; }

/* 挥手的那只手要跟后面的名字留一点缝，旋转的时候才蹭不上 */
.el9-myc-hi-emoji { margin-right: 3px; }

/* 「您近期在本站的消息」跟「随机文章推荐」是同一档小节标题，
   只把上边距收掉 —— 它紧跟在招呼语下面，不该有 24px 的段落间距 */
.el9-myc-sub--caption {
    margin: var(--el9-2) 0 var(--el9-3);
}

/* ---- 卡片列表 ---- */
/* 一整组装在一个框里，行与行之间靠细线分开 ——
   不再一条一个灰底块。之前那种「每条一张卡」的排法，一屏五张卡
   加上卡片自身 10px 的外间距，整页全是灰块，看不出哪几行是同一组 */
.el9-myc-list {
    margin: 0;
    padding: 0;
    list-style: none;
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-md);
    background: var(--el9-bg);
    /* 圆角裁一下，首尾行的白底才不会从角上溢出 */
    overflow: hidden;
}

.el9-myc-card {
    padding: 11px 14px;
    border: 0;
    border-radius: 0;
    background: none;
}

/* 除第一行，每条都带一条上边线 */
.el9-myc-card + .el9-myc-card {
    border-top: 1px solid var(--el9-border);
}

/* 「查看更多」收进来的卡片：显式写死，别指望浏览器对 hidden 的处理到处一致 */
.el9-myc-card[hidden] {
    display: none;
}

/* ---- 查看更多 ----
   居中一颗小胶囊。用带框的样式而不是裸文字：这是页面的操作按钮，
   跟侧栏那种「顺带一提」的入口不是一回事 */
.el9-myc-morebox {
    margin-top: var(--el9-3);
    text-align: center;
}

.el9-myc-more {
    display: inline-flex;
    align-items: baseline;
    gap: 5px;
    padding: 8px 18px;
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-full);
    background: var(--el9-bg);
    color: var(--el9-text-2);
    font-size: 12.5px;
    font-weight: 600;
    line-height: 1.4;
    cursor: pointer;
    transition: border-color .18s ease, color .18s ease, background .18s ease;
}

.el9-myc-more:hover:not(:disabled) {
    border-color: color-mix(in srgb, var(--el9-accent) 45%, var(--el9-border));
    background: color-mix(in srgb, var(--el9-accent) 6%, var(--el9-bg));
    color: var(--el9-accent-text);
}

.el9-myc-more:focus-visible {
    outline: 2px solid var(--el9-accent-text);
    outline-offset: 2px;
}

/* 到底了：别再让人点，但按钮留在原位，不然列表末尾会突然空一块 */
.el9-myc-more.is-done {
    cursor: default;
    border-style: dashed;
    color: var(--el9-text-3);
    background: none;
}

.el9-myc-more-num {
    font-weight: 400;
    font-size: 12px;
    color: var(--el9-text-3);
}

.el9-myc-card-head {
    display: flex;
    align-items: center;
    gap: 8px;
}

/* 行首图标：描边 SVG，跟主题其它图标同一套（原来是 📄 / ↗ 两个 emoji，
   在 14px 下糊成一团，颜色也不受控） */
.el9-myc-card-icon {
    flex: none;
    display: inline-flex;
    align-items: center;
    color: var(--el9-text-3);
}

.el9-myc-card-title {
    min-width: 0;
    font-size: 14.5px;
    font-weight: 600;
    color: var(--el9-text);
    text-decoration: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    transition: color var(--el9-dur) var(--el9-ease);
}

.el9-myc-card-title:hover { color: var(--el9-accent-text); }

.el9-myc-card-title.is-gone {
    font-weight: 400;
    color: var(--el9-text-3);
}

.el9-myc-card-time {
    margin-left: auto;
    flex: none;
    font-size: 12px;
    color: var(--el9-text-3);
}

/* 引文从图标那条线起（不跟标题文字对齐）—— 参考的是「图标在左、两行文字分别
   顶格」的排法，跟标题一起缩进 23px 会让第二行看着像掉进去一块 */
.el9-myc-card-quote {
    margin: 5px 0 0;
    font-size: 13px;
    line-height: 1.65;
    color: var(--el9-text-2);
    overflow-wrap: break-word;
}

.el9-myc-card-quote span { color: var(--el9-text-3); }

/* ---- 最近看过 ----
   跟评论列表共用同一套卡片，每行只有「图标 + 标题 + 时间」。
   单独一节是因为它来自 localStorage（本地），不是数据库里的东西 */
.el9-myc-hist {
    margin: 0 0 var(--el9-4);
}

/* hidden 显式写：这页的区块都带 display 相关的规则，
   一旦哪天给它加了 display，HTML 的 hidden 就会被无声盖掉 */
.el9-myc-hist[hidden] {
    display: none;
}

/* 清空按钮靠右、小字、无边框 —— 它是「顺手擦掉」的动作，
   不该长成一个跟内容抢注意力的按钮 */
.el9-myc-hist-foot {
    margin-top: var(--el9-2);
    text-align: right;
}

.el9-myc-hist-clear {
    padding: 4px 2px;
    border: 0;
    background: none;
    color: var(--el9-text-3);
    font-size: 12px;
    line-height: 1.4;
    cursor: pointer;
    transition: color var(--el9-dur) var(--el9-ease);
}

.el9-myc-hist-clear:hover {
    color: var(--el9-accent-text);
}

.el9-myc-hist-clear:focus-visible {
    outline: 2px solid var(--el9-accent-text);
    outline-offset: 2px;
}

/* 「随机文章推荐」小标题 */
.el9-myc-sub {
    margin: var(--el9-6) 0 var(--el9-3);
    font-size: 14px;
    font-weight: 600;
    color: var(--el9-text);
}

/* 只有一行标题的那种（随机文章推荐），上下比带引用的行收一点 */
.el9-myc-card--link { padding: 10px 14px; }

/* ==========================================================================
   时间线 / 计划表（[timeline] / [plan] 短代码）
   ========================================================================== */

.el9-tl,
.el9-plan {
    margin: 1.5em 0;
    padding: var(--el9-5) var(--el9-6) var(--el9-3);
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-md);
    background: var(--el9-bg);
}

.el9-tl-title,
.el9-plan-title {
    margin: 0 0 var(--el9-4);
    font-size: 15px;
    font-weight: 600;
    color: var(--el9-text);
}

/* 时间线 ------------------------------------------------------------------ */
.el9-tl-list {
    margin: 0;
    padding: 0;
    list-style: none;
}

.el9-tl-item {
    position: relative;
    display: grid;
    grid-template-columns: 84px 1fr;
    gap: var(--el9-3);
    padding: 0 0 var(--el9-5) 20px;
}

/* 节点与竖线都用伪元素：不在正文里多插节点，复制正文时也不会带上 */
.el9-tl-item::before {
    content: "";
    position: absolute;
    left: 0;
    top: 7px;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: var(--el9-accent);
}

.el9-tl-item::after {
    content: "";
    position: absolute;
    left: 4px;
    top: 21px;
    bottom: 2px;
    width: 1px;
    background: var(--el9-border-strong);
}

.el9-tl-item:last-child { padding-bottom: 2px; }
.el9-tl-item:last-child::after { display: none; }

.el9-tl-time {
    font-size: 13px;
    line-height: 1.6;
    color: var(--el9-text-3);
    font-variant-numeric: tabular-nums;
}

.el9-tl-text {
    font-size: 15px;
    line-height: 1.6;
    color: var(--el9-text);
    overflow-wrap: break-word;
}

/* 手机端两列挤不下，日期挪到内容上面一行 */
@media screen and (max-width: 699px) {
    .el9-tl-item {
        grid-template-columns: 1fr;
        gap: 2px;
    }
}

/* 计划表 ------------------------------------------------------------------ */
.el9-plan-list {
    margin: 0;
    padding: 0;
    list-style: none;
}

.el9-plan-item { margin-bottom: var(--el9-5); }
.el9-plan-item:last-child { margin-bottom: var(--el9-3); }

.el9-plan-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--el9-3);
    font-size: 15px;
}

.el9-plan-name {
    color: var(--el9-text);
    overflow-wrap: break-word;
}

.el9-plan-pct {
    flex: 0 0 auto;
    font-size: 13px;
    color: var(--el9-text-3);
    font-variant-numeric: tabular-nums;
}

.el9-plan-bar {
    height: 6px;
    margin-top: 8px;
    border-radius: 999px;
    background: var(--el9-skeleton);
    overflow: hidden;
}

.el9-plan-bar span {
    display: block;
    height: 100%;
    border-radius: 999px;
    background: var(--el9-accent);
}

.el9-plan-note {
    margin: 6px 0 0;
    font-size: 13px;
    line-height: 1.6;
    color: var(--el9-text-2);
}

/* ==========================================================================
   文章密码（Typecho 自带的 contents.password 表单）
   ========================================================================== */

.el9-content.is-locked {
    display: block;
    margin: 1.6em 0;
    padding: 40px 24px 34px;
    border: 1px solid var(--el9-border);
    border-radius: 20px;
    background:
        radial-gradient(120% 80% at 50% -20%, var(--el9-accent-soft), transparent 60%),
        var(--el9-bg);
    text-align: center;
    overflow: hidden;
}

.el9-content.is-locked .el9-lock-head {
    display: flex;
    flex-direction: column;
    align-items: center;
}

/* 正文的段落样式会渗进来，这里逐条压掉 */
.el9-content.is-locked .el9-lock-kicker,
.el9-content.is-locked .el9-lock-title,
.el9-content.is-locked .el9-lock-tip {
    margin: 0 0 8px;
    text-align: center;
}

.el9-content.is-locked .el9-lock-tip { margin-bottom: 22px; }

/* Typecho 那个表单自己带盒子和内边距，这里全撤掉，只留控件 */
.el9-content.is-locked .protected {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin: 0;
    padding: 0;
    border: 0;
    background: transparent;
    text-align: center;
}

/* 「请输入密码访问」—— 上面的标题已经说过了，藏掉 */
.el9-content.is-locked .protected .word {
    display: none;
}

.el9-content.is-locked .protected p:last-child {
    display: flex;
    gap: 8px;
    width: 100%;
    max-width: 340px;
    margin: 0;
}

@media screen and (max-width: 480px) {
    .el9-content.is-locked {
        padding: 32px 18px 26px;
        border-radius: 16px;
    }

    .el9-content.is-locked .protected p:last-child {
        flex-direction: column;
    }

    .el9-content.is-locked .protected input[type="submit"] {
        width: 100%;
        margin-left: 0;
    }
}

/* ==========================================================================
   私密评论
   ========================================================================== */

/*
 * 勾选框排在表情按钮右边，共用 textarea 底部那条 46px 的留白带。
 * 不去挤输入框的 padding-left —— 那会让每一行文字都往里缩。
 */
.el9-secret-opt {
    position: absolute;
    left: 44px;
    bottom: 6px;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    height: 32px;
    padding-right: 4px;
    font-size: 13px;
    color: var(--el9-text-3);
    cursor: pointer;
    user-select: none;
    transition: color var(--el9-dur) var(--el9-ease);
}

.el9-secret-opt:hover { color: var(--el9-text-2); }

.el9-secret-opt input[type="checkbox"] {
    width: 15px;
    height: 15px;
    margin: 0;
    accent-color: var(--el9-accent);
    cursor: pointer;
}

/* 勾上之后整块变强调色，一眼看出「这条会私密」 */
.el9-secret-opt:has(input:checked) { color: var(--el9-accent-text); }

/* 评论列表里的私密段 */
.el9-cmt-secret {
    display: flex;
    align-items: center;
    gap: 7px;
    margin: 6px 0;
    padding: 9px 12px;
    border: 1px dashed var(--el9-border-strong);
    border-radius: var(--el9-r-sm);
    background: var(--el9-bg-soft);
    font-size: 13px;
    color: var(--el9-text-2);
}

.el9-cmt-secret .el9-icon {
    flex: 0 0 auto;
    color: var(--el9-text-3);
}

/* 有权看到的人：去掉盒子，当普通正文排版 */
.el9-cmt-secret.is-open {
    display: block;
    margin: 0;
    padding: 0;
    border: 0;
    background: transparent;
    font-size: 15px;
    line-height: 1.75;
    color: var(--el9-text);
}

/* ==========================================================================
   分类密码
   ========================================================================== */

/* ==========================================================================
   密码锁
   分类加密和文章加密共用一套外观：上面一个浮动的锁，中间标题说明，下面一行输入。
   文章那边是 Typecho 自带的表单，结构改不了，只能把它的盒子剥掉、控件接过来。
   ========================================================================== */

.el9-lock {
    position: relative;
    margin: var(--el9-6) 0;
    padding: 40px 24px 34px;
    border: 1px solid var(--el9-border);
    border-radius: 20px;
    background:
        radial-gradient(120% 80% at 50% -20%, var(--el9-accent-soft), transparent 60%),
        var(--el9-bg);
    text-align: center;
    overflow: hidden;
}

/*
 * 被锁住的时候，这一页只干一件事：输密码。
 *
 * 跟抽签页同一个道理 —— 右边那一栏（名片、热门标签、最新评论、分类）
 * 在这时候全是干扰项，读者正卡在门口，给他一排可以点走的东西只会让人分神。
 * 收掉之后主栏撑满，卡片自己封顶居中。
 *
 * 覆盖两种情况：分类归档页被锁（index.php）、文章落在加密分类里（post.php）。
 */
.el9-layout:has(.el9-lock) .el9-side {
    display: none;
}

.el9-layout:has(.el9-lock) .el9-main {
    flex: 1 1 auto;
    max-width: none;
    /*
     * 这一页只有一张卡，把它放在视口中间。
     *
     * 贴着顶部看着像「页面没加载完」，尤其侧栏收掉之后左边空空荡荡，
     * 卡片孤零零顶在导航条下面。
     *
     * 撑满「视口 - 导航」这一整段：页脚会被推到下一屏，密码页本来也不需要
     * 一眼看见页脚。留 120 的余量反而会让卡片偏上 —— 那 120 补不掉页脚的高度。
     */
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: calc(100vh - var(--el9-nav-h));
    min-height: calc(100dvh - var(--el9-nav-h));
    /*
     * 窄屏的 main 底部垫了「底栏 52 + safe-area + 20」，那是给长页面留的。
     * 这一页只有一张卡，那 70 多像素会把 flex 的中心整体往上顶 —— 收掉。
     */
    padding-bottom: 0;
}

/* 主栏撑满后这张卡会横向拉得很扁，封顶 520 居中；位置交给上面的 flex */
.el9-lock {
    width: 100%;
    max-width: 520px;
    margin: 0 auto;
}

/* 顶上一条淡的渐变亮线，卡片边缘不至于死板 */
.el9-lock::before {
    content: '';
    position: absolute;
    top: 0;
    left: 14%;
    right: 14%;
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--el9-accent), transparent);
    opacity: .5;
}

.el9-lock-ico {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 54px;
    height: 54px;
    margin-bottom: 16px;
    border: 1px solid color-mix(in srgb, var(--el9-accent) 24%, var(--el9-border));
    border-radius: 50%;
    background: var(--el9-bg);
    color: var(--el9-accent-text);
    box-shadow:
        0 10px 24px -12px color-mix(in srgb, var(--el9-accent) 70%, transparent),
        0 0 0 7px color-mix(in srgb, var(--el9-accent) 6%, transparent);
    animation: el9-lock-float 5s ease-in-out infinite;
}

@keyframes el9-lock-float {
    0%, 100% { transform: translateY(0); }
    50%      { transform: translateY(-4px); }
}

.el9-lock-kicker {
    margin: 0 0 7px;
    font-size: 11px;
    font-weight: 600;
    line-height: 1.6;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--el9-accent-text);
}

.el9-lock-title {
    margin: 0 0 8px;
    font-size: 19px;
    font-weight: 650;
    line-height: 1.4;
    color: var(--el9-text);
}

.el9-lock-tip {
    max-width: 30em;
    margin: 0 auto 22px;
    font-size: 14px;
    line-height: 1.7;
    color: var(--el9-text-2);
}

.el9-lock-form {
    display: flex;
    gap: 8px;
    width: 100%;
    max-width: 340px;
    margin: 0 auto;
}

/* 输入框：原生表单那个也归到这一条 */
.el9-lock-input,
.el9-content.is-locked .protected input[type="password"] {
    flex: 1;
    width: auto;
    min-width: 0;
    max-width: none;
    height: 46px;
    padding: 0 16px;
    /* 16px 是下限：iOS Safari 对更小的输入框会放大整页 */
    font-size: 16px;
    color: var(--el9-text);
    /* 白底 + 浅灰线边，跟全站 .el9-input 一套 */
    background: var(--el9-bg);
    border: 1px solid var(--el9-border-strong);
    border-radius: 12px;
    outline: none;
    transition: border-color var(--el9-dur) var(--el9-ease),
                box-shadow var(--el9-dur) var(--el9-ease);
}

.el9-lock-input::placeholder { color: var(--el9-text-3); }

.el9-lock-input:focus,
.el9-content.is-locked .protected input[type="password"]:focus {
    border-color: var(--el9-accent);
    box-shadow: 0 0 0 4px var(--el9-accent-soft);
}

/* 按钮：原生表单那个也归到这一条 */
.el9-lock-btn,
.el9-content.is-locked .protected input[type="submit"] {
    flex: 0 0 auto;
    width: auto;
    height: 46px;
    margin: 0;
    padding: 0 24px;
    font-size: 15px;
    font-weight: 600;
    color: var(--el9-accent-contrast);
    background: var(--el9-accent);
    border: 0;
    border-radius: 12px;
    cursor: pointer;
    /* 不投影（同上）—— 实心主题色已经够分量 */
    transition: filter var(--el9-dur) var(--el9-ease);
}

.el9-lock-btn:hover,
.el9-content.is-locked .protected input[type="submit"]:hover {
    filter: brightness(1.08);
}

.el9-lock-btn:active,
.el9-content.is-locked .protected input[type="submit"]:active {
    transform: translateY(0);
}

.el9-lock-err {
    margin: 12px 0 0;
    font-size: 13px;
    color: var(--el9-c-caution);
}

/* 密码错了：抖一下 + 输入框描红，比单纯加一行字更抓眼睛 */
.el9-lock.is-error {
    animation: el9-lock-shake .4s ease-in-out;
}

.el9-lock.is-error .el9-lock-input {
    border-color: var(--el9-c-caution);
    box-shadow: 0 0 0 4px color-mix(in srgb, var(--el9-c-caution) 12%, transparent);
}

@keyframes el9-lock-shake {
    0%, 100% { transform: translateX(0); }
    20%      { transform: translateX(-5px); }
    40%      { transform: translateX(4px); }
    60%      { transform: translateX(-3px); }
    80%      { transform: translateX(2px); }
}

@media (prefers-reduced-motion: reduce) {
    .el9-lock-ico { animation: none; }
    .el9-lock.is-error { animation: none; }
}

@media screen and (max-width: 480px) {
    .el9-lock {
        padding: 32px 18px 26px;
        border-radius: 16px;
    }

    .el9-lock-title { font-size: 17px; }
    .el9-lock-form { flex-direction: column; }

    /*
     * 竖排时输入框会缩成一条 —— 真凶是 flex:1。
     *
     * flex:1 展开是 flex:1 1 0%，那个 0% 是**主轴基准**：横排时指宽度，竖排时
     * 指高度。表单容器高度是 auto，没有多余空间可分，input 的高度就被压到接近 0，
     * 46px 的 height 也被 flex-basis 顶掉。桌面上看着正常，只有手机上塌。
     */
    .el9-lock-input,
    .el9-content.is-locked .protected input[type="password"] {
        flex: 0 0 auto;
        width: 100%;
    }

    .el9-lock-btn { width: 100%; }
}

/* ==========================================================================
   PJAX 换页进度条
   ========================================================================== */

.el9-pjax-bar {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 260;
    width: 0;
    height: 2px;
    background: var(--el9-accent);
    opacity: 0;
    pointer-events: none;
    transition: width .25s cubic-bezier(.4, 0, .2, 1), opacity .2s linear;
}

.el9-pjax-bar.is-on {
    width: 72%;
    opacity: 1;
}

.el9-pjax-bar.is-done {
    width: 100%;
    opacity: 0;
    transition: width .18s linear, opacity .24s linear .06s;
}

/* QQ 图标（顶部导航那颗，尺寸由 el9QqIcon() 的入参决定） */
.el9-qq-ico { flex: 0 0 auto; }

/* ==========================================================================
   归档（page-archive.php）
   按年份分块，每年一个标题 + 一串条目。说说不进这张表（见模板里的排除逻辑）。
   ========================================================================== */

.el9-arch {
    max-width: 780px;
}

.el9-arch-head {
    margin-bottom: var(--el9-5);
}

.el9-arch-title {
    margin: 0 0 6px;
    font-size: 26px;
    font-weight: 650;
    line-height: 1.35;
    color: var(--el9-text);
}

/* 顶部统计卡：篇数 + 年份跨度 + 全站字数 */
.el9-arch-stat {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-top: var(--el9-4);
    padding: var(--el9-4) var(--el9-5);
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-md);
    background: var(--el9-bg-soft);
}

.el9-arch-stat .el9-arch-meta,
.el9-arch-stat .el9-arch-words {
    margin: 0;
    font-size: 13px;
    line-height: 1.6;
    color: var(--el9-text-2);
}

.el9-arch-stat strong {
    font-weight: 650;
    color: var(--el9-text);
    font-variant-numeric: tabular-nums;
}

/* 两行之间那条细线，比卡片边框更淡，不抢视线 */
.el9-arch-stat .el9-arch-words {
    padding-top: 6px;
    border-top: 1px dashed var(--el9-border);
}

.el9-arch-meta {
    margin: 0;
    font-size: 13px;
    color: var(--el9-text-3);
}

.el9-arch-words {
    margin: 8px 0 0;
    font-size: 13px;
    color: var(--el9-text-3);
}

.el9-arch-intro {
    margin-top: var(--el9-4);
}

.el9-arch-year + .el9-arch-year {
    margin-top: var(--el9-5);
}

.el9-arch-y {
    display: flex;
    align-items: baseline;
    gap: 8px;
    margin: 0 0 4px;
    padding-bottom: 9px;
    border-bottom: 1px solid var(--el9-border);
    font-size: 15px;
    font-weight: 650;
    color: var(--el9-text);
    /* 年份是 details 的 summary：整行可点，自己画箭头，摘掉系统那个三角 */
    cursor: pointer;
    list-style: none;
    user-select: none;
    transition: color var(--el9-dur) var(--el9-ease);
}

.el9-arch-y::-webkit-details-marker {
    display: none;
}

.el9-arch-y:hover {
    color: var(--el9-accent-text);
}

/* 箭头贴在篇数后面，不甩到整行最右 —— 那样会看着像另一个按钮 */
.el9-arch-y::after {
    content: "";
    flex: 0 0 auto;
    width: 6px;
    height: 6px;
    margin-left: -2px;
    border-right: 1.5px solid currentColor;
    border-bottom: 1.5px solid currentColor;
    opacity: .55;
    transform: rotate(45deg) translate(-1px, -1px);
    transition: transform var(--el9-dur) var(--el9-ease);
}

.el9-arch-year[open] .el9-arch-y::after {
    transform: rotate(-135deg) translate(-1px, -1px);
}

/* 年份右边那个小数字：这一年有多少篇 */
.el9-arch-y em {
    font-style: normal;
    font-size: 12px;
    font-weight: 500;
    color: var(--el9-text-3);
    font-variant-numeric: tabular-nums;
}

.el9-arch-list {
    margin: 0;
    padding: 0;
    list-style: none;
}

.el9-arch-list li {
    display: flex;
    align-items: baseline;
    gap: 10px;
    padding: 8px 0;
    border-bottom: 1px dashed var(--el9-border);
}

.el9-arch-list li:last-child {
    border-bottom: 0;
}

.el9-arch-list a {
    display: flex;
    align-items: baseline;
    gap: 12px;
    flex: 1 1 auto;
    min-width: 0;
    color: var(--el9-text);
    text-decoration: none;
    transition: color var(--el9-dur) var(--el9-ease);
}

.el9-arch-list a:hover {
    color: var(--el9-accent-text);
}

.el9-arch-list time {
    flex: 0 0 auto;
    font-size: 12px;
    color: var(--el9-text-3);
    font-variant-numeric: tabular-nums;
}

/* 标题太长就省略，不要把时间挤走 */
.el9-arch-name {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.el9-arch-cmt {
    flex: 0 0 auto;
    font-style: normal;
    font-size: 12px;
    color: var(--el9-text-3);
    font-variant-numeric: tabular-nums;
}

@media screen and (max-width: 699px) {
    .el9-arch-title { font-size: 22px; }
    .el9-arch-list a { gap: 8px; }
}

/* ==========================================================================
   注册（page-register.php）
   ========================================================================== */

/*
 * 注册页：单栏，只有一张卡片。
 *
 * 摆侧栏的时候这一页是「左挂件 + 右表单」，表单被挤在中间，还要先读一堆说明。
 * 仿 Typecho 官方注册页的做法：侧栏收掉、卡片居中、只剩字段和按钮。
 * 用 :has() 认页面 —— 老浏览器不认也没关系，退化成普通双栏，卡片照样居中。
 */
body:has(.el9-reg) .el9-side {
    display: none;
}

body:has(.el9-reg) .el9-layout {
    justify-content: center;
}

.el9-reg {
    max-width: 400px;
    /* 往下压一点，别贴着头顶，接近官方那种「竖着摆在页面中间」的位置 */
    margin: 5vh auto 0;
    padding: var(--el9-6) var(--el9-6) var(--el9-5);
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-lg);
    background: var(--el9-bg);
}

/* 标题居中，和官方那页一致 */
.el9-reg-head {
    text-align: center;
}

.el9-reg-head .el9-reg-title {
    margin-bottom: var(--el9-5);
}

/* 按钮撑满整行，一眼知道下一步点哪儿 */
.el9-reg-submit {
    width: 100%;
}

/* 卡片底部的「已有账号？去登录」 */
.el9-reg-alt {
    margin: var(--el9-4) 0 0;
    text-align: center;
    font-size: 13px;
    color: var(--el9-text-3);
}

.el9-reg-alt a {
    color: var(--el9-accent-text);
    text-decoration: none;
}

.el9-reg-alt a:hover {
    text-decoration: none;
}

@media screen and (max-width: 699px) {
    /* 手机上贴满整宽，卡片壳去掉 —— 小屏再套一层框很挤 */
    .el9-reg {
        margin: 0;
        padding: 0;
        border: 0;
        border-radius: 0;
        background: transparent;
    }
}

.el9-reg-head {
    margin-bottom: var(--el9-5);
}

.el9-reg-title {
    margin: 0 0 6px;
    font-size: 22px;
    font-weight: 650;
    line-height: 1.35;
    color: var(--el9-text);
}

.el9-reg-sub {
    margin: 0;
    font-size: 14px;
    line-height: 1.7;
    color: var(--el9-text-2);
}

.el9-reg-note {
    margin: 0 0 var(--el9-4);
    padding: 11px 15px;
    border-radius: var(--el9-r-sm);
    font-size: 13px;
    line-height: 1.7;
    border: 1px solid var(--el9-border);
    background: var(--el9-bg-soft);
    color: var(--el9-text-2);
}

.el9-reg-note.is-ok {
    border-color: color-mix(in srgb, var(--el9-c-tip) 30%, var(--el9-border));
    background: color-mix(in srgb, var(--el9-c-tip) 8%, var(--el9-bg));
    color: var(--el9-c-tip-ink);
}

.el9-reg-note.is-err {
    border-color: color-mix(in srgb, var(--el9-c-caution) 30%, var(--el9-border));
    background: color-mix(in srgb, var(--el9-c-caution) 7%, var(--el9-bg));
    color: var(--el9-c-caution-ink);
}

.el9-reg-form {
    display: flex;
    flex-direction: column;
    gap: var(--el9-4);
}

.el9-reg-field {
    display: flex;
    flex-direction: column;
    margin: 0;
}

.el9-reg-field label {
    margin-bottom: 6px;
    font-size: 13px;
    color: var(--el9-text-2);
}

.el9-reg-form {
    gap: var(--el9-4);
}

.el9-reg-field .el9-input {
    width: 100%;
}

.el9-reg-hint {
    margin-top: 6px;
    font-size: 12px;
    line-height: 1.7;
    color: var(--el9-text-3);
}

.el9-reg-hint b {
    font-weight: 600;
    color: var(--el9-text-2);
}

/* 「不可修改」这条单独标红，别让人填完才后悔 */
.el9-reg-hint b.is-warn {
    color: var(--el9-c-caution-ink);
}

.el9-reg-actions {
    display: flex;
    align-items: center;
    gap: var(--el9-4);
    flex-wrap: wrap;
    margin: var(--el9-2) 0 0;
}

.el9-reg-login {
    font-size: 13px;
    color: var(--el9-text-2);
    text-decoration: none;
    border-bottom: 1px solid var(--el9-border-strong);
}

.el9-reg-login:hover {
    color: var(--el9-accent-text);
    border-bottom-color: var(--el9-accent);
}

.el9-reg-closed {
    padding: 32px 24px;
    border: 1px dashed var(--el9-border-strong);
    border-radius: var(--el9-r-md);
    background: var(--el9-bg-soft);
    text-align: center;
    font-size: 14px;
    color: var(--el9-text-2);
}

.el9-reg-closed p { margin: 0; }

.el9-reg-extra {
    margin-top: var(--el9-6);
    padding-top: var(--el9-4);
    border-top: 1px solid var(--el9-border);
}

/* ==========================================================================
   个人中心（page-user.php）
   ========================================================================== */

.el9-uc {
    display: flex;
    flex-direction: column;
    gap: var(--el9-4);
}

/* ---- 顶部信息：头像 + 名字 ----
   就是一张带边框的横条，没有封面图 —— 头像和名字叠在照片上会互相打架 */

.el9-uc-head {
    display: flex;
    align-items: center;
    gap: var(--el9-4);
    padding: var(--el9-5);
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-md);
    background: var(--el9-bg);
}

.el9-uc-avatar {
    flex: 0 0 auto;
    line-height: 0;
}

.el9-uc-avatar .el9-avatar {
    display: block;
    border-radius: 50%;
}

.el9-uc-id {
    min-width: 0;
}

.el9-uc-name {
    margin: 0 0 3px;
    font-size: 20px;
    font-weight: 650;
    line-height: 1.3;
    color: var(--el9-text);
    overflow-wrap: break-word;
}

.el9-uc-sub {
    margin: 0;
    font-size: 13px;
    color: var(--el9-text-3);
}

/* ---- 后台快捷入口 ----
   管理员 / 编辑 / 贡献者才看得见，靠 margin-left:auto 顶到右边缘。
   刻意做得比正文轻：这是「顺手去写点东西」的快捷方式，不是这一页的主角。 */

.el9-uc-tools {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 6px;
    margin-left: auto;
}

.el9-uc-admin {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    border: 1px solid var(--el9-border);
    border-radius: 10px;
    background: var(--el9-bg);
    color: var(--el9-text-3);
    text-decoration: none;
    transition: color var(--el9-dur) var(--el9-ease),
                border-color var(--el9-dur) var(--el9-ease),
                background var(--el9-dur) var(--el9-ease),
                transform var(--el9-dur) var(--el9-ease);
}

.el9-uc-admin:hover {
    color: var(--el9-accent-text);
    border-color: color-mix(in srgb, var(--el9-accent) 42%, var(--el9-border));
    background: var(--el9-accent-soft);
    transform: translateY(-1px);
}

.el9-uc-admin:focus-visible {
    outline: 2px solid var(--el9-accent);
    outline-offset: 2px;
}

/* 图标本身不吃点击（不然 hover 会断开） */
.el9-uc-admin .el9-icon {
    display: block;
    pointer-events: none;
}

/* ---- 数据条 ---- */

.el9-uc-stats {
    display: flex;
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-md);
    background: var(--el9-bg);
    overflow: hidden;
}

.el9-uc-stats > div {
    flex: 1;
    padding: 12px 8px;
    text-align: center;
}

.el9-uc-stats > div + div {
    border-left: 1px solid var(--el9-border);
}

.el9-uc-stats b {
    display: block;
    font-size: 18px;
    font-weight: 650;
    line-height: 1.3;
    color: var(--el9-text);
    font-variant-numeric: tabular-nums;
}

.el9-uc-stats span {
    display: block;
    margin-top: 1px;
    font-size: 12px;
    color: var(--el9-text-3);
}

/* ---- 标签页 ----
   默认不启用「只显示一个」：没有 JS 时所有内容照常铺开，
   JS 跑起来才在容器上加 data-tabs="on"，切成单页显示。 */

.el9-uc-tabs {
    display: flex;
    gap: 2px;
    overflow-x: auto;
    border-bottom: 1px solid var(--el9-border);
    scrollbar-width: none;
}

.el9-uc-tabs::-webkit-scrollbar { display: none; }

.el9-uc-tab {
    position: relative;
    flex: 0 0 auto;
    padding: 10px 14px;
    border: 0;
    border-radius: 0;
    background: none;
    font-size: 14px;
    line-height: 1.5;
    color: var(--el9-text-2);
    white-space: nowrap;
    cursor: pointer;
    transition: color var(--el9-dur) var(--el9-ease);
}

.el9-uc-tab:hover { color: var(--el9-text); }

.el9-uc-tab::after {
    content: '';
    position: absolute;
    left: 14px;
    right: 14px;
    bottom: -1px;
    height: 2px;
    border-radius: 2px;
    background: transparent;
    transition: background var(--el9-dur) var(--el9-ease);
}

.el9-uc-tab.is-on {
    color: var(--el9-text);
    font-weight: 600;
}

.el9-uc-tab.is-on::after { background: var(--el9-accent); }

.el9-uc-tab em {
    margin-left: 5px;
    font-style: normal;
    font-size: 11px;
    font-weight: 500;
    color: var(--el9-text-3);
    font-variant-numeric: tabular-nums;
}

.el9-uc-panes {
    display: flex;
    flex-direction: column;
    gap: var(--el9-4);
}

.el9-uc-pane {
    display: flex;
    flex-direction: column;
    gap: var(--el9-4);
}

.el9-uc[data-tabs="on"] .el9-uc-pane { display: none; }
.el9-uc[data-tabs="on"] .el9-uc-pane.is-on { display: flex; }

/* 标签页里的卡片不再单独描边 —— 一屏里三层框会显得碎 */
.el9-uc[data-tabs="on"] .el9-uc-pane .el9-uc-card {
    padding-left: 0;
    padding-right: 0;
    border-left: 0;
    border-right: 0;
    background: none;
}

.el9-uc-sub .el9-dot { margin: 0 5px; }

/* 提示条 */
.el9-uc-note {
    margin: 0;
    padding: 10px 14px;
    border-radius: var(--el9-r-sm);
    font-size: 14px;
    line-height: 1.6;
}

.el9-uc-note.is-ok {
    background: color-mix(in srgb, var(--el9-c-tip) 8%, var(--el9-bg));
    border: 1px solid color-mix(in srgb, var(--el9-c-tip) 32%, transparent);
    color: var(--el9-c-tip-ink);
}

.el9-uc-note.is-err {
    background: color-mix(in srgb, var(--el9-c-caution) 7%, var(--el9-bg));
    border: 1px solid color-mix(in srgb, var(--el9-c-caution) 30%, transparent);
    color: var(--el9-c-caution-ink);
}

.el9-uc-note.is-warn {
    background: color-mix(in srgb, var(--el9-c-warning) 9%, var(--el9-bg));
    border: 1px solid color-mix(in srgb, var(--el9-c-warning) 34%, transparent);
    color: var(--el9-c-warning-ink);
}

/* 卡片 */
.el9-uc-card {
    padding: var(--el9-5) var(--el9-6);
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-md);
    background: var(--el9-bg);
}

.el9-uc-title {
    display: flex;
    align-items: baseline;
    gap: 8px;
    margin: 0 0 var(--el9-4);
    font-size: 15px;
    font-weight: 600;
    color: var(--el9-text);
}

.el9-uc-title small {
    font-size: 12px;
    font-weight: 400;
    color: var(--el9-text-3);
}

/* 表单 */
.el9-uc-form p { margin: 0 0 var(--el9-4); }

.el9-uc-form label,
.el9-uc-label {
    display: block;
    margin-bottom: 6px;
    font-size: 13px;
    color: var(--el9-text-2);
}

/* 用户名那一行：不做成输入框，免得让人以为能改。
   虚线框 + 灰底，一眼就知道是「只读信息」 */
.el9-uc-readonly {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 14px;
    border: 1px dashed var(--el9-border-strong);
    border-radius: var(--el9-r-sm);
    background: var(--el9-bg-soft);
    font-size: 15px;
    color: var(--el9-text-2);
    overflow-wrap: break-word;
}

.el9-uc-readonly em {
    flex: 0 0 auto;
    margin-left: auto;
    padding: 1px 8px;
    border: 1px solid var(--el9-border);
    border-radius: 999px;
    background: var(--el9-bg);
    font-style: normal;
    font-size: 11px;
    line-height: 1.7;
    color: var(--el9-text-3);
    white-space: nowrap;
}

.el9-uc-form .el9-input { width: 100%; }

.el9-uc-form .el9-uc-actions { margin-bottom: 0; }

.el9-uc-hint {
    margin: 0 0 var(--el9-4);
    font-size: 14px;
    line-height: 1.7;
    color: var(--el9-text-2);
}

.el9-uc-card > p:last-child { margin-bottom: 0; }

/* QQ 行 */
.el9-uc-qq {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--el9-3);
    padding: 10px 14px;
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-sm);
    background: var(--el9-bg-soft);
    font-size: 14px;
}

.el9-uc-qq-info {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    min-width: 0;
    color: var(--el9-text-2);
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.el9-uc-qq-info .el9-qq-ico { color: var(--el9-accent-text); }

.el9-uc-qq form { margin: 0; }

.el9-uc-linkbtn {
    padding: 4px 12px;
    border: 0;
    border-radius: 999px;
    background: transparent;
    color: var(--el9-text-3);
    font-size: 13px;
    cursor: pointer;
    transition: background var(--el9-dur) var(--el9-ease), color var(--el9-dur) var(--el9-ease);
}

.el9-uc-linkbtn:hover {
    background: var(--el9-bg-hover);
    color: var(--el9-danger-text);
}

/* 列表 */
.el9-uc-list {
    margin: 0;
    padding: 0;
    list-style: none;
}

.el9-uc-list li {
    padding: 10px 0;
    border-bottom: 1px solid var(--el9-border);
}

.el9-uc-list li:first-child { padding-top: 0; }
.el9-uc-list li:last-child { padding-bottom: 0; border-bottom: 0; }

.el9-uc-list a {
    display: block;
    color: var(--el9-text);
    font-size: 15px;
    line-height: 1.55;
    text-decoration: none;
    overflow-wrap: break-word;
}

.el9-uc-list a:hover { color: var(--el9-accent-text); }

.el9-uc-meta {
    display: block;
    margin-top: 3px;
    font-size: 12px;
    color: var(--el9-text-3);
}

.el9-uc-list--cmt a { color: var(--el9-text-2); font-size: 14px; }

/* 头像做成按钮：能点，但看起来还是张头像 */
.el9-uc-avatar-btn {
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
    border-radius: 50%;
    transition: transform var(--el9-dur) var(--el9-ease);
}

.el9-uc-avatar-btn:hover { transform: scale(1.04); }

.el9-uc-avatar-btn:focus-visible {
    outline: 2px solid var(--el9-accent);
    outline-offset: 3px;
}

/* ---- 头像弹窗 ---- */

.el9-avbox {
    position: fixed;
    inset: 0;
    z-index: 220;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--el9-4);
}

.el9-avbox[hidden] { display: none; }

.el9-avbox-mask {
    position: absolute;
    inset: 0;
    background: rgba(15, 20, 25, .48);
    backdrop-filter: blur(2px);
}

.el9-avbox-panel {
    position: relative;
    width: 100%;
    max-width: 540px;
    max-height: 88vh;
    overflow-y: auto;
    border-radius: var(--el9-r-md);
    background: var(--el9-bg);
    box-shadow: 0 24px 60px -20px rgba(15, 23, 42, .4);
}

.el9-avbox-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--el9-4) var(--el9-5);
    border-bottom: 1px solid var(--el9-border);
}

.el9-avbox-head h2 {
    margin: 0;
    font-size: 16px;
    font-weight: 650;
    color: var(--el9-text);
}

.el9-avbox-x {
    width: 32px;
    height: 32px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: transparent;
    font-size: 22px;
    line-height: 1;
    color: var(--el9-text-3);
    cursor: pointer;
}

.el9-avbox-x:hover {
    background: var(--el9-bg-hover);
    color: var(--el9-text);
}

.el9-avbox-body {
    padding: var(--el9-5);
}

/* ---- 加载更多 ---- */

.el9-uc-more {
    margin: var(--el9-4) 0 0;
    text-align: center;
}

.el9-uc-more .el9-btn {
    min-width: 140px;
}

/* 未验证邮箱那条提示，带一个重发按钮 */
.el9-uc-verify {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--el9-4);
    flex-wrap: wrap;
}

.el9-uc-verify p { margin: 0; }

/* ---- 头像 ---- */

.el9-uc-av {
    display: flex;
    align-items: flex-start;
    gap: var(--el9-5);
    margin-bottom: var(--el9-4);
}

.el9-uc-av-now {
    flex: 0 0 auto;
    line-height: 0;
}

.el9-uc-av-now .el9-avatar {
    display: block;
    border: 1px solid var(--el9-border);
    border-radius: 50%;
}

.el9-uc-av-body {
    flex: 1 1 auto;
    min-width: 0;
}

.el9-uc-av-form {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

/* 地址输入框：跟按钮并排，窄屏时自己掉到下一行 */
.el9-uc-av-url {
    flex: 1 1 200px;
    min-width: 0;
    font-size: 13px;
}

/* 这颗按钮别被 flex 拉长，跟输入框等高就行 */
.el9-uc-av-form .el9-btn {
    flex: 0 0 auto;
    padding: 9px 18px;
}

.el9-uc-av-src {
    margin: 0 0 10px;
    font-size: 12px;
    color: var(--el9-text-2);
}

.el9-uc-av-meta {
    margin: 10px 0 0;
    font-size: 12px;
    color: var(--el9-text-3);
}

.el9-uc-av-rule {
    padding: var(--el9-4);
    border-radius: var(--el9-r-sm);
    background: var(--el9-bg-soft);
    font-size: 13px;
    line-height: 1.7;
    color: var(--el9-text-2);
}

.el9-uc-av-rule p { margin: 0 0 6px; }
.el9-uc-av-rule p:last-child { margin-bottom: 0; }

.el9-uc-av-rule ol {
    margin: 0 0 8px;
    padding-left: 20px;
}

.el9-uc-av-rule li { margin: 2px 0; }

@media screen and (max-width: 699px) {
    .el9-uc-card { padding: var(--el9-4); }
    .el9-uc-name { font-size: 18px; }
    .el9-uc-av { gap: var(--el9-4); }

    .el9-uc-head { gap: var(--el9-3); padding: var(--el9-4); }
    .el9-uc-stats b { font-size: 16px; }
    .el9-uc-tab { padding: 10px 11px; font-size: 13px; }

    /* 手机上一排四颗 38px 会把名字挤没，缩一圈 */
    .el9-uc-tools { gap: 5px; }
    .el9-uc-admin { width: 34px; height: 34px; border-radius: 9px; }

    /*
     * 副标题按「段」换行，别把字拆开。
     *
     * 原来是普通段落，中文可以在任意两字之间断行 —— 头像 + 四颗工具按钮把宽度
     * 吃掉之后，「2026-07-09 加入」被断成「…加」和「入」，单独一个「入」占一行，
     * 看着像排版坏了。
     *
     * 改成 flex：每一段是一个不可分割的块（配合下面的 nowrap），
     * 整行放不下时整段落到第二行，不会再出现孤字。
     */
    .el9-uc-sub {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        column-gap: 6px;
        font-size: 12.5px;
    }

    .el9-uc-sub > span {
        white-space: nowrap;
    }

    /* 分隔点由 gap 顶替 —— 留着的话换行后会孤零零挂在行首 */
    .el9-uc-sub .el9-dot {
        display: none;
        margin: 0;
    }
}

/* 没绑邮箱时的评论区提示 */
.el9-needmail {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    margin: var(--el9-4) 0;
    padding: 14px 16px;
    border: 1px solid color-mix(in srgb, var(--el9-c-warning) 34%, transparent);
    border-radius: var(--el9-r-sm);
    background: color-mix(in srgb, var(--el9-c-warning) 9%, var(--el9-bg));
    font-size: 14px;
    line-height: 1.7;
    color: var(--el9-c-warning-ink);
}

.el9-needmail .el9-icon {
    flex: 0 0 auto;
    margin-top: 2px;
}

.el9-needmail p { margin: 0; }

.el9-needmail a {
    color: inherit;
    font-weight: 600;
    text-decoration: none;
}

/* -------------------------------------------------------------------------
 * 轻提示（点了休眠链接时的那句话）
 *
 * 固定在屏幕下方中间浮一条，1.6 秒自己消失。
 *
 * **一行显示完，不折行**：折成两行会盖住上面一行字，看着也像报错框；
 * 这句话也就二十来个字，宽度够装。
 * ---------------------------------------------------------------------- */
.el9-tip {
    position: fixed;
    left: 50%;
    bottom: 96px;
    z-index: 120;
    display: flex;
    align-items: center;
    gap: 7px;
    width: max-content;
    max-width: calc(100vw - 20px);
    padding: 7px 12px 7px 10px;
    border: 1px solid var(--el9-border);
    border-radius: 10px;
    background: var(--el9-bg);
    color: var(--el9-text);
    font-size: 12.5px;
    line-height: 1.5;
    white-space: nowrap;
    box-shadow: 0 6px 20px rgba(0, 0, 0, .1);
    pointer-events: none;
    opacity: 0;
    transform: translate(-50%, 10px);
    transition: opacity .16s var(--el9-ease), transform .16s var(--el9-ease);
}

.el9-tip.is-on {
    opacity: 1;
    transform: translate(-50%, 0);
}

/*
 * 前面那个橙底感叹号。
 * 只是句提醒，不用红色 —— 红色留给「出错了」，链接打不开还没到那个级别。
 */
.el9-tip-ico {
    flex: 0 0 auto;
    width: 15px;
    height: 15px;
    border-radius: 50%;
    background: #e8a33d;
    color: #fff;
    font-size: 10px;
    font-weight: 700;
    line-height: 15px;
    text-align: center;
}

@media screen and (max-width: 700px) {
    .el9-tip {
        bottom: 80px;
    }
}

/* 窄到装不下一整行时，宁可字号小一档，也不要折行 */
@media screen and (max-width: 400px) {
    .el9-tip {
        font-size: 11.5px;
        padding: 6px 10px 6px 9px;
        gap: 6px;
    }
}

/* -------------------------------------------------------------------------
 * 站外链接确认
 *
 * 正文和评论里点了别人的链接，先拦一下 —— 不直接跳走，弹一张卡片问一句。
 * 目的是让人看清「要去哪个域名」，不是拦着他不让去。
 *
 * 线条卡片：同色底 + 1px 细边 + 轻阴影，不铺满屏、不用大圆角黑按钮。
 * 只在 .el9-content / .el9-cmt 范围内生效：导航和友链那种目录性质的链接
 * 拦了只会烦人。
 * ---------------------------------------------------------------------- */
.el9-extcheck {
    position: fixed;
    inset: 0;
    z-index: 130;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    background: rgba(15, 20, 25, .34);
    -webkit-backdrop-filter: blur(2px);
    backdrop-filter: blur(2px);
    opacity: 0;
    visibility: hidden;
    transition: opacity .18s var(--el9-ease), visibility .18s var(--el9-ease);
}

.el9-extcheck.is-open {
    opacity: 1;
    visibility: visible;
}

.el9-extcheck-card {
    width: 100%;
    max-width: 392px;
    padding: 22px 22px 20px;
    border: 1px solid var(--el9-border);
    border-radius: 14px;
    background: var(--el9-bg);
    box-shadow: 0 18px 50px rgba(0, 0, 0, .16);
    transform: translateY(10px) scale(.985);
    transition: transform .2s var(--el9-ease);
}

.el9-extcheck.is-open .el9-extcheck-card {
    transform: none;
}

.el9-extcheck-head {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 15px;
    font-weight: 600;
    color: var(--el9-text);
}

.el9-extcheck-head svg {
    flex: 0 0 auto;
    color: var(--el9-text-3);
}

.el9-extcheck-tip {
    margin: 8px 0 14px;
    font-size: 13px;
    line-height: 1.65;
    color: var(--el9-text-2);
}

.el9-extcheck-url {
    display: block;
    padding: 9px 12px;
    border: 1px solid var(--el9-border);
    border-radius: 8px;
    background: var(--el9-bg-soft);
    color: var(--el9-text-2);
    font-family: ui-monospace, Menlo, Consolas, monospace;
    font-size: 12.5px;
    line-height: 1.5;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.el9-extcheck-acts {
    display: flex;
    gap: 10px;
    margin-top: 18px;
}

.el9-extcheck-acts .el9-btn {
    flex: 1;
    height: 40px;
}


/* -------------------------------------------------------------------------
 * 下划线动效（hover 才出现的那几处）
 *
 * 跟正文链接同一套：鼠标移上去从左展开，移开往右收起。
 * 单独抽一条规则，省得四个地方各写一份渐变背景。
 * ---------------------------------------------------------------------- */
.el9-rail-foot a,
.el9-card-time,
.el9-reg-alt a,
.el9-needmail a {
    background-image: linear-gradient(currentColor, currentColor);
    background-repeat: no-repeat;
    background-position: right bottom;
    background-size: 0 1px;
    padding-bottom: 2px;
    transition: background-size .28s var(--el9-ease), background-position 0s;
}

.el9-rail-foot a:hover,
.el9-card-time:hover,
.el9-reg-alt a:hover,
.el9-needmail a:hover {
    background-position: left bottom;
    background-size: 100% 1px;
}

/* 这两处本来就是「贴住底边」的小字，多出来的 2px 内边距会把行高撑开一点，收回 */
.el9-card-time {
    padding-bottom: 0;
}

/* -------------------------------------------------------------------------
 * 侧栏「黑名单公示」：刻意不显眼
 *
 * 它是页脚里的一行普通小字，不是入口按钮：不套强调色、不加粗、不加
 * hover 下划线展开动效，鼠标移上去也不许有任何变化（包括 :visited）。
 * 选择器比上面的 .el9-rail-foot a / a:hover 多一个类，用来盖掉那套动效。
 * 保留 a 标签和 href，键盘仍可聚焦、仍可点击，只是看起来跟周围灰字一样。
 * ---------------------------------------------------------------------- */
.el9-rail-foot a.el9-rail-quiet,
.el9-rail-foot a.el9-rail-quiet:visited,
.el9-rail-foot a.el9-rail-quiet:hover,
.el9-rail-foot a.el9-rail-quiet:focus,
.el9-rail-foot a.el9-rail-quiet:focus-visible,
.el9-rail-foot a.el9-rail-quiet:active {
    color: var(--el9-text-3);
    font-weight: 400;
    text-decoration: none;
    background-image: none;
    background-size: 0 0;
    background-position: left bottom;
    padding-bottom: 0;
    transition: none;
    border-bottom: 0;
    box-shadow: none;
    opacity: 1;
}

/* -------------------------------------------------------------------------
 * 站内公告（弹窗）
 *
 * 进首页弹一次，关掉后按内容指纹记到 localStorage，内容不变就不再弹。
 * 层级比灯箱（120）和站外确认（130）都高：它是「进门先说一句」，该在最上面。
 * ---------------------------------------------------------------------- */
.el9-gnotice {
    position: fixed;
    inset: 0;
    z-index: 140;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
}

.el9-gnotice[hidden] {
    display: none;
}

.el9-gnotice-mask {
    position: absolute;
    inset: 0;
    background: rgba(15, 20, 25, .36);
    -webkit-backdrop-filter: blur(2px);
    backdrop-filter: blur(2px);
}

.el9-gnotice-card {
    position: relative;
    width: 100%;
    max-width: 400px;
    padding: 20px 22px 18px;
    border: 1px solid var(--el9-border);
    border-radius: 14px;
    background: var(--el9-bg);
    box-shadow: 0 20px 50px rgba(0, 0, 0, .18);
    animation: el9-gnotice-in .22s var(--el9-ease);
}

@keyframes el9-gnotice-in {
    from { opacity: 0; transform: translateY(10px) scale(.98); }
    to   { opacity: 1; transform: none; }
}

.el9-gnotice-title {
    display: flex;
    align-items: center;
    gap: 7px;
    margin: 0 0 10px;
    font-size: 14px;
    font-weight: 600;
    color: var(--el9-text);
}

.el9-gnotice-title .el9-icon {
    color: var(--el9-accent);
}

.el9-gnotice-text {
    margin: 0 0 16px;
    font-size: 14px;
    line-height: 1.75;
    color: var(--el9-text-2);
}

.el9-gnotice-ok {
    width: 100%;
    height: 40px;
}

/* -------------------------------------------------------------------------
 * 内容遮罩（说说）
 *
 * 两种范围共用一套「点一下揭晓」：
 *   all   → .el9-mask 包住整段，模糊加在 .el9-mask-body 这一层
 *   image → 每张图包一层 .el9-mask-shot，图自己挂 .el9-mask-img，点中哪张揭哪张
 *
 * 模糊要加在一层容器上而不是逐个子元素：逐个子元素的话，段与段之间的
 * 空白不会被糊，看上去像一排排独立的模糊块，不是「整块内容被蒙住」。
 *
 * 强度按他给的那张参考图来：糊到只剩色块，再压一层半透明的纱。
 * 只靠 blur 的话，大色块的图还是能看出轮廓。
 * ---------------------------------------------------------------------- */
.el9-mask {
    position: relative;
    /*
     * 顶部这 6px 是补「字形留白」的。
     *
     * 普通段落的 p 顶边和遮罩块一样都紧贴上一行，但文字的字形是从行高里
     * 那半截 leading 之后才开始的，凭空多出五六像素呼吸感；遮罩是一整块色，
     * 没有这层留白，直接切在时间行下沿，看着就顶上了。
     *
     * 底部同理：里面的 p 自带 8px margin-bottom，被 overflow:hidden 裁掉了，
     * 遮罩底边直接顶着动作栏。上下各补一段，跟普通卡片的呼吸对得上。
     */
    margin: 6px 0 8px;
    overflow: hidden;
    border-radius: var(--el9-r-sm);
}

.el9-mask-body {
    transition: filter .34s var(--el9-ease), transform .34s var(--el9-ease);
}

/* 放大 1.04 是给模糊留出血位 —— 不放大，四周会透出一圈没糊到的边 */
.el9-mask:not(.is-open) .el9-mask-body {
    filter: blur(22px);
    transform: scale(1.04);
    pointer-events: none;
    user-select: none;
    -webkit-user-select: none;
}

.el9-mask-veil {
    position: absolute;
    inset: 0;
    z-index: 2;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    padding: 0;
    border: 0;
    background: rgba(255, 255, 255, .58);
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}

.el9-mask.is-open .el9-mask-veil {
    display: none;
}

/* 图标 + 「内容已遮罩」/「点击查看」两行，竖着排 */
.el9-mask-veil-in,
.el9-mask-shot-tip {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    text-align: center;
    transition: color var(--el9-dur) var(--el9-ease);
}

.el9-mask-veil-in .el9-icon,
.el9-mask-shot-tip .el9-icon {
    flex: 0 0 auto;
    margin-bottom: 3px;
    color: var(--el9-text-2);
    opacity: .8;
}

.el9-mask-veil-in b,
.el9-mask-shot-tip b {
    font-size: 15px;
    font-weight: 600;
    line-height: 1.4;
    color: var(--el9-text);
}

.el9-mask-veil-in i,
.el9-mask-shot-tip i {
    font-size: 12.5px;
    font-style: normal;
    line-height: 1.4;
    color: var(--el9-text-3);
}

.el9-mask-veil:hover .el9-mask-veil-in b {
    color: var(--el9-accent-text);
}

/*
 * 多图时同一套反馈。
 *
 * 单图那层白纱自己是 <button>，:hover 直接挂它身上；多图的提示层是
 * pointer-events:none（点击要落到下面的 img 上），所以得挂在外面那层
 * .el9-mask-shot 上 —— 挂提示层永远等不到 hover。
 *
 * 这点颜色变化是「这张能点」的最小信号：遮罩块本身长得跟静态图一样，
 * 不给反应就只能靠猜。
 */
.el9-mask-shot:hover .el9-mask-shot-tip b {
    color: var(--el9-accent-text);
}

/* 只糊图：不遮表情（那是正文的一部分），也不遮已经揭开的 */
/*
 * 被遮的图外面那层。
 *
 * 宽度必须跟着图走 —— 用 block 撑满整行的话，提示会飘到图右边的空白里，
 * 看着像「整块区域都被蒙住了」，人自然会去点那些其实点不动的空白。
 * inline-block 的 shrink-to-fit 就贴着图，图多大提示层多大。
 *
 * 这一层同时负责 overflow:hidden，把 blur 往外洇的那几像素裁掉。
 */
.el9-mask-shot {
    position: relative;
    /*
     * 收缩到图的宽度而不是撑满 —— 提示层贴着图，图小它小。
     *
     * 用 block 不用 inline-block：inline-block 不参与 margin collapse，
     * 它自己的 margin 会和上面段落那一截叠起来，图文之间凭空多出一倍距离。
     * fit-content 让 block 也能「按内容收缩」。
     */
    display: block;
    width: fit-content;
    max-width: 100%;
    margin: 1.4em 0;
    overflow: hidden;
    line-height: 0;
}

/* 说说里图片的上下间距跟正文不是一个量 */
.el9-card-text .el9-mask-shot {
    margin: var(--el9-2) 0;
}

/*
 * 说说单图那种「撑满正文宽度 + 限高裁切」的，外层也得撑满 ——
 * 里面的 img 是 width:100%，父级没有确定宽度的话这个 100% 没参照物。
 */
.el9-mask-shot:has(> .el9-img-solo:not(.el9-img-solo-small)) {
    display: block;
    width: 100%;
}

/* 网格：占满格子，列宽由 grid 说了算 */
.el9-img-grid > .el9-mask-shot {
    display: block;
    width: 100%;
    height: 100%;
    margin: 0;
}

/* 横滑条：跟里面的图同高，宽度交给图的宽高比 */
.el9-img-strip-track > .el9-mask-shot {
    flex: 0 0 auto;
    height: clamp(150px, 30vw, 216px);
    margin: 0;
}

.el9-img-strip-track > .el9-mask-shot img {
    height: 100%;
    width: auto;
}

/*
 * 间距交给外面那层，免得提示层的白纱盖出一条比图还大的边。
 *
 * 选择器要压过 `.el9-content img` / `.el9-card-text .el9-img-solo` 那两条 ——
 * 它们的优先级比 `.el9-mask-shot img` 高，光写后者归不了零，
 * 结果就是外层 8px + 图自己 8px = 16px，比普通图多一倍。
 */
.el9-content .el9-mask-shot img,
.el9-card-text .el9-mask-shot img,
.is-talk-single .el9-content .el9-mask-shot img {
    margin: 0;
    line-height: normal;
    transition: filter .3s var(--el9-ease), transform .3s var(--el9-ease);
}

.el9-mask-img {
    filter: blur(16px);
    transform: scale(1.06);
    cursor: zoom-in;
}

/* 提示层不吃点击 —— 事件照旧落到下面的图上，由 app.js 的委托统一处理 */
.el9-mask-shot-tip {
    position: absolute;
    inset: 0;
    z-index: 2;
    justify-content: center;
    padding: 8px;
    background: rgba(255, 255, 255, .52);
    pointer-events: none;
}

.el9-mask-shot.is-open .el9-mask-shot-tip {
    display: none;
}

/* -------------------------------------------------------------------------
 * 404 围人小游戏
 *
 * 单栏：这一页没有「阅读」这回事，右边那栏热门标签 / 分类全是干扰，
 * 还会把本来就窄的正文挤成竖着一条 —— 所以桌面端直接不要侧栏。
 * 主栏让出宽度之后，卡片才能做到 860，棋盘才摆得开。
 *
 * 版式：404 与「标题 / 说明」并排在顶部（中间一条主题色竖线），
 * 下来是「状态 —— 战绩 · 重置」的 HUD 条，再往下棋盘，
 * 最后一条按钮带（左边两个按钮、右边站点域名）。
 *
 * 棋盘尺寸由 JS 按格子算出来写进 canvas 的 width/height，
 * 这里只负责别把手机撑破：max-width 100% + height auto。
 * ---------------------------------------------------------------------- */

/* 只在桌面藏侧栏：手机端侧栏是抽屉，那是导航入口，藏了顶栏的按钮会落空 */
@media screen and (min-width: 1000px), print {
    body:has(.el9-g404) .el9-side {
        display: none;
    }

    body:has(.el9-g404) .el9-layout {
        justify-content: center;
    }
}

.el9-g404 {
    max-width: 760px;
    margin: 0 auto;
    padding: 28px 20px 44px;
}

/* 细边卡片：跟站内其它盒子（外链确认、公告弹窗）同一套语言 */
.el9-g404-card {
    padding: 26px 30px 20px;
    border: 1px solid var(--el9-border);
    border-radius: 16px;
    background: var(--el9-bg);
    box-shadow: 0 2px 14px rgba(0, 0, 0, .04);
}

/* 顶部：大号 404 立左边，标题和说明贴着它，用主题色竖线分一下 */
.el9-g404-head {
    display: flex;
    align-items: center;
    gap: 20px;
}

.el9-g404-code {
    flex: 0 0 auto;
    margin: 0;
    font-size: 52px;
    font-weight: 800;
    line-height: .9;
    letter-spacing: -.04em;
    color: var(--el9-text);
}

.el9-g404-copy {
    min-width: 0;
    padding-left: 20px;
    border-left: 2px solid var(--el9-accent);
}

.el9-g404-title {
    margin: 0;
    font-size: 19px;
    font-weight: 600;
    line-height: 1.35;
    color: var(--el9-text);
}

.el9-g404-desc {
    margin: 4px 0 0;
    font-size: 13px;
    line-height: 1.6;
    color: var(--el9-text-2);
}

/* HUD：状态占左边，战绩贴右，重置收在最后 */
.el9-g404-hud {
    display: flex;
    align-items: center;
    gap: 14px;
    margin: 18px 0 12px;
    padding-top: 16px;
    border-top: 1px solid var(--el9-border);
}

.el9-g404-status {
    margin: 0;
    font-size: 14px;
    font-weight: 500;
    color: var(--el9-text);
    transition: color .2s var(--el9-ease);
}

.el9-g404-status.is-win   { color: #28a745; }
.el9-g404-status.is-lose  { color: var(--el9-accent-text); }
.el9-g404-status.is-warn  { color: #d97706; }
.el9-g404-status.is-trap  { color: #9c27b0; }
.el9-g404-status.is-event { color: #d48806; }

/* 一个可以围的人都没有时，这行字单独站出来 */
.el9-g404-status.is-empty {
    margin: 18px 0 0;
    padding-top: 16px;
    border-top: 1px solid var(--el9-border);
    font-size: 14px;
    font-weight: 400;
    color: var(--el9-text-2);
}

.el9-g404-score {
    margin: 0 0 0 auto;
    font-size: 12.5px;
    color: var(--el9-text-3);
    white-space: nowrap;
}

.el9-g404-score b {
    color: var(--el9-text);
    font-weight: 600;
}

.el9-g404-dot {
    margin: 0 4px;
    color: var(--el9-text-3);
}

.el9-g404-reset {
    flex: 0 0 auto;
    height: 30px;
    padding: 0 13px;
    border: 1px solid var(--el9-border-strong);
    border-radius: var(--el9-r-full);
    background: none;
    color: var(--el9-text-2);
    font-size: 12.5px;
    line-height: 1;
    cursor: pointer;
    transition: color var(--el9-dur) var(--el9-ease), border-color var(--el9-dur) var(--el9-ease);
}

.el9-g404-reset:hover {
    color: var(--el9-accent-text);
    border-color: var(--el9-accent);
}

/* 棋盘装在浅底框里：几十个圆点直接浮在白卡上会显得散 */
.el9-g404-board {
    /* 框宽度跟着棋盘走，别一路顶到卡片边上 —— 两侧空出八十多像素反而像没摆满 */
    width: fit-content;
    max-width: 100%;
    margin: 0 auto;
    padding: 14px;
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-md);
    background: var(--el9-bg-soft);
}

/*
 * JS 会把格子算出来的尺寸直接写成 canvas 的内联 style.width/height。
 * 窄屏要等比缩，就得压住这两个内联值 —— 光写 max-width 只会把宽度缩掉，
 * 高度还是原来那个像素数，棋盘会被拉成一竖条。所以 height 必须 !important。
 */
.el9-g404-board canvas {
    display: block;
    width: auto !important;
    max-width: 100% !important;
    height: auto !important;
    cursor: pointer;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
}

/* 颜色图例：跟棋盘上那四色一一对应（色值见 404.php 那段注释） */
.el9-g404-legend {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 6px 16px;
    margin: 12px 0 0;
    font-size: 12px;
    color: var(--el9-text-3);
}

.el9-g404-legend span {
    display: inline-flex;
    align-items: center;
}

.el9-g404-legend i {
    width: 9px;
    height: 9px;
    margin-right: 5px;
    border-radius: 50%;
    background: #b3d9ff;
}

.el9-g404-legend .is-wall { background: #34495e; }
.el9-g404-legend .is-trap { background: #ce93d8; }
.el9-g404-legend .is-lucky { background: #ffd700; }

/* 棋盘下面那行玩法说明：小字、压淡，看完就可以忽略 */
.el9-g404-howto {
    margin: 10px 2px 0;
    font-size: 12px;
    line-height: 1.65;
    text-align: center;
    color: var(--el9-text-3);
}

/* 按钮带：按钮靠左排，域名收到最右 */
.el9-g404-acts {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 16px;
    padding-top: 16px;
    border-top: 1px solid var(--el9-border);
}

.el9-g404-acts .el9-btn {
    min-width: 128px;
    height: 40px;
    border-radius: 10px;
}

.el9-g404-site {
    margin-left: auto;
    font-family: ui-monospace, Menlo, Consolas, monospace;
    font-size: 12.5px;
    color: var(--el9-text-3);
}

@media screen and (max-width: 700px) {
    .el9-g404 {
        padding: 18px 12px 44px;
    }

    .el9-g404-card {
        padding: 22px 16px 18px;
        border-radius: 14px;
    }

    .el9-g404-head {
        gap: 14px;
    }

    .el9-g404-code {
        font-size: 44px;
    }

    .el9-g404-copy {
        padding-left: 14px;
    }

    .el9-g404-title {
        font-size: 17px;
    }

    .el9-g404-desc {
        font-size: 13px;
    }

    .el9-g404-hud {
        flex-wrap: wrap;
        gap: 10px;
        margin-top: 20px;
    }

    /* 战绩到手机上另起一行，不然跟状态挤在一起谁都读不顺 */
    .el9-g404-score {
        flex: 1 0 100%;
        margin-left: 0;
        order: 3;
    }

    .el9-g404-reset {
        margin-left: auto;
        order: 2;
    }

    .el9-g404-board {
        padding: 10px;
    }

    .el9-g404-acts {
        flex-wrap: wrap;
    }

    .el9-g404-acts .el9-btn {
        flex: 1;
        min-width: 0;
    }

    .el9-g404-site {
        flex: 1 0 100%;
        margin-left: 0;
        text-align: center;
    }
}

/* 「我们的故事」页里的战绩小条 */
.el9-myc-game {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px 10px;
    margin: 14px 0 4px;
    padding: 10px 14px;
    border: 1px solid var(--el9-border);
    border-radius: 10px;
    background: var(--el9-bg-soft);
    font-size: 13px;
    color: var(--el9-text-2);
}

.el9-myc-game .el9-icon {
    color: var(--el9-accent);
}

.el9-myc-game b {
    color: var(--el9-text);
    font-weight: 600;
}

/* ------------------------------------------------------------------
 * 今日一签：侧栏那块小卡 + 两个抽签页
 *
 * 侧栏只负责「报今天的结果 + 给两条入口」；
 * 抽的过程在 /liuren.html 和 /zhouyi.html 各自的页面里。
 * ------------------------------------------------------------------ */

/* ---- 侧栏 ---- */

.el9-ft-brief {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px;
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-lg);
    background: var(--el9-bg);
    /* 这一块整块是个链接：点哪都能进摇卦页看详情 */
    text-decoration: none;
    color: inherit;
    transition: border-color var(--el9-dur) var(--el9-ease), background var(--el9-dur) var(--el9-ease);
}

.el9-ft-brief:hover {
    border-color: var(--el9-accent);
    background: var(--el9-accent-soft);
}

/* 有变爻那几句标红：侧栏画不了六爻，至少得让人知道这卦有动 */
.el9-ft-bian {
    color: var(--el9-danger);
}


.el9-ft-orb {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: var(--el9-r-full);
    background: var(--el9-bg-soft);
    color: var(--el9-text-3);
    font-size: 17px;
    font-weight: 600;
    line-height: 1;
    transition: background var(--el9-dur) var(--el9-ease), color var(--el9-dur) var(--el9-ease);
}

.el9-ft-orb.is-drawn {
    background: var(--el9-accent-soft);
    color: var(--el9-accent);
}

/*
 * 周易那一支圆里原本放的是卦符字（䷀ ䷁ 这种），现在改成自己画的六爻。
 *
 * 原因：U+4DC0 那批符号是整块字形，没法只把其中一爻点红。
 * 既然要标出「哪一爻在动」，就得一条一条画 —— 圆里于是变成纵向排列的六条线。
 */
.el9-ft-orb.is-hex {
    /* column-reverse 跟周易页一致：DOM 第一条是最下爻，得让它落在最下面。
       写成 column 的话整卦上下颠倒 —— 乾坤这种上下同体的看不出来，既济、未济就露了。 */
    flex-direction: column-reverse;
    gap: 3px;
}

/*
 * 侧栏版六爻：40px 圆里塞六条，比周易页那版（160 宽 / 9 高）小一圈。
 * 18 × 2 配 3 的间距 = 竖向 27px，圆里上下还能各留 6px。
 * 数字都取整像素 —— 半像素在 1px 线上会糊成灰边。
 */
.el9-ft-line {
    display: flex;
    gap: 4px;
    width: 18px;
    height: 2px;
}

.el9-ft-line i {
    flex: 1;
    border-radius: 1px;
    background: var(--el9-text);
}

/* 变爻（老阳 / 老阴）那一条标红，跟周易页同一套颜色 */
.el9-ft-line.is-bian i {
    background: var(--el9-danger);
}

.el9-ft-txt {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.el9-ft-txt strong {
    font-size: 15px;
    color: var(--el9-text);
    line-height: 1.3;
}

.el9-ft-txt small {
    font-size: 12px;
    color: var(--el9-text-3);
    line-height: 1.4;
}

.el9-ft-links {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
    margin-top: 10px;
}

.el9-ft-link {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 34px;
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-full);
    color: var(--el9-text-2);
    font-size: 13px;
    font-weight: 500;
    text-decoration: none;
    transition: color var(--el9-dur) var(--el9-ease), background var(--el9-dur) var(--el9-ease),
        border-color var(--el9-dur) var(--el9-ease);
}

.el9-ft-link:hover {
    border-color: var(--el9-accent);
    color: var(--el9-accent);
}

/* ---- 抽签页：单页版式 ---- */

/*
 * 这两页不留侧栏。
 *
 * 抽签是「聚焦一件事」的动作，旁边挂一排最新评论、热门标签，注意力就散了。
 * 用 :has 判断当前主栏里是不是抽签页，不用去 header.php 加开关 ——
 * 页面版式是模板自己的事，不该动公共骨架。
 */
.el9-layout:has(.el9-fp) .el9-side {
    display: none;
}

.el9-layout:has(.el9-fp) .el9-main {
    /* 侧栏没了，主栏撑满；内容宽度交给 .el9-fp 自己封顶 */
    flex: 1 1 auto;
    max-width: none;
}

.el9-fp {
    width: 100%;
    max-width: 480px;
    margin: 0 auto;
    padding: var(--el9-4) 0 var(--el9-5);
    text-align: center;
}

/* ---- 抬头 ---- */

.el9-fp-title {
    margin: 0 0 7px;
    font-size: 23px;
    font-weight: 600;
    letter-spacing: .16em;
    text-indent: .16em;
    line-height: 1.3;
}

.el9-fp-lead {
    margin: 0;
    font-size: 12px;
    /* 原版那两页的副标题是「此 刻 · 心 念 · 一 签」，字距拉开才有那个味道 */
    letter-spacing: .2em;
    text-indent: .2em;
    color: var(--el9-text-3);
}

/* ---- 表单：生日 / 取数方式 ---- */

.el9-fp-field {
    margin-top: 10px;
    text-align: left;
}

.el9-fp-label {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    margin-bottom: 5px;
    font-size: 10.5px;
    letter-spacing: .14em;
    color: var(--el9-text-3);
}

.el9-fp-label small {
    font-size: 10px;
    letter-spacing: .06em;
    opacity: .8;
}

.el9-fp-date {
    width: 100%;
    height: 42px;
    padding: 0 14px;
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-lg);
    background: var(--el9-bg-soft);
    font-family: inherit;
    font-size: 14px;
    color: var(--el9-text);
    -webkit-appearance: none;
    appearance: none;
    outline: none;
    transition: border-color var(--el9-dur) var(--el9-ease);
}

.el9-fp-date:focus {
    border-color: var(--el9-accent);
}

.el9-fp-date::-webkit-calendar-picker-indicator {
    opacity: .45;
    cursor: pointer;
}

/* 分段选择：三个取数口径 */
.el9-fp-seg {
    display: flex;
    gap: 2px;
    padding: 3px;
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-lg);
    background: var(--el9-bg-soft);
}

.el9-fp-seg button {
    flex: 1;
    height: 27px;
    border: 0;
    border-radius: calc(var(--el9-r-lg) - 4px);
    background: transparent;
    color: var(--el9-text-3);
    font-family: inherit;
    font-size: 12px;
    white-space: nowrap;
    cursor: pointer;
    transition: color var(--el9-dur) var(--el9-ease), background var(--el9-dur) var(--el9-ease);
}

.el9-fp-seg button.is-active {
    background: var(--el9-bg);
    color: var(--el9-accent);
    font-weight: 600;
    box-shadow: 0 1px 4px rgba(0, 0, 0, .07);
}

.el9-fp-seg button:disabled {
    opacity: .5;
    cursor: default;
}

/*
 * 生日取数的勾选框
 *
 * 用原生 checkbox 配 accent-color —— 自己画一个方框加对勾要写一堆伪元素，
 * 而且键盘、读屏、触控尺寸都得再补一遍，原生控件这些全是现成的。
 */
.el9-fp-check {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 12px;
    padding: 2px 0;
    font-size: 12px;
    letter-spacing: .1em;
    color: var(--el9-text-2);
    text-align: left;
    cursor: pointer;
    user-select: none;
}

.el9-fp-check input {
    flex: 0 0 auto;
    width: 15px;
    height: 15px;
    margin: 0;
    accent-color: var(--el9-accent);
    cursor: pointer;
}

.el9-fp-check small {
    font-size: 10.5px;
    letter-spacing: .06em;
    color: var(--el9-text-3);
}

/* ---- 当前 / 农历 ---- */

.el9-fp-info {
    margin: 11px 0 0;
    padding: 4px 2px;
    border-top: 1px solid var(--el9-border);
    border-bottom: 1px solid var(--el9-border);
}

.el9-fp-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    padding: 2px 0;
    font-size: 12.5px;
    line-height: 1.5;
    text-align: left;
}

/* hidden 属性会被上面的 display:flex 盖掉，这里显式收回来 */
.el9-fp-row[hidden] {
    display: none;
}

.el9-fp-row .k {
    flex: 0 0 auto;
    color: var(--el9-text-3);
    letter-spacing: .1em;
    font-size: 11px;
}

.el9-fp-row .v {
    color: var(--el9-text-2);
    font-weight: 500;
    text-align: right;
    margin-left: auto;
}

/* ---- 取数算式 ---- */

.el9-fp-calc {
    margin-top: 10px;
    padding: 9px 12px 8px;
    border: 1px dashed var(--el9-border);
    border-radius: var(--el9-r-lg);
    background: var(--el9-bg-soft);
}

.el9-fp-nums {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.el9-fp-eq {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 14px;
}

.el9-fp-eq .tag {
    flex: 0 0 auto;
    width: 40px;
    font-family: inherit;
    font-size: 10.5px;
    letter-spacing: .14em;
    color: var(--el9-text-3);
}

.el9-fp-eq .expr {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    flex-wrap: wrap;
    gap: 3px;
    flex: 1;
    color: var(--el9-text-3);
}

.el9-fp-eq .n {
    color: var(--el9-accent);
    font-weight: 600;
}

/* 生日那一行用另一个颜色，一眼分得清哪几个数是生日的 */
.el9-fp-eq .n.is-birth {
    color: var(--el9-text-2);
}

.el9-fp-eq .p,
.el9-fp-eq .eq {
    color: var(--el9-text-3);
    opacity: .55;
}

.el9-fp-eq .sum {
    color: var(--el9-accent);
    font-weight: 700;
    font-size: 16px;
}

.el9-fp-eq .sum.is-big {
    font-size: 21px;
}

.el9-fp-eq.is-total {
    margin-top: 2px;
    padding-top: 9px;
    border-top: 1px solid var(--el9-border);
}

.el9-fp-hint {
    margin: 8px 0 0;
    font-size: 10.5px;
    line-height: 1.75;
    letter-spacing: .04em;
    color: var(--el9-text-3);
    text-align: center;
}

/* ---- 六神格子（跑马灯就在这上面走） ---- */

.el9-fp-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 6px;
    margin: 11px 0 3px;
}

.el9-fp-cell {
    padding: 8px 0;
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-md);
    background: var(--el9-bg-soft);
    color: var(--el9-text-3);
    font-size: 15px;
    letter-spacing: .1em;
    text-indent: .1em;
    text-align: center;
    transition: transform .12s ease, background .12s ease, color .12s ease, box-shadow .12s ease;
}

/*
 * 跑马灯亮起的那一格 / 最后停住的那一格
 *
 * 只把边框和字染成主题色，底色不动 ——
 * 整格铺蓝再配白字，六格轮流闪起来像一排警报灯，签反而被淹没。
 * 描边亮起来已经够抓眼，而且跟「选中」这个语义更贴。
 */
.el9-fp-cell.is-on {
    border-color: var(--el9-accent);
    background: var(--el9-bg);
    color: var(--el9-accent);
    transform: translateY(-1px);
}

/* ---- 结果 ---- */

.el9-fp-result {
    min-height: 84px;
    padding: 9px 0 2px;
}

.el9-fp-name {
    display: block;
    font-size: 28px;
    font-weight: 600;
    letter-spacing: .18em;
    text-indent: .18em;
    line-height: 1.25;
    /* 结果用正文色：一页里已经有两处蓝（描边的格子、按钮），再蓝就糊成一片 */
    color: var(--el9-text);
}

.el9-fp-name.is-idle {
    color: var(--el9-text-3);
    opacity: .55;
}

.el9-fp-meta {
    display: block;
    margin-top: 6px;
    font-size: 11.5px;
    letter-spacing: .12em;
    color: var(--el9-text-3);
}

.el9-fp-text {
    margin: 8px 0 0;
    font-size: 13px;
    line-height: 1.8;
    color: var(--el9-text-2);
}

/* ---- 按钮 ---- */

.el9-fp-btn {
    display: block;
    width: 100%;
    height: 42px;
    margin: 11px 0 0;
    border: 0;
    border-radius: var(--el9-r-full);
    background: var(--el9-accent-soft);
    color: var(--el9-accent);
    font-family: inherit;
    font-size: 15px;
    font-weight: 600;
    letter-spacing: .16em;
    text-indent: .16em;
    cursor: pointer;
    transition: background var(--el9-dur) var(--el9-ease), color var(--el9-dur) var(--el9-ease),
        transform var(--el9-dur) var(--el9-ease), opacity var(--el9-dur) var(--el9-ease);
}

.el9-fp-btn:hover {
    background: var(--el9-accent);
    color: var(--el9-accent-contrast);
}

.el9-fp-btn:active {
    transform: scale(.98);
}

/*
 * 抽完这一天就锁了。必须写 :disabled —— 不写的话鼠标移上去照样变蓝底，
 * 用户会以为能点，点了没反应更难受。
 */
.el9-fp-btn:disabled {
    background: var(--el9-bg-soft);
    color: var(--el9-text-3);
    cursor: default;
    pointer-events: none;
}

.el9-fp-btn.is-locked {
    background: var(--el9-bg-soft);
    color: var(--el9-text-3);
}

/* ---- 生日弹层 ---- */

/*
 * 勾选框点开才出来的那一块。
 *
 * 用 fixed 铺满视口 + 居中一张卡 —— 不这样的话，页面滚到中间点勾选，
 * 弹窗出现在文档流里，人还得往下找。
 */
.el9-fp-modal {
    position: fixed;
    inset: 0;
    z-index: 120;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
}

.el9-fp-modal[hidden] {
    display: none;
}

.el9-fp-modal-mask {
    position: absolute;
    inset: 0;
    background: rgba(15, 20, 25, .45);
    animation: el9-fp-fade .18s var(--el9-ease);
}

.el9-fp-modal-panel {
    position: relative;
    width: 100%;
    max-width: 360px;
    max-height: calc(100vh - 40px);
    overflow-y: auto;
    padding: 22px 20px 18px;
    border-radius: var(--el9-r-xl);
    background: var(--el9-bg);
    box-shadow: 0 24px 60px -20px rgba(15, 20, 25, .42);
    text-align: left;
    animation: el9-fp-pop .2s cubic-bezier(.2, .8, .3, 1);
}

.el9-fp-modal-title {
    margin: 0 0 14px;
    font-size: 16px;
    font-weight: 600;
    letter-spacing: .06em;
    text-align: center;
    color: var(--el9-text);
}

/* 弹层里第一组别再顶一层外边距，标题下面留白已经够了 */
.el9-fp-modal .el9-fp-field:first-of-type {
    margin-top: 0;
}

.el9-fp-modal-foot {
    display: flex;
    gap: 10px;
    margin-top: 18px;
}

.el9-fp-modal-btn {
    flex: 1;
    height: 42px;
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-full);
    background: transparent;
    color: var(--el9-text-2);
    font-family: inherit;
    font-size: 14px;
    cursor: pointer;
    transition: background var(--el9-dur) var(--el9-ease), color var(--el9-dur) var(--el9-ease),
        border-color var(--el9-dur) var(--el9-ease);
}

.el9-fp-modal-btn:hover {
    border-color: var(--el9-accent);
    color: var(--el9-accent);
}

.el9-fp-modal-btn.is-primary {
    border-color: transparent;
    background: var(--el9-accent-soft);
    color: var(--el9-accent);
    font-weight: 600;
}

.el9-fp-modal-btn.is-primary:hover {
    background: var(--el9-accent);
    color: var(--el9-accent-contrast);
}

/* 没选日期时「完成」不能点：空生日进算式毫无意义 */
.el9-fp-modal-btn:disabled {
    opacity: .45;
    cursor: default;
    pointer-events: none;
}

@keyframes el9-fp-fade {
    from { opacity: 0; }
    to { opacity: 1; }
}

@keyframes el9-fp-pop {
    from { opacity: 0; transform: translateY(10px) scale(.98); }
    to { opacity: 1; transform: none; }
}

/* ---- 页脚那条 ---- */

.el9-fp-foot {
    margin: 11px 0 0;
    font-size: 13px;
}

.el9-fp-foot a {
    color: var(--el9-text-3);
    text-decoration: none;
    border-bottom: 1px dashed var(--el9-border);
    padding-bottom: 2px;
}

.el9-fp-foot a:hover {
    color: var(--el9-accent);
    border-color: var(--el9-accent);
}

/*
 * 页面最下面那行小字：说明推算全在本地、不往服务器送东西。
 *
 * 抽签这种东西，用户最怕的是「我的生日被记下来了」—— 明说一句，
 * 比藏在隐私政策里管用。字号压到 11、颜色压到最浅，属于「有，但不打扰」。
 */
.el9-fp-note {
    max-width: 360px;
    margin: 16px auto 0;
    font-size: 11px;
    line-height: 1.75;
    letter-spacing: .02em;
    color: var(--el9-text-3);
    text-align: center;
    opacity: .85;
}

/* ---- 周易：翻牌 ---- */

/*
 * 两个面背对背贴在同一个格子里（grid-area 1/1），
 * 容器高度由较高的那一面决定 —— 翻的时候页面不会跳。
 */
.el9-fp-flip {
    margin: 18px 0 0;
    perspective: 1400px;
}

.el9-fp-flip-inner {
    display: grid;
    position: relative;
    transform-style: preserve-3d;
    transition: transform .55s cubic-bezier(.4, .1, .2, 1);
}

.el9-fp-flip.is-front .el9-fp-flip-inner {
    transform: rotateY(180deg);
}

.el9-fp-face {
    grid-area: 1 / 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 300px;
    padding: 26px 20px;
    border: 1px solid var(--el9-border);
    border-radius: var(--el9-r-xl);
    background: var(--el9-bg);
    backface-visibility: hidden;
    -webkit-backface-visibility: hidden;
}

.el9-fp-face.is-front {
    transform: rotateY(180deg);
}

/* 背面：太极 + 提示 */
.el9-fp-taiji {
    font-size: 54px;
    line-height: 1;
    color: var(--el9-text-3);
    opacity: .65;
}

.el9-fp-back-txt {
    margin: 14px 0 0;
    font-size: 14px;
    letter-spacing: .3em;
    text-indent: .3em;
    color: var(--el9-text-2);
}

.el9-fp-back-sub {
    margin-top: 8px;
    font-size: 12px;
    letter-spacing: .12em;
    color: var(--el9-text-3);
}

/* 正面：卦 */
.el9-fp-gua-no {
    font-size: 12px;
    letter-spacing: .1em;
    color: var(--el9-text-3);
}

/*
 * 六爻：从下往上排。
 *
 * DOM 里第一条是最下爻，靠 column-reverse 让它落在最下面 ——
 * 这样 JS 只管按「下卦在前」的顺序往里塞，不用反过来拼。
 */
.el9-fp-lines {
    display: flex;
    flex-direction: column-reverse;
    gap: 12px;
    margin: 14px 0 18px;
}

/*
 * 线细一档、间距大一档：10 高配 9 间距时六条糊成一块条纹布，
 * 红黑相间更看不出哪几条是变爻。9 配 12，爻与爻之间能喘口气。
 */
.el9-fp-line {
    display: flex;
    gap: 26px;
    width: 160px;
    height: 9px;
}

.el9-fp-line i {
    flex: 1;
    border-radius: 2px;
    background: var(--el9-text);
}

/*
 * 变爻（老阳 / 老阴）标红。
 *
 * 三枚铜钱法里三正、三反各占 1/8，一爻是变爻的概率 1/4 ——
 * 六爻各掷一次，所以一卦可能一个不动，也可能六个全动。
 */
.el9-fp-line.is-bian i {
    background: var(--el9-danger);
}

.el9-fp-gua-name {
    margin: 0;
    font-size: 24px;
    font-weight: 600;
    letter-spacing: .1em;
    line-height: 1.35;
    color: var(--el9-text);
}

.el9-fp-gua-tri {
    margin-top: 8px;
    font-size: 12px;
    letter-spacing: .08em;
    color: var(--el9-text-3);
}

.el9-fp-sep {
    width: 40px;
    height: 1px;
    margin: 15px auto;
    background: var(--el9-border);
}

.el9-fp-gua-ci {
    margin: 0;
    font-size: 14px;
    line-height: 1.9;
    color: var(--el9-text-2);
}

.el9-fp-gua-jie {
    margin: 8px 0 0;
    font-size: 13px;
    line-height: 1.85;
    color: var(--el9-text-3);
}

/* ---- 周易：连抽三次的提示 ---- */

.el9-fp-toast {
    position: fixed;
    left: 50%;
    bottom: 88px;
    z-index: 90;
    max-width: 76vw;
    padding: 11px 18px;
    border-radius: var(--el9-r-full);
    background: rgba(18, 20, 24, .9);
    color: #fff;
    font-size: 13px;
    line-height: 1.5;
    text-align: center;
    opacity: 0;
    transform: translate(-50%, 12px);
    pointer-events: none;
    transition: opacity .28s var(--el9-ease), transform .28s var(--el9-ease);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
}

.el9-fp-toast.is-show {
    opacity: 1;
    transform: translate(-50%, 0);
}

@media screen and (max-width: 699px) {
    .el9-fp {
        /*
         * 底部多留一截：窄屏有悬浮底栏（最新 / 说说 / 搜索 / 友链）压在最下层，
         * 按常规间距算，页面最后一个按钮正好被它盖住一半。
         */
        padding: var(--el9-4) 0 calc(var(--el9-5) + 64px);
    }

    .el9-fp-title {
        font-size: 22px;
    }

    .el9-fp-name {
        font-size: 28px;
    }

    .el9-fp-face {
        min-height: 270px;
        padding: 22px 16px;
    }

    .el9-fp-line {
        width: 140px;
    }
}

/* ==========================================================================
   打印（文章页底部那颗打印机按钮触发）
   ==========================================================================

   目标：纸上只留「标题 + 信息 + 正文 + 脚注」。
   导航、侧栏、评论、上下篇、悬浮钮、底栏这些在纸上全是干扰，
   而且它们带背景色和固定定位，打出来会盖在正文上。

   用 !important 是因为这些元素平时带 backdrop-filter、box-shadow、
   display:flex 之类的规则，权重都不低，不压一层盖不住。
   ========================================================================== */

/*
 * 纸张四边留白：统一在这里定，别交给设备
 *
 * 之前页面里一条 @page 都没有，而且打印样式把 html / body / 容器
 * 的 margin、padding 全清零了 —— 正文直接贴着浏览器划出的「可打印区」排。
 * 于是那圈天地留白全看设备：Chrome/Edge、Safari、iOS AirPrint、
 * 打印机驱动、还有打印对话框里用户自己选的「边距 / 纸张 / 缩放 / 页眉页脚」，
 * 每台都不同，同一篇文章打出来页头页尾差一大截。
 *
 * 这里用 mm 这种物理单位（不随屏幕像素、DPI、缩放变）把四边钉死。
 * 只定边距、不塞正文里，是因为往 body 上加 padding 会在每一页顶部
 * 都叠一层，分页处反而更乱；@page 的 margin 才是分页媒体正规的天头地脚。
 *
 * 不写 !important，也不碰屏幕样式：@page 只对分页媒体生效。
 * 打印对话框里另选了纸张尺寸的，浏览器以用户选的为准。
 *
 * Safari / iOS Safari 到 18.2 才开始认 @page 的 margin 和 size，
 * 更早的 WebKit 连这条都忽略，那些设备上留白仍由系统决定。
 */
@page {
    size: A4;
    margin: 18mm 16mm;
}

/*
 * 页眉页脚：纸面上只留一行 8pt 灰字
 *
 * 主题本来不打印页头页尾，纸上那两行小字是浏览器打印界面自己加的
 * （网址、标题、日期、页码），不在网页 DOM 里，CSS 删不掉。
 *
 * 下面用的是 @page 的 margin box（@top-left / @bottom-right …）。
 * 兼容性只认一条：**只有 Chromium 系支持**（Chrome / Edge 131+）。
 * Apple 在 Safari 18.2 加的是「@page 页边距描述符」（margin / size），
 * 并没有支持 margin box；Firefox、iOS Safari、多数手机自带浏览器也不认。
 * 这些浏览器会整块忽略下面的规则，纸上仍是它自带的默认页眉页脚 ——
 * 这层只能去打印对话框里关（iPhone：分享 → 打印 → 选项 → 关「页眉和页脚」；
 * iOS 17+ 没开关就点缩略图下方「更多」，把页眉页脚输入框清空）。
 *
 * 还有一层：Chrome 就算画出了 margin box，打印预览里若勾着
 * 「页眉和页脚」，它自带的仍会叠上来，得在预览里取消勾选。
 *
 *   页眉左  个人成长计划
 *   页眉右  当前文章标题   ┐ 每篇都不同，写不死，由 app.js 在打印那一刻
 *   页脚左  原文链接       ┘ 生成一条完整的 @page 覆盖下面这份
 *   页脚右  第 N 页 / 共 M 页 —— counter(page) / counter(pages) 浏览器自己数
 *
 * 所以这里这份是**静态兜底**：JS 没跑成（脚本被拦、直接另存 PDF）时
 * 至少还有站点名、域名和页码，不会开天窗；那时页眉右留空、页脚左是域名。
 * 另外三格写空字符串，是让认 margin box 的浏览器把这几格占住、
 * 别再画自带的网址和日期。字号用 pt、颜色用灰，落在 18mm 页边距里，
 * 不抢正文。margin box 不继承页面字体，所以三处各自写一遍 font-family。
 *
 * 单独拆一块写，是为了不认识 margin box 的浏览器顶多忽略这一块，
 * 上面那条 size / margin 照样生效，不会整条 @page 一起失效。
 */
@page {
    @top-left {
        content: "个人成长计划";
        font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Microsoft YaHei", sans-serif;
        font-size: 8pt;
        color: #888;
    }

    @top-center { content: ""; }
    @top-right { content: ""; }

    @bottom-left {
        content: "blog.el9.cn";
        font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Microsoft YaHei", sans-serif;
        font-size: 8pt;
        color: #888;
    }

    @bottom-center { content: ""; }

    @bottom-right {
        content: "第 " counter(page) " 页 / 共 " counter(pages) " 页";
        font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Microsoft YaHei", sans-serif;
        font-size: 8pt;
        color: #888;
    }
}

@media print {
    /* ---- 1. 该藏的全藏掉 ---- */
    .el9-sitenav,
    .el9-sidenav,
    .el9-side,
    .el9-toc-rail,
    .el9-near,
    .el9-article-actions,
    .el9-backtop,
    .el9-gobottom,
    .el9-fab,
    /*
     * 这两条是 fixed 的细横条（文章阅读进度 / PJAX 换页进度）。
     * iOS Safari 打印会把 fixed 元素重复画到每一页，第二页就多出一条
     * 横穿整页的线压在正文上 —— 屏幕正文里根本没有这条线。
     * 之前漏了 .el9-progress，实测它是 print 媒体下唯一还活着的 fixed 元素。
     */
    .el9-progress,
    .el9-pjax-bar,
    .el9-tabbar,
    .el9-drawer,
    .el9-drawer-backdrop,
    .el9-lightbox,
    .el9-composer,
    .el9-gnotice,
    .el9-carousel,
    .el9-feedbar,
    .el9-edit,
    .el9-share-tip,
    .el9-pager,
    .el9-backpath {
        display: none !important;
    }

    /*
     * 评论默认不打印。
     * 点打印时弹的那个菜单选「连评论一起」，会给 body 挂 el9-print-with-comments，
     * 下面那条特异性更高，就把评论区放出来了。
     */
    .el9-comments {
        display: none !important;
    }

    body.el9-print-with-comments .el9-comments {
        display: block !important;
        /* 评论另起一页，不接着正文往下排 —— 接着排的话第一条评论常常被挤到页脚 */
        page-break-before: always;
        break-before: page;
        margin-top: 0;
        padding-top: 0;
        border-top: 0;
    }

    /* 光是「评论内容」要打，发评论的表单、分页、弹层都不要 */
    body.el9-print-with-comments .el9-respond,
    body.el9-print-with-comments .el9-comment-pager,
    body.el9-print-with-comments .el9-fieldbox,
    body.el9-print-with-comments .el9-comments-closed {
        display: none !important;
    }

    /* 一条评论别被劈到两页 */
    body.el9-print-with-comments .el9-comment-list > * {
        page-break-inside: avoid;
        break-inside: avoid;
    }

    /*
     * 纸上点不了的东西都收掉：
     * 「回复」是个带 ?replyTo= 的链接（没有专属类名，只能按 href 认），
     * 「正序 / 倒序」是操作控件，打印出来只会让人以为能点。
     */
    body.el9-print-with-comments .el9-comment-list a[href*="replyTo="],
    body.el9-print-with-comments [data-el9-cmt-order] {
        display: none !important;
    }

    /* ---- 2. 版面铺满整张纸 ---- */
    html,
    body {
        background: #fff !important;
        color: #000 !important;
    }

    /*
     * 分页高度全交给内容自己算，别留屏幕上的 100vh。
     *
     * .el9-main 平时是 min-height: 100vh（把页脚顶到屏幕底部）。
     * 打印时这个 100vh 在部分安卓内核里被算成「整整一页」：主栏先占满一页，
     * 文章头、正文、图片再往里排，只要多出一点点就溢出到下一页 ——
     * 最后多出一张几乎全白的纸，就是手机上偶发的「空白页」。
     * 实测打印媒体下它仍是 min-height: 950px，其余容器都是 0。
     */
    html,
    body,
    .el9-layout,
    .el9-main,
    .el9-article {
        height: auto !important;
        min-height: 0 !important;
        overflow: visible !important;
    }

    .el9-layout {
        display: block !important;
        max-width: none !important;
        padding: 0 !important;
        margin: 0 !important;
        gap: 0 !important;
    }

    .el9-main {
        max-width: none !important;
        width: 100% !important;
        margin: 0 !important;
        padding: 0 !important;
    }

    /* 卡片在纸上没有意义：去掉边框、阴影、圆角和内边距 */
    .el9-article {
        border: 0 !important;
        border-radius: 0 !important;
        box-shadow: none !important;
        background: #fff !important;
        padding: 0 !important;
        margin: 0 !important;
    }

    /* 文章封面是装饰，打印时省一张纸的墨 */
    .el9-article-cover {
        display: none !important;
    }

    /* ---- 3. 正文排版按纸来 ---- */
    .el9-content {
        font-size: 11.5pt;
        line-height: 1.75;
        color: #000 !important;
    }

    .el9-content h2,
    .el9-content h3,
    .el9-content h4 {
        /* 标题别孤零零留在页面底部 */
        page-break-after: avoid;
        break-after: avoid;
    }

    .el9-content img,
    .el9-content blockquote,
    .el9-content table,
    .el9-content .el9-img-grid {
        /* 图、引用、表格别被劈成两页 */
        page-break-inside: avoid;
        break-inside: avoid;
        max-width: 100% !important;
    }

    /*
     * 代码块相反：**必须允许跨页**。
     *
     * 之前把它也写进了上面那条「不许拆」，结果一段比一页还长的代码，
     * 浏览器不肯拆，就直接把超出纸张的那部分裁掉 —— 打印出来只剩前半截，
     * 而且完全看不出是被裁的。这正是「代码打印不全」的真正原因。
     *
     * 另外 pre 平时是 overflow: hidden（配合圆角），跨页时同样会裁内容，一起放开。
     */
    .el9-content pre {
        page-break-inside: auto !important;
        break-inside: auto !important;
        overflow: visible !important;
        max-height: none !important;
    }

    .el9-content img {
        height: auto !important;
    }

    /* 代码块在纸上没有横向滚动，允许折行 */
    .el9-content pre code {
        white-space: pre-wrap !important;
        word-break: break-word;
    }

    /* ---- 4. 链接把地址印出来 ---- */
    /*
     * 纸上点不了，所以站外链接后面补上真实地址。
     * 锚点（脚注编号、目录跳转）不补 —— 补了只是噪声。
     */
    .el9-content a[href^="http"]::after {
        content: " (" attr(href) ")";
        font-size: .8em;
        color: #555;
        word-break: break-all;
    }

    .el9-content a[href^="#"]::after,
    .el9-content .footnote-ref::after,
    .el9-content .footnote-backref::after {
        content: "" !important;
    }

    /*
     * 代码块在纸上要完整。
     *
     * .el9-code-body 平时是 flex + overflow-x: auto（横向滚动容器），
     * 打印时它按「可视宽度」裁掉右边超出部分 —— 长代码直接少半截，
     * 而且不会报错，看起来就像「打印内容不全」。
     * 这里放开 overflow，配合上面 code 的 pre-wrap 让它折行。
     */
    /*
     * 只放开 overflow，**不要改成 display: block**。
     *
     * .el9-code-body 是 flex：左边行号列、右边代码，横向并排。
     * 之前图省事写了 display: block，行号列立刻变成块级元素占满整行，
     * 代码被挤到它下面 —— 打印出来就是「一堆行号堆在上边，代码掉到最下面」。
     */
    .el9-code-body {
        overflow: visible !important;
    }

    /*
     * 行号要留着 —— 打印代码就是为了对着行号看，删掉等于白打。
     *
     * 但行号列和代码是两块独立元素，代码一折行，行号就再也对不上了。
     * 所以打印时代码**不折行**（white-space: pre），靠缩字号让它塞进纸宽：
     * A4 正文区约 190mm，8pt 等宽字体一行能放 110 多个字符，够用。
     * 真遇到超长的行还是会超出，但那种行在屏幕上也一样要横向滚。
     */
    /*
     * 行号列和代码是两块独立元素，要对齐必须三项完全一致：
     * 字体、字号、行高。少一项就会逐行漂移 ——
     * 实测只改字号时，40 行的代码块，行号总高 1116、代码 1170，差了 54px。
     */
    .el9-content pre,
    .el9-content pre code,
    .el9-code-ln {
        font-family: var(--el9-font-mono) !important;
        font-size: 8pt !important;
        line-height: 1.45 !important;
    }

    .el9-content pre code {
        /* 不折行：一折行行号就对不上，宁可缩字号让它塞进去 */
        white-space: pre !important;
    }

    /* 语言标签是装饰，纸上没用 */
    .el9-code-lang {
        display: none !important;
    }

    /* ---- 5. 脚注跟着正文走，别单独占一页 ---- */
    .el9-content .footnotes {
        page-break-inside: auto;
        border-top-color: #999;
    }
}

/* ==========================================================================
   打印：分页与密度（补在上面的打印规则之后，靠后覆盖）
   ==========================================================================

   上一版打印只处理了「藏掉不相关的东西」，分页这件事基本靠浏览器自己判断，
   结果出了三个毛病：

   1. 一篇 28 张截图的长文打出 13 页 —— 正文 11.5pt / 行高 1.75 太松，
      标题上下还各留 40px 和 32px，纸上到处是空白。
   2. 图片被切成两半 —— 图是包在 <p> 里的，页界把 <p> 切开时，
      里面的图跟着断。只给 img 加 break-inside: avoid 没用，得管住包裹它的那块。
   3. 标题被页界切掉一半 —— 之前只写了 break-after: avoid（别孤零零留在页底），
      没写 break-inside: avoid，标题自己照样能被劈开。

   下面按这三条对症改。
   ========================================================================== */
@media print {
    /* ---- 1. 排密一点：正文按五号字（10pt），行高跟着收 ---- */
    .el9-content {
        font-size: 10pt;
        line-height: 1.6;
    }

    .el9-content p {
        margin: 0 0 .6em;
    }

    /* ---- 2. 标题：不许被页界切开，也别孤零零掉到页底 ---- */
    .el9-content h1,
    .el9-content h2,
    .el9-content h3,
    .el9-content h4 {
        break-inside: avoid;
        page-break-inside: avoid;
    }

    .el9-content h2 {
        margin: 13px 0 7px;
        font-size: 14pt;
    }

    .el9-content h3 {
        margin: 10px 0 6px;
        font-size: 12pt;
    }

    .el9-content h4 {
        margin: 11px 0 6px;
        font-size: 10.5pt;
    }

    /* ---- 3. 图和它的包裹块一起走，但别把所有段落都钉死 ---- */
    /*
     * 正文里的图几乎都套在 <p> 或 .el9-img-grid 里。只给 img 写
     * break-inside: avoid 挡不住 —— 浏览器切的是外层那个 <p>，图跟着断成两半。
     * 所以含图的段落仍要单独保护。
     *
     * 但原来连普通段落、列表项也一律 break-inside: avoid：
     * 遇到比一页还长的段落，浏览器不肯拆，会整段推到下一页，前一页剩下的
     * 大半张就空着，部分安卓内核甚至直接给出整张空白页；手机按纸宽缩放后
     * 段落更长，尤其容易撞上。这是「空白页」的第二个来源。
     *
     * 现在只保护真正不能拆的：figure、以及含图的段落；普通段落和列表项
     * 允许跨页，用 orphans / widows 保证不留孤行。img / blockquote /
     * table 自己的 avoid 在上一段，仍然有效。
     */
    .el9-content figure {
        break-inside: avoid;
        page-break-inside: avoid;
    }

    /* 单独一条：不认 :has() 的老内核最多丢这一条，不会连累上面那条 */
    .el9-content p:has(img) {
        break-inside: avoid;
        page-break-inside: avoid;
    }

    .el9-content p,
    .el9-content li {
        break-inside: auto;
        page-break-inside: auto;
        orphans: 2;
        widows: 2;
    }

    /*
     * 单张图最高不超过一页。
     *
     * 手机上截的长图（1080×2400 那种）按纸宽 190mm 铺开有 420mm 高，
     * 一张就横跨两页 —— 这正是「图片被拆开两份」最常见的来源。
     * 限高之后它会整体缩小，保住一张图完整落在一页里。
     * width/height 都写 auto，是为了让它按原始比例缩，不被拉扁。
     */
    .el9-content img {
        max-height: 230mm;
        width: auto;
        height: auto;
    }

    /*
     * 表情图要按「字高」算，不能跟着上面的 height:auto 走。
     *
     * 正文里的表情是 height: 1.2em 跟文字一样高；上面那条把 height 改成 auto，
     * 它就按图片原始像素显示了 —— 一张 72px 的表情在 10pt 的字里显得巨大。
     * 这里把尺寸还回去。
     */
    .el9-content img.el9-emoji,
    .el9-card-text img.el9-emoji,
    .el9-cmt-text img.el9-emoji {
        height: 1.2em !important;
        width: auto !important;
        max-width: 2.4em !important;
        max-height: none !important;
        vertical-align: -0.22em;
    }

    /* 网格平时靠 overflow:hidden 收圆角，纸上别让它裁掉多出来的那一行 */
    .el9-content .el9-img-grid {
        overflow: visible !important;
        border-radius: 0 !important;
    }

    /*
     * 网格里的图在屏幕上是被**裁**成固定比例的：
     *   .el9-img-grid img { aspect-ratio: 1/1 或 3/4; object-fit: cover }
     * 屏幕上这样排整齐好看，但纸上等于把图切掉一大块 ——
     * 一张 5580×3712 的横图会被压成 375×501 的竖框，只剩中间一条。
     *
     * 打印时把比例放开、改成 contain：宁可留白边，也要整张图都在。
     */
    .el9-content .el9-img-grid img {
        width: 100% !important;
        height: auto !important;
        aspect-ratio: auto !important;
        object-fit: contain !important;
        align-self: start !important;
        max-height: 230mm !important;
        border-radius: 0 !important;
    }

    /*
     * 特别宽的横图独占一行。
     *
     * 并排网格里每张只占半栏，21:9 那种长条图塞进去高度只剩几十毫米，
     * 图里的字糊成一团。is-wide 由 JS 按图片自身的宽高比打上
     * （≥ 1.7，约 16:9 往上），这里让它跨满整行，换到下一排去。
     */
    .el9-content .el9-img-grid img.is-wide {
        grid-column: 1 / -1;
    }

    /*
     * 正文上方的「本文目录」折叠块，打印时藏掉。
     *
     * 它是给屏幕点的 —— 纸上一串锚点链接毫无用处，还占 47px 加上下各 16px 边距。
     * 短文章正好被这一块顶出第二页（实测 el9pht 那篇就差在这 79px 上）。
     */
    .el9-toc-inline {
        display: none !important;
    }

    /* ---- 4. 文章头尾别占掉半页 ---- */
    /*
     * 短文章最容易出现这种情况：正文一页放得下，
     * 但标题上方 20px + 标题下方 20px + 正文上方 24px + 底部标签 49px 加起来，
     * 刚好把正文顶出去一截，于是第二页只印了个结尾 —— 看着像白浪费一张纸。
     * 纸上不需要那么大的留白，收紧。
     */
    /*
     * 别把标题压到纸边。
     * 上一版为了省纸把 padding 清零，结果标题几乎贴着页面上沿，
     * 标题和下面那行作者信息也粘在一起 —— 省纸归省纸，不能省成这样。
     */
    .el9-article-head {
        padding: 12px 0 8px !important;
        margin-bottom: 8px !important;
        /*
         * 屏幕上这块是张「白卡」（浅描边 + 大圆角）。
         * 纸上不需要卡片这个概念 —— 描边会把标题框起来，
         * 打出来像贴了一张标签，跟页头那条线也打架。
         */
        background: none !important;
        border: 0 !important;
        border-radius: 0 !important;
    }

    .el9-article-title {
        font-size: 19pt !important;
        line-height: 1.3 !important;
        margin-bottom: 7px !important;
    }

    .el9-content {
        margin-top: 4px !important;
    }

    .el9-article-foot {
        margin-top: 8px !important;
        padding-top: 6px !important;
    }
}

/* ==========================================================================
   打印：多图说说 + 文章头部
   ========================================================================== */

@media print {
    /* ---- 1. 多图说说：横向滑动条在纸上只截得到第一屏 ----
     *
     * 说说里连着放几张图时，JS 会把它们包成 .el9-img-strip：
     * 一条横向可拖的 flex 轨道（overflow-x: auto），配左右箭头和小圆点。
     * 屏幕上这么看是舒服的，但纸上没有「拖」这回事 —— 打印只取轨道可见的那一段，
     * 于是四张图只出来第一张，剩下三张在纸外，等于丢了。
     *
     * 打印时把轨道拆掉，图片改成一张一行、占满宽度地顺着往下排。
     */
    .el9-img-strip {
        display: block !important;
        margin: 8px 0 !important;
    }

    .el9-img-strip-track {
        display: block !important;
        overflow: visible !important;
        height: auto !important;
        padding: 0 !important;
        gap: 0 !important;
    }

    /*
     * 宽度写 auto 而不是 100%：
     * 宽度钉死 100% 再限高的结果是「宽 755 高 869」—— 竖图被压扁。
     * 两个都写 auto，浏览器才会按原始比例缩，缩完居中。
     */
    .el9-img-strip-track img {
        display: block !important;
        width: auto !important;
        height: auto !important;
        max-width: 100% !important;
        max-height: 230mm !important;
        margin: 0 auto 8px !important;
        border-radius: 0 !important;
    }

    /* 小圆点和左右箭头在纸上点不了，纯粹占地方 */
    .el9-img-strip-dots,
    .el9-img-strip-prev,
    .el9-img-strip-next {
        display: none !important;
    }

    /* ---- 2. 文章头部：屏幕上头像居左、日期甩到最右，纸上中间空一大截 ----
     *
     * 改成一行「作者 · 日期 · N 条评论」，左对齐。
     * 头像不打印 —— 纸上认人靠名字，44px 的小圆头像只会把左边挤得别扭。
     */
    .el9-article-meta .el9-avatar {
        display: none !important;
    }

    .el9-article-meta {
        display: block !important;
        margin-top: 2px !important;
        font-size: 9.5pt !important;
        line-height: 1.5 !important;
        color: #555 !important;
    }

    .el9-article-meta-text,
    .el9-article-meta-side {
        display: inline !important;
    }

    .el9-card-name,
    .el9-card-handle {
        display: inline !important;
        font-size: inherit !important;
        color: #333 !important;
    }

    /* 名字和 @handle 之间补个间隔点，纸上一行看得更顺 */
    .el9-card-name::after {
        content: ' · ';
        font-weight: 400;
        color: #999;
    }

    /* handle 和日期之间同样补一个 */
    .el9-article-meta-side::before {
        content: ' · ';
        color: #999;
    }

    .el9-article-meta-side a,
    .el9-article-meta-side .el9-dot {
        display: inline !important;
        color: #555 !important;
        text-decoration: none !important;
    }

    /* 站外链接补地址那条规则会把这几个 meta 链接也补上，纸上太乱，豁免掉 */
    .el9-article-meta-side a::after {
        content: '' !important;
    }
}

/* ==========================================================================
   打印：字号
   ========================================================================== */
@media print {
    /*
     * 标题和作者信息比正文大出一截（约 2.1 倍 / 1.15 倍），
     * 跟屏幕上下的比例靠拢 —— 之前为了省纸压到 19pt，
     * 纸上看着跟小标题差不多，认不出是文章标题。
     */
    .el9-article-title {
        font-size: 22pt !important;
        line-height: 1.3 !important;
        margin-bottom: 8px !important;
    }

    .el9-article-meta {
        font-size: 11pt !important;
        line-height: 1.5 !important;
    }

    .el9-card-name {
        font-weight: 600;
    }
}

/* ==========================================================================
   打印：给不认 @page margin box 的浏览器降级（Safari / iOS / 老安卓）
   ==========================================================================

   WebKit 至今只支持 @page 的 margin / size 描述符，不支持 @top-left
   这类页眉页脚盒子（Apple 18.2 / 26.0 更新说明里都没有）。所以上面那
   四行在 Safari 上一个字都印不出来，纸上只剩系统打印界面自带的网址、
   日期、页码 —— 那两行不在 DOM 里，CSS 删不掉，只能在打印界面里关。

   退一步：把「站名 · 文章标题」和「原文链接」印进正文首尾。这是普通
   DOM 节点，所有内核都认，Safari 也能看到。代价是只有第一页顶和最后
   一页底各一行，不是每页都有，也没有页码。

   由 app.js 在打印前判断浏览器认不认 margin box：认的（Chromium 系）
   不加 el9-print-fallback，仍走每页四行，避免纸上出现两套；不认的才
   挂在 html 上，把内容写进这两个节点。屏幕上它们永远是 display:none。
   ========================================================================== */
.el9-print-head,
.el9-print-foot {
    display: none;
}

@media print {
    html.el9-print-fallback .el9-print-head,
    html.el9-print-fallback .el9-print-foot {
        display: block;
        font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Microsoft YaHei", sans-serif;
        font-size: 8pt;
        line-height: 1.5;
        color: #888;
    }

    html.el9-print-fallback .el9-print-head {
        margin: 0 0 10px;
        break-after: avoid;
        page-break-after: avoid;
        /* 标题不截断，长标题在这儿换行，别溢出纸边 */
        overflow-wrap: anywhere;
    }

    html.el9-print-fallback .el9-print-foot {
        margin: 14px 0 0;
        word-break: break-all;
        break-inside: avoid;
        page-break-inside: avoid;
    }
}
