/* ============================================================
   大时钟 · 授权控制台样式表

   这是**单一样式表**，不是多层主题叠加。早期版本用「末尾追加覆盖层」的方式换肤，
   被覆盖的死声明已经清理掉（见 docs/变更与设计记录.md）。阅读顺序即分节顺序：

     一、压缩基座：重置、全局字体、通用按钮            （文件最前）
     二、基线细化：字体、按钮、登录页
     三、页内弹窗（替代浏览器原生 alert）
     四、页面背景
     五、账号列表布局
     六、组件精修：按钮体系、统计卡、表格、状态徽章
     七、后台视觉基线：卡片、筛选、表格、弹窗、账号详情
     八、当前主题：蓝紫白毛玻璃（配色与材质令牌集中在第八节的 :root）
     九、顶栏页签

   覆盖只依赖一条常规 CSS 规则：同选择器、后写胜出。跨选择器的特异性（例如
   .tabs .tab 高于 .tab）是有意为之，改动前先确认它压住了哪条更宽的规则。
   新增样式请写到对应分节，不要再另起一个覆盖层。
   ============================================================ */


*{box-sizing:border-box}html,body{margin:0;min-height:100%;color:var(--ink);font-family:"Segoe UI","Microsoft YaHei",sans-serif;font-size:14px;letter-spacing:0}button,input,select{font:inherit;letter-spacing:0}button{cursor:pointer}.hidden{display:none!important}
.brand-mark{display:grid;place-items:center;width:42px;height:42px;border-radius:4px;font-weight:900;font-size:16px}.brand-mark.small{width:34px;height:34px;font-size:12px}
.eyebrow{font-size:10px;font-weight:800}.panel-label{font-size:10px;font-weight:900;letter-spacing:.12em}.muted,.subheading{font-size:12px}.login-panel>label,.tool-panel label{display:block;margin-top:22px;font-size:11px;font-weight:800}.login-panel input,.tool-panel input{display:block;width:100%;height:42px;margin-top:7px;padding:0 12px;border:1px solid var(--line);border-radius:4px;outline:0;background:#fbfcfa;color:var(--ink)}.wide{width:100%;margin-top:24px}.message{min-height:24px;margin-top:14px;font-size:11px;line-height:1.5}.login-hint{font-size:10px}
.topbar{display:flex;align-items:center}.top-brand{display:flex;align-items:center}.top-brand strong{display:block}.top-brand small{display:block;margin-top:3px;font-size:10px}.tabs{height:100%;display:flex}.tab{position:relative;border:0;background:transparent}.tab.active:after{content:"";position:absolute}.admin-tools{display:flex;align-items:center;gap:10px;margin-left:auto;font-size:11px}.top-button{height:30px;padding:0 10px;color:#d5dfdb;border-color:#53636a;font-size:10px}.live-dot{display:inline-block;width:7px;height:7px;border-radius:50%}
.page{margin:0 auto}.page-heading{display:flex;justify-content:space-between;align-items:flex-end;gap:20px}.page-heading h1{margin:9px 0 0}.heading-actions{display:flex;gap:12px}.refresh-state{font-size:11px}.stat-grid{display:grid;grid-template-columns:repeat(4,1fr)}.stat-card{padding:13px 15px}.stat-card strong{display:block;margin-top:4px}.section-title{display:flex;align-items:baseline;gap:12px}.section-title h2{margin:0 0 8px}.section-title span{font-size:10px}.segmented{display:flex;gap:2px}.segment{padding:0 16px;border:1px solid var(--line);font-size:11px}.table-panel{overflow:hidden;border:1px solid #dce4e1}.filters{display:flex;align-items:center}.search{display:flex;width:240px;height:36px;border:1px solid var(--line);border-radius:4px}.search span{padding-left:10px;color:#8a9795;line-height:1}.search input{width:100%;height:100%;padding:0 9px;border:0;outline:0}.filters select{height:36px;padding:0 27px 0 10px;border:1px solid var(--line);border-radius:4px;outline:0;color:#63706f;background:#fff}.result-count{margin-left:auto;font-size:10px}.table-scroll{overflow:auto}table{width:100%;border-collapse:collapse}th,td{text-align:left;white-space:nowrap}.account-cell{display:flex;align-items:center}.avatar{display:grid;place-items:center;color:#fff;font-size:11px;font-weight:900}.account-id{display:block;margin-top:2px}.note-cell{max-width:130px;overflow:hidden;text-overflow:ellipsis}.status{display:inline-flex;align-items:center;border:1px solid #bddccf}.status:before{content:"";border-radius:50%;background:currentColor}.row-actions button{height:27px;padding:0 7px;border:1px solid #cfd8d5;border-radius:3px;font-size:10px}.row-actions .danger{color:#bd5d61;border-color:#e4c4c5}.empty{padding:45px;text-align:center;font-size:12px}
.code-layout{display:grid}.tool-panel{border:1px solid #dce4e1;border-radius:4px;background:#fff}.tool-panel h2,.panel-toolbar h2{margin:0;font-size:16px}.tool-panel select{display:block;width:100%;height:42px;margin-top:7px;padding:0 12px;border:1px solid var(--line);border-radius:4px;outline:0;background:#fbfcfa;color:var(--ink)}.field-hint{margin-top:7px;color:#8b9793;font-size:10px}.code-table .panel-toolbar{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:16px;border-bottom:1px solid var(--line)}.panel-toolbar h2{margin-bottom:5px}.panel-actions{display:flex;align-items:center;gap:6px}.selection-count{color:#8b9793;font-size:10px}.code-table .table-scroll{overflow:visible}.code-table table{width:100%;min-width:0;table-layout:fixed}.code-table th,.code-table td{white-space:normal;overflow-wrap:anywhere;word-break:break-word}.code-table th:nth-child(1),.code-table td:nth-child(1){width:5%}.code-table th:nth-child(2),.code-table td:nth-child(2){width:20%}.code-table th:nth-child(3),.code-table td:nth-child(3){width:11%}.code-table th:nth-child(4),.code-table td:nth-child(4){width:10%}.code-table th:nth-child(5),.code-table td:nth-child(5){width:8%}.code-table th:nth-child(6),.code-table td:nth-child(6){width:17%}.code-table th:nth-child(7),.code-table td:nth-child(7){width:16%}.code-table th:nth-child(8),.code-table td:nth-child(8){width:13%}.code-status{font-size:10px}.copyable{font-weight:800}.code-row-action{padding:0 8px;border:1px solid #e4c4c5;font-size:10px;white-space:nowrap}.danger-outline{color:var(--red)}.check-col{width:5%;text-align:center}.check-col input{accent-color:var(--green)}.code-pagination{display:flex;align-items:center;justify-content:center;gap:12px;padding:12px;border-top:1px solid var(--line);font-size:11px}
.dialog-actions{display:flex;justify-content:flex-end}.dialog-actions .outline{height:36px}.dialog-actions .primary{height:36px}#dialogForm label{display:block;font-size:11px;font-weight:800}#dialogForm input{width:100%;height:38px;margin-top:7px;padding:0 10px;border:1px solid var(--line);outline:0}
 .date-filter-wrap{position:relative;display:inline-flex;flex:0 0 126px;width:126px;height:36px}
 .date-filter{width:100%;height:36px;padding:0 32px 0 16px;border:1px solid var(--line);border-radius:4px;outline:0;color:#63706f;background:#fff;font-size:11px;cursor:pointer}
 .date-filter::placeholder{opacity:1}
 .date-filter-icon{position:absolute;top:50%;right:10px;width:13px;height:13px;display:grid;place-items:center;transform:translateY(-50%);pointer-events:none;font-family:"Segoe MDL2 Assets",sans-serif;font-size:13px;line-height:1}
 .date-filter-icon::before{content:"\E787"}
 
 .date-separator{font-size:11px}
@media(max-width:980px){.admin-tools #adminName{display:none}.filters{flex-wrap:wrap}.result-count{margin-left:0}.code-layout{grid-template-columns:1fr}}@media(max-width:700px){.login-panel{padding:40px 28px}.top-brand>div:last-child{display:none}.tabs{margin-left:8px}.admin-tools{gap:5px}.page-heading{align-items:flex-start;flex-direction:column}.stat-grid{grid-template-columns:repeat(2,1fr)}.heading-actions{width:100%;justify-content:space-between}.search{width:100%}.code-table .panel-toolbar{align-items:flex-start;flex-direction:column}.panel-actions{width:100%;flex-wrap:wrap}.code-table th,.code-table td{padding:7px 6px;font-size:10px}.code-table th:nth-child(2),.code-table td:nth-child(2){width:21%}.code-table th:nth-child(6),.code-table td:nth-child(6){width:15%}.code-table th:nth-child(7),.code-table td:nth-child(7){width:11%}}

/* ============================================================
   二、基线细化：字体、按钮、登录页
   ============================================================ */

button:disabled{
  cursor:not-allowed;
  opacity:.48;
}

.brand-mark{
  background:#e2a43a;
  color:#4a2f1d;
}

.panel-label{
  color:#9c712e;
}
.login-panel h2,
.page-heading h1,
.section-title h2,
.tool-panel h2,
.panel-toolbar h2{
  color:#4a2f1d;
}
.muted,.subheading{
  color:#80694e;
}
.login-panel>label,.tool-panel label{
  color:#765c40;
}
.login-panel input,.tool-panel input,.tool-panel select{
  color:#4a2f1d;
}
input:focus,select:focus{
  border-color:#d89424;
  box-shadow:0 0 0 3px rgba(216,148,36,.16);
}

.outline,.top-button{
  border-color:#dfcda5;
}

.message.ok{color:#4d8065}
.message.err{color:#bd5d50}

.app-view{
  background:
    radial-gradient(circle at 12% 7%,rgba(255,250,227,.9),transparent 27%),
    linear-gradient(135deg,#f8e7ba 0%,#f5d88f 100%);
}

.top-brand .brand-mark{
  background:#4a2f1d;
  color:#fff7e4;
}

.page-heading h1{
  margin-top:8px;
}
.heading-actions{
  align-items:center;
}
.refresh-state{
  color:#80694e;
  min-width:120px;
}

.stat-card{
  border-color:#ead7ad;
}

.section-title{
  margin-top:8px;
}
.section-title span{
  color:#967b58;
}
.segmented{
  margin-bottom:10px;
}

.filters{
  border-bottom-color:#ead7ad;
}
.search{
  border-color:#e6d2a8;
  background:#fffdf7;
}
.filters select,
.date-filter{
  border-color:#e6d2a8;
  color:#765c40;
  background:#fffdf7;
}
.result-count{
  color:#80694e;
}
table{
  min-width:1100px;
}

th,td{
  border-bottom-color:#f0e3c7;
}

.account-id,
.note-cell{
  color:#947a5b;
}
.used-account-cell{
  min-width:0;
}
.used-account-name,
.used-account-id{
  display:block;
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
}
.used-account-name{
  color:#5c3c22;
  font-weight:800;
}
.used-account-id{
  margin-top:2px;

  font-family:Consolas,monospace;
  font-size:9px;
}
.status{
  border-color:#bdd4bf;
  color:#4d8065;
  background:#eef7ed;
}

.row-actions{
  display:grid;
  grid-template-columns:repeat(3,max-content);
  align-items:center;
  justify-content:start;
  gap:4px;
}
.row-actions button{
  border-color:#dfcda5;
  color:#765c40;
  background:#fffdf7;
}
.row-actions button:hover{
  background:#fff3d6;
}
.row-actions .danger,
.danger-outline{
  color:#b65b4c;
  border-color:#e6b9ae;
}

.code-layout{
  gap:14px;
}
.tool-panel{
  padding:18px;
}
.field-hint,
.selection-count{
  color:#967b58;
}
.code-table .panel-toolbar{
  border-bottom-color:#ead7ad;
  background:#fff7e5;
}

.code-row-action{
  border-color:#e6b9ae;
  color:#b65b4c;
  background:#fffdf7;
}
.code-pagination{
  border-top-color:#ead7ad;
  color:#80694e;
}

@media(max-width:980px){
  .topbar,.main{
    width:calc(100% - 32px);
  }
}
@media(max-width:700px){
  
  
  
  
  .main{
    padding-top:18px;
  }
}

.audit-table{
  width:100%;
  margin-inline:auto;
}
.audit-table .table-scroll{
  overflow-x:auto;
}
.audit-table table{
  width:100%;
  min-width:0;
  table-layout:fixed;
}
.audit-table th,
.audit-table td{
  text-align:center;
  vertical-align:middle;
  white-space:normal;
  overflow-wrap:anywhere;
  word-break:break-word;
}
.audit-table th:nth-child(1),
.audit-table td:nth-child(1){width:16%}
.audit-table th:nth-child(2),
.audit-table td:nth-child(2){width:11%}
.audit-table th:nth-child(3),
.audit-table td:nth-child(3){width:19%}
.audit-table th:nth-child(4),
.audit-table td:nth-child(4){width:12%}
.audit-table th:nth-child(5),
.audit-table td:nth-child(5){width:10%}
.audit-table th:nth-child(6),
.audit-table td:nth-child(6){width:14%}
.audit-table th:nth-child(7),
.audit-table td:nth-child(7){width:18%}
.audit-result{
  font-weight:800;
}
.audit-result.success{
  color:var(--green);
}
.audit-result.failed{
  color:var(--red);
}
.audit-user-agent{
  display:-webkit-box;
  width:100%;
  max-width:none;
  overflow:hidden;
  color:var(--muted);
  text-align:center;
  text-overflow:ellipsis;
  white-space:normal;
  -webkit-box-orient:vertical;
  -webkit-line-clamp:2;
  line-height:1.45;
}
.admin-audit-table table{
  table-layout:auto;
}
.admin-audit-table th:nth-child(n),
.admin-audit-table td:nth-child(n){
  width:auto;
  min-width:96px;
}
.admin-audit-table th:first-child,
.admin-audit-table td:first-child{
  min-width:150px;
}
.admin-audit-table th:nth-child(3),
.admin-audit-table td:nth-child(3),
.admin-audit-table th:nth-child(4),
.admin-audit-table td:nth-child(4),
.admin-audit-table th:nth-child(7),
.admin-audit-table td:nth-child(7){
  min-width:120px;
}

/* ============================================================
   三、页内弹窗：替代浏览器原生 alert，并始终居中在视口内
   ============================================================ */
dialog{
  position:fixed;
  inset:0;
  width:min(420px,calc(100% - 32px));
  max-height:calc(100vh - 32px);
  margin:auto;
  padding:0;
  overflow:auto;
  border:1px solid #e3c78d;

  color:#4a2f1d;
  background:#fffaf0;
}

#dialogForm h3{
  margin:0;
  color:#4a2f1d;

  line-height:1.4;
}
#dialogForm p{
  margin:12px 0 0;
  color:#80694e;
  font-size:13px;
  line-height:1.7;
  overflow-wrap:anywhere;
}
#dialogForm label{
  margin-top:18px;
  color:#765c40;
}
#dialogForm input{
  color:#4a2f1d;
}
.dialog-actions{
  margin-top:24px;
  gap:8px;
}
.dialog-actions button{
  min-width:78px;
  height:36px;
}

.dialog-actions .primary{
  color:#fff9ec;
}

.topbar{
  border-bottom-width:2px;
}

.code-layout{
  grid-template-columns:300px minmax(0,1fr);
}
@media(max-width:980px){
  .top-brand{
    width:180px;
  }
}
@media(max-width:700px){
  .topbar{
    width:auto;
    height:66px;
    min-height:0;
    padding:0 12px;
    flex-wrap:nowrap;
    gap:0;
  }
  .top-brand{
    width:auto;
    margin-right:0;
  }
  .tabs{
    order:initial;
    width:auto;
    height:100%;
  }
  .tab{
    flex:initial;
    padding:0 10px;
  }
  .admin-tools{
    margin-left:auto;
  }
  .main{
    width:auto;
    padding:18px 12px;
  }
  .page-heading h1{
    font-size:25px;
  }
}

/* ============================================================
   四、页面背景
   ============================================================ */

.app-view{
  min-height:100vh;
}

.table-panel th{
  text-align:center;
}

#accountsPage table tbody td:not(:first-child){
  text-align:center;
}

#accountsPage table tbody tr{
  height:auto;
}

#accountsPage table tbody td{
  height:auto;
  vertical-align:middle;
}

#accountsPage table tbody td:last-child{
  vertical-align:middle;
  white-space:nowrap;
}

#accountsPage .row-actions{
  align-content:start;
  justify-content:center;
}

.code-table th,
.code-table td{
  text-align:center;
}

.code-table td.copyable{
  cursor:copy;
  user-select:none;
  transition:color .14s,background .14s,box-shadow .14s;
}

.code-table td.code-value{
  cursor:text;
  user-select:text;
}

.code-table td.copyable:hover,
.code-table td.copyable:focus-visible{
  outline:none;
}

.code-status-filter{
  height:34px;
  padding:0 27px 0 10px;
  border:1px solid #dfcda5;
  border-radius:4px;
  outline:0;
  color:#765c40;
  background:#fffdf7;
  font-size:11px;
}

.code-status-filter:focus{
  border-color:var(--gold);
  box-shadow:0 0 0 3px rgba(216,148,36,.16);
}

.date-filter{
  user-select:none;
  caret-color:transparent;
}

.date-filter:focus{
  border-color:var(--gold);
  box-shadow:0 0 0 3px rgba(216,148,36,.16);
}

.date-picker-popup{
  position:fixed;
  z-index:1200;
  width:268px;
  padding:12px;
}

.date-picker-popup.hidden{
  display:none;
}

.date-picker-head{
  display:grid;
  grid-template-columns:30px minmax(0,1fr) 30px;
  align-items:center;
  gap:8px;
  min-height:30px;
  margin-bottom:10px;
  text-align:center;
}

.date-picker-head strong{
  font-size:13px;
}

.date-picker-nav{
  position:relative;
  width:30px;
  height:30px;
  display:grid;
  place-items:center;
  border:1px solid #dfcda5;
  border-radius:4px;
  color:#765c40;
  background:#fffdf7;
  padding:0;
  font-size:0;
  line-height:0;
}

