/* =========================================================
   Yuninject 控制台
   冷调墨蓝底 + 双色语义（蓝紫=通道/选中，琥珀=活跃/待办）
   无阴影、无渐变；圆角只用 12 / 8 / 6；零外部依赖
   ========================================================= */

:root {
  /* 色彩 */
  --ink:      #0F1319;
  --panel:    #161B23;
  --raised:   #1C232D;
  --line:     #232B36;
  --line-2:   #2E3846;

  --text:     #E6EAF0;
  --text-2:   #9AA6B5;
  --text-3:   #6B7686;

  --channel:  #6C8CFF;   /* 通道主色：选中 / 下划线 / 主按钮 / 链接 */
  --live:     #FFB020;   /* 活跃 / 待办 */
  --ok:       #3DD68C;   /* 有效 / 已激活 */
  --wait:     #8A94A6;   /* 未使用 */
  --bad:      #E5674F;   /* 过期 */
  --off:      #5A6472;   /* 停用 */

  /* 圆角三级 */
  --r3: 12px;   /* 内容面 */
  --r2: 8px;    /* 控件 */
  --r1: 6px;    /* 标签 */

  /* 字体 */
  --sans: "PingFang SC", "Microsoft YaHei", "Noto Sans CJK SC", -apple-system,
          BlinkMacSystemFont, "Segoe UI", "Hiragino Sans GB", sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono",
          "Courier New", monospace;

  /* 三段式高度 */
  --h-topbar: 56px;
  --h-channel: 64px;
  --h-tabs: 44px;
  --chrome: 172px;   /* topbar + channel + tabs + 分隔线，给 sticky 预览用 */
}

* { box-sizing: border-box; }

html, body { height: 100%; margin: 0; padding: 0; overflow: hidden; }

body {
  background: var(--ink);
  color: var(--text);
  font: 13px/1.45 var(--sans);
  -webkit-font-smoothing: antialiased;
}

.hidden { display: none !important; }
.muted  { color: var(--text-3); }
.pad    { padding: 12px 14px; }
.mono   { font-family: var(--mono); font-variant-numeric: tabular-nums; }
b.req   { color: var(--bad); font-weight: 600; }
.num    { font-family: var(--mono); font-variant-numeric: tabular-nums; }

/* 键盘可达的 focus 环统一放在文件末尾（见最下方），避免被控件的 outline:none 盖掉 */

