diff --git a/app/static/css/base.css b/app/static/css/base.css new file mode 100644 index 0000000..37d70ed --- /dev/null +++ b/app/static/css/base.css @@ -0,0 +1,148 @@ +/* ========================================================================== + 1. Base Tokens, Typography, Reset & Global Safe Areas + ========================================================================== */ + +/* Modern CSS Design System for Notes App */ +:root { + --bg-main: #0f172a; + --bg-surface: #1e293b; + --bg-surface-hover: #334155; + --bg-card: #1e293b; + --bg-input: #0f172a; + --border-color: #334155; + --border-focus: #38bdf8; + + --text-main: #f8fafc; + --text-muted: #94a3b8; + --text-dim: #64748b; + + --primary: #38bdf8; + --primary-hover: #0ea5e9; + --primary-dim: rgba(56, 189, 248, 0.15); + + --success: #10b981; + --success-hover: #059669; + --success-dim: rgba(16, 185, 129, 0.15); + + --danger: #ef4444; + --danger-hover: #dc2626; + --danger-dim: rgba(239, 68, 68, 0.15); + + --tag-bg: #293548; + --tag-text: #7dd3fc; + + --radius-sm: 6px; + --radius-md: 10px; + --radius-lg: 14px; + --radius-full: 9999px; + + --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.2); + --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.3), 0 2px 4px -2px rgba(0, 0, 0, 0.3); + --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.4), 0 4px 6px -4px rgba(0, 0, 0, 0.4); + + --font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif; + --transition: all 0.18s ease-in-out; + + --sat: env(safe-area-inset-top, 0px); + --sar: env(safe-area-inset-right, 0px); + --sab: env(safe-area-inset-bottom, 0px); + --sal: env(safe-area-inset-left, 0px); + --navbar-height: 60px; +} + +[data-theme="light"] { + --bg-main: #f1f5f9; + --bg-surface: #ffffff; + --bg-surface-hover: #f8fafc; + --bg-card: #ffffff; + --bg-input: #f8fafc; + --border-color: #cbd5e1; + --border-focus: #0284c7; + + --text-main: #0f172a; + --text-muted: #475569; + --text-dim: #94a3b8; + + --primary: #0284c7; + --primary-hover: #0369a1; + --primary-dim: rgba(2, 132, 199, 0.1); + + --success: #059669; + --success-hover: #047857; + --success-dim: rgba(5, 150, 105, 0.1); + + --tag-bg: #e2e8f0; + --tag-text: #0369a1; + + --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05); + --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.08); + --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1); +} + +* { + box-sizing: border-box; + margin: 0; + padding: 0; +} + +html, body { + overflow-x: clip; + -webkit-tap-highlight-color: transparent; +} + +body { + background-color: var(--bg-main); + color: var(--text-main); + font-family: var(--font-family); + line-height: 1.5; + -webkit-font-smoothing: antialiased; + min-height: 100vh; + min-height: 100dvh; +} + +.hidden { + display: none !important; +} + + +/* Main Content */ +.main-content { + max-width: 900px; + width: 100%; + margin: 0 auto; + padding: 32px 20px; + display: flex; + flex-direction: column; + gap: 36px; +} + + +/* --- Responsive Mobile Overrides (max-width: 768px) --- */ +@media (max-width: 768px) { + /* 1. iOS Safari Auto-Zoom Fix (< 16px triggers zoom) */ + input, select, textarea, + .input-styled, .search-input-box input, .form-group input, + .search-mini-box input, .reader-select { + font-size: 16px !important; + } + + /* 2. Global Mobile App Container & Safe Areas */ + html, body { + overflow-x: hidden; + -webkit-overflow-scrolling: touch; + min-height: 100dvh; + } + + .app-shell { + min-height: 100dvh; + overflow-x: hidden; + } + + .main-content, + .srs-view, + .reader-view { + padding-bottom: calc(74px + env(safe-area-inset-bottom, 0px)) !important; + } + + +} diff --git a/app/static/css/components.css b/app/static/css/components.css new file mode 100644 index 0000000..fd7a865 --- /dev/null +++ b/app/static/css/components.css @@ -0,0 +1,1147 @@ +/* ========================================================================== + 2. UI Components: Auth, Navbar, Drawer, Buttons, Modals & Mobile Tab Bar + ========================================================================== */ + +/* Auth Screen / Login Overlay */ +.auth-screen, +.login-overlay { + position: fixed; + inset: 0; + z-index: 10000; + min-height: 100vh; + display: flex; + align-items: center; + justify-content: center; + padding: 20px; + background-color: var(--bg-main); + background-image: radial-gradient(circle at top, rgba(56, 189, 248, 0.15), transparent 70%); +} + +.auth-card, +.login-card { + background-color: var(--bg-surface); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + padding: 36px 32px; + width: 100%; + max-width: 420px; + box-shadow: var(--shadow-lg); + animation: fadeInScale 0.2s ease-out; +} + +@keyframes fadeInScale { + from { + opacity: 0; + transform: scale(0.96); + } + to { + opacity: 1; + transform: scale(1); + } +} + +.auth-header, +.login-header { + text-align: center; + margin-bottom: 28px; +} + +.auth-header .app-logo, +.login-header .login-logo { + font-size: 48px; + margin-bottom: 8px; + display: block; +} + +.auth-header h2, +.login-header h1 { + font-size: 24px; + font-weight: 700; + color: var(--text-main); +} + +.auth-header p, +.login-header p { + color: var(--text-muted); + font-size: 14px; + margin-top: 4px; +} + +.login-form { + display: flex; + flex-direction: column; +} + +.login-error { + background-color: var(--danger-dim); + color: var(--danger); + border: 1px solid var(--danger); + padding: 10px 14px; + border-radius: var(--radius-sm); + font-size: 13px; + margin-bottom: 16px; + text-align: center; +} + +.auth-footer, +.login-footer { + margin-top: 24px; + text-align: center; + font-size: 12px; + color: var(--text-dim); +} + +.form-group { + margin-bottom: 18px; +} + +.form-group label { + display: block; + font-size: 13px; + font-weight: 600; + color: var(--text-muted); + margin-bottom: 6px; +} + +.form-group input { + width: 100%; + padding: 12px 14px; + background-color: var(--bg-input); + border: 1px solid var(--border-color); + border-radius: var(--radius-sm); + color: var(--text-main); + font-size: 15px; + outline: none; + transition: var(--transition); +} + +.form-group input:focus { + border-color: var(--border-focus); + box-shadow: 0 0 0 3px var(--primary-dim); +} + +.error-banner { + background-color: var(--danger-dim); + border: 1px solid var(--danger); + color: #fca5a5; + padding: 10px 14px; + border-radius: var(--radius-sm); + font-size: 13px; + margin-bottom: 16px; +} + +.success-banner { + background-color: var(--success-dim, rgba(16, 185, 129, 0.15)); + border: 1px solid var(--success, #10b981); + color: #86efac; + padding: 10px 14px; + border-radius: var(--radius-sm); + font-size: 13px; + margin-bottom: 16px; +} + + +/* App Navbar */ +.app-container { + display: flex; + flex-direction: column; + min-height: 100vh; +} + +/* App Navbar (Unified Layout) */ +.navbar { + background-color: var(--bg-surface); + border-bottom: 1px solid var(--border-color); + padding: 8px 20px; + display: flex; + align-items: center; + justify-content: space-between; + gap: 16px; + position: sticky; + top: 0; + z-index: 100; + min-height: var(--navbar-height); + box-sizing: border-box; +} + +.nav-left { + display: flex; + align-items: center; + gap: 10px; + flex-shrink: 0; +} + +.drawer-toggle-btn { + display: inline-flex; + align-items: center; + justify-content: center; + width: 36px; + height: 36px; + border-radius: var(--radius-sm); + background-color: transparent; + border: 1px solid transparent; + color: var(--text-main); + cursor: pointer; + font-size: 20px; + line-height: 1; + transition: var(--transition); +} + +.drawer-toggle-btn:hover { + background-color: var(--bg-surface-hover); + border-color: var(--border-color); + color: var(--primary); +} + +.nav-brand { + display: flex; + align-items: center; + gap: 8px; + cursor: pointer; + user-select: none; + transition: opacity 0.15s ease; +} + +.nav-brand:hover { + opacity: 0.85; +} + +.brand-icon { + font-size: 24px; +} + +.brand-title { + font-size: 20px; + font-weight: 800; + color: var(--text-main); + letter-spacing: -0.5px; +} + +.brand-sub { + font-size: 12px; + background-color: var(--primary-dim); + color: var(--primary); + padding: 2px 8px; + border-radius: var(--radius-full); + font-weight: 600; + margin-left: 4px; +} + +.nav-center { + display: flex; + align-items: center; + justify-content: center; + gap: 14px; + flex: 1; + min-width: 0; +} + +.nav-stats { + display: flex; + gap: 8px; +} + +.stat-badge { + font-size: 13px; + background-color: var(--bg-main); + border: 1px solid var(--border-color); + padding: 4px 12px; + border-radius: var(--radius-full); + color: var(--text-muted); +} + +.stat-badge strong { + color: var(--text-main); +} + +.stat-badge.stat-today strong { + color: var(--success); +} + +.nav-actions { + display: flex; + align-items: center; + gap: 10px; + flex-shrink: 0; +} + +.user-profile-btn { + display: inline-flex; + align-items: center; + gap: 8px; + padding: 5px 12px; + border-radius: var(--radius-full); + background-color: var(--bg-surface-hover); + border: 1px solid var(--border-color); + color: var(--text-main); + font-size: 13px; + font-weight: 600; + cursor: pointer; + transition: var(--transition); +} + +.user-profile-btn:hover { + border-color: var(--primary); + color: var(--primary); + background-color: var(--primary-dim); +} + +.user-avatar-icon { + font-size: 15px; +} + +.user-badge { + font-size: 13px; + color: var(--text-main); + font-weight: 600; +} + +/* ----------------------------------------------------------------------- + Unified Navigation Drawer (Desktop & Mobile) + ----------------------------------------------------------------------- */ +.drawer-backdrop { + position: fixed; + top: 0; + left: 0; + width: 100vw; + height: 100vh; + background-color: rgba(0, 0, 0, 0.65); + backdrop-filter: blur(4px); + -webkit-backdrop-filter: blur(4px); + z-index: 1999; + opacity: 0; + pointer-events: none; + transition: opacity 0.26s cubic-bezier(0.16, 1, 0.3, 1); +} + +.drawer-backdrop.active { + opacity: 1; + pointer-events: auto; +} + +.app-drawer { + position: fixed; + top: 0; + left: 0; + bottom: 0; + width: min(340px, 86vw); + background-color: var(--bg-surface); + border-right: 1px solid var(--border-color); + box-shadow: 4px 0 28px rgba(0, 0, 0, 0.5); + z-index: 2000; + display: flex; + flex-direction: column; + transform: translateX(-100%); + transition: transform 0.28s cubic-bezier(0.16, 1, 0.3, 1); + will-change: transform; + overflow-y: auto; + -webkit-overflow-scrolling: touch; +} + +.app-drawer.active { + transform: translateX(0); +} + +body.drawer-open { + overflow: hidden !important; +} + +.drawer-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: calc(16px + env(safe-area-inset-top, 0px)) 16px 14px 18px; + border-bottom: 1px solid var(--border-color); + background-color: var(--bg-surface); + position: sticky; + top: 0; + z-index: 10; +} + +.drawer-user-card { + display: flex; + align-items: center; + gap: 12px; + min-width: 0; +} + +.drawer-user-avatar { + width: 42px; + height: 42px; + border-radius: var(--radius-full); + background: linear-gradient(135deg, var(--primary), #6366f1); + color: #ffffff; + display: flex; + align-items: center; + justify-content: center; + font-size: 20px; + flex-shrink: 0; + box-shadow: var(--shadow-sm); +} + +.drawer-user-info { + display: flex; + flex-direction: column; + min-width: 0; +} + +.drawer-user-name { + font-size: 15px; + font-weight: 700; + color: var(--text-main); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.drawer-user-desc { + font-size: 12px; + color: var(--text-muted); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.drawer-close-btn { + width: 34px; + height: 34px; + border-radius: var(--radius-sm); + display: flex; + align-items: center; + justify-content: center; + font-size: 18px; + color: var(--text-muted); + background: transparent; + border: none; + cursor: pointer; + transition: var(--transition); +} + +.drawer-close-btn:hover { + background-color: var(--bg-surface-hover); + color: var(--text-main); +} + +.drawer-stats-summary { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 8px; + padding: 12px 14px; + margin: 12px 14px 4px 14px; + background-color: var(--bg-main); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + text-align: center; +} + +.drawer-stat-item { + display: flex; + flex-direction: column; + gap: 2px; +} + +.drawer-stat-val { + font-size: 16px; + font-weight: 800; + color: var(--text-main); +} + +.drawer-stat-lbl { + font-size: 10px; + font-weight: 600; + color: var(--text-dim); + text-transform: uppercase; + letter-spacing: 0.3px; +} + +.drawer-nav { + flex: 1; + padding: 8px 12px; + display: flex; + flex-direction: column; + gap: 4px; +} + +.drawer-section-title { + font-size: 11px; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.6px; + color: var(--text-dim); + padding: 12px 8px 4px 8px; +} + +.drawer-nav-list { + list-style: none; + padding: 0; + margin: 0; + display: flex; + flex-direction: column; + gap: 3px; +} + +.drawer-nav-item { + width: 100%; + display: flex; + align-items: center; + gap: 12px; + padding: 10px 12px; + border-radius: var(--radius-sm); + background: transparent; + border: 1px solid transparent; + color: var(--text-main); + font-size: 14px; + font-weight: 500; + text-align: left; + cursor: pointer; + transition: var(--transition); + text-decoration: none; +} + +.drawer-nav-item:hover { + background-color: var(--bg-surface-hover); + color: var(--primary); + border-color: var(--border-color); +} + +.drawer-nav-item.active { + background-color: var(--primary-dim); + color: var(--primary); + border-color: rgba(56, 189, 248, 0.3); + font-weight: 700; +} + +.drawer-item-icon { + font-size: 18px; + width: 24px; + text-align: center; + flex-shrink: 0; +} + +.drawer-item-label { + flex: 1; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.drawer-badge { + padding: 2px 7px; + font-size: 11px; + font-weight: 700; + border-radius: var(--radius-full); + background-color: var(--primary); + color: #0f172a; + line-height: 1.2; +} + +.drawer-footer { + padding: 14px 16px calc(14px + env(safe-area-inset-bottom, 0px)) 16px; + border-top: 1px solid var(--border-color); + font-size: 12px; + color: var(--text-dim); + text-align: center; +} + + +/* Buttons */ +.btn { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 6px; + padding: 10px 18px; + border-radius: var(--radius-sm); + font-size: 14px; + font-weight: 600; + cursor: pointer; + border: none; + transition: var(--transition); +} + +.btn-primary { + background-color: var(--primary); + color: #0f172a; +} + +.btn-primary:hover { + background-color: var(--primary-hover); +} + +.btn-success { + background-color: var(--success); + color: #ffffff; +} + +.btn-success:hover { + background-color: var(--success-hover); +} + +.btn-outline { + background-color: transparent; + border: 1px solid var(--border-color); + color: var(--text-muted); +} + +.btn-outline:hover { + border-color: var(--text-main); + color: var(--text-main); +} + +.btn-sm { + padding: 6px 12px; + font-size: 12px; +} + +.btn-lg { + padding: 14px 24px; + font-size: 16px; +} + +.btn-block { + width: 100%; +} + +.btn-subtext { + font-size: 11px; + opacity: 0.8; + margin-left: 4px; +} + +.icon-btn { + background: transparent; + border: 1px solid var(--border-color); + border-radius: var(--radius-sm); + padding: 6px 10px; + cursor: pointer; + color: var(--text-muted); + font-size: 16px; + transition: var(--transition); +} + +.icon-btn:hover { + color: var(--text-main); + border-color: var(--text-main); +} + + +/* Spinner */ +.lookup-spinner { + display: flex; + align-items: center; + justify-content: center; + gap: 12px; + padding: 24px; + color: var(--primary); + font-size: 14px; + font-weight: 500; +} + +.spinner { + width: 24px; + height: 24px; + border: 3px solid var(--border-color); + border-top-color: var(--primary); + border-radius: 50%; + animation: spin 0.8s linear infinite; +} + +@keyframes spin { + to { transform: rotate(360deg); } +} + + +/* Modal */ +.modal-backdrop { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.7); + backdrop-filter: blur(4px); + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; + padding: 20px; +} + +.modal-window { + background-color: var(--bg-surface); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + width: 100%; + max-width: 520px; + box-shadow: var(--shadow-lg); + display: flex; + flex-direction: column; +} + +.modal-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 16px 20px; + border-bottom: 1px solid var(--border-color); +} + +.modal-header h3 { + font-size: 18px; + font-weight: 700; +} + +.modal-body { + padding: 20px; + display: flex; + flex-direction: column; + gap: 14px; +} + +.modal-footer { + display: flex; + justify-content: flex-end; + gap: 10px; + padding: 14px 20px; + border-top: 1px solid var(--border-color); +} + +.modal-sm { + max-width: 420px; +} + +/* Navigation Additions */ +.nav-center { + display: flex; + align-items: center; +} + +.btn-trainer { + background: linear-gradient(135deg, #0284c7, #38bdf8); + color: #0f172a; + font-weight: 700; + box-shadow: 0 2px 10px rgba(56, 189, 248, 0.25); + display: inline-flex; + align-items: center; + gap: 8px; + padding: 7px 14px; + border-radius: var(--radius-sm); + border: none; + cursor: pointer; + transition: var(--transition); +} + +.btn-trainer:hover { + box-shadow: 0 4px 14px rgba(56, 189, 248, 0.45); + transform: translateY(-1px); +} + +.srs-due-badge { + background-color: #0f172a; + color: #38bdf8; + font-size: 11px; + font-weight: 800; + padding: 1px 7px; + border-radius: var(--radius-full); + min-width: 18px; + text-align: center; +} + +.srs-due-badge.has-due { + background-color: #ef4444; + color: #ffffff; + animation: pulseDue 2s infinite; +} + +@keyframes pulseDue { + 0%, 100% { transform: scale(1); } + 50% { transform: scale(1.15); } +} + + +/* Export Modal */ +.export-modal-window { + max-width: 620px; +} + +.modal-lead { + font-size: 14px; + color: var(--text-muted); + margin-bottom: 8px; +} + +.export-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 12px; +} + +.export-tile { + background-color: var(--bg-input); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + padding: 16px; + display: flex; + flex-direction: column; + justify-content: space-between; + gap: 12px; + transition: var(--transition); +} + +.export-tile:hover { + border-color: var(--primary); + transform: translateY(-2px); + box-shadow: var(--shadow-md); +} + +.export-tile-icon { + font-size: 28px; +} + +.export-tile-info h4 { + font-size: 15px; + font-weight: 700; + color: var(--text-main); + margin-bottom: 4px; +} + +.export-tile-info p { + font-size: 12px; + color: var(--text-dim); + line-height: 1.4; +} + + +/* Voice Settings Modal */ +.voice-modal-window { + max-width: 680px; + width: 95%; +} + +.voice-modal-body { + padding: 20px 24px; + display: flex; + flex-direction: column; + gap: 16px; + max-height: 80vh; + overflow-y: auto; +} + +.modal-desc-sub { + font-size: 13px; + color: var(--text-muted); + margin: 0 0 10px 0; +} + +.voice-group-title { + font-size: 14px; + font-weight: 700; + color: var(--text-main); + display: block; + margin-bottom: 10px; +} + +.voice-options-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 12px; +} + +@media (max-width: 680px) { + .voice-options-grid { + grid-template-columns: 1fr; + } +} + +.voice-card-label { + cursor: pointer; + display: block; + position: relative; + user-select: none; +} + +.voice-card-label input[type="radio"] { + position: absolute; + opacity: 0; + pointer-events: none; +} + +.voice-card { + border: 1px solid var(--border-color); + background: var(--bg-card); + border-radius: var(--radius-md); + padding: 14px 14px; + display: flex; + flex-direction: column; + gap: 8px; + height: 100%; + transition: var(--transition); +} + +.voice-card:hover { + border-color: var(--primary-dim); +} + +.voice-card-label input[type="radio"]:checked + .voice-card { + border-color: var(--primary); + background: var(--bg-main); + box-shadow: 0 0 0 2px var(--primary-dim); +} + +.voice-card-head { + display: flex; + justify-content: space-between; + align-items: center; + gap: 6px; +} + +.voice-card-desc { + font-size: 12px; + line-height: 1.4; + color: var(--text-muted); + flex: 1; +} + +.badge-recommended { + background: rgba(16, 185, 129, 0.15); + color: #10b981; + font-size: 10px; + font-weight: 700; + padding: 2px 6px; + border-radius: 4px; + white-space: nowrap; +} + +.badge-uk { + background: rgba(59, 130, 246, 0.15); + color: #3b82f6; + font-size: 10px; + font-weight: 700; + padding: 2px 6px; + border-radius: 4px; + white-space: nowrap; +} + +.voice-test-btn { + align-self: flex-start; + margin-top: 4px; +} + + +/* Mobile Navigation & Tab Bar (iOS Native Style Base) */ +.mobile-only-btn, +.mobile-tab-bar, +.mobile-only { + display: none; +} + +.mobile-tab-bar { + position: fixed; + bottom: 0; + left: 0; + right: 0; + height: calc(56px + env(safe-area-inset-bottom, 0px)); + padding-bottom: env(safe-area-inset-bottom, 0px); + background-color: rgba(30, 41, 59, 0.94); + backdrop-filter: blur(16px); + -webkit-backdrop-filter: blur(16px); + border-top: 1px solid var(--border-color); + z-index: 1000; + align-items: center; + justify-content: space-around; +} + +[data-theme="light"] .mobile-tab-bar { + background-color: rgba(255, 255, 255, 0.94); +} + +.tab-item { + flex: 1; + height: 100%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 3px; + background: none; + border: none; + color: var(--text-muted); + cursor: pointer; + position: relative; + padding: 6px 0; + -webkit-tap-highlight-color: transparent; + transition: var(--transition); +} + +.tab-item:active { + transform: scale(0.92); +} + +.tab-item.active { + color: var(--primary); +} + +.tab-icon { + font-size: 19px; + line-height: 1; +} + +.tab-label { + font-size: 10px; + font-weight: 600; + letter-spacing: -0.2px; +} + +.tab-badge { + position: absolute; + top: 5px; + right: calc(50% - 18px); + background-color: #ef4444; + color: #ffffff; + font-size: 10px; + font-weight: 700; + padding: 1px 5px; + border-radius: 9999px; + line-height: 1.2; +} + +/* Mobile Sheet / Menu */ +.mobile-sheet-window { + max-width: 440px; +} + +.mobile-user-card { + display: flex; + align-items: center; + gap: 12px; + padding: 14px 16px; + background: var(--bg-input); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + margin-bottom: 16px; +} + +.mobile-user-avatar { + font-size: 28px; + background: var(--bg-surface-hover); + width: 48px; + height: 48px; + display: flex; + align-items: center; + justify-content: center; + border-radius: var(--radius-full); +} + +.mobile-user-info strong { + font-size: 16px; + color: var(--text-main); +} + +.mobile-user-info .subtitle { + font-size: 12px; + color: var(--text-muted); +} + +.mobile-menu-actions { + display: flex; + flex-direction: column; + gap: 10px; +} + +/* Sheet drag handle for mobile bottom sheets */ +.sheet-drag-handle { + width: 38px; + height: 4px; + border-radius: 2px; + background-color: var(--border-color); + margin: 0 auto 10px auto; +} + + +/* --- Responsive Mobile Overrides (max-width: 768px) --- */ +@media (max-width: 768px) { + /* 3. Header & Navigation: Unified Responsive Header */ + .navbar { + padding: calc(8px + env(safe-area-inset-top, 0px)) 10px 8px 10px; + gap: 8px; + } + + .brand-sub, + .nav-stats { + display: none !important; + } + + .btn-trainer .trainer-text { + display: none !important; + } + + .btn-trainer { + padding: 6px 10px !important; + font-size: 13px !important; + min-height: 36px; + } + + .user-profile-btn #user-display-name { + display: none !important; + } + + .user-profile-btn { + padding: 6px 10px !important; + border-radius: var(--radius-sm); + min-height: 36px; + } + + .mobile-tab-bar { + display: flex !important; + } + + .mobile-only { + display: block !important; + } + + /* 8. Modals: Mobile Bottom-Sheet style */ + .modal-backdrop { + padding: 0; + align-items: flex-end; + } + + .modal-window { + max-width: 100%; + max-height: calc(90dvh - env(safe-area-inset-top, 0px)); + border-radius: 20px 20px 0 0; + border-bottom: none; + overflow-y: auto; + -webkit-overflow-scrolling: touch; + padding-bottom: env(safe-area-inset-bottom, 0px); + animation: slideUpSheet 0.22s cubic-bezier(0.16, 1, 0.3, 1); + } + + .stats-modal-window { + width: 100%; + max-width: 100%; + } + + .stats-hero-grid { + grid-template-columns: 1fr 1fr; + gap: 8px; + } + + .heatmap-container-wrap { + -webkit-overflow-scrolling: touch; + } + + /* 9. Batch action bar */ + .batch-action-bar { + flex-direction: column; + gap: 10px; + bottom: calc(64px + env(safe-area-inset-bottom, 0px)) !important; + left: 10px; + right: 10px; + } + + .batch-actions { + width: 100%; + justify-content: space-between; + } + +} diff --git a/app/static/css/dictionary.css b/app/static/css/dictionary.css new file mode 100644 index 0000000..1277dab --- /dev/null +++ b/app/static/css/dictionary.css @@ -0,0 +1,929 @@ +/* ========================================================================== + 3. Dictionary, Search, Word Cards, Collections & Tags + ========================================================================== */ + +/* Search Box */ +.search-box-wrapper { + display: flex; + flex-direction: column; + gap: 8px; +} + +.search-input-box { + display: flex; + align-items: center; + background-color: var(--bg-surface); + border: 2px solid var(--border-color); + border-radius: var(--radius-md); + padding: 6px 10px 6px 16px; + transition: var(--transition); + box-shadow: var(--shadow-sm); +} + +.search-input-box:focus-within { + border-color: var(--border-focus); + box-shadow: 0 0 0 4px var(--primary-dim); +} + +.search-icon { + font-size: 18px; + color: var(--text-muted); + margin-right: 12px; +} + +.search-input-box input { + flex: 1; + background: transparent; + border: none; + outline: none; + font-size: 17px; + color: var(--text-main); + padding: 8px 0; +} + +.clear-btn { + background: transparent; + border: none; + color: var(--text-dim); + font-size: 16px; + cursor: pointer; + padding: 4px 8px; + border-radius: 50%; +} + +.clear-btn:hover { + color: var(--text-main); +} + +.translate-action-btn { + margin-left: 8px; +} + +.hotkey-hints { + display: flex; + flex-wrap: wrap; + gap: 12px; + padding: 4px 8px; + font-size: 12px; + color: var(--text-dim); +} + +.hotkey-hints kbd { + background-color: var(--bg-surface-hover); + border: 1px solid var(--border-color); + border-radius: 4px; + padding: 1px 5px; + font-family: monospace; + font-size: 11px; + color: var(--text-muted); +} + + +/* Live Result Card */ +.result-card { + background-color: var(--bg-card); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + padding: 24px; + box-shadow: var(--shadow-md); + animation: fadeIn 0.25s ease-out; +} + +@keyframes fadeIn { + from { opacity: 0; transform: translateY(6px); } + to { opacity: 1; transform: translateY(0); } +} + +.result-header { + margin-bottom: 16px; + padding-bottom: 16px; + border-bottom: 1px solid var(--border-color); +} + +.term-title-row { + display: flex; + align-items: center; + flex-wrap: wrap; + gap: 12px; +} + +.res-term { + font-size: 28px; + font-weight: 800; + letter-spacing: -0.5px; + color: var(--text-main); +} + +.badge-pill { + padding: 3px 10px; + border-radius: var(--radius-full); + font-size: 13px; + font-weight: 600; +} + +.res-phonetic { + background-color: var(--primary-dim); + color: var(--primary); + font-family: monospace; +} + +.res-pos { + background-color: var(--bg-surface-hover); + color: var(--text-muted); +} + +.audio-btn { + background-color: var(--primary-dim); + border: 1px solid var(--primary); + color: var(--primary); + border-radius: var(--radius-full); + padding: 4px 12px; + font-size: 13px; + font-weight: 600; + cursor: pointer; + display: inline-flex; + align-items: center; + gap: 4px; + transition: var(--transition); +} + +.audio-btn:hover { + background-color: var(--primary); + color: #0f172a; +} + +.audio-xs-btn { + background-color: var(--primary-dim); + border: 1px solid var(--primary); + color: var(--primary); + border-radius: var(--radius-full); + padding: 2px 8px; + font-size: 11px; + font-weight: 600; + cursor: pointer; + display: inline-flex; + align-items: center; + gap: 4px; + transition: var(--transition); +} + +.audio-xs-btn:hover { + background-color: var(--primary); + color: #0f172a; +} + +.popup-sentence-audio-btn { + border-color: var(--border-color); + color: var(--text-muted); +} + +.popup-sentence-audio-btn:hover { + border-color: var(--primary); + color: var(--primary); + background-color: var(--primary-dim); +} + +.definition-box { + background-color: var(--bg-main); + border-left: 3px solid var(--primary); + padding: 12px 16px; + border-radius: 0 var(--radius-sm) var(--radius-sm) 0; + margin-bottom: 20px; +} + +.def-label { + font-size: 11px; + font-weight: 700; + text-transform: uppercase; + color: var(--primary); + letter-spacing: 0.5px; + margin-bottom: 4px; +} + +.def-text { + font-size: 14px; + color: var(--text-main); +} + +.card-edit-grid { + display: flex; + flex-direction: column; + gap: 16px; + margin-bottom: 24px; +} + +.input-styled { + width: 100%; + padding: 10px 14px; + background-color: var(--bg-input); + border: 1px solid var(--border-color); + border-radius: var(--radius-sm); + color: var(--text-main); + font-size: 14px; + outline: none; + transition: var(--transition); +} + +.input-styled:focus { + border-color: var(--border-focus); + box-shadow: 0 0 0 3px var(--primary-dim); +} + +.field-group label { + display: block; + font-size: 12px; + font-weight: 600; + color: var(--text-muted); + margin-bottom: 5px; +} + +.field-group .req { + color: var(--danger); +} + +.field-row { + display: flex; + gap: 16px; +} + +.flex-1 { flex: 1; } +.flex-2 { flex: 2; } + +.suggestions-chips { + display: flex; + flex-wrap: wrap; + gap: 6px; + margin-top: 6px; +} + +.suggestion-chip { + font-size: 12px; + background-color: var(--bg-surface-hover); + color: var(--text-muted); + padding: 2px 8px; + border-radius: var(--radius-full); + cursor: pointer; + transition: var(--transition); + border: 1px solid transparent; +} + +.suggestion-chip:hover { + border-color: var(--primary); + color: var(--primary); +} + +.quick-tags { + display: flex; + flex-wrap: wrap; + gap: 6px; + margin-top: 6px; +} + +.tag-chip { + font-size: 11px; + background-color: var(--tag-bg); + color: var(--tag-text); + padding: 2px 8px; + border-radius: var(--radius-full); + cursor: pointer; + user-select: none; + transition: var(--transition); +} + +.tag-chip:hover, .tag-chip.active { + background-color: var(--primary); + color: #0f172a; + font-weight: 600; +} + +.result-actions { + display: flex; + justify-content: flex-end; +} + + +/* Vocabulary Section */ +.vocabulary-section { + display: flex; + flex-direction: column; + gap: 16px; +} + +.section-header { + display: flex; + justify-content: space-between; + align-items: center; + flex-wrap: wrap; + gap: 12px; +} + +.section-title-wrap { + display: flex; + align-items: baseline; + gap: 8px; +} + +.section-title-wrap h3 { + font-size: 20px; + font-weight: 700; +} + +.cards-count-label { + font-size: 13px; + color: var(--text-dim); +} + +.list-controls { + display: flex; + align-items: center; + gap: 8px; +} + +.batch-mode-btn { + white-space: nowrap; + flex-shrink: 0; + height: 35px; + display: inline-flex; + align-items: center; + justify-content: center; +} + +.search-mini-box { + display: flex; + align-items: center; +} + +.search-mini-box input { + background-color: var(--bg-surface); + border: 1px solid var(--border-color); + border-radius: var(--radius-sm); + padding: 8px 12px; + color: var(--text-main); + font-size: 13px; + outline: none; + min-width: 260px; + height: 35px; + box-sizing: border-box; + transition: var(--transition); +} + +.search-mini-box input:focus { + border-color: var(--border-focus); +} + +/* Tags Filter Bar */ +.tags-filter-bar { + display: flex; + flex-wrap: wrap; + gap: 8px; +} + +.filter-chip { + background-color: var(--bg-surface); + border: 1px solid var(--border-color); + color: var(--text-muted); + font-size: 12px; + font-weight: 600; + padding: 4px 12px; + border-radius: var(--radius-full); + cursor: pointer; + transition: var(--transition); +} + +.filter-chip:hover { + border-color: var(--primary); + color: var(--primary); +} + +.filter-chip.active { + background-color: var(--primary); + border-color: var(--primary); + color: #0f172a; +} + +/* Cards List */ +.cards-list { + display: flex; + flex-direction: column; + gap: 12px; +} + +.vocab-card { + background-color: var(--bg-card); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + padding: 16px 20px; + box-shadow: var(--shadow-sm); + transition: var(--transition); + display: flex; + flex-direction: column; + gap: 10px; +} + +.vocab-card:hover { + border-color: var(--border-focus); + box-shadow: var(--shadow-md); +} + +.card-top { + display: flex; + justify-content: space-between; + align-items: flex-start; +} + +.card-term-group { + display: flex; + align-items: center; + gap: 10px; + flex-wrap: wrap; +} + +.card-term { + font-size: 18px; + font-weight: 700; + color: var(--text-main); +} + +.card-phonetic { + font-size: 13px; + color: var(--primary); + font-family: monospace; +} + +.card-pos { + font-size: 11px; + background-color: var(--bg-surface-hover); + color: var(--text-dim); + padding: 2px 6px; + border-radius: 4px; +} + +.card-actions { + display: flex; + gap: 6px; +} + +.card-translation { + font-size: 16px; + font-weight: 600; + color: var(--text-main); +} + +.card-context { + font-size: 14px; + color: var(--text-muted); + font-style: italic; + background-color: var(--bg-main); + padding: 8px 12px; + border-radius: var(--radius-sm); + border-left: 2px solid var(--border-color); +} + +.card-context mark { + background-color: var(--primary-dim); + color: var(--primary); + font-weight: 600; + padding: 0 4px; + border-radius: 2px; +} + +.card-bottom { + display: flex; + justify-content: space-between; + align-items: center; + flex-wrap: wrap; + gap: 8px; + font-size: 12px; + color: var(--text-dim); +} + +.card-tags { + display: flex; + gap: 6px; + flex-wrap: wrap; +} + +.card-tag { + background-color: var(--tag-bg); + color: var(--tag-text); + padding: 2px 8px; + border-radius: var(--radius-full); + font-size: 11px; +} + +.card-notes { + font-size: 12px; + color: #fbbf24; + display: flex; + align-items: center; + gap: 4px; +} + +/* Empty state */ +.empty-state { + text-align: center; + padding: 48px 24px; + background-color: var(--bg-surface); + border: 1px dashed var(--border-color); + border-radius: var(--radius-md); + color: var(--text-muted); +} + +.empty-icon { + font-size: 40px; + margin-bottom: 12px; +} + +.empty-state h4 { + font-size: 16px; + color: var(--text-main); + margin-bottom: 6px; +} + +.empty-state p { + font-size: 13px; + color: var(--text-dim); +} + + +/* Collections & Filters */ +.collections-filter-wrap, .tags-filter-wrap { + display: flex; + flex-direction: column; + gap: 6px; +} + +.filter-header-bar { + display: flex; + align-items: center; + justify-content: space-between; +} + +.filter-title { + font-size: 12px; + font-weight: 700; + color: var(--text-muted); + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.filter-chips-row { + display: flex; + flex-wrap: wrap; + gap: 6px; + align-items: center; +} + +.col-chip { + background-color: var(--bg-surface); + border: 1px solid var(--border-color); + color: var(--text-muted); + font-size: 12px; + font-weight: 600; + padding: 4px 12px; + border-radius: var(--radius-full); + cursor: pointer; + transition: var(--transition); +} + +.col-chip:hover { + border-color: #a855f7; + color: #c084fc; +} + +.col-chip.active { + background-color: #a855f7; + border-color: #a855f7; + color: #ffffff; + font-weight: 700; +} + +.card-collection-badge { + font-size: 11px; + font-weight: 600; + background-color: rgba(168, 85, 247, 0.15); + color: #c084fc; + border: 1px solid rgba(168, 85, 247, 0.3); + padding: 2px 8px; + border-radius: var(--radius-full); +} + +/* Batch Selection */ +.batch-mode-btn.active { + background-color: var(--primary-dim); + border-color: var(--primary); + color: var(--primary); +} + +.card-select-cell { + display: none; + margin-right: 12px; + align-items: center; +} + +.batch-active .card-select-cell { + display: flex; +} + +.card-select-checkbox { + width: 18px; + height: 18px; + cursor: pointer; + accent-color: var(--primary); +} + +.vocab-card.is-selected { + border-color: var(--border-focus); + background-color: rgba(56, 189, 248, 0.05); +} + +.batch-action-bar { + position: fixed; + bottom: 24px; + left: 50%; + transform: translateX(-50%); + width: calc(100% - 32px); + max-width: 760px; + background: rgba(30, 41, 59, 0.96); + backdrop-filter: blur(12px); + border: 1px solid var(--border-focus); + border-radius: var(--radius-lg); + box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.6), 0 0 15px rgba(56, 189, 248, 0.2); + padding: 12px 20px; + display: flex; + justify-content: space-between; + align-items: center; + z-index: 900; + animation: slideUp 0.22s ease-out; +} + +@keyframes slideUp { + from { transform: translate(-50%, 40px); opacity: 0; } + to { transform: translate(-50%, 0); opacity: 1; } +} + +.batch-left { + display: flex; + align-items: center; + gap: 10px; +} + +.batch-check-label { + display: flex; + align-items: center; + gap: 8px; + font-size: 14px; + font-weight: 600; + color: var(--text-main); + cursor: pointer; +} + +.batch-master-checkbox { + width: 18px; + height: 18px; + accent-color: var(--primary); + cursor: pointer; +} + +.batch-actions { + display: flex; + align-items: center; + gap: 8px; +} + +.btn-secondary { + background-color: var(--bg-surface-hover); + color: var(--text-main); + border: 1px solid var(--border-color); +} + +.btn-secondary:hover { + background-color: var(--border-color); +} + +.btn-danger { + background-color: var(--danger); + color: #ffffff; +} + +.btn-danger:hover { + background-color: var(--danger-hover); +} + +.btn-ghost { + background: transparent; + border: none; + color: var(--primary); + cursor: pointer; + font-size: 13px; + padding: 4px 8px; + border-radius: var(--radius-sm); +} + +.btn-ghost:hover { + background-color: var(--primary-dim); +} + +.btn-xs { + padding: 2px 8px; + font-size: 11px; +} + + +/* Duplicate Warning Banner */ +.duplicate-warning-box { + margin-top: 10px; + padding: 10px 14px; + background: rgba(234, 179, 8, 0.12); + border: 1px solid rgba(234, 179, 8, 0.35); + border-radius: var(--radius-md); + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + animation: fadeIn 0.2s ease-in-out; +} + +.dup-left { + display: flex; + align-items: center; + gap: 8px; + font-size: 13px; + color: #facc15; +} + +.dup-icon { + font-size: 16px; +} + + + /* 7. Bottom Sheet for Word Translation Popup on Mobile */ + .reader-word-popup { + position: fixed !important; + top: auto !important; + bottom: calc(58px + env(safe-area-inset-bottom, 0px)) !important; + left: 8px !important; + right: 8px !important; + width: auto !important; + max-width: none !important; + border-radius: 18px !important; + box-shadow: 0 -8px 30px rgba(0, 0, 0, 0.5) !important; + border: 1px solid var(--border-focus) !important; + background-color: var(--bg-surface) !important; + z-index: 10005 !important; + padding: 14px 16px !important; + animation: slideUpSheet 0.22s cubic-bezier(0.16, 1, 0.3, 1) !important; + } + + .reader-settings-panel { + position: fixed !important; + top: auto !important; + bottom: calc(58px + env(safe-area-inset-bottom, 0px)) !important; + left: 8px !important; + right: 8px !important; + width: auto !important; + max-height: calc(85dvh - 60px) !important; + overflow-y: auto !important; + -webkit-overflow-scrolling: touch !important; + border-radius: 20px !important; + box-shadow: 0 -8px 32px rgba(0, 0, 0, 0.55) !important; + border: 1px solid var(--border-focus) !important; + background-color: var(--bg-surface) !important; + color: var(--text-main) !important; + padding: 16px 18px 24px !important; + z-index: 10006 !important; + animation: slideUpSheet 0.22s cubic-bezier(0.16, 1, 0.3, 1) !important; + } + + @keyframes slideUpSheet { + from { + transform: translateY(100%); + opacity: 0; + } + to { + transform: translateY(0); + opacity: 1; + } + } + + +/* --- Responsive Mobile Overrides (max-width: 768px) --- */ +@media (max-width: 768px) { + /* 4. Dictionary & Search */ + .main-content { + padding: 14px 12px calc(76px + env(safe-area-inset-bottom, 0px)); + gap: 20px; + } + + .search-input-box { + padding: 6px 8px 6px 12px; + } + + .search-input-box input { + padding: 8px 0; + min-width: 0; + } + + .translate-action-btn { + padding: 8px 14px; + font-size: 14px; + white-space: nowrap; + } + + .hotkey-hints { + display: none !important; + } + + .lookup-card { + padding: 16px 14px; + } + + .lookup-header { + flex-direction: column; + align-items: flex-start; + gap: 8px; + } + + .meta-inputs-grid .field-row { + flex-direction: column; + gap: 12px; + } + + .result-actions .btn { + width: 100%; + justify-content: center; + min-height: 48px; + } + + .result-actions .btn-subtext { + display: none; + } + + /* Horizontal scrollable chips for collections and tags */ + .filter-chips-row { + flex-wrap: nowrap; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + padding-bottom: 6px; + scrollbar-width: none; + } + + .filter-chips-row::-webkit-scrollbar { + display: none; + } + + .col-chip, .filter-chip { + flex-shrink: 0; + } + + .list-controls { + width: 100%; + display: flex; + align-items: center; + gap: 8px; + margin-top: 10px; + } + + .section-header { + flex-direction: column; + align-items: stretch; + } + + .search-mini-box { + flex: 1; + min-width: 0; + } + + .search-mini-box input { + width: 100%; + min-width: 0; + } + + /* Cards */ + .vocab-card { + padding: 14px; + gap: 8px; + } + + .card-top { + gap: 8px; + } + + .card-term { + font-size: 17px; + } + + .card-actions .icon-btn { + min-width: 36px; + min-height: 36px; + display: flex; + align-items: center; + justify-content: center; + } + + .card-bottom { + font-size: 11px; + } + + +} diff --git a/app/static/css/grammar_cefr.css b/app/static/css/grammar_cefr.css new file mode 100644 index 0000000..5f701be --- /dev/null +++ b/app/static/css/grammar_cefr.css @@ -0,0 +1,1690 @@ +/* ========================================================================== + 6. CEFR Testing & Murphy Grammar Engine + ========================================================================== */ + +/* ========================================================================== + VIEW 4: CEFR Level Testing & Automated Gap Ingestion Styles (Task 15) + ========================================================================== */ + +.cefr-view { + max-width: 960px; + margin: 0 auto; + padding: 24px 16px 80px 16px; + width: 100%; +} + +.cefr-overview-container, +.cefr-quiz-container, +.cefr-summary-container { + width: 100%; +} + +.level-code { + font-weight: 800; +} + +.badge-pos { + font-size: 11px; + font-weight: 700; + text-transform: uppercase; + background: var(--bg-hover); + color: var(--text-muted); + padding: 3px 8px; + border-radius: var(--radius-sm); + border: 1px solid var(--border-color); +} + +.clue-icon { + font-size: 16px; +} + +.clue-label { + font-size: 13px; + color: var(--text-muted); + font-weight: 500; +} + +.cefr-feedback-box .fb-term { + font-size: 16px; + color: var(--text-main); + font-weight: 700; +} + +.cefr-feedback-box .fb-trans { + font-size: 14.5px; + color: var(--text-main); + font-weight: 500; +} + +.progress-labels-row .counts-text { + font-size: 12px; + color: var(--text-muted); +} + +.cefr-header { + display: flex; + justify-content: space-between; + align-items: flex-start; + gap: 16px; + margin-bottom: 24px; + flex-wrap: wrap; +} + +.cefr-header-actions { + display: flex; + align-items: center; + gap: 10px; +} + +/* Background Task Banner in CEFR Overview */ +.cefr-task-banner { + background: linear-gradient(135deg, rgba(59, 130, 246, 0.12), rgba(16, 185, 129, 0.08)); + border: 1px solid rgba(59, 130, 246, 0.3); + border-radius: var(--radius-md); + padding: 14px 18px; + margin-bottom: 24px; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); +} + +.task-banner-inner { + display: flex; + justify-content: space-between; + align-items: center; + gap: 16px; +} + +.task-banner-content { + flex: 1; +} + +.task-banner-title { + display: flex; + align-items: center; + gap: 8px; + font-size: 14px; + color: var(--text-main); + margin-bottom: 4px; +} + +.task-banner-counts { + font-size: 12px; + color: var(--text-muted); + font-weight: 500; + margin-left: auto; +} + +.task-banner-msg { + font-size: 13px; + color: var(--text-muted); +} + +/* Book Source Badge in Question Card & Feedback */ +.cefr-book-badge { + display: inline-flex; + align-items: center; + gap: 4px; + font-size: 12px; + font-weight: 600; + color: #3b82f6; + background: rgba(59, 130, 246, 0.1); + border: 1px solid rgba(59, 130, 246, 0.25); + padding: 2px 10px; + border-radius: var(--radius-sm); + max-width: 280px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.fb-source-citation { + font-size: 12.5px; + font-weight: 500; + color: #3b82f6; + background: rgba(59, 130, 246, 0.08); + border-left: 3px solid #3b82f6; + padding: 6px 10px; + border-radius: 0 var(--radius-sm) var(--radius-sm) 0; + margin: 8px 0; +} + +.cefr-title-wrap h2 { + font-size: 26px; + font-weight: 700; + margin-bottom: 8px; + display: flex; + align-items: center; + gap: 10px; +} + +.cefr-title-wrap .subtitle { + font-size: 15px; + color: var(--text-muted); + line-height: 1.5; +} + +/* Level Selection Grid */ +.cefr-levels-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); + gap: 20px; +} + +.cefr-level-card { + background-color: var(--bg-card); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + padding: 24px; + display: flex; + flex-direction: column; + gap: 18px; + box-shadow: var(--shadow-sm); + transition: transform 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease; +} + +.cefr-level-card:hover { + border-color: var(--primary); + transform: translateY(-2px); + box-shadow: var(--shadow-md); +} + +.level-card-header { + display: flex; + align-items: center; + gap: 14px; +} + +.level-pill { + display: inline-flex; + align-items: center; + justify-content: center; + padding: 6px 14px; + border-radius: 9999px; + font-weight: 800; + font-size: 15px; + letter-spacing: 0.5px; +} + +.level-badge-a1 { + background: rgba(16, 185, 129, 0.15); + color: #10b981; + border: 1px solid rgba(16, 185, 129, 0.35); +} + +.level-badge-a2 { + background: rgba(56, 189, 248, 0.15); + color: #38bdf8; + border: 1px solid rgba(56, 189, 248, 0.35); +} + +.level-badge-b1 { + background: rgba(129, 140, 248, 0.15); + color: #818cf8; + border: 1px solid rgba(129, 140, 248, 0.35); +} + +.level-badge-b2 { + background: rgba(245, 158, 11, 0.15); + color: #fbbf24; + border: 1px solid rgba(245, 158, 11, 0.35); +} + +.level-header-text { + flex: 1; +} + +.level-title { + font-size: 17px; + font-weight: 600; + margin: 0 0 2px 0; +} + +.level-meta-sub { + font-size: 13px; + color: var(--text-muted); +} + +/* Progress bar inside card */ +.level-card-progress { + display: flex; + flex-direction: column; + gap: 6px; +} + +.progress-bar-wrap { + height: 8px; + background-color: var(--bg-hover); + border-radius: 9999px; + overflow: hidden; +} + +.progress-bar-fill { + height: 100%; + border-radius: 9999px; + transition: width 0.4s ease; +} + +.progress-bar-fill.level-badge-a1 { background-color: #10b981; } +.progress-bar-fill.level-badge-a2 { background-color: #38bdf8; } +.progress-bar-fill.level-badge-b1 { background-color: #818cf8; } +.progress-bar-fill.level-badge-b2 { background-color: #f59e0b; } + +.progress-labels-row { + display: flex; + justify-content: space-between; + font-size: 12px; + color: var(--text-muted); +} + +.progress-labels-row .pct-text { + font-weight: 600; + color: var(--text-main); +} + +/* Mini metrics */ +.level-card-metrics { + display: flex; + justify-content: space-between; + background-color: var(--bg-hover); + border-radius: var(--radius-md); + padding: 10px 12px; +} + +.mini-metric { + display: flex; + flex-direction: column; + align-items: center; + gap: 2px; +} + +.mini-metric .m-val { + font-size: 14px; + font-weight: 700; +} + +.mini-metric .m-lbl { + font-size: 11px; + color: var(--text-muted); +} + +.level-card-actions { + display: flex; + flex-direction: column; + gap: 8px; + margin-top: auto; +} + +/* Quiz Topbar */ +.cefr-quiz-topbar { + display: flex; + align-items: center; + justify-content: space-between; + gap: 16px; + margin-bottom: 24px; + padding: 12px 18px; + background-color: var(--bg-card); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); +} + +.cefr-quiz-topbar-left { + display: flex; + align-items: center; + gap: 12px; +} + +.cefr-quiz-topbar-center { + display: flex; + align-items: center; + gap: 14px; + flex: 1; + max-width: 380px; +} + +/* Cloze Card */ +.cefr-quiz-card-wrapper { + display: flex; + flex-direction: column; + gap: 20px; +} + +.cefr-cloze-card { + background-color: var(--bg-card); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + padding: 32px 28px; + box-shadow: var(--shadow-md); + display: flex; + flex-direction: column; + gap: 20px; + animation: fadeIn 0.25s ease-out; +} + +.cefr-cloze-header { + display: flex; + align-items: center; + justify-content: space-between; +} + +.cefr-mode-tag { + font-size: 13px; + font-weight: 600; + color: var(--primary); + background: rgba(56, 189, 248, 0.1); + padding: 4px 10px; + border-radius: var(--radius-sm); +} + +/* Sentence & Blank */ +.cefr-sentence-wrap { + padding: 18px 0; +} + +.cefr-sentence-text { + font-size: 22px; + font-weight: 500; + line-height: 1.6; + color: var(--text-main); + margin: 0; +} + +.cefr-blank { + display: inline-block; + min-width: 90px; + text-align: center; + background: rgba(56, 189, 248, 0.12); + border-bottom: 2px dashed var(--primary); + padding: 2px 12px; + border-radius: 4px; + font-weight: 700; + color: var(--primary); + transition: all 0.25s ease; +} + +.cefr-blank.blank-correct { + background: rgba(16, 185, 129, 0.2); + border-bottom: 2px solid #10b981; + color: #10b981; +} + +.cefr-blank.blank-wrong-revealed { + background: rgba(239, 68, 68, 0.2); + border-bottom: 2px solid #ef4444; + color: #f87171; +} + +/* Clue Box */ +.cefr-clue-box { + display: flex; + align-items: center; + gap: 8px; + background-color: var(--bg-hover); + padding: 10px 14px; + border-radius: var(--radius-md); + font-size: 14px; + color: var(--text-muted); +} + +.cefr-clue-box .clue-term { + color: var(--text-main); + font-size: 15px; +} + +/* Options Grid: 2x2 */ +.cefr-options-grid { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 12px; + margin-top: 6px; +} + +.cefr-opt-btn { + display: flex; + align-items: center; + justify-content: flex-start; + gap: 12px; + background-color: var(--bg-surface); + border: 1.5px solid var(--border-color); + border-radius: var(--radius-md); + padding: 16px 20px; + min-height: 56px; + color: var(--text-main); + font-size: 17px; + font-weight: 600; + cursor: pointer; + transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); + outline: none; + user-select: none; + -webkit-tap-highlight-color: transparent; +} + +.cefr-opt-btn:hover:not(:disabled) { + border-color: var(--primary); + background-color: var(--bg-hover); + transform: translateY(-2px); + box-shadow: 0 4px 12px rgba(56, 189, 248, 0.15); +} + +.cefr-opt-btn:active:not(:disabled) { + transform: scale(0.98); +} + +.cefr-opt-btn .opt-num { + font-size: 13px; + color: var(--text-muted); + font-weight: 500; +} + +.cefr-opt-btn .opt-text { + flex: 1; + text-align: left; +} + +/* Option States */ +.cefr-opt-btn.opt-correct { + background-color: #10b981 !important; + border-color: #10b981 !important; + color: #fff !important; + box-shadow: 0 0 16px rgba(16, 185, 129, 0.4); +} + +.cefr-opt-btn.opt-correct .opt-num { + color: rgba(255, 255, 255, 0.8) !important; +} + +.cefr-opt-btn.opt-wrong { + background-color: #ef4444 !important; + border-color: #ef4444 !important; + color: #fff !important; + box-shadow: 0 0 16px rgba(239, 68, 68, 0.4); +} + +.cefr-opt-btn.opt-wrong .opt-num { + color: rgba(255, 255, 255, 0.8) !important; +} + +.cefr-opt-btn.opt-correct-revealed { + border-color: #10b981 !important; + background-color: rgba(16, 185, 129, 0.15) !important; + color: #10b981 !important; + animation: pulseBorder 1.5s infinite ease-in-out; +} + +@keyframes pulseBorder { + 0%, 100% { box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.5); } + 50% { box-shadow: 0 0 0 6px rgba(16, 185, 129, 0); } +} + +/* Feedback Box */ +.cefr-feedback-box { + border-radius: var(--radius-md); + padding: 18px 20px; + display: flex; + flex-direction: column; + gap: 8px; + animation: fadeIn 0.25s ease-out; +} + +.cefr-feedback-box.feedback-correct { + background: rgba(16, 185, 129, 0.12); + border: 1px solid rgba(16, 185, 129, 0.35); +} + +.cefr-feedback-box.feedback-wrong { + background: rgba(239, 68, 68, 0.12); + border: 1px solid rgba(239, 68, 68, 0.35); +} + +.cefr-feedback-box .fb-title { + font-size: 16px; + font-weight: 700; +} + +.cefr-feedback-box.feedback-correct .fb-title { + color: #10b981; +} + +.cefr-feedback-box.feedback-wrong .fb-title { + color: #ef4444; +} + +.cefr-feedback-box .fb-meta { + display: flex; + align-items: center; + gap: 10px; + font-size: 15px; +} + +.cefr-feedback-box .fb-explanation { + margin: 4px 0 0 0; + font-size: 14px; + line-height: 1.5; + color: var(--text-main); +} + +/* Gap Ingestion Badge inside mistake feedback */ +.cefr-gap-ingested-badge { + display: flex; + align-items: center; + gap: 10px; + background: rgba(239, 68, 68, 0.15); + border: 1px solid rgba(239, 68, 68, 0.3); + border-radius: var(--radius-md); + padding: 10px 14px; + margin-top: 6px; + font-size: 13px; + line-height: 1.4; + color: var(--text-main); +} + +.cefr-gap-ingested-badge .badge-icon { + font-size: 18px; +} + +/* Dual Gap Ingestion (Correct + Chosen Mistake) */ +.cefr-dual-ingested-box { + background: rgba(239, 68, 68, 0.1); + border: 1px solid rgba(239, 68, 68, 0.25); + border-radius: var(--radius-md); + padding: 12px 14px; + margin-top: 10px; + animation: fadeIn 0.2s ease-out; +} + +.dual-ingested-header { + display: flex; + align-items: center; + gap: 8px; + font-size: 13px; + color: var(--text-main); + margin-bottom: 8px; +} + +.dual-ingested-chips { + display: flex; + flex-wrap: wrap; + gap: 8px; +} + +.ingested-chip { + background: var(--bg-card); + border: 1px solid var(--border-color); + border-radius: var(--radius-sm); + padding: 6px 10px; + font-size: 12.5px; + color: var(--text-main); + display: flex; + align-items: center; + gap: 5px; +} + +.ingested-chip.chip-target { + border-left: 3px solid #10b981; +} + +.ingested-chip.chip-chosen { + border-left: 3px solid #ef4444; +} + +.ingested-chip .chip-label { + font-size: 10.5px; + font-weight: 700; + text-transform: uppercase; + color: var(--text-muted); +} + +/* Words Breakdown (All 4 Options with In-library/Add buttons) */ +.cefr-words-breakdown { + margin-top: 16px; + padding-top: 14px; + border-top: 1px solid var(--border-color); + text-align: left; +} + +.words-breakdown-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 10px; + flex-wrap: wrap; + gap: 6px; +} + +.wb-title { + font-size: 13px; + font-weight: 700; + color: var(--text-main); + display: flex; + align-items: center; + gap: 6px; +} + +.wb-hint { + font-size: 11.5px; + color: var(--text-muted); +} + +.words-breakdown-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); + gap: 8px; +} + +.word-breakdown-card { + background: var(--bg-surface); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + padding: 9px 11px; + display: flex; + flex-direction: column; + gap: 4px; + transition: all 0.15s ease; +} + +.word-breakdown-card.is-target { + border-color: rgba(16, 185, 129, 0.4); + background: rgba(16, 185, 129, 0.05); +} + +.word-breakdown-card.is-chosen-mistake { + border-color: rgba(239, 68, 68, 0.4); + background: rgba(239, 68, 68, 0.05); +} + +.wb-card-top { + display: flex; + justify-content: space-between; + align-items: baseline; + gap: 6px; +} + +.wb-term { + font-size: 14px; + color: var(--text-main); + font-weight: 700; +} + +.wb-pos { + font-size: 10px; + font-weight: 700; + color: var(--text-muted); + text-transform: uppercase; +} + +.wb-trans { + font-size: 12px; + color: var(--text-muted); + line-height: 1.35; + flex-grow: 1; +} + +.wb-action-wrap { + margin-top: 6px; +} + +.wb-badge { + font-size: 11px; + font-weight: 700; + padding: 3px 6px; + border-radius: 4px; + display: inline-flex; + align-items: center; + gap: 4px; +} + +.wb-badge.badge-auto-added { + color: #ef4444; + background: rgba(239, 68, 68, 0.12); +} + +.wb-badge.badge-in-lib, +.wb-badge.badge-just-added { + color: #10b981; + background: rgba(16, 185, 129, 0.12); +} + +.btn-add-option-word { + width: 100%; + font-size: 11px; + padding: 4px 8px; + border-radius: var(--radius-sm); +} + +/* Next Button Bar */ +.cefr-next-bar { + margin-top: 10px; + animation: fadeIn 0.2s ease-out; +} + +/* Summary Screen */ +.cefr-summary-container { + max-width: 680px; + margin: 40px auto; +} + +.cefr-summary-card { + background-color: var(--bg-card); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + padding: 44px 32px; + text-align: center; + display: flex; + flex-direction: column; + align-items: center; + gap: 24px; + box-shadow: var(--shadow-lg); + animation: fadeIn 0.3s ease-out; +} + +.cefr-loading-spinner { + display: flex; + align-items: center; + justify-content: center; + gap: 12px; + padding: 48px; + color: var(--text-muted); +} + +/* Mobile Responsive */ +@media (max-width: 640px) { + .cefr-sentence-text { + font-size: 18px; + } + + .cefr-options-grid { + grid-template-columns: 1fr; + } + + .cefr-opt-btn { + min-height: 52px; + padding: 14px 16px; + } + + .cefr-cloze-card { + padding: 20px 16px; + } +} + + +/* ========================================================================== + Task 16: Murphy Grammar Engine & Handwritten Journaling Styles + ========================================================================== */ + +.grammar-view { + padding: 24px 20px 80px 20px; + max-width: 1100px; + margin: 0 auto; + animation: fadeIn 0.2s ease-out; +} + +.grammar-header { + display: flex; + justify-content: space-between; + align-items: flex-start; + gap: 20px; + margin-bottom: 24px; + flex-wrap: wrap; +} + +.grammar-title-wrap h2 { + font-size: 26px; + font-weight: 700; + color: var(--text-main); + margin-bottom: 8px; + letter-spacing: -0.02em; +} + +.grammar-title-wrap .subtitle { + font-size: 14px; + color: var(--text-muted); + max-width: 720px; + line-height: 1.5; +} + +.grammar-top-stats { + display: flex; + gap: 12px; +} + +.grammar-stat-chip { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + background: var(--bg-card); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + padding: 8px 16px; + min-width: 80px; +} + +.grammar-stat-chip .stat-num { + font-size: 20px; + font-weight: 800; + color: var(--color-primary); +} + +.grammar-stat-chip .stat-lbl { + font-size: 11px; + color: var(--text-muted); + font-weight: 600; + text-transform: uppercase; +} + +/* Filter Bar */ +.grammar-filter-bar { + display: flex; + gap: 8px; + overflow-x: auto; + padding-bottom: 8px; + margin-bottom: 24px; + -webkit-overflow-scrolling: touch; +} + +.grammar-filter-pill { + padding: 6px 14px; + border-radius: var(--radius-full); + font-size: 13px; + font-weight: 600; + background: var(--bg-surface); + border: 1px solid var(--border-color); + color: var(--text-muted); + cursor: pointer; + white-space: nowrap; + transition: all 0.15s ease; +} + +.grammar-filter-pill:hover { + border-color: var(--color-primary); + color: var(--text-main); +} + +.grammar-filter-pill.active { + background: var(--color-primary); + border-color: var(--color-primary); + color: #ffffff; +} + +/* Units Grid */ +.grammar-units-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); + gap: 18px; +} + +.grammar-unit-card { + background: var(--bg-card); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + padding: 20px; + display: flex; + flex-direction: column; + cursor: pointer; + transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease; + box-shadow: var(--shadow-sm); +} + +.grammar-unit-card:hover { + transform: translateY(-2px); + box-shadow: var(--shadow-md); + border-color: var(--color-primary); +} + +.grammar-unit-card.is-completed { + border-left: 4px solid #10b981; +} + +.grammar-card-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 10px; +} + +.grammar-unit-number { + font-size: 12px; + font-weight: 700; + text-transform: uppercase; + color: var(--text-muted); + letter-spacing: 0.04em; +} + +.grammar-level-pill { + font-size: 11px; + font-weight: 700; + padding: 3px 8px; + border-radius: 6px; + text-transform: uppercase; + letter-spacing: 0.05em; +} + +.grammar-level-pill.badge-a1 { + background: rgba(239, 68, 68, 0.15); + color: #ef4444; + border: 1px solid rgba(239, 68, 68, 0.25); +} + +.grammar-level-pill.badge-b1 { + background: rgba(59, 130, 246, 0.15); + color: #3b82f6; + border: 1px solid rgba(59, 130, 246, 0.25); +} + +.grammar-card-title { + font-size: 17px; + font-weight: 700; + color: var(--text-main); + margin-bottom: 6px; + line-height: 1.35; +} + +.grammar-card-sub { + font-size: 13px; + color: var(--text-muted); + line-height: 1.45; + margin-bottom: 14px; + flex-grow: 1; +} + +.grammar-card-meta { + margin-bottom: 14px; +} + +.grammar-card-cat { + font-size: 12px; + font-weight: 600; + color: var(--text-muted); + display: inline-flex; + align-items: center; + gap: 4px; +} + +.grammar-card-footer { + display: flex; + justify-content: space-between; + align-items: center; + padding-top: 12px; + border-top: 1px solid var(--border-color); +} + +.grammar-badges { + display: flex; + align-items: center; + gap: 6px; + flex-wrap: wrap; +} + +.badge-status-completed { + font-size: 11px; + font-weight: 700; + color: #10b981; + background: rgba(16, 185, 129, 0.12); + padding: 2px 7px; + border-radius: 4px; + display: inline-flex; + align-items: center; + gap: 3px; +} + +.badge-status-handwritten { + font-size: 11px; + font-weight: 700; + color: #8b5cf6; + background: rgba(139, 92, 246, 0.12); + padding: 2px 7px; + border-radius: 4px; + display: inline-flex; + align-items: center; + gap: 3px; +} + +.badge-status-new { + font-size: 11px; + font-weight: 600; + color: var(--text-muted); + background: var(--bg-surface); + padding: 2px 7px; + border-radius: 4px; +} + +/* ========================================================================== + Grammar Lesson Screen (Theory & Deep Work Mode) + ========================================================================== */ + +.grammar-lesson-container { + max-width: 860px; + margin: 0 auto; + animation: fadeIn 0.2s ease-out; +} + +.grammar-lesson-topbar { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 24px; + gap: 16px; + flex-wrap: wrap; + background: var(--bg-card); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + padding: 12px 18px; +} + +.grammar-topbar-left { + display: flex; + align-items: center; + gap: 12px; +} + +.grammar-lesson-badges { + display: flex; + align-items: center; + gap: 8px; +} + +.grammar-unit-pill { + font-size: 12px; + font-weight: 700; + text-transform: uppercase; + background: var(--bg-surface); + border: 1px solid var(--border-color); + padding: 3px 8px; + border-radius: 6px; + color: var(--text-main); +} + +.grammar-tab-switch { + display: inline-flex; + background: var(--bg-input); + padding: 3px; + border-radius: var(--radius-md); + border: 1px solid var(--border-color); +} + +.grammar-tab-switch .tab-btn { + padding: 6px 14px; + font-size: 13px; + font-weight: 600; + border: none; + background: transparent; + color: var(--text-muted); + border-radius: calc(var(--radius-md) - 2px); + cursor: pointer; + transition: all 0.15s ease; +} + +.grammar-tab-switch .tab-btn.active { + background: var(--bg-card); + color: var(--text-main); + box-shadow: var(--shadow-sm); +} + +.grammar-cat-label { + font-size: 12px; + font-weight: 600; + color: var(--text-muted); +} + +.grammar-theory-header { + margin-bottom: 24px; +} + +.lesson-main-title { + font-size: 26px; + font-weight: 800; + color: var(--text-main); + margin-bottom: 6px; + letter-spacing: -0.02em; +} + +.lesson-sub-title { + font-size: 15px; + color: var(--text-muted); + line-height: 1.5; +} + +.grammar-section-block { + margin-bottom: 28px; +} + +.section-title { + font-size: 16px; + font-weight: 700; + color: var(--text-main); + margin-bottom: 12px; + display: flex; + align-items: center; + gap: 8px; +} + +/* Contrast Cards (Situation A vs Situation B) */ +.grammar-contrasts-list { + display: flex; + flex-direction: column; + gap: 16px; +} + +.grammar-contrast-card { + background: var(--bg-card); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + padding: 20px; + display: grid; + grid-template-columns: 1fr auto 1fr; + gap: 16px; + box-shadow: var(--shadow-sm); +} + +.contrast-col { + display: flex; + flex-direction: column; + gap: 8px; +} + +.contrast-header { + font-size: 13px; + font-weight: 700; + color: var(--text-main); + display: flex; + align-items: center; + gap: 8px; +} + +.contrast-pill { + font-size: 10px; + font-weight: 800; + padding: 2px 6px; + border-radius: 4px; + text-transform: uppercase; +} + +.contrast-pill.a { + background: rgba(59, 130, 246, 0.15); + color: #3b82f6; +} + +.contrast-pill.b { + background: rgba(16, 185, 129, 0.15); + color: #10b981; +} + +.contrast-example { + font-size: 15px; + font-weight: 600; + color: var(--text-main); + background: var(--bg-input); + padding: 10px 12px; + border-radius: var(--radius-md); + border-left: 3px solid var(--color-primary); + line-height: 1.4; +} + +.contrast-trans { + font-size: 13px; + color: var(--text-muted); + line-height: 1.4; + font-style: italic; +} + +.contrast-divider { + display: flex; + align-items: center; + justify-content: center; +} + +.vs-badge { + background: var(--bg-surface-hover); + color: var(--text-muted); + font-weight: 800; + font-size: 11px; + width: 32px; + height: 32px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + border: 1px solid var(--border-color); +} + +.contrast-key-diff { + grid-column: 1 / -1; + background: rgba(245, 158, 11, 0.1); + border: 1px solid rgba(245, 158, 11, 0.25); + border-radius: var(--radius-md); + padding: 10px 14px; + font-size: 13px; + line-height: 1.5; + color: var(--text-main); + margin-top: 6px; +} + +/* Golden Formula Card */ +.grammar-golden-formula-card { + background: linear-gradient(135deg, rgba(99, 102, 241, 0.08), rgba(168, 85, 247, 0.08)); + border: 1px solid rgba(99, 102, 241, 0.3); + border-radius: var(--radius-lg); + padding: 22px; + position: relative; + box-shadow: var(--shadow-sm); +} + +.notebook-pen-icon { + position: absolute; + top: 18px; + right: 20px; + font-size: 24px; + opacity: 0.6; +} + +.formula-instructions { + font-size: 13px; + font-weight: 600; + color: var(--text-muted); + margin-bottom: 10px; +} + +.golden-formula-code { + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; + font-size: 16px; + font-weight: 700; + color: var(--text-main); + background: var(--bg-card); + padding: 14px 18px; + border-radius: var(--radius-md); + border: 1px dashed rgba(99, 102, 241, 0.4); + line-height: 1.5; + white-space: pre-line; +} + +/* Journaling Card & Checkbox */ +.grammar-journaling-card { + background: var(--bg-card); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + padding: 20px; + box-shadow: var(--shadow-sm); +} + +.journaling-prompt-box { + margin-bottom: 16px; +} + +.journaling-prompt-text { + font-size: 14px; + line-height: 1.55; + color: var(--text-main); +} + +.journaling-action-box { + border-top: 1px solid var(--border-color); + padding-top: 16px; +} + +.handwritten-checkbox-label { + display: flex; + align-items: flex-start; + gap: 14px; + cursor: pointer; + user-select: none; + min-height: 48px; + padding: 8px 12px; + border-radius: var(--radius-md); + background: var(--bg-surface); + border: 1px solid var(--border-color); + transition: all 0.15s ease; +} + +.handwritten-checkbox-label:hover { + border-color: #8b5cf6; + background: rgba(139, 92, 246, 0.05); +} + +.handwritten-checkbox { + position: absolute; + opacity: 0; + width: 0; + height: 0; +} + +.custom-chk { + width: 22px; + height: 22px; + border: 2px solid var(--border-color); + border-radius: 6px; + background: var(--bg-card); + flex-shrink: 0; + display: flex; + align-items: center; + justify-content: center; + margin-top: 2px; + transition: all 0.15s ease; +} + +.handwritten-checkbox:checked + .custom-chk { + background: #8b5cf6; + border-color: #8b5cf6; +} + +.handwritten-checkbox:checked + .custom-chk::after { + content: "✓"; + color: #ffffff; + font-size: 14px; + font-weight: 800; +} + +.handwritten-label-text { + display: flex; + flex-direction: column; + gap: 3px; +} + +.handwritten-label-text strong { + font-size: 14px; + color: var(--text-main); +} + +.handwritten-label-text small { + font-size: 12px; + color: var(--text-muted); + line-height: 1.35; +} + +.grammar-theory-footer { + display: flex; + justify-content: flex-end; + margin-top: 28px; +} + +/* ========================================================================== + Cloze Tap Practice (5 Micro-Exercises) + ========================================================================== */ + +.grammar-practice-card-wrap { + background: var(--bg-card); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + padding: 32px 28px; + box-shadow: var(--shadow-md); + display: flex; + flex-direction: column; + gap: 24px; +} + +.practice-header-bar { + display: flex; + justify-content: space-between; + align-items: center; +} + +.practice-step-text { + font-size: 13px; + font-weight: 700; + color: var(--text-muted); + text-transform: uppercase; + letter-spacing: 0.05em; +} + +.practice-dots { + display: flex; + gap: 8px; +} + +.practice-dots .dot { + width: 10px; + height: 10px; + border-radius: 50%; + background: var(--border-color); + transition: all 0.2s ease; +} + +.practice-dots .dot-active { + background: var(--color-primary); + transform: scale(1.2); +} + +.practice-dots .dot-done { + background: #10b981; +} + +.grammar-cloze-box { + background: var(--bg-input); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + padding: 24px 20px; + text-align: center; +} + +.cloze-sentence-display { + font-size: 20px; + font-weight: 600; + color: var(--text-main); + line-height: 1.6; + margin-bottom: 12px; +} + +.cloze-blank { + display: inline-block; + color: var(--color-primary); + border-bottom: 2px dashed var(--color-primary); + padding: 0 8px; + font-weight: 700; + min-width: 80px; + transition: all 0.2s ease; +} + +.cloze-blank.blank-correct { + color: #10b981; + border-bottom-color: #10b981; +} + +.cloze-blank.blank-wrong { + color: #ef4444; + border-bottom-color: #ef4444; +} + +.cloze-clue-display { + font-size: 14px; + color: var(--text-muted); + font-style: italic; +} + +.grammar-tap-options { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 12px; +} + +.grammar-opt-btn { + min-height: 52px; + padding: 14px 18px; + border-radius: var(--radius-md); + font-size: 15px; + font-weight: 600; + text-align: left; + display: flex; + align-items: center; + gap: 12px; + background: var(--bg-surface); + border: 1.5px solid var(--border-color); + color: var(--text-main); + cursor: pointer; + transition: all 0.15s ease; +} + +.grammar-opt-btn .opt-num { + font-size: 11px; + font-weight: 800; + width: 22px; + height: 22px; + border-radius: 50%; + background: var(--bg-surface-hover); + color: var(--text-muted); + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; +} + +.grammar-opt-btn:hover:not(:disabled) { + border-color: var(--color-primary); + background: var(--bg-surface-hover); +} + +.grammar-opt-btn.btn-correct { + background: rgba(16, 185, 129, 0.15) !important; + border-color: #10b981 !important; + color: #10b981 !important; +} + +.grammar-opt-btn.btn-wrong { + background: rgba(239, 68, 68, 0.15) !important; + border-color: #ef4444 !important; + color: #ef4444 !important; +} + +.grammar-feedback-box { + border-radius: var(--radius-md); + padding: 16px 18px; + animation: fadeIn 0.2s ease-out; +} + +.grammar-feedback-box.feedback-correct { + background: rgba(16, 185, 129, 0.12); + border: 1px solid rgba(16, 185, 129, 0.3); +} + +.grammar-feedback-box.feedback-wrong { + background: rgba(239, 68, 68, 0.12); + border: 1px solid rgba(239, 68, 68, 0.3); +} + +.grammar-feedback-box .feedback-title { + font-size: 15px; + font-weight: 700; + margin-bottom: 6px; + display: flex; + align-items: center; + gap: 8px; +} + +.feedback-correct .feedback-title { + color: #10b981; +} + +.feedback-wrong .feedback-title { + color: #ef4444; +} + +.grammar-feedback-box .feedback-text { + font-size: 13.5px; + color: var(--text-main); + line-height: 1.5; +} + +.feedback-srs-ingested { + margin-top: 10px; + padding-top: 10px; + border-top: 1px solid rgba(239, 68, 68, 0.2); + font-size: 12.5px; + font-weight: 600; + color: #ef4444; + display: flex; + align-items: center; + gap: 6px; +} + +/* ========================================================================== + Grammar Summary Card + ========================================================================== */ + +.grammar-summary-card { + background-color: var(--bg-card); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + padding: 44px 32px; + text-align: center; + display: flex; + flex-direction: column; + align-items: center; + gap: 20px; + box-shadow: var(--shadow-lg); + animation: fadeIn 0.3s ease-out; + max-width: 680px; + margin: 0 auto; +} + +.summary-score-large { + font-size: 48px; + font-weight: 900; + color: var(--color-primary); + line-height: 1; +} + +.summary-reminder-box { + display: flex; + align-items: center; + gap: 12px; + background: rgba(139, 92, 246, 0.1); + border: 1px solid rgba(139, 92, 246, 0.25); + border-radius: var(--radius-md); + padding: 12px 18px; + text-align: left; + max-width: 500px; +} + +.summary-reminder-box .reminder-icon { + font-size: 24px; + flex-shrink: 0; +} + +.summary-reminder-box .reminder-text { + display: flex; + flex-direction: column; + gap: 2px; + font-size: 13px; + line-height: 1.4; + color: var(--text-main); +} + +/* Mobile Responsive */ +@media (max-width: 640px) { + .grammar-view { + padding: 16px 12px 90px 12px; + } + + .grammar-contrast-card { + grid-template-columns: 1fr; + } + + .contrast-divider { + margin: 4px 0; + } + + .grammar-tap-options { + grid-template-columns: 1fr; + } + + .grammar-opt-btn { + min-height: 48px; + padding: 12px 14px; + } + + .cloze-sentence-display { + font-size: 17px; + } + + .grammar-lesson-topbar { + flex-direction: column; + align-items: stretch; + } + + .grammar-tab-switch { + width: 100%; + display: flex; + } + + .grammar-tab-switch .tab-btn { + flex: 1; + text-align: center; + } +} + diff --git a/app/static/css/lesson.css b/app/static/css/lesson.css new file mode 100644 index 0000000..8e4760f --- /dev/null +++ b/app/static/css/lesson.css @@ -0,0 +1,1519 @@ +/* ========================================================================== + 7. Comprehensive Lesson Configurator & Session Runner + ========================================================================== */ + +/* ======================================================================= + Comprehensive Lesson Configurator & Session Runner (Beta) + ======================================================================= */ + +.lesson-view, .lesson-runner-view { + padding: 24px 20px; + max-width: 960px; + margin: 0 auto; + width: 100%; + box-sizing: border-box; +} + +@media (max-width: 768px) { + .lesson-view, .lesson-runner-view { + padding: 12px 10px; + padding-bottom: calc(75px + var(--sab)); + } +} + +.lesson-configurator-container { + display: flex; + flex-direction: column; + gap: 20px; +} + +/* Header Bar */ +.lesson-header-bar { + display: flex; + justify-content: space-between; + align-items: flex-start; + gap: 16px; + flex-wrap: wrap; + border-bottom: 1px solid var(--border-color); + padding-bottom: 18px; +} + +.lesson-title-wrap h2 { + font-size: 24px; + font-weight: 800; + margin: 0 0 6px 0; + display: flex; + align-items: center; + gap: 10px; + flex-wrap: wrap; + color: var(--text-main); +} + +.lesson-subtitle { + margin: 0; + font-size: 14px; + color: var(--text-muted); +} + +.badge-beta { + background: linear-gradient(135deg, #8b5cf6, #38bdf8); + color: #fff; + font-size: 11px; + font-weight: 700; + padding: 2px 8px; + border-radius: var(--radius-full); + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.badge-ai { + background: rgba(139, 92, 246, 0.15); + color: #8b5cf6; + border: 1px solid rgba(139, 92, 246, 0.35); + font-size: 12px; + font-weight: 600; + padding: 4px 10px; + border-radius: var(--radius-sm); +} + +.lesson-header-actions { + display: flex; + gap: 10px; + align-items: center; + flex-wrap: wrap; +} + +.pulse-btn { + box-shadow: 0 0 0 0 rgba(56, 189, 248, 0.7); + animation: btnPulse 2s infinite; +} + +@keyframes btnPulse { + 0% { transform: scale(1); box-shadow: 0 0 0 0 rgba(56, 189, 248, 0.4); } + 70% { transform: scale(1.02); box-shadow: 0 0 0 10px rgba(56, 189, 248, 0); } + 100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(56, 189, 248, 0); } +} + +@media (max-width: 768px) { + .lesson-header-bar { + flex-direction: column; + align-items: stretch; + gap: 14px; + padding-bottom: 14px; + } + .lesson-title-wrap h2 { + font-size: 20px; + } + .lesson-subtitle { + font-size: 13px; + } + .lesson-header-actions { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 8px; + width: 100%; + } + .lesson-header-actions #lesson-start-btn { + grid-column: span 2; + order: -1; + padding: 14px; + font-size: 16px; + font-weight: 800; + } +} + +/* Presets Chips Bar */ +.lesson-presets-section { + background: var(--bg-card); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + padding: 16px 20px; +} + +.presets-section-title { + font-size: 14px; + font-weight: 700; + margin-bottom: 12px; + color: var(--text-main); +} + +.lesson-presets-chips-row { + display: flex; + gap: 10px; + overflow-x: auto; + padding-bottom: 6px; + -webkit-overflow-scrolling: touch; + scrollbar-width: none; +} +.lesson-presets-chips-row::-webkit-scrollbar { + display: none; +} + +.lesson-preset-chip { + display: inline-flex; + align-items: center; + gap: 8px; + padding: 9px 16px; + background: var(--bg-main); + border: 1.5px solid var(--border-color); + border-radius: var(--radius-full); + font-size: 13.5px; + font-weight: 600; + color: var(--text-main); + cursor: pointer; + white-space: nowrap; + transition: var(--transition); + user-select: none; + -webkit-tap-highlight-color: transparent; +} + +.lesson-preset-chip:hover { + border-color: var(--primary); + background: var(--bg-surface-hover); +} + +.lesson-preset-chip.active { + background: var(--primary); + color: #fff; + border-color: var(--primary); + box-shadow: 0 2px 10px rgba(56, 189, 248, 0.35); +} + +.preset-del-btn { + margin-left: 6px; + opacity: 0.7; + font-size: 12px; + border-radius: 50%; + padding: 2px 6px; +} + +.preset-del-btn:hover { + opacity: 1; + background: rgba(0, 0, 0, 0.2); +} + +.preset-description-text { + font-size: 13px; + margin: 8px 0 0 0; + color: var(--text-muted); +} + +/* Blocks List & Cards */ +.blocks-section-header { + display: flex; + justify-content: space-between; + align-items: baseline; + gap: 12px; + flex-wrap: wrap; + margin-bottom: 12px; +} + +.blocks-section-header h3 { + margin: 0; + font-size: 18px; + font-weight: 700; + color: var(--text-main); +} + +.blocks-tip { + font-size: 12.5px; + color: var(--text-muted); +} + +.lesson-steps-list { + display: flex; + flex-direction: column; + gap: 12px; +} + +.lesson-step-card { + background: var(--bg-card); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + padding: 16px 18px; + transition: border-color 0.2s ease, box-shadow 0.2s ease; +} + +.lesson-step-card:hover { + border-color: rgba(56, 189, 248, 0.4); +} + +.lesson-step-card.step-disabled { + opacity: 0.55; + background: var(--bg-main); +} + +.step-card-header { + display: flex; + justify-content: space-between; + align-items: center; + gap: 10px; +} + +.step-card-title-wrap { + display: flex; + align-items: center; + gap: 10px; + min-width: 0; + flex: 1; +} + +.step-num { + width: 28px; + height: 28px; + background: var(--bg-main); + border: 1px solid var(--border-color); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + font-size: 12px; + font-weight: 800; + flex-shrink: 0; + color: var(--text-main); +} + +.step-icon { + font-size: 20px; + flex-shrink: 0; +} + +.step-title { + font-size: 15px; + font-weight: 700; + color: var(--text-main); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.step-card-actions { + display: flex; + align-items: center; + gap: 8px; + flex-shrink: 0; +} + +.step-card-actions .icon-btn { + min-width: 34px; + min-height: 34px; + display: flex; + align-items: center; + justify-content: center; + border-radius: var(--radius-sm); + font-size: 13px; +} + +/* Switch Toggle */ +.switch-toggle { + position: relative; + display: inline-block; + width: 46px; + height: 26px; + flex-shrink: 0; +} + +.switch-toggle input { + opacity: 0; + width: 0; + height: 0; +} + +.toggle-slider { + position: absolute; + cursor: pointer; + top: 0; left: 0; right: 0; bottom: 0; + background-color: var(--border-color); + transition: .2s; + border-radius: 26px; +} + +.toggle-slider:before { + position: absolute; + content: ""; + height: 20px; + width: 20px; + left: 3px; + bottom: 3px; + background-color: white; + transition: .2s; + border-radius: 50%; +} + +input:checked + .toggle-slider { + background-color: var(--success); +} + +input:checked + .toggle-slider:before { + transform: translateX(20px); +} + +/* Step Card Body & Params */ +.step-card-body { + margin-top: 14px; + padding-top: 14px; + border-top: 1px solid var(--border-color); +} + +.step-param-row { + display: flex; + gap: 16px; + flex-wrap: wrap; + align-items: flex-end; +} + +.param-group { + display: flex; + flex-direction: column; + gap: 6px; +} + +.param-group label { + font-size: 12.5px; + font-weight: 600; + color: var(--text-muted); +} + +.param-group.flex-2 { + flex: 2; + min-width: 240px; +} + +.segmented-control { + display: inline-flex; + background: var(--bg-main); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + padding: 3px; + gap: 3px; +} + +.seg-btn { + border: none; + background: transparent; + padding: 7px 14px; + font-size: 13px; + font-weight: 600; + color: var(--text-muted); + border-radius: var(--radius-sm); + cursor: pointer; + transition: all 0.15s ease; + user-select: none; + -webkit-tap-highlight-color: transparent; +} + +.seg-btn:hover { + color: var(--text-main); +} + +.seg-btn.active { + background: var(--primary); + color: #fff; + font-weight: 700; + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2); +} + +/* Mode Segmented Control: 2x2 grid on mobile, horizontal pill on desktop */ +.mode-segmented-control { + display: flex; + flex-wrap: wrap; + gap: 4px; + width: 100%; +} + +.mode-segmented-control .seg-btn { + flex: 1 1 calc(50% - 4px); + display: inline-flex; + align-items: center; + justify-content: center; + gap: 6px; + padding: 9px 8px; + font-size: 13px; + text-align: center; +} + +@media (min-width: 768px) { + .step-param-row { + flex-direction: row; + align-items: flex-end; + } + .mode-segmented-control { + display: inline-flex; + flex-wrap: nowrap; + width: auto; + } + .mode-segmented-control .seg-btn { + flex: initial; + padding: 7px 14px; + } +} + +@media (max-width: 767px) { + .step-param-row { + flex-direction: column; + align-items: stretch; + gap: 12px; + } + .param-group { + width: 100%; + } + .param-group.flex-2 { + min-width: 0; + } + .step-select-param { + width: 100%; + padding: 11px 12px; + font-size: 14px; + } +} + +.step-select-param { + background: var(--bg-main); + color: var(--text-main); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + padding: 9px 12px; + font-size: 13.5px; + font-weight: 500; + cursor: pointer; + outline: none; + transition: var(--transition); +} + +.step-select-param:focus { + border-color: var(--primary); +} + +.ai-debrief-info-box { + display: flex; + align-items: center; + gap: 12px; + background: rgba(139, 92, 246, 0.08); + border: 1px dashed rgba(139, 92, 246, 0.35); + padding: 14px 16px; + border-radius: var(--radius-md); + font-size: 13.5px; + color: var(--text-main); + line-height: 1.5; +} + +.ai-box-icon { + font-size: 24px; + flex-shrink: 0; +} + +/* Bottom Floating CTA */ +.lesson-bottom-cta { + padding: 10px 0; +} + +@media (max-width: 768px) { + .lesson-bottom-cta { + position: sticky; + bottom: calc(12px + var(--sab)); + z-index: 40; + padding: 8px 0; + margin-top: 16px; + } + .lesson-bottom-cta .btn { + box-shadow: 0 4px 20px rgba(56, 189, 248, 0.4); + } +} + +.btn-xl { + padding: 15px 24px; + font-size: 17px; + font-weight: 800; + border-radius: var(--radius-lg); +} + +/* ======================================================================= + Lesson Session Runner Stage + ======================================================================= */ + +.lesson-runner-header { + display: flex; + justify-content: space-between; + align-items: center; + gap: 16px; + padding: 14px 0; + border-bottom: 1px solid var(--border-color); + flex-wrap: wrap; + position: sticky; + top: 0; + z-index: 50; + background: var(--bg-main); + backdrop-filter: blur(12px); + -webkit-backdrop-filter: blur(12px); +} + +.runner-nav-left { + display: flex; + align-items: center; + gap: 12px; +} + +.runner-timer-wrap { + font-family: var(--font-mono, monospace); + font-size: 15px; + font-weight: 700; + color: var(--text-main); + background: var(--bg-card); + padding: 5px 12px; + border-radius: var(--radius-full); + border: 1px solid var(--border-color); + white-space: nowrap; +} + +.runner-breadcrumbs-row { + display: flex; + align-items: center; + gap: 6px; + overflow-x: auto; + max-width: 540px; + padding: 4px 0; + -webkit-overflow-scrolling: touch; + scrollbar-width: none; +} +.runner-breadcrumbs-row::-webkit-scrollbar { + display: none; +} + +.runner-crumb { + display: inline-flex; + align-items: center; + gap: 6px; + padding: 5px 12px; + border-radius: var(--radius-full); + font-size: 12px; + font-weight: 600; + background: var(--bg-card); + border: 1px solid var(--border-color); + color: var(--text-muted); + white-space: nowrap; + transition: var(--transition); +} + +.crumb-num { + font-size: 11px; + font-weight: 800; +} + +.runner-crumb.step-done { + background: rgba(16, 185, 129, 0.15); + border-color: rgba(16, 185, 129, 0.4); + color: var(--success); +} + +.runner-crumb.step-active { + background: var(--primary); + border-color: var(--primary); + color: #fff; + box-shadow: 0 0 12px rgba(56, 189, 248, 0.45); +} + +.crumb-separator { + color: var(--text-dim); + font-size: 11px; +} + +@media (max-width: 768px) { + .lesson-runner-header { + padding: 10px 8px; + display: grid; + grid-template-columns: auto 1fr auto; + gap: 8px; + align-items: center; + } + .runner-nav-left { + gap: 6px; + } + .runner-nav-left .btn { + padding: 6px 10px; + font-size: 12px; + } + .runner-timer-wrap { + font-size: 13px; + padding: 4px 8px; + } + .runner-breadcrumbs-row { + max-width: none; + flex-wrap: nowrap; + gap: 4px; + justify-content: center; + } + .runner-crumb { + padding: 4px 8px; + font-size: 11px; + } + /* On mobile, collapse inactive crumbs to save horizontal space */ + .runner-crumb:not(.step-active) .crumb-label { + display: none; + } + .crumb-separator { + font-size: 9px; + } + .runner-nav-right .btn { + padding: 6px 8px; + font-size: 12px; + white-space: nowrap; + } +} + +.lesson-runner-progress-track { + width: 100%; + height: 4px; + background: var(--bg-surface-hover); + overflow: hidden; + margin-bottom: 24px; +} + +.lesson-runner-progress-fill { + height: 100%; + background: linear-gradient(90deg, #38bdf8, #8b5cf6); + transition: width 0.3s ease; +} + +/* Stage Card Box */ +.step-card-box { + background: var(--bg-card); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + padding: 28px 24px; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08); + max-width: 760px; + margin: 0 auto; +} + +@media (max-width: 640px) { + .step-card-box { + padding: 18px 14px; + border-radius: var(--radius-md); + } +} + +.step-mini-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 18px; + gap: 10px; + flex-wrap: wrap; +} + +.step-tags-wrap { + display: flex; + align-items: center; + gap: 8px; + flex-wrap: wrap; +} + +.step-term-display { + text-align: center; + padding: 16px 0; +} + +.display-term { + font-size: 36px; + font-weight: 800; + margin: 0 0 6px 0; + color: var(--text-main); + letter-spacing: -0.5px; +} + +.display-phonetic { + font-size: 18px; + color: var(--text-muted); +} + +.step-context-box { + background: var(--bg-main); + border-left: 3px solid var(--primary); + padding: 12px 16px; + border-radius: 0 var(--radius-sm) var(--radius-sm) 0; + margin-top: 14px; + font-size: 15px; + line-height: 1.5; +} + +/* ----------------------------------------------------------------------- + Vocabulary Step: Modes + ----------------------------------------------------------------------- */ + +/* Mode 1: Quiz (4 Options) */ +.lesson-quiz-card { + max-width: 680px; + margin: 0 auto; +} + +.lesson-quiz-options-grid { + display: grid; + grid-template-columns: 1fr; + gap: 10px; + width: 100%; +} + +@media (min-width: 640px) { + .lesson-quiz-options-grid { + grid-template-columns: repeat(2, 1fr); + gap: 12px; + } +} + +.lesson-quiz-opt-btn { + display: flex; + align-items: center; + gap: 12px; + padding: 14px 16px; + min-height: 56px; + background: var(--bg-main); + border: 1.5px solid var(--border-color); + border-radius: var(--radius-md); + font-size: 15px; + font-weight: 600; + color: var(--text-main); + cursor: pointer; + transition: all 0.15s ease; + text-align: left; + user-select: none; + -webkit-tap-highlight-color: transparent; +} + +.lesson-quiz-opt-btn:hover:not(:disabled) { + border-color: var(--primary); + background: var(--bg-surface-hover); + transform: translateY(-1px); +} + +.lesson-quiz-opt-btn:active:not(:disabled) { + transform: scale(0.98); +} + +.quiz-opt-num { + display: flex; + align-items: center; + justify-content: center; + width: 28px; + height: 28px; + border-radius: 50%; + background: var(--bg-card); + border: 1px solid var(--border-color); + font-size: 12px; + font-weight: 700; + color: var(--text-muted); + flex-shrink: 0; +} + +.quiz-opt-text { + flex: 1; + line-height: 1.35; + word-break: break-word; +} + +.lesson-quiz-opt-btn.opt-correct { + background: rgba(16, 185, 129, 0.18) !important; + border-color: var(--success) !important; + color: var(--success) !important; +} + +.lesson-quiz-opt-btn.opt-correct .quiz-opt-num { + background: var(--success); + color: #fff; + border-color: var(--success); +} + +.lesson-quiz-opt-btn.opt-wrong { + background: rgba(239, 68, 68, 0.18) !important; + border-color: var(--danger) !important; + color: var(--danger) !important; +} + +.lesson-quiz-opt-btn.opt-wrong .quiz-opt-num { + background: var(--danger); + color: #fff; + border-color: var(--danger); +} + +/* Mode 2: Flashcards */ +.translation-reveal-banner { + background: rgba(56, 189, 248, 0.1); + border: 1px solid rgba(56, 189, 248, 0.3); + padding: 16px 20px; + border-radius: var(--radius-md); + text-align: center; + color: var(--text-main); +} + +.tr-text { + font-size: 22px; + display: block; + margin-top: 4px; +} + +.tr-definition { + font-size: 14px; +} + +.rating-buttons-row { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 10px; +} + +@media (max-width: 640px) { + .rating-buttons-row { + grid-template-columns: repeat(2, 1fr); + gap: 8px; + } +} + +.srs-btn-rating { + display: flex; + flex-direction: column; + align-items: center; + padding: 12px 6px; + gap: 4px; + min-height: 52px; + border-radius: var(--radius-md); +} + +.rating-key { + font-size: 11px; + opacity: 0.7; +} + +.rating-label { + font-size: 13px; + font-weight: 700; +} + +/* Mode 3: Typing & Mode 4: Dictation */ +.typing-input-wrap { + display: flex; + flex-direction: column; + gap: 10px; + width: 100%; +} + +@media (min-width: 640px) { + .typing-input-wrap { + flex-direction: row; + } + .typing-input-wrap .typing-main-input { + flex: 1; + } +} + +.typing-main-input { + font-size: 16px !important; /* Prevents auto-zoom on mobile safari/chrome */ + padding: 12px 16px; + border-radius: var(--radius-md); +} + +.dictation-hero-play { + padding: 10px 0; +} + +.dictation-play-btn { + padding: 14px 28px; + font-size: 16px; + font-weight: 700; + border-radius: var(--radius-full); +} + +.dictation-hint { + font-size: 14px; +} + +/* Shared Trainer Feedback Box */ +.trainer-feedback-box { + padding: 14px 18px; + border-radius: var(--radius-md); + font-size: 14.5px; + line-height: 1.5; + animation: fadeIn 0.2s ease-out; +} + +.trainer-feedback-box.feedback-correct { + background: rgba(16, 185, 129, 0.12); + border: 1px solid rgba(16, 185, 129, 0.35); + color: var(--text-main); +} + +.trainer-feedback-box.feedback-wrong { + background: rgba(239, 68, 68, 0.12); + border: 1px solid rgba(239, 68, 68, 0.35); + color: var(--text-main); +} + +/* ----------------------------------------------------------------------- + Grammar Questions & Theory Stage + ----------------------------------------------------------------------- */ + +.grammar-question-box { + background: var(--bg-main); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + padding: 20px 18px; +} + +.grammar-sentence-prompt { + font-size: 20px; + font-weight: 600; + line-height: 1.5; + margin: 0 0 10px 0; + color: var(--text-main); +} + +.clue-tag { + font-size: 13px; + color: var(--text-muted); +} + +.grammar-options-grid { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 12px; +} + +@media (max-width: 640px) { + .grammar-options-grid { + grid-template-columns: 1fr; + gap: 10px; + } +} + +.grammar-opt-btn { + display: flex; + align-items: center; + gap: 12px; + padding: 14px 18px; + min-height: 54px; + background: var(--bg-main); + border: 1.5px solid var(--border-color); + border-radius: var(--radius-md); + cursor: pointer; + font-size: 15px; + font-weight: 600; + color: var(--text-main); + transition: all 0.15s ease; + text-align: left; + user-select: none; + -webkit-tap-highlight-color: transparent; +} + +.grammar-opt-btn:hover:not(:disabled) { + border-color: var(--primary); + background: var(--bg-surface-hover); +} + +.grammar-opt-btn.opt-correct { + background: rgba(16, 185, 129, 0.18) !important; + border-color: var(--success) !important; + color: var(--success) !important; +} + +.grammar-opt-btn.opt-wrong { + background: rgba(239, 68, 68, 0.18) !important; + border-color: var(--danger) !important; + color: var(--danger) !important; +} + +.opt-key { + width: 26px; + height: 26px; + background: var(--bg-card); + border: 1px solid var(--border-color); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + font-size: 12px; + font-weight: 700; + flex-shrink: 0; +} + +.feedback-banner { + padding: 16px 18px; + border-radius: var(--radius-md); +} + +.feedback-banner.fb-success { + background: rgba(16, 185, 129, 0.12); + border: 1px solid rgba(16, 185, 129, 0.35); +} + +.feedback-banner.fb-danger { + background: rgba(239, 68, 68, 0.12); + border: 1px solid rgba(239, 68, 68, 0.35); +} + +.fb-title { + font-size: 16px; + font-weight: 700; + margin-bottom: 6px; +} + +.fb-text { + font-size: 14px; + line-height: 1.45; +} + +/* Murphy Golden Formula & Contrasts */ +.golden-formula-box { + background: linear-gradient(135deg, rgba(99, 102, 241, 0.08), rgba(168, 85, 247, 0.08)); + border: 1px solid rgba(99, 102, 241, 0.3); + border-radius: var(--radius-md); + padding: 16px; +} + +.formula-label { + font-size: 12px; + font-weight: 800; + text-transform: uppercase; + letter-spacing: 0.5px; + color: var(--primary); + margin-bottom: 8px; +} + +.formula-code { + background: var(--bg-card); + border: 1px solid var(--border-color); + border-radius: var(--radius-sm); + padding: 10px 14px; + font-family: var(--font-mono, monospace); + font-size: 14px; + font-weight: 700; + color: var(--text-main); + overflow-x: auto; + white-space: pre-wrap; + margin: 0; +} + +.contrast-card { + background: var(--bg-card); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + padding: 16px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04); +} + +.contrast-row { + display: flex; + flex-direction: column; + gap: 12px; +} + +@media (min-width: 640px) { + .contrast-row { + flex-direction: row; + gap: 16px; + } +} + +.contrast-col { + flex: 1; + background: var(--bg-main); + border: 1px solid var(--border-color); + border-radius: var(--radius-sm); + padding: 12px; +} + +.contrast-col.a { + border-left: 3px solid #38bdf8; +} + +.contrast-col.b { + border-left: 3px solid #10b981; +} + +.contrast-col .col-title { + font-size: 13px; + font-weight: 700; + color: var(--text-main); + margin-bottom: 6px; +} + +.contrast-col .col-example { + font-size: 15px; + font-weight: 600; + color: var(--text-main); + margin-bottom: 4px; +} + +.contrast-col .col-trans { + font-size: 13px; + color: var(--text-muted); +} + +.contrast-diff { + background: rgba(245, 158, 11, 0.1); + border: 1px solid rgba(245, 158, 11, 0.3); + border-radius: var(--radius-sm); + padding: 8px 12px; + font-size: 13px; + color: var(--text-main); +} + +.journaling-box { + background: rgba(56, 189, 248, 0.06); + border: 1px dashed rgba(56, 189, 248, 0.3); + border-radius: var(--radius-md); + padding: 14px 18px; +} + +.hw-text { + font-size: 14px; + font-weight: 600; + color: var(--text-main); +} + +/* ----------------------------------------------------------------------- + Listening Stage + ----------------------------------------------------------------------- */ + +.audio-player-card { + background: var(--bg-main); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + padding: 20px; + text-align: center; +} + +.audio-controls-row { + display: flex; + justify-content: center; + gap: 12px; + align-items: center; + flex-wrap: wrap; +} + +.answer-input-group { + display: flex; + gap: 10px; +} + +@media (max-width: 640px) { + .answer-input-group { + flex-direction: column; + } +} + +.transcript-box { + background: var(--bg-main); + border: 1px solid var(--border-color); + border-radius: var(--radius-sm); + padding: 12px 14px; + font-size: 13.5px; +} + +/* ----------------------------------------------------------------------- + Reading Stage + ----------------------------------------------------------------------- */ + +.article-paragraph-card { + background: var(--bg-main); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + padding: 18px; + margin-bottom: 14px; +} + +.article-para-en { + font-size: 17px; + line-height: 1.75; + margin: 0 0 10px 0; +} + +.clickable-reader-word { + cursor: pointer; + border-radius: 3px; + padding: 1px 3px; + transition: background 0.15s; +} + +.clickable-reader-word:hover { + background: rgba(56, 189, 248, 0.25); + color: var(--primary); +} + +.article-para-ru { + font-size: 14px; + color: var(--text-muted); + border-top: 1px dashed var(--border-color); + padding-top: 8px; + margin: 8px 0 0 0; +} + +.vocab-highlights-bar { + background: var(--bg-main); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + padding: 14px 16px; +} + +.highlights-title { + font-size: 13px; + font-weight: 700; + margin-bottom: 8px; + display: block; +} + +.highlights-chips { + display: flex; + flex-wrap: wrap; + gap: 8px; +} + +.vh-chip { + background: var(--bg-card); + border: 1px solid var(--border-color); + padding: 5px 12px; + border-radius: var(--radius-full); + font-size: 12.5px; +} + +/* Word Popup in Lesson: Floating on laptop, Bottom sheet on mobile */ +.lesson-popup { + position: fixed; + z-index: 1000; + width: 270px; + background: var(--bg-card); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + padding: 14px 16px; + box-shadow: 0 10px 30px rgba(0,0,0,0.25); + animation: fadeIn 0.15s ease-out; +} + +@media (max-width: 640px) { + .lesson-popup { + left: 14px !important; + right: 14px !important; + bottom: calc(20px + var(--sab)) !important; + top: auto !important; + width: auto !important; + border-radius: var(--radius-lg); + box-shadow: 0 4px 30px rgba(0, 0, 0, 0.5); + } +} + +.popup-header { + display: flex; + justify-content: space-between; + align-items: center; + border-bottom: 1px solid var(--border-color); + padding-bottom: 6px; + margin-bottom: 6px; +} + +.popup-close-btn { + border: none; + background: transparent; + cursor: pointer; + color: var(--text-muted); + font-size: 16px; +} + +.popup-trans { + font-size: 15px; + font-weight: 700; + color: var(--text-main); +} + +/* ----------------------------------------------------------------------- + AI Debrief Stage + ----------------------------------------------------------------------- */ + +.lesson-debrief-card { + max-width: 800px; +} + +.debrief-banner-header { + display: flex; + align-items: center; + gap: 20px; + border-bottom: 1px solid var(--border-color); + padding-bottom: 20px; + flex-wrap: wrap; +} + +.grade-badge-wrap { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + width: 90px; + height: 90px; + background: var(--bg-main); + border: 3px solid var(--primary); + border-radius: 50%; + flex-shrink: 0; +} + +.grade-badge { + font-size: 34px; + font-weight: 900; + line-height: 1; + color: var(--primary); +} + +.score-pct { + font-size: 13px; + font-weight: 700; + color: var(--text-muted); +} + +.debrief-titles { + flex: 1; + min-width: 220px; +} + +.debrief-headline { + font-size: 22px; + font-weight: 800; + margin: 0 0 8px 0; + color: var(--text-main); +} + +.blocks-scores-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); + gap: 12px; +} + +.block-score-item { + background: var(--bg-main); + border: 1px solid var(--border-color); + border-radius: var(--radius-sm); + padding: 10px 12px; +} + +.bs-header { + display: flex; + justify-content: space-between; + font-size: 13px; + font-weight: 600; + margin-bottom: 6px; + color: var(--text-main); +} + +.bs-bar { + width: 100%; + height: 6px; + background: var(--bg-card); + border-radius: 3px; + overflow: hidden; +} + +.bs-bar-fill { + height: 100%; + background: var(--success); +} + +.debrief-list, .tomorrow-focus-list { + margin: 8px 0 0 0; + padding-left: 20px; + font-size: 14.5px; + line-height: 1.6; +} + +.tomorrow-focus-list { + list-style: none; + padding-left: 0; +} + +.tomorrow-focus-list li { + padding: 8px 12px; + background: var(--bg-main); + border-left: 3px solid var(--primary); + margin-bottom: 6px; + border-radius: 0 var(--radius-sm) var(--radius-sm) 0; + font-size: 14px; +} + +.error-cards-list { + display: flex; + flex-direction: column; + gap: 8px; +} + +.error-analysis-item { + display: flex; + align-items: flex-start; + gap: 10px; + background: rgba(234, 179, 8, 0.1); + border: 1px solid rgba(234, 179, 8, 0.3); + border-radius: var(--radius-md); + padding: 12px 14px; + font-size: 14px; + line-height: 1.45; +} + +.celebrate-badge { + font-size: 48px; + margin-bottom: 12px; +} + +.step-completed-box h3 { + font-size: 24px; + font-weight: 800; + margin-bottom: 8px; + color: var(--text-main); +} + +.score-highlight { + font-size: 16px; + color: var(--text-muted); +} + +/* History Modal items */ +.lesson-history-list { + display: flex; + flex-direction: column; + gap: 12px; + max-height: 65vh; + overflow-y: auto; +} + +.lesson-history-item { + background: var(--bg-main); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + padding: 14px 16px; +} + +.lh-header { + display: flex; + justify-content: space-between; + font-size: 15px; + font-weight: 700; + margin-bottom: 6px; +} + +.lh-date { + font-size: 12px; + color: var(--text-muted); + font-weight: normal; +} + +.lh-stats { + display: flex; + gap: 12px; + align-items: center; + font-size: 13px; + margin-bottom: 6px; +} + +.lh-headline { + font-size: 13px; + font-style: italic; + color: var(--text-dim); +} + +@media (max-width: 640px) { + .display-term { + font-size: 26px; + } +} + diff --git a/app/static/css/reader.css b/app/static/css/reader.css new file mode 100644 index 0000000..1aaf27e --- /dev/null +++ b/app/static/css/reader.css @@ -0,0 +1,2066 @@ +/* ========================================================================== + 5. Bookshelf, Continuous Reader, Typography Controls & Wikipedia + ========================================================================== */ + +/* ========================================================================== + Stage 5: Interactive Reader & Bookshelf Styles + ========================================================================== */ + +.reader-view { + max-width: 1100px; + margin: 0 auto; + padding: 24px 20px 80px; +} + +.bookshelf-header { + display: flex; + justify-content: space-between; + align-items: center; + flex-wrap: wrap; + gap: 16px; + margin-bottom: 28px; + padding-bottom: 20px; + border-bottom: 1px solid var(--border-color); +} + +.bookshelf-title-wrap h2 { + font-size: 24px; + font-weight: 700; + color: var(--text-main); + display: flex; + align-items: center; + gap: 8px; +} + +.bookshelf-title-wrap .subtitle { + font-size: 14px; + color: var(--text-muted); + margin-top: 4px; +} + +.bookshelf-actions { + display: flex; + align-items: center; + gap: 12px; +} + +.file-upload-label { + cursor: pointer; + display: inline-flex; + align-items: center; + gap: 6px; +} + +.bookshelf-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); + gap: 20px; +} + +.book-card { + background-color: var(--bg-surface); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + padding: 20px; + display: flex; + flex-direction: column; + justify-content: space-between; + transition: var(--transition); + position: relative; + box-shadow: var(--shadow-sm); +} + +.book-card:hover { + border-color: var(--border-focus); + box-shadow: var(--shadow-md); + transform: translateY(-2px); +} + +.book-card-top { + display: flex; + align-items: flex-start; + gap: 14px; + margin-bottom: 14px; +} + +.book-cover-icon { + font-size: 32px; + background: var(--bg-input); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + width: 52px; + height: 64px; + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; +} + +.book-card-info { + flex: 1; + min-width: 0; +} + +.book-card-title { + font-size: 16px; + font-weight: 700; + color: var(--text-main); + margin-bottom: 4px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.book-card-author { + font-size: 13px; + color: var(--text-muted); + margin-bottom: 8px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.book-card-badges { + display: flex; + align-items: center; + gap: 8px; +} + +.badge-format { + text-transform: uppercase; + font-size: 10px; + font-weight: 700; + padding: 2px 6px; + border-radius: var(--radius-sm); + background: var(--tag-bg); + color: var(--tag-text); +} + +.badge-words { + font-size: 12px; + color: var(--text-dim); +} + +.book-progress-wrap { + margin: 14px 0 16px; +} + +.book-progress-labels { + display: flex; + justify-content: space-between; + font-size: 12px; + color: var(--text-dim); + margin-bottom: 6px; +} + +.book-progress-bar-bg { + width: 100%; + height: 6px; + background-color: var(--bg-input); + border-radius: var(--radius-full); + overflow: hidden; +} + +.book-progress-bar-fill { + height: 100%; + background-color: var(--primary); + border-radius: var(--radius-full); + transition: width 0.3s ease; +} + +.book-card-actions { + display: flex; + align-items: center; + justify-content: space-between; + gap: 8px; + padding-top: 12px; + border-top: 1px solid var(--border-color); +} + +/* Bookshelf Divider between General Books & RFC Specifications */ +.bookshelf-divider { + margin: 48px 0 36px; + border: 0; + height: 1px; + background: linear-gradient(90deg, transparent, var(--border-color) 15%, var(--border-color) 85%, transparent); +} + +/* RFC Specifications Section */ +.rfc-section { + margin-top: 8px; +} + +.rfc-header { + margin-bottom: 20px; +} + +.rfc-title-row { + display: flex; + align-items: center; + gap: 14px; +} + +.rfc-icon-badge { + display: inline-flex; + align-items: center; + justify-content: center; + width: 44px; + height: 44px; + font-size: 24px; + background: rgba(14, 165, 233, 0.12); + border: 1px solid rgba(14, 165, 233, 0.28); + border-radius: var(--radius-md); + flex-shrink: 0; +} + +.rfc-heading { + font-size: 20px; + font-weight: 700; + color: var(--text-main); + margin: 0; +} + +.rfc-fetch-box { + background: var(--bg-surface); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + padding: 20px 24px; + margin-bottom: 24px; + box-shadow: var(--shadow-sm); +} + +.rfc-fetch-form { + margin-bottom: 16px; +} + +.rfc-input-wrap { + display: flex; + align-items: stretch; + gap: 10px; +} + +.rfc-input-prefix { + display: inline-flex; + align-items: center; + padding: 0 14px; + font-weight: 700; + font-size: 13px; + letter-spacing: 0.05em; + color: #38bdf8; + background: rgba(56, 189, 248, 0.12); + border: 1px solid rgba(56, 189, 248, 0.25); + border-radius: var(--radius-md); + user-select: none; +} + +.rfc-input { + flex: 1; + min-width: 0; +} + +.rfc-fetch-btn { + white-space: nowrap; + padding: 0 20px; + display: inline-flex; + align-items: center; + justify-content: center; + font-weight: 600; +} + +.rfc-fetch-status { + margin-top: 10px; + padding: 8px 14px; + font-size: 13px; + border-radius: var(--radius-md); + transition: all 0.2s ease; +} + +.rfc-status-loading { + background: rgba(14, 165, 233, 0.1); + color: #38bdf8; + border: 1px solid rgba(14, 165, 233, 0.25); +} + +.rfc-status-success { + background: rgba(34, 197, 94, 0.12); + color: #4ade80; + border: 1px solid rgba(34, 197, 94, 0.25); +} + +.rfc-status-error { + background: rgba(239, 68, 68, 0.12); + color: #f87171; + border: 1px solid rgba(239, 68, 68, 0.25); +} + +.rfc-presets-wrap { + display: flex; + flex-direction: column; + gap: 10px; +} + +.rfc-presets-label { + font-size: 12px; + text-transform: uppercase; + font-weight: 600; + letter-spacing: 0.05em; + color: var(--text-dim); +} + +.rfc-presets-list { + display: flex; + flex-wrap: wrap; + gap: 8px; +} + +.rfc-preset-chip { + background: var(--bg-input); + color: var(--text-main); + border: 1px solid var(--border-color); + border-radius: var(--radius-full); + padding: 6px 14px; + font-size: 12.5px; + font-weight: 500; + cursor: pointer; + transition: var(--transition); + user-select: none; + display: inline-flex; + align-items: center; + gap: 5px; +} + +.rfc-preset-chip:hover { + background: rgba(14, 165, 233, 0.15); + border-color: #38bdf8; + color: #38bdf8; + transform: translateY(-1px); +} + +.rfc-empty-state { + padding: 36px 20px; + background: var(--bg-surface); + border: 1px dashed var(--border-color); + border-radius: var(--radius-lg); + margin-bottom: 24px; +} + +.rfc-card { + border-color: rgba(56, 189, 248, 0.2); +} + +.rfc-card:hover { + border-color: rgba(56, 189, 248, 0.5); + box-shadow: 0 8px 24px rgba(14, 165, 233, 0.12); +} + +.rfc-cover-icon { + background: rgba(14, 165, 233, 0.1); + border-color: rgba(14, 165, 233, 0.25); +} + +.badge-rfc { + background: rgba(14, 165, 233, 0.2); + color: #38bdf8; + border: 1px solid rgba(14, 165, 233, 0.35); +} + +.rfc-progress-fill { + background: linear-gradient(90deg, #0284c7, #38bdf8); +} + +@media (max-width: 640px) { + .rfc-input-wrap { + flex-direction: column; + } + .rfc-input-prefix { + display: none; + } + .rfc-fetch-btn { + width: 100%; + padding: 10px 16px; + } +} + +/* ========================================================================== + Wikipedia Articles Section & Settings Modal + ========================================================================== */ + +.wiki-section { + margin-top: 8px; +} + +.wiki-header { + margin-bottom: 20px; +} + +.wiki-title-row { + display: flex; + align-items: center; + gap: 14px; +} + +.wiki-icon-badge { + display: inline-flex; + align-items: center; + justify-content: center; + width: 44px; + height: 44px; + font-size: 24px; + background: rgba(168, 85, 247, 0.12); + border: 1px solid rgba(168, 85, 247, 0.28); + border-radius: var(--radius-md); + flex-shrink: 0; +} + +.wiki-heading { + font-size: 20px; + font-weight: 700; + color: var(--text-main); + margin: 0; +} + +.wiki-action-box { + background: var(--bg-surface); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + padding: 20px 24px; + margin-bottom: 24px; + box-shadow: var(--shadow-sm); +} + +.wiki-primary-actions { + display: flex; + align-items: center; + gap: 12px; + flex-wrap: wrap; + margin-bottom: 14px; +} + +.wiki-read-btn { + padding: 10px 24px; + font-weight: 700; + font-size: 15px; + background: linear-gradient(135deg, #6366f1, #8b5cf6); + border: none; + box-shadow: 0 4px 14px rgba(99, 102, 241, 0.35); + transition: all 0.2s ease; +} + +.wiki-read-btn:hover { + background: linear-gradient(135deg, #4f46e5, #7c3aed); + transform: translateY(-1px); + box-shadow: 0 6px 18px rgba(99, 102, 241, 0.45); +} + +.wiki-settings-btn { + padding: 10px 18px; + font-weight: 600; + border-color: rgba(168, 85, 247, 0.35); + color: var(--text-main); +} + +.wiki-settings-btn:hover { + background: rgba(168, 85, 247, 0.12); + border-color: #a855f7; + color: #c084fc; +} + +.wiki-badges-row { + display: flex; + align-items: center; + gap: 8px; + flex-wrap: wrap; + font-size: 13px; +} + +.wiki-badges-label { + color: var(--text-dim); + font-size: 12px; + text-transform: uppercase; + font-weight: 600; + letter-spacing: 0.05em; + margin-right: 4px; +} + +.wiki-badge-chip { + background: rgba(168, 85, 247, 0.12); + color: #c084fc; + border: 1px solid rgba(168, 85, 247, 0.28); + border-radius: var(--radius-full); + padding: 4px 12px; + font-weight: 500; + font-size: 12px; + display: inline-flex; + align-items: center; + gap: 4px; +} + +.wiki-fetch-status { + margin-top: 14px; + padding: 10px 16px; + font-size: 13.5px; + border-radius: var(--radius-md); + transition: all 0.2s ease; +} + +.wiki-status-loading { + background: rgba(99, 102, 241, 0.12); + color: #818cf8; + border: 1px solid rgba(99, 102, 241, 0.3); +} + +.wiki-status-success { + background: rgba(34, 197, 94, 0.12); + color: #4ade80; + border: 1px solid rgba(34, 197, 94, 0.25); +} + +.wiki-status-error { + background: rgba(239, 68, 68, 0.12); + color: #f87171; + border: 1px solid rgba(239, 68, 68, 0.25); +} + +.wiki-empty-state { + padding: 36px 20px; + background: var(--bg-surface); + border: 1px dashed var(--border-color); + border-radius: var(--radius-lg); + margin-bottom: 24px; +} + +/* Card styling for Wikipedia and thumbnails */ +.wiki-card { + border-color: rgba(168, 85, 247, 0.22); +} + +.wiki-card:hover { + border-color: rgba(168, 85, 247, 0.55); + box-shadow: 0 8px 24px rgba(168, 85, 247, 0.15); +} + +.wiki-cover-icon { + background: rgba(168, 85, 247, 0.12); + border-color: rgba(168, 85, 247, 0.3); + color: #c084fc; +} + +.badge-wiki { + background: rgba(168, 85, 247, 0.18); + color: #c084fc; + border: 1px solid rgba(168, 85, 247, 0.35); +} + +.wiki-progress-fill { + background: linear-gradient(90deg, #7c3aed, #a855f7); +} + +.book-cover-img-wrap { + width: 52px; + height: 64px; + border-radius: var(--radius-sm); + overflow: hidden; + flex-shrink: 0; + background: rgba(0, 0, 0, 0.2); + border: 1px solid var(--border-color); + display: flex; + align-items: center; + justify-content: center; +} + +.book-cover-img { + width: 100%; + height: 100%; + object-fit: cover; + display: block; +} + +.badge-time { + display: inline-flex; + align-items: center; + gap: 3px; + background: rgba(255, 255, 255, 0.06); + color: var(--text-dim); + font-size: 11px; + font-weight: 500; + padding: 2px 7px; + border-radius: var(--radius-sm); + border: 1px solid rgba(255, 255, 255, 0.08); +} + +/* Wikipedia Settings Modal */ +.wiki-modal-window { + max-width: 620px; + width: 95%; +} + +.wiki-modal-body { + display: flex; + flex-direction: column; + gap: 22px; +} + +.wiki-setting-group { + display: flex; + flex-direction: column; + gap: 10px; +} + +.wiki-group-label { + font-size: 13.5px; + font-weight: 700; + color: var(--text-main); + letter-spacing: 0.02em; +} + +.wiki-radio-cards { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 12px; +} + +.wiki-radio-card { + display: flex; + align-items: flex-start; + gap: 12px; + padding: 14px 16px; + background: var(--bg-input); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + cursor: pointer; + transition: all 0.2s ease; + user-select: none; +} + +.wiki-radio-card:hover { + border-color: rgba(168, 85, 247, 0.4); + background: rgba(168, 85, 247, 0.04); +} + +.wiki-radio-card:has(input:checked) { + border-color: #a855f7; + background: rgba(168, 85, 247, 0.1); + box-shadow: 0 0 0 1px #a855f7; +} + +.wiki-radio-card input[type="radio"] { + margin-top: 3px; + accent-color: #a855f7; +} + +.wiki-radio-card-content { + display: flex; + flex-direction: column; + gap: 5px; +} + +.wiki-card-title-row { + display: flex; + align-items: center; + justify-content: space-between; + gap: 8px; +} + +.wiki-card-desc { + font-size: 12px; + color: var(--text-dim); + line-height: 1.45; + margin: 0; +} + +.badge-level-pill { + font-size: 10.5px; + font-weight: 700; + padding: 1px 7px; + border-radius: var(--radius-full); + text-transform: uppercase; + letter-spacing: 0.04em; +} + +.badge-level-a2 { + background: rgba(34, 197, 94, 0.2); + color: #4ade80; + border: 1px solid rgba(34, 197, 94, 0.35); +} + +.badge-level-b2 { + background: rgba(59, 130, 246, 0.2); + color: #60a5fa; + border: 1px solid rgba(59, 130, 246, 0.35); +} + +.wiki-time-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); + gap: 8px; +} + +.wiki-time-pill { + display: flex; + align-items: center; + position: relative; + cursor: pointer; + user-select: none; +} + +.wiki-time-pill input[type="radio"] { + position: absolute; + opacity: 0; + pointer-events: none; +} + +.wiki-pill-text { + width: 100%; + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + padding: 10px 8px; + background: var(--bg-input); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + font-size: 13px; + font-weight: 600; + color: var(--text-main); + transition: all 0.2s ease; +} + +.wiki-pill-text small { + font-size: 11px; + font-weight: normal; + margin-top: 2px; +} + +.wiki-time-pill:hover .wiki-pill-text { + border-color: rgba(168, 85, 247, 0.4); +} + +.wiki-time-pill input[type="radio"]:checked + .wiki-pill-text { + border-color: #a855f7; + background: rgba(168, 85, 247, 0.12); + color: #c084fc; + box-shadow: 0 0 0 1px #a855f7; +} + +.wiki-select { + width: 100%; + padding: 10px 14px; + font-size: 14px; +} + +.wiki-direct-import-group { + border-top: 1px dashed var(--border-color); + padding-top: 18px; +} + +.wiki-custom-input-wrap { + display: flex; + align-items: center; + gap: 10px; +} + +.wiki-custom-input { + flex: 1; + min-width: 0; +} + +.wiki-custom-fetch-btn { + white-space: nowrap; + padding: 0 18px; + font-weight: 600; +} + +@media (max-width: 640px) { + .wiki-radio-cards { + grid-template-columns: 1fr; + } + .wiki-custom-input-wrap { + flex-direction: column; + } + .wiki-custom-fetch-btn { + width: 100%; + padding: 10px 16px; + } +} + +/* Reader Interface */ +.reader-interface { + background-color: var(--bg-surface); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + box-shadow: var(--shadow-lg); +} + +.reader-toolbar { + position: sticky; + top: var(--navbar-height, 60px); + z-index: 1000; + background-color: var(--bg-surface); + border-top-left-radius: var(--radius-lg); + border-top-right-radius: var(--radius-lg); + border-bottom: 1px solid var(--border-color); + padding: 12px 18px; + display: flex; + justify-content: space-between; + align-items: center; + flex-wrap: wrap; + gap: 12px; + box-shadow: 0 4px 14px rgba(0, 0, 0, 0.15); +} + +.reader-toolbar-left { + display: flex; + align-items: center; + gap: 14px; +} + +.reader-meta { + display: flex; + flex-direction: column; +} + +.reader-title { + font-size: 16px; + font-weight: 700; + color: var(--text-main); + line-height: 1.2; +} + +.reader-author { + font-size: 12px; + color: var(--text-muted); +} + +.reader-toolbar-center { + display: flex; + align-items: center; + gap: 8px; +} + +.reader-select { + padding: 6px 12px; + border-radius: var(--radius-sm); + background-color: var(--bg-input); + color: var(--text-main); + border: 1px solid var(--border-color); + font-size: 13px; + outline: none; + max-width: 240px; +} + +.reader-progress-badge { + font-size: 11px; + font-weight: 700; + font-variant-numeric: tabular-nums; + color: var(--primary); + background: var(--primary-dim); + border: 1px solid rgba(56, 189, 248, 0.35); + padding: 3px 8px; + border-radius: var(--radius-full); + min-width: 40px; + text-align: center; + display: inline-block; + user-select: none; + line-height: 1.2; +} + +.reader-chapter-progress-bar { + position: absolute; + left: 0; + right: 0; + bottom: -1px; + height: 3px; + background-color: rgba(255, 255, 255, 0.08); + overflow: hidden; + pointer-events: none; +} + +.reader-chapter-progress-fill { + height: 100%; + width: 0%; + background: linear-gradient(90deg, #0284c7, #38bdf8); + box-shadow: 0 0 8px rgba(56, 189, 248, 0.5); + transition: width 0.12s cubic-bezier(0.16, 1, 0.3, 1); +} + +.reader-toolbar-right { + display: flex; + align-items: center; + gap: 10px; +} + +.font-controls { + display: flex; + align-items: center; + gap: 4px; +} + +.reader-scroll-area { + --reader-font-size: 18px; + --reader-line-height: 1.65; + --reader-font-family: 'Literata', 'Merriweather', 'Georgia', 'Cambria', serif; + --reader-max-width: 760px; + --reader-padding-h: 24px; + --reader-text-align: left; + --reader-bg: var(--bg-surface); + --reader-text: var(--text-main); + + background-color: var(--reader-bg); + min-height: 60vh; + padding: 0; + transition: background-color 0.2s ease, color 0.2s ease; +} + +.reader-content-body { + max-width: var(--reader-max-width); + margin: 0 auto; + padding: 32px var(--reader-padding-h) 80px; + font-family: var(--reader-font-family); + font-size: var(--reader-font-size); + line-height: var(--reader-line-height); + text-align: var(--reader-text-align); + color: var(--reader-text); + word-break: break-word; + user-select: text; + transition: font-size 0.15s ease, line-height 0.15s ease, max-width 0.2s ease, padding 0.2s ease; +} + +/* Reader Appearance Themes */ +.reader-scroll-area.reader-theme-sepia { + --reader-bg: #fbf0d9; + --reader-text: #433422; +} +.reader-scroll-area.reader-theme-sepia .reader-word:hover { + background-color: rgba(217, 119, 6, 0.25); + color: #92400e; +} +.reader-scroll-area.reader-theme-sepia blockquote { + background-color: #f4e4c1; + border-color: #d6bc97; + color: #5f4b32; +} +.reader-scroll-area.reader-theme-sepia .reader-inline-code, +.reader-scroll-area.reader-theme-sepia .reader-code-wrap pre { + background-color: #efe0bc; + color: #433422; + border-color: #dec89f; +} +.reader-scroll-area.reader-theme-sepia .reader-table th, +.reader-scroll-area.reader-theme-sepia .reader-table td { + border-color: #dec89f; +} + +.reader-scroll-area.reader-theme-light { + --reader-bg: #ffffff; + --reader-text: #1e293b; +} +.reader-scroll-area.reader-theme-light blockquote { + background-color: #f8fafc; + border-color: #cbd5e1; + color: #334155; +} +.reader-scroll-area.reader-theme-light .reader-inline-code, +.reader-scroll-area.reader-theme-light .reader-code-wrap pre { + background-color: #f1f5f9; + color: #0f172a; + border-color: #e2e8f0; +} +.reader-scroll-area.reader-theme-light .reader-word:hover { + background-color: rgba(2, 132, 199, 0.15); + color: #0284c7; +} + +.reader-scroll-area.reader-theme-oled { + --reader-bg: #000000; + --reader-text: #d8e2ec; +} +.reader-scroll-area.reader-theme-oled blockquote { + background-color: #0a0e17; + border-color: #1e293b; +} +.reader-scroll-area.reader-theme-oled .reader-inline-code, +.reader-scroll-area.reader-theme-oled .reader-code-wrap pre { + background-color: #0a0e17; + border-color: #1e293b; +} + +.reader-scroll-area.reader-theme-dark { + --reader-bg: var(--bg-surface); + --reader-text: var(--text-main); +} + +/* Reader Font Families */ +.reader-scroll-area.reader-font-sans { + --reader-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; +} +.reader-scroll-area.reader-font-serif { + --reader-font-family: 'Literata', 'Merriweather', 'Georgia', 'Cambria', 'Times New Roman', serif; +} +.reader-scroll-area.reader-font-mono { + --reader-font-family: 'JetBrains Mono', 'Fira Code', 'Menlo', 'Consolas', monospace; +} + +/* Reader Margin & Width Variants */ +.reader-scroll-area.reader-margins-narrow { + --reader-max-width: 940px; + --reader-padding-h: 12px; +} +.reader-scroll-area.reader-margins-normal { + --reader-max-width: 760px; + --reader-padding-h: 24px; +} +.reader-scroll-area.reader-margins-wide { + --reader-max-width: 600px; + --reader-padding-h: 36px; +} + +/* Reader Text Alignment */ +.reader-scroll-area.reader-align-left { + --reader-text-align: left; +} +.reader-scroll-area.reader-align-justify { + --reader-text-align: justify; + hyphens: auto; +} + +/* Reader Appearance Settings Panel / Sheet */ +.reader-settings-panel { + position: fixed; + top: 64px; + right: 28px; + width: 330px; + max-width: calc(100vw - 32px); + max-height: calc(100vh - 80px); + display: flex; + flex-direction: column; + background-color: var(--bg-surface); + border: 1px solid var(--border-focus); + border-radius: var(--radius-lg); + box-shadow: 0 16px 36px rgba(0, 0, 0, 0.45); + z-index: 10006; + padding: 16px; + animation: fadeIn 0.15s ease-out; +} + +.reader-settings-header { + display: flex; + justify-content: space-between; + align-items: center; + flex-shrink: 0; + margin-bottom: 12px; + padding-bottom: 8px; + border-bottom: 1px solid var(--border-color); +} + +.reader-settings-header h4 { + font-size: 15px; + font-weight: 700; + color: var(--text-main); +} + +.reader-settings-body { + display: flex; + flex-direction: column; + gap: 12px; + overflow-y: auto; + padding-right: 4px; + scrollbar-width: thin; + scrollbar-color: var(--border-focus) transparent; +} + +.reader-settings-body::-webkit-scrollbar { + width: 6px; +} + +.reader-settings-body::-webkit-scrollbar-thumb { + background-color: var(--border-focus); + border-radius: 3px; +} + +.setting-row { + display: flex; + flex-direction: column; + gap: 6px; +} + +.setting-row-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 8px; + align-items: flex-end; +} + +.setting-row-grid .seg-btn { + padding: 6px 4px; + font-size: 11.5px; +} + +.setting-label { + font-size: 11px; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.5px; + color: var(--text-muted); +} + +.setting-segmented-control { + display: flex; + background-color: var(--bg-input); + border: 1px solid var(--border-color); + border-radius: var(--radius-sm); + padding: 2px; + gap: 2px; +} + +.seg-btn { + flex: 1; + padding: 6px 8px; + font-size: 12px; + font-weight: 600; + background: transparent; + border: none; + border-radius: 4px; + color: var(--text-muted); + cursor: pointer; + transition: var(--transition); + text-align: center; +} + +.seg-btn:hover { + color: var(--text-main); +} + +.seg-btn.active { + background-color: var(--primary); + color: #0f172a; +} + +.setting-stepper { + display: flex; + align-items: center; + justify-content: space-between; + background-color: var(--bg-input); + border: 1px solid var(--border-color); + border-radius: var(--radius-sm); + padding: 4px 6px; +} + +.step-btn { + background: var(--bg-surface-hover); + border: 1px solid var(--border-color); + border-radius: 4px; + color: var(--text-main); + font-size: 13px; + font-weight: 700; + width: 38px; + height: 32px; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; +} + +.step-val { + font-size: 14px; + font-weight: 700; + color: var(--primary); +} + +.theme-palette { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 6px; +} + +.theme-chip { + padding: 7px 10px; + font-size: 12px; + font-weight: 600; + border-radius: var(--radius-sm); + border: 2px solid transparent; + cursor: pointer; + text-align: center; + transition: var(--transition); +} + +.theme-chip-dark { background: #1e293b; color: #f8fafc; border-color: #334155; } +.theme-chip-sepia { background: #fbf0d9; color: #433422; border-color: #d6bc97; } +.theme-chip-light { background: #ffffff; color: #0f172a; border-color: #cbd5e1; } +.theme-chip-oled { background: #000000; color: #e2e8f0; border-color: #334155; } + +.theme-chip.active { + border-color: var(--primary) !important; + box-shadow: 0 0 0 2px var(--primary-dim); +} + +.reader-settings-btn { + display: inline-flex; + align-items: center; + gap: 4px; +} + +.reader-content-body h1, +.reader-content-body h2, +.reader-content-body h3, +.reader-content-body h4, +.reader-content-body h5, +.reader-content-body h6 { + font-family: var(--font-family); + margin: 28px 0 16px; + color: var(--text-main); + text-indent: 0; +} + +.reader-content-body h4 { font-size: 1.15em; } +.reader-content-body h5 { font-size: 1.05em; } + +.reader-content-body p { + margin-bottom: 20px; + text-indent: 1.2em; +} + +/* Fenced Code Block */ +.reader-code-block { + margin: 24px 0; + border-radius: var(--radius-md); + background: #141820; + border: 1px solid var(--border-color); + overflow: hidden; + box-shadow: 0 4px 14px rgba(0, 0, 0, 0.3); +} + +.reader-code-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 8px 14px; + background: rgba(255, 255, 255, 0.04); + border-bottom: 1px solid var(--border-color); + font-family: monospace; + font-size: 12px; + color: var(--text-muted); + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.reader-code-lang { + font-weight: 600; +} + +.reader-copy-code-btn { + background: transparent; + border: 1px solid var(--border-color); + color: var(--text-muted); + border-radius: 4px; + padding: 3px 8px; + font-size: 11px; + cursor: pointer; + transition: all 0.15s ease; + display: inline-flex; + align-items: center; + gap: 4px; +} + +.reader-copy-code-btn:hover { + background: rgba(255, 255, 255, 0.08); + color: var(--text-main); + border-color: var(--primary); +} + +.reader-content-body pre { + margin: 0; + padding: 16px; + overflow-x: auto; + background: transparent; + border: none; + border-radius: 0; + font-family: 'JetBrains Mono', 'Fira Code', 'Consolas', monospace; + font-size: 14.5px; + line-height: 1.6; + text-indent: 0 !important; + white-space: pre; + tab-size: 4; +} + +.reader-content-body pre code { + font-family: inherit; + font-size: inherit; + color: #e6edf3; + background: transparent; + padding: 0; + border: none; + white-space: pre; + display: block; + text-indent: 0; +} + +/* Inline Code Badge */ +.reader-inline-code { + font-family: 'JetBrains Mono', 'Consolas', monospace; + font-size: 0.88em; + background: rgba(255, 255, 255, 0.08); + color: var(--primary); + padding: 2px 6px; + border-radius: 4px; + border: 1px solid rgba(255, 255, 255, 0.12); + white-space: pre-wrap; + word-break: break-all; +} + +/* Blockquote */ +.reader-content-body blockquote { + margin: 20px 0; + padding: 12px 20px; + border-left: 4px solid var(--primary); + background: rgba(56, 189, 248, 0.06); + border-radius: 0 var(--radius-md) var(--radius-md) 0; + font-style: italic; + color: var(--text-main); + text-indent: 0; +} + +.reader-content-body blockquote p { + margin: 0; + text-indent: 0; +} + +/* Lists */ +.reader-content-body ul, +.reader-content-body ol { + margin: 16px 0 20px 24px; + padding-left: 12px; + text-indent: 0; +} + +.reader-content-body li { + margin-bottom: 8px; + line-height: 1.7; + text-indent: 0; +} + +.reader-content-body hr { + border: 0; + height: 1px; + background: var(--border-color); + margin: 32px 0; +} + +/* Headings */ +.reader-content-body h1, +.reader-content-body h2, +.reader-content-body h3, +.reader-content-body h4, +.reader-content-body h5, +.reader-content-body h6 { + color: var(--text-main); + font-weight: 700; + line-height: 1.35; + margin: 32px 0 16px; + text-indent: 0 !important; +} + +.reader-content-body h1 { + font-size: 28px; + border-bottom: 1px solid var(--border-color); + padding-bottom: 10px; +} + +.reader-content-body h2 { + font-size: 23px; + border-bottom: 1px solid var(--border-color); + padding-bottom: 8px; +} + +.reader-content-body h3 { + font-size: 19px; +} + +.reader-content-body h4 { + font-size: 17px; +} + +/* Markdown Tables */ +.reader-table-wrap { + overflow-x: auto; + margin: 24px 0; + border-radius: var(--radius-md); + border: 1px solid var(--border-color); + background: var(--bg-surface); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2); +} + +.reader-table { + width: 100%; + border-collapse: collapse; + font-size: 14.5px; + line-height: 1.6; + text-indent: 0 !important; +} + +.reader-table th, +.reader-table td { + padding: 10px 16px; + border-bottom: 1px solid var(--border-color); + border-right: 1px solid var(--border-color); + vertical-align: top; + text-indent: 0 !important; +} + +.reader-table th:last-child, +.reader-table td:last-child { + border-right: none; +} + +.reader-table tr:last-child td { + border-bottom: none; +} + +.reader-table th { + background-color: rgba(255, 255, 255, 0.05); + font-weight: 700; + color: var(--text-main); + text-align: left; +} + +.reader-table tbody tr:hover { + background-color: rgba(255, 255, 255, 0.02); +} + +/* Links & Images */ +.reader-link { + color: var(--primary); + text-decoration: underline; + text-decoration-thickness: 1px; + text-underline-offset: 3px; + transition: color 0.15s ease; +} + +.reader-link:hover { + color: var(--primary-hover); +} + +.reader-img { + max-width: 100%; + height: auto; + border-radius: var(--radius-md); + margin: 8px 0; + vertical-align: middle; +} + +.reader-content-body p img { + margin: 4px 6px; + display: inline-block; + vertical-align: middle; +} + +/* Figures and Media (Images, Diagrams, Animated GIFs, SVGs) */ +.reader-figure { + margin: 28px auto; + padding: 14px; + background: var(--bg-surface); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15); + display: flex; + flex-direction: column; + align-items: center; + max-width: 95%; + box-sizing: border-box; +} + +.reader-figure-img { + max-width: 100%; + max-height: 480px; + width: auto; + height: auto; + border-radius: var(--radius-md); + object-fit: contain; + display: block; +} + +.reader-figcaption { + margin-top: 12px; + padding-top: 10px; + border-top: 1px solid rgba(255, 255, 255, 0.08); + font-size: 13.5px; + line-height: 1.55; + color: var(--text-dim); + text-align: center; + max-width: 90%; + font-style: italic; + user-select: text; +} + +.reader-figcaption .reader-word { + font-style: normal; +} + +.reader-content-body p[style*="text-align: center"], +.reader-content-body p.text-center { + text-indent: 0 !important; +} + +.reader-content-body strong, +.reader-content-body b { + font-weight: 700; + color: var(--text-main); +} + +.reader-content-body em, +.reader-content-body i { + font-style: italic; +} + +.reader-content-body sub, +.reader-content-body sup { + font-size: 0.8em; + line-height: 0; + position: relative; + vertical-align: baseline; +} +.reader-content-body sub { bottom: -0.25em; } +.reader-content-body sup { top: -0.5em; } + +/* Interactive Words */ +.reader-word { + cursor: pointer; + border-radius: 3px; + transition: background-color 0.12s ease, color 0.12s ease; + padding: 1px 2px; +} + +.reader-word:hover { + background-color: var(--primary-dim); + color: var(--primary); +} + +.reader-word.status-mastered.highlight-enabled { + border-bottom: 2px dotted rgba(16, 185, 129, 0.5); +} + +.reader-word.status-learning.highlight-enabled { + border-bottom: 2px dotted rgba(56, 189, 248, 0.5); +} + +/* Click-to-Translate Popup */ +.reader-word-popup { + position: fixed; + z-index: 10005; + background-color: var(--bg-surface); + border: 1px solid var(--border-focus); + border-radius: var(--radius-lg); + box-shadow: 0 12px 24px -4px rgba(0, 0, 0, 0.5); + width: 320px; + max-width: calc(100vw - 32px); + padding: 16px; + animation: fadeInScale 0.15s ease-out; +} + +.popup-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 12px; + padding-bottom: 8px; + border-bottom: 1px solid var(--border-color); +} + +.popup-term-wrap { + display: flex; + align-items: center; + gap: 8px; + flex-wrap: wrap; +} + +.popup-term { + font-size: 18px; + color: var(--text-main); +} + +.popup-phonetic { + font-size: 13px; + color: var(--primary); + font-family: monospace; +} + +.popup-close-btn { + background: none; + border: none; + color: var(--text-dim); + font-size: 16px; + cursor: pointer; + padding: 4px; +} + +/* Phrasal Verb & Collocation Card in Word Popup */ +.popup-phrasal-card { + background: linear-gradient(135deg, rgba(99, 102, 241, 0.12), rgba(168, 85, 247, 0.08)); + border: 1px solid rgba(99, 102, 241, 0.35); + border-radius: var(--radius-sm); + padding: 8px 10px; + margin-bottom: 10px; + animation: fadeIn 0.15s ease-out; +} + +.phrasal-card-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 4px; +} + +.phrasal-tag { + font-size: 10px; + font-weight: 700; + color: var(--primary); + text-transform: uppercase; + letter-spacing: 0.04em; +} + +.phrasal-term-row { + display: flex; + align-items: baseline; + gap: 6px; + flex-wrap: wrap; + margin-bottom: 2px; +} + +.phrasal-term { + font-size: 14px; + color: var(--text-main); +} + +.phrasal-raw { + font-size: 11px; + color: var(--text-muted); + font-style: italic; +} + +.phrasal-translation { + font-size: 12px; + font-weight: 600; + color: var(--success); + margin-bottom: 6px; + line-height: 1.35; +} + +.phrasal-card-actions { + display: flex; + gap: 6px; + margin-top: 4px; +} + +.phrasal-action-btn { + font-size: 11px; + padding: 3px 8px; + width: 100%; + justify-content: center; +} + +.popup-translation { + font-size: 15px; + font-weight: 600; + color: var(--success); + margin-bottom: 8px; +} + +.popup-context-box { + margin-bottom: 14px; +} + +.popup-context { + font-size: 12px; + color: var(--text-muted); + font-style: italic; + background: var(--bg-input); + padding: 8px 10px; + border-radius: var(--radius-sm); + margin-bottom: 6px; + line-height: 1.4; + border-left: 3px solid var(--primary); +} + +.popup-sentence-ai-bar { + display: flex; + align-items: center; + justify-content: space-between; + gap: 8px; + margin-bottom: 6px; +} + +.popup-sentence-btn { + font-size: 11px; + padding: 3px 8px; + cursor: pointer; + border-radius: var(--radius-sm); + display: inline-flex; + align-items: center; + gap: 4px; +} + +.popup-ai-source-badge { + font-size: 10px; + font-weight: 600; + color: var(--primary); + background: rgba(99, 102, 241, 0.12); + border: 1px solid rgba(99, 102, 241, 0.25); + padding: 2px 6px; + border-radius: 9999px; + letter-spacing: 0.02em; +} + +.popup-sentence-loading { + font-size: 11px; + color: var(--text-muted); + padding: 6px 8px; + display: flex; + align-items: center; + gap: 6px; + background: var(--bg-input); + border-radius: var(--radius-sm); + margin-bottom: 6px; +} + +.popup-sentence-translation-wrap { + background: rgba(99, 102, 241, 0.08); + border: 1px solid rgba(99, 102, 241, 0.2); + border-radius: var(--radius-sm); + padding: 8px 10px; + margin-bottom: 6px; + animation: fadeIn 0.15s ease-out; +} + +.popup-sentence-ru { + font-size: 13px; + line-height: 1.45; + color: var(--text-main); + margin-bottom: 6px; +} + +.popup-context-meaning-wrap { + display: flex; + align-items: center; + flex-wrap: wrap; + gap: 6px; + font-size: 11px; + padding-top: 6px; + border-top: 1px dashed rgba(99, 102, 241, 0.2); +} + +.context-meaning-label { + color: var(--text-muted); +} + +.context-meaning-val { + color: var(--success); + font-weight: 600; +} + +.use-meaning-btn { + font-size: 10px; + padding: 1px 6px; + color: var(--primary); + border: 1px solid var(--primary); + border-radius: 4px; + cursor: pointer; + background: transparent; +} + +.use-meaning-btn:hover { + background: rgba(99, 102, 241, 0.15); +} + +.popup-saved-badge { + text-align: center; + font-size: 13px; + font-weight: 600; + color: #f59e0b; + background: rgba(245, 158, 11, 0.12); + border: 1px solid rgba(245, 158, 11, 0.3); + border-radius: var(--radius-sm); + padding: 6px 10px; +} + +.popup-in-library-badge { + display: inline-flex; + align-items: center; + gap: 3px; + font-size: 11px; + font-weight: 600; + color: #f59e0b; + background: rgba(245, 158, 11, 0.15); + border: 1px solid rgba(245, 158, 11, 0.4); + padding: 2px 7px; + border-radius: 9999px; + margin-left: 6px; + letter-spacing: 0.02em; + vertical-align: middle; +} + +.badge-library-star { + display: inline-flex; + align-items: center; + gap: 4px; + font-size: 12px; + font-weight: 600; + color: #f59e0b; + background: rgba(245, 158, 11, 0.15); + border: 1px solid rgba(245, 158, 11, 0.4); + padding: 2px 8px; + border-radius: 9999px; + margin-left: 8px; + vertical-align: middle; +} + +/* ========================================================================== + Continuous Reading & Chapter End Navigation Card + ========================================================================== */ + +/* Chapter Divider (Between chapters in continuous / autoload mode) */ +.reader-chapter-divider { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + margin: 56px 0 36px; + padding: 24px 16px; + border-top: 1px dashed var(--border-color); + border-bottom: 1px dashed var(--border-color); + background: rgba(255, 255, 255, 0.02); + border-radius: var(--radius-md); + text-align: center; + scroll-margin-top: 60px; +} + +.reader-chapter-divider .divider-badge { + font-size: 11px; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.8px; + color: var(--primary); + background: var(--bg-input); + padding: 4px 12px; + border-radius: 9999px; + border: 1px solid var(--border-color); + margin-bottom: 10px; + display: inline-block; +} + +.reader-chapter-divider .divider-title { + font-size: 22px !important; + font-weight: 700; + color: var(--text-main); + margin: 0 !important; + border-bottom: none !important; + padding-bottom: 0 !important; + text-align: center; +} + +/* Chapter End Navigation Card */ +.reader-chapter-footer { + margin: 48px 0 64px; + padding: 24px 20px; + background: var(--bg-surface); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15); + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + gap: 14px; + transition: var(--transition); +} + +.reader-chapter-footer .chapter-footer-status { + display: flex; + align-items: center; + gap: 8px; + font-size: 14px; + font-weight: 600; + color: var(--text-muted); +} + +.reader-chapter-footer .chapter-footer-status .status-check { + display: inline-flex; + align-items: center; + justify-content: center; + width: 24px; + height: 24px; + border-radius: 50%; + background: rgba(34, 197, 94, 0.15); + color: var(--success); + font-size: 13px; + font-weight: 700; +} + +.reader-chapter-footer .chapter-footer-nav { + display: flex; + gap: 12px; + width: 100%; + max-width: 540px; + justify-content: center; + flex-wrap: wrap; +} + +.reader-chapter-footer .reader-footer-nav-btn { + flex: 1; + min-width: 150px; + min-height: 44px; + display: inline-flex; + align-items: center; + justify-content: center; + gap: 6px; + font-size: 14px; + font-weight: 600; + padding: 10px 18px; + border-radius: var(--radius-sm); + cursor: pointer; + transition: var(--transition); +} + +.reader-chapter-footer .chapter-footer-hint { + font-size: 12px; + color: var(--text-dim); + line-height: 1.4; + max-width: 480px; +} + +/* Book Completion Card */ +.reader-chapter-footer.reader-book-finished { + background: linear-gradient(180deg, rgba(56, 189, 248, 0.08) 0%, rgba(20, 24, 32, 0.95) 100%); + border-color: rgba(56, 189, 248, 0.35); +} + +.reader-chapter-footer.reader-book-finished .chapter-footer-hint { + color: var(--text-muted); + font-size: 13px; +} + +/* Reading Theme Adaptations */ +.reader-scroll-area.reader-theme-sepia .reader-chapter-divider, +.reader-scroll-area.reader-theme-light .reader-chapter-divider { + background: rgba(0, 0, 0, 0.025); + border-color: rgba(0, 0, 0, 0.12); +} + +.reader-scroll-area.reader-theme-sepia .reader-chapter-footer, +.reader-scroll-area.reader-theme-light .reader-chapter-footer { + background: rgba(0, 0, 0, 0.03); + border-color: rgba(0, 0, 0, 0.12); + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.06); +} + +.reader-scroll-area.reader-theme-oled .reader-chapter-divider { + background: #080808; + border-color: #222; +} + +.reader-scroll-area.reader-theme-oled .reader-chapter-footer { + background: #0c0c0c; + border-color: #222; +} + + +/* --- Responsive Mobile Overrides (max-width: 768px) --- */ +@media (max-width: 768px) { + /* 6. Bookshelf & Reader View */ + .reader-view { + padding: 14px 12px calc(76px + env(safe-area-inset-bottom, 0px)); + } + + .bookshelf-header { + flex-direction: column; + align-items: stretch; + gap: 12px; + margin-bottom: 18px; + } + + .bookshelf-title-wrap h2 { + font-size: 19px; + } + + .bookshelf-actions { + width: 100%; + display: flex; + gap: 8px; + } + + .bookshelf-actions .btn, + .bookshelf-actions .file-upload-label { + flex: 1; + justify-content: center; + text-align: center; + padding: 10px; + } + + .bookshelf-grid { + grid-template-columns: 1fr; + gap: 12px; + } + + .book-card { + padding: 14px; + } + + /* Reader Interface Toolbar */ + .reader-toolbar { + position: static !important; + top: auto !important; + box-shadow: none !important; + padding: 8px 10px; + gap: 8px; + flex-direction: column; + align-items: stretch; + } + + .reader-toolbar-left { + width: 100%; + justify-content: space-between; + gap: 8px; + } + + .reader-meta { + flex: 1; + min-width: 0; + } + + .reader-title { + font-size: 14px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + .reader-author { + font-size: 11px; + } + + .reader-toolbar-center { + width: 100%; + justify-content: space-between; + gap: 6px; + } + + .reader-select { + flex: 1; + max-width: none; + min-width: 0; + } + + .reader-toolbar-right { + width: 100%; + justify-content: space-between; + gap: 6px; + border-top: 1px solid var(--border-color); + padding-top: 6px; + } + + .reader-content-body { + padding: 14px 12px; + font-size: 17px; + line-height: 1.65; + } + + +} diff --git a/app/static/css/srs.css b/app/static/css/srs.css new file mode 100644 index 0000000..51e7498 --- /dev/null +++ b/app/static/css/srs.css @@ -0,0 +1,1311 @@ +/* ========================================================================== + 4. Spaced Repetition (SRS), 3D Flashcards, Quiz, Typing & Heatmap + ========================================================================== */ + +/* SRS View Structure */ +.srs-view { + min-height: calc(100vh - 65px); + display: flex; + flex-direction: column; + background: radial-gradient(circle at 50% 15%, rgba(56, 189, 248, 0.07), transparent 60%); +} + +.srs-topbar { + background-color: var(--bg-surface); + border-bottom: 1px solid var(--border-color); + padding: 12px 24px; + display: flex; + align-items: center; + justify-content: space-between; + gap: 16px; +} + +.srs-topbar-left { + display: flex; + align-items: center; + gap: 16px; +} + +.srs-mode-switch { + display: flex; + background-color: var(--bg-main); + padding: 3px; + border-radius: var(--radius-md); + border: 1px solid var(--border-color); +} + +.srs-tab { + background: transparent; + border: none; + color: var(--text-muted); + padding: 6px 14px; + border-radius: var(--radius-sm); + font-size: 13px; + font-weight: 600; + cursor: pointer; + transition: var(--transition); +} + +.srs-tab:hover { + color: var(--text-main); +} + +.srs-tab.active { + background-color: var(--primary); + color: #0f172a; + font-weight: 700; + box-shadow: var(--shadow-sm); +} + +.srs-topbar-center { + flex: 1; + max-width: 380px; + display: flex; + flex-direction: column; + align-items: center; + gap: 4px; +} + +.srs-progress-container { + width: 100%; + height: 7px; + background-color: var(--bg-main); + border-radius: var(--radius-full); + overflow: hidden; + border: 1px solid var(--border-color); +} + +.srs-progress-fill { + height: 100%; + background: linear-gradient(90deg, #0284c7, #38bdf8); + border-radius: var(--radius-full); + transition: width 0.3s ease; +} + +.srs-counter { + font-size: 11px; + font-weight: 600; + color: var(--text-dim); +} + +.srs-topbar-right { + display: flex; + align-items: center; +} + +.srs-arena { + flex: 1; + max-width: 720px; + width: 100%; + margin: 0 auto; + padding: 32px 16px; + display: flex; + flex-direction: column; + justify-content: center; +} + +.srs-state-box { + text-align: center; + padding: 64px 24px; + background-color: var(--bg-card); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + box-shadow: var(--shadow-md); + display: flex; + flex-direction: column; + align-items: center; + gap: 16px; +} + +.srs-big-icon { + font-size: 56px; +} + +.srs-empty-buttons { + display: flex; + gap: 12px; + flex-wrap: wrap; + justify-content: center; + margin-top: 12px; +} + +/* Flashcard 3D Card Flip */ +.srs-mode-container { + display: flex; + flex-direction: column; + gap: 20px; + animation: fadeIn 0.25s ease-out; +} + +.flashcard-wrapper { + perspective: 1400px; + min-height: 380px; + cursor: pointer; + user-select: none; +} + +.flashcard-inner { + position: relative; + width: 100%; + min-height: 380px; + transform-style: preserve-3d; + transition: transform 0.48s cubic-bezier(0.4, 0, 0.2, 1); +} + +.flashcard-inner.is-flipped { + transform: rotateY(180deg); +} + +.flashcard-face { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + min-height: 380px; + background-color: var(--bg-card); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + padding: 28px 32px; + box-shadow: var(--shadow-lg); + backface-visibility: hidden; + -webkit-backface-visibility: hidden; + display: flex; + flex-direction: column; + justify-content: space-between; +} + +.flashcard-front { + transform: rotateY(0deg); +} + +.flashcard-back { + transform: rotateY(180deg); + background: radial-gradient(circle at top right, rgba(56, 189, 248, 0.06), var(--bg-card) 70%); +} + +.fc-badge-row { + display: flex; + justify-content: space-between; + align-items: center; +} + +.fc-dir-badge { + font-size: 11px; + font-weight: 700; + letter-spacing: 0.5px; + color: var(--primary); + background-color: var(--primary-dim); + padding: 3px 10px; + border-radius: var(--radius-full); +} + +.fc-pos-badge { + font-size: 11px; + color: var(--text-dim); + background-color: var(--bg-surface-hover); + padding: 2px 8px; + border-radius: 4px; +} + +.fc-center { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + text-align: center; + gap: 16px; + padding: 20px 0; +} + +.fc-main-term { + font-size: 38px; + font-weight: 800; + letter-spacing: -0.5px; + color: var(--text-main); +} + +.fc-phonetic-row { + display: flex; + align-items: center; + gap: 10px; +} + +.audio-round-btn { + width: 36px; + height: 36px; + border-radius: 50%; + display: inline-flex; + align-items: center; + justify-content: center; + background-color: var(--primary-dim); + border: 1px solid var(--primary); + color: var(--primary); + font-size: 16px; + cursor: pointer; + transition: var(--transition); +} + +.audio-round-btn:hover { + background-color: var(--primary); + color: #0f172a; + transform: scale(1.08); +} + +.fc-hint-wrapper { + display: flex; + flex-direction: column; + align-items: center; + gap: 8px; + max-width: 500px; +} + +.fc-hint-content { + font-size: 14px; + font-style: italic; + color: var(--text-muted); + background-color: var(--bg-main); + padding: 10px 16px; + border-radius: var(--radius-sm); + border-left: 3px solid var(--primary); +} + +.fc-footer-hint { + text-align: center; + font-size: 12px; + color: var(--text-dim); +} + +.fc-footer-hint kbd { + background-color: var(--bg-surface-hover); + border: 1px solid var(--border-color); + padding: 2px 6px; + border-radius: 4px; + font-family: monospace; +} + +/* Flashcard Back */ +.fc-back-content { + display: flex; + flex-direction: column; + gap: 14px; + height: 100%; +} + +.fc-back-top { + display: flex; + justify-content: space-between; + align-items: center; + border-bottom: 1px solid var(--border-color); + padding-bottom: 8px; +} + +.fc-back-term { + font-size: 24px; + font-weight: 700; + color: var(--text-main); +} + +.fc-back-translation { + font-size: 22px; + font-weight: 700; + color: var(--primary); +} + +.fc-back-detail-box { + background-color: var(--bg-main); + border-radius: var(--radius-sm); + padding: 10px 14px; + border-left: 2px solid var(--border-color); +} + +.detail-label { + font-size: 10px; + font-weight: 700; + text-transform: uppercase; + color: var(--text-dim); + letter-spacing: 0.5px; + margin-bottom: 2px; + display: block; +} + +.detail-text { + font-size: 13px; + color: var(--text-main); + line-height: 1.4; +} + +.fc-flip-btn-wrap { + display: none; +} + +/* SRS Rating Bar */ +.srs-rating-bar { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 12px; + margin-top: 8px; + animation: fadeIn 0.2s ease-out; +} + +.btn-rate { + padding: 12px 10px; + border-radius: var(--radius-md); + border: 1px solid var(--border-color); + background-color: var(--bg-surface); + cursor: pointer; + display: flex; + flex-direction: column; + align-items: center; + gap: 2px; + transition: var(--transition); +} + +.btn-rate .rate-key { + font-size: 11px; + font-family: monospace; + opacity: 0.7; +} + +.btn-rate .rate-name { + font-size: 15px; + font-weight: 700; +} + +.btn-rate .rate-time { + font-size: 11px; + opacity: 0.75; +} + +/* Rating variants */ +.btn-rate-1 { + border-color: rgba(239, 68, 68, 0.4); + color: #f87171; +} +.btn-rate-1:hover { + background-color: rgba(239, 68, 68, 0.15); + border-color: #ef4444; +} + +.btn-rate-2 { + border-color: rgba(245, 158, 11, 0.4); + color: #fbbf24; +} +.btn-rate-2:hover { + background-color: rgba(245, 158, 11, 0.15); + border-color: #f59e0b; +} + +.btn-rate-3 { + border-color: rgba(56, 189, 248, 0.4); + color: #38bdf8; +} +.btn-rate-3:hover { + background-color: rgba(56, 189, 248, 0.15); + border-color: #38bdf8; +} + +.btn-rate-4 { + border-color: rgba(16, 185, 129, 0.4); + color: #34d399; +} +.btn-rate-4:hover { + background-color: rgba(16, 185, 129, 0.15); + border-color: #10b981; +} + +/* Interactive Trainer Card (Cloze & Dictation) */ +.trainer-card { + background-color: var(--bg-card); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + padding: 32px; + box-shadow: var(--shadow-lg); + display: flex; + flex-direction: column; + gap: 20px; +} + +.trainer-header { + display: flex; + justify-content: space-between; + align-items: center; +} + +.mode-tag { + font-size: 12px; + font-weight: 700; + color: var(--primary); + background-color: var(--primary-dim); + padding: 3px 12px; + border-radius: var(--radius-full); +} + +.trainer-pos { + font-size: 12px; + color: var(--text-dim); +} + +.cloze-sentence-display { + font-size: 20px; + line-height: 1.6; + color: var(--text-main); + background-color: var(--bg-main); + padding: 20px 24px; + border-radius: var(--radius-md); + border-left: 4px solid var(--primary); +} + +.gap-placeholder { + color: var(--primary); + font-weight: 800; + letter-spacing: 2px; + border-bottom: 2px dashed var(--primary); + padding: 0 4px; +} + +.cloze-translation-hint { + font-size: 14px; + color: var(--text-muted); +} + +.cloze-translation-hint strong { + color: var(--text-main); + margin-left: 6px; +} + +.trainer-form { + display: flex; + flex-direction: column; + gap: 12px; +} + +.input-action-row { + display: flex; + gap: 10px; +} + +.input-hero { + font-size: 18px; + padding: 12px 18px; +} + +.trainer-feedback-box { + padding: 14px 18px; + border-radius: var(--radius-sm); + font-size: 15px; + font-weight: 600; + animation: fadeIn 0.2s ease-out; +} + +.trainer-feedback-box.correct { + background-color: var(--success-dim); + border: 1px solid var(--success); + color: #34d399; +} + +.trainer-feedback-box.incorrect { + background-color: var(--danger-dim); + border: 1px solid var(--danger); + color: #fca5a5; +} + +.trainer-revealed-details { + background-color: var(--bg-main); + border-radius: var(--radius-md); + padding: 16px; + display: flex; + flex-direction: column; + gap: 10px; + border: 1px solid var(--border-color); + animation: fadeIn 0.2s ease-out; +} + +/* Audio Dictation Mode */ +.dictation-hero { + display: flex; + flex-direction: column; + align-items: center; + gap: 14px; + padding: 16px 0; +} + +.dictation-pulse-btn { + width: 80px; + height: 80px; + border-radius: 50%; + background: linear-gradient(135deg, #0284c7, #38bdf8); + border: none; + color: #0f172a; + font-size: 34px; + cursor: pointer; + box-shadow: 0 0 0 0 rgba(56, 189, 248, 0.4); + animation: pulseAudio 2s infinite; + display: flex; + align-items: center; + justify-content: center; + transition: var(--transition); +} + +.dictation-pulse-btn:hover { + transform: scale(1.08); +} + +@keyframes pulseAudio { + 0% { box-shadow: 0 0 0 0 rgba(56, 189, 248, 0.6); } + 70% { box-shadow: 0 0 0 22px rgba(56, 189, 248, 0); } + 100% { box-shadow: 0 0 0 0 rgba(56, 189, 248, 0); } +} + +.dictation-instructions { + font-size: 14px; + color: var(--text-muted); +} + +.audio-replay-btn .kbd-sub { + font-size: 10px; + margin-left: 4px; +} + +.dictation-hint-wrap { + display: flex; + align-items: center; + gap: 10px; +} + +.dictation-hint-text { + font-size: 13px; + color: var(--text-muted); + font-style: italic; +} + +/* Interactive Listening Comprehension Mode */ +.listening-card { + background-color: var(--bg-card); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + padding: 28px 32px; + box-shadow: var(--shadow-lg); + display: flex; + flex-direction: column; + gap: 20px; +} + +.listening-header-row { + display: flex; + justify-content: space-between; + align-items: center; + flex-wrap: wrap; + gap: 12px; +} + +.listening-tag-wrap { + display: flex; + align-items: center; + gap: 8px; + flex-wrap: wrap; +} + +.level-badge { + font-size: 11px; + font-weight: 700; + padding: 2px 8px; + border-radius: var(--radius-sm); + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.level-badge.badge-a1 { background: rgba(59, 130, 246, 0.15); color: #60a5fa; border: 1px solid rgba(59, 130, 246, 0.3); } +.level-badge.badge-a2 { background: rgba(16, 185, 129, 0.15); color: #34d399; border: 1px solid rgba(16, 185, 129, 0.3); } +.level-badge.badge-b1 { background: rgba(245, 158, 11, 0.15); color: #fbbf24; border: 1px solid rgba(245, 158, 11, 0.3); } +.level-badge.badge-b2 { background: rgba(249, 115, 22, 0.15); color: #fb923c; border: 1px solid rgba(249, 115, 22, 0.3); } +.level-badge.badge-c1 { background: rgba(168, 85, 247, 0.15); color: #c084fc; border: 1px solid rgba(168, 85, 247, 0.3); } + +.topic-badge { + font-size: 11px; + font-weight: 600; + color: var(--text-dim); + background: var(--bg-main); + border: 1px solid var(--border-color); + padding: 2px 8px; + border-radius: var(--radius-sm); +} + +.listening-filters { + display: flex; + align-items: center; + gap: 8px; + flex-wrap: wrap; +} + +.select-styled { + background-color: var(--bg-main); + border: 1px solid var(--border-color); + border-radius: var(--radius-sm); + color: var(--text-main); + padding: 6px 10px; + font-size: 13px; + outline: none; + cursor: pointer; + transition: var(--transition); +} + +.select-styled:focus { + border-color: var(--primary); + box-shadow: 0 0 0 2px var(--primary-dim); +} + +.select-xs { + font-size: 12px; + padding: 4px 8px; +} + +.listening-hero { + background: linear-gradient(180deg, var(--bg-card) 0%, var(--bg-main) 100%); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + padding: 20px 24px; + display: flex; + flex-direction: column; + gap: 16px; +} + +.listening-scenario-title { + font-size: 18px; + font-weight: 700; + color: var(--text-main); + margin: 0 0 4px 0; +} + +.listening-subtitle { + font-size: 13px; + color: var(--text-muted); + margin: 0; +} + +.listening-audio-controls { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 16px; + margin-top: 4px; +} + +@media (max-width: 600px) { + .listening-audio-controls { + grid-template-columns: 1fr; + } +} + +.audio-control-card { + background: var(--bg-card); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + padding: 14px 16px; + display: flex; + flex-direction: column; + gap: 8px; + transition: var(--transition); +} + +.audio-control-card:hover { + border-color: var(--primary-dim); +} + +.audio-control-label { + font-size: 12px; + font-weight: 600; + color: var(--text-dim); +} + +.listening-play-btn { + width: 100%; + justify-content: center; + font-weight: 600; + display: inline-flex; + align-items: center; + gap: 8px; +} + +.listening-hint-bar { + display: flex; + align-items: center; + gap: 12px; +} + +.listening-hint-text { + font-size: 13px; + color: var(--text-muted); + font-style: italic; + background: var(--bg-main); + border-left: 3px solid var(--primary); + padding: 4px 10px; + border-radius: 0 var(--radius-sm) var(--radius-sm) 0; +} + +.listening-form { + display: flex; + flex-direction: column; + gap: 12px; +} + +.listening-revealed-card { + background-color: var(--bg-main); + border: 1px solid var(--border-color); + border-left: 4px solid var(--primary); + border-radius: var(--radius-md); + padding: 20px; + display: flex; + flex-direction: column; + gap: 16px; + animation: fadeIn 0.25s ease-out; +} + +.revealed-section { + display: flex; + flex-direction: column; + gap: 4px; +} + +.revealed-label { + font-size: 12px; + font-weight: 700; + color: var(--text-dim); + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.revealed-val { + font-size: 16px; + color: #34d399; +} + +.revealed-text { + font-size: 15px; + line-height: 1.5; + color: var(--text-main); + margin: 0; +} + +.listening-next-bar { + display: flex; + justify-content: flex-end; + margin-top: 8px; + padding-top: 12px; + border-top: 1px solid var(--border-color); +} + + +/* Summary Card */ +.srs-summary-card { + background-color: var(--bg-card); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + padding: 44px 32px; + text-align: center; + display: flex; + flex-direction: column; + align-items: center; + gap: 20px; + box-shadow: var(--shadow-lg); + animation: fadeIn 0.3s ease-out; +} + +.summary-trophy { + font-size: 64px; + animation: bounce 0.6s ease; +} + +@keyframes bounce { + 0%, 100% { transform: translateY(0); } + 50% { transform: translateY(-16px); } +} + +.srs-summary-card h2 { + font-size: 28px; + font-weight: 800; +} + +.summary-lead { + font-size: 15px; + color: var(--text-muted); + max-width: 480px; +} + +.summary-metrics { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 16px; + width: 100%; + margin: 12px 0; +} + +.metric-card { + background-color: var(--bg-main); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + padding: 16px 12px; + display: flex; + flex-direction: column; + align-items: center; + gap: 4px; +} + +.metric-val { + font-size: 28px; + font-weight: 800; +} + +.metric-desc { + font-size: 11px; + color: var(--text-dim); +} + +.text-success { color: var(--success); } +.text-primary { color: var(--primary); } + +.summary-rates-bar { + display: flex; + gap: 12px; + font-size: 13px; + color: var(--text-muted); + flex-wrap: wrap; + justify-content: center; +} + +.summary-buttons { + display: flex; + gap: 14px; + margin-top: 12px; + flex-wrap: wrap; + justify-content: center; +} + + +/* Multiple Choice Quiz Mode */ +.quiz-card { + max-width: 680px; + margin: 0 auto; +} + +.quiz-hero { + text-align: center; + padding: 20px 0 16px 0; + border-bottom: 1px solid var(--border-color); + margin-bottom: 20px; +} + +.quiz-prompt-row { + display: flex; + align-items: center; + justify-content: center; + gap: 12px; +} + +.quiz-term-display { + font-size: 32px; + font-weight: 800; + color: var(--text-main); + letter-spacing: -0.02em; +} + +.quiz-context-hint { + margin-top: 8px; + font-size: 14px; + color: var(--text-muted); + font-style: italic; +} + +.quiz-options-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 14px; + margin-bottom: 16px; +} + +.quiz-option-btn { + display: flex; + align-items: center; + gap: 12px; + padding: 16px 18px; + background: var(--bg-main); + border: 2px solid var(--border-color); + border-radius: var(--radius-md); + color: var(--text-main); + font-size: 15px; + font-weight: 600; + text-align: left; + cursor: pointer; + transition: all 0.15s ease; + user-select: none; +} + +.quiz-option-btn:hover:not(:disabled) { + border-color: var(--primary); + background: var(--bg-surface-hover); + transform: translateY(-1px); +} + +.quiz-option-btn:disabled { + cursor: default; +} + +.quiz-opt-num { + width: 26px; + height: 26px; + border-radius: 50%; + background: var(--bg-surface); + border: 1px solid var(--border-color); + display: inline-flex; + align-items: center; + justify-content: center; + font-size: 12px; + font-weight: 700; + color: var(--text-muted); + flex-shrink: 0; +} + +.quiz-opt-text { + flex: 1; + line-height: 1.35; +} + +.quiz-option-btn.opt-correct { + background: rgba(34, 197, 94, 0.15) !important; + border-color: var(--success) !important; + color: var(--success) !important; +} + +.quiz-option-btn.opt-correct .quiz-opt-num { + background: var(--success); + color: #ffffff; + border-color: var(--success); +} + +.quiz-option-btn.opt-wrong { + background: rgba(239, 68, 68, 0.15) !important; + border-color: var(--danger) !important; + color: var(--danger) !important; + animation: shake 0.3s ease; +} + +.quiz-option-btn.opt-wrong .quiz-opt-num { + background: var(--danger); + color: #ffffff; + border-color: var(--danger); +} + +.quiz-next-bar { + margin-top: 16px; +} + +/* Active Typing Mode */ +.typing-hero { + text-align: center; + padding: 16px 0 20px 0; +} + +.typing-prompt-ru { + font-size: 28px; + font-weight: 800; + color: var(--primary); + margin: 8px 0; +} + +.typing-context-hint { + font-size: 14px; + color: var(--text-muted); + font-style: italic; + background: var(--bg-main); + padding: 8px 12px; + border-radius: var(--radius-sm); + display: inline-block; + max-width: 90%; + margin-top: 4px; +} + + +/* Analytics & Activity Heatmap Modal */ +.stats-modal-window { + max-width: 820px; + width: 95%; +} + +.stats-hero-grid { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 12px; + margin-bottom: 24px; +} + +.stat-kpi-card { + background: var(--bg-main); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + padding: 14px 12px; + text-align: center; + display: flex; + flex-direction: column; + align-items: center; + gap: 4px; +} + +.streak-kpi { + border-color: rgba(249, 115, 22, 0.4); + background: rgba(249, 115, 22, 0.05); +} + +.kpi-icon { + font-size: 24px; +} + +.kpi-value { + font-size: 26px; + font-weight: 800; + line-height: 1.1; +} + +.kpi-label { + font-size: 12px; + font-weight: 600; + color: var(--text-muted); +} + +.kpi-sub { + font-size: 11px; + color: var(--text-dim); +} + +.text-accent { + color: #38bdf8; +} + +/* GitHub Heatmap Section */ +.heatmap-section { + background: var(--bg-main); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + padding: 16px; + margin-bottom: 20px; +} + +.heatmap-header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 14px; + flex-wrap: wrap; + gap: 8px; +} + +.heatmap-header h4 { + font-size: 15px; + font-weight: 700; +} + +.heatmap-legend { + display: flex; + align-items: center; + gap: 5px; + font-size: 11px; + color: var(--text-dim); +} + +.legend-cell { + width: 12px; + height: 12px; + border-radius: 2px; + display: inline-block; +} + +.heatmap-container-wrap { + overflow-x: auto; + padding-bottom: 6px; +} + +.heatmap-grid { + display: grid; + grid-auto-flow: column; + grid-template-rows: repeat(7, 12px); + gap: 4px; + min-width: 600px; +} + +.heatmap-cell { + width: 12px; + height: 12px; + border-radius: 2px; + background: rgba(255, 255, 255, 0.05); + cursor: pointer; + transition: transform 0.1s ease; + position: relative; +} + +.heatmap-cell:hover { + transform: scale(1.3); + z-index: 10; + outline: 1px solid var(--text-main); +} + +/* Heatmap Levels (GitHub-style intensity) */ +.lvl-0 { background: rgba(255, 255, 255, 0.06); } +.lvl-1 { background: #166534; } /* 1 review: soft green */ +.lvl-2 { background: #22c55e; } /* 2-3 reviews: vibrant green */ +.lvl-3 { background: #4ade80; } /* 4+ reviews: bright intense green */ + +[data-theme="light"] .lvl-0 { background: #e2e8f0; } +[data-theme="light"] .lvl-1 { background: #86efac; } +[data-theme="light"] .lvl-2 { background: #22c55e; } +[data-theme="light"] .lvl-3 { background: #15803d; } + +.heatmap-footer-note { + margin-top: 10px; + color: var(--text-dim); + font-size: 11px; +} + +/* Segmented Mastery Progress Bar */ +.mastery-section { + background: var(--bg-main); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + padding: 16px; +} + +.mastery-section h4 { + font-size: 15px; + font-weight: 700; + margin-bottom: 12px; +} + +.segmented-progress-bar { + display: flex; + height: 14px; + background: var(--bg-surface); + border-radius: var(--radius-full); + overflow: hidden; + margin-bottom: 12px; + border: 1px solid var(--border-color); +} + +.prog-segment { + height: 100%; + transition: width 0.3s ease; +} + +.seg-mastered { background: #22c55e; } +.seg-review { background: #38bdf8; } +.seg-learning { background: #f59e0b; } +.seg-new { background: #64748b; } + +.mastery-legend-row { + display: flex; + gap: 16px; + flex-wrap: wrap; + font-size: 12px; +} + +.m-legend-item { + display: flex; + align-items: center; + gap: 6px; + color: var(--text-muted); +} + +.dot { + width: 8px; + height: 8px; + border-radius: 50%; + display: inline-block; +} + +.dot-mastered { background: #22c55e; } +.dot-review { background: #38bdf8; } +.dot-learning { background: #f59e0b; } +.dot-new { background: #64748b; } +.dot-leech { background: #ef4444; } + +.text-danger { color: #ef4444; } + +@keyframes shake { + 0%, 100% { transform: translateX(0); } + 25% { transform: translateX(-4px); } + 75% { transform: translateX(4px); } +} + + +/* --- Responsive Mobile Overrides (max-width: 768px) --- */ +@media (max-width: 768px) { + /* 5. SRS Trainer */ + .srs-topbar { + padding: 10px 12px; + flex-direction: column; + align-items: stretch; + gap: 8px; + } + + .srs-topbar-left, .srs-topbar-right { + justify-content: space-between; + width: 100%; + } + + .srs-mode-switch { + overflow-x: auto; + -webkit-overflow-scrolling: touch; + scrollbar-width: none; + } + + .srs-mode-switch::-webkit-scrollbar { + display: none; + } + + .srs-tab { + flex-shrink: 0; + padding: 6px 10px; + font-size: 12px; + } + + .flashcard-wrapper { + min-height: 270px; + max-height: 48dvh; + } + + .flashcard-inner { + min-height: 270px; + } + + .fc-main-term { + font-size: 28px; + } + + .fc-footer-hint { + font-size: 11px; + } + + .srs-rating-bar { + grid-template-columns: 1fr 1fr; + gap: 8px; + width: 100%; + } + + .btn-rate { + min-height: 48px; + padding: 8px 6px; + } + + .rate-key { + display: none; + } + + .quiz-options-grid { + grid-template-columns: 1fr; + gap: 8px; + } + + .quiz-option-btn { + min-height: 48px; + font-size: 14px; + padding: 10px 14px; + } + + +} diff --git a/app/static/css/style.css b/app/static/css/style.css index 4b83906..c14e843 100644 --- a/app/static/css/style.css +++ b/app/static/css/style.css @@ -1,8746 +1,35 @@ -/* Modern CSS Design System for Notes App */ -:root { - --bg-main: #0f172a; - --bg-surface: #1e293b; - --bg-surface-hover: #334155; - --bg-card: #1e293b; - --bg-input: #0f172a; - --border-color: #334155; - --border-focus: #38bdf8; - - --text-main: #f8fafc; - --text-muted: #94a3b8; - --text-dim: #64748b; - - --primary: #38bdf8; - --primary-hover: #0ea5e9; - --primary-dim: rgba(56, 189, 248, 0.15); - - --success: #10b981; - --success-hover: #059669; - --success-dim: rgba(16, 185, 129, 0.15); - - --danger: #ef4444; - --danger-hover: #dc2626; - --danger-dim: rgba(239, 68, 68, 0.15); - - --tag-bg: #293548; - --tag-text: #7dd3fc; - - --radius-sm: 6px; - --radius-md: 10px; - --radius-lg: 14px; - --radius-full: 9999px; - - --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.2); - --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.3), 0 2px 4px -2px rgba(0, 0, 0, 0.3); - --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.4), 0 4px 6px -4px rgba(0, 0, 0, 0.4); - - --font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif; - --transition: all 0.18s ease-in-out; - - --sat: env(safe-area-inset-top, 0px); - --sar: env(safe-area-inset-right, 0px); - --sab: env(safe-area-inset-bottom, 0px); - --sal: env(safe-area-inset-left, 0px); - --navbar-height: 60px; -} - -[data-theme="light"] { - --bg-main: #f1f5f9; - --bg-surface: #ffffff; - --bg-surface-hover: #f8fafc; - --bg-card: #ffffff; - --bg-input: #f8fafc; - --border-color: #cbd5e1; - --border-focus: #0284c7; - - --text-main: #0f172a; - --text-muted: #475569; - --text-dim: #94a3b8; - - --primary: #0284c7; - --primary-hover: #0369a1; - --primary-dim: rgba(2, 132, 199, 0.1); - - --success: #059669; - --success-hover: #047857; - --success-dim: rgba(5, 150, 105, 0.1); - - --tag-bg: #e2e8f0; - --tag-text: #0369a1; - - --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05); - --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.08); - --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1); -} - -* { - box-sizing: border-box; - margin: 0; - padding: 0; -} - -html, body { - overflow-x: clip; - -webkit-tap-highlight-color: transparent; -} - -body { - background-color: var(--bg-main); - color: var(--text-main); - font-family: var(--font-family); - line-height: 1.5; - -webkit-font-smoothing: antialiased; - min-height: 100vh; - min-height: 100dvh; -} - -.hidden { - display: none !important; -} - -/* Auth Screen / Login Overlay */ -.auth-screen, -.login-overlay { - position: fixed; - inset: 0; - z-index: 10000; - min-height: 100vh; - display: flex; - align-items: center; - justify-content: center; - padding: 20px; - background-color: var(--bg-main); - background-image: radial-gradient(circle at top, rgba(56, 189, 248, 0.15), transparent 70%); -} - -.auth-card, -.login-card { - background-color: var(--bg-surface); - border: 1px solid var(--border-color); - border-radius: var(--radius-lg); - padding: 36px 32px; - width: 100%; - max-width: 420px; - box-shadow: var(--shadow-lg); - animation: fadeInScale 0.2s ease-out; -} - -@keyframes fadeInScale { - from { - opacity: 0; - transform: scale(0.96); - } - to { - opacity: 1; - transform: scale(1); - } -} - -.auth-header, -.login-header { - text-align: center; - margin-bottom: 28px; -} - -.auth-header .app-logo, -.login-header .login-logo { - font-size: 48px; - margin-bottom: 8px; - display: block; -} - -.auth-header h2, -.login-header h1 { - font-size: 24px; - font-weight: 700; - color: var(--text-main); -} - -.auth-header p, -.login-header p { - color: var(--text-muted); - font-size: 14px; - margin-top: 4px; -} - -.login-form { - display: flex; - flex-direction: column; -} - -.login-error { - background-color: var(--danger-dim); - color: var(--danger); - border: 1px solid var(--danger); - padding: 10px 14px; - border-radius: var(--radius-sm); - font-size: 13px; - margin-bottom: 16px; - text-align: center; -} - -.auth-footer, -.login-footer { - margin-top: 24px; - text-align: center; - font-size: 12px; - color: var(--text-dim); -} - -.form-group { - margin-bottom: 18px; -} - -.form-group label { - display: block; - font-size: 13px; - font-weight: 600; - color: var(--text-muted); - margin-bottom: 6px; -} - -.form-group input { - width: 100%; - padding: 12px 14px; - background-color: var(--bg-input); - border: 1px solid var(--border-color); - border-radius: var(--radius-sm); - color: var(--text-main); - font-size: 15px; - outline: none; - transition: var(--transition); -} - -.form-group input:focus { - border-color: var(--border-focus); - box-shadow: 0 0 0 3px var(--primary-dim); -} - -.error-banner { - background-color: var(--danger-dim); - border: 1px solid var(--danger); - color: #fca5a5; - padding: 10px 14px; - border-radius: var(--radius-sm); - font-size: 13px; - margin-bottom: 16px; -} - -.success-banner { - background-color: var(--success-dim, rgba(16, 185, 129, 0.15)); - border: 1px solid var(--success, #10b981); - color: #86efac; - padding: 10px 14px; - border-radius: var(--radius-sm); - font-size: 13px; - margin-bottom: 16px; -} - -/* App Navbar */ -.app-container { - display: flex; - flex-direction: column; - min-height: 100vh; -} - -/* App Navbar (Unified Layout) */ -.navbar { - background-color: var(--bg-surface); - border-bottom: 1px solid var(--border-color); - padding: 8px 20px; - display: flex; - align-items: center; - justify-content: space-between; - gap: 16px; - position: sticky; - top: 0; - z-index: 100; - min-height: var(--navbar-height); - box-sizing: border-box; -} - -.nav-left { - display: flex; - align-items: center; - gap: 10px; - flex-shrink: 0; -} - -.drawer-toggle-btn { - display: inline-flex; - align-items: center; - justify-content: center; - width: 36px; - height: 36px; - border-radius: var(--radius-sm); - background-color: transparent; - border: 1px solid transparent; - color: var(--text-main); - cursor: pointer; - font-size: 20px; - line-height: 1; - transition: var(--transition); -} - -.drawer-toggle-btn:hover { - background-color: var(--bg-surface-hover); - border-color: var(--border-color); - color: var(--primary); -} - -.nav-brand { - display: flex; - align-items: center; - gap: 8px; - cursor: pointer; - user-select: none; - transition: opacity 0.15s ease; -} - -.nav-brand:hover { - opacity: 0.85; -} - -.brand-icon { - font-size: 24px; -} - -.brand-title { - font-size: 20px; - font-weight: 800; - color: var(--text-main); - letter-spacing: -0.5px; -} - -.brand-sub { - font-size: 12px; - background-color: var(--primary-dim); - color: var(--primary); - padding: 2px 8px; - border-radius: var(--radius-full); - font-weight: 600; - margin-left: 4px; -} - -.nav-center { - display: flex; - align-items: center; - justify-content: center; - gap: 14px; - flex: 1; - min-width: 0; -} - -.nav-stats { - display: flex; - gap: 8px; -} - -.stat-badge { - font-size: 13px; - background-color: var(--bg-main); - border: 1px solid var(--border-color); - padding: 4px 12px; - border-radius: var(--radius-full); - color: var(--text-muted); -} - -.stat-badge strong { - color: var(--text-main); -} - -.stat-badge.stat-today strong { - color: var(--success); -} - -.nav-actions { - display: flex; - align-items: center; - gap: 10px; - flex-shrink: 0; -} - -.user-profile-btn { - display: inline-flex; - align-items: center; - gap: 8px; - padding: 5px 12px; - border-radius: var(--radius-full); - background-color: var(--bg-surface-hover); - border: 1px solid var(--border-color); - color: var(--text-main); - font-size: 13px; - font-weight: 600; - cursor: pointer; - transition: var(--transition); -} - -.user-profile-btn:hover { - border-color: var(--primary); - color: var(--primary); - background-color: var(--primary-dim); -} - -.user-avatar-icon { - font-size: 15px; -} - -.user-badge { - font-size: 13px; - color: var(--text-main); - font-weight: 600; -} - -/* ----------------------------------------------------------------------- - Unified Navigation Drawer (Desktop & Mobile) - ----------------------------------------------------------------------- */ -.drawer-backdrop { - position: fixed; - top: 0; - left: 0; - width: 100vw; - height: 100vh; - background-color: rgba(0, 0, 0, 0.65); - backdrop-filter: blur(4px); - -webkit-backdrop-filter: blur(4px); - z-index: 1999; - opacity: 0; - pointer-events: none; - transition: opacity 0.26s cubic-bezier(0.16, 1, 0.3, 1); -} - -.drawer-backdrop.active { - opacity: 1; - pointer-events: auto; -} - -.app-drawer { - position: fixed; - top: 0; - left: 0; - bottom: 0; - width: min(340px, 86vw); - background-color: var(--bg-surface); - border-right: 1px solid var(--border-color); - box-shadow: 4px 0 28px rgba(0, 0, 0, 0.5); - z-index: 2000; - display: flex; - flex-direction: column; - transform: translateX(-100%); - transition: transform 0.28s cubic-bezier(0.16, 1, 0.3, 1); - will-change: transform; - overflow-y: auto; - -webkit-overflow-scrolling: touch; -} - -.app-drawer.active { - transform: translateX(0); -} - -body.drawer-open { - overflow: hidden !important; -} - -.drawer-header { - display: flex; - align-items: center; - justify-content: space-between; - padding: calc(16px + env(safe-area-inset-top, 0px)) 16px 14px 18px; - border-bottom: 1px solid var(--border-color); - background-color: var(--bg-surface); - position: sticky; - top: 0; - z-index: 10; -} - -.drawer-user-card { - display: flex; - align-items: center; - gap: 12px; - min-width: 0; -} - -.drawer-user-avatar { - width: 42px; - height: 42px; - border-radius: var(--radius-full); - background: linear-gradient(135deg, var(--primary), #6366f1); - color: #ffffff; - display: flex; - align-items: center; - justify-content: center; - font-size: 20px; - flex-shrink: 0; - box-shadow: var(--shadow-sm); -} - -.drawer-user-info { - display: flex; - flex-direction: column; - min-width: 0; -} - -.drawer-user-name { - font-size: 15px; - font-weight: 700; - color: var(--text-main); - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -.drawer-user-desc { - font-size: 12px; - color: var(--text-muted); - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -.drawer-close-btn { - width: 34px; - height: 34px; - border-radius: var(--radius-sm); - display: flex; - align-items: center; - justify-content: center; - font-size: 18px; - color: var(--text-muted); - background: transparent; - border: none; - cursor: pointer; - transition: var(--transition); -} - -.drawer-close-btn:hover { - background-color: var(--bg-surface-hover); - color: var(--text-main); -} - -.drawer-stats-summary { - display: grid; - grid-template-columns: repeat(3, 1fr); - gap: 8px; - padding: 12px 14px; - margin: 12px 14px 4px 14px; - background-color: var(--bg-main); - border: 1px solid var(--border-color); - border-radius: var(--radius-md); - text-align: center; -} - -.drawer-stat-item { - display: flex; - flex-direction: column; - gap: 2px; -} - -.drawer-stat-val { - font-size: 16px; - font-weight: 800; - color: var(--text-main); -} - -.drawer-stat-lbl { - font-size: 10px; - font-weight: 600; - color: var(--text-dim); - text-transform: uppercase; - letter-spacing: 0.3px; -} - -.drawer-nav { - flex: 1; - padding: 8px 12px; - display: flex; - flex-direction: column; - gap: 4px; -} - -.drawer-section-title { - font-size: 11px; - font-weight: 700; - text-transform: uppercase; - letter-spacing: 0.6px; - color: var(--text-dim); - padding: 12px 8px 4px 8px; -} - -.drawer-nav-list { - list-style: none; - padding: 0; - margin: 0; - display: flex; - flex-direction: column; - gap: 3px; -} - -.drawer-nav-item { - width: 100%; - display: flex; - align-items: center; - gap: 12px; - padding: 10px 12px; - border-radius: var(--radius-sm); - background: transparent; - border: 1px solid transparent; - color: var(--text-main); - font-size: 14px; - font-weight: 500; - text-align: left; - cursor: pointer; - transition: var(--transition); - text-decoration: none; -} - -.drawer-nav-item:hover { - background-color: var(--bg-surface-hover); - color: var(--primary); - border-color: var(--border-color); -} - -.drawer-nav-item.active { - background-color: var(--primary-dim); - color: var(--primary); - border-color: rgba(56, 189, 248, 0.3); - font-weight: 700; -} - -.drawer-item-icon { - font-size: 18px; - width: 24px; - text-align: center; - flex-shrink: 0; -} - -.drawer-item-label { - flex: 1; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - -.drawer-badge { - padding: 2px 7px; - font-size: 11px; - font-weight: 700; - border-radius: var(--radius-full); - background-color: var(--primary); - color: #0f172a; - line-height: 1.2; -} - -.drawer-footer { - padding: 14px 16px calc(14px + env(safe-area-inset-bottom, 0px)) 16px; - border-top: 1px solid var(--border-color); - font-size: 12px; - color: var(--text-dim); - text-align: center; -} - -/* Buttons */ -.btn { - display: inline-flex; - align-items: center; - justify-content: center; - gap: 6px; - padding: 10px 18px; - border-radius: var(--radius-sm); - font-size: 14px; - font-weight: 600; - cursor: pointer; - border: none; - transition: var(--transition); -} - -.btn-primary { - background-color: var(--primary); - color: #0f172a; -} - -.btn-primary:hover { - background-color: var(--primary-hover); -} - -.btn-success { - background-color: var(--success); - color: #ffffff; -} - -.btn-success:hover { - background-color: var(--success-hover); -} - -.btn-outline { - background-color: transparent; - border: 1px solid var(--border-color); - color: var(--text-muted); -} - -.btn-outline:hover { - border-color: var(--text-main); - color: var(--text-main); -} - -.btn-sm { - padding: 6px 12px; - font-size: 12px; -} - -.btn-lg { - padding: 14px 24px; - font-size: 16px; -} - -.btn-block { - width: 100%; -} - -.btn-subtext { - font-size: 11px; - opacity: 0.8; - margin-left: 4px; -} - -.icon-btn { - background: transparent; - border: 1px solid var(--border-color); - border-radius: var(--radius-sm); - padding: 6px 10px; - cursor: pointer; - color: var(--text-muted); - font-size: 16px; - transition: var(--transition); -} - -.icon-btn:hover { - color: var(--text-main); - border-color: var(--text-main); -} - -/* Main Content */ -.main-content { - max-width: 900px; - width: 100%; - margin: 0 auto; - padding: 32px 20px; - display: flex; - flex-direction: column; - gap: 36px; -} - -/* Search Box */ -.search-box-wrapper { - display: flex; - flex-direction: column; - gap: 8px; -} - -.search-input-box { - display: flex; - align-items: center; - background-color: var(--bg-surface); - border: 2px solid var(--border-color); - border-radius: var(--radius-md); - padding: 6px 10px 6px 16px; - transition: var(--transition); - box-shadow: var(--shadow-sm); -} - -.search-input-box:focus-within { - border-color: var(--border-focus); - box-shadow: 0 0 0 4px var(--primary-dim); -} - -.search-icon { - font-size: 18px; - color: var(--text-muted); - margin-right: 12px; -} - -.search-input-box input { - flex: 1; - background: transparent; - border: none; - outline: none; - font-size: 17px; - color: var(--text-main); - padding: 8px 0; -} - -.clear-btn { - background: transparent; - border: none; - color: var(--text-dim); - font-size: 16px; - cursor: pointer; - padding: 4px 8px; - border-radius: 50%; -} - -.clear-btn:hover { - color: var(--text-main); -} - -.translate-action-btn { - margin-left: 8px; -} - -.hotkey-hints { - display: flex; - flex-wrap: wrap; - gap: 12px; - padding: 4px 8px; - font-size: 12px; - color: var(--text-dim); -} - -.hotkey-hints kbd { - background-color: var(--bg-surface-hover); - border: 1px solid var(--border-color); - border-radius: 4px; - padding: 1px 5px; - font-family: monospace; - font-size: 11px; - color: var(--text-muted); -} - -/* Spinner */ -.lookup-spinner { - display: flex; - align-items: center; - justify-content: center; - gap: 12px; - padding: 24px; - color: var(--primary); - font-size: 14px; - font-weight: 500; -} - -.spinner { - width: 24px; - height: 24px; - border: 3px solid var(--border-color); - border-top-color: var(--primary); - border-radius: 50%; - animation: spin 0.8s linear infinite; -} - -@keyframes spin { - to { transform: rotate(360deg); } -} - -/* Live Result Card */ -.result-card { - background-color: var(--bg-card); - border: 1px solid var(--border-color); - border-radius: var(--radius-lg); - padding: 24px; - box-shadow: var(--shadow-md); - animation: fadeIn 0.25s ease-out; -} - -@keyframes fadeIn { - from { opacity: 0; transform: translateY(6px); } - to { opacity: 1; transform: translateY(0); } -} - -.result-header { - margin-bottom: 16px; - padding-bottom: 16px; - border-bottom: 1px solid var(--border-color); -} - -.term-title-row { - display: flex; - align-items: center; - flex-wrap: wrap; - gap: 12px; -} - -.res-term { - font-size: 28px; - font-weight: 800; - letter-spacing: -0.5px; - color: var(--text-main); -} - -.badge-pill { - padding: 3px 10px; - border-radius: var(--radius-full); - font-size: 13px; - font-weight: 600; -} - -.res-phonetic { - background-color: var(--primary-dim); - color: var(--primary); - font-family: monospace; -} - -.res-pos { - background-color: var(--bg-surface-hover); - color: var(--text-muted); -} - -.audio-btn { - background-color: var(--primary-dim); - border: 1px solid var(--primary); - color: var(--primary); - border-radius: var(--radius-full); - padding: 4px 12px; - font-size: 13px; - font-weight: 600; - cursor: pointer; - display: inline-flex; - align-items: center; - gap: 4px; - transition: var(--transition); -} - -.audio-btn:hover { - background-color: var(--primary); - color: #0f172a; -} - -.audio-xs-btn { - background-color: var(--primary-dim); - border: 1px solid var(--primary); - color: var(--primary); - border-radius: var(--radius-full); - padding: 2px 8px; - font-size: 11px; - font-weight: 600; - cursor: pointer; - display: inline-flex; - align-items: center; - gap: 4px; - transition: var(--transition); -} - -.audio-xs-btn:hover { - background-color: var(--primary); - color: #0f172a; -} - -.popup-sentence-audio-btn { - border-color: var(--border-color); - color: var(--text-muted); -} - -.popup-sentence-audio-btn:hover { - border-color: var(--primary); - color: var(--primary); - background-color: var(--primary-dim); -} - -.definition-box { - background-color: var(--bg-main); - border-left: 3px solid var(--primary); - padding: 12px 16px; - border-radius: 0 var(--radius-sm) var(--radius-sm) 0; - margin-bottom: 20px; -} - -.def-label { - font-size: 11px; - font-weight: 700; - text-transform: uppercase; - color: var(--primary); - letter-spacing: 0.5px; - margin-bottom: 4px; -} - -.def-text { - font-size: 14px; - color: var(--text-main); -} - -.card-edit-grid { - display: flex; - flex-direction: column; - gap: 16px; - margin-bottom: 24px; -} - -.input-styled { - width: 100%; - padding: 10px 14px; - background-color: var(--bg-input); - border: 1px solid var(--border-color); - border-radius: var(--radius-sm); - color: var(--text-main); - font-size: 14px; - outline: none; - transition: var(--transition); -} - -.input-styled:focus { - border-color: var(--border-focus); - box-shadow: 0 0 0 3px var(--primary-dim); -} - -.field-group label { - display: block; - font-size: 12px; - font-weight: 600; - color: var(--text-muted); - margin-bottom: 5px; -} - -.field-group .req { - color: var(--danger); -} - -.field-row { - display: flex; - gap: 16px; -} - -.flex-1 { flex: 1; } -.flex-2 { flex: 2; } - -.suggestions-chips { - display: flex; - flex-wrap: wrap; - gap: 6px; - margin-top: 6px; -} - -.suggestion-chip { - font-size: 12px; - background-color: var(--bg-surface-hover); - color: var(--text-muted); - padding: 2px 8px; - border-radius: var(--radius-full); - cursor: pointer; - transition: var(--transition); - border: 1px solid transparent; -} - -.suggestion-chip:hover { - border-color: var(--primary); - color: var(--primary); -} - -.quick-tags { - display: flex; - flex-wrap: wrap; - gap: 6px; - margin-top: 6px; -} - -.tag-chip { - font-size: 11px; - background-color: var(--tag-bg); - color: var(--tag-text); - padding: 2px 8px; - border-radius: var(--radius-full); - cursor: pointer; - user-select: none; - transition: var(--transition); -} - -.tag-chip:hover, .tag-chip.active { - background-color: var(--primary); - color: #0f172a; - font-weight: 600; -} - -.result-actions { - display: flex; - justify-content: flex-end; -} - -/* Vocabulary Section */ -.vocabulary-section { - display: flex; - flex-direction: column; - gap: 16px; -} - -.section-header { - display: flex; - justify-content: space-between; - align-items: center; - flex-wrap: wrap; - gap: 12px; -} - -.section-title-wrap { - display: flex; - align-items: baseline; - gap: 8px; -} - -.section-title-wrap h3 { - font-size: 20px; - font-weight: 700; -} - -.cards-count-label { - font-size: 13px; - color: var(--text-dim); -} - -.list-controls { - display: flex; - align-items: center; - gap: 8px; -} - -.batch-mode-btn { - white-space: nowrap; - flex-shrink: 0; - height: 35px; - display: inline-flex; - align-items: center; - justify-content: center; -} - -.search-mini-box { - display: flex; - align-items: center; -} - -.search-mini-box input { - background-color: var(--bg-surface); - border: 1px solid var(--border-color); - border-radius: var(--radius-sm); - padding: 8px 12px; - color: var(--text-main); - font-size: 13px; - outline: none; - min-width: 260px; - height: 35px; - box-sizing: border-box; - transition: var(--transition); -} - -.search-mini-box input:focus { - border-color: var(--border-focus); -} - -/* Tags Filter Bar */ -.tags-filter-bar { - display: flex; - flex-wrap: wrap; - gap: 8px; -} - -.filter-chip { - background-color: var(--bg-surface); - border: 1px solid var(--border-color); - color: var(--text-muted); - font-size: 12px; - font-weight: 600; - padding: 4px 12px; - border-radius: var(--radius-full); - cursor: pointer; - transition: var(--transition); -} - -.filter-chip:hover { - border-color: var(--primary); - color: var(--primary); -} - -.filter-chip.active { - background-color: var(--primary); - border-color: var(--primary); - color: #0f172a; -} - -/* Cards List */ -.cards-list { - display: flex; - flex-direction: column; - gap: 12px; -} - -.vocab-card { - background-color: var(--bg-card); - border: 1px solid var(--border-color); - border-radius: var(--radius-md); - padding: 16px 20px; - box-shadow: var(--shadow-sm); - transition: var(--transition); - display: flex; - flex-direction: column; - gap: 10px; -} - -.vocab-card:hover { - border-color: var(--border-focus); - box-shadow: var(--shadow-md); -} - -.card-top { - display: flex; - justify-content: space-between; - align-items: flex-start; -} - -.card-term-group { - display: flex; - align-items: center; - gap: 10px; - flex-wrap: wrap; -} - -.card-term { - font-size: 18px; - font-weight: 700; - color: var(--text-main); -} - -.card-phonetic { - font-size: 13px; - color: var(--primary); - font-family: monospace; -} - -.card-pos { - font-size: 11px; - background-color: var(--bg-surface-hover); - color: var(--text-dim); - padding: 2px 6px; - border-radius: 4px; -} - -.card-actions { - display: flex; - gap: 6px; -} - -.card-translation { - font-size: 16px; - font-weight: 600; - color: var(--text-main); -} - -.card-context { - font-size: 14px; - color: var(--text-muted); - font-style: italic; - background-color: var(--bg-main); - padding: 8px 12px; - border-radius: var(--radius-sm); - border-left: 2px solid var(--border-color); -} - -.card-context mark { - background-color: var(--primary-dim); - color: var(--primary); - font-weight: 600; - padding: 0 4px; - border-radius: 2px; -} - -.card-bottom { - display: flex; - justify-content: space-between; - align-items: center; - flex-wrap: wrap; - gap: 8px; - font-size: 12px; - color: var(--text-dim); -} - -.card-tags { - display: flex; - gap: 6px; - flex-wrap: wrap; -} - -.card-tag { - background-color: var(--tag-bg); - color: var(--tag-text); - padding: 2px 8px; - border-radius: var(--radius-full); - font-size: 11px; -} - -.card-notes { - font-size: 12px; - color: #fbbf24; - display: flex; - align-items: center; - gap: 4px; -} - -/* Empty state */ -.empty-state { - text-align: center; - padding: 48px 24px; - background-color: var(--bg-surface); - border: 1px dashed var(--border-color); - border-radius: var(--radius-md); - color: var(--text-muted); -} - -.empty-icon { - font-size: 40px; - margin-bottom: 12px; -} - -.empty-state h4 { - font-size: 16px; - color: var(--text-main); - margin-bottom: 6px; -} - -.empty-state p { - font-size: 13px; - color: var(--text-dim); -} - -/* Modal */ -.modal-backdrop { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-color: rgba(0, 0, 0, 0.7); - backdrop-filter: blur(4px); - display: flex; - align-items: center; - justify-content: center; - z-index: 1000; - padding: 20px; -} - -.modal-window { - background-color: var(--bg-surface); - border: 1px solid var(--border-color); - border-radius: var(--radius-lg); - width: 100%; - max-width: 520px; - box-shadow: var(--shadow-lg); - display: flex; - flex-direction: column; -} - -.modal-header { - display: flex; - justify-content: space-between; - align-items: center; - padding: 16px 20px; - border-bottom: 1px solid var(--border-color); -} - -.modal-header h3 { - font-size: 18px; - font-weight: 700; -} - -.modal-body { - padding: 20px; - display: flex; - flex-direction: column; - gap: 14px; -} - -.modal-footer { - display: flex; - justify-content: flex-end; - gap: 10px; - padding: 14px 20px; - border-top: 1px solid var(--border-color); -} - -.modal-sm { - max-width: 420px; -} - -/* Navigation Additions */ -.nav-center { - display: flex; - align-items: center; -} - -.btn-trainer { - background: linear-gradient(135deg, #0284c7, #38bdf8); - color: #0f172a; - font-weight: 700; - box-shadow: 0 2px 10px rgba(56, 189, 248, 0.25); - display: inline-flex; - align-items: center; - gap: 8px; - padding: 7px 14px; - border-radius: var(--radius-sm); - border: none; - cursor: pointer; - transition: var(--transition); -} - -.btn-trainer:hover { - box-shadow: 0 4px 14px rgba(56, 189, 248, 0.45); - transform: translateY(-1px); -} - -.srs-due-badge { - background-color: #0f172a; - color: #38bdf8; - font-size: 11px; - font-weight: 800; - padding: 1px 7px; - border-radius: var(--radius-full); - min-width: 18px; - text-align: center; -} - -.srs-due-badge.has-due { - background-color: #ef4444; - color: #ffffff; - animation: pulseDue 2s infinite; -} - -@keyframes pulseDue { - 0%, 100% { transform: scale(1); } - 50% { transform: scale(1.15); } -} - -/* Collections & Filters */ -.collections-filter-wrap, .tags-filter-wrap { - display: flex; - flex-direction: column; - gap: 6px; -} - -.filter-header-bar { - display: flex; - align-items: center; - justify-content: space-between; -} - -.filter-title { - font-size: 12px; - font-weight: 700; - color: var(--text-muted); - text-transform: uppercase; - letter-spacing: 0.5px; -} - -.filter-chips-row { - display: flex; - flex-wrap: wrap; - gap: 6px; - align-items: center; -} - -.col-chip { - background-color: var(--bg-surface); - border: 1px solid var(--border-color); - color: var(--text-muted); - font-size: 12px; - font-weight: 600; - padding: 4px 12px; - border-radius: var(--radius-full); - cursor: pointer; - transition: var(--transition); -} - -.col-chip:hover { - border-color: #a855f7; - color: #c084fc; -} - -.col-chip.active { - background-color: #a855f7; - border-color: #a855f7; - color: #ffffff; - font-weight: 700; -} - -.card-collection-badge { - font-size: 11px; - font-weight: 600; - background-color: rgba(168, 85, 247, 0.15); - color: #c084fc; - border: 1px solid rgba(168, 85, 247, 0.3); - padding: 2px 8px; - border-radius: var(--radius-full); -} - -/* Batch Selection */ -.batch-mode-btn.active { - background-color: var(--primary-dim); - border-color: var(--primary); - color: var(--primary); -} - -.card-select-cell { - display: none; - margin-right: 12px; - align-items: center; -} - -.batch-active .card-select-cell { - display: flex; -} - -.card-select-checkbox { - width: 18px; - height: 18px; - cursor: pointer; - accent-color: var(--primary); -} - -.vocab-card.is-selected { - border-color: var(--border-focus); - background-color: rgba(56, 189, 248, 0.05); -} - -.batch-action-bar { - position: fixed; - bottom: 24px; - left: 50%; - transform: translateX(-50%); - width: calc(100% - 32px); - max-width: 760px; - background: rgba(30, 41, 59, 0.96); - backdrop-filter: blur(12px); - border: 1px solid var(--border-focus); - border-radius: var(--radius-lg); - box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.6), 0 0 15px rgba(56, 189, 248, 0.2); - padding: 12px 20px; - display: flex; - justify-content: space-between; - align-items: center; - z-index: 900; - animation: slideUp 0.22s ease-out; -} - -@keyframes slideUp { - from { transform: translate(-50%, 40px); opacity: 0; } - to { transform: translate(-50%, 0); opacity: 1; } -} - -.batch-left { - display: flex; - align-items: center; - gap: 10px; -} - -.batch-check-label { - display: flex; - align-items: center; - gap: 8px; - font-size: 14px; - font-weight: 600; - color: var(--text-main); - cursor: pointer; -} - -.batch-master-checkbox { - width: 18px; - height: 18px; - accent-color: var(--primary); - cursor: pointer; -} - -.batch-actions { - display: flex; - align-items: center; - gap: 8px; -} - -.btn-secondary { - background-color: var(--bg-surface-hover); - color: var(--text-main); - border: 1px solid var(--border-color); -} - -.btn-secondary:hover { - background-color: var(--border-color); -} - -.btn-danger { - background-color: var(--danger); - color: #ffffff; -} - -.btn-danger:hover { - background-color: var(--danger-hover); -} - -.btn-ghost { - background: transparent; - border: none; - color: var(--primary); - cursor: pointer; - font-size: 13px; - padding: 4px 8px; - border-radius: var(--radius-sm); -} - -.btn-ghost:hover { - background-color: var(--primary-dim); -} - -.btn-xs { - padding: 2px 8px; - font-size: 11px; -} - -/* Export Modal */ -.export-modal-window { - max-width: 620px; -} - -.modal-lead { - font-size: 14px; - color: var(--text-muted); - margin-bottom: 8px; -} - -.export-grid { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 12px; -} - -.export-tile { - background-color: var(--bg-input); - border: 1px solid var(--border-color); - border-radius: var(--radius-md); - padding: 16px; - display: flex; - flex-direction: column; - justify-content: space-between; - gap: 12px; - transition: var(--transition); -} - -.export-tile:hover { - border-color: var(--primary); - transform: translateY(-2px); - box-shadow: var(--shadow-md); -} - -.export-tile-icon { - font-size: 28px; -} - -.export-tile-info h4 { - font-size: 15px; - font-weight: 700; - color: var(--text-main); - margin-bottom: 4px; -} - -.export-tile-info p { - font-size: 12px; - color: var(--text-dim); - line-height: 1.4; -} - -/* SRS View Structure */ -.srs-view { - min-height: calc(100vh - 65px); - display: flex; - flex-direction: column; - background: radial-gradient(circle at 50% 15%, rgba(56, 189, 248, 0.07), transparent 60%); -} - -.srs-topbar { - background-color: var(--bg-surface); - border-bottom: 1px solid var(--border-color); - padding: 12px 24px; - display: flex; - align-items: center; - justify-content: space-between; - gap: 16px; -} - -.srs-topbar-left { - display: flex; - align-items: center; - gap: 16px; -} - -.srs-mode-switch { - display: flex; - background-color: var(--bg-main); - padding: 3px; - border-radius: var(--radius-md); - border: 1px solid var(--border-color); -} - -.srs-tab { - background: transparent; - border: none; - color: var(--text-muted); - padding: 6px 14px; - border-radius: var(--radius-sm); - font-size: 13px; - font-weight: 600; - cursor: pointer; - transition: var(--transition); -} - -.srs-tab:hover { - color: var(--text-main); -} - -.srs-tab.active { - background-color: var(--primary); - color: #0f172a; - font-weight: 700; - box-shadow: var(--shadow-sm); -} - -.srs-topbar-center { - flex: 1; - max-width: 380px; - display: flex; - flex-direction: column; - align-items: center; - gap: 4px; -} - -.srs-progress-container { - width: 100%; - height: 7px; - background-color: var(--bg-main); - border-radius: var(--radius-full); - overflow: hidden; - border: 1px solid var(--border-color); -} - -.srs-progress-fill { - height: 100%; - background: linear-gradient(90deg, #0284c7, #38bdf8); - border-radius: var(--radius-full); - transition: width 0.3s ease; -} - -.srs-counter { - font-size: 11px; - font-weight: 600; - color: var(--text-dim); -} - -.srs-topbar-right { - display: flex; - align-items: center; -} - -.srs-arena { - flex: 1; - max-width: 720px; - width: 100%; - margin: 0 auto; - padding: 32px 16px; - display: flex; - flex-direction: column; - justify-content: center; -} - -.srs-state-box { - text-align: center; - padding: 64px 24px; - background-color: var(--bg-card); - border: 1px solid var(--border-color); - border-radius: var(--radius-lg); - box-shadow: var(--shadow-md); - display: flex; - flex-direction: column; - align-items: center; - gap: 16px; -} - -.srs-big-icon { - font-size: 56px; -} - -.srs-empty-buttons { - display: flex; - gap: 12px; - flex-wrap: wrap; - justify-content: center; - margin-top: 12px; -} - -/* Flashcard 3D Card Flip */ -.srs-mode-container { - display: flex; - flex-direction: column; - gap: 20px; - animation: fadeIn 0.25s ease-out; -} - -.flashcard-wrapper { - perspective: 1400px; - min-height: 380px; - cursor: pointer; - user-select: none; -} - -.flashcard-inner { - position: relative; - width: 100%; - min-height: 380px; - transform-style: preserve-3d; - transition: transform 0.48s cubic-bezier(0.4, 0, 0.2, 1); -} - -.flashcard-inner.is-flipped { - transform: rotateY(180deg); -} - -.flashcard-face { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - min-height: 380px; - background-color: var(--bg-card); - border: 1px solid var(--border-color); - border-radius: var(--radius-lg); - padding: 28px 32px; - box-shadow: var(--shadow-lg); - backface-visibility: hidden; - -webkit-backface-visibility: hidden; - display: flex; - flex-direction: column; - justify-content: space-between; -} - -.flashcard-front { - transform: rotateY(0deg); -} - -.flashcard-back { - transform: rotateY(180deg); - background: radial-gradient(circle at top right, rgba(56, 189, 248, 0.06), var(--bg-card) 70%); -} - -.fc-badge-row { - display: flex; - justify-content: space-between; - align-items: center; -} - -.fc-dir-badge { - font-size: 11px; - font-weight: 700; - letter-spacing: 0.5px; - color: var(--primary); - background-color: var(--primary-dim); - padding: 3px 10px; - border-radius: var(--radius-full); -} - -.fc-pos-badge { - font-size: 11px; - color: var(--text-dim); - background-color: var(--bg-surface-hover); - padding: 2px 8px; - border-radius: 4px; -} - -.fc-center { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - text-align: center; - gap: 16px; - padding: 20px 0; -} - -.fc-main-term { - font-size: 38px; - font-weight: 800; - letter-spacing: -0.5px; - color: var(--text-main); -} - -.fc-phonetic-row { - display: flex; - align-items: center; - gap: 10px; -} - -.audio-round-btn { - width: 36px; - height: 36px; - border-radius: 50%; - display: inline-flex; - align-items: center; - justify-content: center; - background-color: var(--primary-dim); - border: 1px solid var(--primary); - color: var(--primary); - font-size: 16px; - cursor: pointer; - transition: var(--transition); -} - -.audio-round-btn:hover { - background-color: var(--primary); - color: #0f172a; - transform: scale(1.08); -} - -.fc-hint-wrapper { - display: flex; - flex-direction: column; - align-items: center; - gap: 8px; - max-width: 500px; -} - -.fc-hint-content { - font-size: 14px; - font-style: italic; - color: var(--text-muted); - background-color: var(--bg-main); - padding: 10px 16px; - border-radius: var(--radius-sm); - border-left: 3px solid var(--primary); -} - -.fc-footer-hint { - text-align: center; - font-size: 12px; - color: var(--text-dim); -} - -.fc-footer-hint kbd { - background-color: var(--bg-surface-hover); - border: 1px solid var(--border-color); - padding: 2px 6px; - border-radius: 4px; - font-family: monospace; -} - -/* Flashcard Back */ -.fc-back-content { - display: flex; - flex-direction: column; - gap: 14px; - height: 100%; -} - -.fc-back-top { - display: flex; - justify-content: space-between; - align-items: center; - border-bottom: 1px solid var(--border-color); - padding-bottom: 8px; -} - -.fc-back-term { - font-size: 24px; - font-weight: 700; - color: var(--text-main); -} - -.fc-back-translation { - font-size: 22px; - font-weight: 700; - color: var(--primary); -} - -.fc-back-detail-box { - background-color: var(--bg-main); - border-radius: var(--radius-sm); - padding: 10px 14px; - border-left: 2px solid var(--border-color); -} - -.detail-label { - font-size: 10px; - font-weight: 700; - text-transform: uppercase; - color: var(--text-dim); - letter-spacing: 0.5px; - margin-bottom: 2px; - display: block; -} - -.detail-text { - font-size: 13px; - color: var(--text-main); - line-height: 1.4; -} - -.fc-flip-btn-wrap { - display: none; -} - -/* SRS Rating Bar */ -.srs-rating-bar { - display: grid; - grid-template-columns: repeat(4, 1fr); - gap: 12px; - margin-top: 8px; - animation: fadeIn 0.2s ease-out; -} - -.btn-rate { - padding: 12px 10px; - border-radius: var(--radius-md); - border: 1px solid var(--border-color); - background-color: var(--bg-surface); - cursor: pointer; - display: flex; - flex-direction: column; - align-items: center; - gap: 2px; - transition: var(--transition); -} - -.btn-rate .rate-key { - font-size: 11px; - font-family: monospace; - opacity: 0.7; -} - -.btn-rate .rate-name { - font-size: 15px; - font-weight: 700; -} - -.btn-rate .rate-time { - font-size: 11px; - opacity: 0.75; -} - -/* Rating variants */ -.btn-rate-1 { - border-color: rgba(239, 68, 68, 0.4); - color: #f87171; -} -.btn-rate-1:hover { - background-color: rgba(239, 68, 68, 0.15); - border-color: #ef4444; -} - -.btn-rate-2 { - border-color: rgba(245, 158, 11, 0.4); - color: #fbbf24; -} -.btn-rate-2:hover { - background-color: rgba(245, 158, 11, 0.15); - border-color: #f59e0b; -} - -.btn-rate-3 { - border-color: rgba(56, 189, 248, 0.4); - color: #38bdf8; -} -.btn-rate-3:hover { - background-color: rgba(56, 189, 248, 0.15); - border-color: #38bdf8; -} - -.btn-rate-4 { - border-color: rgba(16, 185, 129, 0.4); - color: #34d399; -} -.btn-rate-4:hover { - background-color: rgba(16, 185, 129, 0.15); - border-color: #10b981; -} - -/* Interactive Trainer Card (Cloze & Dictation) */ -.trainer-card { - background-color: var(--bg-card); - border: 1px solid var(--border-color); - border-radius: var(--radius-lg); - padding: 32px; - box-shadow: var(--shadow-lg); - display: flex; - flex-direction: column; - gap: 20px; -} - -.trainer-header { - display: flex; - justify-content: space-between; - align-items: center; -} - -.mode-tag { - font-size: 12px; - font-weight: 700; - color: var(--primary); - background-color: var(--primary-dim); - padding: 3px 12px; - border-radius: var(--radius-full); -} - -.trainer-pos { - font-size: 12px; - color: var(--text-dim); -} - -.cloze-sentence-display { - font-size: 20px; - line-height: 1.6; - color: var(--text-main); - background-color: var(--bg-main); - padding: 20px 24px; - border-radius: var(--radius-md); - border-left: 4px solid var(--primary); -} - -.gap-placeholder { - color: var(--primary); - font-weight: 800; - letter-spacing: 2px; - border-bottom: 2px dashed var(--primary); - padding: 0 4px; -} - -.cloze-translation-hint { - font-size: 14px; - color: var(--text-muted); -} - -.cloze-translation-hint strong { - color: var(--text-main); - margin-left: 6px; -} - -.trainer-form { - display: flex; - flex-direction: column; - gap: 12px; -} - -.input-action-row { - display: flex; - gap: 10px; -} - -.input-hero { - font-size: 18px; - padding: 12px 18px; -} - -.trainer-feedback-box { - padding: 14px 18px; - border-radius: var(--radius-sm); - font-size: 15px; - font-weight: 600; - animation: fadeIn 0.2s ease-out; -} - -.trainer-feedback-box.correct { - background-color: var(--success-dim); - border: 1px solid var(--success); - color: #34d399; -} - -.trainer-feedback-box.incorrect { - background-color: var(--danger-dim); - border: 1px solid var(--danger); - color: #fca5a5; -} - -.trainer-revealed-details { - background-color: var(--bg-main); - border-radius: var(--radius-md); - padding: 16px; - display: flex; - flex-direction: column; - gap: 10px; - border: 1px solid var(--border-color); - animation: fadeIn 0.2s ease-out; -} - -/* Audio Dictation Mode */ -.dictation-hero { - display: flex; - flex-direction: column; - align-items: center; - gap: 14px; - padding: 16px 0; -} - -.dictation-pulse-btn { - width: 80px; - height: 80px; - border-radius: 50%; - background: linear-gradient(135deg, #0284c7, #38bdf8); - border: none; - color: #0f172a; - font-size: 34px; - cursor: pointer; - box-shadow: 0 0 0 0 rgba(56, 189, 248, 0.4); - animation: pulseAudio 2s infinite; - display: flex; - align-items: center; - justify-content: center; - transition: var(--transition); -} - -.dictation-pulse-btn:hover { - transform: scale(1.08); -} - -@keyframes pulseAudio { - 0% { box-shadow: 0 0 0 0 rgba(56, 189, 248, 0.6); } - 70% { box-shadow: 0 0 0 22px rgba(56, 189, 248, 0); } - 100% { box-shadow: 0 0 0 0 rgba(56, 189, 248, 0); } -} - -.dictation-instructions { - font-size: 14px; - color: var(--text-muted); -} - -.audio-replay-btn .kbd-sub { - font-size: 10px; - margin-left: 4px; -} - -.dictation-hint-wrap { - display: flex; - align-items: center; - gap: 10px; -} - -.dictation-hint-text { - font-size: 13px; - color: var(--text-muted); - font-style: italic; -} - -/* Interactive Listening Comprehension Mode */ -.listening-card { - background-color: var(--bg-card); - border: 1px solid var(--border-color); - border-radius: var(--radius-lg); - padding: 28px 32px; - box-shadow: var(--shadow-lg); - display: flex; - flex-direction: column; - gap: 20px; -} - -.listening-header-row { - display: flex; - justify-content: space-between; - align-items: center; - flex-wrap: wrap; - gap: 12px; -} - -.listening-tag-wrap { - display: flex; - align-items: center; - gap: 8px; - flex-wrap: wrap; -} - -.level-badge { - font-size: 11px; - font-weight: 700; - padding: 2px 8px; - border-radius: var(--radius-sm); - text-transform: uppercase; - letter-spacing: 0.5px; -} - -.level-badge.badge-a1 { background: rgba(59, 130, 246, 0.15); color: #60a5fa; border: 1px solid rgba(59, 130, 246, 0.3); } -.level-badge.badge-a2 { background: rgba(16, 185, 129, 0.15); color: #34d399; border: 1px solid rgba(16, 185, 129, 0.3); } -.level-badge.badge-b1 { background: rgba(245, 158, 11, 0.15); color: #fbbf24; border: 1px solid rgba(245, 158, 11, 0.3); } -.level-badge.badge-b2 { background: rgba(249, 115, 22, 0.15); color: #fb923c; border: 1px solid rgba(249, 115, 22, 0.3); } -.level-badge.badge-c1 { background: rgba(168, 85, 247, 0.15); color: #c084fc; border: 1px solid rgba(168, 85, 247, 0.3); } - -.topic-badge { - font-size: 11px; - font-weight: 600; - color: var(--text-dim); - background: var(--bg-main); - border: 1px solid var(--border-color); - padding: 2px 8px; - border-radius: var(--radius-sm); -} - -.listening-filters { - display: flex; - align-items: center; - gap: 8px; - flex-wrap: wrap; -} - -.select-styled { - background-color: var(--bg-main); - border: 1px solid var(--border-color); - border-radius: var(--radius-sm); - color: var(--text-main); - padding: 6px 10px; - font-size: 13px; - outline: none; - cursor: pointer; - transition: var(--transition); -} - -.select-styled:focus { - border-color: var(--primary); - box-shadow: 0 0 0 2px var(--primary-dim); -} - -.select-xs { - font-size: 12px; - padding: 4px 8px; -} - -.listening-hero { - background: linear-gradient(180deg, var(--bg-card) 0%, var(--bg-main) 100%); - border: 1px solid var(--border-color); - border-radius: var(--radius-md); - padding: 20px 24px; - display: flex; - flex-direction: column; - gap: 16px; -} - -.listening-scenario-title { - font-size: 18px; - font-weight: 700; - color: var(--text-main); - margin: 0 0 4px 0; -} - -.listening-subtitle { - font-size: 13px; - color: var(--text-muted); - margin: 0; -} - -.listening-audio-controls { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 16px; - margin-top: 4px; -} - -@media (max-width: 600px) { - .listening-audio-controls { - grid-template-columns: 1fr; - } -} - -.audio-control-card { - background: var(--bg-card); - border: 1px solid var(--border-color); - border-radius: var(--radius-md); - padding: 14px 16px; - display: flex; - flex-direction: column; - gap: 8px; - transition: var(--transition); -} - -.audio-control-card:hover { - border-color: var(--primary-dim); -} - -.audio-control-label { - font-size: 12px; - font-weight: 600; - color: var(--text-dim); -} - -.listening-play-btn { - width: 100%; - justify-content: center; - font-weight: 600; - display: inline-flex; - align-items: center; - gap: 8px; -} - -.listening-hint-bar { - display: flex; - align-items: center; - gap: 12px; -} - -.listening-hint-text { - font-size: 13px; - color: var(--text-muted); - font-style: italic; - background: var(--bg-main); - border-left: 3px solid var(--primary); - padding: 4px 10px; - border-radius: 0 var(--radius-sm) var(--radius-sm) 0; -} - -.listening-form { - display: flex; - flex-direction: column; - gap: 12px; -} - -.listening-revealed-card { - background-color: var(--bg-main); - border: 1px solid var(--border-color); - border-left: 4px solid var(--primary); - border-radius: var(--radius-md); - padding: 20px; - display: flex; - flex-direction: column; - gap: 16px; - animation: fadeIn 0.25s ease-out; -} - -.revealed-section { - display: flex; - flex-direction: column; - gap: 4px; -} - -.revealed-label { - font-size: 12px; - font-weight: 700; - color: var(--text-dim); - text-transform: uppercase; - letter-spacing: 0.5px; -} - -.revealed-val { - font-size: 16px; - color: #34d399; -} - -.revealed-text { - font-size: 15px; - line-height: 1.5; - color: var(--text-main); - margin: 0; -} - -.listening-next-bar { - display: flex; - justify-content: flex-end; - margin-top: 8px; - padding-top: 12px; - border-top: 1px solid var(--border-color); -} - -/* Voice Settings Modal */ -.voice-modal-window { - max-width: 680px; - width: 95%; -} - -.voice-modal-body { - padding: 20px 24px; - display: flex; - flex-direction: column; - gap: 16px; - max-height: 80vh; - overflow-y: auto; -} - -.modal-desc-sub { - font-size: 13px; - color: var(--text-muted); - margin: 0 0 10px 0; -} - -.voice-group-title { - font-size: 14px; - font-weight: 700; - color: var(--text-main); - display: block; - margin-bottom: 10px; -} - -.voice-options-grid { - display: grid; - grid-template-columns: repeat(3, 1fr); - gap: 12px; -} - -@media (max-width: 680px) { - .voice-options-grid { - grid-template-columns: 1fr; - } -} - -.voice-card-label { - cursor: pointer; - display: block; - position: relative; - user-select: none; -} - -.voice-card-label input[type="radio"] { - position: absolute; - opacity: 0; - pointer-events: none; -} - -.voice-card { - border: 1px solid var(--border-color); - background: var(--bg-card); - border-radius: var(--radius-md); - padding: 14px 14px; - display: flex; - flex-direction: column; - gap: 8px; - height: 100%; - transition: var(--transition); -} - -.voice-card:hover { - border-color: var(--primary-dim); -} - -.voice-card-label input[type="radio"]:checked + .voice-card { - border-color: var(--primary); - background: var(--bg-main); - box-shadow: 0 0 0 2px var(--primary-dim); -} - -.voice-card-head { - display: flex; - justify-content: space-between; - align-items: center; - gap: 6px; -} - -.voice-card-desc { - font-size: 12px; - line-height: 1.4; - color: var(--text-muted); - flex: 1; -} - -.badge-recommended { - background: rgba(16, 185, 129, 0.15); - color: #10b981; - font-size: 10px; - font-weight: 700; - padding: 2px 6px; - border-radius: 4px; - white-space: nowrap; -} - -.badge-uk { - background: rgba(59, 130, 246, 0.15); - color: #3b82f6; - font-size: 10px; - font-weight: 700; - padding: 2px 6px; - border-radius: 4px; - white-space: nowrap; -} - -.voice-test-btn { - align-self: flex-start; - margin-top: 4px; -} - -/* Summary Card */ -.srs-summary-card { - background-color: var(--bg-card); - border: 1px solid var(--border-color); - border-radius: var(--radius-lg); - padding: 44px 32px; - text-align: center; - display: flex; - flex-direction: column; - align-items: center; - gap: 20px; - box-shadow: var(--shadow-lg); - animation: fadeIn 0.3s ease-out; -} - -.summary-trophy { - font-size: 64px; - animation: bounce 0.6s ease; -} - -@keyframes bounce { - 0%, 100% { transform: translateY(0); } - 50% { transform: translateY(-16px); } -} - -.srs-summary-card h2 { - font-size: 28px; - font-weight: 800; -} - -.summary-lead { - font-size: 15px; - color: var(--text-muted); - max-width: 480px; -} - -.summary-metrics { - display: grid; - grid-template-columns: repeat(3, 1fr); - gap: 16px; - width: 100%; - margin: 12px 0; -} - -.metric-card { - background-color: var(--bg-main); - border: 1px solid var(--border-color); - border-radius: var(--radius-md); - padding: 16px 12px; - display: flex; - flex-direction: column; - align-items: center; - gap: 4px; -} - -.metric-val { - font-size: 28px; - font-weight: 800; -} - -.metric-desc { - font-size: 11px; - color: var(--text-dim); -} - -.text-success { color: var(--success); } -.text-primary { color: var(--primary); } - -.summary-rates-bar { - display: flex; - gap: 12px; - font-size: 13px; - color: var(--text-muted); - flex-wrap: wrap; - justify-content: center; -} - -.summary-buttons { - display: flex; - gap: 14px; - margin-top: 12px; - flex-wrap: wrap; - justify-content: center; -} - -/* Duplicate Warning Banner */ -.duplicate-warning-box { - margin-top: 10px; - padding: 10px 14px; - background: rgba(234, 179, 8, 0.12); - border: 1px solid rgba(234, 179, 8, 0.35); - border-radius: var(--radius-md); - display: flex; - align-items: center; - justify-content: space-between; - gap: 12px; - animation: fadeIn 0.2s ease-in-out; -} - -.dup-left { - display: flex; - align-items: center; - gap: 8px; - font-size: 13px; - color: #facc15; -} - -.dup-icon { - font-size: 16px; -} - -/* Multiple Choice Quiz Mode */ -.quiz-card { - max-width: 680px; - margin: 0 auto; -} - -.quiz-hero { - text-align: center; - padding: 20px 0 16px 0; - border-bottom: 1px solid var(--border-color); - margin-bottom: 20px; -} - -.quiz-prompt-row { - display: flex; - align-items: center; - justify-content: center; - gap: 12px; -} - -.quiz-term-display { - font-size: 32px; - font-weight: 800; - color: var(--text-main); - letter-spacing: -0.02em; -} - -.quiz-context-hint { - margin-top: 8px; - font-size: 14px; - color: var(--text-muted); - font-style: italic; -} - -.quiz-options-grid { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 14px; - margin-bottom: 16px; -} - -.quiz-option-btn { - display: flex; - align-items: center; - gap: 12px; - padding: 16px 18px; - background: var(--bg-main); - border: 2px solid var(--border-color); - border-radius: var(--radius-md); - color: var(--text-main); - font-size: 15px; - font-weight: 600; - text-align: left; - cursor: pointer; - transition: all 0.15s ease; - user-select: none; -} - -.quiz-option-btn:hover:not(:disabled) { - border-color: var(--primary); - background: var(--bg-surface-hover); - transform: translateY(-1px); -} - -.quiz-option-btn:disabled { - cursor: default; -} - -.quiz-opt-num { - width: 26px; - height: 26px; - border-radius: 50%; - background: var(--bg-surface); - border: 1px solid var(--border-color); - display: inline-flex; - align-items: center; - justify-content: center; - font-size: 12px; - font-weight: 700; - color: var(--text-muted); - flex-shrink: 0; -} - -.quiz-opt-text { - flex: 1; - line-height: 1.35; -} - -.quiz-option-btn.opt-correct { - background: rgba(34, 197, 94, 0.15) !important; - border-color: var(--success) !important; - color: var(--success) !important; -} - -.quiz-option-btn.opt-correct .quiz-opt-num { - background: var(--success); - color: #ffffff; - border-color: var(--success); -} - -.quiz-option-btn.opt-wrong { - background: rgba(239, 68, 68, 0.15) !important; - border-color: var(--danger) !important; - color: var(--danger) !important; - animation: shake 0.3s ease; -} - -.quiz-option-btn.opt-wrong .quiz-opt-num { - background: var(--danger); - color: #ffffff; - border-color: var(--danger); -} - -.quiz-next-bar { - margin-top: 16px; -} - -/* Active Typing Mode */ -.typing-hero { - text-align: center; - padding: 16px 0 20px 0; -} - -.typing-prompt-ru { - font-size: 28px; - font-weight: 800; - color: var(--primary); - margin: 8px 0; -} - -.typing-context-hint { - font-size: 14px; - color: var(--text-muted); - font-style: italic; - background: var(--bg-main); - padding: 8px 12px; - border-radius: var(--radius-sm); - display: inline-block; - max-width: 90%; - margin-top: 4px; -} - -/* Analytics & Activity Heatmap Modal */ -.stats-modal-window { - max-width: 820px; - width: 95%; -} - -.stats-hero-grid { - display: grid; - grid-template-columns: repeat(4, 1fr); - gap: 12px; - margin-bottom: 24px; -} - -.stat-kpi-card { - background: var(--bg-main); - border: 1px solid var(--border-color); - border-radius: var(--radius-md); - padding: 14px 12px; - text-align: center; - display: flex; - flex-direction: column; - align-items: center; - gap: 4px; -} - -.streak-kpi { - border-color: rgba(249, 115, 22, 0.4); - background: rgba(249, 115, 22, 0.05); -} - -.kpi-icon { - font-size: 24px; -} - -.kpi-value { - font-size: 26px; - font-weight: 800; - line-height: 1.1; -} - -.kpi-label { - font-size: 12px; - font-weight: 600; - color: var(--text-muted); -} - -.kpi-sub { - font-size: 11px; - color: var(--text-dim); -} - -.text-accent { - color: #38bdf8; -} - -/* GitHub Heatmap Section */ -.heatmap-section { - background: var(--bg-main); - border: 1px solid var(--border-color); - border-radius: var(--radius-md); - padding: 16px; - margin-bottom: 20px; -} - -.heatmap-header { - display: flex; - align-items: center; - justify-content: space-between; - margin-bottom: 14px; - flex-wrap: wrap; - gap: 8px; -} - -.heatmap-header h4 { - font-size: 15px; - font-weight: 700; -} - -.heatmap-legend { - display: flex; - align-items: center; - gap: 5px; - font-size: 11px; - color: var(--text-dim); -} - -.legend-cell { - width: 12px; - height: 12px; - border-radius: 2px; - display: inline-block; -} - -.heatmap-container-wrap { - overflow-x: auto; - padding-bottom: 6px; -} - -.heatmap-grid { - display: grid; - grid-auto-flow: column; - grid-template-rows: repeat(7, 12px); - gap: 4px; - min-width: 600px; -} - -.heatmap-cell { - width: 12px; - height: 12px; - border-radius: 2px; - background: rgba(255, 255, 255, 0.05); - cursor: pointer; - transition: transform 0.1s ease; - position: relative; -} - -.heatmap-cell:hover { - transform: scale(1.3); - z-index: 10; - outline: 1px solid var(--text-main); -} - -/* Heatmap Levels (GitHub-style intensity) */ -.lvl-0 { background: rgba(255, 255, 255, 0.06); } -.lvl-1 { background: #166534; } /* 1 review: soft green */ -.lvl-2 { background: #22c55e; } /* 2-3 reviews: vibrant green */ -.lvl-3 { background: #4ade80; } /* 4+ reviews: bright intense green */ - -[data-theme="light"] .lvl-0 { background: #e2e8f0; } -[data-theme="light"] .lvl-1 { background: #86efac; } -[data-theme="light"] .lvl-2 { background: #22c55e; } -[data-theme="light"] .lvl-3 { background: #15803d; } - -.heatmap-footer-note { - margin-top: 10px; - color: var(--text-dim); - font-size: 11px; -} - -/* Segmented Mastery Progress Bar */ -.mastery-section { - background: var(--bg-main); - border: 1px solid var(--border-color); - border-radius: var(--radius-md); - padding: 16px; -} - -.mastery-section h4 { - font-size: 15px; - font-weight: 700; - margin-bottom: 12px; -} - -.segmented-progress-bar { - display: flex; - height: 14px; - background: var(--bg-surface); - border-radius: var(--radius-full); - overflow: hidden; - margin-bottom: 12px; - border: 1px solid var(--border-color); -} - -.prog-segment { - height: 100%; - transition: width 0.3s ease; -} - -.seg-mastered { background: #22c55e; } -.seg-review { background: #38bdf8; } -.seg-learning { background: #f59e0b; } -.seg-new { background: #64748b; } - -.mastery-legend-row { - display: flex; - gap: 16px; - flex-wrap: wrap; - font-size: 12px; -} - -.m-legend-item { - display: flex; - align-items: center; - gap: 6px; - color: var(--text-muted); -} - -.dot { - width: 8px; - height: 8px; - border-radius: 50%; - display: inline-block; -} - -.dot-mastered { background: #22c55e; } -.dot-review { background: #38bdf8; } -.dot-learning { background: #f59e0b; } -.dot-new { background: #64748b; } -.dot-leech { background: #ef4444; } - -.text-danger { color: #ef4444; } - -@keyframes shake { - 0%, 100% { transform: translateX(0); } - 25% { transform: translateX(-4px); } - 75% { transform: translateX(4px); } -} - -/* Mobile Navigation & Tab Bar (iOS Native Style Base) */ -.mobile-only-btn, -.mobile-tab-bar, -.mobile-only { - display: none; -} - -.mobile-tab-bar { - position: fixed; - bottom: 0; - left: 0; - right: 0; - height: calc(56px + env(safe-area-inset-bottom, 0px)); - padding-bottom: env(safe-area-inset-bottom, 0px); - background-color: rgba(30, 41, 59, 0.94); - backdrop-filter: blur(16px); - -webkit-backdrop-filter: blur(16px); - border-top: 1px solid var(--border-color); - z-index: 1000; - align-items: center; - justify-content: space-around; -} - -[data-theme="light"] .mobile-tab-bar { - background-color: rgba(255, 255, 255, 0.94); -} - -.tab-item { - flex: 1; - height: 100%; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - gap: 3px; - background: none; - border: none; - color: var(--text-muted); - cursor: pointer; - position: relative; - padding: 6px 0; - -webkit-tap-highlight-color: transparent; - transition: var(--transition); -} - -.tab-item:active { - transform: scale(0.92); -} - -.tab-item.active { - color: var(--primary); -} - -.tab-icon { - font-size: 19px; - line-height: 1; -} - -.tab-label { - font-size: 10px; - font-weight: 600; - letter-spacing: -0.2px; -} - -.tab-badge { - position: absolute; - top: 5px; - right: calc(50% - 18px); - background-color: #ef4444; - color: #ffffff; - font-size: 10px; - font-weight: 700; - padding: 1px 5px; - border-radius: 9999px; - line-height: 1.2; -} - -/* Mobile Sheet / Menu */ -.mobile-sheet-window { - max-width: 440px; -} - -.mobile-user-card { - display: flex; - align-items: center; - gap: 12px; - padding: 14px 16px; - background: var(--bg-input); - border: 1px solid var(--border-color); - border-radius: var(--radius-md); - margin-bottom: 16px; -} - -.mobile-user-avatar { - font-size: 28px; - background: var(--bg-surface-hover); - width: 48px; - height: 48px; - display: flex; - align-items: center; - justify-content: center; - border-radius: var(--radius-full); -} - -.mobile-user-info strong { - font-size: 16px; - color: var(--text-main); -} - -.mobile-user-info .subtitle { - font-size: 12px; - color: var(--text-muted); -} - -.mobile-menu-actions { - display: flex; - flex-direction: column; - gap: 10px; -} - -/* Sheet drag handle for mobile bottom sheets */ -.sheet-drag-handle { - width: 38px; - height: 4px; - border-radius: 2px; - background-color: var(--border-color); - margin: 0 auto 10px auto; -} - /* ========================================================================== - Comprehensive Mobile & Responsive System (iPhone 12 / iOS WebKit & Mobile) - ========================================================================== */ -@media (max-width: 768px) { - /* 1. iOS Safari Auto-Zoom Fix (< 16px triggers zoom) */ - input, select, textarea, - .input-styled, .search-input-box input, .form-group input, - .search-mini-box input, .reader-select { - font-size: 16px !important; - } - - /* 2. Global Mobile App Container & Safe Areas */ - html, body { - overflow-x: hidden; - -webkit-overflow-scrolling: touch; - min-height: 100dvh; - } - - .app-shell { - min-height: 100dvh; - overflow-x: hidden; - } - - .main-content, - .srs-view, - .reader-view { - padding-bottom: calc(74px + env(safe-area-inset-bottom, 0px)) !important; - } - - /* 3. Header & Navigation: Unified Responsive Header */ - .navbar { - padding: calc(8px + env(safe-area-inset-top, 0px)) 10px 8px 10px; - gap: 8px; - } - - .brand-sub, - .nav-stats { - display: none !important; - } - - .btn-trainer .trainer-text { - display: none !important; - } - - .btn-trainer { - padding: 6px 10px !important; - font-size: 13px !important; - min-height: 36px; - } - - .user-profile-btn #user-display-name { - display: none !important; - } - - .user-profile-btn { - padding: 6px 10px !important; - border-radius: var(--radius-sm); - min-height: 36px; - } - - .mobile-tab-bar { - display: flex !important; - } - - .mobile-only { - display: block !important; - } - - /* 4. Dictionary & Search */ - .main-content { - padding: 14px 12px calc(76px + env(safe-area-inset-bottom, 0px)); - gap: 20px; - } - - .search-input-box { - padding: 6px 8px 6px 12px; - } - - .search-input-box input { - padding: 8px 0; - min-width: 0; - } - - .translate-action-btn { - padding: 8px 14px; - font-size: 14px; - white-space: nowrap; - } - - .hotkey-hints { - display: none !important; - } - - .lookup-card { - padding: 16px 14px; - } - - .lookup-header { - flex-direction: column; - align-items: flex-start; - gap: 8px; - } - - .meta-inputs-grid .field-row { - flex-direction: column; - gap: 12px; - } - - .result-actions .btn { - width: 100%; - justify-content: center; - min-height: 48px; - } - - .result-actions .btn-subtext { - display: none; - } - - /* Horizontal scrollable chips for collections and tags */ - .filter-chips-row { - flex-wrap: nowrap; - overflow-x: auto; - -webkit-overflow-scrolling: touch; - padding-bottom: 6px; - scrollbar-width: none; - } - - .filter-chips-row::-webkit-scrollbar { - display: none; - } - - .col-chip, .filter-chip { - flex-shrink: 0; - } - - .list-controls { - width: 100%; - display: flex; - align-items: center; - gap: 8px; - margin-top: 10px; - } - - .section-header { - flex-direction: column; - align-items: stretch; - } - - .search-mini-box { - flex: 1; - min-width: 0; - } - - .search-mini-box input { - width: 100%; - min-width: 0; - } - - /* Cards */ - .vocab-card { - padding: 14px; - gap: 8px; - } - - .card-top { - gap: 8px; - } - - .card-term { - font-size: 17px; - } - - .card-actions .icon-btn { - min-width: 36px; - min-height: 36px; - display: flex; - align-items: center; - justify-content: center; - } - - .card-bottom { - font-size: 11px; - } - - /* 5. SRS Trainer */ - .srs-topbar { - padding: 10px 12px; - flex-direction: column; - align-items: stretch; - gap: 8px; - } - - .srs-topbar-left, .srs-topbar-right { - justify-content: space-between; - width: 100%; - } - - .srs-mode-switch { - overflow-x: auto; - -webkit-overflow-scrolling: touch; - scrollbar-width: none; - } - - .srs-mode-switch::-webkit-scrollbar { - display: none; - } - - .srs-tab { - flex-shrink: 0; - padding: 6px 10px; - font-size: 12px; - } - - .flashcard-wrapper { - min-height: 270px; - max-height: 48dvh; - } - - .flashcard-inner { - min-height: 270px; - } - - .fc-main-term { - font-size: 28px; - } - - .fc-footer-hint { - font-size: 11px; - } - - .srs-rating-bar { - grid-template-columns: 1fr 1fr; - gap: 8px; - width: 100%; - } - - .btn-rate { - min-height: 48px; - padding: 8px 6px; - } - - .rate-key { - display: none; - } - - .quiz-options-grid { - grid-template-columns: 1fr; - gap: 8px; - } - - .quiz-option-btn { - min-height: 48px; - font-size: 14px; - padding: 10px 14px; - } - - /* 6. Bookshelf & Reader View */ - .reader-view { - padding: 14px 12px calc(76px + env(safe-area-inset-bottom, 0px)); - } - - .bookshelf-header { - flex-direction: column; - align-items: stretch; - gap: 12px; - margin-bottom: 18px; - } - - .bookshelf-title-wrap h2 { - font-size: 19px; - } - - .bookshelf-actions { - width: 100%; - display: flex; - gap: 8px; - } - - .bookshelf-actions .btn, - .bookshelf-actions .file-upload-label { - flex: 1; - justify-content: center; - text-align: center; - padding: 10px; - } - - .bookshelf-grid { - grid-template-columns: 1fr; - gap: 12px; - } - - .book-card { - padding: 14px; - } - - /* Reader Interface Toolbar */ - .reader-toolbar { - position: static !important; - top: auto !important; - box-shadow: none !important; - padding: 8px 10px; - gap: 8px; - flex-direction: column; - align-items: stretch; - } - - .reader-toolbar-left { - width: 100%; - justify-content: space-between; - gap: 8px; - } - - .reader-meta { - flex: 1; - min-width: 0; - } - - .reader-title { - font-size: 14px; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - } - - .reader-author { - font-size: 11px; - } - - .reader-toolbar-center { - width: 100%; - justify-content: space-between; - gap: 6px; - } - - .reader-select { - flex: 1; - max-width: none; - min-width: 0; - } - - .reader-toolbar-right { - width: 100%; - justify-content: space-between; - gap: 6px; - border-top: 1px solid var(--border-color); - padding-top: 6px; - } - - .reader-content-body { - padding: 14px 12px; - font-size: 17px; - line-height: 1.65; - } - - /* 7. Bottom Sheet for Word Translation Popup on Mobile */ - .reader-word-popup { - position: fixed !important; - top: auto !important; - bottom: calc(58px + env(safe-area-inset-bottom, 0px)) !important; - left: 8px !important; - right: 8px !important; - width: auto !important; - max-width: none !important; - border-radius: 18px !important; - box-shadow: 0 -8px 30px rgba(0, 0, 0, 0.5) !important; - border: 1px solid var(--border-focus) !important; - background-color: var(--bg-surface) !important; - z-index: 10005 !important; - padding: 14px 16px !important; - animation: slideUpSheet 0.22s cubic-bezier(0.16, 1, 0.3, 1) !important; - } - - .reader-settings-panel { - position: fixed !important; - top: auto !important; - bottom: calc(58px + env(safe-area-inset-bottom, 0px)) !important; - left: 8px !important; - right: 8px !important; - width: auto !important; - max-height: calc(85dvh - 60px) !important; - overflow-y: auto !important; - -webkit-overflow-scrolling: touch !important; - border-radius: 20px !important; - box-shadow: 0 -8px 32px rgba(0, 0, 0, 0.55) !important; - border: 1px solid var(--border-focus) !important; - background-color: var(--bg-surface) !important; - color: var(--text-main) !important; - padding: 16px 18px 24px !important; - z-index: 10006 !important; - animation: slideUpSheet 0.22s cubic-bezier(0.16, 1, 0.3, 1) !important; - } - - @keyframes slideUpSheet { - from { - transform: translateY(100%); - opacity: 0; - } - to { - transform: translateY(0); - opacity: 1; - } - } - - /* 8. Modals: Mobile Bottom-Sheet style */ - .modal-backdrop { - padding: 0; - align-items: flex-end; - } - - .modal-window { - max-width: 100%; - max-height: calc(90dvh - env(safe-area-inset-top, 0px)); - border-radius: 20px 20px 0 0; - border-bottom: none; - overflow-y: auto; - -webkit-overflow-scrolling: touch; - padding-bottom: env(safe-area-inset-bottom, 0px); - animation: slideUpSheet 0.22s cubic-bezier(0.16, 1, 0.3, 1); - } - - .stats-modal-window { - width: 100%; - max-width: 100%; - } - - .stats-hero-grid { - grid-template-columns: 1fr 1fr; - gap: 8px; - } - - .heatmap-container-wrap { - -webkit-overflow-scrolling: touch; - } - - /* 9. Batch action bar */ - .batch-action-bar { - flex-direction: column; - gap: 10px; - bottom: calc(64px + env(safe-area-inset-bottom, 0px)) !important; - left: 10px; - right: 10px; - } - - .batch-actions { - width: 100%; - justify-content: space-between; - } -} - -/* ========================================================================== - Stage 5: Interactive Reader & Bookshelf Styles + Notes App — Unified Master Stylesheet (Stage 5 Architecture) + ========================================================================== + This master stylesheet orchestrates the modular CSS architecture for the + Notes English learning platform (notes.qpid.pro). + + Architecture Overview: + -------------------------------------------------------------------------- + 1. base.css - Design tokens (:root variables, dark/light themes), + resets, global typography, scrollbars, safe areas. + 2. components.css - Core UI components: auth overlays, navigation drawer, + buttons, form controls, modals, and mobile tab bar. + 3. dictionary.css - Term lookup, live search preview, cards list, tags, + collections, batch action bar, and word translation popup. + 4. srs.css - Spaced repetition trainer: 3D flip flashcards, quiz, + active typing, dictation, heatmap & mastery progress. + 5. reader.css - Interactive reader & bookshelf: continuous reading, + typography controls, appearance themes, and Wikipedia. + 6. grammar_cefr.css - CEFR level testing, automated gap ingestion, Murphy + grammar units, deep work theory modal, and cloze tap. + 7. lesson.css - Lesson configurator, syllabus suggestions, session + runner (vocab, grammar, listening, reading, AI debrief). + + Offline Support: + All modular stylesheets are registered in sw.js PRECACHE_URLS for seamless + offline PWA usage across desktop and mobile devices. ========================================================================== */ -.reader-view { - max-width: 1100px; - margin: 0 auto; - padding: 24px 20px 80px; -} - -.bookshelf-header { - display: flex; - justify-content: space-between; - align-items: center; - flex-wrap: wrap; - gap: 16px; - margin-bottom: 28px; - padding-bottom: 20px; - border-bottom: 1px solid var(--border-color); -} - -.bookshelf-title-wrap h2 { - font-size: 24px; - font-weight: 700; - color: var(--text-main); - display: flex; - align-items: center; - gap: 8px; -} - -.bookshelf-title-wrap .subtitle { - font-size: 14px; - color: var(--text-muted); - margin-top: 4px; -} - -.bookshelf-actions { - display: flex; - align-items: center; - gap: 12px; -} - -.file-upload-label { - cursor: pointer; - display: inline-flex; - align-items: center; - gap: 6px; -} - -.bookshelf-grid { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); - gap: 20px; -} - -.book-card { - background-color: var(--bg-surface); - border: 1px solid var(--border-color); - border-radius: var(--radius-lg); - padding: 20px; - display: flex; - flex-direction: column; - justify-content: space-between; - transition: var(--transition); - position: relative; - box-shadow: var(--shadow-sm); -} - -.book-card:hover { - border-color: var(--border-focus); - box-shadow: var(--shadow-md); - transform: translateY(-2px); -} - -.book-card-top { - display: flex; - align-items: flex-start; - gap: 14px; - margin-bottom: 14px; -} - -.book-cover-icon { - font-size: 32px; - background: var(--bg-input); - border: 1px solid var(--border-color); - border-radius: var(--radius-md); - width: 52px; - height: 64px; - display: flex; - align-items: center; - justify-content: center; - flex-shrink: 0; -} - -.book-card-info { - flex: 1; - min-width: 0; -} - -.book-card-title { - font-size: 16px; - font-weight: 700; - color: var(--text-main); - margin-bottom: 4px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -.book-card-author { - font-size: 13px; - color: var(--text-muted); - margin-bottom: 8px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -.book-card-badges { - display: flex; - align-items: center; - gap: 8px; -} - -.badge-format { - text-transform: uppercase; - font-size: 10px; - font-weight: 700; - padding: 2px 6px; - border-radius: var(--radius-sm); - background: var(--tag-bg); - color: var(--tag-text); -} - -.badge-words { - font-size: 12px; - color: var(--text-dim); -} - -.book-progress-wrap { - margin: 14px 0 16px; -} - -.book-progress-labels { - display: flex; - justify-content: space-between; - font-size: 12px; - color: var(--text-dim); - margin-bottom: 6px; -} - -.book-progress-bar-bg { - width: 100%; - height: 6px; - background-color: var(--bg-input); - border-radius: var(--radius-full); - overflow: hidden; -} - -.book-progress-bar-fill { - height: 100%; - background-color: var(--primary); - border-radius: var(--radius-full); - transition: width 0.3s ease; -} - -.book-card-actions { - display: flex; - align-items: center; - justify-content: space-between; - gap: 8px; - padding-top: 12px; - border-top: 1px solid var(--border-color); -} - -/* Bookshelf Divider between General Books & RFC Specifications */ -.bookshelf-divider { - margin: 48px 0 36px; - border: 0; - height: 1px; - background: linear-gradient(90deg, transparent, var(--border-color) 15%, var(--border-color) 85%, transparent); -} - -/* RFC Specifications Section */ -.rfc-section { - margin-top: 8px; -} - -.rfc-header { - margin-bottom: 20px; -} - -.rfc-title-row { - display: flex; - align-items: center; - gap: 14px; -} - -.rfc-icon-badge { - display: inline-flex; - align-items: center; - justify-content: center; - width: 44px; - height: 44px; - font-size: 24px; - background: rgba(14, 165, 233, 0.12); - border: 1px solid rgba(14, 165, 233, 0.28); - border-radius: var(--radius-md); - flex-shrink: 0; -} - -.rfc-heading { - font-size: 20px; - font-weight: 700; - color: var(--text-main); - margin: 0; -} - -.rfc-fetch-box { - background: var(--bg-surface); - border: 1px solid var(--border-color); - border-radius: var(--radius-lg); - padding: 20px 24px; - margin-bottom: 24px; - box-shadow: var(--shadow-sm); -} - -.rfc-fetch-form { - margin-bottom: 16px; -} - -.rfc-input-wrap { - display: flex; - align-items: stretch; - gap: 10px; -} - -.rfc-input-prefix { - display: inline-flex; - align-items: center; - padding: 0 14px; - font-weight: 700; - font-size: 13px; - letter-spacing: 0.05em; - color: #38bdf8; - background: rgba(56, 189, 248, 0.12); - border: 1px solid rgba(56, 189, 248, 0.25); - border-radius: var(--radius-md); - user-select: none; -} - -.rfc-input { - flex: 1; - min-width: 0; -} - -.rfc-fetch-btn { - white-space: nowrap; - padding: 0 20px; - display: inline-flex; - align-items: center; - justify-content: center; - font-weight: 600; -} - -.rfc-fetch-status { - margin-top: 10px; - padding: 8px 14px; - font-size: 13px; - border-radius: var(--radius-md); - transition: all 0.2s ease; -} - -.rfc-status-loading { - background: rgba(14, 165, 233, 0.1); - color: #38bdf8; - border: 1px solid rgba(14, 165, 233, 0.25); -} - -.rfc-status-success { - background: rgba(34, 197, 94, 0.12); - color: #4ade80; - border: 1px solid rgba(34, 197, 94, 0.25); -} - -.rfc-status-error { - background: rgba(239, 68, 68, 0.12); - color: #f87171; - border: 1px solid rgba(239, 68, 68, 0.25); -} - -.rfc-presets-wrap { - display: flex; - flex-direction: column; - gap: 10px; -} - -.rfc-presets-label { - font-size: 12px; - text-transform: uppercase; - font-weight: 600; - letter-spacing: 0.05em; - color: var(--text-dim); -} - -.rfc-presets-list { - display: flex; - flex-wrap: wrap; - gap: 8px; -} - -.rfc-preset-chip { - background: var(--bg-input); - color: var(--text-main); - border: 1px solid var(--border-color); - border-radius: var(--radius-full); - padding: 6px 14px; - font-size: 12.5px; - font-weight: 500; - cursor: pointer; - transition: var(--transition); - user-select: none; - display: inline-flex; - align-items: center; - gap: 5px; -} - -.rfc-preset-chip:hover { - background: rgba(14, 165, 233, 0.15); - border-color: #38bdf8; - color: #38bdf8; - transform: translateY(-1px); -} - -.rfc-empty-state { - padding: 36px 20px; - background: var(--bg-surface); - border: 1px dashed var(--border-color); - border-radius: var(--radius-lg); - margin-bottom: 24px; -} - -.rfc-card { - border-color: rgba(56, 189, 248, 0.2); -} - -.rfc-card:hover { - border-color: rgba(56, 189, 248, 0.5); - box-shadow: 0 8px 24px rgba(14, 165, 233, 0.12); -} - -.rfc-cover-icon { - background: rgba(14, 165, 233, 0.1); - border-color: rgba(14, 165, 233, 0.25); -} - -.badge-rfc { - background: rgba(14, 165, 233, 0.2); - color: #38bdf8; - border: 1px solid rgba(14, 165, 233, 0.35); -} - -.rfc-progress-fill { - background: linear-gradient(90deg, #0284c7, #38bdf8); -} - -@media (max-width: 640px) { - .rfc-input-wrap { - flex-direction: column; - } - .rfc-input-prefix { - display: none; - } - .rfc-fetch-btn { - width: 100%; - padding: 10px 16px; - } -} - -/* ========================================================================== - Wikipedia Articles Section & Settings Modal - ========================================================================== */ - -.wiki-section { - margin-top: 8px; -} - -.wiki-header { - margin-bottom: 20px; -} - -.wiki-title-row { - display: flex; - align-items: center; - gap: 14px; -} - -.wiki-icon-badge { - display: inline-flex; - align-items: center; - justify-content: center; - width: 44px; - height: 44px; - font-size: 24px; - background: rgba(168, 85, 247, 0.12); - border: 1px solid rgba(168, 85, 247, 0.28); - border-radius: var(--radius-md); - flex-shrink: 0; -} - -.wiki-heading { - font-size: 20px; - font-weight: 700; - color: var(--text-main); - margin: 0; -} - -.wiki-action-box { - background: var(--bg-surface); - border: 1px solid var(--border-color); - border-radius: var(--radius-lg); - padding: 20px 24px; - margin-bottom: 24px; - box-shadow: var(--shadow-sm); -} - -.wiki-primary-actions { - display: flex; - align-items: center; - gap: 12px; - flex-wrap: wrap; - margin-bottom: 14px; -} - -.wiki-read-btn { - padding: 10px 24px; - font-weight: 700; - font-size: 15px; - background: linear-gradient(135deg, #6366f1, #8b5cf6); - border: none; - box-shadow: 0 4px 14px rgba(99, 102, 241, 0.35); - transition: all 0.2s ease; -} - -.wiki-read-btn:hover { - background: linear-gradient(135deg, #4f46e5, #7c3aed); - transform: translateY(-1px); - box-shadow: 0 6px 18px rgba(99, 102, 241, 0.45); -} - -.wiki-settings-btn { - padding: 10px 18px; - font-weight: 600; - border-color: rgba(168, 85, 247, 0.35); - color: var(--text-main); -} - -.wiki-settings-btn:hover { - background: rgba(168, 85, 247, 0.12); - border-color: #a855f7; - color: #c084fc; -} - -.wiki-badges-row { - display: flex; - align-items: center; - gap: 8px; - flex-wrap: wrap; - font-size: 13px; -} - -.wiki-badges-label { - color: var(--text-dim); - font-size: 12px; - text-transform: uppercase; - font-weight: 600; - letter-spacing: 0.05em; - margin-right: 4px; -} - -.wiki-badge-chip { - background: rgba(168, 85, 247, 0.12); - color: #c084fc; - border: 1px solid rgba(168, 85, 247, 0.28); - border-radius: var(--radius-full); - padding: 4px 12px; - font-weight: 500; - font-size: 12px; - display: inline-flex; - align-items: center; - gap: 4px; -} - -.wiki-fetch-status { - margin-top: 14px; - padding: 10px 16px; - font-size: 13.5px; - border-radius: var(--radius-md); - transition: all 0.2s ease; -} - -.wiki-status-loading { - background: rgba(99, 102, 241, 0.12); - color: #818cf8; - border: 1px solid rgba(99, 102, 241, 0.3); -} - -.wiki-status-success { - background: rgba(34, 197, 94, 0.12); - color: #4ade80; - border: 1px solid rgba(34, 197, 94, 0.25); -} - -.wiki-status-error { - background: rgba(239, 68, 68, 0.12); - color: #f87171; - border: 1px solid rgba(239, 68, 68, 0.25); -} - -.wiki-empty-state { - padding: 36px 20px; - background: var(--bg-surface); - border: 1px dashed var(--border-color); - border-radius: var(--radius-lg); - margin-bottom: 24px; -} - -/* Card styling for Wikipedia and thumbnails */ -.wiki-card { - border-color: rgba(168, 85, 247, 0.22); -} - -.wiki-card:hover { - border-color: rgba(168, 85, 247, 0.55); - box-shadow: 0 8px 24px rgba(168, 85, 247, 0.15); -} - -.wiki-cover-icon { - background: rgba(168, 85, 247, 0.12); - border-color: rgba(168, 85, 247, 0.3); - color: #c084fc; -} - -.badge-wiki { - background: rgba(168, 85, 247, 0.18); - color: #c084fc; - border: 1px solid rgba(168, 85, 247, 0.35); -} - -.wiki-progress-fill { - background: linear-gradient(90deg, #7c3aed, #a855f7); -} - -.book-cover-img-wrap { - width: 52px; - height: 64px; - border-radius: var(--radius-sm); - overflow: hidden; - flex-shrink: 0; - background: rgba(0, 0, 0, 0.2); - border: 1px solid var(--border-color); - display: flex; - align-items: center; - justify-content: center; -} - -.book-cover-img { - width: 100%; - height: 100%; - object-fit: cover; - display: block; -} - -.badge-time { - display: inline-flex; - align-items: center; - gap: 3px; - background: rgba(255, 255, 255, 0.06); - color: var(--text-dim); - font-size: 11px; - font-weight: 500; - padding: 2px 7px; - border-radius: var(--radius-sm); - border: 1px solid rgba(255, 255, 255, 0.08); -} - -/* Wikipedia Settings Modal */ -.wiki-modal-window { - max-width: 620px; - width: 95%; -} - -.wiki-modal-body { - display: flex; - flex-direction: column; - gap: 22px; -} - -.wiki-setting-group { - display: flex; - flex-direction: column; - gap: 10px; -} - -.wiki-group-label { - font-size: 13.5px; - font-weight: 700; - color: var(--text-main); - letter-spacing: 0.02em; -} - -.wiki-radio-cards { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 12px; -} - -.wiki-radio-card { - display: flex; - align-items: flex-start; - gap: 12px; - padding: 14px 16px; - background: var(--bg-input); - border: 1px solid var(--border-color); - border-radius: var(--radius-md); - cursor: pointer; - transition: all 0.2s ease; - user-select: none; -} - -.wiki-radio-card:hover { - border-color: rgba(168, 85, 247, 0.4); - background: rgba(168, 85, 247, 0.04); -} - -.wiki-radio-card:has(input:checked) { - border-color: #a855f7; - background: rgba(168, 85, 247, 0.1); - box-shadow: 0 0 0 1px #a855f7; -} - -.wiki-radio-card input[type="radio"] { - margin-top: 3px; - accent-color: #a855f7; -} - -.wiki-radio-card-content { - display: flex; - flex-direction: column; - gap: 5px; -} - -.wiki-card-title-row { - display: flex; - align-items: center; - justify-content: space-between; - gap: 8px; -} - -.wiki-card-desc { - font-size: 12px; - color: var(--text-dim); - line-height: 1.45; - margin: 0; -} - -.badge-level-pill { - font-size: 10.5px; - font-weight: 700; - padding: 1px 7px; - border-radius: var(--radius-full); - text-transform: uppercase; - letter-spacing: 0.04em; -} - -.badge-level-a2 { - background: rgba(34, 197, 94, 0.2); - color: #4ade80; - border: 1px solid rgba(34, 197, 94, 0.35); -} - -.badge-level-b2 { - background: rgba(59, 130, 246, 0.2); - color: #60a5fa; - border: 1px solid rgba(59, 130, 246, 0.35); -} - -.wiki-time-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); - gap: 8px; -} - -.wiki-time-pill { - display: flex; - align-items: center; - position: relative; - cursor: pointer; - user-select: none; -} - -.wiki-time-pill input[type="radio"] { - position: absolute; - opacity: 0; - pointer-events: none; -} - -.wiki-pill-text { - width: 100%; - display: flex; - flex-direction: column; - align-items: center; - text-align: center; - padding: 10px 8px; - background: var(--bg-input); - border: 1px solid var(--border-color); - border-radius: var(--radius-md); - font-size: 13px; - font-weight: 600; - color: var(--text-main); - transition: all 0.2s ease; -} - -.wiki-pill-text small { - font-size: 11px; - font-weight: normal; - margin-top: 2px; -} - -.wiki-time-pill:hover .wiki-pill-text { - border-color: rgba(168, 85, 247, 0.4); -} - -.wiki-time-pill input[type="radio"]:checked + .wiki-pill-text { - border-color: #a855f7; - background: rgba(168, 85, 247, 0.12); - color: #c084fc; - box-shadow: 0 0 0 1px #a855f7; -} - -.wiki-select { - width: 100%; - padding: 10px 14px; - font-size: 14px; -} - -.wiki-direct-import-group { - border-top: 1px dashed var(--border-color); - padding-top: 18px; -} - -.wiki-custom-input-wrap { - display: flex; - align-items: center; - gap: 10px; -} - -.wiki-custom-input { - flex: 1; - min-width: 0; -} - -.wiki-custom-fetch-btn { - white-space: nowrap; - padding: 0 18px; - font-weight: 600; -} - -@media (max-width: 640px) { - .wiki-radio-cards { - grid-template-columns: 1fr; - } - .wiki-custom-input-wrap { - flex-direction: column; - } - .wiki-custom-fetch-btn { - width: 100%; - padding: 10px 16px; - } -} - -/* Reader Interface */ -.reader-interface { - background-color: var(--bg-surface); - border: 1px solid var(--border-color); - border-radius: var(--radius-lg); - box-shadow: var(--shadow-lg); -} - -.reader-toolbar { - position: sticky; - top: var(--navbar-height, 60px); - z-index: 1000; - background-color: var(--bg-surface); - border-top-left-radius: var(--radius-lg); - border-top-right-radius: var(--radius-lg); - border-bottom: 1px solid var(--border-color); - padding: 12px 18px; - display: flex; - justify-content: space-between; - align-items: center; - flex-wrap: wrap; - gap: 12px; - box-shadow: 0 4px 14px rgba(0, 0, 0, 0.15); -} - -.reader-toolbar-left { - display: flex; - align-items: center; - gap: 14px; -} - -.reader-meta { - display: flex; - flex-direction: column; -} - -.reader-title { - font-size: 16px; - font-weight: 700; - color: var(--text-main); - line-height: 1.2; -} - -.reader-author { - font-size: 12px; - color: var(--text-muted); -} - -.reader-toolbar-center { - display: flex; - align-items: center; - gap: 8px; -} - -.reader-select { - padding: 6px 12px; - border-radius: var(--radius-sm); - background-color: var(--bg-input); - color: var(--text-main); - border: 1px solid var(--border-color); - font-size: 13px; - outline: none; - max-width: 240px; -} - -.reader-progress-badge { - font-size: 11px; - font-weight: 700; - font-variant-numeric: tabular-nums; - color: var(--primary); - background: var(--primary-dim); - border: 1px solid rgba(56, 189, 248, 0.35); - padding: 3px 8px; - border-radius: var(--radius-full); - min-width: 40px; - text-align: center; - display: inline-block; - user-select: none; - line-height: 1.2; -} - -.reader-chapter-progress-bar { - position: absolute; - left: 0; - right: 0; - bottom: -1px; - height: 3px; - background-color: rgba(255, 255, 255, 0.08); - overflow: hidden; - pointer-events: none; -} - -.reader-chapter-progress-fill { - height: 100%; - width: 0%; - background: linear-gradient(90deg, #0284c7, #38bdf8); - box-shadow: 0 0 8px rgba(56, 189, 248, 0.5); - transition: width 0.12s cubic-bezier(0.16, 1, 0.3, 1); -} - -.reader-toolbar-right { - display: flex; - align-items: center; - gap: 10px; -} - -.font-controls { - display: flex; - align-items: center; - gap: 4px; -} - -.reader-scroll-area { - --reader-font-size: 18px; - --reader-line-height: 1.65; - --reader-font-family: 'Literata', 'Merriweather', 'Georgia', 'Cambria', serif; - --reader-max-width: 760px; - --reader-padding-h: 24px; - --reader-text-align: left; - --reader-bg: var(--bg-surface); - --reader-text: var(--text-main); - - background-color: var(--reader-bg); - min-height: 60vh; - padding: 0; - transition: background-color 0.2s ease, color 0.2s ease; -} - -.reader-content-body { - max-width: var(--reader-max-width); - margin: 0 auto; - padding: 32px var(--reader-padding-h) 80px; - font-family: var(--reader-font-family); - font-size: var(--reader-font-size); - line-height: var(--reader-line-height); - text-align: var(--reader-text-align); - color: var(--reader-text); - word-break: break-word; - user-select: text; - transition: font-size 0.15s ease, line-height 0.15s ease, max-width 0.2s ease, padding 0.2s ease; -} - -/* Reader Appearance Themes */ -.reader-scroll-area.reader-theme-sepia { - --reader-bg: #fbf0d9; - --reader-text: #433422; -} -.reader-scroll-area.reader-theme-sepia .reader-word:hover { - background-color: rgba(217, 119, 6, 0.25); - color: #92400e; -} -.reader-scroll-area.reader-theme-sepia blockquote { - background-color: #f4e4c1; - border-color: #d6bc97; - color: #5f4b32; -} -.reader-scroll-area.reader-theme-sepia .reader-inline-code, -.reader-scroll-area.reader-theme-sepia .reader-code-wrap pre { - background-color: #efe0bc; - color: #433422; - border-color: #dec89f; -} -.reader-scroll-area.reader-theme-sepia .reader-table th, -.reader-scroll-area.reader-theme-sepia .reader-table td { - border-color: #dec89f; -} - -.reader-scroll-area.reader-theme-light { - --reader-bg: #ffffff; - --reader-text: #1e293b; -} -.reader-scroll-area.reader-theme-light blockquote { - background-color: #f8fafc; - border-color: #cbd5e1; - color: #334155; -} -.reader-scroll-area.reader-theme-light .reader-inline-code, -.reader-scroll-area.reader-theme-light .reader-code-wrap pre { - background-color: #f1f5f9; - color: #0f172a; - border-color: #e2e8f0; -} -.reader-scroll-area.reader-theme-light .reader-word:hover { - background-color: rgba(2, 132, 199, 0.15); - color: #0284c7; -} - -.reader-scroll-area.reader-theme-oled { - --reader-bg: #000000; - --reader-text: #d8e2ec; -} -.reader-scroll-area.reader-theme-oled blockquote { - background-color: #0a0e17; - border-color: #1e293b; -} -.reader-scroll-area.reader-theme-oled .reader-inline-code, -.reader-scroll-area.reader-theme-oled .reader-code-wrap pre { - background-color: #0a0e17; - border-color: #1e293b; -} - -.reader-scroll-area.reader-theme-dark { - --reader-bg: var(--bg-surface); - --reader-text: var(--text-main); -} - -/* Reader Font Families */ -.reader-scroll-area.reader-font-sans { - --reader-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; -} -.reader-scroll-area.reader-font-serif { - --reader-font-family: 'Literata', 'Merriweather', 'Georgia', 'Cambria', 'Times New Roman', serif; -} -.reader-scroll-area.reader-font-mono { - --reader-font-family: 'JetBrains Mono', 'Fira Code', 'Menlo', 'Consolas', monospace; -} - -/* Reader Margin & Width Variants */ -.reader-scroll-area.reader-margins-narrow { - --reader-max-width: 940px; - --reader-padding-h: 12px; -} -.reader-scroll-area.reader-margins-normal { - --reader-max-width: 760px; - --reader-padding-h: 24px; -} -.reader-scroll-area.reader-margins-wide { - --reader-max-width: 600px; - --reader-padding-h: 36px; -} - -/* Reader Text Alignment */ -.reader-scroll-area.reader-align-left { - --reader-text-align: left; -} -.reader-scroll-area.reader-align-justify { - --reader-text-align: justify; - hyphens: auto; -} - -/* Reader Appearance Settings Panel / Sheet */ -.reader-settings-panel { - position: fixed; - top: 64px; - right: 28px; - width: 330px; - max-width: calc(100vw - 32px); - max-height: calc(100vh - 80px); - display: flex; - flex-direction: column; - background-color: var(--bg-surface); - border: 1px solid var(--border-focus); - border-radius: var(--radius-lg); - box-shadow: 0 16px 36px rgba(0, 0, 0, 0.45); - z-index: 10006; - padding: 16px; - animation: fadeIn 0.15s ease-out; -} - -.reader-settings-header { - display: flex; - justify-content: space-between; - align-items: center; - flex-shrink: 0; - margin-bottom: 12px; - padding-bottom: 8px; - border-bottom: 1px solid var(--border-color); -} - -.reader-settings-header h4 { - font-size: 15px; - font-weight: 700; - color: var(--text-main); -} - -.reader-settings-body { - display: flex; - flex-direction: column; - gap: 12px; - overflow-y: auto; - padding-right: 4px; - scrollbar-width: thin; - scrollbar-color: var(--border-focus) transparent; -} - -.reader-settings-body::-webkit-scrollbar { - width: 6px; -} - -.reader-settings-body::-webkit-scrollbar-thumb { - background-color: var(--border-focus); - border-radius: 3px; -} - -.setting-row { - display: flex; - flex-direction: column; - gap: 6px; -} - -.setting-row-grid { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 8px; - align-items: flex-end; -} - -.setting-row-grid .seg-btn { - padding: 6px 4px; - font-size: 11.5px; -} - -.setting-label { - font-size: 11px; - font-weight: 700; - text-transform: uppercase; - letter-spacing: 0.5px; - color: var(--text-muted); -} - -.setting-segmented-control { - display: flex; - background-color: var(--bg-input); - border: 1px solid var(--border-color); - border-radius: var(--radius-sm); - padding: 2px; - gap: 2px; -} - -.seg-btn { - flex: 1; - padding: 6px 8px; - font-size: 12px; - font-weight: 600; - background: transparent; - border: none; - border-radius: 4px; - color: var(--text-muted); - cursor: pointer; - transition: var(--transition); - text-align: center; -} - -.seg-btn:hover { - color: var(--text-main); -} - -.seg-btn.active { - background-color: var(--primary); - color: #0f172a; -} - -.setting-stepper { - display: flex; - align-items: center; - justify-content: space-between; - background-color: var(--bg-input); - border: 1px solid var(--border-color); - border-radius: var(--radius-sm); - padding: 4px 6px; -} - -.step-btn { - background: var(--bg-surface-hover); - border: 1px solid var(--border-color); - border-radius: 4px; - color: var(--text-main); - font-size: 13px; - font-weight: 700; - width: 38px; - height: 32px; - display: flex; - align-items: center; - justify-content: center; - cursor: pointer; -} - -.step-val { - font-size: 14px; - font-weight: 700; - color: var(--primary); -} - -.theme-palette { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 6px; -} - -.theme-chip { - padding: 7px 10px; - font-size: 12px; - font-weight: 600; - border-radius: var(--radius-sm); - border: 2px solid transparent; - cursor: pointer; - text-align: center; - transition: var(--transition); -} - -.theme-chip-dark { background: #1e293b; color: #f8fafc; border-color: #334155; } -.theme-chip-sepia { background: #fbf0d9; color: #433422; border-color: #d6bc97; } -.theme-chip-light { background: #ffffff; color: #0f172a; border-color: #cbd5e1; } -.theme-chip-oled { background: #000000; color: #e2e8f0; border-color: #334155; } - -.theme-chip.active { - border-color: var(--primary) !important; - box-shadow: 0 0 0 2px var(--primary-dim); -} - -.reader-settings-btn { - display: inline-flex; - align-items: center; - gap: 4px; -} - -.reader-content-body h1, -.reader-content-body h2, -.reader-content-body h3, -.reader-content-body h4, -.reader-content-body h5, -.reader-content-body h6 { - font-family: var(--font-family); - margin: 28px 0 16px; - color: var(--text-main); - text-indent: 0; -} - -.reader-content-body h4 { font-size: 1.15em; } -.reader-content-body h5 { font-size: 1.05em; } - -.reader-content-body p { - margin-bottom: 20px; - text-indent: 1.2em; -} - -/* Fenced Code Block */ -.reader-code-block { - margin: 24px 0; - border-radius: var(--radius-md); - background: #141820; - border: 1px solid var(--border-color); - overflow: hidden; - box-shadow: 0 4px 14px rgba(0, 0, 0, 0.3); -} - -.reader-code-header { - display: flex; - justify-content: space-between; - align-items: center; - padding: 8px 14px; - background: rgba(255, 255, 255, 0.04); - border-bottom: 1px solid var(--border-color); - font-family: monospace; - font-size: 12px; - color: var(--text-muted); - text-transform: uppercase; - letter-spacing: 0.5px; -} - -.reader-code-lang { - font-weight: 600; -} - -.reader-copy-code-btn { - background: transparent; - border: 1px solid var(--border-color); - color: var(--text-muted); - border-radius: 4px; - padding: 3px 8px; - font-size: 11px; - cursor: pointer; - transition: all 0.15s ease; - display: inline-flex; - align-items: center; - gap: 4px; -} - -.reader-copy-code-btn:hover { - background: rgba(255, 255, 255, 0.08); - color: var(--text-main); - border-color: var(--primary); -} - -.reader-content-body pre { - margin: 0; - padding: 16px; - overflow-x: auto; - background: transparent; - border: none; - border-radius: 0; - font-family: 'JetBrains Mono', 'Fira Code', 'Consolas', monospace; - font-size: 14.5px; - line-height: 1.6; - text-indent: 0 !important; - white-space: pre; - tab-size: 4; -} - -.reader-content-body pre code { - font-family: inherit; - font-size: inherit; - color: #e6edf3; - background: transparent; - padding: 0; - border: none; - white-space: pre; - display: block; - text-indent: 0; -} - -/* Inline Code Badge */ -.reader-inline-code { - font-family: 'JetBrains Mono', 'Consolas', monospace; - font-size: 0.88em; - background: rgba(255, 255, 255, 0.08); - color: var(--primary); - padding: 2px 6px; - border-radius: 4px; - border: 1px solid rgba(255, 255, 255, 0.12); - white-space: pre-wrap; - word-break: break-all; -} - -/* Blockquote */ -.reader-content-body blockquote { - margin: 20px 0; - padding: 12px 20px; - border-left: 4px solid var(--primary); - background: rgba(56, 189, 248, 0.06); - border-radius: 0 var(--radius-md) var(--radius-md) 0; - font-style: italic; - color: var(--text-main); - text-indent: 0; -} - -.reader-content-body blockquote p { - margin: 0; - text-indent: 0; -} - -/* Lists */ -.reader-content-body ul, -.reader-content-body ol { - margin: 16px 0 20px 24px; - padding-left: 12px; - text-indent: 0; -} - -.reader-content-body li { - margin-bottom: 8px; - line-height: 1.7; - text-indent: 0; -} - -.reader-content-body hr { - border: 0; - height: 1px; - background: var(--border-color); - margin: 32px 0; -} - -/* Headings */ -.reader-content-body h1, -.reader-content-body h2, -.reader-content-body h3, -.reader-content-body h4, -.reader-content-body h5, -.reader-content-body h6 { - color: var(--text-main); - font-weight: 700; - line-height: 1.35; - margin: 32px 0 16px; - text-indent: 0 !important; -} - -.reader-content-body h1 { - font-size: 28px; - border-bottom: 1px solid var(--border-color); - padding-bottom: 10px; -} - -.reader-content-body h2 { - font-size: 23px; - border-bottom: 1px solid var(--border-color); - padding-bottom: 8px; -} - -.reader-content-body h3 { - font-size: 19px; -} - -.reader-content-body h4 { - font-size: 17px; -} - -/* Markdown Tables */ -.reader-table-wrap { - overflow-x: auto; - margin: 24px 0; - border-radius: var(--radius-md); - border: 1px solid var(--border-color); - background: var(--bg-surface); - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2); -} - -.reader-table { - width: 100%; - border-collapse: collapse; - font-size: 14.5px; - line-height: 1.6; - text-indent: 0 !important; -} - -.reader-table th, -.reader-table td { - padding: 10px 16px; - border-bottom: 1px solid var(--border-color); - border-right: 1px solid var(--border-color); - vertical-align: top; - text-indent: 0 !important; -} - -.reader-table th:last-child, -.reader-table td:last-child { - border-right: none; -} - -.reader-table tr:last-child td { - border-bottom: none; -} - -.reader-table th { - background-color: rgba(255, 255, 255, 0.05); - font-weight: 700; - color: var(--text-main); - text-align: left; -} - -.reader-table tbody tr:hover { - background-color: rgba(255, 255, 255, 0.02); -} - -/* Links & Images */ -.reader-link { - color: var(--primary); - text-decoration: underline; - text-decoration-thickness: 1px; - text-underline-offset: 3px; - transition: color 0.15s ease; -} - -.reader-link:hover { - color: var(--primary-hover); -} - -.reader-img { - max-width: 100%; - height: auto; - border-radius: var(--radius-md); - margin: 8px 0; - vertical-align: middle; -} - -.reader-content-body p img { - margin: 4px 6px; - display: inline-block; - vertical-align: middle; -} - -/* Figures and Media (Images, Diagrams, Animated GIFs, SVGs) */ -.reader-figure { - margin: 28px auto; - padding: 14px; - background: var(--bg-surface); - border: 1px solid var(--border-color); - border-radius: var(--radius-lg); - box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15); - display: flex; - flex-direction: column; - align-items: center; - max-width: 95%; - box-sizing: border-box; -} - -.reader-figure-img { - max-width: 100%; - max-height: 480px; - width: auto; - height: auto; - border-radius: var(--radius-md); - object-fit: contain; - display: block; -} - -.reader-figcaption { - margin-top: 12px; - padding-top: 10px; - border-top: 1px solid rgba(255, 255, 255, 0.08); - font-size: 13.5px; - line-height: 1.55; - color: var(--text-dim); - text-align: center; - max-width: 90%; - font-style: italic; - user-select: text; -} - -.reader-figcaption .reader-word { - font-style: normal; -} - -.reader-content-body p[style*="text-align: center"], -.reader-content-body p.text-center { - text-indent: 0 !important; -} - -.reader-content-body strong, -.reader-content-body b { - font-weight: 700; - color: var(--text-main); -} - -.reader-content-body em, -.reader-content-body i { - font-style: italic; -} - -.reader-content-body sub, -.reader-content-body sup { - font-size: 0.8em; - line-height: 0; - position: relative; - vertical-align: baseline; -} -.reader-content-body sub { bottom: -0.25em; } -.reader-content-body sup { top: -0.5em; } - -/* Interactive Words */ -.reader-word { - cursor: pointer; - border-radius: 3px; - transition: background-color 0.12s ease, color 0.12s ease; - padding: 1px 2px; -} - -.reader-word:hover { - background-color: var(--primary-dim); - color: var(--primary); -} - -.reader-word.status-mastered.highlight-enabled { - border-bottom: 2px dotted rgba(16, 185, 129, 0.5); -} - -.reader-word.status-learning.highlight-enabled { - border-bottom: 2px dotted rgba(56, 189, 248, 0.5); -} - -/* Click-to-Translate Popup */ -.reader-word-popup { - position: fixed; - z-index: 10005; - background-color: var(--bg-surface); - border: 1px solid var(--border-focus); - border-radius: var(--radius-lg); - box-shadow: 0 12px 24px -4px rgba(0, 0, 0, 0.5); - width: 320px; - max-width: calc(100vw - 32px); - padding: 16px; - animation: fadeInScale 0.15s ease-out; -} - -.popup-header { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 12px; - padding-bottom: 8px; - border-bottom: 1px solid var(--border-color); -} - -.popup-term-wrap { - display: flex; - align-items: center; - gap: 8px; - flex-wrap: wrap; -} - -.popup-term { - font-size: 18px; - color: var(--text-main); -} - -.popup-phonetic { - font-size: 13px; - color: var(--primary); - font-family: monospace; -} - -.popup-close-btn { - background: none; - border: none; - color: var(--text-dim); - font-size: 16px; - cursor: pointer; - padding: 4px; -} - -/* Phrasal Verb & Collocation Card in Word Popup */ -.popup-phrasal-card { - background: linear-gradient(135deg, rgba(99, 102, 241, 0.12), rgba(168, 85, 247, 0.08)); - border: 1px solid rgba(99, 102, 241, 0.35); - border-radius: var(--radius-sm); - padding: 8px 10px; - margin-bottom: 10px; - animation: fadeIn 0.15s ease-out; -} - -.phrasal-card-header { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 4px; -} - -.phrasal-tag { - font-size: 10px; - font-weight: 700; - color: var(--primary); - text-transform: uppercase; - letter-spacing: 0.04em; -} - -.phrasal-term-row { - display: flex; - align-items: baseline; - gap: 6px; - flex-wrap: wrap; - margin-bottom: 2px; -} - -.phrasal-term { - font-size: 14px; - color: var(--text-main); -} - -.phrasal-raw { - font-size: 11px; - color: var(--text-muted); - font-style: italic; -} - -.phrasal-translation { - font-size: 12px; - font-weight: 600; - color: var(--success); - margin-bottom: 6px; - line-height: 1.35; -} - -.phrasal-card-actions { - display: flex; - gap: 6px; - margin-top: 4px; -} - -.phrasal-action-btn { - font-size: 11px; - padding: 3px 8px; - width: 100%; - justify-content: center; -} - -.popup-translation { - font-size: 15px; - font-weight: 600; - color: var(--success); - margin-bottom: 8px; -} - -.popup-context-box { - margin-bottom: 14px; -} - -.popup-context { - font-size: 12px; - color: var(--text-muted); - font-style: italic; - background: var(--bg-input); - padding: 8px 10px; - border-radius: var(--radius-sm); - margin-bottom: 6px; - line-height: 1.4; - border-left: 3px solid var(--primary); -} - -.popup-sentence-ai-bar { - display: flex; - align-items: center; - justify-content: space-between; - gap: 8px; - margin-bottom: 6px; -} - -.popup-sentence-btn { - font-size: 11px; - padding: 3px 8px; - cursor: pointer; - border-radius: var(--radius-sm); - display: inline-flex; - align-items: center; - gap: 4px; -} - -.popup-ai-source-badge { - font-size: 10px; - font-weight: 600; - color: var(--primary); - background: rgba(99, 102, 241, 0.12); - border: 1px solid rgba(99, 102, 241, 0.25); - padding: 2px 6px; - border-radius: 9999px; - letter-spacing: 0.02em; -} - -.popup-sentence-loading { - font-size: 11px; - color: var(--text-muted); - padding: 6px 8px; - display: flex; - align-items: center; - gap: 6px; - background: var(--bg-input); - border-radius: var(--radius-sm); - margin-bottom: 6px; -} - -.popup-sentence-translation-wrap { - background: rgba(99, 102, 241, 0.08); - border: 1px solid rgba(99, 102, 241, 0.2); - border-radius: var(--radius-sm); - padding: 8px 10px; - margin-bottom: 6px; - animation: fadeIn 0.15s ease-out; -} - -.popup-sentence-ru { - font-size: 13px; - line-height: 1.45; - color: var(--text-main); - margin-bottom: 6px; -} - -.popup-context-meaning-wrap { - display: flex; - align-items: center; - flex-wrap: wrap; - gap: 6px; - font-size: 11px; - padding-top: 6px; - border-top: 1px dashed rgba(99, 102, 241, 0.2); -} - -.context-meaning-label { - color: var(--text-muted); -} - -.context-meaning-val { - color: var(--success); - font-weight: 600; -} - -.use-meaning-btn { - font-size: 10px; - padding: 1px 6px; - color: var(--primary); - border: 1px solid var(--primary); - border-radius: 4px; - cursor: pointer; - background: transparent; -} - -.use-meaning-btn:hover { - background: rgba(99, 102, 241, 0.15); -} - -.popup-saved-badge { - text-align: center; - font-size: 13px; - font-weight: 600; - color: #f59e0b; - background: rgba(245, 158, 11, 0.12); - border: 1px solid rgba(245, 158, 11, 0.3); - border-radius: var(--radius-sm); - padding: 6px 10px; -} - -.popup-in-library-badge { - display: inline-flex; - align-items: center; - gap: 3px; - font-size: 11px; - font-weight: 600; - color: #f59e0b; - background: rgba(245, 158, 11, 0.15); - border: 1px solid rgba(245, 158, 11, 0.4); - padding: 2px 7px; - border-radius: 9999px; - margin-left: 6px; - letter-spacing: 0.02em; - vertical-align: middle; -} - -.badge-library-star { - display: inline-flex; - align-items: center; - gap: 4px; - font-size: 12px; - font-weight: 600; - color: #f59e0b; - background: rgba(245, 158, 11, 0.15); - border: 1px solid rgba(245, 158, 11, 0.4); - padding: 2px 8px; - border-radius: 9999px; - margin-left: 8px; - vertical-align: middle; -} - -/* ========================================================================== - Continuous Reading & Chapter End Navigation Card - ========================================================================== */ - -/* Chapter Divider (Between chapters in continuous / autoload mode) */ -.reader-chapter-divider { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - margin: 56px 0 36px; - padding: 24px 16px; - border-top: 1px dashed var(--border-color); - border-bottom: 1px dashed var(--border-color); - background: rgba(255, 255, 255, 0.02); - border-radius: var(--radius-md); - text-align: center; - scroll-margin-top: 60px; -} - -.reader-chapter-divider .divider-badge { - font-size: 11px; - font-weight: 700; - text-transform: uppercase; - letter-spacing: 0.8px; - color: var(--primary); - background: var(--bg-input); - padding: 4px 12px; - border-radius: 9999px; - border: 1px solid var(--border-color); - margin-bottom: 10px; - display: inline-block; -} - -.reader-chapter-divider .divider-title { - font-size: 22px !important; - font-weight: 700; - color: var(--text-main); - margin: 0 !important; - border-bottom: none !important; - padding-bottom: 0 !important; - text-align: center; -} - -/* Chapter End Navigation Card */ -.reader-chapter-footer { - margin: 48px 0 64px; - padding: 24px 20px; - background: var(--bg-surface); - border: 1px solid var(--border-color); - border-radius: var(--radius-lg); - box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15); - display: flex; - flex-direction: column; - align-items: center; - text-align: center; - gap: 14px; - transition: var(--transition); -} - -.reader-chapter-footer .chapter-footer-status { - display: flex; - align-items: center; - gap: 8px; - font-size: 14px; - font-weight: 600; - color: var(--text-muted); -} - -.reader-chapter-footer .chapter-footer-status .status-check { - display: inline-flex; - align-items: center; - justify-content: center; - width: 24px; - height: 24px; - border-radius: 50%; - background: rgba(34, 197, 94, 0.15); - color: var(--success); - font-size: 13px; - font-weight: 700; -} - -.reader-chapter-footer .chapter-footer-nav { - display: flex; - gap: 12px; - width: 100%; - max-width: 540px; - justify-content: center; - flex-wrap: wrap; -} - -.reader-chapter-footer .reader-footer-nav-btn { - flex: 1; - min-width: 150px; - min-height: 44px; - display: inline-flex; - align-items: center; - justify-content: center; - gap: 6px; - font-size: 14px; - font-weight: 600; - padding: 10px 18px; - border-radius: var(--radius-sm); - cursor: pointer; - transition: var(--transition); -} - -.reader-chapter-footer .chapter-footer-hint { - font-size: 12px; - color: var(--text-dim); - line-height: 1.4; - max-width: 480px; -} - -/* Book Completion Card */ -.reader-chapter-footer.reader-book-finished { - background: linear-gradient(180deg, rgba(56, 189, 248, 0.08) 0%, rgba(20, 24, 32, 0.95) 100%); - border-color: rgba(56, 189, 248, 0.35); -} - -.reader-chapter-footer.reader-book-finished .chapter-footer-hint { - color: var(--text-muted); - font-size: 13px; -} - -/* Reading Theme Adaptations */ -.reader-scroll-area.reader-theme-sepia .reader-chapter-divider, -.reader-scroll-area.reader-theme-light .reader-chapter-divider { - background: rgba(0, 0, 0, 0.025); - border-color: rgba(0, 0, 0, 0.12); -} - -.reader-scroll-area.reader-theme-sepia .reader-chapter-footer, -.reader-scroll-area.reader-theme-light .reader-chapter-footer { - background: rgba(0, 0, 0, 0.03); - border-color: rgba(0, 0, 0, 0.12); - box-shadow: 0 4px 16px rgba(0, 0, 0, 0.06); -} - -.reader-scroll-area.reader-theme-oled .reader-chapter-divider { - background: #080808; - border-color: #222; -} - -.reader-scroll-area.reader-theme-oled .reader-chapter-footer { - background: #0c0c0c; - border-color: #222; -} - -/* ========================================================================== - VIEW 4: CEFR Level Testing & Automated Gap Ingestion Styles (Task 15) - ========================================================================== */ - -.cefr-view { - max-width: 960px; - margin: 0 auto; - padding: 24px 16px 80px 16px; - width: 100%; -} - -.cefr-overview-container, -.cefr-quiz-container, -.cefr-summary-container { - width: 100%; -} - -.level-code { - font-weight: 800; -} - -.badge-pos { - font-size: 11px; - font-weight: 700; - text-transform: uppercase; - background: var(--bg-hover); - color: var(--text-muted); - padding: 3px 8px; - border-radius: var(--radius-sm); - border: 1px solid var(--border-color); -} - -.clue-icon { - font-size: 16px; -} - -.clue-label { - font-size: 13px; - color: var(--text-muted); - font-weight: 500; -} - -.cefr-feedback-box .fb-term { - font-size: 16px; - color: var(--text-main); - font-weight: 700; -} - -.cefr-feedback-box .fb-trans { - font-size: 14.5px; - color: var(--text-main); - font-weight: 500; -} - -.progress-labels-row .counts-text { - font-size: 12px; - color: var(--text-muted); -} - -.cefr-header { - display: flex; - justify-content: space-between; - align-items: flex-start; - gap: 16px; - margin-bottom: 24px; - flex-wrap: wrap; -} - -.cefr-header-actions { - display: flex; - align-items: center; - gap: 10px; -} - -/* Background Task Banner in CEFR Overview */ -.cefr-task-banner { - background: linear-gradient(135deg, rgba(59, 130, 246, 0.12), rgba(16, 185, 129, 0.08)); - border: 1px solid rgba(59, 130, 246, 0.3); - border-radius: var(--radius-md); - padding: 14px 18px; - margin-bottom: 24px; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); -} - -.task-banner-inner { - display: flex; - justify-content: space-between; - align-items: center; - gap: 16px; -} - -.task-banner-content { - flex: 1; -} - -.task-banner-title { - display: flex; - align-items: center; - gap: 8px; - font-size: 14px; - color: var(--text-main); - margin-bottom: 4px; -} - -.task-banner-counts { - font-size: 12px; - color: var(--text-muted); - font-weight: 500; - margin-left: auto; -} - -.task-banner-msg { - font-size: 13px; - color: var(--text-muted); -} - -/* Book Source Badge in Question Card & Feedback */ -.cefr-book-badge { - display: inline-flex; - align-items: center; - gap: 4px; - font-size: 12px; - font-weight: 600; - color: #3b82f6; - background: rgba(59, 130, 246, 0.1); - border: 1px solid rgba(59, 130, 246, 0.25); - padding: 2px 10px; - border-radius: var(--radius-sm); - max-width: 280px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -.fb-source-citation { - font-size: 12.5px; - font-weight: 500; - color: #3b82f6; - background: rgba(59, 130, 246, 0.08); - border-left: 3px solid #3b82f6; - padding: 6px 10px; - border-radius: 0 var(--radius-sm) var(--radius-sm) 0; - margin: 8px 0; -} - -.cefr-title-wrap h2 { - font-size: 26px; - font-weight: 700; - margin-bottom: 8px; - display: flex; - align-items: center; - gap: 10px; -} - -.cefr-title-wrap .subtitle { - font-size: 15px; - color: var(--text-muted); - line-height: 1.5; -} - -/* Level Selection Grid */ -.cefr-levels-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); - gap: 20px; -} - -.cefr-level-card { - background-color: var(--bg-card); - border: 1px solid var(--border-color); - border-radius: var(--radius-lg); - padding: 24px; - display: flex; - flex-direction: column; - gap: 18px; - box-shadow: var(--shadow-sm); - transition: transform 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease; -} - -.cefr-level-card:hover { - border-color: var(--primary); - transform: translateY(-2px); - box-shadow: var(--shadow-md); -} - -.level-card-header { - display: flex; - align-items: center; - gap: 14px; -} - -.level-pill { - display: inline-flex; - align-items: center; - justify-content: center; - padding: 6px 14px; - border-radius: 9999px; - font-weight: 800; - font-size: 15px; - letter-spacing: 0.5px; -} - -.level-badge-a1 { - background: rgba(16, 185, 129, 0.15); - color: #10b981; - border: 1px solid rgba(16, 185, 129, 0.35); -} - -.level-badge-a2 { - background: rgba(56, 189, 248, 0.15); - color: #38bdf8; - border: 1px solid rgba(56, 189, 248, 0.35); -} - -.level-badge-b1 { - background: rgba(129, 140, 248, 0.15); - color: #818cf8; - border: 1px solid rgba(129, 140, 248, 0.35); -} - -.level-badge-b2 { - background: rgba(245, 158, 11, 0.15); - color: #fbbf24; - border: 1px solid rgba(245, 158, 11, 0.35); -} - -.level-header-text { - flex: 1; -} - -.level-title { - font-size: 17px; - font-weight: 600; - margin: 0 0 2px 0; -} - -.level-meta-sub { - font-size: 13px; - color: var(--text-muted); -} - -/* Progress bar inside card */ -.level-card-progress { - display: flex; - flex-direction: column; - gap: 6px; -} - -.progress-bar-wrap { - height: 8px; - background-color: var(--bg-hover); - border-radius: 9999px; - overflow: hidden; -} - -.progress-bar-fill { - height: 100%; - border-radius: 9999px; - transition: width 0.4s ease; -} - -.progress-bar-fill.level-badge-a1 { background-color: #10b981; } -.progress-bar-fill.level-badge-a2 { background-color: #38bdf8; } -.progress-bar-fill.level-badge-b1 { background-color: #818cf8; } -.progress-bar-fill.level-badge-b2 { background-color: #f59e0b; } - -.progress-labels-row { - display: flex; - justify-content: space-between; - font-size: 12px; - color: var(--text-muted); -} - -.progress-labels-row .pct-text { - font-weight: 600; - color: var(--text-main); -} - -/* Mini metrics */ -.level-card-metrics { - display: flex; - justify-content: space-between; - background-color: var(--bg-hover); - border-radius: var(--radius-md); - padding: 10px 12px; -} - -.mini-metric { - display: flex; - flex-direction: column; - align-items: center; - gap: 2px; -} - -.mini-metric .m-val { - font-size: 14px; - font-weight: 700; -} - -.mini-metric .m-lbl { - font-size: 11px; - color: var(--text-muted); -} - -.level-card-actions { - display: flex; - flex-direction: column; - gap: 8px; - margin-top: auto; -} - -/* Quiz Topbar */ -.cefr-quiz-topbar { - display: flex; - align-items: center; - justify-content: space-between; - gap: 16px; - margin-bottom: 24px; - padding: 12px 18px; - background-color: var(--bg-card); - border: 1px solid var(--border-color); - border-radius: var(--radius-md); -} - -.cefr-quiz-topbar-left { - display: flex; - align-items: center; - gap: 12px; -} - -.cefr-quiz-topbar-center { - display: flex; - align-items: center; - gap: 14px; - flex: 1; - max-width: 380px; -} - -/* Cloze Card */ -.cefr-quiz-card-wrapper { - display: flex; - flex-direction: column; - gap: 20px; -} - -.cefr-cloze-card { - background-color: var(--bg-card); - border: 1px solid var(--border-color); - border-radius: var(--radius-lg); - padding: 32px 28px; - box-shadow: var(--shadow-md); - display: flex; - flex-direction: column; - gap: 20px; - animation: fadeIn 0.25s ease-out; -} - -.cefr-cloze-header { - display: flex; - align-items: center; - justify-content: space-between; -} - -.cefr-mode-tag { - font-size: 13px; - font-weight: 600; - color: var(--primary); - background: rgba(56, 189, 248, 0.1); - padding: 4px 10px; - border-radius: var(--radius-sm); -} - -/* Sentence & Blank */ -.cefr-sentence-wrap { - padding: 18px 0; -} - -.cefr-sentence-text { - font-size: 22px; - font-weight: 500; - line-height: 1.6; - color: var(--text-main); - margin: 0; -} - -.cefr-blank { - display: inline-block; - min-width: 90px; - text-align: center; - background: rgba(56, 189, 248, 0.12); - border-bottom: 2px dashed var(--primary); - padding: 2px 12px; - border-radius: 4px; - font-weight: 700; - color: var(--primary); - transition: all 0.25s ease; -} - -.cefr-blank.blank-correct { - background: rgba(16, 185, 129, 0.2); - border-bottom: 2px solid #10b981; - color: #10b981; -} - -.cefr-blank.blank-wrong-revealed { - background: rgba(239, 68, 68, 0.2); - border-bottom: 2px solid #ef4444; - color: #f87171; -} - -/* Clue Box */ -.cefr-clue-box { - display: flex; - align-items: center; - gap: 8px; - background-color: var(--bg-hover); - padding: 10px 14px; - border-radius: var(--radius-md); - font-size: 14px; - color: var(--text-muted); -} - -.cefr-clue-box .clue-term { - color: var(--text-main); - font-size: 15px; -} - -/* Options Grid: 2x2 */ -.cefr-options-grid { - display: grid; - grid-template-columns: repeat(2, 1fr); - gap: 12px; - margin-top: 6px; -} - -.cefr-opt-btn { - display: flex; - align-items: center; - justify-content: flex-start; - gap: 12px; - background-color: var(--bg-surface); - border: 1.5px solid var(--border-color); - border-radius: var(--radius-md); - padding: 16px 20px; - min-height: 56px; - color: var(--text-main); - font-size: 17px; - font-weight: 600; - cursor: pointer; - transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); - outline: none; - user-select: none; - -webkit-tap-highlight-color: transparent; -} - -.cefr-opt-btn:hover:not(:disabled) { - border-color: var(--primary); - background-color: var(--bg-hover); - transform: translateY(-2px); - box-shadow: 0 4px 12px rgba(56, 189, 248, 0.15); -} - -.cefr-opt-btn:active:not(:disabled) { - transform: scale(0.98); -} - -.cefr-opt-btn .opt-num { - font-size: 13px; - color: var(--text-muted); - font-weight: 500; -} - -.cefr-opt-btn .opt-text { - flex: 1; - text-align: left; -} - -/* Option States */ -.cefr-opt-btn.opt-correct { - background-color: #10b981 !important; - border-color: #10b981 !important; - color: #fff !important; - box-shadow: 0 0 16px rgba(16, 185, 129, 0.4); -} - -.cefr-opt-btn.opt-correct .opt-num { - color: rgba(255, 255, 255, 0.8) !important; -} - -.cefr-opt-btn.opt-wrong { - background-color: #ef4444 !important; - border-color: #ef4444 !important; - color: #fff !important; - box-shadow: 0 0 16px rgba(239, 68, 68, 0.4); -} - -.cefr-opt-btn.opt-wrong .opt-num { - color: rgba(255, 255, 255, 0.8) !important; -} - -.cefr-opt-btn.opt-correct-revealed { - border-color: #10b981 !important; - background-color: rgba(16, 185, 129, 0.15) !important; - color: #10b981 !important; - animation: pulseBorder 1.5s infinite ease-in-out; -} - -@keyframes pulseBorder { - 0%, 100% { box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.5); } - 50% { box-shadow: 0 0 0 6px rgba(16, 185, 129, 0); } -} - -/* Feedback Box */ -.cefr-feedback-box { - border-radius: var(--radius-md); - padding: 18px 20px; - display: flex; - flex-direction: column; - gap: 8px; - animation: fadeIn 0.25s ease-out; -} - -.cefr-feedback-box.feedback-correct { - background: rgba(16, 185, 129, 0.12); - border: 1px solid rgba(16, 185, 129, 0.35); -} - -.cefr-feedback-box.feedback-wrong { - background: rgba(239, 68, 68, 0.12); - border: 1px solid rgba(239, 68, 68, 0.35); -} - -.cefr-feedback-box .fb-title { - font-size: 16px; - font-weight: 700; -} - -.cefr-feedback-box.feedback-correct .fb-title { - color: #10b981; -} - -.cefr-feedback-box.feedback-wrong .fb-title { - color: #ef4444; -} - -.cefr-feedback-box .fb-meta { - display: flex; - align-items: center; - gap: 10px; - font-size: 15px; -} - -.cefr-feedback-box .fb-explanation { - margin: 4px 0 0 0; - font-size: 14px; - line-height: 1.5; - color: var(--text-main); -} - -/* Gap Ingestion Badge inside mistake feedback */ -.cefr-gap-ingested-badge { - display: flex; - align-items: center; - gap: 10px; - background: rgba(239, 68, 68, 0.15); - border: 1px solid rgba(239, 68, 68, 0.3); - border-radius: var(--radius-md); - padding: 10px 14px; - margin-top: 6px; - font-size: 13px; - line-height: 1.4; - color: var(--text-main); -} - -.cefr-gap-ingested-badge .badge-icon { - font-size: 18px; -} - -/* Dual Gap Ingestion (Correct + Chosen Mistake) */ -.cefr-dual-ingested-box { - background: rgba(239, 68, 68, 0.1); - border: 1px solid rgba(239, 68, 68, 0.25); - border-radius: var(--radius-md); - padding: 12px 14px; - margin-top: 10px; - animation: fadeIn 0.2s ease-out; -} - -.dual-ingested-header { - display: flex; - align-items: center; - gap: 8px; - font-size: 13px; - color: var(--text-main); - margin-bottom: 8px; -} - -.dual-ingested-chips { - display: flex; - flex-wrap: wrap; - gap: 8px; -} - -.ingested-chip { - background: var(--bg-card); - border: 1px solid var(--border-color); - border-radius: var(--radius-sm); - padding: 6px 10px; - font-size: 12.5px; - color: var(--text-main); - display: flex; - align-items: center; - gap: 5px; -} - -.ingested-chip.chip-target { - border-left: 3px solid #10b981; -} - -.ingested-chip.chip-chosen { - border-left: 3px solid #ef4444; -} - -.ingested-chip .chip-label { - font-size: 10.5px; - font-weight: 700; - text-transform: uppercase; - color: var(--text-muted); -} - -/* Words Breakdown (All 4 Options with In-library/Add buttons) */ -.cefr-words-breakdown { - margin-top: 16px; - padding-top: 14px; - border-top: 1px solid var(--border-color); - text-align: left; -} - -.words-breakdown-header { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 10px; - flex-wrap: wrap; - gap: 6px; -} - -.wb-title { - font-size: 13px; - font-weight: 700; - color: var(--text-main); - display: flex; - align-items: center; - gap: 6px; -} - -.wb-hint { - font-size: 11.5px; - color: var(--text-muted); -} - -.words-breakdown-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); - gap: 8px; -} - -.word-breakdown-card { - background: var(--bg-surface); - border: 1px solid var(--border-color); - border-radius: var(--radius-md); - padding: 9px 11px; - display: flex; - flex-direction: column; - gap: 4px; - transition: all 0.15s ease; -} - -.word-breakdown-card.is-target { - border-color: rgba(16, 185, 129, 0.4); - background: rgba(16, 185, 129, 0.05); -} - -.word-breakdown-card.is-chosen-mistake { - border-color: rgba(239, 68, 68, 0.4); - background: rgba(239, 68, 68, 0.05); -} - -.wb-card-top { - display: flex; - justify-content: space-between; - align-items: baseline; - gap: 6px; -} - -.wb-term { - font-size: 14px; - color: var(--text-main); - font-weight: 700; -} - -.wb-pos { - font-size: 10px; - font-weight: 700; - color: var(--text-muted); - text-transform: uppercase; -} - -.wb-trans { - font-size: 12px; - color: var(--text-muted); - line-height: 1.35; - flex-grow: 1; -} - -.wb-action-wrap { - margin-top: 6px; -} - -.wb-badge { - font-size: 11px; - font-weight: 700; - padding: 3px 6px; - border-radius: 4px; - display: inline-flex; - align-items: center; - gap: 4px; -} - -.wb-badge.badge-auto-added { - color: #ef4444; - background: rgba(239, 68, 68, 0.12); -} - -.wb-badge.badge-in-lib, -.wb-badge.badge-just-added { - color: #10b981; - background: rgba(16, 185, 129, 0.12); -} - -.btn-add-option-word { - width: 100%; - font-size: 11px; - padding: 4px 8px; - border-radius: var(--radius-sm); -} - -/* Next Button Bar */ -.cefr-next-bar { - margin-top: 10px; - animation: fadeIn 0.2s ease-out; -} - -/* Summary Screen */ -.cefr-summary-container { - max-width: 680px; - margin: 40px auto; -} - -.cefr-summary-card { - background-color: var(--bg-card); - border: 1px solid var(--border-color); - border-radius: var(--radius-lg); - padding: 44px 32px; - text-align: center; - display: flex; - flex-direction: column; - align-items: center; - gap: 24px; - box-shadow: var(--shadow-lg); - animation: fadeIn 0.3s ease-out; -} - -.cefr-loading-spinner { - display: flex; - align-items: center; - justify-content: center; - gap: 12px; - padding: 48px; - color: var(--text-muted); -} - -/* Mobile Responsive */ -@media (max-width: 640px) { - .cefr-sentence-text { - font-size: 18px; - } - - .cefr-options-grid { - grid-template-columns: 1fr; - } - - .cefr-opt-btn { - min-height: 52px; - padding: 14px 16px; - } - - .cefr-cloze-card { - padding: 20px 16px; - } -} - -/* ========================================================================== - Task 16: Murphy Grammar Engine & Handwritten Journaling Styles - ========================================================================== */ - -.grammar-view { - padding: 24px 20px 80px 20px; - max-width: 1100px; - margin: 0 auto; - animation: fadeIn 0.2s ease-out; -} - -.grammar-header { - display: flex; - justify-content: space-between; - align-items: flex-start; - gap: 20px; - margin-bottom: 24px; - flex-wrap: wrap; -} - -.grammar-title-wrap h2 { - font-size: 26px; - font-weight: 700; - color: var(--text-main); - margin-bottom: 8px; - letter-spacing: -0.02em; -} - -.grammar-title-wrap .subtitle { - font-size: 14px; - color: var(--text-muted); - max-width: 720px; - line-height: 1.5; -} - -.grammar-top-stats { - display: flex; - gap: 12px; -} - -.grammar-stat-chip { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - background: var(--bg-card); - border: 1px solid var(--border-color); - border-radius: var(--radius-md); - padding: 8px 16px; - min-width: 80px; -} - -.grammar-stat-chip .stat-num { - font-size: 20px; - font-weight: 800; - color: var(--color-primary); -} - -.grammar-stat-chip .stat-lbl { - font-size: 11px; - color: var(--text-muted); - font-weight: 600; - text-transform: uppercase; -} - -/* Filter Bar */ -.grammar-filter-bar { - display: flex; - gap: 8px; - overflow-x: auto; - padding-bottom: 8px; - margin-bottom: 24px; - -webkit-overflow-scrolling: touch; -} - -.grammar-filter-pill { - padding: 6px 14px; - border-radius: var(--radius-full); - font-size: 13px; - font-weight: 600; - background: var(--bg-surface); - border: 1px solid var(--border-color); - color: var(--text-muted); - cursor: pointer; - white-space: nowrap; - transition: all 0.15s ease; -} - -.grammar-filter-pill:hover { - border-color: var(--color-primary); - color: var(--text-main); -} - -.grammar-filter-pill.active { - background: var(--color-primary); - border-color: var(--color-primary); - color: #ffffff; -} - -/* Units Grid */ -.grammar-units-grid { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); - gap: 18px; -} - -.grammar-unit-card { - background: var(--bg-card); - border: 1px solid var(--border-color); - border-radius: var(--radius-lg); - padding: 20px; - display: flex; - flex-direction: column; - cursor: pointer; - transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease; - box-shadow: var(--shadow-sm); -} - -.grammar-unit-card:hover { - transform: translateY(-2px); - box-shadow: var(--shadow-md); - border-color: var(--color-primary); -} - -.grammar-unit-card.is-completed { - border-left: 4px solid #10b981; -} - -.grammar-card-header { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 10px; -} - -.grammar-unit-number { - font-size: 12px; - font-weight: 700; - text-transform: uppercase; - color: var(--text-muted); - letter-spacing: 0.04em; -} - -.grammar-level-pill { - font-size: 11px; - font-weight: 700; - padding: 3px 8px; - border-radius: 6px; - text-transform: uppercase; - letter-spacing: 0.05em; -} - -.grammar-level-pill.badge-a1 { - background: rgba(239, 68, 68, 0.15); - color: #ef4444; - border: 1px solid rgba(239, 68, 68, 0.25); -} - -.grammar-level-pill.badge-b1 { - background: rgba(59, 130, 246, 0.15); - color: #3b82f6; - border: 1px solid rgba(59, 130, 246, 0.25); -} - -.grammar-card-title { - font-size: 17px; - font-weight: 700; - color: var(--text-main); - margin-bottom: 6px; - line-height: 1.35; -} - -.grammar-card-sub { - font-size: 13px; - color: var(--text-muted); - line-height: 1.45; - margin-bottom: 14px; - flex-grow: 1; -} - -.grammar-card-meta { - margin-bottom: 14px; -} - -.grammar-card-cat { - font-size: 12px; - font-weight: 600; - color: var(--text-muted); - display: inline-flex; - align-items: center; - gap: 4px; -} - -.grammar-card-footer { - display: flex; - justify-content: space-between; - align-items: center; - padding-top: 12px; - border-top: 1px solid var(--border-color); -} - -.grammar-badges { - display: flex; - align-items: center; - gap: 6px; - flex-wrap: wrap; -} - -.badge-status-completed { - font-size: 11px; - font-weight: 700; - color: #10b981; - background: rgba(16, 185, 129, 0.12); - padding: 2px 7px; - border-radius: 4px; - display: inline-flex; - align-items: center; - gap: 3px; -} - -.badge-status-handwritten { - font-size: 11px; - font-weight: 700; - color: #8b5cf6; - background: rgba(139, 92, 246, 0.12); - padding: 2px 7px; - border-radius: 4px; - display: inline-flex; - align-items: center; - gap: 3px; -} - -.badge-status-new { - font-size: 11px; - font-weight: 600; - color: var(--text-muted); - background: var(--bg-surface); - padding: 2px 7px; - border-radius: 4px; -} - -/* ========================================================================== - Grammar Lesson Screen (Theory & Deep Work Mode) - ========================================================================== */ - -.grammar-lesson-container { - max-width: 860px; - margin: 0 auto; - animation: fadeIn 0.2s ease-out; -} - -.grammar-lesson-topbar { - display: flex; - align-items: center; - justify-content: space-between; - margin-bottom: 24px; - gap: 16px; - flex-wrap: wrap; - background: var(--bg-card); - border: 1px solid var(--border-color); - border-radius: var(--radius-lg); - padding: 12px 18px; -} - -.grammar-topbar-left { - display: flex; - align-items: center; - gap: 12px; -} - -.grammar-lesson-badges { - display: flex; - align-items: center; - gap: 8px; -} - -.grammar-unit-pill { - font-size: 12px; - font-weight: 700; - text-transform: uppercase; - background: var(--bg-surface); - border: 1px solid var(--border-color); - padding: 3px 8px; - border-radius: 6px; - color: var(--text-main); -} - -.grammar-tab-switch { - display: inline-flex; - background: var(--bg-input); - padding: 3px; - border-radius: var(--radius-md); - border: 1px solid var(--border-color); -} - -.grammar-tab-switch .tab-btn { - padding: 6px 14px; - font-size: 13px; - font-weight: 600; - border: none; - background: transparent; - color: var(--text-muted); - border-radius: calc(var(--radius-md) - 2px); - cursor: pointer; - transition: all 0.15s ease; -} - -.grammar-tab-switch .tab-btn.active { - background: var(--bg-card); - color: var(--text-main); - box-shadow: var(--shadow-sm); -} - -.grammar-cat-label { - font-size: 12px; - font-weight: 600; - color: var(--text-muted); -} - -.grammar-theory-header { - margin-bottom: 24px; -} - -.lesson-main-title { - font-size: 26px; - font-weight: 800; - color: var(--text-main); - margin-bottom: 6px; - letter-spacing: -0.02em; -} - -.lesson-sub-title { - font-size: 15px; - color: var(--text-muted); - line-height: 1.5; -} - -.grammar-section-block { - margin-bottom: 28px; -} - -.section-title { - font-size: 16px; - font-weight: 700; - color: var(--text-main); - margin-bottom: 12px; - display: flex; - align-items: center; - gap: 8px; -} - -/* Contrast Cards (Situation A vs Situation B) */ -.grammar-contrasts-list { - display: flex; - flex-direction: column; - gap: 16px; -} - -.grammar-contrast-card { - background: var(--bg-card); - border: 1px solid var(--border-color); - border-radius: var(--radius-lg); - padding: 20px; - display: grid; - grid-template-columns: 1fr auto 1fr; - gap: 16px; - box-shadow: var(--shadow-sm); -} - -.contrast-col { - display: flex; - flex-direction: column; - gap: 8px; -} - -.contrast-header { - font-size: 13px; - font-weight: 700; - color: var(--text-main); - display: flex; - align-items: center; - gap: 8px; -} - -.contrast-pill { - font-size: 10px; - font-weight: 800; - padding: 2px 6px; - border-radius: 4px; - text-transform: uppercase; -} - -.contrast-pill.a { - background: rgba(59, 130, 246, 0.15); - color: #3b82f6; -} - -.contrast-pill.b { - background: rgba(16, 185, 129, 0.15); - color: #10b981; -} - -.contrast-example { - font-size: 15px; - font-weight: 600; - color: var(--text-main); - background: var(--bg-input); - padding: 10px 12px; - border-radius: var(--radius-md); - border-left: 3px solid var(--color-primary); - line-height: 1.4; -} - -.contrast-trans { - font-size: 13px; - color: var(--text-muted); - line-height: 1.4; - font-style: italic; -} - -.contrast-divider { - display: flex; - align-items: center; - justify-content: center; -} - -.vs-badge { - background: var(--bg-surface-hover); - color: var(--text-muted); - font-weight: 800; - font-size: 11px; - width: 32px; - height: 32px; - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - border: 1px solid var(--border-color); -} - -.contrast-key-diff { - grid-column: 1 / -1; - background: rgba(245, 158, 11, 0.1); - border: 1px solid rgba(245, 158, 11, 0.25); - border-radius: var(--radius-md); - padding: 10px 14px; - font-size: 13px; - line-height: 1.5; - color: var(--text-main); - margin-top: 6px; -} - -/* Golden Formula Card */ -.grammar-golden-formula-card { - background: linear-gradient(135deg, rgba(99, 102, 241, 0.08), rgba(168, 85, 247, 0.08)); - border: 1px solid rgba(99, 102, 241, 0.3); - border-radius: var(--radius-lg); - padding: 22px; - position: relative; - box-shadow: var(--shadow-sm); -} - -.notebook-pen-icon { - position: absolute; - top: 18px; - right: 20px; - font-size: 24px; - opacity: 0.6; -} - -.formula-instructions { - font-size: 13px; - font-weight: 600; - color: var(--text-muted); - margin-bottom: 10px; -} - -.golden-formula-code { - font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; - font-size: 16px; - font-weight: 700; - color: var(--text-main); - background: var(--bg-card); - padding: 14px 18px; - border-radius: var(--radius-md); - border: 1px dashed rgba(99, 102, 241, 0.4); - line-height: 1.5; - white-space: pre-line; -} - -/* Journaling Card & Checkbox */ -.grammar-journaling-card { - background: var(--bg-card); - border: 1px solid var(--border-color); - border-radius: var(--radius-lg); - padding: 20px; - box-shadow: var(--shadow-sm); -} - -.journaling-prompt-box { - margin-bottom: 16px; -} - -.journaling-prompt-text { - font-size: 14px; - line-height: 1.55; - color: var(--text-main); -} - -.journaling-action-box { - border-top: 1px solid var(--border-color); - padding-top: 16px; -} - -.handwritten-checkbox-label { - display: flex; - align-items: flex-start; - gap: 14px; - cursor: pointer; - user-select: none; - min-height: 48px; - padding: 8px 12px; - border-radius: var(--radius-md); - background: var(--bg-surface); - border: 1px solid var(--border-color); - transition: all 0.15s ease; -} - -.handwritten-checkbox-label:hover { - border-color: #8b5cf6; - background: rgba(139, 92, 246, 0.05); -} - -.handwritten-checkbox { - position: absolute; - opacity: 0; - width: 0; - height: 0; -} - -.custom-chk { - width: 22px; - height: 22px; - border: 2px solid var(--border-color); - border-radius: 6px; - background: var(--bg-card); - flex-shrink: 0; - display: flex; - align-items: center; - justify-content: center; - margin-top: 2px; - transition: all 0.15s ease; -} - -.handwritten-checkbox:checked + .custom-chk { - background: #8b5cf6; - border-color: #8b5cf6; -} - -.handwritten-checkbox:checked + .custom-chk::after { - content: "✓"; - color: #ffffff; - font-size: 14px; - font-weight: 800; -} - -.handwritten-label-text { - display: flex; - flex-direction: column; - gap: 3px; -} - -.handwritten-label-text strong { - font-size: 14px; - color: var(--text-main); -} - -.handwritten-label-text small { - font-size: 12px; - color: var(--text-muted); - line-height: 1.35; -} - -.grammar-theory-footer { - display: flex; - justify-content: flex-end; - margin-top: 28px; -} - -/* ========================================================================== - Cloze Tap Practice (5 Micro-Exercises) - ========================================================================== */ - -.grammar-practice-card-wrap { - background: var(--bg-card); - border: 1px solid var(--border-color); - border-radius: var(--radius-lg); - padding: 32px 28px; - box-shadow: var(--shadow-md); - display: flex; - flex-direction: column; - gap: 24px; -} - -.practice-header-bar { - display: flex; - justify-content: space-between; - align-items: center; -} - -.practice-step-text { - font-size: 13px; - font-weight: 700; - color: var(--text-muted); - text-transform: uppercase; - letter-spacing: 0.05em; -} - -.practice-dots { - display: flex; - gap: 8px; -} - -.practice-dots .dot { - width: 10px; - height: 10px; - border-radius: 50%; - background: var(--border-color); - transition: all 0.2s ease; -} - -.practice-dots .dot-active { - background: var(--color-primary); - transform: scale(1.2); -} - -.practice-dots .dot-done { - background: #10b981; -} - -.grammar-cloze-box { - background: var(--bg-input); - border: 1px solid var(--border-color); - border-radius: var(--radius-lg); - padding: 24px 20px; - text-align: center; -} - -.cloze-sentence-display { - font-size: 20px; - font-weight: 600; - color: var(--text-main); - line-height: 1.6; - margin-bottom: 12px; -} - -.cloze-blank { - display: inline-block; - color: var(--color-primary); - border-bottom: 2px dashed var(--color-primary); - padding: 0 8px; - font-weight: 700; - min-width: 80px; - transition: all 0.2s ease; -} - -.cloze-blank.blank-correct { - color: #10b981; - border-bottom-color: #10b981; -} - -.cloze-blank.blank-wrong { - color: #ef4444; - border-bottom-color: #ef4444; -} - -.cloze-clue-display { - font-size: 14px; - color: var(--text-muted); - font-style: italic; -} - -.grammar-tap-options { - display: grid; - grid-template-columns: repeat(2, 1fr); - gap: 12px; -} - -.grammar-opt-btn { - min-height: 52px; - padding: 14px 18px; - border-radius: var(--radius-md); - font-size: 15px; - font-weight: 600; - text-align: left; - display: flex; - align-items: center; - gap: 12px; - background: var(--bg-surface); - border: 1.5px solid var(--border-color); - color: var(--text-main); - cursor: pointer; - transition: all 0.15s ease; -} - -.grammar-opt-btn .opt-num { - font-size: 11px; - font-weight: 800; - width: 22px; - height: 22px; - border-radius: 50%; - background: var(--bg-surface-hover); - color: var(--text-muted); - display: flex; - align-items: center; - justify-content: center; - flex-shrink: 0; -} - -.grammar-opt-btn:hover:not(:disabled) { - border-color: var(--color-primary); - background: var(--bg-surface-hover); -} - -.grammar-opt-btn.btn-correct { - background: rgba(16, 185, 129, 0.15) !important; - border-color: #10b981 !important; - color: #10b981 !important; -} - -.grammar-opt-btn.btn-wrong { - background: rgba(239, 68, 68, 0.15) !important; - border-color: #ef4444 !important; - color: #ef4444 !important; -} - -.grammar-feedback-box { - border-radius: var(--radius-md); - padding: 16px 18px; - animation: fadeIn 0.2s ease-out; -} - -.grammar-feedback-box.feedback-correct { - background: rgba(16, 185, 129, 0.12); - border: 1px solid rgba(16, 185, 129, 0.3); -} - -.grammar-feedback-box.feedback-wrong { - background: rgba(239, 68, 68, 0.12); - border: 1px solid rgba(239, 68, 68, 0.3); -} - -.grammar-feedback-box .feedback-title { - font-size: 15px; - font-weight: 700; - margin-bottom: 6px; - display: flex; - align-items: center; - gap: 8px; -} - -.feedback-correct .feedback-title { - color: #10b981; -} - -.feedback-wrong .feedback-title { - color: #ef4444; -} - -.grammar-feedback-box .feedback-text { - font-size: 13.5px; - color: var(--text-main); - line-height: 1.5; -} - -.feedback-srs-ingested { - margin-top: 10px; - padding-top: 10px; - border-top: 1px solid rgba(239, 68, 68, 0.2); - font-size: 12.5px; - font-weight: 600; - color: #ef4444; - display: flex; - align-items: center; - gap: 6px; -} - -/* ========================================================================== - Grammar Summary Card - ========================================================================== */ - -.grammar-summary-card { - background-color: var(--bg-card); - border: 1px solid var(--border-color); - border-radius: var(--radius-lg); - padding: 44px 32px; - text-align: center; - display: flex; - flex-direction: column; - align-items: center; - gap: 20px; - box-shadow: var(--shadow-lg); - animation: fadeIn 0.3s ease-out; - max-width: 680px; - margin: 0 auto; -} - -.summary-score-large { - font-size: 48px; - font-weight: 900; - color: var(--color-primary); - line-height: 1; -} - -.summary-reminder-box { - display: flex; - align-items: center; - gap: 12px; - background: rgba(139, 92, 246, 0.1); - border: 1px solid rgba(139, 92, 246, 0.25); - border-radius: var(--radius-md); - padding: 12px 18px; - text-align: left; - max-width: 500px; -} - -.summary-reminder-box .reminder-icon { - font-size: 24px; - flex-shrink: 0; -} - -.summary-reminder-box .reminder-text { - display: flex; - flex-direction: column; - gap: 2px; - font-size: 13px; - line-height: 1.4; - color: var(--text-main); -} - -/* Mobile Responsive */ -@media (max-width: 640px) { - .grammar-view { - padding: 16px 12px 90px 12px; - } - - .grammar-contrast-card { - grid-template-columns: 1fr; - } - - .contrast-divider { - margin: 4px 0; - } - - .grammar-tap-options { - grid-template-columns: 1fr; - } - - .grammar-opt-btn { - min-height: 48px; - padding: 12px 14px; - } - - .cloze-sentence-display { - font-size: 17px; - } - - .grammar-lesson-topbar { - flex-direction: column; - align-items: stretch; - } - - .grammar-tab-switch { - width: 100%; - display: flex; - } - - .grammar-tab-switch .tab-btn { - flex: 1; - text-align: center; - } -} - -/* ======================================================================= - Comprehensive Lesson Configurator & Session Runner (Beta) - ======================================================================= */ - -.lesson-view, .lesson-runner-view { - padding: 24px 20px; - max-width: 960px; - margin: 0 auto; - width: 100%; - box-sizing: border-box; -} - -@media (max-width: 768px) { - .lesson-view, .lesson-runner-view { - padding: 12px 10px; - padding-bottom: calc(75px + var(--sab)); - } -} - -.lesson-configurator-container { - display: flex; - flex-direction: column; - gap: 20px; -} - -/* Header Bar */ -.lesson-header-bar { - display: flex; - justify-content: space-between; - align-items: flex-start; - gap: 16px; - flex-wrap: wrap; - border-bottom: 1px solid var(--border-color); - padding-bottom: 18px; -} - -.lesson-title-wrap h2 { - font-size: 24px; - font-weight: 800; - margin: 0 0 6px 0; - display: flex; - align-items: center; - gap: 10px; - flex-wrap: wrap; - color: var(--text-main); -} - -.lesson-subtitle { - margin: 0; - font-size: 14px; - color: var(--text-muted); -} - -.badge-beta { - background: linear-gradient(135deg, #8b5cf6, #38bdf8); - color: #fff; - font-size: 11px; - font-weight: 700; - padding: 2px 8px; - border-radius: var(--radius-full); - text-transform: uppercase; - letter-spacing: 0.5px; -} - -.badge-ai { - background: rgba(139, 92, 246, 0.15); - color: #8b5cf6; - border: 1px solid rgba(139, 92, 246, 0.35); - font-size: 12px; - font-weight: 600; - padding: 4px 10px; - border-radius: var(--radius-sm); -} - -.lesson-header-actions { - display: flex; - gap: 10px; - align-items: center; - flex-wrap: wrap; -} - -.pulse-btn { - box-shadow: 0 0 0 0 rgba(56, 189, 248, 0.7); - animation: btnPulse 2s infinite; -} - -@keyframes btnPulse { - 0% { transform: scale(1); box-shadow: 0 0 0 0 rgba(56, 189, 248, 0.4); } - 70% { transform: scale(1.02); box-shadow: 0 0 0 10px rgba(56, 189, 248, 0); } - 100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(56, 189, 248, 0); } -} - -@media (max-width: 768px) { - .lesson-header-bar { - flex-direction: column; - align-items: stretch; - gap: 14px; - padding-bottom: 14px; - } - .lesson-title-wrap h2 { - font-size: 20px; - } - .lesson-subtitle { - font-size: 13px; - } - .lesson-header-actions { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 8px; - width: 100%; - } - .lesson-header-actions #lesson-start-btn { - grid-column: span 2; - order: -1; - padding: 14px; - font-size: 16px; - font-weight: 800; - } -} - -/* Presets Chips Bar */ -.lesson-presets-section { - background: var(--bg-card); - border: 1px solid var(--border-color); - border-radius: var(--radius-lg); - padding: 16px 20px; -} - -.presets-section-title { - font-size: 14px; - font-weight: 700; - margin-bottom: 12px; - color: var(--text-main); -} - -.lesson-presets-chips-row { - display: flex; - gap: 10px; - overflow-x: auto; - padding-bottom: 6px; - -webkit-overflow-scrolling: touch; - scrollbar-width: none; -} -.lesson-presets-chips-row::-webkit-scrollbar { - display: none; -} - -.lesson-preset-chip { - display: inline-flex; - align-items: center; - gap: 8px; - padding: 9px 16px; - background: var(--bg-main); - border: 1.5px solid var(--border-color); - border-radius: var(--radius-full); - font-size: 13.5px; - font-weight: 600; - color: var(--text-main); - cursor: pointer; - white-space: nowrap; - transition: var(--transition); - user-select: none; - -webkit-tap-highlight-color: transparent; -} - -.lesson-preset-chip:hover { - border-color: var(--primary); - background: var(--bg-surface-hover); -} - -.lesson-preset-chip.active { - background: var(--primary); - color: #fff; - border-color: var(--primary); - box-shadow: 0 2px 10px rgba(56, 189, 248, 0.35); -} - -.preset-del-btn { - margin-left: 6px; - opacity: 0.7; - font-size: 12px; - border-radius: 50%; - padding: 2px 6px; -} - -.preset-del-btn:hover { - opacity: 1; - background: rgba(0, 0, 0, 0.2); -} - -.preset-description-text { - font-size: 13px; - margin: 8px 0 0 0; - color: var(--text-muted); -} - -/* Blocks List & Cards */ -.blocks-section-header { - display: flex; - justify-content: space-between; - align-items: baseline; - gap: 12px; - flex-wrap: wrap; - margin-bottom: 12px; -} - -.blocks-section-header h3 { - margin: 0; - font-size: 18px; - font-weight: 700; - color: var(--text-main); -} - -.blocks-tip { - font-size: 12.5px; - color: var(--text-muted); -} - -.lesson-steps-list { - display: flex; - flex-direction: column; - gap: 12px; -} - -.lesson-step-card { - background: var(--bg-card); - border: 1px solid var(--border-color); - border-radius: var(--radius-lg); - padding: 16px 18px; - transition: border-color 0.2s ease, box-shadow 0.2s ease; -} - -.lesson-step-card:hover { - border-color: rgba(56, 189, 248, 0.4); -} - -.lesson-step-card.step-disabled { - opacity: 0.55; - background: var(--bg-main); -} - -.step-card-header { - display: flex; - justify-content: space-between; - align-items: center; - gap: 10px; -} - -.step-card-title-wrap { - display: flex; - align-items: center; - gap: 10px; - min-width: 0; - flex: 1; -} - -.step-num { - width: 28px; - height: 28px; - background: var(--bg-main); - border: 1px solid var(--border-color); - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - font-size: 12px; - font-weight: 800; - flex-shrink: 0; - color: var(--text-main); -} - -.step-icon { - font-size: 20px; - flex-shrink: 0; -} - -.step-title { - font-size: 15px; - font-weight: 700; - color: var(--text-main); - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - -.step-card-actions { - display: flex; - align-items: center; - gap: 8px; - flex-shrink: 0; -} - -.step-card-actions .icon-btn { - min-width: 34px; - min-height: 34px; - display: flex; - align-items: center; - justify-content: center; - border-radius: var(--radius-sm); - font-size: 13px; -} - -/* Switch Toggle */ -.switch-toggle { - position: relative; - display: inline-block; - width: 46px; - height: 26px; - flex-shrink: 0; -} - -.switch-toggle input { - opacity: 0; - width: 0; - height: 0; -} - -.toggle-slider { - position: absolute; - cursor: pointer; - top: 0; left: 0; right: 0; bottom: 0; - background-color: var(--border-color); - transition: .2s; - border-radius: 26px; -} - -.toggle-slider:before { - position: absolute; - content: ""; - height: 20px; - width: 20px; - left: 3px; - bottom: 3px; - background-color: white; - transition: .2s; - border-radius: 50%; -} - -input:checked + .toggle-slider { - background-color: var(--success); -} - -input:checked + .toggle-slider:before { - transform: translateX(20px); -} - -/* Step Card Body & Params */ -.step-card-body { - margin-top: 14px; - padding-top: 14px; - border-top: 1px solid var(--border-color); -} - -.step-param-row { - display: flex; - gap: 16px; - flex-wrap: wrap; - align-items: flex-end; -} - -.param-group { - display: flex; - flex-direction: column; - gap: 6px; -} - -.param-group label { - font-size: 12.5px; - font-weight: 600; - color: var(--text-muted); -} - -.param-group.flex-2 { - flex: 2; - min-width: 240px; -} - -.segmented-control { - display: inline-flex; - background: var(--bg-main); - border: 1px solid var(--border-color); - border-radius: var(--radius-md); - padding: 3px; - gap: 3px; -} - -.seg-btn { - border: none; - background: transparent; - padding: 7px 14px; - font-size: 13px; - font-weight: 600; - color: var(--text-muted); - border-radius: var(--radius-sm); - cursor: pointer; - transition: all 0.15s ease; - user-select: none; - -webkit-tap-highlight-color: transparent; -} - -.seg-btn:hover { - color: var(--text-main); -} - -.seg-btn.active { - background: var(--primary); - color: #fff; - font-weight: 700; - box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2); -} - -/* Mode Segmented Control: 2x2 grid on mobile, horizontal pill on desktop */ -.mode-segmented-control { - display: flex; - flex-wrap: wrap; - gap: 4px; - width: 100%; -} - -.mode-segmented-control .seg-btn { - flex: 1 1 calc(50% - 4px); - display: inline-flex; - align-items: center; - justify-content: center; - gap: 6px; - padding: 9px 8px; - font-size: 13px; - text-align: center; -} - -@media (min-width: 768px) { - .step-param-row { - flex-direction: row; - align-items: flex-end; - } - .mode-segmented-control { - display: inline-flex; - flex-wrap: nowrap; - width: auto; - } - .mode-segmented-control .seg-btn { - flex: initial; - padding: 7px 14px; - } -} - -@media (max-width: 767px) { - .step-param-row { - flex-direction: column; - align-items: stretch; - gap: 12px; - } - .param-group { - width: 100%; - } - .param-group.flex-2 { - min-width: 0; - } - .step-select-param { - width: 100%; - padding: 11px 12px; - font-size: 14px; - } -} - -.step-select-param { - background: var(--bg-main); - color: var(--text-main); - border: 1px solid var(--border-color); - border-radius: var(--radius-md); - padding: 9px 12px; - font-size: 13.5px; - font-weight: 500; - cursor: pointer; - outline: none; - transition: var(--transition); -} - -.step-select-param:focus { - border-color: var(--primary); -} - -.ai-debrief-info-box { - display: flex; - align-items: center; - gap: 12px; - background: rgba(139, 92, 246, 0.08); - border: 1px dashed rgba(139, 92, 246, 0.35); - padding: 14px 16px; - border-radius: var(--radius-md); - font-size: 13.5px; - color: var(--text-main); - line-height: 1.5; -} - -.ai-box-icon { - font-size: 24px; - flex-shrink: 0; -} - -/* Bottom Floating CTA */ -.lesson-bottom-cta { - padding: 10px 0; -} - -@media (max-width: 768px) { - .lesson-bottom-cta { - position: sticky; - bottom: calc(12px + var(--sab)); - z-index: 40; - padding: 8px 0; - margin-top: 16px; - } - .lesson-bottom-cta .btn { - box-shadow: 0 4px 20px rgba(56, 189, 248, 0.4); - } -} - -.btn-xl { - padding: 15px 24px; - font-size: 17px; - font-weight: 800; - border-radius: var(--radius-lg); -} - -/* ======================================================================= - Lesson Session Runner Stage - ======================================================================= */ - -.lesson-runner-header { - display: flex; - justify-content: space-between; - align-items: center; - gap: 16px; - padding: 14px 0; - border-bottom: 1px solid var(--border-color); - flex-wrap: wrap; - position: sticky; - top: 0; - z-index: 50; - background: var(--bg-main); - backdrop-filter: blur(12px); - -webkit-backdrop-filter: blur(12px); -} - -.runner-nav-left { - display: flex; - align-items: center; - gap: 12px; -} - -.runner-timer-wrap { - font-family: var(--font-mono, monospace); - font-size: 15px; - font-weight: 700; - color: var(--text-main); - background: var(--bg-card); - padding: 5px 12px; - border-radius: var(--radius-full); - border: 1px solid var(--border-color); - white-space: nowrap; -} - -.runner-breadcrumbs-row { - display: flex; - align-items: center; - gap: 6px; - overflow-x: auto; - max-width: 540px; - padding: 4px 0; - -webkit-overflow-scrolling: touch; - scrollbar-width: none; -} -.runner-breadcrumbs-row::-webkit-scrollbar { - display: none; -} - -.runner-crumb { - display: inline-flex; - align-items: center; - gap: 6px; - padding: 5px 12px; - border-radius: var(--radius-full); - font-size: 12px; - font-weight: 600; - background: var(--bg-card); - border: 1px solid var(--border-color); - color: var(--text-muted); - white-space: nowrap; - transition: var(--transition); -} - -.crumb-num { - font-size: 11px; - font-weight: 800; -} - -.runner-crumb.step-done { - background: rgba(16, 185, 129, 0.15); - border-color: rgba(16, 185, 129, 0.4); - color: var(--success); -} - -.runner-crumb.step-active { - background: var(--primary); - border-color: var(--primary); - color: #fff; - box-shadow: 0 0 12px rgba(56, 189, 248, 0.45); -} - -.crumb-separator { - color: var(--text-dim); - font-size: 11px; -} - -@media (max-width: 768px) { - .lesson-runner-header { - padding: 10px 8px; - display: grid; - grid-template-columns: auto 1fr auto; - gap: 8px; - align-items: center; - } - .runner-nav-left { - gap: 6px; - } - .runner-nav-left .btn { - padding: 6px 10px; - font-size: 12px; - } - .runner-timer-wrap { - font-size: 13px; - padding: 4px 8px; - } - .runner-breadcrumbs-row { - max-width: none; - flex-wrap: nowrap; - gap: 4px; - justify-content: center; - } - .runner-crumb { - padding: 4px 8px; - font-size: 11px; - } - /* On mobile, collapse inactive crumbs to save horizontal space */ - .runner-crumb:not(.step-active) .crumb-label { - display: none; - } - .crumb-separator { - font-size: 9px; - } - .runner-nav-right .btn { - padding: 6px 8px; - font-size: 12px; - white-space: nowrap; - } -} - -.lesson-runner-progress-track { - width: 100%; - height: 4px; - background: var(--bg-surface-hover); - overflow: hidden; - margin-bottom: 24px; -} - -.lesson-runner-progress-fill { - height: 100%; - background: linear-gradient(90deg, #38bdf8, #8b5cf6); - transition: width 0.3s ease; -} - -/* Stage Card Box */ -.step-card-box { - background: var(--bg-card); - border: 1px solid var(--border-color); - border-radius: var(--radius-lg); - padding: 28px 24px; - box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08); - max-width: 760px; - margin: 0 auto; -} - -@media (max-width: 640px) { - .step-card-box { - padding: 18px 14px; - border-radius: var(--radius-md); - } -} - -.step-mini-header { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 18px; - gap: 10px; - flex-wrap: wrap; -} - -.step-tags-wrap { - display: flex; - align-items: center; - gap: 8px; - flex-wrap: wrap; -} - -.step-term-display { - text-align: center; - padding: 16px 0; -} - -.display-term { - font-size: 36px; - font-weight: 800; - margin: 0 0 6px 0; - color: var(--text-main); - letter-spacing: -0.5px; -} - -.display-phonetic { - font-size: 18px; - color: var(--text-muted); -} - -.step-context-box { - background: var(--bg-main); - border-left: 3px solid var(--primary); - padding: 12px 16px; - border-radius: 0 var(--radius-sm) var(--radius-sm) 0; - margin-top: 14px; - font-size: 15px; - line-height: 1.5; -} - -/* ----------------------------------------------------------------------- - Vocabulary Step: Modes - ----------------------------------------------------------------------- */ - -/* Mode 1: Quiz (4 Options) */ -.lesson-quiz-card { - max-width: 680px; - margin: 0 auto; -} - -.lesson-quiz-options-grid { - display: grid; - grid-template-columns: 1fr; - gap: 10px; - width: 100%; -} - -@media (min-width: 640px) { - .lesson-quiz-options-grid { - grid-template-columns: repeat(2, 1fr); - gap: 12px; - } -} - -.lesson-quiz-opt-btn { - display: flex; - align-items: center; - gap: 12px; - padding: 14px 16px; - min-height: 56px; - background: var(--bg-main); - border: 1.5px solid var(--border-color); - border-radius: var(--radius-md); - font-size: 15px; - font-weight: 600; - color: var(--text-main); - cursor: pointer; - transition: all 0.15s ease; - text-align: left; - user-select: none; - -webkit-tap-highlight-color: transparent; -} - -.lesson-quiz-opt-btn:hover:not(:disabled) { - border-color: var(--primary); - background: var(--bg-surface-hover); - transform: translateY(-1px); -} - -.lesson-quiz-opt-btn:active:not(:disabled) { - transform: scale(0.98); -} - -.quiz-opt-num { - display: flex; - align-items: center; - justify-content: center; - width: 28px; - height: 28px; - border-radius: 50%; - background: var(--bg-card); - border: 1px solid var(--border-color); - font-size: 12px; - font-weight: 700; - color: var(--text-muted); - flex-shrink: 0; -} - -.quiz-opt-text { - flex: 1; - line-height: 1.35; - word-break: break-word; -} - -.lesson-quiz-opt-btn.opt-correct { - background: rgba(16, 185, 129, 0.18) !important; - border-color: var(--success) !important; - color: var(--success) !important; -} - -.lesson-quiz-opt-btn.opt-correct .quiz-opt-num { - background: var(--success); - color: #fff; - border-color: var(--success); -} - -.lesson-quiz-opt-btn.opt-wrong { - background: rgba(239, 68, 68, 0.18) !important; - border-color: var(--danger) !important; - color: var(--danger) !important; -} - -.lesson-quiz-opt-btn.opt-wrong .quiz-opt-num { - background: var(--danger); - color: #fff; - border-color: var(--danger); -} - -/* Mode 2: Flashcards */ -.translation-reveal-banner { - background: rgba(56, 189, 248, 0.1); - border: 1px solid rgba(56, 189, 248, 0.3); - padding: 16px 20px; - border-radius: var(--radius-md); - text-align: center; - color: var(--text-main); -} - -.tr-text { - font-size: 22px; - display: block; - margin-top: 4px; -} - -.tr-definition { - font-size: 14px; -} - -.rating-buttons-row { - display: grid; - grid-template-columns: repeat(4, 1fr); - gap: 10px; -} - -@media (max-width: 640px) { - .rating-buttons-row { - grid-template-columns: repeat(2, 1fr); - gap: 8px; - } -} - -.srs-btn-rating { - display: flex; - flex-direction: column; - align-items: center; - padding: 12px 6px; - gap: 4px; - min-height: 52px; - border-radius: var(--radius-md); -} - -.rating-key { - font-size: 11px; - opacity: 0.7; -} - -.rating-label { - font-size: 13px; - font-weight: 700; -} - -/* Mode 3: Typing & Mode 4: Dictation */ -.typing-input-wrap { - display: flex; - flex-direction: column; - gap: 10px; - width: 100%; -} - -@media (min-width: 640px) { - .typing-input-wrap { - flex-direction: row; - } - .typing-input-wrap .typing-main-input { - flex: 1; - } -} - -.typing-main-input { - font-size: 16px !important; /* Prevents auto-zoom on mobile safari/chrome */ - padding: 12px 16px; - border-radius: var(--radius-md); -} - -.dictation-hero-play { - padding: 10px 0; -} - -.dictation-play-btn { - padding: 14px 28px; - font-size: 16px; - font-weight: 700; - border-radius: var(--radius-full); -} - -.dictation-hint { - font-size: 14px; -} - -/* Shared Trainer Feedback Box */ -.trainer-feedback-box { - padding: 14px 18px; - border-radius: var(--radius-md); - font-size: 14.5px; - line-height: 1.5; - animation: fadeIn 0.2s ease-out; -} - -.trainer-feedback-box.feedback-correct { - background: rgba(16, 185, 129, 0.12); - border: 1px solid rgba(16, 185, 129, 0.35); - color: var(--text-main); -} - -.trainer-feedback-box.feedback-wrong { - background: rgba(239, 68, 68, 0.12); - border: 1px solid rgba(239, 68, 68, 0.35); - color: var(--text-main); -} - -/* ----------------------------------------------------------------------- - Grammar Questions & Theory Stage - ----------------------------------------------------------------------- */ - -.grammar-question-box { - background: var(--bg-main); - border: 1px solid var(--border-color); - border-radius: var(--radius-md); - padding: 20px 18px; -} - -.grammar-sentence-prompt { - font-size: 20px; - font-weight: 600; - line-height: 1.5; - margin: 0 0 10px 0; - color: var(--text-main); -} - -.clue-tag { - font-size: 13px; - color: var(--text-muted); -} - -.grammar-options-grid { - display: grid; - grid-template-columns: repeat(2, 1fr); - gap: 12px; -} - -@media (max-width: 640px) { - .grammar-options-grid { - grid-template-columns: 1fr; - gap: 10px; - } -} - -.grammar-opt-btn { - display: flex; - align-items: center; - gap: 12px; - padding: 14px 18px; - min-height: 54px; - background: var(--bg-main); - border: 1.5px solid var(--border-color); - border-radius: var(--radius-md); - cursor: pointer; - font-size: 15px; - font-weight: 600; - color: var(--text-main); - transition: all 0.15s ease; - text-align: left; - user-select: none; - -webkit-tap-highlight-color: transparent; -} - -.grammar-opt-btn:hover:not(:disabled) { - border-color: var(--primary); - background: var(--bg-surface-hover); -} - -.grammar-opt-btn.opt-correct { - background: rgba(16, 185, 129, 0.18) !important; - border-color: var(--success) !important; - color: var(--success) !important; -} - -.grammar-opt-btn.opt-wrong { - background: rgba(239, 68, 68, 0.18) !important; - border-color: var(--danger) !important; - color: var(--danger) !important; -} - -.opt-key { - width: 26px; - height: 26px; - background: var(--bg-card); - border: 1px solid var(--border-color); - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - font-size: 12px; - font-weight: 700; - flex-shrink: 0; -} - -.feedback-banner { - padding: 16px 18px; - border-radius: var(--radius-md); -} - -.feedback-banner.fb-success { - background: rgba(16, 185, 129, 0.12); - border: 1px solid rgba(16, 185, 129, 0.35); -} - -.feedback-banner.fb-danger { - background: rgba(239, 68, 68, 0.12); - border: 1px solid rgba(239, 68, 68, 0.35); -} - -.fb-title { - font-size: 16px; - font-weight: 700; - margin-bottom: 6px; -} - -.fb-text { - font-size: 14px; - line-height: 1.45; -} - -/* Murphy Golden Formula & Contrasts */ -.golden-formula-box { - background: linear-gradient(135deg, rgba(99, 102, 241, 0.08), rgba(168, 85, 247, 0.08)); - border: 1px solid rgba(99, 102, 241, 0.3); - border-radius: var(--radius-md); - padding: 16px; -} - -.formula-label { - font-size: 12px; - font-weight: 800; - text-transform: uppercase; - letter-spacing: 0.5px; - color: var(--primary); - margin-bottom: 8px; -} - -.formula-code { - background: var(--bg-card); - border: 1px solid var(--border-color); - border-radius: var(--radius-sm); - padding: 10px 14px; - font-family: var(--font-mono, monospace); - font-size: 14px; - font-weight: 700; - color: var(--text-main); - overflow-x: auto; - white-space: pre-wrap; - margin: 0; -} - -.contrast-card { - background: var(--bg-card); - border: 1px solid var(--border-color); - border-radius: var(--radius-md); - padding: 16px; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04); -} - -.contrast-row { - display: flex; - flex-direction: column; - gap: 12px; -} - -@media (min-width: 640px) { - .contrast-row { - flex-direction: row; - gap: 16px; - } -} - -.contrast-col { - flex: 1; - background: var(--bg-main); - border: 1px solid var(--border-color); - border-radius: var(--radius-sm); - padding: 12px; -} - -.contrast-col.a { - border-left: 3px solid #38bdf8; -} - -.contrast-col.b { - border-left: 3px solid #10b981; -} - -.contrast-col .col-title { - font-size: 13px; - font-weight: 700; - color: var(--text-main); - margin-bottom: 6px; -} - -.contrast-col .col-example { - font-size: 15px; - font-weight: 600; - color: var(--text-main); - margin-bottom: 4px; -} - -.contrast-col .col-trans { - font-size: 13px; - color: var(--text-muted); -} - -.contrast-diff { - background: rgba(245, 158, 11, 0.1); - border: 1px solid rgba(245, 158, 11, 0.3); - border-radius: var(--radius-sm); - padding: 8px 12px; - font-size: 13px; - color: var(--text-main); -} - -.journaling-box { - background: rgba(56, 189, 248, 0.06); - border: 1px dashed rgba(56, 189, 248, 0.3); - border-radius: var(--radius-md); - padding: 14px 18px; -} - -.hw-text { - font-size: 14px; - font-weight: 600; - color: var(--text-main); -} - -/* ----------------------------------------------------------------------- - Listening Stage - ----------------------------------------------------------------------- */ - -.audio-player-card { - background: var(--bg-main); - border: 1px solid var(--border-color); - border-radius: var(--radius-md); - padding: 20px; - text-align: center; -} - -.audio-controls-row { - display: flex; - justify-content: center; - gap: 12px; - align-items: center; - flex-wrap: wrap; -} - -.answer-input-group { - display: flex; - gap: 10px; -} - -@media (max-width: 640px) { - .answer-input-group { - flex-direction: column; - } -} - -.transcript-box { - background: var(--bg-main); - border: 1px solid var(--border-color); - border-radius: var(--radius-sm); - padding: 12px 14px; - font-size: 13.5px; -} - -/* ----------------------------------------------------------------------- - Reading Stage - ----------------------------------------------------------------------- */ - -.article-paragraph-card { - background: var(--bg-main); - border: 1px solid var(--border-color); - border-radius: var(--radius-md); - padding: 18px; - margin-bottom: 14px; -} - -.article-para-en { - font-size: 17px; - line-height: 1.75; - margin: 0 0 10px 0; -} - -.clickable-reader-word { - cursor: pointer; - border-radius: 3px; - padding: 1px 3px; - transition: background 0.15s; -} - -.clickable-reader-word:hover { - background: rgba(56, 189, 248, 0.25); - color: var(--primary); -} - -.article-para-ru { - font-size: 14px; - color: var(--text-muted); - border-top: 1px dashed var(--border-color); - padding-top: 8px; - margin: 8px 0 0 0; -} - -.vocab-highlights-bar { - background: var(--bg-main); - border: 1px solid var(--border-color); - border-radius: var(--radius-md); - padding: 14px 16px; -} - -.highlights-title { - font-size: 13px; - font-weight: 700; - margin-bottom: 8px; - display: block; -} - -.highlights-chips { - display: flex; - flex-wrap: wrap; - gap: 8px; -} - -.vh-chip { - background: var(--bg-card); - border: 1px solid var(--border-color); - padding: 5px 12px; - border-radius: var(--radius-full); - font-size: 12.5px; -} - -/* Word Popup in Lesson: Floating on laptop, Bottom sheet on mobile */ -.lesson-popup { - position: fixed; - z-index: 1000; - width: 270px; - background: var(--bg-card); - border: 1px solid var(--border-color); - border-radius: var(--radius-md); - padding: 14px 16px; - box-shadow: 0 10px 30px rgba(0,0,0,0.25); - animation: fadeIn 0.15s ease-out; -} - -@media (max-width: 640px) { - .lesson-popup { - left: 14px !important; - right: 14px !important; - bottom: calc(20px + var(--sab)) !important; - top: auto !important; - width: auto !important; - border-radius: var(--radius-lg); - box-shadow: 0 4px 30px rgba(0, 0, 0, 0.5); - } -} - -.popup-header { - display: flex; - justify-content: space-between; - align-items: center; - border-bottom: 1px solid var(--border-color); - padding-bottom: 6px; - margin-bottom: 6px; -} - -.popup-close-btn { - border: none; - background: transparent; - cursor: pointer; - color: var(--text-muted); - font-size: 16px; -} - -.popup-trans { - font-size: 15px; - font-weight: 700; - color: var(--text-main); -} - -/* ----------------------------------------------------------------------- - AI Debrief Stage - ----------------------------------------------------------------------- */ - -.lesson-debrief-card { - max-width: 800px; -} - -.debrief-banner-header { - display: flex; - align-items: center; - gap: 20px; - border-bottom: 1px solid var(--border-color); - padding-bottom: 20px; - flex-wrap: wrap; -} - -.grade-badge-wrap { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - width: 90px; - height: 90px; - background: var(--bg-main); - border: 3px solid var(--primary); - border-radius: 50%; - flex-shrink: 0; -} - -.grade-badge { - font-size: 34px; - font-weight: 900; - line-height: 1; - color: var(--primary); -} - -.score-pct { - font-size: 13px; - font-weight: 700; - color: var(--text-muted); -} - -.debrief-titles { - flex: 1; - min-width: 220px; -} - -.debrief-headline { - font-size: 22px; - font-weight: 800; - margin: 0 0 8px 0; - color: var(--text-main); -} - -.blocks-scores-grid { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); - gap: 12px; -} - -.block-score-item { - background: var(--bg-main); - border: 1px solid var(--border-color); - border-radius: var(--radius-sm); - padding: 10px 12px; -} - -.bs-header { - display: flex; - justify-content: space-between; - font-size: 13px; - font-weight: 600; - margin-bottom: 6px; - color: var(--text-main); -} - -.bs-bar { - width: 100%; - height: 6px; - background: var(--bg-card); - border-radius: 3px; - overflow: hidden; -} - -.bs-bar-fill { - height: 100%; - background: var(--success); -} - -.debrief-list, .tomorrow-focus-list { - margin: 8px 0 0 0; - padding-left: 20px; - font-size: 14.5px; - line-height: 1.6; -} - -.tomorrow-focus-list { - list-style: none; - padding-left: 0; -} - -.tomorrow-focus-list li { - padding: 8px 12px; - background: var(--bg-main); - border-left: 3px solid var(--primary); - margin-bottom: 6px; - border-radius: 0 var(--radius-sm) var(--radius-sm) 0; - font-size: 14px; -} - -.error-cards-list { - display: flex; - flex-direction: column; - gap: 8px; -} - -.error-analysis-item { - display: flex; - align-items: flex-start; - gap: 10px; - background: rgba(234, 179, 8, 0.1); - border: 1px solid rgba(234, 179, 8, 0.3); - border-radius: var(--radius-md); - padding: 12px 14px; - font-size: 14px; - line-height: 1.45; -} - -.celebrate-badge { - font-size: 48px; - margin-bottom: 12px; -} - -.step-completed-box h3 { - font-size: 24px; - font-weight: 800; - margin-bottom: 8px; - color: var(--text-main); -} - -.score-highlight { - font-size: 16px; - color: var(--text-muted); -} - -/* History Modal items */ -.lesson-history-list { - display: flex; - flex-direction: column; - gap: 12px; - max-height: 65vh; - overflow-y: auto; -} - -.lesson-history-item { - background: var(--bg-main); - border: 1px solid var(--border-color); - border-radius: var(--radius-md); - padding: 14px 16px; -} - -.lh-header { - display: flex; - justify-content: space-between; - font-size: 15px; - font-weight: 700; - margin-bottom: 6px; -} - -.lh-date { - font-size: 12px; - color: var(--text-muted); - font-weight: normal; -} - -.lh-stats { - display: flex; - gap: 12px; - align-items: center; - font-size: 13px; - margin-bottom: 6px; -} - -.lh-headline { - font-size: 13px; - font-style: italic; - color: var(--text-dim); -} - -@media (max-width: 640px) { - .display-term { - font-size: 26px; - } -} - +@import "base.css"; +@import "components.css"; +@import "dictionary.css"; +@import "srs.css"; +@import "reader.css"; +@import "grammar_cefr.css"; +@import "lesson.css"; diff --git a/app/static/index.html b/app/static/index.html index 21c566c..f870523 100644 --- a/app/static/index.html +++ b/app/static/index.html @@ -5,7 +5,7 @@ Notes — Персональный тренажер и словарь английского языка - + diff --git a/app/static/sw.js b/app/static/sw.js index dd768f0..e6c7412 100644 --- a/app/static/sw.js +++ b/app/static/sw.js @@ -1,12 +1,19 @@ // Service Worker for Notes English PWA (Stage 2) // Strategy: Cache-first for static assets, Network-first for API calls. -const CACHE_NAME = 'notes-v6.6'; +const CACHE_NAME = 'notes-v6.7'; const OFFLINE_URL = '/'; const PRECACHE_URLS = [ '/', '/static/css/style.css', + '/static/css/base.css', + '/static/css/components.css', + '/static/css/dictionary.css', + '/static/css/srs.css', + '/static/css/reader.css', + '/static/css/grammar_cefr.css', + '/static/css/lesson.css', '/static/js/app.js', '/static/js/modules/api.js', '/static/js/modules/ui.js',