/* ==================================================
   免费鸡蛋页（eggs.html / egg.freegg.top）专用样式层

   约定：
   - 本页专用，先例是首页的 pixel-hero.css、关于页的 ak-about.css：一页一个样式文件，
     不再往全站 style.css（5279 行，且被 user.html / help.html / admin.html 共用）里堆。
   - 只新增选择器、不覆盖 style.css 的公共类（.button / .form-group / .form-result /
     .submit-button / .feature-head 跨页共用，改它们会波及其它页面）。
   - 颜色一律由 style.css 的 :root / html[data-theme="dark"] token 推导，
     不写新的硬编码色值；亮暗两套都要自检。
   - 上线注意：本文件路径必须加进 server.js 的 EGG_ALLOWED_EXACT 子域白名单，
     否则 egg.freegg.top 会把它 301 回主域，表现为「本地好看、线上没样式」。

   P0 状态：只建文件与挂引用，暂无任何规则 —— 保证页面与改动前逐像素一致。
   规则从 P1（切换过渡与侧栏指示条）起逐阶段加入。
   ================================================== */


/* ==================== C1：侧栏鸡蛋角色 ====================
 * 容器高度先占住：引擎 8 个文件是异步注入的，若等角色出现再撑开侧栏，
 * 导航整体下移而指示条胶囊还停在旧位置。
 * 不创建角色时由 JS 直接 hidden（见 eggs-companion.js 的 skip()）。
 * ==================== */

.eggs-mascot {
    display: flex;
    align-items: center;
    height: 84px;
    margin: 0 0 12px;
}

/* 引擎把 svg 放大约 1.131 倍（VIEW_SCALE = 259/229），需要允许溢出 */
.eggs-mascot svg {
    overflow: visible;
}

/* .eggs-mascot--sm（用户主页蛋壳卡里的小号档）已随角色移进右下角 dock 一起删除 */


/* 仅本地注入的角色状态演练面板（线上页面不会有这个节点） */

.eggs-egg-debug {
    position: fixed;
    left: 14px;
    bottom: 14px;
    z-index: 60;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    align-items: center;
    max-width: 360px;
    padding: 10px 12px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--surface);
    box-shadow: var(--shadow);
    font-size: 12px;
}

.eggs-egg-debug-head {
    width: 100%;
    color: var(--muted);
    font-weight: 600;
}

.eggs-egg-debug-read {
    width: 100%;
    color: var(--muted-2);
    font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
}

.eggs-egg-debug select,
.eggs-egg-debug button {
    padding: 4px 10px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--bg-2);
    color: var(--fg);
    font-size: 12px;
    cursor: pointer;
}


/* ==================== M3：解析页层级 ====================
 * 修的是可用性缺陷：平台条（B站/抖音/本地）与子模式条（点播/直播）
 * 原本用同一个 .bili-modes 样式 —— 同高 42px、active 都是 --fg 实心，
 * 两组控件看起来是并列关系，但实际是"先选平台、再选模式"的上下级。
 * 现在：平台条做主控件（更高、带图标、胶囊指示），子模式做次级（更小、文字型、下划线指示）。
 * ==================== */

.feature-bili .bili-seg {
    position: relative;

    height: 52px;

    padding: 4px;

    border: 1px solid var(--up-glass-border);
    border-radius: 14px;

    background: var(--up-glass-bg);

    box-shadow: var(--edge-glow);

    -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
    backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));

    margin-bottom: 14px;
}

.feature-bili .bili-seg .bili-mode-btn {
    position: relative;

    z-index: 1;

    display: inline-flex;

    align-items: center;

    gap: 7px;

    height: 44px;

    padding: 0 22px;

    border-radius: 10px;

    font-size: 14px;

    background: transparent;

    color: var(--muted);
}

/* 去掉 style.css 给相邻按钮加的中缝竖线：有胶囊后它和指示条打架 */
.feature-bili .bili-seg .bili-mode-btn + .bili-mode-btn {
    border-left: none;
}

/* active 不再是实心反色，交给指示条表达，文字只提亮度 */
.feature-bili .bili-seg .bili-mode-btn.active {
    background: transparent;

    color: var(--fg);
}

.feature-bili .bili-mode-icon {
    font-size: 17px;
    line-height: 1;
}

/* 次级：点播 / 直播 —— 明显比平台条小一档、无容器边框 */
.feature-bili .bili-modes--sub {
    position: relative;

    height: auto;

    padding: 0;

    border: none;
    border-radius: 0;

    background: transparent;

    margin: 0 0 22px;

    gap: 4px;
}

.feature-bili .bili-modes--sub .bili-mode-btn {
    height: 32px;

    padding: 0 14px;

    border-radius: 8px;

    font-size: 13px;
}


/* 两条共用的滑动指示条（位置由 eggs-motion.segIndicator 写进 CSS 变量） */
.feature-bili .seg-indicator {
    position: absolute;
    left: 0;
    top: 0;
    z-index: 0;

    width: 0;
    height: 0;

    pointer-events: none;

    background: var(--bg-2);

    box-shadow: inset 0 0 0 1px var(--border);

    transition: none;
}

.feature-bili .bili-seg .seg-indicator {
    border-radius: 10px;
}

