:root{
  --bg:#ffffff;
  --fg:#111111;
  --muted:#586174;
  --border:#d9dde5;
  --border-strong:#c5cbd6;
  --card:#fafbfc;
  --card-2:#f3f5f8;
  --link:#0b57d0;
  --danger:#b00020;
  --success:#0f9d58;
  --warn:#b26a00;
  --btn:#111111;
  --btnfg:#ffffff;
  --btn-secondary:#eef1f5;
  --btn-secondary-fg:#111111;
  --brand:#16a34a;
  --badge-bg:#eef1f5;
  --input-bg:#ffffff;
  --shadow:0 1px 2px rgba(0,0,0,.05), 0 6px 16px rgba(0,0,0,.04);
  --nav-bg:rgba(255,255,255,.88);

  --space-0:0;
  --space-1:2px;
  --space-2:4px;
  --space-3:6px;
  --space-4:8px;
  --space-5:10px;
  --space-6:12px;
  --space-7:14px;
  --space-8:16px;
  --space-9:20px;
  --space-10:24px;
  --space-11:40px;
  --space-12:48px;
  --space-13:60px;

  --z-base:1;
  --z-sticky:2;
  --z-topbar:50;
  --z-overlay:100;
  --z-drawer-overlay:179;
  --z-drawer:180;
  --z-nav-overlay:199;
  --z-nav-drawer:200;
  --z-dropdown:300;
  --z-col-vis:1000;
  --z-spinner:1100;
  --z-toast:9000;
  --z-page-overlay:9999;

  --radius-xs:3px;
  --radius-sm:4px;
  --radius-md:6px;
  --radius-lg:8px;
  --radius-xl:10px;
  --radius-2xl:12px;
  --radius-3xl:14px;
  --radius-4xl:16px;
  --radius-pill:999px;

  --font-size-2xs:.65rem;
  --font-size-xs:.75rem;
  --font-size-sm:.78rem;
  --font-size-md:.82rem;
  --font-size-base:.85rem;
  --font-size-lg:.88rem;
  --font-size-xl:.9rem;
  --font-size-2xl:.92rem;
  --font-size-3xl:.95rem;
  --font-size-4xl:1rem;
  --font-size-5xl:1.05rem;
  --font-size-6xl:1.15rem;
  --font-size-7xl:1.35rem;
  --font-size-8xl:1.6rem;
  --font-size-9xl:1.9rem;

  --focus-ring:0 0 0 2px var(--bg), 0 0 0 4px var(--link);
  --font-mono:'Fira Code',ui-monospace,'SFMono-Regular','Consolas',monospace;
}

@font-face{font-family:'Fira Code';src:url('fonts/fira-code-subset.woff2') format('woff2');font-weight:400;font-style:normal;font-display:swap}

@media (prefers-color-scheme: dark){
  :root{
    --bg:#0e1116;
    --fg:#e7eaf0;
    --muted:#a8b0bf;
    --border:#2a2f3a;
    --border-strong:#394150;
    --card:#151a22;
    --card-2:#1b2230;
    --link:#7ab0ff;
    --danger:#ff5c7a;
    --success:#22C55E;
    --warn:#ffbf66;
    --btn:#22C55E;
    --btnfg:#0a1a0d;
    --brand:#22C55E;
    --btn-secondary:#1b2230;
    --btn-secondary-fg:#e7eaf0;
    --badge-bg:#1b2230;
    --input-bg:#0f141c;
    --shadow:0 1px 2px rgba(0,0,0,.25), 0 8px 24px rgba(0,0,0,.25);
    --nav-bg:rgba(14,17,22,.88);
  }
}
html[data-theme="light"]{
  --bg:#ffffff;
  --fg:#111111;
  --muted:#586174;
  --border:#d9dde5;
  --border-strong:#c5cbd6;
  --card:#fafbfc;
  --card-2:#f3f5f8;
  --link:#0b57d0;
  --danger:#b00020;
  --success:#0f9d58;
  --warn:#b26a00;
  --btn:#111111;
  --btnfg:#ffffff;
  --brand:#16a34a;
  --btn-secondary:#eef1f5;
  --btn-secondary-fg:#111111;
  --badge-bg:#eef1f5;
  --input-bg:#ffffff;
  --shadow:0 1px 2px rgba(0,0,0,.05), 0 6px 16px rgba(0,0,0,.04);
  --nav-bg:rgba(255,255,255,.88);
}
html[data-theme="dark"]{
  --bg:#0e1116;
  --fg:#e7eaf0;
  --muted:#a8b0bf;
  --border:#2a2f3a;
  --border-strong:#394150;
  --card:#151a22;
  --card-2:#1b2230;
  --link:#7ab0ff;
  --danger:#ff5c7a;
  --success:#22C55E;
  --warn:#ffbf66;
  --btn:#22C55E;
  --btnfg:#0a1a0d;
  --brand:#22C55E;
  --btn-secondary:#1b2230;
  --btn-secondary-fg:#e7eaf0;
  --badge-bg:#1b2230;
  --input-bg:#0f141c;
  --shadow:0 1px 2px rgba(0,0,0,.25), 0 8px 24px rgba(0,0,0,.25);
  --nav-bg:rgba(14,17,22,.88);
}
html[data-theme="dark"] ::-webkit-calendar-picker-indicator{
  filter:invert(1);
}
@media(prefers-color-scheme:dark){
  html:not([data-theme]) ::-webkit-calendar-picker-indicator{
    filter:invert(1);
  }
}

*{box-sizing:border-box}
html{scroll-behavior:smooth}