.date-picker-nav::before{
  content:"";
  position:absolute;
  top:50%;
  left:50%;
  display:block;
  width:8px;
  height:8px;
  border-top:1.5px solid currentColor;
  border-right:1.5px solid currentColor;
  transform:translate(-50%,-50%) rotate(45deg);
}

.date-picker-nav[data-date-nav="-1"]::before{
  transform:translate(-50%,-50%) rotate(225deg);
}

.date-picker-nav:hover{
  border-color:#cda45c;
  color:#4a2f1d;
  background:#fff3d6;
}

.date-picker-title{
  width:100%;
  min-width:116px;
  height:30px;
  display:inline-flex;
  align-items:center;
  justify-content:center;
  padding:0 9px;
  border:1px solid transparent;
  border-radius:4px;
  color:#4a2f1d;
  background:transparent;
  font-size:13px;
  font-weight:800;
}

.date-picker-title:hover,
.date-picker-title[aria-expanded="true"]{
  border-color:#dfcda5;
  background:#fff3d6;
}

.date-picker-quick-select{
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(68px,1fr) minmax(68px,1fr);
  gap:6px;
  margin:0 0 10px;
  padding:8px;
  border:1px solid #ead7ad;
}

.date-picker-quick-select.hidden{
  display:none;
}

.date-picker-quick-select label{
  display:grid;
  gap:4px;
  color:#967b58;
  font-size:9px;
  font-weight:800;
  text-align:center;
}

.date-picker-quick-select select{
  width:100%;
  height:28px;
  padding:0 20px 0 5px;
  border:1px solid #e6d2a8;

  outline:0;

  font-size:10px;
  text-align:center;
}

.date-picker-weekdays,
.date-picker-days{
  display:grid;
  grid-template-columns:repeat(7,1fr);
  gap:3px;
}

.date-picker-weekdays{
  margin-bottom:4px;
  color:#967b58;
  font-size:10px;
  text-align:center;
}

.date-picker-day{
  min-width:0;
  height:29px;
  padding:0;
  border:1px solid transparent;

  background:transparent;
  font-size:11px;
}

.date-picker-footer{
  display:flex;
  justify-content:flex-end;
  gap:7px;
  margin-top:11px;
  padding-top:10px;
  border-top:1px solid #ead7ad;
}

.date-picker-footer button{
  height:30px;
  min-width:56px;
  padding:0 9px;
  font-size:10px;
}

.filters select,
.tool-panel select,
.code-status-filter{
  padding-right:35px;
}

.code-table input[type="checkbox"]:focus,
.code-table input[type="checkbox"]:focus-visible{
  outline:none;
  box-shadow:none;
}

.search{
  align-items:center;
}

.search > span{
  position:relative;
  width:32px;
  height:100%;
  display:grid;
  place-items:center;
  flex:0 0 32px;
  padding:0;
  line-height:1;

  font-size:0;
}

.search > span::before{
  content:"";
  position:absolute;
  top:50%;
  left:50%;
  width:8px;
  height:8px;
  border:1.5px solid currentColor;
  border-radius:50%;
  transform:translate(-65%,-65%);
}

.search > span::after{
  content:"";
  position:absolute;
  top:50%;
  left:50%;
  width:5px;
  height:1.5px;
  border-radius:2px;
  background:currentColor;
  transform:translate(1px,2px) rotate(45deg);
  transform-origin:left center;
}

.search:focus-within input{
  box-shadow:none;
}

#adminDialog{
  width:min(560px,calc(100% - 32px));
  max-height:calc(100vh - 32px);
  overflow:auto;
  color:var(--ink);
  background:var(--paper);
}

#adminDialog::backdrop{
  background:rgba(17,28,34,.38);
}

.admin-dialog-form{
  padding:24px;
}

.admin-dialog-heading{
  display:flex;
  align-items:flex-start;
  justify-content:space-between;
  gap:16px;
}

.admin-dialog-heading h3{
  margin:9px 0 0;
  font-size:19px;
}

.dialog-close{
  position:relative;
  width:30px;
  height:30px;
  padding:0;
  border:1px solid var(--line);
  border-radius:4px;

  /* 叉号不再用字体字形：× 的墨迹在 em 框里天然偏心（实测 20px 字号下比按钮中心低 2.3px、
     受字体度量影响），换成两条绝对定位的描边，50%/50% + translate(-50%,-50%) 必然居中。
     font-size:0 收掉原来的字形，无障碍名称由 aria-label 提供。 */
  font-size:0;
}

.dialog-close::before,
.dialog-close::after{
  content:"";
  position:absolute;
  top:50%;
  left:50%;
  width:12px;
  height:1px;
  border-radius:1px;
  background:currentColor;
}

.dialog-close::before{
  transform:translate(-50%,-50%) rotate(45deg);
}

.dialog-close::after{
  transform:translate(-50%,-50%) rotate(-45deg);
}

.admin-list{
  display:grid;
  gap:7px;
  max-height:180px;
  margin-top:20px;
  padding:8px;
  overflow:auto;
  border:1px solid var(--line);
}

.admin-list.is-empty{
  display:block;
  padding:18px;
  color:var(--muted);
  text-align:center;
  font-size:12px;
}

.admin-list-item{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:14px;
  min-height:42px;
  padding:7px 9px;
  border:1px solid transparent;
}

.admin-list-item small{
  font-size:10px;
}

.admin-list-meta{
  display:flex;
  align-items:center;
  justify-content:flex-end;
  gap:9px;
  min-width:0;
}

.admin-current-badge{
  padding:3px 6px;
  border:1px solid #dfcda5;
  border-radius:3px;

  font-size:9px;
  white-space:nowrap;
}

.admin-delete-button{
  height:27px;
  padding:0 8px;
  border:1px solid #e4c4c5;
  border-radius:3px;
  color:#bd5d61;
  background:transparent;
  font-size:10px;
}

.admin-delete-button:hover{
  background:#fff3f3;
}

.admin-list-identity{
  display:flex;
  align-items:center;
  gap:9px;
  min-width:0;
}

.admin-list-identity strong{
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
  font-size:12px;
}

.admin-avatar{
  display:grid;
  place-items:center;
  width:27px;
  height:27px;
  flex:0 0 27px;
  border-radius:50%;
  color:#fff;
  background:#4a2f1d;
  font-size:11px;
  font-weight:800;
}

.admin-create-heading{
  display:flex;
  align-items:baseline;
  gap:10px;
  margin-top:22px;
}

.admin-create-heading h4{
  margin:0;
  font-size:14px;
}

.admin-create-heading span{
  color:var(--muted);
  font-size:10px;
}

.admin-create-grid{
  display:grid;
  grid-template-columns:repeat(3,minmax(0,1fr));
  gap:10px;
  margin-top:13px;
}

.admin-create-grid label{
  display:block;

  font-size:11px;
  font-weight:800;
}

.admin-create-grid input{
  width:100%;
  height:38px;
  margin-top:7px;
  padding:0 10px;
  border:1px solid var(--line);
  border-radius:4px;
  outline:0;
  color:var(--ink);
  background:rgba(255,255,255,.7);
}

.admin-create-grid input:focus{
  border-color:var(--gold);
  box-shadow:0 0 0 3px rgba(216,148,36,.16);
}

@media(max-width:700px){
  .admin-create-grid{
    grid-template-columns:1fr;
  }

  .admin-list-item{
    align-items:flex-start;
    flex-direction:column;
    gap:4px;
  }
}

/* ============================================================
   五、账号列表布局：列宽、单元格对齐与行内操作
   ============================================================ */
#accountsPage .stat-grid--accounts{
  grid-template-columns:repeat(auto-fit,minmax(150px,1fr));
}

#accountsPage .stat-card.orange{
  border-left-color:#c27a2f;
}

#accountsPage .stat-card.partial{
  border-left-color:var(--admin-accent);
}

#accountsPage .status.expired{
  color:var(--dt-red);
  border-color:rgba(189,93,80,.32);
  background:rgba(189,93,80,.09);
}

#accountsPage table{
  min-width:1040px;
  table-layout:fixed;
}
#accountsPage th:first-child,
#accountsPage td:first-child{
  width:18%;
  text-align:left;
}
#accountsPage th:nth-child(2),
#accountsPage td:nth-child(2){
  width:7%;
}
#accountsPage th:nth-child(3),
#accountsPage td:nth-child(3){
  width:13%;
}
#accountsPage th:nth-child(4),
#accountsPage td:nth-child(4){
  width:9%;
}
#accountsPage th:nth-child(5),
#accountsPage td:nth-child(5){
  width:10%;
}
#accountsPage th:nth-child(6),
#accountsPage td:nth-child(6){
  /* 从 16% 让出 4% 给「操作」列（见第 9 列注释），本列内容最长约 120px，12% 仍有富余。 */
  width:12%;
}
#accountsPage th:nth-child(7),
#accountsPage td:nth-child(7){
  width:9%;
}
#accountsPage th:nth-child(8),
#accountsPage td:nth-child(8){
  width:8%;
}
#accountsPage th:nth-child(9),
#accountsPage td:nth-child(9){
  /* 14% 而不是 10%：按钮组是绝对定位居中、不参与单元格宽度计算，待激活行比普通行多两个
     按钮（批准 / 拒绝），10%（实测约 139px）装不下会向两侧溢出、把表格撑得比容器宽 24px，
     最右侧的「操作」被裁；14%（1440 弹窗下约 296px）才容得下四个按钮（实测按钮组约 177px）。
     与第 6 列 12% 配对保持合计 100%。 */
  width:14%;
  min-width:0;
}
#accountsPage table tbody td:first-child{
  text-align:left;
}
#accountsPage .account-cell{
  min-width:0;
}
#accountsPage .account-cell > div{
  min-width:0;
}
#accountsPage .account-name,
#accountsPage .account-id{
  display:block;
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
}
#accountsPage .account-points-cell{
  font-size:12px;
  font-weight:800;
  font-variant-numeric:tabular-nums;
}
#accountsPage .account-auth-cell>small,
#accountsPage .account-device-cell>small,
#accountsPage .account-activity-cell>small{
  display:block;
  margin-top:4px;
  color:#99a3b0;
  font-size:9.5px;
}
#accountsPage .account-auth-cell .status{
  margin-inline:auto;
}
#accountsPage .account-device-cell strong,
#accountsPage .account-activity-cell>span{
  display:block;

  font-size:11px;
  font-weight:700;
}
#accountsPage .account-ip-cell{
  font-family:ui-monospace,Consolas,monospace;
  font-size:10px;
}
#accountsPage .account-ip-cell>span,
#accountsPage .account-ip-cell>small{
  display:block;
}
#accountsPage .account-ip-cell>small{
  margin-top:4px;
  color:#99a3b0;
  font-family:"Segoe UI","Microsoft YaHei",sans-serif;
  font-size:9.5px;
}
#accountsPage th:last-child,
#accountsPage td:last-child{
  text-align:center;
}
#accountsPage .row-actions{
  position:relative;
  display:table-cell;
  padding-top:0;
  padding-bottom:0;
  text-align:center;
  vertical-align:middle;
  white-space:nowrap;
}
#accountsPage .row-action-buttons{
  position:absolute;
  inset:0;
  display:flex;
  align-items:center;
  justify-content:center;
  gap:5px;
}
.menu-toggle{
  position:relative;
}
.row-action-menu{
  position:fixed;
  z-index:60;
  display:grid;
  gap:2px;
}
.row-action-menu button{
  border-radius:3px;

  background:transparent;

  text-align:left;
  white-space:nowrap;
  cursor:pointer;
}

.account-detail-dialog::backdrop{
  background:rgba(34,24,14,.28);
}

.account-detail-heading{
  display:flex;

  justify-content:space-between;
  gap:14px;
}

.account-detail-body{
  grid-template-columns:1fr 1fr;
  gap:1px;
}

.account-detail-row span{
  white-space:nowrap;
}

.account-detail-actions{
  padding-top:2px;
}

/* —— 账号详情：缓存占用（内置网关的参考素材与成片副本） —— */
.account-detail-storage{
  display:grid;
  gap:9px;
  margin-top:2px;
}
.account-storage-body{
  display:grid;
  gap:9px;
}
.account-storage-group{
  display:grid;
  gap:7px;
  padding:11px 13px;
  border:1px solid var(--dt-line);
  border-radius:var(--dt-radius-sm);
  background:var(--dt-surface-2);
}
.account-storage-group-head{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:10px;
}
.account-storage-title{
  min-width:0;
  font-size:12px;
  font-weight:900;
}
/* 上限信息另起一行：跟标题挤在同一行时，窄屏会在「全球上限」这种词中间断行。 */
.account-storage-meta{
  display:block;
  margin-top:2px;
  color:var(--dt-muted-2);
  font-size:11px;
  font-weight:400;
}
/* 清理是危险动作：单独写红描边，不落到 .outline 的纯白描边上（纯白在这层底色里看不见边界）。 */
.account-storage-group-head button.danger{
  flex:0 0 auto;
  height:26px;
  padding:0 11px;
  color:var(--red);
  border:1px solid rgba(221,106,118,.32);
  border-radius:var(--dt-radius-sm);
  background:transparent;
  font-size:11px;
  font-weight:800;
  white-space:nowrap;
}
.account-storage-files{
  display:grid;
  gap:3px;
}
/* 文件名可能很长（前缀 + 32 位摘要），只让它自己省略，别把整行撑出容器。 */
.account-storage-file{
  display:grid;
  grid-template-columns:minmax(0,1fr) auto auto auto;
  align-items:center;
  gap:9px;
  font-size:11px;
}
.account-storage-file-name{
  min-width:0;
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
  color:var(--dt-ink);
}
.account-storage-file-size,
.account-storage-file-time,
.account-storage-file-note{
  color:var(--dt-muted-2);
  white-space:nowrap;
}
.account-storage-empty,
.account-storage-hint{
  color:var(--dt-muted-2);
  font-size:10px;
  line-height:1.6;
}
@media(max-width:700px){
  /* 窄屏：一格一行，避免四列挤在一起把文件名压到看不见。 */
  .account-storage-file{
    grid-template-columns:minmax(0,1fr);
    row-gap:2px;
  }
}

/* —— 账号详情：积分流水 —— */
.account-detail-points{
  display:grid;
  gap:9px;
  margin-top:2px;
}
.account-detail-points-head{
  display:flex;
  align-items:flex-end;
  justify-content:space-between;
  gap:12px;
}
.account-detail-points-head h4{
  margin:4px 0 0;
  font-size:14px;
  font-weight:900;
}
.account-detail-points-total{
  color:var(--dt-muted-2);
  font-size:10px;
}
.account-detail-points-list{
  display:grid;
  gap:5px;

  border:1px solid var(--dt-line);

  background:var(--dt-surface-2);
}
.points-ledger-item{
  display:grid;

  align-items:center;

  min-width:0;

  border-bottom:1px solid rgba(234,215,173,.65);
}
.points-ledger-item:last-child{border-bottom:0}
.points-ledger-kind{
  padding:3px 8px;
  border:1px solid var(--dt-line);
  border-radius:999px;

  font-size:9px;
  font-weight:800;
  white-space:nowrap;
}

.points-ledger-kind.refund,.points-ledger-kind.reversal{color:var(--dt-gold-hot);border-color:rgba(216,148,36,.3);background:rgba(216,148,36,.1)}

.points-ledger-note{
  overflow:hidden;

  text-overflow:ellipsis;
  white-space:nowrap;
}
.points-ledger-amount{
  font-size:11px;
  font-weight:800;
  font-variant-numeric:tabular-nums;
  white-space:nowrap;
}

.points-ledger-date{
  color:var(--dt-muted-2);
  font-size:9.5px;
  white-space:nowrap;
}
.points-ledger-empty{
  padding:20px 12px;
  color:var(--dt-muted-2);
  font-size:11px;
  text-align:center;
}

/* ============================================================
   六、组件精修：按钮体系、统计卡、分段控件、筛选工具条、
   表格面板、账号单元、状态徽章、行内操作与弹窗
   ============================================================ */
html,body{
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}

button,a,select,input{transition:background-color .16s ease,border-color .16s ease,color .16s ease,box-shadow .16s ease,transform .12s ease}
button:active:not(:disabled){transform:translateY(1px)}
button:focus-visible,select:focus-visible,input:focus-visible,a:focus-visible{outline:2px solid rgba(216,148,36,.5);outline-offset:2px}

/* —— 按钮体系 —— */
.primary{
  height:36px;
  padding:0 16px;
  border:1px solid transparent;

  font-weight:800;
}

.primary:active{filter:brightness(.98)}
.primary:disabled{filter:saturate(.6)}
.outline,.top-button{
  height:34px;
  padding:0 13px;
  border:1px solid var(--dt-line-strong);
  border-radius:var(--dt-radius-sm);
  color:var(--dt-ink-soft);
  background:var(--dt-surface-2);
  font-size:12px;
  font-weight:700;
}
.outline:hover,.top-button:hover{
  border-color:var(--dt-gold);
  color:var(--dt-gold-hot);
  background:var(--dt-gold-soft);
}
.wide{height:42px}

