// English translations. This file is the source of truth for keys —
// every other locale should mirror its keys (or fall back to en).
export default {
// Nav (sidebar)
'nav.displays': 'Displays',
'nav.content': 'Content',
'nav.playlists': 'Playlists',
'nav.layouts': 'Layouts',
'nav.widgets': 'Widgets',
'nav.schedule': 'Schedule',
'nav.walls': 'Video Walls',
'nav.reports': 'Reports',
'nav.kiosk': 'Kiosk',
'nav.designer': 'Designer',
'nav.activity': 'Activity',
'nav.teams': 'Teams',
'nav.help': 'Help',
'nav.settings': 'Settings',
'nav.subscription': 'Subscription',
'nav.admin': 'Admin',
// Common (shared across views)
'common.save': 'Save',
'common.cancel': 'Cancel',
'common.delete': 'Delete',
'common.edit': 'Edit',
'common.done': 'Done',
'common.loading': 'Loading...',
'common.connected': 'Connected',
'common.disconnected': 'Disconnected',
'common.never': 'Never',
'common.just_now': 'Just now',
'common.minutes_ago': '{n}m ago',
'common.hours_ago': '{n}h ago',
'common.days_ago': '{n}d ago',
'common.unknown': 'Unknown',
// Auth (login view)
'auth.sign_in': 'Sign In',
'auth.sign_out': 'Sign out',
'auth.create_account': 'Create Account',
'auth.create_admin_account': 'Create Admin Account',
'auth.email': 'Email',
'auth.password': 'Password',
'auth.name': 'Name',
'auth.placeholder_email': 'you@example.com',
'auth.placeholder_password': '••••••••',
'auth.placeholder_name': 'Your name',
'auth.placeholder_register_password': 'At least 6 characters',
'auth.subtitle_setup': 'Create your admin account to get started',
'auth.subtitle_signin': 'Sign in to manage your displays',
'auth.trial_notice': 'New accounts get a 14-day free Pro trial',
'auth.divider_or': 'OR',
'auth.signin_google': 'Sign in with Google',
'auth.signin_microsoft': 'Sign in with Microsoft',
'auth.back_to_signin': 'Back to Sign In',
'auth.support_access': 'Support Access',
'auth.support_token_placeholder': 'Paste support token',
'auth.support_authenticate': 'Authenticate with Support Token',
'auth.terms': 'Terms of Service',
'auth.privacy': 'Privacy Policy',
'auth.error_email_password_required': 'Email and password required',
'auth.error_password_min_6': 'Password must be at least 6 characters',
'auth.error_login_failed': 'Login failed',
'auth.error_registration_failed': 'Registration failed',
'auth.error_paste_support_token': 'Paste a support token',
'auth.error_support_failed': 'Support login failed',
'auth.error_google_failed': 'Google sign-in failed',
'auth.error_microsoft_failed': 'Microsoft sign-in failed',
// Dashboard
'dashboard.title': 'Displays',
'dashboard.subtitle': 'Manage your remote displays',
'dashboard.help_tip': 'Your paired display devices. Green = online, red = offline. Click a device to manage its playlist, view telemetry, or use remote control.',
'dashboard.add': 'Add Display',
'dashboard.create_group': '+ Group',
'dashboard.search': 'Search displays...',
'dashboard.all_status': 'All Status',
'dashboard.online': 'Online',
'dashboard.offline': 'Offline',
'dashboard.awaiting_pairing': 'Awaiting Pairing',
'dashboard.no_preview': 'No preview available',
'dashboard.total_displays': 'Total Displays',
'dashboard.ungrouped': 'Ungrouped',
'dashboard.no_displays': 'No displays yet',
'dashboard.no_displays_desc': 'Install the ScreenTinker app on your TV and pair it using the button above.',
'dashboard.failed_to_load': 'Failed to load displays',
'dashboard.unknown_playlist': 'Unknown playlist',
'dashboard.mixed_playlists': 'Mixed playlists',
'dashboard.playlist_label': 'Playlist: {name}',
'dashboard.devices_count_one': '{n} device',
'dashboard.devices_count_other': '{n} devices',
'dashboard.online_count': '{n} online',
'dashboard.set_playlist_placeholder': 'Set Playlist...',
'dashboard.send_command_placeholder': 'Send Command...',
'dashboard.manage': 'Manage',
'dashboard.manage_tooltip': 'Add/remove devices',
'dashboard.delete_group_tooltip': 'Delete group',
'dashboard.no_devices_in_group': 'No devices in this group. Click Manage to add some.',
'dashboard.manage_group_subtitle': 'Check devices to add them to this group',
'dashboard.draft_suffix': '(draft)',
// Group commands
'dashboard.cmd.screen_on': 'Screen On',
'dashboard.cmd.screen_off': 'Screen Off',
'dashboard.cmd.restart_app': 'Restart App',
'dashboard.cmd.check_update': 'Check Update',
'dashboard.cmd.reboot': 'Reboot',
'dashboard.cmd.shutdown': 'Shutdown',
// Dashboard prompts/confirms
'dashboard.prompt_group_name': 'Group name:',
'dashboard.error_pairing_code': 'Enter a valid 6-digit pairing code',
'dashboard.confirm_add_to_group': '{name} is already in: {groups}\n\nAdd it to "{target}" too?',
'dashboard.confirm_assign_playlist': 'Assign playlist "{playlist}" to all devices in "{group}"?',
'dashboard.confirm_destructive_command': '{cmd} all {n} devices in "{group}"?\n\nThis cannot be undone.',
'dashboard.confirm_delete_group': 'Delete this group? Devices will not be affected.',
// Dashboard toasts
'dashboard.toast.display_paired': 'Display paired successfully!',
'dashboard.toast.group_created': 'Group created',
'dashboard.toast.group_deleted': 'Group deleted',
'dashboard.toast.already_in_group': '{name} is already in {group}',
'dashboard.toast.moved_device': 'Moved {name} to {group}',
'dashboard.toast.removed_device_one': 'Removed {name} from 1 group',
'dashboard.toast.removed_device_other': 'Removed {name} from {n} groups',
'dashboard.toast.playlist_assigned_one': 'Playlist assigned to 1 device',
'dashboard.toast.playlist_assigned_other': 'Playlist assigned to {n} devices',
'dashboard.toast.command_sent': '{cmd} sent to {sent}/{total} devices',
'dashboard.toast.command_sent_with_offline': '{cmd} sent to {sent}/{total} devices ({offline} offline)',
// Content library
'content.title': 'Content Library',
'content.subtitle': 'Upload and manage your media files',
'content.help_tip': 'Upload videos and images here. Select multiple files for bulk upload. Use Remote URL to stream from external sources. Click a thumbnail to preview.',
'content.drop': 'Drop files here or click to upload',
'content.upload_hint': 'Supports MP4, WebM, AVI, MKV, JPEG, PNG, GIF, WebP',
'content.upload_progress': 'Uploading...',
'content.upload_progress_named': 'Uploading {name}...',
'content.upload_progress_named_pct': 'Uploading {name}... {pct}%',
// Remote URL panel
'content.remote_url': 'Remote URL',
'content.remote_desc': 'Stream directly from a URL. Saves local bandwidth.',
'content.remote_url_placeholder': 'https://example.com/video.mp4',
'content.remote_name_placeholder': 'Display name (optional)',
'content.remote_add_btn': 'Add Remote URL',
// YouTube panel
'content.youtube': 'YouTube',
'content.youtube_desc': 'Embed a YouTube video on your displays.',
'content.youtube_url_placeholder': 'https://youtube.com/watch?v=...',
'content.youtube_name_placeholder': 'Display name (optional)',
'content.youtube_add_btn': 'Add YouTube Video',
// Search / folders
'content.search_placeholder': 'Search content...',
'content.new_folder_btn': '+ New Folder',
'content.breadcrumb_root': 'All Content',
'content.rename_btn': 'Rename',
'content.delete_folder_btn': 'Delete folder',
'content.prompt_folder_name': 'Folder name:',
'content.prompt_rename_folder': 'Rename folder:',
'content.confirm_delete_folder': 'Delete this folder? Content inside moves back to the root level. Subfolders will also be deleted.',
// Empty states
'content.empty_folder_title': 'This folder is empty',
'content.empty_folder_desc': 'Drag content here, or use the Move action.',
'content.no_content': 'No content yet',
'content.no_content_desc': 'Upload videos and images to get started.',
'content.failed_to_load': 'Failed to load content',
// Item type labels
'content.type_youtube': 'YouTube',
'content.type_remote': 'Remote URL',
'content.type_remote_short': 'Remote',
'content.type_video': 'Video',
'content.type_image': 'Image',
// Item action buttons
'content.btn_edit': 'Edit',
'content.btn_delete': 'Delete',
'content.btn_confirm_delete': 'Confirm Delete?',
'content.btn_deleting': 'Deleting...',
// Edit modal
'content.edit_modal_title': 'Edit Content',
'content.label_filename': 'Filename / Display Name',
'content.label_remote_url_field': 'Remote URL',
'content.label_mime_type': 'MIME Type',
'content.label_folder': 'Folder',
'content.label_replace_file': 'Replace File',
'content.replace_file_hint': 'Leave empty to keep current file',
'content.folder_root_option': '— Root —',
'content.save_changes': 'Save Changes',
// MIME options
'content.mime.video_mp4': 'Video (MP4)',
'content.mime.video_webm': 'Video (WebM)',
'content.mime.image_jpeg': 'Image (JPEG)',
'content.mime.image_png': 'Image (PNG)',
'content.mime.image_gif': 'Image (GIF)',
'content.mime.image_webp': 'Image (WebP)',
// Content errors / toasts
'content.error_enter_url': 'Enter a URL',
'content.error_enter_youtube_url': 'Enter a YouTube URL',
'content.error_update_failed': 'Update failed',
'content.toast.remote_added': 'Remote content added',
'content.toast.youtube_added': 'YouTube video added',
'content.toast.deleted': 'Content deleted',
'content.toast.updated': 'Content updated',
'content.toast.uploaded_named': '{name} uploaded successfully',
'content.toast.upload_failed_named': 'Failed to upload {name}: {error}',
'content.toast.folder_created_named': 'Folder "{name}" created',
'content.toast.folder_renamed': 'Folder renamed',
'content.toast.folder_deleted': 'Folder deleted',
'content.toast.moved': 'Moved',
'content.toast.moved_to_root': 'Moved to root',
// Device detail
'device.back': 'Back to Displays',
'device.owner_label': 'Owner: {owner}',
'device.rename': 'Rename',
'device.screenshot_btn': 'Screenshot',
'device.remove': 'Remove',
'device.click_to_confirm': 'Click again to confirm',
'device.prompt_new_name': 'Enter new name:',
'device.confirm_discard_draft': 'Discard all unpublished changes and revert to the last published version?',
'device.failed_load': 'Failed to load device',
'device.no_screenshot': 'No screenshot available. Click "Screenshot" to capture one.',
'device.no_content_assigned': 'No content assigned',
'device.now_playing_id': 'Playing: {id}',
'device.playlist_count_one': '1 item in playlist',
'device.playlist_count_other': '{n} items in playlist',
// Tabs
'device.tab.now_playing': 'Now Playing',
'device.tab.now_playing_tip': "Live screenshot of what's currently displaying on this device.",
'device.tab.playlist': 'Playlist',
'device.tab.playlist_tip': 'Content assigned to this device. Drag items to reorder. Add media, widgets, or kiosk pages.',
'device.tab.info': 'Device Info',
'device.tab.info_tip': 'Hardware telemetry, orientation settings, notes, and device controls.',
'device.tab.remote': 'Remote Control',
'device.tab.remote_tip': 'View the device screen in real-time and send key presses. Works on Android APK and web player.',
// Draft banner
'device.draft.banner_title': 'Unpublished changes',
'device.draft.devices_showing_published': 'Devices are still showing the last published version.',
'device.draft.never_published': 'This playlist has never been published. Devices will show nothing until you publish.',
'device.draft.discard': 'Discard',
'device.draft.publish': 'Publish',
'device.draft.publishing': 'Publishing...',
// Layout selector
'device.layout.label': 'Screen Layout',
'device.layout.fullscreen_default': 'Fullscreen (default)',
'device.layout.zones_count': '{name} ({n} zones)',
'device.layout.template_zones_count': '[Template] {name} ({n} zones)',
'device.layout.apply': 'Apply',
// Playlist tab
'device.playlist.label': 'Playlist',
'device.playlist.no_playlist': 'No playlist',
'device.playlist.copy_to_btn': 'Copy To...',
'device.playlist.add_content_btn': 'Add Content',
'device.playlist.empty_title': 'No content assigned',
'device.playlist.empty_desc': "Add content from your library to this display's playlist.",
'device.playlist_picker.with_count': '{name} — {n} items',
'device.playlist_picker.with_auto': '{name} (auto) — {n} items',
// Info cards
'device.info.status': 'Status',
'device.info.ip_address': 'IP Address',
'device.info.battery': 'Battery',
'device.info.storage': 'Storage',
'device.info.size_free': '{size} free',
'device.info.player_type': 'Player Type',
'device.info.web_player': 'Web Player',
'device.info.wifi': 'WiFi',
'device.info.uptime': 'Uptime',
'device.info.android_version': 'Android Version',
'device.info.app_version': 'App Version',
'device.info.screen_resolution': 'Screen Resolution',
'device.info.ram': 'RAM',
'device.info.cpu_usage': 'CPU Usage',
// Uptime timeline
'device.timeline.title': 'Uptime Timeline (Last 24 Hours)',
'device.timeline.h24_ago': '24h ago',
'device.timeline.now': 'Now',
'device.timeline.online': 'Online',
'device.timeline.offline': 'Offline',
'device.timeline.no_data': 'No data',
'device.timeline.uptime_pct_tracked': '{pct}% uptime ({n}min tracked)',
'device.timeline.uptime_pct_no_data': '{pct}% uptime (no data)',
// Form
'device.form.orientation_label': 'Orientation / Rotation',
'device.form.orientation.landscape': 'Landscape (0°)',
'device.form.orientation.portrait': 'Portrait (90° CW)',
'device.form.orientation.landscape_flipped': 'Landscape Flipped (180°)',
'device.form.orientation.portrait_flipped': 'Portrait Flipped (270° CW)',
'device.form.default_content_label': 'Default Content',
'device.form.default_content_none': 'None (show "Waiting...")',
'device.form.notes_label': 'Notes',
'device.form.notes_placeholder': 'Location, setup details, etc.',
'device.form.save_settings': 'Save Settings',
// Control buttons
'device.ctl.reboot_device': 'Reboot Device',
'device.ctl.screen_off': 'Screen Off',
'device.ctl.screen_on': 'Screen On',
'device.ctl.launch_player': 'Launch Player',
'device.ctl.force_update': 'Force Update',
'device.ctl.shutdown': 'Shutdown',
// Remote tab
'device.remote.start_prompt': 'Click "Start Remote" to begin',
'device.remote.start': 'Start Remote',
'device.remote.stop': 'Stop Remote',
'device.remote.vol_up': 'Vol +',
'device.remote.vol_down': 'Vol -',
'device.remote.home': 'Home',
'device.remote.back': 'Back',
'device.remote.recents': 'Recents',
'device.remote.power': 'Power',
'device.remote.ok': 'OK',
'device.remote.settings': 'Settings',
'device.remote.scrn_off': 'Scrn Off',
'device.remote.scrn_on': 'Scrn On',
'device.remote.enable_system_view': 'Enable System View',
'device.remote.system_view_tooltip': 'Prompts the device user to allow full screen capture - enables remote view of home screen, settings, and other apps',
'device.remote.system_view_hint': 'Requires one-time approval on device',
'device.remote.waiting_for_approval': 'Waiting for device approval...',
'device.remote.system_view_enabled': 'System View Enabled',
'device.remote.unlocked_hint': 'Navigation and system controls unlocked',
// Playlist item
'device.pl_item.widget_with_type': 'Widget ({type})',
'device.pl_item.youtube': 'YouTube',
'device.pl_item.video': 'Video',
'device.pl_item.image': 'Image',
'device.pl_item.zone_label': 'Zone: {id}',
'device.pl_item.no_zone': 'No zone',
'device.pl_item.mute': 'Mute',
'device.pl_item.unmute': 'Unmute',
'device.pl_item.remove': 'Remove',
// Copy playlist
'device.copy.no_other_devices': 'No other devices to copy to',
'device.copy.prompt': 'Copy playlist to which device?\n\n{list}\n\nEnter number:',
'device.copy.invalid_selection': 'Invalid selection',
'device.copy.toast': 'Copied {n} items to {device}',
// Add-content modal
'device.assign.empty_all': 'No content, widgets, or kiosk pages yet. Create something first!',
'device.assign.modal_title': 'Add to Playlist',
'device.assign.zone_label': 'Zone',
'device.assign.zone_default': 'Default (fullscreen)',
'device.assign.duration_label': 'Display Duration (seconds, for images/widgets)',
'device.assign.tab.media': 'Media ({n})',
'device.assign.tab.widgets': 'Widgets ({n})',
'device.assign.tab.kiosk': 'Kiosk ({n})',
'device.assign.no_media': 'No media uploaded yet',
'device.assign.no_widgets': 'No widgets created yet.',
'device.assign.no_kiosk': 'No kiosk pages yet.',
'device.assign.create_one': 'Create one',
'device.assign.add_selected': 'Add Selected',
'device.assign.select_first': 'Select something first',
'device.assign.kiosk_widget_name': 'Kiosk: {name}',
// Toasts
'device.toast.screenshot_requested': 'Screenshot requested',
'device.toast.renamed': 'Display renamed',
'device.toast.removing': 'Removing...',
'device.toast.removed': 'Display removed',
'device.toast.settings_saved': 'Settings saved',
'device.toast.published': 'Playlist published — devices updated',
'device.toast.draft_discarded': 'Draft changes discarded',
'device.toast.playlist_changed': 'Playlist changed',
'device.toast.layout_applied': 'Layout applied',
'device.toast.switched_to_fullscreen': 'Switched to fullscreen',
'device.toast.added_to_playlist': 'Added to playlist',
'device.toast.unmuted': 'Unmuted',
'device.toast.muted': 'Muted',
'device.toast.zone_updated': 'Zone updated',
'device.toast.removed_from_playlist': 'Content removed from playlist',
'device.toast.playlist_reordered': 'Playlist reordered',
'device.toast.reboot_sent': 'Reboot command sent',
'device.toast.shutdown_sent': 'Shutdown command sent',
'device.toast.screen_off_sent': 'Screen off command sent',
'device.toast.screen_on_sent': 'Screen on command sent',
'device.toast.launch_sent': 'Launch command sent',
'device.toast.update_triggered': 'Update check triggered',
'device.toast.remote_started': 'Remote session started',
// Settings
'settings.title': 'Settings',
'settings.subtitle': 'Server configuration and setup information',
'settings.account': 'Account',
'settings.save_profile': 'Save Profile',
'settings.email_alerts': 'Email me when devices go offline',
'settings.change_password': 'Change Password',
'settings.password_min_8': 'Must be at least 8 characters.',
'settings.current_password': 'Current Password',
'settings.new_password': 'New Password',
'settings.confirm_new_password': 'Confirm New Password',
'settings.sso_note': 'You sign in via {provider}. Manage your password there.',
'settings.license': 'License',
'settings.license_mit': 'MIT License - all features included.',
'settings.platform_admin_link': 'Platform admin tools are in the',
'settings.platform_admin_page_suffix': 'page.',
'settings.user_management': 'User Management',
'settings.loading_users': 'Loading users...',
'settings.white_label': 'White Label / Branding',
'settings.white_label_desc': 'Customize the look of your dashboard and player for your clients.',
'settings.brand_name': 'Brand Name',
'settings.logo_url': 'Logo URL',
'settings.primary_color': 'Primary Color',
'settings.bg_color': 'Background Color',
'settings.custom_domain': 'Custom Domain',
'settings.favicon_url': 'Favicon URL',
'settings.custom_css': 'Custom CSS (optional)',
'settings.hide_branding': 'Hide "ScreenTinker" branding',
'settings.save_branding': 'Save Branding',
'settings.preview': 'Preview',
'settings.white_label_enterprise_only': 'Custom branding is available on the Enterprise plan',
'settings.view_plans': 'View Plans',
'settings.server_info': 'Server Information',
'settings.server_url': 'Server URL',
'settings.api_endpoint': 'API Endpoint',
'settings.server_url_hint': 'Use this URL when setting up the Android app',
'settings.setup_guide': 'Setup Guide',
'settings.setup_step_1': 'Install the ScreenTinker APK on your TV via sideloading',
'settings.setup_step_2_prefix': 'Open the app and enter this server URL:',
'settings.setup_step_3': 'The app will display a 6-digit pairing code',
'settings.setup_step_4': 'Click "Add Display" on the dashboard and enter the pairing code',
'settings.setup_step_5': 'Upload content in the Content Library',
'settings.setup_step_6': "Assign content to the display's Playlist",
'settings.your_data': 'Your Data',
'settings.your_data_desc': 'Export or import your devices, content, layouts, schedules, and all settings. Use this to migrate between cloud and self-hosted instances.',
'settings.export_my_data': 'Export My Data',
'settings.include_media_zip': 'Include media files (ZIP)',
'settings.import_data': 'Import Data',
'settings.language': 'Language',
'settings.about': 'About',
'settings.about_tagline': 'Digital signage management system.',
'settings.third_party_licenses': 'Third-Party Licenses',
// Import flow
'settings.import.reading_file': 'Reading file...',
'settings.import.zip_detected': 'ZIP export detected: {name} ({size} MB)
Contains data + media files.',
'settings.import.confirm': 'Confirm Import',
'settings.import.invalid_file': 'Invalid file. Must be a ScreenTinker export JSON or ZIP.',
'settings.import.summary_devices': '{n} devices',
'settings.import.summary_content': '{n} content items',
'settings.import.summary_widgets': '{n} widgets',
'settings.import.summary_layouts': '{n} layouts',
'settings.import.summary_schedules': '{n} schedules',
'settings.import.summary_walls': '{n} video walls',
'settings.import.summary_kiosk': '{n} kiosk pages',
'settings.import.found_summary': 'Found: {summary}.
From: {email} (exported {date})',
'settings.import.empty_export': 'empty export',
'settings.import.uploading_zip': 'Uploading and importing... This may take a moment for large files.',
'settings.import.importing': 'Importing...',
'settings.import.complete': 'Import complete: {imported}.',
'settings.import.pairing_codes_title': 'Device Pairing Codes:',
'settings.import.pairing_codes_hint': 'Enter these codes on each device to re-link them. All assignments and schedules will be preserved.',
'settings.import.failed': 'Import failed',
'settings.import.failed_with_error': 'Import failed: {error}',
'settings.import.read_failed': 'Failed to read file: {error}',
// Settings toasts
'settings.toast.support_token_generated': 'Support token generated (valid {hours}h)',
'settings.toast.import_success': 'Data imported successfully',
'settings.toast.name_required': 'Name cannot be empty',
'settings.toast.profile_saved': 'Profile saved',
'settings.toast.current_password_required': 'Enter your current password',
'settings.toast.new_password_min_8': 'New password must be at least 8 characters',
'settings.toast.passwords_dont_match': 'New passwords do not match',
'settings.toast.password_changed': 'Password changed',
'settings.toast.branding_saved': 'Branding saved',
'settings.toast.preview_applied': 'Preview applied (refresh to reset)',
'settings.toast.plan_updated': 'Plan updated',
'settings.toast.user_removed': 'User removed',
// User management table
'settings.user.col_user': 'User',
'settings.user.col_auth': 'Auth',
'settings.user.col_role': 'Role',
'settings.user.col_plan': 'Plan',
'settings.user.col_actions': 'Actions',
'settings.user.remove': 'Remove',
'settings.user.you': 'You',
'settings.user.confirm': 'Confirm?',
'settings.user.count_one': '1 user registered',
'settings.user.count_other': '{n} users registered',
'settings.user.reset_password': 'Reset Password',
'settings.user.prompt_reset_password': 'Enter a new password for {email} (minimum 8 characters):',
'settings.toast.password_reset_for_user': 'Password reset',
// Widgets
'widget.title': 'Widgets',
'widget.subtitle': 'Add dynamic content to your layouts',
'widget.help_tip': 'Dynamic content elements: live clocks, weather, RSS tickers, text, webpages, and social feeds. Create a widget then assign it to a device playlist.',
'widget.new_widget': 'New Widget',
'widget.configure': 'Configure Widget',
'widget.preview': 'Preview',
'widget.preview_title': 'Preview',
'widget.close': 'Close',
'widget.edit_x': 'Edit {type}',
'widget.new_x': 'New {type}',
'widget.empty_title': 'No widgets yet',
'widget.empty_desc': 'Create a widget to add dynamic content to your layouts.',
'widget.this_widget': 'this widget',
'widget.confirm_delete': 'Delete "{name}"? This cannot be undone.',
'widget.toast.saved': 'Widget saved',
'widget.toast.deleted': 'Widget deleted',
'widget.toast.preview_failed': 'Preview failed',
// Widget types
'widget.type.clock.name': 'Clock',
'widget.type.clock.desc': 'Digital clock with date',
'widget.type.weather.name': 'Weather',
'widget.type.weather.desc': 'Current weather conditions',
'widget.type.rss.name': 'News Ticker',
'widget.type.rss.desc': 'Scrolling RSS feed',
'widget.type.text.name': 'Text/HTML',
'widget.type.text.desc': 'Custom text or HTML content',
'widget.type.webpage.name': 'Webpage',
'widget.type.webpage.desc': 'Embed a webpage',
'widget.type.social.name': 'Social Feed',
'widget.type.social.desc': 'Social media feed',
'widget.type.directory_board.name': 'Directory Board',
'widget.type.directory_board.desc': 'Scrolling tenant/room directory for lobbies',
// Widget config form fields
'widget.field.name': 'Widget Name',
'widget.field.format': 'Format',
'widget.field.format_12h': '12 Hour',
'widget.field.format_24h': '24 Hour',
'widget.field.timezone': 'Timezone',
'widget.field.font_size': 'Font Size',
'widget.field.font_size_px': 'Font Size (px)',
'widget.field.color': 'Color',
'widget.field.background': 'Background',
'widget.field.location': 'Location',
'widget.field.location_placeholder': 'City, State',
'widget.field.units': 'Units',
'widget.field.units_imperial': 'Imperial (°F)',
'widget.field.units_metric': 'Metric (°C)',
'widget.field.feed_url': 'Feed URL',
'widget.field.scroll_speed_seconds': 'Scroll Speed (seconds)',
'widget.field.max_items': 'Max Items',
'widget.field.html_content': 'HTML Content',
'widget.field.css_optional': 'CSS (optional)',
'widget.field.url': 'URL',
'widget.field.zoom_pct': 'Zoom (%)',
'widget.field.refresh_interval': 'Refresh Interval (seconds, 0 = never)',
'widget.field.platform': 'Platform',
'widget.field.platform_twitter': 'Twitter/X',
'widget.field.platform_instagram': 'Instagram',
'widget.field.query': 'Query',
'widget.field.query_placeholder': '@handle or #hashtag',
// Content picker
'widget.picker.default_title': 'Select Image',
'widget.picker.select_logo': 'Select Logo',
'widget.picker.select_bg_images': 'Select Background Images',
'widget.picker.search': 'Search images...',
'widget.picker.no_matches': 'No matches.',
'widget.picker.no_images': 'No images in your content library. Upload images first from Content Library.',
'widget.picker.selected_count': '{n} selected',
// Directory Board
'widget.dir.title_label': 'Title',
'widget.dir.title_placeholder': 'Lincoln Warehouse',
'widget.dir.logo_label': 'Logo (optional)',
'widget.dir.footer_text_label': 'Footer Text',
'widget.dir.footer_placeholder': 'For Leasing Inquiries: Contact...',
'widget.dir.bg_images_label': 'Background Images (optional)',
'widget.dir.bg_images_hint': 'Images crossfade every 15 seconds at 30% opacity. Add multiple for rotation.',
'widget.dir.add_bg_image': '+ Add Background Image',
'widget.dir.theme': 'Theme',
'widget.dir.theme_dark': 'Dark',
'widget.dir.theme_light': 'Light',
'widget.dir.scroll_speed': 'Scroll Speed',
'widget.dir.speed_slow': 'Slow',
'widget.dir.speed_medium': 'Medium',
'widget.dir.speed_fast': 'Fast',
'widget.dir.columns': 'Columns',
'widget.dir.columns_auto': 'Auto',
'widget.dir.categories': 'Categories',
'widget.dir.add_category': '+ Add Category',
'widget.dir.add_entry': '+ Add Entry',
'widget.dir.empty_categories': 'Add your first floor or department to get started',
'widget.dir.no_entries': 'No entries yet',
'widget.dir.entry': 'entry',
'widget.dir.entries': 'entries',
'widget.dir.collapse': 'Collapse',
'widget.dir.expand': 'Expand',
'widget.dir.move_up': 'Move up',
'widget.dir.move_down': 'Move down',
'widget.dir.delete_category': 'Delete category',
'widget.dir.delete_entry': 'Delete entry',
'widget.dir.unnamed': '(unnamed)',
'widget.dir.confirm_delete_category': 'Delete category "{name}" and all its entries?',
'widget.dir.category_name_placeholder': 'e.g. First Floor',
'widget.dir.entry_id_placeholder': '101',
'widget.dir.entry_name_placeholder': 'Tenant name',
'widget.dir.entry_subtitle_placeholder': 'Details (optional)',
'widget.dir.available': 'Available',
'widget.dir.change': 'Change',
'widget.dir.choose_logo': 'Choose Logo',
'widget.dir.remove_logo': 'Remove',
'widget.dir.no_bg_images': 'No background images selected',
'widget.dir.remove_bg': 'Remove',
// Designer
'designer.title': 'Content Designer',
'designer.subtitle': 'Create dynamic signage content',
'designer.help_tip': 'Create custom signage with live elements: clocks, weather, RSS tickers, countdowns, QR codes. Publish as a widget or export as PNG.',
'designer.load_design': 'Load Design',
'designer.export_png': 'Export PNG',
'designer.publish': 'Publish to Library',
'designer.preview_hint': 'Click elements to select. Drag to reposition. Live preview updates in real-time.',
'designer.add_element': 'Add Element',
'designer.background': 'Background',
'designer.bg_image': 'Image',
'designer.properties': 'Properties',
'designer.layers': 'Layers',
'designer.no_elements': 'No elements yet',
'designer.save_design_file': 'Save Design File',
'designer.qr_label': 'QR CODE',
'designer.loading_news': 'Loading news...',
'designer.no_items': 'No items',
'designer.feed_unavailable': 'Feed unavailable',
'designer.countdown_now': 'NOW!',
'designer.widget_name': 'Design {date}',
// Element buttons
'designer.el.text': 'Text',
'designer.el.heading': 'Heading',
'designer.el.image': 'Image',
'designer.el.video': 'Video',
'designer.el.clock': 'Clock',
'designer.el.date': 'Date',
'designer.el.weather': 'Weather',
'designer.el.ticker': 'Ticker',
'designer.el.shape': 'Shape',
'designer.el.qr': 'QR Code',
'designer.el.countdown': 'Countdown',
'designer.el.webpage': 'Webpage',
// Backgrounds
'designer.bg.black': 'Black',
'designer.bg.dark_blue': 'Dark Blue',
'designer.bg.dark_gradient': 'Dark Gradient',
'designer.bg.blue_gradient': 'Blue Gradient',
'designer.bg.sunset': 'Sunset',
'designer.bg.ocean': 'Ocean',
'designer.bg.forest': 'Forest',
'designer.bg.dark_red': 'Dark Red',
'designer.bg.white': 'White',
// Defaults / prompts
'designer.default.text': 'Your text here',
'designer.default.heading': 'HEADING',
'designer.default.coming_soon': 'Coming Soon',
'designer.prompt.video_url': 'Video URL (MP4):',
'designer.prompt.weather_location': 'City, State:',
'designer.prompt.rss_url': 'RSS Feed URL:',
'designer.prompt.qr_url': 'QR Code URL:',
'designer.prompt.countdown_date': 'Target date (YYYY-MM-DD):',
'designer.prompt.webpage_url': 'Webpage URL:',
// Properties
'designer.prop.text': 'Text',
'designer.prop.size': 'Size',
'designer.prop.font': 'Font',
'designer.prop.color': 'Color',
'designer.prop.bold': 'Bold',
'designer.prop.shadow': 'Shadow',
'designer.prop.format': 'Format',
'designer.prop.show_seconds': 'Show seconds',
'designer.prop.muted': 'Muted',
'designer.prop.loop': 'Loop',
'designer.prop.opacity': 'Opacity',
'designer.prop.shape': 'Shape',
'designer.prop.location': 'Location',
'designer.prop.feed_url': 'Feed URL',
'designer.prop.speed': 'Speed (seconds)',
'designer.prop.text_color': 'Text Color',
'designer.prop.bg_color': 'BG Color',
'designer.prop.target_date': 'Target Date',
'designer.prop.label': 'Label',
// Toasts
'designer.toast.published': 'Published as widget! Assign it to a layout zone.',
'designer.toast.publish_failed': 'Publish failed',
'designer.toast.export_failed': 'Export failed: {error}',
'designer.toast.loaded': 'Design loaded',
'designer.toast.invalid_file': 'Invalid design file',
// Playlists
'playlist.title': 'Playlists',
'playlist.subtitle': 'Create and manage content playlists',
'playlist.show_auto_generated': 'Show auto-generated',
'playlist.new_playlist_btn': '+ New Playlist',
'playlist.new_playlist': 'New Playlist',
'playlist.empty_title': 'No playlists yet',
'playlist.empty_desc': 'Create your first playlist to organize content for your displays.',
'playlist.all_auto_generated': 'All playlists are auto-generated. Toggle "Show auto-generated" to see them.',
'playlist.tag_auto': 'auto',
'playlist.tag_draft': 'draft',
'playlist.item_count_one': '1 item',
'playlist.item_count_other': '{n} items',
'playlist.created_at': 'Created {date}',
'playlist.display_count_one': '1 display',
'playlist.display_count_other': '{n} displays',
'playlist.assigned_to_one': 'Assigned to 1 display',
'playlist.assigned_to_other': 'Assigned to {n} displays',
'playlist.load_failed': 'Failed to load playlists: {error}',
'playlist.back_to_playlists': 'Back to Playlists',
'playlist.name_placeholder': 'Playlist name',
'playlist.desc_placeholder': 'Description (optional)',
'playlist.create_btn': 'Create',
'playlist.add_desc_placeholder': 'Add a description...',
'playlist.click_to_rename': 'Click to rename',
'playlist.click_to_edit_desc': 'Click to edit description',
'playlist.add_content': '+ Add Content',
'playlist.delete_playlist': 'Delete Playlist',
'playlist.back': 'Back',
'playlist.items_empty': 'This playlist is empty',
'playlist.items_empty_hint': 'Click "Add Content" to add items.',
'playlist.duration': 'Duration',
'playlist.sec': 'sec',
'playlist.move_up': 'Move up',
'playlist.move_down': 'Move down',
'playlist.remove_item': 'Remove item',
'playlist.item_widget': 'Widget',
'playlist.unknown_type': 'Unknown type',
'playlist.confirm_delete': 'Delete "{name}"? This cannot be undone.',
'playlist.confirm_discard_draft': 'Discard all unpublished changes and revert to the last published version?',
'playlist.draft.banner_title': 'Unpublished changes',
'playlist.draft.devices_showing_published': 'Devices are still showing the last published version.',
'playlist.draft.never_published': 'This playlist has never been published. Devices will show nothing until you publish.',
'playlist.draft.discard_changes': 'Discard Changes',
'playlist.draft.publish': 'Publish',
'playlist.draft.publishing': 'Publishing...',
'playlist.toast.created': 'Playlist created',
'playlist.toast.deleted': 'Playlist deleted',
'playlist.toast.published': 'Playlist published — devices updated',
'playlist.toast.draft_discarded': 'Draft changes discarded',
'playlist.toast.item_removed': 'Item removed',
'playlist.add_modal_title': 'Add Content to Playlist',
'playlist.tab_content': 'Content',
'playlist.tab_widgets': 'Widgets',
'playlist.search_placeholder': 'Search...',
'playlist.close': 'Close',
'playlist.no_content_found': 'No content found',
'playlist.no_widgets_found': 'No widgets found',
'playlist.add_btn': 'Add',
'playlist.adding': 'Adding...',
'playlist.added': 'Added',
// Onboarding
'onboarding.back': 'Back',
'onboarding.next': 'Next',
'onboarding.skip': 'Skip Wizard',
'onboarding.go_to_dashboard': 'Go to Dashboard',
'onboarding.pair_display': 'Pair Display',
'onboarding.step.welcome.title': 'Welcome to ScreenTinker!',
'onboarding.step.welcome.intro': "Let's get you set up in under 5 minutes.",
'onboarding.step.welcome.guide_through': 'This wizard will guide you through:',
'onboarding.step.welcome.bullet_download': 'Downloading the player app',
'onboarding.step.welcome.bullet_pair': 'Pairing your first display',
'onboarding.step.welcome.bullet_upload': 'Uploading and assigning content',
'onboarding.step.player.title': 'Step 1: Get the Player App',
'onboarding.step.player.intro': 'Install the player on your display device.',
'onboarding.step.player.android_label': 'Android APK',
'onboarding.step.player.android_desc': 'TV boxes, tablets, Fire TV',
'onboarding.step.player.web_label': 'Web Player',
'onboarding.step.player.web_desc': 'Any browser, Pi, ChromeOS',
'onboarding.step.player.url_hint': 'Open the app on your display and enter this server URL:',
'onboarding.step.pair.title': 'Step 2: Pair Your Display',
'onboarding.step.pair.intro': 'Enter the 6-digit code shown on your display.',
'onboarding.step.pair.name_placeholder': 'Display name (e.g., Lobby TV)',
'onboarding.step.upload.title': 'Step 3: Upload Content',
'onboarding.step.upload.intro': 'Upload a video or image to display.',
'onboarding.step.upload.click_to_select': 'Click to select a file',
'onboarding.step.upload.formats': 'MP4, WebM, JPEG, PNG, GIF',
'onboarding.step.upload.uploading': 'Uploading...',
'onboarding.step.done.title': "You're All Set!",
'onboarding.step.done.intro': 'Your display is paired and content is playing!',
'onboarding.step.done.whats_next': "What's next?",
'onboarding.step.done.next_content': 'Add more content in the Content Library',
'onboarding.step.done.next_layouts': 'Create multi-zone layouts in Layouts',
'onboarding.step.done.next_schedule': 'Set up a schedule in the Schedule calendar',
'onboarding.step.done.next_widgets': 'Add live widgets (clock, weather, ticker) in Widgets',
'onboarding.step.done.next_kiosk': 'Create interactive screens in Kiosk',
'onboarding.step.done.next_designer': 'Design custom content in the Designer',
'onboarding.toast.invalid_code': 'Enter a valid 6-digit code',
'onboarding.toast.pairing': 'Pairing...',
'onboarding.toast.pair_failed': 'Pairing failed',
'onboarding.toast.pair_failed_with_error': 'Pairing failed: {error}',
'onboarding.toast.paired': 'Display paired!',
'onboarding.toast.uploaded_assigning': 'Uploaded! Assigning to display...',
'onboarding.toast.content_assigned': 'Content uploaded and assigned!',
'onboarding.toast.upload_failed': 'Upload failed',
'onboarding.toast.error_with_error': 'Error: {error}',
// Admin (platform admin panel)
'admin.title': 'Platform Admin',
'admin.subtitle': 'Superadmin controls - only you can see this',
'admin.access_denied': 'Access Denied',
'admin.access_denied_desc': 'Platform admin access required.',
'admin.all_users': 'All Users',
'admin.plans': 'Subscription Plans',
'admin.system': 'System',
'admin.col.user': 'User',
'admin.col.auth': 'Auth',
'admin.col.last_login': 'Last Login',
'admin.col.role': 'Role',
'admin.col.plan': 'Plan',
'admin.col.actions': 'Actions',
'admin.col.devices': 'Devices',
'admin.col.storage': 'Storage',
'admin.col.monthly': 'Monthly',
'admin.col.yearly': 'Yearly',
'admin.role.user': 'User',
'admin.role.admin': 'Admin',
'admin.role.superadmin': 'Superadmin',
'admin.remove': 'Remove',
'admin.owner': 'Owner',
'admin.confirm': 'Confirm?',
'admin.total_users': '{n} total users',
'admin.unlimited': 'Unlimited',
'admin.free': 'Free',
'admin.version': 'Version',
'admin.frontend_hash': 'Frontend Hash',
'admin.download_db_backup': 'Download DB Backup',
'admin.server_status': 'Server Status',
'admin.toast.role_updated': 'Role updated',
'admin.toast.plan_updated': 'Plan updated',
'admin.toast.user_removed': 'User removed',
'admin.reset_password': 'Reset Password',
'admin.prompt_reset_password': 'Enter a new password for {email} (minimum 8 characters):',
'admin.toast.password_min_8': 'Password must be at least 8 characters',
'admin.toast.password_reset': 'Password reset',
// Schedule
'schedule.title': 'Schedule',
'schedule.subtitle': 'Content scheduling calendar',
'schedule.help_tip': 'Visual weekly calendar for content scheduling. Click Add Schedule to create time slots. Set recurrence for repeating content. Higher priority overrides lower. Device-level schedules override group-level.',
'schedule.prev_week': '< Prev',
'schedule.next_week': 'Next >',
'schedule.add_schedule': 'Add Schedule',
'schedule.edit_schedule': 'Edit Schedule',
'schedule.apply_to': 'Apply to',
'schedule.target_device': 'Device',
'schedule.target_group': 'Group',
'schedule.group_devices_count': '{n} devices',
'schedule.no_groups_msg': 'No groups created yet. Create groups in the Displays page.',
'schedule.zone_note': 'Note: Zone-based schedules are layout-specific. Ensure all devices in the group use the same layout.',
'schedule.playlist_override': 'Playlist override',
'schedule.no_playlist_override': '— No playlist override —',
'schedule.draft_suffix': '(draft)',
'schedule.layout_override': 'Layout override',
'schedule.no_layout_override': '— No layout override —',
'schedule.content_label': 'Content',
'schedule.content_hint': '(single item, optional)',
'schedule.content_none': '— None —',
'schedule.title_label': 'Title (optional)',
'schedule.title_placeholder': 'e.g., Morning Playlist',
'schedule.start_time': 'Start Time',
'schedule.end_time': 'End Time',
'schedule.repeat': 'Repeat',
'schedule.repeat_none': 'No repeat',
'schedule.repeat_daily': 'Daily',
'schedule.repeat_weekdays': 'Weekdays',
'schedule.repeat_weekends': 'Weekends',
'schedule.repeat_weekly': 'Weekly',
'schedule.priority': 'Priority',
'schedule.color': 'Color',
'schedule.scheduled_label': 'Scheduled',
'schedule.tooltip_group_prefix': 'Group: ',
'schedule.tooltip_priority': 'Priority: {n}',
'schedule.day.sun': 'Sun',
'schedule.day.mon': 'Mon',
'schedule.day.tue': 'Tue',
'schedule.day.wed': 'Wed',
'schedule.day.thu': 'Thu',
'schedule.day.fri': 'Fri',
'schedule.day.sat': 'Sat',
'schedule.hour_12am': '12am',
'schedule.hour_am': 'am',
'schedule.hour_12pm': '12pm',
'schedule.hour_pm': 'pm',
'schedule.toast.no_groups': 'No groups available. Create a group first.',
'schedule.toast.saved': 'Schedule saved',
// Reports
'report.title': 'Reports',
'report.subtitle': 'Proof-of-play analytics and device uptime',
'report.help_tip': 'Proof-of-play analytics. See what played, when, and on which device. Filter by date range and device. Export to CSV for ad verification.',
'report.export_csv': 'Export CSV',
'report.device': 'Device',
'report.all_devices': 'All Devices',
'report.start_date': 'Start Date',
'report.end_date': 'End Date',
'report.load_report': 'Load Report',
'report.select_range': 'Select a date range and click Load Report',
'report.error': 'Error',
'report.total_plays': 'Total Plays',
'report.total_hours': 'Total Hours',
'report.unique_content': 'Unique Content',
'report.active_devices': 'Active Devices',
'report.avg_duration': 'Avg Duration',
'report.plays_per_day': 'Plays per Day',
'report.plays_by_hour': 'Plays by Hour',
'report.top_content': 'Top Content',
'report.by_device': 'By Device',
'report.no_data': 'No data',
'report.col.content': 'Content',
'report.col.device': 'Device',
'report.col.plays': 'Plays',
'report.col.total_hours': 'Total Hours',
'report.col.completion': 'Completion',
// Kiosk
'kiosk.title': 'Kiosk Pages',
'kiosk.subtitle': 'Create interactive touchscreen interfaces',
'kiosk.help_tip': 'Create interactive touchscreen interfaces. Add buttons with icons and actions. Includes idle screen that shows after inactivity. Assign to devices as a widget.',
'kiosk.new_page': 'New Kiosk Page',
'kiosk.prompt_name': 'Kiosk page name:',
'kiosk.empty_title': 'No kiosk pages yet',
'kiosk.empty_desc': 'Create an interactive touchscreen interface for your displays.',
'kiosk.label': 'Kiosk Page',
'kiosk.preview': 'Preview',
'kiosk.confirm_delete': 'Delete kiosk page "{name}"? This cannot be undone.',
'kiosk.toast.deleted': 'Kiosk page deleted',
'kiosk.toast.delete_failed': 'Failed to delete',
'kiosk.toast.saved': 'Kiosk page saved',
'kiosk.not_found': 'Page not found',
'kiosk.back': 'Back to Kiosk Pages',
'kiosk.page_settings': 'Page Settings',
'kiosk.title_label': 'Title',
'kiosk.subtitle_label': 'Subtitle',
'kiosk.logo_url': 'Logo URL',
'kiosk.footer_text': 'Footer Text',
'kiosk.idle_title': 'Idle Screen Title',
'kiosk.idle_default': 'Touch to Begin',
'kiosk.idle_timeout': 'Idle Timeout (seconds)',
'kiosk.style': 'Style',
'kiosk.background': 'Background',
'kiosk.text_color': 'Text Color',
'kiosk.columns': 'Columns',
'kiosk.button_color': 'Button Color',
'kiosk.button_hover': 'Button Hover Color',
'kiosk.buttons': 'Buttons',
'kiosk.add_btn': '+ Add',
'kiosk.icon_placeholder': 'Emoji',
'kiosk.label_placeholder': 'Label',
'kiosk.sublabel_placeholder': 'Sublabel',
'kiosk.action_none': 'No action',
'kiosk.action_url': 'Open URL',
'kiosk.action_page': 'Go to page',
'kiosk.url_placeholder': 'URL or page',
'kiosk.no_buttons': 'No buttons yet',
'kiosk.new_button': 'New Button',
// Layout editor
'layout.title': 'Layouts',
'layout.subtitle': 'Screen layouts and templates',
'layout.help_tip': 'Create multi-zone screen layouts. Use templates or build custom ones. Drag zones to position, resize with corner handle. Assign layouts to devices in the Playlist tab.',
'layout.new_layout': 'New Layout',
'layout.templates': 'Templates',
'layout.my_layouts': 'My Layouts',
'layout.empty_custom': 'No custom layouts yet',
'layout.prompt_name': 'Layout name:',
'layout.default_zone_name': 'Main',
'layout.template_label': 'Template',
'layout.use_template': 'Use Template',
'layout.zone_count_one': '1 zone',
'layout.zone_count_other': '{n} zones',
'layout.confirm_delete': 'Delete layout "{name}"? This cannot be undone.',
'layout.toast.deleted': 'Layout deleted',
'layout.toast.delete_failed': 'Failed to delete layout',
'layout.toast.saved': 'Layout saved',
'layout.not_found': 'Layout not found',
'layout.back': 'Back to Layouts',
'layout.add_zone': 'Add Zone',
'layout.zones': 'Zones',
'layout.properties': 'Properties',
'layout.delete_zone': 'Delete Zone',
'layout.zone_n': 'Zone {n}',
'layout.prop.name': 'Name',
'layout.prop.x': 'X (%)',
'layout.prop.y': 'Y (%)',
'layout.prop.width': 'Width (%)',
'layout.prop.height': 'Height (%)',
'layout.prop.type': 'Type',
'layout.type_content': 'Content',
'layout.type_widget': 'Widget',
// Video walls
'wall.title': 'Video Walls',
'wall.subtitle': 'Combine multiple displays into one large screen',
'wall.help_tip': 'Combine multiple displays into one large screen. Set grid size, drag devices into positions, adjust bezel compensation. Assign content to play across all devices.',
'wall.new_wall': 'New Video Wall',
'wall.prompt_name': 'Video wall name:',
'wall.empty_title': 'No video walls yet',
'wall.empty_desc': 'Create a video wall to combine multiple displays.',
'wall.grid_summary': '{cols}x{rows} grid • {n} devices',
'wall.not_found': 'Wall not found',
'wall.back': 'Back to Video Walls',
'wall.delete_wall': 'Delete Wall',
'wall.grid_config': 'Grid Configuration',
'wall.columns': 'Columns',
'wall.rows': 'Rows',
'wall.h_bezel': 'H Bezel (px)',
'wall.v_bezel': 'V Bezel (px)',
'wall.update': 'Update',
'wall.content': 'Content',
'wall.no_content': 'No content',
'wall.set_content': 'Set Content',
'wall.available_displays': 'Available Displays',
'wall.all_assigned': 'All devices assigned',
'wall.drop_here': 'Drop here',
'wall.toast.placed': '{name} placed at [{col},{row}]',
'wall.toast.grid_updated': 'Grid updated',
'wall.toast.content_updated': 'Content updated',
'wall.toast.deleted': 'Wall deleted',
// Billing
'billing.title': 'Subscription',
'billing.subtitle': 'Manage your plan and billing',
'billing.current_plan': 'Current Plan',
'billing.self_hosted': 'Self-Hosted',
'billing.trial_days_left': 'Trial - {n} days left',
'billing.trial_ends': 'Your {plan} trial ends in {n} days',
'billing.trial_after': "After the trial, you'll be moved to the Free plan (1 device). Upgrade now to keep all your devices and features.",
'billing.devices': 'Devices',
'billing.devices_lc': 'devices',
'billing.storage': 'Storage',
'billing.storage_lc': 'storage',
'billing.features': 'Features',
'billing.feat.remote_control': 'Remote Control',
'billing.feat.remote_urls': 'Remote URLs',
'billing.feat.priority_support': 'Priority Support',
'billing.available_plans': 'Available Plans',
'billing.current': 'Current',
'billing.unlimited': 'Unlimited',
'billing.free': 'Free',
'billing.per_month': '/mo',
'billing.yearly_save': 'or ${price}/year (save {pct}%)',
'billing.monthly': 'Monthly',
'billing.yearly': 'Yearly',
'billing.manage_subscription': 'Manage Subscription',
'billing.self_hosted_note': 'Self-hosted mode: plans can be assigned by admins without billing.',
'billing.failed_to_load': 'Failed to load',
'billing.toast.checkout_failed': 'Failed to start checkout: {error}',
'billing.toast.portal_failed': 'Failed to open billing portal: {error}',
'billing.toast.payment_success': 'Payment successful! Your plan has been upgraded.',
// Teams
'team.title': 'Teams',
'team.subtitle': 'Manage teams and shared access',
'team.help_tip': 'Create teams to share devices with other users. Owners manage the team, editors can change content/playlists, viewers can only monitor.',
'team.new_team': 'New Team',
'team.prompt_name': 'Team name:',
'team.empty_title': 'No teams yet',
'team.empty_desc': 'Create a team to share devices with other users.',
'team.your_role': 'Your role: {role}',
'team.member_count_one': '1 member',
'team.member_count_other': '{n} members',
'team.not_found': 'Team not found',
'team.back': 'Back to Teams',
'team.delete_team': 'Delete Team',
'team.members_count': 'Members ({n})',
'team.invite': '+ Invite',
'team.role_viewer': 'Viewer',
'team.role_editor': 'Editor',
'team.role_owner': 'Owner',
'team.remove': 'Remove',
'team.remove_from_team': 'Remove from team',
'team.no_members': 'No members yet',
'team.shared_devices': 'Shared Devices ({n})',
'team.add_device': '+ Add device...',
'team.no_devices': 'No devices shared with this team',
'team.prompt_email': 'Email address to invite:',
'team.prompt_role': 'Role (viewer, editor, or owner):',
'team.toast.invalid_role': 'Invalid role',
'team.toast.invitation_sent': 'Invitation sent',
'team.toast.role_updated': 'Role updated',
'team.toast.member_removed': 'Member removed',
'team.toast.device_added': 'Device added to team',
'team.toast.device_removed': 'Device removed from team',
'team.toast.deleted': 'Team deleted',
// Activity log
'activity.title': 'Activity Log',
'activity.subtitle': 'Audit trail of all actions',
'activity.load_more': 'Load More',
'activity.empty_title': 'No activity yet',
'activity.empty_desc': 'Actions will appear here as you use the system.',
'activity.system': 'System',
'activity.verb_created': 'created',
'activity.verb_updated': 'updated',
'activity.verb_deleted': 'deleted',
'activity.action_paired_device': 'paired a device',
'activity.action_added_remote_content': 'added remote content',
'activity.noun_content': 'content',
'activity.noun_device': 'device',
'activity.noun_playlist_assignment': 'playlist assignment',
'activity.noun_assignment': 'assignment',
'activity.noun_layout': 'layout',
'activity.noun_widget': 'widget',
'activity.noun_schedule': 'schedule',
'activity.noun_video_wall': 'video wall',
'activity.alert_device_offline': 'alert: device went offline',
// Help
'help.title': 'Help Center',
'help.subtitle': 'Quick guides and FAQ',
'help.faq': 'Frequently Asked Questions',
'help.shortcuts': 'Keyboard Shortcuts',
'help.shortcut_esc': 'Reset web player (on player page)',
'help.shortcut_f': 'Toggle fullscreen (web player)',
// Add Display modal (in index.html)
'add_display.title': 'Add Display',
'add_display.intro': 'Enter the 6-digit pairing code shown on the display.',
'add_display.pairing_code': 'Pairing Code',
'add_display.display_name': 'Display Name (optional)',
'add_display.name_placeholder': 'e.g., Lobby TV',
'add_display.need_player': 'Need a player app? Install one to get a pairing code:',
'add_display.android_apk': 'Android APK',
'add_display.web_player': 'Web Player',
'add_display.raspberry_pi': 'Raspberry Pi',
'add_display.windows': 'Windows',
'add_display.smart_tv_note': 'Smart TVs (LG/Samsung): open the built-in browser and navigate to /player',
'add_display.pair_btn': 'Pair Display',
// Workspace switcher (Phase 3 MVP). devices_count is the only count exposed
// today; matching pattern for users/playlists/etc. when those land later.
'switcher.devices_count_one': '1 device',
'switcher.devices_count_other': '{n} devices',
'switcher.no_devices': 'No devices',
};