/* 滚动条 */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--line-2); border-radius: 6px; border: 2px solid var(--ink); }
::-webkit-scrollbar-thumb:hover { background: #3A4553; }

/* =========================================================
   按钮 / 标签
   ========================================================= */
.btn {
  appearance: none;
  border: 1px solid var(--line-2);
  background: var(--raised);
  color: var(--text);
  font: inherit;
  font-size: 12.5px;
  padding: 6px 12px;
  border-radius: var(--r2);
  cursor: pointer;
  transition: background .12s, border-color .12s, opacity .12s;
  white-space: nowrap;
}
.btn:hover:not(:disabled) { background: #242C38; border-color: #3A4553; }
/* 顶栏里用 <a class="btn"> 当链接：去掉下划线并保持按钮盒模型 */
a.btn { text-decoration: none; display: inline-flex; align-items: center; justify-content: center; }
.btn:disabled { opacity: .45; cursor: not-allowed; }

.btn.primary { background: var(--channel); border-color: var(--channel); color: #0B0E13; font-weight: 600; }
.btn.primary:hover:not(:disabled) { background: #86A0FF; border-color: #86A0FF; }

.btn.danger { background: transparent; border-color: rgba(229,103,79,.5); color: var(--bad); }
.btn.danger:hover:not(:disabled) { background: rgba(229,103,79,.12); border-color: var(--bad); }

.btn.ghost { background: transparent; border-color: var(--line); color: var(--text-2); }
.btn.ghost:hover:not(:disabled) { background: var(--raised); color: var(--text); }

.btn.sm { padding: 3px 9px; font-size: 12px; }
.btn.block { display: block; width: 100%; text-align: center; }
.btn.icon { padding: 0 8px; font-size: 16px; line-height: 1.5; }

.link-inline {
  appearance: none; background: none; border: none; padding: 0;
  color: var(--channel); font: inherit; font-size: 12.5px; cursor: pointer;
}
.link-inline:hover { text-decoration: underline; }

.tag {
  display: inline-block; padding: 0 6px; border-radius: var(--r1);
  font-size: 11px; line-height: 1.7; border: 1px solid var(--line-2); color: var(--text-2);
}
.tag.custom { border-color: rgba(255,176,32,.4); color: var(--live); }
.tag.v      { border-color: rgba(108,140,255,.4); color: var(--channel); font-family: var(--mono); }
.tag.dim    { color: var(--text-3); }

/* 状态戳（卡密） */
.st { font-size: 11.5px; letter-spacing: .02em; }
.st-unused  { color: var(--wait); }
.st-active  { color: var(--ok); }
.st-expired { color: var(--bad); }
.st-revoked { color: var(--off); text-decoration: line-through; }

/* 角色徽章 / 状态徽章 */
.badge {
  display: inline-block; padding: 0 7px; border-radius: var(--r1);
  font-size: 11px; line-height: 1.7; border: 1px solid var(--line-2); color: var(--text-2);
}
.badge.role-admin { color: var(--channel); border-color: rgba(108,140,255,.4); }
.badge.role-user  { color: var(--text-2); }
.badge.ok  { color: var(--ok);  border-color: rgba(61,214,140,.4); }
.badge.warn{ color: var(--live); border-color: rgba(255,176,32,.4); }
.badge.dim { color: var(--text-3); }

/* 标签文字（12px 次级灰） */
.lbl { font-size: 12px; color: var(--text-2); letter-spacing: .02em; }

/* =========================================================
   登录
   ========================================================= */
.login-wrap {
  position: fixed; inset: 0;
  /* 必须显式抬到应用界面之上：通道条是 position:sticky + z-index:5，
     顶栏里的品牌点带 transform（也会形成层叠上下文），
     不给登录层一个更高的 z-index 时它们会画在登录卡片上面。 */
  z-index: 70;
  display: flex; align-items: center; justify-content: center;
  background: var(--ink);
  padding: 20px;
  overflow: auto;
}
.login-card {
  width: 340px; max-width: 100%;
  margin: auto;            /* 小屏/横屏时卡片高于视口也能从头滚起，不会被居中裁掉顶部 */
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r3);
  padding: 28px 24px 20px;
  text-align: center;
}
.login-mark {
  display: block; width: 46px; height: 46px; margin: 0 auto 14px;
  border-radius: 13px;
  box-shadow: 0 8px 20px rgba(0, 0, 0, .35);
}
.login-title { margin: 0; font-size: 17px; font-weight: 600; letter-spacing: .04em; }
.login-sub { margin: 4px 0 22px; color: var(--text-3); font-size: 12px; letter-spacing: .16em; }
.login-input {
  width: 100%;
  background: var(--ink);
  border: 1px solid var(--line-2);
  color: var(--text);
  font: inherit;
  padding: 9px 12px;
  border-radius: var(--r2);
  outline: none;
  text-align: center;
  letter-spacing: .08em;
}
.login-input + .login-input { margin-top: 9px; }
/* 注册验证码：输入框 + 可点击换一张的图片 */
.captcha-row { display: flex; align-items: center; gap: 9px; margin-top: 9px; }
.captcha-row .login-input { flex: 1; min-width: 0; margin-top: 0; }
.captcha-img {
  width: 112px; height: 40px; flex: none;
  border: 1px solid var(--line-2); border-radius: var(--r2);
  background: var(--raised); cursor: pointer; object-fit: cover;
}
.captcha-img.loading { opacity: .45; }
.login-card form { margin: 0; }
.login-error { min-height: 18px; margin: 8px 0 4px; color: var(--bad); font-size: 12px; }
.login-foot { margin-top: 18px; color: var(--text-3); font-size: 11px; }
.login-foot a { color: var(--channel); text-decoration: none; }
.login-foot a:hover { text-decoration: underline; }
.link-btn {
  appearance: none; background: none; border: none;
  color: var(--channel); font: inherit; font-size: 12px;
  padding: 8px 0 0; cursor: pointer;
}
.link-btn:hover { text-decoration: underline; }

/* =========================================================
   顶栏 56px
   ========================================================= */
.app { display: flex; flex-direction: column; height: 100%; }

.topbar {
  flex: none;
  height: var(--h-topbar);
  display: flex; align-items: center; gap: 20px;
  padding: 0 16px;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
}
.brand { display: flex; align-items: center; gap: 9px; }
.brand-dot {
  width: 9px; height: 9px; border-radius: 2px;
  background: var(--channel); transform: rotate(45deg); flex: none;
}
.brand-name { font-size: 14px; font-weight: 600; letter-spacing: .03em; }
.brand-sub {
  padding-left: 10px; border-left: 1px solid var(--line-2);
  color: var(--text-3); font-size: 12px; letter-spacing: .02em;
}
.gnav { display: flex; gap: 4px; margin-right: auto; }
.gnav-btn {
  appearance: none; background: transparent; border: none;
  color: var(--text-2); font: inherit; font-size: 13px;
  padding: 6px 12px; border-radius: var(--r2); cursor: pointer;
  transition: background .12s, color .12s;
}
.gnav-btn:hover { background: var(--raised); color: var(--text); }
.gnav-btn.active { background: var(--raised); color: var(--text); font-weight: 600; }

.topbar-right { display: flex; align-items: center; gap: 12px; }
.top-status { color: var(--ok); font-size: 12px; opacity: 0; transition: opacity .2s; }
.top-status.show { opacity: 1; }
.who { display: inline-flex; align-items: center; }
/* 用户名与角色合成一个 chip，角色标签只出现一次 */
.who-chip {
  display: inline-flex; align-items: baseline; gap: 8px;
  padding: 2px 9px 2px 11px;
  border: 1px solid var(--line-2); border-radius: var(--r1);
}
.who-chip .who-name { font-size: 12.5px; color: var(--text); }
.who-chip .who-role { font-size: 11px; color: var(--text-3); }
.who-chip.role-admin .who-role { color: var(--channel); }
/* 游客：整颗压暗一档，和「这就是你的账号」区分开 */
.who-chip.guest { border-style: dashed; }
.who-chip.guest .who-name { color: var(--text-2); }
.who-chip.guest .who-role { color: var(--warn, var(--text-3)); }

.global-error {
  flex: none;
  margin: 10px 16px 0;
  padding: 8px 12px;
  background: rgba(229,103,79,.10);
  border: 1px solid rgba(229,103,79,.4);
  border-left: 3px solid var(--bad);
  color: var(--bad);
  border-radius: var(--r2);
  font-size: 12.5px;
}

/* =========================================================
   主体骨架：grid 240px 1fr，只有内容区滚动
   ========================================================= */
.shell {
  flex: 1; min-height: 0;
  display: grid;
  grid-template-columns: 240px minmax(0, 1fr);
}
.shell.is-global { grid-template-columns: minmax(0, 1fr); }
.shell.is-global .sidebar { display: none; }
.shell.is-global .channel,
.shell.is-global .tabs { display: none; }

/* ---------------- 左栏 240px ---------------- */
.sidebar {
  min-height: 0;
  display: flex; flex-direction: column;
  border-right: 1px solid var(--line);
  background: var(--panel);
}
.side-head { flex: none; padding: 12px 12px 10px; display: flex; flex-direction: column; gap: 8px; }
.app-search {
  width: 100%;
  background: var(--ink);
  border: 1px solid var(--line-2);
  color: var(--text); font: inherit; font-size: 12.5px;
  padding: 6px 9px; border-radius: var(--r2); outline: none;
}
.app-search::placeholder { color: var(--text-3); }

.app-list { flex: 1; min-height: 0; overflow: auto; }
.app-item {
  display: block; width: 100%; text-align: left;
  background: transparent; border: none;
  border-bottom: 1px solid var(--line);
  border-left: 3px solid transparent;
  color: var(--text); font: inherit; cursor: pointer;
  padding: 9px 11px;
  transition: background .12s;
}
.app-item:hover { background: var(--raised); }
.app-item.active { background: rgba(108,140,255,.10); border-left-color: var(--channel); }
.ai-name {
  display: block; font-size: 13px; font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ai-meta {
  display: flex; align-items: center; gap: 10px; margin-top: 3px;
  font-size: 11px; color: var(--text-3); font-variant-numeric: tabular-nums;
}
.ai-meta .mono { color: var(--text-2); }
.dot-pub {
  width: 6px; height: 6px; border-radius: 50%; background: var(--live); flex: none;
}

/* ---------------- 右栏 main ---------------- */
.main { min-width: 0; min-height: 0; display: flex; flex-direction: column; }

/* 通道条 64px（粘性） */
.channel {
  flex: none; position: sticky; top: 0; z-index: 5;
  min-height: var(--h-channel);
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 10px 18px;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
}
.ch-left { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; min-width: 0; }
.ch-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--off); flex: none; }
.ch-dot.on { background: var(--ok); }
.ch-name { font-size: 15px; font-weight: 600; }
/* App 名在手机上是抽屉开关；桌面上点它聚焦左栏搜索框（布局不变） */
.ch-switch {
  appearance: none; background: none; border: none; padding: 0; margin: 0;
  font: inherit; color: inherit; cursor: pointer;
  display: inline-flex; align-items: center; gap: 4px; min-width: 0;
}
.ch-switch:hover .ch-caret { color: var(--text-2); }
.ch-caret { display: none; font-size: 10px; color: var(--text-3); }
.narrow-only { display: none; }   /* 只在手机断点显示 */
.ch-key { font-family: var(--mono); font-size: 12px; color: var(--text-3); }
.ch-meta { display: inline-flex; align-items: baseline; gap: 6px; }
.ch-meta .v { font-family: var(--mono); font-variant-numeric: tabular-nums; font-size: 13px; color: var(--text); }
.ch-meta .v.live { color: var(--live); }
.ch-pulse { display: inline-flex; align-items: center; gap: 7px; }
/* 有访问记录 → 琥珀实心点（10 分钟内呼吸；更早则半亮，不做装饰动画） */
.pulse { width: 8px; height: 8px; border-radius: 50%; background: var(--off); flex: none; }
.pulse.has { background: var(--live); opacity: .45; }
.pulse.on { background: var(--live); opacity: 1; animation: pulse 1.9s ease-in-out infinite; }
@keyframes pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: .35; transform: scale(.8); }
}
.ch-actions { display: flex; align-items: center; gap: 8px; flex: none; }
.ch-empty { color: var(--text-3); font-size: 13px; }

/* 页签 44px */
.tabs {
  flex: none; height: var(--h-tabs);
  display: flex; align-items: stretch; gap: 2px;
  padding: 0 12px;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
  overflow-x: auto; overflow-y: hidden;
}
.tab {
  appearance: none; background: transparent; border: none;
  border-bottom: 2px solid transparent;
  color: var(--text-2); font: inherit; font-size: 13px;
  padding: 0 14px; cursor: pointer; white-space: nowrap;
}
.tab:hover { color: var(--text); }
.tab.active { color: var(--text); font-weight: 600; border-bottom-color: var(--channel); }

/* 内容区：唯一可滚动的地方 */
.tab-body { flex: 1; min-height: 0; overflow: auto; background: var(--ink); }

/* 一整块内容面（不套娃） */
.panel-face {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r3);
  margin: 14px;
  /* 注意：不能 overflow:hidden —— 会让配置页的吸附预览列失效 */
  overflow: visible;
}
.panel-face > .sec + .sec { border-top: 1px solid var(--line); }