/* —— 登录页 —— */
.login-view{
  position:relative;
  background:
    radial-gradient(circle at 14% 16%,rgba(255,252,236,.92),transparent 30%),
    radial-gradient(circle at 88% 86%,rgba(255,240,198,.9),transparent 34%),
    linear-gradient(135deg,#f8e8bd 0%,#f5d88f 100%);
}
.login-view:before{content:"";position:absolute;inset:0;pointer-events:none}
.login-panel input,.tool-panel input,.tool-panel select{
  border-radius:var(--dt-radius-sm);
  border-color:var(--dt-line);
  background:var(--dt-surface-2);
  transition:border-color .16s,box-shadow .16s,background .16s;
}
.login-panel input:focus,.tool-panel input:focus,.tool-panel select:focus,
.login-panel input:focus-visible,.tool-panel input:focus-visible,.tool-panel select:focus-visible{
  outline:none;
  border-color:var(--dt-gold);
  background:#fff;
  box-shadow:0 0 0 3px rgba(216,148,36,.15);
}

/* —— 顶栏导航 —— */

.top-brand .brand-mark{
  box-shadow:0 2px 6px rgba(74,47,29,.2);
}
.tab{font-weight:800;letter-spacing:.01em}

.tab.active:after{border-radius:3px 3px 0 0}
.top-button{background:rgba(255,250,240,.5)}

/* —— 页面头部 —— */
.page-heading h1{font-size:28px;font-weight:900;letter-spacing:-.01em}

.refresh-state .live-dot{margin-right:7px}

/* —— 统计卡 —— */
.stat-grid{gap:12px;margin-bottom:20px}
.stat-card{
  position:relative;
  overflow:hidden;
  min-height:78px;

  border-left:4px solid var(--dt-line-strong);

  transition:box-shadow .18s,transform .12s,border-color .18s;
}
.stat-card:hover{box-shadow:var(--dt-shadow);transform:translateY(-1px)}
.stat-card:after{content:"";position:absolute;right:-22px;top:-22px;width:64px;height:64px;border-radius:50%;pointer-events:none}
.stat-card span{font-size:11px;font-weight:800;letter-spacing:.06em;text-transform:uppercase}
.stat-card strong{font-size:30px;font-weight:900;font-variant-numeric:tabular-nums}
.stat-card.gold{border-left-color:var(--dt-gold)}
.stat-card.green{border-left-color:var(--dt-green)}
.stat-card.red{border-left-color:var(--dt-red)}

/* —— 分区标题/分段 —— */
.section-title h2{font-size:18px;font-weight:900;letter-spacing:-.01em}
.section-title h2:before{content:"";display:inline-block;width:4px;height:16px;margin-right:9px;border-radius:2px;vertical-align:-2px}
.segment{
  height:34px;

  margin-right:0;
  font-weight:800;
}
.segment:first-child{border-radius:var(--dt-radius-sm) 0 0 var(--dt-radius-sm)}
.segment:last-child{border-radius:0 var(--dt-radius-sm) var(--dt-radius-sm) 0}
.segment:not(:last-child){border-right-width:0}

/* —— 筛选工具条 —— */
.filters{
  gap:8px;
  padding:12px;
  border-bottom:1px solid var(--dt-line);
  background:linear-gradient(180deg,var(--dt-surface) 0%,var(--dt-surface-3) 100%);
}
.search,.filters select,.date-filter{
  height:34px;
  border-radius:var(--dt-radius-sm);
  border-color:var(--dt-line);
  background:var(--dt-surface-2);
}
.search:focus-within{border-color:var(--dt-gold);box-shadow:0 0 0 3px rgba(216,148,36,.14);background:#fff}
.search span{font-size:18px}
.filters select{font-size:11px}

/* —— 表格面板 —— */
.table-panel{
  border-color:var(--dt-line);
  border-radius:var(--dt-radius);
  background:var(--dt-surface);
  box-shadow:var(--dt-shadow-sm);
}
.table-scroll{scrollbar-width:thin}
.table-scroll::-webkit-scrollbar{height:8px;width:8px}
.table-scroll::-webkit-scrollbar-thumb{border-radius:8px}
.table-scroll::-webkit-scrollbar-track{background:transparent}
th,td{height:48px;padding:9px 12px;border-bottom:1px solid rgba(234,215,173,.7);font-size:11px}
th{
  height:38px;

  font-size:10px;font-weight:900;letter-spacing:.05em;text-transform:uppercase;
}
tbody tr{transition:background .14s}

/* —— 账号单元 —— */
.account-cell{gap:10px}
.avatar{
  width:30px;height:30px;
}
.account-name{font-size:12px;font-weight:800;color:var(--dt-ink)}
.account-id{font-size:9.5px;color:var(--dt-muted-2);letter-spacing:.01em;font-variant-numeric:tabular-nums}
.note-cell{color:var(--dt-muted);font-size:10.5px}

/* —— 状态徽章 —— */
.status{
  gap:6px;
  padding:5px 10px;
  border-width:1px;

  font-size:10px;font-weight:800;
}
.status:before{width:6px;height:6px;box-shadow:0 0 0 2px rgba(77,128,101,.12)}

.status.revoked,.status.rejected{color:var(--dt-red);border-color:rgba(189,93,80,.3);background:rgba(189,93,80,.08)}

/* —— 行内操作 —— */
#accountsPage .row-actions{gap:6px}
#accountsPage .row-actions button,
.row-action-menu button{
  border-radius:var(--dt-radius-sm);
}
#accountsPage .row-actions button{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  vertical-align:middle;
  margin:0 2px;
  height:28px;
  padding:0 9px;
  border-color:var(--dt-line);

  font-size:10px;font-weight:700;
  line-height:1;
  white-space:nowrap;
}

#accountsPage .row-actions button.danger,.row-action-menu button.danger{color:var(--dt-red);border-color:rgba(189,93,80,.3)}

/* —— 操作下拉菜单 —— */
.row-action-menu{
  min-width:150px;
  padding:6px;
}
.row-action-menu button{height:32px;padding:0 12px;font-size:11px}

/* —— 弹窗 —— */
dialog{
  border-radius:var(--dt-radius);
  box-shadow:var(--dt-shadow-lg);
}

#dialogForm{padding:26px}
#dialogForm h3{font-size:18px;font-weight:900}
#dialogForm input{border-radius:var(--dt-radius-sm);border-color:var(--dt-line);background:var(--dt-surface-2)}
#dialogForm input:focus,#dialogForm input:focus-visible{outline:none;border-color:var(--dt-gold);box-shadow:0 0 0 3px rgba(216,148,36,.15);background:#fff}

/* —— 账号详情抽屉 —— */

.account-detail-body{border-color:var(--dt-line)}

.account-detail-actions button,.account-detail-actions button.danger{border-radius:var(--dt-radius-sm)}

/* —— 激活码/审计 —— */
.tool-panel,.panel-toolbar{border-radius:var(--dt-radius)}
.tool-panel{box-shadow:var(--dt-shadow-sm)}
.code-row-action{border-radius:var(--dt-radius-sm);height:29px}
.copyable{font-family:ui-monospace,Consolas,monospace}
.code-status{font-weight:800}

/* —— 管理员对话框 —— */
.admin-dialog-form{border-radius:var(--dt-radius)}

/* ============================================================
   七、后台视觉基线：卡片、筛选、表格、弹窗、账号详情与抽屉
   ============================================================ */

.app-view,
.login-view{
  background:var(--admin-bg);
  background-image:none;
}

.brand-mark,
.top-brand .brand-mark{
  color:#fffdf7;
  background:linear-gradient(145deg,#d9af50,#c99734);
  box-shadow:0 7px 16px rgba(190,139,40,.22);
}

/* 登录入口：桌面端居中单卡，移动端保持同一结构。 */
.login-view{
  display:block;
  place-items:normal;
  min-height:100vh;
}

.login-topbar{
  position:sticky;
  top:0;
  z-index:20;
  display:flex;
  align-items:center;
  height:64px;
  padding:0 max(24px,calc((100vw - 1540px) / 2));
}

.brand-lockup{
  display:flex;
  align-items:center;
  gap:12px;
}

.brand-lockup .brand-mark{
  width:40px;
  height:40px;
  border-radius:12px;
  font-size:15px;
}

.brand-lockup strong{
  display:block;
  color:var(--admin-ink-strong);
  font-size:17px;
  line-height:1.2;
}

.brand-lockup small{
  display:block;
  margin-top:4px;
  color:var(--admin-muted);
  font-size:11px;
}

.login-stage{
  min-height:calc(100vh - 64px);
  display:grid;
  place-items:center;
  padding:64px 20px;
}

.login-panel{
  width:min(440px,100%);
  padding:30px 30px 26px;
}

.login-panel .panel-label{
  color:var(--admin-accent);
  font-size:11px;
  letter-spacing:.08em;
}

.login-panel h2{
  margin:12px 0 7px;
  color:var(--admin-ink-strong);
  font-size:27px;
  letter-spacing:0;
}

.login-panel .muted{
  margin:0 0 24px;
  color:var(--admin-muted);
  font-size:13px;
}

.login-panel>label,
.tool-panel label{
  color:#596576;
  font-size:12px;
}

.login-panel input,
.tool-panel input,
.tool-panel select{
  height:42px;
  margin-top:8px;
  border-color:var(--admin-line-strong);
  border-radius:8px;
  background:#fff;
}

.remember-option{
  display:flex!important;
  align-items:center;
  gap:8px;
  margin-top:16px!important;
  color:#596576!important;
  cursor:pointer;
}

.remember-option input{
  width:16px;
  height:16px;
  margin:0;
}

.login-panel .primary.wide{
  height:43px;
  margin-top:22px;
  border:1px solid #6d82a8;
}

.login-panel .message{
  margin-top:12px;
}

.login-hint{
  margin-top:18px;
}

/* 后台外壳：浅色顶栏与胶囊页签。 */
.topbar{
  position:sticky;
  top:0;
  z-index:30;
  width:auto;
  height:70px;
  margin:0;
  padding:0 max(24px,calc((100vw - 1540px) / 2));
  color:var(--admin-ink);
}

/* 版本号条：所有页面共用，位于顶部导航下方 10px。
   放在 .main 里是为了直接复用它的内容盒 —— .main 在 980 / 860 / 700 三个断点各改一次
   宽度或内边距，自己算一遍很容易与它对不上；放在里面则右边缘天然与页面内容对齐。
   高度固定成「.main 上内边距 - 10px」并用负 margin-top 抵消同样的值，使这条占用的纵向
   空间恰好等于原有的上内边距：版本号落在导航下方 10px，而下面的页面内容起始位置与
   没有版本号时完全一致，不会被挤下去。
   改 .main 的 padding-top 时要同步改这两个值。 */
.app-version-bar{
  display:flex;
  justify-content:flex-end;
  align-items:flex-start;
  height:20px;
  margin-top:-20px;
}

.admin-version{
  text-align:right;
  font-size:10px;
  font-weight:800;
  letter-spacing:.04em;
  color:var(--admin-muted);
}

@media(max-width:860px){
  .app-version-bar{
    height:12px;
    margin-top:-12px;
  }
}

.top-brand{
  width:250px;
  gap:11px;
}

.top-brand .brand-mark{
  width:36px;
  height:36px;
  border-radius:10px;
  font-size:12px;
}

.top-brand strong{
  color:var(--admin-ink-strong);
  font-size:15px;
}

.top-brand small{
  color:var(--admin-muted);
}

.tab{
  padding:0 16px;
  color:#79889a;
  font-size:12px;
  border-radius:10px;
}

.tab:hover{
  color:var(--admin-accent-deep);
  background:var(--admin-accent-soft);
}

.tab.active{
  color:var(--admin-ink-strong);
  background:#f4f6f9;
}

.tab.active:after{
  right:16px;
  bottom:-1px;
  left:16px;
  height:2px;
  background:var(--admin-accent);
}

.top-button,
.outline{
  height:36px;
  border-color:var(--admin-line-strong);
  border-radius:8px;
  color:#596779;
  background:#fff;
}

.top-button:hover,
.outline:hover{
  border-color:#bfc9d8;
  color:var(--admin-accent-deep);
  background:#f7f9fc;
}

.main{
  width:auto;
  padding:30px max(24px,calc((100vw - 1540px) / 2)) 52px;
}

.page{
  max-width:1480px;
}

.page-heading{
  margin-bottom:22px;
}

.page-heading h1,
.dashboard-heading h1{
  color:var(--admin-ink-strong);
  letter-spacing:0;
}

.eyebrow{
  color:#7690b5;
  letter-spacing:.04em;
}

/* 运行看板。 */
.dashboard-heading{
  display:flex;
  align-items:flex-end;
  justify-content:space-between;
  gap:24px;
  margin-bottom:42px;
}

.dashboard-heading h1{
  margin:9px 0 0;
  font-size:32px;
}

.dashboard-refresh{
  display:flex;
  align-items:center;
  flex-wrap:wrap;
  gap:6px 14px;
  margin-top:13px;
  color:var(--admin-green);
  font-size:13px;
}

.dashboard-refresh-cycle{
  display:inline-flex;
  align-items:center;
  gap:8px;
}

.dashboard-refresh-next{
  white-space:nowrap;
}

.dashboard-refresh b{
  font-variant-numeric:tabular-nums;
}

.dashboard-actions{
  display:flex;
  align-items:center;
  gap:12px;
}

.dashboard-actions .outline{
  min-width:76px;
  height:46px;
  padding:0 20px;
  border-radius:999px;
  color:#526174;
  font-size:14px;
  font-weight:700;
}

.dashboard-actions .dashboard-account-action{
  display:none;
}

.runtime-intro{
  margin-bottom:22px;
}

.runtime-intro h2{
  margin:12px 0 8px;
  color:var(--admin-ink-strong);
  font-size:30px;
  line-height:1.25;
  letter-spacing:0;
}

.runtime-intro p{
  max-width:980px;
  margin:0;
  color:#778394;
  font-size:14px;
  line-height:1.7;
}

.runtime-updated{
  display:flex;
  align-items:center;
  gap:9px;
  margin-top:16px;
  color:var(--admin-green);
  font-size:13px;
}

.runtime-card-rail{
  display:grid;
  grid-template-columns:repeat(4,minmax(0,1fr));
  /* 各行等高：最高的卡片（含“在线设备”页脚）决定统一高度，避免两行大小不一。 */
  grid-auto-rows:1fr;
  gap:14px;
  margin-bottom:22px;
}

.runtime-card{
  min-height:172px;
  display:flex;
  flex-direction:column;
  padding:20px;
}

.runtime-card-action{
  width:100%;
  color:inherit;
  font:inherit;
  text-align:left;
  cursor:pointer;
  transition:transform .14s,border-color .14s,box-shadow .14s;
}

.runtime-card-action:focus-visible{
  outline:none;
}

.runtime-card-action[aria-busy="true"]{
  cursor:wait;
  opacity:.72;
}

.runtime-card-primary{
  border-color:transparent;
  background:linear-gradient(145deg,#566a8f 0%,#776f98 100%);
}

.runtime-card-head{
  display:flex;
  align-items:center;
  justify-content:flex-start;
  gap:9px;

  font-size:12px;
  font-weight:700;
}

.runtime-card-head small{
  margin-left:auto;

  font-size:10px;
  font-weight:600;
}

.runtime-card-icon{
  display:grid;
  place-items:center;
  flex:0 0 auto;
  width:36px;
  height:36px;
  border-radius:11px;
}

.runtime-card-icon svg{
  width:19px;
  height:19px;
  fill:none;
  stroke:currentColor;
  stroke-width:1.8;
  stroke-linecap:round;
  stroke-linejoin:round;
}

/* 各指标图标用不同色相区分，底为同色系浅色。 */

.runtime-card strong{
  margin-top:12px;

  font-size:42px;
  line-height:1;
  font-variant-numeric:tabular-nums;
}

.runtime-card-copy{
  margin-top:10px;

  font-size:11px;
}

.runtime-card-foot{
  display:flex;
  align-items:center;
  justify-content:space-between;
  margin-top:14px;
  padding-top:12px;
  border-top:1px solid rgba(255,255,255,.16);
  color:rgba(255,255,255,.76);
  font-size:12px;
}

.runtime-card-foot b{
  margin:0;
  color:#fff;
  font-size:18px;
}

.runtime-mini-grid{
  display:grid;
  grid-template-columns:repeat(2,minmax(0,1fr));
  gap:8px;
  margin-top:auto;
}

.runtime-mini-grid button{
  display:flex;
  flex-direction:column;
  gap:6px;
  align-items:flex-start;
  width:100%;
  padding:12px;
  border:1px solid transparent;

  text-align:left;
  cursor:pointer;
  transition:border-color .14s,background .14s,box-shadow .14s,transform .14s;
}

.runtime-mini-grid button:hover{
  transform:translateY(-1px);
}

.runtime-mini-grid button:focus-visible{
  outline:none;
}

.runtime-mini-grid button[aria-busy="true"]{
  cursor:wait;
  opacity:.72;
}

.runtime-mini-grid button>span{
  font-size:11px;
}

.runtime-mini-grid button>small{
  font-size:9px;
}

.runtime-mini-grid b{
  margin:0;

  font-size:22px;
}

.runtime-panel{
  overflow:hidden;
  border:1px solid var(--admin-line);
  border-radius:14px;
  background:#fff;
  box-shadow:0 10px 28px rgba(42,58,82,.06);
}

.runtime-panel-head{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:18px;
  padding:18px 20px;
  border-bottom:1px solid var(--admin-line);
}

.runtime-panel-head h2{
  margin:5px 0 3px;
  color:var(--admin-ink-strong);
  font-size:17px;
}

.runtime-panel-head span{
  color:#8e98a5;
  font-size:11px;
}

.runtime-data-note{
  flex:0 0 auto;
}

.runtime-account-list{
  display:grid;
}

.runtime-account{
  display:grid;
  grid-template-columns:auto minmax(0,1fr) auto;
  align-items:center;
  gap:13px;
  min-height:66px;
  padding:12px 20px;
  border-bottom:1px solid #f0f2f4;
}

.runtime-account:last-child{
  border-bottom:0;
}

.runtime-account-avatar{
  display:grid;
  place-items:center;
  width:38px;
  height:38px;
  border-radius:12px;
  color:#fff;
  background:linear-gradient(145deg,#7289ad,#64799c);
  font-size:14px;
  font-weight:800;
}

.runtime-account-identity{
  min-width:0;
}

.runtime-account-identity strong,
.runtime-account-identity span{
  display:block;
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
}

.runtime-account-identity strong{
  color:var(--admin-ink-strong);
  font-size:13px;
}

.runtime-account-identity span{
  margin-top:4px;
  color:#929ca9;
  font-size:10px;
  font-family:ui-monospace,Consolas,monospace;
}

.runtime-account-activity{
  display:flex;
  align-items:flex-end;
  flex-direction:column;
  gap:5px;
}

.runtime-account-activity time{
  font-size:11px;
}

.runtime-presence{
  padding:4px 8px;
  border-radius:999px;
  color:#768394;
  background:#f3f5f7;
  font-size:10px;
  font-weight:700;
}

.runtime-panel .empty{
  padding:42px 20px;
}

.runtime-ranking-panel{
  margin-bottom:22px;
}

.runtime-ranking-table{
  width:100%;
  min-width:620px;
  table-layout:fixed;
}

.runtime-ranking-table th,
.runtime-ranking-table td{
  height:54px;
  padding:10px 18px;
  text-align:center;
}

.runtime-ranking-table th:nth-child(1),
.runtime-ranking-table td:nth-child(1){
  width:13%;
  text-align:center;
}

.runtime-ranking-table th:nth-child(2),
.runtime-ranking-table td:nth-child(2){
  width:44%;
}

.runtime-ranking-table th:nth-child(3),
.runtime-ranking-table td:nth-child(3){
  width:23%;
}

.runtime-ranking-table th:nth-child(4),
.runtime-ranking-table td:nth-child(4){
  width:21%;
}

.runtime-ranking-table tbody tr:last-child td{
  border-bottom:0;
}

.runtime-rank{
  font-size:15px;
  font-weight:800;
  font-variant-numeric:tabular-nums;
}

.runtime-ranking-user{
  color:var(--admin-ink-strong);
  font-size:13px;
  font-weight:700;
  text-align:left;
}

.dashboard-detail-dialog{
  width:min(900px,calc(100% - 32px));
}

.dashboard-detail-form{
  padding:24px;
}

.dashboard-detail-heading{
  display:flex;
  align-items:flex-start;
  justify-content:space-between;
  gap:18px;
  padding-bottom:16px;
  border-bottom:1px solid var(--admin-line);
}

.dashboard-detail-heading h3{
  margin:7px 0 5px;
  color:var(--admin-ink-strong);
  font-size:20px;
}

.dashboard-detail-heading p{
  margin:0;
  color:var(--admin-muted);
  font-size:11px;
}

.dashboard-detail-body{
  min-height:180px;
  max-height:min(560px,calc(100vh - 250px));
  margin:18px 0 0;
  overflow:auto;
}

.dashboard-detail-loading{
  display:grid;
  place-items:center;
  min-height:180px;
  color:var(--admin-muted);
  font-size:12px;
}

.dashboard-detail-table-wrap{
  border:1px solid var(--admin-line);
  border-radius:10px;
  /* 原来是 overflow:hidden：表格比弹窗正文宽时右侧控件被直接裁掉（「绑定设备」弹窗的
     「解绑」按钮实测被裁 34px）。改成横向可滚动，窄窗口下有滚动条而不是缺一块。 */
  overflow-x:auto;
  overflow-y:hidden;
}

/* 「绑定设备」弹窗顶部的搜索框：客户报出设备短 ID 时直接搜到那一行再操作。 */
.device-detail-search-row{
  display:flex;
  align-items:center;
  /* 12px 而不是 8px：要给搜索框聚焦时那圈 4px 淡紫外发光留出余地，
     否则发光会顶到「搜索」按钮上、两个控件黏在一起。 */
  gap:12px;
  /* 本行是弹窗正文的第一个子元素，而正文是 overflow:auto（滚动容器）：不留内边距的话，
     聚焦发光伸出左边缘与上边缘的 4px 会被裁掉（右侧、下侧有空间所以正常）。
     padding-top 4px + margin-bottom 8px = 输入框下方仍是原来的 12px。 */
  padding:4px 4px 0;
  margin-bottom:8px;
}

.device-detail-search{
  flex:1 1 auto;
  min-width:0;
  height:36px;
  padding:0 12px;
  border:1px solid var(--glass-hairline);
  border-radius:11px;
  color:#4c4667;
  background:rgba(255,255,255,.72);
  font:inherit;
}

/* 搜索框聚焦：描边转强调色 + 白底 + 主题那圈 4px 淡紫外发光（行间距已留出余地）。 */
.device-detail-search:focus{
  outline:none;
  border-color:rgba(122,106,208,.6);
  background:#fff;
  box-shadow:0 0 0 4px rgba(122,106,208,.14);
}

/* 「搜索」按钮从 .outline 继承的描边是纯白，在近白的弹窗体上看不出边界，这里给可见描边。 */
.device-detail-search-row .outline{
  border-color:var(--admin-button-line);
}

.device-code-cell{
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:4px;
}

/* 设备短 ID 徽章：点击复制（客户报号、客服核对都靠它）。
   选择器要压得住两条「好心给按钮设尺寸」的规则：弹窗里的 .dashboard-detail-table td button
   与账号详情里的 .account-detail-row.has-action button（后者设了 height:28px / padding:0 12px /
   border-radius:8px / 11px 粗体，同特异性又排在后面，只写类名会被它盖成普通操作按钮）。 */
button.device-short-id-badge,
.dashboard-detail-table td button.device-short-id-badge,
.account-detail-row .device-row-label button.device-short-id-badge{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  height:auto;
  /* 上下内边距不对称是在补偿字体度量：这里字号更小、行高 1.6，墨迹实测偏低约 1px，
     所以从上面挪 1px 到底下。改字号或行高后要重新量。 */
  padding:.5px 8px 1.5px;
  border:1px solid var(--glass-hairline);
  border-radius:999px;
  color:var(--admin-muted-2);
  background:rgba(255,255,255,.72);
  font-family:ui-monospace,Consolas,monospace;
  font-size:9.5px;
  font-weight:400;
  line-height:1.6;
  /* 不要加 letter-spacing：它会在最后一个字符后面也留一格，把整串推到偏右
     （实测 ID 徽章因此右偏 0.42px）。flex 居中 + 零字距才是真的居中。 */
  letter-spacing:0;
}

/* 悬停只作用于弹窗里那枚（灰紫细字 -> 白底强调色）；账号详情那枚是常态样式，
   不参与悬停，鼠标移上去也不变色。 */
button.device-short-id-badge:hover,
.dashboard-detail-table td button.device-short-id-badge:hover{
  border-color:var(--admin-button-line);
  color:var(--admin-accent-deep);
  background:#fff;
}

button.device-short-id-badge.is-copied,
.dashboard-detail-table td button.device-short-id-badge.is-copied,
.account-detail-row .device-row-label button.device-short-id-badge.is-copied{
  /* 「已复制」只是短暂的反馈：底色回到常态的白底，只留绿色描边与文字，
     不要沿用账号详情常态的淡紫底（那样看着像另一种状态面板）。 */
  border-color:rgba(47,157,122,.3);
  color:var(--admin-green);
  background:rgba(255,255,255,.72);
}

/* 账号详情设备行：设备码 + 徽章同一行（徽章再小一号，跟在设备码后面） */
.device-row-label{
  display:inline-flex;
  align-items:center;
  flex-wrap:wrap;
  gap:6px;
}

.account-detail-row .device-row-label button.device-short-id-badge{
  padding:1.5px 6px .5px;
  /* 账号详情里这枚用强调色描边 + 淡紫底 + 深强调色文字，比弹窗里那枚更醒目 */
  border-color:var(--admin-accent);
  background:var(--admin-accent-soft);
  color:var(--admin-accent-deep);
  font-size:11px;
  line-height:1.5;
}

.dashboard-detail-table{
  width:100%;
  min-width:680px;
  table-layout:fixed;
}

.dashboard-detail-table th,
.dashboard-detail-table td{
  height:48px;
  padding:9px 12px;
  text-align:left;
}

.dashboard-detail-table th:nth-child(1),
.dashboard-detail-table td:nth-child(1){
  width:22%;
}

.dashboard-detail-table th:nth-child(2),
.dashboard-detail-table td:nth-child(2){
  width:34%;
}

.dashboard-detail-table th:nth-child(3),
.dashboard-detail-table td:nth-child(3){
  width:24%;
}

.dashboard-detail-table th:nth-child(4),
.dashboard-detail-table td:nth-child(4){
  width:20%;
}

.dashboard-detail-table tbody tr:last-child td{
  border-bottom:0;
}

/* 「绑定设备」明细表比通用三/四列表多出「有效期」「操作」两列，单独重排列宽。
   min-width 从 880 收到 820：弹窗正文实测 846px，原来 880 的表格会被 overflow 裁掉右端。
   百分比按实测内容宽重排：操作列的四个行内按钮（调整时长 / 取消授权 / 解绑 / 删除）
   合计 254px，加单元格 24px 内边距需要 278px，所以操作列取 35%（1440 弹窗下 296px、820 下限下 287px）；
   另一头设备码 26 字符约 150px、有效期与最近心跳各约 70-85px，各留 12%。
   改这里的百分比前先按这组数以实测为准量一遍：操作列的按钮组一旦比列宽大，最右侧的「删除」会被容器裁掉。 */
.dashboard-detail-table.is-devices{
  min-width:820px;
}

.dashboard-detail-table.is-devices th:nth-child(1),
.dashboard-detail-table.is-devices td:nth-child(1){
  width:11%;
}

.dashboard-detail-table.is-devices th:nth-child(2),
.dashboard-detail-table.is-devices td:nth-child(2){
  width:19%;
}

.dashboard-detail-table.is-devices th:nth-child(3),
.dashboard-detail-table.is-devices td:nth-child(3){
  width:12%;
}

.dashboard-detail-table.is-devices th:nth-child(4),
.dashboard-detail-table.is-devices td:nth-child(4){
  width:12%;
}

.dashboard-detail-table.is-devices th:nth-child(5),
.dashboard-detail-table.is-devices td:nth-child(5){
  width:11%;
}

.dashboard-detail-table.is-devices th:nth-child(6),
.dashboard-detail-table.is-devices td:nth-child(6){
  width:35%;
}

.dashboard-detail-table td button{
  height:28px;
  padding:0 12px;
  border:1px solid var(--admin-line-strong);
  border-radius:8px;
  background:#fff;
  color:var(--admin-accent-deep);
  font-size:11px;
  font-weight:800;
  white-space:nowrap;
}

.dashboard-detail-table td button:hover{
  border-color:var(--admin-accent);
  background:var(--admin-accent-soft);
}

/* 现有数据页统一到同一套颜色与圆角。 */
.table-panel,
.tool-panel{
  border-color:var(--admin-line);
  border-radius:12px;
  background:#fff;
  box-shadow:0 10px 28px rgba(42,58,82,.06);
}

.filters,
.code-table .panel-toolbar{
  border-bottom-color:var(--admin-line);
  background:#fafbfc;
}

.search,
.filters select,
.date-filter,
.code-status-filter{
  border-color:var(--admin-line-strong);
  border-radius:8px;
  color:#5f6c7d;
  background:#fff;
}

.filters select:focus,
.search:focus-within,
.date-filter:focus,
.code-status-filter:focus{
  border-color:var(--admin-accent);
  box-shadow:0 0 0 3px rgba(112,137,180,.14);
}

.segment{
  border-radius:9px;
}

.segment:first-child,
.segment:last-child{
  border-radius:9px;
}

.avatar{
  border-radius:10px;
  background:linear-gradient(145deg,#7289ad,#64799c);
  box-shadow:none;
}

.status{
  border-radius:999px;
}

.status.active{
  color:var(--admin-green);
  border-color:rgba(86,133,107,.24);
  background:rgba(86,133,107,.09);
}

.status.pending{
  color:#a8792d;
  border-color:rgba(176,126,43,.22);
  background:rgba(205,155,66,.09);
}

.status.revoked,
.status.rejected{
  color:var(--admin-red);
  border-color:rgba(184,99,92,.22);
  background:rgba(184,99,92,.08);
}

/* 「未发布」是唯一的中性档：既不是能调用（绿）也不是坏了（红）。单独一条规则、排在
   上面几条之后，不要插进 .status.revoked, 那种跨行选择器列表里 —— 插进去会把后半段
   选择器吃掉。描边宽度/线型由主题节那条统一规则给，这里只写颜色。 */
.status.draft{
  color:#8f8aa3;
  border-color:rgba(150,138,196,.24);
  background:rgba(150,138,196,.08);
}

dialog,
.account-detail-dialog,
.admin-dialog-form{
  border-color:var(--admin-line);
  border-radius:14px;
  color:var(--admin-ink);
  background:#fff;
  box-shadow:0 24px 70px rgba(42,58,82,.18);
}

dialog::backdrop{
  background:rgba(35,46,62,.34);
}

@media(max-width:1180px){
  .top-brand{
    width:200px;
  }
  .tab{
    padding:0 11px;
  }
  .runtime-card-rail{
    grid-template-columns:repeat(3,minmax(0,1fr));
  }
}

@media(max-width:860px){
  .topbar{
    height:auto;
    min-height:112px;
    padding:12px 16px 10px;
    flex-wrap:wrap;
    align-content:center;
    gap:9px;
  }
  .top-brand{
    width:auto;
    margin-right:auto;
  }
  .top-brand .brand-mark{
    width:42px;
    height:42px;
    border-radius:12px;
  }
  .top-brand strong{
    font-size:16px;
  }
  .tabs{
    order:3;
    width:100%;
    height:42px;

    overflow-x:auto;
    border-radius:14px;

    scrollbar-width:none;
  }
  .tabs::-webkit-scrollbar{
    display:none;
  }
  .tab{
    flex:0 0 auto;
    min-width:92px;
    height:36px;
    border-radius:11px;
    font-size:12px;
  }
  .tab.active{
    background:#fff;
    box-shadow:0 4px 12px rgba(49,57,70,.09);
  }
  .tab.active:after{
    display:none;
  }
  .admin-tools{
    gap:6px;
    margin-left:0;
  }
  .admin-tools #adminName,
  .admin-tools #changePasswordBtn,
  .admin-tools #logoutBtn,
  .admin-tools>.live-dot{
    display:none;
  }
  .admin-tools .top-button{
    height:34px;
    padding:0 11px;
  }
  .main{
    padding:22px 14px 46px;
  }
  .dashboard-heading{
    align-items:flex-start;
    flex-direction:column;
    gap:20px;
    margin-bottom:34px;
  }
  .dashboard-heading h1{
    font-size:28px;
  }
  .dashboard-refresh{
    gap:4px;
    font-size:12px;
  }
  .dashboard-refresh-next{
    flex-basis:100%;
  }
  .dashboard-actions{
    display:grid;
    grid-template-columns:repeat(3,minmax(0,1fr));
    gap:8px;
    width:100%;
    min-width:0;
  }
  .dashboard-actions .outline{
    display:inline-flex;
    align-items:center;
    justify-content:center;
    width:100%;
    min-width:0;
    height:42px;
    padding:0 6px;
    font-size:13px;
    white-space:nowrap;
  }
  .dashboard-actions .dashboard-account-action{
    display:inline-flex;
  }
  .runtime-intro h2{
    font-size:27px;
  }
  .runtime-intro p{
    font-size:13px;
  }
  .runtime-card-rail{
    display:flex;
    gap:12px;
    margin-right:-14px;
    margin-bottom:18px;
    padding-right:14px;
    overflow-x:auto;
    scroll-snap-type:x mandatory;
    scrollbar-width:none;
  }
  .runtime-card-rail::-webkit-scrollbar{
    display:none;
  }
  .runtime-card{
    flex:0 0 72vw;
    min-height:176px;
    scroll-snap-align:start;
  }
  .runtime-panel-head{
    align-items:flex-start;
    flex-direction:column;
    padding:16px;
  }
  .runtime-ranking-table{
    min-width:540px;
  }
  .runtime-ranking-table th,
  .runtime-ranking-table td{
    padding:10px 12px;
  }
  .runtime-account{
    grid-template-columns:auto minmax(0,1fr);
    padding:13px 16px;
  }
  .runtime-account-activity{
    grid-column:2;
    align-items:center;
    flex-direction:row;
    justify-content:space-between;
    width:100%;
  }
  .code-layout{
    grid-template-columns:1fr;
  }
}

@media(max-width:560px){
  .login-topbar{
    height:58px;
    padding:0 16px;
  }
  .brand-lockup .brand-mark{
    width:38px;
    height:38px;
    border-radius:11px;
  }
  .brand-lockup strong{
    font-size:16px;
  }
  .login-stage{
    min-height:calc(100vh - 58px);
    padding:28px 14px;
  }
  .login-panel{
    padding:24px 20px 22px;
    border-radius:13px;
  }
  .login-panel h2{
    font-size:25px;
  }
  .stat-grid{
    grid-template-columns:repeat(2,minmax(0,1fr));
  }
}

/* 账号详情：按概览、授权、运行、积分和操作分层。 */
.account-detail-dialog{
  width:min(860px,calc(100% - 32px));
  max-height:92vh;
  padding:0;
  overflow:hidden;
  border:1px solid var(--admin-line);
  border-radius:16px;
  background:#fff;
  box-shadow:0 30px 90px rgba(31,45,64,.24);
}

.account-detail-form{
  display:grid;
  grid-template-rows:auto minmax(0,1fr) auto;
  gap:0;
  max-height:92vh;
  padding:0;
  overflow:hidden;
  background:#fff;
}

.account-detail-heading{
  position:relative;
  z-index:2;
  align-items:center;
  padding:22px 24px;
  border-bottom:1px solid var(--admin-line);
}

.account-detail-identity{
  display:flex;
  align-items:center;
  min-width:0;
  gap:14px;
}

.account-detail-avatar{
  display:grid;
  place-items:center;
  flex:0 0 auto;
  width:48px;
  height:48px;
  border-radius:14px;
  color:#fff;
  background:linear-gradient(145deg,#7289ad,#64799c);
  font-size:18px;
  font-weight:800;
}

.account-detail-title-line{
  display:flex;
  align-items:center;
  flex-wrap:wrap;
  gap:9px;
}

.account-detail-heading h3{
  margin:5px 0 0;
  color:var(--admin-ink-strong);
  font-size:21px;
  font-weight:900;
}

.account-detail-status{
  margin-top:5px;
  padding:4px 9px;
  border-radius:999px;
  color:#768394;
  background:#f1f3f6;
  font-size:10px;
  font-weight:800;
}

.account-detail-status.active{
  color:var(--admin-green);
  background:rgba(86,133,107,.11);
}

.account-detail-status.pending{
  color:#a8792d;
  background:rgba(205,155,66,.12);
}

.account-detail-status.expired{
  color:var(--admin-red);
  background:rgba(184,99,92,.1);
}

.account-detail-status.revoked,
.account-detail-status.rejected{
  color:var(--admin-red);
  background:rgba(184,99,92,.1);
}

.account-detail-sub{
  margin:7px 0 0;

  font-family:ui-monospace,Consolas,monospace;
  font-size:10px;
}

.account-detail-body{
  display:block;
  min-height:0;
  padding:20px 24px;
  overflow:auto;
  border:0;
  border-radius:0;
}

.account-detail-metrics{
  display:grid;
  grid-template-columns:repeat(4,minmax(0,1fr));
  gap:10px;
  margin-bottom:14px;
}

.account-detail-metric{
  display:flex;
  flex-direction:column;
  gap:8px;
  min-height:88px;
  padding:15px;
  border:1px solid var(--admin-line);
}

.account-detail-metric span{
  font-size:10px;
}

/* 指标值允许换行：授权有效期是「2027/10/12 15:17:29」这种 19 字符的定长串，
   在 4 列栅格里（内容宽约 163px）单行放不下，原来 nowrap + ellipsis 会把它截成
   「2027/10/12 15:…」。改为在空格处折行显示完整值，卡片高度由栅格自己拉齐。 */
.account-detail-metric strong{
  margin-top:auto;
  overflow-wrap:anywhere;

  font-size:19px;
  line-height:1.2;
}

.account-detail-section,
.account-detail-points{
  margin-bottom:14px;
  padding:18px;
  border:1px solid var(--admin-line);
}

.account-detail-section-head,
.account-detail-points-head{
  display:flex;
  align-items:flex-end;
  justify-content:space-between;
  gap:14px;
  margin-bottom:14px;
}

.account-detail-section-head h4,
.account-detail-points-head h4{
  margin:0;
  color:var(--admin-ink-strong);
  font-size:15px;
  font-weight:900;
}

.account-detail-section-head p,
.account-detail-points-head p{
  margin:5px 0 0;
  color:#909ba8;
  font-size:10px;
}

.account-detail-fields{
  display:grid;
  grid-template-columns:repeat(2,minmax(0,1fr));
  column-gap:24px;
}

.account-detail-row{
  display:flex;
  align-items:baseline;
  justify-content:space-between;
  gap:16px;
  min-width:0;
  padding:11px 0;
  border-bottom:1px solid #eef0f3;
}

.account-detail-row.is-wide{
  grid-column:1/-1;
}

.account-detail-row span{
  flex:0 0 auto;

  font-size:11px;
}

.account-detail-row b{
  min-width:0;
  overflow:hidden;

  font-size:12px;
  font-weight:700;
  text-align:right;
  text-overflow:ellipsis;
  white-space:nowrap;
}

/* 带操作按钮的详情行：标签靠左、取值贴右、按钮再靠右，三者不被 space-between 拆散。 */
.account-detail-row.has-action{
  align-items:center;
  justify-content:flex-start;
}

.account-detail-row.has-action b{
  margin-left:auto;
}

.account-detail-row.has-action button{
  flex:0 0 auto;
  height:28px;
  padding:0 12px;
  border:1px solid var(--admin-line-strong);
  border-radius:8px;
  background:#fff;
  color:var(--admin-accent-deep);
  font-size:11px;
  font-weight:800;
  white-space:nowrap;
}

.account-detail-row.has-action button:hover{
  border-color:var(--admin-accent);
  background:var(--admin-accent-soft);
}

/* 一台设备的多个操作按钮（调整时长 / 取消授权 / 解绑 / 删除）并排，账号详情与绑定设备弹窗共用。
   四个按钮合计约 254px，is-devices 表里「操作」列的宽度必须容得下它，见下面那节的列宽说明。 */
.device-row-actions{
  display:inline-flex;
  gap:6px;
  flex:0 0 auto;
}

.account-detail-points-list{
  max-height:280px;
  overflow:auto;
  border-color:var(--admin-line);
  border-radius:10px;
}

.points-ledger-item{
  grid-template-columns:auto minmax(0,1fr) auto;
  gap:10px;
  padding:10px 12px;
}

.points-ledger-item .points-ledger-date{
  grid-column:2/-1;
  margin-top:-4px;
  text-align:right;
}

.points-ledger-note{
  font-size:11px;
}

.account-detail-action-group{
  padding-bottom:16px;
}

.account-detail-actions{
  display:flex;
  flex-wrap:wrap;
  gap:8px;
}

.account-detail-actions button{
  height:34px;
  padding:0 13px;
  border:1px solid var(--admin-line-strong);
  border-radius:9px;
  color:#5f6d7e;
  background:#fff;
  font-size:11px;
  font-weight:700;
}

.account-detail-actions button:hover{
  border-color:#bfc9d8;
  color:var(--admin-accent-deep);
  background:#f7f9fc;
}

.account-detail-action-group.is-danger{
  margin-bottom:0;
}

.account-detail-action-group.is-danger .account-detail-actions button.danger{
  color:var(--admin-red);
  border-color:rgba(184,99,92,.3);
  background:#fff;
}

.account-detail-form>.dialog-actions{
  justify-content:flex-end;
  margin:0;
  padding:14px 24px;
  border-top:1px solid var(--admin-line);
}

@media(max-width:700px){
  .account-detail-dialog{
    width:calc(100% - 20px);
    max-height:94vh;
    border-radius:14px;
  }

  .account-detail-form{
    max-height:94vh;
  }

  .account-detail-heading{
    padding:17px 16px;
  }

  .account-detail-avatar{
    width:42px;
    height:42px;
    border-radius:12px;
    font-size:16px;
  }

  .account-detail-heading h3{
    font-size:18px;
  }

  .account-detail-body{
    padding:14px;
  }

  .account-detail-metrics{
    grid-template-columns:repeat(2,minmax(0,1fr));
  }

  .account-detail-metric{
    min-height:78px;
    padding:13px;
  }

  .account-detail-section,
  .account-detail-points{
    padding:15px;
  }

  .account-detail-fields{
    grid-template-columns:1fr;
  }

  .account-detail-row.is-wide{
    grid-column:auto;
  }

  .account-detail-actions button{
    flex:1 1 calc(50% - 8px);
    min-width:0;
  }

  .account-detail-form>.dialog-actions{
    padding:12px 14px;
  }
}

/* —— 内置模型目录 —— */
.builtin-model-panel{
  overflow:hidden;
}

/* 面板头（标题块 + 操作）的共用布局：模型列表、服务商、公告、运营看板都用 `.builtin-model-toolbar`
   （运营看板早先只写了 `.panel-toolbar`，而这条布局规则不在 `.panel-toolbar` 上，于是标题贴到面板
   左边缘、比下面的内容还靠左，`刷新` 也掉到第二行）。 */
.builtin-model-toolbar{
  display:flex;
  align-items:flex-start;
  justify-content:space-between;
  gap:12px;
  /* 与 .builtin-model-list 的 18px 对齐，标题和下方卡片左边缘成一条线。 */
  padding:18px;
  border-bottom:1px solid var(--admin-line);
}

.builtin-model-path{
  max-width:min(52vw,620px);
  overflow:hidden;
  color:#8b96a4;
  font-size:10px;
  text-overflow:ellipsis;
  white-space:nowrap;
}

.builtin-model-list{
  display:grid;
  gap:14px;
  padding:18px;
}

.builtin-model-card{
  padding:16px;
}

.builtin-model-card-head{
  display:flex;
  align-items:flex-start;
  justify-content:space-between;
  gap:16px;
  margin-bottom:14px;
}

/* 卡片头部右侧的按钮组（测试连接 / 删除）。不加这层包裹的话，卡片头是
   space-between 的两列布局，两个按钮会被当成两个独立子项分别推到两端。
   按钮一律不折行：手机端卡片头只剩三百多像素，松手就会折成「测试/连接」「删/除」。 */
.builtin-model-card-head-actions{
  display:flex;
  align-items:center;
  gap:8px;
  flex:0 0 auto;
}

.builtin-model-card-head-actions button{
  white-space:nowrap;
}

/* 「测试连接」和弹窗底部按钮是同一个坑：继承 .outline 的 --glass-border（纯白），
   在近白的卡片底上合成出来就是 rgb(255,255,255)，看着没有边框。这里取弹窗底部
   按钮同一档的 --admin-button-line。用 :not(.danger-outline) 把「删除」排除在外：
   它自带危险色描边，不要被这条压掉。 */
.builtin-model-card-head-actions .outline:not(.danger-outline){
  border-color:var(--admin-button-line);
}

/* 模型卡片标题下的状态徽章行：h3 自带 margin:4px 0 0，徽章再贴上去会挤在一起。 */
.builtin-model-status-row{
  margin-top:8px;
}

.builtin-model-card-head h3{
  margin:4px 0 0;
  color:var(--admin-ink-strong);
  font-size:16px;
  font-weight:900;
}

/* 网格各格一律按内容定高、顶端对齐。默认的 align-items:normal（＝stretch）会把格子拉到
   本排最高那一格的高度，多出来的高度再由 label 自己的 align-content:stretch 平摊进
   「标签行」与「控件行」，于是同一排里控件落在不同高度上——实测「积分消耗」被推下 38px、
   「上游单价」20px、「启用 / 发布」65px。修掉这两处 stretch 才会顶边齐平。 */
.builtin-model-grid{
  display:grid;
  grid-template-columns:repeat(4,minmax(0,1fr));
  align-items:start;
  gap:12px;
}

.builtin-model-grid label{
  display:grid;
  align-content:start;
  gap:6px;
  min-width:0;

  font-size:10px;
  font-weight:700;
}

/* 卡片里的分区标题：占满整行，右侧拖一条淡紫细线到边，把三段分开。
   字段一多就得让「这是哪一类信息」一眼可见，否则十来个框排在一片灰字里没有归宿。 */
.builtin-model-section{
  grid-column:1 / -1;
  display:flex;
  align-items:baseline;
  flex-wrap:wrap;
  gap:4px 10px;
  margin:8px 0 0;

  color:var(--admin-ink-strong);
  font-size:11px;
  font-weight:800;
}

/* 第一段顶着卡片头，不用再让开上一段的间距。 */
.builtin-model-section:first-child{
  margin-top:0;
}

/* 细线吃掉标题右侧的剩余宽度；窄屏上标题和说明换行后，它跟到下一行继续铺。
   用 --glass-hairline（淡紫）而不是 --admin-line（纯白）：卡片底本来就接近白，
   白线在它上面看不出来。 */
.builtin-model-section::after{
  content:'';
  flex:1 1 40px;
  min-width:24px;
  height:1px;
  align-self:center;
  background:var(--glass-hairline);
}

.builtin-model-section em{
  font-style:normal;
  font-size:10px;
  font-weight:500;
  color:var(--muted);
  opacity:.82;
}

.builtin-model-grid input,
.builtin-model-grid select,
.builtin-model-grid textarea{
  width:100%;
  min-width:0;
  border:1px solid var(--admin-line-strong);
  border-radius:9px;
  color:var(--admin-ink-strong);
  background:#fff;
  font:inherit;
  font-size:12px;
  font-weight:600;
  outline:none;
}

.builtin-model-grid input,
.builtin-model-grid select{
  height:36px;
  padding:0 10px;
}

.builtin-model-grid textarea{
  min-height:64px;
  padding:9px 10px;
  resize:vertical;
  line-height:1.5;
}

.builtin-model-grid input:focus,
.builtin-model-grid select:focus,
.builtin-model-grid textarea:focus{
  border-color:#9eb5d3;
  box-shadow:0 0 0 3px rgba(104,135,178,.1);
}

/* 分级计费的价格档位：占满整行，行内「清晰度 / 时长 / 积分 / 删除」四个控件。
   窄屏下允许整行换列，避免 390px 时把积分输入挤到读不出来。 */
.builtin-model-tiers{
  grid-column:1 / -1;
  display:grid;
  gap:8px;
  padding:12px;
  border:1px solid var(--glass-hairline);
  border-radius:12px;
  background:var(--dt-surface);
}

.builtin-model-tiers-head{
  display:flex;
  flex-wrap:wrap;
  align-items:baseline;
  gap:4px 10px;
  font-size:10px;
  color:var(--muted);
}

.builtin-model-tiers-head strong{
  color:var(--admin-ink-strong);
  font-size:11px;
}

/* 档位与「生图分辨率」声明不匹配时提前警告：服务端保存会拒绝，别等点保存才报错。 */
.builtin-model-tier-warning{
  color:var(--red);
  font-size:10px;
  font-weight:700;
}

.builtin-model-tier{
  display:flex;
  flex-wrap:wrap;
  align-items:end;
  gap:8px;
  padding-top:8px;
  border-top:1px dashed var(--glass-hairline);
}

.builtin-model-tier:first-of-type{
  border-top:0;
  padding-top:0;
}

.builtin-model-tier label{
  display:grid;
  gap:4px;
  min-width:110px;
  flex:1 1 120px;
  font-size:10px;
  font-weight:700;
}

.builtin-model-tier input,
.builtin-model-tier select{
  width:100%;
}

.builtin-model-tier-remove{
  flex:0 0 auto;
}

.builtin-model-token-hint{
  grid-column:1 / -1;
}

@media(max-width:640px){
  .builtin-model-tier{
    flex-direction:column;
    align-items:stretch;
  }
  /* 纵向排列时 flex-basis 变成「高度」，沿用行内的 120px 会把每个控件拉成一整格，
     实测 390px 下两组档位要滚将近三屏。这里退回内容高度。 */
  .builtin-model-tier label{
    flex:0 0 auto;
  }
}

.builtin-model-description{
  grid-column:span 2;
}

/* 模型卡里「模型介绍」与「使用服务商」同排，吃掉这一排剩下的 3 格。
   **只在 4 列时给**：列数在 980px 会掉到 2 列，那时 span 3 会在右边撑出一条隐式列，
   整张卡横向溢出（见下面 @media(max-width:980px) 的回退）。 */
.builtin-model-description--wide{
  grid-column:span 3;
}

.builtin-model-switches{
  display:flex;
  align-items:center;
  flex-wrap:wrap;
  gap:8px 16px;
  min-height:36px;
}

.builtin-model-switch{
  display:inline-flex !important;
  grid-template-columns:none !important;
  align-items:center;
  gap:7px !important;
  min-height:36px;

  cursor:pointer;
}

.builtin-model-switch input{
  width:16px;
  height:16px;
}

/* 「发布与能力」的五个勾选项并成一排：左边两个是上下架开关，右边三个是参考能力。
   中间一条竖线把两组分开——一组决定「能不能调」，一组决定「支持哪些参考」，
   不分组就会被读成同一件事（说明文字在分区标题里，不可删）。 */
.builtin-model-toggle-row{
  grid-column:1 / -1;
  display:flex;
  align-items:center;
  flex-wrap:wrap;
  gap:4px 20px;
}

.builtin-model-toggle-divider{
  width:1px;
  align-self:stretch;
  min-height:20px;
  background:var(--glass-hairline);
}

/* 「1 积分 = ? 元」：部署级定价政策，挨着模型列表标题放，跟模型一起保存。
   它不属于任何单个模型，所以不进卡片网格，而是占工具栏中间那一格。 */
.builtin-points-value{
  display:inline-flex;
  align-items:center;
  gap:6px;
  flex:0 0 auto;

  font-size:11px;
  font-weight:700;
  white-space:nowrap;
}

.builtin-points-value input{
  width:88px;
  height:30px;
  padding:0 8px;
  border:1px solid var(--admin-line-strong);
  border-radius:8px;
  color:var(--admin-ink-strong);
  background:#fff;
  font:inherit;
  font-size:12px;
  font-weight:600;
  text-align:right;
  outline:none;
}

/* 表单字段下面那行灰字：说明口径与用途（如「上游单价」是成本、不是售价）。
   `.builtin-model-grid label` 本身是 grid，所以它自然落到输入框的下一行。 */
.builtin-model-field-hint{
  font-size:10px;
  font-weight:500;
  color:var(--muted);
  opacity:.82;
  line-height:1.5;
}

/* 「上游单价」是「口径下拉 + 金额」两个控件共用一个字段名，所以格外包一层 flex 行。
   下拉按内容定宽（`width:auto` 压掉 .builtin-model-grid select 的 100%），金额吃掉剩余宽度；
   金额的 `flex-basis:0` 是为了让 .builtin-model-grid input 的 `width:100%` 不再参与计算，
   否则它会按容器宽度撑开、把下拉挤出这一格。
   **窄屏下允许换行**：390px 时这一格只有约 111px，下拉 66px 之后金额只剩 37px——
   数字还在但已经读不出来了（实测）。给金额一个 min-width，放不下就整行落到下一行。 */
.builtin-model-cost-row{
  display:flex;
  flex-wrap:wrap;
  align-items:center;
  gap:8px;
  min-width:0;
}

.builtin-model-cost-row select{
  flex:0 0 auto;
  width:auto;
}

.builtin-model-cost-row input{
  flex:1 1 0;
  min-width:72px;
}

.builtin-model-panel>.message{
  margin:0 18px 18px;
}

/* 运营看板：卡片承担「一眼看健康度」，表格承担「谁在拖后腿」。
   告警态用左侧色条而不是整块配色——整块变色会让一屏里的所有卡片都在喊。 */
.builtin-metrics-panel{
  margin-bottom:18px;
}

.builtin-metrics-body{
  display:flex;
  flex-direction:column;
  gap:16px;
  padding:0 18px 18px;
}

/* —— 运营看板：五段（今天赚不赚 / 交付 / 需要关注 / 明细 / 容量）——
   为什么要分段：原来 12 张等权重的卡片混在一锅，「今日成功 0」和「今日毛利 −0.80」一样大，
   而运营者打开这一页最先要知道的是**今天赚没赚**。所以钱那一排用大号数字当主角、交付压成一行、
   故障信号单独成段（没有故障时收成一句话，而不是留一面「0 与 —」的墙）、容量折成一行。
   几何仍沿用本节的卡片材质（--glass-hairline / --dt-surface / --dt-radius-sm）。 */
.builtin-metrics-band{
  display:flex;
  flex-direction:column;
  gap:10px;
}

.builtin-band-label{
  margin:0;
  font-size:10px;
  font-weight:900;
  letter-spacing:.12em;
  color:var(--admin-muted);
}

/* ① 今天赚不赚：四块大号数字。 */
.builtin-hero-row{
  display:grid;
  grid-template-columns:repeat(4,minmax(0,1fr));
  gap:12px;
}

.builtin-hero{
  display:flex;
  flex-direction:column;
  gap:2px;
  min-width:0;
  padding:14px 16px;
  border:1px solid var(--glass-hairline);
  border-radius:var(--dt-radius-sm);
  background:var(--dt-surface);
}

.builtin-hero-label{
  font-size:11px;
  color:var(--admin-muted);
}

.builtin-hero-value{
  font-size:26px;
  font-weight:900;
  line-height:1.15;
  letter-spacing:-.02em;
  color:var(--admin-ink-strong);
}

.builtin-hero-hint{
  font-size:11px;
  font-style:normal;
  line-height:1.5;
  color:var(--admin-muted);
  opacity:.85;
}

/* 负毛利是运营者唯一必须立刻看到的东西；正毛利给一个「没事」的绿。 */
.builtin-hero.warn .builtin-hero-value{ color:var(--admin-red); }

.builtin-hero.good .builtin-hero-value{ color:var(--admin-green); }

/* ② 交付：成功率是主数，成功 / 失败 / 排队与耗时并排其后。 */
.builtin-delivery{
  display:flex;
  align-items:center;
  flex-wrap:wrap;
  gap:22px;
  padding:14px 16px;
  border:1px solid var(--glass-hairline);
  border-radius:var(--dt-radius-sm);
  background:var(--dt-surface);
}

.builtin-delivery-rate{
  display:flex;
  flex-direction:column;
  gap:2px;
  padding-right:22px;
  border-right:1px solid var(--glass-hairline);
}

.builtin-delivery-rate strong{
  font-size:26px;
  font-weight:900;
  line-height:1.15;
  letter-spacing:-.02em;
  color:var(--admin-ink-strong);
}

.builtin-delivery-rate span{
  font-size:11px;
  color:var(--admin-muted);
}

.builtin-delivery-rate em{
  font-size:10px;
  font-style:normal;
  color:var(--admin-muted);
  opacity:.8;
}

.builtin-delivery-stats{
  display:flex;
  flex-wrap:wrap;
  gap:20px;
  min-width:0;
}

.builtin-stat{
  display:flex;
  flex-direction:column;
  gap:2px;
}

.builtin-stat b{
  font-size:16px;
  font-weight:800;
  color:var(--admin-ink-strong);
}

.builtin-stat span{
  font-size:10px;
  color:var(--admin-muted);
}

.builtin-stat.warn b{ color:var(--admin-red); }

/* ④ 需要关注：出问题时逐条列出来；全干净时是一句绿色的话。 */
.builtin-alerts{
  display:flex;
  flex-direction:column;
  gap:8px;
}

.builtin-alert{
  display:flex;
  align-items:flex-start;
  gap:12px;
  padding:12px 16px;
  border:1px solid var(--glass-hairline);
  border-left:3px solid var(--admin-red);
  border-radius:var(--dt-radius-sm);
  background:var(--dt-surface);
}

.builtin-alert>b{
  flex:0 0 auto;
  min-width:28px;
  font-size:20px;
  font-weight:900;
  line-height:1.2;
  color:var(--admin-red);
}

.builtin-alert>span{
  display:flex;
  flex-direction:column;
  gap:2px;
  min-width:0;
}

.builtin-alert strong{
  font-size:12px;
  font-weight:700;
  color:var(--admin-ink-strong);
}

.builtin-alert em{
  font-size:11px;
  font-style:normal;
  line-height:1.5;
  color:var(--admin-muted);
}

.builtin-alerts.is-clear{
  padding:12px 16px;
  border:1px solid var(--glass-hairline);
  border-left:3px solid var(--admin-green);
  border-radius:var(--dt-radius-sm);
  background:var(--dt-surface);
  font-size:11px;
  line-height:1.5;
  color:var(--admin-muted);
}

/* ⑤ 明细为空时的中性提示。**不要复用 `.builtin-alerts.is-clear`**：那条绿边是「没问题」的信号，
   而「今天还没有记录」只是没数据，不是好消息。 */
.builtin-metrics-note{
  padding:12px 16px;
  border:1px solid var(--glass-hairline);
  border-radius:var(--dt-radius-sm);
  background:var(--dt-surface);
  font-size:11px;
  line-height:1.5;
  color:var(--admin-muted);
}

/* ③ 容量：四张卡。有上限的（参考素材 / 成片暂存）多一条占用条——这一段要回答的是
   「离写满还有多远」，光给占用数字看不出来。任务表 / 台账没有上限，靠保留期控体积，
   所以它们的第三行写「保留 N 天」。 */
.builtin-capacity-cards{
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(200px,1fr));
  gap:12px;
}

.builtin-capacity-card{
  display:flex;
  flex-direction:column;
  gap:4px;
  min-width:0;
  padding:12px 16px;
  border:1px solid var(--glass-hairline);
  border-radius:var(--dt-radius-sm);
  background:var(--dt-surface);
}

.builtin-capacity-label{
  font-size:11px;
  color:var(--admin-muted);
}

.builtin-capacity-value{
  font-size:18px;
  font-weight:800;
  line-height:1.2;
  color:var(--admin-ink-strong);
}

.builtin-capacity-note{
  font-size:10px;
  line-height:1.5;
  color:var(--admin-muted);
  opacity:.85;
}

/* 占用条：原生 `<progress>`，只改外观。Chromium 需要 appearance:none 才能吃到下面两个伪元素。 */
.builtin-meter{
  display:block;
  width:100%;
  height:6px;
  margin-top:2px;
  appearance:none;
  border:0;
  border-radius:999px;
  background:var(--admin-accent-soft);
}

.builtin-meter::-webkit-progress-bar{
  border-radius:999px;
  background:var(--admin-accent-soft);
}

.builtin-meter::-webkit-progress-value{
  border-radius:999px;
  background:var(--admin-accent);
}

/* 到 80% 才转红：早于这个数就报警会把「正常在涨」当成事故。 */
.builtin-capacity-card.warn .builtin-capacity-value{
  color:var(--admin-red);
}

.builtin-capacity-card.warn .builtin-meter::-webkit-progress-value{
  background:var(--admin-red);
}

/* 钱那一排：宽屏 4 列、中屏 2 列、窄屏 1 列——数字大，挤在一起就没法一眼读完。 */
@media(max-width:1180px){
  .builtin-hero-row{
    grid-template-columns:repeat(2,minmax(0,1fr));
  }
}

@media(max-width:640px){
  .builtin-hero-row{
    grid-template-columns:minmax(0,1fr);
  }

  .builtin-delivery-rate{
    padding-right:0;
    border-right:0;
  }

  /* 窄屏上让这几个小数字对齐成网格：flex 换行后每一格宽度随文字长短变化，
     六个数会摆得参差不齐（390px 实测）。 */
  .builtin-delivery-stats{
    display:grid;
    grid-template-columns:repeat(3,minmax(0,1fr));
    gap:12px 16px;
    width:100%;
  }
}

.builtin-metrics-tables{
  display:grid;
  /* 轨道照旧按 1fr 铺满一行（所以有几张表就几列、宽度均匀）。**坑在「只剩一张表」的前提下**：
     `builtinMetricsTable` 在行数为 0 时返回空串，0 单时只有「存储」一张，auto-fit 把空轨道收掉后
     这一张会**独占整条轨道被拉满整个面板**（三列被撕到两端、中间一大片空白）。
     不要在 `minmax` 上写上限来修——`repeat(auto-fit, …)` 的重复次数是按轨道的**上限**算的，
     给个 420px 会让 1442px 宽的容器只排 3 列、第 4 张表直接换行。给表格自己加 `max-width` 最稳。 */
  grid-template-columns:repeat(auto-fit,minmax(240px,1fr));
  gap:16px;
  align-items:start;
  /* 网格子项的 min-width 默认是 auto：表格内容一旦不可断行，它会撑破轨道、把整行顶出面板。 */
  min-width:0;
}

.builtin-metrics-table{
  width:100%;
  /* 见上：单独一张表时不让它横跨整个面板。多张表时每张都不到这个宽度，等于不生效。 */
  max-width:480px;
  /* 全局 table 带 min-width:1100px（它是给账号/激活码那种宽表用的）。看板这三张表要放进
     网格轨道里，必须收掉这个下限，否则每张表都撑到 1100px、把容器顶出横向滚动
     （本表里 `.audit-table table` 也是同样的处理）。 */
  min-width:0;
  border-collapse:collapse;
  font-size:12px;
  table-layout:fixed;
}

.builtin-metrics-table th,
.builtin-metrics-table td{
  padding:7px 8px;
  border-bottom:1px solid var(--glass-hairline);
  text-align:left;
  /* 失败原因常是一整段上游原文（英文长串、JSON、模型名）：只写 overflow-wrap 在 fixed
     布局下仍可能被撑开，两个属性一起给，中英文都能在任意位置断行。 */
  overflow-wrap:anywhere;
  word-break:break-word;
}

/* 第一列（模型名 / 失败原因）吃掉剩余宽度。fixed 布局下不给它定宽时，列宽会按内容算，
   长文案于是把表头一起顶出右侧——`max-width:0` 是让表格自己分配剩余宽度的标准做法。 */
.builtin-metrics-table th:first-child,
.builtin-metrics-table td:first-child{
  width:auto;
  max-width:0;
}

.builtin-metrics-table th{
  color:var(--muted);
  font-weight:500;
}

.builtin-metrics-table td:not(:first-child),
.builtin-metrics-table th:not(:first-child){
  width:84px;
  white-space:nowrap;
}

/* 窄屏（390px 实测）下表格只有 323px 宽：三四个数字列各占 84px 会把第一列挤到几个像素，
   模型名 / 失败原因就没法读了。收窄数字列、同时压掉左右内边距，把宽度让回第一列。 */
@media(max-width:640px){
  .builtin-metrics-table td:not(:first-child),
  .builtin-metrics-table th:not(:first-child){
    width:56px;
    padding-left:4px;
    padding-right:4px;
  }
}

@media(max-width:980px){
  .builtin-model-grid{
    grid-template-columns:repeat(2,minmax(0,1fr));
  }

  /* 2 列时不再跨列，跟「使用服务商」并排站一格。 */
  .builtin-model-description--wide{
    grid-column:auto;
  }

  .builtin-model-path{
    max-width:42vw;
  }
}

@media(max-width:700px){
  .builtin-model-path{
    display:none;
  }

  .builtin-model-list{
    padding:12px;
  }

  .builtin-model-card{
    padding:14px;
  }

  .builtin-model-grid{
    grid-template-columns:minmax(0,1fr);
  }

  .builtin-model-description{
    grid-column:auto;
  }

  /* 一格宽时「上下架」与「参考能力」必然各占一行，竖线会孤零零挂在第一行末尾、
     不再分隔任何东西，所以窄屏直接收掉。 */
  .builtin-model-toggle-divider{
    display:none;
  }

  .builtin-model-panel>.message{
    margin:0 12px 12px;
  }

  /* 窄屏上工具栏是「标题 + 积分面值」（.builtin-model-path 此时已隐藏）；
     标题文字长的时候让积分面值换到下一行，而不是把它挤出容器。 */
  .builtin-model-toolbar{
    flex-wrap:wrap;
    row-gap:8px;
  }
}

/* 客户端公告页。列表卡片直接复用 .builtin-model-* 的几何（含卡片网格里的下拉与
   多行文本框），这里只补公告特有的两处：行内上移/下移/删除按钮组、生效状态徽章。
   早先这里还压过一条 `#noticePage .builtin-model-grid label{align-content:start}`
   （公告页正文框一高、标题框就被推到单元格竖直中间），现在这条已经提到
   `.builtin-model-grid label` 上、两个页面共用，不必再单独写一份。 */

.notice-row-actions{
  display:flex;
  flex:0 0 auto;
  gap:8px;
}

.notice-row-actions .outline{
  height:30px;
  padding:0 12px;
  white-space:nowrap;
}

/* 徽章一律带描边：只写 color 不写 border 宽度与线型是不生效的。 */
.notice-state{
  display:inline-flex;
  align-items:center;

  margin-right:9px;
  padding:2px 9px;

  border:1px solid transparent;
  border-radius:999px;

  font-size:10px;
  font-weight:800;
  vertical-align:middle;
}

.notice-state.is-on{
  border-color:rgba(23,114,79,.32);
  color:var(--admin-green);
  background:rgba(23,114,79,.07);
}

.notice-state.is-off{
  border-color:var(--glass-hairline);
  color:var(--admin-muted);
  background:rgba(150,138,196,.08);
}

@media(max-width:700px){
  /* 窄屏下按钮组会被标题挤到换行，直接竖排；只作用于公告页，
     不要顺手改 .builtin-model-card-head 本身而影响内置模型页。 */
  #noticePage .builtin-model-card-head{
    flex-direction:column;
  }
}

/* ============================================================
   八、当前主题：蓝紫白毛玻璃

   页面令牌（#1 :root）与各组件在此节的材质、配色集中定义；几何尺寸、
   栅格与响应式断点沿用前面的分节。改配色前先确认 :root 里的令牌含义，
   以及 docs/变更与设计记录.md 里记录的对比度下限。
   ============================================================ */
:root{
  /* 玻璃材质 */
  --glass-surface:rgba(255,255,255,.58);
  --glass-border:rgba(255,255,255,.72);
  --glass-hairline:rgba(150,138,196,.2);
  --glass-blur:saturate(155%) blur(18px);
  --glass-blur-lg:saturate(165%) blur(28px);
  --glass-shadow:0 14px 34px rgba(88,74,150,.1),0 2px 8px rgba(88,74,150,.06);
  --glass-shadow-lg:0 30px 80px rgba(70,58,130,.2),0 6px 18px rgba(70,58,130,.08);
  /* 品牌紫罗兰渐变：所有「白字压渐变」的表面（主按钮、选中页签、选中分段、品牌方块、
     头像、日历选中日）共用它。两端用色的明度按白字对比度反推——原来的 #8b7ae4 / #6b8ef2
     明度约 0.29，白字只有 3.0~3.2:1；现值两端约 0.127 / 0.137，白字 5.6~5.9:1，
     留出余量吸收渐变端点、内描边和抗锯齿带来的局部变亮。色相仍是紫→蓝紫（H 252°→232°）。
     改这个令牌前先量白字对比度。 */
  --glass-tint:linear-gradient(135deg,#6250cc 0%,#4a5cd0 100%);

  /* 语义令牌 */
  --admin-bg:#fbfcff;
  --admin-ink:#3b3653;
  --admin-ink-strong:#201c37;
  /* 弱文字色的下限按「最不利底色」（带蓝紫的卡片底）实测 >= 4.5:1 反推，
     不能再取更浅的值。层级靠字重与字号拉开，不靠继续变浅。 */
  --admin-muted:#69647f;
  --admin-muted-2:#635e81;
  --admin-line:rgba(255,255,255,.72);
  --admin-line-strong:rgba(150,138,196,.3);
  /* 弹窗底部按钮（取消 / 关闭）的描边：继承 .outline 的 --glass-border 是纯白，
     --glass-hairline(.2) 合成后又只有 rgb(234,232,243)，实测「关闭」几乎融进背景，
     所以这里专取深一档的强调色线。取值低于 .outline:hover 的 rgba(122,106,208,.42)，
     悬停才有加深的层次。 */
  --admin-button-line:rgba(122,106,208,.34);
  --admin-accent:#7a6ad0;
  --admin-accent-deep:#6753c2;
  --admin-accent-soft:rgba(122,106,208,.12);
  --admin-sky:#3fa9f5;
  /* 绿/红直接取「小字也够用」的深档：这两个色在本主题里只用于文字、
     3px 色条和状态底（底用的是固定 rgba，不跟令牌），没有大面积填充，所以不需要再分两档。 */
  --admin-green:#17724f;
  --admin-red:#ad3b47;

  /* 兼容暖金层与精修层遗留令牌 */
  --dt-gold:#7a6ad0;
  --dt-gold-hot:#6753c2;
  --dt-gold-soft:rgba(122,106,208,.12);
  --dt-ink:#3b3653;
  --dt-ink-soft:#544d74;
  --dt-muted:#69647f;
  --dt-muted-2:#635e81;
  --dt-line:rgba(150,138,196,.24);
  --dt-line-strong:rgba(150,138,196,.36);
  --dt-surface:rgba(255,255,255,.6);
  --dt-surface-2:rgba(255,255,255,.5);
  --dt-surface-3:rgba(122,106,208,.08);
  --dt-green:#17724f;
  --dt-red:#ad3b47;
  --dt-radius:16px;
  --dt-radius-sm:11px;
  --dt-shadow-sm:0 10px 26px rgba(88,74,150,.08);
  --dt-shadow:0 16px 40px rgba(88,74,150,.12);
  --dt-shadow-lg:0 30px 80px rgba(70,58,130,.2),0 6px 18px rgba(70,58,130,.08);

  /* 早期层使用的裸变量，统一到同一套蓝紫配色，避免个别规则漏改后仍取到暖金或墨绿。 */
  --bg:#eef1fa;
  --paper:rgba(255,255,255,.82);
  --ink:var(--admin-ink);
  --muted:var(--admin-muted);
  --line:var(--glass-hairline);
  --gold:var(--admin-accent);
  --green:var(--admin-green);
  --red:var(--admin-red);
  --shadow:var(--glass-shadow);

  /* 早期层唯一残留绑定：--nav 的最后一次定义原本在第二个 :root，且被 var(--nav) 使用，
     塌缩时按原值搬运过来，保证行为不变。 */
  --nav:#fffaf0;
}

html{
  background:#fbfcff;
}

body{
  color:var(--admin-ink);
  background:#fbfcff;
}

::selection{
  background:rgba(122,106,208,.22);
}

button:focus-visible,
select:focus-visible,
input:focus-visible,
a:focus-visible{
  outline:2px solid rgba(122,106,208,.55);
}

/* —— 页面底色：白起底、四角着色、中部留白的蓝紫柔光 ——
   参考稿是一张模糊过的色块图：紫在右上、粉紫在左上、蓝在右侧与左下，
   中间和底部大片留白。所以基色用近白，只在四角叠柔和径向色斑，
   再用一层居中白斑把中间压回白，避免整页变成一条连续渐变。
   background-attachment:fixed 让色斑固定在视口上，长页面滚动时不会拉长变色。 */
.login-view,
.app-view{
  background-color:#fbfcff;
  background-image:
    /* 点阵层放最前（background-image 的第一层画在最上面），按参考图实测取值：
       点距 18px、点径约 2px、点与底色明度差约 16。放在这里而不是 body 上——
       页面底色由本规则的多层渐变铺满，写在 body 上的背景会被它整个盖住、根本看不见。 */
    radial-gradient(circle,rgba(150,138,196,.16) 1px,transparent 1.4px),
    /* 右上：紫（负坐标把色斑压进角落，避免变成居中圆斑） */
    radial-gradient(58% 46% at 99% -8%,rgba(157,122,238,.82),rgba(157,122,238,0) 63%),
    /* 左上：粉紫 */
    radial-gradient(48% 34% at -4% -6%,rgba(238,178,225,.74),rgba(238,178,225,0) 60%),
    /* 右侧：蓝 */
    radial-gradient(50% 42% at 106% 46%,rgba(138,192,247,.78),rgba(138,192,247,0) 64%),
    /* 左下：青蓝 */
    radial-gradient(56% 44% at -6% 106%,rgba(144,208,247,.78),rgba(144,208,247,0) 64%),
    /* 右下：淡紫 */
    radial-gradient(48% 36% at 98% 106%,rgba(190,178,244,.68),rgba(190,178,244,0) 62%),
    /* 中部：留白 */
    radial-gradient(70% 60% at 42% 46%,rgba(255,255,255,.94),rgba(255,255,255,0) 74%),
    linear-gradient(135deg,#ffffff 0%,#eff6fe 34%,#f3ecfc 62%,#ffffff 100%);
  /* 每层都要给尺寸：点阵 18px 平铺，其余渐变仍按容器自适应。 */
  background-size:18px 18px,auto,auto,auto,auto,auto,auto,auto;
  background-attachment:fixed;
}

.login-view:before{
  background:none;
}

.login-stage{
  background:transparent;
}

/* —— 登录页 —— */
.login-topbar{
  border-bottom:1px solid var(--glass-border);
  background:rgba(255,255,255,.55);
  box-shadow:0 6px 24px rgba(88,74,150,.07);
  backdrop-filter:var(--glass-blur);
}

.login-panel{
  border:1px solid var(--glass-border);
  border-radius:22px;
  background:rgba(255,255,255,.66);
  box-shadow:var(--glass-shadow-lg);
  backdrop-filter:var(--glass-blur-lg);
}

.login-panel .primary.wide{
  border-color:transparent;
  border-radius:13px;
  background:var(--glass-tint);
  box-shadow:0 12px 28px rgba(105,95,205,.3);
}

.login-hint{
  color:var(--admin-muted-2);
}

.login-hint code{
  color:#6753c2;
}

.remember-option input{
  accent-color:#7a6ad0;
}

/* —— 品牌标识与顶栏 —— */
.brand-mark,
.top-brand .brand-mark,
.brand-lockup .brand-mark{
  color:#fff;
  background:var(--glass-tint);
  box-shadow:0 8px 20px rgba(105,95,205,.3);
}

.topbar{
  border-bottom:1px solid var(--glass-border);
  background:rgba(255,255,255,.55);
  box-shadow:0 6px 24px rgba(88,74,150,.07);
  backdrop-filter:var(--glass-blur);
}

/* 顶栏页签的悬停态与选中态由文件末尾的「顶栏导航重做：玻璃胶囊页签」统一定义
   （.tabs .tab 系列，特异性高于本层），这里不再重复声明，避免死规则。 */

.admin-tools{
  color:var(--admin-muted);
}

.live-dot{
  background:var(--admin-green);
  box-shadow:0 0 0 4px rgba(47,157,122,.14);
}

/* —— 按钮体系 —— */
.primary{
  border-color:transparent;
  border-radius:13px;
  color:#fff;
  background:var(--glass-tint);
  box-shadow:0 10px 24px rgba(105,95,205,.28),inset 0 1px 0 rgba(255,255,255,.26);
}

.primary:hover{
  filter:brightness(1.05);
  box-shadow:0 14px 32px rgba(105,95,205,.34);
}

.outline,
.top-button,
.account-detail-actions button{
  border-color:var(--glass-border);
  border-radius:11px;
  color:#5b5478;
  background:rgba(255,255,255,.55);
  box-shadow:0 4px 14px rgba(88,74,150,.06);
  backdrop-filter:blur(10px);
}

/* 「账号操作」按钮长在弹窗里，它继承上面的 --glass-border 是纯白，压在近白卡片上合成后
   就是 rgb(255,255,255)，边界完全看不见（实测计算值 border-color:rgba(255,255,255,.72)）。
   改用弹窗底部按钮同一档的 --admin-button-line：值低于下面悬停态的 rgba(122,106,208,.42)，
   悬停仍有加深的层次。.danger 按钮的特异性更高，仍是自带的红描边，不受这条影响。 */
.account-detail-actions button{
  border-color:var(--admin-button-line);
}

.outline:hover,
.top-button:hover,
.account-detail-actions button:hover{
  border-color:rgba(122,106,208,.42);
  color:var(--admin-accent-deep);
  background:rgba(255,255,255,.86);
}

.danger-outline,
.code-row-action,
.admin-delete-button,
.row-actions .danger,
#accountsPage .row-actions button.danger,
.account-detail-actions button.danger,
.account-detail-action-group.is-danger .account-detail-actions button.danger{
  color:var(--admin-red);
  border-color:rgba(221,106,118,.32);
  background:rgba(255,255,255,.6);
}

#accountsPage .row-actions button.danger:hover{
  background:rgba(221,106,118,.1);
}

/* —— 页面头部 —— */
/* eyebrow / panel-label 是 10px 小字，用深一档的强调色；--admin-accent 在这个底色上只有 4.26:1。 */
.eyebrow,
.panel-label,
.login-panel .panel-label{
  color:var(--admin-accent-deep);
}

.page-heading h1,
.dashboard-heading h1,
.runtime-intro h2,
.section-title h2,
.tool-panel h2,
.panel-toolbar h2,
.runtime-panel-head h2,
.builtin-model-card-head h3,
.account-detail-heading h3,
.account-detail-section-head h4,
.account-detail-points-head h4,
.dashboard-detail-heading h3,
.admin-dialog-heading h3{
  color:var(--admin-ink-strong);
}

.muted,
.subheading,
.runtime-intro p{
  color:var(--admin-muted);
}

.refresh-state,
.dashboard-refresh,
.runtime-updated{
  color:var(--admin-green);
}

.section-title span,
.result-count,
.selection-count,
.field-hint,
.runtime-panel-head span,
.builtin-model-path,
.account-detail-section-head p,
.account-detail-points-head p,
.dashboard-detail-heading p{
  color:var(--admin-muted-2);
}

.section-title h2:before{
  background:var(--glass-tint);
}

/* 窄屏上标题与说明只差 1px 就会把标题挤成两行，改为让说明换行。 */
.section-title{
  flex-wrap:wrap;
}

.section-title h2{
  flex:0 0 auto;
}

/* —— 统计卡与玻璃面板 —— */
.stat-card{
  border:1px solid var(--glass-border);
  border-left-width:3px;
  /* 中性卡（无状态修饰）用天蓝色条；.gold / .green / .red / .orange 特异性更高，仍保留各自的语义色。 */
  border-left-color:var(--admin-sky);
  border-radius:18px;
  background:var(--glass-surface);
  box-shadow:var(--glass-shadow);
  backdrop-filter:var(--glass-blur);
}

.stat-card:after{
  background:radial-gradient(circle,rgba(139,122,228,.22),transparent 70%);
}

.stat-card span{
  color:var(--admin-muted-2);
}

.stat-card strong{
  color:var(--admin-ink-strong);
}

.table-panel,
.tool-panel,
.runtime-panel,
.builtin-model-panel,
.dashboard-detail-table-wrap,
.account-detail-points-list{
  border:1px solid var(--glass-border);
  border-radius:18px;
  background:var(--glass-surface);
  box-shadow:var(--glass-shadow);
  backdrop-filter:var(--glass-blur);
}

.filters,
.code-table .panel-toolbar,
.builtin-model-toolbar,
.runtime-panel-head,
.code-pagination{
  border-color:var(--glass-hairline);
  background:rgba(255,255,255,.34);
}

/* 「第 X / Y 页」现在是可点按钮（点击手输页码跳转），但外观保持原来的纯文字：
   去掉按钮默认的边框 / 底色 / 内边距，字号与颜色继承父级。 */
.code-pagination .pagination-jump{
  padding:0;
  border:0;
  color:inherit;
  background:none;
  font:inherit;
}

/* 就地编辑页码：点一下页码，原地换成这个三字符宽的小输入框（回车/失焦跳转、Esc 取消）。 */
.code-pagination .pagination-inline{
  display:inline-flex;
  align-items:center;
  gap:2px;
}

.code-pagination .pagination-input{
  width:3.4ch;
  padding:1px 4px;
  border:1px solid var(--glass-hairline);
  border-radius:6px;
  color:inherit;
  background:rgba(255,255,255,.9);
  font:inherit;
  text-align:center;
}

.search,
.filters select,
.date-filter,
.code-status-filter,
.tool-panel input,
.tool-panel select,
.login-panel input,
.builtin-model-grid input,
.builtin-model-grid select,
.builtin-model-grid textarea,
.admin-create-grid input,
#dialogForm input{
  border-color:var(--glass-hairline);
  border-radius:11px;
  color:#4c4667;
  background:rgba(255,255,255,.72);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.7);
}

/* 试用卡的时长下拉是「固定值」展示位（disabled 表示不可展开），保持正常字色，
   免得灰掉之后看着像表单坏了。 */
.tool-panel select:disabled{
  color:#4c4667;
  opacity:1;
}

.search:focus-within,
.filters select:focus,
.date-filter:focus,
.code-status-filter:focus,
.tool-panel input:focus,
.tool-panel select:focus,
.login-panel input:focus,
.builtin-model-grid input:focus,
.builtin-model-grid select:focus,
.builtin-model-grid textarea:focus,
.admin-create-grid input:focus,
#dialogForm input:focus,
#dialogForm input:focus-visible,
input:focus,
select:focus{
  outline:none;
  border-color:rgba(122,106,208,.6);
  background:#fff;
  box-shadow:0 0 0 4px rgba(122,106,208,.14);
}

.search > span{
  color:var(--admin-muted-2);
}

.date-filter-icon{
  color:var(--admin-muted-2);
}

.date-filter::placeholder{
  color:var(--admin-muted-2);
}

.date-filter-wrap:focus-within .date-filter-icon{
  color:var(--admin-accent);
}

.date-separator{
  color:var(--admin-muted-2);
}

/* —— 表格 —— */
th{
  color:var(--admin-muted);
  background:rgba(255,255,255,.5);
  border-bottom-color:var(--glass-hairline);
}

th,
td{
  border-bottom-color:rgba(150,138,196,.14);
}

/* 行悬停用淡紫色洗，而不是白色叠加：表格底本来就接近白，原来的 rgba(255,255,255,.48)
   实测只把左侧底色从 rgb(249,251,254) 抬到 rgb(251,253,254)（色差约 2.8，看不出来）。
   alpha .1 在同样底色上给出约 18-20 的色差（相当于 7% 左右明度变化），一眼能看出选中了哪一行。 */
tbody tr:hover{
  background:rgba(122,106,208,.1);
}

.table-scroll{
  scrollbar-color:rgba(150,138,196,.4) transparent;
}

.table-scroll::-webkit-scrollbar-thumb{
  background:rgba(150,138,196,.36);
}

.avatar,
.account-detail-avatar,
.runtime-account-avatar,
.admin-avatar{
  color:#fff;
  background:var(--glass-tint);
  box-shadow:0 6px 16px rgba(105,95,205,.26);
}

.account-name,
.runtime-account-identity strong,
.runtime-ranking-user,
.dashboard-detail-table td{
  color:var(--admin-ink-strong);
}

.account-id,
.note-cell,
.runtime-account-identity span,
#accountsPage .account-auth-cell>small,
#accountsPage .account-device-cell>small,
#accountsPage .account-activity-cell>small,
#accountsPage .account-ip-cell>small{
  color:var(--admin-muted-2);
}

#accountsPage .account-ip-cell{
  color:var(--admin-muted);
}

/* 激活码表「使用账号」的 ID 由早期层给了 #a08360，9px 下只有 3:1，一并收到可读档。 */
.used-account-id{
  color:var(--admin-muted-2);
}

#accountsPage .account-points-cell{
  color:var(--admin-accent-deep);
}

