From c39a619a0395afaca53b75a58652218761df7291 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 9 Jan 2026 22:39:19 +0000 Subject: [PATCH] Add recipe suggester web app with ingredient-based search - Created charming UI with gradient backgrounds and smooth animations - Implemented ingredient search with autocomplete functionality - Added comprehensive database of 40 recipes with full details - Built recipe matching algorithm that scores recipes by ingredient availability - Designed interactive recipe cards with match percentages - Added modal view for detailed recipe instructions - Included responsive design for mobile and desktop --- app.js | 288 ++++++++++++++++++++ index.html | 66 +++++ recipes.js | 778 +++++++++++++++++++++++++++++++++++++++++++++++++++++ styles.css | 552 +++++++++++++++++++++++++++++++++++++ 4 files changed, 1684 insertions(+) create mode 100644 app.js create mode 100644 index.html create mode 100644 recipes.js create mode 100644 styles.css diff --git a/app.js b/app.js new file mode 100644 index 0000000..3d50821 --- /dev/null +++ b/app.js @@ -0,0 +1,288 @@ +// App State +let selectedIngredients = new Set(); +let currentRecipes = []; + +// DOM Elements +const ingredientSearch = document.getElementById('ingredient-search'); +const suggestionsContainer = document.getElementById('suggestions'); +const selectedIngredientsContainer = document.getElementById('selected-ingredients'); +const recipesContainer = document.getElementById('recipes-container'); +const recipeCount = document.getElementById('recipe-count'); +const modal = document.getElementById('recipe-modal'); +const recipeDetails = document.getElementById('recipe-details'); + +// Initialize +function init() { + setupEventListeners(); + updateRecipes(); +} + +// Event Listeners +function setupEventListeners() { + ingredientSearch.addEventListener('input', handleSearch); + ingredientSearch.addEventListener('focus', handleSearch); + + // Close suggestions when clicking outside + document.addEventListener('click', (e) => { + if (!e.target.closest('.search-box')) { + suggestionsContainer.classList.remove('active'); + } + }); + + // Close modal when clicking outside + modal.addEventListener('click', (e) => { + if (e.target === modal) { + closeModal(); + } + }); + + // Close modal with close button + document.querySelector('.close-btn').addEventListener('click', closeModal); + + // Close modal with Escape key + document.addEventListener('keydown', (e) => { + if (e.key === 'Escape' && modal.classList.contains('active')) { + closeModal(); + } + }); +} + +// Search and Autocomplete +function handleSearch(e) { + const searchTerm = e.target.value.toLowerCase().trim(); + + if (searchTerm.length === 0) { + suggestionsContainer.classList.remove('active'); + return; + } + + const matches = ALL_INGREDIENTS.filter(ingredient => + ingredient.toLowerCase().includes(searchTerm) && + !selectedIngredients.has(ingredient) + ); + + displaySuggestions(matches, searchTerm); +} + +function displaySuggestions(matches, searchTerm) { + if (matches.length === 0) { + suggestionsContainer.classList.remove('active'); + return; + } + + suggestionsContainer.innerHTML = matches.slice(0, 10).map(ingredient => { + const highlighted = highlightMatch(ingredient, searchTerm); + return `
${highlighted}
`; + }).join(''); + + suggestionsContainer.classList.add('active'); + + // Add click listeners to suggestions + suggestionsContainer.querySelectorAll('.suggestion-item').forEach(item => { + item.addEventListener('click', () => { + addIngredient(item.dataset.ingredient); + ingredientSearch.value = ''; + suggestionsContainer.classList.remove('active'); + ingredientSearch.focus(); + }); + }); +} + +function highlightMatch(text, searchTerm) { + const index = text.toLowerCase().indexOf(searchTerm.toLowerCase()); + if (index === -1) return text; + + const before = text.slice(0, index); + const match = text.slice(index, index + searchTerm.length); + const after = text.slice(index + searchTerm.length); + + return `${before}${match}${after}`; +} + +// Ingredient Management +function addIngredient(ingredient) { + if (selectedIngredients.has(ingredient)) return; + + selectedIngredients.add(ingredient); + updateSelectedIngredients(); + updateRecipes(); +} + +function removeIngredient(ingredient) { + selectedIngredients.delete(ingredient); + updateSelectedIngredients(); + updateRecipes(); +} + +function updateSelectedIngredients() { + if (selectedIngredients.size === 0) { + selectedIngredientsContainer.innerHTML = ` +
+ 🥕 +

Start adding ingredients to find recipes!

+
+ `; + return; + } + + selectedIngredientsContainer.innerHTML = Array.from(selectedIngredients) + .sort() + .map(ingredient => ` +
+ ${capitalizeFirst(ingredient)} + +
+ `).join(''); +} + +// Recipe Matching and Display +function updateRecipes() { + if (selectedIngredients.size === 0) { + recipesContainer.innerHTML = ` +
+ 👨‍🍳 +

Add some ingredients and I'll suggest delicious recipes!

+
+ `; + recipeCount.textContent = ''; + return; + } + + // Find matching recipes and calculate match scores + const recipesWithScores = RECIPES_DATABASE.map(recipe => { + const matchingIngredients = recipe.ingredients.filter(ing => + selectedIngredients.has(ing) + ); + const missingIngredients = recipe.ingredients.filter(ing => + !selectedIngredients.has(ing) + ); + + const matchScore = (matchingIngredients.length / recipe.ingredients.length) * 100; + + return { + ...recipe, + matchingIngredients, + missingIngredients, + matchScore + }; + }) + .filter(recipe => recipe.matchingIngredients.length > 0) // Only show recipes with at least one matching ingredient + .sort((a, b) => b.matchScore - a.matchScore); // Sort by match score + + currentRecipes = recipesWithScores; + + if (recipesWithScores.length === 0) { + recipesContainer.innerHTML = ` +
+ 😔 +

No recipes found with these ingredients. Try adding more!

