anycoder-791b779d / index.html
Jensin's picture
Upload folder using huggingface_hub
87c5400 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Family Cookbook - Built with anycoder</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
:root {
--primary-color: #e74c3c;
--secondary-color: #f39c12;
--accent-color: #2ecc71;
--dark-color: #2c3e50;
--light-color: #ecf0f1;
--shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
--transition: all 0.3s ease;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
line-height: 1.6;
color: var(--dark-color);
background-color: #f9f9f9;
padding: 0;
margin: 0;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}
header {
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
color: white;
padding: 20px 0;
box-shadow: var(--shadow);
position: sticky;
top: 0;
z-index: 100;
}
.header-content {
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
gap: 20px;
}
.logo {
display: flex;
align-items: center;
gap: 10px;
text-decoration: none;
color: white;
}
.logo i {
font-size: 2rem;
}
.logo h1 {
font-size: 1.8rem;
font-weight: 700;
}
.anycoder-link {
color: white;
text-decoration: none;
font-size: 0.9rem;
opacity: 0.8;
transition: var(--transition);
}
.anycoder-link:hover {
opacity: 1;
text-decoration: underline;
}
nav ul {
display: flex;
list-style: none;
gap: 20px;
}
nav a {
color: white;
text-decoration: none;
font-weight: 500;
padding: 5px 10px;
border-radius: 4px;
transition: var(--transition);
}
nav a:hover, nav a.active {
background-color: rgba(255, 255, 255, 0.2);
}
.hero {
background: linear-gradient(rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)), url('https://images.unsplash.com/photo-1556909114-f6e7ad7d3136?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2070&q=80');
background-size: cover;
background-position: center;
color: white;
text-align: center;
padding: 100px 20px;
margin-bottom: 40px;
}
.hero h2 {
font-size: 3rem;
margin-bottom: 20px;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
}
.hero p {
font-size: 1.2rem;
max-width: 800px;
margin: 0 auto 30px;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5);
}
.btn {
display: inline-block;
background-color: var(--accent-color);
color: white;
padding: 12px 25px;
border: none;
border-radius: 50px;
font-weight: 600;
text-decoration: none;
transition: var(--transition);
cursor: pointer;
}
.btn:hover {
background-color: #27ae60;
transform: translateY(-2px);
}
.recipe-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 30px;
margin-bottom: 50px;
}
.recipe-card {
background-color: white;
border-radius: 10px;
overflow: hidden;
box-shadow: var(--shadow);
transition: var(--transition);
display: flex;
flex-direction: column;
}
.recipe-card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
}
.recipe-img {
height: 200px;
background-size: cover;
background-position: center;
position: relative;
}
.recipe-badge {
position: absolute;
top: 10px;
right: 10px;
background-color: var(--primary-color);
color: white;
padding: 5px 10px;
border-radius: 20px;
font-size: 0.8rem;
font-weight: 600;
}
.recipe-content {
padding: 20px;
flex-grow: 1;
}
.recipe-title {
font-size: 1.5rem;
margin-bottom: 10px;
color: var(--dark-color);
}
.recipe-meta {
display: flex;
gap: 15px;
margin-bottom: 15px;
font-size: 0.9rem;
color: #7f8c8d;
}
.recipe-meta i {
margin-right: 5px;
}
.recipe-description {
color: #7f8c8d;
margin-bottom: 15px;
font-size: 0.95rem;
}
.recipe-actions {
display: flex;
justify-content: space-between;
margin-top: auto;
}
.btn-outline {
background-color: transparent;
color: var(--primary-color);
border: 1px solid var(--primary-color);
}
.btn-outline:hover {
background-color: var(--primary-color);
color: white;
}
.search-container {
margin-bottom: 40px;
display: flex;
gap: 10px;
flex-wrap: wrap;
}
.search-box {
flex-grow: 1;
min-width: 250px;
position: relative;
}
.search-box input {
width: 100%;
padding: 12px 20px 12px 45px;
border: 1px solid #ddd;
border-radius: 50px;
font-size: 1rem;
outline: none;
transition: var(--transition);
}
.search-box input:focus {
border-color: var(--accent-color);
box-shadow: 0 0 0 3px rgba(46, 204, 113, 0.2);
}
.search-box i {
position: absolute;
left: 15px;
top: 50%;
transform: translateY(-50%);
color: #7f8c8d;
}
.filter-btn {
padding: 12px 20px;
border: 1px solid #ddd;
border-radius: 50px;
background-color: white;
cursor: pointer;
transition: var(--transition);
}
.filter-btn:hover {
border-color: var(--primary-color);
color: var(--primary-color);
}
.filter-btn.active {
background-color: var(--primary-color);
color: white;
border-color: var(--primary-color);
}
.recipe-detail {
background-color: white;
border-radius: 10px;
box-shadow: var(--shadow);
padding: 40px;
margin-bottom: 50px;
}
.recipe-detail-header {
display: flex;
gap: 30px;
margin-bottom: 30px;
flex-wrap: wrap;
}
.recipe-detail-img {
flex: 1;
min-width: 300px;
height: 300px;
background-size: cover;
background-position: center;
border-radius: 10px;
}
.recipe-detail-info {
flex: 1;
min-width: 300px;
}
.recipe-detail-title {
font-size: 2.5rem;
margin-bottom: 15px;
color: var(--dark-color);
}
.recipe-detail-story {
font-style: italic;
margin-bottom: 20px;
color: #7f8c8d;
font-size: 1.1rem;
}
.recipe-detail-meta {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
gap: 15px;
margin-bottom: 20px;
}
.meta-item {
display: flex;
align-items: center;
gap: 10px;
}
.meta-item i {
color: var(--primary-color);
font-size: 1.2rem;
}
.recipe-detail-actions {
display: flex;
gap: 10px;
margin-bottom: 20px;
}
.ingredients-section, .instructions-section {
margin-bottom: 40px;
}
.section-title {
font-size: 1.8rem;
margin-bottom: 20px;
color: var(--dark-color);
border-bottom: 2px solid var(--light-color);
padding-bottom: 10px;
}
.ingredients-list {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 20px;
}
.ingredient-item {
display: flex;
margin-bottom: 10px;
}
.ingredient-item input[type="checkbox"] {
margin-right: 10px;
transform: scale(1.2);
}
.ingredient-name {
font-weight: 600;
flex-grow: 1;
}
.ingredient-amount {
color: var(--primary-color);
margin-left: 10px;
}
.ingredient-substitution {
font-size: 0.9rem;
color: #7f8c8d;
margin-top: 5px;
padding-left: 25px;
}
.instructions-list {
list-style: none;
counter-reset: step-counter;
}
.instruction-item {
counter-increment: step-counter;
margin-bottom: 20px;
padding-left: 40px;
position: relative;
}
.instruction-item::before {
content: counter(step-counter);
background-color: var(--primary-color);
color: white;
width: 30px;
height: 30px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
position: absolute;
left: 0;
font-weight: 600;
}
.instruction-text {
font-size: 1.05rem;
margin-bottom: 5px;
}
.instruction-tip {
font-size: 0.9rem;
color: var(--accent-color);
margin-top: 5px;
padding-left: 10px;
border-left: 3px solid var(--accent-color);
}
.image-gallery {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
margin-top: 30px;
}
.gallery-item {
background-size: cover;
background-position: center;
height: 200px;
border-radius: 10px;
position: relative;
overflow: hidden;
}
.gallery-item::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
right: 0;
background: linear-gradient(transparent, rgba(0, 0, 0, 0.7));
padding: 20px;
color: white;
font-size: 0.9rem;
}
.back-btn {
display: inline-flex;
align-items: center;
gap: 5px;
margin-bottom: 20px;
color: var(--primary-color);
text-decoration: none;
font-weight: 500;
}
.back-btn:hover {
text-decoration: underline;
}
.add-recipe-btn {
position: fixed;
bottom: 30px;
right: 30px;
width: 60px;
height: 60px;
border-radius: 50%;
background-color: var(--primary-color);
color: white;
border: none;
font-size: 1.5rem;
cursor: pointer;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
transition: var(--transition);
z-index: 100;
}
.add-recipe-btn:hover {
background-color: #c0392b;
transform: scale(1.05);
}
.modal {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
z-index: 200;
overflow-y: auto;
}
.modal-content {
background-color: white;
margin: 50px auto;
padding: 30px;
border-radius: 10px;
max-width: 800px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
}
.modal-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
padding-bottom: 10px;
border-bottom: 1px solid var(--light-color);
}
.modal-title {
font-size: 1.8rem;
color: var(--dark-color);
}
.close-btn {
background: none;
border: none;
font-size: 1.5rem;
cursor: pointer;
color: #7f8c8d;
transition: var(--transition);
}
.close-btn:hover {
color: var(--primary-color);
}
.form-group {
margin-bottom: 20px;
}
.form-group label {
display: block;
margin-bottom: 5px;
font-weight: 600;
color: var(--dark-color);
}
.form-control {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 5px;
font-size: 1rem;
outline: none;
transition: var(--transition);
}
.form-control:focus {
border-color: var(--accent-color);
box-shadow: 0 0 0 3px rgba(46, 204, 113, 0.2);
}
.textarea-control {
min-height: 100px;
resize: vertical;
}
.ingredient-input {
display: flex;
gap: 10px;
margin-bottom: 10px;
}
.ingredient-input input {
flex-grow: 1;
}
.add-ingredient-btn {
background-color: var(--accent-color);
color: white;
border: none;
padding: 5px 10px;
border-radius: 5px;
cursor: pointer;
transition: var(--transition);
}
.add-ingredient-btn:hover {
background-color: #27ae60;
}
.remove-ingredient-btn {
background-color: var(--primary-color);
color: white;
border: none;
padding: 5px 10px;
border-radius: 5px;
cursor: pointer;
transition: var(--transition);
}
.remove-ingredient-btn:hover {
background-color: #c0392b;
}
.step-input {
display: flex;
gap: 10px;
margin-bottom: 10px;
}
.step-input input, .step-input textarea {
flex-grow: 1;
}
.add-step-btn {
background-color: var(--accent-color);
color: white;
border: none;
padding: 5px 10px;
border-radius: 5px;
cursor: pointer;
transition: var(--transition);
}
.add-step-btn:hover {
background-color: #27ae60;
}
.remove-step-btn {
background-color: var(--primary-color);
color: white;
border: none;
padding: 5px 10px;
border-radius: 5px;
cursor: pointer;
transition: var(--transition);
}
.remove-step-btn:hover {
background-color: #c0392b;
}
.modal-footer {
display: flex;
justify-content: flex-end;
gap: 10px;
margin-top: 20px;
padding-top: 20px;
border-top: 1px solid var(--light-color);
}
.print-btn {
background-color: var(--secondary-color);
color: white;
}
.print-btn:hover {
background-color: #e67e22;
}
@media (max-width: 768px) {
.hero h2 {
font-size: 2.5rem;
}
.hero p {
font-size: 1rem;
}
.recipe-detail-header {
flex-direction: column;
}
.recipe-detail-img {
height: 250px;
}
.recipe-detail {
padding: 20px;
}
.modal-content {
margin: 20px;
padding: 20px;
}
.search-container {
flex-direction: column;
}
.search-box {
min-width: 100%;
}
}
@media (max-width: 480px) {
.header-content {
flex-direction: column;
text-align: center;
}
.hero h2 {
font-size: 2rem;
}
.recipe-grid {
grid-template-columns: 1fr;
}
.ingredients-list {
grid-template-columns: 1fr;
}
.image-gallery {
grid-template-columns: 1fr;
}
}
</style>
</head>
<body>
<header>
<div class="container header-content">
<a href="#" class="logo">
<i class="fas fa-book-open"></i>
<h1>Family Cookbook</h1>
</a>
<a href="https://huggingface.co/spaces/akhaliq/anycoder" class="anycoder-link" target="_blank">Built with anycoder</a>
<nav>
<ul>
<li><a href="#" class="active">Home</a></li>
<li><a href="#">Categories</a></li>
<li><a href="#">Favorites</a></li>
<li><a href="#">About</a></li>
</ul>
</nav>
</div>
</header>
<section class="hero">
<div class="container">
<h2>Preserve Your Family's Culinary Legacy</h2>
<p>Create beautiful, professional recipe pages from your family's cherished recipes. Whether they're handwritten notes, verbal descriptions, or treasured memories, we'll help you format them into a stunning cookbook to pass down through generations.</p>
<a href="#" class="btn" id="addRecipeBtn">Add New Recipe</a>
</div>
</section>
<div class="container">
<div class="search-container">
<div class="search-box">
<i class="fas fa-search"></i>
<input type="text" placeholder="Search recipes..." id="searchInput">
</div>
<button class="filter-btn" data-filter="all">All Recipes</button>
<button class="filter-btn" data-filter="breakfast">Breakfast</button>
<button class="filter-btn" data-filter="lunch">Lunch</button>
<button class="filter-btn" data-filter="dinner">Dinner</button>
<button class="filter-btn" data-filter="dessert">Dessert</button>
</div>
<div class="recipe-grid" id="recipeGrid">
<!-- Recipe cards will be dynamically inserted here -->
</div>
</div>
<div class="container">
<div class="recipe-detail" id="recipeDetail" style="display: none;">
<a href="#" class="back-btn" id="backToGrid">
<i class="fas fa-arrow-left"></i> Back to Recipes
</a>
<div class="recipe-detail-header">
<div class="recipe-detail-img" id="detailImage"></div>
<div class="recipe-detail-info">
<h1 class="recipe-detail-title" id="detailTitle"></h1>
<p class="recipe-detail-story" id="detailStory"></p>
<div class="recipe-detail-meta">
<div class="meta-item">
<i class="fas fa-clock"></i>
<span id="detailPrepTime">Prep: 20 mins</span>
</div>
<div class="meta-item">
<i class="fas fa-utensils"></i>
<span id="detailCookTime">Cook: 30 mins</span>
</div>
<div class="meta-item">
<i class="fas fa-users"></i>
<span id="detailServings">Serves: 4</span>
</div>
<div class="meta-item">
<i class="fas fa-tag"></i>
<span id="detailCategory">Dinner</span>
</div>
</div>
<div class="recipe-detail-actions">
<button class="btn btn-outline" id="editRecipeBtn">
<i class="fas fa-edit"></i> Edit Recipe
</button>
<button class="btn" id="printRecipeBtn">
<i class="fas fa-print"></i> Print Recipe
</button>
</div>
</div>
</div>
<div class="ingredients-section">
<h2 class="section-title">Ingredients</h2>
<div class="ingredients-list" id="detailIngredients">
<!-- Ingredients will be dynamically inserted here -->
</div>
</div>
<div class="instructions-section">
<h2 class="section-title">Instructions</h2>
<ol class="instructions-list" id="detailInstructions">
<!-- Instructions will be dynamically inserted here -->
</ol>
</div>
<div class="image-gallery">
<div class="gallery-item" style="background-image: url('https://images.unsplash.com/photo-1556909114-f6e7ad7d3136?ixlib=rb-4.0.3&auto=format&fit=crop&w=500&q=80');">
<div class="gallery-caption">Final plated dish with fresh herbs garnish</div>
</div>
<div class="gallery-item" style="background-image: url('https://images.unsplash.com/photo-1556909114-f6e7ad7d3136?ixlib=rb-4.0.3&auto=format&fit=crop&w=500&q=80');">
<div class="gallery-caption">Sautéing onions and garlic in olive oil</div>
</div>
<div class="gallery-item" style="background-image: url('https://images.unsplash.com/photo-1556909114-f6e7ad7d3136?ixlib=rb-4.0.3&auto=format&fit=crop&w=500&q=80');">
<div class="gallery-caption">Fresh ingredients laid out before preparation</div>
</div>
</div>
</div>
</div>
<button class="add-recipe-btn" id="addRecipeBtnMobile">
<i class="fas fa-plus"></i>
</button>
<div class="modal" id="recipeModal">
<div class="modal-content">
<div class="modal-header">
<h2 class="modal-title" id="modalTitle">Add New Recipe</h2>
<button class="close-btn" id="closeModal">
<i class="fas fa-times"></i>
</button>
</div>
<form id="recipeForm">
<div class="form-group">
<label for="recipeTitle">Recipe Title</label>
<input type="text" class="form-control" id="recipeTitle" required>
</div>
<div class="form-group">
<label for="recipeStory">Recipe Story</label>
<textarea class="form-control textarea-control" id="recipeStory" placeholder="Brief background about the dish's family significance (2-3 sentences)"></textarea>
</div>
<div class="form-group">
<label for="recipeCategory">Category</label>
<select class="form-control" id="recipeCategory">
<option value="breakfast">Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="dessert">Dessert</option>
<option value="snack">Snack</option>
<option value="drink">Drink</option>
</select>
</div>
<div class="form-group">
<label for="recipePrepTime">Prep Time (minutes)</label>
<input type="number" class="form-control" id="recipePrepTime" min="1" value="20">
</div>
<div class="form-group">
<label for="recipeCookTime">Cook Time (minutes)</label>
<input type="number" class="form-control" id="recipeCookTime" min="1" value="30">
</div>
<div class="form-group">
<label for="recipeServings">Servings</label>
<input type="number" class="form-control" id="recipeServings" min="1" value="4">
</div>
<div class="form-group">
<label>Ingredients</label>
<div id="ingredientsContainer">
<!-- Ingredient inputs will be dynamically added here -->
</div>
<button type="button" class="add-ingredient-btn" id="addIngredientBtn">
<i class="fas fa-plus"></i> Add Ingredient
</button>
</div>
<div class="form-group">
<label>Instructions</label>
<div id="stepsContainer">
<!-- Step inputs will be dynamically added here -->
</div>
<button type="button" class="add-step-btn" id="addStepBtn">
<i class="fas fa-plus"></i> Add Step
</button>
</div>
<div class="form-group">
<label for="recipeImage">Image URL</label>
<input type="url" class="form-control" id="recipeImage" placeholder="https://example.com/image.jpg">
</div>
</form>
<div class="modal-footer">
<button type="button" class="btn btn-outline" id="cancelBtn">Cancel</button>
<button type="button" class="btn" id="saveRecipeBtn">Save Recipe</button>
</div>
</div>
</div>
<script>
// Sample recipe data
const recipes = [
{
id: 1,
title: "Grandma's Famous Lasagna",
story: "This lasagna recipe has been in our family for three generations. Grandma would make it every Sunday, and the smell of it baking would bring the whole family running to the kitchen.",
category: "dinner",
prepTime: 30,
cookTime: 90,
servings: 8,
image: "https://images.unsplash.com/photo-1556909114-f6e7ad7d3136?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80",
ingredients: [
{ name: "Lasagna noodles", amount: "12 sheets", substitution: "Can use gluten-free noodles" },
{ name: "Ground beef", amount: "1 lb (450g)", substitution: "Can substitute with ground turkey or Italian sausage" },
{ name: "Ricotta cheese", amount: "15 oz (425g)", substitution: "Cottage cheese can be used as a substitute" },
{ name: "Mozzarella cheese", amount: "8 oz (225g), shredded", substitution: "" },
{ name: "Parmesan cheese", amount: "1/2 cup, grated", substitution: "Pecorino Romano can be used" },
{ name: "Marinara sauce", amount: "24 oz (680g)", substitution: "Homemade or store-bought" },
{ name: "Onion", amount: "1 medium, diced", substitution: "" },
{ name: "Garlic", amount: "3 cloves, minced", substitution: "1 tsp garlic powder" },
{ name: "Fresh basil", amount: "1/4 cup, chopped", substitution: "1 tbsp dried basil" },
{ name: "Olive oil", amount: "2 tbsp", substitution: "" },
{ name: "Salt and pepper", amount: "to taste", substitution: "" }
],
instructions: [
{
text: "Preheat your oven to 375°F (190°C). Cook lasagna noodles according to package instructions until al dente. Drain and set aside.",
tip: "Add a tablespoon of olive oil to the boiling water to prevent noodles from sticking."
},
{
text: "In a large skillet, heat olive oil over medium heat. Add diced onion and cook until translucent, about 5 minutes. Add minced garlic and cook for another minute until fragrant.",
tip: "Don't let the garlic burn - it becomes bitter."
},
{
text: "Add ground beef to the skillet and cook until browned, breaking it up with a spoon. Drain excess fat if necessary. Stir in marinara sauce and simmer for 10 minutes.",
tip: "For extra flavor, add a pinch of red pepper flakes."
},
{
text: "In a bowl, mix ricotta cheese, half of the mozzarella, half of the Parmesan, and chopped basil. Season with salt and pepper.",
tip: "For a lighter version, you can use part-skim ricotta."
},
{
text: "In a 9x13-inch baking dish, spread a thin layer of meat sauce. Add a layer of lasagna noodles, slightly overlapping. Spread half of the ricotta mixture over the noodles, then top with more meat sauce. Repeat layers, ending with noodles and remaining meat sauce.",
tip: "Make sure each noodle is well coated with sauce to prevent drying out."
},
{
text: "Sprinkle the remaining mozzarella and Parmesan cheese on top. Cover with aluminum foil and bake for 25 minutes.",
tip: "The foil prevents the cheese from burning."
},
{
text: "Remove the foil and bake for another 20-25 minutes until the cheese is bubbly and golden. Let it rest for 10 minutes before serving.",
tip: "Resting allows the lasagna to set and makes it easier to serve."
}
],
images: [
{
url: "https://images.unsplash.com/photo-1556909114-f6e7ad7d3136?ixlib=rb-4.0.3&auto=format&fit=crop&w=500&q=80",
description: "Golden brown lasagna fresh from the oven"
},
{
url: "https://images.unsplash.com/photo-1556909114-f6e7ad7d3136?ixlib=rb-4.0.3&auto=format&fit=crop&w=500&q=80",
description: "Layering noodles and cheese in the baking dish"
},
{
url: "https://images.unsplash.com/photo-1556909114-f6e7ad7d3136?ixlib=rb-4.0.3&auto=format&fit=crop&w=500&q=80",
description: "All ingredients prepared and ready for assembly"
}
]
},
{
id: 2,
title: "Aunt Martha's Chocolate Chip Cookies",
story: "These cookies were a staple at every family gathering. Aunt Martha's secret was always using a bit more vanilla than the recipe called for, and chilling the dough overnight.",
category: "dessert",
prepTime: 20,
cookTime: 12,
servings: 24,
image: "https://images.unsplash.com/photo-1558961363-fa8fdf82db35?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80",
ingredients: [
{ name: "All-purpose flour", amount: "2 1/4 cups (280g)", substitution: "Gluten-free flour blend" },
{ name: "Baking soda", amount: "1 tsp", substitution: "" },
{ name: "Salt", amount: "1 tsp", substitution: "" },
{ name: "Unsalted butter", amount: "1 cup (225g), softened", substitution: "Margarine or coconut oil" },
{ name: "Granulated sugar", amount: "3/4 cup (150g)", substitution: "Coconut sugar" },
{ name: "Brown sugar", amount: "3/4 cup (165g), packed", substitution: "" },
{ name: "Vanilla extract", amount: "2 tsp", substitution: "" },
{ name: "Large eggs", amount: "2", substitution: "Flax eggs for vegan version" },
{ name: "Semi-sweet chocolate chips", amount: "2 cups (340g)", substitution: "Dark chocolate chunks" },
{ name: "Chopped walnuts", amount: "1 cup (optional)", substitution: "Pecans or omit for nut-free" }
],
instructions: [
{
text: "In a medium bowl, whisk together flour, baking soda, and salt. Set aside.",
tip: "Whisking aerates the dry ingredients for better mixing."
},
{
text: "In a large bowl, cream together softened butter, granulated sugar, and brown sugar until light and fluffy, about 3-5 minutes.",
tip: "Creaming properly creates air pockets for chewy cookies."
},
{
text: "Beat in vanilla extract and eggs, one at a time, mixing well after each addition.",
tip: "Room temperature eggs incorporate better."
},
{
text: "Gradually add the dry ingredients to the wet ingredients, mixing just until combined. Don't overmix.",
tip: "Overmixing develops gluten, making cookies tough."
},
{
text: "Fold in chocolate chips and walnuts (if using) with a spatula.",
tip: "Save some chocolate chips to press on top before baking for pretty cookies."
},
{
text: "Cover the dough and refrigerate for at least 2 hours, or preferably overnight.",
tip: "Chilling prevents spreading and enhances flavor."
},
{
text: "Preheat oven to 375°F (190°C). Line baking sheets with parchment paper.",
tip: "Parchment prevents sticking and makes cleanup easy."
},
{
text: "Scoop dough into 1.5 tablespoon balls and place 2 inches apart on baking sheets.",
tip: "Use a cookie scoop for evenly sized cookies."
},
{
text: "Bake for 9-11 minutes until edges are golden but centers are still soft. Let cool on baking sheets for 5 minutes before transferring to wire racks.",
tip: "They'll continue cooking as they cool, so don't overbake."
}
],
images: [
{
url: "https://images.unsplash.com/photo-1558961363-fa8fdf82db35?ixlib=rb-4.0.3&auto=format&fit=crop&w=500&q=80",
description: "Perfectly baked cookies with melty chocolate chips"
},
{
url: "https://images.unsplash.com/photo-1558961363-fa8fdf82db35?ixlib=rb-4.0.3&auto=format&fit=crop&w=500&q=80",
description: "Cookie dough balls ready for baking"
},
{
url: "https://images.unsplash.com/photo-1558961363-fa8fdf82db35?ixlib=rb-4.0.3&auto=format&fit=crop&w=500&q=80",
description: "All ingredients measured and ready to mix"
}
]
},
{
id: 3,
title: "Dad's Hearty Beef Stew",
story: "This was Dad's specialty on cold winter nights. He would slow-cook it all day, and the house would smell amazing. The secret is in the long simmering time and a splash of red wine.",
category: "dinner",
prepTime: 25,
cookTime: 180,
servings: 6,
image: "https://images.unsplash.com/photo-1573164713714-d95e436ab8d6?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80",
ingredients: [
{ name: "Beef chuck", amount: "2 lbs (900g), cut into 1-inch cubes", substitution: "Beef stew meat" },
{ name: "All-purpose flour", amount: "1/4 cup (30g)", substitution: "Gluten-free flour" },
{ name: "Salt and pepper", amount: "to taste", substitution: "" },
{ name: "Olive oil", amount: "2 tbsp", substitution: "" },
{ name: "Onion", amount: "1 large, diced", substitution: "" },
{ name: "Carrots", amount: "3 medium, sliced", substitution: "" },
{ name: "Celery", amount: "3 stalks, sliced", substitution: "" },
{ name: "Garlic", amount: "4 cloves, minced", substitution: "" },
{ name: "Tomato paste", amount: "2 tbsp", substitution: "" },
{ name: "Red wine", amount: "1/2 cup (optional)", substitution: "Beef broth" },
{ name: "Beef broth", amount: "4 cups (950ml)", substitution: "Vegetable broth" },
{ name: "Dried thyme", amount: "1 tsp", substitution: "1 tbsp fresh thyme" },
{ name: "Bay leaves", amount: "2", substitution: "" },
{ name: "Potatoes", amount: "3 medium, cubed", substitution: "Sweet potatoes" },
{ name: "Frozen peas", amount: "1 cup", substitution: "" },
{ name: "Fresh parsley", amount: "2 tbsp, chopped", substitution: "1 tbsp dried parsley" }
],
instructions: [
{
text: "Pat beef cubes dry with paper towels and season generously with salt and pepper. Dredge in flour, shaking off excess.",
tip: "Drying the meat helps it brown better."
},
{
text: "Heat olive oil in a large Dutch oven over medium-high heat. Brown beef in batches, about 3-4 minutes per side. Transfer to a plate.",
tip: "Don't overcrowd the pan or meat will steam instead of brown."
},
{
text: "In the same pot, add onion, carrots, and celery. Cook for 5 minutes until softened. Add garlic and cook for 1 minute until fragrant.",
tip: "This builds the flavor base (mirepoix)."
},
{
text: "Stir in tomato paste and cook for 2 minutes. Deglaze with red wine (if using), scraping up browned bits from the bottom.",
tip: "Deglazing adds incredible flavor."
},
{
text: "Return beef to the pot. Add beef broth, thyme, and bay leaves. Bring to a simmer, then reduce heat to low. Cover and cook for 1.5 hours.",
tip: "Low and slow makes the meat tender."
},
{
text: "Add potatoes and cook for another 30 minutes until tender. Stir in peas and cook for 5 more minutes.",
tip: "Add potatoes later so they don't turn mushy."
},
{
text: "Discard bay leaves. Stir in parsley and season with additional salt and pepper if needed. Serve hot with crusty bread.",
tip: "Stew tastes even better the next day!"
}
],
images: [
{
url: "https://images.unsplash.com/photo-1573164713714-d95e436ab8d6?ixlib=rb-4.0.3&auto=format&fit=crop&w=500&q=80",
description: "Rich, hearty beef stew served in a bowl"
},