/* ==================================================================
   超管后台 · 区域样式
   只引用 tokens.css 令牌；不出现色值字面量、不新建版式语言
   ================================================================== */

/* ---------- 状态块（加载 / 空态 / 失败 / 成功） ---------- */
.hub-state{
  display:flex;align-items:center;gap:9px;
  padding:12px 14px;margin-top:12px;
  border:1px solid var(--line-soft);border-radius:var(--r-m);
  background:var(--wash);
  font-size:var(--t-sm);color:var(--t2);line-height:1.6;
}
.hub-state b{
  flex:none;display:grid;place-items:center;
  width:20px;height:20px;border-radius:999px;
  background:var(--card);border:1px solid var(--line);
  font-size:var(--t-xs);font-weight:500;color:var(--t1);
}
.hub-state.is-loading b{color:var(--blue);border-color:var(--blue-line)}
.hub-state.is-error{background:var(--red-soft);border-color:var(--red-soft);color:var(--red)}
.hub-state.is-error b{color:var(--red);border-color:var(--red-soft)}
.hub-state.is-ok{background:var(--ok-soft);border-color:var(--ok-soft);color:var(--ok)}
.hub-state.is-ok b{color:var(--ok);border-color:var(--ok-soft)}

/* ---------- 多行输入（回复 / 举报模板） ---------- */
textarea.input{
  height:auto;min-height:104px;padding:12px 14px;
  line-height:1.7;resize:vertical;
  font-family:var(--f-sans);font-size:var(--t-sm);
}
textarea.input[readonly]{background:var(--wash);color:var(--t1)}

/* ---------- 表格行内操作 ---------- */
.tbl .more{
  font-size:var(--t-xs);font-weight:500;color:var(--blue);
  white-space:nowrap;cursor:pointer;
}
.tbl .more:hover{color:var(--blue-hover)}
.tbl .more.is-red{color:var(--red)}
.tbl .more[disabled]{color:var(--t2);cursor:default;opacity:.6}
.tbl .who-p,.tbl td.num{overflow-wrap:anywhere}
.tbl td{vertical-align:middle}
.tbl .acts-cell{display:flex;align-items:center;gap:8px;justify-content:flex-end;flex-wrap:nowrap}
.tbl .acts-group{display:flex;align-items:center;gap:4px;flex-wrap:nowrap}

/* R3-021：危险操作（封停 · 删除）成组、与常规操作之间用一条竖线分隔。
   按钮本身的尺寸 / 内边距沿用 ui-fix.css 的全站行内操作标准（40px 热区、0 12px、12.5px），
   这里只负责分组与间距收敛，不再另起一套尺寸。 */
.tbl .acts-group--danger{padding-left:8px;border-left:1px solid var(--line-soft)}
.tbl td .acts-cell .acts-more{display:none}

/* 窄屏：常规操作收进「更多」下拉，危险操作始终显眼 */
@media (max-width:1100px){
  .tbl td .acts-cell .acts-more{display:inline-flex}
  .tbl .acts-cell:not(.is-open) .acts-group--normal{display:none}
  .tbl td.r{position:relative}
  .tbl .acts-cell.is-open .acts-group--normal{
    position:absolute;right:0;top:calc(100% - 2px);z-index:20;
    display:flex;flex-direction:column;align-items:stretch;gap:2px;
    padding:6px;border:1px solid var(--line);border-radius:var(--r-s);
    background:var(--card);box-shadow:var(--sh-1);
  }
}

/* ---------- 分页 ---------- */
.pager button[disabled]{opacity:.45;cursor:default}
.pager button[aria-current="true"]{color:var(--on-blue)}

/* ---------- 反馈卡内的回复区 ---------- */
.task-reply{
  display:flex;flex-direction:column;gap:10px;
  margin-top:12px;padding-top:12px;border-top:1px solid var(--line-soft);
}
.task-reply .u-row{gap:8px;flex-wrap:wrap}
.task-reply .select{
  width:auto;height:36px;font-size:var(--t-sm);padding:0 34px 0 12px;
  background-position:calc(100% - 17px) 16px,calc(100% - 12px) 16px;
}

/* ---------- 手动开通 / 反馈提交表单 ---------- */
.admin-form{display:flex;flex-direction:column;gap:12px}
.admin-form .u-row{gap:8px;flex-wrap:wrap}
.admin-form .select{height:46px}
.admin-form .btn{min-height:46px}

