/* ==========================================================================
   赣州市球迷协会 · PHP 后台样式（原生 CSS，零构建、零框架）

   ⚠️ 设计令牌**逐字取自线上前端编译产物**，改之前请先读
      `/memories/repo/original-admin-shell-spec.md`（含提取方法与出处）。
      权威来源：/www/wwwroot/ganzhou/assets/index-9e4pCPwh.css（Tailwind v4 产物）
   ========================================================================== */

:root {
    /* ==========================================================================
       DESIGN.md Token 层（全站 UI 唯一真值，来源 DESIGN.md §1–§5）
       ⚠️ 新代码一律用这一层，禁止硬编码颜色/间距/圆角；旧变量见下半段的迁移标注
       ========================================================================== */
    /* 色彩 · 主色（品牌红） */
    --c-primary: #C81623;
    --c-primary-hover: #A8121C;
    --c-primary-active: #8C0F17;
    --c-primary-light: #FDF2F3;
    /* 色彩 · 中性 */
    --c-bg: #FAF8F5;
    --c-surface: #FFFFFF;
    --c-border: #E5E7EB;
    --c-border-strong: #D1D5DB;
    /* 色彩 · 文字 */
    --c-text: #1F2937;
    --c-text-sub: #6B7280;
    --c-text-muted: #9CA3AF;
    --c-text-invert: #FFFFFF;
    /* 色彩 · 功能 */
    --c-success: #10B981;
    --c-warning: #F59E0B;
    --c-danger: #EF4444;
    --c-info: #3B82F6;
    /* 色彩 · 遮罩（第 0 步裁决③新增） */
    --c-overlay: rgba(0, 0, 0, .4);
    --c-overlay-heavy: rgba(0, 0, 0, .85);

    /* ---------- 功能色浅底 + 中性色扩展（DESIGN §1） ---------- */
    --c-bg-subtle:       #F9FAFB;   /* 次级底：表头/区块底/悬停 */
    --c-bg-muted:        #F3F4F6;   /* 三级底：分隔线、遮罩、操作 chip 底 */
    --c-text-mid:        #4B5563;   /* 正文与次要文字之间的中间层 */
    --c-success-light:   #ECFDF5;   --c-success-border: #A7F3D0;   --c-success-dark: #047857;
    --c-warning-light:   #FFFBEB;   --c-warning-border: #FDE68A;   --c-warning-dark: #B45309;
    --c-danger-light:    #FEF2F2;   --c-danger-border:  #FECACA;   --c-danger-dark:  #B91C1C;
    --c-info-light:      #EFF6FF;   --c-info-border:    #BFDBFE;   --c-info-dark:    #1D4ED8;

    /* 间距（4 的倍数） */
    --sp-1: 4px;
    --sp-2: 8px;
    --sp-3: 12px;
    --sp-4: 16px;
    --sp-6: 24px;
    --sp-8: 32px;
    --sp-12: 48px;

    /* 字体（字号 / 行高 / 字重成对） */
    --font-family: -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif;
    --fs-h1: 20px;   --lh-h1: 1.4;   --fw-h1: 700;
    --fs-h2: 16px;   --lh-h2: 1.5;   --fw-h2: 600;
    --fs-body: 14px; --lh-body: 1.6; --fw-body: 400;
    --fs-sm: 12px;   --lh-sm: 1.5;   --fw-sm: 400;

    /* 圆角 */
    --r-sm: 4px;
    --r-md: 6px;
    --r-lg: 8px;
    --r-xl: 12px;
    --r-full: 9999px;

    /* 阴影（DESIGN §5） */
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, .04);
    --shadow-md: 0 2px 8px rgba(0, 0, 0, .06);
    --shadow-lg: 0 8px 24px rgba(0, 0, 0, .08);

    /* ==========================================================================
       以下为旧变量（原版像素口径）。值相同者已做零视觉变化的别名；
       值不同者**保留原值**，在对应批次内迁移后删除，避免一次性改全站。
       ✅ P1-d（全站推，2026-10-01）后：--text / --text-muted / --border 的**全站引用已清零**
       （203 处 → var(--c-text) / var(--c-text-sub|muted) / var(--c-border)），
       下面三条定义**已退役**、仅作兜底与回滚参考，**新代码禁止使用**。
       ========================================================================== */
    --brand: var(--c-primary);             /* 同值 ✓ 已别名 */
    --brand-dark: #a30d25;                 /* 待迁移 → var(--c-primary-hover) #A8121C */
    --brand-soft: rgba(200, 22, 35, .1);   /* 待迁移 → var(--c-primary-light) #FDF2F3（语义不同，需逐处确认） */

    --bg-page: var(--c-bg);                /* 同值 ✓ 已别名 */
    --bg: var(--bg-page);
    --panel: var(--c-surface);             /* 同值 ✓ 已别名 */
    --text: #2A2020;                       /* ⚠️ 已退役（P1-d 全站推，28 处 → var(--c-text)）*/
    --text-muted: #8a7f7d;                 /* ⚠️ 已退役（P1-d 全站推，68 处 → var(--c-text-sub) 32 / var(--c-text-muted) 36）*/
    --border: #ece7e4;                     /* ⚠️ 已退役（P1-d 全站推，91 处 → var(--c-border)）*/

    --ok: #0fa84e;                         /* 待迁移 → var(--c-success) #10B981 */
    --warn: #d98600;                       /* 待迁移 → var(--c-warning) #F59E0B */
    --bad: #dc2626;                        /* 待迁移 → var(--c-danger) #EF4444 */

    --radius: 10px;                        /* 待迁移 → --r-md(6) 或 --r-lg(8)；10px 不在 token 内 */
    --radius-xl: var(--r-xl);              /* 同值 ✓ 已别名 */
    /* 原版像素口径阴影（值不变）—— 已重命名为 legacy 以避让 DESIGN 同名 token；13 处引用同步改名 */
    --shadow-legacy-sm: 0 1px 2px rgba(42, 32, 32, .06);
    --shadow: 0 1px 2px rgba(42, 32, 32, .06), 0 1px 3px rgba(42, 32, 32, .08);
    /* 原版弹窗 / 下拉专用抬高阴影（P1-c 起已全部切到 DESIGN --shadow-sm/lg，此变量已无引用；
       保留值仅作回滚参考）*/
    /* --shadow-legacy-lg: 0 10px 24px -8px #0000002e, 0 2px 6px -2px #0000001f; */

    --sidebar-w: 200px;                    /* DESIGN §7.1（原版 lg:w-[180px]，以 DESIGN 为准；第 2 批已切）*/
    --sidebar-w-collapsed: 72px;
    --topbar-h: 56px;                      /* DESIGN §7.1；.brand（侧栏品牌行）与 .topbar 共用，两行保持对齐 */
}

* { box-sizing: border-box; }

html, body {
    margin: 0;
    padding: 0;
    background: var(--bg);
    color: var(--c-text);
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC",
                 "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Arial, sans-serif;
    font-size: 14px;
    line-height: 1.6;
}

a { color: var(--brand); text-decoration: none; }
a:hover { text-decoration: underline; }
code { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 12px; }
.muted { color: var(--c-text-sub); }
.spacer { flex: 1; }

/* ---------- 布局 ---------- */
.layout { display: flex; min-height: 100vh; }

.sidebar {
    /* 原版：`flex flex-col bg-white border-r border-gray-200`，桌面 lg:w-[180px] */
    width: var(--sidebar-w);
    flex: 0 0 var(--sidebar-w);
    background: var(--c-surface);
    border-right: 1px solid var(--c-border);
    color: var(--c-text-mid);
    display: flex;
    flex-direction: column;
    position: sticky;
    top: 0;
    height: 100vh;
    transition: width .3s ease-in-out, flex-basis .3s ease-in-out;
}

/* 折叠态（原版 w-[72px]）：只留图标，文字与底部信息隐藏 */
.layout.is-collapsed .sidebar { width: var(--sidebar-w-collapsed); flex-basis: var(--sidebar-w-collapsed); }
.layout.is-collapsed .brand { justify-content: center; padding: 0; }
.layout.is-collapsed .brand-text,
.layout.is-collapsed .nav-text,
.layout.is-collapsed .who,
.layout.is-collapsed .side-logout { display: none; }
.layout.is-collapsed .nav-item { justify-content: center; padding: 10px 0; gap: 0; }

