:root{
  --bg:#0f1720; --card:#16212c; --card2:#1c2b38; --border:#253544;
  --text:#e6edf3; --muted:#8a9bb0; --y:#FFD100; --ok:#2ecc71; --off:#52606d;
  --warn:#f5a623; --danger:#ef4444; --accent:#3fa9f5; --r:12px;
}
*{box-sizing:border-box}
html,body{margin:0;background:var(--bg);color:var(--text);
  font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;min-height:100vh}

.topbar{display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:12px 20px;background:var(--card);border-bottom:1px solid var(--border);
  position:sticky;top:0;z-index:10;flex-wrap:wrap}
.brand{display:flex;align-items:center;gap:12px}
.logo{width:42px;height:42px;flex-shrink:0}
.brand-title{font-size:1.15rem;font-weight:800;letter-spacing:.02em}
.brand-title .y{color:var(--y)}
.brand-sub{font-size:.72rem;color:var(--muted)}
.topbar-right{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.stat{font-size:.8rem;color:var(--muted);border:1px solid var(--border);
  padding:5px 10px;border-radius:999px}

main{max-width:1300px;margin:0 auto;padding:18px}
h2{font-size:.95rem;text-transform:uppercase;letter-spacing:.04em;color:var(--muted);margin:18px 0 12px}
.empty{color:var(--muted);font-size:.85rem}
.hidden{display:none!important}

.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:14px}

.card{background:var(--card);border:1px solid var(--border);border-radius:var(--r);
  padding:14px;display:flex;flex-direction:column;gap:8px}
.card.discovered{border-style:dashed}
.card-head{display:flex;align-items:center;justify-content:space-between;gap:8px}
.card-name{font-weight:700;font-size:1rem}
.card-serial{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  font-size:.72rem;color:var(--muted);letter-spacing:.02em;margin-top:1px}
.card-site{font-size:.72rem;color:var(--muted)}
.dot{width:10px;height:10px;border-radius:50%;flex-shrink:0}
.dot.on{background:var(--ok);box-shadow:0 0 7px var(--ok)}
.dot.off{background:var(--off)}
.presence{display:flex;align-items:center;gap:6px;font-size:.75rem;color:var(--muted)}

.kv{display:flex;justify-content:space-between;font-size:.82rem;padding:2px 0}
.kv .k{color:var(--muted)}
.pill{font-size:.72rem;padding:2px 8px;border-radius:999px;font-weight:700}
.pill.ok{background:rgba(46,204,113,.15);color:var(--ok)}
.pill.warn{background:rgba(245,166,35,.15);color:var(--warn)}
.pill.danger{background:rgba(239,68,68,.18);color:var(--danger)}
.pill.muted{background:rgba(82,96,109,.2);color:var(--muted)}

.card-actions{display:flex;gap:8px;margin-top:4px;flex-wrap:wrap}
.btn{border:1px solid var(--border);background:var(--card2);color:var(--text);
  padding:8px 14px;border-radius:8px;cursor:pointer;font-size:.83rem;font-weight:600}
