2474 lines
75 KiB
HTML
2474 lines
75 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;
|
||
}
|
||
|
||
.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;
|
||
}
|
||
|
||
.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-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-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;
|
||
}
|
||
|
||
/* 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 */
|
||
.achievements-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
||
gap: 16px;
|
||
}
|
||
|
||
.achievement-card {
|
||
background: var(--bg-card);
|
||
border-radius: 16px;
|
||
padding: 24px;
|
||
border: 1px solid var(--border);
|
||
text-align: center;
|
||
transition: all 0.3s;
|
||
}
|
||
|
||
.achievement-card.locked { opacity: 0.5; }
|
||
|
||
.achievement-card .achievement-icon {
|
||
font-size: 48px;
|
||
margin-bottom: 12px;
|
||
}
|
||
|
||
.achievement-card h4 {
|
||
font-size: 16px;
|
||
margin-bottom: 4px;
|
||
}
|
||
|
||
.achievement-card p {
|
||
font-size: 13px;
|
||
color: var(--text-secondary);
|
||
}
|
||
|
||
/* 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;
|
||
}
|
||
|
||
.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; }
|
||
}
|
||
|
||
@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%; }
|
||
}
|
||
|
||
/* SCROLLBAR */
|
||
::-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); }
|
||
|
||
/* ANIMATIONS */
|
||
.fade-in {
|
||
opacity: 0;
|
||
transform: translateY(20px);
|
||
transition: all 0.6s ease;
|
||
}
|
||
|
||
.fade-in.visible {
|
||
opacity: 1;
|
||
transform: translateY(0);
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<!-- NAV -->
|
||
<nav class="nav">
|
||
<div class="nav-inner">
|
||
<a href="#" class="nav-logo" onclick="showPage('home')">ArabicVibe</a>
|
||
<ul class="nav-links">
|
||
<li><a href="#features" onclick="showPage('home')">Возможности</a></li>
|
||
<li><a href="#courses" onclick="showPage('home')">Курсы</a></li>
|
||
<li><a href="#" onclick="showPage('vocabulary')">Словарь</a></li>
|
||
<li><a href="#" onclick="showPage('quiz')">Тесты</a></li>
|
||
<li><a href="#" 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>
|
||
|
||
<!-- MOBILE MENU -->
|
||
<div class="mobile-menu" id="mobileMenu">
|
||
<a href="#features" onclick="showPage('home');toggleMobile()">Возможности</a>
|
||
<a href="#courses" onclick="showPage('home');toggleMobile()">Курсы</a>
|
||
<a href="#" onclick="showPage('vocabulary');toggleMobile()">Словарь</a>
|
||
<a href="#" onclick="showPage('quiz');toggleMobile()">Тесты</a>
|
||
<a href="#" onclick="showPage('dashboard');toggleMobile()">Прогресс</a>
|
||
</div>
|
||
|
||
<!-- HOME PAGE -->
|
||
<div class="page active" id="page-home">
|
||
|
||
<!-- HERO -->
|
||
<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" href="#" onclick="showPage('vocabulary')">Начать обучение</a>
|
||
<a class="btn btn-outline btn-lg" href="#courses">Смотреть курсы</a>
|
||
</div>
|
||
<div class="hero-stats">
|
||
<div class="hero-stat">
|
||
<h3>150+</h3>
|
||
<p>Словарных слов</p>
|
||
</div>
|
||
<div class="hero-stat">
|
||
<h3>30+</h3>
|
||
<p>Уроков</p>
|
||
</div>
|
||
<div class="hero-stat">
|
||
<h3>100+</h3>
|
||
<p>Тестовых вопросов</p>
|
||
</div>
|
||
<div class="hero-stat">
|
||
<h3>A1–B1</h3>
|
||
<p>Уровни</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- FEATURES -->
|
||
<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>
|
||
|
||
<!-- COURSES -->
|
||
<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" style="width:0%" id="progress-a1"></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" style="width:0%" id="progress-a2"></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" style="width:0%" id="progress-b1"></div>
|
||
</div>
|
||
<small style="color:var(--text-secondary)">Прогресс: <span id="progress-b1-text">0%</span></small>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- FAQ -->
|
||
<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 -->
|
||
<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 href="#courses">Курсы</a>
|
||
<a href="#" onclick="showPage('vocabulary')">Словарь</a>
|
||
<a href="#" onclick="showPage('quiz')">Тесты</a>
|
||
<a href="#" onclick="showPage('lessons')">Уроки</a>
|
||
</div>
|
||
<div class="footer-links">
|
||
<h4>Ресурсы</h4>
|
||
<a href="#faq">FAQ</a>
|
||
<a href="#">Блог</a>
|
||
<a href="#">Советы</a>
|
||
<a href="#">Грамматика</a>
|
||
</div>
|
||
<div class="footer-links">
|
||
<h4>Контакты</h4>
|
||
<a href="#">Telegram</a>
|
||
<a href="#">Email</a>
|
||
<a href="#">Обратная связь</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>
|
||
</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 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 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>
|
||
</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 href="#" onclick="closeModal('login');openModal('register')" style="color:var(--cyan)">Зарегистрироваться</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 href="#" onclick="closeModal('register');openModal('login')" style="color:var(--cyan)">Войти</a>
|
||
</p>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- TOASTS -->
|
||
<div class="toast-container" id="toastContainer"></div>
|
||
|
||
<script>
|
||
// ===== DATA =====
|
||
const vocabularyData = [
|
||
// Greetings
|
||
{ 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:"Пожалуйста, можете мне помочь?"}},
|
||
|
||
// Numbers
|
||
{ id:10, arabic:"واحد", transcription:"wahid", translation:"Один", category:"numbers", example:{arabic:"لدي كتاب واحد", translation:"У меня одна книга"}},
|
||
{ id:11, arabic:"اثنان", transcription:"ithnan", translation:"Два", category:"numbers", example:{arabic:"عندي اثنان من الأصدقاء", translation:"У меня двое друзей"}},
|
||
{ id:12, arabic:"ثلاثة", transcription:"thalatha", translation:"Три", category:"numbers", example:{arabic:"ثلاثة أيام متبقية", translation:"Осталось три дня"}},
|
||
{ id:13, arabic:"أربعة", transcription:"arba'a", translation:"Четыре", category:"numbers", example:{arabic:"أربعة فصول في السنة", translation:"Четыре времени года"}},
|
||
{ id:14, arabic:"خمسة", transcription:"khamsa", translation:"Пять", category:"numbers", example:{arabic:"خمسة أصابع في اليد", translation:"Пять пальцев на руке"}},
|
||
{ id:15, arabic:"عشرة", transcription:"ashara", translation:"Десять", category:"numbers", example:{arabic:"عشرة دقائق فقط", translation:"Всего десять минут"}},
|
||
{ id:16, arabic:"مائة", transcription:"mi'a", translation:"Сто", category:"numbers", example:{arabic:"مائة طالب في المدرسة", translation:"Сто учеников в школе"}},
|
||
|
||
// Family
|
||
{ id:20, arabic:"أب", transcription:"ab", translation:"Отец", category:"family", example:{arabic:"أبي يعمل مهندساً", translation:"Мой отец работает инженером"}},
|
||
{ id:21, arabic:"أم", transcription:"umm", translation:"Мать", category:"family", example:{arabic:"أمي طبيبة", translation:"Моя мать — врач"}},
|
||
{ id:22, arabic:"أخ", transcription:"akh", translation:"Брат", category:"family", example:{arabic:"أخي أكبر مني", translation:"Мой брат старше меня"}},
|
||
{ id:23, arabic:"أخت", transcription:"ukht", translation:"Сестра", category:"family", example:{arabic:"أختي تدرس في الجامعة", translation:"Моя сестра учится в университете"}},
|
||
{ id:24, arabic:"ابن", transcription:"ibn", translation:"Сын", category:"family", example:{arabic:"ابني يحب المدرسة", translation:"Мой сын любит школу"}},
|
||
{ id:25, arabic:"ابنة", transcription:"ibna", translation:"Дочь", category:"family", example:{arabic:"ابنتي ترسم很漂亮", translation:"Моя дочь красиво рисует"}},
|
||
|
||
// Food
|
||
{ id:30, arabic:"ماء", transcription:"ma'", translation:"Вода", category:"food", example:{arabic:"أريد ماءً من فضلك", translation:"Мне воды, пожалуйста"}},
|
||
{ id:31, arabic:"خبز", transcription:"khubz", translation:"Хлеб", category:"food", example:{arabic:"الخبز طازج اليوم", translation:"Хлеб сегодня свежий"}},
|
||
{ id:32, arabic:"لحم", transcription:"lahm", translation:"Мясо", category:"food", example:{arabic:"لحم الغنم لذيذ", translation:"Баранина вкусная"}},
|
||
{ id:33, arabic:"فاكهة", transcription:"fakiha", translation:"Фрукты", category:"food", example:{arabic:"أحب الفاكهة الطازجة", translation:"Я люблю свежие фрукты"}},
|
||
{ id:34, arabic:"حليب", transcription:"halib", translation:"Молоко", category:"food", example:{arabic:"حليب البقر صحي", translation:"Коровье молоко полезно"}},
|
||
{ id:35, arabic:"تفاح", transcription:"tuffah", translation:"Яблоко", category:"food", example:{arabic:"التفاح أحمر", translation:"Яблоко красное"}},
|
||
|
||
// Colors
|
||
{ id:40, arabic:"أحمر", transcription:"ahmar", translation:"Красный", category:"colors", example:{arabic:"الوردة حمراء", translation:"Роза красная"}},
|
||
{ id:41, arabic:"أزرق", transcription:"azraq", translation:"Синий", category:"colors", example:{arabic:"السماء زرقاء", translation:"Небо синее"}},
|
||
{ id:42, arabic:"أخضر", transcription:"akhdar", translation:"Зелёный", category:"colors", example:{arabic:"العشب أخضر", translation:"Трава зелёная"}},
|
||
{ id:43, arabic:"أبيض", transcription:"abyad", translation:"Белый", category:"colors", example:{arabic:"الثلج أبيض", translation:"Снег белый"}},
|
||
{ id:44, arabic:"أسود", transcription:"aswad", translation:"Чёрный", category:"colors", example:{arabic:"القط أسود", translation:"Кот чёрный"}},
|
||
|
||
// Animals
|
||
{ id:50, arabic:"قط", transcription:"qitt", translation:"Кот", category:"animals", example:{arabic:"القط يلعب في الحديقة", translation:"Кот играет в саду"}},
|
||
{ id:51, arabic:"كلب", transcription:"kalb", translation:"Собака", category:"animals", example:{arabic:"الكلب وفي", translation:"Собака верная"}},
|
||
{ id:52, arabic:"طائر", transcription:"ta'ir", translation:"Птица", category:"animals", example:{arabic:"الطائر يطير في السماء", translation:"Птица летит в небе"}},
|
||
{ id:53, arabic:"حصان", transcription:"hisan", translation:"Лошадь", category:"animals", example:{arabic:"الحصان سريع", translation:"Лошадь быстрая"}},
|
||
{ id:54, arabic:"سمكة", transcription:"samaka", translation:"Рыба", category:"animals", 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>
|
||
<p style="margin-top:16px;color:var(--text-secondary)">💡 Запомните: буквы ا د ذ ر ز و не соединяются со следующей буквой.</p>
|
||
`
|
||
},
|
||
{
|
||
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? (к мужчине) / kayf halik? (к женщине)</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>
|
||
`
|
||
},
|
||
{
|
||
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>
|
||
<p style="margin-top:16px;color:var(--text-secondary)">💡 Числа 11-19 образуются добавлением عشرة к единице: أحد عشر (11), اثنا عشر (12).</p>
|
||
`
|
||
},
|
||
{
|
||
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>
|
||
`
|
||
},
|
||
{
|
||
id: 5, 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>
|
||
`
|
||
},
|
||
{
|
||
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">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>
|
||
`
|
||
}
|
||
];
|
||
|
||
const quizQuestions = [
|
||
{ 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 },
|
||
];
|
||
|
||
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:"three-streak", icon:"🔥", title:"3 дня подряд", desc:"Занимайтесь 3 дня", condition: p => p.streak >= 3 },
|
||
{ id:"seven-streak", icon:"⚡", title:"Неделя", desc:"7 дней подряд", condition: p => p.streak >= 7 },
|
||
];
|
||
|
||
// ===== STATE =====
|
||
let currentUser = null;
|
||
let currentFilter = 'all';
|
||
let currentLesson = 0;
|
||
let quizState = { current: 0, answers: [], score: 0 };
|
||
|
||
// ===== STORAGE =====
|
||
function getProgress() {
|
||
const def = {
|
||
lessonsCompleted: 0,
|
||
quizzesCompleted: 0,
|
||
perfectQuizzes: 0,
|
||
wordsLearned: 0,
|
||
streak: 0,
|
||
totalScore: 0,
|
||
lastVisit: null,
|
||
activeDays: [],
|
||
favorites: [],
|
||
quizHistory: []
|
||
};
|
||
try {
|
||
const saved = localStorage.getItem('arabic-progress');
|
||
return saved ? { ...def, ...JSON.parse(saved) } : 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.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;
|
||
}
|
||
|
||
// ===== AUTH =====
|
||
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 = 'Пользователь с таким email уже существует';
|
||
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';
|
||
}
|
||
}
|
||
|
||
// ===== NAVIGATION =====
|
||
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');
|
||
}
|
||
|
||
// ===== THEME =====
|
||
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' ? '☀️' : '🌙';
|
||
}
|
||
|
||
// ===== VOCABULARY =====
|
||
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:'Животные' };
|
||
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);
|
||
if (!p.wordsLearned) p.wordsLearned = 0;
|
||
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);
|
||
}
|
||
}
|
||
|
||
// ===== LESSONS =====
|
||
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('');
|
||
|
||
const lesson = lessonsData[currentLesson];
|
||
content.innerHTML = lesson.content + `
|
||
<div style="margin-top:32px;display:flex;gap:12px">
|
||
<button class="btn btn-primary" onclick="completeLesson(${lesson.id})">✅ Урок пройден</button>
|
||
<button class="btn btn-secondary" onclick="showPage('quiz')">Перейти к тесту</button>
|
||
</div>
|
||
`;
|
||
}
|
||
|
||
function selectLesson(idx) {
|
||
currentLesson = idx;
|
||
renderLessons();
|
||
}
|
||
|
||
function completeLesson(id) {
|
||
const p = getProgress();
|
||
p.lessonsCompleted = Math.min(p.lessonsCompleted + 1, lessonsData.length);
|
||
p.totalScore += 10;
|
||
saveProgress(p);
|
||
checkAchievements();
|
||
showToast('Урок пройден! +10 очков', 'success');
|
||
updateCourseProgress();
|
||
}
|
||
|
||
function updateCourseProgress() {
|
||
const p = getProgress();
|
||
const a1 = Math.min(100, Math.round((p.lessonsCompleted / 4) * 100));
|
||
const a2 = Math.min(100, Math.round(((p.lessonsCompleted - 4) / 2) * 100));
|
||
const b1 = Math.min(100, Math.round(((p.lessonsCompleted - 6) / 4) * 100));
|
||
|
||
document.getElementById('progress-a1').style.width = Math.max(0, a1) + '%';
|
||
document.getElementById('progress-a1-text').textContent = Math.max(0, a1) + '%';
|
||
document.getElementById('progress-a2').style.width = Math.max(0, a2) + '%';
|
||
document.getElementById('progress-a2-text').textContent = Math.max(0, a2) + '%';
|
||
document.getElementById('progress-b1').style.width = Math.max(0, b1) + '%';
|
||
document.getElementById('progress-b1-text').textContent = Math.max(0, b1) + '%';
|
||
}
|
||
|
||
// ===== QUIZ =====
|
||
function renderQuiz() {
|
||
const container = document.getElementById('quizContainer');
|
||
|
||
if (quizState.current >= quizQuestions.length) {
|
||
renderQuizResult();
|
||
return;
|
||
}
|
||
|
||
const q = quizQuestions[quizState.current];
|
||
const progress = ((quizState.current) / quizQuestions.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} / ${quizQuestions.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 === quizQuestions.length - 1 ? 'Завершить' : 'Далее'}</button>
|
||
</div>
|
||
</div>
|
||
`;
|
||
}
|
||
|
||
function selectAnswer(idx) {
|
||
quizState.answers[quizState.current] = idx;
|
||
renderQuiz();
|
||
}
|
||
|
||
function nextQuestion() {
|
||
if (quizState.answers[quizState.current] === undefined) {
|
||
showToast('Выберите ответ', 'error');
|
||
return;
|
||
}
|
||
quizState.current++;
|
||
renderQuiz();
|
||
}
|
||
|
||
function prevQuestion() {
|
||
if (quizState.current > 0) {
|
||
quizState.current--;
|
||
renderQuiz();
|
||
}
|
||
}
|
||
|
||
function renderQuizResult() {
|
||
const container = document.getElementById('quizContainer');
|
||
let correct = 0;
|
||
|
||
quizQuestions.forEach((q, i) => {
|
||
if (quizState.answers[i] === q.correct) correct++;
|
||
});
|
||
|
||
const percent = Math.round((correct / quizQuestions.length) * 100);
|
||
|
||
const p = getProgress();
|
||
p.quizzesCompleted++;
|
||
if (percent === 100) p.perfectQuizzes++;
|
||
p.totalScore += correct * 5;
|
||
p.quizHistory.push({ date: new Date().toISOString(), score: percent, correct, total: quizQuestions.length });
|
||
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}/${quizQuestions.length}</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 };
|
||
renderQuiz();
|
||
}
|
||
|
||
// ===== DASHBOARD =====
|
||
function renderDashboard() {
|
||
const p = updateStreak();
|
||
const stats = document.getElementById('dashboardStats');
|
||
const calendar = document.getElementById('streakCalendar');
|
||
const achievements = document.getElementById('achievementsGrid');
|
||
|
||
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>
|
||
`;
|
||
|
||
// Calendar
|
||
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
|
||
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('');
|
||
}
|
||
|
||
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');
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
// ===== MODALS =====
|
||
function openModal(name) {
|
||
document.getElementById('modal-' + name).classList.add('active');
|
||
}
|
||
|
||
function closeModal(name) {
|
||
document.getElementById('modal-' + name).classList.remove('active');
|
||
document.getElementById(name + '-error')?.textContent = '';
|
||
}
|
||
|
||
// ===== TOASTS =====
|
||
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);
|
||
}
|
||
|
||
// ===== FAQ =====
|
||
function toggleFaq(btn) {
|
||
btn.parentElement.classList.toggle('open');
|
||
}
|
||
|
||
// ===== INIT =====
|
||
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();
|
||
|
||
// Intersection Observer for animations
|
||
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>
|