🔥 Add Fire Glow Login Background

 Beautiful Animated Fire Glow:
- Slow-moving fire gradient background with light/dark modes
- Floating ember particles with realistic animation
- 12-second background animation cycle with subtle color shifts
- Theme-aware gradient colors (warm daylight vs cozy evening)

🎨 Enhanced Login Experience:
- Updated branding to Deck Hearth with fire emoji
- Backdrop blur effects on form elements
- Semi-transparent containers for depth
- Orange focus states to match fire theme
- Enhanced shadows and glow effects

🌙 Theme Support:
- Light mode: Warm daylight fire with golden embers
- Dark mode: Cozy evening fire with bright orange flames
- RGB color variables for backdrop-blur compatibility
- Gradient-bg-ember class for consistent fire theming

The login page now perfectly captures the warm, inviting Deck Hearth atmosphere
This commit is contained in:
Randall Stillwell 2025-07-28 09:51:39 -05:00
parent 308d2de365
commit 2163b9ea0e
3 changed files with 164 additions and 23 deletions

View file

@ -4,8 +4,59 @@ export default function AuthLayout({ children }) {
const { theme } = useTheme(); const { theme } = useTheme();
return ( return (
<div className="min-h-screen" style={{ backgroundColor: 'var(--bg-primary)' }}> <div className="min-h-screen relative overflow-hidden">
{/* Animated Fire Glow Background */}
<div
className="absolute inset-0 fire-glow-bg"
style={{
background: theme === 'dark'
? `
radial-gradient(circle at 20% 80%, rgba(255, 107, 0, 0.15) 0%, transparent 50%),
radial-gradient(circle at 80% 20%, rgba(255, 69, 0, 0.12) 0%, transparent 50%),
radial-gradient(circle at 40% 40%, rgba(220, 38, 127, 0.08) 0%, transparent 50%),
linear-gradient(135deg, rgba(31, 41, 55, 0.95) 0%, rgba(17, 24, 39, 0.98) 100%)
`
: `
radial-gradient(circle at 20% 80%, rgba(255, 171, 64, 0.08) 0%, transparent 50%),
radial-gradient(circle at 80% 20%, rgba(251, 146, 60, 0.06) 0%, transparent 50%),
radial-gradient(circle at 40% 40%, rgba(249, 115, 22, 0.04) 0%, transparent 50%),
linear-gradient(135deg, rgba(255, 251, 235, 0.9) 0%, rgba(254, 243, 199, 0.95) 100%)
`
}}
/>
{/* Floating Embers */}
<div className="absolute inset-0 overflow-hidden pointer-events-none">
{Array.from({ length: 12 }).map((_, i) => (
<div
key={i}
className="absolute animate-ember-float opacity-30"
style={{
left: `${Math.random() * 100}%`,
top: `${Math.random() * 100}%`,
animationDelay: `${Math.random() * 8}s`,
animationDuration: `${8 + Math.random() * 4}s`
}}
>
<div
className="w-1 h-1 rounded-full"
style={{
backgroundColor: theme === 'dark'
? `rgba(255, ${100 + Math.random() * 100}, 0, 0.6)`
: `rgba(251, ${100 + Math.random() * 46}, 60, 0.4)`,
boxShadow: theme === 'dark'
? `0 0 8px rgba(255, ${100 + Math.random() * 100}, 0, 0.4)`
: `0 0 6px rgba(251, ${100 + Math.random() * 46}, 60, 0.3)`
}}
/>
</div>
))}
</div>
{/* Content */}
<div className="relative z-10">
{children} {children}
</div> </div>
</div>
); );
} }

View file

