diff --git a/assets/css/style.css b/assets/css/style.css
index eafeb53..7cb544e 100644
--- a/assets/css/style.css
+++ b/assets/css/style.css
@@ -5631,6 +5631,248 @@ body.cooking-mode-active .app-header {
transform: scale(0.92);
}
+/* ── Screensaver nutrition panel ── */
+.screensaver-nutrition {
+ display: none;
+ align-items: center;
+ justify-content: center;
+ max-width: 90vw;
+ pointer-events: none;
+ user-select: none;
+}
+.ss-nutr-wrap {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 20px;
+}
+.ss-nutr-title {
+ color: rgba(255,255,255,0.75);
+ font-size: 1.3rem;
+ font-weight: 300;
+ letter-spacing: 1px;
+ text-align: center;
+}
+.ss-nutr-charts {
+ display: flex;
+ align-items: flex-start;
+ gap: 36px;
+ flex-wrap: wrap;
+ justify-content: center;
+}
+.ss-nutr-chart-block {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 10px;
+}
+.ss-nutr-chart-label {
+ color: rgba(255,255,255,0.5);
+ font-size: .85rem;
+ text-align: center;
+}
+/* 3D animated pie */
+.ss-pie3d {
+ width: 140px;
+ height: 140px;
+ border-radius: 50%;
+ background: var(--pie-bg, conic-gradient(#4ade80 0deg 90deg, #60a5fa 90deg 180deg, #fbbf24 180deg 270deg, #334155 270deg 360deg));
+ transform: perspective(250px) rotateX(40deg) scale(0.82);
+ box-shadow: 0 12px 32px rgba(0,0,0,0.6), 0 4px 0 rgba(255,255,255,0.06);
+ transition: transform 0.8s cubic-bezier(.34,1.56,.64,1), box-shadow 0.8s;
+ will-change: transform;
+}
+.ss-pie3d.ss-pie3d-ready {
+ transform: perspective(250px) rotateX(30deg) scale(1);
+ animation: ss-pie-spin 18s linear infinite;
+}
+@keyframes ss-pie-spin {
+ from { transform: perspective(250px) rotateX(30deg) rotate(0deg) scale(1); }
+ to { transform: perspective(250px) rotateX(30deg) rotate(360deg) scale(1); }
+}
+.ss-nutr-legend {
+ display: flex;
+ flex-direction: column;
+ gap: 5px;
+ min-width: 130px;
+}
+.ss-leg-row {
+ display: flex;
+ align-items: center;
+ gap: 6px;
+ color: rgba(255,255,255,0.65);
+ font-size: .8rem;
+}
+.ss-leg-dot {
+ width: 9px;
+ height: 9px;
+ border-radius: 50%;
+ flex-shrink: 0;
+}
+.ss-leg-pct {
+ margin-left: auto;
+ color: rgba(255,255,255,0.45);
+}
+/* Score donut column */
+.ss-nutr-scores-col {
+ display: flex;
+ flex-direction: column;
+ gap: 20px;
+ align-items: center;
+}
+.ss-donut-wrap {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 4px;
+}
+.ss-donut-label {
+ color: rgba(255,255,255,0.45);
+ font-size: .75rem;
+}
+/* CSS-only ring donut using conic-gradient */
+.ss-donut-ring {
+ position: relative;
+ width: 72px;
+ height: 72px;
+ border-radius: 50%;
+ background: conic-gradient(var(--color, #4ade80) calc(var(--val, 0) * 1%), rgba(255,255,255,0.08) calc(var(--val, 0) * 1%));
+ transform: perspective(120px) rotateX(30deg) scale(0.7);
+ box-shadow: 0 6px 16px rgba(0,0,0,0.5);
+ transition: transform 0.7s cubic-bezier(.34,1.56,.64,1), background 0.9s ease;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+.ss-donut-ring.ss-donut-ready {
+ transform: perspective(120px) rotateX(25deg) scale(1);
+ animation: ss-donut-bob 4s ease-in-out infinite;
+}
+@keyframes ss-donut-bob {
+ 0%,100% { transform: perspective(120px) rotateX(25deg) scale(1) translateY(0); }
+ 50% { transform: perspective(120px) rotateX(25deg) scale(1) translateY(-4px); }
+}
+.ss-donut-ring::after {
+ content: '';
+ position: absolute;
+ width: 48px;
+ height: 48px;
+ border-radius: 50%;
+ background: #0a0a0a;
+}
+.ss-donut-text {
+ position: relative;
+ z-index: 1;
+ color: rgba(255,255,255,0.8);
+ font-size: .8rem;
+ font-weight: 600;
+}
+
+/* ── Dashboard nutrition card ── */
+.nutr-card {
+ background: var(--bg-card, #fff);
+ border-radius: 14px;
+ padding: 16px;
+ box-shadow: var(--shadow);
+ margin-bottom: 16px;
+}
+.nutr-body {
+ display: flex;
+ gap: 16px;
+ align-items: flex-start;
+ margin: 12px 0;
+}
+.nutr-pie-wrap {
+ position: relative;
+ flex-shrink: 0;
+}
+.nutr-pie-3d {
+ width: 100px;
+ height: 100px;
+ border-radius: 50%;
+ transform: perspective(180px) rotateX(38deg) scale(0.82);
+ box-shadow: 0 8px 20px rgba(0,0,0,0.18);
+ transition: transform 0.7s cubic-bezier(.34,1.56,.64,1);
+ will-change: transform;
+}
+.nutr-pie-3d.nutr-pie-ready {
+ transform: perspective(180px) rotateX(28deg) scale(1);
+ animation: nutr-pie-spin 22s linear infinite;
+}
+@keyframes nutr-pie-spin {
+ from { transform: perspective(180px) rotateX(28deg) rotate(0deg) scale(1); }
+ to { transform: perspective(180px) rotateX(28deg) rotate(360deg) scale(1); }
+}
+.nutr-pie-center {
+ position: absolute;
+ inset: 0;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ pointer-events: none;
+}
+.nutr-pie-total {
+ font-size: 1.4rem;
+ font-weight: 700;
+ line-height: 1;
+}
+.nutr-pie-label {
+ font-size: .6rem;
+ color: var(--text-secondary);
+}
+.nutr-legend {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+}
+.nutr-leg-row {
+ display: flex;
+ align-items: center;
+ gap: 5px;
+ font-size: .78rem;
+}
+.nutr-leg-dot {
+ width: 8px;
+ height: 8px;
+ border-radius: 50%;
+ flex-shrink: 0;
+}
+.nutr-leg-pct {
+ margin-left: auto;
+ color: var(--text-secondary);
+ font-weight: 600;
+}
+/* Score bars */
+.nutr-scores {
+ display: flex;
+ flex-direction: column;
+ gap: 6px;
+ margin-top: 6px;
+}
+.nutr-score-row {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ font-size: .78rem;
+}
+.nutr-score-label { flex: 0 0 80px; white-space: nowrap; }
+.nutr-score-track {
+ flex: 1;
+ height: 7px;
+ border-radius: 4px;
+ background: rgba(0,0,0,0.07);
+ overflow: hidden;
+}
+.nutr-score-fill {
+ height: 100%;
+ border-radius: 4px;
+ width: 0%;
+ transition: width 1s ease;
+}
+.nutr-score-val { flex: 0 0 32px; text-align: right; font-weight: 600; }
+
/* ===== SETUP WIZARD ===== */
.setup-wizard-content {
max-width: 480px;
diff --git a/assets/js/app.js b/assets/js/app.js
index f4ae003..d38b660 100644
--- a/assets/js/app.js
+++ b/assets/js/app.js
@@ -2772,6 +2772,205 @@ function _renderAntiWasteSection(used30, wasted30, usedP30, wastedP30, usedP60,
}
}
+// ===== NUTRITION ANALYSIS SECTION =====
+// Alternates with waste-chart-section every hour (randomised offset)
+
+// Colour palette for pie slices (matches category colours)
+const _NUTR_COLORS = {
+ 'frutta': '#4ade80', 'verdura': '#22d3ee',
+ 'carne': '#f87171', 'pesce': '#60a5fa',
+ 'latticini': '#fbbf24', 'pasta': '#a78bfa',
+ 'pane': '#fb923c', 'cereali': '#f472b6',
+ 'bevande': '#34d399', 'condimenti':'#94a3b8',
+ 'surgelati': '#818cf8', 'conserve': '#e879f9',
+ 'snack': '#fcd34d', 'altro': '#64748b',
+};
+
+let _nutriData = null; // cached result from last inventory fetch
+let _insightFlipTimer = null; // setInterval handle for waste/nutrition alternation
+
+/**
+ * Compute nutrition-related metrics from the current inventory array.
+ * Returns null if not enough data.
+ */
+function _buildNutritionData(inventory) {
+ if (!inventory || inventory.length === 0) return null;
+
+ // Category distribution (product count)
+ const catCounts = {};
+ for (const item of inventory) {
+ const cat = mapToLocalCategory(item.category || '', item.name || '');
+ catCounts[cat] = (catCounts[cat] || 0) + 1;
+ }
+ const total = Object.values(catCounts).reduce((s, v) => s + v, 0);
+
+ // Sorted slices for pie
+ const slices = Object.entries(catCounts)
+ .sort((a, b) => b[1] - a[1])
+ .map(([cat, count]) => ({
+ cat,
+ count,
+ pct: Math.round(count / total * 100),
+ color: _NUTR_COLORS[cat] || '#64748b',
+ icon: CATEGORY_ICONS[cat] || '📦',
+ }));
+
+ // Health score 0-100 based on category mix
+ // + points for fruit/veg/fish; - for snacks/sweets
+ const healthyCats = ['frutta','verdura','pesce','carne'];
+ const unhealthyCats = ['snack','bevande'];
+ const healthyCount = healthyCats.reduce((s, c) => s + (catCounts[c] || 0), 0);
+ const unhealthyCount= unhealthyCats.reduce((s, c) => s + (catCounts[c] || 0), 0);
+ const healthScore = Math.min(100, Math.max(0,
+ Math.round(50 + (healthyCount / Math.max(total, 1)) * 50 - (unhealthyCount / Math.max(total, 1)) * 30)
+ ));
+
+ // Variety score: number of distinct categories / max(16)
+ const varietyScore = Math.min(100, Math.round(Object.keys(catCounts).length / 16 * 100));
+
+ // Freshness score: % products with expiry date set
+ const withExpiry = inventory.filter(i => i.expiry_date).length;
+ const freshnessScore = Math.round(withExpiry / Math.max(total, 1) * 100);
+
+ // Balance: fraction of fresh (frigo+freezer) vs shelf-stable (dispensa)
+ const fresh = inventory.filter(i => i.location === 'frigo' || i.location === 'freezer').length;
+ const fresh_pct = Math.round(fresh / Math.max(total, 1) * 100);
+
+ return { slices, total, healthScore, varietyScore, freshnessScore, fresh_pct };
+}
+
+/**
+ * Render the nutrition analysis card into #nutrition-section.
+ */
+function _renderNutritionSection(inventory) {
+ const section = document.getElementById('nutrition-section');
+ if (!section) return;
+ const data = _buildNutritionData(inventory);
+ if (!data) { section.style.display = 'none'; return; }
+ _nutriData = data;
+
+ const { slices, total, healthScore, varietyScore, freshnessScore, fresh_pct } = data;
+ const top5 = slices.slice(0, 5);
+
+ // Build conic-gradient for pie
+ let deg = 0;
+ const stops = top5.map(s => {
+ const end = deg + s.pct * 3.6;
+ const stop = `${s.color} ${deg.toFixed(1)}deg ${end.toFixed(1)}deg`;
+ deg = end;
+ return stop;
+ });
+ if (deg < 360) stops.push(`#334155 ${deg.toFixed(1)}deg 360deg`);
+ const gradient = `conic-gradient(from 0deg, ${stops.join(', ')})`;
+
+ // Score colour
+ const scoreColor = healthScore >= 70 ? '#4ade80' : healthScore >= 45 ? '#fbbf24' : '#f87171';
+ const scoreLabel = healthScore >= 70 ? '😄 Ottimo' : healthScore >= 45 ? '🙂 Discreto' : '😬 Migliorabile';
+
+ section.innerHTML = `
+
+
+
+
+
+
+
+
+ ${total}
+ prodotti
+
+
+
+
+
+ ${top5.map(s => `
+
+
+ ${s.icon}
+ ${s.cat}
+ ${s.pct}%
+
`).join('')}
+
+
+
+
+
+ ${_nutrScoreBar('🌿 Salute', healthScore, '#4ade80')}
+ ${_nutrScoreBar('🎨 Varietà', varietyScore, '#60a5fa')}
+ ${_nutrScoreBar('❄️ Freschi', fresh_pct, '#22d3ee')}
+
+
+
Basato su ${total} prodotti in dispensa · EverShelf
+
`;
+
+ // Trigger pie animation after render
+ requestAnimationFrame(() => {
+ const pie = document.getElementById('nutr-pie');
+ if (pie) setTimeout(() => pie.classList.add('nutr-pie-ready'), 60);
+ });
+}
+
+function _nutrScoreBar(label, val, color) {
+ return ``;
+}
+
+/**
+ * Start the waste ↔ nutrition alternation on the dashboard.
+ * One is shown, the other hidden; they swap every hour (+ random phase offset).
+ */
+let _insightPhase = null; // 'waste' | 'nutrition'
+
+function _startInsightAlternation(inventory) {
+ clearInterval(_insightFlipTimer);
+ // Pick initial panel based on current minute: even hour → waste, odd → nutrition
+ const isNutritionTurn = Math.floor(Date.now() / 3_600_000) % 2 === 1;
+ _insightPhase = isNutritionTurn ? 'nutrition' : 'waste';
+ _applyInsightPhase();
+ // Flip every hour
+ _insightFlipTimer = setInterval(() => {
+ _insightPhase = _insightPhase === 'waste' ? 'nutrition' : 'waste';
+ _applyInsightPhase();
+ }, 3_600_000);
+}
+
+function _applyInsightPhase() {
+ const wasteEl = document.getElementById('waste-chart-section');
+ const nutrEl = document.getElementById('nutrition-section');
+ if (!wasteEl || !nutrEl) return;
+ const showNutr = _insightPhase === 'nutrition' && nutrEl.innerHTML.trim() !== '';
+ const showWaste = _insightPhase === 'waste' && wasteEl.innerHTML.trim() !== '';
+ // Fade-swap
+ [wasteEl, nutrEl].forEach(el => { el.style.opacity = '0'; el.style.transition = 'opacity .6s'; });
+ setTimeout(() => {
+ wasteEl.style.display = showWaste ? 'block' : 'none';
+ nutrEl.style.display = showNutr ? 'block' : 'none';
+ // If neither ready yet, keep waste visible
+ if (!showWaste && !showNutr) wasteEl.style.display = 'block';
+ requestAnimationFrame(() => {
+ wasteEl.style.opacity = '1';
+ nutrEl.style.opacity = '1';
+ // Animate score bars when nutrition becomes visible
+ if (showNutr) {
+ nutrEl.querySelectorAll('.nutr-score-fill').forEach(bar => {
+ bar.style.width = (bar.dataset.target || 0) + '%';
+ });
+ }
+ });
+ }, 620);
+}
+
// ===== DASHBOARD =====
async function loadDashboard() {
try {
@@ -2885,6 +3084,13 @@ async function loadDashboard() {
);
_startAntiWasteAutoRefresh();
+ // Nutrition section — built from the full inventory list
+ try {
+ const invForNutr = (await api('inventory_list')).inventory || [];
+ _renderNutritionSection(invForNutr);
+ } catch(_e) {}
+ _startInsightAlternation();
+
// Opened (partially used products with known package capacity)
const openedSection = document.getElementById('alert-opened');
const openedList = document.getElementById('opened-list');
@@ -11388,10 +11594,9 @@ function activateScreensaver() {
requestAnimationFrame(() => overlay.classList.add('visible'));
updateScreensaverClock();
_screensaverClockInterval = setInterval(updateScreensaverClock, 1000);
- // Load data and start facts
+ // Load data and start fact/nutrition rotation
loadScreensaverData().then(() => {
- showNextScreensaverFact();
- _screensaverFactInterval = setInterval(showNextScreensaverFact, SCREENSAVER_FACT_DURATION);
+ _startScreensaverRotation();
});
}
@@ -11427,6 +11632,11 @@ function dismissScreensaver(targetPage) {
if (!_screensaverActive) return;
clearInterval(_screensaverClockInterval);
clearInterval(_screensaverFactInterval);
+ clearInterval(_ssRotationTimer);
+ const nutrEl = document.getElementById('screensaver-nutrition');
+ if (nutrEl) { nutrEl.style.display = 'none'; nutrEl.innerHTML = ''; }
+ const factEl = document.getElementById('screensaver-fact');
+ if (factEl) { factEl.classList.remove('visible'); }
const overlay = document.getElementById('screensaver');
overlay.classList.remove('visible');
setTimeout(() => {
@@ -11442,6 +11652,121 @@ function dismissScreensaver(targetPage) {
}, 400);
}
+// Handle for screensaver rotation timer
+let _ssRotationTimer = null;
+let _ssSlot = 0; // 0=fact, 1=nutrition, 2=fact, 3=nutrition …
+
+/**
+ * Start the screensaver content rotation:
+ * Every SCREENSAVER_FACT_DURATION ms flip between fact text and nutrition charts.
+ */
+function _startScreensaverRotation() {
+ clearInterval(_ssRotationTimer);
+ _ssSlot = 0;
+ _showScreensaverSlot(0);
+ _screensaverFactInterval = _ssRotationTimer = setInterval(() => {
+ _ssSlot = (_ssSlot + 1) % 4; // 4 steps: fact, nutr, fact, nutr (with repeats for more facts)
+ _showScreensaverSlot(_ssSlot);
+ }, SCREENSAVER_FACT_DURATION);
+}
+
+function _showScreensaverSlot(slot) {
+ const factEl = document.getElementById('screensaver-fact');
+ const nutrEl = document.getElementById('screensaver-nutrition');
+ if (!factEl || !nutrEl) return;
+ const showNutr = slot % 2 === 1; // odd slots = nutrition
+ // Fade out both
+ factEl.classList.remove('visible');
+ nutrEl.style.opacity = '0';
+ nutrEl.style.transition = 'opacity 1.5s ease';
+ setTimeout(() => {
+ if (!_screensaverActive) return;
+ if (showNutr) {
+ factEl.style.display = 'none';
+ nutrEl.style.display = 'flex';
+ _renderScreensaverNutrition();
+ requestAnimationFrame(() => { nutrEl.style.opacity = '1'; });
+ } else {
+ nutrEl.style.display = 'none';
+ factEl.style.display = '';
+ factEl.textContent = generateScreensaverFact();
+ requestAnimationFrame(() => { factEl.classList.add('visible'); });
+ }
+ }, 1600);
+}
+
+/**
+ * Render animated 3D-style pie charts inside the screensaver.
+ * Shows: category distribution, health score, freshness.
+ */
+function _renderScreensaverNutrition() {
+ const el = document.getElementById('screensaver-nutrition');
+ if (!el) return;
+ // Use cached nutrition data from dashboard if available, else build from screensaver inventory
+ const inv = (_screensaverData && _screensaverData.inventory) || [];
+ const data = (_nutriData && _nutriData.slices) ? _nutriData : _buildNutritionData(inv);
+ if (!data) { el.style.display = 'none'; return; }
+
+ const { slices, total, healthScore, varietyScore, freshnessScore, fresh_pct } = data;
+ const top4 = slices.slice(0, 4);
+
+ // Build conic-gradient
+ let deg = 0;
+ const stops = top4.map(s => {
+ const end = deg + s.pct * 3.6;
+ const stop = `${s.color} ${deg.toFixed(1)}deg ${end.toFixed(1)}deg`;
+ deg = end;
+ return stop;
+ });
+ if (deg < 360) stops.push(`rgba(255,255,255,0.08) ${deg.toFixed(1)}deg 360deg`);
+ const gradient = `conic-gradient(from 0deg, ${stops.join(', ')})`;
+
+ // Three mini donut charts: categories, health, freshness
+ const healthColor = healthScore >= 70 ? '#4ade80' : healthScore >= 45 ? '#fbbf24' : '#f87171';
+ const freshColor = freshnessScore >= 70 ? '#22d3ee' : freshnessScore >= 40 ? '#60a5fa' : '#94a3b8';
+ const varColor = varietyScore >= 70 ? '#a78bfa' : varietyScore >= 40 ? '#fbbf24' : '#64748b';
+
+ el.innerHTML = `
+
+
🥗 La tua dispensa oggi
+
+
+
+
+
${total} prodotti
+
+ ${top4.map(s => `
${s.icon} ${s.cat} ${s.pct}%
`).join('')}
+
+
+
+
+ ${_ssDonut('❤️ Salute', healthScore, healthColor)}
+ ${_ssDonut('🎨 Varietà', varietyScore, varColor)}
+ ${_ssDonut('❄️ Freschi', fresh_pct, freshColor)}
+
+
+
`;
+
+ // Trigger animations
+ requestAnimationFrame(() => {
+ const pie = document.getElementById('ss-pie-main');
+ if (pie) setTimeout(() => pie.classList.add('ss-pie3d-ready'), 80);
+ el.querySelectorAll('.ss-donut-ring').forEach(ring => {
+ const val = parseInt(ring.dataset.val || 0);
+ setTimeout(() => { ring.style.setProperty('--val', val); ring.classList.add('ss-donut-ready'); }, 200);
+ });
+ });
+}
+
+function _ssDonut(label, val, color) {
+ return `
+
+ ${val}%
+
+
${label}
+
`;
+}
+
// Load all data needed for screensaver facts
async function loadScreensaverData() {
try {
@@ -11699,49 +12024,40 @@ function generateScreensaverFact() {
}
// --- Time-of-day greetings & suggestions ---
- facts.push(() => `${greeting}! Se vuoi che ti preparo una ricetta, tocca qui.`);
- facts.push(() => `${greeting}! La tua dispensa è sotto controllo. 😊`);
if (hour >= 6 && hour < 10) {
- facts.push(() => `Buongiorno! Pronto per la colazione? ☕`);
if (byCategory['pane']) facts.push(() => `Buongiorno! Hai del pane per la colazione. 🍞`);
if (byCategory['latticini']) facts.push(() => `C'è del latte in frigo per il cappuccino? ☕🥛`);
+ if (byCategory['frutta']) facts.push(() => `Buongiorno! Una bella frutta fresca per iniziare bene. 🍎`);
}
if (hour >= 11 && hour < 14) {
- facts.push(() => `È quasi ora di pranzo! Cosa cuciniamo? 🍽️`);
if (byCategory['pasta']) facts.push(() => `Ora di pranzo… Un bel piatto di pasta? 🍝`);
+ if (byCategory['verdura']) facts.push(() => `Un'insalata fresca per pranzo? Hai ${byCategory['verdura'].length} verdure! 🥗`);
}
if (hour >= 17 && hour < 21) {
- facts.push(() => `Buona sera! Hai pensato alla cena? 🍽️`);
if (byCategory['carne']) facts.push(() => `Per cena potresti usare la carne che hai. 🥩`);
if (byCategory['pesce']) facts.push(() => `Che ne dici di pesce per cena? 🐟`);
+ if (expiringThisWeek.length > 0) facts.push(() => `Hai ${expiringThisWeek.length} prodotti in scadenza questa settimana — usali stasera!`);
}
if (hour >= 21 || hour < 6) {
- facts.push(() => `Buonanotte! Domani controlla le scadenze. 🌙`);
+ if (expiringSoon.length > 0) facts.push(() => `Buonanotte! Domani ricordati di usare: ${expiringSoon.slice(0,2).map(i=>i.name).join(', ')}.`);
}
// --- Weekly stats ---
const recentIn = stats.recent_in || 0;
const recentOut = stats.recent_out || 0;
- if (recentIn > 0) {
- facts.push(() => `Questa settimana hai aggiunto ${recentIn} prodotti.`);
- }
- if (recentOut > 0) {
- facts.push(() => `Questa settimana hai consumato ${recentOut} prodotti.`);
- }
if (recentIn > 0 && recentOut > 0) {
- facts.push(() => `Bilancio settimanale: +${recentIn} entrati, -${recentOut} usciti.`);
+ facts.push(() => `Bilancio settimana: +${recentIn} aggiunti, −${recentOut} consumati.`);
+ } else if (recentIn > 0) {
+ facts.push(() => `Questa settimana hai aggiunto ${recentIn} prodotti.`);
+ } else if (recentOut > 0) {
+ facts.push(() => `Questa settimana hai consumato ${recentOut} prodotti. Ottimo!`);
}
// --- Tips & curiosità (statici ma ruotano) ---
- facts.push(() => `💡 Lo sapevi? I prodotti in freezer durano molto più a lungo della data di scadenza.`);
+ facts.push(() => `💡 I prodotti in freezer durano molto più a lungo della data di scadenza.`);
facts.push(() => `💡 Il pane congelato mantiene la fragranza per settimane.`);
- facts.push(() => `💡 Le uova si conservano fino a 3-4 settimane dopo la data preferita.`);
- facts.push(() => `💡 Lo yogurt chiuso in frigo dura spesso 1-2 settimane oltre la scadenza.`);
- facts.push(() => `💡 Per evitare sprechi, usa prima i prodotti con scadenza più vicina.`);
+ facts.push(() => `💡 Per evitare sprechi, usa prima i prodotti con scadenza più vicina (FIFO).`);
facts.push(() => `💡 La carne in freezer può durare fino a 6 mesi senza problemi.`);
- facts.push(() => `💡 Le verdure fresche durano di più se conservate nel cassetto del frigo.`);
- facts.push(() => `💡 Controlla regolarmente la dispensa per evitare doppioni nella spesa.`);
- facts.push(() => `💡 I latticini vanno conservati nella parte più fredda del frigo.`);
facts.push(() => `💡 Non ricongelare mai un alimento già scongelato. Cucinalo subito!`);
facts.push(() => `💡 Un frigo ordinato ti fa risparmiare tempo e denaro.`);
facts.push(() => `💡 Le conserve aperte vanno in frigo e consumate in pochi giorni.`);
diff --git a/index.html b/index.html
index 2ef19fa..a955387 100644
--- a/index.html
+++ b/index.html
@@ -11,7 +11,7 @@
EverShelf
-
+
@@ -152,8 +152,11 @@
-
-
+
+