diff --git a/src/components/play/ErrorPage.vue b/src/components/play/ErrorPage.vue index 1e6c94b..8cd837d 100644 --- a/src/components/play/ErrorPage.vue +++ b/src/components/play/ErrorPage.vue @@ -1,11 +1,25 @@ @@ -30,54 +44,110 @@ export default { .error-page { flex: 1; display: flex; - justify-content: center; - align-items: center; - padding: 40px 20px; + flex-direction: column; + background: white; + min-height: 100vh; +} + +.page-header { + text-align: center; + padding: 20px; + background: white; + border-bottom: 3px solid #f44336; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); +} + +.title { + font-size: 20px; + font-weight: 600; + margin: 0; + color: #333; + background: linear-gradient(135deg, #f44336 0%, #e91e63 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; } .error-container { - background: white; - padding: 40px; - border-radius: 20px; - box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15); + flex: 1; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + padding: 40px 20px; text-align: center; - max-width: 400px; - width: 100%; } -.error-icon { - font-size: 48px; - margin-bottom: 16px; +.icon-wrapper { + margin-bottom: 24px; + animation: shake 0.5s ease-in-out; +} + +@keyframes shake { + 0%, 100% { transform: translateX(0); } + 10%, 30%, 50%, 70%, 90% { transform: translateX(-5px); } + 20%, 40%, 60%, 80% { transform: translateX(5px); } +} + +.error-svg { + filter: drop-shadow(0 4px 8px rgba(244, 67, 54, 0.3)); } .error-title { - font-size: 20px; + font-size: 22px; font-weight: 600; margin: 0 0 12px 0; color: #333; } .error-message { - font-size: 16px; + font-size: 14px; color: #666; - margin: 0 0 24px 0; - line-height: 1.5; + margin: 0 0 32px 0; + line-height: 1.6; + max-width: 320px; } .retry-btn { - background: #667eea; + background: linear-gradient(135deg, #4776e6 0%, #8e54e9 100%); color: white; border: none; padding: 12px 32px; - border-radius: 25px; - font-size: 16px; + border-radius: 8px; + font-size: 14px; font-weight: 600; cursor: pointer; transition: all 0.3s ease; + min-width: 140px; } .retry-btn:hover { - background: #5a6fd8; - transform: translateY(-2px); + opacity: 0.9; + transform: translateY(-1px); +} + +.notice-text { + text-align: center; + padding: 20px; + background: #f8f9fa; + border-top: 2px solid #e9ecef; + margin-top: auto; +} + +.notice-text p { + margin: 4px 0; + font-size: 12px; + color: #666; +} + +@media (max-width: 768px) { + .error-svg { + width: 64px; + height: 64px; + } + + .error-title { + font-size: 18px; + } } \ No newline at end of file diff --git a/src/components/play/LoadingOverlay.vue b/src/components/play/LoadingOverlay.vue index cea63bc..3a36018 100644 --- a/src/components/play/LoadingOverlay.vue +++ b/src/components/play/LoadingOverlay.vue @@ -1,7 +1,22 @@ @@ -18,26 +33,140 @@ export default { left: 0; right: 0; bottom: 0; - background: rgba(255, 255, 255, 0.9); + background: white; + display: flex; + flex-direction: column; + z-index: 1000; +} + +.page-header { + text-align: center; + padding: 20px; + background: white; + border-bottom: 3px solid #4776e6; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); +} + +.title { + font-size: 20px; + font-weight: 600; + margin: 0; + color: #333; + background: linear-gradient(135deg, #4776e6 0%, #8e54e9 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +.loading-container { + flex: 1; display: flex; flex-direction: column; justify-content: center; align-items: center; - z-index: 1000; + padding: 40px 20px; +} + +.spinner-wrapper { + position: relative; + width: 80px; + height: 80px; + margin-bottom: 32px; } .loading-spinner { - width: 40px; - height: 40px; - border: 4px solid #f3f3f3; - border-top: 4px solid #667eea; + position: absolute; + top: 50%; + left: 50%; + width: 60px; + height: 60px; + margin-top: -30px; + margin-left: -30px; + border: 4px solid #e9ecef; + border-top: 4px solid #4776e6; border-radius: 50%; animation: spin 1s linear infinite; - margin-bottom: 16px; +} + +.loading-pulse { + position: absolute; + top: 50%; + left: 50%; + width: 80px; + height: 80px; + margin-top: -40px; + margin-left: -40px; + border: 2px solid #4776e6; + border-radius: 50%; + opacity: 0.3; + animation: pulse 2s ease-in-out infinite; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } + +@keyframes pulse { + 0%, 100% { + transform: scale(0.8); + opacity: 0.3; + } + 50% { + transform: scale(1.1); + opacity: 0.6; + } +} + +.loading-text { + font-size: 18px; + font-weight: 600; + margin: 0 0 8px 0; + color: #333; +} + +.loading-subtext { + font-size: 14px; + margin: 0; + color: #666; +} + +.notice-text { + text-align: center; + padding: 20px; + background: #f8f9fa; + border-top: 2px solid #e9ecef; + margin-top: auto; +} + +.notice-text p { + margin: 4px 0; + font-size: 12px; + color: #666; +} + +@media (max-width: 768px) { + .spinner-wrapper { + width: 64px; + height: 64px; + } + + .loading-spinner { + width: 48px; + height: 48px; + margin-top: -24px; + margin-left: -24px; + } + + .loading-pulse { + width: 64px; + height: 64px; + margin-top: -32px; + margin-left: -32px; + } + + .loading-text { + font-size: 16px; + } +} \ No newline at end of file diff --git a/src/components/play/RefreshWaitPage.vue b/src/components/play/RefreshWaitPage.vue index 75b3020..0c9e929 100644 --- a/src/components/play/RefreshWaitPage.vue +++ b/src/components/play/RefreshWaitPage.vue @@ -1,26 +1,54 @@