/* --- #504: skip-to-content link --- */
.skip-link{position:absolute;top:-100%;left:var(--space-8);padding:var(--space-4) var(--space-8);background:var(--link);color:#fff;border-radius:var(--radius-sm);z-index:var(--z-page-overlay);font-weight:600;text-decoration:none}
.skip-link:focus{top:var(--space-4)}

/* --- #504: focus-visible rings on all interactive elements --- */
:focus-visible{outline:none;box-shadow:var(--focus-ring)}
input:focus-visible,select:focus-visible,textarea:focus-visible{box-shadow:var(--focus-ring)}
.nav-pill:focus-visible,.action-pill:focus-visible,.badge:focus-visible{box-shadow:var(--focus-ring);border-radius:var(--radius-2xl)}
@media(forced-colors:active){:focus-visible{outline:2px solid CanvasText;outline-offset:2px;box-shadow:none}}
body{
  background:var(--bg);
  color:var(--fg);
  font-family:Inter, system-ui, Segoe UI, Roboto, Arial, sans-serif;
  margin:0;
  line-height:1.45;
}
.page{
  max-width:1280px;
  margin:0 auto;
  padding:var(--space-9);
}
a{color:var(--link);text-decoration:none}
a:hover{text-decoration:underline}
hr{border:none;border-top:1px solid var(--border);margin:18px 0}
h1,h2,h3{margin:.2em 0 .55em 0;line-height:1.2}
h1{font-size:var(--font-size-9xl)}
h2{font-size:var(--font-size-7xl)}
h3{font-size:var(--font-size-5xl)}

.topbar{
  position:sticky;
  top:0;
  z-index:var(--z-topbar);
  backdrop-filter:blur(8px);
  background:var(--nav-bg);
  border-bottom:1px solid var(--border);
}
.nav-wrap{
  max-width:1280px;
  margin:0 auto;
  padding:var(--space-6) var(--space-9);
  display:flex;
  gap:18px;
  align-items:center;
  flex-wrap:wrap;
}
.nav-brand{
  display:flex;
  align-items:center;
  font-family:var(--font-mono);
  font-weight:600;
  font-size:var(--font-size-4xl);
  color:var(--fg);
  text-decoration:none;
  white-space:nowrap;
  flex-shrink:0;
  letter-spacing:-.01em;
}
.nav-brand:hover{opacity:.8;text-decoration:none}
.nav-brand-php{color:var(--brand)}
.footer-brand{font-size:var(--font-size-xl);opacity:.85}
.login-wrap{max-width:400px;margin:var(--space-11) auto 0;padding:0 var(--space-8)}
.login-card{background:var(--card);border:1px solid var(--border);border-radius:var(--radius-2xl);padding:36px var(--space-11);box-shadow:var(--shadow)}
.login-logo{text-align:center;margin-bottom:var(--space-9);display:flex;justify-content:center}
.login-logo img{max-width:200px;height:auto}
.login-wrap h1{text-align:center;margin:0 0 var(--space-10);font-size:var(--font-size-8xl)}
.login-wrap .row{flex-direction:column;gap:var(--space-7)}
.login-wrap label{width:100%}
.login-wrap input[type=text],.login-wrap input[type=password],.login-wrap input:not([type]){width:100%;box-sizing:border-box}
.login-wrap form>p{margin:var(--space-9) 0 0}
.login-wrap form>p>button{width:100%;padding:var(--space-5)}
.nav-links{
  display:flex;
  gap:var(--space-7);
  flex-wrap:wrap;
  align-items:center;
}
.nav-user{
  margin-right:var(--space-3);
}
.nav-pill{
  display:inline-flex;
  align-items:center;
  gap:var(--space-3);
  padding:9px 13px;
  border-radius:var(--radius-2xl);
  line-height:1.2;
  background:transparent;
}
.nav-pill:hover{
  background:var(--card-2);
  text-decoration:none;
}
.nav-right{
  margin-left:auto;
  display:flex;
  gap:var(--space-5);
  align-items:center;
  flex-wrap:wrap;
}
.nav-dropdown{
  position:relative;
}
.nav-dropdown-toggle{
  padding:9px 13px;
  border-radius:var(--radius-2xl);
  background:transparent;
  color:var(--link);
  border:none;
  cursor:pointer;
  font:inherit;
  line-height:1.2;
}
.nav-dropdown-toggle:hover{
  background:var(--card-2);
  filter:none;
}
.nav-dropdown-menu{
  display:none;
  position:absolute;
  top:calc(100% + 4px);
  left:0;
  min-width:160px;
  background:var(--card);
  border:1px solid var(--border);
  border-radius:var(--radius-2xl);
  box-shadow:var(--shadow);
  z-index:var(--z-overlay);
  padding:var(--space-3) 0;
}
.nav-dropdown.open .nav-dropdown-menu{
  display:block;
}
.nav-dropdown-menu--right{
  left:auto;
  right:0;
}
.nav-user-toggle{
  color:var(--fg);
}
.nav-dropdown-item{
  display:block;
  width:100%;
  padding:9px var(--space-8);
  color:var(--fg);
  white-space:nowrap;
  /* reset for <button> */
  background:none;
  border:none;
  border-radius:0;
  text-align:left;
  cursor:pointer;
  font:inherit;
  box-sizing:border-box;
}
.nav-dropdown-item:hover{
  background:var(--card-2);
  text-decoration:none;
  filter:none;
}
.nav-dropdown-divider{
  border:none;
  border-top:1px solid var(--border);
  margin:var(--space-3) 0;
}

.card{
  background:var(--card);
  border:1px solid var(--border);
  border-radius:var(--radius-4xl);
  padding:var(--space-8);
  box-shadow:var(--shadow);
}
.card + .card{margin-top:var(--space-8)}

.table-wrap{
  overflow:auto;
  max-height:65vh;
  -webkit-overflow-scrolling:touch;
}
.diff-table{font-size:var(--font-size-base);border-collapse:collapse;width:auto;min-width:200px}
.diff-table th,.diff-table td{padding:3px var(--space-4);border:1px solid var(--border)}
.diff-table tr.diff-changed{background:var(--warn-bg, rgba(255,193,7,.12))}

tr.highlight{
  background:var(--warn-bg, rgba(255,193,7,.12));
  outline:2px solid var(--warn, #e6a817);
  outline-offset:-2px;
}

.toolbar{
  display:flex;
  gap:var(--space-6);
  flex-wrap:wrap;
  align-items:center;
  margin-bottom:var(--space-6);
}
.toolbar .spacer{margin-left:auto}

.page-actions{
  display:flex;
  gap:var(--space-5);
  flex-wrap:wrap;
  align-items:center;
  margin-top:var(--space-4);
}
.action-pill{
  display:inline-flex;
  align-items:center;
  gap:var(--space-3);
  padding:var(--space-5) var(--space-6);
  border-radius:var(--radius-2xl);
  background:var(--card-2);
  border:1px solid var(--border);
}
.action-pill:hover{
  text-decoration:none;
  filter:brightness(1.02);
}

.breadcrumbs{
  display:flex;
  flex-wrap:wrap;
  gap:var(--space-4);
  align-items:center;
  color:var(--muted);
  font-size:.94rem;
  margin-bottom:var(--space-5);
}
.breadcrumbs a{
  color:var(--link);
}
.breadcrumbs .sep{
  color:var(--muted);
}

.grid{
  display:grid;
  gap:var(--space-8);
  align-items:stretch;
}
.grid > .card{
  display:flex;
  flex-direction:column;
  margin-top:0;
}
.grid.cols-2{
  grid-template-columns:repeat(auto-fit,minmax(320px,1fr));
}
.grid.cols-3{
  grid-template-columns:repeat(auto-fit,minmax(240px,1fr));
}

.metric{
  background:var(--card);
  border:1px solid var(--border);
  border-radius:var(--radius-4xl);
  padding:var(--space-7) var(--space-8);
  box-shadow:var(--shadow);
}
.metric .label{color:var(--muted);font-size:var(--font-size-2xl)}
.metric .value{font-size:1.65rem;font-weight:700;margin-top:var(--space-3)}

table{
  border-collapse:collapse;
  width:100%;
  background:var(--card);
  border-radius:var(--radius-3xl);
  clip-path:inset(0 round 14px);
}
th,td{
  border:1px solid var(--border);
  padding:var(--space-5) var(--space-6);
  text-align:left;
  vertical-align:top;
}
th{
  background:var(--card-2);
  font-weight:600;
}
th a{color:inherit;text-decoration:none;white-space:nowrap}
th a:hover{text-decoration:underline}
th.sort-active{background:color-mix(in srgb,var(--card-2) 70%,var(--link) 30%)}
tbody tr:nth-child(even) td{
  background:color-mix(in srgb, var(--card) 88%, var(--bg) 12%);
}
tbody tr:hover td{
  background:color-mix(in srgb, var(--card-2) 65%, var(--bg) 35%);
}

.row{
  display:flex;
  gap:var(--space-6);
  flex-wrap:wrap;
  align-items:flex-end;
}
label{
  display:flex;
  flex-direction:column;
  gap:var(--space-3);
  font-size:var(--font-size-3xl);
}
input,select,textarea,button{
  font:inherit;
}
input:not([type="checkbox"]):not([type="radio"]):not([type="file"]),select{
  height:40px;
  padding:0 var(--space-6);
  border:1px solid var(--border-strong);
  border-radius:var(--radius-2xl);
  background:var(--input-bg);
  color:var(--fg);
  min-width:0;
  box-sizing:border-box;
}
/* #443: <select multiple> needs the size attribute to control row count
   instead of the default 40px height that single-selects use, otherwise
   the alert recipients picker collapses to a single row with a scrollbar. */
select[multiple]{
  height:auto;
  padding:var(--space-3) var(--space-4);
  line-height:1.4;
}
select[multiple] option{
  padding:var(--space-2) var(--space-3);
  border-radius:var(--radius-sm);
}
.settings-multi-actions{
  display:flex;
  align-items:center;
  flex-wrap:wrap;
  gap:0.25rem;
  margin-top:0.5rem;
}
textarea{
  padding:var(--space-5) var(--space-6);
  border:1px solid var(--border-strong);
  border-radius:var(--radius-2xl);
  background:var(--input-bg);
  color:var(--fg);
  min-width:0;
  min-height:100px;
  resize:vertical;
}
input:focus,select:focus,textarea:focus{
  outline:none;
  border-color:var(--link);
  box-shadow:0 0 0 3px color-mix(in srgb, var(--link) 22%, transparent);
}
button{
  padding:var(--space-5) var(--space-7);
  border:none;
  border-radius:var(--radius-2xl);
  background:var(--btn);
  color:var(--btnfg);
  cursor:pointer;
}
button:hover{filter:brightness(1.05)}
button:disabled{opacity:.6;cursor:not-allowed}
.button-secondary{
  background:var(--btn-secondary);
  color:var(--btn-secondary-fg);
}
.button-danger{
  background:var(--danger);
  color:#fff;
}

.recovery-banner{
  background:var(--danger);
  color:#fff;
  text-align:center;
  padding:var(--space-4) var(--space-8);
  font-weight:700;
  font-size:var(--font-size-xl);
  position:sticky;
  top:0;
  z-index:var(--z-spinner);
}
.recovery-banner code{
  background:rgba(255,255,255,.2);
  padding:var(--space-1) var(--space-3);
  border-radius:var(--radius-xs);
}

.muted{color:var(--muted)}
.danger{color:var(--danger)}
.success{color:var(--success)}
.warning{color:var(--warn)}
.badge{
  display:inline-block;
  padding:3px var(--space-5);
  border:1px solid var(--border);
  border-radius:var(--radius-pill);
  font-size:12px;
  background:var(--badge-bg);
}
.status-used{color:var(--success);font-weight:600}
.status-reserved{color:var(--warn);font-weight:600}
.status-free{color:var(--muted);font-weight:600}
.badge-network{background:color-mix(in srgb,var(--muted) 15%,var(--badge-bg) 85%);color:var(--muted);font-size:.7rem;padding:2px 6px}
.badge-muted{background:color-mix(in srgb,var(--muted) 10%,var(--badge-bg) 90%);color:var(--muted);border-color:color-mix(in srgb,var(--muted) 30%,var(--border) 70%)}
.badge-success{background:color-mix(in srgb,var(--success) 12%,var(--badge-bg) 88%);color:var(--success);border-color:color-mix(in srgb,var(--success) 35%,var(--border) 65%)}
.badge-broadcast{background:color-mix(in srgb,var(--warn) 15%,var(--badge-bg) 85%);color:var(--warn);font-size:.7rem;padding:2px 6px}
.badge-gateway{background:color-mix(in srgb,var(--link) 15%,var(--badge-bg) 85%);color:var(--link);font-size:.7rem;padding:2px 6px}
.audit-details{display:inline-block;max-width:300px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:bottom;cursor:pointer}
.audit-details.audit-details--expanded{max-width:none;white-space:normal;overflow-wrap:break-word;cursor:pointer}
.badge-role-admin{
  background:color-mix(in srgb,var(--danger) 12%,var(--badge-bg) 88%);
  color:var(--danger);
  border-color:color-mix(in srgb,var(--danger) 40%,var(--border) 60%);
}
.badge-role-netops{
  background:color-mix(in srgb,var(--link) 12%,var(--badge-bg) 88%);
  color:var(--link);
  border-color:color-mix(in srgb,var(--link) 40%,var(--border) 60%);
}
.badge-update{
  background:color-mix(in srgb,var(--warn) 12%,var(--badge-bg) 88%);
  color:var(--warn);
  border-color:color-mix(in srgb,var(--warn) 40%,var(--border) 60%);
}
/* Device type badges (v3.2.0) */
.badge-type-router{background:color-mix(in srgb,var(--link) 15%,var(--badge-bg) 85%);color:var(--link);border-color:color-mix(in srgb,var(--link) 40%,var(--border) 60%)}
.badge-type-switch{background:color-mix(in srgb,var(--success) 15%,var(--badge-bg) 85%);color:var(--success);border-color:color-mix(in srgb,var(--success) 40%,var(--border) 60%)}
.badge-type-server{background:color-mix(in srgb,var(--warn) 15%,var(--badge-bg) 85%);color:var(--warn);border-color:color-mix(in srgb,var(--warn) 40%,var(--border) 60%)}
.badge-type-vm{background:color-mix(in srgb,var(--muted) 25%,var(--badge-bg) 75%);color:var(--fg);border-color:var(--border)}
.badge-type-firewall{background:color-mix(in srgb,var(--danger) 15%,var(--badge-bg) 85%);color:var(--danger);border-color:color-mix(in srgb,var(--danger) 40%,var(--border) 60%)}
.badge-type-other{background:var(--badge-bg);color:var(--muted);border-color:var(--border)}
/* Compact nested table for device interfaces */
.table-compact td,.table-compact th{padding:4px var(--space-8);font-size:.85rem}
.device-ifaces h4{margin:0 0 var(--space-8);font-size:.875rem;font-weight:600;color:var(--muted)}
.util-bar{
  display:inline-block;
  width:60px;
  height:8px;
  background:var(--border);
  border-radius:var(--radius-xs);
  overflow:hidden;
  vertical-align:middle;
  margin-left:var(--space-2);
}
.util-bar-fill{
  display:block;
  height:100%;
  background:var(--success);
  border-radius:var(--radius-xs);
  transition:width .3s;
}
.util-bar-fill--warn{background:var(--warn)}
.util-bar-fill--crit{background:var(--danger)}

/* Site group collapse/expand */
.site-group-toggle{
  display:flex;
  align-items:center;
  width:100%;
  background:none;
  border:none;
  border-bottom:2px solid var(--border);
  padding:0 0 var(--space-3) 0;
  margin:0 0 var(--space-4) 0;
  cursor:pointer;
  font-size:1.05em;
  font-weight:600;
  color:var(--fg);
  text-align:left;
}
.site-group-toggle:hover{color:var(--link)}
.site-group-caret{
  margin-left:auto;
  font-size:.8em;
  transition:transform .15s ease;
  display:inline-block;
}
.site-group-toggle[aria-expanded="false"] .site-group-caret{transform:rotate(-90deg)}
.site-group-toggle[aria-expanded="false"]+.site-group-body{display:none}
.site-group-body{margin-left:var(--space-8)}

summary{
  cursor:pointer;
  padding:var(--space-2) 0;
}
details > summary{
  list-style:none;
}
details > summary::-webkit-details-marker{display:none}


.empty-state{
  padding:var(--space-9);
  border:1px dashed var(--border-strong);
  border-radius:var(--radius-4xl);
  color:var(--muted);
  background:color-mix(in srgb, var(--card) 80%, var(--bg) 20%);
}

.actions-inline{
  display:flex;
  flex-wrap:wrap;
  gap:var(--space-6);
  align-items:center;
}
.actions-inline a{
  display:inline-flex;
  align-items:center;
  padding:var(--space-3) var(--space-5);
  border-radius:var(--radius-xl);
  background:color-mix(in srgb, var(--card-2) 70%, transparent);
}
.actions-inline a:hover{
  background:var(--card-2);
  text-decoration:none;
}

.report-create{color:var(--success);font-weight:600}
.report-update{color:var(--link);font-weight:600}
.report-skip{color:var(--muted);font-weight:600}
.report-invalid{color:var(--danger);font-weight:600}
.report-needs-subnet{color:var(--warn);font-weight:600}

/* Admin notices (config updates, update-available banner) */
.admin-notice{
  display:flex;
  align-items:center;
  gap:var(--space-6);
  flex-wrap:wrap;
  padding:var(--space-5) var(--space-7);
  border-radius:var(--radius-2xl);
  margin-bottom:var(--space-7);
  border:1px solid var(--border);
  font-size:var(--font-size-3xl);
}
.admin-notice--info{
  background:color-mix(in srgb,var(--link) 8%,var(--card));
  border-color:color-mix(in srgb,var(--link) 30%,var(--border));
  color:var(--fg);
}
.admin-notice--update{
  background:color-mix(in srgb,var(--success) 8%,var(--card));
  border-color:color-mix(in srgb,var(--success) 30%,var(--border));
  color:var(--fg);
}
.admin-notice--danger{
  background:color-mix(in srgb,var(--danger) 8%,var(--card));
  border-color:color-mix(in srgb,var(--danger) 30%,var(--border));
  color:var(--fg);
}
.admin-notice--warning{
  background:color-mix(in srgb,var(--warn) 8%,var(--card));
  border-color:color-mix(in srgb,var(--warn) 40%,var(--border));
  color:var(--fg);
}
.admin-notice a{font-weight:600}
.admin-notice-dismiss{
  margin-left:auto;
  background:transparent;
  border:0;
  color:inherit;
  font-size:1.1em;
  cursor:pointer;
  padding:var(--space-1) var(--space-3);
  border-radius:var(--radius-md);
  opacity:.7;
}
.admin-notice-dismiss:hover{opacity:1;background:color-mix(in srgb,var(--fg) 10%,transparent)}

/* Scrollable table wrapper — wrap tables in this on narrow pages */
.table-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch}

/* Spacing / layout utility classes (replaces inline style="" attributes) */
.mt-6{margin-top:var(--space-3)}.mt-8{margin-top:var(--space-4)}.mt-10{margin-top:var(--space-5)}.mt-12{margin-top:var(--space-6)}
.mt-14{margin-top:var(--space-7)}.mt-16{margin-top:var(--space-8)}.mt-18{margin-top:18px}.mt-24{margin-top:var(--space-10)}
.mb-10{margin-bottom:var(--space-5)}.mb-12{margin-bottom:var(--space-6)}.mb-24{margin-bottom:var(--space-10)}
.ml-4{margin-left:var(--space-2)}.ml-12{margin-left:var(--space-6)}
.pb-6{padding-bottom:var(--space-3)}
.m-0{margin:0}
.label-inline{flex-direction:row;align-items:center;gap:var(--space-3)}
.gap-6{gap:var(--space-3)}.gap-8{gap:var(--space-4)}.gap-10{gap:var(--space-5)}.gap-12{gap:var(--space-6)}
.w-full{width:100%}.w-140{width:140px}.w-160{width:160px}.w-220{width:220px}
.mw-90{min-width:90px}.mw-140{min-width:140px}.mw-160{min-width:160px}.mw-200{min-width:200px}
.mw-220{min-width:220px}.mw-260{min-width:260px}.mw-420{min-width:420px}
.d-flex{display:flex}.d-inline{display:inline}.hidden{display:none}
.flex-1{flex:1}.flex-self-end{align-self:flex-end}
.flex-col{display:flex;flex-direction:column}
.flex-wrap{flex-wrap:wrap}
.align-center{align-items:center}
.text-center{text-align:center}
.fw-600{font-weight:600}
.cursor-pointer{cursor:pointer}
.nowrap{white-space:nowrap}
.opacity-70{opacity:.7}
.font-sm{font-size:.9em}
.font-xs{font-size:.85em;font-weight:400}
.pre-wrap{white-space:pre-wrap;margin:0}
.list-indent{margin:0 0 var(--space-6);padding-left:1.4em}
.key-display{word-break:break-all;font-size:var(--font-size-5xl)}
.link-plain{color:inherit;text-decoration:none}
/* SSO button and local-auth separator on login page */
.btn-sso{display:inline-block;padding:var(--space-5) 18px;border-radius:var(--radius-2xl);background:var(--btn);color:var(--btnfg);text-decoration:none;font-weight:600}
.sso-sep{margin:var(--space-7) 0 var(--space-2)}
/* Small button variant for inline admin-notice actions */
.btn-sm{padding:var(--space-2) var(--space-5);font-size:.85em}
/* New-key success card highlight */
.card--success{border-color:var(--success)}
/* Security warning banner */
.security-banner{display:flex;align-items:center;justify-content:space-between;gap:var(--space-6);flex-wrap:wrap;
  padding:var(--space-5) var(--space-7);margin-bottom:var(--space-8);border-radius:var(--radius-md);border:1px solid color-mix(in srgb,var(--warn) 40%,var(--border) 60%);
  background:color-mix(in srgb,var(--warn) 8%,var(--card) 92%);font-size:.9em}
.security-banner a.dismiss-link{white-space:nowrap;color:var(--muted);text-decoration:none;font-size:.85em}
.security-banner a.dismiss-link:hover{text-decoration:underline}
/* Footer metadata bar */
.footer-meta{display:flex;align-items:center;gap:var(--space-5);flex-wrap:wrap;max-width:1280px;margin:0 auto;padding:var(--space-5) var(--space-9)}
.footer-meta img{height:24px;width:auto;flex-shrink:0}
/* Full-width utilization bar (dashboard top-subnets table) */
.util-bar-block{background:var(--border);border-radius:var(--radius-sm);height:8px;overflow:hidden}
.util-bar-block>.util-bar-fill{border-radius:0;width:0}
/* Dynamic utilization bar fill — width set via data-pct attribute in app.js */
.util-bar-fill[data-pct]{width:0}
/* Subnet hierarchy node (indent is set dynamically via data-indent in app.js) */
.subnet-node{margin-top:var(--space-4)}
/* Demo gate standalone page */
.gate-wrap{max-width:480px;margin:var(--space-13) auto;padding:0 var(--space-8)}

/* Highlight row — used when linking to a specific address row */
.highlight-row{animation:highlight-fade 3s ease-out}
@keyframes highlight-fade{from{background:var(--warn)}to{background:inherit}}

/* Expired address row */
.expired-row td{background:rgba(176,0,32,.06)}
html[data-theme=dark] .expired-row td{background:rgba(255,80,80,.08)}
@media(prefers-color-scheme:dark){html:not([data-theme=light]) .expired-row td{background:rgba(255,80,80,.08)}}

/* DHCP pool inline-edit form */
.dhcp-edit-form{display:flex;gap:var(--space-4);flex-wrap:wrap;align-items:flex-end}
.dhcp-edit-form .ip-label{font-weight:600;align-self:center}
.dhcp-edit-form label{display:flex;flex-direction:column;font-size:var(--font-size-base)}
.dhcp-edit-form .btn-group{align-self:flex-end;display:flex;gap:var(--space-3)}
.dhcp-range-header td{font-size:var(--font-size-md);padding:var(--space-2) var(--space-3);background:var(--card)}
.d-inline-form{display:inline}

/* Mobile — 768px breakpoint */
@media (max-width: 768px){
  .page{padding:var(--space-7)}
  .footer-meta{padding:var(--space-4) var(--space-7)}
  .nav-wrap{
    padding:var(--space-5) var(--space-7);
    gap:var(--space-4);
  }
  .nav-links{gap:var(--space-3)}
  .nav-pill{padding:7px 9px;font-size:var(--font-size-2xl)}
  th,td{padding:var(--space-4) var(--space-5);font-size:var(--font-size-xl)}
  h1{font-size:1.45rem}
  h2{font-size:var(--font-size-6xl)}
  .grid.cols-2,.grid.cols-3{
    grid-template-columns:1fr;
  }
  .metric .value{font-size:var(--font-size-7xl)}
  .row{flex-direction:column;align-items:stretch}
  .row > *{width:100%}
  .toolbar{flex-direction:column;align-items:stretch}
  .toolbar .spacer{display:none}
  .page-actions{flex-direction:column;align-items:stretch}
  table{font-size:var(--font-size-lg)}
  /* Prevent nav-right from jumping to new row; keep it inline */
  .nav-right{margin-left:auto}
  /* Reduce subnet tree indentation on small screens */
  .subnet-node{margin-left:0 !important;padding-left:var(--space-4);border-left:2px solid var(--border)}
}

/* Mobile — 480px breakpoint (small phones) */
@media (max-width: 480px){
  .page{padding:var(--space-5)}
  .footer-meta{padding:var(--space-3) var(--space-5)}
  .nav-wrap{padding:var(--space-4) var(--space-5)}
  .nav-pill{padding:var(--space-3) var(--space-4);font-size:var(--font-size-lg)}
  h1{font-size:1.25rem}
  .card{padding:var(--space-6)}
  .metric{padding:var(--space-5) var(--space-6)}
  th,td{padding:var(--space-3) var(--space-4);font-size:var(--font-size-base)}
}

/* Import spinner overlay */
.spinner-overlay{
  position:fixed;top:0;left:0;width:100%;height:100%;
  background:rgba(0,0,0,.55);z-index:var(--z-page-overlay);
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  color:#fff;font-size:1.2rem;gap:var(--space-8);
}
.spinner-overlay .spinner{
  width:48px;height:48px;border:5px solid rgba(255,255,255,.3);
  border-top-color:#fff;border-radius:50%;
  animation:spin .8s linear infinite;
}
@keyframes spin{to{transform:rotate(360deg)}}

/* ---- Inline checkbox label (used in forms alongside other inputs) ---- */
.row-inline{display:flex;align-items:center;gap:var(--space-3);font-size:var(--font-size-xl);cursor:pointer;padding-bottom:var(--space-3);}
.row-inline input[type=checkbox]{width:16px;height:16px;cursor:pointer;flex-shrink:0;}

/* ---- settings.php row header (v2.7.0) ----
   .setting-head is the title line above an input: label text + source badge
   + key <code>. .setting-head--bool wraps the checkbox on the same line
   as the label so bool settings render inline with the control they toggle
   (see GitHub issue #441). Explicit flex-direction:row overrides the global
   `label { display:flex; flex-direction:column }` rule above, which would
   otherwise stack the checkbox and label on separate rows. */
.setting-head{display:flex;flex-direction:row;align-items:baseline;flex-wrap:wrap;gap:.25rem;margin-bottom:.25rem;}
label.setting-head{font-size:inherit;}
.setting-head--bool{cursor:pointer;align-items:center;}
.setting-head--bool input[type=checkbox]{margin:0 .25rem 0 0;flex-shrink:0;}

/* ---- Sticky table headers (#248, #342, #351, #352) ---- */
/* .table-wrap is the scroll container (overflow:auto; max-height:65vh).
   position:sticky on thead th with top:0 sticks the header to the top of the
   table-wrap scrollport. z-index:2 ensures th cells paint above tbody rows. */
thead th{position:sticky;top:0;z-index:var(--z-sticky);background:var(--card-2)}

/* ---- Mobile hamburger nav (#250) ---- */
.nav-toggle{
  display:none;
  background:none;border:none;cursor:pointer;
  font-size:1.4rem;color:var(--fg);padding:var(--space-2) var(--space-4);
  line-height:1;flex-shrink:0;
}
#nav-drawer{
  position:fixed;top:0;right:0;bottom:0;width:280px;max-width:90vw;
  background:var(--card);border-left:1px solid var(--border);
  z-index:var(--z-nav-drawer);overflow-y:auto;
  transform:translateX(100%);transition:transform .22s ease;
  display:flex;flex-direction:column;gap:0;padding:var(--space-8) 0;
  visibility:hidden;pointer-events:none;
}
body.nav-open #nav-drawer{transform:translateX(0);visibility:visible;pointer-events:auto}
.nav-drawer-overlay{
  display:none;position:fixed;inset:0;background:rgba(0,0,0,.35);z-index:var(--z-nav-overlay);
}
body.nav-open .nav-drawer-overlay{display:block}
#nav-drawer .drawer-close{
  align-self:flex-end;background:none;border:none;cursor:pointer;
  font-size:1.2rem;color:var(--muted);padding:var(--space-2) var(--space-8) var(--space-6);
}
#nav-drawer a,#nav-drawer button.nav-drawer-btn{
  display:block;width:100%;text-align:left;background:none;border:none;cursor:pointer;
  color:var(--fg);padding:var(--space-5) var(--space-9);font-size:var(--font-size-4xl);text-decoration:none;
  border-radius:0;
}
#nav-drawer a:hover,#nav-drawer button.nav-drawer-btn:hover{background:var(--card-2)}
#nav-drawer .nav-drawer-section{padding:var(--space-2) var(--space-9);font-size:var(--font-size-sm);font-weight:700;
  color:var(--muted);text-transform:uppercase;letter-spacing:.05em;margin-top:var(--space-4)}
