/* 星河 API · 面板样式（本地内置，无 CDN）
 *
 * 风格：现代 / 简洁 / 扁平 / 年轻化 + 毛玻璃（glassmorphism）。
 * 布局：左侧边栏（可折叠）+ 顶部 Header（标题 / 主题 / 通知 / 用户）+ 右侧内容区，主流后台形态。
 * 组件：Toast 通知、Modal 弹窗、Header 下拉（通知中心 / 用户菜单）。
 * 组件库（见「组件库」区块，跨浏览器一致的自绘控件）：
 *   - 按钮 .btn（.primary/.soft/.ghost/.danger 配色，.small/.mini 尺寸，内联 <svg> 图标）
 *   - 输入 input/textarea（统一 focus/hover/disabled/placeholder）
 *   - 下拉 <select>（admin.js 增强为自定义下拉，多选带标签；data-native 可跳过）
 *   - 多选框 checkbox / 单选框 radio（appearance:none 自绘，加 .switch 变开关）
 * 主题：JS 落 <html data-theme=dark|light>；未设置时兜底深色。
 * 变量名（--fg/--sub/--grid/--accent/--ok/--warn/--danger）被 public/assets/charts.js 读取，勿改名。
 */

/* ───────── 字体（本地 ttf，public/assets/fonts/） ───────── */
@font-face {
    font-family: 'InstrumentSans';
    src: url('./fonts/InstrumentSans-Regular.ttf') format('truetype');
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'InstrumentSans';
    src: url('./fonts/InstrumentSans-Bold.ttf') format('truetype');
    font-weight: 700;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'InstrumentSans';
    src: url('./fonts/InstrumentSans-Italic.ttf') format('truetype');
    font-weight: 400;
    font-style: italic;
    font-display: swap;
}

@font-face {
    font-family: 'GeistMono';
    src: url('./fonts/GeistMono-Regular.ttf') format('truetype');
    font-weight: 400;
    font-display: swap;
}

@font-face {
    font-family: 'GeistMono';
    src: url('./fonts/GeistMono-Bold.ttf') format('truetype');
    font-weight: 700;
    font-display: swap;
}

/* ───────── 深色（默认） ───────── */
:root {
    --bg: #0c1022;
    --bg2: #131a33;
    --panel: rgba(21, 27, 52, .62);
    --panel-solid: #151b34;
    --panel-2: rgba(30, 38, 68, .55);
    --glass: rgba(18, 24, 46, .68);
    --border: rgba(255, 255, 255, .09);
    --rule: rgba(255, 255, 255, .08);
    --fg: #eef1fb;
    --ink: #eef1fb;
    --sub: #9aa6c6;
    --muted: #67718f;
    --grid: rgba(154, 166, 198, .16);
    --accent: #6d7cff;
    --violet: #a78bfa;
    --pink: #f472b6;
    --sky: #38bdf8;
    --brand-a: #6366f1;
    --brand-b: #8b5cf6;
    --accent2: #38d9c8;
    --ok: #2ee6a8;
    --warn: #ffb454;
    --danger: #ff6b81;
    --hover: rgba(255, 255, 255, .05);
    --warn-fg: #ffd9a0;
    --danger-fg: #ffb9c4;
    --radius: 12px;
    --radius-s: 8px;
    --shadow: 0 12px 40px rgba(3, 6, 20, .5);
    --shadow-s: 0 4px 16px rgba(3, 6, 20, .35);
    --glow-a: rgba(99, 102, 241, .12);
    --glow-b: rgba(139, 92, 246, .07);
    --glow-c: rgba(56, 217, 200, .05);
    --font: 'InstrumentSans', system-ui, -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif;
    --font-mono: 'GeistMono', ui-monospace, SFMono-Regular, Menlo, monospace;
    color-scheme: dark;
}

/* ───────── 浅色 ───────── */
html[data-theme="light"] {
    --bg: #f1f3fb;
    --bg2: #ffffff;
    --panel: rgba(255, 255, 255, .74);
    --panel-solid: #ffffff;
    --panel-2: rgba(244, 246, 253, .88);
    --glass: rgba(255, 255, 255, .82);
    --border: rgba(255, 255, 255, .85);
    --rule: #e4e8f4;
    --fg: #171c30;
    --ink: #171c30;
    --sub: #5c6879;
    --muted: #9aa3bd;
    --grid: rgba(92, 104, 130, .15);
    --accent: #5a67f2;
    --violet: #8b5cf6;
    --pink: #ec4899;
    --sky: #0ea5e9;
    --brand-a: #6366f1;
    --brand-b: #8b5cf6;
    --accent2: #0fb5a0;
    --ok: #10b981;
    --warn: #ef8f2f;
    --danger: #ef4757;
    --hover: rgba(90, 103, 242, .06);
    --warn-fg: #9a5b0a;
    --danger-fg: #c02836;
    --shadow: 0 12px 40px rgba(84, 96, 180, .14);
    --shadow-s: 0 4px 14px rgba(84, 96, 180, .10);
    --glow-a: rgba(99, 102, 241, .09);
    --glow-b: rgba(139, 92, 246, .06);
    --glow-c: rgba(34, 211, 238, .05);
    color-scheme: light;
}

/* ───────── 基础 ───────── */
* {
    box-sizing: border-box;
}

html,
body {
    margin: 0;
    padding: 0;
}

body {
    background: var(--bg);
    color: var(--fg);
    font: 15px/1.6 var(--font);
    -webkit-font-smoothing: antialiased;
    min-height: 100vh;
}

/* 彩色光晕（毛玻璃的底色） */
body::before {
    content: '';
    position: fixed;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    background:
        radial-gradient(52rem 32rem at -6rem -8rem, var(--glow-a), transparent 60%),
        radial-gradient(44rem 30rem at 108% 4%, var(--glow-b), transparent 62%),
        radial-gradient(40rem 28rem at 50% 118%, var(--glow-c), transparent 60%);
}

a {
    color: var(--accent);
    text-decoration: none;
}

h1,
h2,
h3 {
    line-height: 1.3;
}

::selection {
    background: rgba(109, 124, 255, .32);
}

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

/* ───────── 外壳布局 ───────── */
.app {
    position: relative;
    z-index: 1;
    display: flex;
    min-height: 100vh;
}

/* ── 侧边栏（玻璃，可折叠 mini） ── */
.sidebar {
    position: sticky;
    top: 0;
    flex: 0 0 236px;
    width: 236px;
    height: 100vh;
    display: flex;
    flex-direction: column;
    padding: 18px 14px 16px;
    background: var(--glass);
    backdrop-filter: blur(20px) saturate(1.4);
    -webkit-backdrop-filter: blur(20px) saturate(1.4);
    border-right: 1px solid var(--rule);
    transition: flex-basis .22s ease, width .22s ease;
    z-index: 30;
}

html[data-side="mini"] .sidebar {
    flex-basis: 74px;
    width: 74px;
    padding: 18px 10px 16px;
}

.side-brand {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 4px 8px 16px;
}

.logo-mark {
    flex: 0 0 36px;
    width: 36px;
    height: 36px;
    display: grid;
    place-items: center;
    /* 品牌徽标（SVG 自带渐变底），圆角贴合 SVG 徽章（rx 5.6/24），阴影随形 */
    border-radius: 23.4%;
    box-shadow: 0 4px 12px rgba(99, 102, 241, .28);
}

.logo-mark svg {
    width: 100%;
    height: 100%;
    display: block;
}

.logo-text {
    font-weight: 700;
    font-size: 16px;
    letter-spacing: .02em;
    white-space: nowrap;
}

.logo-text em {
    font-style: normal;
    color: var(--accent);
    margin-left: 2px;
}

