/* ==============================================================
   TakeKit 设计系统
   --------------------------------------------------------------
   蓝色商务风：主色 #1677FF，白底卡片 + 浅灰边框，圆角 6px。
   全站不使用 emoji，图标统一走 core.js 里的内联 SVG 图标集。

   想换配色，只改下面 :root 里的变量即可，全站跟着变（含深色模式）。
   ============================================================== */

/* ---------- 1. 设计变量 ---------- */
:root {
    /* ---------- 品牌色：蜜桃樱粉 ---------- */
    /* --primary 用于图标、描边、装饰、浅底高亮（坐在浅色背景上） */
    --primary: #ff7ba0;
    --primary-hover: #ff92b1;
    --primary-active: #e85c86;
    /* --primary-strong 用于「白字坐在粉底上」的场合（按钮、选中的菜单/标签），
       比 --primary 深一档，保证白字看得清 */
    --primary-strong: #e85c86;
    --primary-strong-hover: #f2688f;
    --primary-strong-active: #d14670;
    /* --link 用于正文里的链接和文字按钮，再深一档保证可读性 */
    --link: #d94d78;
    --link-hover: #e85c86;
    --primary-soft: #fff2f6;
    --primary-border: #ffc9da;
    --primary-glow: rgba(255, 123, 160, 0.22);

    /* ---------- 樱粉渐变（顶部区域、封面、图标底） ---------- */
    --grad-sakura: linear-gradient(135deg, #ffb3c6 0%, #ffe3ec 100%);
    --grad-sakura-strong: linear-gradient(135deg, #ff9eb8 0%, #ffd0e0 100%);
    --grad-peach: linear-gradient(135deg, #ffc2a8 0%, #ffe9de 100%);

    /* ---------- 语义色 ---------- */
    --success: #52c41a;
    --success-soft: #f6ffed;
    --success-border: #b7eb8f;
    --warning: #faad14;
    --warning-soft: #fffbe6;
    --warning-border: #ffe58f;
    --error: #ff4d4f;
    --error-soft: #fff2f0;
    --error-border: #ffccc7;

    /* ---------- 中性色：带一点暖调，和粉更搭 ---------- */
    --text: #2e2429;
    --text-2: #6b5c63;
    /* 这两级以前偏淡（#9c8c93 在白底上对比度只有 3.0，正文级别的文字读着累）。
       现在 --text-3 压到 4.5:1 上下，描述类文字都用它。 */
    --text-3: #80717a;
    --text-4: #a89aa1;

    --bg-layout: #fffbfd;
    --bg-container: #ffffff;
    /* 整页背景模式下的卡片底色：半透明，让背景透出来 */
    --surface-translucent: rgba(255, 255, 255, 0.84);
    /* 整页背景上那层纱的颜色（不透明度由主播选的档位决定，见 .host-bg-veil） */
    --page-veil-rgb: 253, 247, 249;
    /* 浮在画面上的按钮：半透明底 + 投影，看着像一扇小窗 */
    --float-bg: rgba(255, 255, 255, 0.78);
    --float-border: rgba(255, 255, 255, 0.9);
    --float-shadow: 0 6px 22px rgba(120, 70, 90, 0.16);
    --bg-hover: #fff7fa;
    --bg-fill: #fdf3f6;
    --border: #f0dfe5;
    --border-2: #f7edf1;
    --border-split: #f5e9ee;

    /* ---------- 圆角：比商务风更大，更可爱 ---------- */
    --radius-sm: 8px;
    --radius: 10px;
    --radius-lg: 14px;
    --radius-pill: 999px;

    /* ---------- 阴影：柔、散，带极淡的粉调 ---------- */
    --shadow-sm: 0 1px 3px rgba(214, 120, 150, 0.06);
    --shadow: 0 3px 12px rgba(214, 120, 150, 0.10);
    --shadow-lg: 0 8px 28px rgba(214, 120, 150, 0.16);
    --shadow-pink: 0 6px 18px rgba(255, 123, 160, 0.28);

    /* ---------- 间距刻度 ----------
       全站只用这几个值。以前是 8/12/16/20/24 随手写，
       20 这种不在刻度上的值会让节奏显得零碎。 */
    --sp-1: 4px;
    --sp-2: 8px;
    --sp-3: 12px;
    --sp-4: 16px;
    --sp-5: 24px;
    --sp-6: 32px;

    --header-h: 56px;
    --sidebar-w: 220px;
    /* 沉浸模式下浮在画面上的控件占掉的高度（顶部 14 + 控件 38 + 一点余量）。
       主页和组件页的顶部留白都按它来，两边的节奏才一致。 */
    --float-band: 64px;

    --font: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB',
            'Microsoft YaHei', 'Helvetica Neue', Helvetica, Arial, sans-serif;
    --font-mono: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;

    --transition: 0.2s ease;
}

/* ---------- 深色模式 ---------- */
/* 注意：粉主题在深色下一定要换掉「深底浅粉」这一组，
   否则会残留上一版商务蓝的色块 */
[data-theme='dark'] {
    --primary-soft: #3a2029;
    --primary-border: #5c2f3f;
    --primary-glow: rgba(255, 123, 160, 0.25);
    --primary-strong: #e85c86;
    --primary-strong-hover: #f2688f;
    --primary-strong-active: #d14670;
    --link: #ff9eb8;
    --link-hover: #ffb3c6;

    --grad-sakura: linear-gradient(135deg, #4a2a35 0%, #2e1e26 100%);
    --grad-sakura-strong: linear-gradient(135deg, #5c3340 0%, #3a2530 100%);
    --grad-peach: linear-gradient(135deg, #4a332a 0%, #2e2320 100%);

    --success-soft: #162312;
    --success-border: #274916;
    --warning-soft: #2b2111;
    --warning-border: #594214;
    --error-soft: #2c1618;
    --error-border: #58181c;

    --text: rgba(255, 246, 249, 0.94);
    --text-2: rgba(255, 240, 245, 0.74);
    --text-3: rgba(255, 235, 240, 0.60);
    --text-4: rgba(255, 230, 238, 0.34);

    --bg-layout: #1a1418;
    --bg-container: #241c21;
    --surface-translucent: rgba(36, 28, 33, 0.84);
    /* 深色主题下罩层得是暗的，否则整页泛白 */
    --page-veil-rgb: 30, 23, 28;
    --float-bg: rgba(48, 38, 44, 0.78);
    --float-border: rgba(255, 255, 255, 0.12);
    --float-shadow: 0 6px 22px rgba(0, 0, 0, 0.45);
    --bg-hover: #2d2329;
    --bg-fill: #2d2329;
    --border: #3d3038;
    --border-2: #2f252b;
    --border-split: #2f252b;

    --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.30);
    --shadow: 0 3px 12px rgba(0, 0, 0, 0.35);
    --shadow-lg: 0 8px 28px rgba(0, 0, 0, 0.50);
    --shadow-pink: 0 6px 18px rgba(255, 123, 160, 0.20);
}

/* ---------- 2. 基础 ---------- */
* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

html {
    -webkit-text-size-adjust: 100%;
}

body {
    font-family: var(--font);
    font-size: 14px;
    line-height: 1.5715;
    color: var(--text);
    background: var(--bg-layout);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    transition: background var(--transition), color var(--transition);
}

a {
    color: var(--link);
    text-decoration: none;
    cursor: pointer;
}

a:hover {
    color: var(--link-hover);
}

img {
    max-width: 100%;
}

::-webkit-scrollbar {
    width: 8px;
    height: 8px;
}

::-webkit-scrollbar-track {
    background: transparent;
}

::-webkit-scrollbar-thumb {
    background: var(--text-4);
    border-radius: var(--radius-pill);
}

::-webkit-scrollbar-thumb:hover {
    background: var(--text-3);
}

/* 图标统一对齐 */
.y-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    vertical-align: -0.15em;
}

/* ---------- 3. 布局 ---------- */
.layout {
    display: flex;
    min-height: 100vh;
}

.sidebar {
    width: var(--sidebar-w);
    background: var(--bg-container);
    border-right: 1px solid var(--border-split);
    display: flex;
    flex-direction: column;
    flex-shrink: 0;
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    z-index: 100;
}

.sidebar-logo {
    height: var(--header-h);
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 0 20px;
    font-size: 16px;
    font-weight: 600;
    color: var(--text);
    border-bottom: 1px solid var(--border-split);
    flex-shrink: 0;
}

.sidebar-logo .logo-mark {
    width: 26px;
    height: 26px;
    border-radius: var(--radius-sm);
    background: var(--primary-strong);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.sidebar-menu {
    flex: 1;
    overflow-y: auto;
    padding: 8px;
}

.menu-group {
    font-size: 12px;
    color: var(--text-3);
    padding: 14px 12px 6px;
    font-weight: 500;
}

.menu-item {
    display: flex;
    align-items: center;
    gap: 10px;
    height: 40px;
    padding: 0 12px;
    border-radius: var(--radius);
    color: var(--text-2);
    font-size: 14px;
    cursor: pointer;
    transition: background var(--transition), color var(--transition);
    margin-bottom: 2px;
    user-select: none;
}

.menu-item:hover {
    background: var(--bg-hover);
    color: var(--text);
}

/* 「审核中」这类只是给个状态、点开也没有可操作项的条目，别做得像能点 */
.menu-item.is-muted {
    color: var(--text-3);
    cursor: default;
}

.menu-item.is-muted:hover {
    background: transparent;
    color: var(--text-3);
}

.menu-item.active {
    background: var(--primary-soft);
    color: var(--primary);
    font-weight: 500;
}

/* 一个组件都没开时占位，别让「组件」那一栏下面空一块 */
.menu-empty {
    padding: 2px 12px 6px;
    font-size: 13px;
    color: var(--text-4);
}

.menu-item .menu-badge {
    margin-left: auto;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    border-radius: var(--radius-pill);
    background: var(--error);
    color: #fff;
    font-size: 11px;
    line-height: 18px;
    text-align: center;
    font-weight: 500;
}

.main {
    flex: 1;
    min-width: 0;
    margin-left: var(--sidebar-w);
    display: flex;
    flex-direction: column;
}

.header {
    height: var(--header-h);
    background: var(--bg-container);
    border-bottom: 1px solid var(--border-split);
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 0 24px;
    position: sticky;
    top: 0;
    z-index: 50;
}

.header-title {
    font-size: 15px;
    font-weight: 600;
}

.header-right {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 10px;
}

.content {
    flex: 1;
    padding: 20px var(--viewer-gutter) 40px;
    /*
     * 不再封顶 1400px：窗口放大，内容列跟着放大，左右只留 --viewer-gutter。
     * 封顶的那版在 2K 屏上左右各空几百像素，主播反馈「两边很空」。
     */
    max-width: 100%;
    width: 100%;
    margin: 0 auto;
    /* 同样立成一列：.main 已经是纵向 flex，这里接手后 .host-home 才能吃掉剩下的高度，
       主播个人页内容不满一屏时页脚才会贴到底部（见 .host-footer 的 margin-top: auto）。 */
    display: flex;
    flex-direction: column;
}

@media (max-width: 900px) {
    .sidebar {
        transform: translateX(-100%);
        transition: transform 0.25s ease;
        box-shadow: var(--shadow-lg);
    }

    .sidebar.open {
        transform: translateX(0);
    }

    .main {
        margin-left: 0;
    }

    .content {
        padding: 16px 14px 32px;
    }

    .header {
        padding: 0 14px;
    }
}

.sidebar-mask {
    display: none;
}

@media (max-width: 900px) {
    .sidebar-mask {
        display: block;
        position: fixed;
        inset: 0;
        background: rgba(0, 0, 0, 0.45);
        z-index: 99;
    }
}

/* ------------------------------------------------------------------
 * 沉浸模式：看主播主页 / 组件页时把周围的界面收起来
 *
 * 侧边栏不再占着一整列（改成抽屉，点左上角那个按钮拉开），内容占满整屏，
 * 顶栏只留「当前主播 + 切换 + 一点必要的按钮」。
 * 上面那套 @media 只在窄屏生效，这里要的是任何宽度都成立，所以单独写一份。
 * ------------------------------------------------------------------ */
.layout.immersive .sidebar {
    transform: translateX(-100%);
    transition: transform 0.25s ease;
    box-shadow: var(--shadow-lg);
}

.layout.immersive .sidebar.open {
    transform: translateX(0);
}

.layout.immersive .main {
    margin-left: 0;
}

.layout.immersive .sidebar-mask {
    display: block;
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.45);
    z-index: 99;
}

/* 顶栏整个不显示：看主播时是满屏的，跟分享出去的歌单页一个观感 */
.layout.immersive .header {
    display: none;
}

/* 没有顶栏了，内容从最顶上开始 */
.layout.immersive .content {
    padding-top: 0;
}

/* 汉堡按钮：窄屏本来就要显示，非沉浸模式下任何宽度都显示 */
.fan-menu-toggle {
    display: none;
}

@media (max-width: 900px) {
    .fan-menu-toggle {
        display: inline-flex;
    }
}

/* ---------- 主播切换器（沉浸模式下浮在画面左上角） ---------- */

.host-switch {
    position: fixed;
    top: 14px;
    /* 和内容列的左边线对齐（沉浸模式下内容走 .content 的 padding） */
    left: var(--viewer-gutter);
    z-index: 80;
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
}

/* 拉开侧边栏的小按钮，和切换器并排浮着 */
.float-btns {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-shrink: 0;
}

.float-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    border-radius: 50%;
    background: var(--float-bg);
    border: 1px solid var(--float-border);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    box-shadow: var(--float-shadow);
    color: var(--text-2);
    font-family: inherit;
    cursor: pointer;
    transition: all var(--transition);
}

.float-btn:hover {
    color: var(--primary);
    border-color: var(--primary);
}

/*
 * 像一扇浮在画面上的小窗：半透明 + 毛玻璃 + 投影。
 * 底色用变量而不是写死白色，深色主题下才不会突兀。
 */
.host-switch-chip {
    display: flex;
    align-items: center;
    gap: 9px;
    height: 38px;
    max-width: 260px;
    padding: 0 14px 0 7px;
    background: var(--float-bg);
    border: 1px solid var(--float-border);
    border-radius: 999px;
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    box-shadow: var(--float-shadow);
    color: var(--text);
    font-family: inherit;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    transition: all var(--transition);
}

.host-switch-chip:hover,
.host-switch-chip.open {
    border-color: var(--primary);
    color: var(--primary-strong);
}

.host-switch-chip .avatar {
    border: 1px solid var(--float-border);
}

.host-switch-chip .ellipsis {
    min-width: 0;
}

.host-switch-chip .y-icon {
    color: var(--text-3);
    flex-shrink: 0;
    transition: transform var(--transition);
}

.host-switch-chip.open .y-icon {
    transform: rotate(180deg);
    color: var(--primary);
}

/* 点开后竖直列出关注的主播：人多时自己滚动，不撑破屏幕 */
.host-switch-row {
    position: absolute;
    top: calc(100% + 8px);
    left: 0;
    z-index: 60;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 6px;
    width: min(78vw, 230px);
    max-height: min(60vh, 340px);
    padding: 8px;
    overflow-y: auto;
    overflow-x: hidden;
    background: var(--float-bg);
    border: 1px solid var(--float-border);
    border-radius: var(--radius-lg);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    box-shadow: var(--float-shadow);
    animation: host-switch-in 0.16s ease;
}

@keyframes host-switch-in {
    from { opacity: 0; transform: translateY(-6px); }
    to { opacity: 1; transform: translateY(0); }
}

.host-switch-item {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-shrink: 0;
    width: 100%;
    height: 38px;
    padding: 0 12px 0 6px;
    background: var(--bg-fill);
    border: 1px solid transparent;
    border-radius: 999px;
    color: var(--text-2);
    font-family: inherit;
    font-size: 13px;
    text-align: left;
    cursor: pointer;
    transition: all var(--transition);
}

.host-switch-item:hover {
    background: var(--bg-hover);
    color: var(--text);
}

.host-switch-item.active {
    background: var(--primary-soft);
    border-color: var(--primary);
    color: var(--primary-strong);
    font-weight: 600;
}

.host-switch-add {
    padding: 0 14px;
    color: var(--text-3);
    background: transparent;
    border: 1px dashed var(--float-border);
}

.host-switch-add:hover {
    border-style: solid;
    border-color: var(--primary);
    color: var(--primary);
}

@media (max-width: 640px) {
    .host-switch-chip {
        max-width: 150px;
    }

    .host-switch-row {
        width: calc(100vw - 28px);
    }
}

/* ---------- 4. 工具类 ---------- */.flex { display: flex; }
.flex-col { display: flex; flex-direction: column; }
.flex-1 { flex: 1; min-width: 0; }
.flex-wrap { flex-wrap: wrap; }
.items-center { align-items: center; }
.justify-between { justify-content: space-between; }
.flex-between { display: flex; align-items: center; justify-content: space-between; }
.gap-4 { gap: 4px; }
.gap-8 { gap: 8px; }
.gap-12 { gap: 12px; }
.gap-16 { gap: 16px; }
.mt-8 { margin-top: 8px; }
.mt-12 { margin-top: 12px; }
.mt-16 { margin-top: 16px; }
.mt-24 { margin-top: 24px; }
.mb-8 { margin-bottom: 8px; }
.mb-12 { margin-bottom: 12px; }
.mb-16 { margin-bottom: 16px; }
.mb-24 { margin-bottom: 24px; }
.text-2 { color: var(--text-2); }
.text-3 { color: var(--text-3); }
.text-sm { font-size: 12px; }
.text-lg { font-size: 16px; }
.text-center { text-align: center; }
.bold { font-weight: 600; }
.nowrap { white-space: nowrap; }
.mono { font-family: var(--font-mono); }
.pointer { cursor: pointer; }
.hidden { display: none !important; }

.ellipsis {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* 小屏专用：手机上才出现的元素（.hide-sm 的反面） */
.show-sm { display: none !important; }

@media (max-width: 900px) {
    .hide-sm { display: none !important; }

    .show-sm { display: inline-flex !important; }
}

/* ---------- 5. 卡片 ---------- */
.card {
    background: var(--bg-container);
    border: 1px solid var(--border-split);
    border-radius: var(--radius-lg);
    padding: 20px;
    margin-bottom: 16px;
}

.card:last-child {
    margin-bottom: 0;
}

.card-title {
    font-size: 15px;
    font-weight: 600;
    margin-bottom: 16px;
    display: flex;
    align-items: center;
    gap: 8px;
}

.card-title .sub {
    font-size: 12px;
    font-weight: 400;
    color: var(--text-3);
}

.section-title {
    font-size: 15px;
    font-weight: 600;
    margin: 20px 0 12px;
}

.page-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    margin-bottom: 16px;
}

.page-title {
    font-size: 20px;
    font-weight: 600;
    line-height: 1.4;
}

.page-desc {
    font-size: 13px;
    color: var(--text-3);
    margin-top: 4px;
}

/* ---------- 6. 按钮 ---------- */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    height: 32px;
    padding: 0 15px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--bg-container);
    color: var(--text);
    font-size: 14px;
    font-family: inherit;
    line-height: 1;
    cursor: pointer;
    transition: all var(--transition);
    white-space: nowrap;
    user-select: none;
}

.btn:hover {
    border-color: var(--primary);
    color: var(--primary);
}

.btn:disabled {
    cursor: not-allowed;
    opacity: 0.5;
    border-color: var(--border);
    color: var(--text-3);
}

.btn:disabled:hover {
    border-color: var(--border);
    color: var(--text-3);
}

.btn-primary {
    background: var(--primary-strong);
    border-color: var(--primary-strong);
    color: #fff;
}

.btn-primary:hover {
    background: var(--primary-strong-hover);
    border-color: var(--primary-strong-hover);
    color: #fff;
}

.btn-primary:active {
    background: var(--primary-strong-active);
    border-color: var(--primary-strong-active);
}

.btn-default {
    background: var(--bg-container);
    border-color: var(--border);
    color: var(--text);
}

.btn-danger {
    background: var(--bg-container);
    border-color: var(--error-border);
    color: var(--error);
}

.btn-danger:hover {
    background: var(--error);
    border-color: var(--error);
    color: #fff;
}

.btn-text {
    height: auto;
    padding: 0;
    border: none;
    background: none;
    color: var(--link);
    font-size: 14px;
}

.btn-text:hover {
    color: var(--link-hover);
}

.btn-sm {
    height: 26px;
    padding: 0 10px;
    font-size: 13px;
}

.btn-lg {
    height: 40px;
    padding: 0 20px;
    font-size: 15px;
}

.btn-block {
    width: 100%;
}

.btn-icon {
    width: 32px;
    padding: 0;
}

/* 表格行内操作 */
.link-btn {
    background: none;
    border: none;
    padding: 0;
    color: var(--link);
    font-size: 13px;
    font-family: inherit;
    cursor: pointer;
    transition: color var(--transition);
}

.link-btn:hover {
    color: var(--link-hover);
}

.link-btn.danger {
    color: var(--error);
}

.link-btn.danger:hover {
    color: #ff7875;
}

.link-btn.muted {
    color: var(--text-3);
}

.link-btn.muted:hover {
    color: var(--text-2);
}

.link-btn:disabled {
    color: var(--text-4);
    cursor: not-allowed;
}

/* 表格里并排的几个操作链接之间留点空隙，不然会挤成「编辑隐藏删除」 */
.link-btn + .link-btn {
    margin-left: 10px;
}

.link-sep {
    color: var(--border);
    margin: 0 8px;
    user-select: none;
}

/* ---------- 7. 表单 ---------- */
.field {
    margin-bottom: 16px;
}

.field-label {
    display: block;
    font-size: 14px;
    color: var(--text);
    margin-bottom: 6px;
}

.field-hint {
    font-size: 12px;
    color: var(--text-3);
    margin-top: 4px;
    line-height: 1.6;
}

.input,
.select,
.textarea {
    width: 100%;
    height: 32px;
    padding: 0 11px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--bg-container);
    color: var(--text);
    font-size: 14px;
    font-family: inherit;
    outline: none;
    transition: all var(--transition);
}

