diff --git a/game.js b/game.js
index a7f63a2..62f7967 100644
--- a/game.js
+++ b/game.js
@@ -170,6 +170,7 @@ const WeatherChance = [
* cups: PriceTable
* }} supplies_prices
* @property {number} cups_sold
+ * @property {number} cost_per_cup
*/
/**
@@ -217,7 +218,8 @@ export function init_game() {
400: 3.75
}
},
- cups_sold: 0
+ cups_sold: 0,
+ cost_per_cup: 0
}
}
@@ -412,3 +414,29 @@ export function make_lemonade(game_state) {
cups_sold
}
}
+
+/**
+ * Calculate the cost to produce one cup of lemonade based on the recipe.
+ * Uses the base tier pricing for each ingredient.
+ * @param {Object} recipe - The recipe with lemons, sugar, ice amounts
+ * @returns {number} The cost to make one cup
+ */
+export function calculate_cost_per_cup(game_state, recipe) {
+ const basePrices = {
+ lemons: SupplyPricing.lemons[0].price,
+ sugar: SupplyPricing.sugar[0].price,
+ ice: SupplyPricing.ice[0].price,
+ cup: SupplyPricing.cups[0].price
+ };
+
+ const cost =
+ (recipe.lemons * basePrices.lemons) +
+ (recipe.sugar * basePrices.sugar) +
+ (recipe.ice * basePrices.ice) +
+ basePrices.cup;
+
+ return {
+ ...game_state,
+ cost_per_cup: Math.round(cost * 100) / 100
+ }
+}
diff --git a/index.html b/index.html
index 90d1c3e..065cd8f 100644
--- a/index.html
+++ b/index.html
@@ -166,6 +166,28 @@
+
+
+ Lemons
+ $0.00
+
+
+ Sugar
+ $0.00
+
+
+ Ice
+ $0.00
+
+
+ Cup
+ $0.01
+
+
+ Total per cup
+ $0.00
+
+
diff --git a/index.js b/index.js
index f02a5d0..673fbcf 100644
--- a/index.js
+++ b/index.js
@@ -3,7 +3,7 @@
* Initializes game state, wires up UI events, and coordinates modules.
*/
-import { init_game, set_price_per_cup, calculate_supply_cost } from './game.js';
+import { init_game, set_price_per_cup, calculate_supply_cost, calculate_cost_per_cup } from './game.js';
import { sprites, cups, render, whenSpritesReady } from './canvasController.js';
import { createReactiveState, updateBindings } from './binding.js';
@@ -130,12 +130,40 @@ if (changePriceBtn) {
}
// Recipe modal handlers
+const recipeInputs = document.querySelectorAll('.recipe_input');
+const recipeCostValue = document.querySelector('.recipe_cost_value');
+
+// Base prices for cost breakdown (matches SupplyPricing tier 1 in game.js)
+const basePrices = { lemons: 0.02, sugar: 0.01, ice: 0.01, cup: 0.01 };
+
+function updateRecipeCost() {
+ const lemons = parseInt(document.querySelector('.recipe_input[data-recipe="lemons"]').value) || 0;
+ const sugar = parseInt(document.querySelector('.recipe_input[data-recipe="sugar"]').value) || 0;
+ const ice = parseInt(document.querySelector('.recipe_input[data-recipe="ice"]').value) || 0;
+
+ // Update breakdown rows
+ document.querySelector('.recipe_cost_item[data-cost="lemons"]').textContent = '$' + (lemons * basePrices.lemons).toFixed(2);
+ document.querySelector('.recipe_cost_item[data-cost="sugar"]').textContent = '$' + (sugar * basePrices.sugar).toFixed(2);
+ document.querySelector('.recipe_cost_item[data-cost="ice"]').textContent = '$' + (ice * basePrices.ice).toFixed(2);
+ document.querySelector('.recipe_cost_item[data-cost="cup"]').textContent = '$' + basePrices.cup.toFixed(2);
+
+ // Update total
+ const result = calculate_cost_per_cup(gameState, { lemons, sugar, ice });
+ recipeCostValue.textContent = '$' + result.cost_per_cup.toFixed(2);
+}
+
+// Update cost when recipe inputs change
+recipeInputs.forEach(input => {
+ input.addEventListener('input', updateRecipeCost);
+});
+
if (changeRecipeBtn) {
changeRecipeBtn.addEventListener('click', () => {
// Set inputs to current recipe values
document.querySelector('.recipe_input[data-recipe="lemons"]').value = gameState.recipe.lemons;
document.querySelector('.recipe_input[data-recipe="sugar"]').value = gameState.recipe.sugar;
document.querySelector('.recipe_input[data-recipe="ice"]').value = gameState.recipe.ice;
+ updateRecipeCost();
recipeModal.classList.add('open');
});
@@ -148,8 +176,10 @@ if (changeRecipeBtn) {
const sugar = parseInt(document.querySelector('.recipe_input[data-recipe="sugar"]').value) || 0;
const ice = parseInt(document.querySelector('.recipe_input[data-recipe="ice"]').value) || 0;
+ const result = calculate_cost_per_cup(gameState, { lemons, sugar, ice });
setState({
- recipe: { lemons, sugar, ice }
+ recipe: { lemons, sugar, ice },
+ cost_per_cup: result.cost_per_cup
});
recipeModal.classList.remove('open');
});
diff --git a/style.css b/style.css
index 4da1f2a..afa4509 100644
--- a/style.css
+++ b/style.css
@@ -674,6 +674,45 @@ canvas {
text-align: center;
}
+.recipe_cost_breakdown {
+ background: rgba(255, 255, 255, 0.6);
+ padding: 12px 16px;
+ border-radius: 10px;
+ margin: 16px 0;
+}
+
+.recipe_cost_row {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ font-family: 'Inter', sans-serif;
+ font-size: 13px;
+ color: #7A6146;
+ padding: 4px 0;
+}
+
+.recipe_cost_row.total {
+ border-top: 1px solid #d4c9b8;
+ margin-top: 8px;
+ padding-top: 10px;
+ font-family: 'Fredoka', sans-serif;
+ font-size: 15px;
+ font-weight: 600;
+ color: #5C4632;
+}
+
+.recipe_cost_item {
+ font-family: 'Inter', sans-serif;
+ font-weight: 500;
+}
+
+.recipe_cost_value {
+ font-family: 'Fredoka', sans-serif;
+ font-size: 18px;
+ font-weight: 600;
+ color: #3f7a33;
+}
+
.recipe_save_btn {
font-family: 'Fredoka', sans-serif;
font-size: 16px;