/* ==========================================================================
   尘语 · 样式表

   风格基线：
     · 线条风格 —— 结构由 1px 细线表达，不用投影、不用毛玻璃、不用渐变
     · 一点点圆角 —— 控件 4px、面板 6px，贴边元素保持直角
     · 层次靠「底色差 + 线条 + 留白」三层叠出来，而不是靠立体阴影

   目录：
     01 设计令牌        02 基础与排版      03 布局骨架
     04 顶栏            05 按钮            06 表单
     07 卡片与面板      08 标签与提示      09 首页与板块栏
     10 帖子列表        11 帖子详情        12 Markdown 正文
     13 编辑器          14 侧栏            15 分页
     16 个人主页        17 消息通知        18 好友
     19 私信            20 后台            21 搜索弹窗
     22 头像            23 杂项            24 动效
     25 响应式
   ========================================================================== */

/* ==========================================================================
   01 设计令牌
   ========================================================================== */
:root {
    /* 底色：页面比面板深一档，面板才会「浮」出来 */
    --bg:        #F3F4F5;
    --bg-deep:   #E9EAEC;
    --surface:   #FFFFFF;
    --surface-2: #F7F8F9;

    /* 文字：三档明度就够，别再多 */
    --ink:       #1E2126;
    --ink-2:     #575D66;
    --ink-3:     #8A9099;

    /* 线：hair 用于分隔，hair-2 用于结构轮廓 */
    --hair:      rgba(0, 0, 0, .085);
    --hair-2:    rgba(0, 0, 0, .16);

    /* 强调色：沿用原来的青绿系，但压深一档以便正文里也能当链接色 */
    --accent:    #2F9E90;
    --brand:     #7DCCC3;
    --accent-ink:#FFFFFF;
    --accent-soft: rgba(47, 158, 144, .10);
    --accent-line: rgba(47, 158, 144, .34);

    --danger:    #C0443C;
    --danger-soft: rgba(192, 68, 60, .10);
    --ok:        #3E8E5F;
    --ok-soft:   rgba(62, 142, 95, .10);
    --gold:      #A88447;

    /* 尺度 */
    --bar-h: 58px;
    --maxw:  1240px;

    /* 圆角：只要一点点 */
    --r:    4px;   /* 控件：按钮、输入框、标签、头像 */
    --r-lg: 6px;   /* 面板：卡片、弹层、代码块 */

    /* 间距阶梯（4 的倍数） */
    --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px;
    --s5: 20px; --s6: 24px; --s8: 32px; --s10: 40px;

    /* 字体 */
    --sans: "PingFang SC", "HarmonyOS Sans SC", "MiSans", "Hiragino Sans GB",
            "Microsoft YaHei", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    --mono: ui-monospace, SFMono-Regular, "SF Mono", Consolas, "Liberation Mono", Menlo, monospace;
    /* 标题字：默认就是 --sans，几套界面主题会各自换掉它（见 assets/css/skin-*.css） */
    --display: var(--sans);

    /* 字号阶梯 */
    --t-xs:  11.5px;
    --t-sm:  12.5px;
    --t-md:  13.5px;
    --t-base:14.5px;
    --t-lg:  16px;
    --t-xl:  20px;
    --t-2xl: 26px;

    /* 动效曲线 */
    --ease:      cubic-bezier(.4, 0, .2, 1);
    --ease-out:  cubic-bezier(.16, 1, .3, 1);
    --ease-soft: cubic-bezier(.22, .61, .36, 1);
    --d1: .15s; --d2: .28s; --d3: .46s; --d4: .7s;
}

[data-theme="dark"] {
    --bg:        #2E3038;
    --bg-deep:   #26282F;
    --surface:   #393C46;
    --surface-2: #33363F;

    --ink:       #E9EAF0;
    --ink-2:     #B3B7C2;
    --ink-3:     #838896;

    --hair:      rgba(255, 255, 255, .09);
    --hair-2:    rgba(255, 255, 255, .17);

    --accent:    #CD91AC;
    --brand:     #D9A6BE;
    --accent-ink:#2A2228;
    --accent-soft: rgba(205, 145, 172, .13);
    --accent-line: rgba(205, 145, 172, .38);

    --danger:    #E08680;
    --danger-soft: rgba(224, 134, 128, .12);
    --ok:        #7FC79B;
    --ok-soft:   rgba(127, 199, 155, .12);
    --gold:      #D6B98C;
}

/* ==========================================================================
   02 基础与排版
   ========================================================================== */
* { margin: 0; padding: 0; box-sizing: border-box; }

/* 一点点圆角：默认 4px，面板另给 6px。
   注意这条带 !important，任何需要其它圆角的元素都得跟着带 !important */
*, *::before, *::after { border-radius: var(--r) !important; }

/* 贴边和全屏的元素不能有圆角，否则会在视口边缘露出底色 */
html, body, .topbar, .search-modal, .img-zoom, .mde-over, .load-bar {
    border-radius: 0 !important;
}

/* 面板比控件稍圆一档，层次感更清楚 */
.card, .side-card, .fcard, .bn-card, .pcard, .user-menu, .search-box,
.md-code, .md-table-wrap, .file-drop, .cap-note, .quote-chip, .code-row .code-box {
    border-radius: var(--r-lg) !important;
}

/* 头像是全站唯一的圆形元素 —— 等级头像框的洞是圆的，方角会从圈里戳出来。
   注意上面那条全局规则带 !important，这里必须也带，否则永远输。 */
.av, .avf-hole {
    border-radius: 50% !important;
}
/* 框本身是 PNG，带圆角会削到翅膀尖；容器也保持直角 */
.avf, .avf-img, .avf-shine {
    border-radius: 0 !important;
}

/* [hidden] 必须真的隐藏 —— 作者样式里的 display 会盖掉浏览器默认值 */
[hidden] { display: none !important; }

html {
    background: var(--bg);
    -webkit-text-size-adjust: 100%;
    scroll-behavior: smooth;
    scroll-padding-top: calc(var(--bar-h) + 20px);
}

body {
    background: var(--bg);
    color: var(--ink);
    font-family: var(--sans);
    font-size: var(--t-base);
    line-height: 1.75;
    font-variant-numeric: tabular-nums;
    min-height: 100vh;
    overflow-x: hidden;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    transition: background var(--d2) var(--ease), color var(--d2) var(--ease);
}

a { color: inherit; text-decoration: none; }
img { max-width: 100%; }
button, input, select, textarea { font-family: inherit; font-size: inherit; color: inherit; }

::selection { background: var(--accent-soft); color: var(--ink); }

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

::-webkit-scrollbar { width: 9px; height: 9px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--hair-2); }
::-webkit-scrollbar-thumb:hover { background: var(--ink-3); }

/* 标题层级：字重与字距拉开，中文加一点点字距更透气 */
h1, h2, h3, h4 { line-height: 1.35; font-weight: 600; }

.mono  { font-family: var(--mono); }
.muted { color: var(--ink-3); }
.dim   { color: var(--ink-2); }
.small { font-size: var(--t-sm); }
.center{ text-align: center; }
.nowrap{ white-space: nowrap; }
.serif { font-weight: 700; letter-spacing: .02em; }

.mt8  { margin-top: var(--s2); }
.mt12 { margin-top: var(--s3); }
.mt20 { margin-top: var(--s5); }
.mt28 { margin-top: var(--s8); }

.skip { position: absolute; left: -9999px; }
.skip:focus { left: 12px; top: 10px; z-index: 9999; background: var(--surface); padding: 8px 14px; border: 1px solid var(--accent); }
.dot-sep { opacity: .4; margin: 0 2px; }
.ic { flex: none; }

/* ==========================================================================
   03 布局骨架
   ========================================================================== */
.wrap { width: 100%; max-width: var(--maxw); margin: 0 auto; padding: 0 24px; }
.main { padding-top: calc(var(--bar-h) + 28px); padding-bottom: var(--s10); min-height: 70vh; }

.layout { display: grid; grid-template-columns: minmax(0, 1fr) 268px; gap: var(--s5); align-items: start; }
.layout.single { grid-template-columns: minmax(0, 1fr); }

.foot {
    border-top: 1px solid var(--hair);
    margin-top: var(--s10);
    padding: var(--s5) 0;
    font-size: var(--t-sm);
    color: var(--ink-3);
}
.foot-in { display: flex; align-items: center; justify-content: space-between; gap: var(--s3); flex-wrap: wrap; }
.foot-l, .foot-r { display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap; }
.foot-r a { color: var(--ink-2); transition: color var(--d1) var(--ease); }
.foot-r a:hover { color: var(--accent); }
.foot-online { display: inline-flex; align-items: center; gap: 6px; }
.live { width: 6px; height: 6px; background: var(--ok); }

/* ==========================================================================
   04 顶栏
   ========================================================================== */
.topbar {
    position: fixed; top: 0; left: 0; right: 0; height: var(--bar-h);
    background: var(--surface);
    border-bottom: 1px solid var(--hair-2);
    z-index: 900;
    transition: background var(--d2) var(--ease), border-color var(--d2) var(--ease);
}
/* 阅读进度：贴着顶栏下沿的一条细线 */
.topbar::after {
    content: '';
    position: absolute; left: 0; bottom: -1px; height: 2px; width: 100%;
    background: var(--accent);
    transform: scaleX(var(--scroll, 0));
    transform-origin: left center;
    transition: transform .1s linear;
    pointer-events: none;
}
.topbar-in { display: flex; align-items: center; gap: var(--s3); height: 100%; }

/* PJAX 加载指示：和阅读进度共用顶栏下沿，但换个颜色以便区分 */
.load-bar {
    position: absolute; left: 0; bottom: -1px; height: 2px; width: 0;
    background: var(--brand);
    opacity: 0; pointer-events: none;
    transition: width .3s var(--ease-out), opacity .3s var(--ease);
}
.load-bar.on { opacity: 1; }