.textarea {
    height: auto;
    padding: 8px 11px;
    line-height: 1.6;
    resize: vertical;
    min-height: 76px;
}

.input:hover,
.select:hover,
.textarea:hover {
    border-color: var(--primary-hover);
}

.input:focus,
.select:focus,
.textarea:focus {
    border-color: var(--primary);
    box-shadow: 0 0 0 2px rgba(22, 119, 255, 0.12);
}

.input::placeholder,
.textarea::placeholder {
    color: var(--text-4);
}

.input:disabled,
.select:disabled {
    background: var(--bg-fill);
    color: var(--text-3);
    cursor: not-allowed;
}

.select {
    appearance: none;
    padding-right: 28px;
    cursor: pointer;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23bfbfbf' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 10px center;
}

.search-box {
    position: relative;
    flex: 1;
    min-width: 180px;
}

.search-box .input {
    padding-left: 32px;
}

.search-box .search-icon {
    position: absolute;
    left: 10px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--text-4);
    pointer-events: none;
    display: flex;
}

.input-inline {
    height: 28px;
    padding: 0 8px;
    font-size: 13px;
}

.form-error {
    background: var(--error-soft);
    border: 1px solid var(--error-border);
    color: var(--error);
    border-radius: var(--radius);
    padding: 7px 12px;
    font-size: 13px;
    margin-bottom: 12px;
    line-height: 1.6;
}

/* 开关 */
.switch {
    position: relative;
    display: inline-block;
    width: 40px;
    height: 22px;
    flex-shrink: 0;
}

.switch input {
    opacity: 0;
    width: 0;
    height: 0;
}

.switch-slider {
    position: absolute;
    inset: 0;
    background: var(--text-4);
    border-radius: var(--radius-pill);
    cursor: pointer;
    transition: background var(--transition);
}

.switch-slider::before {
    content: '';
    position: absolute;
    width: 18px;
    height: 18px;
    left: 2px;
    top: 2px;
    background: #fff;
    border-radius: 50%;
    transition: transform var(--transition);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
}

.switch input:checked + .switch-slider {
    background: var(--primary-strong);
}

.switch input:checked + .switch-slider::before {
    transform: translateX(18px);
}

.switch input:disabled + .switch-slider {
    opacity: 0.5;
    cursor: not-allowed;
}

/* 默认收件信息：自动带上这一栏 */
.auto-fill-row {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
}

/* ---------- 8. 标签 ---------- */
.tag {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    height: 22px;
    padding: 0 8px;
    border-radius: var(--radius-sm);
    font-size: 12px;
    line-height: 1;
    background: var(--bg-fill);
    border: 1px solid transparent;
    color: var(--text-2);
    white-space: nowrap;
}

.tag-primary { background: var(--primary-soft); border-color: var(--primary-border); color: var(--primary); }
.tag-success { background: var(--success-soft); border-color: var(--success-border); color: var(--success); }
.tag-warning { background: var(--warning-soft); border-color: var(--warning-border); color: #d48806; }
.tag-error   { background: var(--error-soft);   border-color: var(--error-border);   color: var(--error); }
.tag-default { background: var(--bg-fill); color: var(--text-2); }

[data-theme='dark'] .tag-warning { color: var(--warning); }

/* 航海等级标记：用颜色区分，不用 emoji */
.guard-badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    height: 22px;
    padding: 0 8px;
    border-radius: var(--radius-sm);
    font-size: 12px;
    font-weight: 500;
    white-space: nowrap;
    border: 1px solid transparent;
}

.guard-1 { background: #fff7e6; border-color: #ffd591; color: #ad6800; }
.guard-2 { background: #f9f0ff; border-color: #d3adf7; color: #531dab; }
.guard-3 { background: var(--primary-soft); border-color: var(--primary-border); color: var(--link); }

[data-theme='dark'] .guard-1 { background: #2b2111; border-color: #594214; color: #ffc53d; }
[data-theme='dark'] .guard-2 { background: #1f1433; border-color: #391085; color: #b37feb; }
[data-theme='dark'] .guard-3 { background: #3a2029; border-color: #5c2f3f; color: #ff9eb8; }

.chip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    height: 28px;
    padding: 0 12px;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    background: var(--bg-container);
    color: var(--text-2);
    font-size: 13px;
    cursor: pointer;
    transition: all var(--transition);
    user-select: none;
}

.chip:hover {
    border-color: var(--primary);
    color: var(--primary);
}

.chip.active {
    background: var(--primary-strong);
    border-color: var(--primary-strong);
    color: #fff;
}

.chip .count {
    font-size: 11px;
    opacity: 0.75;
}

.chip-row {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    margin-bottom: 16px;
}

/* ---------- 9. 表格 ---------- */
.table-wrap {
    overflow-x: auto;
}

.table {
    width: 100%;
    border-collapse: collapse;
    font-size: 14px;
}

.table th {
    text-align: left;
    padding: 11px 14px;
    font-weight: 500;
    font-size: 13px;
    color: var(--text-2);
    background: var(--bg-fill);
    border-bottom: 1px solid var(--border-split);
    white-space: nowrap;
}

.table td {
    padding: 12px 14px;
    border-bottom: 1px solid var(--border-split);
    vertical-align: middle;
}

.table tbody tr:last-child td {
    border-bottom: none;
}

.table tbody tr {
    transition: background var(--transition);
}

.table tbody tr:hover {
    background: var(--bg-hover);
}

.cell-empty {
    text-align: center;
    color: var(--text-3);
    padding: 40px 16px !important;
}

/* 批量操作条 */
.bulk-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    padding: 10px 16px;
    background: var(--primary-soft);
    border: 1px solid var(--primary-border);
    border-radius: var(--radius);
    font-size: 13px;
    margin-bottom: 12px;
}

.toolbar-row {
    display: flex;
    gap: 10px;
    align-items: center;
    flex-wrap: wrap;
}

/* ---------- 10. 头像 ---------- */
.avatar {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    object-fit: cover;
    background: var(--bg-fill);
    flex-shrink: 0;
    display: block;
}

.avatar-sm { width: 26px; height: 26px; }
.avatar-lg { width: 56px; height: 56px; }
.avatar-xl { width: 76px; height: 76px; }

/* ---------- 11. 统计卡 ---------- */
.stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    gap: 16px;
    margin-bottom: 16px;
}

.stat-card {
    background: var(--bg-container);
    border: 1px solid var(--border-split);
    border-radius: var(--radius-lg);
    padding: 18px 20px;
}

.stat-label {
    font-size: 13px;
    color: var(--text-3);
    display: flex;
    align-items: center;
    gap: 6px;
    margin-bottom: 6px;
}

.stat-value {
    font-size: 26px;
    font-weight: 600;
    line-height: 1.2;
    font-variant-numeric: tabular-nums;
    color: var(--text);
}

.stat-value.primary { color: var(--primary-strong); }
.stat-value.success { color: var(--success); }
.stat-value.warning { color: #d48806; }
.stat-value.error { color: var(--error); }

@media (max-width: 640px) {
    .stat-grid { grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 10px; }
    .stat-card { padding: 14px; }
    .stat-value { font-size: 21px; }
}

/* ---------- 12. 弹窗 ---------- */
.modal-mask {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.45);
    display: flex;
    align-items: flex-start;
    justify-content: center;
    z-index: 1000;
    padding: 60px 20px 40px;
    overflow-y: auto;
    animation: fadeIn 0.16s ease;
}

.modal {
    background: var(--bg-container);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    width: 100%;
    max-width: 460px;
    animation: modalIn 0.2s ease;
}

.modal-lg { max-width: 680px; }
.modal-sm { max-width: 380px; }

.modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 18px 24px 0;
}

.modal-title {
    font-size: 16px;
    font-weight: 600;
    line-height: 1.4;
}

.modal-close {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border: none;
    background: none;
    border-radius: var(--radius);
    color: var(--text-3);
    cursor: pointer;
    transition: all var(--transition);
}

.modal-close:hover {
    background: var(--bg-hover);
    color: var(--text);
}

.modal-body {
    padding: 20px 24px;
}

.modal-text {
    font-size: 14px;
    line-height: 1.7;
    color: var(--text-2);
}

.modal-footer {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    padding: 0 24px 20px;
}

@keyframes fadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}

@keyframes modalIn {
    from { opacity: 0; transform: translateY(-12px); }
    to { opacity: 1; transform: translateY(0); }
}

/* ---------- 13. Toast ---------- */
.toast-container {
    position: fixed;
    top: 20px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 2000;
    display: flex;
    flex-direction: column;
    gap: 10px;
    align-items: center;
    pointer-events: none;
}

.toast {
    display: flex;
    align-items: center;
    gap: 8px;
    max-width: 92vw;
    padding: 9px 16px;
    background: var(--bg-container);
    border: 1px solid var(--border-split);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    font-size: 14px;
    color: var(--text);
    animation: toastIn 0.2s ease;
}

.toast.leaving {
    animation: toastOut 0.18s ease forwards;
}

.toast-icon {
    display: flex;
    flex-shrink: 0;
}

.toast-success .toast-icon { color: var(--success); }
.toast-error .toast-icon { color: var(--error); }
.toast-warning .toast-icon { color: var(--warning); }
.toast-info .toast-icon { color: var(--primary); }

@keyframes toastIn {
    from { opacity: 0; transform: translateY(-12px); }
    to { opacity: 1; transform: translateY(0); }
}

@keyframes toastOut {
    to { opacity: 0; transform: translateY(-8px); }
}

/* ---------- 14. 空状态 / 加载 ---------- */
.empty {
    text-align: center;
    padding: 48px 20px;
    color: var(--text-3);
}

.empty-icon {
    display: flex;
    justify-content: center;
    color: var(--text-4);
    margin-bottom: 14px;
}

.empty-title {
    font-size: 14px;
    color: var(--text-2);
    margin-bottom: 6px;
}

.empty-desc {
    font-size: 13px;
    line-height: 1.7;
    color: var(--text-3);
}

.skeleton {
    background: linear-gradient(90deg, var(--bg-fill) 25%, var(--bg-hover) 37%, var(--bg-fill) 63%);
    background-size: 400% 100%;
    animation: shimmer 1.4s ease infinite;
    border-radius: var(--radius);
}

.skeleton-list {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.skeleton-row {
    height: 48px;
}

.skeleton-line {
    height: 14px;
    margin-bottom: 10px;
}

@keyframes shimmer {
    0% { background-position: 100% 50%; }
    100% { background-position: 0 50%; }
}

.spinner {
    display: inline-block;
    width: 16px;
    height: 16px;
    border: 2px solid var(--border);
    border-top-color: var(--primary);
    border-radius: 50%;
    animation: spin 0.7s linear infinite;
}

@keyframes spin {
    to { transform: rotate(360deg); }
}

/* ---------- 15. 分页 ---------- */
.pager {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    flex-wrap: wrap;
    margin-top: 16px;
}

.pager-btn {
    height: 32px;
    padding: 0 12px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--bg-container);
    color: var(--text-2);
    font-size: 14px;
    font-family: inherit;
    cursor: pointer;
    transition: all var(--transition);
}

.pager-btn:hover:not(:disabled) {
    border-color: var(--primary);
    color: var(--primary);
}

.pager-btn:disabled {
    color: var(--text-4);
    cursor: not-allowed;
}

.pager-info {
    font-size: 13px;
    color: var(--text-3);
    padding: 0 4px;
}

/* ---------- 16. 组件崩溃占位 ---------- */
.plugin-crash {
    text-align: center;
    padding: 40px 24px;
    background: var(--bg-container);
    border: 1px dashed var(--error-border);
    border-radius: var(--radius-lg);
}

.plugin-crash-icon {
    display: flex;
    justify-content: center;
    color: var(--error);
    margin-bottom: 12px;
}

.plugin-crash h3 {
    font-size: 15px;
    font-weight: 600;
    margin-bottom: 8px;
}

.plugin-crash p {
    font-size: 12px;
    color: var(--text-3);
    font-family: var(--font-mono);
    word-break: break-all;
    line-height: 1.7;
    margin-bottom: 16px;
}

/* ---------- 17. 登录注册面板 ---------- */
.auth-page {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 40px 20px;
    background: var(--bg-layout);
}

.auth-card {
    width: 100%;
    max-width: 440px;
    background: var(--bg-container);
    border: 1px solid var(--border-split);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
    padding: 32px;
}

.auth-brand {
    text-align: center;
    margin-bottom: 26px;
}

.auth-brand .logo-mark {
    width: 44px;
    height: 44px;
    border-radius: var(--radius-lg);
    background: var(--primary-strong);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0 auto 12px;
}

.auth-brand h1 {
    font-size: 19px;
    font-weight: 600;
    margin-bottom: 4px;
}

.auth-brand p {
    font-size: 13px;
    color: var(--text-3);
}

.auth-switch {
    text-align: center;
    font-size: 13px;
    color: var(--text-3);
    margin-top: 16px;
}

.auth-switch a {
    font-size: 13px;
}

/* 提示块 */
.info-block {
    display: flex;
    gap: 9px;
    padding: 11px 14px;
    background: var(--primary-soft);
    border: 1px solid var(--primary-border);
    border-radius: var(--radius);
    font-size: 13px;
    line-height: 1.65;
    color: var(--text-2);
}

.info-block .info-icon {
    color: var(--primary);
    flex-shrink: 0;
    margin-top: 2px;
    display: flex;
}

.info-block.warning {
    background: var(--warning-soft);
    border-color: var(--warning-border);
}

.info-block.warning .info-icon {
    color: var(--warning);
}

/* 注册：B站 个性签名验证 */
.verify-code-box {
    padding: 18px 14px;
    margin-bottom: 16px;
    text-align: center;
    background: var(--bg-fill);
    border: 1px dashed var(--primary-border);
    border-radius: var(--radius);
    cursor: pointer;
    transition: var(--transition);
}

.verify-code-box:hover {
    background: var(--primary-soft);
    border-color: var(--primary);
}

.verify-code {
    font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
    font-size: 26px;
    font-weight: 700;
    letter-spacing: 6px;
    color: var(--primary);
    /* 字母之间已经有间距了，这里把首尾多出来的那点补回去，看起来才是居中的 */
    text-indent: 6px;
    margin-bottom: 6px;
    user-select: all;
}

.verify-steps {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-bottom: 16px;
    font-size: 13px;
    color: var(--text-2);
    line-height: 1.6;
}

.verify-step {
    display: flex;
    align-items: flex-start;
    gap: 8px;
}

