/* AppFast 管理控制台 —— 中性灰阶 + 单一品牌色的后台视觉系统 */

:root {
    /* 中性阶（冷灰） */
    --n-0: #ffffff;
    --n-25: #f7f8fa;
    --n-50: #f1f3f6;
    --n-100: #e7eaef;
    --n-200: #dce0e7;
    --n-300: #c3c9d4;
    --n-400: #8b93a1;
    --n-600: #5a6472;
    --n-700: #3f4855;
    --n-800: #2c3340;
    --n-900: #171b26;

    /* 品牌（靛蓝） */
    --brand-50: #eef0fc;
    --brand-100: #dde1f7;
    --brand-500: #4f5ed6;
    --brand-600: #4353c4;
    --brand-700: #363fa0;

    /* 语义色：前景 / 浅底 / 描边 三件套 */
    --ok: #0f7b4f;
    --ok-bg: #e7f5ee;
    --ok-bd: #b9e0cd;
    --warn: #9a6400;
    --warn-bg: #fdf3e0;
    --warn-bd: #f0d9a8;
    --err: #c0342c;
    --err-bg: #fdeceb;
    --err-bd: #f3c7c4;

    --r-sm: 4px;
    --r: 6px;
    --r-lg: 10px;
    --sh-1: 0 1px 2px rgba(16, 24, 40, .05);
    --sh-2: 0 4px 12px rgba(16, 24, 40, .08);

    --topnav-h: 48px;
    --sidenav-w: 232px;

    --font: -apple-system, "SF Pro Text", "Segoe UI", Roboto, "PingFang SC", "Microsoft YaHei", sans-serif;
    --mono: "SF Mono", Menlo, Consolas, "Courier New", monospace;
}

