/* Claude 暖赤陶。奶油底 + 衬线标题 + 赤陶强调色。
   两处深色：执行过程面板（Agent 的真实 chrome）、安全闸门卡（高风险必须一眼看见）。
   coral 稀缺：只用发送键、主按钮、品牌字标、链接，以及「待确认」那一个状态。 */
:root{
  --canvas:#faf9f5; --soft:#f5f0e8; --card:#efe9de; --cream:#e8e0d2;
  --hairline:#e6dfd8; --hairline-2:#ebe6df;

  --ink:#141413; --body:#3d3d3a; --strong:#252523; --muted:#6c6a64; --dim:#8e8b82;

  --accent:#cc785c; --accent-active:#a9583e; --accent-off:#e6dfd8;

  --dark:#181715; --dark-2:#252320; --dark-3:#1f1e1b; --on-dark:#faf9f5; --on-dark-soft:#a09d96;

  --ok:#5db872; --warn:#d4a017; --err:#c64545; --teal:#5db8a6;

  --serif:"Songti SC","Noto Serif SC","Source Han Serif SC","Tiempos Headline",Georgia,serif;
  --sans:"PingFang SC","Hiragino Sans GB",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
  --mono:"JetBrains Mono",ui-monospace,SFMono-Regular,"SF Mono",Menlo,monospace;
  --r:12px;
}
*{box-sizing:border-box}
html,body{height:100%}
body{
  margin:0; background:var(--canvas); color:var(--body); overflow:hidden;
  font:14px/1.55 var(--sans);
  -webkit-font-smoothing:antialiased;
}
button{font:inherit}
::-webkit-scrollbar{width:9px;height:9px}
::-webkit-scrollbar-thumb{background:#ded6c8;border-radius:5px}
::-webkit-scrollbar-thumb:hover{background:#c9bfad}
::-webkit-scrollbar-track{background:transparent}
:focus-visible{outline:2px solid var(--accent); outline-offset:2px; border-radius:4px}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms !important; animation-iteration-count:1 !important; transition-duration:.01ms !important}
}

.app{display:grid; grid-template-columns:272px 1fr; height:100vh; overflow:hidden}

/* ---------- 侧栏 ---------- */
.side{
  border-right:1px solid var(--hairline); background:var(--soft);
  padding:16px 14px 14px; display:flex; flex-direction:column; min-height:0;
}
.brand{display:flex; align-items:center; gap:10px; padding:2px 4px 16px}
.mark{width:28px; height:28px; flex:none; color:var(--accent); display:grid; place-items:center}
.bt{min-width:0}
.brand b{display:block; font-family:var(--serif); font-size:15px; font-weight:400; letter-spacing:.2px; color:var(--ink)}
.brand span{display:block; font:11px/1.4 var(--mono); color:var(--dim); margin-top:2px}

