v0.166.0: mobile nav off-canvas drawer + sidebar cleanup + versioned logo/favicon URLs
Mobile nav was broken — the <=768px block predated the v0.146.0 accordion and
flattened .nav-links into a horizontal overflow-x strip, clipping the accordion's
nested sub-lists. Replaced with a sticky top bar + off-canvas left drawer that
reuses the vertical sidebar (accordion untouched), plus a no-js static fallback.
Removed the sidebar customer-name span (kept on login). Added ?v={{.Version}}
cache-bust to logo/favicon URLs (Cloudflare 4h edge-cache; 0.126.1 failure mode).
Part 4 (outlined-logo constant swap) gated out per §3a: live felhom.eu main still
serves a logo.svg with live <text>/font-family; constants unchanged.
5 new tests via the real layout/CSS render; nav_accordion invariants unchanged.
This commit is contained in:
@@ -100,12 +100,6 @@ body {
|
||||
display: block;
|
||||
margin: 0 auto 0.5rem;
|
||||
}
|
||||
.customer-name {
|
||||
display: block;
|
||||
font-size: .85rem;
|
||||
color: var(--text-2);
|
||||
margin-top: .25rem;
|
||||
}
|
||||
.nav-links {
|
||||
list-style: none;
|
||||
padding: 1rem 0;
|
||||
@@ -142,6 +136,26 @@ body {
|
||||
.version { color: var(--text-3); }
|
||||
.logout-link { color: var(--text-3); text-decoration: none; transition: color 0.2s ease; }
|
||||
.logout-link:hover { color: var(--blue-bright); }
|
||||
/* Mobile chrome (v0.166.0) — hidden by default so desktop (>768px) stays pixel-identical; the
|
||||
≤768px block below turns the top bar on and converts the sidebar into an off-canvas drawer. */
|
||||
.mobile-topbar { display: none; }
|
||||
.nav-backdrop { display: none; }
|
||||
.nav-burger {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: .375rem;
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--text-2);
|
||||
cursor: pointer;
|
||||
transition: color 0.2s ease;
|
||||
}
|
||||
.nav-burger:hover { color: var(--blue-bright); }
|
||||
.nav-burger:focus-visible {
|
||||
outline: 2px solid var(--blue-bright);
|
||||
outline-offset: -2px;
|
||||
}
|
||||
.nav-burger .ico { width: 24px; height: 24px; }
|
||||
|
||||
/* Main content */
|
||||
.content {
|
||||
@@ -2532,10 +2546,54 @@ a.stat-card:hover {
|
||||
|
||||
/* Responsive */
|
||||
@media(max-width: 768px) {
|
||||
.sidebar { width: 100%; height: auto; position: relative; border-right: none; border-bottom: 1px solid var(--line); }
|
||||
.nav-links { display: flex; padding: 0; overflow-x: auto; }
|
||||
.nav-links a { padding: .5rem 1rem; white-space: nowrap; }
|
||||
.nav-links a.active { border-left: none; border-bottom: 2px solid var(--blue); }
|
||||
/* v0.166.0: the old horizontal .nav-links strip was deleted — it predated the v0.146.0
|
||||
accordion and, because the nested sub-lists share the .nav-links class, laid them out
|
||||
horizontally inside an overflow:hidden row and clipped every sub-item past the first.
|
||||
Replaced by a sticky top bar + off-canvas drawer (JS) with a static-sidebar fallback (no-JS). */
|
||||
.mobile-topbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 800;
|
||||
background: var(--bg-2);
|
||||
border-bottom: 1px solid var(--line);
|
||||
padding: .5rem 1rem;
|
||||
}
|
||||
.mobile-topbar-logo img { height: 36px; width: auto; display: block; }
|
||||
/* JS path: the vertical sidebar becomes an off-canvas left drawer (accordion untouched). */
|
||||
.js .sidebar {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100vh;
|
||||
height: 100dvh;
|
||||
width: min(280px, 85vw);
|
||||
transform: translateX(-100%);
|
||||
transition: transform .2s ease;
|
||||
z-index: 950;
|
||||
border-right: 1px solid var(--line);
|
||||
border-bottom: none;
|
||||
}
|
||||
.js .sidebar.is-open { transform: none; }
|
||||
.js .nav-backdrop:not([hidden]) {
|
||||
display: block;
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, .5);
|
||||
z-index: 900;
|
||||
}
|
||||
body.nav-open { overflow: hidden; }
|
||||
/* No-JS fallback: sidebar renders static inline above the content so no destination dead-ends. */
|
||||
.no-js .sidebar {
|
||||
position: static;
|
||||
height: auto;
|
||||
width: 100%;
|
||||
border-right: none;
|
||||
border-bottom: 1px solid var(--line);
|
||||
}
|
||||
.no-js .nav-burger { display: none; }
|
||||
.content { margin-left: 0; padding: 1rem; }
|
||||
body { flex-direction: column; }
|
||||
.app-row { flex-wrap: wrap; }
|
||||
@@ -2552,6 +2610,10 @@ a.stat-card:hover {
|
||||
.restore-label { min-width: auto; }
|
||||
.restore-select { max-width: 100%; }
|
||||
}
|
||||
/* v0.166.0: honor reduced-motion for the drawer slide, matching the accordion/chevron convention. */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.js .sidebar { transition: none; }
|
||||
}
|
||||
|
||||
/* ===================================================================
|
||||
Storage Init Wizard & Migration UI
|
||||
|
||||
Reference in New Issue
Block a user