/* ============================================================
   PaiwaVPP 主题层 · 基于 Bootstrap 5.3 · 浅色科技蓝
   加载顺序：bootstrap.min.css → site.css
   作用：① 将科技蓝映射到 Bootstrap 变量  ② 组件级变量覆盖
        ③ 兼容别名  ④ 保留 Bootstrap 没有的自定义组件
   ============================================================ */

:root {
    /* ── 品牌色（供自定义组件使用）── */
    --primary: #1664ff;
    --primary-hover: #4080ff;
    --primary-active: #0e52e6;
    --primary-bg: #eef4ff;
    --primary-bg-hover: #e0ebff;
    --primary-border: #bedaff;
    --on-primary: #ffffff;

    --primary-shadow: rgba(22, 100, 255, .25);
    --primary-shadow-hover: rgba(22, 100, 255, .35);
    --primary-focus: rgba(22, 100, 255, .12);
    --primary-glow: rgba(22, 100, 255, .3);

    /* ── 中性色 ── */
    --bg: #f0f2f5;
    --surface: #ffffff;
    --surface-2: #f7f8fb;
    --surface-3: #f0f1f5;
    --border: #e2e5eb;
    --border-2: #d5d9e1;
    --text: #1d2129;
    --text-2: #4e5969;
    --text-3: #6a7688;
    --text-4: #8a96a4;

    /* ── 功能色 ── */
    --success: #00b42a;
    --success-bg: #e8ffea;
    --success-border: #b7f0c0;
    --success-shadow: rgba(0, 180, 42, .12);
    --warning: #ff7d00;
    --warning-hover: #d96a00;
    --warning-bg: #fff7e8;
    --warning-border: #ffe4ba;
    --danger: #f53f3f;
    --danger-hover: #cb2634;
    --danger-bg: #ffece8;
    --danger-border: #fdcdc5;
    --danger-shadow: rgba(245, 63, 63, .12);
    --purple: #722ed1;
    --purple-bg: #f5e8ff;
    --purple-border: #e3c6fb;
    --cyan: #0fa3a3;
    --cyan-bg: #e8fffb;
    --cyan-border: #b7f5ec;

    --overlay-bg: rgba(29, 33, 41, .45);

    /* ── 圆角 ── */
    --r-sm: 4px;
    --r: 6px;
    --r-lg: 8px;
    --r-xl: 12px;

    /* 阴影 */
    --shadow-sm: 0 1px 2px rgba(29, 33, 41, .05);
    --shadow: 0 1px 3px rgba(29, 33, 41, .06), 0 1px 2px rgba(29, 33, 41, .04);
    --shadow-md: 0 4px 14px rgba(29, 33, 41, .08);
    --shadow-lg: 0 12px 40px rgba(29, 33, 41, .16);

    /* 尺寸 */
    --header-h: 56px;
    --sidebar-w: 224px;
    --sidebar-collapsed-w: 64px;

    /* ============================================================
       Bootstrap 5.3 全局变量映射（科技蓝）
       ============================================================ */
    --bs-primary: #1664ff;
    --bs-primary-rgb: 22, 100, 255;
    --bs-secondary: #8a96a4;
    --bs-secondary-rgb: 138, 150, 164;
    --bs-success: #00b42a;
    --bs-success-rgb: 0, 180, 42;
    --bs-info: #0fa3a3;
    --bs-info-rgb: 15, 163, 163;
    --bs-warning: #ff7d00;
    --bs-warning-rgb: 255, 125, 0;
    --bs-danger: #f53f3f;
    --bs-danger-rgb: 245, 63, 63;
    --bs-body-font-family: "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Helvetica, Arial, sans-serif;
    --bs-body-font-size: 0.875rem;
    --bs-body-color: #1d2129;
    --bs-body-bg: #f0f2f5;
    --bs-border-color: #e2e5eb;
    --bs-border-radius: 0.375rem;
    --bs-link-color: #1664ff;
    --bs-link-hover-color: #4080ff;
    --bs-code-color: #722ed1;
}

/* ── Bootstrap 组件级变量覆盖（编译期常量无法通过 --bs-primary 生效，需逐个覆盖）── */
.btn {
    --bs-btn-font-size: 0.8125rem;
    --bs-btn-font-weight: 500;
    --bs-btn-border-radius: var(--r);
    --bs-btn-padding-y: 0.375rem;
    --bs-btn-padding-x: 0.9375rem;
    display: inline-flex; align-items: center; justify-content: center; gap: 6px;
}
.btn .icon { font-size: 15px; }
.btn-primary {
    --bs-btn-bg: var(--primary);
    --bs-btn-border-color: var(--primary);
    --bs-btn-hover-bg: var(--primary-hover);
    --bs-btn-hover-border-color: var(--primary-hover);
    --bs-btn-active-bg: var(--primary-active);
    --bs-btn-active-border-color: var(--primary-active);
    --bs-btn-disabled-bg: var(--primary);
    --bs-btn-disabled-border-color: var(--primary);
    --bs-btn-box-shadow: 0 2px 5px var(--primary-shadow);
    --bs-btn-hover-box-shadow: 0 2px 8px var(--primary-shadow-hover);
}
.btn-outline-primary {
    --bs-btn-color: var(--primary);
    --bs-btn-border-color: var(--primary-border);
    --bs-btn-hover-bg: var(--primary);
    --bs-btn-hover-border-color: var(--primary);
    --bs-btn-active-bg: var(--primary-active);
    --bs-btn-active-border-color: var(--primary-active);
    --bs-btn-disabled-color: var(--primary);
    --bs-btn-disabled-border-color: var(--primary-border);
}
.btn-danger {
    --bs-btn-bg: var(--danger);
    --bs-btn-border-color: var(--danger);
    --bs-btn-hover-bg: var(--danger-hover);
    --bs-btn-hover-border-color: var(--danger-hover);
    --bs-btn-active-bg: var(--danger-hover);
    --bs-btn-disabled-bg: var(--danger);
    --bs-btn-disabled-border-color: var(--danger);
}
.btn-outline-danger {
    --bs-btn-color: var(--danger);
    --bs-btn-border-color: var(--danger-border);
    --bs-btn-hover-bg: var(--danger);
    --bs-btn-hover-border-color: var(--danger);
    --bs-btn-active-bg: var(--danger-hover);
    --bs-btn-disabled-color: var(--danger);
    --bs-btn-disabled-border-color: var(--danger-border);
}
.btn-secondary {
    --bs-btn-bg: var(--surface);
    --bs-btn-border-color: var(--border-2);
    --bs-btn-color: var(--text-2);
    --bs-btn-hover-bg: var(--surface-3);
    --bs-btn-hover-border-color: var(--border-2);
    --bs-btn-hover-color: var(--text);
    --bs-btn-active-bg: var(--surface-3);
    --bs-btn-active-color: var(--text);
}
.btn-sm { --bs-btn-padding-y: .25rem; --bs-btn-padding-x: .75rem; --bs-btn-font-size: .8125rem; border-radius: var(--r); }
.btn-lg { --bs-btn-padding-y: .5rem; --bs-btn-padding-x: 1.25rem; --bs-btn-font-size: .9375rem; }

/* 链接 / 文本 / 背景 主色 */
.text-primary { color: var(--primary) !important; }
.bg-primary { background-color: var(--primary) !important; }
.text-bg-primary { background-color: var(--primary-bg) !important; color: var(--primary) !important; }
.text-bg-success { background-color: var(--success-bg) !important; color: var(--success) !important; }
.text-bg-danger { background-color: var(--danger-bg) !important; color: var(--danger) !important; }
.text-bg-warning { background-color: var(--warning-bg) !important; color: var(--warning) !important; }
.text-bg-info { background-color: var(--cyan-bg) !important; color: var(--cyan) !important; }
.text-bg-secondary { background-color: var(--surface-3) !important; color: var(--text-3) !important; }
a { color: var(--primary); text-decoration: none; transition: color .15s; }
a:hover { color: var(--primary-hover); }

