:root{
  --bg:#0f1115; --panel:#161a22; --panel2:#1a1f29; --line:#262c38;
  --fg:#e6e6e6; --muted:#7b8a9e; --accent:#4f8cff; --ok:#5fd08a; --bad:#f2777a; --warn:#e8c07d;
}
*{box-sizing:border-box}
[hidden]{display:none !important}
html,body{height:100%}
body{
  margin:0;background:var(--bg);color:var(--fg);
  font:14px/1.6 -apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Microsoft YaHei",sans-serif;
  display:flex;flex-direction:column;
}
code{background:var(--panel2);padding:1px 5px;border-radius:4px;font-size:12px}
.muted{color:var(--muted)}.small{font-size:12px}.grow{flex:1}
.pad{padding:28px}

/* header */
header{
  display:flex;gap:12px;align-items:center;padding:10px 18px;
  background:var(--panel);border-bottom:1px solid var(--line);flex:0 0 auto;
}
header h1{font-size:15px;margin:0;font-weight:600;letter-spacing:.3px}
.pill{
  font-size:11px;padding:1px 8px;border-radius:999px;
  background:var(--panel2);border:1px solid var(--line);color:var(--muted);
}
.pill.on{color:var(--ok);border-color:#2b5a3d;background:#14251b}
.pill.off{color:var(--bad);border-color:#5a2b2f;background:#251416}
.pill.warn{color:var(--warn);border-color:#5c4a24;background:#241f14}

/* controls */
input,textarea,button,select{font:inherit;color:var(--fg)}
input[type=password],input[type=text],input[type=file],select,textarea{
  background:var(--panel2);border:1px solid var(--line);border-radius:6px;
  padding:7px 10px;font-size:13px;outline:none;width:100%;
}
input:focus,select:focus,textarea:focus{border-color:var(--accent)}
button{
  background:var(--panel2);border:1px solid var(--line);border-radius:6px;
  padding:6px 12px;font-size:13px;cursor:pointer;transition:.12s;
}
button:hover:not(:disabled){background:#28313f}
button:disabled{opacity:.45;cursor:not-allowed}
button.primary{background:var(--accent);border-color:var(--accent);color:#fff;font-weight:500}
button.primary:hover:not(:disabled){background:#3d7bf0}
button.danger{color:var(--bad);border-color:#4a2427}
button.danger:hover:not(:disabled){background:#2a1618}
button.ghost{background:transparent}
button.small{padding:3px 9px;font-size:12px}

/* login gate */
.gate{flex:1;display:flex;align-items:center;justify-content:center;padding:24px}
.card{
  width:min(430px,100%);background:var(--panel);border:1px solid var(--line);
  border-radius:12px;padding:26px 26px 22px;box-shadow:0 18px 48px rgba(0,0,0,.45);
}
.card h2{margin:0 0 8px;font-size:17px}
.card form{display:flex;gap:8px;margin:16px 0 8px}
.card input{flex:1}
/* 首次设置是两个密码框 + 按钮：必须竖排，横排会被挤成细条没法输入 */
#setupForm{flex-direction:column;align-items:stretch}
#setupForm input{flex:none;width:100%}
#setupForm button{width:100%;margin-top:2px}

/* 门禁提示。以前 .bad 没定义颜色，报错跟普通灰色说明长得一样，
   点了「创建并进入」看着就像没反应 —— 错误必须一眼可见。 */
#gateMsg{margin:12px 0 0;min-height:0;white-space:pre-wrap}
#gateMsg:empty{display:none}
#gateMsg.bad,#gateMsg.warn,#gateMsg.ok,#gateMsg.busy{
  padding:9px 12px;border-radius:8px;font-size:13px;line-height:1.5;border:1px solid transparent;
}
#gateMsg.bad{color:var(--bad);background:#251416;border-color:#5a2b2f}
#gateMsg.warn{color:var(--warn);background:#241f14;border-color:#5c4a24}
#gateMsg.ok{color:var(--ok);background:#14251b;border-color:#245c3c}
#gateMsg.busy{color:var(--fg);background:var(--panel2);border-color:var(--line)}
#gateMsg.busy::before{
  content:"";display:inline-block;width:11px;height:11px;margin-right:8px;
  border:2px solid var(--muted);border-top-color:var(--accent);border-radius:50%;
  vertical-align:-1px;animation:uuspin .7s linear infinite;
}
@keyframes uuspin{to{transform:rotate(360deg)}}
.hint{margin:2px 0 0;min-height:18px;color:var(--muted)}
.hint.bad{color:var(--bad)}
.hint.ok{color:var(--ok)}

/* app shell */
#app{flex:1;display:flex;min-height:0}
.sidebar{
  width:290px;flex:0 0 auto;background:var(--panel);border-right:1px solid var(--line);
  display:flex;flex-direction:column;min-height:0;
}
.tabs{display:flex;padding:8px 8px 0;gap:4px}
.tab{flex:1;background:transparent;border:1px solid transparent;border-radius:6px;padding:5px 6px;font-size:12.5px;color:var(--muted)}
.tab.active{background:var(--panel2);border-color:var(--line);color:var(--fg)}
.side-actions{display:flex;gap:6px;padding:8px}
.list{list-style:none;margin:0;padding:0 8px 12px;overflow:auto;flex:1}
.list li{
  padding:7px 9px;border-radius:6px;cursor:pointer;margin-bottom:2px;
  display:flex;gap:8px;align-items:baseline;border:1px solid transparent;
}
.list li:hover{background:var(--panel2)}
.list li.active{background:var(--panel2);border-color:var(--accent)}
.list .id{font-size:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.list .rev{margin-left:auto;font-size:11px;color:var(--muted);flex:0 0 auto}
.agent-side-state{
  margin-left:auto;flex:0 0 auto;display:inline-flex;align-items:center;gap:5px;
  font-size:11px;color:var(--muted);
}
.agent-side-state i{width:6px;height:6px;border-radius:50%;background:currentColor;box-shadow:0 0 0 3px rgba(123,138,158,.1)}
.agent-side-state.online{color:var(--ok)}
.agent-side-state.online i{box-shadow:0 0 0 3px rgba(95,208,138,.12)}
.agent-side-state.offline{color:var(--bad)}
.agent-side-state.offline i{box-shadow:0 0 0 3px rgba(242,119,122,.1)}
.list .sub{font-size:11px;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.detail{flex:1;min-width:0;display:flex;flex-direction:column;min-height:0}
/* #editor 必须是「会长高的 flex 列」：以前它没有 flex 规则，
   里面 #json 的 flex:1 就完全不生效，textarea 只剩默认 2 行高。 */
#editor{flex:1;min-height:0;display:flex;flex-direction:column}
.detail-head{display:flex;gap:12px;align-items:flex-start;padding:14px 18px 10px;border-bottom:1px solid var(--line)}
.detail-head h2{margin:0 0 3px;font-size:16px}
.head-actions{margin-left:auto;display:flex;gap:6px;flex:0 0 auto}
#json{
  flex:1;margin:0;border:0;border-radius:0;resize:vertical;
  font:13px/1.6 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  background:#111318;padding:14px 18px;min-height:0;
}
.json-toolbar{
  display:flex;gap:6px;align-items:center;padding:7px 14px;
  background:#151920;border-bottom:1px solid #222936;min-height:42px;
}
.json-toolbar>.muted{margin-right:auto;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#editor>.CodeMirror{
  flex:1 1 0;width:100%;height:auto;min-height:220px;
  font:13px/1.65 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
}

/* VS Code 风格 JSON：深色底、紫色键名、绿色字符串、蓝色数字、行号与折叠槽。 */
.cm-s-uu-json.CodeMirror{background:#111318;color:#d4d4d4}
.cm-s-uu-json .CodeMirror-scroll{background:#111318}
.cm-s-uu-json .CodeMirror-gutters{background:#111318;border-right:1px solid #202632}
.cm-s-uu-json .CodeMirror-linenumbers{width:46px}
.cm-s-uu-json .CodeMirror-linenumber{color:#4f5968;padding:0 10px 0 7px;min-width:29px}
.cm-s-uu-json .CodeMirror-foldgutter{width:16px}
.cm-s-uu-json .CodeMirror-foldgutter-open,
.cm-s-uu-json .CodeMirror-foldgutter-folded{color:#687386}
.cm-s-uu-json .CodeMirror-foldgutter-open:hover,
.cm-s-uu-json .CodeMirror-foldgutter-folded:hover{color:#c8d1df}
.cm-s-uu-json .CodeMirror-lines{padding:10px 0}
.cm-s-uu-json .CodeMirror pre.CodeMirror-line,
.cm-s-uu-json .CodeMirror pre.CodeMirror-line-like{padding:0 18px 0 5px}
.cm-s-uu-json .CodeMirror-cursor{border-left:2px solid #d7dae0}
.cm-s-uu-json div.CodeMirror-selected,
.cm-s-uu-json .CodeMirror-focused div.CodeMirror-selected{background:#264f78}
.cm-s-uu-json .CodeMirror-line::selection,
.cm-s-uu-json .CodeMirror-line>span::selection,
.cm-s-uu-json .CodeMirror-line>span>span::selection{background:#264f78}
.cm-s-uu-json .cm-property{color:#c586c0}
.cm-s-uu-json .cm-string,.cm-s-uu-json .cm-string-2{color:#a8cf8b}
.cm-s-uu-json .cm-number{color:#7db8ff}
.cm-s-uu-json .cm-atom{color:#d19a66}
.cm-s-uu-json .cm-keyword{color:#569cd6}
.cm-s-uu-json .cm-def{color:#dcdcaa}
.cm-s-uu-json .cm-error{color:#f48771;text-decoration:underline wavy}
.cm-s-uu-json .CodeMirror-matchingbracket{
  color:#ffd479!important;background:#3a3320;border-bottom:1px solid #ffd479;text-decoration:none;
}
.cm-s-uu-json .CodeMirror-nonmatchingbracket{color:#ff7b72!important;background:#3b1f22}
.cm-s-uu-json .CodeMirror-foldmarker{
  color:#d7ba7d;background:#252b36;border:1px solid #3b4350;border-radius:4px;
  padding:0 5px;margin:0 3px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  line-height:1.1;text-shadow:none;
}
.detail-foot{display:flex;gap:6px;align-items:center;padding:9px 18px;border-top:1px solid var(--line)}
#saveNote{margin-left:auto}
.banner{padding:8px 18px;font-size:12.5px;border-bottom:1px solid var(--line)}
.banner.ok{background:#14251b;color:var(--ok)}
.banner.bad{background:#251416;color:var(--bad)}
.banner.warn{background:#241f14;color:var(--warn)}

.tabs+.tabs{padding-top:6px}
button.ghost.on{color:var(--fg);border-color:var(--line);background:var(--panel2)}
.runbar{
  display:flex;gap:8px;align-items:center;padding:7px 18px;
  border-top:1px solid var(--line);background:#12161d;
}
.runbar code{
  /* pre-line：启动命令有两行（原生 -i 拉取 / uu.sh 常驻） */
  flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:pre-line;
  line-height:1.55;user-select:all;padding:4px 8px;color:var(--ok);
}

.history{border-top:1px solid var(--line);max-height:38%;overflow:auto;padding:8px 18px 14px}
.history h3{font-size:13px;margin:6px 0}
.history .row{display:flex;gap:10px;align-items:center;padding:5px 0;border-bottom:1px solid #1d222c;font-size:12.5px}
.history .row .msg{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.toast{
  position:fixed;left:50%;bottom:26px;transform:translateX(-50%);
  background:var(--panel2);border:1px solid var(--line);border-radius:8px;
  padding:9px 16px;font-size:13px;box-shadow:0 10px 30px rgba(0,0,0,.5);z-index:50;
}
.toast.bad{border-color:#5a2b2f;color:var(--bad)}
.toast.ok{border-color:#2b5a3d;color:var(--ok)}

/* ── 客户端面板（云端控制本地 uu-trae）────────────────── */
#runners{flex:1;min-height:0;display:flex;flex-direction:column}
.runners{flex:1;min-height:0;overflow:auto;padding:12px 18px 20px}
.runner{
  background:var(--panel);border:1px solid var(--line);border-radius:10px;
  padding:11px 14px;margin-bottom:10px;
}
.runner.off{opacity:.62;border-style:dashed}
.agent-runner.off{opacity:1;background:#141820;border-color:#343a47}
.rline1{display:flex;gap:9px;align-items:center}
.rline1 .rid{font-size:14px}
.rline2{display:flex;gap:6px;align-items:center;flex-wrap:wrap;margin-top:6px}
.rline3{margin-top:3px}
.token-stats{display:flex;gap:6px;align-items:center;flex-wrap:wrap;margin-top:7px}
.token-count{
  display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:999px;
  border:1px solid #33405a;background:#192131;color:var(--muted);font-size:11px;line-height:1.5;
}
.token-count b{color:var(--fg);font-size:12px;font-variant-numeric:tabular-nums}
.token-count.warn{border-color:#5c4a24;background:#241f14;color:var(--warn)}
.token-count.warn b{color:var(--warn)}
.racts{display:flex;gap:6px;margin-top:9px;flex-wrap:wrap}
.dim-bad{color:var(--bad);font-size:12px}

/* ── 启动器面板 ───────────────────────────────────────── */
#agents{flex:1;min-height:0;display:flex;flex-direction:column;overflow:auto}
/* 启动器列表必须保持完整高度，由 #agents 统一滚动。
   否则下方程序版本列表越长，启动器卡片会被 flex 压缩到几乎不可见。 */
#agentList.runners{flex:0 0 auto;min-height:0;overflow:visible}
.inline-check{display:flex;align-items:center;gap:5px;white-space:nowrap}
.inline-check input{width:auto;margin:0}
.formbox{margin:12px 18px 4px;padding:13px;background:var(--panel);border:1px solid var(--line);border-radius:10px}
.formgrid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
.formgrid label{display:flex;flex-direction:column;gap:4px;color:var(--muted);font-size:12px}
.formgrid label.wide{grid-column:1/-1}
.formgrid input,.formgrid select{color:var(--fg)}
.formactions{display:flex;gap:7px;margin-top:11px}
.artifact-detect{display:flex;flex-direction:column;gap:5px;margin-top:10px;padding:8px 10px;background:#11151c;border:1px solid var(--line);border-radius:7px}
.artifact-detect-row{display:flex;gap:10px;align-items:center;min-width:0}
.artifact-detect-row .adname{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--fg)}
.artifact-detect-row.ok>span:last-child{color:var(--ok)}
.artifact-detect-row.bad>span:last-child{color:var(--bad)}
.upload-hint{margin-top:8px;line-height:1.7}
.agent-runner-head{display:flex;align-items:flex-start;gap:16px;padding-bottom:11px}
.agent-identity{min-width:0;flex:1}
.agent-title-line{display:flex;align-items:center;gap:8px;min-width:0;flex-wrap:wrap}
.agent-title-line .rid{font-size:16px;line-height:1.35;overflow-wrap:anywhere}
.agent-id{margin-top:3px;color:var(--muted);font-size:11.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.agent-id code{padding:0;background:transparent;color:#9ba9bb}
.agent-head-actions{flex:0 0 auto;display:flex;align-items:center;gap:8px;flex-wrap:wrap;justify-content:flex-end}
.agent-heartbeat{
  flex:0 0 auto;display:inline-flex;align-items:center;gap:6px;margin-top:3px;
  color:var(--muted);font-size:11.5px;white-space:nowrap;
}
.agent-heartbeat i{width:6px;height:6px;border-radius:50%;background:currentColor}
.agent-heartbeat.online{color:var(--ok)}
.agent-heartbeat.offline{color:var(--bad)}
.agent-facts{
  display:grid;grid-template-columns:repeat(5,minmax(0,1fr));
  background:#121720;border:1px solid #252d3a;border-radius:8px;overflow:hidden;
}
.agent-fact{min-width:0;padding:7px 10px;border-right:1px solid #252d3a}
.agent-fact:last-child{border-right:0}
.agent-fact span{display:block;color:var(--muted);font-size:10.5px;line-height:1.4}
.agent-fact b{display:block;margin-top:1px;font-size:12px;font-weight:500;line-height:1.45;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.agent-instances{margin-top:11px;border-top:1px solid var(--line);padding-top:8px}
.agent-instances-head{display:flex;justify-content:space-between;align-items:center;padding:1px 0 3px;color:var(--muted);font-size:11px}
.instance-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap;padding:7px 0;border-bottom:1px solid #1d222c}
.instance-row:last-child{border-bottom:0}
.instance-row .iname{font-size:13px;font-weight:600}
.instance-row .iacts{display:flex;gap:6px;margin-left:auto;flex-wrap:wrap}
.version-panel{margin:0 18px 22px;background:var(--panel);border:1px solid var(--line);border-radius:10px;overflow:hidden}
.version-head{display:flex;align-items:flex-start;gap:12px;padding:12px 14px;border-bottom:1px solid var(--line)}
.version-head h3{margin:0 0 3px;font-size:14px}
.version-head button{margin-left:auto}
.artifact-list{padding:12px 14px 14px}
.artifact-group{border:1px solid #272f3c;border-radius:9px;overflow:hidden;background:#121720}
.artifact-group+.artifact-group{margin-top:10px}
.artifact-group-head{display:flex;align-items:center;gap:12px;padding:9px 12px;background:#19202b;border-bottom:1px solid #272f3c}
.artifact-version-title{display:flex;align-items:baseline;gap:8px;min-width:0}
.artifact-version-title b{font-size:13.5px;letter-spacing:.15px}
.artifact-version-title span{color:var(--muted);font-size:11px}
.artifact-current-count{
  margin-left:auto;padding:2px 8px;border:1px solid #394252;border-radius:999px;
  color:var(--muted);background:#151a23;font-size:10.5px;white-space:nowrap;
}
.artifact-current-count.on{color:var(--ok);border-color:#2b5a3d;background:#14251b}
.artifact-platform{
  display:grid;grid-template-columns:minmax(120px,1fr) 72px 142px 104px minmax(132px,auto);
  gap:12px;align-items:center;min-height:42px;padding:7px 12px;
  border-top:1px solid #202631;font-size:12px;
}
.artifact-platform:first-child{border-top:0}
.artifact-platform.active{background:linear-gradient(90deg,rgba(95,208,138,.055),transparent 58%)}
.artifact-platform-name{display:flex;align-items:baseline;gap:7px;min-width:0}
.artifact-platform-name b{font-size:12.5px;white-space:nowrap}
.artifact-platform-name span{color:var(--muted);font-size:11px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.artifact-size,.artifact-time{color:var(--muted);font-variant-numeric:tabular-nums;white-space:nowrap}
.artifact-state{display:flex;align-items:center}
.artifact-platform .aacts{display:flex;gap:6px;justify-content:flex-end;min-width:0}
.artifact-platform .aacts:empty{display:none}
.agent-hint{background:#12161d;border:1px solid var(--line);border-radius:8px;padding:11px 13px;margin:10px 0}
.agent-hint code{display:inline-block;margin-top:4px;user-select:all;color:var(--ok)}

/* 异常日志：只展示 agent 上报的最后一段，不在浏览器里轮询完整日志。 */
.log-modal{
  position:fixed;inset:0;z-index:70;display:flex;align-items:center;justify-content:center;
  padding:24px;background:rgba(4,6,9,.78);
}
.log-panel{
  width:min(1000px,96vw);height:min(720px,88vh);display:flex;flex-direction:column;
  background:var(--panel);border:1px solid var(--line);border-radius:12px;
  box-shadow:0 22px 70px rgba(0,0,0,.65);overflow:hidden;
}
.log-head{display:flex;align-items:flex-start;gap:12px;padding:13px 16px;border-bottom:1px solid var(--line)}
.log-head h3{margin:0 0 3px;font-size:15px}
.log-head button{margin-left:auto}
.log-tail{
  flex:1;min-height:0;overflow:auto;margin:0;padding:14px 16px 24px;
  white-space:pre-wrap;word-break:break-word;user-select:text;
  background:#0b0e13;color:#c9d3e0;font:12.5px/1.6 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
}
.purchase-panel{height:min(780px,92vh)}
.purchase-list{flex:1;min-height:0;overflow:auto;background:#0b0e13;padding:4px 16px 24px}
.purchase-row{
  display:grid;grid-template-columns:128px minmax(210px,1fr) 80px 180px 190px;
  gap:12px;align-items:start;padding:11px 0;border-bottom:1px solid #1d222c;font-size:12.5px;
}
.purchase-row:last-child{border-bottom:0}
.purchase-row .ptime,.purchase-row .pmeta,.purchase-row .pname span{color:var(--muted)}
.purchase-row .pname{min-width:0;display:flex;flex-direction:column;gap:3px}
.purchase-row .pname b{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.purchase-row .pname span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:11.5px}
.purchase-row .pprice{font-weight:700;color:var(--ok)}
.purchase-row .pmeta{line-height:1.65;word-break:break-all}
.purchase-row .pstate{display:flex;flex-direction:column;align-items:flex-start;gap:5px}
.purchase-row .perror{color:var(--bad);font-size:11.5px;line-height:1.45;word-break:break-word}
button:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible{
  outline:2px solid var(--accent);outline-offset:2px;
}

/* ── 手机 / 窄屏 ────────────────────────────────────────
   手机不保留桌面左侧栏，改成顶部「标签 + 操作 + 横向配置卡」；
   详情区占满余下宽度，避免编辑器和操作按钮被 220px 侧栏挤坏。 */
@media (max-width:760px){
  html,body{height:100%;height:100dvh}
  body{overflow:hidden;-webkit-text-size-adjust:100%}

  header{
    gap:7px;flex-wrap:wrap;padding:max(9px,env(safe-area-inset-top)) 12px 9px;
  }
  header h1{font-size:14px;white-space:nowrap}
  #conn{margin-left:auto}
  #who{display:none}
  header .grow{display:none}
  header button{min-height:36px;padding:6px 10px}

  .gate{padding:max(16px,env(safe-area-inset-top)) 14px max(18px,env(safe-area-inset-bottom));overflow:auto}
  .card{padding:20px 18px 18px;border-radius:10px}
  .card form{flex-direction:column}
  .card form button{width:100%;min-height:44px}

  input[type=password],input[type=text],input[type=file],select,textarea{
    font-size:16px;min-height:42px;padding:9px 11px;
  }
  input[type=file]{padding:8px}
  button{min-height:40px;font-size:14px;padding:8px 12px}
  button.small{min-height:36px;padding:6px 10px;font-size:13px}

  #app{flex-direction:column;min-height:0}
  .sidebar{
    width:100%;max-height:none;flex:0 0 auto;border-right:0;
    border-bottom:1px solid var(--line);overflow:hidden;
  }
  .tabs{
    padding:7px 8px 0;gap:5px;overflow-x:auto;scrollbar-width:none;
  }
  .tabs::-webkit-scrollbar,.list::-webkit-scrollbar{display:none}
  .tabs+.tabs{padding-top:5px}
  .tab{
    flex:1 0 82px;min-width:82px;min-height:36px;padding:6px 9px;font-size:13px;
  }
  .side-actions{padding:7px 8px 4px}
  .side-actions button{flex:1}
  .list{
    display:flex;flex:0 0 auto;gap:6px;padding:5px 8px 9px;
    overflow-x:auto;overflow-y:hidden;scroll-snap-type:x proximity;
  }
  .list li{
    flex:0 0 min(210px,78vw);min-width:min(210px,78vw);max-width:230px;
    margin:0;padding:8px 9px;scroll-snap-align:start;
  }
  .list li.muted{flex-basis:100%;min-width:100%;max-width:none;cursor:default}

  .detail{
    flex:1;min-width:0;min-height:0;overflow-x:hidden;overflow-y:auto;
    -webkit-overflow-scrolling:touch;
  }
  .detail-head{padding:10px 12px 9px;gap:8px;flex-wrap:wrap}
  .detail-head>div:first-child{flex:1 1 100%;min-width:0}
  .detail-head h2{font-size:15px;overflow-wrap:anywhere}
  .head-actions{width:100%;margin-left:0;flex-wrap:wrap}
  .head-actions>button{flex:1 1 96px}
  .head-actions .inline-check{min-height:40px}

  #editor{min-height:0}
  .json-toolbar{padding:7px 10px;flex-wrap:wrap}
  .json-toolbar>.muted{flex:1 1 100%;white-space:normal;line-height:1.45}
  .json-toolbar>button{flex:1 1 110px}
  #editor>.CodeMirror{
    flex:none;height:clamp(340px,58dvh,640px);min-height:340px;
    font-size:16px;line-height:1.6;-webkit-overflow-scrolling:touch;
  }
  .banner{padding:8px 12px}
  .runbar{padding:8px 12px;align-items:center;flex-wrap:nowrap}
  .runbar>.muted.small{display:none}
  .runbar code{
    flex:1 1 220px;min-width:0;white-space:pre-wrap;overflow:visible;text-overflow:clip;
    overflow-wrap:anywhere;word-break:break-word;font-size:11.5px;padding:6px 8px;
  }
  #btnCopyCmd{flex:0 0 auto;width:auto;min-height:36px}
  .detail-foot{
    padding:8px 12px calc(8px + env(safe-area-inset-bottom));
    align-items:stretch;flex-wrap:wrap;
  }
  .detail-foot button{flex:1 1 90px}
  #saveNote{flex:1 1 100%;margin-left:0}
  .history{max-height:42%;padding:8px 12px 14px}
  .history .row .msg{white-space:normal;overflow-wrap:anywhere}

  .runners{padding:10px 12px 18px;-webkit-overflow-scrolling:touch}
  .runner{padding:10px 12px;margin-bottom:9px}
  .rline1{align-items:flex-start;flex-wrap:wrap}
  .rline1 .grow{display:none}
  .rline1 .rid{min-width:0;max-width:100%;overflow-wrap:anywhere}
  .rline1>.muted.small{margin-left:auto}
  .rline2{line-height:1.55}
  .racts{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:7px}
  .racts button{width:100%}
  .agent-runner-head{gap:7px 10px;padding-bottom:10px;flex-wrap:wrap}
  .agent-title-line .rid{font-size:15px}
  .agent-head-actions{width:100%;justify-content:space-between}
  .agent-heartbeat{flex:1 1 auto;margin-top:0}
  .agent-head-actions button{flex:0 0 auto}
  .agent-facts{grid-template-columns:repeat(2,minmax(0,1fr))}
  .agent-fact{border-right:0;border-bottom:1px solid #252d3a}
  .agent-fact:nth-child(2n){border-right:0}
  .agent-fact:last-child{border-bottom:0}
  .agent-fact b{white-space:normal;overflow-wrap:anywhere}

  /* 启动器在手机上是普通长页面，不能继续用桌面 Flex 收缩子项：
     否则实例列表和程序版本会被压成几像素高，无法点击。 */
  #agents{display:block;overflow-y:auto}
  #agents>.formbox,#agents>.version-panel,#agentList.runners{flex:none}
  #agentList.runners{overflow:visible;padding:10px 12px}
  .formbox{margin:10px 10px 4px;padding:11px}
  #artifactForm.formbox{margin:10px;max-width:calc(100% - 20px)}
  .formgrid{grid-template-columns:1fr}
  .formgrid>*{min-width:0}
  .formactions{flex-wrap:wrap}
  .formactions button{flex:1 1 110px}
  .version-panel{margin:0 10px 18px}
  #artifactForm input[type=file]{min-width:0;max-width:100%}
  .version-head{padding:10px 12px;flex-wrap:wrap}
  .version-head>div{min-width:0}
  .version-head button{width:100%;min-height:40px;margin-left:0}
  .artifact-list{padding:9px 10px 12px}
  .artifact-group-head{padding:8px 10px;flex-wrap:wrap;gap:6px 10px}
  .artifact-current-count{margin-left:auto}
  .artifact-platform{
    grid-template-columns:minmax(0,1fr) auto;
    grid-template-areas:"name state" "size time" "actions actions";
    gap:5px 10px;padding:9px 10px;line-height:1.45;
  }
  .artifact-platform-name{grid-area:name}
  .artifact-size{grid-area:size}
  .artifact-time{grid-area:time;text-align:right}
  .artifact-state{grid-area:state;justify-self:end}
  .artifact-platform .aacts{grid-area:actions;width:100%;margin-top:3px;display:grid;grid-template-columns:repeat(2,minmax(0,1fr))}
  .artifact-platform .aacts button{width:100%}
  .agent-instances{padding-top:8px}
  .instance-row{align-items:flex-start}
  .instance-row>span{min-width:0;overflow-wrap:anywhere}
  .instance-row .iacts{width:100%;margin-left:0;display:grid;grid-template-columns:repeat(2,minmax(0,1fr))}
  .instance-row .iacts button{width:100%}
  .agent-hint{overflow-wrap:anywhere}
  .agent-hint code{white-space:pre-wrap;word-break:break-all}

  .toast{
    left:12px;right:12px;bottom:calc(12px + env(safe-area-inset-bottom));
    max-width:none;transform:none;text-align:center;
  }

  .log-modal{padding:0;align-items:stretch}
  .log-panel,.purchase-panel{
    width:100%;height:100dvh;max-height:none;border:0;border-radius:0;
  }
  .log-head{
    padding:calc(12px + env(safe-area-inset-top)) 14px 12px;flex-wrap:wrap;
  }
  .log-head>div{flex:1;min-width:0}
  .log-head h3{overflow-wrap:anywhere}
  .log-head button{min-height:40px;margin-left:auto}
  .log-tail{
    padding:12px 12px calc(20px + env(safe-area-inset-bottom));
    font-size:12px;-webkit-overflow-scrolling:touch;
  }
  .purchase-list{padding:8px 12px calc(16px + env(safe-area-inset-bottom));-webkit-overflow-scrolling:touch}
  .purchase-row{
    grid-template-columns:minmax(0,1fr) auto;
    grid-template-areas:"name price" "time time" "meta meta" "state state";
    gap:7px 10px;padding:11px 12px;margin:7px 0;
    background:#10151c;border:1px solid #1d222c;border-radius:8px;
  }
  .purchase-row:last-child{border-bottom:1px solid #1d222c}
  .purchase-row .pname{grid-area:name}
  .purchase-row .pprice{grid-area:price}
  .purchase-row .ptime{grid-area:time}
  .purchase-row .pmeta{grid-area:meta}
  .purchase-row .pstate{grid-area:state;flex-direction:row;align-items:center;flex-wrap:wrap}
  .purchase-row .pname b,.purchase-row .pname span{white-space:normal;overflow:visible;overflow-wrap:anywhere}
  .purchase-row .pmeta{word-break:normal;overflow-wrap:anywhere}
}

@media (max-width:380px){
  header h1{font-size:13px}
  header button{padding-left:8px;padding-right:8px}
  .tab{flex-basis:74px;min-width:74px}
  .racts{grid-template-columns:1fr}
}

@media (max-width:760px) and (max-height:560px){
  .list li{padding-top:6px;padding-bottom:6px}
  .side-actions{padding-top:5px}
  #editor>.CodeMirror{height:240px;min-height:240px}
}

@media (prefers-reduced-motion:reduce){
  *{scroll-behavior:auto!important;transition:none!important;animation-duration:.01ms!important;animation-iteration-count:1!important}
  #gateMsg.busy::before{animation:none}
}