.feature-bili .bili-modes--sub .seg-indicator {
    border-radius: 8px;

    background: transparent;

    box-shadow: inset 0 -2px 0 0 var(--egg-gold);
}

.feature-bili .seg-indicator.is-live {
    transition:
        transform .34s cubic-bezier(.22, .61, .36, 1),
        width .34s cubic-bezier(.22, .61, .36, 1),
        height .34s cubic-bezier(.22, .61, .36, 1);
}

.feature-bili .bili-mode-btn:focus-visible {
    outline: 2px solid var(--egg-gold);
    outline-offset: 2px;
}


/* ==================== M4：音乐解析页的来源条 / 类型条 ====================
 * 直接复用 .bili-modes / .bili-mode-btn / .seg-indicator 那一整套（同一份
 * 视觉语言：平台条 52px 带图标胶囊、类型条 32px 纯文字下划线），
 * 只在 .feature-music 下补选择器 —— 不另起一套同形不同名的样式。
 * 与视频/直播解析保持一致的好处：两个板块的操作方式可以互相迁移，
 * 用户不需要为"音乐这里是不是另一个世界"重新学一遍。
 * ==================== */

.feature-music .music-src-bar.bili-seg {
    position: relative;

    height: 52px;

    padding: 4px;

    border: 1px solid var(--up-glass-border);
    border-radius: 14px;

    background: var(--up-glass-bg);

    box-shadow: var(--edge-glow);

    -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
    backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));

    margin-bottom: 14px;
}

.feature-music .music-src-bar .bili-mode-btn {
    position: relative;

    z-index: 1;

    display: inline-flex;

    align-items: center;

    gap: 7px;

    height: 44px;

    padding: 0 20px;

    border-radius: 10px;

    font-size: 14px;

    background: transparent;

    color: var(--muted);
}

/* 相邻按钮的中缝竖线由 style.css 给出；有胶囊指示条后它跟指示打架 */
.feature-music .music-src-bar .bili-mode-btn + .bili-mode-btn {
    border-left: none;
}

.feature-music .music-src-bar .bili-mode-btn.active {
    background: transparent;

    color: var(--fg);
}

.feature-music .music-src-icon {
    font-size: 17px;
    line-height: 1;
}

/* 类型条：歌单 / 单曲 —— 次级，比来源条小一档、无容器边框 */
.feature-music .music-kind-bar {
    position: relative;

    height: auto;

    padding: 0;

    border: none;
    border-radius: 0;

    background: transparent;

    margin: 0 0 20px;

    gap: 4px;
}

.feature-music .music-kind-bar .bili-mode-btn {
    height: 32px;

    padding: 0 14px;

    border-radius: 8px;

    font-size: 13px;
}

.feature-music .seg-indicator {
    position: absolute;
    left: 0;
    top: 0;
    z-index: 0;

    width: 0;
    height: 0;

    pointer-events: none;

    background: var(--bg-2);

    box-shadow: inset 0 0 0 1px var(--border);
}

.feature-music .music-src-bar .seg-indicator {
    border-radius: 10px;
}

.feature-music .music-kind-bar .seg-indicator {
    border-radius: 8px;

    background: transparent;

    box-shadow: inset 0 -2px 0 0 var(--egg-gold);
}

.feature-music .bili-mode-btn:focus-visible {
    outline: 2px solid var(--egg-gold);
    outline-offset: 2px;
}

/* 窄屏：来源条五个按钮换行，别横向溢出 */
@media (max-width: 560px) {
    .feature-music .music-src-bar.bili-seg {
        height: auto;
    }

    .feature-music .music-src-bar .bili-mode-btn {
        flex: 1 1 auto;

        justify-content: center;

        padding: 0 12px;
    }
}


/* ---------- 稳定链接：这是这页最有价值的产出，得像个成果 ----------
 * B站直播的永久链接（README：粘一次永久有效，世界端填一次即可），
 * 原来只是一个普通 div + 一个 secondary 按钮，和说明文字同权重。
 * ---------- */

.feature-bili .bili-stable-link {
    display: flex;

    flex-wrap: wrap;

    align-items: center;

    gap: 12px;

    padding: 16px 18px;

    border: 1px solid var(--border);
    border-left: 3px solid var(--egg-gold);
    border-radius: 12px;

    background: var(--bg-2);
}

.feature-bili .bili-stable-url {
    flex: 1 1 260px;

    font-family: ui-monospace, SFMono-Regular, Consolas, monospace;

    font-size: 13px;

    word-break: break-all;

    color: var(--fg);
}

.feature-bili .bili-stable-link .button {
    flex: 0 0 auto;
}

/* 复制成功回弹（eggs-motion.pop 加类，动画结束自动摘掉） */
.is-pop {
    animation: eggs-pop .34s cubic-bezier(.22, .61, .36, 1);
}

@keyframes eggs-pop {

    0%   { transform: scale(1); }
    40%  { transform: scale(1.06); }
    100% { transform: scale(1); }
}


/* ---------- 本地上传三步 ---------- */

.bili-stepper {
    display: flex;

    align-items: center;

    gap: 10px;

    margin-bottom: 14px;

    color: var(--muted-2);

    font-size: 13px;
}

