Docfile commited on
Commit
78cec43
verified
1 Parent(s): 5212392

Create templates/index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +510 -0
templates/index.html ADDED
@@ -0,0 +1,510 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="fr">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Mariam AI - Assistant Fran莽ais Intelligent</title>
7
+ <!-- Tailwind CSS, Font Awesome, Marked et MathJax -->
8
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/tailwindcss/dist/tailwind.min.css">
9
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
10
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/marked/4.0.2/marked.min.js"></script>
11
+ <script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
12
+
13
+ <style>
14
+ @import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@300;400;500;600;700&display=swap');
15
+
16
+ body {
17
+ font-family: 'Plus Jakarta Sans', sans-serif;
18
+ background-color: #fafafa;
19
+ }
20
+
21
+ /* Effet de Glassmorphism */
22
+ .glassmorphism {
23
+ background: rgba(255, 255, 255, 0.95);
24
+ backdrop-filter: blur(10px);
25
+ border: 1px solid rgba(255, 255, 255, 0.3);
26
+ }
27
+
28
+ /* Effet hover sur les cartes */
29
+ .card-hover {
30
+ transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
31
+ }
32
+ .card-hover:hover {
33
+ transform: translateY(-4px);
34
+ box-shadow: 0 12px 24px rgba(0, 0, 0, 0.08);
35
+ }
36
+
37
+ /* Texte en d茅grad茅 */
38
+ .gradient-text {
39
+ background: linear-gradient(135deg, #1a365d 0%, #3182ce 100%);
40
+ -webkit-background-clip: text;
41
+ -webkit-text-fill-color: transparent;
42
+ }
43
+
44
+ /* Animation des points de chargement */
45
+ .loading-dot {
46
+ animation: bounce 1.4s infinite;
47
+ }
48
+ .loading-dot:nth-child(2) { animation-delay: 0.2s; }
49
+ .loading-dot:nth-child(3) { animation-delay: 0.4s; }
50
+ @keyframes bounce {
51
+ 0%, 80%, 100% { transform: translateY(0); }
52
+ 40% { transform: translateY(-6px); }
53
+ }
54
+
55
+ /* Bouton radio personnalis茅 */
56
+ .custom-radio:checked + span {
57
+ background: linear-gradient(135deg, #1a365d 0%, #3182ce 100%);
58
+ color: white;
59
+ }
60
+
61
+ /* Styles pour les sauvegardes */
62
+ .backup-item {
63
+ cursor: pointer;
64
+ }
65
+ .backup-content {
66
+ display: none;
67
+ margin-top: 10px;
68
+ }
69
+ .backup-content-expanded {
70
+ display: block;
71
+ }
72
+
73
+ /* Pr茅visualisation d'images */
74
+ .image-preview {
75
+ display: flex;
76
+ flex-wrap: wrap;
77
+ gap: 10px;
78
+ margin-top: 10px;
79
+ }
80
+ .image-preview-item {
81
+ position: relative;
82
+ width: 100px;
83
+ height: 100px;
84
+ }
85
+ .image-preview-item img {
86
+ width: 100%;
87
+ height: 100%;
88
+ object-fit: cover;
89
+ border-radius: 5px;
90
+ }
91
+ .remove-image {
92
+ position: absolute;
93
+ top: 5px;
94
+ right: 5px;
95
+ background-color: rgba(0, 0, 0, 0.5);
96
+ color: white;
97
+ border: none;
98
+ border-radius: 50%;
99
+ padding: 2px 6px;
100
+ cursor: pointer;
101
+ font-size: 12px;
102
+ }
103
+ .remove-image:hover {
104
+ background-color: rgba(0, 0, 0, 0.7);
105
+ }
106
+
107
+ /* Pr茅server les espaces dans le markdown */
108
+ .prose {
109
+ white-space: pre-wrap;
110
+ word-wrap: break-word;
111
+ overflow-wrap: break-word;
112
+ }
113
+ @media (max-width: 640px) {
114
+ .prose {
115
+ font-size: 0.95rem;
116
+ line-height: 1.6;
117
+ }
118
+ }
119
+ </style>
120
+ </head>
121
+ <body class="min-h-screen bg-gradient-to-br from-blue-50 via-white to-blue-50">
122
+ <header>
123
+ <nav class="glassmorphism sticky top-0 z-50 border-b border-blue-100">
124
+ <div class="container mx-auto px-6 py-4">
125
+ <div class="flex items-center justify-between">
126
+ <div class="flex items-center space-x-4">
127
+ <div class="bg-blue-600 rounded-lg p-2 shadow-lg">
128
+ <i class="fas fa-robot text-white text-xl"></i>
129
+ </div>
130
+ <h1 class="text-2xl font-bold gradient-text">Mariam AI</h1>
131
+ </div>
132
+ <div class="text-blue-900 font-medium">Assistant Fran莽ais Intelligent</div>
133
+ </div>
134
+ </div>
135
+ </nav>
136
+ </header>
137
+
138
+ <main class="container mx-auto px-6 py-12">
139
+ <div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
140
+ <!-- Section Travail Argumentatif -->
141
+ <section class="card-hover glassmorphism rounded-2xl overflow-hidden">
142
+ <div class="p-8">
143
+ <div class="flex items-center space-x-4 mb-8">
144
+ <div class="bg-blue-100 rounded-lg p-3">
145
+ <i class="fas fa-pen-fancy text-blue-600 text-xl"></i>
146
+ </div>
147
+ <h2 class="text-2xl font-bold text-gray-800">Travail Argumentatif</h2>
148
+ </div>
149
+ <form id="francais-form" class="space-y-8">
150
+ <div class="space-y-3">
151
+ <label for="sujet-francais" class="block text-sm font-medium text-gray-700">
152
+ <i class="fas fa-book-open mr-2 text-blue-500"></i>Sujet
153
+ </label>
154
+ <textarea id="sujet-francais" name="sujet" rows="4" class="w-full px-4 py-3 rounded-xl border-2 border-gray-200 focus:border-blue-500 focus:ring-2 focus:ring-blue-200 transition-all duration-200 resize-none" placeholder="Entrez votre sujet ici..."></textarea>
155
+ </div>
156
+
157
+ <div class="space-y-4">
158
+ <label class="block text-sm font-medium text-gray-700">
159
+ <i class="fas fa-tasks mr-2 text-blue-500"></i>Type d'argumentation
160
+ </label>
161
+ <div class="grid grid-cols-3 gap-4">
162
+ <label class="relative">
163
+ <input type="radio" name="choix" value="Etaye" class="custom-radio absolute opacity-0 w-full h-full cursor-pointer" checked>
164
+ <span class="flex items-center justify-center p-3 border-2 border-gray-200 rounded-xl text-sm font-medium transition-all duration-200 hover:border-blue-400">脡tayer</span>
165
+ </label>
166
+ <label class="relative">
167
+ <input type="radio" name="choix" value="refute" class="custom-radio absolute opacity-0 w-full h-full cursor-pointer">
168
+ <span class="flex items-center justify-center p-3 border-2 border-gray-200 rounded-xl text-sm font-medium transition-all duration-200 hover:border-blue-400">R茅futer</span>
169
+ </label>
170
+ <label class="relative">
171
+ <input type="radio" name="choix" value="discuter" class="custom-radio absolute opacity-0 w-full h-full cursor-pointer">
172
+ <span class="flex items-center justify-center p-3 border-2 border-gray-200 rounded-xl text-sm font-medium transition-all duration-200 hover:border-blue-400">Discuter</span>
173
+ </label>
174
+ </div>
175
+ </div>
176
+
177
+ <div class="space-y-4">
178
+ <label class="block text-sm font-medium text-gray-700">
179
+ <i class="fas fa-feather-alt mr-2 text-blue-500"></i>Style d'茅criture
180
+ </label>
181
+ <div class="grid grid-cols-2 gap-4">
182
+ <label class="relative">
183
+ <input type="radio" name="style" value="raffin茅" class="custom-radio absolute opacity-0 w-full h-full cursor-pointer" checked>
184
+ <span class="flex items-center justify-center p-3 border-2 border-gray-200 rounded-xl text-sm font-medium transition-all duration-200 hover:border-blue-400">Raffin茅</span>
185
+ </label>
186
+ <label class="relative">
187
+ <input type="radio" name="style" value="Normal" class="custom-radio absolute opacity-0 w-full h-full cursor-pointer">
188
+ <span class="flex items-center justify-center p-3 border-2 border-gray-200 rounded-xl text-sm font-medium transition-all duration-200 hover:border-blue-400">Normal</span>
189
+ </label>
190
+ </div>
191
+ </div>
192
+
193
+ <button type="submit" class="w-full bg-gradient-to-r from-blue-600 to-blue-800 text-white px-6 py-4 rounded-xl font-medium hover:from-blue-700 hover:to-blue-900 transition-all duration-300 transform hover:scale-[1.02] active:scale-[0.98] shadow-lg">
194
+ <div class="flex items-center justify-center space-x-3">
195
+ <i class="fas fa-magic"></i>
196
+ <span>G茅n茅rer</span>
197
+ </div>
198
+ </button>
199
+ </form>
200
+ <div id="francais-output" class="mt-8 p-6 bg-blue-50 rounded-xl prose max-w-none">
201
+ <!-- Le contenu g茅n茅r茅 sera ins茅r茅 ici -->
202
+ </div>
203
+ </div>
204
+ </section>
205
+
206
+ <!-- Section 脡tude de texte -->
207
+ <section class="card-hover glassmorphism rounded-2xl overflow-hidden">
208
+ <div class="p-8">
209
+ <div class="flex items-center space-x-4 mb-8">
210
+ <div class="bg-blue-100 rounded-lg p-3">
211
+ <i class="fas fa-file-alt text-blue-600 text-xl"></i>
212
+ </div>
213
+ <h2 class="text-2xl font-bold text-gray-800">脡tude de texte</h2>
214
+ </div>
215
+ <form id="etude-texte-form" class="space-y-8" enctype="multipart/form-data">
216
+ <div class="space-y-4">
217
+ <label class="block text-sm font-medium text-gray-700">
218
+ <i class="fas fa-image mr-2 text-blue-500"></i>Image du texte
219
+ </label>
220
+ <div class="border-3 border-dashed border-gray-300 rounded-xl p-8 text-center cursor-pointer hover:border-blue-400 transition-all duration-200" id="drop-zone">
221
+ <input type="file" id="image-upload" name="images" accept="image/*" class="hidden" multiple>
222
+ <div class="space-y-3">
223
+ <div class="bg-blue-50 rounded-full w-16 h-16 flex items-center justify-center mx-auto">
224
+ <i class="fas fa-cloud-upload-alt text-3xl text-blue-500"></i>
225
+ </div>
226
+ <p class="text-sm text-gray-600 font-medium">Glissez vos images ici ou cliquez pour s茅lectionner</p>
227
+ <p class="text-xs text-gray-400">PNG, JPG jusqu'脿 10MB</p>
228
+ </div>
229
+ </div>
230
+ <div id="image-preview" class="image-preview"></div>
231
+ </div>
232
+
233
+ <button type="submit" class="w-full bg-gradient-to-r from-blue-600 to-blue-800 text-white px-6 py-4 rounded-xl font-medium hover:from-blue-700 hover:to-blue-900 transition-all duration-300 transform hover:scale-[1.02] active:scale-[0.98] shadow-lg">
234
+ <div class="flex items-center justify-center space-x-3">
235
+ <i class="fas fa-search"></i>
236
+ <span>Analyser</span>
237
+ </div>
238
+ </button>
239
+ </form>
240
+ <div id="etude-texte-output" class="mt-8 p-6 bg-blue-50 rounded-xl prose max-w-none">
241
+ <!-- Le contenu analys茅 sera ins茅r茅 ici -->
242
+ </div>
243
+ </div>
244
+ </section>
245
+ </div>
246
+
247
+ <!-- Section Sauvegardes -->
248
+ <section class="mt-12">
249
+ <h2 class="text-2xl font-bold text-gray-800 mb-4">Sauvegardes</h2>
250
+ <div id="backups-list" class="space-y-4">
251
+ <!-- Les sauvegardes seront list茅es ici -->
252
+ </div>
253
+ </section>
254
+ </main>
255
+
256
+ <script>
257
+ // Gestion de l'upload d'images
258
+ function initializeFileUpload() {
259
+ const dropZone = document.getElementById('drop-zone');
260
+ const fileInput = document.getElementById('image-upload');
261
+ const imagePreview = document.getElementById('image-preview');
262
+
263
+ dropZone.addEventListener('click', () => fileInput.click());
264
+
265
+ ['dragenter', 'dragover'].forEach(eventName => {
266
+ dropZone.addEventListener(eventName, (e) => {
267
+ e.preventDefault();
268
+ dropZone.classList.add('border-blue-500', 'bg-blue-50');
269
+ });
270
+ });
271
+
272
+ ['dragleave', 'drop'].forEach(eventName => {
273
+ dropZone.addEventListener(eventName, (e) => {
274
+ e.preventDefault();
275
+ dropZone.classList.remove('border-blue-500', 'bg-blue-50');
276
+ });
277
+ });
278
+
279
+ dropZone.addEventListener('drop', (e) => {
280
+ e.preventDefault();
281
+ const files = e.dataTransfer.files;
282
+ handleFiles(files);
283
+ });
284
+
285
+ fileInput.addEventListener('change', () => {
286
+ handleFiles(fileInput.files);
287
+ });
288
+
289
+ function handleFiles(files) {
290
+ Array.from(files).forEach(file => {
291
+ if (!file.type.startsWith('image/')) return;
292
+ const reader = new FileReader();
293
+ reader.onload = (e) => {
294
+ const previewItem = document.createElement('div');
295
+ previewItem.classList.add('image-preview-item');
296
+ previewItem.innerHTML = `
297
+ <img src="${e.target.result}" alt="${file.name}">
298
+ <button class="remove-image" title="Supprimer">脳</button>
299
+ `;
300
+ imagePreview.appendChild(previewItem);
301
+ previewItem.querySelector('.remove-image').addEventListener('click', () => {
302
+ imagePreview.removeChild(previewItem);
303
+ });
304
+ };
305
+ reader.readAsDataURL(file);
306
+ });
307
+ }
308
+ }
309
+
310
+ // Sauvegarde et affichage des r茅ponses dans le localStorage
311
+ function sauvegarderReponse(titre, contenu) {
312
+ const sauvegardes = JSON.parse(localStorage.getItem('mariam_ai_sauvegardes') || '[]');
313
+ const dateSauvegarde = new Date().toISOString();
314
+ sauvegardes.push({ titre, contenu, date: dateSauvegarde });
315
+ localStorage.setItem('mariam_ai_sauvegardes', JSON.stringify(sauvegardes));
316
+ afficherSauvegardes();
317
+ }
318
+
319
+ function supprimerSauvegarde(index) {
320
+ let sauvegardes = JSON.parse(localStorage.getItem('mariam_ai_sauvegardes') || '[]');
321
+ sauvegardes.splice(index, 1);
322
+ localStorage.setItem('mariam_ai_sauvegardes', JSON.stringify(sauvegardes));
323
+ afficherSauvegardes();
324
+ }
325
+
326
+ function afficherSauvegardes() {
327
+ const sauvegardes = JSON.parse(localStorage.getItem('mariam_ai_sauvegardes') || '[]');
328
+ const backupsList = document.getElementById('backups-list');
329
+ backupsList.innerHTML = sauvegardes.length === 0
330
+ ? '<p class="text-gray-600">Aucune sauvegarde pour le moment.</p>'
331
+ : '';
332
+
333
+ sauvegardes.forEach((sauvegarde, index) => {
334
+ const sauvegardeDiv = document.createElement('div');
335
+ sauvegardeDiv.className = 'bg-white rounded-lg shadow-md p-4 relative backup-item';
336
+ sauvegardeDiv.innerHTML = `
337
+ <h3 class="text-lg font-semibold text-gray-800">${sauvegarde.titre}</h3>
338
+ <p class="text-sm text-gray-600 mb-2">${new Date(sauvegarde.date).toLocaleString()}</p>
339
+ <div class="text-sm text-gray-700 backup-content prose max-w-none">${marked.parse(sauvegarde.contenu)}</div>
340
+ <button class="absolute top-2 right-2 text-red-500 hover:text-red-700 focus:outline-none" data-index="${index}">
341
+ <i class="fas fa-trash"></i>
342
+ </button>
343
+ `;
344
+ backupsList.appendChild(sauvegardeDiv);
345
+
346
+ // Toggle du contenu lors d'un clic sur la sauvegarde (hors bouton de suppression)
347
+ const backupContentDiv = sauvegardeDiv.querySelector('.backup-content');
348
+ sauvegardeDiv.addEventListener('click', (e) => {
349
+ if (e.target.tagName === "BUTTON") return;
350
+ backupContentDiv.classList.toggle('backup-content-expanded');
351
+ MathJax.typesetPromise([backupContentDiv]);
352
+ });
353
+
354
+ sauvegardeDiv.querySelector('button').addEventListener('click', () => {
355
+ if (confirm('脢tes-vous s没r de vouloir supprimer cette sauvegarde ?')) {
356
+ supprimerSauvegarde(index);
357
+ }
358
+ });
359
+ });
360
+ }
361
+
362
+ // Gestion des formulaires
363
+ function submitFrancaisForm() {
364
+ const form = document.getElementById('francais-form');
365
+ const output = document.getElementById('francais-output');
366
+
367
+ form.addEventListener('submit', async (e) => {
368
+ e.preventDefault();
369
+ output.innerHTML = `
370
+ <div class="flex items-center justify-center space-x-2 text-blue-600">
371
+ <div class="loading-dot">[x]</div>
372
+ <div class="loading-dot">[x]</div>
373
+ <div class="loading-dot">[x]</div>
374
+ <span class="ml-3 text-sm font-medium text-gray-600">G茅n茅ration en cours...</span>
375
+ </div>`;
376
+
377
+ const formData = new FormData(form);
378
+ try {
379
+ const response = await fetch('/api/francais', { method: 'POST', body: formData });
380
+ const result = await response.json();
381
+ output.innerHTML = marked.parse(result.output);
382
+ sauvegarderReponse(formData.get('sujet'), result.output);
383
+ MathJax.typesetPromise([output]);
384
+ } catch (error) {
385
+ output.innerHTML = `
386
+ <div class="flex items-center space-x-2 text-red-500 bg-red-50 p-4 rounded-lg">
387
+ <i class="fas fa-exclamation-circle"></i>
388
+ <span class="text-sm font-medium">Une erreur est survenue. Veuillez r茅essayer.</span>
389
+ </div>`;
390
+ }
391
+ });
392
+ }
393
+
394
+ function submitEtudeTexteForm() {
395
+ const form = document.getElementById('etude-texte-form');
396
+ const output = document.getElementById('etude-texte-output');
397
+
398
+ form.addEventListener('submit', async (e) => {
399
+ e.preventDefault();
400
+ output.innerHTML = `
401
+ <div class="flex items-center justify-center space-x-2 text-blue-600">
402
+ <div class="loading-dot">[x]</div>
403
+ <div class="loading-dot">[x]</div>
404
+ <div class="loading-dot">[x]</div>
405
+ <span class="ml-3 text-sm font-medium text-gray-600">Analyse en cours...</span>
406
+ </div>`;
407
+
408
+ const formData = new FormData(form);
409
+ try {
410
+ const response = await fetch('/api/etude-texte', { method: 'POST', body: formData });
411
+ const result = await response.json();
412
+ output.innerHTML = marked.parse(result.output);
413
+ const titre = "Analyse d'image " + new Date().toLocaleString();
414
+ sauvegarderReponse(titre, result.output);
415
+ MathJax.typesetPromise([output]);
416
+ } catch (error) {
417
+ output.innerHTML = `
418
+ <div class="flex items-center space-x-2 text-red-500 bg-red-50 p-4 rounded-lg">
419
+ <i class="fas fa-exclamation-circle"></i>
420
+ <span class="text-sm font-medium">Une erreur est survenue. Veuillez r茅essayer.</span>
421
+ </div>`;
422
+ }
423
+ });
424
+ }
425
+
426
+ // Effets d'animation et d'interaction
427
+ function animateOnScroll() {
428
+ const cards = document.querySelectorAll('.card-hover');
429
+ const observer = new IntersectionObserver((entries) => {
430
+ entries.forEach(entry => {
431
+ if (entry.isIntersecting) {
432
+ entry.target.style.opacity = '1';
433
+ entry.target.style.transform = 'translateY(0)';
434
+ }
435
+ });
436
+ }, { threshold: 0.1 });
437
+
438
+ cards.forEach(card => {
439
+ card.style.opacity = '0';
440
+ card.style.transform = 'translateY(20px)';
441
+ card.style.transition = 'all 0.6s cubic-bezier(0.4, 0, 0.2, 1)';
442
+ observer.observe(card);
443
+ });
444
+ }
445
+
446
+ function enhanceTextareaFocus() {
447
+ document.querySelectorAll('textarea').forEach(textarea => {
448
+ textarea.addEventListener('focus', () => {
449
+ textarea.parentElement.classList.add('ring-2', 'ring-blue-200');
450
+ });
451
+ textarea.addEventListener('blur', () => {
452
+ textarea.parentElement.classList.remove('ring-2', 'ring-blue-200');
453
+ });
454
+ });
455
+ }
456
+
457
+ function enhanceRadioButtons() {
458
+ document.querySelectorAll('input[type="radio"] + span').forEach(label => {
459
+ label.addEventListener('mouseenter', () => {
460
+ if (!label.previousElementSibling.checked) {
461
+ label.style.borderColor = '#3182ce';
462
+ }
463
+ });
464
+ label.addEventListener('mouseleave', () => {
465
+ if (!label.previousElementSibling.checked) {
466
+ label.style.borderColor = '#e5e7eb';
467
+ }
468
+ });
469
+ });
470
+ }
471
+
472
+ // Message de bienvenue (optionnel)
473
+ function showWelcomeMessage() {
474
+ const welcomeMessage = document.createElement('div');
475
+ welcomeMessage.innerHTML = `
476
+ <div class="fixed bottom-6 right-6 bg-white rounded-xl shadow-lg p-4 transform transition-all duration-500 opacity-0 translate-y-4">
477
+ <div class="flex items-center space-x-3">
478
+ <div class="bg-blue-100 rounded-lg p-2">
479
+ <i class="fas fa-robot text-blue-600"></i>
480
+ </div>
481
+ <div>
482
+ <p class="text-sm font-medium text-gray-800">Bienvenue sur Mariam AI</p>
483
+ <p class="text-xs text-gray-500">Je suis l脿 pour vous aider</p>
484
+ </div>
485
+ </div>
486
+ </div>`;
487
+ document.body.appendChild(welcomeMessage);
488
+ setTimeout(() => {
489
+ welcomeMessage.firstElementChild.classList.remove('opacity-0', 'translate-y-4');
490
+ }, 1000);
491
+ setTimeout(() => {
492
+ welcomeMessage.firstElementChild.classList.add('opacity-0', 'translate-y-4');
493
+ setTimeout(() => welcomeMessage.remove(), 500);
494
+ }, 5000);
495
+ }
496
+
497
+ // Initialisation au chargement du DOM
498
+ document.addEventListener('DOMContentLoaded', () => {
499
+ initializeFileUpload();
500
+ submitFrancaisForm();
501
+ submitEtudeTexteForm();
502
+ animateOnScroll();
503
+ enhanceTextareaFocus();
504
+ enhanceRadioButtons();
505
+ showWelcomeMessage();
506
+ afficherSauvegardes();
507
+ });
508
+ </script>
509
+ </body>
510
+ </html>