#nav-drawer hr{border:none;border-top:1px solid var(--border);margin:var(--space-3) 0}
@media(max-width:600px){
  .nav-links{display:none}
  .nav-toggle{display:block}
}

/* ---- Inline status badge (#252) ---- */
.status-badge{display:inline-block;cursor:default}
.status-badge[data-addr-id]{cursor:pointer;user-select:none}
.status-badge[data-addr-id]:hover{opacity:.8;text-decoration:underline}
.status-badge.status-used{color:var(--success)}
.status-badge.status-reserved{color:var(--warn)}
.status-badge.status-free{color:var(--muted)}

/* ---- Slide-in form drawer (#247) ---- */
#form-drawer{
  position:fixed;top:0;right:0;bottom:0;width:440px;max-width:95vw;
  background:var(--card);border-left:1px solid var(--border);
  z-index:var(--z-drawer);overflow-y:auto;padding:var(--space-10);
  transform:translateX(100%);transition:transform .22s ease;
  display:flex;flex-direction:column;gap:var(--space-8);
  visibility:hidden;pointer-events:none;
}
#form-drawer.drawer--open{transform:translateX(0);visibility:visible;pointer-events:auto}
.form-drawer-overlay{
  display:none;position:fixed;inset:0;background:rgba(0,0,0,.25);z-index:var(--z-drawer-overlay);
}
.form-drawer-overlay.visible{display:block}
#form-drawer .drawer-header{
  display:flex;align-items:center;justify-content:space-between;
  border-bottom:1px solid var(--border);padding-bottom:var(--space-6);
}
#form-drawer .drawer-title{margin:0;font-size:var(--font-size-6xl);font-weight:700}
#form-drawer .drawer-close-btn{
  background:none;border:none;cursor:pointer;font-size:1.3rem;
  color:var(--muted);padding:var(--space-1) var(--space-3);
}
.drawer-form-card{display:none}
body.drawer-ready .drawer-form-card{display:none}
@media(max-width:600px){
  #form-drawer{width:100vw;top:auto;height:85vh;transform:translateY(100%)}
  #form-drawer.drawer--open{transform:translateY(0)}
}