+
+ `; + recipeCount.textContent = ''; + return; + } + + recipeCount.textContent = `${recipesWithScores.length} recipe${recipesWithScores.length !== 1 ? 's' : ''} found`; + + recipesContainer.innerHTML = recipesWithScores.map(recipe => ` +
+
${recipe.image}
+
${Math.round(recipe.matchScore)}% match
+

${recipe.name}

+
+ ⏱️ ${recipe.time} + 👥 ${recipe.servings} + 📊 ${recipe.difficulty} +
+ ${recipe.missingIngredients.length > 0 ? ` +
+ Missing: ${recipe.missingIngredients.slice(0, 3).map(ing => capitalizeFirst(ing)).join(', ')} + ${recipe.missingIngredients.length > 3 ? ` +${recipe.missingIngredients.length - 3} more` : ''} +
+ ` : '
✓ You have all ingredients!
'} +
+ `).join(''); +} + +// Recipe Details Modal +function showRecipeDetails(recipeId) { + const recipe = currentRecipes.find(r => r.id === recipeId) || + RECIPES_DATABASE.find(r => r.id === recipeId); + + if (!recipe) return; + + const hasAllIngredients = recipe.missingIngredients ? recipe.missingIngredients.length === 0 : false; + const matchScore = recipe.matchScore || 0; + + recipeDetails.innerHTML = ` +
+
${recipe.image}
+

${recipe.name}

+ +
+ ⏱️ ${recipe.time} + 👥 ${recipe.servings} servings + 📊 ${recipe.difficulty} + 🏷️ ${recipe.category} +
+ + ${matchScore > 0 ? ` +
+ ${Math.round(matchScore)}% ingredient match +
+ ` : ''} + + ${hasAllIngredients ? ` +
+ 🎉 You have all the ingredients for this recipe! +
+ ` : ''} + +
+

Ingredients

+
    + ${recipe.ingredients.map(ing => { + const hasIngredient = selectedIngredients.has(ing); + return `
  • ${capitalizeFirst(ing)}${hasIngredient ? ' ✓' : ''}
  • `; + }).join('')} +
+
+ +
+

Instructions

+
    + ${recipe.instructions.map(step => `
  1. ${step}
  2. `).join('')} +
+
+ + ${recipe.missingIngredients && recipe.missingIngredients.length > 0 ? ` +
+ Missing Ingredients:
+ ${recipe.missingIngredients.map(ing => capitalizeFirst(ing)).join(', ')} +
+ ` : ''} +
+ `; + + modal.classList.add('active'); +} + +function closeModal() { + modal.classList.remove('active'); +} + +// Utility Functions +function capitalizeFirst(str) { + return str.charAt(0).toUpperCase() + str.slice(1); +} + +// Initialize app when DOM is ready +if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', init); +} else { + init(); +} + +// Make functions globally accessible for onclick handlers +window.removeIngredient = removeIngredient; +window.showRecipeDetails = showRecipeDetails; diff --git a/index.html b/index.html new file mode 100644 index 0000000..2fd321f --- /dev/null +++ b/index.html @@ -0,0 +1,66 @@ + + + + + + Fridge Chef - Recipe Suggester + + + +
+
+
+

🍳 Fridge Chef

+

Turn your ingredients into delicious meals

+
+
+ +
+
+

What's in your fridge?

+ + + +
+
+ 🥕 +

Start adding ingredients to find recipes!

+
+
+
+ +
+
+

Recipe Suggestions

+
+
+ +
+
+ 👨‍🍳 +

Add some ingredients and I'll suggest delicious recipes!

+
+
+
+
+
+ + + + + + + diff --git a/recipes.js b/recipes.js new file mode 100644 index 0000000..fc0c330 --- /dev/null +++ b/recipes.js @@ -0,0 +1,778 @@ +// Comprehensive recipe database +const RECIPES_DATABASE = [ + { + id: 1, + name: "Classic Spaghetti Carbonara", + ingredients: ["spaghetti", "eggs", "bacon", "parmesan cheese", "black pepper", "salt"], + instructions: [ + "Cook spaghetti according to package directions in salted boiling water", + "While pasta cooks, fry bacon until crispy, then chop into small pieces", + "Beat eggs with grated parmesan cheese and black pepper", + "Drain pasta, reserving 1 cup pasta water", + "Remove pan from heat, add hot pasta to bacon", + "Quickly stir in egg mixture, adding pasta water to create creamy sauce", + "Serve immediately with extra parmesan and black pepper" + ], + time: "20 minutes", + difficulty: "Medium", + servings: 4, + category: "Pasta", + image: "🍝" + }, + { + id: 2, + name: "Chicken Stir Fry", + ingredients: ["chicken breast", "soy sauce", "garlic", "ginger", "bell peppers", "onion", "broccoli", "rice", "vegetable oil", "sesame oil"], + instructions: [ + "Cut chicken into bite-sized pieces", + "Mince garlic and ginger", + "Chop vegetables into similar-sized pieces", + "Heat vegetable oil in a wok or large pan over high heat", + "Cook chicken until golden, then remove", + "Stir-fry vegetables until tender-crisp", + "Return chicken to pan, add soy sauce and sesame oil", + "Serve over cooked rice" + ], + time: "25 minutes", + difficulty: "Easy", + servings: 4, + category: "Asian", + image: "🥘" + }, + { + id: 3, + name: "Margherita Pizza", + ingredients: ["pizza dough", "tomato sauce", "mozzarella cheese", "fresh basil", "olive oil", "salt"], + instructions: [ + "Preheat oven to 475°F (245°C)", + "Roll out pizza dough on floured surface", + "Spread tomato sauce evenly, leaving border for crust", + "Tear mozzarella and distribute over sauce", + "Drizzle with olive oil and sprinkle with salt", + "Bake for 12-15 minutes until crust is golden", + "Top with fresh basil leaves before serving" + ], + time: "30 minutes", + difficulty: "Medium", + servings: 2, + category: "Italian", + image: "🍕" + }, + { + id: 4, + name: "Greek Salad", + ingredients: ["tomatoes", "cucumber", "red onion", "feta cheese", "olives", "olive oil", "lemon juice", "oregano", "salt", "black pepper"], + instructions: [ + "Chop tomatoes and cucumber into chunks", + "Slice red onion thinly", + "Combine vegetables in a large bowl", + "Add olives and crumbled feta cheese", + "Whisk together olive oil, lemon juice, oregano, salt, and pepper", + "Pour dressing over salad and toss gently", + "Let sit for 10 minutes before serving for flavors to meld" + ], + time: "15 minutes", + difficulty: "Easy", + servings: 4, + category: "Salad", + image: "🥗" + }, + { + id: 5, + name: "Beef Tacos", + ingredients: ["ground beef", "taco shells", "lettuce", "tomatoes", "cheddar cheese", "sour cream", "onion", "cumin", "chili powder", "garlic powder", "salt"], + instructions: [ + "Brown ground beef in a large skillet over medium-high heat", + "Add cumin, chili powder, garlic powder, and salt", + "Cook until beef is fully cooked and seasoned", + "Warm taco shells according to package directions", + "Chop lettuce and tomatoes", + "Shred cheese if needed", + "Assemble tacos with beef, lettuce, tomatoes, cheese, and sour cream" + ], + time: "20 minutes", + difficulty: "Easy", + servings: 4, + category: "Mexican", + image: "🌮" + }, + { + id: 6, + name: "Mushroom Risotto", + ingredients: ["arborio rice", "mushrooms", "onion", "garlic", "white wine", "vegetable broth", "parmesan cheese", "butter", "olive oil", "parsley"], + instructions: [ + "Heat broth in a saucepan and keep warm", + "Sauté sliced mushrooms in butter until golden, set aside", + "In same pan, sauté diced onion and garlic in olive oil", + "Add rice and toast for 2 minutes", + "Pour in white wine and stir until absorbed", + "Add broth one ladle at a time, stirring constantly", + "When rice is creamy and al dente, stir in mushrooms, parmesan, and parsley" + ], + time: "40 minutes", + difficulty: "Hard", + servings: 4, + category: "Italian", + image: "🍄" + }, + { + id: 7, + name: "Pancakes", + ingredients: ["flour", "eggs", "milk", "sugar", "baking powder", "salt", "butter", "maple syrup"], + instructions: [ + "Mix flour, sugar, baking powder, and salt in a bowl", + "In another bowl, whisk eggs and milk together", + "Pour wet ingredients into dry and mix until just combined", + "Heat a griddle or pan over medium heat and add butter", + "Pour 1/4 cup batter for each pancake", + "Cook until bubbles form on surface, then flip", + "Cook until golden brown on both sides", + "Serve warm with butter and maple syrup" + ], + time: "20 minutes", + difficulty: "Easy", + servings: 4, + category: "Breakfast", + image: "🥞" + }, + { + id: 8, + name: "Caprese Salad", + ingredients: ["tomatoes", "mozzarella cheese", "fresh basil", "olive oil", "balsamic vinegar", "salt", "black pepper"], + instructions: [ + "Slice tomatoes and mozzarella into 1/4 inch rounds", + "Arrange on a platter, alternating tomato and mozzarella slices", + "Tuck fresh basil leaves between slices", + "Drizzle with olive oil and balsamic vinegar", + "Season with salt and freshly ground black pepper", + "Let sit for 5 minutes before serving to allow flavors to develop" + ], + time: "10 minutes", + difficulty: "Easy", + servings: 2, + category: "Salad", + image: "🍅" + }, + { + id: 9, + name: "Chicken Curry", + ingredients: ["chicken breast", "coconut milk", "curry powder", "onion", "garlic", "ginger", "tomatoes", "rice", "vegetable oil", "cilantro"], + instructions: [ + "Cut chicken into cubes", + "Sauté onion, garlic, and ginger in oil until fragrant", + "Add curry powder and cook for 1 minute", + "Add chicken and brown on all sides", + "Add diced tomatoes and coconut milk", + "Simmer for 20 minutes until chicken is cooked through", + "Serve over rice, garnished with fresh cilantro" + ], + time: "35 minutes", + difficulty: "Medium", + servings: 4, + category: "Indian", + image: "🍛" + }, + { + id: 10, + name: "Caesar Salad", + ingredients: ["romaine lettuce", "parmesan cheese", "croutons", "eggs", "garlic", "lemon juice", "olive oil", "worcestershire sauce", "mustard", "anchovy paste"], + instructions: [ + "Make dressing: blend egg yolk, garlic, lemon juice, worcestershire, mustard, and anchovy paste", + "Slowly drizzle in olive oil while blending until emulsified", + "Chop romaine lettuce into bite-sized pieces", + "Toss lettuce with dressing", + "Add croutons and shaved parmesan cheese", + "Toss again and serve immediately" + ], + time: "15 minutes", + difficulty: "Medium", + servings: 4, + category: "Salad", + image: "🥬" + }, + { + id: 11, + name: "Beef Burgers", + ingredients: ["ground beef", "burger buns", "lettuce", "tomatoes", "onion", "pickles", "cheddar cheese", "ketchup", "mustard", "salt", "black pepper"], + instructions: [ + "Season ground beef with salt and pepper", + "Form into 4 equal patties, making a small indent in the center", + "Heat grill or pan over medium-high heat", + "Cook burgers 4-5 minutes per side for medium", + "Add cheese in last minute of cooking if desired", + "Toast buns lightly", + "Assemble burgers with lettuce, tomato, onion, pickles, ketchup, and mustard" + ], + time: "20 minutes", + difficulty: "Easy", + servings: 4, + category: "American", + image: "🍔" + }, + { + id: 12, + name: "Shrimp Scampi", + ingredients: ["shrimp", "pasta", "garlic", "butter", "white wine", "lemon juice", "parsley", "red pepper flakes", "salt", "black pepper"], + instructions: [ + "Cook pasta according to package directions", + "Peel and devein shrimp", + "Melt butter in large pan, add minced garlic and red pepper flakes", + "Add shrimp and cook until pink, about 2-3 minutes per side", + "Add white wine and lemon juice, simmer for 2 minutes", + "Toss with drained pasta", + "Garnish with fresh parsley and serve" + ], + time: "25 minutes", + difficulty: "Medium", + servings: 4, + category: "Seafood", + image: "🍤" + }, + { + id: 13, + name: "Vegetable Soup", + ingredients: ["carrots", "celery", "onion", "potatoes", "tomatoes", "vegetable broth", "garlic", "thyme", "bay leaves", "olive oil", "salt", "black pepper"], + instructions: [ + "Chop all vegetables into bite-sized pieces", + "Heat olive oil in large pot, sauté onion, carrots, and celery", + "Add garlic and cook for 1 minute", + "Add potatoes, tomatoes, and vegetable broth", + "Add thyme and bay leaves", + "Bring to boil, then simmer for 25 minutes", + "Season with salt and pepper, remove bay leaves before serving" + ], + time: "45 minutes", + difficulty: "Easy", + servings: 6, + category: "Soup", + image: "🥣" + }, + { + id: 14, + name: "Omelette", + ingredients: ["eggs", "milk", "butter", "cheese", "salt", "black pepper"], + instructions: [ + "Beat eggs with milk, salt, and pepper", + "Heat butter in non-stick pan over medium heat", + "Pour in egg mixture", + "As eggs begin to set, gently push edges toward center", + "When mostly set but still slightly runny on top, add cheese to one half", + "Fold omelette in half and cook for 30 more seconds", + "Slide onto plate and serve immediately" + ], + time: "10 minutes", + difficulty: "Medium", + servings: 1, + category: "Breakfast", + image: "🍳" + }, + { + id: 15, + name: "Pad Thai", + ingredients: ["rice noodles", "shrimp", "eggs", "bean sprouts", "peanuts", "lime", "fish sauce", "sugar", "garlic", "tofu", "green onions", "vegetable oil"], + instructions: [ + "Soak rice noodles in warm water for 30 minutes", + "Make sauce: mix fish sauce, sugar, and lime juice", + "Heat oil in wok, scramble eggs and set aside", + "Cook garlic and shrimp until pink", + "Add drained noodles and sauce, toss until noodles soften", + "Add tofu, bean sprouts, and scrambled eggs", + "Serve garnished with peanuts, lime wedges, and green onions" + ], + time: "30 minutes", + difficulty: "Hard", + servings: 4, + category: "Asian", + image: "🍜" + }, + { + id: 16, + name: "French Toast", + ingredients: ["bread", "eggs", "milk", "cinnamon", "vanilla extract", "sugar", "butter", "maple syrup"], + instructions: [ + "Whisk together eggs, milk, cinnamon, vanilla, and sugar", + "Heat butter in a large skillet over medium heat", + "Dip bread slices in egg mixture, coating both sides", + "Cook until golden brown, about 2-3 minutes per side", + "Serve hot with butter and maple syrup", + "Optional: dust with powdered sugar" + ], + time: "15 minutes", + difficulty: "Easy", + servings: 4, + category: "Breakfast", + image: "🍞" + }, + { + id: 17, + name: "Chili Con Carne", + ingredients: ["ground beef", "kidney beans", "tomatoes", "onion", "bell peppers", "garlic", "chili powder", "cumin", "tomato paste", "beef broth", "salt", "black pepper"], + instructions: [ + "Brown ground beef in large pot, drain excess fat", + "Add diced onion, bell peppers, and garlic, cook until soft", + "Add chili powder, cumin, salt, and pepper", + "Stir in tomato paste, diced tomatoes, and beef broth", + "Add kidney beans", + "Bring to boil, then simmer for 45 minutes, stirring occasionally", + "Serve with sour cream, cheese, and green onions if desired" + ], + time: "60 minutes", + difficulty: "Medium", + servings: 6, + category: "American", + image: "🌶️" + }, + { + id: 18, + name: "Grilled Cheese Sandwich", + ingredients: ["bread", "cheddar cheese", "butter"], + instructions: [ + "Butter one side of each bread slice", + "Place cheese between unbuttered sides of bread", + "Heat skillet over medium heat", + "Place sandwich in skillet, buttered side down", + "Cook until golden brown, about 3-4 minutes", + "Flip and cook other side until golden and cheese is melted", + "Cut in half and serve hot" + ], + time: "10 minutes", + difficulty: "Easy", + servings: 1, + category: "American", + image: "🧀" + }, + { + id: 19, + name: "Teriyaki Salmon", + ingredients: ["salmon", "soy sauce", "honey", "ginger", "garlic", "rice vinegar", "sesame oil", "green onions", "sesame seeds"], + instructions: [ + "Make teriyaki sauce: combine soy sauce, honey, ginger, garlic, rice vinegar", + "Marinate salmon in half the sauce for 15 minutes", + "Heat sesame oil in pan over medium-high heat", + "Cook salmon skin-side up first, 4 minutes", + "Flip and cook 4 more minutes", + "Add remaining sauce to pan and cook until thickened", + "Garnish with green onions and sesame seeds" + ], + time: "30 minutes", + difficulty: "Medium", + servings: 4, + category: "Asian", + image: "🐟" + }, + { + id: 20, + name: "Guacamole", + ingredients: ["avocados", "lime juice", "tomatoes", "onion", "cilantro", "jalapeño", "garlic", "salt"], + instructions: [ + "Cut avocados in half, remove pit, and scoop out flesh", + "Mash avocados with fork to desired consistency", + "Add lime juice immediately to prevent browning", + "Dice tomatoes, onion, and jalapeño finely", + "Mince garlic and chop cilantro", + "Mix all ingredients together", + "Season with salt to taste", + "Serve with tortilla chips" + ], + time: "10 minutes", + difficulty: "Easy", + servings: 4, + category: "Mexican", + image: "🥑" + }, + { + id: 21, + name: "Lasagna", + ingredients: ["lasagna noodles", "ground beef", "ricotta cheese", "mozzarella cheese", "parmesan cheese", "eggs", "tomato sauce", "onion", "garlic", "italian seasoning", "salt", "black pepper"], + instructions: [ + "Preheat oven to 375°F (190°C)", + "Cook lasagna noodles according to package directions", + "Brown ground beef with onion and garlic, add tomato sauce and italian seasoning", + "Mix ricotta cheese with eggs, half the mozzarella, and parmesan", + "Layer in 9x13 pan: sauce, noodles, cheese mixture, repeat", + "Top with remaining mozzarella", + "Cover with foil and bake 25 minutes, then uncover and bake 25 more minutes", + "Let rest 15 minutes before serving" + ], + time: "90 minutes", + difficulty: "Hard", + servings: 8, + category: "Italian", + image: "🍝" + }, + { + id: 22, + name: "Fried Rice", + ingredients: ["rice", "eggs", "peas", "carrots", "green onions", "soy sauce", "sesame oil", "garlic", "ginger", "vegetable oil"], + instructions: [ + "Use day-old rice for best results", + "Scramble eggs in wok, set aside", + "Heat oil in wok over high heat", + "Stir-fry carrots and peas until tender", + "Add garlic and ginger, cook 30 seconds", + "Add rice and break up clumps", + "Add soy sauce and sesame oil, toss well", + "Stir in eggs and green onions, serve hot" + ], + time: "20 minutes", + difficulty: "Easy", + servings: 4, + category: "Asian", + image: "🍚" + }, + { + id: 23, + name: "Bruschetta", + ingredients: ["baguette", "tomatoes", "garlic", "fresh basil", "olive oil", "balsamic vinegar", "salt", "black pepper"], + instructions: [ + "Slice baguette into 1/2 inch slices", + "Brush with olive oil and toast until golden", + "Rub toasted bread with cut garlic clove", + "Dice tomatoes and mix with chopped basil", + "Add olive oil, balsamic vinegar, salt, and pepper to tomatoes", + "Let tomato mixture sit for 10 minutes", + "Spoon tomato mixture onto toasted bread just before serving" + ], + time: "20 minutes", + difficulty: "Easy", + servings: 6, + category: "Italian", + image: "🥖" + }, + { + id: 24, + name: "Chicken Alfredo", + ingredients: ["fettuccine", "chicken breast", "heavy cream", "parmesan cheese", "butter", "garlic", "salt", "black pepper", "parsley"], + instructions: [ + "Cook fettuccine according to package directions", + "Season and cook chicken in butter until done, slice", + "In same pan, sauté garlic in butter", + "Add heavy cream and bring to simmer", + "Stir in parmesan cheese until melted and smooth", + "Season with salt and pepper", + "Toss pasta with sauce and top with sliced chicken", + "Garnish with parsley and extra parmesan" + ], + time: "30 minutes", + difficulty: "Medium", + servings: 4, + category: "Italian", + image: "🍝" + }, + { + id: 25, + name: "Quesadilla", + ingredients: ["tortillas", "cheddar cheese", "bell peppers", "onion", "chicken breast", "sour cream", "salsa", "vegetable oil"], + instructions: [ + "Cook diced chicken with bell peppers and onion", + "Heat tortilla in dry skillet", + "On half the tortilla, layer cheese, chicken mixture, more cheese", + "Fold tortilla in half", + "Cook until golden and crispy on both sides", + "Cut into wedges", + "Serve with sour cream and salsa" + ], + time: "20 minutes", + difficulty: "Easy", + servings: 2, + category: "Mexican", + image: "🌮" + }, + { + id: 26, + name: "Minestrone Soup", + ingredients: ["pasta", "kidney beans", "tomatoes", "carrots", "celery", "onion", "garlic", "zucchini", "spinach", "vegetable broth", "olive oil", "italian seasoning", "parmesan cheese"], + instructions: [ + "Heat olive oil in large pot, sauté onion, carrots, and celery", + "Add garlic and italian seasoning, cook 1 minute", + "Add diced tomatoes, vegetable broth, and kidney beans", + "Bring to boil, add pasta and zucchini", + "Simmer until pasta is tender", + "Stir in fresh spinach until wilted", + "Serve with grated parmesan cheese" + ], + time: "40 minutes", + difficulty: "Easy", + servings: 6, + category: "Soup", + image: "🥣" + }, + { + id: 27, + name: "Fish Tacos", + ingredients: ["white fish", "corn tortillas", "cabbage", "lime", "sour cream", "cilantro", "cumin", "chili powder", "garlic powder", "salt"], + instructions: [ + "Season fish with cumin, chili powder, garlic powder, and salt", + "Cook fish in skillet until flaky, about 3-4 minutes per side", + "Break fish into chunks", + "Mix sour cream with lime juice for sauce", + "Shred cabbage thinly", + "Warm tortillas", + "Assemble tacos with fish, cabbage, sauce, and cilantro", + "Serve with lime wedges" + ], + time: "25 minutes", + difficulty: "Easy", + servings: 4, + category: "Mexican", + image: "🐟" + }, + { + id: 28, + name: "Chicken Noodle Soup", + ingredients: ["chicken breast", "egg noodles", "carrots", "celery", "onion", "garlic", "chicken broth", "bay leaves", "thyme", "parsley", "salt", "black pepper"], + instructions: [ + "Cut chicken into bite-sized pieces", + "Sauté onion, carrots, and celery in large pot", + "Add garlic and cook 1 minute", + "Add chicken broth, bay leaves, and thyme", + "Add chicken and simmer until cooked, about 15 minutes", + "Add egg noodles and cook until tender", + "Remove bay leaves, season with salt and pepper", + "Garnish with fresh parsley" + ], + time: "35 minutes", + difficulty: "Easy", + servings: 6, + category: "Soup", + image: "🍜" + }, + { + id: 29, + name: "Pesto Pasta", + ingredients: ["pasta", "basil", "pine nuts", "garlic", "parmesan cheese", "olive oil", "salt", "black pepper"], + instructions: [ + "Cook pasta according to package directions", + "Make pesto: blend basil, pine nuts, garlic, parmesan, and olive oil", + "Season pesto with salt and pepper", + "Reserve 1 cup pasta water before draining", + "Toss hot pasta with pesto", + "Add pasta water as needed to reach desired consistency", + "Serve with extra parmesan" + ], + time: "20 minutes", + difficulty: "Easy", + servings: 4, + category: "Italian", + image: "🍝" + }, + { + id: 30, + name: "Scrambled Eggs", + ingredients: ["eggs", "milk", "butter", "salt", "black pepper", "cheese"], + instructions: [ + "Whisk eggs with milk, salt, and pepper", + "Melt butter in non-stick pan over medium-low heat", + "Pour in egg mixture", + "Let sit for 20 seconds, then gently stir with spatula", + "Continue cooking and stirring gently until eggs are softly set", + "Add cheese in last 30 seconds if desired", + "Remove from heat while still slightly creamy", + "Serve immediately" + ], + time: "10 minutes", + difficulty: "Easy", + servings: 2, + category: "Breakfast", + image: "🥚" + }, + { + id: 31, + name: "BBQ Chicken Pizza", + ingredients: ["pizza dough", "bbq sauce", "chicken breast", "red onion", "mozzarella cheese", "cilantro"], + instructions: [ + "Preheat oven to 475°F (245°C)", + "Cook and shred chicken, toss with BBQ sauce", + "Roll out pizza dough", + "Spread BBQ sauce on dough as base", + "Top with chicken, sliced red onion, and mozzarella", + "Bake 12-15 minutes until crust is golden", + "Garnish with fresh cilantro before serving" + ], + time: "30 minutes", + difficulty: "Medium", + servings: 2, + category: "American", + image: "🍕" + }, + { + id: 32, + name: "Tom Yum Soup", + ingredients: ["shrimp", "mushrooms", "tomatoes", "lemongrass", "lime leaves", "galangal", "fish sauce", "lime juice", "chili peppers", "cilantro", "chicken broth"], + instructions: [ + "Bring chicken broth to boil", + "Add lemongrass, lime leaves, and galangal", + "Simmer for 10 minutes to infuse flavors", + "Add mushrooms and tomatoes", + "Add shrimp and cook until pink", + "Season with fish sauce and lime juice", + "Add chili peppers for heat", + "Garnish with fresh cilantro" + ], + time: "30 minutes", + difficulty: "Medium", + servings: 4, + category: "Asian", + image: "🍲" + }, + { + id: 33, + name: "Chicken Parmesan", + ingredients: ["chicken breast", "bread crumbs", "parmesan cheese", "eggs", "tomato sauce", "mozzarella cheese", "flour", "italian seasoning", "olive oil"], + instructions: [ + "Pound chicken to even thickness", + "Set up breading station: flour, beaten eggs, bread crumbs mixed with parmesan", + "Bread chicken: flour, egg, bread crumbs", + "Fry in olive oil until golden, about 4 minutes per side", + "Place in baking dish, top with tomato sauce and mozzarella", + "Bake at 400°F until cheese is melted and bubbly", + "Serve over pasta" + ], + time: "40 minutes", + difficulty: "Medium", + servings: 4, + category: "Italian", + image: "🍗" + }, + { + id: 34, + name: "Falafel", + ingredients: ["chickpeas", "onion", "garlic", "parsley", "cilantro", "cumin", "coriander", "flour", "baking powder", "salt", "vegetable oil"], + instructions: [ + "Soak dried chickpeas overnight", + "Blend chickpeas, onion, garlic, herbs, and spices in food processor", + "Add flour and baking powder, pulse to combine", + "Refrigerate mixture for 1 hour", + "Form into small balls or patties", + "Deep fry in oil heated to 350°F until golden brown", + "Drain on paper towels", + "Serve in pita with tahini sauce and vegetables" + ], + time: "30 minutes (plus overnight soaking)", + difficulty: "Medium", + servings: 4, + category: "Middle Eastern", + image: "🧆" + }, + { + id: 35, + name: "Mac and Cheese", + ingredients: ["macaroni", "cheddar cheese", "milk", "butter", "flour", "salt", "black pepper", "mustard"], + instructions: [ + "Cook macaroni according to package directions", + "Make roux: melt butter, whisk in flour, cook 1 minute", + "Gradually whisk in milk, cook until thickened", + "Remove from heat, stir in shredded cheese until melted", + "Add mustard, salt, and pepper", + "Toss with drained macaroni", + "Optional: top with bread crumbs and bake until golden" + ], + time: "25 minutes", + difficulty: "Medium", + servings: 4, + category: "American", + image: "🧀" + }, + { + id: 36, + name: "Spring Rolls", + ingredients: ["rice paper", "shrimp", "rice noodles", "carrots", "cucumber", "lettuce", "mint", "cilantro", "peanut sauce"], + instructions: [ + "Cook shrimp and rice noodles, let cool", + "Julienne carrots and cucumber", + "Dip rice paper in warm water until soft", + "Lay flat and add lettuce, noodles, shrimp, vegetables, and herbs", + "Fold sides in and roll tightly", + "Serve with peanut sauce for dipping", + "Keep covered with damp towel until serving" + ], + time: "30 minutes", + difficulty: "Medium", + servings: 4, + category: "Asian", + image: "🥗" + }, + { + id: 37, + name: "Meatballs", + ingredients: ["ground beef", "bread crumbs", "eggs", "parmesan cheese", "garlic", "parsley", "onion", "milk", "salt", "black pepper", "tomato sauce"], + instructions: [ + "Preheat oven to 400°F (200°C)", + "Soak bread crumbs in milk", + "Mix ground beef, soaked bread crumbs, eggs, parmesan, garlic, parsley, and onion", + "Season with salt and pepper", + "Form into 1.5-inch balls", + "Bake for 20 minutes until browned", + "Simmer in tomato sauce for 10 minutes", + "Serve over pasta or in sub sandwich" + ], + time: "45 minutes", + difficulty: "Medium", + servings: 4, + category: "Italian", + image: "🍝" + }, + { + id: 38, + name: "Hummus", + ingredients: ["chickpeas", "tahini", "lemon juice", "garlic", "olive oil", "cumin", "salt", "paprika"], + instructions: [ + "Drain and rinse chickpeas, reserve some liquid", + "Blend chickpeas, tahini, lemon juice, and garlic in food processor", + "Add olive oil slowly while blending", + "Add reserved chickpea liquid to reach desired consistency", + "Season with cumin and salt", + "Transfer to bowl, create well in center", + "Drizzle with olive oil and sprinkle with paprika", + "Serve with pita bread or vegetables" + ], + time: "10 minutes", + difficulty: "Easy", + servings: 6, + category: "Middle Eastern", + image: "🫘" + }, + { + id: 39, + name: "Pork Chops", + ingredients: ["pork chops", "garlic", "thyme", "butter", "olive oil", "salt", "black pepper"], + instructions: [ + "Season pork chops generously with salt and pepper", + "Heat olive oil in skillet over medium-high heat", + "Sear pork chops 4-5 minutes per side", + "Add butter, garlic, and thyme to pan", + "Baste pork chops with butter mixture", + "Cook until internal temperature reaches 145°F", + "Let rest 5 minutes before serving" + ], + time: "20 minutes", + difficulty: "Medium", + servings: 4, + category: "American", + image: "🥩" + }, + { + id: 40, + name: "Banana Bread", + ingredients: ["bananas", "flour", "sugar", "eggs", "butter", "baking soda", "salt", "vanilla extract", "cinnamon"], + instructions: [ + "Preheat oven to 350°F (175°C)", + "Mash ripe bananas in bowl", + "Cream butter and sugar together", + "Beat in eggs and vanilla", + "Mix in mashed bananas", + "In separate bowl, combine flour, baking soda, salt, and cinnamon", + "Fold dry ingredients into wet ingredients", + "Pour into greased loaf pan", + "Bake 60 minutes until toothpick comes out clean" + ], + time: "75 minutes", + difficulty: "Easy", + servings: 8, + category: "Baking", + image: "🍌" + } +]; + +// Extract all unique ingredients for search functionality +const ALL_INGREDIENTS = [...new Set(RECIPES_DATABASE.flatMap(recipe => recipe.ingredients))].sort(); diff --git a/styles.css b/styles.css new file mode 100644 index 0000000..976c662 --- /dev/null +++ b/styles.css @@ -0,0 +1,552 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +:root { + --primary-color: #FF6B6B; + --secondary-color: #4ECDC4; + --accent-color: #FFE66D; + --bg-color: #F7F9FC; + --card-bg: #FFFFFF; + --text-dark: #2C3E50; + --text-light: #7F8C8D; + --shadow: 0 4px 6px rgba(0, 0, 0, 0.1); + --shadow-lg: 0 10px 30px rgba(0, 0, 0, 0.15); +} + +body { + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + min-height: 100vh; + padding: 20px; + color: var(--text-dark); +} + +.container { + max-width: 1400px; + margin: 0 auto; + background: var(--bg-color); + border-radius: 20px; + box-shadow: var(--shadow-lg); + overflow: hidden; +} + +header { + background: linear-gradient(135deg, var(--primary-color), #FF8E53); + color: white; + padding: 40px 30px; + text-align: center; + position: relative; + overflow: hidden; +} + +header::before { + content: ''; + position: absolute; + top: -50%; + right: -50%; + width: 200%; + height: 200%; + background: radial-gradient(circle, rgba(255,255,255,0.1) 0%, transparent 70%); + animation: float 6s ease-in-out infinite; +} + +@keyframes float { + 0%, 100% { transform: translate(0, 0) rotate(0deg); } + 50% { transform: translate(-20px, 20px) rotate(5deg); } +} + +.header-content { + position: relative; + z-index: 1; +} + +h1 { + font-size: 3em; + margin-bottom: 10px; + text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.2); + animation: slideDown 0.5s ease-out; +} + +@keyframes slideDown { + from { + opacity: 0; + transform: translateY(-20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.tagline { + font-size: 1.2em; + opacity: 0.95; + animation: fadeIn 0.8s ease-out 0.2s both; +} + +@keyframes fadeIn { + from { opacity: 0; } + to { opacity: 0.95; } +} + +main { + padding: 40px 30px; + display: grid; + grid-template-columns: 1fr 2fr; + gap: 30px; +} + +@media (max-width: 968px) { + main { + grid-template-columns: 1fr; + } +} + +section { + background: var(--card-bg); + border-radius: 15px; + padding: 30px; + box-shadow: var(--shadow); + transition: transform 0.3s ease; +} + +section:hover { + transform: translateY(-2px); +} + +h2 { + color: var(--text-dark); + margin-bottom: 20px; + font-size: 1.8em; + display: flex; + align-items: center; + gap: 10px; +} + +.search-box { + position: relative; + margin-bottom: 25px; +} + +#ingredient-search { + width: 100%; + padding: 15px 20px; + border: 2px solid #E0E0E0; + border-radius: 50px; + font-size: 16px; + transition: all 0.3s ease; + outline: none; +} + +#ingredient-search:focus { + border-color: var(--secondary-color); + box-shadow: 0 0 0 3px rgba(78, 205, 196, 0.1); + transform: scale(1.02); +} + +.suggestions { + position: absolute; + top: 100%; + left: 0; + right: 0; + background: white; + border-radius: 15px; + box-shadow: var(--shadow-lg); + max-height: 300px; + overflow-y: auto; + z-index: 100; + margin-top: 10px; + display: none; +} + +.suggestions.active { + display: block; + animation: slideIn 0.3s ease-out; +} + +@keyframes slideIn { + from { + opacity: 0; + transform: translateY(-10px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.suggestion-item { + padding: 12px 20px; + cursor: pointer; + transition: all 0.2s ease; + border-bottom: 1px solid #f0f0f0; +} + +.suggestion-item:last-child { + border-bottom: none; +} + +.suggestion-item:hover { + background: var(--bg-color); + padding-left: 25px; +} + +.suggestion-item mark { + background: var(--accent-color); + padding: 2px 4px; + border-radius: 3px; + font-weight: bold; +} + +.selected-ingredients { + display: flex; + flex-wrap: wrap; + gap: 10px; + min-height: 100px; +} + +.ingredient-tag { + background: linear-gradient(135deg, var(--secondary-color), #45B7AA); + color: white; + padding: 10px 15px; + border-radius: 25px; + display: inline-flex; + align-items: center; + gap: 8px; + font-size: 14px; + animation: popIn 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55); + cursor: default; + transition: all 0.3s ease; +} + +@keyframes popIn { + 0% { + opacity: 0; + transform: scale(0.5); + } + 100% { + opacity: 1; + transform: scale(1); + } +} + +.ingredient-tag:hover { + transform: translateY(-2px); + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); +} + +.ingredient-tag .remove-btn { + background: rgba(255, 255, 255, 0.3); + border: none; + color: white; + width: 20px; + height: 20px; + border-radius: 50%; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + transition: all 0.2s ease; + font-size: 16px; + line-height: 1; +} + +.ingredient-tag .remove-btn:hover { + background: rgba(255, 255, 255, 0.5); + transform: rotate(90deg); +} + +.empty-state { + width: 100%; + text-align: center; + padding: 40px 20px; + color: var(--text-light); +} + +.empty-icon { + font-size: 4em; + display: block; + margin-bottom: 15px; + animation: bounce 2s infinite; +} + +@keyframes bounce { + 0%, 100% { transform: translateY(0); } + 50% { transform: translateY(-10px); } +} + +.section-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 20px; +} + +.recipe-count { + background: var(--accent-color); + color: var(--text-dark); + padding: 8px 16px; + border-radius: 20px; + font-weight: bold; + font-size: 14px; + animation: pulse 2s infinite; +} + +@keyframes pulse { + 0%, 100% { transform: scale(1); } + 50% { transform: scale(1.05); } +} + +.recipes-container { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); + gap: 20px; +} + +.recipe-card { + background: white; + border-radius: 15px; + padding: 20px; + box-shadow: var(--shadow); + cursor: pointer; + transition: all 0.3s ease; + animation: fadeInUp 0.5s ease-out; + border: 2px solid transparent; +} + +@keyframes fadeInUp { + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.recipe-card:hover { + transform: translateY(-5px); + box-shadow: var(--shadow-lg); + border-color: var(--primary-color); +} + +.recipe-image { + font-size: 3em; + text-align: center; + margin-bottom: 15px; + animation: rotate 3s ease-in-out infinite; +} + +@keyframes rotate { + 0%, 100% { transform: rotate(-5deg); } + 50% { transform: rotate(5deg); } +} + +.recipe-card h3 { + color: var(--text-dark); + margin-bottom: 10px; + font-size: 1.3em; +} + +.recipe-meta { + display: flex; + gap: 15px; + margin-bottom: 12px; + font-size: 0.9em; + color: var(--text-light); +} + +.recipe-meta span { + display: flex; + align-items: center; + gap: 5px; +} + +.match-score { + background: linear-gradient(135deg, #4CAF50, #45a049); + color: white; + padding: 6px 12px; + border-radius: 20px; + font-size: 0.85em; + font-weight: bold; + display: inline-block; + margin-bottom: 10px; +} + +.missing-ingredients { + font-size: 0.85em; + color: #FF9800; + margin-top: 8px; + padding: 8px; + background: #FFF3E0; + border-radius: 8px; +} + +/* Modal Styles */ +.modal { + display: none; + position: fixed; + z-index: 1000; + left: 0; + top: 0; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.7); + animation: fadeIn 0.3s ease; +} + +.modal.active { + display: flex; + align-items: center; + justify-content: center; +} + +.modal-content { + background: white; + border-radius: 20px; + padding: 40px; + max-width: 700px; + max-height: 90vh; + overflow-y: auto; + position: relative; + animation: scaleIn 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55); + margin: 20px; +} + +@keyframes scaleIn { + from { + opacity: 0; + transform: scale(0.7); + } + to { + opacity: 1; + transform: scale(1); + } +} + +.close-btn { + position: absolute; + top: 20px; + right: 20px; + background: var(--primary-color); + color: white; + border: none; + width: 40px; + height: 40px; + border-radius: 50%; + font-size: 24px; + cursor: pointer; + transition: all 0.3s ease; + display: flex; + align-items: center; + justify-content: center; +} + +.close-btn:hover { + background: #FF5252; + transform: rotate(90deg); +} + +.recipe-detail-image { + font-size: 5em; + text-align: center; + margin-bottom: 20px; +} + +.recipe-detail h2 { + color: var(--text-dark); + margin-bottom: 15px; +} + +.recipe-detail .recipe-meta { + margin-bottom: 25px; + padding-bottom: 20px; + border-bottom: 2px solid #f0f0f0; +} + +.ingredients-list { + margin-bottom: 30px; +} + +.ingredients-list h3 { + color: var(--primary-color); + margin-bottom: 15px; + font-size: 1.3em; +} + +.ingredients-list ul { + list-style: none; +} + +.ingredients-list li { + padding: 10px; + margin-bottom: 8px; + background: var(--bg-color); + border-radius: 8px; + position: relative; + padding-left: 30px; +} + +.ingredients-list li::before { + content: '✓'; + position: absolute; + left: 10px; + color: var(--secondary-color); + font-weight: bold; +} + +.instructions-list h3 { + color: var(--primary-color); + margin-bottom: 15px; + font-size: 1.3em; +} + +.instructions-list ol { + padding-left: 20px; +} + +.instructions-list li { + padding: 12px; + margin-bottom: 12px; + background: var(--bg-color); + border-radius: 8px; + line-height: 1.6; +} + +/* Scrollbar Styles */ +::-webkit-scrollbar { + width: 10px; +} + +::-webkit-scrollbar-track { + background: #f1f1f1; + border-radius: 10px; +} + +::-webkit-scrollbar-thumb { + background: var(--secondary-color); + border-radius: 10px; +} + +::-webkit-scrollbar-thumb:hover { + background: #45B7AA; +} + +/* Loading Animation */ +.loading { + display: inline-block; + width: 20px; + height: 20px; + border: 3px solid rgba(255,255,255,.3); + border-radius: 50%; + border-top-color: white; + animation: spin 1s ease-in-out infinite; +} + +@keyframes spin { + to { transform: rotate(360deg); } +}