* { box-sizing: border-box; }
html, body { margin: 0; }
body {
    font: 14px/20px var(--font);
    color: var(--n-800);
    background: var(--n-25);
    -webkit-font-smoothing: antialiased;
}
a { color: var(--brand-600); text-decoration: none; }
a:hover { color: var(--brand-700); text-decoration: underline; }
h1, h2, h3, p { margin: 0; }
:focus-visible { outline: 2px solid var(--brand-500); outline-offset: 2px; }
.sr-only {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
.icon { width: 16px; height: 16px; flex: none; }

/* ---------- 顶部导航 ---------- */
.topnav {
    position: sticky; top: 0; z-index: 100;
    height: var(--topnav-h);
    display: flex; align-items: center; gap: 14px;
    padding: 0 20px;
    background: var(--n-900);
    color: var(--n-300);
}
.brand { display: flex; align-items: center; gap: 9px; color: #fff; font-size: 15px; font-weight: 600; letter-spacing: -.01em; }
.brand:hover { color: #fff; text-decoration: none; }
.brand-mark {
    width: 24px; height: 24px; border-radius: var(--r-sm);
    display: grid; place-items: center;
    background: var(--brand-600); color: #fff;
    font-size: 11px; font-weight: 700; letter-spacing: .3px;
}
.topnav-divider { width: 1px; height: 18px; background: var(--n-700); }
/* 汉堡按钮只在窄屏出现（见文件末尾的窄屏段） */
.nav-burger { display: none; }
.topnav-title { font-size: 13px; color: var(--n-400); white-space: nowrap; }

.topnav-right { display: flex; align-items: center; gap: 12px; margin-left: auto; font-size: 13px; }
.topnav-user { display: inline-flex; align-items: center; gap: 8px; color: var(--n-200); white-space: nowrap; }
.topnav-user:hover { color: #fff; text-decoration: none; }
.topnav-avatar {
    width: 24px; height: 24px; border-radius: 50%;
    display: grid; place-items: center;
    background: var(--n-700); color: #fff; font-size: 11px; font-weight: 600;
}
.topnav-logout {
    padding: 3px 10px; border: 1px solid var(--n-700); border-radius: var(--r);
    background: transparent; color: var(--n-300); font: 13px/18px var(--font); cursor: pointer;
    white-space: nowrap;
}
.topnav-logout:hover { border-color: var(--n-600); background: var(--n-800); color: #fff; }

/* ---------- 布局 ---------- */
.layout { display: flex; min-height: calc(100vh - var(--topnav-h)); }
.nav-backdrop { display: none; }
.sidenav {
    position: sticky; top: var(--topnav-h);
    width: var(--sidenav-w); flex-shrink: 0;
    height: calc(100vh - var(--topnav-h)); overflow-y: auto;
    padding: 12px 12px 24px;
    background: var(--n-0);
    border-right: 1px solid var(--n-200);
}
.sidenav-section { padding: 6px 0; }
.sidenav-section + .sidenav-section { margin-top: 4px; border-top: 1px solid var(--n-100); padding-top: 10px; }
.sidenav-section-title {
    padding: 4px 10px 6px;
    font-size: 11px; font-weight: 600; letter-spacing: .06em;
    color: var(--n-400); text-transform: uppercase;
}
.sidenav-link {
    display: flex; align-items: center; gap: 10px;
    padding: 7px 10px; margin-bottom: 1px;
    border-radius: var(--r);
    color: var(--n-700); font-size: 13.5px;
}
.sidenav-link .icon { color: var(--n-400); }
.sidenav-link:hover { background: var(--n-50); color: var(--n-900); text-decoration: none; }
.sidenav-link:hover .icon { color: var(--n-600); }
.sidenav-link.active { background: var(--brand-50); color: var(--brand-700); font-weight: 600; }
.sidenav-link.active .icon { color: var(--brand-600); }

.main { flex: 1; min-width: 0; padding: 20px 32px 56px; }
/* 内容区填满可用宽度；各个网格靠 auto-fit 自己增减列，宽屏是多出几列而不是把列拉长 */
.main-inner { width: 100%; }

/* ---------- 面包屑 / 页头 ---------- */
.breadcrumbs {
    display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
    margin-bottom: 14px; color: var(--n-400); font-size: 13px;
}
.breadcrumbs a { color: var(--n-600); }
.breadcrumbs a:hover { color: var(--brand-600); }
.breadcrumbs svg { color: var(--n-300); }

/* ---------- 实体身份色 ----------
   客户页和服务码页结构刻意一致（学一次会两个），所以必须靠颜色和徽章让人一眼分清
   身在哪一层：客户改的是默认值、会波及一批服务码；服务码改的只是它自己。 */
.entity-customer { --entity: #4353c4; --entity-bg: #eef0fc; --entity-bd: #dde1f7; }
.entity-service { --entity: #0d7a72; --entity-bg: #e2f4f1; --entity-bd: #bae3dd; }

.page-entity { border-left: 3px solid var(--entity); padding-left: 14px; }
.entity-badge {
    display: inline-block; margin-bottom: 4px; padding: 1px 9px;
    border: 1px solid var(--entity-bd); border-radius: 4px;
    background: var(--entity-bg); color: var(--entity);
    font-size: 11.5px; font-weight: 600; letter-spacing: .04em;
}
.entity-scope {
    display: flex; align-items: flex-start; gap: 8px;
    margin: 12px 0 18px; padding: 9px 12px;
    border: 1px solid var(--entity-bd); border-radius: var(--r);
    background: var(--entity-bg); color: var(--n-800); font-size: 13px;
}
.entity-scope svg { flex: none; margin-top: 2px; color: var(--entity); }
.entity-scope b { color: var(--entity); }
/* tab 下划线跟随实体色 */
.entity-customer .tabs .tab.active, .entity-service .tabs .tab.active {
    color: var(--entity); border-bottom-color: var(--entity);
}

.page-header { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; margin: 0 0 20px; }
.page-header h1 { font-size: 22px; line-height: 28px; font-weight: 650; letter-spacing: -.01em; word-break: break-all; }
.page-header .desc { margin-top: 4px; color: var(--n-600); font-size: 13px; }
.actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }

/* ---------- 提示条 ---------- */
.flash {
    display: flex; align-items: flex-start; gap: 10px;
    margin-bottom: 16px; padding: 10px 12px;
    border: 1px solid; border-radius: var(--r);
    font-size: 13px;
}
.flash svg { flex-shrink: 0; margin-top: 2px; }
.flash-text { flex: 1; padding-top: 1px; }
.flash-success { background: var(--ok-bg); border-color: var(--ok-bd); color: var(--ok); }
.flash-error { background: var(--err-bg); border-color: var(--err-bd); color: var(--err); }
.flash-success .flash-text, .flash-error .flash-text { color: var(--n-800); }
.flash-close {
    flex-shrink: 0; padding: 0 2px; border: 0; background: none;
    color: var(--n-400); font-size: 16px; line-height: 18px; cursor: pointer;
}
.flash-close:hover { color: var(--n-700); }

/* 卡片组：宽屏下并排，窄屏自动堆叠。只读型页面（概览）用它，避免一列细长条 + 右侧大片留白 */
.card-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(460px, 1fr)); gap: 16px; align-items: start; }
.card-grid > .box { margin-bottom: 0; }

/* ---------- 容器 ---------- */
.box {
    margin-bottom: 16px; overflow: hidden;
    background: var(--n-0);
    border: 1px solid var(--n-200); border-radius: var(--r-lg);
    box-shadow: var(--sh-1);
}
.box-header {
    display: flex; align-items: flex-start; justify-content: space-between; gap: 16px;
    padding: 16px 20px;
}
.box-header + .box-body, .box-header + .table-tools { padding-top: 0; }
.box-header h1 { font-size: 20px; line-height: 26px; font-weight: 650; letter-spacing: -.01em; }
.box-header h2 { font-size: 15px; line-height: 22px; font-weight: 600; }
.counter { color: var(--n-400); font-weight: 400; }
.box-desc { margin-top: 3px; color: var(--n-600); font-size: 13px; }
.box-body { padding: 16px 20px 20px; }
.box-footer { padding: 16px 20px; border-top: 1px solid var(--n-100); background: var(--n-25); }
.box-footer h3 { margin-bottom: 12px; font-size: 13px; font-weight: 600; color: var(--n-700); }

/* ---------- 分区：一个 box 内的独立语义块 ---------- */
.section { padding: 20px; border-top: 1px solid var(--n-100); }
.section:first-child { border-top: 0; }
.section-head { margin-bottom: 16px; }
.section-head h3 { font-size: 15px; font-weight: 600; letter-spacing: -.005em; }
.section-head .hint { margin-top: 3px; color: var(--n-600); font-size: 13px; max-width: 76ch; }
.section-actions {
    display: flex; align-items: center; justify-content: flex-end; gap: 8px;
    margin-top: 18px; padding-top: 16px;
    border-top: 1px solid var(--n-100);
}

/* 整个 tab 一个保存按钮：吸底，长表单滚到哪都点得到 */
.save-bar {
    position: sticky; bottom: 12px; z-index: 20;
    display: flex; align-items: center; gap: 12px;
    margin: 4px 0 16px; padding: 12px 16px;
    background: rgba(255, 255, 255, .92);
    backdrop-filter: saturate(160%) blur(8px);
    -webkit-backdrop-filter: saturate(160%) blur(8px);
    border: 1px solid var(--n-200); border-radius: var(--r-lg);
    box-shadow: 0 4px 16px rgba(16, 24, 40, .1);
}
.save-bar .save-hint { flex: 1; min-width: 0; color: var(--n-600); font-size: 13px; }
.section > .table-wrap { margin: 0 -20px; }
.section > .table-wrap + .section-actions { margin-top: 0; border-top: 0; padding-top: 16px; }

/* 分区内的说明条 */
.alert-inline {
    display: flex; align-items: flex-start; gap: 8px;
    margin-bottom: 16px; padding: 10px 12px;
    border: 1px solid var(--n-200); border-radius: var(--r);
    background: var(--n-25); color: var(--n-700); font-size: 13px;
}
.alert-inline svg { flex-shrink: 0; margin-top: 2px; color: var(--n-400); }
.alert-inline.warn { background: var(--warn-bg); border-color: var(--warn-bd); color: var(--n-800); }
.alert-inline.warn svg { color: var(--warn); }

/* ---------- 表格 ---------- */
.table-tools {
    display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
    gap: 12px 16px; padding: 0 20px 14px;
}
.filters { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.search { position: relative; width: 300px; max-width: 100%; }
.search svg { position: absolute; left: 10px; top: 8px; color: var(--n-400); pointer-events: none; }
.search input[type="search"] { padding-left: 32px; }
.table-wrap { overflow-x: auto; }
.table { width: 100%; border-collapse: separate; border-spacing: 0; }
.table th {
    padding: 8px 12px; text-align: left; white-space: nowrap;
    font-size: 12px; font-weight: 600; letter-spacing: .02em;
    color: var(--n-600);
    border-top: 1px solid var(--n-100);
    border-bottom: 1px solid var(--n-200);
}
.table td { padding: 11px 12px; vertical-align: middle; border-bottom: 1px solid var(--n-100); }
.table th:first-child, .table td:first-child { padding-left: 20px; }
.table th:last-child, .table td:last-child { padding-right: 20px; }
.table tbody tr:hover td { background: var(--n-25); }
.table tbody tr:last-child td { border-bottom: 0; }
.table tbody tr.empty-row:hover td { background: transparent; }
.table .num { text-align: right; font-variant-numeric: tabular-nums; }
.col-actions { text-align: right; white-space: nowrap; }

/* ---------- 空状态 ---------- */
.empty-state { padding: 40px 20px; text-align: center; color: var(--n-600); }
.empty-state .empty-icon {
    width: 36px; height: 36px; margin: 0 auto 12px;
    display: grid; place-items: center;
    border-radius: 50%; background: var(--n-50); color: var(--n-400);
}
.empty-state b { display: block; margin-bottom: 4px; color: var(--n-800); font-size: 14px; font-weight: 600; }
.empty-state p { font-size: 13px; max-width: 46ch; margin: 0 auto; }
.empty-state .actions { justify-content: center; margin-top: 16px; }

/* ---------- 继承（跟随客户） ---------- */
.inherit-chip {
    display: flex; align-items: flex-start; gap: 7px;
    margin-top: 6px; padding: 6px 9px;
    border: 1px solid var(--n-200); border-radius: var(--r);
    background: var(--n-25);
    font-size: 12px; line-height: 16px; color: var(--n-700);
    cursor: pointer;
}
.inherit-chip:hover { border-color: var(--n-300); }
.inherit-chip input { flex-shrink: 0; width: 13px; height: 13px; margin: 1px 0 0; accent-color: var(--brand-600); cursor: pointer; }
.inherit-chip b { font-weight: 600; }
.inherit-chip small { display: block; margin-top: 1px; color: var(--n-400); }
.inherit-tag {
    display: inline-block; margin-left: 6px; padding: 0 6px;
    border: 1px solid var(--n-200); border-radius: 10px;
    background: var(--n-25); color: var(--n-600);
    font-size: 11px; line-height: 17px; font-weight: 500; white-space: nowrap;
}

/* ---------- 页内 tab ---------- */
.tabs { display: flex; gap: 4px; margin-bottom: 18px; border-bottom: 1px solid var(--n-200); }
.tabs .tab {
    padding: 9px 12px; margin-bottom: -1px;
    color: var(--n-600); font-size: 13.5px;
    border-bottom: 2px solid transparent; white-space: nowrap;
}
.tabs .tab:hover { color: var(--n-900); text-decoration: none; }
.tabs .tab.active { color: var(--brand-600); border-bottom-color: var(--brand-600); font-weight: 600; }
@media (max-width: 960px) { .tabs { overflow-x: auto; } }

/* 二级导航：分段控件样式，和一级 tab 的下划线明显不同层 */
.subtabs {
    display: flex; flex-wrap: wrap; gap: 3px;
    margin: -4px 0 18px; padding: 4px;
    width: fit-content; max-width: 100%;
    background: var(--n-50); border-radius: var(--r);
}
.subtabs .subtab {
    padding: 5px 13px; border-radius: var(--r-sm);
    color: var(--n-600); font-size: 13px; white-space: nowrap;
}
.subtabs .subtab:hover { background: var(--n-0); color: var(--n-900); text-decoration: none; }
.subtabs .subtab.active {
    background: var(--n-0); color: var(--entity, var(--brand-600));
    font-weight: 600; box-shadow: var(--sh-1);
}
@media (max-width: 960px) { .subtabs { overflow-x: auto; flex-wrap: nowrap; } }

/* ---------- 分页 ---------- */
.pagination { display: flex; align-items: center; gap: 2px; }
.pagination a, .pagination span {
    min-width: 28px; height: 28px; padding: 0 7px;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: var(--r-sm); color: var(--n-700); font-size: 13px;
}
.pagination a:hover { background: var(--n-50); color: var(--n-900); text-decoration: none; }
.pagination .active { background: var(--brand-50); color: var(--brand-700); font-weight: 600; }
.pagination .gap { color: var(--n-400); }
.pagination .nav { font-size: 15px; }
.pagination .disabled { color: var(--n-300); }

/* ---------- 按钮 ---------- */
.btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 6px;
    min-height: 32px; padding: 5px 14px;
    border: 1px solid var(--n-300); border-radius: var(--r);
    background: var(--n-0); color: var(--n-800);
    font: 500 13.5px/20px var(--font); white-space: nowrap;
    cursor: pointer; text-decoration: none;
    box-shadow: var(--sh-1);
    transition: background-color .12s, border-color .12s, color .12s;
}
.btn:hover { background: var(--n-50); border-color: var(--n-400); color: var(--n-900); text-decoration: none; }
.btn:active { background: var(--n-100); }
.btn-primary { background: var(--brand-600); border-color: var(--brand-600); color: #fff; }
.btn-primary:hover { background: var(--brand-700); border-color: var(--brand-700); color: #fff; }
.btn-primary:active { background: var(--brand-700); }
.btn-danger { color: var(--err); border-color: var(--err-bd); }
.btn-danger:hover { background: var(--err-bg); border-color: var(--err); color: var(--err); }
.btn-danger.solid { background: var(--err); border-color: var(--err); color: #fff; }
.btn-danger.solid:hover { background: #a52b24; border-color: #a52b24; color: #fff; }
.btn-link { border-color: transparent; background: transparent; box-shadow: none; color: var(--n-600); }
.btn-link:hover { border-color: transparent; background: var(--n-50); }
.btn-sm { min-height: 28px; padding: 3px 10px; font-size: 13px; }
.link-btn { padding: 0; border: 0; background: none; font: inherit; color: var(--brand-600); cursor: pointer; }
.link-btn:hover { color: var(--brand-700); text-decoration: underline; }
.link-btn.danger { color: var(--err); }
.link-btn.danger:hover { color: #a52b24; }
.row-actions { display: inline-flex; align-items: center; gap: 14px; }
.inline-form { display: inline; margin: 0; }

/* ---------- 表单 ---------- */
input[type="text"], input[type="email"], input[type="number"], input[type="password"], input[type="search"], input[type="datetime-local"],
select, textarea {
    width: 100%; min-height: 32px; padding: 5px 10px;
    border: 1px solid var(--n-300); border-radius: var(--r);
    background: var(--n-0); color: var(--n-800);
    font: 13.5px/20px var(--font);
}
textarea { min-height: 76px; resize: vertical; }
input::placeholder, textarea::placeholder { color: var(--n-400); }
input:hover, select:hover, textarea:hover { border-color: var(--n-400); }
input:focus, select:focus, textarea:focus {
    outline: none; border-color: var(--brand-500);
    box-shadow: 0 0 0 3px var(--brand-100);
}
input:disabled, select:disabled, textarea:disabled {
    background: var(--n-50); color: var(--n-400); cursor: not-allowed; border-color: var(--n-200);
}
select {
    appearance: none; -webkit-appearance: none; padding-right: 30px; cursor: pointer;
    background: var(--n-0) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'%3E%3Cpath d='M4 6.5l4 4 4-4' fill='none' stroke='%235a6472' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat right 9px center;
}
select[multiple] { padding: 4px; background-image: none; cursor: default; }
.mono, .mono-input { font-family: var(--mono); font-size: 13px; }

.form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); align-items: start; gap: 18px 20px; }
.form-grid.cols-3 { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.form-grid .span-2 { grid-column: span 2; }
.form-grid .span-full { grid-column: 1 / -1; }
.field { min-width: 0; }
.field-head { margin-bottom: 6px; }
.field-label { display: block; font-size: 13px; font-weight: 600; color: var(--n-800); }
.field-label .optional { color: var(--n-400); font-weight: 400; }
.field-label + input { margin-top: 6px; }  /* 不走 ui.field 宏的简单表单（登录页） */
.field-desc { margin-top: 2px; color: var(--n-600); font-size: 12px; line-height: 16px; }
/* 每个字段占两行轨道：标题区（标签 + 说明）一行、控件区一行，用 subgrid 共享父网格的轨道。
   同一行里标题区按最高的那个对齐，有没有说明、控件下面有没有补充内容，输入框都落在同一条水平线上。
   非 .field 的子项（复选框、操作条等）也占两行，保证字段始终从奇数行开始、配对不乱。 */
.form-grid > *, .form-row > * { grid-row: span 2; }
.form-grid > .field, .form-row > .field { display: grid; grid-template-rows: subgrid; row-gap: 0; }

/* 添加规则一类的多字段行：网格排布，取代原先的一行横排。输入框对齐见上面 .field 的 subgrid。 */
.form-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 16px 20px; align-items: start; }
.form-row .narrow { grid-column: span 1; max-width: 120px; }
.form-row .span-2 { grid-column: span 2; }
.form-row .span-full { grid-column: 1 / -1; }
.form-row-actions {
    grid-column: 1 / -1;
    display: flex; align-items: center; gap: 14px;
    margin-top: 2px; padding-top: 14px; border-top: 1px solid var(--n-100);
}
.form-row-actions .btn { margin-left: auto; }

/* 规则卡片：一条规则一张卡，从属设置直接嵌在开关下面，不跟别的规则混在一起 */
.rule-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.rule-card {
    padding: 14px 16px;
    border: 1px solid var(--n-200); border-radius: var(--r);
    background: var(--n-0);
}
.rule-card.wide { grid-column: 1 / -1; }
.rule-card > .checkbox b { font-size: 13.5px; }
.rule-body {
    margin: 12px 0 0 22px; padding-top: 12px;
    border-top: 1px dashed var(--n-200);
    display: grid; gap: 14px;
}
.rule-body.cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }

/* 平台之类的小集合多选：全部平铺，不用滚动的 select multiple */
.choice-row { display: flex; flex-wrap: wrap; gap: 8px; }
.choice {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 4px 11px;
    border: 1px solid var(--n-300); border-radius: 999px;
    background: var(--n-0); color: var(--n-700);
    font-size: 13px; cursor: pointer; user-select: none;
}
.choice:hover { border-color: var(--n-400); background: var(--n-25); }
.choice input { width: 13px; height: 13px; margin: 0; accent-color: var(--brand-600); cursor: pointer; }
.choice:has(input:checked) { border-color: var(--brand-500); background: var(--brand-50); color: var(--brand-700); font-weight: 500; }
.choice:has(input:disabled) { opacity: .55; cursor: not-allowed; }

/* ---------- 搜索多选（ui.multi_picker）：数据集、资源包这类可能很多的选项 ---------- */
.picker { position: relative; }
/* 没有脚本时：就是一个可滚动的勾选列表 */
.picker-panel {
    max-height: 240px; overflow-y: auto; padding: 4px;
    border: 1px solid var(--n-300); border-radius: var(--r); background: var(--n-0);
}
.picker-group { padding: 8px 8px 4px; color: var(--n-600); font-size: 12px; font-weight: 600; }
.picker-option {
    display: flex; align-items: center; gap: 8px; padding: 5px 8px;
    border-radius: 4px; font-size: 13px; cursor: pointer;
}
.picker-option:hover, .picker-option.is-active { background: var(--n-50); }
.picker-option input { width: 13px; height: 13px; margin: 0; flex: none; accent-color: var(--brand-600); }
.picker-option:has(input:checked) { color: var(--brand-700); }
.picker-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.picker-value { margin-left: auto; color: var(--n-400); font: 12px var(--mono); }
.picker-empty { padding: 8px; color: var(--n-600); font-size: 13px; }
/* 有脚本时：上面一个像输入框的控件（已选标签 + 搜索框），列表变成弹出层 */
.picker-control {
    display: flex; flex-wrap: wrap; align-items: center; gap: 4px;
    min-height: 32px; padding: 3px 6px;
    border: 1px solid var(--n-300); border-radius: var(--r); background: var(--n-0); cursor: text;
}
.picker-control:hover { border-color: var(--n-400); }
.picker.is-open .picker-control, .picker-control:focus-within { border-color: var(--brand-500); box-shadow: 0 0 0 3px var(--brand-100); }
.picker-chip {
    display: inline-flex; align-items: center; gap: 2px; max-width: 100%;
    padding: 1px 2px 1px 8px; border-radius: 4px;
    background: var(--brand-50); color: var(--brand-700); font-size: 12.5px; line-height: 20px;
}
.picker-chip button {
    width: 18px; height: 18px; padding: 0; border: 0; border-radius: 3px;
    background: none; color: inherit; font-size: 14px; line-height: 1; cursor: pointer;
}
.picker-chip button:hover { background: var(--brand-100); }
.picker-control input.picker-search {
    flex: 1 0 120px; width: auto; min-height: 24px; padding: 0 4px;
    border: 0; box-shadow: none; background: none;
}
/* 弹出层用 fixed 定位（位置由脚本按控件算）：.box 有 overflow: hidden，absolute 会被卡片裁掉 */
.picker.is-enhanced .picker-panel {
    position: fixed; z-index: 50;
    box-shadow: var(--sh-2);
}
.picker.is-enhanced:not(.is-open) .picker-panel { display: none; }

.checkbox-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 14px 20px; }
.checkbox { display: flex; align-items: flex-start; gap: 8px; cursor: pointer; }
.checkbox input { flex-shrink: 0; width: 14px; height: 14px; margin: 3px 0 0; accent-color: var(--brand-600); cursor: pointer; }
.checkbox b { display: block; font-size: 13px; font-weight: 600; }
.checkbox small { display: block; color: var(--n-600); font-size: 12px; line-height: 16px; }

.inline-fields { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px 16px; }
.inline-fields .field { flex: 1 1 160px; }
.inline-fields .field.narrow { flex: 0 0 96px; }
.inline-fields .field.narrow-select { flex: 0 0 220px; }
.inline-fields .field.w-md { flex: 0 1 320px; }
.inline-fields .checkbox { padding-bottom: 6px; }

.form-actions { display: flex; align-items: center; justify-content: flex-end; gap: 8px; margin-bottom: 16px; }
.box-footer .form-actions, .section-actions .form-actions { margin: 0; }

/* ---------- 键值对 ---------- */
.kv-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 18px 28px; margin: 0; }
.kv-grid > div { min-width: 0; }
.kv-grid dt { margin-bottom: 3px; font-size: 12px; font-weight: 500; color: var(--n-600); }
.kv-grid dd { margin: 0; font-size: 13.5px; color: var(--n-800); word-break: break-all; }
.kv-grid.cols-3 { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.kv-grid.cols-2 { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }

/* ---------- 状态 / 徽标 ---------- */
.status { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; white-space: nowrap; }
.status::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.status-success { color: var(--ok); }
.status-stopped { color: var(--n-400); }
.status-error { color: var(--err); }
.status-warn { color: var(--warn); }
.badge {
    display: inline-block; padding: 0 7px;
    border: 1px solid var(--n-200); border-radius: 10px;
    background: var(--n-25); color: var(--n-700);
    font-size: 11.5px; font-weight: 500; line-height: 18px;
}
.badge-blue { background: var(--brand-50); border-color: var(--brand-100); color: var(--brand-700); }
.muted { color: var(--n-400); }

/* ---------- 仪表盘 ---------- */
.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 16px; margin-bottom: 16px; }
.stat {
    padding: 16px 18px;
    background: var(--n-0); border: 1px solid var(--n-200); border-radius: var(--r-lg);
    box-shadow: var(--sh-1);
}
.stat:hover { border-color: var(--n-300); text-decoration: none; }
.stat-label { display: flex; align-items: center; gap: 7px; color: var(--n-600); font-size: 12.5px; }
.stat-label .icon { color: var(--n-400); }
.stat-value { margin-top: 8px; font-size: 26px; line-height: 32px; font-weight: 650; letter-spacing: -.02em; color: var(--n-900); font-variant-numeric: tabular-nums; }
.stat-sub { margin-top: 3px; color: var(--n-400); font-size: 12px; }
.dash-cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(420px, 1fr)); gap: 16px; align-items: start; }
.dash-cols .box { margin-bottom: 0; }

.quick-links { display: flex; flex-wrap: wrap; gap: 8px; }

/* 用量进度条 */
.meter { height: 6px; border-radius: 3px; background: var(--n-100); overflow: hidden; }
.meter > span { display: block; height: 100%; border-radius: 3px; background: var(--brand-500); }
.meter.warn > span { background: var(--warn); }
.meter.over > span { background: var(--err); }

/* 页头 actions 里的内联表单：下拉不撑满整行 */
.action-inline { display: inline-flex; align-items: center; gap: 8px; }
.select-inline { width: auto; min-width: 110px; }

/* ---------- 下发配置预览 ---------- */
.config-json {
    max-height: 70vh; margin: 0; padding: 14px 16px; overflow: auto;
    border: 1px solid var(--n-200); border-radius: var(--r);
    background: var(--n-25); color: var(--n-800);
    font: 12.5px/1.6 var(--mono);
    /* 配置里有很长的域名列表，允许折行，否则只能一路横拉 */
    white-space: pre-wrap; word-break: break-all;
    tab-size: 4;
}

/* ---------- 登录页 ---------- */
.login-wrap { display: flex; justify-content: center; padding: 80px 16px; }
.login-box { width: 100%; max-width: 380px; }
.login-form { display: grid; gap: 16px; }
.login-submit { width: 100%; margin-top: 4px; }
.login-box .flash { margin-bottom: 16px; }

/* ---------- 操作日志 ---------- */
.log-detail { margin-top: 2px; color: var(--err); font-size: 12px; line-height: 16px; max-width: 320px; }
.log-params summary { color: var(--brand-600); cursor: pointer; font-size: 13px; }
.log-params pre {
    max-width: 420px; max-height: 240px; margin: 6px 0 0; padding: 8px 10px; overflow: auto;
    border: 1px solid var(--n-200); border-radius: var(--r); background: var(--n-25);
    font: 12px/16px var(--mono); white-space: pre-wrap; word-break: break-all;
}

/* ---------- 窄屏 ---------- */
@media (max-width: 960px) {
    /* 侧边栏收成抽屉：默认滑出屏幕，点顶栏汉堡推进来，点遮罩或任意链接（会跳页）关掉 */
    .nav-burger {
        display: grid; place-items: center;
        width: 30px; height: 30px; margin-left: -6px; flex: none;
        border-radius: var(--r); color: var(--n-300); cursor: pointer;
    }
    .nav-burger:hover { background: var(--n-800); color: #fff; }
    .sidenav {
        position: fixed; top: var(--topnav-h); left: 0; bottom: 0; z-index: 90;
        width: 260px; height: auto;
        transform: translateX(-100%);
        transition: transform .18s ease;
        box-shadow: var(--sh-2);
    }
    .nav-toggle:checked ~ .layout .sidenav { transform: none; }
    .nav-backdrop {
        position: fixed; top: var(--topnav-h); right: 0; bottom: 0; left: 0; z-index: 80;
        background: rgba(23, 27, 38, .42);
    }
    .nav-toggle:checked ~ .layout .nav-backdrop { display: block; }

    .main { padding: 16px; }
    .page-header { flex-direction: column; align-items: flex-start; }
    .form-grid, .form-grid.cols-3, .checkbox-grid { grid-template-columns: 1fr; }
    .form-grid .span-2 { grid-column: auto; }
    .kv-grid, .kv-grid.cols-3, .kv-grid.cols-2 { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
    .rule-grid { grid-template-columns: 1fr; }
    .rule-body.cols-2 { grid-template-columns: 1fr; }
    .dash-cols { grid-template-columns: 1fr; }
    .card-grid { grid-template-columns: 1fr; }
    .stat-grid { grid-template-columns: 1fr; }
    .form-row .narrow { max-width: none; }

    /* 表格给一个下限宽度，靠 .table-wrap 横向滚动整体查看。
       否则 auto 布局会把列压到一个字一行（「洋帆物流」竖着排），比滚动难读得多。 */
    .table { min-width: 680px; }
    /* 空状态没有列要撑，留着下限宽度只会把居中的提示文字推出屏幕 */
    .table:has(.empty-row) { min-width: 0; }
    /* 等宽字体的 x 高比正文大一截，13px 挤在窄表格里显得比中文还大；缩一号并禁止折行，
       长匹配规则整条留在一行，跟着表格一起横向滚。 */
    .table .mono { font-size: 12px; white-space: nowrap; }
    .empty-state { padding: 32px 16px; }
}

/* ---------- 手机 ---------- */
@media (max-width: 640px) {
    /* 顶栏在 390px 下装不下「品牌 + 管理控制台 + 用户名 + 退出」，
       会在固定 48px 高度里折行溢出。砍掉纯装饰的副标题，用户名只留头像。 */
    .topnav { gap: 10px; padding: 0 12px; }
    .topnav-divider, .topnav-title, .topnav-username { display: none; }
    .topnav-right { gap: 8px; }
    .topnav-logout { padding: 3px 8px; }

    .main { padding: 14px 12px 40px; }
    /* auto-fit 的 minmax 下限比可用宽度还大时会横向溢出，手机上一律单列 */
    .kv-grid, .kv-grid.cols-3, .kv-grid.cols-2 { grid-template-columns: 1fr; }
    .box-header, .table-tools { padding-left: 14px; padding-right: 14px; }
    .box-body { padding: 14px; }
    .box-footer, .section { padding: 14px; }
    .section > .table-wrap { margin: 0 -14px; }
    .table th:first-child, .table td:first-child { padding-left: 14px; }
    .table th:last-child, .table td:last-child { padding-right: 14px; }
    .page-header h1 { font-size: 20px; line-height: 26px; }
}

/* ---------- 单选卡片 / 卡片小标题 ----------
   认证方式这种「二选一、每个选项都要一句话解释」的场景用，比下拉一眼看得清后果。 */
.option-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 12px; }
.option-card {
    display: flex; align-items: flex-start; gap: 10px;
    padding: 14px 16px;
    border: 1px solid var(--n-200); border-radius: var(--r);
    background: var(--n-0); cursor: pointer;
}
.option-card:hover { border-color: var(--n-300); background: var(--n-25); }
.option-card input { flex: none; width: 14px; height: 14px; margin: 3px 0 0; accent-color: var(--entity, var(--brand-600)); cursor: pointer; }
.option-card b { display: block; font-size: 13.5px; font-weight: 600; }
.option-card small { display: block; margin-top: 2px; color: var(--n-600); font-size: 12px; line-height: 17px; }
.option-card:has(input:checked) {
    border-color: var(--entity, var(--brand-500)); background: var(--entity-bg, var(--brand-50));
    box-shadow: inset 0 0 0 1px var(--entity, var(--brand-500));
}

.card-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 14px; }
.card-head h4 { margin: 0; font-size: 13.5px; font-weight: 600; }
.card-head p { margin-top: 2px; color: var(--n-600); font-size: 12px; line-height: 16px; }
.card-head .status { flex: none; font-size: 12px; }
.card-fields { display: grid; gap: 14px; }
.form-grid.tight { grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 14px 16px; }
.static-value { display: flex; align-items: center; min-height: 32px; font-size: 13.5px; }
[hidden] { display: none !important; }

/* ---------- 企业登录方式：每种一张卡片，单选，选中的才展开参数 ---------- */
.lp-list { display: grid; gap: 12px; }
.lp-card { border: 1px solid var(--n-200); border-radius: var(--r); background: var(--n-0); }
.lp-card:has(.lp-toggle:checked) { border-color: var(--entity-bd, var(--brand-100)); box-shadow: inset 3px 0 0 var(--entity, var(--brand-500)); }
.lp-head { display: flex; align-items: flex-start; gap: 10px; padding: 14px 16px; cursor: pointer; }
.lp-head .lp-toggle { flex: none; width: 15px; height: 15px; margin: 2px 0 0; accent-color: var(--entity, var(--brand-600)); cursor: pointer; }
.lp-title { flex: 1; min-width: 0; }
.lp-title b { display: block; font-size: 13.5px; font-weight: 600; }
.lp-title small { display: block; margin-top: 2px; color: var(--n-600); font-size: 12px; line-height: 17px; }
.lp-head .status { flex: none; font-size: 12px; }
.lp-body { padding: 14px 16px 16px 41px; border-top: 1px dashed var(--n-200); }
.lp-body .alert-inline { margin-bottom: 14px; }
.lp-body .alert-inline code { word-break: break-all; }
.lp-sub { margin: 16px 0 10px; font-size: 12.5px; font-weight: 600; color: var(--n-700); }
.lp-sub:first-child { margin-top: 0; }
.lp-sub .muted { font-weight: 400; }
.lp-check { align-self: end; padding-bottom: 6px; }
@media (max-width: 640px) { .lp-body { padding-left: 16px; } }

/* ---------- 表格行里就地展开的小表单（如「重置密码」）。
   不做浮层：表格外面的 .table-wrap 横向可滚动，浮层会被裁掉 ---------- */
.inline-popover > summary { list-style: none; }
.inline-popover > summary::-webkit-details-marker { display: none; }
.inline-popover .popover-form { display: flex; gap: 6px; align-items: center; margin-top: 6px; }
.popover-form input { width: 220px; }
.input-with-action { display: flex; gap: 8px; }
.input-with-action input { flex: 1; }
