From 28844e845611efecda9d5991b9e0a22db5fdeaa0 Mon Sep 17 00:00:00 2001 From: kveld9 Date: Thu, 16 Apr 2026 20:34:55 -0300 Subject: [PATCH] release --- src-tauri/src/discord.rs | 49 +- src/locales/de.ts | 1172 ++++++++++++- src/locales/en.ts | 1175 ++++++++++++- src/locales/es.ts | 1179 ++++++++++++- src/locales/fr.ts | 1174 ++++++++++++- src/locales/nb.ts | 1173 ++++++++++++- src/locales/nl.ts | 1173 ++++++++++++- src/locales/ru.ts | 1232 ++++++++++++- src/locales/zh.ts | 1167 ++++++++++++- src/pages/Settings.tsx | 3589 ++++++++++++++++++++++++++++++++++---- src/store/authStore.ts | 743 +++++++- src/store/playerStore.ts | 25 +- 12 files changed, 13111 insertions(+), 740 deletions(-) diff --git a/src-tauri/src/discord.rs b/src-tauri/src/discord.rs index 61fc49d6..b4bb1c57 100644 --- a/src-tauri/src/discord.rs +++ b/src-tauri/src/discord.rs @@ -216,6 +216,19 @@ fn try_connect() -> Option { Some(client) } +/// Apply a template string, replacing placeholders with actual values. +/// Supported placeholders: {title}, {artist}, {album}, {paused} +fn apply_template(template: &str, title: &str, artist: &str, album: Option<&str>, is_playing: bool) -> String { + let paused_text = if is_playing { "" } else { "Paused — " }; + let album_text = album.unwrap_or(""); + + template + .replace("{title}", title) + .replace("{artist}", artist) + .replace("{album}", album_text) + .replace("{paused}", paused_text) +} + /// Update the Discord Rich Presence activity. /// /// - `is_playing`: true = playing (timer shown), false = paused (no timer, state shows "Paused"). @@ -225,6 +238,12 @@ fn try_connect() -> Option { /// - `fetch_itunes_covers`: if true, fetch artwork from the iTunes Search API when no /// `cover_art_url` is provided. If false (default), fall back to the Psysonic app icon /// without making any external request — required for privacy opt-in. +/// - `details_template`: template string for the "details" field. Default: "{artist} - {title}". +/// Supported placeholders: {title}, {artist}, {album}, {paused} +/// - `state_template`: template string for the "state" field. Default: "{album}". +/// Supported placeholders: {title}, {artist}, {album}, {paused} +/// - `large_text_template`: template string for the large image tooltip. Default: "{album}". +/// Supported placeholders: {title}, {artist}, {album}, {paused} #[tauri::command] pub async fn discord_update_presence( state: tauri::State<'_, DiscordState>, @@ -235,6 +254,9 @@ pub async fn discord_update_presence( elapsed_secs: Option, cover_art_url: Option, fetch_itunes_covers: bool, + details_template: Option, + state_template: Option, + large_text_template: Option, ) -> Result<(), String> { // Resolve artwork on a dedicated blocking thread — reqwest::blocking must not // run on the Tokio async executor directly. @@ -273,28 +295,25 @@ pub async fn discord_update_presence( let client = guard.as_mut().unwrap(); - // Discord RPC only exposes two visible text rows (details + state). - // The application name "Psysonic" is shown automatically by Discord as the - // header line. Album goes into large_text — visible as a hover tooltip on - // the cover art icon. - let large_text = album.as_deref().unwrap_or("Psysonic"); + // Apply templates for the three configurable text fields. + let details_str = details_template.as_deref().unwrap_or("{artist} - {title}"); + let details_text = apply_template(details_str, &title, &artist, album.as_deref(), is_playing); + + let state_str = state_template.as_deref().unwrap_or("{album}"); + let state_text = apply_template(state_str, &title, &artist, album.as_deref(), is_playing); + + let large_text_str = large_text_template.as_deref().unwrap_or("{album}"); + let large_text = apply_template(large_text_str, &title, &artist, album.as_deref(), is_playing); let assets = if let Some(ref url) = artwork_url { Assets::new() .large_image(url.as_str()) - .large_text(large_text) + .large_text(&large_text) } else { // Fallback to default Psysonic icon Assets::new() .large_image("psysonic") - .large_text(large_text) - }; - - // When paused, show "Paused" as the state text (replaces artist name). - let state_text: String = if is_playing { - artist.clone() - } else { - "Paused".to_string() + .large_text(&large_text) }; // ActivityType::Listening causes the Discord client to auto-start a running @@ -308,7 +327,7 @@ pub async fn discord_update_presence( let mut activity = Activity::new() .activity_type(activity_type) - .details(&title) + .details(&details_text) .state(&state_text) .assets(assets); diff --git a/src/locales/de.ts b/src/locales/de.ts index f30c364b..2e755976 100644 --- a/src/locales/de.ts +++ b/src/locales/de.ts @@ -1,1162 +1,2262 @@ export const deTranslation = { + sidebar: { + library: 'Bibliothek', + mainstage: 'Mainstage', + newReleases: 'Neueste', + allAlbums: 'Alle Alben', + randomAlbums: 'Zufallsalben', + randomPicker: 'Mix erstellen', + artists: 'Künstler', + randomMix: 'Zufallsmix', + favorites: 'Favoriten', + nowPlaying: 'Now Playing', + system: 'System', + statistics: 'Statistiken', + settings: 'Einstellungen', + help: 'Hilfe', + expand: 'Sidebar einblenden', + collapse: 'Sidebar ausblenden', + downloadingTracks: '{{n}} Tracks werden gecacht…', + syncingTracks: 'Synchronisiere {{done}}/{{total}}…', + cancelDownload: 'Download abbrechen', + offlineLibrary: 'Offline-Bibliothek', + genres: 'Genres', + playlists: 'Playlists', + mostPlayed: 'Meistgehört', + radio: 'Internetradio', + folderBrowser: 'Ordner-Browser', + deviceSync: 'Gerätesync', + libraryScope: 'Bibliotheksumfang', + allLibraries: 'Alle Bibliotheken', + expandPlaylists: 'Playlists ausklappen', + collapsePlaylists: 'Playlists einklappen', + }, + home: { + hero: 'Featured', + starred: 'Persönliche Favoriten', + recent: 'Zuletzt hinzugefügt', + mostPlayed: 'Meistgehört', + recentlyPlayed: 'Kürzlich gespielt', + discover: 'Entdecken', + loadMore: 'Mehr laden', + discoverMore: 'Mehr entdecken', + discoverArtists: 'Künstler entdecken', + discoverArtistsMore: 'Alle Künstler' + }, + hero: { + eyebrow: 'Album des Augenblicks', + playAlbum: 'Album abspielen', + enqueue: 'Einreihen', + enqueueTooltip: 'Ganzes Album zur Warteschlange hinzufügen', + }, + search: { + placeholder: 'Suchen nach Künstler, Album oder Song…', + noResults: 'Keine Ergebnisse für „{{query}}"', + artists: 'Künstler', + albums: 'Alben', + songs: 'Songs', + clearLabel: 'Suche leeren', + title: 'Suche', + resultsFor: 'Ergebnisse für „{{query}}"', + album: 'Album', + advanced: 'Erweiterte Suche', + advancedSearchTerm: 'Suchbegriff', + advancedSearchPlaceholder: 'Titel, Album, Künstler…', + advancedGenre: 'Genre', + advancedAllGenres: 'Alle Genres', + advancedYear: 'Jahr', + advancedYearFrom: 'von', + advancedYearTo: 'bis', + advancedAll: 'Alle', + advancedSearch: 'Suchen', + advancedEmpty: 'Suchbegriff eingeben oder Filter wählen, um zu beginnen.', + advancedNoResults: 'Keine Ergebnisse gefunden.', + advancedGenreNote: 'Songs werden zufällig aus dem Genre gewählt.', + recentSearches: 'Zuletzt gesucht', + browse: 'Stöbern', + emptyHint: 'Was möchtest du hören?', + genres: 'Genres', + }, + nowPlaying: { + tooltip: 'Wer hört was?', + title: 'Wer hört was?', + loading: 'Lädt…', + nobody: 'Gerade hört niemand Musik.', + minutesAgo: 'vor {{n}}m', + nothingPlaying: 'Noch nichts am Laufen. Leg einen Track auf!', + aboutArtist: 'Über den Künstler', + fromAlbum: 'Aus diesem Album', + viewAlbum: 'Album öffnen', + goToArtist: 'Zum Künstler', + readMore: 'Mehr lesen', + showLess: 'Weniger anzeigen', + genreInfo: 'Genre', + trackInfo: 'Track-Info', + }, + contextMenu: { + playNow: 'Direkt abspielen', + playNext: 'Als Nächstes abspielen', + addToQueue: 'Zur Warteschlange hinzufügen', + enqueueAlbum: 'Ganzes Album einreihen', + startRadio: 'Radio starten', + instantMix: 'Instant Mix', + instantMixFailed: 'Instant Mix konnte nicht erstellt werden — Server- oder Pluginfehler.', + cliMixNeedsTrack: 'Es läuft nichts — starte zuerst die Wiedergabe und führe den Mix-Befehl erneut aus.', + lfmLove: 'Auf Last.fm liken', + lfmUnlove: 'Last.fm-Like entfernen', + favorite: 'Favorisieren', + favoriteArtist: 'Künstler favorisieren', + favoriteAlbum: 'Album favorisieren', + unfavorite: 'Aus Favoriten entfernen', + unfavoriteArtist: 'Künstler aus Favoriten entfernen', + unfavoriteAlbum: 'Album aus Favoriten entfernen', + removeFromQueue: 'Diesen Song entfernen', + removeFromPlaylist: 'Aus Playlist entfernen', + openAlbum: 'Album öffnen', + goToArtist: 'Zum Künstler', + download: 'Herunterladen (ZIP)', + addToPlaylist: 'Zur Playlist hinzufügen', + selectedPlaylists: '{{count}} Playlists ausgewählt', + selectedAlbums: '{{count}} Alben ausgewählt', + selectedArtists: '{{count}} Künstler ausgewählt', + songInfo: 'Song-Infos', + }, + albumDetail: { + back: 'Zurück', + playAll: 'Alle abspielen', + enqueue: 'Einreihen', + enqueueTooltip: 'Ganzes Album zur Warteschlange hinzufügen', + artistBio: 'Künstler-Bio', + download: 'Download (ZIP)', + downloading: 'Lade…', + cacheOffline: 'Offline verfügbar machen', + offlineCached: 'Offline verfügbar', + offlineDownloading: 'Wird gecacht… ({{n}}/{{total}})', + removeOffline: 'Offline-Cache löschen', + offlineStorageFull: 'Offline-Speicher voll (Limit: {{mb}} MB). Lösche ein Album aus der Offline-Bibliothek oder erhöhe das Limit in den Einstellungen.', + offlineStorageGoToSettings: 'Einstellungen', + offlineStorageGoToLibrary: 'Offline-Bibliothek', + favoriteAdd: 'Zu Favoriten hinzufügen', + favoriteRemove: 'Aus Favoriten entfernen', + favorite: 'Als Favorit', + noBio: 'Keine Biografie verfügbar.', + moreByArtist: 'Mehr von {{artist}}', + tracksCount: '{{n}} Tracks', + goToArtist: 'Zu {{artist}} wechseln', + moreLabelAlbums: 'Weitere Alben von {{label}} anzeigen', + trackTitle: 'Titel', + trackAlbum: 'Album', + trackArtist: 'Interpret', + trackGenre: 'Genre', + trackFormat: 'Format', + trackFavorite: 'Favorit', + trackRating: 'Bewertung', + trackDuration: 'Dauer', + trackTotal: 'Gesamt', + columns: 'Spalten', - resetColumns: 'Zurücksetzen', + notFound: 'Album nicht gefunden.', + bioModal: 'Künstler-Biografie', + bioClose: 'Schließen', + ratingLabel: 'Bewertung', + enlargeCover: 'Vergrößern', + filterSongs: 'Titel filtern…', + sortNatural: 'Reihenfolge', + sortByTitle: 'A–Z (Titel)', + sortByArtist: 'A–Z (Künstler)', + sortByAlbum: 'A–Z (Album)', + }, + entityRating: { + albumShort: 'Albumbewertung', + artistShort: 'Künstlerbewertung', + albumAriaLabel: 'Albumbewertung', + artistAriaLabel: 'Künstlerbewertung', + saveFailed: 'Bewertung konnte nicht gespeichert werden.', + }, + artistDetail: { + back: 'Zurück', + albums: 'Alben', + album: 'Album', + playAll: 'Alle abspielen', + shuffle: 'Zufallswiedergabe', + radio: 'Radio', + loading: 'Lädt…', + noRadio: 'Keine ähnlichen Titel für diesen Künstler gefunden.', + notFound: 'Künstler nicht gefunden.', + albumsBy: 'Alben von {{name}}', + topTracks: 'Beliebteste Titel', + noAlbums: 'Keine Alben gefunden.', + trackTitle: 'Titel', + trackAlbum: 'Album', + trackDuration: 'Dauer', + favoriteAdd: 'Zu Favoriten hinzufügen', + favoriteRemove: 'Aus Favoriten entfernen', + favorite: 'Als Favorit', + albumCount_one: '{{count}} Album', + albumCount_other: '{{count}} Alben', + openedInBrowser: 'Im Browser geöffnet', + featuredOn: 'Auch enthalten auf', + similarArtists: 'Ähnliche Künstler', + cacheOffline: 'Diskografie offline speichern', + offlineCached: 'Diskografie gecacht', + offlineDownloading: 'Wird gecacht… ({{done}}/{{total}} Alben)', + uploadImage: 'Künstlerbild hochladen', + uploadImageError: 'Bild konnte nicht hochgeladen werden', + }, + favorites: { + title: 'Favoriten', + empty: 'Du hast noch keine Favoriten gespeichert.', + artists: 'Künstler', + albums: 'Alben', + songs: 'Songs', + enqueueAll: 'Alle in die Warteschlange', + playAll: 'Alle abspielen', + removeSong: 'Aus Favoriten entfernen', + stations: 'Radiosender', + showingFiltered: 'Zeige {{filtered}} von {{total}} ({{artist}})', + showingCount: 'Zeige {{filtered}} von {{total}}', + clearArtistFilter: 'Künstlerfilter zurücksetzen', + noFilterResults: 'Keine Ergebnisse mit den ausgewählten Filtern.', + allArtists: 'Alle Künstler', + }, + randomLanding: { + title: 'Mix erstellen', + mixByTracks: 'Mix nach Titeln', + mixByTracksDesc: 'Zufällige Auswahl aus deiner gesamten Mediathek', + mixByAlbums: 'Mix nach Alben', + mixByAlbumsDesc: 'Zufällige Alben für neue Entdeckungen', + }, + randomAlbums: { + title: 'Zufallsalben', + refresh: 'Neu laden', + }, + genres: { + title: 'Genres', + genreCount: 'Genres', + albumCount_one: '{{count}} Album', + albumCount_other: '{{count}} Alben', + loading: 'Genres werden geladen…', + empty: 'Keine Genres gefunden.', + albumsLoading: 'Alben werden geladen…', + albumsEmpty: 'Keine Alben in diesem Genre gefunden.', + loadMore: 'Mehr laden', + back: 'Zurück', + }, + randomMix: { + title: 'Zufallsmix', + remix: 'Neu mixen', + remixTooltip: 'Neue Songs laden', + remixGenre: '{{genre}} neu mixen', + remixTooltipGenre: 'Neue {{genre}}-Songs laden', + playAll: 'Alle abspielen', + trackTitle: 'Titel', + trackArtist: 'Künstler', + trackAlbum: 'Album', + trackFavorite: 'Favorit', + trackDuration: 'Dauer', + favoriteAdd: 'Zu Favoriten hinzufügen', + favoriteRemove: 'Aus Favoriten entfernen', + play: 'Abspielen', + trackGenre: 'Genre', + excludeAudiobooks: 'Hörbücher & Hörspiele ausschließen', + excludeAudiobooksDesc: 'Prüft Keywords gegen Genre, Titel, Album und Künstler — z. B. Hörbuch, Audiobook, Spoken Word, …', + genreBlocked: 'Keyword gesperrt', + genreAddedToBlacklist: 'Zur Filterliste hinzugefügt', + genreAlreadyBlocked: 'Bereits gesperrt', + artistBlocked: 'Künstler gesperrt', + artistAddedToBlacklist: 'Künstler zur Filterliste hinzugefügt', + artistClickHint: 'Klicken um diesen Künstler zu sperren', + blacklistToggle: 'Keyword-Filter', + genreMixTitle: 'Genre-Mix', + genreMixDesc: 'Top 20 Genres nach Songanzahl — klicken für einen Zufallsmix', + genreMixAll: 'Alle Songs', + genreMixLoadMore: '10 weitere laden', + genreMixNoGenres: 'Keine Genres auf dem Server gefunden.', + shuffleGenres: 'Andere Genres anzeigen', + filterPanelTitle: 'Filter', + filterPanelDesc: 'Genre-Tag oder Künstlername in der Liste anklicken, um ihn aus zukünftigen Mixes auszuschließen.', + genreClickHint: 'Genre-Tag anklicken,\num es als Filter-Keyword hinzuzufügen.\nPrüft Genre, Titel, Album & Künstler.', + }, + albums: { + title: 'Alle Alben', + sortByName: 'A–Z (Album)', + sortByArtist: 'A–Z (Künstler)', + sortNewest: 'Neueste zuerst', + sortRandom: 'Zufällig', + yearFrom: 'Von', + yearTo: 'Bis', + yearFilterClear: 'Jahresfilter zurücksetzen', + yearFilterLabel: 'Jahr', + select: 'Mehrfachauswahl', + startSelect: 'Mehrfachauswahl aktivieren', + cancelSelect: 'Abbrechen', + selectionCount: '{{count}} ausgewählt', + downloadZips: 'ZIPs herunterladen', + addOffline: 'Offline hinzufügen', + downloadingZip: 'Lade {{current}}/{{total}} herunter: {{name}}', + downloadZipDone: '{{count}} ZIP(s) heruntergeladen', + downloadZipFailed: 'Download fehlgeschlagen: {{name}}', + offlineQueuing: '{{count}} Album(s) für Offline einreihen…', + offlineFailed: '{{name}} konnte nicht offline hinzugefügt werden', + }, + artists: { + title: 'Künstler', + search: 'Suchen…', + all: 'Alle', + gridView: 'Gitteransicht', + listView: 'Listenansicht', + imagesOn: 'Künstlerbilder aktiv — kann Netzwerk- und Systemlast erhöhen', + imagesOff: 'Künstlerbilder deaktiviert — zeigt nur Initialen', + loadMore: 'Mehr laden', + notFound: 'Keine Künstler gefunden.', + albumCount_one: '{{count}} Album', + albumCount_other: '{{count}} Alben', + selectionCount: '{{count}} ausgewählt', + select: 'Mehrfachauswahl', + startSelect: 'Mehrfachauswahl aktivieren', + cancelSelect: 'Abbrechen', + addToPlaylist: 'Zur Playlist hinzufügen', + }, + login: { + subtitle: 'Dein Navidrome Desktop Player', + serverName: 'Server-Name (optional)', + serverNamePlaceholder: 'Mein Navidrome', + serverUrl: 'Server-URL', + serverUrlPlaceholder: '192.168.1.100:4533 oder https://music.example.com', + username: 'Benutzername', + usernamePlaceholder: 'admin', + password: 'Passwort', + showPassword: 'Passwort anzeigen', + hidePassword: 'Passwort verstecken', + connect: 'Verbinden', + connecting: 'Verbinde…', + connected: 'Verbunden!', + error: 'Verbindung fehlgeschlagen – bitte Daten prüfen.', + urlRequired: 'Bitte Server-URL eingeben.', + savedServers: 'Gespeicherte Server', + addNew: 'Oder neuen Server hinzufügen', + }, + connection: { + connected: 'Verbunden', + connectedTo: 'Verbunden mit {{server}}', + disconnected: 'Getrennt', + disconnectedFrom: '{{server}} nicht erreichbar — klicken für Einstellungen', + checking: 'Verbinde…', + extern: 'Extern', + offlineTitle: 'Keine Serververbindung', + offlineSubtitle: '{{server}} ist nicht erreichbar. Prüfe Netzwerk oder Server.', + offlineModeBanner: 'Offline-Modus — Wiedergabe aus lokalem Cache', + offlineNoCacheBanner: 'Keine Serververbindung — {{server}} nicht erreichbar', + offlineLibraryTitle: 'Offline-Bibliothek', + offlineLibraryEmpty: 'Noch keine Alben gecacht. Online gehen, Album öffnen und "Offline verfügbar machen" klicken.', + offlineAlbumCount: '{{n}} Album', + offlineAlbumCount_plural: '{{n}} Alben', + offlineFilterAll: 'Alle', + offlineFilterAlbums: 'Alben', + offlineFilterPlaylists: 'Playlists', + offlineFilterArtists: 'Diskografien', + retry: 'Erneut versuchen', + serverSettings: 'Server-Einstellungen', + switchServerTitle: 'Server wechseln', + switchServerHint: 'Klicken, um einen anderen gespeicherten Server zu wählen.', + manageServers: 'Server verwalten…', + switchFailed: 'Wechsel fehlgeschlagen — Server nicht erreichbar.', + lastfmConnected: 'Last.fm verbunden als @{{user}}', + lastfmSessionInvalid: 'Session ungültig — klicken zum Neu-Verbinden', + }, + common: { + albums: 'Alben', + album: 'Album', + loading: 'Lade…', + loadingMore: 'Lade…', + loadingPlaylists: 'Lade Playlists…', + noAlbums: 'Keine Alben gefunden.', + downloading: 'Lade…', + downloadZip: 'Download (ZIP)', + back: 'Zurück', + cancel: 'Abbrechen', + save: 'Speichern', + delete: 'Löschen', + use: 'Verwenden', + add: 'Hinzufügen', + active: 'Aktiv', + download: 'Herunterladen', + chooseDownloadFolder: 'Download-Ordner wählen', + noFolderSelected: 'Kein Ordner ausgewählt', + rememberDownloadFolder: 'Ordner merken', + filterGenre: 'Genre-Filter', + filterSearchGenres: 'Genres suchen…', + filterNoGenres: 'Keine Genres gefunden', + filterClear: 'Zurücksetzen', + play: 'Abspielen', + bulkSelected: '{{count}} ausgewählt', + clearSelection: 'Auswahl aufheben', + bulkAddToPlaylist: 'Zur Playlist hinzufügen', + bulkRemoveFromPlaylist: 'Aus Playlist entfernen', + bulkClear: 'Auswahl aufheben', + updaterAvailable: 'Update verfügbar', + updaterVersion: 'v{{version}} verfügbar', + updaterWebsite: 'Website', + updaterModalTitle: 'Neue Version verfügbar', + updaterChangelog: 'Was ist neu', + updaterDownloadBtn: 'Jetzt herunterladen', + updaterSkipBtn: 'Version überspringen', + updaterRemindBtn: 'Später erinnern', + updaterDone: 'Download abgeschlossen', + updaterShowFolder: 'Im Ordner anzeigen', + updaterInstallHint: 'Psysonic schließen und das Installationsprogramm manuell ausführen.', + updaterAurHint: 'Update über AUR installieren:', + updaterErrorMsg: 'Download fehlgeschlagen', + updaterRetryBtn: 'Erneut versuchen', + durationHoursMinutes: '{{hours}} Std. {{minutes}} Min.', + durationMinutesOnly: '{{minutes}} Min.', + updaterOpenGitHub: 'Auf GitHub öffnen', + filters: 'Filter', + more: 'mehr', + yearRange: 'Jahresbereich', + clearAll: 'Alles zurücksetzen', + }, + settings: { + title: 'Einstellungen', + language: 'Sprache', + languageEn: 'Englisch', + languageDe: 'Deutsch', + languageFr: 'Französisch', + languageNl: 'Niederländisch', + languageZh: 'Chinesisch', + languageNb: 'Norwegisch', + languageRu: 'Russisch', + font: 'Schriftart', + theme: 'Design', + appearance: 'Darstellung', + servers: 'Server', + serverName: 'Server-Name', + serverUrl: 'Server-URL', + serverUrlPlaceholder: '192.168.1.100:4533 oder https://music.example.com', + serverUsername: 'Benutzername', + serverPassword: 'Passwort', + addServer: 'Server hinzufügen', + addServerTitle: 'Neuen Server hinzufügen', + useServer: 'Verwenden', + deleteServer: 'Löschen', + noServers: 'Keine Server gespeichert.', + serverActive: 'Aktiv', + confirmDeleteServer: 'Server „{{name}}" löschen?', + serverConnecting: 'Verbinde…', + serverConnected: 'Verbunden!', + serverFailed: 'Verbindung fehlgeschlagen.', + testBtn: 'Verbindung testen', + testingBtn: 'Teste…', + serverCompatible: 'Kompatibel mit: Navidrome · Gonic · Airsonic · Subsonic', + audiomuseTitle: 'AudioMuse-AI (Navidrome)', + audiomuseDesc: + 'Aktivieren, wenn dieser Server das AudioMuse-AI-Navidrome-Plugin nutzt. Schaltet Instant Mix pro Titel frei und nutzt ähnliche Künstler vom Server statt Last.fm auf Künstlerseiten.', + audiomuseIssueHint: + 'Instant Mix ist kürzlich fehlgeschlagen — Navidrome-Plugin und AudioMuse-API prüfen. Ohne Server-Treffer werden ähnliche Künstler über Last.fm geladen.', + connected: 'Verbunden', + failed: 'Fehlgeschlagen', + eqTitle: 'Equalizer', + eqEnabled: 'Equalizer aktivieren', + eqPreset: 'Preset', + eqPresetCustom: 'Benutzerdefiniert', + eqPresetBuiltin: 'Eingebaute Presets', + eqPresetCustomGroup: 'Meine Presets', + eqSavePreset: 'Als Preset speichern', + eqPresetName: 'Preset-Name…', + eqDeletePreset: 'Preset löschen', + eqResetBands: 'Auf Flat zurücksetzen', + eqPreGain: 'Vorverstärkung', + eqResetPreGain: 'Vorverstärkung zurücksetzen', + eqAutoEqTitle: 'AutoEQ Kopfhörer-Suche', + eqAutoEqPlaceholder: 'Kopfhörer / IEM Modell suchen…', + eqAutoEqSearching: 'Suche…', + eqAutoEqNoResults: 'Keine Ergebnisse gefunden', + eqAutoEqError: 'Suche fehlgeschlagen', + eqAutoEqRateLimit: 'GitHub Rate-Limit erreicht — in einer Minute erneut versuchen', + eqAutoEqFetchError: 'EQ-Profil konnte nicht geladen werden', + lfmTitle: 'Last.fm', + lfmConnect: 'Mit Last.fm verbinden', + lfmConnecting: 'Warte auf Bestätigung…', + lfmConfirm: 'Ich habe die App autorisiert', + lfmConnected: 'Verbunden als', + lfmDisconnect: 'Trennen', + lfmConnectDesc: 'Verbinde deinen Last.fm Account, um Scrobbling und Now-Playing-Updates direkt aus Psysonic heraus zu aktivieren — keine Navidrome-Konfiguration erforderlich.', + lfmOpenBrowser: 'Es öffnet sich ein Browserfenster. Autorisiere Psysonic auf Last.fm und klicke dann unten auf den Button.', + lfmScrobbles: '{{n}} Scrobbles', + lfmMemberSince: 'Dabei seit {{year}}', + scrobbleEnabled: 'Scrobbling aktiviert', + scrobbleDesc: 'Songs nach 50% Laufzeit an Last.fm senden', + behavior: 'App-Verhalten', + cacheTitle: 'Max. Speichergröße', + cacheDesc: 'Cover und Künstlerbilder. Wenn voll, werden die ältesten Einträge automatisch entfernt. Offline-Alben werden nicht automatisch gelöscht, aber beim manuellen Cache leeren entfernt.', + cacheUsedImages: 'Bilder:', + cacheUsedOffline: 'Offline-Tracks:', + cacheUsedHot: 'Belegter Speicher:', + hotCacheTrackCount: 'Titel im Cache:', + cacheMaxLabel: 'Max. Größe', + cacheClearBtn: 'Cache leeren', + cacheClearWarning: 'Alle Offline-Alben werden damit aus der Bibliothek entfernt.', + cacheClearConfirm: 'Alles löschen', + cacheClearCancel: 'Abbrechen', + offlineDirTitle: 'Offline-Bibliothek (In-App)', + offlineDirDesc: 'Speicherort für Titel, die du innerhalb von Psysonic offline verfügbar machst.', + offlineDirDefault: 'Standard (App-Daten)', + offlineDirChange: 'Verzeichnis ändern', + offlineDirClear: 'Auf Standard zurücksetzen', + offlineDirHint: 'Neue Downloads werden an diesem Ort gespeichert. Bestehende Downloads verbleiben am ursprünglichen Pfad.', + hotCacheTitle: 'Hot-Playback-Cache', + hotCacheAlphaBadge: 'Alpha', + hotCacheDisclaimer: 'Lädt kommende Warteschlangen-Titel vor und behält zuletzt gespielte. Bei aktivierter Option: Speicherplatz und Netzwerk.', + hotCacheDirDefault: 'Standard (App-Daten)', + hotCacheDirChange: 'Ordner ändern', + hotCacheDirClear: 'Auf Standard zurücksetzen', + hotCacheDirHint: 'Beim Ordnerwechsel wird der App-Index zurückgesetzt; alte Dateien bleiben am alten Ort, bis Sie sie löschen.', + hotCacheEnabled: 'Hot-Playback-Cache aktivieren', + hotCacheMaxMb: 'Maximale Cache-Größe', + hotCacheDebounce: 'Debounce bei Warteschlangen-Änderungen', + hotCacheDebounceImmediate: 'Sofort', + hotCacheDebounceSeconds: '{{n}} s', + hotCacheClearBtn: 'Hot-Cache leeren', + audioOutputDevice: 'Audio-Ausgabegerät', + audioOutputDeviceDesc: 'Wähle das Audiogerät, über das Psysonic spielt. Änderungen werden sofort übernommen und starten den aktuellen Track neu.', + audioOutputDeviceDefault: 'Systemstandard', + audioOutputDeviceRefresh: 'Geräteliste aktualisieren', + audioOutputDeviceOsDefaultNow: 'aktuelle Systemausgabe', + audioOutputDeviceListError: 'Audiogeräteliste konnte nicht geladen werden.', + audioOutputDeviceNotInCurrentList: 'nicht in der aktuellen Liste', + hiResTitle: 'Native Hi-Res-Wiedergabe', + hiResEnabled: 'Native Hi-Res-Wiedergabe aktivieren', + hiResDesc: "Standardmäßig wird auf 44,1 kHz begrenzt (maximale Stabilität). Nur aktivieren, wenn Hardware und Netzwerk zuverlässig hohe Abtastraten (88,2 kHz+) unterstützen.", + showArtistImages: 'Künstlerbilder anzeigen', + showArtistImagesDesc: 'Lädt und zeigt Künstlerbilder in der Künstlerübersicht. Standardmäßig deaktiviert, um Server-I/O und Netzwerklast bei großen Bibliotheken zu reduzieren.', + showTrayIcon: 'Tray-Icon anzeigen', + showTrayIconDesc: 'Psysonic-Icon im System-Tray / in der Menüleiste anzeigen.', + minimizeToTray: 'Im Tray minimieren', + minimizeToTrayDesc: 'Beim Schließen des Fensters läuft Psysonic weiter im System-Tray statt zu beenden.', + discordRichPresence: 'Discord Rich Presence', + discordRichPresenceDesc: 'Zeigt den aktuell gespielten Titel im Discord-Profil an. Discord muss dafür geöffnet sein.', + useCustomTitlebar: 'Eigene Titelleiste', + useCustomTitlebarDesc: 'Ersetzt die System-Titelleiste durch eine eingebaute, die zum App-Theme passt. Deaktivieren, um die native GNOME/GTK-Titelleiste zu verwenden.', + discordAppleCovers: 'Cover über Apple Music für Discord laden', + discordAppleCoversDesc: 'Sendet Künstler- und Albumname an die Apple-Such-API, um Cover für dein Discord-Profil zu finden. Standardmäßig aus Datenschutzgründen deaktiviert.', + + discordTemplates: 'Benutzerdefinierte Textvorlagen', + + discordTemplatesDesc: 'Passe an, welche Informationen in deinem Discord-Profil angezeigt werden. Variablen: {title}, {artist}, {album}, {paused}', + + discordTemplateDetails: 'Primäre Zeile (details)', + + discordTemplateState: 'Sekundäre Zeile (state)', + + discordTemplateLargeText: 'Album-Tooltip (largeText)', + nowPlayingEnabled: 'Im Livefenster anzeigen', + nowPlayingEnabledDesc: 'Überträgt den aktuell gespielten Titel an die Livehörer-Ansicht des Servers. Deaktivieren, um keine Wiedergabedaten zu senden.', + lyricsServerFirst: 'Server-Lyrics bevorzugen', + lyricsServerFirstDesc: 'Server-seitige Lyrics (eingebettete Tags, Sidecar-Dateien) vor LRCLIB abfragen. Deaktivieren, um LRCLIB zuerst zu verwenden.', + enableNeteaselyrics: 'Netease Cloud Music Lyrics', + enableNeteaselyricsDesc: 'Netease Cloud Music als letzte Lyrics-Quelle verwenden, wenn Server und LRCLIB nichts liefern. Besonders gut für asiatische und internationale Musik.', + lyricsSourcesTitle: 'Lyrics-Quellen', + lyricsSourcesDesc: 'Wähle, welche Quellen für Lyrics abgefragt werden und in welcher Reihenfolge. Ziehen zum Sortieren. Deaktivierte Quellen werden übersprungen.', + lyricsSourceServer: 'Server', + lyricsSourceLrclib: 'LRCLIB', + lyricsSourceNetease: 'Netease Cloud Music', + downloadsTitle: 'ZIP-Export & Archivierung', + downloadsFolderDesc: 'Zielverzeichnis für Alben, die du als ZIP-Datei auf deinen Computer herunterlädst.', + downloadsDefault: 'Standard-Downloads-Ordner', + pickFolder: 'Auswählen', + pickFolderTitle: 'Download-Ordner auswählen', + clearFolder: 'Download-Ordner löschen', + logout: 'Abmelden', + aboutTitle: 'Über Psysonic', + aboutDesc: 'Ein moderner Desktop-Musikplayer für Subsonic-kompatible Server (Navidrome, Gonic u. a.). Basiert auf Tauri v2 mit einer nativen Rust-Audio-Engine — schlank und schnell, aber vollgepackt mit Features: Wellenform-Seekbar, synchronisierte Lyrics, Last.fm-Integration, 10-Band-EQ, Crossfade, nahtlose Wiedergabe, Replay Gain, Genre-Browser und eine große Theme-Bibliothek.', + aboutLicense: 'Lizenz', + aboutLicenseText: 'GNU GPL v3 — kostenlos nutzbar, veränderbar und unter gleicher Lizenz weiterzugeben.', + aboutRepo: 'Quellcode auf GitHub', + aboutVersion: 'Version', + aboutBuiltWith: 'Gebaut mit Tauri · React · TypeScript · Rust/rodio', + aboutAiCredit: 'Mit freundlicher Unterstützung von Claude Code by Anthropic', + aboutContributorsLabel: 'Mitwirkende', + aboutSpecialThanksLabel: 'Besonderer Dank', + changelog: 'Changelog', + showChangelogOnUpdate: "'Was ist neu' bei Update anzeigen", + showChangelogOnUpdateDesc: 'Zeigt automatisch die Neuerungen an, wenn eine neue Version zum ersten Mal gestartet wird.', + randomMixTitle: 'Zufallsmix', + randomMixBlacklistTitle: 'Eigene Filter-Keywords', + randomMixBlacklistDesc: 'Songs werden ausgeschlossen, wenn ein Keyword auf Genre, Titel, Album oder Künstler zutrifft (aktiv wenn die Checkbox oben an ist).', + randomMixBlacklistPlaceholder: 'Keyword hinzufügen…', + randomMixBlacklistAdd: 'Hinzufügen', + randomMixBlacklistEmpty: 'Noch keine eigenen Keywords hinzugefügt.', + randomMixHardcodedTitle: 'Eingebaute Keywords (aktiv wenn Checkbox an)', + tabAudio: 'Audio', + tabStorage: 'Speicher & Downloads', + tabAppearance: 'Darstellung', + homeCustomizerTitle: 'Startseite', + sidebarTitle: 'Seitenleiste', + sidebarReset: 'Zurücksetzen', + sidebarDrag: 'Ziehen zum Umsortieren', + sidebarFixed: 'Immer sichtbar', - randomNavSplitTitle: 'Mix-Navigation aufteilen', - randomNavSplitDesc: '"Zufallsmix" und "Zufallsalben" als separate Sidebar-Einträge statt als "Mix erstellen"-Hub anzeigen.', + tabInput: 'Eingabe', + tabServer: 'Server', + shortcutsReset: 'Auf Standard zurücksetzen', + shortcutListening: 'Taste drücken…', + shortcutUnbound: '—', + shortcutClear: 'Löschen', + globalShortcutsTitle: 'Globale Shortcuts', + globalShortcutsNote: 'Funktionieren systemweit, auch wenn Psysonic im Hintergrund läuft. Mindestens Ctrl, Alt oder Super als Modifier erforderlich.', + shortcutPlayPause: 'Wiedergabe / Pause', + shortcutNext: 'Nächster Titel', + shortcutPrev: 'Vorheriger Titel', + shortcutVolumeUp: 'Lautstärke erhöhen', + shortcutVolumeDown: 'Lautstärke verringern', + shortcutSeekForward: '10s vorspulen', + shortcutSeekBackward: '10s zurückspulen', + shortcutToggleQueue: 'Warteschlange ein-/ausblenden', + shortcutOpenFolderBrowser: '{{folderBrowser}} öffnen', + shortcutFullscreenPlayer: 'Vollbild-Player', + shortcutNativeFullscreen: 'Nativer Vollbildmodus', + tabSystem: 'System', + tabGeneral: 'Allgemein', + ratingsSectionTitle: 'Bewertungen', + ratingsSkipStarTitle: 'Skip → 1 Stern', + ratingsSkipStarDesc: + 'Wird ein Titel mehrmals hintereinander übersprungen, bekommt er automatisch 1★. Nur für noch nicht bewertete Titel.', + ratingsSkipStarThresholdLabel: 'Skips', + ratingsMixFilterTitle: 'Nach Bewertung filtern', + ratingsMixFilterDesc: + 'Gering bewertete Titel in {{mix}} und {{albums}} ausblenden. Nochmals auf den gewählten Stern klicken, um den Filter zu deaktivieren.', + ratingsMixMinSong: 'Titel', + ratingsMixMinAlbum: 'Alben', + ratingsMixMinArtist: 'Interpreten', + ratingsMixMinThresholdAria: 'Mindest-Sterne: {{label}}', + backupTitle: 'Backup & Wiederherstellung', + backupExport: 'Einstellungen exportieren', + backupExportDesc: 'Speichert alle Einstellungen, Serverprofile, Last.fm-Konfiguration, Theme, EQ und Tastenkürzel in eine .psybkp-Datei. Passwörter werden im Klartext gespeichert — Datei sicher aufbewahren.', + backupImport: 'Einstellungen importieren', + backupImportDesc: 'Stellt Einstellungen aus einer .psybkp-Datei wieder her. Die App wird nach dem Import neu geladen.', + backupImportConfirm: 'Alle aktuellen Einstellungen werden überschrieben. Fortfahren?', + backupSuccess: 'Backup gespeichert', + backupImportSuccess: 'Einstellungen wiederhergestellt — wird neu geladen…', + backupImportError: 'Ungültige oder beschädigte Backup-Datei.', + playbackTitle: 'Wiedergabe', + replayGain: 'Replay Gain', + replayGainDesc: 'Lautstärke mit ReplayGain-Metadaten normalisieren', + replayGainMode: 'Modus', + replayGainTrack: 'Track', + replayGainAlbum: 'Album', + replayGainPreGain: 'Pre-Gain (getaggte Dateien)', + replayGainFallback: 'Fallback (ohne Tags / Radio)', + crossfade: 'Crossfade', + crossfadeDesc: 'Überblendung zwischen Tracks', + crossfadeSecs: '{{n}} s', + notWithGapless: 'Nicht verfügbar wenn Nahtlose Wiedergabe aktiv ist', + notWithCrossfade: 'Nicht verfügbar wenn Crossfade aktiv ist', + gapless: 'Nahtlose Wiedergabe', + gaplessDesc: 'Nächsten Track vorpuffern um Lücken zwischen Songs zu vermeiden', + preloadMode: 'Nächsten Track vorpuffern', + preloadModeDesc: 'Wann mit dem Puffern des nächsten Tracks begonnen werden soll', + nextTrackBufferingTitle: 'Nächster Track – Pufferung', + preloadHotCacheMutualExclusive: 'Preload und Hot Cache erfüllen denselben Zweck – nur eine Methode kann gleichzeitig aktiv sein. Das Aktivieren einer deaktiviert die andere automatisch.', + preloadOff: 'Aus', + preloadBalanced: 'Ausgewogen (30 s vor Ende)', + preloadEarly: 'Früh (nach 5 s Wiedergabe)', + preloadCustom: 'Benutzerdefiniert', + preloadCustomSeconds: 'Sekunden vor Ende: {{n}}', + infiniteQueue: 'Endlose Warteschlange', + infiniteQueueDesc: 'Automatisch Zufallstitel anhängen wenn die Warteschlange leer wird', + experimental: 'Experimentell', + fsPlayerSection: 'Vollbild-Player', + fsShowArtistPortrait: 'Künstlerfoto anzeigen', + fsShowArtistPortraitDesc: 'Künstlerfoto (oder Albumcover) auf der rechten Seite des Vollbild-Players anzeigen.', + fsPortraitDim: 'Abdunkelung des Fotos', + seekbarStyle: 'Seekbar-Stil', + seekbarStyleDesc: 'Aussehen der Wiedergabe-Seekbar auswählen', + seekbarWaveform: 'Wellenform', + seekbarLinedot: 'Linie & Punkt', + seekbarBar: 'Balken', + seekbarThick: 'Dicker Balken', + seekbarSegmented: 'Segmentiert', + seekbarNeon: 'Neonröhre', + seekbarPulsewave: 'Pulswelle', + seekbarParticletrail: 'Partikel-Spur', + seekbarLiquidfill: 'Flüssigkeit', + seekbarRetrotape: 'Retro-Band', + themeSchedulerTitle: 'Theme-Zeitplan', + themeSchedulerEnable: 'Theme-Zeitplan aktivieren', + themeSchedulerEnableSub: 'Wechselt automatisch zwischen zwei Themes basierend auf der Uhrzeit', + themeSchedulerDayTheme: 'Tages-Theme', + themeSchedulerDayStart: 'Tag beginnt um', + themeSchedulerNightTheme: 'Nacht-Theme', + themeSchedulerNightStart: 'Nacht beginnt um', + themeSchedulerActiveHint: 'Theme-Zeitplan ist aktiv - Themes werden automatisch gewechselt.', + visualOptionsTitle: 'Visuelle Optionen', + coverArtBackground: 'Cover-Hintergrund', + coverArtBackgroundSub: 'Zeigt verschwommenes Cover als Hintergrund in Album/Playlist-Kopfzeilen', + playlistCoverPhoto: 'Playlist-Coverfoto', + playlistCoverPhotoSub: 'Zeigt Coverfoto-Raster in der Playlist-Detailansicht', + showBitrate: 'Bitrate anzeigen', + showBitrateSub: 'Audio-Bitrate in Track-Listen anzeigen', + uiScaleTitle: 'Interface-Skalierung', + uiScaleLabel: 'Zoom', + }, + changelog: { + modalTitle: 'Was ist neu', + dontShowAgain: 'Nicht mehr anzeigen', + close: 'Verstanden', + }, + help: { + title: 'Hilfe', + s1: 'Erste Schritte', + q1: 'Welche Server sind kompatibel?', + a1: 'Psysonic funktioniert mit jedem Subsonic-kompatiblen Server: Navidrome, Gonic, Subsonic, Airsonic und anderen. Navidrome ist die empfohlene Wahl.', + q2: 'Wie verbinde ich mich mit meinem Server?', + a2: 'Öffne die Einstellungen und klicke auf "Server hinzufügen". Gib die Server-URL (z. B. 192.168.1.100:4533), Benutzername und Passwort ein. Psysonic testet die Verbindung vor dem Speichern — bei Fehler wird nichts gespeichert.', + q3: 'Kann ich mehrere Server verwenden?', + a3: 'Ja. Du kannst beliebig viele Server in den Einstellungen hinzufügen und jederzeit zwischen ihnen wechseln. Immer ist nur ein Server aktiv.', + s2: 'Wiedergabe', + q4: 'Wie spiele ich Musik ab?', + a4: 'Doppelklick auf einen Track startet die Wiedergabe. Auf Album- und Künstlerseiten gibt es "Alle abspielen". Tracks lassen sich auch per Drag & Drop in die Warteschlange ziehen.', + q5: 'Welche Tastenkürzel gibt es?', + a5: 'Leertaste = Play / Pause · Escape = Vollbild schließen. Medientasten (Play/Pause, Weiter, Zurück) funktionieren auf allen Plattformen. Unter Linux bitte die Buttons in der Playerleiste nutzen. In-App-Kürzel und systemweite globale Shortcuts können in Einstellungen → Tastenkürzel / Globale Shortcuts angepasst werden.', + q6: 'Was ist die Warteschlange?', + a6: 'Die Warteschlange zeigt alle kommenden Tracks. Öffnen mit dem Panel-Icon oben rechts im Header (neben dem Now-Playing-Indikator). Tracks per Drag & Drop umsortieren, mit dem Shuffle-Button mischen oder als Playlist speichern.', + q7: 'Wie öffne ich den Vollbild-Player?', + a7: 'Klick auf das Album-Cover unten in der Playerleiste oder auf das Expand-Icon daneben. Mit Escape wieder schließen.', + q8: 'Wie funktioniert die Wiederholfunktion?', + a8: 'Klick auf den Wiederhol-Button in der Playerleiste, um zwischen den Modi zu wechseln: Aus → Alles wiederholen → Einen wiederholen.', + s3: 'Bibliothek', + q9: 'Wie lade ich ein Album herunter?', + a9: 'Auf der Album-Detailseite auf "Download (ZIP)" klicken. Der Server packt das Album zunächst in eine ZIP-Datei — bei großen Alben oder verlustfreien Dateien (FLAC / WAV) kann es einen Moment dauern, bevor der Download tatsächlich startet. Das ist normal: Der Fortschrittsbalken erscheint erst, wenn der Server fertig ist und die Übertragung beginnt.', + q10: 'Wie markiere ich Tracks und Alben als Favoriten?', + a10: 'Das Stern-Icon auf einem Track oder im Album-Header anklicken. Markierte Einträge erscheinen im Bereich "Favoriten" in der Seitenleiste.', + q11: 'Was ist das Karussell auf der Startseite?', + a11: 'Das Banner oben auf der Startseite wählt zufällige Alben aus der Bibliothek und rotiert alle 10 Sekunden weiter. Mit den Punkten kann man manuell springen, Klick auf das Banner öffnet das Album.', + s4: 'Einstellungen', + q12: 'Wie ändere ich das Theme?', + a12: 'Einstellungen → Design. Eine große Auswahl an Themes in 8 Gruppen: Psysonic Themes, Mediaplayer, Betriebssysteme, Spiele, Filme, Serien, Social Media und Open-Source-Classics (Catppuccin, Nord, Gruvbox, Nightfox).', + q13: 'Wie ändere ich die Sprache?', + a13: 'Einstellungen → Sprache. Englisch, Deutsch, Französisch, Niederländisch und Chinesisch werden unterstützt.', + q15: 'Wie lege ich einen Download-Ordner fest?', + a15: 'Einstellungen → App-Verhalten → Download-Ordner. Beliebigen Ordner wählen — heruntergeladene Alben werden dort als ZIP gespeichert. Ohne eigenen Ordner landet alles im Standard-Downloads-Ordner.', + s5: 'Scrobbling', + q16: 'Wie funktioniert Scrobbling?', + a16: 'Psysonic scrobbled direkt zu Last.fm — keine Navidrome-Konfiguration nötig. Last.fm-Konto in Einstellungen → Last.fm verbinden und Scrobbling dort aktivieren.', + q17: 'Wann wird ein Scrobble gesendet?', + a17: 'Ein Scrobble wird übermittelt, wenn 50 % eines Tracks gehört wurden.', + q22: 'Was ist die Waveform in der Playerleiste?', + a22: 'Die Waveform-Leiste ersetzt den klassischen Fortschrittsbalken. Klick auf eine beliebige Stelle zum Springen, ziehen zum Scrubben. Der gespielte Teil leuchtet in einem Blau-Mauve-Farbverlauf, der gepufferte Bereich erscheint etwas heller, der ungespielter Teil ist abgeblendet.', + q24: 'Kann ich die Warteschlange mischen?', + a24: 'Ja. Die Warteschlange öffnen und auf das Shuffle-Icon im Header klicken. Der aktuell laufende Track bleibt an Position 1 — alle restlichen Tracks werden zufällig neu geordnet.', + q25: 'Öffnen Last.fm- und Wikipedia-Links auf Künstlerseiten im Browser?', + a25: 'Ja — sie öffnen sich im Standard-Systembrowser. Der Button zeigt kurz eine Bestätigungsmeldung beim Klick.', + s7: 'Zufallsmix', + q26: 'Was ist der Zufallsmix?', + a26: 'Der Zufallsmix erstellt eine Playlist aus zufälligen Tracks deiner gesamten Bibliothek. Über "Zufallsmix" in der Seitenleiste erreichbar, dann "Neuer Mix" klicken. Die Anzahl der Tracks ist vor der Generierung einstellbar.', + q27: 'Was ist der Keyword-Filter?', + a27: 'Der Keyword-Filter schließt Tracks aus, deren Genre, Titel oder Album bestimmte Wörter enthält. Hörbücher werden automatisch gefiltert. Eigene Keywords in Einstellungen → Zufallsmix hinzufügen oder per Klick auf ein Genre-Tag direkt in der Trackliste.', + q28: 'Was ist der Super-Genre-Mix?', + a28: 'Der Super-Genre-Mix fasst die Bibliothek in übergeordnete Kategorien zusammen (Rock, Metal, Electronic, Jazz, Klassik usw.) und erstellt daraus einen fokussierten Mix. Einen Kategorie-Chip unterhalb der Trackliste auswählen. Ergebnisse erscheinen schrittweise, während die einzelnen Sub-Genres geladen werden.', + s6: 'Problemlösung', + q18: 'Cover und Künstlerbilder laden langsam.', + a18: 'Bilder werden beim ersten Aufruf vom Server geholt und dann 30 Tage lokal gecacht. Bei langsamen Server-Festplatten kann der erste Seitenaufruf einen Moment dauern. Danach geht alles sofort.', + q19: 'Der Verbindungstest schlägt fehl.', + a19: 'URL inklusive Port prüfen (z. B. http://192.168.1.100:4533). Sicherstellen, dass keine Firewall die Verbindung blockiert. Im lokalen Netzwerk http:// statt https:// versuchen. Benutzername und Passwort kontrollieren.', + q20: 'Kein Ton unter Linux.', + a20: 'Psysonic ist als .deb (Ubuntu/Debian), .rpm (Fedora/RHEL) und über AUR für Arch/CachyOS verfügbar (yay -S psysonic). Es gibt kein AppImage. Falls kein Ton kommt, sicherstellen, dass PipeWire oder PulseAudio läuft.', + q21: 'Die App zeigt einen schwarzen Bildschirm unter Linux.', + a21: 'Meist ein GPU/EGL-Treiberproblem in WebKitGTK. Mit GDK_BACKEND=x11 WEBKIT_DISABLE_COMPOSITING_MODE=1 WEBKIT_DISABLE_DMABUF_RENDERER=1 starten. Das AUR-Paket und die offiziellen .deb/.rpm-Pakete setzen diese Variablen automatisch.', + q29: 'Was sind Crossfade und nahtlose Wiedergabe?', + a29: 'Beides sind experimentelle Audiofunktionen in Einstellungen → Audio. Nahtlose Wiedergabe puffert den nächsten Track vor, um Stille zu eliminieren. Crossfade blendet den aktuellen Track aus, während der nächste eingeblendet wird — Dauer (1–10 s) einstellbar.', + q30: 'Zeigt Psysonic Songtexte an?', + a30: 'Ja. Klick auf das Mikrofon-Icon in der Playerleiste öffnet den Lyrics-Tab im Queue-Panel. Psysonic lädt Texte automatisch von LRCLIB. Sind synchronisierte Lyrics verfügbar, wird die aktuelle Zeile hervorgehoben und scrollt in Echtzeit mit. Bei reinen Texten wird der Volltext statisch angezeigt.', + q31: 'Kann ich Tastenkürzel anpassen?', + a31: 'Ja. Einstellungen → Tastenkürzel erlaubt das Neuzuordnen von In-App-Aktionen (Play/Pause, Weiter, Zurück, Lautstärke, Vollbild u. v. m.). Einstellungen → Globale Shortcuts ermöglicht systemweite Kürzel, die auch im Hintergrund ausgelöst werden.', + q32: 'Kann ich die Schriftart ändern?', + a32: 'Ja. Einstellungen → Schriftart bietet 10 Schriften zur Auswahl, darunter IBM Plex Mono, Fira Code, JetBrains Mono und Courier Prime. Die gewählte Schrift gilt für die gesamte Oberfläche.', + s8: 'Offline-Modus', + q34: 'Was ist der Offline-Modus?', + a34: 'Der Offline-Modus (Beta) ermöglicht das Zwischenspeichern von Alben auf dem Gerät, sodass die Wiedergabe ohne aktive Serververbindung möglich ist. Gecachte Tracks werden lokal gespeichert und direkt von der Festplatte abgespielt — ohne Netzwerkzugriff.', + q35: 'Wie speichere ich ein Album für die Offline-Nutzung?', + a35: 'Album öffnen und auf das Download-Symbol im Album-Header klicken. Psysonic lädt alle Tracks im Hintergrund herunter. Der Fortschritt wird am Button angezeigt. Nach dem Download wird das Symbol grün. Gecachte Alben können in der Offline-Bibliothek (Seitenleiste) verwaltet und gelöscht werden.', + q36: 'Wie viel Speicherplatz darf der Cache belegen?', + a36: 'In Einstellungen → Bibliothek kann eine maximale Cache-Größe festgelegt werden. Wird das Limit erreicht, erscheint ein Warnbanner auf der Albumseite. Einzelne Alben können in der Offline-Bibliothek gelöscht werden, um Speicherplatz freizugeben.', + q37: 'Wie bewerte ich Songs, Alben und Künstler?', + a37: 'Psysonic unterstützt 1–5-Sterne-Bewertungen über die OpenSubsonic-API (erfordert Navidrome ≥ 0.53). Songs können in der Trackliste eines Albums oder einer Playlist (Spalte „Bewertung"), über das Rechtsklick-Kontextmenü oder direkt in der Playerleiste unterhalb des Künstlernamens bewertet werden. Alben werden auf der Albumdetailseite bewertet, Künstler auf der Künstlerseite. Bewertungen werden sofort an den Server übertragen.', + q38: 'Kann ich eine Bewertung entfernen oder ändern?', + a38: 'Ja. Ein erneuter Klick auf den bereits aktiven Stern entfernt die Bewertung vollständig – der zweite Klick auf denselben Stern löscht sie also. Um eine Bewertung zu ändern, einfach einen anderen Stern anklicken.', + q39: 'Was ist Skip-to-1★ und der Bewertungsfilter?', + a39: 'Skip-to-1★ vergibt automatisch eine 1-Stern-Bewertung, wenn ein Song mehrfach hintereinander manuell übersprungen wird. Aktivierung und Schwellenwert in Einstellungen → Bewertungen. Dort lässt sich auch eine Mindestbewertung für Zufalls-Mix und Zufallsalben festlegen – so werden nur Songs, Alben oder Künstler ab einer bestimmten Sternzahl in generierten Mixes berücksichtigt.', + q40: 'Was ist der Ordner-Browser?', + a40: 'Der Ordner-Browser (Sidebar) ermöglicht die Navigation im Musikverzeichnis des Servers über ein Miller-Column-Layout. Ein Klick auf einen Ordner öffnet dessen Inhalt; über das Play-Symbol lassen sich Ordner direkt abspielen oder zur Warteschlange hinzufügen.', + q41: 'Was ist der Theme-Scheduler?', + a41: 'Einstellungen → Darstellung → Theme automatisch wechseln: Tagesthema und Nachtthema mit Startzeiten konfigurieren. Psysonic wechselt automatisch zur eingestellten Uhrzeit. Ist der Scheduler aktiv, erscheint im Theme-Picker ein Hinweis, warum manuelle Änderungen keine sofortige Wirkung haben.', + q42: 'Kann ich die Benutzeroberfläche vergrößern oder verkleinern?', + a42: 'Ja. Einstellungen → Darstellung → Anzeigeskalierung ermöglicht eine Skalierung der gesamten Oberfläche zwischen 80 % und 125 %, unabhängig von der Systemschriftgröße.', + q43: 'Kann ich den Stil der Seekbar ändern?', + a43: 'Ja. Einstellungen → Darstellung → Seekbar-Stil bietet 10 Stile: Wellenform, Linie & Punkt, Balken, Dicker Balken, Segmentiert, Neon-Glow, Pulswelle, Partikelspur, Flüssigfüllung und Retro-Tape.', + q44: 'Was ist AutoEQ?', + a44: 'Der 10-Band-EQ in Einstellungen → Audio enthält eine AutoEQ-Suche. Kopfhörermodell eingeben – Psysonic lädt das Korrekturprofil aus der AutoEQ-Datenbank und überträgt es automatisch auf die EQ-Bänder.', + q45: 'Was ist Replay Gain?', + a45: 'Replay Gain normalisiert die Lautstärke, sodass laute und leise Alben auf einem gleichmäßigen Pegel wiedergegeben werden. Aktivierung in Einstellungen → Audio → Replay Gain; Modus Track (pro Song) oder Album (behält die relative Dynamik innerhalb eines Albums).', + q46: 'Was ist der Hot Cache?', + a46: 'Der Hot Cache (Alpha, Einstellungen → Bibliothek) lädt die nächsten Songs der Warteschlange vorab auf die Festplatte, damit die Wiedergabe ohne Pufferverzögerung startet – besonders nützlich bei langsamen oder entfernten Servern. Psysonic hält den aktuellen Track und die nächsten 5 im Cache und verdrängt ältere Einträge, wenn das Größenlimit erreicht wird. Cache-Größe und Debounce-Verzögerung sind konfigurierbar.', + q47: 'Kann ich eine Playlist offline cachen?', + a47: 'Ja. In den Playlist-Details auf das Download-Symbol klicken – alle Tracks werden im Hintergrund heruntergeladen. Ist die Playlist vollständig gecacht, wechselt das Symbol zu einem roten Papierkorb; ein erneuter Klick entfernt die Playlist aus dem Offline-Cache.', - q48: 'Was ist die Infinite Queue?', - a48: 'Wenn die Warteschlange leer läuft und Wiederholen deaktiviert ist, fügt Psysonic automatisch zufällige Tracks aus deiner Bibliothek hinzu, damit die Wiedergabe nie stoppt. Automatisch hinzugefügte Tracks erscheinen unterhalb des Trenners „— Automatisch hinzugefügt —". Umschalten über das Unendlichkeitssymbol im Warteschlangen-Header. In Einstellungen → Warteschlange kann der automatische Nachschub auf ein bestimmtes Genre beschränkt werden.', - q49: 'Kann ich Psysonic über die Kommandozeile bedienen?', - a49: 'Ja – das Psysonic-Binary kann die laufende App fernsteuern. Beispiele: psysonic --player play / pause / next / prev, --player volume 75, --player seek 15, --player mute, --player shuffle, --player repeat off|all|one, --player star / unstar, --player rating 1–5. Außerdem: Server wechseln (--player server list / set), Ausgabegerät wählen (--player audio-device list / set), Bibliotheks-Ordner filtern (--player library list / set), Instant Mix starten (--player mix new / append) und Suche (--player search track|album|artist ). Vollständige Hilfe: psysonic --player --help. Shell-Completions für bash und zsh sind über psysonic completions verfügbar.', - q50: 'Wie verwalte ich Playlists?', - a50: 'Über „Playlists" in der Seitenleiste. Mit „Neue Playlist" eine Playlist erstellen. In der Playlist-Detailansicht können Tracks per Drag & Drop umsortiert, mit dem ×-Button entfernt und über die Songsuche neue hinzugefügt werden. Die „Vorschläge"-Sektion macht Empfehlungen basierend auf dem Inhalt der Playlist. Rechtsklick auf einen Track für weitere Optionen.', - q51: 'Kann ich meine Einstellungen sichern und wiederherstellen?', - a51: 'Ja. Einstellungen → Backup & Restore ermöglicht den Export aller Einstellungen, Serverprofile, Themes und Tastenkürzel in eine JSON-Datei. Auf einem anderen Gerät oder nach einer Neuinstallation importieren, um alles auf einmal wiederherzustellen. Passwörter sind in der Sicherung enthalten – die Datei sicher aufbewahren.', - q52: 'Wie ändere ich das Audioausgabegerät?', - a52: 'Einstellungen → Audio → Ausgabegerät. Psysonic listet alle verfügbaren Ausgaben auf. Auswahl wechselt die Wiedergabe sofort. Den Aktualisierungsbutton daneben nutzen, wenn ein Gerät nach dem App-Start angeschlossen wurde. Unter Linux werden ALSA-Gerätenamen bereinigt angezeigt.', - q53: 'Was ist Device Sync?', - a53: 'Device Sync überträgt Alben, Playlists oder ganze Künstler auf einen USB-Stick oder eine SD-Karte. Über „Device Sync" in der Seitenleiste öffnen, einen Zielordner auf dem Laufwerk wählen, Quellen in den Browser-Tabs auswählen und auf „Auf Gerät übertragen" klicken. Psysonic lädt die Tracks vom Server und legt sie in der durch die Dateinamen-Vorlage definierten Ordnerstruktur ab.', - q54: 'Was ist die Dateinamen-Vorlage in Device Sync?', - a54: 'Die Dateinamen-Vorlage steuert, wie Tracks auf dem Gerät benannt und organisiert werden. Vorgaben (Standard, Multi-Disc, Alt. Ordner) auswählen oder selbst aus den klickbaren Token-Chips zusammenbauen: {artist}, {album}, {title}, {track_number}, {disc_number}, {year} und / als Ordner-Trennzeichen. Eine Live-Vorschau zeigt, wie ein Beispiel-Track benannt würde.', - q55: 'Funktioniert Device Sync plattformübergreifend?', - a55: 'Ja. Das auf dem Gerät gespeicherte Manifest (psysonic-sync.json) enthält die beim Sync verwendete Dateinamen-Vorlage. Wird Device Sync auf einem anderen Betriebssystem mit anderer Vorlage geöffnet, erkennt Psysonic die bereits vorhandenen Dateien korrekt – Alben werden nicht fälschlich als ausstehend angezeigt.', - s9: 'Device Sync', - q56: 'Was ist Internet Radio?', - a56: 'Die Internetradio-Seite (Seitenleiste) ermöglicht die Wiedergabe beliebiger Livestreams direkt in Psysonic. Sender werden vom Navidrome-Server bezogen – dort über das Admin-Panel hinzufügen oder eine .pls- / .m3u-Datei importieren. Die Wiedergabe erfolgt über HTML5-Audio, nicht den Rust-Audio-Engine – einige EQ- und Replay-Gain-Einstellungen gelten daher nicht für Radio.', - q57: 'Welche Stream-Formate unterstützt Internet Radio?', - a57: 'Psysonic unterstützt alle Formate, die der Audio-Stack des Systems dekodieren kann: MP3, AAC, OGG Vorbis und die meisten HLS-Streams. Da HTML5-Audio verwendet wird, hängt die Codec-Unterstützung von der Plattform ab – MP3 und AAC funktionieren überall.', - s10: 'Internet Radio', - q58: 'Woher bezieht Psysonic Songtexte?', - a58: 'Psysonic unterstützt drei Lyrics-Quellen, alle konfigurierbar in Einstellungen → Lyrics: Navidrome-Server (eingebettete/OpenSubsonic-Lyrics), LRCLIB (community-gepflegte synchronisierte Texte) und NetEase Cloud Music (umfangreicher internationaler Katalog). Jede Quelle kann aktiviert/deaktiviert und per Drag & Drop priorisiert werden. Synchronisierte Lyrics scrollen automatisch und unterstützen Klick-zum-Springen.', - q59: 'Gibt es eine Ansicht, was andere Nutzer gerade hören?', - a59: 'Ja. Das Broadcast-Symbol oben rechts im Header öffnet das „Now Playing"-Dropdown. Es zeigt, was andere Nutzer auf dem Navidrome-Server gerade hören – aktualisiert alle 10 Sekunden. Der eigene Eintrag verschwindet beim Pausieren.', + }, + queue: { + title: 'Warteschlange', + savePlaylist: 'Playlist speichern', + updatePlaylist: 'Playlist aktualisieren', + filterPlaylists: 'Playlists filtern…', + playlistName: 'Name der Playlist', + cancel: 'Abbrechen', + save: 'Speichern', + loadPlaylist: 'Playlist laden', + loading: 'Lade…', + noPlaylists: 'Keine Playlists gefunden.', + load: 'Warteschlange ersetzen & abspielen', + appendToQueue: 'An Warteschlange anhängen', + delete: 'Löschen', + deleteConfirm: 'Playlist "{{name}}" löschen?', + clear: 'Leeren', + shuffle: 'Warteschlange mischen', + gapless: 'Nahtlos', + crossfade: 'Crossfade', + infiniteQueue: 'Endlose Warteschlange', + autoAdded: '— Automatisch hinzugefügt —', + radioAdded: '— Radio —', + hide: 'Verbergen', + close: 'Schließen', + nextTracks: 'Nächste Titel', + emptyQueue: 'Die Warteschlange ist leer.', + trackSingular: 'Titel', + trackPlural: 'Titel', + showRemaining: 'Restzeit anzeigen', + showTotal: 'Gesamtzeit anzeigen', + }, + statistics: { + title: 'Statistiken', + recentlyPlayed: 'Zuletzt gehört', + mostPlayed: 'Meistgespielte Alben', + highestRated: 'Höchstbewertete Alben', + genreDistribution: 'Genre-Verteilung (Top 20)', + loadMore: 'Mehr laden', + statArtists: 'Künstler', + statArtistsTooltip: 'Nur Album-Künstler — Künstler, die ausschließlich als Track-Künstler vorkommen (Featured, Gast usw.) und kein eigenes Album haben, werden nicht gezählt.', + statAlbums: 'Alben', + statSongs: 'Songs', + statGenres: 'Genres', + statPlaytime: 'Gesamtspielzeit', + genreInsights: 'Genre-Einblicke', + formatDistribution: 'Format-Verteilung', + formatSample: 'Stichprobe von {{n}} Titeln', + computing: 'Wird berechnet…', + genreSongs: '{{count}} Songs', + genreAlbums: '{{count}} Alben', + recentlyAdded: 'Neu hinzugefügt', + decadeDistribution: 'Alben nach Jahrzehnt', + decadeAlbums_one: '{{count}} Album', + decadeAlbums_other: '{{count}} Alben', + decadeUnknown: 'Unbekannt', + lfmTitle: 'Last.fm Statistiken', + lfmTopArtists: 'Top-Künstler', + lfmTopAlbums: 'Top-Alben', + lfmTopTracks: 'Top-Titel', + lfmPlays: '{{count}} Plays', + lfmPeriodOverall: 'Gesamt', + lfmPeriod7day: '7 Tage', + lfmPeriod1month: '1 Monat', + lfmPeriod3month: '3 Monate', + lfmPeriod6month: '6 Monate', + lfmPeriod12month: '12 Monate', + lfmNotConnected: 'Verbinde Last.fm in den Einstellungen, um deine Statistiken zu sehen.', + lfmRecentTracks: 'Zuletzt gescrobbelt', + lfmNowPlaying: 'Läuft gerade', + lfmJustNow: 'gerade eben', + lfmMinutesAgo: 'vor {{n}} Min.', + lfmHoursAgo: 'vor {{n}} Std.', + lfmDaysAgo: 'vor {{n}} Tagen', + topRatedSongs: 'Bestbewertete Songs', + topRatedArtists: 'Bestbewertete Künstler', + noRatedSongs: 'Noch keine bewerteten Songs. Songs in Album- oder Playlist-Ansicht bewerten.', + noRatedArtists: 'Noch keine bewerteten Künstler.', + }, + player: { + regionLabel: 'Musikplayer', + openFullscreen: 'Vollbild-Player öffnen', + fullscreen: 'Vollbild-Player', + closeFullscreen: 'Vollbild schließen', + closeTooltip: 'Schließen (Esc)', + noTitle: 'Kein Titel', + stop: 'Stop', + prev: 'Vorheriger Titel', + play: 'Play', + pause: 'Pause', + next: 'Nächster Titel', + repeat: 'Wiederholen', + repeatOff: 'Aus', + repeatAll: 'Alle', + repeatOne: 'Einen', + progress: 'Songfortschritt', + volume: 'Lautstärke', + toggleQueue: 'Warteschlange umschalten', + lyrics: 'Lyrics', + fsLyricsToggle: 'Lyrics im Vollbild', + lyricsLoading: 'Lyrics werden geladen…', + lyricsNotFound: 'Keine Lyrics für diesen Titel gefunden', + lyricsSourceServer: 'Quelle: Server', + lyricsSourceLrclib: 'Quelle: LRCLIB', + lyricsSourceNetease: 'Quelle: Netease', + }, + songInfo: { + title: 'Song-Infos', + songTitle: 'Titel', + artist: 'Künstler', + album: 'Album', + albumArtist: 'Album-Künstler', + year: 'Jahr', + genre: 'Genre', + duration: 'Länge', + track: 'Track', + format: 'Format', + bitrate: 'Bitrate', + sampleRate: 'Abtastrate', + bitDepth: 'Bittiefe', + channels: 'Kanäle', + fileSize: 'Dateigröße', + path: 'Speicherort', + replayGainTrack: 'RG Track Gain', + replayGainAlbum: 'RG Album Gain', + replayGainPeak: 'RG Track Peak', + mono: 'Mono', + stereo: 'Stereo', + }, + playlists: { + title: 'Playlists', + newPlaylist: 'Neue Playlist', + unnamed: 'Unbenannte Playlist', + createName: 'Playlist-Name…', + create: 'Erstellen', + cancel: 'Abbrechen', + empty: 'Noch keine Playlists.', + emptyPlaylist: 'Diese Playlist ist leer.', + addFirstSong: 'Ersten Song hinzufügen', + notFound: 'Playlist nicht gefunden.', + songs: '{{n}} Songs', + playAll: 'Alle abspielen', + shuffle: 'Zufallswiedergabe', + addToQueue: 'Zur Warteschlange', + back: 'Zurück zu Playlists', + deletePlaylist: 'Löschen', + confirmDelete: 'Nochmals klicken zum Bestätigen', + removeSong: 'Aus Playlist entfernen', + addSongs: 'Songs hinzufügen', + searchPlaceholder: 'Bibliothek durchsuchen…', + noResults: 'Keine Ergebnisse.', + suggestions: 'Vorgeschlagene Songs', + noSuggestions: 'Keine Vorschläge verfügbar.', + titleBadge: 'Playlist', + refreshSuggestions: 'Neue Vorschläge', + addSong: 'Zur Playlist hinzufügen', + addSelected: 'Ausgewählte hinzufügen', + cacheOffline: 'Playlist offline speichern', + offlineCached: 'Playlist gecacht', + removeOffline: 'Aus Offline-Cache entfernen', + offlineDownloading: 'Wird gecacht… ({{done}}/{{total}} Alben)', + publicLabel: 'Öffentlich', + privateLabel: 'Privat', + editMeta: 'Playlist bearbeiten', + editNamePlaceholder: 'Playlist-Name…', + editCommentPlaceholder: 'Beschreibung hinzufügen…', + editPublic: 'Öffentliche Playlist', + editSave: 'Speichern', + editCancel: 'Abbrechen', + changeCover: 'Coverbild ändern', + changeCoverLabel: 'Foto ändern', + removeCover: 'Foto entfernen', + coverUpdated: 'Cover aktualisiert', + metaSaved: 'Playlist aktualisiert', + downloadZip: 'Herunterladen (ZIP)', + // Toast notifications for multi-select + addSuccess: '{{count}} Songs zu {{playlist}} hinzugefügt', + addPartial: '{{added}} hinzugefügt, {{skipped}} übersprungen (Duplikate)', + addAllSkipped: 'Alle übersprungen ({{count}} Duplikate)', + addError: 'Fehler beim Hinzufügen von Songs', + createAndAddSuccess: 'Playlist "{{playlist}}" mit {{count}} Songs erstellt', + createError: 'Fehler beim Erstellen der Playlist', + deleteSuccess: '{{count}} Playlists gelöscht', + deleteFailed: 'Fehler beim Löschen von {{name}}', + deleteSelected: 'Ausgewählte löschen', + mergeSuccess: '{{count}} Songs in {{playlist}} zusammengeführt', + mergeNoNewSongs: 'Keine neuen Songs zum Hinzufügen', + mergeError: 'Fehler beim Zusammenführen von Playlists', + mergeInto: 'Zusammenführen in', + selectionCount: '{{count}} ausgewählt', + select: 'Auswählen', + startSelect: 'Auswahl aktivieren', + cancelSelect: 'Abbrechen', + loadingAlbums: '{{count}} Alben werden aufgelöst…', + loadingArtists: '{{count}} Künstler werden aufgelöst…', + myPlaylists: 'Meine Playlists', + noOtherPlaylists: 'Keine anderen Playlists verfügbar', + addToPlaylistSuccess: '{{count}} Songs zu {{playlist}} hinzugefügt', + addToPlaylistNoNew: 'Keine neuen Songs für {{playlist}}', + addToPlaylistError: 'Fehler beim Hinzufügen zur Playlist', + removeSuccess: 'Song aus Playlist entfernt', + removeError: 'Fehler beim Entfernen aus der Playlist', + importCSV: 'CSV importieren', + importCSVTooltip: 'Aus Spotify-CSV importieren', + csvImportReport: 'CSV-Importbericht', + csvImportTotal: 'Gesamt', + csvImportAdded: 'Hinzugefügt', + csvImportDuplicates: 'Duplikate', + csvImportNotFound: 'Nicht gefunden', + csvImportNetworkErrors: 'Netzwerkfehler', + csvImportDuplicatesTitle: 'Doppelte Titel (bereits in Playlist):', + csvImportNotFoundTitle: 'Nicht gefundene Titel:', + csvImportNetworkErrorsTitle: 'Netzwerkfehler (Import kann wiederholt werden):', + csvImportDownloadReport: 'Bericht herunterladen', + csvImportClose: 'Schließen', + csvImportNoValidTracks: 'Keine gültigen Titel in CSV-Datei gefunden', + csvImportFailed: 'CSV-Import fehlgeschlagen', + csvImportToast: '{{added}} hinzugefügt, {{notFound}} nicht gefunden, {{duplicates}} Duplikate', + }, + mostPlayed: { + title: 'Meistgehört', + topArtists: 'Top-Künstler', + topAlbums: 'Top-Alben', + plays: '{{n}}× gespielt', + sortMost: 'Meiste Plays zuerst', + sortLeast: 'Wenigste Plays zuerst', + loadMore: 'Mehr Alben laden', + noData: 'Noch keine Wiedergabedaten. Fang an zu hören!', + noArtists: 'Alle Künstler herausgefiltert.', + filterCompilations: 'Sampler-Künstler ausblenden (Various Artists, Soundtracks usw.)', + filterCompilationsShort: 'Sampler ausblenden', + }, + radio: { + title: 'Internetradio', + empty: 'Keine Radiosender konfiguriert.', + addStation: 'Sender hinzufügen', + editStation: 'Bearbeiten', + deleteStation: 'Sender löschen', + confirmDelete: 'Zum Bestätigen erneut klicken', + stationName: 'Sendername…', + streamUrl: 'Stream-URL…', + homepageUrl: 'Homepage-URL (optional)', + save: 'Speichern', + cancel: 'Abbrechen', + live: 'LIVE', + liveStream: 'Internetradio', + openHomepage: 'Homepage öffnen', + changeCoverLabel: 'Cover ändern', + removeCover: 'Cover entfernen', + browseDirectory: 'Verzeichnis durchsuchen', + directoryPlaceholder: 'Sender suchen…', + noResults: 'Keine Sender gefunden.', + stationAdded: 'Sender hinzugefügt', + filterAll: 'Alle', + filterFavorites: 'Favoriten', + sortManual: 'Manuell', + sortAZ: 'A → Z', + sortZA: 'Z → A', + sortNewest: 'Neueste', + favorite: 'Zu Favoriten hinzufügen', + unfavorite: 'Aus Favoriten entfernen', + noFavorites: 'Keine Lieblingssender.', + listenerCount_one: '{{count}} Hörer', + listenerCount_other: '{{count}} Hörer', + recentlyPlayed: 'Zuletzt gespielt', + upNext: 'Als Nächstes', + }, + folderBrowser: { + empty: 'Leerer Ordner', + error: 'Laden fehlgeschlagen', + }, + deviceSync: { + title: 'Gerätesync', + targetFolder: 'Zielordner', + noFolderChosen: 'Kein Ordner gewählt', + selectDrive: 'Laufwerk auswählen…', + refreshDrives: 'Laufwerke aktualisieren', + noDrivesDetected: 'Keine Wechseldatenträger erkannt', + browseManual: 'Manuell durchsuchen…', + free: 'frei', + notMountedVolume: 'Ziel befindet sich nicht auf einem eingehängten Laufwerk. Das Gerät wurde möglicherweise getrennt.', + chooseFolder: 'Auswählen…', + filenameTemplate: 'Dateinamen-Vorlage', + targetDevice: 'Zielgerät', + templateHint: 'Variablen: {artist}, {album}, {title}, {track_number}, {disc_number}, {year}', + onDevice: 'Auf dem Gerät', + addSources: 'Hinzufügen…', + colName: 'Name', + colType: 'Typ', + syncResult: '{{done}} übertragen, {{skipped}} bereits aktuell ({{total}} gesamt)', + deleteFromDevice: 'Vom Gerät löschen ({{count}})', + confirmDelete: '{{count}} Eintrag/Einträge vom Gerät löschen: {{names}}?', + deleteComplete: '{{count}} Eintrag/Einträge vom Gerät entfernt.', - manifestImported: '{{count}} Quelle(n) aus Geräte-Manifest importiert.', + selectedSources: 'Ausgewählte Quellen', + noSourcesSelected: 'Keine Quellen ausgewählt. Klicke auf Einträge im Browser um sie hinzuzufügen.', + clearAll: 'Alle entfernen', + tabPlaylists: 'Wiedergabelisten', + tabAlbums: 'Alben', + tabArtists: 'Künstler', + searchPlaceholder: 'Suche…', + syncButton: 'Auf Gerät übertragen', + actionTransfer: 'Auf Gerät übertragen', + actionDelete: 'Vom Gerät löschen', + actionApplyAll: 'Änderungen synchronisieren', + templatePreview: 'Vorschau', - templatePresetStandard: 'Standard', - templatePresetMultiDisc: 'Multi-Disc', - templatePresetAltFolder: 'Alt. Ordner', - tokenSlashHint: '/ = Ordner-Trennzeichen', + cancel: 'Abbrechen', + noTargetDir: 'Bitte zuerst einen Zielordner auswählen.', + noSources: 'Bitte mindestens eine Quelle auswählen.', + noTracks: 'Keine Tracks in den ausgewählten Quellen gefunden.', + fetchError: 'Fehler beim Laden der Tracks vom Server.', + syncComplete: 'Übertragung abgeschlossen.', + dismiss: 'Schließen', - cancelSync: 'Abbrechen', - syncCancelled: 'Sync abgebrochen ({{done}} / {{total}} übertragen).', + colStatus: 'Status', + statusSynced: 'Synchronisiert', + statusPending: 'Ausstehend', + statusDeletion: 'Löschung', + markForDeletion: 'Zur Löschung markieren', + removeSource: 'Entfernen', + undoDeletion: 'Löschung rückgängig', + syncInBackground: 'Sync gestartet — du kannst die Seite verlassen.', + syncInProgress: '{{done}} / {{total}} Tracks…', + syncSummary: 'Sync-Zusammenfassung', + calculating: 'Payload wird berechnet…', + filesToAdd: 'Hinzuzufügende Dateien:', + filesToDelete: 'Zu löschende Dateien:', + netChange: 'Nettoänderung:', + availableSpace: 'Verfügbarer Speicher:', + spaceWarning: 'Warnung: Das Zielgerät hat nicht genug gemeldeten Speicherplatz.', + proceed: 'Sync durchführen', + notEnoughSpace: 'Nicht genug physischer Speicherplatz erkannt!', + liveSearch: 'Live', + randomAlbumsLabel: 'Zufallsalben', + }, + }; + diff --git a/src/locales/en.ts b/src/locales/en.ts index 9fc35ab8..ea00336a 100644 --- a/src/locales/en.ts +++ b/src/locales/en.ts @@ -1,1165 +1,2268 @@ export const enTranslation = { + sidebar: { + library: 'Library', + mainstage: 'Mainstage', + newReleases: 'New Releases', + allAlbums: 'All Albums', + randomAlbums: 'Random Albums', + randomPicker: 'Build a Mix', + artists: 'Artists', + randomMix: 'Random Mix', + favorites: 'Favorites', + nowPlaying: 'Now Playing', + system: 'System', + statistics: 'Statistics', + settings: 'Settings', + help: 'Help', + expand: 'Expand Sidebar', + collapse: 'Collapse Sidebar', + + downloadingTracks: 'Caching {{n}} tracks…', + syncingTracks: 'Syncing {{done}}/{{total}}…', + cancelDownload: 'Cancel download', + offlineLibrary: 'Offline Library', + genres: 'Genres', + playlists: 'Playlists', + mostPlayed: 'Most Played', + radio: 'Internet Radio', + folderBrowser: 'Folder Browser', + deviceSync: 'Device Sync', + libraryScope: 'Library scope', + allLibraries: 'All libraries', + expandPlaylists: 'Expand playlists', + collapsePlaylists: 'Collapse playlists', + }, + home: { + hero: 'Featured', + starred: 'Personal Favorites', + recent: 'Recently Added', + mostPlayed: 'Most Played', + recentlyPlayed: 'Recently Played', + discover: 'Discover', + loadMore: 'Load More', + discoverMore: 'Discover More', + discoverArtists: 'Discover Artists', + discoverArtistsMore: 'All Artists' + }, + hero: { + eyebrow: 'Featured Album', + playAlbum: 'Play Album', + enqueue: 'Enqueue', + enqueueTooltip: 'Add entire album to queue', + }, + search: { + placeholder: 'Search for artist, album or song…', + noResults: 'No results for "{{query}}"', + artists: 'Artists', + albums: 'Albums', + songs: 'Songs', + clearLabel: 'Clear search', + title: 'Search', + resultsFor: 'Results for "{{query}}"', + album: 'Album', + advanced: 'Advanced Search', + advancedSearchTerm: 'Search term', + advancedSearchPlaceholder: 'Title, album, artist…', + advancedGenre: 'Genre', + advancedAllGenres: 'All genres', + advancedYear: 'Year', + advancedYearFrom: 'from', + advancedYearTo: 'to', + advancedAll: 'All', + advancedSearch: 'Search', + advancedEmpty: 'Enter a search term or select a filter to begin.', + advancedNoResults: 'No results found.', + advancedGenreNote: 'Songs are randomly selected from this genre.', + recentSearches: 'Recent Searches', + browse: 'Browse', + emptyHint: 'What do you want to hear?', + genres: 'Genres', + }, + nowPlaying: { + tooltip: 'Who is listening?', + title: 'Who is listening?', + loading: 'Loading…', + nobody: 'Nobody is currently listening.', + minutesAgo: '{{n}}m ago', + nothingPlaying: 'Nothing playing yet. Start a track!', + aboutArtist: 'About the Artist', + fromAlbum: 'From this Album', + viewAlbum: 'View Album', + goToArtist: 'Go to Artist', + readMore: 'Read more', + showLess: 'Show less', + genreInfo: 'Genre', + trackInfo: 'Track Info', + }, + contextMenu: { + playNow: 'Play Now', + playNext: 'Play Next', + addToQueue: 'Add to Queue', + enqueueAlbum: 'Enqueue Album', + startRadio: 'Start Radio', + instantMix: 'Instant Mix', + instantMixFailed: 'Could not build Instant Mix — server or plugin error.', + cliMixNeedsTrack: 'Nothing is playing — start playback first, then run the mix command again.', + lfmLove: 'Love on Last.fm', + lfmUnlove: 'Unlove on Last.fm', + favorite: 'Favorite', + favoriteArtist: 'Favorite Artist', + favoriteAlbum: 'Favorite Album', + unfavorite: 'Remove from Favorites', + unfavoriteArtist: 'Remove Artist from Favorites', + unfavoriteAlbum: 'Remove Album from Favorites', + removeFromQueue: 'Remove from Queue', + removeFromPlaylist: 'Remove from Playlist', + openAlbum: 'Open Album', + goToArtist: 'Go to Artist', + download: 'Download (ZIP)', + addToPlaylist: 'Add to Playlist', + selectedPlaylists: '{{count}} playlists selected', + selectedAlbums: '{{count}} albums selected', + selectedArtists: '{{count}} artists selected', + songInfo: 'Song Info', + }, + albumDetail: { + back: 'Back', + playAll: 'Play All', + enqueue: 'Enqueue', + enqueueTooltip: 'Add entire album to queue', + artistBio: 'Artist Bio', + download: 'Download (ZIP)', + downloading: 'Loading…', + cacheOffline: 'Make available offline', + offlineCached: 'Available offline', + offlineDownloading: 'Caching… ({{n}}/{{total}})', + removeOffline: 'Remove offline cache', + offlineStorageFull: 'Offline storage full (limit: {{mb}} MB). Free up space by deleting an album from your Offline Library, or increase the limit in Settings.', + offlineStorageGoToLibrary: 'Offline Library', + offlineStorageGoToSettings: 'Settings', + favoriteAdd: 'Add to Favorites', + favoriteRemove: 'Remove from Favorites', + favorite: 'Favorite', + noBio: 'No biography available.', + moreByArtist: 'More by {{artist}}', + tracksCount: '{{n}} Tracks', + goToArtist: 'Go to {{artist}}', + moreLabelAlbums: 'More albums on {{label}}', + trackTitle: 'Title', + trackAlbum: 'Album', + trackArtist: 'Artist', + trackGenre: 'Genre', + trackFormat: 'Format', + trackFavorite: 'Favorite', + trackRating: 'Rating', + trackDuration: 'Duration', + trackTotal: 'Total', + columns: 'Columns', - resetColumns: 'Reset to defaults', + notFound: 'Album not found.', + bioModal: 'Artist Biography', + bioClose: 'Close', + ratingLabel: 'Rating', + enlargeCover: 'Enlarge', + filterSongs: 'Filter songs…', + sortNatural: 'Natural', + sortByTitle: 'A–Z (Title)', + sortByArtist: 'A–Z (Artist)', + sortByAlbum: 'A–Z (Album)', + }, + entityRating: { + albumShort: 'Album rating', + artistShort: 'Artist rating', + albumAriaLabel: 'Album rating', + artistAriaLabel: 'Artist rating', + saveFailed: 'Could not save rating.', + }, + artistDetail: { + back: 'Back', + albums: 'Albums', + album: 'Album', + playAll: 'Play All', + shuffle: 'Shuffle', + radio: 'Radio', + loading: 'Loading…', + noRadio: 'No similar tracks found for this artist.', + notFound: 'Artist not found.', + albumsBy: 'Albums by {{name}}', + topTracks: 'Top Tracks', + noAlbums: 'No albums found.', + trackTitle: 'Title', + trackAlbum: 'Album', + trackDuration: 'Duration', + favoriteAdd: 'Add to Favorites', + favoriteRemove: 'Remove from Favorites', + favorite: 'Favorite', + albumCount_one: '{{count}} Album', + albumCount_other: '{{count}} Albums', + openedInBrowser: 'Opened in browser', + featuredOn: 'Also Featured On', + similarArtists: 'Similar Artists', + cacheOffline: 'Save discography offline', + offlineCached: 'Discography cached', + offlineDownloading: 'Caching… ({{done}}/{{total}} albums)', + uploadImage: 'Upload artist image', + uploadImageError: 'Failed to upload image', + }, + favorites: { + title: 'Favorites', + empty: "You haven't saved any favorites yet.", + artists: 'Artists', + albums: 'Albums', + songs: 'Songs', + enqueueAll: 'Add all to queue', + playAll: 'Play all', + removeSong: 'Remove from favorites', + stations: 'Radio Stations', + showingFiltered: 'Showing {{filtered}} of {{total}} ({{artist}})', + showingCount: 'Showing {{filtered}} of {{total}}', + clearArtistFilter: 'Clear artist filter', + noFilterResults: 'No results with selected filters.', + allArtists: 'All Artists', + }, + randomLanding: { + title: 'Build a Mix', + mixByTracks: 'Mix by Tracks', + mixByTracksDesc: 'Random selection of tracks from your entire library', + mixByAlbums: 'Mix by Albums', + mixByAlbumsDesc: 'Random album picks for your next discovery', + }, + randomAlbums: { + title: 'Random Albums', + refresh: 'Refresh', + }, + genres: { + title: 'Genres', + genreCount: 'Genres', + albumCount_one: '{{count}} album', + albumCount_other: '{{count}} albums', + loading: 'Loading genres…', + empty: 'No genres found.', + albumsLoading: 'Loading albums…', + albumsEmpty: 'No albums found for this genre.', + loadMore: 'Load more', + back: 'Back', + }, + randomMix: { + title: 'Random Mix', + remix: 'Remix', + remixTooltip: 'Load new random songs', + remixGenre: 'Remix {{genre}}', + remixTooltipGenre: 'Load new {{genre}} songs', + playAll: 'Play All', + trackTitle: 'Title', + trackArtist: 'Artist', + trackAlbum: 'Album', + trackFavorite: 'Favorite', + trackDuration: 'Duration', + favoriteAdd: 'Add to Favorites', + favoriteRemove: 'Remove from Favorites', + play: 'Play', + trackGenre: 'Genre', + excludeAudiobooks: 'Exclude audiobooks & radio plays', + excludeAudiobooksDesc: 'Matches keywords against genre, title, album, and artist — e.g. Hörbuch, Audiobook, Spoken Word, …', + genreBlocked: 'Keyword blocked', + genreAddedToBlacklist: 'Added to filter list', + genreAlreadyBlocked: 'Already blocked', + artistBlocked: 'Artist blocked', + artistAddedToBlacklist: 'Artist added to filter list', + artistClickHint: 'Click to block this artist', + blacklistToggle: 'Keyword Filter', + genreMixTitle: 'Genre Mix', + genreMixDesc: 'Top 20 genres by song count — click to load a random mix', + genreMixAll: 'All Songs', + genreMixLoadMore: 'Load 10 more', + genreMixNoGenres: 'No genres found on server.', + shuffleGenres: 'Show different genres', + filterPanelTitle: 'Filters', + filterPanelDesc: 'Click a genre tag or artist name in the tracklist below to block it from future mixes.', + genreClickHint: 'Click a genre tag to add it\nas a filter keyword.\nMatches genre, title, album & artist.', + }, + albums: { + title: 'All Albums', + sortByName: 'A–Z (Album)', + sortByArtist: 'A–Z (Artist)', + sortNewest: 'Newest first', + sortRandom: 'Random', + yearFrom: 'From', + yearTo: 'To', + yearFilterClear: 'Clear year filter', + yearFilterLabel: 'Year', + select: 'Multi-select', + startSelect: 'Enable multi-select', + cancelSelect: 'Cancel', + selectionCount: '{{count}} selected', + downloadZips: 'Download ZIPs', + addOffline: 'Add Offline', + downloadingZip: 'Downloading {{current}}/{{total}}: {{name}}', + downloadZipDone: '{{count}} ZIP(s) downloaded', + downloadZipFailed: 'Failed to download {{name}}', + offlineQueuing: 'Queuing {{count}} album(s) for offline…', + offlineFailed: 'Failed to add {{name}} offline', + }, + artists: { + title: 'Artists', + search: 'Search…', + all: 'All', + gridView: 'Grid view', + listView: 'List view', + imagesOn: 'Artist images on — may increase network and system load', + imagesOff: 'Artist images off — showing initials only', + loadMore: 'Load more', + notFound: 'No artists found.', + albumCount_one: '{{count}} Album', + albumCount_other: '{{count}} Albums', + selectionCount: '{{count}} selected', + select: 'Multi-select', + startSelect: 'Enable multi-select', + cancelSelect: 'Cancel', + addToPlaylist: 'Add to Playlist', + }, + login: { + subtitle: 'Your Navidrome Desktop Player', + serverName: 'Server Name (optional)', + serverNamePlaceholder: 'My Navidrome', + serverUrl: 'Server URL', + serverUrlPlaceholder: '192.168.1.100:4533 or https://music.example.com', + username: 'Username', + usernamePlaceholder: 'admin', + password: 'Password', + showPassword: 'Show password', + hidePassword: 'Hide password', + connect: 'Connect', + connecting: 'Connecting…', + connected: 'Connected!', + error: 'Connection failed – please check your details.', + urlRequired: 'Please enter a server URL.', + savedServers: 'Saved Servers', + addNew: 'Or add a new server', + }, + connection: { + connected: 'Connected', + connectedTo: 'Connected to {{server}}', + disconnected: 'Disconnected', + disconnectedFrom: 'Cannot reach {{server}} — click to check settings', + checking: 'Connecting…', + extern: 'Extern', + offlineTitle: 'No server connection', + offlineSubtitle: 'Cannot reach {{server}}. Check your network or server.', + offlineModeBanner: 'Offline Mode — playing from local cache', + offlineNoCacheBanner: 'No server connection — cannot reach {{server}}', + offlineLibraryTitle: 'Offline Library', + offlineLibraryEmpty: 'No albums cached yet. Go online, open an album and click "Make available offline".', + offlineAlbumCount: '{{n}} album', + offlineAlbumCount_plural: '{{n}} albums', + offlineFilterAll: 'All', + offlineFilterAlbums: 'Albums', + offlineFilterPlaylists: 'Playlists', + offlineFilterArtists: 'Discographies', + retry: 'Retry', + serverSettings: 'Server Settings', + switchServerTitle: 'Switch server', + switchServerHint: 'Click to choose another saved server.', + manageServers: 'Manage servers…', + switchFailed: 'Could not switch — server unreachable.', + lastfmConnected: 'Last.fm connected as @{{user}}', + lastfmSessionInvalid: 'Session invalid — click to re-connect', + }, + common: { + albums: 'Albums', + album: 'Album', + loading: 'Loading…', + loadingMore: 'Loading…', + loadingPlaylists: 'Loading Playlists…', + noAlbums: 'No albums found.', + downloading: 'Downloading…', + downloadZip: 'Download (ZIP)', + back: 'Back', + cancel: 'Cancel', + save: 'Save', + delete: 'Delete', + use: 'Use', + add: 'Add', + active: 'Active', + download: 'Download', + chooseDownloadFolder: 'Choose download folder', + noFolderSelected: 'No folder selected', + rememberDownloadFolder: 'Remember this folder', + filterGenre: 'Genre Filter', + filterSearchGenres: 'Search genres…', + filterNoGenres: 'No genres match', + filterClear: 'Clear', + play: 'Play', + bulkSelected: '{{count}} selected', + clearSelection: 'Clear selection', + bulkAddToPlaylist: 'Add to Playlist', + bulkRemoveFromPlaylist: 'Remove from Playlist', + bulkClear: 'Clear selection', + updaterAvailable: 'Update available', + updaterVersion: 'v{{version}} is available', + updaterWebsite: 'Website', + updaterModalTitle: 'New Version Available', + updaterChangelog: "What's New", + updaterDownloadBtn: 'Download Now', + updaterSkipBtn: 'Skip this Version', + updaterRemindBtn: 'Remind me Later', + updaterDone: 'Download complete', + updaterShowFolder: 'Show in Folder', + updaterInstallHint: 'Close Psysonic and run the installer manually.', + updaterAurHint: 'Install the update via AUR:', + updaterErrorMsg: 'Download failed', + updaterRetryBtn: 'Retry', + durationHoursMinutes: '{{hours}}h {{minutes}}m', + durationMinutesOnly: '{{minutes}}m', + updaterOpenGitHub: 'Open on GitHub', + filters: 'Filters', + more: 'more', + yearRange: 'Year Range', + clearAll: 'Clear all', + }, + settings: { + title: 'Settings', + language: 'Language', + languageEn: 'English', + languageDe: 'German', + languageFr: 'French', + languageNl: 'Dutch', + languageZh: 'Chinese', + languageNb: 'Norwegian', + languageRu: 'Russian', + languageEs: 'Spanish', + font: 'Font', + theme: 'Theme', + appearance: 'Appearance', + servers: 'Servers', + serverName: 'Server Name', + serverUrl: 'Server URL', + serverUrlPlaceholder: '192.168.1.100:4533 or https://music.example.com', + serverUsername: 'Username', + serverPassword: 'Password', + addServer: 'Add Server', + addServerTitle: 'Add New Server', + useServer: 'Use', + deleteServer: 'Delete', + noServers: 'No servers saved.', + serverActive: 'Active', + confirmDeleteServer: 'Delete server "{{name}}"?', + serverConnecting: 'Connecting…', + serverConnected: 'Connected!', + serverFailed: 'Connection failed.', + testBtn: 'Test Connection', + testingBtn: 'Testing…', + serverCompatible: 'Compatible with: Navidrome · Gonic · Airsonic · Subsonic', + audiomuseTitle: 'AudioMuse-AI (Navidrome)', + audiomuseDesc: + 'Turn on if this server has the AudioMuse-AI Navidrome plugin configured. Enables Instant Mix from tracks and uses server-side similar artists instead of Last.fm on artist pages.', + audiomuseIssueHint: + 'Instant Mix failed recently — check the Navidrome plugin and AudioMuse API. Similar artists fall back to Last.fm when the server returns none.', + connected: 'Connected', + failed: 'Failed', + eqTitle: 'Equalizer', + eqEnabled: 'Enable Equalizer', + eqPreset: 'Preset', + eqPresetCustom: 'Custom', + eqPresetBuiltin: 'Built-in Presets', + eqPresetCustomGroup: 'My Presets', + eqSavePreset: 'Save as Preset', + eqPresetName: 'Preset name…', + eqDeletePreset: 'Delete preset', + eqResetBands: 'Reset to Flat', + eqPreGain: 'Pre-gain', + eqResetPreGain: 'Reset pre-gain', + eqAutoEqTitle: 'AutoEQ Headphone Lookup', + eqAutoEqPlaceholder: 'Search headphone / IEM model…', + eqAutoEqSearching: 'Searching…', + eqAutoEqNoResults: 'No results found', + eqAutoEqError: 'Search failed', + eqAutoEqRateLimit: 'GitHub rate limit reached — try again in a minute', + eqAutoEqFetchError: 'Failed to fetch EQ profile', + lfmTitle: 'Last.fm', + lfmConnect: 'Connect with Last.fm', + lfmConnecting: 'Waiting for authorisation…', + lfmConfirm: 'I have authorised the app', + lfmConnected: 'Connected as', + lfmDisconnect: 'Disconnect', + lfmConnectDesc: 'Connect your Last.fm account to enable scrobbling and Now Playing updates directly from Psysonic — no Navidrome configuration required.', + lfmOpenBrowser: 'A browser window will open. Authorise Psysonic on Last.fm, then click the button below.', + lfmScrobbles: '{{n}} scrobbles', + lfmMemberSince: 'Member since {{year}}', + scrobbleEnabled: 'Scrobbling enabled', + scrobbleDesc: 'Send songs to Last.fm after 50% playtime', + behavior: 'App Behavior', + cacheTitle: 'Max. Storage Size', + cacheDesc: 'Cover art and artist images. When full, the oldest entries are removed automatically. Offline albums are not auto-removed, but will be deleted when clearing the cache manually.', + cacheUsedImages: 'Images:', + cacheUsedOffline: 'Offline tracks:', + cacheUsedHot: 'Size on disk:', + hotCacheTrackCount: 'Tracks in cache:', + cacheMaxLabel: 'Max. size', + cacheClearBtn: 'Clear Cache', + cacheClearWarning: 'This will also remove all offline albums from the library.', + cacheClearConfirm: 'Clear Everything', + cacheClearCancel: 'Cancel', + offlineDirTitle: 'Offline Library (In-App)', + offlineDirDesc: 'Storage location for tracks you make available offline within Psysonic.', + offlineDirDefault: 'Default (App Data)', + offlineDirChange: 'Change Directory', + offlineDirClear: 'Reset to Default', + offlineDirHint: 'New downloads will use this location. Existing downloads remain at their original path.', + hotCacheTitle: 'Hot playback cache', + hotCacheAlphaBadge: 'Alpha', + hotCacheDisclaimer: 'Preloads upcoming queue tracks and keeps previous ones. When enabled, uses disk space and network.', + hotCacheDirDefault: 'Default (App Data)', + hotCacheDirChange: 'Change folder', + hotCacheDirClear: 'Reset to default', + hotCacheDirHint: 'Changing the folder resets the in-app index; files already on disk stay where they are until you remove them.', + hotCacheEnabled: 'Enable hot playback cache', + hotCacheMaxMb: 'Maximum cache size', + hotCacheDebounce: 'Queue change debounce', + hotCacheDebounceImmediate: 'Immediate', + hotCacheDebounceSeconds: '{{n}} s', + hotCacheClearBtn: 'Clear hot cache', + audioOutputDevice: 'Audio Output Device', + audioOutputDeviceDesc: 'Select which audio device Psysonic plays through. Changes take effect immediately and restart the current track.', + audioOutputDeviceDefault: 'System Default', + audioOutputDeviceRefresh: 'Refresh device list', + audioOutputDeviceOsDefaultNow: 'current system output', + audioOutputDeviceListError: 'Could not load the audio device list.', + audioOutputDeviceNotInCurrentList: 'not in current list', + hiResTitle: 'Native Hi-Res Playback', + hiResEnabled: 'Enable native hi-res playback', + hiResDesc: "Forces 44.1 kHz output by default for maximum stability. Enable only if your hardware and network reliably support high sample rates (88.2 kHz+).", + showArtistImages: 'Show Artist Images', + showArtistImagesDesc: 'Load and display artist images in the Artists overview. Disabled by default to reduce server disk I/O and network load on large libraries.', + showTrayIcon: 'Show Tray Icon', + showTrayIconDesc: 'Display the Psysonic icon in the system notification area / menu bar.', + minimizeToTray: 'Minimize to Tray', + minimizeToTrayDesc: 'When closing the window, keep Psysonic running in the system tray instead of quitting.', + discordRichPresence: 'Discord Rich Presence', + discordRichPresenceDesc: 'Show the currently playing track on your Discord profile. Requires Discord to be running.', + useCustomTitlebar: 'Custom title bar', + useCustomTitlebarDesc: 'Replace the system title bar with a built-in one that matches the app theme. Disable to use the native GNOME/GTK title bar.', + discordAppleCovers: 'Fetch covers from Apple Music for Discord', + discordAppleCoversDesc: 'Sends the artist and album name to Apple\'s search API to find cover art for your Discord profile. Disabled by default for privacy.', + + discordTemplates: 'Custom text templates', + + discordTemplatesDesc: 'Customize what information is shown on your Discord profile. Variables: {title}, {artist}, {album}, {paused}', + + discordTemplateDetails: 'Primary line (details)', + + discordTemplateState: 'Secondary line (state)', + + discordTemplateLargeText: 'Album tooltip (largeText)', + nowPlayingEnabled: 'Show in Now Playing', + nowPlayingEnabledDesc: 'Broadcast your currently playing track to the server\'s live listener view. Disable to stop sending playback data.', + lyricsServerFirst: 'Prefer server lyrics', + lyricsServerFirstDesc: 'Check server-provided lyrics (embedded tags, sidecar files) before querying LRCLIB. Disable to use LRCLIB first.', + enableNeteaselyrics: 'Netease Cloud Music lyrics', + enableNeteaselyricsDesc: 'Use Netease Cloud Music as a last-resort lyrics source when server and LRCLIB both return nothing. Best coverage for Asian and international music.', + lyricsSourcesTitle: 'Lyrics Sources', + lyricsSourcesDesc: 'Choose which sources to query for lyrics and in what order. Drag to reorder. Disabled sources are skipped entirely.', + lyricsSourceServer: 'Server', + lyricsSourceLrclib: 'LRCLIB', + lyricsSourceNetease: 'Netease Cloud Music', + downloadsTitle: 'ZIP Export & Archiving', + downloadsFolderDesc: 'Destination folder for albums you download as a ZIP file to your computer.', + downloadsDefault: 'Default Downloads Folder', + pickFolder: 'Select', + pickFolderTitle: 'Select Download Folder', + clearFolder: 'Clear download folder', + logout: 'Logout', + aboutTitle: 'About Psysonic', + aboutDesc: 'A modern desktop music player for Subsonic-compatible servers (Navidrome, Gonic, and others). Built on Tauri v2 with a native Rust audio engine — lightweight and fast, yet packed with features: waveform seekbar, synchronized lyrics, Last.fm integration, 10-band EQ, crossfade, gapless playback, Replay Gain, genre browsing, and a large library of themes.', + aboutLicense: 'License', + aboutLicenseText: 'GNU GPL v3 — free to use, modify, and distribute under the same license.', + aboutRepo: 'Source Code on GitHub', + aboutVersion: 'Version', + aboutBuiltWith: 'Built with Tauri · React · TypeScript · Rust/rodio', + aboutAiCredit: 'Developed with the support of Claude Code by Anthropic', + aboutContributorsLabel: 'Contributors', + aboutSpecialThanksLabel: 'Special Thanks', + changelog: 'Changelog', + showChangelogOnUpdate: "Show 'What's New' on update", + showChangelogOnUpdateDesc: "Automatically show what's new when a new version is launched for the first time.", + randomMixTitle: 'Random Mix', + randomMixBlacklistTitle: 'Custom Filter Keywords', + randomMixBlacklistDesc: 'Songs are excluded when any keyword matches their genre, title, album, or artist (active when the checkbox above is on).', + randomMixBlacklistPlaceholder: 'Add keyword…', + randomMixBlacklistAdd: 'Add', + randomMixBlacklistEmpty: 'No custom keywords added yet.', + randomMixHardcodedTitle: 'Built-in keywords (active when checkbox is on)', + tabAudio: 'Audio', + tabStorage: 'Storage & Downloads', + tabAppearance: 'Appearance', + homeCustomizerTitle: 'Home Page', + sidebarTitle: 'Sidebar', + sidebarReset: 'Reset to default', + sidebarDrag: 'Drag to reorder', + sidebarFixed: 'Always visible', - randomNavSplitTitle: 'Split Mix navigation', - randomNavSplitDesc: 'Show "Random Mix" and "Random Albums" as separate sidebar entries instead of the "Build a Mix" hub.', + tabInput: 'Input', + tabServer: 'Server', + tabSystem: 'System', + tabGeneral: 'General', + ratingsSectionTitle: 'Ratings', + ratingsSkipStarTitle: 'Skip for 1 star', + ratingsSkipStarDesc: + 'After several skips in a row, set the track to 1★. Only for tracks not yet rated.', + ratingsSkipStarThresholdLabel: 'Skips', + ratingsMixFilterTitle: 'Filter by rating', + ratingsMixFilterDesc: + 'Filter low-rated items in {{mix}} and {{albums}}. Click the selected star again to turn off the threshold.', + ratingsMixMinSong: 'Songs', + ratingsMixMinAlbum: 'Albums', + ratingsMixMinArtist: 'Artists', + ratingsMixMinThresholdAria: 'Minimum stars: {{label}}', + backupTitle: 'Backup & Restore', + backupExport: 'Export settings', + backupExportDesc: 'Saves all settings, server profiles, Last.fm config, theme, EQ and keybindings to a .psybkp file. Passwords are stored in plaintext — keep the file secure.', + backupImport: 'Import settings', + backupImportDesc: 'Restores settings from a .psybkp file. The app will reload after import.', + backupImportConfirm: 'This will overwrite all current settings. Continue?', + backupSuccess: 'Backup saved', + backupImportSuccess: 'Settings restored — reloading…', + backupImportError: 'Invalid or corrupted backup file.', + shortcutsReset: 'Reset to defaults', + shortcutListening: 'Press a key…', + shortcutUnbound: '—', + globalShortcutsTitle: 'Global Shortcuts', + globalShortcutsNote: 'Work system-wide even when Psysonic is in the background. Requires Ctrl, Alt, or Super as a modifier.', + shortcutClear: 'Clear', + shortcutPlayPause: 'Play / Pause', + shortcutNext: 'Next track', + shortcutPrev: 'Previous track', + shortcutVolumeUp: 'Volume up', + shortcutVolumeDown: 'Volume down', + shortcutSeekForward: 'Seek forward 10s', + shortcutSeekBackward: 'Seek backward 10s', + shortcutToggleQueue: 'Toggle queue', + shortcutOpenFolderBrowser: 'Open {{folderBrowser}}', + shortcutFullscreenPlayer: 'Fullscreen player', + shortcutNativeFullscreen: 'Native fullscreen', + playbackTitle: 'Playback', + replayGain: 'Replay Gain', + replayGainDesc: 'Normalize track volume using ReplayGain metadata', + replayGainMode: 'Mode', + replayGainTrack: 'Track', + replayGainAlbum: 'Album', + replayGainPreGain: 'Pre-Gain (tagged files)', + replayGainFallback: 'Fallback (untagged / radio)', + crossfade: 'Crossfade', + crossfadeDesc: 'Fade between tracks', + crossfadeSecs: '{{n}} s', + notWithGapless: 'Not available while Gapless is active', + notWithCrossfade: 'Not available while Crossfade is active', + gapless: 'Gapless Playback', + gaplessDesc: 'Pre-buffer next track to eliminate gaps between songs', + preloadMode: 'Preload Next Track', + preloadModeDesc: 'When to start buffering the next track in the queue', + nextTrackBufferingTitle: 'Next Track Buffering', + preloadHotCacheMutualExclusive: 'Preload and Hot Cache serve the same purpose — only one can be active at a time. Enabling one will automatically disable the other.', + preloadOff: 'Off', + preloadBalanced: 'Balanced (30 s before end)', + preloadEarly: 'Early (after 5 s of playback)', + preloadCustom: 'Custom', + preloadCustomSeconds: 'Seconds before end: {{n}}', + infiniteQueue: 'Infinite Queue', + infiniteQueueDesc: 'Automatically append random tracks when the queue runs out', + experimental: 'Experimental', + fsPlayerSection: 'Fullscreen Player', + fsShowArtistPortrait: 'Show artist photo', + fsShowArtistPortraitDesc: 'Display the artist photo (or album art) on the right side of the fullscreen player.', + fsPortraitDim: 'Photo dimming', + seekbarStyle: 'Seekbar Style', + seekbarStyleDesc: 'Choose the look of the player seek bar', + seekbarWaveform: 'Waveform', + seekbarLinedot: 'Line & Dot', + seekbarBar: 'Bar', + seekbarThick: 'Thick Bar', + seekbarSegmented: 'Segmented', + seekbarNeon: 'Neon Glow', + seekbarPulsewave: 'Pulse Wave', + seekbarParticletrail: 'Particle Trail', + seekbarLiquidfill: 'Liquid Fill', + seekbarRetrotape: 'Retro Tape', + themeSchedulerTitle: 'Auto-Switch Theme', + themeSchedulerEnable: 'Enable Theme Scheduler', + themeSchedulerEnableSub: 'Automatically switch between two themes based on the time of day', + themeSchedulerDayTheme: 'Day Theme', + themeSchedulerDayStart: 'Day Starts At', + themeSchedulerNightTheme: 'Night Theme', + themeSchedulerNightStart: 'Night Starts At', + themeSchedulerActiveHint: 'Theme Scheduler is active - theme changes are managed automatically.', + visualOptionsTitle: 'Visual Options', + coverArtBackground: 'Cover Art Background', + coverArtBackgroundSub: 'Show blurred cover art as background in album/playlist headers', + playlistCoverPhoto: 'Playlist Cover Photo', + playlistCoverPhotoSub: 'Show cover photo grid in playlist detail view', + showBitrate: 'Show Bitrate', + showBitrateSub: 'Display audio bitrate in track listings', + uiScaleTitle: 'Interface Scale', + uiScaleLabel: 'Zoom', + }, + changelog: { + modalTitle: "What's New", + dontShowAgain: "Don't show again", + close: 'Got it', + }, + help: { + title: 'Help', + s1: 'Getting Started', + q1: 'Which servers are compatible?', + a1: 'Psysonic works with any Subsonic-compatible server: Navidrome, Gonic, Subsonic, Airsonic, and others. Navidrome is the recommended choice.', + q2: 'How do I connect to my server?', + a2: 'Open Settings and click "Add Server". Enter the server URL (e.g. 192.168.1.100:4533), your username, and password. Psysonic tests the connection before saving — nothing is stored if the connection fails.', + q3: 'Can I use multiple servers?', + a3: 'Yes. You can add as many servers as you like in Settings and switch between them at any time. Only one server is active at a time.', + s2: 'Playback', + q4: 'How do I play music?', + a4: 'Double-click any track to play it. On album and artist pages, use "Play All" to start the whole album. You can also drag tracks into the queue panel.', + q5: 'What keyboard shortcuts are available?', + a5: 'Space = Play / Pause · Escape = Close fullscreen player. Media keys (Play/Pause, Next, Previous) work on all platforms. On Linux, use the player bar buttons for media keys. In-app shortcuts and system-wide global shortcuts can be customized in Settings → Keyboard Shortcuts / Global Shortcuts.', + q6: 'What is the queue?', + a6: 'The queue shows all upcoming tracks. Open it with the panel icon in the top-right header (next to the Now Playing indicator). You can reorder tracks by dragging, shuffle with the shuffle button, and save the queue as a playlist.', + q7: 'How do I open the fullscreen player?', + a7: 'Click the album art thumbnail in the player bar at the bottom, or the expand icon next to it. Press Escape to close it again.', + q8: 'How does repeat work?', + a8: 'Click the repeat button in the player bar to cycle through: Off → Repeat All → Repeat One.', + s3: 'Library', + q9: 'How do I download an album?', + a9: 'Open an album\'s detail page and click "Download (ZIP)". The server compresses the album into a ZIP file first — for large albums or lossless files (FLAC / WAV) this can take a moment before the download actually starts. This is normal: the progress bar appears once the server finishes zipping and the transfer begins.', + q10: 'How do I star / favorite tracks and albums?', + a10: 'Click the star icon on any track row or on the album header. Starred items appear in the Favorites section in the sidebar.', + q11: 'What is the hero carousel on the home page?', + a11: 'The banner at the top of the home page randomly picks albums from your library and rotates through them every 10 seconds. Click the dots to jump to a specific one, or click the banner to open the album.', + s4: 'Settings', + q12: 'How do I change the theme?', + a12: 'Settings → Theme. Choose from a large selection of themes across 8 groups: Psysonic Themes, Mediaplayer, Operating Systems, Games, Movies, Series, Social Media, and Open Source Classics (Catppuccin, Nord, Gruvbox, Nightfox).', + q13: 'How do I change the language?', + a13: 'Settings → Language. English, German, Spanish, French, Dutch, Chinese, Norwegian, and Russian are supported.', + q15: 'How do I set a download folder?', + a15: 'Settings → App Behavior → Download Folder. Pick any folder — downloaded albums are saved there as ZIP files. Without a custom folder, your browser\'s default downloads location is used.', + s5: 'Scrobbling', + q16: 'How does scrobbling work?', + a16: 'Psysonic scrobbles directly to Last.fm — no Navidrome configuration needed. Connect your Last.fm account in Settings → Last.fm and enable scrobbling there.', + q17: 'When is a scrobble sent?', + a17: 'A scrobble is submitted after you\'ve listened to 50% of a track.', + q22: 'What is the waveform in the player bar?', + a22: 'The waveform seekbar replaces the classic progress slider. Click anywhere on it to jump to that position, or drag to scrub. The played portion glows with a blue-to-mauve gradient, the buffered range appears slightly brighter, and the unplayed portion is faded.', + q24: 'Can I shuffle the queue?', + a24: 'Yes. Open the queue panel and click the shuffle icon in the queue header. The currently playing track stays at position 1 — all remaining tracks are randomly reordered.', + q25: 'Do Last.fm and Wikipedia links on artist pages open in a browser?', + a25: 'Yes — they open in your default system browser. The button briefly shows a confirmation label when clicked.', + s7: 'Random Mix', + q26: 'What is Random Mix?', + a26: 'Random Mix builds a playlist of random tracks from your entire library. Open it via "Random Mix" in the sidebar and click "New Mix". You can adjust the track count before generating.', + q27: 'What is the Keyword Filter?', + a27: 'The Keyword Filter excludes tracks whose genre, title, or album name contains specific words. Audiobooks are filtered automatically. Add custom keywords in Settings → Random Mix, or click any genre tag in the track list to add it instantly.', + q28: 'What is the Super Genre Mix?', + a28: 'The Super Genre Mix groups your library into broad categories (Rock, Metal, Electronic, Jazz, Classical, etc.) and builds a focused mix from that style. Select a category chip below the track list. Results appear progressively as each sub-genre is fetched.', + s6: 'Troubleshooting', + q18: 'Cover art and artist images load slowly.', + a18: 'Images are fetched from your server\'s disk on first load and then cached locally for 30 days. If your server\'s storage is slow, the first visit to a page may take a moment. Subsequent visits will be instant.', + q19: 'The connection test fails.', + a19: 'Check the URL including the port (e.g. http://192.168.1.100:4533). Make sure no firewall blocks the connection. Try http:// instead of https:// on a local network. Also verify that your username and password are correct.', + q20: 'No audio on Linux.', + a20: 'Psysonic is available as .deb (Ubuntu/Debian), .rpm (Fedora/RHEL), and via AUR on Arch/CachyOS (yay -S psysonic). There is no AppImage. If audio is missing, ensure PipeWire or PulseAudio is running.', + q21: 'The app shows a black screen on Linux.', + a21: 'This is usually a GPU/EGL driver issue in WebKitGTK. Launch with GDK_BACKEND=x11 WEBKIT_DISABLE_COMPOSITING_MODE=1 WEBKIT_DISABLE_DMABUF_RENDERER=1. The AUR package and official .deb/.rpm installers set these automatically.', + q29: 'What are Crossfade and Gapless Playback?', + a29: 'Both are experimental audio features in Settings → Audio. Gapless pre-buffers the next track to eliminate silence between songs. Crossfade fades out the current track while fading in the next — adjust the duration (1–10 s) to taste.', + q30: 'Does Psysonic show lyrics?', + a30: 'Yes. Click the microphone icon in the player bar to open the Lyrics tab in the queue panel. Psysonic fetches lyrics automatically from LRCLIB. If synced lyrics are available, the active line is highlighted and scrolls in real time as the song plays. If only plain text is available, the full text is shown statically.', + q31: 'Can I customize keyboard shortcuts?', + a31: 'Yes. Settings → Keyboard Shortcuts lets you remap in-app actions (Play/Pause, Next, Previous, Volume Up/Down, Fullscreen, and more) to any key. Settings → Global Shortcuts lets you assign system-wide shortcuts that trigger even when Psysonic is in the background.', + q32: 'Can I change the font?', + a32: 'Yes. Settings → Font lets you choose from 10 fonts including IBM Plex Mono, Fira Code, JetBrains Mono, Courier Prime, and others. The selected font applies to the entire UI.', + s8: 'Offline Mode', + q34: 'What is Offline Mode?', + a34: 'Offline Mode (Beta) lets you cache albums to your device so you can listen without an active server connection. Cached tracks are stored locally and played back directly from disk — no network request is made during playback.', + q35: 'How do I cache an album for offline use?', + a35: 'Open any album and click the download icon in the album header. Psysonic downloads all tracks in the background. Progress is shown on the button. Once cached, the icon turns green. You can view and remove cached albums in the Offline Library page (sidebar).', + q36: 'How much storage can offline caching use?', + a36: 'You can set a maximum cache size in Settings → Library. When the limit is reached, a warning banner appears on the album page. You can delete individual albums from the Offline Library to free up space.', + q37: 'How do I rate songs, albums, and artists?', + a37: 'Psysonic supports 1–5 star ratings via the OpenSubsonic API (requires Navidrome ≥ 0.53). Rate songs in the album or playlist track list using the star column, in the right-click context menu, or directly in the player bar below the artist name. Albums can be rated on their detail page; artists on their artist page. Ratings are saved to the server immediately.', + q38: 'Can I remove or change a rating?', + a38: 'Yes. Click the currently active star to clear the rating entirely — clicking the same star a second time removes it. To change a rating, simply click a different star.', + q39: 'What is Skip-to-1★ and the rating filter?', + a39: 'Skip-to-1★ automatically assigns a 1-star rating to a song after you manually skip it a configurable number of consecutive times. Enable it and set the skip threshold in Settings → Ratings. The same settings panel lets you set a minimum star rating for Random Mix and Random Albums, so only songs, albums, or artists above a certain rating are included in generated mixes.', + q40: 'What is the Folder Browser?', + a40: 'The Folder Browser (sidebar) lets you navigate your server\'s music directory tree using a Miller-column layout. Click a folder to drill into it; click a track or the play icon on a folder to play or enqueue its contents directly.', + q41: 'What is the Theme Scheduler?', + a41: 'Settings → Appearance → Auto-Switch Theme: define a day theme and a night theme with start times. Psysonic switches automatically at the configured hours. When the scheduler is active, a hint in the theme picker explains why manual theme selection has no immediate effect.', + q42: 'Can I resize the interface?', + a42: 'Yes. Settings → Appearance → Interface Scale lets you scale the entire UI between 80 % and 125 % without affecting your system font size.', + q43: 'Can I change the seekbar style?', + a43: 'Yes. Settings → Appearance → Seekbar Style offers 10 styles: Waveform, Line & Dot, Bar, Thick Bar, Segmented, Neon Glow, Pulse Wave, Particle Trail, Liquid Fill, and Retro Tape.', + q44: 'What is AutoEQ?', + a44: 'The 10-band EQ in Settings → Audio includes an AutoEQ lookup. Enter your headphone model and Psysonic fetches a correction profile from the AutoEQ database and applies it automatically to the equalizer bands.', + q45: 'What is Replay Gain?', + a45: 'Replay Gain normalizes track volume so loud and quiet albums play at a consistent level. Enable it in Settings → Audio → Replay Gain and choose Track mode (per-song normalization) or Album mode (preserves relative dynamics within an album).', + q46: 'What is the Hot Cache?', + a46: 'Hot Cache (Alpha, Settings → Library) preloads the next several tracks in your queue to disk so playback starts instantly with no buffering delay — especially useful on slow or remote servers. Psysonic keeps the current track and the next 5 in cache and evicts older entries when the size limit is reached. You can set the maximum cache size and a debounce delay to avoid unnecessary fetches when skipping quickly.', + q47: 'Can I cache a playlist for offline use?', + a47: 'Yes. Open any playlist and click the download icon in the playlist header. All tracks are downloaded in the background — progress is shown in the offline download indicator. Once fully cached, the icon changes to a red trash icon; clicking it removes the playlist from the offline cache.', - q48: 'What is Infinite Queue?', - a48: 'When the queue runs out and Repeat is off, Psysonic silently appends random tracks from your library so playback never stops. Auto-added tracks appear below a "— Added automatically —" divider in the queue. Toggle it with the infinity icon in the queue header. You can also restrict auto-added tracks to a specific genre in Settings → Queue.', - q49: 'Can I control Psysonic from the command line?', - a49: 'Yes — the Psysonic binary doubles as a remote control for the running app. Examples: psysonic --player play / pause / next / prev, --player volume 75, --player seek 15, --player mute, --player shuffle, --player repeat off|all|one, --player star / unstar, --player rating 1-5. You can also switch servers (--player server list / set), change the audio device (--player audio-device list / set), filter the music library (--player library list / set), trigger an Instant Mix (--player mix new / append), and search (--player search track|album|artist ). Run psysonic --player --help for the full list. Shell completions for bash and zsh are available via psysonic completions.', - q50: 'How do I manage playlists?', - a50: 'Open "Playlists" in the sidebar. Click "New Playlist" to create one. On a playlist detail page you can drag tracks to reorder them, remove tracks with the × button, search your library to add songs, and use "Suggestions" to get smart track recommendations based on your playlist content. Right-click any track for more options.', - q51: 'Can I back up and restore my settings?', - a51: 'Yes. Settings → Backup & Restore lets you export all your settings, server profiles, themes, and keybindings to a single JSON file. Import it on another machine or after a reinstall to restore everything at once. Passwords are included in the backup — store the file securely.', - q52: 'How do I change the audio output device?', - a52: 'Settings → Audio → Output Device. Psysonic lists all available audio outputs on your system. Select the one you want — playback switches immediately. Use the refresh button next to the list if a device was connected after the app started. On Linux this uses ALSA device names; generic entries like "default" or "sysdefault" are automatically cleaned up for readability.', - q53: 'What is Device Sync?', - a53: 'Device Sync lets you copy albums, playlists, or entire artists to a USB drive or SD card for listening on other devices. Open it via "Device Sync" in the sidebar. Select a target folder on your drive, choose sources from the browser tabs, and click "Transfer to Device". Psysonic downloads the tracks from your server and writes them in the folder structure defined by the filename template.', - q54: 'What is the filename template in Device Sync?', - a54: 'The filename template controls how tracks are named and organized on the device. Use the preset buttons (Standard, Multi-Disc, Alt. Folder) or build your own using the clickable token chips: {artist}, {album}, {title}, {track_number}, {disc_number}, {year}, and / for folder separators. A live preview shows how an example track would be named.', - q55: 'Does Device Sync work across platforms?', - a55: 'Yes. The sync manifest (psysonic-sync.json) written to the device stores the filename template used during sync. When you open Device Sync on a different OS with a different template, Psysonic uses the stored template to correctly detect which files are already on the device — so albums don\'t show as pending when they are already synced.', - s9: 'Device Sync', - q56: 'What is Internet Radio?', - a56: 'The Internet Radio page (sidebar) lets you play any live stream directly in Psysonic. Stations are fetched from your Navidrome server — add them there via the Navidrome admin panel, or import a .pls / .m3u file. Playback uses the browser\'s built-in HTML5 audio engine rather than the Rust audio engine, so some EQ and Replay Gain settings do not apply to radio.', - q57: 'What stream formats does Internet Radio support?', - a57: 'Psysonic supports any format your system\'s audio stack can decode: MP3, AAC, OGG Vorbis, and most HLS streams. The stream is played via HTML5