import 'dart:async';

import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:intl/intl.dart' as intl;

import 'app_localizations_de.dart';
import 'app_localizations_en.dart';
import 'app_localizations_es.dart';
import 'app_localizations_fr.dart';
import 'app_localizations_id.dart';
import 'app_localizations_ja.dart';
import 'app_localizations_ko.dart';
import 'app_localizations_pt.dart';
import 'app_localizations_ru.dart';
import 'app_localizations_tr.dart';
import 'app_localizations_uk.dart';

// ignore_for_file: type=lint

/// Callers can lookup localized strings with an instance of AppLocalizations
/// returned by `AppLocalizations.of(context)`.
///
/// Applications need to include `AppLocalizations.delegate()` in their app's
/// `localizationDelegates` list, and the locales they support in the app's
/// `supportedLocales` list. For example:
///
/// ```dart
/// import 'l10n/app_localizations.dart';
///
/// return MaterialApp(
///   localizationsDelegates: AppLocalizations.localizationsDelegates,
///   supportedLocales: AppLocalizations.supportedLocales,
///   home: MyApplicationHome(),
/// );
/// ```
///
/// ## Update pubspec.yaml
///
/// Please make sure to update your pubspec.yaml to include the following
/// packages:
///
/// ```yaml
/// dependencies:
///   # Internationalization support.
///   flutter_localizations:
///     sdk: flutter
///   intl: any # Use the pinned version from flutter_localizations
///
///   # Rest of dependencies
/// ```
///
/// ## iOS Applications
///
/// iOS applications define key application metadata, including supported
/// locales, in an Info.plist file that is built into the application bundle.
/// To configure the locales supported by your app, you’ll need to edit this
/// file.
///
/// First, open your project’s ios/Runner.xcworkspace Xcode workspace file.
/// Then, in the Project Navigator, open the Info.plist file under the Runner
/// project’s Runner folder.
///
/// Next, select the Information Property List item, select Add Item from the
/// Editor menu, then select Localizations from the pop-up menu.
///
/// Select and expand the newly-created Localizations item then, for each
/// locale your application supports, add a new item and select the locale
/// you wish to add from the pop-up menu in the Value field. This list should
/// be consistent with the languages listed in the AppLocalizations.supportedLocales
/// property.
abstract class AppLocalizations {
  AppLocalizations(String locale)
    : localeName = intl.Intl.canonicalizedLocale(locale.toString());

  final String localeName;

  static AppLocalizations of(BuildContext context) {
    return Localizations.of<AppLocalizations>(context, AppLocalizations)!;
  }

  static const LocalizationsDelegate<AppLocalizations> delegate =
      _AppLocalizationsDelegate();

  /// A list of this localizations delegate along with the default localizations
  /// delegates.
  ///
  /// Returns a list of localizations delegates containing this delegate along with
  /// GlobalMaterialLocalizations.delegate, GlobalCupertinoLocalizations.delegate,
  /// and GlobalWidgetsLocalizations.delegate.
  ///
  /// Additional delegates can be added by appending to this list in
  /// MaterialApp. This list does not have to be used at all if a custom list
  /// of delegates is preferred or required.
  static const List<LocalizationsDelegate<dynamic>> localizationsDelegates =
      <LocalizationsDelegate<dynamic>>[
        delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
      ];

  /// A list of this localizations delegate's supported locales.
  static const List<Locale> supportedLocales = <Locale>[
    Locale('de'),
    Locale('en'),
    Locale('es'),
    Locale('es', 'ES'),
    Locale('fr'),
    Locale('id'),
    Locale('ja'),
    Locale('ko'),
    Locale('pt'),
    Locale('pt', 'PT'),
    Locale('ru'),
    Locale('tr'),
    Locale('uk'),
  ];

  /// App name - DO NOT TRANSLATE
  ///
  /// In en, this message translates to:
  /// **'SpotiFLAC Mobile'**
  String get appName;

  /// Bottom navigation - Home tab
  ///
  /// In en, this message translates to:
  /// **'Home'**
  String get navHome;

  /// Bottom navigation - Library tab
  ///
  /// In en, this message translates to:
  /// **'Library'**
  String get navLibrary;

  /// Bottom navigation - Settings tab
  ///
  /// In en, this message translates to:
  /// **'Settings'**
  String get navSettings;

  /// Bottom navigation - Extension repo tab
  ///
  /// In en, this message translates to:
  /// **'Repo'**
  String get navStore;

  /// Home screen title
  ///
  /// In en, this message translates to:
  /// **'Home'**
  String get homeTitle;

  /// Subtitle shown below search box
  ///
  /// In en, this message translates to:
  /// **'Paste a supported URL or search by name'**
  String get homeSubtitle;

  /// Title shown on home when no providers are available yet
  ///
  /// In en, this message translates to:
  /// **'No search providers yet'**
  String get homeEmptyTitle;

  /// Subtitle shown on home when no providers are available yet
  ///
  /// In en, this message translates to:
  /// **'Install an extension to continue.'**
  String get homeEmptySubtitle;

  /// Info text about supported URL types
  ///
  /// In en, this message translates to:
  /// **'Supports: Track, Album, Playlist, Artist URLs'**
  String get homeSupports;

  /// Section header for recent searches
  ///
  /// In en, this message translates to:
  /// **'Recent'**
  String get homeRecent;

  /// Filter chip - show all items
  ///
  /// In en, this message translates to:
  /// **'All'**
  String get historyFilterAll;

  /// Filter chip - show albums only
  ///
  /// In en, this message translates to:
  /// **'Albums'**
  String get historyFilterAlbums;

  /// Filter chip - show singles only
  ///
  /// In en, this message translates to:
  /// **'Singles'**
  String get historyFilterSingles;

  /// Search bar placeholder in history
  ///
  /// In en, this message translates to:
  /// **'Search history...'**
  String get historySearchHint;

  /// Settings screen title
  ///
  /// In en, this message translates to:
  /// **'Settings'**
  String get settingsTitle;

  /// Settings section - download options
  ///
  /// In en, this message translates to:
  /// **'Download'**
  String get settingsDownload;

  /// Settings section - visual customization
  ///
  /// In en, this message translates to:
  /// **'Appearance'**
  String get settingsAppearance;

  /// Settings section - extension management
  ///
  /// In en, this message translates to:
  /// **'Extensions'**
  String get settingsExtensions;

  /// Settings section - app info
  ///
  /// In en, this message translates to:
  /// **'About'**
  String get settingsAbout;

  /// Download settings page title
  ///
  /// In en, this message translates to:
  /// **'Download'**
  String get downloadTitle;

  /// Subtitle for ask quality toggle
  ///
  /// In en, this message translates to:
  /// **'Show quality picker for each download'**
  String get downloadAskQualitySubtitle;

  /// Setting for output filename pattern
  ///
  /// In en, this message translates to:
  /// **'Filename Format'**
  String get downloadFilenameFormat;

  /// Setting for output filename pattern for singles/EPs
  ///
  /// In en, this message translates to:
  /// **'Single Filename Format'**
  String get downloadSingleFilenameFormat;

  /// Subtitle description for single filename format setting
  ///
  /// In en, this message translates to:
  /// **'Filename pattern for singles and EPs. Uses the same tags as the album format.'**
  String get downloadSingleFilenameFormatDescription;

  /// Title of the folder organization picker bottom sheet
  ///
  /// In en, this message translates to:
  /// **'Folder Organization'**
  String get downloadFolderOrganization;

  /// Appearance settings page title
  ///
  /// In en, this message translates to:
  /// **'Appearance'**
  String get appearanceTitle;

  /// Follow system theme
  ///
  /// In en, this message translates to:
  /// **'System'**
  String get appearanceThemeSystem;

  /// Light theme
  ///
  /// In en, this message translates to:
  /// **'Light'**
  String get appearanceThemeLight;

  /// Dark theme
  ///
  /// In en, this message translates to:
  /// **'Dark'**
  String get appearanceThemeDark;

  /// Material You dynamic colors
  ///
  /// In en, this message translates to:
  /// **'Dynamic Color'**
  String get appearanceDynamicColor;

  /// Subtitle for dynamic color
  ///
  /// In en, this message translates to:
  /// **'Use colors from your wallpaper'**
  String get appearanceDynamicColorSubtitle;

  /// Layout style for history
  ///
  /// In en, this message translates to:
  /// **'History View'**
  String get appearanceHistoryView;

  /// List layout option
  ///
  /// In en, this message translates to:
  /// **'List'**
  String get appearanceHistoryViewList;

  /// Grid layout option
  ///
  /// In en, this message translates to:
  /// **'Grid'**
  String get appearanceHistoryViewGrid;

  /// Main search provider setting
  ///
  /// In en, this message translates to:
  /// **'Primary Provider'**
  String get optionsPrimaryProvider;

  /// Subtitle for primary provider
  ///
  /// In en, this message translates to:
  /// **'Service used for searching by track or album name'**
  String get optionsPrimaryProviderSubtitle;

  /// Shows active extension name
  ///
  /// In en, this message translates to:
  /// **'Using extension: {extensionName}'**
  String optionsUsingExtension(String extensionName);

  /// Title for the preferred default search tab setting
  ///
  /// In en, this message translates to:
  /// **'Default Search Tab'**
  String get optionsDefaultSearchTab;

  /// Subtitle for the preferred default search tab setting
  ///
  /// In en, this message translates to:
  /// **'Choose which tab opens first for new search results.'**
  String get optionsDefaultSearchTabSubtitle;

  /// Auto-retry with other services
  ///
  /// In en, this message translates to:
  /// **'Auto Fallback'**
  String get optionsAutoFallback;

  /// Subtitle for auto fallback
  ///
  /// In en, this message translates to:
  /// **'Try other services if download fails'**
  String get optionsAutoFallbackSubtitle;

  /// Embed lyrics in audio files
  ///
  /// In en, this message translates to:
  /// **'Embed Lyrics'**
  String get optionsEmbedLyrics;

  /// Subtitle for embed lyrics
  ///
  /// In en, this message translates to:
  /// **'Save synced lyrics alongside your downloaded tracks'**
  String get optionsEmbedLyricsSubtitle;

  /// Title for ReplayGain setting toggle
  ///
  /// In en, this message translates to:
  /// **'ReplayGain'**
  String get optionsReplayGain;

  /// Subtitle when ReplayGain is enabled
  ///
  /// In en, this message translates to:
  /// **'Scan loudness and embed ReplayGain tags (EBU R128)'**
  String get optionsReplayGainSubtitleOn;

  /// Subtitle when ReplayGain is disabled
  ///
  /// In en, this message translates to:
  /// **'Disabled: no loudness normalization tags'**
  String get optionsReplayGainSubtitleOff;

  /// Three-dot menu option to scan loudness and write ReplayGain tags
  ///
  /// In en, this message translates to:
  /// **'Rescan ReplayGain'**
  String get trackReplayGain;

  /// Snackbar/progress message while scanning ReplayGain for a single track
  ///
  /// In en, this message translates to:
  /// **'Analyzing loudness...'**
  String get trackReplayGainScanning;

  /// Snackbar message after ReplayGain tags written for a single track
  ///
  /// In en, this message translates to:
  /// **'ReplayGain tags added'**
  String get trackReplayGainSuccess;

  /// Snackbar message when ReplayGain scan/write fails
  ///
  /// In en, this message translates to:
  /// **'Failed to add ReplayGain tags'**
  String get trackReplayGainFailed;

  /// Batch selection action button label for ReplayGain
  ///
  /// In en, this message translates to:
  /// **'ReplayGain ({count})'**
  String selectionReplayGainCount(int count);

  /// Title of the batch ReplayGain confirmation dialog
  ///
  /// In en, this message translates to:
  /// **'Add ReplayGain'**
  String get replayGainBatchConfirmTitle;

  /// Message of the batch ReplayGain confirmation dialog
  ///
  /// In en, this message translates to:
  /// **'Analyze loudness and write ReplayGain tags to {count} track(s)?'**
  String replayGainBatchConfirmMessage(int count);

  /// Progress dialog title while batch scanning ReplayGain
  ///
  /// In en, this message translates to:
  /// **'Analyzing ReplayGain...'**
  String get replayGainBatchAnalyzing;

  /// Snackbar after batch ReplayGain completes
  ///
  /// In en, this message translates to:
  /// **'ReplayGain added to {success} of {total} tracks'**
  String replayGainBatchSuccess(int success, int total);

  /// Setting title for how artist metadata is written into files
  ///
  /// In en, this message translates to:
  /// **'Artist Tag Mode'**
  String get optionsArtistTagMode;

  /// Bottom-sheet description for artist tag mode setting
  ///
  /// In en, this message translates to:
  /// **'Choose how multiple artists are written into embedded tags.'**
  String get optionsArtistTagModeDescription;

  /// Artist tag mode option that joins multiple artists into one value
  ///
  /// In en, this message translates to:
  /// **'Single joined value'**
  String get optionsArtistTagModeJoined;

  /// Subtitle for joined artist tag mode
  ///
  /// In en, this message translates to:
  /// **'Write one ARTIST value like \"Artist A, Artist B\" for maximum player compatibility.'**
  String get optionsArtistTagModeJoinedSubtitle;

  /// Artist tag mode option that writes repeated ARTIST tags for Vorbis formats
  ///
  /// In en, this message translates to:
  /// **'Split tags for FLAC/Opus'**
  String get optionsArtistTagModeSplitVorbis;

  /// Subtitle for split Vorbis artist tag mode
  ///
  /// In en, this message translates to:
  /// **'Write one artist tag per artist for FLAC and Opus; MP3 and M4A stay joined.'**
  String get optionsArtistTagModeSplitVorbisSubtitle;

  /// Show/hide repo tab
  ///
  /// In en, this message translates to:
  /// **'Extension Repo'**
  String get optionsExtensionStore;

  /// Subtitle for extension repo toggle
  ///
  /// In en, this message translates to:
  /// **'Show Repo tab in navigation'**
  String get optionsExtensionStoreSubtitle;

  /// Auto update check toggle
  ///
  /// In en, this message translates to:
  /// **'Check for Updates'**
  String get optionsCheckUpdates;

  /// Subtitle for update check
  ///
  /// In en, this message translates to:
  /// **'Notify when new version is available'**
  String get optionsCheckUpdatesSubtitle;

  /// Stable vs preview releases
  ///
  /// In en, this message translates to:
  /// **'Update Channel'**
  String get optionsUpdateChannel;

  /// Only stable updates
  ///
  /// In en, this message translates to:
  /// **'Stable releases only'**
  String get optionsUpdateChannelStable;

  /// Include beta/preview updates
  ///
  /// In en, this message translates to:
  /// **'Get preview releases'**
  String get optionsUpdateChannelPreview;

  /// Warning about preview channel
  ///
  /// In en, this message translates to:
  /// **'Preview may contain bugs or incomplete features'**
  String get optionsUpdateChannelWarning;

  /// Delete all download history
  ///
  /// In en, this message translates to:
  /// **'Clear Download History'**
  String get optionsClearHistory;

  /// Subtitle for clear history
  ///
  /// In en, this message translates to:
  /// **'Remove all downloaded tracks from history'**
  String get optionsClearHistorySubtitle;

  /// Enable verbose logs for debugging
  ///
  /// In en, this message translates to:
  /// **'Detailed Logging'**
  String get optionsDetailedLogging;

  /// Status when logging enabled
  ///
  /// In en, this message translates to:
  /// **'Detailed logs are being recorded'**
  String get optionsDetailedLoggingOn;

  /// Status when logging disabled
  ///
  /// In en, this message translates to:
  /// **'Enable for bug reports'**
  String get optionsDetailedLoggingOff;

  /// Extensions page title
  ///
  /// In en, this message translates to:
  /// **'Extensions'**
  String get extensionsTitle;

  /// Extension status - inactive
  ///
  /// In en, this message translates to:
  /// **'Disabled'**
  String get extensionsDisabled;

  /// Extension version display
  ///
  /// In en, this message translates to:
  /// **'Version {version}'**
  String extensionsVersion(String version);

  /// Uninstall extension button
  ///
  /// In en, this message translates to:
  /// **'Uninstall'**
  String get extensionsUninstall;

  /// Repo screen title
  ///
  /// In en, this message translates to:
  /// **'Extension Repo'**
  String get storeTitle;

  /// Repo search placeholder
  ///
  /// In en, this message translates to:
  /// **'Search extensions...'**
  String get storeSearch;

  /// Install extension button
  ///
  /// In en, this message translates to:
  /// **'Install'**
  String get storeInstall;

  /// Already installed badge
  ///
  /// In en, this message translates to:
  /// **'Installed'**
  String get storeInstalled;

  /// Update available button
  ///
  /// In en, this message translates to:
  /// **'Update'**
  String get storeUpdate;

  /// About page title
  ///
  /// In en, this message translates to:
  /// **'About'**
  String get aboutTitle;

  /// Section for contributors
  ///
  /// In en, this message translates to:
  /// **'Contributors'**
  String get aboutContributors;

  /// Role description for mobile dev
  ///
  /// In en, this message translates to:
  /// **'Mobile version developer'**
  String get aboutMobileDeveloper;

  /// Role description for original creator
  ///
  /// In en, this message translates to:
  /// **'Creator of the original SpotiFLAC'**
  String get aboutOriginalCreator;

  /// Role description for logo artist
  ///
  /// In en, this message translates to:
  /// **'The talented artist who created our beautiful app logo!'**
  String get aboutLogoArtist;

  /// Section for translators
  ///
  /// In en, this message translates to:
  /// **'Translators'**
  String get aboutTranslators;

  /// Section for special thanks
  ///
  /// In en, this message translates to:
  /// **'Special Thanks'**
  String get aboutSpecialThanks;

  /// Section for external links
  ///
  /// In en, this message translates to:
  /// **'Links'**
  String get aboutLinks;

  /// Link to mobile GitHub repo
  ///
  /// In en, this message translates to:
  /// **'Mobile source code'**
  String get aboutMobileSource;

  /// Link to PC GitHub repo
  ///
  /// In en, this message translates to:
  /// **'PC source code'**
  String get aboutPCSource;

  /// Link to Keep Android Open campaign website
  ///
  /// In en, this message translates to:
  /// **'Keep Android Open'**
  String get aboutKeepAndroidOpen;

  /// Link to report bugs
  ///
  /// In en, this message translates to:
  /// **'Report an issue'**
  String get aboutReportIssue;

  /// Subtitle for report issue
  ///
  /// In en, this message translates to:
  /// **'Report any problems you encounter'**
  String get aboutReportIssueSubtitle;

  /// Link to suggest features
  ///
  /// In en, this message translates to:
  /// **'Feature request'**
  String get aboutFeatureRequest;

  /// Subtitle for feature request
  ///
  /// In en, this message translates to:
  /// **'Suggest new features for the app'**
  String get aboutFeatureRequestSubtitle;

  /// Link to Telegram channel
  ///
  /// In en, this message translates to:
  /// **'Telegram Channel'**
  String get aboutTelegramChannel;

  /// Subtitle for Telegram channel
  ///
  /// In en, this message translates to:
  /// **'Announcements and updates'**
  String get aboutTelegramChannelSubtitle;

  /// Link to Telegram chat group
  ///
  /// In en, this message translates to:
  /// **'Telegram Community'**
  String get aboutTelegramChat;

  /// Subtitle for Telegram chat
  ///
  /// In en, this message translates to:
  /// **'Chat with other users'**
  String get aboutTelegramChatSubtitle;

  /// Section for social links
  ///
  /// In en, this message translates to:
  /// **'Social'**
  String get aboutSocial;

  /// Section for app info
  ///
  /// In en, this message translates to:
  /// **'App'**
  String get aboutApp;

  /// Version info label
  ///
  /// In en, this message translates to:
  /// **'Version'**
  String get aboutVersion;

  /// Credit description for binimum
  ///
  /// In en, this message translates to:
  /// **'The creator of QQDL & HiFi API. This project helped shape lossless download support.'**
  String get aboutBinimumDesc;

  /// Credit description for sachinsenal0x64
  ///
  /// In en, this message translates to:
  /// **'The original HiFi project creator. A foundation for lossless-source integration.'**
  String get aboutSachinsenalDesc;

  /// Credit description for sjdonado
  ///
  /// In en, this message translates to:
  /// **'Creator of I Don\'t Have Spotify (IDHS). The fallback link resolver that saves the day!'**
  String get aboutSjdonadoDesc;

  /// App description in header card
  ///
  /// In en, this message translates to:
  /// **'Search music metadata, manage extensions, and organize your library.'**
  String get aboutAppDescription;

  /// Section header for artist albums
  ///
  /// In en, this message translates to:
  /// **'Albums'**
  String get artistAlbums;

  /// Section header for singles/EPs
  ///
  /// In en, this message translates to:
  /// **'Singles & EPs'**
  String get artistSingles;

  /// Section header for compilations
  ///
  /// In en, this message translates to:
  /// **'Compilations'**
  String get artistCompilations;

  /// Section header for popular/top tracks
  ///
  /// In en, this message translates to:
  /// **'Popular'**
  String get artistPopular;

  /// Monthly listener count display
  ///
  /// In en, this message translates to:
  /// **'{count} monthly listeners'**
  String artistMonthlyListeners(String count);

  /// Metadata field - download service used
  ///
  /// In en, this message translates to:
  /// **'Service'**
  String get trackMetadataService;

  /// Action button - play track
  ///
  /// In en, this message translates to:
  /// **'Play'**
  String get trackMetadataPlay;

  /// Action button - share track
  ///
  /// In en, this message translates to:
  /// **'Share'**
  String get trackMetadataShare;

  /// Action button - delete track
  ///
  /// In en, this message translates to:
  /// **'Delete'**
  String get trackMetadataDelete;

  /// Button to request permission
  ///
  /// In en, this message translates to:
  /// **'Grant Permission'**
  String get setupGrantPermission;

  /// Skip current step button
  ///
  /// In en, this message translates to:
  /// **'Skip for now'**
  String get setupSkip;

  /// Title when storage access needed
  ///
  /// In en, this message translates to:
  /// **'Storage Access Required'**
  String get setupStorageAccessRequired;

  /// Android 11+ specific explanation
  ///
  /// In en, this message translates to:
  /// **'Android 11+ requires \"All files access\" permission to save files to your chosen download folder.'**
  String get setupStorageAccessMessageAndroid11;

  /// Button to open system settings
  ///
  /// In en, this message translates to:
  /// **'Open Settings'**
  String get setupOpenSettings;

  /// Error when permission denied
  ///
  /// In en, this message translates to:
  /// **'Permission denied. Please grant all permissions to continue.'**
  String get setupPermissionDeniedMessage;

  /// Generic permission required title
  ///
  /// In en, this message translates to:
  /// **'{permissionType} Permission Required'**
  String setupPermissionRequired(String permissionType);

  /// Generic permission required message
  ///
  /// In en, this message translates to:
  /// **'{permissionType} permission is required for the best experience. You can change this later in Settings.'**
  String setupPermissionRequiredMessage(String permissionType);

  /// Dialog title for default folder
  ///
  /// In en, this message translates to:
  /// **'Use Default Folder?'**
  String get setupUseDefaultFolder;

  /// Prompt when no folder selected
  ///
  /// In en, this message translates to:
  /// **'No folder selected. Would you like to use the default Music folder?'**
  String get setupNoFolderSelected;

  /// Button to use default folder
  ///
  /// In en, this message translates to:
  /// **'Use Default'**
  String get setupUseDefault;

  /// Download location dialog title
  ///
  /// In en, this message translates to:
  /// **'Download Location'**
  String get setupDownloadLocationTitle;

  /// iOS-specific folder info
  ///
  /// In en, this message translates to:
  /// **'On iOS, downloads are saved to the app\'s Documents folder. You can access them via the Files app.'**
  String get setupDownloadLocationIosMessage;

  /// iOS documents folder option
  ///
  /// In en, this message translates to:
  /// **'App Documents Folder'**
  String get setupAppDocumentsFolder;

  /// Subtitle for documents folder
  ///
  /// In en, this message translates to:
  /// **'Recommended - accessible via Files app'**
  String get setupAppDocumentsFolderSubtitle;

  /// iOS file picker option
  ///
  /// In en, this message translates to:
  /// **'Choose from Files'**
  String get setupChooseFromFiles;

  /// Subtitle for file picker
  ///
  /// In en, this message translates to:
  /// **'Select iCloud or other location'**
  String get setupChooseFromFilesSubtitle;

  /// iOS folder selection warning
  ///
  /// In en, this message translates to:
  /// **'iOS limitation: Empty folders cannot be selected. Choose a folder with at least one file.'**
  String get setupIosEmptyFolderWarning;

  /// Error when user selects iCloud Drive on iOS
  ///
  /// In en, this message translates to:
  /// **'iCloud Drive is not supported. Please use the app Documents folder.'**
  String get setupIcloudNotSupported;

  /// App tagline in setup
  ///
  /// In en, this message translates to:
  /// **'Download music in lossless and Hi-Res quality'**
  String get setupDownloadInFlac;

  /// Success message for storage permission
  ///
  /// In en, this message translates to:
  /// **'Storage Permission Granted!'**
  String get setupStorageGranted;

  /// Title when storage permission needed
  ///
  /// In en, this message translates to:
  /// **'Storage Permission Required'**
  String get setupStorageRequired;

  /// Explanation for storage permission
  ///
  /// In en, this message translates to:
  /// **'SpotiFLAC needs storage permission to save your downloaded music files.'**
  String get setupStorageDescription;

  /// Success message for notification permission
  ///
  /// In en, this message translates to:
  /// **'Notification Permission Granted!'**
  String get setupNotificationGranted;

  /// Button to enable notifications
  ///
  /// In en, this message translates to:
  /// **'Enable Notifications'**
  String get setupNotificationEnable;

  /// Button to choose folder
  ///
  /// In en, this message translates to:
  /// **'Choose Download Folder'**
  String get setupFolderChoose;

  /// Explanation for folder selection
  ///
  /// In en, this message translates to:
  /// **'Select a folder where your downloaded music will be saved.'**
  String get setupFolderDescription;

  /// Button to select folder
  ///
  /// In en, this message translates to:
  /// **'Select Folder'**
  String get setupSelectFolder;

  /// Button to enable notifications
  ///
  /// In en, this message translates to:
  /// **'Enable Notifications'**
  String get setupEnableNotifications;

  /// Detailed notification explanation
  ///
  /// In en, this message translates to:
  /// **'Get notified about download progress and completion. This helps you track downloads when the app is in background.'**
  String get setupNotificationBackgroundDescription;

  /// Skip button text
  ///
  /// In en, this message translates to:
  /// **'Skip for now'**
  String get setupSkipForNow;

  /// Next button text
  ///
  /// In en, this message translates to:
  /// **'Next'**
  String get setupNext;

  /// Final setup button
  ///
  /// In en, this message translates to:
  /// **'Get Started'**
  String get setupGetStarted;

  /// Instruction for file access permission
  ///
  /// In en, this message translates to:
  /// **'Please enable \"Allow access to manage all files\" in the next screen.'**
  String get setupAllowAccessToManageFiles;

  /// Title for the language selection step in setup
  ///
  /// In en, this message translates to:
  /// **'Choose Language'**
  String get setupLanguageTitle;

  /// Description for the language selection step in setup
  ///
  /// In en, this message translates to:
  /// **'Select your preferred language for the app. You can change this later in Settings.'**
  String get setupLanguageDescription;

  /// Option to use the system language
  ///
  /// In en, this message translates to:
  /// **'System Default'**
  String get setupLanguageSystemDefault;

  /// Dialog button - cancel action
  ///
  /// In en, this message translates to:
  /// **'Cancel'**
  String get dialogCancel;

  /// Dialog button - save changes
  ///
  /// In en, this message translates to:
  /// **'Save'**
  String get dialogSave;

  /// Dialog button - delete item
  ///
  /// In en, this message translates to:
  /// **'Delete'**
  String get dialogDelete;

  /// Dialog button - retry action
  ///
  /// In en, this message translates to:
  /// **'Retry'**
  String get dialogRetry;

  /// Dialog button - clear items
  ///
  /// In en, this message translates to:
  /// **'Clear'**
  String get dialogClear;

  /// Dialog button - action completed
  ///
  /// In en, this message translates to:
  /// **'Done'**
  String get dialogDone;

  /// Dialog button - import data
  ///
  /// In en, this message translates to:
  /// **'Import'**
  String get dialogImport;

  /// Confirm button in Download All dialog
  ///
  /// In en, this message translates to:
  /// **'Download'**
  String get dialogDownload;

