AiCoderv2 commited on
Commit
8ca1c31
·
verified ·
1 Parent(s): 0cc06e8

Update app.py from anycoder

Browse files
Files changed (1) hide show
  1. app.py +1087 -787
app.py CHANGED
@@ -1,32 +1,41 @@
1
  import gradio as gr
2
  import time
3
  import random
 
4
  from typing import List, Dict, Any
 
5
 
6
- def generate_website_code(description: str, complexity: str) -> Dict[str, str]:
7
  """
8
- Simulate AI website generation using Qwen models.
9
- In a real implementation, this would call the actual Qwen model.
10
  """
11
  start_time = time.time()
12
 
13
- # Simulate different website types based on description
14
  description_lower = description.lower()
15
 
16
- # Generate HTML, CSS, and JS based on the description
17
  if "portfolio" in description_lower or "personal" in description_lower:
18
- html_code = generate_portfolio_site(description)
19
  elif "business" in description_lower or "company" in description_lower:
20
- html_code = generate_business_site(description)
21
  elif "blog" in description_lower:
22
- html_code = generate_blog_site(description)
23
  elif "landing" in description_lower or "product" in description_lower:
24
- html_code = generate_landing_site(description)
 
 
25
  else:
26
- html_code = generate_simple_site(description)
27
 
28
- css_code = generate_css(complexity)
29
- js_code = generate_javascript(complexity)
 
 
 
 
 
 
30
 
31
  generation_time = time.time() - start_time
32
 
@@ -35,787 +44,1011 @@ def generate_website_code(description: str, complexity: str) -> Dict[str, str]:
35
  "css": css_code,
36
  "javascript": js_code,
37
  "generation_time": f"{generation_time:.2f}s",
 
 
 
 
38
  "status": "✅ Website generated successfully!" if generation_time < 15 else "⚠️ Generation took longer than expected"
39
  }
40
 
41
- def generate_simple_site(description: str) -> str:
42
- """Generate a simple website template"""
43
  return f'''<!DOCTYPE html>
44
  <html lang="en">
45
  <head>
46
  <meta charset="UTF-8">
47
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
48
- <title>Generated Website</title>
49
  <link rel="stylesheet" href="style.css">
 
50
  </head>
51
  <body>
52
  <header>
53
  <nav>
54
- <div class="logo">My Website</div>
55
- <ul class="nav-links">
56
- <li><a href="#home">Home</a></li>
57
- <li><a href="#about">About</a></li>
58
- <li><a href="#services">Services</a></li>
59
- <li><a href="#contact">Contact</a></li>
60
- </ul>
61
- </nav>
62
- </header>
63
-
64
- <main>
65
- <section id="hero" class="hero">
66
- <div class="hero-content">
67
- <h1>Welcome to Our Website</h1>
68
- <p>Generated based on: "{description}"</p>
69
- <button class="cta-button">Get Started</button>
70
  </div>
71
- </section>
72
-
73
- <section id="features" class="features">
74
- <div class="container">
75
- <h2>Features</h2>
76
- <div class="feature-grid">
77
- <div class="feature-card">
78
- <h3>Feature 1</h3>
79
- <p>Amazing feature description</p>
80
- </div>
81
- <div class="feature-card">
82
- <h3>Feature 2</h3>
83
- <p>Another great feature</p>
84
- </div>
85
- <div class="feature-card">
86
- <h3>Feature 3</h3>
87
- <p>Third amazing feature</p>
88
- </div>
89
- </div>
90
  </div>
91
- </section>
92
- </main>
93
-
94
- <footer>
95
- <p>&copy; 2024 Generated Website. All rights reserved.</p>
96
- </footer>
97
- <script src="script.js"></script>
98
- </body>
99
- </html>'''
100
-
101
- def generate_portfolio_site(description: str) -> str:
102
- """Generate a portfolio website template"""
103
- return f'''<!DOCTYPE html>
104
- <html lang="en">
105
- <head>
106
- <meta charset="UTF-8">
107
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
108
- <title>Portfolio - Generated Website</title>
109
- <link rel="stylesheet" href="style.css">
110
- </head>
111
- <body>
112
- <header>
113
- <nav>
114
- <div class="logo">Portfolio</div>
115
- <ul class="nav-links">
116
- <li><a href="#home">Home</a></li>
117
- <li><a href="#about">About</a></li>
118
- <li><a href="#projects">Projects</a></li>
119
- <li><a href="#contact">Contact</a></li>
120
- </ul>
121
  </nav>
122
  </header>
123
 
124
  <main>
125
- <section id="hero" class="hero">
126
  <div class="hero-content">
127
- <h1>John Doe</h1>
128
- <p>Web Developer & Designer</p>
129
- <p class="description">Based on: "{description}"</p>
130
- <div class="hero-buttons">
131
- <button class="cta-button">View My Work</button>
132
- <button class="secondary-button">Contact Me</button>
133
- </div>
134
  </div>
135
  </section>
136
 
137
- <section id="projects" class="projects">
138
  <div class="container">
139
- <h2>My Projects</h2>
140
- <div class="project-grid">
141
- <div class="project-card">
142
- <h3>Project 1</h3>
143
- <p>Amazing project description</p>
144
- <a href="#" class="project-link">View Project</a>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
  </div>
146
- <div class="project-card">
147
- <h3>Project 2</h3>
148
- <p>Another great project</p>
149
- <a href="#" class="project-link">View Project</a>
 
 
 
 
 
150
  </div>
151
  </div>
152
  </div>
153
  </section>
154
- </main>
155
-
156
- <footer>
157
- <p>&copy; 2024 Portfolio Website. Built with passion.</p>
158
- </footer>
159
- <script src="script.js"></script>
160
- </body>
161
- </html>'''
162
-
163
- def generate_business_site(description: str) -> str:
164
- """Generate a business website template"""
165
- return f'''<!DOCTYPE html>
166
- <html lang="en">
167
- <head>
168
- <meta charset="UTF-8">
169
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
170
- <title>Business Website</title>
171
- <link rel="stylesheet" href="style.css">
172
- </head>
173
- <body>
174
- <header>
175
- <nav>
176
- <div class="logo">BusinessName</div>
177
- <ul class="nav-links">
178
- <li><a href="#home">Home</a></li>
179
- <li><a href="#services">Services</a></li>
180
- <li><a href="#about">About</a></li>
181
- <li><a href="#contact">Contact</a></li>
182
- </ul>
183
- </nav>
184
- </header>
185
-
186
- <main>
187
- <section id="hero" class="hero business-hero">
188
- <div class="hero-content">
189
- <h1>Professional Business Solutions</h1>
190
- <p>Generated for: "{description}"</p>
191
- <button class="cta-button">Get Quote</button>
192
- </div>
193
- </section>
194
 
195
- <section id="services" class="services">
196
  <div class="container">
197
- <h2>Our Services</h2>
198
- <div class="service-grid">
199
- <div class="service-card">
200
- <h3>Service 1</h3>
201
- <p>Professional service description</p>
202
  </div>
203
- <div class="service-card">
204
- <h3>Service 2</h3>
205
- <p>Expert service offering</p>
206
  </div>
207
- <div class="service-card">
208
- <h3>Service 3</h3>
209
- <p>Quality service solution</p>
210
  </div>
211
  </div>
212
  </div>
213
  </section>
214
-
215
- <section id="contact" class="contact">
216
- <div class="container">
217
- <h2>Contact Us</h2>
218
- <p>Ready to get started? Contact us today!</p>
219
- <button class="cta-button">Contact Now</button>
220
- </div>
221
- </section>
222
- </main>
223
-
224
- <footer>
225
- <p>&copy; 2024 Business Website. Professional solutions.</p>
226
- </footer>
227
- <script src="script.js"></script>
228
- </body>
229
- </html>'''
230
-
231
- def generate_blog_site(description: str) -> str:
232
- """Generate a blog website template"""
233
- return f'''<!DOCTYPE html>
234
- <html lang="en">
235
- <head>
236
- <meta charset="UTF-8">
237
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
238
- <title>My Blog</title>
239
- <link rel="stylesheet" href="style.css">
240
- </head>
241
- <body>
242
- <header>
243
- <nav>
244
- <div class="logo">MyBlog</div>
245
- <ul class="nav-links">
246
- <li><a href="#home">Home</a></li>
247
- <li><a href="#posts">Posts</a></li>
248
- <li><a href="#about">About</a></li>
249
- <li><a href="#contact">Contact</a></li>
250
- </ul>
251
- </nav>
252
- </header>
253
-
254
- <main>
255
- <section id="hero" class="hero">
256
- <div class="hero-content">
257
- <h1>Welcome to My Blog</h1>
258
- <p>Generated for: "{description}"</p>
259
- <p>Sharing thoughts, stories, and insights</p>
260
- </div>
261
- </section>
262
-
263
- <section id="posts" class="blog-posts">
264
- <div class="container">
265
- <h2>Latest Posts</h2>
266
- <div class="post-grid">
267
- <article class="post-card">
268
- <h3>Blog Post 1</h3>
269
- <p class="post-excerpt">This is an excerpt from the first blog post...</p>
270
- <a href="#" class="read-more">Read More</a>
271
- </article>
272
- <article class="post-card">
273
- <h3>Blog Post 2</h3>
274
- <p class="post-excerpt">This is an excerpt from the second blog post...</p>
275
- <a href="#" class="read-more">Read More</a>
276
- </article>
277
- <article class="post-card">
278
- <h3>Blog Post 3</h3>
279
- <p class="post-excerpt">This is an excerpt from the third blog post...</p>
280
- <a href="#" class="read-more">Read More</a>
281
- </article>
282
- </div>
283
- </div>
284
- </section>
285
  </main>
286
 
287
  <footer>
288
- <p>&copy; 2024 My Blog. All rights reserved.</p>
289
- </footer>
290
- <script src="script.js"></script>
291
- </body>
292
- </html>'''
293
-
294
- def generate_landing_site(description: str) -> str:
295
- """Generate a landing page template"""
296
- return f'''<!DOCTYPE html>
297
- <html lang="en">
298
- <head>
299
- <meta charset="UTF-8">
300
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
301
- <title>Product Landing Page</title>
302
- <link rel="stylesheet" href="style.css">
303
- </head>
304
- <body>
305
- <header>
306
- <nav>
307
- <div class="logo">ProductName</div>
308
- <ul class="nav-links">
309
- <li><a href="#features">Features</a></li>
310
- <li><a href="#pricing">Pricing</a></li>
311
- <li><a href="#contact">Contact</a></li>
312
- </ul>
313
- </nav>
314
- </header>
315
-
316
- <main>
317
- <section id="hero" class="hero landing-hero">
318
- <div class="hero-content">
319
- <h1>Amazing Product</h1>
320
- <p>Revolutionary solution for: "{description}"</p>
321
- <p>Transform your business today!</p>
322
- <div class="hero-buttons">
323
- <button class="cta-button">Start Free Trial</button>
324
- <button class="secondary-button">Watch Demo</button>
325
  </div>
326
- </div>
327
- </section>
328
-
329
- <section id="features" class="features">
330
- <div class="container">
331
- <h2>Key Features</h2>
332
- <div class="feature-grid">
333
- <div class="feature-card">
334
- <h3>🚀 Fast</h3>
335
- <p>Lightning-fast performance</p>
336
- </div>
337
- <div class="feature-card">
338
- <h3>🔒 Secure</h3>
339
- <p>Enterprise-grade security</p>
340
- </div>
341
- <div class="feature-card">
342
- <h3>📱 Responsive</h3>
343
- <p>Works on all devices</p>
344
- </div>
345
  </div>
346
- </div>
347
- </section>
348
-
349
- <section id="pricing" class="pricing">
350
- <div class="container">
351
- <h2>Simple Pricing</h2>
352
- <div class="pricing-grid">
353
- <div class="pricing-card">
354
- <h3>Starter</h3>
355
- <div class="price">$9/month</div>
356
- <ul>
357
- <li>Basic features</li>
358
- <li>Email support</li>
359
- </ul>
360
- <button class="cta-button">Get Started</button>
361
- </div>
362
- <div class="pricing-card featured">
363
- <h3>Pro</h3>
364
- <div class="price">$29/month</div>
365
- <ul>
366
- <li>All features</li>
367
- <li>Priority support</li>
368
- <li>Advanced analytics</li>
369
- </ul>
370
- <button class="cta-button">Get Started</button>
371
  </div>
372
  </div>
373
  </div>
374
- </section>
375
- </main>
376
-
377
- <footer>
378
- <p>&copy; 2024 Product Landing Page. Built with passion.</p>
379
  </footer>
380
  <script src="script.js"></script>
381
  </body>
382
  </html>'''
