/* ===================================================== RATING PREDICTOR - CUSTOM STYLES Features: Dark Mode, Toast, Skeleton, Highlighting ===================================================== */ /* ============ CSS VARIABLES ============ */ :root { /* Light mode colors */ --bg-primary: #f0f5ff; --bg-secondary: #ffffff; --bg-gradient-from: #eff6ff; --bg-gradient-to: #e0e7ff; --text-primary: #1f2937; --text-secondary: #4b5563; --text-muted: #6b7280; --border-color: #d1d5db; --card-bg: #ffffff; --card-shadow: rgba(0, 0, 0, 0.1); --header-bg: #ffffff; --input-bg: #ffffff; --table-hover: #f9fafb; } /* Dark mode colors */ .dark { --bg-primary: #0f172a; --bg-secondary: #1e293b; --bg-gradient-from: #0f172a; --bg-gradient-to: #1e1b4b; --text-primary: #f1f5f9; --text-secondary: #cbd5e1; --text-muted: #94a3b8; --border-color: #334155; --card-bg: #1e293b; --card-shadow: rgba(0, 0, 0, 0.3); --header-bg: #1e293b; --input-bg: #334155; --table-hover: #334155; } /* Apply variables to body */ body { background: linear-gradient(to bottom right, var(--bg-gradient-from), var(--bg-gradient-to)); color: var(--text-primary); transition: background 0.3s ease, color 0.3s ease; } .dark body { background: linear-gradient(to bottom right, var(--bg-gradient-from), var(--bg-gradient-to)); } /* ============ DARK MODE COMPONENTS ============ */ .dark .bg-white { background-color: var(--card-bg) !important; } .dark .bg-gray-100 { background-color: #334155 !important; } .dark .bg-gray-50 { background-color: #1e293b !important; } .dark .text-gray-800 { color: var(--text-primary) !important; } .dark .text-gray-700 { color: var(--text-secondary) !important; } .dark .text-gray-600 { color: var(--text-muted) !important; } .dark .text-gray-500 { color: var(--text-muted) !important; } .dark .border-gray-300 { border-color: var(--border-color) !important; } .dark .border-gray-200 { border-color: var(--border-color) !important; } .dark input, .dark textarea, .dark select { background-color: var(--input-bg) !important; border-color: var(--border-color) !important; color: var(--text-primary) !important; } .dark input::placeholder, .dark textarea::placeholder { color: var(--text-muted) !important; } .dark .shadow-lg, .dark .shadow-md, .dark .shadow { box-shadow: 0 4px 6px -1px var(--card-shadow), 0 2px 4px -1px var(--card-shadow) !important; } .dark .hover\:bg-gray-50:hover { background-color: var(--table-hover) !important; } .dark .divide-gray-200 > * + * { border-color: var(--border-color) !important; } /* ============ TOAST NOTIFICATIONS ============ */ .toast-container { position: fixed; top: 20px; right: 20px; z-index: 9999; display: flex; flex-direction: column; gap: 10px; max-width: 400px; } .toast { display: flex; align-items: center; padding: 16px 20px; border-radius: 12px; box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15); animation: slideIn 0.3s ease-out, fadeOut 0.3s ease-in forwards; animation-delay: 0s, var(--toast-duration, 3s); backdrop-filter: blur(10px); } .toast-success { background: linear-gradient(135deg, #10b981, #059669); color: white; } .toast-error { background: linear-gradient(135deg, #ef4444, #dc2626); color: white; } .toast-warning { background: linear-gradient(135deg, #f59e0b, #d97706); color: white; } .toast-info { background: linear-gradient(135deg, #3b82f6, #2563eb); color: white; } .toast-icon { font-size: 1.5rem; margin-right: 12px; } .toast-content { flex: 1; } .toast-title { font-weight: 600; font-size: 0.95rem; margin-bottom: 2px; } .toast-message { font-size: 0.85rem; opacity: 0.9; } .toast-close { background: none; border: none; color: white; cursor: pointer; padding: 4px; margin-left: 12px; opacity: 0.7; transition: opacity 0.2s; } .toast-close:hover { opacity: 1; } @keyframes slideIn { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } } @keyframes fadeOut { from { opacity: 1; transform: translateX(0); } to { opacity: 0; transform: translateX(100%); } } /* ============ LOADING SKELETON ============ */ .skeleton { background: linear-gradient(90deg, #e5e7eb 25%, #f3f4f6 50%, #e5e7eb 75%); background-size: 200% 100%; animation: shimmer 1.5s infinite; border-radius: 8px; } .dark .skeleton { background: linear-gradient(90deg, #334155 25%, #475569 50%, #334155 75%); background-size: 200% 100%; } @keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } } .skeleton-text { height: 16px; margin-bottom: 8px; } .skeleton-text-sm { height: 12px; margin-bottom: 6px; } .skeleton-title { height: 24px; width: 60%; margin-bottom: 12px; } .skeleton-box { height: 100px; width: 100%; } .skeleton-circle { border-radius: 50%; } .skeleton-card { padding: 20px; background: var(--card-bg); border-radius: 12px; } /* Loading overlay */ .loading-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0, 0, 0, 0.5); display: flex; align-items: center; justify-content: center; z-index: 9998; backdrop-filter: blur(4px); } .loading-spinner { width: 50px; height: 50px; border: 4px solid rgba(255, 255, 255, 0.3); border-top-color: #ffffff; border-radius: 50%; animation: spin 1s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } /* ============ KEYWORD HIGHLIGHTING ============ */ .highlight-positive { background: linear-gradient(120deg, #bbf7d0 0%, #86efac 100%); padding: 2px 6px; border-radius: 4px; color: #166534; font-weight: 500; } .highlight-negative { background: linear-gradient(120deg, #fecaca 0%, #fca5a5 100%); padding: 2px 6px; border-radius: 4px; color: #991b1b; font-weight: 500; } .highlight-neutral { background: linear-gradient(120deg, #fef3c7 0%, #fde68a 100%); padding: 2px 6px; border-radius: 4px; color: #92400e; font-weight: 500; } .dark .highlight-positive { background: linear-gradient(120deg, #166534 0%, #15803d 100%); color: #bbf7d0; } .dark .highlight-negative { background: linear-gradient(120deg, #991b1b 0%, #b91c1c 100%); color: #fecaca; } .dark .highlight-neutral { background: linear-gradient(120deg, #92400e 0%, #a16207 100%); color: #fef3c7; } /* ============ EXPLANATION/INTERPRETABILITY ============ */ .explanation-container { margin-top: 16px; padding: 16px; background: linear-gradient(135deg, #f8fafc, #f1f5f9); border-radius: 12px; border: 1px solid #e2e8f0; } .dark .explanation-container { background: linear-gradient(135deg, #1e293b, #334155); border-color: #475569; } .word-importance { display: inline-flex; align-items: center; margin: 4px; padding: 4px 10px; border-radius: 20px; font-size: 0.875rem; transition: transform 0.2s; } .word-importance:hover { transform: scale(1.1); } .importance-bar { height: 24px; border-radius: 4px; display: flex; align-items: center; justify-content: space-between; padding: 0 8px; margin-bottom: 4px; font-size: 0.8rem; font-weight: 500; } .importance-positive { background: linear-gradient(90deg, rgba(34, 197, 94, 0.2), rgba(34, 197, 94, 0.6)); color: #166534; } .importance-negative { background: linear-gradient(90deg, rgba(239, 68, 68, 0.6), rgba(239, 68, 68, 0.2)); color: #991b1b; } .dark .importance-positive { color: #86efac; } .dark .importance-negative { color: #fca5a5; } /* ============ N-GRAM ANALYSIS ============ */ .ngram-container { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; } .ngram-badge { display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px; background: linear-gradient(135deg, #818cf8, #6366f1); color: white; border-radius: 20px; font-size: 0.85rem; transition: transform 0.2s, box-shadow 0.2s; } .ngram-badge:hover { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(99, 102, 241, 0.4); } .ngram-count { background: rgba(255, 255, 255, 0.2); padding: 2px 8px; border-radius: 12px; font-size: 0.75rem; font-weight: 600; } .ngram-chart-container { height: 300px; margin-top: 16px; } /* ============ DARK MODE TOGGLE ============ */ .dark-mode-toggle { position: relative; width: 60px; height: 30px; background: linear-gradient(135deg, #fbbf24, #f59e0b); border-radius: 15px; cursor: pointer; transition: background 0.3s; border: none; padding: 0; } .dark .dark-mode-toggle { background: linear-gradient(135deg, #1e3a5f, #0f172a); } .dark-mode-toggle::before { content: '☀️'; position: absolute; left: 4px; top: 50%; transform: translateY(-50%); font-size: 18px; transition: opacity 0.3s; } .dark .dark-mode-toggle::before { opacity: 0; } .dark-mode-toggle::after { content: '🌙'; position: absolute; right: 4px; top: 50%; transform: translateY(-50%); font-size: 18px; opacity: 0; transition: opacity 0.3s; } .dark .dark-mode-toggle::after { opacity: 1; } .toggle-ball { position: absolute; width: 24px; height: 24px; background: white; border-radius: 50%; top: 3px; left: 3px; transition: transform 0.3s; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); } .dark .toggle-ball { transform: translateX(30px); } /* ============ ANIMATIONS ============ */ @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } .fade-in { animation: fadeIn 0.3s ease-out; } @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } } .pulse { animation: pulse 2s infinite; } @keyframes bounce { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-5px); } } .bounce { animation: bounce 0.5s ease; } /* ============ RESPONSIVE ============ */ @media (max-width: 640px) { .toast-container { left: 10px; right: 10px; max-width: none; } .toast { padding: 12px 16px; } }