add sandwich nav
This commit is contained in:
+83
-2
@@ -109,9 +109,9 @@ input, select, textarea { max-width: 100%; }
|
||||
header {
|
||||
border-bottom: 1px solid var(--header-border);
|
||||
padding: 1rem 1.5rem;
|
||||
display: flex;
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr auto;
|
||||
align-items: center;
|
||||
gap: 1.2rem;
|
||||
background: var(--nav-bg);
|
||||
backdrop-filter: blur(12px) saturate(120%);
|
||||
-webkit-backdrop-filter: blur(12px) saturate(120%);
|
||||
@@ -120,6 +120,8 @@ header {
|
||||
z-index: 20;
|
||||
transition: background 0.3s ease;
|
||||
}
|
||||
.brand { justify-self: center; }
|
||||
nav { justify-self: end; }
|
||||
|
||||
.back-link {
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
@@ -479,6 +481,83 @@ details.confirm[open]::before {
|
||||
}
|
||||
.theme-toggle:hover { transform: scale(1.08); }
|
||||
|
||||
/* ── Hamburger (hidden on desktop) ── */
|
||||
.nav-hamburger {
|
||||
display: none; /* shown only at ≤640px */
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
padding: 6px;
|
||||
justify-self: end;
|
||||
}
|
||||
.nav-hamburger span {
|
||||
display: block;
|
||||
width: 20px;
|
||||
height: 1.5px;
|
||||
background: var(--muted);
|
||||
transition: background 0.2s;
|
||||
}
|
||||
.nav-hamburger:hover span { background: var(--fg); }
|
||||
|
||||
/* ── Off-canvas overlay ── */
|
||||
.nav-overlay {
|
||||
position: fixed; inset: 0;
|
||||
background: rgba(0,0,0,0.4);
|
||||
z-index: 49;
|
||||
opacity: 0; pointer-events: none;
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
.nav-overlay.open { opacity: 1; pointer-events: auto; }
|
||||
|
||||
/* ── Off-canvas panel ── */
|
||||
.nav-offcanvas {
|
||||
position: fixed; top: 0; right: 0;
|
||||
width: 100vw; height: 100vh;
|
||||
background: var(--bg);
|
||||
z-index: 50;
|
||||
transform: translateX(100%);
|
||||
transition: transform 0.35s cubic-bezier(0.16, 1, 0.3, 1);
|
||||
display: flex; flex-direction: column;
|
||||
padding: calc(60px + 2rem) 2rem 2rem;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.nav-offcanvas.open { transform: translateX(0); }
|
||||
|
||||
.offcanvas-header {
|
||||
position: absolute; top: 0; left: 0; right: 0;
|
||||
height: 60px;
|
||||
display: flex; align-items: center; justify-content: space-between;
|
||||
padding: 0 1.25rem;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
.nav-close {
|
||||
background: none; border: none;
|
||||
font-size: 1.3rem; color: var(--muted);
|
||||
cursor: pointer; padding: 0.5rem;
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
}
|
||||
.nav-close:hover { color: var(--fg); }
|
||||
|
||||
.offcanvas-links {
|
||||
display: flex; flex-direction: column;
|
||||
gap: 0.15rem; width: 100%;
|
||||
}
|
||||
.offcanvas-links a {
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-size: 1.05rem;
|
||||
letter-spacing: 0.12em;
|
||||
text-transform: uppercase;
|
||||
color: var(--muted);
|
||||
text-decoration: none;
|
||||
padding: 0.75rem 0;
|
||||
border-bottom: 1px solid var(--border);
|
||||
transition: color 0.2s;
|
||||
}
|
||||
.offcanvas-links a:first-child { border-top: 1px solid var(--border); }
|
||||
.offcanvas-links a:hover { color: var(--fg); padding-left: 0.5rem; }
|
||||
|
||||
@media (max-width: 640px) {
|
||||
header { padding: 0.7rem 0.9rem; gap: 0.6rem; }
|
||||
.back-link { font-size: 0.58rem; padding: 0.25rem 0.4rem; letter-spacing: 0.08em; }
|
||||
@@ -489,4 +568,6 @@ details.confirm[open]::before {
|
||||
.theme-toggle { width: 20px; height: 20px; bottom: 1rem; right: 0.9rem; }
|
||||
.reset-banner { top: 44px; }
|
||||
.running-bar { top: 44px; }
|
||||
.nav-desktop { display: none; }
|
||||
.nav-hamburger { display: flex; }
|
||||
}
|
||||
|
||||
+32
-1
@@ -19,16 +19,34 @@
|
||||
<link rel="stylesheet" href="/static/app.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header>
|
||||
<a href="https://fló.fo" class="back-link">← FLÓ.FO</a>
|
||||
<span class="brand">FLÓ <span class="brand-sep">/</span> <span class="brand-sub">ZEITKORT</span></span>
|
||||
<nav>
|
||||
<nav class="nav-desktop">
|
||||
<a href="/">Timer</a>
|
||||
<a hx-get="/settings" hx-target="#main" href="javascript:void(0)">Settings</a>
|
||||
<a hx-get="/about" hx-target="#main" href="javascript:void(0)">About</a>
|
||||
</nav>
|
||||
<button id="nav-hamburger" class="nav-hamburger" aria-label="Open menu">
|
||||
<span></span><span></span><span></span>
|
||||
</button>
|
||||
</header>
|
||||
|
||||
<!-- Off-canvas mobile menu -->
|
||||
<div id="nav-overlay" class="nav-overlay"></div>
|
||||
<div id="nav-offcanvas" class="nav-offcanvas">
|
||||
<div class="offcanvas-header">
|
||||
<span class="brand">FLÓ <span class="brand-sep">/</span> <span class="brand-sub">ZEITKORT</span></span>
|
||||
<button id="nav-close" class="nav-close" aria-label="Close menu">✕</button>
|
||||
</div>
|
||||
<div class="offcanvas-links">
|
||||
<a href="/">Timer</a>
|
||||
<a hx-get="/settings" hx-target="#main" href="javascript:void(0)">Settings</a>
|
||||
<a hx-get="/about" hx-target="#main" href="javascript:void(0)">About</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="reset-banner" role="status" aria-live="polite">
|
||||
<span class="reset-label">POC reset in</span>
|
||||
<span id="reset-countdown" class="reset-countdown" data-reset-at="{{rfc3339 .ResetAt}}">--:--</span>
|
||||
@@ -70,6 +88,19 @@
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
(function () {
|
||||
var overlay = document.getElementById('nav-overlay');
|
||||
var panel = document.getElementById('nav-offcanvas');
|
||||
var openBtn = document.getElementById('nav-hamburger');
|
||||
var closeBtn = document.getElementById('nav-close');
|
||||
function open() { panel.classList.add('open'); overlay.classList.add('open'); }
|
||||
function close() { panel.classList.remove('open'); overlay.classList.remove('open'); }
|
||||
if (openBtn) openBtn.addEventListener('click', open);
|
||||
if (closeBtn) closeBtn.addEventListener('click', close);
|
||||
if (overlay) overlay.addEventListener('click', close);
|
||||
panel.querySelectorAll('a').forEach(function(a) { a.addEventListener('click', close); });
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>{{end}}
|
||||
|
||||
Reference in New Issue
Block a user