.btn:hover{filter:brightness(1.15)}
.btn-y{background:var(--y);color:#000;border-color:var(--y)}
.btn-small{padding:5px 10px;font-size:.75rem}
.btn-on{background:rgba(46,204,113,.15);color:var(--ok);border-color:var(--ok)}
.btn-off{background:rgba(239,68,68,.12);color:var(--danger);border-color:var(--danger)}

/* Modales */
.modal{position:fixed;inset:0;background:rgba(0,0,0,.6);display:flex;
  align-items:center;justify-content:center;z-index:50;padding:16px}
.modal-box{background:var(--card);border:1px solid var(--border);border-radius:var(--r);
  padding:20px;width:100%;max-width:420px;max-height:90vh;overflow:auto}
.modal-box.wide{max-width:820px}
.modal-box h3{margin:0 0 14px;color:var(--y)}
.modal-box label{display:block;font-size:.75rem;color:var(--muted);margin:10px 0 4px}
.modal-box input{width:100%;padding:9px 11px;border-radius:8px;border:1px solid var(--border);
  background:var(--bg);color:var(--text);font-size:.85rem}
.row2{display:flex;gap:10px}.row2>div{flex:1}
.modal-actions{display:flex;justify-content:flex-end;gap:10px;margin-top:16px}
.detail-head{display:flex;align-items:center;justify-content:space-between}
.detail-conn{font-size:.8rem;color:var(--muted);margin:4px 0 14px}

/* Detalle */
.dsection{background:var(--card2);border:1px solid var(--border);border-radius:10px;
  padding:12px;margin-bottom:12px}
.dsection h4{margin:0 0 10px;font-size:.8rem;color:var(--y);text-transform:uppercase;letter-spacing:.03em}
.io-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:8px}
.io{border:1px solid var(--border);border-radius:8px;padding:9px;text-align:center;background:var(--card)}
.io .n{font-size:.68rem;color:var(--muted)}
.io .s{font-weight:800;font-size:.85rem}
.io .s.on{color:var(--ok)}.io .s.off{color:var(--muted)}.io .s.blk{color:var(--danger)}
.relay{cursor:pointer}.relay.blocked{opacity:.55;cursor:not-allowed}
.formline{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin-top:6px}
.formline input{padding:8px 10px;border-radius:8px;border:1px solid var(--border);
  background:var(--bg);color:var(--text);font-size:.82rem;flex:1;min-width:90px}
.banner{background:var(--danger);color:#fff;text-align:center;padding:8px;border-radius:8px;
  font-weight:700;margin-bottom:12px}
a.maplink{color:var(--y);font-weight:700}

/* ===================== Vista de mapa ===================== */
.viewtabs{display:flex;border:1px solid var(--border);border-radius:999px;overflow:hidden}
.vtab{background:transparent;color:var(--muted);border:0;padding:6px 14px;
  font-size:.78rem;font-weight:700;cursor:pointer;font-family:inherit}
.vtab.active{background:var(--y);color:#0b0b0b}

#map{height:calc(100vh - 190px);min-height:420px;border-radius:var(--r);
  border:1px solid var(--border);background:var(--card)}
/* Los tiles de OSM son claros: se atenuan para no romper el tema oscuro. */
#map .leaflet-tile-pane{filter:brightness(.78) saturate(.85)}
.leaflet-container{background:var(--bg);font-family:inherit}
.leaflet-control-attribution{background:rgba(15,23,32,.8)!important;color:var(--muted)!important}
.leaflet-control-attribution a{color:var(--accent)!important}