.brand { display: flex; align-items: center; gap: 10px; flex: none; }
.brand-mark {
    width: 34px; height: 34px;
    background: var(--accent); color: var(--accent-ink);
    display: grid; place-items: center;
    font-size: 17px; font-weight: 700;
    transition: background var(--d2) var(--ease);
}
.brand:hover .brand-mark { background: var(--brand); color: #1E2126; }
/* 后台传了站点图标就用图片，跟头像一样是正圆（支持 GIF，原样落盘不丢动画） */
.brand-logo {
    width: 34px; height: 34px; flex: none;
    object-fit: cover;
    border-radius: 50% !important;
    transition: transform var(--d2) var(--ease-out);
}
.brand:hover .brand-logo { transform: scale(1.06); }
.brand-text { display: flex; flex-direction: column; line-height: 1.25; }
.brand-text b { font-size: 15px; font-weight: 700; letter-spacing: .08em; }
.brand-text i { font-style: normal; font-size: var(--t-xs); color: var(--ink-3); letter-spacing: .02em; }

.nav { display: flex; align-items: center; gap: var(--s1); margin-left: var(--s3); flex: 1; min-width: 0; }
.nav-a {
    position: relative; padding: 8px 12px;
    font-size: var(--t-md); color: var(--ink-2);
    white-space: nowrap; transition: color var(--d2) var(--ease);
}
.nav-a::after {
    content: ''; position: absolute; left: 12px; right: 12px; bottom: 2px; height: 1px;
    background: currentColor;
    transform: scaleX(0); transform-origin: left center;
    transition: transform var(--d2) var(--ease-out);
}
.nav-a:hover { color: var(--ink); }
.nav-a:hover::after { transform: scaleX(1); }
.nav-a.on { color: var(--accent); font-weight: 600; }
.nav-a.on::after { transform: scaleX(1); }
/* 窄屏面板专用的登录/注册入口，宽屏不出现（顶栏已经有按钮了） */
.nav-a-mb { display: none; }

.topbar-right { display: flex; align-items: center; gap: 6px; flex: none; }

.mini-dot {
    margin-left: auto;
    background: var(--danger); color: #fff; font-style: normal;
    font-size: 10px; padding: 1px 6px; font-family: var(--mono);
}

/* 窄屏导航按钮：只在窄屏出现，展开的是同一份 .nav，不复制链接 */
.mb-btn {
    display: none;
    height: 34px; padding: 0 7px;
    border: none; background: transparent;
    color: var(--ink-2); font-family: inherit;
    font-size: var(--t-xs); letter-spacing: .04em;
    cursor: pointer;
    transition: color var(--d1) var(--ease);
}
.mb-btn:hover, body.mb-open .mb-btn { color: var(--accent); }

/* 主题切换：浅色 / 深色 两段式，当前档位由 data-theme 决定 */
.theme-seg {
    display: inline-flex; align-items: stretch;
    height: 34px; padding: 0;
    background: transparent; border: 1px solid var(--hair-2);
    cursor: pointer; overflow: hidden;
    transition: border-color var(--d2) var(--ease);
}
.theme-seg:hover { border-color: var(--accent); }
.ts-opt {
    display: grid; place-items: center;
    padding: 0 10px;
    font-size: var(--t-xs); letter-spacing: .04em; line-height: 1;
    color: var(--ink-3);
    transition: background var(--d2) var(--ease), color var(--d2) var(--ease);
}
.ts-opt + .ts-opt { border-left: 1px solid var(--hair); }
[data-theme="light"] .ts-opt[data-t="light"],
[data-theme="dark"]  .ts-opt[data-t="dark"] {
    background: var(--accent); color: var(--accent-ink);
}

/* 顶栏上的图标按钮（消息通知 / 私信） */
.tb-act {
    position: relative;
    width: 34px; height: 34px; flex: none;
    display: inline-grid; place-items: center;
    border: 1px solid transparent; background: transparent;
    color: var(--ink-2);
    transition: color var(--d1) var(--ease), border-color var(--d1) var(--ease), background var(--d1) var(--ease);
}
.tb-act:hover { color: var(--accent); border-color: var(--hair-2); background: var(--surface-2); }
.tb-act .ic { pointer-events: none; }
/* 未读角标贴在右上角，不占位、不影响图标居中 */
.tb-dot {
    position: absolute; top: -2px; right: -2px;
    padding: 0 4px; min-width: 15px;
    background: var(--danger); color: #fff;
    font-style: normal; font-size: 10px; line-height: 15px;
    font-family: var(--mono); text-align: center;
    pointer-events: none;
}

/* 用户菜单 */
.user-drop { position: relative; }
/* 高度交给内容：顶栏里现在放的是带头像框的头像，四级的框比按钮本身还高 */
.user-btn {
    display: flex; align-items: center; gap: 7px; min-height: 34px; padding: 0 10px 0 3px;
    background: transparent; border: 1px solid transparent;
    cursor: pointer; font-size: var(--t-md); color: var(--ink);
    transition: border-color var(--d1) var(--ease);
}
.user-btn:hover { border-color: var(--hair-2); }
.user-btn .lvb { flex: none; }
.uname { max-width: 84px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.user-menu {
    position: absolute; top: calc(100% + 4px); right: 0; min-width: 178px;
    background: var(--surface); border: 1px solid var(--hair-2);
    padding: 5px; z-index: 950;
    opacity: 0; visibility: hidden; transform: translateY(-6px);
    transition: opacity var(--d2) var(--ease), transform var(--d2) var(--ease-out), visibility var(--d2);
}
.user-menu.on { opacity: 1; visibility: visible; transform: none; }
.user-menu a {
    display: flex; align-items: center; gap: 9px;
    padding: 9px 11px; font-size: var(--t-md); color: var(--ink-2);
    border-left: 2px solid transparent;
    transition: background var(--d1) var(--ease), color var(--d1) var(--ease), border-color var(--d1) var(--ease);
}
.user-menu a:hover { background: var(--surface-2); color: var(--accent); border-left-color: var(--accent); }
.user-menu a .ic { opacity: .7; }
.um-sep { display: block; height: 1px; background: var(--hair); margin: 5px 6px; }
.um-out { color: var(--danger) !important; }
.um-out:hover { background: var(--danger-soft) !important; border-left-color: var(--danger) !important; color: var(--danger) !important; }

/* ==========================================================================
   05 按钮
   ========================================================================== */
.btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 6px;
    height: 36px; padding: 0 16px;
    border: 1px solid transparent; background: transparent;
    cursor: pointer; font-size: var(--t-md); font-weight: 500;
    white-space: nowrap; letter-spacing: .02em;
    transition: background var(--d2) var(--ease), color var(--d2) var(--ease),
                border-color var(--d2) var(--ease), transform .08s var(--ease);
}
.btn:active { transform: translateY(1px); }
.btn[disabled] { opacity: .4; cursor: not-allowed; }
.btn[disabled]:active { transform: none; }

/* 主操作：实心 */
.btn-solid { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.btn-solid:hover { background: var(--brand); border-color: var(--brand); color: #1E2126; }
[data-theme="dark"] .btn-solid:hover { background: var(--brand); color: #2A2228; }

/* 次操作：描边 */
.btn-ghost { border-color: var(--hair-2); color: var(--ink-2); }
.btn-ghost:hover { border-color: var(--accent); color: var(--accent); }

/* 次操作：浅底 */
.btn-plain { background: var(--surface-2); border-color: var(--hair); color: var(--ink-2); }
.btn-plain:hover { background: var(--bg-deep); color: var(--accent); border-color: var(--accent-line); }

/* 文字按钮 */
.btn-line { color: var(--accent); }
.btn-line:hover { background: var(--accent-soft); }

.btn-danger { border-color: var(--danger); color: var(--danger); }
.btn-danger:hover { background: var(--danger); color: #fff; }

.btn-sm { height: 30px; padding: 0 12px; font-size: var(--t-sm); }
.btn-lg { height: 44px; padding: 0 26px; font-size: var(--t-lg); }
.btn-block { width: 100%; }
.btn-post { padding: 0 15px; }

/* ==========================================================================
   06 表单
   ========================================================================== */
.field { margin-bottom: var(--s4); }
.field > label {
    display: block; margin-bottom: 7px;
    font-size: var(--t-sm); font-weight: 600;
    color: var(--ink-2); letter-spacing: .04em;
}
.field .tip { margin-top: 6px; font-size: var(--t-sm); color: var(--ink-3); line-height: 1.7; }
.field .tip a { color: var(--accent); }
.field-row { display: flex; gap: var(--s3); }
.field-row > * { flex: 1; min-width: 0; }

.inp {
    width: 100%; height: 42px; padding: 0 13px;
    border: 1px solid var(--hair-2); background: var(--surface);
    color: var(--ink); font-size: var(--t-base);
    transition: border-color var(--d2) var(--ease), background var(--d2) var(--ease), box-shadow var(--d2) var(--ease);
}
textarea.inp { height: auto; min-height: 96px; padding: 11px 13px; line-height: 1.75; resize: vertical; }
.inp::placeholder { color: var(--ink-3); }
.inp:hover { border-color: var(--ink-3); }
.inp:focus {
    outline: 1px solid var(--accent);
    outline-offset: 1px;
    border-color: var(--accent);
}

/* 验证码行：输入框 + 按钮 / 题目 */
.code-row { display: flex; gap: var(--s2); align-items: stretch; }
.code-row .inp { flex: 1; min-width: 0; }
.code-row .btn { flex: none; white-space: nowrap; }
.code-row .code-box {
    flex: 1; display: flex; align-items: center; justify-content: center; gap: 8px;
    border: 1px solid var(--accent-line); background: var(--accent-soft);
    font-family: var(--mono); font-size: 17px; font-weight: 600;
    letter-spacing: .18em; color: var(--accent);
    cursor: pointer; user-select: none;
}

/* 文件选择 */
.file-drop {
    display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap;
    border: 1px dashed var(--hair-2); background: var(--surface-2);
    padding: 13px 15px;
    transition: border-color var(--d2) var(--ease);
}
.file-drop:hover { border-color: var(--accent); }
.file-drop input[type=file] { font-size: var(--t-sm); color: var(--ink-2); max-width: 100%; }
.fd-tip { font-size: var(--t-sm); color: var(--ink-3); }

/* 登录 / 注册页 */
.auth-wrap { max-width: 430px; margin: var(--s8) auto 0; }
.auth-wrap .card-b { padding: 30px 28px 26px; }
.auth-title { text-align: center; margin-bottom: var(--s6); }
.auth-title h1 { font-size: var(--t-2xl); font-weight: 700; letter-spacing: .06em; }
.auth-title p { margin-top: 6px; font-size: var(--t-sm); color: var(--ink-3); }
.auth-alt { text-align: center; font-size: var(--t-sm); color: var(--ink-3); margin-top: var(--s5); }
.auth-alt a { color: var(--accent); }
/* 第三方登录的分隔线：「─── 或者 ───」 */
.auth-sep {
    display: flex; align-items: center; gap: var(--s3);
    margin: var(--s5) 0 var(--s4);
    color: var(--ink-3); font-size: var(--t-xs); letter-spacing: .1em;
}
.auth-sep::before, .auth-sep::after {
    content: ''; flex: 1; height: 1px; background: var(--hair);
}
.auth-sep span { flex: none; }
/* 开了不止一家第三方登录时，按钮竖着排，别挤成一条 */
.oauth-stack { display: flex; flex-direction: column; gap: var(--s2); }

/* 个人设置 → 账号绑定：一家一行 */
.bind-list { border-top: 1px solid var(--hair); }
.bind-row {
    display: flex; align-items: center; gap: var(--s4);
    padding: 14px 0; border-bottom: 1px solid var(--hair);
}
.bind-ico {
    flex: none; width: 40px; height: 40px;
    display: flex; align-items: center; justify-content: center;
    background: var(--surface-2); color: var(--ink-2);
}
.bind-main { flex: 1; min-width: 0; }
.bind-main b { font-size: var(--t-md); font-weight: 600; }
.bind-sub { margin-top: 3px; font-size: var(--t-sm); color: var(--ink-3); word-break: break-all; }
.bind-act { flex: none; }

/* ==========================================================================
   07 卡片与面板
   ========================================================================== */
.card {
    background: var(--surface);
    border: 1px solid var(--hair-2);
    transition: background var(--d2) var(--ease), border-color var(--d2) var(--ease);
}
.card + .card { margin-top: var(--s5); }

.card-h {
    display: flex; align-items: center; gap: 10px;
    min-height: 52px; padding: 12px var(--s5);
    border-bottom: 1px solid var(--hair);
}
.card-h h2 { font-size: var(--t-base); font-weight: 700; letter-spacing: .06em; }
.card-h .h-sub { font-size: var(--t-sm); color: var(--ink-3); }
.card-h .h-right { margin-left: auto; display: flex; align-items: center; gap: var(--s2); }
.card-b { padding: 5px 0; }
.card-b.pad { padding: var(--s5); }
.pad { padding: var(--s5); }

.page-h {
    display: flex; align-items: flex-end; gap: var(--s3);
    margin-bottom: var(--s5); flex-wrap: wrap;
}
.page-h h1 {
    position: relative;
    font-size: var(--t-xl); font-weight: 700; letter-spacing: .06em;
    padding-bottom: 8px;
}
.page-h h1::after {
    content: ''; position: absolute; left: 0; bottom: 0;
    width: 34px; height: 2px; background: var(--accent);
    transform-origin: left center;
    animation: lineGrow var(--d4) var(--ease-out) both;
}
.page-h .sub { font-size: var(--t-sm); color: var(--ink-3); padding-bottom: 10px; }
.page-h .h-act { margin-left: auto; display: flex; gap: var(--s2); padding-bottom: 8px; }

.crumb {
    display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
    font-size: var(--t-sm); color: var(--ink-3); margin-bottom: var(--s4);
}
.crumb a { color: var(--ink-2); transition: color var(--d1) var(--ease); }
.crumb a:hover { color: var(--accent); }
.crumb .sep { opacity: .45; }

.empty { padding: 52px var(--s5); text-align: center; color: var(--ink-3); font-size: var(--t-md); }
.empty .big { display: block; font-size: var(--t-base); font-weight: 600; color: var(--ink-2); margin-bottom: 6px; }

/* ==========================================================================
   08 标签与提示
   ========================================================================== */
.tag {
    display: inline-flex; align-items: center; gap: 3px;
    padding: 2px 6px;
    font-size: var(--t-xs); font-weight: 600; line-height: 1.5;
    letter-spacing: .06em;
    border: 1px solid transparent;
    flex: none;
}
.tag-pin    { color: var(--accent); border-color: var(--accent-line); background: var(--accent-soft); }
.tag-best   { color: var(--gold); border-color: rgba(168, 132, 71, .35); background: rgba(168, 132, 71, .09); }
.tag-lock   { color: var(--ink-3); border-color: var(--hair-2); }
.tag-you    { color: var(--danger); border-color: rgba(192, 68, 60, .3); background: var(--danger-soft); }
.tag-admin  { color: #fff; background: var(--danger); border-color: var(--danger); }
.tag-audit  { color: var(--gold); border-color: rgba(168, 132, 71, .35); background: rgba(168, 132, 71, .09); }
.tag-reject { color: var(--danger); border-color: rgba(192, 68, 60, .3); background: var(--danger-soft); }

.flash {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    padding: 11px var(--s4); margin-bottom: var(--s4);
    font-size: var(--t-md); line-height: 1.7;
    border: 1px solid transparent;
    border-left-width: 3px;
    animation: flashIn var(--d3) var(--ease-out) both;
}
.flash-ok  { color: var(--ok); border-color: var(--ok-soft); border-left-color: var(--ok); background: var(--ok-soft); }
.flash-err { color: var(--danger); border-color: var(--danger-soft); border-left-color: var(--danger); background: var(--danger-soft); }
.flash a { text-decoration: underline; text-underline-offset: 2px; }
.flash .btn { margin-left: auto; }

.cap-note {
    padding: 12px var(--s4);
    font-size: var(--t-sm); line-height: 1.85; color: var(--ink-2);
    background: var(--surface-2); border: 1px solid var(--hair);
    border-left: 3px solid var(--hair-2);
}

/* ---------- 标签（纯文字，不带图标） ---------- */
.tg {
    display: inline-flex; align-items: center; gap: 4px;
    padding: 1px 7px;
    font-size: var(--t-xs); line-height: 1.7;
    color: var(--ink-2); background: var(--surface-2);
    border: 1px solid var(--hair-2);
    transition: color var(--d1) var(--ease), border-color var(--d1) var(--ease), background var(--d1) var(--ease);
}
.tg:hover { color: var(--accent); border-color: var(--accent); background: var(--accent-soft); }
.tg-on { color: var(--accent); border-color: var(--accent); background: var(--accent-soft); }
.tg-x {
    padding: 0 2px; line-height: 1;
    background: none; border: none; cursor: pointer;
    color: var(--ink-3); font-size: 13px;
    transition: color var(--d1) var(--ease);
}
.tg-x:hover { color: var(--danger); }
.tgrow { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 7px; }

/* 标签列表页 */
.tag-cloud { display: flex; flex-wrap: wrap; gap: var(--s2); padding: var(--s5); }
.tag-cloud .tg { padding: 4px 11px; font-size: var(--t-md); }
.tag-cloud .tg em { font-style: normal; font-family: var(--mono); font-size: var(--t-xs); color: var(--ink-3); }
.tag-cloud .tg:hover em { color: var(--accent); }

/* 标签选择器 */
.tagpick { padding: 11px 12px; background: var(--surface); border: 1px solid var(--hair-2); }
.tagpick-sel { display: flex; flex-wrap: wrap; gap: 6px; min-height: 27px; margin-bottom: 9px; }
.tagpick-sel:empty::after { content: '还没有选择标签'; font-size: var(--t-sm); color: var(--ink-3); }
.tagpick-row { display: flex; gap: var(--s2); }
.tagpick-row .inp { flex: 1; min-width: 0; height: 34px; }
.tagpick-row .btn { flex: none; }
.tagpick-list {
    display: flex; flex-wrap: wrap; gap: 6px;
    max-height: 178px; overflow-y: auto;
    margin-top: 11px; padding-top: 11px;
    border-top: 1px solid var(--hair);
}
.tagpick-item {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 2px 9px;
    font-size: var(--t-sm); color: var(--ink-2);
    background: var(--surface-2); border: 1px solid var(--hair-2);
    cursor: pointer;
    transition: color var(--d1) var(--ease), border-color var(--d1) var(--ease), background var(--d1) var(--ease);
}
.tagpick-item em { font-style: normal; font-family: var(--mono); font-size: var(--t-xs); color: var(--ink-3); }
.tagpick-item:hover { color: var(--accent); border-color: var(--accent); }
.tagpick-item.on { color: var(--accent); border-color: var(--accent); background: var(--accent-soft); }
.tagpick-empty { font-size: var(--t-sm); color: var(--ink-3); }
.tagpick-hint { margin-top: 10px; font-size: var(--t-xs); line-height: 1.75; color: var(--ink-3); }

/* ==========================================================================
   09 首页与板块栏
   ========================================================================== */
.home { display: grid; grid-template-columns: 224px minmax(0, 1fr); gap: var(--s5); align-items: start; }
.home-side, .home-main { min-width: 0; }

.bn-card { background: var(--surface); border: 1px solid var(--hair-2); padding: 13px; }
.bn-card + .bn-card { margin-top: var(--s4); }
.bn-title {
    display: flex; align-items: center;
    padding: 2px 8px 11px;
    font-size: var(--t-xs); font-weight: 700;
    letter-spacing: .14em; color: var(--ink-3);
}
.bn-title a { margin-left: auto; font-weight: 500; letter-spacing: .02em; font-size: var(--t-sm); color: var(--accent); }

.bn-item {
    position: relative;
    display: flex; align-items: center; gap: 10px;
    padding: 8px 9px;
    font-size: var(--t-md); color: var(--ink-2);
    border-left: 2px solid transparent;
    transition: background var(--d1) var(--ease), color var(--d1) var(--ease), border-color var(--d1) var(--ease);
}
.bn-item:hover { background: var(--surface-2); color: var(--ink); }
.bn-item.on { color: var(--accent); border-left-color: var(--accent); background: var(--accent-soft); font-weight: 600; }
.bn-item .bico {
    width: 26px; height: 26px; flex: none; overflow: hidden;
    display: grid; place-items: center;
    background: var(--surface-2); border: 1px solid var(--hair);
    font-size: var(--t-sm); font-weight: 700; color: var(--ink-2);
}
.bn-item.on .bico { background: var(--accent-soft); border-color: var(--accent-line); color: var(--accent); }
.bn-item .bico img { width: 100%; height: 100%; object-fit: cover; display: block; }
.bn-item .bname { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bn-item em { font-style: normal; font-family: var(--mono); font-size: var(--t-xs); color: var(--ink-3); flex: none; }
.bn-item.on em { color: var(--accent); }

.bn-announce { padding: 0 6px; font-size: var(--t-sm); line-height: 1.85; color: var(--ink-2); }
.announce-edit { margin-top: 10px; }
.announce-edit textarea {
    width: 100%; min-height: 78px; padding: 10px 12px;
    border: 1px solid var(--hair-2); background: var(--surface-2); color: var(--ink);
    font-size: var(--t-sm); line-height: 1.75; resize: vertical;
    transition: border-color var(--d2) var(--ease);
}
.announce-edit textarea:focus { outline: none; border-color: var(--accent); background: var(--surface); }

/* ==========================================================================
   10 帖子列表
   ========================================================================== */
.t-row {
    position: relative;
    display: flex; gap: var(--s4);
    padding: 15px var(--s5);
    border-bottom: 1px solid var(--hair);
    transition: background var(--d2) var(--ease);
}
.t-row:last-child { border-bottom: none; }
.t-row::before {
    content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 2px;
    background: var(--accent);
    transform: scaleY(0); transform-origin: center;
    transition: transform var(--d2) var(--ease-out);
}
.t-row:hover { background: var(--surface-2); }
.t-row:hover::before { transform: scaleY(1); }

.t-main { flex: 1; min-width: 0; }
.t-title {
    display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
    font-size: var(--t-base); font-weight: 500; line-height: 1.55;
    color: var(--ink);
    transition: color var(--d1) var(--ease);
}
.t-title:hover { color: var(--accent); }
.t-title > span:last-child {
    background-image: linear-gradient(currentColor, currentColor);
    background-size: 0% 1px; background-repeat: no-repeat; background-position: 0 100%;
    transition: background-size var(--d2) var(--ease-out);
}
.t-title:hover > span:last-child { background-size: 100% 1px; }

.t-meta {
    display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap;
    margin-top: 6px; font-size: var(--t-sm); color: var(--ink-3);
}
.t-meta .who a, .t-meta a { color: var(--ink-2); transition: color var(--d1) var(--ease); }
.t-meta .who a:hover, .t-meta a:hover { color: var(--accent); }

.t-right { flex: none; width: 132px; text-align: right; font-size: var(--t-sm); color: var(--ink-3); line-height: 1.6; }
.t-right b { font-family: var(--mono); font-weight: 600; color: var(--ink-2); }
.t-right .lr a { color: var(--ink-2); }
.t-right .lr a:hover { color: var(--accent); }

/* 管理员快捷操作：平时半透明，悬停整行才显形 */
.t-admin {
    display: flex; gap: 5px; margin-top: 9px; flex-wrap: wrap;
    opacity: 0; transform: translateY(-2px);
    transition: opacity var(--d2) var(--ease), transform var(--d2) var(--ease-out);
}
.t-row:hover .t-admin { opacity: 1; transform: none; }
.t-admin a {
    padding: 2px 8px; font-size: var(--t-xs);
    border: 1px solid var(--hair-2); color: var(--ink-3);
    transition: all var(--d1) var(--ease);
}
.t-admin a:hover { color: var(--accent); border-color: var(--accent); }
.t-admin a.warn { color: var(--gold); border-color: rgba(168, 132, 71, .4); }
.t-admin a.danger:hover { color: var(--danger); border-color: var(--danger); }

/* 板块大行（成员页 / 旧版首页仍在用） */
.board-row {
    display: flex; align-items: center; gap: 15px;
    padding: 15px var(--s5);
    border-bottom: 1px solid var(--hair);
    transition: background var(--d2) var(--ease);
}
.board-row:last-child { border-bottom: none; }
.board-row:hover { background: var(--surface-2); }
.board-ico {
    width: 40px; height: 40px; flex: none; overflow: hidden;
    display: grid; place-items: center;
    background: var(--accent-soft); border: 1px solid var(--accent-line);
    color: var(--accent); font-size: var(--t-lg); font-weight: 700;
}
.board-ico.has-img { padding: 0; background: var(--surface-2); }
.board-ico.has-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.board-main { flex: 1; min-width: 0; }
.board-name { display: flex; align-items: center; gap: var(--s2); font-size: var(--t-base); font-weight: 600; }
.board-desc { margin-top: 3px; font-size: var(--t-sm); color: var(--ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.board-num { display: flex; gap: var(--s5); flex: none; text-align: center; }
.board-num div { min-width: 46px; }
.board-num b { display: block; font-family: var(--mono); font-size: var(--t-md); font-weight: 600; }
.board-num span { font-size: var(--t-xs); color: var(--ink-3); }
.board-last { flex: none; width: 172px; font-size: var(--t-sm); color: var(--ink-3); line-height: 1.55; }
.board-last a { color: var(--ink-2); }
.board-last a:hover { color: var(--accent); }
.board-last .lt { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.bico {
    width: 26px; height: 26px; flex: none; overflow: hidden;
    display: grid; place-items: center;
    background: var(--surface-2); border: 1px solid var(--hair);
    font-size: var(--t-sm); font-weight: 700;
}
.bico img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ==========================================================================
   11 帖子详情
   ========================================================================== */
.thread-h { padding: var(--s6) var(--s6) var(--s4); border-bottom: 1px solid var(--hair); }
.thread-h h1 { font-size: var(--t-xl); font-weight: 700; line-height: 1.5; letter-spacing: .03em; }
.thread-h .th-meta {
    display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap;
    margin-top: var(--s3); font-size: var(--t-sm); color: var(--ink-3);
}
.thread-h .th-meta .who { display: flex; align-items: center; gap: 7px; color: var(--ink-2); }

.post {
    display: flex; gap: var(--s4);
    padding: var(--s5) var(--s6);
    border-bottom: 1px solid var(--hair);
}
.post:last-child { border-bottom: none; }
.post-side { flex: none; width: 108px; text-align: center; }
.post-side .pn { margin-top: 7px; font-size: var(--t-md); font-weight: 600; word-break: break-all; }
.post-side .pn a { color: var(--ink); }
.post-side .pn a:hover { color: var(--accent); }
.post-side .pt { margin-top: 3px; font-size: var(--t-xs); color: var(--ink-3); }
.post-body { flex: 1; min-width: 0; }
.post-bar {
    display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap;
    margin-bottom: 9px; font-size: var(--t-sm); color: var(--ink-3);
}
.post-bar .floor { margin-left: auto; font-family: var(--mono); }
.post-text { font-size: var(--t-base); line-height: 1.85; word-wrap: break-word; overflow-wrap: anywhere; }
.post-act { display: flex; gap: var(--s1); align-items: center; margin-top: var(--s3); }
/* 删除这类动作要用 POST，所以套了层 form —— 别让它破坏这一行的 flex 排布 */
.act-form { display: flex; margin: 0; }

.act-btn {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 5px 10px;
    border: 1px solid transparent; background: transparent;
    cursor: pointer; font-size: var(--t-sm); color: var(--ink-3);
    transition: background var(--d1) var(--ease), color var(--d1) var(--ease), border-color var(--d1) var(--ease);
}
.act-btn:hover { background: var(--surface-2); border-color: var(--hair); color: var(--accent); }
.act-btn.on { color: var(--accent); background: var(--accent-soft); border-color: var(--accent-line); }
.act-btn.on .ic { fill: currentColor; }
.act-btn .n:empty { display: none; }

/* 楼中楼 */
.sub-list { margin-top: var(--s4); border-top: 1px solid var(--hair); }
.sub { padding: 13px 0 11px; border-bottom: 1px solid var(--hair); }
.sub:last-child { border-bottom: none; padding-bottom: 0; }
.sub-h { display: flex; align-items: center; gap: var(--s2); margin-bottom: 6px; font-size: var(--t-sm); color: var(--ink-3); }
.sub-h .who { color: var(--ink-2); font-weight: 500; }
.sub-h .floor { margin-left: auto; font-family: var(--mono); font-size: var(--t-xs); }
.sub-body { padding-left: 34px; font-size: var(--t-md); line-height: 1.8; word-wrap: break-word; overflow-wrap: anywhere; }
.sub-body blockquote {
    margin: 6px 0; padding: 6px 12px;
    border-left: 2px solid var(--hair-2); background: var(--surface-2);
    color: var(--ink-2); font-size: var(--t-sm);
}
.sub-act { padding-left: 34px; margin-top: 6px; }
.sub-act .act-btn { padding: 3px 8px; font-size: var(--t-xs); }
.sub-more { margin-top: var(--s2); padding-left: 34px; }
.sub-more button {
    background: none; border: none; cursor: pointer;
    color: var(--accent); font-size: var(--t-sm); padding: 2px 0;
}
.sub-more button:hover { text-decoration: underline; }

/* 楼中楼头上的「回复 @某某」 */
.sub-to { color: var(--ink-3); }
.sub-to a { color: var(--accent); font-weight: 500; text-decoration: none; }
.sub-to a:hover { text-decoration: underline; text-underline-offset: 3px; }

.quote-chip {
    display: flex; align-items: center; gap: var(--s2);
    margin-bottom: 9px; padding: 7px 12px;
    font-size: var(--t-sm); color: var(--ink-2);
    background: var(--surface-2); border: 1px solid var(--hair);
    border-left: 3px solid var(--accent);
    overflow: hidden;
}
.quote-chip b { font-weight: 600; color: var(--accent); }
.quote-chip .qx { color: var(--ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.quote-chip button {
    margin-left: auto; flex: none;
    background: none; cursor: pointer;
    border: 1px solid var(--hair-2);
    color: var(--ink-3); font-size: var(--t-xs); padding: 2px 8px;
    transition: color var(--d1) var(--ease), border-color var(--d1) var(--ease);
}
.quote-chip button:hover { color: var(--danger); border-color: var(--danger); }

/* ==========================================================================
   12 Markdown 正文
   ========================================================================== */
.md { font-size: var(--t-base); line-height: 1.85; word-wrap: break-word; overflow-wrap: anywhere; }
.md > *:first-child { margin-top: 0 !important; }
.md > *:last-child { margin-bottom: 0 !important; }
.md p { margin: 0 0 var(--s3); }
.md h1, .md h2, .md h3, .md h4, .md h5, .md h6 { margin: var(--s6) 0 10px; font-weight: 700; line-height: 1.4; letter-spacing: .03em; }
.md h1 { font-size: 21px; }
.md h2 { font-size: 18px; }
.md h3 { font-size: 16px; }
.md h4, .md h5, .md h6 { font-size: var(--t-base); }
.md h1, .md h2 { padding-bottom: 7px; border-bottom: 1px solid var(--hair); }
.md ul, .md ol { margin: 0 0 var(--s3); padding-left: 24px; }
.md li { margin: 4px 0; }
.md li > ul, .md li > ol { margin: 5px 0 0; }
.md blockquote {
    margin: 13px 0; padding: 9px 15px;
    border-left: 2px solid var(--accent); background: var(--surface-2);
    color: var(--ink-2);
}
.md blockquote p:last-child { margin-bottom: 0; }
.md hr { border: none; border-top: 1px solid var(--hair); margin: var(--s5) 0; }
.md a { color: var(--accent); text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; text-decoration-color: var(--accent-line); transition: text-decoration-color var(--d2) var(--ease); }
.md a:hover { text-decoration-color: var(--accent); }
/* @提及：正文里的用户名 */
.mention { color: var(--accent); font-weight: 500; text-decoration: none !important; }
.mention:hover { text-decoration: underline !important; text-underline-offset: 3px; }
.md img { display: block; margin: 10px 0; max-width: 100%; height: auto; border: 1px solid var(--hair); cursor: zoom-in; transition: border-color var(--d2) var(--ease); }
.md img:hover { border-color: var(--accent-line); }
.md code {
    padding: 1px 6px; font-family: var(--mono); font-size: .87em;
    background: var(--surface-2); border: 1px solid var(--hair);
}
.md-table-wrap { margin: var(--s4) 0; overflow-x: auto; border: 1px solid var(--hair-2); }
.md table { border-collapse: collapse; width: 100%; font-size: var(--t-md); }
.md th, .md td { padding: 9px 13px; text-align: left; border-bottom: 1px solid var(--hair); }
.md tr:last-child td { border-bottom: none; }
.md th { background: var(--surface-2); font-weight: 600; }
.md tbody tr { transition: background var(--d1) var(--ease); }
.md tbody tr:hover { background: var(--surface-2); }

/* 代码块 */
.md-code {
    margin: var(--s5) 0;
    border: 1px solid var(--hair-2);
    border-left: 2px solid var(--accent);
    background: var(--surface-2);
    overflow: hidden;
}
.code-bar {
    display: flex; align-items: center; gap: 10px;
    padding: 7px 12px 7px 14px;
    border-bottom: 1px solid var(--hair);
    background: var(--surface);
}
/* 语言标签做成一个小胶囊，前面加个点，比纯大写字母好看 */
.code-lang {
    display: inline-flex; align-items: center; gap: 6px;
    font-family: var(--mono); font-size: var(--t-xs);
    letter-spacing: .06em; color: var(--ink-3);
    text-transform: lowercase;
}
.code-lang::before {
    content: ''; width: 6px; height: 6px;
    background: var(--accent); opacity: .55;
    border-radius: 50% !important;
}
.code-copy {
    margin-left: auto; padding: 4px 11px;
    border: 1px solid var(--hair-2); background: transparent; color: var(--ink-3);
    font-size: var(--t-xs); font-family: inherit; cursor: pointer;
    border-radius: var(--r) !important;
    transition: color var(--d1) var(--ease), border-color var(--d1) var(--ease), background var(--d1) var(--ease);
}
.code-copy:hover { color: var(--accent); border-color: var(--accent); background: var(--accent-soft); }
.code-copy.on { color: var(--accent-ink); background: var(--accent); border-color: var(--accent); }
.md-code pre {
    margin: 0; padding: 15px 18px;
    overflow-x: auto;
    tab-size: 4; -moz-tab-size: 4;
    max-height: 560px; overflow-y: auto;
}
.md-code pre code {
    display: block; padding: 0; border: none; background: none;
    font-family: var(--mono); font-size: var(--t-md); line-height: 1.75;
    white-space: pre; letter-spacing: .01em;
}
/* 代码块里的滚动条收细一点，别抢戏 */
.md-code pre::-webkit-scrollbar { height: 8px; width: 8px; }
.md-code pre::-webkit-scrollbar-thumb { background: var(--hair-2); }

/* 代码高亮（自绘） */
.hl-key { color: #A6266E; }
.hl-str { color: #2E7D4F; }
.hl-num { color: #B1620A; }
.hl-com { color: var(--ink-3); font-style: italic; }
.hl-fun { color: #2A62B8; }
.hl-var { color: #7A4EA8; }
.hl-tag { color: #A6266E; }
[data-theme="dark"] .hl-key { color: #EF9AC2; }
[data-theme="dark"] .hl-str { color: #8FD3A6; }
[data-theme="dark"] .hl-num { color: #E8B36B; }
[data-theme="dark"] .hl-fun { color: #8FB6EE; }
[data-theme="dark"] .hl-var { color: #C3A6E8; }
[data-theme="dark"] .hl-tag { color: #EF9AC2; }

/* ==========================================================================
   13 编辑器与评论框
   ========================================================================== */
.editor { padding: var(--s5) var(--s5) var(--s5); }
.editor-foot { display: flex; align-items: center; gap: var(--s3); margin-top: 11px; }
.editor-foot .hint { font-size: var(--t-sm); color: var(--ink-3); }
.editor-foot .go { margin-left: auto; display: flex; gap: var(--s2); align-items: center; }

/* 评论框（thread.php 的回复框：直接放在 .editor 里的裸 textarea）
   之前重写样式表时漏了这条，导致回复框掉回浏览器默认样式 */
.editor textarea {
    display: block; width: 100%; min-height: 138px;
    padding: 12px 14px;
    border: 1px solid var(--hair-2); background: var(--surface); color: var(--ink);
    font-family: inherit; font-size: var(--t-base); line-height: 1.8;
    resize: vertical;
    transition: border-color var(--d2) var(--ease), background var(--d2) var(--ease);
}
.editor textarea::placeholder { color: var(--ink-3); }
.editor textarea:focus { outline: 1px solid var(--accent); outline-offset: 1px; border-color: var(--accent); }

/* 评论 / 发帖的输入区外框 */
.composer { border: 1px solid var(--hair-2); background: var(--surface); }
.composer-bar {
    display: flex; align-items: center; gap: 4px; flex-wrap: wrap;
    padding: 6px 8px; border-bottom: 1px solid var(--hair);
    background: var(--surface-2);
}
.cbar-btn {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 5px 11px;
    border: 1px solid transparent; background: none; cursor: pointer;
    font-size: var(--t-sm); color: var(--ink-2);
    transition: color var(--d1) var(--ease), border-color var(--d1) var(--ease), background var(--d1) var(--ease);
}
.cbar-btn:hover, .cbar-btn.on { color: var(--accent); border-color: var(--accent); background: var(--accent-soft); }
.cbar-btn[disabled] { opacity: .45; cursor: not-allowed; }
.cbar-tip { margin-left: auto; font-size: var(--t-xs); color: var(--ink-3); }
.composer textarea { border: none !important; min-height: 132px; }
.composer textarea:focus { outline: none !important; }

/* 表情面板（纯文字 emoji，不带图标） */
.emoji-panel {
    max-height: 234px; overflow-y: auto;
    padding: 10px 12px;
    border-bottom: 1px solid var(--hair);
    background: var(--surface);
}
.emoji-group + .emoji-group { margin-top: 10px; }
.emoji-group h4 {
    margin-bottom: 6px;
    font-size: var(--t-xs); font-weight: 700;
    letter-spacing: .1em; color: var(--ink-3);
}
.emoji-grid { display: flex; flex-wrap: wrap; gap: 2px; }
.emoji-btn {
    width: 34px; height: 34px;
    display: grid; place-items: center;
    border: 1px solid transparent; background: none; cursor: pointer;
    font-size: 20px; line-height: 1;
    transition: background var(--d1) var(--ease), border-color var(--d1) var(--ease), transform var(--d1) var(--ease-out);
}
.emoji-btn:hover { background: var(--surface-2); border-color: var(--hair-2); transform: scale(1.14); }

/* 已插入的表情图预览 */
.composer-stickers { display: flex; flex-wrap: wrap; gap: 10px; padding: 10px 12px 0; }
.composer-stickers:empty { display: none; }
.sticker-chip { position: relative; border: 1px solid var(--hair-2); background: var(--surface-2); }
.sticker-chip img { display: block; max-width: 104px; max-height: 104px; }
.sticker-chip button {
    position: absolute; top: -7px; right: -7px;
    width: 20px; height: 20px; display: grid; place-items: center;
    border: 1px solid var(--danger); background: var(--surface); color: var(--danger);
    cursor: pointer; font-size: 12px; line-height: 1;
}
.sticker-chip button:hover { background: var(--danger); color: #fff; }

/* 正文里的表情图：不套边框、限制尺寸，别把版面撑破 */
.md img[src*="/uploads/stickers/"] {
    display: inline-block;
    max-width: 190px; max-height: 190px; width: auto;
    margin: 4px 2px; border: none; background: none;
    vertical-align: middle;
}

.mde { position: relative; border: 1px solid var(--hair-2); background: var(--surface); overflow: hidden; }
.mde-top {
    display: flex; align-items: center; gap: 3px; flex-wrap: wrap;
    padding: 6px 8px; border-bottom: 1px solid var(--hair);
    background: var(--surface-2);
}
.mde-tab {
    padding: 5px 12px; border: 1px solid transparent; background: none;
    font-size: var(--t-sm); color: var(--ink-3); cursor: pointer;
    transition: all var(--d1) var(--ease);
}
.mde-tab:hover { color: var(--ink); }
.mde-tab.on { color: var(--accent); border-color: var(--accent-line); background: var(--accent-soft); font-weight: 600; }
.mde-tip { margin-left: auto; padding-right: 4px; font-size: var(--t-xs); color: var(--ink-3); }
/* 工具栏：图标按钮统一 30×30，悬停给一层浅底 + 强调色描边；
   纯文字的两个（表情 / GIF）做成小胶囊，免得跟图标混在一起显得乱 */
.mde-bar {
    display: flex; flex-wrap: wrap; align-items: center; gap: 2px;
    padding: 7px 9px; border-bottom: 1px solid var(--hair);
    background: var(--surface);
}
.mde-btn {
    min-width: 30px; height: 30px; padding: 0 7px;
    display: inline-flex; align-items: center; justify-content: center; gap: 5px;
    border: 1px solid transparent; background: none; color: var(--ink-2);
    font-size: var(--t-sm); font-family: inherit; cursor: pointer;
    border-radius: var(--r) !important;
    transition: background var(--d1) var(--ease), border-color var(--d1) var(--ease), color var(--d1) var(--ease);
}
.mde-btn:hover { background: var(--accent-soft); border-color: var(--accent-line); color: var(--accent); }
.mde-btn:active { transform: translateY(1px); }
.mde-btn svg { pointer-events: none; display: block; }
/* 纯文字的那两个按钮：小胶囊 */
.mde-btn[data-emoji-toggle],
.mde-btn[data-sticker-pick],
.mde-btn[data-md-pick] {
    min-width: 0; padding: 0 10px;
    font-size: var(--t-xs); letter-spacing: .04em;
    border-color: var(--hair-2);
}
.mde-btn[data-emoji-toggle]:hover,
.mde-btn[data-sticker-pick]:hover,
.mde-btn[data-md-pick]:hover { border-color: var(--accent); }
.mde-sep { width: 1px; align-self: stretch; background: var(--hair); margin: 4px 6px; }
.mde-body { display: grid; grid-template-columns: minmax(0, 1fr); }
.mde.split .mde-body { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
/* 并排模式下右边那半也要显示出来（默认模式就是并排，漏了这条等于没有实时预览） */
.mde.split .mde-preview { display: block; }
.mde.split .mde-preview.is-empty { display: grid; }
.mde textarea {
    width: 100%; min-height: 340px; padding: 15px 16px;
    display: block; border: none; background: transparent; color: var(--ink);
    font-family: var(--mono); font-size: var(--t-md); line-height: 1.8;
    resize: vertical; outline: none; tab-size: 4;
}
.mde-preview {
    display: none; min-height: 340px; max-height: 620px; overflow-y: auto;
    padding: 15px 18px; border-left: 1px solid var(--hair);
    background: var(--surface);
}
.mde-preview.is-empty { display: grid; place-items: center; color: var(--ink-3); font-size: var(--t-sm); }
.mde.mode-preview .mde-preview { display: block; }
.mde.mode-preview textarea { display: none; }
.mde.mode-preview .mde-bar { display: none; }
.mde-foot {
    display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap;
    padding: 8px 14px; border-top: 1px solid var(--hair);
    background: var(--surface-2); font-size: var(--t-xs); color: var(--ink-3);
}
.mde-drop-hint { display: inline-flex; align-items: center; gap: 5px; }
.mde-uploading { color: var(--accent); }
.mde-over {
    position: absolute; inset: 0; z-index: 5;
    display: grid; place-items: center;
    background: var(--accent-soft); border: 2px dashed var(--accent);
    color: var(--accent); font-size: var(--t-base); font-weight: 600;
    pointer-events: none;
}

/* ---- 名片背景：显示区域选择器 ----
   舞台按名片区的高度来（.pcard.has-bg 是 224px），这样这里看到的构图和主页上基本一致 */
.bgpick-stage {
    position: relative;
    height: 224px;
    overflow: hidden;
    border: 1px solid var(--hair-2);
    background: var(--bg-deep);
    cursor: grab;
    touch-action: none;     /* 手机上拖动画面时别让整页跟着滚 */
    user-select: none;
}
.bgpick-stage.is-dragging { cursor: grabbing; }
.bgpick-stage:focus-visible { outline: 1px solid var(--accent); outline-offset: 2px; }
.bgpick-media {
    width: 100%; height: 100%;
    object-fit: cover; display: block;
    pointer-events: none;   /* 拖动统一由舞台接管，别让视频自己吞掉手势 */
}
/* 三分线：给眼睛一个参照，压得很淡，只在拖动时稍微清楚一点 */
.bgpick-grid {
    position: absolute; inset: 0; pointer-events: none;
    opacity: .28;
    transition: opacity var(--d1) var(--ease);
    background-image:
        linear-gradient(to right, rgba(255, 255, 255, .9) 1px, transparent 1px),
        linear-gradient(to bottom, rgba(255, 255, 255, .9) 1px, transparent 1px);
    background-size: 33.3333% 33.3333%;
    background-position: -1px -1px;
}
.bgpick-stage.is-dragging .bgpick-grid { opacity: .5; }

.bgpick-bar {
    display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap;
    margin-top: var(--s3);
}
.bgpick-pos {
    margin-left: auto;
    font-size: var(--t-xs); color: var(--ink-2);
    letter-spacing: .02em;
}
.bgpick-zoom {
    display: inline-flex; align-items: center; gap: 8px;
    font-size: var(--t-sm); color: var(--ink-3);
}
.bgpick-zoom input[type=range] { width: 116px; accent-color: var(--accent); }

.bgpick-empty {
    padding: 40px;
    margin-bottom: var(--s4);
    text-align: center;
    font-size: var(--t-md);
    color: var(--ink-3);
    background: var(--bg-deep);
    border: 1px solid var(--hair-2);
}
/* 人机验证挂载点 */
.ac-slot { margin: 6px 0 var(--s4); }
.ac-slot #captcha-element { width: 100%; }
.ac-slot #captcha-element > div { margin: 0 auto; }

/* 验证已通过、等用户自己点按钮：外面套一圈细线 + 轻轻跳一下，提示现在可以按了 */
@keyframes acPulse {
    0%   { transform: scale(1); }
    45%  { transform: scale(1.035); }
    100% { transform: scale(1); }
}
.btn.ac-ready {
    outline: 1px solid var(--accent);
    outline-offset: 2px;
    animation: acPulse .42s var(--ease-out) 1;
}

/* 验证参数已经交给服务端、还在等确认：按钮压暗 + 底下一道来回走的细线，
   让用户知道是「在确认」而不是「点了没反应」 */
@keyframes acWait {
    0%   { transform: scaleX(.12); transform-origin: left center; }
    50%  { transform: scaleX(1);   transform-origin: left center; }
    100% { transform: scaleX(.12); transform-origin: right center; }
}
.btn.ac-wait { position: relative; opacity: .72; cursor: progress; }
.btn.ac-wait::after {
    content: '';
    position: absolute; left: 0; right: 0; bottom: -1px; height: 2px;
    background: var(--accent); opacity: .65;
    animation: acWait 1.15s var(--ease) infinite;
}

/* ==========================================================================
   14 侧栏
   ========================================================================== */
.side-card {
    padding: var(--s4) var(--s4);
    background: var(--surface); border: 1px solid var(--hair-2);
}
.side-card + .side-card { margin-top: var(--s4); }
.side-card h3 {
    margin-bottom: var(--s3); padding-bottom: 9px;
    font-size: var(--t-xs); font-weight: 700;
    letter-spacing: .14em; color: var(--ink-3);
    border-bottom: 1px solid var(--hair);
}
.stat-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s3) var(--s2); }
.stat-grid div b { display: block; font-family: var(--mono); font-size: 17px; font-weight: 600; letter-spacing: -.01em; }
.stat-grid div span { font-size: var(--t-xs); color: var(--ink-3); }
.user-mini {
    display: flex; align-items: center; gap: 9px;
    padding: 6px 0;
    transition: color var(--d1) var(--ease);
}
.user-mini:hover .um-info b { color: var(--accent); }
.user-mini .um-info { flex: 1; min-width: 0; }
.user-mini .um-info b { display: block; font-size: var(--t-md); font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; transition: color var(--d1) var(--ease); }
.user-mini .um-info span { font-size: var(--t-xs); color: var(--ink-3); }
.side-note { font-size: var(--t-sm); line-height: 1.85; color: var(--ink-2); }
.side-note a { color: var(--accent); }

/* ==========================================================================
   15 分页
   ========================================================================== */
.pager {
    display: flex; align-items: center; justify-content: center; gap: 5px; flex-wrap: wrap;
    padding: var(--s4); border-top: 1px solid var(--hair);
}
.pg {
    min-width: 34px; height: 34px; padding: 0 11px;
    display: inline-flex; align-items: center; justify-content: center;
    border: 1px solid var(--hair-2); background: transparent;
    font-size: var(--t-sm); font-family: var(--mono); color: var(--ink-2);
    transition: all var(--d1) var(--ease);
}
.pg:hover { color: var(--accent); border-color: var(--accent); background: var(--accent-soft); }
.pg.on { color: var(--accent-ink); background: var(--accent); border-color: var(--accent); font-weight: 700; }
.pg-dots { padding: 0 2px; color: var(--ink-3); }

/* ==========================================================================
   16 个人主页
   ========================================================================== */
.pcard { position: relative; overflow: hidden; background: var(--surface); border: 1px solid var(--hair-2); }
.pcard-bg { position: absolute; inset: 0; z-index: 0; background: var(--bg-deep); }
.pcard-bg img, .pcard-bg video { width: 100%; height: 100%; object-fit: cover; display: block; }
.pcard-bg::after {
    content: ''; position: absolute; inset: 0; pointer-events: none;
    background: linear-gradient(180deg, rgba(10, 14, 20, .12) 0%, rgba(10, 14, 20, .36) 45%, rgba(10, 14, 20, .72) 100%);
}
.pcard-in { position: relative; z-index: 1; display: flex; gap: var(--s5); align-items: flex-end; padding: 30px var(--s6) var(--s5); }
.pcard.has-bg { min-height: 224px; }
.pcard.has-bg .pcard-in { color: #fff; }
.pcard.has-bg .bio,
.pcard.has-bg .pstat,
.pcard.has-bg .pstat b { color: rgba(255, 255, 255, .92); }
.pcard.has-bg h1,
.pcard.has-bg .bio { text-shadow: 0 1px 6px rgba(0, 0, 0, .5); }
.pcard-body { padding: 0 var(--s6) var(--s5); }
.pcard .pcard-in + .pcard-body { padding-top: 0; }
.pcard-sign {
    margin-top: var(--s3); padding-top: var(--s3);
    font-size: var(--t-sm); line-height: 1.85; color: var(--ink-3);
    border-top: 1px solid var(--hair);
}
.pcard.has-bg .pcard-sign { border-top-color: rgba(255, 255, 255, .28); color: rgba(255, 255, 255, .82); }
.profile-h { display: flex; gap: var(--s5); align-items: center; padding: var(--s6); }
.profile-h .pi { flex: 1; min-width: 0; }
.profile-h h1 { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; font-size: var(--t-xl); font-weight: 700; }
.profile-h .bio { margin-top: 7px; font-size: var(--t-md); color: var(--ink-2); line-height: 1.8; }
.profile-h .pstat { display: flex; gap: var(--s5); flex-wrap: wrap; margin-top: 11px; font-size: var(--t-sm); color: var(--ink-3); }
.profile-h .pstat b { font-family: var(--mono); color: var(--ink); font-weight: 600; }
.profile-actions { display: flex; gap: var(--s2); }

/* 标签页 */
.tabs { display: flex; gap: var(--s1); padding: 0 var(--s5); border-bottom: 1px solid var(--hair); }
.tab {
    position: relative;
    padding: 13px 15px;
    font-size: var(--t-md); font-weight: 500; color: var(--ink-3);
    transition: color var(--d1) var(--ease);
}
.tab::after {
    content: ''; position: absolute; left: 13px; right: 13px; bottom: -1px; height: 2px;
    background: var(--accent);
    transform: scaleX(0); transform-origin: left center;
    transition: transform var(--d2) var(--ease-out);
}
.tab:hover { color: var(--ink); }
.tab.on { color: var(--accent); font-weight: 600; }
.tab.on::after { transform: scaleX(1); }

/* ==========================================================================
   17 消息通知
   ========================================================================== */
.nrow {
    display: flex; align-items: stretch;
    border-bottom: 1px solid var(--hair);
    border-left: 2px solid transparent;
    transition: background var(--d2) var(--ease), border-color var(--d2) var(--ease);
}
.nrow:last-child { border-bottom: none; }
.nrow:hover { background: var(--surface-2); }
.nrow.unread { background: var(--accent-soft); border-left-color: var(--accent); }
.nrow-link { display: flex; gap: var(--s3); flex: 1; min-width: 0; padding: 15px 0 15px var(--s5); }
.nrow-del { display: flex; align-items: center; padding: 0 var(--s4); flex: none; }
.nrow-del button {
    width: 30px; height: 30px;
    display: grid; place-items: center;
    border: 1px solid transparent; background: none; color: var(--ink-3);
    cursor: pointer;
    opacity: 0;
    transition: all var(--d2) var(--ease);
}
.nrow:hover .nrow-del button { opacity: 1; }
.nrow-del button:hover { color: var(--danger); border-color: var(--danger); background: var(--danger-soft); }

.note-row { display: flex; gap: 13px; padding: 15px var(--s5); border-bottom: 1px solid var(--hair); }
.note-row:last-child { border-bottom: none; }
.note-row.unread { border-left: 2px solid var(--accent); }
.note-main { flex: 1; min-width: 0; }
.note-t { font-size: var(--t-md); line-height: 1.7; }
.note-t b { font-weight: 600; }
.note-x { margin-top: 4px; font-size: var(--t-sm); color: var(--ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.note-time { margin-top: 5px; font-family: var(--mono); font-size: var(--t-xs); color: var(--ink-3); }

/* 系统消息 */
.msg-list-item {
    display: flex; gap: var(--s3);
    padding: var(--s4) var(--s5);
    border-bottom: 1px solid var(--hair);
    border-left: 2px solid transparent;
    transition: background var(--d2) var(--ease), border-color var(--d2) var(--ease);
}
.msg-list-item:last-child { border-bottom: none; }
.msg-list-item:hover { background: var(--surface-2); }
.msg-list-item.unread { background: var(--accent-soft); border-left-color: var(--accent); }
.msg-ico {
    width: 36px; height: 36px; flex: none;
    display: grid; place-items: center;
    background: var(--accent-soft); border: 1px solid var(--accent-line); color: var(--accent);
}
.msg-body { flex: 1; min-width: 0; }
.msg-title { font-size: var(--t-base); font-weight: 600; }
.msg-x { margin-top: 4px; font-size: var(--t-sm); color: var(--ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.msg-time { margin-top: 5px; font-family: var(--mono); font-size: var(--t-xs); color: var(--ink-3); }
.msg-doc h1 { font-size: var(--t-xl); margin-bottom: 6px; }
.msg-doc .msg-meta { margin-bottom: var(--s5); padding-bottom: var(--s4); font-size: var(--t-sm); color: var(--ink-3); border-bottom: 1px solid var(--hair); }

/* ==========================================================================
   18 好友
   ========================================================================== */
.flat-stack { display: flex; flex-direction: column; gap: var(--s5); }
.fcard { background: var(--surface); border: 1px solid var(--hair-2); }
.fcard-h {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    min-height: 48px; padding: 11px var(--s5);
    border-bottom: 1px solid var(--hair);
    background: var(--surface-2);
}
.fcard-h h2 { font-size: var(--t-md); font-weight: 700; letter-spacing: .08em; }
.fcard-h .fsub { font-size: var(--t-sm); color: var(--ink-3); }
.fcard-b { padding: 0; }

.fsearch { display: flex; gap: var(--s2); padding: var(--s4) var(--s5); }
.fsearch .inp { flex: 1; min-width: 0; }
.fhint { padding: 0 var(--s5) var(--s4); font-size: var(--t-sm); line-height: 1.85; color: var(--ink-3); }
.fempty { padding: 40px var(--s5); text-align: center; font-size: var(--t-md); line-height: 2; color: var(--ink-3); }
.fempty a { color: var(--accent); }

.flist { border-top: 1px solid var(--hair); }
.frow {
    position: relative;
    display: flex; align-items: center; gap: var(--s3);
    padding: 13px var(--s5);
    border-bottom: 1px solid var(--hair);
    border-left: 2px solid transparent;
    transition: background var(--d2) var(--ease), border-color var(--d2) var(--ease);
}
.frow:last-child { border-bottom: none; }
.frow:hover { background: var(--surface-2); border-left-color: var(--accent); }
.frow-main { flex: 1; min-width: 0; }
.frow-name { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; font-size: var(--t-base); font-weight: 500; }
.frow-name a { transition: color var(--d1) var(--ease); }
.frow-name a:hover { color: var(--accent); }
.frow-sub { margin-top: 3px; font-size: var(--t-sm); color: var(--ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.frow-act { display: flex; gap: 7px; align-items: center; flex: none; flex-wrap: wrap; }
.finline { display: flex; gap: 7px; }
.fid { font-family: var(--mono); font-size: var(--t-xs); color: var(--ink-3); }
.fstate { font-size: var(--t-sm); color: var(--ink-3); }

/* ==========================================================================
   19 私信
   ========================================================================== */
.convo {
    display: flex; align-items: center; gap: var(--s3);
    padding: 13px var(--s5);
    border-bottom: 1px solid var(--hair);
    border-left: 2px solid transparent;
    transition: background var(--d2) var(--ease), border-color var(--d2) var(--ease);
}
.convo:last-child { border-bottom: none; }
.convo:hover { background: var(--surface-2); border-left-color: var(--accent); }
.convo.unread { background: var(--accent-soft); border-left-color: var(--accent); }
.convo-main { flex: 1; min-width: 0; }
.convo-top { display: flex; align-items: baseline; gap: var(--s2); }
.convo-top b { font-size: var(--t-base); font-weight: 600; }
.convo-time { margin-left: auto; flex: none; font-family: var(--mono); font-size: var(--t-xs); color: var(--ink-3); }
.convo-x { margin-top: 3px; font-size: var(--t-sm); color: var(--ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.convo-dot {
    flex: none; padding: 1px 7px;
    background: var(--danger); color: #fff;
    font-style: normal; font-size: var(--t-xs); font-family: var(--mono);
}

.chat-card { display: flex; flex-direction: column; }
.chat-stream {
    display: flex; flex-direction: column; gap: 13px;
    padding: var(--s5); min-height: 220px; max-height: 60vh; overflow-y: auto;
    background: var(--surface-2);
}
.chat-day { text-align: center; }
.chat-day span {
    display: inline-block; padding: 2px 10px;
    background: var(--surface); border: 1px solid var(--hair);
    font-family: var(--mono); font-size: var(--t-xs); color: var(--ink-3);
}
.chat-msg { display: flex; gap: 9px; align-items: flex-start; max-width: 78%; animation: bubbleIn var(--d3) var(--ease-out) both; }
.chat-msg.me { margin-left: auto; flex-direction: row-reverse; }
.chat-msg .cm-av { flex: none; }
.cm-body { min-width: 0; }
.cm-bubble {
    padding: 9px 13px;
    font-size: var(--t-base); line-height: 1.75;
    word-wrap: break-word; overflow-wrap: anywhere;
    background: var(--surface); border: 1px solid var(--hair-2);
}
.chat-msg.me .cm-bubble { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.cm-time { display: flex; align-items: center; gap: var(--s2); margin-top: 4px; font-family: var(--mono); font-size: var(--t-xs); color: var(--ink-3); }
.chat-msg.me .cm-time { justify-content: flex-end; }
.cm-del {
    padding: 0 0 0 8px;
    border: none; background: none; cursor: pointer;
    color: var(--ink-3); font-size: var(--t-xs);
    opacity: 0;
    transition: opacity var(--d2) var(--ease), color var(--d1) var(--ease);
}
.chat-msg:hover .cm-del { opacity: 1; }
.cm-del:hover { color: var(--danger); }

.chat-compose {
    display: flex; gap: var(--s3); align-items: flex-end;
    padding: 13px; border-top: 1px solid var(--hair-2); background: var(--surface);
}
.chat-compose textarea {
    flex: 1; min-width: 0; min-height: 46px; max-height: 160px;
    padding: 12px 13px;
    border: 1px solid var(--hair-2); background: var(--surface-2); color: var(--ink);
    font-size: var(--t-base); line-height: 1.7; resize: none; outline: none;
    transition: border-color var(--d2) var(--ease), background var(--d2) var(--ease), box-shadow var(--d2) var(--ease);
}
.chat-compose textarea:focus {
    outline: 1px solid var(--accent);
    outline-offset: 1px;
    border-color: var(--accent);
    background: var(--surface);
}

/* ==========================================================================
   20 后台
   ========================================================================== */
.admin-grid { display: grid; grid-template-columns: 184px minmax(0, 1fr); gap: var(--s5); align-items: start; }
.admin-nav {
    position: sticky; top: calc(var(--bar-h) + 20px);
    padding: 5px; background: var(--surface); border: 1px solid var(--hair-2);
}
.admin-nav a {
    display: flex; align-items: center; gap: 9px;
    padding: 9px 12px;
    font-size: var(--t-md); color: var(--ink-2);
    border-left: 2px solid transparent;
    transition: all var(--d1) var(--ease);
}
.admin-nav a:hover { background: var(--surface-2); color: var(--accent); border-left-color: var(--hair-2); }
.admin-nav a.on { color: var(--accent); font-weight: 600; border-left-color: var(--accent); background: var(--accent-soft); }

.tbl { width: 100%; border-collapse: collapse; font-size: var(--t-md); }
.tbl th {
    padding: 11px var(--s4); text-align: left; white-space: nowrap;
    font-size: var(--t-xs); font-weight: 700; letter-spacing: .1em;
    color: var(--ink-3); background: var(--surface-2);
    border-bottom: 1px solid var(--hair-2);
}
.tbl td { padding: 12px var(--s4); border-bottom: 1px solid var(--hair); vertical-align: middle; }
.tbl tr:last-child td { border-bottom: none; }
.tbl tbody tr { transition: background var(--d1) var(--ease); }
.tbl tr:hover td { background: var(--surface-2); }
.tbl .actions { display: flex; gap: 6px; justify-content: flex-end; flex-wrap: wrap; }

/* ==========================================================================
   21 搜索弹窗
   ========================================================================== */
.search-modal {
    position: fixed; inset: 0; z-index: 1200;
    display: none; align-items: flex-start; justify-content: center;
    padding: 11vh 18px 18px;
    background: rgba(16, 18, 24, .5);
}
.search-modal.on { display: flex; animation: fadeIn var(--d2) var(--ease) both; }
.search-box {
    width: 100%; max-width: 560px; overflow: hidden;
    background: var(--surface); border: 1px solid var(--hair-2);
}
.search-modal.on .search-box { animation: boxIn var(--d3) var(--ease-out) both; }
.search-head { display: flex; align-items: center; gap: var(--s3); padding: 15px 18px; border-bottom: 1px solid var(--hair); }
.search-ic { color: var(--ink-3); }
.search-head input {
    flex: 1; border: none; background: transparent; outline: none;
    font-size: var(--t-lg); color: var(--ink);
}
.search-head input::placeholder { color: var(--ink-3); }
.search-close {
    flex: none; width: 30px; height: 30px;
    display: grid; place-items: center;
    border: 1px solid transparent; background: none; color: var(--ink-3);
    cursor: pointer;
    transition: all var(--d1) var(--ease);
}
.search-close:hover { color: var(--danger); border-color: var(--danger); }
.search-results { max-height: 52vh; overflow-y: auto; }
.search-results:empty { display: none; }
.sr-item {
    display: block; padding: 12px 18px;
    border-bottom: 1px solid var(--hair);
    border-left: 2px solid transparent;
    transition: background var(--d1) var(--ease), border-color var(--d1) var(--ease);
}
.sr-item:last-child { border-bottom: none; }
.sr-item:hover, .sr-item.sel { background: var(--accent-soft); border-left-color: var(--accent); }
.sr-t { font-size: var(--t-base); font-weight: 500; }
.sr-x { margin-top: 3px; font-size: var(--t-sm); color: var(--ink-3); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.sr-hint { padding: 26px 18px; text-align: center; font-size: var(--t-md); color: var(--ink-3); }
.search-foot { padding: 9px 18px; border-top: 1px solid var(--hair); background: var(--surface-2); font-size: var(--t-xs); color: var(--ink-3); }

/* ==========================================================================
   22 头像
   ========================================================================== */
.av {
    width: 38px; height: 38px; flex: none;
    display: inline-grid; place-items: center; overflow: hidden;
    background: var(--bg-deep); border: 1px solid var(--hair);
    border-radius: 50%;
    color: #fff; font-size: var(--t-md); font-weight: 600;
    object-fit: cover;
}
.av-sm { width: 26px; height: 26px; font-size: var(--t-xs); }
.av-tb { width: 22px; height: 22px; font-size: 10px; }
.av-md { width: 46px; height: 46px; font-size: var(--t-lg); }
.av-lg { width: 76px; height: 76px; font-size: 26px; }
.av-xl { width: 100px; height: 100px; font-size: 36px; }
.av-letter { border: 1px solid rgba(255, 255, 255, .35); }

/* ==========================================================================
   23 杂项
   ========================================================================== */
.toast {
    position: fixed; left: 50%; bottom: 34px;
    padding: 10px 20px;
    background: rgba(24, 26, 32, .96); color: #fff;
    font-size: var(--t-md);
    z-index: 2000;
    opacity: 0; pointer-events: none;
    transform: translate(-50%, 12px);
    transition: opacity var(--d3) var(--ease), transform var(--d3) var(--ease-out);
}
.toast.on { opacity: 1; transform: translate(-50%, 0); }

.to-top {
    position: fixed; right: 26px; bottom: 30px;
    width: 40px; height: 40px;
    display: grid; place-items: center;
    background: var(--surface); border: 1px solid var(--hair-2); color: var(--ink-2);
    cursor: pointer; z-index: 800;
    opacity: 0; visibility: hidden;
    transform: translateY(8px);
    transition: opacity var(--d3) var(--ease), transform var(--d3) var(--ease-out), visibility var(--d3), color var(--d1) var(--ease), border-color var(--d1) var(--ease), background var(--d1) var(--ease);
}
.to-top.on { opacity: 1; visibility: visible; transform: none; }
.to-top:hover { color: var(--accent); border-color: var(--accent); background: var(--accent-soft); }

.img-zoom {
    position: fixed; inset: 0; z-index: 3000;
    display: grid; place-items: center; padding: 24px;
    background: rgba(12, 14, 18, .88);
    cursor: zoom-out;
    animation: fadeIn var(--d1) var(--ease) both;
}
.img-zoom img { max-width: 96vw; max-height: 92vh; border: 1px solid rgba(255, 255, 255, .22); animation: boxIn var(--d3) var(--ease-out) both; }

/* 阅读用时之类的内联块（预留） */
.foot-online .live { margin-right: 1px; }

/* ==========================================================================
   24 动效
   原则：只做「淡入 + 轻微位移」和「线条生长」，
   不做弹跳、不做旋转、不做大幅位移，避免廉价的动感。
   ========================================================================== */
@keyframes fadeIn  { from { opacity: 0; } to { opacity: 1; } }
@keyframes rise    { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes flashIn { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: none; } }
@keyframes boxIn   { from { opacity: 0; transform: translateY(-12px); } to { opacity: 1; transform: none; } }
@keyframes bubbleIn{ from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@keyframes lineGrow{ from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* 首屏内容整块淡入 */
.main > .card,
.main > .home,
.main > .flat-stack,
.main > .layout,
.main > .auth-wrap,
.main > .page-h { animation: rise var(--d4) var(--ease-out) both; }

/* 列表逐条淡入：只给前 12 条排延迟，后面的直接显示，避免长列表等待 */
.card-b > .t-row,
.card-b > .board-row,
.card-b > .nrow,
.card-b > .msg-list-item,
.flist > .frow,
.flist > .convo {
    animation: rise var(--d3) var(--ease-out) both;
}
.card-b > :nth-child(1),  .flist > :nth-child(1)  { animation-delay: .02s; }
.card-b > :nth-child(2),  .flist > :nth-child(2)  { animation-delay: .05s; }
.card-b > :nth-child(3),  .flist > :nth-child(3)  { animation-delay: .08s; }
.card-b > :nth-child(4),  .flist > :nth-child(4)  { animation-delay: .11s; }
.card-b > :nth-child(5),  .flist > :nth-child(5)  { animation-delay: .14s; }
.card-b > :nth-child(6),  .flist > :nth-child(6)  { animation-delay: .17s; }
.card-b > :nth-child(7),  .flist > :nth-child(7)  { animation-delay: .20s; }
.card-b > :nth-child(8),  .flist > :nth-child(8)  { animation-delay: .23s; }
.card-b > :nth-child(9),  .flist > :nth-child(9)  { animation-delay: .26s; }
.card-b > :nth-child(10), .flist > :nth-child(10) { animation-delay: .29s; }
.card-b > :nth-child(n+11), .flist > :nth-child(n+11) { animation-delay: .32s; }

/* 主题切换：浏览器支持的话做一次交叉淡入，比硬切自然 */
@view-transition { navigation: none; }
::view-transition-old(root),
::view-transition-new(root) { animation-duration: .32s; animation-timing-function: cubic-bezier(.4, 0, .2, 1); }

/* PJAX：换页时整块内容先淡出，换完由子元素自己的入场动画接手 */
#main { transition: opacity .17s var(--ease), transform .17s var(--ease-out); }
html.pjax-out #main { opacity: 0; transform: translateY(6px); }

/* 尊重系统的「减少动态效果」设置 */
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after {
        animation-duration: .001ms !important;
        animation-delay: 0ms !important;
        transition-duration: .001ms !important;
    }
}

/* ==========================================================================
   25 响应式
   ========================================================================== */
@media (max-width: 940px) {
    .layout { grid-template-columns: minmax(0, 1fr); }
    .admin-grid { grid-template-columns: minmax(0, 1fr); }
    .admin-nav { position: static; display: flex; overflow-x: auto; gap: 4px; }
    .admin-nav a { white-space: nowrap; }
    .home { grid-template-columns: minmax(0, 1fr); }
    .bn-list { display: flex; gap: 6px; overflow-x: auto; padding-bottom: 3px; }
    .bn-item { flex: none; padding: 7px 11px; }
    .bn-item em { display: none; }
    .pcard-in { padding: 22px var(--s4) var(--s4); flex-direction: column; align-items: center; text-align: center; }
    .mde.split .mde-body { grid-template-columns: minmax(0, 1fr); }
    .mde.split .mde-preview { border-left: none; border-top: 1px solid var(--hair); }
    /* 顶栏到这一档就挤了：通知 / 私信收进用户菜单（那里有同样的角标） */
    .tb-act { display: none; }
}

@media (max-width: 720px) {
    :root { --bar-h: 54px; }
    .wrap { padding: 0 14px; }
    .brand-text i { display: none; }
    .nav { display: none; }
    .topbar-right { margin-left: auto; gap: 4px; }
    /* 窄屏顶栏只留：菜单 / 主题 / 头像(或注册) / 发帖，放不下的都收进菜单面板 */
    .auth-btn { display: none; }
    .btn-post { padding: 0 12px; }
    .user-btn { padding: 0 4px 0 3px; }
    .user-btn .uname { display: none; }
    .mb-btn { display: grid; place-items: center; }
    /* 展开后的导航面板：固定贴在顶栏下沿 */
    body.mb-open .nav {
        display: flex; flex-direction: column; align-items: stretch;
        position: fixed; top: var(--bar-h); left: 0; right: 0;
        margin: 0; gap: 0;
        padding: var(--s3) 14px var(--s4);
        background: var(--surface);
        border-bottom: 1px solid var(--hair-2);
        z-index: 899;
    }
    body.mb-open .nav .nav-a {
        padding: 11px 0; font-size: var(--t-md); font-weight: 400;
    }
    body.mb-open .nav .nav-a::after { display: none; }
    body.mb-open .nav .nav-a + .nav-a { border-top: 1px solid var(--hair); }
    /* 登录 / 注册只在窄屏面板里出现 */
    body.mb-open .nav-a-mb { display: block; }
    .post { flex-direction: column; gap: var(--s3); padding: var(--s4); }
    .post-side { width: auto; display: flex; align-items: center; gap: var(--s2); text-align: left; }
    .post-side .pn { margin-top: 0; }
    .post-side .pt { margin-top: 0; }
    .sub-body, .sub-act, .sub-more { padding-left: 0; }
    .board-last { display: none; }
    .board-num { gap: var(--s4); }
    .board-num div { min-width: 38px; }
    .board-row, .t-row { padding: 14px 15px; gap: 11px; }
    .board-ico { width: 36px; height: 36px; font-size: var(--t-base); }
    .t-right { width: 80px; }
    .thread-h, .card-h, .editor { padding-left: 15px; padding-right: 15px; }
    .profile-h { flex-direction: column; text-align: center; align-items: center; }
    .profile-h .pstat { justify-content: center; }
    .foot-in { justify-content: center; text-align: center; }
    .search-modal { padding-top: 7vh; }
    .chat-msg { max-width: 92%; }
    .frow { flex-wrap: wrap; }
    .frow-act { width: 100%; }
    .nrow-link { padding-left: var(--s4); gap: 10px; }
    .nrow-del { padding: 0 10px; }
    .nrow-del button { opacity: 1; }
    .t-admin { opacity: 1; transform: none; }
    .page-h h1 { font-size: 18px; }
    .auth-title h1 { font-size: 22px; }
}

@media (max-width: 420px) {
    .t-right { display: none; }
    .card-b.pad, .pad, .editor { padding: 15px; }
    .field-row { flex-direction: column; gap: 0; }
    /* 很窄的机器上把顶栏再挤一挤 */
    .brand-text { display: none; }
    .ts-opt { padding: 0 7px; }
    .btn-post { padding: 0 10px; }
}

/* ==========================================================================
   26 等级：头像框 / 等级标识 / 等级页
   ========================================================================== */

/* ---- 头像框 ----
   框是 PNG（从参考图切出来的），每一张的「洞」都已经裁到图片正中，
   所以这里只要把框和头像都居中叠起来就对得齐，不用为每一级算偏移。

   尺寸全部由行内自定义属性算出来：
     --av     头像边长（px，从 av-xl / av-lg / av-md 推出来）
     --fw/-fh 框图片的宽高
     --fhole  洞的直径
   框的盒子 = 头像 × 框/洞，所以 3 级约 1.45 倍，4/5 级带翅膀约 1.8～1.9 倍。 */
.avf {
    position: relative;
    display: inline-grid;
    place-items: center;
    flex: none;
    line-height: 0;
    width: calc(var(--av) * var(--fw) / var(--fhole));
    height: calc(var(--av) * var(--fh) / var(--fhole));
}
.avf-img {
    position: absolute;
    left: 50%; top: 50%;
    transform: translate(-50%, -50%);
    width: 100%; height: 100%;
    z-index: 2;
    pointer-events: none;
    user-select: none;
    -webkit-user-drag: none;
}
/* 框里的头像必须是正圆，不然方角会从圈里戳出来 */
.avf > .av,
.avf > .avf-hole {
    position: relative;
    z-index: 1;
    border-radius: 50%;
    border-color: transparent;
}
/* 不依赖父子选择器再写一条，等级表演示格、后台预览里都是这个类 */
.avf-hole { border-radius: 50%; }

/* 演示格里的头像大小跟着容器走：这样不管头像是 <img> 还是首字方块都一致 */
.avf-demo > .avf-hole {
    width: var(--av);
    height: var(--av);
    font-size: calc(var(--av) * 0.42);
}

/* ---- 流光 ----
   把框图片本身当遮罩，于是一道斜着的光只沿着框的形状扫过去，
   框外面完全不受影响。三级开始有，等级越高扫得越快。 */
.avf-shine {
    position: absolute;
    inset: 0;
    z-index: 3;
    pointer-events: none;
    background-image: linear-gradient(105deg,
        rgba(255, 255, 255, 0) 44%,
        rgba(255, 255, 255, .95) 50%,
        rgba(255, 255, 255, 0) 56%);
    background-size: 300% 100%;
    background-repeat: no-repeat;
    background-position: 110% 0;
    -webkit-mask-image: var(--frame);
            mask-image: var(--frame);
    -webkit-mask-size: 100% 100%;
            mask-size: 100% 100%;
    -webkit-mask-repeat: no-repeat;
            mask-repeat: no-repeat;
}
.fr-3 .avf-shine { animation: dmxShine 6.5s var(--ease) infinite; }
.fr-4 .avf-shine { animation: dmxShine 3.4s var(--ease) infinite; }
.fr-5 .avf-shine { animation: dmxShine 2.2s linear infinite; }

@keyframes dmxShine {
    0%        { background-position: 110% 0; }
    65%, 100% { background-position: -10% 0; }
}

/* 四五级额外给框本体加一层呼吸光晕，动静更大 */
.fr-4 .avf-img { animation: dmxGlow 3.6s var(--ease) infinite; }
.fr-5 .avf-img { animation: dmxGlow 2.4s var(--ease) infinite; }
@keyframes dmxGlow {
    0%, 100% { filter: brightness(1)    drop-shadow(0 0 0 rgba(255, 255, 255, 0)); }
    50%      { filter: brightness(1.12) drop-shadow(0 0 5px rgba(255, 255, 255, .45)); }
}

/* ---- 等级标识 ----
   一级连框都没有，往上逐层加：描边 → 强调色 → 实心底 + 流光 → 金粉底 + 更快的流光。 */
.lvb {
    position: relative;
    display: inline-flex; align-items: center;
    height: 20px; padding: 0 8px;
    border: 1px solid transparent;
    border-radius: var(--r);
    font-size: var(--t-xs); line-height: 1;
    letter-spacing: .03em; white-space: nowrap;
    overflow: hidden;
}
.lvb-t { font-weight: 400; }

.lvb-1 { padding: 0; color: var(--ink-3); }

.lvb-2 { border-color: var(--hair-2); color: var(--ink-2); }

.lvb-3 { border-color: var(--accent); color: var(--accent); }

.lvb-4 {
    border-color: var(--accent);
    background: var(--accent);
    color: var(--accent-ink);
    box-shadow: none;
}

.lvb-5 {
    border-color: transparent;
    background: linear-gradient(135deg, #8E4EC6 0%, #D94F8A 100%);
    color: #fff;
}

/* 标识上的流光：一道斜光从左扫到右 */
.lvb-shine {
    position: absolute;
    inset: 0;
    pointer-events: none;
    background-image: linear-gradient(105deg,
        rgba(255, 255, 255, 0) 38%,
        rgba(255, 255, 255, .9) 50%,
        rgba(255, 255, 255, 0) 62%);
    background-size: 300% 100%;
    background-repeat: no-repeat;
    background-position: 110% 0;
}
.lvb-3 .lvb-shine { animation: dmxShine 5s var(--ease) infinite; }
.lvb-4 .lvb-shine { animation: dmxShine 3s var(--ease) infinite; }
.lvb-5 .lvb-shine { animation: dmxShine 1.9s linear infinite; }

/* 标记里的字压在流光上面，不然光扫过去会盖住文字 */
.lvb-t { position: relative; z-index: 1; }

/* ---- 等级页 ---- */
.lv-hero { display: flex; gap: var(--s5); align-items: center; flex-wrap: wrap; }
.lv-hero-av { flex: none; }
.lv-hero-main { flex: 1; min-width: 240px; }
.lv-hero-top { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; }
.lv-hero-name { font-size: 20px; font-weight: 700; }
.lv-hero-title { font-size: var(--t-sm); color: var(--ink-3); letter-spacing: .12em; }

.lv-bar {
    margin-top: var(--s3); height: 6px;
    background: var(--surface-2); border: 1px solid var(--hair);
    overflow: hidden;
}
.lv-bar-in {
    display: block; height: 100%; background: var(--accent);
    transition: width var(--d3) var(--ease-out);
}
.lv-meta {
    display: flex; gap: var(--s4); flex-wrap: wrap;
    margin-top: 10px; font-size: var(--t-sm); color: var(--ink-3);
}
.lv-meta b { color: var(--ink); font-family: var(--mono); }
.lv-meta .lv-done { color: var(--accent); font-weight: 600; }

.lv-act { display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap; margin-top: var(--s4); }
.lv-tip { font-size: var(--t-sm); color: var(--ink-3); }
.lv-tip b { color: var(--ink); font-family: var(--mono); }
.btn.is-busy { opacity: .55; pointer-events: none; }

/* 等级表 */
.lv-row {
    display: flex; align-items: center; gap: var(--s4);
    padding: 14px var(--s5);
    border-bottom: 1px solid var(--hair);
}
.lv-row:last-child { border-bottom: 0; }
.lv-row.on { background: var(--surface-2); }
.lv-row-fr { flex: none; }
.lv-row-main { flex: 1; min-width: 0; }
.lv-row-t { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; font-size: var(--t-md); }
.lv-row-d { margin-top: 4px; font-size: var(--t-sm); color: var(--ink-3); }
.lv-row-need { flex: none; text-align: right; font-size: var(--t-xs); color: var(--ink-3); }
.lv-row-need b { display: block; font-size: 15px; color: var(--ink); font-family: var(--mono); }

/* 经验规则 */
.lv-rule-head,
.lv-rule {
    display: grid; grid-template-columns: 1.5fr .7fr .8fr .9fr;
    gap: var(--s3); align-items: center;
    padding: 11px var(--s5);
}
.lv-rule-head {
    font-size: var(--t-xs); color: var(--ink-3); letter-spacing: .06em;
    border-bottom: 1px solid var(--hair-2);
}
.lv-rule { border-bottom: 1px solid var(--hair); font-size: var(--t-md); }
.lv-rule:last-of-type { border-bottom: 0; }
/* 表格下面那段说明：上面每行左右都缩进了 --s5，这段也得跟着缩进，
   不然字会贴到卡片边上（.card-b 本身左右是不留白的） */
.lv-note { padding: 0 var(--s5); }
.lv-rule-exp { font-family: var(--mono); color: var(--accent); font-weight: 700; }
.lv-rule-cap { color: var(--ink-3); font-size: var(--t-sm); }
.lv-rule-now { font-size: var(--t-sm); }
.lv-count { font-family: var(--mono); color: var(--ink-2); }
.lv-count.full { color: var(--ink-3); }
.lv-ok { color: var(--accent); }

/* 经验记录 */
.lv-log {
    display: flex; align-items: center; gap: var(--s3);
    padding: 10px var(--s5);
    border-bottom: 1px solid var(--hair);
    font-size: var(--t-sm);
}
.lv-log:last-child { border-bottom: 0; }
.lv-log-a { flex: 1; min-width: 0; color: var(--ink-2); }
.lv-log-x { font-family: var(--mono); color: var(--accent); font-weight: 700; }
.lv-log-x.is-neg { color: var(--ink-3); }
.lv-log-t { color: var(--ink-3); font-size: var(--t-xs); }

/* 关注 / 粉丝页的 tab */
.tab em { font-style: normal; font-family: var(--mono); font-size: var(--t-xs); color: var(--ink-3); margin-left: 4px; }
.tab.is-locked { color: var(--ink-3); opacity: .55; cursor: not-allowed; }
.tab.is-locked::after { display: none; }

/* ---- 后台设置里的小控件 ---- */
.admin-sub {
    margin: var(--s6) 0 var(--s3);
    padding-bottom: 7px;
    border-bottom: 1px solid var(--hair);
    font-size: var(--t-sm); font-weight: 600;
    letter-spacing: .06em; color: var(--ink-2);
}
.admin-sub:first-of-type { margin-top: var(--s4); }
.logo-preview { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.logo-preview img {
    width: 44px; height: 44px; object-fit: cover;
    border: 1px solid var(--hair-2);
    border-radius: 50% !important;
}
/* 注册页顶部提示语（后台可写） */
.auth-note {
    margin-bottom: var(--s5);
    padding: 11px 13px;
    background: var(--surface-2);
    border-left: 2px solid var(--accent);
    font-size: var(--t-sm); line-height: 1.8; color: var(--ink-2);
}

/* 后台用户列表里的等级编辑：横向排一行，别把表格撑成一坨 */
.lv-edit { display: flex; align-items: center; gap: 6px; }
.lv-edit-cur { display: inline-flex; flex: none; }
.lv-edit-quick { display: flex; gap: 3px; flex: none; }
.lv-quick {
    width: 20px; height: 20px;
    display: grid; place-items: center;
    border: 1px solid var(--hair-2);
    font-size: 10px; font-family: var(--mono);
    color: var(--ink-3);
    transition: border-color var(--d1) var(--ease), color var(--d1) var(--ease);
}
.lv-quick:hover { border-color: var(--accent); color: var(--accent); }
.lv-quick.on { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }

/* 后台表格：单元格之间留够气口，别贴在一起 */
.admin-table td, .admin-table th { padding: 11px 14px; vertical-align: middle; }
.admin-table .cell-user { min-width: 150px; }
.admin-table .cell-mail { max-width: 190px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 操作列：按钮必须排成一行。
   以前是 flex-wrap: wrap —— 列一窄，四个按钮就一个个掉到下一行，整格竖着长出去、
   把表格撑破（详情/发消息/停用/设为管理 叠成一条）。
   不换行之后，列宽由按钮撑开，表格宽了就靠外面的 .tbl-wrap 横向滚动。 */
.admin-table .actions { display: flex; gap: 6px; flex-wrap: nowrap; justify-content: flex-end; }
.admin-table .cell-lv { min-width: 250px; }
/* 表格的横向滚动容器：表格比容器宽就横向滚，不去挤列 */
.tbl-wrap { overflow-x: auto; }
@media (max-width: 940px) {
    .admin-table .cell-mail { max-width: 150px; }
}

/* ---- 数据看板 ---- */
.dash-grid {
    display: grid; gap: var(--s3);
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}
.dash-tile {
    display: flex; flex-direction: column; gap: 2px;
    padding: 13px 15px;
    border: 1px solid var(--hair);
    background: var(--surface-2);
}
.dash-t { font-size: var(--t-xs); color: var(--ink-3); letter-spacing: .06em; }
.dash-tile b { font-size: 24px; font-family: var(--mono); font-weight: 700; color: var(--ink); line-height: 1.2; }
.dash-tile em { font-style: normal; font-size: var(--t-xs); color: var(--ink-3); }
.dash-sub { margin-top: 4px; font-size: var(--t-xs); color: var(--ink-2); font-family: var(--mono); }

/* 柱状图：不用 canvas，也不引图表库，就是一堆 div */
.dash-chart {
    display: flex; align-items: flex-end; gap: 4px;
    height: 132px; margin-top: var(--s5);
    padding-bottom: 18px;
    border-bottom: 1px solid var(--hair-2);
}
.dash-col {
    position: relative; flex: 1; min-width: 0; height: 100%;
    display: flex; align-items: flex-end; justify-content: center;
}
.dash-bar {
    display: block; width: 100%; max-width: 26px;
    background: var(--accent); opacity: .82;
    border-radius: 2px !important;
    transition: opacity var(--d1) var(--ease), background var(--d1) var(--ease);
}
.dash-col:hover .dash-bar { opacity: 1; background: var(--brand); }
.dash-bar.is-zero { background: var(--hair-2); opacity: 1; }
.dash-n {
    position: absolute; bottom: -17px; left: 50%; transform: translateX(-50%);
    font-family: var(--mono); font-size: 10px; color: var(--ink-3);
}
.dash-axis {
    display: flex; align-items: center; justify-content: space-between; gap: var(--s3);
    margin-top: 8px; font-size: var(--t-xs); color: var(--ink-3); font-family: var(--mono);
}

.dash-two {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: var(--s6); margin-top: var(--s6);
}
.dash-h {
    margin-bottom: var(--s3); padding-bottom: 6px;
    border-bottom: 1px solid var(--hair);
    font-size: var(--t-sm); font-weight: 600; letter-spacing: .06em; color: var(--ink-2);
}
.dash-row {
    display: flex; align-items: center; gap: 9px;
    padding: 6px 0; font-size: var(--t-sm);
}
.dash-row-n {
    flex: none; max-width: 130px;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    color: var(--ink-2);
}
.dash-row-n:hover { color: var(--accent); }
.dash-row-v { flex: none; margin-left: auto; color: var(--ink); font-weight: 600; }
.dash-mini { flex: 1; min-width: 40px; height: 5px; background: var(--surface-2); overflow: hidden; }
.dash-mini i { display: block; height: 100%; background: var(--accent); opacity: .6; }
.dash-rank {
    flex: none; width: 18px; height: 18px;
    display: grid; place-items: center;
    background: var(--surface-2); border: 1px solid var(--hair-2);
    font-family: var(--mono); font-size: 10px; color: var(--ink-3);
}
.dash-rank.top { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }

/* ---- 批量操作工具栏 ---- */
.bulk-form { display: block; }
.bulk-bar {
    display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap;
    padding: 10px var(--s5);
    border-bottom: 1px solid var(--hair);
    background: var(--surface-2);
}
.bulk-all { display: flex; align-items: center; gap: 6px; font-size: var(--t-sm); color: var(--ink-2); cursor: pointer; }
.bulk-bar .btn { margin-left: 0; }
.bulk-bar [data-bulk-count] { margin-right: auto; font-family: var(--mono); }

/* ---- 用户详情页 ---- */
.ud-head { display: flex; align-items: center; gap: var(--s5); flex-wrap: wrap; }
.ud-head-main { flex: 1; min-width: 240px; }
.ud-meta {
    display: flex; gap: var(--s4); flex-wrap: wrap;
    margin-top: 10px; font-size: var(--t-sm); color: var(--ink-3);
}
.ud-stat {
    display: grid; gap: var(--s3); margin-top: var(--s5);
    grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
}
.ud-stat > div { padding: 11px 13px; border: 1px solid var(--hair); background: var(--surface-2); }
.ud-stat b { display: block; font-size: 19px; font-family: var(--mono); color: var(--ink); }
.ud-stat span { font-size: var(--t-xs); color: var(--ink-3); }
.ud-frames { display: flex; flex-wrap: wrap; gap: 6px; margin-top: var(--s4); }
.ud-frame {
    padding: 2px 8px; font-size: var(--t-xs);
    color: var(--ink-2); background: var(--surface-2); border: 1px solid var(--hair-2);
}
.ud-cols {
    display: grid; gap: var(--s5); margin-top: var(--s5);
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
    align-items: start;
}
.ud-cols > .card { margin-top: 0 !important; }
.ud-inline { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.finline { display: inline; }
.danger-box {
    display: flex; align-items: flex-start; gap: var(--s4); flex-wrap: wrap;
    padding: 13px 15px;
    border: 1px solid var(--hair);
    border-left: 3px solid var(--danger);
    background: var(--surface-2);
}
.danger-box + .danger-box { margin-top: var(--s3); }
.danger-box > div { flex: 1; min-width: 220px; }
.danger-box b { font-size: var(--t-md); }
.danger-box p { margin-top: 4px; line-height: 1.8; }

/* 系统消息的发送对象选择 */
.sys-target {
    display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
    font-size: 13.5px;
}
.sys-target label { display: flex; align-items: center; gap: 7px; cursor: pointer; }
.sys-days { display: flex; align-items: center; gap: 7px; color: var(--ink-3); font-size: var(--t-sm); }
.inp-mini {
    height: 32px; padding: 0 9px;
    font-family: var(--mono); font-size: var(--t-sm);
}
.lv-th-row .field { min-width: 96px; }
.lv-preview { display: flex; gap: var(--s5); flex-wrap: wrap; }
.lv-preview-i {
    display: flex; align-items: center; gap: 12px;
    padding: 10px 14px 10px 10px;
    border: 1px solid var(--hair);
}

/* ---- 首页侧栏的签到卡 ---- */
.lv-side-t {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: var(--s2); font-size: var(--t-sm);
}
.lv-side-t a { font-weight: 600; color: var(--ink); }
.lv-side-t a:hover { color: var(--accent); }
.lv-side-t span { font-size: var(--t-xs); color: var(--ink-3); font-family: var(--mono); }
.lv-bar-sm { height: 4px; margin: 9px 0 11px; }

/* ---- 头像框挑选页 ---- */
.fr-group { margin-bottom: var(--s6); }
.fr-group:last-child { margin-bottom: 0; }
.fr-group-h {
    display: flex; align-items: baseline; gap: var(--s3); flex-wrap: wrap;
    margin-bottom: var(--s4); padding-bottom: 7px;
    border-bottom: 1px solid var(--hair);
}
.fr-group-h span { font-weight: 600; font-size: var(--t-md); letter-spacing: .04em; }
.fr-group-h em { font-style: normal; font-size: var(--t-xs); color: var(--ink-3); }

/* 经验钱包 */
.fr-wallet {
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--s4); flex-wrap: wrap;
}
.fr-wallet-l { display: flex; align-items: baseline; gap: 9px; font-size: var(--t-sm); color: var(--ink-3); }
.fr-wallet-l b { font-size: 26px; font-family: var(--mono); font-weight: 700; color: var(--accent); }
.fr-wallet-l em { font-style: normal; font-size: var(--t-sm); color: var(--ink-2); }
.fr-wallet-r { font-size: var(--t-sm); color: var(--ink-3); }
.fr-wallet-r b { color: var(--ink); font-family: var(--mono); }

.fr-grid {
    display: grid; gap: var(--s4);
    grid-template-columns: repeat(auto-fill, minmax(152px, 1fr));
}
.fr-cell {
    position: relative;
    display: flex; flex-direction: column; align-items: center; gap: 6px;
    padding: 16px 10px 12px;
    background: transparent; border: 1px solid var(--hair);
    transition: border-color var(--d2) var(--ease), background var(--d2) var(--ease);
}
.fr-cell.on { border-color: var(--accent); background: var(--surface-2); }
.fr-cell.locked .avf { filter: saturate(.55) opacity(.75); }

.fr-name { font-size: var(--t-sm); color: var(--ink-2); letter-spacing: .02em; }
.fr-cell.on .fr-name { color: var(--accent); font-weight: 600; }

.fr-flag {
    position: absolute; top: 0; right: 0;
    padding: 3px 7px 2px;
    background: var(--accent); color: var(--accent-ink);
    font-size: 10px; line-height: 1; letter-spacing: .04em;
}
.fr-flag.lock  { background: var(--ink-3); }
.fr-flag.own   { background: var(--surface-2); color: var(--ink-2); border-left: 1px solid var(--hair); border-bottom: 1px solid var(--hair); }
.fr-flag.price { background: var(--surface); color: var(--accent); border-left: 1px solid var(--accent); border-bottom: 1px solid var(--accent); font-family: var(--mono); }

.fr-act { margin-top: 4px; }
.fr-act .btn { min-width: 74px; }
.btn.is-dim { opacity: .5; }

/* ---- 维护页 ---- */
.maint { display: flex; justify-content: center; padding: var(--s10) 0; }
.maint-in { max-width: 470px; text-align: center; }
.maint-in h1 { font-size: 24px; font-weight: 700; letter-spacing: .1em; }
.maint-in p { margin-top: var(--s4); font-size: var(--t-base); line-height: 1.9; color: var(--ink-2); }

@media (max-width: 720px) {
    .lv-hero { gap: var(--s4); }
    .lv-hero-name { font-size: 18px; }
    .lv-row { padding: 13px 15px; gap: var(--s3); }
    .lv-row-d { display: none; }
    .lv-rule-head,
    .lv-rule { grid-template-columns: 1.3fr .6fr .7fr .8fr; gap: 8px; padding: 10px 15px; }
    .lv-rule-cap { font-size: var(--t-xs); }
    .lv-log { padding: 10px 15px; }
}

/* ==========================================================================
   26 等级标识的自定义文字 / 界面主题（皮肤）
   ========================================================================== */

/* 标题字跟着主题走：默认就是 --sans，换皮肤时由 skin-*.css 改 --display */
.brand b, .page-h h1, .card-h h2, .lv-hero-name,
.fr-wallet-l b, .stat-grid b, .lvb-t, .sk-prev-btn {
    font-family: var(--display);
}

/* 自己写过的标识：文字后面缀一枚很小的小点，和默认的等级名区分开，
   不抢戏，但一眼能看出「这句是他自己写的」 */
.lvb-own .lvb-t { position: relative; }
.lvb-own .lvb-t::after {
    content: '';
    display: inline-block;
    width: 3px; height: 3px;
    margin-left: 5px;
    vertical-align: 2px;
    background: currentColor;
    opacity: .5;
    border-radius: 50% !important;
}

/* --- 「我的等级标识」卡片 --- */
.bdg-wrap { display: flex; gap: var(--s8); align-items: flex-start; flex-wrap: wrap; }
.bdg-show {
    flex: 1 1 240px; min-width: 200px;
    display: flex; flex-direction: column; gap: 9px; align-items: flex-start;
    padding: var(--s5);
    background: var(--surface-2);
    border: 1px solid var(--hair);
}
.bdg-hint { font-size: var(--t-sm); color: var(--ink-3); }
.bdg-tools { flex: 0 1 340px; min-width: 240px; }
.bdg-btns { display: flex; gap: 9px; flex-wrap: wrap; align-items: center; }

/* --- 主题商城 --- */
.sk-grid {
    display: grid; gap: var(--s6);
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
}
.sk-card {
    display: flex; flex-direction: column;
    background: var(--surface);
    border: 1px solid var(--hair-2);
    overflow: hidden;
    transition: border-color var(--d2) var(--ease), transform var(--d2) var(--ease-out);
}
.sk-card:hover { border-color: var(--accent-line); transform: translateY(-2px); }
.sk-card.on { border-color: var(--accent); }
.sk-info { padding: var(--s5); display: flex; flex-direction: column; gap: var(--s3); flex: 1; }
.sk-name { display: flex; align-items: center; gap: 9px; }
.sk-name b { font-size: var(--t-lg); font-weight: 600; letter-spacing: .05em; }
.sk-flag {
    font-style: normal; font-size: var(--t-xs);
    padding: 2px 7px;
    background: var(--surface-2); color: var(--ink-3);
    border: 1px solid var(--hair);
}
.sk-flag.on    { background: var(--accent); color: var(--accent-ink); border-color: transparent; }
.sk-flag.own   { color: var(--ink-2); }
.sk-flag.price { color: var(--accent); border-color: var(--accent-line); font-family: var(--mono); }
.sk-note { font-size: var(--t-sm); line-height: 1.75; color: var(--ink-3); flex: 1; }
.sk-card form { margin: 0; }
.sk-info .btn-block { width: 100%; }

/* 三个色点：底色 / 面板 / 强调色 */
.sk-dots { display: flex; align-items: center; gap: 5px; }
.sk-dots i { width: 15px; height: 15px; border: 1px solid var(--hair-2); }
.sk-dots span { margin-left: 3px; font-size: var(--t-xs); color: var(--ink-3); }

/* 微缩页面：顶栏 + 一张正文卡 + 侧边一栏。
   这里出现的 var(--*) 全都被 skin-*.css 里 `.sk-prev[data-skin-prev=…]` 覆盖过，
   所以画出来的就是那套皮肤真穿上的样子。 */
.sk-prev {
    display: block;
    height: 178px;
    background: var(--bg);
    border-bottom: 1px solid var(--hair-2);
    overflow: hidden;
}
.sk-prev-top {
    display: flex; align-items: center; gap: 7px;
    height: 30px; padding: 0 12px;
    background: var(--surface);
    border-bottom: 1px solid var(--hair);
}
.sk-pv-logo { width: 13px; height: 13px; background: var(--accent); flex: none; }
.sk-pv-nav { width: 24px; height: 4px; background: var(--ink-3); opacity: .32; }
.sk-pv-nav.sk-pv-n2 { width: 15px; }
.sk-pv-pill { margin-left: auto; width: 34px; height: 14px; background: var(--accent); flex: none; }

.sk-prev-body { display: flex; gap: 10px; padding: 14px 12px; }
.sk-pv-main {
    flex: 1; min-width: 0;
    display: flex; flex-direction: column; gap: 8px;
    padding: 13px;
    background: var(--surface);
    border: 1px solid var(--hair);
}
.sk-pv-h { width: 56%; height: 7px; background: var(--ink-2); opacity: .5; }
.sk-pv-line { display: block; height: 4px; background: var(--ink-3); opacity: .26; }
.sk-pv-main .sk-pv-w2 { width: 78%; }
.sk-pv-btn {
    align-self: flex-start;
    margin-top: 3px;
    padding: 4px 13px;
    font-size: var(--t-xs);
    background: var(--accent);
    color: var(--accent-ink);
}
.sk-pv-side {
    width: 76px; flex: none;
    display: flex; flex-direction: column; gap: 7px;
    padding: 12px 10px;
    background: var(--surface-2);
    border: 1px solid var(--hair);
}
.sk-pv-av { width: 20px; height: 20px; background: var(--brand); border-radius: 50% !important; }
.sk-pv-side .sk-pv-w3 { width: 62%; }
/* 预览里的控件也跟真页面一样，用同一套圆角令牌 */
.sk-pv-logo, .sk-pv-nav, .sk-pv-pill, .sk-pv-h, .sk-pv-line, .sk-pv-btn { border-radius: var(--r) !important; }

/* --- 换主题那一下 ---
   View Transitions 会给整页做交叉淡入，这里把时长调慢一点、缓动柔一点；
   不支持它的浏览器就靠下面 .sk-swapping 里的颜色过渡兜底。 */
::view-transition-old(root),
::view-transition-new(root) {
    animation-duration: .52s;
    animation-timing-function: cubic-bezier(.22, .61, .36, 1);
}
html.sk-swapping,
html.sk-swapping *,
html.sk-swapping *::before,
html.sk-swapping *::after {
    transition: background-color var(--d4) var(--ease-soft),
                border-color var(--d4) var(--ease-soft),
                color var(--d4) var(--ease-soft),
                fill var(--d4) var(--ease-soft),
                stroke var(--d4) var(--ease-soft) !important;
}
/* 换主题时点一下那张卡，给一点按下去的反馈 */
.sk-card.sk-pop { animation: skPop .42s var(--ease-out); }
@keyframes skPop {
    0%   { transform: scale(1); }
    38%  { transform: scale(.985); }
    100% { transform: scale(1); }
}

/* 上面那些位移/缩放，讨厌动效的人一律不要 */
@media (prefers-reduced-motion: reduce) {
    html[data-skin] .btn:hover,
    .sk-card:hover,
    .sk-card.sk-pop { transform: none !important; animation: none !important; }
    ::view-transition-old(root),
    ::view-transition-new(root) { animation-duration: .01s; }
}

@media (max-width: 720px) {
    .bdg-wrap { gap: var(--s5); }
    .bdg-show, .bdg-tools { flex-basis: 100%; }
    .sk-grid { grid-template-columns: 1fr; gap: var(--s4); }
}

/* ==========================================================================
   27 右下角的 Live2D 站娘
   --------------------------------------------------------------------------
   没有开关按钮：开不开、多大，后台「站点信息与外观」里调（--l2d-w 就是那个宽度）。
   它是纯装饰，所以整体 pointer-events: none —— 右下角的内容照常能点，
   这也是把 pixi 的交互关掉、改成「自己换表情」的原因。
   模型加载完（.l2d-ready）才淡入，免得先露一个白框。
   ========================================================================== */
.l2d-wrap {
    position: fixed;
    /* 后台拖圆圈定的两个百分比：x 是左右、y 是上下。
       translate 让它以「脚底中心」对准那个点，所以默认 88/97 就是右下角。 */
    left: var(--l2d-x, 88%);
    top: var(--l2d-y, 97%);
    transform: translate(-50%, -100%);
    z-index: 880;
    pointer-events: none;
    /* 手机上的老毛病：一个 60fps 重绘的 WebGL 画布搁在 fixed 层里，
       滚动时会跟页面抢合成层，表现就是背景一闪一闪。
       单独给它一层，两边互不打扰。 */
    will-change: transform;
    backface-visibility: hidden;
    -webkit-backface-visibility: hidden;
}
.l2d-wrap.l2d-off { display: none; }
/* 加载失败：别默默消失，把原因冒出来给用户看（手机上没控制台可开） */
.l2d-wrap.l2d-err .l2d-stage { opacity: 1; transform: none; }
.l2d-wrap.l2d-err canvas { display: none; }
.l2d-wrap.l2d-err .l2d-tip {
    position: static; transform: none;
    display: block; max-width: 230px; margin: 0 auto;
    padding: 6px 10px; line-height: 1.5; text-align: center;
    white-space: normal;
    border-color: var(--danger); color: var(--danger);
}

.l2d-stage {
    position: relative;
    width: var(--l2d-w, 310px);
    height: calc(var(--l2d-w, 310px) * 1.28);
    opacity: 0; transform: translateY(12px);
    transition: opacity var(--d4) var(--ease-soft), transform var(--d4) var(--ease-soft);
}
.l2d-wrap.l2d-ready .l2d-stage { opacity: 1; transform: none; }
.l2d-stage canvas { display: block; width: 100%; height: 100%; }

/* 换表情时冒一下表情名 */
.l2d-tip {
    position: absolute; left: 50%; top: 10px; transform: translateX(-50%);
    padding: 2px 10px; font-size: var(--t-xs); letter-spacing: .06em;
    background: var(--surface); color: var(--ink-2);
    border: 1px solid var(--hair-2);
    opacity: 0; transition: opacity var(--d2) var(--ease);
}
.l2d-tip.show { opacity: 1; }

/* 手机上不能照搬桌面定的那两个百分比：
   她的「脚底中心」按 88% 摆，右边会有一截直接甩出屏幕；
   97% 那条又正好压在 iPhone 底下那道 Home 横条上（页面开了 viewport-fit=cover）
   —— 看着都像没显示。窄屏上缩小一点，把中心点夹在屏幕里头、再往上提一点。 */
@media (max-width: 760px) {
    .l2d-wrap {
        --l2d-ww: min(var(--l2d-w, 310px), 42vw);
        left: clamp(calc(var(--l2d-ww) / 2 + 6px), var(--l2d-x, 88%), calc(100% - var(--l2d-ww) / 2 - 6px));
        /* 不认 env() 的老机器这条会整条作废，退回上面那条 top: var(--l2d-y) —— 也行 */
        top: min(var(--l2d-y, 97%), calc(100% - env(safe-area-inset-bottom, 0px) - 10px));
    }
    .l2d-stage {
        width: var(--l2d-ww);
        height: calc(var(--l2d-ww) * 1.28);
    }
}

/* 手机上地址栏一收一放，窗口高度就变一档 —— 用百分比定位的她跟着上下来回跑，
   看着就是「一闪一闪」。svh 是「地址栏还在时」那档高度，滚动全程它是定住的。
   老浏览器不认 svh，这条整段作废，退回上面那条百分比 —— 也能用。 */
@supports (height: 100svh) {
    @media (max-width: 760px) {
        .l2d-wrap {
            top: min(calc(var(--l2d-yn, 97) * 1svh), calc(100svh - env(safe-area-inset-bottom, 0px) - 10px));
        }
    }
}
@media (prefers-reduced-motion: reduce) {
    .l2d-stage { transition: none; }
}

/* --- 后台那个「拖圆圈定位置」的小工具 --- */
.l2d-pick-stage {
    position: relative;
    height: 168px;
    margin-top: 8px;
    background:
        linear-gradient(var(--hair) 1px, transparent 1px) 0 0 / 100% 28px,
        linear-gradient(90deg, var(--hair) 1px, transparent 1px) 0 0 / 28px 100%,
        var(--surface-2);
    border: 1px solid var(--hair-2);
    cursor: crosshair;
    touch-action: none;          /* 手机上拖圆圈别把页面一起滚了 */
    overflow: hidden;
}
.l2d-pick-dot {
    position: absolute;
    width: 22px; height: 22px;
    margin: -11px 0 0 -11px;      /* 让圆心对准那个点 */
    background: var(--accent);
    box-shadow: 0 0 0 6px var(--accent-soft);
    border-radius: 50% !important;
    pointer-events: none;
}
.l2d-pick-row {
    display: flex; align-items: center; gap: var(--s5);
    flex-wrap: wrap; margin-top: 10px;
}
.l2d-pick-row .tip { flex: 1 1 260px; }
.l2d-pick-num { display: flex; align-items: center; gap: 6px; font-size: var(--t-sm); color: var(--ink-3); }
.l2d-pick-num .inp-mini { width: 68px; }
