:root{
--g900:#0f2419; --g800:#16402c; --g700:#1e5a3c; --g600:#2b7a51;
--g500:#3d9b68; --g300:#8fc9a8; --g100:#e4f1e9;
--earth:#8a6d3b; --sand:#f7f5ef;
--ink:#1c2521; --ink2:#4d5b53; --ink3:#87958d;
--line:#dfe6e0; --bg:#f2f5f2; --white:#fff;
--ok:#2b7a51; --warn:#c98a1b; --bad:#c0392b;
--sh:0 1px 2px rgba(15,36,25,.06),0 4px 14px rgba(15,36,25,.06);
}
*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{
font:14px/1.55 -apple-system,BlinkMacSystemFont,"PingFang SC","Hiragino Sans GB","Microsoft YaHei",sans-serif;
color:var(--ink); background:var(--bg); -webkit-font-smoothing:antialiased;
}
h1,h2,h3{margin:0;font-weight:600}
button,input,select{font-family:inherit;font-size:13px}
/ ---------- topbar ---------- /
.topbar{
display:flex;align-items:center;justify-content:space-between;gap:16px;
padding:10px 20px;background:linear-gradient(100deg,var(--g800),var(--g600));color:#fff;
}
.brand{display:flex;align-items:center;gap:12px}
.logo{font-size:26px;line-height:1;opacity:.9}
.brand h1{font-size:16px;letter-spacing:.3px}
.brand p{margin:2px 0 0;font-size:11.5px;opacity:.75}
.topbar-actions{display:flex;align-items:center;gap:8px}
.proj-name{
width:200px;padding:6px 10px;border-radius:6px;border:1px solid rgba(255,255,255,.25);
background:rgba(255,255,255,.12);color:#fff;
}
.proj-name::placeholder{color:rgba(255,255,255,.6)}
.topbar-actions select{
padding:6px 8px;border-radius:6px;border:1px solid rgba(255,255,255,.25);
background:rgba(255,255,255,.12);color:#fff;
}
.topbar-actions select option{color:#1c2521}
/ ---------- buttons ---------- /
.btn{
padding:6px 12px;border:1px solid var(--line);border-radius:6px;background:var(--white);
color:var(--ink);cursor:pointer;transition:.15s;white-space:nowrap;
}
.btn:hover{border-color:var(--g500);color:var(--g700)}
.btn.primary{background:var(--g600);border-color:var(--g600);color:#fff}
.btn.primary:hover{background:var(--g700);color:#fff}
.btn.ghost{background:transparent;border-color:rgba(255,255,255,.35);color:#fff}
.tabs .btn.ghost,main .btn.ghost{border-color:var(--line);color:var(--ink2);background:var(--white)}
.btn.danger{color:var(--bad);border-color:#eccfcb}
.btn.danger:hover{background:#fdf1f0;border-color:var(--bad)}
.btn.sm{padding:4px 9px;font-size:12px}
.btn.block{width:100%;margin-top:8px}
.btn.active-mode{background:var(--g100);border-color:var(--g500);color:var(--g700)}
/ ---------- tabs ---------- /
.tabs{display:flex;gap:2px;padding:0 20px;background:var(--g900)}
.tab{
padding:9px 18px;border:0;background:transparent;color:rgba(255,255,255,.6);
cursor:pointer;font-size:13px;border-bottom:2px solid transparent;
}
.tab:hover{color:#fff}
.tab.active{color:#fff;border-bottom-color:var(--g300);background:rgba(255,255,255,.07)}
main{padding:16px 20px 40px}
.panel{display:none}
.panel.active{display:block}
/ ---------- cards ---------- /
.card{
background:var(--white);border:1px solid var(--line);border-radius:10px;
padding:14px 16px;box-shadow:var(--sh);margin-bottom:14px;
}
.card h3{font-size:13.5px;color:var(--g800);margin-bottom:10px;display:flex;align-items:center;gap:8px}
.card h3 .right{margin-left:auto}
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:14px}
@media(max-width:1100px){.grid2{grid-template-columns:1fr}}
.hint{margin:6px 0 0;font-size:11.5px;color:#8b978f;line-height:1.5}
.inline-hint{margin:0;font-weight:400}
.mini{margin-top:8px;font-size:12px;color:var(--ink2)}
.badge{
background:var(--g100);color:var(--g700);border-radius:20px;padding:1px 8px;
font-size:11px;font-weight:600;
}
.row{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-top:8px}
.row label{font-size:12px;color:var(--ink2)}
.inline{display:flex;align-items:center;gap:4px}
.unit{font-size:12px;color:var(--ink2)}
.row input[type=number],.inline input{width:82px;padding:5px 8px;border:1px solid var(--line);border-radius:6px}
.row select{padding:5px 8px;border:1px solid var(--line);border-radius:6px;flex:1;min-width:130px}
.link{color:var(--g600);cursor:pointer;text-decoration:underline}
details.alt{margin-top:10px;border-top:1px dashed var(--line);padding-top:8px}
details.alt summary{font-size:12px;color:var(--g600);cursor:pointer}
.form-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.form-grid label{display:flex;flex-direction:column;gap:4px;font-size:12px;color:var(--ink2)}
.form-grid input,.form-grid select{padding:6px 9px;border:1px solid var(--line);border-radius:6px;width:100%}
.ck{flex-direction:row!important;align-items:center;gap:6px!important}
.ck.sm{font-size:12px;color:var(--ink2);display:flex;align-items:center;gap:5px}
/ ---------- measure ---------- /
.measure-layout{display:grid;grid-template-columns:1fr 320px;gap:14px;align-items:start}
@media(max-width:1000px){.measure-layout{grid-template-columns:1fr}}
.canvas-wrap{
position:relative;background:#e9ece9;border:1px solid var(--line);border-radius:10px;
overflow:hidden;height:calc(100vh - 190px);min-height:460px;box-shadow:var(--sh);
}
board{display:block;width:100%;height:100%;cursor:crosshair}
.canvas-wrap.mode-pan #board{cursor:grab}
.drop-hint{
position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;
gap:4px;color:#7d8a82;background:repeating-linear-gradient(45deg,#eceeec,#eceeec 12px,#e7eae7 12px,#e7eae7 24px);
pointer-events:none;
}
.drop-hint label,.drop-hint .link{pointer-events:auto}
.drop-hint.hide{display:none}
.dh-icon{font-size:38px;color:var(--g300)}
.drop-hint p{margin:2px}
.drop-hint .sub{font-size:12px}
.canvas-wrap.dragover{outline:2px dashed var(--g500);outline-offset:-6px}
.canvas-hud{
position:absolute;left:10px;bottom:10px;display:flex;gap:8px;font-size:11.5px;
}
.canvas-hud span{background:rgba(15,36,25,.78);color:#fff;padding:4px 9px;border-radius:5px}
.measure-side{display:flex;flex-direction:column;max-height:calc(100vh - 190px)}
.measure-side .grow,.card.grow{flex:1;display:flex;flex-direction:column;min-height:0}
.shape-list{flex:1;overflow:auto;min-height:80px;margin:-2px 0 6px}
.shape-item{
display:flex;align-items:center;gap:6px;padding:5px 6px;border-radius:6px;font-size:12px;
border:1px solid transparent;
}
.shape-item:hover{background:#f6f9f7;border-color:var(--line)}
.shape-item.sel{background:var(--g100);border-color:var(--g300)}
.sw{width:10px;height:10px;border-radius:3px;flex:none}
.shape-item .nm{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.shape-item .vl{color:var(--g700);font-weight:600;font-variant-numeric:tabular-nums}
.shape-item .x{cursor:pointer;color:#b9c3bc;padding:0 2px}
.shape-item .x:hover{color:var(--bad)}
.sum-row{display:flex;justify-content:space-between;font-size:12px;padding:4px 6px;border-top:1px solid var(--line)}
.sum-row b{color:var(--g700);font-variant-numeric:tabular-nums}
/ ---------- tables ---------- /
.tbl{width:100%;border-collapse:collapse;font-size:12.5px}
.tbl th,.tbl td{padding:6px 8px;border-bottom:1px solid var(--line);text-align:left}
.tbl thead th{
background:var(--sand);color:var(--g800);font-weight:600;font-size:11.5px;
position:sticky;top:0;z-index:1;white-space:nowrap;
}
.tbl tfoot th{background:var(--g100);color:var(--g800)}
.tbl td input,.tbl td select{
width:100%;padding:4px 6px;border:1px solid transparent;border-radius:5px;background:#f7f9f7;
}
.tbl td input:focus,.tbl td select:focus{border-color:var(--g500);background:#fff;outline:none}
.tbl td.num,.tbl th.num{text-align:right;font-variant-numeric:tabular-nums}
.tbl-scroll{overflow:auto;flex:1;min-height:200px;max-height:calc(100vh - 340px);border:1px solid var(--line);border-radius:8px}
.plant-tbl td:nth-child(1){min-width:130px}
.plant-tbl input{text-align:right}
.plant-tbl input.txt{text-align:left}
.calc-cell{color:var(--g700);font-weight:600;font-variant-numeric:tabular-nums;white-space:nowrap}
.del{cursor:pointer;color:#c3cdc6}
.del:hover{color:var(--bad)}
/ ---------- plant lib ---------- /
.plant-layout{display:grid;grid-template-columns:300px 1fr;gap:14px;align-items:start}
@media(max-width:1100px){.plant-layout{grid-template-columns:1fr}}
.lib{display:flex;flex-direction:column;max-height:calc(100vh - 170px)}
.search{width:100%;padding:7px 10px;border:1px solid var(--line);border-radius:6px}
.filter-grid{display:grid;grid-template-columns:1fr 1fr;gap:6px;margin:8px 0}
.filter-grid select{padding:5px 6px;border:1px solid var(--line);border-radius:6px;font-size:12px}
.lib-list{flex:1;overflow:auto;min-height:120px;display:flex;flex-direction:column;gap:4px}
.lib-item{
border:1px solid var(--line);border-radius:7px;padding:6px 8px;cursor:pointer;background:#fcfdfc;
}
.lib-item:hover{border-color:var(--g500);background:var(--g100)}
.li-top{display:flex;align-items:center;gap:6px}
.li-name{font-weight:600;font-size:12.5px}
.li-latin{font-size:10.5px;color:#9aa79f;font-style:italic;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.li-tags{display:flex;gap:4px;flex-wrap:wrap;margin-top:3px}
.tag{font-size:10px;padding:1px 5px;border-radius:4px;background:#eef2ef;color:#63736a}
.tag.ev{background:#e3f0e7;color:var(--g700)}
.tag.de{background:#faefdc;color:#a5761d}
.tag.na{background:#e6eefb;color:#3a5c96}
.tag.se{background:#fbe8ef;color:#a53a68}
.plant-foot{display:flex;gap:16px;flex-wrap:wrap;padding:10px 4px 0;border-top:1px solid var(--line);margin-top:10px}
.plant-foot div{display:flex;flex-direction:column}
.plant-foot span{font-size:11px;color:#8b978f}
.plant-foot b{font-size:15px;color:var(--g700);font-variant-numeric:tabular-nums}
.plant-foot .hl b{color:var(--earth)}
/ ---------- 单价提示 ---------- /
.notice{
background:#fdf8ec;border:1px solid #f0e0bd;border-left:3px solid var(--warn);
border-radius:7px;padding:7px 10px;margin:0 0 10px;font-size:11.5px;color:#7a6428;line-height:1.6;
}
.notice b{color:#8a6d16}
.pb-state{display:inline-block;margin-left:6px;padding:1px 7px;border-radius:4px;background:#ece4d0;color:#6d5a25}
.pb-state.on{background:var(--g100);color:var(--g700)}
.plant-tbl input.empty-price{background:#fdf5e6}
.plant-tbl input.from-book{background:#eaf4ee;color:var(--g700);font-weight:600}
/ ---------- kpi ---------- /
.kpi-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:12px;margin-bottom:14px}
.kpi{background:var(--white);border:1px solid var(--line);border-radius:10px;padding:12px 14px;box-shadow:var(--sh);border-left:3px solid var(--g500)}
.kpi.warn{border-left-color:var(--warn)}
.kpi.bad{border-left-color:var(--bad)}
.kpi .k{font-size:11.5px;color:#8b978f}
.kpi .v{font-size:22px;font-weight:600;color:var(--g800);font-variant-numeric:tabular-nums;line-height:1.3}
.kpi .v small{font-size:12px;font-weight:400;color:var(--ink2);margin-left:2px}
.kpi .d{font-size:11px;color:#9aa79f;margin-top:2px}
.res{font-weight:600}
.res.ok{color:var(--ok)} .res.warn{color:var(--warn)} .res.bad{color:var(--bad)}
.bars{display:flex;flex-direction:column;gap:8px}
.bar-row{display:flex;align-items:center;gap:8px;font-size:12px}
.bar-row .lb{width:76px;color:var(--ink2);flex:none}
.bar-track{flex:1;height:16px;background:#f0f3f1;border-radius:4px;overflow:hidden}
.bar-fill{height:100%;background:var(--g500);border-radius:4px}
.bar-row .vv{width:96px;text-align:right;font-variant-numeric:tabular-nums;color:var(--g700);flex:none}
.months{display:grid;grid-template-columns:repeat(12,1fr);gap:4px;text-align:center;font-size:11px}
.mo{border:1px solid var(--line);border-radius:6px;padding:6px 2px;background:#fafcfa}
.mo .mn{color:#8b978f}
.mo .mc{font-weight:600;color:var(--g700);font-size:14px}
.mo.hot{background:var(--g100);border-color:var(--g300)}
.mo.cold{background:#fbf4f4;border-color:#eddede}
.cost-total{display:flex;gap:24px;padding-top:10px;margin-top:6px;border-top:2px solid var(--g100)}
.cost-total div{display:flex;flex-direction:column}
.cost-total span{font-size:11.5px;color:#8b978f}
.cost-total b{font-size:20px;color:var(--g700);font-variant-numeric:tabular-nums}
/ ---------- out ---------- /
.out-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:10px}
.out-btn{
text-align:left;padding:12px 14px;border:1px solid var(--line);border-radius:9px;background:#fcfdfc;
cursor:pointer;display:flex;flex-direction:column;gap:3px;transition:.15s;
}
.out-btn:hover{border-color:var(--g500);background:var(--g100)}
.out-btn b{font-size:13px;color:var(--g800)}
.out-btn span{font-size:11.5px;color:#8b978f;line-height:1.45}
.out-btn.primary{background:var(--g600);border-color:var(--g600)}
.out-btn.primary b,.out-btn.primary span{color:#fff}
.out-btn.primary span{opacity:.8}
.doc{margin:0;padding-left:20px;font-size:12.5px;color:var(--ink2);line-height:1.9}
.doc b{color:var(--g800)}
/ ---------- toast ---------- /
.toast{
position:fixed;left:50%;bottom:34px;transform:translate(-50%,20px);
background:var(--g900);color:#fff;padding:9px 18px;border-radius:8px;font-size:13px;
opacity:0;pointer-events:none;transition:.25s;z-index:99;max-width:70vw;
}
.toast.show{opacity:1;transform:translate(-50%,0)}