wasmdashai commited on
Commit
35daacf
·
verified ·
1 Parent(s): c784037

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +699 -106
index.html CHANGED
@@ -3,20 +3,20 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>VoiceBridge - Saudi Dialect Speech Translator</title>
7
  <script src="https://cdn.tailwindcss.com"></script>
8
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
  <style>
10
- @import url('https://fonts.googleapis.com/css2?family=Tajawal:wght@400;500;700&family=Poppins:wght@300;400;500;600;700&display=swap');
11
 
12
  body {
13
- font-family: 'Poppins', 'Tajawal', sans-serif;
14
  background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
15
  min-height: 100vh;
16
  }
17
 
18
  .gradient-bg {
19
- background: linear-gradient(135deg, #1e3a8a 0%, #1e40af 100%);
20
  }
21
 
22
  .wave-animation {
@@ -43,15 +43,15 @@
43
  @keyframes pulse {
44
  0% {
45
  transform: scale(0.95);
46
- box-shadow: 0 0 0 0 rgba(30, 58, 138, 0.7);
47
  }
48
  70% {
49
  transform: scale(1);
50
- box-shadow: 0 0 0 10px rgba(30, 58, 138, 0);
51
  }
52
  100% {
53
  transform: scale(0.95);
54
- box-shadow: 0 0 0 0 rgba(30, 58, 138, 0);
55
  }
56
  }
57
 
@@ -74,7 +74,7 @@
74
 
75
  .voice-bar {
76
  width: 4px;
77
- background-color: #1e3a8a;
78
  border-radius: 3px;
79
  animation: equalize 1.5s infinite ease-in-out;
80
  }
@@ -99,21 +99,6 @@
99
  transform: translateY(-5px);
100
  box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
101
  }
102
-
103
- .rtl-text {
104
- direction: rtl;
105
- text-align: right;
106
- font-family: 'Tajawal', sans-serif;
107
- }
108
-
109
- .dialect-badge {
110
- background-color: #fef3c7;
111
- color: #92400e;
112
- font-size: 0.75rem;
113
- padding: 0.25rem 0.5rem;
114
- border-radius: 9999px;
115
- margin-left: 0.5rem;
116
- }
117
  </style>
118
  </head>
119
  <body class="min-h-screen flex flex-col">
@@ -126,15 +111,15 @@
126
  <h1 class="text-2xl md:text-3xl font-bold">VoiceBridge</h1>
127
  </div>
128
  <div class="flex items-center space-x-4">
129
- <button class="bg-white text-blue-900 px-4 py-2 rounded-full font-medium hover:bg-blue-50 transition">
130
  <i class="fas fa-cog mr-2"></i>Settings
131
  </button>
132
  </div>
133
  </div>
134
 
135
  <div class="mt-12 mb-16 text-center">
136
- <h2 class="text-3xl md:text-4xl font-bold mb-4">Saudi Dialect Speech Translator</h2>
137
- <p class="text-xl opacity-90 max-w-2xl mx-auto">AI-powered translation with support for Saudi dialects and regional accents</p>
138
  </div>
139
  </div>
140
  </header>
@@ -150,13 +135,13 @@
150
  <div class="flex items-center space-x-2">
151
  <span class="text-sm text-gray-500">Input Language:</span>
152
  <select id="inputLanguage" class="border rounded px-3 py-1 text-sm">
153
- <option value="ar-SA">Arabic (Standard)</option>
154
- <option value="ar-SA-najdi">Arabic (Najdi)</option>
155
- <option value="ar-SA-hejazi">Arabic (Hejazi)</option>
156
- <option value="ar-SA-gulf">Arabic (Gulf)</option>
157
  <option value="en-US">English</option>
158
- <option value="fr-FR">French</option>
159
  <option value="es-ES">Spanish</option>
 
 
 
 
 
160
  </select>
161
  </div>
162
  </div>
@@ -170,7 +155,7 @@
170
  <div class="voice-bar"></div>
171
  </div>
172
 
173
- <button id="startListening" class="bg-blue-900 text-white rounded-full p-4 pulse hover:bg-blue-800 transition">
174
  <i class="fas fa-microphone text-2xl"></i>
175
  </button>
176
 
@@ -192,13 +177,13 @@
192
  <div class="flex items-center space-x-2">
193
  <span class="text-sm text-gray-500">Output Language:</span>
194
  <select id="outputLanguage" class="border rounded px-3 py-1 text-sm">
195
- <option value="ar-SA">Arabic (Standard)</option>
196
- <option value="ar-SA-najdi">Arabic (Najdi)</option>
197
- <option value="ar-SA-hejazi">Arabic (Hejazi)</option>
198
- <option value="ar-SA-gulf">Arabic (Gulf)</option>
199
  <option value="en-US">English</option>
200
- <option value="fr-FR">French</option>
201
  <option value="es-ES">Spanish</option>
 
 
 
 
 
202
  </select>
203
  </div>
204
  </div>
@@ -212,14 +197,14 @@
212
 
213
  <div class="bg-gray-50 rounded-lg p-6 text-center">
214
  <div id="voiceOutputVisualizer" class="voice-visualizer mb-6 opacity-0">
215
- <div class="voice-bar bg-blue-700"></div>
216
- <div class="voice-bar bg-blue-700"></div>
217
- <div class="voice-bar bg-blue-700"></div>
218
- <div class="voice-bar bg-blue-700"></div>
219
- <div class="voice-bar bg-blue-700"></div>
220
  </div>
221
 
222
- <button id="playTranslation" class="bg-blue-900 text-white rounded-full px-6 py-3 hover:bg-blue-800 transition disabled:opacity-50" disabled>
223
  <i class="fas fa-volume-up mr-2"></i> Play Translation
224
  </button>
225
  </div>
@@ -239,7 +224,7 @@
239
  <button id="saveSession" class="bg-white border border-gray-300 rounded-full px-4 py-2 text-sm hover:bg-gray-50 transition">
240
  <i class="fas fa-save mr-2"></i> Save
241
  </button>
242
- <button id="shareTranslation" class="bg-blue-900 text-white rounded-full px-4 py-2 text-sm hover:bg-blue-800 transition">
243
  <i class="fas fa-share-alt mr-2"></i> Share
244
  </button>
245
  </div>
@@ -252,65 +237,561 @@
252
  <div class="grid md:grid-cols-2 lg:grid-cols-3 gap-4">
253
  <div class="bg-white rounded-lg p-4 shadow border border-gray-100">
254
  <div class="flex justify-between items-start mb-2">
255
- <span class="text-sm font-medium text-blue-900 bg-blue-50 px-2 py-1 rounded">NajdiEnglish <span class="dialect-badge">Saudi</span></span>
256
  <span class="text-xs text-gray-500">2 min ago</span>
257
  </div>
258
- <p class="rtl-text text-gray-700 mb-2">وش السالفة؟</p>
259
- <p class="text-gray-900 font-medium">What's up?</p>
260
  </div>
261
 
262
  <div class="bg-white rounded-lg p-4 shadow border border-gray-100">
263
  <div class="flex justify-between items-start mb-2">
264
- <span class="text-sm font-medium text-blue-900 bg-blue-50 px-2 py-1 rounded">HejaziFrench <span class="dialect-badge">Saudi</span></span>
265
  <span class="text-xs text-gray-500">15 min ago</span>
266
  </div>
267
- <p class="rtl-text text-gray-700 mb-2">وين المحل هذا؟</p>
268
- <p class="text-gray-900 font-medium"> est ce magasin?</p>
269
  </div>
270
 
271
  <div class="bg-white rounded-lg p-4 shadow border border-gray-100 hidden md:block">
272
  <div class="flex justify-between items-start mb-2">
273
- <span class="text-sm font-medium text-blue-900 bg-blue-50 px-2 py-1 rounded">EnglishGulf <span class="dialect-badge">Saudi</span></span>
274
  <span class="text-xs text-gray-500">1 hour ago</span>
275
  </div>
276
- <p class="text-gray-700 mb-2">How much does this cost?</p>
277
- <p class="rtl-text text-gray-900 font-medium">بكم هذا؟</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
278
  </div>
279
  </div>
 
 
 
 
280
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
281
 
282
- <!-- Dialect Information -->
283
- <div class="mt-10 bg-white rounded-xl shadow-md p-6">
284
- <h3 class="text-xl font-semibold text-gray-800 mb-4">Supported Saudi Dialects</h3>
285
- <div class="grid md:grid-cols-3 gap-6">
286
- <div class="border border-gray-200 rounded-lg p-4">
287
- <div class="flex items-center mb-2">
288
- <div class="w-10 h-10 rounded-full bg-blue-100 flex items-center justify-center mr-3">
289
- <i class="fas fa-map-marker-alt text-blue-900"></i>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
290
  </div>
291
- <h4 class="font-medium text-gray-800">Najdi Dialect</h4>
292
  </div>
293
- <p class="text-gray-600 text-sm">Spoken in central Saudi Arabia including Riyadh. Characterized by its distinctive pronunciation and vocabulary.</p>
294
  </div>
295
 
296
- <div class="border border-gray-200 rounded-lg p-4">
297
- <div class="flex items-center mb-2">
298
- <div class="w-10 h-10 rounded-full bg-blue-100 flex items-center justify-center mr-3">
299
- <i class="fas fa-umbrella-beach text-blue-900"></i>
 
 
 
 
 
 
 
 
 
 
 
300
  </div>
301
- <h4 class="font-medium text-gray-800">Hejazi Dialect</h4>
302
  </div>
303
- <p class="text-gray-600 text-sm">Spoken in western Saudi Arabia (Jeddah, Mecca, Medina). Influenced by historical trade routes and diverse populations.</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
304
  </div>
 
 
 
 
 
 
 
305
 
306
- <div class="border border-gray-200 rounded-lg p-4">
307
- <div class="flex items-center mb-2">
308
- <div class="w-10 h-10 rounded-full bg-blue-100 flex items-center justify-center mr-3">
309
- <i class="fas fa-water text-blue-900"></i>
310
- </div>
311
- <h4 class="font-medium text-gray-800">Gulf Dialect</h4>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
312
  </div>
313
- <p class="text-gray-600 text-sm">Spoken in eastern Saudi Arabia (Dammam, Khobar). Shares similarities with dialects from neighboring Gulf countries.</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
314
  </div>
315
  </div>
316
  </div>
@@ -325,10 +806,13 @@
325
  <i class="fas fa-language text-2xl"></i>
326
  <h2 class="text-xl font-bold">VoiceBridge</h2>
327
  </div>
328
- <p class="text-gray-400 mt-2">Specialized in Saudi dialects and regional accents</p>
329
  </div>
330
 
331
  <div class="flex space-x-6">
 
 
 
332
  <a href="#" class="text-gray-400 hover:text-white transition">
333
  <i class="fab fa-twitter"></i>
334
  </a>
@@ -336,13 +820,13 @@
336
  <i class="fab fa-instagram"></i>
337
  </a>
338
  <a href="#" class="text-gray-400 hover:text-white transition">
339
- <i class="fab fa-youtube"></i>
340
  </a>
341
  </div>
342
  </div>
343
 
344
  <div class="border-t border-gray-700 mt-8 pt-8 text-center text-gray-400 text-sm">
345
- <p>© 2023 VoiceBridge Saudi. All rights reserved.</p>
346
  </div>
347
  </div>
348
  </footer>
@@ -379,7 +863,7 @@
379
  recognition.onstart = () => {
380
  isListening = true;
381
  startListeningBtn.classList.add('bg-red-600', 'pulse');
382
- startListeningBtn.classList.remove('bg-blue-900');
383
  listeningStatus.textContent = "Listening... Speak now";
384
  voiceInputVisualizer.classList.add('opacity-100');
385
  };
@@ -387,7 +871,7 @@
387
  recognition.onend = () => {
388
  isListening = false;
389
  startListeningBtn.classList.remove('bg-red-600', 'pulse');
390
- startListeningBtn.classList.add('bg-blue-900');
391
  listeningStatus.textContent = "Press the microphone to start speaking";
392
  voiceInputVisualizer.classList.remove('opacity-100');
393
  };
@@ -398,28 +882,12 @@
398
  .map(result => result.transcript)
399
  .join('');
400
 
401
- // Check if Arabic dialect is selected
402
- const isArabicDialect = inputLanguage.value.includes('ar-SA');
403
-
404
- if (isArabicDialect) {
405
- inputText.innerHTML = `<p class="rtl-text text-gray-800">${transcript}</p>`;
406
- } else {
407
- inputText.innerHTML = `<p class="text-gray-800">${transcript}</p>`;
408
- }
409
 
410
  if (event.results[0].isFinal) {
411
  // Simulate translation (in a real app, this would call a translation API)
412
  const translatedText = simulateTranslation(transcript, inputLanguage.value, outputLanguage.value);
413
-
414
- // Check if output is Arabic dialect
415
- const isOutputArabic = outputLanguage.value.includes('ar-SA');
416
-
417
- if (isOutputArabic) {
418
- outputText.innerHTML = `<p class="rtl-text text-gray-800 font-medium">${translatedText}</p>`;
419
- } else {
420
- outputText.innerHTML = `<p class="text-gray-800 font-medium">${translatedText}</p>`;
421
- }
422
-
423
  playTranslationBtn.disabled = false;
424
  }
425
  };
