diff --git a/api/index.php b/api/index.php
index fcea21f..cd6cef9 100644
--- a/api/index.php
+++ b/api/index.php
@@ -1584,6 +1584,10 @@ function getInventoryAnomalies(PDO $db): void {
if (!empty($dismissed[$key])) continue;
$direction = $diff > 0 ? 'phantom' : 'missing';
+ // Special case: expected is negative — more consumption recorded than entries.
+ // The real qty vs tx comparison is meaningless; what we actually know is that
+ // "initial stock was never formally registered as an 'in' transaction".
+ if ($expected <= 0) $direction = 'untracked';
$anomalies[] = [
'inventory_id' => (int)$r['inventory_id'],
'product_id' => (int)$r['product_id'],
diff --git a/assets/js/app.js b/assets/js/app.js
index 7ac5bd2..9b58d6a 100644
--- a/assets/js/app.js
+++ b/assets/js/app.js
@@ -2962,9 +2962,14 @@ function renderBannerItem() {
} else if (entry.type === 'anomaly') {
const an = entry.data;
const isPhantom = an.direction === 'phantom';
+ const isUntracked = an.direction === 'untracked';
banner.className = 'alert-banner banner-anomaly';
iconEl.textContent = '🔍';
- if (isPhantom) {
+ if (isUntracked) {
+ // More consumption recorded than entries — initial stock was never registered
+ titleEl.textContent = `${an.name} — ${t('dashboard.banner_anomaly_untracked_title')}`;
+ detailEl.innerHTML = t('dashboard.banner_anomaly_untracked_detail', { inv_qty: an.inv_qty, unit: an.unit });
+ } else if (isPhantom) {
titleEl.textContent = `${an.name} — ${t('dashboard.banner_anomaly_phantom_title')}`;
detailEl.innerHTML = t('dashboard.banner_anomaly_phantom_detail', { inv_qty: an.inv_qty, unit: an.unit, expected_qty: an.expected_qty });
} else {
diff --git a/translations/de.json b/translations/de.json
index 00eb1a5..60c8089 100644
--- a/translations/de.json
+++ b/translations/de.json
@@ -128,6 +128,9 @@
"banner_finished_check": "Kannst du nachschauen?",
"banner_anomaly_phantom_title": "mehr Bestand als erwartet",
"banner_anomaly_phantom_detail": "Bestand zeigt {inv_qty} {unit}, aber laut Buchungen solltest du nur {expected_qty} {unit} haben. Hast du Bestand ohne Buchung hinzugefĂĽgt?",
+ "banner_anomaly_untracked_title": "Anfangsbestand nicht als Eingang gebucht",
+ "banner_anomaly_untracked_detail": "Du hast {inv_qty} {unit} im Bestand, aber die gebuchten Abgänge übersteigen die Eingänge — der Anfangsbestand wurde wahrscheinlich nie als \"Eingang\" erfasst. Bitte korrigiere die Menge oder trage die fehlenden Eingänge nach."
+,
"banner_anomaly_ghost_title": "weniger Bestand als erwartet",
"banner_anomaly_ghost_detail": "Laut Buchungen solltest du {expected_qty} {unit} von {name} haben, aber der Bestand zeigt nur {inv_qty} {unit}. Hast du etwas ohne Buchung entnommen?",
"consumed": "Verbraucht: {n} ({pct}%)",
diff --git a/translations/en.json b/translations/en.json
index ccfe85d..b1bb40f 100644
--- a/translations/en.json
+++ b/translations/en.json
@@ -128,6 +128,8 @@
"banner_finished_check": "Can you check?",
"banner_anomaly_phantom_title": "you have more stock than expected",
"banner_anomaly_phantom_detail": "Inventory shows {inv_qty} {unit}, but based on records you should only have {expected_qty} {unit}. Did you add stock without recording it?",
+ "banner_anomaly_untracked_title": "stock not recorded as an entry",
+ "banner_anomaly_untracked_detail": "You have {inv_qty} {unit} in inventory, but recorded outflows exceed inflows — the initial stock was likely never added as an \"in\" transaction. You can correct the quantity or log the missing entries.",
"banner_anomaly_ghost_title": "you have less stock than expected",
"banner_anomaly_ghost_detail": "Based on recorded operations you should have {expected_qty} {unit} of {name}, but inventory shows only {inv_qty} {unit}. Did you take stock without recording it?",
"consumed": "Consumed: {n} ({pct}%)",
diff --git a/translations/it.json b/translations/it.json
index 2c6b36f..728cb5f 100644
--- a/translations/it.json
+++ b/translations/it.json
@@ -128,6 +128,8 @@
"banner_finished_check": "Puoi controllare?",
"banner_anomaly_phantom_title": "hai piĂą scorte del previsto",
"banner_anomaly_phantom_detail": "L'inventario segna {inv_qty} {unit}, ma in base alle registrazioni ne dovresti avere solo {expected_qty} {unit}. Hai aggiunto scorte senza registrarle?",
+ "banner_anomaly_untracked_title": "scorte non registrate come entrata",
+ "banner_anomaly_untracked_detail": "Hai {inv_qty} {unit} in inventario, ma le uscite registrate superano le entrate — le scorte iniziali probabilmente non sono mai state aggiunte come entrata. Puoi correggere la quantità o registrare le entrate mancanti.",
"banner_anomaly_ghost_title": "hai meno scorte del previsto",
"banner_anomaly_ghost_detail": "In base alle operazioni registrate dovresti avere {expected_qty} {unit} di {name}, ma l'inventario mostra solo {inv_qty} {unit}. Hai prelevato senza registrarlo?",
"consumed": "Consumati: {n} ({pct}%)",