Jaouadart commited on
Commit
3aaa2c9
·
verified ·
1 Parent(s): c304dea

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +705 -267
index.html CHANGED
@@ -104,14 +104,18 @@
104
  pointer-events: none;
105
  background-color: #10b981;
106
  }
107
- .naming-slot {
108
  min-height: 3rem;
109
  }
110
- .naming-letter-button {
111
  cursor: pointer;
112
  user-select: none;
113
  transition: background-color 0.2s, transform 0.1s;
114
  }
 
 
 
 
115
  </style>
116
  </head>
117
  <body class="flex justify-center">
@@ -126,7 +130,6 @@
126
 
127
  <script>
128
  // --- 1. تعريف الأيقونات كـ SVG نصي ---
129
- // (Icons definition remains the same)
130
  const ICONS = {
131
  Home: (cls) => `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="${cls}"><path d="m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>`,
132
  Share2: (cls) => `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="${cls}"><circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/><line x1="8.59" x2="15.42" y1="13.51" y2="17.49"/><line x1="15.41" x2="8.59" y1="6.51" y2="10.49"/></svg>`,
@@ -134,6 +137,7 @@
134
  Settings: (cls) => `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="${cls}"><path d="M12.22 2h-.44a2 2 0 0 0-2 2v.44a2 2 0 0 1-1.11 1.76l-.42.25a2 2 0 0 0-.83 1.57v.88a2 2 0 0 0 1.1 1.8l.42.25a2 2 0 0 1 1.11 1.76v.44a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.44a2 2 0 0 1 1.11-1.76l.42-.25a2 2 0 0 0 .83-1.57v-.88a2 2 0 0 0-1.1-1.8l-.42-.25a2 2 0 0 1-1.11-1.76V4a2 2 0 0 0-2-2z"/><circle cx="12" cy="12" r="3"/></svg>`,
135
  Info: (cls) => `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="${cls}"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/></svg>`,
136
  Menu: (cls) => `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="${cls}"><line x1="4" x2="20" y1="12" y2="12"/><line x1="4" x2="20" y1="6" y2="6"/><line x1="4" x2="20" y1="18" y2="18"/></svg>`,
 
137
  ChevronRight: (cls) => `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="${cls}"><polyline points="9 18 15 12 9 6"/></svg>`,
138
  Mic: (cls) => `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="${cls}"><path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"/><path d="M19 10v2a7 7 0 0 1-14 0v-2"/><line x1="12" x2="12" y1="19" y2="22"/></svg>`,
139
  Volume2: (cls) => `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="${cls}"><polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"/><path d="M19.07 4.93a10 10 0 0 1 0 14.14"/><path d="M15.54 8.46a5 5 0 0 1 0 7.07"/></svg>`,
@@ -152,7 +156,6 @@
152
  Gamepad: (cls) => `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="${cls}"><path d="M12 21a2 2 0 0 1-2-2v-4H8a2 2 0 0 1-2-2v-4a2 2 0 0 1 2-2h4V5a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2h-4v4a2 2 0 0 1-2 2v2a2 2 0 0 1-2 2z"/><path d="M8 11h4V7H8z"/></svg>`,
153
  BookOpen: (cls) => `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="${cls}"><path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"/><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"/></svg>`,
154
  Brain: (cls) => `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="${cls}"><path d="M12 5C6 5 3 7 3 12s3 7 9 7 9-2 9-7-3-7-9-7z"/><path d="M12 5c-3 0-5 2-5 5v2c0 3 2 5 5 5s5-2 5-5V10c0-3-2-5-5-5z"/></svg>`,
155
- Pencil: (cls) => `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="${cls}"><path d="M17 3a2.85 2.85 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z"/><path d="M15 5l4 4"/></svg>`,
156
  Repeat1: (cls) => `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="${cls}"><path d="m19 14-4 4-4-4"/><path d="M15 18H8a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2h12"/><path d="M10 10l4 4 4-4"/></svg>`,
157
  WhatsApp: (cls) => ICONS.Share2(cls),
158
  };
@@ -169,7 +172,7 @@
169
 
170
 
171
  // --- 2. بيانات التطبيق الثابتة ---