/* ---------------------------------------------------------
   直接挂在面板上的块（「渠道」「成员」两页 —— 其它页都走 section() 的 sec-body）
   这两页以前**根本没有内边距**，内容全贴着卡片左边；而且用的 .section-head / .kv
   这两个类**CSS 里压根没定义**（写了等于没写）。这里补齐，和其它页的 16px 节奏对齐。
   --------------------------------------------------------- */
.section-head {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 16px;
}
.section-head h2, .section-head h3, .section-head h4 {
  margin: 0; font-size: 13px; font-weight: 600; letter-spacing: .02em;
}
.section-head .muted { flex: 1; min-width: 0; }      /* 说明文字：让它自己折行，别把标题挤走 */
.kv {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 0 16px 12px; font-size: 12.5px;
}
.panel-face > .tbl-wrap { margin: 0 16px 14px; }     /* 直接挂在面板上的表格（渠道页） */
.panel-face > .note { padding: 0 16px; }             /* 直接挂在面板上的说明行 */
.member-add .row, .member-add .member-hits { padding: 0 16px; }
.sec-head {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 12px 16px;
}
.sec-head h2 { margin: 0; font-size: 13px; font-weight: 600; letter-spacing: .02em; }
.sec-head .sec-actions { margin-left: auto; display: flex; align-items: center;
  gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
/* 管理员设置入口：按钮多，允许自动换行，窄屏不溢出 */
.admin-nav { display: flex; flex-wrap: wrap; gap: 8px; }
.sec-body { padding: 0 16px 16px; }
.sec-body.flush { padding: 0; }

.empty-state { padding: 44px 20px; text-align: center; color: var(--text-3); font-size: 13px; }

/* 数字块：标签在上（11px 次级灰）、数值在下（20px 等宽），整条约 72px */
.nums { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); }
.nums > .nb + .nb { border-left: 1px solid var(--line); }
.nb { padding: 14px 16px; text-align: left; }
.nb-k {
  display: flex; align-items: baseline; gap: 8px;
  font-size: 11px; color: var(--text-2); letter-spacing: .02em;
}
.nb-k2 { color: var(--text-3); font-variant-numeric: tabular-nums; }
.nb-v {
  margin-top: 3px;
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: 20px; line-height: 1.2; color: var(--text);
}
.nb-v.live { color: var(--live); }
/* KPI 行（5 格，放在内容面内部时左侧不留空） */
.nums.k5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.nums.in-sec > .nb { padding: 10px 14px 10px 0; }
.nums.in-sec > .nb + .nb { padding-left: 16px; }
.note { margin: 12px 0 14px; font-size: 11.5px; color: var(--text-3); line-height: 1.5; }

/* 访客排行（横向细条，按最大值归一化） */
.rank { display: flex; flex-direction: column; }
.rank-row {
  display: grid;
  grid-template-columns: minmax(70px, 150px) minmax(0, 1fr) 44px auto;
  align-items: center; gap: 14px;
  padding: 8px 0; border-bottom: 1px solid var(--line);
}
.rank-row:last-child { border-bottom: none; }
.rank-name {
  font-size: 12.5px; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.link-inline.rank-name { color: var(--channel); text-align: left; }
.rank-bar { height: 4px; background: var(--line); border-radius: 2px; overflow: hidden; }
.rank-bar i { display: block; height: 100%; background: var(--channel); }
.rank-n { text-align: right; font-size: 13px; color: var(--text); }
.rank-right { display: flex; gap: 12px; }
.rank-sub { font-size: 11px; color: var(--text-3); font-variant-numeric: tabular-nums; }

/* 待办提示（琥珀） */
.todos { display: flex; flex-direction: column; gap: 8px; padding: 0 16px 16px; }
.todo {
  display: flex; align-items: center; gap: 12px;
  padding: 8px 12px;
  background: rgba(255,176,32,.07);
  border: 1px solid rgba(255,176,32,.28);
  border-left: 3px solid var(--live);
  border-radius: var(--r2);
  font-size: 12.5px; color: var(--live);
}
.todo .todo-text { flex: 1; min-width: 0; }
.todo .btn { flex: none; }

/* 纯列表（访问记录 / 版本 / 设备明细） */
.rows { display: flex; flex-direction: column; }
.row-item {
  display: grid; align-items: center; gap: 14px;
  padding: 8px 0;
  border-bottom: 1px solid var(--line);
  font-size: 12.5px;
}
.row-item:last-child { border-bottom: none; }
.row-item .mono { font-size: 12px; color: var(--text-2); }

/* =========================================================
   配置页签：表单占满宽度（右列「实时预览」已撤掉）
   ========================================================= */
.config-form { min-width: 0; padding: 4px 18px 24px; }

/* =========================================================
   折叠分组（配置表单）
   ========================================================= */
.group { padding: 4px 0; }
.group + .group { border-top: 1px solid var(--line); }
.group-title {
  font-size: 12px; font-weight: 600; letter-spacing: .02em;
  color: var(--text-2);
  padding: 11px 0; margin: 0;
  display: flex; align-items: center; gap: 8px;
}
.cfg-head {
  appearance: none; width: 100%; text-align: left;
  background: transparent; border: none; font: inherit;
  cursor: pointer; user-select: none;
}
.cfg-head::-moz-focus-inner { border: 0; }
.cards-tool-note { padding: 0 16px 12px; }
.panel-toggle { width: 11px; font-size: 10px; color: var(--text-3); line-height: 1; }
.group-summary { font-size: 11px; font-weight: 400; color: var(--text-3); }
.cfg-body { padding-bottom: 14px; }
.cfg-foot {
  display: flex; align-items: center; justify-content: flex-end; gap: 8px;
  margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line);
}
.cfg-foot .lbl { margin-right: auto; }
.panel-toggle-btn { cursor: pointer; }
.group.collapsed > .cfg-body { display: none; }
.cfg-note { font-size: 11px; color: var(--text-3); line-height: 1.5; margin-bottom: 10px; }
.sub-group { margin-top: 14px; }
.sub-group > .group-title { color: var(--text-3); padding-bottom: 8px; }

/* 字段行 */
.field {
  display: grid; grid-template-columns: 116px minmax(0, 1fr);
  gap: 4px 12px; align-items: center; padding: 5px 0;
}
.field-label { font-size: 12px; color: var(--text-2); }
.field-ctrl { min-width: 0; display: flex; align-items: center; gap: 8px; }
.field-help { grid-column: 2; font-size: 11px; color: var(--text-3); line-height: 1.5; }
.field-help:empty { display: none; }
/* 字段下方的说明（如「弹窗风格」提示）永远落在控件列，不要掉到标签列 */
.field > .policy-help, .field > .style-hint { grid-column: 2; margin-top: 4px; }

/* 一组 field 竖排（比如设置页把「允许注册」「上传注入」两开关摞在一起） */
.fields { display: flex; flex-direction: column; }
.fields > .field + .field { border-top: 1px solid var(--line); }

.form-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px 16px; }
.form-grid .full { grid-column: 1 / -1; }
.form-row { display: flex; flex-direction: column; gap: 4px; }
.form-row > span { font-size: 12px; color: var(--text-2); }

/* 按钮卡片组 */
.btn-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 12px; }
.btn-card { border: 1px solid var(--line-2); border-radius: var(--r2); background: var(--raised); overflow: hidden; }
.btn-card.off { opacity: .5; }
.btn-card-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 8px;
  padding: 7px 10px; border-bottom: 1px solid var(--line);
}
.btn-card-title { font-size: 12.5px; font-weight: 600; }
.btn-card[data-role="positive"] .btn-card-title { color: var(--ok); }
.btn-card[data-role="negative"] .btn-card-title { color: var(--bad); }
.btn-card[data-role="neutral"]  .btn-card-title { color: var(--channel); }
.btn-card-hint { font-size: 10.5px; color: var(--text-3); }
.btn-card-body { padding: 10px; }
.fs { margin-bottom: 9px; }
.fs:last-child { margin-bottom: 0; }
.fs-label { display: block; font-size: 11.5px; color: var(--text-2); margin-bottom: 4px; }
.fs-help { font-size: 10.5px; color: var(--text-3); margin-top: 3px; line-height: 1.5; }