/* ---- Tag badges ---- */
.tag-badge{
  display:inline-block;padding:var(--space-1) var(--space-4);border-radius:var(--radius-xl);
  font-size:var(--font-size-sm);font-weight:600;color:#fff;white-space:nowrap;
}
/* Darken text when badge is light-coloured (handled via inline style; default white) */
.tag-picker{display:flex;flex-wrap:wrap;gap:var(--space-3);margin:var(--space-2) 0;}
.tag-picker label{display:flex;align-items:center;gap:var(--space-2);cursor:pointer;font-size:var(--font-size-base);}
.tag-picker input[type=checkbox]{width:14px;height:14px;cursor:pointer;}


/* ---- Contact typeahead suggestions ---- */
.contact-suggestions{
  position:absolute;z-index:var(--z-nav-drawer);top:100%;left:0;right:0;
  background:var(--card);border:1px solid var(--border);border-radius:var(--radius-sm);
  margin:0;padding:0;list-style:none;max-height:200px;overflow-y:auto;
  box-shadow:0 4px 12px rgba(0,0,0,.15);
}
.contact-suggestions li{
  padding:7px var(--space-5);cursor:pointer;font-size:var(--font-size-xl);
  border-bottom:1px solid var(--border);
}
.contact-suggestions li:last-child{border-bottom:none}
.contact-suggestions li:hover{background:var(--btn);color:var(--btnfg);}

