1589 lines
102 KiB
HTML
1589 lines
102 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="ru" data-theme="light">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||
<title>ArabicVibe — Изучай арабский онлайн</title>
|
||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700;800&family=Noto+Sans+Arabic:wght@400;600;700&display=swap" rel="stylesheet">
|
||
<style>
|
||
[data-theme="light"] {
|
||
--ink: #0F1218;
|
||
--bg: #FFFFFF;
|
||
--bg-card: #F2F4F7;
|
||
--bg-card-hover: #E8FCFF;
|
||
--text-secondary: #5B6573;
|
||
--cyan: #00E5FF;
|
||
--cyan-dark: #00b8cc;
|
||
--accent: #6366f1;
|
||
--accent-light: #818cf8;
|
||
--success: #22c55e;
|
||
--warning: #f59e0b;
|
||
--error: #ef4444;
|
||
--border: #e5e7eb;
|
||
--shadow: 0 4px 24px rgba(0,0,0,0.08);
|
||
--shadow-lg: 0 12px 48px rgba(0,0,0,0.12);
|
||
--gradient-hero: linear-gradient(135deg, #0F1218 0%, #1a1f2e 100%);
|
||
--gradient-accent: linear-gradient(135deg, #00E5FF 0%, #6366f1 100%);
|
||
--gradient-card: linear-gradient(135deg, rgba(0,229,255,0.05) 0%, rgba(99,102,241,0.05) 100%);
|
||
--glass: rgba(255,255,255,0.8);
|
||
--glass-border: rgba(255,255,255,0.2);
|
||
}
|
||
|
||
[data-theme="dark"] {
|
||
--ink: #f0f2f5;
|
||
--bg: #0a0e17;
|
||
--bg-card: #151b2b;
|
||
--bg-card-hover: #1a2235;
|
||
--text-secondary: #8b95a5;
|
||
--cyan: #00E5FF;
|
||
--cyan-dark: #00b8cc;
|
||
--accent: #818cf8;
|
||
--accent-light: #a5b4fc;
|
||
--success: #4ade80;
|
||
--warning: #fbbf24;
|
||
--error: #f87171;
|
||
--border: #1e2738;
|
||
--shadow: 0 4px 24px rgba(0,0,0,0.3);
|
||
--shadow-lg: 0 12px 48px rgba(0,0,0,0.4);
|
||
--gradient-hero: linear-gradient(135deg, #0a0e17 0%, #111827 100%);
|
||
--gradient-accent: linear-gradient(135deg, #00E5FF 0%, #818cf8 100%);
|
||
--gradient-card: linear-gradient(135deg, rgba(0,229,255,0.08) 0%, rgba(129,140,248,0.08) 100%);
|
||
--glass: rgba(15,18,24,0.8);
|
||
--glass-border: rgba(255,255,255,0.1);
|
||
}
|
||
|
||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||
html { scroll-behavior: smooth; }
|
||
|
||
body {
|
||
font: 17px/1.6 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
|
||
color: var(--ink);
|
||
background: var(--bg);
|
||
transition: background 0.3s, color 0.3s;
|
||
}
|
||
|
||
.arabic {
|
||
font-family: 'Noto Sans Arabic', 'Arial', sans-serif;
|
||
direction: rtl;
|
||
unicode-bidi: isolate;
|
||
}
|
||
|
||
.container { max-width: 1200px; margin: 0 auto; padding: 0 24px; }
|
||
|
||
/* NAV */
|
||
.nav {
|
||
position: fixed; top: 0; left: 0; right: 0; z-index: 1000;
|
||
background: var(--glass); backdrop-filter: blur(20px);
|
||
border-bottom: 1px solid var(--border); padding: 0 24px;
|
||
}
|
||
|
||
.nav-inner {
|
||
max-width: 1200px; margin: 0 auto;
|
||
display: flex; align-items: center; justify-content: space-between; height: 70px;
|
||
}
|
||
|
||
.nav-logo {
|
||
font-size: 24px; font-weight: 800;
|
||
background: var(--gradient-accent); -webkit-background-clip: text; -webkit-text-fill-color: transparent;
|
||
text-decoration: none; cursor: pointer;
|
||
}
|
||
|
||
.nav-links { display: flex; gap: 32px; list-style: none; }
|
||
|
||
.nav-links a {
|
||
color: var(--text-secondary); text-decoration: none; font-weight: 600; font-size: 15px;
|
||
transition: color 0.2s; cursor: pointer;
|
||
}
|
||
.nav-links a:hover { color: var(--cyan); }
|
||
|
||
.nav-actions { display: flex; align-items: center; gap: 16px; }
|
||
|
||
.theme-toggle {
|
||
width: 44px; height: 44px; border-radius: 12px; border: 1px solid var(--border);
|
||
background: var(--bg-card); cursor: pointer; display: flex; align-items: center;
|
||
justify-content: center; font-size: 20px; transition: all 0.2s;
|
||
}
|
||
.theme-toggle:hover { border-color: var(--cyan); }
|
||
|
||
.btn {
|
||
display: inline-flex; align-items: center; justify-content: center; gap: 8px;
|
||
padding: 12px 24px; border-radius: 12px; font-weight: 700; font-size: 15px;
|
||
text-decoration: none; border: none; cursor: pointer; transition: all 0.2s;
|
||
}
|
||
|
||
.btn-primary {
|
||
background: var(--gradient-accent); color: #fff;
|
||
box-shadow: 0 4px 16px rgba(0,229,255,0.3);
|
||
}
|
||
.btn-primary:hover { transform: translateY(-2px); box-shadow: 0 8px 24px rgba(0,229,255,0.4); }
|
||
|
||
.btn-secondary { background: var(--bg-card); color: var(--ink); border: 1px solid var(--border); }
|
||
.btn-secondary:hover { border-color: var(--cyan); }
|
||
|
||
.btn-outline { background: transparent; color: var(--cyan); border: 2px solid var(--cyan); }
|
||
.btn-outline:hover { background: var(--cyan); color: #0F1218; }
|
||
|
||
.btn-sm { padding: 8px 16px; font-size: 13px; }
|
||
.btn-lg { padding: 16px 32px; font-size: 17px; }
|
||
|
||
.hamburger {
|
||
display: none; width: 44px; height: 44px; border: none; background: none;
|
||
cursor: pointer; flex-direction: column; align-items: center; justify-content: center; gap: 5px;
|
||
}
|
||
.hamburger span { width: 24px; height: 2px; background: var(--ink); transition: all 0.3s; }
|
||
|
||
/* HERO */
|
||
.hero {
|
||
background: var(--gradient-hero); padding: 140px 24px 100px;
|
||
text-align: center; position: relative; overflow: hidden;
|
||
}
|
||
|
||
.hero::before {
|
||
content: ''; position: absolute; top: -50%; left: -50%; width: 200%; height: 200%;
|
||
background: radial-gradient(circle at 30% 50%, rgba(0,229,255,0.1) 0%, transparent 50%),
|
||
radial-gradient(circle at 70% 50%, rgba(99,102,241,0.1) 0%, transparent 50%);
|
||
animation: pulse 8s ease-in-out infinite;
|
||
}
|
||
|
||
@keyframes pulse { 0%, 100% { opacity: 0.5; } 50% { opacity: 1; } }
|
||
|
||
.hero-content { position: relative; z-index: 1; max-width: 800px; margin: 0 auto; }
|
||
|
||
.hero-badge {
|
||
display: inline-flex; align-items: center; gap: 8px; padding: 8px 20px;
|
||
background: rgba(0,229,255,0.1); border: 1px solid rgba(0,229,255,0.3);
|
||
border-radius: 100px; color: var(--cyan); font-size: 14px; font-weight: 600; margin-bottom: 32px;
|
||
}
|
||
|
||
.hero h1 { font-size: 64px; font-weight: 800; line-height: 1.05; color: #fff; margin-bottom: 24px; }
|
||
.hero h1 span { background: var(--gradient-accent); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
|
||
|
||
.hero-arabic { font-size: 48px; color: var(--cyan); margin-bottom: 24px; opacity: 0.9; }
|
||
.hero p { font-size: 20px; color: #9aa3b2; max-width: 600px; margin: 0 auto 40px; }
|
||
|
||
.hero-actions { display: flex; gap: 16px; justify-content: center; flex-wrap: wrap; }
|
||
|
||
.hero-stats {
|
||
display: flex; gap: 48px; justify-content: center; margin-top: 60px;
|
||
padding-top: 40px; border-top: 1px solid rgba(255,255,255,0.1);
|
||
}
|
||
|
||
.hero-stat h3 { font-size: 36px; font-weight: 800; color: var(--cyan); }
|
||
.hero-stat p { font-size: 14px; color: #9aa3b2; margin: 0; }
|
||
|
||
/* SECTIONS */
|
||
.section { padding: 100px 24px; }
|
||
|
||
.section-header { text-align: center; max-width: 600px; margin: 0 auto 60px; }
|
||
|
||
.section-header .badge {
|
||
display: inline-block; padding: 6px 16px; background: rgba(0,229,255,0.1);
|
||
color: var(--cyan); border-radius: 100px; font-size: 13px; font-weight: 700; margin-bottom: 16px;
|
||
}
|
||
|
||
.section-header h2 { font-size: 42px; font-weight: 800; line-height: 1.15; margin-bottom: 16px; }
|
||
.section-header p { color: var(--text-secondary); font-size: 18px; }
|
||
|
||
/* FEATURES */
|
||
.features-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }
|
||
|
||
.feature-card {
|
||
background: var(--bg-card); border-radius: 20px; padding: 36px;
|
||
border: 1px solid var(--border); transition: all 0.3s; position: relative; overflow: hidden;
|
||
}
|
||
|
||
.feature-card::before {
|
||
content: ''; position: absolute; top: 0; left: 0; right: 0; height: 3px;
|
||
background: var(--gradient-accent); opacity: 0; transition: opacity 0.3s;
|
||
}
|
||
|
||
.feature-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg); border-color: var(--cyan); }
|
||
.feature-card:hover::before { opacity: 1; }
|
||
|
||
.feature-icon {
|
||
width: 56px; height: 56px; border-radius: 16px; background: var(--gradient-card);
|
||
display: flex; align-items: center; justify-content: center; font-size: 28px; margin-bottom: 20px;
|
||
}
|
||
|
||
.feature-card h3 { font-size: 20px; font-weight: 700; margin-bottom: 12px; }
|
||
.feature-card p { color: var(--text-secondary); font-size: 15px; line-height: 1.6; }
|
||
|
||
/* COURSES */
|
||
.courses-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }
|
||
|
||
.course-card {
|
||
background: var(--bg-card); border-radius: 20px; overflow: hidden;
|
||
border: 1px solid var(--border); transition: all 0.3s; cursor: pointer;
|
||
}
|
||
.course-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg); }
|
||
|
||
.course-header { padding: 32px; background: var(--gradient-hero); color: #fff; text-align: center; }
|
||
|
||
.course-level {
|
||
display: inline-block; padding: 4px 16px; background: rgba(0,229,255,0.2);
|
||
border-radius: 100px; font-size: 14px; font-weight: 700; color: var(--cyan); margin-bottom: 12px;
|
||
}
|
||
|
||
.course-header h3 { font-size: 28px; font-weight: 800; margin-bottom: 8px; }
|
||
.course-header p { color: #9aa3b2; font-size: 14px; }
|
||
.course-body { padding: 24px; }
|
||
|
||
.course-info { display: flex; justify-content: space-between; margin-bottom: 20px; font-size: 14px; color: var(--text-secondary); }
|
||
.course-info span { display: flex; align-items: center; gap: 6px; }
|
||
|
||
.course-topics { list-style: none; margin-bottom: 20px; }
|
||
.course-topics li { padding: 10px 0; border-bottom: 1px solid var(--border); font-size: 14px; display: flex; align-items: center; gap: 10px; }
|
||
.course-topics li:last-child { border: none; }
|
||
|
||
.course-progress { height: 6px; background: var(--border); border-radius: 100px; overflow: hidden; margin-bottom: 12px; }
|
||
.course-progress-bar { height: 100%; background: var(--gradient-accent); border-radius: 100px; transition: width 0.5s; }
|
||
|
||
/* VOCABULARY */
|
||
.vocab-section { background: var(--bg-card); }
|
||
|
||
.vocab-controls { display: flex; gap: 16px; margin-bottom: 32px; flex-wrap: wrap; }
|
||
|
||
.vocab-search {
|
||
flex: 1; min-width: 250px; padding: 14px 20px; border-radius: 12px;
|
||
border: 1px solid var(--border); background: var(--bg); color: var(--ink);
|
||
font-size: 16px; outline: none; transition: border-color 0.2s;
|
||
}
|
||
.vocab-search:focus { border-color: var(--cyan); }
|
||
|
||
.vocab-filters { display: flex; gap: 8px; flex-wrap: wrap; }
|
||
|
||
.filter-btn {
|
||
padding: 10px 20px; border-radius: 100px; border: 1px solid var(--border);
|
||
background: var(--bg); color: var(--ink); font-size: 14px; font-weight: 600;
|
||
cursor: pointer; transition: all 0.2s;
|
||
}
|
||
.filter-btn.active, .filter-btn:hover { background: var(--cyan); color: #0F1218; border-color: var(--cyan); }
|
||
|
||
.vocab-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 20px; }
|
||
|
||
.vocab-card {
|
||
background: var(--bg); border-radius: 16px; padding: 24px;
|
||
border: 1px solid var(--border); transition: all 0.3s; cursor: pointer; position: relative;
|
||
}
|
||
.vocab-card:hover { transform: translateY(-2px); box-shadow: var(--shadow); border-color: var(--cyan); }
|
||
|
||
.vocab-card .arabic-word { font-size: 36px; font-weight: 700; margin-bottom: 8px; color: var(--accent); }
|
||
.vocab-card .transcription { font-size: 14px; color: var(--text-secondary); margin-bottom: 8px; font-style: italic; }
|
||
.vocab-card .translation { font-size: 18px; font-weight: 600; margin-bottom: 12px; }
|
||
|
||
.vocab-card .example {
|
||
font-size: 14px; color: var(--text-secondary); padding: 12px;
|
||
background: var(--bg-card); border-radius: 8px; margin-top: 12px;
|
||
}
|
||
.vocab-card .example .arabic { font-size: 18px; color: var(--ink); margin-bottom: 4px; }
|
||
|
||
.vocab-card .category-tag {
|
||
position: absolute; top: 16px; right: 16px; padding: 4px 12px;
|
||
background: rgba(0,229,255,0.1); color: var(--cyan); border-radius: 100px;
|
||
font-size: 12px; font-weight: 600;
|
||
}
|
||
|
||
.vocab-card .audio-btn {
|
||
width: 40px; height: 40px; border-radius: 50%; border: 1px solid var(--border);
|
||
background: var(--bg-card); cursor: pointer; display: flex; align-items: center;
|
||
justify-content: center; font-size: 18px; transition: all 0.2s; margin-top: 12px;
|
||
}
|
||
.vocab-card .audio-btn:hover { background: var(--cyan); border-color: var(--cyan); }
|
||
|
||
.vocab-card .fav-btn {
|
||
position: absolute; top: 16px; left: 16px; width: 36px; height: 36px;
|
||
border-radius: 50%; border: none; background: transparent; cursor: pointer;
|
||
font-size: 20px; transition: all 0.2s;
|
||
}
|
||
.vocab-card .fav-btn:hover { transform: scale(1.2); }
|
||
.vocab-card .fav-btn.active { color: var(--error); }
|
||
|
||
/* QUIZ */
|
||
.quiz-container { max-width: 700px; margin: 0 auto; }
|
||
|
||
.quiz-type-selector {
|
||
display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; margin-bottom: 32px;
|
||
}
|
||
|
||
.quiz-type-card {
|
||
background: var(--bg-card); border-radius: 16px; padding: 24px;
|
||
border: 2px solid var(--border); cursor: pointer; transition: all 0.2s; text-align: center;
|
||
}
|
||
.quiz-type-card:hover { border-color: var(--cyan); transform: translateY(-2px); }
|
||
.quiz-type-card.active { border-color: var(--accent); background: rgba(99,102,241,0.1); }
|
||
.quiz-type-card .icon { font-size: 32px; margin-bottom: 8px; }
|
||
.quiz-type-card h4 { font-size: 16px; margin-bottom: 4px; }
|
||
.quiz-type-card p { font-size: 13px; color: var(--text-secondary); }
|
||
|
||
.quiz-card {
|
||
background: var(--bg-card); border-radius: 20px; padding: 40px;
|
||
border: 1px solid var(--border); margin-bottom: 24px;
|
||
}
|
||
|
||
.quiz-progress { display: flex; align-items: center; gap: 16px; margin-bottom: 32px; }
|
||
.quiz-progress-bar { flex: 1; height: 8px; background: var(--border); border-radius: 100px; overflow: hidden; }
|
||
.quiz-progress-fill { height: 100%; background: var(--gradient-accent); border-radius: 100px; transition: width 0.3s; }
|
||
.quiz-progress-text { font-size: 14px; font-weight: 700; color: var(--text-secondary); }
|
||
|
||
.quiz-question { font-size: 24px; font-weight: 700; margin-bottom: 8px; }
|
||
.quiz-arabic { font-size: 32px; color: var(--accent); margin-bottom: 32px; }
|
||
|
||
.quiz-options { display: flex; flex-direction: column; gap: 12px; }
|
||
|
||
.quiz-option {
|
||
padding: 16px 20px; border-radius: 12px; border: 2px solid var(--border);
|
||
background: var(--bg); cursor: pointer; font-size: 16px; text-align: left;
|
||
transition: all 0.2s; display: flex; align-items: center; gap: 12px;
|
||
}
|
||
.quiz-option:hover { border-color: var(--cyan); }
|
||
.quiz-option.selected { border-color: var(--accent); background: rgba(99,102,241,0.1); }
|
||
.quiz-option.correct { border-color: var(--success); background: rgba(34,197,94,0.1); }
|
||
.quiz-option.wrong { border-color: var(--error); background: rgba(239,68,68,0.1); }
|
||
|
||
.quiz-option .letter {
|
||
width: 32px; height: 32px; border-radius: 8px; background: var(--bg-card);
|
||
display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 14px; flex-shrink: 0;
|
||
}
|
||
|
||
.quiz-input {
|
||
width: 100%; padding: 16px 20px; border-radius: 12px; border: 2px solid var(--border);
|
||
background: var(--bg); color: var(--ink); font-size: 18px; outline: none; transition: border-color 0.2s;
|
||
font-family: 'Noto Sans Arabic', 'Arial', sans-serif; direction: rtl;
|
||
}
|
||
.quiz-input:focus { border-color: var(--cyan); }
|
||
|
||
.quiz-match-container { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
|
||
|
||
.quiz-match-item {
|
||
padding: 12px 16px; border-radius: 8px; border: 1px solid var(--border);
|
||
background: var(--bg); cursor: pointer; transition: all 0.2s; text-align: center;
|
||
}
|
||
.quiz-match-item:hover { border-color: var(--cyan); }
|
||
.quiz-match-item.selected { border-color: var(--accent); background: rgba(99,102,241,0.1); }
|
||
.quiz-match-item.matched { border-color: var(--success); background: rgba(34,197,94,0.1); opacity: 0.7; }
|
||
|
||
.quiz-actions { display: flex; justify-content: space-between; margin-top: 24px; }
|
||
|
||
/* QUIZ RESULTS */
|
||
.quiz-result { text-align: center; padding: 48px; }
|
||
|
||
.quiz-result .score-circle {
|
||
width: 160px; height: 160px; border-radius: 50%; background: var(--gradient-accent);
|
||
display: flex; flex-direction: column; align-items: center; justify-content: center;
|
||
margin: 0 auto 32px; color: #fff;
|
||
}
|
||
.quiz-result .score-circle .number { font-size: 48px; font-weight: 800; line-height: 1; }
|
||
.quiz-result .score-circle .label { font-size: 14px; opacity: 0.8; }
|
||
.quiz-result h3 { font-size: 28px; margin-bottom: 12px; }
|
||
.quiz-result p { color: var(--text-secondary); margin-bottom: 32px; }
|
||
|
||
/* LESSONS */
|
||
.lesson-tabs { display: flex; gap: 8px; margin-bottom: 32px; overflow-x: auto; padding-bottom: 8px; }
|
||
|
||
.lesson-tab {
|
||
padding: 10px 20px; border-radius: 100px; border: 1px solid var(--border);
|
||
background: var(--bg); color: var(--ink); font-size: 14px; font-weight: 600;
|
||
cursor: pointer; white-space: nowrap; transition: all 0.2s;
|
||
}
|
||
.lesson-tab.active, .lesson-tab:hover { background: var(--cyan); color: #0F1218; border-color: var(--cyan); }
|
||
|
||
.lesson-content {
|
||
background: var(--bg-card); border-radius: 20px; padding: 40px; border: 1px solid var(--border);
|
||
}
|
||
|
||
.lesson-content h3 { font-size: 24px; margin-bottom: 24px; }
|
||
.lesson-text { margin-bottom: 24px; }
|
||
.lesson-text p { margin-bottom: 16px; line-height: 1.8; }
|
||
|
||
.lesson-example {
|
||
background: var(--bg); border-radius: 12px; padding: 24px; margin-bottom: 16px;
|
||
border-left: 4px solid var(--cyan);
|
||
}
|
||
.lesson-example .arabic { font-size: 28px; color: var(--accent); margin-bottom: 8px; }
|
||
.lesson-example .transcription { color: var(--text-secondary); font-style: italic; margin-bottom: 4px; }
|
||
.lesson-example .translation { font-weight: 600; }
|
||
|
||
.lesson-exercise {
|
||
background: rgba(0,229,255,0.05); border: 1px solid rgba(0,229,255,0.2);
|
||
border-radius: 12px; padding: 24px; margin-top: 24px;
|
||
}
|
||
.lesson-exercise h4 { font-size: 18px; margin-bottom: 16px; display: flex; align-items: center; gap: 8px; }
|
||
|
||
.exercise-input {
|
||
width: 100%; padding: 12px 16px; border-radius: 8px; border: 1px solid var(--border);
|
||
background: var(--bg); color: var(--ink); font-size: 16px; outline: none; margin-bottom: 12px;
|
||
}
|
||
.exercise-input:focus { border-color: var(--cyan); }
|
||
|
||
.exercise-feedback {
|
||
padding: 12px; border-radius: 8px; font-size: 14px; font-weight: 600; margin-top: 8px;
|
||
display: none;
|
||
}
|
||
.exercise-feedback.correct { display: block; background: rgba(34,197,94,0.1); color: var(--success); }
|
||
.exercise-feedback.wrong { display: block; background: rgba(239,68,68,0.1); color: var(--error); }
|
||
|
||
/* DASHBOARD */
|
||
.dashboard-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px; margin-bottom: 32px; }
|
||
|
||
.stat-card {
|
||
background: var(--bg-card); border-radius: 16px; padding: 24px;
|
||
border: 1px solid var(--border); text-align: center;
|
||
}
|
||
.stat-card .stat-icon { font-size: 32px; margin-bottom: 12px; }
|
||
.stat-card .stat-value { font-size: 32px; font-weight: 800; color: var(--accent); margin-bottom: 4px; }
|
||
.stat-card .stat-label { font-size: 14px; color: var(--text-secondary); }
|
||
|
||
.streak-calendar { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; margin-top: 16px; }
|
||
.streak-day { width: 100%; aspect-ratio: 1; border-radius: 6px; background: var(--border); }
|
||
.streak-day.active { background: var(--cyan); }
|
||
.streak-day.today { background: var(--accent); box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px var(--accent); }
|
||
|
||
.achievements-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 16px; }
|
||
|
||
.achievement-card {
|
||
background: var(--bg-card); border-radius: 16px; padding: 20px;
|
||
border: 1px solid var(--border); text-align: center; transition: all 0.3s;
|
||
}
|
||
.achievement-card.locked { opacity: 0.5; }
|
||
.achievement-card .achievement-icon { font-size: 40px; margin-bottom: 8px; }
|
||
.achievement-card h4 { font-size: 15px; margin-bottom: 4px; }
|
||
.achievement-card p { font-size: 12px; color: var(--text-secondary); }
|
||
|
||
.history-list { display: flex; flex-direction: column; gap: 12px; }
|
||
.history-item {
|
||
background: var(--bg-card); border-radius: 12px; padding: 16px;
|
||
border: 1px solid var(--border); display: flex; justify-content: space-between; align-items: center;
|
||
}
|
||
.history-item .date { font-size: 13px; color: var(--text-secondary); }
|
||
.history-item .score { font-weight: 700; color: var(--accent); }
|
||
|
||
/* MODAL */
|
||
.modal-overlay {
|
||
position: fixed; inset: 0; background: rgba(0,0,0,0.5); backdrop-filter: blur(8px);
|
||
z-index: 2000; display: flex; align-items: center; justify-content: center; padding: 24px;
|
||
opacity: 0; pointer-events: none; transition: opacity 0.3s;
|
||
}
|
||
.modal-overlay.active { opacity: 1; pointer-events: all; }
|
||
|
||
.modal {
|
||
background: var(--bg); border-radius: 24px; padding: 40px; max-width: 500px;
|
||
width: 100%; max-height: 90vh; overflow-y: auto; transform: translateY(20px); transition: transform 0.3s;
|
||
}
|
||
.modal-overlay.active .modal { transform: translateY(0); }
|
||
|
||
.modal-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 24px; }
|
||
.modal-header h3 { font-size: 24px; }
|
||
|
||
.modal-close {
|
||
width: 40px; height: 40px; border-radius: 10px; border: 1px solid var(--border);
|
||
background: var(--bg-card); cursor: pointer; font-size: 20px;
|
||
display: flex; align-items: center; justify-content: center;
|
||
}
|
||
|
||
.form-group { margin-bottom: 20px; }
|
||
.form-group label { display: block; font-size: 14px; font-weight: 600; margin-bottom: 8px; }
|
||
|
||
.form-group input, .form-group select {
|
||
width: 100%; padding: 14px 16px; border-radius: 12px; border: 1px solid var(--border);
|
||
background: var(--bg-card); color: var(--ink); font-size: 16px; outline: none; transition: border-color 0.2s;
|
||
}
|
||
.form-group input:focus, .form-group select:focus { border-color: var(--cyan); }
|
||
.form-error { font-size: 13px; color: var(--error); margin-top: 4px; }
|
||
|
||
/* FAQ */
|
||
.faq-list { max-width: 800px; margin: 0 auto; }
|
||
.faq-item { border-bottom: 1px solid var(--border); }
|
||
|
||
.faq-question {
|
||
width: 100%; padding: 20px 0; background: none; border: none; color: var(--ink);
|
||
font-size: 18px; font-weight: 600; cursor: pointer; display: flex;
|
||
justify-content: space-between; align-items: center; text-align: left;
|
||
}
|
||
.faq-question .icon { font-size: 24px; transition: transform 0.3s; }
|
||
.faq-item.open .faq-question .icon { transform: rotate(45deg); }
|
||
|
||
.faq-answer { max-height: 0; overflow: hidden; transition: max-height 0.3s; }
|
||
.faq-item.open .faq-answer { max-height: 200px; }
|
||
.faq-answer p { padding-bottom: 20px; color: var(--text-secondary); line-height: 1.8; }
|
||
|
||
/* FOOTER */
|
||
.footer { background: var(--gradient-hero); padding: 80px 24px 40px; color: #fff; }
|
||
|
||
.footer-grid { display: grid; grid-template-columns: 2fr 1fr 1fr 1fr; gap: 48px; margin-bottom: 48px; }
|
||
|
||
.footer-brand h3 {
|
||
font-size: 24px; font-weight: 800; margin-bottom: 16px;
|
||
background: var(--gradient-accent); -webkit-background-clip: text; -webkit-text-fill-color: transparent;
|
||
}
|
||
.footer-brand p { color: #9aa3b2; font-size: 14px; line-height: 1.8; }
|
||
|
||
.footer-links h4 { font-size: 16px; font-weight: 700; margin-bottom: 20px; }
|
||
.footer-links a { display: block; color: #9aa3b2; text-decoration: none; font-size: 14px; padding: 6px 0; transition: color 0.2s; cursor: pointer; }
|
||
.footer-links a:hover { color: var(--cyan); }
|
||
|
||
.footer-bottom {
|
||
padding-top: 32px; border-top: 1px solid rgba(255,255,255,0.1);
|
||
display: flex; justify-content: space-between; align-items: center; color: #9aa3b2; font-size: 14px;
|
||
}
|
||
|
||
/* TOAST */
|
||
.toast-container { position: fixed; bottom: 24px; right: 24px; z-index: 3000; display: flex; flex-direction: column; gap: 8px; }
|
||
|
||
.toast {
|
||
padding: 16px 24px; background: var(--bg); border: 1px solid var(--border);
|
||
border-radius: 12px; box-shadow: var(--shadow-lg); display: flex; align-items: center;
|
||
gap: 12px; animation: slideIn 0.3s ease; min-width: 300px;
|
||
}
|
||
.toast.success { border-left: 4px solid var(--success); }
|
||
.toast.error { border-left: 4px solid var(--error); }
|
||
.toast.info { border-left: 4px solid var(--cyan); }
|
||
|
||
@keyframes slideIn { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } }
|
||
|
||
/* MOBILE NAV */
|
||
.mobile-menu {
|
||
display: none; position: fixed; top: 70px; left: 0; right: 0;
|
||
background: var(--bg); border-bottom: 1px solid var(--border); padding: 24px; z-index: 999;
|
||
}
|
||
.mobile-menu.active { display: block; }
|
||
.mobile-menu a { display: block; padding: 12px 0; color: var(--ink); text-decoration: none; font-weight: 600; font-size: 18px; }
|
||
|
||
/* PAGES */
|
||
.page { display: none; }
|
||
.page.active { display: block; }
|
||
|
||
/* RESPONSIVE */
|
||
@media (max-width: 1024px) {
|
||
.features-grid, .courses-grid { grid-template-columns: repeat(2, 1fr); }
|
||
.dashboard-grid { grid-template-columns: repeat(2, 1fr); }
|
||
.footer-grid { grid-template-columns: 1fr 1fr; }
|
||
}
|
||
|
||
@media (max-width: 768px) {
|
||
.nav-links { display: none; }
|
||
.hamburger { display: flex; }
|
||
.hero { padding: 120px 20px 60px; }
|
||
.hero h1 { font-size: 36px; }
|
||
.hero-arabic { font-size: 32px; }
|
||
.hero p { font-size: 16px; }
|
||
.hero-stats { flex-direction: column; gap: 24px; }
|
||
.section { padding: 60px 20px; }
|
||
.section-header h2 { font-size: 28px; }
|
||
.features-grid, .courses-grid { grid-template-columns: 1fr; }
|
||
.dashboard-grid { grid-template-columns: 1fr 1fr; }
|
||
.vocab-grid { grid-template-columns: 1fr; }
|
||
.footer-grid { grid-template-columns: 1fr; gap: 32px; }
|
||
.footer-bottom { flex-direction: column; gap: 12px; text-align: center; }
|
||
.quiz-card { padding: 24px; }
|
||
.lesson-content { padding: 24px; }
|
||
.quiz-type-selector { grid-template-columns: 1fr; }
|
||
.quiz-match-container { grid-template-columns: 1fr; }
|
||
}
|
||
|
||
@media (max-width: 480px) {
|
||
.hero h1 { font-size: 28px; }
|
||
.hero-arabic { font-size: 24px; }
|
||
.dashboard-grid { grid-template-columns: 1fr; }
|
||
.hero-actions { flex-direction: column; }
|
||
.hero-actions .btn { width: 100%; }
|
||
}
|
||
|
||
::-webkit-scrollbar { width: 8px; }
|
||
::-webkit-scrollbar-track { background: var(--bg); }
|
||
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 4px; }
|
||
::-webkit-scrollbar-thumb:hover { background: var(--text-secondary); }
|
||
|
||
.fade-in { opacity: 0; transform: translateY(20px); transition: all 0.6s ease; }
|
||
.fade-in.visible { opacity: 1; transform: translateY(0); }
|
||
|
||
/* Daily goal */
|
||
.daily-goal {
|
||
background: var(--bg-card); border-radius: 16px; padding: 24px;
|
||
border: 1px solid var(--border); margin-bottom: 24px;
|
||
}
|
||
.daily-goal-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; }
|
||
.daily-goal-header h4 { font-size: 18px; }
|
||
.daily-goal-progress { height: 12px; background: var(--border); border-radius: 100px; overflow: hidden; }
|
||
.daily-goal-bar { height: 100%; background: var(--gradient-accent); border-radius: 100px; transition: width 0.5s; }
|
||
.daily-goal-text { font-size: 14px; color: var(--text-secondary); margin-top: 8px; }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<!-- NAV -->
|
||
<nav class="nav">
|
||
<div class="nav-inner">
|
||
<span class="nav-logo" onclick="showPage('home')">ArabicVibe</span>
|
||
<ul class="nav-links">
|
||
<li><a onclick="showPage('home')">Главная</a></li>
|
||
<li><a onclick="showPage('vocabulary')">Словарь</a></li>
|
||
<li><a onclick="showPage('lessons')">Уроки</a></li>
|
||
<li><a onclick="showPage('quiz')">Тесты</a></li>
|
||
<li><a onclick="showPage('dashboard')">Прогресс</a></li>
|
||
</ul>
|
||
<div class="nav-actions">
|
||
<button class="theme-toggle" onclick="toggleTheme()" title="Сменить тему">🌙</button>
|
||
<button class="btn btn-sm btn-secondary" onclick="openModal('login')" id="loginBtn">Войти</button>
|
||
<button class="btn btn-sm btn-primary" onclick="openModal('register')" id="registerBtn">Регистрация</button>
|
||
<div id="userMenu" style="display:none">
|
||
<span id="userName" style="font-weight:600;margin-right:12px"></span>
|
||
<button class="btn btn-sm btn-secondary" onclick="logout()">Выйти</button>
|
||
</div>
|
||
<button class="hamburger" onclick="toggleMobile()">
|
||
<span></span><span></span><span></span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</nav>
|
||
|
||
<div class="mobile-menu" id="mobileMenu">
|
||
<a onclick="showPage('home');toggleMobile()">Главная</a>
|
||
<a onclick="showPage('vocabulary');toggleMobile()">Словарь</a>
|
||
<a onclick="showPage('lessons');toggleMobile()">Уроки</a>
|
||
<a onclick="showPage('quiz');toggleMobile()">Тесты</a>
|
||
<a onclick="showPage('dashboard');toggleMobile()">Прогресс</a>
|
||
</div>
|
||
|
||
<!-- HOME PAGE -->
|
||
<div class="page active" id="page-home">
|
||
|
||
<section class="hero">
|
||
<div class="hero-content">
|
||
<div class="hero-badge">✨ Бесплатно • Без ограничений</div>
|
||
<div class="hero-arabic arabic">مرحباً بكم في عالم العربية</div>
|
||
<h1>Изучай <span>арабский</span> легко и быстро</h1>
|
||
<p>Интерактивные уроки, словарь с произношением, тесты и отслеживание прогресса. Начни с нуля и достигни свободного общения.</p>
|
||
<div class="hero-actions">
|
||
<a class="btn btn-primary btn-lg" onclick="showPage('vocabulary')">Начать обучение</a>
|
||
<a class="btn btn-outline btn-lg" onclick="showPage('lessons')">Смотреть уроки</a>
|
||
</div>
|
||
<div class="hero-stats">
|
||
<div class="hero-stat"><h3>200+</h3><p>Словарных слов</p></div>
|
||
<div class="hero-stat"><h3>30+</h3><p>Уроков</p></div>
|
||
<div class="hero-stat"><h3>150+</h3><p>Тестовых вопросов</p></div>
|
||
<div class="hero-stat"><h3>A1–B1</h3><p>Уровни</p></div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="section" id="features">
|
||
<div class="container">
|
||
<div class="section-header fade-in">
|
||
<div class="badge">ВОЗМОЖНОСТИ</div>
|
||
<h2>Всё для эффективного обучения</h2>
|
||
<p>Интерактивный подход к изучению арабского языка</p>
|
||
</div>
|
||
<div class="features-grid">
|
||
<div class="feature-card fade-in"><div class="feature-icon">📚</div><h3>Структурированные курсы</h3><p>Пошаговые программы от начального до среднего уровня с теорией и практикой</p></div>
|
||
<div class="feature-card fade-in"><div class="feature-icon">🗣️</div><h3>Арабский с произношением</h3><p>Каждое слово с транскрипцией и аудио для правильного произношения</p></div>
|
||
<div class="feature-card fade-in"><div class="feature-icon">✅</div><h3>Интерактивные тесты</h3><p>Разнообразные задания: выбор ответа, заполнение пропусков, сопоставление</p></div>
|
||
<div class="feature-card fade-in"><div class="feature-icon">📊</div><h3>Отслеживание прогресса</h3><p>Статистика, достижения и ежедневные цели для мотивации</p></div>
|
||
<div class="feature-card fade-in"><div class="feature-icon">📖</div><h3>Умный словарь</h3><p>Поиск, фильтрация по темам, избранные слова и карточки для запоминания</p></div>
|
||
<div class="feature-card fade-in"><div class="feature-icon">🌙</div><h3>Тёмная и светлая тема</h3><p>Удобный интерфейс для занятий в любое время суток</p></div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="section" id="courses" style="background:var(--bg-card)">
|
||
<div class="container">
|
||
<div class="section-header fade-in">
|
||
<div class="badge">ПРОГРАММА</div>
|
||
<h2>Выбери свой уровень</h2>
|
||
<p>Курсы для начинающих и продолжающих</p>
|
||
</div>
|
||
<div class="courses-grid">
|
||
<div class="course-card fade-in" onclick="showPage('lessons')">
|
||
<div class="course-header">
|
||
<div class="course-level">A1 — Начальный</div>
|
||
<h3>Арабский с нуля</h3>
|
||
<p>Основы алфавита, базовые слова и фразы</p>
|
||
</div>
|
||
<div class="course-body">
|
||
<div class="course-info"><span>📚 10 уроков</span><span>⏱ 15 часов</span></div>
|
||
<ul class="course-topics">
|
||
<li>🔤 Арабский алфавит</li><li>👋 Приветствия и знакомство</li>
|
||
<li>🔢 Числа от 1 до 100</li><li>👨👩👧 Семья и люди</li><li>🏠 Дом и быт</li>
|
||
</ul>
|
||
<div class="course-progress"><div class="course-progress-bar" id="progress-a1" style="width:0%"></div></div>
|
||
<small style="color:var(--text-secondary)">Прогресс: <span id="progress-a1-text">0%</span></small>
|
||
</div>
|
||
</div>
|
||
<div class="course-card fade-in" onclick="showPage('lessons')">
|
||
<div class="course-header">
|
||
<div class="course-level">A2 — Элементарный</div>
|
||
<h3>Повседневный арабский</h3>
|
||
<p>Расширение словарного запаса и грамматика</p>
|
||
</div>
|
||
<div class="course-body">
|
||
<div class="course-info"><span>📚 12 уроков</span><span>⏱ 20 часов</span></div>
|
||
<ul class="course-topics">
|
||
<li>🛒 Покупки и еда</li><li>✈️ Путешествия</li>
|
||
<li>⏰ Время и даты</li><li>💼 Работа и профессии</li><li>🌤 Погода и природа</li>
|
||
</ul>
|
||
<div class="course-progress"><div class="course-progress-bar" id="progress-a2" style="width:0%"></div></div>
|
||
<small style="color:var(--text-secondary)">Прогресс: <span id="progress-a2-text">0%</span></small>
|
||
</div>
|
||
</div>
|
||
<div class="course-card fade-in" onclick="showPage('lessons')">
|
||
<div class="course-header">
|
||
<div class="course-level">B1 — Средний</div>
|
||
<h3>Арабский для общения</h3>
|
||
<p>Свободное общение и понимание текстов</p>
|
||
</div>
|
||
<div class="course-body">
|
||
<div class="course-info"><span>📚 10 уроков</span><span>⏱ 25 часов</span></div>
|
||
<ul class="course-topics">
|
||
<li>📰 Чтение новостей</li><li>🎬 Обсуждение фильмов</li>
|
||
<li>🏥 Здоровье и медицина</li><li>🌍 Культура и традиции</li><li>💼 Деловой арабский</li>
|
||
</ul>
|
||
<div class="course-progress"><div class="course-progress-bar" id="progress-b1" style="width:0%"></div></div>
|
||
<small style="color:var(--text-secondary)">Прогресс: <span id="progress-b1-text">0%</span></small>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="section" id="faq">
|
||
<div class="container">
|
||
<div class="section-header fade-in">
|
||
<div class="badge">ВОПРОСЫ</div>
|
||
<h2>Часто задаваемые вопросы</h2>
|
||
</div>
|
||
<div class="faq-list">
|
||
<div class="faq-item"><button class="faq-question" onclick="toggleFaq(this)">Нужно ли знать арабский для начала?<span class="icon">+</span></button><div class="faq-answer"><p>Нет! Курс A1 начинается с самого нуля — с алфавита и базовых звуков.</p></div></div>
|
||
<div class="faq-item"><button class="faq-question" onclick="toggleFaq(this)">Сколько времени нужно на обучение?<span class="icon">+</span></button><div class="faq-answer"><p>Рекомендуем 15–30 минут в день. Регулярность важнее длительности.</p></div></div>
|
||
<div class="faq-item"><button class="faq-question" onclick="toggleFaq(this)">Это действительно бесплатно?<span class="icon">+</span></button><div class="faq-answer"><p>Да, все уроки, словарь и тесты полностью бесплатны.</p></div></div>
|
||
<div class="faq-item"><button class="faq-question" onclick="toggleFaq(this)">Как сохраняется прогресс?<span class="icon">+</span></button><div class="faq-answer"><p>Прогресс сохраняется локально в браузере. После регистрации данные привязываются к аккаунту.</p></div></div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<footer class="footer">
|
||
<div class="container">
|
||
<div class="footer-grid">
|
||
<div class="footer-brand"><h3>ArabicVibe</h3><p>Бесплатная платформа для изучения арабского языка. Учитесь в своём темпе, отслеживайте прогресс.</p></div>
|
||
<div class="footer-links"><h4>Обучение</h4><a onclick="showPage('lessons')">Уроки</a><a onclick="showPage('vocabulary')">Словарь</a><a onclick="showPage('quiz')">Тесты</a></div>
|
||
<div class="footer-links"><h4>Ресурсы</h4><a href="#faq">FAQ</a><a>Грамматика</a><a>Советы</a></div>
|
||
<div class="footer-links"><h4>Контакты</h4><a>Telegram</a><a>Email</a><a>Обратная связь</a></div>
|
||
</div>
|
||
<div class="footer-bottom"><span>© 2026 ArabicVibe</span><span>Сделано с ❤️</span></div>
|
||
</div>
|
||
</footer>
|
||
|
||
</div>
|
||
|
||
<!-- VOCABULARY PAGE -->
|
||
<div class="page" id="page-vocabulary">
|
||
<section class="section vocab-section" style="padding-top:120px">
|
||
<div class="container">
|
||
<div class="section-header"><div class="badge">СЛОВАРЬ</div><h2>Арабский словарь</h2><p>Ищите слова, добавляйте в избученные и практикуйте произношение</p></div>
|
||
<div class="vocab-controls">
|
||
<input type="text" class="vocab-search" placeholder="Поиск слов..." oninput="filterVocab()">
|
||
<div class="vocab-filters" id="vocabFilters">
|
||
<button class="filter-btn active" onclick="setFilter('all')">Все</button>
|
||
<button class="filter-btn" onclick="setFilter('greetings')">Приветствия</button>
|
||
<button class="filter-btn" onclick="setFilter('numbers')">Числа</button>
|
||
<button class="filter-btn" onclick="setFilter('family')">Семья</button>
|
||
<button class="filter-btn" onclick="setFilter('food')">Еда</button>
|
||
<button class="filter-btn" onclick="setFilter('colors')">Цвета</button>
|
||
<button class="filter-btn" onclick="setFilter('animals')">Животные</button>
|
||
<button class="filter-btn" onclick="setFilter('body')">Тело</button>
|
||
<button class="filter-btn" onclick="setFilter('time')">Время</button>
|
||
<button class="filter-btn" onclick="setFilter('phrases')">Фразы</button>
|
||
</div>
|
||
</div>
|
||
<div class="vocab-grid" id="vocabGrid"></div>
|
||
</div>
|
||
</section>
|
||
</div>
|
||
|
||
<!-- LESSONS PAGE -->
|
||
<div class="page" id="page-lessons">
|
||
<section class="section" style="padding-top:120px">
|
||
<div class="container">
|
||
<div class="section-header"><div class="badge">УРОКИ</div><h2>Уроки арабского языка</h2><p>Изучайте арабский пошагово с теорией и практикой</p></div>
|
||
<div class="lesson-tabs" id="lessonTabs"></div>
|
||
<div class="lesson-content" id="lessonContent"></div>
|
||
</div>
|
||
</section>
|
||
</div>
|
||
|
||
<!-- QUIZ PAGE -->
|
||
<div class="page" id="page-quiz">
|
||
<section class="section" style="padding-top:120px">
|
||
<div class="container">
|
||
<div class="section-header"><div class="badge">ТЕСТЫ</div><h2>Проверь свои знания</h2><p>Разнообразные тесты для закрепления материала</p></div>
|
||
<div id="quizTypeSelector" class="quiz-type-selector">
|
||
<div class="quiz-type-card active" onclick="selectQuizType('choice')"><div class="icon">✅</div><h4>Выбор ответа</h4><p>Выберите правильный вариант</p></div>
|
||
<div class="quiz-type-card" onclick="selectQuizType('input')"><div class="icon">✍️</div><h4>Ввод слова</h4><p>Напишите перевод самостоятельно</p></div>
|
||
<div class="quiz-type-card" onclick="selectQuizType('match')"><div class="icon">🔗</div><h4>Сопоставление</h4><p>Соедините пары слов</p></div>
|
||
<div class="quiz-type-card" onclick="selectQuizType('mixed')"><div class="icon">🎲</div><h4>Смешанный</h4><p>Разные типы вопросов</p></div>
|
||
</div>
|
||
<div class="quiz-container" id="quizContainer"></div>
|
||
</div>
|
||
</section>
|
||
</div>
|
||
|
||
<!-- DASHBOARD PAGE -->
|
||
<div class="page" id="page-dashboard">
|
||
<section class="section" style="padding-top:120px">
|
||
<div class="container">
|
||
<div class="section-header"><div class="badge">ПРОГРЕСС</div><h2>Мой прогресс</h2><p>Отслеживайте свои достижения и статистику</p></div>
|
||
<div id="dailyGoal"></div>
|
||
<div class="dashboard-grid" id="dashboardStats"></div>
|
||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:24px;margin-top:32px">
|
||
<div>
|
||
<h3 style="margin-bottom:16px">📅 Календарь активности</h3>
|
||
<div class="streak-calendar" id="streakCalendar"></div>
|
||
</div>
|
||
<div>
|
||
<h3 style="margin-bottom:16px">🏆 Достижения</h3>
|
||
<div class="achievements-grid" id="achievementsGrid"></div>
|
||
</div>
|
||
</div>
|
||
<div style="margin-top:32px">
|
||
<h3 style="margin-bottom:16px">📝 История тестов</h3>
|
||
<div class="history-list" id="quizHistory"></div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</div>
|
||
|
||
<!-- MODALS -->
|
||
<div class="modal-overlay" id="modal-login">
|
||
<div class="modal">
|
||
<div class="modal-header"><h3>Вход</h3><button class="modal-close" onclick="closeModal('login')">×</button></div>
|
||
<form onsubmit="handleLogin(event)">
|
||
<div class="form-group"><label>Email</label><input type="email" id="login-email" placeholder="your@email.com" required></div>
|
||
<div class="form-group"><label>Пароль</label><input type="password" id="login-password" placeholder="••••••••" required></div>
|
||
<div class="form-error" id="login-error"></div>
|
||
<button type="submit" class="btn btn-primary" style="width:100%">Войти</button>
|
||
<p style="text-align:center;margin-top:16px;font-size:14px;color:var(--text-secondary)">Нет аккаунта? <a style="color:var(--cyan);cursor:pointer" onclick="closeModal('login');openModal('register')">Зарегистрироваться</a></p>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="modal-overlay" id="modal-register">
|
||
<div class="modal">
|
||
<div class="modal-header"><h3>Регистрация</h3><button class="modal-close" onclick="closeModal('register')">×</button></div>
|
||
<form onsubmit="handleRegister(event)">
|
||
<div class="form-group"><label>Имя</label><input type="text" id="reg-name" placeholder="Ваше имя" required></div>
|
||
<div class="form-group"><label>Email</label><input type="email" id="reg-email" placeholder="your@email.com" required></div>
|
||
<div class="form-group"><label>Пароль</label><input type="password" id="reg-password" placeholder="Минимум 6 символов" required minlength="6"></div>
|
||
<div class="form-group"><label>Подтвердите пароль</label><input type="password" id="reg-password2" placeholder="Повторите пароль" required></div>
|
||
<div class="form-error" id="reg-error"></div>
|
||
<button type="submit" class="btn btn-primary" style="width:100%">Создать аккаунт</button>
|
||
<p style="text-align:center;margin-top:16px;font-size:14px;color:var(--text-secondary)">Уже есть аккаунт? <a style="color:var(--cyan);cursor:pointer" onclick="closeModal('register');openModal('login')">Войти</a></p>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="toast-container" id="toastContainer"></div>
|
||
|
||
<script>
|
||
const vocabularyData = [
|
||
{id:1,arabic:"مرحبا",transcription:"marhaba",translation:"Привет",category:"greetings",example:{arabic:"مرحبا، كيف حالك؟",translation:"Привет, как дела?"}},
|
||
{id:2,arabic:"السلام عليكم",transcription:"as-salamu alaykum",translation:"Мир вам",category:"greetings",example:{arabic:"السلام عليكم يا أصدقاء",translation:"Мир вам, друзья"}},
|
||
{id:3,arabic:"صباح الخير",transcription:"sabah al-khayr",translation:"Доброе утро",category:"greetings",example:{arabic:"صباح الخير يا معلم",translation:"Доброе утро, учитель"}},
|
||
{id:4,arabic:"مساء الخير",transcription:"masa al-khayr",translation:"Добрый вечер",category:"greetings",example:{arabic:"مساء الخير يا جيران",translation:"Добрый вечер, соседи"}},
|
||
{id:5,arabic:"مع السلامة",transcription:"ma'a as-salama",translation:"До свидания",category:"greetings",example:{arabic:"مع السلامة أراك غداً",translation:"До свидания, увидимся завтра"}},
|
||
{id:6,arabic:"شكراً",transcription:"shukran",translation:"Спасибо",category:"greetings",example:{arabic:"شكراً جزيلاً لك",translation:"Большое спасибо тебе"}},
|
||
{id:7,arabic:"عفواً",transcription:"afwan",translation:"Пожалуйста",category:"greetings",example:{arabic:"عفواً هل يمكنك مساعدتي؟",translation:"Пожалуйста, поможете мне?"}},
|
||
{id:8,arabic:"أهلاً وسهلاً",transcription:"ahlan wa sahlan",translation:"Добро пожаловать",category:"greetings",example:{arabic:"أهلاً وسهلاً بكم",translation:"Добро пожаловать к нам"}},
|
||
{id:9,arabic:"تصبح على خير",transcription:"tisbah ala khayr",translation:"Спокойной ночи",category:"greetings",example:{arabic:"تصبح على خير يا صديقي",translation:"Спокойной ночи, друг"}},
|
||
{id:10,arabic:"كيف حالك",transcription:"kayf halak",translation:"Как дела?",category:"greetings",example:{arabic:"مرحبا، كيف حالك اليوم؟",translation:"Привет, как дела сегодня?"}},
|
||
{id:11,arabic:"أنا بخير",transcription:"ana bi-khayr",translation:"У меня всё хорошо",category:"greetings",example:{arabic:"كيف حالك؟ أنا بخير شكراً",translation:"Как дела? Всё хорошо, спасибо"}},
|
||
{id:12,arabic:"واحد",transcription:"wahid",translation:"Один",category:"numbers",example:{arabic:"لدي كتاب واحد",translation:"У меня одна книга"}},
|
||
{id:13,arabic:"اثنان",transcription:"ithnan",translation:"Два",category:"numbers",example:{arabic:"عندي اثنان من الأصدقاء",translation:"У меня двое друзей"}},
|
||
{id:14,arabic:"ثلاثة",transcription:"thalatha",translation:"Три",category:"numbers",example:{arabic:"ثلاثة أيام متبقية",translation:"Осталось три дня"}},
|
||
{id:15,arabic:"أربعة",transcription:"arba'a",translation:"Четыре",category:"numbers",example:{arabic:"أربعة فصول في السنة",translation:"Четыре времени года"}},
|
||
{id:16,arabic:"خمسة",transcription:"khamsa",translation:"Пять",category:"numbers",example:{arabic:"خمسة أصابع في اليد",translation:"Пять пальцев на руке"}},
|
||
{id:17,arabic:"ستة",transcription:"sitta",translation:"Шесть",category:"numbers",example:{arabic:"ستة أيام في الأسبوع",translation:"Шесть дней в неделе"}},
|
||
{id:18,arabic:"سبعة",transcription:"sab'a",translation:"Семь",category:"numbers",example:{arabic:"سبعة أيام في الأسبوع",translation:"Семь дней в неделе"}},
|
||
{id:19,arabic:"ثمانية",transcription:"thamaniya",translation:"Восемь",category:"numbers",example:{arabic:"ثمانية ساعات عمل",translation:"Восемь часов работы"}},
|
||
{id:20,arabic:"تسعة",transcription:"tis'a",translation:"Девять",category:"numbers",example:{arabic:"تسعة أشهر",translation:"Девять месяцев"}},
|
||
{id:21,arabic:"عشرة",transcription:"ashara",translation:"Десять",category:"numbers",example:{arabic:"عشرة دقائق فقط",translation:"Всего десять минут"}},
|
||
{id:22,arabic:"عشرون",transcription:"ishrun",translation:"Двадцать",category:"numbers",example:{arabic:"عمري عشرون سنة",translation:"Мне двадцать лет"}},
|
||
{id:23,arabic:"مائة",transcription:"mi'a",translation:"Сто",category:"numbers",example:{arabic:"مائة طالب في المدرسة",translation:"Сто учеников в школе"}},
|
||
{id:24,arabic:"ألف",transcription:"alf",translation:"Тысяча",category:"numbers",example:{arabic:"ألف كتاب في المكتبة",translation:"Тысяча книг в библиотеке"}},
|
||
{id:25,arabic:"أب",transcription:"ab",translation:"Отец",category:"family",example:{arabic:"أبي يعمل مهندساً",translation:"Мой отец работает инженером"}},
|
||
{id:26,arabic:"أم",transcription:"umm",translation:"Мать",category:"family",example:{arabic:"أمي طبيبة",translation:"Моя мать — врач"}},
|
||
{id:27,arabic:"أخ",transcription:"akh",translation:"Брат",category:"family",example:{arabic:"أخي أكبر مني",translation:"Мой брат старше меня"}},
|
||
{id:28,arabic:"أخت",transcription:"ukht",translation:"Сестра",category:"family",example:{arabic:"أختي تدرس في الجامعة",translation:"Моя сестра учится в университете"}},
|
||
{id:29,arabic:"ابن",transcription:"ibn",translation:"Сын",category:"family",example:{arabic:"ابني يحب المدرسة",translation:"Мой сын любит школу"}},
|
||
{id:30,arabic:"ابنة",transcription:"ibna",translation:"Дочь",category:"family",example:{arabic:"ابنتي جميلة",translation:"Моя дочь красивая"}},
|
||
{id:31,arabic:"عائلة",transcription:"a'ila",translation:"Семья",category:"family",example:{arabic:"عائلتي كبيرة",translation:"Моя семья большая"}},
|
||
{id:32,arabic:"جد",transcription:"jadd",translation:"Дедушка",category:"family",example:{arabic:"جدي حكيم",translation:"Мой дедушка мудрый"}},
|
||
{id:33,arabic:"جدة",transcription:"jadda",translation:"Бабушка",category:"family",example:{arabic:"جدتي تطبخ طعاماً لذيذاً",translation:"Моя бабушка готовит вкусную еду"}},
|
||
{id:34,arabic:"عم",transcription:"amm",translation:"Дядя (по отцу)",category:"family",example:{arabic:"عمي يسكن في القاهرة",translation:"Мой дядя живёт в Каире"}},
|
||
{id:35,arabic:"خال",transcription:"khal",translation:"Дядя (по матери)",category:"family",example:{arabic:"خالي طبيب",translation:"Мой дядя — врач"}},
|
||
{id:36,arabic:"ماء",transcription:"ma'",translation:"Вода",category:"food",example:{arabic:"أريد ماءً من فضلك",translation:"Мне воды, пожалуйста"}},
|
||
{id:37,arabic:"خبز",transcription:"khubz",translation:"Хлеб",category:"food",example:{arabic:"الخبز طازج اليوم",translation:"Хлеб сегодня свежий"}},
|
||
{id:38,arabic:"لحم",transcription:"lahm",translation:"Мясо",category:"food",example:{arabic:"لحم الغنم لذيذ",translation:"Баранина вкусная"}},
|
||
{id:39,arabic:"فاكهة",transcription:"fakiha",translation:"Фрукты",category:"food",example:{arabic:"أحب الفاكهة الطازجة",translation:"Я люблю свежие фрукты"}},
|
||
{id:40,arabic:"حليب",transcription:"halib",translation:"Молоко",category:"food",example:{arabic:"حليب البقر صحي",translation:"Коровье молоко полезно"}},
|
||
{id:41,arabic:"تفاح",transcription:"tuffah",translation:"Яблоко",category:"food",example:{arabic:"التفاح أحمر",translation:"Яблоко красное"}},
|
||
{id:42,arabic:"أرز",transcription:"aruzz",translation:"Рис",category:"food",example:{arabic:"الأرز أبيض",translation:"Рис белый"}},
|
||
{id:43,arabic:"دجاج",transcription:"dajaj",translation:"Курица",category:"food",example:{arabic:"الدجاج مشوي",translation:"Курица запечённая"}},
|
||
{id:44,arabi:"سمك",transcription:"samak",translation:"Рыба",category:"food",example:{arabic:"سمك طازج",translation:"Свежая рыба"}},
|
||
{id:45,arabic:"خضار",transcription:"khudar",translation:"Овощи",category:"food",example:{arabic:"الخضار مفيدة للصحة",translation:"Овощи полезны для здоровья"}},
|
||
{id:46,arabic:"شاي",transcription:"shay",translation:"Чай",category:"food",example:{arabic:"أريد كوباً من الشاي",translation:"Мне чашку чая"}},
|
||
{id:47,arabic:"قهوة",transcription:"qahwa",translation:"Кофе",category:"food",example:{arabic:"القهوة العربية لذيذة",translation:"Арабский кофе вкусный"}},
|
||
{id:48,arabic:"سكر",transcription:"sukkar",translation:"Сахар",category:"food",example:{arabic:"أريد سكراً في الشاي",translation:"Мне сахара в чай"}},
|
||
{id:49,arabic:"ملح",transcription:"milh",translation:"Соль",category:"food",example:{arabic:"ضع ملحاً قليلاً",translation:"Добавь немного соли"}},
|
||
{id:50,arabic:"أحمر",transcription:"ahmar",translation:"Красный",category:"colors",example:{arabic:"الوردة حمراء",translation:"Роза красная"}},
|
||
{id:51,arabic:"أزرق",transcription:"azraq",translation:"Синий",category:"colors",example:{arabic:"السماء زرقاء",translation:"Небо синее"}},
|
||
{id:52,arabic:"أخضر",transcription:"akhdar",translation:"Зелёный",category:"colors",example:{arabic:"العشب أخضر",translation:"Трава зелёная"}},
|
||
{id:53,arabic:"أبيض",transcription:"abyad",translation:"Белый",category:"colors",example:{arabic:"الثلج أبيض",translation:"Снег белый"}},
|
||
{id:54,arabic:"أسود",transcription:"aswad",translation:"Чёрный",category:"colors",example:{arabic:"القط أسود",translation:"Кот чёрный"}},
|
||
{id:55,arabic:"أصفر",transcription:"asfar",translation:"Жёлтый",category:"colors",example:{arabic:"الشمس صفراء",translation:"Солнце жёлтое"}},
|
||
{id:56,arabic:"برتقالي",transcription:"burtuqali",translation:"Оранжевый",category:"colors",example:{arabic:"البرتقالة برتقالية",translation:"Апельсин оранжевый"}},
|
||
{id:57,arabic:"بنفسجي",transcription:"banafsaji",translation:"Фиолетовый",category:"colors",example:{arabic:"الزهرة بنفسجية",translation:"Цветок фиолетовый"}},
|
||
{id:58,arabic:"قط",transcription:"qitt",translation:"Кот",category:"animals",example:{arabic:"القط يلعب في الحديقة",translation:"Кот играет в саду"}},
|
||
{id:59,arabic:"كلب",transcription:"kalb",translation:"Собака",category:"animals",example:{arabic:"الكلبوفي",translation:"Собака верная"}},
|
||
{id:60,arabic:"طائر",transcription:"ta'ir",translation:"Птица",category:"animals",example:{arabic:"الطائر يطير في السماء",translation:"Птица летит в небе"}},
|
||
{id:61,arabic:"حصان",transcription:"hisan",translation:"Лошадь",category:"animals",example:{arabic:"الحصان سريع",translation:"Лошадь быстрая"}},
|
||
{id:62,arabic:"سمكة",transcription:"samaka",translation:"Рыба",category:"animals",example:{arabic:"السمكة تسبح في الماء",translation:"Рыба плавает в воде"}},
|
||
{id:63,arabic:"أسد",transcription:"asad",translation:"Лев",category:"animals",example:{arabic:"الأسد ملك الغابة",translation:"Лев — царь зверей"}},
|
||
{id:64,arabic:"جمل",transcription:"jamal",translation:"Верблюд",category:"animals",example:{arabic:"الجمل يعيش في الصحراء",translation:"Верблюд живёт в пустыне"}},
|
||
{id:65,arabic:"خروف",transcription:"kharuf",translation:"Овца",category:"animals",example:{arabic:"الخروف أبيض",translation:"Овца белая"}},
|
||
{id:66,arabic:"بقرة",transcription:"baqara",translation:"Корова",category:"animals",example:{arabic:"البقرة تعطي حليباً",translation:"Корова даёт молоко"}},
|
||
{id:67,arabic:"يد",transcription:"yad",translation:"Рука",category:"body",example:{arabic:"يدي اليمنى",translation:"Моя правая рука"}},
|
||
{id:68,arabic:"رجل",transcription:"rijl",translation:"Нога",category:"body",example:{arabic:"رجل تؤلمني",translation:"Моя нога болит"}},
|
||
{id:69,arabic:"عين",transcription:"ayn",translation:"Глаз",category:"body",example:{arabic:"عيناي زرقاوان",translation:"Мои глаза синие"}},
|
||
{id:70,arabic:"أنف",transcription:"anf",translation:"Нос",category:"body",example:{arabic:"أنفي كبير",translation:"Мой нос большой"}},
|
||
{id:71,arabic:"فم",transcription:"fam",translation:"Рот",category:"body",example:{arabic:"فمي مفتوح",translation:"Мой рот открыт"}},
|
||
{id:72,arabic:"أذن",transcription:"udhun",translation:"Ухо",category:"body",example:{arabic:"أذني تسمع جيداً",translation:"Моё ухо хорошо слышит"}},
|
||
{id:73,arabic:"رأس",transcription:"ra's",translation:"Голова",category:"body",example:{arabic:"رأسي يؤلمني",translation:"Моя голова болит"}},
|
||
{id:74,arabic:"قلب",transcription:"qalb",translation:"Сердце",category:"body",example:{arabic:"قلبي ينبض",translation:"Моё сердце бьётся"}},
|
||
{id:75,arabic:"ظهر",transcription:"zahr",translation:"Спина",category:"body",example:{arabic:"ظهري يألمني",translation:"Моя спина болит"}},
|
||
{id:76,arabic:"بطن",transcription:"batn",translation:"Живот",category:"body",example:{arabic:"بطني فارغ",translation:"Мой живот пустой"}},
|
||
{id:77,arabic:"وقت",transcription:"waqt",translation:"Время",category:"time",example:{arabic:"الوقت يمر بسرعة",translation:"Время летит быстро"}},
|
||
{id:78,arabic:"يوم",transcription:"yawm",translation:"День",category:"time",example:{arabic:"يوم جميل",translation:"Красивый день"}},
|
||
{id:79,arabic:"ليلة",transcription:"layla",translation:"Ночь",category:"time",example:{arabic:"ليلة سعيدة",translation:"Счастливая ночь"}},
|
||
{id:80,arabic:"صباح",transcription:"sabah",translation:"Утро",category:"time",example:{arabic:"صباح مشرق",translation:"Ясное утро"}},
|
||
{id:81,arabic:"مساء",transcription:"masa'",translation:"Вечер",category:"time",example:{arabic:"مساء هادئ",translation:"Тихий вечер"}},
|
||
{id:82,arabic:"ساعة",transcription:"sa'a",translation:"Час",category:"time",example:{arabic:"ساعة واحدة",translation:"Один час"}},
|
||
{id:83,arabic:"دقيقة",transcription:"daqiqа",translation:"Минута",category:"time",example:{arabic:"دقيقة واحدة من فضلك",translation:"Одну минуту, пожалуйста"}},
|
||
{id:84,arabic:"أمس",transcription:"ams",translation:"Вчера",category:"time",example:{arabic:"أمس كنت في السوق",translation:"Вчера я был на рынке"}},
|
||
{id:85,arabic:"اليوم",transcription:"al-yawm",translation:"Сегодня",category:"time",example:{arabic:"اليوم يوم جميل",translation:"Сегодня прекрасный день"}},
|
||
{id:86,arabic:"غداً",transcription:"ghadan",translation:"Завтра",category:"time",example:{arabic:"غداً سأذهب إلى المدرسة",translation:"Завтра я пойду в школу"}},
|
||
{id:87,arabic:"اسبوع",transcription:"usbua'",translation:"Неделя",category:"time",example:{arabic:"اسبوع واحد",translation:"Одна неделя"}},
|
||
{id:88,arabic:"شهر",transcription:"shahr",translation:"Месяц",category:"time",example:{arabic:"شهر يناير",translation:"Январь"}},
|
||
{id:89,arabic:"سنة",transcription:"sana",translation:"Год",category:"time",example:{arabic:"سنة جديدة",translation:"Новый год"}},
|
||
{id:90,arabic:"نعم",transcription:"na'am",translation:"Да",category:"phrases",example:{arabic:"نعم، أنا موافق",translation:"Да, я согласен"}},
|
||
{id:91,arabic:"لا",transcription:"la",translation:"Нет",category:"phrases",example:{arabic:"لا، شكراً",translation:"Нет, спасибо"}},
|
||
{id:92,arabic:"من فضلك",transcription:"min fadlak",translation:"Пожалуйста",category:"phrases",example:{arabic:"من فضلك، أعطني الماء",translation:"Пожалуйста, дай мне воды"}},
|
||
{id:93,arabic:"أين",transcription:"ayna",translation:"Где",category:"phrases",example:{arabic:"أين المكتبة؟",translation:"Где библиотека?"}},
|
||
{id:94,arabic:"كم",transcription:"kam",translation:"Сколько",category:"phrases",example:{arabic:"كم الثمن؟",translation:"Сколько стоит?"}},
|
||
{id:95,arabic:"ماذا",transcription:"madha",translation:"Что",category:"phrases",example:{arabic:"ماذا تفعل؟",translation:"Что ты делаешь?"}},
|
||
{id:96,arabic:"لماذا",transcription:"limadha",translation:"Почему",category:"phrases",example:{arabic:"لماذا تبكي؟",translation:"Почему ты плачешь?"}},
|
||
{id:97,arabic:"متى",transcription:"mata",translation:"Когда",category:"phrases",example:{arabic:"متى تأتي؟",translation:"Когда ты придёшь?"}},
|
||
{id:98,arabic:"كيف",transcription:"kayf",translation:"Как",category:"phrases",example:{arabic:"كيف حالك؟",translation:"Как дела?"}},
|
||
{id:99,arabic:"أنا",transcription:"ana",translation:"Я",category:"phrases",example:{arabic:"أنا طالب",translation:"Я студент"}},
|
||
{id:100,arabic:"أنت",transcription:"anta",translation:"Ты",category:"phrases",example:{arabic:"أنت صديقي",translation:"Ты мой друг"}},
|
||
{id:101,arabic:"هو",transcription:"huwa",translation:"Он",category:"phrases",example:{arabic:"هو معلم",translation:"Он учитель"}},
|
||
{id:102,arabic:"هي",transcription:"hiya",translation:"Она",category:"phrases",example:{arabic:"هي طبيبة",translation:"Она врач"}},
|
||
{id:103,arabic:"نحن",transcription:"nahnu",translation:"Мы",category:"phrases",example:{arabic:"نحن طلاب",translation:"Мы студенты"}},
|
||
{id:104,arabic:"هم",transcription:"hum",translation:"Они",category:"phrases",example:{arabic:"هم أصدقاء",translation:"Они друзья"}},
|
||
];
|
||
|
||
const lessonsData = [
|
||
{id:1,level:"A1",title:"Арабский алфавит",content:`
|
||
<h3>Арабский алфавит (الأبجدية العربية)</h3>
|
||
<div class="lesson-text">
|
||
<p>Арабский алфавит состоит из 28 букв. Пишутся справа налево. Большинство букв соединяются друг с другом.</p>
|
||
<p>В арабском нет прописных и строчных букв. Форма буквы меняется в зависимости от позиции в слове.</p>
|
||
</div>
|
||
<div class="lesson-example"><div class="arabic">أ ب ت ث ج ح خ</div><div class="transcription">alif, ba, ta, tha, jim, ha, kha</div><div class="translation">Первые 7 букв алфавита</div></div>
|
||
<div class="lesson-example"><div class="arabic">د ذ ر ز س ش ص</div><div class="transcription">dal, dhal, ra, zay, sin, shin, sad</div><div class="translation">Буквы, которые не соединяются</div></div>
|
||
<div class="lesson-example"><div class="arabic">ض ط ظ ع غ ف ق</div><div class="transcription">dad, ta, za, ayn, ghayn, fa, qaf</div><div class="translation">Следующие 7 букв</div></div>
|
||
<div class="lesson-example"><div class="arabic">ك ل م ن ه و ي</div><div class="transcription">kaf, lam, mim, nun, ha, waw, ya</div><div class="translation">Последние 7 букв</div></div>
|
||
<div class="lesson-exercise"><h4>✏️ Упражнение</h4><p>Введите букву «ba» на арабском:</p><input class="exercise-input" id="ex1" placeholder="Введите букву..."><button class="btn btn-primary btn-sm" onclick="checkExercise(1,'ب')">Проверить</button><div class="exercise-feedback" id="ex1-feedback"></div></div>
|
||
<div style="margin-top:32px;display:flex;gap:12px"><button class="btn btn-primary" onclick="completeLesson(1)">✅ Урок пройден</button><button class="btn btn-secondary" onclick="showPage('quiz')">Перейти к тесту</button></div>
|
||
`},
|
||
{id:2,level:"A1",title:"Приветствия",content:`
|
||
<h3>Приветствия и знакомство (التحيات والتعارف)</h3>
|
||
<div class="lesson-text"><p>Арабские приветствия отражают культуру гостеприимства и уважения.</p></div>
|
||
<div class="lesson-example"><div class="arabic">السلام عليكم</div><div class="transcription">as-salamu alaykum</div><div class="translation">Мир вам (формальное приветствие)</div></div>
|
||
<div class="lesson-example"><div class="arabic">مرحباً</div><div class="transcription">marhaba</div><div class="translation">Привет (неформальное)</div></div>
|
||
<div class="lesson-example"><div class="arabic">كيف حالك؟</div><div class="transcription">kayf halak?</div><div class="translation">Как дела?</div></div>
|
||
<div class="lesson-example"><div class="arabic">أنا بخير، شكراً</div><div class="transcription">ana bi-khayr, shukran</div><div class="translation">У меня всё хорошо, спасибо</div></div>
|
||
<div class="lesson-exercise"><h4>✏️ Упражнение</h4><p>Как будет «Спасибо» на арабском?</p><input class="exercise-input" id="ex2" placeholder="Введите слово..."><button class="btn btn-primary btn-sm" onclick="checkExercise(2,'شكراً')">Проверить</button><div class="exercise-feedback" id="ex2-feedback"></div></div>
|
||
<div style="margin-top:32px;display:flex;gap:12px"><button class="btn btn-primary" onclick="completeLesson(2)">✅ Урок пройден</button><button class="btn btn-secondary" onclick="showPage('quiz')">Перейти к тесту</button></div>
|
||
`},
|
||
{id:3,level:"A1",title:"Числа",content:`
|
||
<h3>Числа от 1 до 100 (الأعداد)</h3>
|
||
<div class="lesson-text"><p>Арабские числа используются повсеместно. Важно запомнить основные числа.</p></div>
|
||
<div class="lesson-example"><div class="arabic">١ واحد ٢ اثنان ٣ ثلاثة ٤ أربعة ٥ خمسة</div><div class="transcription">wahid, ithnan, thalatha, arba'a, khamsa</div><div class="translation">1, 2, 3, 4, 5</div></div>
|
||
<div class="lesson-example"><div class="arabic">٦ ستة ٧ سبعة ٨ ثمانية ٩ تسعة ١٠ عشرة</div><div class="transcription">sitta, sab'a, thamaniya, tis'a, ashara</div><div class="translation">6, 7, 8, 9, 10</div></div>
|
||
<div class="lesson-example"><div class="arabic">٢٠ عشرون ٣٠ ثلاثون ١٠٠ مائة</div><div class="transcription">ishrun, thalathun, mi'a</div><div class="translation">20, 30, 100</div></div>
|
||
<div class="lesson-exercise"><h4>✏️ Упражнение</h4><p>Как будет число 5 на арабском?</p><input class="exercise-input" id="ex3" placeholder="Введите число..."><button class="btn btn-primary btn-sm" onclick="checkExercise(3,'خمسة')">Проверить</button><div class="exercise-feedback" id="ex3-feedback"></div></div>
|
||
<div style="margin-top:32px;display:flex;gap:12px"><button class="btn btn-primary" onclick="completeLesson(3)">✅ Урок пройден</button><button class="btn btn-secondary" onclick="showPage('quiz')">Перейти к тесту</button></div>
|
||
`},
|
||
{id:4,level:"A1",title:"Семья",content:`
|
||
<h3>Семья и люди (العائلة والناس)</h3>
|
||
<div class="lesson-text"><p>Семья — важнейшая ценность в арабской культуре.</p></div>
|
||
<div class="lesson-example"><div class="arabic">أب / أم</div><div class="transcription">ab / umm</div><div class="translation">Отец / Мать</div></div>
|
||
<div class="lesson-example"><div class="arabic">ابن / ابنة</div><div class="transcription">ibn / ibna</div><div class="translation">Сын / Дочь</div></div>
|
||
<div class="lesson-example"><div class="arabic">أخ / أخت</div><div class="transcription">akh / ukht</div><div class="translation">Брат / Сестра</div></div>
|
||
<div class="lesson-example"><div class="arabic">عائلة</div><div class="transcription">a'ila</div><div class="translation">Семья</div></div>
|
||
<div class="lesson-exercise"><h4>✏️ Упражнение</h4><p>Как будет «Мать» на арабском?</p><input class="exercise-input" id="ex4" placeholder="Введите слово..."><button class="btn btn-primary btn-sm" onclick="checkExercise(4,'أم')">Проверить</button><div class="exercise-feedback" id="ex4-feedback"></div></div>
|
||
<div style="margin-top:32px;display:flex;gap:12px"><button class="btn btn-primary" onclick="completeLesson(4)">✅ Урок пройден</button><button class="btn btn-secondary" onclick="showPage('quiz')">Перейти к тесту</button></div>
|
||
`},
|
||
{id:5,level:"A1",title:"Еда и напитки",content:`
|
||
<h3>Еда и напитки (الطعام والشراب)</h3>
|
||
<div class="lesson-text"><p>Изучим названия основных продуктов питания и напитков.</p></div>
|
||
<div class="lesson-example"><div class="arabic">ماء / شاي / قهوة</div><div class="transcription">ma' / shay / qahwa</div><div class="translation">Вода / Чай / Кофе</div></div>
|
||
<div class="lesson-example"><div class="arabic">خبز / لحم / دجاج / سمك</div><div class="transcription">khubz / lahm / dajaj / samak</div><div class="translation">Хлеб / Мясо / Курица / Рыба</div></div>
|
||
<div class="lesson-example"><div class="arabic">تفاح / أرز / خضار</div><div class="transcription">tuffah / aruzz / khudar</div><div class="translation">Яблоко / Рис / Овощи</div></div>
|
||
<div class="lesson-exercise"><h4>✏️ Упражнение</h4><p>Как будет «Вода» на арабском?</p><input class="exercise-input" id="ex5" placeholder="Введите слово..."><button class="btn btn-primary btn-sm" onclick="checkExercise(5,'ماء')">Проверить</button><div class="exercise-feedback" id="ex5-feedback"></div></div>
|
||
<div style="margin-top:32px;display:flex;gap:12px"><button class="btn btn-primary" onclick="completeLesson(5)">✅ Урок пройден</button><button class="btn btn-secondary" onclick="showPage('quiz')">Перейти к тесту</button></div>
|
||
`},
|
||
{id:6,level:"A2",title:"Покупки",content:`
|
||
<h3>Покупки и еда (التسوق والطعام)</h3>
|
||
<div class="lesson-text"><p>Давайте научимся делать покупки и заказывать еду.</p></div>
|
||
<div class="lesson-example"><div class="arabic">كم الثمن؟</div><div class="transcription">kam ath-thaman?</div><div class="translation">Сколько стоит?</div></div>
|
||
<div class="lesson-example"><div class="arabic">أريد هذا</div><div class="transcription">uridu hadha</div><div class="translation">Я хочу это</div></div>
|
||
<div class="lesson-example"><div class="arabic">الفاتورة من فضلك</div><div class="transcription">al-fatura min fadlak</div><div class="translation">Счёт, пожалуйста</div></div>
|
||
<div style="margin-top:32px;display:flex;gap:12px"><button class="btn btn-primary" onclick="completeLesson(6)">✅ Урок пройден</button><button class="btn btn-secondary" onclick="showPage('quiz')">Перейти к тесту</button></div>
|
||
`},
|
||
{id:7,level:"A2",title:"Путешествия",content:`
|
||
<h3>Путешествия (السفر)</h3>
|
||
<div class="lesson-text"><p>Полезные фразы для путешествий по арабоговорящим странам.</p></div>
|
||
<div class="lesson-example"><div class="arabic">أين المطار؟</div><div class="transcription">ayna al-matar?</div><div class="translation">Где аэропорт?</div></div>
|
||
<div class="lesson-example"><div class="arabic">أريد غرفة</div><div class="transcription">uridu ghurfa</div><div class="translation">Мне нужен номер</div></div>
|
||
<div class="lesson-example"><div class="arabic">أين محطة القطار؟</div><div class="transcription">ayna mahattat al-qitar?</div><div class="translation">Где вокзал?</div></div>
|
||
<div style="margin-top:32px;display:flex;gap:12px"><button class="btn btn-primary" onclick="completeLesson(7)">✅ Урок пройден</button><button class="btn btn-secondary" onclick="showPage('quiz')">Перейти к тесту</button></div>
|
||
`},
|
||
{id:8,level:"A2",title:"Время и даты",content:`
|
||
<h3>Время и даты (الزمن والتواريخ)</h3>
|
||
<div class="lesson-text"><p>Научимся говорить о времени и датах на арабском.</p></div>
|
||
<div class="lesson-example"><div class="arabic">الساعة كم؟</div><div class="transcription">as-sa'a kam?</div><div class="translation">Который час?</div></div>
|
||
<div class="lesson-example"><div class="arabic">الساعة الثالثة</div><div class="transcription">as-sa'a ath-thalitha</div><div class="translation">Три часа</div></div>
|
||
<div class="lesson-example"><div class="arabic">اليوم الأحد</div><div class="transcription">al-yawm al-ahad</div><div class="translation">Сегодня воскресенье</div></div>
|
||
<div style="margin-top:32px;display:flex;gap:12px"><button class="btn btn-primary" onclick="completeLesson(8)">✅ Урок пройден</button><button class="btn btn-secondary" onclick="showPage('quiz')">Перейти к тесту</button></div>
|
||
`},
|
||
{id:9,level:"B1",title:"Здоровье",content:`
|
||
<h3>Здоровье и медицина (الصحة والطب)</h3>
|
||
<div class="lesson-text"><p>Слова и фразы для обсуждения здоровья.</p></div>
|
||
<div class="lesson-example"><div class="arabic">أنا مريض</div><div class="transcription">ana marid</div><div class="translation">Я болен</div></div>
|
||
<div class="lesson-example"><div class="arabic">أحتاج إلى طبيب</div><div class="transcription">ahtaj ila tabib</div><div class="translation">Мне нужен врач</div></div>
|
||
<div class="lesson-example"><div class="arabic">أين المستشفى؟</div><div class="transcription">ayna al-mustashfa?</div><div class="translation">Где больница?</div></div>
|
||
<div style="margin-top:32px;display:flex;gap:12px"><button class="btn btn-primary" onclick="completeLesson(9)">✅ Урок пройден</button><button class="btn btn-secondary" onclick="showPage('quiz')">Перейти к тесту</button></div>
|
||
`},
|
||
{id:10,level:"B1",title:"Культура",content:`
|
||
<h3>Культура и традиции (الثقافة والتقاليد)</h3>
|
||
<div class="lesson-text"><p>Познакомимся с арабской культурой и традициями.</p></div>
|
||
<div class="lesson-example"><div class="arabic">رمضان كريم</div><div class="transcription">ramadan karim</div><div class="translation">Счастливого Рамадана</div></div>
|
||
<div class="lesson-example"><div class="arabic">عيد مبارك</div><div class="transcription">id mubarak</div><div class="translation">Счастливого праздника</div></div>
|
||
<div class="lesson-example"><div class="arabic">مرحباً بالضيوف</div><div class="transcription">marhaban bi-ḍ-ḍuyuf</div><div class="translation">Добро пожаловать, гости</div></div>
|
||
<div style="margin-top:32px;display:flex;gap:12px"><button class="btn btn-primary" onclick="completeLesson(10)">✅ Урок пройден</button><button class="btn btn-secondary" onclick="showPage('quiz')">Перейти к тесту</button></div>
|
||
`}
|
||
];
|
||
|
||
const quizQuestionsChoice = [
|
||
{question:"Как будет «Привет» на арабском?",options:["مرحبا","شكراً","مع السلامة","صباح الخير"],correct:0},
|
||
{question:"Как переводится شكراً?",options:["Пожалуйста","Спасибо","Привет","До свидания"],correct:1},
|
||
{question:"Число 3 на арабском:",options:["اثنان","أربعة","ثلاثة","خمسة"],correct:2},
|
||
{question:"Как будет «Отец»?",options:["أم","أخ","أب","ابن"],correct:2},
|
||
{question:"Что означает ماء?",options:["Молоко","Вода","Хлеб","Чай"],correct:1},
|
||
{question:"Как будет «Красный»?",options:["أزرق","أخضر","أبيض","أحمر"],correct:3},
|
||
{question:"Как переводится صباح الخير?",options:["Добрый вечер","Доброе утро","Доброй ночи","Спокойной ночи"],correct:1},
|
||
{question:"Число 5 на арабском:",options:["أربعة","ستة","سبعة","خمسة"],correct:3},
|
||
{question:"Как будет «Кот»?",options:["كلب","طائر","قط","حصان"],correct:2},
|
||
{question:"Что означает مع السلامة?",options:["Привет","Спасибо","До свидания","Пожалуйста"],correct:2},
|
||
{question:"Как будет «Белый»?",options:["أسود","أبيض","أحمر","أزرق"],correct:1},
|
||
{question:"Как переводится أخ?",options:["Сестра","Брат","Отец","Мать"],correct:1},
|
||
{question:"Число 10 на арабском:",options:["تسعة","ثمانية","عشرة","سبعة"],correct:2},
|
||
{question:"Как будет «Птица»?",options:["قط","كلب","حصان","طائر"],correct:3},
|
||
{question:"Что означает صباح الخير?",options:["Добрый вечер","Доброе утро","Спокойной ночи","До свидания"],correct:1},
|
||
];
|
||
|
||
const quizQuestionsInput = [
|
||
{question:"Введите «Привет» на арабском:",answer:"مرحبا",hint:"marhaba"},
|
||
{question:"Введите «Спасибо» на арабском:",answer:"شكراً",hint:"shukran"},
|
||
{question:"Введите «Вода» на арабском:",answer:"ماء",hint:"ma'"},
|
||
{question:"Введите «Отец» на арабском:",answer:"أب",hint:"ab"},
|
||
{question:"Введите «Кот» на арабском:",answer:"قط",hint:"qitt"},
|
||
{question:"Введите «Красный» на арабском:",answer:"أحمر",hint:"ahmar"},
|
||
{question:"Введите «Дом» на арабском:",answer:"بيت",hint:"bayt"},
|
||
{question:"Введите «Книга» на арабском:",answer:"كتاب",hint:"kitab"},
|
||
];
|
||
|
||
const quizQuestionsMatch = [
|
||
{pairs:[{left:"مرحبا",right:"Привет"},{left:"شكراً",right:"Спасибо"},{left:"ماء",right:"Вода"},{left:"قط",right:"Кот"},{left:"أحمر",right:"Красный"}]},
|
||
{pairs:[{left:"أب",right:"Отец"},{left:"أم",right:"Мать"},{left:"أخ",right:"Брат"},{left:"أخت",right:"Сестра"},{left:"ابن",right:"Сын"}]},
|
||
{pairs:[{left:"واحد",right:"1"},{left:"اثنان",right:"2"},{left:"ثلاثة",right:"3"},{left:"أربعة",right:"4"},{left:"خمسة",right:"5"}]},
|
||
];
|
||
|
||
const achievementsData = [
|
||
{id:"first-lesson",icon:"📚",title:"Первый урок",desc:"Пройдите первый урок",condition:p=>p.lessonsCompleted>=1},
|
||
{id:"five-lessons",icon:"🎓",title:"Ученик",desc:"Пройдите 5 уроков",condition:p=>p.lessonsCompleted>=5},
|
||
{id:"ten-lessons",icon:"🏆",title:"Отличник",desc:"Пройдите 10 уроков",condition:p=>p.lessonsCompleted>=10},
|
||
{id:"first-quiz",icon:"✅",title:"Тест пройден",desc:"Пройдите первый тест",condition:p=>p.quizzesCompleted>=1},
|
||
{id:"perfect-quiz",icon:"💯",title:"Идеал",desc:"100% в тесте",condition:p=>p.perfectQuizzes>=1},
|
||
{id:"ten-words",icon:"📖",title:"Словарь",desc:"Изучите 10 слов",condition:p=>p.wordsLearned>=10},
|
||
{id:"fifty-words",icon:"📚",title:"Полсотни",desc:"Изучите 50 слов",condition:p=>p.wordsLearned>=50},
|
||
{id:"hundred-words",icon:"🎓",title:"Мастер слов",desc:"Изучите 100 слов",condition:p=>p.wordsLearned>=100},
|
||
{id:"three-streak",icon:"🔥",title:"3 дня подряд",desc:"Занимайтесь 3 дня",condition:p=>p.streak>=3},
|
||
{id:"seven-streak",icon:"⚡",title:"Неделя",desc:"7 дней подряд",condition:p=>p.streak>=7},
|
||
{id:"thirty-streak",icon:"🌟",title:"Месяц",desc:"30 дней подряд",condition:p=>p.streak>=30},
|
||
{id:"five-quizzes",icon:"📝",title:"Эксперт",desc:"Пройдите 5 тестов",condition:p=>p.quizzesCompleted>=5},
|
||
];
|
||
|
||
let currentUser = null;
|
||
let currentFilter = 'all';
|
||
let currentLesson = 0;
|
||
let currentQuizType = 'choice';
|
||
let quizState = {current:0,answers:[],score:0,questions:[]};
|
||
|
||
function getProgress() {
|
||
const def = {lessonsCompleted:0,quizzesCompleted:0,perfectQuizzes:0,wordsLearned:0,streak:0,totalScore:0,lastVisit:null,activeDays:[],favorites:[],quizHistory:[],dailyGoal:5,dailyProgress:0,lastGoalDate:null};
|
||
try {const s=localStorage.getItem('arabic-progress');return s?{...def,...JSON.parse(s)}:def;} catch{return def;}
|
||
}
|
||
|
||
function saveProgress(data) {localStorage.setItem('arabic-progress',JSON.stringify(data));}
|
||
|
||
function updateStreak() {
|
||
const p = getProgress();
|
||
const today = new Date().toISOString().split('T')[0];
|
||
if (p.lastGoalDate !== today) {p.dailyProgress = 0;p.lastGoalDate = today;}
|
||
if (!p.activeDays.includes(today)) {
|
||
p.activeDays.push(today);
|
||
if (p.lastVisit) {
|
||
const last = new Date(p.lastVisit);
|
||
const diff = Math.floor((new Date(today) - last) / 86400000);
|
||
if (diff === 1) {p.streak++;} else if (diff > 1) {p.streak = 1;}
|
||
} else {p.streak = 1;}
|
||
p.lastVisit = today;
|
||
saveProgress(p);
|
||
}
|
||
return p;
|
||
}
|
||
|
||
function getUsers() {try{return JSON.parse(localStorage.getItem('arabic-users')||'[]');}catch{return[];}}
|
||
|
||
function handleLogin(e) {
|
||
e.preventDefault();
|
||
const email = document.getElementById('login-email').value;
|
||
const password = document.getElementById('login-password').value;
|
||
const users = getUsers();
|
||
const user = users.find(u => u.email === email && u.password === btoa(password));
|
||
if (user) {
|
||
currentUser = user;
|
||
localStorage.setItem('arabic-current-user', JSON.stringify(user));
|
||
closeModal('login');
|
||
updateUserUI();
|
||
showToast('Добро пожаловать, ' + user.name + '!', 'success');
|
||
} else {document.getElementById('login-error').textContent = 'Неверный email или пароль';}
|
||
}
|
||
|
||
function handleRegister(e) {
|
||
e.preventDefault();
|
||
const name = document.getElementById('reg-name').value;
|
||
const email = document.getElementById('reg-email').value;
|
||
const password = document.getElementById('reg-password').value;
|
||
const password2 = document.getElementById('reg-password2').value;
|
||
if (password !== password2) {document.getElementById('reg-error').textContent = 'Пароли не совпадают';return;}
|
||
const users = getUsers();
|
||
if (users.find(u => u.email === email)) {document.getElementById('reg-error').textContent = 'Пользователь уже существует';return;}
|
||
const user = {name,email,password:btoa(password),role:'student',createdAt:new Date().toISOString()};
|
||
users.push(user);
|
||
localStorage.setItem('arabic-users', JSON.stringify(users));
|
||
currentUser = user;
|
||
localStorage.setItem('arabic-current-user', JSON.stringify(user));
|
||
closeModal('register');
|
||
updateUserUI();
|
||
showToast('Аккаунт создан!', 'success');
|
||
}
|
||
|
||
function logout() {
|
||
currentUser = null;
|
||
localStorage.removeItem('arabic-current-user');
|
||
updateUserUI();
|
||
showToast('Вы вышли', 'info');
|
||
}
|
||
|
||
function updateUserUI() {
|
||
const loginBtn = document.getElementById('loginBtn');
|
||
const registerBtn = document.getElementById('registerBtn');
|
||
const userMenu = document.getElementById('userMenu');
|
||
const userName = document.getElementById('userName');
|
||
if (currentUser) {
|
||
loginBtn.style.display = 'none';
|
||
registerBtn.style.display = 'none';
|
||
userMenu.style.display = 'flex';
|
||
userMenu.style.alignItems = 'center';
|
||
userName.textContent = currentUser.name;
|
||
} else {
|
||
loginBtn.style.display = '';
|
||
registerBtn.style.display = '';
|
||
userMenu.style.display = 'none';
|
||
}
|
||
}
|
||
|
||
function showPage(page) {
|
||
document.querySelectorAll('.page').forEach(p => p.classList.remove('active'));
|
||
document.getElementById('page-' + page).classList.add('active');
|
||
window.scrollTo(0, 0);
|
||
if (page === 'vocabulary') renderVocab();
|
||
if (page === 'lessons') renderLessons();
|
||
if (page === 'quiz') renderQuiz();
|
||
if (page === 'dashboard') renderDashboard();
|
||
if (page === 'home') updateCourseProgress();
|
||
updateStreak();
|
||
}
|
||
|
||
function toggleMobile() {document.getElementById('mobileMenu').classList.toggle('active');}
|
||
|
||
function toggleTheme() {
|
||
const html = document.documentElement;
|
||
const current = html.getAttribute('data-theme');
|
||
const next = current === 'light' ? 'dark' : 'light';
|
||
html.setAttribute('data-theme', next);
|
||
localStorage.setItem('arabic-theme', next);
|
||
document.querySelector('.theme-toggle').textContent = next === 'dark' ? '☀️' : '🌙';
|
||
}
|
||
|
||
function renderVocab() {
|
||
const search = document.querySelector('.vocab-search').value.toLowerCase();
|
||
const grid = document.getElementById('vocabGrid');
|
||
const progress = getProgress();
|
||
let words = vocabularyData;
|
||
if (currentFilter !== 'all') {words = words.filter(w => w.category === currentFilter);}
|
||
if (search) {words = words.filter(w => w.arabic.includes(search) || w.translation.toLowerCase().includes(search) || w.transcription.toLowerCase().includes(search));}
|
||
grid.innerHTML = words.map(w => `
|
||
<div class="vocab-card">
|
||
<button class="fav-btn ${progress.favorites.includes(w.id)?'active':''}" onclick="toggleFav(${w.id})">${progress.favorites.includes(w.id)?'❤️':'🤍'}</button>
|
||
<div class="category-tag">${getCategoryName(w.category)}</div>
|
||
<div class="arabic-word arabic">${w.arabic}</div>
|
||
<div class="transcription">${w.transcription}</div>
|
||
<div class="translation">${w.translation}</div>
|
||
<div class="example"><div class="arabic">${w.example.arabic}</div><div>${w.example.translation}</div></div>
|
||
<button class="audio-btn" onclick="speak('${w.arabic}')" title="Прослушать">🔊</button>
|
||
</div>
|
||
`).join('');
|
||
}
|
||
|
||
function getCategoryName(cat) {
|
||
const names = {greetings:'Приветствия',numbers:'Числа',family:'Семья',food:'Еда',colors:'Цвета',animals:'Животные',body:'Тело',time:'Время',phrases:'Фразы'};
|
||
return names[cat]||cat;
|
||
}
|
||
|
||
function setFilter(filter) {
|
||
currentFilter = filter;
|
||
document.querySelectorAll('.filter-btn').forEach(b => b.classList.remove('active'));
|
||
event.target.classList.add('active');
|
||
renderVocab();
|
||
}
|
||
|
||
function filterVocab() {renderVocab();}
|
||
|
||
function toggleFav(id) {
|
||
const p = getProgress();
|
||
const idx = p.favorites.indexOf(id);
|
||
if (idx > -1) {p.favorites.splice(idx, 1);}
|
||
else {p.favorites.push(id);p.wordsLearned++;}
|
||
saveProgress(p);
|
||
renderVocab();
|
||
checkAchievements();
|
||
}
|
||
|
||
function speak(text) {
|
||
if ('speechSynthesis' in window) {
|
||
const utterance = new SpeechSynthesisUtterance(text);
|
||
utterance.lang = 'ar-SA';
|
||
utterance.rate = 0.8;
|
||
speechSynthesis.speak(utterance);
|
||
}
|
||
}
|
||
|
||
function renderLessons() {
|
||
const tabs = document.getElementById('lessonTabs');
|
||
const content = document.getElementById('lessonContent');
|
||
tabs.innerHTML = lessonsData.map((l, i) => `<button class="lesson-tab ${i===currentLesson?'active':''}" onclick="selectLesson(${i})">${l.level}: ${l.title}</button>`).join('');
|
||
content.innerHTML = lessonsData[currentLesson].content;
|
||
}
|
||
|
||
function selectLesson(idx) {currentLesson = idx;renderLessons();}
|
||
|
||
function completeLesson(id) {
|
||
const p = getProgress();
|
||
p.lessonsCompleted = Math.min(p.lessonsCompleted + 1, lessonsData.length);
|
||
p.totalScore += 10;
|
||
p.dailyProgress++;
|
||
saveProgress(p);
|
||
checkAchievements();
|
||
showToast('Урок пройден! +10 очков', 'success');
|
||
updateCourseProgress();
|
||
}
|
||
|
||
function checkExercise(num, correct) {
|
||
const input = document.getElementById('ex'+num);
|
||
const feedback = document.getElementById('ex'+num+'-feedback');
|
||
if (input.value.trim() === correct) {
|
||
feedback.className = 'exercise-feedback correct';
|
||
feedback.textContent = '✓ Правильно!';
|
||
const p = getProgress();
|
||
p.totalScore += 5;
|
||
p.dailyProgress++;
|
||
saveProgress(p);
|
||
} else {
|
||
feedback.className = 'exercise-feedback wrong';
|
||
feedback.textContent = '✗ Неверно. Правильный ответ: ' + correct;
|
||
}
|
||
}
|
||
|
||
function updateCourseProgress() {
|
||
const p = getProgress();
|
||
const a1 = Math.min(100, Math.round((p.lessonsCompleted / 5) * 100));
|
||
const a2 = Math.min(100, Math.max(0, Math.round(((p.lessonsCompleted - 5) / 3) * 100)));
|
||
const b1 = Math.min(100, Math.max(0, Math.round(((p.lessonsCompleted - 8) / 2) * 100)));
|
||
document.getElementById('progress-a1').style.width = a1 + '%';
|
||
document.getElementById('progress-a1-text').textContent = a1 + '%';
|
||
document.getElementById('progress-a2').style.width = a2 + '%';
|
||
document.getElementById('progress-a2-text').textContent = a2 + '%';
|
||
document.getElementById('progress-b1').style.width = b1 + '%';
|
||
document.getElementById('progress-b1-text').textContent = b1 + '%';
|
||
}
|
||
|
||
function selectQuizType(type) {
|
||
currentQuizType = type;
|
||
document.querySelectorAll('.quiz-type-card').forEach(c => c.classList.remove('active'));
|
||
event.currentTarget.classList.add('active');
|
||
resetQuiz();
|
||
}
|
||
|
||
function renderQuiz() {
|
||
const container = document.getElementById('quizContainer');
|
||
if (currentQuizType === 'choice' || currentQuizType === 'mixed') {
|
||
renderChoiceQuiz(container);
|
||
} else if (currentQuizType === 'input') {
|
||
renderInputQuiz(container);
|
||
} else if (currentQuizType === 'match') {
|
||
renderMatchQuiz(container);
|
||
}
|
||
}
|
||
|
||
function renderChoiceQuiz(container) {
|
||
if (quizState.questions.length === 0) {
|
||
quizState.questions = currentQuizType === 'mixed' ? shuffleArray([...quizQuestionsChoice]).slice(0,10) : [...quizQuestionsChoice];
|
||
}
|
||
if (quizState.current >= quizState.questions.length) {renderQuizResult();return;}
|
||
const q = quizState.questions[quizState.current];
|
||
const progress = ((quizState.current) / quizState.questions.length) * 100;
|
||
container.innerHTML = `
|
||
<div class="quiz-card">
|
||
<div class="quiz-progress"><div class="quiz-progress-bar"><div class="quiz-progress-fill" style="width:${progress}%"></div></div><div class="quiz-progress-text">${quizState.current+1}/${quizState.questions.length}</div></div>
|
||
<div class="quiz-question">${q.question}</div>
|
||
<div class="quiz-options">${q.options.map((o,i)=>`<button class="quiz-option ${quizState.answers[quizState.current]===i?'selected':''}" onclick="selectAnswer(${i})"><span class="letter">${String.fromCharCode(65+i)}</span>${o}</button>`).join('')}</div>
|
||
<div class="quiz-actions"><button class="btn btn-secondary" onclick="prevQuestion()" ${quizState.current===0?'disabled':''}>Назад</button><button class="btn btn-primary" onclick="nextQuestion()">${quizState.current===quizState.questions.length-1?'Завершить':'Далее'}</button></div>
|
||
</div>`;
|
||
}
|
||
|
||
function renderInputQuiz(container) {
|
||
if (quizState.questions.length === 0) {quizState.questions = [...quizQuestionsInput];}
|
||
if (quizState.current >= quizState.questions.length) {renderQuizResult();return;}
|
||
const q = quizState.questions[quizState.current];
|
||
const progress = ((quizState.current) / quizState.questions.length) * 100;
|
||
container.innerHTML = `
|
||
<div class="quiz-card">
|
||
<div class="quiz-progress"><div class="quiz-progress-bar"><div class="quiz-progress-fill" style="width:${progress}%"></div></div><div class="quiz-progress-text">${quizState.current+1}/${quizState.questions.length}</div></div>
|
||
<div class="quiz-question">${q.question}</div>
|
||
<p style="color:var(--text-secondary);margin-bottom:16px">Подсказка: ${q.hint}</p>
|
||
<input class="quiz-input" id="quizInput" placeholder="Введите на арабском..." value="${quizState.answers[quizState.current]||''}">
|
||
<div class="quiz-actions"><button class="btn btn-secondary" onclick="prevQuestion()">Назад</button><button class="btn btn-primary" onclick="checkInputAnswer()">Проверить и далее</button></div>
|
||
</div>`;
|
||
}
|
||
|
||
function renderMatchQuiz(container) {
|
||
if (quizState.questions.length === 0) {quizState.questions = shuffleArray([...quizQuestionsMatch]).slice(0,1);}
|
||
if (quizState.current >= quizState.questions.length) {renderQuizResult();return;}
|
||
const q = quizState.questions[quizState.current];
|
||
const shuffledRight = shuffleArray([...q.pairs.map((p,i)=>({text:p.right,idx:i}))]);
|
||
container.innerHTML = `
|
||
<div class="quiz-card">
|
||
<div class="quiz-question">Сопоставьте пары слов</div>
|
||
<div class="quiz-match-container" style="margin-top:24px">
|
||
<div>${q.pairs.map((p,i)=>`<div class="quiz-match-item" id="left-${i}" onclick="selectMatch('left',${i})">${p.left}</div>`).join('')}</div>
|
||
<div>${shuffledRight.map((p,i)=>`<div class="quiz-match-item" id="right-${i}" data-idx="${p.idx}" onclick="selectMatch('right',${i})">${p.text}</div>`).join('')}</div>
|
||
</div>
|
||
<div class="quiz-actions"><button class="btn btn-secondary" onclick="resetQuiz()">Заново</button><button class="btn btn-primary" onclick="checkMatch()">Проверить</button></div>
|
||
</div>`;
|
||
window.matchState = {selected:null,pairs:q.pairs,matched:[]};
|
||
}
|
||
|
||
function selectMatch(side, idx) {
|
||
if (!window.matchState) return;
|
||
if (side === 'left') {
|
||
document.querySelectorAll('[id^="left-"]').forEach(el=>el.classList.remove('selected'));
|
||
document.getElementById('left-'+idx).classList.add('selected');
|
||
window.matchState.selected = {side:'left',idx};
|
||
} else if (side === 'right' && window.matchState.selected?.side === 'left') {
|
||
const leftIdx = window.matchState.selected.idx;
|
||
const rightEl = document.getElementById('right-'+idx);
|
||
const rightIdx = parseInt(rightEl.dataset.idx);
|
||
if (leftIdx === rightIdx) {
|
||
document.getElementById('left-'+leftIdx).classList.add('matched');
|
||
rightEl.classList.add('matched');
|
||
window.matchState.matched.push(leftIdx);
|
||
const p = getProgress();p.totalScore+=5;saveProgress(p);
|
||
}
|
||
document.querySelectorAll('[id^="left-"]').forEach(el=>el.classList.remove('selected'));
|
||
window.matchState.selected = null;
|
||
if (window.matchState.matched.length === window.matchState.pairs.length) {
|
||
setTimeout(()=>{
|
||
quizState.current++;
|
||
const p = getProgress();p.totalScore+=10;p.dailyProgress++;saveProgress(p);
|
||
renderQuiz();
|
||
}, 500);
|
||
}
|
||
}
|
||
}
|
||
|
||
function selectAnswer(idx) {quizState.answers[quizState.current]=idx;renderQuiz();}
|
||
|
||
function nextQuestion() {
|
||
if (quizState.answers[quizState.current]===undefined && currentQuizType!=='match'){showToast('Выберите ответ','error');return;}
|
||
quizState.current++;
|
||
renderQuiz();
|
||
}
|
||
|
||
function prevQuestion() {if(quizState.current>0){quizState.current--;renderQuiz();}}
|
||
|
||
function checkInputAnswer() {
|
||
const input = document.getElementById('quizInput');
|
||
const q = quizState.questions[quizState.current];
|
||
quizState.answers[quizState.current] = input.value.trim();
|
||
if (input.value.trim() === q.answer) {
|
||
quizState.score++;
|
||
showToast('Правильно!','success');
|
||
} else {showToast('Ответ: '+q.answer,'info');}
|
||
const p = getProgress();p.totalScore+=quizState.score>0?5:0;p.dailyProgress++;saveProgress(p);
|
||
quizState.current++;
|
||
renderQuiz();
|
||
}
|
||
|
||
function renderQuizResult() {
|
||
const container = document.getElementById('quizContainer');
|
||
let correct = 0;
|
||
if (currentQuizType === 'choice' || currentQuizType === 'mixed') {
|
||
quizState.questions.forEach((q,i)=>{if(quizState.answers[i]===q.correct)correct++;});
|
||
} else if (currentQuizType === 'input') {
|
||
quizState.questions.forEach((q,i)=>{if(quizState.answers[i]===q.answer)correct++;});
|
||
} else {correct = quizState.score;}
|
||
const total = quizState.questions.length;
|
||
const percent = Math.round((correct/total)*100);
|
||
const p = getProgress();
|
||
p.quizzesCompleted++;
|
||
if (percent === 100) p.perfectQuizzes++;
|
||
p.quizHistory.push({date:new Date().toISOString(),score:percent,correct,total,type:currentQuizType});
|
||
saveProgress(p);
|
||
checkAchievements();
|
||
container.innerHTML = `
|
||
<div class="quiz-card"><div class="quiz-result">
|
||
<div class="score-circle"><div class="number">${percent}%</div><div class="label">${correct}/${total}</div></div>
|
||
<h3>${percent>=80?'Отлично!':percent>=50?'Хорошо!':'Попробуйте ещё раз!'}</h3>
|
||
<p>${percent>=80?'Вы отлично знаете материал!':percent>=50?'Неплохо, но есть над чем поработать.':'Рекомендуем повторить уроки.'}</p>
|
||
<div style="display:flex;gap:12px;justify-content:center">
|
||
<button class="btn btn-primary" onclick="resetQuiz()">Пройти ещё раз</button>
|
||
<button class="btn btn-secondary" onclick="showPage('vocabulary')">Перейти к словарю</button>
|
||
</div>
|
||
</div></div>`;
|
||
}
|
||
|
||
function resetQuiz() {quizState={current:0,answers:[],score:0,questions:[]};renderQuiz();}
|
||
|
||
function renderDashboard() {
|
||
const p = updateStreak();
|
||
const stats = document.getElementById('dashboardStats');
|
||
const calendar = document.getElementById('streakCalendar');
|
||
const achievements = document.getElementById('achievementsGrid');
|
||
const history = document.getElementById('quizHistory');
|
||
const dailyGoal = document.getElementById('dailyGoal');
|
||
|
||
dailyGoal.innerHTML = `
|
||
<div class="daily-goal">
|
||
<div class="daily-goal-header"><h4>🎯 Ежедневная цель</h4><span style="font-weight:700;color:var(--accent)">${p.dailyProgress}/${p.dailyGoal}</span></div>
|
||
<div class="daily-goal-progress"><div class="daily-goal-bar" style="width:${Math.min(100,(p.dailyProgress/p.dailyGoal)*100)}%"></div></div>
|
||
<div class="daily-goal-text">${p.dailyProgress>=p.dailyGoal?'Цель достигнута!':'Пройдите ещё '+(p.dailyGoal-p.dailyProgress)+' заданий сегодня'}</div>
|
||
</div>`;
|
||
|
||
stats.innerHTML = `
|
||
<div class="stat-card"><div class="stat-icon">📚</div><div class="stat-value">${p.lessonsCompleted}</div><div class="stat-label">Уроков пройдено</div></div>
|
||
<div class="stat-card"><div class="stat-icon">✅</div><div class="stat-value">${p.quizzesCompleted}</div><div class="stat-label">Тестов сдано</div></div>
|
||
<div class="stat-card"><div class="stat-icon">🔥</div><div class="stat-value">${p.streak}</div><div class="stat-label">Дней подряд</div></div>
|
||
<div class="stat-card"><div class="stat-icon">⭐</div><div class="stat-value">${p.totalScore}</div><div class="stat-label">Баллов набрано</div></div>`;
|
||
|
||
const today = new Date();
|
||
let calHTML = '';
|
||
for (let i=27;i>=0;i--) {
|
||
const date=new Date(today);date.setDate(date.getDate()-i);
|
||
const dateStr=date.toISOString().split('T')[0];
|
||
const isActive=p.activeDays.includes(dateStr);
|
||
const isToday=i===0;
|
||
calHTML+=`<div class="streak-day ${isActive?'active':''} ${isToday?'today':''}" title="${dateStr}"></div>`;
|
||
}
|
||
calendar.innerHTML = calHTML;
|
||
|
||
achievements.innerHTML = achievementsData.map(a=>{
|
||
const unlocked=a.condition(p);
|
||
return `<div class="achievement-card ${unlocked?'':'locked'}"><div class="achievement-icon">${a.icon}</div><h4>${a.title}</h4><p>${a.desc}</p></div>`;
|
||
}).join('');
|
||
|
||
if (p.quizHistory.length>0) {
|
||
history.innerHTML = p.quizHistory.slice(-10).reverse().map(h=>`<div class="history-item"><div><div style="font-weight:600">${h.type==='choice'?'Выбор ответа':h.type==='input'?'Ввод слова':'Сопоставление'}</div><div class="date">${new Date(h.date).toLocaleDateString('ru-RU')}</div></div><div class="score">${h.score}%</div></div>`).join('');
|
||
} else {history.innerHTML='<p style="color:var(--text-secondary)">Пока нет истории тестов</p>';}
|
||
}
|
||
|
||
function checkAchievements() {
|
||
const p = getProgress();
|
||
achievementsData.forEach(a=>{
|
||
if (a.condition(p)){
|
||
const key='achievement-'+a.id;
|
||
if(!localStorage.getItem(key)){localStorage.setItem(key,'1');showToast('🏆 Достижение: '+a.title+'!','success');}
|
||
}
|
||
});
|
||
}
|
||
|
||
function openModal(name) {document.getElementById('modal-'+name).classList.add('active');}
|
||
function closeModal(name) {document.getElementById('modal-'+name).classList.remove('active');}
|
||
|
||
function showToast(message,type='info') {
|
||
const container=document.getElementById('toastContainer');
|
||
const toast=document.createElement('div');
|
||
toast.className='toast '+type;
|
||
toast.innerHTML=`<span>${message}</span>`;
|
||
container.appendChild(toast);
|
||
setTimeout(()=>toast.remove(),3000);
|
||
}
|
||
|
||
function toggleFaq(btn) {btn.parentElement.classList.toggle('open');}
|
||
|
||
function shuffleArray(arr) {
|
||
const a=[...arr];
|
||
for(let i=a.length-1;i>0;i--){const j=Math.floor(Math.random()*(i+1));[a[i],a[j]]=[a[j],a[i]];}
|
||
return a;
|
||
}
|
||
|
||
function init() {
|
||
const theme=localStorage.getItem('arabic-theme')||'light';
|
||
document.documentElement.setAttribute('data-theme',theme);
|
||
document.querySelector('.theme-toggle').textContent=theme==='dark'?'☀️':'🌙';
|
||
const savedUser=localStorage.getItem('arabic-current-user');
|
||
if(savedUser){currentUser=JSON.parse(savedUser);updateUserUI();}
|
||
updateStreak();
|
||
updateCourseProgress();
|
||
const observer=new IntersectionObserver((entries)=>{entries.forEach(entry=>{if(entry.isIntersecting){entry.target.classList.add('visible');}});},{threshold:0.1});
|
||
document.querySelectorAll('.fade-in').forEach(el=>observer.observe(el));
|
||
}
|
||
|
||
document.addEventListener('click',(e)=>{if(e.target.classList.contains('modal-overlay')){e.target.classList.remove('active');}});
|
||
init();
|
||
</script>
|
||
</body>
|
||
</html>
|