:root{
  --bg-0:#0a0e14;
  --bg-1:#10151d;
  --bg-2:#161d27;
  --bg-3:#1d2530;
  --bg-elev:#212a37;
  --line:#2a3441;
  --line-soft:#1c2530;
  --text-0:#eef2f6;
  --text-1:#aab6c4;
  --text-2:#6c7a8a;
  --accent:#31d0ff;
  --accent-dim:#1a8fb8;
  --accent-soft:rgba(49,208,255,.12);
  --amber:#ffb454;
  --green:#3ddc84;
  --red:#ff5c7a;
  --violet:#a78bfa;
  --mono:'JetBrains Mono',ui-monospace,'SF Mono',Menlo,Consolas,monospace;
  --sans:-apple-system,'Segoe UI',Inter,ui-sans-serif,Roboto,Helvetica,Arial,sans-serif;
  --radius:10px;
  --radius-sm:6px;
}
*{box-sizing:border-box;}
html,body{height:100%;margin:0;}
body{
  background:var(--bg-0);
  color:var(--text-0);
  font-family:var(--sans);
  overflow:hidden;
  font-size:13px;
  -webkit-font-smoothing:antialiased;
}
::-webkit-scrollbar{width:10px;height:10px;}
::-webkit-scrollbar-thumb{background:var(--bg-3);border-radius:6px;}
::-webkit-scrollbar-track{background:transparent;}

/* ---------- layout shell ---------- */
#app{display:grid;grid-template-rows:48px 1fr;height:100vh;}
#topbar{
  display:flex;align-items:center;gap:6px;
  padding:0 12px;background:linear-gradient(180deg,var(--bg-1),var(--bg-0));
  border-bottom:1px solid var(--line);
  position:relative;z-index:30;
}
#brand{display:flex;align-items:center;gap:8px;margin-right:10px;user-select:none;}
#brand .logo{width:22px;height:22px;flex:none;}
#brand b{font-size:14px;letter-spacing:.2px;}
#brand span{color:var(--text-2);font-size:11px;font-family:var(--mono);}
.tb-sep{width:1px;height:22px;background:var(--line);margin:0 6px;flex:none;}
.tb-btn{
  display:flex;align-items:center;gap:6px;height:30px;padding:0 10px;
  background:transparent;border:1px solid transparent;border-radius:var(--radius-sm);
  color:var(--text-1);cursor:pointer;font-size:12px;font-family:var(--sans);white-space:nowrap;
  transition:background .12s,color .12s,border-color .12s;
}
.tb-btn:hover{background:var(--bg-2);color:var(--text-0);}
.tb-btn.active{background:var(--accent-soft);color:var(--accent);border-color:rgba(49,208,255,.35);}
.tb-btn svg{width:15px;height:15px;flex:none;}
.tb-spacer{flex:1;}
#zoomlabel{font-family:var(--mono);color:var(--text-2);font-size:11px;min-width:42px;text-align:center;}

#body-grid{display:grid;grid-template-columns:250px 1fr;min-height:0;}

/* ---------- sidebar / palette ---------- */
#sidebar{
  background:var(--bg-1);border-right:1px solid var(--line);
  overflow-y:auto;padding:10px 8px 40px;
}
#sidebar h1{font-size:10px;text-transform:uppercase;letter-spacing:.08em;color:var(--text-2);margin:10px 6px 6px;font-weight:600;}
.cat{margin-bottom:2px;}
.cat-head{
  display:flex;align-items:center;gap:8px;padding:7px 6px;cursor:pointer;
  border-radius:var(--radius-sm);color:var(--text-1);user-select:none;
}
.cat-head:hover{background:var(--bg-2);color:var(--text-0);}
.cat-head svg.chev{width:10px;height:10px;transition:transform .15s;flex:none;color:var(--text-2);}
.cat-head.open svg.chev{transform:rotate(90deg);}
.cat-head .cat-icon{width:15px;height:15px;flex:none;color:var(--accent);}
.cat-head b{font-size:12px;font-weight:500;flex:1;}
.cat-items{display:none;padding:2px 0 6px 4px;}
.cat-items.open{display:block;}
.dev-item{
  display:flex;align-items:center;gap:8px;padding:6px 8px;margin:1px 0;border-radius:var(--radius-sm);
  cursor:grab;color:var(--text-1);font-size:12px;
}
.dev-item:hover{background:var(--bg-2);color:var(--text-0);}
.dev-item svg{width:16px;height:16px;flex:none;color:var(--text-2);}
.dev-item:hover svg{color:var(--accent);}