.verify-num {
    flex-shrink: 0;
    width: 18px;
    height: 18px;
    margin-top: 1px;
    border-radius: 50%;
    background: var(--primary-soft);
    color: var(--primary);
    font-size: 11px;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* B站 资料预览 */
.bili-preview {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 14px;
    background: var(--bg-fill);
    border-radius: var(--radius);
    margin-bottom: 18px;
}

/* 身份选择 */
.identity-list {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.identity-item {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 13px 15px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    cursor: pointer;
    transition: all var(--transition);
}

.identity-item:hover {
    border-color: var(--primary-hover);
}

.identity-item.active {
    border-color: var(--primary);
    background: var(--primary-soft);
}

.identity-item input {
    margin-top: 3px;
    accent-color: var(--primary);
    flex-shrink: 0;
}

.identity-icon {
    color: var(--text-3);
    display: flex;
    margin-top: 1px;
    flex-shrink: 0;
}

.identity-item.active .identity-icon {
    color: var(--primary);
}

.identity-body {
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 0;
}

.identity-title {
    font-size: 14px;
    font-weight: 500;
    color: var(--text);
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
}

.identity-desc {
    font-size: 12px;
    color: var(--text-3);
    line-height: 1.6;
}

/* ---------- 18. 粉丝端：主播主页 ---------- */
/*
 * 内容宽度与左右内边距。
 *
 * 顶栏和主体共用这两个变量 —— 两边要是各写各的，宽屏下品牌和内容就会错位。
 *
 * 这里不再给内容列封顶：窗口放大，内容跟着一起放大，左右只留一条随屏宽增长的
 * --viewer-gutter。以前按屏宽分三档（1000 / 1240 / 1400），2K 屏上 1400 卡在
 * 中间、左右各空出几百像素，主播反馈「两边很空、内容不跟着放大」。
 */
:root {
    --viewer-w: 100%;
    /* 内容列的内边距：小屏 20px，屏越宽越长，最多 56px */
    --viewer-gutter: clamp(20px, 1.6vw, 56px);
}

.viewer-page {
    min-height: 100vh;
    background: var(--bg-layout);
    /* 立成一列，好让 .viewer-body 吃掉头部之外剩下的高度 ——
       内容不满一屏时，页脚才有地方可贴（见 .host-footer 的 margin-top: auto）。 */
    display: flex;
    flex-direction: column;
}

.viewer-header {
    background: var(--bg-container);
    border-bottom: 1px solid var(--border-split);
    position: sticky;
    top: 0;
    z-index: 50;
}

/*
 * 主播开了整页背景时，站点头也跟着浮到画面上 —— 不然顶上会留一条不透明的白条，
 * 背景看起来就「只铺了下面那一截」。品牌和右边那几个按钮各自变成浮起的小药丸，
 * 压在图上照样看得清；整条头部本身不吃点击，中间的空隙可以点到下面的内容。
 */
.viewer-page.has-page-bg .viewer-header {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    background: transparent;
    border-bottom: none;
    pointer-events: none;
}

.viewer-page.has-page-bg .viewer-header-inner {
    height: auto;
    padding: 14px var(--viewer-gutter) 0;
}

.viewer-page.has-page-bg .viewer-header .brand,
.viewer-page.has-page-bg .viewer-header-right > * {
    pointer-events: auto;
    background: var(--float-bg);
    border: 1px solid var(--float-border);
    border-radius: 999px;
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    box-shadow: var(--float-shadow);
}

.viewer-page.has-page-bg .viewer-header .brand {
    height: 38px;
    padding: 0 15px 0 7px;
    border-radius: 999px;
}

.viewer-header-inner {
    max-width: var(--viewer-w);
    margin: 0 auto;
    height: var(--header-h);
    padding: 0 var(--viewer-gutter);
    display: flex;
    align-items: center;
    gap: 12px;
}

.viewer-header .brand {
    display: flex;
    align-items: center;
    gap: 9px;
    font-size: 15px;
    font-weight: 600;
    color: var(--text);
}

.viewer-header .brand .logo-mark {
    width: 24px;
    height: 24px;
    border-radius: var(--radius-sm);
    background: var(--primary-strong);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
}

.viewer-header-right {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 8px;
}

.viewer-body {
    max-width: var(--viewer-w);
    /*
     * 这一条 width: 100% 不能省：.viewer-page 是列向 flex，而下面又写了
     * margin: 0 auto，按 flex 规范横轴带 auto 外边距的项不参与 stretch，
     * 于是宽度会退化成「内容有多宽就多宽」（实测 1500 宽的窗口里只有 958px），
     * 主页内容比顶栏窄一截、右边空出一条 —— 主播反馈的就是这个。
     */
    width: 100%;
    margin: 0 auto;
    padding: 20px var(--viewer-gutter) 48px;
    /* 吃掉头部之外的高度；里面的 .host-home 再吃掉这里剩下的高度 */
    flex: 1 0 auto;
    display: flex;
    flex-direction: column;
}

@media (max-width: 640px) {
    .viewer-header-inner { padding: 0 12px; }
    .viewer-body { padding: 14px 12px 36px; }
}

/* 落地页自带整屏布局，不需要外面再套一层留白 */
.viewer-body-plain {
    max-width: none;
    padding: 0;
}

/* 主播主页：封面 + 资料卡 */

/*
 * 整页背景（主播在装扮里选了「铺满整页」）。
 *
 * 用 fixed 铺满整个视口 —— 挂在容器上只能铺到容器那么高，页面一长下面就是断的。
 * 后台的预览框里会被降级成 absolute（见 .decor-preview-frame），同一份标记两边都能用。
 * z-index 压在侧边栏（100）和顶栏（50）之下，导航的观感不受影响。
 */
/*
 * 背景层和那层纱都在内容下面（z-index: -1）。
 *
 * 之前给的是 0 / 1，而卡片本身没有层级 —— 结果那层纱盖在了卡片上面，
 * 整页看起来像蒙了一层白雾（主播截图反馈过）。负数层级会被 .host-home
 * 的 stacking context 收在里面，既不会跑到页面背景之下，也保证压不到内容。
 */
.host-bg {
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
}

/*
 * 整页背景上盖的那层纱：不铺这层，内容直接压在照片上会看不清。
 * 颜色跟着主题走（浅色主题用暖白、深色主题用暗色），浓度由主播选的档位决定 ——
 * 所以 JS 只负责给 --page-veil-alpha，颜色和合成都留在 CSS 里。
 */
.host-bg-veil {
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background: rgba(var(--page-veil-rgb), var(--page-veil-alpha, 0.22));
}

/* 内容要浮在背景和纱上面 */
.host-home {
    position: relative;
    z-index: 2;
    /*
     * 立成一列，并吃掉 .viewer-body 里剩下的高度：内容不满一屏时，
     * 多出来的高度全落在 .host-footer 的 margin-top: auto 上，页脚
     * （左下文案 + 右下回到顶部）就贴到了页面底部，而不是吊在内容后面、
     * 下面空一大片（主播报过：功能入口卡下面一大片背景，字却浮在半空）。
     * 后台预览里父级是普通块级（.host-home-preview），这些按普通块算，
     * 预览量出来的还是页面本身的高度。
     */
    display: flex;
    flex-direction: column;
    flex: 1 0 auto;
}

.host-home-preview {
    display: block;
}

/*
 * 卡片一律保持不透明、清晰。
 *
 * 之前这里让卡片半透明加毛玻璃「让背景透出来」，但那会连带把卡片里的
 * 文字和图标一起弄糊，整页看着像蒙了一层雾 —— 主播明确反馈不要这个效果。
 * 现在背景只在卡片之间的缝隙里露出来，卡片本身该怎么清楚就怎么清楚。
 */

/*
 * 顶部留白。
 *
 * 以前这里是「封面」（自己画一层背景或渐变），现在背景统一铺满整页，
 * 这里就只剩「给浮在画面上的按钮让出位置」这一个作用了。
 */
.host-cover {
    height: 116px;
}

/*
 * 【Hero 封面区】
 *
 * 主页最上面那一整块「招牌」：封面带里坐着头像、名字、签名、胶囊和操作按钮，
 * 全部收在同一张卡里 —— 卡片的上半截和下半截不再是两种底色。
 *
 * 以前这里是一张白卡、头像从卡片顶部探出去，卡片高度完全跟着内容走 ——
 * 签名一短整块就矮，首屏下面只剩背景，看着空。
 *
 * 卡面交给封面带自己画，所以这里不铺底色：带子留了一点透明度，
 * 底下再垫一层白的话，整页背景就透不过来了。
 * overflow:hidden 是为了收住封面带的圆角。
 */
.host-hero {
    position: relative;
    /*
     * 左右不留边：招牌卡、状态卡、功能入口卡、页脚共用同一条左右边线。
     * 这里原来是 16px，比下面的入口卡缩进去一截，主播截图画线指出过。
     */
    margin: -52px 0 0;
    background: transparent;
    border: 1px solid var(--border-split);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
    overflow: hidden;
    /* 打开主页时和状态卡一起淡入上浮一次（跟入口卡同一套动作） */
    animation: entry-in 0.34s ease both;
}

/*
 * 封面带。
 *
 * 这张卡的上半截就是「招牌」本身：头像、名字、签名、胶囊都压在带子上，
 * 所以它不能是一条空横幅。
 *
 * 主播传了卡图就铺图（图上压一层左深右浅的暗色，白字才读得清，见 JS 的
 * coverStyle）；没传就用他自己的强调色铺满，再叠同款暗角 —— 深一点的底是
 * 白字的前提，也是这一块不再和整页背景糊成一片的原因。
 */
.host-hero-cover {
    position: relative;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 18px 20px;
    min-height: 172px;
    padding: 26px 24px;
    /* 没配封面图时就是这一层强调色。留一点透明度，整页背景能透出来一点 */
    background-color: var(--host-accent, var(--primary));
    background-color: color-mix(in srgb, var(--host-accent, var(--primary)) 88%, transparent);
    background-image: linear-gradient(135deg, rgba(255, 255, 255, 0.14) 0%, rgba(28, 14, 20, 0.36) 100%);
    background-size: cover;
    background-position: 50% 50%;
    background-repeat: no-repeat;
}

/*
 * 主播自己配了封面图时，带子不再留透明：图是实心的，留透明只会让边角
 * 透出背景，看着像没铺满；这里直接把底色收成不透明，图怎么来就怎么显示。
 */
.host-hero-cover.has-photo {
    background-color: var(--host-accent, var(--primary));
}

/*
 * 封面带上那层柔光：左上角一点高光，加一道斜向的浅光。
 * 只铺颜色的话，整条带子看着就是一张纯色卡纸；有了这层才有「面」的感觉。
 * 铺在 ::after 上，两种情况（强调色 / 主播自己配的图）都能用同一套光。
 */
.host-hero-cover::after {
    content: '';
    position: absolute;
    inset: 0;
    pointer-events: none;
    background:
        radial-gradient(120% 150% at 8% 6%, rgba(255, 255, 255, 0.20) 0%, rgba(255, 255, 255, 0) 54%),
        linear-gradient(112deg, rgba(255, 255, 255, 0.12) 0%, rgba(255, 255, 255, 0) 48%);
}

/* 在播时封面带右上角挂一个小标记，扫一眼就知道人在播 */
.host-live-flag {
    position: absolute;
    top: 12px;
    right: 12px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 26px;
    padding: 0 12px;
    border-radius: var(--radius-pill);
    background: rgba(20, 12, 16, 0.5);
    color: #fff;
    font-size: 12.5px;
}

/* 带子里、头像右边那块：名字、签名、胶囊，左对齐坐着 */
.host-hero-info {
    position: relative;
    z-index: 1;
    flex: 1;
    min-width: 0;
}

/*
 * 操作按钮就走封面带里，和头像、名字同一块。
 *
 * 以前它在带子下面那条白边上，换封面图时只换上半截，按钮还压在白色上，
 * 看着像两截拼起来的；现在它整块跟着带子走，背景一换就是一起换。
 */
.host-hero-cover .host-actions {
    position: relative;
    z-index: 1;
    flex: 0 0 auto;
    margin: 0;
    justify-content: flex-end;
}

/*
 * 【直播状态卡】
 *
 * 竖向三段：顶上一条「开播状态 + 一句小字（在播时报分区）」，中间整块直播间封面，
 * 底下直播间标题。在播时描一道强调色的边、状态标变红；没开播封面和标题照常
 * 显示（那是他的直播间，不是一条过期的动态），只是安静地待着。
 *
 * 封面用 flex:1 吃掉状态行和标题行之外的高度 —— 右边一列的高度是网格算出来的，
 * 封面跟着长，卡片就永远和左边那块投稿一样高。
 */
.live-card {
    display: flex;
    flex-direction: column;
    gap: clamp(10px, 0.9vw, 16px);
    /* 和招牌卡、功能入口卡同一条左右边线（同上） */
    margin: 12px 0 0;
    padding: 12px;
    /*
     * 留一点透明度：整页背景能透出来一点，卡片才像是「摆在这个背景上」的，
     * 而不是贴上去的一块白。只放 16%，字仍然压在接近实底的卡上，不会糊。
     */
    background: var(--bg-container);
    background: color-mix(in srgb, var(--bg-container) 84%, transparent);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    border: 1px solid var(--border-split);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
    /* 比 Hero 晚一点点进场，两块一前一后落下来 */
    animation: entry-in 0.34s ease 0.06s both;
}

.live-card.is-live {
    border-color: var(--host-accent, var(--primary));
}

/* 顶上那条：状态标 + 小字 + 在播时的入口按钮，一条排开 */
.live-status {
    display: flex;
    align-items: center;
    gap: clamp(8px, 0.7vw, 12px);
    min-width: 0;
}

/* 直播间封面：宽高比交给卡片，剩下的高度全归它，图自己裁满。
 * 万一没图，底下那层强调色浅底顶上，不会露出破图 */
.live-cover {
    position: relative;
    flex: 1;
    /* 右列两块天然高度顶不起左列时给一道底，封面不至于压成一条线 */
    min-height: clamp(96px, 9vw, 200px);
    border-radius: 10px;
    overflow: hidden;
    background-color: var(--bg-fill);
    background-image: linear-gradient(135deg,
        var(--host-accent-soft, var(--primary-soft)) 0%, var(--bg-fill) 100%);
    background-size: cover;
    background-position: 50% 50%;
    background-repeat: no-repeat;
}

/* 封面图：铺满整块，圆角交给外层 overflow:hidden 收。
 * 这里必须脱出文档流：封面高度是「卡片高度减掉状态行和标题」，图要是还在流里，
 * 就会按自己的原始比例（直播封面常见 4:3）把卡片撑高，左列投稿卡跟着被拉出一截空白 */
.live-cover-img {
    position: absolute;
    inset: 0;
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* 开播状态：排在卡片顶上。在播是红底，没开播是半透明黑底 */
.live-badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    flex: 0 0 auto;
    height: 22px;
    padding: 0 9px;
    border-radius: var(--radius-pill);
    background: rgba(20, 12, 16, 0.6);
    color: #fff;
    font-size: 11.5px;
    white-space: nowrap;
}

.live-badge.is-live {
    background: rgba(255, 77, 106, 0.94);
}

.live-badge .live-pulse {
    width: 7px;
    height: 7px;
}

/* 标题最多两行：直播间标题经常很长，一行放不下就截断，别把卡片撑变形 */
.live-title {
    font-size: 15px;
    font-weight: 600;
    color: var(--text);
    line-height: 1.5;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    word-break: break-word;
}

/* 状态行里那句小字：在播时报分区，没播时说明这块会亮。按内容占宽，长了省略号 */
.live-sub {
    min-width: 0;
    font-size: 12.5px;
    color: var(--text-3);
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

/* 入口按钮：紧跟在开播状态右边，不往卡片最右边推 */
.live-cta {
    flex: 0 0 auto;
}

/* 在播：默认那个绿点改成红色，才和「正在直播」这件事对得上 */
.live-card.is-live .live-pulse.on,
.live-badge.is-live .live-pulse.on {
    background: #ff4d6a;
    animation: liveDotPulse 1.8s ease-in-out infinite;
}

@keyframes liveDotPulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(255, 77, 106, 0.45); }
    50%      { box-shadow: 0 0 0 7px rgba(255, 77, 106, 0); }
}

/*
 * 【两列招牌区：最新投稿 + 直播状态 + 直播公告】
 *
 * 左边一整块是最新投稿，右边一列上面是直播状态、下面是直播公告。
 * 「右边两块加起来正好和左边一样高」不写死像素：左边跨两行、右边第一行自动
 * 吃满剩下的高度，行高由网格自己算 —— 换字号、公告长短都不一样，也不会错位。
 *
 * 投稿拉不到时后端会给空对象，前端给这块加 .no-video：右边那一列退回通栏，
 * 页面就是老的「直播状态 + 公告」竖着排。
 */
.host-showcase {
    display: grid;
    /* 左边略宽：投稿是主角，右边两块是陪衬 */
    grid-template-columns: minmax(0, 1.42fr) minmax(0, 1fr);
    grid-template-rows: 1fr auto;
    gap: clamp(14px, 1.1vw, 22px);
    /* 和招牌卡、功能入口卡同一条左右边线（同上） */
    margin: 12px 0 0;
    align-items: stretch;
}

.host-showcase .video-card {
    grid-column: 1;
    grid-row: 1 / span 2;
}

/* 边距交给网格的 gap，卡片自己不留，否则两列对不上 */
.host-showcase .live-card {
    grid-column: 2;
    grid-row: 1;
    margin: 0;
}

.host-showcase .notice-card {
    grid-column: 2;
    grid-row: 2;
}

/*
 * 直播状态卡分三段：状态行贴顶、直播间标题贴底、封面把中间整块吃满。
 * 封面自己不再设高度上限 —— 它的上限就是卡片高度，而卡片高度由左列投稿卡决定，
 * 所以两列永远等高，封面下面也不会留出一块空。
 */
.host-showcase .live-card {
    justify-content: space-between;
}

/*
 * 投稿或公告拿不到时（服务端还没配 B站 登录、接口抽风）也要把各自的格子占住：
 * 只把内容换成一句提示，位置绝不让给隔壁的直播状态卡，否则整块比例就变了。
 */
.video-card-empty {
    gap: 0;
    /* 右列两块的天然高度顶不起左列，这里给一道底，两列比例不至于塌 */
    min-height: clamp(220px, 22vw, 420px);
    padding: clamp(14px, 1.05vw, 22px) clamp(16px, 1.2vw, 26px) clamp(16px, 1.2vw, 24px);
}

/* 占位卡不可点，鼠标划过就别抬了 */
.video-card-empty:hover {
    transform: none;
    box-shadow: var(--shadow);
}

/* 标题留在顶上（和真卡一样的位置），提示文字在剩下的空间里居中 */
.video-empty {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: clamp(13.5px, 0.88vw, 16px);
    color: var(--text-3);
    text-align: center;
}

.notice-card-empty {
    color: var(--text-3);
}

/* 【最新投稿卡】封面在上、文字在下，整块可点 */
.video-card {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    text-decoration: none;
    color: inherit;
    /* 和直播状态卡同一套玻璃底：整页背景透一点出来 */
    background: var(--bg-container);
    background: color-mix(in srgb, var(--bg-container) 84%, transparent);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    border: 1px solid var(--border-split);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
    animation: entry-in 0.34s ease 0.06s both;
    transition: transform 0.18s ease, box-shadow 0.18s ease;
}

.video-card:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-lg);
}

/*
 * 封面铺满卡片宽度，高度写死一档、跟着视口放大。
 *
 * 以前这里是「16:9 + max-height 封顶」：视觉上高度是封住了，可 16:9 算出来的
 * 高度仍然要算进网格的行高里，左列被顶得比「封面 + 文字」高一大截，标题下面
 * 留一大片白（主播反馈过）。改成写死一档之后，卡片高度就是封面加文字，
 * 右列两块的天然高度撑得起，两列才都刚好贴住内容。
 */
.video-cover {
    position: relative;
    display: block;
    width: 100%;
    height: clamp(170px, 22vw, 420px);
    overflow: hidden;
    background-color: var(--bg-fill);
    background-image: linear-gradient(135deg,
        var(--host-accent-soft, var(--primary-soft)) 0%, var(--bg-fill) 100%);
}

.video-cover img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* 没封面图时这里顶一块：一个播放标记，不至于开天窗 */
.video-cover-fallback {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--host-accent, var(--primary));
    opacity: 0.55;
}

/* 时长压在封面右下角 */
.video-length {
    position: absolute;
    right: 8px;
    bottom: 8px;
    height: 20px;
    padding: 0 8px;
    display: inline-flex;
    align-items: center;
    border-radius: var(--radius-pill);
    background: rgba(0, 0, 0, 0.62);
    color: #fff;
    font-size: clamp(11.5px, 0.72vw, 13px);
    font-variant-numeric: tabular-nums;
}

.video-body {
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: 0;
    padding: clamp(14px, 1.05vw, 22px) clamp(16px, 1.2vw, 26px) clamp(16px, 1.2vw, 24px);
}

.video-label {
    font-size: clamp(12px, 0.78vw, 13.5px);
    letter-spacing: 0.04em;
    color: var(--text-3);
}

.video-title {
    font-size: clamp(15px, 1vw, 20px);
    font-weight: 600;
    line-height: 1.5;
    color: var(--text-1);
    /* 投稿标题有时候很长，最多两行，超出省略 */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.video-meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    font-size: clamp(12.5px, 0.82vw, 14.5px);
    color: var(--text-3);
}

.video-go {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    white-space: nowrap;
    color: var(--host-accent, var(--primary));
}

/* 【直播公告】主播在 B站 直播间写的那段，纯文本、换行原样保留 */
.notice-card {
    display: flex;
    flex-direction: column;
    gap: 8px;
    min-height: 0;
    padding: clamp(14px, 1.05vw, 22px) clamp(16px, 1.2vw, 24px);
    background: var(--bg-container);
    background: color-mix(in srgb, var(--bg-container) 84%, transparent);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    border: 1px solid var(--border-split);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
    animation: entry-in 0.34s ease 0.06s both;
}

.notice-card-label {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: clamp(12px, 0.78vw, 13.5px);
    letter-spacing: 0.04em;
    color: var(--text-3);
}

.notice-card-text {
    font-size: clamp(13.5px, 0.88vw, 16px);
    line-height: 1.75;
    color: var(--text-2);
    /* 公告是纯文本，换行原样留 */
    white-space: pre-line;
    word-break: break-word;
    /* 写太长的公告不把这一列撑破，超出在卡里滚 */
    max-height: clamp(180px, 14vw, 320px);
    overflow: auto;
}

/*
 * 窄屏：两列并排已经放不下了，退回一列竖着排（投稿、直播状态、公告）。
 * 顺序就是 DOM 顺序，不用额外写 order。
 */
@media (max-width: 900px) {
    .host-showcase {
        grid-template-columns: minmax(0, 1fr);
    }

    .host-showcase .video-card,
    .host-showcase .live-card,
    .host-showcase .notice-card {
        grid-column: 1;
        grid-row: auto;
    }

    /* 单列时卡片高度由内容定，封面不再有剩余高度可吃，改成一条固定高度的横幅 */
    .host-showcase .live-cover {
        flex: 0 0 auto;
        height: clamp(150px, 30vw, 280px);
        min-height: 0;
    }
}

/*
 * 头像整个待在封面带里。
 *
 * 以前它靠负边距「骑」在卡片上沿，一半在带子里、一半在白卡上；带子一旦是
 * 定位元素就会把静态的头像盖掉上半截。现在不给它跨界的余地。
 */
.host-avatar {
    position: relative;
    z-index: 1;
    flex: 0 0 auto;
    width: 92px;
    height: 92px;
    margin: 0;
    border-radius: 50%;
    object-fit: cover;
    display: block;
    background: rgba(255, 255, 255, 0.22);
    /* 一圈很淡的白边 + 一道更细的外环：贴着带子，而不是贴上去的贴纸 */
    border: 2px solid rgba(255, 255, 255, 0.55);
    box-shadow:
        0 10px 24px rgba(58, 22, 38, 0.30),
        0 0 0 1px rgba(255, 255, 255, 0.30);
}

