/* ============================================================
   UI 组件库
   ============================================================ */

/* ---------- 卡片 ---------- */
.card{
  background:var(--bg-card);border-radius:var(--radius);
  box-shadow:var(--sh-card);margin-bottom:16px;
}
.card-hd{
  display:flex;align-items:center;gap:10px;
  padding:15px 18px;border-bottom:1px solid var(--bd-2);
}
.card-hd.bd0{border-bottom:none;padding-bottom:6px}
.card-hd h3{font-size:14.5px;font-weight:600;color:var(--t-1)}
.card-hd .sub{font-size:12px;color:var(--t-3)}
.card-hd .r{margin-left:auto;display:flex;align-items:center;gap:8px}
.card-bd{padding:18px}
.card-bd.p0{padding:0}
.card-bd.pt0{padding-top:0}
.card-ft{padding:14px 18px;border-top:1px solid var(--bd-2);display:flex;align-items:center;gap:10px}

/* 小标题 */
.blk-title{display:flex;align-items:center;gap:8px;margin-bottom:12px}
.blk-title .bar{width:3px;height:14px;background:var(--c-primary);border-radius:2px}
.blk-title h4{font-size:13.5px;font-weight:600;color:var(--t-1)}

/* ---------- 按钮 ---------- */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:6px;
  height:32px;padding:0 15px;border-radius:var(--radius-sm);
  border:1px solid var(--bd-1);background:#fff;color:var(--t-2);
  font-size:13px;cursor:pointer;white-space:nowrap;transition:.15s;
  user-select:none;
}
.btn:hover{border-color:#b9c4de;color:var(--c-primary);background:#fbfcff}
.btn svg{width:14px;height:14px;stroke:currentColor;fill:none;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.btn-primary{background:var(--c-primary);border-color:var(--c-primary);color:#fff}
.btn-primary:hover{background:var(--c-primary-hover);border-color:var(--c-primary-hover);color:#fff}
.btn-warn{background:var(--c-warning);border-color:var(--c-warning);color:#fff}
.btn-warn:hover{background:#e06d00;border-color:#e06d00;color:#fff}
.btn-danger{background:#fff;border-color:#f5b7b7;color:var(--c-danger)}
.btn-danger:hover{background:var(--c-danger-bg);border-color:var(--c-danger)}
.btn-danger-solid{background:var(--c-danger);border-color:var(--c-danger);color:#fff}
.btn-ghost{background:transparent;border-color:transparent;color:var(--c-primary);padding:0 8px}
.btn-ghost:hover{background:var(--c-primary-light)}
.btn-link{background:none;border:none;color:var(--c-primary);padding:0 6px;height:auto;font-size:12.5px;cursor:pointer}
.btn-link:hover{color:var(--c-primary-hover);text-decoration:underline}
.btn-link.dgr{color:var(--c-danger)}
.btn-sm{height:27px;padding:0 11px;font-size:12.5px}
.btn-lg{height:38px;padding:0 20px;font-size:14px}
.btn-block{width:100%}
.btn[disabled]{opacity:.5;cursor:not-allowed;pointer-events:none}
.btn-group{display:inline-flex}
.btn-group .btn{border-radius:0;margin-left:-1px}
.btn-group .btn:first-child{border-radius:var(--radius-sm) 0 0 var(--radius-sm);margin-left:0}
.btn-group .btn:last-child{border-radius:0 var(--radius-sm) var(--radius-sm) 0}
.btn-group .btn.on{background:var(--c-primary);border-color:var(--c-primary);color:#fff;z-index:2;position:relative}

/* ---------- 输入控件 ---------- */
.ipt{
  height:32px;padding:0 11px;border:1px solid var(--bd-1);border-radius:var(--radius-sm);
  background:#fff;font-size:13px;color:var(--t-1);outline:none;transition:.15s;width:100%;
}
.ipt::placeholder{color:var(--t-4)}
.ipt:hover{border-color:#b9c4de}
.ipt:focus{border-color:var(--c-primary);box-shadow:0 0 0 2px rgba(46,107,230,.12)}
.ipt.sm{height:28px;font-size:12.5px}
select.ipt{
  appearance:none;cursor:pointer;padding-right:26px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2386909c' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 9px center;
}
textarea.ipt{height:auto;min-height:76px;padding:8px 11px;line-height:1.6;resize:vertical;font-family:var(--font)}
.ipt-wrap{position:relative;display:flex;align-items:center}
.ipt-wrap .sfx{position:absolute;right:10px;color:var(--t-3);display:flex}
.ipt-wrap .sfx svg{width:14px;height:14px;stroke:currentColor;fill:none;stroke-width:1.8}
.ipt-hint{font-size:11.5px;color:var(--t-3);margin-top:4px;line-height:1.5}

/* 开关 */
.sw{position:relative;width:38px;height:20px;border-radius:10px;background:#d5d8dd;cursor:pointer;transition:.2s;flex:0 0 auto}
.sw::after{content:"";position:absolute;top:2px;left:2px;width:16px;height:16px;border-radius:50%;background:#fff;transition:.2s;box-shadow:0 1px 3px rgba(0,0,0,.18)}
.sw.on{background:var(--c-primary)}
.sw.on::after{transform:translateX(18px)}
.sw.mini{width:32px;height:17px}
.sw.mini::after{width:13px;height:13px}
.sw.mini.on::after{transform:translateX(15px)}

/* 复选 / 单选 */
.cb{width:15px;height:15px;border:1.5px solid #c9cdd4;border-radius:3.5px;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;background:#fff;flex:0 0 auto;transition:.15s}
.cb svg{width:10px;height:10px;stroke:#fff;fill:none;stroke-width:2.6;opacity:0}
.cb.on{background:var(--c-primary);border-color:var(--c-primary)}
.cb.on svg{opacity:1}
.cb.ind{background:var(--c-primary);border-color:var(--c-primary)}
.cb.ind svg{opacity:1}
.rd{width:15px;height:15px;border:1.5px solid #c9cdd4;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;background:#fff;flex:0 0 auto}
.rd.on{border-color:var(--c-primary);border-width:5px}

/* ---------- 筛选栏 ---------- */
.filter{
  display:flex;flex-wrap:wrap;align-items:flex-end;gap:12px;
  padding:16px 18px;border-bottom:1px solid var(--bd-2);
}
.fld{display:flex;flex-direction:column;gap:5px}
.fld > label{font-size:12px;color:var(--t-3)}
.fld .ipt{min-width:150px}
.fld.w-lg .ipt{min-width:220px}
.fld.w-sm .ipt{min-width:112px}
.filter .acts{margin-left:auto;display:flex;gap:8px}

/* ---------- 表格 ---------- */
.tbl-wrap{overflow-x:auto}
table.tbl{width:100%;font-size:13px;min-width:640px}
table.tbl thead th{
  background:var(--bg-head);color:var(--t-2);font-weight:500;font-size:12.5px;
  text-align:left;padding:10px 14px;white-space:nowrap;
  border-bottom:1px solid var(--bd-1);position:sticky;top:0;
}
table.tbl thead th:first-child,table.tbl tbody td:first-child{padding-left:18px}
table.tbl thead th:last-child,table.tbl tbody td:last-child{padding-right:18px}
table.tbl tbody td{padding:12px 14px;border-bottom:1px solid var(--bd-2);color:var(--t-2);vertical-align:middle}
table.tbl tbody tr:hover{background:#fafbfd}
table.tbl tbody tr.sel{background:var(--c-primary-lighter)}
table.tbl .pri{color:var(--t-1);font-weight:500}
table.tbl .sub{display:block;font-size:11.5px;color:var(--t-3);margin-top:2px;font-family:var(--font-mono)}
table.tbl td.ops{white-space:nowrap}
table.tbl td.ops .btn-link + .btn-link{border-left:1px solid var(--bd-1);margin-left:2px;padding-left:8px}
table.tbl.num td,table.tbl th.num{text-align:right}
.tbl-empty{padding:56px 0;text-align:center;color:var(--t-3)}
.tbl-empty svg{width:44px;height:44px;stroke:var(--t-4);fill:none;stroke-width:1.3;margin:0 auto 10px;display:block}

/* 分页 */
.pager{display:flex;align-items:center;justify-content:flex-end;gap:10px;padding:14px 18px;font-size:12.5px;color:var(--t-2)}
.pager .total{margin-right:auto;color:var(--t-3)}
.pg-btn{min-width:28px;height:28px;padding:0 7px;border:1px solid var(--bd-1);background:#fff;border-radius:var(--radius-sm);display:inline-flex;align-items:center;justify-content:center;cursor:pointer;color:var(--t-2);font-size:12.5px}
.pg-btn:hover{border-color:var(--c-primary);color:var(--c-primary)}
.pg-btn.on{background:var(--c-primary);border-color:var(--c-primary);color:#fff}
.pg-dots{color:var(--t-3);padding:0 2px}

/* ---------- 标签 ---------- */
.tag{
  display:inline-flex;align-items:center;gap:4px;
  height:21px;padding:0 8px;border-radius:4px;font-size:11.5px;font-weight:500;
  background:var(--c-info-bg);color:var(--t-2);white-space:nowrap;line-height:1;
}
.tag .dot{width:5px;height:5px;border-radius:50%;background:currentColor;flex:0 0 auto}
.tag.ok{background:var(--c-success-bg);color:#0a9f3a}
.tag.warn{background:var(--c-warning-bg);color:#d67600}
.tag.err{background:var(--c-danger-bg);color:#d93a3a}
.tag.info{background:var(--c-primary-light);color:var(--c-primary)}
.tag.gray{background:#f2f3f5;color:#6b7280}
.tag.purple{background:var(--c-purple-bg);color:#6b46e5}
.tag.cyan{background:var(--c-cyan-bg);color:#0a9c99}
.tag.plain{background:#fff;border:1px solid var(--bd-1);color:var(--t-2)}
.tag.lg{height:24px;font-size:12px;padding:0 10px}

/* ---------- 统计卡 ---------- */
.stats{display:grid;grid-template-columns:repeat(4,1fr);gap:14px}
.stats.c3{grid-template-columns:repeat(3,1fr)}
.stats.c2{grid-template-columns:repeat(2,1fr)}
.stats.c5{grid-template-columns:repeat(5,1fr)}
.stat{
  background:#fff;border-radius:var(--radius);box-shadow:var(--sh-card);
  padding:16px 18px 14px;position:relative;overflow:hidden;
}
.stat .lb{display:flex;align-items:center;gap:5px;font-size:12.5px;color:var(--t-3);margin-bottom:8px}
.stat .lb .q{width:13px;height:13px;border-radius:50%;border:1px solid var(--t-4);color:var(--t-4);font-size:9px;display:inline-flex;align-items:center;justify-content:center;cursor:help}
.stat .vl{font-size:26px;font-weight:700;color:var(--t-1);line-height:1.15;letter-spacing:-.5px;font-family:"Segoe UI",var(--font)}
.stat .vl .u{font-size:14px;font-weight:500;color:var(--t-3);margin-left:2px;letter-spacing:0}
.stat .spark{margin-top:8px;height:32px}
.stat .cmp{display:flex;gap:16px;font-size:12px;color:var(--t-3);margin-top:6px;padding-top:9px;border-top:1px dashed var(--bd-2)}
.stat .cmp b{font-weight:600}
.stat .cico{
  position:absolute;right:16px;top:50%;transform:translateY(-50%);
  width:38px;height:38px;border-radius:9px;display:flex;align-items:center;justify-content:center;
}
.stat .cico svg{width:19px;height:19px;stroke:currentColor;fill:none;stroke-width:1.7}

/* ---------- 进度条 ---------- */
.bar{height:6px;border-radius:3px;background:#eef0f4;overflow:hidden}
.bar > i{display:block;height:100%;border-radius:3px;background:var(--c-primary);transition:width .4s}
.bar.ok > i{background:var(--c-success)}
.bar.warn > i{background:var(--c-warning)}
.bar.err > i{background:var(--c-danger)}
.bar.purple > i{background:var(--c-purple)}
.bar.lg{height:9px;border-radius:5px}
.bar-row{display:flex;align-items:center;gap:12px}
.bar-row .nm{width:118px;flex:0 0 auto;font-size:12.5px;color:var(--t-2)}
.bar-row .bar{flex:1}
.bar-row .pc{width:48px;text-align:right;font-size:12.5px;color:var(--t-1);font-weight:600;font-family:var(--font-mono)}

/* ---------- 描述列表 ---------- */
.desc{display:grid;grid-template-columns:repeat(3,1fr);border:1px solid var(--bd-1);border-radius:var(--radius-sm);overflow:hidden}
.desc.c2{grid-template-columns:repeat(2,1fr)}
.desc.c4{grid-template-columns:repeat(4,1fr)}
.desc .it{display:flex;flex-wrap:wrap;border-right:1px solid var(--bd-1);border-bottom:1px solid var(--bd-1);min-height:44px;font-size:13px}
.desc .it .k{
  flex:0 1 148px;min-width:88px;padding:11px 14px;background:var(--bg-head);
  color:var(--t-3);font-size:12.5px;display:flex;align-items:center;
}
.desc .it .v{flex:1 1 140px;padding:11px 14px;color:var(--t-1);display:flex;align-items:center;gap:6px;word-break:break-all;min-width:0}
.desc .it .v .mono{color:var(--t-2)}
.desc.c4 .it .k{flex-basis:104px}

/* ---------- 表单 ---------- */
.form{display:grid;gap:16px}
.form.c2{grid-template-columns:repeat(2,1fr)}
.form.c3{grid-template-columns:repeat(3,1fr)}
.fi{display:flex;flex-direction:column;gap:6px}
.fi.full{grid-column:1/-1}
.fi > label{font-size:12.5px;color:var(--t-2);display:flex;align-items:center;gap:5px}
.fi > label .req{color:var(--c-danger)}
.fi .help{font-size:11.5px;color:var(--t-3);line-height:1.5}
.sec-div{grid-column:1/-1;display:flex;align-items:center;gap:9px;margin-top:4px;padding-bottom:8px;border-bottom:1px solid var(--bd-2)}
.sec-div .bar{width:3px;height:13px;background:var(--c-primary);border-radius:2px}
.sec-div h4{font-size:13px;font-weight:600;color:var(--t-1)}
.sec-div .hint{font-size:11.5px;color:var(--t-3)}

/* 行内多选片 */
.chips{display:flex;flex-wrap:wrap;gap:8px}
.chip{
  display:inline-flex;align-items:center;gap:6px;height:28px;padding:0 11px;
  border:1px solid var(--bd-1);border-radius:14px;font-size:12.5px;color:var(--t-2);
  cursor:pointer;background:#fff;transition:.15s;
}
.chip:hover{border-color:#b9c4de}
.chip.on{background:var(--c-primary-light);border-color:var(--c-primary);color:var(--c-primary);font-weight:500}
.chip .cb{border:none;background:transparent;width:auto;height:auto}

/* ---------- 抽屉 & 弹窗 ---------- */
.mask{position:fixed;inset:0;background:rgba(0,0,0,.42);z-index:900;opacity:0;visibility:hidden;transition:.22s}
.mask.on{opacity:1;visibility:visible}

.drawer{
  position:fixed;top:0;right:0;bottom:0;width:620px;max-width:94vw;background:#fff;
  z-index:910;box-shadow:-6px 0 30px rgba(0,0,0,.13);
  transform:translateX(100%);transition:transform .26s cubic-bezier(.4,0,.2,1);
  display:flex;flex-direction:column;
}
.drawer.on{transform:none}
.drawer.wide{width:880px}
.drawer-hd{
  flex:0 0 auto;padding:16px 22px;border-bottom:1px solid var(--bd-2);
  display:flex;align-items:center;gap:10px;
}
.drawer-hd h3{font-size:15px;font-weight:600}
.drawer-hd .close{margin-left:auto;width:28px;height:28px;border-radius:6px;display:flex;align-items:center;justify-content:center;cursor:pointer;color:var(--t-3)}
.drawer-hd .close:hover{background:var(--bg-hover);color:var(--t-1)}
.drawer-hd .close svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2}
.drawer-bd{flex:1;overflow-y:auto;padding:20px 22px}
.drawer-ft{flex:0 0 auto;padding:14px 22px;border-top:1px solid var(--bd-2);display:flex;justify-content:flex-end;gap:10px;background:#fcfcfd}

.modal{
  position:fixed;left:50%;top:50%;transform:translate(-50%,-46%) scale(.97);
  width:560px;max-width:94vw;max-height:86vh;background:#fff;border-radius:var(--radius-lg);
  z-index:910;box-shadow:var(--sh-pop);opacity:0;visibility:hidden;transition:.22s;
  display:flex;flex-direction:column;
}
.modal.on{opacity:1;visibility:visible;transform:translate(-50%,-50%) scale(1)}
.modal.wide{width:760px}
.modal-hd{padding:17px 22px 12px;display:flex;align-items:center}
.modal-hd h3{font-size:15.5px;font-weight:600}
.modal-hd .close{margin-left:auto;width:26px;height:26px;border-radius:6px;display:flex;align-items:center;justify-content:center;cursor:pointer;color:var(--t-3)}
.modal-hd .close:hover{background:var(--bg-hover)}
.modal-hd .close svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:2}
.modal-bd{padding:4px 22px 20px;overflow-y:auto}
.modal-ft{padding:0 22px 20px;display:flex;justify-content:flex-end;gap:10px}
.modal-ft.top{border-top:1px solid var(--bd-2);padding-top:16px}

/* 二次确认 */
.confirm{width:420px;text-align:left}
.confirm .modal-bd{display:flex;gap:12px;padding-top:8px}
.confirm .ico{width:22px;height:22px;flex:0 0 auto;color:var(--c-warning)}
.confirm .ico svg{width:22px;height:22px;stroke:currentColor;fill:none;stroke-width:1.8}
.confirm h4{font-size:14.5px;margin-bottom:6px}
.confirm p{font-size:12.5px;color:var(--t-3);line-height:1.6}

/* ---------- 步骤条 ---------- */
.steps{display:flex;align-items:flex-start}
.step{flex:1;display:flex;flex-direction:column;align-items:center;position:relative;text-align:center}
.step .cir{
  width:26px;height:26px;border-radius:50%;border:1.5px solid var(--bd-1);background:#fff;
  display:flex;align-items:center;justify-content:center;font-size:12.5px;font-weight:600;
  color:var(--t-3);z-index:2;transition:.2s;
}
.step .cir svg{width:13px;height:13px;stroke:currentColor;fill:none;stroke-width:2.6}
.step .nm{font-size:12.5px;color:var(--t-3);margin-top:7px}
.step .tm{font-size:11px;color:var(--t-4);margin-top:2px;font-family:var(--font-mono)}
.step::before{content:"";position:absolute;top:13px;left:-50%;width:100%;height:1.5px;background:var(--bd-1)}
.step:first-child::before{display:none}
.step.done::before{background:var(--c-primary)}
.step.done .cir{background:var(--c-primary);border-color:var(--c-primary);color:#fff}
.step.done .nm{color:var(--t-1)}
.step.cur .cir{border-color:var(--c-primary);color:var(--c-primary);box-shadow:0 0 0 3px rgba(46,107,230,.13)}
.step.cur .nm{color:var(--c-primary);font-weight:600}
.step.err .cir{border-color:var(--c-danger);color:var(--c-danger);background:var(--c-danger-bg)}
.step.err .nm{color:var(--c-danger)}

/* ---------- 树 ---------- */
.tree{font-size:13px}
.tree .nd{display:flex;align-items:center;gap:7px;padding:6px 8px;border-radius:5px;cursor:pointer}
.tree .nd:hover{background:var(--bg-hover)}
.tree .nd .tw{width:14px;height:14px;display:flex;align-items:center;justify-content:center;color:var(--t-3);transition:transform .18s}
.tree .nd .tw svg{width:10px;height:10px;stroke:currentColor;fill:none;stroke-width:2.4}
.tree .nd.open .tw{transform:rotate(90deg)}
.tree .nd .nm{color:var(--t-1)}
.tree .nd .tag{margin-left:auto;font-size:11px}
.tree .kid{padding-left:22px}
.tree .leaf{display:flex;align-items:center;gap:7px;padding:5px 8px;border-radius:5px;font-size:12.5px}
.tree .leaf:hover{background:var(--bg-hover)}
.tree .col{display:flex;align-items:center;gap:6px;color:var(--t-2);cursor:pointer}

/* ---------- 时间线 ---------- */
.tl{position:relative;padding-left:20px}
.tl::before{content:"";position:absolute;left:5px;top:6px;bottom:6px;width:1.5px;background:var(--bd-1)}
.tl-item{position:relative;padding-bottom:18px}
.tl-item:last-child{padding-bottom:0}
.tl-item::before{
  content:"";position:absolute;left:-18px;top:4px;width:9px;height:9px;border-radius:50%;
  background:#fff;border:2px solid var(--bd-1);
}
.tl-item.on::before{border-color:var(--c-primary);background:var(--c-primary)}
.tl-item.err::before{border-color:var(--c-danger);background:var(--c-danger)}
.tl-item .hd{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--t-1);font-weight:500}
.tl-item .tm{font-size:11.5px;color:var(--t-4);font-family:var(--font-mono);margin-left:auto}
.tl-item .ds{font-size:12.5px;color:var(--t-3);margin-top:3px;line-height:1.6}

/* ---------- 提示条 ---------- */
.alert{
  display:flex;gap:10px;padding:11px 14px;border-radius:var(--radius-sm);
  font-size:12.5px;line-height:1.6;margin-bottom:14px;
  background:var(--c-primary-light);color:#1b4fbd;
}
.alert.warn{background:var(--c-warning-bg);color:#a35a00}
.alert.err{background:var(--c-danger-bg);color:#b32f2f}
.alert.ok{background:var(--c-success-bg);color:#0a8a33}
.alert svg{width:15px;height:15px;flex:0 0 auto;stroke:currentColor;fill:none;stroke-width:1.8;margin-top:1.5px}
.alert b{font-weight:600}

/* ---------- 图表 ---------- */
.chart-box{position:relative;width:100%}
.legend{display:flex;flex-wrap:wrap;gap:14px;font-size:12px;color:var(--t-3);margin-top:10px}
.legend .lg-i{display:flex;align-items:center;gap:6px}
.legend .sw-c{width:9px;height:9px;border-radius:2px;flex:0 0 auto}
.legend .sw-l{width:14px;height:2.5px;border-radius:2px;flex:0 0 auto}

/* 柱状 */
.bars{display:flex;align-items:flex-end;gap:10px;height:180px}
.bars .b{flex:1;display:flex;flex-direction:column;justify-content:flex-end;align-items:center;gap:5px;height:100%}
.bars .b .v{font-size:11px;color:var(--t-2);font-family:var(--font-mono)}
.bars .b .col{width:100%;max-width:38px;border-radius:5px 5px 0 0;background:linear-gradient(180deg,#5b90f5,#2e6be6);transition:height .5s}
.bars .b .col.g{background:linear-gradient(180deg,#3fd06a,#00b42a)}
.bars .b .col.o{background:linear-gradient(180deg,#ffab4d,#ff7d00)}
.bars .b .col.p{background:linear-gradient(180deg,#a78bfa,#7d5cff)}
.bars .b .lb{font-size:11.5px;color:var(--t-3);height:16px}

/* 横向排行 */
.rank{display:flex;flex-direction:column;gap:13px}
.rank .r{display:flex;align-items:center;gap:11px;font-size:12.5px}
.rank .r .no{
  width:19px;height:19px;border-radius:5px;flex:0 0 auto;display:flex;align-items:center;justify-content:center;
  font-size:11px;font-weight:700;background:#f2f3f5;color:var(--t-3);
}
.rank .r:nth-child(1) .no{background:#fff1e0;color:#dd6b00}
.rank .r:nth-child(2) .no{background:#eef1f6;color:#64748b}
.rank .r:nth-child(3) .no{background:#fdf0e3;color:#b0742a}
.rank .r .nm{width:132px;flex:0 0 auto;color:var(--t-1);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rank .r .bar{flex:1}
.rank .r .vl{width:66px;text-align:right;color:var(--t-1);font-weight:600;font-family:var(--font-mono)}

/* 环形进度 */
.ring{position:relative;width:110px;height:110px}
.ring svg{transform:rotate(-90deg)}
.ring .ct{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center}
.ring .ct b{font-size:20px;font-weight:700;color:var(--t-1);font-family:"Segoe UI",var(--font)}
.ring .ct span{font-size:11.5px;color:var(--t-3)}

/* 能量流动图 */
.flow{width:100%;height:auto}

/* 空状态 */
.empty{padding:52px 20px;text-align:center;color:var(--t-3)}
.empty svg{width:60px;height:60px;stroke:var(--t-4);fill:none;stroke-width:1.2;margin:0 auto 12px;display:block}
.empty h4{font-size:14px;color:var(--t-2);margin-bottom:5px}
.empty p{font-size:12.5px;color:var(--t-3)}

/* ---------- 分区头（大标题） ---------- */
.sec-hd{display:flex;align-items:center;gap:10px;margin:22px 0 14px}
.sec-hd:first-child{margin-top:0}
.sec-hd h2{font-size:15px;font-weight:600;color:var(--t-1)}
.sec-hd .line{flex:1;height:1px;background:var(--bd-1)}
.sec-hd .r{margin-left:auto}

/* ---------- 信息条 ---------- */
.kv-inline{display:flex;flex-wrap:wrap;gap:26px;font-size:12.5px;color:var(--t-3)}
.kv-inline b{color:var(--t-1);font-weight:600;font-family:var(--font-mono)}

/* 图例小方块 */
.lg-dot{width:7px;height:7px;border-radius:50%;display:inline-block}

/* 代码块 */
.code{
  background:#1f2430;color:#c7d0dd;border-radius:var(--radius-sm);padding:13px 15px;
  font-family:var(--font-mono);font-size:12px;line-height:1.75;overflow-x:auto;white-space:pre;
}
.code .k{color:#7aa2f7}.code .s{color:#9ece6a}.code .c{color:#5c6370}.code .n{color:#e0af68}

/* 响应式 */
@media (max-width:1400px){
  .stats.c5{grid-template-columns:repeat(3,1fr)}
}
@media (max-width:1200px){
  .stats,.stats.c5{grid-template-columns:repeat(2,1fr)}
  .desc.c4{grid-template-columns:repeat(2,1fr)}
}

.grid2{display:grid;grid-template-columns:1fr 1fr;gap:16px}

/* ============================================================
   Toast 轻提示
   ============================================================ */
.toast-wrap{
  position:fixed;left:50%;top:20px;transform:translateX(-50%);
  z-index:2000;display:flex;flex-direction:column;gap:8px;align-items:center;pointer-events:none;
}
.toast{
  display:flex;align-items:center;gap:9px;padding:10px 17px;border-radius:9px;
  background:#fff;border:1px solid var(--bd-1);box-shadow:0 8px 28px rgba(16,24,40,.13);
  font-size:13px;color:var(--t-1);white-space:nowrap;animation:toastIn .22s ease;
}
.toast.out{animation:toastOut .2s ease forwards}
.toast svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:1.9;flex:0 0 auto}
.toast.ok{color:#0a8a33;border-color:#b7ebc6}
.toast.warn{color:#a35a00;border-color:#ffd8a8}
.toast.err{color:#b32f2f;border-color:#f7c0c0}
.toast.info{color:var(--c-primary);border-color:#c3d6fb}
@keyframes toastIn{from{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:none}}
@keyframes toastOut{to{opacity:0;transform:translateY(-8px)}}

/* 只读字段值 */
.rov{
  display:flex;align-items:center;height:34px;padding:0 11px;
  border:1px solid var(--bd-2);background:#fafbfc;border-radius:var(--radius-sm);
  font-size:13px;color:var(--t-2);overflow:hidden;white-space:nowrap;text-overflow:ellipsis;
}
.rov.em{color:var(--t-4)}
.form.c2 .fi.full,.form.c3 .fi.full{grid-column:1/-1}
textarea.ipt{height:auto;padding:8px 11px;line-height:1.6;resize:vertical;font-family:inherit}

/* ============================================================
   AI 悬浮助手
   ============================================================ */
.ai-fab{
  position:fixed;right:26px;bottom:26px;height:56px;padding:0 20px 0 5px;
  border-radius:999px;z-index:940;cursor:pointer;user-select:none;
  display:flex;align-items:center;gap:10px;
  background:linear-gradient(135deg,#16223a,#1e3556 58%,#151f33);
  box-shadow:0 10px 26px rgba(16,24,40,.30),inset 0 0 0 1px rgba(255,255,255,.07);
  transition:transform .2s,opacity .2s,box-shadow .2s;
}
.ai-fab:hover{
  transform:translateY(-3px);
  box-shadow:0 16px 34px rgba(16,24,40,.36),inset 0 0 0 1px rgba(16,185,129,.42);
}
.ai-fab-ic{
  position:relative;width:46px;height:46px;border-radius:50%;flex:0 0 auto;
  background:radial-gradient(circle at 34% 26%,#375c8c,#1b2c48 76%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.16),0 2px 8px rgba(0,0,0,.28);
  display:flex;align-items:center;justify-content:center;
}
.ai-fab-ic img{width:28px;height:28px;object-fit:contain;display:block}
.ai-fab .dot{
  position:absolute;right:0;top:0;width:11px;height:11px;border-radius:50%;
  background:var(--c-brand);box-shadow:0 0 0 2.5px #16223a;
}
.ai-fab-tx{font-size:13.5px;font-weight:600;color:#fff;letter-spacing:.4px;white-space:nowrap}
.ai-fab.on{transform:scale(.4);opacity:0;pointer-events:none}
/* 弹窗 / 抽屉打开时让出焦点，避免遮挡底部按钮 */
body.is-modal .ai-fab,
body.is-modal .ai-panel{opacity:0;visibility:hidden;pointer-events:none}

.ai-panel{
  position:fixed;right:26px;bottom:26px;width:392px;
  height:min(672px,calc(100vh - 52px));
  background:#fff;border-radius:16px;z-index:950;overflow:hidden;
  display:flex;flex-direction:column;
  box-shadow:0 22px 64px rgba(16,24,40,.24),0 0 0 1px rgba(16,24,40,.05);
  opacity:0;visibility:hidden;transform:translateY(16px) scale(.97);
  transform-origin:bottom right;transition:.22s cubic-bezier(.4,0,.2,1);
}
.ai-panel.on{opacity:1;visibility:visible;transform:none}
.ai-panel.wide{width:568px}
.ai-panel.max{width:min(920px,calc(100vw - 52px));height:calc(100vh - 52px)}

.ai-hd{
  flex:0 0 auto;display:flex;align-items:center;gap:9px;
  padding:13px 14px;border-bottom:1px solid var(--bd-2);background:#fff;
}
.ai-hd .ava{
  width:28px;height:28px;border-radius:50%;
  background:radial-gradient(circle at 32% 26%,#2a4a74,#16223a 74%);
  display:flex;align-items:center;justify-content:center;flex:0 0 auto;
}
.ai-hd .ava img{width:18px;height:18px;object-fit:contain;display:block}
.ai-hd .tt{font-size:14px;font-weight:600;color:var(--t-1);white-space:nowrap}
.ai-beta{
  font-size:10.5px;font-weight:600;color:#fff;background:linear-gradient(135deg,#ff9f43,#ff7d00);
  border-radius:6px;padding:2px 6px;margin-left:2px;letter-spacing:.2px;
}
.ai-hacts{margin-left:auto;display:flex;align-items:center;gap:2px}
.ai-hbtn{
  width:28px;height:28px;border-radius:7px;display:flex;align-items:center;justify-content:center;
  color:var(--t-3);cursor:pointer;transition:.15s;
}
.ai-hbtn:hover{background:var(--bg-hover);color:var(--t-1)}
.ai-hbtn svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:1.8}

.ai-body{flex:1;overflow-y:auto;padding:16px 16px 8px;background:#fbfbfd}
.ai-body::-webkit-scrollbar{width:6px}
.ai-body::-webkit-scrollbar-thumb{background:#e3e5ea;border-radius:3px}

.ai-wel{padding:4px 2px 0}
.ai-wel .big{
  width:54px;height:54px;border-radius:50%;
  background:radial-gradient(circle at 32% 26%,#2a4a74,#16223a 74%);
  display:flex;align-items:center;justify-content:center;margin-bottom:16px;
  box-shadow:0 8px 20px rgba(22,34,58,.26);
}
.ai-wel .big img{width:32px;height:32px;object-fit:contain;display:block}
.ai-wel h3{font-size:19px;font-weight:700;color:var(--t-1);margin:0 0 10px;line-height:1.35}
.ai-wel h3 span{color:#0e9f6e}
.ai-wel p{font-size:13px;color:var(--t-2);line-height:1.75;margin:0 0 18px}
.ai-guess{font-size:12.5px;color:var(--t-3);margin-bottom:9px}
.ai-qs{background:#eef3fe;border-radius:12px;padding:13px 15px;display:flex;flex-direction:column;gap:11px}
.ai-q{font-size:13px;color:#2f6ae0;cursor:pointer;line-height:1.5;transition:.15s}
.ai-q:hover{color:#1e47a8;text-decoration:underline}

.ai-msgs{padding-top:6px}
.ai-msg{display:flex;gap:9px;margin-bottom:14px;align-items:flex-start}
.ai-msg .ava{
  width:26px;height:26px;border-radius:50%;flex:0 0 auto;
  background:radial-gradient(circle at 32% 26%,#2a4a74,#16223a 74%);
  display:flex;align-items:center;justify-content:center;
}
.ai-msg .ava img{width:17px;height:17px;object-fit:contain;display:block}
.ai-msg .bub{
  max-width:82%;padding:10px 13px;border-radius:12px;font-size:13px;line-height:1.72;
  background:#fff;color:var(--t-1);border:1px solid var(--bd-1);
  border-top-left-radius:4px;white-space:pre-wrap;word-break:break-word;
}
.ai-msg.me{flex-direction:row-reverse}
.ai-msg.me .bub{
  background:var(--c-primary);color:#fff;border-color:var(--c-primary);
  border-top-left-radius:12px;border-top-right-radius:4px;
}
.ai-msg.me .ava{background:#dbe4f5}
.ai-msg.me .ava img{display:none}
.ai-msg.me .ava::after{content:"陈";font-size:12px;font-weight:600;color:#2e6be6}
.ai-typing{display:flex;gap:4px;padding:5px 2px}
.ai-typing i{width:6px;height:6px;border-radius:50%;background:#c3c9d4;animation:aiBlink 1.2s infinite}
.ai-typing i:nth-child(2){animation-delay:.18s}
.ai-typing i:nth-child(3){animation-delay:.36s}
@keyframes aiBlink{0%,60%,100%{opacity:.35;transform:translateY(0)}30%{opacity:1;transform:translateY(-3px)}}

.ai-ft{flex:0 0 auto;padding:10px 14px 13px;background:#fff;border-top:1px solid var(--bd-2)}
.ai-tools{display:flex;align-items:center;gap:4px;margin-bottom:9px}
.ai-tool{
  width:30px;height:30px;border-radius:8px;display:flex;align-items:center;justify-content:center;
  color:var(--t-2);cursor:pointer;transition:.15s;
}
.ai-tool:hover{background:var(--bg-hover);color:var(--c-primary)}
.ai-tool svg{width:17px;height:17px;stroke:currentColor;fill:none;stroke-width:1.8}
.ai-input{
  position:relative;border:1px solid var(--bd-1);border-radius:12px;background:#fff;
  transition:.15s;padding:9px 44px 9px 12px;
}
.ai-input:focus-within{border-color:var(--c-primary);box-shadow:0 0 0 3px rgba(46,107,230,.10)}
.ai-input textarea{
  width:100%;border:none;outline:none;resize:none;font-family:inherit;
  font-size:13px;line-height:1.6;color:var(--t-1);height:46px;background:transparent;
}
.ai-input textarea::placeholder{color:var(--t-4)}
.ai-send{
  position:absolute;right:8px;bottom:8px;width:30px;height:30px;border-radius:50%;
  background:var(--c-primary);color:#fff;display:flex;align-items:center;justify-content:center;
  cursor:pointer;transition:.15s;
}
.ai-send:hover{background:var(--c-primary-hover)}
.ai-send svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:2}
.ai-send.off{background:#dfe2e8;cursor:not-allowed}

@media (max-width:720px){
  .ai-panel{right:12px;left:12px;width:auto;bottom:12px;height:min(600px,calc(100vh - 24px))}
  .ai-panel.wide,.ai-panel.max{width:auto}
  .ai-fab{right:16px;bottom:16px;padding:0 5px}
  .ai-fab-tx{display:none}
}

/* ---------- 富文本编辑器（知识库正文） ---------- */
.rt{border:1px solid var(--bd-1);border-radius:var(--radius-sm);overflow:hidden;background:#fff}
.rt-bar{display:flex;align-items:center;gap:2px;flex-wrap:wrap;padding:6px 8px;border-bottom:1px solid var(--bd-1);background:#fafbfd}
.rt-b{min-width:28px;height:26px;padding:0 8px;border:1px solid transparent;border-radius:5px;background:none;color:var(--t-2);font-size:12.5px;font-weight:600;cursor:pointer;font-family:inherit}
.rt-b:hover{background:var(--c-primary-light);color:var(--c-primary)}
.rt-sep{width:1px;height:16px;background:var(--bd-1);margin:0 4px}
.rt-area{min-height:150px;max-height:320px;overflow:auto;padding:10px 12px;font-size:12.5px;line-height:1.7;color:var(--t-1);outline:none}
.rt-area:empty:before{content:attr(data-ph);color:var(--t-3)}
.rt-area h3{font-size:14px;margin:8px 0 4px}
.rt-area ul,.rt-area ol{margin:6px 0;padding-left:20px}

/* ---------- 附件上传 ---------- */
.up{border:1px dashed #c6cfe2;border-radius:var(--radius-sm);background:#fafbfd;padding:18px 12px;text-align:center;cursor:pointer;transition:.15s}
.up:hover,.up.over{border-color:var(--c-primary);background:var(--c-primary-light)}
.up-ic{display:flex;justify-content:center;color:var(--c-primary);margin-bottom:6px}
.up-ic svg{width:22px;height:22px}
.up-tx{font-size:12.5px;color:var(--t-2)}
.up-sub{font-size:11.5px;color:var(--t-3);margin-top:3px}
.up-list{margin-top:8px;display:flex;flex-direction:column;gap:6px}
.up-item{display:flex;align-items:center;gap:8px;padding:7px 10px;border:1px solid var(--bd-1);border-radius:6px;background:#fff;font-size:12.5px;color:var(--t-2)}
.up-item > svg{width:14px;height:14px;color:var(--t-3);flex:0 0 auto}
.up-item span{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.up-del{display:flex;color:var(--t-3);cursor:pointer;font-weight:400}
.up-del svg{width:13px;height:13px}
.up-del:hover{color:var(--c-danger)}

/* ---------- AI 对话记录：气泡 + 逐条回答评价 ---------- */
.chat{display:flex;flex-direction:column;gap:16px}
.chat-row{display:flex;gap:10px;align-items:flex-start}
.chat-row.me{flex-direction:row-reverse}
.chat-av{width:28px;height:28px;border-radius:50%;flex:0 0 28px;display:flex;align-items:center;justify-content:center}
.chat-av svg{width:15px;height:15px}
.chat-av.me{background:var(--c-primary-light);color:var(--c-primary)}
.chat-av.ai{background:var(--c-brand-bg);color:var(--c-brand-dark)}
.chat-bd{max-width:min(780px,82%);border-radius:var(--radius-lg);padding:11px 13px;font-size:13px;line-height:1.7;color:var(--t-1)}
.chat-row.me .chat-bd{background:var(--c-primary-light);border:1px solid #cfdefb}
.chat-row.ai .chat-bd{background:var(--bg-head);border:1px solid var(--bd-1)}
.chat-txt{white-space:pre-wrap}
.chat-src{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}
.chat-time{font-size:11.5px;color:var(--t-3);margin-top:7px}
.msg-eval{margin-top:10px;padding-top:10px;border-top:1px dashed var(--bd-1)}
.rate{display:flex;flex-wrap:wrap;align-items:center;gap:8px}
.rate .rl{font-size:11.5px;color:var(--t-3)}
.rate .rb,.rate .tb,.rate .rtag{display:inline-flex;align-items:center;gap:4px;height:24px;padding:0 10px;border-radius:12px;font-size:12px;cursor:pointer;transition:.15s;user-select:none;background:#fff;color:var(--t-2);border:1px solid var(--bd-1)}
.rate .rb svg{width:12px;height:12px}
.rate .rb:hover{border-color:var(--c-primary);color:var(--c-primary)}
.rate .rb.on{background:var(--c-success-bg);border-color:var(--c-success);color:#0a8f24;font-weight:600}
.rate .rb.dn.on{background:var(--c-danger-bg);border-color:var(--c-danger);color:var(--c-danger)}
.rate .rtag{border-style:dashed;color:var(--t-3)}
.rate .rtag:hover{border-color:var(--c-primary);color:var(--c-primary)}
.rate .rtag.on{background:var(--c-primary-light);border:1px solid var(--c-primary);color:var(--c-primary);font-weight:600}
.rate .tb:hover{border-color:var(--c-purple);color:var(--c-purple)}
.rate .tb.on{background:var(--c-purple-bg);border-color:var(--c-purple);color:var(--c-purple);font-weight:600}
.stars{display:inline-flex;gap:1px;font-size:15px;line-height:1;color:var(--t-4);cursor:pointer;letter-spacing:1px}
.stars i{font-style:normal;transition:.12s}
.stars i:hover{transform:scale(1.15)}
.stars i.on{color:#ff9500}
.train-pick{display:inline-flex;align-items:center;gap:6px;margin-left:auto}
.rate-out{margin-top:9px;font-size:11.5px;color:var(--t-3);background:#fff;border:1px solid var(--bd-2);border-radius:var(--radius-sm);padding:6px 10px;line-height:1.6}
.rate-out.done{color:var(--t-2);border-color:#d8e3fb;background:var(--c-primary-lighter)}

/* 切片条目：可点击查看详情 */
.slice-item{display:block;width:100%;padding:10px 12px;border:1px solid var(--bd-1);border-radius:6px;background:#fff;cursor:pointer;text-align:left;transition:border-color .15s,box-shadow .15s}
.slice-item:hover{border-color:var(--c-primary);box-shadow:0 1px 6px rgba(46,107,230,.12)}
.slice-item:focus-visible{outline:2px solid var(--c-primary);outline-offset:1px}
.slice-item.warn{border-color:#ffd591;background:#fffbf5}
.slice-item.err{border-color:#f5b7b7;background:#fff8f8}

/* —— 溢出防护（永正 ERP 定制）————————————————————————
   宽表格 table.tbl{min-width:640px} 放进 .grid2 双栏时，
   栅格轨道 1fr 的最小值是 auto(=min-content 640)，会把视口撑出横向滚动条。
   给栅格子项补 min-width:0，让溢出回到 .tbl-wrap 内部横向滚动。
   ———————————————————————————————————————————— */
.grid2>*,.grid3>*,.grid4>*{min-width:0}
.card{min-width:0}
.tbl-wrap{max-width:100%}
