diff --git a/src/components/PasswordReset.vue b/src/components/PasswordReset.vue index 3213f94..60bf508 100644 --- a/src/components/PasswordReset.vue +++ b/src/components/PasswordReset.vue @@ -1,139 +1,192 @@ @@ -185,27 +248,22 @@ function resetForm() { } /* ============================================ - RESET CARD + AUTH CARD ============================================ */ -.reset-card { - background: var(--glass-background); - backdrop-filter: var(--glass-blur); - border-radius: var(--radius-2xl); - max-width: 480px; +.auth-card { + max-width: 560px; width: 100%; - box-shadow: var(--shadow-2xl); - border: 1px solid var(--glass-border); animation: slideUp var(--transition-slower) cubic-bezier(0.4, 0, 0.2, 1); position: relative; z-index: 10; } /* ============================================ - CARD HEADER + AUTH HEADER ============================================ */ -.card-header { - padding: var(--spacing-2xl) var(--spacing-xl) var(--spacing-md); +.auth-header { text-align: center; + margin-bottom: var(--spacing-2xl); } .logo-wrapper { @@ -239,118 +297,29 @@ h1 { color: var(--color-text-secondary); font-size: var(--font-size-base); line-height: var(--line-height-relaxed); - margin: 0; + margin: var(--spacing-sm) 0 0 0; animation: subtitleFade var(--transition-slower) ease-out 0.4s both; } /* ============================================ - RESET FORM + FORM ENHANCEMENTS ============================================ */ -.reset-form { - padding: var(--spacing-md) var(--spacing-xl); - display: flex; - flex-direction: column; - gap: var(--spacing-lg); - animation: formSlide var(--transition-slower) ease-out 0.5s both; -} - -.form-group { - display: flex; - flex-direction: column; - gap: var(--spacing-sm); -} - -label { - font-weight: var(--font-weight-semibold); - color: var(--color-text-secondary); - font-size: var(--font-size-sm); -} - -.input-wrapper { - position: relative; - display: flex; - align-items: center; -} - -input { - width: 100%; - padding: var(--spacing-md) var(--spacing-md) var(--spacing-md) 3rem; - border: 2px solid var(--color-border); - border-radius: var(--radius-lg); - font-size: var(--font-size-base); - font-family: inherit; - transition: all var(--transition-slow); - background: var(--color-surface); - color: var(--color-text-primary); - box-sizing: border-box; -} - -input:focus { - outline: none; - border-color: var(--color-primary); - box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1); - transform: translateY(-2px); -} - -input:disabled { - background: var(--color-surface-hover); - cursor: not-allowed; - opacity: 0.6; -} - -input::placeholder { - color: var(--color-text-tertiary); -} - -.input-icon { - position: absolute; - left: var(--spacing-md); - width: 20px; - height: 20px; - color: var(--color-text-tertiary); - pointer-events: none; -} - -.helper-text { - font-size: var(--font-size-xs); - color: var(--color-text-secondary); - margin: 0; +.label-icon { + width: 18px; + height: 18px; + margin-right: var(--spacing-xs); + vertical-align: middle; + color: var(--color-primary); } /* ============================================ - SUBMIT BUTTON + BUTTON ENHANCEMENTS ============================================ */ -.btn-primary { +.btn-modern-large { width: 100%; - padding: var(--spacing-md); - background: var(--gradient-primary); - color: var(--color-text-inverse); - border: none; - border-radius: var(--radius-lg); - font-size: var(--font-size-base); - font-weight: var(--font-weight-bold); - cursor: pointer; - transition: all var(--transition-slow); - box-shadow: var(--shadow-md); - display: flex; - align-items: center; - justify-content: center; - min-height: 52px; -} - -.btn-primary:hover:not(:disabled) { - transform: translateY(-3px); - box-shadow: var(--shadow-lg); -} - -.btn-primary:active:not(:disabled) { - transform: translateY(-1px); -} - -.btn-primary:disabled { - opacity: 0.7; - cursor: not-allowed; - transform: none; + padding: 16px 32px; + font-size: var(--font-size-lg); + min-height: 56px; } .loading-content { @@ -360,73 +329,69 @@ input::placeholder { } .spinner { + width: 22px; + height: 22px; + animation: spin 1s linear infinite; +} + +/* ============================================ + INFO BOXES + ============================================ */ +.info-box { + display: flex; + align-items: flex-start; + gap: var(--spacing-md); +} + +.info-box svg { width: 20px; height: 20px; - animation: spin 1s linear infinite; + flex-shrink: 0; + margin-top: 2px; } /* ============================================ SUCCESS SECTION ============================================ */ .success-section { - padding: var(--spacing-md) var(--spacing-xl) var(--spacing-xl); - text-align: center; animation: formSlide var(--transition-slower) ease-out; } -.check-animation { - width: 80px; - height: 80px; - margin: 0 auto var(--spacing-lg); - padding: var(--spacing-lg); - background: var(--gradient-secondary); - border-radius: var(--radius-full); - color: var(--color-text-inverse); +.email-display { display: flex; align-items: center; justify-content: center; - animation: checkBounce var(--transition-slower) ease-out; -} - -.check-animation svg { - width: 100%; - height: 100%; -} - -.success-section h3 { - margin: 0 0 var(--spacing-md) 0; - color: var(--color-secondary); - font-size: var(--font-size-2xl); - font-weight: var(--font-weight-bold); -} - -.success-message { - margin: var(--spacing-sm) 0; - color: var(--color-text-secondary); - line-height: var(--line-height-relaxed); - font-size: var(--font-size-sm); -} - -.email-display { - color: var(--color-primary) !important; + gap: var(--spacing-sm); + color: var(--color-primary); font-weight: var(--font-weight-semibold); font-size: var(--font-size-lg); - background: rgba(102, 126, 234, 0.1); - padding: var(--spacing-sm); - border-radius: var(--radius-md); - margin: var(--spacing-md) 0 !important; + background: rgba(0, 102, 204, 0.1); + padding: var(--spacing-md); + border-radius: var(--radius-lg); + margin: var(--spacing-lg) 0; word-break: break-all; + border: 2px solid rgba(0, 102, 204, 0.2); +} + +.email-display svg { + width: 24px; + height: 24px; + flex-shrink: 0; } /* ============================================ INSTRUCTIONS ============================================ */ .instructions { - display: flex; - flex-direction: column; - gap: var(--spacing-md); - margin: var(--spacing-lg) 0; - text-align: left; + margin: var(--spacing-xl) 0; +} + +.instructions h3 { + font-size: var(--font-size-xl); + font-weight: var(--font-weight-bold); + color: var(--color-text-primary); + margin: 0 0 var(--spacing-lg) 0; + text-align: center; } .instruction-step { @@ -434,14 +399,25 @@ input::placeholder { gap: var(--spacing-md); padding: var(--spacing-md); background: var(--color-surface-hover); - border-radius: var(--radius-md); + border-radius: var(--radius-lg); border-left: 4px solid var(--color-primary); + margin-bottom: var(--spacing-md); + transition: all var(--transition-base); +} + +.instruction-step:hover { + transform: translateX(4px); + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); +} + +.instruction-step:last-child { + margin-bottom: 0; } .step-number { - width: 36px; - height: 36px; - min-width: 36px; + width: 40px; + height: 40px; + min-width: 40px; display: flex; align-items: center; justify-content: center; @@ -449,205 +425,88 @@ input::placeholder { color: var(--color-text-inverse); border-radius: var(--radius-full); font-weight: var(--font-weight-bold); + font-size: var(--font-size-lg); + box-shadow: 0 2px 8px rgba(0, 102, 204, 0.3); +} + +.step-content { + flex: 1; +} + +.step-content strong { + display: block; + color: var(--color-text-primary); font-size: var(--font-size-base); + font-weight: var(--font-weight-semibold); + margin-bottom: var(--spacing-xs); } .step-content p { margin: 0; color: var(--color-text-secondary); font-size: var(--font-size-sm); - line-height: var(--line-height-normal); -} - -.step-content p:first-child { - font-weight: var(--font-weight-semibold); - color: var(--color-text-primary); - margin-bottom: 0.25rem; -} - -/* ============================================ - SPAM NOTICE - ============================================ */ -.spam-notice { - display: flex; - gap: var(--spacing-md); - padding: var(--spacing-md); - background: rgba(245, 158, 11, 0.1); - border: 1px solid var(--color-warning); - border-radius: var(--radius-md); - margin: var(--spacing-md) 0; -} - -.spam-notice svg { - width: 20px; - height: 20px; - color: var(--color-warning); - flex-shrink: 0; - margin-top: 2px; -} - -.spam-notice p { - margin: 0; - color: var(--color-warning); - font-size: var(--font-size-sm); - line-height: var(--line-height-normal); -} - -.spam-notice strong { - color: var(--color-warning); -} - -/* ============================================ - SECONDARY BUTTON - ============================================ */ -.btn-secondary { - padding: var(--spacing-sm) var(--spacing-lg); - background: rgba(102, 126, 234, 0.1); - color: var(--color-primary); - border: 2px solid rgba(102, 126, 234, 0.2); - border-radius: var(--radius-md); - font-weight: var(--font-weight-semibold); - cursor: pointer; - transition: all var(--transition-slow); - margin-top: var(--spacing-md); -} - -.btn-secondary:hover { - background: rgba(102, 126, 234, 0.2); - transform: translateY(-1px); -} - -/* ============================================ - ERROR MESSAGE - ============================================ */ -.error-message { - display: flex; - align-items: center; - gap: var(--spacing-sm); - margin-top: var(--spacing-md); - padding: var(--spacing-md); - background: #fef2f2; - border: 1px solid #fecaca; - color: var(--color-danger); - border-radius: var(--radius-md); - font-size: var(--font-size-sm); - animation: shakeError 0.5s ease-out; -} - -.error-message svg { - width: 20px; - height: 20px; - flex-shrink: 0; -} - -.error-title { - margin: 0 0 0.25rem 0; - font-weight: var(--font-weight-semibold); - font-size: var(--font-size-sm); -} - -.error-text { - margin: 0; - font-size: var(--font-size-sm); - opacity: 0.9; + line-height: var(--line-height-relaxed); } /* ============================================ DIVIDER ============================================ */ -.divider { +.auth-divider { position: relative; text-align: center; - margin: var(--spacing-xl) 0 var(--spacing-lg); - z-index: 10; + margin: var(--spacing-2xl) 0 var(--spacing-xl) 0; } -.divider::before { +.auth-divider::before { content: ''; position: absolute; top: 50%; - left: -100px; - right: -100px; - height: 1px; - background: rgba(255, 255, 255, 0.3); + left: 0; + right: 0; + height: 2px; + background: var(--color-divider); } -.divider span { +.auth-divider span { position: relative; - background: var(--gradient-primary); - padding: 0 var(--spacing-md); - color: var(--color-text-inverse); - font-size: var(--font-size-sm); - font-weight: var(--font-weight-medium); + background: var(--color-surface); + padding: 0 var(--spacing-lg); + color: var(--color-text-secondary); + font-size: var(--font-size-base); + font-weight: var(--font-weight-semibold); } /* ============================================ - LINKS SECTION + AUTH FOOTER ============================================ */ -.links-section { +.auth-footer { text-align: center; - padding: 0 var(--spacing-xl) var(--spacing-xl); - z-index: 10; - position: relative; } -.links-section.success-mode { - padding: 0; -} - -.back-link { - display: inline-flex; - align-items: center; - justify-content: center; - gap: var(--spacing-sm); - color: rgba(255, 255, 255, 0.9); - text-decoration: none; - font-weight: var(--font-weight-semibold); - padding: var(--spacing-sm) var(--spacing-lg); - border-radius: var(--radius-md); - background: rgba(255, 255, 255, 0.1); - transition: all var(--transition-base); +.auth-footer .btn-modern { + width: 100%; margin-bottom: var(--spacing-md); } -.back-link svg { - width: 16px; - height: 16px; -} - -.back-link:hover { - background: rgba(255, 255, 255, 0.2); - transform: translateY(-1px); -} - .signup-prompt { - margin-top: var(--spacing-md); + margin-top: var(--spacing-lg); } .signup-prompt p { margin: 0 0 var(--spacing-sm) 0; - color: rgba(255, 255, 255, 0.8); + color: var(--color-text-secondary); font-size: var(--font-size-sm); } -.signup-link { - display: inline-flex; - align-items: center; - gap: var(--spacing-sm); - color: var(--color-text-inverse); +.link-text { + color: var(--color-primary); text-decoration: none; - font-weight: var(--font-weight-bold); + font-weight: var(--font-weight-semibold); transition: all var(--transition-base); } -.signup-link svg { - width: 16px; - height: 16px; - transition: all var(--transition-base); -} - -.signup-link:hover { - gap: var(--spacing-sm); +.link-text:hover { + color: var(--color-primary-dark); text-decoration: underline; } @@ -692,6 +551,29 @@ input::placeholder { animation-delay: 4s; } +/* ============================================ + BOTTOM LINK + ============================================ */ +.bottom-link { + position: absolute; + bottom: var(--spacing-2xl); + left: 50%; + transform: translateX(-50%); + z-index: 10; +} + +.bottom-link .btn-modern { + background: rgba(255, 255, 255, 0.15); + backdrop-filter: blur(10px); + color: white; + border: 1px solid rgba(255, 255, 255, 0.3); +} + +.bottom-link .btn-modern:hover { + background: rgba(255, 255, 255, 0.25); + border-color: rgba(255, 255, 255, 0.5); +} + /* ============================================ ANIMATIONS ============================================ */ @@ -749,24 +631,6 @@ input::placeholder { } } -@keyframes checkBounce { - 0% { - transform: scale(0); - } - 50% { - transform: scale(1.1); - } - 100% { - transform: scale(1); - } -} - -@keyframes shakeError { - 0%, 100% { transform: translateX(0); } - 25% { transform: translateX(-5px); } - 75% { transform: translateX(5px); } -} - @keyframes spin { from { transform: rotate(0deg); @@ -793,32 +657,12 @@ input::placeholder { padding: var(--spacing-md); } - .reset-card { - border-radius: var(--radius-xl); + .auth-card { + padding: var(--spacing-xl); } - .card-header { - padding: var(--spacing-xl) var(--spacing-lg) var(--spacing-md); - } - - .reset-form { - padding: var(--spacing-md) var(--spacing-lg); - } - - .success-section { - padding: var(--spacing-md) var(--spacing-lg) var(--spacing-lg); - } - - .links-section { - padding: 0 var(--spacing-lg) var(--spacing-lg); - } - - h1 { - font-size: var(--font-size-3xl); - } - - .subtitle { - font-size: var(--font-size-sm); + .auth-header { + margin-bottom: var(--spacing-lg); } .logo-wrapper { @@ -828,8 +672,16 @@ input::placeholder { padding: var(--spacing-md); } + h1 { + font-size: var(--font-size-2xl); + } + + .subtitle { + font-size: var(--font-size-sm); + } + .instructions { - gap: var(--spacing-sm); + margin: var(--spacing-lg) 0; } .instruction-step { @@ -838,27 +690,9 @@ input::placeholder { } .step-number { - width: 32px; - height: 32px; - font-size: var(--font-size-sm); - } - - .step-content p { - font-size: var(--font-size-sm); - } - - .spam-notice { - gap: var(--spacing-sm); - padding: var(--spacing-sm); - } - - .spam-notice svg { - width: 18px; - height: 18px; - } - - .spam-notice p { - font-size: var(--font-size-sm); + width: 36px; + height: 36px; + font-size: var(--font-size-base); } .email-display { @@ -866,31 +700,8 @@ input::placeholder { word-break: break-word; } - input { - padding: var(--spacing-sm) var(--spacing-sm) var(--spacing-sm) 2.75rem; - font-size: 16px; - } - - .input-icon { - left: var(--spacing-sm); - } - - .divider { - margin: var(--spacing-lg) 0 var(--spacing-md); - } - - .divider::before { - left: -50px; - right: -50px; - } - - .back-link { - width: 100%; - margin-bottom: var(--spacing-md); - } - - .signup-prompt p { - font-size: var(--font-size-sm); + .auth-divider { + margin: var(--spacing-xl) 0 var(--spacing-md) 0; } .blob-1 { @@ -910,29 +721,12 @@ input::placeholder { } @media (max-width: 480px) { - .reset-card { - border-radius: var(--radius-lg); + .auth-card { + padding: var(--spacing-lg); } - .card-header { - padding: var(--spacing-lg) var(--spacing-md) var(--spacing-sm); - } - - .reset-form { - padding: var(--spacing-sm) var(--spacing-md); - gap: var(--spacing-md); - } - - .success-section { - padding: var(--spacing-sm) var(--spacing-md) var(--spacing-md); - } - - .links-section { - padding: 0 var(--spacing-md) var(--spacing-md); - } - - h1 { - font-size: var(--font-size-2xl); + .auth-header { + margin-bottom: var(--spacing-md); } .logo-wrapper { @@ -940,54 +734,32 @@ input::placeholder { height: 56px; } - .check-animation { - width: 64px; - height: 64px; - margin-bottom: var(--spacing-md); - padding: var(--spacing-md); - } - - label { + .step-content strong { font-size: var(--font-size-sm); } - .btn-primary { - padding: var(--spacing-md); - font-size: var(--font-size-sm); + .step-content p { + font-size: var(--font-size-xs); } - .btn-secondary { - padding: var(--spacing-sm) var(--spacing-md); - font-size: var(--font-size-sm); - } - - .error-message { - gap: var(--spacing-xs); - padding: var(--spacing-sm); - font-size: var(--font-size-sm); - } - - .error-message svg { - width: 18px; - height: 18px; - } - - .divider span { - font-size: var(--font-size-sm); - } - - .signup-prompt { - margin-top: var(--spacing-sm); - } - - .signup-prompt p { - font-size: var(--font-size-sm); - margin-bottom: var(--spacing-xs); - } - - .back-link { - padding: var(--spacing-xs) var(--spacing-md); - font-size: var(--font-size-sm); + .bottom-link { + bottom: var(--spacing-md); } } - \ No newline at end of file + +/* Accessibility */ +@media (prefers-reduced-motion: reduce) { + .auth-card, + .logo-wrapper, + h1, + .subtitle, + .decoration-blob, + .instruction-step { + animation: none; + } + + .instruction-step:hover { + transform: none; + } +} + diff --git a/src/components/UserDashboard.vue b/src/components/UserDashboard.vue index 671a723..52a85f5 100644 --- a/src/components/UserDashboard.vue +++ b/src/components/UserDashboard.vue @@ -304,7 +304,6 @@ import { useAuth } from '@/composables/useAuth' import api from '@/services/api' import ModernNavbar from '@/components/ModernNavbar.vue' -const router = useRouter() const auth = useAuth() const activePeriod = ref('week') @@ -322,11 +321,11 @@ const nextWorkout = ref(null) const currentDate = computed(() => { const now = new Date() - return now.toLocaleDateString('en-US', { - weekday: 'long', - year: 'numeric', - month: 'long', - day: 'numeric' + return now.toLocaleDateString('en-US', { + weekday: 'long', + year: 'numeric', + month: 'long', + day: 'numeric' }) }) @@ -353,17 +352,13 @@ function loadNextWorkout() { const upcomingWorkouts = recentWorkouts.value .filter(w => new Date(w.scheduled_date) >= new Date()) .sort((a, b) => new Date(a.scheduled_date) - new Date(b.scheduled_date)) - + if (upcomingWorkouts.length > 0) { nextWorkout.value = upcomingWorkouts[0] } } } -function startQuickWorkout() { - router.push('/calendar') -} - function getWorkoutColor(type) { const colors = { 'Cycling': '#667eea', diff --git a/src/components/WorkoutCalendar.vue b/src/components/WorkoutCalendar.vue index 2006c51..c6deb3e 100644 --- a/src/components/WorkoutCalendar.vue +++ b/src/components/WorkoutCalendar.vue @@ -596,14 +596,6 @@ function isToday(date) { date.getFullYear() === today.getFullYear() } -function formatDate(dateStr) { - return new Date(dateStr).toLocaleDateString('en-US', { - month: 'short', - day: 'numeric', - year: 'numeric', - }) -} - function formatDuration(seconds) { const hours = Math.floor(seconds / 3600) const minutes = Math.floor((seconds % 3600) / 60)