.policy-params { max-width: 260px; margin-top: 8px; }
.policy-help {
  margin-top: 8px; font-size: 11.5px; color: var(--text-3); line-height: 1.5;
  padding-left: 8px; border-left: 2px solid var(--line-2);
}
.policy-help:empty { display: none; }

/* =========================================================
   注入命令
   ========================================================= */
.inject-row { display: flex; align-items: center; gap: 10px; padding: 6px 0; }
.inject-row + .inject-row { border-top: 1px solid var(--line); }
.inject-label { flex: none; width: 40px; font-size: 12px; color: var(--text-2); }
.inject-val {
  flex: 1; min-width: 0;
  background: var(--ink); border: 1px solid var(--line);
  border-radius: var(--r2); padding: 7px 10px;
  font-family: var(--mono); font-size: 12px; color: var(--text);
  white-space: pre-wrap; word-break: break-all; user-select: all;
}
details.legacy { margin-top: 10px; border-top: 1px solid var(--line); padding-top: 10px; }
details.legacy > summary {
  cursor: pointer; font-size: 11.5px; color: var(--text-3); user-select: none; margin-bottom: 8px;
}
details.legacy > summary:hover { color: var(--text-2); }

/* =========================================================
   打包 APK（上传 → 注入 → 下载）
   ========================================================= */
a.btn { text-decoration: none; }   /* <a> 装的按钮不要下划线 */