  /// Tooltip for the button that plays a short track preview snippet
  ///
  /// In en, this message translates to:
  /// **'Play preview'**
  String get previewPlay;

  /// Tooltip for the button that stops the playing track preview snippet
  ///
  /// In en, this message translates to:
  /// **'Stop preview'**
  String get previewStop;

  /// Snackbar shown when a track preview snippet cannot be played
  ///
  /// In en, this message translates to:
  /// **'Preview unavailable'**
  String get previewUnavailable;

  /// Dialog button - discard changes
  ///
  /// In en, this message translates to:
  /// **'Discard'**
  String get dialogDiscard;

  /// Dialog button - remove item
  ///
  /// In en, this message translates to:
  /// **'Remove'**
  String get dialogRemove;

  /// Dialog button - uninstall extension
  ///
  /// In en, this message translates to:
  /// **'Uninstall'**
  String get dialogUninstall;

  /// Dialog title - unsaved changes warning
  ///
  /// In en, this message translates to:
  /// **'Discard Changes?'**
  String get dialogDiscardChanges;

  /// Dialog message - unsaved changes
  ///
  /// In en, this message translates to:
  /// **'You have unsaved changes. Do you want to discard them?'**
  String get dialogUnsavedChanges;

  /// Dialog title - clear all items
  ///
  /// In en, this message translates to:
  /// **'Clear All'**
  String get dialogClearAll;

  /// Dialog title - uninstall extension
  ///
  /// In en, this message translates to:
  /// **'Remove Extension'**
  String get dialogRemoveExtension;

  /// Dialog message - uninstall confirmation
  ///
  /// In en, this message translates to:
  /// **'Are you sure you want to remove this extension? This cannot be undone.'**
  String get dialogRemoveExtensionMessage;

  /// Dialog title - uninstall extension
  ///
  /// In en, this message translates to:
  /// **'Uninstall Extension?'**
  String get dialogUninstallExtension;

  /// Dialog message - uninstall specific extension
  ///
  /// In en, this message translates to:
  /// **'Are you sure you want to remove {extensionName}?'**
  String dialogUninstallExtensionMessage(String extensionName);

  /// Dialog title - clear download history
  ///
  /// In en, this message translates to:
  /// **'Clear History'**
  String get dialogClearHistoryTitle;

  /// Dialog message - clear history confirmation
  ///
  /// In en, this message translates to:
  /// **'Are you sure you want to clear all download history? This cannot be undone.'**
  String get dialogClearHistoryMessage;

  /// Dialog title - delete selected items
  ///
  /// In en, this message translates to:
  /// **'Delete Selected'**
  String get dialogDeleteSelectedTitle;

  /// Dialog message - delete selected tracks
  ///
  /// In en, this message translates to:
  /// **'Delete {count} {count, plural, =1{track} other{tracks}} from history?\n\nThis will also delete the files from storage.'**
  String dialogDeleteSelectedMessage(int count);

  /// Dialog title - import CSV playlist
  ///
  /// In en, this message translates to:
  /// **'Import Playlist'**
  String get dialogImportPlaylistTitle;

  /// Dialog message - import playlist confirmation
  ///
  /// In en, this message translates to:
  /// **'Found {count} tracks in the playlist file. Add them to download queue?'**
  String dialogImportPlaylistMessage(int count);

  /// Label shown in quality picker for CSV import
  ///
  /// In en, this message translates to:
  /// **'{count} tracks from CSV'**
  String csvImportTracks(int count);

  /// Tooltip on the collection screen action that exports the track list as an M3U8 playlist file
  ///
  /// In en, this message translates to:
  /// **'Export as M3U8'**
  String get collectionExportM3u;

  /// Snackbar after M3U8 export; tracks without a local file are not exported
  ///
  /// In en, this message translates to:
  /// **'Exported {exported} of {total} tracks'**
  String collectionExportM3uDone(int exported, int total);

  /// Snackbar when an M3U8 export finds no local files
  ///
  /// In en, this message translates to:
  /// **'No downloaded files to export'**
  String get collectionExportM3uNone;

  /// Snackbar when writing or sharing the M3U8 export fails
  ///
  /// In en, this message translates to:
  /// **'Export failed'**
  String get collectionExportM3uFailed;

  /// Track option and sheet title listing streaming platforms where the track can be opened
  ///
  /// In en, this message translates to:
  /// **'Open on...'**
  String get trackOpenOn;

  /// Shown in the Open on sheet when song.link returns no links
  ///
  /// In en, this message translates to:
  /// **'No platform links found for this track.'**
  String get trackOpenOnNoLinks;

  /// Library settings row opening the duplicate review sheet
  ///
  /// In en, this message translates to:
  /// **'Review duplicates'**
  String get libraryReviewDuplicates;

  /// Subtitle for the duplicate review settings row
  ///
  /// In en, this message translates to:
  /// **'Find tracks stored more than once'**
  String get libraryReviewDuplicatesSubtitle;

  /// Title of the duplicate review sheet
  ///
  /// In en, this message translates to:
  /// **'Duplicates'**
  String get duplicatesTitle;

  /// Shown when the duplicate review sheet finds nothing
  ///
  /// In en, this message translates to:
  /// **'No duplicate tracks found.'**
  String get duplicatesEmpty;

  /// Button that deletes all but the highest-quality copy in a duplicate group
  ///
  /// In en, this message translates to:
  /// **'Keep best'**
  String get duplicatesKeepBest;

  /// Confirmation message for the keep-best action
  ///
  /// In en, this message translates to:
  /// **'Delete {count} lower-quality copies of \"{trackName}\"?'**
  String duplicatesKeepBestMessage(int count, String trackName);

  /// Confirmation message for deleting one duplicate copy
  ///
  /// In en, this message translates to:
  /// **'Delete this copy of \"{trackName}\"?'**
  String duplicatesDeleteCopyMessage(String trackName);

  /// Snackbar - track added to download queue
  ///
  /// In en, this message translates to:
  /// **'Added \"{trackName}\" to queue'**
  String snackbarAddedToQueue(String trackName);

  /// Snackbar - multiple tracks added to queue
  ///
  /// In en, this message translates to:
  /// **'Added {count} tracks to queue'**
  String snackbarAddedTracksToQueue(int count);

  /// Snackbar - track already exists
  ///
  /// In en, this message translates to:
  /// **'\"{trackName}\" already downloaded'**
  String snackbarAlreadyDownloaded(String trackName);

  /// Snackbar - track already exists in local library
  ///
  /// In en, this message translates to:
  /// **'\"{trackName}\" already exists in your library'**
  String snackbarAlreadyInLibrary(String trackName);

  /// Snackbar - history deleted
  ///
  /// In en, this message translates to:
  /// **'History cleared'**
  String get snackbarHistoryCleared;

  /// Snackbar - tracks deleted
  ///
  /// In en, this message translates to:
  /// **'Deleted {count} {count, plural, =1{track} other{tracks}}'**
  String snackbarDeletedTracks(int count);

  /// Snackbar - file open error
  ///
  /// In en, this message translates to:
  /// **'Cannot open file: {error}'**
  String snackbarCannotOpenFile(String error);

  /// Snackbar action - view download queue
  ///
  /// In en, this message translates to:
  /// **'View Queue'**
  String get snackbarViewQueue;

  /// Snackbar - URL copied
  ///
  /// In en, this message translates to:
  /// **'{platform} URL copied to clipboard'**
  String snackbarUrlCopied(String platform);

  /// Snackbar - file doesn't exist
  ///
  /// In en, this message translates to:
  /// **'File not found'**
  String get snackbarFileNotFound;

  /// Snackbar - wrong file type selected
  ///
  /// In en, this message translates to:
  /// **'Please select a .spotiflac-ext file'**
  String get snackbarSelectExtFile;

  /// Snackbar - provider order saved
  ///
  /// In en, this message translates to:
  /// **'Provider priority saved'**
  String get snackbarProviderPrioritySaved;

  /// Snackbar - metadata provider order saved
  ///
  /// In en, this message translates to:
  /// **'Metadata provider priority saved'**
  String get snackbarMetadataProviderSaved;

  /// Snackbar - extension installed successfully
  ///
  /// In en, this message translates to:
  /// **'{extensionName} installed.'**
  String snackbarExtensionInstalled(String extensionName);

  /// Snackbar - extension updated successfully
  ///
  /// In en, this message translates to:
  /// **'{extensionName} updated.'**
  String snackbarExtensionUpdated(String extensionName);

  /// Snackbar - extension install error
  ///
  /// In en, this message translates to:
  /// **'Failed to install extension'**
  String get snackbarFailedToInstall;

  /// Snackbar - extension update error
  ///
  /// In en, this message translates to:
  /// **'Failed to update extension'**
  String get snackbarFailedToUpdate;

  /// Error title - too many requests
  ///
  /// In en, this message translates to:
  /// **'Rate Limited'**
  String get errorRateLimited;

  /// Error message - rate limit explanation
  ///
  /// In en, this message translates to:
  /// **'Too many requests. Please wait a moment before searching again.'**
  String get errorRateLimitedMessage;

  /// Error - search returned no results
  ///
  /// In en, this message translates to:
  /// **'No tracks found'**
  String get errorNoTracksFound;

  /// Subtitle shown under the empty search result state on the home screen
  ///
  /// In en, this message translates to:
  /// **'Try another keyword'**
  String get searchEmptyResultSubtitle;

  /// Error title - URL not handled by any extension or service
  ///
  /// In en, this message translates to:
  /// **'Link not recognized'**
  String get errorUrlNotRecognized;

  /// Error message - URL not recognized explanation
  ///
  /// In en, this message translates to:
  /// **'This link is not supported. Make sure the URL is correct and a compatible extension is installed.'**
  String get errorUrlNotRecognizedMessage;

  /// Error message - generic URL fetch failure
  ///
  /// In en, this message translates to:
  /// **'Failed to load content from this link. Please try again.'**
  String get errorUrlFetchFailed;

  /// Error - extension source not available
  ///
  /// In en, this message translates to:
  /// **'Cannot load {item}: missing extension source'**
  String errorMissingExtensionSource(String item);

  /// Action button - pause download
  ///
  /// In en, this message translates to:
  /// **'Pause'**
  String get actionPause;

  /// Action button - resume download
  ///
  /// In en, this message translates to:
  /// **'Resume'**
  String get actionResume;

  /// Action button - cancel operation
  ///
  /// In en, this message translates to:
  /// **'Cancel'**
  String get actionCancel;

  /// Action button - select all items
  ///
  /// In en, this message translates to:
  /// **'Select All'**
  String get actionSelectAll;

  /// Action button - deselect all
  ///
  /// In en, this message translates to:
  /// **'Deselect'**
  String get actionDeselect;

  /// Selection count indicator
  ///
  /// In en, this message translates to:
  /// **'{count} selected'**
  String selectionSelected(int count);

  /// Status - all items selected
  ///
  /// In en, this message translates to:
  /// **'All tracks selected'**
  String get selectionAllSelected;

  /// Placeholder when nothing selected
  ///
  /// In en, this message translates to:
  /// **'Select tracks to delete'**
  String get selectionSelectToDelete;

  /// Progress indicator - loading track info
  ///
  /// In en, this message translates to:
  /// **'Fetching metadata... {current}/{total}'**
  String progressFetchingMetadata(int current, int total);

  /// Progress indicator - parsing CSV file
  ///
  /// In en, this message translates to:
  /// **'Reading CSV...'**
  String get progressReadingCsv;

  /// Search result category - songs
  ///
  /// In en, this message translates to:
  /// **'Songs'**
  String get searchSongs;

  /// Search result category - artists
  ///
  /// In en, this message translates to:
  /// **'Artists'**
  String get searchArtists;

  /// Search result category - albums
  ///
  /// In en, this message translates to:
  /// **'Albums'**
  String get searchAlbums;

  /// Search result category - playlists
  ///
  /// In en, this message translates to:
  /// **'Playlists'**
  String get searchPlaylists;

  /// Bottom sheet title for search sort options
  ///
  /// In en, this message translates to:
  /// **'Sort Results'**
  String get searchSortTitle;

  /// Sort option - default API order
  ///
  /// In en, this message translates to:
  /// **'Default'**
  String get searchSortDefault;

  /// Sort option - title ascending
  ///
  /// In en, this message translates to:
  /// **'Title (A-Z)'**
  String get searchSortTitleAZ;

  /// Sort option - title descending
  ///
  /// In en, this message translates to:
  /// **'Title (Z-A)'**
  String get searchSortTitleZA;

  /// Sort option - artist ascending
  ///
  /// In en, this message translates to:
  /// **'Artist (A-Z)'**
  String get searchSortArtistAZ;

  /// Sort option - artist descending
  ///
  /// In en, this message translates to:
  /// **'Artist (Z-A)'**
  String get searchSortArtistZA;

  /// Sort option - shortest duration first
  ///
  /// In en, this message translates to:
  /// **'Duration (Shortest)'**
  String get searchSortDurationShort;

  /// Sort option - longest duration first
  ///
  /// In en, this message translates to:
  /// **'Duration (Longest)'**
  String get searchSortDurationLong;

  /// Sort option - oldest release first
  ///
  /// In en, this message translates to:
  /// **'Release Date (Oldest)'**
  String get searchSortDateOldest;

  /// Sort option - newest release first
  ///
  /// In en, this message translates to:
  /// **'Release Date (Newest)'**
  String get searchSortDateNewest;

  /// Tooltip - play button
  ///
  /// In en, this message translates to:
  /// **'Play'**
  String get tooltipPlay;

  /// Setting title - filename pattern
  ///
  /// In en, this message translates to:
  /// **'Filename Format'**
  String get filenameFormat;

  /// Toggle label for showing advanced filename tags
  ///
  /// In en, this message translates to:
  /// **'Show advanced tags'**
  String get filenameShowAdvancedTags;

  /// Description for advanced filename tag toggle
  ///
  /// In en, this message translates to:
  /// **'Enable formatted tags for track padding and date patterns'**
  String get filenameShowAdvancedTagsDescription;

  /// Folder option - flat structure
  ///
  /// In en, this message translates to:
  /// **'No organization'**
  String get folderOrganizationNone;

  /// Folder option - playlist folders
  ///
  /// In en, this message translates to:
  /// **'By Playlist'**
  String get folderOrganizationByPlaylist;

  /// Subtitle for playlist folder option
  ///
  /// In en, this message translates to:
  /// **'Separate folder for each playlist'**
  String get folderOrganizationByPlaylistSubtitle;

  /// Folder option - artist folders
  ///
  /// In en, this message translates to:
  /// **'By Artist'**
  String get folderOrganizationByArtist;

  /// Folder option - album folders
  ///
  /// In en, this message translates to:
  /// **'By Album'**
  String get folderOrganizationByAlbum;

  /// Folder option - nested folders
  ///
  /// In en, this message translates to:
  /// **'Artist/Album'**
  String get folderOrganizationByArtistAlbum;

  /// Folder organization sheet description
  ///
  /// In en, this message translates to:
  /// **'Organize downloaded files into folders'**
  String get folderOrganizationDescription;

  /// Subtitle for no organization option
  ///
  /// In en, this message translates to:
  /// **'All files in download folder'**
  String get folderOrganizationNoneSubtitle;

  /// Subtitle for artist folder option
  ///
  /// In en, this message translates to:
  /// **'Separate folder for each artist'**
  String get folderOrganizationByArtistSubtitle;

  /// Subtitle for album folder option
  ///
  /// In en, this message translates to:
  /// **'Separate folder for each album'**
  String get folderOrganizationByAlbumSubtitle;

  /// Subtitle for nested folder option
  ///
  /// In en, this message translates to:
  /// **'Nested folders for artist and album'**
  String get folderOrganizationByArtistAlbumSubtitle;

  /// Update dialog title
  ///
  /// In en, this message translates to:
  /// **'Update Available'**
  String get updateAvailable;

  /// Update button - dismiss
  ///
  /// In en, this message translates to:
  /// **'Later'**
  String get updateLater;

  /// Update status - initializing
  ///
  /// In en, this message translates to:
  /// **'Starting download...'**
  String get updateStartingDownload;

  /// Update error title
  ///
  /// In en, this message translates to:
  /// **'Download failed'**
  String get updateDownloadFailed;

  /// Update error message
  ///
  /// In en, this message translates to:
  /// **'Failed to download update'**
  String get updateFailedMessage;

  /// Update subtitle
  ///
  /// In en, this message translates to:
  /// **'A new version is ready'**
  String get updateNewVersionReady;

  /// Title of the mandatory update dialog shown when the installed version is too old
  ///
  /// In en, this message translates to:
  /// **'Update required'**
  String get updateRequiredTitle;

  /// Subtitle of the mandatory update dialog; explains why the dialog cannot be dismissed
  ///
  /// In en, this message translates to:
  /// **'This version is {count} releases behind and is no longer supported. Update to keep using the app.'**
  String updateRequiredNotice(int count);

  /// Label for current version
  ///
  /// In en, this message translates to:
  /// **'Current'**
  String get updateCurrent;

  /// Label for new version
  ///
  /// In en, this message translates to:
  /// **'New'**
  String get updateNew;

  /// Update status - downloading
  ///
  /// In en, this message translates to:
  /// **'Downloading...'**
  String get updateDownloading;

  /// Changelog section title
  ///
  /// In en, this message translates to:
  /// **'What\'s New'**
  String get updateWhatsNew;

  /// Update button - download and install
  ///
  /// In en, this message translates to:
  /// **'Download & Install'**
  String get updateDownloadInstall;

  /// Update button - skip this version
  ///
  /// In en, this message translates to:
  /// **'Don\'t remind'**
  String get updateDontRemind;

  /// Provider priority page title
  ///
  /// In en, this message translates to:
  /// **'Provider Priority'**
  String get providerPriorityTitle;

  /// Provider priority page description
  ///
  /// In en, this message translates to:
  /// **'Drag to reorder download providers. The app will try providers from top to bottom when downloading tracks.'**
  String get providerPriorityDescription;

  /// Info tip about fallback behavior
  ///
  /// In en, this message translates to:
  /// **'If a track is not available on the first provider, the app will automatically try the next one.'**
  String get providerPriorityInfo;

  /// Section description for extension fallback selection
  ///
  /// In en, this message translates to:
  /// **'Choose which installed download extensions can be used during automatic fallback.'**
  String get providerPriorityFallbackExtensionsDescription;

  /// Hint below the extension fallback selection list
  ///
  /// In en, this message translates to:
  /// **'Only enabled extensions with download-provider capability are listed here.'**
  String get providerPriorityFallbackExtensionsHint;

  /// Label for extension-provided providers
  ///
  /// In en, this message translates to:
  /// **'Extension'**
  String get providerExtension;

  /// Metadata priority page title
  ///
  /// In en, this message translates to:
  /// **'Metadata Priority'**
  String get metadataProviderPriorityTitle;

  /// Metadata priority page description
  ///
  /// In en, this message translates to:
  /// **'Drag to reorder metadata providers. The app will try providers from top to bottom when searching for tracks and fetching metadata.'**
  String get metadataProviderPriorityDescription;

  /// Info tip about rate limits
  ///
  /// In en, this message translates to:
  /// **'Deezer has no rate limits and is recommended as primary. Spotify may rate limit after many requests.'**
  String get metadataProviderPriorityInfo;

  /// Logs screen title
  ///
  /// In en, this message translates to:
  /// **'Logs'**
  String get logTitle;

  /// Snackbar - logs copied
  ///
  /// In en, this message translates to:
  /// **'Logs copied to clipboard'**
  String get logCopied;

  /// Log search placeholder
  ///
  /// In en, this message translates to:
  /// **'Search logs...'**
  String get logSearchHint;

  /// Filter by log level
  ///
  /// In en, this message translates to:
  /// **'Level'**
  String get logFilterLevel;

  /// Filter section title
  ///
  /// In en, this message translates to:
  /// **'Filter'**
  String get logFilterSection;

  /// Share button tooltip
  ///
  /// In en, this message translates to:
  /// **'Share logs'**
  String get logShareLogs;

  /// Clear button tooltip
  ///
  /// In en, this message translates to:
  /// **'Clear logs'**
  String get logClearLogs;

  /// Clear logs dialog title
  ///
  /// In en, this message translates to:
  /// **'Clear Logs'**
  String get logClearLogsTitle;

  /// Clear logs confirmation message
  ///
  /// In en, this message translates to:
  /// **'Are you sure you want to clear all logs?'**
  String get logClearLogsMessage;

  /// Filter dialog title
  ///
  /// In en, this message translates to:
  /// **'Filter logs by severity'**
  String get logFilterBySeverity;

  /// Empty state title
  ///
  /// In en, this message translates to:
  /// **'No logs yet'**
  String get logNoLogsYet;

  /// Empty state subtitle
  ///
  /// In en, this message translates to:
  /// **'Logs will appear here as you use the app'**
  String get logNoLogsYetSubtitle;

  /// Log count with filter active
  ///
  /// In en, this message translates to:
  /// **'Entries ({count} filtered)'**
  String logEntriesFiltered(int count);

  /// Total log count
  ///
  /// In en, this message translates to:
  /// **'Entries ({count})'**
  String logEntries(int count);

  /// Update channel - stable releases
  ///
  /// In en, this message translates to:
  /// **'Stable'**
  String get channelStable;

  /// Update channel - beta/preview releases
  ///
  /// In en, this message translates to:
  /// **'Preview'**
  String get channelPreview;

  /// Settings section header
  ///
  /// In en, this message translates to:
  /// **'Search Source'**
  String get sectionSearchSource;

  /// Settings section header
  ///
  /// In en, this message translates to:
  /// **'Download'**
  String get sectionDownload;

  /// Settings section header
  ///
  /// In en, this message translates to:
  /// **'Performance'**
  String get sectionPerformance;

  /// Settings section header
  ///
  /// In en, this message translates to:
  /// **'App'**
  String get sectionApp;

  /// Settings section header
  ///
  /// In en, this message translates to:
  /// **'Data'**
  String get sectionData;

  /// Settings section header
  ///
  /// In en, this message translates to:
  /// **'Debug'**
  String get sectionDebug;

  /// Settings section header
  ///
  /// In en, this message translates to:
  /// **'Service'**
  String get sectionService;

  /// Settings section header
  ///
  /// In en, this message translates to:
  /// **'Audio Quality'**
  String get sectionAudioQuality;

  /// Settings section header
  ///
  /// In en, this message translates to:
  /// **'File Settings'**
  String get sectionFileSettings;

  /// Settings section header
  ///
  /// In en, this message translates to:
  /// **'Lyrics'**
  String get sectionLyrics;

  /// Setting - how to save lyrics
  ///
  /// In en, this message translates to:
  /// **'Lyrics Mode'**
  String get lyricsMode;

  /// Lyrics mode picker description
  ///
  /// In en, this message translates to:
  /// **'Choose how lyrics are saved with your downloads'**
  String get lyricsModeDescription;

  /// Lyrics mode option - embed in audio file
  ///
  /// In en, this message translates to:
  /// **'Embed in file'**
  String get lyricsModeEmbed;

  /// Subtitle for embed option
  ///
  /// In en, this message translates to:
  /// **'Lyrics stored inside FLAC metadata'**
  String get lyricsModeEmbedSubtitle;

  /// Lyrics mode option - separate LRC file
  ///
  /// In en, this message translates to:
  /// **'External .lrc file'**
  String get lyricsModeExternal;

  /// Subtitle for external option
  ///
  /// In en, this message translates to:
  /// **'Separate .lrc file for players like Samsung Music'**
  String get lyricsModeExternalSubtitle;

  /// Lyrics mode option - embed and external
  ///
  /// In en, this message translates to:
  /// **'Both'**
  String get lyricsModeBoth;

  /// Subtitle for both option
  ///
  /// In en, this message translates to:
  /// **'Embed and save .lrc file'**
  String get lyricsModeBothSubtitle;

  /// Settings section header
  ///
  /// In en, this message translates to:
  /// **'Color'**
  String get sectionColor;

  /// Settings section header
  ///
  /// In en, this message translates to:
  /// **'Theme'**
  String get sectionTheme;

  /// Settings section header
  ///
  /// In en, this message translates to:
  /// **'Layout'**
  String get sectionLayout;

  /// Settings section header for language
  ///
  /// In en, this message translates to:
  /// **'Language'**
  String get sectionLanguage;

  /// Language setting title
  ///
  /// In en, this message translates to:
  /// **'App Language'**
  String get appearanceLanguage;

  /// Appearance settings description
  ///
  /// In en, this message translates to:
  /// **'Theme, colors, display'**
  String get settingsAppearanceSubtitle;

  /// Download settings description
  ///
  /// In en, this message translates to:
  /// **'Service, quality, fallback'**
  String get settingsDownloadSubtitle;

  /// Extensions settings description
  ///
  /// In en, this message translates to:
  /// **'Manage download providers'**
  String get settingsExtensionsSubtitle;

  /// Logs settings description
  ///
  /// In en, this message translates to:
  /// **'View app logs for debugging'**
  String get settingsLogsSubtitle;

  /// Status when opening shared URL
  ///
  /// In en, this message translates to:
  /// **'Loading shared link...'**
  String get loadingSharedLink;

  /// Exit confirmation message
  ///
  /// In en, this message translates to:
  /// **'Press back again to exit'**
  String get pressBackAgainToExit;

  /// Download all button with count
  ///
  /// In en, this message translates to:
  /// **'Download All ({count})'**
  String downloadAllCount(int count);

  /// Track count display
  ///
  /// In en, this message translates to:
  /// **'{count, plural, =1{1 track} other{{count} tracks}}'**
  String tracksCount(int count);

  /// Action - copy file path
  ///
  /// In en, this message translates to:
  /// **'Copy file path'**
  String get trackCopyFilePath;

  /// Action - delete downloaded file
  ///
  /// In en, this message translates to:
  /// **'Remove from device'**
  String get trackRemoveFromDevice;

  /// Action - fetch lyrics
  ///
  /// In en, this message translates to:
  /// **'Load Lyrics'**
  String get trackLoadLyrics;

  /// Tab title - track metadata
  ///
  /// In en, this message translates to:
  /// **'Metadata'**
  String get trackMetadata;

  /// Tab title - file information
  ///
  /// In en, this message translates to:
  /// **'File Info'**
  String get trackFileInfo;

  /// Tab title - lyrics
  ///
  /// In en, this message translates to:
  /// **'Lyrics'**
  String get trackLyrics;

  /// Error - file doesn't exist
  ///
  /// In en, this message translates to:
  /// **'File not found'**
  String get trackFileNotFound;

  /// Action - open track in Deezer app
  ///
  /// In en, this message translates to:
  /// **'Open in Deezer'**
  String get trackOpenInDeezer;

  /// Action - open track in Spotify app
  ///
  /// In en, this message translates to:
  /// **'Open in Spotify'**
  String get trackOpenInSpotify;

  /// Metadata label - track title
  ///
  /// In en, this message translates to:
  /// **'Track name'**
  String get trackTrackName;

  /// Metadata label - artist name
  ///
  /// In en, this message translates to:
  /// **'Artist'**
  String get trackArtist;

  /// Metadata label - album artist
  ///
  /// In en, this message translates to:
  /// **'Album artist'**
  String get trackAlbumArtist;

  /// Metadata label - album name
  ///
  /// In en, this message translates to:
  /// **'Album'**
  String get trackAlbum;

  /// Metadata label - track number
  ///
  /// In en, this message translates to:
  /// **'Track number'**
  String get trackTrackNumber;

  /// Metadata label - disc number
  ///
  /// In en, this message translates to:
  /// **'Disc number'**
  String get trackDiscNumber;

  /// Metadata label - track length
  ///
  /// In en, this message translates to:
  /// **'Duration'**
  String get trackDuration;

  /// Metadata label - audio quality
  ///
  /// In en, this message translates to:
  /// **'Audio quality'**
  String get trackAudioQuality;

  /// Metadata label - release date
  ///
  /// In en, this message translates to:
  /// **'Release date'**
  String get trackReleaseDate;

  /// Metadata label - music genre
  ///
  /// In en, this message translates to:
  /// **'Genre'**
  String get trackGenre;

  /// Metadata label - record label
  ///
  /// In en, this message translates to:
  /// **'Label'**
  String get trackLabel;

  /// Metadata label - copyright information
  ///
  /// In en, this message translates to:
  /// **'Copyright'**
  String get trackCopyright;

  /// Metadata label - download date
  ///
  /// In en, this message translates to:
  /// **'Downloaded'**
  String get trackDownloaded;

  /// Action - copy lyrics to clipboard
  ///
  /// In en, this message translates to:
  /// **'Copy lyrics'**
  String get trackCopyLyrics;

