/* === FILE: app/static/css/style.css === */ /* Custom scrollbar */ ::-webkit-scrollbar { width: 12px; height: 12px; } ::-webkit-scrollbar-track { background: #0f1117; border-radius: 10px; } ::-webkit-scrollbar-thumb { background: linear-gradient(180deg, #6366f1, #8b5cf6); border-radius: 10px; border: 2px solid #0f1117; } ::-webkit-scrollbar-thumb:hover { background: linear-gradient(180deg, #4f46e5, #7c3aed); } /* Drop zone states */ #drop-zone { transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); } #drop-zone.drag-over { border-color: #6366f1 !important; background-color: rgba(99, 102, 241, 0.1) !important; transform: scale(1.02); } /* File card hover effect */ .file-card { transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); } .file-card:hover { transform: translateY(-4px) scale(1.02); } /* Progress bar animation */ #progress-bar { transition: width 0.3s cubic-bezier(0.4, 0, 0.2, 1); position: relative; overflow: hidden; } #progress-bar::after { content: ""; position: absolute; top: 0; left: 0; bottom: 0; right: 0; background: linear-gradient( 90deg, transparent, rgba(255, 255, 255, 0.3), transparent ); animation: shimmer 2s infinite; } @keyframes shimmer { 0% { transform: translateX(-100%); } 100% { transform: translateX(100%); } } /* Button loading spinner */ .btn-loading { position: relative; pointer-events: none; opacity: 0.7; } .btn-loading::after { content: ""; position: absolute; width: 20px; height: 20px; top: 50%; left: 50%; margin-left: -10px; margin-top: -10px; border: 3px solid rgba(255, 255, 255, 0.3); border-radius: 50%; border-top-color: #ffffff; animation: spin 0.8s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } /* Modal animations */ .modal-enter { animation: modalFadeIn 0.3s cubic-bezier(0.4, 0, 0.2, 1); } @keyframes modalFadeIn { from { opacity: 0; transform: scale(0.95) translateY(20px); } to { opacity: 1; transform: scale(1) translateY(0); } } .modal-exit { animation: modalFadeOut 0.2s cubic-bezier(0.4, 0, 1, 1); } @keyframes modalFadeOut { from { opacity: 1; transform: scale(1) translateY(0); } to { opacity: 0; transform: scale(0.95) translateY(20px); } } /* Smooth transitions */ button, a, .action-btn { transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); } /* Action button styles */ .action-btn:hover { transform: translateY(-2px); } .action-btn:active { transform: translateY(0); } /* Flash message animation */ .flash-message { animation: slideInRight 0.3s cubic-bezier(0.4, 0, 0.2, 1); } @keyframes slideInRight { from { opacity: 0; transform: translateX(100%); } to { opacity: 1; transform: translateX(0); } } /* Pulse animation for empty state */ @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } } .animate-pulse { animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; } /* Gradient text animation */ @keyframes gradient { 0% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } 100% { background-position: 0% 50%; } } .bg-clip-text { -webkit-background-clip: text; background-clip: text; } /* Glassmorphism effect */ .glass { background: rgba(26, 29, 39, 0.8); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); border: 1px solid rgba(255, 255, 255, 0.1); } /* Hover glow effect */ .hover-glow { position: relative; } .hover-glow::before { content: ""; position: absolute; inset: 0; border-radius: inherit; padding: 2px; background: linear-gradient(45deg, #6366f1, #8b5cf6, #ec4899); -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); -webkit-mask-composite: xor; mask-composite: exclude; opacity: 0; transition: opacity 0.3s; } .hover-glow:hover::before { opacity: 1; }