:root {
  --blue: #409eff;
  --blue-strong: #2f8df5;
  --blue-soft: #edf6ff;
  --text: #303133;
  --muted: #909399;
  --line: #ebeef5;
  --line-dark: #dcdfe6;
  --bg: #f3f4fa;
  --panel: #ffffff;
  --green: #67c23a;
  --orange: #e6a23c;
  --red: #f56c6c;
  --sidebar: 150px;
  --topbar: 38px;
  font-family: "Microsoft YaHei", "PingFang SC", Arial, sans-serif;
  color: var(--text);
  font-size: 12px;
}

* { box-sizing: border-box; }
html, body, #app { margin: 0; min-height: 100%; height: 100%; }
body { background: var(--bg); }
button, input, select { font: inherit; }
button { cursor: pointer; }

.app-shell { display: flex; height: 100vh; min-width: 1180px; overflow: hidden; }
.sidebar {
  width: var(--sidebar); flex: 0 0 var(--sidebar); background: #fff;
  border-right: 1px solid var(--line-dark); display: flex; flex-direction: column;
}
.brand { height: var(--topbar); display:flex; align-items:center; gap:7px; padding:0 10px; border-bottom:1px solid var(--line); font-weight:600; }
.brand-mark { width:19px; height:19px; border-radius:4px; background:#2f6be6; color:#fff; display:grid; place-items:center; font-size:11px; font-weight:700; }
.brand-title { letter-spacing:.2px; }
.nav { padding: 6px 0; overflow:auto; }
.nav-item { height:36px; display:flex; align-items:center; gap:9px; padding:0 13px; color:#303133; text-decoration:none; white-space:nowrap; border-left:2px solid transparent; }
.nav-item:hover { background:#f6f9ff; color:var(--blue); }
.nav-item.active { color:var(--blue); background:#f5f9ff; border-left-color:var(--blue); }
.nav-icon { width:15px; text-align:center; color:inherit; font-size:13px; opacity:.9; }
.content-shell { flex:1; min-width:0; display:flex; flex-direction:column; }
.topbar { height:var(--topbar); flex:0 0 var(--topbar); background:#fff; border-bottom:1px solid var(--line-dark); display:flex; align-items:center; justify-content:space-between; padding:0 10px 0 13px; }
.crumb { display:flex; align-items:center; gap:8px; color:#303133; }
.crumb-icon { font-size:11px; }
.top-actions { display:flex; align-items:center; gap:11px; color:#606266; }
.top-action { border:0; background:transparent; color:#606266; padding:2px 4px; }
.top-action:hover { color:var(--blue); }
.user { font-size:11px; color:#606266; }
.logout { border:1px solid var(--line-dark); background:#fff; border-radius:3px; height:24px; padding:0 8px; color:#606266; }
.logout:hover { border-color:var(--blue); color:var(--blue); }
.main { flex:1; overflow:auto; padding:0 7px 18px; background:var(--bg); }
.page-head { height:43px; display:flex; align-items:center; justify-content:space-between; }
.page-title { font-size:17px; font-weight:600; letter-spacing:.2px; }
.page-tools { display:flex; align-items:center; gap:8px; }
.page-head-note { color:#909399; margin-right:6px; }

.panel { background:var(--panel); border:1px solid var(--line); border-radius:4px; margin-bottom:8px; }
.filters { padding:8px; display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.filters.tight { padding:7px 8px; }
.filter-control { height:25px; min-width:110px; border:1px solid var(--line-dark); border-radius:3px; background:#fff; color:#606266; padding:0 9px; outline:none; }
.filter-control:focus { border-color:var(--blue); }
.filter-control.wide { min-width:250px; flex:1; }
.filter-control.date { min-width:138px; }
.filter-label { color:#909399; margin-left:2px; }
.date-range { display:flex; align-items:center; gap:5px; }
.date-range .filter-control { min-width:138px; }
.range-sep { color:#909399; }
.spacer { flex:1; }
.btn { height:25px; padding:0 11px; border:1px solid var(--line-dark); border-radius:3px; background:#fff; color:#606266; display:inline-flex; align-items:center; justify-content:center; gap:4px; white-space:nowrap; }
.btn:hover { color:var(--blue); border-color:#b3d8ff; }
.btn.primary { color:#fff; border-color:var(--blue); background:var(--blue); }
.btn.primary:hover { background:var(--blue-strong); }
.btn.success { color:#fff; border-color:var(--green); background:var(--green); }
.btn.danger { color:#fff; border-color:var(--red); background:var(--red); }
.btn.mini { height:21px; padding:0 6px; font-size:11px; }
.btn.link { color:var(--blue); border:0; background:transparent; padding:0 3px; }
.btn.link:hover { text-decoration:underline; }

.table-panel { padding:8px; overflow:hidden; }
.table-scroll { width:100%; overflow:auto; }
tbody tr.group-head td { background:#f2f6fc; border-top:2px solid #dce6f5; }
tbody tr.group-head:hover td { background:#eaf1fb; }
tbody tr.group-head .group-sub { margin-left:10px; color:#909399; font-weight:400; }
table { width:100%; border-collapse:collapse; table-layout:auto; background:#fff; }
th, td { border:1px solid var(--line); height:33px; padding:5px 9px; text-align:left; white-space:nowrap; font-size:11px; color:#606266; }
th { height:27px; color:#909399; font-weight:500; background:#fff; }
tbody tr:hover { background:#f8fbff; }
.empty { height:42px; text-align:center; color:#909399; }
.sms-text-cell { max-width:300px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; cursor:default; }
.pager { display:flex; align-items:center; justify-content:flex-end; flex-wrap:wrap; gap:8px; padding:10px 2px 1px; color:#909399; }
.pager button { min-width:54px; height:25px; border:1px solid var(--line-dark); border-radius:3px; background:#fff; color:#606266; }
.pager button:disabled { color:#c0c4cc; background:#f5f7fa; cursor:not-allowed; }
.pager select { height:25px; border:1px solid var(--line-dark); border-radius:3px; color:#606266; background:#fff; }
/* 「共 N 条 · 第 x / y 页」靠左，把翻页控件推到右边 */
.pager-total { margin-right:auto; }
.pager-jump { display:inline-flex; align-items:center; gap:4px; }
.pager-jump input { width:56px; height:25px; padding:0 6px; text-align:center; border:1px solid var(--line-dark); border-radius:3px; color:#606266; background:#fff; }
/* 数字框的上下箭头在 25px 高度里太挤，去掉不影响输入 */
.pager-jump input::-webkit-outer-spin-button, .pager-jump input::-webkit-inner-spin-button { -webkit-appearance:none; margin:0; }
.pager-jump input { -moz-appearance:textfield; appearance:textfield; }
.status { display:inline-flex; align-items:center; min-height:19px; border-radius:3px; padding:1px 6px; font-size:11px; }
.status.green { color:#67c23a; background:#f0f9eb; border:1px solid #e1f3d8; }
.status.red { color:#f56c6c; background:#fef0f0; border:1px solid #fde2e2; }
.status.blue { color:#409eff; background:#ecf5ff; border:1px solid #d9ecff; }
.status.orange { color:#e6a23c; background:#fdf6ec; border:1px solid #faecd8; }
.status.gray { color:#909399; background:#f4f4f5; border:1px solid #e9e9eb; }
.copy { cursor:pointer; color:#909399; margin-left:4px; font-size:11px; }
.copy:hover { color:var(--blue); }
.action-cell { display:flex; align-items:center; gap:10px; }
.action-link { color:var(--blue); border:0; background:transparent; padding:0; }
.action-link:hover { text-decoration:underline; }
.action-link.danger { color:var(--red); }
.checkbox { width:13px; height:13px; vertical-align:middle; accent-color:var(--blue); }

/* 勾选框不要吃 .form-row input 那条"文本框"规则：它带 flex:1 + min-width:0 +
   border + min-height:28px，而 .form-row label 固定 82px 宽 —— 勾选框会被压成
   0 内容宽，只剩一个空边框，勾没勾上完全看不出来（2026-09-24 修）。 */
.form-row .check-label { width:auto; display:flex; align-items:center; gap:6px; cursor:pointer; font-weight:400; color:#606266; white-space:nowrap; }
.form-row .check-label input { flex:0 0 auto; min-height:0; padding:0; border:0; border-radius:0; margin:0; }

.metrics { display:grid; grid-template-columns:repeat(11,minmax(96px,1fr)); gap:8px; padding:0 0 8px; }
.metric-card { min-height:58px; border:1px solid var(--line); border-radius:4px; background:#fff; padding:9px 10px; }
.metric-label { color:#909399; margin-bottom:7px; white-space:nowrap; }
.metric-value { font-size:18px; color:#303133; line-height:1; }
.metric-row-2 { grid-template-columns:repeat(6,minmax(112px,1fr)); }
.section-title { font-size:14px; font-weight:600; padding:10px 10px 7px; }
.table-subtitle { color:#909399; padding:0 10px 8px; }
.tabs { display:flex; align-items:center; border-bottom:1px solid var(--line); height:34px; gap:26px; padding-left:3px; }
.tab { height:34px; border:0; border-bottom:2px solid transparent; background:transparent; color:#606266; padding:0 2px; }
.tab.active { color:var(--blue); border-bottom-color:var(--blue); }
.segmented { display:flex; height:25px; }
.segment { min-width:79px; border:0; background:#f5f7fa; color:#606266; padding:0 12px; }
.segment:first-child { border-radius:3px 0 0 3px; }
.segment:last-child { border-radius:0 3px 3px 0; }
.segment.active { background:var(--blue); color:#fff; }
.dash-filter { display:flex; align-items:center; flex-wrap:wrap; gap:8px; padding:8px; }
.dash-filter .filter-control { min-width:180px; }

.error-banner { display:flex; align-items:center; gap:10px; background:#fff5f5; border:1px solid #fbc4c4; color:#b42318; padding:7px 10px; margin:7px 0 0; border-radius:3px; }
.error-banner button { margin-left:auto; color:#1769aa; border:0; background:transparent; text-decoration:underline; white-space:nowrap; }
.loading { color:#909399; padding:32px; text-align:center; }
.toast { position:fixed; top:50px; right:20px; z-index:20; background:#303133; color:#fff; padding:8px 13px; border-radius:3px; box-shadow:0 3px 10px rgba(0,0,0,.15); opacity:0; transform:translateY(-6px); pointer-events:none; transition:.18s; }
.toast.show { opacity:1; transform:translateY(0); }
.modal-backdrop { position:fixed; inset:0; z-index:30; background:rgba(0,0,0,.28); display:grid; place-items:center; }
/* 弹窗限高：内容再长也不超出视口 —— head/foot 固定，body 内部滚动。
   2026-09-26 用户报：批量弹窗文本加多了整个弹窗被拉长，底部的「创建批次」点不到。 */
.modal { width:460px; max-width:calc(100vw - 30px); max-height:calc(100vh - 32px); display:flex; flex-direction:column; background:#fff; border-radius:4px; box-shadow:0 8px 30px rgba(0,0,0,.2); }
.modal-wide { width:760px; }
.modal-content { max-height:62vh; overflow:auto; }
.modal-content pre { margin:0; white-space:pre-wrap; word-break:break-word; font:12px/1.6 Consolas, "Microsoft YaHei", monospace; color:#606266; }
.secret-view { color:#9c2c2c !important; background:#fff7f7; padding:10px; border:1px solid #fde2e2; border-radius:3px; }
.modal-head { flex:0 0 auto; height:42px; display:flex; align-items:center; justify-content:space-between; padding:0 16px; border-bottom:1px solid var(--line); font-size:14px; font-weight:600; }
.modal-close { border:0; background:transparent; color:#909399; font-size:19px; }
.modal-body { padding:16px; flex:1 1 auto; min-height:0; overflow-y:auto; }
.form-row { display:flex; align-items:center; margin-bottom:12px; }
.form-row label { width:82px; color:#606266; }
.form-row input, .form-row select, .form-row textarea { flex:1; min-width:0; border:1px solid var(--line-dark); border-radius:3px; min-height:28px; padding:5px 8px; outline:none; }
.form-row textarea { min-height:68px; resize:vertical; }
/* 控件下面跟一行说明时，说明不能当 .form-row 的第三个 flex 兄弟：.form-row select 是
   flex:1 + flex-basis:0，负空间全被说明吃掉，控件会被压到 ~0 宽（看不见选了什么）。
   说明包一层 .field-col 独占一行（2026-09-24 修）。 */
.form-row .field-col { flex:1; min-width:0; }
.form-row .field-col select, .form-row .field-col input, .form-row .field-col textarea { width:100%; }
.form-row .field-note { font-size:11px; color:#909399; line-height:1.5; margin-top:2px; }
.modal-foot { flex:0 0 auto; display:flex; justify-content:flex-end; gap:8px; padding:10px 16px; border-top:1px solid var(--line); }
.login-wrap { height:100vh; display:grid; place-items:center; background:#f1f4fa; }
.login-card { width:360px; background:#fff; border:1px solid var(--line); border-radius:5px; padding:28px; box-shadow:0 8px 26px rgba(44,62,80,.08); }
.login-card h1 { margin:0 0 7px; font-size:21px; }
.login-card p { margin:0 0 22px; color:#909399; }
.login-card input { width:100%; height:34px; border:1px solid var(--line-dark); border-radius:3px; padding:0 10px; margin-bottom:12px; }
.login-card .btn { width:100%; height:34px; }
.login-error { min-height:18px; color:var(--red); margin-bottom:8px; }

.skeleton-group { max-width: 900px; margin: 0 auto; }
.skeleton-bar { height: 14px; background: linear-gradient(90deg, #ebeef5 25%, #f3f4fa 50%, #ebeef5 75%); background-size: 400% 100%; border-radius: 3px; margin-bottom: 10px; animation: skeleton-pulse 1.2s ease-in-out infinite; }
.skeleton-bar.wide { width: 100%; }
.skeleton-bar:not(.wide) { width: 30%; }
.skeleton-row { display: flex; gap: 10px; margin-bottom: 14px; }
.skeleton-row .skeleton-bar { flex: 1; }
.skeleton-table { margin-top: 18px; }
.skeleton-table .skeleton-bar { height: 28px; margin-bottom: 6px; }
@keyframes skeleton-pulse { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }
.refreshing { opacity: .55; pointer-events: none; transition: opacity .15s; }

@media (max-width: 1400px) {
  :root { --sidebar: 150px; }
  th, td { padding-left:7px; padding-right:7px; }
  .metrics { grid-template-columns:repeat(6,minmax(105px,1fr)); }
}

/* Traffic sources panel */
.section-sub {
  font-size: 12px;
  font-weight: 600;
  color: #666;
  margin: 12px 0 6px;
  padding-bottom: 4px;
  border-bottom: 1px solid #eee;
}
.empty-hint {
  color: #999;
  font-size: 13px;
  padding: 12px 0;
}
.conv-rate {
  font-size: 11px;
  color: #888;
  margin-left: 4px;
}

/* ===== Dashboard KPI redesign ===== */
.dash-kpi-section { margin-bottom: 8px; }
.dash-kpi-group-label {
  font-size: 11px; font-weight: 600; color: #909399;
  text-transform: uppercase; letter-spacing: 0.5px;
  padding: 6px 10px 4px;
}
.dash-kpi-row {
  display: grid; gap: 8px; padding: 0 0 6px;
}
.dash-kpi-row.today { grid-template-columns: repeat(5, 1fr); }
.dash-kpi-row.total { grid-template-columns: repeat(6, 1fr); }
.dash-kpi-card {
  background: #fff; border: 1px solid var(--line); border-radius: 6px;
  padding: 14px 14px 12px; position: relative; overflow: hidden;
}
.dash-kpi-card::before {
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 3px;
}
.dash-kpi-card.kpi-primary::before { background: var(--blue); }
.dash-kpi-card.kpi-success::before { background: var(--green); }
.dash-kpi-card.kpi-warning::before { background: var(--orange); }
.dash-kpi-card.kpi-danger::before { background: var(--red); }
.dash-kpi-card.kpi-neutral::before { background: #c0c4cc; }
.dash-kpi-label {
  font-size: 11px; color: #909399; margin-bottom: 6px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.dash-kpi-value {
  font-size: 26px; font-weight: 700; line-height: 1;
  color: #303133; font-variant-numeric: tabular-nums;
}
.dash-kpi-value.kpi-sm { font-size: 20px; }
.dash-kpi-sub {
  font-size: 11px; color: #b0b4ba; margin-top: 5px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.dash-kpi-value.green { color: #0f8a5f; }
.dash-kpi-value.red { color: #dc2626; }
.dash-kpi-value.blue { color: #2563eb; }

@media (max-width: 1400px) {
  .dash-kpi-row.today { grid-template-columns: repeat(3, 1fr); }
  .dash-kpi-row.total { grid-template-columns: repeat(3, 1fr); }
}

/* ===== 子账号管理（2026-09-29 移植自 admin-web-next SubAccountsView）===== */
/* 只读身份的提示条 / agent 改自己菜单前的提醒条。main 无上内边距，
   贴着 topbar 出现会太挤，加一层贴合 main 内容区节奏的 margin。 */
.info-banner {
  display: flex; align-items: center; gap: 10px;
  background: #f0f7ff; border: 1px solid #c3d9f7; color: #1c5a94;
  padding: 7px 10px; margin: 0 0 8px; border-radius: 3px;
}
/* 此前多处直接用了 .muted（chain-reports 的阶段数据等）但从没定义过 ——
   补上兜底；子账号页归属代理码为空时的占位也用它。 */
.muted { color: #909399; }
/* 可见菜单勾选网格：内联流式排布。
   勾选框不能吃 .form-row input 的"文本框"规则（flex:1 + min-width + border
   会把它压成空壳，见上面 2026-09-24 的 check-label 修正）—— 这里是 grid 内联
   形态，只取内联排列与原生 checkbox 外观，不继承文本框规则。 */
.sa-menu-grid {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 6px 14px; padding: 6px 2px;
}
.sa-menu-grid .check-label {
  display: inline-flex; align-items: center; gap: 5px;
  cursor: pointer; font-weight: 400; color: #606266; white-space: nowrap;
}
.sa-menu-grid .check-label input {
  width: 13px; height: 13px; margin: 0; flex: none;
  accent-color: var(--blue);
}
