Frontend-Redesign nach DESIGN.md: neues Dark-Theme mit grüner Akzentfarbe

- Neue Farbpalette: #0a0d0b Hintergrund, #111511 Surface, #1ed760 Akzent
- Inter-Font via Google Fonts (400/500/600)
- CSS Grid Layout: 240px Sidebar + 1fr Content + 88px Player Bar
- Sidebar: neue Nav-Items mit Padding, Uppercase-Labels, grünes Logo-Icon
- CoverImage: 2-Buchstaben-Kürzel mit 6 Cover-Placeholder-Farben
- BookCard: Play-Overlay (34px), 3px Progress-Bar am Kartenrand
- MiniPlayer: Player Bar mit 3-Spalten-Grid, 4px Progress-Track
- Alle Pages und Komponenten auf neue Tokenfarben aktualisiert
- BookDetail: Fehlermeldung wenn kein Match gefunden

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Audiolib
2026-05-26 17:04:42 +02:00
parent 3871da4bcc
commit a756db9d96
18 changed files with 477 additions and 356 deletions

View File

@@ -37,36 +37,37 @@ export default function FileBrowser({ initialPath = '/', onSelect, onClose }: Pr
return (
<div className="fixed inset-0 bg-black/70 z-50 flex items-center justify-center p-4" onClick={onClose}>
<div
className="bg-surface border border-white/10 rounded-xl w-full max-w-lg shadow-2xl flex flex-col"
className="bg-surface border border-divider rounded-xl w-full max-w-lg flex flex-col"
style={{ maxHeight: '80vh' }}
onClick={(e) => e.stopPropagation()}
>
{/* Header */}
<div className="flex items-center justify-between px-4 py-3 border-b border-white/10 flex-shrink-0">
<h3 className="text-sm font-semibold text-white">Ordner auswählen</h3>
<button onClick={onClose} className="text-gray-400 hover:text-white">
<div className="flex items-center justify-between px-4 py-3 border-b border-divider flex-shrink-0">
<h3 className="text-ink" style={{ fontSize: '13px', fontWeight: 600 }}>Ordner auswählen</h3>
<button onClick={onClose} className="text-muted hover:text-ink transition-colors">
<X size={16} />
</button>
</div>
{/* Quick access */}
<div className="flex gap-1 px-3 py-2 border-b border-white/10 flex-shrink-0 overflow-x-auto">
<div className="flex gap-1 px-3 py-2 border-b border-divider flex-shrink-0 overflow-x-auto">
{['/audiofiles', '/data', '/media', '/'].map((p) => (
<button key={p} onClick={() => load(p)}
className={`flex-shrink-0 px-2 py-1 rounded text-xs transition-colors ${path === p ? 'bg-primary/20 text-primary' : 'text-gray-500 hover:text-white hover:bg-white/5'}`}>
className={`flex-shrink-0 px-2 py-1 rounded transition-colors ${path === p ? 'bg-primary-dim text-primary' : 'text-muted hover:text-ink hover:bg-card'}`}
style={{ fontSize: '11px' }}>
{p}
</button>
))}
</div>
{/* Current path */}
<div className="px-4 py-2 bg-white/5 border-b border-white/10 flex items-center gap-2 flex-shrink-0">
<div className="px-4 py-2 bg-card border-b border-divider flex items-center gap-2 flex-shrink-0">
{parent && (
<button onClick={() => load(parent)} className="text-gray-400 hover:text-white flex-shrink-0">
<button onClick={() => load(parent)} className="text-muted hover:text-ink flex-shrink-0 transition-colors">
<ChevronUp size={16} />
</button>
)}
<p className="text-xs text-gray-300 font-mono truncate">{path}</p>
<p className="text-muted font-mono truncate" style={{ fontSize: '11px' }}>{path}</p>
</div>
{/* Entry list */}
@@ -76,25 +77,27 @@ export default function FileBrowser({ initialPath = '/', onSelect, onClose }: Pr
<Loader2 size={24} className="text-primary animate-spin" />
</div>
) : error ? (
<p className="text-red-400 text-sm px-4 py-6">{error}</p>
<p className="text-red-400 px-4 py-6" style={{ fontSize: '13px' }}>{error}</p>
) : entries.length === 0 ? (
<p className="text-gray-500 text-sm px-4 py-6">Ordner ist leer</p>
<p className="text-muted px-4 py-6" style={{ fontSize: '13px' }}>Ordner ist leer</p>
) : (
entries.map((e) =>
e.isDir ? (
<button
key={e.path}
onClick={() => load(e.path)}
className="w-full flex items-center gap-3 px-4 py-2.5 hover:bg-white/5 text-gray-300 hover:text-white text-sm text-left transition-colors"
className="w-full flex items-center gap-3 px-4 py-2.5 hover:bg-card text-muted hover:text-ink text-left transition-colors"
style={{ fontSize: '13px' }}
>
<Folder size={16} className="text-yellow-500 flex-shrink-0" />
<span className="flex-1 truncate">{e.name}</span>
<ChevronRight size={14} className="flex-shrink-0 text-gray-600" />
<ChevronRight size={14} className="flex-shrink-0 text-muted2" />
</button>
) : (
<div
key={e.path}
className="flex items-center gap-3 px-4 py-2 text-gray-600 text-sm"
className="flex items-center gap-3 px-4 py-2 text-muted2"
style={{ fontSize: '12px' }}
>
<FileAudio size={14} className="flex-shrink-0" />
<span className="truncate">{e.name}</span>
@@ -105,13 +108,14 @@ export default function FileBrowser({ initialPath = '/', onSelect, onClose }: Pr
</div>
{/* Footer */}
<div className="flex items-center justify-between px-4 py-3 border-t border-white/10 flex-shrink-0">
<button onClick={onClose} className="text-gray-400 text-sm hover:text-white">
<div className="flex items-center justify-between px-4 py-3 border-t border-divider flex-shrink-0">
<button onClick={onClose} className="text-muted hover:text-ink transition-colors" style={{ fontSize: '13px' }}>
Abbrechen
</button>
<button
onClick={() => { onSelect(path); onClose() }}
className="flex items-center gap-2 bg-primary text-black px-4 py-2 rounded-lg text-sm font-medium hover:bg-primary/80"
className="flex items-center gap-2 bg-primary text-black px-4 py-2 rounded-lg font-medium hover:opacity-90 transition-opacity"
style={{ fontSize: '13px' }}
>
<Check size={14} />
Auswählen