dilpreet77 commited on
Commit
195e83f
·
verified ·
1 Parent(s): ca71928

Update templates/index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +428 -584
templates/index.html CHANGED
@@ -1,595 +1,439 @@
1
  <!DOCTYPE html>
2
  <html lang="en">
3
  <head>
4
- <meta charset="UTF-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1" />
6
- <title>🍛 Flavor Profile Prediction - Your Culinary Journey Awaits!</title>
7
- <!-- Bootstrap CSS -->
8
- <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.4.1/dist/css/bootstrap.min.css" rel="stylesheet" />
9
- <!-- Tailwind CSS CDN -->
10
- <script src="https://cdn.tailwindcss.com"></script>
11
- <!-- Font Awesome for Icons -->
12
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" />
13
- <!-- Animate.css for Animations -->
14
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css" />
15
- <style>
16
- @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600;700&display=swap');
17
-
18
- body {
19
- background: linear-gradient(135deg, #fff8f0, #ffe8cc, #ffddb5, #ffdab9);
20
- font-family: 'Poppins', sans-serif;
21
- overflow-x: hidden;
22
- position: relative;
23
- min-height: 100vh;
24
- }
25
-
26
- /* Enhanced animated background with foody elements */
27
- body::before {
28
- content: '';
29
- position: fixed;
30
- top: 0;
31
- left: 0;
32
- width: 100%;
33
- height: 100%;
34
- background-image:
35
- /* Floating spices */
36
- radial-gradient(3px 3px at 20px 30px, #8B4513, transparent),
37
- radial-gradient(2px 2px at 80px 50px, #FF6347, transparent),
38
- radial-gradient(4px 4px at 150px 20px, #D2691E, transparent),
39
- radial-gradient(2px 2px at 200px 60px, #FFD700, transparent),
40
- /* Steam wisps */
41
- radial-gradient(1px 20px at 60px 80px, rgba(255, 255, 255, 0.6), transparent),
42
- radial-gradient(1px 15px at 180px 100px, rgba(255, 255, 255, 0.5), transparent),
43
- /* Curry leaves */
44
- radial-gradient(ellipse 8px 4px at 120px 40px, #228B22, transparent),
45
- radial-gradient(ellipse 6px 3px at 250px 70px, #32CD32, transparent);
46
- background-repeat: repeat;
47
- background-size: 300px 200px;
48
- animation: floatSpices 30s linear infinite;
49
- pointer-events: none;
50
- z-index: -1;
51
- opacity: 0.3;
52
- }
53
-
54
- /* Floating bubbles animation */
55
- body::after {
56
- content: '';
57
- position: fixed;
58
- top: 0;
59
- left: 0;
60
- width: 100%;
61
- height: 100%;
62
- background-image:
63
- radial-gradient(circle 8px at 40px 90%, rgba(255, 193, 7, 0.4), transparent),
64
- radial-gradient(circle 5px at 100px 70%, rgba(255, 140, 0, 0.3), transparent),
65
- radial-gradient(circle 6px at 160px 85%, rgba(255, 99, 71, 0.3), transparent),
66
- radial-gradient(circle 4px at 220px 60%, rgba(50, 205, 50, 0.3), transparent);
67
- background-repeat: repeat;
68
- background-size: 280px 180px;
69
- animation: bubbleUp 20s linear infinite;
70
- pointer-events: none;
71
- z-index: -1;
72
- opacity: 0.5;
73
- }
74
-
75
- @keyframes floatSpices {
76
- 0% { transform: translateY(100vh) rotate(0deg); }
77
- 100% { transform: translateY(-100vh) rotate(360deg); }
78
- }
79
-
80
- @keyframes bubbleUp {
81
- 0% { transform: translateY(100vh) scale(0.5); }
82
- 50% { transform: translateY(50vh) scale(1); }
83
- 100% { transform: translateY(-10vh) scale(0.8); }
84
- }
85
-
86
- @keyframes pulse {
87
- 0%, 100% { transform: scale(1); }
88
- 50% { transform: scale(1.05); }
89
- }
90
-
91
- @keyframes bounceIn {
92
- 0% {
93
- opacity: 0;
94
- transform: scale(0.3) translateY(-50px);
95
- }
96
- 50% {
97
- opacity: 1;
98
- transform: scale(1.05) translateY(-25px);
99
- }
100
- 70% {
101
- transform: scale(0.9) translateY(0);
102
- }
103
- 100% {
104
- opacity: 1;
105
- transform: scale(1) translateY(0);
106
- }
107
- }
108
-
109
- @keyframes slideInUp {
110
- 0% {
111
- opacity: 0;
112
- transform: translateY(30px);
113
- }
114
- 100% {
115
- opacity: 1;
116
- transform: translateY(0);
117
- }
118
- }
119
-
120
- @keyframes wiggle {
121
- 0%, 7% { transform: rotateZ(0); }
122
- 15% { transform: rotateZ(-15deg); }
123
- 20% { transform: rotateZ(10deg); }
124
- 25% { transform: rotateZ(-10deg); }
125
- 30% { transform: rotateZ(6deg); }
126
- 35% { transform: rotateZ(-4deg); }
127
- 40%, 100% { transform: rotateZ(0); }
128
- }
129
-
130
- .container-main {
131
- animation: bounceIn 1s ease-out;
132
- backdrop-filter: blur(10px);
133
- background: rgba(255, 255, 255, 0.9);
134
- border-radius: 20px;
135
- box-shadow: 0 15px 35px rgba(0,0,0,0.1);
136
- border: 1px solid rgba(255,255,255,0.2);
137
- }
138
-
139
- .header-title {
140
- background: linear-gradient(135deg, #ff6b6b, #ffa500, #ff1744);
141
- -webkit-background-clip: text;
142
- -webkit-text-fill-color: transparent;
143
- background-clip: text;
144
- animation: pulse 2s infinite;
145
- text-shadow: 2px 2px 4px rgba(0,0,0,0.1);
146
- }
147
-
148
- .emoji-chef {
149
- font-size: 3rem;
150
- animation: wiggle 3s infinite;
151
- display: inline-block;
152
- }
153
-
154
- .card-enhanced {
155
- transition: all 0.4s ease;
156
- border-radius: 15px;
157
- border: none;
158
- box-shadow: 0 8px 25px rgba(0,0,0,0.1);
159
- background: rgba(255, 255, 255, 0.95);
160
- backdrop-filter: blur(5px);
161
- animation: slideInUp 0.8s ease-out;
162
- }
163
-
164
- .card-enhanced:hover {
165
- transform: translateY(-10px) scale(1.02);
166
- box-shadow: 0 15px 40px rgba(0,0,0,0.15);
167
- background: rgba(255, 255, 255, 1);
168
- }
169
-
170
- .btn-predict {
171
- background: linear-gradient(135deg, #ff6b6b, #ffa500);
172
- border: none;
173
- border-radius: 25px;
174
- padding: 12px 30px;
175
- color: white;
176
- font-weight: 600;
177
- transition: all 0.3s ease;
178
- position: relative;
179
- overflow: hidden;
180
- }
181
-
182
- .btn-predict::before {
183
- content: '';
184
- position: absolute;
185
- top: 0;
186
- left: -100%;
187
- width: 100%;
188
- height: 100%;
189
- background: linear-gradient(90deg, transparent, rgba(255,255,255,0.4), transparent);
190
- transition: left 0.5s;
191
- }
192
-
193
- .btn-predict:hover::before {
194
- left: 100%;
195
- }
196
-
197
- .btn-predict:hover {
198
- transform: scale(1.05);
199
- box-shadow: 0 10px 20px rgba(0,0,0,0.2);
200
- }
201
-
202
- .form-control-custom {
203
- border-radius: 15px;
204
- border: 2px solid #ffe8cc;
205
- transition: all 0.3s ease;
206
- background: rgba(255, 255, 255, 0.8);
207
- }
208
-
209
- .form-control-custom:focus {
210
- border-color: #ff6b6b;
211
- box-shadow: 0 0 0 0.2rem rgba(255, 107, 107, 0.25);
212
- transform: scale(1.02);
213
- }
214
-
215
- .ingredient-tag {
216
- background: linear-gradient(135deg, #ffeaa7, #fdcb6e);
217
- color: #2d3436;
218
- padding: 8px 15px;
219
- border-radius: 20px;
220
- margin: 5px;
221
- display: inline-block;
222
- font-weight: 500;
223
- animation: slideInUp 0.5s ease-out;
224
- transition: all 0.3s ease;
225
- box-shadow: 0 4px 15px rgba(253, 203, 110, 0.4);
226
- }
227
-
228
- .ingredient-tag:hover {
229
- transform: translateY(-3px);
230
- box-shadow: 0 8px 20px rgba(253, 203, 110, 0.6);
231
- }
232
-
233
- .result-card {
234
- background: linear-gradient(135deg, #74b9ff, #0984e3);
235
- color: white;
236
- border-radius: 15px;
237
- animation: bounceIn 1s ease-out;
238
- box-shadow: 0 10px 30px rgba(116, 185, 255, 0.4);
239
- }
240
-
241
- .loading-spinner {
242
- border: 4px solid #f3f3f3;
243
- border-top: 4px solid #ff6b6b;
244
- border-radius: 50%;
245
- width: 50px;
246
- height: 50px;
247
- animation: spin 1s linear infinite;
248
- margin: 20px auto;
249
- }
250
-
251
- @keyframes spin {
252
- 0% { transform: rotate(0deg); }
253
- 100% { transform: rotate(360deg); }
254
- }
255
-
256
- .welcome-message {
257
- background: linear-gradient(135deg, #fd79a8, #fdcb6e);
258
- color: white;
259
- padding: 20px;
260
- border-radius: 15px;
261
- animation: slideInUp 1.2s ease-out;
262
- box-shadow: 0 10px 30px rgba(253, 121, 168, 0.3);
263
- margin-bottom: 30px;
264
- }
265
-
266
- .feature-icon {
267
- font-size: 2.5rem;
268
- color: #ff6b6b;
269
- animation: pulse 2s infinite;
270
- margin-bottom: 15px;
271
- }
272
-
273
- .floating-element {
274
- position: absolute;
275
- animation: float 6s ease-in-out infinite;
276
- }
277
-
278
- @keyframes float {
279
- 0%, 100% { transform: translateY(0px); }
280
- 50% { transform: translateY(-20px); }
281
- }
282
-
283
- .spice-icon-1 {
284
- top: 10%;
285
- right: 10%;
286
- animation-delay: 0s;
287
- }
288
-
289
- .spice-icon-2 {
290
- top: 20%;
291
- left: 5%;
292
- animation-delay: 2s;
293
- }
294
-
295
- .spice-icon-3 {
296
- bottom: 15%;
297
- right: 5%;
298
- animation-delay: 4s;
299
- }
300
- </style>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
301
  </head>
302
  <body>
303
- <!-- Floating decorative elements -->
304
- <div class="floating-element spice-icon-1">🌶️</div>
305
- <div class="floating-element spice-icon-2">🧄</div>
306
- <div class="floating-element spice-icon-3">🌿</div>
307
-
308
- <div class="container my-5">
309
- <div class="container-main p-4">
310
- <!-- Welcome Header -->
311
- <div class="welcome-message text-center">
312
- <div class="emoji-chef">👨‍🍳</div>
313
- <h1 class="header-title display-4 fw-bold mb-3">
314
- Welcome to Your Flavor Adventure!
315
- </h1>
316
- <p class="lead mb-0">
317
- <i class="fas fa-sparkles me-2"></i>
318
- Discover the perfect blend of spices and ingredients for your culinary masterpiece!
319
- <i class="fas fa-sparkles ms-2"></i>
320
- </p>
321
- </div>
322
 
323
- <!-- Main Content -->
324
- <div class="row">
325
- <!-- Input Section -->
326
- <div class="col-md-6 mb-4">
327
- <div class="card card-enhanced h-100">
328
- <div class="card-header bg-gradient text-center py-3" style="background: linear-gradient(135deg, #a8e6cf, #7fcdcd);">
329
- <div class="feature-icon">🥘</div>
330
- <h3 class="mb-0 text-white fw-bold">Tell Us About Your Dish</h3>
331
- </div>
332
- <div class="card-body p-4">
333
- <form id="flavorForm">
334
- <div class="mb-4">
335
- <label for="ingredients" class="form-label fw-semibold">
336
- <i class="fas fa-carrot me-2 text-success"></i>
337
- What ingredients are you using?
338
- </label>
339
- <textarea
340
- class="form-control form-control-custom"
341
- id="ingredients"
342
- rows="4"
343
- placeholder="e.g., tomatoes, onions, garlic, cumin, coriander, chicken...">
344
- </textarea>
345
- <small class="form-text text-muted mt-2">
346
- <i class="fas fa-info-circle me-1"></i>
347
- List all your ingredients separated by commas
348
- </small>
349
- </div>
350
-
351
- <div class="mb-4">
352
- <label for="cuisine" class="form-label fw-semibold">
353
- <i class="fas fa-globe me-2 text-primary"></i>
354
- What cuisine style are you aiming for?
355
- </label>
356
- <select class="form-control form-control-custom" id="cuisine">
357
- <option value="">Choose a cuisine...</option>
358
- <option value="indian">🇮🇳 Indian</option>
359
- <option value="italian">🇮🇹 Italian</option>
360
- <option value="mexican">🇲🇽 Mexican</option>
361
- <option value="chinese">🇨🇳 Chinese</option>
362
- <option value="thai">🇹🇭 Thai</option>
363
- <option value="mediterranean">🌊 Mediterranean</option>
364
- <option value="american">🇺🇸 American</option>
365
- <option value="french">🇫🇷 French</option>
366
- </select>
367
- </div>
368
-
369
- <div class="text-center">
370
- <button type="submit" class="btn btn-predict btn-lg">
371
- <i class="fas fa-magic me-2"></i>
372
- Predict My Flavor Profile!
373
- <i class="fas fa-rocket ms-2"></i>
374
- </button>
375
- </div>
376
- </form>
377
- </div>
378
- </div>
379
- </div>
380
-
381
- <!-- Results Section -->
382
- <div class="col-md-6 mb-4">
383
- <div class="card card-enhanced h-100">
384
- <div class="card-header bg-gradient text-center py-3" style="background: linear-gradient(135deg, #ffecd2, #fcb69f);">
385
- <div class="feature-icon">✨</div>
386
- <h3 class="mb-0 text-white fw-bold">Your Flavor Profile</h3>
387
- </div>
388
- <div class="card-body p-4" id="resultsSection">
389
- <div class="text-center text-muted py-5">
390
- <i class="fas fa-utensils fa-3x mb-3 opacity-50"></i>
391
- <h5>Ready to discover your perfect flavor combination?</h5>
392
- <p class="mb-0">Fill in your ingredients and cuisine preference, then click the predict button!</p>
393
- <div class="mt-4">
394
- <div class="ingredient-tag">Sweet 🍯</div>
395
- <div class="ingredient-tag">Spicy 🌶️</div>
396
- <div class="ingredient-tag">Savory 🧂</div>
397
- <div class="ingredient-tag">Aromatic 🌿</div>
398
- </div>
399
- </div>
400
- </div>
401
- </div>
402
- </div>
403
- </div>
404
 
405
- <!-- Features Section -->
406
- <div class="row mt-5">
407
- <div class="col-md-4 mb-3">
408
- <div class="card card-enhanced text-center p-4">
409
- <div class="feature-icon">🎯</div>
410
- <h5 class="fw-bold">Precise Predictions</h5>
411
- <p class="text-muted mb-0">AI-powered analysis of your ingredients for spot-on flavor profiles</p>
412
- </div>
413
- </div>
414
- <div class="col-md-4 mb-3">
415
- <div class="card card-enhanced text-center p-4">
416
- <div class="feature-icon">🌍</div>
417
- <h5 class="fw-bold">Global Cuisines</h5>
418
- <p class="text-muted mb-0">Explore flavors from around the world with cultural authenticity</p>
419
- </div>
420
- </div>
421
- <div class="col-md-4 mb-3">
422
- <div class="card card-enhanced text-center p-4">
423
- <div class="feature-icon">💡</div>
424
- <h5 class="fw-bold">Smart Suggestions</h5>
425
- <p class="text-muted mb-0">Get personalized tips to enhance your cooking experience</p>
426
- </div>
427
- </div>
428
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
429
  </div>
 
 
 
 
 
 
 
 
 
 
 
430
  </div>
 
431
 
432
- <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.4.1/dist/js/bootstrap.bundle.min.js"></script>
433
- <script>
434
- // Enhanced form submission with animations
435
- document.getElementById('flavorForm').addEventListener('submit', function(e) {
436
- e.preventDefault();
437
-
438
- const ingredients = document.getElementById('ingredients').value;
439
- const cuisine = document.getElementById('cuisine').value;
440
- const resultsSection = document.getElementById('resultsSection');
441
-
442
- if (!ingredients.trim()) {
443
- alert('Please enter some ingredients! 🥕');
444
- return;
445
- }
446
-
447
- // Show loading animation
448
- resultsSection.innerHTML = `
449
- <div class="text-center py-4">
450
- <div class="loading-spinner"></div>
451
- <h5 class="mt-3 text-primary">
452
- <i class="fas fa-magic me-2"></i>
453
- Analyzing your ingredients...
454
- <i class="fas fa-sparkles ms-2"></i>
455
- </h5>
456
- <p class="text-muted">Our AI chef is working on your flavor profile!</p>
457
- </div>
458
- `;
459
-
460
- // Simulate API call with realistic delay
461
- setTimeout(() => {
462
- showResults(ingredients, cuisine);
463
- }, 2000);
464
- });
465
-
466
- function showResults(ingredients, cuisine) {
467
- const resultsSection = document.getElementById('resultsSection');
468
- const ingredientList = ingredients.split(',').map(item => item.trim()).filter(item => item);
469
-
470
- // Mock prediction logic (replace with actual API call)
471
- const flavorProfiles = generateFlavorProfile(ingredientList, cuisine);
472
- const suggestions = generateSuggestions(ingredientList, cuisine);
473
-
474
- resultsSection.innerHTML = `
475
- <div class="result-card p-4 mb-4">
476
- <h4 class="mb-3">
477
- <i class="fas fa-award me-2"></i>
478
- Your Flavor Profile Results!
479
- </h4>
480
- <div class="row">
481
- <div class="col-md-6">
482
- <h6><i class="fas fa-star me-2"></i>Primary Flavors:</h6>
483
- <div class="mb-3">
484
- ${flavorProfiles.primary.map(flavor =>
485
- `<div class="ingredient-tag">${flavor}</div>`
486
- ).join('')}
487
- </div>
488
- </div>
489
- <div class="col-md-6">
490
- <h6><i class="fas fa-palette me-2"></i>Flavor Intensity:</h6>
491
- <div class="mb-3">
492
- ${flavorProfiles.intensity.map(intensity =>
493
- `<div class="ingredient-tag">${intensity}</div>`
494
- ).join('')}
495
- </div>
496
- </div>
497
- </div>
498
- </div>
499
-
500
- <div class="card card-enhanced">
501
- <div class="card-body">
502
- <h5 class="card-title">
503
- <i class="fas fa-lightbulb me-2 text-warning"></i>
504
- Chef's Recommendations
505
- </h5>
506
- <div class="alert alert-info">
507
- <strong>Perfect for:</strong> ${suggestions.occasion}
508
- </div>
509
- <div class="alert alert-success">
510
- <strong>Pro Tip:</strong> ${suggestions.tip}
511
- </div>
512
- <div class="alert alert-warning">
513
- <strong>Missing ingredient:</strong> Consider adding ${suggestions.missing} for extra depth!
514
- </div>
515
- </div>
516
- </div>
517
- `;
518
- }
519
-
520
- function generateFlavorProfile(ingredients, cuisine) {
521
- // Mock AI prediction logic
522
- const spiceWords = ['cumin', 'coriander', 'chili', 'pepper', 'garam', 'masala'];
523
- const hasSpices = ingredients.some(ing =>
524
- spiceWords.some(spice => ing.toLowerCase().includes(spice))
525
- );
526
-
527
- const profiles = {
528
- primary: hasSpices ?
529
- ['Spicy 🌶️', 'Aromatic 🌿', 'Warm 🔥'] :
530
- ['Mild 🌸', 'Fresh 🌱', 'Balanced ⚖️'],
531
- intensity: cuisine === 'indian' ?
532
- ['Bold', 'Complex', 'Layered'] :
533
- ['Moderate', 'Harmonious', 'Refined']
534
- };
535
-
536
- return profiles;
537
- }
538
-
539
- function generateSuggestions(ingredients, cuisine) {
540
- const cuisineMap = {
541
- indian: {
542
- occasion: 'Comfort food dinners, family gatherings',
543
- tip: 'Toast your whole spices before grinding for deeper flavor',
544
- missing: 'fresh cilantro or mint'
545
- },
546
- italian: {
547
- occasion: 'Romantic dinners, casual lunches',
548
- tip: 'Use high-quality olive oil and fresh herbs',
549
- missing: 'fresh basil or parmesan cheese'
550
- },
551
- mexican: {
552
- occasion: 'Festive gatherings, outdoor parties',
553
- tip: 'Balance heat with lime juice and fresh herbs',
554
- missing: 'lime zest or fresh jalapeños'
555
- }
556
- };
557
-
558
- return cuisineMap[cuisine] || {
559
- occasion: 'Versatile dining occasions',
560
- tip: 'Taste as you go and adjust seasonings gradually',
561
- missing: 'fresh herbs for brightness'
562
- };
563
- }
564
-
565
- // Add some interactive hover effects
566
- document.querySelectorAll('.card-enhanced').forEach(card => {
567
- card.addEventListener('mouseenter', function() {
568
- this.style.animation = 'pulse 0.5s ease-in-out';
569
- });
570
-
571
- card.addEventListener('mouseleave', function() {
572
- this.style.animation = '';
573
- });
574
- });
575
-
576
- // Animate elements on scroll
577
- const observerOptions = {
578
- threshold: 0.1,
579
- rootMargin: '0px 0px -50px 0px'
580
- };
581
-
582
- const observer = new IntersectionObserver((entries) => {
583
- entries.forEach(entry => {
584
- if (entry.isIntersecting) {
585
- entry.target.style.animation = 'slideInUp 0.6s ease-out';
586
- }
587
- });
588
- }, observerOptions);
589
-
590
- document.querySelectorAll('.card-enhanced').forEach(card => {
591
- observer.observe(card);
592
- });
593
- </script>
594
- </body>
595
- </html>
 
1
  <!DOCTYPE html>
2
  <html lang="en">
3
  <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <title>Flavor Profile Prediction</title>
7
+
8
+ <!-- Bootstrap CSS -->
9
+ <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.4.1/dist/css/bootstrap.min.css" rel="stylesheet" />
10
+ <!-- Tailwind CSS CDN -->
11
+ <script src="https://cdn.tailwindcss.com"></script>
12
+ <!-- Font Awesome for Icons -->
13
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" />
14
+ <!-- Animate.css for Animations -->
15
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css" />
16
+
17
+ <style>
18
+ body {
19
+ background: linear-gradient(135deg, #fff8f0, #ffe8cc, #ffddb5, #ffdab9);
20
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
21
+ overflow-x: hidden;
22
+ position: relative;
23
+ }
24
+
25
+ /* Enhanced animated background with foody elements */
26
+ body::before {
27
+ content: '';
28
+ position: fixed;
29
+ top: 0;
30
+ left: 0;
31
+ width: 100%;
32
+ height: 100%;
33
+ background-image:
34
+ /* Spice particles (cumin-like dots) */
35
+ radial-gradient(3px 3px at 20px 30px, #8B4513, transparent),
36
+ radial-gradient(2px 2px at 80px 50px, #FF4500, transparent),
37
+ radial-gradient(4px 4px at 150px 20px, #D2691E, transparent),
38
+ /* Steam wisps (curved lines for cooking steam) */
39
+ radial-gradient(1px 20px at 60px 80px, rgba(255, 255, 255, 0.6), transparent),
40
+ radial-gradient(1px 15px at 200px 100px, rgba(255, 255, 255, 0.4), transparent),
41
+ /* Floating leaf/curry leaf shapes */
42
+ radial-gradient(ellipse 10px 5px at 120px 60px, #228B22, transparent),
43
+ radial-gradient(ellipse 8px 4px at 250px 90px, #32CD32, transparent);
44
+ background-repeat: repeat;
45
+ background-size: 300px 200px;
46
+ animation: floatSpices 25s linear infinite;
47
+ pointer-events: none;
48
+ z-index: -1;
49
+ opacity: 0.4;
50
+ }
51
+
52
+ /* Additional foody animation layer: Rising bubbles/steam */
53
+ body::after {
54
+ content: '';
55
+ position: fixed;
56
+ top: 0;
57
+ left: 0;
58
+ width: 100%;
59
+ height: 100%;
60
+ background-image:
61
+ radial-gradient(circle 5px at 40px 90%, rgba(255, 193, 7, 0.5), transparent),
62
+ radial-gradient(circle 3px at 100px 70%, rgba(255, 140, 0, 0.4), transparent),
63
+ radial-gradient(circle 4px at 180px 85%, rgba(255, 69, 0, 0.3), transparent),
64
+ radial-gradient(circle 6px at 300px 95%, rgba(255, 215, 0, 0.5), transparent);
65
+ background-repeat: repeat;
66
+ background-size: 400px 150px;
67
+ animation: riseSteam 15s ease-in-out infinite;
68
+ pointer-events: none;
69
+ z-index: -1;
70
+ opacity: 0.3;
71
+ }
72
+
73
+ @keyframes floatSpices {
74
+ 0% {
75
+ transform: translateY(0px) rotate(0deg);
76
+ opacity: 0.4;
77
+ }
78
+ 50% {
79
+ opacity: 0.8;
80
+ }
81
+ 100% {
82
+ transform: translateY(-200px) rotate(180deg);
83
+ opacity: 0.4;
84
+ }
85
+ }
86
+
87
+ @keyframes riseSteam {
88
+ 0% {
89
+ transform: translateY(100vh) scale(0);
90
+ opacity: 0;
91
+ }
92
+ 10% {
93
+ opacity: 1;
94
+ }
95
+ 90% {
96
+ opacity: 1;
97
+ }
98
+ 100% {
99
+ transform: translateY(-100px) scale(1.5);
100
+ opacity: 0;
101
+ }
102
+ }
103
+
104
+ /* Subtle rotating utensil in background (optional, low opacity) */
105
+ .bg-utensil {
106
+ position: fixed;
107
+ top: 20%;
108
+ right: 10%;
109
+ font-size: 3rem;
110
+ color: rgba(230, 126, 34, 0.1);
111
+ z-index: -1;
112
+ animation: rotateUtensil 20s linear infinite;
113
+ }
114
+
115
+ .bg-plate {
116
+ position: fixed;
117
+ bottom: 20%;
118
+ left: 10%;
119
+ font-size: 4rem;
120
+ color: rgba(255, 193, 7, 0.08);
121
+ z-index: -1;
122
+ animation: bouncePlate 8s ease-in-out infinite;
123
+ }
124
+
125
+ @keyframes rotateUtensil {
126
+ from { transform: rotate(0deg); }
127
+ to { transform: rotate(360deg); }
128
+ }
129
+
130
+ @keyframes bouncePlate {
131
+ 0%, 100% { transform: translateY(0px); }
132
+ 50% { transform: translateY(-20px); }
133
+ }
134
+
135
+ /* Ensure main content is perfectly centered */
136
+ main {
137
+ min-height: 100vh;
138
+ display: flex;
139
+ align-items: center;
140
+ justify-content: center;
141
+ padding: 2rem;
142
+ position: relative;
143
+ z-index: 1;
144
+ }
145
+
146
+ /* Card entrance animation */
147
+ .main-card {
148
+ animation: fadeInUp 0.8s ease-out;
149
+ width: 100%;
150
+ max-width: 540px;
151
+ }
152
+
153
+ @keyframes fadeInUp {
154
+ from {
155
+ opacity: 0;
156
+ transform: translateY(30px);
157
+ }
158
+ to {
159
+ opacity: 1;
160
+ transform: translateY(0);
161
+ }
162
+ }
163
+
164
+ /* Smooth input focus ring with scale */
165
+ input:focus, select:focus, textarea:focus {
166
+ outline: none !important;
167
+ box-shadow: 0 0 8px rgba(230, 126, 34, 0.6), 0 0 0 0.2rem rgba(230, 126, 34, 0.25) !important;
168
+ border-color: #e67e22 !important;
169
+ transform: scale(1.02);
170
+ transition: all 0.3s ease;
171
+ }
172
+
173
+ /* Icon shake on focus for fun */
174
+ .input-group:focus-within i.input-icon {
175
+ animation: shake 0.5s ease-in-out;
176
+ }
177
+
178
+ @keyframes shake {
179
+ 0%, 100% { transform: translateX(0); }
180
+ 25% { transform: translateX(-5px); }
181
+ 75% { transform: translateX(5px); }
182
+ }
183
+
184
+ /* Placeholder styling */
185
+ ::placeholder {
186
+ color: #d35400;
187
+ opacity: 0.7;
188
+ }
189
+
190
+ /* Enhanced button hover with pulse */
191
+ .btn-warning {
192
+ background: linear-gradient(45deg, #f39c12, #e67e22);
193
+ border: none;
194
+ transition: all 0.3s ease;
195
+ position: relative;
196
+ overflow: hidden;
197
+ }
198
+
199
+ .btn-warning::before {
200
+ content: '';
201
+ position: absolute;
202
+ top: 0;
203
+ left: -100%;
204
+ width: 100%;
205
+ height: 100%;
206
+ background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
207
+ transition: left 0.5s;
208
+ }
209
+
210
+ .btn-warning:hover::before {
211
+ left: 100%;
212
+ }
213
+
214
+ .btn-warning:hover {
215
+ background: linear-gradient(45deg, #e67e22, #d68910) !important;
216
+ box-shadow: 0 8px 25px rgba(231, 111, 32, 0.4);
217
+ transform: translateY(-2px);
218
+ }
219
+
220
+ /* Card hover enhancement */
221
+ .card:hover {
222
+ box-shadow: 0 20px 40px rgba(230, 126, 34, 0.25) !important;
223
+ transform: translateY(-5px);
224
+ transition: all 0.3s ease;
225
+ }
226
+
227
+ /* Prediction slide-in animation */
228
+ .prediction-result {
229
+ animation: slideInRight 0.6s ease-out;
230
+ border: none;
231
+ background: linear-gradient(135deg, #fff8f0, #ffe8cc);
232
+ box-shadow: 0 4px 15px rgba(230, 126, 34, 0.1);
233
+ }
234
+
235
+ @keyframes slideInRight {
236
+ from {
237
+ opacity: 0;
238
+ transform: translateX(100%);
239
+ }
240
+ to {
241
+ opacity: 1;
242
+ transform: translateX(0);
243
+ }
244
+ }
245
+
246
+ /* Improved Input group styling for icons - Fixed positioning */
247
+ .input-group {
248
+ position: relative;
249
+ display: block; /* Ensure consistent layout */
250
+ }
251
+
252
+ .input-group .input-icon {
253
+ position: absolute;
254
+ left: 12px;
255
+ color: #e67e22;
256
+ z-index: 10;
257
+ transition: color 0.3s ease;
258
+ pointer-events: none; /* Prevent icon from interfering with input */
259
+ }
260
+
261
+ /* For single-line inputs and selects: center vertically */
262
+ .input-group input:not(textarea), .input-group select {
263
+ padding-left: 40px;
264
+ min-height: 42px; /* Consistent height for alignment */
265
+ }
266
+
267
+ .input-group input:not(textarea) + .input-icon,
268
+ .input-group select + .input-icon {
269
+ top: 50%;
270
+ transform: translateY(-50%);
271
+ font-size: 1rem;
272
+ }
273
+
274
+ /* For textarea: Align icon to the top-left, near the first line */
275
+ .input-group textarea {
276
+ padding-left: 40px;
277
+ padding-top: 12px; /* Space for icon */
278
+ resize: vertical; /* Allow vertical resize only */
279
+ }
280
+
281
+ .input-group textarea + .input-icon {
282
+ top: 12px;
283
+ transform: none; /* No vertical centering for multi-line */
284
+ font-size: 1.1rem;
285
+ line-height: 1;
286
+ }
287
+
288
+ /* Loading spinner for button */
289
+ .btn-loading {
290
+ pointer-events: none;
291
+ opacity: 0.7;
292
+ }
293
+
294
+ .spinner-border-sm {
295
+ width: 1rem;
296
+ height: 1rem;
297
+ }
298
+
299
+ /* Responsive adjustments */
300
+ @media (max-width: 576px) {
301
+ .card {
302
+ margin: 10px;
303
+ padding: 20px !important;
304
+ }
305
+
306
+ h1 {
307
+ font-size: 1.8rem !important;
308
+ }
309
+
310
+ /* Hide background elements on small screens for performance */
311
+ body::before, body::after, .bg-utensil, .bg-plate {
312
+ display: none;
313
+ }
314
+
315
+ /* Adjust icon padding on mobile */
316
+ .input-group input, .input-group select, .input-group textarea {
317
+ padding-left: 35px;
318
+ }
319
+
320
+ .input-group .input-icon {
321
+ left: 10px;
322
+ font-size: 0.9rem;
323
+ }
324
+ }
325
+ </style>
326
  </head>
327
  <body>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
328
 
329
+ <!-- Background foody elements -->
330
+ <div class="bg-utensil">
331
+ <i class="fas fa-utensils"></i>
332
+ </div>
333
+ <div class="bg-plate">
334
+ <i class="fas fa-circle"></i> <!-- Simple plate representation -->
335
+ </div>
336
+
337
+ <main>
338
+ <div class="card main-card shadow-lg rounded-4 p-5 w-100 animate__animated" style="background: linear-gradient(135deg, #fff9f1, #fff5e6);">
339
+ <h1 class="text-center mb-5 text-4xl font-extrabold text-orange-600 animate__animated animate__bounceIn">
340
+ <i class="fas fa-utensils me-2"></i>Indian Food Flavor Profile Prediction
341
+ </h1>
342
+
343
+ <form method="post" class="needs-validation" novalidate id="predictionForm">
344
+
345
+ <!-- Ingredients -->
346
+ <div class="mb-4 input-group">
347
+ <label for="ingredients" class="form-label fw-semibold fs-6 text-secondary">
348
+ <i class="fas fa-list me-1"></i>Ingredients (comma separated):
349
+ </label>
350
+ <textarea id="ingredients" name="ingredients" rows="3" required placeholder="e.g., cumin, coriander, ginger" class="form-control rounded-3 border-2 border-warning"></textarea>
351
+ <i class="fas fa-pepper-hot input-icon"></i>
352
+ <div class="invalid-feedback">Please enter ingredients.</div>
353
+ </div>
354
+
355
+ <!-- Diet -->
356
+ <div class="mb-4 input-group">
357
+ <label for="diet" class="form-label fw-semibold fs-6 text-secondary">
358
+ <i class="fas fa-leaf me-1"></i>Diet:
359
+ </label>
360
+ <select id="diet" name="diet" required class="form-select rounded-3 border-2 border-warning">
361
+ <option value="" disabled selected>Select diet</option>
362
+ <option value="vegetarian">Vegetarian</option>
363
+ <option value="non vegetarian">Non Vegetarian</option>
364
+ </select>
365
+ <i class="fas fa-seedling input-icon"></i>
366
+ <div class="invalid-feedback">Please select a diet.</div>
367
+ </div>
368
+
369
+ <!-- Course -->
370
+ <div class="mb-4 input-group">
371
+ <label for="course" class="form-label fw-semibold fs-6 text-secondary">
372
+ <i class="fas fa-drumstick-bite me-1"></i>Course:
373
+ </label>
374
+ <select id="course" name="course" required class="form-select rounded-3 border-2 border-warning">
375
+ <option value="" disabled selected>Select course</option>
376
+ <option value="dessert">Dessert</option>
377
+ <option value="main course">Main Course</option>
378
+ <option value="starter">Starter</option>
379
+ <option value="snack">Snack</option>
380
+ </select>
381
+ <i class="fas fa-utensil-spoon input-icon"></i>
382
+ <div class="invalid-feedback">Please select a course.</div>
383
+ </div>
384
+
385
+ <!-- Region -->
386
+ <div class="mb-4 input-group">
387
+ <label for="region" class="form-label fw-semibold fs-6 text-secondary">
388
+ <i class="fas fa-map-marker-alt me-1"></i>Region:
389
+ </label>
390
+ <select id="region" name="region" required class="form-select rounded-3 border-2 border-warning">
391
+ <option value="" disabled selected>Select region</option>
392
+ <option value="East">East</option>
393
+ <option value="West">West</option>
394
+ <option value="North">North</option>
395
+ <option value="South">South</option>
396
+ </select>
397
+ <i class="fas fa-globe-americas input-icon"></i>
398
+ <div class="invalid-feedback">Please select a region.</div>
399
+ </div>
 
 
 
 
 
 
 
 
 
 
400
 
401
+ <!-- Prep & Cook Time -->
402
+ <div class="row mb-4 g-3">
403
+ <div class="col-6">
404
+ <label for="prep_time" class="form-label fw-semibold fs-6 text-secondary">
405
+ <i class="fas fa-clock me-1"></i>Preparation Time (minutes):
406
+ </label>
407
+ <div class="input-group">
408
+ <input id="prep_time" type="number" name="prep_time" min="0" required placeholder="e.g., 15" class="form-control rounded-3 border-2 border-warning" />
409
+ <i class="fas fa-stopwatch input-icon"></i>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
410
  </div>
411
+ <div class="invalid-feedback">Please enter preparation time.</div>
412
+ </div>
413
+ <div class="col-6">
414
+ <label for="cook_time" class="form-label fw-semibold fs-6 text-secondary">
415
+ <i class="fas fa-fire me-1"></i>Cook Time (minutes):
416
+ </label>
417
+ <div class="input-group">
418
+ <input id="cook_time" type="number" name="cook_time" min="0" required placeholder="e.g., 30" class="form-control rounded-3 border-2 border-warning" />
419
+ <i class="fas fa-burn input-icon"></i>
420
+ </div>
421
+ <div class="invalid-feedback">Please enter cook time.</div>
422
+ </div>
423
  </div>
424
+
425
+ <button type="submit" class="btn btn-warning w-100 py-3 fs-5 fw-bold shadow-sm mb-3" id="submitBtn">
426
+ <i class="fas fa-magic me-2"></i>Predict Flavor Profile
427
+ </button>
428
+ </form>
429
+
430
+ {% if prediction %}
431
+ <div class="prediction-result mt-4 p-4 rounded-3 bg-gradient text-warning fs-5 text-center shadow-sm fw-semibold border-0">
432
+ <i class="fas fa-star-and-crescent me-2"></i>Predicted Flavor Profile: {{ prediction }}
433
+ </div>
434
+ {% endif %}
435
  </div>
436
+ </main>
437
 
438
+ <!-- Bootstrap JS Bundle -->
439
+ <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.4.1