/* 表单控件聚焦态 */
.form-control {
    --bs-border-color: var(--border-2);
    font-size: .8125rem; color: var(--text);
    border-radius: var(--r);
}
.form-control:focus, .form-select:focus {
    border-color: var(--primary);
    box-shadow: 0 0 0 3px var(--primary-focus);
}
.form-control::placeholder { color: var(--text-4); }
.form-control[readonly] { background: var(--surface-2); color: var(--text-3); }
.form-select { --bs-border-color: var(--border-2); font-size: .8125rem; color: var(--text); border-radius: var(--r); }
.form-label { font-size: .8125rem; color: var(--text-2); font-weight: 500; margin-bottom: .3125rem; }
.form-check-input:checked { background-color: var(--primary); border-color: var(--primary); }
.form-check-input:focus { border-color: var(--primary); box-shadow: 0 0 0 3px var(--primary-focus); }
input[type="checkbox"] { accent-color: var(--primary); }

/* 表格 */
.table {
    --bs-table-color: var(--text);
    --bs-table-bg: var(--surface);
    --bs-table-border-color: var(--border);
    --bs-table-hover-bg: #f7f8fb;
    --bs-table-hover-color: var(--text);
    font-size: .8125rem; margin-bottom: 0;
}
.table > :not(caption) > * > * { background-color: var(--surface); }
.table > thead th {
    background: #f5f6f8; color: var(--text);
    font-weight: 600; font-size: .8125rem; white-space: nowrap;
    padding: .85rem 1rem;
    border-bottom: 1px solid var(--border);
}
.table > tbody td {
    white-space: nowrap; vertical-align: middle;
    padding: .9rem 1rem;
    color: var(--text);
    border-bottom: 1px solid var(--border);
}
.table-hover > tbody > tr:hover > * { --bs-table-bg: #f7f8fb; background-color: #f7f8fb; }

/* 表格内文字链接式操作（替代拥挤的边框按钮） */
.table-link { font-size: .8125rem; color: var(--primary); text-decoration: none; margin-right: 14px; white-space: nowrap; cursor: pointer; background: transparent; border: 0; padding: 0; line-height: inherit; }
.table-link:last-child { margin-right: 0; }
.table-link:hover { color: var(--primary-hover); }
.table-link.danger { color: var(--danger); }
.table-link.danger:hover { color: var(--danger-hover); }

/* ============================================================
   标准列表页白卡（.page-card：标题 → 筛选 → 工具栏 → 表格 → 分页）
   对标 vue-element-admin / Arco Pro：整页仅一张卡
   ============================================================ */
.page-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-sm);
    display: flex; flex-direction: column;
}
.page-card-head { padding: 20px 24px 0; }
.page-card-head .btn { flex-shrink: 0; white-space: nowrap; }
.page-card-title { font-size: 1.125rem; font-weight: 600; color: var(--text); margin: 0; line-height: 1.4; }
.page-card-desc { font-size: .8125rem; color: var(--text-3); margin: 4px 0 0; }
.page-card-filters { padding: 18px 24px 2px; }
.page-card-filters .form-label { margin-bottom: 0; color: var(--text-2); white-space: nowrap; }
.page-card-filters .form-control,
.page-card-filters .form-select {
    background-color: var(--surface-2);
    border-color: transparent;
    font-weight: 400;
}
.page-card-filters .form-control:focus,
.page-card-filters .form-select:focus {
    background-color: var(--surface);
    border-color: var(--primary);
    box-shadow: 0 0 0 3px var(--primary-focus);
}
.page-card-toolbar {
    display: flex; align-items: center; justify-content: space-between; gap: 10px;
    padding: 16px 24px;
}
.page-card .table-responsive { padding: 0 12px; flex: 1 0 auto; display: flex; flex-direction: column; }
.page-card .table-responsive > table { flex-shrink: 0; }
.page-card .table-responsive .empty-state { margin: auto; }
.page-card .table > :not(:last-child) > :last-child > * { border-bottom-color: var(--border); }
.page-card-pagination {
    display: flex; justify-content: flex-end; align-items: center;
    padding: 14px 24px 18px;
}
.page-card-tabs { padding: 16px 24px 0; }
.page-card-tabs .nav-tabs { margin-bottom: 0; }
.page-card-body { padding: 18px 24px 22px; flex: 1 0 auto; display: flex; flex-direction: column; }
.page-card-body .empty-state { margin: auto; }

/* page-card 内的品类卡片网格 */
.page-card .cat-list { padding: 6px 12px 12px; }

/* page-card 内的卡片网格 */
.page-card .cards-grid { padding: 4px 0 8px; }

/* 卡片 */
.card {
    --bs-card-border-color: var(--border);
    --bs-card-border-radius: var(--r-lg);
    --bs-card-bg: var(--surface);
    --bs-card-cap-bg: var(--surface-2);
    box-shadow: var(--shadow-sm); border: 1px solid var(--border);
}
.card-header { font-weight: 600; border-bottom: 1px solid var(--border); }

/* 徽章 */
.badge { --bs-badge-font-size: .75rem; --bs-badge-font-weight: 500; --bs-badge-padding-y: .21em; --bs-badge-padding-x: .6em; border-radius: 10px; }
.badge-blue { background: var(--primary-bg); color: var(--primary); }
.badge-green { background: var(--success-bg); color: var(--success); }
.badge-red { background: var(--danger-bg); color: var(--danger); }
.badge-orange { background: var(--warning-bg); color: var(--warning); }
.badge-purple { background: var(--purple-bg); color: var(--purple); }
.badge-cyan { background: var(--cyan-bg); color: var(--cyan); }
.badge-gray { background: var(--surface-3); color: var(--text-3); }
.badge-yellow { background: var(--warning-bg); color: var(--warning-hover); }

/* 标签页（Bootstrap nav-tabs 科技蓝化） */
.nav-tabs {
    --bs-nav-tabs-border-color: var(--border);
    --bs-nav-tabs-link-active-color: var(--primary);
    --bs-nav-tabs-link-active-border-color: var(--border) var(--border) var(--surface);
    gap: 4px; margin-bottom: 16px;
}
.nav-tabs .nav-link {
    color: var(--text-3); font-size: .875rem; border: none;
    border-bottom: 2px solid transparent; border-radius: 0;
    padding: .5rem .75rem; display: inline-flex; align-items: center; gap: 5px;
}
.nav-tabs .nav-link:hover { color: var(--text); border-color: transparent; }
.nav-tabs .nav-link.active {
    color: var(--primary); font-weight: 600; background: transparent;
    border-bottom: 2px solid var(--primary);
}

/* 面包屑（卡外灰色小字面屑，无背景） */
.app-breadcrumb {
    --bs-breadcrumb-font-size: .8125rem;
    --bs-breadcrumb-margin-bottom: 0;
    --bs-breadcrumb-divider-color: var(--text-4);
    --bs-breadcrumb-item-padding-x: .4rem;
    padding: 0;
    margin-bottom: 14px;
    background: transparent;
    border: none;
    border-radius: 0;
    box-shadow: none;
}
.app-breadcrumb a { color: var(--text-3); }
.app-breadcrumb a:hover { color: var(--primary); }
.app-breadcrumb .breadcrumb-item.active { color: var(--text-2); }

/* 模态框（Bootstrap modal 科技蓝化） */
.modal-content { --bs-modal-border-radius: var(--r-xl); --bs-modal-border-color: transparent; box-shadow: var(--shadow-lg); }
.modal-header { border-bottom: 1px solid var(--border); }
.modal-footer { border-top: 1px solid var(--border); }
.dropdown-item.active, .dropdown-item:active { background-color: var(--primary); }
.page-link { color: var(--primary); }
.page-item.active .page-link { background-color: var(--primary); border-color: var(--primary); }
.progress-bar { background-color: var(--primary); }