.brand {
    display: flex;
    align-items: center;
    gap: 12px;
    height: var(--topbar-h);
    padding: 0 16px;
    border-bottom: 1px solid var(--c-bg-muted);
    flex-shrink: 0;
}
/* 原版：w-9 h-9 rounded-xl 品牌色渐变 + 阴影 */
.brand-mark {
    width: 36px; height: 36px;
    flex: 0 0 36px;
    display: grid; place-items: center;
    background: linear-gradient(135deg, var(--brand), var(--brand-dark));
    color: var(--c-text-invert);
    border-radius: var(--r-xl);
    font-weight: 700;
    font-size: 16px;
    box-shadow: 0 4px 6px -1px rgba(200, 22, 35, .2);
    overflow: hidden;
}
.brand-mark img { width: 100%; height: 100%; object-fit: cover; }
.brand-text { display: flex; flex-direction: column; overflow: hidden; }
.brand-name { font-weight: 700; color: var(--c-text); font-size: 14px; line-height: 1.25;
              overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.brand-sub { font-size: 10px; color: var(--c-text-muted); line-height: 1.3; }

/* ---------- 侧边栏导航：扁平单列（对齐旧站 admin.tsx 的一级菜单） ----------
   ⚠️ 这里刻意不做「一级分类 + 二级面板」那种双列侧栏：
      旧站是扁平一级菜单，同组数据靠**页面内的 Tab** 切换（见 app/views/admin/resource/index.php）。
      菜单声明在 config/admin_nav.php，解析在 App\Services\AdminNav。 */
.nav {
    flex: 1;
    overflow-y: auto;
    padding: 12px 8px;
    scrollbar-width: none;                 /* 原版隐藏菜单滚动条 */
}
.nav::-webkit-scrollbar { display: none; }
/* 原版：w-full flex items-center rounded-xl px-3 py-2.5 gap-3 */
.nav-item {
    position: relative;
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 2px;
    padding: 10px 12px;
    border-radius: var(--r-xl);
    color: var(--c-text-mid);
    font-size: 14px;
    line-height: 1.4;
    transition: background .2s, color .2s, box-shadow .2s;
}
.nav-item:hover { background: var(--c-bg-subtle); color: var(--c-text); text-decoration: none; }
/* 原版选中态：bg-[--color-primary]/10 text-[--color-primary] font-semibold shadow-sm */
.nav-item.is-active {
    background: var(--brand-soft);
    color: var(--brand);
    font-weight: 600;
    box-shadow: var(--shadow-sm);
}
.nav-item.is-active .nav-ico { color: var(--brand); }
/* 原版选中态右侧竖条：w-1 h-5 rounded-full bg-[--color-primary] */
.nav-item.is-active::after {
    content: '';
    position: absolute;
    right: 2px;
    top: 50%;
    transform: translateY(-50%);
    width: 4px;
    height: 20px;
    border-radius: 999px;
    background: var(--brand);
}
.nav-ico {
    flex: 0 0 20px;
    text-align: center;
    color: var(--c-text-muted);
    transition: color .2s;
}
.nav-item:hover .nav-ico { color: var(--c-text-mid); }
.nav-text { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* 主菜单与「运维扩展页」之间的分隔线（仍是一级菜单，只是视觉分组） */
.nav-sep {
    height: 1px;
    margin: 10px 4px;
    background: var(--c-bg-muted);
}

.sidebar-foot {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 12px;
    border-top: 1px solid var(--c-bg-muted);
    flex-shrink: 0;
}
/* 折叠按钮（原版：w-full p-2 rounded-lg text-gray-400） */
.side-collapse {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    padding: 8px;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: var(--c-text-muted);
    font-size: 14px;
    line-height: 1;
    cursor: pointer;
    transition: background .2s, color .2s;
}
.side-collapse:hover { background: var(--c-bg-subtle); color: var(--c-text-mid); }

/* 当前管理员（原版：头像渐变圆 + 姓名 + 角色） */
.who {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 6px 4px;
    border-radius: var(--r-xl);
    min-width: 0;
}
.who-avatar {
    width: 32px; height: 32px;
    flex: 0 0 32px;
    display: grid; place-items: center;
    border-radius: 999px;
    background: linear-gradient(135deg, #fbbf24, #f97316);
    color: var(--c-text-invert);
    font-size: 12px;
    font-weight: 700;
}
.who-meta { flex: 1; min-width: 0; }
.who-name { color: var(--c-text-mid); font-size: 14px; font-weight: 500;
            overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.who-role { font-size: 10px; color: var(--c-text-muted);
            overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 原版退出：text-red-400 hover:bg-red-50 text-xs */
.side-logout {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    width: 100%;
    padding: 6px;
    border-radius: 8px;
    color: #f87171;
    font-size: 12px;
    transition: background .2s, color .2s;
}
.side-logout:hover { background: var(--c-danger-light); color: var(--c-danger); text-decoration: none; }

.main {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    overflow: hidden;                      /* 原版：主区不滚，内容区自己滚 */
}

.topbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    height: var(--topbar-h);
    padding: 0 16px;
    background: var(--c-surface);
    border-bottom: 1px solid var(--c-border);
    flex-shrink: 0;
    z-index: 30;
}
@media (min-width: 1024px) { .topbar { padding: 0 24px; } }

/* 面包屑（原版：首页 / 当前页） */
.crumb { display: flex; align-items: center; gap: 8px; font-size: 14px; min-width: 0; }
.crumb-home { color: var(--c-text-muted); }
.crumb-sep { color: var(--c-border-strong); }
.crumb-cur {
    color: var(--c-text-mid);
    font-weight: 500;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.topbar-left { display: flex; align-items: center; gap: 12px; min-width: 0; }
.topbar-right { display: flex; align-items: center; gap: 12px; }
.pill {
    background: var(--c-bg-muted);
    color: var(--c-text-sub);
    border-radius: 999px;
    padding: 2px 10px;
    font-size: 12px;
}

.content {
    flex: 1;
    /* 自身滚动条也预留槽（与 html 的一致，切页不横向抖动） */
    overflow-y: auto;
    padding: 24px 24px 40px;
    scrollbar-gutter: stable;
}   /* 第 2 批：顶 20→24，对齐 §7.1 */

/* ---------------------------------------------------------------------------
   内容区最大宽度（DESIGN §7.1：1200px 居中）
   ───────────────────────────────────────────────────────────────────────────
   表单 / 详情页限宽居中；**列表页（表格列数多）保持内容驱动宽度**，不受 1200px 限制。

   「列表页」不靠页面类型判断，用 :has() 自动识别「有没有宽表格」：
   `.table-wrap` 是全站表格的横向滚动容器（35 个视图里有），表单页都没有 → 恰好等价。
   ⚠️ 整块包在 @supports 里：不支持 :has() 的旧 WebView（微信内置等）会整块失效、
      保持「不限宽」的旧行为 —— 宁可保持现状，也不能把列表页误限宽。
   ⚠️ 例外：媒体库是瓦片网格（.media-grid，1400px 起 6 列；media/index.php:450），
      不是宽表格，但限宽会让 6 列断点永远达不到 → 单独免限宽。
   ⚠️ 写法要点：**用 :not(:has(...)) 只命中需要限宽的页，被豁免的页一个字节都不碰**。
      若写成「.content 限宽 + 豁免页 max-width:none」，豁免页虽然宽度恢复，但
      `margin-inline:auto` 仍在 —— flex 列容器里 auto 外边距会让该 flex item 由
      stretch 变成 fit-content 收缩（实测赛事列表从 1705px 缩成 672px 并被居中，属回归）。
   --------------------------------------------------------------------------- */
@supports selector(:has(*)) {
    /* 只对「没有宽表格、也不是媒体网格」的页（表单 / 详情 / 设置）限宽居中
       ⚠️ 例外：带 `.page-full-width` 包装类的页 = 免限宽（占满侧栏外的全部空间）。
          目前 2 处：
            · 系统设置 /admin/settings?tab=*  —— 6 个 Tab 要与其它模块页**逐像素同宽**；
            · 仪表盘 /admin                  —— 同样的诉求。
          包装类见 app/views/admin/settings/index.php 与 app/views/admin/dashboard.php。
          ❗不加包装类就会被本规则命中，再被 `margin-inline:auto` 在 flex column 容器里
            收缩成 fit-content（实测仪表盘 1024 / 系统设置 815），这是历史上两者偏窄的原因。
          ⚠️ 只加这一个排除项，不改本规则其它部分，也不动 .content 基础规则 →
          其它模块页零变化。 */
    .content:not(:has(.table-wrap)):not(:has(.media-grid)):not(:has(.page-full-width)):not(:has(.sm-page-head)) {
        max-width: 1200px;
        margin-inline: auto;
    }
}

/* ---------- 窄屏：侧栏改为抽屉（原版 fixed + bg-black/50 遮罩） ---------- */
.topbar-left .nav-toggle { display: inline-flex; }
@media (min-width: 1024px) {
    .topbar-left .nav-toggle { display: none; }
}
@media (max-width: 1023px) {
    .sidebar {
        position: fixed;
        inset: 0 auto 0 0;
        z-index: 50;
        width: 320px;
        flex-basis: 320px;
        transform: translateX(-100%);
        box-shadow: var(--shadow-lg);
    }
    .sidebar.is-open { transform: translateX(0); }
    .sidebar.is-open ~ .main::before {
        content: '';
        position: fixed;
        inset: 0;
        background: var(--c-overlay);
        z-index: 40;
    }
}

/* ---------- 卡片 ---------- */
/* DESIGN §6.3：卡片背景 --c-surface / 边框 --c-border / 圆角 --r-lg / **默认无阴影**
   （容器类卡片不加 hover 阴影；批量 18px 不符合 §8-3 的 4 的倍数 → 16px） */
.card {
    background: var(--c-surface);
    border: 1px solid var(--c-border);
    border-radius: var(--r-lg);
    box-shadow: none;
    margin-bottom: var(--sp-4);
    overflow: hidden;
}
.card-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: var(--sp-4);
    border-bottom: 1px solid var(--c-border);
}
.card-title { margin: 0; font-size: var(--fs-h2); font-weight: var(--fw-h2); }

/* ---------- 统计卡片 ---------- */
.stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: var(--sp-4);
    margin-bottom: var(--sp-4);
}
.stat-card {
    background: var(--c-surface);
    border: 1px solid var(--c-border);
    border-radius: var(--r-lg);
    padding: var(--sp-4);
    box-shadow: none;
}
.stat-label { color: var(--c-text-sub); font-size: 13px; }
.stat-value { font-size: 26px; font-weight: 700; margin: 4px 0 2px; }
.stat-foot { color: var(--c-text-muted); font-size: 12px; }

/* ---------- 表格 ---------- */
.table-wrap { overflow-x: auto; }
.table { width: 100%; border-collapse: collapse; }
/* 列表表格（DESIGN §6.4）：行高 48px、单元格内边距 12/16。
   `.is-plain` 是紧凑表（members/checkins、members/points），保持原样不套 48px。
   如需更密的列表，可另加 `.table--compact`（40px）—— 第 3 批不做，等实际需要再加。 */
.table:not(.is-plain) th, .table:not(.is-plain) td {
    padding: var(--sp-3) var(--sp-4);
    height: 48px;
    vertical-align: middle;
    text-align: left;
    border-bottom: 1px solid var(--c-border);
    white-space: nowrap;
}
.table thead th {
    background: var(--c-bg);
    color: var(--c-text-sub);
    font-weight: 600;
    font-size: var(--fs-sm);
}
.table tbody tr:hover { background: var(--c-bg); }

/* 列表表格统一 48px 行高后，弹窗里的「预检 / 预览」表格仍保持紧凑（第 3 批）
   这三处表格是 admin.js / members-settings 动态拼出的预览，不属于列表页。 */
.imp-preview-wrap table.table th, .imp-preview-wrap table.table td,
.ps-preview table.table th, .ps-preview table.table td,
.lv-preview table.table th, .lv-preview table.table td {
    height: auto;
    padding: var(--sp-1) var(--sp-2);
}
.table .empty { text-align: center; color: var(--c-text-muted); padding: 32px 0; }
.th-actions { width: 1%; }
.th-actions .inline { display: inline; }

/* ---------- 标签 ---------- */
.tag {
    display: inline-block;
    /* DESIGN §6.6：高 22px / 内边距 0 8px / 圆角 --r-sm（不再是胶囊形） */
    height: 22px;
    line-height: 22px;
    padding: 0 var(--sp-2);
    border-radius: var(--r-sm);
    font-size: var(--fs-sm);
}
.tag-ok { background: var(--c-success-light); color: var(--c-success-dark); }
.tag-warn { background: var(--c-warning-light); color: var(--c-warning-dark); }
.tag-bad { background: var(--c-danger-light); color: var(--c-danger-dark); }
.tag-muted { background: var(--c-bg-muted); color: var(--c-text-sub); }

/* ---------- 表单 ---------- */
.toolbar {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 14px 16px;
    border-bottom: 1px solid var(--c-border);
    flex-wrap: wrap;
}
.form-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: 14px;
    padding: 18px 16px;
}
.field { display: flex; flex-direction: column; gap: 6px; }
.field-full { grid-column: 1 / -1; }
.field-label { font-size: 13px; color: var(--c-text-mid); font-weight: 500; }
.field-label em { color: var(--c-danger); font-style: normal; }
.field-hint { font-size: 12px; color: var(--c-text-sub); }
.field-error { font-size: 12px; color: var(--c-danger); }

.input {
    width: 100%;
    padding: 8px 11px;
    border: 1px solid var(--c-border);
    border-radius: 8px;
    font-size: 14px;
    color: var(--c-text);
    background: var(--c-surface);
    font-family: inherit;
}
.input:focus {
    outline: none;
    border-color: var(--brand);
    box-shadow: 0 0 0 3px rgba(200, 16, 46, .1);
}
.select { cursor: pointer; }
.textarea { resize: vertical; min-height: 72px; }

.form-actions {
    display: flex;
    gap: 10px;
    padding: 16px;
    border-top: 1px solid var(--c-border);
    background: var(--c-bg-subtle);
}
/*
 * 弹窗里的表单底部按钮：与旧版弹窗一致 —— **右对齐**，「取消」在左、「保存」在右
 * （admin.events.tsx:1776-1779 的 `flex justify-end gap-3 px-5 py-3 border-t bg-gray-50`）。
 * 只作用于 .modal-body 内，页面级表单的按钮位置不变。
 */
.modal-body .form-actions { justify-content: flex-end; }

/* 表单底部的实时汇总卡（旧版赛事弹窗远征区的「💰 远征费用预估汇总」） */
.res-exp-sum {
    margin: 0 16px 14px;
    padding: 10px 12px;
    background: var(--c-surface);
    border: 1px solid var(--c-warning-border);
    border-radius: 10px;
}
.res-exp-sum-h { margin: 0 0 4px; font-size: 12px; font-weight: 600; color: var(--c-text-mid); }
.res-exp-sum-b { margin: 0; font-size: 12px; color: var(--c-text-sub); line-height: 1.7; }

/* =========================================================================
   弹窗表单的「旧版像素口径」（只作用于 .modal-body，页面级表单不受影响）
   ─────────────────────────────────────────────────────────────────────────
   旧版每个编辑弹窗都是同一套：
     · 内容区 p-5（20px）+ space-y-3（行间隔 12px）
     · 分区标题 = <h4 text-xs font-semibold text-gray-400 uppercase border-b pb-1.5>
       （**不是带边框的 fieldset 盒子**）
     · 字段 = 标签 text-xs font-medium text-gray-500 mb-1 + 控件
       border-gray-200 rounded-lg px-3 py-1.5 text-sm
   ========================================================================= */
/* ⚠️ 此处原有 `.modal-body { padding: 20px; }`（旧版 p-5 口径）——
   与下方主弹窗区的 `.modal-body` 同选择器、同性特异性，被后者覆盖成**死值**，
   已于 DESIGN.md 第 1 步（清理重复定义）删除；内边距统一到唯一基座（桌面 24px / 移动 16px）。
   以下 12 条后代规则原样保留，不受影响。 */
.modal-body .form-fieldset { border: 0; margin: 0 0 12px; padding: 0; }
.modal-body .form-fieldset > legend {
    width: 100%;
    margin: 0 0 12px;
    padding: 0 0 6px;
    border-bottom: 1px solid var(--c-bg-muted);
    font-size: 12px;
    font-weight: 600;
    color: var(--c-text-muted);
    text-transform: uppercase;
    letter-spacing: .025em;
}
.modal-body .form-grid { gap: 12px; padding: 0 0 12px; }
.modal-body .form-fieldset .form-grid { padding: 0 0 12px; }
.modal-body .field { gap: 4px; }
.modal-body .field-label { font-size: 12px; font-weight: 500; color: var(--c-text-sub); }
.modal-body .input { padding: 6px 12px; font-size: 14px; }
/* 单图字段必须一行放下：[输入框][缩略图][选择][✕]（旧版 ImageInput 就是一行） */
.modal-body .res-img .check-row { flex-wrap: nowrap; }
.modal-body .res-img .check-row .input { min-width: 0; }

/* =========================================================================
   旧版弹窗的「块 / 小卡 / 单选组 / 地点查找」样式
   ========================================================================= */
/* 地点：输入框 + 查找 + 定位 同行（旧版 VenueLocator） */
.fld-inline { display: flex; align-items: center; gap: 8px; }
.fld-inline .input { flex: 1 1 auto; min-width: 0; }
.fld-geo-find { background: var(--c-info) !important; border-color: var(--c-info) !important; color: var(--c-text-invert) !important; }
.fld-geo-find:hover { background: var(--c-info) !important; border-color: var(--c-info-border) !important; }
.fld-geo-find[disabled] { opacity: .6; }
.fld-geo-msg { margin: 6px 0 0; font-size: 11px; color: var(--c-text-muted); }
/* 灰底参数块（票务设置 / 签到打卡）——旧版 bg-gray-50 rounded-lg p-3 */
.fld-box { padding: 12px; border-radius: 10px; margin-bottom: 12px; }
.fld-box .form-grid { padding: 0; }
.fld-box-gray { background: var(--c-bg-subtle); }
/* 白底盒（远征的交通 / 其它费用） */
.fld-box-white { background: var(--c-surface); border: 1px solid var(--c-warning-border); }
.fld-box-orange { background: rgba(255, 247, 237, .6); border: 1px solid var(--c-warning-border); border-radius: 12px; }
.fld-box-title { margin: 0 0 8px; font-size: 12px; font-weight: 600; color: var(--c-text-sub); }
/* 并排小卡（住宿 单间/标间、餐饮 简餐/快餐）——旧版 grid grid-cols-2 gap-3 */
.fld-cards { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin-bottom: 12px; }
.fld-card { padding: 8px; border-radius: 10px; border: 1px solid var(--c-border); }
.fld-card .form-grid { padding: 0; }
.fld-card-green { background: rgba(240, 253, 244, .5); border-color: #bbf7d0; }
.fld-card-blue  { background: rgba(239, 246, 255, .5); border-color: var(--c-info-border); }
.fld-card-red   { background: rgba(254, 242, 242, .5); border-color: var(--c-danger-border); }
.fld-card-amber { background: rgba(255, 251, 235, .5); border-color: var(--c-warning-border); }
/* 单选组（购票权限：全部可购 / 限定等级 / 关闭购票） */
.fld-radios { display: flex; flex-wrap: wrap; gap: 16px; padding-top: 4px; }
.fld-radio { display: inline-flex; align-items: center; gap: 6px; font-size: 14px; cursor: pointer; }
.fld-radio input { width: 14px; height: 14px; accent-color: var(--brand); }
/* 等级标签多选（旧版「限定等级」下的一排标签，用等级自身颜色） */
.fld-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.fld-chip {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 4px 10px; border-radius: 999px;
    border: 1px solid var(--c-border); background: var(--c-surface);
    font-size: 12px; color: var(--c-text-mid); cursor: pointer;
}
.fld-chip input { display: none; }
.fld-chip.is-on {
    background: var(--chip-c, var(--brand));
    border-color: var(--chip-c, var(--brand));
    color: var(--c-text-invert);
}
/* 场馆地图选点（旧版 VenueMapPicker：点击/拖拽标记） */
.fld-map {
    height: 260px; margin-top: 10px;
    border: 1px solid var(--c-border); border-radius: 10px;
    background: var(--c-bg-subtle); overflow: hidden;
}
/* 打卡核销人员选择器（旧版 verifier-picker：标签 + 搜索 + 结果） */
.fld-verifier { display: flex; flex-direction: column; gap: 6px; }
.fld-vf-list {
    display: flex; flex-wrap: wrap; gap: 6px; align-items: center;
    min-height: 34px; padding: 6px 8px;
    border: 1px solid var(--c-border); border-radius: 8px; background: var(--c-surface);
}
.fld-vf-empty { font-size: 12px; color: var(--c-border-strong); }
.fld-vf-tag {
    display: inline-flex; align-items: center; gap: 4px;
    background: var(--c-danger-light); color: var(--c-primary);
    font-size: 12px; font-weight: 500; padding: 3px 6px; border-radius: 6px;
}
.fld-vf-tag button { border: 0; background: none; color: inherit; cursor: pointer; font-size: 13px; line-height: 1; }
.fld-vf-search { display: flex; align-items: center; gap: 8px; }
.fld-vf-state { font-size: 11px; color: var(--c-text-muted); }
.fld-vf-results {
    border: 1px solid var(--c-border); border-radius: 8px; background: var(--c-surface);
    max-height: 220px; overflow: auto;
}
.fld-vf-item {
    display: flex; align-items: center; gap: 8px; width: 100%;
    padding: 7px 10px; border: 0; border-bottom: 1px solid var(--c-bg-muted);
    background: var(--c-surface); font-size: 13px; text-align: left; cursor: pointer;
}
.fld-vf-item:last-child { border-bottom: 0; }
.fld-vf-item:hover { background: #faf9f8; }
.fld-vf-item span { color: var(--c-text-muted); font-size: 12px; }
.fld-vf-item em { margin-left: auto; font-style: normal; font-size: 12px; color: var(--brand); }
.notice {
    margin: 0 16px 16px;
    padding: 10px 12px;
    background: var(--c-warning-light);
    border-left: 3px solid var(--c-warning);
    border-radius: 6px;
    color: var(--c-warning-dark);
    font-size: 13px;
}

/* ---------- 按钮 ---------- */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    /* DESIGN §6.1：高 36px / 内边距 0 16px / 圆角 --r-md */
    height: 36px;
    padding: 0 var(--sp-4);
    border: 1px solid transparent;
    border-radius: var(--r-md);
    font-size: var(--fs-body);
    font-family: inherit;
    cursor: pointer;
    background: var(--c-bg-muted);
    color: var(--c-text);
    white-space: nowrap;
}
.btn:hover { text-decoration: none; }
.btn-primary { background: var(--brand); color: var(--c-text-invert); }
.btn-primary:hover { background: var(--brand-dark); }
.btn-ghost { background: var(--c-surface); border-color: var(--c-border); color: var(--c-text); }
/* DESIGN §6.1：次按钮 hover 时边框变主色 */
.btn-ghost:hover { background: var(--c-surface); border-color: var(--c-primary); }
.btn-danger { background: var(--c-surface); border-color: var(--c-danger-border); color: var(--c-danger); }
.btn-danger:hover { background: var(--c-danger-light); }
.btn-sm { height: 28px; padding: 0 var(--sp-3); font-size: var(--fs-sm); border-radius: var(--r-md); }
.btn-block { width: 100%; }

/* ---------- 提示条 ---------- */
.alert {
    margin: 0 24px 14px;
    padding: 10px 14px;
    border-radius: 8px;
    font-size: 13px;
}
.alert-success { background: var(--c-success-light); color: var(--c-success-dark); }
.alert-error { background: var(--c-danger-light); color: var(--c-danger-dark); }
.alert-warn { background: var(--c-warning-light); color: var(--c-warning-dark); }
.alert-info { background: var(--c-info-light); color: var(--c-info-dark); }

/* ---------- 分页 ---------- */
.pager {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 12px 16px;
    border-top: 1px solid var(--c-border);
    flex-wrap: wrap;
}
.pager-btns { display: flex; gap: 8px; }

/* 分页条左半：共 N 条 + 「N 条/页」下拉（对齐原版 DataTable 第 484-504 行） */
.pager-left { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.pager-left b { color: var(--c-text); }
.pager-size { display: inline-flex; align-items: center; gap: 6px; }
.pager-size label { display: inline-flex; align-items: center; gap: 6px; color: var(--c-text-sub); }
.pager-size select {
    /* 与页码同高 32px（§8-3：不用 7px 圆角 / 非 4 倍数尺寸） */
    height: 32px;
    padding: 0 var(--sp-2);
    font: inherit;
    font-size: var(--fs-sm);
    color: var(--c-text);
    background: var(--c-surface);
    border: 1px solid var(--c-border);
    border-radius: var(--r-md);
    cursor: pointer;
}
.pager-size select:focus { outline: none; border-color: var(--brand); }

/* 页码：最多 5 个，当前页高亮 */
.pager-pages { display: flex; align-items: center; gap: 6px; }
.pager-page {
    min-width: 32px;
    height: 32px;
    padding: 0 var(--sp-2);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: var(--fs-sm);
    color: var(--c-text);
    background: var(--c-surface);
    border: 1px solid var(--c-border);
    border-radius: var(--r-md);
}
.pager-page:hover { background: var(--c-bg); text-decoration: none; }
.pager-page.is-on {
    color: var(--c-text-invert);
    background: var(--brand);
    border-color: var(--brand);
    font-weight: 600;
}
.pager-btns .is-disabled { opacity: .45; cursor: not-allowed; }

/* ---------- 表头排序（对齐原版 DataTable 的可点表头 + 三角指示） ---------- */
.table thead th.is-sortable { padding: 0; }
.table thead th.is-sortable > a {
    display: flex;
    align-items: center;
    gap: 4px;
    padding: var(--sp-3) var(--sp-4);
    color: inherit;
    white-space: nowrap;
}
.table thead th.is-sortable > a:hover { color: var(--brand); text-decoration: none; }
.table thead th.is-sorted > a { color: var(--brand); }
.sort-ico { font-size: 10px; line-height: 1; opacity: .5; }
.table thead th.is-sorted .sort-ico { opacity: 1; }

/* ---------- 登录页 ----------
   逐字对齐参照 src/routes/admin.tsx:389-484 的未登录分支：
   红色渐变全屏底 + 6 颗琥珀装饰星 + 居中站名/标语 + 白色 16px 圆角卡片。
   Tailwind 值换算：max-w-sm=384px / text-4xl=36px / font-black=900 /
   rounded-2xl=16px / p-6=24px / space-y-4=16px / py-3=12px。 */
.login-page {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 16px;
    position: relative;
    overflow: hidden;
    background: linear-gradient(to bottom right, #D3222A, #B91C22, #8B0A1A);
}

/* 6 颗装饰五角星（原版 6 个绝对定位的 <Star/>，位置/尺寸/旋转内联在视图里） */
.lg-stars { position: absolute; inset: 0; pointer-events: none; }
.lg-star {
    position: absolute;
    display: block;
    line-height: 0;
    color: #fcd34d;                        /* amber-300 */
}
.lg-star svg { width: 100%; height: 100%; display: block; fill: currentColor; }

.lg-box {
    position: relative;
    z-index: 1;
    width: 100%;
    max-width: 384px;
    display: flex;
    flex-direction: column;
    align-items: center;
}

.lg-site {
    margin: 0 0 16px;
    font-size: 36px;
    font-weight: 900;
    line-height: 1.2;
    text-align: center;
    color: var(--c-text-invert);
    letter-spacing: .05em;                 /* tracking-wider */
    filter: drop-shadow(0 4px 3px rgba(0, 0, 0, .09)) drop-shadow(0 2px 2px rgba(0, 0, 0, .06));
}

.lg-slogan-row {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 40px;
    color: #fcd34d;
}
.lg-rule { width: 48px; height: 1px; background: rgba(252, 211, 77, .6); flex: 0 0 48px; }
.lg-slogan { font-size: 16px; font-weight: 500; letter-spacing: .1em; white-space: nowrap; }

/* 白色登录卡：shadow-xl + shadow-black/20 */
.lg-form {
    width: 100%;
    padding: 24px;
    background: var(--c-surface);
    border-radius: 16px;
    box-shadow: 0 20px 25px -5px rgba(0, 0, 0, .2), 0 8px 10px -6px rgba(0, 0, 0, .2);
}
/* space-y-4：非首个子项统一上间距 */
.lg-form > * + * { margin-top: 16px; }

.lg-label {
    display: block;
    margin-bottom: 6px;
    font-size: 12px;
    font-weight: 500;
    color: var(--c-text-sub);                        /* gray-500 */
}
.lg-input {
    width: 100%;
    padding: 12px 16px;
    border: 1px solid var(--c-border);             /* gray-200 */
    border-radius: 12px;
    font-size: 14px;
    font-family: inherit;
    color: var(--c-text);
    background: var(--c-surface);
    outline: none;
    transition: border-color .15s, box-shadow .15s;
}
.lg-input:focus { border-color: var(--c-danger); box-shadow: 0 0 0 2px rgba(239, 68, 68, .1); }
.lg-input:disabled { opacity: .5; }

.lg-pwd { position: relative; }
.lg-input.is-pwd { padding-right: 40px; }   /* 给右侧眼睛留位（pr-10） */
.lg-eye {
    position: absolute;
    right: 12px;
    top: 50%;
    transform: translateY(-50%);
    display: block;
    padding: 0;
    border: 0;
    background: none;
    line-height: 0;
    color: var(--c-text-muted);                        /* gray-400 */
    cursor: pointer;
}
.lg-eye:hover { color: var(--c-text-mid); }          /* gray-600 */
.lg-eye .ico { width: 16px; height: 16px; }

.lg-error {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 12px;
    background: #fef2f2;                   /* red-50 */
    border: 1px solid #fee2e2;             /* red-100 */
    border-radius: 12px;
    font-size: 14px;
    color: #dc2626;                        /* red-600 */
}
.lg-error .ico { width: 16px; height: 16px; flex: 0 0 16px; }

.lg-submit {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    padding: 12px;
    border: 0;
    border-radius: 12px;
    background: linear-gradient(to right, #dc2626, #b91c1c);
    color: var(--c-text-invert);
    font-size: 14px;
    font-weight: 600;
    font-family: inherit;
    cursor: pointer;
    box-shadow: 0 10px 15px -3px rgba(220, 38, 38, .2), 0 4px 6px -4px rgba(220, 38, 38, .2);
    transition: opacity .15s;
}
.lg-submit:hover { opacity: .9; }
.lg-submit:disabled { opacity: .5; cursor: not-allowed; }
.lg-submit .ico { width: 16px; height: 16px; }
.lg-spin {
    width: 16px;
    height: 16px;
    border: 2px solid var(--c-surface);
    border-top-color: transparent;
    border-radius: 999px;
    animation: lg-spin .6s linear infinite;
}
@keyframes lg-spin { to { transform: rotate(360deg); } }

/* display:flex/block 会盖掉 [hidden]，必须显式关掉 */
.lg-error[hidden], .lg-spin[hidden], .lg-submit-ico[hidden] { display: none; }

.lg-back { margin-top: 24px; text-align: center; }
.lg-back a { font-size: 14px; color: rgba(255, 255, 255, .8); }
.lg-back a:hover { color: var(--c-text-invert); text-decoration: none; }

/* ---------- 错误页 ---------- */
.error-page {
    min-height: 100vh;
    display: grid;
    place-items: center;
    padding: 24px;
}
.error-card {
    max-width: 620px;
    width: 100%;
    background: var(--c-surface);
    border: 1px solid var(--c-border);
    border-radius: 14px;
    padding: 36px;
    text-align: center;
    box-shadow: var(--shadow);
}
.error-code { font-size: 52px; font-weight: 800; color: var(--brand); line-height: 1; }
.error-title { margin: 10px 0 8px; font-size: 20px; }
.error-desc { color: var(--c-text-sub); margin: 0 0 18px; }
.error-meta { font-size: 12px; color: var(--c-text-muted); }
.error-trace {
    text-align: left;
    background: #1d2129;
    color: #c9cdd4;
    padding: 14px;
    border-radius: 8px;
    font-size: 12px;
    overflow-x: auto;
    max-height: 260px;
}
.error-actions { display: flex; gap: 10px; justify-content: center; margin-top: 18px; }
.error-hint { margin-top: 16px; font-size: 12px; color: var(--c-warning); }

/* ---------- 响应式 ---------- */
@media (max-width: 860px) {
    .sidebar {
        position: fixed;
        left: -320px;
        z-index: 20;
        transition: left .2s ease;
        box-shadow: 0 0 24px rgba(0, 0, 0, .35);
    }
    .sidebar.is-open { left: 0; }
    .topbar-left .nav-toggle { display: inline-flex; }
    .content { padding: 14px 14px 30px; }
    .topbar { padding: 12px 14px; }
    .alert { margin: 0 14px 12px; }
}

/* ---------- 系统设置：图形化配置块 ---------- */
.setting-block {
    border-top: 1px solid var(--c-border);
    padding-top: 14px;
    margin-top: 14px;
}
.setting-block:first-of-type { border-top: none; margin-top: 0; }
.setting-head {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}
.setting-head code {
    font-size: 13px;
    background: #f4f5f7;
    padding: 2px 6px;
    border-radius: 6px;
}
.setting-head .spacer { flex: 1; }
.setting-desc { padding: 6px 0 0; }

.switch-line {
    display: flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    font-size: 13px;
}
.switch-line input[type="checkbox"] {
    width: 16px;
    height: 16px;
    accent-color: var(--brand);
    cursor: pointer;
}
.switch-text { color: var(--c-text-mid); font-weight: 500; }

.btn-link {
    border: 0;
    background: none;
    color: var(--brand);
    font-size: 12px;
    cursor: pointer;
    padding: 0 0 0 6px;
    font-family: inherit;
}
.btn-link:hover { text-decoration: underline; }

.adv { margin-top: 10px; }
.adv > summary {
    cursor: pointer;
    font-size: 12px;
    color: var(--c-text-sub);
    padding: 4px 0;
}
.adv > summary:hover { color: var(--brand); }
.adv .form { margin-top: 8px; }

/* ---------- 页面内 Tab（系统设置 / 会员管理 等页面的顶部横向 Tab） ----------
   旧站是顶部下划线 Tab；这里用链接实现 —— 每个 Tab 都是真实 URL（?tab=xxx），
   刷新 / 收藏 / 后退都不会丢当前 Tab，也不需要 JS。 */
.st-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 2px;
    border-bottom: 1px solid var(--c-border);
    margin-bottom: 16px;
}
.st-tab {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    /* 旧版：px-5 py-3 text-sm font-medium（admin.events.tsx:599 / admin.shop.tsx:452） */
    padding: 12px 20px;
    font-size: 14px;
    font-weight: 500;
    color: var(--c-text-sub);
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    text-decoration: none;
    white-space: nowrap;
}
.st-tab:hover { color: var(--c-text); text-decoration: none; background: var(--c-bg-subtle); }
.st-tab.is-on {
    color: var(--brand);
    border-bottom-color: var(--brand);
    font-weight: 500;
}
.st-tab-ico { font-size: 14px; }

/* 二级 Tab（「接口设置」内部） */
.st-subtabs {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: 14px;
}
.st-subtab {
    padding: 5px 12px;
    font-size: 13px;
    border: 1px solid var(--c-border);
    border-radius: 999px;
    color: var(--c-text-sub);
    text-decoration: none;
    background: var(--c-surface);
}
.st-subtab:hover { color: var(--c-text); text-decoration: none; border-color: #d5d9e0; }
.st-subtab.is-on {
    background: var(--brand);
    border-color: var(--brand);
    color: var(--c-text-invert);
    font-weight: 600;
}
.st-page-desc { color: var(--c-text-sub); font-size: 13px; margin: -6px 0 14px; }

/* ============================================================================
   系统设置 /admin/settings —— 严格对齐旧版 src/routes/admin.settings.tsx
   外壳：卡片**外**的页头 → 下划线 Tab 栏 → **一张白卡**包住当前 Tab 全部内容
   ⚠️ 下面全部限定在 .st-wrap 内：.st-tabs / .st-tab 还被「会员管理→会员设置」等页面共用，
      直接改基类会连带改到那些页面（旧版各页 Tab 内边距本就略有差异）。
   ============================================================================ */
.st-wrap { display: flex; flex-direction: column; }

/* 页头：旧版 `mb-5` + `h2 text-2xl font-bold text-gray-800` + `p text-sm text-gray-500 mt-1` */
.st-page-head  { margin-bottom: 20px; }
.st-page-title { margin: 0; font-size: 24px; line-height: 1.3; font-weight: 700; color: var(--c-text); }
.st-page-sub   { margin: 4px 0 0; font-size: 14px; color: var(--c-text-sub); }

/* Tab 栏：旧版 `flex flex-wrap gap-0 border-b border-gray-200 mb-6`，tab `px-4 py-3` */
.st-wrap .st-tabs { gap: 0; margin-bottom: 24px; }
.st-wrap .st-tab  { padding: 12px 16px; gap: 6px; }
.st-tab-ico { display: inline-flex; }
.st-tab-ico svg { width: 16px; height: 16px; display: block; }

/* 内容白卡：旧版 `bg-white rounded-xl border border-gray-200 shadow-sm p-6` */
.st-panel {
    background: var(--c-surface);
    border: 1px solid var(--c-border);
    border-radius: 10px;
    box-shadow: var(--shadow-sm);
    padding: 24px;
}

/* Tab 内大标题：旧版 `h3 text-lg font-bold text-gray-800 flex items-center gap-2`
   站点信息页的 h3 与右侧「LOGO + 站点名」在**同一行**（`flex items-center justify-between`） */
.st-tab-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 16px; }
.st-tab-head .st-tab-title { margin: 0; }
.st-tab-preview { display: flex; align-items: center; gap: 12px; flex-shrink: 0; }
.st-tab-preview-logo { width: 32px; height: 32px; object-fit: contain; border-radius: 4px; border: 1px solid var(--c-bg-muted); }
.st-tab-preview-name { font-size: 14px; font-weight: 500; color: var(--c-text-mid); }
.st-tab-title { display: flex; align-items: center; gap: 8px; margin: 0 0 16px; font-size: 18px; line-height: 1.4; font-weight: 700; color: var(--c-text); }
.st-tab-title-ico { display: inline-flex; color: var(--c-primary); }
.st-tab-title-ico svg { width: 20px; height: 20px; display: block; }
.st-tab-desc { margin: -8px 0 16px; font-size: 14px; color: var(--c-text-sub); }
.st-empty { text-align: center; color: var(--c-text-muted); padding: 32px 0; }

/* 二级 Tab：旧版 `flex flex-wrap gap-1 border-b border-gray-200 mb-4`，
   tab `px-3.5 py-2.5 text-sm font-medium border-b-2 -mb-px`，选中再叠 `bg-primary/5` */
.st-wrap .st-subtabs { gap: 4px; margin-bottom: 16px; padding-bottom: 0; border-bottom: 1px solid var(--c-border); }
.st-wrap .st-subtab {
    padding: 10px 14px;
    font-size: 14px;
    font-weight: 500;
    color: var(--c-text-sub);
    background: transparent;
    border: 0;
    border-bottom: 2px solid transparent;
    border-radius: 0;
    margin-bottom: -1px;
    white-space: nowrap;
}
.st-wrap .st-subtab:hover { color: var(--c-text); background: var(--c-bg-subtle); }
.st-wrap .st-subtab.is-on {
    color: var(--brand);
    border-bottom-color: var(--brand);
    background: rgba(200, 16, 46, .05);
    font-weight: 500;
}
.st-subtab-ico { display: inline-flex; }
.st-subtab-ico svg { width: 16px; height: 16px; display: block; }

/* ---------- 小节：旧版的两种形态 ---------- */
.st-sec { display: block; }
.st-sec + .st-sec,
.st-sec + .st-sec-card,
.st-sec-card + .st-sec,
.st-sec-card + .st-sec-card { margin-top: 20px; }

/* 旧版 Section：`text-xs font-semibold text-gray-400 uppercase tracking-wide
   border-b border-gray-100 pb-1.5 mt-6 mb-3` */
.st-sec-title {
    margin: 24px 0 12px;
    padding-bottom: 6px;
    font-size: 12px;
    font-weight: 600;
    color: var(--c-text-muted);
    text-transform: uppercase;
    letter-spacing: .05em;
    border-bottom: 1px solid var(--c-bg-muted);
}
.st-sec:first-child .st-sec-title { margin-top: 0; }

/* 旧版卡片形态：`border border-gray-200 rounded-xl p-5` + `h3 text-base font-bold` + `p text-sm text-gray-500` */
.st-sec-card      { border: 1px solid var(--c-border); border-radius: 10px; padding: 20px; }
.st-sec-head      { margin-bottom: 16px; }
.st-sec-card-title { margin: 0; font-size: 16px; line-height: 1.4; font-weight: 700; color: var(--c-text); }
.st-sec-card-desc { margin: 6px 0 0; font-size: 14px; color: var(--c-text-sub); }
.st-sec-note      { margin: 0 0 12px; font-size: 13px; color: var(--c-text-sub); }

/* 琥珀色小卡：旧版「每日签到规则」= `bg-amber-50/50 border border-amber-100 rounded-xl p-4 space-y-3` */
.st-sec-amber {
    background: rgba(245, 158, 11, .05);
    border: 1px solid #FDE68A;
    border-radius: 10px;
    padding: 16px;
}
.st-sec-amber-desc { margin: 0 0 12px; font-size: 12px; line-height: 1.7; color: var(--c-warning-dark); }
.st-sec-amber .form-actions { padding: 0; margin-top: 12px; border: 0; background: none; justify-content: flex-end; }
.st-sec-amber .st-savebtn { background: var(--c-warning); border-color: var(--c-warning); }
.st-sec-amber .st-savebtn:hover { background: var(--c-warning-dark); border-color: var(--c-warning-dark); }

/* 保存按钮：旧版 SaveBtn = `inline-flex items-center gap-1.5 px-5 py-2.5 text-sm text-white rounded-lg shadow-sm`
   （带 Save 图标）。本项目 .btn-sm 是 28px/12px 的紧凑尺寸，这里必须放大到旧版口径。 */
.st-panel .st-savebtn {
    height: 38px;
    padding: 0 20px;
    gap: 6px;
    font-size: 14px;
    border-radius: 10px;
    box-shadow: var(--shadow-sm);
}
.st-panel .st-savebtn svg { width: 16px; height: 16px; display: block; }
.st-panel .form-actions { padding: 0; margin-top: 20px; border: 0; background: none; }

/* 折叠面板：旧版 Accordion = `border rounded-lg overflow-hidden`
   + 头 `px-4 py-3 bg-gray-50 hover:bg-gray-100 text-sm font-medium text-gray-700` + 体 `p-4 bg-white`。
   ⚠️ 只作用于系统设置白卡内（.adv 在别处是「高级模式 JSON」的折叠块）。 */
.st-panel .adv { margin: 0 0 12px; border: 1px solid var(--c-border); border-radius: 10px; overflow: hidden; }
.st-panel .adv:last-child { margin-bottom: 0; }
.st-panel .adv > summary {
    display: flex; align-items: center; justify-content: space-between;
    padding: 12px 16px; margin: 0;
    background: var(--c-bg-subtle);
    font-size: 14px; font-weight: 500; color: var(--c-text-mid);
    cursor: pointer; list-style: none;
}
.st-panel .adv > summary::-webkit-details-marker { display: none; }
.st-panel .adv > summary::after {
    content: '\203A'; font-size: 18px; line-height: 1;
    color: var(--c-text-muted); transform: rotate(90deg); transition: transform .15s;
}
.st-panel .adv[open] > summary::after { transform: rotate(-90deg); }
.st-panel .adv > summary:hover { background: var(--c-bg-muted); color: var(--c-text); }
.st-panel .adv .form { margin: 0; padding: 16px; background: var(--c-surface); }
.st-panel .adv .form-actions { margin-top: 12px; }

/* ---------- 接口设置子页的「小卡」----------
   旧版：`border border-gray-200 rounded-lg p-5` + 标题 `text-sm font-bold`(14px/700)
   + 右上角「已同步云端」徽章 + 说明 `text-xs text-gray-500`
   + 卡内栅格 `md:grid-cols-2 gap-x-6 gap-y-4`（24/16）+ `max-w-3xl`(768) + 部分字段 `md:col-span-2` */
.st-panel .st-api-card { border: 1px solid var(--c-border); border-radius: 10px; padding: 20px; }
.st-panel .st-api-card + .st-api-card,
.st-panel .st-sec + .st-api-card,
.st-panel .st-api-card + .st-sec { margin-top: 20px; }

.st-api-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 16px; }
.st-api-title { display: flex; align-items: center; gap: 8px; margin: 0; font-size: 14px; line-height: 1.4; font-weight: 700; color: var(--c-text); }
.st-api-title-ico { display: inline-flex; color: var(--c-primary); }
.st-api-title-ico svg { width: 16px; height: 16px; display: block; }
.st-api-badge {
    flex-shrink: 0;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: 10px; line-height: 1.6;
    background: var(--c-success-light); color: var(--c-success-dark);
    border: 1px solid var(--c-success-border);
    white-space: nowrap;
}
.st-api-desc { margin: -8px 0 16px; font-size: 12px; line-height: 1.7; color: var(--c-text-sub); }

/* 分组内容容器：plain 分组按行竖排（20px 间距）；卡片分组自己就是 2 列栅格，
   行用 display:contents「消失」，字段直接成为栅格项 —— 这样 rows[].span 才能跨列。 */
.st-api-body { display: flex; flex-direction: column; gap: 20px; }
.st-api-body .st-row { margin-bottom: 0; }
.st-panel .st-api-card .st-api-body {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px 24px;
}
.st-panel .st-api-card .st-api-body > .st-row:not(.st-row-span) { display: contents; }
/* ⚠️ renderFields 给 password/switch 字段自动加了 `.field-full`（跨整行），但旧版的密码框/开关
   是**半宽**的。卡片里「跨整行」一律由 rows[].span 表达，所以这里把 field-full 收回半宽；
   真正要整宽的字段都在 .st-row-span（1 列栅格）里，不受影响。
   ⚠️ 注意选择器要写成 `.st-row > .field-full`：`display:contents` 只让 .st-row 在**布局**上消失，
      DOM 层级不变，`.st-api-body > .field-full` 选不中（踩过）。 */
.st-panel .st-api-card .st-api-body > .st-row > .field-full { grid-column: span 1; }
.st-panel .st-api-card .st-api-body > .st-row-span { display: grid; grid-template-columns: minmax(0, 1fr); grid-column: span 2; }
@media (max-width: 767px) {
    .st-panel .st-api-card .st-api-body { grid-template-columns: minmax(0, 1fr); }
    .st-panel .st-api-card .st-api-body > .st-row-span { grid-column: span 1; }
}

.st-api-tip {
    display: flex; align-items: flex-start; gap: 8px;
    margin-top: 16px; padding: 12px 16px;
    background: var(--c-info-light);
    border: 1px solid var(--c-info-border);
    border-radius: 10px;
    font-size: 12px; line-height: 1.7; color: var(--c-info-dark);
}
.st-api-tip svg { width: 16px; height: 16px; flex-shrink: 0; margin-top: 2px; }
.st-api-tip code { font-size: 11px; }
.st-api-tip-first { margin: 0 0 16px; }

/* ==========================================================================
   接口设置子页的专用控件（逐条对齐旧版 admin.settings.tsx 的 Toggle / 单选卡 / 上传 / 提示块）
   ========================================================================== */

/* ---- 整行开关：左「标题 + 说明」，右开关（旧版 <Toggle label desc>） ----
   旧版：<div className="mb-4"><Toggle/></div>
     Toggle 内 = flex items-center justify-between + 左 p(14px/500) + p(11px/灰) + 右 button 开关 */
.st-tgl-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.st-tgl-text { min-width: 0; }
.st-tgl-label { margin: 0; font-size: 14px; font-weight: 500; color: var(--c-text); }
.st-tgl-desc { margin: 2px 0 0; font-size: 11px; color: var(--c-text-sub); line-height: 1.5; }
.st-tgl { position: relative; flex-shrink: 0; display: inline-flex; cursor: pointer; }
.st-tgl > input[type="checkbox"] { position: absolute; opacity: 0; width: 0; height: 0; }
.st-tgl-track {
    display: block; width: 44px; height: 24px; border-radius: 999px;
    background: var(--c-bg-muted); transition: background .15s;
}
.st-tgl-track::after {
    content: ''; position: absolute; top: 2px; left: 2px;
    width: 20px; height: 20px; border-radius: 50%;
    background: #fff; box-shadow: 0 1px 2px rgba(0,0,0,.25);
    transition: transform .15s;
}
.st-tgl > input:checked + .st-tgl-track { background: var(--brand); }
.st-tgl > input:checked + .st-tgl-track::after { transform: translateX(20px); }
.st-tgl > input:focus-visible + .st-tgl-track { outline: 2px solid var(--brand); outline-offset: 2px; }

/* ---- 单选卡片组（旧版「接入模式」） ----
   label: `flex items-center gap-2 px-3 py-2 rounded-lg border`；选中 = 主色描边 + 主色 5% 底 */
.st-radios { display: flex; flex-wrap: wrap; gap: 16px; }
.st-radio {
    display: flex; align-items: center; gap: 8px; cursor: pointer; user-select: none;
    padding: 8px 12px; border: 1px solid var(--c-border); border-radius: 10px;
    transition: border-color .15s, background .15s;
}
.st-radio:hover { background: var(--c-bg-subtle); }
.st-radio.is-on { border-color: var(--brand); background: rgba(220, 38, 38, .05); }
.st-radio input[type="radio"] { width: 16px; height: 16px; flex-shrink: 0; accent-color: var(--brand); }
.st-radio-title { display: block; font-size: 14px; font-weight: 500; color: var(--c-text); }
.st-radio-desc { display: block; font-size: 11px; color: var(--c-text-muted); line-height: 1.5; }

/* ---- 文件上传（旧版 商户证书 / 商户私钥） ----
   旧版：label(12px) → [上传按钮][✓ 已上传][清除] → 11px 灰 hint
   没有大 textarea；只有私钥在上传后多一个 <details>「查看/手动编辑」。 */
.st-file-row { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.st-file-btn {
    display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
    padding: 6px 12px; border: 1px solid var(--c-border); border-radius: 10px;
    background: #fff; font-size: 14px; color: var(--c-text-sub); transition: background .15s;
}
.st-file-btn:hover { background: var(--c-bg-subtle); }
.st-file-btn svg { width: 16px; height: 16px; }
.st-file-btn input[type="file"] { display: none; }
.st-file-ok { font-size: 12px; color: #059669; }
.st-file-clear { border: 0; background: none; padding: 0; font-family: inherit; font-size: 12px; color: var(--c-text-muted); cursor: pointer; }
.st-file-clear:hover { color: #dc2626; }
.st-file-note { margin: 4px 0 0; font-size: 11px; color: var(--c-text-muted); line-height: 1.5; }
.st-file-note .st-file-serial { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; color: #059669; }
.st-file-more { margin-top: 4px; }
.st-file-more > summary { font-size: 11px; color: var(--c-text-muted); cursor: pointer; }
.st-file-more textarea { width: 100%; margin-top: 4px; height: 96px; font-size: 10px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }

/* ---- 蓝色提示块（旧版三处用法都在这里）----
   ① 卡内底部  ：`bg-blue-50 border-blue-200 rounded-lg px-4 py-3 text-xs text-blue-700 mt-4`
   ② 卡内顶部  ：`bg-blue-50 border-blue-100 rounded-lg p-3 text-xs text-blue-800 mb-4`（可含多段 + 粗体标题）
   ③ 独立一条  ：同 ①，但自己就是一个块（小程序页第 4 块） */
.st-notice {
    display: flex; align-items: flex-start; gap: 8px;
    background: #eff6ff; border: 1px solid #bfdbfe; border-radius: 10px;
    padding: 12px 16px; font-size: 12px; color: #1d4ed8; line-height: 1.6;
}
.st-notice svg { width: 16px; height: 16px; flex-shrink: 0; margin-top: 2px; }
.st-notice code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.st-notice p { margin: 0; }
.st-notice p + p { margin-top: 2px; }
.st-notice .st-notice-h { font-weight: 700; margin-bottom: 4px; }
.st-api-tip-last { margin: 16px 0 0; }
.st-notice-block { border-color: #bfdbfe; }
/* ② 顶部说明块：整块浅蓝底、无图标、多段 */
.st-notice-box {
    background: #eff6ff; border: 1px solid #dbeafe; border-radius: 10px;
    padding: 12px; font-size: 12px; color: #1e40af; line-height: 1.7;
}
.st-notice-box p { margin: 0; }
.st-notice-box .st-notice-h { font-weight: 700; margin-bottom: 4px; }

/* ---- 出血行（整卡宽，不进 768px 栅格）----
   旧版 <Toggle> 与「接入模式」是卡片 body 的直接子元素，所以开关贴在卡片右边缘。 */
.st-bleed { margin-bottom: 16px; }
.st-bleed:last-child { margin-bottom: 0; }
/* 出血行里的字段不要撑满整卡：文字块与开关分别贴两端（.st-tgl-row 已是 space-between） */
.st-bleed .field + .field { margin-top: 16px; }

/* 栅格内的小组标题（旧版「服务商信息」「子商户信息」：12px / 500 / 灰，段前 8px） */
.st-api-subhead { margin: 8px 0 0; font-size: 12px; font-weight: 500; color: var(--c-text-sub); }
.st-api-subhead:first-child { margin-top: 0; }

/* 密码框内的眼睛按钮（取代原来的「显示」文字按钮） */
.cfg-pwd-row { position: relative; display: flex; align-items: center; gap: 8px; }
.cfg-pwd-row .input[type="password"] { padding-right: 38px; }
.cfg-pwd-eye {
    position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
    display: inline-flex; align-items: center; justify-content: center;
    width: 26px; height: 26px; padding: 0; border: 0; border-radius: 6px;
    background: none; color: var(--c-text-muted); cursor: pointer;
}
.cfg-pwd-eye:hover { background: var(--c-bg-subtle); color: var(--c-text-sub); }
.cfg-pwd-eye svg { width: 16px; height: 16px; }

/* 字段行内的「发送测试」按钮（旧版贴在测试手机号右侧） */
.cfg-testbtn { flex-shrink: 0; }
.cfg-testbtn svg { width: 14px; height: 14px; }

/* 「一格多字段」：一行里的嵌套数组会渲染成这个容器
   （旧版身份证页：服务商 | [启用识别 启用实名核验] 并排） */
.st-cell { display: flex; align-items: flex-end; gap: 24px; }
.st-cell > .field { flex: 1 1 0; min-width: 0; }
.st-cell .st-tgl-row { gap: 12px; }
@media (max-width: 900px) {
    .st-cell { flex-direction: column; align-items: stretch; gap: 16px; }
}

/* 保存按钮右侧的「当前：xxx」 */
.st-cur-label { font-size: 12px; color: var(--c-text-muted); }

/* ⚠️ [hidden] 只是 UA 样式表里的 `display:none`，作者样式的任何 display 都会赢。
   .field / .st-bleed / .st-notice 都声明了 display，所以条件显示必须 !important 兜底。 */
.st-panel [hidden] { display: none !important; }

/* 提示条与卡片之间的间距（.st-notice-block 与 .st-api-card 是兄弟） */
.st-panel .st-api-card + .st-notice-block,
.st-panel .st-notice-block + .st-api-card { margin-top: 20px; }

/* ==========================================================================
   数据管理 Tab（旧版 admin.settings.tsx:2128-2270 的四块）
   ========================================================================== */
.st-dcard { border: 1px solid var(--c-border); border-radius: 12px; padding: 20px; }
.st-dcard + .st-dcard, .st-sec + .st-dcard, .st-panel .st-dcard + .st-sec { margin-top: 20px; }
.st-dcard-head { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }
.st-dcard-head > svg { width: 20px; height: 20px; color: var(--brand); flex-shrink: 0; }
.st-dcard-title { margin: 0; font-size: 16px; font-weight: 700; color: var(--c-text); }
.st-dcard-desc { margin: 0 0 16px; font-size: 14px; color: var(--c-text-sub); }

/* 两张灰底小卡（数据备份 / 站点备份） */
.st-dgrid2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
.st-dsub { border: 1px solid #f3f4f6; border-radius: 12px; padding: 16px; background: rgba(249, 250, 251, .6); }
.st-dsub-head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.st-dsub-head svg { width: 16px; height: 16px; }
.st-dsub-head .is-blue svg { color: #3b82f6; }
.st-dsub-head .is-green svg { color: #059669; }
.st-dsub-title { margin: 0; font-size: 14px; font-weight: 700; color: #374151; }
.st-dsub-desc { margin: 0 0 12px; font-size: 11px; color: var(--c-text-sub); line-height: 1.7; }

/* 按钮（旧版：蓝 #2563eb / 翠绿 #059669 / 主色，白字圆角 + 轻阴影） */
.st-dbtnrow { display: flex; flex-wrap: wrap; gap: 12px; margin-bottom: 20px; }
.st-dbtn {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 8px 16px; border: 1px solid transparent; border-radius: 10px;
    font-family: inherit; font-size: 14px; cursor: pointer; box-shadow: var(--shadow-sm);
}
.st-dbtn svg { width: 16px; height: 16px; }
.st-dbtn.is-blue { background: #2563eb; color: #fff; }
.st-dbtn.is-blue:hover { background: #1d4ed8; }
.st-dbtn.is-green { background: #059669; color: #fff; }
.st-dbtn.is-green:hover { background: #047857; }
.st-dbtn.is-brand { background: var(--brand); color: #fff; }
.st-dbtn.is-brand:hover { background: var(--brand-dark); }
.st-dbtn.is-ghost { background: #fff; border-color: var(--c-border); color: var(--c-text-sub); }
.st-dbtn.is-ghost:hover { background: var(--c-bg-subtle); }

.st-warn { display: flex; align-items: flex-start; gap: 6px; margin: 12px 0 0; font-size: 11px; color: var(--c-text-muted); }
.st-warn svg { width: 14px; height: 14px; color: #f59e0b; flex-shrink: 0; margin-top: 1px; }

/* 「备份历史」小标题行 + 右侧「刷新」 */
.st-dhead3 { display: flex; align-items: center; gap: 8px; margin: 20px 0 8px; }
.st-dhead3 svg { width: 16px; height: 16px; color: var(--c-text-sub); flex-shrink: 0; }
.st-dhead3 h4 { margin: 0; font-size: 14px; font-weight: 700; color: #374151; }
.st-drefresh { margin-left: auto; font-size: 12px; font-weight: 500; color: #2563eb; }

/* 文件名单元格（图标 + 文件名） */
.st-filecell { display: inline-flex; align-items: center; gap: 6px; font-weight: 500; color: #374151; }
.st-filecell svg { width: 16px; height: 16px; color: var(--c-text-muted); flex-shrink: 0; }

.st-linkbtn.is-amber { color: #d97706; }
.st-linkbtn.is-amber:hover { color: #b45309; }
@media (max-width: 900px) {
    .st-dgrid2 { grid-template-columns: minmax(0, 1fr); }
}

/* 云端持久化说明（✓ 翠绿 / ⚠ 琥珀） */
.st-ok-list p { display: flex; align-items: flex-start; gap: 8px; margin: 0; font-size: 14px; color: var(--c-text-sub); }
.st-ok-list p + p { margin-top: 8px; }
.st-ok-list .is-ok svg { width: 16px; height: 16px; color: #10b981; flex-shrink: 0; margin-top: 3px; }
.st-ok-list .is-warn svg { width: 16px; height: 16px; color: #f59e0b; flex-shrink: 0; margin-top: 3px; }
.st-ok-list .is-warn-text { color: #d97706; }

/* ---------- 管理员与权限 Tab（内嵌表格 + 弹窗，旧版 admin.settings.tsx 的 admin tab）---------- */
.st-adm-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 16px; }
.st-adm-sub { margin: 4px 0 0; font-size: 12px; color: var(--c-text-muted); }
.st-addbtn {
    flex-shrink: 0;
    display: inline-flex; align-items: center; gap: 6px;
    height: 36px; padding: 0 16px;
    border: 1px solid var(--brand); border-radius: 10px;
    background: var(--brand); color: var(--c-text-invert);
    font-size: 14px; font-family: inherit; cursor: pointer;
    box-shadow: var(--shadow-sm);
}
.st-addbtn:hover { background: var(--brand-dark); border-color: var(--brand-dark); }
.st-addbtn svg { width: 16px; height: 16px; display: block; }

/* 表格：旧版外壳 `border border-gray-200 rounded-lg`；thead 灰底 + 大写 12px；
   th/td `px-4 py-3`；行分隔 `divide-gray-100`；行 hover `bg-gray-50` */
.st-tablebox { border: 1px solid var(--c-border); border-radius: 10px; overflow-x: auto; }
.st-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.st-table th, .st-table td { padding: 12px 16px; text-align: left; vertical-align: middle; }
.st-table thead th {
    background: var(--c-bg-subtle); color: var(--c-text-sub);
    font-weight: 500; font-size: 12px; text-transform: uppercase; white-space: nowrap;
}
.st-table tbody td { border-top: 1px solid var(--c-bg-muted); }
.st-table tbody tr:hover { background: var(--c-bg-subtle); }
.st-table .st-empty { text-align: center; color: var(--c-text-muted); padding: 32px 16px; }
.st-table .th-r { text-align: right; white-space: nowrap; }

.st-muted-xs { color: var(--c-text-sub); font-size: 12px; }
.st-trunc { max-width: 200px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.st-adm-branch { margin-top: 3px; font-size: 11px; color: var(--c-text-muted); }

/* 徽章（旧版 tailwind 调色板：purple/amber/blue/green/red-100 + -700） */
.st-pill { display: inline-block; padding: 2px 8px; border-radius: 999px; font-size: 12px; line-height: 1.6; font-weight: 500; white-space: nowrap; }
.st-pill + .st-pill { margin-left: 4px; }
.st-pill.is-purple { background: #F3E8FF; color: #7E22CE; }
.st-pill.is-amber  { background: #FEF3C7; color: #B45309; }
.st-pill.is-blue   { background: #DBEAFE; color: #1D4ED8; }
.st-pill.is-green  { background: #DCFCE7; color: #15803D; }
.st-pill.is-red    { background: #FEE2E2; color: #B91C1C; }
.st-pill.is-gray   { background: var(--c-bg-muted); color: var(--c-text-sub); }

/* 可点击的状态徽章（旧版点一下切换启用 / 禁用） */
.st-pillbtn {
    display: inline-block; padding: 2px 8px; border: 0; border-radius: 999px;
    font-family: inherit; font-size: 12px; line-height: 1.6; font-weight: 500;
    cursor: pointer; white-space: nowrap;
}
.st-pillbtn.is-green { background: #DCFCE7; color: #15803D; }
.st-pillbtn.is-red   { background: #FEE2E2; color: #B91C1C; }

/* 行内文字按钮 / 排序箭头 */
.st-linkbtn {
    display: inline; padding: 0; border: 0; background: none;
    font-family: inherit; font-size: 12px; font-weight: 500; cursor: pointer;
}
.st-linkbtn.is-blue { color: #2563EB; }
.st-linkbtn.is-blue:hover { color: #1D4ED8; }
.st-linkbtn.is-red { color: #EF4444; }
.st-linkbtn.is-red:hover { color: #B91C1C; }
.st-table td.th-r .st-linkbtn.is-blue { margin-right: 12px; }
/* 删除按钮是个 <form>，默认块级会把「编辑 / 删除」挤成两行 */
.st-table .inline { display: inline; margin: 0; }
.st-arrowbtn { display: inline-block; padding: 0 5px; margin-right: 10px; font-size: 12px; color: var(--c-text-sub); }
.st-arrowbtn:hover { color: var(--brand); text-decoration: none; }
.st-arrowbtn.is-disabled { opacity: .3; cursor: not-allowed; }

/* 弹窗内：角色多选 */
.st-rolepicks { max-height: 176px; overflow-y: auto; border: 1px solid var(--c-border); border-radius: 10px; }
.st-rolepick { display: flex; align-items: center; gap: 8px; padding: 8px 12px; font-size: 14px; cursor: pointer; border-bottom: 1px solid var(--c-bg-muted); }
.st-rolepick:last-child { border-bottom: 0; }
.st-rolepick:hover { background: var(--c-bg-subtle); }
.st-rolepick input { width: 16px; height: 16px; accent-color: var(--brand); }

/* 角色弹窗的页签（旧版 `border-b-2` 下划线式） */
.st-roletabs { display: flex; padding: 0 20px; border-bottom: 1px solid var(--c-border); }
.st-roletab {
    padding: 10px 16px; margin-bottom: -1px;
    border: 0; border-bottom: 2px solid transparent;
    background: none; font-family: inherit; font-size: 14px; font-weight: 500;
    color: var(--c-text-sub); cursor: pointer;
}
.st-roletab:hover { color: var(--c-text); }
.st-roletab.is-on { color: var(--brand); border-bottom-color: var(--brand); }

.st-adm-foot { margin: 12px 0 0; font-size: 12px; color: var(--c-text-muted); }

/* 字段栅格：旧版 `grid grid-cols-1 md:grid-cols-2 gap-4`，文本输入框 `max-w-sm`(384px)
   ⚠️ 只作用于系统设置白卡内；基类 .form-grid 被模块表单共用，不要直接改。
   只限「.field 的直系 <input>」——图片字段的输入框在 .cfg-img-row 里（要 flex-1），
   textarea 旧版是 w-full（不限宽）。 */
.st-panel .form-grid { grid-template-columns: minmax(0, 1fr); gap: 16px; padding: 0; }
@media (min-width: 768px) { .st-panel .form-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.st-panel .form-grid .field > input.input,
.st-panel .st-row .field > input.input { max-width: 384px; }

/* 显式换行（groups.rows）：旧版每一行都是独立的 `grid grid-cols-1 md:grid-cols-2 gap-4` */
.st-panel .st-row { display: grid; gap: 16px; margin-bottom: 16px; }
.st-panel .st-row:last-child { margin-bottom: 0; }
.st-panel .st-row-full { grid-template-columns: minmax(0, 1fr); }
@media (max-width: 767px) { .st-panel .st-row { grid-template-columns: minmax(0, 1fr) !important; } }

/* 图片字段：旧版 ImageInput = 一行 [输入框 flex-1][选择][✕]，**没有大预览框** */
.cfg-img-row { display: flex; align-items: center; gap: 8px; }
.cfg-img-row .input { flex: 1 1 auto; min-width: 0; }
.cfg-img-pick {
    flex: 0 0 auto;
    display: inline-flex; align-items: center; gap: 4px;
    height: 36px; padding: 0 12px;
    font-size: 14px; color: var(--c-text-sub);
    background: var(--c-surface);
    border: 1px solid var(--c-border); border-radius: 8px;
    cursor: pointer;
}
.cfg-img-pick:hover { background: var(--c-bg-subtle); }
.cfg-img-pick svg { width: 16px; height: 16px; display: block; }
.cfg-img-clear {
    flex: 0 0 auto;
    display: inline-flex; align-items: center; justify-content: center;
    width: 36px; height: 36px; padding: 0;
    color: var(--c-text-muted);
    background: none; border: 0; border-radius: 8px;
    cursor: pointer;
}
.cfg-img-clear:hover { color: var(--c-danger); }
.cfg-img-clear svg { width: 16px; height: 16px; display: block; }
/* 旧版：✕ 只在**有值**时出现（输入框空 → 显示 placeholder → 隐藏 ✕） */
.cfg-img-row:has(.input:placeholder-shown) .cfg-img-clear { display: none; }

/* 列表编辑器的「项」卡片 */
.li-item { border: 1px solid var(--c-border); border-radius: var(--r-lg); margin-bottom: 12px; background: var(--c-surface); }
.li-item-head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 14px;
    border-bottom: 1px solid var(--c-border);
    background: var(--c-bg-subtle);
}
.li-item-head h4 { margin: 0; font-size: 13px; font-weight: 600; }
.li-item-body { padding: 12px 14px; }

/* ==========================================================================
   弹窗（modal）—— 对齐原版的「编辑走弹窗而不是跳页」

   原版全站有 154 处 `fixed inset-0 … bg-black/40` 遮罩 + 居中白卡，
   例如会员、订单、文章的「编辑」「详情」「导入」都是弹窗。
   PHP 侧原本一律跳独立页面，观感差异最大，这里补上同一套视觉。

   渐进增强：`data-modal` 只是让 JS 拦截点击；JS 不可用时链接照常整页跳转。
   ========================================================================== */
.modal { position: fixed; inset: 0; z-index: 60; display: none; }
.modal.is-open { display: block; }
/* 无 JS 兜底：工具栏链接 href="#<弹窗 id>" 时也能打开 */
.modal:target { display: block; }
/* 视觉隐藏但可提交的按钮（无可见「查询」按钮时保证回车能提交） */
.vh-submit {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
/*
 * ⚠️ [hidden] 必须比组件类优先：
 *    `hidden` 属性只声明「UA 样式表里的 display:none」，任何作者样式表的 display
 *    （例如 .btn{display:inline-flex}）都会把它盖掉 ——
 *    表现是「批量删除 (0)」在没勾选时依然显示、「导入」面板默认展开。
 */
[hidden] { display: none !important; }
/* 遮罩：原版 bg-black/40 */
.modal-mask { position: absolute; inset: 0; background: var(--c-overlay); }

.modal-panel {
    position: relative;
    display: flex;
    flex-direction: column;
    width: calc(100% - 32px);
    /* 默认 = **L 级**（DESIGN §6.5）：复杂表单；其它级别见下方 .modal--s/m/xl */
    max-width: 760px;
    max-height: 80vh;
    margin: 6vh auto 0;
    background: var(--c-surface);
    border-radius: var(--r-xl);
    /* 弹窗阴影：DESIGN §5 --shadow-lg（P1-5 已切换；P1-d 起回退用旧值 0 10px 24px -8px #0000002e, 0 2px 6px -2px #0000001f）*/
    box-shadow: var(--shadow-lg);
    overflow: hidden;
    animation: modal-in .16s ease-out;   /* 入场动画：DESIGN §8-2 允许保留 */
}
@keyframes modal-in {
    from { opacity: 0; transform: translateY(-8px) scale(.98); }
    to   { opacity: 1; transform: none; }
}

/* ==========================================================================
   弹窗分级（DESIGN.md §6.5 / 归级约定）：**默认（无修饰类）= L 级**
   调用方在 `.modal` 上声明：.modal--s / .modal--m / .modal--l / .modal--xl
   · S  400px / max 60vh —— 确认、提示
   · M  600px / max 70vh —— 简单表单、导入
   · L  760px / max 80vh —— 复杂表单（默认）
   · XL 960px / max 80vh —— 多栏/多步、灯箱
   §6.5-1 的视口上限（90% 宽 / 85vh 高）由「各级均 ≤ 90% 宽、≤ 80vh」天然满足。
   ========================================================================== */
.modal--s  .modal-panel { max-width: 400px; max-height: 60vh; }
.modal--m  .modal-panel { max-width: 600px; max-height: 70vh; }
.modal--l  .modal-panel { max-width: 760px; max-height: 80vh; }
.modal--xl .modal-panel { max-width: 960px; max-height: 80vh; }

.modal-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    /* 上 16px = §6.5-6「标题与内容间距」；左右 24px = §6.5-5「弹窗内边距 24px」*/
    padding: var(--sp-4) var(--sp-6);
    border-bottom: 1px solid var(--c-border);
    flex-shrink: 0;   /* 头部固定，不随内容滚动（§6.5-3）*/
}
/* 标题 = 区块标题 → DESIGN §3 的 h2（16px / 600）*/
.modal-title { margin: 0; font-size: var(--fs-h2); font-weight: var(--fw-h2); color: var(--c-text); }
.modal-close {
    border: 0;
    background: transparent;
    color: var(--c-text-muted);
    font-size: 20px;
    line-height: 1;
    padding: 2px 7px;
    border-radius: 8px;
    cursor: pointer;
}
.modal-close:hover { background: var(--c-bg-muted); color: var(--c-text-mid); }

/* 弹窗内容区：**全站唯一基座**（DESIGN §6.5-5 内边距 24px；移动端见下方媒体查询）
   旧版像素口径里那条 `.modal-body { padding: 20px }` 已删除（死值）。 */
.modal-body { padding: var(--sp-6); overflow-y: auto; }
/* 弹窗内的表单不再自带外边距/卡片边框（卡片就是弹窗本身） */
.modal-body .card { border: 0; box-shadow: none; margin: 0; border-radius: 0; }
/* ⚠️ bottom 与内容区内边距强耦合 → 用 token 表达，避免 padding 再变时错位 */
.modal-body .form-actions { position: sticky; bottom: calc(var(--sp-6) * -1); background: var(--c-surface); }
.modal-state { padding: 48px 20px; text-align: center; color: var(--c-text-sub); font-size: 13px; }
.modal-state.is-error { color: var(--c-danger); }

@media (max-width: 640px) {
    /* 移动端：允许全屏（§6.5-7），但高度仍受 §6.5-1 上限约束（90vh → 85vh）*/
    .modal-panel { width: 100%; max-width: none; max-height: 85vh; margin: 0; border-radius: 0; }
    /* 分级类特异性高于上面的 .modal-panel，必须一并还原为全屏 */
    .modal--s .modal-panel,
    .modal--m .modal-panel,
    .modal--l .modal-panel,
    .modal--xl .modal-panel { max-width: none; max-height: 85vh; }
    .modal-body { padding: var(--sp-4); }   /* 16px：小屏分级，仍满足 §8-3「4 的倍数」*/
}

/* ---------- 详情（只读）---------- */
.detail-card { margin: 0; }
.detail-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 0;
    margin: 0;
    border-top: 1px solid var(--c-border);
}
.detail-item {
    display: flex;
    gap: 10px;
    padding: 11px 14px;
    border-bottom: 1px solid var(--c-border);
    min-width: 0;
}
/* 长文本 / JSON 占满整行 */
.detail-item.is-wide { grid-column: 1 / -1; flex-direction: column; gap: 6px; }
.detail-item dt {
    flex: 0 0 104px;
    color: var(--c-text-sub);
    font-size: 13px;
    line-height: 1.7;
}
.detail-item dt .muted { font-size: 11px; margin-left: 4px; }
.detail-item dd {
    margin: 0;
    flex: 1;
    min-width: 0;
    font-size: 13px;
    line-height: 1.7;
    word-break: break-word;
}
/* 长文本：详情页完整展示但限制高度，避免一条正文把弹窗撑爆 */
.fv-long {
    white-space: pre-wrap;
    max-height: 260px;
    overflow-y: auto;
    background: var(--c-bg);
    border: 1px solid var(--c-border);
    border-radius: 8px;
    padding: 8px 10px;
}
.fv-long.is-clamp {
    background: none;
    border: 0;
    padding: 0;
    max-height: none;
    overflow: visible;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.fv-thumb {
    width: 56px;
    height: 56px;
    object-fit: cover;
    border-radius: 8px;
    border: 1px solid var(--c-border);
    display: block;
}
/* 多图列（images / 帖子配图）的缩略图排：JSON 数组解析后的横向图片墙 */
.fv-imgs {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    vertical-align: middle;
    flex-wrap: wrap;
}
.fv-imgs .fv-thumb {
    width: 44px;
    height: 44px;
}

/* 折叠的「全部原始字段」 */
.detail-raw {
    margin: 12px 14px 0;
    border: 1px dashed var(--c-border);
    border-radius: var(--r-lg);
    background: var(--c-bg-subtle);
}.detail-raw > summary {
    padding: 9px 12px;
    cursor: pointer;
    font-size: 12px;
    color: var(--c-text-sub);
    user-select: none;
}
.detail-raw > summary:hover { color: var(--c-text); }
.detail-raw .detail-grid { border-top: 1px solid var(--c-border); }
.detail-raw .detail-item { padding: 8px 12px; }
.detail-raw .detail-item dt { flex: 0 0 132px; font-size: 12px; }
.detail-raw code { background: var(--c-bg-subtle); padding: 1px 5px; border-radius: 5px; }


/* ==========================================================================
   列表页工具栏 / 状态 chip / 批量操作栏
   对齐原版：圆角搜索框（图标 + 透明输入框）+ 一排状态 chip + 底部批量条
   ========================================================================== */

/* 搜索框：原版 `flex items-center gap-2 border border-gray-200 rounded-lg px-2.5 py-1.5 bg-white` */
.search-box {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 0 1 280px;
    min-width: 180px;
    padding: 6px 10px;
    background: var(--c-surface);
    border: 1px solid var(--c-border);
    border-radius: var(--r-lg);
}
.search-box:focus-within { border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }
.search-ico { color: var(--c-text-muted); font-size: 14px; line-height: 1; flex-shrink: 0; }
.search-input {
    flex: 1;
    min-width: 0;
    border: 0;
    outline: none;
    background: transparent;
    font-size: 14px;
    color: var(--c-text);
    font-family: inherit;
}

/* 状态 chip 行 */
.chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    padding: 0 16px 14px;
}
.chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 4px 10px;
    border-radius: 8px;
    border: 1px solid var(--c-border);
    background: var(--c-surface);
    color: var(--c-text-mid);
    font-size: 12px;
    line-height: 1.5;
    transition: background .15s, color .15s, border-color .15s;
}
.chip:hover { background: var(--c-bg-subtle); text-decoration: none; }
.chip.is-on {
    background: var(--brand-soft);
    border-color: transparent;
    color: var(--brand);
    font-weight: 600;
}

/* ============================================================================
   系统日志 /admin/logs —— 严格对齐旧版 src/components/system-logs.tsx
   结构：工具栏（无卡片外壳）→ 级别分段标签 → 表格卡 → 分页（仅总页数 > 1 时）
   ============================================================================ */
.syslog-wrap { display: flex; flex-direction: column; gap: var(--sp-4); }

/* ① 工具栏：旧版 `flex items-center justify-between gap-4 flex-wrap` */
.syslog-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-4);
    flex-wrap: wrap;
}
.syslog-bar-left { display: flex; align-items: center; gap: var(--sp-2); flex: 1 1 auto; min-width: 0; }
.syslog-bar-right { display: flex; align-items: center; gap: var(--sp-2); }

/* 搜索：旧版 `relative flex-1 max-w-md` + Input `pl-10` + 绝对定位放大镜 */
.syslog-search { position: relative; flex: 1 1 auto; max-width: 448px; min-width: 180px; }
.syslog-search-ico {
    position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
    display: inline-flex; color: var(--c-text-muted); pointer-events: none;
}
.syslog-search-ico svg { width: 16px; height: 16px; display: block; }
.syslog-input {
    width: 100%; height: 36px;
    padding: 0 var(--sp-4) 0 40px;
    border: 1px solid var(--c-border);
    border-radius: 10px;
    background: var(--c-surface);
    color: var(--c-text);
    font-family: inherit; font-size: var(--fs-body);
    box-shadow: var(--shadow-sm);
}
.syslog-input::placeholder { color: var(--c-text-muted); }
.syslog-input:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }

/* 模块筛选：旧版 `SelectTrigger w-40`（160px）+ Filter 图标 */
.syslog-select-wrap { position: relative; flex: 0 0 160px; width: 160px; }
.syslog-select-ico {
    position: absolute; left: 10px; top: 50%; transform: translateY(-50%);
    display: inline-flex; color: var(--c-text-muted); pointer-events: none;
}
.syslog-select-ico svg { width: 16px; height: 16px; display: block; }
.syslog-select {
    width: 100%; height: 36px;
    padding: 0 8px 0 32px;
    border: 1px solid var(--c-border);
    border-radius: 10px;
    background: var(--c-surface);
    color: var(--c-text);
    font-family: inherit; font-size: var(--fs-body);
    box-shadow: var(--shadow-sm);
    cursor: pointer;
}
.syslog-select:focus { outline: none; border-color: var(--brand); }

/* 工具栏右组：刷新（36×36 方形图标按钮）+ 导出日志（描边按钮） */
.syslog-iconbtn {
    display: inline-flex; align-items: center; justify-content: center;
    width: 36px; height: 36px; padding: 0;
    border: 1px solid var(--c-border);
    border-radius: 10px;
    background: var(--c-surface);
    color: var(--c-text);
    cursor: pointer;
    box-shadow: var(--shadow-sm);
}
.syslog-iconbtn:hover { border-color: var(--c-primary); }
.syslog-iconbtn svg { width: 16px; height: 16px; display: block; }
.syslog-outlinebtn {
    display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
    height: 36px; padding: 0 var(--sp-4);
    border: 1px solid var(--c-border);
    border-radius: 10px;
    background: var(--c-surface);
    color: var(--c-text);
    font-size: var(--fs-body); font-weight: 500;
    box-shadow: var(--shadow-sm);
}
.syslog-outlinebtn:hover { border-color: var(--c-primary); text-decoration: none; }
.syslog-outlinebtn svg { width: 16px; height: 16px; display: block; }

/* ② 级别标签：旧版 TabsList `grid grid-cols-5 w-full max-w-md h-9 rounded-lg bg-muted p-1` */
.syslog-tabs {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    width: 100%; max-width: 448px;
    height: 36px; padding: 4px;
    background: var(--c-bg-muted);
    border-radius: 10px;
}
.syslog-tab {
    display: inline-flex; align-items: center; justify-content: center;
    padding: 0 var(--sp-3);
    border-radius: 10px;
    font-size: var(--fs-body); font-weight: 500;
    color: var(--c-text-sub);
    /* 旧版 TabsTrigger 是 whitespace-nowrap：标签恒为一行（数字变长时宁可溢出也不换行） */
    white-space: nowrap;
    transition: background .15s, color .15s, box-shadow .15s;
}
.syslog-tab:hover { color: var(--c-text); text-decoration: none; }
.syslog-tab.is-on { background: var(--c-surface); color: var(--c-text); box-shadow: var(--shadow-sm); }

/* ③ 表格卡：旧版 Card `rounded-xl border bg-card shadow` + CardContent `p-0` */
.syslog-card {
    background: var(--c-surface);
    border: 1px solid var(--c-border);
    border-radius: 10px;
    box-shadow: var(--shadow-md);
    overflow: hidden;
}
/* 表格：旧版 `w-full text-sm`；th/td `px-4 py-3`；表头灰底 + 500 灰字 */
.syslog-table { width: 100%; border-collapse: collapse; font-size: var(--fs-body); }
.syslog-table th,
.syslog-table td { padding: 12px var(--sp-4); text-align: left; vertical-align: middle; }
.syslog-table thead th {
    background: var(--c-bg-subtle);
    color: var(--c-text-sub);
    font-weight: 500;
    font-size: var(--fs-body);
    white-space: nowrap;
}
.syslog-table tbody td { border-top: 1px solid var(--c-border); }
.syslog-table tbody tr:hover { background: var(--c-bg-subtle); }
.syslog-empty { text-align: center; color: var(--c-text-muted); padding: 48px var(--sp-4); }

/* 单元格口径（旧版 text-xs / font-medium / max-w-xs truncate） */
.syslog-time    { color: var(--c-text-sub); font-size: var(--fs-sm); white-space: nowrap; }
.syslog-action  { font-weight: 500; }
.syslog-details {
    color: var(--c-text-mid); font-size: var(--fs-sm);
    max-width: 320px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.syslog-ip      { color: var(--c-text-muted); }
.syslog-ip code { font-size: var(--fs-sm); }

/* 级别徽章（旧版 Badge `rounded-md border px-2.5 py-0.5 text-xs font-semibold` + 12px 图标） */
.syslog-badge {
    display: inline-flex; align-items: center;
    padding: 2px 10px;
    border: 1px solid transparent;
    border-radius: 10px;
    font-size: var(--fs-sm); font-weight: 600;
    white-space: nowrap;
}
.syslog-badge-ico { display: inline-flex; margin-right: 4px; }
.syslog-badge-ico svg { width: 12px; height: 12px; display: block; }
.syslog-badge.lv-info    { background: var(--c-info-light);    color: var(--c-info-dark); }
.syslog-badge.lv-success { background: var(--c-success-light); color: var(--c-success-dark); }
.syslog-badge.lv-warn    { background: var(--c-warning-light); color: var(--c-warning-dark); }
.syslog-badge.lv-error   { background: var(--c-danger-light);  color: var(--c-danger-dark); }

/* ④ 分页：旧版 `flex items-center justify-between px-4 py-3 border-t` */
.syslog-pager {
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--sp-3); padding: 12px var(--sp-4);
    border-top: 1px solid var(--c-border);
    flex-wrap: wrap;
}
.syslog-pager-info { font-size: var(--fs-body); color: var(--c-text-sub); }
.syslog-pager-info b { color: var(--c-text); }
.syslog-pager-btns { display: flex; align-items: center; gap: var(--sp-2); }
.syslog-pager-size { display: inline-flex; align-items: center; }
.syslog-pager-size select {
    height: 36px; padding: 0 var(--sp-2);
    font-family: inherit; font-size: var(--fs-body);
    color: var(--c-text); background: var(--c-surface);
    border: 1px solid var(--c-border); border-radius: 10px;
    cursor: pointer;
}
.syslog-pager-size select:focus { outline: none; border-color: var(--brand); }
.syslog-pgbtn {
    display: inline-flex; align-items: center; justify-content: center;
    width: 36px; height: 36px;
    border: 1px solid var(--c-border);
    border-radius: 10px;
    background: var(--c-surface);
    color: var(--c-text);
}
.syslog-pgbtn:hover { background: var(--c-bg-subtle); text-decoration: none; }
.syslog-pgbtn.is-disabled { opacity: .5; cursor: not-allowed; }
.syslog-pgbtn svg { width: 16px; height: 16px; display: block; }
.syslog-pgnum { min-width: 60px; text-align: center; font-size: var(--fs-body); color: var(--c-text-sub); }


/* 勾选列 */
.table .th-check { width: 40px; text-align: center; padding-left: var(--sp-2); padding-right: var(--sp-2); }
.table .th-check input { width: 15px; height: 15px; accent-color: var(--brand); cursor: pointer; }

/* 批量操作条：原版 `flex flex-wrap items-center gap-2 mt-3 pt-3 border-t border-gray-50` */
.bulk-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin: 0;
    padding: var(--sp-3) var(--sp-4);
    border-top: 1px solid var(--c-bg-muted);
}
.bulk-bar[hidden] { display: none; }
.bulk-count { font-size: 12px; font-weight: 700; color: var(--brand); }
.bulk-count b { font-size: 13px; }
.bulk-btn {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 5px 10px;
    border-radius: 8px;
    border: 1px solid var(--c-border);
    background: var(--c-surface);
    color: var(--c-text-mid);
    font-size: 12px;
    font-family: inherit;
    cursor: pointer;
    transition: background .15s;
}
.bulk-btn:hover { background: var(--c-bg-subtle); }

/* ==========================================================================
   仪表盘（逐字对齐线上前端；规格见 /memories/repo/original-dashboard-spec.md）
   图表是服务端直出的内联 SVG，不依赖任何 JS 图表库。
   ========================================================================== */

/* ---------- Hero 渐变横幅 ---------- */
/* 原版：bg-gradient-to-br from-[#B91C1C] via-[#C81623] to-[#DC2626]
        rounded-2xl p-6 shadow-lg shadow-red-200/50 overflow-hidden */
.dash-hero {
    position: relative;
    overflow: hidden;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 24px;
    margin-bottom: 24px;
    border-radius: 16px;
    background: linear-gradient(to bottom right, var(--c-danger), var(--c-primary), var(--c-danger));
    color: var(--c-text-invert);
    box-shadow: 0 10px 15px -3px rgba(254, 202, 202, .5), 0 4px 6px -4px rgba(254, 202, 202, .5);
}
/* 右上角装饰：原版是 176×176 的大五角星 SVG（opacity-10），不是圆 */
.hero-star {
    position: absolute;
    top: -40px;                 /* -top-10 */
    right: -24px;               /* -right-6 */
    width: 176px;               /* w-44 */
    height: 176px;
    opacity: .1;
    pointer-events: none;
}
.hero-star svg { width: 100%; height: 100%; display: block; fill: var(--c-text-invert); }
.dash-hero::after {
    content: '';
    position: absolute;
    top: 20px;
    right: 64px;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: rgba(252, 211, 77, .6);
}
.hero-left, .hero-status { position: relative; z-index: 1; }
.hero-title {
    margin: 0;
    font-size: 20px;
    font-weight: 900;
    letter-spacing: .025em;
    display: flex;
    align-items: center;
    gap: 10px;                 /* 原版 gap-2.5 */
}
/* 标题前的 Sparkles（原版 w-5 h-5 text-amber-300） */
.hero-title-ico { width: 20px; height: 20px; flex-shrink: 0; color: #fcd34d; }
/* 副标题：原版把「站名+管理系统概览」与标语合成一行、用「 · 」连接
   （admin.index.tsx:230-232），不再单独占一行标语 */
.hero-sub { margin: 6px 0 0; font-size: 14px; color: rgba(255, 255, 255, .8); }

/* 系统状态卡：原版 bg-white/10 backdrop-blur border border-white/20 rounded-xl px-4 py-2.5 */
.hero-status {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 16px;
    border-radius: 12px;
    background: rgba(255, 255, 255, .1);
    border: 1px solid rgba(255, 255, 255, .2);
    backdrop-filter: blur(4px);
}
.hs-block { display: flex; align-items: center; gap: 6px; }
/* 左格：图标在上、文字在下、整体居中（原版 flex flex-col items-center） */
.hs-block.is-ico { flex-direction: column; align-items: center; gap: 2px; }
/* 右格：两行文案左对齐 */
.hs-block.is-col { flex-direction: column; align-items: flex-start; gap: 0; }
/* Activity 图标（原版 w-4 h-4 text-emerald-300） */
.hs-ico { width: 16px; height: 16px; flex-shrink: 0; color: #6ee7b7; }
.hs-label { font-size: 10px; color: rgba(255, 255, 255, .7); }
.hs-sep { width: 1px; height: 32px; background: rgba(255, 255, 255, .2); }
.hs-online {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 14px;
    font-weight: 700;
}
.hs-online i {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: #34d399;
    animation: hs-pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;
}
@keyframes hs-pulse { 50% { opacity: .35; } }
.hs-note { font-size: 10px; color: rgba(255, 255, 255, .7); }

/* ---------- 12 张统计卡 ---------- */
/* 原版：grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-6 gap-4 */
.dash-cards {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px;
    margin-bottom: 24px;
}
@media (min-width: 768px)  { .dash-cards { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1024px) { .dash-cards { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (min-width: 1280px) { .dash-cards { grid-template-columns: repeat(6, minmax(0, 1fr)); } }

/* 原版：group relative bg-white rounded-xl border border-gray-200 p-5 shadow-sm
        hover:shadow-md hover:-translate-y-0.5 transition-all duration-200 overflow-hidden */
.dash-card {
    position: relative;
    display: block;
    overflow: hidden;
    padding: 20px;
    background: var(--c-surface);
    border: 1px solid var(--c-border);
    border-radius: 12px;
    box-shadow: var(--shadow-sm);
    color: inherit;
    text-align: left;
    transition: box-shadow .2s, transform .2s, border-color .2s;
}
.dash-card:hover {
    box-shadow: var(--shadow-md);
    transform: translateY(-2px);
    text-decoration: none;
}
.dc-head { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
/* 原版：w-10 h-10 rounded-xl bg-gradient-to-br <color>，白图标 */
.dc-ico {
    width: 40px;
    height: 40px;
    flex: 0 0 40px;
    display: grid;
    place-items: center;
    border-radius: 12px;
    color: var(--c-text-invert);
    line-height: 1;
}
.dc-ico .ico { width: 20px; height: 20px; }      /* 原版图标 w-5 h-5 */
/* 卡片右上角同色渐变小圆（原版 absolute -right-3 -top-3 w-16 h-16 rounded-full
   opacity-[0.07] group-hover:opacity-[0.14] bg-gradient-to-br <color>） */
.dc-blob {
    position: absolute;
    top: -12px;
    right: -12px;
    width: 64px;
    height: 64px;
    border-radius: 50%;
    opacity: .07;
    transition: opacity .2s;
}
.dash-card:hover .dc-blob { opacity: .14; }
.dc-blue    { background: linear-gradient(to bottom right, var(--c-info), var(--c-info)); }
.dc-amber { background: linear-gradient(to bottom right, var(--c-warning), var(--c-warning-dark)); }
.dc-pink    { background: linear-gradient(to bottom right, #ec4899, var(--c-danger)); }
.dc-red     { background: linear-gradient(to bottom right, var(--c-danger), var(--c-danger)); }
.dc-teal    { background: linear-gradient(to bottom right, #14b8a6, #0d9488); }
.dc-emerald { background: linear-gradient(to bottom right, var(--c-success), var(--c-success)); }
.dc-indigo  { background: linear-gradient(to bottom right, #6366f1, #4f46e5); }
.dc-purple  { background: linear-gradient(to bottom right, #a855f7, #9333ea); }
.dc-cyan    { background: linear-gradient(to bottom right, #06b6d4, #0891b2); }
.dc-sky     { background: linear-gradient(to bottom right, #0ea5e9, #0284c7); }
.dc-rose    { background: linear-gradient(to bottom right, #f43f5e, #db2777); }
.dc-orange { background: linear-gradient(to bottom right, var(--c-warning), var(--c-warning-dark)); }
/* 「广告投放」原版是 from-yellow-500 to-yellow-600 */
.dc-yellow  { background: linear-gradient(to bottom right, var(--c-warning), var(--c-warning)); }

.dc-label {
    flex: 1;
    min-width: 0;
    font-size: 14px;
    font-weight: 500;
    color: var(--c-text-sub);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.dc-foot { display: flex; align-items: flex-end; justify-content: space-between; }
.dc-value {
    font-size: 24px;
    font-weight: 700;
    color: var(--c-text);
    line-height: 1.15;
    transition: color .2s;
}
.dash-card:hover .dc-value { color: var(--brand); }
/* 原版是 ArrowUpRight 图标（w-4 h-4），不是字符 ↗ */
.dc-arrow { width: 16px; height: 16px; color: var(--c-border-strong); transition: color .2s; }
.dash-card:hover .dc-arrow { color: var(--brand); }

/* ---------- 图表卡 ---------- */
/* 原版：grid grid-cols-1 xl:grid-cols-2 gap-6
        卡片 bg-white rounded-2xl border border-gray-200 p-5 shadow-sm */
.dash-charts {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 24px;
    margin-bottom: 24px;
}
@media (min-width: 1280px) { .dash-charts { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

.chart-card {
    background: var(--c-surface);
    border: 1px solid var(--c-border);
    border-radius: 16px;
    padding: 20px;
    box-shadow: var(--shadow-sm);
}
.cc-head { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; }
/* 原版：w-8 h-8 rounded-lg bg-<c>-50 text-<c>-600 flex items-center justify-center */
.cc-ico {
    width: 32px;
    height: 32px;
    flex: 0 0 32px;
    display: grid;
    place-items: center;
    border-radius: 8px;
    line-height: 1;
}
.cc-ico .ico { width: 16px; height: 16px; }      /* 原版图标 w-4 h-4 */
/* 「会员等级分布」卡右上角那个灰色 Wallet —— 原版是图标不是链接（admin.index.tsx:405） */
.cc-head-ico { width: 16px; height: 16px; margin-left: auto; flex-shrink: 0; color: var(--c-border-strong); }
.cc-red  { background: var(--c-danger-light); color: var(--c-primary); }
.cc-blue { background: var(--c-info-light); color: var(--c-info-dark); }
.cc-pink { background: #fdf2f8; color: #db2777; }
.cc-rose { background: var(--c-danger-light); color: var(--c-danger-dark); }
/* 「公益与捐赠」原版是 bg-red-50 + text-red-500（不是品牌色） */
.cc-red500 { background: var(--c-danger-light); color: var(--c-danger); }
.cc-title { font-size: 14px; font-weight: 700; color: var(--c-text); }
.cc-sub { margin: 0 0 12px; font-size: 11px; color: var(--c-text-muted); }
.cc-body { position: relative; }
.chart-empty {
    height: 256px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 14px;
    color: var(--c-text-muted);
}

/* 图 / 数值 SVG */
.chart-svg { width: 100%; height: auto; display: block; }
.donut-svg { flex: 0 0 auto; }

/* 双柱图并排（票数 / 金额） */
.chart-split { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; margin-top: 8px; }
.cs-label { margin: 0 0 4px; text-align: center; font-size: 12px; font-weight: 600; color: var(--c-text-mid); }
.cs-total { margin: 6px 0 0; text-align: center; font-size: 18px; font-weight: 700; color: var(--c-text); }
.cs-total-label { margin: 0; text-align: center; font-size: 10px; color: var(--c-text-muted); }

/* 环形图 + 图例 */
.donut-wrap { display: flex; align-items: center; gap: 20px; flex-wrap: wrap; }
.chart-legend {
    list-style: none;
    margin: 0;
    padding: 0;
    flex: 1;
    min-width: 150px;
}
.chart-legend li {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 3px 0;
    font-size: 12px;
    color: var(--c-text-mid);
}
.lg-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.lg-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lg-val { font-weight: 600; color: var(--c-text); }

/* 底部数字条：原版 mt-3 grid gap-2 border-t border-gray-100 pt-3 */
.stat-strip {
    display: grid;
    gap: 8px;
    margin-top: 14px;
    padding-top: 12px;
    border-top: 1px solid var(--c-bg-muted);
    text-align: center;
}
.stat-strip.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.stat-strip.grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.ss-val { margin: 0; font-size: 15px; font-weight: 700; color: var(--c-text); }
.ss-label { margin: 2px 0 0; font-size: 10px; color: var(--c-text-muted); }

/* 窄屏里环形图与图例竖排，避免挤压 */
@media (max-width: 640px) {
    .donut-wrap { justify-content: center; }
    .chart-split { grid-template-columns: minmax(0, 1fr); }
    .stat-strip.grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ---------- 顶栏「切换查看的组」下拉（对齐原版 <header> 右侧 select） ---------- */
/* 原版：px-2.5 py-1.5 text-sm text-gray-600 bg-gray-50 border border-gray-200
        rounded-lg hover:bg-gray-100 cursor-pointer outline-none  + hidden sm:block */
.branch-picker {
    padding: 6px 10px;
    font-size: 14px;
    font-family: inherit;
    color: var(--c-text-mid);
    background: var(--c-bg-subtle);
    border: 1px solid var(--c-border);
    border-radius: 8px;
    cursor: pointer;
    outline: none;
    max-width: 190px;
    transition: background .15s, border-color .15s;
}
.branch-picker:hover { background: var(--c-bg-muted); }
.branch-picker:focus { border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }
/* 原版是 hidden sm:block（窄屏隐藏，避免挤掉面包屑） */
@media (max-width: 640px) { .branch-picker { display: none; } }

/* ---------- 仪表盘图表卡：卡片头（标题 + 副标竖排 + 右上跳转链接） ---------- */
/* 原版：flex items-center justify-between mb-1；左侧图标 + (h3 标题 + p 副标)；右侧 管理→ */
.cc-head { align-items: center; margin-bottom: 4px; }
.cc-head-text { display: flex; flex-direction: column; min-width: 0; }
.cc-title { font-size: 14px; font-weight: 700; color: var(--c-text); }
.cc-sub { font-size: 11px; color: var(--c-text-muted); }
.cc-link {
    margin-left: auto;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    gap: 2px;                            /* 原版 gap-0.5 */
    font-size: 12px;
    color: var(--brand);
    white-space: nowrap;
}
.cc-link-ico { width: 14px; height: 14px; }   /* ChevronRight w-3.5 h-3.5 */
.cc-link:hover { text-decoration: underline; }

/* ---------- 环形图并排（赛事购票卡：票数 / 金额） ---------- */
.cs-pie { height: 132px; display: flex; align-items: center; justify-content: center; }
.cs-pie .donut-svg { width: 132px; height: 132px; }
.cs-total.is-money { color: var(--brand); }

/* ---------- 3/5 图 + 2/5 图例（会员等级 / 商城 / 捐赠） ---------- */
.pie-split { display: flex; align-items: center; gap: 0; }
.pie-split-chart { flex: 0 0 60%; height: 168px; }
.pie-split-legend { flex: 1 1 40%; min-width: 0; padding-left: 16px; }
@media (max-width: 640px) {
    .pie-split { flex-direction: column; }
    .pie-split-chart { flex: 0 0 auto; width: 100%; }
    .pie-split-legend { padding-left: 0; padding-top: 12px; width: 100%; }
}

/* 图例行：● 名称 数量 [百分比] */
.chart-legend li { padding: 5px 0; gap: 8px; }
.chart-legend .lg-dot { width: 10px; height: 10px; }
.chart-legend.with-pct .lg-dot { width: 10px; height: 10px; }
.chart-legend .lg-name { font-size: 12px; color: var(--c-text-mid); }
.chart-legend .lg-val { font-size: 14px; font-weight: 700; color: var(--c-text); }
.chart-legend .lg-pct {
    font-size: 10px;
    color: var(--c-text-muted);
    width: 32px;
    text-align: right;
    flex-shrink: 0;
}

/* ---------- 明细行（赛事购票卡底部：● 标题 N 张 ¥金额） ---------- */
.chart-rows {
    list-style: none;
    margin: 12px 0 0;
    padding: 12px 0 0;
    border-top: 1px solid var(--c-bg-muted);
}
.chart-rows li {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 3px 0;
    font-size: 12px;
}
.cr-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.cr-name { flex: 1; min-width: 0; color: var(--c-text-mid); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cr-badge { flex-shrink: 0; color: var(--c-text-muted); }
.cr-val { flex-shrink: 0; width: 76px; text-align: right; color: var(--c-text); font-weight: 600; }

/* ==========================================================================
   会员管理 · 分布图卡（原版 `function lf({data,total,label})` 的三张甜甜圈）
   原版：viewBox 0 0 140 140、svg w-32 h-32、r=44、strokeWidth=22、butt 端点
   图例：flex-wrap justify-center gap-x-3 gap-y-1 mt-3 max-h-24 overflow-y-auto
   ========================================================================== */
.dist-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 16px;
    margin-top: 16px;
}
@media (max-width: 900px) {
    .dist-grid { grid-template-columns: minmax(0, 1fr); }
}
.dist-card {
    background: var(--c-surface);
    border: 1px solid var(--c-border);
    border-radius: 12px;
    padding: 20px;
}
.dist-card.is-lead { border-radius: 16px; box-shadow: var(--shadow-sm); }
.dist-head { display: flex; align-items: center; gap: 8px; margin-bottom: 16px; }
.dist-card.is-lead .dist-head { justify-content: space-between; margin-bottom: 4px; }
.dist-head-l { display: flex; align-items: center; gap: 8px; }
.dist-ico {
    width: 20px; height: 20px; border-radius: 6px;
    display: flex; align-items: center; justify-content: center;
    font-size: 12px; color: var(--brand); background: var(--c-info-light);
}
.dist-ico.is-lg { width: 32px; height: 32px; border-radius: 8px; font-size: 15px; color: var(--c-info-dark); }
.dist-title { font-size: 13px; font-weight: 700; color: var(--c-text); }
.dist-sub { font-size: 11px; color: var(--c-text-muted); }
.dist-empty { font-size: 13px; color: var(--c-text-muted); text-align: center; padding: 48px 0; }

/* donutMini 的标记 */
.dm-wrap { display: flex; flex-direction: column; align-items: center; }
.dm-wrap svg { width: 128px; height: 128px; display: block; }
.dm-label { font-size: 11px; fill: var(--c-text-muted); }
.dm-total { font-size: 16px; font-weight: 700; fill: var(--c-text); }
.dm-legend {
    display: flex; flex-wrap: wrap; justify-content: center;
    column-gap: 12px; row-gap: 4px; margin-top: 12px;
    max-height: 96px; overflow-y: auto; width: 100%;
}
.dm-item { display: flex; align-items: center; gap: 6px; font-size: 12px; }
.dm-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.dm-name { color: var(--c-text-mid); max-width: 60px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dm-val { color: var(--c-text-muted); }

/* Tab 上的计数徽标：原版 `{label} <span class="ml-1 text-xs">({count})</span>` */
.st-tab-count { margin-left: 4px; font-size: 11px; opacity: .75; }

/* 会员列表工具栏左侧的「贡献分」提示条 */
.member-hint {
    display: inline-flex; align-items: center; gap: 4px;
    padding: 4px 8px; border-radius: 4px;
    font-size: 12px; color: var(--c-warning-dark); background: var(--c-warning-light);
}

/* 页面标题区（原版 `<h2 class="text-2xl font-bold text-gray-800">` + `<p class="text-sm text-gray-500 mt-1">`） */
.page-head { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 12px; }
.page-title { margin: 0; font-size: 24px; line-height: 1.3; font-weight: 700; color: var(--c-text); }
.page-desc { margin: 4px 0 0; flex: 1 1 100%; font-size: 13px; color: var(--c-text-sub); }
.page-head-extra { margin-left: auto; display: flex; gap: 8px; flex-wrap: wrap; }
/* 页头（DESIGN §7.1：高 48px，底部间距 16px）——**只作用于页面级页头**：
   `:not(.card *)` 排除卡片内的小标题（events/roster.php 的 5 处 .page-head 就在 .card 里，
   它们自带 padding，若套 48px 会把卡片内间距撑坏）。
   注：:not(.card *) 的特异性 = (.card) → 本规则 (0,2,0) 高于 .res-page-head (0,1,0)。 */
.page-head:not(.card *) { min-height: 48px; margin-bottom: 16px; align-items: center; }

/* 积分流水「类型」徽标配色（原版 R1(reason) 的 5 种） */
.tag.tone-blue   { background: var(--c-info-light); color: var(--c-info-dark); }
/* 状态徽标的蓝底变体（旧版 statusBadge：报名中 = bg-blue-100 text-blue-700） */
.tag.tag-info { background: var(--c-info-light); color: var(--c-info-dark); border-color: var(--c-info-border); }
.tag.tone-green  { background: var(--c-success-light); color: var(--c-success-dark); }
.tag.tone-amber  { background: var(--c-warning-light); color: var(--c-warning-dark); }
.tag.tone-orange { background: var(--c-warning-light); color: var(--c-warning-dark); }
.tag.tone-purple { background: var(--c-info-light); color: var(--c-info-dark); }

/* ==========================================================================
   会员列表（原版 M1 的 27 列）
   ========================================================================== */
.is-col-hidden { display: none; }

.cell-mono  { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
.cell-dim   { color: var(--c-border-strong); font-size: 12px; }
.cell-ok    { color: var(--c-success-dark); font-size: 12px; }
.cell-bad   { color: var(--c-danger); font-size: 12px; }
.cell-strong{ font-weight: 700; }
.fw-500 { font-weight: 500; }

/* 等级徽标：原版 `px-2 py-0.5 rounded text-xs text-white` + 等级自定义色 */
.badge-level {
    display: inline-block; padding: 2px 8px; border-radius: 4px;
    font-size: 12px; line-height: 1.5; color: var(--c-text-invert);
}

/* 系统日志·级别徽标 + 图标（原版 levelConfig：blue/yellow/red/green-100 底 + 同色文字 + 图标） */
.tag.lv-info    { background: var(--c-info-light); color: var(--c-info-dark); border-color: var(--c-info-border); }
.tag.lv-success { background: var(--c-success-light); color: var(--c-success-dark); border-color: var(--c-success-border); }
.tag.lv-warn    { background: var(--c-warning-light); color: var(--c-warning-dark); border-color: var(--c-warning-border); }
.tag.lv-error   { background: var(--c-danger-light); color: var(--c-danger-dark); border-color: var(--c-danger-border); }
.tag .lv-ico    { margin-right: 4px; font-size: 11px; line-height: 1; }

/* ==========================================================================
   数据备份页 · 模块勾选（原版 admin.data.tsx 的 31 个勾选卡片 + 蓝色统计条）
   ========================================================================== */
.mod-pick-bar {
    display: flex; flex-wrap: wrap; align-items: center; gap: 12px;
    margin: 0 0 10px; padding: 8px 12px;
    background: var(--brand-soft); border-radius: 8px;
    font-size: 13px; color: var(--brand);
}
.mod-pick-bar b { color: var(--brand); }
.mod-pick-bar .btn { margin-left: auto; }

.mod-pick {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 6px 12px; max-height: 340px; overflow-y: auto;
    padding: 10px 12px; border: 1px solid var(--c-border); border-radius: 8px;
    background: var(--c-bg-subtle);
}
.mod-pick-item {
    display: flex; align-items: center; gap: 6px;
    font-size: 13px; color: var(--c-text-mid); cursor: pointer;
}
.mod-pick-item input { accent-color: var(--brand); cursor: pointer; }
.mod-pick-name { font-weight: 500; }
.mod-pick-meta { margin-left: auto; font-size: 12px; color: var(--c-text-muted); }

/* 迁移/升级步骤说明（数据备份页底部） */
.steps { margin: 0; padding-left: 20px; font-size: 13px; line-height: 1.9; color: var(--c-text-mid); }
.steps li + li { margin-top: 4px; }
.steps code { background: var(--c-bg-muted); padding: 1px 4px; border-radius: 3px; font-size: 12px; }

/* ==========================================================================
   附件管理 · 拖拽上传区（原版 admin.attachments.tsx:70-87 的虚线卡片）
   ========================================================================== */
.dropzone {
    display: flex; flex-direction: column; align-items: center; gap: 4px;
    padding: 26px 16px; cursor: pointer; text-align: center;
    border: 2px dashed #d5d9e0; border-radius: 10px; background: var(--c-bg-subtle);
    transition: border-color .15s, background .15s, color .15s;
}
.dropzone:hover { border-color: var(--brand); background: var(--brand-soft); }
.dropzone.is-drag {
    border-color: var(--brand); background: var(--brand-soft);
    box-shadow: 0 0 0 3px rgba(37, 99, 235, .12);
}
.dropzone-ico { font-size: 22px; line-height: 1; color: var(--brand); }
.dropzone-main { font-size: 14px; font-weight: 600; color: var(--c-text-mid); }
.dropzone-hint { font-size: 12px; color: var(--c-text-sub); }
.dropzone-input { display: none; }

.wg-wrap { display: inline-flex; flex-wrap: wrap; gap: 2px; }

/* 行操作按钮（原版：px-2 py-1 text-xs rounded + 各自浅底色） */
/* 操作列 chip 组（第 3 批收尾·裁决 A）：**不换行**。
   原先 flex-wrap:wrap 时，会员列表操作列里 6 个 chip（2 个 .act 按钮 + 1 个内联 form + 3 个 <details class="act-dd">）
   会换行成约 8 行，把 .row-actions 撑到 163px、每行高 187px。
   表格本身是 .table-wrap(overflow-x:auto) → 不换行只把操作列变宽，超出部分由表格横向滚动接管。 */
.row-actions { display: flex; flex-wrap: nowrap; gap: 4px; align-items: flex-start; }
.row-actions .inline { display: inline; margin: 0; }
.act {
    display: inline-block; padding: 2px 8px; border-radius: 4px;
    font-size: 12px; line-height: 1.6; cursor: pointer; border: 0;
    text-decoration: none; white-space: nowrap;
}
.act-blue   { background: var(--c-info-light); color: var(--c-info-dark); }
.act-orange { background: var(--c-warning-light); color: var(--c-warning-dark); }
.act-red    { background: var(--c-danger-light); color: var(--c-danger-dark); }
.act-green  { background: var(--c-success-light); color: var(--c-success-dark); }
.act-gray   { background: var(--c-bg-muted); color: var(--c-text-mid); }
.act-purple { background: var(--c-info-light); color: var(--c-info-dark); }
.act-cyan   { background: var(--c-info-light); color: var(--c-info-dark); }
.act:hover  { filter: brightness(.95); text-decoration: none; }
.act-dd { display: inline-block; position: relative; }
.act-dd > summary { list-style: none; }
.act-pop {
    position: absolute; z-index: 30; top: 100%; left: 0; margin-top: 4px;
    display: flex; gap: 6px; flex-wrap: wrap; padding: 8px;
    background: var(--c-surface); border: 1px solid var(--c-border); border-radius: 8px;
    box-shadow: 0 8px 24px rgba(16, 24, 40, .12); min-width: 220px;
}

/* 工具栏上的两个强调按钮（原版 amber-500 / purple-600） */
.btn-warn   { background: var(--c-warning); color: var(--c-text-invert); border-color: var(--c-warning); }
.btn-warn:hover   { background: var(--c-warning); }
.btn-info, .btn-purple { background: var(--c-info); color: #fff; border-color: var(--c-info); }
.btn-info:hover, .btn-purple:hover { background: var(--c-info-dark); }

/* 「列显示」下拉面板 */
.col-panel {
    position: absolute; z-index: 40; right: 0; top: 100%; margin-top: 6px;
    background: var(--c-surface); border: 1px solid var(--c-border); border-radius: 8px;
    box-shadow: 0 8px 24px rgba(16, 24, 40, .12);
    padding: 10px; min-width: 200px; max-height: 320px; overflow-y: auto;
}
.col-panel label { display: flex; align-items: center; gap: 6px; font-size: 12px; padding: 3px 0; cursor: pointer; }

/* ==========================================================================
   会员设置 Tab · 折叠卡（原版：bg-white rounded-lg border overflow-hidden
   + 整行按钮头 w-full flex items-center justify-between p-4 hover:bg-gray-50
   + 正文 px-4 pb-4 border-t pt-4）
   ========================================================================== */
.st-acc-list { display: flex; flex-direction: column; gap: 16px; }

.st-acc { background: var(--c-surface); border: 1px solid var(--c-border); border-radius: 8px; overflow: hidden; }
.st-acc-head {
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px; width: 100%; padding: 16px; cursor: pointer;
    list-style: none; transition: background .15s;
}
.st-acc-head::-webkit-details-marker { display: none; }
.st-acc-head:hover { background: var(--c-bg-subtle); }
.st-acc-title { margin: 0; font-size: 14px; font-weight: 600; color: var(--c-text); }
.st-acc-side { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.st-acc-sum { font-size: 12px; color: var(--c-text-muted); }
.st-acc-sum-mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; color: var(--c-text-muted); }
.st-acc-chev { color: var(--c-text-muted); font-size: 12px; transition: transform .15s; }
.st-acc[open] .st-acc-chev { transform: rotate(180deg); }
.st-acc-body { padding: 16px; border-top: 1px solid var(--c-border); }

.st-acc-row { display: flex; align-items: flex-end; gap: 12px; flex-wrap: wrap; }
.st-acc-label { display: block; font-size: 12px; color: var(--c-text-sub); margin-bottom: 4px; }
.st-acc-hint { color: var(--c-text-muted); }
.st-acc-input { width: 160px; }
.st-acc-switches { display: flex; flex-direction: column; gap: 4px; }
.st-acc-preview { display: flex; align-items: center; gap: 4px; font-size: 13px; }
.st-acc-preview-val { color: var(--c-info-dark); font-weight: 500; }
.st-acc-tip { margin: 0 0 12px; font-size: 12px; color: var(--c-text-muted); line-height: 1.7; }
.st-acc-sub { font-size: 12px; font-weight: 500; color: var(--c-text-sub); border-bottom: 1px solid var(--c-bg-muted); padding-bottom: 4px; margin: 12px 0 8px; }

/* 编号规则说明（原版 bg-blue-50 border-blue-100 rounded-lg p-3 text-xs text-blue-800） */
.st-acc-note {
    margin-top: 12px; padding: 12px; border-radius: 8px;
    background: var(--c-info-light); border: 1px solid var(--c-info-border);
    font-size: 12px; color: var(--c-info-dark); line-height: 1.8;
}
.st-acc-note-title { margin: 0 0 4px; font-weight: 500; }
.st-acc-note-list { margin: 0; padding-left: 18px; list-style: disc; }

/* 字段必填：可勾 chips（原版 flex flex-wrap gap-2 + rounded px-3 py-1.5 border）
   与只读的灰色 chips */
.fld-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.fld-chip {
    display: inline-flex; align-items: center; gap: 8px;
    padding: 6px 12px; border: 1px solid var(--c-border); border-radius: 4px;
    font-size: 13px; cursor: pointer; transition: background .15s, border-color .15s;
    background: var(--c-surface); color: var(--c-text-mid);
}
.fld-chip:hover { background: var(--c-danger-light); }
.fld-chip input { width: 14px; height: 14px; }
.fld-chip.is-locked {
    cursor: default; background: var(--c-bg-subtle); color: var(--c-text-muted); border-color: var(--c-bg-muted);
}
.fld-chip.is-locked:hover { background: var(--c-bg-subtle); }

/* ==========================================================================
   会员等级管理（原版 grid-cols-1 lg:grid-cols-5 gap-4 的两栏布局）
   左 lg:col-span-2 = 表单卡（p-3 bg-gray-50 rounded-lg border）
   右 lg:col-span-3 = 限时折扣 amber 条 + 等级表格
   ========================================================================== */
.lv-grid { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); gap: 16px; }
@media (max-width: 1024px) { .lv-grid { grid-template-columns: minmax(0, 1fr); } }

.lv-form { background: var(--c-bg-subtle); border: 1px solid var(--c-border); border-radius: 8px; padding: 12px; }
.lv-form-title { margin: 0 0 10px; font-size: 13px; font-weight: 500; color: var(--c-text-mid); }
.lv-form-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.lv-form-grid .input { width: 100%; }
.lv-color { height: 32px; padding: 1px 4px; }
.lv-quiz { display: flex; align-items: center; gap: 6px; margin-top: 10px; cursor: pointer; font-size: 12px; color: var(--c-text-mid); }
.lv-quiz input { width: 14px; height: 14px; }
.lv-benefits-input { width: 100%; height: 64px; resize: none; }
.lv-form-actions { display: flex; gap: 8px; margin-top: 12px; }

.lv-table-wrap { overflow-x: auto; }
.lv-disc-bar {
    display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
    padding: 8px; margin-bottom: 12px; border-radius: 8px;
    background: var(--c-warning-light); border: 1px solid var(--c-warning-border);
}
.lv-disc-label { font-size: 12px; font-weight: 500; color: var(--c-warning-dark); white-space: nowrap; }
.lv-disc-hint { font-size: 11px; color: var(--c-warning-dark); }
.lv-disc { font-size: 12px; font-weight: 500; color: var(--c-warning-dark); background: var(--c-warning-light); padding: 1px 6px; border-radius: 4px; }

.lv-table { font-size: 13px; }
.lv-table th { background: var(--c-bg-subtle); color: var(--c-text-sub); font-weight: 500; text-align: left; }
.lv-table td, .lv-table th { padding: 8px; border-bottom: 1px solid var(--c-bg-muted); }
.lv-table tbody tr:hover { background: var(--c-bg-subtle); }
.lv-swatch { display: inline-block; width: 20px; height: 20px; border-radius: 4px; border: 1px solid var(--c-border); }
.lv-num { font-size: 12px; }
.lv-points { color: var(--c-warning-dark); font-weight: 500; font-size: 12px; }
.lv-benefits { color: var(--c-text-mid); font-size: 12px; max-width: 120px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lv-sort { font-size: 12px; }
.lv-del { display: inline-flex; align-items: center; gap: 4px; }
.lv-del input { width: 12px; height: 12px; }
.lv-table-foot { display: flex; align-items: center; gap: 10px; margin-top: 12px; flex-wrap: wrap; }
.btn-ok { background: var(--c-success); color: var(--c-text-invert); border-color: var(--c-success-border); }
.btn-ok:hover { background: var(--c-success); }

/* 通用资源列表：导出下拉 / 导入折叠框 */
.col-panel-hint { padding: 4px 0 8px; font-size: 11px; color: var(--c-text-muted); border-bottom: 1px solid var(--c-bg-muted); }
.col-panel-item {
    display: block; width: 100%; text-align: left; padding: 6px 0;
    font-size: 12px; color: var(--c-text-mid); background: none; border: 0; cursor: pointer;
}
.col-panel-item:hover { color: var(--brand); }
.imp-box { margin-top: 12px; border: 1px dashed var(--c-border); border-radius: 8px; padding: 10px 12px; }
.imp-sum { font-size: 13px; font-weight: 500; color: var(--c-text-mid); cursor: pointer; }

/* ---------- 会员表单分组（对齐原版「基本信息/身份认证/…」七个 fieldset） ---------- */
.form-fieldset {
    border: 1px solid var(--c-border);
    border-radius: 10px;
    margin: 0 16px 14px;
    padding: 0 14px;
}
.form-fieldset > legend {
    padding: 0 6px;
    font-size: 13px;
    font-weight: 600;
    color: var(--c-text-mid);
}
.form-fieldset .form-grid { padding: 12px 0 14px; }
.form-fieldset .form-grid + .form-grid { padding-top: 0; }
.modal-body .form-fieldset { margin-left: 0; margin-right: 0; }

/* 一行多控件的横向排布（验证码按钮 / 勾选框组 / 上传按钮） */
.check-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; font-size: 13px; }
.check-row > label { display: inline-flex; align-items: center; gap: 5px; cursor: pointer; }

/* 证件照 / 头像缩略图（点击选择文件） */
.photo-box { display: flex; gap: 14px; align-items: flex-start; flex-wrap: wrap; }
.photo-thumb {
    width: 128px; height: 80px; flex: 0 0 auto;
    display: flex; align-items: center; justify-content: center;
    border: 2px dashed var(--c-border); border-radius: 8px;
    background: var(--c-bg-subtle); cursor: pointer; overflow: hidden;
}
.photo-thumb:hover { border-color: var(--brand); }
.photo-thumb img { width: 100%; height: 100%; object-fit: contain; }

/* 页内群发弹窗的正文排版（复用 .modal / .modal-panel） */
.bc-block { display: flex; flex-direction: column; gap: 6px; margin-bottom: 14px; }
.bc-block > .field-label { font-size: 13px; font-weight: 600; color: var(--c-text-mid); }
.bc-note { font-size: 12px; line-height: 1.8; color: var(--c-warning-dark); background: var(--c-warning-light);
    border: 1px solid #f6e3bf; border-radius: 8px; padding: 8px 10px; }
.bc-fields { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 10px; }

@media print {
    .sidebar, .topbar, .toolbar, .imp-box, .pager, .chips, .st-tabs { display: none !important; }
    .card { border: 0 !important; box-shadow: none !important; }
}

/* ==========================================================================
   UI 对齐补丁（2026 本轮）

   ⚠️ 本段**只新增类名**，不改上面任何既有类的定义：
      .card / .btn / .modal / .table … 都被几十个后台页复用，
      改一处就会波及全站。需要覆盖既有时一律用「新类 + 更具体选择器」。
   ========================================================================== */

/* ---------- 侧栏品牌位：无 logo 时用奖杯（原版 admin.tsx:504-510 的 Trophy 图标） ---------- */
.brand-mark-ico { font-size: 18px; line-height: 1; }

/* ---------- 顶栏下方的「账号受限通知」横幅（原版 admin.tsx:656-664） ---------- */
/* 原版：mx-4 lg:mx-6 mt-4 lg:mt-6 px-4 py-3 bg-amber-50 border-amber-200 rounded-xl */
.acct-banner {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    margin: 16px 16px 0;
    padding: 12px 16px;
    background: var(--c-warning-light);
    border: 1px solid var(--c-warning-border);
    border-radius: var(--r-xl);
    font-size: 13px;
    line-height: 1.7;
}
@media (min-width: 1024px) { .acct-banner { margin: 16px 24px 0; } }
.acct-banner-ico { flex: 0 0 auto; font-size: 15px; line-height: 1.5; }
.acct-banner-body { min-width: 0; }
.acct-banner-title { font-weight: 600; color: var(--c-warning-dark); }
.acct-banner-text { color: var(--c-warning-dark); }

/* ---------- 仪表盘 Hero 的当天日期行（原版 admin.index.tsx:237-239） ---------- */
.hero-date {
    margin: 4px 0 0;                                 /* 原版 mt-1 */
    font-size: 12px;
    color: rgba(255, 255, 255, .6);
    display: flex;
    align-items: center;
    gap: 6px;
}
.hero-date-ico { width: 14px; height: 14px; flex-shrink: 0; }   /* Clock w-3.5 h-3.5 */

/* ---------- 仪表盘「公益与捐赠」横向条形图 ----------
   旧版这张卡是 4 张图里唯一的横向柱状图（recharts layout="vertical"，
   barSize 14 / radius [0,6,6,0]，admin.index.tsx:566-579），不是环形图。 */
.hbar {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 10px;
    min-height: 208px;          /* 原版图表区 h-52 */
    padding: 4px 0;
}
.hbar-row { display: flex; align-items: center; gap: 10px; }
.hbar-name {
    flex: 0 0 92px;
    width: 92px;                /* 原版 YAxis width={80} + 一点余量 */
    font-size: 12px;
    color: #64748b;
    text-align: right;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.hbar-track {
    flex: 1;
    min-width: 0;
    height: 14px;               /* 原版 barSize 14 */
    background: #f6f3f0;
    border-radius: 0 6px 6px 0; /* 原版 radius [0,6,6,0] */
    overflow: hidden;
}
.hbar-fill { display: block; height: 100%; border-radius: 0 6px 6px 0; }
.hbar-val {
    flex: 0 0 auto;
    min-width: 84px;
    font-size: 12px;
    font-weight: 600;
    color: var(--c-text);
    text-align: right;
}

/* 统计条数值的强调色（原版：捐赠笔数用主色、捐赠总额用 rose-500） */
.ss-val-brand { color: var(--brand); }
.ss-val-rose { color: #f43f5e; }

/* ---------- 页内提示条（功能开关关闭 / 记者上传流程） ---------- */
.notice-bar {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    margin-bottom: 14px;
    padding: 12px 16px;
    border: 1px solid transparent;
    border-radius: var(--r-xl);
    font-size: 12px;
    line-height: 1.8;
}
.notice-bar-ico { flex: 0 0 auto; font-size: 14px; line-height: 1.6; }
.notice-bar-body { min-width: 0; }
.notice-bar p { margin: 0; }
/* ⚠️ 用 .notice-bar p.xxx 提高选择器权重：否则被上面的 .notice-bar p{margin:0} 覆盖 */
.notice-bar p.notice-bar-title { margin: 0 0 2px; font-weight: 700; }
.notice-bar p.notice-bar-actions { margin-top: 8px; }
.notice-bar-warn { background: var(--c-warning-light); border-color: var(--c-warning-border); color: var(--c-warning-dark); }
.notice-bar-warn a { color: inherit; text-decoration: underline; }
.notice-bar-info { background: var(--c-info-light); border-color: var(--c-info-border); color: var(--c-info-dark); }
.notice-bar-info a { color: inherit; text-decoration: underline; }
/* 提示条里的完整链接：可能很长，必须能断行 */
.sm-link-text {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 11px;
    word-break: break-all;
    background: rgba(255, 255, 255, .6);
    padding: 1px 4px;
    border-radius: 4px;
}

/* ---------- 现场素材：列表工具条上的「已选」统计 ---------- */
.sm-sel-num { color: var(--brand); }

/* ---------- 现场素材：常驻批量操作卡（未勾选时整体淡化 + 按钮置灰） ---------- */
.sm-batch { transition: background .15s, border-color .15s; }
.sm-batch.is-idle { background: var(--c-bg-subtle); border-color: var(--c-border); }
.sm-batch-num { font-size: 13px; font-weight: 600; color: var(--brand); }
/* 只在批量卡范围内置灰禁用按钮，不动全站的 .btn 定义 */
.sm-batch .btn:disabled { opacity: .45; cursor: not-allowed; }
.sm-batch .btn:disabled:hover { background: var(--c-surface); }
.sm-batch .btn-primary:disabled:hover { background: var(--brand); }
.sm-batch .btn-danger:disabled:hover { background: var(--c-surface); }
.sm-clear-sel { margin-left: auto; }

/* ---------- 现场素材：图墙 / 列表 切换 ---------- */
.sm-view-switch {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    padding: 2px;
    background: var(--c-bg-muted);
    border-radius: 8px;
}
.sm-view-btn {
    padding: 3px 10px;
    font-size: 12px;
    color: var(--c-text-sub);
    border-radius: 6px;
}
.sm-view-btn:hover { color: var(--c-text); text-decoration: none; }
.sm-view-btn.is-on {
    background: var(--c-surface);
    color: var(--brand);
    font-weight: 600;
    box-shadow: var(--shadow-sm);
}
.sm-check-all {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    color: var(--c-text-sub);
    cursor: pointer;
}
.sm-check-all input { width: 15px; height: 15px; accent-color: var(--brand); cursor: pointer; }

/* ---------- 现场素材：图墙（原版 SmFileGrid：2~5 列缩略图网格） ---------- */
.sm-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px;
    padding: 16px;
}
@media (min-width: 640px)  { .sm-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 900px)  { .sm-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (min-width: 1280px) { .sm-grid { grid-template-columns: repeat(5, minmax(0, 1fr)); } }

.sm-tile {
    position: relative;
    background: var(--c-bg-muted);
    border: 2px solid transparent;
    border-radius: var(--r-xl);
    overflow: hidden;
}
.sm-tile-media {
    display: block;
    width: 100%;
    aspect-ratio: 1 / 1;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
}
.sm-tile-media img,
.sm-tile-media video { display: block; width: 100%; height: 100%; object-fit: cover; }
.sm-tile-doc {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    font-size: 32px;
    opacity: .5;
}
/* 勾选框叠在缩略图左上角（原版同位置；这里保持常显，避免只有 hover 才能发现） */
.sm-tile-check { position: absolute; top: 6px; left: 6px; z-index: 2; }
.sm-tile-check input { width: 16px; height: 16px; accent-color: var(--brand); cursor: pointer; }
/* 视频播放标记（原版 36px 半透明黑圆底） */
.sm-tile-play {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 36px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: rgba(0, 0, 0, .45);
    color: var(--c-text-invert);
    font-size: 12px;
    pointer-events: none;
}
.sm-tile-cap {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 16px 8px 6px;
    background: linear-gradient(to top, rgba(0, 0, 0, .7), rgba(0, 0, 0, 0));
}
.sm-tile-name {
    display: block;
    font-size: 10px;
    color: var(--c-text-invert);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.sm-tile-name:hover { color: var(--c-text-invert); text-decoration: underline; }

/* 表格视图里的缩略图/预览按钮 */
.sm-thumb-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: 1px solid var(--c-border);
    border-radius: 6px;
    background: none;
    cursor: pointer;
    overflow: hidden;
    line-height: 1;
}
.sm-thumb-btn img { display: block; width: 72px; height: 52px; object-fit: cover; }
.sm-thumb-btn.is-video {
    width: 72px;
    height: 52px;
    font-size: 12px;
    color: var(--c-text-sub);
    background: var(--c-bg-muted);
}

/* ---------- 空态（图墙 / 表格通用） ---------- */
.sm-empty { padding: 64px 20px; text-align: center; color: var(--c-text-muted); }
.sm-empty-ico { display: block; font-size: 40px; line-height: 1; opacity: .5; margin-bottom: 8px; }
.sm-empty p { margin: 0; font-size: 13px; }
.table .empty .sm-empty-ico { font-size: 32px; margin-bottom: var(--sp-2); }
.table .empty p { margin: 0; }

/* ---------- 现场素材：全屏预览（原版 SmFilePreview，admin.site-materials.tsx:406-432） ----------
   复用布局里的 .modal / [data-dialog-open] 机制，这里只覆盖成全屏深色。
   选择器 .modal-panel.sm-lb-panel 比 .modal-panel 更具体，不会影响通用弹窗。 */
.sm-lightbox .modal-mask { background: var(--c-overlay-heavy); }
.modal-panel.sm-lb-panel {
    width: 100%;
    max-width: none;
    height: 100vh;
    max-height: none;
    margin: 0;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
    animation: none;
}
.modal-panel.sm-lb-panel .modal-head { border-bottom: 0; padding: 12px 16px; }
.sm-lightbox .modal-title {
    display: block;
    color: var(--c-text-invert);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.sm-lb-head { min-width: 0; }
.sm-lb-meta { display: block; font-size: 11px; color: rgba(255, 255, 255, .6); }
.sm-lightbox .modal-close { background: rgba(255, 255, 255, .15); color: var(--c-text-invert); }
.sm-lightbox .modal-close:hover { background: rgba(255, 255, 255, .25); color: var(--c-text-invert); }
.modal-body.sm-lb-body {
    flex: 1;
    min-height: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
}
.sm-lb-img,
.sm-lb-video { max-width: 100%; max-height: 100%; border-radius: 8px; object-fit: contain; }
.sm-lb-state { color: rgba(255, 255, 255, .6); font-size: 13px; }

/* ==========================================================================
   通用资源页 UI 对齐补丁（广告 / 捐赠 / 公益 三个模块 = 33 个模块共用一套模板）

   ⚠️ 本段**只新增类名**（.res-* / .cell-money / .fv-rich），
      不改上面任何既有类的定义；.stat-grid / .fld-chips / .photo-thumb / .fv-thumb
      等既有类直接复用，需要覆盖时用「新类 + 更具体选择器」。
   ========================================================================== */

/* ---------- 模块页副标题（复用 .page-head / .page-title / .page-desc） ----------
   14px 保持不动（第 2 批复核后回退）：页面级页头的 16px 底距由上面
   `.page-head:not(.card *)`（特异性更高）负责；而 .res-page-head 这条只作用在
   **卡片内小标题**上（events/roster.php 的 5 处），改成 16px 会让它们 +2px、
   违反「卡片内 page-head 高度与间距不变」的回归要求。 */
.res-page-head { margin-bottom: 14px; }

/* ---------- 模块页顶部统计条（复用 .stat-grid / .stat-card，只调间距与强调色） ---------- */
.res-stats { margin-bottom: 16px; }
.res-stats .stat-card { padding: 12px 16px; }
.res-stat-brand { color: var(--brand); }

/* ---------- 多选勾选面板（复用 .fld-chips / .fld-chip，补一行推荐尺寸文案） ---------- */
.res-ms-size { font-size: 11px; color: var(--c-text-muted); }
.res-ms-empty { color: var(--c-warning); }

/* ---------- 表单图片控件（复用 .check-row / .photo-box / .photo-thumb） ---------- */
.res-img { display: flex; flex-direction: column; gap: 8px; }
.res-img .photo-thumb { width: 160px; height: 100px; }
.res-img-file { display: none; }
/*
 * 单图字段的行内小缩略图（旧版 ImageInput 是一行 [输入框][选择][×]，没有大预览框）。
 * 34px 的小方块不占高度，赛事表单「主队 / 主队Logo / 客队」三列才能并在一排。
 */
.res-img-mini {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    flex: 0 0 auto;
    overflow: hidden;
    background: var(--c-bg-subtle);
    border: 1px dashed var(--c-border);
    border-radius: 8px;
}
.res-img-mini img { width: 100%; height: 100%; object-fit: contain; display: block; }
.res-img-mini .res-img-none { font-size: 10px; }
.res-img-state { font-size: 12px; color: var(--c-text-muted); }
.res-img-none { font-size: 12px; }

/* ---------- 列表单元格：可复制的 ID / 金额 ---------- */
.res-copy {
    border: 0;
    background: none;
    padding: 0;
    color: var(--c-text-sub);
    cursor: pointer;
    text-align: left;
}
.res-copy:hover { color: var(--brand); text-decoration: underline; }
.cell-money { font-weight: 600; color: var(--c-text); }
/* 金额的收支配色（fields[x]['signBy']=type）：收入绿 / 支出红（旧版财务金额列） */
.cell-money.is-in  { color: var(--c-success-dark); }
.cell-money.is-out { color: var(--c-danger); }
/* 结余为负时的统计卡（moduleStats 的 sumDiff 返回 bad=true） */
.stat-value.is-bad { color: var(--c-danger); }

/* ---------- 详情里的富文本（活动描述 / 文章正文按 HTML 渲染而不是源码） ---------- */
.fv-rich { font-size: 13px; line-height: 1.8; color: var(--c-text-mid); word-break: break-word; }
.fv-rich p { margin: 0 0 8px; }
.fv-rich ul, .fv-rich ol { margin: 0 0 8px; padding-left: 22px; }
.fv-rich ul { list-style: disc; }
.fv-rich ol { list-style: decimal; }
.fv-rich img { max-width: 100%; height: auto; border-radius: 6px; }
.fv-rich table { border-collapse: collapse; max-width: 100%; }
.fv-rich td, .fv-rich th { border: 1px solid var(--c-border); padding: 4px 8px; }
.fv-rich h1, .fv-rich h2, .fv-rich h3, .fv-rich h4 { margin: 10px 0 6px; font-size: 15px; }
.fv-rich blockquote { margin: 0 0 8px; padding-left: 10px; border-left: 3px solid var(--c-border); color: var(--c-text-sub); }

/* ---------- 富文本编辑器（表单里的活动描述 / 正文；contenteditable + 工具栏） ---------- */
.rt-box { display: flex; flex-direction: column; gap: 6px; }
.rt-toolbar { display: flex; flex-wrap: wrap; gap: 6px; }
.rt-btn {
    border: 1px solid var(--c-border);
    background: var(--c-surface);
    border-radius: 6px;
    padding: 2px 8px;
    font-size: 12px;
    color: var(--c-text-mid);
    cursor: pointer;
}
.rt-btn:hover { background: var(--c-bg-subtle); }
.rt-edit {
    min-height: 160px;
    max-height: 340px;
    overflow: auto;
    border: 1px solid var(--c-border);
    border-radius: 8px;
    padding: 10px 12px;
    background: var(--c-surface);
    font-size: 13px;
    line-height: 1.8;
    color: var(--c-text-mid);
    word-break: break-word;
}
.rt-edit:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }
.rt-edit ul { list-style: disc; padding-left: 22px; }
.rt-edit ol { list-style: decimal; padding-left: 22px; }
.rt-edit img { max-width: 100%; height: auto; border-radius: 6px; }
.rt-edit table { border-collapse: collapse; max-width: 100%; }
.rt-edit td, .rt-edit th { border: 1px solid var(--c-border); padding: 4px 8px; }

/* ---------- 富文本编辑器：完整工具栏（public/assets/js/rich-editor.js） ---------- */
.rte-toolbar {
    display: flex; flex-wrap: wrap; align-items: center; gap: 4px;
    padding: 6px 8px; border: 1px solid var(--c-border); border-radius: 8px;
    background: var(--c-bg-subtle);
}
.rte-group { display: inline-flex; align-items: center; gap: 2px; padding-right: 6px; margin-right: 2px; border-right: 1px solid var(--c-border); }
.rte-btn {
    width: 28px; height: 28px; flex: 0 0 auto;
    display: inline-flex; align-items: center; justify-content: center;
    border: 1px solid transparent; border-radius: 6px; background: transparent;
    color: var(--c-text-mid); cursor: pointer; padding: 0; line-height: 1;
}
.rte-btn:hover { background: #eef1f4; color: #111827; }
.rte-btn:active { background: #e2e6ea; }
.rte-btn svg { width: 16px; height: 16px; }
.rte-btn--text { width: auto; padding: 0 7px; font-size: 12px; font-weight: 600; }
.rte-select {
    height: 28px; font-size: 12px; color: var(--c-text-mid); background: var(--c-surface);
    border: 1px solid var(--c-border); border-radius: 6px; padding: 0 4px; cursor: pointer;
}
.rte-right { margin-left: auto; display: inline-flex; align-items: center; gap: 8px; }
.rte-count { font-size: 12px; color: var(--c-text-muted); white-space: nowrap; }
.rte-state { font-size: 12px; color: var(--c-text-muted); white-space: nowrap; }
.rte-state:not(:empty) { color: var(--brand); }
.rte-source {
    width: 100%; min-height: 320px; max-height: 620px; overflow: auto;
    padding: 10px 12px; border: 1px solid var(--c-border); border-radius: 8px;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 13px; line-height: 1.7; color: var(--c-text-mid); background: var(--c-surface);
}
.rte-preview {
    min-height: 240px; padding: 14px 16px; background: var(--c-surface);
    border: 1px dashed var(--c-border); border-radius: 8px; font-size: 13px; line-height: 1.8; color: var(--c-text-mid);
}
.rte-preview img, .rt-edit img { max-width: 100%; height: auto; }
.rte-preview table { border-collapse: collapse; max-width: 100%; }
.rte-preview td, .rte-preview th { border: 1px solid var(--c-border); padding: 4px 8px; }
.rte-preview blockquote { margin: 8px 0; padding-left: 10px; border-left: 3px solid var(--c-border); color: var(--c-text-sub); }
/* 编辑器里的内容区更宽敞（旧站 min-height 400px） */
.rt-box[data-rte-init] .rt-edit { min-height: 320px; max-height: 620px; }
.rt-edit:empty::before { content: attr(data-placeholder); color: var(--c-text-muted); }
/* 全屏编辑 */
.rte-fullscreen {
    position: fixed; inset: 0; z-index: 2000; background: var(--c-surface);
    padding: 14px 16px; display: flex; flex-direction: column; gap: 8px; overflow: hidden;
}
.rte-fullscreen .rt-edit,
.rte-fullscreen .rte-source { flex: 1 1 auto; min-height: 0; max-height: none; }
body.rte-noscroll { overflow: hidden; }
@media (max-width: 720px) {
    .rte-right { width: 100%; margin-left: 0; justify-content: flex-end; }
}

/* ---------- 打印：只留表格（旧版「打印」是新窗口里的干净报表） ---------- */
@media print {
    .bulk-bar, .res-stats, .res-page-head, .acct-banner { display: none !important; }
    .table .th-actions, .table .th-check { display: none !important; }
}

/* ==========================================================================
   媒体库 /admin/media（旧版 src/routes/admin.media.tsx：左侧文件夹面板 + 右侧文件网格）

   ⚠️ 本段**只新增类名**（.media-*），不改上面任何既有类定义；
      网格/预览/勾选框/视图切换直接复用既有 .sm-grid 一族的同类思路，
      其中视图切换按钮复用现成的 .sm-view-switch / .sm-view-btn。
   ========================================================================== */

/* ---------- 整体两栏（左文件夹面板 + 右主区） ---------- */
.media-layout { display: flex; align-items: flex-start; gap: var(--sp-6); }
.media-main { flex: 1; min-width: 0; }

/* ---------- 左侧文件夹面板 ---------- */
.media-panel {
    flex: 0 0 auto;
    width: 224px;
    display: flex;
    flex-direction: column;
    background: var(--c-surface);
    border: 1px solid var(--c-border);
    border-radius: var(--r-xl);
    box-shadow: var(--shadow-sm);
    overflow: hidden;
    transition: width .2s ease;
}
.media-panel.is-collapsed { width: var(--sp-12); }
.media-panel-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-2);
    padding: var(--sp-3);
    border-bottom: 1px solid var(--c-bg-muted);
}
.media-panel.is-collapsed .media-panel-head { justify-content: center; padding: var(--sp-3) 0; border-bottom: 0; }
.media-panel-title {
    font-size: var(--fs-sm);
    font-weight: 700;
    letter-spacing: .06em;
    color: var(--c-text-sub);
}
.media-panel-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    border-radius: 6px;
    color: var(--c-text-sub);
    font-size: 13px;
}
.media-panel-toggle:hover { background: var(--c-bg-muted); color: var(--c-text); text-decoration: none; }

.media-new { padding: 10px 8px 4px; }
.media-new-btn {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 6px 8px;
    border-radius: 8px;
    font-size: 12px;
    color: var(--c-text-sub);
}
.media-new-btn:hover { background: var(--c-bg-subtle); color: var(--brand); text-decoration: none; }
.media-new-folder { display: flex; flex-direction: column; gap: 6px; }
.media-new-folder .input { font-size: var(--fs-sm); padding: 6px 8px; border-radius: var(--r-md); }
.media-new-actions { display: flex; gap: 6px; }

.media-folders { flex: 1; min-height: 40px; max-height: 52vh; overflow-y: auto; padding: 6px 8px; }
.media-folder-row { position: relative; display: flex; align-items: center; }
.media-folder {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 1;
    min-width: 0;
    padding: 6px 8px;
    border-radius: 8px;
    font-size: 13px;
    color: var(--c-text-mid);
}
.media-folder:hover { background: var(--c-bg-subtle); text-decoration: none; }
.media-folder.is-on { background: var(--brand-soft); color: var(--brand); font-weight: 600; }
.media-folder-ico { flex: 0 0 auto; font-size: 13px; }
.media-folder-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.media-folder-count { flex: 0 0 auto; font-size: var(--fs-sm); color: var(--c-text-muted); }
.media-folder.is-on .media-folder-count { color: var(--brand); }

/* 「⋮」菜单：<details> 原生开合，不依赖 JS */
.media-folder-menu { position: relative; flex: 0 0 auto; }
.media-folder-menu > summary {
    list-style: none;
    cursor: pointer;
    padding: 2px 6px;
    border-radius: 6px;
    color: var(--c-text-sub);
    font-size: 13px;
    line-height: 1.4;
}
.media-folder-menu > summary::-webkit-details-marker { display: none; }
.media-folder-menu > summary:hover { background: var(--c-bg-muted); color: var(--c-text); }
.media-menu-pop {
    position: absolute;
    right: 0;
    top: 26px;
    z-index: 20;
    min-width: 132px;
    padding: 4px;
    background: var(--c-surface);
    border: 1px solid var(--c-border);
    border-radius: 10px;
    box-shadow: var(--shadow-lg);
}
.media-menu-item {
    display: block;
    width: 100%;
    padding: 6px 10px;
    border: 0;
    background: none;
    border-radius: 6px;
    text-align: left;
    font-size: 12px;
    color: var(--c-text-mid);
    cursor: pointer;
}
.media-menu-item:hover { background: var(--c-bg-subtle); text-decoration: none; }
.media-menu-item.is-danger { color: var(--c-danger); }
.media-menu-item.is-danger:hover { background: var(--c-danger-light); }

.media-folder-rename { display: flex; align-items: center; gap: 4px; padding: 2px 0; }
.media-rename-input { flex: 1; min-width: 0; font-size: 12px; padding: 5px 6px; }
.media-folders-empty { margin: var(--sp-3) 0; text-align: center; font-size: var(--fs-sm); color: var(--c-text-muted); }

.media-panel-foot { padding: 8px 14px 10px; border-top: 1px solid var(--c-bg-muted); }
.media-foot-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 11px;
    color: var(--c-text-muted);
}
.media-foot-row b { color: var(--c-text-mid); }

/* ---------- 右侧：标题 / 工具条 ---------- */
.media-page-head { margin-bottom: var(--sp-4); }

/* 工具条：**单行 flex**（对齐旧版 admin.media.tsx:395-465 的 `flex flex-wrap items-center gap-3`）。
   旧版这里不是卡片，所以 .media-bar 自带下外边距；
   ⚠️ 旧版分段控件与按钮用 `py-1.5`=6px，本项目吸附到 --sp-2(8px)（差 2px，见像素差异表 C4）。 */
.media-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--sp-3);
    margin-bottom: var(--sp-4);
}
/* 搜索：左侧放大镜图标 + 无提交按钮（回车提交），右侧清除。旧版 pl-9 = 36px */
.media-search { position: relative; flex: 1 1 200px; min-width: 200px; max-width: 320px; }
.media-search .input { padding-left: 36px; padding-right: 32px; }
.media-search-ico {
    position: absolute;
    left: 12px;
    top: 50%;
    transform: translateY(-50%);
    width: 16px;
    height: 16px;
    color: var(--c-text-muted);
    pointer-events: none;
}
.media-search-clear {
    position: absolute;
    right: 8px;
    top: 50%;
    transform: translateY(-50%);
    width: 20px;
    height: 20px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--r-sm);
    font-size: var(--fs-sm);
    color: var(--c-text-sub);
}
.media-search-clear:hover { background: var(--c-bg-muted); color: var(--c-text); text-decoration: none; }

/* 类别 Tab：**灰底分段控件**（对齐旧版 `flex bg-gray-100 rounded-lg p-1`）
   ⚠️ 旧版 Tab 上**不带计数**（计数在下方统计 chip 里），这里去掉 .media-chip-num */
.media-tabs {
    display: inline-flex;
    flex-wrap: wrap;
    padding: var(--sp-1);
    background: var(--c-bg-muted);
    border-radius: var(--r-lg);
}
.media-tab {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: var(--sp-2) var(--sp-3);
    border-radius: var(--r-md);
    font-size: var(--fs-body);
    color: var(--c-text-sub);
}
.media-tab:hover { color: var(--c-text); text-decoration: none; }
.media-tab.is-on {
    background: var(--c-surface);
    color: var(--c-text);
    font-weight: 500;
    box-shadow: var(--shadow-sm);
}
/* 右侧动作组：ml-auto（对齐旧版 `flex items-center gap-2 ml-auto`） */
.media-actions { display: flex; align-items: center; gap: var(--sp-2); margin-left: auto; }
.media-count { font-size: var(--fs-sm); color: var(--c-text-sub); }
/* 「扇描重复」琥珀色按钮（对齐旧版 text-amber-700 bg-amber-50 border-amber-200） */
.btn-dup { background: var(--c-warning-light); border-color: var(--c-warning-border); color: var(--c-warning-dark); }
.btn-dup:hover { background: var(--c-warning-light); border-color: var(--c-warning); color: var(--c-warning-dark); }
.media-chip-num {
    display: inline-block;
    margin-left: 4px;
    padding: 0 5px;
    border-radius: 999px;
    background: var(--c-bg-muted);
    font-size: 11px;
    color: var(--c-text-muted);
}
.chip.is-on .media-chip-num { background: var(--c-surface); color: var(--brand); }
.media-actions { margin-top: 12px; padding: 0; border: 0; background: none; }
.media-sel-num { color: var(--brand); }

/* ---------- 上传：拖拽区 + 进度条 ---------- */
.media-upload { margin-top: 16px; }
.media-drop {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    padding: 26px 16px;
    border: 2px dashed var(--c-border);
    border-radius: var(--r-xl);
    background: var(--c-bg-subtle);
    cursor: pointer;
    text-align: center;
    transition: border-color .15s, background .15s;
}
.media-drop:hover { border-color: var(--brand); }
.media-drop.is-over { border-color: var(--brand); background: var(--brand-soft); }
.media-drop-ico { font-size: 20px; color: var(--c-text-muted); }
.media-drop-title { margin: 0; font-size: 13px; font-weight: 600; color: var(--c-text-mid); }
.media-drop-hint { margin: 0; font-size: 12px; color: var(--c-text-sub); }
.media-progress {
    margin-top: 10px;
    height: 6px;
    border-radius: 999px;
    background: var(--c-bg-muted);
    overflow: hidden;
}
.media-progress[hidden] { display: none; }
.media-progress > span {
    display: block;
    width: 35%;
    height: 100%;
    border-radius: 999px;
    background: var(--brand);
    animation: media-progress-run 1.1s ease-in-out infinite;
}
@keyframes media-progress-run {
    0%   { margin-left: -35%; }
    100% { margin-left: 100%; }
}

/* ---------- 分类统计卡 ---------- */
.media-stats { margin-top: 16px; }
.media-stats .stat-card { padding: 12px 16px; }
.media-stats .stat-value { font-size: 20px; }

/* ---------- 批量操作卡（常驻，未勾选时淡化 + 按钮置灰） ---------- */
.media-form { margin: 0; }
.media-batch { margin-top: 16px; transition: background .15s, border-color .15s; }
.media-batch.is-idle { background: var(--c-bg-subtle); border-color: var(--c-border); }
.media-batch-num { font-size: 13px; font-weight: 600; color: var(--brand); }
.media-batch .btn:disabled { opacity: .45; cursor: not-allowed; }
.media-batch .btn:disabled:hover { background: var(--c-surface); }
.media-batch .btn-primary:disabled:hover { background: var(--brand); }
.media-batch .btn-danger:disabled:hover { background: var(--c-surface); }
.media-clear-sel { margin-left: auto; }

/* ---------- 文件网格（2~6 列，对齐旧版网格视图） ---------- */
.media-files { margin-top: 16px; }
.media-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px;
    padding: 16px;
}
@media (min-width: 640px)  { .media-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 900px)  { .media-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (min-width: 1400px) { .media-grid { grid-template-columns: repeat(6, minmax(0, 1fr)); } }

.media-tile {
    position: relative;
    display: flex;
    flex-direction: column;
    background: var(--c-surface);
    /* 2px 边框是选中态的一部分（选中时框变主色），只把颜色换成 token */
    border: 2px solid var(--c-border);
    border-radius: var(--r-xl);
    overflow: hidden;
}
.media-tile:hover { box-shadow: var(--shadow-sm); }
.media-tile-media {
    display: block;
    width: 100%;
    aspect-ratio: 1 / 1;
    padding: 0;
    border: 0;
    background: var(--c-bg-muted);
    cursor: pointer;
}
.media-tile-media img,
.media-tile-media video { display: block; width: 100%; height: 100%; object-fit: cover; }
.media-tile-doc {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    font-size: 32px;
    opacity: .5;
}
.media-tile-play {
    position: absolute;
    top: 34%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 36px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: rgba(0, 0, 0, .45);
    color: var(--c-text-invert);
    font-size: 12px;
    pointer-events: none;
}
/* 勾选框常显在缩略图左上角（旧版是 hover 才出现，但只有 hover 才能发现，运营反馈不好找） */
.media-tile-check { position: absolute; top: 6px; left: 6px; z-index: 2; }
.media-tile-check input { width: 16px; height: 16px; accent-color: var(--brand); cursor: pointer; }
.media-tile-cap { padding: 8px 10px 4px; }
.media-tile-name {
    display: block;
    font-size: 12px;
    font-weight: 500;
    color: var(--c-text-mid);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.media-tile-meta { display: block; margin-top: var(--sp-1); font-size: var(--fs-sm); color: var(--c-text-muted); }
.media-tile-actions {
    display: flex;
    align-items: flex-start;
    gap: 6px;
    padding: 6px 10px 10px;
    flex-wrap: wrap;
}
.media-mini {
    display: inline-block;
    padding: 2px 8px;
    border: 1px solid var(--c-border);
    border-radius: 6px;
    background: var(--c-surface);
    font-size: 11px;
    line-height: 1.7;
    color: var(--c-text-mid);
    cursor: pointer;
}
.media-mini:hover { background: var(--c-bg-subtle); text-decoration: none; }
.media-mini.is-danger { color: var(--c-danger); border-color: var(--c-danger-border); }
.media-mini.is-danger:hover { background: var(--c-danger-light); }
.media-move-mini { display: inline; margin: 0; }
.media-move-mini > details { display: inline; }
.media-move-mini > details > summary { list-style: none; }
.media-move-mini > details > summary::-webkit-details-marker { display: none; }
/* ⚠️ 展开层刻意用**静态定位**（不是 absolute 浮层）：
   .table-wrap 是 overflow 滚动容器、.media-tile 是 overflow:hidden（圆角裁切），
   absolute 浮层会被裁掉一半。静态块随行 / 卡片一起撑高，两种视图都不会被裁。 */
.media-move-pop {
    display: flex;
    flex-direction: column;
    gap: 8px;
    width: 100%;
    min-width: 200px;
    box-sizing: border-box;
    margin-top: 6px;
    padding: 10px;
    background: var(--c-bg-subtle);
    border: 1px solid var(--c-border);
    border-radius: 10px;
}
.media-move-pop .select { font-size: 12px; padding: 6px 8px; }
.media-move-pop .btn { align-self: flex-start; }
.media-del-mini { display: inline; margin: 0; }
.media-del-mini.is-inline,
.media-move-mini.is-inline { display: inline-block; vertical-align: top; }
.table .th-actions .media-move-mini + .media-del-mini { margin-left: 4px; }

/* ---------- 空态 ---------- */
.media-empty { padding: 60px 20px; text-align: center; color: var(--c-text-muted); }
.media-empty-ico { display: block; font-size: 40px; line-height: 1; opacity: .5; margin-bottom: 8px; }
.media-empty p { margin: 0; font-size: 13px; }
.table .empty .media-empty-ico { font-size: 32px; margin-bottom: var(--sp-2); }
.table .empty p { margin: 0; }

/* ---------- 重复文件面板 ---------- */
.media-dedup-tip { margin: 0 0 12px; }
.media-dedup-list { max-height: 420px; overflow-y: auto; }
.media-dedup-group {
    margin-bottom: 10px;
    padding: 10px 12px;
    border: 1px solid var(--c-border);
    border-radius: 10px;
}
.media-dedup-head { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.media-dedup-name {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 12px;
    color: var(--c-text-sub);
    text-decoration: line-through;
}
.media-dedup-name.is-keep { color: var(--c-success); font-weight: 600; text-decoration: none; }
.media-dedup-mark { flex: 0 0 auto; font-size: 11px; }
.media-dedup-file { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---------- 预览弹窗里的「下载 / 复制链接」 ---------- */
.media-lb-actions { display: inline-flex; align-items: center; gap: 8px; }
.media-lb-btn {
    padding: 4px 10px;
    border: 0;
    border-radius: 8px;
    background: rgba(255, 255, 255, .15);
    color: var(--c-text-invert);
    font-size: 12px;
    cursor: pointer;
}
.media-lb-btn:hover { background: rgba(255, 255, 255, .28); color: var(--c-text-invert); text-decoration: none; }

/* ---------- 窄屏：面板改为上方通栏 ---------- */
@media (max-width: 900px) {
    .media-layout { flex-direction: column; }
    .media-panel,
    .media-panel.is-collapsed { width: 100%; }
    .media-folders { max-height: 240px; }
}

/* ==================================================================
   角色与权限（/admin/settings/roles）与配置页图片字段
   —— 只新增类，不改上面任何复用类（.card / .btn / .form* / .table…）
   ================================================================== */

/* 角色列表里的「已启权限 X / Y」徽标：满权限 / 过半 / 少量 三种配色
   ⚠️ 2026-10-01 第 5 批（角色页）：徽标统一到 DESIGN §6.6（高 22px / 内边距 0 8px / 圆角 --r-sm，
   与 .tag 同口径，不再是 10px 胶囊）。原紫 #efe6fb/#6b34c9 与蓝 #e6efff/#1f5fd0 **不在 token 内**，
   改用 success / info 功能色浅底：满权限=绿 / 过半=蓝 / 少量=中性。 */
.perm-badge {
    display: inline-block;
    height: 22px;
    line-height: 22px;
    padding: 0 var(--sp-2);
    border-radius: var(--r-sm);
    font-size: var(--fs-sm);
    font-weight: 600;
    background: var(--c-bg-subtle);
    color: var(--c-text-mid);
}
.perm-badge.perm-full { background: var(--c-success-light); color: var(--c-success-dark); }
.perm-badge.perm-half { background: var(--c-info-light);    color: var(--c-info-dark); }
.perm-badge.perm-low  { background: var(--c-bg-subtle);     color: var(--c-text-mid); }

/* 当前正在编辑的那一行高亮（原 #f7fbff 不在 token 内 → 品牌色浅底） */
.table tr.row-on { background: var(--c-primary-light); }

/* 权限矩阵标题行 */
.perm-head {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    flex-wrap: wrap;
    margin: 16px 0 8px;
}
.perm-title { margin: 0; font-size: var(--fs-body); font-weight: 700; }

/* 权限分组（details/summary，JS 不可用时也能展开勾选） */
.perm-group {
    border: 1px solid var(--c-border);
    border-radius: var(--r-lg);
    margin-bottom: 8px;
    overflow: hidden;
}
.perm-group > summary {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    padding: 8px 12px;
    background: var(--c-bg-subtle);
    cursor: pointer;
    list-style: none;
}
.perm-group > summary::-webkit-details-marker { display: none; }
.perm-group > summary:hover { background: var(--c-bg-muted); }
/* ⚠️ 13px 是项目里「表单标签」的通用中间字号（见 .field-label），非 --fs-* 三档之一，
   全站统一迁移，本批不动（归「全站底座」批次）。 */
.perm-group-title { font-size: 13px; font-weight: 600; }
.perm-group-desc { font-size: var(--fs-sm); color: var(--c-text-sub); }
.perm-group-count { font-size: var(--fs-sm); color: var(--c-text-muted); }

.perm-items {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 12px;
    padding: 12px;
    border-top: 1px solid var(--c-border);
    background: var(--c-surface);
}
.perm-item {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-1);
    padding: 4px 8px;
    border: 1px solid var(--c-border);
    border-radius: var(--r-md);
    background: var(--c-bg-subtle);
    font-size: var(--fs-sm);
    cursor: pointer;
    user-select: none;
}
.perm-item:hover { border-color: var(--c-primary); background: var(--c-primary-light); }

/* 角色编辑表单：3 个字段（2 个常规 + 1 个整行）在全局 .form-grid 的 auto-fill 栅格里会排成
   4 列 → 第 3/4 列空置，且「适用层级」下拉只剩 275px（25 字选项被截断）。
   本页锁定 2 列，窄屏降级单列。
   ⚠️ 只作用于本页的 .role-form-grid，不改全局 .form-grid。 */
.form-grid.role-form-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 720px) { .form-grid.role-form-grid { grid-template-columns: minmax(0, 1fr); } }

/* ==================================================================
   系统设置 → 通知管理 · 模板消息场景表（/admin/settings?tab=notify）
   ──────────────────────────────────────────────────────────────────
   4 列：启用 / 场景 / 说明 / 模板 ID
   （对齐旧站 admin.settings.tsx 的「启用 | 场景名称 | 说明 | 模板ID」）
   列宽改用类声明 —— 原先写在 th 上的 style="width:70px" 属硬编码；
   最后一列「模板 ID」不设宽 → 自适应吸收剩余空间。
   ⚠️ 仅该表使用，不改任何既有选择器。
   ================================================================== */
.cfg-tpl-col-on    { width: 72px; }
.cfg-tpl-col-scene { width: 200px; }
.cfg-tpl-col-desc  { width: 240px; }

/* 配置页的图片字段（小程序分享图片）：缩略图预览 */
.cfg-img { display: flex; flex-direction: column; gap: 6px; }
.cfg-img .check-row .input { flex: 1 1 240px; }
.cfg-img-thumb {
    width: 120px;
    height: 96px;
    border: 1px solid var(--c-border);
    border-radius: 8px;
    background: var(--c-bg-subtle);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}
.cfg-img-thumb img { max-width: 100%; max-height: 100%; object-fit: contain; }
.cfg-img-thumb .muted { font-size: 12px; }

/* ============================================================================
   物资台账（/admin/materials）：一物一码 / 扫码出入库 / 批量扫码归还 / 报损审批
   ⚠️ 全部为本次新增类（mat- 前缀），不改动任何既有选择器。
   ============================================================================ */
.mat-tabs { margin: 14px 0 0; }

.mat-toolbar {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    margin: 14px 0;
}
.mat-toolbar-ops {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    margin-left: auto;
}
.mat-rel-badge-wrap { position: relative; }
.mat-badge {
    position: absolute;
    top: -9px;
    right: -9px;
    min-width: 20px;
    height: 20px;
    padding: 0 4px;
    border-radius: 10px;
    background: var(--c-danger);
    color: var(--c-text-invert);
    font-size: 11px;
    font-weight: 700;
    line-height: 20px;
    text-align: center;
    box-shadow: 0 0 0 2px var(--c-surface);
}

.mat-card { margin-bottom: 14px; }
.mat-card-head {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}
.mat-card-title {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    min-width: 0;
}
.mat-card-title .card-title { margin: 0; }
.mat-card-ops {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
    margin-left: auto;
}
.mat-meta {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    padding: 0 0 10px;
    font-size: 12px;
    color: var(--c-text-muted);
}
.mat-meta b { color: var(--c-text); }

.mat-th-ops { width: 220px; }
.mat-td-ops {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
}
.mat-op-form { display: inline-block; margin: 0; }

.mat-chain {
    margin-top: 4px;
    font-size: 11px;
    color: var(--c-text-sub);
}
.mat-reject {
    margin-top: 4px;
    font-size: 11px;
    color: var(--c-danger);
}

.mat-links {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

/* ---- 批量生成物品编码弹窗 ---- */
.mat-preview {
    margin: 12px 0;
    padding: 10px 12px;
    border: 1px solid var(--c-border);
    border-radius: var(--r-lg);
    background: var(--c-bg-subtle);
}
.mat-preview p { margin: 0 0 6px; font-size: 12px; }
.mat-preview-codes {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
}
.mat-preview-code {
    padding: 1px 6px;
    border: 1px solid var(--c-border);
    border-radius: 5px;
    background: var(--c-surface);
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 12px;
    color: var(--c-text);
}

/* ---- 扫码弹窗 ---- */
.mat-scan-row {
    display: flex;
    align-items: center;
    gap: 8px;
}
.mat-scan-row .input { flex: 1; }
.mat-scan-big {
    border: 2px solid var(--c-info-border);
    background: #f8fbff;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    padding: 10px 12px;
}
.mat-scan-msg {
    margin: 10px 0 0;
    padding: 8px 10px;
    border-radius: 8px;
    font-size: 12px;
}
.mat-scan-msg.is-ok { background: var(--c-success-light); color: var(--c-success-dark); }
.mat-scan-msg.is-bad { background: var(--c-danger-light); color: var(--c-danger-dark); }
.mat-tip {
    margin: 8px 0 0;
    padding: 8px 10px;
    border-radius: 8px;
    background: var(--c-warning-light);
    color: var(--c-warning-dark);
    font-size: 12px;
}

/* ---- 批量扫码归还面板 ---- */
.mat-notice {
    margin-bottom: 12px;
    padding: 10px 12px;
    border: 1px solid var(--c-warning-border);
    border-radius: var(--r-lg);
    background: var(--c-warning-light);
}
.mat-notice-head {
    font-size: 12px;
    font-weight: 700;
    color: var(--c-warning-dark);
    margin-bottom: 6px;
}
.mat-notice-list {
    max-height: 140px;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.mat-notice-item {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 4px 8px;
    border-radius: 7px;
    background: var(--c-surface);
    font-size: 11px;
    min-width: 0;
}
.mat-notice-who { color: var(--c-warning-dark); font-weight: 700; }
.mat-notice-mat { color: var(--c-text); }
.mat-notice-time { margin-left: auto; }
.mat-return-stat {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin: 10px 0 6px;
    padding: 8px 10px;
    border-radius: 8px;
    background: var(--c-bg-subtle);
    font-size: 12px;
}
.mat-log {
    max-height: 220px;
    min-height: 90px;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 8px;
    border: 1px solid var(--c-border);
    border-radius: 8px;
    background: var(--c-surface);
}
.mat-log-empty { margin: 0; padding: 24px 0; text-align: center; font-size: 12px; }
.mat-log-item {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 4px 8px;
    border-radius: 7px;
    font-size: 12px;
    min-width: 0;
}
.mat-log-item.is-ok { background: var(--c-success-light); color: var(--c-success-dark); }
.mat-log-item.is-bad { background: var(--c-danger-light); color: var(--c-danger-dark); }
.mat-log-ico { flex: 0 0 auto; }
.mat-log-msg { margin-left: auto; text-align: right; }

/* ---- 报损弹窗 ---- */
.mat-target {
    margin-bottom: 10px;
    padding: 8px 10px;
    border-radius: 8px;
    background: var(--c-bg-subtle);
    font-size: 12px;
    color: var(--c-text);
}

/* ---- 二维码弹窗 ---- */
.mat-qr-body { text-align: center; }
.mat-qr-name { margin: 0; font-weight: 700; }
.mat-qr-code {
    margin: 2px 0 10px;
    font-size: 12px;
    color: var(--c-text-sub);
}
.mat-qr-box {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 216px;
    padding: 8px;
    border: 1px solid var(--c-border);
    border-radius: 10px;
    background: var(--c-surface);
    margin-bottom: 10px;
}

/* ---- 摄像头扫码浮层（原生 BarcodeDetector + getUserMedia） ---- */
.mat-cam {
    position: fixed;
    inset: 0;
    z-index: 80;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, .6);
}
.mat-cam-panel {
    width: min(92vw, 420px);
    padding: 16px;
    border-radius: var(--r-xl);
    background: var(--c-surface);
    box-shadow: var(--shadow-lg);
    text-align: center;
}
.mat-cam-title { margin: 0 0 10px; font-size: 14px; font-weight: 700; }
.mat-cam-video {
    width: 100%;
    max-height: 300px;
    border-radius: 10px;
    background: #111;
}
.mat-cam-tip { margin: 10px 0; font-size: 12px; color: var(--c-text-muted); }

/* ---- 物资管理设置：审批配置只读摘要 / 分级块 ---- */
.mat-cfg-sum {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    margin: 4px 0 12px;
}
.mat-cfg-chip {
    padding: 4px 10px;
    border: 1px solid var(--c-border);
    border-radius: 999px;
    background: var(--c-bg-subtle);
    font-size: 12px;
    color: var(--c-text);
}
.mat-cfg-level {
    margin: 12px 0;
    padding: 12px;
    border: 1px solid var(--c-border);
    border-radius: var(--r-lg);
    background: var(--c-bg-subtle);
}
.mat-cfg-level-head {
    margin-bottom: 8px;
    font-size: 13px;
    font-weight: 700;
    color: var(--c-text);
}
.mat-cfg-edit > summary { cursor: pointer; }

/* ==========================================================================
   捐赠专页（查看证书 / 证书模板设计器 / 列表缩略图）

   ⚠️ 本段**只新增 .adc-* 类名**，不改上面任何既有类定义（.card/.btn/.table/.modal 等
      被 30+ 个后台页复用的类一律不动）。
   ⚠️ 这里**不放 @media print 规则**：打印样式只写在 app/views/admin/donation/certificate.php
      内部 —— 否则「body * {visibility:hidden}」会把其它后台页面的打印也变成白纸。
   ========================================================================== */

/* ---------- 证书纸张（partials/cert-paper.php 的 DOM） ---------- */
.adc-paper-frame {
    position: relative;
    overflow: hidden;
    border-radius: 10px;
    background: var(--c-surface);
    box-shadow: 0 10px 24px -8px rgba(0, 0, 0, .25);
}
.adc-paper {
    position: relative;
    box-sizing: border-box;
    transform-origin: top left;
    color: #333;
}
.adc-paper-body { position: relative; z-index: 1; width: 100%; height: 100%; overflow: hidden; }
.adc-paper-body img { max-width: 100%; height: auto; }
.adc-lace { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
.adc-lace-layer[hidden] { display: none; }

/* ---------- 证书页头部 / 舞台 / 二维码 ---------- */
.adc-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; flex-wrap: wrap; }
.adc-title { margin: 0 0 4px; font-size: 16px; font-weight: 600; }
.adc-sub { margin: 0; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 12px; }
.adc-head-right { text-align: right; font-size: 12px; color: var(--c-text-muted); }
.adc-mono { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 12px; }
.adc-stage { display: flex; justify-content: center; padding: 14px 0 6px; }
.adc-print-target { width: 100%; display: flex; flex-direction: column; align-items: center; }
.adc-cert-foot {
    width: 100%;
    max-width: 640px;
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    margin-top: 12px;
    padding: 0 4px;
}
.adc-foot-label { font-size: 11px; color: var(--c-text-muted); }
.adc-qr-wrap { display: flex; align-items: center; gap: 8px; min-height: 84px; }
.adc-qr { width: 84px; height: 84px; display: block; }
.adc-qr-ns { font-size: 11px; }

/* ---------- 内置红金证书卡（对齐前台 site/donation.php 的 #dn-cert-inner） ---------- */
.adc-rg {
    background: linear-gradient(135deg, #7f1d1d, var(--c-danger), var(--c-danger));
    border-radius: 14px;
    padding: 4px;
    width: 100%;
    max-width: 640px;
}
.adc-rg-inner { background: var(--c-surface); border: 2px solid var(--c-warning-border); border-radius: 11px; padding: 22px; text-align: center; }
.adc-rg-no { font-size: 12px; color: var(--c-text-muted); }
.adc-rg-avatar {
    width: 76px; height: 76px; border-radius: 50%; background: var(--c-warning-light);
    display: inline-flex; align-items: center; justify-content: center; font-size: 26px;
}
.adc-rg-detail { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin: 16px 0; }
.adc-rg-detail div { background: var(--c-warning-light); border-radius: 10px; padding: 10px; text-align: center; }
.adc-rg-detail span { display: block; font-size: 12px; color: var(--c-text-muted); margin-bottom: 3px; }
.adc-rg-usage { background: var(--c-info-light); border-radius: 10px; padding: 10px; font-size: 13px; color: var(--c-info-dark); }

/* ---------- 证书模板列表：缩略图 + 名称 ---------- */
.adc-cell { display: flex; align-items: center; gap: 10px; }
.adc-cell-name { min-width: 0; word-break: break-word; }
.adc-thumb { pointer-events: none; flex: 0 0 auto; border-radius: 4px; box-shadow: 0 1px 3px rgba(0, 0, 0, .18); }

/* ---------- 捐赠详情的统计条补充 ---------- */
.adc-unit { font-size: 13px; font-weight: 400; color: var(--c-text-muted); }
.adc-unit-lg { font-size: 17px; }
.adc-ok { color: var(--c-success); }
.adc-warn { color: var(--c-warning); }




/* ---------- 活动 / 公益报名 + 赛事购票专页（本轮新增类，纯追加，未改动任何既有选择器） ----------
   .adc-bad         统计卡的「已取消」数值色（与 .adc-ok/.adc-warn 同族）
   .reg-status-set  报名名单「状态」单元格里的行内下拉 + 保存按钮
   .fk-filter       通用资源列表工具栏的「外键筛选」下拉（公益报名名单的「所属活动」）
   ------------------------------------------------------------------------- */
.adc-bad { color: var(--c-danger); }
.reg-status-set { display: inline-flex; align-items: center; gap: 4px; margin-left: 6px; vertical-align: middle; }
.reg-status-set select {
    padding: 3px 6px;
    font: inherit;
    font-size: 12px;
    color: var(--c-text);
    background: var(--c-surface);
    border: 1px solid var(--c-border);
    border-radius: 6px;
    cursor: pointer;
}
.reg-status-set select:focus { outline: none; border-color: var(--brand); }
.fk-filter { display: inline-flex; align-items: center; gap: 6px; }
.fk-filter select {
    padding: 4px 8px;
    font: inherit;
    font-size: 13px;
    color: var(--c-text);
    background: var(--c-surface);
    border: 1px solid var(--c-border);
    border-radius: 7px;
    cursor: pointer;
}
.fk-filter select:focus { outline: none; border-color: var(--brand); }

/* ==========================================================================
   评论管理（/admin/comments）—— 本段全部是**新增类**，不影响任何既有页面
   （旧版 admin.content.tsx 的「评论管理」Tab 对齐：头像 + 昵称 + 来源 + 状态徽标）
   ========================================================================== */
.cm-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    padding: 12px 14px;
    border-bottom: 1px solid var(--c-border);
}
.cm-toolbar .chips { margin: 0; }
.cm-search { display: inline-flex; align-items: center; gap: 8px; }
.cm-bulk {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    padding: 10px 14px;
    background: var(--c-bg-subtle);
    border-bottom: 1px solid var(--c-border);
}
.cm-bulk-all { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--c-text); }
.cm-bulk-all input { width: 15px; height: 15px; accent-color: var(--brand); cursor: pointer; }
.cm-bulk-op { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--c-text-sub); }
.cm-bulk-op select {
    padding: 4px 8px;
    font: inherit;
    font-size: 13px;
    background: var(--c-surface);
    border: 1px solid var(--c-border);
    border-radius: 7px;
    cursor: pointer;
}
.cm-bulk-op select:focus { outline: none; border-color: var(--brand); }

.cm-who { display: inline-flex; align-items: center; gap: 8px; }
.cm-avatar {
    width: 26px;
    height: 26px;
    border-radius: 50%;
    object-fit: cover;
    border: 1px solid var(--c-border);
    flex: 0 0 auto;
}
.cm-avatar-txt {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--c-danger-light);
    color: var(--brand);
    font-size: 12px;
    font-weight: 700;
}
.cm-content {
    max-width: 420px;
    white-space: pre-wrap;
    word-break: break-word;
    line-height: 1.5;
}
.cm-owner {
    max-width: 220px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--c-text-muted);
    font-size: 12px;
}
.table tr.cm-row-hidden { background: #fbfbfc; }
.table tr.cm-row-hidden .cm-content { color: var(--c-text-muted); }

/* ==========================================================================
   图片数组控件（widget=images，如商品多图 products.images）
   —— 同样是新增类：只有声明了 widget=images 的字段会渲染出 .res-img-list
   ========================================================================== */
.res-img-list { display: flex; flex-direction: column; gap: 10px; }
.res-img-row {
    display: flex;
    gap: 10px;
    align-items: flex-start;
    padding: 10px;
    border: 1px dashed var(--c-border);
    border-radius: 10px;
    background: var(--c-surface);
}
.res-img-idx {
    flex: 0 0 auto;
    width: 18px;
    text-align: right;
    font-size: 12px;
    line-height: 32px;
    color: var(--c-text-muted);
}
.res-img-row .res-img { flex: 1 1 auto; min-width: 0; }
.res-img-row .photo-thumb { width: 120px; height: 80px; }
.res-img-list-foot { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.res-img-tip { font-size: 12px; }

/* 门店店员管理（/admin/m/shop-stores/:id/staffs） */
.stf-head { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.stf-search { display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.stf-hit-store { font-size: 12px; color: var(--c-text-muted); }
.stf-note { max-width: 240px; }

/* 「管理员设置」弹窗（/admin/profile）顶部账号概览 */
.acct-set-head {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 4px 0 14px;
    border-bottom: 1px solid var(--c-border);
    margin-bottom: 12px;
}
.acct-set-avatar { width: 40px; height: 40px; font-size: 16px; }
.acct-set-meta { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.acct-set-name { font-size: 15px; font-weight: 700; color: var(--c-text); }

/* 顶栏「管理员设置」按钮（入口放在用户区，样式复用 .btn-ghost） */
.topbar-set { display: inline-flex; align-items: center; gap: 6px; }
.topbar-set-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: var(--brand);
    color: var(--c-text-invert);
    font-size: 11px;
    font-weight: 700;
    flex: 0 0 auto;
}
@media (max-width: 640px) {
    .topbar-set-text { display: none; }
}

/* ==========================================================================
 * 「逐页收口」批次新增样式（admin.shop / admin.materials / admin.partners）
 * --------------------------------------------------------------------------
 * ⚠️ 本段**只新增类**，不改 .card / .btn / .table / .modal / .chip 等任何复用类，
 *    也不覆盖已有选择器 —— 其它 30+ 个页面拿到的是完全相同的样式表。
 * ========================================================================== */

/* ---- 列表行内快捷操作（改状态 / 上架下架） ---- */
.res-rowact { display: inline-flex; align-items: center; gap: 4px; margin-left: 4px; white-space: nowrap; }
.res-rowact-label { font-size: 11px; color: var(--c-text-muted); }

/* ---- 上下文筛选提示条（商品 → 该商品的订单） ---- */
.res-ctx-tip {
    display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
    margin: 0 0 12px; padding: 8px 12px;
    background: var(--c-warning-light); border: 1px solid var(--c-warning-border); border-radius: 10px;
    font-size: 13px; color: #8a5a00;
}
.res-ctx-tip .res-ctx-ico { flex: 0 0 auto; }
.res-ctx-tip .btn { margin-left: auto; }

/* ---- 表单：多选控件的实时摘要 ---- */
.res-ms-picked { color: var(--c-warning); font-weight: 600; }

/* ---- 表单：支付方案联动提示 ---- */
.res-pay-hint { margin: 10px 0; }
.res-pay-hint-box {
    border-radius: 10px; padding: 8px 12px; font-size: 12px; line-height: 1.7; margin-bottom: 6px;
}
.res-pay-hint-box.is-info { background: #eef6ff; border: 1px solid #cfe4fb; color: var(--c-info-dark); }
.res-pay-hint-box.is-warn { background: var(--c-warning-light); border: 1px solid var(--c-warning-border); color: #8a5a00; }
.res-pay-hint-box.is-bad { background: var(--c-danger-light); border: 1px solid #f6cccc; color: var(--c-danger-dark); }

/* ---- 表单：多规格组合编辑器 ---- */
.res-specs {
    border: 1px solid var(--c-border); border-radius: 12px; padding: 12px; background: var(--c-bg-subtle);
}
.res-specs-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 8px; }
.res-specs-head-matrix { margin-top: 14px; }
.res-specs-title { font-size: 12px; font-weight: 700; color: var(--c-text); }
.res-specs-empty { margin: 0 0 8px; }
.res-specs-dims { display: flex; flex-direction: column; gap: 10px; }
.res-specs-dim { background: var(--c-surface); border: 1px solid var(--c-border); border-radius: 10px; padding: 10px; }
.res-specs-dim-head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.res-specs-dim-head .input { flex: 1 1 auto; min-width: 0; }
.res-specs-opts { display: flex; flex-direction: column; gap: 6px; }
.res-specs-opt { display: flex; align-items: center; gap: 6px; }
.res-specs-opt .input { flex: 1 1 0; min-width: 0; }
.res-specs-matrix {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 6px 12px;
}
.res-specs-combo { display: flex; align-items: center; gap: 8px; background: var(--c-surface); border: 1px solid var(--c-border); border-radius: 8px; padding: 4px 8px; }
.res-specs-combo-name { flex: 1 1 auto; min-width: 0; font-size: 12px; color: var(--c-text-muted); }
.res-specs-combo .input { width: 100px; flex: 0 0 auto; }
.res-specs-raw { margin-top: 12px; }
.res-specs-raw summary { cursor: pointer; font-size: 12px; color: var(--c-text-sub); }
.res-specs-raw textarea { margin-top: 6px; }

/* ---- 物资台账：明细折叠 + 报损详情 ---- */
.mat-card-toggle { font-size: 12px; }
.mat-detail-list { margin: 0; padding: 0; list-style: none; }
.mat-detail-list li { padding: 4px 0; border-bottom: 1px dashed var(--c-border); font-size: 12px; }
.mat-detail-list li:last-child { border-bottom: 0; }

/* ---- 合作伙伴表单弹窗（旧版 720px） ---- */
.partner-form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (max-width: 640px) { .partner-form-grid { grid-template-columns: 1fr; } }
.partner-logo-pick { display: flex; align-items: center; gap: 8px; }
.partner-logo-box { width: 40px; height: 40px; border-radius: 8px; overflow: hidden; background: #f2efee; display: flex; align-items: center; justify-content: center; flex: 0 0 auto; }
.partner-logo-box img { width: 100%; height: 100%; object-fit: cover; display: block; }
.partner-logo-box span { font-size: 11px; color: var(--c-text-muted); }
.partner-type-cards { display: flex; gap: 8px; flex-wrap: wrap; }
.partner-type-card { display: inline-flex; align-items: center; gap: 6px; border: 1px solid var(--c-border); border-radius: 10px; padding: 6px 12px; cursor: pointer; font-size: 13px; background: var(--c-surface); }
.partner-type-card input { accent-color: var(--brand); }
.partner-type-card.is-on { border-color: var(--brand); color: var(--brand); font-weight: 600; }

/* ==========================================================================
   赛事票务模块（赛事列表 / 购票订单）本轮新增的类
   ⚠️ 纯追加：不改上面任何既有类（.card/.btn/.table/.modal/.col-panel…）的定义；
      未声明相关配置的模块不会输出这些 class，页面与改造前逐字节一致。
   ========================================================================== */

/* ---------- 表格 / 卡片视图切换 ---------- */
.res-viewswitch { display: inline-flex; gap: 4px; }
.res-viewswitch .btn.is-on {
    background: var(--brand-soft); color: var(--brand);
    border-color: rgba(200, 22, 35, .35); font-weight: 600;
}

/* ---------- 同组模块 Tab 条（旧版：标题之后、无卡片、无图标） ---------- */
.res-tabs-row { display: flex; align-items: flex-end; gap: 12px; flex-wrap: wrap; margin-bottom: 20px; }
.res-tabs-row .res-tabs { flex: 1 1 auto; margin-bottom: 0; }
.res-tabs-extra { display: flex; gap: 8px; align-items: center; padding-bottom: 8px; }

/* ---------- 「表格 / 卡片」独立一行（旧版 admin.events.tsx:610-617） ---------- */
.res-viewrow {
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px; flex-wrap: wrap; margin-bottom: 12px;
}
.res-seg { display: inline-flex; background: var(--c-bg-muted); border-radius: 8px; padding: 2px; }
.res-seg-btn {
    display: inline-flex; align-items: center; gap: 4px;
    padding: 6px 12px; font-size: 12px; line-height: 1.4;
    border: 0; background: none; cursor: pointer; color: var(--c-text-sub); border-radius: 6px;
}
.res-seg-btn:hover { color: var(--c-text-mid); }
.res-seg-btn.is-on { background: var(--c-surface); color: var(--c-text); font-weight: 500; box-shadow: 0 1px 2px rgba(16, 24, 40, .08); }
.res-viewcount { font-size: 12px; color: var(--c-text-muted); }

/* 卡片模式下隐藏只对表格有意义的工具栏元素（列设置） */
.is-cardmode .tt-colset { display: none; }

/* ---------- 独立成行的下拉筛选（旧版购票订单 admin.events.tsx:708-734） ---------- */
.res-filters-row {
    display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
    margin-bottom: 12px;
}
.res-filters-chev { display: inline-flex; color: var(--c-text-muted); }
.res-filters-chev .ico { width: 16px; height: 16px; }
.res-filters-row .fk-filter select,
.res-filters-row .fk-filter .input { height: 34px; border: 1px solid var(--c-border); border-radius: 8px; background: var(--c-surface); }
.res-filters-row .fk-filter select { padding: 0 10px; font-size: 14px; }
.res-filters-count { font-size: 12px; color: var(--c-text-muted); margin-left: 4px; }

/* ---------- 最右侧「链接」列（旧版 DataTable 的 linkOf 列） ---------- */
.table th.th-link, .table td.th-link { width: 90px; text-align: center; }

/* ---------- 卡片列表（旧版 admin.events.tsx:640-691） ---------- */
.res-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 16px; padding: 14px; }
.res-card {
    border: 1px solid var(--c-border); border-radius: 12px; overflow: hidden;
    background: var(--c-surface); display: flex; flex-direction: column;
    box-shadow: var(--shadow-sm);
    transition: box-shadow .15s, border-color .15s;
}
.res-card:hover { box-shadow: var(--shadow-md); border-color: var(--c-border-strong); }
/* 封面：旧版 `relative h-40 bg-gray-100→gray-200 居中`，主图 object-cover */
.res-card-cover {
    position: relative; height: 160px; flex-shrink: 0;
    background: linear-gradient(135deg, var(--c-bg-muted) 0%, var(--c-border) 100%);
    display: flex; align-items: center; justify-content: center; overflow: hidden;
}
.res-card-img { width: 100%; height: 100%; object-fit: cover; display: block; }
.res-card-nocover { display: flex; flex-direction: column; align-items: center; gap: 2px; color: var(--c-text-muted); }
.res-card-nocover i { font-size: 30px; line-height: 1.1; font-style: normal; }
.res-card-nocover b { font-size: 12px; font-weight: 400; }
.res-card-badge { position: absolute; top: 8px; right: 8px; }
.res-card-body { padding: 12px; display: flex; flex-direction: column; gap: 8px; }
.res-card-name { margin: 0; font-size: 14px; font-weight: 600; color: var(--c-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 主队 / 比分 / 客队：旧版 `flex items-center justify-between text-xs` */
.res-card-scoreline { display: flex; align-items: center; justify-content: space-between; gap: 6px; font-size: 12px; }
.res-card-teamname { font-weight: 500; color: var(--c-text-mid); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.res-card-scoremid { display: flex; align-items: center; gap: 6px; }
.res-card-score { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 18px; color: var(--c-text-muted); white-space: nowrap; }
.res-card-scorebtn {
    display: inline-flex; align-items: center; justify-content: center;
    padding: 4px; border-radius: 6px; color: var(--c-warning-dark); background: none; border: 0; cursor: pointer; text-decoration: none;
}
.res-card-scorebtn:hover { background: var(--c-warning-light); color: var(--c-warning-dark); text-decoration: none; }
.res-card-scorebtn .ico { width: 12px; height: 12px; }
.res-card-line { font-size: 12px; color: var(--c-text-sub); }
.res-card-line.is-venue { display: flex; align-items: center; gap: 4px; color: var(--c-text-muted); }
.res-card-line.is-venue .ico { width: 12px; height: 12px; flex-shrink: 0; }
.res-card-line.is-venue span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 卡片附加行（config 的 cardView.people / .perm，纯加法；未声明的模块不输出这两行） */
.res-card-line.is-people { display: flex; align-items: center; gap: 4px; color: var(--c-text-muted); }
.res-card-line.is-people .ico { width: 12px; height: 12px; flex-shrink: 0; }
.res-card-line.is-perm { margin-top: 4px; }
.tag-perm { background: var(--c-info-light); color: var(--c-info-dark); border: 1px solid var(--c-info-border); }
.res-card-prices { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--c-text-sub); }
.res-card-price { color: var(--c-warning-dark); font-weight: 500; }
/* 操作行：旧版 `flex items-center gap-2 pt-1 border-t border-gray-100`，四个按钮平分 */
.res-card-acts { display: flex; align-items: stretch; gap: 8px; padding-top: 4px; border-top: 1px solid var(--c-bg-muted); }
.res-card-act {
    flex: 1 1 0; min-width: 0;
    display: inline-flex; align-items: center; justify-content: center; gap: 4px;
    padding: 6px 4px; border: 0; border-radius: 6px; background: none; cursor: pointer;
    font-size: 12px; color: var(--c-text-mid); text-decoration: none; white-space: nowrap;
}
.res-card-act .ico { width: 12px; height: 12px; flex-shrink: 0; }
.res-card-act:hover { background: var(--c-bg-muted); color: var(--c-text); text-decoration: none; }
.res-card-act.is-green { color: var(--c-success-dark); }
.res-card-act.is-green:hover { background: var(--c-success-light); color: var(--c-success-dark); }
.res-card-act.is-red { color: var(--c-danger); }
.res-card-act.is-red:hover { background: var(--c-danger-light); color: var(--c-danger-dark); }
.res-card-delf { flex: 1 1 0; display: inline-flex; margin: 0; }
.res-card-delf .res-card-act { width: 100%; }
.res-card-empty { grid-column: 1 / -1; text-align: center; padding: 64px 0; color: var(--c-text-muted); font-size: 14px; }

/* ---------- 地图跳转链接（列表 / 详情 / 卡片共用） ----------
   旧版是「蓝色下划线小字」（admin.events.tsx:475-483 / :497-506），
   容器是 `flex flex-wrap gap-1 mt-1`；卡片上独占一行，表格单元格里跟在场馆名右侧。 */
.res-geo-wrap { display: inline-flex; flex-wrap: wrap; gap: 4px; margin-left: 8px; vertical-align: middle; }
.res-card .res-geo-wrap { display: flex; margin-left: 0; margin-top: 2px; }
.res-geo { font-size: 12px; color: var(--c-info); text-decoration: underline; white-space: nowrap; }
.res-geo:hover { color: var(--c-info-dark); text-decoration: underline; }
/* 表格「场馆」列里的导航入口：旧版只放一个 Navigation 图标链接 */
.table td .res-geo-wrap { margin-left: 6px; }

/* ---------- 场馆定位面板（表单） ---------- */
.fld-geo { margin-top: 6px; display: flex; flex-direction: column; gap: 4px; }
.fld-geo-links { display: flex; flex-wrap: wrap; gap: 6px; }

/* ---------- 开关字段（widget=checkbox） ---------- */
.fld-switch { display: inline-flex; align-items: center; flex-wrap: wrap; gap: 8px; cursor: pointer; user-select: none; }
.fld-switch input[type="checkbox"] { position: absolute; opacity: 0; width: 0; height: 0; }
.fld-switch-track {
    width: 38px; height: 22px; border-radius: 999px; background: #d7d3cf; position: relative;
    transition: background .15s ease; flex-shrink: 0;
}
.fld-switch-track::after {
    content: ''; position: absolute; top: 2px; left: 2px; width: 18px; height: 18px;
    border-radius: 50%; background: var(--c-surface); box-shadow: 0 1px 3px rgba(0, 0, 0, .2); transition: left .15s ease;
}
.fld-switch input[type="checkbox"]:checked + .fld-switch-track { background: var(--brand); }
.fld-switch input[type="checkbox"]:checked + .fld-switch-track::after { left: 18px; }
.fld-switch-txt { font-size: 12px; color: var(--c-text-sub); white-space: nowrap; }
/* 开关说明跟在「已开启/已关闭」同一行。
   第 2 批：nowrap 改为 normal —— 原来长提示会越出弹窗右侧约 77px，
   被 .modal-panel{overflow:hidden} 裁掉尾巴（活动弹窗「报名与人数 → 开放报名」可见），
   「；其余状态 → 关闭。」完全看不到。信息完整性优先，允许折成 2 行。 */
.fld-switch-hint { font-size: 12px; color: var(--c-text-sub); white-space: normal; }

/* ---------- 结构化行编辑器（widget=jsonRows） ---------- */
.res-jsonrows { display: flex; flex-direction: column; gap: 8px; }
.res-jr-rows { display: flex; flex-direction: column; gap: 8px; }
.res-jr-row {
    display: flex; align-items: flex-end; flex-wrap: wrap; gap: 8px;
    padding: 8px; border: 1px solid var(--c-border); border-radius: 10px; background: var(--c-bg-subtle);
}
.res-jr-idx { font-size: 11px; color: var(--c-text-muted); min-width: 14px; padding-bottom: 6px; }
.res-jr-f { display: flex; flex-direction: column; gap: 2px; }
.res-jr-f > span { font-size: 11px; color: var(--c-text-muted); }
.res-jr-f .input { min-width: 96px; }
.res-jr-f--checkbox { flex-direction: row; align-items: center; gap: 4px; padding-bottom: 6px; }
.res-jr-f--checkbox input { width: 15px; height: 15px; accent-color: var(--brand); }
.res-jr-del { margin-left: auto; }
.res-jr-empty { font-size: 12px; color: var(--c-text-muted); margin: 0; }
.res-jr-raw { margin-top: 4px; }
.res-jr-raw summary { cursor: pointer; font-size: 12px; color: var(--c-text-sub); }
.res-jr-raw textarea { margin-top: 6px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }

/* 票档行版式（rowLayout=tier）：首字段一行 + 其余三列一行（对齐旧版球票分类） */
.res-jr-row--tier {
    flex-direction: column; align-items: stretch; gap: 8px;
    padding: 10px; background: var(--c-surface); border-radius: 10px;
}
.res-jr-row--tier .res-jr-head { display: flex; align-items: center; gap: 8px; }
.res-jr-row--tier .res-jr-head .res-jr-idx { padding-bottom: 0; }
.res-jr-row--tier .res-jr-head .res-jr-del { margin-left: auto; }
.res-jr-row--tier .res-jr-body { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.res-jr-row--tier .res-jr-f .input { width: 100%; min-width: 0; }
.res-jr-row--tier .res-jr-head .res-jr-f { flex: 1; }

/* ---------- 远征「交通方式」行编辑器（widget=transport，旧版固定 5 行版式） ---------- */
.res-tp { padding: 12px; background: var(--c-surface); border: 1px solid var(--c-warning-border); border-radius: 10px; }
.res-tp-list { display: flex; flex-direction: column; gap: 8px; }
.res-tp-row {
    display: flex; align-items: flex-start; gap: 8px; padding: 8px 10px;
    border: 1px solid var(--c-border); border-radius: 8px; background: var(--c-surface);
}
.res-tp-row.is-on { background: #fffbf5; border-color: var(--c-warning-border); }
.res-tp-head {
    display: inline-flex; align-items: center; gap: 5px; min-width: 54px;
    padding-top: 6px; cursor: pointer; flex-shrink: 0; user-select: none;
}
.res-tp-head span { font-size: 12px; font-weight: 500; white-space: nowrap; }
.res-tp-head input { width: 15px; height: 15px; accent-color: var(--c-warning); }
.res-tp-body { flex: 1; min-width: 0; display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px; }
.res-tp-grp { display: inline-flex; align-items: flex-end; gap: 10px; flex-wrap: wrap; }
.res-tp-grp--bus { flex-wrap: wrap; align-items: center; }
.res-tp-f { display: inline-flex; align-items: center; gap: 6px; }
.res-tp-f em { font-style: normal; font-size: var(--fs-sm); color: var(--c-text-muted); white-space: nowrap; }
.res-tp-f em.is-go { color: var(--c-info-dark); }
.res-tp-f em.is-back { color: #6366f1; }
.res-tp-f em.is-rt { color: var(--c-danger); }
.res-tp-f .input { width: 74px; }
.res-tp-f--qty .input { width: 64px; }
.res-tp-f .input[type="text"] { width: 110px; }
.res-tp-chk { display: inline-flex; align-items: center; gap: 4px; cursor: pointer; user-select: none; }
.res-tp-chk em { font-style: normal; font-size: 11px; color: var(--c-info-dark); font-weight: 500; white-space: nowrap; }
.res-tp-chk input { width: 15px; height: 15px; accent-color: var(--c-info); }
.res-tp-buscfg { display: inline-flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.res-tp-seats { font-size: 10px; color: var(--c-text-muted); white-space: nowrap; }

/* ---------- 工具栏日期区间筛选 ---------- */
.input-date { width: 140px; }

/* ---------- 导入预览 ---------- */
.imp-preview { margin-top: 10px; border-top: 1px dashed var(--c-border); padding-top: 10px; }
.imp-preview-t { margin: 0 0 8px; font-size: 12px; color: var(--c-text-sub); }
.imp-preview-wrap { max-height: 260px; overflow: auto; border: 1px solid var(--c-border); border-radius: 8px; }
.imp-preview-wrap table.table { margin: 0; font-size: 12px; }
.imp-preview-acts { display: flex; gap: 8px; margin-top: 10px; }
.partner-thumb { width: 40px; height: 40px; border-radius: 8px; object-fit: cover; display: block; }
.partner-thumb-none { width: 40px; height: 40px; border-radius: 8px; background: #f2efee; display: flex; align-items: center; justify-content: center; font-size: 11px; color: var(--c-text-muted); }
.partner-stat-pick { display: flex; align-items: center; gap: 6px; }

/* ==========================================================================
   后台外壳：lucide 图标（App\Services\AdminIcons）+ 顶栏搜索/通知 + 模块搜索弹窗
   对齐参照 src/routes/admin.tsx:500-763
   ========================================================================== */

/* 图标默认 16px；个别位置再放大（尺寸都按参照的 Tailwind 类换算） */
.ico { width: 16px; height: 16px; flex-shrink: 0; }
.brand-mark-ico { width: 20px; height: 20px; color: var(--c-text-invert); }        /* Trophy w-5 h-5 text-white */
.nav-ico .ico { width: 20px; height: 20px; }                       /* 菜单图标 w-5 h-5 */
.side-collapse .ico { width: 16px; height: 16px; }                 /* Chevron w-4 h-4 */
.side-logout-ico { width: 14px; height: 14px; flex-shrink: 0; }    /* LogOut w-3.5 h-3.5 */
.who { cursor: pointer; color: inherit; }
.who:hover { background: var(--c-bg-subtle); text-decoration: none; }
.who-settings { width: 16px; height: 16px; flex-shrink: 0; color: var(--c-text-muted); }   /* Settings w-4 h-4 */

/* 顶栏「搜索模块」按钮（原版 hidden sm:inline-flex） */
.topbar-search {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 6px 12px;
    font-family: inherit;
    font-size: 14px;
    color: var(--c-text-muted);
    background: var(--c-bg-subtle);
    border: 1px solid var(--c-border);
    border-radius: 8px;
    cursor: pointer;
    transition: background .15s, color .15s;
}
.topbar-search:hover { background: var(--c-bg-muted); color: var(--c-text-mid); }
.topbar-search .ico { width: 14px; height: 14px; }                 /* Search w-3.5 h-3.5 */
.topbar-search-text { color: var(--c-border-strong); }                            /* text-gray-300 */
.topbar-search kbd {
    margin-left: 8px;
    padding: 2px 6px;
    font-size: 10px;
    font-family: inherit;
    color: var(--c-text-muted);
    background: var(--c-surface);
    border: 1px solid var(--c-border);
    border-radius: 4px;
}
@media (max-width: 640px) { .topbar-search { display: none; } }

/* 顶栏通知铃铛（原版这个按钮没有 onClick，纯视觉） */
.topbar-bell {
    position: relative;
    display: inline-flex;
    padding: 8px;
    border: 0;
    border-radius: 8px;
    background: none;
    color: var(--c-text-muted);
    cursor: pointer;
    transition: background .15s, color .15s;
}
.topbar-bell:hover { background: var(--c-bg-subtle); color: var(--c-text-mid); }
.topbar-bell .ico { width: 20px; height: 20px; }                   /* Bell w-5 h-5 */
.topbar-bell-dot {
    position: absolute;
    top: 6px;
    right: 6px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--c-danger);
}

/* ---------- 模块搜索弹窗（原版 fixed inset-0 bg-black/40 + 居中白卡） ---------- */
.mod-search { position: fixed; inset: 0; z-index: 100; background: var(--c-overlay); }
.mod-search[hidden] { display: none; }
.mod-search-mask { position: absolute; inset: 0; }
.mod-search-panel {
    position: relative;
    width: 100%;
    max-width: 448px;                                              /* max-w-md */
    margin: 20vh auto 0;
    background: var(--c-surface);
    border-radius: 12px;
    box-shadow: var(--shadow-lg);
    overflow: hidden;
}
.mod-search-head {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 16px;
    border-bottom: 1px solid var(--c-border);
}
.mod-search-head .ico { width: 20px; height: 20px; color: var(--c-text-muted); flex-shrink: 0; }
.mod-search-head input {
    flex: 1;
    min-width: 0;
    border: 0;
    outline: none;
    background: transparent;
    font-family: inherit;
    font-size: 14px;
    color: var(--c-text);
}
.mod-search-x {
    border: 0;
    background: none;
    padding: 0 2px;
    font-size: 18px;
    line-height: 1;
    color: var(--c-text-muted);
    cursor: pointer;
}
.mod-search-x:hover { color: var(--c-text-mid); }
.mod-search-list { max-height: 240px; overflow-y: auto; padding: 8px 0; }
.mod-search-item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 16px;
    font-size: 14px;
    color: var(--c-text-mid);
}
.mod-search-item:hover { background: var(--c-bg-subtle); text-decoration: none; }
.mod-search-item[hidden] { display: none; }
.mod-search-ico { width: 20px; height: 20px; flex-shrink: 0; color: var(--c-text-muted); }
.mod-search-ico .ico { width: 20px; height: 20px; }
.mod-search-empty { margin: 0; padding: 24px 16px; text-align: center; font-size: 14px; color: var(--c-text-muted); }
.mod-search-empty[hidden] { display: none; }
.mod-search-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 8px 16px;
    border-top: 1px solid var(--c-border);
    background: var(--c-bg-subtle);
    font-size: 10px;
    color: var(--c-text-muted);
}
@media (max-width: 640px) { .mod-search-panel { margin-top: 12vh; } }

/* 仪表盘零散对齐项 */
.dc-yellow { background: linear-gradient(to bottom right, var(--c-warning), var(--c-warning)); }  /* from-yellow-500 to-yellow-600 */
.cc-red500 { background: var(--c-danger-light); color: var(--c-danger); }                             /* bg-red-50 text-red-500 */
.cc-link { display: inline-flex; align-items: center; gap: 2px; }               /* 原版 flex items-center gap-0.5 */
.cc-link-ico { width: 14px; height: 14px; }                                     /* ChevronRight w-3.5 h-3.5 */

/* 页内入口（st-subtab 药丸）里带图标时改成 flex 对齐 —— 图标已是 <svg> 而不是文字 */
.st-subtab { display: inline-flex; align-items: center; gap: 6px; }
.st-subtab .ico { width: 14px; height: 14px; }

/* ---------- 会员等级「限时折扣」控件（参照 admin.members.tsx:2081-2098） ---------- */
.lv-disc-toggle { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; flex-shrink: 0; }
.lv-disc-toggle input { width: 14px; height: 14px; accent-color: var(--c-warning-dark); }
.lv-disc-fields { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.lv-disc-percent { width: 58px; padding: 4px 6px; font-size: 12px; }
.lv-disc-date { width: 134px; padding: 4px 6px; font-size: 12px; }
.lv-disc-unit { font-size: 12px; color: var(--c-text-muted); }
.lv-disc-tilde { font-size: 12px; color: var(--c-border-strong); }
/* 未勾选「启用限时折扣」时收起右侧输入框（参照：勾上才展开）。
   :has() 不支持时保持可见 —— 只是多显示几个空输入框，不影响提交。 */
.lv-disc-bar:has(.lv-disc-toggle input:not(:checked)) .lv-disc-fields { display: none; }

/* ==========================================================================
   会员管理模块本轮新增样式（纯追加，覆盖上面同名类时以本段为准）
   ========================================================================== */

/* ---------- 会员只读详情（弹窗/整页共用） ---------- */
.md-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 0 0 12px; }
.md-name { font-size: 17px; font-weight: 700; color: var(--c-text); }
.md-code { background: var(--c-bg-subtle); padding: 1px 6px; border-radius: 5px; font-size: 12px; }

/* ---------- 导入预检的补充说明（如积分导入的「合计 +N 分 / 未匹配行」） ---------- */
.imp-preview-note {
    margin: 0 0 8px;
    padding: 6px 10px;
    background: var(--c-warning-light);
    border: 1px solid var(--c-warning-border);
    border-radius: 8px;
    font-size: 12px;
    color: var(--c-warning-dark);
}

/* =========================================================================
   全站统一的「导入数据」弹窗（标准版式）
   ─────────────────────────────────────────────────────────────────────────
   参照旧版通用表格组件点击「导入」后弹出的对话框
   （DataTable.tsx:556-660）：
     · 标题「导入数据」+ 右上角关闭
     · 「⬇ 下载 XX 模板」整行描边按钮
     · 虚线拖拽区：上传图标 + 「点击或拖拽Excel文件到此处」+ 红色「选择文件」胶囊
     · 底部「取消」+「确认导入」（未选文件时禁用）
   这些类只服务导入弹窗，不参与其它版式，改动风险面 = 0。
   ========================================================================= */
/* 宽度改用 DESIGN 分级：调用方在 `.modal` 上写 `.modal--m`（600px）。
   原来的 .tt-imp-modal .modal-panel { max-width: 672px; } 已删除（第 4 步 B1）。 */
.tt-imp-modal { z-index: 70; }

/* 「下载 XX 模板」：整行描边按钮（原版 w-full border rounded-lg py-2.5 text-sm） */
.imp-tpl {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    padding: 10px 14px;
    margin: 0 0 14px;
    background: var(--c-surface);
    border: 1px solid var(--c-border);
    border-radius: 8px;
    font-size: 13px;
    color: var(--c-text);
    text-decoration: none;
}
.imp-tpl:hover { background: var(--c-bg-subtle); text-decoration: none; }
.imp-tpl .tt-ico { width: 16px; height: 16px; color: var(--c-text-muted); }
.imp-tpl.is-hidden { display: none; }

/* 虚线拖拽区：贴着原版的 `border-2 border-dashed rounded-xl py-8 text-center` */
.imp-drop {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    padding: 30px 16px;
    border: 2px dashed var(--c-border);
    border-radius: 12px;
    background: var(--c-bg-subtle);
    text-align: center;
    cursor: pointer;
    transition: background .15s, border-color .15s;
}
.imp-drop:hover { border-color: #d9cfc9; background: #faf8f6; }
.imp-drop.is-drag { border-color: var(--brand); background: var(--brand-soft); }
.imp-drop-ico { display: inline-flex; }
.imp-drop-ico svg { width: 26px; height: 26px; color: #b6aaa6; }
.imp-drop.is-drag .imp-drop-ico svg { color: var(--brand); }
.imp-drop-text { margin: 0; font-size: 13px; color: var(--c-text-sub); }

/* 「选择文件」红色胶囊（原版 text-xs bg-primary text-white rounded-full px-3 py-1） */
.imp-pick {
    display: inline-block;
    margin-top: 2px;
    padding: 3px 12px;
    border-radius: 999px;
    background: var(--brand);
    color: var(--c-text-invert);
    font-size: 12px;
    line-height: 18px;
}
.imp-drop:hover .imp-pick { background: var(--brand-dark); }

/* 「已选择：xxx.xlsx（12 KB）」 */
.imp-picked {
    margin: 10px 0 0;
    padding: 6px 10px;
    background: var(--c-bg-subtle);
    border-radius: 8px;
    font-size: 12px;
    color: var(--c-text-mid);
    word-break: break-all;
}

/* 弹窗里的粘贴文本域折叠区（保留粘贴通道，收起时只占一行） */
.imp-paste { margin-top: 12px; }
.imp-paste > summary {
    font-size: 12px;
    color: var(--c-text-sub);
    cursor: pointer;
    list-style: none;
}
.imp-paste > summary::-webkit-details-marker { display: none; }
.imp-paste > summary::before { content: '▸ '; }
.imp-paste[open] > summary::before { content: '▾ '; }
.imp-paste textarea { margin-top: 8px; }

/* 底部按钮：未选文件时「确认导入」置灰（原版 disabled:opacity-40） */
.modal-foot .btn[disabled] { opacity: .45; cursor: not-allowed; }
/* 投放区里的原生文件框一律不显示（由「选择文件」胶囊 / 拖拽代劳） */
.imp-drop input[type="file"] { display: none; }
/* 拖拽进来的文件是按 name="file" 关联到外部表单的，弹窗里不需要再显示原生文件框 */
.tt-imp-modal .imp-file-input { display: none; }

/* =========================================================================
   工作组成员展开区（参照 admin.members.tsx:1486-1878）
   ========================================================================= */
.wg-list { display: flex; flex-direction: column; gap: 16px; }/* 工作组卡片：参照 `bg-white rounded-lg border overflow-hidden` */
.wg-card { background: var(--c-surface); border: 1px solid var(--c-border); border-radius: 8px; overflow: hidden; }
/* 卡片头：参照 `flex items-center gap-3 px-4 py-3 bg-gray-50/50 border-b` */
.wg-head { display: flex; align-items: center; gap: 12px; padding: 12px 16px; background: var(--c-bg-subtle); border-bottom: 1px solid var(--c-border); }
.wg-caret {
    display: inline-flex; align-items: center; justify-content: center;
    width: 20px; height: 20px; flex-shrink: 0;
    color: var(--c-text-muted); text-decoration: none; background: none; border: 0; cursor: pointer;
}
.wg-caret .ico { width: 20px; height: 20px; }
.wg-caret:hover { color: var(--c-text-mid); text-decoration: none; }
.wg-headmain { flex: 1; min-width: 0; }
.wg-nameline { display: flex; align-items: center; gap: 8px; }
.wg-name { font-weight: 600; color: var(--c-text); }
.wg-count {
    display: inline-block; padding: 2px 8px; border-radius: 999px;
    background: var(--c-info-light); color: var(--c-info-dark); font-size: 12px; line-height: 1.6;
}
.wg-leader { display: flex; align-items: center; gap: 6px; margin-top: 2px; font-size: 12px; color: var(--c-success-dark); }
.wg-leader .ico { width: 14px; height: 14px; flex-shrink: 0; }
.wg-desc { margin: 2px 0 0; font-size: 12px; color: var(--c-text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wg-acts { display: flex; align-items: center; gap: 4px; flex-shrink: 0; flex-wrap: wrap; }
.btn-white.is-green { border-color: #a7f3d0; color: var(--c-success-dark); }
.btn-white.is-green:hover { background: var(--c-success-light); }
.btn-white.is-red { border-color: var(--c-danger-border); color: var(--c-danger); }
.btn-white.is-red:hover { background: var(--c-danger-light); }
.wg-body { background: var(--c-surface); }
.wg-newtitle { margin: 0 0 12px; font-size: 14px; font-weight: 600; color: var(--c-text); }
.wg-newlabel { display: block; font-size: 12px; color: var(--c-text-sub); margin-bottom: 4px; }

/* 旧表格版展开行的样式保留（其它页面若沿用表格版仍可用） */
.wg-expand-row > td.wg-expand {
    background: var(--c-bg-subtle);
    border-top: 2px solid var(--c-border);
    padding: 0 14px 12px;
}
.wg-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    padding: 8px 16px;
    border-bottom: 1px solid var(--c-border);
    background: var(--c-surface);
    position: relative;
}
.wg-body .table-wrap { padding: 0 16px; }
.wg-body .pager, .wg-body .wg-foot { padding-left: 16px; padding-right: 16px; }
.wg-search { display: flex; align-items: center; gap: 6px; flex: 0 1 320px; }
.wg-search .input { flex: 1; min-width: 140px; }
/* 列设置 / 导出面板：整行展开在工具条下面（.col-panel 原为绝对定位，这里改回文档流） */
.wg-col-panel, .wg-exp-panel {
    position: absolute;
    right: 16px;
    top: 44px;
    flex: 0 0 100%;
    margin-top: 4px;
    box-shadow: var(--shadow-lg);
}
.wg-imp {
    position: absolute;
    z-index: 20;
    right: 0;
    top: 100%;
    min-width: 320px;
    padding: 10px 12px;
    background: var(--c-surface);
    border: 1px solid var(--c-border);
    border-radius: 10px;
    box-shadow: var(--shadow-lg);
}
.wg-batch { margin: 0; padding: 10px 16px; border-bottom: 1px solid var(--c-border); }
.wg-batch-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.wg-batch-row .muted { font-size: 12px; }
.wg-mtable { font-size: 13px; }
.wg-foot { padding: 8px 2px 2px; font-size: 12px; color: var(--c-text-muted); }

/* ---------- 会员设置：等级动作按钮 + 预览结果 ---------- */
.lv-acts {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin: 0 0 12px;
    padding: 10px 12px;
    background: var(--c-bg-subtle);
    border: 1px solid var(--c-border);
    border-radius: 10px;
}
.lv-acts-label { font-size: 12px; font-weight: 600; color: var(--c-text-mid); margin-right: 2px; }
.lv-preview {
    margin: 0 0 14px;
    padding: 12px;
    border: 1px solid var(--c-border);
    border-radius: 10px;
    background: var(--c-surface);
}
.lv-preview-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 8px;
}
.lv-preview-head .muted { font-size: 12px; }
.lv-preview table.table { font-size: 12px; margin: 0; }

/* ---------- 会员设置：积分年度结转预览 ---------- */
.ps-preview { margin-top: 12px; padding-top: 12px; border-top: 1px dashed var(--c-border); }
.ps-preview-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 8px;
}
.ps-preview-head .muted { font-size: 12px; }
.ps-preview table.table { font-size: 12px; margin: 0; }
.ps-carried { color: var(--brand); font-weight: 600; }
.ps-preview-foot { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px; }

/* ==========================================================================
   会员模块 UI 对齐（2026-09-29）—— 统计卡 / 工具栏按钮组 / 纯表格 / 表单网格
   参照：src/routes/admin.members.tsx、src/components/DataTable.tsx、
        src/components/points-logs.tsx、src/components/checkin-logs.tsx
   ========================================================================== */

/* --- 统计卡：原版 `grid grid-cols-2 md:grid-cols-4 gap-4` + 48px 圆角图标底 --- */
.stat-grid.is-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
.stat-grid.is-3 { grid-template-columns: minmax(0, 1fr); gap: 12px; }
@media (min-width: 768px) { .stat-grid.is-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (min-width: 640px) { .stat-grid.is-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.stat-card.is-ico {
    display: flex; align-items: center; gap: 16px; padding: 16px;
    transition: box-shadow .15s;
}
.stat-card.is-ico:hover {
    box-shadow: var(--shadow-md);
}
.sc-ico {
    width: 48px; height: 48px; border-radius: 12px; flex-shrink: 0;
    display: inline-flex; align-items: center; justify-content: center;
}
.sc-ico .ico { width: 24px; height: 24px; }
.sc-ico.is-blue   { background: var(--c-info-light); color: var(--c-info); }
.sc-ico.is-green  { background: var(--c-success-light); color: #22c55e; }
.sc-ico.is-red    { background: var(--c-danger-light); color: var(--c-danger); }
.sc-ico.is-orange { background: var(--c-warning-light); color: var(--c-warning-dark); }
.sc-ico.is-amber  { background: var(--c-warning-light); color: var(--c-warning-dark); }
.sc-body { min-width: 0; }
.stat-card.is-ico .stat-label { font-size: 12px; color: var(--c-text-sub); }
.stat-card.is-ico .stat-value { margin: 2px 0 0; font-size: 24px; line-height: 1.25; color: var(--c-text); }
.stat-value.is-green  { color: var(--c-success-dark); }
.stat-value.is-red    { color: var(--c-danger); }
.stat-value.is-orange { color: var(--c-warning-dark); }
.stat-value.is-amber  { color: var(--c-warning-dark); }

/* 分布图卡：原版是 20px 主题色裸图标（不是带底色的方块），标题 14px */
.dist-ico { width: 20px; height: 20px; border-radius: 0; background: none; color: var(--brand); }
.dist-ico .ico { width: 20px; height: 20px; }
.dist-title { font-size: 14px; }

/* --- 表格工具栏按钮组：原版 `px-3 py-1.5 text-sm bg-white border-gray-200 rounded-lg` --- */
.btn-white { background: var(--c-surface); border-color: var(--c-border); color: var(--c-text-mid); }
.btn-white:hover { background: var(--c-bg-subtle); }
.btn-sm.btn-white { padding: 6px 12px; font-size: 14px; border-radius: 8px; }
.tt-ico { width: 16px; height: 16px; flex-shrink: 0; vertical-align: -3px; margin-right: 4px; }
.tt-pop { position: relative; display: inline-block; }
.col-panel-grip { color: var(--c-border-strong); display: inline-flex; }
.col-panel-grip .ico { width: 14px; height: 14px; }
.col-panel-lab { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.col-panel label { gap: 8px; padding: 5px 0; font-size: 13px; }
.col-panel-item .tt-ico { margin-right: 4px; }

/* 导入面板：整行（flex-basis:100%）而不是第二个「导入 CSV」按钮 */
.imp-box.is-full { flex-basis: 100%; width: 100%; margin-top: 8px; background: var(--c-bg-subtle); }
.imp-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 6px; }
.imp-head strong { font-size: 13px; color: var(--c-text-mid); }
.imp-close { border: 0; background: none; font-size: 18px; line-height: 1; color: var(--c-text-muted); cursor: pointer; padding: 0 2px; }
.imp-close:hover { color: var(--c-text-mid); }
.imp-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.imp-row .input[type="file"] { flex: 0 1 320px; }

/* --- 纯表格（积分流水 / 签到明细：原版是 Card + 无底色表头、行内小内边距） --- */
.table.is-plain { font-size: 14px; }
.table.is-plain th,
.table.is-plain td {
    padding: 8px 16px 8px 0;
    border-bottom: 1px solid var(--c-bg-muted);
    white-space: normal;
}
.table.is-plain thead th {
    background: none;
    color: var(--c-text-sub);
    font-size: 14px;
    font-weight: 500;
    text-transform: none;
    letter-spacing: 0;
    border-bottom: 1px solid var(--c-border);
}
.table.is-plain tbody tr:hover { background: var(--c-bg-subtle); }
/* 组管理 / 简单列表：参照 thead 是 `bg-gray-50 text-gray-500 text-xs font-medium`（不转大写） */
.table.is-soft thead th { font-weight: 500; font-size: 12px; text-transform: none; letter-spacing: 0; }
.table.is-soft th, .table.is-soft td { padding: 12px 16px; }
.card-pad { padding: var(--sp-4) var(--sp-6); }

/* --- 搜索框：原版 `relative flex-1 min-w-[200px] max-w-sm` + 左侧 16px 放大镜 --- */
.search-wrap { position: relative; flex: 1 1 200px; min-width: 200px; max-width: 420px; }
.search-wrap.is-wide { max-width: 460px; }
.search-wrap .search-ico {
    position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
    width: 16px; height: 16px; color: var(--c-text-muted); pointer-events: none;
}
.search-wrap .input { padding-left: 36px; }
.toolbar-sm { padding: 0; margin: 0; border: 0; background: none; }
.tt-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }

/* --- 表单网格：原版按 fieldset 固定列数（grid-cols-4 / 3 / 2） --- */
.form-grid.fg-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.form-grid.fg-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.form-grid.fg-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 1100px) { .form-grid.fg-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 720px) {
    .form-grid.fg-4, .form-grid.fg-3, .form-grid.fg-2 { grid-template-columns: minmax(0, 1fr); }
}
/* 表单里的「只读统计」区块：原版 bg-gray-50/60 */
.form-fieldset.is-readonly { background: var(--c-bg-subtle); }
.form-fieldset.is-readonly > legend { color: var(--c-text-sub); }
.input[readonly], .input:disabled { background: var(--c-bg-subtle); color: var(--c-text-mid); }

/* --- 会员列表顶部的「贡献分提示 + 群发 / 批量导入积分」独立一行 --- */
.m-toprow {
    display: flex; flex-wrap: wrap; align-items: center;
    justify-content: space-between; gap: 8px; margin-bottom: 8px;
}
.m-toprow-l { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--c-text-sub); }
.m-toprow-r { display: flex; align-items: center; gap: 8px; }
.m-hint {
    display: inline-flex; align-items: center; gap: 4px;
    padding: 4px 8px; border-radius: 4px;
    font-size: 12px; color: var(--c-warning-dark); background: var(--c-warning-light);
}
.m-hint .ico { width: 14px; height: 14px; }

/* --- 其它 Tab 的提示条（原版：bg-blue-50 / bg-gray-50 圆角条） --- */
.tipbar {
    display: flex; align-items: flex-start; gap: 8px;
    padding: 12px 14px; border-radius: 12px;
    font-size: 12px; line-height: 1.7;
}
.tipbar .ico { width: 16px; height: 16px; flex-shrink: 0; margin-top: 2px; }
.tipbar.is-blue { background: var(--c-info-light); border: 1px solid var(--c-info-border); color: var(--c-info-dark); }
.tipbar.is-gray { background: var(--c-bg-subtle); border: 1px solid var(--c-bg-muted); color: var(--c-text-sub); }
.tipbar p { margin: 0; }
.tipbar b { font-weight: 600; }

/* --- 组管理：字母码徽标 / 状态徽标 / 行内「编辑」按钮 --- */
.code-badge {
    display: inline-flex; align-items: center; padding: 2px 8px; border-radius: 6px;
    background: var(--c-danger-light); color: var(--c-danger-dark);
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 12px; font-weight: 600;
}
.pill { display: inline-block; padding: 2px 8px; border-radius: 999px; font-size: 12px; line-height: 1.6; }
.pill.is-on  { background: var(--c-success-light); color: var(--c-success-dark); }
.pill.is-off { background: var(--c-bg-muted); color: var(--c-text-sub); }
.btn-link-sm {
    display: inline-flex; align-items: center; gap: 4px;
    padding: 6px 10px; border-radius: 8px; font-size: 12px;
    color: var(--c-text-mid); background: none; border: 0; cursor: pointer;
}
.btn-link-sm:hover { background: var(--c-bg-muted); color: var(--c-text); }
.btn-link-sm .ico { width: 14px; height: 14px; }


/* ============================================================================
   现场素材 · 共用页头 + Tab 条（对齐旧版 admin.site-materials.tsx:243-307）
   ⚠️ Tab 样式与媒体库「类别 Tab」**不同**：旧版这里是
      `bg-white border border-gray-100 rounded-xl p-1` 容器 +
      **选中项主色实底白字** `bg-[var(--brand)] text-white`。
      逐项换算：gap-1=4 / p-1=4 / rounded-xl=12 / px-4 py-2=16·8 /
      text-xs=12 / font-bold=700 / rounded-lg=8 —— **全部落在 DESIGN token 内**。
   ============================================================================ */
.sm-page-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-3);
    margin-bottom: var(--sp-4);
}
.sm-title { margin: 0; font-size: var(--fs-h1); font-weight: 700; color: var(--c-text); }
.sm-head-actions { display: flex; align-items: center; gap: var(--sp-2); }
.sm-tabs {
    display: inline-flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--sp-1);
    padding: var(--sp-1);
    margin-bottom: var(--sp-4);
    background: var(--c-surface);
    border: 1px solid var(--c-border);
    border-radius: var(--r-xl);
}
.sm-tab {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: var(--sp-2) var(--sp-4);
    border-radius: var(--r-lg);
    font-size: var(--fs-sm);
    font-weight: 700;
    color: var(--c-text-sub);
}
.sm-tab:hover { background: var(--c-bg-subtle); color: var(--c-text); text-decoration: none; }
.sm-tab.is-on { background: var(--c-primary); color: var(--c-text-invert); }
.sm-tab.is-on:hover { background: var(--c-primary-hover); color: var(--c-text-invert); }


/* ============================================================================
   现场素材 · 素材库 Tab 两栏布局（对齐旧版 admin.site-materials.tsx:313-345）
   旧版：`flex flex-col lg:flex-row gap-4` → 左 `lg:w-60 shrink-0 rounded-xl p-3`
         （= 240px / 12px 内边距）→ 右 `flex-1 min-w-0 space-y-3`（区块间距 12px）
   工具栏：`rounded-xl p-3 flex flex-wrap items-center gap-2`（12px / 8px）
   ============================================================================ */
.sm-layout { display: flex; flex-direction: column; gap: var(--sp-4); }
.sm-side {
    flex: 0 0 auto;
    background: var(--c-surface);
    border: 1px solid var(--c-border);
    border-radius: var(--r-xl);
    padding: var(--sp-3);
}
.sm-side-title { font-size: var(--fs-sm); font-weight: 700; color: var(--c-text-sub); margin-bottom: var(--sp-2); }
.sm-side-list { display: flex; flex-direction: column; gap: var(--sp-1); max-height: 60vh; overflow-y: auto; }
.sm-side-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-2);
    padding: var(--sp-2) var(--sp-3);
    border-radius: var(--r-md);
    font-size: var(--fs-body);
    color: var(--c-text-sub);
}
.sm-side-item:hover { background: var(--c-bg-subtle); color: var(--c-text); text-decoration: none; }
.sm-side-item.is-on { background: var(--c-primary-light); color: var(--c-primary); font-weight: 600; }
.sm-side-item b { font-size: var(--fs-sm); font-weight: 600; color: var(--c-text-muted); }
.sm-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--sp-3); }
.sm-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--sp-2);
    padding: var(--sp-3);
    background: var(--c-surface);
    border: 1px solid var(--c-border);
    border-radius: var(--r-xl);
}
.sm-toolbar-q { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); }
.sm-toolbar-spacer { flex: 1 1 auto; }
.sm-toolbar .input { padding: 6px 8px; font-size: var(--fs-sm); }
.sm-toolbar .input.search-input { width: 208px; flex: 0 0 208px; }   /* 旧版 w-52 = 208px */
.sm-fold { background: var(--c-surface); border: 1px solid var(--c-border); border-radius: var(--r-xl); }
.sm-fold > summary { cursor: pointer; padding: var(--sp-3); font-size: var(--fs-body); font-weight: 700; color: var(--c-text-sub); list-style: none; }
.sm-fold > summary::-webkit-details-marker { display: none; }
.sm-fold[open] > summary { border-bottom: 1px solid var(--c-border); }
.sm-stat-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-3); margin-bottom: var(--sp-4); }
@media (min-width: 1024px) {
    .sm-layout { flex-direction: row; align-items: flex-start; }
    .sm-side { width: 240px; }
}
@media (min-width: 768px) { .sm-stat-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

/* ------------------------------------------------------------------
   现场素材 · 素材库：左「文件夹」栏 + 右内容栏
   旧版在线项目为 `flex`：`lg:w-60`(240px) + 右侧 `flex-1`，两栏 `gap-4`(16px)。
   这里改用 grid 显式定位左右栏，避免中间折叠区/表单把内容卡挤出右栏时
   右栏只剩内容宽度（表现为右侧大片留白、工具栏换行）。
   ------------------------------------------------------------------ */
@media (min-width: 1024px) {
    .sm-layout {
        display: grid;
        grid-template-columns: 240px minmax(0, 1fr);
        gap: var(--sp-4);
        align-items: start;
    }
    .sm-side {
        width: auto;
        grid-column: 1;
        grid-row: 1 / span 99;
    }
    .sm-main {
        grid-column: 2;
        min-width: 0;
    }
    /* 右栏内的直接内容卡（素材列表等）同样落到第 2 列 */
    .sm-layout > .card {
        grid-column: 2;
        margin: 0;
    }
}

/* 工具栏内的下拉：`.input` 自带 width:100% 会独占整行、把工具栏挤成多行；按内容宽度即可 */
.sm-toolbar select.input {
    width: auto;
    min-width: 104px;
}

/* ==================================================================
   媒体库（/admin/media）结构对齐旧版 src/routes/admin.media.tsx
   ------------------------------------------------------------------
   旧版右侧主区是 `flex-1 min-w-0 space-y-4`，只有 6 块：
     页头 / 工具栏 / 上传(裸虚线框) / 4 个小统计 chip / 网格或列表 / 分页
   工具栏 `flex flex-wrap items-center gap-3`（gap-3 = 12px），
   动作组 `flex items-center gap-2 ml-auto`（gap-2 = 8px）。
   旧版**没有**「上传文件」大卡片、没有底部批量大卡片、文件区没有卡片头。
   ================================================================== */

/* 右栏 = space-y-4（块间距 16px）；清掉历史遗留的单块 margin，
   否则 .media-actions 的 margin-top:12px 会把动作组压低 12px（肉眼就是「没对齐」） */
.media-main { display: flex; flex-direction: column; gap: var(--sp-4); }
.media-main > * { margin-top: 0; margin-bottom: 0; }
.media-bar { margin-bottom: 0; }
.media-actions { margin-top: 0; padding: 0; border: 0; background: none; }
.media-search .input { padding-right: var(--sp-4); }

/* 图标：旧版 w-4 h-4 = 16px，跟随文字颜色 */
.mi { width: 16px; height: 16px; flex: 0 0 auto; }

/* 类别 Tab：旧版两态都是 font-medium(500) */
.media-tab, .media-tab.is-on { font-weight: 500; }

/* 视图切换：旧版 `flex border rounded-lg overflow-hidden`，两态**纯图标** */
.media-view-switch {
    display: inline-flex;
    border: 1px solid var(--c-border);
    border-radius: var(--r-lg);
    overflow: hidden;
}
.media-view-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 34px;
    background: var(--c-surface);
    color: var(--c-text-muted);
}
.media-view-btn:hover { color: var(--c-text-sub); text-decoration: none; }
.media-view-btn.is-on { background: var(--c-bg-muted); color: var(--c-text); }

/* 「移动 (N)」：摘要当按钮，点开是小面板 */
.media-move-batch { position: relative; }
.media-move-summary { list-style: none; cursor: pointer; }
.media-move-summary::-webkit-details-marker { display: none; }
.media-move-batch[open] > summary { background: var(--c-bg-muted); }

/* 「上传文件」用 label 当按钮（点它打开隐藏的 file input） */
.media-upload-label { cursor: pointer; }

/* 上传区：旧版 border-2 border-dashed rounded-xl p-8（空态 py-16），**没有卡片外壳** */
.media-upload-form { margin: 0; }
.media-file-input { display: none; }
.media-drop {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--sp-3);
    padding: 64px var(--sp-8);
    border: 2px dashed var(--c-border-strong);
    border-radius: var(--r-xl);
    background: none;
    text-align: center;
    cursor: pointer;
    transition: border-color .15s ease, background-color .15s ease;
}
.media-drop:hover { border-color: var(--c-primary); }
.media-drop.is-over { border-color: var(--c-primary); background: var(--c-primary-light); }
.media-drop-ball {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 64px;
    height: 64px;
    border-radius: var(--r-full);
    background: var(--c-bg-muted);
    color: var(--c-text-muted);
}
.media-drop-ball svg { width: 32px; height: 32px; }
.media-drop-title { margin: 0; font-size: var(--fs-body); font-weight: 500; color: var(--c-text-sub); }
.media-drop-hint { margin: 0; font-size: var(--fs-body); color: var(--c-text-muted); }
.media-upload-foot { display: flex; align-items: center; gap: var(--sp-4); margin-top: var(--sp-3); }
.media-upload-foot:empty { display: none; }

/* 4 个小统计 chip：旧版 `bg-white border rounded-lg px-4 py-2.5 shadow-sm` + 图标 + 两行 */
.media-chips { display: flex; flex-wrap: wrap; gap: var(--sp-3); }
.media-chip {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    background: var(--c-surface);
    border: 1px solid var(--c-border);
    border-radius: var(--r-lg);
    padding: 10px var(--sp-4);
    box-shadow: var(--shadow-sm);
}
.media-chip-ico { font-size: 16px; line-height: 1; }
.media-chip-label { font-size: var(--fs-sm); color: var(--c-text-sub); }
.media-chip-value { font-size: var(--fs-body); font-weight: 600; color: var(--c-text-mid); }

/* 文件区：旧版这里没有卡片、没有卡片头 */
.media-files { display: flex; flex-direction: column; gap: var(--sp-4); }

/* 网格：旧版 grid-cols-2 sm:3 md:4 lg:5 xl:6 gap-3 */
.media-grid { display: grid; gap: var(--sp-3); grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 640px)  { .media-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 768px)  { .media-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (min-width: 1024px) { .media-grid { grid-template-columns: repeat(5, minmax(0, 1fr)); } }
@media (min-width: 1280px) { .media-grid { grid-template-columns: repeat(6, minmax(0, 1fr)); } }

/* 卡片：旧版未选中 1px gray-200；选中 `ring-2 ring-primary border-primary` */
.media-tile {
    position: relative;
    display: flex;
    flex-direction: column;
    background: var(--c-surface);
    border: 1px solid var(--c-border);
    border-radius: var(--r-xl);
    overflow: hidden;
    box-shadow: var(--shadow-sm);
    transition: box-shadow .15s ease, border-color .15s ease;
}
.media-tile:hover { box-shadow: var(--shadow-md); }
.media-tile.is-on,
.media-tile:has(.media-tile-check input:checked) {
    border-color: var(--c-primary);
    box-shadow: 0 0 0 2px var(--c-primary);
}
.media-tile-media { background: var(--c-bg-subtle); }

/* 选择标记：旧版在**右上角**（top-2 right-2 w-5 h-5 rounded-full border-2），
   未选中时 hover 才出现；选中 = 主色实底 + 白勾 */
.media-tile-check {
    position: absolute;
    top: var(--sp-2);
    right: var(--sp-2);
    z-index: 4;
    width: 20px;
    height: 20px;
    margin: 0;
    cursor: pointer;
}
.media-tile-check input {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    opacity: 0;
    cursor: pointer;
}
.media-tile-check-dot {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    border-radius: var(--r-full);
    border: 2px solid var(--c-border-strong);
    background: var(--c-surface);
    color: transparent;
    font-size: 12px;
    line-height: 1;
    opacity: 0;
    transition: opacity .15s ease, background-color .15s ease, border-color .15s ease;
    pointer-events: none;
}
.media-tile:hover .media-tile-check-dot { opacity: 1; }
.media-tile-check input:checked + .media-tile-check-dot {
    opacity: 1;
    background: var(--c-primary);
    border-color: var(--c-primary);
    color: var(--c-text-invert);
}
.media-tile-check input:focus-visible + .media-tile-check-dot { outline: 2px solid var(--c-primary); outline-offset: 2px; }

/* 底部信息：旧版 p-2.5（10px）+ 文件名 12px/500 + 体积 mt-0.5（2px） */
.media-tile-cap { padding: 10px; }
.media-tile-name { font-weight: 500; color: var(--c-text-mid); }
.media-tile-meta { margin-top: 2px; }

/* 悬浮操作：旧版是整块黑色半透明遮罩（bg-black/40）+ 白色圆角图标按钮 */
.media-tile-hover {
    position: absolute;
    inset: 0;
    z-index: 3;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--sp-1);
    background: rgba(0, 0, 0, .4);
    opacity: 0;
    transition: opacity .15s ease;
}
.media-tile:hover .media-tile-hover,
.media-tile:focus-within .media-tile-hover { opacity: 1; }
.media-act-form { display: contents; }
.media-act-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    border: 0;
    border-radius: var(--r-lg);
    background: var(--c-surface);
    color: var(--c-text);
    box-shadow: var(--shadow-lg);
    cursor: pointer;
    transition: background-color .15s ease;
}
.media-act-btn:hover { background: var(--c-bg-muted); }
.media-act-btn .mi.is-danger { color: var(--c-danger); }
.media-act-btn.is-flat { width: 28px; height: 28px; box-shadow: none; color: var(--c-text-sub); }
.media-act-btn.is-flat:hover { background: var(--c-bg-muted); color: var(--c-text); }

/* 列表视图：旧版首列是 40px 缩略图，操作列是 3 个 14px 图标按钮 */
.media-row-thumb {
    display: block;
    width: 40px;
    height: 40px;
    padding: 0;
    border: 0;
    border-radius: var(--r-md);
    overflow: hidden;
    background: var(--c-bg-muted);
    cursor: pointer;
}
.media-row-thumb img { display: block; width: 100%; height: 100%; object-fit: cover; }
.media-row-doc {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: var(--r-md);
    background: var(--c-bg-muted);
    color: var(--c-text-muted);
    font-size: 18px;
}
button.media-row-doc { border: 0; cursor: pointer; }
button.media-row-doc.is-video { color: var(--c-primary); }
.media-row-name { font-weight: 500; color: var(--c-text-mid); }
.media-row-ops { display: inline-flex; align-items: center; gap: var(--sp-1); }

/* 空态：旧版 py-16（64px） */
.media-files .media-empty { padding: 64px var(--sp-4); }

/* 工具栏的「删除 (N)」：旧版是**红底实心**（text-white bg-red-600 bg-red-700 hover）；
   本项目 .btn-danger 是「白底 + 红字 + 红描边」的幽灵样式，这里单独给实心版本。
   颜色用语义 token --c-danger(#EF4444) / --c-danger-dark(#B91C1C)，
   ⚠️ 与旧版 red-600(#DC2626) 差一档（DESIGN 禁止新增颜色，故不硬编码）。 */
.media-bar .btn-danger {
    background: var(--c-danger);
    border-color: var(--c-danger);
    color: var(--c-text-invert);
}
.media-bar .btn-danger:hover { background: var(--c-danger-dark); border-color: var(--c-danger-dark); }

/* 🔴 瓦片容器必须是 **block**（原项目就是普通 div，不是 flex）：
   基类写的 `display:flex; flex-direction:column` 会让 .media-tile-media 成为 flex item，
   而 flex item 的 `min-height:auto` = 内容固有高度 → 竖图（如 169x300）会撑到 378px，
   把 aspect-ratio:1/1 顶掉，结果同一行瓦片高度参差不齐。 */
.media-tile { display: block; }
.media-tile-media { min-height: 0; }

/* 「移动 (N)」按钮：原项目是**白底 + 灰描边**（bg-white border-gray-200 hover:bg-gray-50），
   基类 .btn 给的是灰底（--c-bg-muted），这里纠正回白色 */
.media-move-summary { background: var(--c-surface); border: 1px solid var(--c-border); }
.media-move-summary:hover { background: var(--c-bg-subtle); }

/* ==================================================================
   现场素材 · 对齐原项目 admin.site-materials.tsx
   原项目：页头 → 5 张统计卡(grid-cols-2 md:grid-cols-5 gap-3)
          → Tab 条 → Tab 内容
   统计卡：`bg-white border border-gray-100 rounded-xl px-4 py-3`
          + 标签行 `flex items-center gap-2 text-xs text-gray-400`（图标 14px 带色）
          + 数值行 `text-lg font-black text-gray-800 mt-1`（**没有第三行脚注**）
   ================================================================== */
.sm-stat-grid { display: grid; gap: var(--sp-3); grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 768px) { .sm-stat-grid { grid-template-columns: repeat(5, minmax(0, 1fr)); } }
.sm-stat {
    background: var(--c-surface);
    border: 1px solid var(--c-border);
    border-radius: var(--r-xl);
    padding: 12px var(--sp-4);
}
.sm-stat-label {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    font-size: var(--fs-sm);
    color: var(--c-text-muted);
}
.sm-stat-ico { width: 14px; height: 14px; flex: 0 0 auto; }
.sm-stat-ico.is-amber   { color: var(--c-warning); }
.sm-stat-ico.is-emerald { color: var(--c-success); }
.sm-stat-ico.is-blue    { color: var(--c-info); }
.sm-stat-ico.is-purple  { color: var(--c-info); }
.sm-stat-ico.is-primary { color: var(--c-primary); }
.sm-stat-value { margin-top: var(--sp-1); font-size: 18px; font-weight: 900; color: var(--c-text); }

/* 素材库右栏 = `flex-1 min-w-0 space-y-3`（12px） */
.sm-main { gap: var(--sp-3); }
.sm-count { font-size: var(--fs-sm); color: var(--c-text-muted); }
.sm-sel-num { color: var(--c-primary); font-weight: 700; }

/* 批量操作栏：原项目**常驻显示**（未勾选时按钮置灰），
   选中后整块转红底：`bg-red-50/60 border-red-100`，未选中 `bg-gray-50 border-gray-100` */
.sm-batchbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--sp-2);
    padding: var(--sp-3);
    border: 1px solid var(--c-border);
    border-radius: var(--r-xl);
    background: var(--c-bg-subtle);
    transition: background-color .15s ease, border-color .15s ease;
}
.sm-batchbar.is-active { background: var(--c-danger-light); border-color: var(--c-danger-border); }
.sm-batchbar-title { font-size: var(--fs-sm); font-weight: 700; color: var(--c-text-muted); margin-right: var(--sp-1); }
.sm-batchbar.is-active .sm-batchbar-title { color: var(--c-primary); }
.sm-batchbar .btn:disabled { opacity: .45; cursor: not-allowed; }
.sm-batchbar .btn { background: var(--c-surface); border: 1px solid var(--c-border); color: var(--c-text-sub); }
.sm-batchbar .btn:hover:not(:disabled) { background: var(--c-bg-subtle); }
.sm-batchbar .btn-danger { background: var(--c-surface); border-color: var(--c-danger-border); color: var(--c-danger); }
.sm-batchbar .btn-danger:hover:not(:disabled) { background: var(--c-danger-light); }
.sm-batchbar-clear { margin-left: auto; font-size: var(--fs-sm); color: var(--c-text-muted); background: none; border: 0; cursor: pointer; }
.sm-batchbar-clear:hover { color: var(--c-text-sub); }

/* 两种下载方式说明（原项目原句，11px→本项目最小号 12px） */
.sm-hint { margin: 0; font-size: var(--fs-sm); color: var(--c-text-muted); }

/* 分页：原项目是**居中**（`flex items-center justify-center gap-2 pt-2`） */
.sm-main .pager { justify-content: center; }

/* ------------------------------------------------------------------
   现场素材 · 下载记录页 + 左栏标题（对齐原项目 admin.site-materials.tsx）
   · 下载记录：白卡 + 卡头「最近下载记录（近 20 条）」+ 表格 text-xs / th bg-gray-50
   · 左栏：「文件夹（N）」+ 右侧 ＋ 新建
   ------------------------------------------------------------------ */
.sm-side-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--sp-2); }
.sm-side-head .sm-side-title { margin-bottom: 0; }
.sm-side-add {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    border-radius: var(--r-sm);
    color: var(--c-text-muted);
    font-size: 14px;
    line-height: 1;
}
.sm-side-add:hover { color: var(--c-primary); background: var(--c-bg-muted); text-decoration: none; }

.sm-card {
    background: var(--c-surface);
    border: 1px solid var(--c-border);
    border-radius: var(--r-xl);
    overflow: hidden;
}
.sm-card-head {
    padding: var(--sp-3) var(--sp-4);
    border-bottom: 1px solid var(--c-bg-muted);
    font-size: var(--fs-sm);
    font-weight: 900;
    color: var(--c-text-mid);
}
.sm-table-scroll { overflow-x: auto; }
.sm-table { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
.sm-table thead tr { background: var(--c-bg-subtle); }
.sm-table th {
    text-align: left;
    padding: 10px var(--sp-4);
    font-weight: 500;
    color: var(--c-text-muted);
}
.sm-table tbody tr { border-top: 1px solid var(--c-bg-muted); }
.sm-table td { padding: 10px var(--sp-4); }
.sm-table td.is-muted { color: var(--c-text-muted); }
.sm-table td.is-strong { color: var(--c-text-mid); font-weight: 700; }
.sm-table-empty { padding: 48px var(--sp-4); text-align: center; font-size: var(--fs-sm); color: var(--c-text-muted); }

/* ------------------------------------------------------------------
   批量操作栏「选中态」兜底（放在文件**最末尾** + 提高优先级）：
   `.sm-batchbar.is-active` 原本写在中间段，实测被同页某条规则盖住
   （探针元素同 class 却能算出 #FEF2F2），这里再压一条确保生效。
   原项目口径：选中 = bg-red-50/60 + border-red-100，未选中 = bg-gray-50 + border-gray-100。
   ------------------------------------------------------------------ */
.sm-main .sm-batchbar.is-active {
    background: var(--c-danger-light);
    border-color: var(--c-danger-border);
}

/* ------------------------------------------------------------------
   现场素材 · TAB 页版式（对齐原项目 admin.site-materials.tsx）
   · .sm-info      蓝色流程说明卡（bg-blue-50 / border-blue-100 / text-blue-800）
   · .sm-bar       「共 N 个…」+ 右侧主按钮 的一行
   · .sm-badge     状态徽章（rounded-full text-[10px] px-2 py-0.5）
   · .sm-link      表格里的文字链接（编辑=蓝 / 删除=红）
   ------------------------------------------------------------------ */
.sm-info {
    background: var(--c-info-light);
    border: 1px solid var(--c-info-border);
    border-radius: var(--r-xl);
    padding: var(--sp-3) var(--sp-4);
    font-size: var(--fs-sm);
    color: var(--c-info-dark);
    line-height: 1.7;
}
.sm-info p { margin: 0; }
.sm-info-title { font-weight: 700; margin-bottom: var(--sp-1) !important; }
.sm-info-url { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; word-break: break-all; }

.sm-bar { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); }
.sm-bar-count { font-size: var(--fs-sm); color: var(--c-text-muted); }

.sm-badge {
    display: inline-block;
    padding: 2px var(--sp-2);
    border-radius: var(--r-full);
    font-size: 11px;
    line-height: 1.5;
}
.sm-badge.is-on { background: var(--c-success-light); color: var(--c-success-dark); }
.sm-badge.is-off { background: var(--c-bg-muted); color: var(--c-text-muted); }

.sm-table td.is-right, .sm-table th.is-right { text-align: right; }
.sm-table td.is-mono { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; color: var(--c-text-muted); }
.sm-link { background: none; border: 0; padding: 0; font-size: var(--fs-sm); cursor: pointer; }
.sm-link.is-edit { color: var(--c-info-dark); }
.sm-link.is-del { color: var(--c-danger); }
.sm-link:hover { text-decoration: underline; }
.sm-inline-form { display: inline; margin-left: var(--sp-3); }

.sm-card-body { padding: var(--sp-4); }
.sm-form-card { margin-top: var(--sp-3); }

/* 记者登录提示条（旧版 bg-white border rounded-xl p-3 + 靛蓝描边按钮） */
.sm-reporter-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-2);
    background: var(--c-surface);
    border: 1px solid var(--c-border);
    border-radius: var(--r-xl);
    padding: var(--sp-3);
}
.sm-reporter-tip { margin: 0; font-size: var(--fs-sm); color: var(--c-text-sub); }
.sm-reporter-btn { border: 1px solid var(--c-info-border); color: var(--c-info-dark); background: var(--c-surface); }
.sm-reporter-btn:hover { background: var(--c-info-light); }

/* ------------------------------------------------------------------
   媒体库左栏「文件夹」：高度随窗口自适应
   原项目是「内容高度卡片 + 列表 max-h-[60vh] 滚动」；运营要求整栏与窗口高度对齐，
   于是整栏给一个随视口变化的定高，文件夹列表在栏内滚动、底部统计常驻栏底。
   实测（1440×1094 视口）：面板顶边 80px，底部留 24px → 104px 偏移。
   ------------------------------------------------------------------ */
@media (min-width: 1024px) {
    .media-panel {
        position: sticky;
        top: var(--sp-3);
        height: calc(100vh - 104px);
        max-height: calc(100vh - 104px);
    }
    .media-panel.is-collapsed {
        position: static;
        height: auto;
        max-height: none;
    }
    /* 列表在栏内滚动（不再用 52vh 硬上限），统计栏贴底 */
    .media-folders {
        flex: 1 1 auto;
        min-height: 0;
        max-height: none;
        overflow-y: auto;
    }
}

/* ------------------------------------------------------------------
   ⚠️ 统一各页宽度的**真正**开关在根元素：
   长页面（如素材库）是**整页滚动** → 视口滚动条占 15px，body 比短页面窄 15px，
   于是同一模块的多个 Tab 宽度不一致、切页时还会横向抖动。
   在 html 上 `scrollbar-gutter: stable` 预留给视口滚动条，所有页面宽度即严格一致。
   （只给 .content 加是没用的 —— 那时滚动条在文档上，不在 .content 上。）
   ------------------------------------------------------------------ */
html { scrollbar-gutter: stable; }