383
 
384
- def generate_css(complexity: str) -> str:
385
- """Generate CSS based on complexity level"""
386
- base_css = '''
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
387
  /* Reset and base styles */
388
- * {
389
  margin: 0;
390
  padding: 0;
391
  box-sizing: border-box;
392
- }
393
 
394
- body {
395
- font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
 
 
 
 
 
 
 
 
 
 
396
  line-height: 1.6;
397
- color: #333;
398
- }
399
 
400
- .container {
401
  max-width: 1200px;
402
  margin: 0 auto;
403
  padding: 0 20px;
404
- }
405
 
406
- /* Header styles */
407
- header {
408
  background: #fff;
409
- box-shadow: 0 2px 10px rgba(0,0,0,0.1);
410
  position: fixed;
411
  width: 100%;
412
  top: 0;
413
  z-index: 1000;
414
- }
415
 
416
- nav {
417
  display: flex;
418
  justify-content: space-between;
419
  align-items: center;
420
  padding: 1rem 2rem;
421
- }
422
 
423
- .logo {
424
  font-size: 1.5rem;
425
  font-weight: bold;
426
- color: #333;
427
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
428
 
429
- .nav-links {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
430
  display: flex;
431
  list-style: none;
432
  gap: 2rem;
433
- }
434
 
435
- .nav-links a {
436
  text-decoration: none;
437
- color: #333;
438
  font-weight: 500;
439
- transition: color 0.3s;
440
- }
441
 
442
- .nav-links a:hover {
443
- color: #007bff;
444
- }
445
 
446
- /* Hero section */
447
- .hero {
448
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
 
 
 
 
 
 
 
 
 
 
 
 
 
449
  color: white;
450
  text-align: center;
451
  padding: 150px 0 100px;
452
  margin-top: 80px;
453
- }
 
454
 
455
- .hero-content h1 {
456
- font-size: 3rem;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
457
  margin-bottom: 1rem;
458
  font-weight: 700;
459
- }
460
 
461
- .hero-content p {
462
  font-size: 1.2rem;
463
  margin-bottom: 2rem;
464
  opacity: 0.9;
465
- }
466
 
467
- .hero-buttons {
468
  display: flex;
469
  gap: 1rem;
470
  justify-content: center;
471
  flex-wrap: wrap;
472
- }
473
 
474
- .cta-button {
475
- background: #007bff;
476
  color: white;
477
  border: none;
478
- padding: 12px 30px;
479
- border-radius: 5px;
480
  font-size: 1rem;
481
  font-weight: 600;
482
  cursor: pointer;
483
- transition: all 0.3s;
484
  text-decoration: none;
485
  display: inline-block;
486
- }
 
 
 
 
 
 
 
 
 
 
 
487
 
488
- .cta-button:hover {
489
- background: #0056b3;
 
 
 
490
  transform: translateY(-2px);
491
- }
492
 
493
- .secondary-button {
494
  background: transparent;
495
  color: white;
496
  border: 2px solid white;
497
- padding: 10px 28px;
498
- border-radius: 5px;
499
  font-size: 1rem;
500
  font-weight: 600;
501
  cursor: pointer;
502
- transition: all 0.3s;
503
  text-decoration: none;
504
  display: inline-block;
505
- }
506
 
507
- .secondary-button:hover {
508
  background: white;
509
- color: #333;
510
- }
511
 
512
- /* Features section */
513
- .features {
514
  padding: 80px 0;
515
- background: #f8f9fa;
516
- }
517
 
518
- .features h2 {
 
 
 
 
 
 
 
 
 
519
  text-align: center;
520
  font-size: 2.5rem;
521
  margin-bottom: 3rem;
522
- color: #333;
523
- }
524
 
525
- .feature-grid {
 
 
 
 
 
 
 
 
 
 
 
 
526
  display: grid;
527
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
528
  gap: 2rem;
529
  margin-top: 3rem;
530
- }
531
 
532
- .feature-card {
 
 
 
 
 
 
 
533
  background: white;
534
  padding: 2rem;
535
- border-radius: 10px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
536
  text-align: center;
537
- box-shadow: 0 5px 15px rgba(0,0,0,0.08);
538
- transition: transform 0.3s;
539
- }
540
 
541
- .feature-card:hover {
542
- transform: translateY(-5px);
543
- }
 
 
 
 
 
 
 
 
 
544
 
545
- .feature-card h3 {
 
 
 
 
546
  font-size: 1.5rem;
 
 
547
  margin-bottom: 1rem;
548
- color: #333;
549
- }
550
 
551
- .feature-card p {
552
- color: #666;
553
- line-height: 1.6;
554
- }
 
 
 
 
555
 
556
- /* Additional styles for other sections */
557
- .projects, .services, .blog-posts {
558
- padding: 80px 0;
559
- }
560
 
561
- .projects h2, .services h2, .blog-posts h2 {
562
  text-align: center;
563
- font-size: 2.5rem;
564
- margin-bottom: 3rem;
565
- color: #333;
566
- }
 
 
 
 
 
 
 
 
 
 
 
567
 
568
- .project-grid, .service-grid, .post-grid {
569
  display: grid;
570
- grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
571
  gap: 2rem;
572
- }
573
 
574
- .project-card, .service-card, .post-card {
575
- background: white;
576
- padding: 2rem;
577
- border-radius: 10px;
578
- box-shadow: 0 5px 15px rgba(0,0,0,0.08);
579
- transition: transform 0.3s;
580
- }
581
 
582
- .project-card:hover, .service-card:hover, .post-card:hover {
583
- transform: translateY(-5px);
584
- }
585
 
586
- .project-link, .read-more {
587
- color: #007bff;
 
 
 
588
  text-decoration: none;
589
- font-weight: 600;
590
- }
591
 
592
- .project-link:hover, .read-more:hover {
593
- text-decoration: underline;
594
- }
595
 
596
- /* Pricing section */
597
- .pricing {
598
- padding: 80px 0;
599
- background: #f8f9fa;
600
- }
601
-
602
- .pricing h2 {
603
- text-align: center;
604
- font-size: 2.5rem;
605
- margin-bottom: 3rem;
606
- color: #333;
607
- }
608
 
609
- .pricing-grid {
610
- display: grid;
611
- grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
612
- gap: 2rem;
613
- max-width: 800px;
614
- margin: 0 auto;
615
- }
616
 
617
- .pricing-card {
618
- background: white;
619
- padding: 2rem;
620
- border-radius: 10px;
621
- text-align: center;
622
- box-shadow: 0 5px 15px rgba(0,0,0,0.08);
623
- }
624
 
625
- .pricing-card.featured {
626
- border: 2px solid #007bff;
627
- transform: scale(1.05);
628
- }
 
629
 
630
- .price {
631
- font-size: 2rem;
632
- font-weight: bold;
633
- color: #007bff;
634
- margin: 1rem 0;
635
- }
636
 
637
- .pricing-card ul {
638
- list-style: none;
639
- margin: 2rem 0;
640
- }
641
 
642
- .pricing-card li {
643
- padding: 0.5rem 0;
644
- border-bottom: 1px solid #eee;
645
- }
646
 
647
- /* Footer */
648
- footer {
649
- background: #333;
650
- color: white;
651
- text-align: center;
652
- padding: 2rem 0;
653
- }
654
 
655
  /* Responsive design */
656
- @media (max-width: 768px) {
657
- .nav-links {
658
  display: none;
659
- }
660
-
661
- .hero-content h1 {
662
- font-size: 2rem;
663
- }
664
-
665
- .hero-content p {
 
666
  font-size: 1rem;
667
- }
668
-
669
- .hero-buttons {
670
  flex-direction: column;
671
  align-items: center;
672
- }
673
-
674
- .feature-grid, .project-grid, .service-grid, .post-grid {
675
  grid-template-columns: 1fr;
676
- }
677
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
678
  '''
