Opera8 commited on
Commit
7f7ab19
·
verified ·
1 Parent(s): a433f1c

Upload index (1) (6).html

Browse files
Files changed (1) hide show
  1. index (1) (6).html +551 -0
index (1) (6).html ADDED
@@ -0,0 +1,551 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="fa" dir="rtl">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
6
+ <title>آوا هوش - جعبه ابزار صدا</title>
7
+
8
+ <!-- Tailwind CSS -->
9
+ <script src="https://cdn.tailwindcss.com"></script>
10
+
11
+ <!-- Fonts -->
12
+ <link rel="preconnect" href="https://fonts.googleapis.com">
13
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
14
+ <link href="https://fonts.googleapis.com/css2?family=Vazirmatn:wght@100..900&display=swap" rel="stylesheet">
15
+
16
+ <!-- Babel for JSX transformation in browser -->
17
+ <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
18
+
19
+ <style>
20
+ body {
21
+ font-family: 'Vazirmatn', sans-serif;
22
+ background-color: #0f172a;
23
+ color: white;
24
+ -webkit-tap-highlight-color: transparent;
25
+ overflow-x: hidden;
26
+ margin: 0;
27
+ padding: 0;
28
+ }
29
+ /* WordPress Compatibility Fixes */
30
+ #root {
31
+ min-height: 100vh;
32
+ width: 100%;
33
+ position: relative;
34
+ z-index: 10;
35
+ }
36
+
37
+ ::-webkit-scrollbar {
38
+ width: 6px;
39
+ }
40
+ ::-webkit-scrollbar-track {
41
+ background: #0f172a;
42
+ }
43
+ ::-webkit-scrollbar-thumb {
44
+ background: #334155;
45
+ border-radius: 3px;
46
+ }
47
+ ::-webkit-scrollbar-thumb:hover {
48
+ background: #475569;
49
+ }
50
+ /* Custom Animations */
51
+ @keyframes gradient {
52
+ 0% { background-position: 0% 50%; }
53
+ 50% { background-position: 100% 50%; }
54
+ 100% { background-position: 0% 50%; }
55
+ }
56
+ .animate-gradient-x {
57
+ animation: gradient 3s ease infinite;
58
+ }
59
+
60
+ .glass-panel {
61
+ background: rgba(19, 23, 34, 0.8);
62
+ backdrop-filter: blur(12px);
63
+ -webkit-backdrop-filter: blur(12px);
64
+ border: 1px solid rgba(255, 255, 255, 0.05);
65
+ }
66
+ </style>
67
+
68
+ <!-- Import Map to resolve modules -->
69
+ <script type="importmap">
70
+ {
71
+ "imports": {
72
+ "react": "https://esm.sh/react@18.2.0",
73
+ "react-dom/client": "https://esm.sh/react-dom@18.2.0/client",
74
+ "framer-motion": "https://esm.sh/framer-motion@10.16.4",
75
+ "lucide-react": "https://esm.sh/lucide-react@0.292.0",
76
+ "react-dom/": "https://esm.sh/react-dom@^19.2.4/",
77
+ "react/": "https://esm.sh/react@^19.2.4/"
78
+ }
79
+ }
80
+ </script>
81
+ </head>
82
+ <body>
83
+ <div id="root"></div>
84
+
85
+ <!-- MAIN APPLICATION SCRIPT -->
86
+ <script type="text/babel" data-type="module">
87
+ import React, { useState, useEffect } from 'react';
88
+ import ReactDOM from 'react-dom/client';
89
+ import { motion, AnimatePresence } from 'framer-motion';
90
+ import {
91
+ Mic2,
92
+ Wand2,
93
+ Podcast,
94
+ Fingerprint,
95
+ Activity,
96
+ Music,
97
+ Settings,
98
+ User,
99
+ Bell,
100
+ ArrowLeft,
101
+ Sparkles,
102
+ Play,
103
+ Square,
104
+ Volume2,
105
+ X
106
+ } from 'lucide-react';
107
+
108
+ // --- CONSTANTS & DATA ---
109
+ const APP_NAME = "آوا هوش";
110
+
111
+ const FEATURES = [
112
+ {
113
+ id: 'tts',
114
+ title: 'تبدیل متن به گفتار',
115
+ subtitle: '۳۰ گوینده حرفه‌ای',
116
+ icon: Mic2,
117
+ colorFrom: 'from-blue-500',
118
+ colorTo: 'to-cyan-400',
119
+ isHot: true
120
+ },
121
+ {
122
+ id: 'voice-changer',
123
+ title: 'تغییر صدا',
124
+ subtitle: 'مدل‌های جذاب فارسی',
125
+ icon: Wand2,
126
+ colorFrom: 'from-violet-500',
127
+ colorTo: 'to-purple-500'
128
+ },
129
+ {
130
+ id: 'podcast',
131
+ title: 'ساخت پادکست',
132
+ subtitle: 'تولید خودکار با هوش مصنوعی',
133
+ icon: Podcast,
134
+ colorFrom: 'from-pink-500',
135
+ colorTo: 'to-rose-500'
136
+ },
137
+ {
138
+ id: 'clone',
139
+ title: 'کلون کردن صدا',
140
+ subtitle: 'شبیه‌سازی دقیق صدا',
141
+ icon: Fingerprint,
142
+ colorFrom: 'from-amber-500',
143
+ colorTo: 'to-orange-500',
144
+ isNew: true
145
+ },
146
+ {
147
+ id: 'enhance',
148
+ title: 'افزایش کیفیت',
149
+ subtitle: 'حذف نویز و شفاف‌سازی',
150
+ icon: Activity,
151
+ colorFrom: 'from-emerald-500',
152
+ colorTo: 'to-green-400'
153
+ }
154
+ ];
155
+
156
+ const SPECIAL_FEATURE = {
157
+ id: 'ai-gen',
158
+ title: 'تولید صدا Ai',
159
+ subtitle: 'خلق افکت‌های صوتی خاص',
160
+ icon: Music,
161
+ colorFrom: 'from-indigo-600',
162
+ colorTo: 'to-blue-600'
163
+ };
164
+
165
+ const IMAGES = [
166
+ "https://app.puzzley.net/uploads/user/Jydo/%D8%AA%D8%BA%DB%8C%D8%B1%20%D8%B5%D8%AF%D8%A7%20%D8%A8%D8%A7%20%D9%87%D9%88%D8%B4%20%D9%85%D8%B5%D9%86%D9%88%D8%B9%DB%8C/tmpxposlxsv.png?_t=1769590682",
167
+ "https://app.puzzley.net/uploads/user/Jydo/%D8%AA%D8%BA%DB%8C%D8%B1%20%D8%B5%D8%AF%D8%A7%20%D8%A8%D8%A7%20%D9%87%D9%88%D8%B4%20%D9%85%D8%B5%D9%86%D9%88%D8%B9%DB%8C/tmpnv5v143z.png?_t=1769590682",
168
+ "https://app.puzzley.net/uploads/user/Jydo/%D8%AA%D8%BA%DB%8C%D8%B1%20%D8%B5%D8%AF%D8%A7%20%D8%A8%D8%A7%20%D9%87%D9%88%D8%B4%20%D9%85%D8%B5%D9%86%D9%88%D8%B9%DB%8C/tmpkqpm8k8l.png?_t=1769590756"
169
+ ];
170
+
171
+ // --- COMPONENTS ---
172
+
173
+ // 1. Background Effects
174
+ const Particle = ({ index }) => {
175
+ const randomX = Math.random() * 100;
176
+ const randomDelay = Math.random() * 5;
177
+ const randomDuration = 10 + Math.random() * 10;
178
+
179
+ return (
180
+ <motion.div
181
+ className="absolute w-1 h-1 bg-white rounded-full opacity-0"
182
+ initial={{ x: `${randomX}vw`, y: '110vh', opacity: 0 }}
183
+ animate={{
184
+ y: '-10vh',
185
+ opacity: [0, 0.3, 0]
186
+ }}
187
+ transition={{
188
+ duration: randomDuration,
189
+ repeat: Infinity,
190
+ delay: randomDelay,
191
+ ease: "linear"
192
+ }}
193
+ style={{
194
+ left: 0,
195
+ filter: 'blur(1px)'
196
+ }}
197
+ />
198
+ );
199
+ };
200
+
201
+ const BackgroundEffects = () => {
202
+ return (
203
+ <div className="fixed inset-0 z-0 overflow-hidden pointer-events-none bg-[#0B0F19]">
204
+ <div
205
+ className="absolute inset-0 opacity-[0.04]"
206
+ style={{
207
+ backgroundImage: `linear-gradient(#fff 1px, transparent 1px), linear-gradient(90deg, #fff 1px, transparent 1px)`,
208
+ backgroundSize: '50px 50px'
209
+ }}
210
+ ></div>
211
+ {[...Array(15)].map((_, i) => <Particle key={i} index={i} />)}
212
+ <motion.div
213
+ animate={{ scale: [1, 1.15, 1], opacity: [0.15, 0.35, 0.15], rotate: [0, 20, 0] }}
214
+ transition={{ duration: 12, repeat: Infinity, ease: "easeInOut" }}
215
+ className="absolute -top-[10%] -right-[20%] w-[600px] h-[600px] bg-gradient-to-br from-violet-600/20 to-indigo-600/20 rounded-full blur-[120px]"
216
+ />
217
+ <motion.div
218
+ animate={{ scale: [1, 1.25, 1], opacity: [0.1, 0.25, 0.1], x: [0, 30, 0] }}
219
+ transition={{ duration: 15, repeat: Infinity, ease: "easeInOut", delay: 1 }}
220
+ className="absolute top-[40%] -left-[20%] w-[500px] h-[500px] bg-gradient-to-tr from-blue-600/15 to-cyan-500/15 rounded-full blur-[100px]"
221
+ />
222
+ <div className="absolute inset-0 bg-gradient-to-b from-transparent via-[#0B0F19]/60 to-[#0B0F19] pointer-events-none"></div>
223
+ </div>
224
+ );
225
+ };
226
+
227
+ // 2. Header
228
+ const Header = () => {
229
+ return (
230
+ <header className="relative z-20 flex items-center justify-between px-6 pt-6 pb-2">
231
+ <div className="flex items-center gap-3">
232
+ <div className="relative group cursor-pointer">
233
+ <div className="w-10 h-10 rounded-xl bg-gradient-to-br from-violet-600 to-indigo-600 flex items-center justify-center shadow-lg shadow-indigo-500/30 ring-2 ring-white/5">
234
+ <span className="text-xl font-black text-white pb-1">آ</span>
235
+ </div>
236
+ <span className="absolute -top-0.5 -right-0.5 flex h-2.5 w-2.5">
237
+ <span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-cyan-400 opacity-75"></span>
238
+ <span className="relative inline-flex rounded-full h-2.5 w-2.5 bg-cyan-500 border-2 border-[#0B0F19]"></span>
239
+ </span>
240
+ </div>
241
+ <h1 className="text-lg font-bold text-slate-200 tracking-wide opacity-90">{APP_NAME}</h1>
242
+ </div>
243
+ <div className="flex gap-2">
244
+ <button className="p-2 rounded-full bg-white/5 text-white/70 hover:bg-white/10 transition-colors">
245
+ <Bell size={20} />
246
+ </button>
247
+ </div>
248
+ </header>
249
+ );
250
+ };
251
+
252
+ // 3. Hero
253
+ const Hero = () => {
254
+ return (
255
+ <div className="px-6 py-4 mb-2 relative z-10 text-center">
256
+ <motion.div
257
+ initial={{ opacity: 0, y: 10 }}
258
+ animate={{ opacity: 1, y: 0 }}
259
+ transition={{ duration: 0.6, ease: "easeOut", delay: 0.2 }}
260
+ >
261
+ <h2 className="text-2xl font-black text-white mb-2 leading-tight">
262
+ جعبه ابزار <span className="text-transparent bg-clip-text bg-gradient-to-r from-indigo-300 to-cyan-300">هوش مصنوعی</span>
263
+ </h2>
264
+
265
+ <p className="text-slate-400 text-xs leading-5 font-light opacity-80">
266
+ بهترین ابزارها برای ویرایش و تولید صدا
267
+ </p>
268
+ </motion.div>
269
+ </div>
270
+ );
271
+ };
272
+
273
+ // 4. Feature Card
274
+ const FeatureCard = ({ item, index, onClick }) => {
275
+ return (
276
+ <motion.div
277
+ initial={{ opacity: 0, scale: 0.9, y: 30 }}
278
+ animate={{ opacity: 1, scale: 1, y: 0 }}
279
+ transition={{ delay: index * 0.1 + 0.2, duration: 0.5, type: "spring", stiffness: 100, damping: 20 }}
280
+ whileTap={{ scale: 0.96 }}
281
+ onClick={onClick}
282
+ className="relative group cursor-pointer"
283
+ >
284
+ <div className={`absolute -inset-[1px] rounded-[24px] bg-gradient-to-b ${item.colorFrom} ${item.colorTo} opacity-0 group-hover:opacity-40 blur-md transition duration-500`}></div>
285
+ <div className="relative h-full flex flex-col justify-between bg-[#131722]/80 backdrop-blur-xl border border-white/5 p-4 rounded-[24px] shadow-xl overflow-hidden hover:border-white/15 transition-all duration-300">
286
+ <div className="absolute inset-0 z-0 translate-x-[-100%] group-hover:translate-x-[100%] transition-transform duration-1000 bg-gradient-to-r from-transparent via-white/5 to-transparent skew-x-12"></div>
287
+ <div className="flex justify-between items-start mb-4 relative z-10">
288
+ <div className={`relative p-3 rounded-2xl bg-gradient-to-br ${item.colorFrom} ${item.colorTo} shadow-lg ring-1 ring-white/20 group-hover:scale-105 transition-transform duration-300`}>
289
+ <motion.div
290
+ animate={{ rotate: [0, 5, -5, 0] }}
291
+ transition={{ duration: 4, repeat: Infinity, ease: "easeInOut", delay: index * 0.5 }}
292
+ >
293
+ <item.icon className="text-white w-5 h-5 relative z-10" strokeWidth={2} />
294
+ </motion.div>
295
+ </div>
296
+ {(item.isNew || item.isHot) && (
297
+ <motion.div
298
+ initial={{ scale: 0 }}
299
+ animate={{ scale: 1 }}
300
+ transition={{ delay: 0.5 + index * 0.1, type: "spring" }}
301
+ className="flex flex-col items-end gap-1"
302
+ >
303
+ {item.isNew && (
304
+ <span className="px-2 py-0.5 text-[8px] font-bold bg-gradient-to-r from-amber-400 to-orange-500 text-white rounded-full shadow-lg shadow-amber-500/20">جدید</span>
305
+ )}
306
+ {item.isHot && (
307
+ <span className="px-2 py-0.5 text-[8px] font-bold bg-gradient-to-r from-rose-500 to-pink-600 text-white rounded-full shadow-lg shadow-rose-500/20">داغ</span>
308
+ )}
309
+ </motion.div>
310
+ )}
311
+ </div>
312
+ <div className="relative z-10">
313
+ <h3 className="text-[15px] font-bold text-white mb-1 tracking-tight group-hover:text-transparent group-hover:bg-clip-text group-hover:bg-gradient-to-r group-hover:from-white group-hover:to-slate-300 transition-colors">{item.title}</h3>
314
+ <p className="text-[10px] text-slate-400 font-medium leading-relaxed opacity-80 group-hover:opacity-100 transition-opacity">{item.subtitle}</p>
315
+ </div>
316
+ </div>
317
+ </motion.div>
318
+ );
319
+ };
320
+
321
+ // 5. Special Card
322
+ const SpecialCard = ({ item }) => {
323
+ return (
324
+ <motion.div
325
+ initial={{ opacity: 0, scale: 0.95, y: 20 }}
326
+ animate={{ opacity: 1, scale: 1, y: 0 }}
327
+ transition={{ delay: 0.6, duration: 0.6, ease: "easeOut" }}
328
+ whileTap={{ scale: 0.98 }}
329
+ className="relative w-full cursor-pointer group"
330
+ >
331
+ <div className="absolute -inset-[2px] bg-gradient-to-r from-indigo-500 via-purple-500 to-pink-500 rounded-[26px] opacity-70 blur-sm group-hover:opacity-100 group-hover:blur-md transition duration-500 animate-pulse"></div>
332
+ <div className="relative overflow-hidden p-5 bg-[#0f1219] rounded-[24px] border border-white/10">
333
+ <div className="absolute inset-0 opacity-20">
334
+ <div className="absolute top-0 right-0 w-64 h-64 bg-indigo-600 rounded-full blur-[80px] animate-pulse"></div>
335
+ <div className="absolute bottom-0 left-0 w-64 h-64 bg-purple-600 rounded-full blur-[80px] animate-pulse" style={{ animationDelay: '1s' }}></div>
336
+ </div>
337
+ <div className="relative z-10 flex items-center justify-between gap-4">
338
+ <div className="flex items-center gap-4">
339
+ <div className="relative">
340
+ <div className={`w-14 h-14 rounded-2xl bg-gradient-to-br ${item.colorFrom} ${item.colorTo} flex items-center justify-center shadow-lg shadow-indigo-500/30 ring-4 ring-indigo-500/10 group-hover:scale-105 transition-transform duration-300`}>
341
+ <motion.div animate={{ rotate: [0, 10, -10, 0] }} transition={{ duration: 5, repeat: Infinity, ease: "easeInOut" }}>
342
+ <item.icon className="text-white w-7 h-7" strokeWidth={2.5} />
343
+ </motion.div>
344
+ </div>
345
+ <div className="absolute -top-2 -right-2 bg-white text-indigo-700 text-[9px] font-black px-1.5 py-0.5 rounded-full shadow-md border-2 border-[#0f1219]">Ai</div>
346
+ </div>
347
+ <div>
348
+ <div className="flex items-center gap-2 mb-1">
349
+ <h3 className="text-lg font-black text-white">{item.title}</h3>
350
+ <Sparkles className="w-4 h-4 text-yellow-400 fill-yellow-400" />
351
+ </div>
352
+ <p className="text-xs text-slate-300 font-medium opacity-90 max-w-[150px] leading-relaxed">{item.subtitle}</p>
353
+ </div>
354
+ </div>
355
+ <div className="w-10 h-10 rounded-full bg-white/10 hover:bg-white text-white hover:text-indigo-900 flex items-center justify-center border border-white/10 transition-all duration-300">
356
+ <ArrowLeft className="w-4 h-4" strokeWidth={3} />
357
+ </div>
358
+ </div>
359
+ </div>
360
+ </motion.div>
361
+ );
362
+ };
363
+
364
+ // 6. Image Slider
365
+ const ImageSlider = () => {
366
+ const [currentIndex, setCurrentIndex] = useState(0);
367
+ useEffect(() => {
368
+ const timer = setInterval(() => {
369
+ setCurrentIndex((prev) => (prev + 1) % IMAGES.length);
370
+ }, 4000);
371
+ return () => clearInterval(timer);
372
+ }, []);
373
+ return (
374
+ <div className="relative w-full aspect-[2.4/1] rounded-[24px] overflow-hidden shadow-2xl ring-1 ring-white/10 mb-4 group z-20">
375
+ <AnimatePresence mode='popLayout'>
376
+ <motion.img
377
+ key={currentIndex}
378
+ src={IMAGES[currentIndex]}
379
+ alt={`Slide ${currentIndex + 1}`}
380
+ initial={{ opacity: 0, scale: 1.1 }}
381
+ animate={{ opacity: 1, scale: 1 }}
382
+ exit={{ opacity: 0 }}
383
+ transition={{ duration: 0.7 }}
384
+ className="absolute inset-0 w-full h-full object-cover"
385
+ />
386
+ </AnimatePresence>
387
+ <div className="absolute inset-0 bg-gradient-to-t from-[#0B0F19]/80 via-transparent to-transparent opacity-80"></div>
388
+ <div className="absolute bottom-3 left-1/2 -translate-x-1/2 flex gap-1.5 z-10">
389
+ {IMAGES.map((_, index) => (
390
+ <div key={index} className={`h-1.5 rounded-full transition-all duration-300 ${index === currentIndex ? 'w-5 bg-white' : 'w-1.5 bg-white/40'}`} />
391
+ ))}
392
+ </div>
393
+ </div>
394
+ );
395
+ };
396
+
397
+ // 7. TTS Overlay (Text to Speech Feature)
398
+ const TTSOverlay = ({ onClose }) => {
399
+ const [text, setText] = useState('');
400
+ const [speaking, setSpeaking] = useState(false);
401
+
402
+ const speak = () => {
403
+ if (!text) return;
404
+ window.speechSynthesis.cancel();
405
+ // Create utterance
406
+ const u = new SpeechSynthesisUtterance(text);
407
+ // Attempt to use a Persian voice if available, otherwise default
408
+ // iOS/Android usually select based on lang code
409
+ u.lang = 'fa-IR';
410
+ u.rate = 0.9;
411
+
412
+ u.onstart = () => setSpeaking(true);
413
+ u.onend = () => setSpeaking(false);
414
+ u.onerror = () => setSpeaking(false);
415
+
416
+ window.speechSynthesis.speak(u);
417
+ };
418
+
419
+ const stop = () => {
420
+ window.speechSynthesis.cancel();
421
+ setSpeaking(false);
422
+ };
423
+
424
+ return (
425
+ <motion.div
426
+ initial={{ opacity: 0, y: "100%" }}
427
+ animate={{ opacity: 1, y: 0 }}
428
+ exit={{ opacity: 0, y: "100%" }}
429
+ transition={{ type: "spring", damping: 25, stiffness: 200 }}
430
+ className="fixed inset-0 z-50 bg-[#0f172a] flex flex-col"
431
+ style={{ position: 'fixed', top: 0, left: 0, right: 0, bottom: 0 }}
432
+ >
433
+ <BackgroundEffects />
434
+
435
+ {/* Header */}
436
+ <div className="relative z-10 px-6 py-4 flex items-center justify-between glass-panel border-b-0">
437
+ <button onClick={onClose} className="w-10 h-10 rounded-full bg-white/10 flex items-center justify-center active:scale-95 transition-transform">
438
+ <ArrowLeft className="text-white" size={20} />
439
+ </button>
440
+ <h2 className="text-lg font-bold text-white">تبدیل متن به صدا</h2>
441
+ <div className="w-10"></div>
442
+ </div>
443
+
444
+ {/* Content */}
445
+ <div className="relative z-10 flex-1 p-6 flex flex-col gap-6">
446
+ <div className="flex-1 glass-panel rounded-3xl p-1 overflow-hidden shadow-2xl">
447
+ <textarea
448
+ className="w-full h-full bg-transparent p-5 text-right text-lg text-white placeholder-slate-400 focus:outline-none resize-none leading-loose"
449
+ placeholder="متن خود را اینجا بنویسید... (مثال: سلام، به آوا هوش خوش آمدید)"
450
+ value={text}
451
+ onChange={e => setText(e.target.value)}
452
+ />
453
+ </div>
454
+
455
+ {/* Controls */}
456
+ <div className="flex flex-col gap-4 mb-4">
457
+ <motion.button
458
+ whileTap={{ scale: 0.98 }}
459
+ onClick={speaking ? stop : speak}
460
+ className={`w-full py-5 rounded-2xl font-bold text-lg flex items-center justify-center gap-3 shadow-xl transition-all relative overflow-hidden ${speaking ? 'bg-rose-500' : 'bg-gradient-to-r from-blue-600 to-indigo-600'}`}
461
+ >
462
+ {speaking ? (
463
+ <>
464
+ <Square fill="currentColor" size={20} />
465
+ <span>توقف پخش</span>
466
+ <span className="absolute right-4 w-2 h-2 bg-white rounded-full animate-ping"></span>
467
+ </>
468
+ ) : (
469
+ <>
470
+ <Play fill="currentColor" size={24} />
471
+ <span>پخش صدا</span>
472
+ </>
473
+ )}
474
+ </motion.button>
475
+ </div>
476
+ </div>
477
+ </motion.div>
478
+ );
479
+ };
480
+
481
+ // --- MAIN APP COMPONENT ---
482
+ const App = () => {
483
+ const [activeFeature, setActiveFeature] = useState(null);
484
+
485
+ const handleFeatureClick = (id) => {
486
+ if (id === 'tts') {
487
+ setActiveFeature('tts');
488
+ } else {
489
+ // For other features just show a simple alert or log for now
490
+ console.log(`Feature ${id} clicked`);
491
+ }
492
+ };
493
+
494
+ return (
495
+ <div className="min-h-screen relative overflow-x-hidden pb-10">
496
+ <BackgroundEffects />
497
+
498
+ <main className="relative z-10 pt-2">
499
+ <Header />
500
+
501
+ <div className="px-6 mb-2">
502
+ <ImageSlider />
503
+ </div>
504
+
505
+ <Hero />
506
+
507
+ <div className="px-6 mt-2">
508
+ <div className="grid grid-cols-2 gap-4">
509
+ {FEATURES.map((item, index) => (
510
+ <FeatureCard
511
+ key={item.id}
512
+ item={item}
513
+ index={index}
514
+ onClick={() => handleFeatureClick(item.id)}
515
+ />
516
+ ))}
517
+ </div>
518
+
519
+ <div className="mt-6 mb-4">
520
+ <SpecialCard item={SPECIAL_FEATURE} />
521
+ </div>
522
+
523
+ <div className="text-center mt-8 opacity-40">
524
+ <p className="text-[10px] text-slate-300 font-light tracking-widest">
525
+ POWERED BY AVA HOOSH • VER 2.0
526
+ </p>
527
+ </div>
528
+ </div>
529
+ </main>
530
+
531
+ {/* Overlays */}
532
+ <AnimatePresence>
533
+ {activeFeature === 'tts' && (
534
+ <TTSOverlay key="tts" onClose={() => setActiveFeature(null)} />
535
+ )}
536
+ </AnimatePresence>
537
+ </div>
538
+ );
539
+ };
540
+
541
+ // --- RENDER ---
542
+ const rootElement = document.getElementById('root');
543
+ const root = ReactDOM.createRoot(rootElement);
544
+ root.render(
545
+ <React.StrictMode>
546
+ <App />
547
+ </React.StrictMode>
548
+ );
549
+ </script>
550
+ </body>
551
+ </html>