/* 品牌文字列：站名 + 站点描述纵向堆叠（桌面折叠态整体隐藏，窄屏抽屉还原） */
.logo-col {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.logo-tagline {
    color: var(--muted);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: .05em;
    line-height: 1.2;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

html[data-side="mini"] .logo-col {
    display: none;
}

.side-nav {
    display: flex;
    flex-direction: column;
    gap: 4px;
    overflow-y: auto;
    overflow-x: hidden;
}

/* 导航分组标题：小号弱化文字（桌面折叠态转为细分隔线） */
.side-group-title {
    padding: 12px 12px 4px;
    color: var(--muted);
    font-size: 11.5px;
    font-weight: 600;
    letter-spacing: .08em;
    white-space: nowrap;
    user-select: none;
}

.side-link {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 10px 12px;
    border-radius: var(--radius-s);
    color: var(--sub);
    font-weight: 500;
    white-space: nowrap;
    transition: background .15s, color .15s;
}

.side-link .ico {
    display: inline-flex;
    width: 19px;
    height: 19px;
    flex: 0 0 19px;
}

.side-link .ico svg {
    width: 100%;
    height: 100%;
}

.side-link:hover {
    background: var(--hover);
    color: var(--fg);
}

.side-link.on {
    background: rgba(99, 102, 241, .12);
    color: var(--accent);
    font-weight: 700;
    box-shadow: inset 0 0 0 1px rgba(99, 102, 241, .22);
}

html[data-theme="light"] .side-link.on {
    color: var(--brand-a);
}

html[data-side="mini"] .side-link {
    justify-content: center;
    padding: 11px 0;
}

html[data-side="mini"] .side-link .txt {
    display: none;
}

/* 折叠态：分组标题转为细分隔线（文字隐藏） */
html[data-side="mini"] .side-group-title {
    height: 1px;
    margin: 8px 8px 4px;
    padding: 0;
    font-size: 0;
    background: var(--rule);
    border-radius: 1px;
}

.side-foot {
    margin-top: auto;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 14px 8px 2px;
    border-top: 1px solid var(--rule);
    color: var(--muted);
    font-size: 12px;
    font-family: var(--font-mono);
    white-space: nowrap;
    overflow: hidden;
}

.side-dot {
    flex: 0 0 8px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--ok);
    box-shadow: 0 0 8px var(--ok);
}

html[data-side="mini"] .side-foot .txt {
    display: none;
}

html[data-side="mini"] .side-foot {
    justify-content: center;
    padding-left: 0;
    padding-right: 0;
}

/* ── 右列 ── */
.main {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

/* ── 顶部 Header（sticky 玻璃） ── */
.topbar {
    position: sticky;
    top: 0;
    z-index: 25;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    height: 62px;
    padding: 0 26px;
    background: var(--glass);
    backdrop-filter: blur(20px) saturate(1.4);
    -webkit-backdrop-filter: blur(20px) saturate(1.4);
    border-bottom: 1px solid var(--rule);
}

.topbar-left {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
}

.topbar-title {
    margin: 0;
    font-size: 17px;
    font-weight: 700;
    letter-spacing: .01em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

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

.icon-btn {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    padding: 0;
    border: 1px solid transparent;
    border-radius: 10px;
    background: transparent;
    color: var(--sub);
    cursor: pointer;
    transition: background .15s, color .15s;
}

.icon-btn svg {
    width: 19px;
    height: 19px;
}

.icon-btn:hover {
    background: var(--hover);
    color: var(--fg);
}

.only-mobile {
    display: none !important;
}

/* 主题切换（单图标按钮，复用 .icon-btn 外观；浅色显月亮、深色显太阳，点击互切） */
.theme-toggle span {
    display: inline-flex;
    width: 19px;
    height: 19px;
}

.theme-toggle svg {
    width: 100%;
    height: 100%;
}

html[data-theme="light"] .theme-toggle .tt-sun {
    display: none;
}

html[data-theme="dark"] .theme-toggle .tt-moon {
    display: none;
}

/* ── Header 下拉（通知 / 用户） ── */
.pop {
    position: relative;
}

.user-btn {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 5px 9px 5px 5px;
    border: 1px solid var(--rule);
    border-radius: 999px;
    background: var(--panel-2);
    color: var(--fg);
    font: 600 13.5px/1.3 var(--font);
    cursor: pointer;
    transition: border-color .15s, background .15s;
}

.user-btn:hover {
    border-color: var(--accent);
}

.user-btn .chev {
    display: inline-flex;
    width: 14px;
    height: 14px;
    color: var(--muted);
}

.user-btn .chev svg {
    width: 100%;
    height: 100%;
}

.avatar {
    display: inline-grid;
    place-items: center;
    width: 28px;
    height: 28px;
    border-radius: 23.4%;
    overflow: hidden;
    box-shadow: 0 2px 8px rgba(99, 102, 241, .3);
}

.avatar svg {
    display: block;
    width: 100%;
    height: 100%;
}

.badge {
    position: absolute;
    top: 3px;
    right: 3px;
    min-width: 14px;
    height: 14px;
    padding: 0 3px;
    border-radius: 999px;
    background: var(--danger);
    color: #fff;
    font: 700 9.5px/14px var(--font);
    text-align: center;
    box-shadow: 0 1px 4px rgba(239, 71, 87, .3);
}

.pop-panel {
    position: absolute;
    top: calc(100% + 10px);
    right: 0;
    width: 320px;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    background: var(--glass);
    backdrop-filter: blur(22px) saturate(1.5);
    -webkit-backdrop-filter: blur(22px) saturate(1.5);
    box-shadow: var(--shadow);
    overflow: hidden;
    animation: popIn .16s ease;
    z-index: 60;
}

@keyframes popIn {
    from {
        opacity: 0;
        transform: translateY(-6px) scale(.98);
    }

    to {
        opacity: 1;
        transform: none;
    }
}

/* 用户菜单比通知面板窄 */
.pop-panel.user-panel {
    width: min(200px, calc(100vw - 28px));
}

/* 表格行内「更多」菜单（接口管理操作列）：span 容器作定位基准 + 窄面板 */
.row-actions .pop {
    display: inline-block;
    margin-left: 6px;
}

.pop-panel.row-menu {
    width: 136px;
}

.pop-panel.row-menu .pop-item {
    padding: 10px 14px;
}

/* 「更多」按钮右侧下拉箭头：展开时翻转朝上 */
.row-actions [data-pop-toggle] {
    gap: 4px;
}

.row-actions [data-pop-toggle] svg.caret {
    transition: transform .15s;
}

.row-actions [data-pop-toggle][aria-expanded="true"] svg.caret {
    transform: rotate(180deg);
}

.pop-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 13px 16px 11px;
    border-bottom: 1px solid var(--rule);
    font-size: 13.5px;
}

.pop-head .link {
    font-size: 12.5px;
}

.pop-sub {
    color: var(--muted);
    font-size: 12px;
}

.pop-body {
    max-height: 340px;
    overflow-y: auto;
}

.pop-empty {
    padding: 26px 16px;
    color: var(--muted);
    font-size: 13px;
    text-align: center;
}

.pop-foot {
    display: block;
    padding: 11px 16px;
    border-top: 1px solid var(--rule);
    text-align: center;
    font-size: 13px;
    font-weight: 600;
}

.pop-foot:hover {
    background: var(--hover);
}

/* 通知面板底部双链接：调用日志（事件来源）+ 告警中心 */
.pop-foot-row {
    display: flex;
    border-top: 1px solid var(--rule);
}

.pop-foot-row .pop-foot {
    flex: 1;
    border-top: 0;
}

.pop-foot-row .pop-foot+.pop-foot {
    border-left: 1px solid var(--rule);
}

.pop-item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 11px 16px;
    border: 0;
    background: transparent;
    color: var(--fg);
    font: 500 13.5px/1.4 var(--font);
    text-align: left;
    cursor: pointer;
}

.pop-item svg {
    width: 16px;
    height: 16px;
    color: var(--sub);
}

.pop-item:hover {
    background: var(--hover);
}

.pop-item.danger {
    color: var(--danger);
}

.pop-item.danger svg {
    color: var(--danger);
}

/* 通知列表项 */
.ntf {
    display: flex;
    gap: 11px;
    padding: 11px 14px;
    border-bottom: 1px solid var(--rule);
    cursor: pointer;
    transition: background .12s;
}

.ntf:last-child {
    border-bottom: 0;
}

.ntf:hover {
    background: var(--hover);
}

.ntf.unread {
    background: rgba(99, 102, 241, .07);
}

.ntf-dot {
    flex: 0 0 8px;
    width: 8px;
    height: 8px;
    margin-top: 7px;
    border-radius: 50%;
}

.ntf-dot.ok {
    background: var(--ok);
}

.ntf-dot.warn {
    background: var(--warn);
}

.ntf-dot.danger {
    background: var(--danger);
}

.ntf-title .ntf-time {
    margin-left: auto;
    font-weight: 400;
}

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

.ntf-title {
    font-size: 13px;
    font-weight: 600;
    display: flex;
    gap: 8px;
    align-items: baseline;
}

.ntf-title .path {
    font-family: var(--font-mono);
    font-weight: 400;
    color: var(--sub);
    font-size: 12px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ntf-desc {
    color: var(--muted);
    font-size: 12px;
    font-family: var(--font-mono);
}

.ntf-time {
    flex: 0 0 auto;
    color: var(--muted);
    font-size: 11.5px;
    font-family: var(--font-mono);
}

/* ── 内容区 ── */
.page {
    width: 100%;
    max-width: 1180px;
    margin: 0 auto;
    padding: 28px 30px 64px;
}

.page-auth {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    padding: 24px;
}

/* 页头：标题 + 描述（总览样式，全站统一），操作区不与标题同行 */
.page-head {
    margin: 4px 0 24px;
}

.page-head h1 {
    margin: 0;
    font-size: 25px;
    font-weight: 700;
}

.page-head .sub {
    display: block;
    margin: 6px 0 0;
    color: var(--muted);
    font-size: 13px;
}

/* 页头内的分段控件（日志分类）独占一行 */
.page-head .range {
    margin-top: 14px;
}

.range {
    display: inline-flex;
    gap: 3px;
    padding: 3px;
    border: 1px solid var(--rule);
    border-radius: 9px;
    background: var(--panel-solid);
}

.range button,
.range a {
    border: 0;
    padding: 7px 18px;
    border-radius: 7px;
    background: transparent;
    color: var(--sub);
    font: 600 13.5px/1.4 var(--font);
    cursor: pointer;
}

/* 链接态分段控件（日志页分类页签：GET 参数切换，可收藏） */
.range a {
    text-decoration: none;
}

.range button:hover,
.range a:hover {
    color: var(--fg);
}

.range button.on,
.range a.on {
    background: var(--brand-a);
    color: #fff;
}

/* 日志页筛选面板：多条件一行排布，操作按钮贴齐输入行 */
.filter-grid {
    display: grid;
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: 14px;
    align-items: end;
}

.filter-grid label {
    margin-bottom: 0;
}

.filter-grid .f-actions {
    display: flex;
    align-items: center;
    gap: 10px;
    white-space: nowrap;
}

/* 筛选 / 搜索区按钮与输入框同高（input = 10px 内边距 + 14px/1.5 字号） */
.filter-grid .f-actions .btn,
.search-bar .f-actions .btn {
    padding-top: 10px;
    padding-bottom: 10px;
    font-size: 14px;
    line-height: 1.5;
}

/* 登录 / 操作日志简单搜索条：单输入 + 查询 / 重置 */
.search-bar {
    display: flex;
    gap: 14px;
    align-items: flex-end;
    flex-wrap: wrap;
}

.search-bar label {
    margin-bottom: 0;
}

.search-bar .search-field {
    flex: 1 1 300px;
    max-width: 460px;
}

.search-bar .f-actions {
    display: flex;
    align-items: center;
    gap: 10px;
    white-space: nowrap;
}

@media (max-width: 1180px) {
    .filter-grid {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

@media (max-width: 560px) {
    .filter-grid {
        grid-template-columns: 1fr;
    }

    .filter-grid .f-actions {
        grid-column: 1 / -1;
    }
}

/* 日志页分页条 */
.pager {
    display: flex;
    align-items: center;
    gap: 4px;
    flex-wrap: wrap;
    margin-top: 16px;
}

.pager .sum {
    margin-right: auto;
    color: var(--muted);
    font-size: 12.5px;
}

/* 分页条尾部：每页条数选择器 */
.pager-per {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-left: 12px;
    color: var(--muted);
    font-size: 12.5px;
}

.pager-per select {
    width: auto;
    padding: 6px 30px 6px 11px;
    font-size: 12.5px;
}

/* 下拉由组件库自绘（admin.js enhanceSelects 接管原生 select），覆盖其默认整宽 */
.pager-per .sr-select {
    width: auto;
    min-width: 88px;
    padding: 6px 11px;
    border-radius: 8px;
    font: 600 12.5px/1.45 var(--font);
}

.pager .pg {
    min-width: 32px;
    padding: 5px 10px;
    border: 1px solid var(--rule);
    border-radius: 8px;
    background: transparent;
    color: var(--sub);
    text-align: center;
    text-decoration: none;
    font: 600 12.5px/1.4 var(--font);
    transition: background .15s, border-color .15s, color .15s;
}

.pager a.pg:hover {
    background: var(--hover);
    color: var(--fg);
    border-color: var(--brand-a);
}

.pager .pg.on {
    background: var(--brand-a);
    border-color: transparent;
    color: #fff;
}

.pager .pg.dis {
    opacity: .45;
    pointer-events: none;
}

.pager .gap {
    padding: 0 4px;
    color: var(--muted);
}

/* ── 卡片（毛玻璃） ── */
.card {
    position: relative;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    background: var(--panel);
    backdrop-filter: blur(18px) saturate(1.35);
    -webkit-backdrop-filter: blur(18px) saturate(1.35);
    box-shadow: var(--shadow-s);
    padding: 20px 22px;
    margin: 0 0 22px;
}

.card h2 {
    margin: 0 0 20px;
    font-size: 15.5px;
    font-weight: 700;
}

.card h2 small,
.card h2 .sub {
    color: var(--muted);
    font-weight: 400;
    font-size: 12.5px;
    margin-left: 8px;
}

/* 卡片内的说明文字：明确间距，不依赖浏览器默认 margin；
   用 --muted 弱化为提示层级（不影响 span.sub 的 msg-ok/msg-danger 状态色） */
.card p.sub {
    margin: 10px 0;
    font-size: 13px;
    line-height: 1.7;
    color: var(--muted);
}

.grid-2 {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 22px;
    margin-bottom: 22px;
}

.grid-2 .card {
    margin: 0;
}

/* KPI（总览页：上下结构——图标+标签 / 大数值 / 副信息） */
.kpi-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 14px;
    margin-bottom: 22px;
}

.kpi {
    border-radius: var(--radius);
    border: 1px solid var(--border);
    background: var(--panel);
    backdrop-filter: blur(18px) saturate(1.35);
    -webkit-backdrop-filter: blur(18px) saturate(1.35);
    box-shadow: var(--shadow-s);
    padding: 14px 16px;
    position: relative;
    overflow: hidden;
}

/* KPI 图标块：小号浅色圆角方块，每卡一色（底色由主色 color-mix 派生，深浅主题自适应） */
.kpi-ico {
    flex: none;
    width: 26px;
    height: 26px;
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.kpi-ico.t-accent {
    color: var(--accent);
    background: color-mix(in srgb, var(--accent) 14%, transparent);
}

.kpi-ico.t-ok {
    color: var(--ok);
    background: color-mix(in srgb, var(--ok) 13%, transparent);
}

.kpi-ico.t-danger {
    color: var(--danger);
    background: color-mix(in srgb, var(--danger) 13%, transparent);
}

.kpi-ico.t-accent2 {
    color: var(--accent2);
    background: color-mix(in srgb, var(--accent2) 12%, transparent);
}

.kpi-ico.t-warn {
    color: var(--warn);
    background: color-mix(in srgb, var(--warn) 13%, transparent);
}

.kpi-ico.t-violet {
    color: var(--violet);
    background: color-mix(in srgb, var(--violet) 13%, transparent);
}

.kpi-ico.t-pink {
    color: var(--pink);
    background: color-mix(in srgb, var(--pink) 13%, transparent);
}

.kpi-ico.t-sky {
    color: var(--sky);
    background: color-mix(in srgb, var(--sky) 13%, transparent);
}

.kpi-ico svg {
    width: 14px;
    height: 14px;
    display: block;
}

.kpi-head {
    display: flex;
    align-items: center;
    gap: 8px;
}

.kpi-label {
    color: var(--muted);
    font-size: 12.5px;
    font-weight: 600;
}

.kpi-val {
    display: block;
    margin-top: 9px;
    font-size: 23px;
    font-weight: 700;
    font-family: var(--font-mono);
    letter-spacing: -.01em;
}

.kpi-val i {
    font-style: normal;
    font-size: 13px;
    color: var(--muted);
    margin-left: 3px;
}

.kpi-sub {
    display: block;
    margin-top: 5px;
    color: var(--muted);
    font-size: 11.5px;
}

/* 图表容器 */
.chart {
    width: 100%;
    height: 260px;
}

.chart-tiny {
    height: 190px;
}

/* 280px：与右栏（配额卡 + 热力图卡）自然高度接近，配合 .ov-side 末行 1fr 兜底微差 */
.chart-tall {
    height: 280px;
}

.chart-mid {
    height: 220px;
}

/* 弹窗内图表小标题（密钥「使用曲线」双图） */
.chart-title {
    margin: 12px 0 2px;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--fg);
}

/* 高内容弹窗：限高滚动，防止双图在小屏溢出 */
.modal.modal-tall .modal-body {
    max-height: 64vh;
    overflow: auto;
}

/* ── 总览页（需求 XIII）：趋势+侧栏 / 三卡 / 热力图 ── */
.card-head {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    margin-bottom: 14px;
}

.card-head h2 {
    margin: 0;
}

.card-head .card-head-tools {
    margin-left: auto;
}

/* 左右两栏高度保持一致：栅格默认拉伸，右栏热力图卡吃掉剩余高度 */
.ov-grid {
    display: grid;
    grid-template-columns: 2fr 1fr;
    gap: 22px;
    margin-bottom: 22px;
}

.ov-grid .card,
.ov-side .card {
    margin: 0;
}

.ov-side {
    display: grid;
    gap: 22px;
    grid-template-rows: auto 1fr;
}

.ov-trio {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 22px;
    margin-bottom: 22px;
}

.ov-trio .card {
    margin: 0;
}

/* 趋势图底栏：tab 胶囊 + 导出按钮 */
.trend-foot {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin-top: 12px;
}

.chips {
    display: inline-flex;
    gap: 3px;
    padding: 3px;
    border: 1px solid var(--rule);
    border-radius: 9px;
    background: var(--panel-2);
}

.chips button {
    border: 0;
    padding: 5px 12px;
    border-radius: 7px;
    background: transparent;
    color: var(--sub);
    font: 600 12.5px/1.4 var(--font);
    cursor: pointer;
}

.chips button.on {
    background: var(--brand-a);
    color: #fff;
}

.trend-tools {
    margin-left: auto;
    display: inline-flex;
    gap: 8px;
}

/* 灰色说明小字（趋势卡 / 配额 / 异常卡） */
.ov-note {
    margin: 12px 0 0;
    color: var(--muted);
    font-size: 12px;
    line-height: 1.7;
}

/* 全局配额 */
.quota-row {
    display: flex;
    align-items: baseline;
    gap: 7px;
    font-family: var(--font-mono);
}

.quota-row b {
    font-size: 21px;
    font-weight: 700;
}

.quota-cap {
    color: var(--muted);
    font-size: 12.5px;
}

.quota-sep {
    color: var(--muted);
    font-size: 13px;
}

/* 用量热力图：7 行（周一~周日）× 24 列（小时） */
.heat {
    display: grid;
    gap: 4px;
}

/* 热力图卡被拉伸补齐右栏高度时，格区在剩余空间垂直居中，图例贴底 */
.heat-card {
    display: flex;
    flex-direction: column;
}

.heat-card .heat {
    flex: 1;
    align-content: center;
}

.heat-row {
    display: grid;
    grid-template-columns: 18px repeat(24, 1fr);
    gap: 4px;
    align-items: center;
}

.heat-day {
    color: var(--sub);
    font-size: 11px;
    font-family: var(--font-mono);
    text-align: center;
}

/* l0 空档格：panel-2 与卡背景几乎同色，混入 muted 加深保证可见 */
.heat-cell {
    width: 100%;
    aspect-ratio: 1 / 1;
    border-radius: 4px;
    background: color-mix(in srgb, var(--muted) 22%, transparent);
}

.heat-cell.l1 {
    background: color-mix(in srgb, var(--accent) 25%, transparent);
}

.heat-cell.l2 {
    background: color-mix(in srgb, var(--accent) 45%, transparent);
}

.heat-cell.l3 {
    background: color-mix(in srgb, var(--accent) 70%, transparent);
}

.heat-cell.l4 {
    background: var(--accent);
}

.heat-legend {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 4px;
    margin-top: 10px;
    color: var(--muted);
    font-size: 11.5px;
}

.heat-legend .heat-cell {
    width: 12px;
    flex: none;
}

/* 近 1 小时异常：行式计数列表 */
.anom {
    display: grid;
    gap: 10px;
}

.anom-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 13px;
    border: 1px solid var(--rule);
    border-radius: var(--radius-s);
    background: var(--panel-2);
}

.anom-row span {
    color: var(--sub);
    font-size: 13px;
}

.anom-row b {
    font: 700 18px/1 var(--font-mono);
}

/* 窄屏：总览布局降级堆叠 */
@media (max-width: 1020px) {

    .ov-grid,
    .ov-trio {
        grid-template-columns: 1fr;
    }

    .kpi-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}

/* ── 表格 ── */
.tbl {
    width: 100%;
    border-collapse: collapse;
    font-size: 13.5px;
}

.tbl th,
.tbl td {
    padding: 11px 13px;
    text-align: center;
    border-bottom: 1px solid var(--rule);
}

.tbl thead th {
    position: sticky;
    top: 0;
    z-index: 2;
    background: rgba(99, 102, 241, .08);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    color: var(--sub);
    font: 700 11.5px/1.4 var(--font-mono);
    text-transform: uppercase;
    letter-spacing: .07em;
    white-space: nowrap;
}

.tbl tbody tr {
    transition: background .12s;
}

.tbl tbody tr:nth-child(even) {
    background: rgba(99, 102, 241, .035);
}

.tbl tbody tr:hover {
    background: var(--hover);
}

.tbl td.mono,
.tbl .mono {
    font-family: var(--font-mono);
    font-size: 12.5px;
}

.tbl .num {
    font-family: var(--font-mono);
}

/* 表格空态行（视图统一用 td.empty） */
.tbl td.empty {
    padding: 26px 14px;
    color: var(--muted);
    text-align: center;
}

/* 行内操作按钮组（接口管理等页的操作列） */
.row-actions {
    white-space: nowrap;
}

.row-actions .btn+.btn {
    margin-left: 6px;
}

/* pill 标签 */
.tag {
    display: inline-flex;
    align-items: center;
    vertical-align: middle;
    gap: 6px;
    padding: 2.5px 10px;
    border-radius: 999px;
    font: 600 11.5px/1.5 var(--font-mono);
    background: var(--panel-2);
    color: var(--sub);
    border: 1px solid var(--rule);
    white-space: nowrap;
}

.tag::before {
    content: '';
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
}

.tag.ok {
    color: var(--ok);
    background: rgba(46, 230, 168, .1);
    border-color: rgba(46, 230, 168, .3);
}

.tag.warn {
    color: var(--warn);
    background: rgba(255, 180, 84, .1);
    border-color: rgba(255, 180, 84, .3);
}

.tag.danger {
    color: var(--danger);
    background: rgba(255, 107, 129, .1);
    border-color: rgba(255, 107, 129, .3);
}

.tag.muted {
    color: var(--muted);
}

/* 接口级覆盖值高亮（紫，区别于文件配置默认值） */
.tag.ov {
    color: var(--accent);
    background: rgba(99, 102, 241, .10);
    border-color: rgba(99, 102, 241, .32);
}

/* 配额进度条 */
.bar {
    position: relative;
    height: 7px;
    min-width: 90px;
    border-radius: 999px;
    background: var(--panel-2);
    overflow: hidden;
}

.bar i {
    position: absolute;
    inset: 0 auto 0 0;
    border-radius: 999px;
    background: var(--accent);
}

.bar i.full {
    background: var(--danger);
}

/* ── 表单 ── */
label {
    display: block;
    color: var(--sub);
    font-size: 13px;
    font-weight: 600;
    margin-bottom: 6px;
}

/* 嵌套结构 <label><span>标题</span><input></label>：标题与控件之间留出间距 */
/* （label.check 开关行文字为裸文本节点，无 span 子元素，不受影响） */
label>span {
    display: block;
    margin-bottom: 7px;
}

/* input:not([type]) 兜底：漏写 type 的文本框（默认即 text）也套用统一样式 */
input[type="text"],
input[type="password"],
input[type="number"],
input[type="url"],
input:not([type]),
select,
textarea {
    width: 100%;
    padding: 10px 13px;
    border-radius: var(--radius-s);
    border: 1px solid var(--rule);
    background: var(--panel-2);
    color: var(--fg);
    font: 14px/1.5 var(--font);
    transition: border-color .15s, box-shadow .15s;
}

input:hover,
select:hover,
textarea:hover {
    border-color: var(--muted);
}

input:focus,
select:focus,
textarea:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px rgba(99, 102, 241, .18);
}

/* 表单校验错误态（JS 接管，替代浏览器原生气泡）：红边框 + 控件下方内联红色提示 */
.sr-err-input {
    border-color: var(--danger) !important;
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--danger) 14%, transparent);
}