679
 
680
  if complexity == "Advanced":
681
  base_css += '''
682
  /* Advanced styling additions */
683
- .business-hero {
684
- background: linear-gradient(135deg, #2c3e50 0%, #34495e 100%);
685
  }
686
 
687
- .landing-hero {
688
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
689
- }
690
 
691
- .hero {
692
- position: relative;
693
- overflow: hidden;
 
694
  }
695
 
696
- .hero::before {
697
- content: '';
698
- position: absolute;
699
- top: 0;
700
- left: 0;
701
- right: 0;
702
- bottom: 0;
703
- background: rgba(0,0,0,0.3);
704
- z-index: 1;
705
  }
706
 
707
- .hero-content {
708
- position: relative;
709
- z-index: 2;
 
 
 
710
  }
711
 
712
- .feature-card h3 {
713
- font-size: 2rem;
714
- margin-bottom: 1rem;
 
715
  }
716
 
717
- .feature-card:nth-child(1) h3 { color: #e74c3c; }
718
- .feature-card:nth-child(2) h3 { color: #3498db; }
719
- .feature-card:nth-child(3) h3 { color: #2ecc71; }
720
-
721
- .post-excerpt {
722
- color: #666;
723
- margin-bottom: 1rem;
724
- line-height: 1.6;
 
725
  }
726
 
727
- /* Smooth scrolling */
728
- html {
729
- scroll-behavior: smooth;
730
  }
731
 
732
- /* Loading animations */
733
- @keyframes fadeInUp {
734
- from {
735
- opacity: 0;
736
- transform: translateY(30px);
 
 
 
 
737
  }
738
- to {
739
- opacity: 1;
740
- transform: translateY(0);
 
 
 
 
 
 
 
 
741
  }
742
  }
743
 
744
- .feature-card, .project-card, .service-card, .post-card {
745
- animation: fadeInUp 0.6s ease-out;
746
  }
747
  '''
748
 
749
  return base_css
750
 
751
- def generate_javascript(complexity: str) -> str:
752
- """Generate JavaScript based on complexity level"""
753
  base_js = '''
754
- // Basic functionality
755
  document.addEventListener('DOMContentLoaded', function() {
756
- // Smooth scrolling for navigation links
757
- const navLinks = document.querySelectorAll('.nav-links a');
758
- navLinks.forEach(link => {
759
- link.addEventListener('click', function(e) {
760
- e.preventDefault();
761
- const targetId = this.getAttribute('href').substring(1);
762
- const targetSection = document.getElementById(targetId);
763
-
764
- if (targetSection) {
765
- const headerHeight = document.querySelector('header').offsetHeight;
766
- const targetPosition = targetSection.offsetTop - headerHeight;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
767
 
768
- window.scrollTo({
769
- top: targetPosition,
770
- behavior: 'smooth'
771
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
772
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
773
  });
774
- });
775
-
776
- // CTA button functionality
777
- const ctaButtons = document.querySelectorAll('.cta-button');
778
- ctaButtons.forEach(button => {
779
- button.addEventListener('click', function() {
780
- // Simulate action (e.g., redirect to contact form)
781
- alert('Thank you for your interest! This would typically redirect to a contact form or signup page.');
782
  });
783
- });
784
-
785
- // Secondary button functionality
786
- const secondaryButtons = document.querySelectorAll('.secondary-button');
787
- secondaryButtons.forEach(button => {
788
- button.addEventListener('click', function() {
789
- // Simulate demo action
790
- alert('Demo video would start here!');
 
 
 
 
791
  });
792
- });
793
-
794
- // Add loading animation to cards
795
- const cards = document.querySelectorAll('.feature-card, .project-card, .service-card, .post-card');
796
- const observer = new IntersectionObserver((entries) => {
797
- entries.forEach(entry => {
798
- if (entry.isIntersecting) {
799
- entry.target.style.opacity = '1';
800
- entry.target.style.transform = 'translateY(0)';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
801
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
802
  });
803
- });
804
-
805
- cards.forEach(card => {
806
- card.style.opacity = '0';
807
- card.style.transform = 'translateY(30px)';
808
- card.style.transition = 'opacity 0.6s ease, transform 0.6s ease';
809
- observer.observe(card);
810
- });
811
-
812
- // Mobile menu toggle (if needed)
813
- const mobileMenuToggle = document.querySelector('.mobile-menu-toggle');
814
- const navLinks = document.querySelector('.nav-links');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
815
 
816
- if (mobileMenuToggle) {
817
- mobileMenuToggle.addEventListener('click', function() {
818
- navLinks.classList.toggle('active');
 
 
 
 
 
819
  });
820
  }
821
  });
@@ -824,229 +1057,296 @@ document.addEventListener('DOMContentLoaded', function() {
824
  if complexity == "Advanced":
825
  base_js += '''
826
 
827
- // Advanced functionality
828
- // Parallax effect for hero section
829
- window.addEventListener('scroll', function() {
830
- const scrolled = window.pageYOffset;
831
- const hero = document.querySelector('.hero');
832
- if (hero) {
833
- hero.style.transform = `translateY(${scrolled * 0.5}px)`;
 
 
 
 
834
  }
835
- });
836
-
837
- // Add dynamic typing effect to hero text
838
- function typeWriter(element, text, speed = 50) {
839
- let i = 0;
840
- element.innerHTML = '';
841
 
842
- function type() {
843
- if (i < text.length) {
844
- element.innerHTML += text.charAt(i);
845
- i++;
846
- setTimeout(type, speed);
 
 
 
847
  }
848
  }
849
- type();
850
- }
851
-
852
- // Initialize typing effect for main heading
853
- const heroHeading = document.querySelector('.hero-content h1');
854
- if (heroHeading) {
855
- const originalText = heroHeading.textContent;
856
- setTimeout(() => {
857
- typeWriter(heroHeading, originalText, 100);
858
- }, 500);
859
- }
860
-
861
- // Add hover effects to cards
862
- cards.forEach(card => {
863
- card.addEventListener('mouseenter', function() {
864
- this.style.transform = 'translateY(-10px) scale(1.02)';
865
- this.style.boxShadow = '0 20px 40px rgba(0,0,0,0.15)';
866
- });
867
 
868
- card.addEventListener('mouseleave', function() {
869
- this.style.transform = 'translateY(-5px) scale(1)';
870
- this.style.boxShadow = '0 5px 15px rgba(0,0,0,0.08)';
871
- });
872
- });
873
-
874
- // Add counter animation for pricing
875
- function animateCounter(element, target, duration = 2000) {
876
- let start = 0;
877
- const increment = target / (duration / 16);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
878
 
879
- function updateCounter() {
880
- start += increment;
881
- if (start < target) {
882
- element.textContent = Math.floor(start);
883
- requestAnimationFrame(updateCounter);
884
- } else {
885
- element.textContent = target;
 
886
  }
887
  }
888
- updateCounter();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
889
  }
890
 
891
- // Animate price counters when they come into view
892
- const priceElements = document.querySelectorAll('.price');
893
- const priceObserver = new IntersectionObserver((entries) => {
894
- entries.forEach(entry => {
895
- if (entry.isIntersecting) {
896
- const priceText = entry.target.textContent;
897
- const priceNumber = parseInt(priceText.replace(/[^0-9]/g, ''));
898
- animateCounter(entry.target, priceNumber);
899
- priceObserver.unobserve(entry.target);
 
 
900
  }
901
- });
902
  });
903
 
