/* Main styles for Talk2Me application */ /* Loading animations */ .loading-dots { display: inline-flex; align-items: center; gap: 4px; } .loading-dots span { width: 8px; height: 8px; border-radius: 50%; background-color: #007bff; animation: dotPulse 1.4s infinite ease-in-out both; } .loading-dots span:nth-child(1) { animation-delay: -0.32s; } .loading-dots span:nth-child(2) { animation-delay: -0.16s; } @keyframes dotPulse { 0%, 80%, 100% { transform: scale(0); opacity: 0.5; } 40% { transform: scale(1); opacity: 1; } } /* Wave animation for recording */ .recording-wave { position: relative; display: inline-block; width: 40px; height: 40px; } .recording-wave span { position: absolute; bottom: 0; width: 4px; height: 100%; background: #fff; border-radius: 2px; animation: wave 1.2s linear infinite; } .recording-wave span:nth-child(1) { left: 0; animation-delay: 0s; } .recording-wave span:nth-child(2) { left: 8px; animation-delay: -1.1s; } .recording-wave span:nth-child(3) { left: 16px; animation-delay: -1s; } .recording-wave span:nth-child(4) { left: 24px; animation-delay: -0.9s; } .recording-wave span:nth-child(5) { left: 32px; animation-delay: -0.8s; } @keyframes wave { 0%, 40%, 100% { transform: scaleY(0.4); } 20% { transform: scaleY(1); } } /* Spinner animation */ .spinner-custom { width: 40px; height: 40px; position: relative; display: inline-block; } .spinner-custom::before { content: ''; position: absolute; width: 100%; height: 100%; border-radius: 50%; border: 3px solid rgba(0, 123, 255, 0.2); } .spinner-custom::after { content: ''; position: absolute; width: 100%; height: 100%; border-radius: 50%; border: 3px solid transparent; border-top-color: #007bff; animation: spin 0.8s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } /* Translation animation */ .translation-animation { position: relative; display: inline-flex; align-items: center; gap: 10px; } .translation-animation .arrow { width: 30px; height: 2px; background: #28a745; position: relative; animation: moveArrow 1.5s infinite; } .translation-animation .arrow::after { content: ''; position: absolute; right: -8px; top: -4px; width: 0; height: 0; border-left: 8px solid #28a745; border-top: 5px solid transparent; border-bottom: 5px solid transparent; } @keyframes moveArrow { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(10px); } } /* Processing text animation */ .processing-text { display: inline-block; position: relative; font-style: italic; color: #6c757d; } .processing-text::after { content: ''; position: absolute; bottom: -2px; left: 0; width: 100%; height: 2px; background: linear-gradient(90deg, transparent 0%, #007bff 50%, transparent 100%); animation: processLine 2s linear infinite; } @keyframes processLine { 0% { transform: translateX(-100%); } 100% { transform: translateX(100%); } } /* Fade in animation for results */ .fade-in { animation: fadeIn 0.5s ease-in; } @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } /* Pulse animation for buttons */ .btn-pulse { animation: pulse 2s infinite; } @keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(0, 123, 255, 0.7); } 70% { box-shadow: 0 0 0 10px rgba(0, 123, 255, 0); } 100% { box-shadow: 0 0 0 0 rgba(0, 123, 255, 0); } } /* Loading overlay */ .loading-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(255, 255, 255, 0.9); display: flex; align-items: center; justify-content: center; z-index: 9999; opacity: 0; pointer-events: none; transition: opacity 0.3s ease; } .loading-overlay.active { opacity: 1; pointer-events: all; } .loading-content { text-align: center; } .loading-content .spinner-custom { margin-bottom: 20px; } /* Status indicator animations */ .status-indicator { transition: all 0.3s ease; } .status-indicator.processing { font-weight: 500; color: #007bff; } .status-indicator.success { color: #28a745; } .status-indicator.error { color: #dc3545; } /* Card loading state */ .card-loading { position: relative; overflow: hidden; } .card-loading::after { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: linear-gradient( 90deg, transparent, rgba(255, 255, 255, 0.4), transparent ); animation: shimmer 2s infinite; } @keyframes shimmer { 100% { left: 100%; } } /* Text skeleton loader */ .skeleton-loader { background: #eee; background: linear-gradient(90deg, #eee 25%, #f5f5f5 50%, #eee 75%); background-size: 200% 100%; animation: loading 1.5s infinite; border-radius: 4px; height: 20px; margin: 10px 0; } @keyframes loading { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } } /* Audio playing animation */ .audio-playing { display: inline-flex; align-items: flex-end; gap: 2px; height: 20px; } .audio-playing span { width: 3px; background: #28a745; animation: audioBar 0.5s ease-in-out infinite alternate; } .audio-playing span:nth-child(1) { height: 40%; animation-delay: 0s; } .audio-playing span:nth-child(2) { height: 60%; animation-delay: 0.1s; } .audio-playing span:nth-child(3) { height: 80%; animation-delay: 0.2s; } .audio-playing span:nth-child(4) { height: 60%; animation-delay: 0.3s; } .audio-playing span:nth-child(5) { height: 40%; animation-delay: 0.4s; } @keyframes audioBar { to { height: 100%; } } /* Smooth transitions */ .btn { transition: all 0.3s ease; } .card { transition: transform 0.3s ease, box-shadow 0.3s ease; } .card:hover { transform: translateY(-2px); box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15); } /* Success notification */ .success-notification { position: fixed; top: 20px; left: 50%; transform: translateX(-50%); background-color: #28a745; color: white; padding: 12px 24px; border-radius: 8px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); display: flex; align-items: center; gap: 10px; z-index: 9999; opacity: 0; transition: opacity 0.3s ease, transform 0.3s ease; pointer-events: none; } .success-notification.show { opacity: 1; transform: translateX(-50%) translateY(0); pointer-events: all; } .success-notification i { font-size: 18px; } /* Mobile optimizations */ @media (max-width: 768px) { .loading-overlay { background: rgba(255, 255, 255, 0.95); } .spinner-custom, .recording-wave { transform: scale(0.8); } .success-notification { width: 90%; max-width: 300px; font-size: 14px; } /* Make the entire layout more compact on mobile */ body { font-size: 14px; } /* Reduce spacing on mobile */ .mb-3 { margin-bottom: 0.5rem !important; } .mb-4 { margin-bottom: 0.75rem !important; } /* Compact cards on mobile */ .card { margin-bottom: 8px !important; } /* Hide less important elements on small screens */ .text-muted.small { font-size: 0.75rem; } /* Adjust button sizes */ .btn { font-size: 0.875rem; } /* Make dropdowns more compact */ .form-select { font-size: 0.875rem; padding: 0.25rem 0.5rem; } } /* Streaming translation styles */ .streaming-text { position: relative; min-height: 1.5em; } .streaming-active::after { content: '▊'; display: inline-block; animation: cursor-blink 1s infinite; color: #007bff; font-weight: bold; } @keyframes cursor-blink { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } } /* Smooth text appearance for streaming */ .streaming-text { transition: all 0.1s ease-out; } /* Multi-speaker styles */ .speaker-button { position: relative; padding: 8px 16px; border-radius: 20px; border: 2px solid; background-color: white; font-weight: 500; transition: all 0.3s ease; min-width: 120px; } .speaker-button.active { color: white !important; transform: scale(1.05); box-shadow: 0 2px 8px rgba(0,0,0,0.2); } .speaker-avatar { display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px; border-radius: 50%; background-color: rgba(255,255,255,0.3); color: inherit; font-weight: bold; font-size: 12px; margin-right: 8px; } .speaker-button.active .speaker-avatar { background-color: rgba(255,255,255,0.3); } .conversation-entry { margin-bottom: 16px; padding: 12px; border-radius: 12px; background-color: #f8f9fa; position: relative; animation: slideIn 0.3s ease-out; } @keyframes slideIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } .conversation-speaker { display: flex; align-items: center; margin-bottom: 8px; font-weight: 600; } .conversation-speaker-avatar { display: inline-flex; align-items: center; justify-content: center; width: 25px; height: 25px; border-radius: 50%; color: white; font-size: 11px; margin-right: 8px; } .conversation-text { margin-left: 33px; line-height: 1.5; } .conversation-time { font-size: 0.8rem; color: #6c757d; margin-left: auto; } .conversation-translation { font-style: italic; opacity: 0.9; } /* Speaker list responsive */ @media (max-width: 768px) { .speaker-button { min-width: 100px; padding: 6px 12px; font-size: 0.9rem; } .speaker-avatar { width: 25px; height: 25px; font-size: 10px; } }