/* ---- ⌘K / Ctrl+K search overlay (#253) ---- */
#search-overlay{
  display:none;position:fixed;inset:0;z-index:var(--z-col-vis);
  background:rgba(0,0,0,.45);align-items:flex-start;justify-content:center;
  padding-top:12vh;
}
#search-overlay.visible{display:flex;}
.so-box{
  width:min(640px,94vw);background:var(--card);border:1px solid var(--border);
  border-radius:var(--radius-lg);box-shadow:0 8px 32px rgba(0,0,0,.3);overflow:hidden;
}
#search-overlay-input{
  display:block;width:100%;box-sizing:border-box;
  padding:var(--space-7) var(--space-12) var(--space-7) var(--space-8);font-size:1.1rem;
  background:var(--card);color:var(--fg);border:none;border-bottom:1px solid var(--border);
  outline:none;
}
.so-close{
  position:absolute;right:10px;top:10px;background:none;border:none;
  font-size:1.4rem;cursor:pointer;color:var(--muted);line-height:1;
}
.so-box{position:relative;}
#search-overlay-list{
  list-style:none;margin:0;padding:0;max-height:320px;overflow-y:auto;
}
.so-item{
  padding:var(--space-5) var(--space-7);cursor:pointer;border-bottom:1px solid var(--border);
  display:flex;align-items:center;gap:var(--space-4);font-size:var(--font-size-3xl);
}
.so-item:last-child{border-bottom:none}
.so-item:hover,.so-item.active{background:var(--btn);color:var(--btnfg);}
.so-item:hover .so-status,.so-item.active .so-status{
  background:rgba(255,255,255,.2);color:inherit;
}
.so-ip{font-weight:600;font-family:monospace;font-size:var(--font-size-4xl);}
.so-host{color:var(--muted);font-size:var(--font-size-lg);}
.so-item:hover .so-host,.so-item.active .so-host{color:inherit;opacity:.8;}
.so-status{font-size:var(--font-size-sm);padding:1px 6px;border-radius:var(--radius-xs);margin-left:auto;}
.so-loading,.so-empty{
  padding:var(--space-7) var(--space-8);color:var(--muted);text-align:center;font-size:var(--font-size-2xl);
}
.so-hint{
  padding:var(--space-3) var(--space-7);font-size:var(--font-size-sm);color:var(--muted);
  border-top:1px solid var(--border);text-align:right;
}
.so-hint kbd{
  background:var(--border);border-radius:var(--radius-xs);padding:1px 4px;font-size:var(--font-size-xs);
}
/* ---- Dashboard widgets (#257) ---- */
.widget-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--space-3);}
.widget-header h2{margin:0;}
.widget-hide-btn{
  background:none;border:none;cursor:pointer;color:var(--muted);
  font-size:var(--font-size-4xl);padding:var(--space-1) var(--space-3);border-radius:var(--radius-sm);line-height:1;
}
.widget-hide-btn:hover{background:var(--border);color:var(--fg);}