.bili-step {
    display: inline-flex;

    align-items: center;

    gap: 7px;
}

.bili-step i {
    display: inline-flex;

    align-items: center;
    justify-content: center;

    width: 20px;
    height: 20px;

    border: 1px solid var(--border);
    border-radius: 50%;

    font-style: normal;

    font-size: 11px;

    color: var(--muted-2);
}

.bili-step.is-now {
    color: var(--fg);
}

.bili-step.is-now i {
    border-color: var(--egg-gold);

    background: var(--egg-gold);

    color: var(--on-accent);
}

.bili-step.is-done {
    color: var(--muted);
}

.bili-step.is-done i {
    border-color: var(--egg-gold);

    color: var(--egg-gold);
}

/* 步骤之间的连接线 */
.bili-step + .bili-step::before {
    content: '';

    width: 18px;
    height: 1px;

    margin-right: 3px;

    background: var(--border);
}


@media (prefers-reduced-motion: reduce) {

    .feature-bili .seg-indicator,
    .feature-bili .seg-indicator.is-live {
        transition: none;
    }

    .is-pop {
        animation: none;
    }
}


/* ==================== M2：下载中心 ====================
 * 原来搜索框、结果计数、列表、"加载更多"全是同一层灰度，
 * 看不出"先做什么"。这里只调层级，不改任何接口逻辑。
 * 颜色一律从 style.css 的 token 派生，不引入新硬编码色值。
 * ==================== */

.feature-download {
    --eggs-ring: color-mix(in srgb, var(--egg-gold) 55%, transparent);
    --eggs-ring-soft: color-mix(in srgb, var(--egg-gold) 18%, transparent);
}


/* 搜索框：页面主操作，焦点态要明显 */

.feature-download .dl-search-input {
    border-radius: 12px;
}

.feature-download .dl-search-input:focus {
    border-color: var(--egg-gold);

    box-shadow: 0 0 0 3px var(--eggs-ring-soft);
}

.feature-download .dl-search .dl-search-btn {
    border-radius: 12px;
}

.feature-download .dl-search .dl-search-btn:focus-visible {
    outline: 2px solid var(--egg-gold);
    outline-offset: 2px;
}


/* 结果计数：数字比句子重一档，滚动时有落点 */

.feature-download .dl-count {
    color: var(--fg);

    font-weight: 700;

    font-variant-numeric: tabular-nums;
}


/* 结果列表：与 VRChat 资源同一套卡片语言（download-card 同时带 vrc-res-card 类，
   但这里限定在 .feature-download 下，两边互不影响） */

.feature-download .download-list {
    display: grid;

    gap: 14px;

    margin-top: 14px;
}

.feature-download .download-card {
    padding: 20px 22px;

    border: 1px solid var(--up-glass-border);
    border-radius: 14px;

    background: var(--up-glass-bg);

    box-shadow: var(--edge-glow), var(--shadow-2);

    -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
    backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
}

.feature-download .download-card:hover {
    border-color: var(--muted-3);
}

.feature-download .dl-empty {
    padding: 26px 22px;

    border: 1px dashed var(--border);
    border-radius: 14px;

    color: var(--muted-2);
}


/* 「加载更多」加载态：文案不动，右侧转个小圈，避免撑宽按钮 */

.feature-download .dl-more {
    display: inline-flex;

    align-items: center;

    gap: 8px;
}

.feature-download .dl-more.is-loading::after {
    content: '';

    width: 12px;
    height: 12px;

    border: 2px solid var(--border);
    border-top-color: var(--egg-gold);
    border-radius: 50%;

    animation: dl-spin .7s linear infinite;
}

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


/* 人机验证小窗：淡入 + 轻微上浮，关闭时反向 */

.dl-modal-overlay {
    animation: dl-overlay-in .18s ease-out;
}

.dl-modal-overlay .dl-modal {
    animation: dl-modal-in .22s cubic-bezier(.22, .61, .36, 1);
}

.dl-modal-overlay.is-closing {
    animation: dl-overlay-out .18s ease-in forwards;
}

.dl-modal-overlay.is-closing .dl-modal {
    animation: dl-modal-out .18s ease-in forwards;
}

@keyframes dl-overlay-in {
    from { opacity: 0; }
    to   { opacity: 1; }
}

@keyframes dl-overlay-out {
    from { opacity: 1; }
    to   { opacity: 0; }
}

@keyframes dl-modal-in {
    from { opacity: 0; transform: translateY(10px) scale(.97); }
    to   { opacity: 1; transform: none; }
}

@keyframes dl-modal-out {
    from { opacity: 1; transform: none; }
    to   { opacity: 0; transform: translateY(6px) scale(.98); }
}


@media (prefers-reduced-motion: reduce) {

    .dl-modal-overlay,
    .dl-modal-overlay .dl-modal,
    .dl-modal-overlay.is-closing,
    .dl-modal-overlay.is-closing .dl-modal,
    .feature-download .dl-more.is-loading::after {
        animation: none;
    }

    /* 加载态没有转圈时，至少留个可见的静态标记 */
    .feature-download .dl-more.is-loading::after {
        border-top-color: transparent;
    }
}