.nav{display:flex; flex-direction:column; gap:2px; margin-bottom:16px}
.nav button{
  display:flex; align-items:center; gap:9px; width:100%; text-align:left; cursor:pointer;
  background:transparent; border:1px solid transparent; border-radius:8px;
  color:var(--muted); font-size:13px; padding:7px 9px; transition:.12s ease;
}
.nav button:hover{background:var(--card); color:var(--ink)}
.nav button.on{background:var(--cream); border-color:var(--hairline); color:var(--ink)}
.nav button i{font-style:normal; font-size:12px; color:var(--dim); width:13px; text-align:center}
.nav button.on i{color:var(--accent)}
.nav button em{
  margin-left:auto; font-style:normal; font-size:10.5px; font-family:var(--mono);
  color:var(--dim); background:var(--canvas); border-radius:9999px; padding:0 6px; line-height:15px;
}
.nav button em:empty{display:none}
.nav button em.hot{background:var(--accent); color:#fff}

.sec{min-height:0; display:flex; flex-direction:column; margin-bottom:14px}
.sec-h{display:flex; align-items:center; justify-content:space-between; padding:0 4px 8px}
.sec h4{margin:0; font-size:12px; font-weight:500; color:var(--muted); letter-spacing:1px}
.mini{
  background:var(--canvas); border:1px solid var(--hairline); border-radius:8px; cursor:pointer;
  color:var(--body); font-size:12px; font-weight:500; padding:4px 11px; transition:.12s ease; white-space:nowrap;
}
.mini:hover{border-color:var(--dim); color:var(--ink); background:var(--card)}
.mini.primary{background:var(--accent); border-color:var(--accent); color:#fff}
.mini.primary:hover{background:var(--accent-active); border-color:var(--accent-active)}
.mini:disabled{opacity:.5; cursor:not-allowed; background:var(--accent-off); border-color:var(--accent-off); color:var(--dim)}

.sessions{overflow-y:auto; flex:1; min-height:60px; margin:0 -4px; padding:0 4px}
.find{
  width:100%; background:var(--canvas); border:1px solid var(--hairline); border-radius:8px;
  color:var(--ink); font:inherit; font-size:12.5px; padding:6px 10px; margin-bottom:8px; flex:none;
  outline:0; transition:.12s ease;
}
.find::placeholder{color:var(--dim)}
.find:focus{border-color:var(--accent); box-shadow:0 0 0 3px #cc785c26}
.srow{display:flex; align-items:stretch; gap:2px; margin-bottom:2px}
.sitem{
  display:block; width:auto; flex:1; min-width:0; text-align:left; cursor:pointer;
  background:transparent; border:1px solid transparent; border-radius:8px;
  padding:7px 9px; margin-bottom:0; transition:.12s ease; color:var(--muted);
}
.sitem:hover{background:var(--card); color:var(--ink)}
.srow.on .sitem{background:var(--cream); border-color:var(--hairline); color:var(--ink)}
.sdel{
  flex:none; align-self:center; background:transparent; border:0; cursor:pointer;
  color:var(--dim); font-size:11px; padding:4px 6px; border-radius:6px;
}
.sdel:hover{color:var(--ink); background:var(--card)}
.sdel:disabled{opacity:.5; cursor:not-allowed}
.sitem .t{font-size:12.5px; line-height:1.45; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden}
.sitem .d{font-size:10.5px; color:var(--dim); font-family:var(--mono); margin-top:3px}
.hint{font-size:12px; color:var(--dim); padding:8px 10px}

.src{
  margin-top:auto; background:var(--canvas); border:1px solid var(--hairline);
  border-radius:var(--r); padding:11px 12px; flex:none;
}
.src .f{font-family:var(--mono); font-size:11.5px; word-break:break-all; color:var(--ink)}
.src .m{font-size:11px; color:var(--muted); margin-top:4px}
.src .tag{
  display:inline-block; margin-top:8px; padding:2px 8px; border-radius:9999px;
  background:var(--cream); color:var(--body); font-size:10.5px; font-family:var(--mono);
}

/* ---------- 主区 ---------- */
.main{min-width:0; min-height:0; display:flex; flex-direction:column}
.view{display:none; flex-direction:column; min-height:0; height:100%}
.view.on{display:flex}

.top{
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  padding:14px 26px; border-bottom:1px solid var(--hairline); flex:none;
}
.top h1{
  margin:0; font-family:var(--serif); font-size:17px; font-weight:400; color:var(--ink);
  letter-spacing:0; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.status{display:flex; align-items:center; gap:7px; font-size:11.5px; color:var(--muted); font-family:var(--mono); flex:none}
.status i{width:7px; height:7px; border-radius:50%; background:var(--dim); font-style:normal}
.status.on i{background:var(--teal); animation:p 1.1s ease-in-out infinite}
.status.done i{background:var(--ok)}
.status.err i{background:var(--err)}
@keyframes p{0%,100%{opacity:1}50%{opacity:.28}}

/* ---------- 对话流 ---------- */
.stream{flex:1; overflow-y:auto; padding:28px 26px 10px}
.wrap{max-width:840px; margin:0 auto}

.u{display:flex; justify-content:flex-end; margin-bottom:20px}
.u div{
  background:var(--cream); color:var(--ink); padding:10px 15px; font-size:13.5px;
  border-radius:14px 14px 4px 14px; max-width:80%; white-space:pre-wrap; word-break:break-word;
}

.a{margin-bottom:28px}

.acts{margin:0 0 14px; border:1px solid #2e2c28; border-radius:var(--r); background:var(--dark); overflow:hidden}
.acts-head{
  display:flex; align-items:center; gap:9px; width:100%; cursor:pointer; text-align:left;
  background:transparent; border:0; color:var(--on-dark-soft); font-size:12px; padding:9px 13px; transition:.12s ease;
}
.acts-head:hover{background:var(--dark-2); color:var(--on-dark)}
.acts-head .car{color:var(--on-dark-soft); font-size:9px; transition:transform .15s; flex:none}
.acts.open .acts-head .car{transform:rotate(90deg)}
.acts-head .hd{font-weight:500}
.acts-head .mt{margin-left:auto; font-family:var(--mono); font-size:11px; color:#6f6c66; flex:none}
.acts-head .sp{width:7px; height:7px; border-radius:50%; background:var(--teal); animation:p 1.1s ease-in-out infinite; flex:none}
.acts-body{display:none; padding:2px 13px 11px; border-top:1px solid #2e2c28}
.acts.open .acts-body{display:block}

.row{
  display:flex; align-items:baseline; gap:8px; padding:3.5px 0;
  font-family:var(--mono); font-size:11.5px; line-height:1.55; color:var(--on-dark-soft);
}
.row .ic{flex:none; width:11px; text-align:center; color:var(--teal)}
.row.done .ic{color:var(--ok)}
.row.err .ic{color:var(--err)}
.row .tx{min-width:0; word-break:break-word}
.row .n{color:#6f6c66; flex:none}
.row .dur{color:#6f6c66; font-size:10.5px; flex:none}
.srow{position:relative}
.srow .row{padding-right:52px}
.rowmore{
  position:absolute; right:0; top:2px; opacity:0; cursor:pointer; transition:.12s ease;
  background:var(--dark-3); border:1px solid #2e2c28; border-radius:5px;
  color:var(--on-dark-soft); font-size:10.5px; font-family:var(--mono); padding:1px 7px; line-height:1.5;
}
.srow:hover .rowmore{opacity:1}
.rowmore:hover{color:var(--on-dark); border-color:var(--on-dark-soft)}
.srow.open .rowmore{opacity:1; color:var(--teal); border-color:#5db8a666}
pre.raw{
  font-family:var(--mono); font-size:11px; color:var(--on-dark-soft); line-height:1.5;
  background:var(--dark-3); border:1px solid #2e2c28; border-radius:6px;
  padding:8px 10px; margin:4px 0 7px; overflow-x:auto; white-space:pre-wrap; word-break:break-all;
}

/* 回答正文 */
.body{font-size:14px; line-height:1.72; word-break:break-word; color:var(--body)}
.body:empty{display:none}
.body p{margin:0 0 10px}
.body table{border-collapse:collapse; width:100%; margin:12px 0; font-size:12.5px}
.body th,.body td{border:1px solid var(--hairline); padding:6px 10px; text-align:left}
.body th{background:var(--card); font-weight:500; color:var(--muted)}
.body td{font-family:var(--mono); font-size:12px; color:var(--body)}
.body code{font-family:var(--mono); font-size:12px; background:var(--card); padding:1px 5px; border-radius:4px; color:var(--strong)}
.body h3{font-family:var(--serif); font-size:15px; margin:20px 0 8px; font-weight:400; color:var(--ink)}
.body strong{color:var(--ink); font-weight:500}
.body hr{border:0; border-top:1px solid var(--hairline); margin:16px 0}

/* ---------- 安全闸门卡 ---------- */
/* 闸门是这套 demo 的论点，所以单独给它一块视觉重量：深底 + 左侧等级色条 */
.gate{
  margin:14px 0; border:1px solid #2e2c28; border-left:3px solid var(--dim);
  border-radius:var(--r); background:var(--dark); overflow:hidden;
}
.gate.lv-L{border-left-color:var(--teal)}
.gate.lv-M{border-left-color:var(--ok)}
.gate.lv-H{border-left-color:var(--warn)}
.gate.lv-C{border-left-color:var(--err)}
/* X 不是风险等级：这个动作没通过静态校验，压根没进入分级 */
.gate.lv-X{border-left-color:var(--dim)}
.gate-h{display:flex; align-items:center; gap:9px; padding:10px 13px; border-bottom:1px solid #2e2c28}
.gate-h b{font-size:12.5px; font-weight:500; color:var(--on-dark)}
.gate-h .lv{
  font-family:var(--mono); font-size:10.5px; padding:1px 8px; border-radius:9999px; flex:none;
  background:#ffffff14; color:var(--on-dark);
}
.gate-h .dec{margin-left:auto; font-family:var(--mono); font-size:11px; color:var(--on-dark-soft); flex:none}
.gate-b{padding:11px 13px}
.gate ul{margin:0; padding-left:18px; color:var(--on-dark-soft); font-size:12px; line-height:1.65}
.gate li{margin-bottom:2px}
.gate .pend{
  font-family:var(--mono); font-size:11px; color:#6f6c66; margin-top:9px; word-break:break-all;
}
.gate-act{display:flex; gap:8px; margin-top:12px}
.gate-act button{
  cursor:pointer; border-radius:8px; font-size:12.5px; font-weight:500; padding:6px 15px; transition:.12s ease;
  background:var(--accent); border:1px solid var(--accent); color:#fff;
}
.gate-act button:hover{background:var(--accent-active); border-color:var(--accent-active)}
.gate-act button.ghost{background:transparent; border-color:#3d3a35; color:var(--on-dark-soft)}
.gate-act button.ghost:hover{background:var(--dark-2); color:var(--on-dark)}
.gate-act button:disabled{opacity:.5; cursor:not-allowed}

/* 执行结果卡：请求与响应都是真实 HTTP 报文，直接铺出来 */
.exec{margin:14px 0; border:1px solid var(--hairline); border-radius:var(--r); background:var(--canvas); overflow:hidden}
.exec-h{display:flex; align-items:center; gap:9px; padding:10px 14px; border-bottom:1px solid var(--hairline-2)}
.exec-h b{font-size:12.5px; font-weight:500; color:var(--ink)}
.exec-h .ms{margin-left:auto; font-family:var(--mono); font-size:10.5px; color:var(--dim); flex:none}
.exec-h .badge{margin-left:0}
.exec-b{padding:0}
.exec .kv2{display:flex; gap:10px; padding:8px 14px; border-top:1px solid var(--hairline-2); font-size:12px; align-items:baseline}
.exec .kv2:first-child{border-top:0}
.exec .kv2 .k{color:var(--dim); flex:none; width:52px}
.exec .kv2 .v{font-family:var(--mono); font-size:11.5px; color:var(--body); min-width:0; word-break:break-all}
.exec .io{border-top:1px solid var(--hairline-2); padding:9px 14px}
.exec .io .lbl{font-size:10.5px; font-family:var(--mono); color:var(--dim); margin-bottom:5px}
.exec pre{
  font-family:var(--mono); font-size:11px; color:var(--body); background:var(--soft);
  border:1px solid var(--hairline); border-radius:6px; padding:8px 10px; margin:0;
  overflow-x:auto; white-space:pre-wrap; word-break:break-all; max-height:220px;
}

/* 报修卡：预览即将打开的 App 页。地址是预留的，不提交工单。 */
.repair{margin:14px 0; border:1px solid var(--hairline); border-radius:var(--r); background:var(--canvas); padding:14px 16px}
.repair-h{display:flex; align-items:center; gap:8px; margin-bottom:6px}
.repair-h b{font-family:var(--serif); font-size:14px; font-weight:400; color:var(--ink)}
.repair p{margin:0 0 12px; font-size:12.5px; color:var(--muted)}
.repair-phone{
  width:min(280px, 100%); border:1px solid var(--hairline); border-radius:16px; background:var(--soft);
  overflow:hidden;
}
.rp-top{display:flex; justify-content:space-between; align-items:center; padding:8px 12px; background:var(--dark); color:var(--on-dark); font-size:11px}
.rp-top em{font-style:normal; color:var(--on-dark-soft)}
.rp-body{padding:12px}
.rp-title{font-family:var(--serif); font-size:15px; color:var(--ink); margin-bottom:10px}
.rp-field{display:flex; gap:10px; padding:7px 0; border-top:1px solid var(--hairline); font-size:12.5px}
.rp-field span{color:var(--dim); width:36px; flex:none}
.rp-field b{font-weight:500; color:var(--ink)}
.rp-btn{margin-top:12px; text-align:center; background:var(--accent); color:#fff; border-radius:8px; padding:7px 0; font-size:12.5px}
.rp-sub{margin-top:6px; font-size:11px; color:var(--dim); text-align:center}
.rp-empty{font-size:12.5px; color:var(--muted); line-height:1.6}
.repair-foot{display:flex; align-items:center; gap:10px; margin-top:12px}
.repair-url{font-family:var(--mono); font-size:11px; color:var(--dim); word-break:break-all}
.repair-mask{
  position:fixed; inset:0; z-index:40; background:rgba(20,20,19,.45);
  display:flex; align-items:center; justify-content:center; padding:24px;
}
.repair-sheet{
  width:min(420px, 100%); background:var(--canvas); border-radius:16px; padding:16px 18px 18px;
  border:1px solid var(--hairline);
}
.repair-sheet-h{display:flex; align-items:center; justify-content:space-between; margin-bottom:12px}
.repair-sheet-h b{font-family:var(--serif); font-size:16px; font-weight:400; color:var(--ink)}
.repair-tabs{display:flex; gap:6px; margin-bottom:12px}
.repair-tabs button{
  font:inherit; font-size:12px; border:1px solid var(--hairline); background:transparent;
  border-radius:9999px; padding:5px 12px; color:var(--muted); cursor:pointer;
}
.repair-tabs button.on{background:var(--dark); color:var(--on-dark); border-color:var(--dark)}
.repair-stage .repair-phone{width:100%}
.repair-sheet .repair-url{display:block; margin-top:10px}
.repair-sheet p{margin:8px 0 0; font-size:12px; color:var(--muted)}

.follows{display:flex; flex-wrap:wrap; gap:7px; margin-top:14px}
.follows:empty{display:none}
.chip{
  background:var(--canvas); border:1px solid var(--hairline); border-radius:9999px; cursor:pointer;
  color:var(--body); font-size:12px; padding:6px 13px; transition:.12s ease; text-align:left;
}
.chip:hover{border-color:var(--accent); color:var(--accent-active); background:#cc785c14}

.empty{color:var(--dim); text-align:center; padding:40px 20px; font-size:13.5px}
.empty b{display:block; font-family:var(--serif); color:var(--ink); font-size:22px; margin-bottom:10px; font-weight:400}
.stream:has(> .wrap > .empty){display:flex; align-items:center; justify-content:center}
.stream:has(> .wrap > .empty) > .wrap{width:100%; margin:0}
.starters{display:flex; flex-direction:column; gap:8px; max-width:560px; margin:30px auto 0}
.starters button{
  cursor:pointer; text-align:left; background:var(--canvas); border:1px solid var(--hairline);
  border-radius:var(--r); color:var(--body); font-size:13px; padding:12px 15px; transition:.12s ease;
}
.starters button:hover{border-color:var(--dim); color:var(--ink); background:var(--cream)}
.starters button .tagline{display:block; font-size:11px; color:var(--dim); margin-top:3px}

/* ---------- 输入 ---------- */
.composer{padding:12px 26px 20px; flex:none}
.cwrap{
  max-width:840px; margin:0 auto; display:flex; gap:10px; align-items:flex-end;
  background:var(--canvas); border:1px solid var(--hairline); border-radius:var(--r);
  padding:9px 9px 9px 15px; transition:.12s ease;
}
.cwrap:focus-within{border-color:var(--accent); box-shadow:0 0 0 3px #cc785c26}
textarea{
  flex:1; background:transparent; border:0; outline:0; resize:none; color:var(--ink);
  font:inherit; font-size:13.5px; line-height:1.6; max-height:140px; padding:6px 0;
}
textarea::placeholder{color:var(--dim)}
.send{
  flex:none; width:36px; height:36px; border-radius:8px; border:0; cursor:pointer;
  background:var(--accent); color:#fff; font-size:15px; display:grid; place-items:center; transition:.12s ease;
}
.send:hover:not(:disabled){background:var(--accent-active)}
.send:disabled{background:var(--accent-off); color:var(--muted); cursor:not-allowed}
/* 麦克风是次级入口，平时不抢 coral（它留给发送键）；只有录音中才用红，
   因为那是一个「正在进行、需要被看见」的状态，和待确认卡同一个道理。 */
.mic{
  flex:none; width:36px; height:36px; border-radius:8px; cursor:pointer;
  border:1px solid var(--hairline); background:var(--canvas); color:var(--muted);
  display:grid; place-items:center; transition:.12s ease;
  user-select:none; touch-action:none;
}
.mic:hover:not(:disabled){border-color:var(--dim); color:var(--ink)}
.mic.rec{background:var(--err); border-color:var(--err); color:#fff; animation:mic-pulse 1.1s ease-in-out infinite}
.mic.wait{color:var(--muted); border-color:var(--dim); cursor:progress}
.mic:disabled{opacity:.45; cursor:not-allowed}
@keyframes mic-pulse{
  0%,100%{box-shadow:0 0 0 0 #c6454566}
  50%{box-shadow:0 0 0 6px #c6454500}
}

/* 长按时人的视线在输入框上，所以录音反馈做进输入栏本身：边框转红 + 一条随真实
   音量起伏的电平条。右上角那行状态字不再承担「正在录音」，太远，看不见。
   红还是同一个语义：正在进行、需要被看见，和麦克风键、待确认卡一致。 */
.cfield{flex:1; min-width:0; position:relative; display:flex}
.cwrap.rec{border-color:var(--err); box-shadow:0 0 0 3px #c6454526}
.cwrap.wait{border-color:var(--dim); box-shadow:none}

.listen{display:none; position:absolute; inset:0; align-items:center; gap:11px; padding:6px 0; pointer-events:none}
.cwrap.rec .listen,.cwrap.wait .listen{display:flex}
/* 录音期间把 textarea 藏起来但不卸载：里面已打的字要留着，转写完还要接在后面 */
.cwrap.rec textarea,.cwrap.wait textarea{visibility:hidden}

.ldot{flex:none; width:7px; height:7px; border-radius:50%; background:var(--err); animation:p 1.1s ease-in-out infinite}
.cwrap.wait .ldot{display:none}

/* 30 根柱子由 rAF 逐帧写 scaleY，不加 transition——rAF 的节奏本身就是平滑，
   再叠一层过渡只会让电平条滞后于声音。 */
.bars{flex:1; min-width:0; display:flex; align-items:center; gap:2px; height:22px}
.bars i{flex:1; min-width:2px; height:100%; border-radius:1px; background:var(--err); opacity:.8; transform:scaleY(.06); transform-origin:center}
/* 转写中不是录音了：同一排柱子改成来回扫的进度，别让人以为还在听 */
.cwrap.wait .bars i{background:var(--muted); opacity:.4; animation:bar-sweep 1s ease-in-out infinite; animation-delay:calc(var(--i) * 28ms)}
@keyframes bar-sweep{0%,100%{transform:scaleY(.06)}50%{transform:scaleY(.55)}}

.lmsg{flex:none; min-width:40px; text-align:right; font-family:var(--mono); font-size:11.5px; color:var(--err)}
.cwrap.wait .lmsg{color:var(--muted); min-width:0}

/* 松手后视线还在输入栏上，所以失败原因也落在这里闪一下。
   右上角同时保留一份，那是不随时间消失的持久状态。 */
.cwrap.err{border-color:var(--err); box-shadow:0 0 0 3px #c6454526}
.cwrap.err .listen{display:flex}
.cwrap.err textarea{visibility:hidden}
.cwrap.err .ldot,.cwrap.err .bars{display:none}
.cwrap.err .lmsg{color:var(--err); min-width:0}

/* ---------- 设备面板 / 审计 ---------- */
.pane{flex:1; overflow-y:auto; padding:24px 26px 34px}
.pane-inner{max-width:960px; margin:0 auto}
.card{background:var(--canvas); border:1px solid var(--hairline); border-radius:var(--r); padding:16px 18px; margin-bottom:12px}
.card h3{margin:0 0 11px; font-family:var(--serif); font-size:15px; font-weight:400; color:var(--ink)}
.kv{display:flex; gap:12px; font-size:12.5px; padding:6px 0; border-top:1px solid var(--hairline-2)}
.kv:first-of-type{border-top:0}
.kv .k{color:var(--dim); flex:none; width:74px}
.kv .v{color:var(--body); min-width:0; word-break:break-word}
.kv .v.mono{font-family:var(--mono); font-size:11.5px}
.badge{
  display:inline-block; padding:2px 9px; border-radius:9999px; font-size:10.5px;
  font-family:var(--mono); background:var(--card); color:var(--muted); border:1px solid var(--hairline);
  vertical-align:middle;
}
.badge.ok{background:#5db8721f; color:#3f8a52; border-color:#5db87240}
.badge.run{background:var(--accent); color:#fff; border-color:var(--accent)}
.badge.err{background:#c645451f; color:var(--err); border-color:#c6454540}
.badge.warn{background:#d4a0171f; color:#8a6a08; border-color:#d4a01740}

table.grid{border-collapse:collapse; width:100%; font-size:12.5px}
table.grid th,table.grid td{border-bottom:1px solid var(--hairline-2); padding:8px 10px; text-align:left; vertical-align:top}
table.grid th{font-size:11px; color:var(--dim); font-weight:500; letter-spacing:.5px}
table.grid td.mono{font-family:var(--mono); font-size:11.5px}
table.grid tr:hover td{background:var(--soft)}
.dot{display:inline-block; width:7px; height:7px; border-radius:50%; background:var(--dim); margin-right:5px; vertical-align:1px}
.dot.on{background:var(--ok)}
.pill{
  display:inline-block; font-family:var(--mono); font-size:10.5px; padding:1px 7px; border-radius:9999px;
  background:var(--card); color:var(--muted); border:1px solid var(--hairline);
  /* createBy 里带连字符（internal-task），不给 nowrap 会在窄列里断成两行 */
  white-space:nowrap;
}
.pill.on{background:#5db8721f; color:#3f8a52; border-color:#5db87240}
.lvl{display:inline-block; font-family:var(--mono); font-size:10.5px; padding:1px 7px; border-radius:5px; color:#fff}
.lvl.L{background:var(--teal)}
.lvl.M{background:var(--ok)}
.lvl.H{background:var(--warn)}
.lvl.C{background:var(--err)}
.lvl.X{background:var(--dim)}

/* ---------- 技能管理 / 产物中心 ---------- */
/* 两页共用的小件：一行输入 + 按钮、一组行内动作、名字下面挂一行等宽小字 */
.rowline{display:flex; gap:8px; align-items:center; margin:10px 0}
.rowline .find{flex:1 1 auto; width:auto; margin-bottom:0}
.rowacts{display:flex; gap:6px; align-items:center; flex-wrap:wrap}
/* 表格里的操作列：三个按钮必须横着排，不然窄列里会摞成三行。
   类名别叫 acts——那已经被执行过程面板占了（深色底），撞上会整格变黑。 */
table.grid td.acts-cell{white-space:nowrap}
table.grid td.acts-cell .rowacts{flex-wrap:nowrap}
a.mini{display:inline-block; text-decoration:none; line-height:1.5}
.sn{font-weight:500; color:var(--ink)}
.sid{font-family:var(--mono); font-size:10.5px; color:var(--dim); margin-top:3px; word-break:break-all}
.hint.err{color:var(--err)}
input.filein{
  flex:1 1 auto; min-width:0; font:inherit; font-size:12px; color:var(--muted);
  background:var(--canvas); border:1px solid var(--hairline); border-radius:8px; padding:5px 8px;
}
input.filein::file-selector-button{
  font:inherit; font-size:11.5px; cursor:pointer; margin-right:9px; padding:2px 9px;
  border:1px solid var(--hairline); border-radius:6px; background:var(--soft); color:var(--body);
}
/* 展开的更新行：贴在它所属的那一行下面，缩进一格表示从属关系 */
table.grid tr.sub td{background:var(--soft); padding:10px 12px 12px 22px}
table.grid tr.sub .hint{padding:4px 0 0}
/* 挂载那几行右侧要放按钮，值这一栏得把剩余宽度吃掉 */
.kv .v{flex:1}

/* 产物卡：交付物是这一轮的落点，单独给一张卡，不混进工具行 */
.artifact{margin:14px 0; border:1px solid var(--hairline); border-radius:var(--r); background:var(--canvas); padding:12px 14px}
.artifact-h{display:flex; align-items:center; gap:9px}
.artifact-h .ico{color:var(--accent); font-size:13px; flex:none}
.artifact-h .fn{font-family:var(--mono); font-size:12.5px; color:var(--ink); min-width:0; word-break:break-all}
.artifact-h .act{margin-left:auto; flex:none}
.artifact-m{font-family:var(--mono); font-size:10.5px; color:var(--dim); margin-top:6px; word-break:break-all}

/* 访问口令页。整页替换，所以自己撑满视口居中 */
.authgate{min-height:100vh; display:flex; align-items:center; justify-content:center; padding:24px; background:var(--canvas)}
.authcard{
  width:100%; max-width:360px; background:var(--card); border:1px solid var(--hairline);
  border-radius:var(--r); padding:24px 22px; display:flex; flex-direction:column; gap:10px;
}
.authcard h2{margin:0 0 2px; font-size:15px; color:var(--ink)}
.authcard .hint{padding:0; margin:0 0 6px}
.authcard input{
  font:inherit; font-size:13px; color:var(--ink); background:var(--canvas);
  border:1px solid var(--hairline); border-radius:8px; padding:9px 11px;
}
.authcard input:focus{outline:none; border-color:var(--accent)}
.authcard .mini{width:100%; justify-content:center; padding:8px 0}

@media (max-width:820px){
  .app{grid-template-columns:1fr}
  .side{display:none}
}
