style: overhaul design to authentic Google Gemini Material 3 Dark theme
MindSift CI & Docker Release / Lint, Build & Unit Tests (push) Successful in 2m8s
MindSift CI & Docker Release / Build & Push Docker Image (push) Successful in 1m45s

This commit is contained in:
sandrodach committed 2026-10-24 18:32:03 +02:00
1 parent 10323867e9
commit 31aa43c460
11 files changed
+413 -444

No files matched your search

+58 -56
View File
@@ -266,16 +266,16 @@ export const SharedListsView: React.FC<SharedListsViewProps> = ({ onRefreshGloba
return (
<div className="max-w-4xl mx-auto space-y-6">
{/* Top Space Bar & Realtime Indicator */}
<div className="p-4 sm:p-5 rounded-3xl bg-[#1e1f20] gemini-border flex flex-wrap items-center justify-between gap-3">
<div className="p-4 sm:p-5 rounded-2xl bg-[#1e1f20] border border-white/[0.08] flex flex-wrap items-center justify-between gap-3">
<div className="flex flex-wrap items-center gap-2">
{spaces.map((sp) => (
<button
key={sp.id}
onClick={() => setActiveSpace(sp)}
className={`h-10 px-4 rounded-full text-xs sm:text-sm font-medium flex items-center gap-2 transition-all ${
className={`h-9 px-4 rounded-full text-xs sm:text-sm font-medium flex items-center gap-2 transition-colors ${
activeSpace?.id === sp.id
? 'bg-[#8ab4f8] text-[#0b0f19] font-semibold shadow-sm'
: 'bg-[#131314] text-[#9aa0a6] hover:text-[#e3e3e3] gemini-border'
? 'bg-[#282a2c] text-[#a8c7fa] border border-[#a8c7fa]/30'
: 'bg-[#131314] text-[#c4c7c5] hover:text-[#e3e3e3] border border-white/[0.08]'
}`}
>
<span>{sp.icon}</span>
@@ -285,16 +285,16 @@ export const SharedListsView: React.FC<SharedListsViewProps> = ({ onRefreshGloba
<button
onClick={() => setShowNewSpaceModal((prev) => !prev)}
className="h-10 px-3.5 rounded-full bg-[#131314] hover:bg-[#282a2c] gemini-border text-xs text-[#8ab4f8] flex items-center gap-1"
className="h-9 px-3.5 rounded-full bg-[#131314] hover:bg-[#282a2c] border border-white/[0.08] text-xs text-[#c4c7c5] hover:text-[#e3e3e3] flex items-center gap-1.5 transition-colors"
>
<Plus className="w-3.5 h-3.5" /> Space
<Plus className="w-3.5 h-3.5 text-[#a8c7fa]" /> Space
</button>
<button
onClick={() => setShowJoinModal((prev) => !prev)}
className="h-10 px-3.5 rounded-full bg-[#131314] hover:bg-[#282a2c] gemini-border text-xs text-[#c58af9] flex items-center gap-1"
className="h-9 px-3.5 rounded-full bg-[#131314] hover:bg-[#282a2c] border border-white/[0.08] text-xs text-[#c4c7c5] hover:text-[#e3e3e3] flex items-center gap-1.5 transition-colors"
>
<UserPlus className="w-3.5 h-3.5" /> Code einlösen
<UserPlus className="w-3.5 h-3.5 text-[#a8c7fa]" /> Code einlösen
</button>
</div>
@@ -304,8 +304,8 @@ export const SharedListsView: React.FC<SharedListsViewProps> = ({ onRefreshGloba
<div
className={`h-8 px-3 rounded-full text-xs flex items-center gap-1.5 ${
wsConnected
? 'bg-[#81c995]/15 text-[#81c995] border border-[#81c995]/30'
: 'bg-[#282a2c] text-[#9aa0a6]'
? 'bg-[#a8dab5]/10 text-[#a8dab5] border border-[#a8dab5]/25'
: 'bg-[#282a2c] text-[#8e918f] border border-white/[0.08]'
}`}
>
<Radio className={`w-3.5 h-3.5 ${wsConnected ? 'animate-pulse' : ''}`} />
@@ -315,14 +315,14 @@ export const SharedListsView: React.FC<SharedListsViewProps> = ({ onRefreshGloba
<button
onClick={copyInviteCode}
title="Einladungscode für Partner oder Familie kopieren"
className="h-8 px-3 rounded-full bg-[#131314] hover:bg-[#282a2c] gemini-border text-xs text-[#e3e3e3] flex items-center gap-1.5"
className="h-8 px-3 rounded-full bg-[#131314] hover:bg-[#282a2c] border border-white/[0.08] text-xs text-[#c4c7c5] hover:text-[#e3e3e3] flex items-center gap-1.5 transition-colors"
>
<Users className="w-3.5 h-3.5 text-[#8ab4f8]" />
<Users className="w-3.5 h-3.5 text-[#a8c7fa]" />
<span>Code: {activeSpace.inviteCode}</span>
{copiedInvite ? (
<Check className="w-3.5 h-3.5 text-[#81c995]" />
<Check className="w-3.5 h-3.5 text-[#a8dab5]" />
) : (
<Copy className="w-3 h-3 text-[#9aa0a6]" />
<Copy className="w-3 h-3 text-[#8e918f]" />
)}
</button>
</div>
@@ -333,19 +333,19 @@ export const SharedListsView: React.FC<SharedListsViewProps> = ({ onRefreshGloba
{showNewSpaceModal && (
<form
onSubmit={handleCreateSpace}
className="p-4 rounded-3xl bg-[#131314] gemini-border flex items-center gap-3"
className="p-4 rounded-2xl bg-[#1e1f20] border border-white/[0.08] flex items-center gap-3"
>
<input
type="text"
value={newSpaceName}
onChange={(e) => setNewSpaceName(e.target.value)}
placeholder="Name des neuen Familien-/Team-Spaces (z. B. Sommerurlaub 2027)…"
className="flex-1 h-10 px-4 rounded-full bg-[#1e1f20] text-sm text-[#e3e3e3] gemini-border focus:outline-none"
placeholder="Name des neuen Familien-/Team-Spaces (z. B. Urlaub 2026)…"
className="flex-1 h-10 px-4 rounded-full bg-[#131314] text-sm text-[#e3e3e3] placeholder-[#8e918f] border border-white/[0.08] focus:outline-none focus:border-[#a8c7fa] transition-colors"
autoFocus
/>
<button
type="submit"
className="h-10 px-5 rounded-full bg-[#8ab4f8] text-[#0b0f19] font-semibold text-xs sm:text-sm"
className="h-10 px-5 rounded-full bg-[#a8c7fa] text-[#041e49] font-medium text-xs sm:text-sm hover:bg-[#c2e7ff] transition-colors"
>
Space anlegen
</button>
@@ -355,19 +355,19 @@ export const SharedListsView: React.FC<SharedListsViewProps> = ({ onRefreshGloba
{showJoinModal && (
<form
onSubmit={handleJoinSpace}
className="p-4 rounded-3xl bg-[#131314] gemini-border flex items-center gap-3"
className="p-4 rounded-2xl bg-[#1e1f20] border border-white/[0.08] flex items-center gap-3"
>
<input
type="text"
value={joinCode}
onChange={(e) => setJoinCode(e.target.value)}
placeholder="Invite-Code des Partners eingeben…"
className="flex-1 h-10 px-4 rounded-full bg-[#1e1f20] text-sm text-[#e3e3e3] gemini-border focus:outline-none uppercase"
className="flex-1 h-10 px-4 rounded-full bg-[#131314] text-sm text-[#e3e3e3] placeholder-[#8e918f] border border-white/[0.08] focus:outline-none focus:border-[#a8c7fa] uppercase transition-colors"
autoFocus
/>
<button
type="submit"
className="h-10 px-5 rounded-full bg-[#c58af9] text-[#0b0f19] font-semibold text-xs sm:text-sm"
className="h-10 px-5 rounded-full bg-[#a8c7fa] text-[#041e49] font-medium text-xs sm:text-sm hover:bg-[#c2e7ff] transition-colors"
>
Beitreten
</button>
@@ -383,15 +383,15 @@ export const SharedListsView: React.FC<SharedListsViewProps> = ({ onRefreshGloba
<button
key={lst.id}
onClick={() => setActiveListId(lst.id)}
className={`h-11 px-5 rounded-full text-sm font-medium flex items-center gap-2 transition-all ${
className={`h-10 px-4 rounded-full text-xs sm:text-sm font-medium flex items-center gap-2 transition-colors ${
isSelected
? 'bg-[#1e1f20] text-[#8ab4f8] border border-[#8ab4f8]/50 shadow-gemini-glow'
: 'bg-[#131314] text-[#9aa0a6] hover:text-[#e3e3e3] gemini-border'
? 'bg-[#282a2c] text-[#e3e3e3] border border-white/[0.12]'
: 'bg-[#131314] text-[#c4c7c5] hover:text-[#e3e3e3] border border-white/[0.08]'
}`}
>
<span>{lst.icon}</span>
<span>{lst.title}</span>
<span className="px-2 py-0.5 rounded-full bg-[#0b0f19] text-xs text-[#8ab4f8]">
<span className="px-2 py-0.2 rounded-full bg-[#131314] text-xs text-[#a8c7fa] border border-white/[0.06]">
{openCount}
</span>
</button>
@@ -400,9 +400,9 @@ export const SharedListsView: React.FC<SharedListsViewProps> = ({ onRefreshGloba
<button
onClick={() => setShowNewListModal((prev) => !prev)}
className="h-11 px-4 rounded-full bg-[#131314] hover:bg-[#1e1f20] gemini-border text-xs sm:text-sm text-[#e3e3e3] flex items-center gap-1.5"
className="h-10 px-4 rounded-full bg-[#131314] hover:bg-[#1e1f20] border border-white/[0.08] text-xs sm:text-sm text-[#c4c7c5] hover:text-[#e3e3e3] flex items-center gap-1.5 transition-colors"
>
<Plus className="w-4 h-4 text-[#8ab4f8]" />
<Plus className="w-4 h-4 text-[#a8c7fa]" />
<span>Neue Liste</span>
</button>
</div>
@@ -410,7 +410,7 @@ export const SharedListsView: React.FC<SharedListsViewProps> = ({ onRefreshGloba
{showNewListModal && (
<form
onSubmit={handleCreateList}
className="p-4 rounded-3xl bg-[#131314] gemini-border flex flex-wrap items-center gap-3"
className="p-4 rounded-2xl bg-[#1e1f20] border border-white/[0.08] flex flex-wrap items-center gap-3"
>
<div className="flex items-center gap-1.5">
{['🛒', '🏔️', '🍕', '🎉', '🧰', '🎁'].map((ic) => (
@@ -418,8 +418,10 @@ export const SharedListsView: React.FC<SharedListsViewProps> = ({ onRefreshGloba
key={ic}
type="button"
onClick={() => setNewListIcon(ic)}
className={`w-9 h-9 rounded-full flex items-center justify-center ${
newListIcon === ic ? 'bg-[#8ab4f8]/25 border border-[#8ab4f8]' : 'bg-[#1e1f20]'
className={`w-9 h-9 rounded-full flex items-center justify-center transition-colors ${
newListIcon === ic
? 'bg-[#a8c7fa]/20 border border-[#a8c7fa]/40 text-[#a8c7fa]'
: 'bg-[#131314] hover:bg-[#282a2c] border border-white/[0.08]'
}`}
>
{ic}
@@ -431,12 +433,12 @@ export const SharedListsView: React.FC<SharedListsViewProps> = ({ onRefreshGloba
value={newListTitle}
onChange={(e) => setNewListTitle(e.target.value)}
placeholder="Titel der Liste (z. B. Baumarkt, Drogerie, Camping)…"
className="flex-1 h-10 px-4 rounded-full bg-[#1e1f20] text-sm text-[#e3e3e3] gemini-border focus:outline-none"
className="flex-1 h-10 px-4 rounded-full bg-[#131314] text-sm text-[#e3e3e3] placeholder-[#8e918f] border border-white/[0.08] focus:outline-none focus:border-[#a8c7fa] transition-colors"
autoFocus
/>
<button
type="submit"
className="h-10 px-5 rounded-full bg-[#8ab4f8] text-[#0b0f19] font-semibold text-xs sm:text-sm"
className="h-10 px-5 rounded-full bg-[#a8c7fa] text-[#041e49] font-medium text-xs sm:text-sm hover:bg-[#c2e7ff] transition-colors"
>
Liste erstellen
</button>
@@ -445,7 +447,7 @@ export const SharedListsView: React.FC<SharedListsViewProps> = ({ onRefreshGloba
{/* Active Shared List Card */}
{activeList ? (
<div className="p-6 sm:p-8 rounded-3xl bg-[#1e1f20] gemini-border shadow-card-depth">
<div className="p-6 sm:p-8 rounded-2xl bg-[#1e1f20] border border-white/[0.08]">
{/* Quick-Add Pill Form */}
<form onSubmit={handleAddItem} className="space-y-3 mb-6">
<div className="flex flex-col sm:flex-row gap-2.5">
@@ -454,7 +456,7 @@ export const SharedListsView: React.FC<SharedListsViewProps> = ({ onRefreshGloba
value={newItemText}
onChange={(e) => setNewItemText(e.target.value)}
placeholder={`Eintrag zu "${activeList.title}" hinzufügen (z. B. Hafermilch)…`}
className="flex-1 h-12 px-5 rounded-full bg-[#131314] text-sm sm:text-base text-[#e3e3e3] placeholder-[#9aa0a6] gemini-border focus:outline-none focus:border-[#8ab4f8]"
className="flex-1 h-11 px-5 rounded-full bg-[#131314] text-sm sm:text-base text-[#e3e3e3] placeholder-[#8e918f] border border-white/[0.08] focus:outline-none focus:border-[#a8c7fa] transition-colors"
/>
<div className="flex gap-2">
<input
@@ -462,12 +464,12 @@ export const SharedListsView: React.FC<SharedListsViewProps> = ({ onRefreshGloba
value={newItemQty}
onChange={(e) => setNewItemQty(e.target.value)}
placeholder="Menge (z.B. 2x)"
className="w-32 h-12 px-4 rounded-full bg-[#131314] text-sm text-[#e3e3e3] placeholder-[#9aa0a6] gemini-border focus:outline-none focus:border-[#8ab4f8]"
className="w-32 h-11 px-4 rounded-full bg-[#131314] text-sm text-[#e3e3e3] placeholder-[#8e918f] border border-white/[0.08] focus:outline-none focus:border-[#a8c7fa] transition-colors"
/>
<button
type="submit"
disabled={!newItemText.trim()}
className="h-12 px-6 rounded-full bg-[#8ab4f8] disabled:bg-[#282a2c] text-[#0b0f19] disabled:text-[#5f6368] font-semibold text-sm flex items-center gap-1.5 transition-colors"
className="h-11 px-5 rounded-full bg-[#a8c7fa] disabled:bg-[#282a2c] text-[#041e49] disabled:text-[#8e918f] font-medium text-sm flex items-center gap-1.5 hover:bg-[#c2e7ff] transition-colors"
>
<Plus className="w-4 h-4" />
<span>Hinzufügen</span>
@@ -477,7 +479,7 @@ export const SharedListsView: React.FC<SharedListsViewProps> = ({ onRefreshGloba
{/* Category Quick-Select Pills */}
<div className="flex flex-wrap items-center gap-1.5">
<span className="text-xs text-[#9aa0a6] mr-1">Kategorie:</span>
<span className="text-xs text-[#8e918f] mr-1">Kategorie:</span>
{CATEGORIES.map((cat) => (
<button
key={cat}
@@ -485,8 +487,8 @@ export const SharedListsView: React.FC<SharedListsViewProps> = ({ onRefreshGloba
onClick={() => setNewItemCategory((prev) => (prev === cat ? '' : cat))}
className={`px-3 py-1 rounded-full text-xs transition-colors ${
newItemCategory === cat
? 'bg-[#8ab4f8]/20 text-[#8ab4f8] border border-[#8ab4f8]/40'
: 'bg-[#131314] text-[#9aa0a6] hover:text-[#e3e3e3]'
? 'bg-[#a8c7fa]/15 text-[#a8c7fa] border border-[#a8c7fa]/25 font-medium'
: 'bg-[#131314] text-[#8e918f] hover:text-[#c4c7c5] border border-white/[0.08]'
}`}
>
{cat}
@@ -498,29 +500,29 @@ export const SharedListsView: React.FC<SharedListsViewProps> = ({ onRefreshGloba
{/* Open Items */}
<div className="space-y-2">
{openItems.length === 0 ? (
<div className="py-8 text-center text-[#9aa0a6] text-sm flex flex-col items-center gap-2">
<Sparkles className="w-6 h-6 text-[#81c995]" />
<span>Alles erledigt! Keine offenen Punkte auf dieser Liste.</span>
<div className="py-8 text-center text-[#8e918f] text-sm flex flex-col items-center gap-2">
<Sparkles className="w-5 h-5 text-[#a8dab5]" />
<span>Alles erledigt. Keine offenen Punkte auf dieser Liste.</span>
</div>
) : (
openItems.map((item) => (
<div
key={item.id}
onClick={() => handleToggleItem(item)}
className="p-4 rounded-2xl bg-[#131314] hover:bg-[#242628] gemini-border flex items-center justify-between gap-3 cursor-pointer transition-all active:scale-[0.99]"
className="p-3.5 sm:p-4 rounded-2xl bg-[#131314] hover:bg-[#282a2c]/60 border border-white/[0.08] flex items-center justify-between gap-3 cursor-pointer transition-colors group"
>
<div className="flex items-center gap-3.5 min-w-0">
<Circle className="w-5 h-5 text-[#8ab4f8] flex-shrink-0" />
<span className="text-base font-medium text-[#e3e3e3] truncate">
<Circle className="w-5 h-5 text-[#8e918f] group-hover:text-[#a8c7fa] flex-shrink-0 transition-colors" />
<span className="text-sm sm:text-base font-normal text-[#e3e3e3] truncate">
{item.content}
</span>
{item.quantity && (
<span className="px-2.5 py-0.5 rounded-full bg-[#1e1f20] text-[#8ab4f8] text-xs font-medium">
<span className="px-2.5 py-0.5 rounded-full bg-[#1e1f20] text-[#a8c7fa] border border-white/[0.06] text-xs font-medium">
{item.quantity}
</span>
)}
{item.category && (
<span className="hidden sm:inline px-2.5 py-0.5 rounded-full bg-[#1e1f20] text-[#9aa0a6] text-xs">
<span className="hidden sm:inline px-2.5 py-0.5 rounded-full bg-[#1e1f20] text-[#8e918f] text-xs">
{item.category}
</span>
)}
@@ -532,7 +534,7 @@ export const SharedListsView: React.FC<SharedListsViewProps> = ({ onRefreshGloba
e.stopPropagation();
handleDeleteItem(item.id);
}}
className="w-8 h-8 rounded-full hover:bg-[#f28b82]/20 text-[#5f6368] hover:text-[#f28b82] flex items-center justify-center"
className="w-8 h-8 rounded-full hover:bg-[#f28b82]/20 text-[#8e918f] hover:text-[#f28b82] flex items-center justify-center transition-colors"
>
<Trash2 className="w-3.5 h-3.5" />
</button>
@@ -545,35 +547,35 @@ export const SharedListsView: React.FC<SharedListsViewProps> = ({ onRefreshGloba
{completedItems.length > 0 && (
<div className="mt-8 pt-6 border-t border-white/[0.06]">
<div className="flex items-center justify-between mb-3">
<span className="text-xs font-semibold uppercase tracking-wider text-[#9aa0a6]">
<span className="text-xs font-medium uppercase tracking-wider text-[#8e918f]">
Bereits im Einkaufswagen / Erledigt ({completedItems.length})
</span>
<button
onClick={handleClearCompleted}
className="px-3.5 py-1 rounded-full bg-[#131314] hover:bg-[#f28b82]/20 text-xs text-[#9aa0a6] hover:text-[#f28b82] transition-colors"
className="px-3.5 py-1 rounded-full bg-[#131314] hover:bg-[#f28b82]/15 border border-white/[0.08] text-xs text-[#8e918f] hover:text-[#f28b82] transition-colors"
>
Erledigte aufräumen
</button>
</div>
<div className="space-y-2 opacity-70">
<div className="space-y-1.5 opacity-75">
{completedItems.map((item) => (
<div
key={item.id}
onClick={() => handleToggleItem(item)}
className="p-3.5 rounded-2xl bg-[#131314]/60 gemini-border flex items-center justify-between gap-3 cursor-pointer"
className="p-3 rounded-2xl bg-[#131314]/50 border border-white/[0.04] hover:bg-[#131314]/80 flex items-center justify-between gap-3 cursor-pointer transition-colors"
>
<div className="flex items-center gap-3 min-w-0">
<CheckCircle2 className="w-5 h-5 text-[#81c995] flex-shrink-0" />
<span className="text-sm text-[#9aa0a6] line-through truncate">
<CheckCircle2 className="w-5 h-5 text-[#a8dab5] flex-shrink-0" />
<span className="text-sm text-[#8e918f] line-through truncate">
{item.content}
</span>
{item.quantity && (
<span className="text-xs text-[#5f6368]">({item.quantity})</span>
<span className="text-xs text-[#8e918f]">({item.quantity})</span>
)}
</div>
{item.completedByName && (
<span className="text-xs text-[#5f6368]">✓ {item.completedByName}</span>
<span className="text-xs text-[#8e918f]">✓ {item.completedByName}</span>
)}
</div>
))}