/* ==================== M1：VRChat 资源卡 ====================
 * 原来是「发丝线分隔的长条列表」：一屏扫过去没有分组感，
 * 右侧统计和标题挤在同一水平线上，看不出主次。
 * 改成卡片网格后，同一行的卡片等高，底部统计行贴卡片底边对齐。
 *
 * 全部限定在 .feature-vrchat 下：这些类只在聚合页出现，
 * 用户主页与管理后台共用 style.css，不能顺手被改到。
 * ==================== */

.feature-vrchat .vrc-res-list {
    display: grid;

    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));

    gap: 16px;

    border-top: none;
}

.feature-vrchat .vrc-res-card {
    position: relative;

    display: flex;

    flex-direction: column;

    overflow: hidden;

    padding: 20px 22px;

    border: 1px solid var(--up-glass-border);
    border-radius: 14px;
    background: var(--up-glass-bg);

    box-shadow: var(--edge-glow), var(--shadow-2);

    -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
    backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));

    transition:
        border-color .2s ease,
        transform .2s ease;
}

.feature-vrchat .vrc-res-card:hover {
    border-color: var(--muted-3);

    transform: translateY(-1px);
}

/* 鼠标聚光：坐标由 eggs-motion.js 写成 --mx/--my，颜色从 --egg-gold 派生。
   不支持 color-mix 的浏览器会整条声明失效，结果只是没有光斑，不影响可读性 */
.feature-vrchat .vrc-res-card::after {
    content: '';

    position: absolute;
    inset: 0;

    pointer-events: none;

    background: radial-gradient(
        220px circle at var(--mx, 50%) var(--my, 50%),
        color-mix(in srgb, var(--egg-gold) 16%, transparent),
        transparent 62%
    );

    opacity: 0;

    transition: opacity .25s ease;
}

.feature-vrchat .vrc-res-card.is-spot::after {
    opacity: 1;
}

/* 标签升成胶囊：原来是 1px 方框小块，和边框、卡片边界混在一起 */
.feature-vrchat .vrc-res-tag {
    padding: 3px 10px;

    border: none;
    border-radius: 999px;

    background: var(--bg-2);

    color: var(--muted-2);

    font-size: 11px;
}

.feature-vrchat .vrc-res-desc {
    flex: 1 1 auto;

    margin: 10px 0 0;

    font-size: 14px;

    line-height: 1.75;
}

/* 统计行贴底，保证同一行卡片的「作者 / 浏览 / 点赞」在同一水平线上 */
.feature-vrchat .vrc-res-bottom {
    margin-top: auto;

    padding-top: 16px;

    border-top: 1px solid var(--border-soft);
}

.feature-vrchat .vrc-res-register {
    margin-top: 12px;
}


/* ==================== P1：侧栏滑动指示条 ====================
 * 指示条是 .eggs-nav 的子元素（JS 在 buildNav 里建），这样移动端横向滚动时它会跟着滚。
 * 位置由 eggs-motion.js 用 offsetLeft/offsetTop 写成 transform + width/height，
 * 这里只负责外观与过渡；第一次定位不带过渡（.is-live 才开过渡），避免进场「从左上角飞来」。
 * ==================== */

.eggs-nav {
    position: relative;

    /* BewlyCat 统一：玻璃容器（与账号中心胶囊导航同一配方） */
    padding: 8px;

    border: 1px solid var(--up-glass-border);

    border-radius: 16px;

    background: var(--up-glass-bg);

    box-shadow: var(--edge-glow), var(--shadow-2);

    -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));

    backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
}

html.glass-off .eggs-nav {
    -webkit-backdrop-filter: none;

    backdrop-filter: none;
}

.eggs-nav-indicator {
    position: absolute;
    left: 0;
    top: 0;
    z-index: 0;
    width: 0;
    height: 0;
    border-radius: 12px;
    background: var(--bg-2);
    box-shadow: inset 0 0 0 1px var(--border);
    pointer-events: none;
    transition: none;
}

.eggs-nav-indicator.is-live {
    transition:
        transform .42s cubic-bezier(.22, .61, .36, 1),
        width .42s cubic-bezier(.22, .61, .36, 1),
        height .42s cubic-bezier(.22, .61, .36, 1);
}


/* 导航项：有胶囊高亮后，原来的整行下边线显乱，改成项内留白 + 图标着色 */

.eggs-page .eggs-nav-item {
    position: relative;
    z-index: 1;
    padding: 14px;
    border-bottom: none;
    border-radius: 12px;
    transition:
        color .18s ease,
        transform .18s ease;
}

.eggs-page .eggs-nav-item + .eggs-nav-item {
    margin-top: 2px;
}

.eggs-page .eggs-nav-item:hover {
    color: var(--fg);
}

.eggs-page .eggs-nav-item .eggs-nav-icon {
    transition:
        color .18s ease,
        transform .18s ease;
}

.eggs-page .eggs-nav-item:hover .eggs-nav-icon,
.eggs-page .eggs-nav-item.active .eggs-nav-icon {
    color: var(--egg-gold);
}

.eggs-page .eggs-nav-item:hover .eggs-nav-icon {
    transform: translateY(-1px);
}