  /// Label showing the lyrics source/provider
  ///
  /// In en, this message translates to:
  /// **'Source: {source}'**
  String trackLyricsSource(String source);

  /// Message when lyrics not found
  ///
  /// In en, this message translates to:
  /// **'Lyrics not available for this track'**
  String get trackLyricsNotAvailable;

  /// Message when no embedded lyrics in audio file
  ///
  /// In en, this message translates to:
  /// **'No lyrics found in this file'**
  String get trackLyricsNotInFile;

  /// Action - fetch lyrics from online providers
  ///
  /// In en, this message translates to:
  /// **'Fetch from Online'**
  String get trackFetchOnlineLyrics;

  /// Message when lyrics request times out
  ///
  /// In en, this message translates to:
  /// **'Request timed out. Try again later.'**
  String get trackLyricsTimeout;

  /// Message when lyrics loading fails
  ///
  /// In en, this message translates to:
  /// **'Failed to load lyrics'**
  String get trackLyricsLoadFailed;

  /// Action - embed lyrics into audio file
  ///
  /// In en, this message translates to:
  /// **'Embed Lyrics'**
  String get trackEmbedLyrics;

  /// Snackbar - lyrics saved to file
  ///
  /// In en, this message translates to:
  /// **'Lyrics embedded successfully'**
  String get trackLyricsEmbedded;

  /// Message when track is instrumental (no lyrics)
  ///
  /// In en, this message translates to:
  /// **'Instrumental track'**
  String get trackInstrumental;

  /// Snackbar - content copied
  ///
  /// In en, this message translates to:
  /// **'Copied to clipboard'**
  String get trackCopiedToClipboard;

  /// Delete confirmation title
  ///
  /// In en, this message translates to:
  /// **'Remove from device?'**
  String get trackDeleteConfirmTitle;

  /// Delete confirmation message
  ///
  /// In en, this message translates to:
  /// **'This will permanently delete the downloaded file and remove it from your history.'**
  String get trackDeleteConfirmMessage;

  /// Relative date - today
  ///
  /// In en, this message translates to:
  /// **'Today'**
  String get dateToday;

  /// Relative date - yesterday
  ///
  /// In en, this message translates to:
  /// **'Yesterday'**
  String get dateYesterday;

  /// Relative date - days ago
  ///
  /// In en, this message translates to:
  /// **'{count} days ago'**
  String dateDaysAgo(int count);

  /// Relative date - weeks ago
  ///
  /// In en, this message translates to:
  /// **'{count} weeks ago'**
  String dateWeeksAgo(int count);

  /// Relative date - months ago
  ///
  /// In en, this message translates to:
  /// **'{count} months ago'**
  String dateMonthsAgo(int count);

  /// Repo filter - all extensions
  ///
  /// In en, this message translates to:
  /// **'All'**
  String get storeFilterAll;

  /// Repo filter - metadata providers
  ///
  /// In en, this message translates to:
  /// **'Metadata'**
  String get storeFilterMetadata;

  /// Repo filter - download providers
  ///
  /// In en, this message translates to:
  /// **'Download'**
  String get storeFilterDownload;

  /// Repo filter - utility extensions
  ///
  /// In en, this message translates to:
  /// **'Utility'**
  String get storeFilterUtility;

  /// Repo filter - lyrics providers
  ///
  /// In en, this message translates to:
  /// **'Lyrics'**
  String get storeFilterLyrics;

  /// Repo filter - integrations
  ///
  /// In en, this message translates to:
  /// **'Integration'**
  String get storeFilterIntegration;

  /// Button to clear all filters
  ///
  /// In en, this message translates to:
  /// **'Clear filters'**
  String get storeClearFilters;

  /// Store setup screen - heading when no repo is configured
  ///
  /// In en, this message translates to:
  /// **'Add Extension Repository'**
  String get storeAddRepoTitle;

  /// Store setup screen - explanatory text
  ///
  /// In en, this message translates to:
  /// **'Enter a GitHub repository URL that contains a registry.json file to browse and install extensions.'**
  String get storeAddRepoDescription;

  /// Label for the repository URL input field
  ///
  /// In en, this message translates to:
  /// **'Repository URL'**
  String get storeRepoUrlLabel;

  /// Hint/placeholder for the repository URL input field
  ///
  /// In en, this message translates to:
  /// **'https://github.com/user/repo'**
  String get storeRepoUrlHint;

  /// Button to submit a new repository URL
  ///
  /// In en, this message translates to:
  /// **'Add Repository'**
  String get storeAddRepoButton;

  /// Tooltip for the change-repository icon button in the app bar
  ///
  /// In en, this message translates to:
  /// **'Change repository'**
  String get storeChangeRepoTooltip;

  /// Title of the change/remove repository dialog
  ///
  /// In en, this message translates to:
  /// **'Extension Repository'**
  String get storeRepoDialogTitle;

  /// Label shown above the current repository URL in the dialog
  ///
  /// In en, this message translates to:
  /// **'Current repository:'**
  String get storeRepoDialogCurrent;

  /// Label for the new repository URL field inside the dialog
  ///
  /// In en, this message translates to:
  /// **'New Repository URL'**
  String get storeNewRepoUrlLabel;

  /// Error heading when the store cannot be loaded
  ///
  /// In en, this message translates to:
  /// **'Failed to load repository'**
  String get storeLoadError;

  /// Message when store has no extensions
  ///
  /// In en, this message translates to:
  /// **'No extensions available'**
  String get storeEmptyNoExtensions;

  /// Message when search/filter returns no results
  ///
  /// In en, this message translates to:
  /// **'No extensions found'**
  String get storeEmptyNoResults;

  /// Extension detail - unique ID
  ///
  /// In en, this message translates to:
  /// **'ID'**
  String get extensionId;

  /// Extension detail - error message
  ///
  /// In en, this message translates to:
  /// **'Error'**
  String get extensionError;

  /// Section header - extension features
  ///
  /// In en, this message translates to:
  /// **'Capabilities'**
  String get extensionCapabilities;

  /// Capability - provides metadata
  ///
  /// In en, this message translates to:
  /// **'Metadata Provider'**
  String get extensionMetadataProvider;

  /// Capability - provides downloads
  ///
  /// In en, this message translates to:
  /// **'Download Provider'**
  String get extensionDownloadProvider;

  /// Capability - provides lyrics
  ///
  /// In en, this message translates to:
  /// **'Lyrics Provider'**
  String get extensionLyricsProvider;

  /// Capability - handles URLs
  ///
  /// In en, this message translates to:
  /// **'URL Handler'**
  String get extensionUrlHandler;

  /// Capability - quality selection
  ///
  /// In en, this message translates to:
  /// **'Quality Options'**
  String get extensionQualityOptions;

  /// Capability - post-processing
  ///
  /// In en, this message translates to:
  /// **'Post-Processing Hooks'**
  String get extensionPostProcessingHooks;

  /// Section header - required permissions
  ///
  /// In en, this message translates to:
  /// **'Permissions'**
  String get extensionPermissions;

  /// Section header - extension settings
  ///
  /// In en, this message translates to:
  /// **'Settings'**
  String get extensionSettings;

  /// Button to uninstall extension
  ///
  /// In en, this message translates to:
  /// **'Remove Extension'**
  String get extensionRemoveButton;

  /// Extension detail - last update
  ///
  /// In en, this message translates to:
  /// **'Updated'**
  String get extensionUpdated;

  /// Extension detail - minimum app version
  ///
  /// In en, this message translates to:
  /// **'Min App Version'**
  String get extensionMinAppVersion;

  /// Capability - custom track matching algorithm
  ///
  /// In en, this message translates to:
  /// **'Custom Track Matching'**
  String get extensionCustomTrackMatching;

  /// Capability - post-download processing
  ///
  /// In en, this message translates to:
  /// **'Post-Processing'**
  String get extensionPostProcessing;

  /// Post-processing hooks count
  ///
  /// In en, this message translates to:
  /// **'{count} hook(s) available'**
  String extensionHooksAvailable(int count);

  /// URL patterns count
  ///
  /// In en, this message translates to:
  /// **'{count} pattern(s)'**
  String extensionPatternsCount(int count);

  /// Track matching strategy name
  ///
  /// In en, this message translates to:
  /// **'Strategy: {strategy}'**
  String extensionStrategy(String strategy);

  /// Section header - provider priority
  ///
  /// In en, this message translates to:
  /// **'Provider Priority'**
  String get extensionsProviderPrioritySection;

  /// Section header - installed extensions
  ///
  /// In en, this message translates to:
  /// **'Installed Extensions'**
  String get extensionsInstalledSection;

  /// Empty state - no extensions
  ///
  /// In en, this message translates to:
  /// **'No extensions installed'**
  String get extensionsNoExtensions;

  /// Empty state subtitle
  ///
  /// In en, this message translates to:
  /// **'Install .spotiflac-ext files to add new providers'**
  String get extensionsNoExtensionsSubtitle;

  /// Button to install extension from file
  ///
  /// In en, this message translates to:
  /// **'Install Extension'**
  String get extensionsInstallButton;

  /// Security warning about extensions
  ///
  /// In en, this message translates to:
  /// **'Extensions can add new metadata and download providers. Only install extensions from trusted sources.'**
  String get extensionsInfoTip;

  /// Success message after install
  ///
  /// In en, this message translates to:
  /// **'Extension installed successfully'**
  String get extensionsInstalledSuccess;

  /// Success message after installing multiple extensions
  ///
  /// In en, this message translates to:
  /// **'{count} extensions installed successfully'**
  String extensionsInstalledCount(int count);

  /// Message when installing multiple extensions partially succeeds
  ///
  /// In en, this message translates to:
  /// **'Installed {installed} of {attempted} extensions'**
  String extensionsInstallPartialSuccess(int installed, int attempted);

  /// Setting - download provider order
  ///
  /// In en, this message translates to:
  /// **'Download Priority'**
  String get extensionsDownloadPriority;

  /// Subtitle for download priority
  ///
  /// In en, this message translates to:
  /// **'Set download service order'**
  String get extensionsDownloadPrioritySubtitle;

  /// Setting and page title for choosing which download extensions can be used during fallback
  ///
  /// In en, this message translates to:
  /// **'Fallback Extensions'**
  String get extensionsFallbackTitle;

  /// Subtitle for download fallback extensions menu
  ///
  /// In en, this message translates to:
  /// **'Choose which installed download extensions can be used as fallback'**
  String get extensionsFallbackSubtitle;

  /// Empty state - no download providers
  ///
  /// In en, this message translates to:
  /// **'No extensions with download provider'**
  String get extensionsNoDownloadProvider;

  /// Setting - metadata provider order
  ///
  /// In en, this message translates to:
  /// **'Metadata Priority'**
  String get extensionsMetadataPriority;

  /// Subtitle for metadata priority
  ///
  /// In en, this message translates to:
  /// **'Set search & metadata source order'**
  String get extensionsMetadataPrioritySubtitle;

  /// Empty state - no metadata providers
  ///
  /// In en, this message translates to:
  /// **'No extensions with metadata provider'**
  String get extensionsNoMetadataProvider;

  /// Setting - search provider selection
  ///
  /// In en, this message translates to:
  /// **'Search Provider'**
  String get extensionsSearchProvider;

  /// Empty state - no search providers
  ///
  /// In en, this message translates to:
  /// **'No extensions with custom search'**
  String get extensionsNoCustomSearch;

  /// Search provider setting description
  ///
  /// In en, this message translates to:
  /// **'Choose which service to use for searching tracks'**
  String get extensionsSearchProviderDescription;

  /// Label for custom search provider
  ///
  /// In en, this message translates to:
  /// **'Custom search'**
  String get extensionsCustomSearch;

  /// Error message when extension fails to load
  ///
  /// In en, this message translates to:
  /// **'Error loading extension'**
  String get extensionsErrorLoading;

  /// Quality option - CD quality FLAC
  ///
  /// In en, this message translates to:
  /// **'FLAC Lossless'**
  String get qualityFlacLossless;

  /// Technical spec for lossless
  ///
  /// In en, this message translates to:
  /// **'16-bit / 44.1kHz'**
  String get qualityFlacLosslessSubtitle;

  /// Quality option - high resolution FLAC
  ///
  /// In en, this message translates to:
  /// **'Hi-Res FLAC'**
  String get qualityHiResFlac;

  /// Technical spec for hi-res
  ///
  /// In en, this message translates to:
  /// **'24-bit / up to 96kHz'**
  String get qualityHiResFlacSubtitle;

  /// Quality option - maximum resolution FLAC
  ///
  /// In en, this message translates to:
  /// **'Hi-Res FLAC Max'**
  String get qualityHiResFlacMax;

  /// Technical spec for hi-res max
  ///
  /// In en, this message translates to:
  /// **'24-bit / up to 192kHz'**
  String get qualityHiResFlacMaxSubtitle;

  /// Quality option label for lossy 320kbps
  ///
  /// In en, this message translates to:
  /// **'Lossy 320kbps'**
  String get downloadLossy320;

  /// Setting title to pick output format for lossy downloads
  ///
  /// In en, this message translates to:
  /// **'Lossy Format'**
  String get downloadLossyFormat;

  /// Toggle for automatic post-download audio conversion
  ///
  /// In en, this message translates to:
  /// **'Auto-convert after download'**
  String get downloadAutoConvert;

  /// Explanation of safe automatic post-download conversion
  ///
  /// In en, this message translates to:
  /// **'Convert completed downloads to a smaller lossy format. The original is replaced only after conversion succeeds.'**
  String get downloadAutoConvertSubtitle;

  /// Automatic conversion output format setting
  ///
  /// In en, this message translates to:
  /// **'Output format'**
  String get downloadAutoConvertFormat;

  /// Automatic conversion format picker explanation
  ///
  /// In en, this message translates to:
  /// **'Choose the lossy format used for newly completed downloads.'**
  String get downloadAutoConvertFormatSubtitle;

  /// Automatic conversion bitrate setting
  ///
  /// In en, this message translates to:
  /// **'Output quality'**
  String get downloadAutoConvertBitrate;

  /// Automatic conversion bitrate picker explanation
  ///
  /// In en, this message translates to:
  /// **'Higher bitrates preserve more detail but create larger files.'**
  String get downloadAutoConvertBitrateSubtitle;

  /// MP3 automatic conversion option description
  ///
  /// In en, this message translates to:
  /// **'Best compatibility across players and devices'**
  String get downloadAutoConvertMp3Subtitle;

  /// M4A AAC automatic conversion option description
  ///
  /// In en, this message translates to:
  /// **'Efficient AAC audio in an M4A container'**
  String get downloadAutoConvertM4aSubtitle;

  /// Opus automatic conversion option description
  ///
  /// In en, this message translates to:
  /// **'Best efficiency for modern players'**
  String get downloadAutoConvertOpusSubtitle;

  /// Title of the lossy format picker bottom sheet
  ///
  /// In en, this message translates to:
  /// **'Lossy 320kbps Format'**
  String get downloadLossy320Format;

  /// Description in the lossy format picker
  ///
  /// In en, this message translates to:
  /// **'Choose the output format for 320kbps lossy downloads. The original stream will be converted to your selected format when needed.'**
  String get downloadLossy320FormatDesc;

  /// Lossy format option - MP3 320kbps
  ///
  /// In en, this message translates to:
  /// **'MP3 320kbps'**
  String get downloadLossyMp3;

  /// Subtitle for MP3 320kbps lossy option
  ///
  /// In en, this message translates to:
  /// **'Best compatibility, ~10MB per track'**
  String get downloadLossyMp3Subtitle;

  /// Lossy format option - AAC in M4A container at 320kbps
  ///
  /// In en, this message translates to:
  /// **'AAC/M4A 320kbps'**
  String get downloadLossyAac;

  /// Subtitle for AAC/M4A 320kbps lossy option
  ///
  /// In en, this message translates to:
  /// **'Best mobile compatibility, M4A container'**
  String get downloadLossyAacSubtitle;

  /// Lossy format option - Opus 256kbps
  ///
  /// In en, this message translates to:
  /// **'Opus 256kbps'**
  String get downloadLossyOpus256;

  /// Subtitle for Opus 256kbps lossy option
  ///
  /// In en, this message translates to:
  /// **'Best quality Opus, ~8MB per track'**
  String get downloadLossyOpus256Subtitle;

  /// Lossy format option - Opus 128kbps
  ///
  /// In en, this message translates to:
  /// **'Opus 128kbps'**
  String get downloadLossyOpus128;

  /// Subtitle for Opus 128kbps lossy option
  ///
  /// In en, this message translates to:
  /// **'Smallest size, ~4MB per track'**
  String get downloadLossyOpus128Subtitle;

  /// Setting - show quality picker
  ///
  /// In en, this message translates to:
  /// **'Ask Before Download'**
  String get downloadAskBeforeDownload;

  /// Setting - download folder
  ///
  /// In en, this message translates to:
  /// **'Download Directory'**
  String get downloadDirectory;

  /// Setting - separate folder for singles
  ///
  /// In en, this message translates to:
  /// **'Separate Singles Folder'**
  String get downloadSeparateSinglesFolder;

  /// Setting - album folder organization
  ///
  /// In en, this message translates to:
  /// **'Album Folder Structure'**
  String get downloadAlbumFolderStructure;

  /// Album folder structure picker description
  ///
  /// In en, this message translates to:
  /// **'Choose how album folders are structured'**
  String get albumFolderStructureDescription;

  /// Setting - choose whether artist folders use Album Artist or Track Artist
  ///
  /// In en, this message translates to:
  /// **'Use Album Artist for folders'**
  String get downloadUseAlbumArtistForFolders;

  /// Setting - strip featured artists from folder name
  ///
  /// In en, this message translates to:
  /// **'Primary artist only for folders'**
  String get downloadUsePrimaryArtistOnly;

  /// Subtitle when primary artist only is enabled
  ///
  /// In en, this message translates to:
  /// **'Featured artists removed from folder name (e.g. Justin Bieber, Quavo → Justin Bieber)'**
  String get downloadUsePrimaryArtistOnlyEnabled;

  /// Subtitle when primary artist only is disabled
  ///
  /// In en, this message translates to:
  /// **'Full artist string used for folder name'**
  String get downloadUsePrimaryArtistOnlyDisabled;

  /// Dialog title - choose audio quality
  ///
  /// In en, this message translates to:
  /// **'Select Quality'**
  String get downloadSelectQuality;

  /// Label - download source
  ///
  /// In en, this message translates to:
  /// **'Download From'**
  String get downloadFrom;

  /// Theme option - pure black
  ///
  /// In en, this message translates to:
  /// **'AMOLED Dark'**
  String get appearanceAmoledDark;

  /// Subtitle for AMOLED dark
  ///
  /// In en, this message translates to:
  /// **'Pure black background'**
  String get appearanceAmoledDarkSubtitle;

  /// Toggle for shared-element (Hero) transitions
  ///
  /// In en, this message translates to:
  /// **'Hero animations'**
  String get appearanceHeroAnimations;

  /// Subtitle for the Hero animations toggle
  ///
  /// In en, this message translates to:
  /// **'Fly covers between screens, e.g. when opening the player'**
  String get appearanceHeroAnimationsSubtitle;

  /// Toggle that forces backdrop blur on even when the device profile disabled it
  ///
  /// In en, this message translates to:
  /// **'Always use blur effects'**
  String get appearanceForceBlur;

  /// Subtitle for the force-blur toggle
  ///
  /// In en, this message translates to:
  /// **'Enable the navigation bar blur even on devices where it is off by default. May cost performance.'**
  String get appearanceForceBlurSubtitle;

  /// Button - clear all queue items
  ///
  /// In en, this message translates to:
  /// **'Clear All'**
  String get queueClearAll;

  /// Clear queue confirmation
  ///
  /// In en, this message translates to:
  /// **'Are you sure you want to clear all downloads?'**
  String get queueClearAllMessage;

  /// Setting toggle for auto-export
  ///
  /// In en, this message translates to:
  /// **'Auto-export failed downloads'**
  String get settingsAutoExportFailed;

  /// Subtitle for auto-export setting
  ///
  /// In en, this message translates to:
  /// **'Save failed downloads to TXT file automatically'**
  String get settingsAutoExportFailedSubtitle;

  /// Setting for network type preference
  ///
  /// In en, this message translates to:
  /// **'Download Network'**
  String get settingsDownloadNetwork;

  /// Network option - use any connection
  ///
  /// In en, this message translates to:
  /// **'WiFi + Mobile Data'**
  String get settingsDownloadNetworkAny;

  /// Network option - only use WiFi
  ///
  /// In en, this message translates to:
  /// **'WiFi Only'**
  String get settingsDownloadNetworkWifiOnly;

  /// Subtitle explaining network preference
  ///
  /// In en, this message translates to:
  /// **'Choose which network to use for downloads. When set to WiFi Only, downloads will pause on mobile data.'**
  String get settingsDownloadNetworkSubtitle;

  /// Setting title - how many tracks download at the same time
  ///
  /// In en, this message translates to:
  /// **'Concurrent downloads'**
  String get settingsConcurrentDownloads;

  /// Subtitle explaining the concurrent downloads picker
  ///
  /// In en, this message translates to:
  /// **'Downloading several tracks at once is faster, but some providers may rate-limit parallel requests.'**
  String get settingsConcurrentDownloadsSubtitle;

  /// Concurrent downloads option - sequential
  ///
  /// In en, this message translates to:
  /// **'1 track at a time'**
  String get concurrentDownloadsOne;

  /// Concurrent downloads option - parallel
  ///
  /// In en, this message translates to:
  /// **'Up to {count} tracks at once'**
  String concurrentDownloadsCount(int count);

  /// Album folder option
  ///
  /// In en, this message translates to:
  /// **'Artist / Album'**
  String get albumFolderArtistAlbum;

  /// Folder structure example
  ///
  /// In en, this message translates to:
  /// **'Albums/Artist Name/Album Name/'**
  String get albumFolderArtistAlbumSubtitle;

  /// Album folder option with year
  ///
  /// In en, this message translates to:
  /// **'Artist / [Year] Album'**
  String get albumFolderArtistYearAlbum;

  /// Folder structure example
  ///
  /// In en, this message translates to:
  /// **'Albums/Artist Name/[2005] Album Name/'**
  String get albumFolderArtistYearAlbumSubtitle;

  /// Album folder option
  ///
  /// In en, this message translates to:
  /// **'Album Only'**
  String get albumFolderAlbumOnly;

  /// Folder structure example
  ///
  /// In en, this message translates to:
  /// **'Albums/Album Name/'**
  String get albumFolderAlbumOnlySubtitle;

  /// Album folder option with year
  ///
  /// In en, this message translates to:
  /// **'[Year] Album'**
  String get albumFolderYearAlbum;

  /// Folder structure example
  ///
  /// In en, this message translates to:
  /// **'Albums/[2005] Album Name/'**
  String get albumFolderYearAlbumSubtitle;

  /// Album folder option with singles inside artist
  ///
  /// In en, this message translates to:
  /// **'Artist / Album + Singles'**
  String get albumFolderArtistAlbumSingles;

  /// Folder structure example
  ///
  /// In en, this message translates to:
  /// **'Artist/Album/ and Artist/Singles/'**
  String get albumFolderArtistAlbumSinglesSubtitle;

  /// Album folder option with singles directly in artist folder
  ///
  /// In en, this message translates to:
  /// **'Artist / Album (Singles flat)'**
  String get albumFolderArtistAlbumFlat;

  /// Folder structure example for flat singles
  ///
  /// In en, this message translates to:
  /// **'Artist/Album/ and Artist/song.flac'**
  String get albumFolderArtistAlbumFlatSubtitle;

  /// Button - delete selected tracks
  ///
  /// In en, this message translates to:
  /// **'Delete Selected'**
  String get downloadedAlbumDeleteSelected;

  /// Delete confirmation with count
  ///
  /// In en, this message translates to:
  /// **'Delete {count} {count, plural, =1{track} other{tracks}} from this album?\n\nThis will also delete the files from storage.'**
  String downloadedAlbumDeleteMessage(int count);

  /// Selection count indicator
  ///
  /// In en, this message translates to:
  /// **'{count} selected'**
  String downloadedAlbumSelectedCount(int count);

  /// Selection hint
  ///
  /// In en, this message translates to:
  /// **'Tap tracks to select'**
  String get downloadedAlbumTapToSelect;

  /// Delete button text with count
  ///
  /// In en, this message translates to:
  /// **'Delete {count} {count, plural, =1{track} other{tracks}}'**
  String downloadedAlbumDeleteCount(int count);

  /// Placeholder when nothing selected
  ///
  /// In en, this message translates to:
  /// **'Select tracks to delete'**
  String get downloadedAlbumSelectToDelete;

  /// Header for disc separator in multi-disc albums
  ///
  /// In en, this message translates to:
  /// **'Disc {discNumber}'**
  String downloadedAlbumDiscHeader(int discNumber);

  /// Recent access item type - artist
  ///
  /// In en, this message translates to:
  /// **'Artist'**
  String get recentTypeArtist;

  /// Recent access item type - album
  ///
  /// In en, this message translates to:
  /// **'Album'**
  String get recentTypeAlbum;

  /// Recent access item type - song/track
  ///
  /// In en, this message translates to:
  /// **'Song'**
  String get recentTypeSong;

  /// Recent access item type - playlist
  ///
  /// In en, this message translates to:
  /// **'Playlist'**
  String get recentTypePlaylist;

  /// Empty state text for recent access list
  ///
  /// In en, this message translates to:
  /// **'No recent items yet'**
  String get recentEmpty;

  /// Confirmation message before clearing all recent activity
  ///
  /// In en, this message translates to:
  /// **'Clear all recent activity? Download history and music files will not be deleted.'**
  String get recentClearAllMessage;

  /// Button label to unhide hidden downloads in recent access
  ///
  /// In en, this message translates to:
  /// **'Show All Downloads'**
  String get recentShowAllDownloads;

  /// Snackbar message when tapping playlist in recent access
  ///
  /// In en, this message translates to:
  /// **'Playlist: {name}'**
  String recentPlaylistInfo(String name);

  /// Button - download artist discography
  ///
  /// In en, this message translates to:
  /// **'Download Discography'**
  String get discographyDownload;

  /// Option - download entire discography
  ///
  /// In en, this message translates to:
  /// **'Download All'**
  String get discographyDownloadAll;

  /// Subtitle showing total tracks and albums
  ///
  /// In en, this message translates to:
  /// **'{count} tracks from {albumCount} releases'**
  String discographyDownloadAllSubtitle(int count, int albumCount);

  /// Option - download only albums
  ///
  /// In en, this message translates to:
  /// **'Albums Only'**
  String get discographyAlbumsOnly;

  /// Subtitle showing album tracks count
  ///
  /// In en, this message translates to:
  /// **'{count} tracks from {albumCount} albums'**
  String discographyAlbumsOnlySubtitle(int count, int albumCount);

  /// Option - download only singles
  ///
  /// In en, this message translates to:
  /// **'Singles & EPs Only'**
  String get discographySinglesOnly;

  /// Subtitle showing singles tracks count
  ///
  /// In en, this message translates to:
  /// **'{count} tracks from {albumCount} singles'**
  String discographySinglesOnlySubtitle(int count, int albumCount);

  /// Option - manually select albums to download
  ///
  /// In en, this message translates to:
  /// **'Select Albums...'**
  String get discographySelectAlbums;

  /// Subtitle for select albums option
  ///
  /// In en, this message translates to:
  /// **'Choose specific albums or singles'**
  String get discographySelectAlbumsSubtitle;

  /// Progress - fetching album tracks
  ///
  /// In en, this message translates to:
  /// **'Fetching tracks...'**
  String get discographyFetchingTracks;

  /// Progress - fetching specific album
  ///
  /// In en, this message translates to:
  /// **'Fetching {current} of {total}...'**
  String discographyFetchingAlbum(int current, int total);

  /// Selection count badge
  ///
  /// In en, this message translates to:
  /// **'{count} selected'**
  String discographySelectedCount(int count);

  /// Button - download selected albums
  ///
  /// In en, this message translates to:
  /// **'Download Selected'**
  String get discographyDownloadSelected;

  /// Snackbar - tracks added from discography
  ///
  /// In en, this message translates to:
  /// **'Added {count} tracks to queue'**
  String discographyAddedToQueue(int count);

  /// Snackbar - with skipped tracks count
  ///
  /// In en, this message translates to:
  /// **'{added} added, {skipped} already downloaded'**
  String discographySkippedDownloaded(int added, int skipped);

  /// Error - no albums found for artist
  ///
  /// In en, this message translates to:
  /// **'No albums available'**
  String get discographyNoAlbums;

