From ed1358d7562476362dbcc7a61e4f16f4bcdf388a Mon Sep 17 00:00:00 2001 From: BEKO2210 Date: Mon, 24 Aug 2026 11:47:42 +0000 Subject: [PATCH 1/4] fix(ui): Touch-Ziele auf 44px und Ausrichtung bei 412px Gemessen mit Playwright bei 412x915 (entspricht dem Samsung A15). Vorher unter 44px: Lagerort-Loeschen 26x26, Listen-Aktionen 32x32, Rechtstexte-Links 24px, Sync-Buttons 36px, Formular-Buttons 38-42px. Jetzt: 0 Elemente unter 44px auf allen Tabs und im Produktformular. - min-h/min-w 44px fuer alle Buttons, Links, Inputs und Selects - Icon-Zeile der Produktkarten linksbuendig zum Text (-ms-3) - "Archiv anzeigen" und "Alle" rechtsbuendig zu den Karten (-me-2) - Hauptbereich: Innenabstand unten auf 7.5rem + safe-area, damit die letzte Karte nicht hinter der Navigationsleiste liegt - Leerer Zustand: beide Buttons gleich breit, Sekundaerbutton in Markenfarbe statt Grau - MHD-Verteilung: Legende zaehlt jetzt auch "kritisch" mit, Legendentext von 9.6px auf 12px - Kategorien-Karte streckt sich nicht mehr auf Zeilenhoehe Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01DQtq3HymU7S6JrHKY8dpzU --- src/App.tsx | 2 +- src/components/Dashboard.tsx | 20 +++++++++---------- src/components/ProductForm.tsx | 10 +++++----- src/components/ProductList.tsx | 36 +++++++++++++++++----------------- src/components/Settings.tsx | 30 ++++++++++++++-------------- 5 files changed, 49 insertions(+), 49 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 948e18f..a8d63bb 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -103,7 +103,7 @@ export default function App() { -
+
{/* No AnimatePresence / mode="wait": exit-gated transitions can deadlock on rapid tab switches and leave the page blank. A plain keyed fade-in remounts the page on navigation — the old page diff --git a/src/components/Dashboard.tsx b/src/components/Dashboard.tsx index 3ec670b..0638b78 100644 --- a/src/components/Dashboard.tsx +++ b/src/components/Dashboard.tsx @@ -144,12 +144,12 @@ export function Dashboard() {

{t('dashboard.noProducts')}

{t('dashboard.noProductsDesc')}

-
- - @@ -263,9 +263,9 @@ export function Dashboard() { {stats.soonCount > 0 &&
} {stats.goodCount > 0 &&
}
-
+
{t('dashboard.expired_count', { count: stats.expiredCount })} - {t('dashboard.warning_count', { count: stats.warningCount + stats.soonCount })} + {t('dashboard.warning_count', { count: stats.criticalCount + stats.warningCount + stats.soonCount })} {t('dashboard.ok_count', { count: stats.goodCount })}
@@ -278,7 +278,7 @@ export function Dashboard() { title={t('dashboard.urgent')} tone="orange" action={ - } @@ -302,8 +302,8 @@ export function Dashboard() {
{categoryBreakdown.length > 0 && ( -
-

{t('dashboard.categories')}

+
+

{t('dashboard.categories')}

{categoryBreakdown.map(({ key, label, count }) => (
@@ -318,12 +318,12 @@ export function Dashboard() {
- {t('dashboard.lowStock')} + {t('dashboard.lowStock')}

0 ? 'text-yellow-400' : 'text-gray-300'}`}>

- {t('dashboard.storageLocations')} + {t('dashboard.storageLocations')}

diff --git a/src/components/ProductForm.tsx b/src/components/ProductForm.tsx index 41a70f0..1cf8301 100644 --- a/src/components/ProductForm.tsx +++ b/src/components/ProductForm.tsx @@ -245,7 +245,7 @@ function InlineScanner({ onScanned, autoStart = false }: { onScanned: (data: { b @@ -471,7 +471,7 @@ function DateScanner({ onResult }: { onResult: (parsed: ParsedExpiry) => void })
@@ -750,10 +750,10 @@ export function ProductForm() {
) : (
- -
diff --git a/src/components/ProductList.tsx b/src/components/ProductList.tsx index 9e2dee8..8271625 100644 --- a/src/components/ProductList.tsx +++ b/src/components/ProductList.tsx @@ -148,7 +148,7 @@ export function ProductList() {

{showArchived ? t('products.archive') : t('products.title')}

-
@@ -161,7 +161,7 @@ export function ProductList() { placeholder={t('products.searchPlaceholder')} value={filters.search} onChange={(e) => setFilter('search', e.target.value)} - className={`w-full rounded-lg border border-primary-600 bg-primary-800 py-2 ps-10 text-gray-200 placeholder-gray-500 focus:border-green-500 focus:outline-none ${filters.search ? 'pe-10' : 'pe-4'}`} + className={`min-h-[44px] w-full rounded-lg border border-primary-600 bg-primary-800 py-2 ps-10 text-gray-200 placeholder-gray-500 focus:border-green-500 focus:outline-none ${filters.search ? 'pe-10' : 'pe-4'}`} /> {filters.search && (
- setFilter('category', e.target.value)} className="min-h-[44px] rounded-lg border border-primary-600 bg-primary-900 px-3 py-2 text-sm text-gray-300 focus:border-green-500 focus:outline-none"> {(['konserven', 'wasser', 'medizin', 'werkzeug', 'hygiene', 'lebensmittel', 'getranke', 'elektronik', 'kleidung', 'sonstiges'] as ProductCategory[]).map((key) => ( ))} - setFilter('location', e.target.value)} className="min-h-[44px] rounded-lg border border-primary-600 bg-primary-900 px-3 py-2 text-sm text-gray-300 focus:border-green-500 focus:outline-none"> {locations.map((loc) => ())} - setFilter('status', e.target.value)} className="min-h-[44px] rounded-lg border border-primary-600 bg-primary-900 px-3 py-2 text-sm text-gray-300 focus:border-green-500 focus:outline-none"> @@ -273,21 +273,21 @@ export function ProductList() { )}
{!showArchived && ( -
- - -
)} {showArchived && ( -
-
@@ -298,8 +298,8 @@ export function ProductList() {
{t('products.confirmDelete')}
- - + +
)} @@ -443,14 +443,14 @@ function ConsumeModal({ productId, products, onConfirm, onClose }: { productId: if (val < step || (fraction < 1 && val === max)) return null; const label = fraction === 1 ? t('consume.allQuick') : `${Math.round(fraction * 100)}%`; return ( - + ); })}
{isAll &&

{t('consume.archiveWarning')}

}
diff --git a/src/components/Settings.tsx b/src/components/Settings.tsx index 85fbcc2..8d801d1 100644 --- a/src/components/Settings.tsx +++ b/src/components/Settings.tsx @@ -288,7 +288,7 @@ export function Settings() {
@@ -531,9 +531,9 @@ export function Settings() { deleteStorageLocation(loc.id!); }} aria-label={t('settings.deleteLocation', { name: loc.name })} - className="rounded p-1.5 text-gray-400 transition-colors hover:bg-primary-600 hover:text-red-400" + className="flex min-h-[44px] min-w-[44px] items-center justify-center rounded-lg text-gray-400 transition-colors hover:bg-primary-600 hover:text-red-400" > - +
))} @@ -658,7 +658,7 @@ export function Settings() { value={syncServerUrl} onChange={(e) => setSyncServerUrl(e.target.value)} placeholder="http://192.168.0.20:8787" - className="w-full rounded-lg border border-primary-600 bg-primary-900 px-3 py-2 text-sm text-gray-200 placeholder-gray-500 focus:border-sky-500 focus:outline-none" + className="min-h-[44px] w-full rounded-lg border border-primary-600 bg-primary-900 px-3 py-2 text-sm text-gray-200 placeholder-gray-500 focus:border-sky-500 focus:outline-none" />
@@ -669,7 +669,7 @@ export function Settings() { value={syncDeviceName} onChange={(e) => setSyncDeviceName(e.target.value)} placeholder={t('sync.deviceNamePlaceholder')} - className="w-full rounded-lg border border-primary-600 bg-primary-900 px-3 py-2 text-sm text-gray-200 placeholder-gray-500 focus:border-sky-500 focus:outline-none" + className="min-h-[44px] w-full rounded-lg border border-primary-600 bg-primary-900 px-3 py-2 text-sm text-gray-200 placeholder-gray-500 focus:border-sky-500 focus:outline-none" /> @@ -681,7 +681,7 @@ export function Settings() { value={syncCode} onChange={(e) => setSyncCode(e.target.value)} placeholder={t('sync.syncCodePlaceholder')} - className="w-full rounded-lg border border-primary-600 bg-primary-900 px-3 py-2 text-sm text-gray-200 placeholder-gray-500 focus:border-sky-500 focus:outline-none" + className="min-h-[44px] w-full rounded-lg border border-primary-600 bg-primary-900 px-3 py-2 text-sm text-gray-200 placeholder-gray-500 focus:border-sky-500 focus:outline-none" /> )} @@ -689,7 +689,7 @@ export function Settings() {
@@ -698,7 +698,7 @@ export function Settings() { @@ -706,7 +706,7 @@ export function Settings() { @@ -822,7 +822,7 @@ export function Settings() {
); } diff --git a/src/components/SectionHeader.tsx b/src/components/SectionHeader.tsx index 20e76b0..999f9f5 100644 --- a/src/components/SectionHeader.tsx +++ b/src/components/SectionHeader.tsx @@ -3,14 +3,16 @@ import type { LucideIcon } from 'lucide-react'; type Tone = 'green' | 'blue' | 'orange' | 'yellow' | 'purple' | 'cyan' | 'red'; +/* Struktur spricht in Messing, Farbe bleibt dem Status vorbehalten: + nur "orange" und "red" faerben wirklich, alles andere ist Beschriftung. */ const TONES: Record = { - green: 'bg-green-500/15 text-green-400', - blue: 'bg-blue-500/15 text-blue-400', - orange: 'bg-orange-500/15 text-orange-400', - yellow: 'bg-yellow-500/15 text-yellow-400', - purple: 'bg-purple-500/15 text-purple-400', - cyan: 'bg-cyan-500/15 text-cyan-400', - red: 'bg-red-500/15 text-red-400', + green: 'text-[color:var(--pt-accent)]', + blue: 'text-[color:var(--pt-accent)]', + orange: 'text-[color:var(--pt-warn)]', + yellow: 'text-[color:var(--pt-accent)]', + purple: 'text-[color:var(--pt-accent)]', + cyan: 'text-[color:var(--pt-accent)]', + red: 'text-[color:var(--pt-crit)]', }; interface SectionHeaderProps { @@ -22,16 +24,15 @@ interface SectionHeaderProps { className?: string; } -/** Consistent section header: a tinted icon badge + title (matches the score page). */ +/** Abschnittskopf im Inventarblatt-Stil: Symbol, Versalien-Beschriftung, feine Linie. */ export function SectionHeader({ icon: Icon, title, tone = 'green', action, className = 'mb-3' }: SectionHeaderProps) { + const toneClass = TONES[tone]; + return ( -
-
- - - -

{title}

-
+
+ +

{title}

+
); diff --git a/src/index.css b/src/index.css index 37cc1dd..1df1435 100644 --- a/src/index.css +++ b/src/index.css @@ -58,6 +58,50 @@ } } +/* ===== Gestaltungs-Grundlagen "Lagerlogbuch" ===== + Akzent = Messing/Khaki (Konservendeckel) fuer Beschriftungen und Struktur, + Rot/Orange/Gruen bleiben ausschliesslich Statusfarben. + Zahlen und Datumsangaben laufen in JetBrains Mono wie auf einem Inventarblatt. */ +:root { + --pt-accent: #d1bf84; + --pt-accent-soft: rgba(209, 191, 132, 0.14); + --pt-crit: #f26d5b; + --pt-warn: #e8763a; + --pt-ok: #4ade80; +} + +html:not(.dark) { + --pt-accent: #6e6330; + --pt-accent-soft: rgba(110, 99, 48, 0.1); +} + +@layer components { + /* Kleine Versalien-Beschriftung ueber Abschnitten und Kennzahlen */ + .eyebrow { + font-family: 'Bebas Neue', sans-serif; + text-transform: uppercase; + letter-spacing: 0.16em; + font-size: 0.8125rem; + line-height: 1; + color: var(--pt-accent); + } + + /* Seitentitel und Kachel-Ueberschriften */ + .title-display { + font-family: 'Bebas Neue', sans-serif; + text-transform: uppercase; + letter-spacing: 0.05em; + line-height: 0.95; + } + + /* Alle Zahlen, Mengen, Datumsangaben */ + .num { + font-family: 'JetBrains Mono', monospace; + font-variant-numeric: tabular-nums; + letter-spacing: -0.02em; + } +} + @layer utilities { .no-scrollbar::-webkit-scrollbar { display: none; diff --git a/tailwind.config.ts b/tailwind.config.ts index 5b03650..c123ca4 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -13,10 +13,10 @@ export default { 300: '#6ca688', 400: '#4d936f', 500: '#2e8056', - 600: '#27744c', - 700: '#1e6540', - 800: '#1a3a2a', - 900: '#0f1f17', + 600: '#33493b', + 700: '#26382d', + 800: '#141f19', + 900: '#0b110e', }, olive: { 100: '#e8e4d0', From 53b9bb7788165ff89c0e1fbb56ffa07f0980d632 Mon Sep 17 00:00:00 2001 From: BEKO2210 Date: Mon, 24 Aug 2026 12:21:04 +0000 Subject: [PATCH 3/4] feat(ui): Gestaltungssystem "Lagerlogbuch" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Die App liest sich jetzt wie ein Inventarblatt statt wie ein Standard-Dashboard: - Farbfundament: Flaechen deutlich tiefer (primary-600..900 neu), ein Messing-Akzent (--pt-accent, aus der vorhandenen Khaki-Reihe) traegt alle Beschriftungen und Struktur. Rot/Orange/Gruen sind nur noch Statusfarben — die Regenbogen-Icons (blau/lila/cyan/gelb) in Dashboard, Einstellungen und Featurelisten sind raus. - Typografie: Bebas Neue fuer Seitentitel, Abschnitts-Beschriftungen (.eyebrow) und die Navigation; JetBrains Mono mit Tabellenziffern (.num) fuer alle Zahlen, Mengen und Datumsangaben. line-height 1.1, damit Umlaut-Punkte (VORRAETE) nicht clippen. - Kopfzeile: Wortmarke in Versalien plus aktiver Produktbestand rechts — die eine Zahl, die immer zaehlt. - Dashboard: vier StatRinge + separater MHD-Balken zeigten dieselben Daten doppelt; zusammengelegt zu einem Lagerstand-Panel (Gesamtzahl, segmentierter Balken, Legende mit Mono-Zahlen). - SectionHeader: Icon + Versalien-Label + feine Linie statt bunter Icon-Kacheln. - Statistik: Kategorie-/Lagerort-Balken einheitlich Messing; bg-[...]/70 auf CSS-Variable erzeugte gar keine Klasse — die Balken waren unsichtbar. Jetzt opacity-80. Messstand (Playwright 412x915): 0 Touch-Ziele unter 44px, kein Querscrollen, keine Konsolenfehler; tsc sauber, 110/110 Tests gruen. Auf dem Samsung A15 gegengeprueft. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01DQtq3HymU7S6JrHKY8dpzU --- src/components/Dashboard.tsx | 94 ++++++++++++++++---------------- src/components/Navigation.tsx | 2 +- src/components/Preparedness.tsx | 2 +- src/components/ProductForm.tsx | 2 +- src/components/ProductList.tsx | 10 ++-- src/components/Settings.tsx | 28 +++++----- src/components/Statistics.tsx | 42 +++++++------- src/generated/release-notes.json | 12 ++-- src/index.css | 2 +- 9 files changed, 99 insertions(+), 95 deletions(-) diff --git a/src/components/Dashboard.tsx b/src/components/Dashboard.tsx index 0638b78..be5ebe6 100644 --- a/src/components/Dashboard.tsx +++ b/src/components/Dashboard.tsx @@ -180,15 +180,15 @@ export function Dashboard() { {/* Feature-Übersicht */}
-

{t('onboarding.features')}

+

{t('onboarding.features')}

{[ - { icon: , text: t('onboarding.featureOffline') }, - { icon: , text: t('onboarding.featureCamera') }, - { icon: , text: t('onboarding.featureImages') }, - { icon: , text: t('onboarding.featureNotifications') }, - { icon: , text: t('onboarding.featureExport') }, - { icon: , text: t('onboarding.featurePrivacy') }, + { icon: , text: t('onboarding.featureOffline') }, + { icon: , text: t('onboarding.featureCamera') }, + { icon: , text: t('onboarding.featureImages') }, + { icon: , text: t('onboarding.featureNotifications') }, + { icon: , text: t('onboarding.featureExport') }, + { icon: , text: t('onboarding.featurePrivacy') }, ].map((item, i) => (
{item.icon} @@ -203,12 +203,30 @@ export function Dashboard() { return (
-
-
- - - - + {/* Lagerstand: eine Zahl, ein Balken, eine Legende — statt vier Ringen + plus separatem Verteilungsbalken mit denselben Daten. */} +
+ +
+

+

{t('dashboard.total')}

+
+
+ {stats.expiredCount + stats.criticalCount > 0 &&
} + {stats.warningCount + stats.soonCount > 0 &&
} + {stats.goodCount > 0 &&
} + {total === 0 &&
} +
+
+ 0 ? 'text-[color:var(--pt-crit)]' : 'text-gray-500'}> + {stats.expiredCount + stats.criticalCount} {t('dashboard.critical')} + + 0 ? 'text-[color:var(--pt-warn)]' : 'text-gray-500'}> + {stats.warningCount + stats.soonCount} {t('dashboard.soon')} + + 0 ? 'text-[color:var(--pt-ok)]' : 'text-gray-500'}> + {stats.goodCount} {t('dashboard.good')} +
@@ -219,8 +237,8 @@ export function Dashboard() {
- - {t('preparedness.cardTitle')} + + {t('preparedness.cardTitle')}

{preparedness.survivalDays !== null @@ -234,8 +252,8 @@ export function Dashboard() {

- {stats.totalProducts > 0 && ( -
- -
- {stats.expiredCount > 0 &&
} - {stats.criticalCount > 0 &&
} - {stats.warningCount > 0 &&
} - {stats.soonCount > 0 &&
} - {stats.goodCount > 0 &&
} -
-
- {t('dashboard.expired_count', { count: stats.expiredCount })} - {t('dashboard.warning_count', { count: stats.criticalCount + stats.warningCount + stats.soonCount })} - {t('dashboard.ok_count', { count: stats.goodCount })} -
-
- )} - {urgentProducts.length > 0 && (

{product.name}

-

{product.storageLocation} · {formatDate(product.expiryDate, product.expiryPrecision)}

+

{product.storageLocation} · {formatDate(product.expiryDate, product.expiryPrecision)}

- {formatDaysUntil(product.daysLeft)} + {formatDaysUntil(product.daysLeft)}
))} @@ -302,13 +302,13 @@ export function Dashboard() {
{categoryBreakdown.length > 0 && ( -
-

{t('dashboard.categories')}

+
+

{t('dashboard.categories')}

{categoryBreakdown.map(({ key, label, count }) => (
{label} - {count} + {count}
))}
@@ -317,14 +317,14 @@ export function Dashboard() {
- - {t('dashboard.lowStock')} + 0 ? 'text-[color:var(--pt-warn)]' : 'text-[color:var(--pt-accent)]'} /> + {t('dashboard.lowStock')}
-

0 ? 'text-yellow-400' : 'text-gray-300'}`}>

+

0 ? 'text-[color:var(--pt-warn)]' : 'text-gray-300'}`}>

- {t('dashboard.storageLocations')} -

+ {t('dashboard.storageLocations')} +

diff --git a/src/components/Navigation.tsx b/src/components/Navigation.tsx index e4d5f45..07f8b92 100644 --- a/src/components/Navigation.tsx +++ b/src/components/Navigation.tsx @@ -50,7 +50,7 @@ function NavItem({ label, icon: Icon, isActive, onClick }: NavItemProps) { > - {label} + {label} ); } diff --git a/src/components/Preparedness.tsx b/src/components/Preparedness.tsx index 41f8ef3..60a54dc 100644 --- a/src/components/Preparedness.tsx +++ b/src/components/Preparedness.tsx @@ -137,7 +137,7 @@ export function Preparedness() {
-

{t('preparedness.title')}

+

{t('preparedness.title')}

{t('preparedness.subtitle')}

diff --git a/src/components/ProductForm.tsx b/src/components/ProductForm.tsx index 1cf8301..0f1c759 100644 --- a/src/components/ProductForm.tsx +++ b/src/components/ProductForm.tsx @@ -720,7 +720,7 @@ export function ProductForm() { )} -

+

{editingProductId ? t('form.editTitle') : t('form.addTitle')}

diff --git a/src/components/ProductList.tsx b/src/components/ProductList.tsx index 8271625..0802198 100644 --- a/src/components/ProductList.tsx +++ b/src/components/ProductList.tsx @@ -145,10 +145,10 @@ export function ProductList() { return (
-

+

{showArchived ? t('products.archive') : t('products.title')}

-
@@ -231,7 +231,7 @@ export function ProductList() {
)} -

+

{t('products.productCount', { count: filtered.length })}

@@ -266,8 +266,8 @@ export function ProductList() {
- {t('products.mhd')}: {formatDate(product.expiryDate, product.expiryPrecision)} ({formatDaysUntil(product.daysLeft)}) - {product.quantity} {product.unit} + {t('products.mhd')}: {formatDate(product.expiryDate, product.expiryPrecision)} ({formatDaysUntil(product.daysLeft)}) + {product.quantity} {product.unit} {product.minStock !== undefined && product.minStock > 0 && product.quantity < product.minStock && ( {t('products.lowStockWarning', { min: product.minStock })} )} diff --git a/src/components/Settings.tsx b/src/components/Settings.tsx index 8d801d1..83ef438 100644 --- a/src/components/Settings.tsx +++ b/src/components/Settings.tsx @@ -281,7 +281,7 @@ export function Settings() { return (
-

{t('settings.title')}

+

{t('settings.title')}

{/* Über PrepTrack / Info */} @@ -300,12 +300,12 @@ export function Settings() {
{[ - { icon: , text: t('onboarding.featureOffline') }, + { icon: , text: t('onboarding.featureOffline') }, { icon: , text: t('onboarding.featureCamera') }, - { icon: , text: t('onboarding.featureImages') }, - { icon: , text: t('onboarding.featureNotifications') }, + { icon: , text: t('onboarding.featureImages') }, + { icon: , text: t('onboarding.featureNotifications') }, { icon: , text: t('onboarding.featureExport') }, - { icon: , text: t('onboarding.featurePrivacy') }, + { icon: , text: t('onboarding.featurePrivacy') }, ].map((item, i) => (
{item.icon} @@ -320,7 +320,7 @@ export function Settings() { {/* Language */}

- + {t('settings.language')}

@@ -353,7 +353,7 @@ export function Settings() {

{t('settings.iosInstallHint')}{' '} - {' '} + {' '} {t('settings.iosShare')}{' '} "{t('settings.iosHomeScreen')}".

@@ -397,7 +397,7 @@ export function Settings() { {/* Appearance */}

- + {t('settings.appearance')}

- {installError && ( -

- {installError} -

- )} - {!isInstallable && ( -

- {t('settings.installTip')} -

- )} -
- )} -
- )} - - {isInstalled && ( -
-
- - {t('settings.appInstalled')} -
-
- )} {/* Appearance */}
diff --git a/src/i18n/locales/ar/translation.json b/src/i18n/locales/ar/translation.json index 9021a03..6557279 100644 --- a/src/i18n/locales/ar/translation.json +++ b/src/i18n/locales/ar/translation.json @@ -52,7 +52,7 @@ "confirmDelete": "هل تريد الحذف فعلاً؟ لا يمكن التراجع.", "deleteBtn": "حذف", "cancel": "إلغاء", - "noFilterResults": "لا توجد نتائج لهذه الفلاتر.", + "noFilterResults": "لا توجد نتائج — عدّل البحث أو عوامل التصفية.", "archiveEmpty": "الأرشيف فارغ.", "noProducts": "لم يتم تسجيل أي منتجات بعد.", "lowStockWarning": "مخزون منخفض (الحد الأدنى: {{min}})", diff --git a/src/i18n/locales/de/translation.json b/src/i18n/locales/de/translation.json index a5d4133..d3863a7 100644 --- a/src/i18n/locales/de/translation.json +++ b/src/i18n/locales/de/translation.json @@ -52,7 +52,7 @@ "confirmDelete": "Wirklich löschen? Nicht rückgängig machbar.", "deleteBtn": "Löschen", "cancel": "Abbrechen", - "noFilterResults": "Kein Treffer für diese Filter.", + "noFilterResults": "Nichts gefunden — Suche oder Filter anpassen.", "archiveEmpty": "Archiv ist leer.", "noProducts": "Noch keine Produkte erfasst.", "lowStockWarning": "Unterbestand (Min: {{min}})", diff --git a/src/i18n/locales/en/translation.json b/src/i18n/locales/en/translation.json index ed3f0d7..b20ec51 100644 --- a/src/i18n/locales/en/translation.json +++ b/src/i18n/locales/en/translation.json @@ -52,7 +52,7 @@ "confirmDelete": "Really delete? This cannot be undone.", "deleteBtn": "Delete", "cancel": "Cancel", - "noFilterResults": "No results for these filters.", + "noFilterResults": "Nothing found — adjust your search or filters.", "archiveEmpty": "Archive is empty.", "noProducts": "No products added yet.", "lowStockWarning": "Low stock (Min: {{min}})", diff --git a/src/i18n/locales/fr/translation.json b/src/i18n/locales/fr/translation.json index dbb7016..6ff5d23 100644 --- a/src/i18n/locales/fr/translation.json +++ b/src/i18n/locales/fr/translation.json @@ -52,7 +52,7 @@ "confirmDelete": "Vraiment supprimer ? Cette action est irréversible.", "deleteBtn": "Supprimer", "cancel": "Annuler", - "noFilterResults": "Aucun résultat pour ces filtres.", + "noFilterResults": "Aucun résultat — ajustez la recherche ou les filtres.", "archiveEmpty": "Les archives sont vides.", "noProducts": "Aucun produit ajouté encore.", "lowStockWarning": "Stock faible (Min : {{min}})", diff --git a/src/i18n/locales/it/translation.json b/src/i18n/locales/it/translation.json index cb55f89..fbf42d3 100644 --- a/src/i18n/locales/it/translation.json +++ b/src/i18n/locales/it/translation.json @@ -52,7 +52,7 @@ "confirmDelete": "Eliminare davvero? Non si può annullare.", "deleteBtn": "Elimina", "cancel": "Annulla", - "noFilterResults": "Nessun risultato per questi filtri.", + "noFilterResults": "Nessun risultato — modifica la ricerca o i filtri.", "archiveEmpty": "L'archivio è vuoto.", "noProducts": "Nessun prodotto aggiunto ancora.", "lowStockWarning": "Scorte basse (Min: {{min}})", diff --git a/src/i18n/locales/pt/translation.json b/src/i18n/locales/pt/translation.json index 2b3b24f..e30895e 100644 --- a/src/i18n/locales/pt/translation.json +++ b/src/i18n/locales/pt/translation.json @@ -52,7 +52,7 @@ "confirmDelete": "Realmente excluir? Não pode ser desfeito.", "deleteBtn": "Excluir", "cancel": "Cancelar", - "noFilterResults": "Nenhum resultado para estes filtros.", + "noFilterResults": "Nada encontrado — ajusta a pesquisa ou os filtros.", "archiveEmpty": "Arquivo vazio.", "noProducts": "Nenhum produto cadastrado.", "lowStockWarning": "Estoque baixo (Mín: {{min}})",