webui: slightly more professional look to login page

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
Joachim Wiberg
2026-06-04 17:49:39 +02:00
parent bf670acc57
commit 674a2d3abf
3 changed files with 58 additions and 10 deletions
+29 -6
View File
@@ -50,6 +50,9 @@
--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;
@@ -76,6 +79,7 @@
--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);
}
}
@@ -93,6 +97,7 @@
--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) */
@@ -108,6 +113,7 @@
--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; }
@@ -565,12 +571,19 @@ details[open].nav-group-top > summary.nav-group-summary-top::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;
}
@@ -578,10 +591,12 @@ details[open].nav-group-top > summary.nav-group-summary-top::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 {
@@ -1231,14 +1246,22 @@ details[open].nav-group-top > summary.nav-group-summary-top::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
========================================================================== */
+23
View File
@@ -442,3 +442,26 @@
}
document.addEventListener('DOMContentLoaded', focusAutofocusWhenVisible);
})();
// ─── Login page: progress bar on submit ────────────────────────────────────
// The login form is a native POST (not HTMX), so htmx:beforeSend never fires.
// Start the bar and disable the button to show the user something is happening.
(function() {
document.addEventListener('DOMContentLoaded', function() {
var form = document.querySelector('form[action="/login"]');
if (!form) return;
form.addEventListener('submit', function() {
var bar = document.getElementById('page-progress');
if (bar) {
bar.style.transition = 'none';
bar.style.width = '0%';
bar.style.opacity = '1';
bar.offsetWidth;
bar.style.transition = 'width 8s cubic-bezier(0.05, 0.8, 0.4, 1)';
bar.style.width = '85%';
}
var btn = form.querySelector('button[type="submit"]');
if (btn) { btn.disabled = true; btn.textContent = 'Logging in\u2026'; }
});
});
})();
+6 -4
View File
@@ -13,13 +13,15 @@
<script src="/assets/js/app.js"></script>
</head>
<body class="login-page">
<div id="page-progress" class="page-progress" aria-hidden="true"></div>
<div class="login-wrapper">
<div class="login-card">
<div class="login-icon" aria-hidden="true">
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
<rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect>
<path d="M7 11V7a5 5 0 0 1 10 0v4"></path>
<div class="login-header">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path>
<circle cx="12" cy="7" r="4"></circle>
</svg>
<h1>Login</h1>
</div>
{{if .Error}}
<div class="alert alert-error" role="alert">{{.Error}}</div>