/* 键盘可见性：方向键换功能时必须有清晰焦点环 */

.eggs-page .eggs-nav-item:focus-visible {
    outline: 2px solid var(--egg-gold);
    outline-offset: 2px;
}

/* 切换功能时新内容的入场由 JS 驱动，这里给一个不会被动画「撑开」的基线 */

.eggs-content > * {
    will-change: opacity, transform;
}


@media (max-width: 700px) {

    /* 横滑标签形态下，胶囊内边距收紧，避免一项就吃掉半个屏宽 */
    .eggs-page .eggs-nav-item {
        padding: 10px 14px;
    }

    .eggs-page .eggs-nav-item + .eggs-nav-item {
        margin-top: 0;
        margin-left: 2px;
    }
}


@media (prefers-reduced-motion: reduce) {

    .eggs-nav-indicator,
    .eggs-nav-indicator.is-live,
    .eggs-page .eggs-nav-item,
    .eggs-page .eggs-nav-item .eggs-nav-icon {
        transition: none;
    }

    .eggs-content > * {
        will-change: auto;
    }
}


/* ==================================================
   S3 · 首屏氛围背景（freegg-points 低密度档）

   为什么是 absolute + 100vh 而不是 fixed：滚出首屏后容器真的离开视口，
   freegg-points.js 自带的 IntersectionObserver 会把 rAF 停掉，
   不必再挂一个滚动监听去手动暂停。
   为什么是 opacity 而不是叠一层 --bg 半透明遮罩：效果等价（都是往页底色压），
   但省掉一次颜色混合，也不用假设页底色能拆成 rgb 分量。
   强度与竖向淡出都收在这一个容器上，页面上任何一处文字都不直接压在画布上。
   ================================================== */

