:root{
  --ink:#16283a; --sub:#5f7near; --sub:#607a92; --line:#dbe7f4; --line2:#eef4fb;
  --blue:#2f7bd6; --blue2:#6bb2f8; --blue-soft:#eaf4ff; --bg:#f5f9ff; --card:#ffffff;
  --ok:#1f9d63; --bad:#d2453f; --shadow:0 12px 30px rgba(30,80,140,.08);
  --radius:16px;
}
*{box-sizing:border-box}
html,body{height:100%}
body{
  margin:0;background:radial-gradient(1100px 520px at 8% -8%,#e2f0ff 0,#f7fbff 46%,#f4f9ff 100%);
  color:var(--ink);font:15px/1.65 "PingFang SC","Microsoft YaHei",system-ui,-apple-system,"Segoe UI",sans-serif;
  -webkit-font-smoothing:antialiased;display:flex;flex-direction:column;min-height:100%;
}
a{color:var(--blue);text-decoration:none}
a:hover{text-decoration:underline}
code{background:#eef5fd;padding:1px 6px;border-radius:6px;font-size:12.5px}

/* 锁定条 */
.qdfy-lockbar{background:#fff1f0;border-bottom:1px solid #ffd6d2;color:#9d332d;padding:12px 18px;font-size:13.5px;line-height:1.7}
.qdfy-lockbar code{background:#ffe3e0}

/* 页脚署名（全站唯一出口） */
.qdfy-foot{margin-top:auto;padding:16px 12px 20px;text-align:center}
.qdfy-foot-in{display:inline-flex;flex-wrap:wrap;gap:8px;align-items:center;justify-content:center;
  color:#7791a8;font-size:12.5px;background:rgba(255,255,255,.72);border:1px solid var(--line2);
  padding:7px 16px;border-radius:999px}
.qdfy-brand{color:var(--ink);font-weight:700;letter-spacing:.3px}
.qdfy-sep{opacity:.45}
.qdfy-author,.qdfy-wechat{color:var(--blue)}
.qdfy-badge{display:inline-grid;place-items:center;width:18px;height:18px;border-radius:6px;
  background:linear-gradient(145deg,#2f7bd6,#7cc2ff);color:#fff;font-size:11px;font-weight:700;vertical-align:1px}

/* ---------- 应用骨架 ---------- */
.app{flex:1;display:flex;min-height:0;max-width:1180px;width:100%;margin:0 auto;padding:18px 18px 0;gap:16px}
.side{width:252px;flex:0 0 252px;background:rgba(255,255,255,.86);border:1px solid var(--line);
  border-radius:var(--radius);padding:16px 14px;display:flex;flex-direction:column;box-shadow:var(--shadow);backdrop-filter:blur(6px)}
.brand{display:flex;gap:10px;align-items:center;margin-bottom:14px}
.avatar{width:42px;height:42px;border-radius:13px;background:linear-gradient(150deg,#2f7bd6,#83c7ff);
  display:grid;place-items:center;font-size:22px;box-shadow:0 8px 18px rgba(47,123,214,.26)}
.brand-name{font-weight:700;font-size:15px;display:flex;align-items:center;gap:5px}
.brand-sub{font-size:11.5px;color:var(--sub)}
.newchat{border:1px dashed #b9d7f5;background:var(--blue-soft);color:var(--blue);border-radius:11px;
  padding:9px;font-size:13.5px;cursor:pointer;transition:.15s}
.newchat:hover{background:#dfeeff;border-color:#8dc2f2}
.sess-list{margin-top:12px;flex:1;overflow:auto;display:flex;flex-direction:column;gap:4px}
.sess{display:flex;justify-content:space-between;gap:6px;padding:8px 9px;border-radius:10px;cursor:pointer;font-size:13.5px;color:#33506b}
.sess:hover{background:#f2f8ff}
.sess.on{background:#e6f1ff;color:var(--blue);font-weight:600}
.sess-t{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:150px}
.sess-d{font-size:11px;color:#9db2c6;flex:0 0 auto}
.side-foot{display:flex;align-items:center;gap:10px;border-top:1px solid var(--line2);padding-top:10px;font-size:12.5px}
.me{color:var(--sub);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mini{font-size:12.5px;color:var(--sub)}
.mini:hover{color:var(--blue)}

.main{flex:1;min-width:0;display:flex;flex-direction:column;background:rgba(255,255,255,.9);
  border:1px solid var(--line);border-radius:var(--radius);box-shadow:var(--shadow);overflow:hidden}
.topbar{display:flex;align-items:center;gap:10px;padding:12px 16px;border-bottom:1px solid var(--line2);background:#fbfdff}
.top-t{display:flex;flex-direction:column;line-height:1.35}
.top-t span{font-size:11.5px;color:var(--sub)}
.burger{display:none;border:0;background:transparent;font-size:18px;cursor:pointer;color:var(--sub)}

.stream{flex:1;overflow-y:auto;padding:20px 18px 8px;display:flex;flex-direction:column;gap:12px;scroll-behavior:smooth}
.hello{text-align:center;color:var(--sub);font-size:13.5px;margin:18px auto 8px;max-width:420px}
.hello-avatar{width:52px;height:52px;border-radius:16px;margin:0 auto 10px;display:grid;place-items:center;
  font-size:26px;background:linear-gradient(150deg,#dcecff,#f2f9ff);border:1px solid #d7e9ff}
.msg{display:flex;gap:9px;max-width:82%}
.msg .bubble{padding:10px 14px;border-radius:14px;font-size:14.5px;line-height:1.7;white-space:pre-wrap;word-break:break-word}
.msg.bot{align-self:flex-start}
.msg.bot .bubble{background:#f4f9ff;border:1px solid #e3effc;border-top-left-radius:5px}
.msg.user{align-self:flex-end;flex-direction:row-reverse}
.msg.user .bubble{background:linear-gradient(150deg,#2f7bd6,#4f9ae8);color:#fff;border-top-right-radius:5px;box-shadow:0 6px 16px rgba(47,123,214,.18)}
.msg .who{width:30px;height:30px;border-radius:10px;flex:0 0 30px;display:grid;place-items:center;font-size:15px;
  background:#eaf4ff;border:1px solid #dceaf9}
.msg.user .who{background:#dcecff;border-color:#cfe3fa}
.typing{display:inline-flex;gap:3px;align-items:center;height:18px}
.typing i{width:4px;height:4px;border-radius:50%;background:#8fb8dd;animation:bl 1.2s infinite}
.typing i:nth-child(2){animation-delay:.15s}.typing i:nth-child(3){animation-delay:.3s}
@keyframes bl{0%,60%,100%{opacity:.25;transform:translateY(0)}30%{opacity:1;transform:translateY(-2px)}}

.composer{display:flex;gap:10px;align-items:flex-end;padding:12px 14px 14px;border-top:1px solid var(--line2);background:#fbfdff;position:relative}
.composer textarea{flex:1;resize:none;max-height:140px;min-height:44px;padding:11px 13px;border:1px solid var(--line);
  border-radius:13px;font:inherit;font-size:14.5px;background:#fff;color:var(--ink)}
.composer textarea:focus{outline:none;border-color:var(--blue2);box-shadow:0 0 0 3px rgba(107,178,248,.16)}
.send{width:44px;height:44px;border-radius:13px;border:0;background:linear-gradient(150deg,#2f7bd6,#4f9ae8);
  color:#fff;font-size:18px;cursor:pointer;box-shadow:0 8px 18px rgba(47,123,214,.25)}
.send:disabled{opacity:.45;cursor:not-allowed}
.hint{position:absolute;left:16px;bottom:-2px;font-size:11.5px;color:#a8bccd}

/* ---------- 登录 ---------- */
.login-wrap{flex:1;display:grid;place-items:center;padding:36px 18px}
.login-card{width:100%;max-width:380px;background:var(--card);border:1px solid var(--line);border-radius:20px;
  padding:30px 26px;box-shadow:var(--shadow);text-align:center}
.login-whale{width:58px;height:58px;border-radius:18px;margin:0 auto 12px;display:grid;place-items:center;font-size:30px;
  background:linear-gradient(150deg,#dcecff,#f4faff);border:1px solid #d7e9ff}
.login-card h1{margin:0;font-size:21px;letter-spacing:.4px}
.login-sub{color:var(--sub);font-size:12.5px;margin:6px 0 18px}
.login-card label{display:block;text-align:left;font-size:12.5px;color:var(--sub);margin:12px 0 5px}
.login-card input{width:100%;padding:11px 13px;border:1px solid var(--line);border-radius:11px;font-size:14.5px;background:#fbfdff}
.login-card input:focus{outline:none;border-color:var(--blue2);box-shadow:0 0 0 3px rgba(107,178,248,.16)}
.btn-full{width:100%;margin-top:18px;padding:12px;border:0;border-radius:12px;cursor:pointer;color:#fff;font-size:15px;
  background:linear-gradient(150deg,#2f7bd6,#4f9ae8);box-shadow:0 8px 20px rgba(47,123,214,.24)}
.login-err{background:#fff3f2;border:1px solid #ffd7d3;color:#a3352f;padding:9px 12px;border-radius:10px;font-size:13px;margin-bottom:6px}
.login-tip{font-size:12.5px;color:var(--sub);margin:14px 0 0}

/* ---------- 后台 ---------- */
.admin{flex:1;width:100%;max-width:900px;margin:0 auto;padding:22px 18px 0}
.admin-top{display:flex;justify-content:space-between;align-items:flex-start;gap:12px;margin-bottom:6px}
.admin-sub{display:block;font-size:12px;color:var(--sub);margin-top:2px}
.card{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);padding:20px;margin-top:16px;box-shadow:var(--shadow)}
.card h2{font-size:15.5px;margin:0 0 12px;display:flex;align-items:center;gap:8px}
.h2-sub{font-size:12px;color:var(--sub);font-weight:400}
.stat-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:10px}
.stat{background:#f6fbff;border:1px solid var(--line2);border-radius:12px;padding:12px 14px;display:flex;flex-direction:column;gap:2px}
.stat span{font-size:12px;color:var(--sub)}
.stat b{font-size:20px}
.stat b.g{color:var(--ok)}.stat b.r{color:var(--bad)}
.card label{display:block;font-size:12.5px;color:var(--sub);margin:13px 0 5px}
.card input[type=text],.card input:not([type]),.card input[type=password],.card textarea{width:100%;padding:10px 12px;
  border:1px solid var(--line);border-radius:10px;font:inherit;font-size:14px;background:#fbfdff;color:var(--ink)}
.card textarea{resize:vertical}
.card input:focus,.card textarea:focus{outline:none;border-color:var(--blue2);box-shadow:0 0 0 3px rgba(107,178,248,.16)}
label.chk{display:flex;align-items:center;gap:8px;font-size:13.5px;color:var(--ink);margin-top:14px}
.btns{display:flex;gap:10px;margin-top:16px}
.btn{border:0;border-radius:11px;padding:10px 20px;font-size:14px;cursor:pointer;color:#fff;
  background:linear-gradient(150deg,#2f7bd6,#4f9ae8);box-shadow:0 7px 16px rgba(47,123,214,.22)}
.btn.ghost{background:#fff;color:var(--blue);border:1px solid #bcd8f4;box-shadow:none}
.inline{display:flex;align-items:center;gap:10px;margin-top:12px;flex-wrap:wrap}
.tip{font-size:12.5px;color:var(--sub);line-height:1.7;margin:8px 0 0}
.flash{padding:10px 14px;border-radius:11px;font-size:13.5px;margin-top:12px}
.flash.ok{background:#effaf4;border:1px solid #c9eedd;color:#146c47}
.flash.bad{background:#fff3f2;border:1px solid #ffd7d3;color:#a3352f}
.mem-add{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:12px}
.mem-add input[name=mem_content]{flex:1 1 240px}
.tag-in{flex:0 0 130px}.imp-in{flex:0 0 64px}
.mem-list{display:flex;flex-direction:column;gap:8px;max-height:420px;overflow:auto}
.mem{border:1px solid var(--line2);border-radius:11px;padding:10px 12px;background:#fbfdff}
.mem-c{font-size:14px}
.mem-m{display:flex;gap:12px;align-items:center;flex-wrap:wrap;font-size:11.5px;color:var(--sub);margin-top:5px}
.mem-m form{display:inline}
.mem-tag{background:#eaf4ff;color:#3b7bb8;padding:1px 7px;border-radius:999px}
.link{border:0;background:none;color:var(--blue);cursor:pointer;font-size:11.5px;padding:0}
.link.danger{color:var(--bad)}
.tbl{width:100%;border-collapse:collapse;font-size:13.5px}
.tbl th{text-align:left;color:var(--sub);font-weight:500;font-size:12px;padding:6px 8px;border-bottom:1px solid var(--line2)}
.tbl td{padding:8px;border-bottom:1px dashed var(--line2)}
.about-line{font-size:14px;line-height:1.9;margin:0}

@media (max-width:820px){
  .app{padding:10px 10px 0;gap:0}
  .side{position:fixed;left:0;top:0;bottom:0;z-index:30;transform:translateX(-105%);transition:.22s;width:270px;border-radius:0;box-shadow:0 0 40px rgba(20,60,110,.18)}
  .side.open{transform:none}
  .burger{display:block}
  .msg{max-width:92%}
  .stream{padding:14px 12px 6px}
  .admin{padding:14px 12px 0}
}

/* ---------- 站内推荐位 ---------- */
.qdfy-ad{display:flex;flex-direction:column;gap:1px;margin:10px 0 0;padding:10px 12px;border-radius:12px;
  background:linear-gradient(150deg,#fff8ec,#fffdf8);border:1px solid #ffe8c8;text-decoration:none;transition:.15s}
.qdfy-ad:hover{text-decoration:none;border-color:#f5c883;transform:translateY(-1px)}
.qdfy-ad-t{font-size:11.5px;color:#9a6a1e;font-weight:600;letter-spacing:.3px}
.qdfy-ad-h{font-size:14px;color:#d9822b;font-weight:700}
.qdfy-ad-s{font-size:11.5px;color:#a98a5e}
.qdfy-ad-line{margin-top:9px;font-size:12.5px;color:#7a6a4f;background:#fffaf0;border:1px solid #ffe8c8;
  border-radius:9px;padding:8px 11px;line-height:1.75}
.qdfy-ad-line a{color:#c9741f;font-weight:600}

/* ---------- 后台表单栅格 ---------- */
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.sel{width:100%;padding:10px 12px;border:1px solid var(--line);border-radius:10px;
  font:inherit;font-size:14px;background:#fbfdff;color:var(--ink)}
.sel:focus{outline:none;border-color:var(--blue2);box-shadow:0 0 0 3px rgba(107,178,248,.16)}
.tbl .g{color:var(--ok)}
.tbl .r{color:#9db2c6}
@media (max-width:560px){.grid2{grid-template-columns:1fr}}

/* 节点部署命令与日志 */
.node-detail td{background:#fbfdff}
.node-detail summary{cursor:pointer;font-size:12.5px;color:var(--blue);outline:none}
.node-detail pre.cmd{margin:0;padding:10px 12px;background:#0f2033;color:#c9e6ff;border-radius:9px;
  font-size:12.5px;line-height:1.6;overflow-x:auto;white-space:pre-wrap;word-break:break-all}
.node-detail pre.log{margin:0;padding:10px 12px;background:#f6f9fc;border:1px solid var(--line2);
  border-radius:9px;font-size:12px;line-height:1.65;max-height:280px;overflow:auto;color:#3d556b;white-space:pre-wrap}
