Spaces:
Sleeping
Sleeping
| /* ============================================ | |
| ECHO TUTOR PRO — Premium Design System | |
| ============================================ */ | |
| /* --- CSS Custom Properties --- */ | |
| :root { | |
| --bg-primary: #0a0e1a; | |
| --bg-secondary: #111827; | |
| --bg-card: rgba(17, 24, 39, 0.6); | |
| --bg-glass: rgba(255, 255, 255, 0.04); | |
| --bg-glass-hover: rgba(255, 255, 255, 0.08); | |
| --border-glass: rgba(255, 255, 255, 0.08); | |
| --border-glow: rgba(99, 179, 237, 0.3); | |
| --accent: #63b3ed; | |
| --accent-bright: #90cdf4; | |
| --accent-dim: #2b6cb0; | |
| --accent-glow: rgba(99, 179, 237, 0.4); | |
| --accent-2: #9f7aea; | |
| --accent-2-glow: rgba(159, 122, 234, 0.3); | |
| --text-primary: #f7fafc; | |
| --text-secondary: #a0aec0; | |
| --text-muted: #718096; | |
| --success: #68d391; | |
| --warning: #f6ad55; | |
| --error: #fc8181; | |
| --user-msg: rgba(99, 179, 237, 0.12); | |
| --user-msg-border: rgba(99, 179, 237, 0.25); | |
| --ai-msg: rgba(159, 122, 234, 0.1); | |
| --ai-msg-border: rgba(159, 122, 234, 0.2); | |
| --radius-sm: 8px; | |
| --radius-md: 14px; | |
| --radius-lg: 20px; | |
| --radius-xl: 28px; | |
| --radius-full: 50%; | |
| --shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.3); | |
| --shadow-md: 0 4px 20px rgba(0, 0, 0, 0.4); | |
| --shadow-lg: 0 8px 40px rgba(0, 0, 0, 0.5); | |
| --shadow-glow: 0 0 30px var(--accent-glow); | |
| --font-body: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; | |
| --font-mono: 'JetBrains Mono', monospace; | |
| --transition-fast: 0.15s ease; | |
| --transition-normal: 0.3s cubic-bezier(0.4, 0, 0.2, 1); | |
| --transition-slow: 0.5s cubic-bezier(0.4, 0, 0.2, 1); | |
| } | |
| /* --- Reset & Base --- */ | |
| *, | |
| *::before, | |
| *::after { | |
| box-sizing: border-box; | |
| margin: 0; | |
| padding: 0; | |
| } | |
| html { | |
| font-size: 16px; | |
| scroll-behavior: smooth; | |
| } | |
| body { | |
| font-family: var(--font-body); | |
| background: var(--bg-primary); | |
| color: var(--text-primary); | |
| min-height: 100vh; | |
| min-height: 100dvh; | |
| overflow-x: hidden; | |
| overflow-y: hidden; | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| justify-content: center; | |
| -webkit-font-smoothing: antialiased; | |
| } | |
| /* --- Particle Background --- */ | |
| #particles-canvas { | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| z-index: 0; | |
| pointer-events: none; | |
| } | |
| /* --- Toast Notification --- */ | |
| .toast { | |
| position: fixed; | |
| top: 20px; | |
| left: 50%; | |
| transform: translateX(-50%) translateY(-100px); | |
| background: rgba(17, 24, 39, 0.95); | |
| -webkit-backdrop-filter: blur(20px); | |
| backdrop-filter: blur(20px); | |
| border-left: 4px solid var(--accent-primary); | |
| border-radius: var(--radius-md); | |
| padding: 14px 24px; | |
| font-size: 0.9rem; | |
| font-weight: 500; | |
| color: #fff; | |
| box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3); | |
| z-index: 9999; | |
| transition: transform 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275); | |
| pointer-events: none; | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| } | |
| .toast.visible { | |
| transform: translateX(-50%) translateY(0); | |
| } | |
| .toast.error { | |
| border-left-color: var(--error); | |
| } | |
| .toast.success { | |
| border-left-color: var(--success); | |
| } | |
| /* --- RTL Support --- */ | |
| [dir="rtl"] { | |
| font-family: 'Cairo', 'Inter', sans-serif; | |
| } | |
| [dir="rtl"] .header-left { | |
| flex-direction: row-reverse; | |
| } | |
| [dir="rtl"] .header-left img { | |
| margin-right: 0 ; | |
| margin-left: 12px ; | |
| } | |
| [dir="rtl"] .header-right { | |
| flex-direction: row-reverse; | |
| } | |
| [dir="rtl"] .message.user { | |
| align-self: flex-start; | |
| border-radius: 18px 18px 4px 18px; | |
| } | |
| [dir="rtl"] .message.ai { | |
| align-self: flex-end; | |
| border-radius: 18px 18px 18px 4px; | |
| } | |
| [dir="rtl"] .input-wrapper { | |
| flex-direction: row-reverse; | |
| } | |
| [dir="rtl"] .chat-input { | |
| text-align: right; | |
| } | |
| [dir="rtl"] .modal-header { | |
| flex-direction: row-reverse; | |
| } | |
| [dir="rtl"] .modal-close { | |
| margin-left: 0; | |
| margin-right: auto; | |
| } | |
| [dir="rtl"] .nav-tab { | |
| flex-direction: column; | |
| } | |
| [dir="rtl"] .streak-display { | |
| margin-left: 10px; | |
| margin-right: 0; | |
| } | |
| /* ============================================ | |
| ONBOARDING SCREEN | |
| ============================================ */ | |
| .onboarding-screen { | |
| position: fixed; | |
| inset: 0; | |
| z-index: 100; | |
| display: block; | |
| background: var(--bg-primary); | |
| animation: fadeIn 0.6s ease; | |
| overflow-y: auto; | |
| padding: 0; | |
| } | |
| .onboarding-screen.hidden { | |
| opacity: 0; | |
| pointer-events: none; | |
| transition: opacity 0.5s ease; | |
| } | |
| /* Make onboarding-content always centered and scrollable if needed */ | |
| .onboarding-content { | |
| position: absolute; | |
| top: 0; | |
| left: 50%; | |
| transform: translateX(-50%); | |
| width: 100%; | |
| max-width: 520px; | |
| min-height: 100vh; | |
| box-sizing: border-box; | |
| text-align: center; | |
| padding: 32px 12px 32px 12px; | |
| animation: slideUp 0.7s cubic-bezier(0.16, 1, 0.3, 1); | |
| overflow-y: auto; | |
| } | |
| /* Logo Orb */ | |
| .onboarding-logo { | |
| margin-bottom: 24px; | |
| display: flex; | |
| justify-content: center; | |
| } | |
| .logo-orb { | |
| width: 80px; | |
| height: 80px; | |
| position: relative; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| } | |
| .logo-core { | |
| width: 36px; | |
| height: 36px; | |
| background: radial-gradient( | |
| circle, | |
| var(--accent-bright) 0%, | |
| var(--accent) 50%, | |
| var(--accent-dim) 100% | |
| ); | |
| border-radius: var(--radius-full); | |
| box-shadow: | |
| 0 0 20px var(--accent-glow), | |
| 0 0 60px rgba(99, 179, 237, 0.15); | |
| animation: corePulse 3s ease-in-out infinite; | |
| } | |
| .logo-ring { | |
| position: absolute; | |
| border-radius: var(--radius-full); | |
| border: 1.5px solid; | |
| } | |
| .logo-ring.ring-1 { | |
| width: 58px; | |
| height: 58px; | |
| border-color: rgba(99, 179, 237, 0.25); | |
| animation: ringRotate 8s linear infinite; | |
| } | |
| .logo-ring.ring-2 { | |
| width: 76px; | |
| height: 76px; | |
| border-color: rgba(159, 122, 234, 0.15); | |
| animation: ringRotate 12s linear infinite reverse; | |
| } | |
| .onboarding-title { | |
| font-size: 2.2rem; | |
| font-weight: 700; | |
| letter-spacing: 3px; | |
| margin-bottom: 6px; | |
| } | |
| .accent { | |
| color: var(--accent); | |
| } | |
| .onboarding-subtitle { | |
| font-size: 0.95rem; | |
| color: var(--text-muted); | |
| margin-bottom: 32px; | |
| font-weight: 300; | |
| } | |
| /* Selection Sections */ | |
| .selection-section { | |
| margin-bottom: 24px; | |
| } | |
| .selection-label { | |
| font-size: 0.8rem; | |
| text-transform: uppercase; | |
| letter-spacing: 2px; | |
| color: var(--text-muted); | |
| margin-bottom: 12px; | |
| font-weight: 500; | |
| } | |
| /* Level Cards */ | |
| .level-cards { | |
| display: flex; | |
| gap: 10px; | |
| justify-content: center; | |
| } | |
| .level-card { | |
| background: var(--bg-glass); | |
| -webkit-backdrop-filter: blur(10px); | |
| backdrop-filter: blur(10px); | |
| border: 1px solid var(--border-glass); | |
| border-radius: var(--radius-md); | |
| padding: 14px 16px; | |
| min-width: 130px; | |
| cursor: pointer; | |
| transition: all var(--transition-normal); | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| gap: 4px; | |
| color: var(--text-secondary); | |
| } | |
| .level-card:hover { | |
| background: var(--bg-glass-hover); | |
| border-color: var(--border-glow); | |
| transform: translateY(-2px); | |
| } | |
| .level-card.active { | |
| background: rgba(99, 179, 237, 0.1); | |
| border-color: var(--accent); | |
| color: var(--text-primary); | |
| box-shadow: var(--shadow-glow); | |
| } | |
| .level-icon { | |
| font-size: 1.5rem; | |
| } | |
| .level-name { | |
| font-size: 0.85rem; | |
| font-weight: 600; | |
| } | |
| .level-desc { | |
| font-size: 0.7rem; | |
| color: var(--text-muted); | |
| } | |
| /* Topic Grid */ | |
| .topic-grid { | |
| display: grid; | |
| grid-template-columns: repeat(4, 1fr); | |
| gap: 8px; | |
| } | |
| .topic-card { | |
| background: var(--bg-glass); | |
| -webkit-backdrop-filter: blur(10px); | |
| backdrop-filter: blur(10px); | |
| border: 1px solid var(--border-glass); | |
| border-radius: var(--radius-sm); | |
| padding: 12px 6px; | |
| cursor: pointer; | |
| transition: all var(--transition-normal); | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| gap: 4px; | |
| color: var(--text-secondary); | |
| font-size: 0.75rem; | |
| } | |
| .topic-card:hover { | |
| background: var(--bg-glass-hover); | |
| border-color: var(--border-glow); | |
| transform: translateY(-2px); | |
| } | |
| .topic-card.active { | |
| background: rgba(159, 122, 234, 0.1); | |
| border-color: var(--accent-2); | |
| color: var(--text-primary); | |
| box-shadow: 0 0 20px var(--accent-2-glow); | |
| } | |
| .topic-icon { | |
| font-size: 1.3rem; | |
| } | |
| .topic-name { | |
| font-weight: 500; | |
| } | |
| /* Start Button */ | |
| .start-btn { | |
| margin-top: 28px; | |
| padding: 14px 44px; | |
| background: linear-gradient(135deg, var(--accent) 0%, var(--accent-2) 100%); | |
| border: none; | |
| border-radius: var(--radius-xl); | |
| color: white; | |
| font-size: 1rem; | |
| font-weight: 600; | |
| cursor: pointer; | |
| display: inline-flex; | |
| align-items: center; | |
| gap: 10px; | |
| transition: all var(--transition-normal); | |
| box-shadow: 0 4px 20px var(--accent-glow); | |
| letter-spacing: 0.5px; | |
| } | |
| .start-btn:hover { | |
| transform: translateY(-2px) scale(1.02); | |
| box-shadow: 0 8px 30px var(--accent-glow); | |
| } | |
| .start-btn:active { | |
| transform: scale(0.98); | |
| } | |
| /* ============================================ | |
| MAIN APP CONTAINER | |
| ============================================ */ | |
| .app-container { | |
| position: relative; | |
| z-index: 1; | |
| width: 100%; | |
| max-width: 480px; | |
| height: 100vh; | |
| height: 100dvh; | |
| display: flex; | |
| flex-direction: column; | |
| padding: 0 16px; | |
| animation: fadeIn 0.5s ease; | |
| /* Prevent content being hidden under keyboard on iOS */ | |
| padding-bottom: env(safe-area-inset-bottom, 0px); | |
| } | |
| .app-container.hidden { | |
| display: none; | |
| } | |
| /* --- Header --- */ | |
| .app-header { | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| padding: 14px 0 10px; | |
| flex-shrink: 0; | |
| } | |
| .header-left { | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| } | |
| .header-orb { | |
| width: 32px; | |
| height: 32px; | |
| border-radius: var(--radius-full); | |
| background: rgba(99, 179, 237, 0.1); | |
| border: 1.5px solid rgba(99, 179, 237, 0.3); | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| } | |
| .header-orb-core { | |
| width: 14px; | |
| height: 14px; | |
| background: var(--accent); | |
| border-radius: var(--radius-full); | |
| box-shadow: 0 0 10px var(--accent-glow); | |
| animation: corePulse 3s ease-in-out infinite; | |
| } | |
| .header-title { | |
| font-size: 1rem; | |
| font-weight: 700; | |
| letter-spacing: 2px; | |
| } | |
| .header-status { | |
| font-size: 0.65rem; | |
| color: var(--text-muted); | |
| text-transform: uppercase; | |
| letter-spacing: 1px; | |
| } | |
| .header-right { | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| } | |
| .session-stats { | |
| display: flex; | |
| gap: 10px; | |
| } | |
| .stat { | |
| font-size: 0.72rem; | |
| color: var(--text-muted); | |
| font-family: var(--font-mono); | |
| } | |
| .icon-btn { | |
| width: 36px; | |
| height: 36px; | |
| border-radius: var(--radius-full); | |
| background: var(--bg-glass); | |
| border: 1px solid var(--border-glass); | |
| color: var(--text-muted); | |
| cursor: pointer; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| transition: all var(--transition-fast); | |
| } | |
| .icon-btn:hover { | |
| background: var(--bg-glass-hover); | |
| border-color: var(--border-glow); | |
| color: var(--text-primary); | |
| } | |
| /* --- Avatar Section --- */ | |
| .avatar-section { | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| padding: 10px 0 8px; | |
| flex-shrink: 0; | |
| } | |
| .avatar-container { | |
| position: relative; | |
| width: 140px; | |
| height: 140px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| } | |
| /* Avatar Glow */ | |
| .avatar-glow { | |
| position: absolute; | |
| width: 120px; | |
| height: 120px; | |
| border-radius: var(--radius-full); | |
| background: radial-gradient(circle, var(--accent-glow) 0%, transparent 70%); | |
| filter: blur(20px); | |
| opacity: 0.4; | |
| transition: | |
| opacity var(--transition-normal), | |
| background var(--transition-normal); | |
| animation: glowPulse 4s ease-in-out infinite; | |
| } | |
| /* Avatar Rings */ | |
| .avatar-ring { | |
| position: absolute; | |
| border-radius: var(--radius-full); | |
| border: 1.5px solid; | |
| transition: all var(--transition-normal); | |
| } | |
| .ring-outer { | |
| width: 130px; | |
| height: 130px; | |
| border-color: rgba(99, 179, 237, 0.12); | |
| animation: ringRotate 10s linear infinite; | |
| } | |
| .ring-inner { | |
| width: 110px; | |
| height: 110px; | |
| border-color: rgba(159, 122, 234, 0.12); | |
| animation: ringRotate 7s linear infinite reverse; | |
| } | |
| /* Avatar Orb */ | |
| .avatar-orb { | |
| width: 88px; | |
| height: 88px; | |
| border-radius: var(--radius-full); | |
| background: linear-gradient(135deg, #1a365d 0%, #2b6cb0 50%, #1a365d 100%); | |
| border: 2px solid rgba(99, 179, 237, 0.3); | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| position: relative; | |
| z-index: 2; | |
| transition: all var(--transition-normal); | |
| animation: | |
| float 5s ease-in-out infinite, | |
| breathe 4s ease-in-out infinite; | |
| box-shadow: | |
| inset 0 -4px 12px rgba(0, 0, 0, 0.3), | |
| 0 0 20px var(--accent-glow); | |
| } | |
| /* Breathing animation */ | |
| .orb-breath { | |
| position: absolute; | |
| inset: -4px; | |
| border-radius: var(--radius-full); | |
| background: radial-gradient( | |
| circle, | |
| rgba(99, 179, 237, 0.1) 0%, | |
| transparent 70% | |
| ); | |
| animation: breatheGlow 4s ease-in-out infinite; | |
| pointer-events: none; | |
| } | |
| /* Avatar mini particles */ | |
| .avatar-particles { | |
| position: absolute; | |
| inset: -20px; | |
| pointer-events: none; | |
| z-index: 1; | |
| } | |
| /* Orb Face */ | |
| .orb-face { | |
| width: 60px; | |
| height: 60px; | |
| position: relative; | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| justify-content: center; | |
| } | |
| /* Eyebrows */ | |
| .orb-brows { | |
| display: flex; | |
| gap: 18px; | |
| margin-bottom: 2px; | |
| position: relative; | |
| z-index: 5; | |
| } | |
| .orb-brow { | |
| width: 12px; | |
| height: 3px; | |
| background: var(--accent-bright); | |
| border-radius: 3px; | |
| transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); | |
| opacity: 0.8; | |
| } | |
| .orb-brow.left { | |
| transform: rotate(-8deg); | |
| } | |
| .orb-brow.right { | |
| transform: rotate(8deg); | |
| } | |
| /* Eyes */ | |
| .orb-eyes { | |
| display: flex; | |
| gap: 14px; | |
| margin-bottom: 6px; | |
| } | |
| .orb-eye { | |
| width: 14px; | |
| height: 14px; | |
| background: var(--accent-bright); | |
| border-radius: var(--radius-full); | |
| position: relative; | |
| transition: all 0.2s ease; | |
| box-shadow: 0 0 8px var(--accent-glow); | |
| overflow: hidden; | |
| } | |
| .orb-pupil { | |
| width: 5px; | |
| height: 5px; | |
| background: white; | |
| border-radius: var(--radius-full); | |
| position: absolute; | |
| top: 4px; | |
| left: 4px; | |
| transition: all 0.1s ease; | |
| z-index: 2; | |
| } | |
| .orb-eyelid { | |
| position: absolute; | |
| top: -100%; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| background: #1a365d; | |
| border-radius: var(--radius-full); | |
| transition: top 0.08s ease; | |
| z-index: 3; | |
| } | |
| .orb-eye-shine { | |
| position: absolute; | |
| top: 2px; | |
| right: 2px; | |
| width: 4px; | |
| height: 4px; | |
| background: rgba(255, 255, 255, 0.7); | |
| border-radius: var(--radius-full); | |
| z-index: 4; | |
| pointer-events: none; | |
| } | |
| /* Cheeks */ | |
| .orb-cheeks { | |
| display: flex; | |
| justify-content: space-between; | |
| width: 50px; | |
| position: absolute; | |
| top: 32px; | |
| } | |
| .orb-cheek { | |
| width: 8px; | |
| height: 5px; | |
| border-radius: var(--radius-full); | |
| background: rgba(252, 129, 129, 0); | |
| transition: all 0.5s ease; | |
| } | |
| /* Mouth with lip-sync bars */ | |
| .orb-mouth-area { | |
| display: flex; | |
| justify-content: center; | |
| } | |
| .orb-mouth { | |
| display: flex; | |
| align-items: flex-end; | |
| justify-content: center; | |
| gap: 1px; | |
| height: 12px; | |
| width: 22px; | |
| transition: all var(--transition-fast); | |
| } | |
| .mouth-bar { | |
| width: 3px; | |
| height: 3px; | |
| background: var(--accent); | |
| border-radius: 1px; | |
| transition: | |
| height 0.08s ease, | |
| background 0.2s ease; | |
| } | |
| /* Emotion indicator */ | |
| .emotion-indicator { | |
| font-size: 1.1rem; | |
| height: 22px; | |
| margin-top: 4px; | |
| transition: all 0.4s ease; | |
| opacity: 0; | |
| } | |
| .emotion-indicator.visible { | |
| opacity: 1; | |
| animation: emotionPop 0.4s cubic-bezier(0.34, 1.56, 0.64, 1); | |
| } | |
| /* ─── AVATAR STATES ─── */ | |
| /* IDLE — Relaxed, slight smile */ | |
| .avatar-container .orb-brow.left { | |
| transform: rotate(-8deg); | |
| } | |
| .avatar-container .orb-brow.right { | |
| transform: rotate(8deg); | |
| } | |
| .avatar-container .mouth-bar { | |
| height: 3px; | |
| background: var(--accent); | |
| } | |
| .avatar-container .mouth-bar:nth-child(2), | |
| .avatar-container .mouth-bar:nth-child(4) { | |
| height: 4px; | |
| } | |
| .avatar-container .mouth-bar:nth-child(3) { | |
| height: 5px; | |
| } | |
| /* LISTENING — Alert, wide eyes, raised brows */ | |
| .avatar-container.listening .avatar-glow { | |
| opacity: 0.6; | |
| background: radial-gradient( | |
| circle, | |
| rgba(72, 187, 120, 0.4) 0%, | |
| transparent 70% | |
| ); | |
| } | |
| .avatar-container.listening .avatar-orb { | |
| border-color: rgba(72, 187, 120, 0.5); | |
| box-shadow: | |
| inset 0 -4px 12px rgba(0, 0, 0, 0.3), | |
| 0 0 30px rgba(72, 187, 120, 0.3); | |
| animation: | |
| float 5s ease-in-out infinite, | |
| breathe 2s ease-in-out infinite; | |
| } | |
| .avatar-container.listening .orb-eye { | |
| background: var(--success); | |
| box-shadow: 0 0 12px rgba(72, 187, 120, 0.5); | |
| width: 16px; | |
| height: 16px; | |
| } | |
| .avatar-container.listening .orb-pupil { | |
| width: 6px; | |
| height: 6px; | |
| top: 5px; | |
| left: 5px; | |
| } | |
| .avatar-container.listening .orb-brow.left { | |
| transform: rotate(-2deg) translateY(-3px); | |
| } | |
| .avatar-container.listening .orb-brow.right { | |
| transform: rotate(2deg) translateY(-3px); | |
| } | |
| .avatar-container.listening .mouth-bar { | |
| height: 2px; | |
| background: var(--success); | |
| } | |
| .avatar-container.listening .mouth-bar:nth-child(3) { | |
| height: 3px; | |
| } | |
| .avatar-container.listening .ring-outer { | |
| border-color: rgba(72, 187, 120, 0.2); | |
| animation-duration: 3s; | |
| } | |
| .avatar-container.listening .ring-inner { | |
| border-color: rgba(72, 187, 120, 0.15); | |
| animation-duration: 2s; | |
| } | |
| .avatar-container.listening .orb-cheek { | |
| background: rgba(72, 187, 120, 0.15); | |
| } | |
| /* SPEAKING — Animated mouth bars, expressive brows */ | |
| .avatar-container.speaking .avatar-glow { | |
| opacity: 0.7; | |
| background: radial-gradient(circle, var(--accent-2-glow) 0%, transparent 70%); | |
| } | |
| .avatar-container.speaking .avatar-orb { | |
| border-color: rgba(159, 122, 234, 0.5); | |
| box-shadow: | |
| inset 0 -4px 12px rgba(0, 0, 0, 0.3), | |
| 0 0 30px var(--accent-2-glow); | |
| } | |
| .avatar-container.speaking .orb-eye { | |
| background: var(--accent-2); | |
| box-shadow: 0 0 12px var(--accent-2-glow); | |
| width: 13px; | |
| height: 13px; | |
| } | |
| .avatar-container.speaking .orb-brow.left { | |
| transform: rotate(-12deg) translateY(-2px); | |
| } | |
| .avatar-container.speaking .orb-brow.right { | |
| transform: rotate(12deg) translateY(-2px); | |
| } | |
| .avatar-container.speaking .orb-brow { | |
| background: var(--accent-2); | |
| } | |
| .avatar-container.speaking .mouth-bar { | |
| background: var(--accent-2); | |
| } | |
| .avatar-container.speaking .ring-outer { | |
| border-color: rgba(159, 122, 234, 0.2); | |
| animation-duration: 4s; | |
| } | |
| .avatar-container.speaking .orb-cheek { | |
| background: rgba(159, 122, 234, 0.1); | |
| } | |
| /* THINKING — Squinting, concentrated */ | |
| .avatar-container.thinking .avatar-glow { | |
| opacity: 0.5; | |
| animation: glowPulse 1.5s ease-in-out infinite; | |
| } | |
| .avatar-container.thinking .orb-eye { | |
| height: 6px; | |
| width: 14px; | |
| border-radius: 7px; | |
| } | |
| .avatar-container.thinking .orb-pupil { | |
| width: 4px; | |
| height: 3px; | |
| top: 2px; | |
| } | |
| .avatar-container.thinking .orb-brow.left { | |
| transform: rotate(-15deg) translateY(1px); | |
| } | |
| .avatar-container.thinking .orb-brow.right { | |
| transform: rotate(15deg) translateY(1px); | |
| } | |
| .avatar-container.thinking .mouth-bar { | |
| height: 2px; | |
| } | |
| .avatar-container.thinking .mouth-bar:nth-child(3) { | |
| height: 3px; | |
| } | |
| .avatar-container.thinking .ring-outer { | |
| animation-duration: 2s; | |
| } | |
| .avatar-container.thinking .ring-inner { | |
| animation-duration: 1.5s; | |
| } | |
| /* HAPPY — Smiling, blushing cheeks */ | |
| .avatar-container.happy .orb-eye { | |
| height: 8px; | |
| width: 14px; | |
| border-radius: 14px 14px 4px 4px; | |
| } | |
| .avatar-container.happy .orb-cheek { | |
| background: rgba(252, 129, 129, 0.35); | |
| width: 10px; | |
| height: 6px; | |
| } | |
| .avatar-container.happy .orb-brow.left { | |
| transform: rotate(-4deg) translateY(-4px); | |
| } | |
| .avatar-container.happy .orb-brow.right { | |
| transform: rotate(4deg) translateY(-4px); | |
| } | |
| .avatar-container.happy .mouth-bar { | |
| background: var(--success); | |
| height: 4px; | |
| } | |
| .avatar-container.happy .mouth-bar:nth-child(2), | |
| .avatar-container.happy .mouth-bar:nth-child(4) { | |
| height: 6px; | |
| } | |
| .avatar-container.happy .mouth-bar:nth-child(3) { | |
| height: 8px; | |
| } | |
| /* Waveform Canvas */ | |
| .waveform-canvas { | |
| position: absolute; | |
| bottom: -8px; | |
| left: 50%; | |
| transform: translateX(-50%); | |
| z-index: 3; | |
| opacity: 0; | |
| transition: opacity var(--transition-normal); | |
| } | |
| .avatar-container.listening .waveform-canvas { | |
| opacity: 1; | |
| } | |
| /* State Label */ | |
| .state-label { | |
| font-size: 0.75rem; | |
| color: var(--text-muted); | |
| text-transform: uppercase; | |
| letter-spacing: 2px; | |
| margin-top: 8px; | |
| transition: color var(--transition-normal); | |
| } | |
| /* Avatar Character Selector */ | |
| .avatar-chars { | |
| display: flex; | |
| gap: 8px; | |
| justify-content: center; | |
| margin-top: 10px; | |
| } | |
| .char-btn { | |
| background: rgba(255,255,255,0.05); | |
| border: 2px solid transparent; | |
| border-radius: 50%; | |
| width: 36px; | |
| height: 36px; | |
| font-size: 18px; | |
| cursor: pointer; | |
| transition: all 0.2s ease; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| } | |
| .char-btn:hover { | |
| background: rgba(255,255,255,0.12); | |
| transform: scale(1.15); | |
| } | |
| .char-btn.active { | |
| border-color: var(--accent-primary); | |
| background: rgba(99,179,237,0.15); | |
| box-shadow: 0 0 12px rgba(99,179,237,0.3); | |
| } | |
| /* Avatar Character CSS Animations */ | |
| .avatar-orb.char-robot { | |
| background: linear-gradient(135deg, #606778, #2d3142) ; | |
| border-radius: 12px ; | |
| box-shadow: 0 0 30px rgba(100,200,255,0.4) ; | |
| } | |
| .avatar-orb.char-robot::before { | |
| content: ''; | |
| position: absolute; | |
| top: 10px; | |
| left: 50%; | |
| transform: translateX(-50%); | |
| width: 8px; | |
| height: 8px; | |
| background: #00e5ff; | |
| border-radius: 50%; | |
| box-shadow: 0 0 8px #00e5ff; | |
| animation: robotBlink 2s infinite; | |
| } | |
| @keyframes robotBlink { | |
| 0%, 90%, 100% { opacity: 1; } | |
| 95% { opacity: 0; } | |
| } | |
| .avatar-orb.char-owl { | |
| background: linear-gradient(135deg, #6b4c23, #3d2b0c) ; | |
| border-radius: 40% 40% 50% 50% ; | |
| } | |
| .avatar-orb.char-owl::after { | |
| content: '🦉'; | |
| position: absolute; | |
| font-size: 40px; | |
| top: 50%; | |
| left: 50%; | |
| transform: translate(-50%, -50%); | |
| animation: owlBob 2s ease-in-out infinite; | |
| } | |
| @keyframes owlBob { | |
| 0%, 100% { transform: translate(-50%, -50%) rotate(-5deg); } | |
| 50% { transform: translate(-50%, -52%) rotate(5deg); } | |
| } | |
| .avatar-orb.char-star { | |
| background: linear-gradient(135deg, #f6d365, #fda085) ; | |
| clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%) ; | |
| border-radius: 0 ; | |
| animation: starSpin 4s linear infinite ; | |
| } | |
| @keyframes starSpin { | |
| 0% { transform: rotate(0deg) scale(1); } | |
| 50% { transform: rotate(180deg) scale(1.05); } | |
| 100% { transform: rotate(360deg) scale(1); } | |
| } | |
| /* Animated avatar speaking lips */ | |
| .avatar-orb.speaking .orb-mouth { | |
| animation: mouthTalk 0.3s steps(1) infinite; | |
| } | |
| @keyframes mouthTalk { | |
| 0%, 100% { border-radius: 50% 50% 60% 60%; height: 18px; } | |
| 50% { border-radius: 40% 40% 50% 50%; height: 8px; } | |
| } | |
| padding: 16px; | |
| margin-bottom: 10px; | |
| overflow: hidden; | |
| display: flex; | |
| flex-direction: column; | |
| box-shadow: var(--shadow-md); | |
| min-height: 0; | |
| } | |
| .messages-container { | |
| flex: 1; | |
| overflow-y: auto; | |
| display: flex; | |
| flex-direction: column; | |
| gap: 8px; | |
| padding-right: 6px; | |
| scroll-behavior: smooth; | |
| } | |
| /* Custom Scrollbar */ | |
| .messages-container::-webkit-scrollbar { | |
| width: 4px; | |
| } | |
| .messages-container::-webkit-scrollbar-track { | |
| background: transparent; | |
| } | |
| .messages-container::-webkit-scrollbar-thumb { | |
| background: rgba(99, 179, 237, 0.2); | |
| border-radius: 2px; | |
| } | |
| .messages-container::-webkit-scrollbar-thumb:hover { | |
| background: rgba(99, 179, 237, 0.4); | |
| } | |
| /* Message Bubbles */ | |
| .message { | |
| padding: 10px 16px; | |
| border-radius: var(--radius-md); | |
| max-width: 85%; | |
| word-break: break-word; | |
| font-size: 0.9rem; | |
| line-height: 1.55; | |
| animation: msgSlideIn 0.35s cubic-bezier(0.16, 1, 0.3, 1); | |
| position: relative; | |
| } | |
| .message.user { | |
| background: var(--user-msg); | |
| border: 1px solid var(--user-msg-border); | |
| align-self: flex-start; | |
| color: var(--text-primary); | |
| } | |
| .message.ai { | |
| background: var(--ai-msg); | |
| border: 1px solid var(--ai-msg-border); | |
| align-self: flex-end; | |
| color: var(--text-primary); | |
| } | |
| .message.ai-error { | |
| background: rgba(252, 129, 129, 0.1); | |
| border: 1px solid rgba(252, 129, 129, 0.25); | |
| align-self: flex-end; | |
| color: var(--error); | |
| } | |
| /* Streaming message cursor */ | |
| .message.ai.streaming::after { | |
| content: '▋'; | |
| animation: blink 0.8s infinite; | |
| color: var(--accent-2); | |
| margin-left: 2px; | |
| } | |
| /* Inline corrections/suggestions styling */ | |
| .message strong { | |
| color: var(--accent-bright); | |
| font-weight: 600; | |
| } | |
| .message em { | |
| color: var(--accent-2); | |
| font-style: italic; | |
| } | |
| /* Typing Indicator */ | |
| .typing-indicator { | |
| padding: 14px 18px; | |
| display: flex; | |
| align-items: center; | |
| gap: 4px; | |
| } | |
| .typing-indicator span { | |
| display: inline-block; | |
| width: 7px; | |
| height: 7px; | |
| background: var(--accent-2); | |
| border-radius: var(--radius-full); | |
| animation: typingBounce 1.4s infinite; | |
| opacity: 0.7; | |
| } | |
| .typing-indicator span:nth-child(2) { | |
| animation-delay: 0.15s; | |
| } | |
| .typing-indicator span:nth-child(3) { | |
| animation-delay: 0.3s; | |
| } | |
| /* --- Controls Bar --- */ | |
| .controls-bar { | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| padding: 10px 0 20px; | |
| flex-shrink: 0; | |
| /* Always visible above keyboard */ | |
| position: relative; | |
| z-index: 10; | |
| padding-bottom: max(20px, env(safe-area-inset-bottom, 20px)); | |
| } | |
| .ctrl-btn { | |
| width: 46px; | |
| height: 46px; | |
| border-radius: var(--radius-full); | |
| border: 1.5px solid var(--border-glass); | |
| background: var(--bg-glass); | |
| -webkit-backdrop-filter: blur(10px); | |
| backdrop-filter: blur(10px); | |
| color: var(--text-secondary); | |
| cursor: pointer; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| transition: all var(--transition-fast); | |
| flex-shrink: 0; | |
| position: relative; | |
| outline: none; | |
| } | |
| .ctrl-btn:hover { | |
| background: var(--bg-glass-hover); | |
| border-color: var(--border-glow); | |
| color: var(--text-primary); | |
| transform: scale(1.05); | |
| } | |
| .ctrl-btn:active { | |
| transform: scale(0.95); | |
| } | |
| .stt-btn { | |
| min-width: 52px; | |
| padding: 0 6px; | |
| font-size: 0.62rem; | |
| font-weight: 700; | |
| letter-spacing: 0.5px; | |
| } | |
| /* Mic Button */ | |
| .mic-btn.active { | |
| background: rgba(72, 187, 120, 0.15); | |
| border-color: var(--success); | |
| color: var(--success); | |
| } | |
| .mic-pulse { | |
| position: absolute; | |
| width: 100%; | |
| height: 100%; | |
| border-radius: var(--radius-full); | |
| border: 2px solid var(--success); | |
| opacity: 0; | |
| pointer-events: none; | |
| } | |
| .mic-btn.active .mic-pulse { | |
| animation: micPulse 1.5s ease-out infinite; | |
| } | |
| /* Send Button */ | |
| .send-btn { | |
| background: linear-gradient(135deg, var(--accent) 0%, var(--accent-2) 100%); | |
| border: none; | |
| color: white; | |
| } | |
| .send-btn:hover { | |
| box-shadow: 0 0 20px var(--accent-glow); | |
| transform: scale(1.08); | |
| } | |
| /* End Button */ | |
| .end-btn:hover { | |
| border-color: var(--error); | |
| color: var(--error); | |
| background: rgba(252, 129, 129, 0.1); | |
| } | |
| /* Mute Button */ | |
| .mute-btn.muted { | |
| border-color: var(--warning); | |
| color: var(--warning); | |
| } | |
| /* Input */ | |
| .input-wrapper { | |
| flex: 1; | |
| } | |
| .chat-input { | |
| width: 100%; | |
| background: var(--bg-glass); | |
| -webkit-backdrop-filter: blur(10px); | |
| backdrop-filter: blur(10px); | |
| border: 1.5px solid var(--border-glass); | |
| border-radius: var(--radius-xl); | |
| padding: 12px 18px; | |
| color: var(--text-primary); | |
| font-size: 0.9rem; | |
| font-family: var(--font-body); | |
| outline: none; | |
| transition: all var(--transition-fast); | |
| } | |
| .chat-input::placeholder { | |
| color: var(--text-muted); | |
| } | |
| .chat-input:focus { | |
| border-color: var(--border-glow); | |
| box-shadow: 0 0 15px rgba(99, 179, 237, 0.1); | |
| background: var(--bg-glass-hover); | |
| } | |
| /* ============================================ | |
| KEYFRAME ANIMATIONS | |
| ============================================ */ | |
| @keyframes fadeIn { | |
| from { | |
| opacity: 0; | |
| } | |
| to { | |
| opacity: 1; | |
| } | |
| } | |
| @keyframes slideUp { | |
| from { | |
| opacity: 0; | |
| transform: translateY(30px); | |
| } | |
| to { | |
| opacity: 1; | |
| transform: translateY(0); | |
| } | |
| } | |
| @keyframes float { | |
| 0%, | |
| 100% { | |
| transform: translateY(0); | |
| } | |
| 50% { | |
| transform: translateY(-8px); | |
| } | |
| } | |
| @keyframes corePulse { | |
| 0%, | |
| 100% { | |
| transform: scale(1); | |
| opacity: 1; | |
| } | |
| 50% { | |
| transform: scale(1.1); | |
| opacity: 0.85; | |
| } | |
| } | |
| @keyframes glowPulse { | |
| 0%, | |
| 100% { | |
| opacity: 0.4; | |
| transform: scale(1); | |
| } | |
| 50% { | |
| opacity: 0.6; | |
| transform: scale(1.05); | |
| } | |
| } | |
| @keyframes ringRotate { | |
| from { | |
| transform: rotate(0deg); | |
| } | |
| to { | |
| transform: rotate(360deg); | |
| } | |
| } | |
| @keyframes mouthSpeak { | |
| 0% { | |
| height: 8px; | |
| width: 22px; | |
| } | |
| 100% { | |
| height: 14px; | |
| width: 26px; | |
| } | |
| } | |
| @keyframes msgSlideIn { | |
| from { | |
| opacity: 0; | |
| transform: translateY(12px) scale(0.97); | |
| } | |
| to { | |
| opacity: 1; | |
| transform: translateY(0) scale(1); | |
| } | |
| } | |
| @keyframes typingBounce { | |
| 0%, | |
| 60%, | |
| 100% { | |
| transform: translateY(0); | |
| } | |
| 30% { | |
| transform: translateY(-6px); | |
| } | |
| } | |
| @keyframes blink { | |
| 0%, | |
| 100% { | |
| opacity: 1; | |
| } | |
| 50% { | |
| opacity: 0; | |
| } | |
| } | |
| @keyframes micPulse { | |
| 0% { | |
| transform: scale(1); | |
| opacity: 0.6; | |
| } | |
| 100% { | |
| transform: scale(1.6); | |
| opacity: 0; | |
| } | |
| } | |
| @keyframes breathe { | |
| 0%, | |
| 100% { | |
| transform: translateY(0) scale(1); | |
| } | |
| 50% { | |
| transform: translateY(-4px) scale(1.02); | |
| } | |
| } | |
| @keyframes breatheGlow { | |
| 0%, | |
| 100% { | |
| opacity: 0.15; | |
| transform: scale(1); | |
| } | |
| 50% { | |
| opacity: 0.35; | |
| transform: scale(1.08); | |
| } | |
| } | |
| @keyframes emotionPop { | |
| 0% { | |
| transform: scale(0) translateY(5px); | |
| opacity: 0; | |
| } | |
| 70% { | |
| transform: scale(1.2) translateY(-2px); | |
| opacity: 1; | |
| } | |
| 100% { | |
| transform: scale(1) translateY(0); | |
| opacity: 1; | |
| } | |
| } | |
| /* ============================================ | |
| RESPONSIVE | |
| ============================================ */ | |
| @media (max-width: 520px) { | |
| /* ── BODY ── */ | |
| body { | |
| overflow-y: auto; /* allow onboarding to scroll */ | |
| } | |
| body.in-chat { | |
| overflow-y: hidden; /* lock scroll in chat */ | |
| } | |
| /* ── APP CONTAINER ── */ | |
| .app-container { | |
| padding: 0 8px; | |
| /* dvh shrinks when keyboard opens; svh as older-browser fallback */ | |
| height: 100svh; | |
| height: 100dvh; | |
| max-width: 100%; | |
| min-height: 0; | |
| display: flex; | |
| flex-direction: column; | |
| padding-bottom: 0; | |
| overscroll-behavior: none; | |
| } | |
| /* ── HEADER ── */ | |
| .app-header { | |
| padding: 8px 0 6px; | |
| flex-shrink: 0; | |
| gap: 4px; | |
| } | |
| .header-left { | |
| gap: 6px; | |
| flex-shrink: 0; | |
| } | |
| .header-left img { | |
| width: 30px ; | |
| height: 30px ; | |
| margin-right: 6px ; | |
| } | |
| .header-title { | |
| font-size: 0.8rem; | |
| letter-spacing: 1px; | |
| } | |
| .header-status { | |
| font-size: 0.55rem; | |
| } | |
| .header-right { | |
| gap: 4px; | |
| overflow: hidden; | |
| flex-shrink: 1; | |
| } | |
| /* Hide less critical header items on mobile to prevent overflow */ | |
| .session-stats { | |
| display: none; | |
| } | |
| .xp-display { | |
| display: none; | |
| } | |
| .streak-display { | |
| font-size: 0.75rem; | |
| flex-shrink: 0; | |
| } | |
| .icon-btn { | |
| width: 32px; | |
| height: 32px; | |
| flex-shrink: 0; | |
| touch-action: manipulation; | |
| -webkit-tap-highlight-color: transparent; | |
| } | |
| /* ── AVATAR ── */ | |
| .avatar-section { | |
| padding: 4px 0 2px; | |
| flex-shrink: 0; | |
| } | |
| .avatar-container { | |
| width: 90px; | |
| height: 90px; | |
| } | |
| .avatar-glow { | |
| width: 78px; | |
| height: 78px; | |
| } | |
| .ring-outer { | |
| width: 86px; | |
| height: 86px; | |
| } | |
| .ring-inner { | |
| width: 74px; | |
| height: 74px; | |
| } | |
| .avatar-orb { | |
| width: 60px; | |
| height: 60px; | |
| } | |
| .state-label { | |
| font-size: 0.6rem; | |
| margin-top: 4px; | |
| letter-spacing: 1px; | |
| } | |
| .emotion-indicator { | |
| height: 16px; | |
| font-size: 0.85rem; | |
| } | |
| /* ── CHAT PANEL ── */ | |
| .chat-panel { | |
| flex: 1; | |
| min-height: 0; | |
| overflow: hidden; | |
| padding: 10px; | |
| margin-bottom: 0; | |
| } | |
| .messages-container { | |
| overflow-y: scroll; | |
| -webkit-overflow-scrolling: touch; | |
| overscroll-behavior: contain; | |
| } | |
| /* ── CONTROLS BAR ── */ | |
| .controls-bar { | |
| display: flex; | |
| align-items: center; | |
| gap: 5px; | |
| padding: 8px 0 max(14px, env(safe-area-inset-bottom, 14px)); | |
| flex-shrink: 0; | |
| position: sticky; | |
| bottom: 0; | |
| background: var(--bg-primary); | |
| border-top: 1px solid var(--border-glass); | |
| z-index: 20; | |
| /* GPU layer — prevents Android Chrome burying bar behind keyboard */ | |
| transform: translateZ(0); | |
| -webkit-transform: translateZ(0); | |
| will-change: transform; | |
| } | |
| /* All control buttons: 44px touch target (Apple/Google HIG minimum) */ | |
| .ctrl-btn { | |
| width: 44px; | |
| height: 44px; | |
| flex-shrink: 0; | |
| touch-action: manipulation; | |
| -webkit-tap-highlight-color: transparent; | |
| /* Make embedded SVGs not steal pointer events */ | |
| pointer-events: auto; | |
| } | |
| .ctrl-btn svg, | |
| .ctrl-btn span { | |
| pointer-events: none; | |
| } | |
| .send-btn { | |
| width: 48px; | |
| height: 44px; | |
| flex-shrink: 0; | |
| } | |
| /* Shrink the AUTO / STT label button to save space */ | |
| .stt-btn { | |
| width: 36px; | |
| height: 44px; | |
| font-size: 0.55rem; | |
| padding: 0 2px; | |
| min-width: 36px; | |
| } | |
| .chat-input { | |
| font-size: 16px; /* blocks iOS auto-zoom (needs ≥16px) */ | |
| padding: 10px 12px; | |
| -webkit-tap-highlight-color: transparent; | |
| min-width: 0; /* allow flex shrink */ | |
| } | |
| /* ── ONBOARDING ── */ | |
| .onboarding-title { | |
| font-size: 1.8rem; | |
| } | |
| .level-cards { | |
| flex-direction: column; | |
| align-items: center; | |
| } | |
| .level-card { | |
| min-width: 90%; | |
| } | |
| .topic-grid { | |
| grid-template-columns: repeat(2, 1fr); | |
| } | |
| .scenario-grid { | |
| grid-template-columns: repeat(2, 1fr); | |
| } | |
| /* ── SIDE PANEL ── */ | |
| .side-panel { | |
| width: 100%; | |
| right: -100%; | |
| } | |
| /* ── MODALS ── */ | |
| .modal-card { | |
| width: 95vw; | |
| max-height: 90vh; | |
| overflow-y: auto; | |
| -webkit-overflow-scrolling: touch; | |
| } | |
| } | |
| @media (max-height: 720px) and (max-width: 900px) { | |
| .app-header { | |
| padding: 10px 0 8px; | |
| } | |
| .avatar-section { | |
| padding: 6px 0 4px; | |
| } | |
| .avatar-container { | |
| width: 112px; | |
| height: 112px; | |
| } | |
| .avatar-glow { | |
| width: 96px; | |
| height: 96px; | |
| } | |
| .ring-outer { | |
| width: 104px; | |
| height: 104px; | |
| } | |
| .ring-inner { | |
| width: 88px; | |
| height: 88px; | |
| } | |
| .avatar-orb { | |
| width: 68px; | |
| height: 68px; | |
| } | |
| .state-label { | |
| margin-top: 6px; | |
| font-size: 0.7rem; | |
| } | |
| .chat-panel { | |
| padding: 12px; | |
| margin-bottom: 8px; | |
| } | |
| .controls-bar { | |
| padding: 8px 0 14px; | |
| } | |
| .ctrl-btn { | |
| width: 42px; | |
| height: 42px; | |
| } | |
| .chat-input { | |
| padding: 10px 16px; | |
| } | |
| } | |
| @media (min-width: 1024px) { | |
| .app-container { | |
| max-width: 720px; | |
| padding: 0 24px; | |
| } | |
| .onboarding-content { | |
| max-width: 760px; | |
| } | |
| .topic-grid, | |
| .scenario-grid { | |
| grid-template-columns: repeat(4, minmax(0, 1fr)); | |
| } | |
| } | |
| @media (min-width: 521px) and (max-width: 768px) { | |
| .topic-grid { | |
| grid-template-columns: repeat(4, 1fr); | |
| } | |
| } | |
| /* ============================================ | |
| PRONUNCIATION BAR | |
| ============================================ */ | |
| .pronunciation-bar { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 6px; | |
| padding: 10px 16px; | |
| background: var(--bg-glass); | |
| -webkit-backdrop-filter: blur(10px); | |
| backdrop-filter: blur(10px); | |
| border: 1px solid var(--border-glass); | |
| border-radius: var(--radius-md); | |
| margin-bottom: 6px; | |
| animation: slideUp 0.4s ease; | |
| } | |
| .pronun-score-visual { | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| } | |
| .pronun-stars { | |
| display: flex; | |
| gap: 2px; | |
| } | |
| .pronun-star { | |
| font-size: 0.85rem; | |
| transition: all 0.2s ease; | |
| } | |
| .pronun-star.filled { | |
| filter: none; | |
| } | |
| .pronun-star.empty { | |
| opacity: 0.25; | |
| filter: grayscale(1); | |
| } | |
| .pronun-score-num { | |
| font-family: var(--font-mono); | |
| font-size: 0.85rem; | |
| font-weight: 600; | |
| color: var(--accent-bright); | |
| } | |
| .pronun-bar-track { | |
| height: 6px; | |
| background: rgba(255, 255, 255, 0.06); | |
| border-radius: 3px; | |
| overflow: hidden; | |
| } | |
| .pronun-bar-fill { | |
| height: 100%; | |
| background: linear-gradient( | |
| 90deg, | |
| var(--error) 0%, | |
| #f6ad55 30%, | |
| var(--success) 70%, | |
| #38b2ac 100% | |
| ); | |
| border-radius: 3px; | |
| transition: width 0.6s cubic-bezier(0.4, 0, 0.2, 1); | |
| } | |
| .pronun-label { | |
| font-size: 0.72rem; | |
| color: var(--text-muted); | |
| text-align: center; | |
| } | |
| /* ============================================ | |
| SESSION SUMMARY MODAL | |
| ============================================ */ | |
| .modal-overlay { | |
| position: fixed; | |
| inset: 0; | |
| background: rgba(0, 0, 0, 0.65); | |
| -webkit-backdrop-filter: blur(8px); | |
| backdrop-filter: blur(8px); | |
| z-index: 10000; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| animation: fadeIn 0.3s ease; | |
| padding: 20px; | |
| } | |
| .modal-card { | |
| background: var(--bg-card); | |
| border: 1px solid var(--border-glass); | |
| border-radius: var(--radius-xl); | |
| padding: 28px; | |
| max-width: 440px; | |
| width: 100%; | |
| animation: slideUp 0.4s cubic-bezier(0.34, 1.56, 0.64, 1); | |
| box-shadow: 0 20px 60px rgba(0, 0, 0, 0.4); | |
| } | |
| .modal-header { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| margin-bottom: 20px; | |
| } | |
| .modal-header h2 { | |
| font-size: 1.2rem; | |
| font-weight: 600; | |
| color: var(--text-primary); | |
| font-family: var(--font-heading); | |
| } | |
| .modal-close { | |
| background: none; | |
| border: none; | |
| color: var(--text-muted); | |
| font-size: 1.5rem; | |
| cursor: pointer; | |
| line-height: 1; | |
| transition: color 0.2s; | |
| } | |
| .modal-close:hover { | |
| color: var(--text-primary); | |
| } | |
| .summary-stats { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fit, minmax(100px, 1fr)); | |
| gap: 12px; | |
| margin-bottom: 22px; | |
| } | |
| .summary-stat { | |
| background: var(--bg-glass); | |
| border: 1px solid var(--border-glass); | |
| border-radius: var(--radius-md); | |
| padding: 14px 10px; | |
| text-align: center; | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| gap: 4px; | |
| } | |
| .summary-stat-icon { | |
| font-size: 1.3rem; | |
| } | |
| .summary-stat-val { | |
| font-size: 1.4rem; | |
| font-weight: 700; | |
| color: var(--accent-bright); | |
| font-family: var(--font-mono); | |
| } | |
| .summary-stat-label { | |
| font-size: 0.65rem; | |
| color: var(--text-muted); | |
| text-transform: uppercase; | |
| letter-spacing: 0.5px; | |
| } | |
| .progress-section { | |
| margin-bottom: 20px; | |
| } | |
| .progress-section h3 { | |
| font-size: 0.85rem; | |
| color: var(--text-secondary); | |
| margin-bottom: 10px; | |
| font-weight: 500; | |
| } | |
| .progress-bars { | |
| display: flex; | |
| gap: 6px; | |
| align-items: flex-end; | |
| height: 60px; | |
| } | |
| .progress-bar-day { | |
| flex: 1; | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| gap: 4px; | |
| } | |
| .progress-bar-fill { | |
| width: 100%; | |
| min-height: 4px; | |
| background: linear-gradient(to top, var(--accent), var(--accent-2)); | |
| border-radius: 3px 3px 0 0; | |
| transition: height 0.5s ease; | |
| } | |
| .progress-bar-label { | |
| font-size: 0.55rem; | |
| color: var(--text-muted); | |
| text-transform: uppercase; | |
| } | |
| .btn-primary { | |
| width: 100%; | |
| padding: 12px; | |
| background: linear-gradient(135deg, var(--accent) 0%, var(--accent-2) 100%); | |
| border: none; | |
| border-radius: var(--radius-md); | |
| color: white; | |
| font-weight: 600; | |
| font-size: 0.9rem; | |
| cursor: pointer; | |
| transition: all var(--transition-fast); | |
| font-family: var(--font-body); | |
| } | |
| .btn-primary:hover { | |
| transform: translateY(-1px); | |
| box-shadow: 0 8px 25px var(--accent-glow); | |
| } | |
| /* ============================================ | |
| SIDE PANEL (Grammar + Vocab) | |
| ============================================ */ | |
| .side-panel { | |
| position: fixed; | |
| top: 0; | |
| right: -360px; | |
| width: 360px; | |
| height: 100vh; | |
| height: 100dvh; | |
| background: var(--bg-card); | |
| border-left: 1px solid var(--border-glass); | |
| z-index: 9000; | |
| display: flex; | |
| flex-direction: column; | |
| transition: right 0.35s cubic-bezier(0.4, 0, 0.2, 1); | |
| box-shadow: -10px 0 40px rgba(0, 0, 0, 0.3); | |
| } | |
| .side-panel.open { | |
| right: 0; | |
| } | |
| .panel-header { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| padding: 16px; | |
| border-bottom: 1px solid var(--border-glass); | |
| } | |
| .panel-tabs { | |
| display: flex; | |
| gap: 4px; | |
| flex-wrap: wrap; | |
| } | |
| .panel-tab { | |
| padding: 6px 14px; | |
| background: transparent; | |
| border: 1px solid var(--border-glass); | |
| border-radius: var(--radius-sm); | |
| color: var(--text-muted); | |
| font-size: 0.78rem; | |
| cursor: pointer; | |
| transition: all 0.2s; | |
| font-family: var(--font-body); | |
| } | |
| .panel-tab.active { | |
| background: var(--bg-glass-hover); | |
| color: var(--accent-bright); | |
| border-color: var(--accent); | |
| } | |
| .panel-close { | |
| background: none; | |
| border: none; | |
| color: var(--text-muted); | |
| font-size: 1.4rem; | |
| cursor: pointer; | |
| line-height: 1; | |
| } | |
| .panel-close:hover { | |
| color: var(--text-primary); | |
| } | |
| .panel-body { | |
| flex: 1; | |
| overflow-y: auto; | |
| padding: 14px; | |
| } | |
| .panel-empty { | |
| text-align: center; | |
| padding: 30px 10px; | |
| color: var(--text-muted); | |
| font-size: 0.82rem; | |
| } | |
| /* Corrections */ | |
| .correction-card { | |
| background: var(--bg-glass); | |
| border: 1px solid var(--border-glass); | |
| border-radius: var(--radius-sm); | |
| padding: 10px 12px; | |
| margin-bottom: 8px; | |
| animation: msgSlideIn 0.3s ease; | |
| } | |
| .correction-wrong { | |
| color: var(--error); | |
| text-decoration: line-through; | |
| font-size: 0.82rem; | |
| opacity: 0.7; | |
| } | |
| .correction-right { | |
| color: var(--success); | |
| font-weight: 500; | |
| font-size: 0.85rem; | |
| } | |
| .correction-arrow { | |
| color: var(--text-muted); | |
| margin: 0 6px; | |
| font-size: 0.75rem; | |
| } | |
| /* Vocab Controls */ | |
| .vocab-controls { | |
| display: flex; | |
| gap: 4px; | |
| margin-bottom: 12px; | |
| } | |
| .vocab-mode-btn { | |
| flex: 1; | |
| padding: 6px; | |
| background: transparent; | |
| border: 1px solid var(--border-glass); | |
| border-radius: var(--radius-sm); | |
| color: var(--text-muted); | |
| font-size: 0.72rem; | |
| cursor: pointer; | |
| transition: all 0.2s; | |
| font-family: var(--font-body); | |
| } | |
| .vocab-mode-btn.active { | |
| background: var(--bg-glass-hover); | |
| color: var(--accent-bright); | |
| border-color: var(--accent); | |
| } | |
| /* Vocab Word Item */ | |
| .vocab-item { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| padding: 8px 10px; | |
| background: var(--bg-glass); | |
| border: 1px solid var(--border-glass); | |
| border-radius: var(--radius-sm); | |
| margin-bottom: 6px; | |
| animation: msgSlideIn 0.3s ease; | |
| } | |
| .vocab-word { | |
| font-weight: 600; | |
| color: var(--accent-bright); | |
| font-size: 0.85rem; | |
| } | |
| .vocab-context { | |
| font-size: 0.72rem; | |
| color: var(--text-muted); | |
| margin-top: 2px; | |
| } | |
| .vocab-remove { | |
| background: none; | |
| border: none; | |
| color: var(--text-muted); | |
| cursor: pointer; | |
| font-size: 0.8rem; | |
| opacity: 0.5; | |
| } | |
| .vocab-remove:hover { | |
| opacity: 1; | |
| color: var(--error); | |
| } | |
| /* 3D Flashcard */ | |
| .flashcard-view { | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| gap: 14px; | |
| padding: 10px 0; | |
| } | |
| .flashcard { | |
| width: 100%; | |
| max-width: 280px; | |
| height: 180px; | |
| perspective: 600px; | |
| cursor: pointer; | |
| } | |
| .flashcard-inner { | |
| width: 100%; | |
| height: 100%; | |
| position: relative; | |
| transition: transform 0.6s cubic-bezier(0.4, 0, 0.2, 1); | |
| transform-style: preserve-3d; | |
| } | |
| .flashcard.flipped .flashcard-inner { | |
| transform: rotateY(180deg); | |
| } | |
| .flashcard-front, | |
| .flashcard-back { | |
| position: absolute; | |
| inset: 0; | |
| -webkit-backface-visibility: hidden; | |
| backface-visibility: hidden; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| padding: 20px; | |
| border-radius: var(--radius-md); | |
| border: 1px solid var(--border-glass); | |
| text-align: center; | |
| } | |
| .flashcard-front { | |
| background: linear-gradient( | |
| 135deg, | |
| rgba(99, 179, 237, 0.15), | |
| rgba(159, 122, 234, 0.15) | |
| ); | |
| font-size: 1.3rem; | |
| font-weight: 600; | |
| color: var(--accent-bright); | |
| } | |
| .flashcard-back { | |
| background: var(--bg-glass-hover); | |
| transform: rotateY(180deg); | |
| font-size: 0.9rem; | |
| color: var(--text-secondary); | |
| } | |
| .flashcard-nav { | |
| display: flex; | |
| align-items: center; | |
| gap: 16px; | |
| } | |
| .fc-btn { | |
| width: 36px; | |
| height: 36px; | |
| border-radius: var(--radius-full); | |
| border: 1px solid var(--border-glass); | |
| background: var(--bg-glass); | |
| color: var(--text-secondary); | |
| cursor: pointer; | |
| font-size: 1rem; | |
| transition: all 0.2s; | |
| font-family: var(--font-body); | |
| } | |
| .fc-btn:hover { | |
| background: var(--bg-glass-hover); | |
| border-color: var(--accent); | |
| color: var(--accent-bright); | |
| } | |
| .fc-counter { | |
| font-size: 0.78rem; | |
| color: var(--text-muted); | |
| font-family: var(--font-mono); | |
| } | |
| /* Quiz */ | |
| .quiz-view { | |
| padding: 10px 0; | |
| } | |
| .quiz-question { | |
| background: var(--bg-glass); | |
| border: 1px solid var(--border-glass); | |
| border-radius: var(--radius-md); | |
| padding: 20px; | |
| text-align: center; | |
| font-size: 0.95rem; | |
| color: var(--text-secondary); | |
| margin-bottom: 14px; | |
| } | |
| .quiz-options { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 6px; | |
| } | |
| .quiz-option { | |
| padding: 10px 14px; | |
| background: var(--bg-glass); | |
| border: 1px solid var(--border-glass); | |
| border-radius: var(--radius-sm); | |
| color: var(--text-primary); | |
| font-size: 0.85rem; | |
| cursor: pointer; | |
| transition: all 0.2s; | |
| text-align: left; | |
| font-family: var(--font-body); | |
| } | |
| .quiz-option:hover { | |
| background: var(--bg-glass-hover); | |
| border-color: var(--accent); | |
| } | |
| .quiz-option.correct { | |
| background: rgba(72, 187, 120, 0.15); | |
| border-color: var(--success); | |
| color: var(--success); | |
| } | |
| .quiz-option.wrong { | |
| background: rgba(252, 129, 129, 0.15); | |
| border-color: var(--error); | |
| color: var(--error); | |
| } | |
| .quiz-result { | |
| text-align: center; | |
| padding: 10px; | |
| font-size: 0.9rem; | |
| font-weight: 500; | |
| margin-top: 10px; | |
| } | |
| .quiz-next { | |
| margin-top: 12px; | |
| } | |
| /* Voice Profiles */ | |
| .voice-profiles-list { | |
| display: flex; | |
| flex-wrap: wrap; | |
| gap: 6px; | |
| margin-bottom: 12px; | |
| } | |
| .voice-profile-chip { | |
| border: 1px solid var(--border-glass); | |
| background: var(--bg-glass); | |
| color: var(--text-secondary); | |
| border-radius: var(--radius-sm); | |
| padding: 6px 10px; | |
| font-size: 0.72rem; | |
| cursor: pointer; | |
| } | |
| .voice-profile-chip.active { | |
| border-color: var(--accent); | |
| color: var(--accent-bright); | |
| background: var(--bg-glass-hover); | |
| } | |
| .voice-editor { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 8px; | |
| } | |
| .voice-input, | |
| .voice-select { | |
| width: 100%; | |
| border: 1px solid var(--border-glass); | |
| background: var(--bg-glass); | |
| color: var(--text-primary); | |
| border-radius: var(--radius-sm); | |
| padding: 8px 10px; | |
| font-size: 0.8rem; | |
| font-family: var(--font-body); | |
| } | |
| .voice-label { | |
| font-size: 0.68rem; | |
| color: var(--text-muted); | |
| text-transform: uppercase; | |
| letter-spacing: 0.4px; | |
| } | |
| .voice-actions { | |
| display: flex; | |
| gap: 8px; | |
| margin-top: 6px; | |
| } | |
| .voice-actions .btn-primary, | |
| .voice-actions .btn-secondary { | |
| width: auto; | |
| padding: 8px 12px; | |
| font-size: 0.78rem; | |
| } | |
| /* App Settings */ | |
| .settings-group { | |
| background: var(--bg-glass); | |
| border: 1px solid var(--border-glass); | |
| border-radius: var(--radius-md); | |
| padding: 10px; | |
| margin-bottom: 10px; | |
| } | |
| .settings-title { | |
| font-size: 0.74rem; | |
| color: var(--accent-bright); | |
| text-transform: uppercase; | |
| letter-spacing: 0.6px; | |
| margin-bottom: 8px; | |
| } | |
| .setting-item { | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| gap: 10px; | |
| padding: 8px 6px; | |
| border-radius: var(--radius-sm); | |
| } | |
| .setting-item + .setting-item { | |
| border-top: 1px solid var(--border-glass); | |
| } | |
| .setting-copy { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 2px; | |
| } | |
| .setting-name { | |
| font-size: 0.82rem; | |
| color: var(--text-primary); | |
| font-weight: 600; | |
| } | |
| .setting-desc { | |
| font-size: 0.72rem; | |
| color: var(--text-muted); | |
| } | |
| .setting-item input[type='checkbox'] { | |
| width: 18px; | |
| height: 18px; | |
| accent-color: var(--accent); | |
| cursor: pointer; | |
| } | |
| /* UI behavior modifiers */ | |
| body.ui-compact .message { | |
| padding: 8px 12px; | |
| font-size: 0.84rem; | |
| line-height: 1.45; | |
| } | |
| body.ui-compact .chat-panel { | |
| padding: 12px; | |
| } | |
| body.ui-compact .controls-bar { | |
| padding: 8px 0 14px; | |
| } | |
| body.ui-compact .ctrl-btn { | |
| width: 42px; | |
| height: 42px; | |
| } | |
| body.ui-reduced-motion * { | |
| animation-duration: 0.01ms ; | |
| animation-iteration-count: 1 ; | |
| transition-duration: 0.01ms ; | |
| } | |
| body.no-particles #particles-canvas { | |
| display: none; | |
| } | |
| body.no-waveform .waveform-canvas { | |
| display: none; | |
| } | |
| /* Utility */ | |
| .hidden { | |
| display: none ; | |
| } | |
| /* ============================================ | |
| LIGHT THEME | |
| ============================================ */ | |
| [data-theme='light'] { | |
| --bg-primary: #f0f4f8; | |
| --bg-secondary: #ffffff; | |
| --bg-card: rgba(255, 255, 255, 0.85); | |
| --bg-glass: rgba(0, 0, 0, 0.03); | |
| --bg-glass-hover: rgba(0, 0, 0, 0.06); | |
| --border-glass: rgba(0, 0, 0, 0.1); | |
| --text-primary: #1a202c; | |
| --text-secondary: #2d3748; | |
| --text-muted: #718096; | |
| --text-hint: #a0aec0; | |
| --shadow-glow: 0 4px 20px rgba(99, 179, 237, 0.15); | |
| --accent-glow: rgba(99, 179, 237, 0.2); | |
| --accent-2-glow: rgba(159, 122, 234, 0.2); | |
| } | |
| [data-theme='light'] body { | |
| background: #f0f4f8; | |
| } | |
| [data-theme='light'] #particles-canvas { | |
| opacity: 0.15; | |
| } | |
| [data-theme='light'] .app-header { | |
| background: rgba(255, 255, 255, 0.7); | |
| border-bottom-color: rgba(0, 0, 0, 0.08); | |
| } | |
| [data-theme='light'] .message.user { | |
| background: linear-gradient( | |
| 135deg, | |
| rgba(99, 179, 237, 0.2), | |
| rgba(99, 179, 237, 0.1) | |
| ); | |
| border-color: rgba(99, 179, 237, 0.3); | |
| } | |
| [data-theme='light'] .message.ai { | |
| background: rgba(255, 255, 255, 0.7); | |
| border-color: rgba(0, 0, 0, 0.08); | |
| } | |
| [data-theme='light'] .controls-bar { | |
| background: rgba(255, 255, 255, 0.8); | |
| border-top-color: rgba(0, 0, 0, 0.08); | |
| } | |
| [data-theme='light'] .chat-input { | |
| background: rgba(0, 0, 0, 0.04); | |
| border-color: rgba(0, 0, 0, 0.1); | |
| color: #1a202c; | |
| } | |
| [data-theme='light'] .side-panel { | |
| background: rgba(255, 255, 255, 0.95); | |
| border-left-color: rgba(0, 0, 0, 0.1); | |
| } | |
| [data-theme='light'] .modal-card { | |
| background: #ffffff; | |
| border-color: rgba(0, 0, 0, 0.1); | |
| } | |
| [data-theme='light'] .onboarding-screen { | |
| background: #f0f4f8; | |
| } | |
| [data-theme='light'] .level-card, | |
| [data-theme='light'] .topic-card, | |
| [data-theme='light'] .lang-card, | |
| [data-theme='light'] .scenario-card { | |
| background: rgba(255, 255, 255, 0.7); | |
| border-color: rgba(0, 0, 0, 0.08); | |
| } | |
| [data-theme='light'] .pronunciation-bar { | |
| background: rgba(255, 255, 255, 0.8); | |
| border-color: rgba(0, 0, 0, 0.08); | |
| } | |
| [data-theme='light'] .avatar-orb { | |
| background: linear-gradient(135deg, #e8edf5, #d0d8e8); | |
| } | |
| /* Theme toggle animation */ | |
| #theme-btn svg { | |
| transition: transform 0.3s ease; | |
| } | |
| [data-theme='light'] #theme-btn svg { | |
| transform: rotate(180deg); | |
| } | |
| /* ============================================ | |
| LANGUAGE CARDS | |
| ============================================ */ | |
| .lang-cards { | |
| display: flex; | |
| gap: 10px; | |
| justify-content: center; | |
| flex-wrap: wrap; | |
| } | |
| .lang-card { | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| gap: 6px; | |
| padding: 14px 18px; | |
| background: var(--bg-glass); | |
| -webkit-backdrop-filter: blur(10px); | |
| backdrop-filter: blur(10px); | |
| border: 1px solid var(--border-glass); | |
| border-radius: var(--radius-md); | |
| cursor: pointer; | |
| transition: all var(--transition-normal); | |
| color: var(--text-secondary); | |
| font-family: var(--font-body); | |
| min-width: 90px; | |
| } | |
| .lang-card:hover { | |
| background: var(--bg-glass-hover); | |
| border-color: var(--accent); | |
| transform: translateY(-2px); | |
| } | |
| .lang-card.active { | |
| background: rgba(99, 179, 237, 0.12); | |
| border-color: var(--accent); | |
| color: var(--text-primary); | |
| box-shadow: var(--shadow-glow); | |
| } | |
| .lang-flag { | |
| font-size: 1.8rem; | |
| } | |
| .lang-name { | |
| font-size: 0.8rem; | |
| font-weight: 600; | |
| } | |
| /* ============================================ | |
| MODE TOGGLE (Topics / Role-Play) | |
| ============================================ */ | |
| .mode-toggle { | |
| display: flex; | |
| gap: 8px; | |
| justify-content: center; | |
| margin-bottom: 10px; | |
| } | |
| .mode-btn { | |
| padding: 10px 24px; | |
| border-radius: var(--radius-full); | |
| background: var(--bg-glass); | |
| border: 1px solid var(--border-glass); | |
| color: var(--text-muted); | |
| cursor: pointer; | |
| font-family: var(--font-body); | |
| font-size: 0.85rem; | |
| font-weight: 500; | |
| transition: all var(--transition-normal); | |
| } | |
| .mode-btn:hover { | |
| background: var(--bg-glass-hover); | |
| color: var(--text-primary); | |
| } | |
| .mode-btn.active { | |
| background: linear-gradient(135deg, var(--accent), var(--accent-2)); | |
| color: white; | |
| border-color: transparent; | |
| box-shadow: 0 4px 15px var(--accent-glow); | |
| } | |
| /* ============================================ | |
| SCENARIO GRID | |
| ============================================ */ | |
| .scenario-grid { | |
| display: grid; | |
| grid-template-columns: repeat(3, 1fr); | |
| gap: 8px; | |
| } | |
| .scenario-card { | |
| background: var(--bg-glass); | |
| -webkit-backdrop-filter: blur(10px); | |
| backdrop-filter: blur(10px); | |
| border: 1px solid var(--border-glass); | |
| border-radius: var(--radius-md); | |
| padding: 14px 10px; | |
| cursor: pointer; | |
| text-align: center; | |
| transition: all var(--transition-normal); | |
| color: var(--text-secondary); | |
| font-family: var(--font-body); | |
| } | |
| .scenario-card:hover { | |
| transform: translateY(-2px); | |
| background: var(--bg-glass-hover); | |
| border-color: var(--accent); | |
| } | |
| .scenario-card.active { | |
| background: rgba(99, 179, 237, 0.12); | |
| border-color: var(--accent); | |
| color: var(--text-primary); | |
| box-shadow: var(--shadow-glow); | |
| } | |
| .scenario-icon { | |
| font-size: 1.5rem; | |
| display: block; | |
| margin-bottom: 6px; | |
| } | |
| .scenario-name { | |
| font-size: 0.78rem; | |
| font-weight: 600; | |
| } | |
| .scenario-desc { | |
| font-size: 0.65rem; | |
| color: var(--text-muted); | |
| margin-top: 3px; | |
| } | |
| /* ============================================ | |
| XP / LEVEL / STREAK DISPLAYS | |
| ============================================ */ | |
| .xp-display { | |
| display: flex; | |
| align-items: center; | |
| gap: 6px; | |
| padding: 4px 10px; | |
| border-radius: var(--radius-full); | |
| background: var(--bg-glass); | |
| border: 1px solid var(--border-glass); | |
| cursor: pointer; | |
| } | |
| .xp-level { | |
| font-size: 0.72rem; | |
| font-weight: 700; | |
| background: linear-gradient(135deg, var(--accent), var(--accent-2)); | |
| -webkit-background-clip: text; | |
| -webkit-text-fill-color: transparent; | |
| background-clip: text; | |
| } | |
| .xp-bar-mini { | |
| width: 40px; | |
| height: 4px; | |
| border-radius: 2px; | |
| background: var(--bg-glass); | |
| overflow: hidden; | |
| } | |
| .xp-bar-mini-fill { | |
| height: 100%; | |
| border-radius: 2px; | |
| background: linear-gradient(90deg, var(--accent), var(--accent-2)); | |
| transition: width 0.5s ease; | |
| } | |
| .xp-value { | |
| font-size: 0.68rem; | |
| color: var(--text-muted); | |
| font-family: var(--font-mono); | |
| } | |
| .streak-display { | |
| font-size: 0.75rem; | |
| font-weight: 600; | |
| padding: 4px 8px; | |
| border-radius: var(--radius-full); | |
| background: var(--bg-glass); | |
| border: 1px solid var(--border-glass); | |
| cursor: pointer; | |
| } | |
| /* XP Popup */ | |
| .xp-popup { | |
| position: fixed; | |
| top: 60px; | |
| right: 20px; | |
| z-index: 500; | |
| padding: 8px 16px; | |
| border-radius: var(--radius-md); | |
| background: linear-gradient(135deg, var(--accent), var(--accent-2)); | |
| color: white; | |
| font-weight: 700; | |
| font-size: 0.9rem; | |
| opacity: 0; | |
| transform: translateY(20px); | |
| pointer-events: none; | |
| transition: all 0.3s ease; | |
| box-shadow: 0 4px 20px var(--accent-glow); | |
| } | |
| .xp-popup.show { | |
| opacity: 1; | |
| transform: translateY(0); | |
| animation: xpPop 1.5s ease forwards; | |
| } | |
| @keyframes xpPop { | |
| 0% { | |
| opacity: 0; | |
| transform: translateY(20px) scale(0.8); | |
| } | |
| 20% { | |
| opacity: 1; | |
| transform: translateY(0) scale(1.1); | |
| } | |
| 40% { | |
| transform: translateY(0) scale(1); | |
| } | |
| 80% { | |
| opacity: 1; | |
| transform: translateY(-10px); | |
| } | |
| 100% { | |
| opacity: 0; | |
| transform: translateY(-30px) scale(0.8); | |
| } | |
| } | |
| /* ============================================ | |
| EXERCISES MODAL | |
| ============================================ */ | |
| .exercises-card { | |
| max-width: 520px; | |
| width: 95%; | |
| } | |
| .exercise-types { | |
| display: flex; | |
| flex-wrap: wrap; | |
| gap: 6px; | |
| margin-bottom: 16px; | |
| } | |
| .ex-type-btn { | |
| padding: 8px 14px; | |
| border-radius: var(--radius-full); | |
| background: var(--bg-glass); | |
| border: 1px solid var(--border-glass); | |
| color: var(--text-muted); | |
| cursor: pointer; | |
| font-family: var(--font-body); | |
| font-size: 0.78rem; | |
| font-weight: 500; | |
| transition: all 0.2s; | |
| } | |
| .ex-type-btn:hover { | |
| background: var(--bg-glass-hover); | |
| color: var(--text-primary); | |
| } | |
| .ex-type-btn.active { | |
| background: linear-gradient(135deg, var(--accent), var(--accent-2)); | |
| color: white; | |
| border-color: transparent; | |
| } | |
| .exercise-area { | |
| min-height: 200px; | |
| padding: 16px; | |
| background: var(--bg-glass); | |
| border: 1px solid var(--border-glass); | |
| border-radius: var(--radius-md); | |
| margin-bottom: 14px; | |
| } | |
| .exercise-question { | |
| font-size: 1rem; | |
| color: var(--text-primary); | |
| line-height: 1.7; | |
| margin-bottom: 16px; | |
| font-weight: 500; | |
| } | |
| .exercise-options { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 8px; | |
| } | |
| .exercise-option { | |
| padding: 12px 16px; | |
| background: var(--bg-glass); | |
| border: 1px solid var(--border-glass); | |
| border-radius: var(--radius-sm); | |
| cursor: pointer; | |
| font-family: var(--font-body); | |
| font-size: 0.88rem; | |
| color: var(--text-secondary); | |
| transition: all 0.2s; | |
| text-align: left; | |
| } | |
| .exercise-option:hover:not(.disabled) { | |
| background: var(--bg-glass-hover); | |
| border-color: var(--accent); | |
| transform: translateX(4px); | |
| } | |
| .exercise-option.correct { | |
| background: rgba(72, 187, 120, 0.15); | |
| border-color: var(--success); | |
| color: var(--success); | |
| } | |
| .exercise-option.wrong { | |
| background: rgba(252, 129, 129, 0.15); | |
| border-color: var(--error); | |
| color: var(--error); | |
| } | |
| .exercise-option.disabled { | |
| pointer-events: none; | |
| opacity: 0.7; | |
| } | |
| .exercise-input-area { | |
| display: flex; | |
| gap: 8px; | |
| align-items: center; | |
| } | |
| .exercise-input { | |
| flex: 1; | |
| padding: 10px 14px; | |
| background: var(--bg-glass); | |
| border: 1px solid var(--border-glass); | |
| border-radius: var(--radius-sm); | |
| color: var(--text-primary); | |
| font-family: var(--font-body); | |
| font-size: 0.88rem; | |
| outline: none; | |
| transition: border-color 0.2s; | |
| } | |
| .exercise-input:focus { | |
| border-color: var(--accent); | |
| } | |
| .exercise-result { | |
| margin-top: 12px; | |
| padding: 10px 14px; | |
| border-radius: var(--radius-sm); | |
| font-size: 0.88rem; | |
| font-weight: 500; | |
| text-align: center; | |
| } | |
| .exercise-result.correct { | |
| background: rgba(72, 187, 120, 0.1); | |
| color: var(--success); | |
| } | |
| .exercise-result.wrong { | |
| background: rgba(252, 129, 129, 0.1); | |
| color: var(--error); | |
| } | |
| .exercise-explain { | |
| margin-top: 8px; | |
| padding: 10px; | |
| background: rgba(99, 179, 237, 0.08); | |
| border-left: 3px solid var(--accent); | |
| border-radius: 0 var(--radius-sm) var(--radius-sm) 0; | |
| font-size: 0.82rem; | |
| color: var(--text-muted); | |
| line-height: 1.5; | |
| } | |
| .exercise-footer { | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| padding-top: 4px; | |
| } | |
| .exercise-progress, | |
| .exercise-score { | |
| font-size: 0.78rem; | |
| color: var(--text-muted); | |
| font-family: var(--font-mono); | |
| } | |
| /* Sentence Reorder drag area */ | |
| .reorder-area { | |
| display: flex; | |
| flex-wrap: wrap; | |
| gap: 8px; | |
| min-height: 50px; | |
| padding: 12px; | |
| background: var(--bg-glass); | |
| border: 2px dashed var(--border-glass); | |
| border-radius: var(--radius-md); | |
| margin-bottom: 10px; | |
| } | |
| .reorder-word { | |
| padding: 8px 14px; | |
| background: rgba(99, 179, 237, 0.12); | |
| border: 1px solid rgba(99, 179, 237, 0.3); | |
| border-radius: var(--radius-full); | |
| font-size: 0.85rem; | |
| color: var(--accent-bright); | |
| cursor: pointer; | |
| transition: all 0.2s; | |
| user-select: none; | |
| font-family: var(--font-body); | |
| font-weight: 500; | |
| } | |
| .reorder-word:hover { | |
| transform: scale(1.05); | |
| } | |
| .reorder-word.placed { | |
| background: rgba(159, 122, 234, 0.12); | |
| border-color: rgba(159, 122, 234, 0.3); | |
| color: var(--accent-2); | |
| } | |
| /* ============================================ | |
| BADGES | |
| ============================================ */ | |
| .badges-section h3 { | |
| font-size: 0.85rem; | |
| color: var(--text-muted); | |
| margin-bottom: 10px; | |
| } | |
| .badges-grid, | |
| .badges-full-grid { | |
| display: grid; | |
| grid-template-columns: repeat(4, 1fr); | |
| gap: 10px; | |
| } | |
| .badge-item { | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| gap: 4px; | |
| padding: 12px 8px; | |
| background: var(--bg-glass); | |
| border: 1px solid var(--border-glass); | |
| border-radius: var(--radius-md); | |
| text-align: center; | |
| transition: all 0.3s; | |
| } | |
| .badge-item.earned { | |
| border-color: var(--accent); | |
| box-shadow: 0 0 15px var(--accent-glow); | |
| } | |
| .badge-item.locked { | |
| opacity: 0.4; | |
| filter: grayscale(1); | |
| } | |
| .badge-icon { | |
| font-size: 1.5rem; | |
| } | |
| .badge-label { | |
| font-size: 0.68rem; | |
| font-weight: 600; | |
| color: var(--text-secondary); | |
| } | |
| .badge-desc { | |
| font-size: 0.58rem; | |
| color: var(--text-muted); | |
| } | |
| /* ============================================ | |
| SUMMARY ENHANCEMENTS | |
| ============================================ */ | |
| .summary-actions { | |
| display: flex; | |
| gap: 10px; | |
| margin-top: 14px; | |
| } | |
| .btn-primary { | |
| padding: 10px 20px; | |
| border-radius: var(--radius-full); | |
| background: linear-gradient(135deg, var(--accent), var(--accent-2)); | |
| color: white; | |
| font-weight: 600; | |
| font-size: 0.85rem; | |
| border: none; | |
| cursor: pointer; | |
| transition: all 0.2s; | |
| font-family: var(--font-body); | |
| } | |
| .btn-primary:hover { | |
| transform: translateY(-1px); | |
| box-shadow: 0 4px 15px var(--accent-glow); | |
| } | |
| .btn-secondary { | |
| padding: 10px 20px; | |
| border-radius: var(--radius-full); | |
| background: var(--bg-glass); | |
| border: 1px solid var(--border-glass); | |
| color: var(--text-secondary); | |
| font-weight: 500; | |
| font-size: 0.85rem; | |
| cursor: pointer; | |
| transition: all 0.2s; | |
| font-family: var(--font-body); | |
| } | |
| .btn-secondary:hover { | |
| background: var(--bg-glass-hover); | |
| border-color: var(--accent); | |
| } | |
| /* ============================================ | |
| AUTH MODAL | |
| ============================================ */ | |
| .auth-card { | |
| max-width: 460px; | |
| } | |
| .auth-tabs { | |
| display: flex; | |
| gap: 8px; | |
| margin-bottom: 14px; | |
| } | |
| .auth-tab { | |
| flex: 1; | |
| padding: 10px 12px; | |
| border-radius: var(--radius-sm); | |
| border: 1px solid var(--border-glass); | |
| background: var(--bg-glass); | |
| color: var(--text-secondary); | |
| cursor: pointer; | |
| font-family: var(--font-body); | |
| } | |
| .auth-tab.active { | |
| border-color: var(--accent); | |
| color: var(--accent-bright); | |
| background: var(--bg-glass-hover); | |
| } | |
| .auth-panel { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 8px; | |
| } | |
| .auth-otp-box { | |
| margin-top: 8px; | |
| border-top: 1px solid var(--border-glass); | |
| padding-top: 10px; | |
| } | |
| .auth-actions { | |
| display: flex; | |
| gap: 8px; | |
| } | |
| .auth-current { | |
| margin-top: 10px; | |
| font-size: 0.8rem; | |
| color: var(--text-secondary); | |
| } | |
| .auth-footer { | |
| margin-top: 10px; | |
| } | |
| .auth-standalone { | |
| max-width: 460px; | |
| } | |
| .auth-page-panel { | |
| margin-top: 10px; | |
| } | |
| .auth-switch-line { | |
| margin-top: 14px; | |
| font-size: 0.82rem; | |
| color: var(--text-secondary); | |
| } | |
| /* ============================================ | |
| RESPONSIVE ADJUSTMENTS (Phase 3) | |
| ============================================ */ | |
| @media (max-width: 600px) { | |
| .lang-cards { | |
| gap: 6px; | |
| flex-wrap: wrap; | |
| justify-content: center; | |
| } | |
| .lang-card { | |
| padding: 10px 12px; | |
| min-width: 70px; | |
| flex: 1 1 calc(33% - 10px); | |
| } | |
| .lang-flag { | |
| font-size: 1.4rem; | |
| } | |
| .lang-name { | |
| font-size: 0.7rem; | |
| } | |
| .level-cards { | |
| flex-wrap: wrap; | |
| } | |
| .level-card { | |
| flex: 1 1 calc(50% - 10px); | |
| font-size: 0.8rem; | |
| padding: 10px 16px; | |
| } | |
| .topic-grid { | |
| grid-template-columns: repeat(2, 1fr); | |
| } | |
| .scenario-grid { | |
| grid-template-columns: repeat(2, 1fr); | |
| } | |
| .badges-grid, | |
| .badges-full-grid { | |
| grid-template-columns: repeat(3, 1fr); | |
| } | |
| .exercise-types { | |
| gap: 4px; | |
| flex-wrap: wrap; | |
| justify-content: center; | |
| } | |
| .ex-type-btn { | |
| padding: 6px 10px; | |
| font-size: 0.72rem; | |
| flex: 1 1 auto; | |
| } | |
| .xp-display { | |
| padding: 3px 6px; | |
| } | |
| .xp-bar-mini { | |
| width: 30px; | |
| } | |
| .xp-value { | |
| display: none; | |
| } | |
| .streak-display { | |
| font-size: 0.68rem; | |
| } | |
| .session-stats { | |
| gap: 6px; | |
| } | |
| .side-panel { | |
| width: 100%; | |
| right: -100%; | |
| } | |
| .side-panel:not(.hidden) { | |
| right: 0; | |
| } | |
| .onboarding-content { | |
| min-height: 100vh; | |
| padding: 24px 4px 24px 4px; | |
| box-sizing: border-box; | |
| position: static; | |
| transform: none; | |
| left: 0; | |
| width: 100%; | |
| max-width: 100vw; | |
| } | |
| } | |
| @media (max-height: 700px) { | |
| .onboarding-screen { | |
| align-items: flex-start; | |
| padding-top: 20px; | |
| } | |
| } | |
| /* ============================================ | |
| MOBILE OPTIMIZATIONS (FINAL POLISH) | |
| ============================================ */ | |
| /* Hide developer controls globally */ | |
| .stt-btn, | |
| #stt-btn { | |
| display: none ; | |
| } | |
| /* Mobile specific tweaks for professional feel */ | |
| @media (max-width: 768px) { | |
| /* Simplified Header */ | |
| .app-header { | |
| padding: 8px 12px; | |
| background: rgba(10, 14, 26, 0.98); | |
| backdrop-filter: blur(12px); | |
| } | |
| .header-left { | |
| flex: 1; | |
| overflow: hidden; | |
| } | |
| .header-title { | |
| font-size: 1.1rem; | |
| white-space: nowrap; | |
| letter-spacing: -0.5px; | |
| } | |
| /* Hide non-essential status text to declutter */ | |
| .header-status { | |
| display: none ; | |
| } | |
| /* Compact Right Header */ | |
| .header-right { | |
| gap: 8px; | |
| } | |
| /* Hide textual stats on mobile */ | |
| .session-stats { | |
| display: none ; | |
| } | |
| /* Make XP bar unobtrusive */ | |
| .xp-display { | |
| padding: 0; | |
| background: transparent; | |
| border: none; | |
| box-shadow: none; | |
| } | |
| .xp-level { | |
| font-size: 0.75rem; | |
| color: var(--accent); | |
| font-weight: 700; | |
| } | |
| .xp-bar-mini { | |
| display: none; | |
| } | |
| .xp-value { | |
| display: none ; | |
| } | |
| /* Streak icon only */ | |
| .streak-display { | |
| background: transparent; | |
| border: none; | |
| padding: 0; | |
| font-size: 0.9rem; | |
| } | |
| /* Better Controls Bar for Thumb Reach */ | |
| .controls-bar { | |
| padding: 12px 14px; | |
| gap: 12px; | |
| background: rgba(17, 24, 39, 0.95); | |
| border-top: 1px solid var(--border-glass); | |
| padding-bottom: max(12px, env(safe-area-inset-bottom)); | |
| box-shadow: 0 -4px 20px rgba(0, 0, 0, 0.4); | |
| } | |
| /* Prominent Mic Button */ | |
| .mic-btn { | |
| width: 60px; | |
| height: 60px; | |
| border-radius: var(--radius-full); | |
| background: var(--bg-secondary); | |
| border: 2px solid var(--accent); | |
| box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3); | |
| } | |
| .mic-btn.active { | |
| background: rgba(252, 129, 129, 0.15); | |
| border-color: var(--error); | |
| box-shadow: 0 0 25px rgba(252, 129, 129, 0.5); | |
| animation: pulseMic 1.5s infinite; | |
| } | |
| /* Adjust Chat Area */ | |
| .chat-panel { | |
| padding: 15px 15px 100px 15px; | |
| } | |
| /* Chat Bubbles - cleaner look */ | |
| .message { | |
| font-size: 0.95rem; | |
| padding: 12px 16px; | |
| max-width: 88%; | |
| border-radius: 18px; | |
| line-height: 1.5; | |
| } | |
| /* Avatar Container - slightly smaller */ | |
| .avatar-container { | |
| height: 140px; | |
| margin-top: 0; | |
| margin-bottom: 0; | |
| } | |
| .avatar-orb { | |
| width: 90px; | |
| height: 90px; | |
| } | |
| .state-label { | |
| opacity: 0; | |
| display: none; | |
| } | |
| /* Hide Waveform on mobile */ | |
| .waveform-canvas { | |
| display: none ; | |
| } | |
| /* Hide particles by default on mobile for performance */ | |
| #particles-canvas { | |
| opacity: 0.2; | |
| } | |
| } | |
| @keyframes pulseMic { | |
| 0% { | |
| transform: scale(1); | |
| box-shadow: 0 0 0 0 rgba(252, 129, 129, 0.7); | |
| } | |
| 70% { | |
| transform: scale(1.05); | |
| box-shadow: 0 0 0 10px rgba(252, 129, 129, 0); | |
| } | |
| 100% { | |
| transform: scale(1); | |
| box-shadow: 0 0 0 0 rgba(252, 129, 129, 0); | |
| } | |
| } | |
| /* ==================================================== | |
| BOTTOM NAVIGATION BAR | |
| ==================================================== */ | |
| .bottom-nav { | |
| position: fixed; | |
| bottom: 0; | |
| left: 50%; | |
| transform: translateX(-50%); | |
| width: 100%; | |
| max-width: 480px; | |
| background: rgba(8, 14, 28, 0.96); | |
| border-top: 1px solid rgba(99, 179, 237, 0.14); | |
| backdrop-filter: blur(20px); | |
| -webkit-backdrop-filter: blur(20px); | |
| display: flex; | |
| align-items: stretch; | |
| z-index: 200; | |
| padding-bottom: env(safe-area-inset-bottom, 0px); | |
| } | |
| .nav-tab { | |
| flex: 1; | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| justify-content: center; | |
| gap: 3px; | |
| padding: 10px 4px 8px; | |
| background: none; | |
| border: none; | |
| cursor: pointer; | |
| color: var(--text-muted); | |
| transition: color 0.2s; | |
| position: relative; | |
| } | |
| .nav-tab::before { | |
| content: ''; | |
| position: absolute; | |
| top: 0; | |
| left: 20%; | |
| right: 20%; | |
| height: 2px; | |
| background: var(--accent); | |
| border-radius: 0 0 3px 3px; | |
| transform: scaleX(0); | |
| transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1); | |
| } | |
| .nav-tab.active { | |
| color: var(--accent); | |
| } | |
| .nav-tab.active::before { | |
| transform: scaleX(1); | |
| } | |
| .nav-tab-icon { | |
| font-size: 1.3rem; | |
| line-height: 1; | |
| } | |
| .nav-tab-label { | |
| font-size: 0.65rem; | |
| font-weight: 600; | |
| letter-spacing: 0.04em; | |
| text-transform: uppercase; | |
| } | |
| /* ==================================================== | |
| GENERIC APP SCREEN (Stories / Flashcards / Progress) | |
| ==================================================== */ | |
| .app-screen { | |
| position: fixed; | |
| inset: 0; | |
| background: var(--bg-primary); | |
| z-index: 100; | |
| display: flex; | |
| flex-direction: column; | |
| overflow-y: auto; | |
| overflow-x: hidden; | |
| padding-bottom: calc(60px + env(safe-area-inset-bottom, 0px)); | |
| max-width: 480px; | |
| left: 50%; | |
| transform: translateX(-50%); | |
| } | |
| .screen-header { | |
| padding: 20px 16px 12px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| flex-wrap: wrap; | |
| gap: 10px; | |
| border-bottom: 1px solid var(--border-glass); | |
| position: sticky; | |
| top: 0; | |
| background: rgba(10,14,26,0.95); | |
| backdrop-filter: blur(12px); | |
| z-index: 10; | |
| } | |
| .screen-title { | |
| font-size: 1.25rem; | |
| font-weight: 700; | |
| color: var(--text-primary); | |
| } | |
| /* ==================================================== | |
| STORIES SCREEN | |
| ==================================================== */ | |
| .story-level-tabs { | |
| display: flex; | |
| gap: 6px; | |
| } | |
| .story-lvl-btn { | |
| padding: 5px 10px; | |
| border-radius: 20px; | |
| border: 1px solid var(--border-glass); | |
| background: var(--bg-glass); | |
| color: var(--text-secondary); | |
| font-size: 0.72rem; | |
| font-weight: 600; | |
| cursor: pointer; | |
| transition: all 0.2s; | |
| } | |
| .story-lvl-btn.active { | |
| background: var(--accent-dim); | |
| border-color: var(--accent); | |
| color: var(--accent-bright); | |
| } | |
| .story-topic-row { | |
| display: flex; | |
| gap: 8px; | |
| padding: 12px 16px; | |
| overflow-x: auto; | |
| scrollbar-width: none; | |
| flex-shrink: 0; | |
| } | |
| .story-topic-row::-webkit-scrollbar { display: none; } | |
| .story-topic-chip { | |
| white-space: nowrap; | |
| padding: 6px 13px; | |
| border-radius: 20px; | |
| border: 1px solid var(--border-glass); | |
| background: var(--bg-glass); | |
| color: var(--text-secondary); | |
| font-size: 0.78rem; | |
| cursor: pointer; | |
| transition: all 0.2s; | |
| flex-shrink: 0; | |
| } | |
| .story-topic-chip.active { | |
| background: rgba(159,122,234,0.2); | |
| border-color: var(--accent-2); | |
| color: #c4b5fd; | |
| } | |
| .story-image-wrap { | |
| position: relative; | |
| margin: 0 16px 12px; | |
| border-radius: var(--radius-lg); | |
| overflow: hidden; | |
| min-height: 180px; | |
| background: var(--bg-secondary); | |
| flex-shrink: 0; | |
| } | |
| .story-image-placeholder { | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| min-height: 180px; | |
| } | |
| .story-placeholder-inner { | |
| text-align: center; | |
| padding: 24px 20px; | |
| color: var(--text-muted); | |
| } | |
| .story-placeholder-inner p { | |
| margin: 10px 0 18px; | |
| font-size: 0.88rem; | |
| line-height: 1.6; | |
| } | |
| .story-gen-btn { | |
| padding: 10px 22px; | |
| font-size: 0.9rem; | |
| } | |
| .story-image { | |
| width: 100%; | |
| height: 210px; | |
| object-fit: cover; | |
| display: block; | |
| border-radius: var(--radius-lg); | |
| transition: opacity 0.4s; | |
| } | |
| .story-image-shimmer { | |
| position: absolute; | |
| inset: 0; | |
| background: linear-gradient(90deg, var(--bg-secondary) 25%, rgba(255,255,255,0.06) 50%, var(--bg-secondary) 75%); | |
| background-size: 200%; | |
| animation: shimmer 1.5s infinite; | |
| border-radius: var(--radius-lg); | |
| } | |
| @keyframes shimmer { | |
| 0% { background-position: 200% center; } | |
| 100% { background-position: -200% center; } | |
| } | |
| .story-card { | |
| margin: 0 16px 20px; | |
| padding: 18px; | |
| background: var(--bg-card); | |
| border: 1px solid var(--border-glass); | |
| border-radius: var(--radius-lg); | |
| flex-shrink: 0; | |
| } | |
| .story-card-header { | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| margin-bottom: 12px; | |
| } | |
| .story-title { | |
| font-size: 1.1rem; | |
| font-weight: 700; | |
| color: var(--accent-bright); | |
| flex: 1; | |
| } | |
| .story-actions { | |
| display: flex; | |
| gap: 8px; | |
| } | |
| .story-action-btn { | |
| background: var(--bg-glass); | |
| border: 1px solid var(--border-glass); | |
| border-radius: 10px; | |
| padding: 6px 10px; | |
| font-size: 1rem; | |
| cursor: pointer; | |
| transition: background 0.2s; | |
| color: var(--text-primary); | |
| } | |
| .story-action-btn:hover { | |
| background: var(--bg-glass-hover); | |
| } | |
| .story-body { | |
| font-size: 0.95rem; | |
| line-height: 1.85; | |
| color: var(--text-primary); | |
| margin-bottom: 18px; | |
| } | |
| .story-body .story-word-highlight { | |
| background: rgba(99,179,237,0.15); | |
| border-bottom: 2px solid var(--accent); | |
| border-radius: 3px; | |
| cursor: pointer; | |
| padding: 0 2px; | |
| transition: background 0.15s; | |
| } | |
| .story-body .story-word-highlight:hover { | |
| background: rgba(99,179,237,0.3); | |
| } | |
| .story-vocab-title { | |
| font-size: 0.85rem; | |
| font-weight: 700; | |
| color: var(--text-secondary); | |
| text-transform: uppercase; | |
| letter-spacing: 0.08em; | |
| margin-bottom: 10px; | |
| } | |
| .story-vocab-grid { | |
| display: grid; | |
| grid-template-columns: repeat(2, 1fr); | |
| gap: 8px; | |
| margin-bottom: 16px; | |
| } | |
| .story-vocab-item { | |
| background: var(--bg-glass); | |
| border: 1px solid var(--border-glass); | |
| border-radius: var(--radius-md); | |
| padding: 10px 12px; | |
| cursor: pointer; | |
| transition: all 0.2s; | |
| } | |
| .story-vocab-item:hover { | |
| border-color: var(--accent); | |
| background: rgba(99,179,237,0.08); | |
| } | |
| .story-vocab-word { | |
| font-weight: 700; | |
| font-size: 0.92rem; | |
| color: var(--accent-bright); | |
| } | |
| .story-vocab-translation { | |
| font-size: 0.78rem; | |
| color: var(--text-muted); | |
| margin-top: 2px; | |
| } | |
| .story-vocab-example { | |
| font-size: 0.75rem; | |
| color: var(--text-secondary); | |
| margin-top: 5px; | |
| font-style: italic; | |
| line-height: 1.4; | |
| } | |
| .story-practice-btn { | |
| width: 100%; | |
| padding: 12px; | |
| } | |
| /* ==================================================== | |
| FLASHCARDS / SRS SCREEN | |
| ==================================================== */ | |
| .fc-deck-select { | |
| display: flex; | |
| gap: 6px; | |
| } | |
| .fc-deck-btn { | |
| padding: 5px 12px; | |
| border-radius: 20px; | |
| border: 1px solid var(--border-glass); | |
| background: var(--bg-glass); | |
| color: var(--text-secondary); | |
| font-size: 0.76rem; | |
| font-weight: 600; | |
| cursor: pointer; | |
| transition: all 0.2s; | |
| } | |
| .fc-deck-btn.active { | |
| background: rgba(159,122,234,0.2); | |
| border-color: var(--accent-2); | |
| color: #c4b5fd; | |
| } | |
| .fc-stats-row { | |
| display: flex; | |
| gap: 8px; | |
| padding: 10px 16px; | |
| flex-shrink: 0; | |
| } | |
| .fc-stat-chip { | |
| flex: 1; | |
| text-align: center; | |
| background: var(--bg-glass); | |
| border: 1px solid var(--border-glass); | |
| border-radius: var(--radius-md); | |
| padding: 8px 4px; | |
| font-size: 0.8rem; | |
| color: var(--text-secondary); | |
| } | |
| .srs-card-wrap { | |
| flex: 1; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| padding: 16px; | |
| perspective: 1000px; | |
| min-height: 260px; | |
| } | |
| .srs-empty-state { | |
| text-align: center; | |
| padding: 30px 20px; | |
| color: var(--text-muted); | |
| } | |
| .srs-empty-state h3 { | |
| margin: 10px 0 8px; | |
| color: var(--text-secondary); | |
| } | |
| .srs-empty-state p { | |
| font-size: 0.88rem; | |
| line-height: 1.6; | |
| } | |
| .srs-card { | |
| width: 100%; | |
| max-width: 340px; | |
| aspect-ratio: 1.6; | |
| cursor: pointer; | |
| transform-style: preserve-3d; | |
| transition: transform 0.55s cubic-bezier(0.4, 0, 0.2, 1); | |
| position: relative; | |
| } | |
| .srs-card.flipped { | |
| transform: rotateY(180deg); | |
| } | |
| .srs-front, | |
| .srs-back { | |
| position: absolute; | |
| inset: 0; | |
| border-radius: var(--radius-xl); | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| justify-content: center; | |
| padding: 24px; | |
| backface-visibility: hidden; | |
| -webkit-backface-visibility: hidden; | |
| } | |
| .srs-front { | |
| background: linear-gradient(135deg, rgba(26,32,56,0.95) 0%, rgba(17,24,39,0.95) 100%); | |
| border: 1px solid rgba(99,179,237,0.2); | |
| box-shadow: 0 8px 40px rgba(0,0,0,0.5), 0 0 0 1px rgba(99,179,237,0.08); | |
| } | |
| .srs-back { | |
| background: linear-gradient(135deg, rgba(42,20,70,0.95) 0%, rgba(25,15,50,0.95) 100%); | |
| border: 1px solid rgba(159,122,234,0.25); | |
| box-shadow: 0 8px 40px rgba(0,0,0,0.5), 0 0 0 1px rgba(159,122,234,0.1); | |
| transform: rotateY(180deg); | |
| } | |
| .srs-card-tag { | |
| font-size: 0.65rem; | |
| font-weight: 700; | |
| text-transform: uppercase; | |
| letter-spacing: 0.15em; | |
| color: var(--text-muted); | |
| margin-bottom: 8px; | |
| } | |
| .srs-card-word { | |
| font-size: 2rem; | |
| font-weight: 800; | |
| color: var(--accent-bright); | |
| text-align: center; | |
| line-height: 1.2; | |
| } | |
| .srs-card-hint { | |
| font-size: 0.72rem; | |
| color: var(--text-muted); | |
| margin-top: 12px; | |
| } | |
| .srs-card-translation { | |
| font-size: 1.4rem; | |
| font-weight: 700; | |
| color: #c4b5fd; | |
| text-align: center; | |
| margin-bottom: 10px; | |
| } | |
| .srs-card-example { | |
| font-size: 0.82rem; | |
| color: var(--text-secondary); | |
| text-align: center; | |
| font-style: italic; | |
| line-height: 1.5; | |
| } | |
| .srs-speak-btn { | |
| margin-top: 12px; | |
| background: rgba(159,122,234,0.2); | |
| border: 1px solid rgba(159,122,234,0.3); | |
| border-radius: 20px; | |
| color: #c4b5fd; | |
| font-size: 0.78rem; | |
| padding: 5px 14px; | |
| cursor: pointer; | |
| } | |
| .srs-progress-dots { | |
| position: absolute; | |
| bottom: -22px; | |
| left: 50%; | |
| transform: translateX(-50%); | |
| display: flex; | |
| gap: 5px; | |
| } | |
| .srs-dot { | |
| width: 6px; | |
| height: 6px; | |
| border-radius: 50%; | |
| background: var(--border-glass); | |
| transition: background 0.2s, transform 0.2s; | |
| } | |
| .srs-dot.active { | |
| background: var(--accent); | |
| transform: scale(1.3); | |
| } | |
| .srs-dot.done { | |
| background: var(--success); | |
| } | |
| .srs-rating-row { | |
| display: flex; | |
| gap: 8px; | |
| padding: 12px 16px 16px; | |
| flex-shrink: 0; | |
| } | |
| .srs-rate-btn { | |
| flex: 1; | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| gap: 3px; | |
| padding: 10px 4px; | |
| border-radius: var(--radius-md); | |
| border: 1px solid var(--border-glass); | |
| background: var(--bg-glass); | |
| cursor: pointer; | |
| font-size: 1.1rem; | |
| transition: all 0.2s; | |
| color: var(--text-primary); | |
| } | |
| .srs-rate-btn span { | |
| font-size: 0.65rem; | |
| font-weight: 700; | |
| text-transform: uppercase; | |
| letter-spacing: 0.06em; | |
| color: var(--text-muted); | |
| } | |
| .srs-rate-btn.again { border-color: rgba(252, 129, 129, 0.3); } | |
| .srs-rate-btn.again:hover { background: rgba(252, 129, 129, 0.12); border-color: var(--error); } | |
| .srs-rate-btn.hard { border-color: rgba(246, 173, 85, 0.3); } | |
| .srs-rate-btn.hard:hover { background: rgba(246, 173, 85, 0.12); border-color: var(--warning); } | |
| .srs-rate-btn.good { border-color: rgba(99, 179, 237, 0.3); } | |
| .srs-rate-btn.good:hover { background: rgba(99, 179, 237, 0.12); border-color: var(--accent); } | |
| .srs-rate-btn.easy { border-color: rgba(104, 211, 145, 0.3); } | |
| .srs-rate-btn.easy:hover { background: rgba(104, 211, 145, 0.12); border-color: var(--success); } | |
| /* ==================================================== | |
| PROGRESS SCREEN | |
| ==================================================== */ | |
| .progress-grid { | |
| display: grid; | |
| grid-template-columns: repeat(3, 1fr); | |
| gap: 10px; | |
| padding: 16px 16px 8px; | |
| } | |
| .prog-card { | |
| background: var(--bg-card); | |
| border: 1px solid var(--border-glass); | |
| border-radius: var(--radius-lg); | |
| padding: 16px 12px; | |
| text-align: center; | |
| transition: border-color 0.2s; | |
| } | |
| .prog-card:hover { | |
| border-color: var(--accent); | |
| } | |
| .prog-card.xp-card { | |
| grid-column: span 3; | |
| background: linear-gradient(135deg, rgba(10,18,40,0.95) 0%, rgba(26,32,56,0.95) 100%); | |
| border-color: rgba(99,179,237,0.2); | |
| padding: 20px 16px; | |
| } | |
| .prog-card-icon { | |
| font-size: 1.5rem; | |
| margin-bottom: 4px; | |
| } | |
| .prog-card-val { | |
| font-size: 1.6rem; | |
| font-weight: 800; | |
| color: var(--accent-bright); | |
| line-height: 1; | |
| } | |
| .xp-card .prog-card-val { | |
| font-size: 2.2rem; | |
| margin: 4px 0; | |
| } | |
| .prog-card-label { | |
| font-size: 0.7rem; | |
| font-weight: 600; | |
| color: var(--text-muted); | |
| text-transform: uppercase; | |
| letter-spacing: 0.08em; | |
| margin-top: 4px; | |
| } | |
| .prog-xp-bar { | |
| height: 6px; | |
| background: var(--bg-glass); | |
| border-radius: 3px; | |
| margin-top: 8px; | |
| overflow: hidden; | |
| } | |
| .prog-xp-fill { | |
| height: 100%; | |
| background: linear-gradient(90deg, var(--accent-dim), var(--accent)); | |
| border-radius: 3px; | |
| transition: width 0.6s cubic-bezier(0.4, 0, 0.2, 1); | |
| } | |
| .leaderboard-section { | |
| margin: 8px 16px 16px; | |
| background: var(--bg-card); | |
| border: 1px solid var(--border-glass); | |
| border-radius: var(--radius-lg); | |
| overflow: hidden; | |
| flex-shrink: 0; | |
| } | |
| .lb-header { | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| padding: 14px 16px; | |
| border-bottom: 1px solid var(--border-glass); | |
| } | |
| .lb-header h3 { | |
| font-size: 0.95rem; | |
| font-weight: 700; | |
| } | |
| .lb-refresh-btn { | |
| background: none; | |
| border: none; | |
| font-size: 1rem; | |
| cursor: pointer; | |
| color: var(--text-muted); | |
| transition: color 0.2s, transform 0.3s; | |
| } | |
| .lb-refresh-btn:hover { | |
| color: var(--accent); | |
| transform: rotate(180deg); | |
| } | |
| .lb-loading { | |
| padding: 20px; | |
| text-align: center; | |
| color: var(--text-muted); | |
| font-size: 0.85rem; | |
| } | |
| .lb-row { | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| padding: 10px 16px; | |
| border-bottom: 1px solid var(--border-glass); | |
| transition: background 0.15s; | |
| } | |
| .lb-row:last-child { border-bottom: none; } | |
| .lb-row:hover { background: var(--bg-glass); } | |
| .lb-row.me { background: rgba(99,179,237,0.07); } | |
| .lb-rank { | |
| width: 22px; | |
| font-size: 0.8rem; | |
| font-weight: 800; | |
| color: var(--text-muted); | |
| text-align: center; | |
| flex-shrink: 0; | |
| } | |
| .lb-rank.gold { color: #fbbf24; } | |
| .lb-rank.silver { color: #94a3b8; } | |
| .lb-rank.bronze { color: #b45309; } | |
| .lb-flag { font-size: 1.2rem; flex-shrink: 0; } | |
| .lb-info { flex: 1; min-width: 0; } | |
| .lb-name { | |
| font-size: 0.88rem; | |
| font-weight: 600; | |
| color: var(--text-primary); | |
| white-space: nowrap; | |
| overflow: hidden; | |
| text-overflow: ellipsis; | |
| } | |
| .lb-level { | |
| font-size: 0.7rem; | |
| color: var(--text-muted); | |
| } | |
| .lb-xp { | |
| font-size: 0.85rem; | |
| font-weight: 700; | |
| color: var(--accent); | |
| flex-shrink: 0; | |
| } | |
| .badges-progress-section { | |
| margin: 0 16px 24px; | |
| } | |
| /* ==================================================== | |
| LIGHT THEME OVERRIDES FOR NEW SCREENS | |
| ==================================================== */ | |
| [data-theme="light"] .app-screen { | |
| background: #f0f4ff; | |
| } | |
| [data-theme="light"] .screen-header { | |
| background: rgba(240,244,255,0.95); | |
| border-bottom-color: rgba(100,130,220,0.2); | |
| } | |
| [data-theme="light"] .screen-title { color: #111827; } | |
| [data-theme="light"] .story-lvl-btn, | |
| [data-theme="light"] .story-topic-chip, | |
| [data-theme="light"] .fc-deck-btn, | |
| [data-theme="light"] .fc-stat-chip { | |
| background: #ffffff; | |
| border-color: rgba(100,130,220,0.25); | |
| color: #374151; | |
| } | |
| [data-theme="light"] .story-card, | |
| [data-theme="light"] .lb-row, | |
| [data-theme="light"] .prog-card, | |
| [data-theme="light"] .leaderboard-section { | |
| background: #ffffff; | |
| border-color: rgba(100,130,220,0.2); | |
| } | |
| [data-theme="light"] .srs-front { | |
| background: linear-gradient(135deg, #e8eef8 0%, #dce7f7 100%); | |
| border-color: rgba(100,130,220,0.3); | |
| } | |
| [data-theme="light"] .srs-back { | |
| background: linear-gradient(135deg, #ede9fe 0%, #ddd6fe 100%); | |
| border-color: rgba(139,92,246,0.3); | |
| } | |
| [data-theme="light"] .srs-card-word { color: #1d4ed8; } | |
| [data-theme="light"] .srs-card-translation { color: #6d28d9; } | |
| [data-theme="light"] .srs-card-example { color: #374151; } | |
| [data-theme="light"] .bottom-nav { | |
| background: rgba(240,244,255,0.97); | |
| border-top-color: rgba(100,130,220,0.2); | |
| } | |
| [data-theme="light"] .nav-tab { color: #9ca3af; } | |
| [data-theme="light"] .nav-tab.active { color: #2563eb; } | |
| [data-theme="light"] .nav-tab::before { background: #2563eb; } | |
| [data-theme="light"] .lb-name { color: #111827; } | |
| [data-theme="light"] .prog-card-val { color: #1d4ed8; } | |
| /* ==================================================== | |
| APP CONTAINER PADDING FOR BOTTOM NAV | |
| ==================================================== */ | |
| .app-container.has-bottom-nav { | |
| padding-bottom: calc(60px + env(safe-area-inset-bottom, 0px)); | |
| } | |