Category Background
Field Methodology

Portion Preferences & Visual Scaling

A tactile, repeatable methodology for estimating plate proportions, balancing meal satisfaction, and establishing physical comfort.

Select Components

Proteins Palm Size

Grilled Chicken Breast

A dense protein option providing sustained satiety without a heavy digestive load.

Grains & Bases Closed Fist

Brown Rice & Quinoa Blend

Slow-release carbohydrates that fuel daily tasks while maintaining stable glucose patterns.

Greens & Veggies Two Open Hands

Roasted Broccoli & Kale

Fiber-rich greens that supply essential micronutrients and bulk to the meal.

Fats & Extras Thumb Size

Avocado & Olive Oil

Rich lipid sources for optimal nutrient absorption and meal satisfaction.

Proteins One Cupped Hand

Simmered Black Beans

A double-duty ingredient providing clean plant-based protein and high soluble fiber.

Fats & Extras Thumb Size

Greek Yogurt Herb Sauce

A lighter alternative to classic sour cream, adding tang and moderate richness.

Your Custom Plate

No items added to the plate estimator. Click "Add to Estimator" on the left to begin compiling your meal.

Estimated Satiety Rank: --
Digestion Comfort Level: --
Volume Density: --

Visual Reference Guide

Palm Size (Proteins)

Typically corresponds to a standard portion of poultry, fish, or plant protein blocks.

Closed Fist (Carbs/Bases)

Best used to size energy-providing grains, starches, or whole fruit portions.

Two Open Hands (Greens)

The ideal volume reference for leafy salads, non-starchy vegetables, and crucifers.

Thumb Size (Lipids/Fats)

Applies to concentrated oils, nut butters, cheeses, and heavy dressings.

Navigating The Trade-offs of Meal Scaling

Adjusting your portion preferences is rarely a simple calculation of reduction or excess. True balance requires weighing satiety goals against digestion times and daily energy outputs. A meal that is too rich in complex grains may cause sluggishness, while a bowl lacking lipids might leave you looking for food soon after.

' + item.guide + '
'; selectedList.appendChild(itemEl); }); const sizeSelects = selectedList.querySelectorAll('.js-item-size'); sizeSelects.forEach(select => { select.addEventListener('change', (e) => { const id = e.target.getAttribute('data-id'); const newSize = e.target.value; const targetItem = addedItems.find(i => i.id === id); if (targetItem) { targetItem.size = newSize; calculateStats(); } }); }); const removeBtns = selectedList.querySelectorAll('.js-remove-item'); removeBtns.forEach(btn => { btn.addEventListener('click', () => { const id = btn.getAttribute('data-id'); removeItem(id); }); }); calculateStats(); } function calculateStats() { if (addedItems.length === 0) return; let proteinScore = 0; let grainScore = 0; let vegScore = 0; let fatScore = 0; addedItems.forEach(item => { let multiplier = 2; if (item.size === 'light') multiplier = 1; if (item.size === 'hearty') multiplier = 3; if (item.type === 'protein') proteinScore += multiplier; else if (item.type === 'grain') grainScore += multiplier; else if (item.type === 'vegetable') vegScore += multiplier; else if (item.type === 'fat') fatScore += multiplier; }); const totalSatiety = (proteinScore * 2) + (grainScore * 1.5) + (fatScore * 1.2) + (vegScore * 0.8); let satietyText = "Moderate"; if (totalSatiety < 4) satietyText = "Light Sustenance"; else if (totalSatiety > 8) satietyText = "Long-lasting Fullness"; else satietyText = "Optimal Satiety"; const heavyLoad = (grainScore * 1.2) + (fatScore * 1.5) + (proteinScore * 1.0); const lightBalance = vegScore * 1.5; const comfortScore = 10 - (heavyLoad - lightBalance) * 0.5; let comfortText = "Steady & Clean"; if (comfortScore < 5) comfortText = "Heavy / Slow Transit"; else if (comfortScore > 8) comfortText = "Light & High Energy"; let densityText = "Balanced Proportions"; if (vegScore > (grainScore + fatScore)) { densityText = "High Volume / Low Density"; } else if ((grainScore + fatScore) > (vegScore + proteinScore)) { densityText = "Concentrated Fuel / Low Volume"; } if (satietyVal) satietyVal.textContent = satietyText; if (digestVal) digestVal.textContent = comfortText; if (volumeVal) volumeVal.textContent = densityText; } function removeItem(id) { addedItems = addedItems.filter(item => item.id !== id); const originalBtn = Array.from(addButtons).find(btn => btn.getAttribute('data-id') === id); if (originalBtn) { originalBtn.disabled = false; originalBtn.textContent = 'Add to Estimator'; originalBtn.classList.remove('bg-[#1C231F]', 'text-[#FDFBF7]', 'opacity-50'); originalBtn.classList.add('text-[#1C231F]', 'hover:bg-[#1C231F]', 'hover:text-[#FDFBF7]'); } updatePlateUI(); } addButtons.forEach(button => { button.addEventListener('click', () => { const id = button.getAttribute('data-id'); const name = button.getAttribute('data-name'); const guide = button.getAttribute('data-guide'); const type = button.getAttribute('data-type'); if (addedItems.some(item => item.id === id)) return; addedItems.push({ id, name, guide, type, size: 'moderate' }); button.disabled = true; button.textContent = 'Added'; button.classList.add('bg-[#1C231F]', 'text-[#FDFBF7]', 'opacity-50'); button.classList.remove('text-[#1C231F]', 'hover:bg-[#1C231F]', 'hover:text-[#FDFBF7]'); updatePlateUI(); }); }); if (resetBtn) { resetBtn.addEventListener('click', () => { addedItems = []; addButtons.forEach(button => { button.disabled = false; button.textContent = 'Add to Estimator'; button.classList.remove('bg-[#1C231F]', 'text-[#FDFBF7]', 'opacity-50'); button.classList.add('text-[#1C231F]', 'hover:bg-[#1C231F]', 'hover:text-[#FDFBF7]'); }); updatePlateUI(); }); } let currentCategory = 'all'; let searchQuery = ''; function filterList() { componentCards.forEach(card => { const category = card.getAttribute('data-category'); const name = card.getAttribute('data-name').toLowerCase(); const matchesCategory = (currentCategory === 'all' || category === currentCategory); const matchesSearch = name.includes(searchQuery); if (matchesCategory && matchesSearch) { card.style.display = 'flex'; } else { card.style.display = 'none'; } }); } filterTabs.forEach(tab => { tab.addEventListener('click', () => { filterTabs.forEach(t => { t.classList.remove('active-tab', 'bg-[#1C231F]', 'text-[#FDFBF7]', 'border-[#1C231F]'); t.classList.add('border-[#E6E1D6]', 'text-[#1C231F]'); }); tab.classList.add('active-tab', 'bg-[#1C231F]', 'text-[#FDFBF7]', 'border-[#1C231F]'); tab.classList.remove('border-[#E6E1D6]', 'text-[#1C231F]'); currentCategory = tab.getAttribute('data-category'); filterList(); }); }); if (searchInput) { searchInput.addEventListener('input', (e) => { searchQuery = e.target.value.toLowerCase().trim(); filterList(); }); } });