responsive nav: hamburger menu <=1100px, column buttons <=640px, endpoint pill ellipsis, injected buttons (Export/Update/Topology) relocate into the menu
This commit is contained in:
@@ -14,6 +14,28 @@
|
||||
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
<link rel="stylesheet" href="styles_v2.css">
|
||||
<style>
|
||||
/* ── responsive nav (2026-09-30) ── */
|
||||
.hamburger-btn { display: none; background: rgba(15,23,42,0.8); border: 1px solid var(--border-color);
|
||||
color: #e2e8f0; border-radius: 8px; padding: 0.55rem 0.8rem; font-size: 1.1rem; cursor: pointer; }
|
||||
@media (max-width: 1100px) {
|
||||
.top-nav { flex-wrap: wrap; gap: 0.5rem; }
|
||||
.nav-metrics { order: 3; width: 100%; justify-content: flex-start; gap: 0.5rem; }
|
||||
.metric-pill { font-size: 0.7rem; padding: 0.25rem 0.5rem; max-width: 48%; overflow: hidden; }
|
||||
.metric-pill .pill-value { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: inline-block; max-width: 180px; vertical-align: bottom; }
|
||||
.hamburger-btn { display: inline-block; order: 2; margin-left: auto; }
|
||||
.nav-menu { display: none; order: 4; width: 100%; }
|
||||
.nav-menu.open { display: block; }
|
||||
.nav-menu .action-area { display: flex !important; flex-wrap: wrap; gap: 0.4rem !important; padding: 0.5rem 0;
|
||||
border-top: 1px solid var(--border-color); }
|
||||
.nav-menu .btn { padding: 0.4rem 0.6rem; font-size: 0.75rem; }
|
||||
.action-area .btn i { margin-right: 0.25rem; }
|
||||
}
|
||||
@media (max-width: 640px) {
|
||||
.nav-menu .action-area { flex-direction: column; }
|
||||
.nav-menu .btn { width: 100%; text-align: left; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -41,7 +63,11 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="action-area" style="display: flex; gap: 0.75rem;">
|
||||
<button id="hamburgerBtn" class="hamburger-btn" onclick="toggleNavMenu()" aria-label="Menu">
|
||||
<i class="fa-solid fa-bars"></i>
|
||||
</button>
|
||||
<div id="navMenu" class="nav-menu">
|
||||
<div class="action-area" style="display: flex; gap: 0.75rem; flex-wrap: wrap;">
|
||||
<a href="/api/export/csv" class="btn btn-secondary" style="text-decoration: none;" download>
|
||||
<i class="fa-solid fa-file-csv"></i> Nodes CSV
|
||||
</a>
|
||||
@@ -66,6 +92,7 @@
|
||||
<button class="btn btn-secondary" style="border-color: var(--accent-rose); color: var(--accent-rose);" onclick="killSwitch()">
|
||||
<i class="fa-solid fa-skull"></i> Kill Switch
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
@@ -602,6 +629,30 @@ function applyInstallerPersist() {
|
||||
}
|
||||
document.addEventListener('DOMContentLoaded', () => setTimeout(applyInstallerPersist, 100));
|
||||
</script>
|
||||
<script>
|
||||
function toggleNavMenu() {
|
||||
const m = document.getElementById('navMenu');
|
||||
const b = document.getElementById('hamburgerBtn');
|
||||
if (m && b) {
|
||||
m.classList.toggle('open');
|
||||
b.innerHTML = m.classList.contains('open') ? '<i class="fa-solid fa-xmark"></i>' : '<i class="fa-solid fa-bars"></i>';
|
||||
}
|
||||
}
|
||||
// injected buttons (Export All, Update All, Topology) go into the nav-menu when it exists
|
||||
const _origNavInject = setInterval(() => {
|
||||
const menu = document.getElementById('navMenu');
|
||||
if (!menu) return;
|
||||
clearInterval(_origNavInject);
|
||||
const mo = new MutationObserver(() => {
|
||||
const ks = document.querySelector('.nav-menu button[onclick="killSwitch()"]');
|
||||
['exportAllBtn', 'updateAllBtn', 'topoBtn'].forEach(id => {
|
||||
const b = document.getElementById(id);
|
||||
if (b && !menu.contains(b)) menu.querySelector('.action-area').appendChild(b);
|
||||
});
|
||||
});
|
||||
mo.observe(document.body, { childList: true, subtree: true });
|
||||
}, 500);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
<!-- ═══ NexusOps v2 UI markup ═══ -->
|
||||
|
||||
Reference in New Issue
Block a user