mirror of
https://github.com/kernelkit/infix.git
synced 2026-08-06 15:43:02 +02:00
webui: sidebar fixes, content sectioning, and theme fixes
Drop the useless 768–1024px icon-only sidebar mode; everything up to 1024px now uses the hamburger overlay and full-width sidebar. Fix the user dropdown on touch devices: click now toggles aria-expanded so CSS-driven visibility works without hover. A document click listener closes the menu when tapping outside. Give the sidebar proper light/dark tokens instead of hardcoded dark values. Introduce --sidebar-hover-fg (primary in light, white in dark) so nav-link hover text is legible in both themes. Fix dropdown hover background using --border instead of --border-subtle, which had zero contrast against the surface in dark mode. Keep active nav link in sync with the current URL via JS so it updates correctly after htmx navigation instead of staying on the initial server-rendered page. Also, add YouTube-style progress when laoding pages that take time, e.g., Dashboard. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
+119
-74
@@ -42,13 +42,17 @@
|
||||
--warning: var(--amber-500);
|
||||
--danger: var(--red-500);
|
||||
|
||||
/* Sidebar (Always Dark) */
|
||||
--sidebar-bg: var(--slate-800);
|
||||
--sidebar-fg: var(--slate-200);
|
||||
--sidebar-hover: rgba(255, 255, 255, 0.1);
|
||||
--sidebar-border: rgba(255, 255, 255, 0.1);
|
||||
/* Sidebar — Light mode */
|
||||
--sidebar-bg: var(--slate-100);
|
||||
--sidebar-fg: var(--slate-700);
|
||||
--sidebar-hover: rgba(0, 0, 0, 0.07);
|
||||
--sidebar-hover-fg: var(--primary);
|
||||
--sidebar-border: rgba(0, 0, 0, 0.08);
|
||||
--sidebar-width: 240px;
|
||||
|
||||
/* Login page */
|
||||
--dot-color: rgba(0, 0, 0, 0.055);
|
||||
|
||||
/* Layout */
|
||||
--radius: 8px;
|
||||
--radius-sm: 4px;
|
||||
@@ -70,6 +74,12 @@
|
||||
--fg-muted: var(--slate-400);
|
||||
--border: var(--slate-700);
|
||||
--border-subtle: var(--slate-800);
|
||||
--sidebar-bg: var(--slate-800);
|
||||
--sidebar-fg: var(--slate-200);
|
||||
--sidebar-hover: rgba(255, 255, 255, 0.1);
|
||||
--sidebar-hover-fg: #fff;
|
||||
--sidebar-border: rgba(255, 255, 255, 0.1);
|
||||
--dot-color: rgba(255, 255, 255, 0.045);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,6 +92,12 @@
|
||||
--border: var(--slate-700);
|
||||
--border-subtle: var(--slate-800);
|
||||
--zebra-stripe: rgba(255,255,255,0.03);
|
||||
--sidebar-bg: var(--slate-800);
|
||||
--sidebar-fg: var(--slate-200);
|
||||
--sidebar-hover: rgba(255, 255, 255, 0.1);
|
||||
--sidebar-hover-fg: #fff;
|
||||
--sidebar-border: rgba(255, 255, 255, 0.1);
|
||||
--dot-color: rgba(255, 255, 255, 0.045);
|
||||
}
|
||||
|
||||
/* Force Light Mode (override system dark preference) */
|
||||
@@ -92,6 +108,12 @@
|
||||
--fg-muted: var(--slate-500);
|
||||
--border: var(--slate-200);
|
||||
--border-subtle: var(--slate-100);
|
||||
--sidebar-bg: var(--slate-100);
|
||||
--sidebar-fg: var(--slate-700);
|
||||
--sidebar-hover: rgba(0, 0, 0, 0.07);
|
||||
--sidebar-hover-fg: var(--primary);
|
||||
--sidebar-border: rgba(0, 0, 0, 0.08);
|
||||
--dot-color: rgba(0, 0, 0, 0.055);
|
||||
}
|
||||
.light .alert-error { background: #fef2f2; color: #991b1b; border-color: #fecaca; }
|
||||
.light .alert-info { background: #eff6ff; color: #1e40af; border-color: #bfdbfe; }
|
||||
@@ -180,7 +202,6 @@ a:hover {
|
||||
|
||||
.sidebar-header {
|
||||
padding: 1.5rem 1.25rem;
|
||||
border-bottom: 1px solid var(--sidebar-border);
|
||||
}
|
||||
|
||||
.sidebar-logo {
|
||||
@@ -195,45 +216,58 @@ a:hover {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
/* Accordion Nav Groups */
|
||||
details.nav-group {
|
||||
border-top: 1px solid var(--sidebar-border);
|
||||
}
|
||||
details.nav-group:first-child {
|
||||
border-top: none;
|
||||
/* Standalone nav link (Dashboard) */
|
||||
.nav-standalone {
|
||||
margin: 0.25rem 0.5rem 0.5rem;
|
||||
}
|
||||
|
||||
details.nav-group > summary.nav-group-summary {
|
||||
/* Top-level accordion groups (Status / Configure / Maintenance) */
|
||||
details.nav-group-top {
|
||||
}
|
||||
|
||||
details.nav-group-top > summary.nav-group-summary-top {
|
||||
list-style: none;
|
||||
cursor: pointer;
|
||||
font-size: 0.65rem;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.08em;
|
||||
font-size: 0.7rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.07em;
|
||||
text-transform: uppercase;
|
||||
color: var(--sidebar-fg);
|
||||
opacity: 0.5;
|
||||
padding: 0.875rem 1rem 0.375rem;
|
||||
opacity: 0.7;
|
||||
padding: 0.75rem 1rem 0.375rem;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
user-select: none;
|
||||
transition: opacity 0.15s;
|
||||
}
|
||||
details.nav-group > summary.nav-group-summary:hover { opacity: 0.8; }
|
||||
details.nav-group > summary.nav-group-summary::-webkit-details-marker { display: none; }
|
||||
details.nav-group > summary.nav-group-summary::marker { display: none; }
|
||||
details.nav-group-top > summary.nav-group-summary-top:hover { opacity: 1; }
|
||||
details.nav-group-top > summary.nav-group-summary-top::-webkit-details-marker { display: none; }
|
||||
details.nav-group-top > summary.nav-group-summary-top::marker { display: none; }
|
||||
|
||||
details.nav-group > summary.nav-group-summary::after {
|
||||
details.nav-group-top > summary.nav-group-summary-top::after {
|
||||
content: '▸';
|
||||
font-size: 0.7rem;
|
||||
}
|
||||
details[open].nav-group > summary.nav-group-summary::after {
|
||||
details[open].nav-group-top > summary.nav-group-summary-top::after {
|
||||
content: '▾';
|
||||
}
|
||||
|
||||
/* Static sub-section labels within top-level accordion */
|
||||
.nav-section-label {
|
||||
font-size: 0.6rem;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
color: var(--sidebar-fg);
|
||||
opacity: 0.45;
|
||||
padding: 0.75rem 1rem 0.2rem;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.nav-group-items {
|
||||
list-style: none;
|
||||
padding-bottom: 0.5rem;
|
||||
padding-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.nav-icon {
|
||||
@@ -262,13 +296,13 @@ details[open].nav-group > summary.nav-group-summary::after {
|
||||
font-size: 0.875rem;
|
||||
border-radius: 0.375rem;
|
||||
margin: 0 0.5rem;
|
||||
transition: background-color 0.15s;
|
||||
transition: background-color 0.15s, color 0.15s;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.nav-link:hover {
|
||||
background-color: var(--sidebar-hover);
|
||||
color: #fff;
|
||||
color: var(--sidebar-hover-fg);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
@@ -278,6 +312,22 @@ details[open].nav-group > summary.nav-group-summary::after {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* Button styled as a nav-link (for actions like Reboot) */
|
||||
.nav-link-btn {
|
||||
width: 100%;
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
text-align: left;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
.nav-link-danger:hover {
|
||||
color: var(--danger);
|
||||
background-color: var(--sidebar-hover);
|
||||
}
|
||||
|
||||
.sidebar-footer {
|
||||
padding: 1.25rem;
|
||||
border-top: 1px solid var(--sidebar-border);
|
||||
@@ -521,12 +571,19 @@ details[open].nav-group > summary.nav-group-summary::after {
|
||||
Authentication
|
||||
========================================================================== */
|
||||
|
||||
@keyframes login-rise {
|
||||
from { opacity: 0; transform: translateY(14px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
|
||||
.login-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 100vh;
|
||||
background: var(--bg);
|
||||
background-color: var(--bg);
|
||||
background-image: radial-gradient(var(--dot-color) 1.5px, transparent 1.5px);
|
||||
background-size: 22px 22px;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
@@ -534,10 +591,12 @@ details[open].nav-group > summary.nav-group-summary::after {
|
||||
background: var(--surface);
|
||||
padding: 2.5rem;
|
||||
border-radius: var(--radius);
|
||||
box-shadow: var(--shadow);
|
||||
box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.07), 0 2px 4px -2px rgb(0 0 0 / 0.07),
|
||||
0 0 0 1px var(--border);
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
border: 1px solid var(--border);
|
||||
border-top: 2px solid var(--primary);
|
||||
animation: login-rise 0.4s cubic-bezier(0.16, 1, 0.3, 1) both;
|
||||
}
|
||||
|
||||
.login-logo {
|
||||
@@ -551,6 +610,19 @@ details[open].nav-group > summary.nav-group-summary::after {
|
||||
Alerts & Banners
|
||||
========================================================================== */
|
||||
|
||||
/* Top progress bar — shown during htmx page navigations */
|
||||
.page-progress {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 2px;
|
||||
width: 0%;
|
||||
background: var(--primary);
|
||||
z-index: 9999;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.conn-banner {
|
||||
background: var(--danger);
|
||||
color: #fff;
|
||||
@@ -1023,8 +1095,8 @@ details[open].nav-group > summary.nav-group-summary::after {
|
||||
justify-content: flex-end;
|
||||
padding: 0 1rem;
|
||||
height: 48px;
|
||||
background: var(--surface);
|
||||
border-bottom: 1px solid var(--border);
|
||||
background: var(--sidebar-bg);
|
||||
border-bottom: 1px solid var(--sidebar-border);
|
||||
flex-shrink: 0;
|
||||
z-index: 100;
|
||||
}
|
||||
@@ -1139,7 +1211,7 @@ details[open].nav-group > summary.nav-group-summary::after {
|
||||
}
|
||||
.dropdown-item:hover,
|
||||
.dropdown-item:focus {
|
||||
background: var(--border-subtle);
|
||||
background: var(--border);
|
||||
color: var(--fg);
|
||||
text-decoration: none;
|
||||
}
|
||||
@@ -1174,20 +1246,28 @@ details[open].nav-group > summary.nav-group-summary::after {
|
||||
}
|
||||
.login-theme-btn:hover { color: var(--fg); border-color: var(--fg-muted); }
|
||||
|
||||
/* Login lock icon */
|
||||
.login-icon {
|
||||
.login-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 1.5rem;
|
||||
gap: 0.5rem;
|
||||
margin-bottom: 1.75rem;
|
||||
color: var(--fg-muted);
|
||||
}
|
||||
|
||||
.login-header h1 {
|
||||
font-size: 1.25rem;
|
||||
font-weight: 600;
|
||||
color: var(--fg);
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Responsive Layout
|
||||
========================================================================== */
|
||||
|
||||
/* Mobile (≤768px): Sidebar hidden, hamburger visible */
|
||||
@media (max-width: 768px) {
|
||||
/* Narrow (≤1024px): Sidebar hidden behind hamburger overlay */
|
||||
@media (max-width: 1024px) {
|
||||
#sidebar {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
@@ -1221,43 +1301,8 @@ details[open].nav-group > summary.nav-group-summary::after {
|
||||
}
|
||||
}
|
||||
|
||||
/* Tablet (769px–1024px): Icon-only sidebar */
|
||||
@media (min-width: 769px) and (max-width: 1024px) {
|
||||
:root {
|
||||
--sidebar-width: 64px;
|
||||
}
|
||||
|
||||
.nav-link span:not(.nav-icon) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Accordion in icon-only mode: always show items, hide section headers */
|
||||
details.nav-group > summary.nav-group-summary {
|
||||
display: none;
|
||||
}
|
||||
details.nav-group:not([open]) > .nav-group-items {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
justify-content: center;
|
||||
padding: 0.6rem;
|
||||
}
|
||||
|
||||
.sidebar-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.sidebar-logo {
|
||||
max-width: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Desktop: hamburger hidden */
|
||||
@media (min-width: 769px) {
|
||||
/* Desktop (>1024px): hamburger hidden, sidebar always visible */
|
||||
@media (min-width: 1025px) {
|
||||
.hamburger-btn {
|
||||
display: none;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user