.host-name {
    font-size: 21px;
    font-weight: 700;
    letter-spacing: -0.2px;
    color: #fff;
    /* 图上没有纯色底，名字压一层极淡的投影才稳 */
    text-shadow: 0 1px 3px rgba(56, 22, 36, 0.35);
    margin-bottom: 6px;
    word-break: break-all;
}

.host-bio {
    font-size: 13px;
    color: rgba(255, 255, 255, 0.88);
    line-height: 1.6;
    max-width: 560px;
    margin: 0 0 12px;
    word-break: break-word;
    /* 签名最多两行：带子高度是固定的，长签名不能把它顶开 */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/*
 * 数据胶囊（粉丝数 / 直播间号 / 功能数）是参考信息，不是操作。
 * 调小、调淡、去掉边框感，让它们在视觉上退到名字和签名后面。
 */
.host-meta .host-pill {
    font-size: 12px;
    padding: 2px 9px;
    color: var(--text-3);
}

.host-meta .host-pill .y-icon {
    opacity: 0.75;
}

/* 带子上的胶囊：半透明白底白字，压在封面图或强调色上都读得清 */
.host-hero-cover .host-pill {
    background: rgba(255, 255, 255, 0.18);
    color: #fff;
}

.host-hero-cover .host-pill .y-icon {
    opacity: 0.9;
}

/* 在播标记里的点用红的，和下面状态卡保持一致（默认那个绿点是留给他处的） */
.host-live-flag .live-pulse.on {
    background: #ff4d6a;
}

/* 操作区：招牌卡右下的按钮组（进直播间的入口只留状态卡那一个，这里没有主操作了） */
.host-actions {
    margin-top: var(--sp-4);
    gap: var(--sp-2);
}

/* 按钮挪到卡片下半截后，外面上边距不用了（那里靠分隔线和内边距撑开） */
.host-hero-body .host-actions {
    margin-top: 0;
}

.host-meta {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    /* 胶囊跟着名字左对齐坐在封面带上，不再居中 */
    justify-content: flex-start;
    margin-bottom: 0;
}

/* 数据胶囊 */
.host-pill {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    height: 26px;
    padding: 0 12px;
    border-radius: var(--radius-pill);
    background: var(--bg-fill);
    color: var(--text-2);
    font-size: 12.5px;
    white-space: nowrap;
}

.host-actions {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    justify-content: center;
}

/*
 * 【页脚】
 *
 * 整页的收尾。以前最后一张入口卡之后就直接没了，一大片背景空在那里，
 * 页面看着像没画完；现在收一条很低调的线：左边一行字，右边回到顶部。
 */
.host-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    /*
     * 上边距用 auto：父级 .host-home 是纵向列，多出来的高度全落在这里，
     * 于是内容不满一屏时页脚贴到视口底部。内容超过一屏时 auto 按 0 算，
     * 由 padding-top 保住原来的 24px 间距；后台预览里父级是普通块级
     * （.host-home-preview），auto 也是 0，和以前一样跟在内容后面。
     *
     * 左右也不留边：页脚左边缘要跟功能入口卡对齐，同一页只有一条左边线。
     */
    margin: auto 0 8px;
    padding-top: 24px;
    font-size: 12.5px;
    color: var(--text-3);
}

/*
 * 页脚要贴到视口底部：容器自己的下留白收掉，
 * 只留这 8px + 容器的 16px。原来 32 + 48 = 80px，主播说「不够底部」。
 */
.viewer-body:has(.host-home) {
    padding-bottom: 16px;
}

.layout.immersive .content:has(.host-home) {
    padding-bottom: 16px;
}

.host-footer-text {
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

/* ============================================================
   备案号（页脚）
   ------------------------------------------------------------
   工信部 ICP 备案号和公安联网备案号要做到两件事才合规：
   号码写标准格式、可点击跳到官方系统。样式上就按页脚那种
   很轻的辅助文字做：小字号、次要颜色，不抢内容。
   ============================================================ */

.filing {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 4px 8px;
    font-size: 12.5px;
    line-height: 1.6;
    color: var(--text-3);
}

/* 页脚是左右布局时，备案号靠右、跟左边那行字对齐基线 */
.host-footer .filing {
    justify-content: flex-end;
    gap: 0 8px;
}

.filing-item {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    color: var(--text-3);
    text-decoration: none;
    transition: color .15s;
}

.filing-item:hover {
    color: var(--text-1);
    text-decoration: underline;
}

/* 公安备案号前面那个盾牌图标，跟着文字颜色走 */
.filing-item .y-icon {
    flex: none;
    opacity: .8;
}

.filing-sep {
    color: var(--text-3);
    opacity: .5;
}

/* 后台弹窗里的预览区：把页脚那块原样摆出来看效果 */
.filing-editor .field-hint {
    margin-top: 8px;
}

.filing-preview-label {
    margin: 16px 0 8px;
    font-size: 12.5px;
    color: var(--text-3);
}

.filing-preview {
    padding: 14px 12px;
    border: 1px dashed var(--border);
    border-radius: var(--radius);
    background: var(--bg-2);
    transition: opacity .15s;
}

/* 还没填成标准写法：压淡，提示「这样挂上去不对」但不打断输入 */
.filing-preview.is-dim {
    opacity: .45;
}

.filing-empty {
    display: block;
    text-align: center;
    font-size: 12.5px;
    color: var(--text-3);
}

/*
 * 没有自己页脚的页面（组件独立页、粉丝中心），备案号跟在内容后面。
 *
 * 这两处的父容器都是纵向 flex（.content / .plugin-page），所以用 margin-top: auto
 * 把备案号顶到可视区最底边 —— 内容不满一屏时它贴着底部，内容超出一屏时它仍在内容末尾。
 * 光写 margin-top: 24px 会出现「内容很短、备案号悬在页面中间、下面一大片空白」的样子。
 */
.plugin-page-filing,
.filing-wrap.fan-filing {
    margin-top: auto;
    padding-top: 24px;
}

.filing-wrap.fan-filing {
    padding-bottom: 8px;
}

.filing-wrap.sl-filing {
    margin-top: 18px;
}

/*
 * 【回到顶部】
 *
 * 以前它是页脚里的一颗小按钮，站在内容末尾 —— 只有正好停在页面底部才看得到，
 * 想用的时候多半已经滚过去了。改成浮在右下角，滚过一屏再出现（见 views.js 的 showTop）。
 */
.to-top {
    position: fixed;
    right: var(--viewer-gutter);
    bottom: 20px;
    z-index: 60;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    height: 36px;
    padding: 0 14px;
    border: 1px solid var(--float-border);
    border-radius: var(--radius-pill);
    background: var(--float-bg);
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
    box-shadow: var(--float-shadow);
    color: var(--text-2);
    font-size: 12.5px;
    font-family: inherit;
    cursor: pointer;
    transition: all var(--transition);
}

.to-top:hover {
    color: var(--host-accent, var(--primary));
    border-color: var(--host-accent, var(--primary));
}

/*
 * 【首屏骨架】
 *
 * 按 Hero、状态卡、功能入口的形状各摆一块，底子用现成的 .skeleton（带 shimmer）。
 * 以前这里只有三行通用灰条，跟现在的结构对不上，页面会先闪一下再拼回来。
 */
.host-skeleton-cover {
    height: 176px;
    margin: -52px 0 0;
    border-radius: var(--radius-lg);
}

/* 骨架跟着真结构走：左边一块大的（投稿），右边上下两块（状态、公告） */
.host-skeleton-showcase {
    display: grid;
    grid-template-columns: minmax(0, 1.42fr) minmax(0, 1fr);
    grid-template-rows: 1fr auto;
    gap: clamp(14px, 1.1vw, 22px);
    margin: 12px 0 0;
}

.host-skeleton-video {
    grid-column: 1;
    grid-row: 1 / span 2;
    min-height: clamp(220px, 22vw, 420px);
    border-radius: var(--radius-lg);
}

.host-skeleton-live {
    grid-column: 2;
    grid-row: 1;
    border-radius: var(--radius-lg);
}

.host-skeleton-notice {
    grid-column: 2;
    grid-row: 2;
    height: 96px;
    border-radius: var(--radius-lg);
}

.host-skeleton-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 14px;
    margin: 40px 0 0;
}

.host-skeleton-tile {
    height: 84px;
    border-radius: var(--radius-lg);
}

@media (max-width: 640px) {
    /*
     * 手机上顶部留白要高一些：屏幕窄，浮动的主播切换器会横向铺开，
     * 和封面带撞在一起。留够一条带子（14+38+一点余量）就错开了。
     *
     * 左右边距一律交给 .viewer-body 的内边距（这里已经收到 12px），
     * 自己再加 10px 就会比功能入口那排卡片缩进去一截、两边对不齐。
     */
    .host-cover { height: 148px; }
    .host-hero { margin: -46px 0 0; }
    .host-hero-cover { min-height: 148px; padding: 20px 16px; gap: 14px; }
    /* 窄屏放不下「头像 + 资料 + 一排按钮」，按钮另起一行顶格排 */
    .host-hero-cover .host-actions { flex-basis: 100%; justify-content: flex-start; }
    .host-avatar { width: 76px; height: 76px; }
    .host-name { font-size: 18px; }
    .host-bio { font-size: 12.5px; margin-bottom: 10px; }
    .host-showcase { margin: 10px 0 0; }
    .live-card { margin: 10px 0 0; padding: 10px; gap: 9px; }
    /* 两列区里的直播卡不该再吃那 10px：间距由网格的 gap 给 */
    .host-showcase .live-card { margin: 0; }
    .host-showcase .live-cover { height: 140px; }
    .live-title { font-size: 14px; }
    .live-badge { height: 20px; padding: 0 8px; font-size: 11px; }
    /* 手机上把「进入直播间」收成只剩图标，标题才有一行的宽度 */
    .live-cta { padding-left: 10px; padding-right: 10px; }
    .live-cta .live-cta-text { display: none; }
    /* 手机上一屏窄，封面按视口算已经收得够小（clamp 的下限就是给窄屏的） */
    .host-footer { margin: auto 0 26px; }
    .host-skeleton-cover { height: 148px; margin: -46px 0 0; }
    .host-skeleton-showcase { grid-template-columns: minmax(0, 1fr); gap: 10px; }
    .host-skeleton-video { grid-row: auto; min-height: 180px; }
    .host-skeleton-live { grid-column: 1; grid-row: auto; height: 88px; }
    .host-skeleton-notice { grid-column: 1; grid-row: auto; height: 72px; }
    .host-skeleton-grid { margin: 34px 0 0; }
}

.entry-grid {
    display: grid;
    /*
     * auto-fit 而不是 auto-fill：宽屏下一行能放下 4 列时，只有 3 张功能卡
     * 会留下一个空轨道，右边照样空一块；auto-fit 会把空轨道收掉，卡片自己
     * 铺满整行。
     */
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 14px;
}

/* 大小：小 = 一排放得下更多，大 = 一屏就两三张，像海报一样 */
.entry-grid.size-sm {
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 10px;
}

.entry-grid.size-lg {
    grid-template-columns: repeat(auto-fill, minmax(360px, 1fr));
    gap: 16px;
}

/* 图标块跟着档位走：小的收一点、大的放一点，卡片才不会头重脚轻 */
.entry-grid.size-sm .entry-icon,
.entry-grid.size-sm .entry-thumb {
    width: 44px;
    height: 44px;
    border-radius: 14px;
}

.entry-grid.size-lg .entry-icon,
.entry-grid.size-lg .entry-thumb {
    width: 62px;
    height: 62px;
    border-radius: 18px;
}

/* 布局：单列通栏，一行一个 */
.entry-grid.layout-list {
    grid-template-columns: 1fr;
    gap: var(--sp-3);
}

/*
 * 单列通栏要单独排版。
 *
 * 之前它跟网格布局共用一套：左边一个小图标、右边一大片空白、描述还被截断，
 * 卡片又高又松。通栏的特点是横向空间富裕，所以改成「图在左、文字在中、箭头贴右」，
 * 描述只留一行，高度压下来。
 */
.entry-grid.layout-list .entry-card {
    padding: var(--sp-3) var(--sp-4);
    min-height: 0;
    gap: var(--sp-4);
}

/* 通栏时配图做成长条，比正方形更贴横向的版面 */
.entry-grid.layout-list .entry-card.has-image {
    min-height: 96px;
}

.entry-grid.layout-list .entry-cover {
    left: 0;
    width: 168px;
    height: 100%;
    right: auto;
    inset: 0 auto 0 0;
}

/* 图在左，文字就整体右移，压在图上会读不清 */
.entry-grid.layout-list .entry-card.has-image .entry-body,
.entry-grid.layout-list .entry-card.has-image .entry-arrow {
    margin-left: 168px;
}

.entry-grid.layout-list .entry-icon,
.entry-grid.layout-list .entry-thumb {
    width: 48px;
    height: 48px;
}

.entry-grid.layout-list .entry-body {
    flex-direction: row;
    align-items: baseline;
    gap: var(--sp-3);
    min-width: 0;
}

.entry-grid.layout-list .entry-title {
    flex-shrink: 0;
}

/* 描述只留一行：通栏本来就宽，两行会把卡片顶高 */
.entry-grid.layout-list .entry-desc {
    -webkit-line-clamp: 1;
    line-clamp: 1;
}

@media (max-width: 640px) {
    /* 手机上横向空间不够，图缩窄一点 */
    .entry-grid.layout-list .entry-cover {
        width: 104px;
    }

    .entry-grid.layout-list .entry-card.has-image .entry-body,
    .entry-grid.layout-list .entry-card.has-image .entry-arrow {
        margin-left: 104px;
    }

    .entry-grid.layout-list .entry-body {
        flex-direction: column;
        align-items: flex-start;
        gap: 2px;
    }

    .entry-grid.layout-list .entry-desc {
        -webkit-line-clamp: 2;
        line-clamp: 2;
    }
}

/* 布局：双列。不看屏幕宽度，固定两列，适合「就想整齐排两行」的主播 */
.entry-grid.layout-duo {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--sp-3);
}

/* 布局：横向一排。放不下就左右滑，一屏永远是齐平的一行 */
.entry-grid.layout-row {
    display: flex;
    gap: var(--sp-3);
    overflow-x: auto;
    padding-bottom: 6px;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
}

.entry-grid.layout-row .entry-card {
    flex: 0 0 268px;
    scroll-snap-align: start;
}

/*
 * 布局：图标墙。只留图标和名字，卡片缩成小方块，
 * 组件多的时候一眼能扫完；配了图的卡片就只显示图。
 */
.entry-grid.layout-icons {
    grid-template-columns: repeat(auto-fill, minmax(124px, 1fr));
    gap: var(--sp-3);
}

.entry-grid.layout-icons .entry-card {
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 10px;
    padding: 18px 12px;
}

.entry-grid.layout-icons .entry-icon,
.entry-grid.layout-icons .entry-thumb {
    width: 50px;
    height: 50px;
    border-radius: 16px;
}

.entry-grid.layout-icons .entry-title {
    font-size: 13.5px;
    font-weight: 500;
}

/* 小方块里放不下描述和箭头，直接收掉，别挤成一团 */
.entry-grid.layout-icons .entry-desc,
.entry-grid.layout-icons .entry-arrow {
    display: none;
}

.entry-grid.layout-icons .entry-card.has-image {
    min-height: 104px;
    padding: 12px;
}

.entry-grid.layout-icons .entry-card.has-image .entry-body {
    display: none;
}

/*
 * 布局：一大多小。第一张占两行两列当主推，其余照常排。
 * 第一张里图标也放大，中间留白靠 justify-content 顶到底部。
 */
.entry-grid.layout-hero {
    grid-template-columns: repeat(auto-fill, minmax(232px, 1fr));
    gap: var(--sp-3);
}

.entry-grid.layout-hero .entry-card:first-child {
    grid-column: span 2;
    grid-row: span 2;
    min-height: 172px;
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-end;
    gap: 14px;
    padding: 22px;
}

.entry-grid.layout-hero .entry-card:first-child .entry-icon,
.entry-grid.layout-hero .entry-card:first-child .entry-thumb {
    width: 64px;
    height: 64px;
    border-radius: 20px;
}

.entry-grid.layout-hero .entry-card:first-child .entry-title {
    font-size: 19px;
}

.entry-grid.layout-hero .entry-card:first-child .entry-desc {
    font-size: 13px;
    -webkit-line-clamp: 2;
    line-clamp: 2;
}

@media (max-width: 640px) {
    /* 窄屏放不下两列和「一大两小」，都退回普通平铺，别硬挤 */
    .entry-grid.layout-duo {
        grid-template-columns: 1fr;
    }

    .entry-grid.layout-hero {
        grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    }

    .entry-grid.layout-hero .entry-card:first-child {
        grid-column: auto;
        grid-row: auto;
        min-height: 148px;
        padding: 18px;
    }

    .entry-grid.layout-hero .entry-card:first-child .entry-icon,
    .entry-grid.layout-hero .entry-card:first-child .entry-thumb {
        width: 54px;
        height: 54px;
        border-radius: 16px;
    }

    .entry-grid.layout-hero .entry-card:first-child .entry-title {
        font-size: 16px;
    }

    .entry-grid.layout-row .entry-card {
        flex-basis: 224px;
    }

    .entry-grid.layout-icons {
        grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
    }
}

/*
 * 入场：卡片依次淡入上浮。
 * 只做一次、每个错开 40ms（延迟由模板按序号给），再多就晃眼了。
 */
@keyframes entry-in {
    from { opacity: 0; transform: translateY(8px); }
    to { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
    .entry-card {
        animation: none !important;
    }
}

/*
 * 功能入口卡。
 *
 * 升级点（2026-10 美化工单）：图标块放大到 54、标题加粗半号、描述行高放开，
 * 箭头从「一个灰三角」换成一颗圆形底的小棋子；鼠标移上去时卡片左边
 * 亮起一道强调色的竖条。都是纯样式，不加任何数据。
 */
.entry-card {
    animation: entry-in 0.32s ease both;
    position: relative;
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 18px 20px;
    background: var(--bg-container);
    border: 1px solid var(--border-split);
    border-radius: var(--radius-lg);
    cursor: pointer;
    text-align: left;
    font-family: inherit;
    overflow: hidden;
    transition: all var(--transition);
}

/* 和状态卡一样留一点透明度；整张都是配图的卡片不算（图本身就是底色） */
.entry-card:not(.has-image) {
    background: color-mix(in srgb, var(--bg-container) 84%, transparent);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
}

/* 卡片左侧的强调色竖条：平时不在，移上去才亮 —— 有指向感又不吵。
   配了图的卡片整张都是图，这条竖条就不加了。 */
.entry-card:not(.has-image)::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 3px;
    background: var(--host-accent, var(--primary));
    opacity: 0;
    transition: opacity var(--transition);
}

.entry-card:hover::before {
    opacity: 1;
}

.entry-card:hover {
    border-color: var(--host-accent, var(--primary));
    box-shadow: var(--shadow);
    transform: translateY(-2px);
}

.entry-card:active {
    transform: translateY(0);
}

.entry-card:hover .entry-arrow {
    color: var(--host-accent, var(--primary));
    transform: translateX(3px);
}

.entry-card:hover .entry-icon {
    transform: scale(1.06);
}

.entry-icon {
    width: 54px;
    height: 54px;
    border-radius: 16px;
    background: var(--host-accent-soft, var(--primary-soft));
    color: var(--host-accent, var(--primary));
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    transition: transform var(--transition);
}

/* 一排入口卡片之间换个色调，不至于寡淡。
   颜色按组件 id 自动分配（Yuri.tintOf），所以新加组件不用回来改这里 —— 
   只要保证下面这几号色都齐着就行。 */