  /// Error - some albums failed to load
  ///
  /// In en, this message translates to:
  /// **'Failed to fetch some albums'**
  String get discographyFailedToFetch;

  /// Section header for storage access settings
  ///
  /// In en, this message translates to:
  /// **'Storage Access'**
  String get sectionStorageAccess;

  /// Toggle for MANAGE_EXTERNAL_STORAGE permission
  ///
  /// In en, this message translates to:
  /// **'All Files Access'**
  String get allFilesAccess;

  /// Subtitle when all files access is enabled
  ///
  /// In en, this message translates to:
  /// **'Can write to any folder'**
  String get allFilesAccessEnabledSubtitle;

  /// Subtitle when all files access is disabled
  ///
  /// In en, this message translates to:
  /// **'Limited to media folders only'**
  String get allFilesAccessDisabledSubtitle;

  /// Description explaining when to enable all files access
  ///
  /// In en, this message translates to:
  /// **'Enable this if you encounter write errors when saving to custom folders. Android 13+ restricts access to certain directories by default.'**
  String get allFilesAccessDescription;

  /// Message when permission is permanently denied
  ///
  /// In en, this message translates to:
  /// **'Permission was denied. Please enable \'All files access\' manually in system settings.'**
  String get allFilesAccessDeniedMessage;

  /// Snackbar message when user disables all files access
  ///
  /// In en, this message translates to:
  /// **'All Files Access disabled. The app will use limited storage access.'**
  String get allFilesAccessDisabledMessage;

  /// Settings menu item - local library
  ///
  /// In en, this message translates to:
  /// **'Local Library'**
  String get settingsLocalLibrary;

  /// Subtitle for local library settings
  ///
  /// In en, this message translates to:
  /// **'Scan music & detect duplicates'**
  String get settingsLocalLibrarySubtitle;

  /// Settings menu item - cache management
  ///
  /// In en, this message translates to:
  /// **'Storage & Cache'**
  String get settingsCache;

  /// Subtitle for cache management menu
  ///
  /// In en, this message translates to:
  /// **'View size and clear cached data'**
  String get settingsCacheSubtitle;

  /// Library settings page title
  ///
  /// In en, this message translates to:
  /// **'Local Library'**
  String get libraryTitle;

  /// Section header for scan settings
  ///
  /// In en, this message translates to:
  /// **'Scan Settings'**
  String get libraryScanSettings;

  /// Toggle to enable library scanning
  ///
  /// In en, this message translates to:
  /// **'Enable Local Library'**
  String get libraryEnableLocalLibrary;

  /// Subtitle for enable toggle
  ///
  /// In en, this message translates to:
  /// **'Scan and track your existing music'**
  String get libraryEnableLocalLibrarySubtitle;

  /// Folder selection setting
  ///
  /// In en, this message translates to:
  /// **'Library Folder'**
  String get libraryFolder;

  /// Placeholder when no folder selected
  ///
  /// In en, this message translates to:
  /// **'Tap to select folder'**
  String get libraryFolderHint;

  /// Action to add another local library source
  ///
  /// In en, this message translates to:
  /// **'Add library folder'**
  String get libraryAddFolder;

  /// Supported storage locations for local library sources
  ///
  /// In en, this message translates to:
  /// **'Internal storage, SD card, SSD, or another external drive'**
  String get libraryAddFolderSubtitle;

  /// Library source is connected and accessible
  ///
  /// In en, this message translates to:
  /// **'Online'**
  String get librarySourceOnline;

  /// Library source is temporarily disconnected
  ///
  /// In en, this message translates to:
  /// **'Offline. Reconnect the storage to restore these tracks'**
  String get librarySourceOffline;

  /// Library source has been disabled by the user
  ///
  /// In en, this message translates to:
  /// **'Disabled'**
  String get librarySourceDisabled;

  /// Live progress for one library folder scan
  ///
  /// In en, this message translates to:
  /// **'{scanned} of {total} files scanned ({progress}%)'**
  String librarySourceScanCount(int scanned, int total, String progress);

  /// Label for a removable or external library source
  ///
  /// In en, this message translates to:
  /// **'External storage'**
  String get libraryExternalStorage;

  /// Action to remove one indexed library source
  ///
  /// In en, this message translates to:
  /// **'Remove library folder'**
  String get libraryRemoveFolder;

  /// Confirmation shown before removing a library source
  ///
  /// In en, this message translates to:
  /// **'Remove this folder and its indexed tracks from SpotiFLAC Mobile? Audio files on the storage will not be deleted.'**
  String get libraryRemoveFolderMessage;

  /// Toggle for duplicate indicator in search
  ///
  /// In en, this message translates to:
  /// **'Show Duplicate Indicator'**
  String get libraryShowDuplicateIndicator;

  /// Subtitle for duplicate indicator toggle
  ///
  /// In en, this message translates to:
  /// **'Show when searching for existing tracks'**
  String get libraryShowDuplicateIndicatorSubtitle;

  /// Setting for automatic library scanning
  ///
  /// In en, this message translates to:
  /// **'Auto Scan'**
  String get libraryAutoScan;

  /// Subtitle for auto scan setting
  ///
  /// In en, this message translates to:
  /// **'Automatically scan your library for new files'**
  String get libraryAutoScanSubtitle;

  /// Auto scan disabled
  ///
  /// In en, this message translates to:
  /// **'Off'**
  String get libraryAutoScanOff;

  /// Auto scan when app opens
  ///
  /// In en, this message translates to:
  /// **'Every app open'**
  String get libraryAutoScanOnOpen;

  /// Auto scan once per day
  ///
  /// In en, this message translates to:
  /// **'Daily'**
  String get libraryAutoScanDaily;

  /// Auto scan once per week
  ///
  /// In en, this message translates to:
  /// **'Weekly'**
  String get libraryAutoScanWeekly;

  /// Section header for library actions
  ///
  /// In en, this message translates to:
  /// **'Actions'**
  String get libraryActions;

  /// Button to start library scan
  ///
  /// In en, this message translates to:
  /// **'Scan Library'**
  String get libraryScan;

  /// Subtitle for scan button
  ///
  /// In en, this message translates to:
  /// **'Scan for audio files'**
  String get libraryScanSubtitle;

  /// Message when trying to scan without folder
  ///
  /// In en, this message translates to:
  /// **'Select a folder first'**
  String get libraryScanSelectFolderFirst;

  /// Button to remove entries for missing files
  ///
  /// In en, this message translates to:
  /// **'Cleanup Missing Files'**
  String get libraryCleanupMissingFiles;

  /// Subtitle for cleanup button
  ///
  /// In en, this message translates to:
  /// **'Remove entries for files that no longer exist'**
  String get libraryCleanupMissingFilesSubtitle;

  /// Button to clear all library entries
  ///
  /// In en, this message translates to:
  /// **'Clear Library'**
  String get libraryClear;

  /// Subtitle for clear button
  ///
  /// In en, this message translates to:
  /// **'Remove all scanned tracks'**
  String get libraryClearSubtitle;

  /// Dialog title for clear confirmation
  ///
  /// In en, this message translates to:
  /// **'Clear Library'**
  String get libraryClearConfirmTitle;

  /// Dialog message for clear confirmation
  ///
  /// In en, this message translates to:
  /// **'This will remove all scanned tracks from your library. Your actual music files will not be deleted.'**
  String get libraryClearConfirmMessage;

  /// Section header for about info
  ///
  /// In en, this message translates to:
  /// **'About Local Library'**
  String get libraryAbout;

  /// Description of local library feature
  ///
  /// In en, this message translates to:
  /// **'Scans your existing music collection to detect duplicates when downloading. Supports FLAC, ALAC, M4A, MP3, Opus, OGG, WAV, AIFF, and APE formats. Metadata is read from file tags when available.'**
  String get libraryAboutDescription;

  /// Unit label for tracks count (without the number itself)
  ///
  /// In en, this message translates to:
  /// **'{count, plural, =1{track} other{tracks}}'**
  String libraryTracksUnit(int count);

  /// Unit label for files count during library scanning
  ///
  /// In en, this message translates to:
  /// **'{count, plural, =1{file} other{files}}'**
  String libraryFilesUnit(int count);

  /// Last scan time display
  ///
  /// In en, this message translates to:
  /// **'Last scanned: {time}'**
  String libraryLastScanned(String time);

  /// Shown when library has never been scanned
  ///
  /// In en, this message translates to:
  /// **'Never'**
  String get libraryLastScannedNever;

  /// Status during scan
  ///
  /// In en, this message translates to:
  /// **'Scanning...'**
  String get libraryScanning;

  /// Status shown after file scanning finishes but library persistence is still running
  ///
  /// In en, this message translates to:
  /// **'Finalizing library...'**
  String get libraryScanFinalizing;

  /// Scan progress display
  ///
  /// In en, this message translates to:
  /// **'{progress}% of {total} files'**
  String libraryScanProgress(String progress, int total);

  /// Badge shown on tracks that exist in local library
  ///
  /// In en, this message translates to:
  /// **'In Library'**
  String get libraryInLibrary;

  /// Snackbar after cleanup
  ///
  /// In en, this message translates to:
  /// **'Removed {count} missing files from library'**
  String libraryRemovedMissingFiles(int count);

  /// Snackbar after clearing library
  ///
  /// In en, this message translates to:
  /// **'Library cleared'**
  String get libraryCleared;

  /// Dialog title for storage permission
  ///
  /// In en, this message translates to:
  /// **'Storage Access Required'**
  String get libraryStorageAccessRequired;

  /// Dialog message for storage permission
  ///
  /// In en, this message translates to:
  /// **'SpotiFLAC needs storage access to scan your music library. Please grant permission in settings.'**
  String get libraryStorageAccessMessage;

  /// Error when folder doesn't exist
  ///
  /// In en, this message translates to:
  /// **'Selected folder does not exist'**
  String get libraryFolderNotExist;

  /// Badge for tracks downloaded via SpotiFLAC
  ///
  /// In en, this message translates to:
  /// **'Downloaded'**
  String get librarySourceDownloaded;

  /// Badge for tracks from local library scan
  ///
  /// In en, this message translates to:
  /// **'Local'**
  String get librarySourceLocal;

  /// Filter chip - show all library items
  ///
  /// In en, this message translates to:
  /// **'All'**
  String get libraryFilterAll;

  /// Filter chip - show only downloaded items
  ///
  /// In en, this message translates to:
  /// **'Downloaded'**
  String get libraryFilterDownloaded;

  /// Filter chip - show only local library items
  ///
  /// In en, this message translates to:
  /// **'Local'**
  String get libraryFilterLocal;

  /// Filter bottom sheet title
  ///
  /// In en, this message translates to:
  /// **'Filters'**
  String get libraryFilterTitle;

  /// Reset all filters button
  ///
  /// In en, this message translates to:
  /// **'Reset'**
  String get libraryFilterReset;

  /// Apply filters button
  ///
  /// In en, this message translates to:
  /// **'Apply'**
  String get libraryFilterApply;

  /// Filter section - source type
  ///
  /// In en, this message translates to:
  /// **'Source'**
  String get libraryFilterSource;

  /// Filter section - audio quality
  ///
  /// In en, this message translates to:
  /// **'Quality'**
  String get libraryFilterQuality;

  /// Filter option - high resolution audio
  ///
  /// In en, this message translates to:
  /// **'Hi-Res (24bit)'**
  String get libraryFilterQualityHiRes;

  /// Filter option - CD quality audio
  ///
  /// In en, this message translates to:
  /// **'CD (16bit)'**
  String get libraryFilterQualityCD;

  /// Filter option - lossy compressed audio
  ///
  /// In en, this message translates to:
  /// **'Lossy'**
  String get libraryFilterQualityLossy;

  /// Filter section - file format
  ///
  /// In en, this message translates to:
  /// **'Format'**
  String get libraryFilterFormat;

  /// Filter section - metadata completeness
  ///
  /// In en, this message translates to:
  /// **'Metadata'**
  String get libraryFilterMetadata;

  /// Filter option - items with complete metadata
  ///
  /// In en, this message translates to:
  /// **'Complete metadata'**
  String get libraryFilterMetadataComplete;

  /// Filter option - items missing any tracked metadata field
  ///
  /// In en, this message translates to:
  /// **'Missing any metadata'**
  String get libraryFilterMetadataMissingAny;

  /// Filter option - items missing release year/date
  ///
  /// In en, this message translates to:
  /// **'Missing year'**
  String get libraryFilterMetadataMissingYear;

  /// Filter option - items missing genre
  ///
  /// In en, this message translates to:
  /// **'Missing genre'**
  String get libraryFilterMetadataMissingGenre;

  /// Filter option - items missing album artist
  ///
  /// In en, this message translates to:
  /// **'Missing album artist'**
  String get libraryFilterMetadataMissingAlbumArtist;

  /// Filter section - sort order
  ///
  /// In en, this message translates to:
  /// **'Sort'**
  String get libraryFilterSort;

  /// Sort option - newest first
  ///
  /// In en, this message translates to:
  /// **'Latest'**
  String get libraryFilterSortLatest;

  /// Sort option - oldest first
  ///
  /// In en, this message translates to:
  /// **'Oldest'**
  String get libraryFilterSortOldest;

  /// Sort option - album ascending
  ///
  /// In en, this message translates to:
  /// **'Album (A-Z)'**
  String get libraryFilterSortAlbumAsc;

  /// Sort option - album descending
  ///
  /// In en, this message translates to:
  /// **'Album (Z-A)'**
  String get libraryFilterSortAlbumDesc;

  /// Sort option - genre ascending
  ///
  /// In en, this message translates to:
  /// **'Genre (A-Z)'**
  String get libraryFilterSortGenreAsc;

  /// Sort option - genre descending
  ///
  /// In en, this message translates to:
  /// **'Genre (Z-A)'**
  String get libraryFilterSortGenreDesc;

  /// Relative time - less than a minute ago
  ///
  /// In en, this message translates to:
  /// **'Just now'**
  String get timeJustNow;

  /// Relative time - minutes ago
  ///
  /// In en, this message translates to:
  /// **'{count, plural, =1{1 minute ago} other{{count} minutes ago}}'**
  String timeMinutesAgo(int count);

  /// Relative time - hours ago
  ///
  /// In en, this message translates to:
  /// **'{count, plural, =1{1 hour ago} other{{count} hours ago}}'**
  String timeHoursAgo(int count);

  /// Tutorial welcome page title
  ///
  /// In en, this message translates to:
  /// **'Welcome to SpotiFLAC Mobile!'**
  String get tutorialWelcomeTitle;

  /// Tutorial welcome page description
  ///
  /// In en, this message translates to:
  /// **'Learn how to find music with extensions, choose the quality you want, and manage downloads in SpotiFLAC Mobile.'**
  String get tutorialWelcomeDesc;

  /// Tutorial welcome tip 1
  ///
  /// In en, this message translates to:
  /// **'Search with an installed extension or paste a supported music link'**
  String get tutorialWelcomeTip1;

  /// Tutorial welcome tip 2
  ///
  /// In en, this message translates to:
  /// **'Choose from the audio qualities offered by your download provider'**
  String get tutorialWelcomeTip2;

  /// Tutorial welcome tip 3
  ///
  /// In en, this message translates to:
  /// **'Embed metadata, cover art, lyrics, and release information automatically'**
  String get tutorialWelcomeTip3;

  /// Tutorial search page title
  ///
  /// In en, this message translates to:
  /// **'Finding Music'**
  String get tutorialSearchTitle;

  /// Tutorial search page description
  ///
  /// In en, this message translates to:
  /// **'Search with your selected extension or paste a supported music link.'**
  String get tutorialSearchDesc;

  /// Tutorial download page title
  ///
  /// In en, this message translates to:
  /// **'Downloading Music'**
  String get tutorialDownloadTitle;

  /// Tutorial download page description
  ///
  /// In en, this message translates to:
  /// **'Pick an available quality, start the download, and follow its progress in the queue.'**
  String get tutorialDownloadDesc;

  /// Tutorial library page title
  ///
  /// In en, this message translates to:
  /// **'Your Library'**
  String get tutorialLibraryTitle;

  /// Tutorial library page description
  ///
  /// In en, this message translates to:
  /// **'Downloaded and locally scanned music is organized in your Library.'**
  String get tutorialLibraryDesc;

  /// Tutorial library tip 1
  ///
  /// In en, this message translates to:
  /// **'Manage active, pending, and completed downloads from the Library queue'**
  String get tutorialLibraryTip1;

  /// Tutorial library tip 2
  ///
  /// In en, this message translates to:
  /// **'Tap a track to play it with the built-in player'**
  String get tutorialLibraryTip2;

  /// Tutorial library tip 3
  ///
  /// In en, this message translates to:
  /// **'Browse tracks, albums, and playlists in list or grid views'**
  String get tutorialLibraryTip3;

  /// Tutorial extensions page title
  ///
  /// In en, this message translates to:
  /// **'Extensions'**
  String get tutorialExtensionsTitle;

  /// Tutorial extensions page description
  ///
  /// In en, this message translates to:
  /// **'Extensions add search, download, metadata, lyrics, and other integrations.'**
  String get tutorialExtensionsDesc;

  /// Tutorial extensions tip 1
  ///
  /// In en, this message translates to:
  /// **'Browse the Repo tab to discover useful extensions'**
  String get tutorialExtensionsTip1;

  /// Tutorial extensions tip 2
  ///
  /// In en, this message translates to:
  /// **'Choose providers for search, downloads, metadata, and fallbacks'**
  String get tutorialExtensionsTip2;

  /// Tutorial extensions tip 3
  ///
  /// In en, this message translates to:
  /// **'Connect accounts when required and keep extensions up to date'**
  String get tutorialExtensionsTip3;

  /// Tutorial settings page title
  ///
  /// In en, this message translates to:
  /// **'Customize Your Experience'**
  String get tutorialSettingsTitle;

  /// Tutorial settings page description
  ///
  /// In en, this message translates to:
  /// **'Fine-tune downloads, playback, Library behavior, appearance, and storage.'**
  String get tutorialSettingsDesc;

  /// Tutorial settings tip 1
  ///
  /// In en, this message translates to:
  /// **'Change download location and folder organization'**
  String get tutorialSettingsTip1;

  /// Tutorial settings tip 2
  ///
  /// In en, this message translates to:
  /// **'Set quality, concurrency, filenames, and conversion preferences'**
  String get tutorialSettingsTip2;

  /// Tutorial settings tip 3
  ///
  /// In en, this message translates to:
  /// **'Customize app theme and appearance'**
  String get tutorialSettingsTip3;

  /// Tutorial completion message
  ///
  /// In en, this message translates to:
  /// **'You\'re ready. Select your extensions, then search or paste a supported link.'**
  String get tutorialReadyMessage;

  /// Button to force a complete rescan of library
  ///
  /// In en, this message translates to:
  /// **'Force Full Scan'**
  String get libraryForceFullScan;

  /// Subtitle for force full scan button
  ///
  /// In en, this message translates to:
  /// **'Rescan all files, ignoring cache'**
  String get libraryForceFullScanSubtitle;

  /// Button to remove history entries for deleted files
  ///
  /// In en, this message translates to:
  /// **'Cleanup Orphaned Downloads'**
  String get cleanupOrphanedDownloads;

  /// Subtitle for orphaned cleanup button
  ///
  /// In en, this message translates to:
  /// **'Remove history entries for files that no longer exist'**
  String get cleanupOrphanedDownloadsSubtitle;

  /// Snackbar after orphan cleanup
  ///
  /// In en, this message translates to:
  /// **'Removed {count} orphaned entries from history'**
  String cleanupOrphanedDownloadsResult(int count);

  /// Snackbar when no orphans found
  ///
  /// In en, this message translates to:
  /// **'No orphaned entries found'**
  String get cleanupOrphanedDownloadsNone;

  /// Cache management page title
  ///
  /// In en, this message translates to:
  /// **'Storage & Cache'**
  String get cacheTitle;

  /// Heading for cache summary card
  ///
  /// In en, this message translates to:
  /// **'Cache overview'**
  String get cacheSummaryTitle;

  /// Helper text for cache summary card
  ///
  /// In en, this message translates to:
  /// **'Clearing cache will not remove downloaded music files.'**
  String get cacheSummarySubtitle;

  /// Total cache size shown in summary
  ///
  /// In en, this message translates to:
  /// **'Estimated cache usage: {size}'**
  String cacheEstimatedTotal(String size);

  /// Section header for cache entries
  ///
  /// In en, this message translates to:
  /// **'Cached Data'**
  String get cacheSectionStorage;

  /// Section header for cleanup actions
  ///
  /// In en, this message translates to:
  /// **'Maintenance'**
  String get cacheSectionMaintenance;

  /// Cache item title for app cache directory
  ///
  /// In en, this message translates to:
  /// **'App cache directory'**
  String get cacheAppDirectory;

  /// Description of what app cache directory contains
  ///
  /// In en, this message translates to:
  /// **'HTTP responses, WebView data, and other temporary app data.'**
  String get cacheAppDirectoryDesc;

  /// Cache item title for temporary files directory
  ///
  /// In en, this message translates to:
  /// **'Temporary directory'**
  String get cacheTempDirectory;

  /// Description of what temporary directory contains
  ///
  /// In en, this message translates to:
  /// **'Temporary files from downloads and audio conversion.'**
  String get cacheTempDirectoryDesc;

  /// Cache item title for persistent cover images
  ///
  /// In en, this message translates to:
  /// **'Cover image cache'**
  String get cacheCoverImage;

  /// Description of what cover image cache contains
  ///
  /// In en, this message translates to:
  /// **'Downloaded album and track cover art. Will re-download when viewed.'**
  String get cacheCoverImageDesc;

  /// Cache item title for local library cover art images
  ///
  /// In en, this message translates to:
  /// **'Library cover cache'**
  String get cacheLibraryCover;

  /// Description of what library cover cache contains
  ///
  /// In en, this message translates to:
  /// **'Cover art extracted from local music files. Will re-extract on next scan.'**
  String get cacheLibraryCoverDesc;

  /// Toggle title for ReplayGain playback normalization in the built-in player
  ///
  /// In en, this message translates to:
  /// **'Volume normalization'**
  String get libraryPlaybackNormalization;

  /// Subtitle explaining playback volume normalization
  ///
  /// In en, this message translates to:
  /// **'Even out loudness between tracks using their ReplayGain or R128 tags, when present'**
  String get libraryPlaybackNormalizationSubtitle;

  /// Cache item title for saved audio analysis results
  ///
  /// In en, this message translates to:
  /// **'Audio analysis cache'**
  String get cacheAudioAnalysis;

  /// Description of what audio analysis cache contains
  ///
  /// In en, this message translates to:
  /// **'Saved spectrograms and analysis results. Will re-analyze on next open.'**
  String get cacheAudioAnalysisDesc;

  /// Cache item title for explore home feed cache
  ///
  /// In en, this message translates to:
  /// **'Explore feed cache'**
  String get cacheExploreFeed;

  /// Description of what explore feed cache contains
  ///
  /// In en, this message translates to:
  /// **'Explore tab content (new releases, trending). Will refresh on next visit.'**
  String get cacheExploreFeedDesc;

  /// Cache item title for track ID lookup cache
  ///
  /// In en, this message translates to:
  /// **'Track lookup cache'**
  String get cacheTrackLookup;

  /// Description of what track lookup cache contains
  ///
  /// In en, this message translates to:
  /// **'Spotify/Deezer track ID lookups. Clearing may slow next few searches.'**
  String get cacheTrackLookupDesc;

  /// Description of what cleanup unused data does
  ///
  /// In en, this message translates to:
  /// **'Remove orphaned download history and library entries for missing files.'**
  String get cacheCleanupUnusedDesc;

  /// Label when cache category has no data
  ///
  /// In en, this message translates to:
  /// **'No cached data'**
  String get cacheNoData;

  /// Cache size and file count
  ///
  /// In en, this message translates to:
  /// **'{size} in {count} files'**
  String cacheSizeWithFiles(String size, int count);

  /// Cache size only
  ///
  /// In en, this message translates to:
  /// **'{size}'**
  String cacheSizeOnly(String size);

  /// Track cache entry count
  ///
  /// In en, this message translates to:
  /// **'{count} entries'**
  String cacheEntries(int count);

  /// Snackbar after clearing selected cache
  ///
  /// In en, this message translates to:
  /// **'Cleared: {target}'**
  String cacheClearSuccess(String target);

  /// Dialog title before clearing one cache category
  ///
  /// In en, this message translates to:
  /// **'Clear cache?'**
  String get cacheClearConfirmTitle;

  /// Dialog message before clearing selected cache
  ///
  /// In en, this message translates to:
  /// **'This will clear cached data for {target}. Downloaded music files will not be deleted.'**
  String cacheClearConfirmMessage(String target);

  /// Dialog title before clearing all caches
  ///
  /// In en, this message translates to:
  /// **'Clear all cache?'**
  String get cacheClearAllConfirmTitle;

  /// Dialog message before clearing all caches
  ///
  /// In en, this message translates to:
  /// **'This will clear all cache categories on this page. Downloaded music files will not be deleted.'**
  String get cacheClearAllConfirmMessage;

  /// Button label to clear all caches
  ///
  /// In en, this message translates to:
  /// **'Clear all cache'**
  String get cacheClearAll;

  /// Action title for cleaning unused entries
  ///
  /// In en, this message translates to:
  /// **'Cleanup unused data'**
  String get cacheCleanupUnused;

  /// Subtitle for cleanup unused data action
  ///
  /// In en, this message translates to:
  /// **'Remove orphaned download history and missing library entries'**
  String get cacheCleanupUnusedSubtitle;

  /// Snackbar after unused data cleanup
  ///
  /// In en, this message translates to:
  /// **'Cleanup completed: {downloadCount} orphaned downloads, {libraryCount} missing library entries'**
  String cacheCleanupResult(int downloadCount, int libraryCount);

  /// Button label to refresh cache statistics
  ///
  /// In en, this message translates to:
  /// **'Refresh stats'**
  String get cacheRefreshStats;

  /// Menu action - save album cover art as file
  ///
  /// In en, this message translates to:
  /// **'Save Cover Art'**
  String get trackSaveCoverArt;

  /// Menu action - save lyrics as .lrc file
  ///
  /// In en, this message translates to:
  /// **'Save Lyrics (.lrc)'**
  String get trackSaveLyrics;

  /// Snackbar while saving lyrics to file
  ///
  /// In en, this message translates to:
  /// **'Saving lyrics...'**
  String get trackSaveLyricsProgress;

  /// Menu action - re-embed metadata into audio file
  ///
  /// In en, this message translates to:
  /// **'Re-enrich'**
  String get trackReEnrich;

  /// Subtitle for re-enrich metadata action for local items
  ///
  /// In en, this message translates to:
  /// **'Search metadata online and embed into file'**
  String get trackReEnrichOnlineSubtitle;

  /// Checkbox label for cover art field in re-enrich
  ///
  /// In en, this message translates to:
  /// **'Cover Art'**
  String get trackReEnrichFieldCover;

  /// Checkbox label for lyrics field in re-enrich
  ///
  /// In en, this message translates to:
  /// **'Lyrics'**
  String get trackReEnrichFieldLyrics;

  /// Checkbox label for basic tags in re-enrich (title/artist are never overwritten)
  ///
  /// In en, this message translates to:
  /// **'Album, Album Artist'**
  String get trackReEnrichFieldBasicTags;

  /// Checkbox label for track info in re-enrich
  ///
  /// In en, this message translates to:
  /// **'Track & Disc Number'**
  String get trackReEnrichFieldTrackInfo;

  /// Checkbox label for release info in re-enrich
  ///
  /// In en, this message translates to:
  /// **'Date & ISRC'**
  String get trackReEnrichFieldReleaseInfo;

  /// Checkbox label for extra metadata in re-enrich
  ///
  /// In en, this message translates to:
  /// **'Genre, Label, Copyright'**
  String get trackReEnrichFieldExtra;

  /// Select all fields checkbox in re-enrich
  ///
  /// In en, this message translates to:
  /// **'Select All'**
  String get trackReEnrichSelectAll;

  /// Batch metadata mode that only writes ISRC
  ///
  /// In en, this message translates to:
  /// **'ISRC only'**
  String get trackReEnrichModeIsrc;

  /// Explanation for the ISRC-only batch metadata mode
  ///
  /// In en, this message translates to:
  /// **'Find and add the recording identifier without changing other tags'**
  String get trackReEnrichModeIsrcSubtitle;