/* ── 兼容别名（供 JS 生成markup / 未迁移视图使用）── */
.form-input { display: block; width: auto; min-height: 32px; padding: .25rem .6875rem; font-size: .8125rem; color: var(--text); background: var(--surface); border: 1px solid var(--border-2); border-radius: var(--r); transition: all .15s; }
.form-input:focus { border-color: var(--primary); box-shadow: 0 0 0 3px var(--primary-focus); outline: none; }
textarea.form-input { height: auto; min-height: 64px; resize: vertical; line-height: 1.5; padding: .4375rem .6875rem; }
.btn-xs { --bs-btn-padding-y: .125rem; --bs-btn-padding-x: .5625rem; --bs-btn-font-size: .75rem; border-radius: var(--r-sm); }
.btn-cancel { --bs-btn-bg: var(--surface); --bs-btn-border-color: var(--border-2); --bs-btn-color: var(--text-2); --bs-btn-hover-bg: var(--surface-3); --bs-btn-hover-color: var(--text); }
.btn-outline-blue { --bs-btn-color: var(--primary); --bs-btn-border-color: var(--primary-border); --bs-btn-hover-bg: var(--primary); --bs-btn-hover-border-color: var(--primary); --bs-btn-active-bg: var(--primary-active); }
.btn-outline-red { --bs-btn-color: var(--danger); --bs-btn-border-color: var(--danger-border); --bs-btn-hover-bg: var(--danger); --bs-btn-hover-border-color: var(--danger); --bs-btn-active-bg: var(--danger-hover); }
.table-wrap { overflow-x: auto; }
.cell-strong { font-weight: 600; color: var(--text); }

/* ── 基础排版 / 滚动条 ── */
* { box-sizing: border-box; }
html, body { height: 100%; }
body {
    font-family: var(--bs-body-font-family);
    background: var(--bg); color: var(--text);
    font-size: .875rem; line-height: 1.5715;
    -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
}
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 4px; border: 2px solid transparent; background-clip: content-box; }
::-webkit-scrollbar-thumb:hover { background: var(--border-2); border: 2px solid transparent; background-clip: content-box; }

/* ── SVG 图标 ── */
.icon { width: 1em; height: 1em; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; flex-shrink: 0; vertical-align: -0.125em; }
.icon-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

.text-muted { color: var(--text-3) !important; font-size: .78125rem; }
.text-danger, .text-red { color: var(--danger) !important; }
.text-ellipsis { max-width: 200px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ============================================================
   框架布局
   ============================================================ */
.app-body { display: flex; min-height: calc(100vh - var(--header-h)); }

.app-navbar {
    height: var(--header-h); background: var(--surface);
    border-bottom: 1px solid var(--border); box-shadow: var(--shadow-sm);
    padding: 0 20px; display: flex; align-items: center;
    position: sticky; top: 0; z-index: 1030; gap: 12px;
}
.app-brand { display: flex; align-items: center; gap: 10px; font-size: 15px; font-weight: 700; color: var(--text); margin-right: 8px; white-space: nowrap; }
.app-brand:hover { color: var(--text); }
.brand-logo { width: 32px; height: 32px; border-radius: 8px; background: linear-gradient(135deg, var(--primary) 0%, var(--primary-hover) 100%); color: var(--on-primary); display: flex; align-items: center; justify-content: center; font-size: 18px; box-shadow: 0 2px 8px var(--primary-shadow); }
.brand-sub { font-size: 11px; font-weight: 500; color: var(--text-3); letter-spacing: .3px; }
.sidebar-toggle { width: 34px; height: 34px; border: none; background: transparent; border-radius: var(--r); color: var(--text-2); cursor: pointer; display: flex; align-items: center; justify-content: center; font-size: 18px; transition: all .15s; }
.sidebar-toggle:hover { background: var(--surface-3); color: var(--text); }
.app-user { margin-left: auto; display: flex; align-items: center; gap: 10px; }
.app-username { font-size: 13px; color: var(--text-2); max-width: 140px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.app-avatar { width: 32px; height: 32px; border-radius: 50%; background: var(--primary-bg); color: var(--primary); display: flex; align-items: center; justify-content: center; font-size: 13px; font-weight: 600; }
.btn-logout { background: transparent; border: 1px solid var(--border); color: var(--text-3); font-size: 12px; padding: 5px 12px; border-radius: var(--r); cursor: pointer; display: inline-flex; align-items: center; gap: 5px; transition: all .15s; }
.btn-logout:hover { border-color: var(--danger); color: var(--danger); background: var(--danger-bg); }

/* ── 侧边栏 ── */
.sidebar { width: var(--sidebar-w); flex-shrink: 0; background: var(--surface); border-right: 1px solid var(--border); padding: 12px 0; overflow-y: auto; overflow-x: hidden; transition: width .2s ease; position: sticky; top: var(--header-h); height: calc(100vh - var(--header-h)); }
.sidebar-group { margin-bottom: 4px; }
.sidebar-group-title { padding: 14px 20px 6px; font-size: 11px; font-weight: 600; color: var(--text-3); letter-spacing: .8px; white-space: nowrap; }
.sidebar-menu { list-style: none; margin: 0; padding: 0; }
.sidebar-item { margin: 2px 10px; border-radius: var(--r-lg); }
.sidebar-link { display: flex; align-items: center; gap: 10px; height: 38px; padding: 0 12px; font-size: 14px; color: var(--text-2); border-radius: var(--r-lg); transition: all .15s; white-space: nowrap; }
.sidebar-link:hover { background: var(--surface-2); color: var(--text); }
.sidebar-item.active .sidebar-link { background: var(--surface-3); color: var(--primary); font-weight: 600; }
.sidebar-icon { font-size: 17px; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.sidebar-item.active .sidebar-icon { color: var(--primary); }
body.sidebar-collapsed .sidebar { width: var(--sidebar-collapsed-w); }
body.sidebar-collapsed .sidebar-group-title, body.sidebar-collapsed .sidebar-text { display: none; }
body.sidebar-collapsed .sidebar-link { justify-content: center; padding: 0; }
body.sidebar-collapsed .sidebar-item { margin: 2px 8px; }

.main-content { flex: 1; min-width: 0; padding: 18px 24px 28px; display: flex; flex-direction: column; }
/* 主卡片最低高度与视口底部齐平：内容少时撑满剩余空间，内容多时自然增长 */
.main-content > .page-card,
.main-content > .station-layout,
.main-content > .sm-layout { flex: 1 0 auto; }

/* ============================================================
   页面骨架：页头 / 筛选 / 卡片 / 空状态
   ============================================================ */
.page-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; padding: 16px 20px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); box-shadow: var(--shadow-sm); }
.page-head { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); box-shadow: var(--shadow-sm); padding: 16px 20px; }
.page-header + .filter-bar { border-top-left-radius: 0; border-top-right-radius: 0; margin-top: -1px; margin-bottom: 16px; }
.page-header:has(+ .filter-bar) { border-bottom-left-radius: 0; border-bottom-right-radius: 0; box-shadow: none; border-bottom: none; }
.page-title { font-size: 20px; font-weight: 600; color: var(--text); display: flex; align-items: center; gap: 8px; line-height: 1.4; margin: 0; }
.page-desc { font-size: 13px; color: var(--text-3); margin: 4px 0 0; }
.back-link { display: inline-flex; align-items: center; gap: 4px; font-size: 13px; color: var(--text-3); margin-bottom: 6px; }
.back-link:hover { color: var(--primary); }
.back-link .icon { font-size: 15px; }

.grid { display: grid; gap: 16px; }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }

.filter-bar { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); box-shadow: var(--shadow-sm); padding: 12px 16px; margin-bottom: 16px; }
.page-header + .filter-bar { border-top-left-radius: 0; border-top-right-radius: 0; border-top: 1px dashed var(--border); box-shadow: none; margin-top: -1px; }
.search-box { position: relative; display: inline-flex; align-items: center; }
.search-box .icon { position: absolute; left: 9px; font-size: 14px; color: var(--text-4); pointer-events: none; z-index: 4; }
.search-box .form-control, .search-box .form-input, .search-box input { padding-left: 30px; }

.status-dot { display: inline-block; width: 7px; height: 7px; border-radius: 50%; margin-right: 6px; vertical-align: 1px; }
.status-dot.online { background: var(--success); box-shadow: 0 0 0 3px var(--success-shadow); }
.status-dot.offline { background: var(--text-4); }
.status-dot.alarm { background: var(--danger); box-shadow: 0 0 0 3px var(--danger-shadow); animation: pulse 1.6s infinite; }
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }

.notice-bar { display: flex; align-items: center; gap: 8px; padding: 9px 14px; margin-bottom: 14px; border-radius: var(--r); font-size: 13px; line-height: 1.6; border: 1px solid transparent; }
.notice-bar .icon { font-size: 15px; flex-shrink: 0; }
.notice-bar.info { background: var(--primary-bg); border-color: var(--primary-border); color: var(--primary); }
.notice-bar.warning { background: var(--warning-bg); border-color: var(--warning-border); color: var(--warning); }
.notice-bar.warning span, .notice-bar.info span { color: var(--text-2); }

.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px 18px; }
.form-group { display: flex; flex-direction: column; gap: 5px; }
.form-group.full-width, .form-group[style*="1/-1"] { grid-column: 1 / -1; }
.form-group .required, .form-label .text-danger { color: var(--danger); margin-left: 2px; }
.form-group .field-error, .form-group span.text-danger { font-size: 12px; }
.form-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--border); }
.checkbox-label { display: flex; align-items: center; gap: 5px; font-size: 13px; color: var(--text-2); cursor: pointer; }

.empty-state { text-align: center; padding: 56px 20px; }
.empty-state-icon { width: 72px; height: 72px; margin: 0 auto 14px; border-radius: 50%; background: var(--surface-3); color: var(--text-4); display: flex; align-items: center; justify-content: center; font-size: 34px; }
.empty-state-text { font-size: 14px; font-weight: 600; color: var(--text-2); margin-bottom: 6px; }
.empty-state-hint { font-size: 13px; color: var(--text-3); }
.empty-state-sm { text-align: center; padding: 44px 20px; }
.empty-state-sm .empty-state-icon { width: 56px; height: 56px; font-size: 26px; margin-bottom: 12px; }

.icon-btn { width: 30px; height: 30px; padding: 0; display: inline-flex; align-items: center; justify-content: center; background: transparent; border: none; border-radius: var(--r); color: var(--text-3); cursor: pointer; font-size: 16px; transition: all .15s; }
.icon-btn:hover { background: var(--primary-bg); color: var(--primary); }
.icon-btn.danger:hover { background: var(--danger-bg); color: var(--danger); }

/* ============================================================
   首页 / KPI / 快捷入口 / 欢迎卡
   ============================================================ */
.welcome-card { background: linear-gradient(120deg, var(--primary) 0%, var(--primary-hover) 55%, #63a4ff 100%); border-radius: var(--r-xl); padding: 24px 28px; color: var(--on-primary); display: flex; align-items: center; justify-content: space-between; margin-bottom: 18px; box-shadow: 0 6px 20px var(--primary-shadow); position: relative; overflow: hidden; }
.welcome-card::after { content: ''; position: absolute; right: -40px; top: -60px; width: 240px; height: 240px; border-radius: 50%; background: rgba(255, 255, 255, .08); }
.welcome-card::before { content: ''; position: absolute; right: 90px; bottom: -90px; width: 180px; height: 180px; border-radius: 50%; background: rgba(255, 255, 255, .06); }
.welcome-title { font-size: 20px; font-weight: 700; margin-bottom: 6px; position: relative; z-index: 1; }
.welcome-desc { font-size: 13px; opacity: .88; position: relative; z-index: 1; }
.welcome-icon { font-size: 54px; opacity: .35; position: relative; z-index: 1; }

.kpi-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); padding: 18px 20px; box-shadow: var(--shadow-sm); display: flex; align-items: center; gap: 14px; }
.kpi-icon { width: 44px; height: 44px; border-radius: 11px; display: flex; align-items: center; justify-content: center; font-size: 22px; flex-shrink: 0; }
.kpi-icon.blue { background: var(--primary-bg); color: var(--primary); }
.kpi-icon.green { background: var(--success-bg); color: var(--success); }
.kpi-icon.orange { background: var(--warning-bg); color: var(--warning); }
.kpi-icon.purple { background: var(--purple-bg); color: var(--purple); }
.kpi-icon.cyan { background: var(--cyan-bg); color: var(--cyan); }
.kpi-value { font-size: 26px; font-weight: 700; color: var(--text); line-height: 1.2; }
.kpi-label { font-size: 12.5px; color: var(--text-3); margin-top: 2px; }

.quick-section-title { font-size: 15px; font-weight: 600; margin: 22px 0 12px; display: flex; align-items: center; gap: 8px; }
.quick-section-title .icon { color: var(--primary); font-size: 17px; }
.quick-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; }
.quick-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); padding: 18px; display: flex; align-items: center; gap: 14px; transition: all .2s; box-shadow: var(--shadow-sm); text-decoration: none; }
.quick-card:hover { border-color: var(--primary-border); box-shadow: var(--shadow-md); transform: translateY(-2px); }
.quick-card:hover .quick-arrow { color: var(--primary); transform: translateX(3px); }
.quick-icon { width: 44px; height: 44px; border-radius: 11px; display: flex; align-items: center; justify-content: center; font-size: 21px; flex-shrink: 0; }
.quick-name { font-size: 14.5px; font-weight: 600; margin-bottom: 2px; color: var(--text); }
.quick-desc { font-size: 12px; color: var(--text-3); }
.quick-arrow { margin-left: auto; color: var(--text-4); font-size: 18px; transition: all .2s; }

/* ============================================================
   品类卡片网格（L1，内嵌物模型树）
   ============================================================ */
.cat-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 14px; align-items: start; }
.cat-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); padding: 16px 18px; transition: all .2s; position: relative; box-shadow: var(--shadow-sm); display: flex; flex-direction: column; gap: 12px; }
.cat-card:hover { border-color: var(--primary-border); box-shadow: var(--shadow-md); }
.cat-card-top { display: flex; align-items: center; gap: 12px; }
.cat-icon { width: 46px; height: 46px; flex-shrink: 0; border-radius: 10px; background: var(--primary-bg); display: flex; align-items: center; justify-content: center; font-size: 24px; }
.cat-info { flex: 1; min-width: 0; }
.cat-name { font-size: 15px; font-weight: 600; margin-bottom: 3px; color: var(--text); display: flex; align-items: center; gap: 8px; }
.cat-stats { font-size: 12.5px; color: var(--text-3); line-height: 1.6; }
.cat-stats span { color: var(--text); font-weight: 600; }
.cat-actions { display: flex; gap: 6px; margin-left: auto; flex-shrink: 0; }
.cat-action-btn { width: 30px; height: 30px; background: var(--surface); border: 1px solid var(--border); cursor: pointer; font-size: 14px; border-radius: var(--r); color: var(--text-3); display: inline-flex; align-items: center; justify-content: center; box-shadow: var(--shadow-sm); transition: all .15s; }
.cat-action-btn:hover { color: var(--primary); border-color: var(--primary-border); background: var(--primary-bg); }

/* 卡片内嵌物模型树（默认隐藏，按需开启） */
.cat-tree { display: none; border-top: 1px dashed var(--border); padding-top: 10px; }
.cat-tree-title { font-size: 12px; font-weight: 600; color: var(--text-3); margin-bottom: 6px; }
.cat-tree-body { max-height: 210px; overflow-y: auto; }
.cat-tree-empty { font-size: 12.5px; color: var(--text-4); padding: 4px 0; display: flex; align-items: center; gap: 4px; }
.page-tree-container { background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--r); padding: 14px 16px; }
.page-tree-root { font-size: 14px; font-weight: 600; margin-bottom: 10px; display: flex; align-items: center; gap: 6px; }
.tree-root-label { font-size: 11px; color: var(--primary); background: var(--primary-bg); padding: 1px 9px; border-radius: 10px; font-weight: 500; }
.page-tree-children { padding-left: 8px; }
.tree-node { padding: 4px 0; font-size: 13px; display: flex; align-items: center; gap: 6px; }
.tree-connector { width: 16px; border-left: 1px solid var(--border-2); border-bottom: 1px solid var(--border-2); height: 12px; margin-bottom: 4px; flex-shrink: 0; }
.tree-name { font-weight: 500; color: var(--primary); }
.tree-name.child { color: var(--primary-hover); }
.tree-dps { font-size: 11.5px; color: var(--text-3); margin-left: 4px; }
.tree-rel { font-size: 11.5px; color: var(--warning); font-weight: 500; }
.tree-req { font-size: 11.5px; margin-left: 4px; }
.tree-req.required { color: var(--warning); font-weight: 500; }
.tree-req.optional { color: var(--text-3); }