@@ -436,8 +904,7 @@
436
  // Event Listeners
437
  startListeningBtn.addEventListener('click', () => {
438
  if (!isListening) {
439
- // Set language for recognition (standard Arabic for all dialects)
440
- recognition.lang = 'ar-SA';
441
  recognition.start();
442
  } else {
443
  recognition.stop();
@@ -447,9 +914,7 @@
447
  playTranslationBtn.addEventListener('click', () => {
448
  if (outputText.textContent && outputText.textContent !== "Translation will appear here...") {
449
  const utterance = new SpeechSynthesisUtterance(outputText.textContent);
450
-
451
- // Set language for synthesis (standard Arabic for all dialects)
452
- utterance.lang = outputLanguage.value.includes('ar-SA') ? 'ar-SA' : outputLanguage.value;
453
 
454
  // Show visualizer while speaking
455
  voiceOutputVisualizer.classList.remove('opacity-0');
@@ -465,8 +930,136 @@
465
  });
466
 
467
  clearAllBtn.addEventListener('click', () => {
468
- inputText.innerHTML = '<
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
469
  </html>
470
 
471
-
472
 
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>VoiceBridge - Speech to Speech Translator</title>
7
  <script src="https://cdn.tailwindcss.com"></script>
8
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
  <style>
10
+ @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap');
11
 
12
  body {
13
+ font-family: 'Poppins', sans-serif;
14
  background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
15
  min-height: 100vh;
16
  }
17
 
18
  .gradient-bg {
19
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
20
  }
21
 
22
  .wave-animation {
 
43
  @keyframes pulse {
44
  0% {
45
  transform: scale(0.95);
46
+ box-shadow: 0 0 0 0 rgba(102, 126, 234, 0.7);
47
  }
48
  70% {
49
  transform: scale(1);
50
+ box-shadow: 0 0 0 10px rgba(102, 126, 234, 0);
51
  }
52
  100% {
53
  transform: scale(0.95);
54
+ box-shadow: 0 0 0 0 rgba(102, 126, 234, 0);
55
  }
56
  }
57
 
 
74
 
75
  .voice-bar {
76
  width: 4px;
77
+ background-color: #667eea;
78
  border-radius: 3px;
79
  animation: equalize 1.5s infinite ease-in-out;
80
  }
 
99
  transform: translateY(-5px);
100
  box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
101
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  </style>
103
  </head>
104
  <body class="min-h-screen flex flex-col">
 
111
  <h1 class="text-2xl md:text-3xl font-bold">VoiceBridge</h1>
112
  </div>
113
  <div class="flex items-center space-x-4">
114
+ <button class="bg-white text-indigo-600 px-4 py-2 rounded-full font-medium hover:bg-indigo-50 transition">
115
  <i class="fas fa-cog mr-2"></i>Settings
116
  </button>
117
  </div>
118
  </div>
119
 
120
  <div class="mt-12 mb-16 text-center">
121
+ <h2 class="text-3xl md:text-4xl font-bold mb-4">Real-time Speech to Speech Translation</h2>
122
+ <p class="text-xl opacity-90 max-w-2xl mx-auto">Break language barriers instantly with our AI-powered voice translator</p>
123
  </div>
124
  </div>
125
  </header>
 
135
  <div class="flex items-center space-x-2">
136
  <span class="text-sm text-gray-500">Input Language:</span>
137
  <select id="inputLanguage" class="border rounded px-3 py-1 text-sm">
 
 
 
 
138
  <option value="en-US">English</option>
 
139
  <option value="es-ES">Spanish</option>
140
+ <option value="fr-FR">French</option>
141
+ <option value="de-DE">German</option>
142
+ <option value="ar-SA">Arabic</option>
143
+ <option value="zh-CN">Chinese</option>
144
+ <option value="ja-JP">Japanese</option>
145
  </select>
146
  </div>
147
  </div>
 
155
  <div class="voice-bar"></div>
156
  </div>
157
 
158
+ <button id="startListening" class="bg-indigo-600 text-white rounded-full p-4 pulse hover:bg-indigo-700 transition">
159
  <i class="fas fa-microphone text-2xl"></i>
160
  </button>
161
 
 
177
  <div class="flex items-center space-x-2">
178
  <span class="text-sm text-gray-500">Output Language:</span>
179
  <select id="outputLanguage" class="border rounded px-3 py-1 text-sm">
 
 
 
 
180
  <option value="en-US">English</option>
 
181
  <option value="es-ES">Spanish</option>
182
+ <option value="fr-FR">French</option>
183
+ <option value="de-DE">German</option>
184
+ <option value="ar-SA">Arabic</option>
185
+ <option value="zh-CN">Chinese</option>
186
+ <option value="ja-JP">Japanese</option>
187
  </select>
188
  </div>
189
  </div>
 
197
 
198
  <div class="bg-gray-50 rounded-lg p-6 text-center">
199
  <div id="voiceOutputVisualizer" class="voice-visualizer mb-6 opacity-0">
200
+ <div class="voice-bar bg-indigo-400"></div>
201
+ <div class="voice-bar bg-indigo-400"></div>
202
+ <div class="voice-bar bg-indigo-400"></div>
203
+ <div class="voice-bar bg-indigo-400"></div>
204
+ <div class="voice-bar bg-indigo-400"></div>
205
  </div>
206
 
207
+ <button id="playTranslation" class="bg-indigo-600 text-white rounded-full px-6 py-3 hover:bg-indigo-700 transition disabled:opacity-50" disabled>
208
  <i class="fas fa-volume-up mr-2"></i> Play Translation
209
  </button>
210
  </div>
 
224
  <button id="saveSession" class="bg-white border border-gray-300 rounded-full px-4 py-2 text-sm hover:bg-gray-50 transition">
225
  <i class="fas fa-save mr-2"></i> Save
226
  </button>
227
+ <button id="shareTranslation" class="bg-indigo-600 text-white rounded-full px-4 py-2 text-sm hover:bg-indigo-700 transition">
228
  <i class="fas fa-share-alt mr-2"></i> Share
229
  </button>
230
  </div>
 
237
  <div class="grid md:grid-cols-2 lg:grid-cols-3 gap-4">
238
  <div class="bg-white rounded-lg p-4 shadow border border-gray-100">
239
  <div class="flex justify-between items-start mb-2">
240
+ <span class="text-sm font-medium text-indigo-600 bg-indigo-50 px-2 py-1 rounded">EnglishSpanish</span>
241
  <span class="text-xs text-gray-500">2 min ago</span>
242
  </div>
243
+ <p class="text-gray-700 mb-2">Hello, how are you?</p>
244
+ <p class="text-gray-900 font-medium">Hola, ¿cómo estás?</p>
245
  </div>
246
 
247
  <div class="bg-white rounded-lg p-4 shadow border border-gray-100">
248
  <div class="flex justify-between items-start mb-2">
249
+ <span class="text-sm font-medium text-indigo-600 bg-indigo-50 px-2 py-1 rounded">FrenchEnglish</span>
250
  <span class="text-xs text-gray-500">15 min ago</span>
251
  </div>
252
+ <p class="text-gray-700 mb-2">Où est la gare?</p>
253
+ <p class="text-gray-900 font-medium">Where is the train station?</p>
254
  </div>
255
 
256
  <div class="bg-white rounded-lg p-4 shadow border border-gray-100 hidden md:block">
257
  <div class="flex justify-between items-start mb-2">
258
+ <span class="text-sm font-medium text-indigo-600 bg-indigo-50 px-2 py-1 rounded">ArabicGerman</span>
259
  <span class="text-xs text-gray-500">1 hour ago</span>
260
  </div>
261
+ <p class="text-gray-700 mb-2">كم الساعة؟</p>
262
+ <p class="text-gray-900 font-medium">Wie spät ist es?</p>
263
+ </div>
264
+ </div>
265
+ </div>
266
+ </main>
267
+
268
+ <!-- Footer -->
269
+ <footer class="bg-gray-800 text-white py-8">
270
+ <div class="container mx-auto px-4">
271
+ <div class="flex flex-col md:flex-row justify-between items-center">
272
+ <div class="mb-4 md:mb-0">
273
+ <div class="flex items-center space-x-2">
274
+ <i class="fas fa-language text-2xl"></i>
275
+ <h2 class="text-xl font-bold">VoiceBridge</h2>
276
+ </div>
277
+ <p class="text-gray-400 mt-2">Breaking language barriers one conversation at a time</p>
278
+ </div>
279
+
280
+ <div class="flex space-x-6">
281
+ <a href="#" class="text-gray-400 hover:text-white transition">
282
+ <i class="fab fa-facebook-f"></i>
283
+ </a>
284
+ <a href="#" class="text-gray-400 hover:text-white transition">
285
+ <i class="fab fa-twitter"></i>
286
+ </a>
287
+ <a href="#" class="text-gray-400 hover:text-white transition">
288
+ <i class="fab fa-instagram"></i>
289
+ </a>
290
+ <a href="#" class="text-gray-400 hover:text-white transition">
291
+ <i class="fab fa-github"></i>
292
+ </a>
293
  </div>
294
  </div>
295
+
296
+ <div class="border-t border-gray-700 mt-8 pt-8 text-center text-gray-400 text-sm">
297
+ <p>© 2023 VoiceBridge. All rights reserved.</p>
298
+ </div>
299
  </div>
300
+ </footer>
301
+
302
+ <script>
303
+ // DOM Elements
304
+ const startListeningBtn = document.getElementById('startListening');
305
+ const listeningStatus = document.getElementById('listeningStatus');
306
+ const inputText = document.getElementById('inputText');
307
+ const outputText = document.getElementById('outputText');
308
+ const playTranslationBtn = document.getElementById('playTranslation');
309
+ const voiceInputVisualizer = document.getElementById('voiceInputVisualizer');
310
+ const voiceOutputVisualizer = document.getElementById('voiceOutputVisualizer');
311
+ const inputLanguage = document.getElementById('inputLanguage');
312
+ const outputLanguage = document.getElementById('outputLanguage');
313
+ const clearAllBtn = document.getElementById('clearAll');
314
+ const copyTranslationBtn = document.getElementById('copyTranslation');
315
+ const saveSessionBtn = document.getElementById('saveSession');
316
+ const shareTranslationBtn = document.getElementById('shareTranslation');
317
+
318
+ // Speech Recognition and Synthesis
319
+ const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
320
+ const synth = window.speechSynthesis;
321
+
322
+ let recognition;
323
+ let isListening = false;
324
+
325
+ // Initialize Speech Recognition
326
+ if (SpeechRecognition) {
327
+ recognition = new SpeechRecognition();
328
+ recognition.continuous = false;
329
+ recognition.interimResults = true;
330
+
331
+ recognition.onstart = () => {
332
+ isListening = true;
333
+ startListeningBtn.classList.add('bg-red-600', 'pulse');
334
+ startListeningBtn.classList.remove('bg-indigo-600');
335
+ listeningStatus.textContent = "Listening... Speak now";
336
+ voiceInputVisualizer.classList.add('opacity-100');
337
+ };
338
+
339
+ recognition.onend = () => {
340
+ isListening = false;
341
+ startListeningBtn.classList.remove('bg-red-600', 'pulse');
342
+ startListeningBtn.classList.add('bg-indigo-600');
343
+ listeningStatus.textContent = "Press the microphone to start speaking";
344
+ voiceInputVisualizer.classList.remove('opacity-100');
345
+ };
346
+
347
+ recognition.onresult = (event) => {
348
+ const transcript = Array.from(event.results)
349
+ .map(result => result[0])
350
+ .map(result => result.transcript)
351
+ .join('');
352
+
353
+ inputText.innerHTML = `<p class="text-gray-800">${transcript}</p>`;
354
+
355
+ if (event.results[0].isFinal) {
356
+ // Simulate translation (in a real app, this would call a translation API)
357
+ const translatedText = simulateTranslation(transcript, inputLanguage.value, outputLanguage.value);
358
+ outputText.innerHTML = `<p class="text-gray-800 font-medium">${translatedText}</p>`;
359
+ playTranslationBtn.disabled = false;
360
+ }
361
+ };
362
+
363
+ recognition.onerror = (event) => {
364
+ console.error('Speech recognition error', event.error);
365
+ listeningStatus.textContent = `Error: ${event.error}`;
366
+ };
367
+ } else {
368
+ listeningStatus.textContent = "Speech recognition not supported in your browser";
369
+ startListeningBtn.disabled = true;
370
+ }
371
+
372
+ // Event Listeners
373
+ startListeningBtn.addEventListener('click', () => {
374
+ if (!isListening) {
375
+ recognition.lang = inputLanguage.value;
376
+ recognition.start();
377
+ } else {
378
+ recognition.stop();
379
+ }
380
+ });
381
+
382
+ playTranslationBtn.addEventListener('click', () => {
383
+ if (outputText.textContent && outputText.textContent !== "Translation will appear here...") {
384
+ const utterance = new SpeechSynthesisUtterance(outputText.textContent);
385
+ utterance.lang = outputLanguage.value;
386
+
387
+ // Show visualizer while speaking
388
+ voiceOutputVisualizer.classList.remove('opacity-0');
389
+ voiceOutputVisualizer.classList.add('opacity-100');
390
+
391
+ utterance.onend = () => {
392
+ voiceOutputVisualizer.classList.add('opacity-0');
393
+ voiceOutputVisualizer.classList.remove('opacity-100');
394
+ };
395
+
396
+ synth.speak(utterance);
397
+ }
398
+ });
399
+
400
+ clearAllBtn.addEventListener('click', () => {
401
+ inputText.innerHTML = '<p class="text-gray-500 italic">Recognized text will appear here...</p>';
402
+ outputText.innerHTML = '<p class="text-gray-500 italic">Translation will appear here...</p>';
403
+ playTranslationBtn.disabled = true;
404
+ });
405
+
406
+ copyTranslationBtn.addEventListener('click', () => {
407
+ if (outputText.textContent && outputText.textContent !== "Translation will appear here...") {
408
+ navigator.clipboard.writeText(outputText.textContent)
409
+ .then(() => {
410
+ const originalText = copyTranslationBtn.innerHTML;
411
+ copyTranslationBtn.innerHTML = '<i class="fas fa-check mr-2"></i> Copied!';
412
+ setTimeout(() => {
413
+ copyTranslationBtn.innerHTML = originalText;
414
+ }, 2000);
415
+ });
416
+ }
417
+ });
418
+
419
+ saveSessionBtn.addEventListener('click', () => {
420
+ // In a real app, this would save to local storage or a database
421
+ alert('Translation saved to your history');
422
+ });
423
+
424
+ shareTranslationBtn.addEventListener('click', () => {
425
+ if (outputText.textContent && outputText.textContent !== "Translation will appear here...") {
426
+ if (navigator.share) {
427
+ navigator.share({
428
+ title: 'VoiceBridge Translation',
429
+ text: `Original: ${inputText.textContent}\nTranslation: ${outputText.textContent}`,
430
+ }).catch(err => {
431
+ console.error('Error sharing:', err);
432
+ });
433
+ } else {
434
+ // Fallback for browsers that don't support Web Share API
435
+ alert('Share functionality not supported in your browser');
436
+ }
437
+ }
438
+ });
439
+
440
+ // Language change handlers
441
+ inputLanguage.addEventListener('change', () => {
442
+ if (isListening) {
443
+ recognition.stop();
444
+ recognition.lang = inputLanguage.value;
445
+ recognition.start();
446
+ }
447
+ });
448
+
449
+ outputLanguage.addEventListener('change', () => {
450
+ if (inputText.textContent && inputText.textContent !== "Recognized text will appear here...") {
451
+ const translatedText = simulateTranslation(inputText.textContent, inputLanguage.value, outputLanguage.value);
452
+ outputText.innerHTML = `<p class="text-gray-800 font-medium">${translatedText}</p>`;
453
+ }
454
+ });
455
+
456
+ // Simulate translation function (in a real app, replace with API call)
457
+ function simulateTranslation(text, fromLang, toLang) {
458
+ // This is just a simulation - in a real app you would call a translation API
459
+ const translations = {
460
+ 'en-US_es-ES': {
461
+ 'Hello, how are you?': 'Hola, ¿cómo estás?',
462
+ 'What time is it?': '¿Qué hora es?',
463
+ 'Where is the bathroom?': '¿Dónde está el baño?',
464
+ 'Thank you very much': 'Muchas gracias',
465
+ 'I need help': 'Necesito ayuda'
466
+ },
467
+ 'es-ES_en-US': {
468
+ 'Hola, ¿cómo estás?': 'Hello, how are you?',
469
+ '¿Qué hora es?': 'What time is it?',
470
+ '¿Dónde está el baño?': 'Where is the bathroom?',
471
+ 'Muchas gracias': 'Thank you very much',
472
+ 'Necesito ayuda': 'I need help'
473
+ },
474
+ 'en-US_fr-FR': {
475
+ 'Hello, how are you?': 'Bonjour, comment ça va?',
476
+ 'What time is it?': 'Quelle heure est-il?',
477
+ 'Where is the bathroom?': 'Où sont les toilettes?',
478
+ 'Thank you very much': 'Merci beaucoup',
479
+ 'I need help': 'J\'ai besoin d\'aide'
480
+ },
481
+ 'fr-FR_en-US': {
482
+ 'Bonjour, comment ça va?': 'Hello, how are you?',
483
+ 'Quelle heure est-il?': 'What time is it?',
484
+ 'Où sont les toilettes?': 'Where is the bathroom?',
485
+ 'Merci beaucoup': 'Thank you very much',
486
+ 'J\'ai besoin d\'aide': 'I need help'
487
+ },
488
+ 'en-US_de-DE': {
489
+ 'Hello, how are you?': 'Hallo, wie geht es dir?',
490
+ 'What time is it?': 'Wie spät ist es?',
491
+ 'Where is the bathroom?': 'Wo ist die Toilette?',
492
+ 'Thank you very much': 'Vielen Dank',
493
+ 'I need help': 'Ich brauche Hilfe'
494
+ },
495
+ 'de-DE_en-US': {
496
+ 'Hallo, wie geht es dir?': 'Hello, how are you?',
497
+ 'Wie spät ist es?': 'What time is it?',
498
+ 'Wo ist die Toilette?': 'Where is the bathroom?',
499
+ 'Vielen Dank': 'Thank you very much',
500
+ 'Ich brauche Hilfe': 'I need help'
501
+ }
502
+ };
503
+
504
+ const langPair = `${fromLang.split('-')[0]}_${toLang.split('-')[0]}`;
505
+
506
+ if (translations[langPair] && translations[langPair][text]) {
507
+ return translations[langPair][text];
508
+ }
509
+
510
+ // Fallback for untranslated phrases
511
+ return `[Translation: ${text} from ${fromLang} to ${toLang}]`;
512
+ }
513
+
514
+ // Initialize voice visualizer animation
515
+ function initVoiceVisualizer() {
516
+ const bars = voiceInputVisualizer.querySelectorAll('.voice-bar');
517
+ bars.forEach(bar => {
518
+ const randomHeight = Math.random() * 60 + 10;
519
+ bar.style.height = `${randomHeight}%`;
520
+ });
521
+
522
+ if (isListening) {
523
+ requestAnimationFrame(initVoiceVisualizer);
524
+ }
525
+ }
526
+
527
+ // Start visualizer when listening starts
528
+ voiceInputVisualizer.addEventListener('animationstart', initVoiceVisualizer);
529
+ </script>
530
+ </body>
531
+ </html>
532
+
533
+ <!DOCTYPE html>
534
+ <html lang="en">
535
+ <head>
536
+ <meta charset="UTF-8">
537
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
538
+ <title>VoiceBridge - Speech to Speech Translator</title>
539
+ <script src="https://cdn.tailwindcss.com"></script>
540
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
541
+ <style>
542
+ @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap');
543
+
544
+ body {
545
+ font-family: 'Poppins', sans-serif;
546
+ background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
547
+ min-height: 100vh;
548
+ }
549
+
550
+ .gradient-bg {
551
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
552
+ }
553
+
554
+ .wave-animation {
555
+ position: relative;
556
+ overflow: hidden;
557
+ }
558
+
559
+ .wave-animation::after {
560
+ content: "";
561
+ position: absolute;
562
+ bottom: 0;
563
+ left: 0;
564
+ right: 0;
565
+ height: 20px;
566
+ background: url('data:image/svg+xml;utf8,<svg viewBox="0 0 1200 120" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none"><path d="M0,0V46.29c47.79,22.2,103.59,32.17,158,28,70.36-5.37,136.33-33.31,206.8-37.5C438.64,32.43,512.34,53.67,583,72.05c69.27,18,138.3,24.88,209.4,13.08,36.15-6,69.85-17.84,104.45-29.34C989.49,25,1113-14.29,1200,52.47V0Z" fill="%23ffffff" opacity=".25"/><path d="M0,0V15.81C13,36.92,27.64,56.86,47.69,72.05,99.41,111.27,165,111,224.58,91.58c31.15-10.15,60.09-26.07,89.67-39.8,40.92-19,84.73-46,130.83-49.67,36.26-2.85,70.9,9.42,98.6,31.56,31.77,25.39,62.32,62,103.63,73,40.44,10.79,81.35-6.69,119.13-24.28s75.16-39,116.92-43.05c59.73-5.85,113.28,22.88,168.9,38.84,30.2,8.66,59,6.17,87.09-7.5,22.43-10.89,48-26.93,60.65-49.24V0Z" fill="%23ffffff" opacity=".5"/><path d="M0,0V5.63C149.93,59,314.09,71.32,475.83,42.57c43-7.64,84.23-20.12,127.61-26.46,59-8.63,112.48,12.24,165.56,35.4C827.93,77.22,886,95.24,951.2,90c86.53-7,172.46-45.71,248.8-84.81V0Z" fill="%23ffffff"/></svg>');
567
+ background-size: cover;
568
+ z-index: 10;
569
+ }
570
+
571
+ .pulse {
572
+ animation: pulse 2s infinite;
573
+ }
574
+
575
+ @keyframes pulse {
576
+ 0% {
577
+ transform: scale(0.95);
578
+ box-shadow: 0 0 0 0 rgba(102, 126, 234, 0.7);
579
+ }
580
+ 70% {
581
+ transform: scale(1);
582
+ box-shadow: 0 0 0 10px rgba(102, 126, 234, 0);
583
+ }
584
+ 100% {
585
+ transform: scale(0.95);
586
+ box-shadow: 0 0 0 0 rgba(102, 126, 234, 0);
587
+ }
588
+ }
589
+
590
+ .language-selector {
591
+ transition: all 0.3s ease;
592
+ }
593
+
594
+ .language-selector:hover {
595
+ transform: translateY(-5px);
596
+ box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
597
+ }
598
+
599
+ .voice-visualizer {
600
+ height: 60px;
601
+ display: flex;
602
+ align-items: flex-end;
603
+ justify-content: center;
604
+ gap: 3px;
605
+ }
606
+
607
+ .voice-bar {
608
+ width: 4px;
609
+ background-color: #667eea;
610
+ border-radius: 3px;
611
+ animation: equalize 1.5s infinite ease-in-out;
612
+ }
613
+
614
+ @keyframes equalize {
615
+ 0%, 100% { height: 10%; }
616
+ 50% { height: 100%; }
617
+ }
618
+
619
+ .voice-bar:nth-child(1) { animation-delay: -0.9s; }
620
+ .voice-bar:nth-child(2) { animation-delay: -0.6s; }
621
+ .voice-bar:nth-child(3) { animation-delay: -0.3s; }
622
+ .voice-bar:nth-child(4) { animation-delay: -0.6s; }
623
+ .voice-bar:nth-child(5) { animation-delay: -0.9s; }
624
 
625
+ .result-card {
626
+ transition: all 0.3s ease;
627
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
628
+ }
629
+
630
+ .result-card:hover {
631
+ transform: translateY(-5px);
632
+ box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
633
+ }
634
+ </style>
635
+ </head>
636
+ <body class="min-h-screen flex flex-col">
637
+ <!-- Header -->
638
+ <header class="gradient-bg text-white wave-animation">
639
+ <div class="container mx-auto px-4 py-8">
640
+ <div class="flex justify-between items-center">
641
+ <div class="flex items-center space-x-2">
642
+ <i class="fas fa-language text-3xl"></i>
643
+ <h1 class="text-2xl md:text-3xl font-bold">VoiceBridge</h1>
644
+ </div>
645
+ <div class="flex items-center space-x-4">
646
+ <button class="bg-white text-indigo-600 px-4 py-2 rounded-full font-medium hover:bg-indigo-50 transition">
647
+ <i class="fas fa-cog mr-2"></i>Settings
648
+ </button>
649
+ </div>
650
+ </div>
651
+
652
+ <div class="mt-12 mb-16 text-center">
653
+ <h2 class="text-3xl md:text-4xl font-bold mb-4">Real-time Speech to Speech Translation</h2>
654
+ <p class="text-xl opacity-90 max-w-2xl mx-auto">Break language barriers instantly with our AI-powered voice translator</p>
655
+ </div>
656
+ </div>
657
+ </header>
658
+
659
+ <!-- Main Content -->
660
+ <main class="flex-grow container mx-auto px-4 py-8 -mt-10">
661
+ <div class="bg-white rounded-xl shadow-xl overflow-hidden">
662
+ <div class="grid md:grid-cols-2 gap-6 p-6">
663
+ <!-- Input Section -->
664
+ <div class="space-y-6">
665
+ <div class="flex justify-between items-center">
666
+ <h3 class="text-xl font-semibold text-gray-800">Speak Now</h3>
667
+ <div class="flex items-center space-x-2">
668
+ <span class="text-sm text-gray-500">Input Language:</span>
669
+ <select id="inputLanguage" class="border rounded px-3 py-1 text-sm">
670
+ <option value="en-US">English</option>
671
+ <option value="es-ES">Spanish</option>
672
+ <option value="fr-FR">French</option>
673
+ <option value="de-DE">German</option>
674
+ <option value="ar-SA">Arabic</option>
675
+ <option value="zh-CN">Chinese</option>
676
+ <option value="ja-JP">Japanese</option>
677
+ </select>
678
+ </div>
679
+ </div>
680
+
681
+ <div class="bg-gray-50 rounded-lg p-6 text-center">
682
+ <div id="voiceInputVisualizer" class="voice-visualizer mb-6">
683
+ <div class="voice-bar"></div>
684
+ <div class="voice-bar"></div>
685
+ <div class="voice-bar"></div>
686
+ <div class="voice-bar"></div>
687
+ <div class="voice-bar"></div>
688
+ </div>
689
+
690
+ <button id="startListening" class="bg-indigo-600 text-white rounded-full p-4 pulse hover:bg-indigo-700 transition">
691
+ <i class="fas fa-microphone text-2xl"></i>
692
+ </button>
693
+
694
+ <p id="listeningStatus" class="mt-4 text-gray-600">Press the microphone to start speaking</p>
695
+ </div>
696
+
697
+ <div class="result-card bg-gray-50 rounded-lg p-4">
698
+ <h4 class="font-medium text-gray-700 mb-2">Your Speech</h4>
699
+ <div id="inputText" class="min-h-20 p-3 bg-white rounded border border-gray-200">
700
+ <p class="text-gray-500 italic">Recognized text will appear here...</p>
701
  </div>
 
702
  </div>
 
703
  </div>
704
 
705
+ <!-- Output Section -->
706
+ <div class="space-y-6">
707
+ <div class="flex justify-between items-center">
708
+ <h3 class="text-xl font-semibold text-gray-800">Translation</h3>
709
+ <div class="flex items-center space-x-2">
710
+ <span class="text-sm text-gray-500">Output Language:</span>
711
+ <select id="outputLanguage" class="border rounded px-3 py-1 text-sm">
712
+ <option value="en-US">English</option>
713
+ <option value="es-ES">Spanish</option>
714
+ <option value="fr-FR">French</option>
715
+ <option value="de-DE">German</option>
716
+ <option value="ar-SA">Arabic</option>
717
+ <option value="zh-CN">Chinese</option>
718
+ <option value="ja-JP">Japanese</option>
719
+ </select>
720
  </div>
 
721
  </div>
722
+
723
+ <div class="result-card bg-gray-50 rounded-lg p-4">
724
+ <h4 class="font-medium text-gray-700 mb-2">Translated Text</h4>
725
+ <div id="outputText" class="min-h-20 p-3 bg-white rounded border border-gray-200">
726
+ <p class="text-gray-500 italic">Translation will appear here...</p>
727
+ </div>
728
+ </div>
729
+
730
+ <div class="bg-gray-50 rounded-lg p-6 text-center">
731
+ <div id="voiceOutputVisualizer" class="voice-visualizer mb-6 opacity-0">
732
+ <div class="voice-bar bg-indigo-400"></div>
733
+ <div class="voice-bar bg-indigo-400"></div>
734
+ <div class="voice-bar bg-indigo-400"></div>
735
+ <div class="voice-bar bg-indigo-400"></div>
736
+ <div class="voice-bar bg-indigo-400"></div>
737
+ </div>
738
+
739
+ <button id="playTranslation" class="bg-indigo-600 text-white rounded-full px-6 py-3 hover:bg-indigo-700 transition disabled:opacity-50" disabled>
740
+ <i class="fas fa-volume-up mr-2"></i> Play Translation
741
+ </button>
742
+ </div>
743
  </div>
744
+ </div>
745
+
746
+ <!-- Quick Actions -->
747
+ <div class="bg-gray-100 px-6 py-4 border-t border-gray-200 flex justify-between items-center">
748
+ <button id="clearAll" class="text-gray-600 hover:text-gray-800 transition">
749
+ <i class="fas fa-trash-alt mr-2"></i> Clear All
750
+ </button>
751
 
752
+ <div class="flex space-x-3">
753
+ <button id="copyTranslation" class="bg-white border border-gray-300 rounded-full px-4 py-2 text-sm hover:bg-gray-50 transition">
754
+ <i class="fas fa-copy mr-2"></i> Copy
755
+ </button>
756
+ <button id="saveSession" class="bg-white border border-gray-300 rounded-full px-4 py-2 text-sm hover:bg-gray-50 transition">
757
+ <i class="fas fa-save mr-2"></i> Save
758
+ </button>
759
+ <button id="shareTranslation" class="bg-indigo-600 text-white rounded-full px-4 py-2 text-sm hover:bg-indigo-700 transition">
760
+ <i class="fas fa-share-alt mr-2"></i> Share
761
+ </button>
762
+ </div>
763
+ </div>
764
+ </div>
765
+
766
+ <!-- Recent Translations -->
767
+ <div class="mt-10">
768
+ <h3 class="text-xl font-semibold text-gray-800 mb-4">Recent Translations</h3>
769
+ <div class="grid md:grid-cols-2 lg:grid-cols-3 gap-4">
770
+ <div class="bg-white rounded-lg p-4 shadow border border-gray-100">
771
+ <div class="flex justify-between items-start mb-2">
772
+ <span class="text-sm font-medium text-indigo-600 bg-indigo-50 px-2 py-1 rounded">English → Spanish</span>
773
+ <span class="text-xs text-gray-500">2 min ago</span>
774
  </div>
775
+ <p class="text-gray-700 mb-2">Hello, how are you?</p>
776
+ <p class="text-gray-900 font-medium">Hola, ¿cómo estás?</p>
777
+ </div>
778
+
779
+ <div class="bg-white rounded-lg p-4 shadow border border-gray-100">
780
+ <div class="flex justify-between items-start mb-2">
781
+ <span class="text-sm font-medium text-indigo-600 bg-indigo-50 px-2 py-1 rounded">French → English</span>
782
+ <span class="text-xs text-gray-500">15 min ago</span>
783
+ </div>
784
+ <p class="text-gray-700 mb-2">Où est la gare?</p>
785
+ <p class="text-gray-900 font-medium">Where is the train station?</p>
786
+ </div>
787
+
788
+ <div class="bg-white rounded-lg p-4 shadow border border-gray-100 hidden md:block">
789
+ <div class="flex justify-between items-start mb-2">
790
+ <span class="text-sm font-medium text-indigo-600 bg-indigo-50 px-2 py-1 rounded">Arabic → German</span>
791
+ <span class="text-xs text-gray-500">1 hour ago</span>
792
+ </div>
793
+ <p class="text-gray-700 mb-2">كم الساعة؟</p>
794
+ <p class="text-gray-900 font-medium">Wie spät ist es?</p>
795
  </div>
796
  </div>
797
  </div>
 
806
  <i class="fas fa-language text-2xl"></i>
807
  <h2 class="text-xl font-bold">VoiceBridge</h2>
808
  </div>
809
+ <p class="text-gray-400 mt-2">Breaking language barriers one conversation at a time</p>
810
  </div>
811
 
812
  <div class="flex space-x-6">
813
+ <a href="#" class="text-gray-400 hover:text-white transition">
814
+ <i class="fab fa-facebook-f"></i>
815
+ </a>
816
  <a href="#" class="text-gray-400 hover:text-white transition">
817
  <i class="fab fa-twitter"></i>
818
  </a>
 
820
  <i class="fab fa-instagram"></i>
821
  </a>
822
  <a href="#" class="text-gray-400 hover:text-white transition">
823
+ <i class="fab fa-github"></i>
824
  </a>
825
  </div>
826
  </div>
827
 
828
  <div class="border-t border-gray-700 mt-8 pt-8 text-center text-gray-400 text-sm">
829
+ <p>© 2023 VoiceBridge. All rights reserved.</p>
830
  </div>
831
  </div>
832
  </footer>
 
863
  recognition.onstart = () => {
864
  isListening = true;
865
  startListeningBtn.classList.add('bg-red-600', 'pulse');
866
+ startListeningBtn.classList.remove('bg-indigo-600');
867
  listeningStatus.textContent = "Listening... Speak now";
868
  voiceInputVisualizer.classList.add('opacity-100');
869
  };
 
871
  recognition.onend = () => {
872
  isListening = false;
873
  startListeningBtn.classList.remove('bg-red-600', 'pulse');
874
+ startListeningBtn.classList.add('bg-indigo-600');
875
  listeningStatus.textContent = "Press the microphone to start speaking";
876
  voiceInputVisualizer.classList.remove('opacity-100');
877
  };
 
882
  .map(result => result.transcript)
883
  .join('');
884
 
885
+ inputText.innerHTML = `<p class="text-gray-800">${transcript}</p>`;
 
 
 
 
 
 
 
886
 
887
  if (event.results[0].isFinal) {
888
  // Simulate translation (in a real app, this would call a translation API)
889
  const translatedText = simulateTranslation(transcript, inputLanguage.value, outputLanguage.value);
890
+ outputText.innerHTML = `<p class="text-gray-800 font-medium">${translatedText}</p>`;
 
 
 
 
 
 
 
 
 
891
  playTranslationBtn.disabled = false;
892
  }
893
  };
 
904
  // Event Listeners
905
  startListeningBtn.addEventListener('click', () => {
906
  if (!isListening) {
907
+ recognition.lang = inputLanguage.value;
 
908
  recognition.start();
909
  } else {
910
  recognition.stop();
 
914
  playTranslationBtn.addEventListener('click', () => {
915
  if (outputText.textContent && outputText.textContent !== "Translation will appear here...") {
916
  const utterance = new SpeechSynthesisUtterance(outputText.textContent);
917
+ utterance.lang = outputLanguage.value;
 
 
918
 
919
  // Show visualizer while speaking
920
  voiceOutputVisualizer.classList.remove('opacity-0');
 
930
  });
931
 
932
  clearAllBtn.addEventListener('click', () => {
933
+ inputText.innerHTML = '<p class="text-gray-500 italic">Recognized text will appear here...</p>';
934
+ outputText.innerHTML = '<p class="text-gray-500 italic">Translation will appear here...</p>';
935
+ playTranslationBtn.disabled = true;
936
+ });
937
+
938
+ copyTranslationBtn.addEventListener('click', () => {
939
+ if (outputText.textContent && outputText.textContent !== "Translation will appear here...") {
940
+ navigator.clipboard.writeText(outputText.textContent)
941
+ .then(() => {
942
+ const originalText = copyTranslationBtn.innerHTML;
943
+ copyTranslationBtn.innerHTML = '<i class="fas fa-check mr-2"></i> Copied!';
944
+ setTimeout(() => {
945
+ copyTranslationBtn.innerHTML = originalText;
946
+ }, 2000);
947
+ });
948
+ }
949
+ });
950
+
951
+ saveSessionBtn.addEventListener('click', () => {
952
+ // In a real app, this would save to local storage or a database
953
+ alert('Translation saved to your history');
954
+ });
955
+
956
+ shareTranslationBtn.addEventListener('click', () => {
957
+ if (outputText.textContent && outputText.textContent !== "Translation will appear here...") {
958
+ if (navigator.share) {
959
+ navigator.share({
960
+ title: 'VoiceBridge Translation',
961
+ text: `Original: ${inputText.textContent}\nTranslation: ${outputText.textContent}`,
962
+ }).catch(err => {
963
+ console.error('Error sharing:', err);
964
+ });
965
+ } else {
966
+ // Fallback for browsers that don't support Web Share API
967
+ alert('Share functionality not supported in your browser');
968
+ }
969
+ }
970
+ });
971
+
972
+ // Language change handlers
973
+ inputLanguage.addEventListener('change', () => {
974
+ if (isListening) {
975
+ recognition.stop();
976
+ recognition.lang = inputLanguage.value;
977
+ recognition.start();
978
+ }
979
+ });
980
+
981
+ outputLanguage.addEventListener('change', () => {
982
+ if (inputText.textContent && inputText.textContent !== "Recognized text will appear here...") {
983
+ const translatedText = simulateTranslation(inputText.textContent, inputLanguage.value, outputLanguage.value);
984
+ outputText.innerHTML = `<p class="text-gray-800 font-medium">${translatedText}</p>`;
985
+ }
986
+ });
987
+
988
+ // Simulate translation function (in a real app, replace with API call)
989
+ function simulateTranslation(text, fromLang, toLang) {
990
+ // This is just a simulation - in a real app you would call a translation API
991
+ const translations = {
992
+ 'en-US_es-ES': {
993
+ 'Hello, how are you?': 'Hola, ¿cómo estás?',
994
+ 'What time is it?': '¿Qué hora es?',
995
+ 'Where is the bathroom?': '¿Dónde está el baño?',
996
+ 'Thank you very much': 'Muchas gracias',
997
+ 'I need help': 'Necesito ayuda'
998
+ },
999
+ 'es-ES_en-US': {
1000
+ 'Hola, ¿cómo estás?': 'Hello, how are you?',
1001
+ '¿Qué hora es?': 'What time is it?',
1002
+ '¿Dónde está el baño?': 'Where is the bathroom?',
1003
+ 'Muchas gracias': 'Thank you very much',
1004
+ 'Necesito ayuda': 'I need help'
1005
+ },
1006
+ 'en-US_fr-FR': {
1007
+ 'Hello, how are you?': 'Bonjour, comment ça va?',
1008
+ 'What time is it?': 'Quelle heure est-il?',
1009
+ 'Where is the bathroom?': 'Où sont les toilettes?',
1010
+ 'Thank you very much': 'Merci beaucoup',
1011
+ 'I need help': 'J\'ai besoin d\'aide'
1012
+ },
1013
+ 'fr-FR_en-US': {
1014
+ 'Bonjour, comment ça va?': 'Hello, how are you?',
1015
+ 'Quelle heure est-il?': 'What time is it?',
1016
+ 'Où sont les toilettes?': 'Where is the bathroom?',
1017
+ 'Merci beaucoup': 'Thank you very much',
1018
+ 'J\'ai besoin d\'aide': 'I need help'
1019
+ },
1020
+ 'en-US_de-DE': {
1021
+ 'Hello, how are you?': 'Hallo, wie geht es dir?',
1022
+ 'What time is it?': 'Wie spät ist es?',
1023
+ 'Where is the bathroom?': 'Wo ist die Toilette?',
1024
+ 'Thank you very much': 'Vielen Dank',
1025
+ 'I need help': 'Ich brauche Hilfe'
1026
+ },
1027
+ 'de-DE_en-US': {
1028
+ 'Hallo, wie geht es dir?': 'Hello, how are you?',
1029
+ 'Wie spät ist es?': 'What time is it?',
1030
+ 'Wo ist die Toilette?': 'Where is the bathroom?',
1031
+ 'Vielen Dank': 'Thank you very much',
1032
+ 'Ich brauche Hilfe': 'I need help'
1033
+ }
1034
+ };
1035
+
1036
+ const langPair = `${fromLang.split('-')[0]}_${toLang.split('-')[0]}`;
1037
+
1038
+ if (translations[langPair] && translations[langPair][text]) {
1039
+ return translations[langPair][text];
1040
+ }
1041
+
1042
+ // Fallback for untranslated phrases
1043
+ return `[Translation: ${text} from ${fromLang} to ${toLang}]`;
1044
+ }
1045
+
1046
+ // Initialize voice visualizer animation
1047
+ function initVoiceVisualizer() {
1048
+ const bars = voiceInputVisualizer.querySelectorAll('.voice-bar');
1049
+ bars.forEach(bar => {
1050
+ const randomHeight = Math.random() * 60 + 10;
1051
+ bar.style.height = `${randomHeight}%`;
1052
+ });
1053
+
1054
+ if (isListening) {
1055
+ requestAnimationFrame(initVoiceVisualizer);
1056
+ }
1057
+ }
1058
+
1059
+ // Start visualizer when listening starts
1060
+ voiceInputVisualizer.addEventListener('animationstart', initVoiceVisualizer);
1061
+ </script>
1062
+ </body>
1063
  </html>
1064
 
 
1065