.sr-err-msg {
    display: block;
    margin-top: 6px;
    font-size: 12px;
    line-height: 1.4;
    font-weight: 500;
    color: var(--danger);
    text-align: left;
}

input:disabled,
select:disabled,
textarea:disabled,
input[readonly] {
    opacity: .55;
    cursor: not-allowed;
}

input::placeholder,
textarea::placeholder {
    color: var(--muted);
    opacity: 1;
}

select {
    appearance: none;
    background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%), linear-gradient(135deg, var(--muted) 50%, transparent 50%);
    background-position: calc(100% - 18px) 55%, calc(100% - 13px) 55%;
    background-size: 5px 5px;
    background-repeat: no-repeat;
}

.form-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 17px 18px;
    align-items: start;
}

.form-grid .full {
    grid-column: 1 / -1;
}

/* 垂直对齐：开关行与同行「标题+输入框」格子的控件本体水平对齐——
   开关行贴行底（align-self:end；左右格子都有 6px 底边距，控件与开关的底边因此平齐），
   再加 10.5px 底部内边距把开关中心抬到控件中心高度：
   控件高 43px（10px 内边距×2 + 21px 行高 + 1px 边框×2），开关高 22px，(43-22)/2 = 10.5px */
.form-grid>label.check {
    align-self: end;
    padding-bottom: 10.5px;
    line-height: 22px;
}