/* ============================================================
   品类产品组成配置（两步向导）
   ============================================================ */
.step-indicator { display: flex; align-items: center; justify-content: center; gap: 16px; margin-bottom: 20px; padding: 18px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); box-shadow: var(--shadow-sm); }
.step-item { display: flex; align-items: center; gap: 9px; color: var(--text-3); transition: all .2s; }
.step-item.active { color: var(--text); }
.step-num { width: 30px; height: 30px; border-radius: 50%; background: var(--surface-3); color: var(--text-3); display: flex; align-items: center; justify-content: center; font-size: 13px; font-weight: 600; border: 1px solid var(--border-2); transition: all .2s; }
.step-item.active .step-num { background: var(--primary); color: var(--on-primary); border-color: var(--primary); box-shadow: 0 2px 8px var(--primary-shadow); }
.step-label { font-size: 14px; font-weight: 500; }
.step-arrow { color: var(--text-4); font-size: 18px; }

.config-section { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); padding: 20px 22px; margin-bottom: 16px; box-shadow: var(--shadow-sm); }
.section-title { font-size: 15px; font-weight: 600; margin: 0 0 4px; color: var(--text); display: flex; align-items: center; gap: 6px; }
.section-desc { font-size: 13px; color: var(--text-3); margin: 0 0 16px; }

.select-all-bar { display: flex; align-items: center; justify-content: space-between; padding: 9px 14px; background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--r); margin-bottom: 12px; }
.select-all-label { display: flex; align-items: center; gap: 7px; font-size: 13px; color: var(--text-2); cursor: pointer; }
.select-all-count { font-size: 12px; color: var(--text-3); }

.product-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: 10px; max-height: 480px; overflow-y: auto; padding-right: 2px; }
.product-card { background: var(--surface-2); border: 1.5px solid var(--border); border-radius: var(--r); padding: 10px 12px; cursor: pointer; transition: all .15s; position: relative; }
.product-card:hover { border-color: var(--primary-border); background: var(--primary-bg); }
.product-card.selected { border-color: var(--primary); background: var(--primary-bg); box-shadow: 0 2px 8px var(--primary-focus); }
.product-card input[type="checkbox"] { position: absolute; top: 10px; right: 10px; width: 16px; height: 16px; }
.product-card-header { display: flex; justify-content: space-between; align-items: center; gap: 6px; margin-bottom: 5px; padding-right: 20px; }
.product-card-name { font-size: 13.5px; font-weight: 600; color: var(--text); margin-bottom: 2px; }
.product-card-code { font-size: 11.5px; color: var(--text-3); font-family: Consolas, monospace; }
.field-count { font-size: 11px; color: var(--text-3); background: var(--surface); padding: 1px 7px; border-radius: 10px; border: 1px solid var(--border); white-space: nowrap; }

.step-actions { display: flex; justify-content: space-between; align-items: center; margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--border); }
.selected-hint { font-size: 13px; color: var(--text-3); }
.selected-hint strong { color: var(--primary); }

.config-layout { display: flex; gap: 20px; }
.config-left { flex: 1; min-width: 0; }
.config-right { width: 460px; flex-shrink: 0; }
.config-table-header { display: flex; justify-content: space-between; align-items: center; padding: 10px 14px; background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--r) var(--r) 0 0; font-size: 13.5px; font-weight: 600; color: var(--text); }
.selected-count { font-size: 12px; color: var(--text-3); font-weight: 400; }
.config-table { border: 1px solid var(--border); border-top: none; border-radius: 0 0 var(--r) var(--r); max-height: 520px; overflow-y: auto; background: var(--surface); }
.config-row { display: flex; align-items: center; padding: 11px 14px; border-bottom: 1px solid var(--border); gap: 12px; }
.config-row:last-child { border-bottom: none; }
.config-row-name { width: 170px; flex-shrink: 0; font-size: 13px; display: flex; align-items: center; gap: 7px; }
.config-row-fields { flex: 1; display: flex; gap: 14px; align-items: center; flex-wrap: wrap; }
.config-field { display: flex; align-items: center; gap: 6px; }
.config-field label { font-size: 12px; color: var(--text-3); white-space: nowrap; }
.config-select { background: var(--surface); border: 1px solid var(--border-2); color: var(--text); padding: 3px 26px 3px 9px; border-radius: var(--r-sm); font-size: 12.5px; min-width: 110px; height: 28px; cursor: pointer; appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2386909c' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 7px center; }
.config-select:focus { border-color: var(--primary); outline: none; }

.tree-header { padding: 10px 14px; background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--r) var(--r) 0 0; font-size: 13.5px; font-weight: 600; color: var(--text); }
.tree-content { background: var(--surface); border: 1px solid var(--border); border-top: none; border-radius: 0 0 var(--r) var(--r); padding: 16px; font-family: Consolas, "Cascadia Code", monospace; font-size: 13px; color: var(--text-2); min-height: 200px; overflow-x: auto; }
.tree-root { font-size: 14px; font-weight: 600; color: var(--text); margin-bottom: 12px; padding-bottom: 9px; border-bottom: 1px solid var(--border); white-space: nowrap; }
.tree-root small { color: var(--text-3); font-weight: 400; }
.tree-content .tree-node { margin-bottom: 4px; white-space: nowrap; display: block; }
.tree-sub-node { margin-left: 22px; }
.tree-line { color: var(--text-4); margin-right: 5px; }
.tree-node-name { color: var(--text); font-weight: 500; }
.tree-node-meta { color: var(--text-3); font-size: 12px; margin-left: 5px; }
.tree-node-relation { color: var(--primary); font-size: 12px; margin-left: 5px; }
.tree-empty { color: var(--text-4); font-size: 13px; text-align: center; padding: 24px; }

/* ============================================================
   场站页（左树 + 右卡片）
   ============================================================ */
.station-layout { display: flex; align-items: stretch; background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); box-shadow: var(--shadow-sm); overflow: hidden; }
.station-tree { width: 248px; min-width: 248px; border-right: 1px solid var(--border); display: flex; flex-direction: column; }
.station-layout > .page-card { flex: 1; min-width: 0; border: 0; border-radius: 0; box-shadow: none; }
.tree-title { padding: 12px 16px; font-size: 13px; font-weight: 600; border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 7px; }
.tree-title .icon { font-size: 16px; color: var(--primary); }
.tree-body { padding: 8px; flex: 1; overflow-y: auto; }
.tree-group { margin-bottom: 2px; }
.tree-group-label { padding: 7px 10px; font-size: 13px; cursor: pointer; display: flex; align-items: center; gap: 6px; border-radius: var(--r); color: var(--text); font-weight: 500; }
.tree-group-label:hover { background: var(--surface-3); }
.tree-toggle { font-size: 13px; color: var(--text-3); transition: transform .15s; width: 14px; height: 14px; display: inline-flex; align-items: center; justify-content: center; }
.tree-group.collapsed .tree-toggle { transform: rotate(-90deg); }
.tree-group.collapsed .tree-children { display: none; }
.tree-children { padding-left: 14px; }
.tree-child-label { padding: 6px 10px; font-size: 12.5px; color: var(--text-2); display: flex; align-items: center; gap: 6px; border-radius: var(--r); }
.tree-child-label:hover { background: var(--surface-3); }
.tree-child-label .icon { font-size: 14px; color: var(--text-3); }