.build-upload { display: flex; flex-direction: column; gap: 10px; padding: 2px 0 6px; }
.build-file-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
/* 原生 file 控件换成与 .btn 一致的观感（不用浏览器默认外观） */
.file-input {
  flex: 1 1 320px; width: auto; min-width: 0;
  padding: 5px 9px; cursor: pointer; color: var(--text-2);
}
.file-input::file-selector-button {
  appearance: none; margin-right: 10px; padding: 5px 12px;
  border: 1px solid var(--line-2); border-radius: var(--r2);
  background: var(--raised); color: var(--text);
  font: inherit; font-size: 12.5px; cursor: pointer;
  transition: background .12s, border-color .12s;
}
.file-input::file-selector-button:hover { background: #242C38; border-color: #3A4553; }
.file-meta { display: flex; align-items: baseline; gap: 12px; font-size: 12px; color: var(--text-2); }
.file-meta .fm-size { color: var(--text-3); }
.build-upload-bar { display: flex; align-items: center; gap: 10px; }

/* 运行保护（注入前勾选） */
.build-guards {
  display: flex; flex-direction: column; gap: 4px;
  padding: 10px 12px; border: 1px solid var(--line); border-radius: var(--r2);
  background: var(--raised);
}
.build-guards-title { font-size: 11.5px; color: var(--text-2); margin-bottom: 2px; }
.guard-row {
  display: flex; align-items: flex-start; gap: 8px;
  padding: 3px 0; cursor: pointer; user-select: none;
}
.guard-row input { margin-top: 2px; accent-color: var(--channel); }
.guard-text { display: flex; flex-direction: column; gap: 1px; font-size: 12px; }
.guard-text b { font-weight: 600; color: var(--text); }
.guard-text .muted { font-size: 11px; }

/* 进度条：填充一律用通道色；完成态转绿 */
.progress { position: relative; flex: 1; height: 6px; background: var(--line); border-radius: 3px; overflow: hidden; }
.progress > i { display: block; height: 100%; width: 0; background: var(--channel); transition: width .25s linear; }
.progress.done > i { background: var(--ok); }
.pct { font-size: 11.5px; color: var(--text-2); font-variant-numeric: tabular-nums; min-width: 34px; text-align: right; }

/* 进行中的呼吸点（琥珀） */
.bl-dot {
  display: inline-block; width: 7px; height: 7px; border-radius: 50%;
  background: var(--live); margin-right: 5px; vertical-align: middle;
  animation: pulse 1.9s ease-in-out infinite;
}
.badge.bad { color: var(--bad); border-color: rgba(229,103,79,.4); }

.build-live { padding: 12px 0 4px; }
.build-live:empty { display: none; }
.build-live-main { display: flex; flex-direction: column; gap: 8px; }
.build-live-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.build-live-head .lbl { color: var(--text-3); }
.build-live-file { color: var(--text-3); font-size: 12px; }
.build-status-row { display: flex; align-items: center; gap: 10px; }
.build-status-row .progress { max-width: 420px; }
.build-stage { font-size: 11.5px; color: var(--text-3); }

/* 本次注入的配置地址（本机地址用琥珀提醒） */
.build-base { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; font-size: 12px; color: var(--text-2); }
.build-base.warn { color: var(--live); }
.build-base-warn {
  margin-top: 6px; font-size: 11.5px; line-height: 1.5; color: var(--live);
  padding-left: 8px; border-left: 2px solid var(--live);
}

.build-error { font-size: 12.5px; color: var(--bad); }

/* 完成区（琥珀只用于进行中，完成用绿） */
.build-done {
  display: flex; flex-direction: column; gap: 8px; padding: 10px 12px;
  border: 1px solid rgba(61,214,140,.28); border-left: 3px solid var(--ok);
  border-radius: var(--r2); background: rgba(61,214,140,.06);
}
.build-done-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.build-done-name { font-size: 12px; color: var(--text-2); }
.build-note { font-size: 11.5px; color: var(--text-3); line-height: 1.5; }

/* 注入日志（可折叠，等宽，限高） */
.build-log-wrap { margin-top: 4px; }
.build-log-wrap > summary { cursor: pointer; font-size: 11.5px; color: var(--text-3); user-select: none; }
.build-log-wrap > summary:hover { color: var(--text-2); }
.build-log {
  margin: 8px 0 0; padding: 10px 12px; max-height: 160px; overflow: auto;
  background: var(--ink); border: 1px solid var(--line); border-radius: var(--r2);
  font-family: var(--mono); font-size: 11.5px; line-height: 1.55;
  color: var(--text-2); white-space: pre-wrap; word-break: break-all;
}

/* 构建历史 */
.build-history { margin-top: 8px; padding-top: 10px; border-top: 1px solid var(--line); }
.build-hist-head { padding: 0 0 6px; }
.build-hist-head h3 { margin: 0; font-size: 13px; font-weight: 600; letter-spacing: .02em; }
.build-history table.tbl td.mono { color: var(--text); }
.build-history table.tbl td.time { white-space: nowrap; }
.hist-stage { font-size: 11px; color: var(--text-3); margin-top: 2px; }

/* 数据页：紧凑筛选 + 表头排序箭头 + 分页条 */
.sec.data-sec .sec-head { flex-wrap: wrap; }
.sec.data-sec .sec-actions { flex-wrap: wrap; justify-content: flex-end; }
input.data-filter[type="search"] {
  width: 120px; max-width: 38vw; height: 26px;
  background: var(--raised); color: var(--text);
  border: 1px solid var(--line); border-radius: 6px;
  padding: 4px 7px; font-size: 12px;
}
input.data-filter[type="search"]:focus { outline: none; border-color: var(--channel); }
.tbl th.sortable { cursor: pointer; user-select: none; position: relative; }
.tbl th.sortable:hover { color: var(--text); }
.tbl th.sortable:focus-visible { outline: 2px solid var(--channel); outline-offset: -2px; }
.tbl th.sorted { color: var(--text); }
.sort-arrow {
  position: absolute; right: 3px; top: 50%; transform: translateY(-50%);
  font-size: 10px; color: var(--text-3); line-height: 1;
}
.tbl th.sorted .sort-arrow { color: var(--channel); }
.pager select.data-ps { width: auto; padding: 3px 4px; font-size: 11.5px; }
.pager {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  padding-top: 10px; margin-top: 2px; border-top: 1px solid var(--line);
}
.pager .btn:disabled { opacity: .45; cursor: not-allowed; }

/* =========================================================
   表格（表头用发丝线，不用背景块）
   ========================================================= */
.tbl-wrap { overflow-x: auto; }
table.tbl { width: 100%; border-collapse: collapse; font-size: 12.5px; }
table.tbl th, table.tbl td {
  text-align: left; padding: 8px 10px;      /* 列一多，横向内边距很吃宽度：14→10 省下 8px/列 */
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
/* 单元格里的长文本（文件名 / 包名 / User-Agent…）：超出就省略号，别把整张表撑破。
   **不能直接给 <td> 写 max-width** —— 实测 table-layout:auto 下浏览器基本忽略它
   （UA 那列写了 320px 照样撑到 700+），必须套一层 inline-block 才截得住。
   宽度由调用方按列给（`cut(text, 宽)`），`title` 里留着全文，悬停能看到。 */
table.tbl .cut {
  display: inline-block; max-width: 220px; vertical-align: bottom;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
table.tbl th { font-size: 12px; font-weight: 400; color: var(--text-2); letter-spacing: .02em; }
table.tbl td.num, table.tbl th.num { text-align: right; font-family: var(--mono); font-variant-numeric: tabular-nums; }
table.tbl tbody tr:hover td { background: rgba(255,255,255,.015); }
table.tbl tbody tr:last-child td { border-bottom: none; }
table.tbl td.mono { font-family: var(--mono); font-size: 12px; color: var(--text-2); }
table.tbl td.time { color: var(--text-3); font-variant-numeric: tabular-nums; font-family: var(--mono); font-size: 12px; }
table.tbl td.ua { color: var(--text-3); }   /* 截断交给里面的 .cut（见上） */
table.tbl td.act { text-align: right; white-space: nowrap; }
table.tbl td.act .btn + .btn { margin-left: 6px; }

/* =========================================================
   卡密：工具条 + 卡存根
   ========================================================= */
.cards-tool {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: 14px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--line);
}
.cards-tool .form-row { min-width: 108px; }
.cards-tool .form-row.wide { min-width: 180px; }
.seg-group {
  display: inline-flex; border: 1px solid var(--line-2); border-radius: var(--r2); overflow: hidden;
}
.seg {
  appearance: none; background: var(--raised); border: none;
  color: var(--text-2); font: inherit; font-size: 12.5px;
  padding: 6px 14px; cursor: pointer;
}
.seg + .seg { border-left: 1px solid var(--line-2); }
.seg:hover { color: var(--text); }
.seg.active { background: var(--channel); color: #0B0E13; font-weight: 600; }

.cards-filters {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  padding: 10px 16px; border-bottom: 1px solid var(--line);
}
.filter-btn {
  appearance: none; background: transparent; border: 1px solid transparent;
  color: var(--text-2); font: inherit; font-size: 12.5px;
  padding: 4px 10px; border-radius: var(--r2); cursor: pointer;
}
.filter-btn:hover { color: var(--text); background: var(--raised); }
.filter-btn.active { color: var(--channel); border-color: rgba(108,140,255,.4); }
.cards-filters .chips { margin-left: auto; display: flex; flex-wrap: wrap; gap: 12px; }
.chip { display: inline-flex; align-items: baseline; gap: 6px; font-size: 12px; color: var(--text-2); }
.chip .chip-n { font-family: var(--mono); font-variant-numeric: tabular-nums; color: var(--text); font-size: 13px; }

.cards-issued {
  margin: 14px 16px; border: 1px solid rgba(255,176,32,.3); border-radius: var(--r2);
  background: rgba(255,176,32,.05); overflow: hidden;
}
.cards-issued-head {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 12px; border-bottom: 1px solid rgba(255,176,32,.22);
}
.cards-issued-tip { flex: 1; font-size: 12px; color: var(--live); }
.cards-issued-body {
  margin: 0; padding: 10px 12px; max-height: 180px; overflow: auto;
  font-family: var(--mono); font-size: 12.5px; line-height: 1.8;
  color: var(--text); white-space: pre; user-select: all;
}

/* 卡存根行 */
.stub-head, .stub-row {
  display: grid;
  grid-template-columns: 190px 64px 70px minmax(120px, 1fr) 76px minmax(80px, 140px) auto;
  align-items: center; gap: 12px;
  padding: 9px 16px;
  border-bottom: 1px solid var(--line);
}
.stub-head { font-size: 12px; color: var(--text-2); }
.stub-head .act { text-align: right; }
.stubs { padding-bottom: 4px; overflow-x: auto; }   /* 兜底：再窄也不撑破内容面 */
.stub-row { font-size: 12.5px; }
.stub-row:hover { background: rgba(255,255,255,.015); }
.stub-code { font-family: var(--mono); font-size: 15px; letter-spacing: .01em; }
.stub-remark { color: var(--text-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.stub-acts { display: flex; gap: 6px; justify-content: flex-end; align-items: center; }
/* 「更多 ⋯」不是描边按钮，安静一点，悬停才显出轮廓 */
.btn.more-btn { background: transparent; border-color: transparent; color: var(--text-3); }
.btn.more-btn:hover:not(:disabled) {
  background: transparent; border-color: var(--line-2); color: var(--text);
}
.btn.more-btn[aria-expanded="true"] { border-color: var(--line-2); color: var(--text); }
/* 剩余有效期：绝对到期时间 + 相对时间（上一行）＋ 紧急度细条（下一行） */
.stub-bar { display: flex; flex-direction: column; gap: 5px; padding: 2px 0; }
.stub-bar .bar-line { display: flex; align-items: baseline; gap: 8px; white-space: nowrap; }
.stub-bar .bar-at { font-size: 12.5px; color: var(--text); }
.stub-bar .bar-at.plain { font-size: 12px; color: var(--text-3); }
.stub-bar .bar-lbl { font-size: 11px; color: var(--text-3); font-variant-numeric: tabular-nums; }
.stub-bar .track { height: 3px; background: var(--line); border-radius: 2px; overflow: hidden; }
.stub-bar .track i { display: block; height: 100%; background: var(--channel); }
.stub-bar .track.ok i { background: var(--ok); }      /* > 3 天 */
.stub-bar .track.warn i { background: var(--live); }  /* 1 - 3 天 */
.stub-bar .track.bad i { background: var(--bad); }    /* < 1 天 */
.stub-devs {
  padding: 8px 16px 12px; border-bottom: 1px solid var(--line);
  display: flex; flex-wrap: wrap; gap: 8px; background: var(--ink);
}
.stub-dev {
  display: inline-flex; align-items: baseline; gap: 8px;
  border: 1px solid var(--line-2); border-radius: var(--r1);
  padding: 2px 8px; font-size: 11.5px;
}
.stub-dev .mono { color: var(--text); font-size: 12px; }

/* 「更多 ⋯」浮层：fixed 定位，不受内容区 overflow 裁剪 */
.menu {
  position: fixed; z-index: 60; min-width: 152px;
  background: var(--raised); border: 1px solid var(--line-2);
  border-radius: var(--r2); padding: 4px;
}
.menu-item {
  display: block; width: 100%; text-align: left;
  appearance: none; background: transparent; border: none;
  color: var(--text); font: inherit; font-size: 12.5px;
  padding: 6px 10px; border-radius: var(--r1); cursor: pointer;
}
.menu-item:hover:not(:disabled) { background: var(--line); }
.menu-item:disabled { color: var(--off); cursor: not-allowed; }
.menu-item.danger { color: var(--bad); }
.menu-item.danger:hover:not(:disabled) { background: rgba(229,103,79,.12); }

/* =========================================================
   图表（14 天双柱）
   ========================================================= */
/* 折线图（内联 SVG） */
.linechart { position: relative; width: 100%; height: 180px; }
.linechart.empty { height: auto; }
.linechart svg { display: block; width: 100%; height: 180px; }
.lc-grid { stroke: var(--line); stroke-width: 1; shape-rendering: crispEdges; }
.lc-ylabel, .lc-xlabel { fill: var(--text-3); font-size: 11px; font-variant-numeric: tabular-nums; }
.lc-line { fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.lc-line.visitor { stroke: var(--channel); }                        /* 访客：实线 */
.lc-line.newbie  { stroke: var(--live); stroke-dasharray: 4 2; }    /* 新增访客：虚线 */
.lc-dot { stroke-width: 1; }
.lc-dot.visitor { fill: var(--channel); stroke: var(--channel); }
.lc-dot.newbie  { fill: var(--live);    stroke: var(--live); }
.lc-hit { fill: transparent; cursor: crosshair; }
.lc-hit:focus-visible { outline: none; }
.lc-hline { stroke: var(--line-2); stroke-width: 1; shape-rendering: crispEdges; }
.lc-tip {
  position: absolute; z-index: 6; pointer-events: none;
  display: flex; gap: 12px; align-items: baseline;
  padding: 4px 9px; border-radius: var(--r1);
  background: var(--raised); border: 1px solid var(--line-2);
  color: var(--text); font-size: 11.5px; white-space: nowrap;
}
.lc-tip .lc-tip-d { font-family: var(--mono); color: var(--text-2); }

.chart-legend { display: flex; gap: 16px; margin-top: 10px; font-size: 12px; color: var(--text-2); }
.chart-legend .lg { display: inline-flex; align-items: center; gap: 7px; }
.chart-legend .lg::before { content: ""; width: 18px; height: 0; border-top-width: 2px; }
.chart-legend .lg-visitor::before { border-top-style: solid;  border-top-color: var(--channel); }
.chart-legend .lg-newbie::before  { border-top-style: dashed; border-top-color: var(--live); }

/* =========================================================
   表单控件
   ========================================================= */
input[type=text], input[type=password], input[type=number], input[type=search],
input:not([type]), select, textarea {
  background: var(--ink);
  border: 1px solid var(--line-2);
  color: var(--text);
  font: inherit; font-size: 12.5px;
  padding: 6px 9px; border-radius: var(--r2); outline: none; width: 100%;
}
input::placeholder, textarea::placeholder { color: var(--text-3); }
input:focus, select:focus, textarea:focus { border-color: var(--channel); }
textarea { font-family: var(--mono); font-size: 12px; resize: vertical; line-height: 1.6; }
select { cursor: pointer; }

.switch { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; user-select: none; }
.switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.switch .track {
  width: 34px; height: 18px; border-radius: 10px;
  background: var(--line-2); position: relative; transition: background .15s; flex: none;
}
.switch .track::after {
  content: ""; position: absolute; top: 2px; left: 2px;
  width: 14px; height: 14px; border-radius: 50%;
  background: var(--text-3); transition: transform .15s, background .15s;
}
.switch input:checked + .track { background: rgba(108,140,255,.35); }
.switch input:checked + .track::after { transform: translateX(16px); background: var(--channel); }
.switch input:focus-visible + .track { outline: 2px solid var(--channel); outline-offset: 2px; }
.switch-text { font-size: 12px; color: var(--text-2); width: 18px; }

.color-row { display: flex; align-items: center; gap: 8px; width: 100%; }
.color-row input[type=color] {
  width: 34px; height: 26px; padding: 0; flex: none;
  border: 1px solid var(--line-2); border-radius: var(--r1); background: var(--ink); cursor: pointer;
}
.color-row input[type=text] { flex: 1; min-width: 0; font-family: var(--mono); font-size: 12px; }

/* =========================================================
   弹窗 / Toast
   ========================================================= */
.modal-backdrop {
  position: fixed; inset: 0; z-index: 50;
  background: rgba(8,10,14,.72);
  display: flex; align-items: flex-start; justify-content: center;
  padding: 90px 20px 20px;
}
.modal {
  width: 420px; max-width: 100%;
  background: var(--panel); border: 1px solid var(--line-2);
  border-radius: var(--r3); overflow: hidden;
}
.modal-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 16px; border-bottom: 1px solid var(--line);
}
.modal-head h3 { margin: 0; font-size: 13.5px; font-weight: 600; }
.modal form { padding: 16px; }
.modal .form-row { margin-bottom: 12px; }
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 18px; }

/* 新建入口：先选「组」还是「App」 */
.new-kind { display: grid; gap: 10px; padding: 16px; }
.new-kind-card {
  display: grid; grid-template-columns: 28px 1fr; gap: 2px 8px;
  text-align: left; padding: 12px 14px; cursor: pointer;
  background: var(--raised); color: var(--text);
  border: 1px solid var(--line-2); border-radius: var(--r2);
}
.new-kind-card:hover { border-color: var(--channel); }
.new-kind-icon { grid-row: 1 / span 2; align-self: center; color: var(--channel); font-size: 17px; }
.new-kind-name { font-size: 13.5px; font-weight: 600; }
.new-kind-hint { font-size: 11.5px; color: var(--text-3); }

/* 使用指南：当前页浮层（iframe 载入 /showcase?embed=1，文档只维护一份） */
.guide-backdrop {
  position: fixed; inset: 0; z-index: 75;
  background: rgba(8, 10, 14, .72);
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
}
.guide-panel {
  width: min(980px, 100%); height: min(88vh, 920px);
  background: var(--panel); border: 1px solid var(--line-2);
  border-radius: var(--r3);
  display: flex; flex-direction: column; overflow: hidden;
  outline: none;   /* 打开时把焦点放在面板上，但不画焦点环 */
}
.guide-backdrop .guide-panel:focus,
.guide-backdrop .guide-panel:focus-visible { outline: none; }
.guide-head {
  flex: none; display: flex; align-items: center; justify-content: space-between;
  gap: 12px; padding: 8px 10px 8px 16px; border-bottom: 1px solid var(--line);
}
.guide-head h2 { margin: 0; font-size: 13.5px; font-weight: 600; }
/* 指南正文：用 fetch + Shadow DOM 渲染（不再用 iframe）。
   iframe 在部分网络/反代环境下会拿到 200 却始终处于 loading（线上实际遇到过），
   同一份文档用 fetch 取回来渲染则稳定；Shadow DOM 又刚好把两套样式隔开。 */
.guide-body { flex: 1; min-height: 0; width: 100%; overflow: auto; background: var(--ink); }
.guide-msg { padding: 28px 22px; color: var(--text-2); font-size: 13px; line-height: 1.7; }
.guide-msg.err { color: var(--bad); }

.toast {
  position: fixed; bottom: 26px; left: 50%; transform: translateX(-50%);
  background: var(--raised); border: 1px solid var(--line-2);
  color: var(--text); padding: 8px 16px; border-radius: var(--r2);
  font-size: 12.5px; z-index: 80;
}
.toast.err { border-color: var(--bad); color: var(--bad); }

/* =========================================================
   窄屏：左栏折成顶部横向 App 选择器
   断点取 1100（不是更小的 980）：数据页那张 9 列的访客表要 ~830px 才放得下，
   左栏占 240px 时窗口小于 ~1100 就装不下了 —— 与其让表格横向滚，
   不如把左栏让给内容。
   ========================================================= */
@media (max-width: 1100px) {
  .shell { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr); }
  .sidebar { border-right: none; border-bottom: 1px solid var(--line); }
  .side-head { flex-direction: row; align-items: center; padding: 9px 12px; }
  .side-head .btn { width: auto; flex: none; }
  .app-list { display: flex; overflow-x: auto; overflow-y: hidden; }
  .app-item {
    border-bottom: none; border-right: 1px solid var(--line);
    border-left: 3px solid transparent; min-width: 150px; flex: none;
  }
  .app-item.active { border-left-color: transparent; border-bottom: 2px solid var(--channel); }
}

/* KPI 数字块折成两列：这个是「真的窄」才需要的，比上面那个断点更小。
   顺带把表格压紧一点：列多的表（数据页 9 列 / 用户页 7 列）在这个宽度上
   就差几十像素，字号 12.5→12、内边距 10→8 正好塞得下，不用横向滚。 */
@media (max-width: 980px) {
  table.tbl { font-size: 12px; }
  table.tbl th, table.tbl td { padding: 8px; }
  table.tbl td.act { white-space: normal; }   /* 操作按钮允许换行，别独占一大列 */
  .nums { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .nums.k5 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .nums > .nb:nth-child(3) { border-left: none; }
  .nums.k5 > .nb:nth-child(odd) { border-left: none; padding-left: 0; }
  .nums.k5 > .nb:nth-child(even) { padding-left: 16px; }
  .nb { text-align: left; }
  .nums > .nb:nth-child(n+3) { border-top: 1px solid var(--line); }
  .cards-tool { gap: 10px; }
  .brand-sub { display: none; }
  .gnav { gap: 2px; }
  .policy-params { max-width: none; }
}

/* 房间不够宽时卡存根折成两行（与左栏折叠是两回事，所以单独一个断点） */
@media (max-width: 1360px) {
  .stub-head { display: none; }
  .stub-row {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "code   status"
      "type   type"
      "bar    bar"
      "dev    acts";
    row-gap: 6px; column-gap: 12px;
    padding: 12px 16px;
    align-items: center;
  }
  .stub-code  { grid-area: code; }
  .stub-type  { grid-area: type; }
  .stub-status{ grid-area: status; justify-self: end; }
  .stub-bar   { grid-area: bar; }
  .stub-devcell { grid-area: dev; }
  .stub-remark{ display: none; }
  .stub-acts  { grid-area: acts; justify-content: flex-end; flex-wrap: wrap; }
}
@media (max-width: 620px) {
  .stub-row {
    grid-template-areas:
      "code   status"
      "bar    bar"
      "dev    dev"
      "acts   acts";
  }
  .stub-type { display: none; }
  .stub-acts { justify-content: flex-start; }
  .ch-left { gap: 10px; }
}

/* =========================================================
   手机（<= 760px）
   这一档修的是「一行塞不下时不肯换行」造成的挤压：
   · 顶栏品牌/导航/账号三段横向挤 → 导航单独占一行；
   · 通道条的 4 个操作把 .ch-left 压到几十像素 → App 名一字一行、
     整条通道高到 400+px，把配置页内容挤得只剩一条缝；
   · 配置表单两列 → 单列，标签和控件的比例恢复正常。
   ========================================================= */
@media (max-width: 760px) {
  /* ---------- 顶栏：品牌 + 账号一行，导航一行 ---------- */
  .topbar {
    height: auto; min-height: var(--h-topbar);
    flex-wrap: wrap; align-items: center;
    gap: 6px 10px; padding: 8px 12px;
  }
  .topbar .brand { flex: 1 1 auto; min-width: 0; }
  .topbar-right { flex: none; margin-left: auto; gap: 8px; flex-wrap: nowrap; }
  .topbar-right a.btn { display: none; }        /* 「示例」入口：登录页里还有，顶栏放不下 */
  .topbar-right .btn { padding: 5px 10px; font-size: 12px; }
  .top-status { display: none; }
  .who-chip { padding: 2px 8px; gap: 6px; }
  .who-chip .who-role, .who-chip .who-uid { display: none; }

  .gnav { order: 3; flex: 1 1 100%; margin-right: 0; gap: 2px; }
  .gnav-btn { flex: 1 1 0; text-align: center; padding: 7px 6px; white-space: nowrap; }

  /* ---------- 通道条：信息一行，操作一行 ---------- */
  .channel {
    flex-wrap: wrap; align-items: flex-start;
    gap: 8px 12px; padding: 10px 12px;
  }
  .ch-left { flex: 1 1 100%; gap: 6px 12px; min-width: 0; }
  .ch-name {
    flex: 0 1 auto; min-width: 0; max-width: 100%;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .ch-key, .ch-uid {
    min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .ch-meta, .ch-pulse, .ch-pulse .lbl { white-space: nowrap; }
  .ch-actions { flex: 1 1 100%; flex-wrap: wrap; gap: 8px; }
  .ch-actions .btn { padding: 5px 10px; font-size: 12px; }
  .ch-actions select { width: auto; max-width: 100%; }

  /* ---------- App 选择：侧栏收成抽屉，入口在通道条的 App 名上 ---------- */
  .ch-switch { cursor: pointer; }
  .ch-caret { display: inline; }
  .narrow-only { display: inline-flex; }

  .shell { grid-template-rows: minmax(0, 1fr); }
  .sidebar {
    position: fixed; z-index: 65; top: 0; bottom: 0; left: 0;
    width: min(82vw, 330px);
    border-right: 1px solid var(--line); border-bottom: none;
    transform: translateX(-102%);
    transition: transform .18s ease;
  }
  body.apps-open .sidebar { transform: none; }
  .drawer-backdrop {
    position: fixed; inset: 0; z-index: 64;
    background: rgba(8, 10, 14, .62);
  }
  /* 1100 断点把列表横过来了；抽屉里恢复成竖排 */
  .app-list { display: block; overflow-y: auto; overflow-x: hidden; }
  .app-item {
    min-width: 0; width: 100%;
    border-right: none; border-bottom: 1px solid var(--line);
  }
  .app-item.active {
    border-left-color: var(--channel);
    border-bottom: 1px solid var(--line);
  }

  /* ---------- 页签：窄屏收紧内边距，6 个页签尽量一屏放下（360 宽刚好） ---------- */
  .tab { padding: 0 10px; font-size: 12.5px; }

  /* ---------- 配置页：单列，别把输入框压成一条 ---------- */
  .panel-face { margin: 10px; }
  .config-form { padding: 2px 12px 20px; }
  .form-grid { grid-template-columns: minmax(0, 1fr); }
  /* 长文本字段（HTML 代码/更新说明）：标签叠到上面，别让 116px 标签列把输入框压窄 */
  .field-code { grid-template-columns: minmax(0, 1fr); gap: 6px; align-items: start; }
  .field-code > .field-ctrl, .field-code > .field-help { grid-column: 1; }
  .field-code textarea { width: 100%; box-sizing: border-box; }
  .cfg-card-head { flex-wrap: wrap; gap: 2px 10px; }
  .cfg-card-head .muted { flex-basis: 100%; }
  .btn-grid { grid-template-columns: minmax(0, 1fr); }
  .policy-params { max-width: none; }

  /* 登录/注册卡片：小屏留白收一点，输入框别贴边 */
  .login-card { padding: 24px 20px 18px; }

  /* 使用指南：手机入口在「设置」页；浮层占满整屏 */
  #guide-btn { display: none; }
  .guide-backdrop { padding: 0; }
  .guide-panel { width: 100%; height: 100%; border: none; border-radius: 0; }
}

/* =========================================================
   键盘可达：所有可点元素统一 focus 环
   （必须放在最后：控件的 outline:none 与它同权重，靠顺序取胜）
   ========================================================= */
:focus-visible,
input:focus-visible,
input[type]:focus-visible,
select:focus-visible,
textarea:focus-visible,
button:focus-visible,
a:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--channel);
  outline-offset: 2px;
}

/* 动效偏好 */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  .pulse.on { animation: none; }
}

/* ---------------------------------------------------------
   成员 / 权限（App 详情 → 成员页）
--------------------------------------------------------- */
.badge.share { color: var(--text-2); border-color: var(--line); }
.badge.lv-owner  { color: var(--channel); border-color: rgba(108,140,255,.4); }
.badge.lv-editor { color: var(--ok);  border-color: rgba(61,214,140,.4); }
.badge.lv-viewer { color: var(--text-2); }

.member-list { display: flex; flex-direction: column; margin: 6px 0 14px; }
.member-row {
  display: flex; align-items: center; gap: 10px;
  /* 左右 16px：内容不贴边，分隔线仍然通栏（和设置页的 .row-item 一个套路）。
     以前是 2px —— 名字几乎顶在卡片左边框上。 */
  padding: 9px 16px; border-bottom: 1px solid var(--line);
}
.member-row:last-child { border-bottom: none; }
.member-row .m-name { flex: 1; font-size: 13px; }
.member-lv {
  /* 这两个变量以前写成了 --bg-2/--text-1（本项目没有定义）——
     会退化成透明底 + 初始色，选择框在深色界面上几乎看不出边界。 */
  background: var(--raised); color: var(--text); font-size: 12px;
  border: 1px solid var(--line); border-radius: 6px; padding: 4px 6px;
}
.member-add { margin-top: 14px; }
.member-add .row { display: flex; gap: 8px; align-items: center; margin-top: 8px; }
.member-q {
  flex: 1; min-width: 160px; background: var(--bg-2); color: var(--text-1);
  border: 1px solid var(--line); border-radius: 6px; padding: 7px 10px; font-size: 13px;
}
.member-hits { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.chip-btn {
  background: var(--bg-2); color: var(--text-1); cursor: pointer;
  border: 1px solid var(--line); border-radius: 999px; padding: 4px 11px; font-size: 12px;
}
.chip-btn:hover { border-color: var(--channel); color: var(--channel); }
.quota-in {
  width: 74px; background: var(--bg-2); color: var(--text-1); font-size: 12px;
  border: 1px solid var(--line); border-radius: 6px; padding: 4px 6px;
}

/* 自己的 UID / App ID：对外标识，等宽字体方便核对 */
.who-chip .who-uid {
  font-size: 10.5px; color: var(--text-3); cursor: pointer;
  border-left: 1px solid var(--line); padding-left: 7px; margin-left: 2px;
}
.who-chip .who-uid:hover { color: var(--channel); }
.ch-uid { font-size: 10.5px; color: var(--text-3); }
.uid-cell .link-inline { font-size: 11.5px; color: var(--text-2); }
.uid-cell .link-inline:hover { color: var(--channel); }

/* 配置页：弹窗类型列表（开关 + 齿轮） */
.popup-types { padding: 2px 0; }
.popup-type-row {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 11px 0; border-top: 1px solid var(--line);
}
.popup-type-row:first-child { border-top: none; }
.popup-type-main { flex: 1 1 180px; min-width: 0; }
.popup-type-title {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  font-size: 13px; font-weight: 600;
}
.popup-type-hint { font-size: 11.5px; font-weight: 400; color: var(--text-3); }
.popup-type-desc { font-size: 11.5px; color: var(--text-3); margin-top: 2px; }
.popup-detail-head { display: flex; align-items: center; gap: 10px; margin: 0 0 12px; }
.tpl-preview-wrap { padding: 4px 0 6px; }
.tpl-admin-list { padding: 2px 0; margin-top: 6px; }
.upd-admin-list { padding: 2px 0; margin-top: 6px; }
.tpl-admin-row {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 0; border-top: 1px solid var(--line);
}
.tpl-admin-row:first-child { border-top: none; }
.tpl-admin-main { flex: 1; min-width: 0; display: flex; align-items: center; gap: 12px; }
.tpl-admin-info { flex: 1; min-width: 0; }
.tpl-admin-thumb {
  width: 56px; height: 56px; flex: none; object-fit: cover;
  border: 1px solid var(--line); border-radius: 6px; background: var(--ink);
}
.tpl-admin-thumb-empty {
  display: flex; align-items: center; justify-content: center;
  font-size: 10.5px; color: var(--text-3); letter-spacing: .02em;
}
.tpl-admin-name {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-size: 13px; font-weight: 600;
}
.tpl-admin-meta { font-size: 11px; color: var(--text-3); margin-top: 2px; word-break: break-all; }
.tpl-preview {
  display: block; max-width: 280px; max-height: 180px;
  object-fit: contain; border: 1px solid var(--line); border-radius: var(--r2);
  background: var(--ink);
}
.upd-admin-row {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 12px 0; border-top: 1px solid var(--line);
}
.upd-admin-row:first-child { border-top: none; }
.upd-admin-info { flex: 1; min-width: 0; }
.upd-admin-title {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-size: 13.5px; font-weight: 600;
}
.upd-admin-meta { font-size: 11px; color: var(--text-3); margin-top: 3px; }
.upd-admin-body {
  font-size: 12px; color: var(--text-2); margin-top: 6px;
  white-space: pre-wrap; overflow-wrap: anywhere;
}
.cert-admin-list { margin-top: 6px; }
.cert-admin-row {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 12px 0; border-top: 1px solid var(--line);
}
.cert-admin-row:first-child { border-top: none; }
.cert-admin-info { flex: 1; min-width: 0; }
.cert-admin-user {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  font-size: 13px; font-weight: 600;
}
.cert-admin-user .mono { font-size: 10.5px; color: var(--text-3); font-weight: 400; }
.cert-admin-subject {
  font-size: 12.5px; color: var(--text-2); margin-top: 2px;
  word-break: break-all;
}
.cert-admin-meta { font-size: 11px; color: var(--text-3); margin-top: 2px; }
.cert-admin-badges { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 5px; }
.cert-admin-actions {
  display: flex; align-items: center; justify-content: flex-end;
  gap: 6px; flex-wrap: wrap; flex: none;
}
.cert-admin-lock { font-size: 11px; white-space: nowrap; }

/* 配置页的两张卡片（主弹窗 / 卡密弹窗） */
.cfg-card {
  border: 1px solid var(--line); border-radius: 10px;
  margin: 0 0 14px; background: rgba(255,255,255,.015); overflow: hidden;
}
.cfg-card-head {
  display: flex; align-items: baseline; gap: 10px;
  padding: 11px 14px; border-bottom: 1px solid var(--line); background: rgba(255,255,255,.02);
}
.cfg-card-head h3 { margin: 0; font-size: 13.5px; font-weight: 600; color: var(--text); }
.cfg-card-head .muted { font-size: 11.5px; }
.cfg-card-body { padding: 4px 12px 8px; }
.cfg-card-body .cfg-group { border-bottom: none; }

/* 已用过的 Key：只读 + 复制 + 重新生成 */
.key-readonly { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.key-readonly .mono { color: var(--text-2); }

.note.warn-note { color: var(--live); }   /* 渠道包名不一致的告警：描成琥珀，别跟普通说明一个色 */

/* =========================================================
   管理员：全部 App（图标 + 目标包信息）
   ========================================================= */
.admin-apps-head {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 2px 0 10px;
}
.admin-apps-head input[type="search"] {
  flex: 1; min-width: 180px; height: 30px;
  background: var(--raised); color: var(--text);
  border: 1px solid var(--line); border-radius: var(--r1);
  padding: 4px 9px; font-size: 12.5px;
}
.admin-apps-head input[type="search"]:focus { outline: none; border-color: var(--channel); }
.admin-app-list { display: flex; flex-direction: column; }
.admin-app-row {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 10px 4px; border-top: 1px solid var(--line);
  cursor: pointer; border-radius: var(--r1);
}
.admin-app-row:first-child { border-top: none; }
.admin-app-row:hover { background: rgba(255,255,255,.025); }
.admin-app-row:focus-visible { outline: 2px solid var(--channel); outline-offset: 1px; }
.admin-app-icon {
  width: 44px; height: 44px; flex: none; overflow: hidden;
  border-radius: 10px; background: var(--raised);
  border: 1px solid var(--line);
  display: flex; align-items: center; justify-content: center;
}
.admin-app-icon img { width: 100%; height: 100%; object-fit: contain; }
.admin-app-icon-txt { font-size: 12px; color: var(--text-3); }
.admin-app-main { min-width: 0; flex: 1; }
.admin-app-title { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.admin-app-name { font-size: 13.5px; font-weight: 600; }
.admin-app-badges { display: flex; gap: 4px; flex-wrap: wrap; }
.admin-app-target { margin-top: 3px; font-size: 12px; color: var(--text-2); }
.admin-app-meta {
  display: flex; gap: 12px; flex-wrap: wrap;
  margin-top: 4px; font-size: 11px; color: var(--text-3);
}