/* 设置页行式布局：每行左侧「标题 + 当前/来源 + 提示」，右侧「控件 + 恢复默认 + 保存」 */
.set-rows {
    display: flex;
    flex-direction: column;
}

.set-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 24px;
    padding: 14px 0;
    border-bottom: 1px solid var(--rule);
}

.set-row:last-child {
    border-bottom: 0;
    padding-bottom: 2px;
}

.set-info {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 3px;
}

.set-t {
    font-size: 13px;
    font-weight: 600;
    color: var(--fg);
}

.set-meta {
    font-size: 12px;
    color: var(--muted);
}

.set-meta b {
    font-weight: 600;
    color: var(--sub);
}

.set-hint {
    margin: 0;
    font-size: 12.5px;
    line-height: 1.6;
    color: var(--muted);
}

.set-ctl {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-shrink: 0;
}

.set-ctl input[type="text"],
.set-ctl input[type="number"],
.set-ctl .sr-select {
    width: 210px;
}

.set-ctl .check {
    margin: 0;
}

/* 表单后的操作按钮：与上方内容拉开距离 */
.btn-gap {
    margin-top: 16px;
}

/* 设置页通道子分组：开关作组头，对应配置字段跟在组内，永不分离 */
.ch-group {
    padding: 15px 16px 16px;
    border: 1px solid var(--rule);
    border-radius: var(--radius-s);
    background: color-mix(in srgb, var(--panel-2) 55%, transparent);
}

