Improve login page UI and fix hot-dev script for macOS

This commit is contained in:
courtmanr@gmail.com 2025-11-20 12:21:49 +00:00
parent 1626b0e3ae
commit 1e229d5f38
3 changed files with 131 additions and 61 deletions

View file

@ -368,7 +368,7 @@ const LoginForm: Component<{
<div class="min-h-screen flex items-center justify-center bg-gradient-to-br from-blue-50 via-white to-cyan-50 dark:from-gray-900 dark:via-gray-800 dark:to-blue-900 py-12 px-4 sm:px-6 lg:px-8"> <div class="min-h-screen flex items-center justify-center bg-gradient-to-br from-blue-50 via-white to-cyan-50 dark:from-gray-900 dark:via-gray-800 dark:to-blue-900 py-12 px-4 sm:px-6 lg:px-8">
<div class="max-w-md w-full space-y-8"> <div class="max-w-md w-full space-y-8">
<div class="animate-fade-in"> <div class="animate-fade-in">
<div class="flex justify-center mb-4"> <div class="flex justify-center mb-8">
<div class="relative group"> <div class="relative group">
<div class="absolute -inset-1 bg-gradient-to-r from-blue-600 to-cyan-600 rounded-full blur opacity-25 group-hover:opacity-75 transition duration-1000 group-hover:duration-200 animate-pulse-slow"></div> <div class="absolute -inset-1 bg-gradient-to-r from-blue-600 to-cyan-600 rounded-full blur opacity-25 group-hover:opacity-75 transition duration-1000 group-hover:duration-200 animate-pulse-slow"></div>
<img <img
@ -378,10 +378,12 @@ const LoginForm: Component<{
/> />
</div> </div>
</div> </div>
<h2 class="mt-6 text-center text-3xl font-extrabold bg-gradient-to-r from-blue-600 to-cyan-600 bg-clip-text text-transparent">
<h2 class="mt-6 text-center text-4xl font-extrabold bg-gradient-to-r from-blue-600 to-cyan-600 bg-clip-text text-transparent animate-fade-in delay-100 pb-1">
Welcome to Pulse Welcome to Pulse
</h2> </h2>
<p class="mt-2 text-center text-sm text-gray-600 dark:text-gray-400">
<p class="mt-3 text-center text-sm text-gray-600 dark:text-gray-400 animate-fade-in delay-200">
Enter your credentials to continue Enter your credentials to continue
</p> </p>
</div> </div>
@ -524,8 +526,7 @@ const LoginForm: Component<{
<Show when={error()}> <Show when={error()}>
<div <div
class={`rounded-md p-4 ${ class={`rounded-md p-4 ${error().includes('locked')
error().includes('locked')
? 'bg-orange-50 dark:bg-orange-900/20' ? 'bg-orange-50 dark:bg-orange-900/20'
: 'bg-red-50 dark:bg-red-900/20' : 'bg-red-50 dark:bg-red-900/20'
}`} }`}
@ -555,8 +556,7 @@ const LoginForm: Component<{
</div> </div>
<div class="ml-3"> <div class="ml-3">
<p <p
class={`text-sm ${ class={`text-sm ${error().includes('locked')
error().includes('locked')
? 'text-orange-800 dark:text-orange-200' ? 'text-orange-800 dark:text-orange-200'
: 'text-red-800 dark:text-red-200' : 'text-red-800 dark:text-red-200'
}`} }`}

View file

@ -8,6 +8,7 @@
transform: translateY(-100%); transform: translateY(-100%);
opacity: 0; opacity: 0;
} }
to { to {
transform: translateY(0); transform: translateY(0);
opacity: 1; opacity: 1;
@ -25,6 +26,7 @@
transform: translateX(100%) scale(0.95); transform: translateX(100%) scale(0.95);
filter: blur(4px); filter: blur(4px);
} }
to { to {
opacity: 1; opacity: 1;
transform: translateX(0) scale(1); transform: translateX(0) scale(1);
@ -80,7 +82,8 @@
/* Slider thumb styles with value display */ /* Slider thumb styles with value display */
.threshold-slider::-webkit-slider-thumb { .threshold-slider::-webkit-slider-thumb {
@apply appearance-none w-12 h-5 rounded-full cursor-pointer relative; @apply appearance-none w-12 h-5 rounded-full cursor-pointer relative;
margin-top: -2.5px; /* Center thumb on track */ margin-top: -2.5px;
/* Center thumb on track */
background: white; background: white;
border: 2px solid currentColor; border: 2px solid currentColor;
box-shadow: box-shadow:
@ -99,15 +102,18 @@
/* Color coding for different metrics */ /* Color coding for different metrics */
.threshold-slider.slider-cpu { .threshold-slider.slider-cpu {
color: #3b82f6; /* blue-500 */ color: #3b82f6;
/* blue-500 */
} }
.threshold-slider.slider-memory { .threshold-slider.slider-memory {
color: #10b981; /* green-500 */ color: #10b981;
/* green-500 */
} }
.threshold-slider.slider-disk { .threshold-slider.slider-disk {
color: #f59e0b; /* amber-500 */ color: #f59e0b;
/* amber-500 */
} }
/* Value display inside thumb */ /* Value display inside thumb */
@ -227,20 +233,24 @@
/* Global scrollbar styling */ /* Global scrollbar styling */
* { * {
scrollbar-width: thin; scrollbar-width: thin;
scrollbar-color: rgba(156, 163, 175, 0.5) transparent; /* gray-400 with transparency */ scrollbar-color: rgba(156, 163, 175, 0.5) transparent;
/* gray-400 with transparency */
} }
.dark * { .dark * {
scrollbar-color: rgba(55, 65, 81, 0.5) transparent; /* gray-700 with transparency */ scrollbar-color: rgba(55, 65, 81, 0.5) transparent;
/* gray-700 with transparency */
} }
/* Make scrollbars even more subtle on hover */ /* Make scrollbars even more subtle on hover */
*:hover { *:hover {
scrollbar-color: rgba(156, 163, 175, 0.7) rgba(243, 244, 246, 0.5); /* Slightly more visible on hover */ scrollbar-color: rgba(156, 163, 175, 0.7) rgba(243, 244, 246, 0.5);
/* Slightly more visible on hover */
} }
.dark *:hover { .dark *:hover {
scrollbar-color: rgba(75, 85, 99, 0.7) rgba(31, 41, 55, 0.3); /* dark mode hover */ scrollbar-color: rgba(75, 85, 99, 0.7) rgba(31, 41, 55, 0.3);
/* dark mode hover */
} }
*::-webkit-scrollbar { *::-webkit-scrollbar {
@ -311,20 +321,24 @@ body,
0% { 0% {
transform: scale(1); transform: scale(1);
} }
25% { 25% {
transform: scale(1.05); transform: scale(1.05);
} }
50% { 50% {
transform: scale(1); transform: scale(1);
} }
} }
@keyframes pulse-ring { @keyframes pulse-ring {
0%, 0%,
100% { 100% {
opacity: 0.92; opacity: 0.92;
transform: scale(1); transform: scale(1);
} }
50% { 50% {
opacity: 0.6; opacity: 0.6;
transform: scale(1.1); transform: scale(1.1);
@ -376,6 +390,7 @@ body,
opacity: 0; opacity: 0;
transform: translateY(-10px); transform: translateY(-10px);
} }
to { to {
opacity: 1; opacity: 1;
transform: translateY(0); transform: translateY(0);
@ -387,6 +402,7 @@ body,
opacity: 0; opacity: 0;
transform: translateY(20px); transform: translateY(20px);
} }
to { to {
opacity: 1; opacity: 1;
transform: translateY(0); transform: translateY(0);
@ -394,17 +410,19 @@ body,
} }
@keyframes pulse-slow { @keyframes pulse-slow {
0%, 0%,
100% { 100% {
opacity: 0.25; opacity: 0.25;
} }
50% { 50% {
opacity: 0.75; opacity: 0.75;
} }
} }
.animate-fade-in { .animate-fade-in {
animation: fade-in 0.6s ease-out; animation: fade-in 0.6s ease-out forwards;
} }
.animate-slide-up { .animate-slide-up {
@ -414,3 +432,50 @@ body,
.animate-pulse-slow { .animate-pulse-slow {
animation: pulse-slow 3s cubic-bezier(0.4, 0, 0.6, 1) infinite; animation: pulse-slow 3s cubic-bezier(0.4, 0, 0.6, 1) infinite;
} }
/* New Premium Animations */
@keyframes float {
0%,
100% {
transform: translateY(0);
}
50% {
transform: translateY(-10px);
}
}
.animate-float {
animation: float 6s ease-in-out infinite;
}
@keyframes gradient-x {
0%,
100% {
background-size: 200% 200%;
background-position: left center;
}
50% {
background-size: 200% 200%;
background-position: right center;
}
}
.animate-gradient-x {
animation: gradient-x 3s ease infinite;
}
.delay-100 {
animation-delay: 100ms;
}
.delay-200 {
animation-delay: 200ms;
}
.delay-300 {
animation-delay: 300ms;
}

View file

@ -123,14 +123,14 @@ kill_port() {
printf "[hot-dev] Cleaning up existing processes...\n" printf "[hot-dev] Cleaning up existing processes...\n"
# Don't stop ourselves if we're running under systemd # Don't stop ourselves if we're running under systemd
if [[ -z "${INVOCATION_ID:-}" ]]; then # if [[ -z "${INVOCATION_ID:-}" ]]; then
# Not running under systemd, safe to stop the service # Not running under systemd, safe to stop the service
sudo systemctl stop pulse-hot-dev 2>/dev/null || true # sudo systemctl stop pulse-hot-dev 2>/dev/null || true
fi # fi
sudo systemctl stop pulse-backend 2>/dev/null || true # sudo systemctl stop pulse-backend 2>/dev/null || true
sudo systemctl stop pulse 2>/dev/null || true # sudo systemctl stop pulse 2>/dev/null || true
sudo systemctl stop pulse-frontend 2>/dev/null || true # sudo systemctl stop pulse-frontend 2>/dev/null || true
pkill -f "backend-watch.sh" 2>/dev/null || true pkill -f "backend-watch.sh" 2>/dev/null || true
pkill -f vite 2>/dev/null || true pkill -f vite 2>/dev/null || true
@ -271,6 +271,7 @@ printf "[hot-dev] Starting backend file watcher...\n"
cd "${ROOT_DIR}" cd "${ROOT_DIR}"
while true; do while true; do
# Watch for changes to .go files (excluding vendor and node_modules) # Watch for changes to .go files (excluding vendor and node_modules)
if command -v inotifywait >/dev/null 2>&1; then
inotifywait -r -e modify,create,delete,move \ inotifywait -r -e modify,create,delete,move \
--exclude '(vendor/|node_modules/|\.git/|\.swp$|\.tmp$|~$)' \ --exclude '(vendor/|node_modules/|\.git/|\.swp$|\.tmp$|~$)' \
--format '%e %w%f' \ --format '%e %w%f' \
@ -312,6 +313,10 @@ printf "[hot-dev] Starting backend file watcher...\n"
echo "[hot-dev] Watching for changes..." echo "[hot-dev] Watching for changes..."
fi fi
done done
else
echo "[hot-dev] inotifywait not found. Auto-rebuild disabled."
sleep 3600
fi
done done
) & ) &
WATCHER_PID=$! WATCHER_PID=$!