  /// Batch metadata mode that fills only empty tags
  ///
  /// In en, this message translates to:
  /// **'Fill missing tags'**
  String get trackReEnrichModeMissing;

  /// Explanation for the fill-missing batch metadata mode
  ///
  /// In en, this message translates to:
  /// **'Keep existing values and fill only fields that are empty'**
  String get trackReEnrichModeMissingSubtitle;

  /// Batch metadata mode that replaces selected tag groups
  ///
  /// In en, this message translates to:
  /// **'Update selected tags'**
  String get trackReEnrichModeReplace;

  /// Explanation for the selected-tag batch metadata mode
  ///
  /// In en, this message translates to:
  /// **'Choose which existing values may be replaced by online metadata'**
  String get trackReEnrichModeReplaceSubtitle;

  /// Heading above batch re-enrich field checkboxes
  ///
  /// In en, this message translates to:
  /// **'Tags to update'**
  String get trackReEnrichFieldsTitle;

  /// Button that searches metadata and opens the batch change review
  ///
  /// In en, this message translates to:
  /// **'Review changes'**
  String get trackReEnrichReview;

  /// Title of the batch metadata review sheet
  ///
  /// In en, this message translates to:
  /// **'Review metadata changes'**
  String get trackReEnrichReviewTitle;

  /// Summary shown above proposed batch metadata changes
  ///
  /// In en, this message translates to:
  /// **'{changeCount} proposed changes across {trackCount} tracks'**
  String trackReEnrichReviewSubtitle(int changeCount, int trackCount);

  /// Message when batch metadata preview has no proposed changes
  ///
  /// In en, this message translates to:
  /// **'No metadata changes were found for the selected tracks.'**
  String get trackReEnrichNoChanges;

  /// Confirmation button in the batch metadata review sheet
  ///
  /// In en, this message translates to:
  /// **'Apply changes'**
  String get trackReEnrichApplyChanges;

  /// Proposed value when lyrics will be refreshed during re-enrich
  ///
  /// In en, this message translates to:
  /// **'Refresh from online'**
  String get trackReEnrichRefreshOnline;

  /// Menu action - edit embedded metadata
  ///
  /// In en, this message translates to:
  /// **'Edit Metadata'**
  String get trackEditMetadata;

  /// Snackbar after cover art saved
  ///
  /// In en, this message translates to:
  /// **'Cover art saved to {fileName}'**
  String trackCoverSaved(String fileName);

  /// Snackbar when no cover art URL or embedded cover
  ///
  /// In en, this message translates to:
  /// **'No cover art source available'**
  String get trackCoverNoSource;

  /// Snackbar after lyrics saved
  ///
  /// In en, this message translates to:
  /// **'Lyrics saved to {fileName}'**
  String trackLyricsSaved(String fileName);

  /// Snackbar while re-enriching metadata
  ///
  /// In en, this message translates to:
  /// **'Re-enriching metadata...'**
  String get trackReEnrichProgress;

  /// Snackbar while searching metadata from internet for local items
  ///
  /// In en, this message translates to:
  /// **'Searching metadata online...'**
  String get trackReEnrichSearching;

  /// Snackbar after successful re-enrichment
  ///
  /// In en, this message translates to:
  /// **'Metadata re-enriched successfully'**
  String get trackReEnrichSuccess;

  /// Snackbar when FFmpeg embed fails for MP3/Opus
  ///
  /// In en, this message translates to:
  /// **'FFmpeg metadata embed failed'**
  String get trackReEnrichFfmpegFailed;

  /// Action/button label for queueing FLAC redownloads for local tracks
  ///
  /// In en, this message translates to:
  /// **'Queue FLAC'**
  String get queueFlacAction;

  /// Confirmation dialog body before queueing FLAC redownloads for local tracks
  ///
  /// In en, this message translates to:
  /// **'Search online matches for the selected tracks and queue FLAC downloads.\n\nExisting files will not be modified or deleted.\n\nOnly high-confidence matches are queued automatically.\n\n{count} selected'**
  String queueFlacConfirmMessage(int count);

  /// Snackbar when no safe FLAC redownload matches were found
  ///
  /// In en, this message translates to:
  /// **'No reliable online matches found for the selection'**
  String get queueFlacNoReliableMatches;

  /// Snackbar when some selected local tracks were queued for FLAC redownload and some were skipped
  ///
  /// In en, this message translates to:
  /// **'Added {addedCount} tracks to queue, skipped {skippedCount}'**
  String queueFlacQueuedWithSkipped(int addedCount, int skippedCount);

  /// Snackbar when save operation fails
  ///
  /// In en, this message translates to:
  /// **'Failed: {error}'**
  String trackSaveFailed(String error);

  /// Menu item - convert audio format
  ///
  /// In en, this message translates to:
  /// **'Convert Format'**
  String get trackConvertFormat;

  /// Title of convert bottom sheet
  ///
  /// In en, this message translates to:
  /// **'Convert Audio'**
  String get trackConvertTitle;

  /// Label for format selection
  ///
  /// In en, this message translates to:
  /// **'Target Format'**
  String get trackConvertTargetFormat;

  /// Label for bitrate selection
  ///
  /// In en, this message translates to:
  /// **'Bitrate'**
  String get trackConvertBitrate;

  /// Toggle to preserve the source file during conversion
  ///
  /// In en, this message translates to:
  /// **'Keep original file'**
  String get trackConvertKeepOriginal;

  /// Description for preserving the source file during conversion
  ///
  /// In en, this message translates to:
  /// **'Add the converted file as a separate library entry'**
  String get trackConvertKeepOriginalDescription;

  /// Confirmation dialog title
  ///
  /// In en, this message translates to:
  /// **'Confirm Conversion'**
  String get trackConvertConfirmTitle;

  /// Confirmation dialog message
  ///
  /// In en, this message translates to:
  /// **'Convert from {sourceFormat} to {targetFormat} at {bitrate}?\n\nThe original file will be deleted after conversion.'**
  String trackConvertConfirmMessage(
    String sourceFormat,
    String targetFormat,
    String bitrate,
  );

  /// Confirmation dialog message for lossless-to-lossless conversion
  ///
  /// In en, this message translates to:
  /// **'Convert from {sourceFormat} to {targetFormat}? (Lossless — no quality loss)\n\nThe original file will be deleted after conversion.'**
  String trackConvertConfirmMessageLossless(
    String sourceFormat,
    String targetFormat,
  );

  /// Confirmation message when the source file will be preserved
  ///
  /// In en, this message translates to:
  /// **'Convert from {sourceFormat} to {targetFormat}?\n\nThe original file will be kept and the converted file will be added as a separate library entry.'**
  String trackConvertConfirmKeepOriginal(
    String sourceFormat,
    String targetFormat,
  );

  /// Hint shown when converting between lossless formats
  ///
  /// In en, this message translates to:
  /// **'Lossless conversion — no quality loss'**
  String get trackConvertLosslessHint;

  /// Snackbar while converting
  ///
  /// In en, this message translates to:
  /// **'Converting audio...'**
  String get trackConvertConverting;

  /// Snackbar after successful conversion
  ///
  /// In en, this message translates to:
  /// **'Converted to {format} successfully'**
  String trackConvertSuccess(String format);

  /// Snackbar when conversion fails
  ///
  /// In en, this message translates to:
  /// **'Conversion failed'**
  String get trackConvertFailed;

  /// Title for CUE split bottom sheet
  ///
  /// In en, this message translates to:
  /// **'Split CUE Sheet'**
  String get cueSplitTitle;

  /// Album name in CUE split sheet
  ///
  /// In en, this message translates to:
  /// **'Album: {album}'**
  String cueSplitAlbum(String album);

  /// Artist name in CUE split sheet
  ///
  /// In en, this message translates to:
  /// **'Artist: {artist}'**
  String cueSplitArtist(String artist);

  /// Number of tracks in CUE sheet
  ///
  /// In en, this message translates to:
  /// **'{count} tracks'**
  String cueSplitTrackCount(int count);

  /// CUE split confirmation dialog title
  ///
  /// In en, this message translates to:
  /// **'Split CUE Album'**
  String get cueSplitConfirmTitle;

  /// CUE split confirmation dialog message
  ///
  /// In en, this message translates to:
  /// **'Split \"{album}\" into {count} individual FLAC files?\n\nFiles will be saved to the same directory.'**
  String cueSplitConfirmMessage(String album, int count);

  /// Snackbar while splitting CUE
  ///
  /// In en, this message translates to:
  /// **'Splitting CUE sheet... ({current}/{total})'**
  String cueSplitSplitting(int current, int total);

  /// Snackbar after successful CUE split
  ///
  /// In en, this message translates to:
  /// **'Split into {count} tracks successfully'**
  String cueSplitSuccess(int count);

  /// Snackbar when CUE split fails
  ///
  /// In en, this message translates to:
  /// **'CUE split failed'**
  String get cueSplitFailed;

  /// Error when CUE audio file is missing
  ///
  /// In en, this message translates to:
  /// **'Audio file not found for this CUE sheet'**
  String get cueSplitNoAudioFile;

  /// Button text to start CUE splitting
  ///
  /// In en, this message translates to:
  /// **'Split into Tracks'**
  String get cueSplitButton;

  /// Generic action button - create
  ///
  /// In en, this message translates to:
  /// **'Create'**
  String get actionCreate;

  /// Library section title for custom folders
  ///
  /// In en, this message translates to:
  /// **'My folders'**
  String get collectionFoldersTitle;

  /// Custom folder for saved tracks to download later
  ///
  /// In en, this message translates to:
  /// **'Wishlist'**
  String get collectionWishlist;

  /// Custom folder for favorite tracks
  ///
  /// In en, this message translates to:
  /// **'Loved'**
  String get collectionLoved;

  /// Custom folder for favorite artists
  ///
  /// In en, this message translates to:
  /// **'Favorite Artists'**
  String get collectionFavoriteArtists;

  /// Single playlist label
  ///
  /// In en, this message translates to:
  /// **'Playlist'**
  String get collectionPlaylist;

  /// Action to add a track to user playlist
  ///
  /// In en, this message translates to:
  /// **'Add to playlist'**
  String get collectionAddToPlaylist;

  /// Action to create a new playlist
  ///
  /// In en, this message translates to:
  /// **'Create playlist'**
  String get collectionCreatePlaylist;

  /// Empty state title when user has no playlists
  ///
  /// In en, this message translates to:
  /// **'No playlists yet'**
  String get collectionNoPlaylistsYet;

  /// Track count label for custom playlists
  ///
  /// In en, this message translates to:
  /// **'{count, plural, =1{1 track} other{{count} tracks}}'**
  String collectionPlaylistTracks(int count);

  /// Artist count label for favorite artists
  ///
  /// In en, this message translates to:
  /// **'{count, plural, =1{1 artist} other{{count} artists}}'**
  String collectionArtistCount(int count);

  /// Snackbar after adding track to playlist
  ///
  /// In en, this message translates to:
  /// **'Added to \"{playlistName}\"'**
  String collectionAddedToPlaylist(String playlistName);

  /// Snackbar when track already exists in playlist
  ///
  /// In en, this message translates to:
  /// **'Already in \"{playlistName}\"'**
  String collectionAlreadyInPlaylist(String playlistName);

  /// Hint text for playlist name input
  ///
  /// In en, this message translates to:
  /// **'Playlist name'**
  String get collectionPlaylistNameHint;

  /// Validation error for empty playlist name
  ///
  /// In en, this message translates to:
  /// **'Playlist name is required'**
  String get collectionPlaylistNameRequired;

  /// Action to rename playlist
  ///
  /// In en, this message translates to:
  /// **'Rename playlist'**
  String get collectionRenamePlaylist;

  /// Action to delete playlist
  ///
  /// In en, this message translates to:
  /// **'Delete playlist'**
  String get collectionDeletePlaylist;

  /// Snackbar after renaming playlist
  ///
  /// In en, this message translates to:
  /// **'Playlist renamed'**
  String get collectionPlaylistRenamed;

  /// Wishlist empty state title
  ///
  /// In en, this message translates to:
  /// **'Wishlist is empty'**
  String get collectionWishlistEmptyTitle;

  /// Wishlist empty state subtitle
  ///
  /// In en, this message translates to:
  /// **'Tap + on tracks to save what you want to download later'**
  String get collectionWishlistEmptySubtitle;

  /// Loved empty state title
  ///
  /// In en, this message translates to:
  /// **'Loved folder is empty'**
  String get collectionLovedEmptyTitle;

  /// Loved empty state subtitle
  ///
  /// In en, this message translates to:
  /// **'Tap love on tracks to keep your favorites'**
  String get collectionLovedEmptySubtitle;

  /// Favorite artists empty state title
  ///
  /// In en, this message translates to:
  /// **'No favorite artists yet'**
  String get collectionFavoriteArtistsEmptyTitle;

  /// Favorite artists empty state subtitle
  ///
  /// In en, this message translates to:
  /// **'Tap the heart on an artist page to keep them here'**
  String get collectionFavoriteArtistsEmptySubtitle;

  /// Playlist empty state title
  ///
  /// In en, this message translates to:
  /// **'Playlist is empty'**
  String get collectionPlaylistEmptyTitle;

  /// Playlist empty state subtitle
  ///
  /// In en, this message translates to:
  /// **'Long-press + on any track to add it here'**
  String get collectionPlaylistEmptySubtitle;

  /// Tooltip for removing track from playlist
  ///
  /// In en, this message translates to:
  /// **'Remove from playlist'**
  String get collectionRemoveFromPlaylist;

  /// Tooltip for removing track from wishlist/loved folder
  ///
  /// In en, this message translates to:
  /// **'Remove from folder'**
  String get collectionRemoveFromFolder;

  /// Snackbar after adding track to loved folder
  ///
  /// In en, this message translates to:
  /// **'\"{trackName}\" added to Loved'**
  String collectionAddedToLoved(String trackName);

  /// Snackbar after removing track from loved folder
  ///
  /// In en, this message translates to:
  /// **'\"{trackName}\" removed from Loved'**
  String collectionRemovedFromLoved(String trackName);

  /// Snackbar after adding track to wishlist
  ///
  /// In en, this message translates to:
  /// **'\"{trackName}\" added to Wishlist'**
  String collectionAddedToWishlist(String trackName);

  /// Snackbar after removing track from wishlist
  ///
  /// In en, this message translates to:
  /// **'\"{trackName}\" removed from Wishlist'**
  String collectionRemovedFromWishlist(String trackName);

  /// Snackbar after adding artist to favorite artists
  ///
  /// In en, this message translates to:
  /// **'\"{artistName}\" added to Favorite Artists'**
  String collectionAddedToFavoriteArtists(String artistName);

  /// Snackbar after removing artist from favorite artists
  ///
  /// In en, this message translates to:
  /// **'\"{artistName}\" removed from Favorite Artists'**
  String collectionRemovedFromFavoriteArtists(String artistName);

  /// Bottom sheet action label - add track to loved folder
  ///
  /// In en, this message translates to:
  /// **'Add to Loved'**
  String get trackOptionAddToLoved;

  /// Bottom sheet action label - remove track from loved folder
  ///
  /// In en, this message translates to:
  /// **'Remove from Loved'**
  String get trackOptionRemoveFromLoved;

  /// Bottom sheet action label - add track to wishlist
  ///
  /// In en, this message translates to:
  /// **'Add to Wishlist'**
  String get trackOptionAddToWishlist;

  /// Bottom sheet action label - remove track from wishlist
  ///
  /// In en, this message translates to:
  /// **'Remove from Wishlist'**
  String get trackOptionRemoveFromWishlist;

  /// Action label - add artist to favorite artists
  ///
  /// In en, this message translates to:
  /// **'Add to Favorite Artists'**
  String get artistOptionAddToFavorites;

  /// Action label - remove artist from favorite artists
  ///
  /// In en, this message translates to:
  /// **'Remove from Favorite Artists'**
  String get artistOptionRemoveFromFavorites;

  /// Bottom sheet action to pick a custom cover image for a playlist
  ///
  /// In en, this message translates to:
  /// **'Change cover image'**
  String get collectionPlaylistChangeCover;

  /// Bottom sheet action to remove custom cover image from a playlist
  ///
  /// In en, this message translates to:
  /// **'Remove cover image'**
  String get collectionPlaylistRemoveCover;

  /// Share button text with count in selection mode
  ///
  /// In en, this message translates to:
  /// **'Share {count} {count, plural, =1{track} other{tracks}}'**
  String selectionShareCount(int count);

  /// Snackbar when no selected files exist on disk
  ///
  /// In en, this message translates to:
  /// **'No shareable files found'**
  String get selectionShareNoFiles;

  /// Convert button text with count in selection mode
  ///
  /// In en, this message translates to:
  /// **'Convert {count} {count, plural, =1{track} other{tracks}}'**
  String selectionConvertCount(int count);

  /// Snackbar when no selected tracks support conversion
  ///
  /// In en, this message translates to:
  /// **'No convertible tracks selected'**
  String get selectionConvertNoConvertible;

  /// Confirmation dialog title for batch conversion
  ///
  /// In en, this message translates to:
  /// **'Batch Convert'**
  String get selectionBatchConvertConfirmTitle;

  /// Confirmation dialog message for batch conversion
  ///
  /// In en, this message translates to:
  /// **'Convert {count} {count, plural, =1{track} other{tracks}} to {format} at {bitrate}?\n\nOriginal files will be deleted after conversion.'**
  String selectionBatchConvertConfirmMessage(
    int count,
    String format,
    String bitrate,
  );

  /// Confirmation dialog message for lossless batch conversion
  ///
  /// In en, this message translates to:
  /// **'Convert {count} {count, plural, =1{track} other{tracks}} to {format}? (Lossless — no quality loss)\n\nOriginal files will be deleted after conversion.'**
  String selectionBatchConvertConfirmMessageLossless(int count, String format);

  /// Batch conversion confirmation when source files will be preserved
  ///
  /// In en, this message translates to:
  /// **'Convert {count} {count, plural, =1{track} other{tracks}} to {format}?\n\nOriginal files will be kept and converted files will be added as separate library entries.'**
  String selectionBatchConvertConfirmKeepOriginal(int count, String format);

  /// Snackbar after batch conversion completes
  ///
  /// In en, this message translates to:
  /// **'Converted {success} of {total} tracks to {format}'**
  String selectionBatchConvertSuccess(int success, int total, String format);

  /// Downloaded tracks count badge
  ///
  /// In en, this message translates to:
  /// **'{count} downloaded'**
  String downloadedAlbumDownloadedCount(int count);

  /// Subtitle when album artist is used for folder names
  ///
  /// In en, this message translates to:
  /// **'Folder named after Album Artist tag'**
  String get downloadUseAlbumArtistForFoldersAlbumSubtitle;

  /// Subtitle when track artist is used for folder names
  ///
  /// In en, this message translates to:
  /// **'Folder named after Track Artist tag'**
  String get downloadUseAlbumArtistForFoldersTrackSubtitle;

  /// Settings item title for lyrics provider order
  ///
  /// In en, this message translates to:
  /// **'Lyrics Provider Priority'**
  String get lyricsProvidersTitle;

  /// Description on the lyrics provider priority page
  ///
  /// In en, this message translates to:
  /// **'Enable, disable and reorder lyrics sources. Providers are tried top-to-bottom until lyrics are found.'**
  String get lyricsProvidersDescription;

  /// Info tip on lyrics provider priority page
  ///
  /// In en, this message translates to:
  /// **'Extension lyrics providers run before built-in lyrics providers. At least one provider must remain enabled.'**
  String get lyricsProvidersInfoText;

  /// Section header for enabled providers
  ///
  /// In en, this message translates to:
  /// **'Enabled ({count})'**
  String lyricsProvidersEnabledSection(int count);

  /// Section header for disabled providers
  ///
  /// In en, this message translates to:
  /// **'Disabled ({count})'**
  String lyricsProvidersDisabledSection(int count);

  /// Snackbar when user tries to disable the last enabled provider
  ///
  /// In en, this message translates to:
  /// **'At least one provider must remain enabled'**
  String get lyricsProvidersAtLeastOne;

  /// Snackbar after saving lyrics provider priority
  ///
  /// In en, this message translates to:
  /// **'Lyrics provider priority saved'**
  String get lyricsProvidersSaved;

  /// Body text of the discard-changes dialog on lyrics provider page
  ///
  /// In en, this message translates to:
  /// **'You have unsaved changes that will be lost.'**
  String get lyricsProvidersDiscardContent;

  /// Description for LRCLIB provider
  ///
  /// In en, this message translates to:
  /// **'Open-source synced lyrics database'**
  String get lyricsProviderLrclibDesc;

  /// Description for Netease provider
  ///
  /// In en, this message translates to:
  /// **'NetEase Cloud Music (good for Asian songs)'**
  String get lyricsProviderNeteaseDesc;

  /// Description for Musixmatch provider
  ///
  /// In en, this message translates to:
  /// **'Largest lyrics database (multi-language)'**
  String get lyricsProviderMusixmatchDesc;

  /// Description for Apple Music provider
  ///
  /// In en, this message translates to:
  /// **'Word-by-word synced lyrics (via proxy)'**
  String get lyricsProviderAppleMusicDesc;

  /// Description for QQ Music provider
  ///
  /// In en, this message translates to:
  /// **'QQ Music (good for Chinese songs, via proxy)'**
  String get lyricsProviderQqMusicDesc;

  /// Description for LyricsPlus provider
  ///
  /// In en, this message translates to:
  /// **'Word-by-word karaoke lyrics (Apple/Musixmatch/Spotify/QQ, via proxy)'**
  String get lyricsProviderLyricsPlusDesc;

  /// Generic description for extension-based lyrics providers
  ///
  /// In en, this message translates to:
  /// **'Extension provider'**
  String get lyricsProviderExtensionDesc;

  /// Title of SAF migration dialog
  ///
  /// In en, this message translates to:
  /// **'Storage Update Required'**
  String get safMigrationTitle;

  /// First paragraph of SAF migration dialog
  ///
  /// In en, this message translates to:
  /// **'SpotiFLAC now uses Android Storage Access Framework (SAF) for downloads. This fixes \"permission denied\" errors on Android 10+.'**
  String get safMigrationMessage1;

  /// Second paragraph of SAF migration dialog
  ///
  /// In en, this message translates to:
  /// **'Please select your download folder again to switch to the new storage system.'**
  String get safMigrationMessage2;

  /// Snackbar after successfully migrating to SAF
  ///
  /// In en, this message translates to:
  /// **'Download folder updated to SAF mode'**
  String get safMigrationSuccess;

  /// Settings menu item - donate page
  ///
  /// In en, this message translates to:
  /// **'Support Development'**
  String get settingsDonate;

  /// Subtitle for donate menu item
  ///
  /// In en, this message translates to:
  /// **'Buy the developer a coffee'**
  String get settingsDonateSubtitle;

  /// Settings menu item - backup and restore page
  ///
  /// In en, this message translates to:
  /// **'Backup & Restore'**
  String get settingsBackup;

  /// Subtitle for backup and restore settings item
  ///
  /// In en, this message translates to:
  /// **'Move your library, history and settings to a new device'**
  String get settingsBackupSubtitle;

  /// App bar title for the backup and restore page
  ///
  /// In en, this message translates to:
  /// **'Backup & Restore'**
  String get backupTitle;

  /// Section title for the export/backup card
  ///
  /// In en, this message translates to:
  /// **'Create backup'**
  String get backupExportSectionTitle;

  /// Description of what a backup contains
  ///
  /// In en, this message translates to:
  /// **'Save your settings, download history, liked tracks, wishlist, favorite artists and playlists into a single file you can keep or move to another phone.'**
  String get backupExportSectionDescription;

  /// Button to create and share a backup file
  ///
  /// In en, this message translates to:
  /// **'Create backup file'**
  String get backupExportButton;

  /// Section title for the import/restore card
  ///
  /// In en, this message translates to:
  /// **'Restore backup'**
  String get backupImportSectionTitle;

  /// Description for the restore action
  ///
  /// In en, this message translates to:
  /// **'Pick a backup file to restore your data. This replaces the current settings, history and library on this device.'**
  String get backupImportSectionDescription;

  /// Button to pick a backup file to restore
  ///
  /// In en, this message translates to:
  /// **'Choose backup file'**
  String get backupImportButton;

  /// Snackbar after a backup file is created
  ///
  /// In en, this message translates to:
  /// **'Backup created'**
  String get backupCreated;

  /// Snackbar when backup creation fails
  ///
  /// In en, this message translates to:
  /// **'Failed to create backup'**
  String get backupCreateFailed;

  /// Confirmation dialog title before restoring a backup
  ///
  /// In en, this message translates to:
  /// **'Restore this backup?'**
  String get backupRestoreConfirmTitle;

  /// Confirmation dialog message before restoring a backup
  ///
  /// In en, this message translates to:
  /// **'This will replace your current settings, download history, liked tracks, wishlist and playlists with the contents of the backup. This cannot be undone.'**
  String get backupRestoreConfirmMessage;

  /// Confirm button to proceed with restore
  ///
  /// In en, this message translates to:
  /// **'Restore'**
  String get backupRestoreConfirmButton;

  /// Snackbar after a successful restore
  ///
  /// In en, this message translates to:
  /// **'Backup restored successfully'**
  String get backupRestored;

  /// Snackbar when restore fails
  ///
  /// In en, this message translates to:
  /// **'Failed to restore backup'**
  String get backupRestoreFailed;

  /// Snackbar when the chosen file is not a valid backup
  ///
  /// In en, this message translates to:
  /// **'This file is not a valid SpotiFLAC backup'**
  String get backupInvalidFile;

  /// Hint shown after restoring that an app restart is recommended
  ///
  /// In en, this message translates to:
  /// **'Restart the app to make sure every change is applied.'**
  String get backupRestoreRestartHint;

  /// Header above the list summarizing what the backup contains
  ///
  /// In en, this message translates to:
  /// **'Backup contents'**
  String get backupContentsTitle;

  /// Backup contents row label for settings
  ///
  /// In en, this message translates to:
  /// **'App settings'**
  String get backupContentsSettings;

  /// Backup contents row for history count
  ///
  /// In en, this message translates to:
  /// **'{count} history {count, plural, =1{item} other{items}}'**
  String backupContentsHistory(int count);

  /// Backup contents row for liked tracks count
  ///
  /// In en, this message translates to:
  /// **'{count} liked {count, plural, =1{track} other{tracks}}'**
  String backupContentsLiked(int count);

  /// Backup contents row for wishlist tracks count
  ///
  /// In en, this message translates to:
  /// **'{count} wishlist {count, plural, =1{track} other{tracks}}'**
  String backupContentsWishlist(int count);

  /// Backup contents row for playlist count
  ///
  /// In en, this message translates to:
  /// **'{count, plural, =1{1 playlist} other{{count} playlists}}'**
  String backupContentsPlaylists(int count);

  /// Backup contents row for favorite artists count
  ///
  /// In en, this message translates to:
  /// **'{count, plural, =1{1 favorite artist} other{{count} favorite artists}}'**
  String backupContentsArtists(int count);

  /// Backup contents row for installed extensions count
  ///
  /// In en, this message translates to:
  /// **'{count, plural, =1{1 extension} other{{count} extensions}}'**
  String backupContentsExtensions(int count);

  /// Toggle to include secret extension settings (tokens, API keys) in the backup
  ///
  /// In en, this message translates to:
  /// **'Include extension credentials'**
  String get backupIncludeSecrets;

  /// Explanation for the include-credentials toggle
  ///
  /// In en, this message translates to:
  /// **'Tokens and API keys from extensions will be saved into the backup file. Keep the file private. When off, you re-enter them after restoring.'**
  String get backupIncludeSecretsDescription;

  /// Snackbar/hint when some extensions failed to reinstall during restore
  ///
  /// In en, this message translates to:
  /// **'{count} {count, plural, =1{extension} other{extensions}} could not be reinstalled. Install them manually from the repo.'**
  String backupExtensionsRestoreFailed(int count);

  /// Tooltip for the Love All button on album/playlist screens
  ///
  /// In en, this message translates to:
  /// **'Love All'**
  String get tooltipLoveAll;

  /// Tooltip for the Add to Playlist button
  ///
  /// In en, this message translates to:
  /// **'Add to Playlist'**
  String get tooltipAddToPlaylist;

  /// Snackbar after removing multiple tracks from Loved folder
  ///
  /// In en, this message translates to:
  /// **'Removed {count} tracks from Loved'**
  String snackbarRemovedTracksFromLoved(int count);

  /// Snackbar after adding multiple tracks to Loved folder
  ///
  /// In en, this message translates to:
  /// **'Added {count} tracks to Loved'**
  String snackbarAddedTracksToLoved(int count);