.entry-icon.tint-1 { background: #fff1e6; color: #f08a4b; }
.entry-icon.tint-2 { background: #f0f7ff; color: #5b9bd5; }
.entry-icon.tint-0 { background: var(--primary-soft); color: var(--primary); }
.entry-icon.tint-3 { background: #eaf7f0; color: #43997a; }
.entry-icon.tint-4 { background: #f3eeff; color: #8571d4; }
.entry-icon.tint-5 { background: #fff8e2; color: #c9973a; }

/* 主播给这个组件配了图：占掉图标那个位置，尺寸和图标对齐，卡片高度不会因此变化 */
.entry-thumb {
    width: 54px;
    height: 54px;
    border-radius: 16px;
    object-fit: cover;
    flex-shrink: 0;
    transition: transform var(--transition);
}

.entry-card:hover .entry-thumb {
    transform: scale(1.06);
}

/* ------------------------------------------------------------------
 * 配了图的组件卡：整张卡片用图片打底，文字浮在图上
 *
 * 图片是绝对定位铺满整卡的，卡片自己 overflow:hidden 收掉圆角外的部分。
 * 文字下面压一层由下往上的渐变，不然浅色照片上的白字根本读不出来。
 * ------------------------------------------------------------------ */
.entry-card.has-image {
    position: relative;
    display: flex;
    align-items: flex-end;
    min-height: 148px;
    padding: 16px 18px;
    border-color: transparent;
    overflow: hidden;
    color: #fff;
}

.entry-card.has-image.size-md {
    min-height: 148px;
}

.entry-grid.size-sm .entry-card.has-image {
    min-height: 118px;
}

.entry-grid.size-lg .entry-card.has-image {
    min-height: 200px;
}

.entry-cover {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.4s ease;
}

.entry-card.has-image:hover .entry-cover {
    transform: scale(1.05);
}

/* 渐变蒙层：覆盖整张图，越往下越暗，保证底部的标题读得清 */
.entry-card.has-image::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(to top,
        rgba(20, 12, 16, 0.72) 0%,
        rgba(20, 12, 16, 0.34) 38%,
        rgba(20, 12, 16, 0) 72%);
    pointer-events: none;
}

.entry-card.has-image .entry-body,
.entry-card.has-image .entry-arrow {
    position: relative;
    z-index: 1;
}

.entry-card.has-image .entry-title {
    color: #fff;
    font-size: 16px;
    font-weight: 600;
    text-shadow: 0 1px 6px rgba(0, 0, 0, 0.45);
}

.entry-card.has-image .entry-desc {
    color: rgba(255, 255, 255, 0.88);
    text-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
}

.entry-card.has-image .entry-arrow {
    color: rgba(255, 255, 255, 0.9);
}

.entry-card.has-image:hover .entry-arrow {
    color: #fff;
}

[data-theme='dark'] .entry-icon.tint-1 { background: #3a2a1e; color: #ffab70; }
[data-theme='dark'] .entry-icon.tint-2 { background: #1e2a3a; color: #7fb4e8; }
[data-theme='dark'] .entry-icon.tint-3 { background: #1c332a; color: #6fc9a2; }
[data-theme='dark'] .entry-icon.tint-4 { background: #2b2440; color: #ac9bf0; }
[data-theme='dark'] .entry-icon.tint-5 { background: #3a3220; color: #e0bd63; }

.entry-body {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 3px;
}

.entry-title {
    font-size: 16px;
    font-weight: 600;
    color: var(--text);
}

.entry-desc {
    font-size: 12.5px;
    color: var(--text-3);
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    line-height: 1.55;
}

/* 箭头棋子：一颗圆形底的 chevron，移上去时染成强调色 */
.entry-arrow {
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: var(--bg-fill);
    color: var(--text-4);
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all var(--transition);
}

.entry-card:hover .entry-arrow {
    background: var(--host-accent-soft, var(--primary-soft));
}

/* 组件整页 */
.plugin-page {
    min-height: 200px;
}

.plugin-page-head {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 18px;
    flex-wrap: wrap;
}

/*
 * 沉浸模式下（粉丝端看主播）顶部要留出浮动控件那条带子，
 * 否则标题会被那组按钮压住。留白高度和主页一致，两边的节奏才对得上。
 */
.layout.immersive .plugin-page-head {
    padding-top: var(--float-band);
    margin-bottom: var(--sp-4);
}

.plugin-page-title {
    font-size: 18px;
    font-weight: 600;
    color: var(--text);
    display: flex;
    align-items: baseline;
    gap: var(--sp-2);
    flex-wrap: wrap;
}

/* 返回按钮 */
.back-link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 32px;
    padding: 0 12px 0 8px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--bg-container);
    color: var(--text-2);
    font-size: 14px;
    font-family: inherit;
    cursor: pointer;
    transition: all var(--transition);
}

.back-link:hover {
    border-color: var(--primary);
    color: var(--primary);
}

/* 主播列表卡片（会员中心主页） */
.host-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 12px;
}

.host-list-item {
    display: flex;
    align-items: center;
    gap: 13px;
    padding: 15px 16px;
    background: var(--bg-container);
    border: 1px solid var(--border-split);
    border-radius: var(--radius-lg);
    transition: all var(--transition);
}

.host-list-item:hover {
    border-color: var(--primary);
    box-shadow: var(--shadow-sm);
}

.host-list-item.current {
    border-color: var(--primary);
    background: var(--primary-soft);
}

.host-list-body {
    flex: 1;
    min-width: 0;
    cursor: pointer;
}

.host-list-name {
    font-size: 14px;
    font-weight: 500;
    margin-bottom: 2px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.host-list-sub {
    font-size: 12px;
    color: var(--text-3);
}

/* ---------- 19. 歌单组件 ---------- */
.song-toolbar {
    display: flex;
    gap: 10px;
    align-items: center;
    flex-wrap: wrap;
    margin-bottom: 14px;
}

.toolbar-sort {
    width: 130px;
}

.song-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.song-item {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 14px 18px;
    background: var(--bg-container);
    border: 1px solid var(--border-split);
    border-radius: var(--radius-lg);
    cursor: pointer;
    transition: all var(--transition);
}

.song-item:hover {
    border-color: var(--primary);
    background: var(--primary-soft);
}

.song-item.copied {
    border-color: var(--success);
    background: var(--success-soft);
}

.song-main {
    flex: 1;
    min-width: 0;
}

.song-name {
    font-size: 14px;
    font-weight: 500;
    margin-bottom: 4px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.song-meta {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    font-size: 12px;
    color: var(--text-3);
}

.song-remark {
    font-size: 12px;
    color: var(--text-3);
    margin-top: 4px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.song-action {
    flex-shrink: 0;
    font-size: 12px;
    color: var(--text-4);
}

.song-item:hover .song-action {
    color: var(--primary);
}

.song-footer {
    text-align: center;
    margin-top: 16px;
    font-size: 12px;
    color: var(--text-3);
}

/* 歌单后台 */
.add-form {
    display: grid;
    grid-template-columns: 1.4fr 1fr 0.8fr 0.9fr 1.4fr auto;
    gap: 8px;
    padding-top: 16px;
    margin-top: 16px;
    border-top: 1px solid var(--border-split);
}

@media (max-width: 1100px) {
    .add-form { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 640px) {
    .add-form { grid-template-columns: 1fr; }
}

.import-panel {
    padding-top: 16px;
    margin-top: 16px;
    border-top: 1px solid var(--border-split);
}

.import-tip {
    background: var(--bg-fill);
    border-radius: var(--radius);
    padding: 14px 16px;
    font-size: 13px;
    line-height: 1.8;
    color: var(--text-2);
    margin-bottom: 14px;
}

.import-tip strong {
    display: block;
    color: var(--text);
    margin-bottom: 6px;
    font-weight: 600;
}

.import-tip ul {
    margin-left: 18px;
}

.import-tip code {
    background: var(--bg-container);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 1px 6px;
    font-family: var(--font-mono);
    font-size: 12px;
}

.file-drop {
    border: 1px dashed var(--primary-border);
    border-radius: var(--radius);
    padding: 24px;
    text-align: center;
    background: var(--primary-soft);
    cursor: pointer;
    transition: all var(--transition);
}

.file-drop:hover {
    border-color: var(--primary);
}

.file-drop-text {
    font-size: 14px;
    color: var(--primary);
    word-break: break-all;
}

/* ---------- 20. 舰礼组件 ---------- */
.monitor-bar {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    padding: 14px 18px;
    background: var(--bg-container);
    border: 1px solid var(--border-split);
    border-radius: var(--radius-lg);
    margin-bottom: 16px;
}

.monitor-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex-shrink: 0;
    background: var(--text-4);
}

.monitor-dot.on { background: var(--success); }
.monitor-dot.warn { background: var(--warning); }
.monitor-dot.off { background: var(--error); }

.guard-record {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 14px 18px;
    background: var(--bg-container);
    border: 1px solid var(--border-split);
    border-radius: var(--radius-lg);
}

.guard-record-main {
    flex: 1;
    min-width: 0;
}

.guard-record-name {
    font-size: 14px;
    font-weight: 500;
    margin-bottom: 4px;
}

.guard-record-meta {
    display: flex;
    gap: 14px;
    flex-wrap: wrap;
    font-size: 12px;
    color: var(--text-3);
}

/* ---------- 21. 棉花糖组件 ---------- */
.marshmallow-card {
    background: var(--bg-container);
    border: 1px solid var(--border-split);
    border-radius: var(--radius-lg);
    padding: 18px 20px;
}

.marshmallow-card.unread {
    border-left: 3px solid var(--primary);
}

.marshmallow-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 10px;
}

.marshmallow-content {
    font-size: 14px;
    line-height: 1.8;
    color: var(--text);
    white-space: pre-wrap;
    word-break: break-word;
}

.marshmallow-reply {
    margin-top: 14px;
    padding: 12px 16px;
    background: var(--primary-soft);
    border-radius: var(--radius);
    font-size: 13px;
    line-height: 1.75;
    white-space: pre-wrap;
    word-break: break-word;
    color: var(--text-2);
}

.marshmallow-reply::before {
    content: '主播回复';
    display: block;
    font-size: 12px;
    font-weight: 600;
    color: var(--primary);
    margin-bottom: 5px;
}

.marshmallow-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    flex-wrap: wrap;
    margin-top: 12px;
    font-size: 12px;
    color: var(--text-3);
}

.code-display {
    text-align: center;
    padding: 26px 20px;
    background: var(--bg-fill);
    border-radius: var(--radius-lg);
}

.code-value {
    font-family: var(--font-mono);
    font-size: 32px;
    font-weight: 600;
    letter-spacing: 6px;
    color: var(--primary);
    margin: 14px 0;
    user-select: all;
}

.mood-row {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
}

/* ---------- 22. 我的组件列表 ---------- */
.plugin-row {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 16px 20px;
    background: var(--bg-container);
    border: 1px solid var(--border-split);
    border-radius: var(--radius-lg);
    margin-bottom: 10px;
}

.plugin-row:last-child {
    margin-bottom: 0;
}

.plugin-icon-box {
    width: 42px;
    height: 42px;
    border-radius: var(--radius);
    background: var(--primary-soft);
    color: var(--primary);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.plugin-row.disabled .plugin-icon-box {
    background: var(--bg-fill);
    color: var(--text-3);
}

@media (max-width: 640px) {
    .plugin-row { flex-wrap: wrap; gap: 12px; padding: 14px; }
}

/* 主播切换条（会员中心里绑定了多个主播时出现） */
.host-switch-bar {
    border-top: 1px solid var(--border-split);
    background: var(--bg-container);
}

.host-switch-list {
    display: flex;
    gap: 8px;
    overflow-x: auto;
    flex: 1;
    min-width: 0;
    padding-bottom: 2px;
    scrollbar-width: none;
}

.host-switch-list::-webkit-scrollbar {
    display: none;
}

.host-switch-btn {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    height: 34px;
    padding: 0 12px 0 6px;
    border: 1px solid var(--border);
    border-radius: var(--radius-pill);
    background: var(--bg-container);
    color: var(--text-2);
    font-size: 13px;
    font-family: inherit;
    cursor: pointer;
    white-space: nowrap;
    transition: all var(--transition);
    flex-shrink: 0;
}

.host-switch-btn:hover {
    border-color: var(--primary);
    color: var(--primary);
}

.host-switch-btn.active {
    background: var(--primary-strong);
    border-color: var(--primary-strong);
    color: #fff;
}

.switch-all-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: var(--bg-fill);
    color: var(--text-3);
}

.host-switch-btn.active .switch-all-icon {
    background: rgba(255, 255, 255, 0.25);
    color: #fff;
}

/* ---------- 23. 快速开始步骤 ---------- */
.setup-step {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 13px 0;
    border-bottom: 1px solid var(--border-split);
}

.setup-step:last-child {
    border-bottom: none;
}

.setup-num {
    width: 24px;
    height: 24px;
    border-radius: 50%;
    background: var(--bg-fill);
    color: var(--text-3);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 13px;
    font-weight: 600;
    flex-shrink: 0;
}

.setup-step.done .setup-num {
    background: var(--success-soft);
    color: var(--success);
}

/* 主页地址展示 */
.url-box {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    padding: 12px 16px;
    background: var(--bg-fill);
    border-radius: var(--radius);
}

.url-box code {
    flex: 1;
    min-width: 200px;
    font-family: var(--font-mono);
    font-size: 13px;
    color: var(--primary);
    word-break: break-all;
}

/* 概览里的组件标签 */
.plugin-chips {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
}

/* ---------- 24. 组件模板还会用到的零散样式 ---------- */

.skeleton-card {
    height: 76px;
    margin-bottom: 10px;
}

.copied-text {
    font-size: 12px;
    font-weight: 500;
    color: var(--success);
    display: inline-flex;
    align-items: center;
    gap: 4px;
}

/* 舰长展示网格 */
.wall-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
    gap: 12px;
}

/* 舰长墙：当前舰长数（每天凌晨 5 点核对） */
.wall-count-card {
    text-align: center;
    padding: 48px 20px;
}

.wall-count-num {
    font-size: 72px;
    font-weight: 700;
    line-height: 1.1;
    color: var(--primary);
    font-variant-numeric: tabular-nums;
}

.wall-count-label {
    margin-top: 6px;
    font-size: 15px;
    font-weight: 600;
    color: var(--text-2);
}

/* 舰长墙里每个人下面挂的标签：舰长等级 + 粉丝牌 */
.wall-badges {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 4px;
    margin-top: 2px;
}

/* 粉丝牌：B站 勋章的简化画法，颜色跟着主题走，不照抄对方配色 */
.medal-badge {
    display: inline-flex;
    align-items: center;
    height: 18px;
    padding: 0 6px;
    border-radius: var(--radius-pill);
    background: var(--primary-soft);
    color: var(--primary);
    font-size: 11px;
    font-weight: 600;
    line-height: 18px;
    white-space: nowrap;
}

.wall-item {
    text-align: center;
    padding: 16px 10px;
    background: var(--bg-container);
    border: 1px solid var(--border-split);
    border-radius: var(--radius-lg);
    transition: all var(--transition);
}

.wall-item:hover {
    border-color: var(--primary);
}

.wall-item .avatar {
    margin: 0 auto 8px;
}

.wall-name {
    font-size: 13px;
    margin-bottom: 6px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* 心情小圆点 */
.mood-dot {
    display: inline-block;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
    margin-right: 5px;
    opacity: 0.7;
}

/* 页内小标题 */
.mini-title {
    font-size: 14px;
    font-weight: 600;
    margin-bottom: 10px;
}

/* ---------- 25. 产品落地页（工具首页） ---------- */
.landing {
    min-height: 100vh;
}

.landing-hero {
    /* 顶部主视觉：桃粉渐变 + 淡淡的白色光斑，比纯色有层次 */
    background: var(--grad-sakura);
    padding: 76px 20px 84px;
    position: relative;
    overflow: hidden;
}

.landing-hero::after {
    content: '';
    position: absolute;
    inset: 0;
    background:
        radial-gradient(circle at 12% 22%, rgba(255, 255, 255, 0.55), transparent 42%),
        radial-gradient(circle at 88% 76%, rgba(255, 255, 255, 0.38), transparent 40%);
    pointer-events: none;
}

[data-theme='dark'] .landing-hero::after {
    background:
        radial-gradient(circle at 12% 22%, rgba(255, 255, 255, 0.06), transparent 42%),
        radial-gradient(circle at 88% 76%, rgba(255, 255, 255, 0.04), transparent 40%);
}

.landing-hero-inner {
    max-width: 760px;
    margin: 0 auto;
    text-align: center;
    position: relative;
    z-index: 1;
}

.landing-badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 30px;
    padding: 0 14px;
    border-radius: var(--radius-pill);
    background: rgba(255, 255, 255, 0.72);
    color: var(--link);
    font-size: 13px;
    font-weight: 500;
    margin-bottom: 20px;
    backdrop-filter: blur(6px);
}

[data-theme='dark'] .landing-badge {
    background: rgba(255, 255, 255, 0.10);
    color: var(--text);
}

.landing-title {
    font-size: 36px;
    line-height: 1.35;
    font-weight: 700;
    letter-spacing: -0.5px;
    color: #4a2b36;
    margin-bottom: 16px;
}

[data-theme='dark'] .landing-title {
    color: var(--text);
}

.landing-sub {
    font-size: 15px;
    line-height: 1.85;
    color: #7a5a66;
    max-width: 560px;
    margin: 0 auto 30px;
}

[data-theme='dark'] .landing-sub {
    color: var(--text-2);
}

.landing-cta {
    display: flex;
    gap: 12px;
    justify-content: center;
    flex-wrap: wrap;
}

.landing-section {
    max-width: 980px;
    margin: 0 auto;
    padding: 0 20px;
}

.landing-section:first-of-type {
    margin-top: -44px;
    position: relative;
    z-index: 2;
}

.landing-h2 {
    font-size: 22px;
    font-weight: 700;
    text-align: center;
    margin-bottom: 8px;
}

.landing-h2-sub {
    text-align: center;
    font-size: 13.5px;
    color: var(--text-3);
    margin-bottom: 26px;
}

.landing-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 18px;
}

.landing-card {
    background: var(--bg-container);
    border: 1px solid var(--border-split);
    border-radius: var(--radius-lg);
    padding: 26px 24px;
    box-shadow: var(--shadow-sm);
    transition: all var(--transition);
}

.landing-card:hover {
    box-shadow: var(--shadow);
    transform: translateY(-3px);
    border-color: var(--primary-border);
}

.landing-card .entry-icon {
    margin-bottom: 16px;
}

.landing-card-title {
    font-size: 16.5px;
    font-weight: 600;
    margin-bottom: 8px;
}

.landing-card-desc {
    font-size: 13.5px;
    line-height: 1.8;
    color: var(--text-2);
}

.landing-flow {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 18px;
    margin-top: 40px;
}

.landing-flow-col {
    background: var(--bg-container);
    border: 1px solid var(--border-split);
    border-radius: var(--radius-lg);
    padding: 24px;
}

.landing-flow-title {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 15px;
    font-weight: 600;
    margin-bottom: 16px;
    color: var(--text);
}

.landing-flow-title .y-icon {
    color: var(--primary);
}

.landing-steps {
    list-style: none;
    counter-reset: step;
}

.landing-steps li {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    font-size: 13.5px;
    line-height: 1.7;
    color: var(--text-2);
    padding: 7px 0;
}

.step-num {
    flex-shrink: 0;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: var(--primary-soft);
    color: var(--link);
    font-size: 12px;
    font-weight: 600;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-top: 1px;
}

.landing-foot {
    text-align: center;
    font-size: 12.5px;
    color: var(--text-4);
    padding: 40px 20px 56px;
}

@media (max-width: 700px) {
    .landing-hero { padding: 52px 16px 72px; }
    .landing-title { font-size: 25px; }
    .landing-sub { font-size: 14px; }
    .landing-flow { grid-template-columns: 1fr; }
    .landing-section:first-of-type { margin-top: -34px; }
}

/* ---------- 26. 主播 / 粉丝模式切换 ---------- */
.mode-switch {
    display: inline-flex;
    padding: 3px;
    border-radius: var(--radius-pill);
    background: var(--bg-fill);
    flex-shrink: 0;
}

.mode-switch-btn {
    display: inline-flex;
    align-items: center;
    height: 26px;
    padding: 0 14px;
    border-radius: var(--radius-pill);
    font-size: 13px;
    color: var(--text-3);
    cursor: pointer;
    transition: all var(--transition);
    white-space: nowrap;
    text-decoration: none;
}

.mode-switch-btn:hover {
    color: var(--link);
}

.mode-switch-btn.active {
    background: var(--bg-container);
    color: var(--link);
    font-weight: 500;
    box-shadow: var(--shadow-sm);
}

/*
 * 手机上以前整块隐藏（.mode-switch { display: none }），结果是主播在手机上
 * 找不到回主播端的路 —— 侧边栏里那组开关也一起看不到。现在改成压缩显示：
 * 字号、内边距收小，宽度交给父容器，抽屉里和顶栏里都能用。
 */
@media (max-width: 900px) {
    .mode-switch {
        display: flex;
        padding: 2px;
    }

    .mode-switch-btn {
        height: 24px;
        padding: 0 10px;
        font-size: 12.5px;
    }
}

/* ---------- 27. 个人主页页 ---------- */
.decor-layout {
    display: grid;
    grid-template-columns: minmax(320px, 400px) 1fr;
    gap: 20px;
    align-items: start;
}

.decor-panel .card:last-child {
    margin-bottom: 0;
}

.decor-label {
    font-size: 13px;
    color: var(--text-2);
    margin-bottom: 8px;
}

/* 渐变色块 / 颜色块 */
.decor-swatches {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
    align-items: center;
}

.decor-swatch {
    width: 52px;
    height: 38px;
    border-radius: var(--radius-sm);
    border: 2px solid transparent;
    cursor: pointer;
    padding: 0;
    position: relative;
    transition: all var(--transition);
    box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.04);
}

.decor-swatch:hover {
    transform: translateY(-2px);
}

.decor-swatch.active {
    border-color: var(--text);
    box-shadow: 0 0 0 2px var(--bg-container), var(--shadow);
}

.decor-swatch-color {
    width: 38px;
    height: 38px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-3);
    background: var(--bg-fill);
}

.decor-imagerow {
    display: flex;
    gap: 8px;
}

/* 面板上的输入项：只显示当前值，点右边「修改」进弹窗改 */
.decor-valuerow {
    display: flex;
    gap: 10px;
    align-items: center;
    min-width: 0;
}

.decor-value {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    padding: 9px 12px;
    border-radius: var(--radius);
    background: var(--bg-fill);
    color: var(--text-2);
    font-size: 13px;
}

.decor-value.empty { color: var(--text-3); }

/* 分段选择器（遮罩浓度用） */
.seg-group {
    display: inline-flex;
    padding: 3px;
    border-radius: var(--radius);
    background: var(--bg-fill);
}

/* 选项多的分段控件（比如六种排布方式）排不下就换行，别撑出侧栏 */
.seg-group.seg-wrap {
    display: flex;
    flex-wrap: wrap;
    gap: 2px;
}

.seg-group.seg-wrap .seg-btn {
    padding: 0 13px;
}

.seg-btn {
    height: 28px;
    padding: 0 18px;
    border: none;
    background: none;
    border-radius: var(--radius-sm);
    font-size: 13px;
    font-family: inherit;
    color: var(--text-3);
    cursor: pointer;
    transition: all var(--transition);
}

.seg-btn:hover {
    color: var(--link);
}

.seg-btn.active {
    background: var(--bg-container);
    color: var(--link);
    font-weight: 500;
    box-shadow: var(--shadow-sm);
}

/* 模块排序列表 */
.decor-order {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.decor-order-item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 12px;
    border: 1px solid var(--border-split);
    border-radius: var(--radius);
    background: var(--bg-container);
    cursor: grab;
}

/* 拖动排序：抓握提示 + 正在拖的那一项虚化，好看出落点 */
.decor-grip {
    color: var(--text-4);
    display: flex;
    flex-shrink: 0;
}

.decor-order-item.is-dragging {
    opacity: 0.45;
    border-style: dashed;
    border-color: var(--primary-border);
}

.decor-thumb-sm {
    width: 30px;
    height: 30px;
}

.decor-order-item .entry-icon {
    width: 34px;
    height: 34px;
}

/* 实时预览 */
.decor-preview {
    position: sticky;
    top: 76px;
}

.decor-preview-label {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    color: var(--text-3);
    margin-bottom: 10px;
}

.decor-preview-frame {
    /* 预览区模拟粉丝端：背景用暖白，里面的卡片自己带边框，
       所以这里不套额外的 card，避免和真实效果不一致 */
    background: var(--bg-layout);
    border: 1px solid var(--border-split);
    border-radius: var(--radius-lg);
    padding: 0;
    overflow: hidden;
    /* 缩放层是绝对定位的，所以外框的宽高完全由这里（和 JS 设的高度）决定 */
    position: relative;
    min-width: 0;
}

/* 预览所在的那一列也允许被压缩，不然里面的 1280px 会把整行顶宽 */
.decor-preview {
    min-width: 0;
}

/*
 * 等比缩放层：按 PREVIEW_W（1280）排版，再缩到框的宽度。
 * transform-origin 必须在左上，否则缩完会往中间跑、右下角空一块。
 */
.decor-preview-scaler {
    /*
     * 绝对定位：它按 1280px 排版，但绝不能参与父级的宽度计算 ——
     * 否则会把网格列顶开，整个面板被挤到屏幕外面去。
     */
    position: absolute;
    top: 0;
    left: 0;
    transform-origin: top left;
    will-change: transform;
}

.decor-preview-frame .host-home {
    /* 和真实页面一致的内边距，这样卡片宽度比例才对得上 */
    padding: 0 24px 40px;
}

/*
 * 预览框里整页背景要降级成 absolute。
 * 真实页面用的是 fixed（铺满视口），在这么小的预览框里 fixed 会溢出到整个屏幕上。
 */
.decor-preview-frame .host-bg,
.decor-preview-frame .host-bg-veil {
    position: absolute;
}

/* 预览框得自己是定位上下文，不然 absolute 会往上找到更外层的元素 */
.decor-preview-frame {
    position: relative;
}

/* 注意：这里不要再去改 .entry-grid 的列数。
   预览是「按 1280 排版再等比缩小」，列数必须和真实页面走同一套规则，
   一旦在这里压成单列，预览就又和线上不一致了。 */

/* ---------- 装扮面板：滑块 / 头像 / 组件配图 ---------- */

.decor-slider {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 6px;
}

.decor-slider input[type='range'] {
    flex: 1;
    min-width: 0;
    accent-color: var(--primary);
}

.decor-slider-label {
    width: 30px;
    flex-shrink: 0;
    font-size: 13px;
    color: var(--text-2);
}

.decor-slider-value {
    width: 42px;
    flex-shrink: 0;
    text-align: right;
    font-size: 12px;
    color: var(--text-3);
    font-variant-numeric: tabular-nums;
}

.decor-avatar-row {
    display: flex;
    align-items: center;
    gap: 14px;
}

.decor-avatar-preview {
    width: 56px;
    height: 56px;
    border-radius: 50%;
    object-fit: cover;
    flex-shrink: 0;
    background: var(--bg-fill);
    border: 1px solid var(--border-split);
}

.decor-thumb-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 7px 0;
}

.decor-thumb {
    width: 40px;
    height: 40px;
    border-radius: var(--radius);
    object-fit: cover;
    flex-shrink: 0;
}

/* 这一行的图标要和配图一样大，切换时行高不会跳 */
.decor-thumb-row .entry-icon {
    width: 40px;
    height: 40px;
}

@media (max-width: 1100px) {
    .decor-layout { grid-template-columns: 1fr; }
    .decor-preview { position: static; }
}

/* ---------- 28. 粉丝端侧边栏与引导页 ---------- */

/* 侧边栏里的主播项 */
.host-nav-item {
    gap: 9px;
}

.host-nav-item .avatar-sm {
    width: 24px;
    height: 24px;
    border: 1px solid var(--border-split);
}

.menu-group {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.menu-group-count {
    font-size: 11px;
    color: var(--text-4);
    font-weight: 400;
}

.sidebar-loading {
    padding: 8px 12px;
}

.sidebar-hint {
    font-size: 12.5px;
    color: var(--text-4);
    padding: 10px 12px;
    line-height: 1.7;
}

.sidebar-foot {
    padding: 12px;
    border-top: 1px solid var(--border-split);
    flex-shrink: 0;
}

/* 还没绑定主播时的引导 */
.bind-welcome {
    text-align: center;
    padding: 70px 24px 60px;
    background: var(--bg-container);
    border: 1px solid var(--border-split);
    border-radius: var(--radius-lg);
    /* 一点点粉色氛围，不要太空 */
    background-image: radial-gradient(circle at 50% 0%, var(--primary-soft), transparent 58%);
}

.bind-welcome-icon {
    width: 88px;
    height: 88px;
    border-radius: 50%;
    background: var(--grad-sakura);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0 auto 20px;
    box-shadow: var(--shadow-pink);
}

.bind-welcome-title {
    font-size: 20px;
    font-weight: 700;
    margin-bottom: 12px;
}

.bind-welcome-desc {
    font-size: 13.5px;
    line-height: 1.9;
    color: var(--text-2);
    margin-bottom: 24px;
}

.bind-welcome-actions {
    display: flex;
    justify-content: center;
}

.bind-welcome-hint {
    font-size: 12.5px;
    color: var(--text-4);
    margin-top: 16px;
}

/*
 * 沉浸模式下内容从最顶上开始，左上角那排浮动按钮正好压在 y=14~52，
 * 所以这类页面的第一块要往下让一让。
 */
.layout.immersive .bind-welcome,
.layout.immersive .page-pad {
    margin-top: 76px;
}

/* 账号资料：头像 + 昵称横排 */
.account-line {
    display: flex;
    align-items: center;
    gap: 12px;
}

/* 粉丝端侧边栏在窄屏下的开关 */
#fan-menu-toggle {
    margin-right: 4px;
}

@media (max-width: 900px) {
    #fan-menu-toggle { display: inline-flex !important; }
}

/* ---------- 29. 歌单页设置面板 ---------- */

.decor-group {
    margin-bottom: 20px;
}

.decor-group:last-child {
    margin-bottom: 0;
}

/* 勾选式的小方块（列开关、筛选开关） */
.decor-checks {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
}

.decor-check {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 30px;
    padding: 0 12px;
    border: 1px solid var(--border);
    border-radius: var(--radius-pill);
    background: var(--bg-container);
    color: var(--text-2);
    font-size: 13px;
    cursor: pointer;
    transition: all var(--transition);
    user-select: none;
}

.decor-check:hover {
    border-color: var(--primary-border);
}

.decor-check.active {
    background: var(--primary-soft);
    border-color: var(--primary);
    color: var(--link);
}

.decor-check input {
    accent-color: var(--primary);
    cursor: pointer;
}

.decor-url {
    font-family: var(--font-mono);
    font-size: 12px;
    background: var(--bg-fill);
    padding: 1px 6px;
    border-radius: var(--radius-sm);
    color: var(--link);
}

/* 迷你预览：模拟独立歌单页的样子 */
.sl-preview {
    background: var(--bg-layout);
    border: 1px solid var(--border-split);
    border-radius: var(--radius-lg);
    overflow: hidden;
}

.sl-preview-hero {
    padding: 22px 16px 16px;
    text-align: center;
}

/* 预览的背景铺满整块，和真实页面一致 */
.sl-preview {
    background-size: cover;
    background-position: 50% 50%;
    background-repeat: no-repeat;
}

/* 背景位置的两个滑块 */
.pos-row {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 8px;
}

.pos-tag {
    width: 34px;
    flex-shrink: 0;
    font-size: 12.5px;
    color: var(--text-3);
}

.pos-range {
    flex: 1;
    accent-color: var(--primary);
    cursor: pointer;
}

.pos-val {
    width: 42px;
    flex-shrink: 0;
    text-align: right;
    font-family: var(--font-mono);
    font-size: 12px;
    color: var(--text-3);
}

.sl-preview-avatar {
    width: 54px;
    height: 54px;
    border-radius: 50%;
    overflow: hidden;
    margin: 0 auto 10px;
    background: var(--bg-container);
}

.sl-preview-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.sl-preview-title {
    font-size: 15px;
    font-weight: 700;
    letter-spacing: -0.2px;
    word-break: break-all;
}

.sl-preview-filters {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
    padding: 12px 14px 0;
}

.sl-preview-pill {
    height: 24px;
    padding: 0 10px;
    line-height: 24px;
    border-radius: var(--radius-pill);
    background: var(--bg-container);
    border: 1px solid var(--border-split);
    color: var(--text-3);
    font-size: 11.5px;
    white-space: nowrap;
}

.sl-preview-table {
    padding: 12px 14px 16px;
    font-size: 11.5px;
}

.sl-preview-row {
    display: flex;
    gap: 10px;
    padding: 7px 10px;
    border-radius: var(--radius-sm);
    color: var(--text-3);
}

.sl-preview-row > span {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.sl-preview-row .sl-preview-name {
    flex: 1.6;
}

.sl-preview-head {
    background: var(--bg-fill);
    color: var(--link);
    font-weight: 600;
}

.sl-preview-row:not(.sl-preview-head):nth-child(even) {
    background: var(--bg-container);
}

/* ---------- 30. 舰礼收集 ---------- */

/* 收集卡片：一格一张小长方形（比上舰统计的月份卡大一些） */
.collect-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
    gap: 14px;
    margin-bottom: 8px;
}

.collect-card {
    display: flex;
    flex-direction: column;
    gap: 8px;
    min-height: 200px;
    background: var(--bg-container);
    border: 1px solid var(--border-split);
    border-radius: var(--radius-lg);
    padding: 16px;
    margin-bottom: 0;
    transition: border-color .15s, box-shadow .15s;
}

.collect-card:hover {
    border-color: var(--primary-border);
    box-shadow: var(--shadow-md, 0 2px 12px rgba(0, 0, 0, .06));
}

.collect-card-top {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 8px;
}

.collect-card-top .collect-title {
    margin-bottom: 0;
    font-size: 14.5px;
    line-height: 1.35;
}

.collect-time {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 12.5px;
    color: var(--text-3);
}

/* 发货状态 / 错过人数这类标记 */
.collect-flags {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    min-height: 22px;
}

.collect-card .collect-stats {
    gap: 10px;
    margin-top: auto;
    padding-top: 10px;
}

.collect-card .collect-stat b {
    font-size: 14px;
}

.collect-actions {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    padding-top: 10px;
    border-top: 1px solid var(--border-split);
}

.collect-actions .link-btn {
    margin-left: auto;
}

/* 上传快递单号的窗口 */
.ship-modal {
    max-width: 640px;
}

/* 传文档那一行：按钮 + 选中的文件名 */
.ship-upload {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    flex-wrap: wrap;
}

.collect-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 14px;
    flex-wrap: wrap;
}

.collect-title {
    font-size: 15px;
    font-weight: 600;
    margin-bottom: 4px;
}

.collect-meta {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
    font-size: 12.5px;
    color: var(--text-3);
    align-items: center;
}

.collect-stats {
    display: flex;
    gap: 16px;
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px solid var(--border-split);
    flex-wrap: wrap;
}

.collect-stat {
    font-size: 12.5px;
    color: var(--text-3);
}

.collect-stat b {
    color: var(--text);
    font-size: 15px;
    margin-right: 3px;
}

/* 已填 / 未填 可以点开看人 */
.collect-stat.done,
.collect-stat.todo {
    cursor: pointer;
    padding: 3px 10px;
    border-radius: 999px;
    border: 1px solid var(--border-split);
    background: var(--bg-body);
    transition: border-color .15s, color .15s;
}

.collect-stat.done:hover {
    border-color: var(--success, #34a853);
    color: var(--success, #34a853);
}

.collect-stat.todo:hover {
    border-color: var(--primary);
    color: var(--primary);
}

/* ---------- 查看收集：已填写 / 未填写 ---------- */

.collect-detail {
    position: relative;
    max-width: 940px;
}

/* 两个可切换的页签 */
.detail-tabs {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 14px;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--border-split);
}

.detail-tab {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 7px 16px;
    font-size: 13.5px;
    color: var(--text-2);
    background: var(--bg-body);
    border: 1px solid var(--border-split);
    border-radius: 999px;
    cursor: pointer;
    transition: border-color .15s, color .15s, background .15s;
}

.detail-tab:hover {
    border-color: var(--primary);
    color: var(--primary);
}

.detail-tab.active {
    background: var(--primary);
    border-color: var(--primary);
    color: #fff;
}

.detail-tab b {
    font-size: 14px;
    font-weight: 700;
}

.detail-tab.active .fan-dot {
    box-shadow: 0 0 0 2px rgba(255, 255, 255, .55);
}

/* ---------- 设置收集 ---------- */

.collect-editor {
    max-width: 820px;
}

.editor-section {
    padding: 14px 16px;
    margin-bottom: 12px;
    border: 1px solid var(--border-split);
    border-radius: var(--radius-lg);
    background: var(--bg-container);
}

.editor-section-head {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    margin-bottom: 12px;
}

.editor-section-head b {
    font-size: 14px;
}

.readonly-box {
    padding: 8px 12px;
    border: 1px dashed var(--border-split);
    border-radius: var(--radius);
    background: var(--bg-body);
    font-size: 13.5px;
    color: var(--text-2);
}

.preset-row {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    margin-bottom: 12px;
}

.field-card {
    border: 1px solid var(--border-split);
    border-radius: var(--radius);
    background: var(--bg-body);
    padding: 10px 12px;
    margin-bottom: 8px;
}

.field-card:hover {
    border-color: var(--primary);
}

.field-card-head {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.field-no {
    width: 22px;
    height: 22px;
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: rgba(251, 114, 153, .14);
    color: var(--primary);
    font-size: 12px;
    font-weight: 700;
}

.field-card-extra {
    margin-top: 8px;
}

.field-card-ops {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-top: 8px;
    padding-top: 8px;
    border-top: 1px dashed var(--border-split);
}

.field-card-ops .link-btn[disabled] {
    opacity: .4;
    cursor: not-allowed;
}

.detail-summary {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    margin-bottom: 14px;
}

.detail-stat {
    display: flex;
    align-items: baseline;
    gap: 5px;
    padding: 8px 14px;
    border-radius: var(--radius);
    background: var(--bg-body);
    border: 1px solid var(--border-split);
}

.detail-stat b {
    font-size: 18px;
    line-height: 1;
}

.detail-stat span {
    font-size: 12.5px;
    color: var(--text-3);
}

.detail-stat.done b {
    color: var(--success, #34a853);
}

.detail-stat.todo b {
    color: var(--primary);
}

.fan-section {
    margin-top: 18px;
}

.fan-section-head {
    display: flex;
    align-items: center;
    gap: 8px;
    padding-bottom: 8px;
    margin-bottom: 12px;
    border-bottom: 1px solid var(--border-split);
}

.fan-section-head b {
    font-size: 14px;
}

.fan-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--text-4);
}

.fan-dot.done {
    background: var(--success, #34a853);
}

.fan-dot.todo {
    background: var(--primary);
}

.fan-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(148px, 1fr));
    gap: 10px;
}

.fan-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    padding: 14px 8px 12px;
    border: 1px solid var(--border-split);
    border-radius: var(--radius-lg);
    background: var(--bg-container);
    cursor: pointer;
    text-align: center;
    transition: border-color .15s, box-shadow .15s, transform .15s;
}