@ -67,21 +67,27 @@ export default function Login() {
<div className="max-w-md w-full space-y-8"> <div className="max-w-md w-full space-y-8">
<div> <div>
<div className="text-center"> <div className="text-center">
<div className="text-6xl mb-4">🃏</div> <div className="text-6xl mb-4">🔥</div>
<h2 className="text-3xl font-bold" style={{ color: 'var(--text-primary)' }}> <h2 className="text-3xl font-bold gradient-text-flame mb-2">
Sign in to TCG Vault Welcome to Deck Hearth
</h2> </h2>
<p className="mt-2 text-sm" style={{ color: 'var(--text-secondary)' }}> <p className="mt-2 text-sm" style={{ color: 'var(--text-secondary)' }}>
Access your trading card collection Sign in to access your trading card collection
</p> </p>
</div> </div>
</div> </div>
<div className="p-8 rounded-2xl shadow-lg" style={{ backgroundColor: 'var(--bg-secondary)' }}> <div
className="p-8 rounded-2xl shadow-2xl backdrop-blur-sm border border-opacity-20"
style={{
backgroundColor: 'rgba(var(--bg-secondary-rgb), 0.85)',
borderColor: 'var(--border)'
}}
>
<form onSubmit={handleSubmit} className="space-y-6"> <form onSubmit={handleSubmit} className="space-y-6">
{error && ( {error && (
<div className="p-4 rounded-lg bg-red-100 border border-red-200"> <div className="p-4 rounded-lg bg-red-500 bg-opacity-10 border border-red-500 border-opacity-20 backdrop-blur-sm">
<p className="text-red-700 text-sm">{error}</p> <p className="text-red-400 text-sm">{error}</p>
</div> </div>
)} )}
@ -97,9 +103,9 @@ export default function Login() {
required required
value={formData.email} value={formData.email}
onChange={(e) => handleInputChange('email', e.target.value)} onChange={(e) => handleInputChange('email', e.target.value)}
className="w-full px-4 py-3 rounded-lg border transition-all duration-200 focus:ring-2 focus:ring-purple-500 focus:border-transparent" className="w-full px-4 py-3 rounded-lg border transition-all duration-200 focus:ring-2 focus:ring-orange-500 focus:border-transparent backdrop-blur-sm"
style={{ style={{
backgroundColor: 'var(--bg-primary)', backgroundColor: 'rgba(var(--bg-primary-rgb), 0.7)',
borderColor: 'var(--border)', borderColor: 'var(--border)',
color: 'var(--text-primary)' color: 'var(--text-primary)'
}} }}
@ -119,9 +125,9 @@ export default function Login() {
required required
value={formData.password} value={formData.password}
onChange={(e) => handleInputChange('password', e.target.value)} onChange={(e) => handleInputChange('password', e.target.value)}
className="w-full px-4 py-3 rounded-lg border transition-all duration-200 focus:ring-2 focus:ring-purple-500 focus:border-transparent" className="w-full px-4 py-3 rounded-lg border transition-all duration-200 focus:ring-2 focus:ring-orange-500 focus:border-transparent backdrop-blur-sm"
style={{ style={{
backgroundColor: 'var(--bg-primary)', backgroundColor: 'rgba(var(--bg-primary-rgb), 0.7)',
borderColor: 'var(--border)', borderColor: 'var(--border)',
color: 'var(--text-primary)' color: 'var(--text-primary)'
}} }}
@ -136,7 +142,7 @@ export default function Login() {
className={`w-full px-4 py-3 rounded-lg font-medium transition-all duration-200 ${ className={`w-full px-4 py-3 rounded-lg font-medium transition-all duration-200 ${
loading loading
? 'opacity-50 cursor-not-allowed' ? 'opacity-50 cursor-not-allowed'
: 'gradient-bg-purple text-white hover:shadow-lg transform hover:scale-105' : 'gradient-bg-ember text-white hover:shadow-xl transform hover:scale-105 hover:shadow-orange-500/20'
}`} }`}
> >
{loading ? ( {loading ? (
@ -145,13 +151,13 @@ export default function Login() {
Signing in... Signing in...
</div> </div>
) : ( ) : (
'Sign in' 'Sign in to Deck Hearth'
)} )}
</button> </button>
</div> </div>
{/* Quick Login for Testing */} {/* Quick Login for Testing */}
<div className="mt-6 pt-6 border-t" style={{ borderColor: 'var(--border)' }}> <div className="mt-6 pt-6 border-t border-opacity-20" style={{ borderColor: 'var(--border)' }}>
<div className="text-center"> <div className="text-center">
<p className="text-sm mb-3" style={{ color: 'var(--text-secondary)' }}> <p className="text-sm mb-3" style={{ color: 'var(--text-secondary)' }}>
Quick Login for Testing: Quick Login for Testing:
@ -160,9 +166,9 @@ export default function Login() {
<button <button
type="button" type="button"
onClick={() => handleQuickLogin('admin@tcgvault.com', 'admin123')} onClick={() => handleQuickLogin('admin@tcgvault.com', 'admin123')}
className="px-3 py-2 rounded-lg text-xs font-medium border transition-all duration-200 hover:shadow-md" className="px-3 py-2 rounded-lg text-xs font-medium border border-opacity-20 transition-all duration-200 hover:shadow-md backdrop-blur-sm hover:bg-opacity-80"
style={{ style={{
backgroundColor: 'var(--bg-primary)', backgroundColor: 'rgba(var(--bg-primary-rgb), 0.6)',
borderColor: 'var(--border)', borderColor: 'var(--border)',
color: 'var(--text-primary)' color: 'var(--text-primary)'
}} }}
@ -172,9 +178,9 @@ export default function Login() {
<button <button
type="button" type="button"
onClick={() => handleQuickLogin('alice@tcgvault.com', 'alice123')} onClick={() => handleQuickLogin('alice@tcgvault.com', 'alice123')}
className="px-3 py-2 rounded-lg text-xs font-medium border transition-all duration-200 hover:shadow-md" className="px-3 py-2 rounded-lg text-xs font-medium border border-opacity-20 transition-all duration-200 hover:shadow-md backdrop-blur-sm hover:bg-opacity-80"
style={{ style={{
backgroundColor: 'var(--bg-primary)', backgroundColor: 'rgba(var(--bg-primary-rgb), 0.6)',
borderColor: 'var(--border)', borderColor: 'var(--border)',
color: 'var(--text-primary)' color: 'var(--text-primary)'
}} }}
@ -184,9 +190,9 @@ export default function Login() {
<button <button
type="button" type="button"
onClick={() => handleQuickLogin('bob@tcgvault.com', 'bob123')} onClick={() => handleQuickLogin('bob@tcgvault.com', 'bob123')}
className="px-3 py-2 rounded-lg text-xs font-medium border transition-all duration-200 hover:shadow-md" className="px-3 py-2 rounded-lg text-xs font-medium border border-opacity-20 transition-all duration-200 hover:shadow-md backdrop-blur-sm hover:bg-opacity-80"
style={{ style={{
backgroundColor: 'var(--bg-primary)', backgroundColor: 'rgba(var(--bg-primary-rgb), 0.6)',
borderColor: 'var(--border)', borderColor: 'var(--border)',
color: 'var(--text-primary)' color: 'var(--text-primary)'
}} }}
@ -206,7 +212,13 @@ export default function Login() {
</div> </div>
{/* Testing Guide */} {/* Testing Guide */}
<div className="p-4 rounded-xl border" style={{ backgroundColor: 'var(--bg-secondary)', borderColor: 'var(--border)' }}> <div
className="p-4 rounded-xl border border-opacity-20 backdrop-blur-sm"
style={{
backgroundColor: 'rgba(var(--bg-secondary-rgb), 0.6)',
borderColor: 'var(--border)'
}}
>
<div className="text-center"> <div className="text-center">
<h3 className="text-sm font-semibold mb-2" style={{ color: 'var(--text-primary)' }}> <h3 className="text-sm font-semibold mb-2" style={{ color: 'var(--text-primary)' }}>
🧪 Testing Accounts 🧪 Testing Accounts

View file

@ -33,6 +33,11 @@ body {
--input-border-light: #e8dcc6; --input-border-light: #e8dcc6;
--input-text-light: #2d1810; --input-text-light: #2d1810;
--input-placeholder-light: #5d4037; --input-placeholder-light: #5d4037;
/* RGB color variables for backdrop-blur effects */
--bg-primary-rgb: 254, 252, 248;
--bg-secondary-rgb: 247, 243, 237;
--bg-tertiary-rgb: 240, 230, 214;
} }
[data-theme="dark"] { [data-theme="dark"] {
@ -59,6 +64,11 @@ body {
--search-border-dark: #4a2f1f; --search-border-dark: #4a2f1f;
--search-text-dark: #fff8f0; --search-text-dark: #fff8f0;
--search-placeholder-dark: #d7c4b0; --search-placeholder-dark: #d7c4b0;
/* RGB color variables for backdrop-blur effects */
--bg-primary-rgb: 26, 15, 10;
--bg-secondary-rgb: 45, 27, 18;
--bg-tertiary-rgb: 61, 35, 23;
} }
/* Apply theme colors */ /* Apply theme colors */
@ -96,6 +106,11 @@ body {
--input-border: var(--input-border-light); --input-border: var(--input-border-light);
--input-text: var(--input-text-light); --input-text: var(--input-text-light);
--input-placeholder: var(--input-placeholder-light); --input-placeholder: var(--input-placeholder-light);
/* RGB color variables for backdrop-blur effects */
--bg-primary-rgb: 254, 252, 248;
--bg-secondary-rgb: 247, 243, 237;
--bg-tertiary-rgb: 240, 230, 214;
} }
/* Dark theme variables */ /* Dark theme variables */
@ -172,6 +187,10 @@ body {
background: var(--gradient-secondary); background: var(--gradient-secondary);
} }
.gradient-bg-ember {
background: linear-gradient(135deg, #d84315 0%, #bf360c 100%);
}
/* Fire glow effects */ /* Fire glow effects */
.fire-glow { .fire-glow {
box-shadow: 0 0 20px rgba(255, 111, 0, 0.3); box-shadow: 0 0 20px rgba(255, 111, 0, 0.3);
@ -698,3 +717,62 @@ body {
.animate-float { .animate-float {
animation: float 4s ease-in-out infinite; animation: float 4s ease-in-out infinite;
} }
/* Fire Glow Background Animation */
@keyframes fire-glow {
0%, 100% {
filter: hue-rotate(0deg) brightness(1) saturate(1);
transform: scale(1);
}
25% {
filter: hue-rotate(5deg) brightness(1.05) saturate(1.1);
transform: scale(1.02);
}
50% {
filter: hue-rotate(-3deg) brightness(0.98) saturate(1.05);
transform: scale(0.99);
}
75% {
filter: hue-rotate(8deg) brightness(1.03) saturate(1.08);
transform: scale(1.01);
}
}
.fire-glow-bg {
animation: fire-glow 12s ease-in-out infinite;
}
/* Ember Floating Animation */
@keyframes ember-float {
0% {
transform: translateY(0px) translateX(0px) scale(0.8);
opacity: 0;
}
10% {
opacity: 0.6;
}
20% {
transform: translateY(-30px) translateX(15px) scale(1);
opacity: 0.8;
}
40% {
transform: translateY(-60px) translateX(-10px) scale(0.9);
opacity: 1;
}
60% {
transform: translateY(-90px) translateX(20px) scale(1.1);
opacity: 0.7;
}
80% {
transform: translateY(-120px) translateX(-5px) scale(0.8);
opacity: 0.4;
}
100% {
transform: translateY(-150px) translateX(10px) scale(0.6);
opacity: 0;
}
}
.animate-ember-float {
animation: ember-float 10s linear infinite;
}