.eggs-backdrop {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 100vh;
    min-height: 520px;
    z-index: 0;
    overflow: hidden;
    pointer-events: none;

    /* 整体强度：把场景里最亮的点位压进正文的对比度预算内（实测见验收记录） */
    opacity: .55;

    /* 遮罩是这一层的关键，不是装饰：正文（尤其是 13px 的次级灰字）压在点阵上，
       最亮的一格就能把对比度从 7:1 拉到 1.6:1。所以把可见区收成右下椭圆 ——
       左上那块（标题、说明、整条侧栏、页脚）按椭圆几何算下来透明度为 0，
       实测过 4.5:1 的判据见 s3-check.mjs。 */
    -webkit-mask-image: radial-gradient(72% 80% at 97% 97%, #000 0, #000 38%, rgba(0, 0, 0, .45) 66%, transparent 90%);
            mask-image: radial-gradient(72% 80% at 97% 97%, #000 0, #000 38%, rgba(0, 0, 0, .45) 66%, transparent 90%);
}

.eggs-backdrop .fp-canvas {
    position: absolute;
    inset: 0;
    display: block;
    width: 100%;
    height: 100%;
}

/* 画布是定位元素，会盖在普通流之上；正文与页脚抬到它上面。
   用兄弟选择器而不是给 main 加类：eggs.css 同时被 user.html 引入，那边没有这个容器，
   写成裸 main{} 会平白改到用户主页的层叠。 */
.eggs-backdrop ~ main,
.eggs-backdrop ~ .site-foot {
    position: relative;
    z-index: 1;
}

@media (max-width: 700px) {

    /* 小屏上点阵密度已经按配置比例降过一档，这里再把整体强度收一半 */
    .eggs-backdrop {
        opacity: .32;
    }
}

/* 侧栏底部那句提示原本用 --muted-3：实测 12px 小字在暗色下 3.98:1、亮色下 3.22:1，
   两档都不到 AA 的 4.5:1（这是既有问题，与这层氛围无关，只是量对比度时一并被抓出来）。
   换成本页正文同级的 --muted：暗 7.11:1 / 亮 5.95:1。
   没有直接改 --muted-3 本身：它全站都在用，改一处要重审所有页面。 */
.eggs-page .eggs-note {
    color: var(--muted);
}


/* ==================================================
   S5 · 右下角助手 dock

   角色从侧栏的装饰变成这一页的入口：点蛋向上展开竖排菜单。
   层级 90/95 是刻意的 —— 必须低于 .dl-modal-overlay(999) 与 freegg-loader(9999)，
   否则人机验证窗会被菜单盖住。

   降级不靠 JS 通知：角色没创建时宿主 .eggs-mascot 是空的，
   :empty 兄弟选择器就让普通蛋形按钮显示出来。
   减弱动效、移动端、引擎缺失、脚本没跑 —— 四种情况自动都落到这枚普通按钮上，
   菜单功能一个不少。
   ================================================== */

/* 一份组件两种挂载：data-mount="corner" 是视口右下角（user / help），
   "sidebar" 是嵌进左侧栏内容流（eggs）。定位只写在 corner 那一档，
   侧栏模式跟着侧栏走、不占额外高度。 */
.eggs-dock {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 12px;
}

.eggs-dock[data-mount="corner"] {
    position: fixed;

    /* 贴的是「中间内容区的右下角」，不是视口右下角。
       默认 22px 是没量到内容列时的兜底；宽屏下由 eggs-dock.js 按真实布局写成 --dock-right。
       bottom 抬到固定底栏上方，不再压在底栏上（用户红框位置） */
    right: var(--dock-right, 22px);
    bottom: calc(var(--edge-foot-h, 50px) + 16px);
    z-index: 90;
}

.eggs-dock[data-mount="sidebar"] {
    position: relative;      /* 给面板当定位参照 */

    align-items: flex-start;
    margin-top: 26px;
    z-index: 2;
}

/* 侧栏是 sticky，自带一层层叠上下文；不写 z-index 时它按 auto 参与排序，
   而正文里的卡片是 relative + transform（也是层叠上下文、也是 auto），
   同层按 DOM 顺序画 —— 侧栏在前、卡片在后，浮出面板就被 VRChat 卡片盖住（实测命中测试返回卡片）。
   给侧栏一个明确的层，面板才真的浮在正文上面。 */
.eggs-sidebar {
    z-index: 3;
}

/* flyout 才是被开关的那个容器（菜单与对话框是它的两个子块），
   所以浮出位置挂在 flyout 上，不挂在 menu 上。

   面板默认在蛋的正下方展开、左右锁在侧栏这一列（既不越到正文上，也不被正文盖）；
   下方放不下就整块翻到蛋上方，绝不压过蛋本身。
   三个值都由 eggs-dock.js 现量写成 --flyout-*。
   祖先链上没有 transform/filter，fixed 参照的是视口。 */
.eggs-dock[data-mount="sidebar"] .eggs-dock-flyout {
    position: fixed;
    top: var(--flyout-top, 154px);
    left: var(--flyout-left, 193px);
    width: var(--flyout-w, 250px);

    /* 不占侧栏高度 → 不动 sticky、不撑滚动区。
       --flyout-max 由 JS 按"这一侧还剩多少"给：下方展开时是底栏上沿，
       翻到蛋上方时是蛋的上沿 —— 不写死成底栏，否则长对话会压过蛋 */
    max-height: var(--flyout-max, calc(100vh - var(--flyout-top, 154px) - var(--edge-foot-h, 50px) - 24px));
}

/* display 必须挂在 :not([hidden]) 上。写成 .eggs-dock[data-mount=...] .eggs-dock-flyout
   的特异度是 (0,4,0)，会压过 .eggs-dock-flyout[hidden] 的 (0,2,0)，
   结果 hidden 属性失效：一加载面板就按 CSS 默认值杵在左上角，而 JS 以为它关着，
   于是 Esc / 点蛋 / 点外面全都"没反应"（实测踩过） */
.eggs-dock[data-mount="sidebar"] .eggs-dock-flyout:not([hidden]) {
    /* 高度被夹住时不整块滚：整块滚会把输入行滚出视野，压缩交给问答记录 */
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

/* corner 挂载（user / help）：展开框弹到蛋的右侧，不再向上堆叠——
   蛋的上方现在是独立「回到顶部」按钮，向上开会与它重叠（用户实测）。
   位置值由 eggs-dock.js 现量写成 --flyout-left / --flyout-bottom；
   ≤700px dock 回落到视口角落，展开框交回向上堆叠的老布局。 */
.eggs-dock[data-mount="corner"] .eggs-dock-flyout:not([hidden]) {
    position: fixed;
    left: var(--flyout-left, auto);
    bottom: var(--flyout-bottom, calc(var(--edge-foot-h, 50px) + 16px));
    max-width: min(320px, calc(100vw - 24px));
}

@media (max-width: 700px) {
    .eggs-dock[data-mount="corner"] .eggs-dock-flyout:not([hidden]) {
        position: static;
    }
}

.eggs-dock[data-mount="sidebar"] .eggs-dock-menu {
    flex: 0 0 auto;
}

.eggs-dock-menu {
    z-index: 95;

    display: flex;
    flex-direction: column;
    align-items: stretch;

    min-width: 178px;
    padding: 6px;

    background: var(--up-glass-bg);
    border: 1px solid var(--up-glass-border);
    border-radius: 16px;
    box-shadow: var(--edge-glow), var(--shadow-3);

    -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
    backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
}

.eggs-dock-menu[hidden],
.eggs-dock-flyout[hidden] {
    display: none;
}

.eggs-dock-item {
    display: flex;
    align-items: center;
    gap: 10px;

    padding: 9px 12px;

    background: transparent;
    border: none;
    border-radius: 10px;

    color: var(--fg-soft);
    font-family: inherit;
    font-size: 13px;
    line-height: 1.4;
    text-align: left;
    text-decoration: none;

    cursor: pointer;

    transition: background-color 0.15s ease, color 0.15s ease;
}

.eggs-dock-item:hover,
.eggs-dock-item:focus-visible {
    background: color-mix(in srgb, var(--fg) 8%, transparent);
    color: var(--fg);
}

.eggs-dock-item svg {
    flex: 0 0 auto;
    width: 16px;
    height: 16px;
    color: var(--muted-2);
}

.eggs-dock-item:hover svg,
.eggs-dock-item:focus-visible svg {
    color: var(--egg-gold);
}

/* 语言条目：字号/字重/图标间距一律跟着 .eggs-dock-item，不再自己写一套。
   原来这里写死 font-weight:600，::before 又叠了 margin-right:10px（.eggs-dock-item
   本身已有 gap:10px），结果比下面两项粗一档、文字还多缩进 10px。
   只覆盖顶栏胶囊的尺寸和边框，那两样在菜单里是错的 */
.eggs-dock .lang-toggle {
    width: 100%;
    min-width: 0;
    height: auto;
    padding: 9px 12px;

    justify-content: space-between;

    background: transparent;
    border: none;
    border-radius: 10px;

    /* style.css 的 .lang-toggle 胶囊自带 font-weight:600 + letter-spacing:.02em，
       .eggs-dock-item 没声明这两样，压不住 —— 不显式写回来就会比下面两项粗一档 */
    font-weight: 400;
    letter-spacing: normal;
}

/* i18n.js 会重写这颗按钮的 innerHTML，图标放进标签里会被抹掉，所以用 ::before；
   间距交给 .eggs-dock-item 的 gap，不要再叠 margin-right */
.eggs-dock .lang-toggle::before {
    content: '';

    flex: 0 0 auto;
    width: 16px;
    height: 16px;

    background: currentColor;
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7'%3E%3Ccircle cx='12' cy='12' r='9.2'/%3E%3Cpath d='M3 12h18M12 2.9c2.6 2.5 4 5.6 4 9.1s-1.4 6.6-4 9.1c-2.6-2.5-4-5.6-4-9.1s1.4-6.6 4-9.1z'/%3E%3C/svg%3E") center / contain no-repeat;
            mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7'%3E%3Ccircle cx='12' cy='12' r='9.2'/%3E%3Cpath d='M3 12h18M12 2.9c2.6 2.5 4 5.6 4 9.1s-1.4 6.6-4 9.1c-2.6-2.5-4-5.6-4-9.1s1.4-6.6 4-9.1z'/%3E%3C/svg%3E") center / contain no-repeat;
}

.eggs-dock .lang-toggle:hover,
.eggs-dock .lang-toggle:focus-visible {
    background: color-mix(in srgb, var(--fg) 8%, transparent);
    color: var(--fg);
}

/* 中英切换：左边写清这是"语言"，右边把两个选项都摆出来。
   金色底是一块会滑的 thumb（.lang-toggle-inner::before），两段文字只换颜色 ——
   语言指示要的是"从这格滑到那格"，不是整块翻转，所以把 style.css 挂在
   .lang-toggle-inner 上的那套 flip 动画在这里关掉 */
.eggs-dock .lang-toggle-label {
    flex: 1 1 auto;
}

.eggs-dock .lang-toggle.wobbling .lang-toggle-inner {
    animation: none;
}

.eggs-dock .lang-toggle-inner {
    --lang-seg-w: 34px;
    --lang-seg-gap: 2px;

    position: relative;

    display: inline-flex;
    flex: 0 0 auto;
    align-items: center;
    gap: var(--lang-seg-gap);

    padding: 2px;
    background: var(--bg-2);
    border: 1px solid var(--border-soft);
    border-radius: 999px;
}

.eggs-dock .lang-toggle-inner::before {
    content: '';

    position: absolute;
    top: 2px;
    bottom: 2px;
    left: 2px;
    width: var(--lang-seg-w);

    border-radius: 999px;
    background: var(--egg-gold);

    transform: translateX(0);
    transition: transform 0.26s cubic-bezier(0.32, 0.9, 0.4, 1);
}

.eggs-dock .lang-toggle[data-lang="en"] .lang-toggle-inner::before {
    transform: translateX(calc(var(--lang-seg-w) + var(--lang-seg-gap)));
}

.eggs-dock .lang-seg {
    position: relative;             /* 文字要压在 thumb 上面 */
    z-index: 1;

    flex: 0 0 var(--lang-seg-w);    /* 两格等宽：thumb 位移量才算得准 */
    padding: 1px 0;
    border-radius: 999px;

    font-size: 11px;
    letter-spacing: 0.06em;
    text-align: center;
    color: var(--muted);
    transition: color 0.2s ease;
}

.eggs-dock .lang-seg.is-on {
    font-weight: 600;
    /* 亮色金底是棕金（白字）、暗色金底是亮橙（深字）——正好是 --on-accent 的两态 */
    color: var(--on-accent);
}

@media (prefers-reduced-motion: reduce) {
    .eggs-dock .lang-toggle-inner::before {
        transition: none;
    }
}

/* 引擎加载失败时 companion 会把宿主 hidden；我的 .eggs-dock .eggs-mascot 是 display:flex，
   特异度高于 UA 的 [hidden]，不显式压回去会露出一个空盒子 */
.eggs-dock .eggs-mascot[hidden] {
    display: none;
}

.eggs-dock-launcher {
    position: relative;

    width: 68px;
    height: 68px;
    padding: 0;

    background: transparent;
    border: none;
    border-radius: 50% 50% 50% 50% / 58% 58% 42% 42%;

    cursor: pointer;
}

.eggs-dock-launcher:focus-visible {
    outline: 2px solid var(--egg-gold);
    outline-offset: 3px;
}

/* 角色宿主：铺满按钮，svg 由引擎注入并允许溢出（引擎把视图放大了约 1.131 倍） */
.eggs-dock .eggs-mascot {
    display: flex;
    align-items: center;
    justify-content: center;

    width: 100%;
    height: 100%;
    margin: 0;
}

/* 没角色时的替身：与首页顶栏同一颗蛋的画法 */
.eggs-dock-egg {
    display: none;

    width: 44px;
    height: 56px;
    margin: 6px auto 0;

    background: #26262c;
    border-radius: 50% 50% 50% 50% / 58% 58% 42% 42%;

    box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, 0.22), 0 2px 10px rgba(0, 0, 0, 0.45);
}

/* 亮色两套写法都要盖到（首页显式写 data-theme="light"，功能站是摘掉属性） */
html[data-theme="light"] .eggs-dock-egg,
html:not([data-theme]) .eggs-dock-egg {
    background: #fff;
    box-shadow: inset 0 0 0 1.5px rgba(0, 0, 0, 0.18), 0 2px 8px rgba(0, 0, 0, 0.12);
}

.eggs-mascot:empty ~ .eggs-dock-egg {
    display: block;
}

/* 悬停只做"预备"反馈：发光 + 轻微浮起。
   侧栏里鼠标经常路过，一碰就弹面板会很吵；展开只靠点击（eggs-dock.js）。 */
.eggs-dock-launcher:hover .eggs-dock-egg {
    transform: translateY(-2px);
    filter: drop-shadow(0 0 10px color-mix(in srgb, var(--egg-gold) 35%, transparent));
}

.eggs-dock-launcher:hover .eggs-mascot svg {
    filter: drop-shadow(0 0 10px color-mix(in srgb, var(--egg-gold) 30%, transparent));
}

.eggs-dock-launcher:active .eggs-dock-egg {
    transform: translateY(0);
}

.eggs-dock-egg {
    transition: transform 0.2s ease, box-shadow 0.35s ease, background-color 0.35s ease;
}

@media (max-width: 700px) {

    .eggs-dock[data-mount="corner"] {
        --dock-right: 14px;   /* 窄屏没有"内容列外面"这回事，写死回视口角落 */
        right: 14px;
        bottom: calc(var(--edge-foot-h, 74px) + 12px);
    }

    /* ≤700px 侧栏转 static 并占满整行，面板再往右浮就出屏了 —— 回落到流内 */
    .eggs-dock[data-mount="sidebar"] .eggs-dock-flyout {
        position: static;
        width: auto;
        max-height: none;
        overflow: visible;
    }

    .eggs-dock-launcher {
        width: 56px;
        height: 56px;
    }

    .eggs-dock-egg {
        width: 36px;
        height: 46px;
    }

    .eggs-dock-menu {
        min-width: 160px;
    }
}

@media (prefers-reduced-motion: reduce) {

    .eggs-dock-item,
    .eggs-dock-egg {
        transition: none;
    }
}


/* ==================== BewlyCat 玻璃统一层 ====================
 * 功能面板里定义在 style.css 的公共部件（稳定链接 / 验证模态 / 输入行 / 按钮）
 * 在 egg 页语境下换玻璃质感。全部走共享 token：
 * html.glass-off 时 --up-glass-* 自动回退实色，backdrop 在文末统一关闭。
 * 只换外观：seg-indicator 滑块、聚光灯 --mx/--my、FLIP 机制一概不动。
 * ==================== */

/* 稳定链接块：左边 3px 金边保留 */
.feature-bili .bili-stable-link {
    background: var(--up-glass-bg);

    border-color:
        var(--up-glass-border)
        var(--up-glass-border)
        var(--up-glass-border)
        var(--egg-gold);
}

/* 人机验证模态框体（overlay 仍是 style.css 的压暗层） */
.dl-modal-overlay .dl-modal {
    background: var(--up-glass-bg);

    border: 1px solid var(--up-glass-border);

    border-radius: 16px;

    box-shadow: var(--edge-glow), var(--shadow-3);

    -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
    backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
}

/* 输入行 / 搜索框：玻璃底 + 金色聚焦环（对齐账号中心 .acct-input 的视觉语言） */
.eggs-page .bili-input-row input,
.feature-download .dl-search-input {
    border-color: var(--up-glass-border);

    background: var(--up-glass-bg);
}

.eggs-page .bili-input-row input:focus,
.feature-download .dl-search-input:focus {
    border-color: var(--egg-gold);

    box-shadow:
        0 0 0 3px color-mix(in srgb, var(--egg-gold) 18%, transparent);
}

/* egg 页语境下的按钮胶囊化（不动 style.css 的公共 .button / .submit-button） */
.eggs-page .button,
.eggs-page .submit-button,
.eggs-page .bili-secondary-btn {
    border-radius: 999px;
}

/* glass-off：关闭这层新加的 backdrop（变量回退由 style.css 的 token 重指统一处理） */
html.glass-off .eggs-dock-menu,
html.glass-off .feature-bili .bili-seg,
html.glass-off .feature-download .download-card,
html.glass-off .feature-vrchat .vrc-res-card,
html.glass-off .dl-modal-overlay .dl-modal {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
}