.ch-group+.ch-group {
    margin-top: 14px;
}

.ch-head {
    margin-bottom: 12px;
    font-size: 14px;
    font-weight: 600;
    color: var(--fg);
}

.form-row {
    display: flex;
    align-items: center;
    gap: 9px;
}

.form-row label {
    margin: 0;
}

.field-hint {
    color: var(--muted);
    font-size: 12px;
    margin-top: 4px;
}

/* 按钮（组件库：图标插槽 + 多配色方案） */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    padding: 9px 18px;
    border-radius: 9px;
    border: 1px solid var(--rule);
    background: var(--panel-2);
    color: var(--fg);
    font: 600 13.5px/1.4 var(--font);
    cursor: pointer;
    transition: transform .12s, box-shadow .15s, background .15s, border-color .15s, color .15s;
}

.btn svg {
    width: 16px;
    height: 16px;
    flex: 0 0 16px;
}

.btn:hover {
    border-color: var(--accent);
}

.btn:active {
    transform: scale(.97);
}

.btn:disabled {
    opacity: .5;
    cursor: not-allowed;
    transform: none;
}

.btn.primary {
    border: 0;
    background: var(--brand-a);
    color: #fff;
    box-shadow: 0 2px 8px rgba(99, 102, 241, .28);
}

.btn.primary:hover {
    box-shadow: 0 4px 14px rgba(99, 102, 241, .38);
}

.btn.danger {
    border-color: rgba(255, 107, 129, .45);
    color: var(--danger);
    background: rgba(255, 107, 129, .08);
}

.btn.danger:hover {
    background: rgba(255, 107, 129, .16);
    border-color: var(--danger);
}

.btn.soft {
    border-color: rgba(99, 102, 241, .35);
    background: rgba(99, 102, 241, .10);
    color: var(--accent);
}

.btn.soft:hover {
    background: rgba(99, 102, 241, .17);
    border-color: rgba(99, 102, 241, .55);
}

html[data-theme="light"] .btn.soft {
    color: var(--brand-a);
}

.btn.ghost {
    border-color: transparent;
    background: transparent;
    color: var(--sub);
}

.btn.ghost:hover {
    border-color: transparent;
    background: var(--hover);
    color: var(--fg);
}

/* 警示色按钮（日志筛选重置等）：实底橙 + 白色文字 */
.btn.warn {
    border: 0;
    background: var(--warn);
    color: #fff;
}

.btn.warn:hover {
    filter: brightness(.93);
}

.btn.small {
    padding: 5px 12px;
    font-size: 12.5px;
    border-radius: 9px;
}

.btn.small svg {
    width: 14px;
    height: 14px;
    flex-basis: 14px;
}

.btn.mini {
    padding: 3.5px 10px;
    font-size: 12px;
    border-radius: 8px;
}

.btn.mini svg {
    width: 13px;
    height: 13px;
    flex-basis: 13px;
}

.link {
    border: 0;
    background: transparent;
    color: var(--accent);
    font: 600 13px/1.4 var(--font);
    cursor: pointer;
    padding: 0;
}

.link:hover {
    text-decoration: underline;
}

.link.danger {
    color: var(--danger);
}