.cards-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(330px, 1fr)); gap: 14px; }
.site-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); padding: 16px 18px; transition: all .2s; box-shadow: var(--shadow-sm); }
.site-card:hover { border-color: var(--primary-border); box-shadow: var(--shadow-md); transform: translateY(-2px); }
.site-card-header { display: flex; align-items: center; gap: 11px; margin-bottom: 14px; }
.site-card-icon { width: 40px; height: 40px; border-radius: 10px; background: var(--primary-bg); display: flex; align-items: center; justify-content: center; font-size: 20px; flex-shrink: 0; }
.site-card-name { font-size: 14.5px; font-weight: 600; }
.site-card-meta { font-size: 12px; color: var(--text-3); margin-top: 2px; }
.site-card-body { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 12px; font-size: 12.5px; margin-bottom: 14px; }
.site-card-stat { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.site-card-stat span:last-child { color: var(--text); font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.site-card-stat .stat-num { color: var(--primary); font-weight: 600; }
.site-card-footer { display: flex; gap: 8px; border-top: 1px solid var(--border); padding-top: 12px; }

/* ============================================================
   场站模型 / 场站设备（全屏左树布局）
   ============================================================ */
/* 整卡白壳：左树 + 右工作区合并为一张白卡，竖线分隔；最低高度与底部齐平 */
.sm-layout { display: flex; align-items: stretch; background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); box-shadow: var(--shadow-sm); overflow: hidden; }
.sm-tree-panel, .dm-tree-panel { width: 260px; min-width: 260px; background: var(--surface); border-right: 1px solid var(--border); display: flex; flex-direction: column; }
.sm-tree-panel-header { padding: 15px 18px; border-bottom: 1px solid var(--border); }
.sm-tree-panel-title { font-size: 13.5px; font-weight: 600; display: flex; align-items: center; gap: 7px; }
.sm-tree-panel-title .icon { font-size: 16px; color: var(--primary); }
.sm-tree-panel-body { flex: 1; overflow-y: auto; padding: 8px; }
.sm-tree-group { margin-bottom: 2px; }
.sm-tree-owner { padding: 7px 10px; font-size: 13px; cursor: pointer; display: flex; align-items: center; gap: 6px; font-weight: 500; border-radius: var(--r); color: var(--text); }
.sm-tree-owner:hover { background: var(--surface-3); }
.sm-tree-owner .icon { font-size: 15px; color: var(--text-3); }
.sm-tree-toggle { font-size: 12px; color: var(--text-3); transition: transform .15s; width: 14px; height: 14px; display: inline-flex; align-items: center; justify-content: center; }
.sm-tree-group.collapsed .sm-tree-toggle, .sm-tree-project.collapsed .sm-tree-toggle { transform: rotate(-90deg); }
.sm-tree-group.collapsed .sm-tree-project-list, .sm-tree-project.collapsed .sm-tree-site-list { display: none; }
.sm-tree-project { margin-left: 10px; }
.sm-tree-project-label { padding: 6px 10px; font-size: 12.5px; color: var(--text-2); cursor: pointer; display: flex; align-items: center; gap: 6px; border-radius: var(--r); }
.sm-tree-project-label:hover { background: var(--surface-3); }
.sm-tree-project-label .icon { font-size: 14px; color: var(--text-3); }
.sm-tree-site-list { padding-left: 14px; }
.sm-tree-site { display: flex; align-items: center; gap: 6px; padding: 6px 10px; font-size: 12.5px; color: var(--text-2); border-radius: var(--r); margin: 1px 0; }
.sm-tree-site:hover { background: var(--surface-3); color: var(--text); }
.sm-tree-site.active { background: var(--primary-bg); color: var(--primary); font-weight: 600; }
.sm-tree-site .icon { font-size: 14px; }
.sm-tree-site.active .icon { color: var(--primary); }

.sm-right-content, .dm-right-content { flex: 1; min-width: 0; overflow-y: auto; padding: 20px 24px 28px; }
.view-enter { animation: fadeIn .25s ease; }
@keyframes fadeIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }

.btn-add-model { background: var(--primary); color: var(--on-primary); border: none; border-radius: var(--r); padding: 0 16px; height: 34px; font-size: 13.5px; font-weight: 600; cursor: pointer; display: inline-flex; align-items: center; gap: 6px; box-shadow: 0 2px 6px var(--primary-shadow); transition: all .15s; white-space: nowrap; }
.btn-add-model:hover { background: var(--primary-hover); box-shadow: 0 3px 10px var(--primary-shadow-hover); color: var(--on-primary); }

.site-info-bar { display: flex; align-items: center; gap: 26px; flex-wrap: wrap; background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); box-shadow: var(--shadow-sm); padding: 14px 20px; margin-bottom: 20px; }
.site-info-item { display: flex; align-items: center; gap: 6px; font-size: 13px; }
.site-info-label { color: var(--text-3); }
.site-info-value { font-weight: 600; color: var(--text); display: inline-flex; align-items: center; gap: 5px; }

