- DRAMLOG
+
+ DRAMLOG
-
- Premium Digitaler Tasting Begleiter für Genießer. +
+ Modern Minimalist Tasting Tool.
- DRAMLOG
+
+ DRAMLOG
{activeSession && (
-
-
+
+
-
+
Live: {activeSession.name}
@@ -195,7 +195,7 @@ export default function Home() {
{t('home.logout')}
@@ -206,7 +206,7 @@ export default function Home() {
-
+
@@ -215,27 +215,27 @@ export default function Home() {
-
+
-
+
Collection
-
+
{bottles.length} Bottles
{isLoading ? (
-
+
) : fetchError ? (
-
- {t('common.error')}
- {fetchError}
+
+ {t('common.error')}
+ {fetchError}
{t('home.reTry')}
diff --git a/src/components/ActiveSessionBanner.tsx b/src/components/ActiveSessionBanner.tsx
index 254eb6a..1cc8dce 100644
--- a/src/components/ActiveSessionBanner.tsx
+++ b/src/components/ActiveSessionBanner.tsx
@@ -14,7 +14,7 @@ export default function ActiveSessionBanner() {
return (
-
+
-
+
diff --git a/src/components/AvatarStack.tsx b/src/components/AvatarStack.tsx
index 85e4040..5161103 100644
--- a/src/components/AvatarStack.tsx
+++ b/src/components/AvatarStack.tsx
@@ -30,7 +30,7 @@ export default function AvatarStack({ names, limit = 3, size = 'sm' }: AvatarSta
{visibleNames.map((name, i) => (
{getInitials(name)}
diff --git a/src/components/BottleDetails.tsx b/src/components/BottleDetails.tsx
index 23cada4..5db25ae 100644
--- a/src/components/BottleDetails.tsx
+++ b/src/components/BottleDetails.tsx
@@ -24,7 +24,7 @@ export default function BottleDetails({ bottleId, sessionId, userId }: BottleDet
if (loading) {
return (
-
+
{t('common.loading')}
);
@@ -42,7 +42,7 @@ export default function BottleDetails({ bottleId, sessionId, userId }: BottleDet
Inhalte konnten nicht geladen werden. Bitte stelle eine Internetverbindung her, um diese Flasche zum ersten Mal zu laden.
-
+
Zurück zum Vault
@@ -56,22 +56,22 @@ export default function BottleDetails({ bottleId, sessionId, userId }: BottleDet
{/* Back Button */}
Zurück zur Sammlung
{isOffline && (
-
-
- Offline-Modus: Daten aus dem Cache
+
+
+ Offline-Modus: Daten aus dem Cache
)}
{/* Hero Section */}
-
+
-
+
{bottle.name}
-
{bottle.distillery}
+ {bottle.distillery}
{bottle.whiskybase_id && (
@@ -92,9 +92,9 @@ export default function BottleDetails({ bottleId, sessionId, userId }: BottleDet
href={`https://www.whiskybase.com/whiskies/whisky/${bottle.whiskybase_id}`}
target="_blank"
rel="noopener noreferrer"
- className="inline-flex items-center gap-2 px-4 py-2 bg-[#db0000] text-white rounded-xl text-sm font-bold shadow-lg shadow-red-600/20 hover:scale-[1.05] transition-transform"
+ className="inline-flex items-center gap-2 px-4 py-2 bg-zinc-900 text-zinc-400 border border-zinc-800 rounded-xl text-xs font-bold hover:text-orange-600 transition-colors"
>
-
+
Whiskybase ID: {bottle.whiskybase_id}
@@ -102,59 +102,59 @@ export default function BottleDetails({ bottleId, sessionId, userId }: BottleDet
-
+
-
+
Kategorie
- {bottle.category || '-'}
+ {bottle.category || '-'}
-
-
+
+
Alkoholgehalt
- {bottle.abv}% Vol.
+ {bottle.abv}% Vol.
-
-
+
+
Alter
- {bottle.age ? `${bottle.age} J.` : '-'}
+ {bottle.age ? `${bottle.age} J.` : '-'}
{bottle.distilled_at && (
-
-
+
+
Destilliert
- {bottle.distilled_at}
+ {bottle.distilled_at}
)}
{bottle.bottled_at && (
-
-
+
+
Abgefüllt
- {bottle.bottled_at}
+ {bottle.bottled_at}
)}
{bottle.batch_info && (
-
-
+
+
Batch / Code
- {bottle.batch_info}
+ {bottle.batch_info}
)}
-
-
+
+
Letzter Dram
-
+
{tastings && tastings.length > 0
? new Date(tastings[0].created_at).toLocaleDateString('de-DE')
: 'Noch nie'}
@@ -164,9 +164,9 @@ export default function BottleDetails({ bottleId, sessionId, userId }: BottleDet
{isOffline ? (
-
-
- Bearbeiten & Löschen nur online möglich
+
+
+ Bearbeiten & Löschen nur online möglich
) : (
<>
@@ -178,21 +178,21 @@ export default function BottleDetails({ bottleId, sessionId, userId }: BottleDet
-
+
{/* Tasting Notes Section */}
- Tasting Notes
+ Tasting Notes
Hier findest du deine bisherigen Eindrücke.
{/* Form */}
-
-
+
+
Dram bewerten
diff --git a/src/components/BottleGrid.tsx b/src/components/BottleGrid.tsx
index 248f105..a061d18 100644
--- a/src/components/BottleGrid.tsx
+++ b/src/components/BottleGrid.tsx
@@ -36,71 +36,65 @@ function BottleCard({ bottle, sessionId }: BottleCardProps) {
return (
- {/* Image Layer - Edge to Edge */}
-
+ {/* Image Layer - Clean Split Top */}
+
-
- {/* Gradient Overlay as requested: bottom third, black to transparent */}
-
- {/* Content Layer */}
-
-
- {/* Tags Layer - Minimalist Glassmorphism */}
-
-
- {shortenCategory(bottle.category)}
-
-
- {bottle.abv}% VOL
-
-
+ {/* Info Layer - Clean Split Bottom */}
+
+
+
+ {bottle.distillery}
+
+
+ {bottle.name || t('grid.unknownBottle')}
+
+
-
-
- {bottle.distillery}
-
-
- {bottle.name || t('grid.unknownBottle')}
-
-
+
+
+ {shortenCategory(bottle.category)}
+
+
+ {bottle.abv}% VOL
+
+
- {/* Metadata items */}
-
-
-
- {new Date(bottle.created_at).toLocaleDateString(locale === 'de' ? 'de-DE' : 'en-US')}
+ {/* Metadata items */}
+
+
+
+ {new Date(bottle.created_at).toLocaleDateString(locale === 'de' ? 'de-DE' : 'en-US')}
+
+ {bottle.last_tasted && (
+
+
+ {new Date(bottle.last_tasted).toLocaleDateString(locale === 'de' ? 'de-DE' : 'en-US')}
- {bottle.last_tasted && (
-
-
- {new Date(bottle.last_tasted).toLocaleDateString(locale === 'de' ? 'de-DE' : 'en-US')}
-
- )}
-
+ )}
{/* Top Overlays */}
{(bottle.is_whisky === false || (bottle.confidence && bottle.confidence < 70)) && (
-
-
-
+
+
+
)}
{sessionId && (
-
-
- ADD TO SESSION
+
+
+ ADD
)}
@@ -200,13 +194,13 @@ export default function BottleGrid({ bottles }: BottleGridProps) {
-
+
setSearchQuery(e.target.value)}
- className="w-full pl-8 pr-8 py-4 bg-transparent border-b border-white/10 focus:border-[#C89D46] outline-none transition-all text-white placeholder:text-[#8F9096] font-sans"
+ className="w-full pl-8 pr-8 py-4 bg-transparent border-b border-zinc-800 focus:border-orange-500 outline-none transition-all text-zinc-50 placeholder:text-zinc-500"
/>
{searchQuery && (
setSortBy(e.target.value as any)}
- className="bg-transparent border-none text-[#8F9096] text-xs font-sans font-bold uppercase tracking-widest outline-none cursor-pointer hover:text-white transition-colors appearance-none"
+ className="bg-transparent border-none text-zinc-500 text-xs font-bold uppercase tracking-widest outline-none cursor-pointer hover:text-white transition-colors appearance-none"
>
-
-
-
+
+
+
setIsFiltersOpen(!isFiltersOpen)}
- className={`flex items-center gap-2 text-xs font-sans font-bold uppercase tracking-widest transition-all ${isFiltersOpen || activeFiltersCount > 0
- ? 'text-[#C89D46]'
- : 'text-[#8F9096] hover:text-white'
+ className={`flex items-center gap-2 text-xs font-bold uppercase tracking-widest transition-all ${isFiltersOpen || activeFiltersCount > 0
+ ? 'text-orange-500'
+ : 'text-zinc-500 hover:text-white'
}`}
>
{t('grid.filters')}
{activeFiltersCount > 0 && (
-
+
{activeFiltersCount}
)}
@@ -247,13 +241,13 @@ export default function BottleGrid({ bottles }: BottleGridProps) {
- {/* Category Quick Filter - Glass Chips */}
+ {/* Category Quick Filter - Flat Chips */}
setSelectedCategory(null)}
- className={`px-4 py-2 rounded-full text-[10px] font-sans font-bold uppercase tracking-widest whitespace-nowrap transition-all border ${selectedCategory === null
- ? 'bg-[#C89D46] border-[#C89D46] text-[#0F1014]'
- : 'bg-white/5 border-white/10 text-[#8F9096] hover:border-white/20'
+ className={`px-4 py-2 rounded-full text-[10px] font-bold uppercase tracking-widest whitespace-nowrap transition-all border ${selectedCategory === null
+ ? 'bg-orange-600 border-orange-600 text-white'
+ : 'bg-zinc-900 border-zinc-800 text-zinc-400 hover:border-zinc-700'
}`}
>
{t('common.all')}
@@ -262,9 +256,9 @@ export default function BottleGrid({ bottles }: BottleGridProps) {
setSelectedCategory(selectedCategory === cat ? null : cat)}
- className={`px-4 py-2 rounded-full text-[10px] font-sans font-bold uppercase tracking-widest whitespace-nowrap transition-all border ${selectedCategory === cat
- ? 'bg-[#C89D46] border-[#C89D46] text-[#0F1014]'
- : 'bg-white/5 border-white/10 text-[#8F9096] hover:border-white/20'
+ className={`px-4 py-2 rounded-full text-[10px] font-bold uppercase tracking-widest whitespace-nowrap transition-all border ${selectedCategory === cat
+ ? 'bg-orange-600 border-orange-600 text-white'
+ : 'bg-zinc-900 border-zinc-800 text-zinc-400 hover:border-zinc-700'
}`}
>
{shortenCategory(cat)}
@@ -272,17 +266,17 @@ export default function BottleGrid({ bottles }: BottleGridProps) {
))}
- {/* Collapsible Advanced Filters - Minimalist Overlay */}
+ {/* Collapsible Advanced Filters - Industrial Overlay */}
{isFiltersOpen && (
-
+
-
+
setSelectedDistillery(null)}
- className={`px-4 py-2 rounded-full text-[10px] font-sans font-bold uppercase tracking-widest transition-all border ${selectedDistillery === null
- ? 'bg-[#C89D46] border-[#C89D46] text-[#0F1014]'
- : 'bg-white/5 border-white/10 text-[#8F9096]'
+ className={`px-4 py-2 rounded-full text-[10px] font-bold uppercase tracking-widest transition-all border ${selectedDistillery === null
+ ? 'bg-orange-600 border-orange-600 text-white'
+ : 'bg-zinc-800 border-zinc-700 text-zinc-400'
}`}
>
{t('common.all')}
@@ -291,9 +285,9 @@ export default function BottleGrid({ bottles }: BottleGridProps) {
setSelectedDistillery(selectedDistillery === dist ? null : dist)}
- className={`px-4 py-2 rounded-full text-[10px] font-sans font-bold uppercase tracking-widest transition-all border ${selectedDistillery === dist
- ? 'bg-[#C89D46] border-[#C89D46] text-[#0F1014]'
- : 'bg-white/5 border-white/10 text-[#8F9096]'
+ className={`px-4 py-2 rounded-full text-[10px] font-bold uppercase tracking-widest transition-all border ${selectedDistillery === dist
+ ? 'bg-orange-600 border-orange-600 text-white'
+ : 'bg-zinc-800 border-zinc-700 text-zinc-400'
}`}
>
{dist}
@@ -302,20 +296,20 @@ export default function BottleGrid({ bottles }: BottleGridProps) {
-
+
{
setSelectedCategory(null);
setSelectedDistillery(null);
setSearchQuery('');
}}
- className="text-[10px] font-sans font-bold text-red-500 uppercase tracking-widest hover:text-red-400"
+ className="text-[10px] font-bold text-red-500 uppercase tracking-widest hover:text-red-400"
>
{t('grid.resetAll')}
setIsFiltersOpen(false)}
- className="px-8 py-3 bg-white text-[#0F1014] text-[10px] font-sans font-bold rounded-full uppercase tracking-widest transition-transform active:scale-95"
+ className="px-8 py-3 bg-zinc-50 text-zinc-950 text-[10px] font-bold rounded-full uppercase tracking-widest transition-transform active:scale-95"
>
{t('grid.close')}
diff --git a/src/components/BottomNavigation.tsx b/src/components/BottomNavigation.tsx
index 8fe190e..39f847c 100644
--- a/src/components/BottomNavigation.tsx
+++ b/src/components/BottomNavigation.tsx
@@ -31,7 +31,7 @@ export const BottomNavigation = ({ onHome, onShelf, onSearch, onProfile, onScan
};
return (
-
+
{/* Hidden Input for Scanning */}
- {/* Background Container mit Glassmorphism */}
-
+
+ {/* Left Items */}
+
+
+
-
- {/* Left Actions */}
-
-
- Home
-
+
+
+
-
-
- Shelf
-
+ {/* PRIMARY ACTION - The "Industrial Button" */}
+
+
+
- {/* Spacer für den Center Button */}
-
-
- {/* Right Actions */}
-
-
- Search
-
-
-
-
- Admin
-
-
-
- {/* THE FLOATING MAGIC BUTTON */}
-
-
-
-
-
-
- {/* Visual Gold Glow */}
-
-
+ {/* Right Items */}
+
+
+
+
+
+
);
diff --git a/src/components/BuddyList.tsx b/src/components/BuddyList.tsx
index 4ba9208..4aebbcc 100644
--- a/src/components/BuddyList.tsx
+++ b/src/components/BuddyList.tsx
@@ -80,18 +80,18 @@ export default function BuddyList() {
};
return (
-
+
-
-
+
+
{t('buddy.title')}
{!isCollapsed && buddies.length > 0 && (
- ({buddies.length})
+ ({buddies.length})
)}
{isCollapsed ? : }
@@ -106,23 +106,23 @@ export default function BuddyList() {
value={newName}
onChange={(e) => setNewName(e.target.value)}
placeholder={t('buddy.placeholder')}
- className="flex-1 bg-white/5 border border-white/10 rounded-xl px-4 py-2 text-sm text-white placeholder:text-[#8F9096] focus:outline-none focus:border-[#C89D46] transition-colors"
+ className="flex-1 bg-zinc-950 border border-zinc-800 rounded-xl px-4 py-2 text-sm text-zinc-50 placeholder:text-zinc-600 focus:outline-none focus:border-orange-600 transition-colors"
/>
{isAdding ? : }
{isLoading ? (
-
+
) : buddies.length === 0 ? (
-
+
{t('buddy.noBuddies')}
) : (
@@ -130,22 +130,22 @@ export default function BuddyList() {
{buddies.map((buddy) => (
-
+
{buddy.name[0].toUpperCase()}
- {buddy.name}
+ {buddy.name}
{buddy.buddy_profile_id && (
- {t('common.link')}
+ {t('common.link')}
)}
handleDeleteBuddy(buddy.id)}
- className="text-[#8F9096] hover:text-red-400 opacity-0 group-hover:opacity-100 transition-all p-2 hover:bg-white/5 rounded-xl"
+ className="text-zinc-600 hover:text-red-500 opacity-0 group-hover:opacity-100 transition-all p-2 hover:bg-zinc-800 rounded-xl"
>
@@ -160,17 +160,17 @@ export default function BuddyList() {
{buddies.slice(0, 5).map((b, i) => (
-
+
{b.name[0].toUpperCase()}
))}
{buddies.length > 5 && (
-
+
+{buddies.length - 5}
)}
- {buddies.length} Buddies
+ {buddies.length} Buddies
)}
diff --git a/src/components/DramOfTheDay.tsx b/src/components/DramOfTheDay.tsx
index 8bdfe23..d34ad47 100644
--- a/src/components/DramOfTheDay.tsx
+++ b/src/components/DramOfTheDay.tsx
@@ -44,7 +44,7 @@ export default function DramOfTheDay({ bottles }: DramOfTheDayProps) {
{isRolling ? (
@@ -55,23 +55,23 @@ export default function DramOfTheDay({ bottles }: DramOfTheDayProps) {
{suggestion && (
-
-
+
+
setSuggestion(null)}
- className="absolute top-6 right-6 text-zinc-400 hover:text-zinc-600 dark:hover:text-zinc-200"
+ className="absolute top-6 right-6 text-zinc-500 hover:text-orange-600"
>
-
+
- {t('home.dramOfDay.title')}
-
+ {t('home.dramOfDay.title')}
+
{suggestion.name}
{suggestion.distillery && (
@@ -83,13 +83,13 @@ export default function DramOfTheDay({ bottles }: DramOfTheDayProps) {
setSuggestion(null)}
- className="block w-full py-4 bg-zinc-900 dark:bg-zinc-100 text-white dark:text-zinc-900 rounded-2xl font-black uppercase tracking-widest text-xs hover:bg-amber-600 dark:hover:bg-amber-600 hover:text-white transition-all shadow-xl"
+ className="block w-full py-4 bg-orange-600 text-white rounded-2xl font-bold uppercase tracking-widest text-xs hover:bg-orange-700 transition-all shadow-xl shadow-orange-950/20"
>
{t('home.dramOfDay.viewBottle')}
{t('home.dramOfDay.rollAgain')}
diff --git a/src/components/EditBottleForm.tsx b/src/components/EditBottleForm.tsx
index f1758da..6d6223d 100644
--- a/src/components/EditBottleForm.tsx
+++ b/src/components/EditBottleForm.tsx
@@ -123,9 +123,9 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
}
return (
-
+
-
+
{t('bottle.editTitle')}
setFormData({ ...formData, name: e.target.value })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-amber-500"
+ className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
/>
@@ -152,7 +152,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
type="text"
value={formData.distillery}
onChange={(e) => setFormData({ ...formData, distillery: e.target.value })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-amber-500"
+ className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
/>
@@ -161,7 +161,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
type="text"
value={formData.category}
onChange={(e) => setFormData({ ...formData, category: e.target.value })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-amber-500"
+ className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
/>
@@ -172,7 +172,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
step="0.1"
value={formData.abv}
onChange={(e) => setFormData({ ...formData, abv: parseFloat(e.target.value) })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-amber-500"
+ className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
/>
@@ -181,7 +181,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
type="number"
value={formData.age}
onChange={(e) => setFormData({ ...formData, age: parseInt(e.target.value) })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-amber-500"
+ className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
/>
@@ -192,7 +192,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
type="button"
onClick={handleDiscover}
disabled={isSearching}
- className="text-amber-600 hover:text-amber-700 flex items-center gap-1 normal-case font-bold"
+ className="text-orange-600 hover:text-orange-700 flex items-center gap-1 normal-case font-bold"
>
{isSearching ? : }
{t('bottle.autoSearch')}
@@ -202,17 +202,17 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
type="text"
value={formData.whiskybase_id}
onChange={(e) => setFormData({ ...formData, whiskybase_id: e.target.value })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-amber-500"
+ className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
/>
{discoveryResult && (
-
+
Treffer gefunden:
- {discoveryResult.title}
+ {discoveryResult.title}
{t('bottle.applyId')}
@@ -236,7 +236,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
placeholder="0.00"
value={formData.purchase_price}
onChange={(e) => setFormData({ ...formData, purchase_price: e.target.value })}
- className="w-full px-4 py-2 bg-amber-50 dark:bg-amber-900/10 border border-amber-200 dark:border-amber-900/30 rounded-xl outline-none focus:ring-2 focus:ring-amber-500 font-bold text-amber-700 dark:text-amber-400"
+ className="w-full px-4 py-2 bg-zinc-950 border border-zinc-800 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50 font-bold text-zinc-100"
/>
@@ -247,7 +247,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
placeholder="z.B. 2010"
value={formData.distilled_at}
onChange={(e) => setFormData({ ...formData, distilled_at: e.target.value })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-amber-500"
+ className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
/>
@@ -258,7 +258,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
placeholder="z.B. 2022"
value={formData.bottled_at}
onChange={(e) => setFormData({ ...formData, bottled_at: e.target.value })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-amber-500"
+ className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
/>
@@ -269,7 +269,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
placeholder="z.B. Batch 12 oder L-Code"
value={formData.batch_info}
onChange={(e) => setFormData({ ...formData, batch_info: e.target.value })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-amber-500"
+ className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
/>
@@ -279,7 +279,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
{isSaving ? : }
{t('bottle.saveChanges')}
diff --git a/src/components/FloatingScannerButton.tsx b/src/components/FloatingScannerButton.tsx
index 09056ca..039ed29 100644
--- a/src/components/FloatingScannerButton.tsx
+++ b/src/components/FloatingScannerButton.tsx
@@ -38,7 +38,7 @@ export default function FloatingScannerButton({ onImageSelected }: FloatingScann
whileTap={{ scale: 0.9 }}
initial={{ y: 100, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
- className="relative group p-6 rounded-full bg-amber-600 text-black shadow-[0_0_30px_rgba(217,119,6,0.4)] hover:shadow-[0_0_40px_rgba(217,119,6,0.6)] transition-all overflow-hidden"
+ className="relative group p-6 rounded-full bg-orange-600 text-black shadow-lg shadow-orange-950/40 hover:shadow-orange-950/60 transition-all overflow-hidden"
>
{/* Shine Animation */}
{/* Pulse ring */}
-
+
);
diff --git a/src/components/LanguageSwitcher.tsx b/src/components/LanguageSwitcher.tsx
index 0c0943b..d309ec6 100644
--- a/src/components/LanguageSwitcher.tsx
+++ b/src/components/LanguageSwitcher.tsx
@@ -11,8 +11,8 @@ const LanguageSwitcher = () => {
setLocale('de')}
className={`p-1.5 rounded-lg transition-all ${locale === 'de'
- ? 'bg-amber-100 dark:bg-amber-900/30 scale-110 shadow-sm'
- : 'opacity-50 hover:opacity-100 grayscale hover:grayscale-0'
+ ? 'bg-orange-950/30 scale-110 shadow-sm shadow-orange-950/20'
+ : 'opacity-50 hover:opacity-100 grayscale hover:grayscale-0'
}`}
title="Deutsch"
>
@@ -21,8 +21,8 @@ const LanguageSwitcher = () => {
setLocale('en')}
className={`p-1.5 rounded-lg transition-all ${locale === 'en'
- ? 'bg-amber-100 dark:bg-amber-900/30 scale-110 shadow-sm'
- : 'opacity-50 hover:opacity-100 grayscale hover:grayscale-0'
+ ? 'bg-orange-950/30 scale-110 shadow-sm shadow-orange-950/20'
+ : 'opacity-50 hover:opacity-100 grayscale hover:grayscale-0'
}`}
title="English"
>
diff --git a/src/components/OfflineIndicator.tsx b/src/components/OfflineIndicator.tsx
index beb07d0..c8b0c32 100644
--- a/src/components/OfflineIndicator.tsx
+++ b/src/components/OfflineIndicator.tsx
@@ -103,8 +103,8 @@ export default function OfflineIndicator() {
return (
- Offline-Modus aktiv
-
+ Offline-Modus aktiv
+
Alle Funktionen sind vollständig offline verfügbar.
@@ -112,9 +112,9 @@ export default function OfflineIndicator() {
}
return (
-
-
-
+
+
+
{progress > 0 ? `Vorbereitung... ${progress}%` : 'Warte auf System...'}
diff --git a/src/components/PlanManagementClient.tsx b/src/components/PlanManagementClient.tsx
index 2214555..3e08b86 100644
--- a/src/components/PlanManagementClient.tsx
+++ b/src/components/PlanManagementClient.tsx
@@ -129,11 +129,11 @@ export default function PlanManagementClient({ initialPlans }: PlanManagementCli
return (
{/* Actions Bar */}
-
+
Create New Plan
@@ -141,7 +141,7 @@ export default function PlanManagementClient({ initialPlans }: PlanManagementCli
Grant Monthly Credits
@@ -151,8 +151,8 @@ export default function PlanManagementClient({ initialPlans }: PlanManagementCli
{message && (
{message.type === 'success' ? : }
{message.text}
@@ -164,27 +164,27 @@ export default function PlanManagementClient({ initialPlans }: PlanManagementCli
{plans.map((plan) => (
{!plan.is_active && (
-
+
Inactive
)}
- {plan.display_name}
- {plan.name}
+ {plan.display_name}
+ {plan.name}
- {plan.monthly_credits}
- Credits/Month
+ {plan.monthly_credits}
+ Credits/Month
- €{plan.price.toFixed(2)}
- per month
+ €{plan.price.toFixed(2)}
+ per month
{plan.description && (
{plan.description}
@@ -192,14 +192,14 @@ export default function PlanManagementClient({ initialPlans }: PlanManagementCli
handleEdit(plan)}
- className="flex-1 py-2 bg-zinc-900 dark:bg-zinc-100 text-white dark:text-zinc-900 font-bold rounded-lg text-sm transition-colors flex items-center justify-center gap-2"
+ className="flex-1 py-2 bg-zinc-800 hover:bg-zinc-700 text-white font-bold rounded-xl text-[10px] uppercase tracking-widest transition-colors flex items-center justify-center gap-2 border border-zinc-700"
>
Edit
handleDelete(plan.id)}
- className="px-3 py-2 bg-red-600 hover:bg-red-700 text-white font-bold rounded-lg text-sm transition-colors"
+ className="px-3 py-2 bg-red-600/20 hover:bg-red-600 text-red-500 hover:text-white font-bold rounded-xl text-sm transition-colors border border-red-900/50"
>
@@ -210,15 +210,15 @@ export default function PlanManagementClient({ initialPlans }: PlanManagementCli
{/* Edit/Create Modal */}
{(editingPlan || isCreating) && (
-
-
+
+
-
+
{isCreating ? 'Create Plan' : 'Edit Plan'}
{ setEditingPlan(null); setIsCreating(false); }}
- className="p-2 hover:bg-zinc-100 dark:hover:bg-zinc-800 rounded-lg transition-colors"
+ className="p-2 hover:bg-zinc-800 rounded-xl transition-colors text-zinc-500"
>
@@ -227,79 +227,79 @@ export default function PlanManagementClient({ initialPlans }: PlanManagementCli
-
+
setFormData({ ...formData, name: e.target.value })}
placeholder="e.g. starter"
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-amber-500/50"
+ className="w-full px-4 py-2 bg-zinc-800 border border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-orange-600/50 text-white"
/>
-
+
setFormData({ ...formData, display_name: e.target.value })}
placeholder="e.g. Starter"
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-amber-500/50"
+ className="w-full px-4 py-2 bg-zinc-800 border border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-orange-600/50 text-white"
/>
-
+
setFormData({ ...formData, monthly_credits: parseInt(e.target.value) || 0 })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-amber-500/50"
+ className="w-full px-4 py-2 bg-zinc-800 border border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-orange-600/50 text-white"
/>
-
+
setFormData({ ...formData, price: parseFloat(e.target.value) || 0 })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-amber-500/50"
+ className="w-full px-4 py-2 bg-zinc-800 border border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-orange-600/50 text-white"
/>
-
+
-
+
setFormData({ ...formData, sort_order: parseInt(e.target.value) || 0 })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-amber-500/50"
+ className="w-full px-4 py-2 bg-zinc-800 border border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-orange-600/50 text-white"
/>
-
@@ -307,7 +307,7 @@ export default function PlanManagementClient({ initialPlans }: PlanManagementCli
{isCreating ? 'Create Plan' : 'Save Changes'}
diff --git a/src/components/ResultCard.tsx b/src/components/ResultCard.tsx
index 44443f3..535592b 100644
--- a/src/components/ResultCard.tsx
+++ b/src/components/ResultCard.tsx
@@ -34,75 +34,75 @@ export default function ResultCard({ data, bottleName, image, onShare }: ResultC
{/* The Trading Card */}
-
+
{/* Bottle Image with Vignette */}
{image ? (
) : (
- No Image
+ No Data
)}
-
+
{/* Content Overlay */}
-
-
- Tasting Record
- {bottleName}
+
+
+ Verified Tasting Record
+ {bottleName}
{/* Radar Chart Area */}
-
+
-
-
+
+
-
+
-
- Verified Report
+
+ Authenticated Report
{/* Score Badge */}
-
- {displayScore}
- Score
+
+ {displayScore}
+ Rating
{/* Decorative Elements */}
-
-
+
+
{/* Share Button */}
-
- Share Report
+
+ Share Tasting Report
);
diff --git a/src/components/ScanAndTasteFlow.tsx b/src/components/ScanAndTasteFlow.tsx
index 8ffa1ac..a7b6e0a 100644
--- a/src/components/ScanAndTasteFlow.tsx
+++ b/src/components/ScanAndTasteFlow.tsx
@@ -133,12 +133,12 @@ export default function ScanAndTasteFlow({ isOpen, onClose, base64Image }: ScanA
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
- className="fixed inset-0 z-[60] bg-[#0F1014] flex flex-col h-[100dvh] w-screen overflow-hidden overscroll-none"
+ className="fixed inset-0 z-[60] bg-zinc-950 flex flex-col h-[100dvh] w-screen overflow-hidden overscroll-none"
>
{/* Close Button */}
@@ -160,15 +160,15 @@ export default function ScanAndTasteFlow({ isOpen, onClose, base64Image }: ScanA
-
+
- Analysiere Etikett...
-
+
Analysiere Etikett...
+
KI-gestütztes Scanning
@@ -223,10 +223,10 @@ export default function ScanAndTasteFlow({ isOpen, onClose, base64Image }: ScanA
-
- Speichere Tasting...
+
+ Speichere Tasting...
)}
diff --git a/src/components/SessionBottomSheet.tsx b/src/components/SessionBottomSheet.tsx
index 7020e56..3a3a4db 100644
--- a/src/components/SessionBottomSheet.tsx
+++ b/src/components/SessionBottomSheet.tsx
@@ -76,7 +76,7 @@ export default function SessionBottomSheet({ isOpen, onClose }: SessionBottomShe
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
onClick={onClose}
- className="fixed inset-0 bg-black/60 backdrop-blur-sm z-[80]"
+ className="fixed inset-0 bg-zinc-950/80 backdrop-blur-sm z-[80]"
/>
{/* Sheet */}
@@ -85,12 +85,12 @@ export default function SessionBottomSheet({ isOpen, onClose }: SessionBottomShe
animate={{ y: 0 }}
exit={{ y: '100%' }}
transition={{ type: 'spring', damping: 25, stiffness: 200 }}
- className="fixed bottom-0 left-0 right-0 bg-[#1A1B20] border-t border-white/10 rounded-t-[32px] z-[90] p-8 pb-12 max-h-[80vh] overflow-y-auto shadow-[0_-10px_40px_rgba(0,0,0,0.5)]"
+ className="fixed bottom-0 left-0 right-0 bg-zinc-950 border-t border-zinc-800 rounded-t-[32px] z-[90] p-8 pb-12 max-h-[80vh] overflow-y-auto shadow-[0_-10px_40px_rgba(0,0,0,0.5)]"
>
{/* Drag Handle */}
-
+
- Tasting Session
+ Tasting Session
{/* New Session Input */}
@@ -100,12 +100,12 @@ export default function SessionBottomSheet({ isOpen, onClose }: SessionBottomShe
onChange={(e) => setNewSessionName(e.target.value)}
onKeyDown={(e) => e.key === 'Enter' && handleCreateSession()}
placeholder="Neue Session erstellen..."
- className="w-full bg-white/5 border border-white/10 rounded-2xl py-4 px-6 text-white focus:outline-none focus:border-[#C89D46] transition-colors"
+ className="w-full bg-zinc-900 border border-zinc-800 rounded-2xl py-4 px-6 text-zinc-50 focus:outline-none focus:border-orange-600 transition-colors"
/>
{isCreating ? : }
@@ -113,10 +113,10 @@ export default function SessionBottomSheet({ isOpen, onClose }: SessionBottomShe
{/* Session List */}
- Aktuelle Sessions
+ Aktuelle Sessions
{isLoading ? (
-
+
) : sessions.length > 0 ? (
sessions.map((s) => (
@@ -126,14 +126,14 @@ export default function SessionBottomSheet({ isOpen, onClose }: SessionBottomShe
setActiveSession({ id: s.id, name: s.name });
onClose();
}}
- className={`w-full flex items-center justify-between p-4 rounded-2xl border transition-all ${activeSession?.id === s.id ? 'bg-[#C89D46]/10 border-[#C89D46] text-[#C89D46]' : 'bg-white/5 border-white/5 hover:border-white/20 text-white'}`}
+ className={`w-full flex items-center justify-between p-4 rounded-2xl border transition-all ${activeSession?.id === s.id ? 'bg-orange-600/10 border-orange-600 text-orange-500' : 'bg-zinc-900 border-zinc-800 hover:border-zinc-700 text-zinc-50'}`}
>
{s.name}
- {activeSession?.id === s.id ? : }
+ {activeSession?.id === s.id ? : }
))
) : (
- Keine aktiven Sessions gefunden
+ Keine aktiven Sessions gefunden
)}
diff --git a/src/components/SessionList.tsx b/src/components/SessionList.tsx
index 6d66c2a..98816ea 100644
--- a/src/components/SessionList.tsx
+++ b/src/components/SessionList.tsx
@@ -140,18 +140,18 @@ export default function SessionList() {
};
return (
-
+
-
-
+
+
{t('session.title')}
{!isCollapsed && sessions.length > 0 && (
- ({sessions.length})
+ ({sessions.length})
)}
{isCollapsed ? : }
@@ -166,23 +166,23 @@ export default function SessionList() {
value={newName}
onChange={(e) => setNewName(e.target.value)}
placeholder={t('session.sessionName')}
- className="flex-1 bg-white/5 border border-white/10 rounded-xl px-4 py-2 text-sm text-white placeholder:text-[#8F9096] focus:outline-none focus:border-[#C89D46] transition-colors"
+ className="flex-1 bg-zinc-950 border border-zinc-800 rounded-xl px-4 py-2 text-sm text-zinc-50 placeholder:text-zinc-600 focus:outline-none focus:border-orange-600 transition-colors"
/>
{isCreating ? : }
{isLoading ? (
-
+
) : sessions.length === 0 ? (
-
+
{t('session.noSessions')}
) : (
@@ -191,18 +191,18 @@ export default function SessionList() {
-
+
{session.name}
{session.ended_at && (
- Closed
+ Closed
)}
-
+
{new Date(session.scheduled_at).toLocaleDateString(locale === 'de' ? 'de-DE' : 'en-US')}
@@ -225,28 +225,28 @@ export default function SessionList() {
!session.ended_at ? (
setActiveSession({ id: session.id, name: session.name })}
- className="p-2 bg-white/10 text-white rounded-xl hover:bg-[#C89D46] hover:text-[#0F1014] transition-all"
+ className="p-2 bg-zinc-800 text-zinc-50 rounded-xl hover:bg-orange-600 hover:text-white transition-all"
title="Start Session"
>
) : (
-
+
)
) : (
-
+
)}
-
+
handleDeleteSession(e, session.id)}
disabled={!!isDeleting}
className={`p-2 rounded-xl transition-all ${activeSession?.id === session.id
- ? 'text-[#0F1014]/40 hover:text-[#0F1014]'
- : 'text-[#8F9096] hover:text-red-400'
+ ? 'text-white/40 hover:text-white'
+ : 'text-zinc-600 hover:text-red-500'
}`}
title="Session löschen"
>
@@ -268,17 +268,17 @@ export default function SessionList() {
{sessions.slice(0, 3).map((s, i) => (
-
+
{s.name[0].toUpperCase()}
))}
{sessions.length > 3 && (
-
+
+{sessions.length - 3}
)}
- {sessions.length} Sessions
+ {sessions.length} Sessions
)}
diff --git a/src/components/SessionTimeline.tsx b/src/components/SessionTimeline.tsx
index 3ffce37..eecbeef 100644
--- a/src/components/SessionTimeline.tsx
+++ b/src/components/SessionTimeline.tsx
@@ -61,46 +61,46 @@ export default function SessionTimeline({ tastings, sessionStart }: SessionTimel
return (
{/* Dot */}
-
+
{isSmoky && }
-
+
- Dram #{index + 1}
-
+ Dram #{index + 1}
+
{wallClockTime} ({index === 0 ? 'Start' : `+${diffMinutes}m`})
{isSmoky && (
- Peat Bomb
+ Peat Bomb
)}
{tasting.bottle_name}
{tasting.tags.slice(0, 2).map(tag => (
-
+
{tag}
))}
- {tasting.rating}
- Punkte
+ {tasting.rating}
+ Punkte
{wasPreviousSmoky && timeSinceLastDram < 20 && (
-
-
-
+
+
+
Achtung: Gaumen war noch torf-belegt (nur {timeSinceLastDram}m Abstand).
diff --git a/src/components/StatsDashboard.tsx b/src/components/StatsDashboard.tsx
index 0110061..73fa162 100644
--- a/src/components/StatsDashboard.tsx
+++ b/src/components/StatsDashboard.tsx
@@ -61,8 +61,8 @@ export default function StatsDashboard({ bottles }: StatsDashboardProps) {
label: t('home.stats.avgRating'),
value: `${stats.avgRating}/100`,
icon: Star,
- color: 'text-amber-600',
- bg: 'bg-amber-50 dark:bg-amber-900/20'
+ color: 'text-orange-600',
+ bg: 'bg-orange-900/20'
},
{
label: t('home.stats.topDistillery'),
@@ -74,17 +74,18 @@ export default function StatsDashboard({ bottles }: StatsDashboardProps) {
];
return (
-
+
{statItems.map((item, idx) => {
+ const value = idx === 1 ? stats.totalCount : item.value;
return (
-
- {idx === 1 ? stats.totalCount : item.value}
+
+ {value}
-
+
{item.label}
diff --git a/src/components/TagSelector.tsx b/src/components/TagSelector.tsx
index 50f720e..324be14 100644
--- a/src/components/TagSelector.tsx
+++ b/src/components/TagSelector.tsx
@@ -70,35 +70,35 @@ export default function TagSelector({ category, selectedTagIds, onToggleTag, lab
key={tag.id}
type="button"
onClick={() => onToggleTag(tag.id)}
- className="inline-flex items-center gap-1.5 px-3 py-1.5 bg-amber-600 text-white rounded-full text-[10px] font-black uppercase tracking-tight shadow-sm shadow-amber-600/20 animate-in fade-in zoom-in-95"
+ className="inline-flex items-center gap-1.5 px-3 py-1.5 bg-orange-600 text-white rounded-full text-[10px] font-bold uppercase tracking-tight shadow-sm shadow-orange-600/20 animate-in fade-in zoom-in-95"
>
{tag.is_system_default ? t(`aroma.${tag.name}`) : tag.name}
))
) : (
- Noch keine Tags gewählt...
+ Noch keine Tags gewählt...
)}
{/* Search and Suggest */}
-
+
setSearch(e.target.value)}
placeholder="Tag suchen oder hinzufügen..."
- className="w-full pl-9 pr-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-xs focus:ring-2 focus:ring-amber-500 outline-none transition-all dark:text-zinc-200 placeholder:text-zinc-400"
+ className="w-full pl-9 pr-4 py-2 bg-zinc-900 border border-zinc-800 rounded-xl text-xs focus:ring-1 focus:ring-orange-600 outline-none transition-all text-zinc-200 placeholder:text-zinc-600"
/>
{isCreating && (
-
+
)}
{search && (
-
+
{filteredTags.length > 0 ? (
filteredTags.map(tag => (
@@ -109,17 +109,17 @@ export default function TagSelector({ category, selectedTagIds, onToggleTag, lab
onToggleTag(tag.id);
setSearch('');
}}
- className="w-full px-4 py-2.5 text-left text-xs font-bold text-zinc-700 dark:text-zinc-300 hover:bg-zinc-50 dark:hover:bg-zinc-700/50 flex items-center justify-between border-b border-zinc-100 dark:border-zinc-700 last:border-0"
+ className="w-full px-4 py-2.5 text-left text-xs font-bold text-zinc-300 hover:bg-zinc-800/50 flex items-center justify-between border-b border-zinc-800 last:border-0"
>
{tag.is_system_default ? t(`aroma.${tag.name}`) : tag.name}
- {selectedTagIds.includes(tag.id) && }
+ {selectedTagIds.includes(tag.id) && }
))
) : (
"{search}" als neuen Tag hinzufügen
@@ -133,7 +133,7 @@ export default function TagSelector({ category, selectedTagIds, onToggleTag, lab
{/* AI Suggestions */}
{!search && suggestedTagNames && suggestedTagNames.length > 0 && (
-
+
{t('camera.wbMatchFound') ? 'KI Vorschläge' : 'AI Suggestions'}
@@ -144,7 +144,7 @@ export default function TagSelector({ category, selectedTagIds, onToggleTag, lab
key={tag.id}
type="button"
onClick={() => onToggleTag(tag.id)}
- className="px-2.5 py-1 rounded-lg bg-amber-50 dark:bg-amber-900/20 text-amber-600 dark:text-amber-400 text-[10px] font-bold uppercase tracking-tight hover:bg-amber-100 dark:hover:bg-amber-900/30 transition-colors border border-amber-200 dark:border-amber-800/50 flex items-center gap-1.5"
+ className="px-2.5 py-1 rounded-lg bg-orange-950/20 text-orange-500 text-[10px] font-bold uppercase tracking-tight hover:bg-orange-900/30 transition-colors border border-orange-900/50 flex items-center gap-1.5"
>
{tag.is_system_default ? t(`aroma.${tag.name}`) : tag.name}
@@ -157,7 +157,7 @@ export default function TagSelector({ category, selectedTagIds, onToggleTag, lab
{/* AI Custom Suggestions */}
{!search && suggestedCustomTagNames && suggestedCustomTagNames.length > 0 && (
-
+
Dominante Note anlegen?
@@ -177,7 +177,7 @@ export default function TagSelector({ category, selectedTagIds, onToggleTag, lab
}
setCreatingSuggestion(null);
}}
- className="px-2.5 py-1 rounded-lg bg-zinc-50 dark:bg-zinc-800/50 text-zinc-500 dark:text-zinc-400 text-[10px] font-bold uppercase tracking-tight hover:bg-amber-600 hover:text-white transition-all border border-dashed border-zinc-200 dark:border-zinc-700/50 flex items-center gap-1.5 disabled:opacity-50"
+ className="px-2.5 py-1 rounded-lg bg-zinc-900/50 text-zinc-400 text-[10px] font-bold uppercase tracking-tight hover:bg-orange-600 hover:text-white transition-all border border-dashed border-zinc-800 flex items-center gap-1.5 disabled:opacity-50"
>
{creatingSuggestion === name ? : }
{name}
@@ -188,7 +188,7 @@ export default function TagSelector({ category, selectedTagIds, onToggleTag, lab
)}
{/* Suggestions Chips (limit to 6 random or most common) */}
- {!search && tags.length > 0 && (
+ {!search && (tags || []).length > 0 && (
{(tags || [])
.filter(t => !selectedTagIds.includes(t.id) && (!suggestedTagNames || !suggestedTagNames.some((s: string) => s.toLowerCase() === t.name.toLowerCase())))
@@ -198,7 +198,7 @@ export default function TagSelector({ category, selectedTagIds, onToggleTag, lab
key={tag.id}
type="button"
onClick={() => onToggleTag(tag.id)}
- className="px-2.5 py-1 rounded-lg bg-zinc-100 dark:bg-zinc-800 text-zinc-500 dark:text-zinc-400 text-[10px] font-bold uppercase tracking-tight hover:bg-zinc-200 dark:hover:bg-zinc-700 hover:text-zinc-700 dark:hover:text-zinc-200 transition-colors border border-zinc-200/50 dark:border-zinc-700/50"
+ className="px-2.5 py-1 rounded-lg bg-zinc-900 text-zinc-500 text-[10px] font-bold uppercase tracking-tight hover:bg-zinc-800 hover:text-zinc-200 transition-colors border border-zinc-800"
>
{tag.is_system_default ? t(`aroma.${tag.name}`) : tag.name}
diff --git a/src/components/TastingEditor.tsx b/src/components/TastingEditor.tsx
index 4fa86a3..c4d52b2 100644
--- a/src/components/TastingEditor.tsx
+++ b/src/components/TastingEditor.tsx
@@ -123,18 +123,18 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
};
return (
-
+
{/* Top Context Bar - Flex Child 1 */}
-
+
- Kontext
- {activeSessionName || 'Trinkst du in Gesellschaft?'}
+ Kontext
+ {activeSessionName || 'Trinkst du in Gesellschaft?'}
-
+
@@ -146,50 +146,50 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
-
+
- Palette-Checker
-
+
Palette-Checker
+
Dein letzter Dram "{lastDramInSession?.name}" war torfig. Trink etwas Wasser!
- setShowPaletteWarning(false)} className="text-[10px] font-black uppercase text-amber-500 underline mt-2 block">Verstanden
+ setShowPaletteWarning(false)} className="text-[10px] font-bold uppercase text-orange-500 underline mt-2 block">Verstanden
)}
{/* Hero Section */}
-
+
{image ? (
) : (
- No Photo
+ No Photo
)}
-
+
{bottleMetadata.distillery || 'Destillerie'}
-
{bottleMetadata.name || 'Unbekannter Malt'}
-
+
{bottleMetadata.name || 'Unbekannter Malt'}
+
{bottleMetadata.category || 'Whisky'} {bottleMetadata.abv ? `• ${bottleMetadata.abv}%` : ''} {bottleMetadata.age ? `• ${bottleMetadata.age}y` : ''}
{/* Rating Slider */}
-
+
-
+
-
-
+
+
{t('tasting.rating')}
- {rating}/100
+ {rating}/100
setRating(parseInt(e.target.value))}
- className="w-full h-2 bg-zinc-800 rounded-full appearance-none cursor-pointer accent-amber-600 transition-all"
+ className="w-full h-2 bg-zinc-800 rounded-full appearance-none cursor-pointer accent-orange-600 transition-all"
/>
-
+
Swill
Dram
Legendary
@@ -210,9 +210,9 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
setIsSample(type === 'Sample')}
- className={`flex-1 py-4 rounded-2xl text-[10px] font-black uppercase tracking-widest border transition-all ${(type === 'Sample' ? isSample : !isSample)
- ? 'bg-zinc-100 border-zinc-100 text-zinc-900 shadow-lg'
- : 'bg-transparent border-white/10 text-white/40 hover:border-white/30'
+ className={`flex-1 py-4 rounded-xl text-[10px] font-bold uppercase tracking-widest border transition-all ${(type === 'Sample' ? isSample : !isSample)
+ ? 'bg-orange-600 border-orange-600 text-white shadow-lg'
+ : 'bg-transparent border-zinc-800 text-zinc-500 hover:border-zinc-700'
}`}
>
{type}
@@ -230,14 +230,14 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
{/* Sections */}
{/* Nose Section */}
-
+
-
+
- {t('tasting.nose')}
- Aroma & Bouquet
+ {t('tasting.nose')}
+ Aroma & Bouquet
@@ -245,7 +245,7 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
} />
- Tags
+ Tags
- Eigene Notizen
+ Eigene Notizen
{/* Palate Section */}
-
+
-
+
- {t('tasting.palate')}
- Geschmack & Textur
+ {t('tasting.palate')}
+ Geschmack & Textur
@@ -282,7 +282,7 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
} />
- Tags
+ Tags
- Eigene Notizen
+ Eigene Notizen
{/* Finish Section */}
-
+
-
+
- {t('tasting.finish')}
- Abgang & Nachklang
+ {t('tasting.finish')}
+ Abgang & Nachklang
} />
-
+
- Aroma Tags
+ Aroma Tags
- Gefühl & Textur
+ Gefühl & Textur
- Eigene Notizen
+ Eigene Notizen
@@ -354,14 +354,14 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
{/* Buddy Selection */}
{buddies && buddies.length > 0 && (
-
+
-
+
- Mit wem trinkst du?
- Gesellschaft & Buddies
+ Mit wem trinkst du?
+ Gesellschaft & Buddies
@@ -369,9 +369,9 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
toggleBuddy(buddy.id)}
- className={`px-5 py-3 rounded-2xl text-[10px] font-black uppercase transition-all border flex items-center gap-2 ${selectedBuddyIds.includes(buddy.id)
- ? 'bg-amber-600 border-amber-600 text-white shadow-lg'
- : 'bg-transparent border-white/10 text-white/40 hover:border-white/30'
+ className={`px-5 py-3 rounded-xl text-[10px] font-bold uppercase transition-all border flex items-center gap-2 ${selectedBuddyIds.includes(buddy.id)
+ ? 'bg-orange-600 border-orange-600 text-white shadow-lg'
+ : 'bg-transparent border-zinc-800 text-zinc-500 hover:border-zinc-700'
}`}
>
{selectedBuddyIds.includes(buddy.id) && }
@@ -385,15 +385,15 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
{/* Sticky Footer - Flex Child 3 */}
-
+
{t('tasting.saveTasting')}
- {rating}
+ {rating}
@@ -404,15 +404,15 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
function CustomSlider({ label, value, onChange, icon }: any) {
return (
-
+
-
-
+
+
{icon}
- {label}
+ {label}
- {value}
+ {value}
onChange(parseInt(e.target.value))}
- className="w-full h-1.5 bg-zinc-800 rounded-full appearance-none cursor-pointer accent-[#C89D46] transition-all"
+ className="w-full h-1.5 bg-zinc-800 rounded-full appearance-none cursor-pointer accent-orange-600 transition-all"
/>
);
diff --git a/src/components/UserManagementClient.tsx b/src/components/UserManagementClient.tsx
index 350eb57..1a12f3b 100644
--- a/src/components/UserManagementClient.tsx
+++ b/src/components/UserManagementClient.tsx
@@ -166,61 +166,61 @@ export default function UserManagementClient({ initialUsers, plans }: UserManage
return (
{/* Search Bar */}
-
+
-
+
setSearchTerm(e.target.value)}
- className="w-full pl-10 pr-4 py-3 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-amber-500/50"
+ className="w-full pl-10 pr-4 py-3 bg-zinc-800 border border-zinc-700 rounded-2xl text-sm focus:outline-none focus:ring-2 focus:ring-orange-600/50 text-white"
/>
{/* User Table */}
-
- Users ({filteredUsers.length})
-
+
+ Users ({filteredUsers.length})
+
-
- User
- Balance
- Used
- Daily Limit
- Costs
- Actions
+
+ User
+ Balance
+ Used
+ Daily Limit
+ Costs
+ Actions
-
+
{filteredUsers.map((user) => (
-
-
+
+
- {user.username}
- {user.email}
+ {user.username}
+ {user.email}
-
-
+
+
{user.balance}
-
+
{user.total_used}
-
+
{user.daily_limit || 'Global (80)'}
-
+
G:{user.google_search_cost} / AI:{user.gemini_ai_cost}
-
+
handleEditUser(user)}
- className="inline-flex items-center gap-2 px-3 py-1.5 bg-amber-600 hover:bg-amber-700 text-white rounded-lg text-xs font-bold transition-colors"
+ className="inline-flex items-center gap-2 px-4 py-2 bg-orange-600 hover:bg-orange-700 text-white rounded-xl text-[10px] font-bold uppercase tracking-widest transition-all shadow-md shadow-orange-950/20"
>
Edit
@@ -235,18 +235,18 @@ export default function UserManagementClient({ initialUsers, plans }: UserManage
{/* Edit Modal */}
{editingUser && (
-
-
-
+
+
+
- Edit User
- {editingUser.email}
+ Edit User
+ {editingUser.email}
setEditingUser(null)}
- className="p-2 hover:bg-zinc-100 dark:hover:bg-zinc-800 rounded-lg transition-colors"
+ className="p-2 hover:bg-zinc-800 rounded-xl transition-colors text-zinc-500"
>
-
+
@@ -262,40 +262,40 @@ export default function UserManagementClient({ initialUsers, plans }: UserManage
{/* Current Balance */}
-
- Current Balance
- {editingUser.balance} Credits
+
+ Current Balance
+ {editingUser.balance} Credits
{/* Add/Remove Credits */}
- Adjust Credits
+ Adjust Credits
- Amount
+ Amount
setCreditAmount(e.target.value)}
placeholder="e.g. 100 or -50"
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-amber-500/50"
+ className="w-full px-4 py-2 bg-zinc-800 border border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-orange-600/50 text-white"
/>
- Reason
+ Reason
setReason(e.target.value)}
placeholder="e.g. Monthly bonus"
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-amber-500/50"
+ className="w-full px-4 py-2 bg-zinc-800 border border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-orange-600/50 text-white"
/>
Update Credits
@@ -306,20 +306,20 @@ export default function UserManagementClient({ initialUsers, plans }: UserManage
{/* Subscription Plan */}
- Subscription Plan
+ Subscription Plan
{currentPlan && (
-
- Current Plan
- {currentPlan.display_name}
- {currentPlan.monthly_credits} credits/month
+
+ Current Plan
+ {currentPlan.display_name}
+ {currentPlan.monthly_credits} credits/month
)}
- Assign Plan
+ Assign Plan
+
Collection
-
+
{bottles.length} Bottles
{t('common.error')}
-{fetchError}
+{t('common.error')}
+{fetchError}
{t('common.loading')}
Offline-Modus: Daten aus dem Cache
+Offline-Modus: Daten aus dem Cache
+
{bottle.name}
-
{bottle.distillery}
+{bottle.distillery}
{bottle.whiskybase_id && (+
{/* Tasting Notes Section */}
Tasting Notes
+Tasting Notes
Hier findest du deine bisherigen Eindrücke.
+
+
Dram bewerten
diff --git a/src/components/BottleGrid.tsx b/src/components/BottleGrid.tsx
index 248f105..a061d18 100644
--- a/src/components/BottleGrid.tsx
+++ b/src/components/BottleGrid.tsx
@@ -36,71 +36,65 @@ function BottleCard({ bottle, sessionId }: BottleCardProps) {
return (
- {/* Image Layer - Edge to Edge */}
-
+ {/* Image Layer - Clean Split Top */}
+
-
- {/* Gradient Overlay as requested: bottom third, black to transparent */}
-
- {/* Content Layer */}
-
-
- {/* Tags Layer - Minimalist Glassmorphism */}
-
-
- {shortenCategory(bottle.category)}
-
-
- {bottle.abv}% VOL
-
-
+ {/* Info Layer - Clean Split Bottom */}
+
+
+
+ {bottle.distillery}
+
+
+ {bottle.name || t('grid.unknownBottle')}
+
+
-
-
- {bottle.distillery}
-
-
- {bottle.name || t('grid.unknownBottle')}
-
-
+
+
+ {shortenCategory(bottle.category)}
+
+
+ {bottle.abv}% VOL
+
+
- {/* Metadata items */}
-
-
-
- {new Date(bottle.created_at).toLocaleDateString(locale === 'de' ? 'de-DE' : 'en-US')}
+ {/* Metadata items */}
+
+
+
+ {new Date(bottle.created_at).toLocaleDateString(locale === 'de' ? 'de-DE' : 'en-US')}
+
+ {bottle.last_tasted && (
+
+
+ {new Date(bottle.last_tasted).toLocaleDateString(locale === 'de' ? 'de-DE' : 'en-US')}
- {bottle.last_tasted && (
-
-
- {new Date(bottle.last_tasted).toLocaleDateString(locale === 'de' ? 'de-DE' : 'en-US')}
-
- )}
-
+ )}
{/* Top Overlays */}
{(bottle.is_whisky === false || (bottle.confidence && bottle.confidence < 70)) && (
-
-
-
+
+
+
)}
{sessionId && (
-
-
- ADD TO SESSION
+
+
+ ADD
)}
@@ -200,13 +194,13 @@ export default function BottleGrid({ bottles }: BottleGridProps) {
-
+
setSearchQuery(e.target.value)}
- className="w-full pl-8 pr-8 py-4 bg-transparent border-b border-white/10 focus:border-[#C89D46] outline-none transition-all text-white placeholder:text-[#8F9096] font-sans"
+ className="w-full pl-8 pr-8 py-4 bg-transparent border-b border-zinc-800 focus:border-orange-500 outline-none transition-all text-zinc-50 placeholder:text-zinc-500"
/>
{searchQuery && (
setSortBy(e.target.value as any)}
- className="bg-transparent border-none text-[#8F9096] text-xs font-sans font-bold uppercase tracking-widest outline-none cursor-pointer hover:text-white transition-colors appearance-none"
+ className="bg-transparent border-none text-zinc-500 text-xs font-bold uppercase tracking-widest outline-none cursor-pointer hover:text-white transition-colors appearance-none"
>
-
-
-
+
+
+
setIsFiltersOpen(!isFiltersOpen)}
- className={`flex items-center gap-2 text-xs font-sans font-bold uppercase tracking-widest transition-all ${isFiltersOpen || activeFiltersCount > 0
- ? 'text-[#C89D46]'
- : 'text-[#8F9096] hover:text-white'
+ className={`flex items-center gap-2 text-xs font-bold uppercase tracking-widest transition-all ${isFiltersOpen || activeFiltersCount > 0
+ ? 'text-orange-500'
+ : 'text-zinc-500 hover:text-white'
}`}
>
{t('grid.filters')}
{activeFiltersCount > 0 && (
-
+
{activeFiltersCount}
)}
@@ -247,13 +241,13 @@ export default function BottleGrid({ bottles }: BottleGridProps) {
- {/* Category Quick Filter - Glass Chips */}
+ {/* Category Quick Filter - Flat Chips */}
setSelectedCategory(null)}
- className={`px-4 py-2 rounded-full text-[10px] font-sans font-bold uppercase tracking-widest whitespace-nowrap transition-all border ${selectedCategory === null
- ? 'bg-[#C89D46] border-[#C89D46] text-[#0F1014]'
- : 'bg-white/5 border-white/10 text-[#8F9096] hover:border-white/20'
+ className={`px-4 py-2 rounded-full text-[10px] font-bold uppercase tracking-widest whitespace-nowrap transition-all border ${selectedCategory === null
+ ? 'bg-orange-600 border-orange-600 text-white'
+ : 'bg-zinc-900 border-zinc-800 text-zinc-400 hover:border-zinc-700'
}`}
>
{t('common.all')}
@@ -262,9 +256,9 @@ export default function BottleGrid({ bottles }: BottleGridProps) {
setSelectedCategory(selectedCategory === cat ? null : cat)}
- className={`px-4 py-2 rounded-full text-[10px] font-sans font-bold uppercase tracking-widest whitespace-nowrap transition-all border ${selectedCategory === cat
- ? 'bg-[#C89D46] border-[#C89D46] text-[#0F1014]'
- : 'bg-white/5 border-white/10 text-[#8F9096] hover:border-white/20'
+ className={`px-4 py-2 rounded-full text-[10px] font-bold uppercase tracking-widest whitespace-nowrap transition-all border ${selectedCategory === cat
+ ? 'bg-orange-600 border-orange-600 text-white'
+ : 'bg-zinc-900 border-zinc-800 text-zinc-400 hover:border-zinc-700'
}`}
>
{shortenCategory(cat)}
@@ -272,17 +266,17 @@ export default function BottleGrid({ bottles }: BottleGridProps) {
))}
- {/* Collapsible Advanced Filters - Minimalist Overlay */}
+ {/* Collapsible Advanced Filters - Industrial Overlay */}
{isFiltersOpen && (
-
+
-
+
setSelectedDistillery(null)}
- className={`px-4 py-2 rounded-full text-[10px] font-sans font-bold uppercase tracking-widest transition-all border ${selectedDistillery === null
- ? 'bg-[#C89D46] border-[#C89D46] text-[#0F1014]'
- : 'bg-white/5 border-white/10 text-[#8F9096]'
+ className={`px-4 py-2 rounded-full text-[10px] font-bold uppercase tracking-widest transition-all border ${selectedDistillery === null
+ ? 'bg-orange-600 border-orange-600 text-white'
+ : 'bg-zinc-800 border-zinc-700 text-zinc-400'
}`}
>
{t('common.all')}
@@ -291,9 +285,9 @@ export default function BottleGrid({ bottles }: BottleGridProps) {
setSelectedDistillery(selectedDistillery === dist ? null : dist)}
- className={`px-4 py-2 rounded-full text-[10px] font-sans font-bold uppercase tracking-widest transition-all border ${selectedDistillery === dist
- ? 'bg-[#C89D46] border-[#C89D46] text-[#0F1014]'
- : 'bg-white/5 border-white/10 text-[#8F9096]'
+ className={`px-4 py-2 rounded-full text-[10px] font-bold uppercase tracking-widest transition-all border ${selectedDistillery === dist
+ ? 'bg-orange-600 border-orange-600 text-white'
+ : 'bg-zinc-800 border-zinc-700 text-zinc-400'
}`}
>
{dist}
@@ -302,20 +296,20 @@ export default function BottleGrid({ bottles }: BottleGridProps) {
-
+
{
setSelectedCategory(null);
setSelectedDistillery(null);
setSearchQuery('');
}}
- className="text-[10px] font-sans font-bold text-red-500 uppercase tracking-widest hover:text-red-400"
+ className="text-[10px] font-bold text-red-500 uppercase tracking-widest hover:text-red-400"
>
{t('grid.resetAll')}
setIsFiltersOpen(false)}
- className="px-8 py-3 bg-white text-[#0F1014] text-[10px] font-sans font-bold rounded-full uppercase tracking-widest transition-transform active:scale-95"
+ className="px-8 py-3 bg-zinc-50 text-zinc-950 text-[10px] font-bold rounded-full uppercase tracking-widest transition-transform active:scale-95"
>
{t('grid.close')}
diff --git a/src/components/BottomNavigation.tsx b/src/components/BottomNavigation.tsx
index 8fe190e..39f847c 100644
--- a/src/components/BottomNavigation.tsx
+++ b/src/components/BottomNavigation.tsx
@@ -31,7 +31,7 @@ export const BottomNavigation = ({ onHome, onShelf, onSearch, onProfile, onScan
};
return (
-
+
{/* Hidden Input for Scanning */}
- {/* Background Container mit Glassmorphism */}
-
+
+ {/* Left Items */}
+
+
+
-
- {/* Left Actions */}
-
-
- Home
-
+
+
+
-
-
- Shelf
-
+ {/* PRIMARY ACTION - The "Industrial Button" */}
+
+
+
- {/* Spacer für den Center Button */}
-
-
- {/* Right Actions */}
-
-
- Search
-
-
-
-
- Admin
-
-
-
- {/* THE FLOATING MAGIC BUTTON */}
-
-
-
-
-
-
- {/* Visual Gold Glow */}
-
-
+ {/* Right Items */}
+
+
+
+
+
+
);
diff --git a/src/components/BuddyList.tsx b/src/components/BuddyList.tsx
index 4ba9208..4aebbcc 100644
--- a/src/components/BuddyList.tsx
+++ b/src/components/BuddyList.tsx
@@ -80,18 +80,18 @@ export default function BuddyList() {
};
return (
-
+
-
-
+
+
{t('buddy.title')}
{!isCollapsed && buddies.length > 0 && (
- ({buddies.length})
+ ({buddies.length})
)}
{isCollapsed ? : }
@@ -106,23 +106,23 @@ export default function BuddyList() {
value={newName}
onChange={(e) => setNewName(e.target.value)}
placeholder={t('buddy.placeholder')}
- className="flex-1 bg-white/5 border border-white/10 rounded-xl px-4 py-2 text-sm text-white placeholder:text-[#8F9096] focus:outline-none focus:border-[#C89D46] transition-colors"
+ className="flex-1 bg-zinc-950 border border-zinc-800 rounded-xl px-4 py-2 text-sm text-zinc-50 placeholder:text-zinc-600 focus:outline-none focus:border-orange-600 transition-colors"
/>
{isAdding ? : }
{isLoading ? (
-
+
) : buddies.length === 0 ? (
-
+
{t('buddy.noBuddies')}
) : (
@@ -130,22 +130,22 @@ export default function BuddyList() {
{buddies.map((buddy) => (
-
+
{buddy.name[0].toUpperCase()}
- {buddy.name}
+ {buddy.name}
{buddy.buddy_profile_id && (
- {t('common.link')}
+ {t('common.link')}
)}
handleDeleteBuddy(buddy.id)}
- className="text-[#8F9096] hover:text-red-400 opacity-0 group-hover:opacity-100 transition-all p-2 hover:bg-white/5 rounded-xl"
+ className="text-zinc-600 hover:text-red-500 opacity-0 group-hover:opacity-100 transition-all p-2 hover:bg-zinc-800 rounded-xl"
>
@@ -160,17 +160,17 @@ export default function BuddyList() {
{buddies.slice(0, 5).map((b, i) => (
-
+
{b.name[0].toUpperCase()}
))}
{buddies.length > 5 && (
-
+
+{buddies.length - 5}
)}
- {buddies.length} Buddies
+ {buddies.length} Buddies
)}
diff --git a/src/components/DramOfTheDay.tsx b/src/components/DramOfTheDay.tsx
index 8bdfe23..d34ad47 100644
--- a/src/components/DramOfTheDay.tsx
+++ b/src/components/DramOfTheDay.tsx
@@ -44,7 +44,7 @@ export default function DramOfTheDay({ bottles }: DramOfTheDayProps) {
{isRolling ? (
@@ -55,23 +55,23 @@ export default function DramOfTheDay({ bottles }: DramOfTheDayProps) {
{suggestion && (
-
-
+
+
setSuggestion(null)}
- className="absolute top-6 right-6 text-zinc-400 hover:text-zinc-600 dark:hover:text-zinc-200"
+ className="absolute top-6 right-6 text-zinc-500 hover:text-orange-600"
>
-
+
- {t('home.dramOfDay.title')}
-
+ {t('home.dramOfDay.title')}
+
{suggestion.name}
{suggestion.distillery && (
@@ -83,13 +83,13 @@ export default function DramOfTheDay({ bottles }: DramOfTheDayProps) {
setSuggestion(null)}
- className="block w-full py-4 bg-zinc-900 dark:bg-zinc-100 text-white dark:text-zinc-900 rounded-2xl font-black uppercase tracking-widest text-xs hover:bg-amber-600 dark:hover:bg-amber-600 hover:text-white transition-all shadow-xl"
+ className="block w-full py-4 bg-orange-600 text-white rounded-2xl font-bold uppercase tracking-widest text-xs hover:bg-orange-700 transition-all shadow-xl shadow-orange-950/20"
>
{t('home.dramOfDay.viewBottle')}
{t('home.dramOfDay.rollAgain')}
diff --git a/src/components/EditBottleForm.tsx b/src/components/EditBottleForm.tsx
index f1758da..6d6223d 100644
--- a/src/components/EditBottleForm.tsx
+++ b/src/components/EditBottleForm.tsx
@@ -123,9 +123,9 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
}
return (
-
+
-
+
{t('bottle.editTitle')}
setFormData({ ...formData, name: e.target.value })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-amber-500"
+ className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
/>
@@ -152,7 +152,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
type="text"
value={formData.distillery}
onChange={(e) => setFormData({ ...formData, distillery: e.target.value })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-amber-500"
+ className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
/>
@@ -161,7 +161,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
type="text"
value={formData.category}
onChange={(e) => setFormData({ ...formData, category: e.target.value })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-amber-500"
+ className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
/>
@@ -172,7 +172,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
step="0.1"
value={formData.abv}
onChange={(e) => setFormData({ ...formData, abv: parseFloat(e.target.value) })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-amber-500"
+ className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
/>
@@ -181,7 +181,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
type="number"
value={formData.age}
onChange={(e) => setFormData({ ...formData, age: parseInt(e.target.value) })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-amber-500"
+ className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
/>
@@ -192,7 +192,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
type="button"
onClick={handleDiscover}
disabled={isSearching}
- className="text-amber-600 hover:text-amber-700 flex items-center gap-1 normal-case font-bold"
+ className="text-orange-600 hover:text-orange-700 flex items-center gap-1 normal-case font-bold"
>
{isSearching ? : }
{t('bottle.autoSearch')}
@@ -202,17 +202,17 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
type="text"
value={formData.whiskybase_id}
onChange={(e) => setFormData({ ...formData, whiskybase_id: e.target.value })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-amber-500"
+ className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
/>
{discoveryResult && (
-
+
Treffer gefunden:
- {discoveryResult.title}
+ {discoveryResult.title}
{t('bottle.applyId')}
@@ -236,7 +236,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
placeholder="0.00"
value={formData.purchase_price}
onChange={(e) => setFormData({ ...formData, purchase_price: e.target.value })}
- className="w-full px-4 py-2 bg-amber-50 dark:bg-amber-900/10 border border-amber-200 dark:border-amber-900/30 rounded-xl outline-none focus:ring-2 focus:ring-amber-500 font-bold text-amber-700 dark:text-amber-400"
+ className="w-full px-4 py-2 bg-zinc-950 border border-zinc-800 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50 font-bold text-zinc-100"
/>
@@ -247,7 +247,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
placeholder="z.B. 2010"
value={formData.distilled_at}
onChange={(e) => setFormData({ ...formData, distilled_at: e.target.value })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-amber-500"
+ className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
/>
@@ -258,7 +258,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
placeholder="z.B. 2022"
value={formData.bottled_at}
onChange={(e) => setFormData({ ...formData, bottled_at: e.target.value })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-amber-500"
+ className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
/>
@@ -269,7 +269,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
placeholder="z.B. Batch 12 oder L-Code"
value={formData.batch_info}
onChange={(e) => setFormData({ ...formData, batch_info: e.target.value })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-amber-500"
+ className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
/>
@@ -279,7 +279,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
{isSaving ? : }
{t('bottle.saveChanges')}
diff --git a/src/components/FloatingScannerButton.tsx b/src/components/FloatingScannerButton.tsx
index 09056ca..039ed29 100644
--- a/src/components/FloatingScannerButton.tsx
+++ b/src/components/FloatingScannerButton.tsx
@@ -38,7 +38,7 @@ export default function FloatingScannerButton({ onImageSelected }: FloatingScann
whileTap={{ scale: 0.9 }}
initial={{ y: 100, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
- className="relative group p-6 rounded-full bg-amber-600 text-black shadow-[0_0_30px_rgba(217,119,6,0.4)] hover:shadow-[0_0_40px_rgba(217,119,6,0.6)] transition-all overflow-hidden"
+ className="relative group p-6 rounded-full bg-orange-600 text-black shadow-lg shadow-orange-950/40 hover:shadow-orange-950/60 transition-all overflow-hidden"
>
{/* Shine Animation */}
{/* Pulse ring */}
-
+
);
diff --git a/src/components/LanguageSwitcher.tsx b/src/components/LanguageSwitcher.tsx
index 0c0943b..d309ec6 100644
--- a/src/components/LanguageSwitcher.tsx
+++ b/src/components/LanguageSwitcher.tsx
@@ -11,8 +11,8 @@ const LanguageSwitcher = () => {
setLocale('de')}
className={`p-1.5 rounded-lg transition-all ${locale === 'de'
- ? 'bg-amber-100 dark:bg-amber-900/30 scale-110 shadow-sm'
- : 'opacity-50 hover:opacity-100 grayscale hover:grayscale-0'
+ ? 'bg-orange-950/30 scale-110 shadow-sm shadow-orange-950/20'
+ : 'opacity-50 hover:opacity-100 grayscale hover:grayscale-0'
}`}
title="Deutsch"
>
@@ -21,8 +21,8 @@ const LanguageSwitcher = () => {
setLocale('en')}
className={`p-1.5 rounded-lg transition-all ${locale === 'en'
- ? 'bg-amber-100 dark:bg-amber-900/30 scale-110 shadow-sm'
- : 'opacity-50 hover:opacity-100 grayscale hover:grayscale-0'
+ ? 'bg-orange-950/30 scale-110 shadow-sm shadow-orange-950/20'
+ : 'opacity-50 hover:opacity-100 grayscale hover:grayscale-0'
}`}
title="English"
>
diff --git a/src/components/OfflineIndicator.tsx b/src/components/OfflineIndicator.tsx
index beb07d0..c8b0c32 100644
--- a/src/components/OfflineIndicator.tsx
+++ b/src/components/OfflineIndicator.tsx
@@ -103,8 +103,8 @@ export default function OfflineIndicator() {
return (
- Offline-Modus aktiv
-
+ Offline-Modus aktiv
+
Alle Funktionen sind vollständig offline verfügbar.
@@ -112,9 +112,9 @@ export default function OfflineIndicator() {
}
return (
-
-
-
+
+
+
{progress > 0 ? `Vorbereitung... ${progress}%` : 'Warte auf System...'}
diff --git a/src/components/PlanManagementClient.tsx b/src/components/PlanManagementClient.tsx
index 2214555..3e08b86 100644
--- a/src/components/PlanManagementClient.tsx
+++ b/src/components/PlanManagementClient.tsx
@@ -129,11 +129,11 @@ export default function PlanManagementClient({ initialPlans }: PlanManagementCli
return (
{/* Actions Bar */}
-
+
Create New Plan
@@ -141,7 +141,7 @@ export default function PlanManagementClient({ initialPlans }: PlanManagementCli
Grant Monthly Credits
@@ -151,8 +151,8 @@ export default function PlanManagementClient({ initialPlans }: PlanManagementCli
{message && (
{message.type === 'success' ? : }
{message.text}
@@ -164,27 +164,27 @@ export default function PlanManagementClient({ initialPlans }: PlanManagementCli
{plans.map((plan) => (
{!plan.is_active && (
-
+
Inactive
)}
- {plan.display_name}
- {plan.name}
+ {plan.display_name}
+ {plan.name}
- {plan.monthly_credits}
- Credits/Month
+ {plan.monthly_credits}
+ Credits/Month
- €{plan.price.toFixed(2)}
- per month
+ €{plan.price.toFixed(2)}
+ per month
{plan.description && (
{plan.description}
@@ -192,14 +192,14 @@ export default function PlanManagementClient({ initialPlans }: PlanManagementCli
handleEdit(plan)}
- className="flex-1 py-2 bg-zinc-900 dark:bg-zinc-100 text-white dark:text-zinc-900 font-bold rounded-lg text-sm transition-colors flex items-center justify-center gap-2"
+ className="flex-1 py-2 bg-zinc-800 hover:bg-zinc-700 text-white font-bold rounded-xl text-[10px] uppercase tracking-widest transition-colors flex items-center justify-center gap-2 border border-zinc-700"
>
Edit
handleDelete(plan.id)}
- className="px-3 py-2 bg-red-600 hover:bg-red-700 text-white font-bold rounded-lg text-sm transition-colors"
+ className="px-3 py-2 bg-red-600/20 hover:bg-red-600 text-red-500 hover:text-white font-bold rounded-xl text-sm transition-colors border border-red-900/50"
>
@@ -210,15 +210,15 @@ export default function PlanManagementClient({ initialPlans }: PlanManagementCli
{/* Edit/Create Modal */}
{(editingPlan || isCreating) && (
-
-
+
+
-
+
{isCreating ? 'Create Plan' : 'Edit Plan'}
{ setEditingPlan(null); setIsCreating(false); }}
- className="p-2 hover:bg-zinc-100 dark:hover:bg-zinc-800 rounded-lg transition-colors"
+ className="p-2 hover:bg-zinc-800 rounded-xl transition-colors text-zinc-500"
>
@@ -227,79 +227,79 @@ export default function PlanManagementClient({ initialPlans }: PlanManagementCli
-
+
setFormData({ ...formData, name: e.target.value })}
placeholder="e.g. starter"
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-amber-500/50"
+ className="w-full px-4 py-2 bg-zinc-800 border border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-orange-600/50 text-white"
/>
-
+
setFormData({ ...formData, display_name: e.target.value })}
placeholder="e.g. Starter"
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-amber-500/50"
+ className="w-full px-4 py-2 bg-zinc-800 border border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-orange-600/50 text-white"
/>
-
+
setFormData({ ...formData, monthly_credits: parseInt(e.target.value) || 0 })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-amber-500/50"
+ className="w-full px-4 py-2 bg-zinc-800 border border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-orange-600/50 text-white"
/>
-
+
setFormData({ ...formData, price: parseFloat(e.target.value) || 0 })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-amber-500/50"
+ className="w-full px-4 py-2 bg-zinc-800 border border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-orange-600/50 text-white"
/>
-
+
-
+
setFormData({ ...formData, sort_order: parseInt(e.target.value) || 0 })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-amber-500/50"
+ className="w-full px-4 py-2 bg-zinc-800 border border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-orange-600/50 text-white"
/>
-
@@ -307,7 +307,7 @@ export default function PlanManagementClient({ initialPlans }: PlanManagementCli
{isCreating ? 'Create Plan' : 'Save Changes'}
diff --git a/src/components/ResultCard.tsx b/src/components/ResultCard.tsx
index 44443f3..535592b 100644
--- a/src/components/ResultCard.tsx
+++ b/src/components/ResultCard.tsx
@@ -34,75 +34,75 @@ export default function ResultCard({ data, bottleName, image, onShare }: ResultC
{/* The Trading Card */}
-
+
{/* Bottle Image with Vignette */}
{image ? (
) : (
- No Image
+ No Data
)}
-
+
{/* Content Overlay */}
-
-
- Tasting Record
- {bottleName}
+
+
+ Verified Tasting Record
+ {bottleName}
{/* Radar Chart Area */}
-
+
-
-
+
+
-
+
-
- Verified Report
+
+ Authenticated Report
{/* Score Badge */}
-
- {displayScore}
- Score
+
+ {displayScore}
+ Rating
{/* Decorative Elements */}
-
-
+
+
{/* Share Button */}
-
- Share Report
+
+ Share Tasting Report
);
diff --git a/src/components/ScanAndTasteFlow.tsx b/src/components/ScanAndTasteFlow.tsx
index 8ffa1ac..a7b6e0a 100644
--- a/src/components/ScanAndTasteFlow.tsx
+++ b/src/components/ScanAndTasteFlow.tsx
@@ -133,12 +133,12 @@ export default function ScanAndTasteFlow({ isOpen, onClose, base64Image }: ScanA
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
- className="fixed inset-0 z-[60] bg-[#0F1014] flex flex-col h-[100dvh] w-screen overflow-hidden overscroll-none"
+ className="fixed inset-0 z-[60] bg-zinc-950 flex flex-col h-[100dvh] w-screen overflow-hidden overscroll-none"
>
{/* Close Button */}
@@ -160,15 +160,15 @@ export default function ScanAndTasteFlow({ isOpen, onClose, base64Image }: ScanA
-
+
- Analysiere Etikett...
-
+
Analysiere Etikett...
+
KI-gestütztes Scanning
@@ -223,10 +223,10 @@ export default function ScanAndTasteFlow({ isOpen, onClose, base64Image }: ScanA
-
- Speichere Tasting...
+
+ Speichere Tasting...
)}
diff --git a/src/components/SessionBottomSheet.tsx b/src/components/SessionBottomSheet.tsx
index 7020e56..3a3a4db 100644
--- a/src/components/SessionBottomSheet.tsx
+++ b/src/components/SessionBottomSheet.tsx
@@ -76,7 +76,7 @@ export default function SessionBottomSheet({ isOpen, onClose }: SessionBottomShe
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
onClick={onClose}
- className="fixed inset-0 bg-black/60 backdrop-blur-sm z-[80]"
+ className="fixed inset-0 bg-zinc-950/80 backdrop-blur-sm z-[80]"
/>
{/* Sheet */}
@@ -85,12 +85,12 @@ export default function SessionBottomSheet({ isOpen, onClose }: SessionBottomShe
animate={{ y: 0 }}
exit={{ y: '100%' }}
transition={{ type: 'spring', damping: 25, stiffness: 200 }}
- className="fixed bottom-0 left-0 right-0 bg-[#1A1B20] border-t border-white/10 rounded-t-[32px] z-[90] p-8 pb-12 max-h-[80vh] overflow-y-auto shadow-[0_-10px_40px_rgba(0,0,0,0.5)]"
+ className="fixed bottom-0 left-0 right-0 bg-zinc-950 border-t border-zinc-800 rounded-t-[32px] z-[90] p-8 pb-12 max-h-[80vh] overflow-y-auto shadow-[0_-10px_40px_rgba(0,0,0,0.5)]"
>
{/* Drag Handle */}
-
+
- Tasting Session
+ Tasting Session
{/* New Session Input */}
@@ -100,12 +100,12 @@ export default function SessionBottomSheet({ isOpen, onClose }: SessionBottomShe
onChange={(e) => setNewSessionName(e.target.value)}
onKeyDown={(e) => e.key === 'Enter' && handleCreateSession()}
placeholder="Neue Session erstellen..."
- className="w-full bg-white/5 border border-white/10 rounded-2xl py-4 px-6 text-white focus:outline-none focus:border-[#C89D46] transition-colors"
+ className="w-full bg-zinc-900 border border-zinc-800 rounded-2xl py-4 px-6 text-zinc-50 focus:outline-none focus:border-orange-600 transition-colors"
/>
{isCreating ? : }
@@ -113,10 +113,10 @@ export default function SessionBottomSheet({ isOpen, onClose }: SessionBottomShe
{/* Session List */}
- Aktuelle Sessions
+ Aktuelle Sessions
{isLoading ? (
-
+
) : sessions.length > 0 ? (
sessions.map((s) => (
@@ -126,14 +126,14 @@ export default function SessionBottomSheet({ isOpen, onClose }: SessionBottomShe
setActiveSession({ id: s.id, name: s.name });
onClose();
}}
- className={`w-full flex items-center justify-between p-4 rounded-2xl border transition-all ${activeSession?.id === s.id ? 'bg-[#C89D46]/10 border-[#C89D46] text-[#C89D46]' : 'bg-white/5 border-white/5 hover:border-white/20 text-white'}`}
+ className={`w-full flex items-center justify-between p-4 rounded-2xl border transition-all ${activeSession?.id === s.id ? 'bg-orange-600/10 border-orange-600 text-orange-500' : 'bg-zinc-900 border-zinc-800 hover:border-zinc-700 text-zinc-50'}`}
>
{s.name}
- {activeSession?.id === s.id ? : }
+ {activeSession?.id === s.id ? : }
))
) : (
- Keine aktiven Sessions gefunden
+ Keine aktiven Sessions gefunden
)}
diff --git a/src/components/SessionList.tsx b/src/components/SessionList.tsx
index 6d66c2a..98816ea 100644
--- a/src/components/SessionList.tsx
+++ b/src/components/SessionList.tsx
@@ -140,18 +140,18 @@ export default function SessionList() {
};
return (
-
+
-
-
+
+
{t('session.title')}
{!isCollapsed && sessions.length > 0 && (
- ({sessions.length})
+ ({sessions.length})
)}
{isCollapsed ? : }
@@ -166,23 +166,23 @@ export default function SessionList() {
value={newName}
onChange={(e) => setNewName(e.target.value)}
placeholder={t('session.sessionName')}
- className="flex-1 bg-white/5 border border-white/10 rounded-xl px-4 py-2 text-sm text-white placeholder:text-[#8F9096] focus:outline-none focus:border-[#C89D46] transition-colors"
+ className="flex-1 bg-zinc-950 border border-zinc-800 rounded-xl px-4 py-2 text-sm text-zinc-50 placeholder:text-zinc-600 focus:outline-none focus:border-orange-600 transition-colors"
/>
{isCreating ? : }
{isLoading ? (
-
+
) : sessions.length === 0 ? (
-
+
{t('session.noSessions')}
) : (
@@ -191,18 +191,18 @@ export default function SessionList() {
-
+
{session.name}
{session.ended_at && (
- Closed
+ Closed
)}
-
+
{new Date(session.scheduled_at).toLocaleDateString(locale === 'de' ? 'de-DE' : 'en-US')}
@@ -225,28 +225,28 @@ export default function SessionList() {
!session.ended_at ? (
setActiveSession({ id: session.id, name: session.name })}
- className="p-2 bg-white/10 text-white rounded-xl hover:bg-[#C89D46] hover:text-[#0F1014] transition-all"
+ className="p-2 bg-zinc-800 text-zinc-50 rounded-xl hover:bg-orange-600 hover:text-white transition-all"
title="Start Session"
>
) : (
-
+
)
) : (
-
+
)}
-
+
handleDeleteSession(e, session.id)}
disabled={!!isDeleting}
className={`p-2 rounded-xl transition-all ${activeSession?.id === session.id
- ? 'text-[#0F1014]/40 hover:text-[#0F1014]'
- : 'text-[#8F9096] hover:text-red-400'
+ ? 'text-white/40 hover:text-white'
+ : 'text-zinc-600 hover:text-red-500'
}`}
title="Session löschen"
>
@@ -268,17 +268,17 @@ export default function SessionList() {
{sessions.slice(0, 3).map((s, i) => (
-
+
{s.name[0].toUpperCase()}
))}
{sessions.length > 3 && (
-
+
+{sessions.length - 3}
)}
- {sessions.length} Sessions
+ {sessions.length} Sessions
)}
diff --git a/src/components/SessionTimeline.tsx b/src/components/SessionTimeline.tsx
index 3ffce37..eecbeef 100644
--- a/src/components/SessionTimeline.tsx
+++ b/src/components/SessionTimeline.tsx
@@ -61,46 +61,46 @@ export default function SessionTimeline({ tastings, sessionStart }: SessionTimel
return (
{/* Dot */}
-
+
{isSmoky && }
-
+
- Dram #{index + 1}
-
+ Dram #{index + 1}
+
{wallClockTime} ({index === 0 ? 'Start' : `+${diffMinutes}m`})
{isSmoky && (
- Peat Bomb
+ Peat Bomb
)}
{tasting.bottle_name}
{tasting.tags.slice(0, 2).map(tag => (
-
+
{tag}
))}
- {tasting.rating}
- Punkte
+ {tasting.rating}
+ Punkte
{wasPreviousSmoky && timeSinceLastDram < 20 && (
-
-
-
+
+
+
Achtung: Gaumen war noch torf-belegt (nur {timeSinceLastDram}m Abstand).
diff --git a/src/components/StatsDashboard.tsx b/src/components/StatsDashboard.tsx
index 0110061..73fa162 100644
--- a/src/components/StatsDashboard.tsx
+++ b/src/components/StatsDashboard.tsx
@@ -61,8 +61,8 @@ export default function StatsDashboard({ bottles }: StatsDashboardProps) {
label: t('home.stats.avgRating'),
value: `${stats.avgRating}/100`,
icon: Star,
- color: 'text-amber-600',
- bg: 'bg-amber-50 dark:bg-amber-900/20'
+ color: 'text-orange-600',
+ bg: 'bg-orange-900/20'
},
{
label: t('home.stats.topDistillery'),
@@ -74,17 +74,18 @@ export default function StatsDashboard({ bottles }: StatsDashboardProps) {
];
return (
-
+
{statItems.map((item, idx) => {
+ const value = idx === 1 ? stats.totalCount : item.value;
return (
-
- {idx === 1 ? stats.totalCount : item.value}
+
+ {value}
-
+
{item.label}
diff --git a/src/components/TagSelector.tsx b/src/components/TagSelector.tsx
index 50f720e..324be14 100644
--- a/src/components/TagSelector.tsx
+++ b/src/components/TagSelector.tsx
@@ -70,35 +70,35 @@ export default function TagSelector({ category, selectedTagIds, onToggleTag, lab
key={tag.id}
type="button"
onClick={() => onToggleTag(tag.id)}
- className="inline-flex items-center gap-1.5 px-3 py-1.5 bg-amber-600 text-white rounded-full text-[10px] font-black uppercase tracking-tight shadow-sm shadow-amber-600/20 animate-in fade-in zoom-in-95"
+ className="inline-flex items-center gap-1.5 px-3 py-1.5 bg-orange-600 text-white rounded-full text-[10px] font-bold uppercase tracking-tight shadow-sm shadow-orange-600/20 animate-in fade-in zoom-in-95"
>
{tag.is_system_default ? t(`aroma.${tag.name}`) : tag.name}
))
) : (
- Noch keine Tags gewählt...
+ Noch keine Tags gewählt...
)}
{/* Search and Suggest */}
-
+
setSearch(e.target.value)}
placeholder="Tag suchen oder hinzufügen..."
- className="w-full pl-9 pr-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-xs focus:ring-2 focus:ring-amber-500 outline-none transition-all dark:text-zinc-200 placeholder:text-zinc-400"
+ className="w-full pl-9 pr-4 py-2 bg-zinc-900 border border-zinc-800 rounded-xl text-xs focus:ring-1 focus:ring-orange-600 outline-none transition-all text-zinc-200 placeholder:text-zinc-600"
/>
{isCreating && (
-
+
)}
{search && (
-
+
{filteredTags.length > 0 ? (
filteredTags.map(tag => (
@@ -109,17 +109,17 @@ export default function TagSelector({ category, selectedTagIds, onToggleTag, lab
onToggleTag(tag.id);
setSearch('');
}}
- className="w-full px-4 py-2.5 text-left text-xs font-bold text-zinc-700 dark:text-zinc-300 hover:bg-zinc-50 dark:hover:bg-zinc-700/50 flex items-center justify-between border-b border-zinc-100 dark:border-zinc-700 last:border-0"
+ className="w-full px-4 py-2.5 text-left text-xs font-bold text-zinc-300 hover:bg-zinc-800/50 flex items-center justify-between border-b border-zinc-800 last:border-0"
>
{tag.is_system_default ? t(`aroma.${tag.name}`) : tag.name}
- {selectedTagIds.includes(tag.id) && }
+ {selectedTagIds.includes(tag.id) && }
))
) : (
"{search}" als neuen Tag hinzufügen
@@ -133,7 +133,7 @@ export default function TagSelector({ category, selectedTagIds, onToggleTag, lab
{/* AI Suggestions */}
{!search && suggestedTagNames && suggestedTagNames.length > 0 && (
-
+
{t('camera.wbMatchFound') ? 'KI Vorschläge' : 'AI Suggestions'}
@@ -144,7 +144,7 @@ export default function TagSelector({ category, selectedTagIds, onToggleTag, lab
key={tag.id}
type="button"
onClick={() => onToggleTag(tag.id)}
- className="px-2.5 py-1 rounded-lg bg-amber-50 dark:bg-amber-900/20 text-amber-600 dark:text-amber-400 text-[10px] font-bold uppercase tracking-tight hover:bg-amber-100 dark:hover:bg-amber-900/30 transition-colors border border-amber-200 dark:border-amber-800/50 flex items-center gap-1.5"
+ className="px-2.5 py-1 rounded-lg bg-orange-950/20 text-orange-500 text-[10px] font-bold uppercase tracking-tight hover:bg-orange-900/30 transition-colors border border-orange-900/50 flex items-center gap-1.5"
>
{tag.is_system_default ? t(`aroma.${tag.name}`) : tag.name}
@@ -157,7 +157,7 @@ export default function TagSelector({ category, selectedTagIds, onToggleTag, lab
{/* AI Custom Suggestions */}
{!search && suggestedCustomTagNames && suggestedCustomTagNames.length > 0 && (
-
+
Dominante Note anlegen?
@@ -177,7 +177,7 @@ export default function TagSelector({ category, selectedTagIds, onToggleTag, lab
}
setCreatingSuggestion(null);
}}
- className="px-2.5 py-1 rounded-lg bg-zinc-50 dark:bg-zinc-800/50 text-zinc-500 dark:text-zinc-400 text-[10px] font-bold uppercase tracking-tight hover:bg-amber-600 hover:text-white transition-all border border-dashed border-zinc-200 dark:border-zinc-700/50 flex items-center gap-1.5 disabled:opacity-50"
+ className="px-2.5 py-1 rounded-lg bg-zinc-900/50 text-zinc-400 text-[10px] font-bold uppercase tracking-tight hover:bg-orange-600 hover:text-white transition-all border border-dashed border-zinc-800 flex items-center gap-1.5 disabled:opacity-50"
>
{creatingSuggestion === name ? : }
{name}
@@ -188,7 +188,7 @@ export default function TagSelector({ category, selectedTagIds, onToggleTag, lab
)}
{/* Suggestions Chips (limit to 6 random or most common) */}
- {!search && tags.length > 0 && (
+ {!search && (tags || []).length > 0 && (
{(tags || [])
.filter(t => !selectedTagIds.includes(t.id) && (!suggestedTagNames || !suggestedTagNames.some((s: string) => s.toLowerCase() === t.name.toLowerCase())))
@@ -198,7 +198,7 @@ export default function TagSelector({ category, selectedTagIds, onToggleTag, lab
key={tag.id}
type="button"
onClick={() => onToggleTag(tag.id)}
- className="px-2.5 py-1 rounded-lg bg-zinc-100 dark:bg-zinc-800 text-zinc-500 dark:text-zinc-400 text-[10px] font-bold uppercase tracking-tight hover:bg-zinc-200 dark:hover:bg-zinc-700 hover:text-zinc-700 dark:hover:text-zinc-200 transition-colors border border-zinc-200/50 dark:border-zinc-700/50"
+ className="px-2.5 py-1 rounded-lg bg-zinc-900 text-zinc-500 text-[10px] font-bold uppercase tracking-tight hover:bg-zinc-800 hover:text-zinc-200 transition-colors border border-zinc-800"
>
{tag.is_system_default ? t(`aroma.${tag.name}`) : tag.name}
diff --git a/src/components/TastingEditor.tsx b/src/components/TastingEditor.tsx
index 4fa86a3..c4d52b2 100644
--- a/src/components/TastingEditor.tsx
+++ b/src/components/TastingEditor.tsx
@@ -123,18 +123,18 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
};
return (
-
+
{/* Top Context Bar - Flex Child 1 */}
-
+
- Kontext
- {activeSessionName || 'Trinkst du in Gesellschaft?'}
+ Kontext
+ {activeSessionName || 'Trinkst du in Gesellschaft?'}
-
+
@@ -146,50 +146,50 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
-
+
- Palette-Checker
-
+
Palette-Checker
+
Dein letzter Dram "{lastDramInSession?.name}" war torfig. Trink etwas Wasser!
- setShowPaletteWarning(false)} className="text-[10px] font-black uppercase text-amber-500 underline mt-2 block">Verstanden
+ setShowPaletteWarning(false)} className="text-[10px] font-bold uppercase text-orange-500 underline mt-2 block">Verstanden
)}
{/* Hero Section */}
-
+
{image ? (
) : (
- No Photo
+ No Photo
)}
-
+
{bottleMetadata.distillery || 'Destillerie'}
-
{bottleMetadata.name || 'Unbekannter Malt'}
-
+
{bottleMetadata.name || 'Unbekannter Malt'}
+
{bottleMetadata.category || 'Whisky'} {bottleMetadata.abv ? `• ${bottleMetadata.abv}%` : ''} {bottleMetadata.age ? `• ${bottleMetadata.age}y` : ''}
{/* Rating Slider */}
-
+
-
+
-
-
+
+
{t('tasting.rating')}
- {rating}/100
+ {rating}/100
setRating(parseInt(e.target.value))}
- className="w-full h-2 bg-zinc-800 rounded-full appearance-none cursor-pointer accent-amber-600 transition-all"
+ className="w-full h-2 bg-zinc-800 rounded-full appearance-none cursor-pointer accent-orange-600 transition-all"
/>
-
+
Swill
Dram
Legendary
@@ -210,9 +210,9 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
setIsSample(type === 'Sample')}
- className={`flex-1 py-4 rounded-2xl text-[10px] font-black uppercase tracking-widest border transition-all ${(type === 'Sample' ? isSample : !isSample)
- ? 'bg-zinc-100 border-zinc-100 text-zinc-900 shadow-lg'
- : 'bg-transparent border-white/10 text-white/40 hover:border-white/30'
+ className={`flex-1 py-4 rounded-xl text-[10px] font-bold uppercase tracking-widest border transition-all ${(type === 'Sample' ? isSample : !isSample)
+ ? 'bg-orange-600 border-orange-600 text-white shadow-lg'
+ : 'bg-transparent border-zinc-800 text-zinc-500 hover:border-zinc-700'
}`}
>
{type}
@@ -230,14 +230,14 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
{/* Sections */}
{/* Nose Section */}
-
+
-
+
- {t('tasting.nose')}
- Aroma & Bouquet
+ {t('tasting.nose')}
+ Aroma & Bouquet
@@ -245,7 +245,7 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
} />
- Tags
+ Tags
- Eigene Notizen
+ Eigene Notizen
{/* Palate Section */}
-
+
-
+
- {t('tasting.palate')}
- Geschmack & Textur
+ {t('tasting.palate')}
+ Geschmack & Textur
@@ -282,7 +282,7 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
} />
- Tags
+ Tags
- Eigene Notizen
+ Eigene Notizen
{/* Finish Section */}
-
+
-
+
- {t('tasting.finish')}
- Abgang & Nachklang
+ {t('tasting.finish')}
+ Abgang & Nachklang
} />
-
+
- Aroma Tags
+ Aroma Tags
- Gefühl & Textur
+ Gefühl & Textur
- Eigene Notizen
+ Eigene Notizen
@@ -354,14 +354,14 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
{/* Buddy Selection */}
{buddies && buddies.length > 0 && (
-
+
-
+
- Mit wem trinkst du?
- Gesellschaft & Buddies
+ Mit wem trinkst du?
+ Gesellschaft & Buddies
@@ -369,9 +369,9 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
toggleBuddy(buddy.id)}
- className={`px-5 py-3 rounded-2xl text-[10px] font-black uppercase transition-all border flex items-center gap-2 ${selectedBuddyIds.includes(buddy.id)
- ? 'bg-amber-600 border-amber-600 text-white shadow-lg'
- : 'bg-transparent border-white/10 text-white/40 hover:border-white/30'
+ className={`px-5 py-3 rounded-xl text-[10px] font-bold uppercase transition-all border flex items-center gap-2 ${selectedBuddyIds.includes(buddy.id)
+ ? 'bg-orange-600 border-orange-600 text-white shadow-lg'
+ : 'bg-transparent border-zinc-800 text-zinc-500 hover:border-zinc-700'
}`}
>
{selectedBuddyIds.includes(buddy.id) && }
@@ -385,15 +385,15 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
{/* Sticky Footer - Flex Child 3 */}
-
+
{t('tasting.saveTasting')}
- {rating}
+ {rating}
@@ -404,15 +404,15 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
function CustomSlider({ label, value, onChange, icon }: any) {
return (
-
+
-
-
+
+
{icon}
- {label}
+ {label}
- {value}
+ {value}
onChange(parseInt(e.target.value))}
- className="w-full h-1.5 bg-zinc-800 rounded-full appearance-none cursor-pointer accent-[#C89D46] transition-all"
+ className="w-full h-1.5 bg-zinc-800 rounded-full appearance-none cursor-pointer accent-orange-600 transition-all"
/>
);
diff --git a/src/components/UserManagementClient.tsx b/src/components/UserManagementClient.tsx
index 350eb57..1a12f3b 100644
--- a/src/components/UserManagementClient.tsx
+++ b/src/components/UserManagementClient.tsx
@@ -166,61 +166,61 @@ export default function UserManagementClient({ initialUsers, plans }: UserManage
return (
{/* Search Bar */}
-
+
-
+
setSearchTerm(e.target.value)}
- className="w-full pl-10 pr-4 py-3 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-amber-500/50"
+ className="w-full pl-10 pr-4 py-3 bg-zinc-800 border border-zinc-700 rounded-2xl text-sm focus:outline-none focus:ring-2 focus:ring-orange-600/50 text-white"
/>
{/* User Table */}
-
- Users ({filteredUsers.length})
-
+
+ Users ({filteredUsers.length})
+
-
- User
- Balance
- Used
- Daily Limit
- Costs
- Actions
+
+ User
+ Balance
+ Used
+ Daily Limit
+ Costs
+ Actions
-
+
{filteredUsers.map((user) => (
-
-
+
+
- {user.username}
- {user.email}
+ {user.username}
+ {user.email}
-
-
+
+
{user.balance}
-
+
{user.total_used}
-
+
{user.daily_limit || 'Global (80)'}
-
+
G:{user.google_search_cost} / AI:{user.gemini_ai_cost}
-
+
handleEditUser(user)}
- className="inline-flex items-center gap-2 px-3 py-1.5 bg-amber-600 hover:bg-amber-700 text-white rounded-lg text-xs font-bold transition-colors"
+ className="inline-flex items-center gap-2 px-4 py-2 bg-orange-600 hover:bg-orange-700 text-white rounded-xl text-[10px] font-bold uppercase tracking-widest transition-all shadow-md shadow-orange-950/20"
>
Edit
@@ -235,18 +235,18 @@ export default function UserManagementClient({ initialUsers, plans }: UserManage
{/* Edit Modal */}
{editingUser && (
-
-
-
+
+
+
- Edit User
- {editingUser.email}
+ Edit User
+ {editingUser.email}
setEditingUser(null)}
- className="p-2 hover:bg-zinc-100 dark:hover:bg-zinc-800 rounded-lg transition-colors"
+ className="p-2 hover:bg-zinc-800 rounded-xl transition-colors text-zinc-500"
>
-
+
@@ -262,40 +262,40 @@ export default function UserManagementClient({ initialUsers, plans }: UserManage
{/* Current Balance */}
-
- Current Balance
- {editingUser.balance} Credits
+
+ Current Balance
+ {editingUser.balance} Credits
{/* Add/Remove Credits */}
- Adjust Credits
+ Adjust Credits
- Amount
+ Amount
setCreditAmount(e.target.value)}
placeholder="e.g. 100 or -50"
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-amber-500/50"
+ className="w-full px-4 py-2 bg-zinc-800 border border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-orange-600/50 text-white"
/>
- Reason
+ Reason
setReason(e.target.value)}
placeholder="e.g. Monthly bonus"
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-amber-500/50"
+ className="w-full px-4 py-2 bg-zinc-800 border border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-orange-600/50 text-white"
/>
Update Credits
@@ -306,20 +306,20 @@ export default function UserManagementClient({ initialUsers, plans }: UserManage
{/* Subscription Plan */}
- Subscription Plan
+ Subscription Plan
{currentPlan && (
-
- Current Plan
- {currentPlan.display_name}
- {currentPlan.monthly_credits} credits/month
+
+ Current Plan
+ {currentPlan.display_name}
+ {currentPlan.monthly_credits} credits/month
)}
- Assign Plan
+ Assign Plan
Dram bewerten
+ {bottle.distillery} +
++ {bottle.name || t('grid.unknownBottle')} +
+- {bottle.distillery} -
-- {bottle.name || t('grid.unknownBottle')} -
-
-
+
+
{t('buddy.title')}
{!isCollapsed && buddies.length > 0 && (
- ({buddies.length})
+ ({buddies.length})
)}
{isCollapsed ? : }
@@ -106,23 +106,23 @@ export default function BuddyList() {
value={newName}
onChange={(e) => setNewName(e.target.value)}
placeholder={t('buddy.placeholder')}
- className="flex-1 bg-white/5 border border-white/10 rounded-xl px-4 py-2 text-sm text-white placeholder:text-[#8F9096] focus:outline-none focus:border-[#C89D46] transition-colors"
+ className="flex-1 bg-zinc-950 border border-zinc-800 rounded-xl px-4 py-2 text-sm text-zinc-50 placeholder:text-zinc-600 focus:outline-none focus:border-orange-600 transition-colors"
/>
{isAdding ? : }
{isLoading ? (
-
+
) : buddies.length === 0 ? (
-
+
{t('buddy.noBuddies')}
) : (
@@ -130,22 +130,22 @@ export default function BuddyList() {
{buddies.map((buddy) => (
-
+
{buddy.name[0].toUpperCase()}
- {buddy.name}
+ {buddy.name}
{buddy.buddy_profile_id && (
- {t('common.link')}
+ {t('common.link')}
)}
handleDeleteBuddy(buddy.id)}
- className="text-[#8F9096] hover:text-red-400 opacity-0 group-hover:opacity-100 transition-all p-2 hover:bg-white/5 rounded-xl"
+ className="text-zinc-600 hover:text-red-500 opacity-0 group-hover:opacity-100 transition-all p-2 hover:bg-zinc-800 rounded-xl"
>
@@ -160,17 +160,17 @@ export default function BuddyList() {
{buddies.slice(0, 5).map((b, i) => (
-
+
{b.name[0].toUpperCase()}
))}
{buddies.length > 5 && (
-
+
+{buddies.length - 5}
)}
- {buddies.length} Buddies
+ {buddies.length} Buddies
)}
diff --git a/src/components/DramOfTheDay.tsx b/src/components/DramOfTheDay.tsx
index 8bdfe23..d34ad47 100644
--- a/src/components/DramOfTheDay.tsx
+++ b/src/components/DramOfTheDay.tsx
@@ -44,7 +44,7 @@ export default function DramOfTheDay({ bottles }: DramOfTheDayProps) {
{isRolling ? (
@@ -55,23 +55,23 @@ export default function DramOfTheDay({ bottles }: DramOfTheDayProps) {
{suggestion && (
-
-
+
+
setSuggestion(null)}
- className="absolute top-6 right-6 text-zinc-400 hover:text-zinc-600 dark:hover:text-zinc-200"
+ className="absolute top-6 right-6 text-zinc-500 hover:text-orange-600"
>
-
+
- {t('home.dramOfDay.title')}
-
+ {t('home.dramOfDay.title')}
+
{suggestion.name}
{suggestion.distillery && (
@@ -83,13 +83,13 @@ export default function DramOfTheDay({ bottles }: DramOfTheDayProps) {
setSuggestion(null)}
- className="block w-full py-4 bg-zinc-900 dark:bg-zinc-100 text-white dark:text-zinc-900 rounded-2xl font-black uppercase tracking-widest text-xs hover:bg-amber-600 dark:hover:bg-amber-600 hover:text-white transition-all shadow-xl"
+ className="block w-full py-4 bg-orange-600 text-white rounded-2xl font-bold uppercase tracking-widest text-xs hover:bg-orange-700 transition-all shadow-xl shadow-orange-950/20"
>
{t('home.dramOfDay.viewBottle')}
{t('home.dramOfDay.rollAgain')}
diff --git a/src/components/EditBottleForm.tsx b/src/components/EditBottleForm.tsx
index f1758da..6d6223d 100644
--- a/src/components/EditBottleForm.tsx
+++ b/src/components/EditBottleForm.tsx
@@ -123,9 +123,9 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
}
return (
-
+
-
+
{t('bottle.editTitle')}
setFormData({ ...formData, name: e.target.value })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-amber-500"
+ className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
/>
@@ -152,7 +152,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
type="text"
value={formData.distillery}
onChange={(e) => setFormData({ ...formData, distillery: e.target.value })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-amber-500"
+ className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
/>
@@ -161,7 +161,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
type="text"
value={formData.category}
onChange={(e) => setFormData({ ...formData, category: e.target.value })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-amber-500"
+ className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
/>
@@ -172,7 +172,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
step="0.1"
value={formData.abv}
onChange={(e) => setFormData({ ...formData, abv: parseFloat(e.target.value) })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-amber-500"
+ className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
/>
@@ -181,7 +181,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
type="number"
value={formData.age}
onChange={(e) => setFormData({ ...formData, age: parseInt(e.target.value) })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-amber-500"
+ className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
/>
@@ -192,7 +192,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
type="button"
onClick={handleDiscover}
disabled={isSearching}
- className="text-amber-600 hover:text-amber-700 flex items-center gap-1 normal-case font-bold"
+ className="text-orange-600 hover:text-orange-700 flex items-center gap-1 normal-case font-bold"
>
{isSearching ? : }
{t('bottle.autoSearch')}
@@ -202,17 +202,17 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
type="text"
value={formData.whiskybase_id}
onChange={(e) => setFormData({ ...formData, whiskybase_id: e.target.value })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-amber-500"
+ className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
/>
{discoveryResult && (
-
+
Treffer gefunden:
- {discoveryResult.title}
+ {discoveryResult.title}
{t('bottle.applyId')}
@@ -236,7 +236,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
placeholder="0.00"
value={formData.purchase_price}
onChange={(e) => setFormData({ ...formData, purchase_price: e.target.value })}
- className="w-full px-4 py-2 bg-amber-50 dark:bg-amber-900/10 border border-amber-200 dark:border-amber-900/30 rounded-xl outline-none focus:ring-2 focus:ring-amber-500 font-bold text-amber-700 dark:text-amber-400"
+ className="w-full px-4 py-2 bg-zinc-950 border border-zinc-800 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50 font-bold text-zinc-100"
/>
@@ -247,7 +247,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
placeholder="z.B. 2010"
value={formData.distilled_at}
onChange={(e) => setFormData({ ...formData, distilled_at: e.target.value })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-amber-500"
+ className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
/>
@@ -258,7 +258,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
placeholder="z.B. 2022"
value={formData.bottled_at}
onChange={(e) => setFormData({ ...formData, bottled_at: e.target.value })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-amber-500"
+ className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
/>
@@ -269,7 +269,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
placeholder="z.B. Batch 12 oder L-Code"
value={formData.batch_info}
onChange={(e) => setFormData({ ...formData, batch_info: e.target.value })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-amber-500"
+ className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
/>
@@ -279,7 +279,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
{isSaving ? : }
{t('bottle.saveChanges')}
diff --git a/src/components/FloatingScannerButton.tsx b/src/components/FloatingScannerButton.tsx
index 09056ca..039ed29 100644
--- a/src/components/FloatingScannerButton.tsx
+++ b/src/components/FloatingScannerButton.tsx
@@ -38,7 +38,7 @@ export default function FloatingScannerButton({ onImageSelected }: FloatingScann
whileTap={{ scale: 0.9 }}
initial={{ y: 100, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
- className="relative group p-6 rounded-full bg-amber-600 text-black shadow-[0_0_30px_rgba(217,119,6,0.4)] hover:shadow-[0_0_40px_rgba(217,119,6,0.6)] transition-all overflow-hidden"
+ className="relative group p-6 rounded-full bg-orange-600 text-black shadow-lg shadow-orange-950/40 hover:shadow-orange-950/60 transition-all overflow-hidden"
>
{/* Shine Animation */}
{/* Pulse ring */}
-
+
);
diff --git a/src/components/LanguageSwitcher.tsx b/src/components/LanguageSwitcher.tsx
index 0c0943b..d309ec6 100644
--- a/src/components/LanguageSwitcher.tsx
+++ b/src/components/LanguageSwitcher.tsx
@@ -11,8 +11,8 @@ const LanguageSwitcher = () => {
setLocale('de')}
className={`p-1.5 rounded-lg transition-all ${locale === 'de'
- ? 'bg-amber-100 dark:bg-amber-900/30 scale-110 shadow-sm'
- : 'opacity-50 hover:opacity-100 grayscale hover:grayscale-0'
+ ? 'bg-orange-950/30 scale-110 shadow-sm shadow-orange-950/20'
+ : 'opacity-50 hover:opacity-100 grayscale hover:grayscale-0'
}`}
title="Deutsch"
>
@@ -21,8 +21,8 @@ const LanguageSwitcher = () => {
setLocale('en')}
className={`p-1.5 rounded-lg transition-all ${locale === 'en'
- ? 'bg-amber-100 dark:bg-amber-900/30 scale-110 shadow-sm'
- : 'opacity-50 hover:opacity-100 grayscale hover:grayscale-0'
+ ? 'bg-orange-950/30 scale-110 shadow-sm shadow-orange-950/20'
+ : 'opacity-50 hover:opacity-100 grayscale hover:grayscale-0'
}`}
title="English"
>
diff --git a/src/components/OfflineIndicator.tsx b/src/components/OfflineIndicator.tsx
index beb07d0..c8b0c32 100644
--- a/src/components/OfflineIndicator.tsx
+++ b/src/components/OfflineIndicator.tsx
@@ -103,8 +103,8 @@ export default function OfflineIndicator() {
return (
- Offline-Modus aktiv
-
+ Offline-Modus aktiv
+
Alle Funktionen sind vollständig offline verfügbar.
@@ -112,9 +112,9 @@ export default function OfflineIndicator() {
}
return (
-
-
-
+
+
+
{progress > 0 ? `Vorbereitung... ${progress}%` : 'Warte auf System...'}
diff --git a/src/components/PlanManagementClient.tsx b/src/components/PlanManagementClient.tsx
index 2214555..3e08b86 100644
--- a/src/components/PlanManagementClient.tsx
+++ b/src/components/PlanManagementClient.tsx
@@ -129,11 +129,11 @@ export default function PlanManagementClient({ initialPlans }: PlanManagementCli
return (
{/* Actions Bar */}
-
+
Create New Plan
@@ -141,7 +141,7 @@ export default function PlanManagementClient({ initialPlans }: PlanManagementCli
Grant Monthly Credits
@@ -151,8 +151,8 @@ export default function PlanManagementClient({ initialPlans }: PlanManagementCli
{message && (
{message.type === 'success' ? : }
{message.text}
@@ -164,27 +164,27 @@ export default function PlanManagementClient({ initialPlans }: PlanManagementCli
{plans.map((plan) => (
{!plan.is_active && (
-
+
Inactive
)}
- {plan.display_name}
- {plan.name}
+ {plan.display_name}
+ {plan.name}
- {plan.monthly_credits}
- Credits/Month
+ {plan.monthly_credits}
+ Credits/Month
- €{plan.price.toFixed(2)}
- per month
+ €{plan.price.toFixed(2)}
+ per month
{plan.description && (
{plan.description}
@@ -192,14 +192,14 @@ export default function PlanManagementClient({ initialPlans }: PlanManagementCli
handleEdit(plan)}
- className="flex-1 py-2 bg-zinc-900 dark:bg-zinc-100 text-white dark:text-zinc-900 font-bold rounded-lg text-sm transition-colors flex items-center justify-center gap-2"
+ className="flex-1 py-2 bg-zinc-800 hover:bg-zinc-700 text-white font-bold rounded-xl text-[10px] uppercase tracking-widest transition-colors flex items-center justify-center gap-2 border border-zinc-700"
>
Edit
handleDelete(plan.id)}
- className="px-3 py-2 bg-red-600 hover:bg-red-700 text-white font-bold rounded-lg text-sm transition-colors"
+ className="px-3 py-2 bg-red-600/20 hover:bg-red-600 text-red-500 hover:text-white font-bold rounded-xl text-sm transition-colors border border-red-900/50"
>
@@ -210,15 +210,15 @@ export default function PlanManagementClient({ initialPlans }: PlanManagementCli
{/* Edit/Create Modal */}
{(editingPlan || isCreating) && (
-
-
+
+
-
+
{isCreating ? 'Create Plan' : 'Edit Plan'}
{ setEditingPlan(null); setIsCreating(false); }}
- className="p-2 hover:bg-zinc-100 dark:hover:bg-zinc-800 rounded-lg transition-colors"
+ className="p-2 hover:bg-zinc-800 rounded-xl transition-colors text-zinc-500"
>
@@ -227,79 +227,79 @@ export default function PlanManagementClient({ initialPlans }: PlanManagementCli
-
+
setFormData({ ...formData, name: e.target.value })}
placeholder="e.g. starter"
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-amber-500/50"
+ className="w-full px-4 py-2 bg-zinc-800 border border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-orange-600/50 text-white"
/>
-
+
setFormData({ ...formData, display_name: e.target.value })}
placeholder="e.g. Starter"
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-amber-500/50"
+ className="w-full px-4 py-2 bg-zinc-800 border border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-orange-600/50 text-white"
/>
-
+
setFormData({ ...formData, monthly_credits: parseInt(e.target.value) || 0 })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-amber-500/50"
+ className="w-full px-4 py-2 bg-zinc-800 border border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-orange-600/50 text-white"
/>
-
+
setFormData({ ...formData, price: parseFloat(e.target.value) || 0 })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-amber-500/50"
+ className="w-full px-4 py-2 bg-zinc-800 border border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-orange-600/50 text-white"
/>
-
+
-
+
setFormData({ ...formData, sort_order: parseInt(e.target.value) || 0 })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-amber-500/50"
+ className="w-full px-4 py-2 bg-zinc-800 border border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-orange-600/50 text-white"
/>
-
@@ -307,7 +307,7 @@ export default function PlanManagementClient({ initialPlans }: PlanManagementCli
{isCreating ? 'Create Plan' : 'Save Changes'}
diff --git a/src/components/ResultCard.tsx b/src/components/ResultCard.tsx
index 44443f3..535592b 100644
--- a/src/components/ResultCard.tsx
+++ b/src/components/ResultCard.tsx
@@ -34,75 +34,75 @@ export default function ResultCard({ data, bottleName, image, onShare }: ResultC
{/* The Trading Card */}
-
+
{/* Bottle Image with Vignette */}
{image ? (
) : (
- No Image
+ No Data
)}
-
+
{/* Content Overlay */}
-
-
- Tasting Record
- {bottleName}
+
+
+ Verified Tasting Record
+ {bottleName}
{/* Radar Chart Area */}
-
+
-
-
+
+
-
+
-
- Verified Report
+
+ Authenticated Report
{/* Score Badge */}
-
- {displayScore}
- Score
+
+ {displayScore}
+ Rating
{/* Decorative Elements */}
-
-
+
+
{/* Share Button */}
-
- Share Report
+
+ Share Tasting Report
);
diff --git a/src/components/ScanAndTasteFlow.tsx b/src/components/ScanAndTasteFlow.tsx
index 8ffa1ac..a7b6e0a 100644
--- a/src/components/ScanAndTasteFlow.tsx
+++ b/src/components/ScanAndTasteFlow.tsx
@@ -133,12 +133,12 @@ export default function ScanAndTasteFlow({ isOpen, onClose, base64Image }: ScanA
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
- className="fixed inset-0 z-[60] bg-[#0F1014] flex flex-col h-[100dvh] w-screen overflow-hidden overscroll-none"
+ className="fixed inset-0 z-[60] bg-zinc-950 flex flex-col h-[100dvh] w-screen overflow-hidden overscroll-none"
>
{/* Close Button */}
@@ -160,15 +160,15 @@ export default function ScanAndTasteFlow({ isOpen, onClose, base64Image }: ScanA
-
+
- Analysiere Etikett...
-
+
Analysiere Etikett...
+
KI-gestütztes Scanning
@@ -223,10 +223,10 @@ export default function ScanAndTasteFlow({ isOpen, onClose, base64Image }: ScanA
-
- Speichere Tasting...
+
+ Speichere Tasting...
)}
diff --git a/src/components/SessionBottomSheet.tsx b/src/components/SessionBottomSheet.tsx
index 7020e56..3a3a4db 100644
--- a/src/components/SessionBottomSheet.tsx
+++ b/src/components/SessionBottomSheet.tsx
@@ -76,7 +76,7 @@ export default function SessionBottomSheet({ isOpen, onClose }: SessionBottomShe
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
onClick={onClose}
- className="fixed inset-0 bg-black/60 backdrop-blur-sm z-[80]"
+ className="fixed inset-0 bg-zinc-950/80 backdrop-blur-sm z-[80]"
/>
{/* Sheet */}
@@ -85,12 +85,12 @@ export default function SessionBottomSheet({ isOpen, onClose }: SessionBottomShe
animate={{ y: 0 }}
exit={{ y: '100%' }}
transition={{ type: 'spring', damping: 25, stiffness: 200 }}
- className="fixed bottom-0 left-0 right-0 bg-[#1A1B20] border-t border-white/10 rounded-t-[32px] z-[90] p-8 pb-12 max-h-[80vh] overflow-y-auto shadow-[0_-10px_40px_rgba(0,0,0,0.5)]"
+ className="fixed bottom-0 left-0 right-0 bg-zinc-950 border-t border-zinc-800 rounded-t-[32px] z-[90] p-8 pb-12 max-h-[80vh] overflow-y-auto shadow-[0_-10px_40px_rgba(0,0,0,0.5)]"
>
{/* Drag Handle */}
-
+
- Tasting Session
+ Tasting Session
{/* New Session Input */}
@@ -100,12 +100,12 @@ export default function SessionBottomSheet({ isOpen, onClose }: SessionBottomShe
onChange={(e) => setNewSessionName(e.target.value)}
onKeyDown={(e) => e.key === 'Enter' && handleCreateSession()}
placeholder="Neue Session erstellen..."
- className="w-full bg-white/5 border border-white/10 rounded-2xl py-4 px-6 text-white focus:outline-none focus:border-[#C89D46] transition-colors"
+ className="w-full bg-zinc-900 border border-zinc-800 rounded-2xl py-4 px-6 text-zinc-50 focus:outline-none focus:border-orange-600 transition-colors"
/>
{isCreating ? : }
@@ -113,10 +113,10 @@ export default function SessionBottomSheet({ isOpen, onClose }: SessionBottomShe
{/* Session List */}
- Aktuelle Sessions
+ Aktuelle Sessions
{isLoading ? (
-
+
) : sessions.length > 0 ? (
sessions.map((s) => (
@@ -126,14 +126,14 @@ export default function SessionBottomSheet({ isOpen, onClose }: SessionBottomShe
setActiveSession({ id: s.id, name: s.name });
onClose();
}}
- className={`w-full flex items-center justify-between p-4 rounded-2xl border transition-all ${activeSession?.id === s.id ? 'bg-[#C89D46]/10 border-[#C89D46] text-[#C89D46]' : 'bg-white/5 border-white/5 hover:border-white/20 text-white'}`}
+ className={`w-full flex items-center justify-between p-4 rounded-2xl border transition-all ${activeSession?.id === s.id ? 'bg-orange-600/10 border-orange-600 text-orange-500' : 'bg-zinc-900 border-zinc-800 hover:border-zinc-700 text-zinc-50'}`}
>
{s.name}
- {activeSession?.id === s.id ? : }
+ {activeSession?.id === s.id ? : }
))
) : (
- Keine aktiven Sessions gefunden
+ Keine aktiven Sessions gefunden
)}
diff --git a/src/components/SessionList.tsx b/src/components/SessionList.tsx
index 6d66c2a..98816ea 100644
--- a/src/components/SessionList.tsx
+++ b/src/components/SessionList.tsx
@@ -140,18 +140,18 @@ export default function SessionList() {
};
return (
-
+
-
-
+
+
{t('session.title')}
{!isCollapsed && sessions.length > 0 && (
- ({sessions.length})
+ ({sessions.length})
)}
{isCollapsed ? : }
@@ -166,23 +166,23 @@ export default function SessionList() {
value={newName}
onChange={(e) => setNewName(e.target.value)}
placeholder={t('session.sessionName')}
- className="flex-1 bg-white/5 border border-white/10 rounded-xl px-4 py-2 text-sm text-white placeholder:text-[#8F9096] focus:outline-none focus:border-[#C89D46] transition-colors"
+ className="flex-1 bg-zinc-950 border border-zinc-800 rounded-xl px-4 py-2 text-sm text-zinc-50 placeholder:text-zinc-600 focus:outline-none focus:border-orange-600 transition-colors"
/>
{isCreating ? : }
{isLoading ? (
-
+
) : sessions.length === 0 ? (
-
+
{t('session.noSessions')}
) : (
@@ -191,18 +191,18 @@ export default function SessionList() {
-
+
{session.name}
{session.ended_at && (
- Closed
+ Closed
)}
-
+
{new Date(session.scheduled_at).toLocaleDateString(locale === 'de' ? 'de-DE' : 'en-US')}
@@ -225,28 +225,28 @@ export default function SessionList() {
!session.ended_at ? (
setActiveSession({ id: session.id, name: session.name })}
- className="p-2 bg-white/10 text-white rounded-xl hover:bg-[#C89D46] hover:text-[#0F1014] transition-all"
+ className="p-2 bg-zinc-800 text-zinc-50 rounded-xl hover:bg-orange-600 hover:text-white transition-all"
title="Start Session"
>
) : (
-
+
)
) : (
-
+
)}
-
+
handleDeleteSession(e, session.id)}
disabled={!!isDeleting}
className={`p-2 rounded-xl transition-all ${activeSession?.id === session.id
- ? 'text-[#0F1014]/40 hover:text-[#0F1014]'
- : 'text-[#8F9096] hover:text-red-400'
+ ? 'text-white/40 hover:text-white'
+ : 'text-zinc-600 hover:text-red-500'
}`}
title="Session löschen"
>
@@ -268,17 +268,17 @@ export default function SessionList() {
{sessions.slice(0, 3).map((s, i) => (
-
+
{s.name[0].toUpperCase()}
))}
{sessions.length > 3 && (
-
+
+{sessions.length - 3}
)}
- {sessions.length} Sessions
+ {sessions.length} Sessions
)}
diff --git a/src/components/SessionTimeline.tsx b/src/components/SessionTimeline.tsx
index 3ffce37..eecbeef 100644
--- a/src/components/SessionTimeline.tsx
+++ b/src/components/SessionTimeline.tsx
@@ -61,46 +61,46 @@ export default function SessionTimeline({ tastings, sessionStart }: SessionTimel
return (
{/* Dot */}
-
+
{isSmoky && }
-
+
- Dram #{index + 1}
-
+ Dram #{index + 1}
+
{wallClockTime} ({index === 0 ? 'Start' : `+${diffMinutes}m`})
{isSmoky && (
- Peat Bomb
+ Peat Bomb
)}
{tasting.bottle_name}
{tasting.tags.slice(0, 2).map(tag => (
-
+
{tag}
))}
- {tasting.rating}
- Punkte
+ {tasting.rating}
+ Punkte
{wasPreviousSmoky && timeSinceLastDram < 20 && (
-
-
-
+
+
+
Achtung: Gaumen war noch torf-belegt (nur {timeSinceLastDram}m Abstand).
diff --git a/src/components/StatsDashboard.tsx b/src/components/StatsDashboard.tsx
index 0110061..73fa162 100644
--- a/src/components/StatsDashboard.tsx
+++ b/src/components/StatsDashboard.tsx
@@ -61,8 +61,8 @@ export default function StatsDashboard({ bottles }: StatsDashboardProps) {
label: t('home.stats.avgRating'),
value: `${stats.avgRating}/100`,
icon: Star,
- color: 'text-amber-600',
- bg: 'bg-amber-50 dark:bg-amber-900/20'
+ color: 'text-orange-600',
+ bg: 'bg-orange-900/20'
},
{
label: t('home.stats.topDistillery'),
@@ -74,17 +74,18 @@ export default function StatsDashboard({ bottles }: StatsDashboardProps) {
];
return (
-
+
{statItems.map((item, idx) => {
+ const value = idx === 1 ? stats.totalCount : item.value;
return (
-
- {idx === 1 ? stats.totalCount : item.value}
+
+ {value}
-
+
{item.label}
diff --git a/src/components/TagSelector.tsx b/src/components/TagSelector.tsx
index 50f720e..324be14 100644
--- a/src/components/TagSelector.tsx
+++ b/src/components/TagSelector.tsx
@@ -70,35 +70,35 @@ export default function TagSelector({ category, selectedTagIds, onToggleTag, lab
key={tag.id}
type="button"
onClick={() => onToggleTag(tag.id)}
- className="inline-flex items-center gap-1.5 px-3 py-1.5 bg-amber-600 text-white rounded-full text-[10px] font-black uppercase tracking-tight shadow-sm shadow-amber-600/20 animate-in fade-in zoom-in-95"
+ className="inline-flex items-center gap-1.5 px-3 py-1.5 bg-orange-600 text-white rounded-full text-[10px] font-bold uppercase tracking-tight shadow-sm shadow-orange-600/20 animate-in fade-in zoom-in-95"
>
{tag.is_system_default ? t(`aroma.${tag.name}`) : tag.name}
))
) : (
- Noch keine Tags gewählt...
+ Noch keine Tags gewählt...
)}
{/* Search and Suggest */}
-
+
setSearch(e.target.value)}
placeholder="Tag suchen oder hinzufügen..."
- className="w-full pl-9 pr-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-xs focus:ring-2 focus:ring-amber-500 outline-none transition-all dark:text-zinc-200 placeholder:text-zinc-400"
+ className="w-full pl-9 pr-4 py-2 bg-zinc-900 border border-zinc-800 rounded-xl text-xs focus:ring-1 focus:ring-orange-600 outline-none transition-all text-zinc-200 placeholder:text-zinc-600"
/>
{isCreating && (
-
+
)}
{search && (
-
+
{filteredTags.length > 0 ? (
filteredTags.map(tag => (
@@ -109,17 +109,17 @@ export default function TagSelector({ category, selectedTagIds, onToggleTag, lab
onToggleTag(tag.id);
setSearch('');
}}
- className="w-full px-4 py-2.5 text-left text-xs font-bold text-zinc-700 dark:text-zinc-300 hover:bg-zinc-50 dark:hover:bg-zinc-700/50 flex items-center justify-between border-b border-zinc-100 dark:border-zinc-700 last:border-0"
+ className="w-full px-4 py-2.5 text-left text-xs font-bold text-zinc-300 hover:bg-zinc-800/50 flex items-center justify-between border-b border-zinc-800 last:border-0"
>
{tag.is_system_default ? t(`aroma.${tag.name}`) : tag.name}
- {selectedTagIds.includes(tag.id) && }
+ {selectedTagIds.includes(tag.id) && }
))
) : (
"{search}" als neuen Tag hinzufügen
@@ -133,7 +133,7 @@ export default function TagSelector({ category, selectedTagIds, onToggleTag, lab
{/* AI Suggestions */}
{!search && suggestedTagNames && suggestedTagNames.length > 0 && (
-
+
{t('camera.wbMatchFound') ? 'KI Vorschläge' : 'AI Suggestions'}
@@ -144,7 +144,7 @@ export default function TagSelector({ category, selectedTagIds, onToggleTag, lab
key={tag.id}
type="button"
onClick={() => onToggleTag(tag.id)}
- className="px-2.5 py-1 rounded-lg bg-amber-50 dark:bg-amber-900/20 text-amber-600 dark:text-amber-400 text-[10px] font-bold uppercase tracking-tight hover:bg-amber-100 dark:hover:bg-amber-900/30 transition-colors border border-amber-200 dark:border-amber-800/50 flex items-center gap-1.5"
+ className="px-2.5 py-1 rounded-lg bg-orange-950/20 text-orange-500 text-[10px] font-bold uppercase tracking-tight hover:bg-orange-900/30 transition-colors border border-orange-900/50 flex items-center gap-1.5"
>
{tag.is_system_default ? t(`aroma.${tag.name}`) : tag.name}
@@ -157,7 +157,7 @@ export default function TagSelector({ category, selectedTagIds, onToggleTag, lab
{/* AI Custom Suggestions */}
{!search && suggestedCustomTagNames && suggestedCustomTagNames.length > 0 && (
-
+
Dominante Note anlegen?
@@ -177,7 +177,7 @@ export default function TagSelector({ category, selectedTagIds, onToggleTag, lab
}
setCreatingSuggestion(null);
}}
- className="px-2.5 py-1 rounded-lg bg-zinc-50 dark:bg-zinc-800/50 text-zinc-500 dark:text-zinc-400 text-[10px] font-bold uppercase tracking-tight hover:bg-amber-600 hover:text-white transition-all border border-dashed border-zinc-200 dark:border-zinc-700/50 flex items-center gap-1.5 disabled:opacity-50"
+ className="px-2.5 py-1 rounded-lg bg-zinc-900/50 text-zinc-400 text-[10px] font-bold uppercase tracking-tight hover:bg-orange-600 hover:text-white transition-all border border-dashed border-zinc-800 flex items-center gap-1.5 disabled:opacity-50"
>
{creatingSuggestion === name ? : }
{name}
@@ -188,7 +188,7 @@ export default function TagSelector({ category, selectedTagIds, onToggleTag, lab
)}
{/* Suggestions Chips (limit to 6 random or most common) */}
- {!search && tags.length > 0 && (
+ {!search && (tags || []).length > 0 && (
{(tags || [])
.filter(t => !selectedTagIds.includes(t.id) && (!suggestedTagNames || !suggestedTagNames.some((s: string) => s.toLowerCase() === t.name.toLowerCase())))
@@ -198,7 +198,7 @@ export default function TagSelector({ category, selectedTagIds, onToggleTag, lab
key={tag.id}
type="button"
onClick={() => onToggleTag(tag.id)}
- className="px-2.5 py-1 rounded-lg bg-zinc-100 dark:bg-zinc-800 text-zinc-500 dark:text-zinc-400 text-[10px] font-bold uppercase tracking-tight hover:bg-zinc-200 dark:hover:bg-zinc-700 hover:text-zinc-700 dark:hover:text-zinc-200 transition-colors border border-zinc-200/50 dark:border-zinc-700/50"
+ className="px-2.5 py-1 rounded-lg bg-zinc-900 text-zinc-500 text-[10px] font-bold uppercase tracking-tight hover:bg-zinc-800 hover:text-zinc-200 transition-colors border border-zinc-800"
>
{tag.is_system_default ? t(`aroma.${tag.name}`) : tag.name}
diff --git a/src/components/TastingEditor.tsx b/src/components/TastingEditor.tsx
index 4fa86a3..c4d52b2 100644
--- a/src/components/TastingEditor.tsx
+++ b/src/components/TastingEditor.tsx
@@ -123,18 +123,18 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
};
return (
-
+
{/* Top Context Bar - Flex Child 1 */}
-
+
- Kontext
- {activeSessionName || 'Trinkst du in Gesellschaft?'}
+ Kontext
+ {activeSessionName || 'Trinkst du in Gesellschaft?'}
-
+
@@ -146,50 +146,50 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
-
+
- Palette-Checker
-
+
Palette-Checker
+
Dein letzter Dram "{lastDramInSession?.name}" war torfig. Trink etwas Wasser!
- setShowPaletteWarning(false)} className="text-[10px] font-black uppercase text-amber-500 underline mt-2 block">Verstanden
+ setShowPaletteWarning(false)} className="text-[10px] font-bold uppercase text-orange-500 underline mt-2 block">Verstanden
)}
{/* Hero Section */}
-
+
{image ? (
) : (
- No Photo
+ No Photo
)}
-
+
{bottleMetadata.distillery || 'Destillerie'}
-
{bottleMetadata.name || 'Unbekannter Malt'}
-
+
{bottleMetadata.name || 'Unbekannter Malt'}
+
{bottleMetadata.category || 'Whisky'} {bottleMetadata.abv ? `• ${bottleMetadata.abv}%` : ''} {bottleMetadata.age ? `• ${bottleMetadata.age}y` : ''}
{/* Rating Slider */}
-
+
-
+
-
-
+
+
{t('tasting.rating')}
- {rating}/100
+ {rating}/100
setRating(parseInt(e.target.value))}
- className="w-full h-2 bg-zinc-800 rounded-full appearance-none cursor-pointer accent-amber-600 transition-all"
+ className="w-full h-2 bg-zinc-800 rounded-full appearance-none cursor-pointer accent-orange-600 transition-all"
/>
-
+
Swill
Dram
Legendary
@@ -210,9 +210,9 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
setIsSample(type === 'Sample')}
- className={`flex-1 py-4 rounded-2xl text-[10px] font-black uppercase tracking-widest border transition-all ${(type === 'Sample' ? isSample : !isSample)
- ? 'bg-zinc-100 border-zinc-100 text-zinc-900 shadow-lg'
- : 'bg-transparent border-white/10 text-white/40 hover:border-white/30'
+ className={`flex-1 py-4 rounded-xl text-[10px] font-bold uppercase tracking-widest border transition-all ${(type === 'Sample' ? isSample : !isSample)
+ ? 'bg-orange-600 border-orange-600 text-white shadow-lg'
+ : 'bg-transparent border-zinc-800 text-zinc-500 hover:border-zinc-700'
}`}
>
{type}
@@ -230,14 +230,14 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
{/* Sections */}
{/* Nose Section */}
-
+
-
+
- {t('tasting.nose')}
- Aroma & Bouquet
+ {t('tasting.nose')}
+ Aroma & Bouquet
@@ -245,7 +245,7 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
} />
- Tags
+ Tags
- Eigene Notizen
+ Eigene Notizen
{/* Palate Section */}
-
+
-
+
- {t('tasting.palate')}
- Geschmack & Textur
+ {t('tasting.palate')}
+ Geschmack & Textur
@@ -282,7 +282,7 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
} />
- Tags
+ Tags
- Eigene Notizen
+ Eigene Notizen
{/* Finish Section */}
-
+
-
+
- {t('tasting.finish')}
- Abgang & Nachklang
+ {t('tasting.finish')}
+ Abgang & Nachklang
} />
-
+
- Aroma Tags
+ Aroma Tags
- Gefühl & Textur
+ Gefühl & Textur
- Eigene Notizen
+ Eigene Notizen
@@ -354,14 +354,14 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
{/* Buddy Selection */}
{buddies && buddies.length > 0 && (
-
+
-
+
- Mit wem trinkst du?
- Gesellschaft & Buddies
+ Mit wem trinkst du?
+ Gesellschaft & Buddies
@@ -369,9 +369,9 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
toggleBuddy(buddy.id)}
- className={`px-5 py-3 rounded-2xl text-[10px] font-black uppercase transition-all border flex items-center gap-2 ${selectedBuddyIds.includes(buddy.id)
- ? 'bg-amber-600 border-amber-600 text-white shadow-lg'
- : 'bg-transparent border-white/10 text-white/40 hover:border-white/30'
+ className={`px-5 py-3 rounded-xl text-[10px] font-bold uppercase transition-all border flex items-center gap-2 ${selectedBuddyIds.includes(buddy.id)
+ ? 'bg-orange-600 border-orange-600 text-white shadow-lg'
+ : 'bg-transparent border-zinc-800 text-zinc-500 hover:border-zinc-700'
}`}
>
{selectedBuddyIds.includes(buddy.id) && }
@@ -385,15 +385,15 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
{/* Sticky Footer - Flex Child 3 */}
-
+
{t('tasting.saveTasting')}
- {rating}
+ {rating}
@@ -404,15 +404,15 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
function CustomSlider({ label, value, onChange, icon }: any) {
return (
-
+
-
-
+
+
{icon}
- {label}
+ {label}
- {value}
+ {value}
onChange(parseInt(e.target.value))}
- className="w-full h-1.5 bg-zinc-800 rounded-full appearance-none cursor-pointer accent-[#C89D46] transition-all"
+ className="w-full h-1.5 bg-zinc-800 rounded-full appearance-none cursor-pointer accent-orange-600 transition-all"
/>
);
diff --git a/src/components/UserManagementClient.tsx b/src/components/UserManagementClient.tsx
index 350eb57..1a12f3b 100644
--- a/src/components/UserManagementClient.tsx
+++ b/src/components/UserManagementClient.tsx
@@ -166,61 +166,61 @@ export default function UserManagementClient({ initialUsers, plans }: UserManage
return (
{/* Search Bar */}
-
+
-
+
setSearchTerm(e.target.value)}
- className="w-full pl-10 pr-4 py-3 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-amber-500/50"
+ className="w-full pl-10 pr-4 py-3 bg-zinc-800 border border-zinc-700 rounded-2xl text-sm focus:outline-none focus:ring-2 focus:ring-orange-600/50 text-white"
/>
{/* User Table */}
-
- Users ({filteredUsers.length})
-
+
+ Users ({filteredUsers.length})
+
-
- User
- Balance
- Used
- Daily Limit
- Costs
- Actions
+
+ User
+ Balance
+ Used
+ Daily Limit
+ Costs
+ Actions
-
+
{filteredUsers.map((user) => (
-
-
+
+
- {user.username}
- {user.email}
+ {user.username}
+ {user.email}
-
-
+
+
{user.balance}
-
+
{user.total_used}
-
+
{user.daily_limit || 'Global (80)'}
-
+
G:{user.google_search_cost} / AI:{user.gemini_ai_cost}
-
+
handleEditUser(user)}
- className="inline-flex items-center gap-2 px-3 py-1.5 bg-amber-600 hover:bg-amber-700 text-white rounded-lg text-xs font-bold transition-colors"
+ className="inline-flex items-center gap-2 px-4 py-2 bg-orange-600 hover:bg-orange-700 text-white rounded-xl text-[10px] font-bold uppercase tracking-widest transition-all shadow-md shadow-orange-950/20"
>
Edit
@@ -235,18 +235,18 @@ export default function UserManagementClient({ initialUsers, plans }: UserManage
{/* Edit Modal */}
{editingUser && (
-
-
-
+
+
+
- Edit User
- {editingUser.email}
+ Edit User
+ {editingUser.email}
setEditingUser(null)}
- className="p-2 hover:bg-zinc-100 dark:hover:bg-zinc-800 rounded-lg transition-colors"
+ className="p-2 hover:bg-zinc-800 rounded-xl transition-colors text-zinc-500"
>
-
+
@@ -262,40 +262,40 @@ export default function UserManagementClient({ initialUsers, plans }: UserManage
{/* Current Balance */}
-
- Current Balance
- {editingUser.balance} Credits
+
+ Current Balance
+ {editingUser.balance} Credits
{/* Add/Remove Credits */}
- Adjust Credits
+ Adjust Credits
- Amount
+ Amount
setCreditAmount(e.target.value)}
placeholder="e.g. 100 or -50"
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-amber-500/50"
+ className="w-full px-4 py-2 bg-zinc-800 border border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-orange-600/50 text-white"
/>
- Reason
+ Reason
setReason(e.target.value)}
placeholder="e.g. Monthly bonus"
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-amber-500/50"
+ className="w-full px-4 py-2 bg-zinc-800 border border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-orange-600/50 text-white"
/>
Update Credits
@@ -306,20 +306,20 @@ export default function UserManagementClient({ initialUsers, plans }: UserManage
{/* Subscription Plan */}
- Subscription Plan
+ Subscription Plan
{currentPlan && (
-
- Current Plan
- {currentPlan.display_name}
- {currentPlan.monthly_credits} credits/month
+
+ Current Plan
+ {currentPlan.display_name}
+ {currentPlan.monthly_credits} credits/month
)}
- Assign Plan
+ Assign Plan
{t('home.dramOfDay.title')}
-
+ {t('home.dramOfDay.title')}
+
{suggestion.name}
{suggestion.distillery && (
@@ -83,13 +83,13 @@ export default function DramOfTheDay({ bottles }: DramOfTheDayProps) {
setSuggestion(null)}
- className="block w-full py-4 bg-zinc-900 dark:bg-zinc-100 text-white dark:text-zinc-900 rounded-2xl font-black uppercase tracking-widest text-xs hover:bg-amber-600 dark:hover:bg-amber-600 hover:text-white transition-all shadow-xl"
+ className="block w-full py-4 bg-orange-600 text-white rounded-2xl font-bold uppercase tracking-widest text-xs hover:bg-orange-700 transition-all shadow-xl shadow-orange-950/20"
>
{t('home.dramOfDay.viewBottle')}
{t('home.dramOfDay.rollAgain')}
diff --git a/src/components/EditBottleForm.tsx b/src/components/EditBottleForm.tsx
index f1758da..6d6223d 100644
--- a/src/components/EditBottleForm.tsx
+++ b/src/components/EditBottleForm.tsx
@@ -123,9 +123,9 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
}
return (
-
+
-
+
{t('bottle.editTitle')}
setFormData({ ...formData, name: e.target.value })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-amber-500"
+ className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
/>
@@ -152,7 +152,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
type="text"
value={formData.distillery}
onChange={(e) => setFormData({ ...formData, distillery: e.target.value })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-amber-500"
+ className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
/>
@@ -161,7 +161,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
type="text"
value={formData.category}
onChange={(e) => setFormData({ ...formData, category: e.target.value })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-amber-500"
+ className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
/>
@@ -172,7 +172,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
step="0.1"
value={formData.abv}
onChange={(e) => setFormData({ ...formData, abv: parseFloat(e.target.value) })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-amber-500"
+ className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
/>
@@ -181,7 +181,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
type="number"
value={formData.age}
onChange={(e) => setFormData({ ...formData, age: parseInt(e.target.value) })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-amber-500"
+ className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
/>
@@ -192,7 +192,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
type="button"
onClick={handleDiscover}
disabled={isSearching}
- className="text-amber-600 hover:text-amber-700 flex items-center gap-1 normal-case font-bold"
+ className="text-orange-600 hover:text-orange-700 flex items-center gap-1 normal-case font-bold"
>
{isSearching ? : }
{t('bottle.autoSearch')}
@@ -202,17 +202,17 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
type="text"
value={formData.whiskybase_id}
onChange={(e) => setFormData({ ...formData, whiskybase_id: e.target.value })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-amber-500"
+ className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
/>
{discoveryResult && (
-
+
Treffer gefunden:
- {discoveryResult.title}
+ {discoveryResult.title}
{t('bottle.applyId')}
@@ -236,7 +236,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
placeholder="0.00"
value={formData.purchase_price}
onChange={(e) => setFormData({ ...formData, purchase_price: e.target.value })}
- className="w-full px-4 py-2 bg-amber-50 dark:bg-amber-900/10 border border-amber-200 dark:border-amber-900/30 rounded-xl outline-none focus:ring-2 focus:ring-amber-500 font-bold text-amber-700 dark:text-amber-400"
+ className="w-full px-4 py-2 bg-zinc-950 border border-zinc-800 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50 font-bold text-zinc-100"
/>
@@ -247,7 +247,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
placeholder="z.B. 2010"
value={formData.distilled_at}
onChange={(e) => setFormData({ ...formData, distilled_at: e.target.value })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-amber-500"
+ className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
/>
@@ -258,7 +258,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
placeholder="z.B. 2022"
value={formData.bottled_at}
onChange={(e) => setFormData({ ...formData, bottled_at: e.target.value })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-amber-500"
+ className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
/>
@@ -269,7 +269,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
placeholder="z.B. Batch 12 oder L-Code"
value={formData.batch_info}
onChange={(e) => setFormData({ ...formData, batch_info: e.target.value })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-amber-500"
+ className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
/>
+
{t('bottle.editTitle')}
setFormData({ ...formData, name: e.target.value })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-amber-500"
+ className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
/>
Treffer gefunden:
-{discoveryResult.title}
+{discoveryResult.title}
{plan.display_name}
-{plan.name}
+{plan.display_name}
+{plan.name}
{plan.description}
@@ -192,14 +192,14 @@ export default function PlanManagementClient({ initialPlans }: PlanManagementCli
+
{isCreating ? 'Create Plan' : 'Edit Plan'}
{ setEditingPlan(null); setIsCreating(false); }}
- className="p-2 hover:bg-zinc-100 dark:hover:bg-zinc-800 rounded-lg transition-colors"
+ className="p-2 hover:bg-zinc-800 rounded-xl transition-colors text-zinc-500"
>
@@ -227,79 +227,79 @@ export default function PlanManagementClient({ initialPlans }: PlanManagementCli
-
+
setFormData({ ...formData, name: e.target.value })}
placeholder="e.g. starter"
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-amber-500/50"
+ className="w-full px-4 py-2 bg-zinc-800 border border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-orange-600/50 text-white"
/>
-
+
setFormData({ ...formData, display_name: e.target.value })}
placeholder="e.g. Starter"
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-amber-500/50"
+ className="w-full px-4 py-2 bg-zinc-800 border border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-orange-600/50 text-white"
/>
-
+
setFormData({ ...formData, monthly_credits: parseInt(e.target.value) || 0 })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-amber-500/50"
+ className="w-full px-4 py-2 bg-zinc-800 border border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-orange-600/50 text-white"
/>
-
+
setFormData({ ...formData, price: parseFloat(e.target.value) || 0 })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-amber-500/50"
+ className="w-full px-4 py-2 bg-zinc-800 border border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-orange-600/50 text-white"
/>
-
+
-
+
setFormData({ ...formData, sort_order: parseInt(e.target.value) || 0 })}
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-amber-500/50"
+ className="w-full px-4 py-2 bg-zinc-800 border border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-orange-600/50 text-white"
/>
-
@@ -307,7 +307,7 @@ export default function PlanManagementClient({ initialPlans }: PlanManagementCli
{isCreating ? 'Create Plan' : 'Save Changes'}
diff --git a/src/components/ResultCard.tsx b/src/components/ResultCard.tsx
index 44443f3..535592b 100644
--- a/src/components/ResultCard.tsx
+++ b/src/components/ResultCard.tsx
@@ -34,75 +34,75 @@ export default function ResultCard({ data, bottleName, image, onShare }: ResultC
{/* The Trading Card */}
-
+
{/* Bottle Image with Vignette */}
{image ? (
) : (
- No Image
+ No Data
)}
-
+
{/* Content Overlay */}
-
-
- Tasting Record
- {bottleName}
+
+
+ Verified Tasting Record
+ {bottleName}
{/* Radar Chart Area */}
-
+
-
-
+
+
-
+
-
- Verified Report
+
+ Authenticated Report
{/* Score Badge */}
-
- {displayScore}
- Score
+
+ {displayScore}
+ Rating
{/* Decorative Elements */}
-
-
+
+
{/* Share Button */}
-
- Share Report
+
+ Share Tasting Report
);
diff --git a/src/components/ScanAndTasteFlow.tsx b/src/components/ScanAndTasteFlow.tsx
index 8ffa1ac..a7b6e0a 100644
--- a/src/components/ScanAndTasteFlow.tsx
+++ b/src/components/ScanAndTasteFlow.tsx
@@ -133,12 +133,12 @@ export default function ScanAndTasteFlow({ isOpen, onClose, base64Image }: ScanA
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
- className="fixed inset-0 z-[60] bg-[#0F1014] flex flex-col h-[100dvh] w-screen overflow-hidden overscroll-none"
+ className="fixed inset-0 z-[60] bg-zinc-950 flex flex-col h-[100dvh] w-screen overflow-hidden overscroll-none"
>
{/* Close Button */}
@@ -160,15 +160,15 @@ export default function ScanAndTasteFlow({ isOpen, onClose, base64Image }: ScanA
-
+
- Analysiere Etikett...
-
+
Analysiere Etikett...
+
KI-gestütztes Scanning
@@ -223,10 +223,10 @@ export default function ScanAndTasteFlow({ isOpen, onClose, base64Image }: ScanA
-
- Speichere Tasting...
+
+ Speichere Tasting...
)}
diff --git a/src/components/SessionBottomSheet.tsx b/src/components/SessionBottomSheet.tsx
index 7020e56..3a3a4db 100644
--- a/src/components/SessionBottomSheet.tsx
+++ b/src/components/SessionBottomSheet.tsx
@@ -76,7 +76,7 @@ export default function SessionBottomSheet({ isOpen, onClose }: SessionBottomShe
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
onClick={onClose}
- className="fixed inset-0 bg-black/60 backdrop-blur-sm z-[80]"
+ className="fixed inset-0 bg-zinc-950/80 backdrop-blur-sm z-[80]"
/>
{/* Sheet */}
@@ -85,12 +85,12 @@ export default function SessionBottomSheet({ isOpen, onClose }: SessionBottomShe
animate={{ y: 0 }}
exit={{ y: '100%' }}
transition={{ type: 'spring', damping: 25, stiffness: 200 }}
- className="fixed bottom-0 left-0 right-0 bg-[#1A1B20] border-t border-white/10 rounded-t-[32px] z-[90] p-8 pb-12 max-h-[80vh] overflow-y-auto shadow-[0_-10px_40px_rgba(0,0,0,0.5)]"
+ className="fixed bottom-0 left-0 right-0 bg-zinc-950 border-t border-zinc-800 rounded-t-[32px] z-[90] p-8 pb-12 max-h-[80vh] overflow-y-auto shadow-[0_-10px_40px_rgba(0,0,0,0.5)]"
>
{/* Drag Handle */}
-
+
- Tasting Session
+ Tasting Session
{/* New Session Input */}
@@ -100,12 +100,12 @@ export default function SessionBottomSheet({ isOpen, onClose }: SessionBottomShe
onChange={(e) => setNewSessionName(e.target.value)}
onKeyDown={(e) => e.key === 'Enter' && handleCreateSession()}
placeholder="Neue Session erstellen..."
- className="w-full bg-white/5 border border-white/10 rounded-2xl py-4 px-6 text-white focus:outline-none focus:border-[#C89D46] transition-colors"
+ className="w-full bg-zinc-900 border border-zinc-800 rounded-2xl py-4 px-6 text-zinc-50 focus:outline-none focus:border-orange-600 transition-colors"
/>
{isCreating ? : }
@@ -113,10 +113,10 @@ export default function SessionBottomSheet({ isOpen, onClose }: SessionBottomShe
{/* Session List */}
- Aktuelle Sessions
+ Aktuelle Sessions
{isLoading ? (
-
+
) : sessions.length > 0 ? (
sessions.map((s) => (
@@ -126,14 +126,14 @@ export default function SessionBottomSheet({ isOpen, onClose }: SessionBottomShe
setActiveSession({ id: s.id, name: s.name });
onClose();
}}
- className={`w-full flex items-center justify-between p-4 rounded-2xl border transition-all ${activeSession?.id === s.id ? 'bg-[#C89D46]/10 border-[#C89D46] text-[#C89D46]' : 'bg-white/5 border-white/5 hover:border-white/20 text-white'}`}
+ className={`w-full flex items-center justify-between p-4 rounded-2xl border transition-all ${activeSession?.id === s.id ? 'bg-orange-600/10 border-orange-600 text-orange-500' : 'bg-zinc-900 border-zinc-800 hover:border-zinc-700 text-zinc-50'}`}
>
{s.name}
- {activeSession?.id === s.id ? : }
+ {activeSession?.id === s.id ? : }
))
) : (
- Keine aktiven Sessions gefunden
+ Keine aktiven Sessions gefunden
)}
diff --git a/src/components/SessionList.tsx b/src/components/SessionList.tsx
index 6d66c2a..98816ea 100644
--- a/src/components/SessionList.tsx
+++ b/src/components/SessionList.tsx
@@ -140,18 +140,18 @@ export default function SessionList() {
};
return (
-
+
-
-
+
+
{t('session.title')}
{!isCollapsed && sessions.length > 0 && (
- ({sessions.length})
+ ({sessions.length})
)}
{isCollapsed ? : }
@@ -166,23 +166,23 @@ export default function SessionList() {
value={newName}
onChange={(e) => setNewName(e.target.value)}
placeholder={t('session.sessionName')}
- className="flex-1 bg-white/5 border border-white/10 rounded-xl px-4 py-2 text-sm text-white placeholder:text-[#8F9096] focus:outline-none focus:border-[#C89D46] transition-colors"
+ className="flex-1 bg-zinc-950 border border-zinc-800 rounded-xl px-4 py-2 text-sm text-zinc-50 placeholder:text-zinc-600 focus:outline-none focus:border-orange-600 transition-colors"
/>
{isCreating ? : }
{isLoading ? (
-
+
) : sessions.length === 0 ? (
-
+
{t('session.noSessions')}
) : (
@@ -191,18 +191,18 @@ export default function SessionList() {
-
+
{session.name}
{session.ended_at && (
- Closed
+ Closed
)}
-
+
{new Date(session.scheduled_at).toLocaleDateString(locale === 'de' ? 'de-DE' : 'en-US')}
@@ -225,28 +225,28 @@ export default function SessionList() {
!session.ended_at ? (
setActiveSession({ id: session.id, name: session.name })}
- className="p-2 bg-white/10 text-white rounded-xl hover:bg-[#C89D46] hover:text-[#0F1014] transition-all"
+ className="p-2 bg-zinc-800 text-zinc-50 rounded-xl hover:bg-orange-600 hover:text-white transition-all"
title="Start Session"
>
) : (
-
+
)
) : (
-
+
)}
-
+
handleDeleteSession(e, session.id)}
disabled={!!isDeleting}
className={`p-2 rounded-xl transition-all ${activeSession?.id === session.id
- ? 'text-[#0F1014]/40 hover:text-[#0F1014]'
- : 'text-[#8F9096] hover:text-red-400'
+ ? 'text-white/40 hover:text-white'
+ : 'text-zinc-600 hover:text-red-500'
}`}
title="Session löschen"
>
@@ -268,17 +268,17 @@ export default function SessionList() {
{sessions.slice(0, 3).map((s, i) => (
-
+
{s.name[0].toUpperCase()}
))}
{sessions.length > 3 && (
-
+
+{sessions.length - 3}
)}
- {sessions.length} Sessions
+ {sessions.length} Sessions
)}
diff --git a/src/components/SessionTimeline.tsx b/src/components/SessionTimeline.tsx
index 3ffce37..eecbeef 100644
--- a/src/components/SessionTimeline.tsx
+++ b/src/components/SessionTimeline.tsx
@@ -61,46 +61,46 @@ export default function SessionTimeline({ tastings, sessionStart }: SessionTimel
return (
{/* Dot */}
-
+
{isSmoky && }
-
+
- Dram #{index + 1}
-
+ Dram #{index + 1}
+
{wallClockTime} ({index === 0 ? 'Start' : `+${diffMinutes}m`})
{isSmoky && (
- Peat Bomb
+ Peat Bomb
)}
{tasting.bottle_name}
{tasting.tags.slice(0, 2).map(tag => (
-
+
{tag}
))}
- {tasting.rating}
- Punkte
+ {tasting.rating}
+ Punkte
{wasPreviousSmoky && timeSinceLastDram < 20 && (
-
-
-
+
+
+
Achtung: Gaumen war noch torf-belegt (nur {timeSinceLastDram}m Abstand).
diff --git a/src/components/StatsDashboard.tsx b/src/components/StatsDashboard.tsx
index 0110061..73fa162 100644
--- a/src/components/StatsDashboard.tsx
+++ b/src/components/StatsDashboard.tsx
@@ -61,8 +61,8 @@ export default function StatsDashboard({ bottles }: StatsDashboardProps) {
label: t('home.stats.avgRating'),
value: `${stats.avgRating}/100`,
icon: Star,
- color: 'text-amber-600',
- bg: 'bg-amber-50 dark:bg-amber-900/20'
+ color: 'text-orange-600',
+ bg: 'bg-orange-900/20'
},
{
label: t('home.stats.topDistillery'),
@@ -74,17 +74,18 @@ export default function StatsDashboard({ bottles }: StatsDashboardProps) {
];
return (
-
+
{statItems.map((item, idx) => {
+ const value = idx === 1 ? stats.totalCount : item.value;
return (
-
- {idx === 1 ? stats.totalCount : item.value}
+
+ {value}
-
+
{item.label}
diff --git a/src/components/TagSelector.tsx b/src/components/TagSelector.tsx
index 50f720e..324be14 100644
--- a/src/components/TagSelector.tsx
+++ b/src/components/TagSelector.tsx
@@ -70,35 +70,35 @@ export default function TagSelector({ category, selectedTagIds, onToggleTag, lab
key={tag.id}
type="button"
onClick={() => onToggleTag(tag.id)}
- className="inline-flex items-center gap-1.5 px-3 py-1.5 bg-amber-600 text-white rounded-full text-[10px] font-black uppercase tracking-tight shadow-sm shadow-amber-600/20 animate-in fade-in zoom-in-95"
+ className="inline-flex items-center gap-1.5 px-3 py-1.5 bg-orange-600 text-white rounded-full text-[10px] font-bold uppercase tracking-tight shadow-sm shadow-orange-600/20 animate-in fade-in zoom-in-95"
>
{tag.is_system_default ? t(`aroma.${tag.name}`) : tag.name}
))
) : (
- Noch keine Tags gewählt...
+ Noch keine Tags gewählt...
)}
{/* Search and Suggest */}
-
+
setSearch(e.target.value)}
placeholder="Tag suchen oder hinzufügen..."
- className="w-full pl-9 pr-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-xs focus:ring-2 focus:ring-amber-500 outline-none transition-all dark:text-zinc-200 placeholder:text-zinc-400"
+ className="w-full pl-9 pr-4 py-2 bg-zinc-900 border border-zinc-800 rounded-xl text-xs focus:ring-1 focus:ring-orange-600 outline-none transition-all text-zinc-200 placeholder:text-zinc-600"
/>
{isCreating && (
-
+
)}
{search && (
-
+
{filteredTags.length > 0 ? (
filteredTags.map(tag => (
@@ -109,17 +109,17 @@ export default function TagSelector({ category, selectedTagIds, onToggleTag, lab
onToggleTag(tag.id);
setSearch('');
}}
- className="w-full px-4 py-2.5 text-left text-xs font-bold text-zinc-700 dark:text-zinc-300 hover:bg-zinc-50 dark:hover:bg-zinc-700/50 flex items-center justify-between border-b border-zinc-100 dark:border-zinc-700 last:border-0"
+ className="w-full px-4 py-2.5 text-left text-xs font-bold text-zinc-300 hover:bg-zinc-800/50 flex items-center justify-between border-b border-zinc-800 last:border-0"
>
{tag.is_system_default ? t(`aroma.${tag.name}`) : tag.name}
- {selectedTagIds.includes(tag.id) && }
+ {selectedTagIds.includes(tag.id) && }
))
) : (
"{search}" als neuen Tag hinzufügen
@@ -133,7 +133,7 @@ export default function TagSelector({ category, selectedTagIds, onToggleTag, lab
{/* AI Suggestions */}
{!search && suggestedTagNames && suggestedTagNames.length > 0 && (
-
+
{t('camera.wbMatchFound') ? 'KI Vorschläge' : 'AI Suggestions'}
@@ -144,7 +144,7 @@ export default function TagSelector({ category, selectedTagIds, onToggleTag, lab
key={tag.id}
type="button"
onClick={() => onToggleTag(tag.id)}
- className="px-2.5 py-1 rounded-lg bg-amber-50 dark:bg-amber-900/20 text-amber-600 dark:text-amber-400 text-[10px] font-bold uppercase tracking-tight hover:bg-amber-100 dark:hover:bg-amber-900/30 transition-colors border border-amber-200 dark:border-amber-800/50 flex items-center gap-1.5"
+ className="px-2.5 py-1 rounded-lg bg-orange-950/20 text-orange-500 text-[10px] font-bold uppercase tracking-tight hover:bg-orange-900/30 transition-colors border border-orange-900/50 flex items-center gap-1.5"
>
{tag.is_system_default ? t(`aroma.${tag.name}`) : tag.name}
@@ -157,7 +157,7 @@ export default function TagSelector({ category, selectedTagIds, onToggleTag, lab
{/* AI Custom Suggestions */}
{!search && suggestedCustomTagNames && suggestedCustomTagNames.length > 0 && (
-
+
Dominante Note anlegen?
@@ -177,7 +177,7 @@ export default function TagSelector({ category, selectedTagIds, onToggleTag, lab
}
setCreatingSuggestion(null);
}}
- className="px-2.5 py-1 rounded-lg bg-zinc-50 dark:bg-zinc-800/50 text-zinc-500 dark:text-zinc-400 text-[10px] font-bold uppercase tracking-tight hover:bg-amber-600 hover:text-white transition-all border border-dashed border-zinc-200 dark:border-zinc-700/50 flex items-center gap-1.5 disabled:opacity-50"
+ className="px-2.5 py-1 rounded-lg bg-zinc-900/50 text-zinc-400 text-[10px] font-bold uppercase tracking-tight hover:bg-orange-600 hover:text-white transition-all border border-dashed border-zinc-800 flex items-center gap-1.5 disabled:opacity-50"
>
{creatingSuggestion === name ? : }
{name}
@@ -188,7 +188,7 @@ export default function TagSelector({ category, selectedTagIds, onToggleTag, lab
)}
{/* Suggestions Chips (limit to 6 random or most common) */}
- {!search && tags.length > 0 && (
+ {!search && (tags || []).length > 0 && (
{(tags || [])
.filter(t => !selectedTagIds.includes(t.id) && (!suggestedTagNames || !suggestedTagNames.some((s: string) => s.toLowerCase() === t.name.toLowerCase())))
@@ -198,7 +198,7 @@ export default function TagSelector({ category, selectedTagIds, onToggleTag, lab
key={tag.id}
type="button"
onClick={() => onToggleTag(tag.id)}
- className="px-2.5 py-1 rounded-lg bg-zinc-100 dark:bg-zinc-800 text-zinc-500 dark:text-zinc-400 text-[10px] font-bold uppercase tracking-tight hover:bg-zinc-200 dark:hover:bg-zinc-700 hover:text-zinc-700 dark:hover:text-zinc-200 transition-colors border border-zinc-200/50 dark:border-zinc-700/50"
+ className="px-2.5 py-1 rounded-lg bg-zinc-900 text-zinc-500 text-[10px] font-bold uppercase tracking-tight hover:bg-zinc-800 hover:text-zinc-200 transition-colors border border-zinc-800"
>
{tag.is_system_default ? t(`aroma.${tag.name}`) : tag.name}
diff --git a/src/components/TastingEditor.tsx b/src/components/TastingEditor.tsx
index 4fa86a3..c4d52b2 100644
--- a/src/components/TastingEditor.tsx
+++ b/src/components/TastingEditor.tsx
@@ -123,18 +123,18 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
};
return (
-
+
{/* Top Context Bar - Flex Child 1 */}
-
+
- Kontext
- {activeSessionName || 'Trinkst du in Gesellschaft?'}
+ Kontext
+ {activeSessionName || 'Trinkst du in Gesellschaft?'}
-
+
@@ -146,50 +146,50 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
-
+
- Palette-Checker
-
+
Palette-Checker
+
Dein letzter Dram "{lastDramInSession?.name}" war torfig. Trink etwas Wasser!
- setShowPaletteWarning(false)} className="text-[10px] font-black uppercase text-amber-500 underline mt-2 block">Verstanden
+ setShowPaletteWarning(false)} className="text-[10px] font-bold uppercase text-orange-500 underline mt-2 block">Verstanden
)}
{/* Hero Section */}
-
+
{image ? (
) : (
- No Photo
+ No Photo
)}
-
+
{bottleMetadata.distillery || 'Destillerie'}
-
{bottleMetadata.name || 'Unbekannter Malt'}
-
+
{bottleMetadata.name || 'Unbekannter Malt'}
+
{bottleMetadata.category || 'Whisky'} {bottleMetadata.abv ? `• ${bottleMetadata.abv}%` : ''} {bottleMetadata.age ? `• ${bottleMetadata.age}y` : ''}
{/* Rating Slider */}
-
+
-
+
-
-
+
+
{t('tasting.rating')}
- {rating}/100
+ {rating}/100
setRating(parseInt(e.target.value))}
- className="w-full h-2 bg-zinc-800 rounded-full appearance-none cursor-pointer accent-amber-600 transition-all"
+ className="w-full h-2 bg-zinc-800 rounded-full appearance-none cursor-pointer accent-orange-600 transition-all"
/>
-
+
Swill
Dram
Legendary
@@ -210,9 +210,9 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
setIsSample(type === 'Sample')}
- className={`flex-1 py-4 rounded-2xl text-[10px] font-black uppercase tracking-widest border transition-all ${(type === 'Sample' ? isSample : !isSample)
- ? 'bg-zinc-100 border-zinc-100 text-zinc-900 shadow-lg'
- : 'bg-transparent border-white/10 text-white/40 hover:border-white/30'
+ className={`flex-1 py-4 rounded-xl text-[10px] font-bold uppercase tracking-widest border transition-all ${(type === 'Sample' ? isSample : !isSample)
+ ? 'bg-orange-600 border-orange-600 text-white shadow-lg'
+ : 'bg-transparent border-zinc-800 text-zinc-500 hover:border-zinc-700'
}`}
>
{type}
@@ -230,14 +230,14 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
{/* Sections */}
{/* Nose Section */}
-
+
-
+
- {t('tasting.nose')}
- Aroma & Bouquet
+ {t('tasting.nose')}
+ Aroma & Bouquet
@@ -245,7 +245,7 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
} />
- Tags
+ Tags
- Eigene Notizen
+ Eigene Notizen
{/* Palate Section */}
-
+
-
+
- {t('tasting.palate')}
- Geschmack & Textur
+ {t('tasting.palate')}
+ Geschmack & Textur
@@ -282,7 +282,7 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
} />
- Tags
+ Tags
- Eigene Notizen
+ Eigene Notizen
{/* Finish Section */}
-
+
-
+
- {t('tasting.finish')}
- Abgang & Nachklang
+ {t('tasting.finish')}
+ Abgang & Nachklang
} />
-
+
- Aroma Tags
+ Aroma Tags
- Gefühl & Textur
+ Gefühl & Textur
- Eigene Notizen
+ Eigene Notizen
@@ -354,14 +354,14 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
{/* Buddy Selection */}
{buddies && buddies.length > 0 && (
-
+
-
+
- Mit wem trinkst du?
- Gesellschaft & Buddies
+ Mit wem trinkst du?
+ Gesellschaft & Buddies
@@ -369,9 +369,9 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
toggleBuddy(buddy.id)}
- className={`px-5 py-3 rounded-2xl text-[10px] font-black uppercase transition-all border flex items-center gap-2 ${selectedBuddyIds.includes(buddy.id)
- ? 'bg-amber-600 border-amber-600 text-white shadow-lg'
- : 'bg-transparent border-white/10 text-white/40 hover:border-white/30'
+ className={`px-5 py-3 rounded-xl text-[10px] font-bold uppercase transition-all border flex items-center gap-2 ${selectedBuddyIds.includes(buddy.id)
+ ? 'bg-orange-600 border-orange-600 text-white shadow-lg'
+ : 'bg-transparent border-zinc-800 text-zinc-500 hover:border-zinc-700'
}`}
>
{selectedBuddyIds.includes(buddy.id) && }
@@ -385,15 +385,15 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
{/* Sticky Footer - Flex Child 3 */}
-
+
{t('tasting.saveTasting')}
- {rating}
+ {rating}
@@ -404,15 +404,15 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
function CustomSlider({ label, value, onChange, icon }: any) {
return (
-
+
-
-
+
+
{icon}
- {label}
+ {label}
- {value}
+ {value}
onChange(parseInt(e.target.value))}
- className="w-full h-1.5 bg-zinc-800 rounded-full appearance-none cursor-pointer accent-[#C89D46] transition-all"
+ className="w-full h-1.5 bg-zinc-800 rounded-full appearance-none cursor-pointer accent-orange-600 transition-all"
/>
);
diff --git a/src/components/UserManagementClient.tsx b/src/components/UserManagementClient.tsx
index 350eb57..1a12f3b 100644
--- a/src/components/UserManagementClient.tsx
+++ b/src/components/UserManagementClient.tsx
@@ -166,61 +166,61 @@ export default function UserManagementClient({ initialUsers, plans }: UserManage
return (
{/* Search Bar */}
-
+
-
+
setSearchTerm(e.target.value)}
- className="w-full pl-10 pr-4 py-3 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-amber-500/50"
+ className="w-full pl-10 pr-4 py-3 bg-zinc-800 border border-zinc-700 rounded-2xl text-sm focus:outline-none focus:ring-2 focus:ring-orange-600/50 text-white"
/>
{/* User Table */}
-
- Users ({filteredUsers.length})
-
+
+ Users ({filteredUsers.length})
+
-
- User
- Balance
- Used
- Daily Limit
- Costs
- Actions
+
+ User
+ Balance
+ Used
+ Daily Limit
+ Costs
+ Actions
-
+
{filteredUsers.map((user) => (
-
-
+
+
- {user.username}
- {user.email}
+ {user.username}
+ {user.email}
-
-
+
+
{user.balance}
-
+
{user.total_used}
-
+
{user.daily_limit || 'Global (80)'}
-
+
G:{user.google_search_cost} / AI:{user.gemini_ai_cost}
-
+
handleEditUser(user)}
- className="inline-flex items-center gap-2 px-3 py-1.5 bg-amber-600 hover:bg-amber-700 text-white rounded-lg text-xs font-bold transition-colors"
+ className="inline-flex items-center gap-2 px-4 py-2 bg-orange-600 hover:bg-orange-700 text-white rounded-xl text-[10px] font-bold uppercase tracking-widest transition-all shadow-md shadow-orange-950/20"
>
Edit
@@ -235,18 +235,18 @@ export default function UserManagementClient({ initialUsers, plans }: UserManage
{/* Edit Modal */}
{editingUser && (
-
-
-
+
+
+
- Edit User
- {editingUser.email}
+ Edit User
+ {editingUser.email}
setEditingUser(null)}
- className="p-2 hover:bg-zinc-100 dark:hover:bg-zinc-800 rounded-lg transition-colors"
+ className="p-2 hover:bg-zinc-800 rounded-xl transition-colors text-zinc-500"
>
-
+
@@ -262,40 +262,40 @@ export default function UserManagementClient({ initialUsers, plans }: UserManage
{/* Current Balance */}
-
- Current Balance
- {editingUser.balance} Credits
+
+ Current Balance
+ {editingUser.balance} Credits
{/* Add/Remove Credits */}
- Adjust Credits
+ Adjust Credits
- Amount
+ Amount
setCreditAmount(e.target.value)}
placeholder="e.g. 100 or -50"
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-amber-500/50"
+ className="w-full px-4 py-2 bg-zinc-800 border border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-orange-600/50 text-white"
/>
- Reason
+ Reason
setReason(e.target.value)}
placeholder="e.g. Monthly bonus"
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-amber-500/50"
+ className="w-full px-4 py-2 bg-zinc-800 border border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-orange-600/50 text-white"
/>
Update Credits
@@ -306,20 +306,20 @@ export default function UserManagementClient({ initialUsers, plans }: UserManage
{/* Subscription Plan */}
- Subscription Plan
+ Subscription Plan
{currentPlan && (
-
- Current Plan
- {currentPlan.display_name}
- {currentPlan.monthly_credits} credits/month
+
+ Current Plan
+ {currentPlan.display_name}
+ {currentPlan.monthly_credits} credits/month
)}
- Assign Plan
+ Assign Plan
Tasting Record
-{bottleName}
+Verified Tasting Record
+{bottleName}
Analysiere Etikett...
-+
Analysiere Etikett...
+
Speichere Tasting...
+Speichere Tasting...
Tasting Session
+Tasting Session
{/* New Session Input */}Aktuelle Sessions
+Aktuelle Sessions
{isLoading ? (
-
+
+
{t('session.title')}
{!isCollapsed && sessions.length > 0 && (
- ({sessions.length})
+ ({sessions.length})
)}
{isCollapsed ? : }
@@ -166,23 +166,23 @@ export default function SessionList() {
value={newName}
onChange={(e) => setNewName(e.target.value)}
placeholder={t('session.sessionName')}
- className="flex-1 bg-white/5 border border-white/10 rounded-xl px-4 py-2 text-sm text-white placeholder:text-[#8F9096] focus:outline-none focus:border-[#C89D46] transition-colors"
+ className="flex-1 bg-zinc-950 border border-zinc-800 rounded-xl px-4 py-2 text-sm text-zinc-50 placeholder:text-zinc-600 focus:outline-none focus:border-orange-600 transition-colors"
/>
{isCreating ? : }
{isLoading ? (
-
+
) : sessions.length === 0 ? (
-
+
{t('session.noSessions')}
) : (
@@ -191,18 +191,18 @@ export default function SessionList() {
-
+
{session.name}
{session.ended_at && (
- Closed
+ Closed
)}
-
+
{new Date(session.scheduled_at).toLocaleDateString(locale === 'de' ? 'de-DE' : 'en-US')}
@@ -225,28 +225,28 @@ export default function SessionList() {
!session.ended_at ? (
setActiveSession({ id: session.id, name: session.name })}
- className="p-2 bg-white/10 text-white rounded-xl hover:bg-[#C89D46] hover:text-[#0F1014] transition-all"
+ className="p-2 bg-zinc-800 text-zinc-50 rounded-xl hover:bg-orange-600 hover:text-white transition-all"
title="Start Session"
>
) : (
-
+
)
) : (
-
+
)}
-
+
handleDeleteSession(e, session.id)}
disabled={!!isDeleting}
className={`p-2 rounded-xl transition-all ${activeSession?.id === session.id
- ? 'text-[#0F1014]/40 hover:text-[#0F1014]'
- : 'text-[#8F9096] hover:text-red-400'
+ ? 'text-white/40 hover:text-white'
+ : 'text-zinc-600 hover:text-red-500'
}`}
title="Session löschen"
>
@@ -268,17 +268,17 @@ export default function SessionList() {
{sessions.slice(0, 3).map((s, i) => (
-
+
{s.name[0].toUpperCase()}
))}
{sessions.length > 3 && (
-
+
+{sessions.length - 3}
)}
- {sessions.length} Sessions
+ {sessions.length} Sessions
)}
diff --git a/src/components/SessionTimeline.tsx b/src/components/SessionTimeline.tsx
index 3ffce37..eecbeef 100644
--- a/src/components/SessionTimeline.tsx
+++ b/src/components/SessionTimeline.tsx
@@ -61,46 +61,46 @@ export default function SessionTimeline({ tastings, sessionStart }: SessionTimel
return (
{/* Dot */}
-
+
{isSmoky && }
-
+
- Dram #{index + 1}
-
+ Dram #{index + 1}
+
{wallClockTime} ({index === 0 ? 'Start' : `+${diffMinutes}m`})
{isSmoky && (
- Peat Bomb
+ Peat Bomb
)}
{tasting.bottle_name}
{tasting.tags.slice(0, 2).map(tag => (
-
+
{tag}
))}
- {tasting.rating}
- Punkte
+ {tasting.rating}
+ Punkte
{wasPreviousSmoky && timeSinceLastDram < 20 && (
-
-
-
+
+
+
Achtung: Gaumen war noch torf-belegt (nur {timeSinceLastDram}m Abstand).
diff --git a/src/components/StatsDashboard.tsx b/src/components/StatsDashboard.tsx
index 0110061..73fa162 100644
--- a/src/components/StatsDashboard.tsx
+++ b/src/components/StatsDashboard.tsx
@@ -61,8 +61,8 @@ export default function StatsDashboard({ bottles }: StatsDashboardProps) {
label: t('home.stats.avgRating'),
value: `${stats.avgRating}/100`,
icon: Star,
- color: 'text-amber-600',
- bg: 'bg-amber-50 dark:bg-amber-900/20'
+ color: 'text-orange-600',
+ bg: 'bg-orange-900/20'
},
{
label: t('home.stats.topDistillery'),
@@ -74,17 +74,18 @@ export default function StatsDashboard({ bottles }: StatsDashboardProps) {
];
return (
-
+
{statItems.map((item, idx) => {
+ const value = idx === 1 ? stats.totalCount : item.value;
return (
-
- {idx === 1 ? stats.totalCount : item.value}
+
+ {value}
-
+
{item.label}
diff --git a/src/components/TagSelector.tsx b/src/components/TagSelector.tsx
index 50f720e..324be14 100644
--- a/src/components/TagSelector.tsx
+++ b/src/components/TagSelector.tsx
@@ -70,35 +70,35 @@ export default function TagSelector({ category, selectedTagIds, onToggleTag, lab
key={tag.id}
type="button"
onClick={() => onToggleTag(tag.id)}
- className="inline-flex items-center gap-1.5 px-3 py-1.5 bg-amber-600 text-white rounded-full text-[10px] font-black uppercase tracking-tight shadow-sm shadow-amber-600/20 animate-in fade-in zoom-in-95"
+ className="inline-flex items-center gap-1.5 px-3 py-1.5 bg-orange-600 text-white rounded-full text-[10px] font-bold uppercase tracking-tight shadow-sm shadow-orange-600/20 animate-in fade-in zoom-in-95"
>
{tag.is_system_default ? t(`aroma.${tag.name}`) : tag.name}
))
) : (
- Noch keine Tags gewählt...
+ Noch keine Tags gewählt...
)}
{/* Search and Suggest */}
-
+
setSearch(e.target.value)}
placeholder="Tag suchen oder hinzufügen..."
- className="w-full pl-9 pr-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-xs focus:ring-2 focus:ring-amber-500 outline-none transition-all dark:text-zinc-200 placeholder:text-zinc-400"
+ className="w-full pl-9 pr-4 py-2 bg-zinc-900 border border-zinc-800 rounded-xl text-xs focus:ring-1 focus:ring-orange-600 outline-none transition-all text-zinc-200 placeholder:text-zinc-600"
/>
{isCreating && (
-
+
)}
{search && (
-
+
{filteredTags.length > 0 ? (
filteredTags.map(tag => (
@@ -109,17 +109,17 @@ export default function TagSelector({ category, selectedTagIds, onToggleTag, lab
onToggleTag(tag.id);
setSearch('');
}}
- className="w-full px-4 py-2.5 text-left text-xs font-bold text-zinc-700 dark:text-zinc-300 hover:bg-zinc-50 dark:hover:bg-zinc-700/50 flex items-center justify-between border-b border-zinc-100 dark:border-zinc-700 last:border-0"
+ className="w-full px-4 py-2.5 text-left text-xs font-bold text-zinc-300 hover:bg-zinc-800/50 flex items-center justify-between border-b border-zinc-800 last:border-0"
>
{tag.is_system_default ? t(`aroma.${tag.name}`) : tag.name}
- {selectedTagIds.includes(tag.id) && }
+ {selectedTagIds.includes(tag.id) && }
))
) : (
"{search}" als neuen Tag hinzufügen
@@ -133,7 +133,7 @@ export default function TagSelector({ category, selectedTagIds, onToggleTag, lab
{/* AI Suggestions */}
{!search && suggestedTagNames && suggestedTagNames.length > 0 && (
-
+
{t('camera.wbMatchFound') ? 'KI Vorschläge' : 'AI Suggestions'}
@@ -144,7 +144,7 @@ export default function TagSelector({ category, selectedTagIds, onToggleTag, lab
key={tag.id}
type="button"
onClick={() => onToggleTag(tag.id)}
- className="px-2.5 py-1 rounded-lg bg-amber-50 dark:bg-amber-900/20 text-amber-600 dark:text-amber-400 text-[10px] font-bold uppercase tracking-tight hover:bg-amber-100 dark:hover:bg-amber-900/30 transition-colors border border-amber-200 dark:border-amber-800/50 flex items-center gap-1.5"
+ className="px-2.5 py-1 rounded-lg bg-orange-950/20 text-orange-500 text-[10px] font-bold uppercase tracking-tight hover:bg-orange-900/30 transition-colors border border-orange-900/50 flex items-center gap-1.5"
>
{tag.is_system_default ? t(`aroma.${tag.name}`) : tag.name}
@@ -157,7 +157,7 @@ export default function TagSelector({ category, selectedTagIds, onToggleTag, lab
{/* AI Custom Suggestions */}
{!search && suggestedCustomTagNames && suggestedCustomTagNames.length > 0 && (
-
+
Dominante Note anlegen?
@@ -177,7 +177,7 @@ export default function TagSelector({ category, selectedTagIds, onToggleTag, lab
}
setCreatingSuggestion(null);
}}
- className="px-2.5 py-1 rounded-lg bg-zinc-50 dark:bg-zinc-800/50 text-zinc-500 dark:text-zinc-400 text-[10px] font-bold uppercase tracking-tight hover:bg-amber-600 hover:text-white transition-all border border-dashed border-zinc-200 dark:border-zinc-700/50 flex items-center gap-1.5 disabled:opacity-50"
+ className="px-2.5 py-1 rounded-lg bg-zinc-900/50 text-zinc-400 text-[10px] font-bold uppercase tracking-tight hover:bg-orange-600 hover:text-white transition-all border border-dashed border-zinc-800 flex items-center gap-1.5 disabled:opacity-50"
>
{creatingSuggestion === name ? : }
{name}
@@ -188,7 +188,7 @@ export default function TagSelector({ category, selectedTagIds, onToggleTag, lab
)}
{/* Suggestions Chips (limit to 6 random or most common) */}
- {!search && tags.length > 0 && (
+ {!search && (tags || []).length > 0 && (
{(tags || [])
.filter(t => !selectedTagIds.includes(t.id) && (!suggestedTagNames || !suggestedTagNames.some((s: string) => s.toLowerCase() === t.name.toLowerCase())))
@@ -198,7 +198,7 @@ export default function TagSelector({ category, selectedTagIds, onToggleTag, lab
key={tag.id}
type="button"
onClick={() => onToggleTag(tag.id)}
- className="px-2.5 py-1 rounded-lg bg-zinc-100 dark:bg-zinc-800 text-zinc-500 dark:text-zinc-400 text-[10px] font-bold uppercase tracking-tight hover:bg-zinc-200 dark:hover:bg-zinc-700 hover:text-zinc-700 dark:hover:text-zinc-200 transition-colors border border-zinc-200/50 dark:border-zinc-700/50"
+ className="px-2.5 py-1 rounded-lg bg-zinc-900 text-zinc-500 text-[10px] font-bold uppercase tracking-tight hover:bg-zinc-800 hover:text-zinc-200 transition-colors border border-zinc-800"
>
{tag.is_system_default ? t(`aroma.${tag.name}`) : tag.name}
diff --git a/src/components/TastingEditor.tsx b/src/components/TastingEditor.tsx
index 4fa86a3..c4d52b2 100644
--- a/src/components/TastingEditor.tsx
+++ b/src/components/TastingEditor.tsx
@@ -123,18 +123,18 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
};
return (
-
+
{/* Top Context Bar - Flex Child 1 */}
-
+
- Kontext
- {activeSessionName || 'Trinkst du in Gesellschaft?'}
+ Kontext
+ {activeSessionName || 'Trinkst du in Gesellschaft?'}
-
+
@@ -146,50 +146,50 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
-
+
- Palette-Checker
-
+
Palette-Checker
+
Dein letzter Dram "{lastDramInSession?.name}" war torfig. Trink etwas Wasser!
- setShowPaletteWarning(false)} className="text-[10px] font-black uppercase text-amber-500 underline mt-2 block">Verstanden
+ setShowPaletteWarning(false)} className="text-[10px] font-bold uppercase text-orange-500 underline mt-2 block">Verstanden
)}
{/* Hero Section */}
-
+
{image ? (
) : (
- No Photo
+ No Photo
)}
-
+
{bottleMetadata.distillery || 'Destillerie'}
-
{bottleMetadata.name || 'Unbekannter Malt'}
-
+
{bottleMetadata.name || 'Unbekannter Malt'}
+
{bottleMetadata.category || 'Whisky'} {bottleMetadata.abv ? `• ${bottleMetadata.abv}%` : ''} {bottleMetadata.age ? `• ${bottleMetadata.age}y` : ''}
{/* Rating Slider */}
-
+
-
+
-
-
+
+
{t('tasting.rating')}
- {rating}/100
+ {rating}/100
setRating(parseInt(e.target.value))}
- className="w-full h-2 bg-zinc-800 rounded-full appearance-none cursor-pointer accent-amber-600 transition-all"
+ className="w-full h-2 bg-zinc-800 rounded-full appearance-none cursor-pointer accent-orange-600 transition-all"
/>
-
+
Swill
Dram
Legendary
@@ -210,9 +210,9 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
setIsSample(type === 'Sample')}
- className={`flex-1 py-4 rounded-2xl text-[10px] font-black uppercase tracking-widest border transition-all ${(type === 'Sample' ? isSample : !isSample)
- ? 'bg-zinc-100 border-zinc-100 text-zinc-900 shadow-lg'
- : 'bg-transparent border-white/10 text-white/40 hover:border-white/30'
+ className={`flex-1 py-4 rounded-xl text-[10px] font-bold uppercase tracking-widest border transition-all ${(type === 'Sample' ? isSample : !isSample)
+ ? 'bg-orange-600 border-orange-600 text-white shadow-lg'
+ : 'bg-transparent border-zinc-800 text-zinc-500 hover:border-zinc-700'
}`}
>
{type}
@@ -230,14 +230,14 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
{/* Sections */}
{/* Nose Section */}
-
+
-
+
- {t('tasting.nose')}
- Aroma & Bouquet
+ {t('tasting.nose')}
+ Aroma & Bouquet
@@ -245,7 +245,7 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
} />
- Tags
+ Tags
- Eigene Notizen
+ Eigene Notizen
{/* Palate Section */}
-
+
-
+
- {t('tasting.palate')}
- Geschmack & Textur
+ {t('tasting.palate')}
+ Geschmack & Textur
@@ -282,7 +282,7 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
} />
- Tags
+ Tags
- Eigene Notizen
+ Eigene Notizen
{/* Finish Section */}
-
+
-
+
- {t('tasting.finish')}
- Abgang & Nachklang
+ {t('tasting.finish')}
+ Abgang & Nachklang
} />
-
+
- Aroma Tags
+ Aroma Tags
- Gefühl & Textur
+ Gefühl & Textur
- Eigene Notizen
+ Eigene Notizen
@@ -354,14 +354,14 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
{/* Buddy Selection */}
{buddies && buddies.length > 0 && (
-
+
-
+
- Mit wem trinkst du?
- Gesellschaft & Buddies
+ Mit wem trinkst du?
+ Gesellschaft & Buddies
@@ -369,9 +369,9 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
toggleBuddy(buddy.id)}
- className={`px-5 py-3 rounded-2xl text-[10px] font-black uppercase transition-all border flex items-center gap-2 ${selectedBuddyIds.includes(buddy.id)
- ? 'bg-amber-600 border-amber-600 text-white shadow-lg'
- : 'bg-transparent border-white/10 text-white/40 hover:border-white/30'
+ className={`px-5 py-3 rounded-xl text-[10px] font-bold uppercase transition-all border flex items-center gap-2 ${selectedBuddyIds.includes(buddy.id)
+ ? 'bg-orange-600 border-orange-600 text-white shadow-lg'
+ : 'bg-transparent border-zinc-800 text-zinc-500 hover:border-zinc-700'
}`}
>
{selectedBuddyIds.includes(buddy.id) && }
@@ -385,15 +385,15 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
{/* Sticky Footer - Flex Child 3 */}
-
+
{t('tasting.saveTasting')}
- {rating}
+ {rating}
@@ -404,15 +404,15 @@ export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSes
function CustomSlider({ label, value, onChange, icon }: any) {
return (
-
+
-
-
+
+
{icon}
- {label}
+ {label}
- {value}
+ {value}
onChange(parseInt(e.target.value))}
- className="w-full h-1.5 bg-zinc-800 rounded-full appearance-none cursor-pointer accent-[#C89D46] transition-all"
+ className="w-full h-1.5 bg-zinc-800 rounded-full appearance-none cursor-pointer accent-orange-600 transition-all"
/>
);
diff --git a/src/components/UserManagementClient.tsx b/src/components/UserManagementClient.tsx
index 350eb57..1a12f3b 100644
--- a/src/components/UserManagementClient.tsx
+++ b/src/components/UserManagementClient.tsx
@@ -166,61 +166,61 @@ export default function UserManagementClient({ initialUsers, plans }: UserManage
return (
{/* Search Bar */}
-
+
-
+
setSearchTerm(e.target.value)}
- className="w-full pl-10 pr-4 py-3 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-amber-500/50"
+ className="w-full pl-10 pr-4 py-3 bg-zinc-800 border border-zinc-700 rounded-2xl text-sm focus:outline-none focus:ring-2 focus:ring-orange-600/50 text-white"
/>
{/* User Table */}
-
- Users ({filteredUsers.length})
-
+
+ Users ({filteredUsers.length})
+
-
- User
- Balance
- Used
- Daily Limit
- Costs
- Actions
+
+ User
+ Balance
+ Used
+ Daily Limit
+ Costs
+ Actions
-
+
{filteredUsers.map((user) => (
-
-
+
+
- {user.username}
- {user.email}
+ {user.username}
+ {user.email}
-
-
+
+
{user.balance}
-
+
{user.total_used}
-
+
{user.daily_limit || 'Global (80)'}
-
+
G:{user.google_search_cost} / AI:{user.gemini_ai_cost}
-
+
handleEditUser(user)}
- className="inline-flex items-center gap-2 px-3 py-1.5 bg-amber-600 hover:bg-amber-700 text-white rounded-lg text-xs font-bold transition-colors"
+ className="inline-flex items-center gap-2 px-4 py-2 bg-orange-600 hover:bg-orange-700 text-white rounded-xl text-[10px] font-bold uppercase tracking-widest transition-all shadow-md shadow-orange-950/20"
>
Edit
@@ -235,18 +235,18 @@ export default function UserManagementClient({ initialUsers, plans }: UserManage
{/* Edit Modal */}
{editingUser && (
-
-
-
+
+
+
- Edit User
- {editingUser.email}
+ Edit User
+ {editingUser.email}
setEditingUser(null)}
- className="p-2 hover:bg-zinc-100 dark:hover:bg-zinc-800 rounded-lg transition-colors"
+ className="p-2 hover:bg-zinc-800 rounded-xl transition-colors text-zinc-500"
>
-
+
@@ -262,40 +262,40 @@ export default function UserManagementClient({ initialUsers, plans }: UserManage
{/* Current Balance */}
-
- Current Balance
- {editingUser.balance} Credits
+
+ Current Balance
+ {editingUser.balance} Credits
{/* Add/Remove Credits */}
- Adjust Credits
+ Adjust Credits
- Amount
+ Amount
setCreditAmount(e.target.value)}
placeholder="e.g. 100 or -50"
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-amber-500/50"
+ className="w-full px-4 py-2 bg-zinc-800 border border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-orange-600/50 text-white"
/>
- Reason
+ Reason
setReason(e.target.value)}
placeholder="e.g. Monthly bonus"
- className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-amber-500/50"
+ className="w-full px-4 py-2 bg-zinc-800 border border-zinc-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-orange-600/50 text-white"
/>
Update Credits
@@ -306,20 +306,20 @@ export default function UserManagementClient({ initialUsers, plans }: UserManage
{/* Subscription Plan */}
- Subscription Plan
+ Subscription Plan
{currentPlan && (
-
- Current Plan
- {currentPlan.display_name}
- {currentPlan.monthly_credits} credits/month
+
+ Current Plan
+ {currentPlan.display_name}
+ {currentPlan.monthly_credits} credits/month
)}
- Assign Plan
+ Assign Plan
+
Achtung: Gaumen war noch torf-belegt (nur {timeSinceLastDram}m Abstand).
Kontext
-{activeSessionName || 'Trinkst du in Gesellschaft?'}
+Kontext
+{activeSessionName || 'Trinkst du in Gesellschaft?'}
Palette-Checker
-+
Palette-Checker
+Dein letzter Dram "{lastDramInSession?.name}" war torfig. Trink etwas Wasser!
-
+
{bottleMetadata.distillery || 'Destillerie'}
-
{bottleMetadata.name || 'Unbekannter Malt'}
-+
{bottleMetadata.name || 'Unbekannter Malt'}
+{bottleMetadata.category || 'Whisky'} {bottleMetadata.abv ? `• ${bottleMetadata.abv}%` : ''} {bottleMetadata.age ? `• ${bottleMetadata.age}y` : ''}
{t('tasting.nose')}
-Aroma & Bouquet
+{t('tasting.nose')}
+Aroma & Bouquet
Tags
+Tags
Eigene Notizen
+Eigene Notizen
{t('tasting.palate')}
-Geschmack & Textur
+{t('tasting.palate')}
+Geschmack & Textur
Tags
+Tags
Eigene Notizen
+Eigene Notizen
{t('tasting.finish')}
-Abgang & Nachklang
+{t('tasting.finish')}
+Abgang & Nachklang
Aroma Tags
+Aroma Tags
Gefühl & Textur
+Gefühl & Textur
Eigene Notizen
+Eigene Notizen
Mit wem trinkst du?
-Gesellschaft & Buddies
+Mit wem trinkst du?
+Gesellschaft & Buddies
Users ({filteredUsers.length})
-Users ({filteredUsers.length})
+| User | -Balance | -Used | -Daily Limit | -Costs | -Actions | +|||||
|---|---|---|---|---|---|---|---|---|---|---|
| User | +Balance | +Used | +Daily Limit | +Costs | +Actions | |||||
| + | ||||||||||
|
-
{user.username}
- {user.email}
+ {user.username}
+ {user.email}
|
- - + | + {user.balance} | -+ | {user.total_used} | -+ | {user.daily_limit || 'Global (80)'} | -+ | G:{user.google_search_cost} / AI:{user.gemini_ai_cost} | -+ |
-
-
+
+
+
-
Edit User-{editingUser.email} +Edit User+{editingUser.email}
{/* Current Balance */}
-
- Current Balance
- {editingUser.balance} Credits
+
+
{/* Add/Remove Credits */}
Current Balance
+ {editingUser.balance} Credits
- Adjust Credits+Adjust Credits
-
-
- Subscription Plan+Subscription Plan{currentPlan && ( -
- Current Plan
- {currentPlan.display_name}
- {currentPlan.monthly_credits} credits/month
+
+
)}
Current Plan
+ {currentPlan.display_name}
+ {currentPlan.monthly_credits} credits/month
- |