#accountsPage .account-device-cell strong,
#accountsPage .account-activity-cell>span{
  color:var(--admin-ink);
}

.empty{
  color:var(--admin-muted-2);
}

.message{
  color:var(--admin-muted);
}

.message.ok,
.audit-result.success{
  color:var(--admin-green);
}

.message.err,
.audit-result.failed{
  color:var(--admin-red);
}

/* —— 状态徽章 —— */
/* 徽章一律要有描边。列表的 .status 自带 border:1px solid，而 .account-detail-status 与
   .runtime-presence（在线 / 最近活动）原来只可能写到 border-color、没有 width/style，
   于是颜色不生效、看起来比别的徽章少一圈。这里统一给宽度与线型，**不动 border-color**，
   各状态自己的描边色才不会被后写胜出盖掉。 */
.status,
.account-detail-status,
.runtime-presence{
  border-width:1px;
  border-style:solid;
}

.status.active,
.account-detail-status.active{
  color:var(--admin-green);
  border-color:rgba(47,157,122,.3);
  background:rgba(47,157,122,.13);
}

.status.pending,
.account-detail-status.pending{
  color:#a2721c;
  border-color:rgba(214,164,64,.32);
  background:rgba(233,186,94,.16);
}

.status.revoked,
.status.rejected,
#accountsPage .status.expired,
.account-detail-status.revoked,
.account-detail-status.rejected,
.account-detail-status.expired{
  color:#c8505f;
  border-color:rgba(221,106,118,.3);
  background:rgba(221,106,118,.13);
}