/* ── 物模型卡片 ── */
.model-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.model-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-xl); padding: 20px; transition: all .2s; box-shadow: var(--shadow-sm); }
.model-card:hover { border-color: var(--primary-border); transform: translateY(-3px); box-shadow: var(--shadow-md); }
.model-card-header { display: flex; align-items: flex-start; gap: 13px; margin-bottom: 14px; }
.model-card-icon { width: 46px; height: 46px; border-radius: 12px; background: var(--primary-bg); display: flex; align-items: center; justify-content: center; font-size: 24px; flex-shrink: 0; }
.model-card-title { flex: 1; min-width: 0; }
.model-card-name { font-size: 15.5px; font-weight: 600; margin-bottom: 3px; }
.model-card-l2 { font-size: 12px; color: var(--text-3); }
.model-card-status { font-size: 13px; display: flex; align-items: center; gap: 16px; color: var(--text-2); margin-bottom: 4px; }
.model-card-divider { height: 1px; background: var(--border); margin: 13px 0; }
.model-card-footer { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.device-count { font-size: 12.5px; color: var(--text-3); }
.model-card-actions { display: flex; gap: 8px; }
.btn-config { background: var(--primary); color: var(--on-primary); border: none; border-radius: var(--r); padding: 0 12px; height: 28px; font-size: 12.5px; cursor: pointer; transition: all .15s; display: inline-flex; align-items: center; gap: 4px; }
.btn-config:hover { background: var(--primary-hover); color: var(--on-primary); }
.btn-delete { background: var(--surface); color: var(--danger); border: 1px solid var(--danger-border); border-radius: var(--r); padding: 0 12px; height: 28px; font-size: 12.5px; cursor: pointer; transition: all .15s; display: inline-flex; align-items: center; gap: 4px; }
.btn-delete:hover { background: var(--danger-bg); border-color: var(--danger); }

/* ── 场站设备卡片 ── */
.device-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); padding: 16px 18px; transition: all .2s; box-shadow: var(--shadow-sm); }
.device-card:hover { border-color: var(--primary-border); box-shadow: var(--shadow-md); }
.device-card-header { display: flex; align-items: center; gap: 9px; margin-bottom: 13px; }
.device-card-icon { width: 36px; height: 36px; border-radius: 9px; background: var(--primary-bg); display: flex; align-items: center; justify-content: center; font-size: 18px; }
.device-card-name { font-size: 14px; font-weight: 600; }
.device-card-body { display: flex; flex-direction: column; gap: 7px; font-size: 12.5px; margin-bottom: 13px; }
.device-card-row { display: flex; justify-content: space-between; }
.device-card-bar { height: 6px; background: var(--surface-3); border-radius: 3px; overflow: hidden; }
.device-card-bar-fill { height: 100%; background: linear-gradient(90deg, #23c343, var(--success)); border-radius: 3px; transition: width .4s; }

/* ============================================================
   自定义浮层模态框（vpp-modal，避免与 Bootstrap .modal 冲突）
   ============================================================ */
.vpp-modal-overlay { position: fixed; inset: 0; background: var(--overlay-bg); display: flex; align-items: center; justify-content: center; z-index: 1050; padding: 24px; animation: overlayIn .18s ease; }
@keyframes overlayIn { from { opacity: 0; } to { opacity: 1; } }
.vpp-modal-content { background: var(--surface); border-radius: var(--r-xl); width: 480px; max-width: 100%; max-height: 85vh; display: flex; flex-direction: column; box-shadow: var(--shadow-lg); animation: modalIn .2s ease; }
@keyframes modalIn { from { opacity: 0; transform: scale(.97) translateY(10px); } to { opacity: 1; transform: scale(1) translateY(0); } }
.vpp-modal-header { display: flex; justify-content: space-between; align-items: center; padding: 16px 20px; border-bottom: 1px solid var(--border); }
.vpp-modal-header h3 { font-size: 16px; font-weight: 600; display: flex; align-items: center; gap: 8px; margin: 0; }
.vpp-modal-close { background: none; border: none; color: var(--text-3); font-size: 20px; cursor: pointer; width: 30px; height: 30px; border-radius: var(--r); display: flex; align-items: center; justify-content: center; line-height: 1; }
.vpp-modal-close:hover { background: var(--surface-3); color: var(--text); }
.vpp-modal-body { padding: 18px 20px; overflow-y: auto; flex: 1; font-size: 14px; color: var(--text-2); }
.vpp-modal-footer { display: flex; justify-content: flex-end; gap: 10px; padding: 14px 20px; border-top: 1px solid var(--border); }
.modal-search { margin-bottom: 12px; }
.modal-search .form-control, .modal-search .form-input { width: 100%; height: 36px; }
.category-list { display: flex; flex-direction: column; gap: 4px; max-height: 46vh; overflow-y: auto; }
.category-item { display: flex; align-items: center; gap: 10px; padding: 9px 12px; border-radius: var(--r); cursor: pointer; font-size: 13.5px; border: 1px solid transparent; transition: all .12s; }
.category-item:hover { background: var(--primary-bg); }
.category-item.added { opacity: .55; cursor: default; }
.category-item.added:hover { background: transparent; }
.category-icon { width: 30px; height: 30px; border-radius: 8px; background: var(--surface-3); display: flex; align-items: center; justify-content: center; font-size: 16px; flex-shrink: 0; }
.category-name { font-weight: 500; color: var(--text); flex: 1; }
.category-code { color: var(--text-4); font-size: 11.5px; font-family: Consolas, monospace; }

/* 确认对话框 */
.confirm-body { display: flex; gap: 14px; align-items: flex-start; }
.confirm-icon { width: 40px; height: 40px; border-radius: 50%; background: var(--danger-bg); color: var(--danger); display: flex; align-items: center; justify-content: center; font-size: 20px; flex-shrink: 0; }
.confirm-icon.warning { background: var(--warning-bg); color: var(--warning); }
.confirm-title { font-size: 15px; font-weight: 600; color: var(--text); margin-bottom: 4px; }
.confirm-text { font-size: 13px; color: var(--text-3); line-height: 1.6; }

/* ============================================================
   Toast（vpp-toast，避免与 Bootstrap .toast 冲突）
   ============================================================ */
.vpp-toast-container { position: fixed; top: 72px; right: 20px; z-index: 2000; display: flex; flex-direction: column; gap: 10px; pointer-events: none; }
.vpp-toast { min-width: 280px; max-width: 400px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); box-shadow: var(--shadow-lg); padding: 11px 14px; display: flex; align-items: flex-start; gap: 10px; pointer-events: auto; animation: toastIn .25s ease; border-left: 3px solid var(--text-3); }
.vpp-toast.removing { animation: toastOut .2s ease forwards; }
@keyframes toastIn { from { opacity: 0; transform: translateX(28px); } to { opacity: 1; transform: translateX(0); } }
@keyframes toastOut { to { opacity: 0; transform: translateX(28px); } }
.vpp-toast-icon { font-size: 17px; margin-top: 1px; flex-shrink: 0; }
.vpp-toast.success { border-left-color: var(--success); }
.vpp-toast.success .vpp-toast-icon { color: var(--success); }
.vpp-toast.error { border-left-color: var(--danger); }
.vpp-toast.error .vpp-toast-icon { color: var(--danger); }
.vpp-toast.warning { border-left-color: var(--warning); }
.vpp-toast.warning .vpp-toast-icon { color: var(--warning); }
.vpp-toast.info { border-left-color: var(--primary); }
.vpp-toast.info .vpp-toast-icon { color: var(--primary); }
.vpp-toast-content { flex: 1; font-size: 13.5px; color: var(--text); line-height: 1.5; }
.vpp-toast-close { border: none; background: transparent; color: var(--text-4); cursor: pointer; font-size: 15px; padding: 0; line-height: 1; }
.vpp-toast-close:hover { color: var(--text-2); }

/* ============================================================
   全局加载浮层（VPP.loading）
   ============================================================ */
.vpp-loading-overlay { position: fixed; inset: 0; z-index: 1080; background: rgba(255, 255, 255, .55); backdrop-filter: blur(3px); display: flex; align-items: center; justify-content: center; animation: overlayIn .18s ease; }
.vpp-loading-overlay.closing { animation: loadingOut .16s ease forwards; }
@keyframes loadingOut { to { opacity: 0; } }
.vpp-loading-card { display: flex; flex-direction: column; align-items: center; gap: 16px; padding: 30px 40px; background: var(--surface); border-radius: var(--r-xl); box-shadow: var(--shadow-lg); animation: modalIn .22s ease; }
.vpp-spinner { position: relative; width: 46px; height: 46px; flex-shrink: 0; }
.vpp-spinner::before, .vpp-spinner::after { content: ''; position: absolute; inset: 0; border-radius: 50%; border: 3px solid transparent; }
.vpp-spinner::before { border-top-color: var(--primary); border-right-color: var(--primary); animation: vpp-spin .75s linear infinite; }
.vpp-spinner::after { border-bottom-color: var(--primary-border); opacity: .5; animation: vpp-spin 1.1s linear infinite reverse; }
@keyframes vpp-spin { to { transform: rotate(360deg); } }
.vpp-loading-text { font-size: 13.5px; color: var(--text-2); font-weight: 500; letter-spacing: .3px; }

/* ============================================================
   Icon picker
   ============================================================ */
.icon-picker-trigger { display: flex; align-items: center; justify-content: space-between; padding: 8px 12px; gap: 10px; border: 1px solid var(--border); border-radius: var(--r); background: var(--surface); cursor: pointer; width: 100%; transition: all .15s; text-align: left; }
.icon-picker-trigger:hover { border-color: var(--primary-border); }
.icon-picker-trigger.open { border-color: var(--primary); box-shadow: 0 0 0 3px var(--primary-focus); }
.icon-picker-preview { display: flex; align-items: center; gap: 4px; }
.icon-picker-chevron { color: var(--text-3); font-size: 16px; transition: transform .2s; }
.icon-picker-trigger.open .icon-picker-chevron { transform: rotate(180deg); }
.icon-picker-panel { position: fixed; background: var(--surface); border: 1px solid var(--border); border-radius: var(--r); box-shadow: var(--shadow-md); z-index: 1200; padding: 10px; max-height: min(420px, calc(100vh - 140px)); display: flex; flex-direction: column; animation: overlayIn .14s ease; }
.icon-picker-search { display: flex; align-items: center; gap: 8px; padding: 6px 10px; background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--r); margin-bottom: 8px; }
.icon-picker-search .icon { color: var(--text-3); font-size: 14px; }
.icon-picker-search input { flex: 1; border: none; background: transparent; outline: none; font-size: 13px; color: var(--text); }
.icon-picker-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(72px, 1fr)); gap: 6px; overflow-y: auto; flex: 1; padding-right: 4px; scrollbar-width: thin; scrollbar-color: var(--primary-glow) transparent; }
.icon-picker-grid::-webkit-scrollbar { width: 8px; }
.icon-picker-grid::-webkit-scrollbar-track { background: transparent; }
.icon-picker-grid::-webkit-scrollbar-thumb { background: var(--primary-glow); border-radius: 4px; }
.icon-picker-grid::-webkit-scrollbar-thumb:hover { background: var(--primary-shadow-hover); }
.icon-picker-group-title { grid-column: 1 / -1; font-size: 11px; font-weight: 600; color: var(--text-3); letter-spacing: .6px; padding: 6px 4px 2px; border-bottom: 1px dashed var(--border); }
.icon-picker-item { display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 10px 4px; background: var(--surface-2); border: 1.5px solid transparent; border-radius: var(--r); cursor: pointer; transition: all .12s; color: var(--text-2); font-size: 11px; }
.icon-picker-item .icon { font-size: 22px; color: var(--text); }
.icon-picker-item:hover { background: var(--primary-bg); border-color: var(--primary-border); }
.icon-picker-item:hover .icon { color: var(--primary); }
.icon-picker-item.active { background: var(--primary-bg); border-color: var(--primary); }
.icon-picker-item.active .icon { color: var(--primary); }
.icon-picker-footer { display: flex; align-items: center; justify-content: space-between; margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--border); font-size: 12px; }
.icon-picker-footer .text-muted { color: var(--text-3); }
.btn-clear-icon { background: transparent; border: none; color: var(--text-3); font-size: 12px; cursor: pointer; padding: 2px 6px; border-radius: 4px; transition: all .12s; }
.btn-clear-icon:hover { color: var(--danger); background: var(--danger-bg); }