  /// Dialog title for bulk download confirmation
  ///
  /// In en, this message translates to:
  /// **'Download All'**
  String get dialogDownloadAllTitle;

  /// Body of the Download All confirmation dialog
  ///
  /// In en, this message translates to:
  /// **'Download {count} tracks?'**
  String dialogDownloadAllMessage(int count);

  /// Checkbox label in import dialog to skip already-downloaded songs
  ///
  /// In en, this message translates to:
  /// **'Skip already downloaded songs'**
  String get homeSkipAlreadyDownloaded;

  /// Context menu item to navigate to the album page
  ///
  /// In en, this message translates to:
  /// **'Go to Album'**
  String get homeGoToAlbum;

  /// Snackbar when album info cannot be loaded
  ///
  /// In en, this message translates to:
  /// **'Album info not available'**
  String get homeAlbumInfoUnavailable;

  /// Snackbar while loading a CUE sheet file
  ///
  /// In en, this message translates to:
  /// **'Loading CUE sheet...'**
  String get snackbarLoadingCueSheet;

  /// Snackbar after successfully saving track metadata
  ///
  /// In en, this message translates to:
  /// **'Metadata saved successfully'**
  String get snackbarMetadataSaved;

  /// Snackbar when lyrics embedding fails
  ///
  /// In en, this message translates to:
  /// **'Failed to embed lyrics'**
  String get snackbarFailedToEmbedLyrics;

  /// Snackbar when writing metadata back to file fails
  ///
  /// In en, this message translates to:
  /// **'Failed to write back to storage'**
  String get snackbarFailedToWriteStorage;

  /// Generic error snackbar with error detail
  ///
  /// In en, this message translates to:
  /// **'Error: {error}'**
  String snackbarError(String error);

  /// Snackbar when an extension button has no action configured
  ///
  /// In en, this message translates to:
  /// **'No action defined for this button'**
  String get snackbarNoActionDefined;

  /// Empty state message when an album has no tracks
  ///
  /// In en, this message translates to:
  /// **'No tracks found for this album'**
  String get noTracksFoundForAlbum;

  /// Subtitle shown in the download location picker sheet
  ///
  /// In en, this message translates to:
  /// **'Choose where to save your downloaded tracks'**
  String get downloadLocationSubtitle;

  /// Storage mode option - app-managed folder
  ///
  /// In en, this message translates to:
  /// **'App Folder (Recommended)'**
  String get storageModeAppFolder;

  /// Subtitle for app folder storage mode
  ///
  /// In en, this message translates to:
  /// **'Saves to Music/SpotiFLAC by default'**
  String get storageModeAppFolderSubtitle;

  /// Storage mode option - Storage Access Framework
  ///
  /// In en, this message translates to:
  /// **'Custom Folder (SAF)'**
  String get storageModeSaf;

  /// Subtitle for SAF storage mode
  ///
  /// In en, this message translates to:
  /// **'Pick any folder, including SD card'**
  String get storageModeSafSubtitle;

  /// Title of the warning banner shown in Files settings when the saved SAF folder grant is no longer valid
  ///
  /// In en, this message translates to:
  /// **'Download folder access lost'**
  String get downloadFolderAccessLostTitle;

  /// Subtitle of the warning banner shown when the saved SAF folder grant is no longer valid
  ///
  /// In en, this message translates to:
  /// **'Downloads will fail until you re-select the folder'**
  String get downloadFolderAccessLostSubtitle;

  /// Button that reopens the folder picker to restore download folder access
  ///
  /// In en, this message translates to:
  /// **'Re-select folder'**
  String get downloadFolderReselect;

  /// Error shown on downloads that failed because the persisted Android SAF folder grant is no longer valid
  ///
  /// In en, this message translates to:
  /// **'SAF permission invalid or revoked. Please reconfigure download location in Settings.'**
  String get downloadErrorSafPermissionLost;

  /// Error shown on downloads that failed because the iOS download folder bookmark could not be opened
  ///
  /// In en, this message translates to:
  /// **'Download folder access lost. Please re-select your download folder in Settings.'**
  String get downloadErrorFolderAccessLost;

  /// Description shown in filename format editor
  ///
  /// In en, this message translates to:
  /// **'Use {artist}, {title}, {album}, {track}, {year}, {date}, {disc} as placeholders.'**
  String downloadFilenameDescription(
    Object album,
    Object artist,
    Object date,
    Object disc,
    Object title,
    Object track,
    Object year,
  );

  /// Label above filename tag chips
  ///
  /// In en, this message translates to:
  /// **'Tap to insert tag:'**
  String get downloadFilenameInsertTag;

  /// Subtitle when separate singles folder is on
  ///
  /// In en, this message translates to:
  /// **'Singles and EPs saved in a separate folder'**
  String get downloadSeparateSinglesEnabled;

  /// Subtitle when separate singles folder is off
  ///
  /// In en, this message translates to:
  /// **'Singles and albums saved in the same folder'**
  String get downloadSeparateSinglesDisabled;

  /// Setting title for artist folder filter options
  ///
  /// In en, this message translates to:
  /// **'Artist Name Filters'**
  String get downloadArtistNameFilters;

  /// Setting to create a subfolder per playlist source
  ///
  /// In en, this message translates to:
  /// **'Playlist Source Folder'**
  String get downloadCreatePlaylistSourceFolder;

  /// Subtitle when playlist folder is enabled
  ///
  /// In en, this message translates to:
  /// **'A subfolder is created for each playlist'**
  String get downloadCreatePlaylistSourceFolderEnabled;

  /// Subtitle when playlist folder is disabled
  ///
  /// In en, this message translates to:
  /// **'All tracks saved directly to download folder'**
  String get downloadCreatePlaylistSourceFolderDisabled;

  /// Subtitle when folder organization is already set to playlist
  ///
  /// In en, this message translates to:
  /// **'Handled by folder organization setting'**
  String get downloadCreatePlaylistSourceFolderRedundant;

  /// Setting for SongLink region used during fallback resolution
  ///
  /// In en, this message translates to:
  /// **'SongLink Region'**
  String get downloadSongLinkRegion;

  /// Setting for legacy TLS/network handling
  ///
  /// In en, this message translates to:
  /// **'Network Compatibility Mode'**
  String get downloadNetworkCompatibilityMode;

  /// Subtitle when network compatibility mode is on
  ///
  /// In en, this message translates to:
  /// **'Using legacy TLS settings for older networks'**
  String get downloadNetworkCompatibilityModeEnabled;

  /// Subtitle when network compatibility mode is off
  ///
  /// In en, this message translates to:
  /// **'Using standard network settings'**
  String get downloadNetworkCompatibilityModeDisabled;

  /// Setting title for allowing requests to private/local network targets
  ///
  /// In en, this message translates to:
  /// **'Allow Local Network Access'**
  String get downloadAllowLocalNetwork;

  /// Subtitle when allow local network access is on
  ///
  /// In en, this message translates to:
  /// **'Requests to local/private addresses are allowed (for local proxy or custom DNS)'**
  String get downloadAllowLocalNetworkEnabled;

  /// Subtitle when allow local network access is off
  ///
  /// In en, this message translates to:
  /// **'Local/private addresses are blocked for security'**
  String get downloadAllowLocalNetworkDisabled;

  /// Subtitle when quality picker is disabled due to extension service
  ///
  /// In en, this message translates to:
  /// **'Select a provider with quality options to enable this option'**
  String get downloadSelectServiceToEnable;

  /// Subtitle when lyrics embedding is blocked by metadata toggle
  ///
  /// In en, this message translates to:
  /// **'Enable metadata embedding first'**
  String get downloadEmbedLyricsDisabled;

  /// Setting to include translated lyrics from Netease
  ///
  /// In en, this message translates to:
  /// **'Netease: Include Translation'**
  String get downloadNeteaseIncludeTranslation;

  /// Subtitle when Netease translation is on
  ///
  /// In en, this message translates to:
  /// **'Chinese translation lines included'**
  String get downloadNeteaseIncludeTranslationEnabled;

  /// Subtitle when Netease translation is off
  ///
  /// In en, this message translates to:
  /// **'Original lyrics only'**
  String get downloadNeteaseIncludeTranslationDisabled;

  /// Setting to include romanized lyrics from Netease
  ///
  /// In en, this message translates to:
  /// **'Netease: Include Romanization'**
  String get downloadNeteaseIncludeRomanization;

  /// Subtitle when Netease romanization is on
  ///
  /// In en, this message translates to:
  /// **'Romanization lines included'**
  String get downloadNeteaseIncludeRomanizationEnabled;

  /// Subtitle when Netease romanization is off
  ///
  /// In en, this message translates to:
  /// **'No romanization'**
  String get downloadNeteaseIncludeRomanizationDisabled;

  /// Setting for word-by-word multi-person lyrics from Apple Music and QQ Music
  ///
  /// In en, this message translates to:
  /// **'Apple / QQ: Multi-Person Lyrics'**
  String get downloadAppleQqMultiPerson;

  /// Subtitle when multi-person lyrics is on
  ///
  /// In en, this message translates to:
  /// **'Speaker labels included for duets and group tracks'**
  String get downloadAppleQqMultiPersonEnabled;

  /// Subtitle when multi-person lyrics is off
  ///
  /// In en, this message translates to:
  /// **'Standard lyrics without speaker labels'**
  String get downloadAppleQqMultiPersonDisabled;

  /// Setting for preserving Apple Music word-by-word eLRC timestamps
  ///
  /// In en, this message translates to:
  /// **'Apple Music eLRC Word Sync'**
  String get downloadAppleElrcWordSync;

  /// Subtitle when Apple Music eLRC word sync is enabled
  ///
  /// In en, this message translates to:
  /// **'Raw word-by-word timestamps preserved'**
  String get downloadAppleElrcWordSyncEnabled;

  /// Subtitle when Apple Music eLRC word sync is disabled
  ///
  /// In en, this message translates to:
  /// **'Safer line-by-line Apple Music lyrics'**
  String get downloadAppleElrcWordSyncDisabled;

  /// Setting for Musixmatch lyrics translation language
  ///
  /// In en, this message translates to:
  /// **'Musixmatch Language'**
  String get downloadMusixmatchLanguage;

  /// Subtitle when no language is set
  ///
  /// In en, this message translates to:
  /// **'Auto (original language)'**
  String get downloadMusixmatchLanguageAuto;

  /// Setting to strip contributing artists from Album Artist folder name
  ///
  /// In en, this message translates to:
  /// **'Filter Contributing Artists'**
  String get downloadFilterContributing;

  /// Subtitle when contributing artist filter is on
  ///
  /// In en, this message translates to:
  /// **'Contributing artists removed from Album Artist folder name'**
  String get downloadFilterContributingEnabled;

  /// Subtitle when contributing artist filter is off
  ///
  /// In en, this message translates to:
  /// **'Full Album Artist string used'**
  String get downloadFilterContributingDisabled;

  /// Shown when no lyrics providers are active
  ///
  /// In en, this message translates to:
  /// **'No providers enabled'**
  String get downloadProvidersNoneEnabled;

  /// Label for Musixmatch language input field
  ///
  /// In en, this message translates to:
  /// **'Language code'**
  String get downloadMusixmatchLanguageCode;

  /// Placeholder for Musixmatch language input
  ///
  /// In en, this message translates to:
  /// **'e.g. en, de, ja'**
  String get downloadMusixmatchLanguageHint;

  /// Description in Musixmatch language picker
  ///
  /// In en, this message translates to:
  /// **'Enter a BCP-47 language code (e.g. en, de, ja) to request translated lyrics from Musixmatch.'**
  String get downloadMusixmatchLanguageDesc;

  /// Button to clear Musixmatch language (use auto)
  ///
  /// In en, this message translates to:
  /// **'Auto'**
  String get downloadMusixmatchAuto;

  /// Subtitle for any-network option in picker
  ///
  /// In en, this message translates to:
  /// **'Use WiFi or mobile data'**
  String get downloadNetworkAnySubtitle;

  /// Subtitle for WiFi-only option in picker
  ///
  /// In en, this message translates to:
  /// **'Downloads pause when on mobile data'**
  String get downloadNetworkWifiOnlySubtitle;

  /// Description in SongLink region picker
  ///
  /// In en, this message translates to:
  /// **'Region used when resolving track links via SongLink. Choose the country where your streaming services are available.'**
  String get downloadSongLinkRegionDesc;

  /// Snackbar when the audio format is not supported for the requested operation
  ///
  /// In en, this message translates to:
  /// **'Unsupported audio format'**
  String get snackbarUnsupportedAudioFormat;

  /// Tooltip for refresh button on cache management page
  ///
  /// In en, this message translates to:
  /// **'Refresh'**
  String get cacheRefresh;

  /// Dialog message for bulk playlist download confirmation
  ///
  /// In en, this message translates to:
  /// **'Download {trackCount} {trackCount, plural, =1{track} other{tracks}} from {playlistCount} {playlistCount, plural, =1{playlist} other{playlists}}?'**
  String dialogDownloadPlaylistsMessage(int trackCount, int playlistCount);

  /// Button label for bulk downloading selected playlists
  ///
  /// In en, this message translates to:
  /// **'Download {count} {count, plural, =1{playlist} other{playlists}}'**
  String bulkDownloadPlaylistsButton(int count);

  /// Button label when no playlists are selected for download
  ///
  /// In en, this message translates to:
  /// **'Select playlists to download'**
  String get bulkDownloadSelectPlaylists;

  /// Snackbar when selected playlists contain no tracks
  ///
  /// In en, this message translates to:
  /// **'Selected playlists have no tracks'**
  String get snackbarSelectedPlaylistsEmpty;

  /// Playlist count display
  ///
  /// In en, this message translates to:
  /// **'{count, plural, =1{1 playlist} other{{count} playlists}}'**
  String playlistsCount(int count);

  /// Section title for selective online metadata auto-fill in the edit metadata sheet
  ///
  /// In en, this message translates to:
  /// **'Auto-fill from online'**
  String get editMetadataAutoFill;

  /// Description for the auto-fill section
  ///
  /// In en, this message translates to:
  /// **'Choose a metadata extension, select fields, then review its data before applying'**
  String get editMetadataAutoFillDesc;

  /// Label for the metadata extension selector in online auto-fill
  ///
  /// In en, this message translates to:
  /// **'Metadata source'**
  String get editMetadataAutoFillSource;

  /// Automatic source option that follows configured metadata provider priority
  ///
  /// In en, this message translates to:
  /// **'Automatic (provider priority)'**
  String get editMetadataAutoFillSourceAutomatic;

  /// Button label for finding an online metadata candidate
  ///
  /// In en, this message translates to:
  /// **'Find metadata'**
  String get editMetadataAutoFillFind;

  /// Title for the online metadata preview
  ///
  /// In en, this message translates to:
  /// **'Data from {source}'**
  String editMetadataAutoFillPreview(String source);

  /// Preview value when the selected metadata source provides cover artwork
  ///
  /// In en, this message translates to:
  /// **'Cover artwork available'**
  String get editMetadataAutoFillCoverAvailable;

  /// Button label for applying the previewed metadata
  ///
  /// In en, this message translates to:
  /// **'Apply selected data'**
  String get editMetadataAutoFillApply;

  /// Snackbar confirming fields applied from a selected metadata source
  ///
  /// In en, this message translates to:
  /// **'Filled {count} {count, plural, =1{field} other{fields}} from {source}'**
  String editMetadataAutoFillDoneFromSource(int count, String source);

  /// Button label to fetch online metadata and fill selected fields
  ///
  /// In en, this message translates to:
  /// **'Fetch & Fill'**
  String get editMetadataAutoFillFetch;

  /// Snackbar shown while searching for online metadata
  ///
  /// In en, this message translates to:
  /// **'Searching online...'**
  String get editMetadataAutoFillSearching;

  /// Snackbar when online metadata search returns no results
  ///
  /// In en, this message translates to:
  /// **'No matching metadata found online'**
  String get editMetadataAutoFillNoResults;

  /// Snackbar confirming how many fields were auto-filled
  ///
  /// In en, this message translates to:
  /// **'Filled {count} {count, plural, =1{field} other{fields}} from online metadata'**
  String editMetadataAutoFillDone(int count);

  /// Snackbar when user taps Fetch without selecting any fields
  ///
  /// In en, this message translates to:
  /// **'Select at least one field to auto-fill'**
  String get editMetadataAutoFillNoneSelected;

  /// Chip label for title field in auto-fill selector
  ///
  /// In en, this message translates to:
  /// **'Title'**
  String get editMetadataFieldTitle;

  /// Chip label for artist field in auto-fill selector
  ///
  /// In en, this message translates to:
  /// **'Artist'**
  String get editMetadataFieldArtist;

  /// Chip label for album field in auto-fill selector
  ///
  /// In en, this message translates to:
  /// **'Album'**
  String get editMetadataFieldAlbum;

  /// Chip label for album artist field in auto-fill selector
  ///
  /// In en, this message translates to:
  /// **'Album Artist'**
  String get editMetadataFieldAlbumArtist;

  /// Chip label for date field in auto-fill selector
  ///
  /// In en, this message translates to:
  /// **'Date'**
  String get editMetadataFieldDate;

  /// Chip label for track number field in auto-fill selector
  ///
  /// In en, this message translates to:
  /// **'Track #'**
  String get editMetadataFieldTrackNum;

  /// Chip label for disc number field in auto-fill selector
  ///
  /// In en, this message translates to:
  /// **'Disc #'**
  String get editMetadataFieldDiscNum;

  /// Chip label for genre field in auto-fill selector
  ///
  /// In en, this message translates to:
  /// **'Genre'**
  String get editMetadataFieldGenre;

  /// Chip label for ISRC field in auto-fill selector
  ///
  /// In en, this message translates to:
  /// **'ISRC'**
  String get editMetadataFieldIsrc;

  /// Chip label for label field in auto-fill selector
  ///
  /// In en, this message translates to:
  /// **'Label'**
  String get editMetadataFieldLabel;

  /// Chip label for copyright field in auto-fill selector
  ///
  /// In en, this message translates to:
  /// **'Copyright'**
  String get editMetadataFieldCopyright;

  /// Chip label for cover art field in auto-fill selector
  ///
  /// In en, this message translates to:
  /// **'Cover Art'**
  String get editMetadataFieldCover;

  /// Button to select all fields for auto-fill
  ///
  /// In en, this message translates to:
  /// **'All'**
  String get editMetadataSelectAll;

  /// Button to select only fields that are currently empty
  ///
  /// In en, this message translates to:
  /// **'Empty only'**
  String get editMetadataSelectEmpty;

  /// Header for active downloads section with count
  ///
  /// In en, this message translates to:
  /// **'Downloading ({count})'**
  String queueDownloadingCount(int count);

  /// Shown while filter results are being computed
  ///
  /// In en, this message translates to:
  /// **'Filtering...'**
  String get queueFilteringIndicator;

  /// Track count label with plural support
  ///
  /// In en, this message translates to:
  /// **'{count, plural, =1{1 track} other{{count} tracks}}'**
  String queueTrackCount(int count);

  /// Album count label with plural support
  ///
  /// In en, this message translates to:
  /// **'{count, plural, =1{1 album} other{{count} albums}}'**
  String queueAlbumCount(int count);

  /// Empty state title when no album downloads exist
  ///
  /// In en, this message translates to:
  /// **'No album downloads'**
  String get queueEmptyAlbums;

  /// Empty state subtitle for album downloads
  ///
  /// In en, this message translates to:
  /// **'Download multiple tracks from an album to see them here'**
  String get queueEmptyAlbumsSubtitle;

  /// Empty state title when no single track downloads exist
  ///
  /// In en, this message translates to:
  /// **'No single downloads'**
  String get queueEmptySingles;

  /// Empty state subtitle for single track downloads
  ///
  /// In en, this message translates to:
  /// **'Single track downloads will appear here'**
  String get queueEmptySinglesSubtitle;

  /// Playlist count label with plural support
  ///
  /// In en, this message translates to:
  /// **'{count, plural, =1{1 playlist} other{{count} playlists}}'**
  String queuePlaylistCount(int count);

  /// Empty state subtitle for the playlists library view
  ///
  /// In en, this message translates to:
  /// **'Create a playlist to organize your tracks'**
  String get queueEmptyPlaylistsSubtitle;

  /// Setting title - which library view opens when switching to the Library tab
  ///
  /// In en, this message translates to:
  /// **'Default view'**
  String get libraryDefaultView;

  /// Default view option - keep the last used library view
  ///
  /// In en, this message translates to:
  /// **'Last used'**
  String get libraryDefaultViewLastUsed;

  /// Empty state title when download history is empty
  ///
  /// In en, this message translates to:
  /// **'No download history'**
  String get queueEmptyHistory;

  /// Empty state subtitle for download history
  ///
  /// In en, this message translates to:
  /// **'Downloaded tracks will appear here'**
  String get queueEmptyHistorySubtitle;

  /// Shown when all playlists are selected in selection mode
  ///
  /// In en, this message translates to:
  /// **'All playlists selected'**
  String get selectionAllPlaylistsSelected;

  /// Hint shown in playlist selection mode
  ///
  /// In en, this message translates to:
  /// **'Tap playlists to select'**
  String get selectionTapPlaylistsToSelect;

  /// Hint shown when no playlists are selected for deletion
  ///
  /// In en, this message translates to:
  /// **'Select playlists to delete'**
  String get selectionSelectPlaylistsToDelete;

  /// Title for audio analysis section
  ///
  /// In en, this message translates to:
  /// **'Audio Quality Analysis'**
  String get audioAnalysisTitle;

  /// Description for audio analysis tap-to-analyze prompt
  ///
  /// In en, this message translates to:
  /// **'Verify lossless quality with spectrum analysis'**
  String get audioAnalysisDescription;

  /// Loading text while analyzing audio
  ///
  /// In en, this message translates to:
  /// **'Analyzing audio...'**
  String get audioAnalysisAnalyzing;

  /// Sample rate metric label
  ///
  /// In en, this message translates to:
  /// **'Sample Rate'**
  String get audioAnalysisSampleRate;

  /// Audio codec metric label
  ///
  /// In en, this message translates to:
  /// **'Codec'**
  String get audioAnalysisCodec;

  /// Audio container metric label
  ///
  /// In en, this message translates to:
  /// **'Container'**
  String get audioAnalysisContainer;

  /// Decoded sample format metric label
  ///
  /// In en, this message translates to:
  /// **'Decoded Format'**
  String get audioAnalysisDecodedFormat;

  /// Bit depth metric label
  ///
  /// In en, this message translates to:
  /// **'Bit Depth'**
  String get audioAnalysisBitDepth;

  /// Channels metric label
  ///
  /// In en, this message translates to:
  /// **'Channels'**
  String get audioAnalysisChannels;

  /// Duration metric label
  ///
  /// In en, this message translates to:
  /// **'Duration'**
  String get audioAnalysisDuration;

  /// Nyquist frequency metric label
  ///
  /// In en, this message translates to:
  /// **'Nyquist'**
  String get audioAnalysisNyquist;

  /// File size metric label
  ///
  /// In en, this message translates to:
  /// **'Size'**
  String get audioAnalysisFileSize;

  /// Dynamic range metric label
  ///
  /// In en, this message translates to:
  /// **'Dynamic Range'**
  String get audioAnalysisDynamicRange;

  /// Peak amplitude metric label
  ///
  /// In en, this message translates to:
  /// **'Peak'**
  String get audioAnalysisPeak;

  /// RMS level metric label
  ///
  /// In en, this message translates to:
  /// **'RMS'**
  String get audioAnalysisRms;

  /// Integrated loudness metric label
  ///
  /// In en, this message translates to:
  /// **'LUFS'**
  String get audioAnalysisLufs;

  /// True peak metric label
  ///
  /// In en, this message translates to:
  /// **'True Peak'**
  String get audioAnalysisTruePeak;

  /// Clipping metric label
  ///
  /// In en, this message translates to:
  /// **'Clipping'**
  String get audioAnalysisClipping;

  /// Displayed when no clipped samples were detected
  ///
  /// In en, this message translates to:
  /// **'No clipping'**
  String get audioAnalysisNoClipping;

  /// Estimated spectral cutoff metric label
  ///
  /// In en, this message translates to:
  /// **'Spectral Cutoff'**
  String get audioAnalysisSpectralCutoff;

  /// Displayed when no reliable broadband spectral cutoff can be detected
  ///
  /// In en, this message translates to:
  /// **'Not detected'**
  String get audioAnalysisCutoffNotDetected;

  /// Per-channel audio analysis section label
  ///
  /// In en, this message translates to:
  /// **'Per-channel Stats'**
  String get audioAnalysisChannelStats;

  /// Total samples metric label
  ///
  /// In en, this message translates to:
  /// **'Samples'**
  String get audioAnalysisSamples;

  /// Tooltip/label for the button that re-runs the audio analysis, discarding cached results
  ///
  /// In en, this message translates to:
  /// **'Re-analyze'**
  String get audioAnalysisRescan;

  /// Loading text while audio is being re-analyzed after an explicit refresh
  ///
  /// In en, this message translates to:
  /// **'Re-analyzing audio...'**
  String get audioAnalysisRescanning;

  /// Extensions page - label for home feed provider selector
  ///
  /// In en, this message translates to:
  /// **'Home Feed Provider'**
  String get extensionsHomeFeedProvider;

  /// Extensions page - description for home feed provider picker
  ///
  /// In en, this message translates to:
  /// **'Choose which extension provides the home feed on the main screen'**
  String get extensionsHomeFeedDescription;

  /// Label for auto-selected search provider
  ///
  /// In en, this message translates to:
  /// **'Auto'**
  String get extensionsHomeFeedAuto;

  /// Extensions page - subtitle for auto home feed option
  ///
  /// In en, this message translates to:
  /// **'Automatically select the best available'**
  String get extensionsHomeFeedAutoSubtitle;

  /// Extensions page - home feed provider option: off
  ///
  /// In en, this message translates to:
  /// **'Off'**
  String get extensionsHomeFeedOff;

  /// Extensions page - subtitle for off home feed option
  ///
  /// In en, this message translates to:
  /// **'Do not show the home feed on the main screen'**
  String get extensionsHomeFeedOffSubtitle;

  /// Extensions page - subtitle for a specific extension home feed option
  ///
  /// In en, this message translates to:
  /// **'Use {extensionName} home feed'**
  String extensionsHomeFeedUse(String extensionName);

  /// Extensions page - shown when no installed extension has home feed
  ///
  /// In en, this message translates to:
  /// **'No extensions with home feed'**
  String get extensionsNoHomeFeedExtensions;

  /// Dialog title when confirming cancellation of an active download
  ///
  /// In en, this message translates to:
  /// **'Cancel download?'**
  String get cancelDownloadTitle;

  /// Dialog body when confirming cancellation of an active download
  ///
  /// In en, this message translates to:
  /// **'This will cancel the active download for \"{trackName}\".'**
  String cancelDownloadContent(String trackName);

  /// Dialog button - keep the active download (do not cancel)
  ///
  /// In en, this message translates to:
  /// **'Keep'**
  String get cancelDownloadKeep;

  /// Dialog title when opening a cancelled queue item
  ///
  /// In en, this message translates to:
  /// **'Download cancelled'**
  String get queueCancelledTitle;

  /// Dialog body when opening a cancelled queue item
  ///
  /// In en, this message translates to:
  /// **'This download was cancelled. Retry it or remove it from the queue.'**
  String get queueCancelledMessage;

  /// Snackbar error when FFmpeg fails to write metadata
  ///
  /// In en, this message translates to:
  /// **'Failed to save metadata via FFmpeg'**
  String get metadataSaveFailedFfmpeg;

  /// Snackbar error when writing metadata file back to storage fails
  ///
  /// In en, this message translates to:
  /// **'Failed to write metadata back to storage'**
  String get metadataSaveFailedStorage;

  /// Snackbar shown when folder picker fails to open
  ///
  /// In en, this message translates to:
  /// **'Failed to open folder picker: {error}'**
  String snackbarFolderPickerFailed(String error);

  /// Notification title while downloading a track
  ///
  /// In en, this message translates to:
  /// **'Downloading {trackName}'**
  String notifDownloadingTrack(String trackName);

  /// Notification title while finalizing (embedding metadata) a track
  ///
  /// In en, this message translates to:
  /// **'Finalizing {trackName}'**
  String notifFinalizingTrack(String trackName);

  /// Notification body while embedding metadata into a downloaded track
  ///
  /// In en, this message translates to:
  /// **'Embedding metadata...'**
  String get notifEmbeddingMetadata;