/* ───────── 组件库（跨浏览器一致的自绘控件） ─────────
 * 用法（PHP 视图无需改结构，CSS 自动生效）：
 * - 多选框：原生 <input type="checkbox">，自动自绘；加 .switch 类变为开关
 * - 单选框：原生 <input type="radio">，自动自绘
 * - 下拉：原生 <select> 由 admin.js 增强为自定义下拉（含多选标签），不想增强的加 data-native
 * - 按钮：.btn + .primary/.soft/.ghost/.danger + .small/.mini；内联 <svg> 自动作为图标
 */
input[type="checkbox"],
input[type="radio"] {
    appearance: none;
    -webkit-appearance: none;
    position: relative;
    flex: 0 0 auto;
    width: 17px;
    height: 17px;
    margin: 0;
    padding: 0;
    border: 1.5px solid var(--rule);
    border-radius: 5px;
    background: var(--panel-2);
    cursor: pointer;
    vertical-align: -3px;
    transition: background .15s, border-color .15s, box-shadow .15s;
}

input[type="checkbox"]:hover,
input[type="radio"]:hover {
    border-color: var(--accent);
}

input[type="checkbox"]:checked {
    border-color: var(--brand-a);
    background: var(--brand-a);
}

input[type="checkbox"]:checked::after {
    content: '';
    position: absolute;
    inset: 0;
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6L9 17l-5-5'/%3E%3C/svg%3E") center / 11px no-repeat;
}

input[type="radio"] {
    border-radius: 50%;
}

input[type="radio"]:checked {
    border-color: var(--brand-a);
    background: var(--brand-a);
}

input[type="radio"]:checked::after {
    content: '';
    position: absolute;
    inset: 0;
    background: #fff;
    width: 7px;
    height: 7px;
    margin: auto;
    border-radius: 50%;
}

input[type="checkbox"]:disabled,
input[type="radio"]:disabled {
    opacity: .45;
    cursor: not-allowed;
}

/* 开关（checkbox 加 .switch 类） */
input[type="checkbox"].switch {
    width: 38px;
    height: 22px;
    border-radius: 999px;
    vertical-align: -6px;
}

input[type="checkbox"].switch:checked::after {
    content: none;
}

input[type="checkbox"].switch::before {
    content: '';
    position: absolute;
    top: 2px;
    left: 2px;
    width: 15px;
    height: 15px;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 1px 3px rgba(0, 0, 0, .3);
    transition: transform .18s ease;
}

input[type="checkbox"].switch:checked::before {
    transform: translateX(16px);
}

input[type="checkbox"].switch:disabled::before {
    box-shadow: none;
}

/* 复选/开关所在 label：横向对齐 */
label.check {
    display: flex;
    align-items: center;
    gap: 8px;
    color: var(--fg);
    font-weight: 500;
    cursor: pointer;
    user-select: none;
}

/* 卡片标题图标：品牌色，稍大 */
.card h2 .sr-ico {
    width: 16px;
    height: 16px;
    margin-right: 7px;
    vertical-align: -3px;
    color: var(--accent);
}

/* ── 自定义 Select 下拉（admin.js enhanceSelects 渲染） ── */
.sr-select {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 10px 13px;
    border-radius: var(--radius-s);
    border: 1px solid var(--rule);
    background: var(--panel-2);
    color: var(--fg);
    font: 14px/1.5 var(--font);
    text-align: left;
    cursor: pointer;
    transition: border-color .15s, box-shadow .15s;
}

.sr-select:hover {
    border-color: var(--muted);
}

.sr-select.open {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px rgba(99, 102, 241, .18);
}

.sr-select:disabled {
    opacity: .55;
    cursor: not-allowed;
}

.sr-select .sr-select-val {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.sr-select .sr-select-ph {
    color: var(--muted);
}

.sr-select .sr-select-chev {
    flex: 0 0 14px;
    width: 14px;
    height: 14px;
    color: var(--muted);
    transition: transform .18s;
}

.sr-select.open .sr-select-chev {
    transform: rotate(180deg);
}

/* 多选：触发器内标签 */
.sr-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    min-width: 0;
}

.sr-tag {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    max-width: 170px;
    padding: 0 7px;
    border-radius: 999px;
    background: rgba(99, 102, 241, .14);
    color: var(--accent);
    font: 600 11.5px/1.8 var(--font);
    white-space: nowrap;
}

html[data-theme="light"] .sr-tag {
    color: var(--brand-a);
}

.sr-tag i {
    font-style: normal;
    overflow: hidden;
    text-overflow: ellipsis;
}

.sr-tag .sr-tag-x {
    border: 0;
    background: transparent;
    color: inherit;
    opacity: .6;
    cursor: pointer;
    font: 700 12px/1.8 var(--font);
    padding: 0;
}

.sr-tag .sr-tag-x:hover {
    opacity: 1;
}

.sr-more {
    flex: 0 0 auto;
    font: 600 11.5px/1.8 var(--font-mono);
    color: var(--muted);
}

/* 下拉面板 */
.sr-select-pop {
    position: fixed;
    z-index: 150;
    /* 高于 .modal-mask(140)：弹窗内也能浮在遮罩之上 */
    min-width: 180px;
    max-height: 288px;
    overflow-y: auto;
    padding: 5px;
    border-radius: 10px;
    border: 1px solid var(--border);
    background: var(--glass);
    backdrop-filter: blur(22px) saturate(1.5);
    -webkit-backdrop-filter: blur(22px) saturate(1.5);
    box-shadow: var(--shadow);
    animation: popIn .14s ease;
}

.sr-opt {
    display: flex;
    align-items: center;
    gap: 9px;
    width: 100%;
    padding: 7.5px 10px;
    border: 0;
    border-radius: 7px;
    background: transparent;
    color: var(--fg);
    font: 13.5px/1.4 var(--font);
    text-align: left;
    cursor: pointer;
    transition: background .12s;
}

.sr-opt:hover {
    background: var(--hover);
}

.sr-opt.active {
    background: rgba(99, 102, 241, .13);
}