.status.partial,
.account-detail-status.partial{
  color:var(--admin-accent-deep);
  border-color:rgba(122,106,208,.32);
  background:rgba(122,106,208,.14);
}

.account-detail-status,
.runtime-presence{
  color:var(--admin-muted);
  /* 中性描边用淡紫细线，和卡片、菜单项同一条线；离线徽章的底色就接近白。 */
  border-color:rgba(150,138,196,.3);
  background:rgba(255,255,255,.6);
}

.runtime-presence.online{
  color:var(--admin-green);
  border-color:rgba(47,157,122,.3);
  background:rgba(47,157,122,.13);
}

/* —— 分段控件 —— */
.segment{
  border-color:var(--glass-hairline);
  color:#6b6588;
  background:rgba(255,255,255,.5);
}

.segment.active{
  color:#fff;
  border-color:transparent;
  background:var(--glass-tint);
  box-shadow:0 8px 20px rgba(105,95,205,.26);
}

/* —— 运行看板 —— */
.runtime-card{
  border:1px solid var(--glass-border);
  border-radius:20px;
  background:var(--glass-surface);
  box-shadow:var(--glass-shadow);
  backdrop-filter:var(--glass-blur);
}

.runtime-card-action:hover{
  border-color:var(--glass-border);
  box-shadow:0 20px 44px rgba(88,74,150,.16);
  transform:translateY(-2px);
}