/* 飞书 Webhook 配置 */
.feishu-config-grid{align-items:stretch}
.feishu-switch-row{min-height:46px}
.feishu-events{margin:0;padding:0;border:0;min-width:0}
.feishu-events legend{margin-bottom:8px;font-size:var(--t-sm);font-weight:500;color:var(--ink)}
.feishu-event-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}
.feishu-actions{display:flex;align-items:center;justify-content:flex-end;gap:8px;flex-wrap:wrap}
.feishu-time,.feishu-detail{overflow-wrap:anywhere;text-align:right}
@media (max-width:680px){
  .feishu-event-grid{grid-template-columns:minmax(0,1fr)}
  .feishu-actions .btn{flex:1 1 0;min-width:0}
}

/* ---------- 前台「我的反馈」列表 ---------- */
.fb-item{border-top:1px solid var(--line-soft);padding:12px 0}
.fb-item:first-child{border-top:none;padding-top:0}
.fb-item .fb-t{
  display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  font-size:var(--t-sm);font-weight:500;color:var(--ink);
}
.fb-item .fb-b{
  margin-top:6px;font-size:var(--t-xs);color:var(--t2);
  line-height:1.7;overflow-wrap:anywhere;white-space:pre-wrap;
}

@media (max-width:680px){
  .tbl .acts-cell{justify-content:flex-start}
}

/* 账号管理表格：固定列宽 + 对齐修正（2026-10-21） */
.tbl--users{table-layout:fixed;width:100%}
/* R3-021：操作列按按钮实际宽度给固定像素宽，前面的列按比例瓜分剩余空间，
   这样 1440 下「设为管理员 / 封停 / 删除」能排在一行且不被裁切。
   R4-031：① 操作列收紧到按钮组实际宽度（不再多出 150px 空白），②「注册时间 /
   最近登录」两列右对齐并吃掉省下的空间，让最近登录信息与操作按钮贴到一起，
   ③ 每行给统一的加高行高，9 行高低一致不再参差。 */
.tbl--users th:nth-child(1),.tbl--users td:nth-child(1){width:13%}
.tbl--users th:nth-child(2),.tbl--users td:nth-child(2){width:20%}
.tbl--users th:nth-child(3),.tbl--users td:nth-child(3){width:9%}
.tbl--users th:nth-child(4),.tbl--users td:nth-child(4){width:8%}
.tbl--users th:nth-child(5),.tbl--users td:nth-child(5){width:10%;text-align:right}
.tbl--users th:nth-child(6),.tbl--users td:nth-child(6){width:10%;text-align:right}
.tbl--users th:nth-child(7),.tbl--users td:nth-child(7){width:240px}
/* R4-031 ②：每行统一给 132px 行高（原先内容少时只有 122px，高低参差） */
.tbl--users tbody tr{height:132px}
@media (min-width:1401px){
  /* R4-031 ①：宽桌面下把「注册时间 / 最近登录」两列加宽并右对齐，
     同时把操作列从「吃掉全部剩余宽度」收紧到按钮组实际宽度（24% ≈ 313px @1440），
     最近登录的值与操作按钮之间的距离从 ~150px 收到 ~55px。 */
  .tbl--users th:nth-child(1),.tbl--users td:nth-child(1){width:13%}
  .tbl--users th:nth-child(2),.tbl--users td:nth-child(2){width:20%}
  .tbl--users th:nth-child(3),.tbl--users td:nth-child(3){width:9%}
  .tbl--users th:nth-child(4),.tbl--users td:nth-child(4){width:8%}
  .tbl--users th:nth-child(5),.tbl--users td:nth-child(5){width:12%;text-align:right}
  .tbl--users th:nth-child(6),.tbl--users td:nth-child(6){width:14%;text-align:right}
  .tbl--users th:nth-child(7),.tbl--users td:nth-child(7){width:24%}
}
@media (max-width:1100px){
  .tbl--users th:nth-child(7),.tbl--users td:nth-child(7){width:200px}
  .tbl--users th:nth-child(6),.tbl--users td:nth-child(6){width:12%}
  .tbl--users tbody tr{height:120px}
}
/* 390：账号表格在卡片内横向滚动，操作区不被裁切，页面本身不产生横向溢出 */
@media (max-width:680px){
  .panel.u-flush{overflow-x:auto}
  .tbl--users{min-width:840px}
  .tbl--users th:nth-child(1),.tbl--users td:nth-child(1){width:120px}
  .tbl--users th:nth-child(2),.tbl--users td:nth-child(2){width:170px}
  .tbl--users th:nth-child(3),.tbl--users td:nth-child(3){width:80px}
  .tbl--users th:nth-child(4),.tbl--users td:nth-child(4){width:70px}
  .tbl--users th:nth-child(5),.tbl--users td:nth-child(5){width:95px}
  .tbl--users th:nth-child(6),.tbl--users td:nth-child(6){width:95px}
  .tbl--users th:nth-child(7),.tbl--users td:nth-child(7){width:210px}
}
.tbl--users td{vertical-align:middle}
.tbl--users td.muted{color:var(--t2);font-family:var(--f-sans)}