/* ---- Column visibility (#256) ---- */
.col-hidden{display:none;}
.col-vis-wrap{position:relative;display:inline-block;}
.col-vis-gear{font-size:var(--font-size-md);}
.col-vis-drop{
  display:none;position:absolute;right:0;top:100%;z-index:var(--z-dropdown);
  background:var(--card);border:1px solid var(--border);border-radius:var(--radius-md);
  padding:var(--space-4) var(--space-6);min-width:140px;box-shadow:0 4px 12px rgba(0,0,0,.15);
}
.col-vis-drop.visible{display:block;}
.col-vis-drop label{display:flex;align-items:center;gap:var(--space-3);padding:3px 0;cursor:pointer;font-size:var(--font-size-lg);white-space:nowrap;}

/* ---- Subnet map view (#255) ---- */
.subnet-view-btn{margin-left:var(--space-2);}
.subnet-view-btn.active{background:var(--btn);color:var(--btnfg);font-weight:600;}
.map-group{border-left:2px solid var(--border);padding-left:var(--space-5);margin-bottom:var(--space-9);}
.map-group-label{font-weight:600;margin-bottom:var(--space-4);color:var(--muted);}
.map-node{position:relative;}
.map-node-inner{
  display:flex;align-items:center;gap:var(--space-5);flex-wrap:wrap;
  padding:var(--space-2) var(--space-3);border-radius:var(--radius-sm);margin-bottom:3px;
  border-left:2px solid var(--border);
}
.map-node-inner:hover{background:rgba(0,0,0,.04);}
html[data-theme=dark] .map-node-inner:hover{background:rgba(255,255,255,.06);}
.map-cidr{font-weight:600;font-family:monospace;}
.map-desc{font-size:var(--font-size-base);flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.map-util{display:flex;align-items:center;gap:5px;margin-left:auto;}
.map-util .util-bar{width:60px;}
.map-pct{font-size:.8rem;min-width:30px;}
.map-cap{padding:var(--space-4) var(--space-6);color:var(--muted);font-style:italic;font-size:var(--font-size-xl);}

/* ---- Inline cell editing (#254) ---- */
td[data-editable]:hover{background:var(--btn);color:var(--btnfg);border-radius:var(--radius-xs);}
td[data-editable].cell-saving{opacity:.5;}
.inline-edit-input{
  width:100%;box-sizing:border-box;padding:var(--space-1) var(--space-2);font:inherit;
  background:var(--bg);color:var(--fg);border:1px solid var(--btn);border-radius:var(--radius-xs);
  outline:none;
}

.nav-kbd{
  font-size:var(--font-size-2xs);padding:1px 5px;
  border:1px solid currentColor;border-radius:var(--radius-xs);
  opacity:.55;vertical-align:middle;margin-left:var(--space-2);
  font-family:inherit;pointer-events:none;
}
.nav-search-link:hover .nav-kbd{opacity:.85;}

/* ── Tooltips (#354) ─────────────────────────────────────────────────────── */
/* JS renders a single shared #ipam-tooltip div at position:fixed so it is
   never clipped by overflow:hidden/clip on ancestor containers (.table-wrap). */
[data-tooltip]{ cursor:help; }
#ipam-tooltip{
  display:block;
  position:fixed;
  z-index:var(--z-toast);
  visibility:hidden;
  opacity:0;
  transition:opacity .15s;
  background:var(--fg);
  color:var(--bg);
  font-size:var(--font-size-sm);
  line-height:1.4;
  white-space:normal;
  max-width:240px;
  padding:5px 9px;
  border-radius:var(--radius-sm);
  text-align:center;
  pointer-events:none;
}
#ipam-tooltip.visible{
  visibility:visible;
  opacity:1;
}

/* ── Subnet stats placeholder (#565) ────────────────────────────────────── */
.subnet-stats-placeholder{display:inline-block;min-width:180px;height:1em;border-radius:var(--radius-xs);background:linear-gradient(90deg,var(--card-2) 25%,var(--border) 50%,var(--card-2) 75%);background-size:200% 100%;animation:shimmer 1.5s ease-in-out infinite}
@media(prefers-reduced-motion:reduce){.subnet-stats-placeholder{animation:none}}

