evaluate this app and ideas to make it better: <html><head><base href="." /><title>Personalized Recipe & Meal Planner</title><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"><link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;600&family=Playfair+Display:wght@700&display=swap" rel="stylesheet"><script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script><script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script><style>:root {  /* Light theme */  --primary: #2b6777;  --secondary: #c8d8e4;  --accent: #52ab98;  --background: #f2f2f2;  --text: #2f4858;  --card-bg: #ffffff;  --shadow: rgba(0,0,0,0.1);  /* Font families */  --heading-font: 'Playfair Display', serif;  --body-font: 'Montserrat', sans-serif;}[data-theme="dark"] {  --primary: #52ab98;  --secondary: #2b6777;  --accent: #c8d8e4;  --background: #1a1a1a;  --text: #f2f2f2;  --card-bg: #2f4858;  --shadow: rgba(255,255,255,0.1);}body {  font-family: var(--body-font);  margin: 0;  padding: 10px;  background: var(--background);  color: var(--text);  transition: all 0.3s ease;} .theme-toggle {  position: fixed;  top: 20px;  right: 20px;  background: var(--accent);  border: none;  border-radius: 50%;  width: 50px;  height: 50px;  cursor: pointer;  display: flex;  align-items: center;  justify-content: center;  font-size: 1.5em;  color: var(--background);  box-shadow: 0 2px 5px var(--shadow);  transition: all 0.3s ease;} .theme-toggle:hover {  transform: scale(1.1);} .app-container {  max-width: 1200px;  margin: 0 auto;  padding: 15px;  background: var(--card-bg);  border-radius: 10px;  box-shadow: 0 0 20px var(--shadow);} .header {  text-align: center;  margin-bottom: 20px;} .header h1 {  font-family: var(--heading-font);  color: var(--primary);  font-size: clamp(1.5em, 5vw, 3em);  margin-bottom: 10px;} .header p {  font-size: clamp(0.9em, 2vw, 1.1em);  color: var(--text);} .ingredient-input input {  flex: 1;  min-width: 200px;  padding: 12px;  border: 2px solid var(--primary);  border-radius: 5px;  font-size: 1em;  font-family: var(--body-font);  background: var(--card-bg);  color: var(--text);} .ingredient-input button {  background: var(--accent);  color: var(--background);  border: none;  padding: 12px 24px;  border-radius: 5px;  cursor: pointer;  transition: all 0.3s;  font-family: var(--body-font);  font-weight: 600;} .ingredient-input button:hover {  transform: translateY(-2px);  box-shadow: 0 4px 8px var(--shadow);} .recipe-card {  background: var(--card-bg);  border-radius: 10px;  padding: 20px;  box-shadow: 0 4px 15px var(--shadow);  transition: transform 0.3s ease;} .recipe-card:hover {  transform: translateY(-5px);} .recipe-card h3 {  font-family: var(--heading-font);  color: var(--primary);  margin: 15px 0;}.ingredient-input {  display: flex;  gap: 10px;  margin-bottom: 20px;  flex-wrap: wrap;} .ingredients-list {  display: flex;  flex-wrap: wrap;  gap: 10px;  margin-bottom: 20px;} .ingredient-tag {  background: var(--light);  padding: 5px 10px;  border-radius: 15px;  display: flex;  align-items: center;  gap: 5px;  font-size: clamp(0.8em, 2vw, 1em);} .recipe-container {  display: grid;  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));  gap: 20px;  margin-top: 20px;} .recipe-image {  width: 100%;  height: clamp(250px, 40vw, 400px);  border-radius: 5px;  margin-bottom: 10px;} .recipe-image img {  width: 100%;  height: 100%;  object-fit: cover;  border-radius: 5px;} .nutrition-info {  display: grid;  grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));  gap: 10px;  margin-top: 10px;} .dietary-filters {  display: flex;  gap: 8px;  margin-bottom: 20px;  flex-wrap: wrap;  justify-content: center;} .dietary-filter {  background: var(--card-bg);  border: 2px solid var(--accent);  padding: 5px 15px;  border-radius: 20px;  cursor: pointer;  transition: all 0.3s;  font-size: clamp(0.8em, 2vw, 1em);} .dietary-filter.active {  background: var(--accent);  color: var(--background);} .generate-recipes {  width: 100%;  max-width: 300px;  margin: 20px auto;  padding: clamp(10px, 3vw, 15px) clamp(20px, 5vw, 30px);  font-size: clamp(0.9em, 2.5vw, 1.1em);  background: var(--accent);  color: var(--background);  border: none;  border-radius: 5px;  cursor: pointer;  transition: all 0.3s;  font-family: var(--body-font);  font-weight: 600;} .generate-recipes:hover {  transform: translateY(-2px);  box-shadow: 0 4px 8px var(--shadow);} .recipe-instructions {  font-size: clamp(0.85em, 2vw, 1em);} .notification {  width: 90%;  max-width: 400px;  left: 50%;  transform: translateX(-50%);} .recipe-instructions h2 {  color: var(--primary);  font-family: var(--heading-font);  margin: 1.5em 0 0.5em;  font-size: 1.3em;} .recipe-instructions h3 {  color: var(--accent);  font-family: var(--heading-font);  margin: 1em 0 0.5em;  font-size: 1.1em;} .recipe-instructions ul, .recipe-instructions ol {  padding-left: 1.5em;  margin: 0.5em 0;} .recipe-instructions p {  margin: 0.5em 0;  line-height: 1.5;} .recipe-instructions strong {  color: var(--primary);} .allergy-input {  display: flex;  gap: 10px;  margin: 20px 0;  flex-wrap: wrap;} .allergy-input input {  flex: 1;  min-width: 200px;  padding: 12px;  border: 2px solid var(--primary);  border-radius: 5px;  font-size: 1em;  font-family: var(--body-font);  background: var(--card-bg);  color: var(--text);} .allergy-input button {  background: #ff4444;  color: var(--background);  border: none;  padding: 12px 24px;  border-radius: 5px;  cursor: pointer;  transition: all 0.3s;  font-family: var(--body-font);  font-weight: 600;} .allergy-input button:hover {  transform: translateY(-2px);  box-shadow: 0 4px 8px var(--shadow);} .allergies-list {  display: flex;  flex-wrap: wrap;  gap: 10px;  margin-bottom: 20px;} .allergy-tag {  background: #ff4444;  color: white;  padding: 5px 10px;  border-radius: 15px;  display: flex;  align-items: center;  gap: 5px;  font-size: clamp(0.8em, 2vw, 1em);} .loading-overlay {  position: fixed;  top: 0;  left: 0;  right: 0;  bottom: 0;  background: rgba(0, 0, 0, 0.7);  display: flex;  justify-content: center;  align-items: center;  z-index: 1000;} .loading-spinner {  font-size: 48px;  animation: bounce 0.6s infinite alternate;  text-shadow: 0 0 10px rgba(255,255,255,0.5);} @keyframes bounce {  from {    transform: scale(1) rotate(0deg);  }  to {    transform: scale(1.2) rotate(10deg);  }} @media (max-width: 600px) {  .app-container {    padding: 10px;  }  .recipe-card {    padding: 10px;  }  .nutrition-info {    grid-template-columns: repeat(2, 1fr);  }  .dietary-filters {    justify-content: flex-start;  }} @media (max-width: 400px) {  body {    padding: 5px;  }  .ingredient-input {    flex-direction: column;  }  .ingredient-input input,  .ingredient-input button {    width: 100%;  }}</style></head><body><button class="theme-toggle" onclick="toggleTheme()" aria-label="Toggle dark mode"><i class="fas fa-moon"></i></button><div id="app" class="app-container"><div class="notification" role="alert"></div><div class="header"><h1>🥗 Recipe & Meal Planner</h1><p>Your personal assistant for delicious meals!</p></div><div class="dietary-filters" role="group" aria-label="Dietary Filters"></div><div class="ingredient-input"><input placeholder="Enter ingredients you have (e.g. chicken, rice, tomatoes)..." aria-label="Ingredient input" onkeyup="if(event.key === 'Enter') addIngredient()"><button onclick="addIngredient()" aria-label="Add ingredient">Add</button></div><div class="ingredients-list"></div><div class="allergy-input"><input placeholder="Optional: Enter allergies (e.g. peanuts, shellfish, dairy)..." aria-label="Optional allergy input" onkeyup="if(event.key === 'Enter') addAllergy()"><button onclick="addAllergy()" aria-label="Add allergy">Add Allergy</button></div><div class="allergies-list"></div><button class="generate-recipes" onclick="generateCustomRecipes()">Generate Custom Recipes</button><div class="loading-overlay" style="display: none;" aria-live="assertive" aria-busy="true"><div class="loading-spinner">🍳</div></div><div class="recipe-container"></div></div><script>const state = {newIngredient: '',ingredients: [],dietaryFilters: ['Vegetarian', 'Vegan', 'Gluten-Free', 'Keto', 'Low-Carb'],activeFilters: [],recipes: [],isLoading: false,notification: {message: '',type: ''},allergies: []};async function generateCustomRecipes() {if (state.ingredients.length === 0) {showNotification('Please add some ingredients first!', 'error');return;}state.isLoading = true;const loadingOverlay = document.querySelector('.loading-overlay');loadingOverlay.style.display = 'flex';const loadingEmojis = ['🍳', '🥗', '👨‍🍳', '🥘', '⚡'];let emojiIndex = 0;const loadingSpinner = document.querySelector('.loading-spinner');const loadingInterval = setInterval(() => {loadingSpinner.textContent = loadingEmojis[emojiIndex];emojiIndex = (emojiIndex + 1) % loadingEmojis.length;}, 600);try {const recipes = await Promise.all([generateSingleRecipe('Create a unique main course recipe'),generateSingleRecipe('Create a different recipe, perhaps a side dish or dessert')]);state.recipes = recipes;renderRecipes();showNotification('Recipes generated successfully!', 'success');} catch (error) {showNotification('Failed to generate recipes. Please try again.', 'error');console.error('Error generating recipes:', error);} finally {clearInterval(loadingInterval);state.isLoading = false;loadingOverlay.style.display = 'none';}}async function generateSingleRecipe(recipeType) {const allergyWarning = state.allergies.length > 0 ? ` Please avoid these allergens: ${state.allergies.join(', ')}.` : ''; const prompt = encodeURIComponent(`${recipeType} using these ingredients: ${state.ingredients.join(', ')}.${allergyWarning} Include detailed name, description, step-by-step instructions, and cooking time.`); try {const textResponse = await fetch(`https://text.pollinations.ai/${prompt}`);const recipeText = await textResponse.text();const recipe = parseRecipeText(recipeText);const imagePrompt = encodeURIComponent(`Professional food photography of ${recipe.name}, styled dish, high resolution`);const imageUrl = `https://image.pollinations.ai/prompt/${imagePrompt}`;return {...recipe,imageUrl,imageLoaded: false,dietary: generateRandomDietaryTags()};} catch (error) {throw new Error('Failed to generate recipe');}}function parseRecipeText(text) {const lines = text.split('\n');let name = lines[0] || 'Delicious Recipe';let description = lines[1] || 'A wonderful combination of flavors';name = name.replace(/^(recipe for|how to make|recipe:|name:)/i, '').trim();const markdownInstructions = text.split('\n').slice(2).join('\n').replace(/(\d+\.|step\s+\d+[:.])/gi, '### $1').replace(/ingredients:/i, '## Ingredients:').replace(/instructions:/i, '## Instructions:').replace(/(\w+):/g, '**$1:**');return {name,description,instructions: markdownInstructions,calories: Math.floor(Math.random() * 500) + 200,protein: Math.floor(Math.random() * 30) + 10,carbs: Math.floor(Math.random() * 50) + 20,fat: Math.floor(Math.random() * 20) + 5};}function generateRandomDietaryTags() {return state.dietaryFilters.filter(() => Math.random() > 0.5);}function renderIngredients() {const list = document.querySelector('.ingredients-list');list.innerHTML = state.ingredients.map(ingredient => `<div class="ingredient-tag">${ingredient}<button onclick="removeIngredient('${ingredient}')" aria-label="Remove ingredient">×</button></div>`).join('');}function renderAllergies() {const list = document.querySelector('.allergies-list');list.innerHTML = state.allergies.map(allergy => `<div class="allergy-tag">${allergy}<button onclick="removeAllergy('${allergy}')" aria-label="Remove allergy">×</button></div>`).join('');}function renderFilters() {const filters = document.querySelector('.dietary-filters');filters.innerHTML = state.dietaryFilters.map(filter => `<button class="dietary-filter ${state.activeFilters.includes(filter) ? 'active' : ''}"onclick="toggleFilter('${filter}')" aria-pressed="${state.activeFilters.includes(filter)}">${filter}</button>`).join('');}function renderRecipes() {const container = document.querySelector('.recipe-container');const filteredRecipes = state.activeFilters.length === 0 ? state.recipes : state.recipes.filter(recipe => state.activeFilters.every(filter => recipe.dietary.includes(filter)));container.innerHTML = filteredRecipes.map(recipe => `<div class="recipe-card"><div class="recipe-image"><img src="${recipe.imageUrl}" alt="Image of ${recipe.name}, styled with professional food photography" class="${recipe.imageLoaded ? '' : 'loading'}" onload="this.classList.remove('loading')" loading="lazy"></div><h3>${recipe.name}</h3><p>${recipe.description}</p><div class="nutrition-info"><div class="nutrition-item">Calories: ${recipe.calories}</div><div class="nutrition-item">Protein: ${recipe.protein}g</div><div class="nutrition-item">Carbs: ${recipe.carbs}g</div><div class="nutrition-item">Fat: ${recipe.fat}g</div></div><div class="recipe-instructions">${marked.parse(recipe.instructions)}</div></div>`).join('');}function addIngredient() {const input = document.querySelector('.ingredient-input input');const ingredient = input.value.trim();if (ingredient && !state.ingredients.includes(ingredient)) {state.ingredients.push(ingredient);input.value = '';showNotification('Ingredient added successfully!', 'success');renderIngredients();} else if (state.ingredients.includes(ingredient)) {showNotification('Ingredient already exists.', 'error');}}function addAllergy() {const input = document.querySelector('.allergy-input input');const allergy = input.value.trim();if (allergy && !state.allergies.includes(allergy)) {state.allergies.push(allergy);input.value = '';showNotification('Allergy added successfully!', 'success');renderAllergies();} else if (state.allergies.includes(allergy)) {showNotification('Allergy already exists.', 'error');}}function removeIngredient(ingredient) {state.ingredients = state.ingredients.filter(i => i !== ingredient);showNotification('Ingredient removed.', 'success');renderIngredients();}function removeAllergy(allergy) {state.allergies = state.allergies.filter(a => a !== allergy);showNotification('Allergy removed.', 'success');renderAllergies();}function toggleFilter(filter) {if (state.activeFilters.includes(filter)) {state.activeFilters = state.activeFilters.filter(f => f !== filter);} else {state.activeFilters.push(filter);}renderFilters();renderRecipes();}function showNotification(message, type = 'success') {const notificationEl = document.querySelector('.notification');notificationEl.textContent = message;notificationEl.className = `notification ${type}`;notificationEl.style.display = 'flex';setTimeout(() => {notificationEl.style.display = 'none';}, 3000);}function toggleTheme() {const body = document.body;const currentTheme = body.getAttribute('data-theme');const toggleButton = document.querySelector('.theme-toggle i');if (currentTheme === 'dark') {body.removeAttribute('data-theme');toggleButton.classList.remove('fa-sun');toggleButton.classList.add('fa-moon');} else {body.setAttribute('data-theme', 'dark');toggleButton.classList.remove('fa-moon');toggleButton.classList.add('fa-sun');}}document.addEventListener('DOMContentLoaded', () => {renderFilters();renderIngredients();renderAllergies();renderRecipes();});</script></body></html>