<!DOCTYPE html>
<html lang="en-GB">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Phil’s Food | Weekly Meal Planner & Smart Grocery List</title>
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
<style>
@import url('https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700&display=swap');
body { font-family: 'Outfit', sans-serif; }
.tab-active { border-bottom: 3px solid #e05638; color: #e05638; font-weight: 600; }
.custom-scrollbar::-webkit-scrollbar { width: 6px; }
.custom-scrollbar::-webkit-scrollbar-track { background: #f1f1f1; }
.custom-scrollbar::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 4px; }
</style>
</head>
<body class="bg-slate-50 text-slate-800 min-h-screen flex flex-col">
<!-- Header -->
<header class="bg-white shadow-sm sticky top-0 z-50 border-b border-slate-200">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex justify-between items-center h-16">
<div class="flex items-center space-x-3">
<div class="bg-red-600 text-white p-2 rounded-xl flex items-center justify-center w-10 h-10 shadow-md">
<i class="fa-solid font-bold text-xl fa-utensils"></i>
</div>
<span class="font-bold text-xl tracking-tight text-slate-900">Phil’s<span class="text-red-600">Food</span></span>
<span class="bg-red-50 text-red-700 text-xs font-semibold px-2.5 py-0.5 rounded-full border border-red-200">UK Measures</span>
</div>
<nav class="flex space-x-6 text-sm font-medium text-slate-500">
<button onclick="switchTab('recipes')" id="tab-btn-recipes" class="py-5 px-1 tab-active transition-all flex items-center space-x-2">
<i class="fa-solid fa-book-open"></i><span>Recipes</span>
</button>
<button onclick="switchTab('planner')" id="tab-btn-planner" class="py-5 px-1 hover:text-slate-700 transition-all flex items-center space-x-2">
<i class="fa-solid fa-calendar-days"></i><span>Weekly Plan</span>
</button>
<button onclick="switchTab('shopping')" id="tab-btn-shopping" class="py-5 px-1 hover:text-slate-700 transition-all flex items-center space-x-2 relative">
<i class="fa-solid fa-cart-shopping"></i><span>Shopping List</span>
<span id="badge-count" class="hidden absolute -top-1 -right-3 bg-red-600 text-white text-[10px] font-bold px-1.5 py-0.5 rounded-full">0</span>
</button>
</nav>
</div>
</div>
</header>
<!-- Main Content -->
<main class="flex-grow max-w-7xl w-full mx-auto px-4 sm:px-6 lg:px-8 py-6">
<section id="view-recipes" class="space-y-6">
<div class="flex flex-col md:flex-row justify-between items-start md:items-center gap-4 bg-white p-6 rounded-2xl border border-slate-200 shadow-sm">
<div>
<h1 class="text-2xl font-bold text-slate-900">Phil’s Recipe Library</h1>
<p class="text-slate-500 text-sm mt-1">Search BBC Good Food live or filter through your saved meal catalog.</p>
</div>
<div class="flex flex-wrap items-center gap-3 w-full md:w-auto">
<div class="relative flex-grow md:w-80">
<input type="text" id="recipe-search" onkeydown="if(event.key==='Enter') executeSearch()" placeholder="Search BBC Good Food (press Enter)..." class="w-full pl-9 pr-20 py-2 border border-slate-300 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-red-500">
<i class="fa-solid fa-magnifying-glass absolute left-3 top-2.5 text-slate-400 text-sm"></i>
<button onclick="executeSearch()" class="absolute right-1.5 top-1.5 bg-red-600 hover:bg-red-700 text-white text-xs px-3 py-1 rounded-lg transition font-medium">Search</button>
</div>
<button onclick="openImportModal()" class="bg-slate-900 hover:bg-slate-800 text-white text-sm px-4 py-2 rounded-xl transition flex items-center space-x-2">
<i class="fa-solid fa-plus"></i><span>Import Custom</span>
</button>
</div>
</div>
<div class="flex items-center space-x-2 overflow-x-auto pb-2 custom-scrollbar">
<button onclick="filterCategory('All')" class="cat-btn bg-red-600 text-white px-4 py-1.5 rounded-full text-sm font-medium transition shadow-sm">All</button>
<button onclick="filterCategory('Breakfast')" class="cat-btn bg-white hover:bg-slate-100 text-slate-700 border border-slate-200 px-4 py-1.5 rounded-full text-sm font-medium transition">Breakfast</button>
<button onclick="filterCategory('Lunch')" class="cat-btn bg-white hover:bg-slate-100 text-slate-700 border border-slate-200 px-4 py-1.5 rounded-full text-sm font-medium transition">Lunch</button>
<button onclick="filterCategory('Dinner')" class="cat-btn bg-white hover:bg-slate-100 text-slate-700 border border-slate-200 px-4 py-1.5 rounded-full text-sm font-medium transition">Dinner</button>
<button onclick="filterCategory('Snack')" class="cat-btn bg-white hover:bg-slate-100 text-slate-700 border border-slate-200 px-4 py-1.5 rounded-full text-sm font-medium transition">Snacks & Extras</button>
</div>
<div id="recipe-grid" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"></div>
</section>
<!-- PLANNER TAB -->
<section id="view-planner" class="hidden space-y-6">
<div class="flex justify-between items-center bg-white p-6 rounded-2xl border border-slate-200 shadow-sm">
<div>
<h1 class="text-2xl font-bold text-slate-900">7-Day UK Meal Planner</h1>
<p class="text-slate-500 text-sm mt-1">Plan your week to auto-generate an exact UK metric grocery list.</p>
</div>
<button onclick="clearWeeklyPlan()" class="text-sm text-red-600 hover:text-red-700 font-medium border border-red-200 hover:bg-red-50 px-4 py-2 rounded-xl transition flex items-center space-x-2">
<i class="fa-solid fa-trash-can"></i><span>Clear Plan</span>
</button>
</div>
<div class="grid grid-cols-1 lg:grid-cols-7 gap-4" id="planner-grid"></div>
</section>
<!-- SHOPPING TAB -->
<section id="view-shopping" class="hidden space-y-6">
<div class="flex justify-between items-center bg-white p-6 rounded-2xl border border-slate-200 shadow-sm">
<div>
<h1 class="text-2xl font-bold text-slate-900">Weekly UK Shopping List</h1>
<p class="text-slate-500 text-sm mt-1">Consolidated ingredients in grams, ml, and standard UK measures.</p>
</div>
<div class="flex space-x-3">
<button onclick="window.print()" class="bg-white border border-slate-300 hover:bg-slate-50 text-slate-700 text-sm px-4 py-2 rounded-xl transition flex items-center space-x-2">
<i class="fa-solid fa-print"></i><span>Print</span>
</button>
<button onclick="copyShoppingList()" class="bg-red-600 hover:bg-red-700 text-white text-sm px-4 py-2 rounded-xl transition flex items-center space-x-2 shadow-sm">
<i class="fa-solid fa-copy"></i><span>Copy to Clipboard</span>
</button>
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
<div class="md:col-span-2 bg-white rounded-2xl border border-slate-200 p-6 shadow-sm">
<h2 class="font-bold text-lg mb-4 text-slate-900 flex items-center justify-between">
<span>Ingredients to Buy</span>
<span id="items-left-count" class="text-xs bg-slate-100 text-slate-600 px-2.5 py-1 rounded-full font-semibold">0 items</span>
</h2>
<div id="shopping-list-container" class="space-y-2"></div>
</div>
<div>
<div class="bg-amber-50 border border-amber-200 rounded-2xl p-5 text-amber-900">
<h3 class="font-bold text-sm mb-1 flex items-center space-x-2">
<i class="fa-solid fa-lightbulb text-amber-600"></i>
<span>UK Standard Units</span>
</h3>
<p class="text-xs text-amber-800 leading-relaxed">Ingredients parsed directly from recipes are formatted in metric UK units (grams, ml, etc.).</p>
</div>
</div>
</div>
</section>
</main>
<!-- MODALS -->
<div id="modal-recipe" class="fixed inset-0 bg-slate-900/60 backdrop-blur-sm z-50 hidden flex items-center justify-center p-4">
<div class="bg-white rounded-3xl max-w-2xl w-full max-h-[90vh] flex flex-col shadow-2xl overflow-hidden">
<div class="relative h-48 bg-slate-200">
<img id="modal-img" src="" class="w-full h-full object-cover">
<button onclick="closeModal('modal-recipe')" class="absolute top-4 right-4 bg-white/80 hover:bg-white text-slate-700 rounded-full w-9 h-9 flex items-center justify-center shadow-md">
<i class="fa-solid fa-xmark text-lg"></i>
</button>
<span id="modal-badge" class="absolute bottom-4 left-4 bg-red-600 text-white text-xs font-bold px-3 py-1 rounded-full uppercase tracking-wider"></span>
</div>
<div class="p-6 overflow-y-auto custom-scrollbar space-y-6 flex-grow">
<div>
<h2 id="modal-title" class="text-2xl font-bold text-slate-900"></h2>
<div class="flex items-center space-x-4 text-xs font-semibold text-slate-500 mt-2">
<span><i class="fa-regular fa-clock mr-1"></i><span id="modal-prep"></span></span>
<span><i class="fa-solid fa-fire mr-1"></i><span id="modal-servings"></span></span>
</div>
</div>
<div>
<h3 class="font-bold text-sm text-slate-900 uppercase tracking-wider mb-3">Ingredients (UK Measures)</h3>
<ul id="modal-ingredients" class="grid grid-cols-1 md:grid-cols-2 gap-2 text-sm text-slate-700 bg-slate-50 p-4 rounded-xl border border-slate-100"></ul>
</div>
<div>
<h3 class="font-bold text-sm text-slate-900 uppercase tracking-wider mb-3">Method</h3>
<ol id="modal-method" class="space-y-3 text-sm text-slate-700"></ol>
</div>
</div>
<div class="p-4 bg-slate-50 border-t border-slate-200 flex justify-between items-center">
<span class="text-xs text-slate-500">Phil’s Food Verified</span>
<button id="modal-add-btn" class="bg-red-600 hover:bg-red-700 text-white text-sm font-semibold px-5 py-2.5 rounded-xl transition flex items-center space-x-2">
<i class="fa-solid fa-calendar-plus"></i><span>Add to Planner</span>
</button>
</div>
</div>
</div>
<div id="modal-import" class="fixed inset-0 bg-slate-900/60 backdrop-blur-sm z-50 hidden flex items-center justify-center p-4">
<div class="bg-white rounded-3xl max-w-lg w-full p-6 shadow-2xl space-y-4">
<div class="flex justify-between items-center border-b pb-3">
<h3 class="font-bold text-lg text-slate-900">Import Custom Recipe</h3>
<button onclick="closeModal('modal-import')" class="text-slate-400 hover:text-slate-600"><i class="fa-solid fa-xmark text-lg"></i></button>
</div>
<div class="space-y-3">
<div>
<label class="text-xs font-bold text-slate-700">Recipe Name</label>
<input type="text" id="import-title" placeholder="e.g. Shepherd's Pie" class="w-full border rounded-xl p-2 text-sm mt-1 focus:ring-2 focus:ring-red-500 focus:outline-none">
</div>
<div class="grid grid-cols-2 gap-3">
<div>
<label class="text-xs font-bold text-slate-700">Meal Type</label>
<select id="import-category" class="w-full border rounded-xl p-2 text-sm mt-1 focus:ring-2 focus:ring-red-500">
<option value="Breakfast">Breakfast</option>
<option value="Lunch">Lunch</option>
<option value="Dinner" selected>Dinner</option>
<option value="Snack">Snack</option>
</select>
</div>
<div>
<label class="text-xs font-bold text-slate-700">Prep Time</label>
<input type="text" id="import-time" placeholder="45 mins" class="w-full border rounded-xl p-2 text-sm mt-1">
</div>
</div>
<div>
<label class="text-xs font-bold text-slate-700">Ingredients (One per line)</label>
<textarea id="import-ingredients" rows="3" placeholder="500g minced lamb 2 tbsp olive oil" class="w-full border rounded-xl p-2 text-sm mt-1 focus:ring-2 focus:ring-red-500"></textarea>
</div>
<div>
<label class="text-xs font-bold text-slate-700">Method (One step per line)</label>
<textarea id="import-method" rows="3" placeholder="Brown the mince. Bake for 30 mins." class="w-full border rounded-xl p-2 text-sm mt-1 focus:ring-2 focus:ring-red-500"></textarea>
</div>
</div>
<div class="flex justify-end space-x-3 pt-2">
<button onclick="closeModal('modal-import')" class="px-4 py-2 border rounded-xl text-sm font-medium text-slate-600">Cancel</button>
<button onclick="saveImportedRecipe()" class="px-4 py-2 bg-red-600 hover:bg-red-700 text-white rounded-xl text-sm font-semibold">Save Recipe</button>
</div>
</div>
</div>
<div id="modal-select-day" class="fixed inset-0 bg-slate-900/60 backdrop-blur-sm z-50 hidden flex items-center justify-center p-4">
<div class="bg-white rounded-3xl max-w-sm w-full p-6 shadow-2xl space-y-4 text-center">
<h3 class="font-bold text-lg text-slate-900">Add to Weekly Plan</h3>
<div id="day-selector-buttons" class="grid grid-cols-1 gap-2 pt-2"></div>
<button onclick="closeModal('modal-select-day')" class="w-full py-2 text-slate-500 text-sm font-medium">Cancel</button>
</div>
</div>
<script>
// Live Cloudflare Worker URL
const WORKER_URL = "https://bbc-search-api.ian-henry09.workers.dev";
const initialRecipes = [
{
id: '1',
title: 'Classic Chicken Tikka Masala',
category: 'Dinner',
prepTime: '45 mins',
servings: 4,
image: 'https://images.unsplash.com/photo-1565557623262-b51c2513a641?auto=format&fit=crop&w=600&q=80',
ingredients: ['600g chicken breasts', '150g natural yogurt', '2 tbsp vegetable oil', '1 large onion', '400g can chopped tomatoes', '150ml double cream'],
method: ['Marinate chicken in yogurt.', 'Fry onions, add tomatoes and chicken.', 'Stir through double cream before serving.']
}
];
const DAYS = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
let recipes = JSON.parse(localStorage.getItem('phils_food_recipes')) || initialRecipes;
let planner = JSON.parse(localStorage.getItem('phils_food_planner')) || { Monday: [], Tuesday: [], Wednesday: [], Thursday: [], Friday: [], Saturday: [], Sunday: [] };
let currentCategory = 'All';
let selectedRecipeForPlan = null;
window.addEventListener('DOMContentLoaded', () => { renderRecipes(); renderPlanner(); updateBadge(); });
function saveState() {
localStorage.setItem('phils_food_recipes', JSON.stringify(recipes));
localStorage.setItem('phils_food_planner', JSON.stringify(planner));
updateBadge();
}
async function executeSearch() {
const q = document.getElementById('recipe-search').value.trim();
if (!q) return renderRecipes();
const grid = document.getElementById('recipe-grid');
grid.innerHTML = '<div class="col-span-full text-center py-12 text-slate-500"><i class="fa-solid fa-spinner fa-spin text-red-600 text-2xl mb-3 block"></i>Searching BBC Good Food inventory...</div>';
try {
const response = await fetch(`${WORKER_URL}?q=${encodeURIComponent(q)}`);
const remoteRecipes = await response.json();
if (Array.isArray(remoteRecipes) && remoteRecipes.length > 0) {
remoteRecipes.forEach(r => {
if (!recipes.some(existing => existing.id === r.id)) {
recipes.unshift(r);
}
});
saveState();
}
} catch (e) {
console.error("Live search failed:", e);
}
renderRecipes();
}
function switchTab(tabName) {
['recipes', 'planner', 'shopping'].forEach(tab => {
document.getElementById(`view-${tab}`).classList.add('hidden');
document.getElementById(`tab-btn-${tab}`).classList.remove('tab-active');
});
document.getElementById(`view-${tabName}`).classList.remove('hidden');
document.getElementById(`tab-btn-${tabName}`).classList.add('tab-active');
if (tabName === 'planner') renderPlanner();
if (tabName === 'shopping') generateShoppingList();
}
function filterCategory(cat) {
currentCategory = cat;
document.querySelectorAll('.cat-btn').forEach(btn => {
btn.className = btn.innerText.includes(cat) ? "cat-btn bg-red-600 text-white px-4 py-1.5 rounded-full text-sm font-medium transition shadow-sm" : "cat-btn bg-white text-slate-700 border border-slate-200 px-4 py-1.5 rounded-full text-sm font-medium transition";
});
renderRecipes();
}
function renderRecipes() {
const query = document.getElementById('recipe-search').value.toLowerCase();
const grid = document.getElementById('recipe-grid');
grid.innerHTML = '';
const filtered = recipes.filter(r => {
const matchesCat = currentCategory === 'All' || r.category === currentCategory;
const matchesSearch = r.title.toLowerCase().includes(query) || r.ingredients.some(i => i.toLowerCase().includes(query));
return matchesCat && matchesSearch;
});
if (filtered.length === 0) {
grid.innerHTML = `<div class="col-span-full text-center py-12 text-slate-400">No matching recipes found. Press 'Search' to query BBC Good Food live!</div>`;
return;
}
filtered.forEach(r => {
const card = document.createElement('div');
card.className = "bg-white rounded-2xl border border-slate-200 overflow-hidden shadow-sm hover:shadow-md transition flex flex-col";
card.innerHTML = `
<div class="relative h-44 overflow-hidden bg-slate-100">
<img src="${r.image}" class="w-full h-full object-cover">
<span class="absolute top-3 right-3 bg-white/95 backdrop-blur-md text-slate-800 text-xs font-bold px-2.5 py-1 rounded-full shadow-sm">${r.category}</span>
</div>
<div class="p-5 flex-grow flex flex-col justify-between space-y-4">
<div>
<h3 class="font-bold text-slate-900 text-lg leading-snug">${r.title}</h3>
<div class="flex items-center space-x-3 text-xs text-slate-500 font-medium mt-2">
<span><i class="fa-regular fa-clock mr-1"></i>${r.prepTime}</span>
<span><i class="fa-solid fa-user-group mr-1"></i>${r.servings} Servings</span>
</div>
</div>
<div class="flex space-x-2 pt-2 border-t border-slate-100">
<button onclick="openRecipeDetail('${r.id}')" class="flex-1 bg-slate-100 hover:bg-slate-200 text-slate-700 text-xs font-semibold py-2 rounded-xl">View Method</button>
<button onclick="promptAddToPlan('${r.id}')" class="bg-red-600 hover:bg-red-700 text-white text-xs font-semibold px-3 py-2 rounded-xl flex items-center space-x-1">
<i class="fa-solid fa-plus"></i><span>Plan</span>
</button>
</div>
</div>
`;
grid.appendChild(card);
});
}
function openRecipeDetail(id) {
const r = recipes.find(x => x.id === id);
if (!r) return;
document.getElementById('modal-img').src = r.image;
document.getElementById('modal-title').innerText = r.title;
document.getElementById('modal-badge').innerText = r.category;
document.getElementById('modal-prep').innerText = r.prepTime;
document.getElementById('modal-servings').innerText = `${r.servings} Servings`;
document.getElementById('modal-ingredients').innerHTML = r.ingredients.map(i => `<li><i class="fa-solid fa-angle-right text-red-500 mr-1.5"></i>${i}</li>`).join('');
document.getElementById('modal-method').innerHTML = r.method.map((m, idx) => `<li class="flex items-start space-x-3"><span class="bg-red-100 text-red-700 text-xs font-bold rounded-full w-6 h-6 flex items-center justify-center flex-shrink-0 mt-0.5">${idx + 1}</span><span>${m}</span></li>`).join('');
document.getElementById('modal-add-btn').onclick = () => { closeModal('modal-recipe'); promptAddToPlan(r.id); };
document.getElementById('modal-recipe').classList.remove('hidden');
}
function closeModal(id) { document.getElementById(id).classList.add('hidden'); }
function openImportModal() { document.getElementById('modal-import').classList.remove('hidden'); }
function saveImportedRecipe() {
const title = document.getElementById('import-title').value.trim();
if (!title) return alert('Recipe title required');
recipes.unshift({
id: Date.now().toString(),
title,
category: document.getElementById('import-category').value,
prepTime: document.getElementById('import-time').value.trim() || '30 mins',
servings: 4,
image: 'https://images.unsplash.com/photo-1495521821757-a1efb6729352?auto=format&fit=crop&w=600&q=80',
ingredients: document.getElementById('import-ingredients').value.split('\n').filter(i => i.trim()),
method: document.getElementById('import-method').value.split('\n').filter(m => m.trim())
});
saveState(); renderRecipes(); closeModal('modal-import');
}
function promptAddToPlan(recipeId) {
selectedRecipeForPlan = recipes.find(r => r.id === recipeId);
const container = document.getElementById('day-selector-buttons');
container.innerHTML = '';
DAYS.forEach(day => {
const btn = document.createElement('button');
btn.className = "w-full text-left bg-slate-50 hover:bg-red-50 text-slate-700 text-sm font-semibold p-3 rounded-xl border border-slate-200 flex justify-between items-center";
btn.innerHTML = `<span>${day}</span><i class="fa-solid fa-chevron-right text-xs"></i>`;
btn.onclick = () => { planner[day].push(selectedRecipeForPlan); saveState(); closeModal('modal-select-day'); switchTab('planner'); };
container.appendChild(btn);
});
document.getElementById('modal-select-day').classList.remove('hidden');
}
function renderPlanner() {
const container = document.getElementById('planner-grid');
container.innerHTML = '';
DAYS.forEach(day => {
const dayCard = document.createElement('div');
dayCard.className = "bg-white border border-slate-200 rounded-2xl p-4 shadow-sm flex flex-col justify-between min-h-[220px]";
const dayMeals = planner[day] || [];
const mealsHTML = dayMeals.map((m, idx) => `
<div class="bg-slate-50 p-2.5 rounded-xl border border-slate-100 flex justify-between items-center">
<div class="truncate pr-2">
<span class="text-[10px] font-bold text-red-600 block uppercase">${m.category}</span>
<span class="text-xs font-semibold text-slate-800 truncate block">${m.title}</span>
</div>
<button onclick="removeMealFromPlan('${day}', ${idx})" class="text-slate-300 hover:text-red-600"><i class="fa-solid fa-xmark text-sm"></i></button>
</div>
`).join('');
dayCard.innerHTML = `
<div>
<div class="flex justify-between items-center border-b pb-2 mb-3">
<h3 class="font-bold text-slate-900 text-sm">${day}</h3>
<span class="text-[10px] font-bold bg-slate-100 text-slate-600 px-2 py-0.5 rounded-full">${dayMeals.length}</span>
</div>
<div class="space-y-2">${mealsHTML || '<p class="text-xs text-slate-400 italic py-4 text-center">No meals planned</p>'}</div>
</div>
<button onclick="switchTab('recipes')" class="mt-4 w-full py-1.5 border border-dashed border-slate-300 hover:border-red-400 text-slate-500 rounded-xl text-xs font-medium flex items-center justify-center space-x-1">
<i class="fa-solid fa-plus text-[10px]"></i><span>Add Meal</span>
</button>
`;
container.appendChild(dayCard);
});
}
function removeMealFromPlan(day, idx) { planner[day].splice(idx, 1); saveState(); renderPlanner(); }
function clearWeeklyPlan() { if (confirm('Clear plan?')) { planner = { Monday: [], Tuesday: [], Wednesday: [], Thursday: [], Friday: [], Saturday: [], Sunday: [] }; saveState(); renderPlanner(); } }
function generateShoppingList() {
const container = document.getElementById('shopping-list-container');
container.innerHTML = '';
const allIngredients = Object.values(planner).flat().flatMap(r => r ? r.ingredients : []);
if (!allIngredients.length) { container.innerHTML = '<div class="text-center py-12 text-slate-400">Your shopping list is empty.</div>'; return; }
document.getElementById('items-left-count').innerText = `${allIngredients.length} items`;
allIngredients.forEach(ing => {
const item = document.createElement('label');
item.className = "flex items-center space-x-3 p-3 rounded-xl border border-slate-100 hover:bg-slate-50 cursor-pointer";
item.innerHTML = `<input type="checkbox" onchange="this.nextElementSibling.classList.toggle('line-through'); this.nextElementSibling.classList.toggle('text-slate-400')" class="rounded text-red-600 focus:ring-red-500 w-4 h-4"><span class="text-sm text-slate-700">${ing}</span>`;
container.appendChild(item);
});
}
function updateBadge() {
const count = Object.values(planner).flat().length;
const b = document.getElementById('badge-count');
b.innerText = count;
b.classList.toggle('hidden', count === 0);
}
function copyShoppingList() {
const items = Object.values(planner).flat().flatMap(r => r ? r.ingredients : []);
if (!items.length) return alert('No items to copy!');
navigator.clipboard.writeText("Phil’s Food Shopping List:\n\n" + items.map(i => `- ${i}`).join('\n'));
alert('Shopping list copied!');
}
</script>
</body>
</html>