/* ---------- canvas area ---------- */
#canvas-wrap{position:relative;overflow:hidden;background:var(--bg-0);cursor:default;}
#canvas-wrap.panning{cursor:grabbing;}
#gridsvg{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;}
#world{position:absolute;left:0;top:0;transform-origin:0 0;}
#linksvg{position:absolute;left:-20000px;top:-20000px;width:40000px;height:40000px;overflow:visible;}
#nodelayer{position:absolute;left:0;top:0;}

.node{
  position:absolute;width:88px;
  display:flex;flex-direction:column;align-items:center;gap:5px;
  cursor:grab;user-select:none;transform:translate(-50%,-50%);
}
.node.dragging{cursor:grabbing;z-index:20;}
.node .box{
  width:56px;height:56px;border-radius:14px;background:var(--bg-2);
  border:1.5px solid var(--line);display:flex;align-items:center;justify-content:center;
  box-shadow:0 2px 10px rgba(0,0,0,.35);position:relative;transition:border-color .12s,box-shadow .12s;
}
.node .box svg{width:28px;height:28px;color:var(--nc,var(--accent));}
.node.selected .box{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft),0 2px 10px rgba(0,0,0,.35);}
.node .label{font-size:11px;color:var(--text-0);text-align:center;max-width:100px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.node .sub{font-size:9.5px;font-family:var(--mono);color:var(--text-2);margin-top:-4px;max-width:104px;overflow:hidden;text-overflow:ellipsis;white-space:normal;white-space:nowrap;}
.node .connector{
  position:absolute;right:-7px;top:50%;transform:translateY(-50%);width:14px;height:14px;border-radius:50%;
  background:var(--bg-0);border:2px solid var(--accent);opacity:0;transition:opacity .12s,transform .12s;cursor:crosshair;
}
.node:hover .connector{opacity:1;}
.node .connector:hover{transform:translateY(-50%) scale(1.3);}
.node .status-dot{position:absolute;left:-3px;bottom:-3px;width:11px;height:11px;border-radius:50%;background:var(--green);border:2px solid var(--bg-0);}

.link-line{stroke-width:2.2;fill:none;cursor:pointer;}
.link-hit{stroke-width:14;fill:none;stroke:transparent;cursor:pointer;}
.link-label{font-family:var(--mono);font-size:9px;fill:var(--text-2);}
.link-label-bg{fill:var(--bg-1);opacity:.85;}
.pkt{filter:drop-shadow(0 0 4px currentColor);}

text, .link-label, .link-label-bg, .node .label, .node .sub {
  user-select: none;
}

.notebox { user-select: none; }
.notebox div[contenteditable] { user-select: text; }

#note{
  position:absolute;min-width:120px;min-height:60px;background:rgba(255,206,84,.1);
  border:1.5px dashed var(--amber);border-radius:8px;padding:8px;color:#ffe1a8;font-size:12px;
}

/* rubber-band select */
#rubber{position:absolute;border:1px solid var(--accent);background:rgba(49,208,255,.08);pointer-events:none;display:none;}

/* minimap */
#minimap{
  position:absolute;right:14px;bottom:14px;width:180px;height:120px;background:rgba(16,21,29,.9);
  border:1px solid var(--line);border-radius:var(--radius);backdrop-filter:blur(6px);overflow:hidden;
}
#minimap svg{width:100%;height:100%;}