.fan-card:hover {
    border-color: var(--primary);
    box-shadow: 0 4px 14px rgba(0, 0, 0, .06);
    transform: translateY(-1px);
}

.fan-card.todo {
    opacity: .78;
}

.fan-card.todo:hover {
    opacity: 1;
}

.fan-avatar {
    width: 44px;
    height: 44px;
    border-radius: 50%;
    object-fit: cover;
    background: var(--bg-body);
    border: 2px solid var(--bg-container);
    box-shadow: 0 0 0 1px var(--border-split);
}

.fan-card.done .fan-avatar {
    box-shadow: 0 0 0 2px var(--success, #34a853);
}

.fan-name {
    font-size: 13px;
    font-weight: 600;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.fan-sub {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
    justify-content: center;
}

/* 点开某个人看填写内容 */
.detail-pop {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, .34);
    border-radius: var(--radius-lg);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    z-index: 5;
}

.detail-pop-card {
    background: var(--bg-container);
    border-radius: var(--radius-lg);
    width: 100%;
    max-width: 520px;
    max-height: 100%;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    box-shadow: 0 18px 48px rgba(0, 0, 0, .22);
}

.detail-pop-head {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 16px 18px;
    border-bottom: 1px solid var(--border-split);
}

.detail-pop-body {
    padding: 16px 18px;
    overflow-y: auto;
}

.detail-pop-foot {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 18px;
    border-top: 1px solid var(--border-split);
}

.info-row {
    display: flex;
    gap: 12px;
    padding: 9px 0;
    border-bottom: 1px dashed var(--border-split);
}

.info-row:last-child {
    border-bottom: none;
}

.info-label {
    width: 108px;
    flex: none;
    font-size: 12.5px;
    color: var(--text-3);
}

.info-value {
    flex: 1;
    font-size: 13.5px;
    word-break: break-all;
}

/* 字段设计器里的一行 */
.field-row {
    display: flex;
    gap: 8px;
    align-items: center;
    padding: 10px 12px;
    border: 1px solid var(--border-split);
    border-radius: var(--radius);
    background: var(--bg-container);
    margin-bottom: 8px;
    flex-wrap: wrap;
}

.field-row .field-row-label {
    flex: 1;
    min-width: 120px;
}

/* 粉丝填表的字段 */
.form-field {
    margin-bottom: 16px;
}

.form-field-label {
    display: block;
    font-size: 13.5px;
    color: var(--text);
    margin-bottom: 6px;
}

.form-field-label .req {
    color: var(--error);
    margin-left: 2px;
}

/* 表单里已过期的图片 */
.expired-img {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 8px 12px;
    border-radius: var(--radius);
    background: var(--bg-fill);
    color: var(--text-3);
    font-size: 12.5px;
}

/* 候选人勾选列表 */
.candidate-list {
    max-height: 340px;
    overflow-y: auto;
    border: 1px solid var(--border-split);
    border-radius: var(--radius);
}

.candidate-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 14px;
    border-bottom: 1px solid var(--border-split);
    cursor: pointer;
    transition: background var(--transition);
}