/* 运维日志行 */
.logline{font-family:var(--f-mono);font-size:var(--t-xs);line-height:1.6;padding:6px 0;border-bottom:1px dashed var(--line-soft);overflow-wrap:anywhere}
.logline:last-child{border-bottom:none}
.logline.is-red{color:var(--red)}

/* R3-023：日志并入「运行信息」，默认 5 条 + 折叠，展开后限高滚动 */
.wx-log{margin-top:14px;padding-top:12px;border-top:1px solid var(--line-soft)}
.wx-log-hd{display:flex;align-items:center;justify-content:space-between;gap:10px}
.wx-log-hd .note-ink{font-size:var(--t-sm)}
.wx-log-list{margin-top:8px}
.wx-log-list .logline.is-extra{display:none}
.wx-log-list.is-open{
  max-height:260px;overflow-y:auto;overscroll-behavior:contain;
  -webkit-overflow-scrolling:touch;padding-right:6px;
}
.wx-log-list.is-open .logline.is-extra{display:block}

/* VIP 页面布局：等级分布 +「VIP 开通与到期」上下两块，R3-022 合并后不再用双列栅格 */
.vip-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:var(--gap);align-items:start}
@media (max-width:900px){.vip-grid{grid-template-columns:1fr}}
/* R3-022：开通表单 用户 / 等级 / 时长 / 备注 一行排开，窄屏两列再单列 */
.vip-grant-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;align-items:end}
.vip-user-row{display:flex;align-items:center;gap:8px}
.vip-user-row .input{flex:1 1 auto;min-width:0}
.vip-user-row .btn{flex:0 0 auto}
@media (max-width:1100px){.vip-grant-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:640px){.vip-grant-grid{grid-template-columns:1fr}}
.vip-table-wrap{overflow-x:auto}
.vip-row-actions{display:flex;gap:6px;justify-content:flex-end;flex-wrap:wrap}

/* 收藏玩家 / 监控任务行：图标与文字分离，避免挤在一起 */
.acct-row + .acct-row{margin-top:2px}
.acct-row .hub-state{width:100%}

/* R13-G13：模块区改为 4 列，8 个入口成 4×2 规整网格（含置灰的「待开发」占位） */
.tools{grid-template-columns:repeat(4,minmax(0,1fr))}
@media (max-width:1180px){ .tools{grid-template-columns:repeat(3,minmax(0,1fr))} }
@media (max-width:820px){ .tools{grid-template-columns:repeat(2,minmax(0,1fr))} }
@media (max-width:520px){ .tools{grid-template-columns:minmax(0,1fr)} }
.admin-feature-head{display:flex;align-items:flex-start;justify-content:space-between;gap:14px}
.admin-feature-head .note-h{margin-top:3px;font-size:var(--t-h3);font-weight:600}
.admin-feature-kicker{display:block;font-size:var(--t-xs);color:var(--blue);font-weight:500}
.admin-feature-foot{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  flex-wrap:wrap;margin-top:auto;padding-top:16px;
}
.module-empty{
  padding:24px 16px;text-align:center;color:var(--t2);
  font-size:var(--t-sm);line-height:1.7;
}