/* ============================================================
   登录页（左侧深蓝品牌面板 + 2.5D 插画，右侧白色表单卡）
   ============================================================ */
.auth-page {
    min-height: 100vh;
    display: flex;
    background: #f4f6fa;
}

/* 左侧品牌面板 */
.auth-aside {
    width: 46%; flex-shrink: 0;
    display: flex; flex-direction: column; justify-content: space-between;
    padding: 44px 52px;
    color: #fff; position: relative; overflow: hidden;
    background: linear-gradient(150deg, #0c1e45 0%, #123a8a 48%, #1664ff 100%);
}
.auth-aside::before {
    content: ''; position: absolute; inset: 0; pointer-events: none;
    background:
        radial-gradient(circle at 85% 12%, rgba(96, 165, 255, .35), rgba(96, 165, 255, 0) 45%),
        radial-gradient(circle at 8% 88%, rgba(22, 100, 255, .45), rgba(22, 100, 255, 0) 50%),
        linear-gradient(rgba(255, 255, 255, .045) 1px, transparent 1px),
        linear-gradient(90deg, rgba(255, 255, 255, .045) 1px, transparent 1px);
    background-size: auto, auto, 38px 38px, 38px 38px;
    -webkit-mask-image: linear-gradient(135deg, rgba(0, 0, 0, .9), transparent 72%);
    mask-image: linear-gradient(135deg, rgba(0, 0, 0, .9), transparent 72%);
}
.auth-brand, .auth-copy { position: relative; z-index: 2; }

.auth-brand { display: flex; align-items: center; gap: 11px; font-size: 17px; font-weight: 700; letter-spacing: .5px; }
.auth-brand .brand-logo { width: 36px; height: 36px; font-size: 19px; box-shadow: 0 4px 14px rgba(22, 100, 255, .5); }

.auth-hero { display: flex; flex-direction: column; }
.auth-hero img {
    width: 100%; max-width: 480px; margin: 0 auto 18px;
    border-radius: 14px;
    mix-blend-mode: screen; /* 黑底等距图融入深蓝面板，亮色元素保留 */
}
.auth-hero-title { font-size: 27px; font-weight: 700; line-height: 1.45; letter-spacing: 1px; margin-bottom: 12px; }
.auth-hero-sub { font-size: 13.5px; line-height: 1.95; color: rgba(255, 255, 255, .72); max-width: 420px; }

.auth-copy { font-size: 12px; color: rgba(255, 255, 255, .45); }

/* 右侧表单区 */
.auth-main {
    flex: 1; display: flex; align-items: center; justify-content: center; padding: 40px;
}
.auth-card {
    width: 400px; flex-shrink: 0;
    background: var(--surface);
    border-radius: var(--r-xl);
    box-shadow: 0 12px 50px rgba(15, 42, 92, .10), 0 2px 12px rgba(29, 33, 41, .05);
    padding: 40px 38px 34px;
}
.auth-title { font-size: 20px; font-weight: 700; color: var(--text); margin-bottom: 6px; }
.auth-subtitle { font-size: 13px; color: var(--text-3); margin-bottom: 26px; }
.auth-form-group { margin-bottom: 18px; }
.auth-form-group > label { display: block; font-size: 13px; color: var(--text-2); margin-bottom: 7px; font-weight: 500; }
.auth-input-wrap { position: relative; }
.auth-input-wrap .icon { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); color: var(--text-4); font-size: 16px; pointer-events: none; z-index: 4; }
.auth-input-wrap .form-control, .auth-input-wrap .form-input { width: 100%; height: 42px; padding-left: 38px; font-size: 14px; }
.auth-row { display: flex; align-items: center; justify-content: space-between; margin-bottom: 22px; font-size: 13px; }
.auth-row label { display: flex; align-items: center; gap: 6px; cursor: pointer; color: var(--text-3); margin: 0; }
.btn-auth {
    width: 100%; height: 42px; font-size: 14.5px; font-weight: 600;
    background: var(--primary); border: none; border-radius: var(--r);
    color: var(--on-primary); cursor: pointer; transition: all .15s;
    box-shadow: 0 4px 12px var(--primary-shadow);
}
.btn-auth:hover { background: var(--primary-hover); color: var(--on-primary); box-shadow: 0 6px 16px var(--primary-shadow-hover); }
.auth-error {
    background: var(--danger-bg); border: 1px solid var(--danger-border);
    border-radius: var(--r); padding: 10px 14px; margin-bottom: 18px;
    font-size: 13px; color: var(--danger);
    display: flex; align-items: center; gap: 8px;
}
.auth-card-brand { display: none; }

@media (max-width: 900px) {
    .auth-aside { display: none; }
    .auth-main { width: 100%; }
    .auth-card-brand { display: flex; align-items: center; justify-content: center; gap: 10px; margin-bottom: 24px; font-size: 18px; font-weight: 700; color: var(--text); }
    .auth-card-brand .brand-logo { width: 40px; height: 40px; font-size: 21px; }
}

/* ============================================================
   响应式
   ============================================================ */
@media (max-width: 1280px) {
    .grid-4 { grid-template-columns: repeat(2, 1fr); }
    .model-grid { grid-template-columns: repeat(2, 1fr); }
    .quick-grid { grid-template-columns: repeat(2, 1fr); }
    .config-layout { flex-direction: column; }
    .config-right { width: 100%; }
}
@media (max-width: 900px) {
    .grid-3, .grid-4 { grid-template-columns: 1fr; }
    .model-grid, .quick-grid { grid-template-columns: 1fr; }
    .form-grid { grid-template-columns: 1fr; }
    .station-layout { flex-direction: column; }
    .station-tree { width: 100%; border-right: none; border-bottom: 1px solid var(--border); }
    .sm-layout { flex-direction: column; }
    .sm-tree-panel, .dm-tree-panel { width: 100%; min-width: 0; border-right: none; border-bottom: 1px solid var(--border); }
    .login-hero { display: none; }
    .login-mobile-brand { display: block; }
    .sidebar { position: fixed; left: 0; top: var(--header-h); z-index: 1020; height: calc(100vh - var(--header-h)); box-shadow: var(--shadow-lg); }
    body:not(.sidebar-collapsed) .sidebar { width: var(--sidebar-w); }
    body.sidebar-collapsed .sidebar { width: 0; padding: 0; border: none; }
    body.sidebar-collapsed .sidebar-group-title, body.sidebar-collapsed .sidebar-text { display: block; }
    body.sidebar-collapsed .sidebar-link { justify-content: flex-start; padding: 0 12px; }
    .brand-sub { display: none; }
    body:not(.sidebar-collapsed)::after { content: ''; position: fixed; left: 0; right: 0; top: var(--header-h); bottom: 0; background: var(--overlay-bg); z-index: 1010; }
}