.runtime-card-action:focus-visible{
  border-color:var(--admin-accent);
  box-shadow:0 0 0 4px rgba(122,106,208,.18);
}

.runtime-card-head{
  color:var(--admin-muted-2);
}

/* 卡片标题右侧的小字由前一层的 #9aa4b1 提供，10px 且只有 2.9:1，这里一并收到可读档。 */
.runtime-card-head small{
  color:var(--admin-muted-2);
}

.runtime-card-icon{
  color:var(--admin-accent);
  background:rgba(255,255,255,.72);
}

.runtime-card strong{
  color:var(--admin-ink-strong);
}

.runtime-card-copy{
  color:var(--admin-muted-2);
}

.runtime-card-copy b{
  color:var(--admin-accent-deep);
}

.runtime-card-action .runtime-card-copy b{
  color:var(--admin-accent-deep);
}

/* —— 运行看板主卡：白玻璃底 + 紫色描边环 ——
   前面几版都栽在同一件事上：这只卡是全页唯一的大面积深色块，而整页都是 90%+ 亮度的浅色玻璃，
   无论色相怎么调，明度差都会让它「跳」出来。所以改成：面积不变、明度融入，
   强调全部交给小面积元素——2px 紫色描边 + 紫色外发光 + 紫色数字。
   底色、磨砂、圆角与相邻卡完全一致，卡片之间不再有两种材质语言。
   必须排在上面那组通用 .runtime-card-* 之后：.runtime-card-primary strong 与
   .runtime-card strong 特异性同为 0,1,1，靠后的那条才会生效。 */