.sr-opt .sr-opt-txt {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.sr-opt.on {
    color: var(--accent);
    font-weight: 600;
}

html[data-theme="light"] .sr-opt.on {
    color: var(--brand-a);
}

.sr-opt.disabled {
    opacity: .45;
    cursor: not-allowed;
}

.sr-opt .sr-opt-check {
    flex: 0 0 15px;
    width: 15px;
    height: 15px;
    display: none;
    color: currentColor;
}

.sr-opt .sr-opt-check svg {
    width: 100%;
    height: 100%;
    display: block;
}

/* 单选选中项：只用背景色标记，不再显示对号 */
.sr-select-pop:not(.multi) .sr-opt.on {
    background: rgba(99, 102, 241, .13);
}

.sr-select-pop.multi .sr-opt .sr-opt-check {
    display: block;
    border: 1.5px solid var(--rule);
    border-radius: 4px;
    background: var(--panel-2);
    color: transparent;
}

.sr-select-pop.multi .sr-opt:hover .sr-opt-check {
    border-color: var(--accent);
}

.sr-select-pop.multi .sr-opt.on {
    color: var(--fg);
}

.sr-select-pop.multi .sr-opt.on .sr-opt-check {
    border-color: var(--brand-a);
    background: var(--brand-a);
    color: #fff;
}

.sr-pop-tools {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 5px 10px 7px;
    border-bottom: 1px solid var(--rule);
    margin-bottom: 4px;
}

.sr-pop-tools .link {
    font-size: 12px;
}

/* 行内提示 */
.msg-ok {
    color: var(--ok);
}

.msg-danger {
    color: var(--danger);
}

.msg-warn {
    color: var(--warn);
}

.hidden {
    display: none !important;
}

/* banner 横幅 */
.banner {
    position: relative;
    z-index: 1;
    max-width: 1180px;
    margin: 16px auto -8px;
    padding: 11px 16px;
    border-radius: var(--radius-s);
    font-size: 13.5px;
    border: 1px solid var(--rule);
    background: var(--panel);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
}

.banner-warn {
    border-color: rgba(255, 180, 84, .4);
    color: var(--warn-fg);
}

.banner-danger {
    border-color: rgba(255, 107, 129, .4);
    color: var(--danger-fg);
}

/* 告示 / 密钥明文 */
.alert {
    padding: 12px 15px;
    border-radius: var(--radius-s);
    border: 1px solid rgba(255, 180, 84, .4);
    background: rgba(255, 180, 84, .08);
    color: var(--warn-fg);
    font-size: 13.5px;
}

.secret {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 14px;
    border-radius: var(--radius-s);
    border: 1px dashed rgba(99, 102, 241, .5);
    background: rgba(99, 102, 241, .07);
    font-family: var(--font-mono);
    font-size: 13px;
    word-break: break-all;
}

/* 健康状态列表 */
.health {
    list-style: none;
    margin: 0;
    padding: 0;
}

.health li {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 13px 2px;
    border-bottom: 1px dashed var(--rule);
    font-size: 13.5px;
}

.health li:last-child {
    border-bottom: 0;
}

.health .k {
    color: var(--sub);
}

.health .v {
    margin-left: auto;
    font-family: var(--font-mono);
    font-size: 12.5px;
}

/* 列表后紧跟的按钮（如告警页「发送测试告警」）与列表拉开距离 */
.health+.btn {
    margin-top: 10px;
}

/* 底部吸附操作条 */
.sticky-actions {
    position: sticky;
    bottom: 0;
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 13px 18px;
    margin-top: 4px;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    background: var(--glass);
    backdrop-filter: blur(18px) saturate(1.4);
    -webkit-backdrop-filter: blur(18px) saturate(1.4);
    box-shadow: var(--shadow-s);
}

.sticky-actions .msg {
    margin-left: auto;
    font-size: 13px;
}

/* ── 登录页 ── */
.login-card {
    width: min(400px, 100%);
    border-radius: 16px;
    border: 1px solid var(--border);
    background: var(--glass);
    backdrop-filter: blur(26px) saturate(1.5);
    -webkit-backdrop-filter: blur(26px) saturate(1.5);
    box-shadow: var(--shadow);
    padding: 38px 34px;
}

/* 登录卡品牌徽标：标题上方的圆角徽章（与公开页 brand-ico 同比例圆角） */
.login-card .login-logo {
    display: block;
    width: 44px;
    height: 44px;
    margin: 0 0 14px;
    border-radius: 23.4%;
}

.login-card h1 {
    margin: 0 0 6px;
    font-size: 26px;
    font-weight: 700;
    color: var(--fg);
}

.login-card .sub {
    color: var(--muted);
    font-size: 13.5px;
    margin: 0 0 24px;
}

.login-card .sub.small {
    margin: 18px 0 0;
    font-size: 12px;
}

.login-card input {
    margin-bottom: 14px;
}

.login-card .btn {
    width: 100%;
}

/* 登录卡片内的错误提示：与下方表单拉开距离 */
.login-card .alert {
    margin-bottom: 18px;
}

/* ── 两步验证（TOTP） ── */
/* 设置页绑定信息区块 */
.totp-bind {
    margin-top: 16px;
    padding: 16px;
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    background: var(--panel-2);
}

.totp-bind .sub {
    margin: 0 0 12px;
}

.totp-ways {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    margin-bottom: 16px;
}

.totp-way {
    flex: 1 1 180px;
    min-width: 170px;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
    padding: 12px;
    border: 1px solid var(--rule);
    border-radius: var(--radius-s);
    background: var(--panel-solid);
}

.totp-way-t {
    font-size: 12.5px;
    font-weight: 600;
    color: var(--fg);
}

.totp-code {
    display: block;
    box-sizing: border-box;
    width: 100%;
    padding: 7px 9px;
    font-family: var(--font-mono);
    font-size: 11.5px;
    line-height: 1.5;
    color: var(--ink);
    background: var(--panel-2);
    border: 1px solid var(--rule);
    border-radius: var(--radius-s);
    word-break: break-all;
    user-select: text;
}

/* 二维码白底衬底，保证暗色主题下可正常扫描 */
#totp-qr img,
#totp-qr canvas {
    display: block;
    background: #ffffff;
    border-radius: 6px;
    padding: 6px;
}

/* 挑战页：放弃本次登录 */
.totp-alt {
    margin-top: 12px;
}

/* 关闭两步验证弹窗：动态码输入 */
.totp-modal-field {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-top: 12px;
    font-size: 13px;
    color: var(--sub);
}

/* 登录页浮动主题切换 */
.theme-toggle-float {
    position: fixed;
    top: 18px;
    right: 18px;
    z-index: 20;
}

/* ── Toast 通知 ── */
.toasts {
    position: fixed;
    top: 74px;
    right: 22px;
    z-index: 120;
    display: flex;
    flex-direction: column;
    gap: 10px;
    width: min(360px, calc(100vw - 44px));
    pointer-events: none;
}

.toast {
    display: flex;
    align-items: flex-start;
    gap: 11px;
    padding: 13px 15px;
    border-radius: 12px;
    border: 1px solid var(--border);
    background: var(--glass);
    backdrop-filter: blur(22px) saturate(1.5);
    -webkit-backdrop-filter: blur(22px) saturate(1.5);
    box-shadow: var(--shadow);
    font-size: 13.5px;
    pointer-events: auto;
    animation: toastIn .28s cubic-bezier(.21, 1.02, .55, 1.01);
    position: relative;
    overflow: hidden;
}

@keyframes toastIn {
    from {
        opacity: 0;
        transform: translateX(30px) scale(.96);
    }

    to {
        opacity: 1;
        transform: none;
    }
}

.toast.out {
    opacity: 0;
    transform: translateX(24px);
    transition: opacity .25s, transform .25s;
}

.toast-ico {
    flex: 0 0 20px;
    width: 20px;
    height: 20px;
    margin-top: 1px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: var(--tone, var(--accent));
    color: #fff;
    font-size: 11px;
    font-weight: 700;
}

.toast-body {
    flex: 1;
    min-width: 0;
}

.toast-title {
    display: block;
    font-weight: 700;
    font-size: 13px;
    margin-bottom: 3px;
}

.toast-text {
    display: block;
    color: var(--sub);
    font-size: 12.5px;
    word-break: break-word;
}

.toast.ok {
    --tone: var(--ok);
}

.toast.err {
    --tone: var(--danger);
}

.toast.warn {
    --tone: var(--warn);
}

.toast.info {
    --tone: var(--accent);
}

.toast .toast-x {
    flex: 0 0 auto;
    border: 0;
    background: transparent;
    color: var(--muted);
    font-size: 15px;
    cursor: pointer;
    padding: 0 2px;
    line-height: 1;
}

/* ── Modal 弹窗 ── */
.modal-mask {
    position: fixed;
    inset: 0;
    z-index: 140;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    background: rgba(8, 10, 24, .45);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    animation: fadeIn .18s ease;
}

@keyframes fadeIn {
    from {
        opacity: 0;
    }

    to {
        opacity: 1;
    }
}

.modal {
    width: min(440px, 100%);
    border-radius: 14px;
    border: 1px solid var(--border);
    background: var(--glass);
    backdrop-filter: blur(28px) saturate(1.6);
    -webkit-backdrop-filter: blur(28px) saturate(1.6);
    box-shadow: var(--shadow);
    animation: modalIn .22s cubic-bezier(.21, 1.02, .55, 1.01);
    overflow: hidden;
}

.modal.wide {
    width: min(560px, 100%);
}

@keyframes modalIn {
    from {
        opacity: 0;
        transform: translateY(14px) scale(.96);
    }

    to {
        opacity: 1;
        transform: none;
    }
}

.modal-head {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 20px 24px 0;
}

.modal-ico {
    flex: 0 0 40px;
    width: 40px;
    height: 40px;
    display: grid;
    place-items: center;
    border-radius: 10px;
    font-size: 18px;
    color: #fff;
    background: var(--brand-a);
}

.modal-ico.danger {
    background: var(--danger);
}

.modal-ico svg {
    width: 20px;
    height: 20px;
}

.modal-title {
    font-size: 16.5px;
    font-weight: 700;
}

.modal-body {
    padding: 14px 24px 4px;
    color: var(--sub);
    font-size: 13.5px;
}

.modal-body .secret {
    margin: 10px 0;
}