/* ── Contact card popover (#561) ─────────────────────────────────────────── */
#contact-card{
  display:none;
  position:fixed;
  z-index:var(--z-dropdown);
  background:var(--card);
  border:1px solid var(--border);
  border-radius:var(--radius-sm);
  box-shadow:0 4px 16px rgba(0,0,0,.18);
  padding:var(--space-6) 34px var(--space-6) var(--space-7);
  max-width:320px;
  min-width:200px;
  font-size:var(--font-size-base);
  line-height:1.5;
}
#contact-card.visible{display:block}
.cc-name{font-weight:700;font-size:var(--font-size-xl);margin-bottom:var(--space-2)}
.cc-row{color:var(--muted);margin-top:var(--space-1);overflow-wrap:break-word}
.cc-row a{color:var(--link)}
.cc-label{font-weight:600;color:var(--fg);margin-right:var(--space-2)}
.contact-card-trigger{cursor:pointer}
.cc-close{position:absolute;top:var(--space-2);right:var(--space-2);background:none;border:none;cursor:pointer;font-size:1.1rem;color:var(--muted);border-radius:var(--radius-sm);width:28px;height:28px;display:flex;align-items:center;justify-content:center;line-height:1;transition:color .15s,background .15s}
.cc-close:hover{color:var(--fg);background:color-mix(in srgb,var(--fg) 8%,transparent)}
.cc-close:focus-visible{outline:2px solid var(--link);outline-offset:2px}

/* ── Contact browse overlay (#562) ──────────────────────────────────────── */
.contact-browse-btn{
  background:var(--card);border:1px solid var(--border);border-radius:var(--radius-sm);
  cursor:pointer;padding:var(--space-1) var(--space-4);font-size:var(--font-size-sm);
  color:var(--link);vertical-align:middle;margin-left:var(--space-2);
}
.contact-browse-btn:hover{background:var(--btn);color:var(--btnfg)}
#contact-browse-overlay{
  display:none;position:fixed;inset:0;z-index:var(--z-col-vis);
  background:rgba(0,0,0,.45);align-items:flex-start;justify-content:center;
  padding-top:12vh;
}
#contact-browse-overlay.visible{display:flex}
.cb-box{
  width:min(480px,94vw);background:var(--card);border:1px solid var(--border);
  border-radius:var(--radius-lg);box-shadow:0 8px 32px rgba(0,0,0,.3);overflow:hidden;
  position:relative;
}
.cb-close{
  position:absolute;right:10px;top:10px;background:none;border:none;
  font-size:1.4rem;cursor:pointer;color:var(--muted);line-height:1;z-index:1;
}
#contact-browse-input{
  display:block;width:100%;box-sizing:border-box;
  padding:var(--space-7) var(--space-12) var(--space-7) var(--space-8);font-size:1rem;
  background:var(--card);color:var(--fg);border:none;border-bottom:1px solid var(--border);outline:none;
}
#contact-browse-list{list-style:none;margin:0;padding:0;max-height:360px;overflow-y:auto}
.cb-item{padding:var(--space-5) var(--space-7);cursor:pointer;border-bottom:1px solid var(--border)}
.cb-item:last-child{border-bottom:none}
.cb-item:hover,.cb-item.active{background:var(--btn);color:var(--btnfg)}
.cb-item-name{font-weight:600}
.cb-item-meta{font-size:var(--font-size-sm);color:var(--muted)}
.cb-item:hover .cb-item-meta,.cb-item.active .cb-item-meta{color:inherit;opacity:.8}
.cb-empty{padding:var(--space-7) var(--space-8);color:var(--muted);text-align:center}