.candidate-item:last-child {
    border-bottom: none;
}

.candidate-item:hover {
    background: var(--bg-hover);
}

.candidate-item input {
    accent-color: var(--primary);
    cursor: pointer;
}

/* ---------- 31. 账号管理：只读字段 + 修改按钮 ---------- */

.info-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 13px 0;
    border-bottom: 1px solid var(--border-split);
    flex-wrap: wrap;
}

.info-row:last-child {
    border-bottom: none;
}

.info-row-label {
    width: 110px;
    flex-shrink: 0;
    font-size: 13.5px;
    color: var(--text-2);
}

.info-row-value {
    flex: 1;
    min-width: 140px;
    font-size: 14px;
    color: var(--text);
    word-break: break-all;
}

.info-row-value.empty {
    color: var(--text-4);
}

/* 只读值里的补充说明要独占一行，不能和值挤在一起 */
.info-row-value .field-hint {
    display: block;
    margin-top: 4px;
}

.info-row-actions {
    display: flex;
    gap: 8px;
    flex-shrink: 0;
}

@media (max-width: 640px) {
    .info-row-label {
        width: 100%;
    }
}

/* ---------- 32. 通用小工具 ---------- */

.text-4 { color: var(--text-4); }
.w-full { width: 100%; }

.divider {
    height: 1px;
    background: var(--border-split);
    margin: 18px 0;
}

.form-row {
    display: flex;
    gap: 14px;
}

.form-row > .field {
    flex: 1;
    min-width: 0;
}

@media (max-width: 640px) {
    .form-row {
        flex-direction: column;
        gap: 0;
    }
}

/* ---------- 33. 舰礼收集：月份分组 ---------- */

.month-group {
    margin-bottom: 26px;
}

.month-title {
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: 14px;
    font-weight: 600;
    color: var(--text);
    margin-bottom: 12px;
    padding-bottom: 9px;
    border-bottom: 1px solid var(--border-split);
}

/* 提交明细里的图片缩略图 */
.sub-thumb {
    width: 44px;
    height: 44px;
    object-fit: cover;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border);
    display: block;
}

/* ---------- 34. 粉丝端：舰礼信息填写 ---------- */

.collect-block {
    background: var(--bg-container);
    border: 1px solid var(--primary-border);
    border-radius: var(--radius-lg);
    padding: 18px 20px;
}

.collect-block .collect-card {
    background: var(--bg-layout);
    margin-bottom: 10px;
}

.collect-block .collect-card:last-child {
    margin-bottom: 0;
}

.collect-extra {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
    align-items: center;
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px dashed var(--border-split);
}

/* ---------- 34.1 舰礼介绍（主播写，粉丝看） ---------- */

.collect-intro {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin-top: 12px;
    padding: 12px 14px;
    border-radius: var(--radius);
    background: var(--primary-soft, #FFF0F5);
    border: 1px solid var(--primary-border);
}

.collect-intro-img {
    width: 100%;
    max-height: 260px;
    object-fit: cover;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border-split);
    display: block;
}

.collect-intro-text {
    font-size: 13px;
    line-height: 1.8;
    color: var(--text-2);
    /* 主播习惯分几行写「奖品 / 时间 / 注意」，换行按原样显示 */
    white-space: pre-line;
}

/* 紧凑模式：卡片里只露缩略图和一小段字 */
.collect-intro.compact {
    flex-direction: row;
    align-items: flex-start;
    gap: 12px;
    margin-top: 10px;
    padding: 10px 12px;
}

.collect-intro.compact .collect-intro-img {
    width: 84px;
    height: 84px;
    max-height: none;
    flex-shrink: 0;
}

.collect-intro.compact .collect-intro-text {
    font-size: 12.5px;
    line-height: 1.7;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* 图片字段：预览 + 上传按钮 */
.img-field {
    display: flex;
    flex-direction: column;
    gap: 10px;
    align-items: flex-start;
}

.img-preview {
    display: flex;
    align-items: center;
    gap: 12px;
}

.img-preview img {
    width: 96px;
    height: 96px;
    object-fit: cover;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    display: block;
}

/* ---------- 34.2 舰礼样品（主播按等级设，粉丝看自己那份） ---------- */

.gift-tabs {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    margin-bottom: 12px;
}

.gift-tab {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 12px;
    border: 1px solid var(--border-split);
    border-radius: var(--radius);
    background: var(--bg-container);
    cursor: pointer;
    transition: var(--transition);
}

.gift-tab:hover {
    border-color: var(--primary-border);
}

.gift-tab.active {
    border-color: var(--primary);
    background: var(--primary-soft);
}

.gift-tab-text {
    font-size: 12.5px;
    color: var(--text-3);
}

.gift-tab.active .gift-tab-text {
    color: var(--link);
}

.gift-editor {
    padding: 14px;
    border: 1px solid var(--border-split);
    border-radius: var(--radius);
    background: var(--bg-container);
}

.gift-preview {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-top: 10px;
}

/* 缩略图按原图比例完整显示，不裁切 */
.gift-preview img {
    width: 120px;
    height: 120px;
    flex: none;
    object-fit: contain;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border);
    background: var(--bg-fill);
    display: block;
}

.gift-editor-foot {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px dashed var(--border-split);
}

/* ---------- 34.3 粉丝端：按月份列的上舰记录 ---------- */

.fan-months {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.fan-month {
    padding: 14px 16px;
    border: 1px solid var(--border-split);
    border-radius: var(--radius-lg);
    background: var(--bg-container);
    cursor: pointer;
    transition: var(--transition);
}

.fan-month:hover {
    border-color: var(--primary-border);
}

/* 还能填 / 还能改的月份：粉色描边，一眼看得出要处理 */
.fan-month.active {
    border-color: var(--primary);
    box-shadow: 0 0 0 3px var(--primary-soft);
}

.fan-month-head {
    display: flex;
    align-items: center;
    gap: 10px;
}

.fan-month-title {
    display: flex;
    align-items: center;
    font-size: 15px;
    font-weight: 600;
}

.fan-month-meta {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin-top: 8px;
    font-size: 12.5px;
    color: var(--text-3);
}

.fan-month-gift {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    margin-top: 12px;
    padding: 12px;
    border: 1px solid var(--primary-border);
    border-radius: var(--radius);
    background: var(--primary-soft);
}

.fan-month-foot {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 12px;
}

.gift-thumb {
    width: 72px;
    height: 72px;
    flex: none;
    object-fit: contain;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border);
    background: var(--bg-fill);
    display: block;
    cursor: zoom-in;
}

.gift-big {
    display: block;
    width: 100%;
    max-height: 360px;
    margin-top: 12px;
    object-fit: contain;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    background: var(--bg-fill);
    cursor: zoom-in;
}

/* 点图片放大看一整张 */
.img-lightbox {
    position: fixed;
    inset: 0;
    z-index: 3000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--sp-6);
    background: rgba(30, 20, 26, 0.74);
    cursor: zoom-out;
}

.img-lightbox img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
}

/* ---------- 35. 危险操作提示 ---------- */

.alert-box {
    display: flex;
    gap: 10px;
    align-items: flex-start;
    padding: 14px 16px;
    border-radius: var(--radius);
    font-size: 13px;
    line-height: 1.75;
    background: var(--bg-fill);
    color: var(--text-2);
}

.alert-box strong {
    color: var(--text);
    font-weight: 600;
}

.alert-box.danger {
    background: var(--error-soft);
    border: 1px solid var(--error-border);
    color: var(--text-2);
}

.alert-box.danger svg {
    color: var(--error);
    flex-shrink: 0;
    margin-top: 2px;
}

.danger-list {
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 7px;
}

.danger-list li {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 8px 12px;
    border-radius: var(--radius-sm);
    background: var(--error-soft);
    font-size: 13px;
    color: var(--text-2);
}

.danger-list li b {
    color: var(--error);
    font-size: 14px;
}

/* 预览里的卡片布局 */
.sl-preview-cards {
    padding: 12px 14px 16px;
    display: flex;
    flex-direction: column;
    gap: 7px;
}

.sl-preview-card {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 9px 12px;
    border-radius: var(--radius);
    background: var(--bg-container);
    border: 1px solid var(--border-split);
    font-size: 11.5px;
    color: var(--text-3);
}

.sl-preview-card .sl-preview-name {
    font-weight: 600;
    color: var(--text-2);
}

.sl-preview-card-meta {
    display: flex;
    gap: 8px;
    flex-shrink: 0;
}

/* ---------- 36. 歌单管理（照参考图的工具栏 + 筛选行 + 表格） ---------- */