.runtime-card-primary{
  color:var(--admin-ink-strong);
  border:2px solid rgba(122,106,208,.55);
  background-color:var(--glass-surface);
  background-image:none;
  box-shadow:0 0 0 3px rgba(122,106,208,.13),0 16px 36px rgba(105,95,205,.16);
  backdrop-filter:var(--glass-blur);
}

/* .runtime-card-action:hover（0,2,0）会盖掉上面的描边，命中态要在本层重新声明。 */
.runtime-card-primary:hover{
  border-color:rgba(122,106,208,.72);
  box-shadow:0 0 0 3px rgba(122,106,208,.17),0 22px 46px rgba(105,95,205,.22);
}

.runtime-card-primary .runtime-card-head{
  color:var(--admin-accent-deep);
}

.runtime-card-primary .runtime-card-icon{
  color:var(--admin-accent);
  background:rgba(122,106,208,.12);
}

.runtime-card-primary strong{
  color:var(--admin-accent);
}

.runtime-card-primary .runtime-card-copy{
  color:var(--admin-muted-2);
}

/* 页脚原来沿用深色卡的白线与白字，换回白玻璃后必须改掉，否则文字会看不见。 */
.runtime-card-primary .runtime-card-foot{
  border-top-color:var(--glass-hairline);
  color:var(--admin-muted-2);
}