  /// Notification title when track is already in library, with count
  ///
  /// In en, this message translates to:
  /// **'Already in Library ({completed}/{total})'**
  String notifAlreadyInLibraryCount(int completed, int total);

  /// Notification title when track is already in library
  ///
  /// In en, this message translates to:
  /// **'Already in Library'**
  String get notifAlreadyInLibrary;

  /// Notification title when download is complete, with count
  ///
  /// In en, this message translates to:
  /// **'Download Complete ({completed}/{total})'**
  String notifDownloadCompleteCount(int completed, int total);

  /// Notification title when a single download is complete
  ///
  /// In en, this message translates to:
  /// **'Download Complete'**
  String get notifDownloadComplete;

  /// Notification title when queue finishes with some failures
  ///
  /// In en, this message translates to:
  /// **'Downloads Finished ({completed} done, {failed} failed)'**
  String notifDownloadsFinished(int completed, int failed);

  /// Notification title shown when a download needs the user to complete a verification challenge but the app is in the background
  ///
  /// In en, this message translates to:
  /// **'Verification required'**
  String get notifVerificationRequiredTitle;

  /// Notification body prompting the user to return to the app to solve a verification challenge
  ///
  /// In en, this message translates to:
  /// **'Open the app to complete verification and resume downloads'**
  String get notifVerificationRequiredBody;

  /// Notification title when all downloads finish successfully
  ///
  /// In en, this message translates to:
  /// **'All Downloads Complete'**
  String get notifAllDownloadsComplete;

  /// Notification body for queue complete - how many tracks were downloaded
  ///
  /// In en, this message translates to:
  /// **'{count, plural, =1{1 track downloaded successfully} other{{count} tracks downloaded successfully}}'**
  String notifTracksDownloadedSuccess(int count);

  /// Notification body when queue finishes with failures
  ///
  /// In en, this message translates to:
  /// **'{completed, plural, =1{1 track downloaded} other{{completed} tracks downloaded}}, {failed, plural, =1{1 failed} other{{failed} failed}}'**
  String notifDownloadsFinishedBody(int completed, int failed);

  /// Notification title when downloads are canceled by the user
  ///
  /// In en, this message translates to:
  /// **'Downloads canceled'**
  String get notifDownloadsCanceledTitle;

  /// Notification body when downloads are canceled by the user
  ///
  /// In en, this message translates to:
  /// **'{count, plural, =1{1 download canceled by user} other{{count} downloads canceled by user}}'**
  String notifDownloadsCanceledBody(int count);

  /// Notification title while scanning local library
  ///
  /// In en, this message translates to:
  /// **'Scanning local library'**
  String get notifScanningLibrary;

  /// Notification body for library scan progress when total is known
  ///
  /// In en, this message translates to:
  /// **'{scanned}/{total} files • {percentage}%'**
  String notifLibraryScanProgressWithTotal(
    int scanned,
    int total,
    int percentage,
  );

  /// Notification body for library scan progress when total is unknown
  ///
  /// In en, this message translates to:
  /// **'{scanned} files scanned • {percentage}%'**
  String notifLibraryScanProgressNoTotal(int scanned, int percentage);

  /// Notification title when library scan finishes
  ///
  /// In en, this message translates to:
  /// **'Library scan complete'**
  String get notifLibraryScanComplete;

  /// Notification body for library scan complete - number of indexed tracks
  ///
  /// In en, this message translates to:
  /// **'{count} tracks indexed'**
  String notifLibraryScanCompleteBody(int count);

  /// Library scan complete suffix - excluded track count
  ///
  /// In en, this message translates to:
  /// **'{count} excluded'**
  String notifLibraryScanExcluded(int count);

  /// Library scan complete suffix - error count
  ///
  /// In en, this message translates to:
  /// **'{count} errors'**
  String notifLibraryScanErrors(int count);

  /// Notification title when library scan fails
  ///
  /// In en, this message translates to:
  /// **'Library scan failed'**
  String get notifLibraryScanFailed;

  /// Notification title when library scan is cancelled by the user
  ///
  /// In en, this message translates to:
  /// **'Library scan cancelled'**
  String get notifLibraryScanCancelled;

  /// Notification body when library scan is cancelled
  ///
  /// In en, this message translates to:
  /// **'Scan stopped before completion.'**
  String get notifLibraryScanStopped;

  /// Notification title while downloading an app update
  ///
  /// In en, this message translates to:
  /// **'Downloading SpotiFLAC Mobile v{version}'**
  String notifDownloadingUpdate(String version);

  /// Notification body showing update download progress
  ///
  /// In en, this message translates to:
  /// **'{received} / {total} MB • {percentage}%'**
  String notifUpdateProgress(String received, String total, int percentage);

  /// Notification title when app update download is complete
  ///
  /// In en, this message translates to:
  /// **'Update Ready'**
  String get notifUpdateReady;

  /// Notification body when app update is ready to install
  ///
  /// In en, this message translates to:
  /// **'SpotiFLAC Mobile v{version} downloaded. Tap to install.'**
  String notifUpdateReadyBody(String version);

  /// Notification title when app update download fails
  ///
  /// In en, this message translates to:
  /// **'Update Failed'**
  String get notifUpdateFailed;

  /// Notification body when app update download fails
  ///
  /// In en, this message translates to:
  /// **'Could not download update. Try again later.'**
  String get notifUpdateFailedBody;

  /// Search filter label - tracks
  ///
  /// In en, this message translates to:
  /// **'Tracks'**
  String get searchTracks;

  /// Default placeholder for the main search field on Home
  ///
  /// In en, this message translates to:
  /// **'Paste supported URL or search...'**
  String get homeSearchHintDefault;

  /// Placeholder for the main search field when a provider is selected
  ///
  /// In en, this message translates to:
  /// **'Search with {providerName}...'**
  String homeSearchHintProvider(String providerName);

  /// Tooltip for importing a CSV or M3U playlist file into Home search
  ///
  /// In en, this message translates to:
  /// **'Import playlist (CSV, M3U)'**
  String get homeImportCsvTooltip;

  /// Tooltip for the Home search provider picker
  ///
  /// In en, this message translates to:
  /// **'Change search provider'**
  String get homeChangeSearchProviderTooltip;

  /// Generic action - paste from clipboard
  ///
  /// In en, this message translates to:
  /// **'Paste'**
  String get actionPaste;

  /// Placeholder shown in the tutorial search demo
  ///
  /// In en, this message translates to:
  /// **'Paste or search...'**
  String get tutorialSearchHint;

  /// Accessibility label for completed download state in tutorial demo
  ///
  /// In en, this message translates to:
  /// **'Download completed'**
  String get tutorialDownloadCompletedSemantics;

  /// Accessibility label for active download state in tutorial demo
  ///
  /// In en, this message translates to:
  /// **'Download in progress'**
  String get tutorialDownloadInProgressSemantics;

  /// Accessibility label for idle download button in tutorial demo
  ///
  /// In en, this message translates to:
  /// **'Start download'**
  String get tutorialStartDownloadSemantics;

  /// Settings toggle title for writing metadata into downloaded files
  ///
  /// In en, this message translates to:
  /// **'Embed Metadata'**
  String get optionsEmbedMetadata;

  /// Subtitle when metadata embedding is enabled
  ///
  /// In en, this message translates to:
  /// **'Write metadata, cover art, and embedded lyrics to files'**
  String get optionsEmbedMetadataSubtitleOn;

  /// Subtitle when metadata embedding is disabled
  ///
  /// In en, this message translates to:
  /// **'Disabled (advanced): skip all metadata embedding'**
  String get optionsEmbedMetadataSubtitleOff;

  /// Message shown when a track file has no embedded cover art
  ///
  /// In en, this message translates to:
  /// **'No embedded album art found'**
  String get trackCoverNoEmbeddedArt;

  /// Button label for replacing selected cover art
  ///
  /// In en, this message translates to:
  /// **'Replace Cover'**
  String get trackCoverReplace;

  /// Button label for selecting cover art
  ///
  /// In en, this message translates to:
  /// **'Pick Cover'**
  String get trackCoverPick;

  /// Tooltip for clearing the newly selected cover art
  ///
  /// In en, this message translates to:
  /// **'Clear selected cover'**
  String get trackCoverClearSelected;

  /// Label for the currently embedded cover preview
  ///
  /// In en, this message translates to:
  /// **'Current cover'**
  String get trackCoverCurrent;

  /// Label for the newly selected cover preview
  ///
  /// In en, this message translates to:
  /// **'Selected cover'**
  String get trackCoverSelected;

  /// Notice shown when a new cover has been selected but not saved yet
  ///
  /// In en, this message translates to:
  /// **'The selected cover will replace the current embedded cover when you tap Save.'**
  String get trackCoverReplaceNotice;

  /// Label for selecting the embedded cover art resolution
  ///
  /// In en, this message translates to:
  /// **'Cover resolution'**
  String get trackCoverResolution;

  /// Explanation below the embedded cover art resolution selector
  ///
  /// In en, this message translates to:
  /// **'Sets the longest edge when saved. Enlarging does not add image detail.'**
  String get trackCoverResolutionHint;

  /// Error shown when resizing cover art before saving metadata fails
  ///
  /// In en, this message translates to:
  /// **'The cover image could not be resized. Please try another size or image.'**
  String get trackCoverResizeFailed;

  /// Generic action - stop
  ///
  /// In en, this message translates to:
  /// **'Stop'**
  String get actionStop;

  /// Accessibility label for a queue item that is finalizing
  ///
  /// In en, this message translates to:
  /// **'Finalizing download'**
  String get queueFinalizingDownload;

  /// Tooltip on a queued download row; moves the item to the front of the queue so the next free slot downloads it
  ///
  /// In en, this message translates to:
  /// **'Download next'**
  String get queueDownloadNext;

  /// Queue item menu action - move the queued item one position earlier
  ///
  /// In en, this message translates to:
  /// **'Move up'**
  String get queueMoveUp;

  /// Queue item menu action - move the queued item one position later
  ///
  /// In en, this message translates to:
  /// **'Move down'**
  String get queueMoveDown;

  /// Tag editor button that fills genre and album artist from MusicBrainz by ISRC
  ///
  /// In en, this message translates to:
  /// **'Fetch from MusicBrainz'**
  String get editMetadataMusicBrainzButton;

  /// Snackbar after MusicBrainz suggestions were applied to the tag editor fields
  ///
  /// In en, this message translates to:
  /// **'Updated from MusicBrainz'**
  String get editMetadataMusicBrainzFilled;

  /// Snackbar when the MusicBrainz lookup returns no data
  ///
  /// In en, this message translates to:
  /// **'Nothing found on MusicBrainz'**
  String get editMetadataMusicBrainzNothing;

  /// Snackbar when the MusicBrainz lookup is tapped without an ISRC
  ///
  /// In en, this message translates to:
  /// **'Requires an ISRC tag'**
  String get editMetadataMusicBrainzNeedsIsrc;

  /// Repeat toggle tooltip when repeat is disabled
  ///
  /// In en, this message translates to:
  /// **'Repeat off'**
  String get nowPlayingRepeatOff;

  /// Repeat toggle tooltip when the whole queue repeats
  ///
  /// In en, this message translates to:
  /// **'Repeat all'**
  String get nowPlayingRepeatAll;

  /// Repeat toggle tooltip when the current track repeats
  ///
  /// In en, this message translates to:
  /// **'Repeat one'**
  String get nowPlayingRepeatOne;

  /// Snackbar shown when connectivity returns and network-failed downloads can be retried
  ///
  /// In en, this message translates to:
  /// **'{count} downloads failed while offline'**
  String queueNetworkFailedOffline(int count);

  /// Accessibility label when a downloaded file is missing from disk
  ///
  /// In en, this message translates to:
  /// **'Downloaded file missing'**
  String get queueDownloadedFileMissing;

  /// Accessibility label for completed download state in queue
  ///
  /// In en, this message translates to:
  /// **'Download completed'**
  String get queueDownloadCompleted;

  /// Title shown on a failed queue item when the download service rate limits requests
  ///
  /// In en, this message translates to:
  /// **'Service rate limited'**
  String get queueRateLimitTitle;

  /// Explanation shown on a failed queue item when the download service rate limits requests
  ///
  /// In en, this message translates to:
  /// **'This track may still be available. Wait a few minutes, reduce parallel downloads, then retry.'**
  String get queueRateLimitMessage;

  /// Accessibility label for picking an accent color
  ///
  /// In en, this message translates to:
  /// **'Select accent color {hex}'**
  String appearanceSelectAccentColor(String hex);

  /// Tooltip when auto-scroll is enabled on the log screen
  ///
  /// In en, this message translates to:
  /// **'Auto-scroll ON'**
  String get logAutoScrollOn;

  /// Tooltip when auto-scroll is disabled on the log screen
  ///
  /// In en, this message translates to:
  /// **'Auto-scroll OFF'**
  String get logAutoScrollOff;

  /// Tooltip for copying logs
  ///
  /// In en, this message translates to:
  /// **'Copy logs'**
  String get logCopyLogs;

  /// Tooltip for clearing the log search field
  ///
  /// In en, this message translates to:
  /// **'Clear search'**
  String get logClearSearch;

  /// Diagnostic badge label when ISP blocking is detected
  ///
  /// In en, this message translates to:
  /// **'ISP BLOCKING DETECTED'**
  String get logIssueIspBlockingLabel;

  /// Diagnostic badge description for ISP blocking
  ///
  /// In en, this message translates to:
  /// **'Your ISP may be blocking access to download services'**
  String get logIssueIspBlockingDescription;

  /// Diagnostic badge suggestion for ISP blocking
  ///
  /// In en, this message translates to:
  /// **'Try using a VPN or change DNS to 1.1.1.1 or 8.8.8.8'**
  String get logIssueIspBlockingSuggestion;

  /// Diagnostic badge label when the service rate limits requests
  ///
  /// In en, this message translates to:
  /// **'RATE LIMITED'**
  String get logIssueRateLimitedLabel;

  /// Diagnostic badge description for rate limiting
  ///
  /// In en, this message translates to:
  /// **'Too many requests to the service'**
  String get logIssueRateLimitedDescription;

  /// Diagnostic badge suggestion for rate limiting
  ///
  /// In en, this message translates to:
  /// **'Wait a few minutes before trying again'**
  String get logIssueRateLimitedSuggestion;

  /// Diagnostic badge label for generic network errors
  ///
  /// In en, this message translates to:
  /// **'NETWORK ERROR'**
  String get logIssueNetworkErrorLabel;

  /// Diagnostic badge description for generic network errors
  ///
  /// In en, this message translates to:
  /// **'Connection issues detected'**
  String get logIssueNetworkErrorDescription;

  /// Diagnostic badge suggestion for generic network errors
  ///
  /// In en, this message translates to:
  /// **'Check your internet connection'**
  String get logIssueNetworkErrorSuggestion;

  /// Diagnostic badge label when a track is unavailable
  ///
  /// In en, this message translates to:
  /// **'TRACK NOT FOUND'**
  String get logIssueTrackNotFoundLabel;

  /// Diagnostic badge description when a track is unavailable
  ///
  /// In en, this message translates to:
  /// **'Some tracks could not be found on download services'**
  String get logIssueTrackNotFoundDescription;

  /// Diagnostic badge suggestion when a track is unavailable
  ///
  /// In en, this message translates to:
  /// **'The track may not be available in lossless quality'**
  String get logIssueTrackNotFoundSuggestion;

  /// Snackbar shown while clickable artist metadata is being resolved
  ///
  /// In en, this message translates to:
  /// **'Looking up artist...'**
  String get clickableLookingUpArtist;

  /// Snackbar shown when clickable metadata cannot open a destination
  ///
  /// In en, this message translates to:
  /// **'{type} information not available'**
  String clickableInformationUnavailable(String type);

  /// Section title for extension tags
  ///
  /// In en, this message translates to:
  /// **'Tags'**
  String get extensionDetailsTags;

  /// Section title for extension metadata information
  ///
  /// In en, this message translates to:
  /// **'Information'**
  String get extensionDetailsInformation;

  /// Capability label for utility-only extensions
  ///
  /// In en, this message translates to:
  /// **'Utility Functions'**
  String get extensionUtilityFunctions;

  /// Generic action - dismiss
  ///
  /// In en, this message translates to:
  /// **'Dismiss'**
  String get actionDismiss;

  /// Tooltip for editing the selected download folder
  ///
  /// In en, this message translates to:
  /// **'Change folder'**
  String get setupChangeFolderTooltip;

  /// Accessibility label for opening a track item
  ///
  /// In en, this message translates to:
  /// **'Open track {trackName} by {artistName}'**
  String a11yOpenTrackByArtist(String trackName, String artistName);

  /// Accessibility label for opening a generic item
  ///
  /// In en, this message translates to:
  /// **'Open {itemType} {name}'**
  String a11yOpenItem(String itemType, String name);

  /// Accessibility label for opening a grouped item with count
  ///
  /// In en, this message translates to:
  /// **'Open {title}, {count} {count, plural, =1{item} other{items}}'**
  String a11yOpenItemCount(String title, int count);

  /// Accessibility label for opening an album item with track count
  ///
  /// In en, this message translates to:
  /// **'Open album {albumName} by {artistName}, {trackCount} tracks'**
  String a11yOpenAlbumByArtistTrackCount(
    String albumName,
    String artistName,
    int trackCount,
  );

  /// Accessibility label for a queue or list track item
  ///
  /// In en, this message translates to:
  /// **'{trackName} by {artistName}'**
  String a11yTrackByArtist(String trackName, String artistName);

  /// Accessibility label for selecting an album
  ///
  /// In en, this message translates to:
  /// **'Select album {albumName}'**
  String a11ySelectAlbum(String albumName);

  /// Accessibility label for opening an album
  ///
  /// In en, this message translates to:
  /// **'Open album {albumName}'**
  String a11yOpenAlbum(String albumName);

  /// Settings menu item - file and folder settings
  ///
  /// In en, this message translates to:
  /// **'Files & Folders'**
  String get settingsFiles;

  /// Subtitle for files & folders settings
  ///
  /// In en, this message translates to:
  /// **'Download location, filename, folder structure'**
  String get settingsFilesSubtitle;

  /// Settings menu item - metadata settings
  ///
  /// In en, this message translates to:
  /// **'Metadata'**
  String get settingsMetadata;

  /// Subtitle for metadata settings
  ///
  /// In en, this message translates to:
  /// **'Cover art, tags, ReplayGain, providers'**
  String get settingsMetadataSubtitle;

  /// Settings menu item - lyrics settings
  ///
  /// In en, this message translates to:
  /// **'Lyrics'**
  String get settingsLyrics;

  /// Subtitle for lyrics settings
  ///
  /// In en, this message translates to:
  /// **'Embed, mode, providers, language options'**
  String get settingsLyricsSubtitle;

  /// Settings menu item - app settings
  ///
  /// In en, this message translates to:
  /// **'App'**
  String get settingsApp;

  /// Subtitle for app settings
  ///
  /// In en, this message translates to:
  /// **'Updates, data, extension repo, debug'**
  String get settingsAppSubtitle;

  /// Settings section header for metadata providers
  ///
  /// In en, this message translates to:
  /// **'Providers'**
  String get sectionMetadataProviders;

  /// Settings section header for deduplication
  ///
  /// In en, this message translates to:
  /// **'Duplicates'**
  String get sectionDuplicates;

  /// Settings section header for per-provider lyrics options
  ///
  /// In en, this message translates to:
  /// **'Provider Options'**
  String get sectionLyricsProviderOptions;

  /// Settings item title for metadata provider order
  ///
  /// In en, this message translates to:
  /// **'Metadata Provider Priority'**
  String get metadataProvidersTitle;

  /// Subtitle for metadata provider priority item
  ///
  /// In en, this message translates to:
  /// **'Drag to set search and metadata source order'**
  String get metadataProvidersSubtitle;

  /// Setting - skip tracks already in download history
  ///
  /// In en, this message translates to:
  /// **'Skip Duplicate Downloads'**
  String get downloadDeduplication;

  /// Subtitle when deduplication is on
  ///
  /// In en, this message translates to:
  /// **'Already-downloaded tracks will be skipped'**
  String get downloadDeduplicationEnabled;

  /// Deduplication subtitle when separate quality versions are allowed
  ///
  /// In en, this message translates to:
  /// **'Existing files at the selected quality will be skipped'**
  String get downloadDeduplicationWithQualityVariants;

  /// Subtitle when deduplication is off
  ///
  /// In en, this message translates to:
  /// **'All tracks will be downloaded regardless of history'**
  String get downloadDeduplicationDisabled;

  /// Setting to retain multiple quality versions of the same track
  ///
  /// In en, this message translates to:
  /// **'Allow different quality versions'**
  String get downloadQualityVariants;

  /// Description for retaining multiple quality versions
  ///
  /// In en, this message translates to:
  /// **'Keep every quality version; add its measured quality to the filename only when the name is already used'**
  String get downloadQualityVariantsDescription;

  /// Track menu action to download another quality version
  ///
  /// In en, this message translates to:
  /// **'Download another quality'**
  String get trackOptionDownloadQualityVariant;

  /// Settings item for configuring fallback extension providers
  ///
  /// In en, this message translates to:
  /// **'Fallback Extensions'**
  String get downloadFallbackExtensions;

  /// Subtitle for fallback extensions item
  ///
  /// In en, this message translates to:
  /// **'Choose which extensions can be used as fallback'**
  String get downloadFallbackExtensionsSubtitle;

  /// Hint text for the edit metadata date field
  ///
  /// In en, this message translates to:
  /// **'YYYY-MM-DD or YYYY'**
  String get editMetadataFieldDateHint;

  /// Label for total tracks field in the edit metadata sheet
  ///
  /// In en, this message translates to:
  /// **'Track Total'**
  String get editMetadataFieldTrackTotal;

  /// Label for total discs field in the edit metadata sheet
  ///
  /// In en, this message translates to:
  /// **'Disc Total'**
  String get editMetadataFieldDiscTotal;

  /// Label for composer field in the edit metadata sheet
  ///
  /// In en, this message translates to:
  /// **'Composer'**
  String get editMetadataFieldComposer;

  /// Label for comment field in the edit metadata sheet
  ///
  /// In en, this message translates to:
  /// **'Comment'**
  String get editMetadataFieldComment;

  /// Label for an album or release type metadata value
  ///
  /// In en, this message translates to:
  /// **'Release Type'**
  String get trackAlbumType;

  /// Hint for the release type metadata field
  ///
  /// In en, this message translates to:
  /// **'Album, single, EP, compilation...'**
  String get editMetadataFieldAlbumTypeHint;

  /// Label for the explicit content metadata field
  ///
  /// In en, this message translates to:
  /// **'Explicit'**
  String get editMetadataFieldExplicit;

  /// Description for the explicit content metadata switch
  ///
  /// In en, this message translates to:
  /// **'Mark this track as containing explicit content'**
  String get editMetadataFieldExplicitHint;

  /// Displayed value when a track is marked explicit
  ///
  /// In en, this message translates to:
  /// **'Explicit'**
  String get metadataExplicitValue;

  /// Label for the release barcode metadata field
  ///
  /// In en, this message translates to:
  /// **'UPC / Barcode'**
  String get editMetadataFieldUpc;

  /// Hint for the release barcode metadata field
  ///
  /// In en, this message translates to:
  /// **'Numeric UPC, EAN, or GTIN'**
  String get editMetadataFieldUpcHint;

  /// Expandable section label for advanced metadata fields
  ///
  /// In en, this message translates to:
  /// **'Advanced'**
  String get editMetadataAdvanced;

  /// Filter option - items missing track number
  ///
  /// In en, this message translates to:
  /// **'Missing track number'**
  String get libraryFilterMetadataMissingTrackNumber;

  /// Filter option - items missing disc number
  ///
  /// In en, this message translates to:
  /// **'Missing disc number'**
  String get libraryFilterMetadataMissingDiscNumber;

  /// Filter option - items missing artist
  ///
  /// In en, this message translates to:
  /// **'Missing artist'**
  String get libraryFilterMetadataMissingArtist;

  /// Filter option - items with an invalid ISRC format
  ///
  /// In en, this message translates to:
  /// **'Incorrect ISRC format'**
  String get libraryFilterMetadataIncorrectIsrcFormat;

  /// Filter option - items without any ISRC tag
  ///
  /// In en, this message translates to:
  /// **'Missing ISRC'**
  String get libraryFilterMetadataMissingIsrc;

  /// Filter option - items missing record label
  ///
  /// In en, this message translates to:
  /// **'Missing label'**
  String get libraryFilterMetadataMissingLabel;

  /// Confirmation message for deleting selected playlists
  ///
  /// In en, this message translates to:
  /// **'Delete {count} {count, plural, =1{playlist} other{playlists}}?'**
  String collectionDeletePlaylistsMessage(int count);

  /// Snackbar after deleting selected playlists
  ///
  /// In en, this message translates to:
  /// **'{count} {count, plural, =1{playlist} other{playlists}} deleted'**
  String collectionPlaylistsDeleted(int count);

  /// Snackbar after adding multiple tracks to a playlist
  ///
  /// In en, this message translates to:
  /// **'Added {count} {count, plural, =1{track} other{tracks}} to {playlistName}'**
  String collectionAddedTracksToPlaylist(int count, String playlistName);

  /// Snackbar after adding multiple tracks to a playlist when some were already present
  ///
  /// In en, this message translates to:
  /// **'Added {count} {count, plural, =1{track} other{tracks}} to {playlistName} ({alreadyCount} already in playlist)'**
  String collectionAddedTracksToPlaylistWithExisting(
    int count,
    String playlistName,
    int alreadyCount,
  );

  /// Generic item count label
  ///
  /// In en, this message translates to:
  /// **'{count} {count, plural, =1{item} other{items}}'**
  String itemCount(int count);

  /// Snackbar summary after batch metadata re-enrichment finishes with failures
  ///
  /// In en, this message translates to:
  /// **'Metadata re-enriched successfully ({successCount}/{total}) - Failed: {failedCount}'**
  String trackReEnrichSuccessWithFailures(
    int successCount,
    int total,
    int failedCount,
  );

  /// Button label for deleting selected tracks
  ///
  /// In en, this message translates to:
  /// **'Delete {count} {count, plural, =1{track} other{tracks}}'**
  String selectionDeleteTracksCount(int count);

  /// Queue status while downloading with speed
  ///
  /// In en, this message translates to:
  /// **'Downloading - {speed} MB/s'**
  String queueDownloadSpeedStatus(String speed);

  /// Queue status before download progress is available
  ///
  /// In en, this message translates to:
  /// **'Starting...'**
  String get queueDownloadStarting;

  /// No description provided for @queueCheckingDownloadSession.
  ///
  /// In en, this message translates to:
  /// **'Checking download session...'**
  String get queueCheckingDownloadSession;

  /// No description provided for @queueResolvingDownloadMetadata.
  ///
  /// In en, this message translates to:
  /// **'Resolving track metadata...'**
  String get queueResolvingDownloadMetadata;

  /// No description provided for @queueResolvingDownloadStream.
  ///
  /// In en, this message translates to:
  /// **'Preparing audio stream...'**
  String get queueResolvingDownloadStream;

  /// No description provided for @queueWaitingForVerification.
  ///
  /// In en, this message translates to:
  /// **'Waiting for verification...'**
  String get queueWaitingForVerification;

  /// No description provided for @queueResumingAfterVerification.
  ///
  /// In en, this message translates to:
  /// **'Resuming after verification...'**
  String get queueResumingAfterVerification;

  /// Accessibility label for selecting a track
  ///
  /// In en, this message translates to:
  /// **'Select track'**
  String get a11ySelectTrack;

  /// Accessibility label for deselecting a track
  ///
  /// In en, this message translates to:
  /// **'Deselect track'**
  String get a11yDeselectTrack;

  /// Accessibility label for playing a local library track
  ///
  /// In en, this message translates to:
  /// **'Play {trackName} by {artistName}'**
  String a11yPlayTrackByArtist(String trackName, String artistName);

  /// Store extension result count
  ///
  /// In en, this message translates to:
  /// **'{count} {count, plural, =1{extension} other{extensions}}'**
  String storeExtensionsCount(int count);

  /// Store compatibility badge for minimum app version
  ///
  /// In en, this message translates to:
  /// **'Requires v{version}+'**
  String storeRequiresVersion(String version);

  /// Generic action button label
  ///
  /// In en, this message translates to:
  /// **'Go'**
  String get actionGo;

  /// Header for log issue analysis summary
  ///
  /// In en, this message translates to:
  /// **'Issue Summary'**
  String get logIssueSummary;