/* 分享链接那一条（现在住在「歌单页设置」面板里） */
.share-url-row {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.share-url-row .decor-url {
    flex: 1;
    min-width: 180px;
    padding: 6px 10px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* 短链前缀的检查结果：可以用是主色，不能用是红色 */
.field-hint.short-key-good {
    color: var(--link);
}

.field-hint.short-key-bad {
    color: var(--error);
}

/* 一行小统计 */
.mini-stats {
    display: flex;
    align-items: center;
    gap: 12px;
    font-size: 13px;
    color: var(--text-3);
    margin-bottom: 12px;
}

.mini-stats b {
    color: var(--text);
    font-size: 15px;
    font-weight: 700;
    margin-right: 2px;
}

.mini-stats .ok b { color: var(--success, #52c41a); }
.mini-stats .muted b { color: var(--text-4); }
.mini-stats i {
    width: 1px;
    height: 12px;
    background: var(--border);
}

/* 工具栏按钮：每个动作一个颜色，和参考图一致 */
.song-tool-card { padding: 16px 18px; }

.song-toolbar-btns {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
    align-items: center;
}

/* 工具栏分组：改数据的排左边，改歌单页的靠右，中间用竖线分开 */
.st-cluster {
    display: flex;
    gap: 8px;
    align-items: center;
}

.st-sep {
    width: 1px;
    height: 22px;
    background: var(--border);
    margin: 0 2px;
}

.st-spacer { flex: 1 1 auto; }

.st-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 40px;
    padding: 0 18px;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    background: var(--bg-container);
    color: var(--text);
    font-size: 14px;
    font-weight: 500;
    cursor: pointer;
    transition: all var(--transition);
    white-space: nowrap;
}

.st-btn:hover:not(:disabled) {
    transform: translateY(-1px);
    box-shadow: var(--shadow-md);
}

.st-btn:disabled {
    opacity: 0.45;
    cursor: not-allowed;
}

.st-add    { color: #1677ff; border-color: #91caff; background: #f0f7ff; }
.st-edit   { color: #722ed1; border-color: #d3adf7; background: #f9f0ff; }
.st-batch  { color: #13c2c2; border-color: #87e8de; background: #e6fffb; }
.st-del    { color: #ff4d4f; border-color: #ffccc7; background: #fff2f0; }
.st-sort   { color: #1677ff; border-color: #91caff; background: #f0f7ff; }
.st-import { color: #389e0d; border-color: #b7eb8f; background: #f6ffed; }
.st-export { color: #389e0d; border-color: #b7eb8f; background: #f6ffed; }
.st-decor  { color: var(--primary); border-color: var(--primary-border); background: var(--primary-soft, #FFF0F5); }

html[data-theme="dark"] .st-add,
html[data-theme="dark"] .st-sort   { background: rgba(22, 119, 255, 0.12); }
html[data-theme="dark"] .st-edit   { background: rgba(114, 46, 209, 0.14); }
html[data-theme="dark"] .st-batch  { background: rgba(19, 194, 194, 0.12); }
html[data-theme="dark"] .st-del    { background: rgba(255, 77, 79, 0.12); }
html[data-theme="dark"] .st-import,
html[data-theme="dark"] .st-export { background: rgba(56, 158, 13, 0.14); }

/* 批量编辑抽屉 */
.batch-drawer {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin-top: 14px;
    padding: 12px 14px;
    border-radius: var(--radius);
    background: var(--bg-fill);
    border: 1px dashed var(--border);
}

/* 筛选行：左边填条件、右边是动作，两段各自成组 */
.song-filter-row {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    margin-top: 16px;
    padding-top: 16px;
    border-top: 1px solid var(--border-split);
}

.song-filter-fields {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
    align-items: center;
    flex: 1 1 auto;
    min-width: 0;
}

.song-filter-acts {
    display: flex;
    gap: 8px;
    align-items: center;
    margin-left: auto;
}

.song-filter-fields .input,
.song-filter-fields .select {
    width: 130px;
    height: 40px;
}

.song-filter-fields .sl-status-select { width: 118px; }

.st-filter-apply { height: 40px; padding: 0 20px; }
.st-filter-reset { height: 40px; padding: 0 16px; }

/* 歌名那一列放宽一点 */
.sl-th-name { min-width: 180px; }

/* 设置面板里的方块选择器：选中用加深色，不用单选框 */
.col-picker {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
}

.col-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 38px;
    padding: 0 18px;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    background: var(--bg-container);
    color: var(--text-3);
    font-size: 14px;
    cursor: pointer;
    transition: all var(--transition);
    user-select: none;
}

.col-chip:hover {
    border-color: var(--primary-border);
    color: var(--text-2);
}

.col-chip.on {
    background: var(--primary);
    border-color: var(--primary);
    color: #fff;
    font-weight: 600;
    box-shadow: 0 3px 12px rgba(255, 123, 160, 0.35);
}

.col-chip.locked {
    background: var(--bg-fill);
    border-style: dashed;
    color: var(--text-4);
    cursor: default;
}

.col-chip.locked:hover {
    border-color: var(--border);
    color: var(--text-4);
}

/* ---------- 37. 舰长登记：月份卡片 ---------- */

/* 上舰统计按 当前月 / 过往月 / 未来月 分三段 */
.month-section {
    margin-bottom: 20px;
}

.month-section:last-child {
    margin-bottom: 0;
}

.month-section-title {
    font-size: 13px;
    font-weight: 600;
    color: var(--text-3);
    margin-bottom: 10px;
}

.month-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 14px;
}

.month-card {
    background: var(--bg-container);
    border: 1px solid var(--border-split);
    border-radius: var(--radius-lg);
    padding: 16px 18px;
    cursor: pointer;
    transition: all var(--transition);
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.month-card:hover {
    border-color: var(--primary);
    box-shadow: var(--shadow-md);
    transform: translateY(-2px);
}

.month-card-top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    color: var(--text-3);
}

.month-card:hover .month-card-top {
    color: var(--primary);
}

.month-card-title {
    font-size: 14.5px;
    font-weight: 600;
    color: var(--text);
}

.month-card-num {
    font-size: 13px;
    color: var(--text-2);
}

.month-card-num b {
    font-size: 22px;
    color: var(--primary);
    font-weight: 700;
    margin-right: 3px;
}

.month-card-tags,
.month-card-foot {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
    align-items: center;
}

.month-card-foot {
    padding-top: 10px;
    border-top: 1px solid var(--border-split);
    margin-top: auto;
}

/* 补录面板 */
.pick-panel {
    padding: 16px;
    border-radius: var(--radius);
    background: var(--primary-soft, #FFF0F5);
    border: 1px solid var(--primary-border);
}

.candidate-item.picked {
    background: var(--primary-soft, #FFF0F5);
    box-shadow: inset 3px 0 0 var(--primary);
}

.candidate-item.dim {
    opacity: 0.55;
}

/* ---------- 38. 侧边栏分组 + 代管提示条 ---------- */

.nav-group {
    margin-bottom: 6px;
}

.nav-group-head {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 9px 12px;
    margin: 6px 0 2px;
    border-radius: var(--radius);
    cursor: pointer;
    color: var(--text-3);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.4px;
    user-select: none;
    transition: all var(--transition);
}

.nav-group-head:hover {
    background: var(--bg-hover);
    color: var(--text-2);
}

.nav-group-title {
    flex: 1;
}

.nav-group-badge {
    min-width: 18px;
    height: 18px;
    padding: 0 6px;
    border-radius: 9px;
    background: var(--primary);
    color: #fff;
    font-size: 11px;
    font-weight: 600;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

/* 管理功能那一组用主色区分开，一眼看出和管理面板不是一回事 */
.admin-group {
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px dashed var(--border);
}

.admin-group .nav-group-head {
    color: var(--primary);
}

.admin-group .nav-group-head:hover {
    background: var(--primary-soft, #FFF0F5);
    color: var(--primary);
}

.nav-group-body {
    padding-left: 2px;
}

/* 代管提示条 */
.acting-bar {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 13px 18px;
    margin-bottom: 18px;
    border-radius: var(--radius-lg);
    background: linear-gradient(135deg, #FFF7E6, #FFFBF0);
    border: 1px solid #FFE0A3;
    flex-wrap: wrap;
}

html[data-theme="dark"] .acting-bar {
    background: linear-gradient(135deg, rgba(255, 193, 7, 0.12), rgba(255, 193, 7, 0.06));
    border-color: rgba(255, 193, 7, 0.35);
}

.acting-bar-icon {
    width: 32px;
    height: 32px;
    border-radius: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #FFF1CC;
    color: #D48806;
    flex-shrink: 0;
}

.acting-bar-title {
    font-size: 13.5px;
    font-weight: 600;
    color: var(--text);
    margin-bottom: 2px;
}

.acting-bar-sub {
    font-size: 12px;
    color: var(--text-3);
}

/* 账号名可点 */
.link-name {
    cursor: pointer;
    transition: color var(--transition);
}

.link-name:hover {
    color: var(--primary);
    text-decoration: underline;
}

/* 补录名单的汇总条 */
.roster-sum {
    display: flex;
    align-items: center;
    gap: 16px;
    flex-wrap: wrap;
    padding: 12px 16px;
    margin-bottom: 12px;
    border-radius: var(--radius);
    background: var(--bg-fill);
    font-size: 13px;
    color: var(--text-3);
}

.roster-sum b {
    font-size: 16px;
    font-weight: 700;
    color: var(--text);
    margin: 0 2px;
}

.roster-sum .ok b { color: var(--success, #52c41a); }
.roster-sum .warn b { color: var(--warning, #faad14); }
.roster-sum .muted b { color: var(--text-4); }

/* 直播间接入状态条 */
.conn-status {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 14px 16px;
    border-radius: var(--radius);
    background: var(--bg-fill);
}

.conn-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    flex-shrink: 0;
    background: var(--text-4);
}

.conn-dot.on {
    background: var(--success, #52c41a);
    box-shadow: 0 0 0 4px rgba(82, 196, 26, 0.18);
}

.conn-dot.off {
    background: var(--warning, #faad14);
    box-shadow: 0 0 0 4px rgba(250, 173, 20, 0.18);
}

/* 直播监控页的开关键 */
.live-switch {
    display: flex;
    align-items: center;
    gap: 16px;
    flex-wrap: wrap;
}

.live-switch b {
    color: var(--text);
    font-size: 15px;
    margin: 0 2px;
}

/* ---------- 39. B站 账号：按字段填写 ---------- */

.cookie-paste {
    padding: 14px 16px;
    border-radius: var(--radius);
    background: var(--primary-soft, #FFF0F5);
    border: 1px solid var(--primary-border);
    margin-bottom: 18px;
}

.cookie-paste-head {
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: 13px;
    color: var(--text-2);
    margin-bottom: 10px;
}

.cookie-fields {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
    gap: 16px 20px;
    margin-bottom: 16px;
}

.cookie-field-head {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 6px;
    flex-wrap: wrap;
}

.cookie-field-label {
    font-size: 13.5px;
    color: var(--text);
    font-weight: 500;
}

.cookie-field-label .req {
    color: var(--error);
    margin-left: 2px;
}

.cookie-field .input {
    font-family: var(--font-mono);
    font-size: 12.5px;
}

.cookie-field .field-hint {
    line-height: 1.6;
}

/* ---------- 40. 直播监控：登录的 B站 账号 + 实时指示 ---------- */

.bili-account {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 14px 16px;
    border-radius: var(--radius);
    background: var(--bg-fill);
    margin-bottom: 12px;
}

.bili-account-face {
    width: 48px;
    height: 48px;
    border-radius: 50%;
    object-fit: cover;
    border: 2px solid var(--primary);
    flex-shrink: 0;
    background: var(--bg-container);
}

.bili-account-name {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 15px;
    font-weight: 600;
    color: var(--text);
}

/* 实时刷新的小圆点，一动一动的 */
.live-pulse {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--text-4);
    flex-shrink: 0;
}

.live-pulse.on {
    background: var(--success, #52c41a);
    animation: livePulse 1.6s ease-in-out infinite;
}

@keyframes livePulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(82, 196, 26, 0.5); }
    50%      { box-shadow: 0 0 0 6px rgba(82, 196, 26, 0); }
}

/* ---------- 41. 扫码登录 ---------- */

.qr-img {
    width: 220px;
    height: 220px;
    display: block;
    margin: 0 auto;
    border-radius: var(--radius);
    background: #fff;
    padding: 8px;
    border: 1px solid var(--border-split);
}

.qr-ok {
    color: var(--success, #52c41a);
}

.bili-empty {
    padding: 16px;
    border-radius: var(--radius);
    background: var(--bg-fill);
}

/* ---------- 图片取景弹窗 ---------- */

.modal-imgpos {
    max-width: 520px;
}

.imgpos-frame {
    position: relative;
    width: 100%;
    max-height: 46vh;
    margin: 0 auto;
    overflow: hidden;
    border-radius: var(--radius-lg);
    background: var(--bg-fill);
    border: 1px solid var(--border);
    cursor: grab;
    touch-action: none;
    /* 选框外面的部分压暗一点，一眼看出「只有框里才算数」 */
    box-shadow: 0 0 0 9999px rgba(20, 12, 16, 0.06);
}

.imgpos-frame:active {
    cursor: grabbing;
}

.imgpos-frame img {
    width: 100%;
    height: 100%;
    display: block;
    user-select: none;
    -webkit-user-drag: none;
    pointer-events: none;
}

.modal-imgpos .modal-footer {
    align-items: center;
    gap: 8px;
}

/* ---------- 取色弹窗 ---------- */

.modal-color {
    max-width: 420px;
}

/* 上面那一条：单色就是纯色块，渐变就是按当前方向和两头颜色合成 */
.color-preview {
    height: 56px;
    border-radius: var(--radius-lg);
    border: 1px solid var(--border);
    box-shadow: var(--shadow);
}

/* 渐变模式下的两头：先点一头，再在下面挑颜色 */
.color-ends {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 12px;
}

.color-end {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 30px;
    padding: 0 10px;
    border: 1px solid var(--border);
    border-radius: var(--radius-pill);
    background: var(--bg-container);
    color: var(--text-2);
    font-size: 12.5px;
    cursor: pointer;
}

.color-end.active {
    border-color: var(--primary);
    background: var(--primary-soft);
    color: var(--primary-strong);
}

.color-end-dot {
    width: 12px;
    height: 12px;
    border-radius: 50%;
    box-shadow: inset 0 0 0 1px rgba(20, 12, 16, 0.12);
}

.color-ends-hint {
    font-size: 12px;
    color: var(--text-4);
}

.color-palette {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(30px, 1fr));
    gap: 8px;
    margin-top: 12px;
}

.color-dot {
    width: 100%;
    aspect-ratio: 1 / 1;
    padding: 0;
    border: 1px solid rgba(20, 12, 16, 0.08);
    border-radius: 8px;
    cursor: pointer;
}

.color-dot.active {
    box-shadow: 0 0 0 2px var(--bg-container), 0 0 0 4px var(--primary);
}

.color-custom {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 12px;
}

.color-native {
    width: 42px;
    height: 32px;
    padding: 0;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--bg-container);
    cursor: pointer;
}

.color-hex {
    width: 108px;
    text-transform: uppercase;
}

/* 「更多颜色」那个小按钮：跟在色块后面，比色块高一点，一眼能找到 */
.decor-more {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    height: 30px;
    padding: 0 10px;
    border: 1px dashed var(--border);
    border-radius: var(--radius-pill);
    background: transparent;
    color: var(--text-3);
    font-size: 12.5px;
    cursor: pointer;
}

.decor-more:hover {
    border-color: var(--primary);
    color: var(--primary-strong);
}

/* ============================================================
   账号管理：批量操作条 / 勾选框 / 数据足迹
   ============================================================ */

/* 勾了几个账号才出现，用浅色底和上边框跟工具栏分开 */
.batch-bar {
    margin-top: 10px;
    padding: 10px 12px;
    border-top: 1px dashed var(--border);
    background: var(--primary-soft);
    border-radius: 10px;
}

/* 列表里的勾选框：跟站内其它原生勾选框保持一致，只用主色调一下 */
.table input[type="checkbox"],
.batch-bar input[type="checkbox"] {
    width: 15px;
    height: 15px;
    accent-color: var(--primary);
    cursor: pointer;
    vertical-align: middle;
}

.info-list {
    display: flex;
    flex-direction: column;
}

/* 使用统计：占比条与出错数字 */
.usage-bar {
    height: 6px;
    border-radius: 999px;
    background: var(--bg-fill);
    overflow: hidden;
}

.usage-bar > span {
    display: block;
    height: 100%;
    border-radius: 999px;
    background: var(--primary);
}

.usage-err {
    color: #d48806;
    font-weight: 600;
}

/* ================================================================
   站点公告：站长在后台「站点设置」里写的话

   前台表现分成两种：
   - 入口：粉丝端侧边栏、主播端顶栏各一个按钮（.notice-entry），
     紧急且没看过时带个红点（.notice-dot）；
   - 弹窗：点入口弹，紧急的那份登录之后自己弹（Yuri.notice，见 core.js）。
   以前是页面顶上压一条横幅，正文一长就把内容顶下去，主播反馈不要，改掉了。
   ================================================================ */
.notice-entry {
    position: relative;
}

/* 侧边栏那个入口占满一行，跟主题切换、退出登录那一排拉开一点距离 */
.sidebar-foot .notice-entry {
    width: 100%;
    justify-content: center;
}

/* 紧急且没看过：入口右上角一个红点，不抢眼球但看得见 */
.notice-dot {
    position: absolute;
    top: 5px;
    right: 6px;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--error);
    box-shadow: 0 0 0 2px var(--bg-container);
}

.notice-body {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.notice-tag {
    align-self: flex-start;
    height: 22px;
    line-height: 20px;
    padding: 0 9px;
    border-radius: var(--radius-pill);
    background: var(--primary-soft);
    border: 1px solid var(--primary-border);
    color: var(--primary-strong);
    font-size: 12px;
}

.notice-tag.is-urgent {
    background: var(--error-soft);
    border-color: var(--error-border);
    color: var(--error);
}

.notice-text {
    color: var(--text);
    font-size: 14px;
    line-height: 1.8;
    /* 站长在后台敲的换行原样显示 */
    white-space: pre-line;
    word-break: break-word;
    /* 公告很长时弹窗自己滚，别把「知道了」顶出屏幕 */
    max-height: 46vh;
    overflow: auto;
}

/* 直播监控：健康度提醒列表（哪个直播间要留意、为什么） */
.alert-list {
    margin-top: 10px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.alert-item {
    display: flex;
    align-items: baseline;
    gap: 8px;
    flex-wrap: wrap;
    line-height: 1.7;
}

/* ================================================================
   后台设计基座（作用域 .admin-shell）
   ----------------------------------------------------------------
   只作用于后台页面：admin.html 的 body 上带 .admin-shell 这个类。
   粉丝端 fan.html、主播主页 index.html、歌单公开页 songlist.html
   都没有这个类，拿不到下面任何一条规则，观感与现在完全一致。

   装扮设置里的主播主页预览（.decor-preview-frame 里的
   .host-home-preview）虽然也嵌在后台页面里，但它必须和真实主页长
   得一样，所以下面每条规则都排除这个子树。
   ================================================================ */

/* ---------- 字号刻度：后台统一只用这六档 ----------
   值写成 clamp(原值, vw, 上限)：小屏和平板就是原来的像素，窗口越宽字越大，
   到上限为止 —— 2K 屏上后台不会显得又空又小（下限=原值，窄屏观感不变）。 ---------- */
.admin-shell {
    --fs-xs: clamp(12.5px, 0.78vw, 14px);   /* 表头、辅助说明 */
    --fs-sm: clamp(13.5px, 0.84vw, 15px);   /* 正文、表格 */
    --fs-md: clamp(15px, 0.94vw, 17px);     /* 卡片标题、空态标题 */
    --fs-lg: clamp(17px, 1.06vw, 19px);     /* 弹窗标题 */
    --fs-xl: clamp(22px, 1.4vw, 28px);      /* 页面标题 */
    --fs-2xl: clamp(28px, 1.8vw, 36px);     /* 统计数字 */
}

/* ---------- 基座 1/6：页头 ---------- */
.admin-shell .page-head:not(.host-home-preview *) {
    margin-bottom: var(--sp-5);
    gap: var(--sp-4);
}

.admin-shell .page-title:not(.host-home-preview *) {
    font-size: var(--fs-xl);
}

.admin-shell .page-desc:not(.host-home-preview *) {
    font-size: var(--fs-sm);
    margin-top: var(--sp-1);
}

/* ---------- 基座 2/6：卡片 ---------- */
.admin-shell .card:not(.host-home-preview *) {
    padding: var(--sp-5);
    margin-bottom: var(--sp-4);
    box-shadow: var(--shadow-sm);
}

.admin-shell .card-title:not(.host-home-preview *) {
    font-size: var(--fs-md);
    margin-bottom: var(--sp-4);
}

.admin-shell .section-title:not(.host-home-preview *) {
    font-size: var(--fs-md);
    margin: var(--sp-5) 0 var(--sp-3);
}

/* ---------- 基座 3/6：统计卡 ---------- */
.admin-shell .stat-grid:not(.host-home-preview *) {
    gap: var(--sp-4);
    margin-bottom: var(--sp-4);
}

.admin-shell .stat-card:not(.host-home-preview *) {
    padding: var(--sp-4) var(--sp-5);
    box-shadow: var(--shadow-sm);
}

.admin-shell .stat-label:not(.host-home-preview *) {
    font-size: var(--fs-xs);
    margin-bottom: var(--sp-2);
}

.admin-shell .stat-value:not(.host-home-preview *) {
    font-size: var(--fs-2xl);
}

/* ---------- 基座 4/6：表格 ---------- */
.admin-shell .table:not(.host-home-preview *) {
    font-size: var(--fs-sm);
}

.admin-shell .table th:not(.host-home-preview *) {
    font-size: var(--fs-xs);
    padding: 10px 14px;
    letter-spacing: 0.02em;
}

.admin-shell .table td:not(.host-home-preview *) {
    padding: 13px 14px;
}

/* ---------- 基座 5/6：弹窗 ---------- */
.admin-shell .modal:not(.host-home-preview *) {
    box-shadow: var(--shadow-lg);
}

.admin-shell .modal-header:not(.host-home-preview *) {
    padding: var(--sp-4) var(--sp-5) 0;
}

.admin-shell .modal-title:not(.host-home-preview *) {
    font-size: var(--fs-lg);
}

.admin-shell .modal-body:not(.host-home-preview *) {
    padding: var(--sp-5);
}

.admin-shell .modal-footer:not(.host-home-preview *) {
    padding: 0 var(--sp-5) var(--sp-4);
}

/* ---------- 基座 6/6：空态 ---------- */
.admin-shell .empty:not(.host-home-preview *) {
    padding: 48px var(--sp-4);
}

.admin-shell .empty-icon:not(.host-home-preview *) {
    margin-bottom: var(--sp-4);
}

.admin-shell .empty-title:not(.host-home-preview *) {
    font-size: var(--fs-md);
}

.admin-shell .empty-desc:not(.host-home-preview *) {
    font-size: var(--fs-sm);
}

/* ---------- 壳层 1/2：侧边栏（作用域 .admin-shell） ---------- */
.admin-shell .sidebar-logo {
    padding: 0 18px;
    font-size: 15.5px;
    letter-spacing: 0.01em;
}

.admin-shell .sidebar-logo .logo-mark {
    background: var(--grad-sakura);
    box-shadow: var(--shadow-pink);
}

.admin-shell .sidebar-menu {
    padding: 10px;
}

/* 「组件」「设置」这种小标题：压低、拉字距，只做分隔，不抢条目 */
.admin-shell .menu-group {
    padding: 16px 10px 6px;
    font-size: 11.5px;
    font-weight: 600;
    letter-spacing: 0.06em;
    color: var(--text-4);
}

.admin-shell .menu-item {
    height: 36px;
    gap: 9px;
    padding: 0 10px;
    margin-bottom: 1px;
    border-radius: var(--radius-sm);
    font-size: var(--fs-sm);
}

/* 选中项左侧加一道指示条，扫一眼就知道自己在哪 */
.admin-shell .menu-item.active {
    box-shadow: inset 2px 0 0 var(--primary);
}

.admin-shell .menu-item .menu-badge {
    min-width: 16px;
    height: 16px;
    line-height: 16px;
    font-size: 10.5px;
}

.admin-shell .nav-group-head {
    padding: 8px 10px;
    margin: 8px 0 2px;
    font-size: 11.5px;
    letter-spacing: 0.06em;
}

/* 管理功能那一组原来是虚线，改成一条淡分隔线，安静一些 */
.admin-shell .admin-group {
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px solid var(--border-split);
}

/* ---------- 壳层 2/2：顶栏（作用域 .admin-shell） ---------- */
.admin-shell .header {
    gap: 12px;
    padding: 0 var(--viewer-gutter);
}

.admin-shell .header-title {
    font-size: 15.5px;
    letter-spacing: 0.01em;
}

/* 账号区收成一颗胶囊：头像 + 昵称 + 身份 */
.admin-shell .header-user {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    height: 36px;
    padding: 0 10px 0 4px;
    border: 1px solid var(--border-split);
    border-radius: var(--radius-pill);
    background: var(--bg-container);
}

.admin-shell .header-avatar {
    width: 28px;
    height: 28px;
    border-radius: var(--radius-pill);
    object-fit: cover;
    background: var(--bg-fill);
    flex-shrink: 0;
}

.admin-shell .header-name {
    max-width: 140px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: var(--fs-sm);
    font-weight: 500;
    color: var(--text);
}

.admin-shell .header-user .tag {
    height: 20px;
    padding: 0 7px;
    font-size: 11px;
}

/* 窄屏：侧边栏收进抽屉，顶栏照旧贴边；菜单按钮只在窄屏出现，
   否则侧边栏一收就再也点不开了 */
.admin-shell #menu-toggle {
    display: none;
}

/* ---------- 宽屏自适应：内容列不封顶，块级尺寸跟着视口一起长 ---------- */

/*
 * 以前给内容列封顶 1400px：2K 屏上窗口越大、两边空白越多，里面的字号和块还是
 * 原来那么大，看着又空又小。下面这些值一律写成 clamp(原值, vw, 上限)：
 * 窄屏取原值（观感不变），窗口越宽越大，到上限为止。
 *
 * 不套媒体查询是有意的 —— clamp 的下限就是原来的像素值，小屏自然回到原样，
 * 中间也不会在某个断点上跳一下。这段放文件最后：选择器和基础规则同权重，
 * 靠顺序赢。
 */

/* 主播主页：招牌卡 */
.host-hero-cover {
    min-height: clamp(172px, 12vw, 260px);
    padding: clamp(26px, 2vw, 46px) clamp(24px, 2.2vw, 56px);
    gap: clamp(18px, 1.4vw, 30px) clamp(20px, 1.6vw, 34px);
}

.host-avatar {
    width: clamp(92px, 6vw, 148px);
    height: clamp(92px, 6vw, 148px);
}

.host-name {
    font-size: clamp(21px, 1.45vw, 32px);
}

.host-bio {
    font-size: clamp(13px, 0.85vw, 16px);
    max-width: clamp(560px, 38vw, 900px);
}

.host-meta .host-pill {
    font-size: clamp(12px, 0.8vw, 14px);
    padding: 3px clamp(9px, 0.7vw, 14px);
}

/* 直播状态卡 */
.live-card {
    padding: clamp(12px, 1.1vw, 22px);
}

.live-cover {
    min-height: clamp(96px, 9vw, 200px);
}

.live-title {
    font-size: clamp(15px, 1vw, 20px);
}

.live-sub {
    font-size: clamp(12.5px, 0.85vw, 15px);
}

/* 功能入口：卡片最小宽度跟着长，铺满整行的同时不至于瘦长 */
.entry-grid {
    gap: clamp(14px, 1.1vw, 22px);
    grid-template-columns: repeat(auto-fit, minmax(clamp(280px, 19vw, 420px), 1fr));
}

.entry-card {
    padding: clamp(18px, 1.3vw, 30px) clamp(20px, 1.7vw, 36px);
    gap: clamp(16px, 1.3vw, 28px);
}

.entry-title {
    font-size: clamp(16px, 1.1vw, 21px);
}

.entry-desc {
    font-size: clamp(12.5px, 0.85vw, 15px);
}

/* 页脚 */
.host-footer {
    padding-top: clamp(24px, 1.8vw, 40px);
    font-size: clamp(12.5px, 0.8vw, 14px);
}

/*
 * 后台壳层：字号刻度本身已经改成 clamp（见「后台设计基座」那节的 --fs-*），
 * 这里只补卡片留白。基座那几条带 :not(.host-home-preview *) 的选择器权重更高，
 * 这里必须跟上同样的写法，否则压不过它。
 */
.admin-shell .card:not(.host-home-preview *) {
    padding: clamp(24px, 1.6vw, 34px);
}

.admin-shell .stat-card:not(.host-home-preview *) {
    padding: clamp(16px, 1.15vw, 24px) clamp(24px, 1.6vw, 34px);
}

@media (max-width: 900px) {
    .admin-shell .header {
        padding: 0 14px;
    }

    .admin-shell #menu-toggle {
        display: inline-flex;
    }
}


/* ---------- 网页小工具：卡片墙 ---------- */
.wt-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 16px;
}

.wt-card {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 18px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--bg-1);
    text-decoration: none;
    color: var(--text-1);
    transition: border-color .16s, transform .16s, box-shadow .16s;
}

.wt-card:hover {
    border-color: var(--primary);
    transform: translateY(-2px);
    box-shadow: var(--shadow-sm);
}

.wt-icon {
    width: 40px;
    height: 40px;
    border-radius: 10px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--primary-soft);
    color: var(--primary);
}

.wt-name {
    font-weight: 600;
    font-size: 15px;
}

.wt-desc {
    color: var(--text-3);
    font-size: 13px;
    line-height: 1.6;
    min-height: 42px;
}

.wt-go {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    color: var(--primary);
    font-size: 13px;
}

.wt-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 0;
    border-bottom: 1px solid var(--border);
}

.wt-row:last-child {
    border-bottom: none;
}

.wt-row-edit {
    display: flex;
    flex-direction: column;
    gap: 8px;
    flex: 1;
}