.runtime-card-primary .runtime-card-foot b{
  color:var(--admin-accent-deep);
}

/* 原先用透明描边 + 近白底，在白玻璃卡里和背景糊成一片。
   这里比 --glass-hairline（20%）再重一档：小卡片浮在半透明玻璃卡上，
   底色本身也偏白，20% 的线在实际 1x 尺寸下仍然偏弱。 */
.runtime-mini-grid button{
  border-color:var(--admin-line-strong);
  border-radius:13px;
  color:var(--admin-muted);
  background:rgba(255,255,255,.55);
}

.runtime-mini-grid button:hover{
  border-color:rgba(122,106,208,.34);
  background:rgba(255,255,255,.92);
  box-shadow:0 10px 24px rgba(88,74,150,.12);
}

.runtime-mini-grid button:focus-visible{
  border-color:var(--admin-accent);
  box-shadow:0 0 0 4px rgba(122,106,208,.18);
}

.runtime-mini-grid b{
  color:var(--admin-ink-strong);
}

.runtime-mini-grid button>small{
  color:var(--admin-muted-2);
}

.runtime-account{
  border-bottom-color:rgba(150,138,196,.14);
}

.runtime-account.is-online{
  background:linear-gradient(90deg,rgba(122,106,208,.1),transparent 46%);
}

.runtime-account-activity time{
  color:var(--admin-muted-2);
}

.runtime-rank{
  color:var(--admin-accent-deep);
}

/* —— 图标色相（沿用彩色区分，底改为玻璃白） —— */
.runtime-card-icon--dau{color:#3d6fbf;background:rgba(230,238,251,.9)}
.runtime-card-icon--yesterday{color:#7a63c4;background:rgba(239,233,251,.9)}
.runtime-card-icon--wau{color:#3f8f62;background:rgba(228,242,233,.9)}
.runtime-card-icon--mau{color:#b8801f;background:rgba(248,238,214,.9)}
.runtime-card-icon--account{color:#2f8a90;background:rgba(223,240,241,.9)}
.runtime-card-icon--runtime{color:#b85a6a;background:rgba(251,232,236,.9)}

/* —— 服务商/内置模型配置卡 —— */
.builtin-model-list{
  background:transparent;
}

.builtin-model-card{
  border:1px solid var(--glass-border);
  border-radius:16px;
  background:rgba(255,255,255,.6);
  box-shadow:var(--glass-shadow);
  backdrop-filter:var(--glass-blur);
}

.builtin-model-grid label{
  color:var(--admin-muted-2);
}

.builtin-model-switch{
  color:#5b5478 !important;
}

.builtin-model-switch input{
  accent-color:var(--admin-accent);
}

.menu-toggle{
  color:#5b5478;
  border-color:var(--glass-border);
  background:rgba(255,255,255,.55);
}

/* —— 激活码表 —— */
.code-status.available{color:var(--admin-green)}
.code-status.used{color:var(--admin-muted-2)}
.code-status.revoked{color:var(--admin-red)}

.copyable{
  color:var(--admin-ink-strong);
}

.code-table td.copyable:hover,
.code-table td.copyable:focus-visible{
  color:var(--admin-accent-deep);
  background:rgba(122,106,208,.12);
}

.code-table td.copyable.is-copied{
  color:var(--admin-green);
  background:rgba(47,157,122,.12);
  box-shadow:inset 0 0 0 1px rgba(47,157,122,.3);
}

.points-ledger-kind{
  border-color:var(--glass-hairline);
  color:#5b5478;
  background:rgba(255,255,255,.6);
}

.points-ledger-kind.recharge{color:var(--admin-green);border-color:rgba(47,157,122,.3);background:rgba(47,157,122,.12)}
.points-ledger-kind.consume{color:#a2721c;border-color:rgba(214,164,64,.3);background:rgba(233,186,94,.16)}
.points-ledger-kind.refund,
.points-ledger-kind.reversal{color:var(--admin-accent-deep);border-color:rgba(122,106,208,.3);background:rgba(122,106,208,.12)}
.points-ledger-kind.clear{color:var(--admin-red);border-color:rgba(221,106,118,.3);background:rgba(221,106,118,.12)}

.points-ledger-item{
  border-bottom-color:rgba(150,138,196,.16);
}

.points-ledger-note{
  color:#5b5478;
}

.points-ledger-amount.plus{color:var(--admin-green)}
.points-ledger-amount.minus{color:var(--admin-red)}
.points-ledger-date,
.points-ledger-empty,
.account-detail-points-total{
  color:var(--admin-muted-2);
}

/* —— 弹窗与浮层 —— */
dialog,
#adminDialog,
.account-detail-dialog,
.account-detail-form,
.admin-dialog-form,
.dashboard-detail-form{
  border:1px solid var(--glass-border);
  border-radius:20px;
  color:var(--admin-ink);
  background:rgba(255,255,255,.82);
  box-shadow:var(--glass-shadow-lg);
  backdrop-filter:var(--glass-blur-lg);
}

dialog::backdrop,
#adminDialog::backdrop,
.account-detail-dialog::backdrop{
  background:rgba(58,46,102,.3);
  backdrop-filter:blur(6px);
}

.dialog-close{
  border-color:var(--glass-hairline);
  color:var(--admin-muted);
  background:rgba(255,255,255,.6);
}

.dialog-close:hover{
  color:var(--admin-accent-deep);
  border-color:rgba(122,106,208,.4);
}

/* 弹窗底部这排按钮（取消 / 关闭）单独给可见描边：它们落在接近白的弹窗底上，
   继承 .outline 的 --glass-border（纯白）合成后就是 rgb(255,255,255)，看起来没有边框。
   其余 .outline 按钮（顶栏、行内操作等）保持原样。 */
.dialog-actions .outline{
  border-color:var(--admin-button-line);
  color:#5b5478;
  background:rgba(255,255,255,.6);
}

.dialog-actions .primary{
  border-color:transparent;
  background:var(--glass-tint);
}

.admin-list{
  border-color:var(--glass-hairline);
  border-radius:13px;
  background:rgba(255,255,255,.4);
}

.admin-list-item{
  border-color:var(--glass-hairline);
  border-radius:11px;
  background:rgba(255,255,255,.55);
}

.admin-list-item small{
  color:var(--admin-muted);
}

.admin-current-badge{
  border-color:rgba(122,106,208,.3);
  color:var(--admin-accent-deep);
  background:rgba(122,106,208,.12);
}

.admin-create-grid label{
  color:var(--admin-muted-2);
}

/* —— 账号详情抽屉 —— */
.account-detail-heading{
  border-bottom-color:var(--glass-hairline);
  background:transparent;
}

.account-detail-body{
  background:transparent;
}

.account-detail-metric{
  border-color:var(--glass-hairline);
  border-radius:14px;
  background:rgba(255,255,255,.72);
}

.account-detail-metric.is-accent{
  border-color:rgba(122,106,208,.34);
  background:linear-gradient(180deg,rgba(255,255,255,.9),rgba(122,106,208,.1));
}

.account-detail-metric span{
  color:var(--admin-muted-2);
}

.account-detail-metric strong{
  color:var(--admin-ink-strong);
}

.account-detail-metric.is-success strong{
  color:var(--admin-green);
}

.account-detail-metric.is-danger strong{
  color:var(--admin-red);
}

.account-detail-section,
.account-detail-points{
  border-color:var(--glass-hairline);
  border-radius:16px;
  background:rgba(255,255,255,.62);
}

/* 弹窗内部的面板改用淡紫细线，纯白描边在近白弹窗上看不出边界。 */
.account-detail-dialog .account-detail-points-list,
.dashboard-detail-table-wrap{
  border-color:var(--glass-hairline);
}

.account-detail-row{
  border-bottom-color:rgba(150,138,196,.14);
  background:transparent;
}

.account-detail-row span{
  color:var(--admin-muted-2);
}

.account-detail-row b{
  color:var(--admin-ink-strong);
}

.account-detail-sub{
  color:var(--admin-muted-2);
}

.account-detail-action-group.is-danger{
  border-color:rgba(221,106,118,.26);
  background:linear-gradient(180deg,rgba(255,255,255,.7),rgba(221,106,118,.06));
}

.account-detail-action-group.is-danger .account-detail-section-head h4{
  color:var(--admin-red);
}

.account-detail-form>.dialog-actions{
  border-top-color:var(--glass-hairline);
  background:transparent;
}

/* —— 行内操作菜单 —— */
/* .danger 故意不写进来：它自带一条红色描边（rgba(221,106,118,.32)），写进这里会被
   --glass-border 盖成纯白（同特异性、后写胜出），危险按钮就变成看不见边框的那个。 */
#accountsPage .row-actions button,
.row-action-menu button{
  border-color:var(--glass-border);
  border-radius:11px;
}

#accountsPage .row-actions button{
  color:#5b5478;
  background:rgba(255,255,255,.6);
}

#accountsPage .row-actions button:hover{
  border-color:rgba(122,106,208,.42);
  color:var(--admin-accent-deep);
  background:rgba(255,255,255,.92);
}

.row-action-menu{
  border:1px solid var(--glass-border);
  border-radius:14px;
  background:rgba(255,255,255,.88);
  box-shadow:var(--glass-shadow-lg);
  backdrop-filter:var(--glass-blur-lg);
}

.row-action-menu button{
  border:0;
  color:#5b5478;
}

.row-action-menu button:hover{
  background:rgba(122,106,208,.12);
}

.row-action-menu button.danger{
  color:var(--admin-red);
}

/* —— 日期选择浮层 —— */
.date-picker-popup{
  border:1px solid var(--glass-border);
  border-radius:16px;
  color:var(--admin-ink);
  background:rgba(255,255,255,.88);
  box-shadow:var(--glass-shadow-lg);
  backdrop-filter:var(--glass-blur-lg);
}

.date-picker-nav,
.date-picker-title{
  border-color:var(--glass-hairline);
  border-radius:9px;
  color:#5b5478;
  background:rgba(255,255,255,.6);
}

.date-picker-nav:hover,
.date-picker-title:hover,
.date-picker-title[aria-expanded="true"]{
  border-color:rgba(122,106,208,.4);
  color:var(--admin-accent-deep);
  background:rgba(122,106,208,.12);
}

.date-picker-quick-select{
  border-color:var(--glass-hairline);
  border-radius:12px;
  background:rgba(255,255,255,.5);
}

.date-picker-quick-select label,
.date-picker-weekdays{
  color:var(--admin-muted-2);
}

.date-picker-quick-select select{
  border-color:var(--glass-hairline);
  border-radius:8px;
  color:#5b5478;
  background:rgba(255,255,255,.75);
}

.date-picker-quick-select select:focus{
  border-color:rgba(122,106,208,.6);
  box-shadow:0 0 0 3px rgba(122,106,208,.14);
}

.date-picker-day{
  border-radius:9px;
  color:#5b5478;
}

.date-picker-day:hover{
  border-color:rgba(122,106,208,.4);
  color:var(--admin-accent-deep);
  background:rgba(122,106,208,.12);
}

.date-picker-day.is-outside{
  color:#c3bede;
}

.date-picker-day.is-today{
  border-color:rgba(122,106,208,.55);
}

.date-picker-day.is-selected{
  color:#fff;
  border-color:transparent;
  background:var(--glass-tint);
}

.date-picker-footer{
  border-top-color:var(--glass-hairline);
}

/* —— 移动端断点：同步玻璃材质 ——
   页签槽（.tabs）同样由文件末尾那段接管，这里只留与它无关的覆盖。 */
@media(max-width:860px){
  .runtime-panel-head,
  .builtin-model-toolbar{
    background:transparent;
  }
}

/* ============================================================
   九、顶栏页签：玻璃胶囊

   状态用两个伪元素承载，避免 background 渐变无法插值造成的硬切：
     ::before 悬停层——极浅紫底 + 淡紫描边，由内向外轻微展开；
     ::after  选中层——紫罗兰渐变实底，带内高光与外投影，落位时回弹。
   选中层另挂一次性的高光扫过，切页时给出明确的「已切换」反馈。

   选择器统一带 .tabs 前缀：更宽的规则把「下划线」写成了 .tab.active:after
   并带 left/right/height，特异性高于裸 .tab:after，不加前缀会被压成
   底部 2px 细条，白字失去实底。
   ============================================================ */
.tabs{
  align-items:center;
  gap:6px;
}

.tabs .tab{
  position:relative;
  display:inline-flex;
  align-items:center;
  /* 窄屏的旧规则给 .tab 留了固定 min-width:92px（见 2205 段），胶囊比文字宽时
     文字会贴在左内边距上。这里显式居中；宽屏下胶囊宽度即内容宽，视觉不变。 */
  justify-content:center;
  height:38px;
  padding:0 18px;
  border:0;
  border-radius:12px;
  color:#6f6a8c;
  font-size:12.5px;
  font-weight:800;
  letter-spacing:.01em;
  background:transparent;
  transition:color .24s ease;
  isolation:isolate;
}

/* 悬停层：由内向外展开，只作「可点」的弱提示。 */
.tabs .tab:before{
  content:"";
  position:absolute;
  top:0;
  right:0;
  bottom:0;
  left:0;
  z-index:-2;
  border:1px solid rgba(122,106,208,.2);
  border-radius:inherit;
  background:rgba(122,106,208,.1);
  opacity:0;
  transform:scale(.92);
  transition:opacity .24s ease,transform .32s cubic-bezier(.34,1.3,.5,1);
  pointer-events:none;
}

.tabs .tab:hover{
  color:var(--admin-accent-deep);
  background:transparent;
}

.tabs .tab:hover:before{
  opacity:1;
  transform:scale(1);
}

/* 选中层：实心紫罗兰渐变的「你在这里」，投影落在顶栏之外形成悬浮感。
   第一层渐变是高光条纹，只在切页时随动画扫过，静止时停在视野之外。 */
.tabs .tab:after{
  content:"";
  position:absolute;
  top:0;
  right:0;
  bottom:0;
  left:0;
  width:auto;
  height:auto;
  z-index:-1;
  border-radius:inherit;
  background-color:#4a5cd0;
  background-image:
    linear-gradient(115deg,rgba(255,255,255,0) 36%,rgba(255,255,255,.45) 50%,rgba(255,255,255,0) 64%),
    var(--glass-tint);
  background-repeat:no-repeat;
  background-size:220% 100%,100% 100%;
  /* 高光带占图片宽度的 36%~64%，而图片宽是元素的 220%，所以默认 background-position:0 会把
     高光带的一半留在胶囊右端；动画跑完不带 forwards，就停在那里，把右端白字对比度压到 3.46:1。
     这里让它在静止时整体落在画外（-170% 与关键帧起点一致），只在扫过时可见。 */
  background-position:-170% 0,0 0;
  box-shadow:0 10px 22px rgba(105,95,205,.3),inset 0 1px 0 rgba(255,255,255,.34),inset 0 0 0 1px rgba(255,255,255,.18);
  opacity:0;
  transform:scale(.9);
  transition:opacity .26s ease,transform .34s cubic-bezier(.34,1.46,.5,1),filter .24s ease;
  pointer-events:none;
}

.tabs .tab.active{
  color:#fff;
  background:transparent;
}

.tabs .tab.active:before{
  opacity:0;
}

/* 早期层用 display:none 关掉了这条伪元素，这里连同下划线一起收回。 */
.tabs .tab.active:after{
  display:block;
  opacity:1;
  transform:scale(1);
  animation:dsz-tab-sheen .72s cubic-bezier(.3,.72,.3,1);
}

.tabs .tab.active:hover:after{
  filter:brightness(1.07);
}

@keyframes dsz-tab-sheen{
  from{
    background-position:-170% 0,0 0;
  }
  to{
    background-position:270% 0,0 0;
  }
}

@media(prefers-reduced-motion:reduce){
  .tabs .tab,
  .tabs .tab:before,
  .tabs .tab:after{
    transition:none;
    animation:none;
  }
}

@media(max-width:1180px){
  .tabs .tab{
    padding:0 12px;
  }
}

@media(max-width:860px){
  /* 窄屏页签槽同步玻璃材质，选中胶囊沿用同一套紫罗兰渐变。 */
  .tabs{
    gap:4px;
    padding:3px;
    border:1px solid var(--glass-border);
    background:rgba(255,255,255,.5);
    backdrop-filter:var(--glass-blur);
    box-shadow:inset 0 1px 0 rgba(255,255,255,.6);
  }

  .tabs .tab{
    height:34px;
    padding:0 13px;
    border:0;
    border-radius:10px;
    font-size:12px;
  }

  .tabs .tab.active{
    background:transparent;
  }

  .tabs .tab.active:after{
    display:block;
    box-shadow:0 5px 12px rgba(105,95,205,.26),inset 0 1px 0 rgba(255,255,255,.34);
  }
}