/* 操作详情弹层：键值行列表 */
.detail-list {
    display: flex;
    flex-direction: column;
}

.detail-row {
    display: flex;
    gap: 14px;
    padding: 8px 0;
    border-bottom: 1px dashed var(--rule);
    font-size: 13px;
    line-height: 1.5;
}

.detail-row:last-child {
    border-bottom: 0;
}

.detail-k {
    flex: 0 0 64px;
    color: var(--muted);
}

.detail-v {
    flex: 1;
    min-width: 0;
    word-break: break-all;
    white-space: pre-wrap;
    color: var(--fg);
}

.modal-foot {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
    padding: 18px 24px 22px;
}

/* ── 响应式（<960px：侧栏抽屉） ── */
@media (max-width: 960px) {
    .sidebar {
        position: fixed;
        left: 0;
        top: 0;
        transform: translateX(-104%);
        transition: transform .24s ease;
        box-shadow: none;
    }

    .sidebar.open {
        transform: none;
        box-shadow: var(--shadow);
    }

    html[data-side="mini"] .sidebar {
        flex-basis: 236px;
        width: 236px;
        padding: 18px 14px 16px;
    }

    html[data-side="mini"] .logo-col {
        display: flex;
    }

    html[data-side="mini"] .side-link .txt,
    html[data-side="mini"] .side-foot .txt {
        display: block;
    }

    html[data-side="mini"] .side-link {
        justify-content: flex-start;
        padding: 10px 12px;
    }

    /* 窄屏抽屉：分组标题还原为文字 */
    html[data-side="mini"] .side-group-title {
        height: auto;
        margin: 0;
        padding: 12px 12px 4px;
        font-size: 11.5px;
        background: none;
    }

    .only-desktop {
        display: none !important;
    }

    .only-mobile {
        display: inline-flex !important;
    }

    .topbar {
        padding: 0 16px;
    }

    .page {
        padding: 20px 16px 56px;
    }

    .grid-2,
    .form-grid {
        grid-template-columns: 1fr;
    }

    /* 窄屏单列布局不存在同行对齐，去掉开关行的底部补偿 */
    .form-grid>label.check {
        padding-bottom: 0;
    }

    /* 行式设置项窄屏改为上下堆叠，控件区换行并让输入框占满 */
    .set-row {
        flex-direction: column;
        align-items: stretch;
        gap: 10px;
    }

    .set-ctl {
        flex-wrap: wrap;
    }

    .set-ctl input[type="text"],
    .set-ctl input[type="number"],
    .set-ctl .sr-select {
        flex: 1;
        width: auto;
        min-width: 0;
    }

    .kpi-grid {
        grid-template-columns: repeat(2, 1fr);
    }

    .user-btn .who-name,
    .user-btn .chev {
        display: none;
    }

    .toasts {
        top: 70px;
        right: 14px;
    }

    .pop-panel {
        width: min(320px, calc(100vw - 28px));
    }

    .sr-select-pop {
        max-width: calc(100vw - 28px);
    }
}

@media (max-width: 560px) {
    .kpi-grid {
        grid-template-columns: 1fr 1fr;
        gap: 10px;
    }

    .kpi strong {
        font-size: 20px;
    }

    .page-head h1 {
        font-size: 21px;
    }

    .topbar-title {
        font-size: 15.5px;
    }
}

/* 滚动条 */
::-webkit-scrollbar {
    width: 9px;
    height: 9px;
}

::-webkit-scrollbar-thumb {
    background: var(--rule);
    border-radius: 999px;
    border: 2px solid transparent;
    background-clip: content-box;
}

::-webkit-scrollbar-thumb:hover {
    background: var(--muted);
    background-clip: content-box;
}

/* ───────────── 接口文档页（app/Views/admin/endpoint_doc.php） ───────────── */
.doc-head .doc-head-main {
    min-width: 0;
}

.doc-head .doc-back {
    margin-left: auto;
}

.doc-title {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.method-badge {
    display: inline-flex;
    align-items: center;
    padding: 2.5px 9px;
    border-radius: 7px;
    background: var(--brand-a);
    color: #fff;
    font: 700 11.5px/1.5 var(--font-mono);
    letter-spacing: .5px;
}

.doc-path {
    padding: 2.5px 9px;
    border-radius: 7px;
    border: 1px solid var(--rule);
    background: var(--panel-2);
    color: var(--sub);
    font-size: 12.5px;
    user-select: all;
}

.doc-tags {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
    margin: 9px 0 2px;
}

.doc-head .sub {
    display: block;
    margin: 7px 0 0;
}

/* 双栏：左侧文档区块 + 右侧测试面板（窄屏单列） */
.doc-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 400px;
    gap: 22px;
    align-items: start;
}

.doc-main {
    display: grid;
    /* 显式单列且允许收缩：避免 pre 长行（white-space:pre）把隐式 auto 轨道
       撑到超出栅格列，导致表格伸进右侧测试面板下方 */
    grid-template-columns: minmax(0, 1fr);
    gap: 18px;
    min-width: 0;
}

.doc-main .card {
    margin: 0;
}

.doc-main .card .sub {
    margin: 0;
    line-height: 1.75;
}

.doc-td-left {
    text-align: left !important;
}

.doc-code {
    margin: 0 0 12px;
    padding: 14px 16px;
    border-radius: 10px;
    border: 1px solid var(--rule);
    background: var(--panel-2);
    font-size: 12.5px;
    line-height: 1.7;
    overflow-x: auto;
    color: var(--sub);
    white-space: pre;
    user-select: all;
}

.doc-fields {
    margin-top: 2px;
}

.doc-none {
    padding: 6px 0 2px;
}

.doc-notes {
    margin: 0;
    padding: 0;
    list-style: none;
    display: grid;
    gap: 9px;
}

.doc-notes li {
    position: relative;
    padding-left: 20px;
    color: var(--sub);
    font-size: 13px;
    line-height: 1.7;
}

.doc-notes li::before {
    content: '';
    position: absolute;
    left: 4px;
    top: 9px;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--accent);
    opacity: .75;
}

/* 请求测试面板 */
.doc-side {
    position: sticky;
    top: 86px;
}

.doc-test .sub {
    margin: 0 0 14px;
}

.doc-test-hint {
    padding: 8px 11px;
    border-radius: 9px;
    border: 1px dashed var(--warn);
    color: var(--warn);
    font-size: 12.5px;
    line-height: 1.65;
    opacity: .92;
}

.doc-field {
    margin-bottom: 14px;
}

.doc-field-label {
    display: block;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--sub);
    margin-bottom: 6px;
}

.doc-key-row {
    display: flex;
    gap: 8px;
    align-items: center;
}

.doc-key-row input {
    flex: 1;
    min-width: 0;
    font-family: var(--font-mono);
    font-size: 12.5px;
}

.doc-params {
    display: grid;
    gap: 8px;
    margin-bottom: 6px;
}

.doc-param-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr) auto;
    gap: 8px;
    align-items: center;
}

.doc-param-row input {
    width: 100%;
    font-size: 12.5px;
}

.doc-param-del {
    padding: 3.5px 9px;
}

.doc-params-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin-bottom: 6px;
}

.doc-params-head .doc-field-label {
    margin-bottom: 0;
}

.doc-params-actions {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.doc-send {
    width: 100%;
    margin: 4px 0 16px;
}

.doc-test .field-hint {
    margin: 6px 0 0;
}

.doc-result {
    min-height: 46px;
}

.doc-result-hint {
    margin: 0;
}

.doc-result-meta {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
    margin-bottom: 9px;
}

.doc-result-body {
    margin: 0;
    padding: 13px 15px;
    border-radius: 10px;
    border: 1px solid var(--rule);
    background: var(--panel-2);
    font-size: 12px;
    line-height: 1.7;
    overflow-x: auto;
    max-height: 420px;
    white-space: pre;
    color: var(--sub);
}

@media (max-width: 1180px) {
    .doc-grid {
        grid-template-columns: 1fr;
    }

    .doc-side {
        position: static;
    }
}