/* VP 雷达 */
.vp-summary{
  display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  gap:8px;margin-top:16px;
}
.vp-summary > div{
  padding:12px 8px;border-radius:var(--r-m);background:var(--wash);
  text-align:center;min-width:0;
}
.vp-summary strong{
  display:block;font-family:var(--f-mono);font-size:var(--t-h3);
  font-weight:500;color:var(--ink);font-variant-numeric:tabular-nums;
}
.vp-summary span{display:block;margin-top:2px;font-size:var(--t-xs);color:var(--t2)}
.vp-instances{display:flex;flex-direction:column;gap:10px;margin-top:14px}
.vp-instance{
  padding:14px;border:1px solid var(--line);border-radius:var(--r-m);
  background:var(--card);
}
.vp-instance.is-online{border-color:var(--ok)}
.vp-instance.is-degraded{border-color:var(--warn)}
.vp-instance.is-offline{border-color:var(--red)}
.vp-instance-head{display:flex;align-items:flex-start;justify-content:space-between;gap:10px}
.vp-instance-name{min-width:0}
.vp-instance-name strong{display:block;font-size:var(--t-sm);font-weight:500;color:var(--ink)}
.vp-instance-name span{display:block;margin-top:2px;font-size:var(--t-xs);color:var(--t2);overflow-wrap:anywhere}
.vp-instance-facts{
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:8px;margin-top:12px;
}
.vp-instance-facts div{padding:9px;border-radius:var(--r-s);background:var(--wash)}
.vp-instance-facts span{display:block;font-size:var(--t-xs);color:var(--t2)}
.vp-instance-facts strong{display:block;margin-top:2px;font-family:var(--f-mono);font-size:var(--t-xs);font-weight:500;color:var(--ink);overflow-wrap:anywhere}
.vp-endpoint{
  display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;
  gap:8px;margin-top:9px;min-width:0;
}
.vp-endpoint > span{font-size:var(--t-xs);color:var(--t2);white-space:nowrap}
.vp-endpoint code{
  min-width:0;padding:7px 9px;border-radius:var(--r-s);background:var(--wash);
  font-family:var(--f-mono);font-size:var(--t-xs);color:var(--t1);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.vp-reason{margin-top:9px;font-size:var(--t-xs);color:var(--t2);line-height:1.6}

/* 玩家核查（表单 + 官方事实 + 举报模板；R3-025 后只在 admin-reports.html 使用） */
.vp-view{display:flex;flex-direction:column;min-width:0;margin-top:12px}
.vp-view[hidden]{display:none}
.vp-check-form{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:end;gap:10px}
.vp-check-form .btn{padding-block:10px}
.vp-check-facts{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:8px;margin-top:12px}
.vp-check-facts > div{padding:10px 11px;border-radius:var(--r-s);background:var(--wash);min-width:0}
.vp-check-facts span{display:block;font-size:var(--t-xs);color:var(--t2)}
.vp-check-facts strong{
  display:block;margin-top:3px;font-family:var(--f-mono);font-size:var(--t-xs);
  font-weight:500;color:var(--ink);overflow-wrap:anywhere;
}
.vp-template{margin-top:12px;min-width:0}
.vp-template-foot{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:8px}
.vp-template-foot .note{flex:1 1 auto;min-width:0}
.feature-details{margin-top:14px;border-top:1px solid var(--line-soft);padding-top:12px}
.feature-details summary{cursor:pointer;font-size:var(--t-xs);font-weight:500;color:var(--t1)}
.feature-details p{margin-top:8px;font-size:var(--t-xs);color:var(--t2);line-height:1.7}

/* 社交 */
.social-self{
  display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;
  gap:8px;margin-top:14px;padding:10px 12px;border-radius:var(--r-m);background:var(--wash);
}
.social-self > span{font-size:var(--t-xs);color:var(--t2)}
.social-self code{
  min-width:0;font-family:var(--f-mono);font-size:var(--t-xs);color:var(--t1);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.social-tabs{display:flex;gap:3px;margin-top:14px;padding:3px;border-radius:999px;background:var(--wash)}
.social-tabs button{
  flex:1;min-height:36px;padding:7px 9px;border-radius:999px;
  font-size:var(--t-xs);color:var(--t2);white-space:nowrap;
}
.social-tabs button[aria-selected=true]{background:var(--card);color:var(--ink);font-weight:500;box-shadow:var(--sh-1)}
#social-request-count{display:inline-grid;place-items:center;min-width:18px;height:18px;margin-left:3px;border-radius:999px;background:var(--red-soft);color:var(--red);font-family:var(--f-mono)}
#social-request-count[hidden]{display:none}
.social-view{display:flex;flex-direction:column;gap:8px;min-height:158px;margin-top:12px}
.social-view[hidden],.social-chat[hidden]{display:none}
.social-user-row{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:11px 0;border-bottom:1px solid var(--line-soft);
}
.social-user-row:last-child{border-bottom:none}
.social-user-info{display:flex;align-items:center;gap:9px;min-width:0}
.social-avatar{
  width:34px;height:34px;flex:0 0 auto;border-radius:50%;overflow:hidden;
  display:grid;place-items:center;background:var(--blue-soft);color:var(--blue);
  font-family:var(--f-mono);font-size:var(--t-xs);font-weight:500;
}
.social-avatar img{width:100%;height:100%;object-fit:cover;display:block}
.social-user-copy{min-width:0}
.social-user-copy strong{display:block;font-size:var(--t-sm);font-weight:500;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.social-user-copy span{display:block;margin-top:2px;font-size:var(--t-xs);color:var(--t2)}
.social-user-actions{display:flex;align-items:center;justify-content:flex-end;gap:4px;flex-wrap:wrap}
.social-user-actions .btn{padding-inline:10px}
.social-chat{margin-top:12px;border:1px solid var(--line);border-radius:var(--r-m);overflow:hidden}
.social-chat > header{display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:8px;padding:9px;border-bottom:1px solid var(--line-soft);background:var(--wash)}
.social-chat > header strong{text-align:center;font-size:var(--t-sm);font-weight:500;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.social-messages{display:flex;flex-direction:column;gap:8px;min-height:190px;max-height:260px;overflow-y:auto;padding:12px}
.social-message{align-self:flex-start;max-width:82%;padding:9px 11px;border-radius:var(--r-m);background:var(--wash)}
.social-message.is-self{align-self:flex-end;background:var(--blue-soft)}
.social-message p{font-size:var(--t-sm);color:var(--t1);line-height:1.55;white-space:pre-wrap;overflow-wrap:anywhere}
.social-message footer{display:flex;align-items:center;justify-content:flex-end;gap:7px;margin-top:4px}
.social-message small{font-size:var(--t-xs);color:var(--t2)}
.social-message button{font-size:var(--t-xs);color:var(--blue)}
.social-chat-form{padding:10px;border-top:1px solid var(--line-soft)}
.social-chat-form > label{font-size:var(--t-xs);font-weight:500;color:var(--ink)}
.social-compose{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:end;gap:8px;margin-top:6px}
.social-compose textarea{min-height:66px;max-height:130px}
.social-compose .btn{min-height:42px}

@media (max-width:980px){
  .vp-instance-facts{grid-template-columns:1fr 1fr}
}
@media (max-width:768px){
  .social-view{min-height:120px}
}
@media (max-width:520px){
  .vp-check-form{grid-template-columns:1fr}
  .vp-summary{grid-template-columns:1fr 1fr}
  .vp-endpoint,.social-self{grid-template-columns:1fr auto}
  .vp-endpoint > span,.social-self > span{grid-column:1/-1}
  .social-user-row{align-items:flex-start;flex-direction:column}
  .social-user-actions{justify-content:flex-start}
  .social-compose{grid-template-columns:1fr}
  .social-compose .btn{width:100%}
}

/* ==================================================================
   AUTH 闸门：未登录 / 非超管不渲染后台布局，只给登录引导卡
   ================================================================== */
html.admin-gate-pending main{display:none}
.admin-gate{padding:clamp(28px,6vw,72px) 0}
.admin-gate-card{
  max-width:520px;margin:0 auto;padding:30px 26px;text-align:center;
  background:var(--card);border:1px solid var(--line-soft);
  border-radius:var(--r-l);box-shadow:var(--sh-1);
}
.admin-gate-ico{
  display:grid;place-items:center;width:44px;height:44px;margin:0 auto 14px;
  border-radius:999px;background:var(--blue-soft);
}
.admin-gate-ico svg{
  width:22px;height:22px;stroke:var(--blue);stroke-width:1.8;fill:none;
  stroke-linecap:round;stroke-linejoin:round;
}
.admin-gate-t{font-size:var(--t-h3);font-weight:600;color:var(--ink)}
.admin-gate-d{margin-top:8px;font-size:var(--t-sm);color:var(--t2);line-height:1.7}
.admin-gate-who{margin-top:10px;overflow-wrap:anywhere}
.admin-gate-acts{display:flex;justify-content:center;gap:10px;flex-wrap:wrap;margin-top:18px}
.admin-gate-acts .btn{min-width:104px}

/* ==================================================================
   R13-G13：VP雷达 / 社交 移回模块区，作为普通 .tool 入口卡；
   button.tool 与 a.tool 外观完全一致，「待开发」是置灰不可点的占位。
   ================================================================== */
button.tool{
  width:100%;min-width:0;border:0;appearance:none;
  font:inherit;color:inherit;cursor:pointer;
}
button.tool:focus-visible{outline:2px solid var(--blue);outline-offset:2px}
.tool.is-todo{
  cursor:default;
  background:var(--wash);box-shadow:inset 0 0 0 1px var(--line);
}
.tool.is-todo:hover{transform:none;box-shadow:inset 0 0 0 1px var(--line)}
.tool.is-todo .tool-i{background:var(--wash-deep)}
.tool.is-todo .tool-i svg{stroke:var(--t2)}
.tool.is-todo .tool-t{color:var(--t2)}
.tool.is-todo .tool-d{color:var(--t2)}

/* 弹层：承载收起前的全部功能
   admin.html 不引 misc.css，这里按同一套基线结构把弹层样式局部实现一遍，
   只作用于 .admin-modal，不影响其它页面。 */
.admin-modal{
  position:fixed;inset:0;z-index:300;
  display:flex;align-items:center;justify-content:center;
  padding:clamp(14px,3vw,32px);
}
.admin-modal[hidden]{display:none}
.admin-modal .modal-mask{position:absolute;inset:0;background:var(--mask)}
.admin-modal .modal-card{
  position:relative;width:min(880px,100%);
  max-height:calc(100vh - clamp(28px,6vw,64px));
  display:flex;flex-direction:column;
  background:var(--card);border-radius:var(--r-l);
  box-shadow:var(--sh-2);overflow:hidden;
}
.admin-modal .modal-hd{
  padding:18px 24px;border-bottom:1px solid var(--line-soft);
  display:flex;align-items:flex-start;justify-content:space-between;gap:12px;
}
.admin-modal .modal-hd h2{font-size:var(--t-h3);font-weight:600;color:var(--ink)}
.admin-modal .modal-hd p{margin-top:3px;font-size:var(--t-xs);color:var(--t2)}
.admin-modal .modal-bd{padding:18px 24px;overflow-y:auto;flex:1;-webkit-overflow-scrolling:touch}
.admin-modal .modal-ft{
  padding:14px 24px;border-top:1px solid var(--line-soft);
  display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap;
}
@media (max-width:680px){
  .admin-modal{padding:0;align-items:flex-end}
  .admin-modal .modal-card{
    width:100%;max-height:92svh;border-radius:var(--r-l) var(--r-l) 0 0;
  }
  .admin-modal .modal-bd{padding:16px 18px}
  .admin-modal .modal-hd{padding:16px 18px}
  .admin-modal .modal-ft{padding:12px 18px}
}
.admin-modal-body{min-width:0}
.admin-modal-body .admin-feature-foot{
  margin-top:14px;padding-top:14px;border-top:1px solid var(--line-soft);
}
.admin-modal-body .vp-view,.admin-modal-body .social-view{margin-top:12px}
/* R25-5：弹层内的表头不吸顶。
   ui-fix.css 给 table thead th 设了 position:sticky + top:var(--hd-h)，
   弹层是滚动容器，表头会被下推到页头高度之外、贴顶时跑出可视区。
   模块内的表格一律不吸顶（与 admin-users / admin-vip 的做法一致）。 */
.admin-modal-body table thead th{position:static}
/* 窄屏下表格锁在弹层宽度内，长明细在单元格内换行，不撑出横向滚动条。
   table.tbl 的 min-width:max-content 必须显式改回 0，否则 table-layout:fixed
   算出的列宽不生效，表格仍按 542px 撑开。 */
@media (max-width:720px){
  .admin-modal-body table.tbl{table-layout:fixed;width:100%;min-width:0}
  .admin-modal-body table.tbl td,
  .admin-modal-body table.tbl th{overflow-wrap:anywhere;white-space:normal}
}
body.is-modal-open{overflow:hidden}


/* ==================================================================
   R4-034：延迟删除 —— 10 秒红色倒计时条 + 取消删除
   点删除不立即发请求：行置灰并标记「即将删除」，条从右向左缩短，
   到点才提交 DELETE；期间点「取消删除」整行恢复。
   ================================================================== */
tr.is-deleting,.social-user-row.is-deleting{opacity:.55}
tr.is-deleting .who-n{text-decoration:line-through}
.del-mark{margin-left:8px;white-space:nowrap}
.del-bar-row td{padding:0 12px 10px}
.del-bar-row{padding:6px 0}
.del-bar-wrap{
  display:flex;align-items:center;gap:10px;
  padding:8px 10px;border-radius:var(--r-m);
  background:var(--red-soft);border:1px solid var(--red-soft);
}
.del-bar-txt{flex:0 1 auto;min-width:0;font-size:var(--t-xs);font-weight:500;color:var(--red);overflow-wrap:anywhere}
.del-bar{
  position:relative;flex:1 1 auto;min-width:64px;height:8px;
  border-radius:999px;background:var(--card);overflow:hidden;
}
.del-bar-fill{
  position:absolute;left:0;top:0;bottom:0;width:100%;
  border-radius:999px;background:var(--red);
  /* 靠左锚定、宽度 100% → 0：视觉上右边缘向左收缩 */
  transition:width 10s linear;
}
.del-bar-fill.is-running{width:0}
.del-bar-sec{flex:none;font-size:var(--t-xs);color:var(--red);font-variant-numeric:tabular-nums}
.del-bar-cancel{
  flex:none;min-height:28px;padding:4px 12px;
  font-size:var(--t-xs);font-weight:500;color:var(--t1);
  background:var(--card);border:1px solid var(--line);border-radius:var(--r-m);
  cursor:pointer;white-space:nowrap;
}
.del-bar-cancel:hover{border-color:var(--blue-line);color:var(--blue)}
.del-bar-cancel:focus-visible{outline:2px solid var(--blue);outline-offset:2px}
@media (max-width:680px){
  .del-bar-wrap{flex-wrap:wrap}
  .del-bar-txt{flex:1 1 100%}
}

/* ==================================================================
   R4-035：权限管理（admin-roles.html）
   ================================================================== */
.roles-form{display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:14px}
.roles-form .field{flex:1 1 220px;min-width:0}
@media (max-width:680px){
  .roles-form .btn{width:100%}
}


/* ==================================================================
   R21：微信机器人控制台（wechat-bot.html）
   ================================================================== */
.wx-ctl-body{display:flex;flex-direction:column;gap:12px;padding:14px}
.wx-ctl-actions{display:flex;flex-wrap:wrap;gap:8px}
.wx-ctl-msg{min-height:1.5em;overflow-wrap:anywhere}
.wx-ctl-msg.is-ok{color:var(--ok)}
.wx-ctl-msg.is-red{color:var(--red)}
.wx-ctl-msg.is-warn{color:var(--warn)}
.wx-login-box{display:flex;align-items:flex-start;gap:16px;flex-wrap:wrap;padding-top:4px}
.wx-login-box[hidden]{display:none}
.wx-qr{flex:none;width:220px;height:220px;display:flex;align-items:center;justify-content:center;border:1px solid var(--line);border-radius:var(--r-m);background:var(--qr-bg);overflow:hidden}
.wx-qr img{display:block;width:200px;height:200px;object-fit:contain}
.wx-qr-meta{display:flex;flex-direction:column;gap:8px;min-width:0;flex:1 1 180px}
#wx-strip{flex:0 0 100%}
@media (max-width:680px){
  .wx-ctl-actions .btn{flex:1 1 calc(50% - 8px);min-width:0}
  .wx-qr{width:100%;max-width:260px;height:auto;aspect-ratio:1}
  .wx-qr img{width:100%;height:auto}
}

/* 远程操控：截图面板 + 所见即点 + 自动登录巡航 */
.wx-view-body{display:flex;flex-direction:column;gap:12px;padding:14px}
.wx-view-bar{display:flex;flex-wrap:wrap;align-items:center;gap:8px}
.wx-view-bar .note{margin-left:auto}
.wx-auto{display:inline-flex;align-items:center;gap:6px;font-size:.85rem;color:var(--t2);cursor:pointer}
.wx-stage{position:relative;border:1px solid var(--line);border-radius:var(--r-m);overflow:hidden;background:var(--stage-bg);line-height:0}
.wx-stage img{display:block;width:100%;height:auto;cursor:crosshair}
.wx-stage.is-empty img{opacity:0}
.wx-cross{position:absolute;width:1px;height:1px;pointer-events:none}
.wx-cross::before,.wx-cross::after{content:"";position:absolute;background:var(--adm-ok)}
.wx-cross::before{left:-999px;right:-999px;top:0;height:1px}
.wx-cross::after{top:-999px;bottom:-999px;left:0;width:1px}
.wx-coord{position:absolute;transform:translate(8px,-50%);padding:1px 6px;border-radius:4px;background:var(--scrim-72);color:var(--on-scrim);font-size:.72rem;line-height:1.6;pointer-events:none;white-space:nowrap}
.wx-hot{position:absolute;border:3px solid var(--adm-warn);border-radius:6px;box-shadow:0 0 0 9999px var(--scrim-45);pointer-events:none;animation:wx-hot 1.2s ease-in-out infinite}
@keyframes wx-hot{0%,100%{opacity:.55}50%{opacity:1}}
.wx-scan{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:var(--scrim-62);padding:12px}
.wx-scan[hidden]{display:none}
.wx-scan-box{display:flex;flex-direction:column;align-items:center;gap:10px;padding:14px;border-radius:var(--r-m);background:var(--card);max-width:100%}
.wx-scan-box strong{font-size:1.05rem;line-height:1.4;text-align:center}
.wx-scan-qr{width:260px;height:260px;max-width:60vw;max-height:60vw;border-radius:8px;background:var(--qr-bg) center no-repeat;background-size:cover}
.wx-steps{max-height:220px;overflow-y:auto}
.wx-step{display:flex;flex-wrap:wrap;gap:8px;align-items:baseline;padding:4px 0;border-bottom:1px solid var(--line);font-size:.85rem}
.wx-step:last-child{border-bottom:0}
.wx-step .t{color:var(--t2);font-variant-numeric:tabular-nums}
.wx-step .k{flex:none;padding:0 6px;border-radius:4px;background:var(--wash);font-size:.75rem}
.wx-step.is-ok .k{color:var(--ok)}
.wx-step.is-warn .k{color:var(--warn)}
.wx-step.is-red .k{color:var(--red)}
.wx-step .a{min-width:0;flex:1 1 240px;overflow-wrap:anywhere}
@media (max-width:680px){
  .wx-view-bar .note{margin-left:0;flex:1 1 100%}
  .wx-scan-qr{width:min(260px,72vw);height:min(260px,72vw)}
}

/* ==================================================================
   R26-2 · 运维弹层（#modal-ops）布局
   ------------------------------------------------------------------
   修复前实测（超管真机 1440x900 / 390x844 打开弹层）：
     1. 内容总高 2871px / 2676px，弹层可视区只有 674px / 598px —— 要滚 4~5 屏
        才能看到底部的「打开完整运维页」，核心信息全埋在滚动里；
     2. 六格概览沿用默认 .minis 四列，880px 弹层里排成 4+2 断行，末行空一半；
     3. 概览值字号 --t-h3（17~19px），390px 下「2026/10/28 15:17:27」在
        172px 的格子里挤成两行且贴边；
     4. 四个区块只是 panel-h + stack 平铺，没有卡片边界，一整片白底行线，
        区块之间层次不清（整页 admin-ops.html 是 .panel 卡片，两处观感不一致）；
     5. 「刷新」「打开完整运维页」压在内容最底部，不滚到底根本见不到。
   修法（信息一个不删：6 个概览 + 4 个区块 + 2 张表全在）：
     · 概览改 3 列 × 2 行（窄屏 2 列 × 3 行），值降到 --t-sm 并允许换行；
     · 四个区块各包一张浅色卡片，宽屏两列并排（内容高度减半），窄屏单列；
     · 刷新提到弹层页头，打开完整运维页提到弹层页脚，两者都常驻不随内容滚动。
   颜色只用 tokens 的 --wash / --card / --line-soft，不引入新色、不加黑底。
   ================================================================== */
.admin-modal-body .ops-overview{margin-bottom:12px}
.admin-modal-body .ops-blocks{
  display:grid;gap:12px;grid-template-columns:minmax(0,1fr);
}
/* 880px 弹层里两列并排：block1+block2 一行、block3+block4 一行 */
@media (min-width:900px){
  .admin-modal-body .ops-blocks{grid-template-columns:repeat(2,minmax(0,1fr));align-items:start}
}
.admin-modal-body .ops-block{
  margin:0;min-width:0;
  padding:14px 16px;border-radius:var(--r-md);
  background:var(--wash);
  box-shadow:inset 0 0 0 1px var(--line-soft);
}
.admin-modal-body .ops-block > .panel-h{margin-bottom:8px}
/* .stack 的行距是 --gap（18~28px），30 行键值会撑成一堵墙；运维区块内收紧到 8px */
.admin-modal-body .ops-block > .stack{gap:8px}
body[data-page="admin-ops"] .panel > .stack{gap:10px}
.admin-modal-body .ops-block > .stack + .table-scroll,
.admin-modal-body .ops-block > .table-scroll + .note,
.admin-modal-body .ops-block > .stack + .note{margin-top:10px}
.admin-modal-body .ops-block .note{margin-top:10px;line-height:1.6}

/* 概览六格 */
.admin-modal-body .minis{
  display:grid;gap:10px;
  grid-template-columns:repeat(3,minmax(0,1fr));
}
.admin-modal-body .mini{
  padding:11px 13px;border-radius:var(--r-md);
  background:var(--wash);
  box-shadow:inset 0 0 0 1px var(--line-soft);
}
.admin-modal-body .mini .v{
  font-size:var(--t-sm);font-weight:600;line-height:1.35;
  white-space:normal;overflow-wrap:anywhere;
}
.admin-modal-body .mini .k{margin-top:3px;line-height:1.4}
@media (max-width:720px){
  .admin-modal-body .minis{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:380px){
  .admin-modal-body .minis{gap:8px}
  .admin-modal-body .mini{padding:10px 11px}
}

/* 页头 / 页脚的操作区：刷新与「打开完整运维页」常驻，不随内容滚动 */
.admin-modal .modal-hd .acts,
.admin-modal .modal-ft .acts{
  display:flex;align-items:center;gap:8px;flex-shrink:0;flex-wrap:wrap;justify-content:flex-end;
}
.admin-modal .modal-hd .acts{margin-left:auto}
@media (max-width:680px){
  .admin-modal .modal-ft .note{display:none}
  .admin-modal .modal-ft .acts{flex:1 1 100%;justify-content:stretch}
  .admin-modal .modal-ft .acts .btn{flex:1 1 0;justify-content:center}
}

/* 整页 admin-ops.html 的六格概览与弹层口径一致：3 列 × 2 行，
   超宽屏（>=1400px）再拉成一行 6 列，窄屏 2 列。 */
body[data-page="admin-ops"] .minis{grid-template-columns:repeat(3,minmax(0,1fr))}
@media (min-width:1400px){
  body[data-page="admin-ops"] .minis{grid-template-columns:repeat(6,minmax(0,1fr))}
}
@media (max-width:720px){
  body[data-page="admin-ops"] .minis{grid-template-columns:repeat(2,minmax(0,1fr))}
}