172
-
173
  const shuffleArray = (array) => {
174
  const shuffled = [...array];
175
  for (let i = shuffled.length - 1; i > 0; i--) {
@@ -180,145 +183,144 @@
180
  };
181
 
182
  const APP_NAME = "Tifawin";
 
183
  const WHATSAPP_LINK = "https://chat.whatsapp.com/J8bK9L0X4M7P2S1R6Q5T";
184
 
185
- // بيانات الحروف الأساسية (لـ TIFINAGH_LETTERS_BASIC)
 
 
 
 
 
 
 
 
 
 
 
 
 
186
  const tifinaghData = [
187
- { letter: 'ⴰ', word_arabic: 'جدار-ⴰⴳⴰⴷⵉⵔ', image: 'images/2947c16d27f8042f7d60783c6808519a.jpg', audio: 'audio/aman.mp3' },
188
- { letter: 'ⴱ', word_arabic: 'فراشة-ⵉⴱⵔⴱⵉⵍⵍⵓ', image: 'images/3fd6beebd231e2f325469a40b0831b59.jpg', audio: 'audio/barbi.mp3' },
189
- { letter: 'ⴳ', word_arabic: 'دخان-ⴰⴳⴳⵓ', image: 'images/c0094eb5dcc49d7cce573d42f270d8de.jpg', audio: 'audio/ca.mp3' },
190
- { letter: 'ⴷ', word_arabic: 'تمرة-ⵜⵉⵏⵉ', image: 'images/placeholder_date.jpg', audio: 'audio/da.mp3' },
191
- { letter: 'ⴹ', word_arabic: 'قدم-ⴰⴹⴰⵔ', image: 'images/placeholder_foot.jpg', audio: 'audio/dha.mp3' },
192
- { letter: 'ⴼ', word_arabic: 'عين-ⵜⵉⵟ', image: 'images/placeholder_eye.jpg', audio: 'audio/fa.mp3' },
193
- { letter: 'ⵀ', word_arabic: 'فم-ⴰⴽⵓⵎ', image: 'images/placeholder_mouth.jpg', audio: 'audio/ha.mp3' },
194
- { letter: 'ⵃ', word_arabic: 'قلب-ⵓⵍ', image: 'images/placeholder_heart.jpg', audio: 'audio/hha.mp3' },
195
- { letter: 'ⵇ', word_arabic: 'قمح-ⵉⵔⴷⵏ', image: 'images/placeholder_wheat.jpg', audio: 'audio/qa.mp3' },
196
- { letter: 'ⵅ', word_arabic: 'غيمة-ⴰⵙⴰⴼ', image: 'images/placeholder_cloud.jpg', audio: 'audio/kha.mp3' },
197
- { letter: 'ⵉ', word_arabic: 'شمس-ⴰⵢⵢⵓⵔ', image: 'images/placeholder_sun.jpg', audio: 'audio/i.mp3' },
198
- { letter: 'ⵊ', word_arabic: 'جبن-ⴰⵛⵛⴰⵔ', image: 'images/placeholder_cheese.jpg', audio: 'audio/ja.mp3' },
199
- { letter: 'ⴽ', word_arabic: 'صخرة-ⴰⴷⴳⴰⵏ', image: 'images/placeholder_rock.jpg', audio: 'audio/ka.mp3' },
200
- { letter: 'ⵍ', word_arabic: 'عسل-ⵜⴰⵎⵉⵎⵜ', image: 'images/placeholder_honey.jpg', audio: 'audio/la.mp3' },
201
- { letter: 'ⵎ', word_arabic: 'بحر-ⵉⵍⵍ', image: 'images/placeholder_sea.jpg', audio: 'audio/ma.mp3' },
202
- { letter: 'ⵏ', word_arabic: 'وجه-ⴰⵡⴷⴰⵎ', image: 'images/placeholder_face.jpg', audio: 'audio/na.mp3' },
203
- { letter: 'ⵖ', word_arabic: 'طائرة-ⴰⵢⵢⵓⵔ', image: 'images/placeholder_plane.jpg', audio: 'audio/gha.mp3' },
204
  ];
205
 
206
- // ** بيانات تعلم الأمازيغية (تيفيناغ) **
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
207
  const LEARNING_DATA = {
208
  tifinaghLetters: tifinaghData.map(item => {
209
  const parts = item.word_arabic.split('-');
210
- return { main: item.letter, word: parts.length > 1 ? parts[0].trim() : item.word_arabic.trim(), transliteration: parts.length > 1 ? parts[1].trim() : '', imageUrl: item.image, audioUrl: item.audio };
 
 
 
 
 
 
211
  }),
212
- numbers: [
213
- { number: '0', word_tifinagh: 'ⴰⵎⵢⴰ', word_arabic: 'صفر ', image: 'images/d3a43a956f3129b847739dec5f10c81f.jpg', audio: 'audio/zero.mp3' },
214
- { number: '1', word_tifinagh: 'ⵢⴰⵏ', word_arabic: ' واحد', image: 'images/b26681eaa5caacbf1c7bfb112f546def.jpg', audio: 'audio/one.mp3' },
215
- { number: '2', word_tifinagh: 'ⵙⵉⵏ', word_arabic: ' اثنان', image: 'images/placeholder_two.jpg', audio: 'audio/two.mp3' },
216
- { number: '3', word_tifinagh: 'ⴽⵕⴰⴹ', word_arabic: ' ثلاثة', image: 'images/placeholder_three.jpg', audio: 'audio/three.mp3' },
217
- ].map(item => ({ main: item.number, word: item.word_arabic.trim(), transliteration: item.word_tifinagh.trim(), imageUrl: item.image, audioUrl: item.audio })),
 
218
  tools: [{ main: 'ⴰⴽⵕⵕⴰⵊ', word: 'قلم رصاص', imageUrl: 'images/37b71533177feb9d55d55efba947309e.jpg', audioUrl: 'audio/schoolSupplies/pencil.mp3' }],
219
- fruits: [
220
- { main: 'ⵜⴰⴷⴼⴼⵓⵢⵜ', word: 'تفاحة', imageUrl: 'images/da1da4f2015a32322f547ae5fff5236c.jpg', audioUrl: 'audio/fruits/apple.mp3' },
221
- { main: 'ⵜⴰⴱⴰⵏⴰⵏⵜ', word: 'موز', imageUrl: 'images/placeholder_banana.jpg', audioUrl: 'audio/fruits/banana.mp3' },
222
- { main: 'ⴰⵡⵔⵉⵖ', word: 'برتقال', imageUrl: 'images/placeholder_orange.jpg', audioUrl: 'audio/fruits/orange.mp3' },
223
- ],
224
  vegetables: [{ main: 'ⵜⴰⵎⴰⵟⵉⵛⵜ', word: 'طماطم', imageUrl: 'images/6056d9839a962b5a78cddc402ef88c09.jpg', audioUrl: 'audio/vegetables/tomato.mp3' }],
225
- animals: [
226
- { main: 'ⴰⵎⵓⵛⵛ', word: 'قط', imageUrl: 'images/cat.jpeg', audioUrl: 'audio/animaux.ogg' },
227
- { main: 'ⴰⵢⴷⵉ', word: 'كلب', imageUrl: 'images/124419894dcfde81ffbca1e072804c71.jpg', audioUrl: 'audio/dog.mp3' },
228
- { main: 'ⴰⵡⵉ', word: 'أسد', imageUrl: 'images/placeholder_lion.jpg', audioUrl: 'audio/lion.mp3' },
229
- { main: 'ⵉⵖ', word: 'خروف', imageUrl: 'images/placeholder_sheep.jpg', audioUrl: 'audio/sheep.mp3' },
230
- ],
231
  body: [{ main: 'ⵉⵅⴼ', word: 'الرأس', imageUrl: 'images/33dda7fe89cfd5526918246dae320059.jpg', audioUrl: 'audio/bodyParts/head.mp3' }],
 
 
232
  family: [{ main: 'ⵉⵎⵎⵉ', word: 'أمي', imageUrl: 'images/5957c378462b920ceb24f6aa294b5100.jpg', audioUrl: 'audio/family/mother.mp3' }],
233
- // باقي البيانات (colors, days, months, seasons, games, stories) لم تتغير
 
 
 
 
 
 
234
  };
235
-
236
- const TIFINAGH_LETTERS_BASIC = LEARNING_DATA.tifinaghLetters.map(i => i.main);
237
-
238
 
239
  // --- بيانات مستويات الألعاب الجديدة ---
240
 
241
- // بيانات لعبة الذاكرة:
242
- const MEMORY_GAME_BASE_ITEMS = [
243
  ...LEARNING_DATA.animals,
244
  ...LEARNING_DATA.fruits,
245
- // استخدام تيفيناغ الأرقام: ⵢⴰⵏ, ⵙⵉⵏ, ⴽⵕⴰⴹ
246
- ...LEARNING_DATA.numbers.map(n => ({...n, main: n.transliteration || n.main})),
247
  ...LEARNING_DATA.tools,
 
248
  { main: 'ⵉⵎⵉ', word: 'فم', imageUrl: 'images/placeholder_mouth_game.jpg', audioUrl: null },
249
  { main: 'ⴰⴼⵓⵙ', word: 'يد', imageUrl: 'images/placeholder_hand_game.jpg', audioUrl: null },
250
  { main: 'ⴰⵛⵛⴰ', word: 'أكل', imageUrl: 'images/placeholder_eat_game.jpg', audioUrl: null },
251
  { main: 'ⴰⴼⵔⴰ', word: 'طير', imageUrl: 'images/placeholder_bird_game.jpg', audioUrl: null },
252
  { main: '���ⵎⴰⵏ', word: 'ماء', imageUrl: 'images/placeholder_water_game.jpg', audioUrl: null },
253
- ];
254
 
255
  const memoryGameLevels = [
256
- { level: 1, pairs: 3, items: MEMORY_GAME_BASE_ITEMS.slice(0, 3) },
257
- { level: 2, pairs: 4, items: MEMORY_GAME_BASE_ITEMS.slice(0, 4) },
258
- { level: 3, pairs: 5, items: MEMORY_GAME_BASE_ITEMS.slice(0, 5) },
259
- { level: 4, pairs: 6, items: MEMORY_GAME_BASE_ITEMS.slice(0, 6) },
260
- { level: 5, pairs: 8, items: MEMORY_GAME_BASE_ITEMS.slice(0, 8) },
261
- { level: 6, pairs: 10, items: MEMORY_GAME_BASE_ITEMS.slice(0, 10) },
262
- { level: 7, pairs: 12, items: MEMORY_GAME_BASE_ITEMS.slice(0, 12) },
263
- { level: 8, pairs: 14, items: MEMORY_GAME_BASE_ITEMS.slice(0, 14) },
264
- { level: 9, pairs: 15, items: MEMORY_GAME_BASE_ITEMS.slice(0, 15) },
265
- { level: 10, pairs: 16, items: MEMORY_GAME_BASE_ITEMS.slice(0, 16) },
266
  ];
267
 
268
- // بيانات لعبة تسمية الصورة (الجديدة)
269
- const NAMING_GAME_ITEMS_LIST = [
270
- { item: LEARNING_DATA.animals[0] }, // ⴰⵎⵓⵛⵛ
271
- { item: LEARNING_DATA.animals[1] }, // ⴰⵢⴷⵉ
272
- { item: LEARNING_DATA.fruits[0] }, // ⵜⴰⴷⴼⴼⵓⵢⵜ
273
- { item: LEARNING_DATA.vegetables[0] }, // ⵜⴰⵎⴰⵟⵉⵛⵜ
274
- { item: LEARNING_DATA.tools[0] }, // ⴰⴽⵕⵕⴰⵊ
275
- { item: LEARNING_DATA.fruits[1] }, // ⵜⴰⴱⴰⵏⴰⵏⵜ
276
- { item: LEARNING_DATA.animals[2] }, // ⴰⵡⵉ
277
- { item: LEARNING_DATA.fruits[2] }, // ⴰⵡⵔⵉⵖ
278
- { item: LEARNING_DATA.body[0] }, // ⵉⵅⴼ
279
- { item: LEARNING_DATA.family[0] }, // ⵉⵎⵎⵉ
280
- ].map((data, index) => ({...data, id: `name-${index}`}));
281
-
282
- const NAMING_LEVEL_CONFIG = [
283
- { level: 1, itemIndex: 0, availableLettersCount: 5 }, // ⴰⵎⵓⵛⵛ (4 حروف)
284
- { level: 2, itemIndex: 1, availableLettersCount: 5 }, // ⴰⵢⴷⵉ (4 حروف)
285
- { level: 3, itemIndex: 2, availableLettersCount: 7 }, // ⵜⴰⴷⴼⴼⵓⵢⵜ (7 حروف)
286
- { level: 4, itemIndex: 3, availableLettersCount: 8 }, // ⵜⴰⵎⴰⵟⵉⵛⵜ (7 حروف)
287
- { level: 5, itemIndex: 4, availableLettersCount: 9 }, // ⴰⴽⵕⵕⴰⵊ (5 حروف)
288
- { level: 6, itemIndex: 5, availableLettersCount: 9 }, // ⵜⴰⴱⴰⵏⴰⵏⵜ (7 حروف)
289
- { level: 7, itemIndex: 6, availableLettersCount: 7 }, // ⴰⵡⵉ (3 حروف)
290
- { level: 8, itemIndex: 7, availableLettersCount: 8 }, // ⴰⵡⵔⵉⵖ (5 حروف)
291
- { level: 9, itemIndex: 8, availableLettersCount: 7 }, // ⵉⵅⴼ (3 حروف)
292
- { level: 10, itemIndex: 9, availableLettersCount: 9 }, // ⵉⵎⵎⵉ (3 حروف)
293
- ];
294
 
295
- // تهيئة مستويات لعبة التسمية لمرة واحدة عند التحميل
296
- const namingGameLevels = NAMING_LEVEL_CONFIG.map(level => {
297
- const item = NAMING_GAME_ITEMS_LIST[level.itemIndex].item;
298
- // تأكد من إزالة أي مسافات زائدة داخل الكلمة Tifinagh
299
- const correctWord = item.main ? item.main.replace(/\s/g, '') : '';
300
- const correctLetters = correctWord.split('');
301
-
302
- let availableLettersPool = [...correctLetters];
303
-
304
- // إضافة حروف عشوائية لتكملة العدد المطلوب للحيرة
305
- // نأخذ 12 حرف كحد أقصى لعرض مريح
306
- let fillerLetters = shuffleArray(
307
- TIFINAGH_LETTERS_BASIC.filter(l => !correctLetters.includes(l))
308
- ).slice(0, level.availableLettersCount - correctLetters.length);
309
-
310
- availableLettersPool = shuffleArray([...availableLettersPool, ...fillerLetters]).slice(0, 12);
311
-
312
- return {
313
- ...level,
314
- item: item,
315
- correctWord: correctWord,
316
- availableLetters: availableLettersPool,
317
- maxLetters: correctWord.length,
318
- };
319
- });
320
 
321
- // (CATEGORIES data remains the same)
322
  const CATEGORIES = [
323
  { id: 'tifinaghLetters', title: 'تعلم الحروف', subtitle: 'ⴰ, ⴱ, ⴳ...', iconName: 'AArrowUp', imageUrl: 'images/6e318d538a2d8f0b5ad685db558ffe4e.jpg' },
324
  { id: 'numbers', title: 'تعلم الأرقام', subtitle: '0, 1, 2...', iconName: 'Hash', imageUrl: 'images/0751e273c2de27e4b04dfeb7ee99b448.jpg' },
@@ -347,64 +349,82 @@
347
  isDarkMode: false,
348
  isAppMuted: false,
349
  isRecording: false,
350
- currentGameState: null,
 
351
  currentLevel: 1,
352
- gameData: null,
353
  memoryGame: {
354
- flippedCards: [],
355
- matchedCards: [],
356
- lockBoard: false,
357
  },
358
- namingGame: {
359
- userWord: [],
360
- availableLettersPool: [],
361
  }
362
  };
363
 
 
364
  window.setState = (newState) => {
365
- // منطق إعادة تعيين حالة الألعاب عند تغيير الشاشة أو المستوى
366
- if (newState.currentScreen && newState.currentScreen !== appState.currentScreen) {
367
  appState.currentIndex = 0;
368
- appState.currentGameState = null;
369
  appState.currentLevel = 1;
370
  }
 
 
371
  if (newState.currentGameState && newState.currentGameState !== appState.currentGameState) {
372
  appState.currentLevel = 1;
373
- appState.gameData = null;
374
  appState.memoryGame = { flippedCards: [], matchedCards: [], lockBoard: false };
375
- appState.namingGame = { userWord: [], availableLettersPool: [] };
 
376
  }
377
- if (newState.currentLevel && newState.currentLevel !== appState.currentLevel && newState.currentGameState) {
378
- appState.gameData = null;
379
  appState.memoryGame = { flippedCards: [], matchedCards: [], lockBoard: false };
380
- appState.namingGame = { userWord: [], availableLettersPool: [] };
 
381
  }
382
 
383
 
384
  Object.assign(appState, newState);
385
 
 
386
  document.body.classList.toggle('dark', appState.isDarkMode);
387
  document.getElementById('app-container').classList.toggle('dark', appState.isDarkMode);
388
 
389
  renderApp();
390
  };
391
 
 
392
  window.toggleMenu = () => {
393
  setState({ isMenuOpen: !appState.isMenuOpen });
394
  };
395
 
396
- // (renderHeader, renderFooter functions remain the same)
397
- // ...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
398
  const renderHeader = () => {
399
- // ... (Code for renderHeader)
400
  const headerElement = document.getElementById('app-header');
401
  const categoryMeta = CATEGORIES.find(c => c.id === appState.selectedCategory);
402
 
403
  let title = APP_NAME;
404
  if (appState.currentGameState === 'memory') {
405
- title = 'لعبة الذاكرة (الصورة والكلمة)';
406
- } else if (appState.currentGameState === 'naming') {
407
- title = 'لعبة تسمية الصورة';
408
  } else if (categoryMeta && appState.currentScreen !== 'home' && !['settings', 'info', 'appDefinition', 'games'].includes(appState.currentScreen)) {
409
  title = categoryMeta.title;
410
  } else if (appState.currentScreen === 'settings') {
@@ -420,7 +440,7 @@
420
  headerElement.innerHTML = `
421
  <div class="flex items-center justify-between p-4 h-16 bg-blue-800 dark:bg-gray-800 text-white shadow-lg rounded-b-xl transition-colors">
422
  <button onclick="
423
- ${appState.currentGameState ? `setState({currentGameState: null, currentLevel: 1, currentScreen: 'games'})` : `toggleMenu()`}
424
  "
425
  class="p-1 rounded-full hover:bg-white/10 transition-colors" aria-label="العودة / القائمة">
426
  ${appState.currentGameState ? renderIcon('ChevronRight', 'w-6 h-6 text-white') : renderIcon('Menu', 'w-6 h-6 text-white')}
@@ -434,9 +454,9 @@
434
  </div>
435
  `;
436
  };
437
-
438
  const renderFooter = () => {
439
- // ... (Code for renderFooter)
440
  const footerElement = document.getElementById('app-footer');
441
  const navItems = [
442
  { id: 'home', iconName: 'Home', label: 'الرئيسية' },
@@ -478,7 +498,363 @@
478
  </div>
479
  `;
480
  };
481
- // ... (renderGamesHome remains the same)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
482
  const renderGamesHome = () => {
483
  const content = document.getElementById('app-content');
484
 
@@ -486,18 +862,18 @@
486
  {
487
  id: 'memory',
488
  title: 'لعبة الذاكرة',
489
- subtitle: 'طابق الصور والكلمات الأمازيغية',
490
  iconName: 'Brain',
491
  color: 'bg-green-500',
492
  action: `setState({currentGameState: 'memory'})`
493
  },
494
  {
495
- id: 'naming',
496
- title: 'تسمية الصورة (تيفيناغ)',
497
- subtitle: 'اكتب اسم الصورة بالحروف الأمازيغية',
498
- iconName: 'Pencil',
499
  color: 'bg-red-500',
500
- action: `setState({currentGameState: 'naming'})`
501
  },
502
  ];
503
 
@@ -529,11 +905,11 @@
529
  const levelData = memoryGameLevels[appState.currentLevel - 1];
530
  if (!levelData) return alert('انتهت المستويات!');
531
 
 
532
  let cards = [];
533
  levelData.items.forEach(item => {
534
- const itemId = item.main + item.word; // استخدام تركيبة فريدة كـ ID
535
- cards.push({ id: itemId, type: 'image', content: item.imageUrl, alt: item.word });
536
- cards.push({ id: itemId, type: 'word', content: item.main, alt: item.word });
537
  });
538
 
539
  setState({
@@ -559,8 +935,7 @@
559
  const card1 = newGameData[index1];
560
  const card2 = newGameData[index2];
561
 
562
- // التحقق من المطابقة: يجب أن يتطابق ID وأن يكون النوعان مختلفين (صورة وكلمة)
563
- if (card1.id === card2.id && card1.type !== card2.type) {
564
  // Match found
565
  newGameData[index1].isMatched = true;
566
  newGameData[index2].isMatched = true;
@@ -580,7 +955,7 @@
580
  initMemoryGame();
581
  } else {
582
  alert('تهانينا! لقد أنهيت لعبة الذاكرة بنجاح!');
583
- setState({ currentGameState: null, currentScreen: 'games' });
584
  }
585
  }, 800);
586
  }
@@ -605,16 +980,13 @@
605
  const renderMemoryGame = () => {
606
  if (!appState.gameData) {
607
  initMemoryGame();
608
- return;
609
  }
610
 
611
  const content = document.getElementById('app-content');
612
  const levelData = memoryGameLevels[appState.currentLevel - 1];
613
- const totalCards = levelData.pairs * 2;
614
- let cols = 4;
615
- if (totalCards > 16) cols = 5;
616
-
617
- const gridClass = `grid gap-2 w-full max-w-sm mx-auto`;
618
 
619
  content.innerHTML = `
620
  <div class="p-4 pt-6 min-h-[calc(100vh-130px)] bg-gray-50 dark:bg-gray-900 transition-colors">
@@ -622,7 +994,7 @@
622
  لعبة الذاكرة - المستوى ${appState.currentLevel}
623
  </h3>
624
  <p class="text-sm text-gray-600 dark:text-gray-400 mb-4 text-center">
625
- طابق ${levelData.pairs} أزواج: <span class="text-blue-600 font-bold">صورة ↔ كلمة أمازيغية</span>
626
  </p>
627
 
628
  <div class="${gridClass}" style="grid-template-columns: repeat(${cols}, minmax(0, 1fr));">
@@ -634,7 +1006,7 @@
634
  ${card.type === 'image' ? `
635
  <img src="${card.content}" alt="${card.alt}" class="w-full h-full object-cover rounded-md" onerror="this.onerror=null; this.src='https://placehold.co/80x80?text=صورة';"/>
636
  ` : `
637
- <span class="text-3xl font-black text-blue-800 dark:text-white text-center">${card.content}</span>
638
  `}
639
  </div>
640
 
@@ -656,140 +1028,137 @@
656
  `;
657
  };
658
 
659
- // --- 8.2 لعبة تسمية الصورة (Image Naming Game) ---
660
 
661
- window.initNamingGame = () => {
662
- const levelData = namingGameLevels[appState.currentLevel - 1];
663
  if (!levelData) return alert('انتهت المستويات!');
664
 
665
- // إعادة تعيين حالة اللعبة الحالية
666
  setState({
667
  gameData: levelData,
668
- namingGame: {
669
- userWord: Array(levelData.maxLetters).fill(null),
670
- // إعادة تعيين الحروف المتاحة مع إزالة حالة الاستخدام السابقة
671
- availableLettersPool: levelData.availableLetters.map((letter, index) => ({ letter, isUsed: false, poolIndex: index }))
672
  },
673
- currentGameState: 'naming',
674
  currentLevel: levelData.level,
675
  });
676
  };
677
 
678
- window.handleLetterClick = (letterIndex) => {
679
- const state = appState.namingGame;
680
- // يجب أن نستخدم نسخة من المصفوفات لتجنب التعديل المباشر على الحالة
681
- const newPool = [...state.availableLettersPool];
682
- if (newPool[letterIndex].isUsed) return;
683
-
684
- const letter = newPool[letterIndex].letter;
685
 
686
- const newUserWord = [...state.userWord];
687
- const slotIndex = newUserWord.findIndex(l => l === null);
688
- if (slotIndex === -1) return;
689
 
690
- newUserWord[slotIndex] = { letter, poolIndex: letterIndex };
691
- newPool[letterIndex].isUsed = true;
692
-
693
- setState({ namingGame: { userWord: newUserWord, availableLettersPool: newPool } });
 
694
 
695
- if (newUserWord.every(l => l !== null)) {
696
- checkNamingWin(newUserWord.map(item => item.letter).join(''));
697
  }
698
  };
699
 
700
  window.removeLetter = (slotIndex) => {
701
- const state = appState.namingGame;
702
- const letterItem = state.userWord[slotIndex];
703
- if (!letterItem) return;
704
 
705
- const newUserWord = [...state.userWord];
706
- newUserWord[slotIndex] = null;
707
 
708
- const newPool = [...state.availableLettersPool];
709
- // استخدام poolIndex للرجوع للحرف الصحيح
710
- newPool[letterItem.poolIndex].isUsed = false;
711
 
712
- setState({ namingGame: { userWord: newUserWord, availableLettersPool: newPool } });
 
 
713
  };
714
 
715
- window.checkNamingWin = (userWord) => {
716
- const correctWord = appState.gameData.correctWord;
717
- const isCorrect = userWord === correctWord;
718
 
719
  if (isCorrect) {
720
  setTimeout(() => {
721
- if (appState.currentLevel < namingGameLevels.length) {
722
- alert(`إجابة صحيحة! كلمة "${correctWord}" تعني "${appState.gameData.item.word.trim()}". المستوى ${appState.currentLevel} مكتمل.`);
723
  setState({ currentLevel: appState.currentLevel + 1 });
724
- initNamingGame();
725
  } else {
726
- alert('تهانينا! لقد أتقنت تسمية جميع الصور بنجاح!');
727
- setState({ currentGameState: null, currentScreen: 'games' });
728
  }
729
  }, 500);
730
  } else {
731
- alert('خطأ! حاول ترتيب الحروف بشكل صحيح لتكوين الكلمة الأمازيغية.');
732
  }
733
  };
734
 
735
 
736
- const renderNamingGame = () => {
737
  if (!appState.gameData) {
738
- initNamingGame();
739
  return;
740
  }
741
 
742
  const content = document.getElementById('app-content');
743
  const levelData = appState.gameData;
744
- const state = appState.namingGame;
745
-
746
- // تحديد عدد الأعمدة للوحة المفاتيح
747
- const keyCols = state.availableLettersPool.length > 8 ? 6 : 4;
748
- const keyGridClass = `grid grid-cols-${keyCols} gap-2 mb-8 max-w-sm mx-auto`;
749
 
 
 
 
750
  content.innerHTML = `
751
  <div class="p-4 pt-6 min-h-[calc(100vh-130px)] bg-gray-50 dark:bg-gray-900 transition-colors">
752
  <h3 class="text-2xl font-black text-gray-800 dark:text-white mb-2 text-center">
753
- تسمية الصورة - المستوى ${appState.currentLevel}
754
  </h3>
755
  <p class="text-sm text-gray-600 dark:text-gray-400 mb-4 text-center">
756
- اكتب الاسم الأمازيغي للصورة باستخدام الحروف المتاحة. الكلمة من ${levelData.maxLetters} حروف.
757
  </p>
758
 
759
- <div class="w-40 h-40 mx-auto rounded-xl shadow-2xl overflow-hidden mb-6 border-4 border-blue-500/50 dark:border-blue-300/50">
760
- <img src="${levelData.item.imageUrl}" alt="${levelData.item.word}" class="w-full h-full object-cover" onerror="this.onerror=null; this.src='https://placehold.co/160x160?text=صورة';"/>
 
 
 
761
  </div>
762
-
763
- <h4 class="text-lg font-bold text-gray-700 dark:text-gray-300 mb-2 text-center">اكتب الكلمة:</h4>
764
- <div class="flex justify-center flex-wrap gap-1.5 mb-8 max-w-sm mx-auto">
765
- ${state.userWord.map((item, index) => `
 
766
  <button onclick="removeLetter(${index})"
767
- class="naming-slot w-10 h-10 flex items-center justify-center border-2 ${item ? 'border-green-500 bg-green-100 dark:bg-green-900/50' : 'border-dashed border-gray-400 dark:border-gray-600 bg-white dark:bg-gray-700/50'} rounded-lg transition-all"
768
- aria-label="خانة الحرف رقم ${index + 1}">
769
- <span class="text-2xl font-black ${item ? 'text-green-800 dark:text-white' : 'text-transparent'}">${item ? item.letter : ''}</span>
770
  </button>
771
  `).join('')}
772
  </div>
773
 
774
  <h4 class="text-lg font-bold text-gray-700 dark:text-gray-300 mt-6 mb-2 text-center">الحروف المتاحة:</h4>
775
- <div class="${keyGridClass}">
776
- ${state.availableLettersPool.map((item, index) => `
777
- <button onclick="handleLetterClick(${index})"
778
- class="naming-letter-button w-full h-10 flex items-center justify-center bg-purple-500 text-white text-xl font-black rounded-lg shadow-md transition-all ${item.isUsed ? 'opacity-30 pointer-events-none' : 'hover:bg-purple-600'}"
779
- aria-label="الحرف ${item.letter}"
780
- ${item.isUsed ? 'disabled' : ''}>
781
- ${item.letter}
 
 
782
  </button>
783
  `).join('')}
784
  </div>
785
 
786
  <div class="mt-8 text-center">
787
- <button onclick="checkNamingWin(appState.namingGame.userWord.map(item => item ? item.letter : '').join(''))"
788
  class="px-6 py-3 bg-blue-600 text-white font-bold rounded-xl shadow-lg hover:bg-blue-700 disabled:opacity-50"
789
- ${state.userWord.some(l => l === null) ? 'disabled' : ''}>
790
- تحقق من الإجابة
791
  </button>
792
- <button onclick="initNamingGame()"
793
  class="px-4 py-2 bg-yellow-500 text-white font-bold rounded-xl shadow-lg hover:bg-yellow-600 mr-2">
794
  إعادة المستوى
795
  </button>
@@ -797,15 +1166,17 @@
797
  </div>
798
  `;
799
  };
 
800
 
801
- // (renderApp and window.onload functions remain the same)
 
802
  const renderApp = () => {
803
- // ... (Logic for renderApp, including other screens)
804
  const screen = appState.currentScreen;
805
  const content = document.getElementById('app-content');
806
  const header = document.getElementById('app-header');
807
  const footer = document.getElementById('app-footer');
808
 
 
809
  const shouldShowNav = screen !== 'welcome';
810
  header.style.display = shouldShowNav ? 'block' : 'none';
811
  footer.style.display = shouldShowNav ? 'block' : 'none';
@@ -813,54 +1184,121 @@
813
  if (shouldShowNav) {
814
  renderHeader();
815
  renderFooter();
816
- } else {
817
- // Simplified welcome screen rendering (add it back if needed)
818
- content.innerHTML = `
819
- <div class="flex flex-col items-center justify-center min-h-screen p-4 bg-white dark:bg-gray-800">
820
- <div class="text-center">
821
- <h1 class="text-6xl font-black text-blue-800 dark:text-blue-300 mb-2">${APP_NAME}</h1>
822
- <p class="text-2xl font-bold text-gray-700 dark:text-gray-400 mb-10">تطبيق تعليم التيفيناغ للأطفال</p>
823
- <button onclick="setState({currentScreen: 'home'})"
824
- class="px-10 py-4 bg-green-500 text-white text-xl font-bold rounded-full shadow-lg hover:bg-green-600 transition-transform transform hover:scale-105">
825
- ابدأ التعلم
826
- </button>
827
- <p class="mt-6 text-sm text-gray-500 dark:text-gray-600">اضغط للبدء</p>
828
- </div>
829
- </div>
830
- `;
831
  }
832
 
833
- if (screen === 'games') {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
834
  content.style.paddingTop = shouldShowNav ? '4rem' : '0';
835
  content.style.paddingBottom = shouldShowNav ? '5rem' : '0';
836
  if (appState.currentGameState === 'memory') {
837
  renderMemoryGame();
838
- } else if (appState.currentGameState === 'naming') {
839
- renderNamingGame();
840
  } else {
841
  renderGamesHome();
842
  }
 
 
 
 
843
  } else {
844
- // Simplified placeholder for other screens
845
- content.style.paddingTop = shouldShowNav ? '4rem' : '0';
846
- content.style.paddingBottom = shouldShowNav ? '5rem' : '0';
847
- if (screen !== 'welcome' && screen !== 'games') {
848
- content.innerHTML = `
849
- <div class="p-4 pt-6 text-center min-h-[calc(100vh-130px)] bg-gray-50 dark:bg-gray-900 transition-colors">
850
- <h2 class="text-3xl font-black text-gray-800 dark:text-white mb-6">شاشة ${screen}</h2>
851
- <p class="text-gray-600 dark:text-gray-400">سيتم إضافة المحتوى الكامل لهذه الشاشة لاحقًا.</p>
852
- <button onclick="setState({currentScreen: 'home'})"
853
- class="mt-8 px-4 py-2 bg-blue-500 text-white rounded-lg">العودة للرئيسية</button>
854
- </div>
855
- `;
856
- }
 
 
 
 
 
 
 
 
 
857
  }
858
  };
 
 
 
 
859
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
860
  window.onload = () => {
861
- // محاكاة بدء الشاشة من 'home' لتجاوز شاشة الترحيب إذا لزم الأمر
862
- // setState({currentScreen: 'home'});
863
- renderApp();
864
  };
865
 
866
  </script>
 
104
  pointer-events: none;
105
  background-color: #10b981;
106
  }
107
+ .ordering-slot {
108
  min-height: 3rem;
109
  }
110
+ .ordering-letter {
111
  cursor: pointer;
112
  user-select: none;
113
  transition: background-color 0.2s, transform 0.1s;
114
  }
115
+ .ordering-letter.active {
116
+ transform: scale(0.95);
117
+ }
118
+
119
  </style>
120
  </head>
121
  <body class="flex justify-center">
 
130
 
131
  <script>
132
  // --- 1. تعريف الأيقونات كـ SVG نصي ---
 
133
  const ICONS = {
134
  Home: (cls) => `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="${cls}"><path d="m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>`,
135
  Share2: (cls) => `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="${cls}"><circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/><line x1="8.59" x2="15.42" y1="13.51" y2="17.49"/><line x1="15.41" x2="8.59" y1="6.51" y2="10.49"/></svg>`,
 
137
  Settings: (cls) => `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="${cls}"><path d="M12.22 2h-.44a2 2 0 0 0-2 2v.44a2 2 0 0 1-1.11 1.76l-.42.25a2 2 0 0 0-.83 1.57v.88a2 2 0 0 0 1.1 1.8l.42.25a2 2 0 0 1 1.11 1.76v.44a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.44a2 2 0 0 1 1.11-1.76l.42-.25a2 2 0 0 0 .83-1.57v-.88a2 2 0 0 0-1.1-1.8l-.42-.25a2 2 0 0 1-1.11-1.76V4a2 2 0 0 0-2-2z"/><circle cx="12" cy="12" r="3"/></svg>`,
138
  Info: (cls) => `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="${cls}"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/></svg>`,
139
  Menu: (cls) => `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="${cls}"><line x1="4" x2="20" y1="12" y2="12"/><line x1="4" x2="20" y1="6" y2="6"/><line x1="4" x2="20" y1="18" y2="18"/></svg>`,
140
+ ChevronLeft: (cls) => `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="${cls}"><polyline points="15 18 9 12 15 6"/></svg>`,
141
  ChevronRight: (cls) => `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="${cls}"><polyline points="9 18 15 12 9 6"/></svg>`,
142
  Mic: (cls) => `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="${cls}"><path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"/><path d="M19 10v2a7 7 0 0 1-14 0v-2"/><line x1="12" x2="12" y1="19" y2="22"/></svg>`,
143
  Volume2: (cls) => `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="${cls}"><polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"/><path d="M19.07 4.93a10 10 0 0 1 0 14.14"/><path d="M15.54 8.46a5 5 0 0 1 0 7.07"/></svg>`,
 
156
  Gamepad: (cls) => `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="${cls}"><path d="M12 21a2 2 0 0 1-2-2v-4H8a2 2 0 0 1-2-2v-4a2 2 0 0 1 2-2h4V5a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2h-4v4a2 2 0 0 1-2 2v2a2 2 0 0 1-2 2z"/><path d="M8 11h4V7H8z"/></svg>`,
157
  BookOpen: (cls) => `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="${cls}"><path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"/><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"/></svg>`,
158
  Brain: (cls) => `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="${cls}"><path d="M12 5C6 5 3 7 3 12s3 7 9 7 9-2 9-7-3-7-9-7z"/><path d="M12 5c-3 0-5 2-5 5v2c0 3 2 5 5 5s5-2 5-5V10c0-3-2-5-5-5z"/></svg>`,
 
159
  Repeat1: (cls) => `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="${cls}"><path d="m19 14-4 4-4-4"/><path d="M15 18H8a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2h12"/><path d="M10 10l4 4 4-4"/></svg>`,
160
  WhatsApp: (cls) => ICONS.Share2(cls),
161
  };
 
172
 
173
 
174
  // --- 2. بيانات التطبيق الثابتة ---
175
+ // Helper to shuffle an array
176
  const shuffleArray = (array) => {
177
  const shuffled = [...array];
178
  for (let i = shuffled.length - 1; i > 0; i--) {
 
183
  };
184
 
185
  const APP_NAME = "Tifawin";
186
+ const APP_NAME_LETTERS = "TIMMUZIT";
187
  const WHATSAPP_LINK = "https://chat.whatsapp.com/J8bK9L0X4M7P2S1R6Q5T";
188
 
189
+ const DEVELOPER_INFO = {
190
+ name: "حسن العمراني (Hassan Alamrani)",
191
+ title: "مطوّر الواجهة التعليمية",
192
+ bio: "مهندس برمجيات متخصص في تطوير واجهات المستخدم التفاعلية وتطبيقات الويب التعليمية. شغوف بدمج التكنولوجيا لتعزيز تعليم اللغات والتراث الثقافي.",
193
+ image: "images/developer_avatar.png"
194
+ };
195
+
196
+ const VOICE_OVER_ARTISTS = [
197
+ { name: "فاطمة الزهراء", role: "المعلق الصوتي الأساسي (أصوات الكبار)" },
198
+ { name: "أحمد الصغير", role: "معلق صوتي للأطفال (أصوات الحروف والأرقام)" },
199
+ { name: "طاقم تطوان للتعابير", role: "تسجيل فصول السنة" }
200
+ ];
201
+
202
+ // ** بيانات تعلم الأمازيغية (تيفيناغ) **
203
  const tifinaghData = [
204
+ { letter: 'ⴰ', word_tifinagh: '', word_arabic: 'جدار-ⴰⴳⴰⴷⵉⵔ', image: 'images/2947c16d27f8042f7d60783c6808519a.jpg', audio: 'audio/aman.mp3' },
205
+ { letter: 'ⴱ', word_tifinagh: '', word_arabic: 'فراشة-ⵉⴱⵔⴱⵉⵍⵍⵓ', image: 'images/3fd6beebd231e2f325469a40b0831b59.jpg', audio: 'audio/barbi.mp3' },
206
+ { letter: 'ⴳ', word_tifinagh: '', word_arabic: 'دخان-ⴰⴳⴳⵓ', image: 'images/c0094eb5dcc49d7cce573d42f270d8de.jpg', audio: 'audio/ca.mp3' },
207
+ { letter: 'ⴷ', word_tifinagh: '', word_arabic: 'تمرة-ⵜⵉⵏⵉ', image: 'images/placeholder_date.jpg', audio: 'audio/da.mp3' },
208
+ { letter: 'ⴹ', word_tifinagh: '', word_arabic: 'قدم-ⴰⴹⴰⵔ', image: 'images/placeholder_foot.jpg', audio: 'audio/dha.mp3' },
209
+ { letter: 'ⴼ', word_tifinagh: '', word_arabic: 'عين-ⵜⵉⵟ', image: 'images/placeholder_eye.jpg', audio: 'audio/fa.mp3' },
210
+ { letter: 'ⵀ', word_tifinagh: '', word_arabic: 'فم-ⴰⴽⵓⵎ', image: 'images/placeholder_mouth.jpg', audio: 'audio/ha.mp3' },
211
+ { letter: 'ⵃ', word_tifinagh: '', word_arabic: 'قلب-ⵓⵍ', image: 'images/placeholder_heart.jpg', audio: 'audio/hha.mp3' },
212
+ { letter: 'ⵇ', word_tifinagh: '', word_arabic: 'قمح-ⵉⵔⴷⵏ', image: 'images/placeholder_wheat.jpg', audio: 'audio/qa.mp3' },
213
+ { letter: 'ⵅ', word_tifinagh: '', word_arabic: 'غيمة-ⴰⵙⴰⴼ', image: 'images/placeholder_cloud.jpg', audio: 'audio/kha.mp3' },
214
+ { letter: 'ⵉ', word_tifinagh: '', word_arabic: 'شمس-ⴰⵢⵢⵓⵔ', image: 'images/placeholder_sun.jpg', audio: 'audio/i.mp3' },
215
+ { letter: 'ⵊ', word_tifinagh: '', word_arabic: 'جبن-ⴰⵛⵛⴰⵔ', image: 'images/placeholder_cheese.jpg', audio: 'audio/ja.mp3' },
216
+ { letter: 'ⴽ', word_tifinagh: '', word_arabic: 'صخرة-ⴰⴷⴳⴰⵏ', image: 'images/placeholder_rock.jpg', audio: 'audio/ka.mp3' },
217
+ { letter: 'ⵍ', word_tifinagh: '', word_arabic: 'عسل-ⵜⴰⵎⵉⵎⵜ', image: 'images/placeholder_honey.jpg', audio: 'audio/la.mp3' },
218
+ { letter: 'ⵎ', word_tifinagh: '', word_arabic: 'بحر-ⵉⵍⵍ', image: 'images/placeholder_sea.jpg', audio: 'audio/ma.mp3' },
 
 
219
  ];
220
 
221
+ const animalsData = [
222
+ { word_tifinagh: 'ⴰⵎⵓⵛⵛ', word_arabic: 'قط ', image: 'images/cat.jpeg', audio: 'audio/animaux.ogg' },
223
+ { word_tifinagh: 'ⴰⵢⴷⵉ', word_arabic: 'كلب', image: 'images/124419894dcfde81ffbca1e072804c71.jpg', audio: 'audio/dog.mp3' },
224
+ { word_tifinagh: 'ⴰⵡⵉ', word_arabic: 'أسد', image: 'images/placeholder_lion.jpg', audio: 'audio/lion.mp3' },
225
+ { word_tifinagh: 'ⵉⵖ', word_arabic: 'خروف', image: 'images/placeholder_sheep.jpg', audio: 'audio/sheep.mp3' },
226
+ ];
227
+
228
+ const fruitsData = [
229
+ { main: 'ⵜⴰⴷⴼⴼⵓⵢⵜ', word: 'تفاحة', imageUrl: 'images/da1da4f2015a32322f547ae5fff5236c.jpg', audioUrl: 'audio/fruits/apple.mp3' },
230
+ { main: 'ⵜⴰⴱⴰⵏⴰⵏⵜ', word: 'موز', imageUrl: 'images/placeholder_banana.jpg', audioUrl: 'audio/fruits/banana.mp3' },
231
+ { main: 'ⴰⵡⵔⵉⵖ', word: 'برتقال', imageUrl: 'images/placeholder_orange.jpg', audioUrl: 'audio/fruits/orange.mp3' },
232
+ ];
233
+
234
+ const numbersData = [
235
+ { number: '0', word_tifinagh: 'ⴰⵎⵢⴰ', word_arabic: 'صفر ', image: 'images/d3a43a956f3129b847739dec5f10c81f.jpg', audio: 'audio/zero.mp3' },
236
+ { number: '1', word_tifinagh: 'ⵢⴰⵏ ', word_arabic: ' واحد', image: 'images/b26681eaa5caacbf1c7bfb112f546def.jpg', audio: 'audio/one.mp3' },
237
+ { number: '2', word_tifinagh: 'ⵙⵉⵏ ', word_arabic: ' اثنان', image: 'images/placeholder_two.jpg', audio: 'audio/two.mp3' },
238
+ { number: '3', word_tifinagh: 'ⴽⵕⴰⴹ ', word_arabic: ' ثلاثة', image: 'images/placeholder_three.jpg', audio: 'audio/three.mp3' },
239
+ ];
240
+
241
  const LEARNING_DATA = {
242
  tifinaghLetters: tifinaghData.map(item => {
243
  const parts = item.word_arabic.split('-');
244
+ return {
245
+ main: item.letter,
246
+ word: parts.length > 1 ? parts[0].trim() : item.word_arabic.trim(),
247
+ transliteration: parts.length > 1 ? parts[1].trim() : '',
248
+ imageUrl: item.image,
249
+ audioUrl: item.audio,
250
+ };
251
  }),
252
+ numbers: numbersData.map(item => ({
253
+ main: item.number,
254
+ word: item.word_arabic.trim(),
255
+ transliteration: item.word_tifinagh.trim(),
256
+ imageUrl: item.image,
257
+ audioUrl: item.audio,
258
+ })),
259
  tools: [{ main: 'ⴰⴽⵕⵕⴰⵊ', word: 'قلم رصاص', imageUrl: 'images/37b71533177feb9d55d55efba947309e.jpg', audioUrl: 'audio/schoolSupplies/pencil.mp3' }],
260
+ fruits: fruitsData,
 
 
 
 
261
  vegetables: [{ main: 'ⵜⴰⵎⴰⵟⵉⵛⵜ', word: 'طماطم', imageUrl: 'images/6056d9839a962b5a78cddc402ef88c09.jpg', audioUrl: 'audio/vegetables/tomato.mp3' }],
262
+ animals: animalsData.map(item => ({ main: item.word_tifinagh, word: item.word_arabic, imageUrl: item.image, audioUrl: item.audio })),
 
 
 
 
 
263
  body: [{ main: 'ⵉⵅⴼ', word: 'الرأس', imageUrl: 'images/33dda7fe89cfd5526918246dae320059.jpg', audioUrl: 'audio/bodyParts/head.mp3' }],
264
+ days: [{ main: 'ⴰⵢⵏⴰⵙ', word: 'الاثنين', imageUrl: 'images/37b71533177feb9d55d55efba947309e.jpg', audioUrl: 'audio/days/monday.mp3' }],
265
+ months: [{ main: 'ⵉⵏⵏⴰⵢⵔ', word: 'يناير', imageUrl: 'images/b26681eaa5caacbf1c7bfb112f546def.jpg', audioUrl: 'audio/months/january.mp3' }],
266
  family: [{ main: 'ⵉⵎⵎⵉ', word: 'أمي', imageUrl: 'images/5957c378462b920ceb24f6aa294b5100.jpg', audioUrl: 'audio/family/mother.mp3' }],
267
+ colors: [
268
+ { main: 'ⴰⵣⴳⴳⵯⴰⵖ', word: 'أحمر', imageUrl: 'images/b008721ac76def4ddfdbdb51fc82d320.jpg', audioUrl: 'audio/colors/red.mp3', colorClass: 'bg-red-600' },
269
+ { main: 'ⴰⵣⴳⴳⵯⴰⵖ', word: 'أزرق', imageUrl: 'images/b008721ac76def4ddfdbdb51fc82d320.jpg', audioUrl: 'audio/colors/blue.mp3', colorClass: 'bg-blue-600' },
270
+ ],
271
+ seasons: [{ main: 'ⵜⴰⴳⵔⵙⵜ', word: 'الشتاء', imageUrl: 'images/b2d331ea13a2df600219904dabd028fa.jpg', audioUrl: 'audio/AUD-20250926-WA0003.opus' }],
272
+ games: [{ main: "أسد صغير شجاع", word: "في غابة بعيدة، عاش أسد صغير اسمه سمير...", imageUrl: "images/Screenshot_20250927_141840_One Read.jpg", audioUrl: null }],
273
+ stories: [{ main: "السلحفاة والأرنب", word: "في غابة خضراء، قرر أرنب وسلحفاة...", imageUrl: "images/73b552bd0d3472c121adccc68a5bbb7f.jpg", audioUrl: null }],
274
  };
 
 
 
275
 
276
  // --- بيانات مستويات الألعاب الجديدة ---
277
 
278
+ const MEMORY_GAME_ITEMS = [
 
279
  ...LEARNING_DATA.animals,
280
  ...LEARNING_DATA.fruits,
281
+ ...LEARNING_DATA.numbers,
 
282
  ...LEARNING_DATA.tools,
283
+ // بيانات إضافية وهمية لتغطية المستويات العليا
284
  { main: 'ⵉⵎⵉ', word: 'فم', imageUrl: 'images/placeholder_mouth_game.jpg', audioUrl: null },
285
  { main: 'ⴰⴼⵓⵙ', word: 'يد', imageUrl: 'images/placeholder_hand_game.jpg', audioUrl: null },
286
  { main: 'ⴰⵛⵛⴰ', word: 'أكل', imageUrl: 'images/placeholder_eat_game.jpg', audioUrl: null },
287
  { main: 'ⴰⴼⵔⴰ', word: 'طير', imageUrl: 'images/placeholder_bird_game.jpg', audioUrl: null },
288
  { main: '���ⵎⴰⵏ', word: 'ماء', imageUrl: 'images/placeholder_water_game.jpg', audioUrl: null },
289
+ ].slice(0, 16).map((item, index) => ({...item, id: `item-${index}`})); // تحديد 16 عنصراً فريداً
290
 
291
  const memoryGameLevels = [
292
+ { level: 1, pairs: 3, items: MEMORY_GAME_ITEMS.slice(0, 3) }, // 6 cards (3x2)
293
+ { level: 2, pairs: 4, items: MEMORY_GAME_ITEMS.slice(0, 4) }, // 8 cards (4x2)
294
+ { level: 3, pairs: 5, items: MEMORY_GAME_ITEMS.slice(0, 5) }, // 10 cards (5x2)
295
+ { level: 4, pairs: 6, items: MEMORY_GAME_ITEMS.slice(0, 6) }, // 12 cards (4x3)
296
+ { level: 5, pairs: 8, items: MEMORY_GAME_ITEMS.slice(0, 8) }, // 16 cards (4x4)
297
+ { level: 6, pairs: 10, items: MEMORY_GAME_ITEMS.slice(0, 10) }, // 20 cards (5x4)
298
+ { level: 7, pairs: 12, items: MEMORY_GAME_ITEMS.slice(0, 12) }, // 24 cards (6x4)
299
+ { level: 8, pairs: 14, items: MEMORY_GAME_ITEMS.slice(0, 14) }, // 28 cards (7x4)
300
+ { level: 9, pairs: 15, items: MEMORY_GAME_ITEMS.slice(0, 15) }, // 30 cards (6x5)
301
+ { level: 10, pairs: 16, items: MEMORY_GAME_ITEMS.slice(0, 16) }, // 32 cards (8x4)
302
  ];
303
 
304
+ const TIFINAGH_LETTERS_BASIC = LEARNING_DATA.tifinaghLetters.map(i => i.main);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
305
 
306
+ const tifinaghOrderingLevels = [
307
+ { level: 1, letters: TIFINAGH_LETTERS_BASIC.slice(0, 4) },
308
+ { level: 2, letters: TIFINAGH_LETTERS_BASIC.slice(0, 5) },
309
+ { level: 3, letters: TIFINAGH_LETTERS_BASIC.slice(0, 6) },
310
+ { level: 4, letters: TIFINAGH_LETTERS_BASIC.slice(0, 7) },
311
+ { level: 5, letters: TIFINAGH_LETTERS_BASIC.slice(0, 8) },
312
+ { level: 6, letters: TIFINAGH_LETTERS_BASIC.slice(0, 9) },
313
+ { level: 7, letters: TIFINAGH_LETTERS_BASIC.slice(0, 10) },
314
+ { level: 8, letters: TIFINAGH_LETTERS_BASIC.slice(0, 11) },
315
+ { level: 9, letters: TIFINAGH_LETTERS_BASIC.slice(0, 12) },
316
+ { level: 10, letters: TIFINAGH_LETTERS_BASIC.slice(0, 13) },
317
+ ].map(levelData => ({
318
+ ...levelData,
319
+ correctOrder: levelData.letters,
320
+ scrambledLetters: shuffleArray(levelData.letters),
321
+ }));
 
 
 
 
 
 
 
 
 
322
 
323
+
324
  const CATEGORIES = [
325
  { id: 'tifinaghLetters', title: 'تعلم الحروف', subtitle: 'ⴰ, ⴱ, ⴳ...', iconName: 'AArrowUp', imageUrl: 'images/6e318d538a2d8f0b5ad685db558ffe4e.jpg' },
326
  { id: 'numbers', title: 'تعلم الأرقام', subtitle: '0, 1, 2...', iconName: 'Hash', imageUrl: 'images/0751e273c2de27e4b04dfeb7ee99b448.jpg' },
 
349
  isDarkMode: false,
350
  isAppMuted: false,
351
  isRecording: false,
352
+ // New Game State
353
+ currentGameState: null, // 'memory' or 'tifinagh_ordering'
354
  currentLevel: 1,
355
+ gameData: null, // Stores specific data for the current game
356
  memoryGame: {
357
+ flippedCards: [], // Indices of currently flipped cards
358
+ matchedCards: [], // IDs of matched items
359
+ lockBoard: false, // Prevents flipping more cards
360
  },
361
+ tifinaghOrderingGame: {
362
+ userOrder: [], // Letters the user has placed
363
+ availableLetters: [], // Letters waiting to be placed
364
  }
365
  };
366
 
367
+ // دالة تحديث الحالة وإعادة رسم التطبيق
368
  window.setState = (newState) => {
369
+ if (newState.currentScreen && newState.currentScreen !== appState.selectedCategory) {
 
370
  appState.currentIndex = 0;
371
+ appState.currentGameState = null; // Reset game state on screen change
372
  appState.currentLevel = 1;
373
  }
374
+
375
+ // Handle game specific screen logic
376
  if (newState.currentGameState && newState.currentGameState !== appState.currentGameState) {
377
  appState.currentLevel = 1;
 
378
  appState.memoryGame = { flippedCards: [], matchedCards: [], lockBoard: false };
379
+ appState.tifinaghOrderingGame = { userOrder: [], availableLetters: [] };
380
+ appState.gameData = null;
381
  }
382
+ if (newState.currentLevel && newState.currentLevel !== appState.currentLevel) {
 
383
  appState.memoryGame = { flippedCards: [], matchedCards: [], lockBoard: false };
384
+ appState.tifinaghOrderingGame = { userOrder: [], availableLetters: [] };
385
+ appState.gameData = null;
386
  }
387
 
388
 
389
  Object.assign(appState, newState);
390
 
391
+ // تطبيق الوضع الليلي فوراً على الجسم والحاوية
392
  document.body.classList.toggle('dark', appState.isDarkMode);
393
  document.getElementById('app-container').classList.toggle('dark', appState.isDarkMode);
394
 
395
  renderApp();
396
  };
397
 
398
+ // دالة تبديل حالة القائمة الجانبية
399
  window.toggleMenu = () => {
400
  setState({ isMenuOpen: !appState.isMenuOpen });
401
  };
402
 
403
+ // الدوال الجديدة للتحكم في التسجيل (محاكاة)
404
+ window.startRecording = () => {
405
+ setState({ isRecording: true, currentScreen: appState.currentScreen });
406
+ console.log("Recording Started...");
407
+ alert("بدأ التسجيل! تحدث الآن...");
408
+ };
409
+
410
+ window.stopRecording = () => {
411
+ setState({ isRecording: false, currentScreen: appState.currentScreen });
412
+ console.log("Recording Stopped.");
413
+ alert("تم إيقاف التسجيل. (في التطبيق الحقيقي، هنا يمكن مقارنة الصوت)");
414
+ };
415
+
416
+
417
+ // --- 4. مكونات الواجهة المشتركة (رأس الصفحة وتذييلها) ---
418
+
419
  const renderHeader = () => {
 
420
  const headerElement = document.getElementById('app-header');
421
  const categoryMeta = CATEGORIES.find(c => c.id === appState.selectedCategory);
422
 
423
  let title = APP_NAME;
424
  if (appState.currentGameState === 'memory') {
425
+ title = 'لعبة الذاكرة';
426
+ } else if (appState.currentGameState === 'tifinagh_ordering') {
427
+ title = 'ترتيب الحروف';
428
  } else if (categoryMeta && appState.currentScreen !== 'home' && !['settings', 'info', 'appDefinition', 'games'].includes(appState.currentScreen)) {
429
  title = categoryMeta.title;
430
  } else if (appState.currentScreen === 'settings') {
 
440
  headerElement.innerHTML = `
441
  <div class="flex items-center justify-between p-4 h-16 bg-blue-800 dark:bg-gray-800 text-white shadow-lg rounded-b-xl transition-colors">
442
  <button onclick="
443
+ ${appState.currentGameState ? `setState({currentGameState: null, currentLevel: 1})` : `toggleMenu()`}
444
  "
445
  class="p-1 rounded-full hover:bg-white/10 transition-colors" aria-label="العودة / القائمة">
446
  ${appState.currentGameState ? renderIcon('ChevronRight', 'w-6 h-6 text-white') : renderIcon('Menu', 'w-6 h-6 text-white')}
 
454
  </div>
455
  `;
456
  };
457
+
458
  const renderFooter = () => {
459
+ // ... (Footer rendering remains mostly the same)
460
  const footerElement = document.getElementById('app-footer');
461
  const navItems = [
462
  { id: 'home', iconName: 'Home', label: 'الرئيسية' },
 
498
  </div>
499
  `;
500
  };
501
+
502
+ // --- 5. شاشة 1: شاشة الترحيب (Welcome Screen) ---
503
+ const renderWelcomeScreen = () => {
504
+ // ... (Code remains the same)
505
+ const content = document.getElementById('app-content');
506
+
507
+ const logoHTML = `
508
+ <div class="flex flex-col items-center">
509
+ <div class="text-6xl font-black text-blue-600 dark:text-blue-400 mb-4 drop-shadow-lg">
510
+ ${renderIcon('Carrot', 'w-16 h-16 text-orange-500 dark:text-orange-300 icon-shadow', 2)}
511
+ </div>
512
+ <h1 class="text-6xl font-extrabold text-gray-900 dark:text-white mb-2 leading-none">Tifawin</h1>
513
+ <p class="text-xl font-medium text-gray-600 dark:text-gray-300 mt-2">تعلم الأمازيغية للأطفال</p>
514
+ </div>
515
+ `;
516
+
517
+ const copyrightText = "TIFIWIN-AZIZIJAOUAD@2025";
518
+
519
+ content.innerHTML = `
520
+ <div class="flex flex-col items-center justify-between min-h-[calc(100vh)] p-8 bg-white dark:bg-gray-900 transition-colors">
521
+
522
+ <div class="flex-grow flex flex-col items-center justify-center text-center w-full">
523
+ ${logoHTML}
524
+
525
+ <p class="text-lg text-gray-500 dark:text-gray-400 mt-10 max-w-xs">
526
+ انطلق في رحلة ممتعة لاستكشاف حروف وألوان ومفردات اللغة الأمازيغية.
527
+ </p>
528
+ </div>
529
+
530
+ <button onclick="setState({currentScreen: 'home'})"
531
+ class="w-full max-w-xs py-4 bg-green-500 hover:bg-green-600 text-white text-xl font-bold rounded-full shadow-2xl shadow-green-400/50 transition-all card-shadow mb-6">
532
+ هيا نبدأ!
533
+ </button>
534
+
535
+ <p class="text-xs text-gray-400 dark:text-gray-600 font-mono tracking-wider">
536
+ ${copyrightText}
537
+ </p>
538
+ </div>
539
+ `;
540
+ };
541
+
542
+
543
+ // --- 6. شاشة 2: الشاشة الرئيسية (Home Screen) ---
544
+ const renderHomeScreen = () => {
545
+ // ... (Code remains the same)
546
+ const content = document.getElementById('app-content');
547
+
548
+ const cardsHTML = CATEGORIES.map(category => `
549
+ <button
550
+ onclick="setState({currentScreen: '${category.id}', selectedCategory: '${category.id}'})"
551
+ class="relative w-full h-32 rounded-2xl overflow-hidden card-shadow group"
552
+ aria-label="الذهاب إلى قسم ${category.title}"
553
+ >
554
+ <img
555
+ src="${category.imageUrl}"
556
+ alt="${category.title}"
557
+ class="w-full h-full object-cover transition-transform duration-300 group-hover:scale-110"
558
+ onerror="this.onerror=null; this.src='https://placehold.co/300x200/cccccc/000000?text=صورة+${category.title}';"
559
+ />
560
+
561
+ <div class="absolute inset-0 flex flex-col items-center justify-center p-3 text-white font-extrabold text-lg image-overlay">
562
+ <span class="text-xl font-black text-center leading-tight drop-shadow-md">${category.title}</span>
563
+ <span class="text-xs opacity-80 mt-1 drop-shadow-sm">${category.subtitle}</span>
564
+ </div>
565
+ </button>
566
+ `).join('');
567
+
568
+ content.innerHTML = `
569
+ <div class="p-4 bg-gray-50 dark:bg-gray-900 min-h-[calc(100vh-130px)] transition-colors">
570
+ <h2 class="text-2xl font-bold text-gray-800 dark:text-white mb-4 text-center">أقسام التعلم</h2>
571
+ <div class="grid grid-cols-2 sm:grid-cols-3 gap-3">
572
+ ${cardsHTML}
573
+ </div>
574
+ <p class="text-center text-gray-500 dark:text-gray-400 mt-6 text-sm">
575
+ اختر قسمًا لتبدأ رحلة التعلم الممتعة!
576
+ </p>
577
+ </div>
578
+ `;
579
+ };
580
+
581
+ // --- 7. شاشة التعلم العامة (Learning Screen) ---
582
+ const renderLearningScreen = () => {
583
+ // ... (Code remains the same)
584
+ const categoryId = appState.selectedCategory;
585
+ const content = document.getElementById('app-content');
586
+ const data = LEARNING_DATA[categoryId] || [];
587
+ const categoryMeta = CATEGORIES.find(c => c.id === categoryId);
588
+
589
+ if (data.length === 0 || !categoryMeta) {
590
+ content.innerHTML = `
591
+ <div class="p-8 min-h-[calc(100vh-130px)] flex flex-col items-center justify-center bg-gray-50 dark:bg-gray-900 transition-colors">
592
+ <p class="text-xl font-bold text-red-500 mb-4 dark:text-red-400">عفواً! لا توجد بيانات لهذا القسم.</p>
593
+ <button onclick="setState({currentScreen: 'home', selectedCategory: null})"
594
+ class="px-6 py-3 bg-blue-600 text-white font-bold rounded-xl shadow-lg hover:bg-blue-700 card-shadow">
595
+ العودة للرئيسية
596
+ </button>
597
+ </div>
598
+ `;
599
+ return;
600
+ }
601
+
602
+
603
+ const currentItem = data[appState.currentIndex];
604
+ const isColorsCategory = categoryId === 'colors';
605
+ const isRecordingActive = appState.isRecording;
606
+
607
+ window.playAudio = () => {
608
+ if (appState.isAppMuted) {
609
+ console.log("Audio is muted by user setting.");
610
+ return;
611
+ }
612
+ if (currentItem.audioUrl) {
613
+ const audioPath = currentItem.audioUrl;
614
+ new Audio(audioPath).play().catch(e => console.error("Error playing audio:", e));
615
+ } else {
616
+ alert('ملف صوتي غير متوفر لهذا العنصر.');
617
+ }
618
+ };
619
+
620
+ window.handleNext = () => {
621
+ const newIndex = (appState.currentIndex + 1) % data.length;
622
+ setState({ currentIndex: newIndex, currentScreen: categoryId });
623
+ };
624
+ window.handlePrev = () => {
625
+ const newIndex = (appState.currentIndex - 1 + data.length) % data.length;
626
+ setState({ currentIndex: newIndex, currentScreen: categoryId });
627
+ };
628
+
629
+ const mainCardGradient = appState.isDarkMode
630
+ ? 'from-gray-700 to-gray-600'
631
+ : (categoryId === 'tifinaghLetters' ? 'from-orange-400 to-pink-300' : 'from-blue-400 to-purple-300');
632
+
633
+ let illustrationContent;
634
+ if (isColorsCategory && currentItem.word !== 'أبيض') {
635
+ illustrationContent = `
636
+ <div class="w-40 h-40 sm:w-44 sm:h-44 rounded-full shadow-inner ${currentItem.colorClass || 'bg-gray-400'} border-4 border-white/80"></div>
637
+ `;
638
+ } else {
639
+ illustrationContent = `
640
+ <img
641
+ src="${currentItem.imageUrl || 'https://placehold.co/150x150/cccccc/000000?text=صورة'}"
642
+ alt="${currentItem.word}"
643
+ class="w-40 h-40 sm:w-44 sm:h-44 rounded-xl object-cover shadow-lg border-4 border-white/50"
644
+ onerror="this.onerror=null; this.src='https://placehold.co/150x150/cccccc/000000?text=صورة+${categoryMeta.title}';"
645
+ />
646
+ `;
647
+ }
648
+
649
+ let mainWordDisplay = currentItem.main;
650
+ let secondaryText = currentItem.word;
651
+
652
+ const cornerElementHTML = (categoryId === 'tifinaghLetters') ? `
653
+ <div class="absolute top-0 right-0 p-3 bg-white/20 backdrop-blur-sm rounded-tr-3xl rounded-bl-3xl shadow-md text-white">
654
+ <h2 class="font-black text-4xl icon-shadow">
655
+ ${currentItem.main}
656
+ </h2>
657
+ </div>
658
+ ` : '';
659
+
660
+ const micAction = isRecordingActive ? 'stopRecording()' : 'startRecording()';
661
+ const micButtonClass = isRecordingActive
662
+ ? 'bg-red-600 hover:bg-red-700 shadow-2xl shadow-red-400/70 animate-pulse'
663
+ : 'bg-red-500 hover:bg-red-600 shadow-2xl shadow-red-400/70';
664
+
665
+
666
+ content.innerHTML = `
667
+ <div class="p-4 flex flex-col items-center justify-between min-h-[calc(100vh-130px)] bg-gray-50 dark:bg-gray-900 transition-colors">
668
+
669
+ <div class="w-full max-w-sm mx-auto bg-gradient-to-br ${mainCardGradient} rounded-3xl p-4 sm:p-6 shadow-2xl mt-2 flex flex-col justify-center items-center relative">
670
+
671
+ ${cornerElementHTML}
672
+
673
+ <h2 class="text-white text-xl font-bold mb-3 drop-shadow-md mt-4">${categoryMeta.title}</h2>
674
+
675
+ <div class="flex items-center justify-center w-full p-2 mb-3">
676
+ ${illustrationContent}
677
+ </div>
678
+
679
+ <div class="mt-1 text-center text-white">
680
+ <p class="text-3xl font-black mb-1 drop-shadow-lg leading-tight">${mainWordDisplay}</p>
681
+ <p class="text-sm font-medium opacity-80 italic drop-shadow-sm">
682
+ ${secondaryText}
683
+ </p>
684
+ </div>
685
+ </div>
686
+
687
+ <div class="w-full max-w-sm mx-auto mt-4 bg-white dark:bg-gray-700 p-4 rounded-xl shadow-lg flex items-center gap-3 transition-colors">
688
+ <button onclick="playAudio()" class="p-2 rounded-full ${appState.isAppMuted ? 'bg-gray-200' : 'bg-green-100 hover:bg-green-200'} transition-colors" aria-label="تشغيل الصوت">
689
+ ${renderIcon('Volume2', `w-7 h-7 ${appState.isAppMuted ? 'text-gray-500' : 'text-green-600'} flex-shrink-0`, 3)}
690
+ </button>
691
+ <div class="flex-grow">
692
+ <p class="text-sm text-gray-700 dark:text-gray-300 font-bold">استمع إلى النطق</p>
693
+ <p class="text-xs text-gray-500 dark:text-gray-400 mt-1 text-left">${currentItem.audioUrl ? 'ملف الصوت متوفر' : 'ملف الصوت غير متوفر'}</p>
694
+ </div>
695
+
696
+ <p class="text-sm text-blue-800 dark:text-blue-300 font-bold flex-shrink-0">
697
+ نطق
698
+ </p>
699
+ </div>
700
+
701
+ <div class="flex justify-around w-full max-w-sm mx-auto mt-4 mb-4">
702
+ <button onclick="handlePrev()" class="control-btn bg-green-500 hover:bg-green-600 shadow-xl shadow-green-300/70" aria-label="العنصر السابق">
703
+ ${renderIcon('ChevronRight', 'w-8 h-8 text-white', 3)}
704
+ </button>
705
+
706
+ <button onclick="${micAction}" class="control-btn p-6 ${micButtonClass}" aria-label="${isRecordingActive ? 'إيقاف التسجيل' : 'بدء التسجيل'}">
707
+ ${renderIcon('Mic', 'w-10 h-10 text-white', 3)}
708
+ </button>
709
+
710
+ <button onclick="handleNext()" class="control-btn bg-blue-500 hover:bg-blue-600 shadow-xl shadow-blue-300/70" aria-label="العنصر التالي">
711
+ ${renderIcon('ChevronLeft', 'w-8 h-8 text-white', 3)}
712
+ </button>
713
+ </div>
714
+ </div>
715
+ `;
716
+ // تشغيل الصوت تلقائيًا عند التحميل
717
+ if (!appState.isAppMuted && currentItem.audioUrl) {
718
+ // تأخير بسيط لضمان تحميل الواجهة
719
+ setTimeout(() => playAudio(currentItem.audioUrl), 500);
720
+ }
721
+ };
722
+
723
+ // --- 7.1 شاشة الإعدادات (Settings Screen) ---
724
+ const renderSettingsScreen = () => {
725
+ // ... (Code remains the same)
726
+ const content = document.getElementById('app-content');
727
+
728
+ const renderToggle = (id, label, stateKey) => `
729
+ <div class="flex items-center justify-between p-4 bg-white dark:bg-gray-700 rounded-xl shadow-md transition-colors">
730
+ <span class="text-gray-800 dark:text-white font-bold">${label}</span>
731
+ <label class="relative inline-flex items-center cursor-pointer">
732
+ <input type="checkbox" value="" class="sr-only peer" ${appState[stateKey] ? 'checked' : ''} onchange="setState({${stateKey}: event.target.checked, currentScreen: 'settings'})">
733
+ <div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 dark:peer-focus:ring-blue-800 rounded-full peer dark:bg-gray-600 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:right-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-500 peer-checked:bg-blue-600"></div>
734
+ </label>
735
+ </div>
736
+ `;
737
+
738
+ content.innerHTML = `
739
+ <div class="p-4 pt-6 min-h-[calc(100vh-130px)] bg-gray-50 dark:bg-gray-900 transition-colors">
740
+ <h2 class="text-3xl font-black text-gray-800 dark:text-white mb-6 text-center">الإعدادات</h2>
741
+
742
+ <div class="space-y-4 max-w-sm mx-auto">
743
+
744
+ ${renderToggle('dark-mode-toggle', 'الوضع الليلي (Dark Mode)', 'isDarkMode')}
745
+
746
+ ${renderToggle('mute-audio-toggle', 'كتم صوت العناصر التعليمية', 'isAppMuted')}
747
+
748
+ <div class="text-sm text-gray-500 dark:text-gray-400 p-2">
749
+ * ملاحظة: الإعدادات تُطبق فورًا على جميع شاشات التطبيق.
750
+ </div>
751
+
752
+ <div class="mt-8 pt-4 border-t border-gray-200 dark:border-gray-700">
753
+ <h3 class="text-xl font-bold text-gray-700 dark:text-gray-300 mb-4">خيارات أخرى</h3>
754
+ <button class="w-full py-3 bg-gray-200 dark:bg-gray-600 text-gray-800 dark:text-gray-200 font-bold rounded-xl hover:bg-gray-300 dark:hover:bg-gray-500 transition-colors">
755
+ إدارة البيانات (حذف/تصدير)
756
+ </button>
757
+ </div>
758
+ </div>
759
+ </div>
760
+ `;
761
+ };
762
+
763
+ // --- 7.2 شاشة حول التطبيق (Info Screen) ---
764
+ const renderInfoScreen = () => {
765
+ // ... (Code remains the same)
766
+ const content = document.getElementById('app-content');
767
+
768
+ const artistsHTML = VOICE_OVER_ARTISTS.map(artist => `
769
+ <li class="p-3 bg-white dark:bg-gray-700 rounded-lg shadow-sm flex flex-col sm:flex-row justify-between items-start sm:items-center transition-colors">
770
+ <span class="text-gray-800 dark:text-gray-200 font-bold">${artist.name}</span>
771
+ <span class="text-sm text-blue-600 dark:text-blue-400 italic mt-1 sm:mt-0">${artist.role}</span>
772
+ </li>
773
+ `).join('');
774
+
775
+ content.innerHTML = `
776
+ <div class="p-4 pt-6 min-h-[calc(100vh-130px)] bg-gray-50 dark:bg-gray-900 transition-colors">
777
+ <h2 class="text-3xl font-black text-gray-800 dark:text-white mb-6 text-center">حول تطبيق ${APP_NAME}</h2>
778
+
779
+ <div class="max-w-md mx-auto bg-blue-100 dark:bg-blue-900/50 p-6 rounded-2xl shadow-xl mb-8 border-t-4 border-blue-500 transition-colors">
780
+ <h3 class="text-2xl font-black text-blue-800 dark:text-blue-300 mb-4 text-center">مطوّر البرنامج</h3>
781
+ <div class="flex flex-col items-center text-center">
782
+ <img src="${DEVELOPER_INFO.image}"
783
+ alt="${DEVELOPER_INFO.name}"
784
+ class="w-24 h-24 rounded-full object-cover border-4 border-white dark:border-gray-700 shadow-lg mb-3"
785
+ onerror="this.onerror=null; this.src='https://placehold.co/96x96/4A5568/ffffff?text=المطور';"
786
+ />
787
+ <p class="text-xl font-bold text-gray-900 dark:text-white">${DEVELOPER_INFO.name}</p>
788
+ <p class="text-sm text-blue-700 dark:text-blue-400 mb-3">${DEVELOPER_INFO.title}</p>
789
+ <p class="text-gray-700 dark:text-gray-300 text-sm leading-relaxed italic">"${DEVELOPER_INFO.bio}"</p>
790
+ </div>
791
+ </div>
792
+
793
+ <div class="max-w-md mx-auto">
794
+ <h3 class="text-2xl font-black text-gray-800 dark:text-white mb-4 border-b pb-2 border-gray-200 dark:border-gray-700">المعلقون الصوتيون</h3>
795
+ <ul class="space-y-3">
796
+ ${artistsHTML}
797
+ </ul>
798
+ </div>
799
+ </div>
800
+ `;
801
+ };
802
+
803
+ // --- 7.3 شاشة تعريف التطبيق (App Definition Screen) ---
804
+ const renderAppDefinitionScreen = () => {
805
+ // ... (Code remains the same)
806
+ const content = document.getElementById('app-content');
807
+
808
+ const features = [
809
+ { title: 'تعلم الأحرف والأرقام', description: 'أساسيات لغة الأمازيغية (تيفيناغ) مع النطق الواضح.', icon: 'AArrowUp' },
810
+ { title: 'المفردات المصنفة', description: 'أقسام متخصصة للحيوانات، الألوان، العائلة، وأجزاء الجسم.', icon: 'Palette' },
811
+ { title: 'تفاعلي بالصوت', description: 'إمكانية الاستماع للنطق والتسجيل للمقارنة (ميزة التسجيل قيد التطوير).', icon: 'Volume2' },
812
+ { title: 'إعدادات مخصصة', description: 'التحكم في الوضع الليلي وكتم الصوت لتجربة مريحة.', icon: 'Settings' },
813
+ ];
814
+
815
+ const featuresHTML = features.map(f => `
816
+ <div class="flex items-start p-3 bg-white dark:bg-gray-700 rounded-xl shadow-sm transition-colors">
817
+ <div class="flex-shrink-0 p-2 bg-blue-100 dark:bg-blue-900 rounded-full">
818
+ ${renderIcon(f.icon, 'w-6 h-6 text-blue-600 dark:text-blue-300')}
819
+ </div>
820
+ <div class="mr-3">
821
+ <h4 class="font-bold text-gray-800 dark:text-white">${f.title}</h4>
822
+ <p class="text-sm text-gray-600 dark:text-gray-400 mt-0.5">${f.description}</p>
823
+ </div>
824
+ </div>
825
+ `).join('');
826
+
827
+ content.innerHTML = `
828
+ <div class="p-4 pt-6 min-h-[calc(100vh-130px)] bg-gray-50 dark:bg-gray-900 transition-colors">
829
+ <h2 class="text-3xl font-black text-gray-800 dark:text-white mb-4 text-center">ما هو تطبيق ${APP_NAME_LETTERS}؟</h2>
830
+
831
+ <div class="max-w-md mx-auto space-y-6">
832
+ <div class="bg-blue-500/10 dark:bg-blue-900/40 p-5 rounded-2xl border-l-4 border-blue-600">
833
+ <p class="text-lg text-gray-700 dark:text-gray-300 font-medium leading-relaxed">
834
+ تطبيق **${APP_NAME}** هو أداة تعليمية تفاعلية مصممة لتعليم الأطفال والمبتدئين
835
+ أساسيات **اللغة الأمازيغية (تيفيناغ)** بطريقة مسلية ومنظمة، مع التركيز على النطق الصحيح والمفردات اليومية.
836
+ </p>
837
+ </div>
838
+
839
+ <h3 class="text-2xl font-bold text-gray-800 dark:text-white border-b pb-2">المميزات الرئيسية</h3>
840
+
841
+ <div class="space-y-4">
842
+ ${featuresHTML}
843
+ </div>
844
+
845
+ <div class="mt-6 pt-4 border-t border-gray-200 dark:border-gray-700 text-center">
846
+ <p class="text-sm text-gray-500 dark:text-gray-400">
847
+ الإصدار الحالي: 1.2 | جميع الحقوق محفوظة 2024
848
+ </p>
849
+ </div>
850
+ </div>
851
+ </div>
852
+ `;
853
+ };
854
+
855
+
856
+ // --- 8. شاشات الألعاب الجديدة ---
857
+
858
  const renderGamesHome = () => {
859
  const content = document.getElementById('app-content');
860
 
 
862
  {
863
  id: 'memory',
864
  title: 'لعبة الذاكرة',
865
+ subtitle: 'طابق الصور والمفردات الأمازيغية',
866
  iconName: 'Brain',
867
  color: 'bg-green-500',
868
  action: `setState({currentGameState: 'memory'})`
869
  },
870
  {
871
+ id: 'tifinagh_ordering',
872
+ title: 'ترتيب حروف تيفيناغ',
873
+ subtitle: 'رتّب الحروف الأمازيغية بشكل صحيح',
874
+ iconName: 'Repeat1',
875
  color: 'bg-red-500',
876
+ action: `setState({currentGameState: 'tifinagh_ordering'})`
877
  },
878
  ];
879
 
 
905
  const levelData = memoryGameLevels[appState.currentLevel - 1];
906
  if (!levelData) return alert('انتهت المستويات!');
907
 
908
+ // إنشاء بطاقات مزدوجة (صورة + كلمة أمازيغية)
909
  let cards = [];
910
  levelData.items.forEach(item => {
911
+ cards.push({ id: item.id, type: 'image', content: item.imageUrl, alt: item.word });
912
+ cards.push({ id: item.id, type: 'word', content: item.main, alt: item.word });
 
913
  });
914
 
915
  setState({
 
935
  const card1 = newGameData[index1];
936
  const card2 = newGameData[index2];
937
 
938
+ if (card1.id === card2.id) {
 
939
  // Match found
940
  newGameData[index1].isMatched = true;
941
  newGameData[index2].isMatched = true;
 
955
  initMemoryGame();
956
  } else {
957
  alert('تهانينا! لقد أنهيت لعبة الذاكرة بنجاح!');
958
+ setState({ currentGameState: null });
959
  }
960
  }, 800);
961
  }
 
980
  const renderMemoryGame = () => {
981
  if (!appState.gameData) {
982
  initMemoryGame();
983
+ return; // Wait for state update and re-render
984
  }
985
 
986
  const content = document.getElementById('app-content');
987
  const levelData = memoryGameLevels[appState.currentLevel - 1];
988
+ const cols = levelData.pairs <= 4 ? 4 : (levelData.pairs <= 8 ? 4 : 5);
989
+ const gridClass = `grid grid-cols-${cols} gap-2 w-full max-w-sm mx-auto`;
 
 
 
990
 
991
  content.innerHTML = `
992
  <div class="p-4 pt-6 min-h-[calc(100vh-130px)] bg-gray-50 dark:bg-gray-900 transition-colors">
 
994
  لعبة الذاكرة - المستوى ${appState.currentLevel}
995
  </h3>
996
  <p class="text-sm text-gray-600 dark:text-gray-400 mb-4 text-center">
997
+ طابق ${levelData.pairs} أزواج
998
  </p>
999
 
1000
  <div class="${gridClass}" style="grid-template-columns: repeat(${cols}, minmax(0, 1fr));">
 
1006
  ${card.type === 'image' ? `
1007
  <img src="${card.content}" alt="${card.alt}" class="w-full h-full object-cover rounded-md" onerror="this.onerror=null; this.src='https://placehold.co/80x80?text=صورة';"/>
1008
  ` : `
1009
+ <span class="text-3xl font-black text-blue-800 dark:text-white">${card.content}</span>
1010
  `}
1011
  </div>
1012
 
 
1028
  `;
1029
  };
1030
 
1031
+ // --- 8.2 لعبة ترتيب حروف تيفيناغ (Tifinagh Ordering Game) ---
1032
 
1033
+ window.initTifinaghOrderingGame = () => {
1034
+ const levelData = tifinaghOrderingLevels[appState.currentLevel - 1];
1035
  if (!levelData) return alert('انتهت المستويات!');
1036
 
 
1037
  setState({
1038
  gameData: levelData,
1039
+ tifinaghOrderingGame: {
1040
+ userOrder: Array(levelData.letters.length).fill(null),
1041
+ availableLetters: shuffleArray(levelData.letters)
 
1042
  },
1043
+ currentGameState: 'tifinagh_ordering',
1044
  currentLevel: levelData.level,
1045
  });
1046
  };
1047
 
1048
+ window.placeLetter = (letter, slotIndex) => {
1049
+ const newOrder = [...appState.tifinaghOrderingGame.userOrder];
1050
+ const newAvailable = appState.tifinaghOrderingGame.availableLetters.filter(l => l !== letter);
 
 
 
 
1051
 
1052
+ newOrder[slotIndex] = letter;
 
 
1053
 
1054
+ const isCompleted = newAvailable.length === 0;
1055
+
1056
+ setState({
1057
+ tifinaghOrderingGame: { userOrder: newOrder, availableLetters: newAvailable }
1058
+ });
1059
 
1060
+ if (isCompleted) {
1061
+ checkOrderingWin(newOrder);
1062
  }
1063
  };
1064
 
1065
  window.removeLetter = (slotIndex) => {
1066
+ const letter = appState.tifinaghOrderingGame.userOrder[slotIndex];
1067
+ if (!letter) return;
 
1068
 
1069
+ const newOrder = [...appState.tifinaghOrderingGame.userOrder];
1070
+ newOrder[slotIndex] = null;
1071
 
1072
+ const newAvailable = [...appState.tifinaghOrderingGame.availableLetters, letter];
 
 
1073
 
1074
+ setState({
1075
+ tifinaghOrderingGame: { userOrder: newOrder, availableLetters: newAvailable }
1076
+ });
1077
  };
1078
 
1079
+ window.checkOrderingWin = (userOrder) => {
1080
+ const correctOrder = appState.gameData.correctOrder;
1081
+ const isCorrect = userOrder.every((letter, index) => letter === correctOrder[index]);
1082
 
1083
  if (isCorrect) {
1084
  setTimeout(() => {
1085
+ if (appState.currentLevel < tifinaghOrderingLevels.length) {
1086
+ alert(`مذهل! التسلسل صحيح. المستوى ${appState.currentLevel} مكتمل.`);
1087
  setState({ currentLevel: appState.currentLevel + 1 });
1088
+ initTifinaghOrderingGame();
1089
  } else {
1090
+ alert('تهانينا! لقد أتقنت ترتيب حروف تيفيناغ!');
1091
+ setState({ currentGameState: null });
1092
  }
1093
  }, 500);
1094
  } else {
1095
+ alert('حاول مرة أخرى! التسلسل غير صحيح.');
1096
  }
1097
  };
1098
 
1099
 
1100
+ const renderTifinaghOrderingGame = () => {
1101
  if (!appState.gameData) {
1102
+ initTifinaghOrderingGame();
1103
  return;
1104
  }
1105
 
1106
  const content = document.getElementById('app-content');
1107
  const levelData = appState.gameData;
1108
+ const state = appState.tifinaghOrderingGame;
 
 
 
 
1109
 
1110
+ const cols = levelData.letters.length <= 6 ? 6 : 7;
1111
+ const gridClass = `grid grid-cols-${cols} gap-2 w-full mx-auto`;
1112
+
1113
  content.innerHTML = `
1114
  <div class="p-4 pt-6 min-h-[calc(100vh-130px)] bg-gray-50 dark:bg-gray-900 transition-colors">
1115
  <h3 class="text-2xl font-black text-gray-800 dark:text-white mb-2 text-center">
1116
+ ترتيب الحروف - المستوى ${appState.currentLevel}
1117
  </h3>
1118
  <p class="text-sm text-gray-600 dark:text-gray-400 mb-4 text-center">
1119
+ رتّب الحروف التالية بالضغط عليها ثم الضغط على المكان المناسب.
1120
  </p>
1121
 
1122
+ <div class="bg-blue-100 dark:bg-blue-900 p-3 rounded-xl mb-4 text-center max-w-sm mx-auto">
1123
+ <p class="text-xs text-blue-700 dark:text-blue-300 font-bold mb-1">تسلسل الحروف (مساعدة):</p>
1124
+ <div class="flex justify-center flex-wrap gap-2">
1125
+ ${levelData.correctOrder.map(l => `<span class="text-lg font-bold text-blue-800 dark:text-white">${l}</span>`).join('')}
1126
+ </div>
1127
  </div>
1128
+
1129
+
1130
+ <h4 class="text-lg font-bold text-gray-700 dark:text-gray-300 mt-6 mb-2 text-center">مكان الترتيب:</h4>
1131
+ <div class="flex justify-center flex-wrap gap-2 mb-8">
1132
+ ${state.userOrder.map((letter, index) => `
1133
  <button onclick="removeLetter(${index})"
1134
+ class="ordering-slot w-10 h-10 flex items-center justify-center border-2 border-dashed ${letter ? 'border-green-500 bg-green-100 dark:bg-green-900/50' : 'border-gray-400 dark:border-gray-600'} rounded-lg transition-all"
1135
+ aria-label="مكان الحرف رقم ${index + 1}">
1136
+ <span class="text-2xl font-black ${letter ? 'text-green-800 dark:text-white' : 'text-transparent'}">${letter || ''}</span>
1137
  </button>
1138
  `).join('')}
1139
  </div>
1140
 
1141
  <h4 class="text-lg font-bold text-gray-700 dark:text-gray-300 mt-6 mb-2 text-center">الحروف المتاحة:</h4>
1142
+ <div class="flex justify-center flex-wrap gap-2 mb-8">
1143
+ ${state.availableLetters.map((letter, index) => `
1144
+ <button onclick="
1145
+ const slotIndex = appState.tifinaghOrderingGame.userOrder.findIndex(l => l === null);
1146
+ if (slotIndex !== -1) placeLetter('${letter}', slotIndex);
1147
+ "
1148
+ class="ordering-letter w-12 h-12 flex items-center justify-center bg-purple-500 text-white text-3xl font-black rounded-lg shadow-md hover:bg-purple-600"
1149
+ aria-label="الحرف ${letter}">
1150
+ ${letter}
1151
  </button>
1152
  `).join('')}
1153
  </div>
1154
 
1155
  <div class="mt-8 text-center">
1156
+ <button onclick="checkOrderingWin(appState.tifinaghOrderingGame.userOrder)"
1157
  class="px-6 py-3 bg-blue-600 text-white font-bold rounded-xl shadow-lg hover:bg-blue-700 disabled:opacity-50"
1158
+ ${state.availableLetters.length > 0 ? 'disabled' : ''}>
1159
+ تحقق من الترتيب
1160
  </button>
1161
+ <button onclick="initTifinaghOrderingGame()"
1162
  class="px-4 py-2 bg-yellow-500 text-white font-bold rounded-xl shadow-lg hover:bg-yellow-600 mr-2">
1163
  إعادة المستوى
1164
  </button>
 
1166
  </div>
1167
  `;
1168
  };
1169
+
1170
 
1171
+ // --- 9. دالة الرسم الرئيسية والتهيئة ---
1172
+
1173
  const renderApp = () => {
 
1174
  const screen = appState.currentScreen;
1175
  const content = document.getElementById('app-content');
1176
  const header = document.getElementById('app-header');
1177
  const footer = document.getElementById('app-footer');
1178
 
1179
+ // التحكم في عرض الـ Header و الـ Footer
1180
  const shouldShowNav = screen !== 'welcome';
1181
  header.style.display = shouldShowNav ? 'block' : 'none';
1182
  footer.style.display = shouldShowNav ? 'block' : 'none';
 
1184
  if (shouldShowNav) {
1185
  renderHeader();
1186
  renderFooter();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1187
  }
1188
 
1189
+ // تحديد محتوى الشاشة
1190
+ if (screen === 'welcome') {
1191
+ renderWelcomeScreen();
1192
+ content.style.paddingTop = '0';
1193
+ content.style.paddingBottom = '0';
1194
+ } else if (screen === 'home' || screen === 'profile') {
1195
+ content.style.paddingTop = shouldShowNav ? '4rem' : '0';
1196
+ content.style.paddingBottom = shouldShowNav ? '5rem' : '0';
1197
+ renderHomeScreen();
1198
+ } else if (screen === 'settings') {
1199
+ content.style.paddingTop = shouldShowNav ? '4rem' : '0';
1200
+ content.style.paddingBottom = shouldShowNav ? '5rem' : '0';
1201
+ renderSettingsScreen();
1202
+ } else if (screen === 'info') {
1203
+ content.style.paddingTop = shouldShowNav ? '4rem' : '0';
1204
+ content.style.paddingBottom = shouldShowNav ? '5rem' : '0';
1205
+ renderInfoScreen();
1206
+ } else if (screen === 'appDefinition') {
1207
+ content.style.paddingTop = shouldShowNav ? '4rem' : '0';
1208
+ content.style.paddingBottom = shouldShowNav ? '5rem' : '0';
1209
+ renderAppDefinitionScreen();
1210
+ } else if (screen === 'games') {
1211
  content.style.paddingTop = shouldShowNav ? '4rem' : '0';
1212
  content.style.paddingBottom = shouldShowNav ? '5rem' : '0';
1213
  if (appState.currentGameState === 'memory') {
1214
  renderMemoryGame();
1215
+ } else if (appState.currentGameState === 'tifinagh_ordering') {
1216
+ renderTifinaghOrderingGame();
1217
  } else {
1218
  renderGamesHome();
1219
  }
1220
+ } else if (CATEGORIES.some(c => c.id === screen)) {
1221
+ content.style.paddingTop = shouldShowNav ? '4rem' : '0';
1222
+ content.style.paddingBottom = shouldShowNav ? '5rem' : '0';
1223
+ renderLearningScreen();
1224
  } else {
1225
+ content.innerHTML = `
1226
+ <div class="p-8 min-h-[calc(100vh-130px)] flex flex-col items-center justify-center bg-gray-50 dark:bg-gray-900 transition-colors">
1227
+ <p class="text-xl font-bold text-purple-600 dark:text-purple-400 mb-4">هذا القسم قيد الإنشاء!</p>
1228
+ <button onclick="setState({currentScreen: 'home', selectedCategory: null, currentGameState: null})"
1229
+ class="px-6 py-3 bg-purple-600 text-white font-bold rounded-xl shadow-lg hover:bg-purple-700 card-shadow">
1230
+ العودة للرئيسية
1231
+ </button>
1232
+ </div>
1233
+ `;
1234
+ }
1235
+
1236
+ // إدارة الـ Menu Overlay
1237
+ const existingMenu = document.getElementById('menu-overlay');
1238
+ const appContainer = document.getElementById('app-container');
1239
+
1240
+ if (appState.isMenuOpen) {
1241
+ if (!existingMenu) {
1242
+ const menuHTML = renderMenu();
1243
+ appContainer.insertAdjacentHTML('afterend', menuHTML);
1244
+ }
1245
+ } else if (existingMenu) {
1246
+ existingMenu.remove();
1247
  }
1248
  };
1249
+
1250
+ // --- 8. القائمة الجانبية (Menu) ---
1251
+ const renderMenu = () => {
1252
+ if (!appState.isMenuOpen) return '';
1253
 
1254
+ const cardsHTML = CATEGORIES.map(category => `
1255
+ <button
1256
+ onclick="setState({currentScreen: '${category.id}', selectedCategory: '${category.id}', isMenuOpen: false})"
1257
+ class="relative w-full h-24 rounded-xl overflow-hidden card-shadow group text-right"
1258
+ aria-label="الذهاب إلى قسم ${category.title}"
1259
+ >
1260
+ <div class="absolute inset-0" style="background-image: url('${category.imageUrl}'); background-size: cover; background-position: center;">
1261
+ <div class="absolute inset-0 bg-blue-900/70 p-3 flex items-center gap-3 transition-all group-hover:bg-blue-800/80">
1262
+ <div class="p-2 bg-white/20 rounded-lg">
1263
+ ${renderIcon(category.iconName, 'w-6 h-6 text-white')}
1264
+ </div>
1265
+ <div class="mr-3 text-right text-white">
1266
+ <span class="text-lg font-black leading-tight drop-shadow-md">${category.title}</span>
1267
+ <span class="text-xs opacity-80 mt-1 block">${category.subtitle}</span>
1268
+ </div>
1269
+ </div>
1270
+ </div>
1271
+ </button>
1272
+ `).join('');
1273
+
1274
+ return `
1275
+ <div id="menu-overlay"
1276
+ class="fixed inset-0 z-30 bg-black/50 transition-opacity duration-300"
1277
+ onclick="toggleMenu()">
1278
+
1279
+ <div class="absolute top-0 right-0 h-full w-full max-w-sm bg-gray-50 dark:bg-gray-800 shadow-2xl overflow-y-auto transform transition-transform duration-300 translate-x-0"
1280
+ onclick="event.stopPropagation()">
1281
+
1282
+ <div class="p-4 pt-16 border-b border-gray-200 dark:border-gray-700 bg-blue-800 dark:bg-gray-900 text-white rounded-bl-3xl">
1283
+ <h3 class="text-2xl font-black">جميع الأقسام</h3>
1284
+ <p class="text-sm opacity-80 mt-1">اختر ما تريد تعلمه الآن:</p>
1285
+ </div>
1286
+
1287
+ <div class="p-4 grid grid-cols-1 gap-3 hide-scrollbar">
1288
+ ${cardsHTML}
1289
+ </div>
1290
+ <div class="p-4">
1291
+ <button onclick="toggleMenu()" class="w-full py-3 bg-red-500 text-white font-bold rounded-xl shadow-lg">إغلاق القائمة</button>
1292
+ </div>
1293
+ </div>
1294
+ </div>
1295
+ `;
1296
+ };
1297
+
1298
+
1299
+ // تهيئة التطبيق عند تحميل النافذة
1300
  window.onload = () => {
1301
+ renderApp();
 
 
1302
  };
1303
 
1304
  </script>