  /// Total error count in log issue analysis
  ///
  /// In en, this message translates to:
  /// **'Total errors: {count}'**
  String logTotalErrors(int count);

  /// Affected domains in log issue analysis
  ///
  /// In en, this message translates to:
  /// **'Affected: {domains}'**
  String logAffectedDomains(String domains);

  /// Library scan status when a scan was cancelled
  ///
  /// In en, this message translates to:
  /// **'Scan cancelled'**
  String get libraryScanCancelled;

  /// Library scan status subtitle after cancellation
  ///
  /// In en, this message translates to:
  /// **'You can retry the scan when ready.'**
  String get libraryScanCancelledSubtitle;

  /// Library count note for downloaded history items excluded from the local list
  ///
  /// In en, this message translates to:
  /// **'{count} from Downloads history (excluded from list)'**
  String libraryDownloadsHistoryExcluded(int count);

  /// Setting title for Android native download worker
  ///
  /// In en, this message translates to:
  /// **'Native download worker'**
  String get downloadNativeWorker;

  /// Setting subtitle for Android native download worker
  ///
  /// In en, this message translates to:
  /// **'Android background service for extension downloads'**
  String get downloadNativeWorkerSubtitle;

  /// Extension detail section header for service status
  ///
  /// In en, this message translates to:
  /// **'Service Status'**
  String get extensionServiceStatus;

  /// Extension capability label for service health checks
  ///
  /// In en, this message translates to:
  /// **'Service health'**
  String get extensionServiceHealth;

  /// Extension service health check count
  ///
  /// In en, this message translates to:
  /// **'{count} {count, plural, =1{check} other{checks}} configured'**
  String extensionHealthChecksConfigured(int count);

  /// Hint for an OAuth login link field before connecting Spotify
  ///
  /// In en, this message translates to:
  /// **'Tap Connect to Spotify to fill this field.'**
  String get extensionOauthConnectHint;

  /// Timestamp for the latest extension service health check
  ///
  /// In en, this message translates to:
  /// **'Last checked {time}'**
  String extensionLastChecked(String time);

  /// Tooltip for refreshing extension service health status
  ///
  /// In en, this message translates to:
  /// **'Refresh status'**
  String get extensionRefreshStatus;

  /// Extension detail section title for custom URL handling
  ///
  /// In en, this message translates to:
  /// **'Custom URL Handling'**
  String get extensionCustomUrlHandling;

  /// Extension detail subtitle for custom URL handling
  ///
  /// In en, this message translates to:
  /// **'This extension can handle links from these sites'**
  String get extensionCustomUrlHandlingSubtitle;

  /// Extension detail hint explaining share-to-app URL handling
  ///
  /// In en, this message translates to:
  /// **'Share links from these sites to SpotiFLAC Mobile and this extension will handle them.'**
  String get extensionCustomUrlHandlingShareHint;

  /// Count of settings exposed by an extension quality option
  ///
  /// In en, this message translates to:
  /// **'{count} {count, plural, =1{setting} other{settings}}'**
  String extensionSettingsCount(int count);

  /// Extension service health status - online
  ///
  /// In en, this message translates to:
  /// **'Online'**
  String get extensionHealthOnline;

  /// Extension service health status - degraded
  ///
  /// In en, this message translates to:
  /// **'Degraded'**
  String get extensionHealthDegraded;

  /// Extension service health status - offline
  ///
  /// In en, this message translates to:
  /// **'Offline'**
  String get extensionHealthOffline;

  /// Extension service health status - not configured
  ///
  /// In en, this message translates to:
  /// **'Not configured'**
  String get extensionHealthNotConfigured;

  /// Extension service health status - unknown
  ///
  /// In en, this message translates to:
  /// **'Unknown'**
  String get extensionHealthUnknown;

  /// Label for a required extension service health check
  ///
  /// In en, this message translates to:
  /// **'required'**
  String get extensionHealthRequired;

  /// Value shown when an extension setting has no value
  ///
  /// In en, this message translates to:
  /// **'Not set'**
  String get extensionSettingNotSet;

  /// Fallback error when an extension action fails without details
  ///
  /// In en, this message translates to:
  /// **'Action failed'**
  String get extensionActionFailed;

  /// Hint for editing an extension setting value
  ///
  /// In en, this message translates to:
  /// **'Enter value'**
  String get extensionEnterValue;

  /// Tooltip for online extension service
  ///
  /// In en, this message translates to:
  /// **'Service online'**
  String get extensionHealthServiceOnline;

  /// Tooltip for degraded extension service
  ///
  /// In en, this message translates to:
  /// **'Service degraded'**
  String get extensionHealthServiceDegraded;

  /// Tooltip for offline extension service
  ///
  /// In en, this message translates to:
  /// **'Service offline'**
  String get extensionHealthServiceOffline;

  /// Tooltip for unknown extension service health
  ///
  /// In en, this message translates to:
  /// **'Service status unknown'**
  String get extensionHealthServiceUnknown;

  /// Audio channel layout label - stereo
  ///
  /// In en, this message translates to:
  /// **'Stereo'**
  String get audioAnalysisStereo;

  /// Audio channel layout label - mono
  ///
  /// In en, this message translates to:
  /// **'Mono'**
  String get audioAnalysisMono;

  /// Button label to open a track in a named music service
  ///
  /// In en, this message translates to:
  /// **'Open in {serviceName}'**
  String trackOpenInService(String serviceName);

  /// Lyrics source label for embedded lyrics
  ///
  /// In en, this message translates to:
  /// **'Embedded'**
  String get trackLyricsEmbeddedSource;

  /// Fallback album name when metadata is missing
  ///
  /// In en, this message translates to:
  /// **'Unknown Album'**
  String get unknownAlbum;

  /// Fallback artist name when metadata is missing
  ///
  /// In en, this message translates to:
  /// **'Unknown Artist'**
  String get unknownArtist;

  /// Audio permission type label
  ///
  /// In en, this message translates to:
  /// **'Audio'**
  String get permissionAudio;

  /// Storage permission type label
  ///
  /// In en, this message translates to:
  /// **'Storage'**
  String get permissionStorage;

  /// Notification permission type label
  ///
  /// In en, this message translates to:
  /// **'Notification'**
  String get permissionNotification;

  /// Error when the selected folder is invalid
  ///
  /// In en, this message translates to:
  /// **'Invalid folder selected'**
  String get errorInvalidFolderSelected;

  /// Store detail value when any app version is accepted
  ///
  /// In en, this message translates to:
  /// **'Any'**
  String get storeAnyVersion;

  /// Store extension category - metadata
  ///
  /// In en, this message translates to:
  /// **'Metadata'**
  String get storeCategoryMetadata;

  /// Store extension category - download
  ///
  /// In en, this message translates to:
  /// **'Download'**
  String get storeCategoryDownload;

  /// Store extension category - utility
  ///
  /// In en, this message translates to:
  /// **'Utility'**
  String get storeCategoryUtility;

  /// Store extension category - lyrics
  ///
  /// In en, this message translates to:
  /// **'Lyrics'**
  String get storeCategoryLyrics;

  /// Store extension category - integration
  ///
  /// In en, this message translates to:
  /// **'Integration'**
  String get storeCategoryIntegration;

  /// Section header for all artist releases
  ///
  /// In en, this message translates to:
  /// **'Releases'**
  String get artistReleases;

  /// Button to clear selected fields for auto-fill
  ///
  /// In en, this message translates to:
  /// **'None'**
  String get editMetadataSelectNone;

  /// Button to retry every failed download in the queue
  ///
  /// In en, this message translates to:
  /// **'Retry {count} failed'**
  String queueRetryAllFailed(int count);

  /// Settings switch title for storing completed downloads in history
  ///
  /// In en, this message translates to:
  /// **'Save download history'**
  String get settingsSaveDownloadHistory;

  /// Settings switch subtitle for storing completed downloads in history
  ///
  /// In en, this message translates to:
  /// **'Keep completed downloads in history and library views'**
  String get settingsSaveDownloadHistorySubtitle;

  /// Confirmation dialog title shown before disabling download history
  ///
  /// In en, this message translates to:
  /// **'Turn off download history?'**
  String get dialogDisableHistoryTitle;

  /// Confirmation dialog message shown before disabling download history
  ///
  /// In en, this message translates to:
  /// **'Existing history will be cleared. Downloaded files will not be deleted.'**
  String get dialogDisableHistoryMessage;

  /// Confirmation action to disable download history and clear existing entries
  ///
  /// In en, this message translates to:
  /// **'Turn off and clear'**
  String get dialogDisableAndClear;

  /// Title and tooltip for finding the current collection in other services
  ///
  /// In en, this message translates to:
  /// **'Open in Other Services'**
  String get openInOtherServices;

  /// Empty state when no extensions can be searched for cross-service links
  ///
  /// In en, this message translates to:
  /// **'No other compatible services'**
  String get shareSheetNoExtensions;

  /// Cross-service share sheet row subtitle when a service has no match
  ///
  /// In en, this message translates to:
  /// **'Not found'**
  String get shareSheetNotFound;

  /// Tooltip for copying a cross-service link
  ///
  /// In en, this message translates to:
  /// **'Copy Link'**
  String get shareSheetCopyLink;

  /// Snackbar after copying a cross-service link
  ///
  /// In en, this message translates to:
  /// **'{service} link copied'**
  String shareSheetLinkCopied(Object service);

  /// Section header for playback settings in library settings
  ///
  /// In en, this message translates to:
  /// **'Playback'**
  String get libraryPlayback;

  /// Setting option to use an external music player
  ///
  /// In en, this message translates to:
  /// **'External player'**
  String get libraryExternalPlayer;

  /// Subtitle for external player option
  ///
  /// In en, this message translates to:
  /// **'Recommended for listening, best quality, gapless playback, EQ, and wider format support'**
  String get libraryExternalPlayerSubtitle;

  /// Setting option to use the built-in preview player
  ///
  /// In en, this message translates to:
  /// **'Built-in preview player'**
  String get libraryBuiltInPreviewPlayer;

  /// Subtitle for built-in preview player option
  ///
  /// In en, this message translates to:
  /// **'Only for quick local previews inside SpotiFLAC Mobile, not recommended for regular listening'**
  String get libraryBuiltInPreviewPlayerSubtitle;

  /// Info note explaining the built-in player is for previews only
  ///
  /// In en, this message translates to:
  /// **'The built-in player is a preview tool for checking local tracks quickly. Use an external music player for actual listening.'**
  String get libraryBuiltInPlayerInfo;

  /// Title for the now playing screen
  ///
  /// In en, this message translates to:
  /// **'Now Playing'**
  String get nowPlayingTitle;

  /// Empty state when no track is currently playing
  ///
  /// In en, this message translates to:
  /// **'Nothing is playing'**
  String get nowPlayingNothingPlaying;

  /// Tooltip for minimizing the now playing screen
  ///
  /// In en, this message translates to:
  /// **'Minimize'**
  String get nowPlayingMinimize;

  /// Title for the playback queue sheet
  ///
  /// In en, this message translates to:
  /// **'Up next'**
  String get nowPlayingUpNext;

  /// Tooltip for the previous-track playback control
  ///
  /// In en, this message translates to:
  /// **'Previous track'**
  String get nowPlayingPreviousTrack;

  /// Tooltip for the next-track playback control
  ///
  /// In en, this message translates to:
  /// **'Next track'**
  String get nowPlayingNextTrack;

  /// Menu item and section title for track metadata details
  ///
  /// In en, this message translates to:
  /// **'Details'**
  String get nowPlayingDetails;

  /// Menu item to open the current track in an external player
  ///
  /// In en, this message translates to:
  /// **'Open in external player'**
  String get nowPlayingOpenInExternalPlayer;

  /// Tab label for the player view
  ///
  /// In en, this message translates to:
  /// **'Player'**
  String get nowPlayingTabPlayer;

  /// Tab label for the lyrics view
  ///
  /// In en, this message translates to:
  /// **'Lyrics'**
  String get nowPlayingTabLyrics;

  /// Empty state when the playing file has no embedded lyrics
  ///
  /// In en, this message translates to:
  /// **'No lyrics in this file'**
  String get nowPlayingNoLyrics;

  /// Snackbar when shuffle library is requested but library has no tracks
  ///
  /// In en, this message translates to:
  /// **'Your library is empty'**
  String get nowPlayingLibraryEmpty;

  /// Snackbar when shuffling the library fails
  ///
  /// In en, this message translates to:
  /// **'Could not shuffle library: {error}'**
  String nowPlayingShuffleLibraryFailed(String error);

  /// Tooltip when shuffle mode is enabled
  ///
  /// In en, this message translates to:
  /// **'Shuffle on'**
  String get nowPlayingShuffleOn;

  /// Tooltip when shuffle mode is disabled
  ///
  /// In en, this message translates to:
  /// **'Play in order'**
  String get nowPlayingPlayInOrder;

  /// Button label to shuffle and play the entire local library
  ///
  /// In en, this message translates to:
  /// **'Shuffle library'**
  String get nowPlayingShuffleLibrary;

  /// Empty state when the playback queue has no items
  ///
  /// In en, this message translates to:
  /// **'Queue is empty'**
  String get nowPlayingQueueEmpty;

  /// Empty state when track metadata cannot be loaded
  ///
  /// In en, this message translates to:
  /// **'No metadata available'**
  String get nowPlayingNoMetadata;

  /// Snackbar shown when an announcement CTA link cannot be opened
  ///
  /// In en, this message translates to:
  /// **'Unable to open link. Please try again.'**
  String get announcementUnableToOpenLink;

  /// Hint shown when lossless conversion will cap bit depth or sample rate
  ///
  /// In en, this message translates to:
  /// **'Lossless output with {quality} cap'**
  String trackConvertLosslessOutputWithCap(String quality);

  /// Confirmation dialog message for capped lossless conversion of a single file
  ///
  /// In en, this message translates to:
  /// **'Convert from {sourceFormat} to {targetFormat} ({quality})?\n\nThe output stays in a lossless codec, but bit depth/sample rate will be capped. Original file will be deleted after conversion.'**
  String trackConvertConfirmMessageLosslessCapped(
    String sourceFormat,
    String targetFormat,
    String quality,
  );

  /// Confirmation dialog message for capped lossless batch conversion
  ///
  /// In en, this message translates to:
  /// **'Convert {count} {count, plural, =1{track} other{tracks}} to {format} ({quality})?\n\nThe output stays in a lossless codec, but bit depth/sample rate will be capped. Original files will be deleted after conversion.'**
  String selectionBatchConvertConfirmMessageLosslessCapped(
    int count,
    String format,
    String quality,
  );

  /// Convert button label for lossless conversion with quality cap
  ///
  /// In en, this message translates to:
  /// **'{sourceFormat} → {targetFormat} ({quality})'**
  String trackConvertActionLabelLossless(
    String sourceFormat,
    String targetFormat,
    String quality,
  );

  /// Convert button label for lossy conversion
  ///
  /// In en, this message translates to:
  /// **'{sourceFormat} → {targetFormat} @ {bitrate}'**
  String trackConvertActionLabelLossy(
    String sourceFormat,
    String targetFormat,
    String bitrate,
  );

  /// Subtitle for Paxsenix special thanks entry on the about page
  ///
  /// In en, this message translates to:
  /// **'Lyrics proxy for Musixmatch, Netease, Apple Music, QQ Music, Spotify, Deezer, YouTube, Kugou, and Genius'**
  String get aboutPaxsenixSubtitle;

  /// Snackbar when a track is inserted as the next queue item
  ///
  /// In en, this message translates to:
  /// **'Playing next'**
  String get snackbarPlayingNext;

  /// Snackbar when a track is added to the playback queue without naming it
  ///
  /// In en, this message translates to:
  /// **'Added to queue'**
  String get snackbarAddedToQueueGeneric;

  /// Button label for deleting multiple selected playlists
  ///
  /// In en, this message translates to:
  /// **'Delete {count} {count, plural, =1{playlist} other{playlists}}'**
  String selectionDeletePlaylistsCount(int count);

  /// Tooltip for shuffle playback action
  ///
  /// In en, this message translates to:
  /// **'Shuffle'**
  String get actionShuffle;

  /// Status label when primary-artist-only folder naming is enabled
  ///
  /// In en, this message translates to:
  /// **'Primary only: On'**
  String get downloadPrimaryArtistOnlyOn;

  /// Status label when primary-artist-only folder naming is disabled
  ///
  /// In en, this message translates to:
  /// **'Primary only: Off'**
  String get downloadPrimaryArtistOnlyOff;

  /// Status label when album-artist folder filtering uses primary artist only
  ///
  /// In en, this message translates to:
  /// **'Album Artist metadata: Primary only'**
  String get downloadAlbumArtistMetadataPrimaryOnly;

  /// Status label when album-artist folder filtering uses full metadata
  ///
  /// In en, this message translates to:
  /// **'Album Artist metadata: Full'**
  String get downloadAlbumArtistMetadataFull;

  /// Label for keeping original bit depth or sample rate during conversion
  ///
  /// In en, this message translates to:
  /// **'Original'**
  String get trackConvertOriginal;

  /// Label when no bit depth or sample rate cap is applied during lossless conversion
  ///
  /// In en, this message translates to:
  /// **'Original quality'**
  String get trackConvertOriginalQuality;

  /// Suffix used in converted lossless quality labels
  ///
  /// In en, this message translates to:
  /// **'Lossless'**
  String get trackConvertLosslessSuffix;

  /// Section label for lossless conversion dithering options
  ///
  /// In en, this message translates to:
  /// **'Dithering'**
  String get trackConvertDithering;

  /// Section label for lossless conversion resampler options
  ///
  /// In en, this message translates to:
  /// **'Resampler'**
  String get trackConvertResampler;

  /// Lossless conversion dither option with no dithering applied
  ///
  /// In en, this message translates to:
  /// **'None'**
  String get trackConvertDitherNone;

  /// Lossless conversion triangular probability density function dither option
  ///
  /// In en, this message translates to:
  /// **'TPDF'**
  String get trackConvertDitherTriangular;

  /// Lossless conversion high-pass triangular dither option
  ///
  /// In en, this message translates to:
  /// **'Triangular HP'**
  String get trackConvertDitherTriangularHp;

  /// Lossless conversion default FFmpeg swresample resampler option
  ///
  /// In en, this message translates to:
  /// **'SWR'**
  String get trackConvertResamplerSwr;

  /// Lossless conversion SoX resampler option
  ///
  /// In en, this message translates to:
  /// **'SoXr'**
  String get trackConvertResamplerSoxr;

  /// Fallback changelog text when release notes cannot be parsed
  ///
  /// In en, this message translates to:
  /// **'See release notes for details.'**
  String get updateSeeReleaseNotes;

  /// Fallback track title when metadata is missing
  ///
  /// In en, this message translates to:
  /// **'Unknown title'**
  String get unknownTitle;

  /// Menu action to play a track as the next queue item
  ///
  /// In en, this message translates to:
  /// **'Play next'**
  String get trackPlayNext;

  /// Menu action to add a track to the playback queue
  ///
  /// In en, this message translates to:
  /// **'Add to queue'**
  String get trackAddToQueue;

  /// Snackbar after installing an extension from the repo tab
  ///
  /// In en, this message translates to:
  /// **'{extensionName} installed. Enable it in Settings > Extensions'**
  String snackbarExtensionInstalledEnable(String extensionName);

  /// Snackbar after updating an extension from the repo tab
  ///
  /// In en, this message translates to:
  /// **'{extensionName} updated to v{version}'**
  String snackbarExtensionUpdatedVersion(String extensionName, String version);

  /// Snackbar when extension install fails in the repo tab
  ///
  /// In en, this message translates to:
  /// **'Failed to install {extensionName}'**
  String snackbarFailedToInstallNamed(String extensionName);

  /// Snackbar when extension update fails in the repo tab
  ///
  /// In en, this message translates to:
  /// **'Failed to update {extensionName}'**
  String snackbarFailedToUpdateNamed(String extensionName);

  /// Badge label for EP releases
  ///
  /// In en, this message translates to:
  /// **'EP'**
  String get releaseTypeEp;

  /// Badge label for single releases
  ///
  /// In en, this message translates to:
  /// **'Single'**
  String get releaseTypeSingle;

  /// Label shown when metadata autofill downloaded cover art from the internet
  ///
  /// In en, this message translates to:
  /// **'Online cover'**
  String get trackCoverOnline;

  /// Country name for SongLink region picker
  ///
  /// In en, this message translates to:
  /// **'United States'**
  String get regionCountryUS;

  /// Country name for SongLink region picker
  ///
  /// In en, this message translates to:
  /// **'United Kingdom'**
  String get regionCountryGB;

  /// Country name for SongLink region picker
  ///
  /// In en, this message translates to:
  /// **'France'**
  String get regionCountryFR;

  /// Country name for SongLink region picker
  ///
  /// In en, this message translates to:
  /// **'Germany'**
  String get regionCountryDE;

  /// Country name for SongLink region picker
  ///
  /// In en, this message translates to:
  /// **'Japan'**
  String get regionCountryJP;

  /// Country name for SongLink region picker
  ///
  /// In en, this message translates to:
  /// **'South Korea'**
  String get regionCountryKR;

  /// Country name for SongLink region picker
  ///
  /// In en, this message translates to:
  /// **'India'**
  String get regionCountryIN;

  /// Country name for SongLink region picker
  ///
  /// In en, this message translates to:
  /// **'Indonesia'**
  String get regionCountryID;

  /// Country name for SongLink region picker
  ///
  /// In en, this message translates to:
  /// **'Brazil'**
  String get regionCountryBR;

  /// Country name for SongLink region picker
  ///
  /// In en, this message translates to:
  /// **'Mexico'**
  String get regionCountryMX;

  /// Country name for SongLink region picker
  ///
  /// In en, this message translates to:
  /// **'Australia'**
  String get regionCountryAU;

  /// Country name for SongLink region picker
  ///
  /// In en, this message translates to:
  /// **'Canada'**
  String get regionCountryCA;

  /// Country name for SongLink region picker
  ///
  /// In en, this message translates to:
  /// **'Kosovo'**
  String get regionCountryXK;

  /// Settings option title for extension verification browser preference
  ///
  /// In en, this message translates to:
  /// **'Verification browser'**
  String get extensionVerificationBrowserTitle;

  /// Subtitle when external browser is preferred for extension verification
  ///
  /// In en, this message translates to:
  /// **'Open challenges in the default browser first'**
  String get extensionVerificationBrowserSubtitleExternal;

  /// Subtitle when in-app browser is preferred for extension verification
  ///
  /// In en, this message translates to:
  /// **'Open challenges in the in-app browser first'**
  String get extensionVerificationBrowserSubtitleInApp;

  /// Chip label for external browser verification mode
  ///
  /// In en, this message translates to:
  /// **'External'**
  String get extensionVerificationBrowserExternal;

  /// Chip label for in-app browser verification mode
  ///
  /// In en, this message translates to:
  /// **'In-app'**
  String get extensionVerificationBrowserInApp;

  /// Dialog title when automatic browser launch for verification fails
  ///
  /// In en, this message translates to:
  /// **'Open verification manually'**
  String get extensionVerificationHelpTitleManual;

  /// Dialog title when verification is taking longer than expected
  ///
  /// In en, this message translates to:
  /// **'Verification still waiting'**
  String get extensionVerificationHelpTitleWaiting;

  /// Dialog message when automatic browser launch for verification fails
  ///
  /// In en, this message translates to:
  /// **'SpotiFLAC Mobile could not open the browser automatically. Open this link in your browser, or copy it manually.'**
  String get extensionVerificationHelpMessageManual;

  /// Dialog message when verification may need manual browser help
  ///
  /// In en, this message translates to:
  /// **'If the browser did not open, or verification finished but did not return to SpotiFLAC Mobile, open this link again or copy it manually.'**
  String get extensionVerificationHelpMessageWaiting;

  /// Button to dismiss the extension verification help dialog
  ///
  /// In en, this message translates to:
  /// **'Close'**
  String get extensionVerificationClose;

  /// Button to copy the extension verification URL
  ///
  /// In en, this message translates to:
  /// **'Copy link'**
  String get extensionVerificationCopyLink;

  /// Snackbar after copying the extension verification URL
  ///
  /// In en, this message translates to:
  /// **'Verification link copied'**
  String get extensionVerificationLinkCopied;

  /// Button to open the extension verification URL in a browser
  ///
  /// In en, this message translates to:
  /// **'Open browser'**
  String get extensionVerificationOpenBrowser;

  /// Placeholder of the search field on the Settings tab
  ///
  /// In en, this message translates to:
  /// **'Search settings'**
  String get settingsSearchHint;

  /// Shown when a Settings search returns nothing
  ///
  /// In en, this message translates to:
  /// **'No settings match \"{query}\"'**
  String settingsSearchNoResults(String query);

  /// Settings group covering look and feel
  ///
  /// In en, this message translates to:
  /// **'Extensions & appearance'**
  String get settingsGroupInterface;

  /// Settings group covering the library, metadata and lyrics
  ///
  /// In en, this message translates to:
  /// **'Content & metadata'**
  String get settingsGroupContent;

  /// Settings group covering download behaviour and storage
  ///
  /// In en, this message translates to:
  /// **'Downloads & files'**
  String get settingsGroupDownloads;

  /// Settings group covering app-level data, cache and logs
  ///
  /// In en, this message translates to:
  /// **'System'**
  String get settingsGroupSystem;

  /// Settings group covering the about page and donations
  ///
  /// In en, this message translates to:
  /// **'About & support'**
  String get settingsGroupHelp;

  /// Filter option for tracks without embedded or sidecar lyrics
  ///
  /// In en, this message translates to:
  /// **'Missing lyrics'**
  String get libraryFilterMetadataMissingLyrics;

  /// Track menu action that copies the track title
  ///
  /// In en, this message translates to:
  /// **'Copy track name'**
  String get trackOptionCopyTrackName;

  /// Track menu action that copies the artist name
  ///
  /// In en, this message translates to:
  /// **'Copy artist'**
  String get trackOptionCopyArtist;

  /// Track menu action that copies the track title and artist
  ///
  /// In en, this message translates to:
  /// **'Copy track and artist'**
  String get trackOptionCopyTrackAndArtist;

  /// Metadata menu action that copies only the selected value
  ///
  /// In en, this message translates to:
  /// **'Copy value'**
  String get metadataCopyValue;

  /// Metadata menu action that copies the selected key and value
  ///
  /// In en, this message translates to:
  /// **'Copy field and value'**
  String get metadataCopyField;

  /// Metadata menu action that copies every visible key and value
  ///
  /// In en, this message translates to:
  /// **'Copy all metadata'**
  String get metadataCopyAll;
}

class _AppLocalizationsDelegate
    extends LocalizationsDelegate<AppLocalizations> {
  const _AppLocalizationsDelegate();

  @override
  Future<AppLocalizations> load(Locale locale) {
    return SynchronousFuture<AppLocalizations>(lookupAppLocalizations(locale));
  }

  @override
  bool isSupported(Locale locale) => <String>[
    'de',
    'en',
    'es',
    'fr',
    'id',
    'ja',
    'ko',
    'pt',
    'ru',
    'tr',
    'uk',
  ].contains(locale.languageCode);

  @override
  bool shouldReload(_AppLocalizationsDelegate old) => false;
}

AppLocalizations lookupAppLocalizations(Locale locale) {
  // Lookup logic when language+country codes are specified.
  switch (locale.languageCode) {
    case 'es':
      {
        switch (locale.countryCode) {
          case 'ES':
            return AppLocalizationsEsEs();
        }
        break;
      }
    case 'pt':
      {
        switch (locale.countryCode) {
          case 'PT':
            return AppLocalizationsPtPt();
        }
        break;
      }
  }

  // Lookup logic when only language code is specified.
  switch (locale.languageCode) {
    case 'de':
      return AppLocalizationsDe();
    case 'en':
      return AppLocalizationsEn();
    case 'es':
      return AppLocalizationsEs();
    case 'fr':
      return AppLocalizationsFr();
    case 'id':
      return AppLocalizationsId();
    case 'ja':
      return AppLocalizationsJa();
    case 'ko':
      return AppLocalizationsKo();
    case 'pt':
      return AppLocalizationsPt();
    case 'ru':
      return AppLocalizationsRu();
    case 'tr':
      return AppLocalizationsTr();
    case 'uk':
      return AppLocalizationsUk();
  }

  throw FlutterError(
    'AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely '
    'an issue with the localizations generation tool. Please file an issue '
    'on GitHub with a reproducible sample app and the gen-l10n configuration '
    'that was used.',
  );
}