/* ---- CSP-safe utility classes (replaces JS inline style assignments) ---- */
.hidden{display:none !important;}
.d-inline{display:inline;}
.badge--success{background:var(--success);color:#fff;}
.card--warn{border-left:4px solid var(--warn);}
.th-sortable{cursor:pointer;}

/* Contact typeahead: parent needs position:relative for absolute dropdown */
.contact-typeahead-wrap{position:relative;}

/* Form visible inside drawer (overrides body.drawer-ready .drawer-form-card{display:none}) */
#form-drawer-body .drawer-form-card{display:block;}

/* Utilization bar widths via data-pct attribute (replaces JS el.style.width) */
.util-bar-fill[data-pct="0"]{width:0%}
.util-bar-fill[data-pct="1"]{width:1%}
.util-bar-fill[data-pct="2"]{width:2%}
.util-bar-fill[data-pct="3"]{width:3%}
.util-bar-fill[data-pct="4"]{width:4%}
.util-bar-fill[data-pct="5"]{width:5%}
.util-bar-fill[data-pct="6"]{width:6%}
.util-bar-fill[data-pct="7"]{width:7%}
.util-bar-fill[data-pct="8"]{width:8%}
.util-bar-fill[data-pct="9"]{width:9%}
.util-bar-fill[data-pct="10"]{width:10%}
.util-bar-fill[data-pct="11"]{width:11%}
.util-bar-fill[data-pct="12"]{width:12%}
.util-bar-fill[data-pct="13"]{width:13%}
.util-bar-fill[data-pct="14"]{width:14%}
.util-bar-fill[data-pct="15"]{width:15%}
.util-bar-fill[data-pct="16"]{width:16%}
.util-bar-fill[data-pct="17"]{width:17%}
.util-bar-fill[data-pct="18"]{width:18%}
.util-bar-fill[data-pct="19"]{width:19%}
.util-bar-fill[data-pct="20"]{width:20%}
.util-bar-fill[data-pct="21"]{width:21%}
.util-bar-fill[data-pct="22"]{width:22%}
.util-bar-fill[data-pct="23"]{width:23%}
.util-bar-fill[data-pct="24"]{width:24%}
.util-bar-fill[data-pct="25"]{width:25%}
.util-bar-fill[data-pct="26"]{width:26%}
.util-bar-fill[data-pct="27"]{width:27%}
.util-bar-fill[data-pct="28"]{width:28%}
.util-bar-fill[data-pct="29"]{width:29%}
.util-bar-fill[data-pct="30"]{width:30%}
.util-bar-fill[data-pct="31"]{width:31%}
.util-bar-fill[data-pct="32"]{width:32%}
.util-bar-fill[data-pct="33"]{width:33%}
.util-bar-fill[data-pct="34"]{width:34%}
.util-bar-fill[data-pct="35"]{width:35%}
.util-bar-fill[data-pct="36"]{width:36%}
.util-bar-fill[data-pct="37"]{width:37%}
.util-bar-fill[data-pct="38"]{width:38%}
.util-bar-fill[data-pct="39"]{width:39%}
.util-bar-fill[data-pct="40"]{width:40%}
.util-bar-fill[data-pct="41"]{width:41%}
.util-bar-fill[data-pct="42"]{width:42%}
.util-bar-fill[data-pct="43"]{width:43%}
.util-bar-fill[data-pct="44"]{width:44%}
.util-bar-fill[data-pct="45"]{width:45%}
.util-bar-fill[data-pct="46"]{width:46%}
.util-bar-fill[data-pct="47"]{width:47%}
.util-bar-fill[data-pct="48"]{width:48%}
.util-bar-fill[data-pct="49"]{width:49%}
.util-bar-fill[data-pct="50"]{width:50%}
.util-bar-fill[data-pct="51"]{width:51%}
.util-bar-fill[data-pct="52"]{width:52%}
.util-bar-fill[data-pct="53"]{width:53%}
.util-bar-fill[data-pct="54"]{width:54%}
.util-bar-fill[data-pct="55"]{width:55%}
.util-bar-fill[data-pct="56"]{width:56%}
.util-bar-fill[data-pct="57"]{width:57%}
.util-bar-fill[data-pct="58"]{width:58%}
.util-bar-fill[data-pct="59"]{width:59%}
.util-bar-fill[data-pct="60"]{width:60%}
.util-bar-fill[data-pct="61"]{width:61%}
.util-bar-fill[data-pct="62"]{width:62%}
.util-bar-fill[data-pct="63"]{width:63%}
.util-bar-fill[data-pct="64"]{width:64%}
.util-bar-fill[data-pct="65"]{width:65%}
.util-bar-fill[data-pct="66"]{width:66%}
.util-bar-fill[data-pct="67"]{width:67%}
.util-bar-fill[data-pct="68"]{width:68%}
.util-bar-fill[data-pct="69"]{width:69%}
.util-bar-fill[data-pct="70"]{width:70%}
.util-bar-fill[data-pct="71"]{width:71%}
.util-bar-fill[data-pct="72"]{width:72%}
.util-bar-fill[data-pct="73"]{width:73%}
.util-bar-fill[data-pct="74"]{width:74%}
.util-bar-fill[data-pct="75"]{width:75%}
.util-bar-fill[data-pct="76"]{width:76%}
.util-bar-fill[data-pct="77"]{width:77%}
.util-bar-fill[data-pct="78"]{width:78%}
.util-bar-fill[data-pct="79"]{width:79%}
.util-bar-fill[data-pct="80"]{width:80%}
.util-bar-fill[data-pct="81"]{width:81%}
.util-bar-fill[data-pct="82"]{width:82%}
.util-bar-fill[data-pct="83"]{width:83%}
.util-bar-fill[data-pct="84"]{width:84%}
.util-bar-fill[data-pct="85"]{width:85%}
.util-bar-fill[data-pct="86"]{width:86%}
.util-bar-fill[data-pct="87"]{width:87%}
.util-bar-fill[data-pct="88"]{width:88%}
.util-bar-fill[data-pct="89"]{width:89%}
.util-bar-fill[data-pct="90"]{width:90%}
.util-bar-fill[data-pct="91"]{width:91%}
.util-bar-fill[data-pct="92"]{width:92%}
.util-bar-fill[data-pct="93"]{width:93%}
.util-bar-fill[data-pct="94"]{width:94%}
.util-bar-fill[data-pct="95"]{width:95%}
.util-bar-fill[data-pct="96"]{width:96%}
.util-bar-fill[data-pct="97"]{width:97%}
.util-bar-fill[data-pct="98"]{width:98%}
.util-bar-fill[data-pct="99"]{width:99%}
.util-bar-fill[data-pct="100"]{width:100%}

/* Subnet list-view node indentation via data-indent (step 28px, depth 0–15) */
.subnet-node[data-indent="0"]{margin-left:0}
.subnet-node[data-indent="28"]{margin-left:28px}
.subnet-node[data-indent="56"]{margin-left:56px}
.subnet-node[data-indent="84"]{margin-left:84px}
.subnet-node[data-indent="112"]{margin-left:112px}
.subnet-node[data-indent="140"]{margin-left:140px}
.subnet-node[data-indent="168"]{margin-left:168px}
.subnet-node[data-indent="196"]{margin-left:196px}
.subnet-node[data-indent="224"]{margin-left:224px}
.subnet-node[data-indent="252"]{margin-left:252px}
.subnet-node[data-indent="280"]{margin-left:280px}
.subnet-node[data-indent="308"]{margin-left:308px}
.subnet-node[data-indent="336"]{margin-left:336px}
.subnet-node[data-indent="364"]{margin-left:364px}
.subnet-node[data-indent="392"]{margin-left:392px}
.subnet-node[data-indent="420"]{margin-left:420px}

/* Subnet map-view node indentation via data-indent (step 22px, depth 0–15) */
.map-node-inner[data-indent="0"]{margin-left:0}
.map-node-inner[data-indent="22"]{margin-left:22px}
.map-node-inner[data-indent="44"]{margin-left:44px}
.map-node-inner[data-indent="66"]{margin-left:66px}
.map-node-inner[data-indent="88"]{margin-left:88px}
.map-node-inner[data-indent="110"]{margin-left:110px}
.map-node-inner[data-indent="132"]{margin-left:132px}
.map-node-inner[data-indent="154"]{margin-left:154px}
.map-node-inner[data-indent="176"]{margin-left:176px}
.map-node-inner[data-indent="198"]{margin-left:198px}
.map-node-inner[data-indent="220"]{margin-left:220px}
.map-node-inner[data-indent="242"]{margin-left:242px}
.map-node-inner[data-indent="264"]{margin-left:264px}
.map-node-inner[data-indent="286"]{margin-left:286px}
.map-node-inner[data-indent="308"]{margin-left:308px}

/* --- #449: password show/hide eye-icon button --- */
/* Wraps a sensitive <input> + sibling .pw-toggle button. The button sits
   inside the right edge of the input; the input reserves padding-right so
   the typed value doesn't slide under the icon. The 36px right offset
   leaves room for password manager icons (1Password, Bitwarden) which
   paint at right:0–8px. */
.pw-wrap{position:relative;display:block}
.pw-wrap .pw-input{padding-right:76px}
.pw-toggle{position:absolute;right:36px;top:50%;transform:translateY(-50%);background:transparent;border:0;padding:var(--space-2);margin:0;cursor:pointer;color:var(--muted);display:inline-flex;align-items:center;justify-content:center;border-radius:var(--radius-sm)}
.pw-toggle:hover,.pw-toggle:focus{color:var(--fg);outline:none}
.pw-toggle:focus-visible{box-shadow:var(--focus-ring)}
.pw-eye{display:inline-block;vertical-align:middle}
.pw-eye--closed{display:none}
.pw-toggle[aria-pressed="true"] .pw-eye--open{display:none}
.pw-toggle[aria-pressed="true"] .pw-eye--closed{display:inline-block}
body.pw-toggle-hidden .pw-toggle{display:none}
/* CodeRabbit m3 (PR #450): keep right padding when the IPAM eye is hidden so
   the password manager icon at right:0-8px is not crowded against the typed
   value. The eye reservation drops from 76px (eye + PM icon) to 36px (PM
   icon only), not all the way to 8px. */
body.pw-toggle-hidden .pw-wrap .pw-input{padding-right:36px}

/* --- #317: keyboard shortcut hint badge --- */
.kbd-hint{display:inline-block;margin-left:0.4em;padding:0 0.35em;border:1px solid var(--border);border-radius:var(--radius-xs);font:0.78em/1.4 ui-monospace,Menlo,monospace;color:var(--muted);background:transparent;vertical-align:middle}

/* --- #507: loading state on POST form submit --- */
.button-loading{min-width:80px;position:relative;color:transparent !important}
.button-loading::after{content:"";position:absolute;left:50%;top:50%;width:16px;height:16px;margin:-8px 0 0 -8px;border:2px solid currentcolor;border-top-color:transparent;border-radius:50%;animation:spin .6s linear infinite}

/* --- #508: skeleton loaders for slow tables --- */
.skeleton-shell{padding:var(--space-8) 0}
.skeleton-row{height:18px;margin:var(--space-6) 0;border-radius:var(--radius-sm);background:linear-gradient(90deg,var(--card-2) 25%,var(--border) 50%,var(--card-2) 75%);background-size:200% 100%;animation:shimmer 1.5s ease-in-out infinite}
.skeleton-row:nth-child(odd){width:90%}
.skeleton-row:nth-child(even){width:70%}
@keyframes shimmer{0%{background-position:200% 0}100%{background-position:-200% 0}}

/* --- #509: monospace font for IP/CIDR/MAC columns --- */
.ip-cell{font-family:var(--font-mono);font-variant-numeric:tabular-nums}
.ip-badge{font-family:var(--font-mono);font-size:var(--font-size-base)}
.monospace{font-family:var(--font-mono)}

/* Contact picker (v3.0.0 #563) */
.contact-badge{background:var(--badge-bg);font-size:.85em;padding:2px 8px;border-radius:4px;white-space:nowrap}
.contact-badges{display:flex;flex-wrap:wrap;gap:4px}
.contact-picker-row{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.contact-picker-row select{min-width:200px}
.contact-picker-remove{min-width:32px;min-height:32px;padding:0;line-height:1}

/* --- prefers-reduced-motion: suppress all animations/transitions --- */
@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:0.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:0.01ms !important;
    scroll-behavior:auto !important;
  }
}

/* --- Sparklines (v3.1.0 #311) --- */
.sparkline{display:inline-block;vertical-align:middle}