/* Marcador: punto de presencia + nombre del equipo siempre visible */
.tmark{display:flex;align-items:center;gap:6px;white-space:nowrap}
.tmark-dot{width:14px;height:14px;border-radius:50%;flex-shrink:0;border:2px solid #0b0b0b}
.tmark.on .tmark-dot{background:var(--ok);box-shadow:0 0 10px var(--ok)}
.tmark.off .tmark-dot{background:var(--off)}
.tmark-name{background:rgba(15,23,32,.88);border:1px solid var(--border);
  border-radius:6px;padding:2px 7px;font-size:.74rem;font-weight:700;color:var(--text)}
.tmark.off .tmark-name{color:var(--muted)}

/* Popup del marcador */
.leaflet-popup-content-wrapper{background:var(--card);color:var(--text);
  border:1px solid var(--border);border-radius:10px}
.leaflet-popup-tip{background:var(--card);border:1px solid var(--border)}
.leaflet-popup-content{margin:12px 14px;font-size:.8rem}
.leaflet-popup-close-button{color:var(--muted)!important}
.mpop-name{font-weight:800;font-size:.95rem}
.mpop-sub{font-size:.72rem;color:var(--muted);margin-bottom:8px}
.mpop-row{padding:1px 0}
.mpop .btn{margin-top:10px}
.map-head{display:flex;align-items:center;justify-content:space-between;gap:12px}
.map-head h2{margin:18px 0 12px}

/* Los paneles/controles de Leaflet usan z-index hasta 1000: el modal y la
   barra superior deben quedar por encima del mapa. */
.modal{z-index:2000}
.topbar{z-index:1100}
.btn-danger{background:rgba(239,68,68,.12);color:var(--danger);border-color:var(--danger)}
.modal-actions .spacer{flex:1}

/* ===================== Pantalla de login ===================== */
.login-body{display:flex;align-items:center;justify-content:center;min-height:100vh;padding:20px}
.login-box{background:var(--card);border:1px solid var(--border);border-radius:var(--r);
  padding:32px 28px;width:100%;max-width:360px;display:flex;flex-direction:column;align-items:stretch}
.login-logo{width:64px;height:64px;align-self:center}
.login-title{font-size:1.25rem;font-weight:800;letter-spacing:.02em;text-align:center;margin-top:14px}
.login-title .y{color:var(--y)}
.login-sub{font-size:.75rem;color:var(--muted);text-align:center;margin-bottom:22px}
.login-box label{font-size:.75rem;color:var(--muted);margin-bottom:6px}
.login-box input{width:100%;padding:11px 12px;border-radius:8px;border:1px solid var(--border);
  background:var(--bg);color:var(--text);font-size:.95rem;font-family:inherit}
.login-box input:focus{outline:none;border-color:var(--y)}
.login-btn{margin-top:18px;padding:11px;font-size:.9rem;font-weight:700}
.login-btn:disabled{opacity:.6;cursor:default}
.login-error{margin:14px 0 0;padding:9px 11px;border-radius:8px;font-size:.8rem;
  background:rgba(239,68,68,.12);color:var(--danger);border:1px solid var(--danger)}

/* Boton de salir en la barra superior */
.btn-logout{font-size:.75rem;padding:5px 10px}

/* ===================== Usuarios y roles ===================== */
.whoami{font-size:.75rem;color:var(--muted);border:1px solid var(--border);
  padding:5px 10px;border-radius:999px}
.utable{width:100%;border-collapse:collapse;font-size:.85rem}
.utable th{text-align:left;font-size:.7rem;text-transform:uppercase;letter-spacing:.04em;
  color:var(--muted);font-weight:600;padding:6px 8px;border-bottom:1px solid var(--border)}
.utable td{padding:8px;border-bottom:1px solid var(--border)}
.utable select{background:var(--bg);color:var(--text);border:1px solid var(--border);
  border-radius:6px;padding:5px 8px;font-size:.8rem;font-family:inherit}
.utable .tu{font-size:.68rem;color:var(--y);border:1px solid var(--y);
  border-radius:999px;padding:1px 6px;margin-left:4px}
.formline select{background:var(--bg);color:var(--text);border:1px solid var(--border);
  border-radius:8px;padding:8px 10px;font-size:.82rem;font-family:inherit}
.rolehelp{font-size:.74rem;color:var(--muted);line-height:1.6;margin:10px 0 0}
.login-box label.mt{margin-top:14px}

/* Restricciones por rol. Es comodidad visual: el permiso real lo valida el
   servidor en cada endpoint. */
body.no-admin [data-edit],
body.no-admin [data-register]{display:none}
body.solo-lectura .relay{pointer-events:none;opacity:.6}
body.solo-lectura .formline,
body.solo-lectura [data-all]{display:none}

/* ===================== Registro de auditoría ===================== */
.audit-scroll{max-height:55vh;overflow-y:auto;border:1px solid var(--border);border-radius:8px}
.atable{font-size:.78rem}
.atable th{position:sticky;top:0;background:var(--card);z-index:1}
.atable td{vertical-align:top}
.audit-ts{color:var(--muted);white-space:nowrap}
.audit-ip{color:var(--muted);white-space:nowrap}
.audit-role{font-size:.65rem;color:var(--muted);text-transform:uppercase;letter-spacing:.03em}
.audit-bad td{background:rgba(239,68,68,.07)}
.audit-bad td:nth-child(3){color:var(--danger)}
.pwwarn{background:rgba(245,166,35,.12);border:1px solid var(--warn);color:var(--warn);
  border-radius:8px;padding:9px 11px;font-size:.78rem;margin:0 0 12px}
.pwold{font-size:.62rem;color:var(--warn);border:1px solid var(--warn);
  border-radius:999px;padding:1px 6px;margin-left:4px;white-space:nowrap}