/* ---------- modal (device config) ---------- */
.overlay{position:fixed;inset:0;background:rgba(5,7,10,.55);backdrop-filter:blur(0.5px);display:none;align-items:center;justify-content:center;z-index:100;}
.overlay.open{display:flex;}
.modal{
  width:620px;max-height:86vh;background:var(--bg-1);border:1px solid var(--line);border-radius:14px;
  box-shadow:0 20px 60px rgba(0,0,0,.5);display:flex;flex-direction:column;overflow:hidden;
}
.modal-head{display:flex;align-items:center;gap:10px;padding:14px 16px;border-bottom:1px solid var(--line);flex:none;}
.modal-head .icon{width:34px;height:34px;border-radius:10px;background:var(--bg-2);display:flex;align-items:center;justify-content:center;flex:none;}
.modal-head .icon svg{width:19px;height:19px;color:var(--accent);}
.modal-head .ti{flex:1;min-width:0;}
.modal-head .ti b{display:block;font-size:14px;}
.modal-head .ti span{color:var(--text-2);font-size:11px;font-family:var(--mono);}
.modal-close{width:26px;height:26px;border-radius:7px;display:flex;align-items:center;justify-content:center;color:var(--text-2);cursor:pointer;flex:none;}
.modal-close:hover{background:var(--bg-2);color:var(--text-0);}
.tabs{display:flex;gap:2px;padding:8px 12px 0;border-bottom:1px solid var(--line);flex:none;overflow-x:auto;}
.tab{padding:8px 12px;font-size:12px;color:var(--text-2);cursor:pointer;border-bottom:2px solid transparent;white-space:nowrap;}
.tab.active{color:var(--accent);border-color:var(--accent);}
.tabpanel{display:none;padding:14px 16px;overflow-y:auto;min-height:0;}
.tabpanel.active{display:block;flex:1;}
#cfg-panels{flex:1;min-height:0;display:flex;flex-direction:column;overflow:hidden;}
.field{margin-bottom:12px;}
.field label{display:block;font-size:11px;color:var(--text-2);margin-bottom:4px;}
.field input[type=text],.field input[type=number],.field input[type=password],.field select,.field textarea{
  width:100%;background:var(--bg-2);border:1px solid var(--line);border-radius:7px;padding:7px 9px;
  color:var(--text-0);font-size:12.5px;font-family:var(--sans);outline:none;
}
.field textarea{resize:vertical;min-height:50px;font-family:var(--mono);}
.field input:focus,.field select:focus,.field textarea:focus{border-color:var(--accent);}
.row2{display:grid;grid-template-columns:1fr 1fr;gap:10px;}
.row3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:10px;}
.row4{display:grid;grid-template-columns:1fr 1fr 1fr auto;gap:8px;}
.chk{display:flex;align-items:center;gap:8px;font-size:12.5px;color:var(--text-1);padding:6px 0;cursor:pointer;}
.chk input{accent-color:var(--accent);width:14px;height:14px;}
.mini-table{width:100%;border-collapse:collapse;font-size:11.5px;}
.mini-table th{text-align:left;color:var(--text-2);font-weight:500;font-size:10px;text-transform:uppercase;letter-spacing:.05em;padding:4px 6px;border-bottom:1px solid var(--line);}
.mini-table td{padding:3px 6px;border-bottom:1px solid var(--line-soft);vertical-align:middle;}
.mini-table input,.mini-table select{width:100%;background:var(--bg-2);border:1px solid var(--line);border-radius:5px;padding:4px 6px;color:var(--text-0);font-size:11px;font-family:var(--mono);}
.btn{
  background:var(--bg-2);border:1px solid var(--line);color:var(--text-0);border-radius:7px;
  padding:7px 12px;font-size:12px;cursor:pointer;display:inline-flex;align-items:center;gap:6px;
}
.btn:hover{background:var(--bg-3);}
.btn.primary{background:var(--accent);border-color:var(--accent);color:#04202b;font-weight:600;}
.btn.primary:hover{background:#5fdaff;}
.btn.danger{color:var(--red);}
.btn.sm{padding:4px 8px;font-size:11px;}
.btn:disabled{opacity:.5;cursor:default;}
.modal-foot{display:flex;justify-content:space-between;padding:12px 16px;border-top:1px solid var(--line);flex:none;}
.badge{font-size:9.5px;font-family:var(--mono);padding:2px 6px;border-radius:5px;background:var(--bg-2);color:var(--text-2);border:1px solid var(--line);}
.color-swatches{display:flex;gap:6px;}
.swatch{width:20px;height:20px;border-radius:6px;cursor:pointer;border:2px solid transparent;}
.swatch.sel{border-color:#fff;}

/* IP list per port */
.port-block{border:1px solid var(--line);border-radius:10px;margin-bottom:12px;overflow:hidden;}
.port-block-head{display:flex;align-items:center;gap:8px;padding:8px 10px;background:var(--bg-2);}
.port-block-head b{font-size:12px;flex:1;}
.port-block-body{padding:8px 10px;}
.ip-row{display:grid;grid-template-columns:22px 1fr 100px 1fr 1fr auto;gap:6px;align-items:center;padding:5px 0;border-bottom:1px solid var(--line-soft);}
.ip-row:last-child{border-bottom:none;}
.ip-row input[type=text]{background:var(--bg-2);border:1px solid var(--line);border-radius:5px;padding:5px 7px;color:var(--text-0);font-size:11px;font-family:var(--mono);width:100%;}
.ip-row input[disabled]{opacity:.65;}
.ip-badge{font-size:9px;font-family:var(--mono);padding:2px 5px;border-radius:4px;white-space:nowrap;}
.ip-badge.static{background:rgba(49,208,255,.12);color:var(--accent);}
.ip-badge.dhcp{background:rgba(61,220,132,.12);color:var(--green);}
.primary-star{cursor:pointer;color:var(--text-2);font-size:14px;}
.primary-star.on{color:var(--amber);}

/* DHCP / DNS server panels */
.svc-panel{background:var(--bg-2);border:1px solid var(--line);border-radius:10px;padding:12px;margin-top:8px;}
.svc-panel h5{margin:0 0 10px;font-size:11px;color:var(--text-1);text-transform:uppercase;letter-spacing:.05em;}
.kv-row{display:flex;justify-content:space-between;padding:4px 0;font-size:12px;}
.kv-row span:first-child{color:var(--text-2);}

/* ---------- console (embedded in device modal tab) ---------- */
.console-wrap{display:flex;flex-direction:column;height:100%;min-height:280px;background:#0d1117;border-radius:10px;border:1px solid var(--line);overflow:hidden;}
.console-body{flex:1;overflow-y:auto;padding:10px 12px;font-family:var(--mono);font-size:12px;line-height:1.6;min-height:0;}
.console-body .l{white-space:pre-wrap;word-break:break-word;}
.l-ok{color:var(--green);}
.l-err{color:var(--red);}
.l-info{color:var(--text-1);}
.l-dim{color:var(--text-2);}
.console-inputbar{display:flex;align-items:center;gap:8px;padding:8px 12px;border-top:1px solid var(--line-soft);flex:none;}
.console-inputbar span{color:var(--accent);font-family:var(--mono);font-size:12px;}
.console-inputbar input{flex:1;background:transparent;border:none;outline:none;color:var(--text-0);font-family:var(--mono);font-size:12px;}

/* connect popup */
#connpop{position:fixed;z-index:110;background:var(--bg-1);border:1px solid var(--line);border-radius:10px;padding:12px;width:270px;box-shadow:0 14px 40px rgba(0,0,0,.5);display:none;}
#connpop.open{display:block;}
#connpop h4{margin:0 0 8px;font-size:12px;color:var(--text-1);}

/* toast */
#toast{position:fixed;left:50%;bottom:26px;transform:translateX(-50%) translateY(20px);background:var(--bg-elev);border:1px solid var(--line);
  color:var(--text-0);padding:9px 16px;border-radius:9px;font-size:12px;opacity:0;pointer-events:none;transition:all .2s;z-index:200;box-shadow:0 10px 30px rgba(0,0,0,.4);}
#toast.show{opacity:1;transform:translateX(-50%) translateY(0);}

.hidden{display:none !important;}

#ipcalc-results .kv-row {display:flex;justify-content:space-between;padding:4px 0;font-size:12px;border-bottom:1px solid var(--line-soft);}
#ipcalc-results .kv-row span:first-child {color:var(--text-2);}
#ipcalc-results .kv-row span:last-child {font-family:var(--mono);color: var(--text-0);}
#ipcalc-results {font-family:var(--mono);font-size: 12.5px;}
.calc-line {display:flex;flex-wrap:wrap;align-items:baseline;padding:3px 0;border-bottom:1px solid var(--line-soft);}
.calc-line:last-child {border-bottom: none;}
.cl-label {width:130px;flex-shrink:0;color:var(--text-2);}
.cl-value {color:var(--text-0);margin-right:12px;white-space:nowrap;}
.binary {color:#3ddc84;font-size:11px;letter-spacing:0.2px;font-weight:300;}
.class-badge {background:var(--bg-2);padding:0 6px;border-radius:4px;font-size:10px;color:var(--accent);margin-left:6px;}
.private-info .cl-value {color:var(--amber);}

/* ---------- auth / account / projects / admin ---------- */
#project-indicator{display:none;align-items:center;gap:6px;padding:5px 10px;border-radius:var(--radius-sm);cursor:pointer;color:var(--text-1);font-size:12px;background:var(--bg-2);border:1px solid var(--line);margin-right:8px;max-width:220px;}
#project-indicator:hover{background:var(--bg-3);color:var(--text-0);}
#project-indicator svg{width:13px;height:13px;flex:none;color:var(--accent);}
#project-indicator span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
#project-indicator.show{display:flex;}

#btn-account{width:32px;height:32px;border-radius:50%;background:var(--bg-2);border:1px solid var(--line);color:var(--text-1);display:flex;align-items:center;justify-content:center;cursor:pointer;flex:none;font-size:12px;font-weight:700;}
#btn-account:hover{border-color:var(--accent);color:var(--accent);}
#btn-account.logged-in{background:var(--accent);color:#04202b;border-color:var(--accent);}
#btn-account svg{width:16px;height:16px;}

.account-menu{position:fixed;z-index:130;background:var(--bg-1);border:1px solid var(--line);border-radius:10px;padding:6px;width:220px;box-shadow:0 14px 40px rgba(0,0,0,.5);display:none;}
.account-menu.open{display:block;}
.account-menu .who{padding:10px 10px 8px;border-bottom:1px solid var(--line-soft);margin-bottom:4px;}
.account-menu .who b{display:block;font-size:13px;}
.account-menu .who span{font-size:10.5px;color:var(--text-2);font-family:var(--mono);}
.am-item{display:flex;align-items:center;gap:8px;padding:8px 10px;border-radius:7px;font-size:12.5px;color:var(--text-1);cursor:pointer;}
.am-item:hover{background:var(--bg-2);color:var(--text-0);}
.am-item svg{width:14px;height:14px;flex:none;color:var(--text-2);}
.am-item.danger{color:var(--red);}
.am-item.danger svg{color:var(--red);}

.authtabs{display:flex;gap:2px;padding:0 16px;margin-top:4px;}
.authtab{padding:9px 14px;font-size:12.5px;color:var(--text-2);cursor:pointer;border-bottom:2px solid transparent;}
.authtab.active{color:var(--accent);border-color:var(--accent);}
.auth-form{padding:16px;}
.auth-err{color:var(--red);font-size:12px;margin-top:6px;min-height:16px;}
.auth-hint{color:var(--text-2);font-size:11px;line-height:1.5;margin-top:10px;padding-top:10px;border-top:1px solid var(--line-soft);}

.project-list{max-height:50vh;overflow-y:auto;padding:4px 0;}
.project-row{display:flex;align-items:center;gap:10px;padding:10px 12px;border-radius:9px;cursor:pointer;border:1px solid transparent;}
.project-row:hover{background:var(--bg-2);}
.project-row.active{border-color:var(--accent);background:var(--accent-soft);}
.project-row .pi{width:34px;height:34px;border-radius:9px;background:var(--bg-2);display:flex;align-items:center;justify-content:center;flex:none;color:var(--accent);}
.project-row .pi svg{width:17px;height:17px;}
.project-row .pmeta{flex:1;min-width:0;}
.project-row .pmeta b{display:block;font-size:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.project-row .pmeta span{font-size:10.5px;color:var(--text-2);font-family:var(--mono);}
.project-row .pactions{display:flex;gap:4px;flex:none;}
.project-row input.rename-input{background:var(--bg-2);border:1px solid var(--accent);border-radius:5px;padding:4px 7px;color:var(--text-0);font-size:12.5px;width:100%;}

.user-table{width:100%;border-collapse:collapse;font-size:12px;}
.user-table th{text-align:left;color:var(--text-2);font-weight:500;font-size:10px;text-transform:uppercase;letter-spacing:.05em;padding:6px 8px;border-bottom:1px solid var(--line);}
.user-table td{padding:8px;border-bottom:1px solid var(--line-soft);vertical-align:middle;}
.role-pill{font-size:9.5px;font-family:var(--mono);padding:2px 6px;border-radius:5px;background:var(--bg-2);color:var(--text-2);border:1px solid var(--line);}
.role-pill.admin{background:rgba(255,180,84,.12);color:var(--amber);border-color:rgba(255,180,84,.3);}

.temppass-box{background:var(--bg-2);border:1px dashed var(--accent);border-radius:9px;padding:12px;text-align:center;margin-top:10px;}
.temppass-box .code{font-family:var(--mono);font-size:20px;letter-spacing:2px;color:var(--accent);margin:6px 0;}