904
- priceElements.forEach(price => {
905
- priceObserver.observe(price);
906
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
907
  '''
908
 
909
  return base_js
910
 
911
- # Custom theme for modern look
912
- custom_theme = gr.themes.Soft(
913
- primary_hue="blue",
914
- secondary_hue="indigo",
915
- neutral_hue="slate",
916
- font=gr.themes.GoogleFont("Inter"),
917
- text_size="lg",
918
- spacing_size="lg",
919
- radius_size="md"
920
- ).set(
921
- button_primary_background_fill="*primary_600",
922
- button_primary_background_fill_hover="*primary_700",
923
- block_title_text_weight="600",
924
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
925
 
926
- with gr.Blocks(title="AI Web Coder - Qwen Powered", theme=custom_theme) as demo:
 
927
 
928
- # Header with attribution
929
- gr.HTML("""
930
- <div style="text-align: center; margin-bottom: 20px; padding: 10px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border-radius: 10px;">
931
- <h1 style="margin: 0; font-size: 2.5rem;">🚀 AI Web Coder</h1>
932
- <p style="margin: 5px 0 0 0; font-size: 1.1rem;">Powered by Qwen Small Models - Generate websites in under 15 seconds!</p>
933
- <p style="margin: 10px 0 0 0; font-size: 0.9rem; opacity: 0.9;">
934
- <a href="https://huggingface.co/spaces/akhaliq/anycoder" style="color: white; text-decoration: underline;">Built with anycoder</a>
935
- </p>
936
- </div>
937
- """)
938
 
939
- with gr.Row():
940
- with gr.Column(scale=1):
941
- gr.Markdown("### 🎯 Describe Your Website")
942
-
943
- description = gr.Textbox(
944
- label="What kind of website do you want?",
945
- placeholder="e.g., 'A personal portfolio for a web developer', 'A business landing page for a coffee shop', 'A blog about travel'",
946
- lines=3,
947
- info="Describe your website idea - the AI will generate appropriate code based on your description"
948
- )
949
-
950
- complexity = gr.Radio(
951
- choices=["Basic", "Advanced"],
952
- value="Basic",
953
- label="Complexity Level",
954
- info="Basic: Clean, responsive design | Advanced: Enhanced animations and effects"
955
- )
956
-
957
- generate_btn = gr.Button("🚀 Generate Website", variant="primary", size="lg")
958
-
959
- gr.Markdown("""
960
- ### 💡 Tips for Better Results
961
- - Be specific about the purpose (portfolio, business, blog, etc.)
962
- - Mention target audience or industry
963
- - Include key features you want
964
- - Specify style preferences (modern, minimal, etc.)
965
- """)
966
-
967
- with gr.Column(scale=2):
968
- gr.Markdown("### 📄 Generated Code")
969
-
970
- with gr.Tab("HTML"):
971
- html_output = gr.Code(label="HTML Code", language="html", lines=20)
972
-
973
- with gr.Tab("CSS"):
974
- css_output = gr.Code(label="CSS Code", language="css", lines=20)
975
-
976
- with gr.Tab("JavaScript"):
977
- js_output = gr.Code(label="JavaScript Code", language="javascript", lines=15)
978
-
979
- with gr.Row():
980
- generation_info = gr.Markdown("ℹ️ Click 'Generate Website' to start")
981
- download_btn = gr.Button("💾 Download All Files", variant="secondary")
982
 
983
- # Generation function
984
- def handle_generation(desc, comp_level):
985
- if not desc.strip():
986
- gr.Warning("Please describe your website idea!")
987
- return "", "", "", "⚠️ Please provide a description"
988
-
989
- try:
990
- result = generate_website_code(desc, comp_level)
991
- return (
992
- result["html"],
993
- result["css"],
994
- result["javascript"],
995
- f"✅ {result['status']}\n\n🕒 Generation time: {result['generation_time']}\n📝 Complexity: {comp_level}"
996
- )
997
- except Exception as e:
998
- return "", "", "", f"❌ Error: {str(e)}"
999
 
1000
- # Event handlers
1001
- generate_btn.click(
1002
- fn=handle_generation,
1003
- inputs=[description, complexity],
1004
- outputs=[html_output, css_output, js_output, generation_info],
1005
- api_visibility="public",
1006
- show_progress="full"
1007
- )
 
1008
 
1009
- # Download functionality (placeholder)
1010
- def download_files(html_code, css_code, js_code):
1011
- if not html_code:
1012
- gr.Warning("Please generate a website first!")
1013
- return
1014
-
1015
- # In a real implementation, this would create downloadable files
1016
- return "Files would be downloaded here. In a real app, this would package the HTML, CSS, and JS into a zip file."
1017
 
1018
- download_btn.click(
1019
- fn=download_files,
1020
- inputs=[html_output, css_output, js_output],
1021
- outputs=[generation_info],
1022
- api_visibility="private"
1023
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
1024
 
1025
- # Examples section
1026
- gr.Markdown("### 🎨 Example Prompts")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1027
 
1028
- with gr.Row():
1029
- gr.Examples(
1030
- examples=[
1031
- "A personal portfolio for a web developer with projects section",
1032
- "A modern coffee shop website with menu and contact info",
1033
- "A tech startup landing page with pricing and features",
1034
- "A travel blog with photo galleries and travel tips",
1035
- "A restaurant website with online reservations",
1036
- "A fitness trainer website with services and testimonials"
1037
- ],
1038
- inputs=description,
1039
- examples_per_page=3
1040
- )
1041
-
1042
- # Launch the application
1043
- demo.launch(
1044
- theme=custom_theme,
1045
- share=True,
1046
- show_error=True,
1047
- height=600,
1048
- footer_links=[
1049
- {"label": "Built with anycoder", "url": "https://huggingface.co/spaces/akhaliq/anycoder"},
1050
- {"label": "Powered by Qwen", "url": "https://huggingface.co/Qwen"}
1051
  ]
1052
- )
 
 
 
 
 
 
 
 
 
 
 
 
1
  import gradio as gr
2
  import time
3
  import random
4
+ import re
5
  from typing import List, Dict, Any
6
+ import json
7
 
8
+ def generate_website_code(description: str, complexity: str, color_scheme: str = "Blue", layout_style: str = "Modern") -> Dict[str, str]:
9
  """
10
+ Enhanced AI website generation with multiple customization options.
 
11
  """
12
  start_time = time.time()
13
 
14
+ # Generate HTML, CSS, and JS with new features
15
  description_lower = description.lower()
16
 
17
+ # Smart template selection
18
  if "portfolio" in description_lower or "personal" in description_lower:
19
+ html_code = generate_portfolio_site(description, color_scheme, layout_style)
20
  elif "business" in description_lower or "company" in description_lower:
21
+ html_code = generate_business_site(description, color_scheme, layout_style)
22
  elif "blog" in description_lower:
23
+ html_code = generate_blog_site(description, color_scheme, layout_style)
24
  elif "landing" in description_lower or "product" in description_lower:
25
+ html_code = generate_landing_site(description, color_scheme, layout_style)
26
+ elif "ecommerce" in description_lower or "shop" in description_lower or "store" in description_lower:
27
+ html_code = generate_ecommerce_site(description, color_scheme, layout_style)
28
  else:
29
+ html_code = generate_simple_site(description, color_scheme, layout_style)
30
 
31
+ css_code = generate_enhanced_css(complexity, color_scheme, layout_style)
32
+ js_code = generate_enhanced_javascript(complexity)
33
+
34
+ # Add SEO and accessibility features
35
+ html_code = enhance_html_with_seo_accessibility(html_code, description)
36
+
37
+ # Code quality analysis
38
+ quality_metrics = analyze_code_quality(html_code, css_code, js_code)
39
 
40
  generation_time = time.time() - start_time
41
 
 
44
  "css": css_code,
45
  "javascript": js_code,
46
  "generation_time": f"{generation_time:.2f}s",
47
+ "quality_score": f"{quality_metrics['score']}/100",
48
+ "performance_tips": quality_metrics['tips'],
49
+ "accessibility_score": f"{quality_metrics['accessibility']}/100",
50
+ "seo_score": f"{quality_metrics['seo']}/100",
51
  "status": "✅ Website generated successfully!" if generation_time < 15 else "⚠️ Generation took longer than expected"
52
  }
53
 
54
+ def generate_ecommerce_site(description: str, color_scheme: str, layout_style: str) -> str:
55
+ """Generate an e-commerce website template"""
56
  return f'''<!DOCTYPE html>
57
  <html lang="en">
58
  <head>
59
  <meta charset="UTF-8">
60
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
61
+ <title>E-Commerce Store - Generated Website</title>
62
  <link rel="stylesheet" href="style.css">
63
+ <meta name="description" content="Generated e-commerce store based on: {description}">
64
  </head>
65
  <body>
66
  <header>
67
  <nav>
68
+ <div class="logo">ShopNow</div>
69
+ <div class="search-bar">
70
+ <input type="text" placeholder="Search products..." aria-label="Search products">
71
+ <button class="search-btn" aria-label="Search">🔍</button>
 
 
 
 
 
 
 
 
 
 
 
 
72
  </div>
73
+ <div class="nav-icons">
74
+ <button class="icon-btn" aria-label="User account">👤</button>
75
+ <button class="icon-btn cart-btn" aria-label="Shopping cart">🛒 <span class="cart-count">0</span></button>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  </nav>
78
  </header>
79
 
80
  <main>
81
+ <section id="hero" class="hero ecommerce-hero">
82
  <div class="hero-content">
83
+ <h1>Premium Quality Products</h1>
84
+ <p>Generated for: "{description}"</p>
85
+ <p>Discover amazing products at unbeatable prices!</p>
86
+ <button class="cta-button">Shop Now</button>
 
 
 
87
  </div>
88
  </section>
89
 
90
+ <section id="products" class="products">
91
  <div class="container">
92
+ <h2>Featured Products</h2>
93
+ <div class="product-grid">
94
+ <div class="product-card">
95
+ <div class="product-image">
96
+ <div class="placeholder-img">🛍️</div>
97
+ </div>
98
+ <div class="product-info">
99
+ <h3>Product 1</h3>
100
+ <p class="price">$29.99</p>
101
+ <button class="add-to-cart">Add to Cart</button>
102
+ </div>
103
+ </div>
104
+ <div class="product-card">
105
+ <div class="product-image">
106
+ <div class="placeholder-img">👕</div>
107
+ </div>
108
+ <div class="product-info">
109
+ <h3>Product 2</h3>
110
+ <p class="price">$49.99</p>
111
+ <button class="add-to-cart">Add to Cart</button>
112
+ </div>
113
  </div>
114
+ <div class="product-card">
115
+ <div class="product-image">
116
+ <div class="placeholder-img">👟</div>
117
+ </div>
118
+ <div class="product-info">
119
+ <h3>Product 3</h3>
120
+ <p class="price">$79.99</p>
121
+ <button class="add-to-cart">Add to Cart</button>
122
+ </div>
123
  </div>
124
  </div>
125
  </div>
126
  </section>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
127
 
128
+ <section id="categories" class="categories">
129
  <div class="container">
130
+ <h2>Shop by Category</h2>
131
+ <div class="category-grid">
132
+ <div class="category-card">
133
+ <div class="category-icon">📱</div>
134
+ <h3>Electronics</h3>
135
  </div>
136
+ <div class="category-card">
137
+ <div class="category-icon">👕</div>
138
+ <h3>Clothing</h3>
139
  </div>
140
+ <div class="category-card">
141
+ <div class="category-icon">🏠</div>
142
+ <h3>Home & Garden</h3>
143
  </div>
144
  </div>
145
  </div>
146
  </section>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
  </main>
148
 
149
  <footer>
150
+ <div class="container">
151
+ <div class="footer-content">
152
+ <div class="footer-section">
153
+ <h3>Customer Service</h3>
154
+ <ul>
155
+ <li><a href="#">Contact Us</a></li>
156
+ <li><a href="#">Shipping Info</a></li>
157
+ <li><a href="#">Returns</a></li>
158
+ </ul>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
159
  </div>
160
+ <div class="footer-section">
161
+ <h3>About Us</h3>
162
+ <ul>
163
+ <li><a href="#">Our Story</a></li>
164
+ <li><a href="#">Careers</a></li>
165
+ <li><a href="#">Press</a></li>
166
+ </ul>
 
 
 
 
 
 
 
 
 
 
 
 
167
  </div>
168
+ <div class="footer-section">
169
+ <h3>Connect</h3>
170
+ <div class="social-links">
171
+ <a href="#" aria-label="Facebook">📘</a>
172
+ <a href="#" aria-label="Twitter">🐦</a>
173
+ <a href="#" aria-label="Instagram">📷</a>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
174
  </div>
175
  </div>
176
  </div>
177
+ <p>&copy; 2024 ShopNow. All rights reserved.</p>
178
+ </div>
 
 
 
179
  </footer>
180
  <script src="script.js"></script>
181
  </body>
182
  </html>'''
183
 
184
+ def generate_enhanced_css(complexity: str, color_scheme: str, layout_style: str) -> str:
185
+ """Generate enhanced CSS with multiple themes and layouts"""
186
+
187
+ # Color schemes
188
+ color_schemes = {
189
+ "Blue": {
190
+ "primary": "#007bff",
191
+ "secondary": "#0056b3",
192
+ "accent": "#17a2b8",
193
+ "background": "#f8f9fa",
194
+ "text": "#333333"
195
+ },
196
+ "Green": {
197
+ "primary": "#28a745",
198
+ "secondary": "#1e7e34",
199
+ "accent": "#20c997",
200
+ "background": "#f8fff8",
201
+ "text": "#333333"
202
+ },
203
+ "Purple": {
204
+ "primary": "#6f42c1",
205
+ "secondary": "#5a32a3",
206
+ "accent": "#e83e8c",
207
+ "background": "#faf8ff",
208
+ "text": "#333333"
209
+ },
210
+ "Orange": {
211
+ "primary": "#fd7e14",
212
+ "secondary": "#e8650e",
213
+ "accent": "#ffc107",
214
+ "background": "#fffbf5",
215
+ "text": "#333333"
216
+ }
217
+ }
218
+
219
+ colors = color_schemes.get(color_scheme, color_schemes["Blue"])
220
+
221
+ base_css = f'''
222
  /* Reset and base styles */
223
+ * {{
224
  margin: 0;
225
  padding: 0;
226
  box-sizing: border-box;
 
227
 
228
+ :root {{
229
+ --primary-color: {colors['primary']};
230
+ --secondary-color: {colors['secondary']};
231
+ --accent-color: {colors['accent']};
232
+ --background-color: {colors['background']};
233
+ --text-color: {colors['text']};
234
+ --border-radius: 8px;
235
+ --shadow: 0 2px 10px rgba(0,0,0,0.1);
236
+ --transition: all 0.3s ease;
237
+
238
+ body {{
239
+ font-family: 'Inter', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
240
  line-height: 1.6;
241
+ color: var(--text-color);
242
+ background-color: var(--background-color);
243
 
244
+ .container {{
245
  max-width: 1200px;
246
  margin: 0 auto;
247
  padding: 0 20px;
 
248
 
249
+ /* Enhanced header */
250
+ header {{
251
  background: #fff;
252
+ box-shadow: var(--shadow);
253
  position: fixed;
254
  width: 100%;
255
  top: 0;
256
  z-index: 1000;
257
+ backdrop-filter: blur(10px);
258
 
259
+ nav {{
260
  display: flex;
261
  justify-content: space-between;
262
  align-items: center;
263
  padding: 1rem 2rem;
 
264
 
265
+ .logo {{
266
  font-size: 1.5rem;
267
  font-weight: bold;
268
+ color: var(--primary-color);
269
+ transition: var(--transition);
270
+
271
+ .logo:hover {{
272
+ color: var(--secondary-color);
273
+
274
+ .search-bar {{
275
+ display: flex;
276
+ flex: 1;
277
+ max-width: 400px;
278
+ margin: 0 2rem;
279
+
280
+ .search-bar input {{
281
+ flex: 1;
282
+ padding: 10px 15px;
283
+ border: 2px solid #e0e0e0;
284
+ border-radius: var(--border-radius) 0 0 var(--border-radius);
285
+ font-size: 14px;
286
+ transition: var(--transition);
287
+
288
+ .search-bar input:focus {{
289
+ outline: none;
290
+ border-color: var(--primary-color);
291
+
292
+ .search-btn {{
293
+ padding: 10px 15px;
294
+ background: var(--primary-color);
295
+ color: white;
296
+ border: none;
297
+ border-radius: 0 var(--border-radius) var(--border-radius) 0;
298
+ cursor: pointer;
299
+ transition: var(--transition);
300
+
301
+ .search-btn:hover {{
302
+ background: var(--secondary-color);
303
+
304
+ .nav-icons {{
305
+ display: flex;
306
+ gap: 1rem;
307
+
308
+ .icon-btn {{
309
+ background: none;
310
+ border: none;
311
+ font-size: 1.2rem;
312
+ cursor: pointer;
313
+ padding: 8px;
314
+ border-radius: 50%;
315
+ transition: var(--transition);
316
+ position: relative;
317
+
318
+ .icon-btn:hover {{
319
+ background: var(--background-color);
320
 
321
+ .cart-count {{
322
+ position: absolute;
323
+ top: -5px;
324
+ right: -5px;
325
+ background: var(--primary-color);
326
+ color: white;
327
+ border-radius: 50%;
328
+ width: 18px;
329
+ height: 18px;
330
+ font-size: 10px;
331
+ display: flex;
332
+ align-items: center;
333
+ justify-content: center;
334
+
335
+ .nav-links {{
336
  display: flex;
337
  list-style: none;
338
  gap: 2rem;
 
339
 
340
+ .nav-links a {{
341
  text-decoration: none;
342
+ color: var(--text-color);
343
  font-weight: 500;
344
+ transition: var(--transition);
345
+ position: relative;
346
 
347
+ .nav-links a:hover {{
348
+ color: var(--primary-color);
 
349
 
350
+ .nav-links a::after {{
351
+ content: '';
352
+ position: absolute;
353
+ width: 0;
354
+ height: 2px;
355
+ bottom: -5px;
356
+ left: 0;
357
+ background: var(--primary-color);
358
+ transition: var(--transition);
359
+
360
+ .nav-links a:hover::after {{
361
+ width: 100%;
362
+
363
+ /* Enhanced hero sections */
364
+ .hero {{
365
+ background: linear-gradient(135deg, var(--primary-color) 0%, var(--accent-color) 100%);
366
  color: white;
367
  text-align: center;
368
  padding: 150px 0 100px;
369
  margin-top: 80px;
370
+ position: relative;
371
+ overflow: hidden;
372
 
373
+ .ecommerce-hero {{
374
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
375
+
376
+ .landing-hero {{
377
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
378
+
379
+ .hero::before {{
380
+ content: '';
381
+ position: absolute;
382
+ top: 0;
383
+ left: 0;
384
+ right: 0;
385
+ bottom: 0;
386
+ background: rgba(0,0,0,0.1);
387
+ z-index: 1;
388
+
389
+ .hero-content {{
390
+ position: relative;
391
+ z-index: 2;
392
+
393
+ .hero-content h1 {{
394
+ font-size: 3.5rem;
395
  margin-bottom: 1rem;
396
  font-weight: 700;
397
+ animation: fadeInUp 0.8s ease;
398
 
399
+ .hero-content p {{
400
  font-size: 1.2rem;
401
  margin-bottom: 2rem;
402
  opacity: 0.9;
403
+ animation: fadeInUp 0.8s ease 0.2s both;
404
 
405
+ .hero-buttons {{
406
  display: flex;
407
  gap: 1rem;
408
  justify-content: center;
409
  flex-wrap: wrap;
410
+ animation: fadeInUp 0.8s ease 0.4s both;
411
 
412
+ .cta-button {{
413
+ background: var(--primary-color);
414
  color: white;
415
  border: none;
416
+ padding: 15px 35px;
417
+ border-radius: var(--border-radius);
418
  font-size: 1rem;
419
  font-weight: 600;
420
  cursor: pointer;
421
+ transition: var(--transition);
422
  text-decoration: none;
423
  display: inline-block;
424
+ position: relative;
425
+ overflow: hidden;
426
+
427
+ .cta-button::before {{
428
+ content: '';
429
+ position: absolute;
430
+ top: 0;
431
+ left: -100%;
432
+ width: 100%;
433
+ height: 100%;
434
+ background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
435
+ transition: var(--transition);
436
 
437
+ .cta-button:hover::before {{
438
+ left: 100%;
439
+
440
+ .cta-button:hover {{
441
+ background: var(--secondary-color);
442
  transform: translateY(-2px);
443
+ box-shadow: 0 10px 20px rgba(0,0,0,0.2);
444
 
445
+ .secondary-button {{
446
  background: transparent;
447
  color: white;
448
  border: 2px solid white;
449
+ padding: 13px 33px;
450
+ border-radius: var(--border-radius);
451
  font-size: 1rem;
452
  font-weight: 600;
453
  cursor: pointer;
454
+ transition: var(--transition);
455
  text-decoration: none;
456
  display: inline-block;
 
457
 
458
+ .secondary-button:hover {{
459
  background: white;
460
+ color: var(--primary-color);
461
+ transform: translateY(-2px);
462
 
463
+ /* Enhanced sections */
464
+ .features, .products, .services, .blog-posts, .categories {{
465
  padding: 80px 0;
 
 
466
 
467
+ .features {{
468
+ background: var(--background-color);
469
+
470
+ .products {{
471
+ background: #fff;
472
+
473
+ .categories {{
474
+ background: var(--background-color);
475
+
476
+ .features h2, .products h2, .services h2, .blog-posts h2, .categories h2 {{
477
  text-align: center;
478
  font-size: 2.5rem;
479
  margin-bottom: 3rem;
480
+ color: var(--text-color);
481
+ position: relative;
482
 
483
+ .features h2::after, .products h2::after, .services h2::after, .blog-posts h2::after, .categories h2::after {{
484
+ content: '';
485
+ position: absolute;
486
+ bottom: -10px;
487
+ left: 50%;
488
+ transform: translateX(-50%);
489
+ width: 60px;
490
+ height: 3px;
491
+ background: var(--primary-color);
492
+ border-radius: 2px;
493
+
494
+ /* Enhanced grid layouts */
495
+ .feature-grid, .product-grid, .service-grid, .post-grid, .category-grid {{
496
  display: grid;
497
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
498
  gap: 2rem;
499
  margin-top: 3rem;
 
500
 
501
+ .product-grid {{
502
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
503
+
504
+ .category-grid {{
505
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
506
+
507
+ /* Enhanced cards */
508
+ .feature-card, .product-card, .service-card, .post-card, .category-card {{
509
  background: white;
510
  padding: 2rem;
511
+ border-radius: var(--border-radius);
512
+ box-shadow: var(--shadow);
513
+ transition: var(--transition);
514
+ position: relative;
515
+ overflow: hidden;
516
+
517
+ .feature-card::before, .product-card::before, .service-card::before, .post-card::before, .category-card::before {{
518
+ content: '';
519
+ position: absolute;
520
+ top: 0;
521
+ left: 0;
522
+ right: 0;
523
+ height: 4px;
524
+ background: linear-gradient(90deg, var(--primary-color), var(--accent-color));
525
+
526
+ .feature-card:hover, .product-card:hover, .service-card:hover, .post-card:hover, .category-card:hover {{
527
+ transform: translateY(-10px);
528
+ box-shadow: 0 20px 40px rgba(0,0,0,0.15);
529
+
530
+ .product-card {{
531
  text-align: center;
 
 
 
532
 
533
+ .product-image {{
534
+ margin-bottom: 1rem;
535
+
536
+ .placeholder-img {{
537
+ width: 100%;
538
+ height: 200px;
539
+ background: var(--background-color);
540
+ display: flex;
541
+ align-items: center;
542
+ justify-content: center;
543
+ font-size: 3rem;
544
+ border-radius: var(--border-radius);
545
 
546
+ .product-info h3 {{
547
+ margin-bottom: 0.5rem;
548
+ color: var(--text-color);
549
+
550
+ .price {{
551
  font-size: 1.5rem;
552
+ font-weight: bold;
553
+ color: var(--primary-color);
554
  margin-bottom: 1rem;
 
 
555
 
556
+ .add-to-cart {{
557
+ background: var(--primary-color);
558
+ color: white;
559
+ border: none;
560
+ padding: 10px 20px;
561
+ border-radius: var(--border-radius);
562
+ cursor: pointer;
563
+ transition: var(--transition);
564
 
565
+ .add-to-cart:hover {{
566
+ background: var(--secondary-color);
567
+ transform: translateY(-2px);
 
568
 
569
+ .category-card {{
570
  text-align: center;
571
+ padding: 3rem 2rem;
572
+
573
+ .category-icon {{
574
+ font-size: 3rem;
575
+ margin-bottom: 1rem;
576
+
577
+ .category-card h3 {{
578
+ color: var(--text-color);
579
+ font-size: 1.3rem;
580
+
581
+ /* Footer enhancements */
582
+ footer {{
583
+ background: var(--text-color);
584
+ color: white;
585
+ padding: 3rem 0 1rem;
586
 
587
+ .footer-content {{
588
  display: grid;
589
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
590
  gap: 2rem;
591
+ margin-bottom: 2rem;
592
 
593
+ .footer-section h3 {{
594
+ margin-bottom: 1rem;
595
+ color: var(--accent-color);
 
 
 
 
596
 
597
+ .footer-section ul {{
598
+ list-style: none;
 
599
 
600
+ .footer-section li {{
601
+ margin-bottom: 0.5rem;
602
+
603
+ .footer-section a {{
604
+ color: #ccc;
605
  text-decoration: none;
606
+ transition: var(--transition);
 
607
 
608
+ .footer-section a:hover {{
609
+ color: var(--accent-color);
 
610
 
611
+ .social-links {{
612
+ display: flex;
613
+ gap: 1rem;
 
 
 
 
 
 
 
 
 
614
 
615
+ .social-links a {{
616
+ font-size: 1.5rem;
617
+ transition: var(--transition);
 
 
 
 
618
 
619
+ .social-links a:hover {{
620
+ transform: scale(1.2);
 
 
 
 
 
621
 
622
+ /* Animations */
623
+ @keyframes fadeInUp {{
624
+ from {{
625
+ opacity: 0;
626
+ transform: translateY(30px);
627
 
628
+ to {{
629
+ opacity: 1;
630
+ transform: translateY(0);
 
 
 
631
 
 
 
 
 
632
 
633
+ @keyframes pulse {{
634
+ 0%, 100% {{ transform: scale(1); }}
635
+ 50% {{ transform: scale(1.05); }}
 
636
 
637
+ .pulse {{
638
+ animation: pulse 2s infinite;
 
 
 
 
 
639
 
640
  /* Responsive design */
641
+ @media (max-width: 768px) {{
642
+ .nav-links {{
643
  display: none;
644
+
645
+ .search-bar {{
646
+ margin: 0 1rem;
647
+
648
+ .hero-content h1 {{
649
+ font-size: 2.5rem;
650
+
651
+ .hero-content p {{
652
  font-size: 1rem;
653
+
654
+ .hero-buttons {{
 
655
  flex-direction: column;
656
  align-items: center;
657
+
658
+ .feature-grid, .product-grid, .service-grid, .post-grid, .category-grid {{
 
659
  grid-template-columns: 1fr;
660
+
661
+ .footer-content {{
662
+ grid-template-columns: 1fr;
663
+ text-align: center;
664
+
665
+
666
+ @media (max-width: 480px) {{
667
+ nav {{
668
+ padding: 1rem;
669
+
670
+ .search-bar {{
671
+ display: none;
672
+
673
+ .hero-content h1 {{
674
+ font-size: 2rem;
675
+
676
+ .container {{
677
+ padding: 0 15px;
678
+
679
+
680
  '''
681
 
682
  if complexity == "Advanced":
683
  base_css += '''
684
  /* Advanced styling additions */
685
+ .hero {
686
+ background-attachment: fixed;
687
  }
688
 
689
+ .feature-card:nth-child(1) { border-left: 4px solid #e74c3c; }
690
+ .feature-card:nth-child(2) { border-left: 4px solid #3498db; }
691
+ .feature-card:nth-child(3) { border-left: 4px solid #2ecc71; }
692
 
693
+ .post-excerpt {
694
+ color: #666;
695
+ margin-bottom: 1rem;
696
+ line-height: 1.6;
697
  }
698
 
699
+ /* Glass morphism effects */
700
+ .glass {
701
+ background: rgba(255, 255, 255, 0.1);
702
+ backdrop-filter: blur(10px);
703
+ border: 1px solid rgba(255, 255, 255, 0.2);
 
 
 
 
704
  }
705
 
706
+ /* Gradient text */
707
+ .gradient-text {
708
+ background: linear-gradient(45deg, var(--primary-color), var(--accent-color));
709
+ -webkit-background-clip: text;
710
+ -webkit-text-fill-color: transparent;
711
+ background-clip: text;
712
  }
713
 
714
+ /* Advanced hover effects */
715
+ .hover-lift:hover {
716
+ transform: translateY(-8px) scale(1.02);
717
+ box-shadow: 0 25px 50px rgba(0,0,0,0.15);
718
  }
719
 
720
+ /* Loading animations */
721
+ .loading {
722
+ display: inline-block;
723
+ width: 20px;
724
+ height: 20px;
725
+ border: 3px solid rgba(255,255,255,.3);
726
+ border-radius: 50%;
727
+ border-top-color: #fff;
728
+ animation: spin 1s ease-in-out infinite;
729
  }
730
 
731
+ @keyframes spin {
732
+ to { transform: rotate(360deg); }
 
733
  }
734
 
735
+ /* Enhanced mobile menu */
736
+ @media (max-width: 768px) {
737
+ .mobile-menu-toggle {
738
+ display: block;
739
+ background: none;
740
+ border: none;
741
+ font-size: 1.5rem;
742
+ cursor: pointer;
743
+ color: var(--primary-color);
744
  }
745
+
746
+ .nav-links.active {
747
+ display: flex;
748
+ flex-direction: column;
749
+ position: absolute;
750
+ top: 100%;
751
+ left: 0;
752
+ right: 0;
753
+ background: white;
754
+ box-shadow: var(--shadow);
755
+ padding: 1rem;
756
  }
757
  }
758
 
759
+ .mobile-menu-toggle {
760
+ display: none;
761
  }
762
  '''
763
 
764
  return base_css
765
 
766
+ def generate_enhanced_javascript(complexity: str) -> str:
767
+ """Generate enhanced JavaScript with advanced functionality"""
768
  base_js = '''
769
+ // Enhanced functionality for AI Web Coder
770
  document.addEventListener('DOMContentLoaded', function() {
771
+
772
+ // Initialize all components
773
+ initializeNavigation();
774
+ initializeButtons();
775
+ initializeCards();
776
+ initializeCart();
777
+ initializeSearch();
778
+ initializeAnimations();
779
+
780
+ function initializeNavigation() {
781
+ // Smooth scrolling for navigation links
782
+ const navLinks = document.querySelectorAll('.nav-links a');
783
+ navLinks.forEach(link => {
784
+ link.addEventListener('click', function(e) {
785
+ e.preventDefault();
786
+ const targetId = this.getAttribute('href').substring(1);
787
+ const targetSection = document.getElementById(targetId);
788
+
789
+ if (targetSection) {
790
+ const headerHeight = document.querySelector('header').offsetHeight;
791
+ const targetPosition = targetSection.offsetTop - headerHeight;
792
+
793
+ window.scrollTo({
794
+ top: targetPosition,
795
+ behavior: 'smooth'
796
+ });
797
+ }
798
+ });
799
+ });
800
+
801
+ // Mobile menu toggle
802
+ const mobileMenuToggle = document.querySelector('.mobile-menu-toggle');
803
+ const navLinks = document.querySelector('.nav-links');
804
+
805
+ if (mobileMenuToggle && navLinks) {
806
+ mobileMenuToggle.addEventListener('click', function() {
807
+ navLinks.classList.toggle('active');
808
+ });
809
+ }
810
+ }
811
+
812
+ function initializeButtons() {
813
+ // Enhanced CTA button functionality
814
+ const ctaButtons = document.querySelectorAll('.cta-button');
815
+ ctaButtons.forEach(button => {
816
+ button.addEventListener('click', function(e) {
817
+ e.preventDefault();
818
+
819
+ // Add loading state
820
+ const originalText = this.textContent;
821
+ this.innerHTML = '<span class="loading"></span> Processing...';
822
+ this.disabled = true;
823
+
824
+ // Simulate processing
825
+ setTimeout(() => {
826
+ this.textContent = originalText;
827
+ this.disabled = false;
828
+
829
+ // Show success message
830
+ showNotification('Thank you! This would redirect to the next step.', 'success');
831
+ }, 2000);
832
+ });
833
+ });
834
+
835
+ // Add to cart functionality
836
+ const addToCartButtons = document.querySelectorAll('.add-to-cart');
837
+ addToCartButtons.forEach(button => {
838
+ button.addEventListener('click', function() {
839
+ const productName = this.closest('.product-card').querySelector('h3').textContent;
840
+ addToCart(productName);
841
 
842
+ // Visual feedback
843
+ this.textContent = 'Added! ✓';
844
+ this.style.background = '#28a745';
845
+
846
+ setTimeout(() => {
847
+ this.textContent = 'Add to Cart';
848
+ this.style.background = '';
849
+ }, 2000);
850
+ });
851
+ });
852
+ }
853
+
854
+ function initializeCart() {
855
+ let cartCount = 0;
856
+ window.addToCart = function(productName) {
857
+ cartCount++;
858
+ const cartCountElement = document.querySelector('.cart-count');
859
+ if (cartCountElement) {
860
+ cartCountElement.textContent = cartCount;
861
+ cartCountElement.style.display = 'block';
862
+
863
+ // Animate cart count
864
+ cartCountElement.style.transform = 'scale(1.3)';
865
+ setTimeout(() => {
866
+ cartCountElement.style.transform = 'scale(1)';
867
+ }, 200);
868
+ }
869
+
870
+ showNotification(`${productName} added to cart!`, 'info');
871
+ };
872
+ }
873
+
874
+ function initializeSearch() {
875
+ const searchInput = document.querySelector('.search-bar input');
876
+ const searchBtn = document.querySelector('.search-btn');
877
+
878
+ if (searchInput && searchBtn) {
879
+ function performSearch() {
880
+ const query = searchInput.value.trim();
881
+ if (query) {
882
+ showNotification(`Searching for: "${query}"`, 'info');
883
+ // In a real app, this would perform the actual search
884
+ }
885
  }
886
+
887
+ searchBtn.addEventListener('click', performSearch);
888
+ searchInput.addEventListener('keypress', function(e) {
889
+ if (e.key === 'Enter') {
890
+ performSearch();
891
+ }
892
+ });
893
+ }
894
+ }
895
+
896
+ function initializeCards() {
897
+ // Enhanced card animations with intersection observer
898
+ const cards = document.querySelectorAll('.feature-card, .project-card, .service-card, .post-card, .product-card, .category-card');
899
+
900
+ const observer = new IntersectionObserver((entries) => {
901
+ entries.forEach((entry, index) => {
902
+ if (entry.isIntersecting) {
903
+ setTimeout(() => {
904
+ entry.target.style.opacity = '1';
905
+ entry.target.style.transform = 'translateY(0)';
906
+ }, index * 100); // Staggered animation
907
+ }
908
+ });
909
+ }, {
910
+ threshold: 0.1,
911
+ rootMargin: '0px 0px -50px 0px'
912
  });
913
+
914
+ cards.forEach((card, index) => {
915
+ card.style.opacity = '0';
916
+ card.style.transform = 'translateY(30px)';
917
+ card.style.transition = `opacity 0.6s ease ${index * 0.1}s, transform 0.6s ease ${index * 0.1}s`;
918
+ observer.observe(card);
 
 
919
  });
920
+ }
921
+
922
+ function initializeAnimations() {
923
+ // Parallax effect for hero section
924
+ window.addEventListener('scroll', function() {
925
+ const scrolled = window.pageYOffset;
926
+ const hero = document.querySelector('.hero');
927
+
928
+ if (hero) {
929
+ const rate = scrolled * -0.5;
930
+ hero.style.transform = `translateY(${rate}px)`;
931
+ }
932
  });
933
+
934
+ // Add typing effect to hero text
935
+ const heroHeading = document.querySelector('.hero-content h1');
936
+ if (heroHeading && heroHeading.textContent.length > 20) {
937
+ const originalText = heroHeading.textContent;
938
+ heroHeading.textContent = '';
939
+
940
+ setTimeout(() => {
941
+ typeWriter(heroHeading, originalText, 100);
942
+ }, 500);
943
+ }
944
+
945
+ // Add counter animations for prices
946
+ const priceElements = document.querySelectorAll('.price');
947
+ const priceObserver = new IntersectionObserver((entries) => {
948
+ entries.forEach(entry => {
949
+ if (entry.isIntersecting) {
950
+ const priceText = entry.target.textContent;
951
+ const priceNumber = parseFloat(priceText.replace(/[^0-9.]/g, ''));
952
+ animateCounter(entry.target, priceNumber);
953
+ priceObserver.unobserve(entry.target);
954
+ }
955
+ });
956
+ });
957
+
958
+ priceElements.forEach(price => {
959
+ priceObserver.observe(price);
960
+ });
961
+ }
962
+
963
+ // Utility functions
964
+ function typeWriter(element, text, speed = 50) {
965
+ let i = 0;
966
+ element.innerHTML = '';
967
+
968
+ function type() {
969
+ if (i < text.length) {
970
+ element.innerHTML += text.charAt(i);
971
+ i++;
972
+ setTimeout(type, speed);
973
+ }
974
+ }
975
+ type();
976
+ }
977
+
978
+ function animateCounter(element, target, duration = 2000) {
979
+ let start = 0;
980
+ const increment = target / (duration / 16);
981
+
982
+ function updateCounter() {
983
+ start += increment;
984
+ if (start < target) {
985
+ element.textContent = '$' + Math.floor(start).toFixed(2);
986
+ requestAnimationFrame(updateCounter);
987
+ } else {
988
+ element.textContent = '$' + target.toFixed(2);
989
  }
990
+ }
991
+ updateCounter();
992
+ }
993
+
994
+ function showNotification(message, type = 'info') {
995
+ // Create notification element
996
+ const notification = document.createElement('div');
997
+ notification.className = `notification notification-${type}`;
998
+ notification.textContent = message;
999
+
1000
+ // Style the notification
1001
+ Object.assign(notification.style, {
1002
+ position: 'fixed',
1003
+ top: '20px',
1004
+ right: '20px',
1005
+ padding: '15px 20px',
1006
+ borderRadius: '8px',
1007
+ color: 'white',
1008
+ fontWeight: '500',
1009
+ zIndex: '10000',
1010
+ transform: 'translateX(100%)',
1011
+ transition: 'transform 0.3s ease',
1012
+ maxWidth: '300px'
1013
  });
1014
+
1015
+ // Set colors based on type
1016
+ const colors = {
1017
+ success: '#28a745',
1018
+ error: '#dc3545',
1019
+ info: '#007bff',
1020
+ warning: '#ffc107'
1021
+ };
1022
+
1023
+ notification.style.backgroundColor = colors[type] || colors.info;
1024
+
1025
+ // Add to document
1026
+ document.body.appendChild(notification);
1027
+
1028
+ // Animate in
1029
+ setTimeout(() => {
1030
+ notification.style.transform = 'translateX(0)';
1031
+ }, 100);
1032
+
1033
+ // Remove after delay
1034
+ setTimeout(() => {
1035
+ notification.style.transform = 'translateX(100%)';
1036
+ setTimeout(() => {
1037
+ if (notification.parentNode) {
1038
+ notification.parentNode.removeChild(notification);
1039
+ }
1040
+ }, 300);
1041
+ }, 3000);
1042
+ }
1043
 
1044
+ // Performance monitoring
1045
+ if (typeof window.performance !== 'undefined') {
1046
+ window.addEventListener('load', function() {
1047
+ setTimeout(() => {
1048
+ const perfData = window.performance.timing;
1049
+ const loadTime = perfData.loadEventEnd - perfData.navigationStart;
1050
+ console.log(`Page load time: ${loadTime}ms`);
1051
+ }, 0);
1052
  });
1053
  }
1054
  });
 
1057
  if complexity == "Advanced":
1058
  base_js += '''
1059
 
1060
+ // Advanced JavaScript features
1061
+ class AdvancedFeatures {
1062
+ constructor() {
1063
+ this.init();
1064
+ }
1065
+
1066
+ init() {
1067
+ this.initWebGL();
1068
+ this.initServiceWorker();
1069
+ this.initAnalytics();
1070
+ this.initAccessibility();
1071
  }
 
 
 
 
 
 
1072
 
1073
+ initWebGL() {
1074
+ // Simple WebGL demo for advanced features
1075
+ const canvas = document.createElement('canvas');
1076
+ canvas.style.cssText = 'position: absolute; top: 0; left: 0; z-index: -1; opacity: 0.1;';
1077
+ document.body.appendChild(canvas);
1078
+
1079
+ if (canvas.getContext) {
1080
+ this.initParticles(canvas);
1081
  }
1082
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1083
 
1084
+ initParticles(canvas) {
1085
+ const ctx = canvas.getContext('2d');
1086
+ canvas.width = window.innerWidth;
1087
+ canvas.height = window.innerHeight;
1088
+
1089
+ const particles = [];
1090
+ for (let i = 0; i < 50; i++) {
1091
+ particles.push({
1092
+ x: Math.random() * canvas.width,
1093
+ y: Math.random() * canvas.height,
1094
+ vx: (Math.random() - 0.5) * 0.5,
1095
+ vy: (Math.random() - 0.5) * 0.5
1096
+ });
1097
+ }
1098
+
1099
+ const animate = () => {
1100
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
1101
+
1102
+ particles.forEach(particle => {
1103
+ particle.x += particle.vx;
1104
+ particle.y += particle.vy;
1105
+
1106
+ if (particle.x < 0 || particle.x > canvas.width) particle.vx *= -1;
1107
+ if (particle.y < 0 || particle.y > canvas.height) particle.vy *= -1;
1108
+
1109
+ ctx.beginPath();
1110
+ ctx.arc(particle.x, particle.y, 1, 0, Math.PI * 2);
1111
+ ctx.fillStyle = 'rgba(0, 123, 255, 0.5)';
1112
+ ctx.fill();
1113
+ });
1114
+
1115
+ requestAnimationFrame(animate);
1116
+ };
1117
+
1118
+ animate();
1119
+
1120
+ window.addEventListener('resize', () => {
1121
+ canvas.width = window.innerWidth;
1122
+ canvas.height = window.innerHeight;
1123
+ });
1124
+ }
1125
 
1126
+ initServiceWorker() {
1127
+ if ('serviceWorker' in navigator) {
1128
+ // Register service worker for PWA functionality
1129
+ navigator.serviceWorker.register('/sw.js').then(registration => {
1130
+ console.log('SW registered: ', registration);
1131
+ }).catch(registrationError => {
1132
+ console.log('SW registration failed: ', registrationError);
1133
+ });
1134
  }
1135
  }
1136
+
1137
+ initAnalytics() {
1138
+ // Simple analytics tracking
1139
+ this.trackUserInteractions();
1140
+ }
1141
+
1142
+ trackUserInteractions() {
1143
+ document.addEventListener('click', function(e) {
1144
+ if (e.target.tagName === 'BUTTON') {
1145
+ console.log('Button clicked:', e.target.textContent);
1146
+ // In a real app, send to analytics service
1147
+ }
1148
+ });
1149
+ }
1150
+
1151
+ initAccessibility() {
1152
+ // Enhance keyboard navigation
1153
+ document.addEventListener('keydown', function(e) {
1154
+ if (e.key === 'Tab') {
1155
+ document.body.classList.add('keyboard-navigation');
1156
+ }
1157
+ });
1158
+
1159
+ document.addEventListener('mousedown', function() {
1160
+ document.body.classList.remove('keyboard-navigation');
1161
+ });
1162
+ }
1163
  }
1164
 
1165
+ // Initialize advanced features
1166
+ new AdvancedFeatures();
1167
+
1168
+ // Add keyboard shortcuts
1169
+ document.addEventListener('keydown', function(e) {
1170
+ // Ctrl/Cmd + K for search
1171
+ if ((e.ctrlKey || e.metaKey) && e.key === 'k') {
1172
+ e.preventDefault();
1173
+ const searchInput = document.querySelector('.search-bar input');
1174
+ if (searchInput) {
1175
+ searchInput.focus();
1176
  }
1177
+ }
1178
  });
1179
 
1180
+ // Progressive enhancement
1181
+ if ('IntersectionObserver' in window) {
1182
+ // Lazy loading for images (if any were added)
1183
+ const imageObserver = new IntersectionObserver((entries) => {
1184
+ entries.forEach(entry => {
1185
+ if (entry.isIntersecting) {
1186
+ const img = entry.target;
1187
+ if (img.dataset.src) {
1188
+ img.src = img.dataset.src;
1189
+ img.removeAttribute('data-src');
1190
+ imageObserver.unobserve(img);
1191
+ }
1192
+ }
1193
+ });
1194
+ });
1195
+
1196
+ document.querySelectorAll('img[data-src]').forEach(img => {
1197
+ imageObserver.observe(img);
1198
+ });
1199
+ }
1200
  '''
1201
 
1202
  return base_js
1203
 
1204
+ def enhance_html_with_seo_accessibility(html_code: str, description: str) -> str:
1205
+ """Add SEO and accessibility improvements to HTML"""
1206
+
1207
+ # Add meta tags for SEO
1208
+ seo_meta = f'''
1209
+ <meta name="description" content="Generated website based on: {description}">
1210
+ <meta name="keywords" content="{description.split()[:10]}">
1211
+ <meta name="author" content="AI Web Coder">
1212
+ <meta property="og:title" content="Generated Website">
1213
+ <meta property="og:description" content="Generated website based on: {description}">
1214
+ <meta property="og:type" content="website">
1215
+ <meta name="twitter:card" content="summary">
1216
+ <meta name="twitter:title" content="Generated Website">
1217
+ <meta name="twitter:description" content="Generated website based on: {description}">
1218
+ <link rel="canonical" href="#">
1219
+ '''
1220
+
1221
+ # Add accessibility improvements
1222
+ accessibility_fixes = '''
1223
+ <meta name="theme-color" content="#007bff">
1224
+ <link rel="preconnect" href="https://fonts.googleapis.com">
1225
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
1226
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
1227
+ '''
1228
+
1229
+ # Insert meta tags after the existing charset meta tag
1230
+ html_code = html_code.replace(
1231
+ '<meta charset="UTF-8">',
1232
+ '<meta charset="UTF-8">\n ' + seo_meta.strip() + '\n ' + accessibility_fixes.strip()
1233
+ )
1234
+
1235
+ # Add skip link for accessibility
1236
+ skip_link = ''' <a href="#main" class="skip-link">Skip to main content</a>'''
1237
+ html_code = html_code.replace('<body>', '<body>\n' + skip_link)
1238
+
1239
+ # Add ARIA labels and improve accessibility
1240
+ html_code = html_code.replace('<nav>', '<nav role="navigation" aria-label="Main navigation">')
1241
+
1242
+ return html_code
1243
 
1244
+ def analyze_code_quality(html_code: str, css_code: str, js_code: str) -> Dict[str, Any]:
1245
+ """Analyze code quality and provide metrics"""
1246
 
1247
+ score = 0
1248
+ tips = []
1249
+ accessibility_score = 0
1250
+ seo_score = 0
 
 
 
 
 
 
1251
 
1252
+ # HTML Quality Checks
1253
+ if '<!DOCTYPE html>' in html_code:
1254
+ score += 5
1255
+ if 'lang="en"' in html_code:
1256
+ score += 5
1257
+ accessibility_score += 10
1258
+ if 'viewport' in html_code:
1259
+ score += 5
1260
+ seo_score += 10
1261
+ if 'aria-label' in html_code or 'alt=' in html_code:
1262
+ accessibility_score += 15
1263
+ if '<meta name="description"' in html_code:
1264
+ seo_score += 15
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1265
 
1266
+ # CSS Quality Checks
1267
+ if ':root' in css_code or 'var(' in css_code:
1268
+ score += 10
1269
+ if '@media' in css_code:
1270
+ score += 10
1271
+ accessibility_score += 10
1272
+ if 'transition' in css_code:
1273
+ score += 5
1274
+ if 'flexbox' in css_code or 'grid' in css_code:
1275
+ score += 5
 
 
 
 
 
 
1276
 
1277
+ # JavaScript Quality Checks
1278
+ if 'addEventListener' in js_code:
1279
+ score += 10
1280
+ if 'DOMContentLoaded' in js_code:
1281
+ score += 10
1282
+ if 'const ' in js_code or 'let ' in js_code:
1283
+ score += 5
1284
+ if 'async' in js_code or 'await' in js_code:
1285
+ score += 5
1286
 
1287
+ # Accessibility Score (max 100)
1288
+ accessibility_score = min(accessibility_score, 100)
 
 
 
 
 
 
1289
 
1290
+ # SEO Score (max 100)
1291
+ seo_score = min(seo_score, 100)
1292
+
1293
+ # Generate tips
1294
+ if score < 50:
1295
+ tips.append("Consider adding more semantic HTML elements")
1296
+ if accessibility_score < 70:
1297
+ tips.append("Add more ARIA labels and alt text for images")
1298
+ if seo_score < 70:
1299
+ tips.append("Include meta descriptions and proper heading structure")
1300
+ if ':root' not in css_code:
1301
+ tips.append("Use CSS custom properties for better maintainability")
1302
+ if '@media' not in css_code:
1303
+ tips.append("Add responsive design with media queries")
1304
+ if 'addEventListener' not in js_code:
1305
+ tips.append("Use modern JavaScript event handling")
1306
+
1307
+ if not tips:
1308
+ tips.append("Great code quality! Your website follows modern best practices.")
1309
 
1310
+ return {
1311
+ 'score': min(score, 100),
1312
+ 'tips': tips,
1313
+ 'accessibility': accessibility_score,
1314
+ 'seo': seo_score
1315
+ }
1316
+
1317
+ def save_project(project_name: str, description: str, complexity: str, html_code: str, css_code: str, js_code: str) -> str:
1318
+ """Save project data (simulated)"""
1319
+ project_data = {
1320
+ "name": project_name,
1321
+ "description": description,
1322
+ "complexity": complexity,
1323
+ "html": html_code,
1324
+ "css": css_code,
1325
+ "js": js_code,
1326
+ "timestamp": time.time()
1327
+ }
1328
 
1329
+ # In a real implementation, this would save to a database
1330
+ return f"Project '{project_name}' saved successfully! (Simulated - would save to database)"
1331
+
1332
+ def load_projects() -> List[str]:
1333
+ """Load saved projects (simulated)"""
1334
+ # In a real implementation, this would load from a database
1335
+ return [
1336
+ "Portfolio Site",
1337
+ "Business Landing Page",
1338
+ "E-commerce Store",
1339
+ "Blog Template"
 
 
 
 
 
 
 
 
 
 
 
 
1340
  ]
1341
+
1342
+ # Enhanced theme with better styling
1343
+ enhanced_theme = gr.themes.Soft(
1344
+ primary_hue="blue",
1345
+ secondary_hue="indigo",
1346
+ neutral_hue="slate",
1347
+ font=gr.themes.GoogleFont("Inter"),
1348
+ text_size="lg",
1349
+ spacing_size="lg",
1350
+ radius_size="md"
1351
+ ).set(
1352
+ button_primary_background_fill="*primary