// ── i18n: locale bundles and t() helper ──────────────────────────────────────
// To add a new language: add an entry to LOCALES below with all keys translated.
// The language code must match a valid BCP 47 tag (used for speech recognition).
// Keys missing in a non-English locale fall back to English automatically.

const LOCALES = {
  en: {
    offline_title: 'Connection lost',
    offline_browser_detail: 'Your browser reports that this device is offline.',
    offline_network_detail: 'Hermes is unreachable from this browser right now.',
    offline_autorefresh: 'I will refresh this page automatically when Hermes is reachable again.',
    offline_check_now: 'Check now',
    offline_checking: 'Checking…',
    offline_stream_waiting: 'Connection lost. Waiting to refresh…',
    _lang: 'en',
    _label: 'English',
    _speech: 'en-US',
    // boot.js
    cancelling: 'Cancelling\u2026',
    cancel_failed: 'Cancel failed: ',
    mic_denied: 'Microphone access denied. Check browser permissions.',
    mic_no_speech: 'No speech detected. Try again.',
    mic_network: 'Speech recognition unavailable.',
    mic_error: 'Voice input error: ',
    // Composer voice buttons (#1488 — distinct labels for dictation vs voice mode)
    voice_dictate: 'Dictate',
    voice_dictate_active: 'Stop dictation',
    voice_mode_toggle: 'Voice mode',
    voice_mode_toggle_active: 'Exit voice mode',
    // Turn-based voice mode (#1333)
    voice_listening: 'Listening…',
    voice_speaking: 'Speaking…',
    voice_thinking: 'Thinking…',
    voice_error: 'Voice not supported in this browser',
    voice_mode_active: 'Voice mode on',
    voice_mode_off: 'Voice mode off',
    session_imported: 'Session imported',
    import_failed: 'Import failed: ',
    import_invalid_json: 'Invalid JSON',
    image_pasted: 'Image pasted: ',
    // messages.js
    edit_message: 'Edit message',
    regenerate: 'Regenerate response',
    copy: 'Copy',
    copied: 'Copied!',
    copy_failed: 'Copy failed',
    selected_text_reply: 'Reply with selection',
    selected_text_reply_title: 'Append selected chat text as quoted context',
    selected_text_reply_appended: 'Selected text added to composer',

    diff_loading: 'Loading diff',
    diff_error: 'Could not load patch file',
    diff_too_large: 'Patch file too large to display inline',
    tree_view: 'Tree',
    raw_view: 'Raw',
    parse_failed_note: 'parse failed',
    you: 'You',
    mcp_servers_title: 'MCP Servers',
    mcp_servers_desc: 'View MCP servers configured in config.yaml.',
    mcp_no_servers: 'No MCP servers configured.',
    mcp_add_server: '+ Add Server',
    mcp_field_name: 'Server Name',
    mcp_transport_label: 'Transport Type',
    mcp_field_command: 'Command',
    mcp_field_args: 'Arguments (comma-separated)',
    mcp_field_url: 'URL',
    mcp_field_timeout: 'Timeout (seconds)',
    mcp_save: 'Save',
    mcp_cancel: 'Cancel',
    mcp_name_required: 'Server name is required.',
    mcp_url_required: 'URL is required for HTTP transport.',
    mcp_command_required: 'Command is required for stdio transport.',
    mcp_saved: 'MCP server saved.',
    mcp_save_failed: 'Failed to save MCP server.',
    mcp_delete_confirm_title: 'Delete MCP Server',
    mcp_delete_confirm_message: 'Delete MCP server "{0}"? This action cannot be undone.',
    mcp_deleted: 'MCP server deleted.',
    mcp_delete_failed: 'Failed to delete MCP server.',
    mcp_load_failed: 'Failed to load MCP servers.',
    mcp_restart_hint: 'Server changes are read-only here for now. Edit config.yaml and restart Hermes for changes to take effect.',
    mcp_toggle_followup: 'Enable/disable controls are intentionally deferred until MCP reload semantics are explicit.',
    mcp_status_active: 'Active',
    mcp_status_configured: 'Configured',
    mcp_status_disabled: 'Disabled',
    mcp_status_invalid_config: 'Invalid config',
    mcp_status_unknown: 'Unknown',
    mcp_tool_count: '{0} tools',
    mcp_enabled_yes: 'Enabled',
    mcp_enabled_no: 'Disabled',
    mcp_tools_title: 'MCP Tools',
    mcp_tools_desc: 'Search known tools across active MCP servers.',
    mcp_tools_search_placeholder: 'Search tools by name, server, or description…',
    mcp_tools_no_tools: 'No MCP tools are available from the active runtime inventory.',
    mcp_tools_no_matches: 'No MCP tools match your search.',
    mcp_tools_load_failed: 'Failed to load MCP tools.',
    mcp_tools_schema_empty: 'No schema parameters.',
    mcp_tools_runtime_note: 'Tool inventory only uses already-known active MCP runtime data; the WebUI does not start or probe servers.',
    mcp_tools_summary_no_matches: (query,total) => `No MCP tools matching “${query}” (${total} total MCP tools).`,
    mcp_tools_summary_none: 'No MCP tools to show.',
    mcp_tools_summary_matching: (query) => ` matching “${query}”`,
    mcp_tools_summary_total_note: (total) => ` (${total} total MCP tools)`,
    mcp_tools_summary_showing: (start,end,filtered,searchNote,totalNote,page,pages) => `Showing ${start}-${end} of ${filtered} MCP tools${searchNote}${totalNote}. Page ${page} of ${pages}.`,
    mcp_tools_page_size_prefix: 'Show',
    mcp_tools_page_size_suffix: 'per page',
    mcp_tools_per_page_aria: 'MCP tools per page',
    mcp_tools_inactive_configured_servers: (servers) => `Configured but inactive in this WebUI runtime: ${servers}.`,
    mcp_tools_pagination_label: 'MCP tools pagination',
    mcp_tools_previous_page: '‹ Prev',
    mcp_tools_previous_page_aria: 'Previous MCP tools page',
    mcp_tools_next_page: 'Next ›',
    mcp_tools_next_page_aria: 'Next MCP tools page',
    // PDF preview (#480)
    pdf_loading: 'Loading PDF {0}…',
    pdf_too_large: 'PDF too large for inline preview',
    pdf_no_pages: 'PDF has no pages',
    pdf_error: 'Failed to render PDF preview',
    pdf_download: 'Download PDF',
    // HTML sandbox preview (#482)
    html_loading: 'Loading HTML preview…',
    html_too_large: 'HTML too large for inline preview',
    html_error: 'Failed to render HTML preview',
    html_open_full: 'Open full page',
    html_sandbox_label: 'HTML Preview (sandboxed)',
    thinking: 'Thinking',
    expand_all: 'Expand all',
    collapse_all: 'Collapse all',
    edit_failed: 'Edit failed: ',
    regen_failed: 'Regenerate failed: ',
    reconnect_active: 'A response is still being generated. Reload when ready?',
    reconnect_finished: 'A response was in progress when you last left. Messages may have updated.',
    // approval card
    approval_heading: 'Approval required',
    approval_desc_prefix: 'Dangerous command detected',
    approval_btn_once: 'Allow once',
    approval_btn_once_title: 'Allow this one command (Enter)',
    approval_btn_session: 'Allow session',
    approval_btn_session_title: 'Allow for this conversation session',
    approval_btn_always: 'Always allow',
    approval_btn_always_title: 'Always allow this command pattern',
    approval_btn_deny: 'Deny',
    approval_btn_deny_title: 'Deny — do not run this command',
    approval_responding: 'Responding\u2026',
    clarify_heading: 'Clarification needed',
    clarify_hint: 'Pick a choice, or type your own answer below.',
    clarify_other: 'Other',
    clarify_send: 'Send',
    clarify_input_placeholder: 'Type your response…',
    clarify_responding: 'Responding\u2026',
    untitled: 'Untitled',
    n_messages: (n) => `${n} messages`,
    load_older_messages: '↑ Scroll up or click to load older messages',
    session_jump_start: 'Start',
    session_jump_start_label: 'Jump to beginning of session',
    session_jump_end: 'End',
    session_jump_end_label: 'Jump to end of session',
    jump_to_question: 'to question',
    jump_to_question_label: 'Jump to the question for this response',
    queued_label: 'Sends after response',
    queued_count: (n) => n === 1 ? '1 queued' : `${n} queued`,
    queued_cancel: 'Cancel queued message',
    model_unavailable: ' (unavailable)',
    model_unavailable_title: 'This model is no longer in your current provider list',
    provider_mismatch_warning: (m,p)=>`"${m}" may not work with your configured provider (${p}). Send anyway, or run \`hermes model\` in your terminal to switch.`,
    provider_mismatch_label: 'Provider mismatch',
    model_not_found_label: 'Model not found',
    model_custom_label: 'Custom model ID',
    model_custom_placeholder: 'e.g. openai/gpt-5.4',
    model_search_placeholder: 'Search models…',
    model_search_no_results: 'No models found',
    model_group_configured: 'Configured',
    ws_search_placeholder: 'Search workspaces…',
    ws_no_results: 'No workspaces found',
    workspace_new_worktree_conversation: 'New conversation in worktree',
    workspace_new_worktree_conversation_meta: 'Create an isolated git worktree for this workspace.',
    workspace_worktree_created: 'Worktree conversation created',
    workspace_worktree_failed: 'Worktree creation failed: ',
    session_worktree_badge: 'Worktree',
    model_scope_advisory: 'Applies to this conversation from your next message.',
    model_scope_toast: 'Applies to this conversation from your next message.',
    // commands.js
    cmd_clear: 'Clear conversation messages',
    cmd_compress: 'Manually compress conversation context (usage: /compress [focus topic])',
    ctx_compress_hint: 'Compress context to free up space →',
    ctx_compress_action: '⚠ Compress now to free context',
    cmd_compact_alias: 'Legacy alias for /compress',
    cmd_model: 'Switch model (e.g. /model gpt-4o)',
    cmd_workspace: 'Switch workspace by name',
    cmd_terminal: 'Open the workspace terminal',
    cmd_new: 'Start a new chat session',
    cmd_usage: 'Toggle token usage display on/off',
    cmd_theme: 'Switch appearance (theme: system/dark/light, skin: default/ares/mono/slate/poseidon/sisyphus/charizard/sienna/catppuccin/nous/geist-contrast)',
    cmd_personality: 'Switch agent personality',
    cmd_skills: 'List available Hermes skills',
    available_commands: 'Available commands:',
    type_slash: 'Type / to see commands',
    conversation_cleared: 'Conversation cleared',
    command_label: 'Command',
    context_compaction_label: 'Context compaction',
    retrieval_context_label: 'Indexed context',
    retrieval_context_preview: 'Earlier messages are stored and retrievable with context tools',
    preserved_task_list_label: 'Preserved task list',
    reference_only_label: 'Reference only',
    model_usage: 'Usage: /model <name>',
    no_model_match: 'No model matching "',
    switched_to: 'Switched to ',
    workspace_usage: 'Usage: /workspace <name>',
    no_workspace_match: 'No workspace matching "',
    switched_workspace: 'Switched to workspace: ',
    workspace_switch_failed: 'Workspace switch failed: ',
    new_session: 'New session created',
    new_session_creating: 'Creating new conversation…',
    compressing: 'Requesting context compression...',
    compress_running_label: 'Compressing',
    compress_complete_label: 'Compression complete',
    auto_compress_label: 'Automatic compression',
    compress_failed_label: 'Compression failed',
    focus_label: 'Focus',
    token_usage_on: 'Token usage on',
    token_usage_off: 'Token usage off',
    usage_cache_hit_detail: 'Cache: {0}% hit ({1} read / {2} write)',
    usage_cached_percent: '{0}% cached',
    theme_usage: 'Usage: /theme ',
    theme_set: 'Theme: ',
    no_active_session: 'No active session',
    cmd_queue: 'Queue a message for the next turn',
    cmd_goal: 'Set or inspect a persistent goal',
    goal_evaluating_progress: 'Evaluating goal progress…',
    goal_working_toward: 'Working toward goal…',
    goal_continuing_toast: 'Continuing toward goal…',
    goal_status_none: 'No active goal. Set one with /goal <text>.',
    goal_status_active: (turns, max_turns, goal) => `⊙ Goal (active, ${turns}/${max_turns} turns): ${goal}`,
    goal_status_paused: (turns, max_turns, reason, goal) => `⏸ Goal (paused, ${turns}/${max_turns}${reason ? `, ${reason}` : ''}): ${goal}`,
    goal_status_done: (turns, max_turns, goal) => `✓ Goal done (${turns}/${max_turns}): ${goal}`,
    goal_set: (turns, goal) => `⊙ Goal set (${turns}-turn budget): ${goal}`,
    goal_paused: (goal) => `⏸ Goal paused: ${goal}`,
    goal_resumed: (goal) => `▶ Goal resumed: ${goal}`,
    goal_cleared: 'Goal cleared.',
    goal_no_goal: 'No active goal.',
    goal_achieved: (reason) => `✓ Goal achieved: ${reason}`,
    goal_paused_budget_exhausted: (turns, max_turns) => `⏸ Goal paused — ${turns}/${max_turns} turns used. Use /goal resume to keep going, or /goal clear to stop.`,
    goal_continuing: (turns, max_turns, reason) => `↻ Continuing toward goal (${turns}/${max_turns}): ${reason}`,
    cmd_interrupt: 'Cancel current turn and send a new message',
    cmd_steer: 'Inject a mid-turn correction without interrupting the agent',
    cmd_queue_no_msg: 'Usage: /queue <message>',
    cmd_queue_not_busy: 'No active task — just send normally',
    cmd_queue_confirm: 'Message queued',
    cmd_interrupt_no_msg: 'Usage: /interrupt <message>',
    cmd_interrupt_confirm: 'Interrupted — sending new message',
    cmd_steer_no_msg: 'Usage: /steer <message>',
    cmd_steer_fallback: 'Steer unavailable — queued for next turn instead',
    cmd_steer_delivered: 'Steer delivered — agent will see it on its next tool result',
    steer_leftover_queued: 'Steer queued for next turn',
    busy_steer_fallback: 'Steer unavailable — queued for next turn',
    busy_interrupt_confirm: 'Interrupted — sending new message',
    settings_label_busy_input_mode: 'Busy input mode',
    settings_desc_busy_input_mode: 'Controls what happens when you send a message while the agent is running. Queue waits; Interrupt cancels and starts fresh; Steer injects a correction mid-turn without interrupting (falls back to queue when agent or stream unavailable).',
    settings_label_fade_text_effect: 'Fade text effect',
    settings_desc_fade_text_effect: 'Fade newly streamed words in while the assistant is responding. Similar to OpenWebUI; off by default for maximum performance.',
    settings_busy_input_mode_queue: 'Queue follow-up',
    settings_busy_input_mode_interrupt: 'Interrupt current turn',
    settings_busy_input_mode_steer: 'Steer (mid-turn correction)',

  slash_skill_badge:'Skill',
  slash_skill_desc:'Invoke this skill',
  cmd_stop:'Stop the current response',
  cmd_title:'Get or set the session title',
  cmd_retry:'Resend the last message',
  cmd_undo:'Remove the last exchange',
  cmd_btw:'Ask a side question (ephemeral)',
  cmd_btw_usage:'/btw <question> — ask a side question using session context',
   cmd_background:'Run a prompt in background',
   cmd_background_usage:'/background <prompt> — run in parallel without blocking',
   cmd_branch:'Fork this conversation into a new session',
   cmd_branch_usage:'/branch [name] — fork conversation (optionally with a name)',
   branch_forked:'Forked into new session',
   branch_failed:'Fork failed: ',
   fork_from_here:'Fork from here',
   forked_from:'Forked from',
   subagent_children:'Subagent sessions',
   btw_asking:'Asking side question...',
  btw_label:'Side question — not in history',
  btw_done:'Side question answered',
  btw_no_answer:'No answer received.',
  btw_failed:'Side question failed: ',
  bg_running:'Running in background...',
  bg_complete:'Background task complete',
  bg_label:'Background result:',
  bg_no_answer:'(no answer)',
  bg_failed:'Background task failed: ',
  undo_exchange:'Undo last exchange',
  cmd_status:'Show session info',
  cmd_voice:'Toggle microphone input',
  stream_stopped:'Response stopped.',
  no_active_task:'No active task to stop.',
  cancel_unavailable:'Cancel not available.',
  retry_failed:'Retry failed: ',
  undo_failed:'Undo failed: ',
  undid_n_messages:'Removed',
  undid_messages_suffix:'message(s).',
  status_heading:'Session Status',
  status_session_id:'Session ID',
  status_title:'Title',
  status_model:'Model',
  status_provider:'Provider',
  status_workspace:'Workspace',
  status_personality:'Personality',
  status_messages:'Messages',
  status_agent_running:'Agent running',
    status_profile: 'Profile',
    status_hermes_home: 'Hermes home',
    status_started: 'Started',
    status_updated: 'Updated',
    status_tokens: 'Tokens',
    status_ephemeral: 'Ephemeral snapshot — not saved to transcript history.',
    status_no_tokens: 'No tokens used',
    status_unknown: 'Unknown',
  status_yes:'Yes',
  status_no:'No',
  status_load_failed:'Failed to load status: ',
  title_current:'Current title',
  title_change_hint:'Use `/title <new name>` to rename.',
  title_set:'Title set to',
  cmd_webui_only_session:'This command is not available for CLI-imported sessions.',
  cmd_voice_use_mic:'Click the mic button in the composer.',
  usage_heading:'Token Usage',
  usage_default_model:'default',
  usage_unknown:'unknown',
  usage_input_tokens:'Input tokens',
  usage_output_tokens:'Output tokens',
  usage_total:'Total tokens',
  usage_estimated_cost:'Estimated cost',
  usage_settings_tip:'Note: cost estimates are approximate.',
  usage_load_failed:'Failed to load usage: ',
    usage_personality_none:'none',
    // Session toolsets (#493)
    session_toolsets:'Session Toolsets',
    session_toolsets_desc:'Restrict available tools for this session (blank = use global config)',
    session_toolsets_global:'Global (default)',
    session_toolsets_custom:'Custom',
    session_toolsets_placeholder:'tool1, tool2, …',
    session_toolsets_apply:'Apply',
    session_toolsets_clear:'Clear (use global)',
    session_toolsets_applied:'Toolsets updated',
    session_toolsets_cleared:'Toolsets cleared — using global config',
    session_toolsets_failed:'Failed to update toolsets: ',
  untitled:'Untitled',
    no_personalities: 'No personalities found (add them to ~/.hermes/personalities/)',
    available_personalities: 'Available personalities:',
    personality_switch_hint: '\n\nUse `/personality <name>` to switch, or `/personality none` to clear.',
    personalities_load_failed: 'Failed to load personalities',
    personality_cleared: 'Personality cleared',
    personality_set: 'Personality: ',
    failed_colon: 'Failed: ',
    // ui.js
    no_workspace: 'No workspace',
    terminal_open_title: 'Open workspace terminal',
    terminal_no_workspace_title: 'Select a workspace to open terminal',
    terminal_title: 'Terminal',
    terminal_clear: 'Clear',
    terminal_copy_output: 'Copy output',
    terminal_restart: 'Restart',
    terminal_collapse: 'Collapse',
    terminal_expand: 'Expand',
    terminal_close: 'Close',
    terminal_input_placeholder: 'Run a command...',
    terminal_start_failed: 'Terminal start failed: ',
    terminal_input_failed: 'Terminal input failed: ',
    terminal_copy_failed: 'Copy failed: ',
    terminal_error: 'Terminal error',
    workspace_empty_no_path: 'No workspace selected. Set a workspace in Settings \u2192 Workspace to browse files.',
    workspace_empty_dir: 'This workspace is empty.',
    workspace_show_hidden_files: 'Show hidden files',
    workspace_show_hidden_files_desc: 'Include .DS_Store, .git, node_modules, and other hidden / system files in the file tree.',
    workspace_hidden_files_visible: 'hidden visible',
    workspace_hidden_files_visible_title: 'Hidden files are visible — click for options',
    workspace_options: 'Workspace options',
    dialog_confirm_title: 'Confirm action',
    dialog_prompt_title: 'Enter a value',
    dialog_confirm_btn: 'Confirm',
    // workspace.js
    unsaved_confirm: 'You have unsaved changes in the preview. Discard and navigate?',
    discard: 'Discard',
    save: 'Save',
    edit: 'Edit',
    clear: 'Clear',
    create: 'Create',
    remove: 'Remove',
    save_title: 'Save changes',
    edit_title: 'Edit this file',
    saved: 'Saved',
    save_failed: 'Save failed: ',
    image_load_failed: 'Could not load image',
    file_open_failed: 'Could not open file',
    downloading: (name) => `Downloading ${name}\u2026`,
    double_click_rename: 'Double-click to rename',
    renamed_to: 'Renamed to ',
    rename_failed: 'Rename failed: ',
    delete_title: 'Delete',
    delete_confirm: (name) => `Delete ${name}?`,
    delete_dir_confirm: (name) => `Delete folder "${name}" and all its contents?`,
    rename_title: 'Rename',
    rename_prompt: 'New name:',
    deleted: 'Deleted ',
    delete_failed: 'Delete failed: ',
    reveal_in_finder: 'Reveal in File Manager',
    reveal_failed: 'Failed to reveal: ',
    copy_file_path: 'Copy file path',
    download_folder: 'Download Folder',
    path_copied: 'File path copied to clipboard',
    path_copy_failed: 'Failed to copy path: ',
    session_rename: 'Rename conversation',
    session_rename_desc: 'Edit the title of this conversation',
    new_file_prompt: 'New file name (e.g. notes.md):',
    project_name_prompt: 'Project name:',
    created: 'Created ',
    create_failed: 'Create failed: ',
    new_folder_prompt: 'New folder name:',
    folder_created: 'Created folder ',
    folder_create_failed: 'Create folder failed: ',
  workspace_auto_create_folder: 'Create folder if it doesn\'t exist',
  folder_add_as_space_btn: 'Add as Space',
  folder_add_as_space_msg: 'Add this folder as a new space in your workspace list?',
  folder_add_as_space_title: 'Add as Space?',
    remove_title: 'Remove',
    empty_dir: '(empty)',
    upload_failed: 'Upload failed: ',
    upload_too_large: (maxMb, fileMb) => `File is too large (${fileMb} MB). Maximum upload size is ${maxMb} MB.`,
    all_uploads_failed: (n) => `All ${n} upload(s) failed`,
    archive_extracted: (n, c) => `Extracted ${n} file(s) from ${c} archive(s)`,
    session_pin: 'Pin conversation',
    session_unpin: 'Unpin conversation',
    session_pin_desc: 'Keep this conversation at the top',
    session_unpin_desc: 'Remove from pinned',
    session_pin_failed: 'Pin failed: ',
    session_move_project: 'Move to project',
    session_move_project_desc_has: 'Change the project for this conversation',
    session_move_project_desc_none: 'Assign a project to this conversation',
    session_archive: 'Archive conversation',
    session_hide_external: 'Hide from list',
    session_restore: 'Restore conversation',
    session_archive_desc: 'Hide this conversation until archived is shown',
    session_archive_worktree_desc: 'Hide this conversation; keep its worktree on disk',
    session_hide_external_desc: 'Hide this imported session from WebUI without deleting the source history.',
    session_restore_desc: 'Bring this conversation back into the main list',
    session_archived: 'Session archived',
    session_archived_worktree: 'Session archived. Worktree remains on disk.',
    session_hidden: 'Session hidden from list',
    session_restored: 'Session restored',
    session_archive_failed: 'Archive failed: ',
    session_duplicate: 'Duplicate conversation',
    session_duplicate_desc: 'Create a copy with the same workspace and model',
    session_duplicated: 'Session duplicated',
    session_duplicate_failed: 'Duplicate failed: ',
    session_stop_response: 'Stop response',
    session_stop_response_desc: 'Cancel the running response for this conversation',
    session_delete: 'Delete conversation',
    session_delete_desc: 'Permanently remove this conversation',
    session_delete_confirm: 'Delete this conversation?',
    session_delete_worktree_desc: 'Delete only the WebUI conversation; keep the worktree on disk',
    session_delete_worktree_confirm: (path) => `Delete this conversation? The worktree at ${path} will remain on disk.`,
    session_deleted: 'Conversation deleted',
    session_deleted_worktree: 'Conversation deleted. Worktree remains on disk.',
    session_worktree_remove: 'Remove worktree',
    session_worktree_remove_desc: (path) => `Delete the git worktree at ${path} from disk`,
    session_worktree_remove_confirm: (path) => `Remove git worktree from disk?\n\nPath: ${path}\n\nThis will delete the entire worktree directory. Session data remains in WebUI.`,
    session_worktree_remove_not_exists: (path) => `The worktree at ${path} no longer exists on disk.`,
    session_worktree_remove_confirm_label: 'Remove',
    session_worktree_removed: 'Worktree removed.',
    session_worktree_remove_failed: 'Failed to remove worktree: ',
    session_worktree_remove_status_failed: 'Failed to read worktree status: ',
    session_worktree_remove_locked_by_stream: 'Cannot remove — an active streaming session is using this worktree.',
    session_worktree_remove_locked_by_terminal: 'Cannot remove — an active terminal session is using this worktree.',
    session_worktree_remove_unsafe_blocked: 'Resolve local changes or unpushed commits before removing this worktree.',
    session_worktree_remove_dirty_warning: 'WARNING: This worktree has uncommitted changes which will be lost.',
    session_worktree_remove_untracked_warning: (count) => `${count} untracked file(s) will be permanently deleted.`,
    session_worktree_remove_ahead_warning: (ahead) => `${ahead} unpushed commit(s) will be lost.`,
    session_select_mode: 'Select',
    session_select_mode_desc: 'Select conversations to batch manage',
    session_select_all: 'Select all',
    session_deselect_all: 'Deselect all',
    session_selected_count: '{0} selected',
    session_batch_archive: 'Archive',
    session_batch_delete: 'Delete',
    session_batch_move: 'Move to project',
    session_batch_delete_confirm: 'Delete {0} conversations?',
    session_batch_archive_confirm: 'Archive {0} conversations?',
    session_batch_delete_worktree_confirm: 'Delete {0} conversations? {1} worktree-backed conversation(s) will leave their worktree directories on disk.',
    session_batch_archive_worktree_confirm: 'Archive {0} conversations? {1} worktree-backed conversation(s) will keep their worktree directories on disk.',
    session_no_selection: 'No conversations selected',
    // settings panel
    settings_heading_title: 'Control Center',
    settings_heading_subtitle: 'Preferences, conversation tools, and system controls.',
    settings_section_conversation_title: 'Conversation',
    settings_section_appearance_title: 'Appearance',
    settings_section_appearance_meta: 'Theme, accent colors, and visual style.',
    settings_section_preferences_title: 'Preferences',
    settings_section_preferences_meta: 'Defaults and UI behavior for Hermes Web UI.',
    settings_section_system_title: 'System',
    settings_section_system_meta: 'Instance version and access controls.',
    settings_check_now: 'Check now',
    settings_checking: 'Checking\u2026',
    settings_up_to_date: 'Up to date \u2713',
    settings_updates_available: '{count} update(s) available',
    settings_updates_disabled: 'Update checks disabled',
    settings_update_check_failed: 'Update check failed',
    settings_label_workspace_panel_open: 'Keep workspace panel open by default',
    settings_desc_workspace_panel_open: 'When enabled, the workspace / file browser panel opens automatically with each new session. You can still close it manually at any time.',
    settings_label_session_jump_buttons: 'Show session jump buttons',
    settings_desc_session_jump_buttons: 'Show floating Start and End buttons while reading long session histories.',

    settings_label_session_endless_scroll: 'Load older messages while scrolling up',

    settings_desc_session_endless_scroll: 'When enabled, older messages load automatically as you scroll upward. When disabled, use the older-messages button.',

    settings_label_tab_visibility: 'Sidebar tabs',
    settings_desc_tab_visibility: 'Choose which tabs appear in the sidebar and rail. Chat and Settings are always visible.',
    open_in_browser: 'Open in browser',
    settings_dropdown_conversation: 'Conversation',
    settings_dropdown_appearance: 'Appearance',
    settings_dropdown_preferences: 'Preferences',
    settings_dropdown_providers: 'Providers',
    settings_dropdown_system: 'System',
    settings_tab_conversation: 'Conversation',
    settings_tab_appearance: 'Appearance',
    settings_tab_preferences: 'Preferences',
    settings_tab_plugins: 'Plugins',
    settings_plugins_title: 'Plugins',
    settings_plugins_meta: 'View installed Hermes plugins and the lifecycle hooks they register. This panel is read-only.',
    settings_plugins_empty: 'No Hermes plugins are currently visible. Install or enable plugins from the Hermes CLI/config to see them here.',
    plugins_unnamed: 'Unnamed plugin',
    plugins_no_description: 'No description provided.',
    plugins_no_hooks: 'No registered lifecycle hooks',
    plugins_registered_hooks: 'Registered hooks',
    plugins_enabled: 'Enabled',
    plugins_disabled: 'Disabled',
    plugins_active_provider: 'Active (provider)',
    plugins_provider_no_hooks: 'Provider plugin — no agent-visibility hooks',
    plugins_load_failed: 'Failed to load plugins: ',
    settings_tab_system: 'System',
    settings_title: 'Settings',
    settings_save_btn: 'Save Settings',
    settings_label_model: 'Default Model',
    settings_desc_model: 'Used for new conversations. Existing conversations keep their selected model.',
    settings_label_send_key: 'Send Key',
    settings_label_theme: 'Theme',
    settings_label_skin: 'Skin',
    settings_label_font_size: 'Font size',
    font_size_small: 'Small',
    font_size_default: 'Default',
    font_size_large: 'Large',
    font_size_xlarge: 'Extra Large',
    settings_autosave_saving: 'Saving…',
    settings_autosave_saved: 'Saved',
    settings_autosave_failed: 'Save failed',
    settings_autosave_retry: 'Retry',
    settings_label_language: 'Language',
    settings_label_quota_chip: 'Show provider quota chip in composer',
    settings_desc_quota_chip: 'Displays an ambient remaining-quota indicator (e.g. OpenRouter credit balance) in the composer footer. Default off. Only visible on wide displays (≥1400px) when enabled, to keep the composer uncluttered on laptop and standard desktop widths.',
    settings_label_hide_suggestions: 'Hide new-chat suggestions',
    settings_desc_hide_suggestions: 'Hide the three default suggestion buttons on the empty new-chat screen to avoid accidental taps.',
    settings_label_token_usage: 'Show token usage',
    settings_label_sidebar_density: 'Sidebar density',
    cmd_reasoning: 'Toggle thinking visibility (show/hide), set effort level, or check current status',
    settings_label_external_sessions: 'Show non-WebUI sessions',
    settings_label_previous_messaging_sessions: 'Show previous messaging sessions',
    settings_label_sync_insights: 'Sync to insights',
    settings_label_check_updates: 'Check for updates',
    settings_label_whats_new_summary: "Summarize What's New with AI",
    settings_label_bot_name: 'Default assistant name',
    settings_label_password: 'Access Password',
    settings_saved: 'Settings saved',
    settings_save_failed: 'Save failed: ',
    settings_load_failed: 'Failed to load settings: ',
    settings_saved_pw: 'Settings saved — password protection enabled and this browser stays signed in',
    settings_saved_pw_updated: 'Settings saved — password updated',
    // login page (used server-side via /api/i18n/login endpoint)
    login_title: 'Sign in',
    login_subtitle: 'Enter your password to continue',
    login_placeholder: 'Password',
    login_btn: 'Sign in',
    login_invalid_pw: 'Invalid password',
    login_conn_failed: 'Connection failed',
    dialog_confirm_title: 'Confirm action',
    dialog_prompt_title: 'Enter a value',
    dialog_confirm_btn: 'Confirm',
    discard: 'Discard',
    clear: 'Clear',
    create: 'Create',
    remove: 'Remove',
    project_name_prompt: 'Project name:',
    // Sidebar & Tabs
    tab_chat: 'Chat',
    tab_tasks: 'Tasks',
    tab_skills: 'Skills',
    tab_memory: 'Memory',
    tab_workspaces: 'Spaces',
    tab_profiles: 'Profiles',
    tab_kanban: 'Kanban',
    kanban_board: 'Board',
    kanban_visible_tasks: '{0} visible tasks',
    kanban_search_tasks: 'Search tasks',
    kanban_all_assignees: 'All assignees',
    kanban_all_tenants: 'All tenants',
    kanban_include_archived: 'Include archived',
    kanban_no_matching_tasks: 'No matching tasks',
    kanban_no_data: 'No Kanban data',
    kanban_work_queue_hint: 'This is the Hermes Agent work queue. Create or triage a task, assign it, move it to Ready, then let the dispatcher claim it.',
    kanban_unavailable: 'Kanban unavailable',
    kanban_read_only: 'Read-only view',
    kanban_empty: 'Empty',
    kanban_task: 'Task',
    kanban_no_description: 'No description',
    kanban_refresh: 'Refresh',
    kanban_status_triage: 'Triage',
    kanban_status_todo: 'Todo',
    kanban_status_ready: 'Ready',
    kanban_status_running: 'Running',
    kanban_status_blocked: 'Blocked',
    kanban_status_done: 'Done',
    kanban_comments_count: 'Comments ({0})',
    kanban_events_count: 'Events ({0})',
    kanban_links: 'Links',
    kanban_parents: 'Parents',
    kanban_children: 'Children',
    kanban_runs_count: 'Runs ({0})',
    kanban_no_comments: 'No comments',
    kanban_no_events: 'No events',
    kanban_no_runs: 'No runs',
    kanban_title: 'Title',
    kanban_description: 'Description',
    kanban_description_placeholder: 'Optional — what needs to happen, acceptance criteria, links',
    kanban_status: 'Status',
    kanban_assignee: 'Assignee',
    kanban_assignee_placeholder: 'Optional — leave blank for any worker',
    kanban_tenant: 'Tenant',
    kanban_tenant_placeholder: 'Optional — project or team slug',
    kanban_priority: 'Priority',
    kanban_priority_hint: 'Higher numbers run first. Default 0.',
    kanban_title_required: 'Title is required.',
    kanban_new_task: 'New task',
    kanban_edit_task: 'Edit task',
    kanban_status_original_hint: 'Actual status: {0}. This dialog only supports Triage/Todo/Ready edits.',
    kanban_run_dispatcher: 'Run dispatcher',
    kanban_run_dispatcher_confirm: 'This will claim Ready tasks on this board and spawn worker subprocesses (one per task, up to 8 per click). Continue?',
    kanban_assignee_profiles_label: 'Hermes profiles',
    kanban_assignee_other_label: 'Other (CLI lanes / removed profiles)',
    kanban_assignee_unassigned: '— Unassigned (won\u2019t auto-run) —',
    kanban_ready_needs_assignee: 'You picked Unassigned + Ready. The dispatcher will skip this task. Submit again to confirm, or pick a profile.',
    kanban_dispatch_preview_prefix: 'Preview:',
    kanban_dispatch_run_prefix: 'Dispatched:',
    kanban_dispatch_spawned: 'spawned',
    kanban_dispatch_promoted: 'promoted',
    kanban_dispatch_reclaimed: 'reclaimed',
    kanban_dispatch_skipped_unassigned: 'skipped (no assignee)',
    kanban_dispatch_skipped_nonspawnable: 'skipped (unknown profile)',
    kanban_dispatch_auto_blocked: 'auto-blocked',
    kanban_dispatch_timed_out: 'timed out',
    kanban_dispatch_crashed: 'crashed',
    kanban_add_comment: 'Add comment',
      kanban_only_mine: 'Only mine',
      kanban_bulk_action: 'Bulk action',
      kanban_nudge_dispatcher: 'Preview dispatcher',
      kanban_stats: 'Stats',
      kanban_worker_log: 'Worker log',
      kanban_block: 'Block',
      kanban_unblock: 'Unblock',
      kanban_back_to_board: 'Back to board',
      kanban_lanes_by_profile: 'Lanes by profile',
      kanban_new_board: 'New board…',
      kanban_rename_board: 'Rename current board…',
      kanban_archive_board: 'Archive current board…',
      kanban_archive_board_confirm: 'Archive board "{name}"? Tasks remain on disk and the board can be restored from kanban/boards/_archived/.',
      kanban_board_archived: 'Board archived',
      kanban_board_name: 'Name',
      kanban_board_slug: 'Slug (lowercase, hyphens)',
      kanban_board_description: 'Description (optional)',
      kanban_board_icon: 'Icon (emoji, optional)',
      kanban_board_color: 'Color (optional)',
      kanban_board_name_required: 'Name is required',
      kanban_board_slug_required: 'Slug is required',
      kanban_card_complete: 'complete',
      kanban_card_archive: 'archive',
      kanban_unassigned: 'unassigned',
    kanban_status_archived: 'Archived',
    tab_todos: 'Todos',
    tab_insights: 'Insights',
    tab_dashboard: 'Hermes Dashboard',
    dashboard_loopback_warning: 'Dashboard is loopback-only on the server. Either browse from the server itself or restart it with --host 0.0.0.0 (insecure).',
    tab_logs: 'Logs',
    tab_settings: 'Settings',
    new_conversation: 'New conversation',
    filter_conversations: 'Filter conversations...',
    session_time_unknown: 'Unknown',
    session_time_minutes_ago: (n) => `${n}m`,
    session_time_hours_ago: (n) => `${n}h`,
    session_time_days_ago: (n) => `${n}d`,
    session_time_last_week: '1w',
    session_time_bucket_today: 'Today',
    session_time_bucket_yesterday: 'Yesterday',
    session_time_bucket_this_week: 'This week',
    session_time_bucket_last_week: 'Last week',
    session_time_bucket_older: 'Older',
    scheduled_jobs: 'Scheduled jobs',
    new_job: 'New job',
    loading: 'Loading...',
    search_skills: 'Search skills...',
    new_skill: 'New skill',
    personal_memory: 'Personal memory',
    current_task_list: 'Current task list',
    // Logs
    logs_title: 'Logs',
    logs_file: 'File',
    logs_tail: 'Tail',
    logs_auto_refresh: 'Auto-refresh (5s)',
    logs_wrap: 'Wrap lines',
    logs_copy_all: 'Copy all',
    logs_empty: 'No log lines yet.',
    logs_loading: 'Loading logs…',
    logs_load_failed: 'Logs failed to load',
    logs_status_idle: 'Choose a log file to view recent lines.',
    logs_no_mtime: 'not written yet',
    logs_truncated_hint: 'Showing the tail of a large log file; older bytes were skipped to keep memory bounded.',
    logs_copied: 'Logs copied',
    logs_severity: 'Severity',
    logs_severity_all: 'All',
    logs_severity_errors: 'Errors',
    logs_severity_warnings: 'Warnings+',
    logs_filter_active: 'shown (filter active)',

    // Insights
    insights_title: 'Usage Analytics',
    insights_sessions: 'Sessions',
    insights_messages: 'Messages',
    insights_tokens: 'Tokens',
    insights_cost: 'Estimated Cost',
    insights_no_cost: 'N/A',
    insights_models: 'Models',
    insights_activity_by_day: 'Activity by Day',
    insights_activity_by_hour: 'Activity by Hour',
    insights_peak_hour: 'Peak: {hour}',
    insights_token_breakdown: 'Token Breakdown',
    insights_input_tokens: 'Input',
    insights_output_tokens: 'Output',
    insights_total: 'Total',
    insights_daily_tokens: 'Daily Tokens',
    insights_model_name: 'Model',
    insights_model_sessions: 'Sessions',
    insights_model_tokens: 'Tokens',
    insights_model_cost: 'Cost',
    insights_model_share: 'Share',
    insights_no_usage_data: 'No usage data yet',
    insights_footer: 'Showing data from the last {days} days',
    workspace_desc: 'Add and switch workspaces for your sessions.',
    session_meta_messages: (n) => `${n} msg${n === 1 ? '' : 's'}`,
    session_meta_children: (n) => `${n} child${n === 1 ? '' : 'ren'}`,
    // Softened label: avoids exposing the technical internal term
    // 'segment' in the default visible badge. User-facing copy remains
    // translatable for locales that prefer a different wording. (#2155)
    session_meta_segments: (n) => `${n} prior turn${n === 1 ? '' : 's'}`,
    session_lineage_segment_untitled: 'Untitled segment',
    session_lineage_segment_open: 'Open lineage segment',
    new_profile: 'New profile',
    transcript: 'Transcript',
    download_transcript: 'Download as Markdown',
    import: 'Import',
    export_session_json: 'JSON',
    export_session_json_tooltip: 'Export full session as JSON',
    import_session_json_tooltip: 'Import session from JSON',
    clear_conversation_btn_tooltip: 'Clear all messages in this conversation',
    // Settings detail
    settings_label_rtl: 'Right-to-left chat layout',
    settings_desc_rtl: 'Flips alignment of chat messages and the composer input for languages like Arabic or Hebrew. Affects only the chat area — sidebar and other panels stay left-to-right.',
    settings_label_sound: 'Notification sound',
    settings_desc_sound: 'Play a sound when the assistant finishes a response.',
    // TTS (#499)
    tts_listen: 'Listen',
    tts_not_supported: 'Speech synthesis not supported in this browser.',
    settings_label_tts: 'Text-to-Speech for responses',
    settings_desc_tts: "Show a speaker button on each assistant message to read it aloud using your browser's speech synthesis.",
    settings_label_tts_auto_read: 'Auto-read responses aloud',
    settings_desc_tts_auto_read: 'Automatically speak each new assistant response when it finishes. Pauses when you start typing.',
    // Composer voice-mode pref (#1488)
    settings_label_voice_mode: 'Hands-free voice mode button',
    settings_desc_voice_mode: 'Show the voice-mode button (audio waveform) next to the dictation mic. Lets you speak naturally — Hermes auto-sends after a pause and reads replies aloud. Requires a browser that supports both speech recognition and TTS.',
    settings_label_tts_voice: 'Voice',
    settings_desc_tts_voice: "Preferred voice. Populated from your browser's available voices.",
    settings_label_tts_rate: 'Speech rate',
    settings_label_tts_pitch: 'Speech pitch',
    settings_label_notifications: 'Browser notifications',
    settings_desc_notifications: 'Show a system notification when a response completes while the app is in the background.',
    settings_desc_token_usage: 'Displays input/output token count below each assistant reply. Also toggled with /usage.',
    settings_label_api_redact: 'Redact sensitive data in API responses',
    settings_desc_api_redact: 'Self-hosted users can disable for transparency (not recommended for shared instances).',
    settings_sidebar_density_compact: 'Compact',
    settings_sidebar_density_detailed: 'Detailed',
    settings_desc_sidebar_density: 'Controls how much metadata the session list shows in the left sidebar.',
    settings_label_auto_title_refresh: 'Adaptive title refresh',
    settings_auto_title_refresh_off: 'Off',
    settings_auto_title_refresh_5: 'Every 5 exchanges',
    settings_auto_title_refresh_10: 'Every 10 exchanges',
    settings_auto_title_refresh_20: 'Every 20 exchanges',
    settings_desc_auto_title_refresh: 'Automatically re-generates the session title based on the latest exchange, keeping it relevant as the conversation evolves. Requires an LLM title generation model to be configured.',
    settings_desc_external_sessions: 'Show conversations from CLI, Telegram, Discord, Slack, and other channels in the session list. Click to import and continue.',
    settings_desc_previous_messaging_sessions: 'Show older Discord, Telegram, Slack, and Weixin sessions that were replaced by reset or compression.',
    settings_desc_sync_insights: 'Mirrors WebUI token usage to state.db so hermes /insights includes browser session data. Off by default.',
    settings_desc_check_updates: 'Show a banner when newer versions of the WebUI or Agent are available. Runs a background git fetch periodically.',
    settings_desc_whats_new_summary: "Changes the What's New action from opening the raw diff first to generating a short, human-readable summary. The regular diff comparison stays available after the summary.",
    settings_desc_bot_name: 'Used for the default profile only. Other profiles use their own profile names.',
    settings_desc_password: 'Enter a new password to set or change it. Leave blank to keep current setting.',
    password_placeholder: 'Enter new password…',
    password_env_var_locked: 'The HERMES_WEBUI_PASSWORD environment variable is currently set and takes precedence. Unset it and restart the server to manage the password from here.',
    password_env_var_locked_placeholder: 'Locked: HERMES_WEBUI_PASSWORD env var is set',
    disable_auth: 'Disable Auth',
    sign_out: 'Sign Out',
    // Providers panel
    providers_tab_title: 'Providers',
    providers_section_title: 'Providers',
    providers_section_meta: 'Manage API keys for AI providers. Changes take effect immediately.',
    providers_status_configured: 'API key configured',
    providers_status_not_configured: 'No API key',
    providers_status_oauth: 'OAuth',
    providers_status_api_key: 'API key',
    providers_status_not_configured_label: 'Not configured',
    providers_oauth_hint: 'Authenticated via OAuth. No API key needed.',
    providers_oauth_config_yaml_hint: 'Token configured via config.yaml. To update, edit the providers section in your config.yaml or run hermes auth.',
    providers_oauth_not_configured_hint: 'Not authenticated. Run hermes auth in the terminal to configure this provider.',
    providers_save: 'Save',
    providers_remove: 'Remove',
    providers_saving: 'Saving…',
    providers_removing: 'Removing…',
    providers_enter_key: 'Please enter an API key',
    providers_empty: 'No configurable providers found.',
    providers_key_updated: 'API key saved',
    providers_key_removed: 'API key removed',
    providers_key_placeholder_new: 'sk-...',
    providers_key_placeholder_replace: 'Enter new key to replace…',
    provider_quota_title: 'Active provider quota',
    provider_quota_active_provider: 'Active provider',
    provider_quota_last_checked_after_refresh: 'Last checked after refresh',
    provider_quota_last_checked: 'Last checked {0}',
    provider_quota_refresh_usage: 'Refresh usage',
    provider_quota_refreshing: 'Refreshing...',
    provider_quota_refresh_title: 'Refresh provider usage limits now',
    provider_quota_refresh_succeeded: 'Provider usage refreshed',
    provider_quota_refresh_failed: 'Provider usage refresh failed',
    provider_quota_session_limit: '5-hour limit',
    provider_quota_weekly_limit: 'Weekly limit',
    provider_quota_window_fallback: 'Window',
    provider_quota_metric_remaining: 'Remaining',
    provider_quota_metric_used: 'Used',
    provider_quota_metric_limit: 'Limit',
    provider_quota_status_available: 'available',
    provider_quota_status_exhausted: 'exhausted',
    provider_quota_status_unavailable: 'unavailable',
    provider_quota_status_failed: 'failed',
    provider_quota_status_checked: 'checked',
    provider_quota_status_no_key: 'no key',
    provider_quota_status_invalid_key: 'invalid key',
    provider_quota_status_unsupported: 'unsupported',
    provider_quota_used_meta: '{0} used',
    provider_quota_resets_meta: 'resets {0}',
    provider_quota_credential_pool: 'Credential pool',
    provider_quota_credential_label: 'Credential {0}',
    provider_quota_pool_plans: 'Plans: {0}',
    provider_quota_pool_no_windows: 'No account-limit windows reported.',
    provider_quota_account_limits_loaded: 'Account limits loaded.',
    provider_quota_unavailable: 'Quota status unavailable',
    provider_quota_retry_after: 'Retry after {0}',
    provider_quota_pool_summary_available: '{0}/{1} available',
    provider_quota_pool_summary_exhausted: '{0} exhausted',
    provider_quota_pool_summary_failed: '{0} failed',
    provider_quota_pool_summary_checked: '{0} checked',
    cancel: 'Cancel',
    create_job: 'Create job',
    save_skill: 'Save skill',
    editing: 'Editing',
    // Empty state
    empty_title: 'What can I help with?',
    empty_subtitle: 'Ask anything, run commands, explore files, or manage your scheduled tasks.',
    suggest_files: 'What files are in this workspace?',
    suggest_schedule: "What's on my schedule today?",
    suggest_plan: 'Help me plan a small project.',
    // onboarding
    onboarding_badge: 'FIRST RUN',
    onboarding_title: 'Welcome to Hermes Web UI',
    onboarding_lead: 'A quick guided setup will verify Hermes, save a real provider configuration, choose a workspace and model, and optionally protect the app with a password.',
    onboarding_back: 'Back',
    onboarding_continue: 'Continue',
    onboarding_skip: 'Skip setup',
    onboarding_skipped: 'Setup skipped — using existing config.',
    onboarding_open: 'Open Hermes',
    onboarding_step_system_title: 'System check',
    onboarding_step_system_desc: 'Verify Hermes Agent and config visibility.',
    onboarding_step_setup_title: 'Provider setup',
    onboarding_step_setup_desc: 'Save the minimum Hermes provider config.',
    onboarding_step_workspace_title: 'Workspace + model',
    onboarding_step_workspace_desc: 'Pick defaults for new sessions and chat.',
    onboarding_step_password_title: 'Optional password',
    onboarding_step_password_desc: 'Protect the Web UI before sharing it.',
    onboarding_step_finish_title: 'Finish',
    onboarding_step_finish_desc: 'Review and enter the app.',
    onboarding_notice_system_ready: 'Hermes Agent looks reachable from the Web UI.',
    onboarding_notice_system_unavailable: 'Hermes Agent is not fully available yet. Bootstrap can install it, but provider setup may still require a terminal.',
    onboarding_check_agent: 'Hermes Agent',
    onboarding_check_agent_ready: 'Detected and importable',
    onboarding_check_agent_missing: 'Missing or partially importable',
    onboarding_check_password: 'Password',
    onboarding_check_password_enabled: 'Already enabled',
    onboarding_check_password_disabled: 'Not enabled yet',
    onboarding_check_provider: 'Provider config',
    onboarding_check_provider_ready: 'Ready to chat',
    onboarding_check_provider_partial: 'Saved but incomplete',
    onboarding_check_provider_pending: 'Needs verification',
    onboarding_config_file: 'Config file:',
    onboarding_env_file: '.env file:',
    onboarding_unknown: 'Unknown',
    onboarding_current_provider: 'Current setup:',
    onboarding_missing_imports: 'Missing imports:',
    onboarding_notice_setup_required: 'Choose a simple provider path here. Advanced OAuth flows still belong in the Hermes CLI for now.',
    onboarding_notice_setup_already_ready: 'A working Hermes provider setup is already detected. You can keep it or replace it here.',
    onboarding_oauth_provider_ready_title: 'Provider already authenticated',
    onboarding_oauth_provider_ready_body: 'This instance is configured to use an OAuth provider (<strong>{provider}</strong>) that was set up via the Hermes CLI. No API key is needed here — click Continue to finish setup.',
    onboarding_oauth_provider_not_ready_title: 'OAuth provider not yet authenticated',
    onboarding_oauth_provider_not_ready_body: 'This instance is configured to use <strong>{provider}</strong>, which uses OAuth rather than an API key. Run <code>hermes auth</code> or <code>hermes model</code> in a terminal to authenticate, then reload the Web UI.',
    onboarding_oauth_switch_hint: 'Or choose a different provider below to switch to an API-key setup:',
    oauth_login_codex: 'Login with Codex (ChatGPT)',
    oauth_codex_step1: 'Step 1: Visit this URL and enter the code',
    oauth_codex_step2: 'Step 2: Enter this code on the page',
    oauth_codex_polling: 'Waiting for authorization...',
    oauth_codex_success: 'Codex OAuth login successful!',
    oauth_codex_error: 'OAuth login failed',
    oauth_codex_expired: 'Code expired, please try again',
    onboarding_notice_workspace: 'These values reuse the same settings APIs as the normal app.',
    onboarding_workspace_label: 'Workspace',
    onboarding_workspace_or_path: 'Or enter a workspace path',
    onboarding_workspace_placeholder: '/home/you/workspace',
    onboarding_provider_label: 'Setup mode',
    onboarding_quick_setup_badge: 'quick setup',
    provider_category_easy_start: 'Easy start',
    provider_category_self_hosted: 'Open / self-hosted',
    provider_category_specialized: 'Specialized',
    onboarding_api_key_label: 'API key',
    onboarding_api_key_placeholder: 'Leave blank to keep an existing saved key',
    onboarding_api_key_label_optional: 'API key (optional)',
    onboarding_api_key_placeholder_optional: 'Leave blank for keyless servers',
    onboarding_api_key_help_keyless: 'Most LM Studio / Ollama / vLLM installs run keyless — leave this blank if your server doesn\'t require authentication. Use the Test connection button to verify.',
    onboarding_api_key_help_prefix: 'Saved as a secret in your Hermes .env file using',
    onboarding_base_url_label: 'Base URL',
    onboarding_base_url_placeholder: 'https://your-endpoint.example/v1',
    onboarding_base_url_help: 'Use this for OpenAI-compatible routers, self-hosted servers, LiteLLM, Ollama, LM Studio, vLLM, or similar endpoints.',
    onboarding_model_label: 'Default model',
    onboarding_workspace_help: 'Pick the model Hermes should use for new chats after setup completes.',
    onboarding_custom_model_placeholder: 'your-model-name',
    onboarding_custom_model_help: 'For custom endpoints, enter the exact model ID your server expects.',
    onboarding_notice_password_enabled: 'A password is already configured. Enter a new one only if you want to replace it.',
    onboarding_notice_password_recommended: 'Optional but recommended if you will expose the UI beyond localhost.',
    onboarding_password_label: 'Password (optional)',
    onboarding_password_placeholder: 'Leave blank to skip',
    onboarding_password_help: 'Passwords are stored through the existing settings API and hashed server-side.',
    onboarding_notice_finish: 'You can reopen Settings later to change any of this.',
    onboarding_not_set: 'Not set',
    onboarding_password_will_enable: 'Will be enabled',
    onboarding_password_will_replace: 'Will be replaced',
    onboarding_password_keep_existing: 'Keep current password',
    onboarding_password_remains_disabled: 'Will remain disabled',
    onboarding_password_skipped: 'Skipped for now',
    onboarding_finish_help: 'Finishing stores <code>onboarding_completed</code> in settings and drops you into the normal app.',
    onboarding_error_choose_workspace: 'Choose a workspace before continuing.',
    onboarding_error_choose_model: 'Choose a model before continuing.',
    onboarding_error_provider_required: 'Choose a setup mode before continuing.',
    onboarding_error_base_url_required: 'Base URL is required for custom endpoints.',
    onboarding_probe_test_button: 'Test connection',
    onboarding_probe_probing: 'Testing connection…',
    onboarding_probe_ok: 'Connected. {n} model(s) available.',
    onboarding_probe_error_generic: 'Could not reach the configured base URL.',
    onboarding_probe_error_invalid_url: 'Base URL must start with http:// or https://.',
    onboarding_probe_error_dns: 'Could not resolve the host. Check the URL or use the host\'s IP address.',
    onboarding_probe_error_connect_refused: 'Connection refused — the server may not be running on that address. From inside Docker, try the host IP instead of localhost.',
    onboarding_probe_error_timeout: 'The endpoint did not respond in time. Check that the server is running and the URL is correct.',
    onboarding_probe_error_http_4xx: 'The endpoint returned a client error. Check authentication and the URL path (typically ends in /v1).',
    onboarding_probe_error_http_5xx: 'The endpoint returned a server error. Check the LM Studio / Ollama server logs.',
    onboarding_probe_error_parse: 'The endpoint did not return a model list in the expected shape. Verify the URL points to the OpenAI-compatible API root.',
    onboarding_probe_error_unreachable: 'Could not reach the configured base URL.',
    onboarding_error_probe_failed: 'Could not validate the configured base URL.',
    onboarding_error_workspace_required: 'Workspace is required.',
    onboarding_error_model_required: 'Model is required.',
    onboarding_complete: 'Onboarding complete',

    // panel/runtime i18n
    error_prefix: 'Error: ',
    not_available: 'N/A',
    never: 'never',
    add: 'Add',
    add_failed: 'Add failed: ',
    remove_failed: 'Remove failed: ',
    switch_failed: 'Switch failed: ',
    name_required: 'Name is required',
    content_required: 'Content is required',
    view: 'View',
    dismiss: 'Dismiss',
    disable: 'Disable',
    cron_no_jobs: 'No scheduled jobs found.',
    cron_status_off: 'off',
    cron_status_paused: 'paused',
    cron_status_error: 'error',
    cron_status_active: 'active',
    cron_status_running: 'running\u2026',
    cron_status_needs_attention: 'needs attention',
    cron_attention_desc: 'This recurring job has no next run time. The scheduler may have failed to compute its next run.',
    cron_attention_croniter_hint: 'The Gateway runtime may be missing the croniter package. Restart the Gateway with cron support, then resume this job.',
    cron_attention_resume: 'Resume and recalculate',
    cron_jobs_project: 'Cron Jobs',
    cron_attention_run_once: 'Run once now',
    cron_attention_copy_diagnostics: 'Copy diagnostics',
    cron_diagnostics_copied: 'Cron diagnostics copied',
    cron_next: 'Next',
    cron_last: 'Last',
    cron_run_now: 'Run now',
    cron_pause: 'Pause',
    cron_resume: 'Resume',
    cron_job_name_placeholder: 'Job name',
    cron_schedule_placeholder: 'Schedule',
    cron_prompt_placeholder: 'Prompt',
    cron_last_output: 'Last output',
    cron_expand_prompt: 'Expand prompt',
    cron_collapse_prompt: 'Collapse prompt',
    cron_expand_output: 'Expand output',
    cron_collapse_output: 'Collapse output',
    cron_all_runs: 'All runs',
    cron_hide_runs: 'Hide runs',
    cron_no_runs_yet: '(no runs yet)',
    cron_schedule_required_example: 'Schedule is required (e.g. "0 9 * * *" or "every 1h")',
    cron_schedule_required: 'Schedule is required',
    cron_prompt_required: 'Prompt is required',
    cron_job_created: 'Job created',
    cron_duplicate: 'Duplicate',
    cron_duplicated: 'Job duplicated (paused)',
    cron_job_triggered: 'Job triggered',
    cron_job_paused: 'Job paused',
    cron_job_resumed: 'Job resumed',
    cron_job_updated: 'Job updated',
    cron_delete_confirm_title: 'Delete cron job',
    cron_delete_confirm_message: 'This cannot be undone.',
    cron_job_deleted: 'Job deleted',
    cron_completion_status: (name, status) => `Cron "${name}" ${status}`,
    status_failed: 'failed',
    status_completed: 'completed',
    todos_no_active: 'No active task list in this session.',
    clear_conversation_title: 'Clear conversation',
    clear_conversation_message: 'Clear all messages? This cannot be undone.',
    clear_failed: 'Clear failed: ',
    skills_no_match: 'No skills match.',
    linked_files: 'Linked Files',
    skill_load_failed: 'Could not load skill: ',
    skill_file_load_failed: 'Could not load file: ',
    skill_name_required: 'Skill name is required',
    skill_updated: 'Skill updated',
    skill_created: 'Skill created',
    skill_deleted: 'Skill deleted',
    skill_delete_confirm: 'Delete skill "{0}"?',
    skills_empty_title: 'Select a skill',
    skills_empty_sub: 'Pick a skill from the sidebar to view its contents, or create a new one.',
    skills_edit: 'Edit',
    skills_delete: 'Delete',
    skills_back_to: 'Back to {0}',
    tasks_empty_title: 'Select a scheduled job',
    tasks_empty_sub: 'Pick a job from the sidebar to view its details and runs, or create a new one.',
    workspaces_empty_title: 'Select a space',
    workspaces_empty_sub: 'Pick a space from the sidebar to view its files and settings, or add a new one.',
    profiles_empty_title: 'Select a profile',
    profiles_empty_sub: 'Pick an agent profile from the sidebar to view and edit its settings, or create a new one.',
    memory_notes_label: 'memory (notes)',
    memory_saved: 'Memory saved',
    my_notes: 'My Notes',
    user_profile: 'User Profile',
    no_notes_yet: 'No notes yet.',
    no_profile_yet: 'No profile yet.',
    agent_soul: 'Agent Soul',
    no_soul_yet: 'No soul defined yet.',
    workspace_choose_path: 'Choose workspace path',
    workspace_choose_path_meta: 'Add a validated path and switch this conversation',
    workspace_manage: 'Manage workspaces',
    workspace_manage_meta: 'Open the Spaces panel',
    workspace_use_title: 'Use in current session',
    workspace_use: 'Use',
    workspace_add_path_placeholder: 'Add workspace path (e.g. /home/user/my-project)',
    workspace_paths_validated_hint: 'Paths are validated as existing directories before saving.',

    workspace_drag_hint: 'Drag to reorder',
    workspace_reorder_failed: 'Reorder failed',
    workspace_added: 'Workspace added',
    workspace_renamed: 'Workspace renamed',
    workspace_remove_confirm_title: 'Remove workspace',
    workspace_remove_confirm_message: (path) => `Remove "${path}"?`,
    workspace_removed: 'Workspace removed',
    workspace_switch_prompt_title: 'Switch workspace',
    workspace_switch_prompt_message: 'Enter an absolute workspace path to add and switch this conversation to.',
    workspace_switch_prompt_confirm: 'Switch',
    workspace_switch_prompt_placeholder: '/Users/you/project',
    workspace_not_added: 'Workspace was not added',
    workspace_already_saved: 'Workspace already saved — choose it from the list',
    workspace_busy_switch: 'Cannot switch workspace while agent is running',
    discard_file_edits_title: 'Discard file edits?',
    discard_file_edits_message: 'Switching workspaces will discard unsaved file edits in the preview.',
    workspace_switched_to: (name) => `Switched to ${name}`,
    profiles_no_profiles: 'No profiles found.',
    profile_api_keys_configured: 'API keys configured',
    profile_gateway_running: 'Gateway running',
    profile_gateway_stopped: 'Gateway stopped',
    profile_active: 'ACTIVE',
    profile_no_configuration: 'No configuration',
    profile_skill_count: (count) => `${count} skill${count === 1 ? '' : 's'}`,
    profile_use: 'Use',
    profile_switch_title: 'Switch to this profile',
    profile_delete_title: 'Delete this profile',
    profile_default_label: '(default)',
    profile_name_placeholder: 'Profile name (lowercase, a-z 0-9 hyphens)',
    profile_clone_label: 'Clone config from active profile',
    profile_model_label: 'Model / provider',
    profile_model_hint: 'Choose from configured providers and models for this new profile.',
    profile_model_use_default: 'Use active profile default',
    profile_base_url_placeholder: 'Base URL (optional, e.g. http://localhost:11434)',
    profile_api_key_placeholder: 'API key (optional)',
    manage_profiles: 'Manage profiles',
    profiles_load_failed: 'Failed to load profiles',
    profile_switched_new_conversation: (name) => `Switched to profile: ${name} — new conversation started`,
    profile_switched: (name) => `Switched to profile: ${name}`,
    profile_name_rule: 'Lowercase letters, numbers, hyphens, underscores only',
    profile_base_url_rule: 'Base URL must start with http:// or https://',
    profile_created: (name) => `Profile created: ${name}`,
    profile_delete_confirm_title: (name) => `Delete profile "${name}"?`,
    profile_delete_confirm_message: 'All sessions, config, skills, and memory for this profile will be permanently deleted. This cannot be undone.',
    profile_deleted: (name) => `Profile deleted: ${name}`,
    active_conversation_none: 'No active conversation selected.',
    active_conversation_meta: (title, count) => `${title} · ${count} message${count === 1 ? '' : 's'}`,
    settings_unsaved_changes: 'You have unsaved changes.',
    sign_out_failed: 'Sign out failed: ',
    disable_auth_confirm_title: 'Disable password protection',
    disable_auth_confirm_message: 'Anyone will be able to access this instance.',
    auth_disabled: 'Auth disabled — password protection removed',
    disable_auth_failed: 'Failed to disable auth: ',
    bg_error_single: (title) => `"${title}" has encountered an error`,
    bg_error_multi: (count) => `${count} sessions have encountered an error`,
    // skill form
    skill_name: 'Name',
    skill_category: 'Category',
    skill_category_placeholder: 'Optional, e.g. devops',
    skill_content: 'SKILL.md content',
    skill_content_placeholder: 'YAML frontmatter + markdown body',
    skill_rename_not_supported: 'Renaming a skill is not supported. Create a new skill and delete the old one to rename.',
    skill_metadata: 'Metadata',
    // cron form
    cron_name_label: 'Name',
    cron_name_placeholder: 'Optional',
    cron_schedule_label: 'Schedule',
    cron_schedule_hint: "Use 'every 1h' or a cron expression for recurring jobs. Bare durations like '30m' run once.",
    cron_schedule_once_warning: "Duration forms like '30m' run once and are removed after running. Use 'every 30m' to keep a recurring job.",
    cron_prompt_label: 'Prompt',
    cron_deliver_label: 'Deliver output to',
    cron_deliver_local: 'Local (save output only)',
    cron_profile_label: 'Profile',
    cron_profile_server_default: 'server default',
    cron_profile_server_default_hint: 'Uses the WebUI server default profile at run time. Existing jobs without a profile keep this legacy behavior.',
    cron_toast_notifications_label: 'Completion toasts',
    cron_toast_notifications_hint: 'Show a toast when this cron finishes. The Tasks badge and new-run marker still update when this is off.',
    cron_toast_notifications_enabled: 'Enabled',
    cron_toast_notifications_disabled: 'Disabled',
    cron_skills_label: 'Skills',
    cron_skills_placeholder: 'Add skills (optional)…',
    cron_skills_edit_hint: 'Skill list is not editable after creation.',
    // workspace form
    workspace_name_label: 'Name',
    workspace_name_placeholder: 'Optional friendly name',
    workspace_path_label: 'Path',
    workspace_path_required: 'Path is required',
    workspace_path_readonly: 'Path cannot be changed. Rename only.',
    workspace_new_title: 'New space',
    // profile form
    profile_name_label: 'Name',
    profile_base_url_label: 'Base URL',
    profile_api_key_label: 'API key',
    cmd_yolo: 'Toggle YOLO mode (skip approvals)',
    yolo_no_session: 'No active session',
    yolo_enabled: '⚡ YOLO mode ON — approvals skipped this session',
    yolo_disabled: 'YOLO mode OFF',
    yolo_pill_label: 'YOLO',
    yolo_pill_title_active: 'YOLO mode active — click to disable',
    approval_skip_all: '⚡ Skip all this session',
    approval_skip_all_title: 'Skip all approval prompts for this session',
    // composer action tooltips
    composer_send: 'Send message',
    composer_queue: 'Queue message',
    composer_interrupt: 'Interrupt and send',
    composer_steer: 'Steer current response',
    composer_stop: 'Stop generation',
    composer_disabled_clarify: 'Respond to the clarification request',
    composer_disabled_compression: 'Waiting for compression to finish',
    composer_disabled_empty: 'Type a message to send',
    composer_mobile_workspace: 'Workspace',
    composer_mobile_model: 'Model',
    composer_mobile_reasoning: 'Reasoning',
    composer_mobile_context: 'Context',
    media_audio_label: 'Audio',
    media_svg_label: 'Diagram',
    media_video_label: 'Video',
    csv_loading: 'Loading CSV',
    csv_too_large: 'CSV file too large for inline rendering',
    csv_no_data: 'CSV file has insufficient data to render as table',
    csv_error: 'Failed to load CSV file',
    csv_header_note: 'First row shown as table header',
    excalidraw_loading: 'Loading diagram',
    excalidraw_too_large: 'Excalidraw file too large for inline rendering',
    excalidraw_invalid: 'Invalid Excalidraw file format',
    excalidraw_error: 'Failed to load Excalidraw file',
    excalidraw_label: 'Diagram',
    excalidraw_download: 'Download',
    excalidraw_empty: 'Empty diagram',
    excalidraw_render_error: 'Failed to render diagram',
    excalidraw_simplified: 'Simplified SVG preview — not pixel-identical to Excalidraw canvas',
    // ── Checkpoints / Rollback ──
    checkpoint_title: 'Checkpoints',
    checkpoint_empty: 'No checkpoints found for this workspace.',
    checkpoint_loading: 'Loading checkpoints…',
    checkpoint_error: 'Failed to load checkpoints',
    checkpoint_date: 'Date',
    checkpoint_message: 'Message',
    checkpoint_files: 'Files',
    checkpoint_view_diff: 'View diff',
    checkpoint_restore: 'Restore',
    checkpoint_restore_confirm_title: 'Restore checkpoint?',
    checkpoint_restore_confirm_message: (ckpt) => `Restore workspace to checkpoint "${ckpt}"? This will overwrite files with the saved versions. Files added after this checkpoint will not be deleted.`,
    checkpoint_restored: 'Checkpoint restored',
    checkpoint_diff_title: 'Changes in checkpoint',
    checkpoint_diff_no_changes: 'No differences found between this checkpoint and the current workspace.',
    checkpoint_diff_files_changed: (n) => `${n} file${n === 1 ? '' : 's'} changed`,
  },

  it: {
    offline_title: 'Connessione persa',
    offline_browser_detail: 'Il browser segnala che questo dispositivo è offline.',
    offline_network_detail: 'Hermes non è raggiungibile da questo browser al momento.',
    offline_autorefresh: 'Aggiornerò automaticamente la pagina quando Hermes sarà di nuovo raggiungibile.',
    offline_check_now: 'Verifica ora',
    offline_checking: 'Verifica in corso…',
    offline_stream_waiting: 'Connessione persa. In attesa di aggiornare…',
    _lang: 'it',
    _label: 'Italiano',
    _speech: 'it-IT',
    // boot.js
    cancelling: 'Annullamento\u2026',
    cancel_failed: 'Annullamento fallito: ',
    mic_denied: 'Accesso al microfono negato. Controlla i permessi del browser.',
    mic_no_speech: 'Nessuna voce rilevata. Riprova.',
    mic_network: 'Riconoscimento vocale non disponibile.',
    mic_error: 'Errore input vocale: ',
    // Composer voice buttons (#1488 — distinct labels for dictation vs voice mode)
    voice_dictate: 'Detta',
    voice_dictate_active: 'Interrompi dettatura',
    voice_mode_toggle: 'Modalità vocale',
    voice_mode_toggle_active: 'Esci dalla modalità vocale',
    // Turn-based voice mode (#1333)
    voice_listening: 'In ascolto…',
    voice_speaking: 'Sto parlando…',
    voice_thinking: 'Pensando…',
    voice_error: 'Voce non supportata in questo browser',
    voice_mode_active: 'Modalità vocale attiva',
    voice_mode_off: 'Modalità vocale disattiva',
    session_imported: 'Sessione importata',
    import_failed: 'Importazione fallita: ',
    import_invalid_json: 'JSON non valido',
    image_pasted: 'Immagine incollata: ',
    // messages.js
    edit_message: 'Modifica messaggio',
    regenerate: 'Rigenera risposta',
    copy: 'Copia',
    copied: 'Copiato!',
    copy_failed: 'Copia fallita',
    selected_text_reply: 'Rispondi con selezione',
    selected_text_reply_title: 'Aggiungi il testo della chat selezionato come contesto citato',
    selected_text_reply_appended: 'Testo selezionato aggiunto al compositore',

    diff_loading: 'Caricamento diff',
    diff_error: 'Impossibile caricare il file patch',
    diff_too_large: 'File patch troppo grande per la visualizzazione inline',
    tree_view: 'Albero',
    raw_view: 'Raw',
    parse_failed_note: 'parsing fallito',
    you: 'Tu',
    mcp_servers_title: 'Server MCP',
    mcp_servers_desc: 'Visualizza i server MCP configurati in config.yaml.',
    mcp_no_servers: 'Nessun server MCP configurato.',
    mcp_add_server: '+ Aggiungi Server',
    mcp_field_name: 'Nome Server',
    mcp_transport_label: 'Tipo Trasporto',
    mcp_field_command: 'Comando',
    mcp_field_args: 'Argomenti (separati da virgola)',
    mcp_field_url: 'URL',
    mcp_field_timeout: 'Timeout (secondi)',
    mcp_save: 'Salva',
    mcp_cancel: 'Annulla',
    mcp_name_required: 'Il nome del server è obbligatorio.',
    mcp_url_required: "L'URL è obbligatorio per il trasporto HTTP.",
    mcp_command_required: 'Il comando è obbligatorio per il trasporto stdio.',
    mcp_saved: 'Server MCP salvato.',
    mcp_save_failed: 'Salvataggio server MCP fallito.',
    mcp_delete_confirm_title: 'Elimina Server MCP',
    mcp_delete_confirm_message: 'Eliminare il server MCP "{0}"? Questa azione non può essere annullata.',
    mcp_deleted: 'Server MCP eliminato.',
    mcp_delete_failed: 'Eliminazione server MCP fallita.',
    mcp_load_failed: 'Caricamento server MCP fallito.',
    mcp_restart_hint: 'Le modifiche ai server sono in sola lettura qui. Modifica config.yaml e riavvia Hermes per applicare le modifiche.',
    mcp_toggle_followup: 'I controlli abilita/disabilita sono rinviati finché la semantica di ricaricamento MCP non sarà esplicita.',
    mcp_status_active: 'Attivo',
    mcp_status_configured: 'Configurato',
    mcp_status_disabled: 'Disabilitato',
    mcp_status_invalid_config: 'Configurazione non valida',
    mcp_status_unknown: 'Sconosciuto',
    mcp_tool_count: '{0} strumenti',
    mcp_enabled_yes: 'Abilitato',
    mcp_enabled_no: 'Disabilitato',
    mcp_tools_title: 'Strumenti MCP',
    mcp_tools_desc: 'Cerca strumenti noti tra i server MCP attivi.',
    mcp_tools_search_placeholder: 'Cerca strumenti per nome, server o descrizione…',
    mcp_tools_no_tools: "Nessuno strumento MCP disponibile dall'inventario runtime attivo.",
    mcp_tools_no_matches: 'Nessuno strumento MCP corrisponde alla ricerca.',
    mcp_tools_load_failed: 'Caricamento strumenti MCP fallito.',
    mcp_tools_schema_empty: 'Nessun parametro schema.',
    mcp_tools_runtime_note: "L'inventario strumenti usa solo dati runtime MCP già noti; la WebUI non avvia né interroga i server.",
    mcp_tools_summary_no_matches: (query,total) => `No MCP tools matching “${query}” (${total} total MCP tools).`,
    mcp_tools_summary_none: 'No MCP tools to show.',
    mcp_tools_summary_matching: (query) => ` matching “${query}”`,
    mcp_tools_summary_total_note: (total) => ` (${total} total MCP tools)`,
    mcp_tools_summary_showing: (start,end,filtered,searchNote,totalNote,page,pages) => `Showing ${start}-${end} of ${filtered} MCP tools${searchNote}${totalNote}. Page ${page} of ${pages}.`,
    mcp_tools_page_size_prefix: 'Show',
    mcp_tools_page_size_suffix: 'per page',
    mcp_tools_per_page_aria: 'MCP tools per page',
    mcp_tools_inactive_configured_servers: (servers) => `Configured but inactive in this WebUI runtime: ${servers}.`,
    mcp_tools_pagination_label: 'MCP tools pagination',
    mcp_tools_previous_page: '‹ Prev',
    mcp_tools_previous_page_aria: 'Previous MCP tools page',
    mcp_tools_next_page: 'Next ›',
    mcp_tools_next_page_aria: 'Next MCP tools page',
    // PDF preview (#480)
    pdf_loading: 'Caricamento PDF {0}…',
    pdf_too_large: "PDF troppo grande per l'anteprima inline",
    pdf_no_pages: 'Il PDF non ha pagine',
    pdf_error: 'Rendering anteprima PDF fallito',
    pdf_download: 'Scarica PDF',
    // HTML sandbox preview (#482)
    html_loading: 'Caricamento anteprima HTML…',
    html_too_large: "HTML troppo grande per l'anteprima inline",
    html_error: 'Rendering anteprima HTML fallito',
    html_open_full: 'Apri pagina intera',
    html_sandbox_label: 'Anteprima HTML (sandbox)',
    thinking: 'Pensando',
    expand_all: 'Espandi tutto',
    collapse_all: 'Comprimi tutto',
    edit_failed: 'Modifica fallita: ',
    regen_failed: 'Rigenerazione fallita: ',
    reconnect_active: 'Una risposta è ancora in generazione. Ricaricare quando pronta?',
    reconnect_finished: 'Una risposta era in corso quando hai lasciato. I messaggi potrebbero essere aggiornati.',
    // approval card
    approval_heading: 'Approvazione richiesta',
    approval_desc_prefix: 'Comando pericoloso rilevato',
    approval_btn_once: 'Consenti una volta',
    approval_btn_once_title: 'Consenti questo comando (Invio)',
    approval_btn_session: 'Consenti sessione',
    approval_btn_session_title: 'Consenti per questa sessione di conversazione',
    approval_btn_always: 'Consenti sempre',
    approval_btn_always_title: 'Consenti sempre questo tipo di comando',
    approval_btn_deny: 'Nega',
    approval_btn_deny_title: 'Nega — non eseguire questo comando',
    approval_responding: 'Rispondendo\u2026',
    clarify_heading: 'Chiarimento necessario',
    clarify_hint: "Scegli un'opzione o scrivi la tua risposta qui sotto.",
    clarify_other: 'Altro',
    clarify_send: 'Invia',
    clarify_input_placeholder: 'Scrivi la tua risposta…',
    clarify_responding: 'Rispondendo\u2026',
    untitled: 'Senza titolo',
    n_messages: (n) => n === 1 ? `${n} messaggio` : `${n} messaggi`,
    load_older_messages: '↑ Scorri in alto o clicca per caricare i messaggi precedenti',
    session_jump_start: 'Inizio',
    session_jump_start_label: "Vai all'inizio della sessione",
    session_jump_end: 'Fine',
    session_jump_end_label: 'Vai alla fine della sessione',
    jump_to_question: 'alla domanda',
    jump_to_question_label: 'Vai alla domanda di questa risposta',
    queued_label: 'Inviato dopo la risposta',
    queued_count: (n) => n === 1 ? '1 in coda' : `${n} in coda`,
    queued_cancel: 'Annulla messaggio in coda',
    model_unavailable: ' (non disponibile)',
    model_unavailable_title: 'Questo modello non è più nella lista provider attuale',
    provider_mismatch_warning: (m,p)=>`"${m}" potrebbe non funzionare con il provider configurato (${p}). Invia comunque, o esegui \`hermes model\` nel terminale per cambiare.`,
    provider_mismatch_label: 'Provider non corrispondente',
    model_not_found_label: 'Modello non trovato',
    model_custom_label: 'ID modello personalizzato',
    model_custom_placeholder: 'es. openai/gpt-5.4',
    model_search_placeholder: 'Cerca modelli…',
    model_search_no_results: 'Nessun modello trovato',
    model_group_configured: 'Configurato',
    ws_search_placeholder: 'Cerca workspace…',
    ws_no_results: 'Nessun workspace trovato',
    workspace_new_worktree_conversation: 'Nuova conversazione in worktree',
    workspace_new_worktree_conversation_meta: 'Crea un worktree git isolato per questo workspace.',
    workspace_worktree_created: 'Conversazione worktree creata',
    workspace_worktree_failed: 'Creazione worktree fallita: ',
    session_worktree_badge: 'Worktree',
    model_scope_advisory: 'Si applica a questa conversazione dal prossimo messaggio.',
    model_scope_toast: 'Si applica a questa conversazione dal prossimo messaggio.',
    // commands.js
    cmd_clear: 'Cancella i messaggi della conversazione',
    cmd_compress: 'Comprimi manualmente il contesto della conversazione (uso: /compress [argomento])',
    ctx_compress_hint: 'Comprimi il contesto per liberare spazio →',
    ctx_compress_action: '⚠ Comprimi ora per liberare contesto',
    cmd_compact_alias: 'Alias legacy per /compress',
    cmd_model: 'Cambia modello (es. /model gpt-4o)',
    cmd_workspace: 'Cambia workspace per nome',
    cmd_terminal: 'Apri il terminale del workspace',
    cmd_new: 'Avvia una nuova sessione di chat',
    cmd_usage: 'Attiva/disattiva visualizzazione uso token',
    cmd_theme: 'Cambia aspetto (tema: system/dark/light, skin: default/ares/mono/slate/poseidon/sisyphus/charizard/sienna/catppuccin/nous/geist-contrast)',
    cmd_personality: "Cambia personalità dell'agente",
    cmd_skills: 'Elenca le skill Hermes disponibili',
    available_commands: 'Comandi disponibili:',
    type_slash: 'Digita / per vedere i comandi',
    conversation_cleared: 'Conversazione cancellata',
    command_label: 'Comando',
    context_compaction_label: 'Compattazione contesto',
    retrieval_context_label: 'Contesto indicizzato',
    retrieval_context_preview: 'I messaggi precedenti sono archiviati e recuperabili con gli strumenti di contesto',
    preserved_task_list_label: 'Lista task preservata',
    reference_only_label: 'Solo riferimento',
    model_usage: 'Uso: /model <nome>',
    no_model_match: 'Nessun modello corrispondente a "',
    switched_to: 'Passato a ',
    workspace_usage: 'Uso: /workspace <nome>',
    no_workspace_match: 'Nessun workspace corrispondente a "',
    switched_workspace: 'Passato al workspace: ',
    workspace_switch_failed: 'Cambio workspace fallito: ',
    new_session: 'Nuova sessione creata',
    new_session_creating: 'Creazione nuova conversazione…',
    compressing: 'Richiesta compressione contesto...',
    compress_running_label: 'Compressione in corso',
    compress_complete_label: 'Compressione completata',
    auto_compress_label: 'Compressione automatica',
    compress_failed_label: 'Compressione fallita',
    focus_label: 'Focus',
    token_usage_on: 'Uso token attivo',
    token_usage_off: 'Uso token disattivo',
    usage_cache_hit_detail: 'Cache: {0}% in cache ({1} letti / {2} scritti)',
    usage_cached_percent: '{0}% in cache',
    theme_usage: 'Uso: /theme ',
    theme_set: 'Tema: ',
    no_active_session: 'Nessuna sessione attiva',
    cmd_queue: 'Metti in coda un messaggio per il prossimo turno',
    cmd_goal: 'Imposta o controlla un obiettivo persistente',
    goal_evaluating_progress: 'Valutazione progresso obiettivo…',
    goal_working_toward: "Lavorando verso l'obiettivo…",
    goal_continuing_toast: "Proseguendo verso l'obiettivo…",
    goal_status_none: 'Nessun obiettivo attivo. Impostane uno con /goal <testo>.',
    goal_status_active: (turns, max_turns, goal) => `⊙ Obiettivo (attivo, ${turns}/${max_turns} turni): ${goal}`,
    goal_status_paused: (turns, max_turns, reason, goal) => `⏸ Obiettivo (in pausa, ${turns}/${max_turns}${reason ? `, ${reason}` : ''}): ${goal}`,
    goal_status_done: (turns, max_turns, goal) => `✓ Obiettivo completato (${turns}/${max_turns}): ${goal}`,
    goal_set: (turns, goal) => `⊙ Obiettivo impostato (budget ${turns} turni): ${goal}`,
    goal_paused: (goal) => `⏸ Obiettivo in pausa: ${goal}`,
    goal_resumed: (goal) => `▶ Obiettivo ripreso: ${goal}`,
    goal_cleared: 'Obiettivo rimosso.',
    goal_no_goal: 'Nessun obiettivo attivo.',
    goal_achieved: (reason) => `✓ Obiettivo raggiunto: ${reason}`,
    goal_paused_budget_exhausted: (turns, max_turns) => `⏸ Obiettivo in pausa — ${turns}/${max_turns} turni usati. Usa /goal resume per continuare, o /goal clear per fermarti.`,
    goal_continuing: (turns, max_turns, reason) => `↻ Proseguendo verso l'obiettivo (${turns}/${max_turns}): ${reason}`,
    cmd_interrupt: 'Annulla il turno corrente e invia un nuovo messaggio',
    cmd_steer: "Inietta una correzione a metà turno senza interrompere l'agente",
    cmd_queue_no_msg: 'Uso: /queue <messaggio>',
    cmd_queue_not_busy: 'Nessun task attivo — invia normalmente',
    cmd_queue_confirm: 'Messaggio in coda',
    cmd_interrupt_no_msg: 'Uso: /interrupt <messaggio>',
    cmd_interrupt_confirm: 'Interrotto — invio nuovo messaggio',
    cmd_steer_no_msg: 'Uso: /steer <messaggio>',
    cmd_steer_fallback: 'Steer non disponibile — messaggio in coda per il prossimo turno',
    cmd_steer_delivered: "Steer consegnato — l'agente lo vedrà al prossimo risultato strumento",
    steer_leftover_queued: 'Steer in coda per il prossimo turno',
    busy_steer_fallback: 'Steer non disponibile — messaggio in coda per il prossimo turno',
    busy_interrupt_confirm: 'Interrotto — invio nuovo messaggio',
    settings_label_busy_input_mode: 'Modalità input occupato',
    settings_desc_busy_input_mode: "Controlla cosa succede quando invii un messaggio mentre l'agente è in esecuzione. Coda attende; Interrompi annulla e ricomincia; Steer inietta una correzione a metà turno senza interrompere (fallback a coda se agente o stream non disponibili).",
    settings_label_fade_text_effect: 'Effetto dissolvenza testo',
    settings_desc_fade_text_effect: 'Dissolve gradualmente le nuove parole trasmesse in streaming mentre l’assistente risponde. Simile a OpenWebUI; disattivato per impostazione predefinita per massime prestazioni.',
    settings_busy_input_mode_queue: 'Accoda follow-up',
    settings_busy_input_mode_interrupt: 'Interrompi turno corrente',
    settings_busy_input_mode_steer: 'Steer (correzione a metà turno)',

  slash_skill_badge:'Skill',
  slash_skill_desc:'Invoca questa skill',
  cmd_stop:'Ferma la risposta corrente',
  cmd_title:'Mostra o imposta il titolo della sessione',
  cmd_retry:"Reinvia l'ultimo messaggio",
  cmd_undo:"Rimuovi l'ultimo scambio",
  cmd_btw:'Fai una domanda laterale (effimera)',
  cmd_btw_usage:'/btw <domanda> — fai una domanda laterale usando il contesto della sessione',
   cmd_background:'Esegui un prompt in background',
   cmd_background_usage:'/background <prompt> — esegui in parallelo senza bloccare',
   cmd_branch:'Dirama questa conversazione in una nuova sessione',
   cmd_branch_usage:'/branch [nome] — dirama la conversazione (opzionalmente con un nome)',
   branch_forked:'Diramata in nuova sessione',
   branch_failed:'Diramazione fallita: ',
   fork_from_here:'Dirama da qui',
   forked_from:'Diramata da',
   subagent_children:'Sessioni subagente',
   btw_asking:'Domanda laterale in corso...',
  btw_label:'Domanda laterale — non nella cronologia',
  btw_done:'Domanda laterale risposta',
  btw_no_answer:'Nessuna risposta ricevuta.',
  btw_failed:'Domanda laterale fallita: ',
  bg_running:'In esecuzione in background...',
  bg_complete:'Task in background completato',
  bg_label:'Risultato background:',
  bg_no_answer:'(nessuna risposta)',
  bg_failed:'Task in background fallito: ',
  undo_exchange:'Annulla ultimo scambio',
  cmd_status:'Mostra info sessione',
  cmd_voice:'Attiva/disattiva input microfono',
  stream_stopped:'Risposta fermata.',
  no_active_task:'Nessun task attivo da fermare.',
  cancel_unavailable:'Annullamento non disponibile.',
  retry_failed:'Riprova fallito: ',
  undo_failed:'Annulla fallito: ',
  undid_n_messages:'Rimossi',
  undid_messages_suffix:'messaggio/i.',
  status_heading:'Stato Sessione',
  status_session_id:'ID Sessione',
  status_title:'Titolo',
  status_model:'Modello',
  status_provider:'Provider',
  status_workspace:'Workspace',
  status_personality:'Personalità',
  status_messages:'Messaggi',
  status_agent_running:'Agente in esecuzione',
    status_profile: 'Profilo',
    status_hermes_home: 'Home Hermes',
    status_started: 'Avviato',
    status_updated: 'Aggiornato',
    status_tokens: 'Token',
    status_ephemeral: 'Snapshot effimero — non salvato nella cronologia trascrizioni.',
    status_no_tokens: 'Nessun token usato',
    status_unknown: 'Sconosciuto',
  status_yes:'Sì',
  status_no:'No',
  status_load_failed:'Caricamento stato fallito: ',
  title_current:'Titolo attuale',
  title_change_hint:'Usa `/title <nuovo nome>` per rinominare.',
  title_set:'Titolo impostato a',
  cmd_webui_only_session:'Questo comando non è disponibile per sessioni importate da CLI.',
  cmd_voice_use_mic:'Clicca il pulsante microfono nel compositore.',
  usage_heading:'Uso Token',
  usage_default_model:'predefinito',
  usage_unknown:'sconosciuto',
  usage_input_tokens:'Token input',
  usage_output_tokens:'Token output',
  usage_total:'Token totali',
  usage_estimated_cost:'Costo stimato',
  usage_settings_tip:'Nota: le stime dei costi sono approssimative.',
  usage_load_failed:'Caricamento uso fallito: ',
    usage_personality_none:'nessuna',
    // Session toolsets (#493)
    session_toolsets:'Strumenti Sessione',
    session_toolsets_desc:'Limita gli strumenti disponibili per questa sessione (vuoto = usa config globale)',
    session_toolsets_global:'Globale (predefinito)',
    session_toolsets_custom:'Personalizzato',
    session_toolsets_placeholder:'strumento1, strumento2, …',
    session_toolsets_apply:'Applica',
    session_toolsets_clear:'Pulisci (usa globale)',
    session_toolsets_applied:'Strumenti aggiornati',
    session_toolsets_cleared:'Strumenti azzerati — uso config globale',
    session_toolsets_failed:'Aggiornamento strumenti fallito: ',
  untitled:'Senza titolo',
    no_personalities: 'Nessuna personalità trovata (aggiungile in ~/.hermes/personalities/)',
    available_personalities: 'Personalità disponibili:',
    personality_switch_hint: '\\n\\nUsa `/personality <nome>` per cambiare, o `/personality none` per rimuovere.',
    personalities_load_failed: 'Caricamento personalità fallito',
    personality_cleared: 'Personalità rimossa',
    personality_set: 'Personalità: ',
    failed_colon: 'Fallito: ',
    // ui.js
    no_workspace: 'Nessun workspace',
    terminal_open_title: 'Apri terminale workspace',
    terminal_no_workspace_title: 'Seleziona un workspace per aprire il terminale',
    terminal_title: 'Terminale',
    terminal_clear: 'Pulisci',
    terminal_copy_output: 'Copia output',
    terminal_restart: 'Riavvia',
    terminal_collapse: 'Comprimi',
    terminal_expand: 'Espandi',
    terminal_close: 'Chiudi',
    terminal_input_placeholder: 'Esegui un comando...',
    terminal_start_failed: 'Avvio terminale fallito: ',
    terminal_input_failed: 'Input terminale fallito: ',
    terminal_copy_failed: 'Copia fallita: ',
    terminal_error: 'Errore terminale',
    workspace_empty_no_path: 'Nessun workspace selezionato. Imposta un workspace in Impostazioni \u2192 Workspace per esplorare i file.',
    workspace_empty_dir: 'Questo workspace è vuoto.',
    workspace_show_hidden_files: 'Mostra file nascosti',
    workspace_show_hidden_files_desc: "Includi .DS_Store, .git, node_modules e altri file nascosti/di sistema nell'albero dei file.",
    workspace_hidden_files_visible: 'nascosti visibili',
    workspace_hidden_files_visible_title: 'I file nascosti sono visibili — clicca per opzioni',
    workspace_options: 'Opzioni workspace',
    dialog_confirm_title: 'Conferma azione',
    dialog_prompt_title: 'Inserisci un valore',
    dialog_confirm_btn: 'Conferma',
    // workspace.js
    unsaved_confirm: "Hai modifiche non salvate nell'anteprima. Scartare e navigare?",
    discard: 'Scarta',
    save: 'Salva',
    edit: 'Modifica',
    clear: 'Pulisci',
    create: 'Crea',
    remove: 'Rimuovi',
    save_title: 'Salva modifiche',
    edit_title: 'Modifica questo file',
    saved: 'Salvato',
    save_failed: 'Salvataggio fallito: ',
    image_load_failed: "Impossibile caricare l'immagine",
    file_open_failed: 'Impossibile aprire il file',
    downloading: (name) => `Scaricamento ${name}\u2026`,
    double_click_rename: 'Doppio clic per rinominare',
    renamed_to: 'Rinominato in ',
    rename_failed: 'Rinomina fallita: ',
    delete_title: 'Elimina',
    delete_confirm: (name) => `Eliminare ${name}?`,
    delete_dir_confirm: (name) => `Eliminare la cartella "${name}" e tutto il suo contenuto?`,
    rename_title: 'Rinomina',
    rename_prompt: 'Nuovo nome:',
    deleted: 'Eliminato ',
    delete_failed: 'Eliminazione fallita: ',
    reveal_in_finder: 'Mostra nel File Manager',
    reveal_failed: 'Mostra fallito: ',
    copy_file_path: 'Copia percorso file',
    download_folder: 'Download Folder', // TODO: translate
    path_copied: 'Percorso file copiato negli appunti',
    path_copy_failed: 'Copia percorso fallita: ',
    session_rename: 'Rinomina conversazione',
    session_rename_desc: 'Modifica il titolo di questa conversazione',
    new_file_prompt: 'Nuovo nome file (es. note.md):',
    project_name_prompt: 'Nome progetto:',
    created: 'Creato ',
    create_failed: 'Creazione fallita: ',
    new_folder_prompt: 'Nuovo nome cartella:',
    folder_created: 'Cartella creata ',
    folder_create_failed: 'Creazione cartella fallita: ',
  workspace_auto_create_folder: 'Crea cartella se non esiste',
  folder_add_as_space_btn: 'Aggiungi come Spazio',
  folder_add_as_space_msg: 'Aggiungere questa cartella come nuovo spazio nella lista workspace?',
  folder_add_as_space_title: 'Aggiungere come Spazio?',
    remove_title: 'Rimuovi',
    empty_dir: '(vuota)',
    upload_failed: 'Upload fallito: ',
    upload_too_large: (maxMb, fileMb) => `File troppo grande (${fileMb} MB). La dimensione massima è ${maxMb} MB.`,
    all_uploads_failed: (n) => `Tutti gli ${n} upload sono falliti`,
    archive_extracted: (n, c) => `Estratti ${n} file da ${c} archivio/i`,
    session_pin: 'Fissa conversazione',
    session_unpin: 'Sblocca conversazione',
    session_pin_desc: 'Mantieni questa conversazione in cima',
    session_unpin_desc: 'Rimuovi dalle fissate',
    session_pin_failed: 'Fissa fallito: ',
    session_move_project: 'Sposta nel progetto',
    session_move_project_desc_has: 'Cambia il progetto per questa conversazione',
    session_move_project_desc_none: 'Assegna un progetto a questa conversazione',
    session_archive: 'Archivia conversazione',
    session_hide_external: 'Nascondi dalla lista',
    session_restore: 'Ripristina conversazione',
    session_archive_desc: 'Nascondi questa conversazione fino a mostrare archiviate',
    session_archive_worktree_desc: 'Nascondi questa conversazione; mantieni il suo worktree su disco',
    session_hide_external_desc: 'Nascondi questa sessione importata dalla WebUI senza eliminare lo storico originale.',
    session_restore_desc: 'Riporta questa conversazione nella lista principale',
    session_archived: 'Sessione archiviata',
    session_archived_worktree: 'Sessione archiviata. Il worktree rimane su disco.',
    session_hidden: 'Sessione nascosta dalla lista',
    session_restored: 'Sessione ripristinata',
    session_archive_failed: 'Archiviazione fallita: ',
    session_duplicate: 'Duplica conversazione',
    session_duplicate_desc: 'Crea una copia con lo stesso workspace e modello',
    session_duplicated: 'Sessione duplicata',
    session_duplicate_failed: 'Duplicazione fallita: ',
    session_stop_response: 'Ferma risposta',
    session_stop_response_desc: 'Annulla la risposta in corso per questa conversazione',
    session_delete: 'Elimina conversazione',
    session_delete_desc: 'Rimuovi permanentemente questa conversazione',
    session_delete_confirm: 'Eliminare questa conversazione?',
    session_delete_worktree_desc: 'Elimina solo la conversazione di WebUI; mantieni il worktree su disco',
    session_delete_worktree_confirm: (path) => `Eliminare questa conversazione? Il worktree in ${path} rimarrà su disco.`,
    session_deleted: 'Conversazione eliminata',
    session_deleted_worktree: 'Conversazione eliminata. Il worktree rimane su disco.',
    session_worktree_remove: 'Rimuovi worktree',
    session_worktree_remove_desc: (path) => `Elimina il git worktree in ${path} dal disco`,
    session_worktree_remove_confirm: (path) => `Rimuovere il git worktree dal disco?\n\nPercorso: ${path}\n\nVerrà eliminata l'intera directory del worktree. I dati della sessione restano in WebUI.`,
    session_worktree_remove_not_exists: (path) => `Il worktree in ${path} non esiste più sul disco.`,
    session_worktree_remove_confirm_label: 'Rimuovi',
    session_worktree_removed: 'Worktree rimosso.',
    session_worktree_remove_failed: 'Rimozione worktree fallita: ',
    session_worktree_remove_status_failed: 'Lettura stato worktree fallita: ',
    session_worktree_remove_locked_by_stream: 'Impossibile rimuovere — una sessione di streaming attiva sta usando questo worktree.',
    session_worktree_remove_locked_by_terminal: 'Impossibile rimuovere — una sessione terminale attiva sta usando questo worktree.',
    session_worktree_remove_unsafe_blocked: 'Risolvi le modifiche locali o i commit non inviati prima di rimuovere questo worktree.',
    session_worktree_remove_dirty_warning: 'ATTENZIONE: Questo worktree ha modifiche non committate che andranno perse.',
    session_worktree_remove_untracked_warning: (count) => `${count} file non tracciati verranno eliminati definitivamente.`,
    session_worktree_remove_ahead_warning: (ahead) => `${ahead} commit non inviati andranno persi.`,
    session_select_mode: 'Seleziona',
    session_select_mode_desc: 'Seleziona conversazioni per gestione in blocco',
    session_select_all: 'Seleziona tutto',
    session_deselect_all: 'Deseleziona tutto',
    session_selected_count: '{0} selezionate',
    session_batch_archive: 'Archivia',
    session_batch_delete: 'Elimina',
    session_batch_move: 'Sposta nel progetto',
    session_batch_delete_confirm: 'Eliminare {0} conversazioni?',
    session_batch_archive_confirm: 'Archiviare {0} conversazioni?',
    session_batch_delete_worktree_confirm: 'Eliminare {0} conversazioni? {1} conversazioni con worktree lasceranno le loro directory worktree su disco.',
    session_batch_archive_worktree_confirm: 'Archiviare {0} conversazioni? {1} conversazioni con worktree manterranno le loro directory worktree su disco.',
    session_no_selection: 'Nessuna conversazione selezionata',
    // settings panel
    settings_heading_title: 'Pannello di Controllo',
    settings_heading_subtitle: 'Preferenze, strumenti di conversazione e controlli di sistema.',
    settings_section_conversation_title: 'Conversazione',
    settings_section_appearance_title: 'Aspetto',
    settings_section_appearance_meta: 'Tema, colori accento e stile visivo.',
    settings_section_preferences_title: 'Preferenze',
    settings_section_preferences_meta: 'Predefiniti e comportamento UI per Hermes Web UI.',
    settings_section_system_title: 'Sistema',
    settings_section_system_meta: 'Versione istanza e controlli di accesso.',
    settings_check_now: 'Verifica ora',
    settings_checking: 'Verifica in corso\u2026',
    settings_up_to_date: 'Aggiornato \u2713',
    settings_updates_available: '{count} aggiornamento/i disponibile/i',
    settings_updates_disabled: 'Verifica aggiornamenti disabilitata',
    settings_update_check_failed: 'Verifica aggiornamenti fallita',
    settings_label_workspace_panel_open: 'Mantieni il pannello workspace aperto per impostazione predefinita',
    settings_desc_workspace_panel_open: 'Se abilitato, il pannello workspace/esplora file si apre automaticamente a ogni nuova sessione. Puoi comunque chiuderlo manualmente in qualsiasi momento.',
    settings_label_session_jump_buttons: 'Mostra pulsanti salto sessione',
    settings_desc_session_jump_buttons: 'Mostra pulsanti fluttuanti Inizio e Fine durante la lettura di sessioni lunghe.',

    settings_label_session_endless_scroll: 'Carica messaggi precedenti scorrendo in alto',

    settings_desc_session_endless_scroll: 'Se abilitato, i messaggi precedenti si caricano automaticamente scorrendo in alto. Se disabilitato, usa il pulsante messaggi precedenti.',

    settings_label_tab_visibility: 'Schede della barra laterale',
    settings_desc_tab_visibility: 'Scegli quali schede mostrare nella barra laterale e nel rail. Chat e Impostazioni sono sempre visibili.',
    open_in_browser: 'Apri nel browser',
    settings_dropdown_conversation: 'Conversazione',
    settings_dropdown_appearance: 'Aspetto',
    settings_dropdown_preferences: 'Preferenze',
    settings_dropdown_providers: 'Provider',
    settings_dropdown_system: 'Sistema',
    settings_tab_conversation: 'Conversazione',
    settings_tab_appearance: 'Aspetto',
    settings_tab_preferences: 'Preferenze',
    settings_tab_plugins: 'Plugin',
    settings_plugins_title: 'Plugins',  // TODO: translate
    settings_plugins_meta: 'View installed Hermes plugins and the lifecycle hooks they register. This panel is read-only.',  // TODO: translate
    settings_plugins_empty: 'No Hermes plugins are currently visible. Install or enable plugins from the Hermes CLI/config to see them here.',  // TODO: translate
    plugins_unnamed: 'Unnamed plugin',  // TODO: translate
    plugins_no_description: 'No description provided.',  // TODO: translate
    plugins_no_hooks: 'No registered lifecycle hooks',  // TODO: translate
    plugins_registered_hooks: 'Registered hooks',  // TODO: translate
    plugins_enabled: 'Enabled',  // TODO: translate
    plugins_disabled: 'Disabled',  // TODO: translate
    plugins_active_provider: 'Active (provider)',  // TODO: translate
    plugins_provider_no_hooks: 'Provider plugin — no agent-visibility hooks',  // TODO: translate
    plugins_load_failed: 'Failed to load plugins: ',  // TODO: translate
    settings_tab_system: 'Sistema',
    settings_title: 'Impostazioni',
    settings_save_btn: 'Salva Impostazioni',
    settings_label_model: 'Modello Predefinito',
    settings_desc_model: 'Usato per le nuove conversazioni. Le conversazioni esistenti mantengono il modello selezionato.',
    settings_label_send_key: 'Tasto Invio',
    settings_label_theme: 'Tema',
    settings_label_skin: 'Skin',
    settings_label_font_size: 'Dimensione font',
    font_size_small: 'Piccolo',
    font_size_default: 'Predefinito',
    font_size_large: 'Grande',
    font_size_xlarge: 'Molto grande',
    settings_autosave_saving: 'Salvataggio…',
    settings_autosave_saved: 'Salvato',
    settings_autosave_failed: 'Salvataggio fallito',
    settings_autosave_retry: 'Riprova',
    settings_label_language: 'Lingua',
    settings_label_quota_chip: 'Mostra il chip della quota del provider nel compositore',
    settings_desc_quota_chip: "Mostra un indicatore di quota residua (es. saldo crediti OpenRouter) nel piè di pagina del compositore. Predefinito disattivato. Visibile solo su schermi larghi (≥1400px) quando attivato, per mantenere il compositore non affollato su laptop e desktop standard.",
    settings_label_hide_suggestions: 'Hide new-chat suggestions',
    settings_desc_hide_suggestions: 'Hide the three default suggestion buttons on the empty new-chat screen to avoid accidental taps.',
    settings_label_token_usage: 'Mostra uso token',
    settings_label_sidebar_density: 'Densità sidebar',
    cmd_reasoning: 'Mostra/nascondi ragionamento, imposta livello sforzo o controlla stato attuale',
    settings_label_external_sessions: 'Mostra sessioni non-WebUI',
    settings_label_previous_messaging_sessions: 'Mostra sessioni di messaggistica precedenti',
    settings_label_sync_insights: 'Sincronizza con insights',
    settings_label_check_updates: 'Verifica aggiornamenti',
    settings_label_whats_new_summary: "Summarize What's New with AI",
    settings_label_bot_name: 'Nome assistente predefinito',
    settings_label_password: 'Password di Accesso',
    settings_saved: 'Impostazioni salvate',
    settings_save_failed: 'Salvataggio fallito: ',
    settings_load_failed: 'Caricamento impostazioni fallito: ',
    settings_saved_pw: 'Impostazioni salvate — protezione password abilitata e questo browser rimane autenticato',
    settings_saved_pw_updated: 'Impostazioni salvate — password aggiornata',
    // login page (used server-side via /api/i18n/login endpoint)
    login_title: 'Accedi',
    login_subtitle: 'Inserisci la password per continuare',
    login_placeholder: 'Password',
    login_btn: 'Accedi',
    login_invalid_pw: 'Password non valida',
    login_conn_failed: 'Connessione fallita',
    dialog_confirm_title: 'Conferma azione',
    dialog_prompt_title: 'Inserisci un valore',
    dialog_confirm_btn: 'Conferma',
    discard: 'Scarta',
    clear: 'Pulisci',
    create: 'Crea',
    remove: 'Rimuovi',
    project_name_prompt: 'Nome progetto:',
    // Sidebar & Tabs
    tab_chat: 'Chat',
    tab_tasks: 'Task',
    tab_skills: 'Skill',
    tab_memory: 'Memoria',
    tab_workspaces: 'Spazi',
    tab_profiles: 'Profili',
    tab_kanban: 'Kanban',
    kanban_board: 'Bacheca',
    kanban_visible_tasks: '{0} task visibili',
    kanban_search_tasks: 'Cerca task',
    kanban_all_assignees: 'Tutti gli assegnatari',
    kanban_all_tenants: 'Tutti i tenant',
    kanban_include_archived: 'Includi archiviati',
    kanban_no_matching_tasks: 'Nessun task corrispondente',
    kanban_no_data: 'Nessun dato Kanban',
    kanban_work_queue_hint: 'Questa è la coda di lavoro di Hermes Agent. Crea o classifica un task, assegnalo, spostalo in Pronto, poi lascia che il dispatcher lo reclami.',
    kanban_unavailable: 'Kanban non disponibile',
    kanban_read_only: 'Vista sola lettura',
    kanban_empty: 'Vuoto',
    kanban_task: 'Task',
    kanban_no_description: 'Nessuna descrizione',
    kanban_refresh: 'Aggiorna',
    kanban_status_triage: 'Triage',
    kanban_status_todo: 'Da fare',
    kanban_status_ready: 'Pronto',
    kanban_status_running: 'In esecuzione',
    kanban_status_blocked: 'Bloccato',
    kanban_status_done: 'Completato',
    kanban_comments_count: 'Commenti ({0})',
    kanban_events_count: 'Eventi ({0})',
    kanban_links: 'Link',
    kanban_parents: 'Genitori',
    kanban_children: 'Figli',
    kanban_runs_count: 'Esecuzioni ({0})',
    kanban_no_comments: 'Nessun commento',
    kanban_no_events: 'Nessun evento',
    kanban_no_runs: 'Nessuna esecuzione',
    kanban_title: 'Titolo',
    kanban_description: 'Descrizione',
    kanban_description_placeholder: 'Opzionale — cosa deve succedere, criteri di accettazione, link',
    kanban_status: 'Stato',
    kanban_assignee: 'Assegnatario',
    kanban_assignee_placeholder: 'Opzionale — lascia vuoto per qualsiasi worker',
    kanban_tenant: 'Tenant',
    kanban_tenant_placeholder: 'Opzionale — slug progetto o team',
    kanban_priority: 'Priorità',
    kanban_priority_hint: 'I numeri più alti vengono eseguiti prima. Predefinito 0.',
    kanban_title_required: 'Il titolo è obbligatorio.',
    kanban_new_task: 'Nuovo task',
    kanban_edit_task: 'Modifica task',
    kanban_status_original_hint: 'Stato effettivo: {0}. Questa finestra supporta solo modifiche Triage/Da fare/Pronto.',
    kanban_run_dispatcher: 'Avvia dispatcher',
    kanban_run_dispatcher_confirm: 'Questo reclamerà i task Pronti su questa bacheca e avvierà sottoprocessi worker (uno per task, fino a 8 per clic). Continuare?',
    kanban_assignee_profiles_label: 'Profili Hermes',
    kanban_assignee_other_label: 'Altro (canali CLI / profili rimossi)',
    kanban_assignee_unassigned: '— Non assegnato (non verrà eseguito automaticamente) —',
    kanban_ready_needs_assignee: 'Hai scelto Non assegnato + Pronto. Il dispatcher salterà questo task. Invia di nuovo per confermare, o scegli un profilo.',
    kanban_dispatch_preview_prefix: 'Anteprima:',
    kanban_dispatch_run_prefix: 'Smistato:',
    kanban_dispatch_spawned: 'avviato',
    kanban_dispatch_promoted: 'promosso',
    kanban_dispatch_reclaimed: 'reclamato',
    kanban_dispatch_skipped_unassigned: 'saltato (nessun assegnatario)',
    kanban_dispatch_skipped_nonspawnable: 'saltato (profilo sconosciuto)',
    kanban_dispatch_auto_blocked: 'auto-bloccato',
    kanban_dispatch_timed_out: 'scaduto',
    kanban_dispatch_crashed: 'crash',
    kanban_add_comment: 'Aggiungi commento',
      kanban_only_mine: 'Solo miei',
      kanban_bulk_action: 'Azione in blocco',
      kanban_nudge_dispatcher: 'Anteprima dispatcher',
      kanban_stats: 'Statistiche',
      kanban_worker_log: 'Log worker',
      kanban_block: 'Blocca',
      kanban_unblock: 'Sblocca',
      kanban_back_to_board: 'Torna alla bacheca',
      kanban_lanes_by_profile: 'Corsie per profilo',
      kanban_new_board: 'Nuova bacheca…',
      kanban_rename_board: 'Rinomina bacheca attuale…',
      kanban_archive_board: 'Archivia bacheca attuale…',
      kanban_archive_board_confirm: 'Archiviare la bacheca "{name}"? I task rimangono su disco e la bacheca può essere ripristinata da kanban/boards/_archived/.',
      kanban_board_archived: 'Bacheca archiviata',
      kanban_board_name: 'Nome',
      kanban_board_slug: 'Slug (minuscole, trattini)',
      kanban_board_description: 'Descrizione (opzionale)',
      kanban_board_icon: 'Icona (emoji, opzionale)',
      kanban_board_color: 'Colore (opzionale)',
      kanban_board_name_required: 'Il nome è obbligatorio',
      kanban_board_slug_required: 'Lo slug è obbligatorio',
      kanban_card_complete: 'completato',
      kanban_card_archive: 'archivia',
      kanban_unassigned: 'non assegnato',
    kanban_status_archived: 'Archiviato',
    tab_todos: 'Todos',
    tab_insights: 'Insights',
    tab_dashboard: 'Dashboard Hermes',
    dashboard_loopback_warning: 'La dashboard è solo loopback sul server. Naviga dal server stesso o riavvialo con --host 0.0.0.0 (non sicuro).',
    tab_logs: 'Log',
    tab_settings: 'Impostazioni',
    new_conversation: 'Nuova conversazione',
    filter_conversations: 'Filtra conversazioni...',
    session_time_unknown: 'Sconosciuto',
    session_time_minutes_ago: (n) => `${n}m`,
    session_time_hours_ago: (n) => `${n}h`,
    session_time_days_ago: (n) => `${n}g`,
    session_time_last_week: '1sett',
    session_time_bucket_today: 'Oggi',
    session_time_bucket_yesterday: 'Ieri',
    session_time_bucket_this_week: 'Questa settimana',
    session_time_bucket_last_week: 'Settimana scorsa',
    session_time_bucket_older: 'Precedenti',
    scheduled_jobs: 'Job pianificati',
    new_job: 'Nuovo job',
    loading: 'Caricamento...',
    search_skills: 'Cerca skill...',
    new_skill: 'Nuova skill',
    personal_memory: 'Memoria personale',
    current_task_list: 'Lista task corrente',
    // Logs
    logs_title: 'Log',
    logs_file: 'File',
    logs_tail: 'Coda',
    logs_auto_refresh: 'Aggiornamento automatico (5s)',
    logs_wrap: 'A capo automatico',
    logs_copy_all: 'Copia tutto',
    logs_empty: 'Nessuna riga di log.',
    logs_loading: 'Caricamento log…',
    logs_load_failed: 'Caricamento log fallito',
    logs_status_idle: 'Scegli un file di log per vedere le righe recenti.',
    logs_no_mtime: 'non ancora scritto',
    logs_truncated_hint: 'Visualizzazione della coda di un file di log grande; i byte precedenti sono stati saltati per contenere la memoria.',
    logs_copied: 'Log copiati',

    // Insights
    insights_title: 'Analitiche di Utilizzo',
    insights_sessions: 'Sessioni',
    insights_messages: 'Messaggi',
    insights_tokens: 'Token',
    insights_cost: 'Costo Stimato',
    insights_no_cost: 'N/D',
    insights_models: 'Modelli',
    insights_activity_by_day: 'Attività per Giorno',
    insights_activity_by_hour: 'Attività per Ora',
    insights_peak_hour: 'Picco: {hour}',
    insights_token_breakdown: 'Ripartizione Token',
    insights_input_tokens: 'Input',
    insights_output_tokens: 'Output',
    insights_total: 'Totale',
    insights_daily_tokens: 'Token Giornalieri',
    insights_model_name: 'Modello',
    insights_model_sessions: 'Sessioni',
    insights_model_tokens: 'Token',
    insights_model_cost: 'Costo',
    insights_model_share: 'Quota',
    insights_no_usage_data: 'Nessun dato di utilizzo',
    insights_footer: 'Dati mostrati dagli ultimi {days} giorni',
    workspace_desc: 'Aggiungi e cambia workspace per le tue sessioni.',
    session_meta_messages: (n) => `${n} msg`,
    session_meta_children: (n) => `${n} figli${n === 1 ? 'o' : ''}`,
    session_meta_segments: (n) => `${n} segment${n === 1 ? 'o' : 'i'}`,
    session_lineage_segment_untitled: 'Segmento senza titolo',
    session_lineage_segment_open: 'Apri segmento genealogia',
    new_profile: 'Nuovo profilo',
    transcript: 'Trascrizione',
    download_transcript: 'Scarica come Markdown',
    import: 'Importa',
    export_session_json: 'JSON',
    export_session_json_tooltip: 'Esporta sessione completa come JSON',
    import_session_json_tooltip: 'Importa sessione da JSON',
    clear_conversation_btn_tooltip: 'Cancella tutti i messaggi in questa conversazione',
    // Settings detail
    settings_label_rtl: 'Layout chat da destra a sinistra',
    settings_desc_rtl: "Inverte l'allineamento dei messaggi e dell'input del compositore per lingue come arabo o ebraico. Influisce solo sull'area chat — la barra laterale e gli altri pannelli rimangono da sinistra a destra.",
    settings_label_sound: 'Suono notifica',
    settings_desc_sound: 'Riproduci un suono quando l\'assistente termina una risposta.',
    // TTS (#499)
    tts_listen: 'Ascolta',
    tts_not_supported: 'Sintesi vocale non supportata in questo browser.',
    settings_label_tts: 'Sintesi vocale per le risposte',
    settings_desc_tts: 'Mostra un pulsante altoparlante su ogni messaggio dell\'assistente per leggerlo ad alta voce usando la sintesi vocale del browser.',
    settings_label_tts_auto_read: 'Leggi automaticamente le risposte ad alta voce',
    settings_desc_tts_auto_read: 'Leggi automaticamente ogni nuova risposta dell\'assistente quando termina. In pausa quando inizi a scrivere.',
    // Composer voice-mode pref (#1488)
    settings_label_voice_mode: 'Pulsante modalità vocale a mani libere',
    settings_desc_voice_mode: 'Mostra il pulsante modalità vocale (forma d\'onda audio) accanto al microfono di dettatura. Ti permette di parlare naturalmente — Hermes invia automaticamente dopo una pausa e legge le risposte ad alta voce. Richiede un browser che supporti sia il riconoscimento vocale che la sintesi vocale.',
    settings_label_tts_voice: 'Voce',
    settings_desc_tts_voice: 'Voce preferita. Popolata dalle voci disponibili nel browser.',
    settings_label_tts_rate: 'Velocità voce',
    settings_label_tts_pitch: 'Tono voce',
    settings_label_notifications: 'Notifiche browser',
    settings_desc_notifications: 'Mostra una notifica di sistema quando una risposta termina mentre l\'app è in background.',
    settings_desc_token_usage: 'Mostra il conteggio token input/output sotto ogni risposta dell\'assistente. Attivabile anche con /usage.',
    settings_label_api_redact: 'Oscura dati sensibili nelle risposte API',
    settings_desc_api_redact: 'Gli utenti self-hosted possono disabilitare per trasparenza (sconsigliato per istanze condivise).',
    settings_sidebar_density_compact: 'Compatta',
    settings_sidebar_density_detailed: 'Dettagliata',
    settings_desc_sidebar_density: 'Controlla quanti metadati mostra la lista sessioni nella sidebar sinistra.',
    settings_label_auto_title_refresh: 'Aggiornamento adattivo titolo',
    settings_auto_title_refresh_off: 'Off',
    settings_auto_title_refresh_5: 'Ogni 5 scambi',
    settings_auto_title_refresh_10: 'Ogni 10 scambi',
    settings_auto_title_refresh_20: 'Ogni 20 scambi',
    settings_desc_auto_title_refresh: 'Rigenera automaticamente il titolo della sessione in base all\'ultimo scambio, mantenendolo pertinente mentre la conversazione evolve. Richiede un modello LLM per la generazione titoli.',
    settings_desc_external_sessions: 'Mostra conversazioni da CLI, Telegram, Discord, Slack e altri canali nella lista sessioni. Clicca per importare e continuare.',
    settings_desc_previous_messaging_sessions: 'Mostra sessioni Discord, Telegram, Slack e Weixin più vecchie sostituite da reset o compressione.',
    settings_desc_sync_insights: 'Rispecchia l\'uso token WebUI su state.db così hermes /insights include i dati delle sessioni browser. Disattivato per impostazione predefinita.',
    settings_desc_check_updates: 'Mostra un banner quando sono disponibili versioni più recenti della WebUI o dell\'Agente. Esegue un git fetch in background periodicamente.',
    settings_desc_whats_new_summary: "Changes the What's New action from opening the raw diff first to generating a short, human-readable summary. The regular diff comparison stays available after the summary.",
    settings_desc_bot_name: 'Usato solo per il profilo predefinito. Gli altri profili usano i propri nomi.',
    settings_desc_password: 'Inserisci una nuova password per impostarla o cambiarla. Lascia vuoto per mantenere l\'impostazione attuale.',
    password_placeholder: 'Inserisci nuova password…',
    password_env_var_locked: 'La variabile d\'ambiente HERMES_WEBUI_PASSWORD è attualmente impostata e ha la precedenza. Rimuovila e riavvia il server per gestire la password da qui.',
    password_env_var_locked_placeholder: 'Bloccato: variabile d\'ambiente HERMES_WEBUI_PASSWORD impostata',
    disable_auth: 'Disabilita Auth',
    sign_out: 'Esci',
    // Providers panel
    providers_tab_title: 'Provider',
    providers_section_title: 'Provider',
    providers_section_meta: 'Gestisci le chiavi API per i provider AI. Le modifiche hanno effetto immediato.',
    providers_status_configured: 'Chiave API configurata',
    providers_status_not_configured: 'Nessuna chiave API',
    providers_status_oauth: 'OAuth',
    providers_status_api_key: 'Chiave API',
    providers_status_not_configured_label: 'Non configurato',
    providers_oauth_hint: 'Autenticato via OAuth. Nessuna chiave API necessaria.',
    providers_oauth_config_yaml_hint: 'Token configurato via config.yaml. Per aggiornare, modifica la sezione providers in config.yaml o esegui hermes auth.',
    providers_oauth_not_configured_hint: 'Non autenticato. Esegui hermes auth nel terminale per configurare questo provider.',
    providers_save: 'Salva',
    providers_remove: 'Rimuovi',
    providers_saving: 'Salvataggio…',
    providers_removing: 'Rimozione…',
    providers_enter_key: 'Inserisci una chiave API',
    providers_empty: 'Nessun provider configurabile trovato.',
    providers_key_updated: 'Chiave API salvata',
    providers_key_removed: 'Chiave API rimossa',
    providers_key_placeholder_new: 'sk-...',
    providers_key_placeholder_replace: 'Inserisci nuova chiave da sostituire…',
    provider_quota_title: 'Quota del provider attivo',
    provider_quota_active_provider: 'Provider attivo',
    provider_quota_last_checked_after_refresh: 'Ultimo controllo dopo l’aggiornamento',
    provider_quota_last_checked: 'Ultimo controllo {0}',
    provider_quota_refresh_usage: 'Aggiorna utilizzo',
    provider_quota_refreshing: 'Aggiornamento...',
    provider_quota_refresh_title: 'Aggiorna ora i limiti di utilizzo del provider',
    provider_quota_refresh_succeeded: 'Utilizzo del provider aggiornato',
    provider_quota_refresh_failed: 'Aggiornamento dell’utilizzo del provider non riuscito',
    provider_quota_session_limit: 'Limite di 5 ore',
    provider_quota_weekly_limit: 'Limite settimanale',
    provider_quota_window_fallback: 'Finestra',
    provider_quota_metric_remaining: 'Rimanente',
    provider_quota_metric_used: 'Usato',
    provider_quota_metric_limit: 'Limite',
    provider_quota_status_available: 'disponibile',
    provider_quota_status_exhausted: 'esaurito',
    provider_quota_status_unavailable: 'non disponibile',
    provider_quota_status_failed: 'non riuscito',
    provider_quota_status_checked: 'controllato',
    provider_quota_status_no_key: 'nessuna chiave',
    provider_quota_status_invalid_key: 'chiave non valida',
    provider_quota_status_unsupported: 'non supportato',
    provider_quota_used_meta: '{0} usato',
    provider_quota_resets_meta: 'si reimposta {0}',
    provider_quota_credential_pool: 'Pool di credenziali',
    provider_quota_credential_label: 'Credenziale {0}',
    provider_quota_pool_plans: 'Piani: {0}',
    provider_quota_pool_no_windows: 'Nessuna finestra di limite account segnalata.',
    provider_quota_account_limits_loaded: 'Limiti account caricati.',
    provider_quota_unavailable: 'Stato quota non disponibile',
    provider_quota_retry_after: 'Riprova dopo {0}',
    provider_quota_pool_summary_available: '{0}/{1} disponibili',
    provider_quota_pool_summary_exhausted: '{0} esauriti',
    provider_quota_pool_summary_failed: '{0} non riusciti',
    provider_quota_pool_summary_checked: '{0} controllati',
    cancel: 'Annulla',
    create_job: 'Crea job',
    save_skill: 'Salva skill',
    editing: 'Modifica in corso',
    // Empty state
    empty_title: 'Cosa posso fare per te?',
    empty_subtitle: 'Chiedi qualsiasi cosa, esegui comandi, esplora file o gestisci i tuoi task pianificati.',
    suggest_files: 'Quali file ci sono in questo workspace?',
    suggest_schedule: 'Cosa ho in programma oggi?',
    suggest_plan: 'Aiutami a pianificare un piccolo progetto.',
    // onboarding
    onboarding_badge: 'PRIMO AVVIO',
    onboarding_title: 'Benvenuto in Hermes Web UI',
    onboarding_lead: 'Una configurazione guidata rapida verificherà Hermes, salverà una configurazione provider reale, sceglierà un workspace e un modello e opzionalmente proteggerà l\'app con una password.',
    onboarding_back: 'Indietro',
    onboarding_continue: 'Continua',
    onboarding_skip: 'Salta configurazione',
    onboarding_skipped: 'Configurazione saltata — uso configurazione esistente.',
    onboarding_open: 'Apri Hermes',
    onboarding_step_system_title: 'Verifica sistema',
    onboarding_step_system_desc: 'Verifica Hermes Agent e visibilità configurazione.',
    onboarding_step_setup_title: 'Configurazione provider',
    onboarding_step_setup_desc: 'Salva la configurazione minima provider Hermes.',
    onboarding_step_workspace_title: 'Workspace + modello',
    onboarding_step_workspace_desc: 'Scegli le impostazioni predefinite per nuove sessioni e chat.',
    onboarding_step_password_title: 'Password opzionale',
    onboarding_step_password_desc: 'Proteggi la Web UI prima di condividerla.',
    onboarding_step_finish_title: 'Fine',
    onboarding_step_finish_desc: 'Rivedi e accedi all\'app.',
    onboarding_notice_system_ready: 'Hermes Agent sembra raggiungibile dalla Web UI.',
    onboarding_notice_system_unavailable: 'Hermes Agent non è ancora completamente disponibile. Bootstrap può installarlo, ma la configurazione provider potrebbe richiedere un terminale.',
    onboarding_check_agent: 'Hermes Agent',
    onboarding_check_agent_ready: 'Rilevato e importabile',
    onboarding_check_agent_missing: 'Mancante o parzialmente importabile',
    onboarding_check_password: 'Password',
    onboarding_check_password_enabled: 'Già abilitata',
    onboarding_check_password_disabled: 'Non ancora abilitata',
    onboarding_check_provider: 'Configurazione provider',
    onboarding_check_provider_ready: 'Pronto per chattare',
    onboarding_check_provider_partial: 'Salvata ma incompleta',
    onboarding_check_provider_pending: 'Necessita verifica',
    onboarding_config_file: 'File config:',
    onboarding_env_file: 'File .env:',
    onboarding_unknown: 'Sconosciuto',
    onboarding_current_provider: 'Configurazione attuale:',
    onboarding_missing_imports: 'Import mancanti:',
    onboarding_notice_setup_required: 'Scegli un percorso provider semplice qui. I flussi OAuth avanzati rimangono nella CLI di Hermes per ora.',
    onboarding_notice_setup_already_ready: 'Una configurazione provider Hermes funzionante è già stata rilevata. Puoi mantenerla o sostituirla qui.',
    onboarding_oauth_provider_ready_title: 'Provider già autenticato',
    onboarding_oauth_provider_ready_body: 'Questa istanza è configurata per usare un provider OAuth (<strong>{provider}</strong>) impostato tramite la CLI di Hermes. Nessuna chiave API necessaria — clicca Continua per finire.',
    onboarding_oauth_provider_not_ready_title: 'Provider OAuth non ancora autenticato',
    onboarding_oauth_provider_not_ready_body: 'Questa istanza è configurata per usare <strong>{provider}</strong>, che usa OAuth invece di una chiave API. Esegui <code>hermes auth</code> o <code>hermes model</code> in un terminale per autenticarti, poi ricarica la Web UI.',
    onboarding_oauth_switch_hint: 'Oppure scegli un provider diverso qui sotto per passare a una configurazione con chiave API:',
    oauth_login_codex: 'Accedi con Codex (ChatGPT)',
    oauth_codex_step1: 'Passo 1: Visita questo URL e inserisci il codice',
    oauth_codex_step2: 'Passo 2: Inserisci questo codice nella pagina',
    oauth_codex_polling: 'In attesa di autorizzazione...',
    oauth_codex_success: 'Accesso Codex OAuth riuscito!',
    oauth_codex_error: 'Accesso OAuth fallito',
    oauth_codex_expired: 'Codice scaduto, riprova',
    onboarding_notice_workspace: 'Questi valori usano le stesse API di impostazioni dell\'app normale.',
    onboarding_workspace_label: 'Workspace',
    onboarding_workspace_or_path: 'Oppure inserisci un percorso workspace',
    onboarding_workspace_placeholder: '/home/tu/workspace',
    onboarding_provider_label: 'Modalità configurazione',
    onboarding_quick_setup_badge: 'configurazione rapida',
    provider_category_easy_start: 'Avvio facile',
    provider_category_self_hosted: 'Open / self-hosted',
    provider_category_specialized: 'Specializzato',
    onboarding_api_key_label: 'Chiave API',
    onboarding_api_key_placeholder: 'Lascia vuoto per mantenere una chiave salvata esistente',
    onboarding_api_key_label_optional: 'Chiave API (opzionale)',
    onboarding_api_key_placeholder_optional: 'Lascia vuoto per server senza chiave',
    onboarding_api_key_help_keyless: 'La maggior parte delle installazioni LM Studio / Ollama / vLLM funzionano senza chiave — lascia vuoto se il tuo server non richiede autenticazione. Usa il pulsante Test connessione per verificare.',
    onboarding_api_key_help_prefix: 'Salvato come segreto nel tuo file .env di Hermes usando',
    onboarding_base_url_label: 'URL Base',
    onboarding_base_url_placeholder: 'https://tuo-endpoint.example/v1',
    onboarding_base_url_help: 'Usa questo per router compatibili OpenAI, server self-hosted, LiteLLM, Ollama, LM Studio, vLLM o endpoint simili.',
    onboarding_model_label: 'Modello predefinito',
    onboarding_workspace_help: 'Scegli il modello che Hermes userà per le nuove chat dopo la configurazione.',
    onboarding_custom_model_placeholder: 'nome-tuo-modello',
    onboarding_custom_model_help: 'Per endpoint personalizzati, inserisci l\'ID esatto del modello che il tuo server si aspetta.',
    onboarding_notice_password_enabled: 'Una password è già configurata. Inseriscine una nuova solo se vuoi sostituirla.',
    onboarding_notice_password_recommended: 'Opzionale ma consigliato se esporrai l\'interfaccia oltre localhost.',
    onboarding_password_label: 'Password (opzionale)',
    onboarding_password_placeholder: 'Lascia vuoto per saltare',
    onboarding_password_help: 'Le password sono salvate tramite le API impostazioni esistenti e hashate lato server.',
    onboarding_notice_finish: 'Puoi riaprire le Impostazioni più tardi per modificare tutto questo.',
    onboarding_not_set: 'Non impostato',
    onboarding_password_will_enable: 'Sarà abilitata',
    onboarding_password_will_replace: 'Sarà sostituita',
    onboarding_password_keep_existing: 'Mantieni password attuale',
    onboarding_password_remains_disabled: 'Rimarrà disabilitata',
    onboarding_password_skipped: 'Saltata per ora',
    onboarding_finish_help: 'Completare salva <code>onboarding_completed</code> nelle impostazioni e ti porta nell\'app normale.',
    onboarding_error_choose_workspace: 'Scegli un workspace prima di continuare.',
    onboarding_error_choose_model: 'Scegli un modello prima di continuare.',
    onboarding_error_provider_required: 'Scegli una modalità di configurazione prima di continuare.',
    onboarding_error_base_url_required: 'L\'URL Base è obbligatorio per endpoint personalizzati.',
    onboarding_probe_test_button: 'Test connessione',
    onboarding_probe_probing: 'Test connessione in corso…',
    onboarding_probe_ok: 'Connesso. {n} modello/i disponibile/i.',
    onboarding_probe_error_generic: 'Impossibile raggiungere l\'URL base configurato.',
    onboarding_probe_error_invalid_url: 'L\'URL base deve iniziare con http:// o https://.',
    onboarding_probe_error_dns: 'Impossibile risolvere l\'host. Controlla l\'URL o usa l\'indirizzo IP dell\'host.',
    onboarding_probe_error_connect_refused: 'Connessione rifiutata — il server potrebbe non essere in esecuzione su quell\'indirizzo. Da dentro Docker, prova l\'IP host invece di localhost.',
    onboarding_probe_error_timeout: 'L\'endpoint non ha risposto in tempo. Verifica che il server sia in esecuzione e che l\'URL sia corretto.',
    onboarding_probe_error_http_4xx: 'L\'endpoint ha restituito un errore client. Controlla l\'autenticazione e il percorso URL (tipicamente termina in /v1).',
    onboarding_probe_error_http_5xx: 'L\'endpoint ha restituito un errore server. Controlla i log del server LM Studio / Ollama.',
    onboarding_probe_error_parse: 'L\'endpoint non ha restituito una lista modelli nel formato atteso. Verifica che l\'URL punti alla root API compatibile OpenAI.',
    onboarding_probe_error_unreachable: 'Impossibile raggiungere l\'URL base configurato.',
    onboarding_error_probe_failed: 'Impossibile validare l\'URL base configurato.',
    onboarding_error_workspace_required: 'Il workspace è obbligatorio.',
    onboarding_error_model_required: 'Il modello è obbligatorio.',
    onboarding_complete: 'Configurazione completata',

    // panel/runtime i18n
    error_prefix: 'Errore: ',
    not_available: 'N/D',
    never: 'mai',
    add: 'Aggiungi',
    add_failed: 'Aggiunta fallita: ',
    remove_failed: 'Rimozione fallita: ',
    switch_failed: 'Cambio fallito: ',
    name_required: 'Il nome è obbligatorio',
    content_required: 'Il contenuto è obbligatorio',
    view: 'Visualizza',
    dismiss: 'Ignora',
    disable: 'Disabilita',
    cron_no_jobs: 'Nessun job pianificato trovato.',
    cron_status_off: 'spento',
    cron_status_paused: 'in pausa',
    cron_status_error: 'errore',
    cron_status_active: 'attivo',
    cron_status_running: 'in esecuzione\u2026',
    cron_status_needs_attention: 'richiede attenzione',
    cron_attention_desc: 'Questo job ricorrente non ha una prossima esecuzione. Lo scheduler potrebbe non essere riuscito a calcolare la prossima esecuzione.',
    cron_attention_croniter_hint: 'Il runtime Gateway potrebbe non avere il pacchetto croniter. Riavvia il Gateway con supporto cron, poi riprendi questo job.',
    cron_attention_resume: 'Riprendi e ricalcola',
    cron_jobs_project: 'Job Pianificati',
    cron_attention_run_once: 'Esegui una volta ora',
    cron_attention_copy_diagnostics: 'Copia diagnostica',
    cron_diagnostics_copied: 'Diagnostica copiata',
    cron_next: 'Prossimo',
    cron_last: 'Ultimo',
    cron_run_now: 'Esegui ora',
    cron_pause: 'Pausa',
    cron_resume: 'Riprendi',
    cron_job_name_placeholder: 'Nome job',
    cron_schedule_placeholder: 'Pianificazione',
    cron_prompt_placeholder: 'Prompt',
    cron_last_output: 'Ultimo output',
    cron_expand_prompt: 'Espandi prompt',
    cron_collapse_prompt: 'Comprimi prompt',
    cron_expand_output: 'Espandi output',
    cron_collapse_output: 'Comprimi output',
    cron_all_runs: 'Tutte le esecuzioni',
    cron_hide_runs: 'Nascondi esecuzioni',
    cron_no_runs_yet: '(nessuna esecuzione)',
    cron_schedule_required_example: 'La pianificazione è obbligatoria (es. "0 9 * * *" o "every 1h")',
    cron_schedule_required: 'La pianificazione è obbligatoria',
    cron_prompt_required: 'Il prompt è obbligatorio',
    cron_job_created: 'Job creato',
    cron_duplicate: 'Duplica',
    cron_duplicated: 'Job duplicato (in pausa)',
    cron_job_triggered: 'Job avviato',
    cron_job_paused: 'Job in pausa',
    cron_job_resumed: 'Job ripreso',
    cron_job_updated: 'Job aggiornato',
    cron_delete_confirm_title: 'Elimina job pianificato',
    cron_delete_confirm_message: 'Questa azione non può essere annullata.',
    cron_job_deleted: 'Job eliminato',
    cron_completion_status: (name, status) => `Cron "${name}" ${status}`,
    status_failed: 'fallito',
    status_completed: 'completato',
    todos_no_active: 'Nessuna lista task attiva in questa sessione.',
    clear_conversation_title: 'Cancella conversazione',
    clear_conversation_message: 'Cancellare tutti i messaggi? Questa azione non può essere annullata.',
    clear_failed: 'Cancellazione fallita: ',
    skills_no_match: 'Nessuna skill corrispondente.',
    linked_files: 'File Collegati',
    skill_load_failed: 'Impossibile caricare la skill: ',
    skill_file_load_failed: 'Impossibile caricare il file: ',
    skill_name_required: 'Il nome della skill è obbligatorio',
    skill_updated: 'Skill aggiornata',
    skill_created: 'Skill creata',
    skill_deleted: 'Skill eliminata',
    skill_delete_confirm: 'Eliminare la skill "{0}"?',
    skills_empty_title: 'Seleziona una skill',
    skills_empty_sub: 'Scegli una skill dalla sidebar per vederne i contenuti, o creane una nuova.',
    skills_edit: 'Modifica',
    skills_delete: 'Elimina',
    skills_back_to: 'Torna a {0}',
    tasks_empty_title: 'Seleziona un job pianificato',
    tasks_empty_sub: 'Scegli un job dalla sidebar per vederne dettagli ed esecuzioni, o creane uno nuovo.',
    workspaces_empty_title: 'Seleziona uno spazio',
    workspaces_empty_sub: 'Scegli uno spazio dalla sidebar per vederne file e impostazioni, o aggiungine uno nuovo.',
    profiles_empty_title: 'Seleziona un profilo',
    profiles_empty_sub: 'Scegli un profilo agente dalla sidebar per vedere e modificare le sue impostazioni, o creane uno nuovo.',
    memory_notes_label: 'memoria (note)',
    memory_saved: 'Memoria salvata',
    my_notes: 'Le Mie Note',
    user_profile: 'Profilo Utente',
    no_notes_yet: 'Ancora nessuna nota.',
    no_profile_yet: 'Ancora nessun profilo.',
    agent_soul: 'Anima dell\'Agente',
    no_soul_yet: 'Nessuna anima definita.',
    workspace_choose_path: 'Scegli percorso workspace',
    workspace_choose_path_meta: 'Aggiungi un percorso validato e cambia questa conversazione',
    workspace_manage: 'Gestisci workspace',
    workspace_manage_meta: 'Apri il pannello Spazi',
    workspace_use_title: 'Usa nella sessione corrente',
    workspace_use: 'Usa',
    workspace_add_path_placeholder: 'Aggiungi percorso workspace (es. /home/utente/mio-progetto)',
    workspace_paths_validated_hint: 'I percorsi sono validati come directory esistenti prima del salvataggio.',

    workspace_drag_hint: 'Trascina per riordinare',
    workspace_reorder_failed: 'Riordino fallito',
    workspace_added: 'Workspace aggiunto',
    workspace_renamed: 'Workspace rinominato',
    workspace_remove_confirm_title: 'Rimuovi workspace',
    workspace_remove_confirm_message: (path) => `Rimuovere "${path}"?`,
    workspace_removed: 'Workspace rimosso',
    workspace_switch_prompt_title: 'Cambia workspace',
    workspace_switch_prompt_message: 'Inserisci un percorso workspace assoluto da aggiungere e a cui passare questa conversazione.',
    workspace_switch_prompt_confirm: 'Cambia',
    workspace_switch_prompt_placeholder: '/Users/tu/progetto',
    workspace_not_added: 'Workspace non aggiunto',
    workspace_already_saved: 'Workspace già salvato — sceglilo dalla lista',
    workspace_busy_switch: 'Impossibile cambiare workspace mentre l\'agente è in esecuzione',
    discard_file_edits_title: 'Scartare le modifiche ai file?',
    discard_file_edits_message: 'Cambiare workspace scarterà le modifiche non salvate nell\'anteprima.',
    workspace_switched_to: (name) => `Passato a ${name}`,
    profiles_no_profiles: 'Nessun profilo trovato.',
    profile_api_keys_configured: 'Chiavi API configurate',
    profile_gateway_running: 'Gateway in esecuzione',
    profile_gateway_stopped: 'Gateway fermo',
    profile_active: 'ATTIVO',
    profile_no_configuration: 'Nessuna configurazione',
    profile_skill_count: (count) => `${count} skill`,
    profile_use: 'Usa',
    profile_switch_title: 'Passa a questo profilo',
    profile_delete_title: 'Elimina questo profilo',
    profile_default_label: '(predefinito)',
    profile_name_placeholder: 'Nome profilo (minuscole, a-z 0-9 trattini)',
    profile_clone_label: 'Clona config dal profilo attivo',
    profile_model_label: 'Modello / provider',
    profile_model_hint: 'Scegli tra provider e modelli configurati per questo nuovo profilo.',
    profile_model_use_default: 'Usa il default del profilo attivo',
    profile_base_url_placeholder: 'Base URL (opzionale, es. http://localhost:11434)',
    profile_api_key_placeholder: 'Chiave API (opzionale)',
    manage_profiles: 'Gestisci profili',
    profiles_load_failed: 'Caricamento profili fallito',
    profile_switched_new_conversation: (name) => `Passato al profilo: ${name} — nuova conversazione avviata`,
    profile_switched: (name) => `Passato al profilo: ${name}`,
    profile_name_rule: 'Solo lettere minuscole, numeri, trattini, underscore',
    profile_base_url_rule: 'L\'URL Base deve iniziare con http:// o https://',
    profile_created: (name) => `Profilo creato: ${name}`,
    profile_delete_confirm_title: (name) => `Eliminare il profilo "${name}"?`,
    profile_delete_confirm_message: 'Tutte le sessioni, configurazioni, skill e memoria per questo profilo saranno eliminate permanentemente. Questa azione non può essere annullata.',
    profile_deleted: (name) => `Profilo eliminato: ${name}`,
    active_conversation_none: 'Nessuna conversazione attiva selezionata.',
    active_conversation_meta: (title, count) => `${title} · ${count} messaggi${count === 1 ? 'o' : ''}`,
    settings_unsaved_changes: 'Hai modifiche non salvate.',
    sign_out_failed: 'Disconnessione fallita: ',
    disable_auth_confirm_title: 'Disabilita protezione password',
    disable_auth_confirm_message: 'Chiunque potrà accedere a questa istanza.',
    auth_disabled: 'Auth disabilitata — protezione password rimossa',
    disable_auth_failed: 'Disabilitazione auth fallita: ',
    bg_error_single: (title) => `"${title}" ha incontrato un errore`,
    bg_error_multi: (count) => `${count} sessioni hanno incontrato un errore`,
    // skill form
    skill_name: 'Nome',
    skill_category: 'Categoria',
    skill_category_placeholder: 'Opzionale, es. devops',
    skill_content: 'Contenuto SKILL.md',
    skill_content_placeholder: 'Frontmatter YAML + corpo markdown',
    skill_rename_not_supported: 'Rinominare una skill non è supportato. Crea una nuova skill ed elimina la vecchia per rinominare.',
    skill_metadata: 'Metadati',
    // cron form
    cron_name_label: 'Nome',
    cron_name_placeholder: 'Opzionale',
    cron_schedule_label: 'Pianificazione',
    cron_schedule_hint: 'Usa \'every 1h\' o un\'espressione cron per job ricorrenti. Durate semplici come \'30m\' vengono eseguite una volta sola.',
    cron_schedule_once_warning: 'Forme di durata come \'30m\' vengono eseguite una volta e rimosse dopo l\'esecuzione. Usa \'every 30m\' per mantenere un job ricorrente.',
    cron_prompt_label: 'Prompt',
    cron_deliver_label: 'Recapita output a',
    cron_deliver_local: 'Locale (solo salva output)',
    cron_profile_label: 'Profilo',
    cron_profile_server_default: 'predefinito server',
    cron_profile_server_default_hint: 'Usa il profilo predefinito del server WebUI a runtime. I job esistenti senza profilo mantengono questo comportamento legacy.',
    cron_toast_notifications_label: 'Notifiche di completamento',
    cron_toast_notifications_hint: 'Mostra un avviso al termine di questo cron. Il badge Task e il segnalibro nuovo-run continuano ad aggiornarsi anche con questa opzione disattivata.',
    cron_toast_notifications_enabled: 'Abilitato',
    cron_toast_notifications_disabled: 'Disabilitato',
    cron_skills_label: 'Skill',
    cron_skills_placeholder: 'Aggiungi skill (opzionale)…',
    cron_skills_edit_hint: 'La lista skill non è modificabile dopo la creazione.',
    // workspace form
    workspace_name_label: 'Nome',
    workspace_name_placeholder: 'Nome descrittivo opzionale',
    workspace_path_label: 'Percorso',
    workspace_path_required: 'Il percorso è obbligatorio',
    workspace_path_readonly: 'Il percorso non può essere cambiato. Solo rinomina.',
    workspace_new_title: 'Nuovo spazio',
    // profile form
    profile_name_label: 'Nome',
    profile_base_url_label: 'URL Base',
    profile_api_key_label: 'Chiave API',
    cmd_yolo: 'Attiva/disattiva modalità YOLO (salta approvazioni)',
    yolo_no_session: 'Nessuna sessione attiva',
    yolo_enabled: '⚡ Modalità YOLO ON — approvazioni saltate questa sessione',
    yolo_disabled: 'Modalità YOLO OFF',
    yolo_pill_label: 'YOLO',
    yolo_pill_title_active: 'Modalità YOLO attiva — clicca per disabilitare',
    approval_skip_all: '⚡ Salta tutto questa sessione',
    approval_skip_all_title: 'Salta tutte le richieste di approvazione per questa sessione',
    // composer action tooltips
    composer_send: 'Invia messaggio',
    composer_queue: 'Accoda messaggio',
    composer_interrupt: 'Interrompi e invia',
    composer_steer: 'Correggi risposta in corso',
    composer_stop: 'Ferma generazione',
    composer_disabled_clarify: 'Rispondi alla richiesta di chiarimento',
    composer_disabled_compression: 'In attesa del completamento della compressione',
    composer_disabled_empty: 'Scrivi un messaggio da inviare',
    composer_mobile_workspace: 'Workspace',
    composer_mobile_model: 'Modello',
    composer_mobile_reasoning: 'Ragionamento',
    composer_mobile_context: 'Contesto',
    media_audio_label: 'Audio',
    media_svg_label: 'Diagramma',
    media_video_label: 'Video',
    csv_loading: 'Caricamento CSV',
    csv_too_large: 'File CSV troppo grande per il rendering inline',
    csv_no_data: 'Il file CSV ha dati insufficienti per il rendering come tabella',
    csv_error: 'Caricamento file CSV fallito',
    csv_header_note: 'Prima riga mostrata come intestazione tabella',
    excalidraw_loading: 'Caricamento diagramma',
    excalidraw_too_large: 'File Excalidraw troppo grande per il rendering inline',
    excalidraw_invalid: 'Formato file Excalidraw non valido',
    excalidraw_error: 'Caricamento file Excalidraw fallito',
    excalidraw_label: 'Diagramma',
    excalidraw_download: 'Scarica',
    excalidraw_empty: 'Diagramma vuoto',
    excalidraw_render_error: 'Rendering diagramma fallito',
    excalidraw_simplified: 'Anteprima SVG semplificata — non identica al canvas Excalidraw',
    // ── Checkpoints / Rollback ──
    checkpoint_title: 'Checkpoint',
    checkpoint_empty: 'Nessun checkpoint trovato per questo workspace.',
    checkpoint_loading: 'Caricamento checkpoint…',
    checkpoint_error: 'Caricamento checkpoint fallito',
    checkpoint_date: 'Data',
    checkpoint_message: 'Messaggio',
    checkpoint_files: 'File',
    checkpoint_view_diff: 'Vedi diff',
    checkpoint_restore: 'Ripristina',
    checkpoint_restore_confirm_title: 'Ripristinare checkpoint?',
    checkpoint_restore_confirm_message: (ckpt) => `Ripristinare il workspace al checkpoint "${ckpt}"? Questo sovrascriverà i file con le versioni salvate. I file aggiunti dopo questo checkpoint non saranno eliminati.`,
    checkpoint_restored: 'Checkpoint ripristinato',
    checkpoint_diff_title: 'Modifiche nel checkpoint',
    checkpoint_diff_no_changes: 'Nessuna differenza trovata tra questo checkpoint e il workspace attuale.',
    checkpoint_diff_files_changed: (n) => `${n} file modificat${n === 1 ? 'o' : 'i'}`,
  },

  ja: {
    offline_title: '接続が切断されました',
    offline_browser_detail: 'ブラウザはこのデバイスがオフラインだと報告しています。',
    offline_network_detail: '現在、このブラウザからHermesに到達できません。',
    offline_autorefresh: 'Hermesに再接続できたら、このページを自動的に更新します。',
    offline_check_now: '今すぐ確認',
    offline_checking: '確認中…',
    offline_stream_waiting: '接続が切断されました。更新を待っています…',
    _lang: 'ja',
    _label: '日本語',
    _speech: 'ja-JP',
    // boot.js
    cancelling: 'キャンセル中…',
    cancel_failed: 'キャンセル失敗: ',
    mic_denied: 'マイクへのアクセスが拒否されました。ブラウザの権限を確認してください。',
    mic_no_speech: '音声が検出されませんでした。もう一度お試しください。',
    mic_network: '音声認識を利用できません。',
    mic_error: '音声入力エラー: ',
    // Turn-based voice mode (#1333)
    // Composer voice buttons (#1488)
    voice_dictate: 'ディクテーション',
    voice_dictate_active: 'ディクテーション停止',
    voice_mode_toggle: '音声モード',
    voice_mode_toggle_active: '音声モードを終了',
    voice_listening: '聞き取り中…',
    voice_speaking: '発話中…',
    voice_thinking: '考え中…',
    voice_error: 'このブラウザでは音声入力に対応していません',
    voice_mode_active: '音声モード ON',
    voice_mode_off: '音声モード OFF',
    session_imported: 'セッションをインポートしました',
    import_failed: 'インポート失敗: ',
    import_invalid_json: '無効な JSON',
    image_pasted: '画像を貼り付けました: ',
    // messages.js
    edit_message: 'メッセージを編集',
    regenerate: '応答を再生成',
    copy: 'コピー',
    copied: 'コピーしました!',
    copy_failed: 'コピー失敗',
    selected_text_reply: '選択範囲で返信',
    selected_text_reply_title: '選択したチャットテキストを引用コンテキストとして追加',
    selected_text_reply_appended: '選択したテキストを入力欄に追加しました',

    diff_loading: '差分を読み込み中',
    diff_error: 'パッチファイルを読み込めませんでした',
    diff_too_large: 'パッチファイルが大きすぎてインライン表示できません',
    tree_view: 'ツリー',
    raw_view: '生データ',
    parse_failed_note: '解析失敗',
    you: 'あなた',
    mcp_servers_title: 'MCPサーバー',
    mcp_servers_desc: 'config.yaml で設定された MCP サーバーを管理します。',
    mcp_no_servers: 'MCPサーバーは設定されていません。',
    mcp_add_server: '+ サーバーを追加',
    mcp_field_name: 'サーバー名',
    mcp_transport_label: 'トランスポート種別',
    mcp_field_command: 'コマンド',
    mcp_field_args: '引数 (カンマ区切り)',
    mcp_field_url: 'URL',
    mcp_field_timeout: 'タイムアウト (秒)',
    mcp_save: '保存',
    mcp_cancel: 'キャンセル',
    mcp_name_required: 'サーバー名は必須です。',
    mcp_url_required: 'HTTP トランスポートには URL が必要です。',
    mcp_command_required: 'stdio トランスポートにはコマンドが必要です。',
    mcp_saved: 'MCPサーバーを保存しました。',
    mcp_save_failed: 'MCPサーバーの保存に失敗しました。',
    mcp_delete_confirm_title: 'MCPサーバーを削除',
    mcp_delete_confirm_message: 'MCPサーバー "{0}" を削除しますか? この操作は取り消せません。',
    mcp_deleted: 'MCPサーバーを削除しました。',
    mcp_delete_failed: 'MCPサーバーの削除に失敗しました。',
    mcp_load_failed: 'MCPサーバーの読み込みに失敗しました。',
    mcp_restart_hint: 'ここでのサーバー変更は現状読み取り専用です。反映するには config.yaml を編集して Hermes を再起動してください。',
    mcp_toggle_followup: '有効/無効の切り替えは、MCP のリロード仕様が明確になるまで意図的に保留しています。',
    mcp_status_active: 'アクティブ',
    mcp_status_configured: '設定済み',
    mcp_status_disabled: '無効',
    mcp_status_invalid_config: '不正な設定',
    mcp_status_unknown: '不明',
    mcp_tool_count: '{0} 個のツール',
    mcp_enabled_yes: '有効',
    mcp_enabled_no: '無効',
    mcp_tools_title: 'MCP ツール',
    mcp_tools_desc: 'アクティブな MCP サーバー全体から既知のツールを検索します。',
    mcp_tools_search_placeholder: '名前、サーバー、説明でツールを検索…',
    mcp_tools_no_tools: 'アクティブなランタイムに利用可能な MCP ツールがありません。',
    mcp_tools_no_matches: '一致する MCP ツールはありません。',
    mcp_tools_load_failed: 'MCP ツールの読み込みに失敗しました。',
    mcp_tools_schema_empty: 'スキーマパラメータはありません。',
    mcp_tools_runtime_note: 'ツール一覧は既知の MCP ランタイム情報のみを使用します。WebUI はサーバーの起動や探索を行いません。',
    mcp_tools_summary_no_matches: (query,total) => `No MCP tools matching “${query}” (${total} total MCP tools).`,
    mcp_tools_summary_none: 'No MCP tools to show.',
    mcp_tools_summary_matching: (query) => ` matching “${query}”`,
    mcp_tools_summary_total_note: (total) => ` (${total} total MCP tools)`,
    mcp_tools_summary_showing: (start,end,filtered,searchNote,totalNote,page,pages) => `Showing ${start}-${end} of ${filtered} MCP tools${searchNote}${totalNote}. Page ${page} of ${pages}.`,
    mcp_tools_page_size_prefix: 'Show',
    mcp_tools_page_size_suffix: 'per page',
    mcp_tools_per_page_aria: 'MCP tools per page',
    mcp_tools_inactive_configured_servers: (servers) => `Configured but inactive in this WebUI runtime: ${servers}.`,
    mcp_tools_pagination_label: 'MCP tools pagination',
    mcp_tools_previous_page: '‹ Prev',
    mcp_tools_previous_page_aria: 'Previous MCP tools page',
    mcp_tools_next_page: 'Next ›',
    mcp_tools_next_page_aria: 'Next MCP tools page',
    // PDF preview (#480)
    pdf_loading: 'PDF {0} を読み込み中…',
    pdf_too_large: 'PDF が大きすぎてインラインプレビューできません',
    pdf_no_pages: 'PDF にページがありません',
    pdf_error: 'PDF プレビューの描画に失敗しました',
    pdf_download: 'PDF をダウンロード',
    // HTML sandbox preview (#482)
    html_loading: 'HTML プレビューを読み込み中…',
    html_too_large: 'HTML が大きすぎてインラインプレビューできません',
    html_error: 'HTML プレビューの描画に失敗しました',
    html_open_full: 'フルページを開く',
    html_sandbox_label: 'HTML プレビュー (サンドボックス)',
    thinking: '考え中',
    expand_all: 'すべて展開',
    collapse_all: 'すべて折りたたむ',
    edit_failed: '編集失敗: ',
    regen_failed: '再生成失敗: ',
    reconnect_active: '応答を生成中です。準備ができたら再読み込みしますか?',
    reconnect_finished: '前回離脱時に応答が進行中でした。メッセージが更新されている可能性があります。',
    // approval card
    approval_heading: '承認が必要',
    approval_desc_prefix: '危険なコマンドを検出しました',
    approval_btn_once: '今回だけ許可',
    approval_btn_once_title: 'このコマンド1回だけ許可 (Enter)',
    approval_btn_session: 'セッション中許可',
    approval_btn_session_title: 'この会話セッション中は許可',
    approval_btn_always: '常に許可',
    approval_btn_always_title: 'このコマンドパターンを常に許可',
    approval_btn_deny: '拒否',
    approval_btn_deny_title: '拒否 — このコマンドを実行しない',
    approval_responding: '応答中…',
    clarify_heading: '確認が必要',
    clarify_hint: '選択肢を選ぶか、下に独自の回答を入力してください。',
    clarify_other: 'その他',
    clarify_send: '送信',
    clarify_input_placeholder: '回答を入力…',
    clarify_responding: '応答中…',
    untitled: '無題',
    n_messages: (n) => `${n} 件のメッセージ`,
    load_older_messages: '↑ 上にスクロール、またはクリックして過去のメッセージを読み込む',
    session_jump_start: '開始',
    session_jump_start_label: 'セッションの先頭へ移動',
    session_jump_end: '末尾',
    session_jump_end_label: 'セッションの末尾へ移動',
    jump_to_question: '質問へ',
    jump_to_question_label: 'この回答の質問へ移動',
    queued_label: '応答後に送信',
    queued_count: (n) => `${n} 件キュー中`,
    queued_cancel: 'キューに入れたメッセージをキャンセル',
    model_unavailable: ' (利用不可)',
    model_unavailable_title: 'このモデルは現在のプロバイダ一覧に含まれていません',
    provider_mismatch_warning: (m,p)=>`"${m}" は設定されたプロバイダ (${p}) で動作しない可能性があります。このまま送信するか、ターミナルで \`hermes model\` を実行して切り替えてください。`,
    provider_mismatch_label: 'プロバイダ不一致',
    model_not_found_label: 'モデルが見つかりません',
    model_custom_label: 'カスタムモデルID',
    model_custom_placeholder: '例: openai/gpt-5.4',
    model_search_placeholder: 'モデルを検索…',
    model_search_no_results: 'モデルが見つかりません',
    model_group_configured: '設定済み',
    ws_search_placeholder: 'ワークスペースを検索…',
    ws_no_results: 'ワークスペースが見つかりません',
    workspace_new_worktree_conversation: 'worktree で新しい会話',
    workspace_new_worktree_conversation_meta: 'このワークスペース用に隔離された git worktree を作成します。',
    workspace_worktree_created: 'worktree 会話を作成しました',
    workspace_worktree_failed: 'worktree の作成に失敗しました: ',
    session_worktree_badge: 'Worktree',
    model_scope_advisory: '次回のメッセージからこの会話に適用されます。',
    model_scope_toast: '次回のメッセージからこの会話に適用されます。',
    // commands.js
    cmd_clear: '会話メッセージをクリア',
    cmd_compress: '会話コンテキストを手動で圧縮 (使い方: /compress [トピック])',
    ctx_compress_hint: 'コンテキストを圧縮して空きを確保 →',
    ctx_compress_action: '⚠ 今すぐ圧縮してコンテキストを確保',
    cmd_compact_alias: '/compress の旧エイリアス',
    cmd_model: 'モデルを切り替え (例: /model gpt-4o)',
    cmd_workspace: '名前でワークスペースを切り替え',
    cmd_terminal: 'ワークスペースのターミナルを開く',
    cmd_new: '新しいチャットセッションを開始',
    cmd_usage: 'トークン使用量表示の ON/OFF を切り替え',
    cmd_theme: '外観を切り替え (theme: system/dark/light, skin: default/ares/mono/slate/poseidon/sisyphus/charizard/sienna/catppuccin/nous/geist-contrast)',
    cmd_personality: 'エージェントのパーソナリティを切り替え',
    cmd_skills: '利用可能な Hermes スキルを一覧表示',
    available_commands: '利用可能なコマンド:',
    type_slash: '/ を入力するとコマンド一覧',
    conversation_cleared: '会話をクリアしました',
    command_label: 'コマンド',
    context_compaction_label: 'コンテキスト圧縮',
    retrieval_context_label: 'インデックス済みコンテキスト',
    retrieval_context_preview: '以前のメッセージは保存され、コンテキストツールで取得できます',
    preserved_task_list_label: '保持されたタスクリスト',
    reference_only_label: '参照専用',
    model_usage: '使い方: /model <名前>',
    no_model_match: '一致するモデルなし: "',
    switched_to: '切り替えました: ',
    workspace_usage: '使い方: /workspace <名前>',
    no_workspace_match: '一致するワークスペースなし: "',
    switched_workspace: 'ワークスペースを切り替えました: ',
    workspace_switch_failed: 'ワークスペース切替失敗: ',
    new_session: '新しいセッションを作成しました',
    new_session_creating: '新しい会話を作成中…',
    compressing: 'コンテキスト圧縮を要求中...',
    compress_running_label: '圧縮中',
    compress_complete_label: '圧縮完了',
    auto_compress_label: '自動圧縮',
    compress_failed_label: '圧縮失敗',
    focus_label: 'フォーカス',
    token_usage_on: 'トークン使用量: ON',
    token_usage_off: 'トークン使用量: OFF',
    usage_cache_hit_detail: 'キャッシュ: {0}% ヒット（読み取り {1} / 書き込み {2}）',
    usage_cached_percent: '{0}% キャッシュ済み',
    theme_usage: '使い方: /theme ',
    theme_set: 'テーマ: ',
    no_active_session: 'アクティブなセッションがありません',
    cmd_queue: '次のターン用にメッセージをキュー',
    cmd_goal: '永続ゴールを設定または確認',
    goal_evaluating_progress: 'Evaluating goal progress…',
    goal_working_toward: 'Working toward goal…',
    goal_continuing_toast: 'Continuing toward goal…',
    goal_status_none: 'No active goal. Set one with /goal <text>.',
    goal_status_active: (turns, max_turns, goal) => `⊙ Goal (active, ${turns}/${max_turns} turns): ${goal}`,
    goal_status_paused: (turns, max_turns, reason, goal) => `⏸ Goal (paused, ${turns}/${max_turns}${reason ? `, ${reason}` : ''}): ${goal}`,
    goal_status_done: (turns, max_turns, goal) => `✓ Goal done (${turns}/${max_turns}): ${goal}`,
    goal_set: (turns, goal) => `⊙ Goal set (${turns}-turn budget): ${goal}`,
    goal_paused: (goal) => `⏸ Goal paused: ${goal}`,
    goal_resumed: (goal) => `▶ Goal resumed: ${goal}`,
    goal_cleared: 'Goal cleared.',
    goal_no_goal: 'No active goal.',
    goal_achieved: (reason) => `✓ Goal achieved: ${reason}`,
    goal_paused_budget_exhausted: (turns, max_turns) => `⏸ Goal paused — ${turns}/${max_turns} turns used. Use /goal resume to keep going, or /goal clear to stop.`,
    goal_continuing: (turns, max_turns, reason) => `↻ Continuing toward goal (${turns}/${max_turns}): ${reason}`,
    cmd_interrupt: '現在のターンをキャンセルして新規メッセージを送信',
    cmd_steer: 'エージェントを中断せずにターン中に修正を注入',
    cmd_queue_no_msg: '使い方: /queue <メッセージ>',
    cmd_queue_not_busy: 'アクティブなタスクなし — 通常通り送信してください',
    cmd_queue_confirm: 'メッセージをキューに入れました',
    cmd_interrupt_no_msg: '使い方: /interrupt <メッセージ>',
    cmd_interrupt_confirm: '中断 — 新しいメッセージを送信中',
    cmd_steer_no_msg: '使い方: /steer <メッセージ>',
    cmd_steer_fallback: 'ステア利用不可 — 代わりに次のターンへキュー',
    cmd_steer_delivered: 'ステア送信完了 — 次のツール結果でエージェントが認識します',
    steer_leftover_queued: 'ステアを次のターンへキュー',
    busy_steer_fallback: 'ステア利用不可 — 次のターンへキュー',
    busy_interrupt_confirm: '中断 — 新しいメッセージを送信中',
    settings_label_busy_input_mode: 'ビジー時の入力モード',
    settings_desc_busy_input_mode: 'エージェント実行中にメッセージを送信した時の動作を制御します。Queue は待機、Interrupt はキャンセルして再開、Steer は中断せずにターン中に修正を注入します (エージェントやストリームが利用不可ならキューにフォールバック)。',
    settings_label_fade_text_effect: 'テキストのフェード効果',
    settings_desc_fade_text_effect: 'アシスタントの応答中に新しくストリーミングされた単語をフェードインします。OpenWebUI に似た表示です。最大パフォーマンスのため既定ではオフです。',
    settings_busy_input_mode_queue: 'フォローアップをキュー',
    settings_busy_input_mode_interrupt: '現在のターンを中断',
    settings_busy_input_mode_steer: 'ステア (ターン中の修正)',

  slash_skill_badge:'スキル',
  slash_skill_desc:'このスキルを呼び出す',
  cmd_stop:'現在の応答を停止',
  cmd_title:'セッションタイトルを取得・設定',
  cmd_retry:'最後のメッセージを再送信',
  cmd_undo:'最後のやり取りを削除',
  cmd_btw:'サイド質問 (一時的)',
  cmd_btw_usage:'/btw <質問> — セッション文脈でサイド質問',
   cmd_background:'プロンプトをバックグラウンド実行',
   cmd_background_usage:'/background <プロンプト> — ブロックせずに並列実行',
   cmd_branch:'この会話を新しいセッションへ分岐',
   cmd_branch_usage:'/branch [名前] — 会話を分岐 (任意で名前指定)',
   branch_forked:'新しいセッションへ分岐しました',
   branch_failed:'分岐失敗: ',
   fork_from_here:'ここから分岐',
   forked_from:'分岐元',
   subagent_children:'サブエージェントセッション',
   btw_asking:'サイド質問を問い合わせ中...',
  btw_label:'サイド質問 — 履歴に残らない',
  btw_done:'サイド質問に回答しました',
  btw_no_answer:'回答が得られませんでした。',
  btw_failed:'サイド質問失敗: ',
  bg_running:'バックグラウンド実行中...',
  bg_complete:'バックグラウンドタスク完了',
  bg_label:'バックグラウンド結果:',
  bg_no_answer:'(回答なし)',
  bg_failed:'バックグラウンドタスク失敗: ',
  undo_exchange:'最後のやり取りを取り消す',
  cmd_status:'セッション情報を表示',
  cmd_voice:'マイク入力を切り替え',
  stream_stopped:'応答を停止しました。',
  no_active_task:'停止できるアクティブタスクがありません。',
  cancel_unavailable:'キャンセルできません。',
  retry_failed:'再試行失敗: ',
  undo_failed:'取り消し失敗: ',
  undid_n_messages:'削除',
  undid_messages_suffix:'件のメッセージ。',
  status_heading:'セッションステータス',
  status_session_id:'セッションID',
  status_title:'タイトル',
  status_model:'モデル',
  status_provider:'プロバイダー',
  status_workspace:'ワークスペース',
  status_personality:'パーソナリティ',
  status_messages:'メッセージ',
  status_agent_running:'エージェント実行中',
    status_profile: 'プロファイル',
    status_hermes_home: 'Hermes ホーム',
    status_started: '開始',
    status_tokens: 'トークン',
    status_updated: '更新',
    status_ephemeral: '一時的なスナップショット — 履歴には保存されません。',
    status_no_tokens: 'トークン未使用',
    status_unknown: '不明',
  status_yes:'はい',
  status_no:'いいえ',
  status_load_failed:'ステータス読み込み失敗: ',
  title_current:'現在のタイトル',
  title_change_hint:'`/title <新しい名前>` で改名できます。',
  title_set:'タイトルを設定: ',
  cmd_webui_only_session:'CLI からインポートしたセッションでは使えません。',
  cmd_voice_use_mic:'コンポーザーのマイクボタンをクリックしてください。',
  usage_heading:'トークン使用量',
  usage_default_model:'デフォルト',
  usage_unknown:'不明',
  usage_input_tokens:'入力トークン',
  usage_output_tokens:'出力トークン',
  usage_total:'合計トークン',
  usage_estimated_cost:'推定コスト',
  usage_settings_tip:'注: コスト推定はおおよその値です。',
  usage_load_failed:'使用量読み込み失敗: ',
    usage_personality_none:'なし',
    // Session toolsets (#493)
    session_toolsets:'セッションツールセット',
    session_toolsets_desc:'このセッションで利用可能なツールを制限 (空欄=グローバル設定を使用)',
    session_toolsets_global:'グローバル (デフォルト)',
    session_toolsets_custom:'カスタム',
    session_toolsets_placeholder:'tool1, tool2, …',
    session_toolsets_apply:'適用',
    session_toolsets_clear:'クリア (グローバルを使用)',
    session_toolsets_applied:'ツールセットを更新しました',
    session_toolsets_cleared:'ツールセットをクリアしました — グローバル設定を使用',
    session_toolsets_failed:'ツールセット更新失敗: ',
  untitled:'無題',
    no_personalities: 'パーソナリティが見つかりません (~/.hermes/personalities/ に追加してください)',
    available_personalities: '利用可能なパーソナリティ:',
    personality_switch_hint: '\n\n`/personality <名前>` で切り替え、`/personality none` でクリアします。',
    personalities_load_failed: 'パーソナリティの読み込みに失敗しました',
    personality_cleared: 'パーソナリティをクリアしました',
    personality_set: 'パーソナリティ: ',
    failed_colon: '失敗: ',
    // ui.js
    no_workspace: 'ワークスペースなし',
    terminal_open_title: 'ワークスペースのターミナルを開く',
    terminal_no_workspace_title: 'ターミナルを開くにはワークスペースを選択してください',
    terminal_title: 'ターミナル',
    terminal_clear: 'クリア',
    terminal_copy_output: '出力をコピー',
    terminal_restart: '再起動',
    terminal_collapse: '折りたたむ',
    terminal_expand: '展開',
    terminal_close: '閉じる',
    terminal_input_placeholder: 'コマンドを実行...',
    terminal_start_failed: 'ターミナル起動失敗: ',
    terminal_input_failed: 'ターミナル入力失敗: ',
    terminal_copy_failed: 'コピー失敗: ',
    terminal_error: 'ターミナルエラー',
    workspace_empty_no_path: 'ワークスペースが選択されていません。設定 → ワークスペースで選択してください。',
    workspace_empty_dir: 'このワークスペースは空です。',
    workspace_show_hidden_files: '隠しファイルを表示',
    workspace_show_hidden_files_desc: 'Include .DS_Store, .git, node_modules, and other hidden / system files in the file tree.',
    workspace_hidden_files_visible: 'hidden visible',
    workspace_hidden_files_visible_title: 'Hidden files are visible — click for options',
    workspace_options: 'Workspace options',
    dialog_confirm_title: '操作の確認',
    dialog_prompt_title: '値を入力',
    dialog_confirm_btn: '確認',
    // workspace.js
    unsaved_confirm: 'プレビューに未保存の変更があります。破棄して移動しますか?',
    discard: '破棄',
    save: '保存',
    edit: '編集',
    clear: 'クリア',
    create: '作成',
    remove: '削除',
    save_title: '変更を保存',
    edit_title: 'このファイルを編集',
    saved: '保存しました',
    save_failed: '保存失敗: ',
    image_load_failed: '画像を読み込めませんでした',
    file_open_failed: 'ファイルを開けませんでした',
    downloading: (name) => `${name} をダウンロード中…`,
    double_click_rename: 'ダブルクリックで名前変更',
    renamed_to: '名前を変更: ',
    rename_failed: '名前変更失敗: ',
    delete_title: '削除',
    delete_confirm: (name) => `${name} を削除しますか?`,
    delete_dir_confirm: (name) => `フォルダ "${name}" とその内容をすべて削除しますか?`,
    rename_title: '名前変更',
    rename_prompt: '新しい名前:',
    deleted: '削除しました: ',
    delete_failed: '削除失敗: ',
    reveal_in_finder: 'ファイルマネージャーで表示',
    reveal_failed: '表示に失敗しました: ',
    copy_file_path: 'ファイルパスをコピー',
    download_folder: 'Download Folder', // TODO: translate
    path_copied: 'ファイルパスをクリップボードにコピーしました',
    path_copy_failed: 'パスのコピーに失敗しました: ',
    session_rename: '会話の名前を変更',
    session_rename_desc: 'この会話のタイトルを編集',
    new_file_prompt: '新しいファイル名 (例: notes.md):',
    project_name_prompt: 'プロジェクト名:',
    created: '作成しました: ',
    create_failed: '作成失敗: ',
    new_folder_prompt: '新しいフォルダ名:',
    folder_created: 'フォルダを作成しました: ',
    folder_create_failed: 'フォルダ作成失敗: ',
  workspace_auto_create_folder: 'フォルダが存在しなければ作成',
  folder_add_as_space_btn: 'スペースとして追加',
  folder_add_as_space_msg: 'このフォルダをワークスペース一覧に新しいスペースとして追加しますか?',
  folder_add_as_space_title: 'スペースとして追加?',
    remove_title: '削除',
    empty_dir: '(空)',
    upload_failed: 'アップロード失敗: ',
    upload_too_large: (maxMb, fileMb) => `ファイルが大きすぎます (${fileMb} MB)。最大アップロードサイズは ${maxMb} MB です。`,
    all_uploads_failed: (n) => `${n} 件のアップロードがすべて失敗しました`,
    archive_extracted: (n, c) => `${c} 個のアーカイブから ${n} 件のファイルを展開しました`,
    session_pin: '会話をピン留め',
    session_unpin: 'ピン留めを解除',
    session_pin_desc: 'この会話を上部に固定',
    session_unpin_desc: 'ピン留めから外す',
    session_pin_failed: 'ピン留め失敗: ',
    session_move_project: 'プロジェクトへ移動',
    session_move_project_desc_has: 'この会話のプロジェクトを変更',
    session_move_project_desc_none: 'この会話にプロジェクトを割り当て',
    session_archive: '会話をアーカイブ',
    session_hide_external: 'リストから非表示',
    session_restore: '会話を復元',
    session_archive_desc: 'アーカイブを表示するまでこの会話を非表示にする',
    session_archive_worktree_desc: 'この会話を非表示にし、worktree はディスク上に残します',
    session_hide_external_desc: '元の履歴を削除せずに、この取り込んだセッションを WebUI のリストから非表示にします。',
    session_restore_desc: 'この会話をメイン一覧に戻す',
    session_archived: 'セッションをアーカイブしました',
    session_archived_worktree: 'セッションをアーカイブしました。Worktree はディスク上に残ります。',
    session_hidden: 'セッションをリストから非表示にしました',
    session_restored: 'セッションを復元しました',
    session_archive_failed: 'アーカイブ失敗: ',
    session_duplicate: '会話を複製',
    session_duplicate_desc: '同じワークスペースとモデルでコピーを作成',
    session_duplicated: 'セッションを複製しました',
    session_duplicate_failed: '複製失敗: ',
    session_stop_response: '応答を停止',
    session_stop_response_desc: 'この会話の実行中の応答をキャンセルします',
    session_delete: '会話を削除',
    session_delete_desc: 'この会話を完全に削除',
    session_delete_confirm: 'この会話を削除しますか?',
    session_delete_worktree_desc: 'WebUI の会話だけを削除し、worktree はディスク上に残します',
    session_delete_worktree_confirm: (path) => `この会話を削除しますか? ${path} の worktree はディスク上に残ります。`,
    session_deleted: '会話を削除しました',
    session_deleted_worktree: '会話を削除しました。Worktree はディスク上に残ります。',
    session_worktree_remove: 'ワークツリーを削除',
    session_worktree_remove_desc: (path) => `${path} のgitワークツリーをディスクから削除します`,
    session_worktree_remove_confirm: (path) => `gitワークツリーをディスクから削除しますか？\n\nパス: ${path}\n\nワークツリーディレクトリ全体が削除されます。セッションデータはWebUIに残ります。`,
    session_worktree_remove_not_exists: (path) => `${path} のワークツリーはディスク上に存在しません。`,
    session_worktree_remove_confirm_label: '削除',
    session_worktree_removed: 'ワークツリーを削除しました。',
    session_worktree_remove_failed: 'ワークツリーの削除に失敗: ',
    session_worktree_remove_status_failed: 'ワークツリー状態の読み取りに失敗: ',
    session_worktree_remove_locked_by_stream: '削除できません — アクティブなストリーミングセッションがこのワークツリーを使用中です。',
    session_worktree_remove_locked_by_terminal: '削除できません — アクティブな端末セッションがこのワークツリーを使用中です。',
    session_worktree_remove_unsafe_blocked: 'このワークツリーを削除する前に、ローカル変更または未プッシュのコミットを解消してください。',
    session_worktree_remove_dirty_warning: '警告: このワークツリーにはコミットされていない変更があり、失われます。',
    session_worktree_remove_untracked_warning: (count) => `${count}件の追跡されていないファイルが完全に削除されます。`,
    session_worktree_remove_ahead_warning: (ahead) => `${ahead}件の未プッシュコミットが失われます。`,
    session_select_mode: '選択',
    session_select_mode_desc: '会話を選択して一括管理',
    session_select_all: 'すべて選択',
    session_deselect_all: '選択解除',
    session_selected_count: '{0} 件選択',
    session_batch_archive: 'アーカイブ',
    session_batch_delete: '削除',
    session_batch_move: 'プロジェクトへ移動',
    session_batch_delete_confirm: '{0} 件の会話を削除しますか?',
    session_batch_archive_confirm: '{0} 件の会話をアーカイブしますか?',
    session_batch_delete_worktree_confirm: '{0} 件の会話を削除しますか? {1} 件の worktree 付き会話は、worktree ディレクトリをディスク上に残します。',
    session_batch_archive_worktree_confirm: '{0} 件の会話をアーカイブしますか? {1} 件の worktree 付き会話は、worktree ディレクトリをディスク上に保持します。',
    session_no_selection: '会話が選択されていません',
    // settings panel
    settings_heading_title: 'コントロールセンター',
    settings_heading_subtitle: '環境設定、会話ツール、システム制御。',
    settings_section_conversation_title: '会話',
    settings_section_appearance_title: '外観',
    settings_section_appearance_meta: 'テーマ、アクセントカラー、ビジュアルスタイル。',
    settings_section_preferences_title: '環境設定',
    settings_section_preferences_meta: 'Hermes Web UI のデフォルトと UI 動作。',
    settings_section_system_title: 'システム',
    settings_section_system_meta: 'インスタンスのバージョンとアクセス制御。',
    settings_check_now: '今すぐ確認',
    settings_checking: '確認中…',
    settings_up_to_date: '最新です ✓',
    settings_updates_available: '{count} 件のアップデートあり',
    settings_update_check_failed: 'アップデート確認失敗',
    settings_updates_disabled: 'アップデート確認は無効です',
    settings_label_workspace_panel_open: 'ワークスペースパネルをデフォルトで開いておく',
    settings_desc_workspace_panel_open: '有効にすると、新しいセッションごとにワークスペース/ファイルブラウザパネルが自動で開きます。手動でいつでも閉じられます。',
    settings_label_session_jump_buttons: 'セッションジャンプボタンを表示',
    settings_desc_session_jump_buttons: '長いセッション履歴を読むときに、浮動表示の「開始」と「末尾」ボタンを表示します。',

    settings_label_session_endless_scroll: '上スクロールで古いメッセージを読み込む',

    settings_desc_session_endless_scroll: '有効にすると、上にスクロールしたとき古いメッセージを自動で読み込みます。無効の場合は古いメッセージボタンを使います。',

    settings_label_tab_visibility: 'サイドバータブ',
    settings_desc_tab_visibility: 'サイドバーとレールに表示するタブを選択します。チャットと設定は常に表示されます。',
    open_in_browser: 'ブラウザで開く',
    settings_dropdown_conversation: '会話',
    settings_dropdown_appearance: '外観',
    settings_dropdown_preferences: '環境設定',
    settings_dropdown_providers: 'プロバイダ',
    settings_dropdown_system: 'システム',
    settings_tab_conversation: '会話',
    settings_tab_appearance: '外観',
    settings_tab_preferences: '環境設定',
    settings_tab_plugins: 'プラグイン',
    settings_plugins_title: 'Plugins',  // TODO: translate
    settings_plugins_meta: 'View installed Hermes plugins and the lifecycle hooks they register. This panel is read-only.',  // TODO: translate
    settings_plugins_empty: 'No Hermes plugins are currently visible. Install or enable plugins from the Hermes CLI/config to see them here.',  // TODO: translate
    plugins_unnamed: 'Unnamed plugin',  // TODO: translate
    plugins_no_description: 'No description provided.',  // TODO: translate
    plugins_no_hooks: 'No registered lifecycle hooks',  // TODO: translate
    plugins_registered_hooks: 'Registered hooks',  // TODO: translate
    plugins_enabled: 'Enabled',  // TODO: translate
    plugins_disabled: 'Disabled',  // TODO: translate
    plugins_active_provider: 'Active (provider)',  // TODO: translate
    plugins_provider_no_hooks: 'Provider plugin — no agent-visibility hooks',  // TODO: translate
    plugins_load_failed: 'Failed to load plugins: ',  // TODO: translate
    settings_tab_system: 'システム',
    settings_title: '設定',
    settings_save_btn: '設定を保存',
    settings_label_model: 'デフォルトモデル',
    settings_desc_model: '新しい会話で使用されます。既存の会話は選択済みモデルを保持します。',
    settings_label_send_key: '送信キー',
    settings_label_theme: 'テーマ',
    settings_label_skin: 'スキン',
    settings_label_font_size: 'フォントサイズ',
    font_size_small: '小',
    font_size_default: 'デフォルト',
    font_size_large: '大',
    font_size_xlarge: '特大',
    settings_autosave_saving: '保存中…',
    settings_autosave_saved: '保存しました',
    settings_autosave_failed: '保存失敗',
    settings_autosave_retry: '再試行',
    settings_label_language: '言語',
    settings_label_quota_chip: 'コンポーザーにプロバイダーのクォータチップを表示',
    settings_desc_quota_chip: 'コンポーザーのフッターに残りクォータインジケーター（例: OpenRouter のクレジット残高）を表示します。デフォルトはオフ。有効にした場合、ラップトップや標準デスクトップの幅でコンポーザーが混雑しないよう、ワイドディスプレイ（≥1400px）でのみ表示されます。',
    settings_label_hide_suggestions: 'Hide new-chat suggestions',
    settings_desc_hide_suggestions: 'Hide the three default suggestion buttons on the empty new-chat screen to avoid accidental taps.',
    settings_label_token_usage: 'トークン使用量を表示',
    settings_label_sidebar_density: 'サイドバー密度',
    cmd_reasoning: '思考表示の切り替え (表示/非表示)、努力レベル設定、現在状態の確認',
    settings_label_external_sessions: '非WebUIセッションを表示',
    settings_label_previous_messaging_sessions: '以前のメッセージングセッションを表示',
    settings_label_sync_insights: 'インサイトに同期',
    settings_label_check_updates: 'アップデートを確認',
    settings_label_whats_new_summary: "Summarize What's New with AI",
    settings_label_bot_name: 'デフォルトのアシスタント名',
    settings_label_password: 'アクセスパスワード',
    settings_saved: '設定を保存しました',
    settings_save_failed: '保存失敗: ',
    settings_load_failed: '設定の読み込みに失敗: ',
    settings_saved_pw: '設定を保存 — パスワード保護を有効化、このブラウザはサインイン状態を維持します',
    settings_saved_pw_updated: '設定を保存 — パスワードを更新しました',
    // login page (used server-side via /api/i18n/login endpoint)
    login_title: 'サインイン',
    login_subtitle: 'パスワードを入力して続行',
    login_placeholder: 'パスワード',
    login_btn: 'サインイン',
    login_invalid_pw: 'パスワードが無効です',
    login_conn_failed: '接続失敗',
    dialog_confirm_title: '操作の確認',
    dialog_prompt_title: '値を入力',
    dialog_confirm_btn: '確認',
    discard: '破棄',
    clear: 'クリア',
    create: '作成',
    remove: '削除',
    project_name_prompt: 'プロジェクト名:',
    // Sidebar & Tabs
    tab_chat: 'チャット',
    tab_tasks: 'タスク',
    tab_skills: 'スキル',
    tab_memory: 'メモリ',
    tab_workspaces: 'スペース',
    tab_profiles: 'プロファイル',
    tab_kanban: 'カンバン',
    kanban_board: 'ボード',
    kanban_visible_tasks: '表示中のタスク: {0}',
    kanban_search_tasks: 'タスクを検索',
    kanban_all_assignees: '担当者: すべて',
    kanban_all_tenants: 'テナント: すべて',
    kanban_include_archived: 'アーカイブを含める',
    kanban_no_matching_tasks: '一致するタスクがありません',
    kanban_no_data: 'カンバンデータがありません',
    kanban_work_queue_hint: 'これは Hermes Agent のワークキューです。タスクを作成またはトリアージし、担当者を割り当て、Ready に移動すると、ディスパッチャーがそれをクレームします。',
    kanban_unavailable: 'カンバンを利用できません',
    kanban_read_only: '読み取り専用',
    kanban_empty: '空',
    kanban_task: 'タスク',
    kanban_no_description: '説明なし',
    kanban_refresh: '更新',
    kanban_status_triage: 'トリアージ',
    kanban_status_todo: 'ToDo',
    kanban_status_ready: '準備完了',
    kanban_status_running: '実行中',
    kanban_status_blocked: 'ブロック中',
    kanban_status_done: '完了',
    kanban_status_original_hint: 'Actual status: {0}. This dialog only supports Triage/Todo/Ready edits.',
    kanban_comments_count: 'コメント ({0})',
    kanban_events_count: 'イベント ({0})',
    kanban_links: 'リンク',
    kanban_parents: '親',
    kanban_children: '子',
    kanban_runs_count: '実行 ({0})',
    kanban_no_comments: 'コメントなし',
    kanban_no_events: 'イベントなし',
    kanban_no_runs: '実行なし',
    kanban_title: 'タイトル',
    kanban_description: '説明',
    kanban_description_placeholder: '任意 — 何をすべきか、受け入れ基準、リンク',
    kanban_status: 'ステータス',
    kanban_assignee: '担当者',
    kanban_assignee_placeholder: '任意 — 空欄で任意のワーカーに',
    kanban_tenant: 'テナント',
    kanban_tenant_placeholder: '任意 — プロジェクトまたはチームのスラッグ',
    kanban_priority: '優先度',
    kanban_priority_hint: '値が大きいほど優先されます。既定値は 0。',
    kanban_title_required: 'タイトルは必須です。',
    kanban_edit_task: 'タスクを編集',
    kanban_run_dispatcher: 'ディスパッチャーを実行',
    kanban_run_dispatcher_confirm: 'このボードの「Ready」タスクを取得し、ワーカーサブプロセスを起動します(クリック1回につき最大8件)。続行しますか?',
    kanban_assignee_profiles_label: 'Hermes プロファイル',
    kanban_assignee_other_label: 'その他 (CLI レーン / 削除されたプロファイル)',
    kanban_assignee_unassigned: '— 未割当 (自動実行されません) —',
    kanban_ready_needs_assignee: '担当者「未割当」+「Ready」を選択しました。ディスパッチャーはこのタスクをスキップします。続行するにはもう一度送信するか、プロファイルを選んでください。',
    kanban_dispatch_preview_prefix: 'プレビュー:',
    kanban_dispatch_run_prefix: '実行:',
    kanban_dispatch_spawned: '起動',
    kanban_dispatch_promoted: '昇格',
    kanban_dispatch_reclaimed: '再取得',
    kanban_dispatch_skipped_unassigned: 'スキップ (担当者なし)',
    kanban_dispatch_skipped_nonspawnable: 'スキップ (不明なプロファイル)',
    kanban_dispatch_auto_blocked: '自動ブロック',
    kanban_dispatch_timed_out: 'タイムアウト',
    kanban_dispatch_crashed: 'クラッシュ',
    kanban_new_task: '新規タスク',
    kanban_add_comment: 'コメント追加',
      kanban_only_mine: '自分のみ',
      kanban_bulk_action: '一括操作',
      kanban_nudge_dispatcher: 'ディスパッチャープレビュー',
      kanban_stats: '統計',
      kanban_worker_log: 'ワーカーログ',
      kanban_block: 'ブロック',
      kanban_unblock: 'ブロック解除',
      kanban_back_to_board: 'ボードに戻る',
      kanban_lanes_by_profile: 'プロファイル別レーン',
      kanban_new_board: '新規ボード…',
      kanban_rename_board: '現在のボード名を変更…',
      kanban_archive_board: '現在のボードをアーカイブ…',
      kanban_archive_board_confirm: 'ボード "{name}" をアーカイブしますか? タスクはディスク上に残り、kanban/boards/_archived/ から復元できます。',
      kanban_board_archived: 'ボードをアーカイブしました',
      kanban_board_name: '名前',
      kanban_board_slug: 'スラッグ (小文字・ハイフン)',
      kanban_board_description: '説明 (任意)',
      kanban_board_icon: 'アイコン (絵文字、任意)',
      kanban_board_color: '色 (任意)',
      kanban_board_name_required: '名前は必須です',
      kanban_board_slug_required: 'スラッグは必須です',
      kanban_card_complete: '完了',
      kanban_card_archive: 'アーカイブ',
      kanban_unassigned: '未割り当て',
    kanban_status_archived: 'アーカイブ済み',
    tab_todos: 'ToDo',
    tab_insights: 'インサイト',
    tab_dashboard: 'Hermes ダッシュボード',
    dashboard_loopback_warning: 'ダッシュボードはサーバー上のループバック専用です。サーバー上で閲覧するか、--host 0.0.0.0（安全ではありません）で再起動してください。',
    tab_logs: 'ログ',
    tab_settings: '設定',
    new_conversation: '新しい会話',
    filter_conversations: '会話を絞り込み...',
    session_time_unknown: '不明',
    session_time_minutes_ago: (n) => `${n}分前`,
    session_time_hours_ago: (n) => `${n}時間前`,
    session_time_days_ago: (n) => `${n}日前`,
    session_time_last_week: '1週間前',
    session_time_bucket_today: '今日',
    session_time_bucket_yesterday: '昨日',
    session_time_bucket_this_week: '今週',
    session_time_bucket_last_week: '先週',
    session_time_bucket_older: 'それ以前',
    scheduled_jobs: 'スケジュールジョブ',
    new_job: '新規ジョブ',
    loading: '読み込み中...',
    search_skills: 'スキルを検索...',
    new_skill: '新規スキル',
    personal_memory: '個人メモリ',
    current_task_list: '現在のタスクリスト',
    // Logs
    logs_title: 'ログ',
    logs_file: 'ファイル',
    logs_tail: '末尾',
    logs_auto_refresh: '自動更新 (5秒)',
    logs_wrap: '行を折り返す',
    logs_copy_all: 'すべてコピー',
    logs_empty: 'ログはまだありません。',
    logs_loading: 'ログを読み込み中…',
    logs_load_failed: 'ログの読み込みに失敗しました',
    logs_status_idle: 'ログファイルを選択すると最近の行を表示します。',
    logs_no_mtime: '未書き込み',
    logs_truncated_hint: '大きなログファイルの末尾を表示しています。メモリ使用量を抑えるため、古いデータは省略されました。',
    logs_copied: 'ログをコピーしました',
    logs_severity: '重大度',
    logs_severity_all: 'すべて',
    logs_severity_errors: 'エラー',
    logs_severity_warnings: '警告+',
    logs_filter_active: '表示中（フィルター有効）',

    // Insights
    insights_title: '使用状況分析',
    insights_sessions: 'セッション',
    insights_messages: 'メッセージ',
    insights_tokens: 'トークン',
    insights_cost: '推定コスト',
    insights_no_cost: 'N/A',
    insights_models: 'モデル',
    insights_activity_by_day: '日別アクティビティ',
    insights_activity_by_hour: '時間別アクティビティ',
    insights_peak_hour: 'ピーク: {hour}',
    insights_token_breakdown: 'トークン内訳',
    insights_input_tokens: '入力',
    insights_output_tokens: '出力',
    insights_total: '合計',
    insights_daily_tokens: '日別トークン',
    insights_model_name: 'モデル',
    insights_model_sessions: 'セッション',
    insights_model_tokens: 'トークン',
    insights_model_cost: 'コスト',
    insights_model_share: 'シェア',
    insights_no_usage_data: '使用データはまだありません',
    insights_footer: '直近 {days} 日間のデータを表示',
    workspace_desc: 'セッション用のワークスペースを追加・切り替えします。',
    session_meta_messages: (n) => `${n} 件`,
    session_meta_children: (n) => `${n} 子`,
    session_meta_segments: (n) => `${n} セグメント`,
    session_lineage_segment_untitled: '無題のセグメント',
    session_lineage_segment_open: '系譜セグメントを開く',
    new_profile: '新規プロファイル',
    transcript: 'トランスクリプト',
    download_transcript: 'Markdown としてダウンロード',
    import: 'インポート',
    export_session_json: 'JSON',
    export_session_json_tooltip: 'セッション全体をJSONとしてエクスポート',
    import_session_json_tooltip: 'JSONからセッションをインポート',
    clear_conversation_btn_tooltip: 'この会話のすべてのメッセージをクリア',
    // Settings detail
    settings_label_rtl: 'チャットの右から左へのレイアウト',
    settings_desc_rtl: 'アラビア語やヘブライ語のような言語向けに、チャットメッセージとコンポーザー入力の配置を反転します。チャット領域のみに影響し、サイドバーや他のパネルは左から右のままです。',
    settings_label_sound: '通知音',
    settings_desc_sound: 'アシスタントが応答を完了したときに音を鳴らします。',
    // TTS (#499)
    tts_listen: '読み上げ',
    tts_not_supported: 'このブラウザは音声合成に対応していません。',
    settings_label_tts: '応答の読み上げ (TTS)',
    settings_desc_tts: 'アシスタントの各メッセージにスピーカーボタンを表示し、ブラウザの音声合成で読み上げます。',
    settings_label_tts_auto_read: '応答を自動で読み上げ',
    settings_desc_tts_auto_read: '新しいアシスタント応答が完了するたびに自動で読み上げます。入力中は一時停止します。',
    // Composer voice-mode pref (#1488)
    settings_label_voice_mode: 'ハンズフリー音声モードのボタン',
    settings_desc_voice_mode: '音声波形ボタンをディクテーションマイクの隣に表示します。発話の合間に自動送信し、返答を読み上げます。音声認識と TTS の両方をサポートするブラウザが必要です。',
    settings_label_tts_voice: '声',
    settings_desc_tts_voice: '優先する声。ブラウザで利用可能な声から選択されます。',
    settings_label_tts_rate: '読み上げ速度',
    settings_label_tts_pitch: '読み上げピッチ',
    settings_label_notifications: 'ブラウザ通知',
    settings_desc_notifications: 'アプリがバックグラウンドの間に応答が完了したらシステム通知を表示します。',
    settings_desc_token_usage: 'アシスタント応答の下に入力/出力トークン数を表示します。/usage でも切替可能。',
    settings_label_api_redact: 'API 応答内の機密データをマスク',
    settings_desc_api_redact: 'セルフホスト利用者は透明性のため無効化できます (共有インスタンスでは非推奨)。',
    settings_sidebar_density_compact: 'コンパクト',
    settings_sidebar_density_detailed: '詳細',
    settings_desc_sidebar_density: '左サイドバーのセッション一覧に表示するメタデータ量を制御します。',
    settings_label_auto_title_refresh: 'タイトル自動更新',
    settings_auto_title_refresh_off: 'オフ',
    settings_auto_title_refresh_5: '5 回ごと',
    settings_auto_title_refresh_10: '10 回ごと',
    settings_auto_title_refresh_20: '20 回ごと',
    settings_desc_auto_title_refresh: '最新のやり取りに基づいてセッションタイトルを自動再生成し、会話の進行に合わせて適切に保ちます。LLM タイトル生成モデルの設定が必要です。',
    settings_desc_external_sessions: 'CLI、Telegram、Discord、Slack その他のチャネルからの会話をセッション一覧に表示します。クリックでインポートして続行できます。',
    settings_desc_previous_messaging_sessions: 'reset または compression によって置き換えられた以前の Discord、Telegram、Slack、Weixin セッションを表示します。',
    settings_desc_sync_insights: 'WebUI のトークン使用量を state.db にミラーし、hermes /insights にブラウザセッションのデータを含めます。デフォルトはオフ。',
    settings_desc_check_updates: 'WebUI または Agent の新しいバージョンが利用可能な時にバナーを表示します。バックグラウンドで定期的に git fetch を実行します。',
    settings_desc_whats_new_summary: "Changes the What's New action from opening the raw diff first to generating a short, human-readable summary. The regular diff comparison stays available after the summary.",
    settings_desc_bot_name: 'デフォルトプロファイルでのみ使用されます。他のプロファイルはそれぞれのプロファイル名を使用します。',
    settings_desc_password: '新しいパスワードを入力すると設定または変更します。空欄なら現在の設定を維持。',
    password_placeholder: '新しいパスワードを入力…',
    password_env_var_locked: '現在 HERMES_WEBUI_PASSWORD 環境変数が設定されており優先されます。ここで管理するには変数を解除してサーバーを再起動してください。',
    password_env_var_locked_placeholder: 'ロック中: HERMES_WEBUI_PASSWORD 環境変数が設定されています',
    disable_auth: '認証を無効化',
    sign_out: 'サインアウト',
    // Providers panel
    providers_tab_title: 'プロバイダ',
    providers_section_title: 'プロバイダ',
    providers_section_meta: 'AI プロバイダの APIキー を管理します。変更は即時反映されます。',
    providers_status_configured: 'APIキー設定済み',
    providers_status_not_configured: 'APIキーなし',
    providers_status_oauth: 'OAuth',
    providers_status_api_key: 'APIキー',
    providers_status_not_configured_label: '未設定',
    providers_oauth_hint: 'OAuth 認証済み。APIキーは不要です。',
    providers_oauth_config_yaml_hint: 'config.yaml でトークンが設定されています。更新するには config.yaml の providers セクションを編集するか hermes auth を実行してください。',
    providers_oauth_not_configured_hint: '未認証です。ターミナルで hermes auth を実行してこのプロバイダを設定してください。',
    providers_save: '保存',
    providers_remove: '削除',
    providers_saving: '保存中…',
    providers_removing: '削除中…',
    providers_enter_key: 'APIキーを入力してください',
    providers_empty: '設定可能なプロバイダが見つかりません。',
    providers_key_updated: 'APIキーを保存しました',
    providers_key_removed: 'APIキーを削除しました',
    providers_key_placeholder_new: 'sk-...',
    providers_key_placeholder_replace: '置き換える新しいキーを入力…',
    provider_quota_title: 'アクティブなプロバイダーのクォータ',
    provider_quota_active_provider: 'アクティブなプロバイダー',
    provider_quota_last_checked_after_refresh: '更新後に最終確認',
    provider_quota_last_checked: '最終確認 {0}',
    provider_quota_refresh_usage: '使用量を更新',
    provider_quota_refreshing: '更新中...',
    provider_quota_refresh_title: 'プロバイダーの使用制限を今すぐ更新',
    provider_quota_refresh_succeeded: 'プロバイダーの使用量を更新しました',
    provider_quota_refresh_failed: 'プロバイダーの使用量の更新に失敗しました',
    provider_quota_session_limit: '5時間制限',
    provider_quota_weekly_limit: '週間制限',
    provider_quota_window_fallback: 'ウィンドウ',
    provider_quota_metric_remaining: '残り',
    provider_quota_metric_used: '使用済み',
    provider_quota_metric_limit: '制限',
    provider_quota_status_available: '利用可能',
    provider_quota_status_exhausted: '使い切り済み',
    provider_quota_status_unavailable: '利用不可',
    provider_quota_status_failed: '失敗',
    provider_quota_status_checked: '確認済み',
    provider_quota_status_no_key: 'キーなし',
    provider_quota_status_invalid_key: '無効なキー',
    provider_quota_status_unsupported: '未対応',
    provider_quota_used_meta: '{0} 使用済み',
    provider_quota_resets_meta: '{0} にリセット',
    provider_quota_credential_pool: '認証情報プール',
    provider_quota_credential_label: '認証情報 {0}',
    provider_quota_pool_plans: 'プラン: {0}',
    provider_quota_pool_no_windows: 'アカウント制限ウィンドウは報告されていません。',
    provider_quota_account_limits_loaded: 'アカウント制限を読み込みました。',
    provider_quota_unavailable: 'クォータ状態は利用できません',
    provider_quota_retry_after: '{0} 以降に再試行',
    provider_quota_pool_summary_available: '{0}/{1} 利用可能',
    provider_quota_pool_summary_exhausted: '{0} 使い切り済み',
    provider_quota_pool_summary_failed: '{0} 失敗',
    provider_quota_pool_summary_checked: '{0} 確認済み',
    cancel: 'キャンセル',
    create_job: 'ジョブを作成',
    save_skill: 'スキルを保存',
    editing: '編集中',
    // Empty state
    empty_title: '何をお手伝いしましょう?',
    empty_subtitle: '何でも質問する、コマンド実行、ファイル探索、スケジュールタスク管理ができます。',
    suggest_files: 'このワークスペースにあるファイルは?',
    suggest_schedule: '今日のスケジュールは?',
    suggest_plan: '小さなプロジェクトの計画を手伝って。',
    // onboarding
    onboarding_badge: '初回起動',
    onboarding_title: 'Hermes Web UI へようこそ',
    onboarding_lead: 'クイックガイドで Hermes を確認し、プロバイダ設定を保存し、ワークスペースとモデルを選択し、必要ならパスワードでアプリを保護します。',
    onboarding_back: '戻る',
    onboarding_continue: '続ける',
    onboarding_skip: 'セットアップをスキップ',
    onboarding_skipped: 'セットアップをスキップ — 既存設定を使用します。',
    onboarding_open: 'Hermes を開く',
    onboarding_step_system_title: 'システム確認',
    onboarding_step_system_desc: 'Hermes Agent と設定の可視性を確認します。',
    onboarding_step_setup_title: 'プロバイダ設定',
    onboarding_step_setup_desc: '最低限の Hermes プロバイダ設定を保存します。',
    onboarding_step_workspace_title: 'ワークスペース + モデル',
    onboarding_step_workspace_desc: '新規セッションとチャットのデフォルトを選択します。',
    onboarding_step_password_title: 'パスワード (任意)',
    onboarding_step_password_desc: '共有前に Web UI を保護します。',
    onboarding_step_finish_title: '完了',
    onboarding_step_finish_desc: '確認してアプリに入ります。',
    onboarding_notice_system_ready: 'Web UI から Hermes Agent へ到達できそうです。',
    onboarding_notice_system_unavailable: 'Hermes Agent はまだ完全には利用できません。Bootstrap でインストールできますが、プロバイダ設定にはターミナルが必要な場合があります。',
    onboarding_check_agent: 'Hermes Agent',
    onboarding_check_agent_ready: '検出済み・インポート可能',
    onboarding_check_agent_missing: '不在または部分的にしかインポートできません',
    onboarding_check_password: 'パスワード',
    onboarding_check_password_enabled: '既に有効',
    onboarding_check_password_disabled: '未有効',
    onboarding_check_provider: 'プロバイダ設定',
    onboarding_check_provider_ready: 'チャット可能',
    onboarding_check_provider_partial: '保存済みだが不完全',
    onboarding_check_provider_pending: '検証が必要',
    onboarding_config_file: '設定ファイル:',
    onboarding_env_file: '.env ファイル:',
    onboarding_unknown: '不明',
    onboarding_current_provider: '現在の設定:',
    onboarding_missing_imports: '不足しているインポート:',
    onboarding_notice_setup_required: 'シンプルなプロバイダ経路をここで選んでください。高度な OAuth フローは現状 Hermes CLI 側で扱います。',
    onboarding_notice_setup_already_ready: '動作する Hermes プロバイダ設定が既に検出されています。維持するか、ここで置き換えできます。',
    onboarding_oauth_provider_ready_title: 'プロバイダは認証済み',
    onboarding_oauth_provider_ready_body: 'このインスタンスは Hermes CLI で設定された OAuth プロバイダ (<strong>{provider}</strong>) を使用します。APIキーは不要 — 続けるをクリックしてセットアップを完了してください。',
    onboarding_oauth_provider_not_ready_title: 'OAuth プロバイダは未認証',
    onboarding_oauth_provider_not_ready_body: 'このインスタンスは <strong>{provider}</strong> を使用しますが、これは APIキー ではなく OAuth を使用します。ターミナルで <code>hermes auth</code> または <code>hermes model</code> を実行して認証し、Web UI を再読み込みしてください。',
    onboarding_oauth_switch_hint: 'または下から別のプロバイダを選び、APIキー設定に切り替え:',
    oauth_login_codex: 'Codex (ChatGPT) でログイン',
    oauth_codex_step1: 'ステップ 1: この URL にアクセスしてコードを入力',
    oauth_codex_step2: 'ステップ 2: ページにこのコードを入力',
    oauth_codex_polling: '認可待ち...',
    oauth_codex_success: 'Codex OAuth ログインに成功しました!',
    oauth_codex_error: 'OAuth ログインに失敗しました',
    oauth_codex_expired: 'コードの有効期限が切れました。もう一度お試しください',
    onboarding_notice_workspace: 'これらの値は通常アプリと同じ設定 API を使用します。',
    onboarding_workspace_label: 'ワークスペース',
    onboarding_workspace_or_path: 'またはワークスペースのパスを入力',
    onboarding_workspace_placeholder: '/home/you/workspace',
    onboarding_provider_label: 'セットアップモード',
    onboarding_quick_setup_badge: 'クイックセットアップ',
    provider_category_easy_start: '簡単スタート',
    provider_category_self_hosted: 'オープン / セルフホスト',
    provider_category_specialized: '専門用途',
    onboarding_api_key_label: 'APIキー',
    onboarding_api_key_placeholder: '空欄で既存の保存済みキーを維持',
    onboarding_api_key_label_optional: 'APIキー (任意)',
    onboarding_api_key_placeholder_optional: 'キー不要のサーバーの場合は空欄にしてください',
    onboarding_api_key_help_keyless: 'LM Studio / Ollama / vLLM の多くはキーなしで動作します。認証が不要なサーバーの場合は空欄にしてください。『接続テスト』で確認できます。',
    onboarding_api_key_help_prefix: 'Hermes の .env ファイルにシークレットとして保存されます — 使用変数:',
    onboarding_base_url_label: 'ベース URL',
    onboarding_base_url_placeholder: 'https://your-endpoint.example/v1',
    onboarding_base_url_help: 'OpenAI 互換ルーター、セルフホストサーバー、LiteLLM、Ollama、LM Studio、vLLM、または同様のエンドポイントで使用してください。',
    onboarding_model_label: 'デフォルトモデル',
    onboarding_workspace_help: 'セットアップ完了後の新規チャットで Hermes が使用するモデルを選択してください。',
    onboarding_custom_model_placeholder: 'your-model-name',
    onboarding_custom_model_help: 'カスタムエンドポイントの場合、サーバーが期待する正確なモデル ID を入力してください。',
    onboarding_notice_password_enabled: 'パスワードは既に設定済みです。置き換える場合のみ新しいものを入力してください。',
    onboarding_notice_password_recommended: '任意ですが、localhost 以外で UI を公開する場合は推奨します。',
    onboarding_password_label: 'パスワード (任意)',
    onboarding_password_placeholder: '空欄でスキップ',
    onboarding_password_help: 'パスワードは既存の設定 API 経由で保存され、サーバー側でハッシュ化されます。',
    onboarding_notice_finish: '後で設定からいつでも変更できます。',
    onboarding_not_set: '未設定',
    onboarding_password_will_enable: '有効化されます',
    onboarding_password_will_replace: '置き換えられます',
    onboarding_password_keep_existing: '現在のパスワードを維持',
    onboarding_password_remains_disabled: '無効のまま',
    onboarding_password_skipped: '今回はスキップ',
    onboarding_finish_help: '完了すると <code>onboarding_completed</code> が設定に保存され、通常アプリへ入ります。',
    onboarding_error_choose_workspace: '続行する前にワークスペースを選択してください。',
    onboarding_error_choose_model: '続行する前にモデルを選択してください。',
    onboarding_error_provider_required: '続行する前にセットアップモードを選択してください。',
    onboarding_error_base_url_required: 'カスタムエンドポイントにはベース URL が必要です。',
    onboarding_probe_test_button: '接続テスト',
    onboarding_probe_probing: '接続をテスト中…',
    onboarding_probe_ok: '接続成功。{n} 個のモデルが利用可能です。',
    onboarding_probe_error_generic: '設定されたベース URL に到達できません。',
    onboarding_probe_error_invalid_url: 'ベース URL は http:// または https:// で始まる必要があります。',
    onboarding_probe_error_dns: 'ホストを名前解決できませんでした。URL を確認するか、ホストの IP アドレスを使用してください。',
    onboarding_probe_error_connect_refused: '接続が拒否されました。サーバーが起動していない可能性があります。Docker 内からは localhost ではなくホスト IP を試してください。',
    onboarding_probe_error_timeout: '時間内に応答がありません。サーバーが起動しているか、URL が正しいか確認してください。',
    onboarding_probe_error_http_4xx: 'クライアントエラーが返されました。認証設定と URL パス (通常は /v1) を確認してください。',
    onboarding_probe_error_http_5xx: 'サーバーエラーが返されました。LM Studio / Ollama のログを確認してください。',
    onboarding_probe_error_parse: 'モデル一覧が期待する形式で返されませんでした。URL が OpenAI 互換 API のルートを指しているか確認してください。',
    onboarding_probe_error_unreachable: '設定されたベース URL に到達できません。',
    onboarding_error_probe_failed: 'ベース URL を検証できませんでした。',
    onboarding_error_workspace_required: 'ワークスペースは必須です。',
    onboarding_error_model_required: 'モデルは必須です。',
    onboarding_complete: 'オンボーディング完了',

    // panel/runtime i18n
    error_prefix: 'エラー: ',
    not_available: 'N/A',
    never: 'なし',
    add: '追加',
    add_failed: '追加失敗: ',
    remove_failed: '削除失敗: ',
    switch_failed: '切替失敗: ',
    name_required: '名前は必須です',
    content_required: '内容は必須です',
    view: '表示',
    dismiss: '閉じる',
    disable: '無効化',
    cron_no_jobs: 'スケジュールジョブが見つかりません。',
    cron_status_off: 'オフ',
    cron_status_paused: '一時停止',
    cron_status_error: 'エラー',
    cron_status_active: '有効',
    cron_status_running: '実行中…',
    cron_status_needs_attention: '要対応',
    cron_attention_desc: 'この繰り返しジョブには次回実行時刻がありません。スケジューラが次回実行時刻を計算できなかった可能性があります。',
    cron_attention_croniter_hint: 'Gateway ランタイムに croniter パッケージが不足している可能性があります。cron サポート付きで Gateway を再起動し、ジョブを再開してください。',
    cron_attention_resume: '再開して再計算',
    cron_jobs_project: 'Cronジョブ',
    cron_attention_run_once: '今すぐ1回実行',
    cron_attention_copy_diagnostics: '診断情報をコピー',
    cron_diagnostics_copied: 'Cron 診断情報をコピーしました',
    cron_next: '次回',
    cron_last: '前回',
    cron_run_now: '今すぐ実行',
    cron_pause: '一時停止',
    cron_resume: '再開',
    cron_job_name_placeholder: 'ジョブ名',
    cron_schedule_placeholder: 'スケジュール',
    cron_prompt_placeholder: 'プロンプト',
    cron_last_output: '前回の出力',
    cron_expand_prompt: 'プロンプトを展開',
    cron_collapse_prompt: 'プロンプトを折りたたむ',
    cron_expand_output: '出力を展開',
    cron_collapse_output: '出力を折りたたむ',
    cron_all_runs: 'すべての実行',
    cron_hide_runs: '実行履歴を隠す',
    cron_no_runs_yet: '(まだ実行されていません)',
    cron_schedule_required_example: 'スケジュールは必須です (例: "0 9 * * *" または "every 1h")',
    cron_schedule_required: 'スケジュールは必須です',
    cron_prompt_required: 'プロンプトは必須です',
    cron_job_created: 'ジョブを作成しました',
    cron_duplicate: '複製',
    cron_duplicated: 'ジョブを複製しました (一時停止)',
    cron_job_triggered: 'ジョブを起動しました',
    cron_job_paused: 'ジョブを一時停止しました',
    cron_job_resumed: 'ジョブを再開しました',
    cron_job_updated: 'ジョブを更新しました',
    cron_delete_confirm_title: 'Cronジョブを削除',
    cron_delete_confirm_message: 'この操作は取り消せません。',
    cron_job_deleted: 'ジョブを削除しました',
    cron_completion_status: (name, status) => `Cron "${name}" ${status}`,
    status_failed: '失敗',
    status_completed: '完了',
    todos_no_active: 'このセッションにアクティブなタスクリストがありません。',
    clear_conversation_title: '会話をクリア',
    clear_conversation_message: 'すべてのメッセージをクリアしますか? この操作は取り消せません。',
    clear_failed: 'クリア失敗: ',
    skills_no_match: '一致するスキルがありません。',
    linked_files: 'リンクされたファイル',
    skill_load_failed: 'スキルを読み込めませんでした: ',
    skill_file_load_failed: 'ファイルを読み込めませんでした: ',
    skill_name_required: 'スキル名は必須です',
    skill_updated: 'スキルを更新しました',
    skill_created: 'スキルを作成しました',
    skill_deleted: 'スキルを削除しました',
    skill_delete_confirm: 'スキル "{0}" を削除しますか?',
    skills_empty_title: 'スキルを選択',
    skills_empty_sub: 'サイドバーからスキルを選んで内容を表示するか、新しいスキルを作成してください。',
    skills_edit: '編集',
    skills_delete: '削除',
    skills_back_to: '{0} に戻る',
    tasks_empty_title: 'スケジュールジョブを選択',
    tasks_empty_sub: 'サイドバーからジョブを選んで詳細と実行履歴を表示するか、新規作成してください。',
    workspaces_empty_title: 'スペースを選択',
    workspaces_empty_sub: 'サイドバーからスペースを選んでファイルと設定を表示するか、新しく追加してください。',
    profiles_empty_title: 'プロファイルを選択',
    profiles_empty_sub: 'サイドバーからエージェントプロファイルを選んで設定を表示・編集するか、新規作成してください。',
    memory_notes_label: 'メモリ (ノート)',
    memory_saved: 'メモリを保存しました',
    my_notes: 'マイノート',
    user_profile: 'ユーザープロファイル',
    no_notes_yet: 'まだノートはありません。',
    no_profile_yet: 'まだプロファイルはありません。',
    agent_soul: 'エージェントソウル',
    no_soul_yet: 'ソウルがまだ定義されていません。',
    workspace_choose_path: 'ワークスペースのパスを選択',
    workspace_choose_path_meta: '検証済みパスを追加してこの会話を切り替え',
    workspace_manage: 'ワークスペースを管理',
    workspace_manage_meta: 'スペースパネルを開く',
    workspace_use_title: '現在のセッションで使用',
    workspace_use: '使用',
    workspace_add_path_placeholder: 'ワークスペースパスを追加 (例: /home/user/my-project)',
    workspace_paths_validated_hint: '保存前に既存ディレクトリとして検証されます。',

    workspace_drag_hint: 'ドラッグして並び替え',
    workspace_reorder_failed: '並び替え失敗',
    workspace_added: 'ワークスペースを追加しました',
    workspace_renamed: 'ワークスペース名を変更しました',
    workspace_remove_confirm_title: 'ワークスペースを削除',
    workspace_remove_confirm_message: (path) => `"${path}" を削除しますか?`,
    workspace_removed: 'ワークスペースを削除しました',
    workspace_switch_prompt_title: 'ワークスペースを切り替え',
    workspace_switch_prompt_message: '追加してこの会話を切り替える絶対パスを入力してください。',
    workspace_switch_prompt_confirm: '切り替え',
    workspace_switch_prompt_placeholder: '/Users/you/project',
    workspace_not_added: 'ワークスペースは追加されませんでした',
    workspace_already_saved: 'ワークスペースは既に保存済み — 一覧から選択してください',
    workspace_busy_switch: 'エージェント実行中はワークスペースを切り替えできません',
    discard_file_edits_title: 'ファイル編集を破棄しますか?',
    discard_file_edits_message: 'ワークスペース切替でプレビュー内の未保存編集が破棄されます。',
    workspace_switched_to: (name) => `${name} に切り替えました`,
    profiles_no_profiles: 'プロファイルが見つかりません。',
    profile_api_keys_configured: 'APIキー設定済み',
    profile_gateway_running: 'Gateway 実行中',
    profile_gateway_stopped: 'Gateway 停止中',
    profile_active: 'アクティブ',
    profile_no_configuration: '設定なし',
    profile_skill_count: (count) => `${count} 件のスキル`,
    profile_use: '使用',
    profile_switch_title: 'このプロファイルに切り替え',
    profile_delete_title: 'このプロファイルを削除',
    profile_default_label: '(デフォルト)',
    profile_name_placeholder: 'プロファイル名 (小文字 a-z 0-9 ハイフン)',
    profile_clone_label: 'アクティブプロファイルから設定をコピー',
    profile_model_label: 'モデル / プロバイダー',
    profile_model_hint: 'この新しいプロファイルで使う設定済みプロバイダーとモデルを選択します。',
    profile_model_use_default: 'アクティブプロファイルのデフォルトを使用',
    profile_base_url_placeholder: 'ベース URL (任意、例: http://localhost:11434)',
    profile_api_key_placeholder: 'APIキー (任意)',
    manage_profiles: 'プロファイルを管理',
    profiles_load_failed: 'プロファイルの読み込みに失敗しました',
    profile_switched_new_conversation: (name) => `プロファイルを切替: ${name} — 新しい会話を開始しました`,
    profile_switched: (name) => `プロファイルを切替: ${name}`,
    profile_name_rule: '小文字、数字、ハイフン、アンダースコアのみ',
    profile_base_url_rule: 'ベース URL は http:// または https:// で始める必要があります',
    profile_created: (name) => `プロファイルを作成: ${name}`,
    profile_delete_confirm_title: (name) => `プロファイル "${name}" を削除しますか?`,
    profile_delete_confirm_message: 'このプロファイルのすべてのセッション、設定、スキル、メモリが完全に削除されます。この操作は取り消せません。',
    profile_deleted: (name) => `プロファイルを削除: ${name}`,
    active_conversation_none: 'アクティブな会話が選択されていません。',
    active_conversation_meta: (title, count) => `${title} · ${count} 件のメッセージ`,
    settings_unsaved_changes: '未保存の変更があります。',
    sign_out_failed: 'サインアウト失敗: ',
    disable_auth_confirm_title: 'パスワード保護を無効化',
    disable_auth_confirm_message: '誰でもこのインスタンスにアクセスできるようになります。',
    auth_disabled: '認証無効化 — パスワード保護を解除しました',
    disable_auth_failed: '認証の無効化に失敗: ',
    bg_error_single: (title) => `"${title}" でエラーが発生しました`,
    bg_error_multi: (count) => `${count} 件のセッションでエラーが発生しました`,
    // skill form
    skill_name: '名前',
    skill_category: 'カテゴリ',
    skill_category_placeholder: '任意、例: devops',
    skill_content: 'SKILL.md の内容',
    skill_content_placeholder: 'YAML フロントマター + Markdown 本文',
    skill_rename_not_supported: 'スキルの名前変更には対応していません。新しいスキルを作成し、古いものを削除してください。',
    skill_metadata: 'メタデータ',
    // cron form
    cron_name_label: '名前',
    cron_name_placeholder: '任意',
    cron_schedule_label: 'スケジュール',
    cron_schedule_hint: "繰り返し実行には 'every 1h' または Cron 式を使います。'30m' のような期間だけの指定は 1 回だけ実行されます。",
    cron_schedule_once_warning: "'30m' のような期間指定は 1 回だけ実行され、実行後に削除されます。繰り返すには 'every 30m' を使ってください。",
    cron_prompt_label: 'プロンプト',
    cron_deliver_label: '出力先',
    cron_deliver_local: 'ローカル (出力を保存のみ)',
    cron_profile_label: 'プロフィール',
    cron_profile_server_default: 'サーバーデフォルト',
    cron_profile_server_default_hint: '実行時に WebUI サーバーのデフォルトプロフィールを使用します。プロフィールのない既存ジョブはこの従来の動作を維持します。',
    cron_toast_notifications_label: '完了トースト',
    cron_toast_notifications_hint: 'この Cron が完了したときにトーストを表示します。オフでもタスクバッジと新規実行マーカーは更新されます。',
    cron_toast_notifications_enabled: '有効',
    cron_toast_notifications_disabled: '無効',
    cron_skills_label: 'スキル',
    cron_skills_placeholder: 'スキルを追加 (任意)…',
    cron_skills_edit_hint: 'スキル一覧は作成後に編集できません。',
    // workspace form
    workspace_name_label: '名前',
    workspace_name_placeholder: '任意の表示名',
    workspace_path_label: 'パス',
    workspace_path_required: 'パスは必須です',
    workspace_path_readonly: 'パスは変更できません。名前変更のみ可能です。',
    workspace_new_title: '新規スペース',
    // profile form
    profile_name_label: '名前',
    profile_base_url_label: 'ベース URL',
    profile_api_key_label: 'APIキー',
    cmd_yolo: 'YOLO モード切替 (承認スキップ)',
    yolo_no_session: 'アクティブなセッションがありません',
    yolo_enabled: '⚡ YOLO モード ON — このセッションは承認をスキップ',
    yolo_disabled: 'YOLO モード OFF',
    yolo_pill_label: 'YOLO',
    yolo_pill_title_active: 'YOLO モード有効 — クリックで無効化',
    approval_skip_all: '⚡ このセッションはすべてスキップ',
    approval_skip_all_title: 'このセッションのすべての承認プロンプトをスキップ',
    // composer action tooltips
    composer_send: 'メッセージを送信',
    composer_queue: 'メッセージをキュー',
    composer_interrupt: '中断して送信',
    composer_steer: '現在の応答をステア',
    composer_stop: '生成を停止',
    composer_disabled_clarify: '確認要求に応答してください',
    composer_disabled_compression: '圧縮の完了待ち',
    composer_disabled_empty: '送信するメッセージを入力してください',
    composer_mobile_workspace: 'ワークスペース',
    composer_mobile_model: 'モデル',
    composer_mobile_reasoning: '思考',
    composer_mobile_context: 'コンテキスト',
    media_audio_label: '音声',
    media_svg_label: '図',
    media_video_label: '動画',
    csv_loading: 'CSV を読み込み中',
    csv_too_large: 'CSV ファイルが大きすぎてインライン表示できません',
    csv_no_data: 'CSV ファイルのデータが不足しているためテーブル表示できません',
    csv_error: 'CSV ファイルの読み込みに失敗しました',
    csv_header_note: '先頭行をテーブルヘッダーとして表示',
    excalidraw_loading: '図を読み込み中',
    excalidraw_too_large: 'Excalidraw ファイルが大きすぎてインライン表示できません',
    excalidraw_invalid: '無効な Excalidraw ファイル形式',
    excalidraw_error: 'Excalidraw ファイルの読み込みに失敗しました',
    excalidraw_label: '図',
    excalidraw_download: 'ダウンロード',
    excalidraw_empty: '空の図',
    excalidraw_render_error: '図の描画に失敗しました',
    excalidraw_simplified: '簡略化された SVG プレビュー — Excalidraw キャンバスとピクセル単位では一致しません',
    // ── Checkpoints / Rollback ──
    checkpoint_title: 'チェックポイント',
    checkpoint_empty: 'このワークスペースのチェックポイントが見つかりません。',
    checkpoint_loading: 'チェックポイントを読み込み中…',
    checkpoint_error: 'チェックポイントの読み込みに失敗しました',
    checkpoint_date: '日時',
    checkpoint_message: 'メッセージ',
    checkpoint_files: 'ファイル',
    checkpoint_view_diff: '差分を表示',
    checkpoint_restore: '復元',
    checkpoint_restore_confirm_title: 'チェックポイントを復元しますか?',
    checkpoint_restore_confirm_message: (ckpt) => `ワークスペースをチェックポイント "${ckpt}" に復元しますか? ファイルが保存版で上書きされます。このチェックポイント後に追加されたファイルは削除されません。`,
    checkpoint_restored: 'チェックポイントを復元しました',
    checkpoint_diff_title: 'チェックポイントの変更内容',
    checkpoint_diff_no_changes: 'このチェックポイントと現在のワークスペースの間に差分はありません。',
    checkpoint_diff_files_changed: (n) => `${n} 件のファイルが変更されました`,
  },

  ru: {
    offline_title: 'Соединение потеряно',
    offline_browser_detail: 'Браузер сообщает, что это устройство офлайн.',
    offline_network_detail: 'Hermes сейчас недоступен из этого браузера.',
    offline_autorefresh: 'Я автоматически обновлю страницу, когда Hermes снова станет доступен.',
    offline_check_now: 'Проверить сейчас',
    offline_checking: 'Проверка…',
    offline_stream_waiting: 'Соединение потеряно. Ожидаю обновления…',
    _lang: 'ru',
    _label: 'Русский',
    _speech: 'ru-RU',
    cancelling: 'Отменяю…',
    cancel_failed: 'Не удалось отменить: ',
    mic_denied: 'Доступ к микрофону запрещён. Проверьте разрешения браузера.',
    mic_no_speech: 'Речь не распознана. Попробуйте ещё раз.',
    mic_network: 'Распознавание речи недоступно.',
    mic_error: 'Ошибка ввода речи: ',
    // Composer voice buttons (#1488)
    voice_dictate: 'Диктовка',
    voice_dictate_active: 'Остановить диктовку',
    voice_mode_toggle: 'Голосовой режим',
    voice_mode_toggle_active: 'Выйти из голосового режима',
    voice_listening: 'Слушаю…',
    voice_speaking: 'Говорю…',
    voice_thinking: 'Думаю…',
    voice_error: 'Голосовой ввод не поддерживается в этом браузере',
    voice_mode_active: 'Голосовой режим включён',
    voice_mode_off: 'Голосовой режим выключен',
    session_imported: 'Сеанс импортирован',
    import_failed: 'Не удалось импортировать: ',
    import_invalid_json: 'Неверный JSON',
    image_pasted: 'Изображение вставлено: ',
    edit_message: 'Редактировать сообщение',
    regenerate: 'Сгенерировать ответ заново',
    copy: 'Копировать',
    copied: 'Скопировано!',
    copy_failed: '\u041e\u0448\u0438\u0431\u043a\u0430 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f',
    selected_text_reply: 'Ответить с выделенным',
    selected_text_reply_title: 'Добавить выделенный текст чата как цитируемый контекст',
    selected_text_reply_appended: 'Выделенный текст добавлен в поле ввода',

    diff_loading: 'Загрузка diff',
    diff_error: 'Не удалось загрузить файл патча',
    diff_too_large: 'Файл патча слишком большой для отображения',
    tree_view: '樹狀',
    raw_view: '原始',
    parse_failed_note: 'parse failed',
    you: 'Вы',
    mcp_servers_title: 'MCP 伺服器',
    mcp_servers_desc: '管理 config.yaml 中設定的 MCP 伺服器。',
    mcp_no_servers: '未設定 MCP 伺服器。',
    mcp_add_server: '+ 新增伺服器',
    mcp_field_name: '伺服器名稱',
    mcp_transport_label: '傳輸類型',
    mcp_field_command: '命令',
    mcp_field_args: '參數（逗號分隔）',
    mcp_field_url: 'URL',
    mcp_field_timeout: '逾時（秒）',
    mcp_save: '儲存',
    mcp_cancel: '取消',
    mcp_name_required: '需要伺服器名稱。',
    mcp_url_required: 'HTTP 傳輸需要 URL。',
    mcp_command_required: 'stdio 傳輸需要命令。',
    mcp_saved: 'MCP 伺服器已儲存。',
    mcp_save_failed: '儲存 MCP 伺服器失敗。',
    mcp_delete_confirm_title: '刪除 MCP 伺服器',
    mcp_delete_confirm_message: '刪除 MCP 伺服器「{0}」？此操作無法撤銷。',
    mcp_deleted: 'MCP 伺服器已刪除。',
    mcp_delete_failed: '刪除 MCP 伺服器失敗。',
    mcp_load_failed: '載入 MCP 伺服器失敗。',
    mcp_restart_hint: 'Server changes are read-only here for now. Edit config.yaml and restart Hermes for changes to take effect.',
    mcp_toggle_followup: 'Enable/disable controls are intentionally deferred until MCP reload semantics are explicit.',
    mcp_status_active: 'Active',
    mcp_status_configured: 'Configured',
    mcp_status_disabled: 'Disabled',
    mcp_status_invalid_config: 'Invalid config',
    mcp_status_unknown: 'Unknown',
    mcp_tool_count: '{0} tools',
    mcp_enabled_yes: 'Enabled',
    mcp_enabled_no: 'Disabled',
    mcp_tools_title: 'MCP Tools',
    mcp_tools_desc: 'Search known tools across active MCP servers.',
    mcp_tools_search_placeholder: 'Search tools by name, server, or description…',
    mcp_tools_no_tools: 'No MCP tools are available from the active runtime inventory.',
    mcp_tools_no_matches: 'No MCP tools match your search.',
    mcp_tools_load_failed: 'Failed to load MCP tools.',
    mcp_tools_schema_empty: 'No schema parameters.',
    mcp_tools_runtime_note: 'Tool inventory only uses already-known active MCP runtime data; the WebUI does not start or probe servers.',
    mcp_tools_summary_no_matches: (query,total) => `No MCP tools matching “${query}” (${total} total MCP tools).`,
    mcp_tools_summary_none: 'No MCP tools to show.',
    mcp_tools_summary_matching: (query) => ` matching “${query}”`,
    mcp_tools_summary_total_note: (total) => ` (${total} total MCP tools)`,
    mcp_tools_summary_showing: (start,end,filtered,searchNote,totalNote,page,pages) => `Showing ${start}-${end} of ${filtered} MCP tools${searchNote}${totalNote}. Page ${page} of ${pages}.`,
    mcp_tools_page_size_prefix: 'Show',
    mcp_tools_page_size_suffix: 'per page',
    mcp_tools_per_page_aria: 'MCP tools per page',
    mcp_tools_inactive_configured_servers: (servers) => `Configured but inactive in this WebUI runtime: ${servers}.`,
    mcp_tools_pagination_label: 'MCP tools pagination',
    mcp_tools_previous_page: '‹ Prev',
    mcp_tools_previous_page_aria: 'Previous MCP tools page',
    mcp_tools_next_page: 'Next ›',
    mcp_tools_next_page_aria: 'Next MCP tools page',
    thinking: 'Думаю',
    expand_all: 'Развернуть всё',
    collapse_all: 'Свернуть всё',
    edit_failed: 'Не удалось отредактировать: ',
    regen_failed: 'Не удалось сгенерировать заново: ',
    reconnect_active: 'Ответ всё ещё генерируется. Обновить, когда будет готово?',
    reconnect_finished: 'Когда вы уходили, ответ ещё генерировался. Сообщения могли обновиться.',
    approval_heading: 'Требуется подтверждение',
    approval_desc_prefix: 'Обнаружена опасная команда',
    approval_btn_once: 'Разрешить один раз',
    approval_btn_once_title: 'Разрешить только эту команду (Enter)',
    approval_btn_session: 'Разрешить на этот сеанс',
    approval_btn_session_title: 'Разрешить для этого сеанса разговора',
    approval_btn_always: 'Всегда разрешать',
    approval_btn_always_title: 'Всегда разрешать команды по этому шаблону',
    approval_btn_deny: 'Запретить',
    approval_btn_deny_title: 'Запретить — не выполнять эту команду',
    approval_responding: 'Отвечаю…',
    untitled: 'Без названия',
    n_messages: (n) => `${n} сообщений`,
    load_older_messages: '↑ Прокрутите вверх или нажмите, чтобы загрузить ранние сообщения',
    session_jump_start: 'Начало',
    session_jump_start_label: 'Перейти к началу сессии',
    session_jump_end: 'Конец',
    session_jump_end_label: 'Перейти к концу сессии',
    jump_to_question: 'к вопросу',
    jump_to_question_label: 'Перейти к вопросу для этого ответа',
    queued_label: 'Отправить после ответа',
    queued_count: (n) => n === 1 ? '1 в очереди' : `${n} в очереди`,
    queued_cancel: 'Отменить сообщение',
    model_unavailable: ' (недоступна)',
    model_unavailable_title: 'Эта модель больше не входит в ваш текущий список провайдеров',
    provider_mismatch_warning: (m, p) =>
    `"${m}" может не работать с вашим настроенным провайдером (${p}). Всё равно отправить или запустите \`hermes model\` в терминале, чтобы переключиться.`,
    provider_mismatch_label: 'Несовпадение провайдера',
    model_not_found_label: 'Модель не найдена',
    model_custom_label: 'Пользовательский ID модели',
    model_custom_placeholder: 'например, openai/gpt-5.4',
    cmd_help: 'Показать доступные команды',
    cmd_clear: 'Очистить сообщения беседы',
    cmd_compact: 'Сжать контекст беседы',
    cmd_model: 'Переключить модель (например, /model gpt-4o)',
    cmd_workspace: 'Переключить рабочее пространство по названию',
    cmd_terminal: 'Открыть терминал рабочей области',
    cmd_new: 'Начать новую сессию чата',
    cmd_usage: 'Показать или скрыть использование токенов',
    cmd_theme: 'Переключить внешний вид (тема: system/dark/light, скин: default/ares/mono/slate/poseidon/sisyphus/charizard/sienna/catppuccin/nous/geist-contrast)',
    cmd_personality: 'Переключить личность агента',
    cmd_skills: 'Показать доступные навыки Hermes',
    available_commands: 'Доступные команды:',
    type_slash: 'Введите /, чтобы увидеть команды',
    conversation_cleared: 'Беседа очищена',
    model_usage: 'Использование: /model <name>',
    no_model_match: 'Нет модели, соответствующей "',
    switched_to: 'Переключено на ',
    workspace_usage: 'Использование: /workspace <name>',
    no_workspace_match: 'Нет рабочего пространства, соответствующего "',
    switched_workspace: 'Переключено на рабочее пространство: ',
    workspace_switch_failed: 'Не удалось переключить рабочее пространство: ',
    new_session: 'Новая сессия создана',
    new_session_creating: 'Создаём новую беседу…',
    compressing: 'Запрашиваю сжатие контекста...',
    token_usage_on: 'Отображение токенов включено',
    usage_personality_none: 'none', // TODO: translate
    token_usage_off: 'Отображение токенов выключено',
    usage_cache_hit_detail: 'Кэш: {0}% попаданий ({1} чтение / {2} запись)',
    usage_cached_percent: '{0}% из кэша',
    theme_usage: 'Использование: /theme ',
    theme_set: 'Тема: ',
    no_active_session: 'Нет активной сессии',
    cmd_queue: 'Поставить сообщение в очередь на следующий оборот',
    cmd_goal: 'Задать или проверить постоянную цель',
    goal_evaluating_progress: 'Evaluating goal progress…',
    goal_working_toward: 'Working toward goal…',
    goal_continuing_toast: 'Continuing toward goal…',
    goal_status_none: 'No active goal. Set one with /goal <text>.',
    goal_status_active: (turns, max_turns, goal) => `⊙ Goal (active, ${turns}/${max_turns} turns): ${goal}`,
    goal_status_paused: (turns, max_turns, reason, goal) => `⏸ Goal (paused, ${turns}/${max_turns}${reason ? `, ${reason}` : ''}): ${goal}`,
    goal_status_done: (turns, max_turns, goal) => `✓ Goal done (${turns}/${max_turns}): ${goal}`,
    goal_set: (turns, goal) => `⊙ Goal set (${turns}-turn budget): ${goal}`,
    goal_paused: (goal) => `⏸ Goal paused: ${goal}`,
    goal_resumed: (goal) => `▶ Goal resumed: ${goal}`,
    goal_cleared: 'Goal cleared.',
    goal_no_goal: 'No active goal.',
    goal_achieved: (reason) => `✓ Goal achieved: ${reason}`,
    goal_paused_budget_exhausted: (turns, max_turns) => `⏸ Goal paused — ${turns}/${max_turns} turns used. Use /goal resume to keep going, or /goal clear to stop.`,
    goal_continuing: (turns, max_turns, reason) => `↻ Continuing toward goal (${turns}/${max_turns}): ${reason}`,
    cmd_interrupt: 'Прервать текущий оборот и отправить новое сообщение',
    cmd_steer: 'Направить агента исправлением (переходит к прерыванию)',
    cmd_queue_no_msg: 'Использование: /queue <сообщение>',
    cmd_queue_not_busy: 'Нет активной задачи — просто отправьте',
    cmd_queue_confirm: 'Сообщение в очереди',
    cmd_interrupt_no_msg: 'Использование: /interrupt <сообщение>',
    cmd_interrupt_confirm: 'Прервано — отправка нового сообщения',
    cmd_steer_no_msg: 'Использование: /steer <сообщение>',
    cmd_steer_fallback: 'Steer недоступен — прервано и поставлено в очередь',
    cmd_steer_delivered: 'Steer доставлен — агент увидит его в следующем ответе инструмента',
    steer_leftover_queued: 'Steer поставлен в очередь на следующий ход',
    busy_steer_fallback: 'Steer недоступен — прервано',
    busy_interrupt_confirm: 'Прервано — отправка нового сообщения',
    settings_label_busy_input_mode: 'Режим ввода при занятости',
    settings_desc_busy_input_mode: 'Определяет поведение при отправке сообщения во время работы агента. Очередь ждёт; Прерывание отменяет и начинает заново; Steer внедряет коррекцию без прерывания.',
    settings_label_fade_text_effect: 'Эффект плавного появления текста',
    settings_desc_fade_text_effect: 'Плавно показывает новые слова во время ответа ассистента. Похоже на OpenWebUI; по умолчанию выключено для максимальной производительности.',
    settings_busy_input_mode_queue: 'Поставить в очередь',
    settings_busy_input_mode_interrupt: 'Прервать текущий оборот',
    settings_busy_input_mode_steer: 'Steer (прерывание + отправка)',

    no_personalities: 'Личности не найдены (добавьте их в ~/.hermes/personalities/)',
    clarify_heading: 'Требуется уточнение',
    clarify_hint: 'Выберите вариант или введите свой ответ ниже.',
    clarify_input_placeholder: 'Введите ответ…',
    clarify_other: 'Другое',
    clarify_responding: 'Отвечаю…',
    clarify_send: 'Отправить',
    cmd_compact_alias: 'Устаревший псевдоним для /compress',
    cmd_compress: 'Сжать контекст беседы (использование: /compress [тема])',
    ctx_compress_hint: 'Сжать контекст для освобождения места →',
    ctx_compress_action: '⚠ Сжать сейчас для освобождения контекста',
    command_label: 'Команда',
    compress_complete_label: 'Сжатие завершено',
    auto_compress_label: 'Автосжатие',
    compress_failed_label: 'Ошибка сжатия',
    compress_running_label: 'Сжатие…',
    context_compaction_label: 'Сжатие контекста',
    retrieval_context_label: 'Индексированный контекст',
    retrieval_context_preview: 'Предыдущие сообщения сохранены и доступны через инструменты контекста',
    preserved_task_list_label: 'Сохранённый список задач',
    focus_label: 'Фокус',
    model_search_no_results: 'Модели не найдены',
    model_group_configured: 'Настроенные',
    ws_search_placeholder: 'Поиск рабочих пространств…',
    ws_no_results: 'Рабочие пространства не найдены',
    workspace_new_worktree_conversation: 'Новый разговор в worktree',
    workspace_new_worktree_conversation_meta: 'Создать изолированный git worktree для этого рабочего пространства.',
    workspace_worktree_created: 'Разговор в worktree создан',
    workspace_worktree_failed: 'Не удалось создать worktree: ',
    session_worktree_badge: 'Worktree',
    model_search_placeholder: 'Поиск моделей…',
    model_scope_advisory: 'Применяется к этой беседе со следующего сообщения.',
    session_toolsets: 'Session Toolsets', // TODO: translate
    session_toolsets_desc: 'Restrict available tools for this session (blank = use global config)', // TODO: translate
    session_toolsets_global: 'Global (default)', // TODO: translate
    session_toolsets_custom: 'Custom', // TODO: translate
    session_toolsets_placeholder: 'tool1, tool2, \u2026', // TODO: translate
    session_toolsets_apply: 'Apply', // TODO: translate
    session_toolsets_clear: 'Clear (use global)', // TODO: translate
    session_toolsets_applied: 'Toolsets updated', // TODO: translate
    session_toolsets_cleared: 'Toolsets cleared — using global config', // TODO: translate
    session_toolsets_failed: 'Failed to update toolsets: ', // TODO: translate
    model_scope_toast: 'Применяется к этой беседе со следующего сообщения.',
    reference_only_label: 'Только справка',
    settings_label_skin: 'Скин',
    settings_label_font_size: 'Размер шрифта',
    font_size_small: 'Маленький',
    font_size_default: 'Стандарт',
    font_size_large: 'Большой',
    font_size_xlarge: 'Очень большой',
    settings_autosave_saving: 'Сохранение…',
    settings_autosave_saved: 'Сохранено',
    settings_autosave_failed: 'Не удалось сохранить',
    settings_autosave_retry: 'Повторить',
    workspace_empty_dir: 'Это рабочее пространство пусто.',
    workspace_show_hidden_files: 'Показывать скрытые файлы',
    workspace_show_hidden_files_desc: 'Include .DS_Store, .git, node_modules, and other hidden / system files in the file tree.',
    workspace_hidden_files_visible: 'hidden visible',
    workspace_hidden_files_visible_title: 'Hidden files are visible — click for options',
    workspace_options: 'Workspace options',
    workspace_empty_no_path: 'Рабочее пространство не выбрано. Настройте его в Настройки → Рабочее пространство.',
    available_personalities: 'Доступные личности:',
    personality_switch_hint: '\n\nИспользуйте `/personality <name>` для переключения или `/personality none` для сброса.',
    personalities_load_failed: 'Не удалось загрузить личности',
    personality_cleared: 'Личность очищена',
    personality_set: 'Личность: ',
    failed_colon: 'Не удалось: ',
    no_workspace: 'Нет рабочего пространства',
    terminal_open_title: 'Открыть терминал рабочей области',
    terminal_no_workspace_title: 'Выберите рабочую область, чтобы открыть терминал',
    terminal_title: 'Терминал',
    terminal_clear: 'Очистить',
    terminal_copy_output: 'Копировать вывод',
    terminal_restart: 'Перезапустить',
    terminal_collapse: 'Свернуть',
    terminal_expand: 'Развернуть',
    terminal_close: 'Закрыть',
    terminal_input_placeholder: 'Введите команду...',
    terminal_start_failed: 'Не удалось запустить терминал: ',
    terminal_input_failed: 'Ошибка ввода терминала: ',
    terminal_copy_failed: 'Не удалось скопировать: ',
    terminal_error: 'Ошибка терминала',
    dialog_confirm_title: 'Подтвердить действие',
    dialog_prompt_title: 'Введите значение',
    dialog_confirm_btn: 'Подтвердить',
    unsaved_confirm: 'У вас есть несохранённые изменения в предпросмотре. Отменить и перейти дальше?',
    discard: 'Отменить',
    save: 'Сохранить',
    edit: 'Редактировать',
    clear: 'Очистить',
    create: 'Создать',
    remove: 'Удалить',
    save_title: 'Сохранить изменения',
    edit_title: 'Редактировать этот файл',
    saved: 'Сохранено',
    save_failed: 'Не удалось сохранить: ',
    image_load_failed: 'Не удалось загрузить изображение',
    file_open_failed: 'Не удалось открыть файл',
    downloading: (name) => `Скачиваю ${name}…`,
    double_click_rename: 'Дважды щёлкните, чтобы переименовать',
    renamed_to: 'Переименовано в ',
    rename_failed: 'Не удалось переименовать: ',
    delete_title: 'Удалить',
    delete_confirm: (name) => `Удалить ${name}?`,
    delete_dir_confirm: (name) => `Удалить папку "${name}" и всё её содержимое?`,
    rename_title: 'Переименовать',
    rename_prompt: 'Новое имя:',
    deleted: 'Удалено ',
    delete_failed: 'Не удалось удалить: ',
    reveal_in_finder: 'Показать в файловом менеджере',
    reveal_failed: 'Не удалось открыть: ',
    copy_file_path: 'Копировать путь к файлу',
    download_folder: 'Download Folder', // TODO: translate
    path_copied: 'Путь к файлу скопирован в буфер обмена',
    path_copy_failed: 'Не удалось скопировать путь: ',
    session_rename: 'Переименовать беседу',
    session_rename_desc: 'Изменить название этой беседы',
    new_file_prompt: 'Имя нового файла (например, notes.md):',
    project_name_prompt: 'Имя проекта:',
    created: 'Создано ',
    create_failed: 'Не удалось создать: ',
    new_folder_prompt: 'Имя новой папки:',
    folder_created: 'Папка создана ',
    folder_create_failed: 'Не удалось создать папку: ',
  workspace_auto_create_folder: 'Создать папку, если она не существует',
  folder_add_as_space_btn: 'Добавить',
  folder_add_as_space_msg: 'Добавить эту папку как новое пространство?',
  folder_add_as_space_title: 'Добавить как пространство?',
    remove_title: 'Удаление',
    empty_dir: '(пусто)',
    upload_failed: 'Не удалось загрузить: ',
    upload_too_large: (maxMb, fileMb) => `Файл слишком большой (${fileMb} МБ). Максимальный размер загрузки: ${maxMb} МБ.`,
    all_uploads_failed: (n) => `Не удалось загрузить все ${n} файлов`,
    archive_extracted: (n, c) => `Извлечено ${n} файл(ов) из ${c} архив(ов)`,
    settings_title: 'Настройки',
    settings_save_btn: 'Сохранить настройки',
    settings_label_model: 'Модель по умолчанию',
    settings_desc_model: 'Используется для новых бесед. Существующие беседы сохраняют выбранную модель.',
    settings_label_send_key: 'Клавиша отправки',
    settings_label_theme: 'Тема',
    settings_label_language: 'Язык',
    settings_label_quota_chip: 'Показывать чип квоты провайдера в композиторе',
    settings_desc_quota_chip: 'Отображает фоновый индикатор остатка квоты (например, баланс кредитов OpenRouter) в подвале композитора. По умолчанию отключено. Виден только на широких экранах (≥1400px) при включении, чтобы не загромождать композитор на ноутбуках и стандартных мониторах.',
    settings_label_hide_suggestions: 'Hide new-chat suggestions',
    settings_desc_hide_suggestions: 'Hide the three default suggestion buttons on the empty new-chat screen to avoid accidental taps.',
    settings_label_token_usage: 'Показывать использование токенов',
    settings_label_sidebar_density: 'Плотность боковой панели',
    cmd_reasoning: 'Toggle thinking visibility (show/hide), set effort level, or check current status',
    settings_label_external_sessions: 'Показывать внешние сеансы',
    settings_label_previous_messaging_sessions: 'Показывать предыдущие сеансы обмена сообщениями',
    settings_label_sync_insights: 'Синхронизировать с Insights',
    settings_label_check_updates: 'Проверять обновления',
    settings_label_whats_new_summary: "Summarize What's New with AI",
    settings_label_bot_name: 'Имя помощника по умолчанию',
    settings_label_password: 'Пароль доступа',
    settings_saved: 'Настройки сохранены',
    settings_save_failed: 'Не удалось сохранить: ',
    settings_load_failed: 'Не удалось загрузить настройки: ',
    settings_saved_pw: 'Настройки сохранены (пароль задан — теперь требуется вход)',
    settings_saved_pw_updated: 'Настройки сохранены (пароль обновлён)',
    login_title: 'Вход',
    login_subtitle: 'Введите пароль, чтобы продолжить',
    login_placeholder: 'Пароль',
    login_btn: 'Войти',
    login_invalid_pw: 'Неверный пароль',
    login_conn_failed: 'Не удалось подключиться',
    tab_chat: 'Чат',
    tab_tasks: 'Задачи',
    tab_skills: 'Навыки',
    tab_memory: 'Память',
    tab_workspaces: 'Рабочие пространства',
    tab_profiles: 'Профили',
    tab_kanban: 'Kanban',
    kanban_board: 'Board',
    kanban_visible_tasks: '{0} visible tasks',
    kanban_search_tasks: 'Search tasks',
    kanban_all_assignees: 'All assignees',
    kanban_all_tenants: 'All tenants',
    kanban_include_archived: 'Include archived',
    kanban_no_matching_tasks: 'No matching tasks',
    kanban_no_data: 'No Kanban data',
    kanban_work_queue_hint: 'This is the Hermes Agent work queue. Create or triage a task, assign it, move it to Ready, then let the dispatcher claim it.',
    kanban_unavailable: 'Kanban unavailable',
    kanban_read_only: 'Read-only view',
    kanban_empty: 'Empty',
    kanban_task: 'Task',
    kanban_no_description: 'No description',
    kanban_refresh: 'Refresh',
    kanban_status_triage: 'Triage',
    kanban_status_todo: 'Todo',
    kanban_status_ready: 'Ready',
    kanban_status_running: 'Running',
    kanban_status_blocked: 'Blocked',
    kanban_status_done: 'Done',
    kanban_status_original_hint: 'Actual status: {0}. This dialog only supports Triage/Todo/Ready edits.',
    kanban_comments_count: 'Comments ({0})',
    kanban_events_count: 'Events ({0})',
    kanban_links: 'Links',
    kanban_parents: 'Parents',
    kanban_children: 'Children',
    kanban_runs_count: 'Runs ({0})',
    kanban_no_comments: 'No comments',
    kanban_no_events: 'No events',
    kanban_no_runs: 'No runs',
    kanban_title: 'Заголовок',
    kanban_description: 'Описание',
    kanban_description_placeholder: 'Необязательно — что нужно сделать, критерии приёмки, ссылки',
    kanban_status: 'Статус',
    kanban_assignee: 'Исполнитель',
    kanban_assignee_placeholder: 'Необязательно — оставьте пустым для любого исполнителя',
    kanban_tenant: 'Арендатор',
    kanban_tenant_placeholder: 'Необязательно — слаг проекта или команды',
    kanban_priority: 'Приоритет',
    kanban_priority_hint: 'Большие числа выполняются первыми. По умолчанию 0.',
    kanban_title_required: 'Заголовок обязателен.',
    kanban_edit_task: 'Редактировать задачу',
    kanban_run_dispatcher: 'Запустить диспетчер',
    kanban_run_dispatcher_confirm: 'Это захватит задачи в состоянии Ready на этой доске и запустит подпроцессы-исполнители (по одному на задачу, до 8 за нажатие). Продолжить?',
    kanban_assignee_profiles_label: 'Профили Hermes',
    kanban_assignee_other_label: 'Другие (CLI каналы / удалённые профили)',
    kanban_assignee_unassigned: '— Не назначено (не запустится автоматически) —',
    kanban_ready_needs_assignee: 'Вы выбрали «Не назначено» + «Ready». Диспетчер пропустит эту задачу. Отправьте ещё раз для подтверждения или выберите профиль.',
    kanban_dispatch_preview_prefix: 'Предпросмотр:',
    kanban_dispatch_run_prefix: 'Отправлено:',
    kanban_dispatch_spawned: 'запущено',
    kanban_dispatch_promoted: 'повышено',
    kanban_dispatch_reclaimed: 'возвращено',
    kanban_dispatch_skipped_unassigned: 'пропущено (без исполнителя)',
    kanban_dispatch_skipped_nonspawnable: 'пропущено (неизвестный профиль)',
    kanban_dispatch_auto_blocked: 'автоблок',
    kanban_dispatch_timed_out: 'таймаут',
    kanban_dispatch_crashed: 'падение',
    kanban_new_task: 'New task',
    kanban_add_comment: 'Add comment',
      kanban_only_mine: 'Only mine',
      kanban_bulk_action: 'Bulk action',
      kanban_nudge_dispatcher: 'Preview dispatcher',
      kanban_stats: 'Stats',
      kanban_worker_log: 'Worker log',
      kanban_block: 'Block',
      kanban_unblock: 'Unblock',
      kanban_back_to_board: 'Back to board',
      kanban_lanes_by_profile: 'Lanes by profile',
      kanban_new_board: 'New board…',
      kanban_rename_board: 'Rename current board…',
      kanban_archive_board: 'Archive current board…',
      kanban_archive_board_confirm: 'Archive board "{name}"? Tasks remain on disk and the board can be restored from kanban/boards/_archived/.',
      kanban_board_archived: 'Board archived',
      kanban_board_name: 'Name',
      kanban_board_slug: 'Slug (lowercase, hyphens)',
      kanban_board_description: 'Description (optional)',
      kanban_board_icon: 'Icon (emoji, optional)',
      kanban_board_color: 'Color (optional)',
      kanban_board_name_required: 'Name is required',
      kanban_board_slug_required: 'Slug is required',
      kanban_card_complete: 'complete',
      kanban_card_archive: 'archive',
      kanban_unassigned: 'unassigned',
    kanban_status_archived: 'Archived',
    tab_todos: 'Список дел',
    tab_insights: 'Аналитика',
    tab_dashboard: 'Панель Hermes',
    dashboard_loopback_warning: 'Панель доступна только через loopback на сервере. Откройте её с самого сервера или перезапустите с --host 0.0.0.0 (небезопасно).',
    tab_logs: 'Logs',
    tab_settings: 'Настройки',

    logs_title: 'Logs',  // TODO: translate
    logs_file: 'File',  // TODO: translate
    logs_tail: 'Tail',  // TODO: translate
    logs_auto_refresh: 'Auto-refresh (5s)',  // TODO: translate
    logs_wrap: 'Wrap lines',  // TODO: translate
    logs_copy_all: 'Copy all',  // TODO: translate
    logs_empty: 'No log lines yet.',  // TODO: translate
    logs_loading: 'Loading logs…',  // TODO: translate
    logs_load_failed: 'Logs failed to load',  // TODO: translate
    logs_status_idle: 'Choose a log file to view recent lines.',  // TODO: translate
    logs_no_mtime: 'not written yet',  // TODO: translate
    logs_truncated_hint: 'Showing the tail of a large log file; older bytes were skipped to keep memory bounded.',  // TODO: translate
    logs_copied: 'Logs copied',  // TODO: translate
    logs_severity: 'Уровень',
    logs_severity_all: 'Все',
    logs_severity_errors: 'Ошибки',
    logs_severity_warnings: 'Предупреждения+',
    logs_filter_active: 'показано (фильтр активен)',
    new_conversation: 'Новая беседа',
    filter_conversations: 'Фильтр бесед...',
    session_time_unknown: 'Неизвестно',
    session_time_minutes_ago: (n) => `${n}м`,
    session_time_hours_ago: (n) => `${n}ч`,
    session_time_days_ago: (n) => `${n}д`,
    session_time_last_week: '1н',
    session_time_bucket_today: 'Сегодня',
    session_time_bucket_yesterday: 'Вчера',
    session_time_bucket_this_week: 'На этой неделе',
    session_time_bucket_last_week: 'На прошлой неделе',
    session_time_bucket_older: 'Ранее',
    scheduled_jobs: 'Запланированные задания',
    new_job: 'Новое задание',
    loading: 'Загрузка...',
    search_skills: 'Поиск навыков...',
    new_skill: 'Новый навык',
    personal_memory: 'Личная память',
    current_task_list: 'Текущий список задач',
    workspace_desc: 'Добавляйте рабочие пространства и переключайтесь между ними в своих сеансах.',
    session_meta_messages: (n) => `${n} сообщ.`,
    session_meta_children: (n) => `${n} ${n === 1 ? 'дочерн.' : 'дочерн.'}`,
    session_meta_segments: (n) => `${n} сегм.`,
    session_lineage_segment_untitled: 'Сегмент без названия',
    session_lineage_segment_open: 'Открыть сегмент цепочки',
    new_profile: 'Новый профиль',
    transcript: 'Транскрипт',
    download_transcript: 'Скачать как Markdown',
    import: 'Импорт',
    export_session_json: 'JSON',
    export_session_json_tooltip: 'Экспортировать сессию как JSON',
    import_session_json_tooltip: 'Импортировать сессию из JSON',
    clear_conversation_btn_tooltip: 'Очистить все сообщения в этой беседе',
    settings_label_rtl: 'Раскладка чата справа налево',
    settings_desc_rtl: 'Переворачивает выравнивание сообщений чата и поля ввода для языков вроде арабского или иврита. Влияет только на область чата — боковая панель и другие панели остаются слева направо.',
    settings_label_sound: 'Звук уведомления',
    settings_desc_sound: 'Проигрывать звук, когда помощник завершает ответ.',
    settings_label_notifications: 'Уведомления браузера',
    settings_desc_notifications: 'Показывать системное уведомление, когда ответ готов, а вкладка находится в фоне.',
    settings_desc_token_usage: 'Показывает количество входных и выходных токенов под каждым ответом помощника. Также переключается через /usage.',
    settings_sidebar_density_compact: 'Компактно',
    settings_sidebar_density_detailed: 'Подробно',
    settings_desc_sidebar_density: 'Управляет тем, сколько метаданных показывается в списке сеансов на левой панели.',
    settings_label_auto_title_refresh: 'Адаптивное обновление заголовка',
    settings_auto_title_refresh_off: 'Выкл',
    settings_auto_title_refresh_5: 'Каждые 5 обменов',
    settings_auto_title_refresh_10: 'Каждые 10 обменов',
    settings_auto_title_refresh_20: 'Каждые 20 обменов',
    settings_desc_auto_title_refresh: 'Автоматически переформулирует заголовок сессии на основе последнего обмена, чтобы он оставался актуальным по мере развития беседы. Требует настроенную модель генерации заголовков.',
    settings_desc_external_sessions: 'Показать беседы из CLI, Telegram, Discord, Slack и других каналов в списке сеансов. Нажмите для импорта и продолжения.',
    settings_desc_previous_messaging_sessions: 'Показывать предыдущие сеансы Discord, Telegram, Slack и Weixin, замененные сбросом или сжатием.',
    settings_desc_sync_insights: 'Синхронизирует использование токенов WebUI в state.db, чтобы Hermes /insights включал данные браузерных сеансов. Выключено по умолчанию.',
    settings_desc_check_updates: 'Показывает баннер, когда доступны более новые версии WebUI или Agent. Периодически выполняет git fetch в фоне.',
    settings_desc_whats_new_summary: "Changes the What's New action from opening the raw diff first to generating a short, human-readable summary. The regular diff comparison stays available after the summary.",
    settings_desc_bot_name: 'Используется только для профиля по умолчанию. Другие профили используют свои имена.',
    settings_desc_password: 'Введите новый пароль, чтобы задать или изменить его. Оставьте пустым, чтобы сохранить текущую настройку.',
    password_placeholder: 'Введите новый пароль…',
    password_env_var_locked: 'Переменная окружения HERMES_WEBUI_PASSWORD сейчас задана и имеет приоритет. Сбросьте её и перезапустите сервер, чтобы управлять паролем отсюда.',
    password_env_var_locked_placeholder: 'Заблокировано: задана переменная HERMES_WEBUI_PASSWORD',
    disable_auth: 'Отключить авторизацию',
    sign_out: 'Выйти',
    // Providers panel (English fallback — native translations welcome in follow-up PRs)
    providers_tab_title: 'Providers',
    providers_section_title: 'Providers',
    providers_section_meta: 'Manage API keys for AI providers. Changes take effect immediately.',
    providers_status_configured: 'API key configured',
    providers_status_not_configured: 'No API key',
    providers_status_oauth: 'OAuth',
    providers_status_api_key: 'API key',
    providers_status_not_configured_label: 'Not configured',
    providers_oauth_hint: 'Authenticated via OAuth. No API key needed.',
    providers_oauth_config_yaml_hint: 'Token configured via config.yaml. To update, edit the providers section in your config.yaml or run hermes auth.',
    providers_oauth_not_configured_hint: 'Not authenticated. Run hermes auth in the terminal to configure this provider.',
    providers_save: 'Save',
    providers_remove: 'Remove',
    providers_saving: 'Saving…',
    providers_removing: 'Removing…',
    providers_enter_key: 'Please enter an API key',
    providers_empty: 'No configurable providers found.',
    providers_key_updated: 'API key saved',
    providers_key_removed: 'API key removed',
    providers_key_placeholder_new: 'sk-...',
    providers_key_placeholder_replace: 'Enter new key to replace…',
    provider_quota_title: 'Квота активного провайдера',
    provider_quota_active_provider: 'Активный провайдер',
    provider_quota_last_checked_after_refresh: 'Последняя проверка после обновления',
    provider_quota_last_checked: 'Последняя проверка: {0}',
    provider_quota_refresh_usage: 'Обновить использование',
    provider_quota_refreshing: 'Обновление...',
    provider_quota_refresh_title: 'Обновить лимиты использования провайдера сейчас',
    provider_quota_refresh_succeeded: 'Использование провайдера обновлено',
    provider_quota_refresh_failed: 'Не удалось обновить использование провайдера',
    provider_quota_session_limit: 'Лимит на 5 часов',
    provider_quota_weekly_limit: 'Недельный лимит',
    provider_quota_window_fallback: 'Окно',
    provider_quota_metric_remaining: 'Осталось',
    provider_quota_metric_used: 'Использовано',
    provider_quota_metric_limit: 'Лимит',
    provider_quota_status_available: 'доступно',
    provider_quota_status_exhausted: 'исчерпано',
    provider_quota_status_unavailable: 'недоступно',
    provider_quota_status_failed: 'ошибка',
    provider_quota_status_checked: 'проверено',
    provider_quota_status_no_key: 'нет ключа',
    provider_quota_status_invalid_key: 'недействительный ключ',
    provider_quota_status_unsupported: 'не поддерживается',
    provider_quota_used_meta: 'использовано {0}',
    provider_quota_resets_meta: 'сброс {0}',
    provider_quota_credential_pool: 'Пул учетных данных',
    provider_quota_credential_label: 'Учетные данные {0}',
    provider_quota_pool_plans: 'Планы: {0}',
    provider_quota_pool_no_windows: 'Окна лимитов аккаунта не переданы.',
    provider_quota_account_limits_loaded: 'Лимиты аккаунта загружены.',
    provider_quota_unavailable: 'Статус квоты недоступен',
    provider_quota_retry_after: 'Повторить после {0}',
    provider_quota_pool_summary_available: 'доступно {0}/{1}',
    provider_quota_pool_summary_exhausted: '{0} исчерпано',
    provider_quota_pool_summary_failed: '{0} с ошибкой',
    provider_quota_pool_summary_checked: '{0} проверено',
    cancel: 'Отмена',
    create_job: 'Создать задание',
    save_skill: 'Сохранить навык',
    editing: 'Редактирование',
    empty_title: 'Чем я могу помочь?',
    empty_subtitle: 'Спрашивайте что угодно, запускайте команды, изучайте файлы или управляйте запланированными задачами.',
    suggest_files: 'Какие файлы есть в этом рабочем пространстве?',
    suggest_schedule: 'Что у меня сегодня в расписании?',
    suggest_plan: 'Помоги спланировать небольшой проект.',
    onboarding_badge: 'ПЕРВЫЙ ЗАПУСК',
    onboarding_title: 'Добро пожаловать в Hermes Web UI',
    onboarding_lead: 'Краткая пошаговая настройка проверит Hermes, сохранит рабочую конфигурацию провайдера, выберет рабочее пространство и модель и при желании защитит приложение паролем.',
    onboarding_back: 'Назад',
    onboarding_continue: 'Продолжить',
    onboarding_skip: 'Пропустить настройку',
    onboarding_skipped: 'Настройка пропущена — используется существующая конфигурация.',
    onboarding_open: 'Открыть Hermes',
    onboarding_step_system_title: 'Проверка системы',
    onboarding_step_system_desc: 'Проверить Hermes Agent и видимость конфигурации.',
    onboarding_step_setup_title: 'Настройка провайдера',
    onboarding_step_setup_desc: 'Сохранить минимальную рабочую конфигурацию провайдера Hermes.',
    onboarding_step_workspace_title: 'Рабочее пространство и модель',
    onboarding_step_workspace_desc: 'Выбрать значения по умолчанию для новых сеансов и чатов.',
    onboarding_step_password_title: 'Необязательный пароль',
    onboarding_step_password_desc: 'Защитить Web UI перед тем, как делиться им.',
    onboarding_step_finish_title: 'Готово',
    onboarding_step_finish_desc: 'Проверьте настройки и войдите в приложение.',
    onboarding_notice_system_ready: 'Hermes Agent, похоже, доступен из Web UI.',
    onboarding_notice_system_unavailable: 'Hermes Agent ещё не полностью доступен. Bootstrap может установить его, но для настройки провайдера всё ещё может понадобиться терминал.',
    onboarding_check_agent: 'Hermes Agent',
    onboarding_check_agent_ready: 'Обнаружен и доступен для импорта',
    onboarding_check_agent_missing: 'Отсутствует или доступен только частично',
    onboarding_check_password: 'Пароль',
    onboarding_check_password_enabled: 'Уже включён',
    onboarding_check_password_disabled: 'Пока не включён',
    onboarding_check_provider: 'Конфигурация провайдера',
    onboarding_check_provider_ready: 'Готова к чату',
    onboarding_check_provider_partial: 'Сохранена, но не завершена',
    onboarding_check_provider_pending: 'Требует проверки',
    onboarding_config_file: 'Файл конфигурации:',
    onboarding_env_file: 'Файл .env:',
    onboarding_unknown: 'Неизвестно',
    onboarding_current_provider: 'Текущая конфигурация:',
    onboarding_missing_imports: 'Отсутствующие импорты:',
    onboarding_notice_setup_required: 'Выберите здесь простой путь настройки провайдера. Продвинутые OAuth-сценарии пока остаются в Hermes CLI.',
    onboarding_notice_setup_already_ready: 'Уже обнаружена рабочая конфигурация провайдера Hermes. Вы можете оставить её или заменить здесь.',
    onboarding_oauth_provider_ready_title: 'Провайдер уже авторизован',
    onboarding_oauth_provider_ready_body: 'Этот экземпляр настроен на использование OAuth-провайдера (<strong>{provider}</strong>), настроенного через Hermes CLI. API-ключ здесь не нужен — нажмите «Продолжить», чтобы завершить настройку.',
    onboarding_oauth_provider_not_ready_title: 'OAuth-провайдер ещё не авторизован',
    onboarding_oauth_provider_not_ready_body: 'Этот экземпляр настроен на использование <strong>{provider}</strong>, который работает через OAuth, а не через API-ключ. Запустите <code>hermes auth</code> или <code>hermes model</code> в терминале, чтобы пройти авторизацию, затем обновите Web UI.',
    onboarding_oauth_switch_hint: 'Или выберите ниже другой провайдер, чтобы перейти на настройку с ключом API:',
    onboarding_notice_workspace: 'Эти значения используют те же API настроек, что и обычное приложение.',
    onboarding_workspace_label: 'Рабочее пространство',
    onboarding_workspace_or_path: 'Или укажите путь к рабочему пространству',
    onboarding_workspace_placeholder: '/home/you/workspace',
    onboarding_provider_label: 'Режим настройки',
    onboarding_quick_setup_badge: 'Быстрая настройка',
    provider_category_easy_start: 'Быстрый старт',
    provider_category_self_hosted: 'Локальные / Open source',
    provider_category_specialized: 'Специализированные',
    onboarding_api_key_label: 'Ключ API',
    onboarding_api_key_placeholder: 'Оставьте пустым, чтобы сохранить уже сохранённый ключ',
    onboarding_api_key_label_optional: 'API key (optional)', // TODO: translate
    onboarding_api_key_placeholder_optional: 'Leave blank for keyless servers', // TODO: translate
    onboarding_api_key_help_keyless: 'Most LM Studio / Ollama / vLLM installs run keyless — leave this blank if your server doesn\'t require authentication. Use the Test connection button to verify.', // TODO: translate
    oauth_login_codex: 'Login with Codex (ChatGPT)', // TODO: translate
    oauth_codex_step1: 'Step 1: Visit this URL and enter the code', // TODO: translate
    oauth_codex_step2: 'Step 2: Enter this code on the page', // TODO: translate
    oauth_codex_polling: 'Waiting for authorization...', // TODO: translate
    oauth_codex_success: 'Codex OAuth login successful!', // TODO: translate
    oauth_codex_error: 'OAuth login failed', // TODO: translate
    oauth_codex_expired: 'Code expired, please try again', // TODO: translate
    onboarding_api_key_help_prefix: 'Сохраняется как секрет в вашем файле `.env` Hermes с помощью',
    onboarding_base_url_label: 'Базовый URL',
    onboarding_base_url_placeholder: 'https://your-endpoint.example/v1',
    onboarding_base_url_help: 'Используйте это для OpenAI-compatible маршрутизаторов, self-hosted серверов, LiteLLM, Ollama, LM Studio, vLLM и похожих endpoint-ов.',
    onboarding_model_label: 'Модель по умолчанию',
    onboarding_workspace_help: 'Выберите модель, которую Hermes должен использовать для новых чатов после завершения настройки.',
    onboarding_custom_model_placeholder: 'имя_вашей_модели',
    onboarding_custom_model_help: 'Для собственных endpoint-ов укажите точный ID модели, который ожидает ваш сервер.',
    onboarding_notice_password_enabled: 'Пароль уже настроен. Вводите новый только если хотите заменить текущий.',
    onboarding_notice_password_recommended: 'Необязательно, но рекомендуется, если вы собираетесь открывать UI не только на localhost.',
    onboarding_password_label: 'Пароль (необязательно)',
    onboarding_password_placeholder: 'Оставьте пустым, чтобы пропустить',
    onboarding_password_help: 'Пароли сохраняются через существующий API настроек и хэшируются на сервере.',
    onboarding_notice_finish: 'Позже вы сможете снова открыть настройки и изменить любое из этих значений.',
    onboarding_not_set: 'Не задано',
    onboarding_password_will_enable: 'Будет включён',
    onboarding_password_will_replace: 'Будет заменён текущий пароль',
    onboarding_password_keep_existing: 'Оставить текущий пароль',
    onboarding_password_remains_disabled: 'Останется отключённым',
    onboarding_password_skipped: 'Пропустить пока',
    onboarding_finish_help: 'После завершения в настройках сохранится <code>onboarding_completed</code>, и вы попадёте в обычное приложение.',
    onboarding_error_choose_workspace: 'Выберите рабочее пространство перед продолжением.',
    onboarding_error_choose_model: 'Выберите модель перед продолжением.',
    onboarding_error_provider_required: 'Выберите режим настройки перед продолжением.',
    onboarding_error_base_url_required: 'Для собственных endpoint-ов требуется базовый URL.',
    onboarding_probe_test_button: 'Test connection', // TODO: translate
    onboarding_probe_probing: 'Testing connection…', // TODO: translate
    onboarding_probe_ok: 'Connected. {n} model(s) available.', // TODO: translate
    onboarding_probe_error_generic: 'Could not reach the configured base URL.', // TODO: translate
    onboarding_probe_error_invalid_url: 'Base URL must start with http:// or https://.', // TODO: translate
    onboarding_probe_error_dns: 'Could not resolve the host. Check the URL or use the host\'s IP address.', // TODO: translate
    onboarding_probe_error_connect_refused: 'Connection refused — the server may not be running on that address. From inside Docker, try the host IP instead of localhost.', // TODO: translate
    onboarding_probe_error_timeout: 'The endpoint did not respond in time. Check that the server is running and the URL is correct.', // TODO: translate
    onboarding_probe_error_http_4xx: 'The endpoint returned a client error. Check authentication and the URL path (typically ends in /v1).', // TODO: translate
    onboarding_probe_error_http_5xx: 'The endpoint returned a server error. Check the LM Studio / Ollama server logs.', // TODO: translate
    onboarding_probe_error_parse: 'The endpoint did not return a model list in the expected shape. Verify the URL points to the OpenAI-compatible API root.', // TODO: translate
    onboarding_probe_error_unreachable: 'Could not reach the configured base URL.', // TODO: translate
    onboarding_error_probe_failed: 'Could not validate the configured base URL.', // TODO: translate
    onboarding_error_workspace_required: 'Рабочее пространство обязательно.',
    onboarding_error_model_required: 'Модель обязательна.',
    onboarding_complete: 'Первичная настройка завершена',
    error_prefix: 'Ошибка: ',
    not_available: 'н/д',
    never: 'никогда',
    add: 'Добавить',
    add_failed: 'Не удалось добавить: ',
    remove_failed: 'Не удалось удалить: ',
    switch_failed: 'Не удалось переключить: ',
    name_required: 'Требуется имя',
    content_required: 'Требуется содержимое',
    view: 'Просмотр',
    dismiss: 'Скрыть',
    disable: 'Отключить',
    cron_no_jobs: 'Запланированные задания не найдены.',
    cron_status_off: 'неактивно',
    cron_status_paused: 'на паузе',
    cron_status_error: 'ошибка',
    cron_status_active: 'активно',
    cron_status_running: 'выполняется\u2026',
    cron_status_needs_attention: 'требует внимания',
    cron_attention_desc: 'У этого повторяющегося задания нет времени следующего запуска. Планировщик мог не суметь вычислить следующий запуск.',
    cron_attention_croniter_hint: 'В окружении Gateway может отсутствовать пакет croniter. Перезапустите Gateway с поддержкой cron, затем возобновите это задание.',
    cron_attention_resume: 'Возобновить и пересчитать',
    cron_jobs_project: 'Задания Cron',
    cron_attention_run_once: 'Запустить один раз сейчас',
    cron_attention_copy_diagnostics: 'Скопировать диагностику',
    cron_diagnostics_copied: 'Диагностика cron скопирована',
    cron_next: 'Следующий',
    cron_last: 'Последний',
    cron_run_now: 'Запустить сейчас',
    cron_pause: 'Пауза',
    cron_resume: 'Возобновить',
    cron_job_name_placeholder: 'Имя задания',
    cron_schedule_placeholder: 'Расписание',
    cron_prompt_placeholder: 'Промпт',
    cron_last_output: 'Последний вывод',
    cron_expand_prompt: 'Развернуть промпт',
    cron_collapse_prompt: 'Свернуть промпт',
    cron_expand_output: 'Развернуть вывод',
    cron_collapse_output: 'Свернуть вывод',
    cron_all_runs: 'Все запуски',
    cron_hide_runs: 'Скрыть запуски',
    cron_no_runs_yet: '(пока запусков нет)',
    cron_schedule_required_example: 'Требуется расписание (например, "0 9 * * *" или "every 1h")',
    cron_schedule_required: 'Требуется расписание',
    cron_prompt_required: 'Требуется промпт',
    cron_job_created: 'Задание создано',
    cron_duplicate: 'Дублировать',
    cron_duplicated: 'Задание дублировано (приостановлено)',
    cron_job_triggered: 'Задание запущено',
    cron_job_paused: 'Задание поставлено на паузу',
    cron_job_resumed: 'Задание возобновлено',
    cron_job_updated: 'Задание обновлено',
    cron_delete_confirm_title: 'Удалить cron-задание',
    cron_delete_confirm_message: 'Это действие нельзя отменить.',
    cron_job_deleted: 'Задание удалено',
    cron_completion_status: (name, status) => `Cron-задание «${name}» — ${status}`,
    status_failed: 'неудачно',
    status_completed: 'завершено',
    todos_no_active: 'В этой сессии нет активного списка задач.',
    clear_conversation_title: 'Очистить беседу',
    clear_conversation_message: 'Очистить все сообщения? Это действие нельзя отменить.',
    clear_failed: 'Не удалось очистить: ',
    skills_no_match: 'Подходящих навыков не найдено.',
    linked_files: 'Связанные файлы',
    skill_load_failed: 'Не удалось загрузить навык: ',
    skill_file_load_failed: 'Не удалось загрузить файл: ',
    skill_name_required: 'Требуется имя навыка',
    skill_updated: 'Навык обновлён',
    skill_created: 'Навык создан',
    memory_notes_label: 'память (заметки)',
    memory_saved: 'Память сохранена',
    my_notes: 'Мои заметки',
    user_profile: 'Пользовательский профиль',
    no_notes_yet: 'Пока нет заметок.',
    no_profile_yet: 'Пока нет профиля.',
    agent_soul: 'Душа агента',
    no_soul_yet: 'Душа пока не задана.',
    workspace_choose_path: 'Выберите путь к рабочему пространству',
    workspace_choose_path_meta: 'Добавьте проверенный путь и переключите эту беседу',
    workspace_manage: 'Управление рабочими пространствами',
    workspace_manage_meta: 'Открыть панель Spaces',
    workspace_use_title: 'Использовать в текущем сеансе',
    workspace_use: 'Использовать',
    workspace_add_path_placeholder: 'Добавьте путь к рабочему пространству (например, /Users/you/project)',
    workspace_paths_validated_hint: 'Перед сохранением пути проверяются на существование.',

    workspace_drag_hint: 'Перетащите для изменения порядка',
    workspace_reorder_failed: 'Не удалось изменить порядок',
    workspace_added: 'Рабочее пространство добавлено',
    workspace_renamed: 'Рабочее пространство переименовано',
    workspace_remove_confirm_title: 'Удалить рабочее пространство',
    workspace_remove_confirm_message: (path) => `Удалить «${path}»?`,
    workspace_removed: 'Рабочее пространство удалено',
    workspace_switch_prompt_title: 'Переключить рабочее пространство',
    workspace_switch_prompt_message: 'Введите абсолютный путь к рабочему пространству, чтобы добавить его и переключить эту беседу.',
    workspace_switch_prompt_confirm: 'Переключить',
    workspace_switch_prompt_placeholder: '/Users/you/project',
    workspace_not_added: 'Рабочее пространство не добавлено',
    workspace_already_saved: 'Рабочее пространство уже сохранено — выберите его из списка',
    workspace_busy_switch: 'Нельзя переключать рабочее пространство, пока агент работает',
    discard_file_edits_title: 'Отменить изменения файлов?',
    discard_file_edits_message: 'При переключении рабочих пространств несохранённые изменения в предпросмотре будут потеряны.',
    workspace_switched_to: (name) => `Переключено на ${name}`,
    profiles_no_profiles: 'Профили не найдены.',
    profile_api_keys_configured: 'API-ключи настроены',
    profile_gateway_running: 'Gateway запущен',
    profile_gateway_stopped: 'Gateway остановлен',
    profile_active: 'АКТИВЕН',
    profile_no_configuration: 'Нет конфигурации',
    profile_skill_count: (count) => {
    const mod10 = count % 10;
    const mod100 = count % 100;
    const word = mod10 === 1 && mod100 !== 11
      ? 'навык'
      : (mod10 >= 2 && mod10 <= 4 && (mod100 < 10 || mod100 >= 20)
        ? 'навыка'
        : 'навыков');
    return `${count} ${word}`;
  },
    profile_use: 'Использовать',
    profile_switch_title: 'Переключиться на этот профиль',
    profile_delete_title: 'Удалить этот профиль',
    profile_default_label: '(по умолчанию)',
    profile_name_placeholder: 'Название профиля (строчные буквы, a-z, 0-9, дефисы)',
    profile_clone_label: 'Скопировать конфигурацию из активного профиля',
    profile_model_label: 'Модель / провайдер',
    profile_model_hint: 'Выберите настроенного провайдера и модель для этого нового профиля.',
    profile_model_use_default: 'Использовать значение активного профиля',
    profile_base_url_placeholder: 'Базовый URL (необязательно, например http://localhost:11434)',
    profile_api_key_placeholder: 'API-ключ (необязательно)',
    manage_profiles: 'Управление профилями',
    profiles_load_failed: 'Не удалось загрузить профили',
    profile_switched_new_conversation: (name) => `Переключено на профиль: ${name} — начата новая беседа`,
    profile_switched: (name) => `Переключено на профиль: ${name}`,
    profile_name_rule: 'Только строчные буквы, цифры, дефисы и подчёркивания',
    profile_base_url_rule: 'Базовый URL должен начинаться с http:// или https://',
    profile_created: (name) => `Профиль создан: ${name}`,
    profile_delete_confirm_title: (name) => `Удалить профиль «${name}»?`,
    profile_delete_confirm_message: 'Все сеансы, конфигурация, навыки и память этого профиля будут удалены безвозвратно. Это действие невозможно отменить.',
    profile_deleted: (name) => `Профиль удалён: ${name}`,
    active_conversation_none: 'Активная беседа не выбрана.',
    active_conversation_meta: (title, count) => {
    const mod10 = count % 10;
    const mod100 = count % 100;
    const word = mod10 === 1 && mod100 !== 11
      ? 'сообщение'
      : (mod10 >= 2 && mod10 <= 4 && (mod100 < 10 || mod100 >= 20)
        ? 'сообщения'
        : 'сообщений');
    return `${title} · ${count} ${word}`;
  },
    settings_unsaved_changes: 'У вас есть несохранённые изменения.',
    sign_out_failed: 'Не удалось выйти: ',
    disable_auth_confirm_title: 'Отключить защиту паролем',
    disable_auth_confirm_message: 'Любой сможет получить доступ к этому экземпляру.',
    auth_disabled: 'Авторизация отключена — защита паролем снята',
    disable_auth_failed: 'Не удалось отключить авторизацию: ',
    bg_error_single: (title) => `В "${title}" возникла ошибка`,
    bg_error_multi: (count) => `${count} сеансов столкнулись с ошибкой`,
    skill_deleted: 'Навык удалён',
    skill_delete_confirm: 'Удалить навык "{0}"?',
    skills_empty_title: 'Выберите навык',
    skills_empty_sub: 'Выберите навык на боковой панели, чтобы просмотреть его содержимое, или создайте новый.',
    skills_edit: 'Редактировать',
    skills_delete: 'Удалить',
    skills_back_to: 'Назад к {0}',
    tasks_empty_title: 'Выберите запланированное задание',
    tasks_empty_sub: 'Выберите задание на боковой панели, чтобы просмотреть его детали и запуски, или создайте новое.',
    workspaces_empty_title: 'Выберите пространство',
    workspaces_empty_sub: 'Выберите пространство на боковой панели, чтобы просмотреть его файлы и настройки, или добавьте новое.',
    profiles_empty_title: 'Выберите профиль',
    profiles_empty_sub: 'Выберите профиль агента на боковой панели, чтобы просмотреть и изменить его настройки, или создайте новый.',
    // skill form
    skill_name: 'Имя',
    skill_category: 'Категория',
    skill_category_placeholder: 'Необязательно, например devops',
    skill_content: 'Содержимое SKILL.md',
    skill_content_placeholder: 'YAML-заголовок + тело markdown',
    skill_rename_not_supported: 'Переименование навыка не поддерживается. Создайте новый навык и удалите старый.',
    skill_metadata: 'Метаданные',
    // cron form
    cron_name_label: 'Имя',
    cron_name_placeholder: 'Необязательно',
    cron_schedule_label: 'Расписание',
    cron_schedule_hint: "Для повторяющихся заданий используйте 'every 1h' или cron-выражение. Простые интервалы вроде '30m' выполняются один раз.",
    cron_schedule_once_warning: "Интервалы вроде '30m' выполняются один раз и удаляются после запуска. Используйте 'every 30m' для повторяющегося задания.",
    cron_prompt_label: 'Запрос',
    cron_deliver_label: 'Доставлять вывод',
    cron_deliver_local: 'Локально (только сохранение)',
    cron_profile_label: 'Профиль',
    cron_profile_server_default: 'по умолчанию сервера',
    cron_profile_server_default_hint: 'Использует профиль WebUI-сервера по умолчанию во время запуска. Существующие задания без профиля сохраняют это поведение.',
    cron_toast_notifications_label: 'Уведомления о завершении',
    cron_toast_notifications_hint: 'Показывать toast, когда это cron-задание завершается. Значок задач и маркер нового запуска всё равно обновляются.',
    cron_toast_notifications_enabled: 'Включено',
    cron_toast_notifications_disabled: 'Отключено',
    cron_skills_label: 'Навыки',
    cron_skills_placeholder: 'Добавить навыки (необязательно)…',
    cron_skills_edit_hint: 'Список навыков нельзя изменить после создания.',
    // workspace form
    workspace_name_label: 'Имя',
    workspace_name_placeholder: 'Необязательное понятное имя',
    workspace_path_label: 'Путь',
    workspace_path_required: 'Путь обязателен',
    workspace_path_readonly: 'Путь нельзя изменить. Только переименование.',
    workspace_new_title: 'Новое пространство',
    // profile form
    profile_name_label: 'Имя',
    profile_base_url_label: 'Базовый URL',
    profile_api_key_label: 'API-ключ',
  
    // Session management and settings keys (en fallback — pending translation)
    session_archive: 'Archive conversation',
    session_hide_external: 'Скрыть из списка',
    session_archive_desc: 'Hide this conversation until archived is shown',
    session_archive_worktree_desc: 'Hide this conversation; keep its worktree on disk',
    session_hide_external_desc: 'Скрыть эту импортированную сессию из WebUI без удаления исходной истории.',
    session_archive_failed: 'Archive failed: ',
    session_archived: 'Session archived',
    session_archived_worktree: 'Session archived. Worktree remains on disk.',
    session_hidden: 'Сессия скрыта из списка',
    session_delete: 'Delete conversation',
    session_delete_desc: 'Permanently remove this conversation',
    session_delete_confirm: 'Delete this conversation?',
    session_delete_worktree_desc: 'Delete only the WebUI conversation; keep the worktree on disk',
    session_delete_worktree_confirm: (path) => `Delete this conversation? The worktree at ${path} will remain on disk.`,
    session_deleted: 'Conversation deleted',
    session_deleted_worktree: 'Conversation deleted. Worktree remains on disk.',
    session_worktree_remove: 'Remove worktree',
    session_worktree_remove_desc: (path) => `Delete the git worktree at ${path} from disk`,
    session_worktree_remove_confirm: (path) => `Remove git worktree from disk?\n\nPath: ${path}\n\nThis will delete the entire worktree directory. Session data remains in WebUI.`,
    session_worktree_remove_not_exists: (path) => `The worktree at ${path} no longer exists on disk.`,
    session_worktree_remove_confirm_label: 'Remove',
    session_worktree_removed: 'Worktree removed.',
    session_worktree_remove_failed: 'Failed to remove worktree: ',
    session_worktree_remove_status_failed: 'Failed to read worktree status: ',
    session_worktree_remove_locked_by_stream: 'Cannot remove — an active streaming session is using this worktree.',
    session_worktree_remove_locked_by_terminal: 'Cannot remove — an active terminal session is using this worktree.',
    session_worktree_remove_unsafe_blocked: 'Resolve local changes or unpushed commits before removing this worktree.',
    session_worktree_remove_dirty_warning: 'WARNING: This worktree has uncommitted changes which will be lost.',
    session_worktree_remove_untracked_warning: (count) => `${count} untracked file(s) will be permanently deleted.`,
    session_worktree_remove_ahead_warning: (ahead) => `${ahead} unpushed commit(s) will be lost.`,
    session_duplicate: 'Duplicate conversation',
    session_duplicate_desc: 'Create a copy with the same workspace and model',
    session_duplicate_failed: 'Duplicate failed: ',
    session_stop_response: 'Stop response',
    session_stop_response_desc: 'Cancel the running response for this conversation',
    session_duplicated: 'Session duplicated',
    session_move_project: 'Move to project',
    session_move_project_desc_has: 'Change the project for this conversation',
    session_move_project_desc_none: 'Assign a project to this conversation',
    session_pin: 'Pin conversation',
    session_pin_desc: 'Keep this conversation at the top',
    session_pin_failed: 'Pin failed: ',
    session_restore: 'Restore conversation',
    session_restore_desc: 'Bring this conversation back into the main list',
    session_restored: 'Session restored',
    session_unpin: 'Unpin conversation',
    session_unpin_desc: 'Remove from pinned',
    session_select_mode: 'Выбрать',
    session_select_mode_desc: 'Выберите беседы для массового управления',
    session_select_all: 'Выбрать все',
    session_deselect_all: 'Снять выделение',
    session_selected_count: '{0} выбрано',
    session_batch_archive: 'В архив',
    session_batch_delete: 'Удалить',
    session_batch_move: 'Переместить в проект',
    session_batch_delete_confirm: 'Удалить {0} бесед(ы)?',
    session_batch_archive_confirm: 'Архивировать {0} бесед(ы)?',
    session_batch_delete_worktree_confirm: 'Удалить {0} бесед(ы)? У {1} бесед с worktree каталоги worktree останутся на диске.',
    session_batch_archive_worktree_confirm: 'Архивировать {0} бесед(ы)? У {1} бесед с worktree каталоги worktree останутся на диске.',
    session_no_selection: 'Ничего не выбрано',
    settings_dropdown_appearance: 'Appearance',
    settings_dropdown_conversation: 'Conversation',
    settings_dropdown_preferences: 'Preferences',
    settings_dropdown_providers: 'Providers',
    settings_dropdown_system: 'System',
    settings_heading_subtitle: 'Preferences, conversation tools, and system controls.',
    settings_heading_title: 'Control Center',
    settings_section_appearance_meta: 'Theme, accent colors, and visual style.',
    settings_section_appearance_title: 'Appearance',
    settings_section_conversation_title: 'Conversation',
    settings_section_preferences_meta: 'Defaults and UI behavior for Hermes Web UI.',
    settings_section_preferences_title: 'Preferences',
    settings_section_system_meta: 'Instance version and access controls.',
    settings_check_now: 'Проверить',
    settings_checking: 'Проверка\u2026',
    settings_up_to_date: 'Актуально \u2713',
    settings_updates_available: 'Доступно обновлений: {count}',
    settings_updates_disabled: 'Проверка обновлений отключена',
    settings_update_check_failed: 'Ошибка проверки обновлений',
    settings_label_workspace_panel_open: 'Открывать панель рабочей области по умолчанию',
    settings_desc_workspace_panel_open: 'При включении панель файлов будет открываться автоматически в каждой новой сессии.',
    settings_label_session_jump_buttons: 'Показывать кнопки перехода по сессии',
    settings_desc_session_jump_buttons: 'Показывать плавающие кнопки «Начало» и «Конец» при чтении длинных историй сессий.',

    settings_label_session_endless_scroll: 'Загружать старые сообщения при прокрутке вверх',

    settings_desc_session_endless_scroll: 'Если включено, старые сообщения загружаются автоматически при прокрутке вверх. Если выключено, используйте кнопку загрузки старых сообщений.',

    settings_label_tab_visibility: 'Вкладки боковой панели',
    settings_desc_tab_visibility: 'Выберите, какие вкладки отображаются на боковой панели и в рейле. Чат и настройки всегда видны.',
    open_in_browser: 'Открыть в браузере',
    settings_section_system_title: 'System',
    settings_tab_appearance: 'Appearance',
    settings_tab_conversation: 'Conversation',
    settings_tab_preferences: 'Preferences',
    settings_tab_plugins: 'Плагины',
    settings_plugins_title: 'Plugins',  // TODO: translate
    settings_plugins_meta: 'View installed Hermes plugins and the lifecycle hooks they register. This panel is read-only.',  // TODO: translate
    settings_plugins_empty: 'No Hermes plugins are currently visible. Install or enable plugins from the Hermes CLI/config to see them here.',  // TODO: translate
    plugins_unnamed: 'Unnamed plugin',  // TODO: translate
    plugins_no_description: 'No description provided.',  // TODO: translate
    plugins_no_hooks: 'No registered lifecycle hooks',  // TODO: translate
    plugins_registered_hooks: 'Registered hooks',  // TODO: translate
    plugins_enabled: 'Enabled',  // TODO: translate
    plugins_disabled: 'Disabled',  // TODO: translate
    plugins_active_provider: 'Active (provider)',  // TODO: translate
    plugins_provider_no_hooks: 'Provider plugin — no agent-visibility hooks',  // TODO: translate
    plugins_load_failed: 'Failed to load plugins: ',  // TODO: translate
    settings_tab_system: 'System',
    status_updated: 'Updated',
    status_ephemeral: 'Ephemeral snapshot — not saved to transcript history.',
    status_no_tokens: 'No token data',
    status_profile: 'Profile',
    status_hermes_home: 'Hermes home',
    status_started: 'Started',
    status_tokens: 'Tokens',
    status_unknown: 'Unknown',
    cmd_branch:'Fork this conversation into a new session',
    cmd_branch_usage:'/branch [name] — fork conversation (optionally with a name)',
    branch_forked:'Forked into new session',
    branch_failed:'Fork failed: ',
    fork_from_here:'Fork from here',
    forked_from:'Forked from',
    cmd_yolo: 'Переключить YOLO режим (без подтверждений)',
    yolo_no_session: 'Нет активного сеанса',
    yolo_enabled: '⚡ YOLO режим ВКЛ — подтверждения пропущены',
    yolo_disabled: 'YOLO режим ВЫКЛ',
    yolo_pill_label: 'YOLO',
    yolo_pill_title_active: 'YOLO режим активен — нажмите для отключения',
    approval_skip_all: '⚡ Пропустить все в этом сеансе',
    approval_skip_all_title: 'Пропустить все запросы подтверждения в этом сеансе',
    // composer action tooltips
    composer_send: 'Отправить сообщение',
    composer_queue: 'Поставить в очередь',
    composer_interrupt: 'Прервать и отправить',
    composer_steer: 'Направить ответ',
    composer_stop: 'Остановить генерацию',
    composer_disabled_clarify: 'Ответьте на запрос о разъяснении',
    composer_disabled_compression: 'Ожидание завершения сжатия',
    composer_disabled_empty: 'Введите сообщение для отправки',
    composer_mobile_workspace: 'Рабочее пространство',
    composer_mobile_model: 'Модель',
    composer_mobile_reasoning: 'Рассуждение',
    composer_mobile_context: 'Контекст',
    media_audio_label: 'Аудио',
    media_svg_label: 'Диаграмма',
    media_video_label: 'Видео',
    csv_loading: 'Загрузка CSV',
    csv_too_large: 'CSV-файл слишком большой для встроенного отображения',
    csv_no_data: 'Недостаточно данных в CSV-файле',
    csv_error: 'Не удалось загрузить CSV-файл',
    csv_header_note: 'Первая строка отображается как заголовок таблицы',
    excalidraw_loading: 'Загрузка диаграммы',
    excalidraw_too_large: 'Файл Excalidraw слишком большой для отображения',
    excalidraw_invalid: 'Неверный формат файла Excalidraw',
    excalidraw_error: 'Не удалось загрузить файл Excalidraw',
    excalidraw_label: 'Диаграмма',
    excalidraw_download: 'Скачать',
    excalidraw_empty: 'Пустая диаграмма',
    excalidraw_render_error: 'Не удалось отобразить диаграмму',
    excalidraw_simplified: 'Упрощённый предпросмотр SVG — не полностью идентичен оригиналу Excalidraw',
    pdf_loading: 'Загрузка PDF {0}…',
    pdf_too_large: 'PDF слишком большой для встроенного просмотра',
    pdf_no_pages: 'Не удалось отобразить предварительный просмотр PDF',
    pdf_error: 'Не удалось загрузить PDF',
    pdf_download: 'Скачать PDF',
    html_loading: 'Загрузка предпросмотра HTML…',
    html_too_large: 'HTML слишком большой для встроенного просмотра',
    html_error: 'Не удалось загрузить предпросмотр HTML',
    html_open_full: 'Открыть на всю страницу',
    html_sandbox_label: 'Предпросмотр HTML',
    // TTS (#499)
    tts_listen: 'Прослушать',
    tts_not_supported: 'Синтез речи не поддерживается',
    settings_label_tts: 'Синтез речи для ответов',
    settings_desc_tts: 'Показать кнопку динамика на сообщениях ассистента',
    settings_label_tts_auto_read: 'Авто-чтение ответов',
    settings_desc_tts_auto_read: 'Автоматически озвучивать ответы ассистента',
    // Composer voice-mode pref (#1488)
    settings_label_voice_mode: 'Кнопка режима свободных рук',
    settings_desc_voice_mode: 'Показывать кнопку голосового режима (аудиоволны) рядом с микрофоном диктовки. Hermes автоматически отправляет реплики после паузы и зачитывает ответы вслух. Требуется браузер с поддержкой распознавания речи и TTS.',
    settings_label_tts_voice: 'Голос',
    settings_desc_tts_voice: 'Выберите голос для синтеза речи',
    settings_label_tts_rate: 'Скорость речи',
    settings_label_tts_pitch: 'Тон речи',

    checkpoint_date: 'Date',  // TODO: translate
    checkpoint_diff_files_changed: (n) => `${n} file${n === 1 ? '' : 's'} changed`,  // TODO: translate
    checkpoint_diff_no_changes: 'No differences found between this checkpoint and the current workspace.',  // TODO: translate
    checkpoint_diff_title: 'Changes in checkpoint',  // TODO: translate
    checkpoint_empty: 'No checkpoints found for this workspace.',  // TODO: translate
    checkpoint_error: 'Failed to load checkpoints',  // TODO: translate
    checkpoint_files: 'Files',  // TODO: translate
    checkpoint_loading: 'Loading checkpoints…',  // TODO: translate
    checkpoint_message: 'Message',  // TODO: translate
    checkpoint_restore: 'Restore',  // TODO: translate
    checkpoint_restore_confirm_message: (ckpt) => `Restore workspace to checkpoint "${ckpt}"? This will overwrite files with the saved versions. Files added after this checkpoint will not be deleted.`,  // TODO: translate
    checkpoint_restore_confirm_title: 'Restore checkpoint?',  // TODO: translate
    checkpoint_restored: 'Checkpoint restored',  // TODO: translate
    checkpoint_title: 'Checkpoints',  // TODO: translate
    checkpoint_view_diff: 'View diff',  // TODO: translate
    insights_activity_by_day: 'Activity by Day',  // TODO: translate
    insights_activity_by_hour: 'Activity by Hour',  // TODO: translate
    insights_cost: 'Estimated Cost',  // TODO: translate
    insights_daily_tokens: 'Daily Tokens',
    insights_model_name: 'Model',
    insights_model_sessions: 'Sessions',
    insights_model_tokens: 'Tokens',
    insights_model_cost: 'Cost',
    insights_model_share: 'Share',
    insights_no_usage_data: 'No usage data yet',
    insights_footer: 'Showing data from the last {days} days',  // TODO: translate
    insights_input_tokens: 'Input',  // TODO: translate
    insights_messages: 'Messages',  // TODO: translate
    insights_models: 'Models',  // TODO: translate
    insights_no_cost: 'N/A',  // TODO: translate
    insights_output_tokens: 'Output',  // TODO: translate
    insights_peak_hour: 'Peak: {hour}',  // TODO: translate
    insights_sessions: 'Sessions',  // TODO: translate
    insights_title: 'Usage Analytics',  // TODO: translate
    insights_token_breakdown: 'Token Breakdown',  // TODO: translate
    insights_tokens: 'Tokens',  // TODO: translate
    insights_total: 'Total',  // TODO: translate
    settings_desc_api_redact: 'Self-hosted users can disable for transparency (not recommended for shared instances).',  // TODO: translate
    settings_label_api_redact: 'Redact sensitive data in API responses',  // TODO: translate
    subagent_children: 'Subagent sessions',  // TODO: translate
  },

  es: {
    offline_title: 'Conexión perdida',
    offline_browser_detail: 'Tu navegador indica que este dispositivo está sin conexión.',
    offline_network_detail: 'Hermes no está disponible desde este navegador ahora mismo.',
    offline_autorefresh: 'Actualizaré esta página automáticamente cuando Hermes vuelva a estar disponible.',
    offline_check_now: 'Comprobar ahora',
    offline_checking: 'Comprobando…',
    offline_stream_waiting: 'Conexión perdida. Esperando para actualizar…',
    _lang: 'es',
    _label: 'Español',
    _speech: 'es-ES',
    // boot.js
    cancelling: 'Cancelando…',
    cancel_failed: 'Error al cancelar: ',
    mic_denied: 'Acceso al micrófono denegado. Revisa los permisos del navegador.',
    mic_no_speech: 'No se detectó voz. Inténtalo de nuevo.',
    mic_network: 'El reconocimiento de voz no está disponible.',
    mic_error: 'Error de entrada por voz: ',
    session_imported: 'Sesión importada',
    import_failed: 'Error al importar: ',
    import_invalid_json: 'JSON inválido',
    image_pasted: 'Imagen pegada: ',
    // messages.js
    edit_message: 'Editar mensaje',
    regenerate: 'Regenerar respuesta',
    copy: 'Copiar',
    copied: '¡Copiado!',
    copy_failed: 'Error al copiar',
    selected_text_reply: 'Responder con selección',
    selected_text_reply_title: 'Añadir el texto del chat seleccionado como contexto citado',
    selected_text_reply_appended: 'Texto seleccionado añadido al compositor',

    diff_loading: 'Cargando diff',
    diff_error: 'No se pudo cargar el archivo de parche',
    diff_too_large: 'Archivo de parche demasiado grande para mostrar',
    tree_view: '树形',
    raw_view: '原始',
    parse_failed_note: 'parse failed',
    you: 'Tú',
    mcp_servers_title: 'MCP 服务器',
    mcp_servers_desc: '管理 config.yaml 中配置的 MCP 服务器。',
    mcp_no_servers: '未配置 MCP 服务器。',
    mcp_add_server: '+ 添加服务器',
    mcp_field_name: '服务器名称',
    mcp_transport_label: '传输类型',
    mcp_field_command: '命令',
    mcp_field_args: '参数（逗号分隔）',
    mcp_field_url: 'URL',
    mcp_field_timeout: '超时（秒）',
    mcp_save: '保存',
    mcp_cancel: '取消',
    mcp_name_required: '需要服务器名称。',
    mcp_url_required: 'HTTP 传输需要 URL。',
    mcp_command_required: 'stdio 传输需要命令。',
    mcp_saved: 'MCP 服务器已保存。',
    mcp_save_failed: '保存 MCP 服务器失败。',
    mcp_delete_confirm_title: '删除 MCP 服务器',
    mcp_delete_confirm_message: '删除 MCP 服务器「{0}」？此操作无法撤销。',
    mcp_deleted: 'MCP 服务器已删除。',
    mcp_delete_failed: '删除 MCP 服务器失败。',
    mcp_load_failed: '加载 MCP 服务器失败。',
    mcp_restart_hint: 'Server changes are read-only here for now. Edit config.yaml and restart Hermes for changes to take effect.',
    mcp_toggle_followup: 'Enable/disable controls are intentionally deferred until MCP reload semantics are explicit.',
    mcp_status_active: 'Active',
    mcp_status_configured: 'Configured',
    mcp_status_disabled: 'Disabled',
    mcp_status_invalid_config: 'Invalid config',
    mcp_status_unknown: 'Unknown',
    mcp_tool_count: '{0} tools',
    mcp_enabled_yes: 'Enabled',
    mcp_enabled_no: 'Disabled',
    mcp_tools_title: 'MCP Tools',
    mcp_tools_desc: 'Search known tools across active MCP servers.',
    mcp_tools_search_placeholder: 'Search tools by name, server, or description…',
    mcp_tools_no_tools: 'No MCP tools are available from the active runtime inventory.',
    mcp_tools_no_matches: 'No MCP tools match your search.',
    mcp_tools_load_failed: 'Failed to load MCP tools.',
    mcp_tools_schema_empty: 'No schema parameters.',
    mcp_tools_runtime_note: 'Tool inventory only uses already-known active MCP runtime data; the WebUI does not start or probe servers.',
    mcp_tools_summary_no_matches: (query,total) => `No MCP tools matching “${query}” (${total} total MCP tools).`,
    mcp_tools_summary_none: 'No MCP tools to show.',
    mcp_tools_summary_matching: (query) => ` matching “${query}”`,
    mcp_tools_summary_total_note: (total) => ` (${total} total MCP tools)`,
    mcp_tools_summary_showing: (start,end,filtered,searchNote,totalNote,page,pages) => `Showing ${start}-${end} of ${filtered} MCP tools${searchNote}${totalNote}. Page ${page} of ${pages}.`,
    mcp_tools_page_size_prefix: 'Show',
    mcp_tools_page_size_suffix: 'per page',
    mcp_tools_per_page_aria: 'MCP tools per page',
    mcp_tools_inactive_configured_servers: (servers) => `Configured but inactive in this WebUI runtime: ${servers}.`,
    mcp_tools_pagination_label: 'MCP tools pagination',
    mcp_tools_previous_page: '‹ Prev',
    mcp_tools_previous_page_aria: 'Previous MCP tools page',
    mcp_tools_next_page: 'Next ›',
    mcp_tools_next_page_aria: 'Next MCP tools page',
    thinking: 'Pensando',
    expand_all: 'Expandir todo',
    collapse_all: 'Contraer todo',
    edit_failed: 'Error al editar: ',
    regen_failed: 'Error al regenerar: ',
    reconnect_active: 'Todavía se está generando una respuesta. ¿Recargar cuando termine?',
    reconnect_finished: 'Había una respuesta en curso cuando te fuiste. Puede que los mensajes se hayan actualizado.',
    // approval card
    approval_heading: 'Se requiere aprobación',
    approval_desc_prefix: 'Se detectó un comando peligroso',
    approval_btn_once: 'Permitir una vez',
    approval_btn_once_title: 'Permitir solo este comando (Enter)',
    approval_btn_session: 'Permitir en la sesión',
    approval_btn_session_title: 'Permitir durante esta sesión de conversación',
    approval_btn_always: 'Permitir siempre',
    approval_btn_always_title: 'Permitir siempre este patrón de comando',
    approval_btn_deny: 'Denegar',
    approval_btn_deny_title: 'Denegar — no ejecutar este comando',
    approval_responding: 'Respondiendo…',
    clarify_heading: 'Se necesita aclaración',
    clarify_hint: 'Elige una opción o escribe tu propia respuesta abajo.',
    clarify_other: 'Otra',
    clarify_send: 'Enviar',
    clarify_input_placeholder: 'Escribe tu respuesta…',
    clarify_responding: 'Respondiendo…',
    untitled: 'Sin título',
    n_messages: (n) => `${n} mensajes`,
    load_older_messages: '↑ Desplázate hacia arriba o haz clic para cargar mensajes anteriores',
    session_jump_start: 'Inicio',
    session_jump_start_label: 'Saltar al inicio de la sesión',
    session_jump_end: 'Fin',
    session_jump_end_label: 'Saltar al final de la sesión',
    jump_to_question: 'a la pregunta',
    jump_to_question_label: 'Saltar a la pregunta de esta respuesta',
    queued_label: 'Enviar después de la respuesta',
    queued_count: (n) => n === 1 ? '1 en cola' : `${n} en cola`,
    queued_cancel: 'Cancelar mensaje en cola',
    model_unavailable: ' (no disponible)',
    model_unavailable_title: 'Este modelo ya no está en tu lista actual de proveedores',
    provider_mismatch_warning: (m,p)=>`"${m}" puede no funcionar con tu proveedor configurado (${p}). Envía de todas formas, o ejecuta \`hermes model\` en la terminal para cambiar.`,
    provider_mismatch_label: 'Proveedor incompatible',
    model_not_found_label: 'Modelo no encontrado',
    model_custom_label: 'ID de modelo personalizado',
    model_custom_placeholder: 'p. ej. openai/gpt-5.4',
    model_search_placeholder: 'Buscar modelos…',
    model_search_no_results: 'No se encontraron modelos',
    model_group_configured: 'Configurados',
    ws_search_placeholder: 'Buscar espacios de trabajo…',
    ws_no_results: 'No se encontraron espacios de trabajo',
    workspace_new_worktree_conversation: 'Nueva conversación en worktree',
    workspace_new_worktree_conversation_meta: 'Crear un git worktree aislado para este espacio de trabajo.',
    workspace_worktree_created: 'Conversación en worktree creada',
    workspace_worktree_failed: 'Error al crear worktree: ',
    session_worktree_badge: 'Worktree',
    session_toolsets: 'Session Toolsets', // TODO: translate
    session_toolsets_desc: 'Restrict available tools for this session (blank = use global config)', // TODO: translate
    session_toolsets_global: 'Global (default)', // TODO: translate
    session_toolsets_custom: 'Custom', // TODO: translate
    session_toolsets_placeholder: 'tool1, tool2, \u2026', // TODO: translate
    session_toolsets_apply: 'Apply', // TODO: translate
    session_toolsets_clear: 'Clear (use global)', // TODO: translate
    session_toolsets_applied: 'Toolsets updated', // TODO: translate
    session_toolsets_cleared: 'Toolsets cleared — using global config', // TODO: translate
    session_toolsets_failed: 'Failed to update toolsets: ', // TODO: translate
    model_scope_advisory: 'Se aplica a esta conversación desde tu próximo mensaje.',
    model_scope_toast: 'Se aplica a esta conversación desde tu próximo mensaje.',
    // commands.js
    cmd_help: 'Listar los comandos disponibles',
    cmd_clear: 'Borrar los mensajes de la conversación',
    cmd_compress: 'Comprimir manualmente el contexto de la conversación (uso: /compress [tema])',
    ctx_compress_hint: 'Comprimir contexto para liberar espacio →',
    ctx_compress_action: '⚠ Comprimir ahora para liberar contexto',
    cmd_compact_alias: 'Alias antiguo de /compress',
    cmd_compact: 'Comprimir contexto de la conversación',
    cmd_model: 'Cambiar de modelo (p. ej. /model gpt-4o)',
    cmd_workspace: 'Cambiar de espacio de trabajo por nombre',
    cmd_terminal: 'Abrir terminal del espacio de trabajo',
    cmd_new: 'Iniciar una nueva sesión de chat',
    cmd_usage: 'Activar o desactivar el uso de tokens',
    cmd_theme: 'Cambiar apariencia (tema: system/dark/light, skin: default/ares/mono/slate/poseidon/sisyphus/charizard/sienna/catppuccin/nous/geist-contrast)',
    cmd_personality: 'Cambiar la personalidad del agente',
    cmd_skills: 'Listar las skills de Hermes disponibles',
    available_commands: 'Comandos disponibles:',
    type_slash: 'Escribe / para ver los comandos',
    conversation_cleared: 'Conversación borrada',
    command_label: 'Comando',
    context_compaction_label: 'Compacción de contexto',
    retrieval_context_label: 'Contexto indexado',
    retrieval_context_preview: 'Los mensajes anteriores se almacenan y se pueden recuperar con herramientas de contexto',
    preserved_task_list_label: 'Lista de tareas conservada',
    reference_only_label: 'Solo referencia',
    model_usage: 'Uso: /model <name>',
    no_model_match: 'No hay ningún modelo que coincida con "',
    switched_to: 'Se cambió a ',
    workspace_usage: 'Uso: /workspace <name>',
    no_workspace_match: 'No hay ningún espacio de trabajo que coincida con "',
    switched_workspace: 'Se cambió al espacio de trabajo: ',
    workspace_switch_failed: 'Error al cambiar de espacio de trabajo: ',
    new_session: 'Nueva sesión creada',
    new_session_creating: 'Creando nueva conversación…',
    compressing: 'Solicitando compresión del contexto...',
    compress_running_label: 'Comprimiendo',
    compress_complete_label: 'Compresión completa',
    auto_compress_label: 'Compresión automática',
    compress_failed_label: 'La compresión falló',
    focus_label: 'Tema',
    token_usage_on: 'Uso de tokens activado',
    usage_personality_none: 'none', // TODO: translate
    token_usage_off: 'Uso de tokens desactivado',
    usage_cache_hit_detail: 'Caché: {0}% de acierto ({1} lectura / {2} escritura)',
    usage_cached_percent: '{0}% en caché',
    theme_usage: 'Uso: /theme ',
    theme_set: 'Tema: ',
    no_active_session: 'No hay ninguna sesión activa',
    cmd_queue: 'Poner mensaje en cola para el siguiente turno',
    cmd_goal: 'Definir o consultar un objetivo persistente',
    goal_evaluating_progress: 'Evaluating goal progress…',
    goal_working_toward: 'Working toward goal…',
    goal_continuing_toast: 'Continuing toward goal…',
    goal_status_none: 'No active goal. Set one with /goal <text>.',
    goal_status_active: (turns, max_turns, goal) => `⊙ Goal (active, ${turns}/${max_turns} turns): ${goal}`,
    goal_status_paused: (turns, max_turns, reason, goal) => `⏸ Goal (paused, ${turns}/${max_turns}${reason ? `, ${reason}` : ''}): ${goal}`,
    goal_status_done: (turns, max_turns, goal) => `✓ Goal done (${turns}/${max_turns}): ${goal}`,
    goal_set: (turns, goal) => `⊙ Goal set (${turns}-turn budget): ${goal}`,
    goal_paused: (goal) => `⏸ Goal paused: ${goal}`,
    goal_resumed: (goal) => `▶ Goal resumed: ${goal}`,
    goal_cleared: 'Goal cleared.',
    goal_no_goal: 'No active goal.',
    goal_achieved: (reason) => `✓ Goal achieved: ${reason}`,
    goal_paused_budget_exhausted: (turns, max_turns) => `⏸ Goal paused — ${turns}/${max_turns} turns used. Use /goal resume to keep going, or /goal clear to stop.`,
    goal_continuing: (turns, max_turns, reason) => `↻ Continuing toward goal (${turns}/${max_turns}): ${reason}`,
    cmd_interrupt: 'Cancelar turno actual y enviar nuevo mensaje',
    cmd_steer: 'Inyectar una corrección a mitad del turno sin interrumpir al agente',
    cmd_queue_no_msg: 'Uso: /queue <mensaje>',
    cmd_queue_not_busy: 'Sin tarea activa \u2014 env\u00eda normalmente',
    cmd_queue_confirm: 'Mensaje en cola',
    cmd_interrupt_no_msg: 'Uso: /interrupt <mensaje>',
    cmd_interrupt_confirm: 'Interrumpido \u2014 enviando nuevo mensaje',
    cmd_steer_no_msg: 'Uso: /steer <mensaje>',
    cmd_steer_fallback: 'Steer no disponible — en cola para el siguiente turno',
    cmd_steer_delivered: 'Steer entregado \u2014 el agente lo ver\u00e1 en su pr\u00f3ximo resultado de herramienta',
    steer_leftover_queued: 'Steer en cola para el pr\u00f3ximo turno',
    busy_steer_fallback: 'Steer no disponible — en cola para el siguiente turno',
    busy_interrupt_confirm: 'Interrumpido \u2014 enviando nuevo mensaje',
    settings_label_busy_input_mode: 'Modo de entrada ocupada',
    settings_desc_busy_input_mode: 'Controla qué sucede al enviar mensajes mientras el agente está activo. Cola espera; Interrumpir cancela y empieza de nuevo; Steer inyecta una corrección sin interrumpir (usa cola si el agente no está disponible).',
    settings_label_fade_text_effect: 'Efecto de desvanecimiento de texto',
    settings_desc_fade_text_effect: 'Hace aparecer gradualmente las palabras nuevas mientras el asistente responde. Similar a OpenWebUI; desactivado por defecto para máximo rendimiento.',
    settings_busy_input_mode_queue: 'Poner en cola',
    settings_busy_input_mode_interrupt: 'Interrumpir turno actual',
    settings_busy_input_mode_steer: 'Steer (corrección a mitad de turno)',
    no_personalities: 'No se encontraron personalidades (añádelas a ~/.hermes/personalities/)',
    available_personalities: 'Personalidades disponibles:',
    personality_switch_hint: '\n\nUsa `/personality <name>` para cambiar, o `/personality none` para limpiar.',
    personalities_load_failed: 'No se pudieron cargar las personalidades',
    personality_cleared: 'Personalidad borrada',
    personality_set: 'Personalidad: ',
    failed_colon: 'Error: ',
    // ui.js
    no_workspace: 'Sin espacio de trabajo',
    terminal_open_title: 'Abrir terminal del espacio de trabajo',
    terminal_no_workspace_title: 'Selecciona un espacio de trabajo para abrir el terminal',
    terminal_title: 'Terminal',
    terminal_clear: 'Limpiar',
    terminal_copy_output: 'Copiar salida',
    terminal_restart: 'Reiniciar',
    terminal_collapse: 'Contraer',
    terminal_expand: 'Expandir',
    terminal_close: 'Cerrar',
    terminal_input_placeholder: 'Ejecuta un comando...',
    terminal_start_failed: 'Error al iniciar el terminal: ',
    terminal_input_failed: 'Error de entrada del terminal: ',
    terminal_copy_failed: 'Error al copiar: ',
    terminal_error: 'Error del terminal',
    workspace_empty_no_path: 'No hay espacio de trabajo seleccionado. Configure un espacio de trabajo en Ajustes \u2192 Workspace para explorar archivos.',
    workspace_empty_dir: 'Este espacio de trabajo está vacío.',
    workspace_show_hidden_files: 'Mostrar archivos ocultos',
    workspace_show_hidden_files_desc: 'Include .DS_Store, .git, node_modules, and other hidden / system files in the file tree.',
    workspace_hidden_files_visible: 'hidden visible',
    workspace_hidden_files_visible_title: 'Hidden files are visible — click for options',
    workspace_options: 'Workspace options',
    // workspace.js
    unsaved_confirm: 'Tienes cambios sin guardar en la vista previa. ¿Descartar y navegar?',
    save: 'Guardar',
    edit: 'Editar',
    save_title: 'Guardar cambios',
    edit_title: 'Editar este archivo',
    saved: 'Guardado',
    save_failed: 'Error al guardar: ',
    image_load_failed: 'No se pudo cargar la imagen',
    file_open_failed: 'No se pudo abrir el archivo',
    downloading: (name) => `Descargando ${name}…`,
    double_click_rename: 'Haz doble clic para renombrar',
    renamed_to: 'Renombrado a ',
    rename_failed: 'Error al renombrar: ',
    delete_title: 'Eliminar',
    delete_confirm: (name) => `¿Eliminar ${name}?`,
    delete_dir_confirm: (name) => `¿Eliminar carpeta "${name}" y todo su contenido?`,
    rename_title: 'Renombrar',
    rename_prompt: 'Nuevo nombre:',
    deleted: 'Eliminado ',
    delete_failed: 'Error al eliminar: ',
    reveal_in_finder: 'Mostrar en el gestor de archivos',
    reveal_failed: 'Error al mostrar: ',
    copy_file_path: 'Copiar ruta del archivo',
    download_folder: 'Download Folder', // TODO: translate
    path_copied: 'Ruta del archivo copiada al portapapeles',
    path_copy_failed: 'Error al copiar la ruta: ',
    session_rename: 'Renombrar conversación',
    session_rename_desc: 'Editar el título de esta conversación',
    new_file_prompt: 'Nombre del archivo nuevo (p. ej. notes.md):',
    created: 'Creado ',
    create_failed: 'Error al crear: ',
    new_folder_prompt: 'Nombre de la carpeta nueva:',
    folder_created: 'Carpeta creada ',
    folder_create_failed: 'Error al crear la carpeta: ',
  workspace_auto_create_folder: 'Crear carpeta si no existe',
  folder_add_as_space_btn: 'Añadir como espacio',
  folder_add_as_space_msg: '¿Añadir esta carpeta como un nuevo espacio?',
  folder_add_as_space_title: '¿Añadir como espacio?',
    remove_title: 'Quitar',
    empty_dir: '(vacío)',
    upload_failed: 'Error al subir: ',
    upload_too_large: (maxMb, fileMb) => `El archivo es demasiado grande (${fileMb} MB). El tamaño máximo de subida es ${maxMb} MB.`,
    all_uploads_failed: (n) => `Fallaron las ${n} subida(s)`,
    archive_extracted: (n, c) => `${n} archivo(s) extraído(s) de ${c} archivo(s) comprimido(s)`,
    // settings panel
    settings_title: 'Configuración',
    settings_save_btn: 'Guardar configuración',
    settings_label_model: 'Modelo predeterminado',
    settings_desc_model: 'Se usa para conversaciones nuevas. Las conversaciones existentes conservan su modelo seleccionado.',
    settings_label_send_key: 'Tecla de envío',
    settings_label_theme: 'Tema',
    settings_label_skin: 'Piel',
    settings_label_font_size: 'Tamaño de fuente',
    font_size_small: 'Pequeño',
    font_size_default: 'Por defecto',
    font_size_large: 'Grande',
    font_size_xlarge: 'Extra grande',
    settings_autosave_saving: 'Guardando…',
    settings_autosave_saved: 'Guardado',
    settings_autosave_failed: 'Error al guardar',
    settings_autosave_retry: 'Reintentar',
    settings_label_language: 'Idioma',
    settings_label_quota_chip: 'Mostrar el chip de cuota del proveedor en el compositor',
    settings_desc_quota_chip: 'Muestra un indicador ambiental de cuota restante (por ejemplo, saldo de crédito de OpenRouter) en el pie del compositor. Predeterminado: desactivado. Solo visible en pantallas anchas (≥1400px) cuando se activa, para mantener el compositor despejado en portátiles y monitores estándar.',
    settings_label_hide_suggestions: 'Hide new-chat suggestions',
    settings_desc_hide_suggestions: 'Hide the three default suggestion buttons on the empty new-chat screen to avoid accidental taps.',
    settings_label_token_usage: 'Mostrar uso de tokens',
    settings_label_sidebar_density: 'Densidad de la barra lateral',
    cmd_reasoning: 'Toggle thinking visibility (show/hide), set effort level, or check current status',
    settings_label_external_sessions: 'Mostrar sesiones externas',
    settings_label_previous_messaging_sessions: 'Mostrar sesiones de mensajería anteriores',
    settings_label_sync_insights: 'Sincronizar con insights',
    settings_label_check_updates: 'Buscar actualizaciones',
    settings_label_whats_new_summary: "Summarize What's New with AI",
    settings_label_bot_name: 'Nombre predeterminado del asistente',
    settings_label_password: 'Contraseña de acceso',
    settings_saved: 'Configuración guardada',
    settings_save_failed: 'Error al guardar: ',
    settings_load_failed: 'Error al cargar la configuración: ',
    settings_saved_pw: 'Configuración guardada — la contraseña queda activada y este navegador sigue autenticado',
    settings_saved_pw_updated: 'Configuración guardada — contraseña actualizada',
    // login page (used server-side via /api/i18n/login endpoint)
    login_title: 'Iniciar sesión',
    login_subtitle: 'Introduce tu contraseña para continuar',
    login_placeholder: 'Contraseña',
    login_btn: 'Entrar',
    login_invalid_pw: 'Contraseña inválida',
    login_conn_failed: 'Error de conexión',
    dialog_confirm_title: 'Confirmar acción',
    dialog_prompt_title: 'Introduce un valor',
    dialog_confirm_btn: 'Confirmar',
    discard: 'Descartar',
    clear: 'Borrar',
    create: 'Crear',
    remove: 'Quitar',
    project_name_prompt: 'Nombre del proyecto:',
    // Sidebar & Tabs
    tab_chat: 'Chat',
    tab_tasks: 'Tareas',
    tab_skills: 'Habilidades',
    tab_memory: 'Memoria',
    tab_workspaces: 'Espacios',
    tab_profiles: 'Perfiles',
    tab_kanban: 'Kanban',
    kanban_board: 'Board',
    kanban_visible_tasks: '{0} visible tasks',
    kanban_search_tasks: 'Search tasks',
    kanban_all_assignees: 'All assignees',
    kanban_all_tenants: 'All tenants',
    kanban_include_archived: 'Include archived',
    kanban_no_matching_tasks: 'No matching tasks',
    kanban_no_data: 'No Kanban data',
    kanban_work_queue_hint: 'This is the Hermes Agent work queue. Create or triage a task, assign it, move it to Ready, then let the dispatcher claim it.',
    kanban_unavailable: 'Kanban unavailable',
    kanban_read_only: 'Read-only view',
    kanban_empty: 'Empty',
    kanban_task: 'Task',
    kanban_no_description: 'No description',
    kanban_refresh: 'Refresh',
    kanban_status_triage: 'Triage',
    kanban_status_todo: 'Todo',
    kanban_status_ready: 'Ready',
    kanban_status_running: 'Running',
    kanban_status_blocked: 'Blocked',
    kanban_status_done: 'Done',
    kanban_status_original_hint: 'Actual status: {0}. This dialog only supports Triage/Todo/Ready edits.',
    kanban_comments_count: 'Comments ({0})',
    kanban_events_count: 'Events ({0})',
    kanban_links: 'Links',
    kanban_parents: 'Parents',
    kanban_children: 'Children',
    kanban_runs_count: 'Runs ({0})',
    kanban_no_comments: 'No comments',
    kanban_no_events: 'No events',
    kanban_no_runs: 'No runs',
    kanban_title: 'Título',
    kanban_description: 'Descripción',
    kanban_description_placeholder: 'Opcional — qué hay que hacer, criterios de aceptación, enlaces',
    kanban_status: 'Estado',
    kanban_assignee: 'Responsable',
    kanban_assignee_placeholder: 'Opcional — déjalo en blanco para cualquier trabajador',
    kanban_tenant: 'Tenant',
    kanban_tenant_placeholder: 'Opcional — slug del proyecto o equipo',
    kanban_priority: 'Prioridad',
    kanban_priority_hint: 'Los números más altos se ejecutan primero. Predeterminado: 0.',
    kanban_title_required: 'El título es obligatorio.',
    kanban_edit_task: 'Editar tarea',
    kanban_run_dispatcher: 'Ejecutar despachador',
    kanban_run_dispatcher_confirm: 'Esto reclamará tareas Ready en este tablero y generará subprocesos worker (uno por tarea, hasta 8 por clic). ¿Continuar?',
    kanban_assignee_profiles_label: 'Perfiles Hermes',
    kanban_assignee_other_label: 'Otros (carriles CLI / perfiles eliminados)',
    kanban_assignee_unassigned: '— Sin asignar (no se ejecutará automáticamente) —',
    kanban_ready_needs_assignee: 'Elegiste «Sin asignar» + «Ready». El despachador omitirá esta tarea. Envía de nuevo para confirmar o selecciona un perfil.',
    kanban_dispatch_preview_prefix: 'Vista previa:',
    kanban_dispatch_run_prefix: 'Despachado:',
    kanban_dispatch_spawned: 'generadas',
    kanban_dispatch_promoted: 'promovidas',
    kanban_dispatch_reclaimed: 'recuperadas',
    kanban_dispatch_skipped_unassigned: 'omitidas (sin asignar)',
    kanban_dispatch_skipped_nonspawnable: 'omitidas (perfil desconocido)',
    kanban_dispatch_auto_blocked: 'auto-bloqueadas',
    kanban_dispatch_timed_out: 'expiradas',
    kanban_dispatch_crashed: 'fallaron',
    kanban_new_task: 'New task',
    kanban_add_comment: 'Add comment',
      kanban_only_mine: 'Only mine',
      kanban_bulk_action: 'Bulk action',
      kanban_nudge_dispatcher: 'Preview dispatcher',
      kanban_stats: 'Stats',
      kanban_worker_log: 'Worker log',
      kanban_block: 'Block',
      kanban_unblock: 'Unblock',
      kanban_back_to_board: 'Back to board',
      kanban_lanes_by_profile: 'Lanes by profile',
      kanban_new_board: 'New board…',
      kanban_rename_board: 'Rename current board…',
      kanban_archive_board: 'Archive current board…',
      kanban_archive_board_confirm: 'Archive board "{name}"? Tasks remain on disk and the board can be restored from kanban/boards/_archived/.',
      kanban_board_archived: 'Board archived',
      kanban_board_name: 'Name',
      kanban_board_slug: 'Slug (lowercase, hyphens)',
      kanban_board_description: 'Description (optional)',
      kanban_board_icon: 'Icon (emoji, optional)',
      kanban_board_color: 'Color (optional)',
      kanban_board_name_required: 'Name is required',
      kanban_board_slug_required: 'Slug is required',
      kanban_card_complete: 'complete',
      kanban_card_archive: 'archive',
      kanban_unassigned: 'unassigned',
    kanban_status_archived: 'Archived',
    tab_todos: 'Todos',
    tab_insights: 'Analíticas',
    tab_dashboard: 'Panel de Hermes',
    dashboard_loopback_warning: 'El panel solo usa loopback en el servidor. Navega desde el propio servidor o reinícialo con --host 0.0.0.0 (inseguro).',
    tab_logs: 'Logs',
    tab_settings: 'Ajustes',

    logs_title: 'Logs',  // TODO: translate
    logs_file: 'File',  // TODO: translate
    logs_tail: 'Tail',  // TODO: translate
    logs_auto_refresh: 'Auto-refresh (5s)',  // TODO: translate
    logs_wrap: 'Wrap lines',  // TODO: translate
    logs_copy_all: 'Copy all',  // TODO: translate
    logs_empty: 'No log lines yet.',  // TODO: translate
    logs_loading: 'Loading logs…',  // TODO: translate
    logs_load_failed: 'Logs failed to load',  // TODO: translate
    logs_status_idle: 'Choose a log file to view recent lines.',  // TODO: translate
    logs_no_mtime: 'not written yet',  // TODO: translate
    logs_truncated_hint: 'Showing the tail of a large log file; older bytes were skipped to keep memory bounded.',  // TODO: translate
    logs_copied: 'Logs copied',  // TODO: translate
    logs_severity: 'Severidad',
    logs_severity_all: 'Todo',
    logs_severity_errors: 'Errores',
    logs_severity_warnings: 'Advertencias+',
    logs_filter_active: 'mostrados (filtro activo)',
    new_conversation: 'Nueva conversación',
    filter_conversations: 'Filtrar conversaciones...',
    session_time_unknown: 'Desconocido',
    session_time_minutes_ago: (n) => `${n}m`,
    session_time_hours_ago: (n) => `${n}h`,
    session_time_days_ago: (n) => `${n}d`,
    session_time_last_week: '1sem',
    session_time_bucket_today: 'Hoy',
    session_time_bucket_yesterday: 'Ayer',
    session_time_bucket_this_week: 'Esta semana',
    session_time_bucket_last_week: 'La semana pasada',
    session_time_bucket_older: 'Más antiguo',
    scheduled_jobs: 'Tareas programadas',
    new_job: 'Nueva tarea',
    loading: 'Cargando...',
    search_skills: 'Buscar skills...',
    new_skill: 'Nueva skill',
    personal_memory: 'Memoria personal',
    current_task_list: 'Lista de tareas actual',
    workspace_desc: 'Añade y cambia espacios de trabajo para tus sesiones.',
    session_meta_messages: (n) => `${n} mens.`,
    session_meta_children: (n) => `${n} ${n === 1 ? 'hijo' : 'hijos'}`,
    session_meta_segments: (n) => `${n} ${n === 1 ? 'segmento' : 'segmentos'}`,
    session_lineage_segment_untitled: 'Segmento sin título',
    session_lineage_segment_open: 'Abrir segmento de linaje',
    new_profile: 'Nuevo perfil',
    transcript: 'Transcripción',
    download_transcript: 'Descargar como Markdown',
    import: 'Importar',
    export_session_json: 'JSON',
    export_session_json_tooltip: 'Exportar sesión completa como JSON',
    import_session_json_tooltip: 'Importar sesión desde JSON',
    clear_conversation_btn_tooltip: 'Borrar todos los mensajes de esta conversación',
    // Settings detail
    settings_label_rtl: 'Diseño de chat de derecha a izquierda',
    settings_desc_rtl: 'Invierte la alineación de los mensajes y la entrada del compositor para idiomas como árabe o hebreo. Afecta solo al área del chat — la barra lateral y otros paneles siguen de izquierda a derecha.',
    settings_label_sound: 'Sonido de notificación',
    settings_desc_sound: 'Reproduce un sonido cuando el asistente termina una respuesta.',
    settings_label_notifications: 'Notificaciones del navegador',
    settings_desc_notifications: 'Muestra una notificación del sistema cuando una respuesta termina mientras la pestaña está en segundo plano.',
    settings_desc_token_usage: 'Muestra el conteo de tokens de entrada/salida debajo de cada respuesta del asistente. También se puede alternar con /usage.',
    settings_sidebar_density_compact: 'Compacta',
    settings_sidebar_density_detailed: 'Detallada',
    settings_desc_sidebar_density: 'Controla cuántos metadatos muestra la lista de sesiones en la barra lateral izquierda.',
    settings_label_auto_title_refresh: 'Actualización adaptativa del título',
    settings_auto_title_refresh_off: 'Desactivado',
    settings_auto_title_refresh_5: 'Cada 5 intercambios',
    settings_auto_title_refresh_10: 'Cada 10 intercambios',
    settings_auto_title_refresh_20: 'Cada 20 intercambios',
    settings_desc_auto_title_refresh: 'Regenera automáticamente el título de la sesión basándose en el último intercambio, manteniéndolo relevante a medida que evoluciona la conversación. Requiere un modelo LLM de generación de títulos configurado.',
    settings_desc_external_sessions: 'Mostrar conversaciones de CLI, Telegram, Discord, Slack y otros canales en la lista de sesiones. Haz clic para importar y continuar.',
    settings_desc_previous_messaging_sessions: 'Mostrar sesiones antiguas de Discord, Telegram, Slack y Weixin reemplazadas por reset o compresión.',
    settings_desc_sync_insights: 'Refleja el uso de tokens de la WebUI en state.db para que hermes /insights incluya datos de sesiones del navegador. Desactivado por defecto.',
    settings_desc_check_updates: 'Muestra un banner cuando haya versiones más nuevas de la WebUI o del Agent. Ejecuta periódicamente un git fetch en segundo plano.',
    settings_desc_whats_new_summary: "Changes the What's New action from opening the raw diff first to generating a short, human-readable summary. The regular diff comparison stays available after the summary.",
    settings_desc_bot_name: 'Solo se usa para el perfil predeterminado. Los otros perfiles usan sus propios nombres.',
    settings_desc_password: 'Introduce una nueva contraseña para establecerla o cambiarla. Déjalo en blanco para mantener la configuración actual.',
    password_placeholder: 'Introduce una contraseña nueva…',
    password_env_var_locked: 'La variable de entorno HERMES_WEBUI_PASSWORD está definida y tiene prioridad. Quítala y reinicia el servidor para gestionar la contraseña desde aquí.',
    password_env_var_locked_placeholder: 'Bloqueado: la variable HERMES_WEBUI_PASSWORD está definida',
    disable_auth: 'Desactivar autenticación',
    sign_out: 'Cerrar sesión',
    // Providers panel (English fallback — native translations welcome in follow-up PRs)
    providers_tab_title: 'Providers',
    providers_section_title: 'Providers',
    providers_section_meta: 'Manage API keys for AI providers. Changes take effect immediately.',
    providers_status_configured: 'API key configured',
    providers_status_not_configured: 'No API key',
    providers_status_oauth: 'OAuth',
    providers_status_api_key: 'API key',
    providers_status_not_configured_label: 'Not configured',
    providers_oauth_hint: 'Authenticated via OAuth. No API key needed.',
    providers_oauth_config_yaml_hint: 'Token configured via config.yaml. To update, edit the providers section in your config.yaml or run hermes auth.',
    providers_oauth_not_configured_hint: 'Not authenticated. Run hermes auth in the terminal to configure this provider.',
    providers_save: 'Save',
    providers_remove: 'Remove',
    providers_saving: 'Saving…',
    providers_removing: 'Removing…',
    providers_enter_key: 'Please enter an API key',
    providers_empty: 'No configurable providers found.',
    providers_key_updated: 'API key saved',
    providers_key_removed: 'API key removed',
    providers_key_placeholder_new: 'sk-...',
    providers_key_placeholder_replace: 'Enter new key to replace…',
    provider_quota_title: 'Cuota del proveedor activo',
    provider_quota_active_provider: 'Proveedor activo',
    provider_quota_last_checked_after_refresh: 'Última comprobación tras actualizar',
    provider_quota_last_checked: 'Última comprobación {0}',
    provider_quota_refresh_usage: 'Actualizar uso',
    provider_quota_refreshing: 'Actualizando...',
    provider_quota_refresh_title: 'Actualizar ahora los límites de uso del proveedor',
    provider_quota_refresh_succeeded: 'Uso del proveedor actualizado',
    provider_quota_refresh_failed: 'Error al actualizar el uso del proveedor',
    provider_quota_session_limit: 'Límite de 5 horas',
    provider_quota_weekly_limit: 'Límite semanal',
    provider_quota_window_fallback: 'Ventana',
    provider_quota_metric_remaining: 'Restante',
    provider_quota_metric_used: 'Usado',
    provider_quota_metric_limit: 'Límite',
    provider_quota_status_available: 'disponible',
    provider_quota_status_exhausted: 'agotado',
    provider_quota_status_unavailable: 'no disponible',
    provider_quota_status_failed: 'fallido',
    provider_quota_status_checked: 'comprobado',
    provider_quota_status_no_key: 'sin clave',
    provider_quota_status_invalid_key: 'clave no válida',
    provider_quota_status_unsupported: 'no compatible',
    provider_quota_used_meta: '{0} usado',
    provider_quota_resets_meta: 'se restablece {0}',
    provider_quota_credential_pool: 'Grupo de credenciales',
    provider_quota_credential_label: 'Credencial {0}',
    provider_quota_pool_plans: 'Planes: {0}',
    provider_quota_pool_no_windows: 'No se informaron ventanas de límite de cuenta.',
    provider_quota_account_limits_loaded: 'Límites de cuenta cargados.',
    provider_quota_unavailable: 'Estado de cuota no disponible',
    provider_quota_retry_after: 'Reintentar después de {0}',
    provider_quota_pool_summary_available: '{0}/{1} disponibles',
    provider_quota_pool_summary_exhausted: '{0} agotadas',
    provider_quota_pool_summary_failed: '{0} fallidas',
    provider_quota_pool_summary_checked: '{0} comprobadas',
    cancel: 'Cancelar',
    create_job: 'Crear tarea',
    save_skill: 'Guardar skill',
    editing: 'Editando',
    // Empty state
    empty_title: '¿En qué puedo ayudarte?',
    empty_subtitle: 'Pregunta lo que quieras, ejecuta comandos, explora archivos o gestiona tus tareas programadas.',
    suggest_files: '¿Qué archivos hay en este espacio de trabajo?',
    suggest_schedule: '¿Qué tengo hoy en mi agenda?',
    suggest_plan: 'Ayúdame a planificar un proyecto pequeño.',
    // onboarding
    onboarding_badge: 'PRIMER USO',
    onboarding_title: 'Bienvenido a Hermes Web UI',
    onboarding_lead: 'Una guía rápida verificará Hermes, guardará una configuración real del proveedor, elegirá un espacio de trabajo y un modelo, y opcionalmente protegerá la app con una contraseña.',
    onboarding_back: 'Atrás',
    onboarding_continue: 'Continuar',
    onboarding_skip: 'Omitir configuración',
    onboarding_skipped: 'Configuración omitida — se usa la configuración existente.',
    onboarding_open: 'Abrir Hermes',
    onboarding_step_system_title: 'Comprobación del sistema',
    onboarding_step_system_desc: 'Verifica Hermes Agent y la visibilidad de la configuración.',
    onboarding_step_setup_title: 'Configuración del proveedor',
    onboarding_step_setup_desc: 'Guarda la configuración mínima real de Hermes.',
    onboarding_step_workspace_title: 'Espacio de trabajo + modelo',
    onboarding_step_workspace_desc: 'Elige los valores predeterminados para nuevas sesiones y chats.',
    onboarding_step_password_title: 'Contraseña opcional',
    onboarding_step_password_desc: 'Protege la Web UI antes de compartirla.',
    onboarding_step_finish_title: 'Finalizar',
    onboarding_step_finish_desc: 'Revisa todo y entra en la app.',
    onboarding_notice_system_ready: 'Parece que Hermes Agent está accesible desde la Web UI.',
    onboarding_notice_system_unavailable: 'Hermes Agent todavía no está totalmente disponible. Bootstrap puede instalarlo, pero la configuración del proveedor quizá aún requiera una terminal.',
    onboarding_check_agent: 'Hermes Agent',
    onboarding_check_agent_ready: 'Detectado e importable',
    onboarding_check_agent_missing: 'Falta o solo es parcialmente importable',
    onboarding_check_password: 'Contraseña',
    onboarding_check_password_enabled: 'Ya está activada',
    onboarding_check_password_disabled: 'Todavía no está activada',
    onboarding_check_provider: 'Configuración del proveedor',
    onboarding_check_provider_ready: 'Listo para chatear',
    onboarding_check_provider_partial: 'Guardado pero incompleto',
    onboarding_check_provider_pending: 'Necesita verificación',
    onboarding_config_file: 'Archivo de configuración:',
    onboarding_env_file: 'Archivo .env:',
    onboarding_unknown: 'Desconocido',
    onboarding_current_provider: 'Configuración actual:',
    onboarding_missing_imports: 'Importaciones faltantes:',
    onboarding_notice_setup_required: 'Elige aquí una ruta simple de proveedor. Los flujos OAuth avanzados siguen siendo del CLI de Hermes por ahora.',
    onboarding_notice_setup_already_ready: 'Ya se detectó una configuración funcional del proveedor de Hermes. Puedes conservarla o reemplazarla aquí.',
    onboarding_oauth_provider_ready_title: 'Proveedor ya autenticado',
    onboarding_oauth_provider_ready_body: 'Esta instancia está configurada para usar un proveedor OAuth (<strong>{provider}</strong>) configurado mediante la CLI de Hermes. No se necesita clave API aquí — haz clic en Continuar para finalizar la configuración.',
    onboarding_oauth_provider_not_ready_title: 'Proveedor OAuth no autenticado aún',
    onboarding_oauth_provider_not_ready_body: 'Esta instancia está configurada para usar <strong>{provider}</strong>, que utiliza OAuth en lugar de una clave API. Ejecuta <code>hermes auth</code> o <code>hermes model</code> en una terminal para autenticarte y recarga la interfaz web.',
    onboarding_oauth_switch_hint: 'O elige un proveedor diferente a continuación para cambiar a la configuración con clave API:',
    onboarding_notice_workspace: 'Estos valores reutilizan las mismas APIs de configuración que la app normal.',
    onboarding_workspace_label: 'Espacio de trabajo',
    onboarding_workspace_or_path: 'O introduce la ruta de un espacio de trabajo',
    onboarding_workspace_placeholder: '/home/you/workspace',
    onboarding_provider_label: 'Modo de configuración',
    onboarding_quick_setup_badge: 'configuración rápida',
    provider_category_easy_start: 'Inicio rápido',
    provider_category_self_hosted: 'Local / Open source',
    provider_category_specialized: 'Especializados',
    onboarding_api_key_label: 'API key',
    onboarding_api_key_placeholder: 'Déjala en blanco para conservar una key ya guardada',
    onboarding_api_key_label_optional: 'API key (optional)', // TODO: translate
    onboarding_api_key_placeholder_optional: 'Leave blank for keyless servers', // TODO: translate
    onboarding_api_key_help_keyless: 'Most LM Studio / Ollama / vLLM installs run keyless — leave this blank if your server doesn\'t require authentication. Use the Test connection button to verify.', // TODO: translate
    oauth_login_codex: 'Login with Codex (ChatGPT)', // TODO: translate
    oauth_codex_step1: 'Step 1: Visit this URL and enter the code', // TODO: translate
    oauth_codex_step2: 'Step 2: Enter this code on the page', // TODO: translate
    oauth_codex_polling: 'Waiting for authorization...', // TODO: translate
    oauth_codex_success: 'Codex OAuth login successful!', // TODO: translate
    oauth_codex_error: 'OAuth login failed', // TODO: translate
    oauth_codex_expired: 'Code expired, please try again', // TODO: translate
    onboarding_api_key_help_prefix: 'Se guarda como secreto en tu archivo .env de Hermes usando',
    onboarding_base_url_label: 'Base URL',
    onboarding_base_url_placeholder: 'https://tu-endpoint.example/v1',
    onboarding_base_url_help: 'Úsalo para routers OpenAI-compatible, servidores autoalojados, LiteLLM, Ollama, LM Studio, vLLM o endpoints parecidos.',
    onboarding_model_label: 'Modelo predeterminado',
    onboarding_workspace_help: 'Elige el modelo que Hermes debe usar para nuevos chats cuando termine la configuración.',
    onboarding_custom_model_placeholder: 'tu-modelo',
    onboarding_custom_model_help: 'Para endpoints personalizados, introduce el identificador exacto del modelo que espera tu servidor.',
    onboarding_notice_password_enabled: 'Ya hay una contraseña configurada. Introduce una nueva solo si quieres reemplazarla.',
    onboarding_notice_password_recommended: 'Es opcional, pero recomendable si vas a exponer la UI más allá de localhost.',
    onboarding_password_label: 'Contraseña (opcional)',
    onboarding_password_placeholder: 'Déjala en blanco para omitirla',
    onboarding_password_help: 'Las contraseñas se guardan mediante la API de configuración existente y se hashean en el servidor.',
    onboarding_notice_finish: 'Puedes volver a abrir Configuración más tarde para cambiar cualquiera de estos valores.',
    onboarding_not_set: 'Sin definir',
    onboarding_password_will_enable: 'Se activará',
    onboarding_password_will_replace: 'Se reemplazará',
    onboarding_password_keep_existing: 'Mantener la contraseña actual',
    onboarding_password_remains_disabled: 'Seguirá desactivada',
    onboarding_password_skipped: 'Se omitirá por ahora',
    onboarding_finish_help: 'Al finalizar se guarda <code>onboarding_completed</code> en la configuración y entras en la app normal.',
    onboarding_error_choose_workspace: 'Elige un espacio de trabajo antes de continuar.',
    onboarding_error_choose_model: 'Elige un modelo antes de continuar.',
    onboarding_error_provider_required: 'Elige un modo de configuración antes de continuar.',
    onboarding_error_base_url_required: 'La base URL es obligatoria para endpoints personalizados.',
    onboarding_probe_test_button: 'Test connection', // TODO: translate
    onboarding_probe_probing: 'Testing connection…', // TODO: translate
    onboarding_probe_ok: 'Connected. {n} model(s) available.', // TODO: translate
    onboarding_probe_error_generic: 'Could not reach the configured base URL.', // TODO: translate
    onboarding_probe_error_invalid_url: 'Base URL must start with http:// or https://.', // TODO: translate
    onboarding_probe_error_dns: 'Could not resolve the host. Check the URL or use the host\'s IP address.', // TODO: translate
    onboarding_probe_error_connect_refused: 'Connection refused — the server may not be running on that address. From inside Docker, try the host IP instead of localhost.', // TODO: translate
    onboarding_probe_error_timeout: 'The endpoint did not respond in time. Check that the server is running and the URL is correct.', // TODO: translate
    onboarding_probe_error_http_4xx: 'The endpoint returned a client error. Check authentication and the URL path (typically ends in /v1).', // TODO: translate
    onboarding_probe_error_http_5xx: 'The endpoint returned a server error. Check the LM Studio / Ollama server logs.', // TODO: translate
    onboarding_probe_error_parse: 'The endpoint did not return a model list in the expected shape. Verify the URL points to the OpenAI-compatible API root.', // TODO: translate
    onboarding_probe_error_unreachable: 'Could not reach the configured base URL.', // TODO: translate
    onboarding_error_probe_failed: 'Could not validate the configured base URL.', // TODO: translate
    onboarding_error_workspace_required: 'El espacio de trabajo es obligatorio.',
    onboarding_error_model_required: 'El modelo es obligatorio.',
    onboarding_complete: 'Onboarding completado',

    // panel/runtime i18n
    error_prefix: 'Error: ',
    not_available: 'N/A',
    never: 'never',
    add: 'Add',
    add_failed: 'Add failed: ',
    remove_failed: 'Remove failed: ',
    switch_failed: 'Switch failed: ',
    name_required: 'Name is required',
    content_required: 'Content is required',
    view: 'View',
    dismiss: 'Dismiss',
    disable: 'Disable',
    cron_no_jobs: 'No scheduled jobs found.',
    cron_status_off: 'off',
    cron_status_paused: 'paused',
    cron_status_error: 'error',
    cron_status_active: 'active',
    cron_status_running: 'ejecutándose\u2026',
    cron_status_needs_attention: 'needs attention',
    cron_attention_desc: 'This recurring job has no next run time. The scheduler may have failed to compute its next run.',
    cron_attention_croniter_hint: 'The Gateway runtime may be missing the croniter package. Restart the Gateway with cron support, then resume this job.',
    cron_attention_resume: 'Resume and recalculate',
    cron_jobs_project: 'Tareas Programadas',
    cron_attention_run_once: 'Run once now',
    cron_attention_copy_diagnostics: 'Copy diagnostics',
    cron_diagnostics_copied: 'Cron diagnostics copied',
    cron_next: 'Next',
    cron_last: 'Last',
    cron_run_now: 'Run now',
    cron_pause: 'Pause',
    cron_resume: 'Resume',
    cron_job_name_placeholder: 'Job name',
    cron_schedule_placeholder: 'Schedule',
    cron_prompt_placeholder: 'Prompt',
    cron_last_output: 'Last output',
    cron_expand_prompt: 'Expand prompt',
    cron_collapse_prompt: 'Collapse prompt',
    cron_expand_output: 'Expand output',
    cron_collapse_output: 'Collapse output',
    cron_all_runs: 'All runs',
    cron_hide_runs: 'Hide runs',
    cron_no_runs_yet: '(no runs yet)',
    cron_schedule_required_example: 'Schedule is required (e.g. "0 9 * * *" or "every 1h")',
    cron_schedule_required: 'Schedule is required',
    cron_prompt_required: 'Prompt is required',
    cron_job_created: 'Job created',
    cron_duplicate: 'Duplicar',
    cron_duplicated: 'Trabajo duplicado (en pausa)',
    cron_job_triggered: 'Job triggered',
    cron_job_paused: 'Job paused',
    cron_job_resumed: 'Job resumed',
    cron_job_updated: 'Job updated',
    cron_delete_confirm_title: 'Delete cron job',
    cron_delete_confirm_message: 'This cannot be undone.',
    cron_job_deleted: 'Job deleted',
    cron_completion_status: (name, status) => `Cron "${name}" ${status}`,
    status_failed: 'failed',
    status_completed: 'completed',
    todos_no_active: 'No active task list in this session.',
    clear_conversation_title: 'Clear conversation',
    clear_conversation_message: 'Clear all messages? This cannot be undone.',
    clear_failed: 'Clear failed: ',
    skills_no_match: 'No skills match.',
    linked_files: 'Linked Files',
    skill_load_failed: 'Could not load skill: ',
    skill_file_load_failed: 'Could not load file: ',
    skill_name_required: 'Skill name is required',
    skill_updated: 'Skill updated',
    skill_created: 'Skill created',
    skill_deleted: 'Skill deleted',
    skill_delete_confirm: 'Delete skill "{0}"?',
    skills_empty_title: 'Select a skill',
    skills_empty_sub: 'Pick a skill from the sidebar to view its contents, or create a new one.',
    skills_edit: 'Edit',
    skills_delete: 'Delete',
    skills_back_to: 'Back to {0}',
    tasks_empty_title: 'Select a scheduled job',
    tasks_empty_sub: 'Pick a job from the sidebar to view its details and runs, or create a new one.',
    workspaces_empty_title: 'Select a space',
    workspaces_empty_sub: 'Pick a space from the sidebar to view its files and settings, or add a new one.',
    profiles_empty_title: 'Select a profile',
    profiles_empty_sub: 'Pick an agent profile from the sidebar to view and edit its settings, or create a new one.',
    memory_notes_label: 'memory (notes)',
    memory_saved: 'Memory saved',
    my_notes: 'My Notes',
    user_profile: 'User Profile',
    no_notes_yet: 'No notes yet.',
    no_profile_yet: 'No profile yet.',
    agent_soul: 'Agent Soul',
    no_soul_yet: 'No soul defined yet.',
    workspace_choose_path: 'Choose workspace path',
    workspace_choose_path_meta: 'Add a validated path and switch this conversation',
    workspace_manage: 'Manage workspaces',
    workspace_manage_meta: 'Open the Spaces panel',
    workspace_use_title: 'Use in current session',
    workspace_use: 'Use',
    workspace_add_path_placeholder: 'Add workspace path (e.g. /home/user/my-project)',
    workspace_paths_validated_hint: 'Paths are validated as existing directories before saving.',

    workspace_drag_hint: 'Arrastra para reordenar',
    workspace_reorder_failed: 'Error al reordenar',
    workspace_added: 'Workspace added',
    workspace_renamed: 'Espacio renombrado',
    workspace_remove_confirm_title: 'Remove workspace',
    workspace_remove_confirm_message: (path) => `Remove "${path}"?`,
    workspace_removed: 'Workspace removed',
    workspace_switch_prompt_title: 'Switch workspace',
    workspace_switch_prompt_message: 'Enter an absolute workspace path to add and switch this conversation to.',
    workspace_switch_prompt_confirm: 'Switch',
    workspace_switch_prompt_placeholder: '/Users/you/project',
    workspace_not_added: 'Workspace was not added',
    workspace_already_saved: 'Workspace already saved — choose it from the list',
    workspace_busy_switch: 'Cannot switch workspace while agent is running',
    discard_file_edits_title: 'Discard file edits?',
    discard_file_edits_message: 'Switching workspaces will discard unsaved file edits in the preview.',
    workspace_switched_to: (name) => `Switched to ${name}`,
    profiles_no_profiles: 'No profiles found.',
    profile_api_keys_configured: 'API keys configured',
    profile_gateway_running: 'Gateway running',
    profile_gateway_stopped: 'Gateway stopped',
    profile_active: 'ACTIVE',
    profile_no_configuration: 'No configuration',
    profile_skill_count: (count) => `${count} habilidad${count === 1 ? '' : 'es'}`,
    profile_use: 'Use',
    profile_switch_title: 'Switch to this profile',
    profile_delete_title: 'Eliminar este perfil',
    profile_default_label: '(predeterminado)',
    profile_name_placeholder: 'Nombre del perfil (minúsculas, a-z, 0-9, guiones)',
    profile_clone_label: 'Clonar configuración del perfil activo',
    profile_model_label: 'Modelo / proveedor',
    profile_model_hint: 'Elige entre proveedores y modelos configurados para este nuevo perfil.',
    profile_model_use_default: 'Usar el valor predeterminado del perfil activo',
    profile_base_url_placeholder: 'URL base (opcional, p. ej. http://localhost:11434)',
    profile_api_key_placeholder: 'Clave API (opcional)',
    manage_profiles: 'Manage profiles',
    profiles_load_failed: 'Failed to load profiles',
    profile_switched_new_conversation: (name) => `Switched to profile: ${name} — new conversation started`,
    profile_switched: (name) => `Switched to profile: ${name}`,
    profile_name_rule: 'Lowercase letters, numbers, hyphens, underscores only',
    profile_base_url_rule: 'Base URL must start with http:// or https://',
    profile_created: (name) => `Profile created: ${name}`,
    profile_delete_confirm_title: (name) => `Delete profile "${name}"?`,
    profile_delete_confirm_message: 'Todas las sesiones, configuración, habilidades y memoria de este perfil se eliminarán de forma permanente. Esta acción no se puede deshacer.',
    profile_deleted: (name) => `Profile deleted: ${name}`,
    active_conversation_none: 'No active conversation selected.',
    active_conversation_meta: (title, count) => `${title} · ${count} message${count === 1 ? '' : 's'}`,
    settings_unsaved_changes: 'You have unsaved changes.',
    sign_out_failed: 'Error al cerrar sesión: ',
    disable_auth_confirm_title: 'Desactivar protección por contraseña',
    disable_auth_confirm_message: 'Anyone will be able to access this instance.',
    auth_disabled: 'Autenticación desactivada — protección por contraseña eliminada',
    disable_auth_failed: 'Failed to disable auth: ',
    bg_error_single: (title) => `"${title}" has encountered an error`,
    bg_error_multi: (count) => `${count} sessions have encountered an error`,
    // skill form
    skill_name: 'Nombre',
    skill_category: 'Categoría',
    skill_category_placeholder: 'Opcional, p. ej. devops',
    skill_content: 'Contenido de SKILL.md',
    skill_content_placeholder: 'Frontmatter YAML + cuerpo markdown',
    skill_rename_not_supported: 'No se admite renombrar una habilidad. Crea una nueva y elimina la anterior.',
    skill_metadata: 'Metadatos',
    // cron form
    cron_name_label: 'Nombre',
    cron_name_placeholder: 'Opcional',
    cron_schedule_label: 'Programación',
    cron_schedule_hint: "Usa 'every 1h' o una expresión cron para trabajos recurrentes. Duraciones como '30m' se ejecutan una sola vez.",
    cron_schedule_once_warning: "Las duraciones como '30m' se ejecutan una vez y se eliminan después de correr. Usa 'every 30m' para mantener un trabajo recurrente.",
    cron_prompt_label: 'Prompt',
    cron_deliver_label: 'Entregar salida a',
    cron_deliver_local: 'Local (solo guardar salida)',
    cron_profile_label: 'Perfil',
    cron_profile_server_default: 'predeterminado del servidor',
    cron_profile_server_default_hint: 'Usa el perfil predeterminado del servidor WebUI durante la ejecución. Los trabajos existentes sin perfil conservan este comportamiento heredado.',
    cron_toast_notifications_label: 'Avisos de finalización',
    cron_toast_notifications_hint: 'Muestra un toast cuando este cron termina. La insignia de Tareas y el marcador de nueva ejecución se actualizan aunque esté desactivado.',
    cron_toast_notifications_enabled: 'Activado',
    cron_toast_notifications_disabled: 'Desactivado',
    cron_skills_label: 'Habilidades',
    cron_skills_placeholder: 'Añadir habilidades (opcional)…',
    cron_skills_edit_hint: 'La lista de habilidades no es editable después de crear.',
    // workspace form
    workspace_name_label: 'Nombre',
    workspace_name_placeholder: 'Nombre opcional',
    workspace_path_label: 'Ruta',
    workspace_path_required: 'La ruta es obligatoria',
    workspace_path_readonly: 'La ruta no se puede cambiar. Solo renombrar.',
    workspace_new_title: 'Nuevo espacio',
    // profile form
    profile_name_label: 'Nombre',
    profile_base_url_label: 'URL base',
    profile_api_key_label: 'Clave API',
  
    cmd_status: 'Show session info',
    // Session management and settings keys (en fallback — pending translation)
    session_archive: 'Archive conversation',
    session_hide_external: 'Ocultar de la lista',
    session_archive_desc: 'Hide this conversation until archived is shown',
    session_archive_worktree_desc: 'Ocultar esta conversación; conservar su worktree en disco',
    session_hide_external_desc: 'Ocultar esta sesión importada de WebUI sin eliminar el historial original.',
    session_archive_failed: 'Archive failed: ',
    session_archived: 'Session archived',
    session_archived_worktree: 'Sesión archivada. El worktree permanece en disco.',
    session_hidden: 'Sesión ocultada de la lista',
    session_delete: 'Delete conversation',
    session_delete_desc: 'Permanently remove this conversation',
    session_delete_confirm: '¿Eliminar esta conversación?',
    session_delete_worktree_desc: 'Eliminar solo la conversación de WebUI; conservar el worktree en disco',
    session_delete_worktree_confirm: (path) => `¿Eliminar esta conversación? El worktree en ${path} permanecerá en disco.`,
    session_deleted: 'Conversación eliminada',
    session_deleted_worktree: 'Conversación eliminada. El worktree permanece en disco.',
    session_worktree_remove: 'Eliminar worktree',
    session_worktree_remove_desc: (path) => `Eliminar el git worktree en ${path} del disco`,
    session_worktree_remove_confirm: (path) => `¿Eliminar el git worktree del disco?\n\nRuta: ${path}\n\nSe eliminará todo el directorio del worktree. Los datos de la sesión permanecen en WebUI.`,
    session_worktree_remove_not_exists: (path) => `El worktree en ${path} ya no existe en el disco.`,
    session_worktree_remove_confirm_label: 'Eliminar',
    session_worktree_removed: 'Worktree eliminado.',
    session_worktree_remove_failed: 'Error al eliminar worktree: ',
    session_worktree_remove_status_failed: 'Error al leer el estado del worktree: ',
    session_worktree_remove_locked_by_stream: 'No se puede eliminar — una sesión de streaming activa está usando este worktree.',
    session_worktree_remove_locked_by_terminal: 'No se puede eliminar — una sesión de terminal activa está usando este worktree.',
    session_worktree_remove_unsafe_blocked: 'Resuelve los cambios locales o los commits no enviados antes de eliminar este worktree.',
    session_worktree_remove_dirty_warning: 'ADVERTENCIA: Este worktree tiene cambios no confirmados que se perderán.',
    session_worktree_remove_untracked_warning: (count) => `${count} archivo(s) no rastreados se eliminarán permanentemente.`,
    session_worktree_remove_ahead_warning: (ahead) => `${ahead} commit(s) no enviados se perderán.`,
    session_duplicate: 'Duplicate conversation',
    session_duplicate_desc: 'Create a copy with the same workspace and model',
    session_duplicate_failed: 'Duplicate failed: ',
    session_stop_response: 'Stop response',
    session_stop_response_desc: 'Cancel the running response for this conversation',
    session_duplicated: 'Session duplicated',
    session_move_project: 'Move to project',
    session_move_project_desc_has: 'Change the project for this conversation',
    session_move_project_desc_none: 'Assign a project to this conversation',
    session_pin: 'Pin conversation',
    session_pin_desc: 'Keep this conversation at the top',
    session_pin_failed: 'Pin failed: ',
    session_restore: 'Restore conversation',
    session_restore_desc: 'Bring this conversation back into the main list',
    session_restored: 'Session restored',
    session_unpin: 'Unpin conversation',
    session_unpin_desc: 'Remove from pinned',
    session_select_mode: 'Seleccionar',
    session_select_mode_desc: 'Selecciona conversaciones para gestión masiva',
    session_select_all: 'Seleccionar todo',
    session_deselect_all: 'Deseleccionar todo',
    session_selected_count: '{0} seleccionadas',
    session_batch_archive: 'Archivar',
    session_batch_delete: 'Eliminar',
    session_batch_move: 'Mover al proyecto',
    session_batch_delete_confirm: '¿Eliminar {0} conversaciones?',
    session_batch_archive_confirm: '¿Archivar {0} conversaciones?',
    session_batch_delete_worktree_confirm: '¿Eliminar {0} conversaciones? {1} conversaciones con worktree dejarán sus directorios de worktree en disco.',
    session_batch_archive_worktree_confirm: '¿Archivar {0} conversaciones? {1} conversaciones con worktree conservarán sus directorios de worktree en disco.',
    session_no_selection: 'Ninguna conversación seleccionada',
    settings_dropdown_appearance: 'Appearance',
    settings_dropdown_conversation: 'Conversation',
    settings_dropdown_preferences: 'Preferences',
    settings_dropdown_providers: 'Providers',
    settings_dropdown_system: 'System',
    settings_heading_subtitle: 'Preferences, conversation tools, and system controls.',
    settings_heading_title: 'Control Center',
    settings_section_appearance_meta: 'Theme, accent colors, and visual style.',
    settings_section_appearance_title: 'Appearance',
    settings_section_conversation_title: 'Conversation',
    settings_section_preferences_meta: 'Defaults and UI behavior for Hermes Web UI.',
    settings_section_preferences_title: 'Preferences',
    settings_section_system_meta: 'Instance version and access controls.',
    settings_check_now: 'Comprobar ahora',
    settings_checking: 'Comprobando\u2026',
    settings_up_to_date: 'Actualizado \u2713',
    settings_updates_available: '{count} actualización(es) disponible(s)',
    settings_updates_disabled: 'Comprobación de actualizaciones desactivada',
    settings_update_check_failed: 'Error al comprobar actualizaciones',
    settings_label_workspace_panel_open: 'Mantener panel de espacio abierto',
    settings_desc_workspace_panel_open: 'Al activar, el panel de archivos se abre automáticamente en cada nueva sesión. Aún puedes cerrarlo manualmente.',
    settings_label_session_jump_buttons: 'Mostrar botones de salto de sesión',
    settings_desc_session_jump_buttons: 'Muestra botones flotantes de Inicio y Fin al leer historiales de sesión largos.',

    settings_label_session_endless_scroll: 'Cargar mensajes antiguos al desplazarse hacia arriba',

    settings_desc_session_endless_scroll: 'Si está activado, los mensajes antiguos se cargan automáticamente al desplazarte hacia arriba. Si está desactivado, usa el botón de mensajes antiguos.',

    settings_label_tab_visibility: 'Pestañas de la barra lateral',
    settings_desc_tab_visibility: 'Elige qué pestañas aparecen en la barra lateral y el rail. Chat y Configuración siempre están visibles.',
    open_in_browser: 'Abrir en el navegador',
    settings_section_system_title: 'System',
    settings_tab_appearance: 'Appearance',
    settings_tab_conversation: 'Conversation',
    settings_tab_preferences: 'Preferences',
    settings_tab_plugins: 'Plugins',
    settings_plugins_title: 'Plugins',  // TODO: translate
    settings_plugins_meta: 'View installed Hermes plugins and the lifecycle hooks they register. This panel is read-only.',  // TODO: translate
    settings_plugins_empty: 'No Hermes plugins are currently visible. Install or enable plugins from the Hermes CLI/config to see them here.',  // TODO: translate
    plugins_unnamed: 'Unnamed plugin',  // TODO: translate
    plugins_no_description: 'No description provided.',  // TODO: translate
    plugins_no_hooks: 'No registered lifecycle hooks',  // TODO: translate
    plugins_registered_hooks: 'Registered hooks',  // TODO: translate
    plugins_enabled: 'Enabled',  // TODO: translate
    plugins_disabled: 'Disabled',  // TODO: translate
    plugins_active_provider: 'Active (provider)',  // TODO: translate
    plugins_provider_no_hooks: 'Provider plugin — no agent-visibility hooks',  // TODO: translate
    plugins_load_failed: 'Failed to load plugins: ',  // TODO: translate
    settings_tab_system: 'System',
    status_updated: 'Updated',
    status_ephemeral: 'Ephemeral snapshot — not saved to transcript history.',
    status_no_tokens: 'No token data',
    status_profile: 'Profile',
    status_hermes_home: 'Hermes home',
    status_started: 'Started',
    status_tokens: 'Tokens',
    status_unknown: 'Unknown',
    cmd_yolo: 'Alternar modo YOLO (saltar aprobaciones)',
    cmd_branch:'Fork this conversation into a new session',
    cmd_branch_usage:'/branch [name] — fork conversation (optionally with a name)',
    branch_forked:'Forked into new session',
    branch_failed:'Fork failed: ',
    fork_from_here:'Fork from here',
    forked_from:'Forked from',
    yolo_no_session: 'No hay sesión activa',
    yolo_enabled: '⚡ Modo YOLO activado — aprobaciones omitidas',
    yolo_disabled: 'Modo YOLO desactivado',
    yolo_pill_label: 'YOLO',
    yolo_pill_title_active: 'Modo YOLO activo — haz clic para desactivar',
    approval_skip_all: '⚡ Saltar todo en esta sesión',
    approval_skip_all_title: 'Saltar todas las solicitudes de aprobación en esta sesión',
    // composer action tooltips
    composer_send: 'Enviar mensaje',
    composer_queue: 'Poner en cola',
    composer_interrupt: 'Interrumpir y enviar',
    composer_steer: 'Dirigir respuesta actual',
    composer_stop: 'Detener generación',
    composer_disabled_clarify: 'Responde a la solicitud de aclaración',
    composer_disabled_compression: 'Esperando a que finalice la compresión',
    composer_disabled_empty: 'Escribe un mensaje para enviar',
    composer_mobile_workspace: 'Espacio de trabajo',
    composer_mobile_model: 'Modelo',
    composer_mobile_reasoning: 'Razonamiento',
    composer_mobile_context: 'Contexto',
    media_audio_label: 'Audio',
    media_svg_label: 'Diagrama',
    media_video_label: 'Vídeo',
    csv_loading: 'Cargando CSV',
    csv_too_large: 'Archivo CSV demasiado grande para mostrar en línea',
    csv_no_data: 'El archivo CSV no tiene suficientes datos para mostrar como tabla',
    csv_error: 'Error al cargar el archivo CSV',
    csv_header_note: 'La primera fila se muestra como encabezado de tabla',
    excalidraw_loading: 'Cargando diagrama',
    excalidraw_too_large: 'Archivo Excalidraw demasiado grande para mostrar en línea',
    excalidraw_invalid: 'Formato de archivo Excalidraw no válido',
    excalidraw_error: 'Error al cargar archivo Excalidraw',
    excalidraw_label: 'Diagrama',
    excalidraw_download: 'Descargar',
    excalidraw_empty: 'Diagrama vacío',
    excalidraw_render_error: 'Error al renderizar el diagrama',
    excalidraw_simplified: 'Vista previa SVG simplificada — no es idéntica al lienzo de Excalidraw',
    pdf_loading: 'Cargando PDF {0}…',
    pdf_too_large: 'PDF demasiado grande para vista previa',
    pdf_no_pages: 'No se pudo renderizar la vista previa del PDF',
    pdf_error: 'Error al cargar el PDF',
    pdf_download: 'Descargar PDF',
    html_loading: 'Cargando vista previa de HTML…',
    html_too_large: 'HTML demasiado grande para vista previa',
    html_error: 'Error al cargar la vista previa de HTML',
    html_open_full: 'Abrir página completa',
    html_sandbox_label: 'Vista previa de HTML',
    // TTS (#499)
    tts_listen: 'Escuchar',
    tts_not_supported: 'Síntesis de voz no disponible',
    settings_label_tts: 'Texto a voz para respuestas',
    settings_desc_tts: 'Mostrar botón de altavoz en mensajes del asistente',
    settings_label_tts_auto_read: 'Leer respuestas automáticamente',
    settings_desc_tts_auto_read: 'Leer en voz alta las respuestas del asistente automáticamente',
    // Composer voice-mode pref (#1488)
    settings_label_voice_mode: 'Hands-free voice mode button',  // TODO: translate
    settings_desc_voice_mode: 'Show the voice-mode button (audio waveform) next to the dictation mic. Lets you speak naturally — Hermes auto-sends after a pause and reads replies aloud. Requires a browser that supports both speech recognition and TTS.',  // TODO: translate
    settings_label_tts_voice: 'Voz',
    settings_desc_tts_voice: 'Seleccionar voz para síntesis de voz',
    settings_label_tts_rate: 'Velocidad de voz',
    settings_label_tts_pitch: 'Tono de voz',
    checkpoint_date: 'Date',  // TODO: translate
    checkpoint_diff_files_changed: (n) => `${n} file${n === 1 ? '' : 's'} changed`,  // TODO: translate
    checkpoint_diff_no_changes: 'No differences found between this checkpoint and the current workspace.',  // TODO: translate
    checkpoint_diff_title: 'Changes in checkpoint',  // TODO: translate
    checkpoint_empty: 'No checkpoints found for this workspace.',  // TODO: translate
    checkpoint_error: 'Failed to load checkpoints',  // TODO: translate
    checkpoint_files: 'Files',  // TODO: translate
    checkpoint_loading: 'Loading checkpoints…',  // TODO: translate
    checkpoint_message: 'Message',  // TODO: translate
    checkpoint_restore: 'Restore',  // TODO: translate
    checkpoint_restore_confirm_message: (ckpt) => `Restore workspace to checkpoint "${ckpt}"? This will overwrite files with the saved versions. Files added after this checkpoint will not be deleted.`,  // TODO: translate
    checkpoint_restore_confirm_title: 'Restore checkpoint?',  // TODO: translate
    checkpoint_restored: 'Checkpoint restored',  // TODO: translate
    checkpoint_title: 'Checkpoints',  // TODO: translate
    checkpoint_view_diff: 'View diff',  // TODO: translate
    insights_activity_by_day: 'Activity by Day',  // TODO: translate
    insights_activity_by_hour: 'Activity by Hour',  // TODO: translate
    insights_cost: 'Estimated Cost',  // TODO: translate
    insights_daily_tokens: 'Daily Tokens',
    insights_model_name: 'Model',
    insights_model_sessions: 'Sessions',
    insights_model_tokens: 'Tokens',
    insights_model_cost: 'Cost',
    insights_model_share: 'Share',
    insights_no_usage_data: 'No usage data yet',
    insights_footer: 'Showing data from the last {days} days',  // TODO: translate
    insights_input_tokens: 'Input',  // TODO: translate
    insights_messages: 'Messages',  // TODO: translate
    insights_models: 'Models',  // TODO: translate
    insights_no_cost: 'N/A',  // TODO: translate
    insights_output_tokens: 'Output',  // TODO: translate
    insights_peak_hour: 'Peak: {hour}',  // TODO: translate
    insights_sessions: 'Sessions',  // TODO: translate
    insights_title: 'Usage Analytics',  // TODO: translate
    insights_token_breakdown: 'Token Breakdown',  // TODO: translate
    insights_tokens: 'Tokens',  // TODO: translate
    insights_total: 'Total',  // TODO: translate
    settings_desc_api_redact: 'Self-hosted users can disable for transparency (not recommended for shared instances).',  // TODO: translate
    settings_label_api_redact: 'Redact sensitive data in API responses',  // TODO: translate
    voice_error: 'Voice not supported in this browser',  // TODO: translate
    voice_listening: 'Listening…',  // TODO: translate
    voice_mode_active: 'Voice mode on',  // TODO: translate
    voice_mode_off: 'Voice mode off',  // TODO: translate
    voice_speaking: 'Speaking…',  // TODO: translate
    voice_thinking: 'Thinking…',  // TODO: translate
    // Composer voice buttons (#1488)
    voice_dictate: 'Dictate',  // TODO: translate
    voice_dictate_active: 'Stop dictation',  // TODO: translate
    voice_mode_toggle: 'Voice mode',  // TODO: translate
    voice_mode_toggle_active: 'Exit voice mode',  // TODO: translate
    subagent_children: 'Subagent sessions',  // TODO: translate
  },

  de: {
    offline_title: 'Verbindung verloren',
    offline_browser_detail: 'Dein Browser meldet, dass dieses Gerät offline ist.',
    offline_network_detail: 'Hermes ist von diesem Browser aus gerade nicht erreichbar.',
    offline_autorefresh: 'Ich aktualisiere diese Seite automatisch, sobald Hermes wieder erreichbar ist.',
    offline_check_now: 'Jetzt prüfen',
    offline_checking: 'Prüfe…',
    offline_stream_waiting: 'Verbindung verloren. Warte auf Aktualisierung…',
    _lang: 'de',
    _label: 'Deutsch',
    _speech: 'de-DE',
    // boot.js
    cancelling: 'Wird abgebrochen\u2026',
    cancel_failed: 'Abbrechen fehlgeschlagen: ',
    mic_denied: 'Mikrofonzugriff verweigert. Überprüfen Sie die Browserberechtigungen.',
    mic_no_speech: 'Keine Sprache erkannt. Versuchen Sie es erneut.',
    mic_network: 'Spracherkennung nicht verfügbar.',
    mic_error: 'Spracheingabefehler: ',
    session_imported: 'Sitzung importiert',
    import_failed: 'Import fehlgeschlagen: ',
    import_invalid_json: 'Ungültiges JSON',
    image_pasted: 'Bild eingefügt: ',
    // messages.js
    edit_message: 'Nachricht bearbeiten',
    regenerate: 'Antwort regenerieren',
    copy: 'Kopieren',
    copied: 'Kopiert!',
    copy_failed: 'Kopieren fehlgeschlagen',
    selected_text_reply: 'Mit Auswahl antworten',
    selected_text_reply_title: 'Ausgewählten Chattext als Zitatkontext anhängen',
    selected_text_reply_appended: 'Auswahl zum Composer hinzugefügt',

    diff_loading: 'Lade Diff',
    diff_error: 'Patch-Datei konnte nicht geladen werden',
    diff_too_large: 'Patch-Datei zu groß für Inline-Anzeige',
    tree_view: 'Baum',
    raw_view: 'Rohdaten',
    parse_failed_note: 'parse failed',
    you: 'Du',
    mcp_servers_title: 'MCP-Server',
    mcp_servers_desc: 'MCP-Server in config.yaml verwalten.',
    mcp_no_servers: 'Keine MCP-Server konfiguriert.',
    mcp_add_server: '+ Server hinzufügen',
    mcp_field_name: 'Servername',
    mcp_transport_label: 'Transporttyp',
    mcp_field_command: 'Befehl',
    mcp_field_args: 'Argumente (kommagetrennt)',
    mcp_field_url: 'URL',
    mcp_field_timeout: 'Timeout (Sekunden)',
    mcp_save: 'Speichern',
    mcp_cancel: 'Abbrechen',
    mcp_name_required: 'Servername ist erforderlich.',
    mcp_url_required: 'URL für HTTP-Transport erforderlich.',
    mcp_command_required: 'Befehl für stdio-Transport erforderlich.',
    mcp_saved: 'MCP-Server gespeichert.',
    mcp_save_failed: 'Fehler beim Speichern.',
    mcp_delete_confirm_title: 'MCP-Server löschen',
    mcp_delete_confirm_message: 'MCP-Server «{0}» löschen? Dies kann nicht rückgängig gemacht werden.',
    mcp_deleted: 'MCP-Server gelöscht.',
    mcp_delete_failed: 'Fehler beim Löschen.',
    mcp_load_failed: 'Fehler beim Laden.',
    mcp_restart_hint: 'Server changes are read-only here for now. Edit config.yaml and restart Hermes for changes to take effect.',
    mcp_toggle_followup: 'Enable/disable controls are intentionally deferred until MCP reload semantics are explicit.',
    mcp_status_active: 'Active',
    mcp_status_configured: 'Configured',
    mcp_status_disabled: 'Disabled',
    mcp_status_invalid_config: 'Invalid config',
    mcp_status_unknown: 'Unknown',
    mcp_tool_count: '{0} tools',
    mcp_enabled_yes: 'Enabled',
    mcp_enabled_no: 'Disabled',
    mcp_tools_title: 'MCP Tools',
    mcp_tools_desc: 'Search known tools across active MCP servers.',
    mcp_tools_search_placeholder: 'Search tools by name, server, or description…',
    mcp_tools_no_tools: 'No MCP tools are available from the active runtime inventory.',
    mcp_tools_no_matches: 'No MCP tools match your search.',
    mcp_tools_load_failed: 'Failed to load MCP tools.',
    mcp_tools_schema_empty: 'No schema parameters.',
    mcp_tools_runtime_note: 'Tool inventory only uses already-known active MCP runtime data; the WebUI does not start or probe servers.',
    mcp_tools_summary_no_matches: (query,total) => `No MCP tools matching “${query}” (${total} total MCP tools).`,
    mcp_tools_summary_none: 'No MCP tools to show.',
    mcp_tools_summary_matching: (query) => ` matching “${query}”`,
    mcp_tools_summary_total_note: (total) => ` (${total} total MCP tools)`,
    mcp_tools_summary_showing: (start,end,filtered,searchNote,totalNote,page,pages) => `Showing ${start}-${end} of ${filtered} MCP tools${searchNote}${totalNote}. Page ${page} of ${pages}.`,
    mcp_tools_page_size_prefix: 'Show',
    mcp_tools_page_size_suffix: 'per page',
    mcp_tools_per_page_aria: 'MCP tools per page',
    mcp_tools_inactive_configured_servers: (servers) => `Configured but inactive in this WebUI runtime: ${servers}.`,
    mcp_tools_pagination_label: 'MCP tools pagination',
    mcp_tools_previous_page: '‹ Prev',
    mcp_tools_previous_page_aria: 'Previous MCP tools page',
    mcp_tools_next_page: 'Next ›',
    mcp_tools_next_page_aria: 'Next MCP tools page',
    thinking: 'Nachdenken',
    expand_all: 'Alle ausklappen',
    collapse_all: 'Alle einklappen',
    edit_failed: 'Bearbeiten fehlgeschlagen: ',
    regen_failed: 'Regeneration fehlgeschlagen: ',
    reconnect_active: 'Eine Antwort wird noch generiert. Neu laden, wenn bereit?',
    reconnect_finished: 'Eine Antwort war in Arbeit, als Sie zuletzt gegangen sind. Nachrichten könnten aktualisiert worden sein.',
    // approval card
    approval_heading: 'Genehmigung erforderlich',
    approval_desc_prefix: 'Gefährlicher Befehl erkannt',
    approval_btn_once: 'Einmal zulassen',
    approval_btn_once_title: 'Diesen einen Befehl zulassen (Enter)',
    approval_btn_session: 'Sitzung zulassen',
    approval_btn_session_title: 'Für diese Konversationssitzung zulassen',
    approval_btn_always: 'Immer zulassen',
    approval_btn_always_title: 'Dieses Befehlsmuster immer zulassen',
    approval_btn_deny: 'Ablehnen',
    approval_btn_deny_title: 'Ablehnen \u2014 diesen Befehl nicht ausführen',
    approval_responding: 'Antwortet\u2026',
    clarify_heading: 'Klärung erforderlich',
    clarify_hint: 'Wähle eine Option oder schreibe deine eigene Antwort unten.',
    clarify_other: 'Andere',
    clarify_send: 'Senden',
    clarify_input_placeholder: 'Gib deine Antwort ein…',
    clarify_responding: 'Antwortet\u2026',
    untitled: 'Unbenannt',
    n_messages: (n) => `${n} Nachrichten`,
    load_older_messages: '↑ Nach oben scrollen oder klicken, um ältere Nachrichten zu laden',
    session_jump_start: 'Anfang',
    session_jump_start_label: 'Zum Anfang der Sitzung springen',
    session_jump_end: 'Ende',
    session_jump_end_label: 'Zum Ende der Sitzung springen',
    jump_to_question: 'zur Frage',
    jump_to_question_label: 'Zur Frage dieser Antwort springen',
    queued_label: 'Wird nach Antwort gesendet',
    queued_count: (n) => n === 1 ? '1 in Warteschlange' : `${n} in Warteschlange`,
    queued_cancel: 'Nachricht abbrechen',
    model_unavailable: ' (nicht verfügbar)',
    model_unavailable_title: 'Dieses Modell ist nicht mehr in Ihrer aktuellen Provider-Liste',
    provider_mismatch_warning: (m,p)=>`"${m}" funktioniert möglicherweise nicht mit Ihrem konfigurierten Provider (${p}). Trotzdem senden, oder \`hermes model\` im Terminal ausführen.`,
    provider_mismatch_label: 'Provider-Konflikt',
    model_not_found_label: 'Modell nicht gefunden',
    // commands.js
    cmd_help: 'Verfügbare Befehle auflisten',
    archive_extracted: (n, c) => `${n} Datei(en) aus ${c} Archiv(en) entpackt`,
    cmd_clear: 'Konversationsverlauf löschen',
    cmd_compress: 'Kontext manuell komprimieren (Nutzung: /compress [Thema])',
    ctx_compress_hint: 'Kontext komprimieren um Platz zu schaffen →',
    ctx_compress_action: '⚠ Jetzt komprimieren um Kontext freizugeben',
    cmd_compact_alias: 'Alte Alias für /compress',
    cmd_model: 'Modell wechseln (z.B. /model gpt-4o)',
    cmd_workspace: 'Workspace nach Namen wechseln',
    cmd_terminal: 'Workspace-Terminal öffnen',
    cmd_new: 'Neue Chat-Sitzung starten',
    cmd_usage: 'Token-Verbrauchsanzeige umschalten',
    cmd_theme: 'Darstellung wechseln (Theme: system/dark/light, Skin: default/ares/mono/slate/poseidon/sisyphus/charizard/sienna/catppuccin/nous/geist-contrast)',
    cmd_personality: 'Agenten-Persönlichkeit wechseln',
    cmd_skills: 'Verfügbare Hermes-Skills auflisten',
    available_commands: 'Verfügbare Befehle:',
    type_slash: 'Tippe / für Befehle',
    conversation_cleared: 'Konversation gelöscht',
    command_label: 'Befehl',
    context_compaction_label: 'Kontextkomprimierung',
    retrieval_context_label: 'Indizierter Kontext',
    retrieval_context_preview: 'Frühere Nachrichten sind gespeichert und über Kontextwerkzeuge abrufbar',
    preserved_task_list_label: 'Beibehaltene Aufgabenliste',
    reference_only_label: 'Nur Referenz',
    model_usage: 'Nutzung: /model <name>',
    no_model_match: 'Kein Modell gefunden für "',
    switched_to: 'Gewechselt zu ',
    workspace_usage: 'Nutzung: /workspace <name>',
    no_workspace_match: 'Kein Workspace gefunden für "',
    switched_workspace: 'Gewechselt zu Workspace: ',
    workspace_switch_failed: 'Workspace-Wechsel fehlgeschlagen: ',
    new_session: 'Neue Sitzung erstellt',
    new_session_creating: 'Neue Unterhaltung wird erstellt…',
    compressing: 'Kontext-Komprimierung wird angefordert...',
    compress_running_label: 'Komprimierung',
    compress_complete_label: 'Komprimierung abgeschlossen',
    auto_compress_label: 'Automatische Komprimierung',
    compress_failed_label: 'Komprimierung fehlgeschlagen',
    focus_label: 'Thema',
    token_usage_on: 'Token-Verbrauch an',
    usage_personality_none: 'none', // TODO: translate
    token_usage_off: 'Token-Verbrauch aus',
    usage_cache_hit_detail: 'Cache: {0}% Treffer ({1} gelesen / {2} geschrieben)',
    usage_cached_percent: '{0}% im Cache',
    theme_usage: 'Nutzung: /theme ',
    theme_set: 'Theme: ',
    no_active_session: 'Keine aktive Sitzung',
    model_scope_advisory: 'Gilt für diesen Chat ab Ihrer nächsten Nachricht.',
    model_scope_toast: 'Gilt für diesen Chat ab Ihrer nächsten Nachricht.',
    cmd_queue: 'Nachricht f\u00fcr den n\u00e4chsten Durchgang einreihen',
    cmd_goal: 'Ein dauerhaftes Ziel setzen oder prüfen',
    goal_evaluating_progress: 'Evaluating goal progress…',
    goal_working_toward: 'Working toward goal…',
    goal_continuing_toast: 'Continuing toward goal…',
    goal_status_none: 'No active goal. Set one with /goal <text>.',
    goal_status_active: (turns, max_turns, goal) => `⊙ Goal (active, ${turns}/${max_turns} turns): ${goal}`,
    goal_status_paused: (turns, max_turns, reason, goal) => `⏸ Goal (paused, ${turns}/${max_turns}${reason ? `, ${reason}` : ''}): ${goal}`,
    goal_status_done: (turns, max_turns, goal) => `✓ Goal done (${turns}/${max_turns}): ${goal}`,
    goal_set: (turns, goal) => `⊙ Goal set (${turns}-turn budget): ${goal}`,
    goal_paused: (goal) => `⏸ Goal paused: ${goal}`,
    goal_resumed: (goal) => `▶ Goal resumed: ${goal}`,
    goal_cleared: 'Goal cleared.',
    goal_no_goal: 'No active goal.',
    goal_achieved: (reason) => `✓ Goal achieved: ${reason}`,
    goal_paused_budget_exhausted: (turns, max_turns) => `⏸ Goal paused — ${turns}/${max_turns} turns used. Use /goal resume to keep going, or /goal clear to stop.`,
    goal_continuing: (turns, max_turns, reason) => `↻ Continuing toward goal (${turns}/${max_turns}): ${reason}`,
    cmd_interrupt: 'Aktuellen Durchgang abbrechen und neue Nachricht senden',
    cmd_steer: 'Korrektursignal einf\u00fcgen ohne Unterbrechung',
    cmd_queue_no_msg: 'Verwendung: /queue <Nachricht>',
    cmd_queue_not_busy: 'Keine aktive Aufgabe \u2014 normal senden',
    cmd_queue_confirm: 'Nachricht eingereiht',
    cmd_interrupt_no_msg: 'Verwendung: /interrupt <Nachricht>',
    cmd_interrupt_confirm: 'Unterbrochen \u2014 neue Nachricht wird gesendet',
    cmd_steer_no_msg: 'Verwendung: /steer <Nachricht>',
    cmd_steer_fallback: 'Steer nicht verf\u00fcgbar \u2014 f\u00fcr n\u00e4chsten Durchgang eingereiht',
    cmd_steer_delivered: 'Steer geliefert \u2014 der Agent sieht es bei seinem n\u00e4chsten Tool-Ergebnis',
    steer_leftover_queued: 'Steer f\u00fcr n\u00e4chsten Durchgang eingereiht',
    busy_steer_fallback: 'Steer nicht verf\u00fcgbar \u2014 f\u00fcr n\u00e4chsten Durchgang eingereiht',
    busy_interrupt_confirm: 'Unterbrochen \u2014 neue Nachricht wird gesendet',
    settings_label_busy_input_mode: 'Eingabemodus bei Besch\u00e4ftigung',
    settings_desc_busy_input_mode: 'Steuert, was passiert, wenn Sie w\u00e4hrend der Agentenaktivit\u00e4t eine Nachricht senden. Warteschlange wartet; Unterbrechen bricht ab und startet neu; Steer f\u00fcgt eine Korrektur ein ohne zu unterbrechen.',
    settings_label_fade_text_effect: 'Text-Fade-Effekt',
    settings_desc_fade_text_effect: 'Blendet neu gestreamte Wörter während der Antwort des Assistenten sanft ein. Ähnlich wie OpenWebUI; für maximale Leistung standardmäßig deaktiviert.',
    settings_busy_input_mode_queue: 'In Warteschlange einreihen',
    settings_busy_input_mode_interrupt: 'Aktuellen Durchgang unterbrechen',
    settings_busy_input_mode_steer: 'Steer (Korrektur ohne Unterbrechung)',
    no_personalities: 'Keine Persönlichkeiten gefunden (füge sie in ~/.hermes/personalities/ hinzu)',
    available_personalities: 'Verfügbare Persönlichkeiten:',
    personality_switch_hint: '\n\nNutze `/personality <name>` zum Wechseln, oder `/personality none` zum Löschen.',
    personalities_load_failed: 'Fehler beim Laden der Persönlichkeiten',
    personality_cleared: 'Persönlichkeit gelöscht',
    personality_set: 'Persönlichkeit: ',
    failed_colon: 'Fehlgeschlagen: ',
    // ui.js
    no_workspace: 'Kein Workspace',
    terminal_open_title: 'Workspace-Terminal öffnen',
    terminal_no_workspace_title: 'Wähle einen Workspace, um das Terminal zu öffnen',
    terminal_title: 'Terminal',
    terminal_clear: 'Leeren',
    terminal_copy_output: 'Ausgabe kopieren',
    terminal_restart: 'Neu starten',
    terminal_collapse: 'Einklappen',
    terminal_expand: 'Ausklappen',
    terminal_close: 'Schließen',
    terminal_input_placeholder: 'Befehl ausführen...',
    terminal_start_failed: 'Terminal konnte nicht gestartet werden: ',
    terminal_input_failed: 'Terminal-Eingabe fehlgeschlagen: ',
    terminal_copy_failed: 'Kopieren fehlgeschlagen: ',
    terminal_error: 'Terminalfehler',
    workspace_empty_no_path: 'Kein Workspace ausgewählt. Wähle einen Workspace unter Einstellungen \u2192 Workspace, um Dateien zu durchsuchen.',
    workspace_empty_dir: 'Dieser Workspace ist leer.',
    workspace_show_hidden_files: 'Versteckte Dateien anzeigen',
    workspace_show_hidden_files_desc: '.DS_Store, .git, node_modules und weitere versteckte / Systemdateien im Dateibaum anzeigen.',
    workspace_hidden_files_visible: 'versteckt sichtbar',
    workspace_hidden_files_visible_title: 'Versteckte Dateien sind sichtbar — Klicken für Optionen',
    workspace_options: 'Arbeitsbereich-Optionen',
    dialog_confirm_title: 'Aktion bestätigen',
    dialog_prompt_title: 'Wert eingeben',
    dialog_confirm_btn: 'Bestätigen',
    // workspace.js
    unsaved_confirm: 'Sie haben ungespeicherte Änderungen in der Vorschau. Verwerfen und fortfahren?',
    discard: 'Verwerfen',
    save: 'Speichern',
    edit: 'Bearbeiten',
    clear: 'Leeren',
    create: 'Erstellen',
    remove: 'Entfernen',
    save_title: 'Änderungen speichern',
    edit_title: 'Diese Datei bearbeiten',
    saved: 'Gespeichert',
    save_failed: 'Speichern fehlgeschlagen: ',
    image_load_failed: 'Bild konnte nicht geladen werden',
    file_open_failed: 'Datei konnte nicht geöffnet werden',
    downloading: (name) => `Lade ${name} herunter\u2026`,
    double_click_rename: 'Doppelklick zum Umbenennen',
    renamed_to: 'Umbenannt in ',
    rename_failed: 'Umbenennen fehlgeschlagen: ',
    delete_title: 'Löschen',
    delete_confirm: (name) => `${name} löschen?`,
    delete_dir_confirm: (name) => `Ordner "${name}" und gesamten Inhalt löschen?`,
    rename_title: 'Umbenennen',
    rename_prompt: 'Neuer Name:',
    deleted: 'Gelöscht ',
    delete_failed: 'Löschen fehlgeschlagen: ',
    reveal_in_finder: 'Im Dateimanager anzeigen',
    reveal_failed: 'Anzeige fehlgeschlagen: ',
    copy_file_path: 'Dateipfad kopieren',
    download_folder: 'Download Folder', // TODO: translate
    path_copied: 'Dateipfad in die Zwischenablage kopiert',
    path_copy_failed: 'Pfad konnte nicht kopiert werden: ',
    session_rename: 'Unterhaltung umbenennen',
    session_rename_desc: 'Titel dieser Unterhaltung bearbeiten',
    new_file_prompt: 'Neuer Dateiname (z.B. notes.md):',
    project_name_prompt: 'Projektname:',
    created: 'Erstellt ',
    create_failed: 'Erstellen fehlgeschlagen: ',
    new_folder_prompt: 'Neuer Ordnername:',
    folder_created: 'Ordner erstellt ',
    folder_create_failed: 'Ordner erstellen fehlgeschlagen: ',
  workspace_auto_create_folder: 'Ordner erstellen, falls nicht vorhanden',
  folder_add_as_space_btn: 'Als Bereich hinzufügen',
  folder_add_as_space_msg: 'Diesen Ordner als neuen Bereich zur Liste hinzufügen?',
  folder_add_as_space_title: 'Als Bereich hinzufügen?',
    remove_title: 'Entfernen',
    empty_dir: '(leer)',
    upload_failed: 'Upload fehlgeschlagen: ',
    upload_too_large: (maxMb, fileMb) => `Datei ist zu groß (${fileMb} MB). Die maximale Uploadgröße beträgt ${maxMb} MB.`,
    all_uploads_failed: (n) => `Alle ${n} Upload(s) fehlgeschlagen`,
    // settings panel
    settings_title: 'Einstellungen',
    settings_save_btn: 'Einstellungen speichern',
    settings_label_model: 'Standard-Modell',
    settings_desc_model: 'Wird für neue Chats verwendet. Bestehende Chats behalten ihr ausgewähltes Modell.',
    settings_label_send_key: 'Sende-Taste',
    settings_label_theme: 'Theme',
    settings_label_skin: 'Skin',
    settings_label_font_size: 'Font size',
    font_size_small: 'Small',
    font_size_default: 'Default',
    font_size_large: 'Large',
    font_size_xlarge: 'Extra Large',
    settings_autosave_saving: 'Wird gespeichert…',
    settings_autosave_saved: 'Gespeichert',
    settings_autosave_failed: 'Speichern fehlgeschlagen',
    settings_autosave_retry: 'Wiederholen',
    settings_label_language: 'Sprache',
    settings_label_quota_chip: 'Anbieter-Kontingent-Chip im Editor anzeigen',
    settings_desc_quota_chip: 'Zeigt einen Hintergrund-Indikator des verbleibenden Kontingents (z. B. OpenRouter-Guthaben) in der Editor-Fußzeile an. Standardmäßig deaktiviert. Bei Aktivierung nur auf breiten Bildschirmen (≥1400px) sichtbar, damit der Editor auf Laptops und Standard-Desktops übersichtlich bleibt.',
    settings_label_hide_suggestions: 'Hide new-chat suggestions',
    settings_desc_hide_suggestions: 'Hide the three default suggestion buttons on the empty new-chat screen to avoid accidental taps.',
    settings_label_token_usage: 'Token-Verbrauch anzeigen',
    settings_label_sidebar_density: 'Seitenleistendichte',
    cmd_reasoning: 'Toggle thinking visibility (show/hide), set effort level, or check current status',
    settings_label_external_sessions: 'Externe Sitzungen anzeigen',
    settings_label_previous_messaging_sessions: 'Vorherige Messaging-Sitzungen anzeigen',
    settings_label_sync_insights: 'Mit Insights synchronisieren',
    settings_label_check_updates: 'Nach Updates suchen',
    settings_label_whats_new_summary: "Summarize What's New with AI",
    settings_label_bot_name: 'Standard-Assistentenname',
    settings_label_password: 'Zugangspasswort',
    settings_saved: 'Einstellungen gespeichert',
    settings_save_failed: 'Speichern fehlgeschlagen: ',
    settings_load_failed: 'Laden der Einstellungen fehlgeschlagen: ',
    settings_saved_pw: 'Einstellungen gespeichert — Passwortschutz aktiviert und dieser Browser bleibt angemeldet',
    settings_saved_pw_updated: 'Einstellungen gespeichert — Passwort aktualisiert',
    // login page
    login_title: 'Anmelden',
    login_subtitle: 'Geben Sie Ihr Passwort ein, um fortzufahren',
    login_placeholder: 'Passwort',
    login_btn: 'Anmelden',
    login_invalid_pw: 'Ungültiges Passwort',
    login_conn_failed: 'Verbindung fehlgeschlagen',
    dialog_confirm_title: 'Aktion bestätigen',
    dialog_prompt_title: 'Wert eingeben',
    dialog_confirm_btn: 'Bestätigen',
    discard: 'Verwerfen',
    clear: 'Leeren',
    create: 'Erstellen',
    remove: 'Entfernen',
    project_name_prompt: 'Projektname:',
    // Sidebar & Tabs
    tab_chat: 'Chat',
    tab_tasks: 'Aufgaben',
    tab_skills: 'Skills',
    tab_memory: 'Gedächtnis',
    tab_workspaces: 'Spaces',
    tab_profiles: 'Profile',
    tab_kanban: 'Kanban',
    kanban_board: 'Board',
    kanban_visible_tasks: '{0} visible tasks',
    kanban_search_tasks: 'Search tasks',
    kanban_all_assignees: 'All assignees',
    kanban_all_tenants: 'All tenants',
    kanban_include_archived: 'Include archived',
    kanban_no_matching_tasks: 'No matching tasks',
    kanban_no_data: 'No Kanban data',
    kanban_work_queue_hint: 'This is the Hermes Agent work queue. Create or triage a task, assign it, move it to Ready, then let the dispatcher claim it.',
    kanban_unavailable: 'Kanban unavailable',
    kanban_read_only: 'Read-only view',
    kanban_empty: 'Empty',
    kanban_task: 'Task',
    kanban_no_description: 'No description',
    kanban_refresh: 'Refresh',
    kanban_status_triage: 'Triage',
    kanban_status_todo: 'Todo',
    kanban_status_ready: 'Ready',
    kanban_status_running: 'Running',
    kanban_status_blocked: 'Blocked',
    kanban_status_done: 'Done',
    kanban_status_original_hint: 'Actual status: {0}. This dialog only supports Triage/Todo/Ready edits.',
    kanban_comments_count: 'Comments ({0})',
    kanban_events_count: 'Events ({0})',
    kanban_links: 'Links',
    kanban_parents: 'Parents',
    kanban_children: 'Children',
    kanban_runs_count: 'Runs ({0})',
    kanban_no_comments: 'No comments',
    kanban_no_events: 'No events',
    kanban_no_runs: 'No runs',
    kanban_title: 'Titel',
    kanban_description: 'Beschreibung',
    kanban_description_placeholder: 'Optional — was zu tun ist, Akzeptanzkriterien, Links',
    kanban_status: 'Status',
    kanban_assignee: 'Zugewiesen an',
    kanban_assignee_placeholder: 'Optional — leer lassen für beliebigen Worker',
    kanban_tenant: 'Mandant',
    kanban_tenant_placeholder: 'Optional — Projekt- oder Team-Slug',
    kanban_priority: 'Priorität',
    kanban_priority_hint: 'Höhere Zahlen laufen zuerst. Standard: 0.',
    kanban_title_required: 'Titel ist erforderlich.',
    kanban_edit_task: 'Aufgabe bearbeiten',
    kanban_run_dispatcher: 'Dispatcher ausführen',
    kanban_run_dispatcher_confirm: 'Dies beansprucht Ready-Aufgaben auf diesem Board und startet Worker-Subprozesse (einen pro Aufgabe, bis zu 8 pro Klick). Fortfahren?',
    kanban_assignee_profiles_label: 'Hermes-Profile',
    kanban_assignee_other_label: 'Andere (CLI-Bahnen / entfernte Profile)',
    kanban_assignee_unassigned: '— Nicht zugewiesen (läuft nicht automatisch) —',
    kanban_ready_needs_assignee: 'Du hast „Nicht zugewiesen“ + „Ready“ gewählt. Der Dispatcher überspringt diese Aufgabe. Erneut senden zum Bestätigen oder ein Profil wählen.',
    kanban_dispatch_preview_prefix: 'Vorschau:',
    kanban_dispatch_run_prefix: 'Gestartet:',
    kanban_dispatch_spawned: 'gestartet',
    kanban_dispatch_promoted: 'befördert',
    kanban_dispatch_reclaimed: 'zurückgenommen',
    kanban_dispatch_skipped_unassigned: 'übersprungen (kein Bearbeiter)',
    kanban_dispatch_skipped_nonspawnable: 'übersprungen (unbekanntes Profil)',
    kanban_dispatch_auto_blocked: 'auto-blockiert',
    kanban_dispatch_timed_out: 'Zeitüberschreitung',
    kanban_dispatch_crashed: 'abgestürzt',
    kanban_new_task: 'New task',
    kanban_add_comment: 'Add comment',
      kanban_only_mine: 'Only mine',
      kanban_bulk_action: 'Bulk action',
      kanban_nudge_dispatcher: 'Preview dispatcher',
      kanban_stats: 'Stats',
      kanban_worker_log: 'Worker log',
      kanban_block: 'Block',
      kanban_unblock: 'Unblock',
      kanban_back_to_board: 'Back to board',
      kanban_lanes_by_profile: 'Lanes by profile',
      kanban_new_board: 'New board…',
      kanban_rename_board: 'Rename current board…',
      kanban_archive_board: 'Archive current board…',
      kanban_archive_board_confirm: 'Archive board "{name}"? Tasks remain on disk and the board can be restored from kanban/boards/_archived/.',
      kanban_board_archived: 'Board archived',
      kanban_board_name: 'Name',
      kanban_board_slug: 'Slug (lowercase, hyphens)',
      kanban_board_description: 'Description (optional)',
      kanban_board_icon: 'Icon (emoji, optional)',
      kanban_board_color: 'Color (optional)',
      kanban_board_name_required: 'Name is required',
      kanban_board_slug_required: 'Slug is required',
      kanban_card_complete: 'complete',
      kanban_card_archive: 'archive',
      kanban_unassigned: 'unassigned',
    kanban_status_archived: 'Archived',
    tab_todos: 'Todos',
    tab_insights: 'Statistiken',
    tab_dashboard: 'Hermes-Dashboard',
    dashboard_loopback_warning: 'Das Dashboard ist auf dem Server nur per Loopback erreichbar. Öffne es direkt auf dem Server oder starte es mit --host 0.0.0.0 neu (unsicher).',
    tab_logs: 'Logs',
    tab_settings: 'Einstellungen',

    logs_title: 'Logs',  // TODO: translate
    logs_file: 'File',  // TODO: translate
    logs_tail: 'Tail',  // TODO: translate
    logs_auto_refresh: 'Auto-refresh (5s)',  // TODO: translate
    logs_wrap: 'Wrap lines',  // TODO: translate
    logs_copy_all: 'Copy all',  // TODO: translate
    logs_empty: 'No log lines yet.',  // TODO: translate
    logs_loading: 'Loading logs…',  // TODO: translate
    logs_load_failed: 'Logs failed to load',  // TODO: translate
    logs_status_idle: 'Choose a log file to view recent lines.',  // TODO: translate
    logs_no_mtime: 'not written yet',  // TODO: translate
    logs_truncated_hint: 'Showing the tail of a large log file; older bytes were skipped to keep memory bounded.',  // TODO: translate
    logs_copied: 'Logs copied',  // TODO: translate
    logs_severity: 'Schweregrad',
    logs_severity_all: 'Alle',
    logs_severity_errors: 'Fehler',
    logs_severity_warnings: 'Warnungen+',
    logs_filter_active: 'angezeigt (Filter aktiv)',
    new_conversation: 'Neuer Chat',
    filter_conversations: 'Chats filtern...',
    scheduled_jobs: 'Geplante Aufgaben',
    new_job: 'Neuer Job',
    loading: 'Lädt...',
    search_skills: 'Skills suchen...',
    new_skill: 'Neuer Skill',
    personal_memory: 'Persönliches Gedächtnis',
    current_task_list: 'Aktuelle Aufgabenliste',
    workspace_desc: 'Workspaces hinzufügen und wechseln.',
    session_meta_messages: (n) => `${n} Nachr.`,
    session_meta_children: (n) => `${n} ${n === 1 ? 'Subagent' : 'Subagents'}`,
    session_meta_segments: (n) => `${n} Segment${n === 1 ? '' : 'e'}`,
    session_lineage_segment_untitled: 'Unbenanntes Segment',
    session_lineage_segment_open: 'Liniensegment öffnen',
    new_profile: 'Neues Profil',
    transcript: 'Protokoll',
    download_transcript: 'Als Markdown herunterladen',
    import: 'Importieren',
    export_session_json: 'JSON',
    export_session_json_tooltip: 'Gesamte Sitzung als JSON exportieren',
    import_session_json_tooltip: 'Sitzung aus JSON importieren',
    clear_conversation_btn_tooltip: 'Alle Nachrichten in dieser Konversation löschen',
    // Settings detail
    settings_label_rtl: 'Chat-Layout von rechts nach links',
    settings_desc_rtl: 'Kehrt die Ausrichtung von Chat-Nachrichten und Eingabefeld für Sprachen wie Arabisch oder Hebräisch um. Betrifft nur den Chat-Bereich — Seitenleiste und andere Panels bleiben von links nach rechts.',
    settings_label_sound: 'Benachrichtigungston',
    settings_desc_sound: 'Spielt einen Ton ab, wenn der Assistent eine Antwort beendet.',
    settings_label_notifications: 'Browser-Benachrichtigungen',
    settings_desc_notifications: 'Zeigt eine Systembenachrichtigung an, wenn eine Antwort fertiggestellt wird, während der Tab im Hintergrund ist.',
    settings_desc_token_usage: 'Zeigt die Anzahl der Input/Output-Token unter jeder Antwort des Assistenten an. Auch umschaltbar mit /usage.',
    settings_sidebar_density_compact: 'Kompakt',
    settings_sidebar_density_detailed: 'Detailliert',
    settings_desc_sidebar_density: 'Steuert, wie viele Metadaten die Sitzungsliste in der linken Seitenleiste anzeigt.',
    settings_label_auto_title_refresh: 'Adaptive Titelaktualisierung',
    settings_auto_title_refresh_off: 'Aus',
    settings_auto_title_refresh_5: 'Alle 5 Antworten',
    settings_auto_title_refresh_10: 'Alle 10 Antworten',
    settings_auto_title_refresh_20: 'Alle 20 Antworten',
    settings_desc_auto_title_refresh: 'Generiert den Sitzungstitel automatisch anhand des letzten Austauschs neu und hält ihn so aktuell, während sich das Gespräch entwickelt. Erfordert ein konfiguriertes LLM-Titelgenerierungsmodell.',
    settings_desc_external_sessions: 'Zeigt Gespräche von CLI, Telegram, Discord, Slack und anderen Kanälen in der Sitzungsliste an. Klicken zum Importieren und Fortsetzen.',
    settings_desc_previous_messaging_sessions: 'Zeigt ältere Discord-, Telegram-, Slack- und Weixin-Sitzungen, die durch Reset oder Compression ersetzt wurden.',
    settings_desc_sync_insights: 'Spiegelt den WebUI-Token-Verbrauch in die state.db, sodass hermes /insights Browser-Sitzungsdaten enthält. Standardmäßig aus.',
    settings_desc_check_updates: 'Zeigt ein Banner an, wenn neuere Versionen der WebUI oder des Agenten verfügbar sind. Führt regelmäßig einen Git-Fetch im Hintergrund aus.',
    settings_desc_whats_new_summary: "Changes the What's New action from opening the raw diff first to generating a short, human-readable summary. The regular diff comparison stays available after the summary.",
    settings_desc_bot_name: 'Wird nur für das Standardprofil verwendet. Andere Profile verwenden ihre eigenen Namen.',
    settings_desc_password: 'Geben Sie ein neues Passwort ein, um es zu setzen oder zu ändern. Leer lassen, um die aktuelle Einstellung beizubehalten.',
    password_placeholder: 'Neues Passwort eingeben…',
    password_env_var_locked: 'Die Umgebungsvariable HERMES_WEBUI_PASSWORD ist gesetzt und hat Vorrang. Entferne sie und starte den Server neu, um das Passwort hier zu verwalten.',
    password_env_var_locked_placeholder: 'Gesperrt: HERMES_WEBUI_PASSWORD-Umgebungsvariable ist gesetzt',
    disable_auth: 'Authentifizierung deaktivieren',
    sign_out: 'Abmelden',
    // Providers panel (English fallback — native translations welcome in follow-up PRs)
    providers_tab_title: 'Providers',
    providers_section_title: 'Providers',
    providers_section_meta: 'Manage API keys for AI providers. Changes take effect immediately.',
    providers_status_configured: 'API key configured',
    providers_status_not_configured: 'No API key',
    providers_status_oauth: 'OAuth',
    providers_status_api_key: 'API key',
    providers_status_not_configured_label: 'Not configured',
    providers_oauth_hint: 'Authenticated via OAuth. No API key needed.',
    providers_oauth_config_yaml_hint: 'Token configured via config.yaml. To update, edit the providers section in your config.yaml or run hermes auth.',
    providers_oauth_not_configured_hint: 'Not authenticated. Run hermes auth in the terminal to configure this provider.',
    providers_save: 'Save',
    providers_remove: 'Remove',
    providers_saving: 'Saving…',
    providers_removing: 'Removing…',
    providers_enter_key: 'Please enter an API key',
    providers_empty: 'No configurable providers found.',
    providers_key_updated: 'API key saved',
    providers_key_removed: 'API key removed',
    providers_key_placeholder_new: 'sk-...',
    providers_key_placeholder_replace: 'Enter new key to replace…',
    provider_quota_title: 'Kontingent des aktiven Anbieters',
    provider_quota_active_provider: 'Aktiver Anbieter',
    provider_quota_last_checked_after_refresh: 'Zuletzt nach Aktualisierung geprüft',
    provider_quota_last_checked: 'Zuletzt geprüft {0}',
    provider_quota_refresh_usage: 'Nutzung aktualisieren',
    provider_quota_refreshing: 'Wird aktualisiert...',
    provider_quota_refresh_title: 'Nutzungslimits des Anbieters jetzt aktualisieren',
    provider_quota_refresh_succeeded: 'Anbieternutzung aktualisiert',
    provider_quota_refresh_failed: 'Aktualisierung der Anbieternutzung fehlgeschlagen',
    provider_quota_session_limit: '5-Stunden-Limit',
    provider_quota_weekly_limit: 'Wöchentliches Limit',
    provider_quota_window_fallback: 'Fenster',
    provider_quota_metric_remaining: 'Verbleibend',
    provider_quota_metric_used: 'Verwendet',
    provider_quota_metric_limit: 'Limit',
    provider_quota_status_available: 'verfügbar',
    provider_quota_status_exhausted: 'ausgeschöpft',
    provider_quota_status_unavailable: 'nicht verfügbar',
    provider_quota_status_failed: 'fehlgeschlagen',
    provider_quota_status_checked: 'geprüft',
    provider_quota_status_no_key: 'kein Schlüssel',
    provider_quota_status_invalid_key: 'ungültiger Schlüssel',
    provider_quota_status_unsupported: 'nicht unterstützt',
    provider_quota_used_meta: '{0} verwendet',
    provider_quota_resets_meta: 'Zurücksetzung {0}',
    provider_quota_credential_pool: 'Anmeldedatenpool',
    provider_quota_credential_label: 'Anmeldedaten {0}',
    provider_quota_pool_plans: 'Pläne: {0}',
    provider_quota_pool_no_windows: 'Keine Kontolimit-Fenster gemeldet.',
    provider_quota_account_limits_loaded: 'Kontolimits geladen.',
    provider_quota_unavailable: 'Kontingentstatus nicht verfügbar',
    provider_quota_retry_after: 'Nach {0} erneut versuchen',
    provider_quota_pool_summary_available: '{0}/{1} verfügbar',
    provider_quota_pool_summary_exhausted: '{0} ausgeschöpft',
    provider_quota_pool_summary_failed: '{0} fehlgeschlagen',
    provider_quota_pool_summary_checked: '{0} geprüft',
    cancel: 'Abbrechen',
    create_job: 'Job erstellen',
    save_skill: 'Skill speichern',
    editing: 'Bearbeitung',
    // Empty state
    empty_title: 'Wie kann ich helfen?',
    empty_subtitle: 'Frage mich alles, führe Befehle aus, erkunde Dateien oder verwalte deine Aufgaben.',
    suggest_files: 'Welche Dateien sind in diesem Workspace?',
    suggest_schedule: 'Was steht heute auf meinem Plan?',
    suggest_plan: 'Hilf mir, ein kleines Projekt zu planen.',
    onboarding_password_will_enable: 'Wird aktiviert',
    onboarding_password_will_replace: 'Wird ersetzt',
    onboarding_password_keep_existing: 'Aktuelles Passwort beibehalten',
    onboarding_password_remains_disabled: 'Bleibt deaktiviert',
    profile_delete_confirm_message: 'Alle Sitzungen, Konfigurationen, Fähigkeiten und Erinnerungen dieses Profils werden dauerhaft gelöscht. Diese Aktion kann nicht rückgängig gemacht werden.',
    // skill form
    skill_name: 'Name',
    skill_category: 'Kategorie',
    skill_category_placeholder: 'Optional, z. B. devops',
    skill_content: 'SKILL.md-Inhalt',
    skill_content_placeholder: 'YAML-Frontmatter + Markdown-Text',
    skill_rename_not_supported: 'Umbenennen einer Fähigkeit wird nicht unterstützt. Erstelle eine neue und lösche die alte.',
    skill_metadata: 'Metadaten',
    // cron form
    cron_name_label: 'Name',
    cron_duplicate: 'Duplizieren',
    cron_duplicated: 'Aufgabe dupliziert (pausiert)',
    cron_name_placeholder: 'Optional',
    cron_schedule_label: 'Zeitplan',
    cron_schedule_hint: "Für wiederkehrende Aufgaben 'every 1h' oder einen Cron-Ausdruck verwenden. Reine Dauern wie '30m' laufen einmal.",
    cron_schedule_once_warning: "Dauerangaben wie '30m' laufen einmal und werden nach der Ausführung entfernt. Verwende 'every 30m' für eine wiederkehrende Aufgabe.",
    cron_prompt_label: 'Prompt',
    cron_deliver_label: 'Ausgabe senden an',
    cron_deliver_local: 'Lokal (nur speichern)',
    cron_profile_label: 'Profil',
    cron_profile_server_default: 'Serverstandard',
    cron_profile_server_default_hint: 'Verwendet zur Laufzeit das Standardprofil des WebUI-Servers. Bestehende Jobs ohne Profil behalten dieses Legacy-Verhalten.',
    cron_toast_notifications_label: 'Abschluss-Toasts',
    cron_toast_notifications_hint: 'Zeigt einen Toast, wenn dieser Cron fertig ist. Aufgaben-Badge und Marker für neue Läufe werden trotzdem aktualisiert.',
    cron_toast_notifications_enabled: 'Aktiviert',
    cron_toast_notifications_disabled: 'Deaktiviert',
    cron_skills_label: 'Fähigkeiten',
    cron_skills_placeholder: 'Fähigkeiten hinzufügen (optional)…',
    cron_skills_edit_hint: 'Die Fähigkeitenliste kann nach der Erstellung nicht bearbeitet werden.',
    cron_status_running: 'läuft\u2026',
    // workspace form
    workspace_name_label: 'Name',
    workspace_name_placeholder: 'Optionaler Anzeigename',
    workspace_path_label: 'Pfad',
    workspace_path_required: 'Pfad ist erforderlich',
    workspace_path_readonly: 'Pfad kann nicht geändert werden. Nur umbenennen.',
    workspace_new_title: 'Neuer Bereich',
    // profile form
    profile_name_label: 'Name',
    profile_base_url_label: 'Basis-URL',
    profile_api_key_label: 'API-Schlüssel',
  
    // Session management and settings keys (en fallback — pending translation)
    session_archive: 'Archive conversation',
    session_hide_external: 'Aus Liste ausblenden',
    session_archive_desc: 'Hide this conversation until archived is shown',
    session_archive_worktree_desc: 'Diese Konversation ausblenden; den Worktree auf der Festplatte behalten',
    session_hide_external_desc: 'Diese importierte Sitzung aus der WebUI-Liste ausblenden, ohne den ursprünglichen Verlauf zu löschen.',
    session_archive_failed: 'Archive failed: ',
    session_archived: 'Session archived',
    session_archived_worktree: 'Sitzung archiviert. Der Worktree bleibt auf der Festplatte.',
    session_hidden: 'Sitzung aus Liste ausgeblendet',
    session_delete: 'Delete conversation',
    session_delete_desc: 'Permanently remove this conversation',
    session_delete_confirm: 'Diese Konversation löschen?',
    session_delete_worktree_desc: 'Nur die WebUI-Konversation löschen; den Worktree auf der Festplatte behalten',
    session_delete_worktree_confirm: (path) => `Diese Konversation löschen? Der Worktree unter ${path} bleibt auf der Festplatte.`,
    session_deleted: 'Konversation gelöscht',
    session_deleted_worktree: 'Konversation gelöscht. Der Worktree bleibt auf der Festplatte.',
    session_worktree_remove: 'Worktree entfernen',
    session_worktree_remove_desc: (path) => `Git-Worktree unter ${path} von der Festplatte löschen`,
    session_worktree_remove_confirm: (path) => `Git-Worktree von der Festplatte entfernen?\n\nPfad: ${path}\n\nDas gesamte Worktree-Verzeichnis wird gelöscht. Sitzungsdaten bleiben in WebUI.`,
    session_worktree_remove_not_exists: (path) => `Der Worktree unter ${path} existiert nicht mehr auf der Festplatte.`,
    session_worktree_remove_confirm_label: 'Entfernen',
    session_worktree_removed: 'Worktree entfernt.',
    session_worktree_remove_failed: 'Fehler beim Entfernen des Worktree: ',
    session_worktree_remove_status_failed: 'Fehler beim Lesen des Worktree-Status: ',
    session_worktree_remove_locked_by_stream: 'Entfernen nicht möglich — eine aktive Streaming-Sitzung verwendet diesen Worktree.',
    session_worktree_remove_locked_by_terminal: 'Entfernen nicht möglich — eine aktive Terminal-Sitzung verwendet diesen Worktree.',
    session_worktree_remove_unsafe_blocked: 'Löse lokale Änderungen oder nicht gepushte Commits, bevor du diesen Worktree entfernst.',
    session_worktree_remove_dirty_warning: 'WARNUNG: Dieser Worktree hat nicht festgeschriebene Änderungen, die verloren gehen.',
    session_worktree_remove_untracked_warning: (count) => `${count} nicht verfolgte Datei(en) werden dauerhaft gelöscht.`,
    session_worktree_remove_ahead_warning: (ahead) => `${ahead} nicht gepushte Commit(s) gehen verloren.`,
    session_duplicate: 'Duplicate conversation',
    session_duplicate_desc: 'Create a copy with the same workspace and model',
    session_duplicate_failed: 'Duplicate failed: ',
    session_stop_response: 'Stop response',
    session_stop_response_desc: 'Cancel the running response for this conversation',
    session_duplicated: 'Session duplicated',
    session_move_project: 'Move to project',
    session_move_project_desc_has: 'Change the project for this conversation',
    session_move_project_desc_none: 'Assign a project to this conversation',
    session_pin: 'Pin conversation',
    session_pin_desc: 'Keep this conversation at the top',
    session_pin_failed: 'Pin failed: ',
    session_restore: 'Restore conversation',
    session_restore_desc: 'Bring this conversation back into the main list',
    session_restored: 'Session restored',
    session_unpin: 'Unpin conversation',
    session_unpin_desc: 'Remove from pinned',
    session_select_mode: 'Auswählen',
    session_select_mode_desc: 'Konversationen für Massenverwaltung auswählen',
    session_select_all: 'Alle auswählen',
    session_deselect_all: 'Auswahl aufheben',
    session_selected_count: '{0} ausgewählt',
    session_batch_archive: 'Archivieren',
    session_batch_delete: 'Löschen',
    session_batch_move: 'Zum Projekt verschieben',
    session_batch_delete_confirm: '{0} Konversationen löschen?',
    session_batch_archive_confirm: '{0} Konversationen archivieren?',
    session_batch_delete_worktree_confirm: '{0} Konversationen löschen? {1} worktree-gestützte Konversation(en) behalten ihre Worktree-Verzeichnisse auf der Festplatte.',
    session_batch_archive_worktree_confirm: '{0} Konversationen archivieren? {1} worktree-gestützte Konversation(en) behalten ihre Worktree-Verzeichnisse auf der Festplatte.',
    session_no_selection: 'Keine Konversationen ausgewählt',
    settings_dropdown_appearance: 'Appearance',
    settings_dropdown_conversation: 'Conversation',
    settings_dropdown_preferences: 'Preferences',
    settings_dropdown_providers: 'Providers',
    settings_dropdown_system: 'System',
    settings_heading_subtitle: 'Preferences, conversation tools, and system controls.',
    settings_heading_title: 'Control Center',
    settings_section_appearance_meta: 'Theme, accent colors, and visual style.',
    settings_section_appearance_title: 'Appearance',
    settings_section_conversation_title: 'Conversation',
    settings_section_preferences_meta: 'Defaults and UI behavior for Hermes Web UI.',
    settings_section_preferences_title: 'Preferences',
    settings_section_system_meta: 'Instance version and access controls.',
    settings_check_now: 'Jetzt prüfen',
    settings_checking: 'Prüfung\u2026',
    settings_up_to_date: 'Aktuell \u2713',
    settings_updates_available: '{count} Update(s) verfügbar',
    settings_updates_disabled: 'Update-Prüfung deaktiviert',
    settings_update_check_failed: 'Update-Prüfung fehlgeschlagen',
    settings_label_workspace_panel_open: 'Arbeitsbereich-Panel standardmäßig öffnen',
    settings_desc_workspace_panel_open: 'Wenn aktiviert, wird der Datei-Browser bei jeder neuen Sitzung automatisch geöffnet. Er kann jederzeit manuell geschlossen werden.',
    settings_label_session_jump_buttons: 'Sitzungs-Sprungtasten anzeigen',
    settings_desc_session_jump_buttons: 'Zeigt beim Lesen langer Sitzungsverläufe schwebende Anfang- und Ende-Tasten an.',

    settings_label_session_endless_scroll: 'Ältere Nachrichten beim Hochscrollen laden',

    settings_desc_session_endless_scroll: 'Wenn aktiviert, werden ältere Nachrichten beim Hochscrollen automatisch geladen. Wenn deaktiviert, nutzt du den Button für ältere Nachrichten.',

    settings_label_tab_visibility: 'Seitenleiste-Tabs',
    settings_desc_tab_visibility: 'Wähle, welche Tabs in der Seitenleiste und im Rail angezeigt werden. Chat und Einstellungen sind immer sichtbar.',

    workspace_drag_hint: 'Ziehen zum Neuordnen',
    workspace_reorder_failed: 'Neuordnen fehlgeschlagen',
    open_in_browser: 'Im Browser öffnen',
    settings_section_system_title: 'System',
    settings_tab_appearance: 'Appearance',
    settings_tab_conversation: 'Conversation',
    settings_tab_preferences: 'Preferences',
    settings_tab_plugins: 'Plugins',
    settings_plugins_title: 'Plugins',  // TODO: translate
    settings_plugins_meta: 'View installed Hermes plugins and the lifecycle hooks they register. This panel is read-only.',  // TODO: translate
    settings_plugins_empty: 'No Hermes plugins are currently visible. Install or enable plugins from the Hermes CLI/config to see them here.',  // TODO: translate
    plugins_unnamed: 'Unnamed plugin',  // TODO: translate
    plugins_no_description: 'No description provided.',  // TODO: translate
    plugins_no_hooks: 'No registered lifecycle hooks',  // TODO: translate
    plugins_registered_hooks: 'Registered hooks',  // TODO: translate
    plugins_enabled: 'Enabled',  // TODO: translate
    plugins_disabled: 'Disabled',  // TODO: translate
    plugins_active_provider: 'Active (provider)',  // TODO: translate
    plugins_provider_no_hooks: 'Provider plugin — no agent-visibility hooks',  // TODO: translate
    plugins_load_failed: 'Failed to load plugins: ',  // TODO: translate
    settings_tab_system: 'System',
    status_updated: 'Updated',
    status_ephemeral: 'Ephemeral snapshot — not saved to transcript history.',
    status_no_tokens: 'No token data',
    status_profile: 'Profile',
    status_hermes_home: 'Hermes home',
    status_started: 'Started',
    status_tokens: 'Tokens',
    status_unknown: 'Unknown',
    cmd_yolo: 'YOLO-Modus umschalten',
    yolo_no_session: 'Keine aktive Sitzung',
    cmd_branch:'Fork this conversation into a new session',
    cmd_branch_usage:'/branch [name] — fork conversation (optionally with a name)',
    branch_forked:'Forked into new session',
    branch_failed:'Fork failed: ',
    fork_from_here:'Fork from here',
    forked_from:'Forked from',
    yolo_enabled: '⚡ YOLO-Modus AN — Genehmigungen übersprungen',
    yolo_disabled: 'YOLO-Modus AUS',
    yolo_pill_label: 'YOLO',
    yolo_pill_title_active: 'YOLO-Modus aktiv — Klicken zum Deaktivieren',
    approval_skip_all: '⚡ Alle in dieser Sitzung überspringen',
    approval_skip_all_title: 'Alle Genehmigungsanfragen in dieser Sitzung überspringen',
    // composer action tooltips
    composer_send: 'Nachricht senden',
    composer_queue: 'Nachricht einreihen',
    composer_interrupt: 'Unterbrechen und senden',
    composer_steer: 'Antwort steuern',
    composer_stop: 'Generierung stoppen',
    composer_disabled_clarify: 'Auf die Klärungsanfrage antworten',
    composer_disabled_compression: 'Warte auf Abschluss der Komprimierung',
    composer_disabled_empty: 'Nachricht eingeben zum Senden',
    composer_mobile_workspace: 'Arbeitsbereich',
    composer_mobile_model: 'Modell',
    composer_mobile_reasoning: 'Reasoning',
    composer_mobile_context: 'Kontext',
    model_custom_label: 'Benutzerdefinierte Modell-ID',
    model_custom_placeholder: 'z.B. openai/gpt-5.4',
    model_search_placeholder: 'Modelle suchen…',
    model_search_no_results: 'Keine Modelle gefunden',
    model_group_configured: 'Konfiguriert',
    ws_search_placeholder: 'Arbeitsbereiche suchen…',
    ws_no_results: 'Keine Arbeitsbereiche gefunden',
    workspace_new_worktree_conversation: 'Neue Unterhaltung in Worktree',
    workspace_new_worktree_conversation_meta: 'Erstellt einen isolierten git worktree für diesen Arbeitsbereich.',
    workspace_worktree_created: 'Worktree-Unterhaltung erstellt',
    workspace_worktree_failed: 'Worktree-Erstellung fehlgeschlagen: ',
    session_worktree_badge: 'Worktree',
    session_toolsets: 'Session Toolsets', // TODO: translate
    session_toolsets_desc: 'Restrict available tools for this session (blank = use global config)', // TODO: translate
    session_toolsets_global: 'Global (default)', // TODO: translate
    session_toolsets_custom: 'Custom', // TODO: translate
    session_toolsets_placeholder: 'tool1, tool2, \u2026', // TODO: translate
    session_toolsets_apply: 'Apply', // TODO: translate
    session_toolsets_clear: 'Clear (use global)', // TODO: translate
    session_toolsets_applied: 'Toolsets updated', // TODO: translate
    session_toolsets_cleared: 'Toolsets cleared — using global config', // TODO: translate
    session_toolsets_failed: 'Failed to update toolsets: ', // TODO: translate
    session_time_unknown: 'Unbekannt',
    session_time_minutes_ago: (n) => `Vor ${n} Minuten`,
    session_time_hours_ago: (n) => `Vor ${n} Stunden`,
    session_time_days_ago: (n) => `Vor ${n} Tagen`,
    session_time_last_week: 'Letzte Woche',
    session_time_bucket_today: 'Heute',
    session_time_bucket_yesterday: 'Gestern',
    session_time_bucket_this_week: 'Diese Woche',
    session_time_bucket_last_week: 'Letzte Woche',
    session_time_bucket_older: 'Älter',
    onboarding_badge: 'Ersteinrichtung',
    onboarding_title: 'Willkommen bei Hermes',
    onboarding_lead: 'Lassen Sie uns Ihren Agenten einrichten.',
    onboarding_back: 'Zurück',
    onboarding_continue: 'Weiter',
    onboarding_skip: 'Überspringen',
    onboarding_skipped: 'Einrichtung übersprungen',
    onboarding_open: 'Einrichtung öffnen',
    onboarding_step_system_title: 'Agent-Status',
    onboarding_step_system_desc: 'Hermes Agent muss installiert und erreichbar sein.',
    onboarding_step_setup_title: 'Einrichtung',
    onboarding_step_setup_desc: 'Konfigurieren Sie einen Anbieter und ein Modell.',
    onboarding_step_workspace_title: 'Arbeitsbereich',
    onboarding_step_workspace_desc: 'Wählen Sie einen Arbeitsbereich für Ihre Dateien.',
    onboarding_step_password_title: 'Passwort (optional)',
    onboarding_step_password_desc: 'Sichern Sie den Zugriff mit einem Passwort.',
    onboarding_step_finish_title: 'Fertig!',
    onboarding_step_finish_desc: 'Ihr Agent ist bereit.',
    onboarding_notice_system_ready: 'Agent ist bereit und erreichbar.',
    onboarding_notice_system_unavailable: 'Agent nicht erreichbar. Bitte starten Sie Hermes Agent.',
    onboarding_check_agent: 'Agent-Verbindung',
    onboarding_check_agent_ready: 'Agent erreichbar',
    onboarding_check_agent_missing: 'Agent nicht erreichbar',
    onboarding_check_password: 'Passwortschutz',
    onboarding_check_password_enabled: 'Passwort aktiviert',
    onboarding_check_password_disabled: 'Kein Passwort',
    onboarding_check_provider: 'Modellanbieter',
    onboarding_check_provider_ready: 'Anbieter konfiguriert',
    onboarding_check_provider_partial: 'Teilweise konfiguriert',
    onboarding_check_provider_pending: 'Nicht konfiguriert',
    onboarding_config_file: 'Konfigurationsdatei',
    onboarding_env_file: 'Umgebungsdatei',
    onboarding_unknown: 'Unbekannt',
    onboarding_current_provider: 'Aktueller Anbieter',
    onboarding_missing_imports: 'Fehlende Abhängigkeiten',
    onboarding_notice_setup_required: 'Einrichtung erforderlich',
    onboarding_notice_setup_already_ready: 'Bereits eingerichtet',
    onboarding_oauth_provider_ready_title: 'Anbieter bereit',
    onboarding_oauth_provider_ready_body: '{provider} ist konfiguriert. Kein API-Schlüssel erforderlich.',
    onboarding_oauth_provider_not_ready_title: 'Anbieter nicht eingerichtet',
    onboarding_oauth_provider_not_ready_body: '{provider} erfordert einen API-Schlüssel.',
    onboarding_oauth_switch_hint: 'Zu OAuth wechseln',
    onboarding_notice_workspace: 'Arbeitsbereich empfohlen',
    onboarding_workspace_label: 'Arbeitsbereich',
    onboarding_workspace_or_path: 'Name oder Pfad',
    onboarding_workspace_placeholder: 'z.B. ~/projects/my-app',
    onboarding_provider_label: 'Anbieter',
    onboarding_quick_setup_badge: 'Schnelleinrichtung',
    provider_category_easy_start: 'Einfach starten',
    provider_category_self_hosted: 'Selbst gehostet',
    provider_category_specialized: 'Spezialisiert',
    onboarding_api_key_label: 'API-Schlüssel',
    onboarding_api_key_placeholder: 'sk-…',
    onboarding_api_key_label_optional: 'API key (optional)', // TODO: translate
    onboarding_api_key_placeholder_optional: 'Leave blank for keyless servers', // TODO: translate
    onboarding_api_key_help_keyless: 'Most LM Studio / Ollama / vLLM installs run keyless — leave this blank if your server doesn\'t require authentication. Use the Test connection button to verify.', // TODO: translate
    oauth_login_codex: 'Login with Codex (ChatGPT)', // TODO: translate
    oauth_codex_step1: 'Step 1: Visit this URL and enter the code', // TODO: translate
    oauth_codex_step2: 'Step 2: Enter this code on the page', // TODO: translate
    oauth_codex_polling: 'Waiting for authorization...', // TODO: translate
    oauth_codex_success: 'Codex OAuth login successful!', // TODO: translate
    oauth_codex_error: 'OAuth login failed', // TODO: translate
    oauth_codex_expired: 'Code expired, please try again', // TODO: translate
    onboarding_api_key_help_prefix: 'Gefunden unter',
    onboarding_base_url_label: 'Base URL',
    onboarding_base_url_placeholder: 'https://api.openai.com/v1',
    onboarding_base_url_help: 'Verwenden Sie dies für OpenAI-kompatible Router, selbst gehostete Server, LiteLLM, Ollama, LM Studio, vLLM oder ähnliche Endpunkte.',
    onboarding_model_label: 'Modell',
    onboarding_workspace_help: 'Der Arbeitsbereich ist das Stammverzeichnis für Dateien und Terminal-Befehle.',
    onboarding_custom_model_placeholder: 'Exakte Modell-ID eingeben',
    onboarding_custom_model_help: 'Geben Sie die genaue Modell-ID ein, die Ihr Server erwartet.',
    onboarding_notice_password_enabled: 'Passwortschutz aktiviert.',
    onboarding_notice_password_recommended: 'Empfohlen für den öffentlichen Zugriff.',
    onboarding_password_label: 'Passwort',
    onboarding_password_placeholder: 'Passwort festlegen',
    onboarding_password_help: 'Passwörter werden über die Einstellungs-API gespeichert und serverseitig gehasht.',
    onboarding_notice_finish: 'Ihr Agent ist bereit!',
    onboarding_not_set: 'Nicht festgelegt',
    onboarding_password_skipped: 'Übersprungen',
    onboarding_finish_help: 'Sie können dies später in den Einstellungen ändern.',
    onboarding_error_choose_workspace: 'Bitte wählen Sie einen Arbeitsbereich.',
    onboarding_error_choose_model: 'Bitte wählen Sie ein Modell.',
    onboarding_error_provider_required: 'Anbieter erforderlich.',
    onboarding_error_base_url_required: 'Base URL erforderlich.',
    onboarding_probe_test_button: 'Test connection', // TODO: translate
    onboarding_probe_probing: 'Testing connection…', // TODO: translate
    onboarding_probe_ok: 'Connected. {n} model(s) available.', // TODO: translate
    onboarding_probe_error_generic: 'Could not reach the configured base URL.', // TODO: translate
    onboarding_probe_error_invalid_url: 'Base URL must start with http:// or https://.', // TODO: translate
    onboarding_probe_error_dns: 'Could not resolve the host. Check the URL or use the host\'s IP address.', // TODO: translate
    onboarding_probe_error_connect_refused: 'Connection refused — the server may not be running on that address. From inside Docker, try the host IP instead of localhost.', // TODO: translate
    onboarding_probe_error_timeout: 'The endpoint did not respond in time. Check that the server is running and the URL is correct.', // TODO: translate
    onboarding_probe_error_http_4xx: 'The endpoint returned a client error. Check authentication and the URL path (typically ends in /v1).', // TODO: translate
    onboarding_probe_error_http_5xx: 'The endpoint returned a server error. Check the LM Studio / Ollama server logs.', // TODO: translate
    onboarding_probe_error_parse: 'The endpoint did not return a model list in the expected shape. Verify the URL points to the OpenAI-compatible API root.', // TODO: translate
    onboarding_probe_error_unreachable: 'Could not reach the configured base URL.', // TODO: translate
    onboarding_error_probe_failed: 'Could not validate the configured base URL.', // TODO: translate
    onboarding_error_workspace_required: 'Arbeitsbereich erforderlich.',
    onboarding_error_model_required: 'Modell erforderlich.',
    onboarding_complete: 'Einrichtung abgeschlossen!',
    error_prefix: 'Fehler: ',
    not_available: 'Nicht verfügbar',
    never: 'Nie',
    add: 'Hinzufügen',
    add_failed: 'Hinzufügen fehlgeschlagen',
    remove_failed: 'Entfernen fehlgeschlagen',
    switch_failed: 'Wechsel fehlgeschlagen',
    name_required: 'Name erforderlich.',
    content_required: 'Inhalt erforderlich.',
    view: 'Anzeigen',
    dismiss: 'Verwerfen',
    disable: 'Deaktivieren',
    cron_no_jobs: 'Keine geplanten Aufgaben.',
    cron_status_off: 'Inaktiv',
    cron_status_paused: 'Pausiert',
    cron_status_error: 'Fehler',
    cron_status_active: 'Aktiv',
    cron_status_needs_attention: 'Erfordert Aufmerksamkeit',
    cron_attention_desc: 'Dieser Job hat Probleme.',
    cron_attention_croniter_hint: 'Der Croniter-Ausdruck ist möglicherweise ungültig.',
    cron_attention_resume: 'Fortsetzen',
    cron_jobs_project: 'Cron-Jobs',
    cron_attention_run_once: 'Einmal ausführen',
    cron_attention_copy_diagnostics: 'Diagnose kopieren',
    cron_diagnostics_copied: 'Diagnoseinformationen kopiert.',
    cron_next: 'Nächstes: ',
    cron_last: 'Letztes: ',
    cron_run_now: 'Jetzt ausführen',
    cron_pause: 'Pausieren',
    cron_resume: 'Fortsetzen',
    cron_job_name_placeholder: 'Aufgabenname',
    cron_schedule_placeholder: '0 9 * * *',
    cron_prompt_placeholder: 'Aufgabenbeschreibung',
    cron_last_output: 'Letzte Ausgabe',
    cron_expand_prompt: 'Prompt erweitern',
    cron_collapse_prompt: 'Prompt einklappen',
    cron_expand_output: 'Ausgabe erweitern',
    cron_collapse_output: 'Ausgabe einklappen',
    cron_all_runs: 'Alle Ausführungen',
    cron_hide_runs: 'Ausführungen ausblenden',
    cron_no_runs_yet: 'Noch keine Ausführungen.',
    cron_schedule_required_example: 'z.B. 0 9 * * *, every 2h, 30m',
    cron_schedule_required: 'Zeitplan erforderlich.',
    cron_prompt_required: 'Beschreibung erforderlich.',
    cron_job_created: 'Aufgabe erstellt.',
    cron_job_triggered: 'Aufgabe gestartet.',
    cron_job_paused: 'Aufgabe pausiert.',
    cron_job_resumed: 'Aufgabe fortgesetzt.',
    cron_job_updated: 'Aufgabe aktualisiert.',
    cron_delete_confirm_title: 'Aufgabe löschen',
    cron_delete_confirm_message: 'Sind Sie sicher?',
    cron_job_deleted: 'Aufgabe gelöscht.',
    cron_completion_status: 'Abschlussstatus',
    status_failed: 'Fehlgeschlagen',
    status_completed: 'Abgeschlossen',
    todos_no_active: 'Keine aktiven Aufgaben.',
    clear_conversation_title: 'Konversation löschen',
    clear_conversation_message: 'Alle Nachrichten werden gelöscht.',
    clear_failed: 'Löschen fehlgeschlagen.',
    skills_no_match: 'Keine passende Fähigkeit.',
    linked_files: 'Verknüpfte Dateien',
    skill_load_failed: 'Fähigkeit konnte nicht geladen werden.',
    skill_file_load_failed: 'Datei konnte nicht geladen werden.',
    skill_name_required: 'Name erforderlich.',
    skill_updated: 'Fähigkeit aktualisiert.',
    skill_created: 'Fähigkeit erstellt.',
    skill_deleted: 'Fähigkeit gelöscht.',
    skill_delete_confirm: 'Fähigkeit wirklich löschen?',
    skills_empty_title: 'Keine Fähigkeiten',
    skills_empty_sub: 'Installieren Sie Fähigkeiten.',
    skills_edit: 'Bearbeiten',
    skills_delete: 'Löschen',
    skills_back_to: 'Zurück',
    tasks_empty_title: 'Keine Aufgaben',
    tasks_empty_sub: 'Verwalten Sie geplante Aufgaben.',
    workspaces_empty_title: 'Keine Arbeitsbereiche',
    workspaces_empty_sub: 'Richten Sie Arbeitsbereiche ein.',
    profiles_empty_title: 'Keine Profile',
    profiles_empty_sub: 'Erstellen Sie Profile.',
    memory_notes_label: 'Notizen',
    memory_saved: 'Notiz gespeichert.',
    my_notes: 'Meine Notizen',
    user_profile: 'Benutzerprofil',
    no_notes_yet: 'Noch keine Notizen.',
    no_profile_yet: 'Noch kein Profil.',
    agent_soul: 'Agenten-Seele',
    no_soul_yet: 'Noch keine Seele definiert.',
    workspace_choose_path: 'Arbeitsbereich wählen',
    workspace_choose_path_meta: 'Wählen Sie ein Verzeichnis.',
    workspace_manage: 'Arbeitsbereiche verwalten',
    workspace_manage_meta: 'Hinzufügen, Umbenennen, Entfernen.',
    workspace_use_title: 'Arbeitsbereich verwenden',
    workspace_use: 'Arbeitsbereich',
    workspace_add_path_placeholder: '~/projects/my-app',
    workspace_paths_validated_hint: 'Pfad ist gültig.',
    workspace_added: 'Arbeitsbereich hinzugefügt.',
    workspace_renamed: 'Arbeitsbereich umbenannt.',
    workspace_remove_confirm_title: 'Arbeitsbereich entfernen',
    workspace_remove_confirm_message: 'Arbeitsbereich entfernen?',
    workspace_removed: 'Arbeitsbereich entfernt.',
    workspace_switch_prompt_title: 'Zum Arbeitsbereich wechseln',
    workspace_switch_prompt_message: 'Wechsel zum Arbeitsbereich?',
    workspace_switch_prompt_confirm: 'Wechseln',
    workspace_switch_prompt_placeholder: 'Arbeitsbereichsname',
    workspace_not_added: 'Arbeitsbereich nicht hinzugefügt.',
    workspace_already_saved: 'Arbeitsbereich bereits vorhanden.',
    workspace_busy_switch: 'Arbeitsbereich kann nicht gewechselt werden.',
    discard_file_edits_title: 'Änderungen verwerfen',
    discard_file_edits_message: 'Ungespeicherte Änderungen verwerfen?',
    workspace_switched_to: 'Arbeitsbereich gewechselt zu: ',
    profiles_no_profiles: 'Keine Profile vorhanden.',
    profile_api_keys_configured: 'API-Schlüssel konfiguriert',
    profile_gateway_running: 'Gateway läuft',
    profile_gateway_stopped: 'Gateway gestoppt',
    profile_active: 'Aktiv',
    profile_no_configuration: 'Keine Konfiguration',
    profile_skill_count: (count) => `${count} Fähigkeit${count === 1 ? '' : 'en'}`,
    profile_use: 'Verwenden',
    profile_switch_title: 'Profil wechseln',
    profile_delete_title: 'Profil löschen',
    profile_default_label: 'Standard',
    profile_name_placeholder: 'Profilname',
    profile_clone_label: 'Klonen',
    profile_model_label: 'Modell / Anbieter',
    profile_model_hint: 'Wähle konfigurierte Anbieter und Modelle für dieses neue Profil.',
    profile_model_use_default: 'Standard des aktiven Profils verwenden',
    profile_base_url_placeholder: 'https://api.openai.com/v1',
    profile_api_key_placeholder: 'sk-…',
    manage_profiles: 'Profile verwalten',
    profiles_load_failed: 'Profile konnten nicht geladen werden.',
    profile_switched_new_conversation: 'Profil gewechselt. Neue Konversation.',
    profile_switched: 'Profil gewechselt.',
    profile_name_rule: 'Nur alphanumerische Zeichen.',
    profile_base_url_rule: 'Muss mit http:// oder https:// beginnen.',
    profile_created: 'Profil erstellt.',
    profile_delete_confirm_title: 'Profil löschen',
    profile_deleted: 'Profil gelöscht.',
    active_conversation_none: 'Keine aktive Konversation',
    active_conversation_meta: 'Aktive Konversation',
    settings_unsaved_changes: 'Ungespeicherte Änderungen',
    sign_out_failed: 'Abmeldung fehlgeschlagen.',
    disable_auth_confirm_title: 'Passwortschutz deaktivieren',
    disable_auth_confirm_message: 'Zugriff ohne Authentifizierung?',
    auth_disabled: 'Passwortschutz deaktiviert.',
    disable_auth_failed: 'Deaktivieren fehlgeschlagen.',
    bg_error_single: 'Hinterfrage {count} fehlgeschlagen.',
    bg_error_multi: '{count} Hinterfragen fehlgeschlagen.',
    media_audio_label: 'Audio',
    media_svg_label: 'Diagramm',
    media_video_label: 'Video',
    csv_loading: 'CSV wird geladen',
    csv_too_large: 'CSV-Datei zu groß für Inline-Anzeige',
    csv_no_data: 'CSV-Datei enthält nicht genügend Daten',
    csv_error: 'CSV-Datei konnte nicht geladen werden',
    csv_header_note: 'Erste Zeile wird als Tabellenüberschrift angezeigt',
    excalidraw_loading: 'Diagramm wird geladen',
    excalidraw_too_large: 'Excalidraw-Datei zu groß für Inline-Anzeige',
    excalidraw_invalid: 'Ungültiges Excalidraw-Dateiformat',
    excalidraw_error: 'Excalidraw-Datei konnte nicht geladen werden',
    excalidraw_label: 'Diagramm',
    excalidraw_download: 'Herunterladen',
    excalidraw_empty: 'Leeres Diagramm',
    excalidraw_render_error: 'Diagramm konnte nicht gerendert werden',
    excalidraw_simplified: 'Vereinfachte SVG-Vorschau — nicht pixelgenau zum Excalidraw-Canvas',
    pdf_loading: 'PDF wird geladen {0}…',
    pdf_too_large: 'PDF zu groß für Inline-Vorschau',
    pdf_no_pages: 'PDF-Vorschau konnte nicht gerendert werden',
    pdf_error: 'PDF konnte nicht geladen werden',
    pdf_download: 'PDF herunterladen',
    html_loading: 'HTML-Vorschau wird geladen…',
    html_too_large: 'HTML zu groß für Inline-Vorschau',
    html_error: 'HTML-Vorschau konnte nicht geladen werden',
    html_open_full: 'Vollständige Seite öffnen',
    html_sandbox_label: 'HTML-Vorschau',
    // TTS (#499)
    tts_listen: 'Anhören',
    tts_not_supported: 'Sprachsynthese nicht verfügbar',
    settings_label_tts: 'Text-zu-Sprache für Antworten',
    settings_desc_tts: 'Lautsprecher-Symbol auf Assistenten-Nachrichten anzeigen',
    settings_label_tts_auto_read: 'Antworten automatisch vorlesen',
    settings_desc_tts_auto_read: 'Assistenten-Antworten automatisch vorlesen',
    // Composer voice-mode pref (#1488)
    settings_label_voice_mode: 'Hands-free voice mode button',  // TODO: translate
    settings_desc_voice_mode: 'Show the voice-mode button (audio waveform) next to the dictation mic. Lets you speak naturally — Hermes auto-sends after a pause and reads replies aloud. Requires a browser that supports both speech recognition and TTS.',  // TODO: translate
    settings_label_tts_voice: 'Stimme',
    settings_desc_tts_voice: 'Stimme für Sprachsynthese auswählen',
    settings_label_tts_rate: 'Sprechgeschwindigkeit',
    settings_label_tts_pitch: 'Tonhöhe',

    checkpoint_date: 'Date',  // TODO: translate
    checkpoint_diff_files_changed: (n) => `${n} file${n === 1 ? '' : 's'} changed`,  // TODO: translate
    checkpoint_diff_no_changes: 'No differences found between this checkpoint and the current workspace.',  // TODO: translate
    checkpoint_diff_title: 'Changes in checkpoint',  // TODO: translate
    checkpoint_empty: 'No checkpoints found for this workspace.',  // TODO: translate
    checkpoint_error: 'Failed to load checkpoints',  // TODO: translate
    checkpoint_files: 'Files',  // TODO: translate
    checkpoint_loading: 'Loading checkpoints…',  // TODO: translate
    checkpoint_message: 'Message',  // TODO: translate
    checkpoint_restore: 'Restore',  // TODO: translate
    checkpoint_restore_confirm_message: (ckpt) => `Restore workspace to checkpoint "${ckpt}"? This will overwrite files with the saved versions. Files added after this checkpoint will not be deleted.`,  // TODO: translate
    checkpoint_restore_confirm_title: 'Restore checkpoint?',  // TODO: translate
    checkpoint_restored: 'Checkpoint restored',  // TODO: translate
    checkpoint_title: 'Checkpoints',  // TODO: translate
    checkpoint_view_diff: 'View diff',  // TODO: translate
    insights_activity_by_day: 'Activity by Day',  // TODO: translate
    insights_activity_by_hour: 'Activity by Hour',  // TODO: translate
    insights_cost: 'Estimated Cost',  // TODO: translate
    insights_daily_tokens: 'Daily Tokens',
    insights_model_name: 'Model',
    insights_model_sessions: 'Sessions',
    insights_model_tokens: 'Tokens',
    insights_model_cost: 'Cost',
    insights_model_share: 'Share',
    insights_no_usage_data: 'No usage data yet',
    insights_footer: 'Showing data from the last {days} days',  // TODO: translate
    insights_input_tokens: 'Input',  // TODO: translate
    insights_messages: 'Messages',  // TODO: translate
    insights_models: 'Models',  // TODO: translate
    insights_no_cost: 'N/A',  // TODO: translate
    insights_output_tokens: 'Output',  // TODO: translate
    insights_peak_hour: 'Peak: {hour}',  // TODO: translate
    insights_sessions: 'Sessions',  // TODO: translate
    insights_title: 'Usage Analytics',  // TODO: translate
    insights_token_breakdown: 'Token Breakdown',  // TODO: translate
    insights_tokens: 'Tokens',  // TODO: translate
    insights_total: 'Total',  // TODO: translate
    settings_desc_api_redact: 'Self-hosted users can disable for transparency (not recommended for shared instances).',  // TODO: translate
    settings_label_api_redact: 'Redact sensitive data in API responses',  // TODO: translate
    voice_error: 'Voice not supported in this browser',  // TODO: translate
    voice_listening: 'Listening…',  // TODO: translate
    voice_mode_active: 'Voice mode on',  // TODO: translate
    voice_mode_off: 'Voice mode off',  // TODO: translate
    voice_speaking: 'Speaking…',  // TODO: translate
    voice_thinking: 'Thinking…',  // TODO: translate
    // Composer voice buttons (#1488)
    voice_dictate: 'Dictate',  // TODO: translate
    voice_dictate_active: 'Stop dictation',  // TODO: translate
    voice_mode_toggle: 'Voice mode',  // TODO: translate
    voice_mode_toggle_active: 'Exit voice mode',  // TODO: translate
    subagent_children: 'Subagent sessions',  // TODO: translate
  },

  zh: {
    offline_title: '连接已断开',
    offline_browser_detail: '浏览器报告此设备当前离线。',
    offline_network_detail: '此浏览器当前无法连接到 Hermes。',
    offline_autorefresh: '当 Hermes 可访问时，我会自动刷新此页面。',
    offline_check_now: '立即检查',
    offline_checking: '正在检查…',
    offline_stream_waiting: '连接已断开。正在等待刷新…',
    _lang: 'zh',
    _label: '\u7b80\u4f53\u4e2d\u6587',
    _speech: 'zh-CN',
    // boot.js
    cancelling: '正在取消...',
    cancel_failed: '取消失败：',
    mic_denied: '麦克风访问被拒绝，请检查浏览器权限。',
    mic_no_speech: '没有检测到语音，请再试一次。',
    mic_network: '语音识别当前不可用。',
    mic_error: '语音输入出错：',
    session_imported: '会话已导入',
    import_failed: '导入失败：',
    import_invalid_json: 'JSON 无效',
    image_pasted: '已粘贴图片：',
    // messages.js
    edit_message: '编辑消息',
    regenerate: '重新生成回复',
    copy: '复制',
    copied: '已复制',
    copy_failed: '复制失败',
    selected_text_reply: '用所选内容回复',
    selected_text_reply_title: '将所选聊天文本作为引用上下文追加',
    selected_text_reply_appended: '已将所选文本添加到输入框',

    diff_loading: '加载 diff',
    diff_error: '无法加载 patch 文件',
    diff_too_large: 'Patch 文件过大，无法内联显示',
    tree_view: '树形',
    raw_view: '原始',
    parse_failed_note: '解析失败',
    you: '你',
    mcp_servers_title: 'MCP 服务器',
    mcp_servers_desc: '管理 config.yaml 中配置的 MCP 服务器。',
    mcp_no_servers: '未配置 MCP 服务器。',
    mcp_add_server: '+ 添加服务器',
    mcp_field_name: '服务器名称',
    mcp_transport_label: '传输类型',
    mcp_field_command: '命令',
    mcp_field_args: '参数（逗号分隔）',
    mcp_field_url: 'URL',
    mcp_field_timeout: '超时（秒）',
    mcp_save: '保存',
    mcp_cancel: '取消',
    mcp_name_required: '服务器名称为必填项。',
    mcp_url_required: 'HTTP 传输需要 URL。',
    mcp_command_required: 'stdio 传输需要命令。',
    mcp_saved: 'MCP 服务器已保存。',
    mcp_save_failed: 'MCP 服务器保存失败。',
    mcp_delete_confirm_title: '删除 MCP 服务器',
    mcp_delete_confirm_message: '确定删除 MCP 服务器「{0}」吗？此操作不可撤销。',
    mcp_deleted: 'MCP 服务器已删除。',
    mcp_delete_failed: 'MCP 服务器删除失败。',
    mcp_load_failed: 'MCP 服务器加载失败。',
    mcp_restart_hint: '服务器更改目前为只读。请编辑 config.yaml 并重启 Hermes。',
    mcp_toggle_followup: '在 MCP 的重新加载规范明确之前，我们有意暂缓启用/禁用的切换。',
    mcp_status_active: '运行中',
    mcp_status_configured: '已配置',
    mcp_status_disabled: '已禁用',
    mcp_status_invalid_config: '配置无效',
    mcp_status_unknown: '未知',
    mcp_tool_count: '{0} 个工具',
    mcp_enabled_yes: '已启用',
    mcp_enabled_no: '已禁用',
    mcp_tools_title: 'MCP 工具',
    mcp_tools_desc: '搜索活跃 MCP 服务器中的已知工具。',
    mcp_tools_search_placeholder: '按名称、服务器或描述搜索工具…',
    mcp_tools_no_tools: '当前运行时清单中没有可用的 MCP 工具。',
    mcp_tools_no_matches: '没有匹配的 MCP 工具。',
    mcp_tools_load_failed: '加载 MCP 工具失败。',
    mcp_tools_schema_empty: '无参数。',
    mcp_tools_runtime_note: '工具清单仅使用已知的活跃 MCP 运行时数据；WebUI 不会启动或探测服务器。',
    mcp_tools_summary_no_matches: (query,total) => `No MCP tools matching “${query}” (${total} total MCP tools).`,
    mcp_tools_summary_none: 'No MCP tools to show.',
    mcp_tools_summary_matching: (query) => ` matching “${query}”`,
    mcp_tools_summary_total_note: (total) => ` (${total} total MCP tools)`,
    mcp_tools_summary_showing: (start,end,filtered,searchNote,totalNote,page,pages) => `Showing ${start}-${end} of ${filtered} MCP tools${searchNote}${totalNote}. Page ${page} of ${pages}.`,
    mcp_tools_page_size_prefix: 'Show',
    mcp_tools_page_size_suffix: 'per page',
    mcp_tools_per_page_aria: 'MCP tools per page',
    mcp_tools_inactive_configured_servers: (servers) => `Configured but inactive in this WebUI runtime: ${servers}.`,
    mcp_tools_pagination_label: 'MCP tools pagination',
    mcp_tools_previous_page: '‹ Prev',
    mcp_tools_previous_page_aria: 'Previous MCP tools page',
    mcp_tools_next_page: 'Next ›',
    mcp_tools_next_page_aria: 'Next MCP tools page',
    thinking: '思考过程',
    expand_all: '全部展开',
    collapse_all: '全部折叠',
    edit_failed: '编辑失败：',
    regen_failed: '重新生成失败：',
    reconnect_active: '回复仍在生成中，准备好后要重新加载吗？',
    reconnect_finished: '你离开时有回复正在生成，消息内容可能已经更新。',
    // approval card
    approval_heading: '需要审批',
    approval_desc_prefix: '检测到危险命令',
    approval_btn_once: '允许一次',
    approval_btn_once_title: '允许执行此命令一次（Enter）',
    approval_btn_session: '本次允许',
    approval_btn_session_title: '本次会话期间允许',
    approval_btn_always: '始终允许',
    approval_btn_always_title: '始终允许此命令模式',
    approval_btn_deny: '拒绝',
    approval_btn_deny_title: '拒绝 — 不执行此命令',
    approval_responding: '处理中…',
    clarify_heading: '需要澄清',
    clarify_hint: '请选择一个选项，或在下方输入你自己的回答。',
    clarify_other: '其他',
    clarify_send: '发送',
    clarify_input_placeholder: '请输入你的回答…',
    clarify_responding: '处理中…',
    untitled: '未命名',
    n_messages: (n) => `${n} 条消息`,
    load_older_messages: '↑ 向上滚动或点击加载更早的消息',
    session_jump_start: '开头',
    session_jump_start_label: '跳转到会话开头',
    session_jump_end: '结尾',
    session_jump_end_label: '跳转到会话结尾',
    jump_to_question: '回到问题',
    jump_to_question_label: '跳转到这条回答对应的问题',
    queued_label: '响应后发送',
    queued_count: (n) => n === 1 ? '1 条排队' : `${n} 条排队`,
    queued_cancel: '取消排队消息',
    model_unavailable: '（不可用）',
    model_unavailable_title: '这个模型已经不在当前 provider 列表中',
    provider_mismatch_warning: (m,p)=>`\"${m}\" 可能无法在当前配置的提供商 (${p}) 下工作。直接发送，或在终端运行 \`hermes model\` 切换。`,
    provider_mismatch_label: '提供商不匹配',
    model_not_found_label: '未找到模型',
    model_custom_label: '自定义模型 ID',
    model_custom_placeholder: '例如 openai/gpt-5.4',
    model_search_placeholder: '搜索模型…',
    model_search_no_results: '未找到模型',
    model_group_configured: '已配置',
    ws_search_placeholder: '搜索工作区…',
    ws_no_results: '未找到工作区',
    workspace_new_worktree_conversation: '在 worktree 中新建对话',
    workspace_new_worktree_conversation_meta: '为此工作区创建隔离的 git worktree。',
    workspace_worktree_created: '已创建 worktree 对话',
    workspace_worktree_failed: 'Worktree 创建失败：',
    session_worktree_badge: 'Worktree',
    session_toolsets: 'Session 工具集',
    session_toolsets_desc: '限制此会话可用工具（留空 = 使用全局配置）',
    session_toolsets_global: '全局（默认）',
    session_toolsets_custom: '自定义',
    session_toolsets_placeholder: 'tool1, tool2, \u2026', // TODO: translate
    session_toolsets_apply: '应用',
    session_toolsets_clear: '清除（使用全局）',
    session_toolsets_applied: '工具集已更新',
    session_toolsets_cleared: '工具集已清除 — 使用全局配置',
    session_toolsets_failed: '更新工具集失败：',
    model_scope_advisory: '从下一条消息起应用于当前对话。',
    model_scope_toast: '从下一条消息起应用于当前对话。',
    // commands.js
    cmd_help: '查看可用命令',
    cmd_clear: '清空当前对话消息',
    cmd_compress: '手动压缩对话上下文（用法：/compress [主题]）',
    ctx_compress_hint: '压缩上下文以释放空间 →',
    ctx_compress_action: '⚠ 立即压缩以释放上下文',
    cmd_compact_alias: '旧别名：/compress',
    cmd_model: '切换模型（例如 /model gpt-4o）',
    cmd_workspace: '按名称切换工作区',
    cmd_terminal: '打开工作区 Terminal',
    cmd_new: '新建聊天会话',
    cmd_usage: '切换 token 用量显示',
    cmd_theme: '切换外观（主题：system/dark/light，皮肤：default/ares/mono/slate/poseidon/sisyphus/charizard/sienna/catppuccin/nous/geist-contrast）',
    cmd_personality: '切换 Agent 人设',
    cmd_skills: '列出可用的 Hermes 技能',
    available_commands: '可用命令：',
    type_slash: '输入 / 可查看命令',
    conversation_cleared: '对话已清空',
    command_label: '命令',
    context_compaction_label: '上下文压缩',
    retrieval_context_label: '已索引上下文',
    retrieval_context_preview: '较早消息已存储，可通过上下文工具检索',
    preserved_task_list_label: '保留的任务列表',
    reference_only_label: '仅供参考',
    model_usage: '用法：/model <name>',
    no_model_match: '没有匹配“',
    switched_to: '已切换到 ',
    workspace_usage: '用法：/workspace <name>',
    no_workspace_match: '没有匹配“',
    switched_workspace: '已切换工作区：',
    workspace_switch_failed: '工作区切换失败：',
    new_session: '已新建会话',
    new_session_creating: '正在创建新会话…',
    compressing: '正在请求压缩上下文...',
    compress_running_label: '压缩中',
    compress_complete_label: '压缩完成',
    auto_compress_label: '自动压缩',
    compress_failed_label: '压缩失败',
    focus_label: '主题',
    token_usage_on: 'Token 用量显示已开启',
    usage_personality_none: '无',
    token_usage_off: 'Token 用量显示已关闭',
    usage_cache_hit_detail: '缓存：{0}% 命中（读取 {1} / 写入 {2}）',
    usage_cached_percent: '{0}% 已缓存',
    theme_usage: '用法：/theme ',
    theme_set: '主题：',
    no_active_session: '当前没有活动会话',
    cmd_queue: '将消息加入下一轮的队列',
    cmd_goal: '设置或查看持久目标',
    goal_evaluating_progress: 'Evaluating goal progress…',
    goal_working_toward: 'Working toward goal…',
    goal_continuing_toast: 'Continuing toward goal…',
    goal_status_none: 'No active goal. Set one with /goal <text>.',
    goal_status_active: (turns, max_turns, goal) => `⊙ Goal (active, ${turns}/${max_turns} turns): ${goal}`,
    goal_status_paused: (turns, max_turns, reason, goal) => `⏸ Goal (paused, ${turns}/${max_turns}${reason ? `, ${reason}` : ''}): ${goal}`,
    goal_status_done: (turns, max_turns, goal) => `✓ Goal done (${turns}/${max_turns}): ${goal}`,
    goal_set: (turns, goal) => `⊙ Goal set (${turns}-turn budget): ${goal}`,
    goal_paused: (goal) => `⏸ Goal paused: ${goal}`,
    goal_resumed: (goal) => `▶ Goal resumed: ${goal}`,
    goal_cleared: 'Goal cleared.',
    goal_no_goal: 'No active goal.',
    goal_achieved: (reason) => `✓ Goal achieved: ${reason}`,
    goal_paused_budget_exhausted: (turns, max_turns) => `⏸ Goal paused — ${turns}/${max_turns} turns used. Use /goal resume to keep going, or /goal clear to stop.`,
    goal_continuing: (turns, max_turns, reason) => `↻ Continuing toward goal (${turns}/${max_turns}): ${reason}`,
    cmd_interrupt: '取消当前回合并发送新消息',
    cmd_steer: '用纠正信息引导代理（回退为中断）',
    cmd_queue_no_msg: '用法：/queue <消息>',
    cmd_queue_not_busy: '没有活动任务 — 直接发送即可',
    cmd_queue_confirm: '消息已加入队列',
    cmd_interrupt_no_msg: '用法：/interrupt <消息>',
    cmd_interrupt_confirm: '已中断 — 正在发送新消息',
    cmd_steer_no_msg: '用法：/steer <消息>',
    cmd_steer_fallback: 'Steer 不可用 — 已中断并加入队列',
    cmd_steer_delivered: 'Steer 已交付 — 代理将在下一个工具结果中看到',
    steer_leftover_queued: 'Steer 已加入下轮队列',
    busy_steer_fallback: 'Steer 不可用 — 已中断',
    busy_interrupt_confirm: '已中断 — 正在发送新消息',
    settings_label_busy_input_mode: '忙碌输入模式',
    settings_desc_busy_input_mode: '控制当代理正在运行时你发送消息会发生什么。队列会等待；中断会取消并重新开始；引导会在不中断的情况下注入中间修正（当流不可用时回退到队列）。',
    settings_label_fade_text_effect: '淡入文字效果',
    settings_desc_fade_text_effect: '在助手回复时淡入新流式单词。类似于 OpenWebUI；默认关闭以获得最佳性能。',
    settings_busy_input_mode_queue: '队列后续消息',
    settings_busy_input_mode_interrupt: '中断当前轮次',
    settings_busy_input_mode_steer: '引导（中间修正）',
    settings_plugins_title: '插件',
    settings_plugins_meta: '查看已安装的 Hermes 插件及其注册的生命周期挂钩。此面板为只读。',
    settings_plugins_empty: '当前没有可见的 Hermes 插件。通过 Hermes CLI/配置文件安装或启用插件后即可在此查看。',
    plugins_unnamed: '未命名插件',
    plugins_no_description: '未提供描述信息。',
    plugins_no_hooks: '未注册生命周期挂钩',
    plugins_registered_hooks: '已注册的挂钩',
    plugins_enabled: '已启用',
    plugins_disabled: '已禁用',
    plugins_active_provider: '激活（提供方）',
    plugins_provider_no_hooks: '提供方插件 — 无代理可见挂钩',
    plugins_load_failed: '加载插件失败：',
    workspace_empty_no_path: '未选择工作区。请在 设置 → 工作区 中设置工作区以浏览文件。',
    workspace_empty_dir: '此工作区为空。',
    workspace_show_hidden_files: '显示隐藏文件',
    workspace_show_hidden_files_desc: '将 .DS_Store、.git、node_modules 以及其他隐藏文件/系统文件包含在文件树中。',
    workspace_hidden_files_visible: '隐藏 显示',
    workspace_hidden_files_visible_title: '隐藏文件已显示 — 点击查看选项',
    workspace_options: '工作区选项',
    no_personalities: '没有找到人设（可添加到 ~/.hermes/personalities/）',
    available_personalities: '可用人设：',
    personality_switch_hint: '\n\n使用 `/personality <name>` 切换，或用 `/personality none` 清空。',
    personalities_load_failed: '加载人设失败',
    personality_cleared: '人设已清空',
    personality_set: '当前人设：',
    failed_colon: '失败：',
    // ui.js
    no_workspace: '未选择工作区',
    terminal_open_title: '打开工作区 Terminal',
    terminal_no_workspace_title: '请先选择工作区再打开 Terminal',
    terminal_title: '终端',
    terminal_clear: '清屏',
    terminal_copy_output: '复制输出',
    terminal_restart: '重启',
    terminal_collapse: '折叠',
    terminal_expand: '展开',
    terminal_close: '关闭',
    terminal_input_placeholder: '输入命令...',
    terminal_start_failed: '终端启动失败：',
    terminal_input_failed: '终端输入失败：',
    terminal_copy_failed: '复制失败：',
    terminal_error: '终端错误',
    dialog_confirm_title: '确认操作',
    dialog_prompt_title: '输入内容',
    dialog_confirm_btn: '确认',
    // workspace.js
    unsaved_confirm: '预览区有未保存修改，要放弃更改并继续跳转吗？',
    discard: '放弃',
    save: '保存',
    edit: '编辑',
    clear: '清空',
    create: '创建',
    remove: '移除',
    save_title: '保存修改',
    edit_title: '编辑此文件',
    saved: '已保存',
    save_failed: '保存失败：',
    image_load_failed: '图片加载失败',
    file_open_failed: '无法打开文件',
    downloading: (name) => `正在下载 ${name}...`,
    double_click_rename: '双击重命名',
    renamed_to: '已重命名为 ',
    rename_failed: '重命名失败：',
    delete_title: '删除',
    delete_confirm: (name) => `要删除 ${name} 吗？`,
    delete_dir_confirm: (name) => `删除文件夹 "${name}" 及其所有内容？`,
    rename_title: '重命名',
    rename_prompt: '新名称:',
    deleted: '已删除 ',
    delete_failed: '删除失败：',
    reveal_in_finder: '在文件管理器中显示',
    reveal_failed: '显示失败：',
    copy_file_path: '\u590d\u5236\u6587\u4ef6\u8def\u5f84',
    download_folder: 'Download Folder', // TODO: translate
    path_copied: '\u6587\u4ef6\u8def\u5f84\u5df2\u590d\u5236\u5230\u526a\u8d34\u677f',
    path_copy_failed: '\u590d\u5236\u8def\u5f84\u5931\u8d25\uff1a',
    session_rename: '\u91cd\u547d\u540d\u5bf9\u8bdd',
    session_rename_desc: '\u7f16\u8f91\u6b64\u5bf9\u8bdd\u7684\u6807\u9898',
    new_file_prompt: '新文件名（例如 notes.md）：',
    project_name_prompt: '项目名称：',
    created: '已创建 ',
    create_failed: '创建失败：',
    new_folder_prompt: '新文件夹名称：',
    folder_created: '已创建文件夹 ',
    folder_create_failed: '创建文件夹失败：',
  workspace_auto_create_folder: '如果文件夹不存在则创建',
  folder_add_as_space_btn: '添加为工作区',
  folder_add_as_space_msg: '是否将此文件夹添加为新的工作区？',
  folder_add_as_space_title: '添加为工作区？',
    remove_title: '移除',
    empty_dir: '(空)',
    upload_failed: '上传失败：',
    upload_too_large: (maxMb, fileMb) => `\u6587\u4ef6\u8fc7\u5927\uff08${fileMb} MB\uff09\u3002\u6700\u5927\u4e0a\u4f20\u5927\u5c0f\u4e3a ${maxMb} MB\u3002`,
    all_uploads_failed: (n) => `${n} 个文件全部上传失败`,
    // settings panel
    settings_title: '设置',
    settings_save_btn: '保存设置',
    settings_label_model: '默认模型',
    settings_desc_model: '用于新对话。现有对话保持各自选定的模型。',
    settings_label_send_key: '发送快捷键',
    settings_label_theme: '主题',
    settings_label_skin: '皮肤',
    settings_label_font_size: '字体大小',
    font_size_small: '小',
    font_size_default: '默认',
    font_size_large: '大',
    font_size_xlarge: '超大',
    settings_autosave_saving: '保存中…',
    settings_autosave_saved: '已保存',
    settings_autosave_failed: '保存失败',
    settings_autosave_retry: '重试',
    settings_label_language: '语言',
    settings_label_quota_chip: '在编辑器中显示供应商配额标签',
    settings_desc_quota_chip: '在编辑器底部显示剩余配额指示器（如 OpenRouter 信用余额）。默认关闭。启用时仅在宽屏（≥1400px）显示，以保持笔记本和标准桌面屏幕上编辑器的整洁。',
    settings_label_hide_suggestions: 'Hide new-chat suggestions',
    settings_desc_hide_suggestions: 'Hide the three default suggestion buttons on the empty new-chat screen to avoid accidental taps.',
    settings_label_token_usage: '显示 token 用量',
    settings_label_sidebar_density: '侧边栏密度',
    cmd_reasoning: '切换思维可见性（显示/隐藏）、设置工作强度或查看当前状态',
    settings_label_external_sessions: '显示外部会话',
    settings_label_previous_messaging_sessions: '显示以前的消息会话',
    settings_label_sync_insights: '同步到 insights',
    settings_label_check_updates: '检查更新',
    settings_label_whats_new_summary: "Summarize What's New with AI",
    settings_label_bot_name: '默认助手名称',
    settings_label_password: '访问密码',
    settings_saved: '设置已保存',
    settings_save_failed: '保存失败：',
    settings_load_failed: '设置加载失败：',
    settings_saved_pw: '设置已保存，已启用密码保护，当前浏览器会保持登录',
    settings_saved_pw_updated: '设置已保存，密码已更新',
    // login page
    login_title: '登录',
    login_subtitle: '输入密码继续使用',
    login_placeholder: '密码',
    login_btn: '登录',
    login_invalid_pw: '密码错误',
    login_conn_failed: '连接失败',
    // sidebar & navigation
    tab_chat: '聊天',
    tab_memory: '记忆',
    tab_skills: '技能',
    tab_tasks: '任务',
    tab_kanban: '看板',
    kanban_board: '看板',
    kanban_visible_tasks: '{0} 个可见任务',
    kanban_search_tasks: '搜索任务',
    kanban_all_assignees: '所有负责人',
    kanban_all_tenants: '所有租户',
    kanban_include_archived: '包含已归档',
    kanban_no_matching_tasks: '没有匹配的任务',
    kanban_no_data: '无看板数据',
    kanban_work_queue_hint: '这是 Hermes Agent 的工作队列。创建或分类任务，分配任务，将其移至“就绪”状态，然后让调度员认领任务。',
    kanban_unavailable: '看板不可用',
    kanban_read_only: '只读视图',
    kanban_empty: '空',
    kanban_task: '任务',
    kanban_no_description: '无描述',
    kanban_refresh: '刷新',
    kanban_status_triage: '待分类',
    kanban_status_todo: '待办',
    kanban_status_ready: '就绪',
    kanban_status_running: '进行中',
    kanban_status_blocked: '阻塞',
    kanban_status_done: '完成',
    kanban_status_original_hint: '实际状态：{0}。此对话框仅支持编辑 Triage/Todo/Ready。',
    kanban_comments_count: '评论 ({0})',
    kanban_events_count: '事件 ({0})',
    kanban_links: '链接',
    kanban_parents: '父任务',
    kanban_children: '子任务',
    kanban_runs_count: '运行 ({0})',
    kanban_no_comments: '无评论',
    kanban_no_events: '无事件',
    kanban_no_runs: '无运行记录',
    kanban_title: '标题',
    kanban_description: '描述',
    kanban_description_placeholder: '可选 — 需要做什么、验收标准、链接',
    kanban_status: '状态',
    kanban_assignee: '负责人',
    kanban_assignee_placeholder: '可选 — 留空表示任意工作器',
    kanban_tenant: '租户',
    kanban_tenant_placeholder: '可选 — 项目或团队标识',
    kanban_priority: '优先级',
    kanban_priority_hint: '数值越高越先执行,默认为 0。',
    kanban_title_required: '标题为必填项。',
    kanban_edit_task: '编辑任务',
    kanban_run_dispatcher: '运行调度器',
    kanban_run_dispatcher_confirm: '将认领此看板的 Ready 任务并生成工作子进程(每次点击最多 8 个)。是否继续?',
    kanban_assignee_profiles_label: 'Hermes 配置',
    kanban_assignee_other_label: '其他 (CLI 通道 / 已删除的配置)',
    kanban_assignee_unassigned: '— 未分配 (不会自动运行) —',
    kanban_ready_needs_assignee: '您选择了「未分配」+「Ready」。调度器将跳过此任务。再次提交以确认,或选择一个配置。',
    kanban_dispatch_preview_prefix: '预览:',
    kanban_dispatch_run_prefix: '已调度:',
    kanban_dispatch_spawned: '已启动',
    kanban_dispatch_promoted: '已提升',
    kanban_dispatch_reclaimed: '已收回',
    kanban_dispatch_skipped_unassigned: '跳过 (未分配)',
    kanban_dispatch_skipped_nonspawnable: '跳过 (未知配置)',
    kanban_dispatch_auto_blocked: '自动阻止',
    kanban_dispatch_timed_out: '超时',
    kanban_dispatch_crashed: '崩溃',
    kanban_new_task: '新建任务',
    kanban_add_comment: '添加评论',
      kanban_only_mine: '仅我的',
      kanban_bulk_action: '批量操作',
      kanban_nudge_dispatcher: '提醒调度器',
      kanban_stats: '统计',
      kanban_worker_log: '工作日志',
      kanban_block: '阻塞',
      kanban_unblock: '解除阻塞',
      kanban_back_to_board: '返回看板',
      kanban_lanes_by_profile: '按配置文件分列',
      kanban_new_board: '新建看板…',
      kanban_rename_board: '重命名当前看板…',
      kanban_archive_board: '归档当前看板…',
      kanban_archive_board_confirm: '归档看板 "{name}"？任务仍保存在磁盘上，并且可以从 kanban/boards/_archived/ 恢复该看板。',
      kanban_board_archived: '看板已归档',
      kanban_board_name: '名称',
      kanban_board_slug: '标识（小写，连字符）',
      kanban_board_description: '描述（可选）',
      kanban_board_icon: '图标（emoji，可选）',
      kanban_board_color: '颜色（可选）',
      kanban_board_name_required: '名称为必填',
      kanban_board_slug_required: '标识为必填',
      kanban_card_complete: '完成',
      kanban_card_archive: '归档',
      kanban_unassigned: '未分配',
    kanban_status_archived: '已归档',
    tab_todos: '待办',
    tab_insights: '统计',
    tab_dashboard: 'Hermes 仪表盘',
    dashboard_loopback_warning: '仪表盘在服务器上仅限 loopback 访问。请从服务器本机浏览，或使用 --host 0.0.0.0 重启（不安全）。',
    tab_workspaces: '工作区',
    tab_profiles: '配置',
    tab_logs: '日志',
    tab_settings: '设置',

    logs_title: '日志',
    logs_file: '文件',
    logs_tail: '末尾',
    logs_auto_refresh: '自动刷新（5秒）',
    logs_wrap: '自动换行',
    logs_copy_all: '全部复制',
    logs_empty: '暂无日志。',
    logs_loading: '加载日志中…',
    logs_load_failed: '日志加载失败',
    logs_status_idle: '选择日志文件以查看最新内容。',
    logs_no_mtime: '尚未写入',
    logs_truncated_hint: '此处显示的是日志文件的末尾内容。为节省内存，已省略较早的数据。',
    logs_copied: '日志已复制',
    logs_severity: '严重性',
    logs_severity_all: '全部',
    logs_severity_errors: '错误',
    logs_severity_warnings: '警告+',
    logs_filter_active: '已显示（筛选器已启用）',
    new_conversation: '新建对话',
    filter_conversations: '筛选对话…',
    session_time_unknown: '未知',
    session_time_minutes_ago: (n) => `${n}分`,
    session_time_hours_ago: (n) => `${n}小时`,
    session_time_days_ago: (n) => `${n}天`,
    session_time_last_week: '1周',
    session_time_bucket_today: '今天',
    session_time_bucket_yesterday: '昨天',
    session_time_bucket_this_week: '本周',
    session_time_bucket_last_week: '上周',
    session_time_bucket_older: '更早',
    scheduled_jobs: '定时任务',
    new_job: '新任务',
    search_skills: '搜索技能…',
    new_skill: '新技能',
    save_skill: '保存技能',
    personal_memory: '个人记忆',
    current_task_list: '当前任务列表',
    workspace_desc: '为你的会话添加并切换工作区。',
    session_meta_messages: (n) => `${n} 条消息`,
    session_meta_children: (n) => `${n} 子会话`,
    session_meta_segments: (n) => `${n} 段`,
    session_lineage_segment_untitled: '未命名段',
    session_lineage_segment_open: '打开脉络段',
    new_profile: '新配置',
    transcript: '记录',
    download_transcript: '下载为 Markdown',
    import: '导入',
    export_session_json: 'JSON',
    export_session_json_tooltip: '将会话完整导出为 JSON',
    import_session_json_tooltip: '从 JSON 导入会话',
    clear_conversation_btn_tooltip: '清空此会话中的所有消息',
    editing: '编辑中',
    empty_title: '有什么可以帮您？',
    empty_subtitle: '随时提问、运行命令、浏览文件或管理定时任务。',
    cancel: '取消',
    loading: '加载中…',
    create_job: '创建任务',
    suggest_plan: '帮我规划一个小项目。',
    suggest_schedule: '今天有什么安排？',
    suggest_files: '这个工作区有哪些文件？',
    sign_out: '退出登录',
    // Providers panel (English fallback — native translations welcome in follow-up PRs)
    providers_tab_title: '提供商',
    providers_section_title: '提供商',
    providers_section_meta: '管理 AI 提供商的 API 密钥。更改立即生效。',
    providers_status_configured: 'API 密钥已配置',
    providers_status_not_configured: '无 API 密钥',
    providers_status_oauth: 'OAuth',
    providers_status_api_key: 'API 密钥',
    providers_status_not_configured_label: '未配置',
    providers_oauth_hint: '通过 OAuth 认证。无需 API 密钥。',
    providers_oauth_config_yaml_hint: '通过 config.yaml 配置的令牌。如需更新，请编辑 config.yaml 中的 providers 部分或运行 hermes auth。',
    providers_oauth_not_configured_hint: '未认证。在终端中运行 hermes auth 以配置此提供商。',
    providers_save: '保存',
    providers_remove: '移除',
    providers_saving: '保存中…',
    providers_removing: '移除中…',
    providers_enter_key: '请输入 API 密钥',
    providers_empty: '未找到可配置的提供商。',
    providers_key_updated: 'API 密钥已保存',
    providers_key_removed: 'API 密钥已移除',
    providers_key_placeholder_new: 'sk-...',
    providers_key_placeholder_replace: '输入新密钥以替换…',
    provider_quota_title: '当前提供商配额',
    provider_quota_active_provider: '当前提供商',
    provider_quota_last_checked_after_refresh: '刷新后检查',
    provider_quota_last_checked: '上次检查 {0}',
    provider_quota_refresh_usage: '刷新用量',
    provider_quota_refreshing: '正在刷新...',
    provider_quota_refresh_title: '立即刷新提供商用量限制',
    provider_quota_refresh_succeeded: '提供商用量已刷新',
    provider_quota_refresh_failed: '提供商用量刷新失败',
    provider_quota_session_limit: '5 小时限制',
    provider_quota_weekly_limit: '每周限制',
    provider_quota_window_fallback: '窗口',
    provider_quota_metric_remaining: '剩余',
    provider_quota_metric_used: '已用',
    provider_quota_metric_limit: '限额',
    provider_quota_status_available: '可用',
    provider_quota_status_exhausted: '已耗尽',
    provider_quota_status_unavailable: '不可用',
    provider_quota_status_failed: '失败',
    provider_quota_status_checked: '已检查',
    provider_quota_status_no_key: '无密钥',
    provider_quota_status_invalid_key: '无效密钥',
    provider_quota_status_unsupported: '不支持',
    provider_quota_used_meta: '已用 {0}',
    provider_quota_resets_meta: '重置于 {0}',
    provider_quota_credential_pool: '凭据池',
    provider_quota_credential_label: '凭据 {0}',
    provider_quota_pool_plans: '方案：{0}',
    provider_quota_pool_no_windows: '未报告账户限制窗口。',
    provider_quota_account_limits_loaded: '账户限制已加载。',
    provider_quota_unavailable: '配额状态不可用',
    provider_quota_retry_after: '重试时间 {0}',
    provider_quota_pool_summary_available: '{0}/{1} 可用',
    provider_quota_pool_summary_exhausted: '{0} 个已耗尽',
    provider_quota_pool_summary_failed: '{0} 个失败',
    provider_quota_pool_summary_checked: '已检查 {0} 个',
    password_placeholder: '输入新密码…',
    password_env_var_locked: '当前已设置 HERMES_WEBUI_PASSWORD 环境变量并具有优先级。请取消该变量并重启服务器，才能在此管理密码。',
    password_env_var_locked_placeholder: '已锁定：已设置 HERMES_WEBUI_PASSWORD 环境变量',
    disable_auth: '停用认证',
    settings_label_rtl: '从右到左聊天布局',
    settings_desc_rtl: '为阿拉伯语或希伯来语等语言翻转聊天消息和编辑器输入的对齐方式。仅影响聊天区域 — 侧边栏和其他面板保持从左到右。',
    settings_label_sound: '通知声音',
    settings_label_notifications: '浏览器通知',
    settings_desc_sound: '助手完成回复时播放提示音。',
    settings_desc_notifications: '当标签页在后台时，回复完成后显示系统通知。',
    settings_desc_token_usage: '在助手每次回复下方显示输入/输出 token 数量。也可以用 /usage 切换。',
    settings_sidebar_density_compact: '紧凑',
    settings_sidebar_density_detailed: '详细',
    settings_desc_sidebar_density: '控制左侧会话列表展示多少元信息。',
    settings_label_auto_title_refresh: '自适应标题更新',
    settings_auto_title_refresh_off: '关闭',
    settings_auto_title_refresh_5: '每 5 轮对话',
    settings_auto_title_refresh_10: '每 10 轮对话',
    settings_auto_title_refresh_20: '每 20 轮对话',
    settings_desc_auto_title_refresh: '基于最新对话自动重新生成会话标题，使其随对话发展保持相关。需要配置 LLM 标题生成模型。',
    settings_desc_external_sessions: '在会话列表中显示来自 CLI、Telegram、Discord、Slack 等渠道的对话。点击可导入并继续对话。',
    settings_desc_previous_messaging_sessions: '显示被 reset 或 compression 替换的较旧的 Discord、Telegram、Slack 和 Weixin 会话。',
    settings_desc_sync_insights: '将 WebUI token 使用情况同步到 state.db，使 hermes /insights 包含浏览器会话数据。默认关闭。',
    settings_desc_check_updates: '当有更新的 WebUI 或助手版本时显示横幅。会在后台定期执行 git fetch。',
    settings_desc_whats_new_summary: "Changes the What's New action from opening the raw diff first to generating a short, human-readable summary. The regular diff comparison stays available after the summary.",
    settings_desc_bot_name: '仅用于默认个人资料。其他个人资料会使用各自的名称。',
    settings_desc_password: '输入新密码以设置或更改。留空保持当前设置。',
    // onboarding
    onboarding_badge: '首次运行',
    onboarding_title: '欢迎使用 Hermes Web UI',
    archive_extracted: (n, c) => `从 ${c} 个压缩包中解压了 ${n} 个文件`,
    onboarding_lead: '快速引导将验证 Hermes、保存真实的提供商配置、选择工作区和模型，并可选设置密码保护应用。',
    onboarding_back: '返回',
    onboarding_continue: '继续',
    onboarding_skip: '跳过设置',
    onboarding_skipped: '设置已跳过 — 使用现有配置。',
    onboarding_open: '打开 Hermes',
    onboarding_step_system_title: '系统检查',
    onboarding_step_system_desc: '验证 Hermes Agent 与配置可见性。',
    onboarding_step_setup_title: '提供商设置',
    onboarding_step_setup_desc: '保存最小可用的 Hermes 提供商配置。',
    onboarding_step_workspace_title: '工作区 + 模型',
    onboarding_step_workspace_desc: '为新会话和聊天选择默认值。',
    onboarding_step_password_title: '可选密码',
    onboarding_step_password_desc: '在分享前为 Web UI 添加保护。',
    onboarding_step_finish_title: '完成',
    onboarding_step_finish_desc: '确认信息并进入应用。',
    onboarding_notice_system_ready: 'Hermes Agent 看起来可从 Web UI 访问。',
    onboarding_notice_system_unavailable: 'Hermes Agent 尚未完全可用。Bootstrap 可以安装它，但提供商设置可能仍需要终端。',
    onboarding_check_agent: 'Hermes Agent',
    onboarding_check_agent_ready: '已检测且可导入',
    onboarding_check_agent_missing: '缺失或仅部分可导入',
    onboarding_check_password: '密码',
    onboarding_check_password_enabled: '已启用',
    onboarding_check_password_disabled: '尚未启用',
    onboarding_check_provider: '提供商配置',
    onboarding_check_provider_ready: '可开始聊天',
    onboarding_check_provider_partial: '已保存但不完整',
    onboarding_check_provider_pending: '需要验证',
    onboarding_config_file: '配置文件：',
    onboarding_env_file: '.env 文件：',
    onboarding_unknown: '未知',
    onboarding_current_provider: '当前配置：',
    onboarding_missing_imports: '缺失导入：',
    onboarding_notice_setup_required: '请先在此选择一个简单的提供商路径。高级 OAuth 流程暂时仍建议在 Hermes CLI 中完成。',
    onboarding_notice_setup_already_ready: '已检测到可用的 Hermes 提供商配置。你可以保留它，或在这里替换。',
    onboarding_oauth_provider_ready_title: '提供商已完成认证',
    onboarding_oauth_provider_ready_body: '此实例已配置为使用通过 Hermes CLI 设置的 OAuth 提供商（<strong>{provider}</strong>）。这里不需要 API key，点击继续即可完成设置。',
    onboarding_oauth_provider_not_ready_title: 'OAuth 提供商尚未认证',
    onboarding_oauth_provider_not_ready_body: '此实例已配置为使用 <strong>{provider}</strong>，该提供商使用 OAuth 而非 API key。请在终端运行 <code>hermes auth</code> 或 <code>hermes model</code> 完成认证，然后重新加载 Web UI。',
    onboarding_oauth_switch_hint: '或者在下方选择其他提供商，切换到 API key 配置：',
    onboarding_notice_workspace: '这些值复用与正式应用相同的设置 API。',
    onboarding_workspace_label: '工作区',
    onboarding_workspace_or_path: '或输入工作区路径',
    onboarding_workspace_placeholder: '/home/you/workspace',
    onboarding_provider_label: '设置模式',
    onboarding_quick_setup_badge: '快速设置',
    provider_category_easy_start: '快速开始',
    provider_category_self_hosted: '本地 / 开源',
    provider_category_specialized: '专业服务',
    onboarding_api_key_label: 'API key',
    onboarding_api_key_placeholder: '留空可保留已保存的 key',
    onboarding_api_key_label_optional: 'API 密钥（可选）',
    onboarding_api_key_placeholder_optional: '留空用于无需密钥的服务器',
    onboarding_api_key_help_keyless: '大多数 LM Studio / Ollama / vLLM 安装无需密钥即可运行。',
    oauth_login_codex: '使用 Codex (ChatGPT) 登录',
    oauth_codex_step1: '步骤 1：访问此 URL 并输入代码',
    oauth_codex_step2: '步骤 2：在页面上输入此代码',
    oauth_codex_polling: '等待授权…',
    oauth_codex_success: 'Codex OAuth 登录成功！',
    oauth_codex_error: 'OAuth 登录失败',
    oauth_codex_expired: '代码已过期，请重试',
    onboarding_api_key_help_prefix: '会作为密钥保存到 Hermes .env 文件中，变量名为',
    onboarding_base_url_label: 'Base URL',
    onboarding_base_url_placeholder: 'https://your-endpoint.example/v1',
    onboarding_base_url_help: '用于 OpenAI 兼容路由、自托管服务、LiteLLM、Ollama、LM Studio、vLLM 或类似端点。',
    onboarding_model_label: '默认模型',
    onboarding_workspace_help: '选择设置完成后 Hermes 在新聊天中使用的模型。',
    onboarding_custom_model_placeholder: 'your-model-name',
    onboarding_custom_model_help: '对于自定义端点，请填写服务端要求的精确模型 ID。',
    onboarding_notice_password_enabled: '已配置密码。仅在你想替换时输入新密码。',
    onboarding_notice_password_recommended: '可选，但如果你会把 UI 暴露到 localhost 之外，建议设置。',
    onboarding_password_label: '密码（可选）',
    onboarding_password_placeholder: '留空则跳过',
    onboarding_password_help: '密码通过现有设置 API 保存，并在服务端进行哈希处理。',
    onboarding_notice_finish: '你之后仍可在设置中修改这些选项。',
    onboarding_not_set: '未设置',
    onboarding_password_will_enable: '将启用',
    onboarding_password_will_replace: '将被替换',
    onboarding_password_keep_existing: '保留当前密码',
    onboarding_password_remains_disabled: '将保持禁用',
    onboarding_password_skipped: '暂时跳过',
    onboarding_finish_help: '完成后会在设置中写入 <code>onboarding_completed</code>，并进入常规应用界面。',
    onboarding_error_choose_workspace: '继续前请先选择工作区。',
    onboarding_error_choose_model: '继续前请先选择模型。',
    onboarding_error_provider_required: '继续前请先选择设置模式。',
    onboarding_error_base_url_required: '自定义端点必须填写 Base URL。',
    onboarding_probe_test_button: '测试连接',
    onboarding_probe_probing: '正在测试连接…',
    onboarding_probe_ok: '已连接。{n} 个模型可用。',
    onboarding_probe_error_generic: '无法访问配置的基础 URL。',
    onboarding_probe_error_invalid_url: '基础 URL 必须以 http:// 或 https:// 开头。',
    onboarding_probe_error_dns: '无法解析主机名。请检查 URL，或在 Docker 中使用主机 IP 而非 localhost。',
    onboarding_probe_error_connect_refused: '连接被拒绝 — 该地址上可能没有运行服务器。在 Docker 容器内，请使用主机 IP 而非 localhost。',
    onboarding_probe_error_timeout: '端点未及时响应。请确认服务器正在运行且 URL 正确。',
    onboarding_probe_error_http_4xx: '端点返回客户端错误。请检查认证信息和 URL 路径（通常以 /v1 结尾）。',
    onboarding_probe_error_http_5xx: '端点返回服务器错误。请检查 LM Studio / Ollama 服务器日志。',
    onboarding_probe_error_parse: '端点未返回预期的模型列表格式。请确认 URL 指向 OpenAI 兼容的 API 根路径。',
    onboarding_probe_error_unreachable: '无法访问配置的基础 URL。',
    onboarding_error_probe_failed: '无法验证配置的基础 URL。',
    onboarding_error_workspace_required: '必须填写工作区。',
    onboarding_error_model_required: '必须填写模型。',
    onboarding_complete: '引导完成',

    // panel/runtime i18n
    error_prefix: '错误：',
    not_available: '无',
    never: '从未',
    add: '添加',
    add_failed: '添加失败：',
    remove_failed: '移除失败：',
    switch_failed: '切换失败：',
    name_required: '名称不能为空',
    content_required: '内容不能为空',
    view: '查看',
    dismiss: '忽略',
    disable: '停用',
    cron_no_jobs: '未找到定时任务。',
    cron_status_off: '关闭',
    cron_status_paused: '暂停',
    cron_status_error: '错误',
    cron_status_active: '已启用',
    cron_status_running: '执行中\u2026',
    cron_status_needs_attention: '需要处理',
    cron_attention_desc: '这个重复定时任务没有下次运行时间。调度器可能没能计算出下一次运行。',
    cron_attention_croniter_hint: 'Gateway 运行环境可能缺少 croniter 包。请用支持 cron 的环境重启 Gateway，然后恢复这个任务。',
    cron_attention_resume: '恢复并重新计算',
    cron_jobs_project: '定时任务',
    cron_attention_run_once: '立即运行一次',
    cron_attention_copy_diagnostics: '复制诊断信息',
    cron_diagnostics_copied: '定时任务诊断信息已复制',
    cron_next: '下次',
    cron_last: '上次',
    cron_run_now: '立即运行',
    cron_pause: '暂停',
    cron_resume: '恢复',
    cron_job_name_placeholder: '任务名称',
    cron_schedule_placeholder: '调度表达式',
    cron_prompt_placeholder: '提示词',
    cron_last_output: '最近输出',
    cron_expand_prompt: '展开提示词',
    cron_collapse_prompt: '收起提示词',
    cron_expand_output: '展开输出',
    cron_collapse_output: '收起输出',
    cron_all_runs: '全部运行记录',
    cron_hide_runs: '隐藏记录',
    cron_no_runs_yet: '（暂无运行记录）',
    cron_schedule_required_example: '必须填写调度（例如 "0 9 * * *" 或 "every 1h"）',
    cron_schedule_required: '必须填写调度',
    cron_prompt_required: '必须填写提示词',
    cron_job_created: '任务已创建',
    cron_job_triggered: '任务已触发',
    cron_job_paused: '任务已暂停',
    cron_job_resumed: '任务已恢复',
    cron_job_updated: '任务已更新',
    cron_delete_confirm_title: '删除定时任务',
    cron_delete_confirm_message: '此操作无法撤销。',
    cron_job_deleted: '任务已删除',
    cron_completion_status: (name, status) => `定时任务“${name}”${status}`,
    status_failed: '失败',
    status_completed: '完成',
    todos_no_active: '此会话暂无活动任务列表。',
    clear_conversation_title: '清空对话',
    clear_conversation_message: '要清空所有消息吗？此操作无法撤销。',
    clear_failed: '清空失败：',
    skills_no_match: '没有匹配的技能。',
    linked_files: '关联文件',
    skill_load_failed: '加载技能失败：',
    skill_file_load_failed: '加载文件失败：',
    skill_name_required: '技能名称不能为空',
    skill_updated: '技能已更新',
    skill_created: '技能已创建',
    memory_notes_label: '记忆（备注）',
    memory_saved: '记忆已保存',
    my_notes: '我的备注',
    user_profile: '用户画像',
    no_notes_yet: '暂无备注。',
    no_profile_yet: '暂无用户画像。',
    agent_soul: '智能体灵魂',
    no_soul_yet: '暂无灵魂定义。',
    workspace_choose_path: '选择工作区路径',
    workspace_choose_path_meta: '添加已校验路径并切换当前会话',
    workspace_manage: '管理工作区',
    workspace_manage_meta: '打开 Spaces 面板',
    workspace_use_title: '用于当前会话',
    workspace_use: '使用',
    workspace_add_path_placeholder: '添加工作区路径（例如 /home/user/my-project）',
    workspace_paths_validated_hint: '保存前会校验路径是否为已存在目录。',

    workspace_drag_hint: '拖动以重新排序',
    workspace_reorder_failed: '重新排序失败',
    workspace_added: '工作区已添加',
    workspace_renamed: '工作区已重命名',
    workspace_remove_confirm_title: '移除工作区',
    workspace_remove_confirm_message: (path) => `要移除"${path}"吗？`,
    workspace_removed: '工作区已移除',
    workspace_switch_prompt_title: '切换工作区',
    workspace_switch_prompt_message: '输入绝对路径以添加并切换当前会话的工作区。',
    workspace_switch_prompt_confirm: '切换',
    workspace_switch_prompt_placeholder: '/Users/you/project',
    workspace_not_added: '工作区未添加成功',
    workspace_already_saved: '工作区已存在，请在列表中选择',
    workspace_busy_switch: 'Agent 运行中，无法切换工作区',
    discard_file_edits_title: '放弃文件编辑？',
    discard_file_edits_message: '切换工作区将丢弃预览区未保存的文件修改。',
    workspace_switched_to: (name) => `已切换到 ${name}`,
    profiles_no_profiles: '未找到配置档。',
    profile_api_keys_configured: '已配置 API 密钥',
    profile_gateway_running: '网关运行中',
    profile_gateway_stopped: '网关已停止',
    profile_active: '当前',
    profile_no_configuration: '无配置',
    profile_skill_count: (count) => `${count} 个技能`,
    profile_use: '使用',
    profile_switch_title: '切换到此配置档',
    profile_delete_title: '删除此配置档',
    profile_default_label: '（默认）',
    profile_name_placeholder: '配置档名称（小写字母、a-z、0-9、连字符）',
    profile_clone_label: '复制当前配置档的配置',
    profile_model_label: '模型 / 提供商',
    profile_model_hint: '为这个新配置档选择已配置的提供商和模型。',
    profile_model_use_default: '使用当前配置档默认值',
    profile_base_url_placeholder: 'Base URL（可选，例如 http://localhost:11434）',
    profile_api_key_placeholder: 'API 密钥（可选）',
    manage_profiles: '管理配置档',
    profiles_load_failed: '加载配置档失败',
    profile_switched_new_conversation: (name) => `已切换到配置档：${name}，并新建对话`,
    profile_switched: (name) => `已切换到配置档：${name}`,
    profile_name_rule: '仅允许小写字母、数字、连字符和下划线',
    profile_base_url_rule: 'Base URL 必须以 http:// 或 https:// 开头',
    profile_created: (name) => `配置档已创建：${name}`,
    profile_delete_confirm_title: (name) => `删除配置档“${name}”？`,
    profile_delete_confirm_message: '该配置档的所有会话、配置、技能和记忆将被永久删除。此操作无法撤销。',
    profile_deleted: (name) => `配置档已删除：${name}`,
    active_conversation_none: '当前未选择活动会话。',
    active_conversation_meta: (title, count) => `${title} · ${count} 条消息`,
    settings_unsaved_changes: '你有未保存的更改。',
    sign_out_failed: '退出登录失败：',
    disable_auth_confirm_title: '停用密码保护',
    disable_auth_confirm_message: '任何人都可以访问此实例。',
    auth_disabled: '认证已停用，密码保护已移除',
    disable_auth_failed: '停用认证失败：',
    bg_error_single: (title) => `“${title}”出现错误`,
    bg_error_multi: (count) => `${count} 个会话出现错误`,
    skill_deleted: '技能已删除',
    skill_delete_confirm: '删除技能 "{0}"？',
    skills_empty_title: '选择一个技能',
    skills_empty_sub: '从侧边栏中选择一个技能以查看其内容，或创建一个新技能。',
    skills_edit: '编辑',
    skills_delete: '删除',
    skills_back_to: '返回 {0}',
    tasks_empty_title: '选择一个计划任务',
    tasks_empty_sub: '从侧边栏中选择一个任务以查看其详情和运行记录，或创建一个新任务。',
    workspaces_empty_title: '选择一个空间',
    workspaces_empty_sub: '从侧边栏中选择一个空间以查看其文件和设置，或添加一个新空间。',
    profiles_empty_title: '选择一个配置文件',
    profiles_empty_sub: '从侧边栏中选择一个代理配置文件以查看和编辑其设置，或创建一个新配置文件。',
    // skill form
    skill_name: '名称',
    skill_category: '分类',
    skill_category_placeholder: '可选，例如 devops',
    skill_content: 'SKILL.md 内容',
    skill_content_placeholder: 'YAML frontmatter + markdown 正文',
    skill_rename_not_supported: '不支持重命名技能。请创建新技能并删除旧技能。',
    skill_metadata: '元数据',
    // cron form
    cron_name_label: '名称',
    cron_name_placeholder: '可选',
    cron_schedule_label: '计划',
    cron_schedule_hint: "循环任务请用 'every 1h' 或 Cron 表达式。像 '30m' 这样的裸时长只会运行一次。",
    cron_schedule_once_warning: "像 '30m' 这样的时长写法只会运行一次，并在运行后移除。要保留循环任务，请使用 'every 30m'。",
    cron_prompt_label: '提示词',
    cron_deliver_label: '输出位置',
    cron_deliver_local: '本地（仅保存输出）',
    cron_profile_label: '配置档',
    cron_profile_server_default: '服务器默认',
    cron_profile_server_default_hint: '运行时使用 WebUI 服务器默认配置档。没有配置档的现有作业会保留此旧行为。',
    cron_toast_notifications_label: '完成提示',
    cron_toast_notifications_hint: '此 Cron 完成时显示 toast。关闭后，任务徽标和新运行标记仍会更新。',
    cron_toast_notifications_enabled: '已启用',
    cron_toast_notifications_disabled: '已禁用',
    cron_skills_label: '技能',
    cron_skills_placeholder: '添加技能（可选）…',
    cron_skills_edit_hint: '创建后无法再编辑技能列表。',
    cron_duplicate: '复制',
    cron_duplicated: '任务已复制（已暂停）',
    // workspace form
    workspace_name_label: '名称',
    workspace_name_placeholder: '可选的友好名称',
    workspace_path_label: '路径',
    workspace_path_required: '路径是必填项',
    workspace_path_readonly: '路径不可更改。只能重命名。',
    workspace_new_title: '新空间',
    // profile form
    profile_name_label: '名称',
    profile_base_url_label: '基础 URL',
    profile_api_key_label: 'API 密钥',
  
    // Session management and settings keys (en fallback — pending translation)
    session_archive: '归档会话',
    session_hide_external: '从列表中隐藏',
    session_archive_desc: '隐藏此会话，直到显示归档',
    session_archive_worktree_desc: '隐藏此会话；保留磁盘上的 worktree',
    session_hide_external_desc: '从 WebUI 列表中隐藏此导入的会话，不删除原始历史记录。',
    session_archive_failed: '归档失败：',
    session_archived: '会话已归档',
    session_archived_worktree: '会话已归档。Worktree 仍保留在磁盘上。',
    session_hidden: '已从列表中隐藏会话',
    session_delete: '删除会话',
    session_delete_desc: '永久删除此会话',
    session_delete_confirm: '删除此会话？',
    session_delete_worktree_desc: '仅删除 WebUI 会话；保留磁盘上的 worktree',
    session_delete_worktree_confirm: (path) => `删除此会话？位于 ${path} 的 worktree 将保留在磁盘上。`,
    session_deleted: '会话已删除',
    session_deleted_worktree: '会话已删除。Worktree 仍保留在磁盘上。',
    session_worktree_remove: '删除 worktree',
    session_worktree_remove_desc: (path) => `删除位于 ${path} 的 git worktree`,
    session_worktree_remove_confirm: (path) => `确定从磁盘删除 git worktree？\n\n路径：${path}\n\n整个 worktree 目录将被删除，WebUI 中的会话数据保留。`,
    session_worktree_remove_not_exists: (path) => `位于 ${path} 的 worktree 在磁盘上已不存在。`,
    session_worktree_remove_confirm_label: '删除',
    session_worktree_removed: 'Worktree 已删除。',
    session_worktree_remove_failed: '删除 worktree 失败：',
    session_worktree_remove_status_failed: '读取 worktree 状态失败：',
    session_worktree_remove_locked_by_stream: '无法删除 — 存在活跃的流式会话正在使用此 worktree。',
    session_worktree_remove_locked_by_terminal: '无法删除 — 存在活跃的终端会话正在使用此 worktree。',
    session_worktree_remove_unsafe_blocked: '请先处理本地更改或未推送提交，再删除此 worktree。',
    session_worktree_remove_dirty_warning: '⚠️ 此 worktree 有未提交的更改，将被永久删除。',
    session_worktree_remove_untracked_warning: (count) => `${count} 个未追踪文件将被永久删除。`,
    session_worktree_remove_ahead_warning: (ahead) => `${ahead} 个未推送的提交将丢失。`,
    session_duplicate: '复制会话',
    session_duplicate_desc: '用相同工作区和模型创建副本',
    session_duplicate_failed: '复制失败：',
    session_stop_response: '停止回复',
    session_stop_response_desc: '取消此会话正在进行的回复',
    session_duplicated: '会话已复制',
    session_move_project: '移至项目',
    session_move_project_desc_has: '更改此会话的项目',
    session_move_project_desc_none: '为此会话分配项目',
    session_pin: '置顶会话',
    session_pin_desc: '将此会话保持在顶部',
    session_pin_failed: '置顶失败：',
    session_restore: '恢复会话',
    session_restore_desc: '将会话恢复到主列表',
    session_restored: '会话已恢复',
    session_unpin: '取消置顶',
    session_unpin_desc: '从置顶中移除',
    session_select_mode: '选择',
    session_select_mode_desc: '选择会话以批量管理',
    session_select_all: '全选',
    session_deselect_all: '取消全选',
    session_selected_count: '已选 {0} 个',
    session_batch_archive: '归档',
    session_batch_delete: '删除',
    session_batch_move: '移动到项目',
    session_batch_delete_confirm: '删除 {0} 个会话？',
    session_batch_archive_confirm: '归档 {0} 个会话？',
    session_batch_delete_worktree_confirm: '删除 {0} 个会话？其中 {1} 个 worktree 会话会把 worktree 目录保留在磁盘上。',
    session_batch_archive_worktree_confirm: '归档 {0} 个会话？其中 {1} 个 worktree 会话会把 worktree 目录保留在磁盘上。',
    session_no_selection: '未选择任何会话',
    settings_dropdown_appearance: '外观',
    settings_dropdown_conversation: '对话',
    settings_dropdown_preferences: '偏好',
    settings_dropdown_providers: '提供商',
    settings_dropdown_system: '系统',
    settings_heading_subtitle: '偏好设置、对话工具和系统控制。',
    settings_heading_title: '控制中心',
    settings_section_appearance_meta: '主题、强调色和视觉风格。',
    settings_section_appearance_title: '外观',
    settings_section_conversation_title: '对话',
    settings_section_preferences_meta: 'Hermes WebUI 的默认和 UI 行为。',
    settings_section_preferences_title: '偏好',
    settings_section_system_meta: '实例版本和访问控制。',
    settings_check_now: '立即检查',
    settings_checking: '检查中\u2026',
    settings_up_to_date: '已是最新 \u2713',
    settings_updates_available: '有 {count} 个更新可用',
    settings_updates_disabled: '更新检查已禁用',
    settings_update_check_failed: '更新检查失败',
    settings_label_workspace_panel_open: '默认保持工作区面板打开',
    settings_desc_workspace_panel_open: '启用后，工作区/文件浏览器面板会在每次新会话时自动打开。您仍可随时手动关闭。',
    settings_label_session_jump_buttons: '显示会话跳转按钮',
    settings_desc_session_jump_buttons: '阅读较长会话历史时显示悬浮的开头和结尾按钮。',

    settings_label_session_endless_scroll: '向上滚动时加载更早的消息',

    settings_desc_session_endless_scroll: '启用后，向上滚动时会自动加载更早的消息。禁用时请使用加载更早消息按钮。',

    settings_label_tab_visibility: '侧边栏标签',
    settings_desc_tab_visibility: '选择在侧边栏和导航栏中显示哪些标签。聊天和设置始终可见。',
    open_in_browser: '在浏览器中打开',
    settings_section_system_title: '系统',
    settings_tab_appearance: '外观',
    settings_tab_conversation: '对话',
    settings_tab_preferences: '偏好',
    settings_tab_plugins: '插件',
    settings_tab_system: '系统',
    status_updated: '已更新',
    status_ephemeral: '临时快照 — 不会保存到对话记录。',
    status_no_tokens: '无令牌数据',
    status_profile: '配置文件',
    status_hermes_home: 'Hermes 主目录',
    status_started: '开始时间',
    status_tokens: '令牌',
    status_unknown: '未知',
    cmd_yolo: 'YOLO 模式切换',
    yolo_no_session: '无活动会话',
    yolo_enabled: '⚡ YOLO 模式已开启 — 将跳过所有审批',
    cmd_branch: '将此对话分叉到新会话',
    cmd_branch_usage:'/branch [名称] — 分叉会话（可选择添加名称）',
    branch_forked: '已创建新分叉',
    branch_failed: '分叉失败：',
    fork_from_here: '从此处分叉',
    forked_from: '分叉自',
    yolo_disabled: 'YOLO 模式已关闭',
    yolo_pill_label: 'YOLO',
    yolo_pill_title_active: 'YOLO 模式激活 — 点击关闭',
    approval_skip_all: '⚡ 本次会话全部跳过',
    approval_skip_all_title: '跳过本次会话的所有审批提示',
    // composer action tooltips
    composer_send: '发送消息',
    composer_queue: '消息加入队列',
    composer_interrupt: '中断并发送',
    composer_steer: '引导当前响应',
    composer_stop: '停止生成',
    composer_disabled_clarify: '请回复上方的澄清请求',
    composer_disabled_compression: '等待压缩完成',
    composer_disabled_empty: '请输入消息后发送',
    composer_mobile_workspace: '工作区',
    composer_mobile_model: '模型',
    composer_mobile_reasoning: '推理',
    composer_mobile_context: '上下文',

    pdf_loading: '正在加载 PDF {0}…',
    pdf_too_large: 'PDF 文件过大，无法内联预览',
    pdf_no_pages: '无法渲染 PDF 预览',
    pdf_error: 'PDF 加载失败',
    pdf_download: '下载 PDF',
    html_loading: '正在加载 HTML 预览…',
    html_too_large: 'HTML 文件过大，无法内联预览',
    html_error: 'HTML 预览加载失败',
    html_open_full: '打开完整页面',
    html_sandbox_label: 'HTML 预览',
    media_audio_label: '音频',
    media_svg_label: '图表',
    media_video_label: '视频',
    csv_loading: '加载 CSV',
    csv_too_large: 'CSV 文件过大，无法内联渲染',
    csv_no_data: 'CSV 文件数据不足，无法渲染为表格',
    csv_error: '加载 CSV 文件失败',
    csv_header_note: '第一行显示为表格标题',
    excalidraw_loading: '加载图表',
    excalidraw_too_large: 'Excalidraw 文件过大，无法内联渲染',
    excalidraw_invalid: '无效的 Excalidraw 文件格式',
    excalidraw_error: '加载 Excalidraw 文件失败',
    excalidraw_label: '图表',
    excalidraw_download: '下载',
    excalidraw_empty: '空图表',
    excalidraw_render_error: '渲染图表失败',
    excalidraw_simplified: '简化 SVG 预览 — 与 Excalidraw 画布不完全相同',
    // TTS (#499)
    tts_listen: '收听',
    tts_not_supported: '语音合成不可用',
    settings_label_tts: '回复语音合成',
    settings_desc_tts: '在助手消息上显示扬声器按钮',
    settings_label_tts_auto_read: '自动朗读回复',
    settings_desc_tts_auto_read: '自动朗读助手回复',
    // Composer voice-mode pref (#1488)
    settings_label_voice_mode: '免提语音模式按钮',
    settings_desc_voice_mode: '在听写麦克风旁显示语音模式按钮（音频波形）。让您自然说话 — Hermes 会在停顿后自动发送并朗读回复。需要支持语音识别和 TTS 的浏览器。',
    settings_label_tts_voice: '语音',
    settings_desc_tts_voice: '选择语音合成声音',
    settings_label_tts_rate: '语速',
    settings_label_tts_pitch: '音调',
    checkpoint_date: '日期',
    checkpoint_diff_files_changed: (n) => `${n} file${n === 1 ? '' : 's'} changed`,  // TODO: translate
    checkpoint_diff_no_changes: '此检查点与当前工作区之间无差异。',
    checkpoint_diff_title: '检查点变更',
    checkpoint_empty: '此工作区未找到检查点。',
    checkpoint_error: '加载检查点失败',
    checkpoint_files: '文件',
    checkpoint_loading: '加载检查点中…',
    checkpoint_message: '消息',
    checkpoint_restore: '恢复',
    checkpoint_restore_confirm_message: (ckpt) => `将工作区恢复到检查点 "${ckpt}"？此操作将用已保存版本覆盖文件。此检查点之后添加的文件不会被删除。`,
    checkpoint_restore_confirm_title: '恢复检查点？',
    checkpoint_restored: '检查点已恢复',
    checkpoint_title: '检查点',
    checkpoint_view_diff: '查看差异',
    insights_activity_by_day: '按日活动',
    insights_activity_by_hour: '按时活动',
    insights_cost: '预估费用',
    insights_daily_tokens: '每日令牌',
    insights_model_name: '模型',
    insights_model_sessions: '会话',
    insights_model_tokens: '令牌',
    insights_model_cost: '费用',
    insights_model_share: '占比',
    insights_no_usage_data: '暂无使用数据',
    insights_footer: '显示最近 {days} 天的数据',
    insights_input_tokens: '输入',
    insights_messages: '消息',
    insights_models: '模型',
    insights_no_cost: 'N/A',
    insights_output_tokens: '输出',
    insights_peak_hour: '高峰：{hour}时',
    insights_sessions: '会话',
    insights_title: '使用分析',
    insights_token_breakdown: '令牌分解',
    insights_tokens: '令牌',
    insights_total: '总计',
    settings_desc_api_redact: '自托管用户可禁用以实现透明（不推荐用于共享实例）。',
    settings_label_api_redact: '在 API 响应中隐藏敏感数据',
    voice_error: '此浏览器不支持语音功能',
    voice_listening: '正在聆听…',
    voice_mode_active: '语音模式已开启',
    voice_mode_off: '语音模式已关闭',
    voice_speaking: '正在说话…',
    voice_thinking: '思考中…',
    // Composer voice buttons (#1488)
    voice_dictate: '听写',
    voice_dictate_active: '停止听写',
    voice_mode_toggle: '语音模式',
    voice_mode_toggle_active: '退出语音模式',
    subagent_children: '子代理会话',
  },

  // Traditional Chinese (zh-Hant)
  'zh-Hant': {
    _lang: 'zh-Hant',
    _label: '\u7e41\u9ad4\u4e2d\u6587',
    _speech: 'zh-TW',
    // boot.js
    cancelling: '\u6b63\u5728\u53d6\u6d88...',
    cancel_failed: '\u53d6\u6d88\u5931\u6557\uff1a',
    mic_denied: '\u9ea6\u514b\u98a8\u8a2a\u554f\u88ab\u62d2\u7d75\uff0c\u8acb\u6aa2\u67e5\u700f\u89bd\u5668\u6b0a\u9650\u3002',
    mic_no_speech: '\u6c92\u6709\u6aa2\u6e2c\u5230\u8a71\u97f3\uff0c\u8acb\u518d\u5617\u4e00\u6b21\u3002',
    mic_network: '\u8a71\u97f3\u8b58\u5225\u76ee\u524d\u4e0d\u53ef\u7528\u3002',
    mic_error: '\u8a71\u97f3\u8f38\u5165\u51fa\u932f\uff1a',
    session_imported: '\u6703\u8a71\u5df2\u5c0e\u5165',
    import_failed: '\u5c0e\u5165\u5931\u6557\uff1a',
    import_invalid_json: 'JSON \u7121\u6548',
    image_pasted: '\u5df2\u7c98\u8cbc\u5716\u7247\uff1a',
    // messages.js
    edit_message: '\u7de8\u8f2f\u8a0a\u606f',
    regenerate: '\u91cd\u65b0\u751f\u6210\u56de\u8986',
    copy: '\u8907\u88fd',
    copied: '\u5df2\u8907\u88fd',
    copy_failed: '\u8907\u88fd\u5931\u6557',
    selected_text_reply: '用所選內容回覆',
    selected_text_reply_title: '將所選聊天文字作為引用上下文附加',
    selected_text_reply_appended: '已將所選文字加入輸入框',

    diff_loading: '載入 diff',
    diff_error: '無法載入 patch 檔案',
    diff_too_large: 'Patch 檔案過大，無法內聯顯示',
    tree_view: '樹狀',
    raw_view: '原始',
    parse_failed_note: '解析失敗',
    you: '\u4f60',
    mcp_servers_title: 'MCP 伺服器',
    mcp_servers_desc: '管理 config.yaml 中設定的 MCP 伺服器。',
    mcp_no_servers: '未設定 MCP 伺服器。',
    mcp_add_server: '+ 新增伺服器',
    mcp_field_name: '伺服器名稱',
    mcp_transport_label: '傳輸類型',
    mcp_field_command: '命令',
    mcp_field_args: '參數（以逗號分隔）',
    mcp_field_url: 'URL',
    mcp_field_timeout: '逾時（秒）',
    mcp_save: '儲存',
    mcp_cancel: '取消',
    mcp_name_required: '伺服器名稱為必填。',
    mcp_url_required: 'HTTP 傳輸需要 URL。',
    mcp_command_required: 'stdio 傳輸需要命令。',
    mcp_saved: 'MCP 伺服器已儲存。',
    mcp_save_failed: '儲存 MCP 伺服器失敗。',
    mcp_delete_confirm_title: '刪除 MCP 伺服器',
    mcp_delete_confirm_message: '刪除 MCP 伺服器「{0}」？此操作無法復原。',
    mcp_deleted: 'MCP 伺服器已刪除。',
    mcp_delete_failed: '刪除 MCP 伺服器失敗。',
    mcp_load_failed: '載入 MCP 伺服器失敗。',
    mcp_restart_hint: 'Server changes are read-only here for now. Edit config.yaml and restart Hermes for changes to take effect.',
    mcp_toggle_followup: 'Enable/disable controls are intentionally deferred until MCP reload semantics are explicit.',
    mcp_status_active: 'Active',
    mcp_status_configured: 'Configured',
    mcp_status_disabled: 'Disabled',
    mcp_status_invalid_config: 'Invalid config',
    mcp_status_unknown: 'Unknown',
    mcp_tool_count: '{0} tools',
    mcp_enabled_yes: 'Enabled',
    mcp_enabled_no: 'Disabled',
    mcp_tools_title: 'MCP Tools',
    mcp_tools_desc: 'Search known tools across active MCP servers.',
    mcp_tools_search_placeholder: 'Search tools by name, server, or description…',
    mcp_tools_no_tools: 'No MCP tools are available from the active runtime inventory.',
    mcp_tools_no_matches: 'No MCP tools match your search.',
    mcp_tools_load_failed: 'Failed to load MCP tools.',
    mcp_tools_schema_empty: 'No schema parameters.',
    mcp_tools_runtime_note: 'Tool inventory only uses already-known active MCP runtime data; the WebUI does not start or probe servers.',
    mcp_tools_summary_no_matches: (query,total) => `No MCP tools matching “${query}” (${total} total MCP tools).`,
    mcp_tools_summary_none: 'No MCP tools to show.',
    mcp_tools_summary_matching: (query) => ` matching “${query}”`,
    mcp_tools_summary_total_note: (total) => ` (${total} total MCP tools)`,
    mcp_tools_summary_showing: (start,end,filtered,searchNote,totalNote,page,pages) => `Showing ${start}-${end} of ${filtered} MCP tools${searchNote}${totalNote}. Page ${page} of ${pages}.`,
    mcp_tools_page_size_prefix: 'Show',
    mcp_tools_page_size_suffix: 'per page',
    mcp_tools_per_page_aria: 'MCP tools per page',
    mcp_tools_inactive_configured_servers: (servers) => `Configured but inactive in this WebUI runtime: ${servers}.`,
    mcp_tools_pagination_label: 'MCP tools pagination',
    mcp_tools_previous_page: '‹ Prev',
    mcp_tools_previous_page_aria: 'Previous MCP tools page',
    mcp_tools_next_page: 'Next ›',
    mcp_tools_next_page_aria: 'Next MCP tools page',
    thinking: '\u601d\u8003\u904e\u7a0b',
    expand_all: '\u5168\u90e8\u5c55\u958b',
    collapse_all: '\u5168\u90e8\u6298\u758a',
    edit_failed: '\u7de8\u8f2f\u5931\u6557\uff1a',
    regen_failed: '\u91cd\u65b0\u751f\u6210\u5931\u6557\uff1a',
    reconnect_active: '\u56de\u8986\u4ecd\u5728\u751f\u6210\u4e2d\uff0c\u6e96\u5099\u597d\u5f8c\u8981\u91cd\u65b0\u52a0\u8f09\u55ce\uff1f',
    reconnect_finished: '\u4f60\u96e2\u958b\u6642\u6709\u56de\u8986\u6b63\u5728\u751f\u6210\uff0c\u8a0a\u606f\u5167\u5bb9\u53ef\u80fd\u5df2\u7d93\u66f4\u65b0\u3002',
    // approval card
    approval_heading: '\u9700\u8981\u5be9\u6838',
    approval_desc_prefix: '\u6aa2\u6e2c\u5230\u5371\u96aa\u547d\u4ee4',
    approval_btn_once: '\u5141\u8a31\u4e00\u6b21',
    approval_btn_once_title: '\u5141\u8a31\u57f7\u884c\u6b64\u547d\u4ee4\u4e00\u6b21\uff08Enter\uff09',
    approval_btn_session: '\u672c\u6b21\u5141\u8a31',
    approval_btn_session_title: '\u672c\u6b21\u6703\u8a71\u671f\u9593\u5141\u8a31',
    approval_btn_always: '始終允許',
    approval_btn_always_title: '始終允許此命令模式',
    approval_btn_deny: '\u62d2\u7d55',
    approval_btn_deny_title: '\u62d2\u7edd — \u4e0d\u57f7\u884c\u6b64\u547d\u4ee4',
    approval_responding: '\u8655\u7406\u4e2d\u2026',
    clarify_heading: '\u9700\u8981\u91d0\u6e05',
    clarify_hint: '\u8acb\u9078\u64c7\u4e00\u500b\u9078\u9805\uff0c\u6216\u5728\u4e0b\u65b9\u8f38\u5165\u4f60\u81ea\u5df1\u7684\u56de\u7b54\u3002',
    clarify_other: '\u5176\u4ed6',
    clarify_send: '\u9001\u51fa',
    clarify_input_placeholder: '\u8f38\u5165\u4f60\u7684\u56de\u7b54\u2026',
    clarify_responding: '\u8655\u7406\u4e2d\u2026',
    untitled: '\u672a\u547d\u540d',
    n_messages: (n) => `${n} \u689d\u8a0a\u606f`,
    load_older_messages: '↑ 向上捲動或點擊以載入較早的訊息',
    session_jump_start: '開頭',
    session_jump_start_label: '跳至會話開頭',
    session_jump_end: '結尾',
    session_jump_end_label: '跳至會話結尾',
    jump_to_question: '回到問題',
    jump_to_question_label: '跳至這則回答對應的問題',
    model_unavailable: '\uff08\u4e0d\u53ef\u7528\uff09',
    model_unavailable_title: '\u6b64\u6a21\u578b\u5df2\u7d93\u4e0d\u5728\u7576\u524d provider \u5217\u8868\u4e2d',
    provider_mismatch_warning: (m,p)=>`\"${m}\" \u53ef\u80fd\u7121\u6cd5\u5728\u7576\u524d\u914d\u7f6e\u7684\u63d0\u4f9b\u8005 (${p}) \u4e0b\u904b\u4f5c\u3002\u5c1a\u9001\uff0c\u6216\u5728\u7d42\u7aef\u57f7\u884c \`hermes model\` \u5207\u63db\u3002`,
    provider_mismatch_label: '\u63d0\u4f9b\u8005\u4e0d\u76f8\u7b26',
    model_not_found_label: '\u672a\u627e\u5230\u6a21\u578b',
    // commands.js
    cmd_help: '\u67e5\u770b\u53ef\u7528\u547d\u4ee4',
    cmd_clear: '\u6e05\u7a7a\u7576\u524d\u5c0d\u8a71\u8a0a\u606f',
    cmd_compress: '\u624b\u52d5\u58d3\u7e2e\u5c0d\u8a71\u4e0a\u4e0b\u6587\uff08\u7528\u6cd5\uff1a/compress [\u4e3b\u984c]\uff09',
    ctx_compress_hint: '\u58d3\u7e2e\u4e0a\u4e0b\u6587\u4ee5\u91cb\u653e\u7a7a\u9593 →',
    ctx_compress_action: '\u26a0 \u7acb\u5373\u58d3\u7e2e\u4ee5\u91cb\u653e\u4e0a\u4e0b\u6587',
    cmd_compact_alias: '\u820a\u5225\u540d\uff1a/compress',
    cmd_model: '\u5207\u63db\u6a21\u578b\uff08\u4f8b\u5982 /model gpt-4o\uff09',
    cmd_workspace: '\u6309\u540d\u7a31\u5207\u63db\u5de5\u4f5c\u5340',
    cmd_terminal: '\u6253\u958b\u5de5\u4f5c\u5340 Terminal',
    cmd_new: '\u65b0\u5efa\u804a\u5929\u6703\u8a71',
    cmd_usage: '\u5207\u63db token \u7528\u91cf\u986f\u793a',
    cmd_theme: '\u5207\u63db\u5916\u89c0\uff08\u4e3b\u984c\uff1asystem/dark/light\uff0c\u76ae\u819a\uff1adefault/ares/mono/slate/poseidon/sisyphus/charizard/sienna/catppuccin/nous/geist-contrast\uff09',
    cmd_personality: '\u5207\u63db Agent \u4eba\u8a2d',
    cmd_skills: '\u5217\u51fa\u53ef\u7528\u7684 Hermes \u6280\u80fd',
    available_commands: '\u53ef\u7528\u547d\u4ee4\uff1a',
    type_slash: '\u8f38\u5165 / \u53ef\u67e5\u770b\u547d\u4ee4',
    conversation_cleared: '\u5c0d\u8a71\u5df2\u6e05\u7a7a',
    command_label: '\u547d\u4ee4',
    context_compaction_label: '\u4e0a\u4e0b\u6587\u58d3\u7e2e',
    preserved_task_list_label: '\u4fdd\u7559\u7684\u4efb\u52d9\u6e05\u55ae',
    reference_only_label: '\u50c5\u4f9b\u53c3\u8003',
    model_usage: '\u7528\u6cd5\uff1a/model <name>',
    no_model_match: '\u6c92\u6709\u5339\u914d\u201c',
    switched_to: '\u5df2\u5207\u63db\u5230 ',
    workspace_usage: '\u7528\u6cd5\uff1a/workspace <name>',
    no_workspace_match: '\u6c92\u6709\u5339\u914d\u201c',
    switched_workspace: '\u5df2\u5207\u63db\u5de5\u4f5c\u5340\uff1a',
    workspace_switch_failed: '\u5de5\u4f5c\u5340\u5207\u63db\u5931\u6557\uff1a',
    new_session: '\u5df2\u65b0\u5efa\u6703\u8a71',
    new_session_creating: '正在建立新對話…',
    compressing: '\u6b63\u5728\u8981\u6c42\u58d3\u7e2e\u4e0a\u4e0b\u6587...',
    compress_running_label: '\u58d3\u7e2e\u4e2d',
    compress_complete_label: '\u58d3\u7e2e\u5b8c\u6210',
    auto_compress_label: '\u81ea\u52d5\u58d3\u7e2e',
    compress_failed_label: '\u58d3\u7e2e\u5931\u6557',
    focus_label: '\u4e3b\u984c',
    token_usage_on: 'Token \u7528\u91cf\u986f\u793a\u5df2\u958b\u555f',
    token_usage_off: 'Token \u7528\u91cf\u986f\u793a\u5df2\u95dc\u9589',
    usage_cache_hit_detail: '快取：{0}% 命中（讀取 {1} / 寫入 {2}）',
    usage_cached_percent: '{0}% 已快取',
    theme_usage: '\u7528\u6cd5\uff1a/theme ',
    theme_set: '\u4e3b\u984c\uff1a',
    no_active_session: '\u7576\u524d\u6c92\u6709\u6d3b\u52d5\u6703\u8a71',

    workspace_empty_no_path: '未選擇工作區。請在 設定 → 工作區 中設定工作區以瀏覽檔案。',
    workspace_empty_dir: '此工作區為空。',
    workspace_show_hidden_files: '顯示隱藏檔案',
    workspace_show_hidden_files_desc: 'Include .DS_Store, .git, node_modules, and other hidden / system files in the file tree.',
    workspace_hidden_files_visible: 'hidden visible',
    workspace_hidden_files_visible_title: 'Hidden files are visible — click for options',
    workspace_options: 'Workspace options',
    no_personalities: '\u6c92\u6709\u627e\u5230\u4eba\u8a2d\uff08\u53ef\u6dfb\u52a0\u5230 ~/.hermes/personalities/\uff09',
    available_personalities: '\u53ef\u7528\u4eba\u8a2d\uff1a',
    personality_switch_hint: '\n\n\u4f7f\u7528 `/personality <name>` \u5207\u63db\uff0c\u6216\u7528 `/personality none` \u6e05\u7a7a\u3002',
    personalities_load_failed: '\u52a0\u8f7d\u4eba\u8a2d\u5931\u6557',
    personality_cleared: '\u4eba\u8a2d\u5df2\u6e05\u7a7a',
    personality_set: '\u7576\u524d\u4eba\u8a2d\uff1a',
    failed_colon: '\u5931\u6557\uff1a',
    // ui.js
    no_workspace: '\u672a\u9078\u64c7\u5de5\u4f5c\u5340',
    terminal_open_title: '\u6253\u958b\u5de5\u4f5c\u5340 Terminal',
    terminal_no_workspace_title: '\u8acb\u5148\u9078\u64c7\u5de5\u4f5c\u5340\u518d\u6253\u958b Terminal',
    terminal_title: 'Terminal',
    terminal_clear: '\u6e05\u7a7a',
    terminal_copy_output: '\u8907\u88fd\u8f38\u51fa',
    terminal_restart: '\u91cd\u555f',
    terminal_collapse: '\u6536\u5408',
    terminal_expand: '\u5c55\u958b',
    terminal_close: '\u95dc\u9589',
    terminal_input_placeholder: '\u8f38\u5165\u547d\u4ee4...',
    terminal_start_failed: 'Terminal \u555f\u52d5\u5931\u6557\uff1a',
    terminal_input_failed: 'Terminal \u8f38\u5165\u5931\u6557\uff1a',
    terminal_copy_failed: '\u8907\u88fd\u5931\u6557\uff1a',
    terminal_error: 'Terminal \u932f\u8aa4',
    // workspace.js
    unsaved_confirm: '\u9810\u89bd\u5340\u6709\u672a\u5132\u5b58\u4fee\u6539\uff0c\u8981\u653e\u68c4\u66f4\u6539\u5e76\u7e7c\u7e8c\u8df3\u8ee2\u55ce\uff1f',
    save: '\u5132\u5b58',
    edit: '\u7de8\u8f2f',
    save_title: '\u5132\u5b58\u4fee\u6539',
    edit_title: '\u7de8\u8f2f\u6b64\u6587\u4ef6',
    saved: '\u5df2\u5132\u5b58',
    save_failed: '\u5132\u5b58\u5931\u6557\uff1a',
    image_load_failed: '\u5716\u7247\u52a0\u8f09\u5931\u6557',
    file_open_failed: '\u7121\u6cd5\u6253\u958b\u6587\u4ef6',
    downloading: (name) => `\u6b63\u5728\u4e0b\u8f09 ${name}...`,
    double_click_rename: '\u96d9\u64ca\u91cd\u547d\u540d',
    renamed_to: '\u5df2\u91cd\u547d\u540d\u70ba ',
    rename_failed: '\u91cd\u547d\u540d\u5931\u6557\uff1a',
    delete_title: '\u522a\u9664',
    delete_confirm: (name) => `\u8981\u522a\u9664 ${name} \u55ce\uff1f`,
    delete_dir_confirm: (name) => `刪除資料夾 "${name}" 及其所有內容？`,
    rename_title: '重新命名',
    rename_prompt: '新名稱:',
    deleted: '\u5df2\u522a\u9664 ',
    delete_failed: '\u522a\u9664\u5931\u6557\uff1a',
    reveal_in_finder: '\u5728\u6a94\u6848\u7ba1\u7406\u54e1\u4e2d\u986f\u793a',
    reveal_failed: '\u986f\u793a\u5931\u6557\uff1a',
    copy_file_path: '\u8907\u88fd\u6a94\u6848\u8def\u5f91',
    download_folder: 'Download Folder', // TODO: translate
    path_copied: '\u6a94\u6848\u8def\u5f91\u5df2\u8907\u88fd\u5230\u526a\u8cbc\u7c3f',
    path_copy_failed: '\u8907\u88fd\u8def\u5f91\u5931\u6557\uff1a',
    session_rename: '\u91cd\u65b0\u547d\u540d\u5c0d\u8a71',
    session_rename_desc: '\u7de8\u8f2f\u6b64\u5c0d\u8a71\u7684\u6a19\u984c',
    new_file_prompt: '\u65b0\u6587\u4ef6\u540d\uff08\u4f8b\u5982 notes.md\uff09\uff1a',
    created: '\u5df2\u5275\u5efa ',
    create_failed: '\u5275\u5efa\u5931\u6557\uff1a',
    new_folder_prompt: '\u65b0\u6587\u4ef6\u593e\u540d\u7a31\uff1a',
    folder_created: '\u5df2\u5275\u5efa\u6587\u4ef6\u593e ',
    folder_create_failed: '\u5275\u5efa\u6587\u4ef6\u593e\u5931\u6557\uff1a',
  workspace_auto_create_folder: '\u8cc7\u6599\u593e\u4e0d\u5b58\u5728\u6642\u5247\u5efa\u7acb',
  folder_add_as_space_btn: '\u65b0\u589e\u70ba\u5de5\u4f5c\u5340',
  folder_add_as_space_msg: '\u662f\u5426\u5c07\u6b64\u8cc7\u6599\u593e\u65b0\u589e\u70ba\u5de5\u4f5c\u5340\uff1f',
  folder_add_as_space_title: '\u65b0\u589e\u70ba\u5de5\u4f5c\u5340\uff1f',
    remove_title: '\u79fb\u9664',
    empty_dir: '(空)',
    upload_failed: '上傳失敗：',
    upload_too_large: (maxMb, fileMb) => `檔案過大（${fileMb} MB）。最大上傳大小為 ${maxMb} MB。`,
    all_uploads_failed: (n) => `${n} 個檔案全部上傳失敗`,
    session_pin: '釘選對話',
    session_unpin: '取消釘選',
    session_pin_desc: '將此對話置頂',
    session_unpin_desc: '從置頂移除',
    session_pin_failed: '釘選失敗：',
    session_move_project: '移至專案',
    session_move_project_desc_has: '變更此對話的專案',
    session_move_project_desc_none: '為此對話指定專案',
    session_archive: '封存對話',
    session_hide_external: '從列表中隱藏',
    session_restore: '還原對話',
    session_archive_desc: '隱藏此對話，直到開啟顯示封存',
    session_archive_worktree_desc: '隱藏此對話；保留磁碟上的 worktree',
    session_hide_external_desc: '從 WebUI 列表中隱藏此匯入的對話，不刪除原始歷史記錄。',
    session_restore_desc: '將此對話移回主清單',
    session_archived: '對話已封存',
    session_archived_worktree: '對話已封存。Worktree 仍保留在磁碟上。',
    session_hidden: '已從列表中隱藏對話',
    session_restored: '對話已還原',
    session_archive_failed: '封存失敗：',
    session_duplicate: '複製對話',
    session_duplicate_desc: '建立一個相同工作區與模型的副本',
    session_duplicated: '對話已複製',
    session_duplicate_failed: '複製失敗：',
    session_stop_response: 'Stop response',
    session_stop_response_desc: 'Cancel the running response for this conversation',
    session_delete: '刪除對話',
    session_delete_desc: '永久移除這個對話',
    session_delete_confirm: '刪除此對話？',
    session_delete_worktree_desc: '只刪除 WebUI 對話；保留磁碟上的 worktree',
    session_delete_worktree_confirm: (path) => `刪除此對話？位於 ${path} 的 worktree 將保留在磁碟上。`,
    session_deleted: '對話已刪除',
    session_deleted_worktree: '對話已刪除。Worktree 仍保留在磁碟上。',
    session_worktree_remove: '刪除 worktree',
    session_worktree_remove_desc: (path) => `刪除位於 ${path} 的 git worktree`,
    session_worktree_remove_confirm: (path) => `確定從磁碟刪除 git worktree？\n\n路徑：${path}\n\n整個 worktree 目錄將被刪除，WebUI 中的工作階段資料保留。`,
    session_worktree_remove_not_exists: (path) => `位於 ${path} 的 worktree 在磁碟上已不存在。`,
    session_worktree_remove_confirm_label: '刪除',
    session_worktree_removed: 'Worktree 已刪除。',
    session_worktree_remove_failed: '刪除 worktree 失敗：',
    session_worktree_remove_status_failed: '讀取 worktree 狀態失敗：',
    session_worktree_remove_locked_by_stream: '無法刪除 — 存在活躍的串流工作階段正在使用此 worktree。',
    session_worktree_remove_locked_by_terminal: '無法刪除 — 存在活躍的終端機工作階段正在使用此 worktree。',
    session_worktree_remove_unsafe_blocked: '請先處理本機變更或未推送提交，再刪除此 worktree。',
    session_worktree_remove_dirty_warning: '⚠️ 此 worktree 有未提交的變更，將被永久刪除。',
    session_worktree_remove_untracked_warning: (count) => `${count} 個未追蹤檔案將被永久刪除。`,
    session_worktree_remove_ahead_warning: (ahead) => `${ahead} 個未推送的提交將丟失。`,
    session_select_mode: '選取',
    session_select_mode_desc: '選取會話以批次管理',
    session_select_all: '全選',
    session_deselect_all: '取消全選',
    session_selected_count: '已選 {0} 個',
    session_batch_archive: '封存',
    session_batch_delete: '刪除',
    session_batch_move: '移至專案',
    session_batch_delete_confirm: '刪除 {0} 個會話？',
    session_batch_archive_confirm: '封存 {0} 個會話？',
    session_batch_delete_worktree_confirm: '刪除 {0} 個會話？其中 {1} 個 worktree 會話會把 worktree 目錄保留在磁碟上。',
    session_batch_archive_worktree_confirm: '封存 {0} 個會話？其中 {1} 個 worktree 會話會把 worktree 目錄保留在磁碟上。',
    session_no_selection: '未選取任何會話',
    // settings panel
    settings_heading_title: '控制中心',
    settings_heading_subtitle: '偏好設定、對話工具與系統控制。',
    settings_section_conversation_title: '對話',
    settings_section_appearance_title: '外觀',
    settings_section_appearance_meta: '主題、強調色與視覺風格。',
    settings_section_preferences_title: '偏好設定',
    settings_section_preferences_meta: 'Hermes Web UI 的預設值與介面行為。',
    settings_section_system_title: '系統',
    settings_section_system_meta: '實例版本與存取控制。',
    settings_check_now: '立即檢查',
    settings_checking: '檢查中\u2026',
    settings_up_to_date: '已是最新 \u2713',
    settings_updates_available: '有 {count} 個更新可用',
    settings_updates_disabled: '更新檢查已禁用',
    settings_update_check_failed: '更新檢查失敗',
    settings_label_workspace_panel_open: '預設保持工作區面板開啓',
    settings_desc_workspace_panel_open: '啟用後，工作區/檔案瀏覽器面板會在每次新會話時自動開啓。您仍可隨時手動關閉。',
    settings_label_session_jump_buttons: '顯示會話跳轉按鈕',
    settings_desc_session_jump_buttons: '閱讀較長會話歷史時顯示浮動的開頭與結尾按鈕。',

    settings_label_session_endless_scroll: '向上捲動時載入較早訊息',

    settings_desc_session_endless_scroll: '啟用後，向上捲動時會自動載入較早訊息。停用時請使用載入較早訊息按鈕。',

    settings_label_tab_visibility: '側邊欄標籤',
    settings_desc_tab_visibility: '選擇在側邊欄和導航列中顯示哪些標籤。聊天和設定始終可見。',
    open_in_browser: '在瀏覽器中開啓',
    settings_dropdown_conversation: '對話',
    settings_dropdown_appearance: '外觀',
    settings_dropdown_preferences: '偏好設定',
    settings_dropdown_providers: '供應商',
    settings_dropdown_system: '系統',
    settings_tab_conversation: '對話',
    settings_tab_appearance: '外觀',
    settings_tab_preferences: '偏好設定',
    settings_tab_plugins: '外掛',
    settings_plugins_title: '外掛',
    settings_plugins_meta: '檢視已安裝的 Hermes 外掛及其註冊的生命週期鉤子。此面板為唯讀。',
    settings_plugins_empty: '目前沒有可見的 Hermes 外掛。透過 Hermes CLI/設定檔安裝或啟用外掛後即可在此檢視。',
    plugins_unnamed: '未命名外掛',
    plugins_no_description: '未提供描述。',
    plugins_no_hooks: '未註冊生命週期鉤子',
    plugins_registered_hooks: '已註冊的鉤子',
    plugins_enabled: '已啟用',
    plugins_disabled: '已停用',
    plugins_active_provider: '啟用中（提供者）',
    plugins_provider_no_hooks: '提供者外掛 — 無代理可見鉤子',
    plugins_load_failed: '載入外掛失敗：',
    settings_tab_system: '系統',
    settings_title: '\u8a2d\u5b9a',
    settings_save_btn: '\u5132\u5b58\u8a2d\u5b9a',
    settings_label_model: '\u9ed8\u8a8d\u6a21\u578b',
    settings_desc_model: '\u7528\u65bc\u65b0\u6703\u8a71\u3002\u73fe\u6709\u6703\u8a71\u6703\u4fdd\u7559\u5404\u81ea\u9078\u5b9a\u7684\u6a21\u578b\u3002',
    settings_label_send_key: '\u767c\u9001\u5feb\u6377\u9375',
    settings_label_theme: '\u4e3b\u984c',
    settings_label_skin: '佈景',
    settings_label_font_size: '\u5b57\u9ad4\u5927\u5c0f',
    font_size_small: '\u5c0f',
    font_size_default: '\u9810\u8a2d',
    font_size_large: '\u5927',
    font_size_xlarge: '\u8d85\u5927',
    settings_autosave_saving: '\u5132\u5b58\u4e2d…',
    settings_autosave_saved: '\u5df2\u5132\u5b58',
    settings_autosave_failed: '\u5132\u5b58\u5931\u6557',
    settings_autosave_retry: '\u91cd\u8a66',
    settings_label_language: '\u8a9e\u8a00',
    settings_label_quota_chip: '在編輯器中顯示供應商配額標籤',
    settings_desc_quota_chip: '在編輯器底部顯示剩餘配額指示器（如 OpenRouter 點數餘額）。預設關閉。啟用時僅在寬螢幕（≥1400px）顯示，以保持筆記型電腦和標準桌面螢幕上編輯器的整潔。',
    settings_label_hide_suggestions: 'Hide new-chat suggestions',
    settings_desc_hide_suggestions: 'Hide the three default suggestion buttons on the empty new-chat screen to avoid accidental taps.',
    settings_label_token_usage: '\u986f\u793a token \u7528\u91cf',
    settings_label_sidebar_density: '側邊欄密度',
    cmd_reasoning: '切換思考區塊可見性（顯示/隱藏）或設定努力等級',
    settings_label_external_sessions: '顯示外部會話',
    settings_label_previous_messaging_sessions: '顯示以前的訊息對話',
    settings_label_sync_insights: '\u540c\u6b65\u5230 insights',
    settings_label_check_updates: '\u6aa2\u67e5\u66f4\u65b0',
    settings_label_whats_new_summary: "Summarize What's New with AI",
    settings_label_bot_name: '預設助手名稱',
    settings_label_password: '\u8a2a\u554f\u5bc6\u78bc',
    settings_saved: '\u8a2d\u5b9a\u5df2\u5132\u5b58',
    settings_save_failed: '\u5132\u5b58\u5931\u6557\uff1a',
    settings_load_failed: '\u8a2d\u5b9a\u52a0\u8f09\u5931\u6557\uff1a',
    archive_extracted: (n, c) => `\u5f9e ${c} \u500b\u58d3\u7e2e\u5305\u4e2d\u89e3\u58d3\u7e2e\u4e86 ${n} \u500b\u6a94\u6848`,
    settings_saved_pw: '\u8a2d\u5b9a\u5df2\u5132\u5b58\uff0c\u5bc6\u78bc\u4fdd\u8b77\u5df2\u555f\u7528\uff0c\u7576\u524d\u700f\u89bd\u5668\u6703\u4fdd\u6301\u767b\u5165',
    settings_saved_pw_updated: '\u8a2d\u5b9a\u5df2\u5132\u5b58\uff0c\u5bc6\u78bc\u5df2\u66f4\u65b0',
    // login page
    login_title: '\u767b\u5f55',
    login_subtitle: '\u8f38\u5165\u5bc6\u78bc\u7e7c\u7e8c\u4f7f\u7528',
    login_placeholder: '\u5bc6\u78bc',
    login_btn: '\u767b\u5f55',
    login_invalid_pw: '\u5bc6\u78bc\u932f\u8aa4',
    login_conn_failed: '\u9023\u63a5\u5931\u6557',
    // missing keys from English
    dialog_confirm_title: '確認操作',
    dialog_prompt_title: '輸入內容',
    dialog_confirm_btn: '確認',
    discard: '放棄',
    clear: '清空',
    create: '建立',
    remove: '移除',
    project_name_prompt: '專案名稱：',
    tab_chat: '\u804a\u5929',
    tab_memory: '\u8a18\u61b6',
    tab_skills: '\u6280\u80fd',
    tab_tasks: '\u4efb\u52d9',
    tab_todos: '待辦',
    tab_insights: '統計',
    tab_dashboard: 'Hermes 儀表板',
    dashboard_loopback_warning: '儀表板在伺服器上僅限 loopback 存取。請從伺服器本機瀏覽，或使用 --host 0.0.0.0 重新啟動（不安全）。',
    tab_logs: 'Logs',
    tab_workspaces: '\u5de5\u4f5c\u5340',
    tab_kanban: 'Kanban',
    kanban_board: '看板',
    kanban_visible_tasks: '{0} 個可見任務',
    kanban_search_tasks: '搜尋任務',
    kanban_all_assignees: '所有指派對象',
    kanban_all_tenants: '所有租戶',
    kanban_include_archived: '包含已封存',
    kanban_no_matching_tasks: '沒有符合的任務',
    kanban_no_data: '沒有看板資料',
    kanban_work_queue_hint: '這是 Hermes Agent 的工作佇列。建立或分類任務、指派對象、移至 Ready，然後讓調度器認領。',
    kanban_unavailable: '看板無法使用',
    kanban_read_only: '唯讀檢視',
    kanban_empty: '空',
    kanban_task: '任務',
    kanban_no_description: '無描述',
    kanban_refresh: '重新整理',
    kanban_status_triage: '分類',
    kanban_status_todo: '待辦',
    kanban_status_ready: '準備就緒',
    kanban_status_running: '執行中',
    kanban_status_blocked: '已封鎖',
    kanban_status_done: '完成',
    kanban_comments_count: '留言 ({0})',
    kanban_events_count: '事件 ({0})',
    kanban_links: '連結',
    kanban_parents: '父任務',
    kanban_children: '子任務',
    kanban_runs_count: '執行 ({0})',
    kanban_no_comments: '沒有留言',
    kanban_no_events: '沒有事件',
    kanban_no_runs: '沒有執行紀錄',
    kanban_title: '標題',
    kanban_description: '描述',
    kanban_description_placeholder: '選填 — 需要完成的事項、驗收標準、連結',
    kanban_status: '狀態',
    kanban_status_original_hint: '實際狀態：{0}。此對話框僅支援編輯 Triage/Todo/Ready。',
    kanban_assignee: '指派對象',
    kanban_assignee_placeholder: '選填 — 個人資料或名稱',
    kanban_tenant: '租戶',
    kanban_tenant_placeholder: '預設',
    kanban_priority: '優先順序',
    kanban_priority_hint: '數字越大越先執行。預設為 0。',
    kanban_title_required: '標題為必填。',
    kanban_new_task: '新任務',
    kanban_add_comment: '新增留言',
    kanban_only_mine: '僅顯示我的',
    kanban_bulk_action: '批次操作',
    kanban_nudge_dispatcher: '預覽調度器',
    kanban_stats: '統計',
    kanban_worker_log: '工作者日誌',
    kanban_block: '封鎖',
    kanban_unblock: '解除封鎖',
    kanban_back_to_board: '返回看板',
    kanban_lanes_by_profile: '按設定檔分泳道',
    kanban_new_board: '新看板…',
    kanban_rename_board: '重新命名目前看板…',
    kanban_archive_board: '封存目前看板…',
    kanban_archive_board_confirm: '封存看板「{name}」？任務仍保留在磁碟上，可從 kanban/boards/_archived/ 復原。',
    kanban_board_archived: '看板已封存',
    kanban_board_name: '名稱',
    kanban_board_slug: '代號（小寫、連字號）',
    kanban_board_description: '描述（選填）',
    kanban_board_icon: '圖示（表情符號，選填）',
    kanban_board_color: '顏色（選填）',
    kanban_board_name_required: '名稱為必填',
    kanban_board_slug_required: '代號為必填',
    kanban_card_complete: '完成',
    kanban_card_archive: '封存',
    kanban_unassigned: '未指派',
    kanban_status_archived: '已封存',
    kanban_edit_task: '編輯任務',
    kanban_run_dispatcher: '執行調度器',
    kanban_run_dispatcher_confirm: '將認領此看板的 Ready 任務並產生工作子程序（每次點擊最多 8 個）。是否繼續？',
    kanban_assignee_profiles_label: 'Hermes 設定檔',
    kanban_assignee_other_label: '其他（CLI 通道 / 已刪除的設定檔）',
    kanban_assignee_unassigned: '— 未指派（不會自動執行）—',
    kanban_ready_needs_assignee: '您選擇了「未指派」＋「Ready」。調度器將跳過此任務。再次送出以確認，或選擇一個設定檔。',
    kanban_dispatch_preview_prefix: '預覽：',
    kanban_dispatch_run_prefix: '已調度：',
    kanban_dispatch_spawned: '已啟動',
    kanban_dispatch_promoted: '已提升',
    kanban_dispatch_reclaimed: '已收回',
    kanban_dispatch_skipped_unassigned: '跳過（未指派）',
    kanban_dispatch_skipped_nonspawnable: '跳過（未知設定檔）',
    kanban_dispatch_auto_blocked: '自動封鎖',
    kanban_dispatch_timed_out: '逾時',
    kanban_dispatch_crashed: '崩潰',
    logs_severity: '嚴重性',
    logs_severity_all: '全部',
    logs_severity_errors: '錯誤',
    logs_severity_warnings: '警告+',
    logs_filter_active: '已顯示（篩選器已啟用）',
    new_conversation: '新對話',
    filter_conversations: '篩選對話',
    scheduled_jobs: '排程任務',
    new_job: '\u65b0\u4efb\u52d9',
    search_skills: '\u641c\u5c0b\u6280\u80fd',
    new_skill: '\u65b0\u6280\u80fd',
    save_skill: '\u5132\u5b58\u6280\u80fd',
    personal_memory: '\u500b\u4eba\u8a18\u61b6',
    current_task_list: '\u76ee\u524d\u4efb\u52d9\u6e05\u55ae',
    session_meta_messages: (n) => `${n} 則訊息`,
    session_meta_children: (n) => `${n} 則子`,
    session_meta_segments: (n) => `${n} 段`,
    session_lineage_segment_untitled: '未命名段',
    session_lineage_segment_open: '開啟脈絡段',
    new_profile: '\u65b0\u914d\u7f6e\u6a94',
    transcript: '\u8a18\u9304',
    download_transcript: '\u4e0b\u8f09\u8a18\u9304',
    import: '\u5c0e\u5165',
    export_session_json: 'JSON',
    export_session_json_tooltip: '\u5c07\u6703\u8a71\u5b8c\u6574\u532f\u51fa\u70ba JSON',
    import_session_json_tooltip: '\u5f9e JSON \u532f\u5165\u6703\u8a71',
    clear_conversation_btn_tooltip: '\u6e05\u7a7a\u6b64\u6703\u8a71\u4e2d\u7684\u6240\u6709\u8a0a\u606f',
    editing: '\u7de8\u8f2f\u4e2d',
    empty_title: '有什麼可以幫忙？',
    empty_subtitle: '點擊上方按鈕開始對話',
    cancel: '\u53d6\u6d88',
    loading: '\u52a0\u8f09\u4e2d',
    create_job: '\u5efa\u7acb\u4efb\u52d9',
    suggest_plan: '幫我規劃一個小專案',
    suggest_schedule: '今天的時程如何？',
    suggest_files: '這個工作區有哪些檔案？',
    sign_out: '\u767b\u51fa',
    password_placeholder: '\u5bc6\u78bc',
    password_env_var_locked: '\u76ee\u524d\u5df2\u8a2d\u5b9a HERMES_WEBUI_PASSWORD \u74b0\u5883\u8b8a\u6578\u4e14\u512a\u5148\u751f\u6548\u3002\u8acb\u53d6\u6d88\u8a2d\u5b9a\u4e26\u91cd\u65b0\u555f\u52d5\u4f3a\u670d\u5668\uff0c\u624d\u80fd\u5728\u6b64\u7ba1\u7406\u5bc6\u78bc\u3002',
    password_env_var_locked_placeholder: '\u5df2\u9396\u5b9a\uff1a\u5df2\u8a2d\u5b9a HERMES_WEBUI_PASSWORD \u74b0\u5883\u8b8a\u6578',
    disable_auth: '\u505c\u7528\u9a57\u8b49',
    settings_label_rtl: '從右到左聊天版面',
    settings_desc_rtl: '為阿拉伯語或希伯來語等語言翻轉聊天訊息和編輯器輸入的對齊方式。僅影響聊天區域 — 側邊欄和其他面板保持從左到右。',
    settings_label_sound: '\u901a\u77e5\u8072\u97f3',
    settings_label_notifications: '\u700f\u89bd\u901a\u77e5',
    settings_desc_sound: '助手完成回答時播放聲音。',
    settings_desc_notifications: '當分頁在後台時，有回答完成時會顯示系統通知。',
    settings_desc_token_usage: '\u5728\u52a9\u624b\u6bcf\u6b21\u56de\u7b54\u4e0b\u65b9\u986f\u793a Input/Output token \u6578\u91cf\u3002\u4e5f\u53ef\u4ee5\u7528 /usage \u5207\u63db\u3002',
    settings_sidebar_density_compact: '精簡',
    settings_sidebar_density_detailed: '詳細',
    settings_desc_sidebar_density: '控制左側對話清單要顯示多少額外資訊。',
    settings_label_auto_title_refresh: '\u81ea\u9002\u61c9\u6a19\u984c\u66f4\u65b0',
    settings_auto_title_refresh_off: '\u95dc\u9589',
    settings_auto_title_refresh_5: '\u6bcf 5 \u8f2a\u5c0d\u8a71',
    settings_auto_title_refresh_10: '\u6bcf 10 \u8f2a\u5c0d\u8a71',
    settings_auto_title_refresh_20: '\u6bcf 20 \u8f2a\u5c0d\u8a71',
    settings_desc_auto_title_refresh: '\u57fa\u65bc\u6700\u65b0\u5c0d\u8a71\u81ea\u52d5\u91cd\u65b0\u751f\u6210\u6703\u8a71\u6a19\u984c\uff0c\u4f7f\u5176\u968f\u5c0d\u8a71\u767c\u5c55\u4fdd\u6301\u76f8\u95dc\u3002\u9700\u8981\u914d\u7f6e LLM \u6a19\u984c\u751f\u6210\u6a21\u578b\u3002',
    settings_desc_external_sessions: '在會話列表中顯示來自 CLI、Telegram、Discord、Slack 等管道的對話。點擊可導入並繼續對話。',
    settings_desc_previous_messaging_sessions: '顯示被 reset 或 compression 替換的較舊的 Discord、Telegram、Slack 和 Weixin 對話。',
    settings_desc_sync_insights: '將 WebUI token 使用情況同步到 state.db，使 hermes /insights 包含瀏覽器會話數據。預設未啟用。',
    settings_desc_check_updates: '當有更新的 WebUI 或助手版本時顯示標記。將在後台正常執行 Git-Fetch。',
    settings_desc_whats_new_summary: "Changes the What's New action from opening the raw diff first to generating a short, human-readable summary. The regular diff comparison stays available after the summary.",
    settings_desc_bot_name: '僅用於預設個人檔案。其他個人檔案會使用各自的名稱。',
    settings_desc_password: '\u8a2d\u5b9a WebUI \u767b\u5165\u5bc6\u78bc\u3002\u5047\u5982\u5df2\u8a2d\u7f6e\uff0c\u6bcf\u6b21\u52a0\u8f09\u90fd\u9700\u8981\u767b\u5165\u3002',
    onboarding_password_will_enable: '\u5c07\u6703\u555f\u7528',
    onboarding_password_will_replace: '\u5c07\u6703\u53d6\u4ee3',
    onboarding_password_keep_existing: '\u4fdd\u7559\u76ee\u524d\u5bc6\u78bc',
    onboarding_password_remains_disabled: '\u6703\u7e7c\u7e8c\u4fdd\u6301\u95dc\u9589',
    // boot.js
    cancelling: '\u6b63\u5728\u53d6\u6d88...',
    cancel_failed: '\u53d6\u6d88\u5931\u6557\uff1a',
    mic_denied: '\u9ea6\u514b\u98a8\u8a2a\u554f\u88ab\u62d2\u7d75\uff0c\u8acb\u6aa2\u67e5\u700f\u89bd\u5668\u6b0a\u9650\u3002',
    mic_no_speech: '\u6c92\u6709\u6aa2\u6e2c\u5230\u8a71\u97f3\uff0c\u8acb\u518d\u5617\u4e00\u6b21\u3002',
    mic_network: '\u8a71\u97f3\u8b58\u5225\u76ee\u524d\u4e0d\u53ef\u7528\u3002',
    mic_error: '\u8a71\u97f3\u8f38\u5165\u51fa\u932f\uff1a',
    session_imported: '\u6703\u8a71\u5df2\u5c0e\u5165',
    import_failed: '\u5c0e\u5165\u5931\u6557\uff1a',
    import_invalid_json: 'JSON \u7121\u6548',
    image_pasted: '\u5df2\u7c98\u8cbc\u5716\u7247\uff1a',
    // messages.js
    edit_message: '\u7de8\u8f2f\u8a0a\u606f',
    regenerate: '\u91cd\u65b0\u751f\u6210\u56de\u8986',
    copy: '\u8907\u88fd',
    copied: '\u5df2\u8907\u88fd',
    // ui.js
    workspace_desc: '\u8acb\u9078\u64c7\u5de5\u4f5c\u5340\uff0c\u6216\u8f09\u5165\u65b0\u540d\u7a31\u5beb\u4e00\u500b',
    tab_profiles: '\u914d\u7f6e',
    tab_settings: '\u8a2d\u5b9a',
    profile_delete_confirm_message: '\u6b64\u914d\u7f6e\u6a94\u7684\u6240\u6709\u6703\u8a71\u3001\u8a2d\u5b9a\u3001\u6280\u80fd\u548c\u8a18\u61b6\u5c07\u88ab\u6c38\u4e45\u522a\u9664\u3002\u6b64\u64cd\u4f5c\u7121\u6cd5\u64a4\u92b7\u3002',
    workspace_renamed: '\u5de5\u4f5c\u5340\u5df2\u91cd\u65b0\u547d\u540d',
    cron_name_placeholder: '\u9078\u586b',
    active_conversation_meta: (n) => `${n} 則訊息`,
    all_uploads_failed: (n) => `${n} 個上傳失敗`,
    cron_job_name_placeholder: '\u4efb\u52d9\u540d\u7a31',
    cron_prompt_placeholder: '\u63d0\u793a\u8a5e',
    cron_schedule_placeholder: '\u6392\u7a0b',
    delete_confirm: (name) => `刪除「${name}」？`,
    downloading: (filename) => `正在下載 ${filename}…`,
    n_messages: (n) => `${n} 則訊息`,
    load_older_messages: '↑ 向上捲動或點擊以載入較早的訊息',
    session_jump_start: '開頭',
    session_jump_start_label: '跳至會話開頭',
    session_jump_end: '結尾',
    session_jump_end_label: '跳至會話結尾',
    jump_to_question: '回到問題',
    jump_to_question_label: '跳至這則回答對應的問題',
    onboarding_api_key_help_prefix: '\u900f\u904e\u4ee5\u4e0b\u65b9\u5f0f\u5132\u5b58\u70ba Hermes .env \u6a94\u6848\u4e2d\u7684\u6a5f\u5bc6',
    onboarding_api_key_label: 'API \u91d1\u9470',
    onboarding_api_key_placeholder: '\u7559\u7a7a\u4ee5\u4fdd\u7559\u5df2\u5132\u5b58\u7684\u91d1\u9470',
    onboarding_api_key_label_optional: 'API key (optional)', // TODO: translate
    onboarding_api_key_placeholder_optional: 'Leave blank for keyless servers', // TODO: translate
    onboarding_api_key_help_keyless: 'Most LM Studio / Ollama / vLLM installs run keyless — leave this blank if your server doesn\'t require authentication. Use the Test connection button to verify.', // TODO: translate
    onboarding_back: '\u4e0a\u4e00\u6b65',
    onboarding_badge: '\u9996\u6b21\u57f7\u884c',
    onboarding_base_url_help: '\u7528\u65bc OpenAI \u76f8\u5bb9\u8def\u7531\u5668\u3001\u81ea\u67b6\u4f3a\u670d\u5668\u3001LiteLLM\u3001Ollama\u3001LM Studio\u3001vLLM \u7b49\u7aef\u9ede\u3002',
    onboarding_base_url_label: '\u57fa\u790e URL',
    onboarding_base_url_placeholder: 'https://your-endpoint.example/v1',
    onboarding_check_agent: 'Hermes Agent',
    onboarding_check_agent_missing: '\u907a\u5931\u6216\u50c5\u90e8\u5206\u53ef\u7528',
    onboarding_check_agent_ready: '\u5df2\u5075\u6e2c\u5230\u4e26\u53ef\u4f9b\u532f\u5165',
    onboarding_check_password: '\u5bc6\u78bc',
    onboarding_check_password_disabled: '\u5c1a\u672a\u555f\u7528',
    onboarding_check_password_enabled: '\u5df2\u555f\u7528',
    onboarding_check_provider: '\u63d0\u4f9b\u8005\u914d\u7f6e',
    onboarding_check_provider_partial: '\u5df2\u5132\u5b58\u4f46\u672a\u5b8c\u6210',
    onboarding_check_provider_pending: '\u9700\u8981\u9a57\u8b49',
    onboarding_check_provider_ready: '\u53ef\u958b\u59cb\u804a\u5929',
    onboarding_complete: '\u521d\u59cb\u8a2d\u5b9a\u5b8c\u6210',
    onboarding_config_file: '\u8a2d\u5b9a\u6a94\uff1a',
    onboarding_continue: '\u7e7c\u7e8c',
    onboarding_current_provider: '\u76ee\u524d\u914d\u7f6e\uff1a',
    onboarding_custom_model_help: '\u5c0d\u65bc\u81ea\u8a02\u7aef\u9ede\uff0c\u8acb\u6307\u5b9a\u60a8\u7684\u4f3a\u670d\u5668\u9810\u671f\u7684\u6a21\u578b ID\u3002',
    onboarding_custom_model_placeholder: 'your_model_name',
    onboarding_env_file: '.env \u6a94\u6848\uff1a',
    onboarding_error_base_url_required: '\u81ea\u8a02\u7aef\u9ede\u9700\u8981\u57fa\u790e URL\u3002',
    onboarding_probe_test_button: 'Test connection', // TODO: translate
    onboarding_probe_probing: 'Testing connection…', // TODO: translate
    onboarding_probe_ok: 'Connected. {n} model(s) available.', // TODO: translate
    onboarding_probe_error_generic: 'Could not reach the configured base URL.', // TODO: translate
    onboarding_probe_error_invalid_url: 'Base URL must start with http:// or https://.', // TODO: translate
    onboarding_probe_error_dns: 'Could not resolve the host. Check the URL or use the host\'s IP address.', // TODO: translate
    onboarding_probe_error_connect_refused: 'Connection refused — the server may not be running on that address. From inside Docker, try the host IP instead of localhost.', // TODO: translate
    onboarding_probe_error_timeout: 'The endpoint did not respond in time. Check that the server is running and the URL is correct.', // TODO: translate
    onboarding_probe_error_http_4xx: 'The endpoint returned a client error. Check authentication and the URL path (typically ends in /v1).', // TODO: translate
    onboarding_probe_error_http_5xx: 'The endpoint returned a server error. Check the LM Studio / Ollama server logs.', // TODO: translate
    onboarding_probe_error_parse: 'The endpoint did not return a model list in the expected shape. Verify the URL points to the OpenAI-compatible API root.', // TODO: translate
    onboarding_probe_error_unreachable: 'Could not reach the configured base URL.', // TODO: translate
    onboarding_error_probe_failed: 'Could not validate the configured base URL.', // TODO: translate
    onboarding_error_choose_model: '\u8acb\u5148\u9078\u64c7\u6a21\u578b\u518d\u7e7c\u7e8c\u3002',
    onboarding_error_choose_workspace: '\u8acb\u5148\u9078\u64c7\u5de5\u4f5c\u5340\u518d\u7e7c\u7e8c\u3002',
    onboarding_error_model_required: '\u9700\u8981\u6a21\u578b\u3002',
    onboarding_error_provider_required: '\u8acb\u5148\u9078\u64c7\u8a2d\u5b9a\u6a21\u5f0f\u518d\u7e7c\u7e8c\u3002',
    onboarding_error_workspace_required: '\u9700\u8981\u5de5\u4f5c\u5340\u3002',
    onboarding_finish_help: '\u5b8c\u6210\u5f8c\uff0c<code>onboarding_completed</code> \u5c07\u5132\u5b58\u5728\u8a2d\u5b9a\u4e2d\uff0c\u60a8\u5c07\u9032\u5165\u6b63\u5e38\u61c9\u7528\u7a0b\u5f0f\u3002',
    onboarding_lead: '\u5feb\u901f\u9010\u6b65\u8a2d\u5b9a\uff1a\u6aa2\u67e5 Hermes\u3001\u5132\u5b58\u63d0\u4f9b\u8005\u914d\u7f6e\u3001\u9078\u64c7\u5de5\u4f5c\u5340\u8207\u6a21\u578b\uff0c\u4e26\u53ef\u9078\u64c7\u52a0\u5165\u5bc6\u78bc\u4fdd\u8b77\u3002',
    onboarding_missing_imports: '\u7f3a\u5c11\u7684\u532f\u5165\uff1a',
    onboarding_model_label: '\u9810\u8a2d\u6a21\u578b',
    onboarding_not_set: '\u672a\u8a2d\u5b9a',
    onboarding_notice_finish: '\u60a8\u4e4b\u5f8c\u53ef\u4ee5\u96a8\u6642\u56de\u5230\u8a2d\u5b9a\u9801\u9762\u8b8a\u66f4\u9019\u4e9b\u503c\u3002',
    onboarding_notice_password_enabled: '\u5bc6\u78bc\u5df2\u8a2d\u5b9a\u3002\u50c5\u5728\u9700\u8981\u53d6\u4ee3\u6642\u8f38\u5165\u65b0\u5bc6\u78bc\u3002',
    onboarding_notice_password_recommended: '\u9078\u586b\uff0c\u4f46\u5efa\u8b70\u5728\u975e localhost \u74b0\u5883\u4f7f\u7528\u3002',
    onboarding_notice_setup_already_ready: '\u5df2\u5075\u6e2c\u5230\u53ef\u7528\u7684 Hermes \u63d0\u4f9b\u8005\u914d\u7f6e\u3002\u60a8\u53ef\u4ee5\u4fdd\u7559\u6216\u5728\u6b64\u53d6\u4ee3\u3002',
    onboarding_notice_setup_required: '\u5728\u6b64\u9078\u64c7\u5feb\u901f\u63d0\u4f9b\u8005\u8a2d\u5b9a\u8def\u5f91\u3002\u9032\u968e OAuth \u8a2d\u5b9a\u4ecd\u8acb\u4f7f\u7528 Hermes CLI\u3002',
    onboarding_notice_system_ready: 'Hermes Agent \u53ef\u5f9e Web UI \u5b58\u53d6\u3002',
    onboarding_notice_system_unavailable: 'Hermes Agent \u5c1a\u672a\u5b8c\u5168\u53ef\u7528\u3002\u5f15\u5c0e\u7a0b\u5f0f\u53ef\u80fd\u5b89\u88dd\u5b83\uff0c\u4f46\u63d0\u4f9b\u8005\u8a2d\u5b9a\u53ef\u80fd\u4ecd\u9700\u7d42\u7aef\u6a5f\u3002',
    onboarding_notice_workspace: '\u9019\u4e9b\u503c\u4f7f\u7528\u8207\u4e00\u822c\u61c9\u7528\u7a0b\u5f0f\u76f8\u540c\u7684\u8a2d\u5b9a API\u3002',
    onboarding_oauth_provider_not_ready_body: '\u6b64\u5be6\u4f8b\u8a2d\u5b9a\u4f7f\u7528 <strong>{provider}</strong>\uff0c\u5b83\u4f7f\u7528 OAuth \u800c\u975e API \u91d1\u9470\u3002\u8acb\u5728\u7d42\u7aef\u6a5f\u4e2d\u57f7\u884c <code>hermes auth</code> \u6216 <code>hermes model</code> \u9032\u884c\u6388\u6b0a\uff0c\u7136\u5f8c\u91cd\u65b0\u6574\u7406 Web UI\u3002',
    onboarding_oauth_provider_not_ready_title: 'OAuth \u63d0\u4f9b\u8005\u5c1a\u672a\u6388\u6b0a',
    onboarding_oauth_provider_ready_body: '\u6b64\u5be6\u4f8b\u8a2d\u5b9a\u4f7f\u7528\u900f\u904e Hermes CLI \u914d\u7f6e\u7684 OAuth \u63d0\u4f9b\u8005\uff08<strong>{provider}</strong>\uff09\u3002\u7121\u9700 API \u91d1\u9470 \u2014 \u6309\u7e7c\u7e8c\u5b8c\u6210\u8a2d\u5b9a\u3002',
    onboarding_oauth_provider_ready_title: '\u63d0\u4f9b\u8005\u5df2\u6388\u6b0a',
    onboarding_oauth_switch_hint: '\u6216\u9078\u64c7\u4e0b\u65b9\u5176\u4ed6\u63d0\u4f9b\u8005\u4ee5\u5207\u63db\u5230 API \u91d1\u9470\u8a2d\u5b9a\uff1a',
    onboarding_open: '\u958b\u555f Hermes',
    onboarding_password_help: '\u5bc6\u78bc\u900f\u904e\u73fe\u6709\u8a2d\u5b9a API \u5132\u5b58\uff0c\u4e26\u5728\u4f3a\u670d\u5668\u7aef\u9032\u884c\u96dc\u6e4a\u8655\u7406\u3002',
    onboarding_password_label: '\u5bc6\u78bc\uff08\u9078\u586b\uff09',
    onboarding_password_placeholder: '\u7559\u7a7a\u4ee5\u8df3\u904e',
    onboarding_password_remains_disabled: '\u5c07\u4fdd\u6301\u505c\u7528',
    onboarding_password_skipped: '\u66ab\u6642\u8df3\u904e',
    onboarding_password_will_enable: '\u5c07\u555f\u7528',
    onboarding_password_will_replace: '\u5c07\u53d6\u4ee3',
    onboarding_provider_label: '\u8a2d\u5b9a\u6a21\u5f0f',
    onboarding_quick_setup_badge: '\u5feb\u901f\u8a2d\u5b9a',
    oauth_login_codex: 'Login with Codex (ChatGPT)', // TODO: translate
    oauth_codex_step1: 'Step 1: Visit this URL and enter the code', // TODO: translate
    oauth_codex_step2: 'Step 2: Enter this code on the page', // TODO: translate
    oauth_codex_polling: 'Waiting for authorization...', // TODO: translate
    oauth_codex_success: 'Codex OAuth login successful!', // TODO: translate
    oauth_codex_error: 'OAuth login failed', // TODO: translate
    oauth_codex_expired: 'Code expired, please try again', // TODO: translate
    provider_category_easy_start: '\u5feb\u901f\u958b\u59cb',
    provider_category_self_hosted: '\u672c\u5730 / \u958b\u6e90',
    provider_category_specialized: '\u5c08\u696d\u670d\u52d9',
    onboarding_skip: '\u8df3\u904e\u8a2d\u5b9a',
    onboarding_skipped: '\u5df2\u8df3\u904e\u8a2d\u5b9a \u2014 \u4f7f\u7528\u73fe\u6709\u914d\u7f6e\u3002',
    onboarding_step_finish_desc: '\u6aa2\u8996\u8a2d\u5b9a\u4e26\u9032\u5165\u61c9\u7528\u7a0b\u5f0f\u3002',
    onboarding_step_finish_title: '\u5b8c\u6210',
    onboarding_step_password_desc: '\u5206\u4eab\u524d\u4fdd\u8b77 Web UI\u3002',
    onboarding_step_password_title: '\u9078\u586b\u5bc6\u78bc',
    onboarding_step_setup_desc: '\u5132\u5b58\u6700\u5c0f\u53ef\u7528\u7684 Hermes \u63d0\u4f9b\u8005\u914d\u7f6e\u3002',
    onboarding_step_setup_title: '\u63d0\u4f9b\u8005\u8a2d\u5b9a',
    onboarding_step_system_desc: '\u9a57\u8b49 Hermes Agent \u8207\u914d\u7f6e\u53ef\u898b\u6027\u3002',
    onboarding_step_system_title: '\u7cfb\u7d71\u6aa2\u67e5',
    onboarding_step_workspace_desc: '\u70ba\u65b0\u6703\u8a71\u9078\u64c7\u9810\u8a2d\u503c\u3002',
    onboarding_step_workspace_title: '\u5de5\u4f5c\u5340\u8207\u6a21\u578b',
    onboarding_title: '\u6b61\u8fce\u4f7f\u7528 Hermes Web UI',
    onboarding_unknown: '\u672a\u77e5',
    onboarding_workspace_help: '\u9078\u64c7 Hermes \u5728\u8a2d\u5b9a\u5b8c\u6210\u5f8c\u7528\u65bc\u65b0\u804a\u5929\u5ba4\u7684\u6a21\u578b\u3002',
    onboarding_workspace_label: '\u5de5\u4f5c\u5340',
    onboarding_workspace_or_path: '\u6216\u8f38\u5165\u5de5\u4f5c\u5340\u8def\u5f91',
    onboarding_workspace_placeholder: '/home/you/workspace',
    project_name_prompt: '\u5c08\u6848\u540d\u7a31\uff1a',
    provider_mismatch_warning: (provider) => `提供者不符：會話使用 ${provider}`,
    session_meta_messages: (n) => `${n} 則訊息`,
    session_meta_children: (n) => `${n} 則子`,
    session_meta_segments: (n) => `${n} 段`,
    session_lineage_segment_untitled: '未命名段',
    session_lineage_segment_open: '開啟脈絡段',
    skill_created: '\u6280\u80fd\u5df2\u5efa\u7acb',
    skill_file_load_failed: '\u8f09\u5165\u6a94\u6848\u5931\u6557\uff1a',
    skill_load_failed: '\u8f09\u5165\u6280\u80fd\u5931\u6557\uff1a',
    skill_name_required: '\u9700\u8981\u6280\u80fd\u540d\u7a31',
    skill_updated: '\u6280\u80fd\u5df2\u66f4\u65b0',
    skills_no_match: '\u627e\u4e0d\u5230\u7b26\u5408\u7684\u6280\u80fd\u3002',
    slash_skill_badge: '\u6280\u80fd',
    slash_skill_desc: '\u547c\u53eb\u6b64\u6280\u80fd',
    title_change_hint: '\u4f7f\u7528 /title <\u65b0\u540d\u7a31> \u91cd\u65b0\u547d\u540d\u3002',
    title_current: '\u76ee\u524d\u6a19\u984c',
    title_set: '\u6a19\u984c\u5df2\u8a2d\u70ba',
    todos_no_active: '\u6b64\u6703\u8a71\u4e2d\u7121\u6d3b\u8e8d\u4efb\u52d9\u6e05\u55ae\u3002',
    upload_failed: '\u4e0a\u50b3\u5931\u6557\uff1a',
    upload_too_large: (maxMb, fileMb) => `\u6a94\u6848\u904e\u5927\uff08${fileMb} MB\uff09\u3002\u6700\u5927\u4e0a\u50b3\u5927\u5c0f\u70ba ${maxMb} MB\u3002`,
    active_conversation_none: '\u672a\u9078\u53d6\u6d3b\u8e8d\u6703\u8a71\u3002',
    add: '\u65b0\u589e',
    add_failed: '\u65b0\u589e\u5931\u6557\uff1a',
    auth_disabled: '\u9a57\u8b49\u5df2\u505c\u7528 \u2014 \u5bc6\u78bc\u4fdd\u8b77\u5df2\u95dc\u9589',
    cancel_unavailable: '\u7121\u6cd5\u53d6\u6d88\u3002',
    clear_conversation_message: '\u6e05\u9664\u6240\u6709\u8a0a\u606f\uff1f\u6b64\u64cd\u4f5c\u7121\u6cd5\u5fa9\u539f\u3002',
    clear_conversation_title: '\u6e05\u9664\u5c0d\u8a71',
    clear_failed: '\u6e05\u9664\u5931\u6557\uff1a',
    content_required: '\u9700\u8981\u5167\u5bb9',
    create_failed: '\u5efa\u7acb\u5931\u6557\uff1a',
    delete_failed: '\u522a\u9664\u5931\u6557\uff1a',
    disable: '\u505c\u7528',
    disable_auth: '\u505c\u7528\u9a57\u8b49',
    disable_auth_confirm_message: '\u4efb\u4f55\u4eba\u90fd\u53ef\u4ee5\u5b58\u53d6\u6b64\u5be6\u4f8b\u3002',
    disable_auth_confirm_title: '\u505c\u7528\u5bc6\u78bc\u4fdd\u8b77',
    disable_auth_failed: '\u505c\u7528\u9a57\u8b49\u5931\u6557\uff1a',
    discard_file_edits_message: '\u5207\u63db\u5de5\u4f5c\u5340\u5c07\u653e\u68c4\u672a\u5132\u5b58\u7684\u9810\u89bd\u8b8a\u66f4\u3002',
    discard_file_edits_title: '\u653e\u68c4\u6a94\u6848\u7de8\u8f2f\uff1f',
    dismiss: '\u95dc\u9589',
    edit: '\u7de8\u8f2f',
    error_prefix: '\u932f\u8aa4\uff1a',
    linked_files: '\u95dc\u806f\u6a94\u6848',
    manage_profiles: '\u7ba1\u7406\u8a2d\u5b9a\u6a94',
    memory_notes_label: '\u8a18\u61b6\uff08\u5099\u8a3b\uff09',
    model_custom_label: '\u81ea\u8a02\u6a21\u578b ID',
    model_custom_placeholder: '\u4f8b\u5982 openai/gpt-5.4',
    model_search_no_results: '\u627e\u4e0d\u5230\u6a21\u578b',
    model_group_configured: '已設定',
    ws_search_placeholder: '搜尋工作區…',
    ws_no_results: '找不到工作區',
    model_search_placeholder: '\u641c\u5c0b\u6a21\u578b\u2026',
    session_toolsets: 'Session Toolsets', // TODO: translate
    session_toolsets_desc: 'Restrict available tools for this session (blank = use global config)', // TODO: translate
    session_toolsets_global: 'Global (default)', // TODO: translate
    session_toolsets_custom: 'Custom', // TODO: translate
    session_toolsets_placeholder: 'tool1, tool2, \u2026', // TODO: translate
    session_toolsets_apply: 'Apply', // TODO: translate
    session_toolsets_clear: 'Clear (use global)', // TODO: translate
    session_toolsets_applied: 'Toolsets updated', // TODO: translate
    session_toolsets_cleared: 'Toolsets cleared — using global config', // TODO: translate
    session_toolsets_failed: 'Failed to update toolsets: ', // TODO: translate
    model_scope_advisory: '\u5f9e\u4e0b\u4e00\u5247\u8a0a\u606f\u8d77\u9069\u7528\u65bc\u6b64\u6703\u8a71\u3002',
    model_scope_toast: '\u5f9e\u4e0b\u4e00\u5247\u8a0a\u606f\u8d77\u9069\u7528\u65bc\u6b64\u6703\u8a71\u3002',
    my_notes: '\u6211\u7684\u5099\u8a3b',
    name_required: '\u9700\u8981\u540d\u7a31',
    never: '\u5f9e\u4e0d',
    no_active_session: '\u7121\u6d3b\u8e8d\u6703\u8a71',
    cmd_queue: '\u5c07\u8a0a\u606f\u52a0\u5165\u4e0b\u4e00\u8f2a\u7684\u4f47\u5217',
    cmd_goal: '設定或查看持久目標',
    goal_evaluating_progress: 'Evaluating goal progress…',
    goal_working_toward: 'Working toward goal…',
    goal_continuing_toast: 'Continuing toward goal…',
    goal_status_none: 'No active goal. Set one with /goal <text>.',
    goal_status_active: (turns, max_turns, goal) => `⊙ Goal (active, ${turns}/${max_turns} turns): ${goal}`,
    goal_status_paused: (turns, max_turns, reason, goal) => `⏸ Goal (paused, ${turns}/${max_turns}${reason ? `, ${reason}` : ''}): ${goal}`,
    goal_status_done: (turns, max_turns, goal) => `✓ Goal done (${turns}/${max_turns}): ${goal}`,
    goal_set: (turns, goal) => `⊙ Goal set (${turns}-turn budget): ${goal}`,
    goal_paused: (goal) => `⏸ Goal paused: ${goal}`,
    goal_resumed: (goal) => `▶ Goal resumed: ${goal}`,
    goal_cleared: 'Goal cleared.',
    goal_no_goal: 'No active goal.',
    goal_achieved: (reason) => `✓ Goal achieved: ${reason}`,
    goal_paused_budget_exhausted: (turns, max_turns) => `⏸ Goal paused — ${turns}/${max_turns} turns used. Use /goal resume to keep going, or /goal clear to stop.`,
    goal_continuing: (turns, max_turns, reason) => `↻ Continuing toward goal (${turns}/${max_turns}): ${reason}`,
    cmd_interrupt: '\u53d6\u6d88\u7576\u524d\u56de\u5408\u4e26\u767c\u9001\u65b0\u8a0a\u606f',
    cmd_steer: '\u5728\u56de\u5408\u9032\u884c\u4e2d\u6ce8\u5165\u7d3a\u6b63\uff0c\u4e0d\u4e2d\u65b7\u4ee3\u7406',
    cmd_queue_no_msg: '\u7528\u6cd5\uff1a/queue <\u8a0a\u606f>',
    cmd_queue_not_busy: '\u6c92\u6709\u6d3b\u52d5\u4efb\u52d9 \u2014 \u76f4\u63a5\u767c\u9001\u5373\u53ef',
    cmd_queue_confirm: '\u8a0a\u606f\u5df2\u52a0\u5165\u4f47\u5217',
    cmd_interrupt_no_msg: '\u7528\u6cd5\uff1a/interrupt <\u8a0a\u606f>',
    cmd_interrupt_confirm: '\u5df2\u4e2d\u65ad \u2014 \u6b63\u5728\u767c\u9001\u65b0\u8a0a\u606f',
    cmd_steer_no_msg: '\u7528\u6cd5\uff1a/steer <\u8a0a\u606f>',
    cmd_steer_fallback: 'Steer \u4e0d\u53ef\u7528 \u2014 \u5df2\u52a0\u5165\u4e0b\u4e00\u8f2a\u4f47\u5217',
    cmd_steer_delivered: 'Steer \u5df2\u9001\u9054 \u2014 \u4ee3\u7406\u5c07\u5728\u4e0b\u4e00\u500b\u5de5\u5177\u7d50\u679c\u4e2d\u770b\u5230',
    steer_leftover_queued: 'Steer \u5df2\u52a0\u5165\u4e0b\u4e00\u8f2a\u4f47\u5217',
    busy_steer_fallback: 'Steer \u4e0d\u53ef\u7528 \u2014 \u5df2\u52a0\u5165\u4e0b\u4e00\u8f2a\u4f47\u5217',
    busy_interrupt_confirm: '\u5df2\u4e2d\u65ad \u2014 \u6b63\u5728\u767c\u9001\u65b0\u8a0a\u606f',
    settings_label_busy_input_mode: '\u5fd9\u788c\u8f38\u5165\u6a21\u5f0f',
    settings_desc_busy_input_mode: '\u63a7\u5236\u5728\u4ee3\u7406\u904b\u884c\u6642\u767c\u9001\u8a0a\u606f\u7684\u884c\u70ba\u3002\u4f47\u5217\u7b49\u5f85\uff1b\u4e2d\u65b7\u53d6\u6d88\u4e26\u91cd\u65b0\u958b\u59cb\uff1bSteer\u4e2d\u9014\u6ce8\u5165\u7d3a\u6b63\uff0c\u4e0d\u4e2d\u65b7\u3002',
    settings_label_fade_text_effect: '文字淡入效果',
    settings_desc_fade_text_effect: '在助理回覆時讓新串流輸出的詞語淡入顯示。類似 OpenWebUI；為獲得最佳效能預設關閉。',
    settings_busy_input_mode_queue: '\u52a0\u5165\u4f47\u5217',
    settings_busy_input_mode_interrupt: '\u4e2d\u65ad\u7576\u524d\u56de\u5408',
    settings_busy_input_mode_steer: 'Steer\uff08\u4e2d\u9014\u7d3a\u6b63\uff09',
    no_active_task: '\u7121\u57f7\u884c\u4e2d\u7684\u4efb\u52d9\u53ef\u505c\u6b62\u3002',
    no_notes_yet: '\u5c1a\u7121\u5099\u8a3b\u3002',
    no_profile_yet: '\u5c1a\u7121\u8a2d\u5b9a\u6a94\u3002',
    agent_soul: '智能體靈魂',
    no_soul_yet: '尚無靈魂定義。',
    not_available: '\u7121',
    profile_active: '\u555f\u7528\u4e2d',
    profile_api_key_placeholder: 'API \u91d1\u9470\uff08\u9078\u586b\uff09',
    profile_api_keys_configured: 'API \u91d1\u9470\u5df2\u8a2d\u5b9a',
    profile_base_url_placeholder: '\u57fa\u672c URL\uff08\u9078\u586b\uff0c\u4f8b\u5982 http://localhost:11434\uff09',
    profile_base_url_rule: '\u57fa\u672c URL \u5fc5\u9808\u4ee5 http:// \u6216 https:// \u958b\u982d',
    profile_clone_label: '\u5f9e\u555f\u7528\u4e2d\u7684\u8a2d\u5b9a\u6a94\u8907\u88fd\u914d\u7f6e',
    profile_model_label: '\u6a21\u578b / \u63d0\u4f9b\u5546',
    profile_model_hint: '\u70ba\u9019\u500b\u65b0\u8a2d\u5b9a\u6a94\u9078\u64c7\u5df2\u8a2d\u5b9a\u7684\u63d0\u4f9b\u5546\u548c\u6a21\u578b\u3002',
    profile_model_use_default: '\u4f7f\u7528\u555f\u7528\u4e2d\u8a2d\u5b9a\u6a94\u7684\u9810\u8a2d\u503c',
    profile_created: (name) => `設定檔 ${name} 已建立`,
    profile_default_label: '\uff08\u9810\u8a2d\uff09',
    profile_delete_confirm_title: (name) => `刪除設定檔「${name}」？`,
    profile_deleted: (name) => `設定檔 ${name} 已刪除`,
    profile_gateway_running: 'Gateway \u57f7\u884c\u4e2d',
    profile_gateway_stopped: 'Gateway \u5df2\u505c\u6b62',
    profile_name_placeholder: '\u8a2d\u5b9a\u6a94\u540d\u7a31\uff08\u5c0f\u5beb\u5b57\u6bcd\u3001\u6578\u5b57\u3001\u9023\u5b57\u865f\uff09',
    profile_name_rule: '\u50c5\u9650\u5c0f\u5beb\u5b57\u6bcd\u3001\u6578\u5b57\u3001\u9023\u5b57\u865f\u548c\u5e95\u7dda',
    profile_no_configuration: '\u7121\u914d\u7f6e',
    profile_skill_count: (n) => `${n} 個技能`,
    profile_switch_title: '\u5207\u63db\u5230\u6b64\u8a2d\u5b9a\u6a94',
    profile_switched: (name) => `已切換到 ${name}`,
    profile_switched_new_conversation: (name) => `已切換到 ${name}（新會話）`,
    profile_use: '\u4f7f\u7528',
    profiles_load_failed: '\u8f09\u5165\u8a2d\u5b9a\u6a94\u5931\u6557',
    profiles_no_profiles: '\u627e\u4e0d\u5230\u8a2d\u5b9a\u6a94\u3002',
    remove: '\u79fb\u9664',
    remove_failed: '\u79fb\u9664\u5931\u6557\uff1a',
    rename_failed: '\u91cd\u65b0\u547d\u540d\u5931\u6557\uff1a',
    retry_failed: '\u91cd\u8a66\u5931\u6557\uff1a',
    save: '\u5132\u5b58',
    save_failed: '\u5132\u5b58\u5931\u6557\uff1a',
    session_time_bucket_last_week: '\u4e0a\u9031',
    session_time_bucket_older: '\u66f4\u65e9',
    session_time_bucket_this_week: '\u672c\u9031',
    session_time_bucket_today: '\u4eca\u5929',
    session_time_bucket_yesterday: '\u6628\u5929',
    session_time_days_ago: (d) => `${d}\u5929`,
    session_time_hours_ago: (h) => `${h}\u5c0f\u6642`,
    session_time_last_week: '1\u9031',
    session_time_minutes_ago: (m) => `${m}\u5206`,
    session_time_unknown: '\u672a\u77e5',
    settings_unsaved_changes: '\u60a8\u6709\u672a\u5132\u5b58\u7684\u8b8a\u66f4\u3002',
    sign_out_failed: '\u767b\u51fa\u5931\u6557\uff1a',
    stream_stopped: '\u56de\u61c9\u5df2\u505c\u6b62\u3002',
    switch_failed: '\u5207\u63db\u5931\u6557\uff1a',
    undid_messages_suffix: '\u5247\u8a0a\u606f\u3002',
    undid_n_messages: '\u5df2\u79fb\u9664',
    undo_exchange: '\u5fa9\u539f\u6700\u5f8c\u4e00\u8f2a',
    undo_failed: '\u5fa9\u539f\u5931\u6557\uff1a',
    user_profile: '\u4f7f\u7528\u8005\u8a2d\u5b9a\u6a94',
    view: '\u6aa2\u8996',
    workspace_add_path_placeholder: '\u65b0\u589e\u5de5\u4f5c\u5340\u8def\u5f91\uff08\u4f8b\u5982 /Users/you/project\uff09',
    workspace_added: '\u5de5\u4f5c\u5340\u5df2\u65b0\u589e',
    workspace_already_saved: '\u5de5\u4f5c\u5340\u5df2\u5132\u5b58 \u2014 \u5f9e\u6e05\u55ae\u4e2d\u9078\u53d6',
    workspace_busy_switch: 'Agent \u57f7\u884c\u4e2d\u7121\u6cd5\u5207\u63db\u5de5\u4f5c\u5340',
    workspace_choose_path: '\u9078\u64c7\u5de5\u4f5c\u5340\u8def\u5f91',
    workspace_choose_path_meta: '\u65b0\u589e\u9a57\u8b49\u904e\u7684\u8def\u5f91\u4e26\u5207\u63db\u6b64\u6703\u8a71',
    workspace_manage: '\u7ba1\u7406\u5de5\u4f5c\u5340',
    workspace_manage_meta: '\u958b\u555f Spaces \u9762\u677f',
    workspace_not_added: '\u5de5\u4f5c\u5340\u672a\u65b0\u589e',
    workspace_paths_validated_hint: '\u8def\u5f91\u6703\u5148\u9a57\u8b49\u662f\u5426\u5b58\u5728\u518d\u5132\u5b58\u3002',

    workspace_drag_hint: '拖曳以重新排列',
    workspace_reorder_failed: '重新排列失敗',
    workspace_remove_confirm_message: (name) => `移除工作區「${name}」？`,
    workspace_remove_confirm_title: '\u79fb\u9664\u5de5\u4f5c\u5340',
    workspace_removed: '\u5de5\u4f5c\u5340\u5df2\u79fb\u9664',
    workspace_switch_prompt_confirm: '\u5207\u63db',
    workspace_switch_prompt_message: '\u8f38\u5165\u5de5\u4f5c\u5340\u7684\u7d55\u5c0d\u8def\u5f91\u4ee5\u65b0\u589e\u4e26\u5207\u63db\u6b64\u6703\u8a71\u3002',
    workspace_switch_prompt_placeholder: '/Users/you/project',
    workspace_switch_prompt_title: '\u5207\u63db\u5de5\u4f5c\u5340',
    workspace_switched_to: (name) => `已切換到 ${name}`,
    workspace_use: '\u4f7f\u7528',
    workspace_use_title: '\u5728\u7576\u524d\u6703\u8a71\u4e2d\u4f7f\u7528',
    bg_complete: '\u80cc\u666f\u4efb\u52d9\u5b8c\u6210',
    bg_error_multi: (n) => `${n} 個背景任務失敗`,
    cmd_status: '顯示會話資訊',
    memory_saved: '記憶已儲存',
    profile_delete_title: '刪除此設定檔',
    bg_error_single: (n) => `${n} 個背景任務失敗`,
    bg_failed: '\u80cc\u666f\u4efb\u52d9\u5931\u6557\uff1a',
    bg_label: '\u80cc\u666f\u7d50\u679c\uff1a',
    bg_no_answer: '\uff08\u7121\u56de\u61c9\uff09',
    bg_running: '\u80cc\u666f\u57f7\u884c\u4e2d\u2026',
    btw_asking: '\u6b63\u5728\u8a62\u554f\u9644\u5e36\u554f\u984c\u2026',
    btw_done: '\u9644\u5e36\u554f\u984c\u5df2\u56de\u7b54',
    btw_failed: '\u9644\u5e36\u554f\u984c\u5931\u6557\uff1a',
    btw_label: '\u9644\u5e36\u554f\u984c \u2014 \u4e0d\u5728\u6b77\u53f2\u8a18\u9304\u4e2d',
    btw_no_answer: '\u672a\u6536\u5230\u56de\u61c9\u3002',
    cmd_background: '\u5728\u80cc\u666f\u57f7\u884c\u63d0\u793a\u8a5e',
    cmd_background_usage: '/background <\u63d0\u793a\u8a5e> \u2014 \u5e73\u884c\u57f7\u884c\u4e0d\u963b\u585e',
    cmd_btw: '\u63d0\u51fa\u9644\u5e36\u554f\u984c\uff08\u66ab\u6642\u6027\uff09',
    cmd_btw_usage: '/btw <\u554f\u984c> \u2014 \u4f7f\u7528\u7576\u524d\u6703\u8a71\u80cc\u666f\u63d0\u554f',
    cmd_compact: '\u58d3\u7e2e\u5c0d\u8a71\u4e0a\u4e0b\u6587',
    cmd_retry: '\u91cd\u65b0\u767c\u9001\u6700\u5f8c\u4e00\u689d\u8a0a\u606f',
    cmd_stop: '\u505c\u6b62\u7576\u524d\u56de\u61c9',
    cmd_title: '\u53d6\u5f97\u6216\u8a2d\u5b9a\u6703\u8a71\u6a19\u984c',
    cmd_undo: '\u79fb\u9664\u6700\u5f8c\u4e00\u8f2a\u5c0d\u8a71',
    cmd_voice: '\u5207\u63db\u9ea5\u514b\u98a8\u8f38\u5165',
    cmd_voice_use_mic: '\u9ede\u64ca\u7de8\u8f2f\u5668\u4e2d\u7684\u9ea5\u514b\u98a8\u6309\u9215\u3002',
    cmd_webui_only_session: '\u6b64\u6307\u4ee4\u4e0d\u9069\u7528\u65bc CLI \u532f\u5165\u7684\u6703\u8a71\u3002',
    cron_all_runs: '\u6240\u6709\u57f7\u884c',
    cron_completion_status: (n) => `${n} 次完成`,
    cron_delete_confirm_message: '\u6b64\u64cd\u4f5c\u7121\u6cd5\u5fa9\u539f\u3002',
    cron_delete_confirm_title: '\u522a\u9664\u6392\u7a0b\u4efb\u52d9',
    cron_hide_runs: '\u96b1\u85cf\u57f7\u884c\u8a18\u9304',
    cron_job_created: '\u6392\u7a0b\u4efb\u52d9\u5df2\u5efa\u7acb',
    cron_duplicate: '\u8907\u88fd',
    cron_duplicated: '\u4efb\u52d9\u5df2\u8907\u88fd\uff08\u5df2\u66ab\u505c\uff09',
    cron_job_deleted: '\u6392\u7a0b\u4efb\u52d9\u5df2\u522a\u9664',
    cron_job_name_placeholder: '\u4efb\u52d9\u540d\u7a31',
    cron_job_paused: '\u6392\u7a0b\u4efb\u52d9\u5df2\u66ab\u505c',
    cron_job_resumed: '\u6392\u7a0b\u4efb\u52d9\u5df2\u6062\u5fa9',
    cron_job_triggered: '\u6392\u7a0b\u4efb\u52d9\u5df2\u89f8\u767c',
    cron_job_updated: '\u6392\u7a0b\u4efb\u52d9\u5df2\u66f4\u65b0',
    cron_last: '\u4e0a\u6b21',
    cron_last_output: '\u6700\u5f8c\u8f38\u51fa',
    cron_expand_prompt: '展開提示詞',
    cron_collapse_prompt: '收起提示詞',
    cron_expand_output: '展開輸出',
    cron_collapse_output: '收起輸出',
    cron_next: '\u4e0b\u6b21',
    cron_no_jobs: '\u627e\u4e0d\u5230\u6392\u7a0b\u4efb\u52d9\u3002',
    cron_no_runs_yet: '\uff08\u5c1a\u7121\u57f7\u884c\u8a18\u9304\uff09',
    cron_pause: '\u66ab\u505c',
    cron_prompt_placeholder: '\u63d0\u793a\u8a5e',
    cron_prompt_required: '\u9700\u8981\u63d0\u793a\u8a5e',
    cron_resume: '\u6062\u5fa9',
    cron_run_now: '\u7acb\u5373\u57f7\u884c',
    cron_schedule_placeholder: '\u6392\u7a0b',
    cron_schedule_required: '\u9700\u8981\u6392\u7a0b',
    cron_schedule_required_example: '\u9700\u8981\u6392\u7a0b\uff08\u4f8b\u5982 "0 9 * * *" \u6216 "every 1h"\uff09',
    cron_status_active: '已啟用',
    cron_status_running: '\u57f7\u884c\u4e2d\u2026',
    cron_status_error: '\u932f\u8aa4',
    cron_status_off: '\u672a\u555f\u7528',
    cron_status_paused: '\u5df2\u66ab\u505c',
    cron_status_needs_attention: '\u9700\u8981\u8655\u7406',
    cron_attention_desc: '\u9019\u500b\u91cd\u8907\u6392\u7a0b\u4efb\u52d9\u6c92\u6709\u4e0b\u6b21\u57f7\u884c\u6642\u9593\u3002\u6392\u7a0b\u5668\u53ef\u80fd\u7121\u6cd5\u8a08\u7b97\u4e0b\u4e00\u6b21\u57f7\u884c\u3002',
    cron_attention_croniter_hint: 'Gateway \u57f7\u884c\u74b0\u5883\u53ef\u80fd\u7f3a\u5c11 croniter \u5957\u4ef6\u3002\u8acb\u7528\u652f\u63f4 cron \u7684\u74b0\u5883\u91cd\u555f Gateway\uff0c\u7136\u5f8c\u6062\u5fa9\u9019\u500b\u4efb\u52d9\u3002',
    cron_attention_resume: '\u6062\u5fa9\u4e26\u91cd\u65b0\u8a08\u7b97',
    cron_jobs_project: '\u5b9a\u6642\u4efb\u52d9',
    cron_attention_run_once: '\u7acb\u5373\u57f7\u884c\u4e00\u6b21',
    cron_attention_copy_diagnostics: '\u8907\u88fd\u8a3a\u65b7\u8cc7\u8a0a',
    cron_diagnostics_copied: '\u6392\u7a0b\u4efb\u52d9\u8a3a\u65b7\u8cc7\u8a0a\u5df2\u8907\u88fd',
    providers_empty: '\u627e\u4e0d\u5230\u53ef\u8a2d\u5b9a\u7684\u63d0\u4f9b\u8005\u3002',
    providers_enter_key: '\u8acb\u8f38\u5165 API \u91d1\u9470',
    providers_key_placeholder_new: 'sk-...',
    providers_key_placeholder_replace: '\u8f38\u5165\u65b0\u91d1\u9470\u4ee5\u53d6\u4ee3\u2026',
    providers_key_removed: 'API \u91d1\u9470\u5df2\u79fb\u9664',
    providers_key_updated: 'API \u91d1\u9470\u5df2\u5132\u5b58',
    provider_quota_title: '目前提供者配額',
    provider_quota_active_provider: '目前提供者',
    provider_quota_last_checked_after_refresh: '重新整理後檢查',
    provider_quota_last_checked: '上次檢查 {0}',
    provider_quota_refresh_usage: '重新整理用量',
    provider_quota_refreshing: '正在重新整理...',
    provider_quota_refresh_title: '立即重新整理提供者用量限制',
    provider_quota_refresh_succeeded: '提供者用量已重新整理',
    provider_quota_refresh_failed: '提供者用量重新整理失敗',
    provider_quota_session_limit: '5 小時限制',
    provider_quota_weekly_limit: '每週限制',
    provider_quota_window_fallback: '視窗',
    provider_quota_metric_remaining: '剩餘',
    provider_quota_metric_used: '已用',
    provider_quota_metric_limit: '限制',
    provider_quota_status_available: '可用',
    provider_quota_status_exhausted: '已耗盡',
    provider_quota_status_unavailable: '不可用',
    provider_quota_status_failed: '失敗',
    provider_quota_status_checked: '已檢查',
    provider_quota_status_no_key: '無金鑰',
    provider_quota_status_invalid_key: '金鑰無效',
    provider_quota_status_unsupported: '不支援',
    provider_quota_used_meta: '已用 {0}',
    provider_quota_resets_meta: '重設於 {0}',
    provider_quota_credential_pool: '憑證池',
    provider_quota_credential_label: '憑證 {0}',
    provider_quota_pool_plans: '方案：{0}',
    provider_quota_pool_no_windows: '未回報帳戶限制視窗。',
    provider_quota_account_limits_loaded: '帳戶限制已載入。',
    provider_quota_unavailable: '配額狀態不可用',
    provider_quota_retry_after: '重試時間 {0}',
    provider_quota_pool_summary_available: '{0}/{1} 可用',
    provider_quota_pool_summary_exhausted: '{0} 個已耗盡',
    provider_quota_pool_summary_failed: '{0} 個失敗',
    provider_quota_pool_summary_checked: '已檢查 {0} 個',
    providers_oauth_hint: '\u5df2\u900f\u904e OAuth \u9a57\u8b49\u3002\u7121\u9700 API \u91d1\u9470\u3002',
    providers_oauth_config_yaml_hint: '\u5df2\u900f\u904e config.yaml \u8a2d\u5b9a\u6b0a\u8b49\u3002\u8981\u66f4\u65b0\uff0c\u8acb\u7de8\u8f2f config.yaml \u4e2d\u7684 providers \u5340\u6bb5\uff0c\u6216\u57f7\u884c hermes auth\u3002',
    providers_oauth_not_configured_hint: '\u5c1a\u672a\u9a57\u8b49\u3002\u8acb\u5728\u7d42\u7aef\u6a5f\u57f7\u884c hermes auth \u4ee5\u8a2d\u5b9a\u6b64\u63d0\u4f9b\u8005\u3002',
    providers_remove: '\u79fb\u9664',
    providers_removing: '\u79fb\u9664\u4e2d\u2026',
    providers_save: '\u5132\u5b58',
    providers_saving: '\u5132\u5b58\u4e2d\u2026',
    providers_section_meta: '管理 AI 提供者的 API 金鑰。變更會立即生效。',
    providers_section_title: '供應商',
    providers_status_api_key: 'API 金鑰',
    providers_status_configured: 'API \u91d1\u9470\u5df2\u8a2d\u5b9a',
    providers_status_not_configured: '\u7121 API \u91d1\u9470',
    providers_status_not_configured_label: '\u672a\u8a2d\u5b9a',
    providers_status_oauth: 'OAuth',
    providers_tab_title: '供應商',
    status_agent_running: 'Agent 執行中',
    status_profile: '個人資料',
    status_hermes_home: 'Hermes 主目錄',
    status_started: '開始時間',
    status_tokens: 'Token',
    status_updated: '已更新',
    status_ephemeral: '临时快照 — 不会保存到对话历史。',
    status_no_tokens: '未使用 Token',
    status_unknown: '未知',
    status_completed: '\u5df2\u5b8c\u6210',
    status_failed: '\u5931\u6557',
    status_heading: '\u6703\u8a71\u72c0\u614b',
    status_load_failed: '\u8f09\u5165\u72c0\u614b\u5931\u6557\uff1a',
    status_messages: '\u8a0a\u606f\u6578',
    status_model: '\u6a21\u578b',
    status_provider: '供应商',
    status_no: '\u5426',
    status_personality: '\u4eba\u8a2d',
    status_session_id: '\u6703\u8a71 ID',
    status_title: '\u6a19\u984c',
    status_workspace: '\u5de5\u4f5c\u5340',
    status_yes: '\u662f',
    usage_default_model: '\u9810\u8a2d',
    usage_estimated_cost: '\u9810\u4f30\u8cbb\u7528',
    usage_heading: 'Token \u7528\u91cf',
    usage_input_tokens: '\u8f38\u5165 Token',
    usage_load_failed: '\u8f09\u5165\u7528\u91cf\u5931\u6557\uff1a',
    usage_output_tokens: '\u8f38\u51fa Token',
    usage_personality_none: '\u7121',
    usage_settings_tip: '\u6ce8\u610f\uff1a\u8cbb\u7528\u70ba\u9810\u4f30\u503c\u3002',
    usage_total: '\u7e3d Token \u6578',
    usage_unknown: '\u672a\u77e5',
    cmd_yolo: 'YOLO 模式切換',
    yolo_no_session: '無活動工作階段',
    yolo_enabled: '⚡ YOLO 模式已開啟 — 將跳過所有審批',
    yolo_disabled: 'YOLO 模式已關閉',
    cmd_branch:'Fork this conversation into a new session',
    cmd_branch_usage:'/branch [name] — fork conversation (optionally with a name)',
    branch_forked:'Forked into new session',
    branch_failed:'Fork failed: ',
    fork_from_here:'Fork from here',
    forked_from:'Forked from',
    yolo_pill_label: 'YOLO',
    yolo_pill_title_active: 'YOLO 模式激活 — 點擊關閉',
    approval_skip_all: '⚡ 本次工作階段全部跳過',
    approval_skip_all_title: '跳過本次工作階段的所有審批提示',
    // composer action tooltips
    composer_send: '\u50b3\u9001\u8a0a\u606f',
    composer_queue: '\u8a0a\u606f\u52a0\u5165\u4f47\u5217',
    composer_interrupt: '\u4e2d\u65b7\u4e26\u50b3\u9001',
    composer_steer: '\u5f15\u5c0e\u76ee\u524d\u56de\u61c9',
    composer_stop: '\u505c\u6b62\u7522\u751f',
    composer_disabled_clarify: '\u8acb\u56de\u8986\u4e0a\u65b9\u7684\u6f84\u6e05\u8981\u6c42',
    composer_disabled_compression: '\u7b49\u5f85\u58d3\u7e2e\u5b8c\u6210',
    composer_disabled_empty: '\u8acb\u8f38\u5165\u8a0a\u606f\u5f8c\u50b3\u9001',
    composer_mobile_workspace: '工作區',
    composer_mobile_model: '模型',
    composer_mobile_reasoning: '推理',
    composer_mobile_context: '上下文',
    // Queued messages
    queued_label: '回應後發送',
    queued_count: (n) => n === 1 ? '1 已排隊' : `${n} 已排隊`,
    queued_cancel: '取消排隊訊息',

    // Skills
    skill_deleted: '技能已刪除',
    skill_delete_confirm: '確定要刪除此技能嗎？',
    skills_empty_title: '尚無技能',
    skills_empty_sub: '安裝技能以擴展代理的能力',
    skills_edit: '編輯',
    skills_delete: '刪除',
    skills_back_to: '返回技能列表',

    // Tasks
    tasks_empty_title: '無任務',
    tasks_empty_sub: '管理排程與背景任務',

    // Workspaces
    workspaces_empty_title: '尚無工作區',
    workspaces_empty_sub: '設定工作區以組織您的專案',

    // Profiles
    profiles_empty_title: '尚無設定檔',
    profiles_empty_sub: '建立設定檔以快速切換環境',

    // Skill editor
    skill_name: '名稱',
    skill_category: '類別',
    skill_category_placeholder: '例如: devops',
    skill_content: '內容',
    skill_content_placeholder: '輸入技能內容...',
    skill_rename_not_supported: '此技能不支援重新命名',
    skill_metadata: '中繼資料',

    // Cron labels
    cron_name_label: '任務名稱',
    cron_schedule_label: '排程',
    cron_schedule_hint: "循環任務請用 'every 1h' 或 Cron 表達式。像 '30m' 這樣的裸時長只會執行一次。",
    cron_schedule_once_warning: "像 '30m' 這樣的時長寫法只會執行一次，並在執行後移除。要保留循環任務，請使用 'every 30m'。",
    cron_prompt_label: '提示',
    cron_deliver_label: '發送至',
    cron_deliver_local: '僅本地儲存',
    cron_profile_label: '設定檔',
    cron_profile_server_default: '伺服器預設',
    cron_profile_server_default_hint: '執行時使用 WebUI 伺服器預設設定檔。沒有設定檔的既有工作會保留此舊行為。',
    cron_skills_label: '技能',
    cron_skills_placeholder: '選用技能（逗號分隔）',
    cron_skills_edit_hint: '定義要載入的技能',

    // Workspace labels
    workspace_name_label: '名稱',
    workspace_name_placeholder: '例如: main-project',
    workspace_path_label: '路徑',
    workspace_path_required: '工作區路徑為必填',
    workspace_path_readonly: '路徑由環境設定檔決定，無法變更',
    workspace_new_title: '新增工作區',

    // Profile labels
    profile_name_label: '名稱',
    profile_base_url_label: 'Base URL',
    profile_api_key_label: 'API 金鑰',
    media_audio_label: '音訊',
    media_svg_label: '圖表',
    media_video_label: '影片',
    csv_loading: '載入 CSV',
    csv_too_large: 'CSV 檔案過大，無法內嵌渲染',
    csv_no_data: 'CSV 檔案資料不足，無法渲染為表格',
    csv_error: '載入 CSV 檔案失敗',
    csv_header_note: '第一列顯示為表格標題',
    excalidraw_loading: '載入圖表',
    excalidraw_too_large: 'Excalidraw 檔案過大，無法內嵌渲染',
    excalidraw_invalid: '無效的 Excalidraw 檔案格式',
    excalidraw_error: '載入 Excalidraw 檔案失敗',
    excalidraw_label: '圖表',
    excalidraw_download: '下載',
    excalidraw_empty: '空圖表',
    excalidraw_render_error: '渲染圖表失敗',
    excalidraw_simplified: '簡化 SVG 預覽 — 與 Excalidraw 畫布不完全相同',
    pdf_loading: '正在載入 PDF {0}…',
    pdf_too_large: 'PDF 檔案過大，無法內嵌預覽',
    pdf_no_pages: '無法渲染 PDF 預覽',
    pdf_error: 'PDF 載入失敗',
    pdf_download: '下載 PDF',
    html_loading: '正在載入 HTML 預覽…',
    html_too_large: 'HTML 檔案過大，無法內嵌預覽',
    html_error: 'HTML 預覽載入失敗',
    html_open_full: '開啟完整頁面',
    html_sandbox_label: 'HTML 預覽',
    // TTS (#499)
    tts_listen: '收聽',
    tts_not_supported: '語音合成無法使用',
    settings_label_tts: '回覆語音合成',
    settings_desc_tts: '在助手訊息上顯示喇叭按鈕',
    settings_label_tts_auto_read: '自動朗讀回覆',
    settings_desc_tts_auto_read: '自動朗讀助手回覆',
    // Composer voice-mode pref (#1488)
    settings_label_voice_mode: 'Hands-free voice mode button',  // TODO: translate
    settings_desc_voice_mode: 'Show the voice-mode button (audio waveform) next to the dictation mic. Lets you speak naturally — Hermes auto-sends after a pause and reads replies aloud. Requires a browser that supports both speech recognition and TTS.',  // TODO: translate
    settings_label_tts_voice: '語音',
    settings_desc_tts_voice: '選擇語音合成聲音',
    settings_label_tts_rate: '語速',
    settings_label_tts_pitch: '音調',

    checkpoint_date: 'Date',  // TODO: translate
    checkpoint_diff_files_changed: (n) => `${n} file${n === 1 ? '' : 's'} changed`,  // TODO: translate
    checkpoint_diff_no_changes: 'No differences found between this checkpoint and the current workspace.',  // TODO: translate
    checkpoint_diff_title: 'Changes in checkpoint',  // TODO: translate
    checkpoint_empty: 'No checkpoints found for this workspace.',  // TODO: translate
    checkpoint_error: 'Failed to load checkpoints',  // TODO: translate
    checkpoint_files: 'Files',  // TODO: translate
    checkpoint_loading: 'Loading checkpoints…',  // TODO: translate
    checkpoint_message: 'Message',  // TODO: translate
    checkpoint_restore: 'Restore',  // TODO: translate
    checkpoint_restore_confirm_message: (ckpt) => `Restore workspace to checkpoint "${ckpt}"? This will overwrite files with the saved versions. Files added after this checkpoint will not be deleted.`,  // TODO: translate
    checkpoint_restore_confirm_title: 'Restore checkpoint?',  // TODO: translate
    checkpoint_restored: 'Checkpoint restored',  // TODO: translate
    checkpoint_title: 'Checkpoints',  // TODO: translate
    checkpoint_view_diff: 'View diff',  // TODO: translate
    insights_activity_by_day: 'Activity by Day',  // TODO: translate
    insights_activity_by_hour: 'Activity by Hour',  // TODO: translate
    insights_cost: 'Estimated Cost',  // TODO: translate
    insights_daily_tokens: 'Daily Tokens',
    insights_model_name: 'Model',
    insights_model_sessions: 'Sessions',
    insights_model_tokens: 'Tokens',
    insights_model_cost: 'Cost',
    insights_model_share: 'Share',
    insights_no_usage_data: 'No usage data yet',
    insights_footer: 'Showing data from the last {days} days',  // TODO: translate
    insights_input_tokens: 'Input',  // TODO: translate
    insights_messages: 'Messages',  // TODO: translate
    insights_models: 'Models',  // TODO: translate
    insights_no_cost: 'N/A',  // TODO: translate
    insights_output_tokens: 'Output',  // TODO: translate
    insights_peak_hour: 'Peak: {hour}',  // TODO: translate
    insights_sessions: 'Sessions',  // TODO: translate
    insights_title: 'Usage Analytics',  // TODO: translate
    insights_token_breakdown: 'Token Breakdown',  // TODO: translate
    insights_tokens: 'Tokens',  // TODO: translate
    insights_total: 'Total',  // TODO: translate
    settings_desc_api_redact: 'Self-hosted users can disable for transparency (not recommended for shared instances).',  // TODO: translate
    settings_label_api_redact: 'Redact sensitive data in API responses',  // TODO: translate
    voice_error: 'Voice not supported in this browser',  // TODO: translate
    voice_listening: 'Listening…',  // TODO: translate
    voice_mode_active: 'Voice mode on',  // TODO: translate
    voice_mode_off: 'Voice mode off',  // TODO: translate
    voice_speaking: 'Speaking…',  // TODO: translate
    voice_thinking: 'Thinking…',  // TODO: translate
    // Composer voice buttons (#1488)
    voice_dictate: 'Dictate',  // TODO: translate
    voice_dictate_active: 'Stop dictation',  // TODO: translate
    voice_mode_toggle: 'Voice mode',  // TODO: translate
    voice_mode_toggle_active: 'Exit voice mode',  // TODO: translate
    subagent_children: 'Subagent sessions',  // TODO: translate
  },

  pt: {
    offline_title: 'Conexão perdida',
    offline_browser_detail: 'O navegador informa que este dispositivo está offline.',
    offline_network_detail: 'O Hermes está inacessível neste navegador agora.',
    offline_autorefresh: 'Vou atualizar esta página automaticamente quando o Hermes voltar a responder.',
    offline_check_now: 'Verificar agora',
    offline_checking: 'Verificando…',
    offline_stream_waiting: 'Conexão perdida. Aguardando para atualizar…',
    _lang: 'pt',
    _label: 'Português',
    _speech: 'pt-BR',
    // boot.js
    cancelling: 'Cancelando…',
    cancel_failed: 'Falha ao cancelar: ',
    mic_denied: 'Acesso ao microfone negado. Verifique as permissões do navegador.',
    mic_no_speech: 'Nenhuma fala detectada. Tente novamente.',
    mic_network: 'Reconhecimento de fala indisponível.',
    mic_error: 'Erro no input de voz: ',
    session_imported: 'Sessão importada',
    import_failed: 'Falha na importação: ',
    import_invalid_json: 'JSON inválido',
    image_pasted: 'Imagem colada: ',
    // messages.js
    edit_message: 'Editar mensagem',
    regenerate: 'Regenerar resposta',
    copy: 'Copiar',
    copied: 'Copiado!',
    copy_failed: 'Falha ao copiar',
    selected_text_reply: 'Responder com seleção',
    selected_text_reply_title: 'Anexar o texto selecionado do chat como contexto citado',
    selected_text_reply_appended: 'Texto selecionado adicionado ao compositor',
    you: 'Você',
    thinking: 'Pensando',
    expand_all: 'Expandir tudo',
    collapse_all: 'Recolher tudo',
    edit_failed: 'Falha ao editar: ',
    regen_failed: 'Falha ao regenerar: ',
    reconnect_active: 'Uma resposta ainda está sendo gerada. Recarregar quando estiver pronto?',
    reconnect_finished: 'Uma resposta estava em andamento quando você saiu. As mensagens podem ter atualizado.',
    // approval card
    approval_heading: 'Aprovação necessária',
    approval_desc_prefix: 'Comando perigoso detectado',
    approval_btn_once: 'Permitir uma vez',
    approval_btn_once_title: 'Permitir este comando (Enter)',
    approval_btn_session: 'Permitir sessão',
    approval_btn_session_title: 'Permitir para esta sessão de conversa',
    approval_btn_always: 'Sempre permitir',
    approval_btn_always_title: 'Sempre permitir este padrão de comando',
    approval_btn_deny: 'Negar',
    approval_btn_deny_title: 'Negar — não executar este comando',
    approval_responding: 'Respondendo…',
    clarify_heading: 'Esclarecimento necessário',
    clarify_hint: 'Escolha uma opção ou digite sua resposta abaixo.',
    clarify_other: 'Outro',
    clarify_send: 'Enviar',
    clarify_input_placeholder: 'Digite sua resposta…',
    clarify_responding: 'Respondendo…',
    untitled: 'Sem título',
    n_messages: (n) => `${n} mensagens`,
    load_older_messages: '↑ Role para cima ou clique para carregar mensagens mais antigas',
    session_jump_start: 'Início',
    session_jump_start_label: 'Ir para o início da sessão',
    session_jump_end: 'Fim',
    session_jump_end_label: 'Ir para o fim da sessão',
    jump_to_question: 'para a pergunta',
    jump_to_question_label: 'Ir para a pergunta desta resposta',
    queued_label: 'Envia após a resposta',
    queued_count: (n) => n === 1 ? '1 na fila' : `${n} na fila`,
    queued_cancel: 'Cancelar mensagem na fila',
    model_unavailable: ' (indisponível)',
    model_unavailable_title: 'Este modelo não está mais na sua lista de provedores',
    provider_mismatch_warning: (m,p)=>`"${m}" pode não funcionar com seu provedor configurado (${p}). Enviar assim mesmo, ou execute \`hermes model\` no terminal para trocar.`,
    provider_mismatch_label: 'Provedor incompatível',
    model_not_found_label: 'Modelo não encontrado',
    composer_mobile_workspace: 'Workspace',
    composer_mobile_model: 'Modelo',
    composer_mobile_reasoning: 'Raciocínio',
    composer_mobile_context: 'Contexto',
    model_custom_label: 'ID de modelo customizado',
    model_custom_placeholder: 'ex: openai/gpt-5.4',
    model_search_placeholder: 'Buscar modelos…',
    session_toolsets: 'Session Toolsets', // TODO: translate
    session_toolsets_desc: 'Restrict available tools for this session (blank = use global config)', // TODO: translate
    session_toolsets_global: 'Global (default)', // TODO: translate
    session_toolsets_custom: 'Custom', // TODO: translate
    session_toolsets_placeholder: 'tool1, tool2, \u2026', // TODO: translate
    session_toolsets_apply: 'Apply', // TODO: translate
    session_toolsets_clear: 'Clear (use global)', // TODO: translate
    session_toolsets_applied: 'Toolsets updated', // TODO: translate
    session_toolsets_cleared: 'Toolsets cleared — using global config', // TODO: translate
    session_toolsets_failed: 'Failed to update toolsets: ', // TODO: translate
    model_search_no_results: 'Nenhum modelo encontrado',
    model_group_configured: 'Configurados',
    ws_search_placeholder: 'Buscar espaços de trabalho…',
    ws_no_results: 'Nenhum espaço de trabalho encontrado',
    workspace_new_worktree_conversation: 'Nova conversa em worktree',
    workspace_new_worktree_conversation_meta: 'Cria um git worktree isolado para este espaço de trabalho.',
    workspace_worktree_created: 'Conversa em worktree criada',
    workspace_worktree_failed: 'Falha ao criar worktree: ',
    session_worktree_badge: 'Worktree',
    // commands.js
    cmd_clear: 'Limpar mensagens da conversa',
    cmd_compress: 'Comprimir manualmente o contexto (uso: /compress [tópico])',
    cmd_compact_alias: 'Alias legado para /compress',
    cmd_model: 'Trocar modelo (ex: /model gpt-4o)',
    cmd_workspace: 'Trocar workspace por nome',
    cmd_new: 'Iniciar nova sessão de chat',
    cmd_usage: 'Alternar exibição de uso de tokens',
    cmd_theme: 'Trocar aparência (tema: system/dark/light, skin: default/ares/mono/slate/poseidon/sisyphus/charizard/sienna/catppuccin/nous/geist-contrast)',
    cmd_personality: 'Trocar personalidade do agente',
    cmd_skills: 'Listar skills disponíveis do Hermes',
    available_commands: 'Comandos disponíveis:',
    type_slash: 'Digite / para ver comandos',
    conversation_cleared: 'Conversa limpa',
    command_label: 'Comando',
    context_compaction_label: 'Compactação de contexto',
    preserved_task_list_label: 'Lista de tarefas preservada',
    reference_only_label: 'Apenas referência',
    model_usage: 'Uso: /model <nome>',
    no_model_match: 'Nenhum modelo correspondendo "',
    switched_to: 'Trocado para ',
    workspace_usage: 'Uso: /workspace <nome>',
    no_workspace_match: 'Nenhum workspace correspondendo "',
    switched_workspace: 'Trocado para workspace: ',
    workspace_switch_failed: 'Falha ao trocar workspace: ',
    new_session: 'Nova sessão criada',
    new_session_creating: 'Criando nova conversa…',
    compressing: 'Solicitando compressão de contexto...',
    compress_running_label: 'Comprimindo',
    compress_complete_label: 'Compressão completa',
    auto_compress_label: 'Compressão automática',
    compress_failed_label: 'Falha na compressão',
    focus_label: 'Foco',
    token_usage_on: 'Uso de tokens ligado',
    token_usage_off: 'Uso de tokens desligado',
    usage_cache_hit_detail: 'Cache: {0}% de acerto ({1} leitura / {2} escrita)',
    usage_cached_percent: '{0}% em cache',
    theme_usage: 'Uso: /theme ',
    theme_set: 'Tema: ',
    no_active_session: 'Nenhuma sessão ativa',
    cmd_queue: 'Enfileirar mensagem para o próximo turno',
    cmd_goal: 'Definir ou consultar uma meta persistente',
    goal_evaluating_progress: 'Evaluating goal progress…',
    goal_working_toward: 'Working toward goal…',
    goal_continuing_toast: 'Continuing toward goal…',
    goal_status_none: 'No active goal. Set one with /goal <text>.',
    goal_status_active: (turns, max_turns, goal) => `⊙ Goal (active, ${turns}/${max_turns} turns): ${goal}`,
    goal_status_paused: (turns, max_turns, reason, goal) => `⏸ Goal (paused, ${turns}/${max_turns}${reason ? `, ${reason}` : ''}): ${goal}`,
    goal_status_done: (turns, max_turns, goal) => `✓ Goal done (${turns}/${max_turns}): ${goal}`,
    goal_set: (turns, goal) => `⊙ Goal set (${turns}-turn budget): ${goal}`,
    goal_paused: (goal) => `⏸ Goal paused: ${goal}`,
    goal_resumed: (goal) => `▶ Goal resumed: ${goal}`,
    goal_cleared: 'Goal cleared.',
    goal_no_goal: 'No active goal.',
    goal_achieved: (reason) => `✓ Goal achieved: ${reason}`,
    goal_paused_budget_exhausted: (turns, max_turns) => `⏸ Goal paused — ${turns}/${max_turns} turns used. Use /goal resume to keep going, or /goal clear to stop.`,
    goal_continuing: (turns, max_turns, reason) => `↻ Continuing toward goal (${turns}/${max_turns}): ${reason}`,
    cmd_interrupt: 'Cancelar turno atual e enviar nova mensagem',
    cmd_steer: 'Injetar correção no meio do turno sem interromper',
    cmd_queue_no_msg: 'Uso: /queue <mensagem>',
    cmd_queue_not_busy: 'Nenhuma tarefa ativa — apenas envie normalmente',
    cmd_queue_confirm: 'Mensagem enfileirada',
    cmd_interrupt_no_msg: 'Uso: /interrupt <mensagem>',
    cmd_interrupt_confirm: 'Interrompido — enviando nova mensagem',
    cmd_steer_no_msg: 'Uso: /steer <mensagem>',
    cmd_steer_fallback: 'Steer indisponível — enfileirado para próximo turno',
    cmd_steer_delivered: 'Steer entregue — agente verá no próximo resultado',
    steer_leftover_queued: 'Steer enfileirado para próximo turno',
    busy_steer_fallback: 'Steer indisponível — enfileirado para próximo turno',
    busy_interrupt_confirm: 'Interrompido — enviando nova mensagem',
    settings_label_busy_input_mode: 'Modo de input ocupado',
    settings_desc_busy_input_mode: 'Controla o que acontece ao enviar mensagem com agente rodando. Fila espera; Interromper cancela; Steer injeta correção.',
    settings_label_fade_text_effect: 'Efeito de fade no texto',
    settings_desc_fade_text_effect: 'Faz novas palavras aparecerem gradualmente enquanto o assistente responde. Similar ao OpenWebUI; desativado por padrão para melhor desempenho.',
    settings_busy_input_mode_queue: 'Enfileirar follow-up',
    settings_busy_input_mode_interrupt: 'Interromper turno atual',
    settings_busy_input_mode_steer: 'Steer (correção no meio do turno)',

    slash_skill_badge: 'Skill',
    slash_skill_desc: 'Invocar esta skill',
    cmd_stop: 'Parar resposta atual',
    cmd_title: 'Obter ou definir título da sessão',
    cmd_retry: 'Reenviar última mensagem',
    cmd_undo: 'Remover última troca',
    cmd_btw: 'Fazer pergunta lateral (efêmera)',
    cmd_btw_usage: '/btw <pergunta> — fazer pergunta lateral',
    cmd_background: 'Rodar prompt em background',
    cmd_background_usage: '/background <prompt> — rodar em paralelo',
    btw_asking: 'Fazendo pergunta lateral...',
    btw_label: 'Pergunta lateral — não no histórico',
    btw_done: 'Pergunta lateral respondida',
    btw_no_answer: 'Nenhuma resposta recebida.',
    btw_failed: 'Pergunta lateral falhou: ',
    cmd_branch:'Fork this conversation into a new session',
    cmd_branch_usage:'/branch [name] — fork conversation (optionally with a name)',
    branch_forked:'Forked into new session',
    branch_failed:'Fork failed: ',
    fork_from_here:'Fork from here',
    forked_from:'Forked from',
    bg_running: 'Rodando em background...',
    bg_complete: 'Tarefa de background completa',
    bg_label: 'Resultado de background:',
    bg_no_answer: '(sem resposta)',
    bg_failed: 'Tarefa de background falhou: ',
    undo_exchange: 'Desfazer última troca',
    cmd_status: 'Mostrar info da sessão',
    cmd_voice: 'Alternar input de microfone',
    stream_stopped: 'Resposta parada.',
    no_active_task: 'Nenhuma tarefa ativa para parar.',
    cancel_unavailable: 'Cancelar indisponível.',
    retry_failed: 'Retry falhou: ',
    undo_failed: 'Undo falhou: ',
    undid_n_messages: 'Removido',
    undid_messages_suffix: 'mensagem(s).',
    status_heading: 'Status da Sessão',
    status_session_id: 'ID da Sessão',
    status_title: 'Título',
    status_model: 'Modelo',
    status_provider: 'Provedor',
    status_workspace: 'Workspace',
    status_personality: 'Personalidade',
    status_messages: 'Mensagens',
    status_agent_running: 'Agente rodando',
    status_profile: 'Perfil',
    status_hermes_home: 'Diretório Hermes',
    status_started: 'Iniciado',
    status_tokens: 'Tokens',
    status_updated: 'Atualizado',
    status_ephemeral: 'Instantâneo efêmero — não salvo no histórico.',
    status_no_tokens: 'Nenhum token usado',
    status_unknown: 'Desconhecido',
    status_yes: 'Sim',
    status_no: 'Não',
    status_load_failed: 'Falha ao carregar status: ',
    title_current: 'Título atual',
    title_change_hint: 'Use `/title <novo nome>` para renomear.',
    title_set: 'Título definido como',
    cmd_webui_only_session: 'Comando indisponível para sessões CLI.',
    cmd_voice_use_mic: 'Clique no botão de mic no composer.',
    usage_heading: 'Uso de Tokens',
    usage_default_model: 'padrão',
    usage_unknown: 'desconhecido',
    usage_input_tokens: 'Tokens de input',
    usage_output_tokens: 'Tokens de output',
    usage_total: 'Total de tokens',
    usage_estimated_cost: 'Custo estimado',
    usage_settings_tip: 'Nota: estimativas são aproximadas.',
    usage_load_failed: 'Falha ao carregar uso: ',
    usage_personality_none: 'nenhuma',

    no_personalities: 'Nenhuma personalidade encontrada (adicione em ~/.hermes/personalities/)',
    available_personalities: 'Personalidades disponíveis:',
    personality_switch_hint: '\n\nUse `/personality <nome>` para trocar, ou `/personality none` para limpar.',
    personalities_load_failed: 'Falha ao carregar personalidades',
    personality_cleared: 'Personalidade limpa',
    personality_set: 'Personalidade: ',
    failed_colon: 'Falhou: ',
    // ui.js
    no_workspace: 'Nenhum workspace',
    workspace_empty_no_path: 'Nenhum workspace selecionado. Configure em Configurações → Workspace.',
    workspace_empty_dir: 'Este workspace está vazio.',
    workspace_show_hidden_files: 'Mostrar arquivos ocultos',
    workspace_show_hidden_files_desc: 'Include .DS_Store, .git, node_modules, and other hidden / system files in the file tree.',
    workspace_hidden_files_visible: 'hidden visible',
    workspace_hidden_files_visible_title: 'Hidden files are visible — click for options',
    workspace_options: 'Workspace options',
    dialog_confirm_title: 'Confirmar ação',
    dialog_prompt_title: 'Digite um valor',
    dialog_confirm_btn: 'Confirmar',
    // workspace.js
    unsaved_confirm: 'Você tem mudanças não salvas. Descartar e navegar?',
    discard: 'Descartar',
    save: 'Salvar',
    edit: 'Editar',
    clear: 'Limpar',
    create: 'Criar',
    remove: 'Remover',
    save_title: 'Salvar mudanças',
    edit_title: 'Editar este arquivo',
    saved: 'Salvo',
    save_failed: 'Falha ao salvar: ',
    image_load_failed: 'Não foi possível carregar imagem',
    file_open_failed: 'Não foi possível abrir arquivo',
    downloading: (name) => `Baixando ${name}…`,
    double_click_rename: 'Duplo clique para renomear',
    renamed_to: 'Renomeado para ',
    rename_failed: 'Falha ao renomear: ',
    delete_title: 'Excluir',
    delete_confirm: (name) => `Excluir ${name}?`,
    deleted: 'Excluído ',
    delete_failed: 'Falha ao excluir: ',
    reveal_in_finder: 'Mostrar no gerenciador de arquivos',
    reveal_failed: 'Falha ao mostrar: ',
    copy_file_path: 'Copiar caminho do arquivo',
    download_folder: 'Download Folder', // TODO: translate
    path_copied: 'Caminho do arquivo copiado para a área de transferência',
    path_copy_failed: 'Falha ao copiar caminho: ',
    session_rename: 'Renomear conversa',
    session_rename_desc: 'Editar o título desta conversa',
    new_file_prompt: 'Nome do novo arquivo (ex: notes.md):',
    project_name_prompt: 'Nome do projeto:',
    created: 'Criado ',
    create_failed: 'Falha ao criar: ',
    new_folder_prompt: 'Nome da nova pasta:',
    folder_created: 'Pasta criada ',
    folder_create_failed: 'Falha ao criar pasta: ',
    workspace_auto_create_folder: 'Criar pasta se não existir',
    folder_add_as_space_btn: 'Adicionar como Space',
    folder_add_as_space_msg: 'Adicionar esta pasta como novo space?',
    folder_add_as_space_title: 'Adicionar como Space?',
    remove_title: 'Remover',
    empty_dir: '(vazio)',
    upload_failed: 'Falha ao upload: ',
    upload_too_large: (maxMb, fileMb) => `O arquivo é grande demais (${fileMb} MB). O tamanho máximo de upload é ${maxMb} MB.`,
    all_uploads_failed: (n) => `Todos ${n} upload(s) falharam`,
    session_pin: 'Fixar conversa',
    session_unpin: 'Desfixar conversa',
    session_pin_desc: 'Manter esta conversa no topo',
    session_unpin_desc: 'Remover dos fixados',
    session_pin_failed: 'Falha ao fixar: ',
    session_move_project: 'Mover para projeto',
    session_move_project_desc_has: 'Mudar projeto desta conversa',
    session_move_project_desc_none: 'Atribuir projeto a esta conversa',
    session_archive: 'Arquivar conversa',
    session_hide_external: 'Ocultar da lista',
    session_restore: 'Restaurar conversa',
    session_archive_desc: 'Esconder conversa até mostrar arquivados',
    session_archive_worktree_desc: 'Esconder esta conversa; manter o worktree no disco',
    session_hide_external_desc: 'Ocultar esta sessão importada do WebUI sem excluir o histórico original.',
    session_restore_desc: 'Trazer conversa de volta à lista principal',
    session_archived: 'Sessão arquivada',
    session_archived_worktree: 'Sessão arquivada. O worktree permanece no disco.',
    session_hidden: 'Sessão ocultada da lista',
    session_restored: 'Sessão restaurada',
    session_archive_failed: 'Falha ao arquivar: ',
    session_duplicate: 'Duplicar conversa',
    session_duplicate_desc: 'Criar cópia com mesmo workspace e modelo',
    session_duplicated: 'Sessão duplicada',
    session_duplicate_failed: 'Falha ao duplicar: ',
    session_stop_response: 'Stop response',
    session_stop_response_desc: 'Cancel the running response for this conversation',
    session_delete: 'Excluir conversa',
    session_delete_desc: 'Remover permanentemente esta conversa',
    session_delete_confirm: 'Excluir esta conversa?',
    session_delete_worktree_desc: 'Excluir apenas a conversa no WebUI; manter o worktree no disco',
    session_delete_worktree_confirm: (path) => `Excluir esta conversa? O worktree em ${path} permanecerá no disco.`,
    session_deleted: 'Conversa excluída',
    session_deleted_worktree: 'Conversa excluída. O worktree permanece no disco.',
    session_worktree_remove: 'Remover worktree',
    session_worktree_remove_desc: (path) => `Excluir o git worktree em ${path} do disco`,
    session_worktree_remove_confirm: (path) => `Remover git worktree do disco?\n\nCaminho: ${path}\n\nTodo o diretório do worktree será excluído. Dados da sessão permanecem no WebUI.`,
    session_worktree_remove_not_exists: (path) => `O worktree em ${path} não existe mais no disco.`,
    session_worktree_remove_confirm_label: 'Remover',
    session_worktree_removed: 'Worktree removido.',
    session_worktree_remove_failed: 'Falha ao remover worktree: ',
    session_worktree_remove_status_failed: 'Falha ao ler o status do worktree: ',
    session_worktree_remove_locked_by_stream: 'Não é possível remover — uma sessão de streaming ativa está usando este worktree.',
    session_worktree_remove_locked_by_terminal: 'Não é possível remover — uma sessão de terminal ativa está usando este worktree.',
    session_worktree_remove_unsafe_blocked: 'Resolva alterações locais ou commits não enviados antes de remover este worktree.',
    session_worktree_remove_dirty_warning: 'AVISO: Este worktree tem alterações não confirmadas que serão perdidas.',
    session_worktree_remove_untracked_warning: (count) => `${count} arquivo(s) não rastreados serão excluídos permanentemente.`,
    session_worktree_remove_ahead_warning: (ahead) => `${ahead} commit(s) não enviados serão perdidos.`,
    session_batch_delete_worktree_confirm: 'Excluir {0} conversas? {1} conversa(s) com worktree manterão seus diretórios de worktree no disco.',
    session_batch_archive_worktree_confirm: 'Arquivar {0} conversas? {1} conversa(s) com worktree manterão seus diretórios de worktree no disco.',
    session_batch_delete_confirm: 'Excluir {0} conversas?',
    session_batch_archive_confirm: 'Arquivar {0} conversas?',
    session_select_mode: 'Selecionar',
    session_select_mode_desc: 'Selecionar conversas para gerenciamento em lote',
    session_select_all: 'Selecionar todas',
    session_selected_count: '{0} selecionadas',
    session_no_selection: 'Nenhuma conversa selecionada',
    // settings panel
    settings_heading_title: 'Control Center',
    settings_heading_subtitle: 'Preferências, ferramentas de conversa e controles do sistema.',
    settings_section_conversation_title: 'Conversa',
    settings_section_appearance_title: 'Aparência',
    settings_section_appearance_meta: 'Tema, cores de destaque e estilo visual.',
    settings_section_preferences_title: 'Preferências',
    settings_section_preferences_meta: 'Padrões e comportamento UI do Hermes Web UI.',
    settings_section_system_title: 'Sistema',
    settings_section_system_meta: 'Versão da instância e controles de acesso.',
    settings_check_now: 'Verificar agora',
    settings_checking: 'Verificando…',
    settings_up_to_date: 'Atualizado ✓',
    settings_updates_available: '{count} atualização(ões) disponível(is)',
    settings_updates_disabled: 'Verificação de updates desativada',
    settings_update_check_failed: 'Falha ao verificar updates',
    settings_label_workspace_panel_open: 'Manter painel workspace aberto por padrão',
    settings_desc_workspace_panel_open: 'Quando ativo, o painel workspace abre automaticamente com cada nova sessão.',
    settings_label_session_jump_buttons: 'Mostrar botões de salto da sessão',
    settings_desc_session_jump_buttons: 'Mostra botões flutuantes Início e Fim ao ler históricos longos de sessão.',

    settings_label_session_endless_scroll: 'Carregar mensagens antigas ao rolar para cima',

    settings_desc_session_endless_scroll: 'Quando ativado, mensagens antigas carregam automaticamente ao rolar para cima. Quando desativado, use o botão de mensagens antigas.',

    settings_label_tab_visibility: 'Abas da barra lateral',
    settings_desc_tab_visibility: 'Escolha quais abas aparecem na barra lateral e no rail. Chat e Configurações estão sempre visíveis.',
    open_in_browser: 'Abrir no navegador',
    settings_dropdown_conversation: 'Conversa',
    settings_dropdown_appearance: 'Aparência',
    settings_dropdown_preferences: 'Preferências',
    settings_dropdown_providers: 'Provedores',
    settings_dropdown_system: 'Sistema',
    settings_tab_conversation: 'Conversa',
    settings_tab_appearance: 'Aparência',
    settings_tab_preferences: 'Preferências',
    settings_tab_plugins: 'Plugins',
    settings_plugins_title: 'Plugins',  // TODO: translate
    settings_plugins_meta: 'View installed Hermes plugins and the lifecycle hooks they register. This panel is read-only.',  // TODO: translate
    settings_plugins_empty: 'No Hermes plugins are currently visible. Install or enable plugins from the Hermes CLI/config to see them here.',  // TODO: translate
    plugins_unnamed: 'Unnamed plugin',  // TODO: translate
    plugins_no_description: 'No description provided.',  // TODO: translate
    plugins_no_hooks: 'No registered lifecycle hooks',  // TODO: translate
    plugins_registered_hooks: 'Registered hooks',  // TODO: translate
    plugins_enabled: 'Enabled',  // TODO: translate
    plugins_disabled: 'Disabled',  // TODO: translate
    plugins_active_provider: 'Active (provider)',  // TODO: translate
    plugins_provider_no_hooks: 'Provider plugin — no agent-visibility hooks',  // TODO: translate
    plugins_load_failed: 'Failed to load plugins: ',  // TODO: translate
    settings_tab_system: 'Sistema',
    settings_title: 'Configurações',
    settings_save_btn: 'Salvar Configurações',
    settings_label_model: 'Modelo Padrão',
    settings_desc_model: 'Usado para novas conversas. Conversas existentes mantêm o modelo selecionado.',
    settings_label_send_key: 'Tecla de Envio',
    settings_label_theme: 'Tema',
    settings_label_skin: 'Skin',
    settings_label_font_size: 'Tamanho da fonte',
    font_size_small: 'Pequeno',
    font_size_default: 'Padrão',
    font_size_large: 'Grande',
    font_size_xlarge: 'Extra grande',
    settings_autosave_saving: 'Salvando…',
    settings_autosave_saved: 'Salvo',
    settings_autosave_failed: 'Falha ao salvar',
    settings_autosave_retry: 'Tentar novamente',
    settings_label_language: 'Idioma',
    settings_label_quota_chip: 'Mostrar o chip de cota do provedor no compositor',
    settings_desc_quota_chip: 'Exibe um indicador ambiente de cota restante (por exemplo, saldo de crédito do OpenRouter) no rodapé do compositor. Desativado por padrão. Visível apenas em telas largas (≥1400px) quando ativado, para manter o compositor livre em laptops e monitores padrão.',
    settings_label_hide_suggestions: 'Hide new-chat suggestions',
    settings_desc_hide_suggestions: 'Hide the three default suggestion buttons on the empty new-chat screen to avoid accidental taps.',
    settings_label_token_usage: 'Mostrar uso de tokens',
    settings_label_sidebar_density: 'Densidade da sidebar',
    cmd_reasoning: 'Alternar visibilidade do pensamento (mostrar/ocultar)',
    settings_label_external_sessions: 'Mostrar sessões externas',
    settings_label_previous_messaging_sessions: 'Mostrar sessões de mensagens anteriores',
    settings_label_sync_insights: 'Sincronizar para insights',
    settings_label_check_updates: 'Verificar atualizações',
    settings_label_whats_new_summary: "Summarize What's New with AI",
    settings_label_bot_name: 'Nome padrão do assistente',
    settings_label_password: 'Senha de Acesso',
    settings_saved: 'Configurações salvas',
    settings_save_failed: 'Falha ao salvar: ',
    settings_load_failed: 'Falha ao carregar configurações: ',
    settings_saved_pw: 'Configurações salvas — senha ativada e navegador permanece logado',
    settings_saved_pw_updated: 'Configurações salvas — senha atualizada',
    // login page
    login_title: 'Entrar',
    login_subtitle: 'Digite sua senha para continuar',
    login_placeholder: 'Senha',
    login_btn: 'Entrar',
    login_invalid_pw: 'Senha inválida',
    login_conn_failed: 'Falha na conexão',

    // Sidebar & Tabs
    tab_chat: 'Chat',
    tab_tasks: 'Tarefas',
    tab_skills: 'Skills',
    tab_memory: 'Memória',
    tab_workspaces: 'Spaces',
    tab_profiles: 'Perfis',
    tab_kanban: 'Kanban',
    kanban_board: 'Board',
    kanban_visible_tasks: '{0} visible tasks',
    kanban_search_tasks: 'Search tasks',
    kanban_all_assignees: 'All assignees',
    kanban_all_tenants: 'All tenants',
    kanban_include_archived: 'Include archived',
    kanban_no_matching_tasks: 'No matching tasks',
    kanban_no_data: 'No Kanban data',
    kanban_work_queue_hint: 'This is the Hermes Agent work queue. Create or triage a task, assign it, move it to Ready, then let the dispatcher claim it.',
    kanban_unavailable: 'Kanban unavailable',
    kanban_read_only: 'Read-only view',
    kanban_empty: 'Empty',
    kanban_task: 'Task',
    kanban_no_description: 'No description',
    kanban_refresh: 'Refresh',
    kanban_status_triage: 'Triage',
    kanban_status_todo: 'Todo',
    kanban_status_ready: 'Ready',
    kanban_status_running: 'Running',
    kanban_status_blocked: 'Blocked',
    kanban_status_done: 'Done',
    kanban_status_original_hint: 'Actual status: {0}. This dialog only supports Triage/Todo/Ready edits.',
    kanban_comments_count: 'Comments ({0})',
    kanban_events_count: 'Events ({0})',
    kanban_links: 'Links',
    kanban_parents: 'Parents',
    kanban_children: 'Children',
    kanban_runs_count: 'Runs ({0})',
    kanban_no_comments: 'No comments',
    kanban_no_events: 'No events',
    kanban_no_runs: 'No runs',
    kanban_title: 'Título',
    kanban_description: 'Descrição',
    kanban_description_placeholder: 'Opcional — o que precisa ser feito, critérios de aceitação, links',
    kanban_status: 'Status',
    kanban_assignee: 'Responsável',
    kanban_assignee_placeholder: 'Opcional — deixe em branco para qualquer worker',
    kanban_tenant: 'Tenant',
    kanban_tenant_placeholder: 'Opcional — slug do projeto ou equipe',
    kanban_priority: 'Prioridade',
    kanban_priority_hint: 'Números maiores executam primeiro. Padrão: 0.',
    kanban_title_required: 'O título é obrigatório.',
    kanban_edit_task: 'Editar tarefa',
    kanban_run_dispatcher: 'Executar despachador',
    kanban_run_dispatcher_confirm: 'Isso reivindicará tarefas Ready neste quadro e gerará subprocessos worker (um por tarefa, até 8 por clique). Continuar?',
    kanban_assignee_profiles_label: 'Perfis Hermes',
    kanban_assignee_other_label: 'Outros (faixas CLI / perfis removidos)',
    kanban_assignee_unassigned: '— Não atribuído (não rodará automaticamente) —',
    kanban_ready_needs_assignee: 'Você selecionou «Não atribuído» + «Ready». O despachador pulará esta tarefa. Envie novamente para confirmar ou escolha um perfil.',
    kanban_dispatch_preview_prefix: 'Prévia:',
    kanban_dispatch_run_prefix: 'Despachado:',
    kanban_dispatch_spawned: 'iniciadas',
    kanban_dispatch_promoted: 'promovidas',
    kanban_dispatch_reclaimed: 'reclamadas',
    kanban_dispatch_skipped_unassigned: 'puladas (sem responsável)',
    kanban_dispatch_skipped_nonspawnable: 'puladas (perfil desconhecido)',
    kanban_dispatch_auto_blocked: 'auto-bloqueadas',
    kanban_dispatch_timed_out: 'tempo esgotado',
    kanban_dispatch_crashed: 'falharam',
    kanban_new_task: 'New task',
    kanban_add_comment: 'Add comment',
      kanban_only_mine: 'Only mine',
      kanban_bulk_action: 'Bulk action',
      kanban_nudge_dispatcher: 'Preview dispatcher',
      kanban_stats: 'Stats',
      kanban_worker_log: 'Worker log',
      kanban_block: 'Block',
      kanban_unblock: 'Unblock',
      kanban_back_to_board: 'Back to board',
      kanban_lanes_by_profile: 'Lanes by profile',
      kanban_new_board: 'New board…',
      kanban_rename_board: 'Rename current board…',
      kanban_archive_board: 'Archive current board…',
      kanban_archive_board_confirm: 'Archive board "{name}"? Tasks remain on disk and the board can be restored from kanban/boards/_archived/.',
      kanban_board_archived: 'Board archived',
      kanban_board_name: 'Name',
      kanban_board_slug: 'Slug (lowercase, hyphens)',
      kanban_board_description: 'Description (optional)',
      kanban_board_icon: 'Icon (emoji, optional)',
      kanban_board_color: 'Color (optional)',
      kanban_board_name_required: 'Name is required',
      kanban_board_slug_required: 'Slug is required',
      kanban_card_complete: 'complete',
      kanban_card_archive: 'archive',
      kanban_unassigned: 'unassigned',
    kanban_status_archived: 'Archived',
    tab_todos: 'Todos',
    tab_insights: 'Estatísticas',
    tab_dashboard: 'Painel Hermes',
    dashboard_loopback_warning: 'O painel é somente loopback no servidor. Navegue pelo próprio servidor ou reinicie com --host 0.0.0.0 (inseguro).',
    tab_logs: 'Logs',
    tab_settings: 'Configurações',

    logs_title: 'Logs',  // TODO: translate
    logs_file: 'File',  // TODO: translate
    logs_tail: 'Tail',  // TODO: translate
    logs_auto_refresh: 'Auto-refresh (5s)',  // TODO: translate
    logs_wrap: 'Wrap lines',  // TODO: translate
    logs_copy_all: 'Copy all',  // TODO: translate
    logs_empty: 'No log lines yet.',  // TODO: translate
    logs_loading: 'Loading logs…',  // TODO: translate
    logs_load_failed: 'Logs failed to load',  // TODO: translate
    logs_status_idle: 'Choose a log file to view recent lines.',  // TODO: translate
    logs_no_mtime: 'not written yet',  // TODO: translate
    logs_truncated_hint: 'Showing the tail of a large log file; older bytes were skipped to keep memory bounded.',  // TODO: translate
    logs_copied: 'Logs copied',  // TODO: translate
    logs_severity: 'Severidade',
    logs_severity_all: 'Todos',
    logs_severity_errors: 'Erros',
    logs_severity_warnings: 'Avisos+',
    logs_filter_active: 'exibidos (filtro ativo)',
    new_conversation: 'Nova conversa',
    filter_conversations: 'Filtrar conversas...',
    session_time_unknown: 'Desconhecido',
    session_time_minutes_ago: (n) => `${n}m`,
    session_time_hours_ago: (n) => `${n}h`,
    session_time_days_ago: (n) => `${n}d`,
    session_time_last_week: '1s',
    session_time_bucket_today: 'Hoje',
    session_time_bucket_yesterday: 'Ontem',
    session_time_bucket_this_week: 'Esta semana',
    session_time_bucket_last_week: 'Semana passada',
    session_time_bucket_older: 'Antigo',
    scheduled_jobs: 'Tarefas agendadas',
    new_job: 'Nova tarefa',
    loading: 'Carregando...',
    search_skills: 'Buscar skills...',
    new_skill: 'Nova skill',
    personal_memory: 'Memória pessoal',
    current_task_list: 'Lista de tarefas atual',
    workspace_desc: 'Adicionar e trocar workspaces para suas sessões.',
    session_meta_messages: (n) => `${n} msg${n === 1 ? '' : 's'}`,
    session_meta_children: (n) => `${n} child${n === 1 ? '' : 'ren'}`,
    session_meta_segments: (n) => `${n} segment${n === 1 ? '' : 's'}`,
    session_lineage_segment_untitled: 'Segmento sem título',
    session_lineage_segment_open: 'Abrir segmento de linhagem',
    new_profile: 'Novo perfil',
    transcript: 'Transcrição',
    download_transcript: 'Baixar como Markdown',
    import: 'Importar',
    export_session_json: 'JSON',
    export_session_json_tooltip: 'Exportar sessão completa como JSON',
    import_session_json_tooltip: 'Importar sessão de JSON',
    clear_conversation_btn_tooltip: 'Limpar todas as mensagens nesta conversa',
    // Settings detail
    settings_label_rtl: 'Layout de chat da direita para a esquerda',
    settings_desc_rtl: 'Inverte o alinhamento das mensagens do chat e da entrada do compositor para idiomas como árabe ou hebraico. Afeta apenas a área do chat — a barra lateral e outros painéis permanecem da esquerda para a direita.',
    settings_label_sound: 'Som de notificação',
    settings_desc_sound: 'Tocar som quando assistente finalizar resposta.',
    settings_label_notifications: 'Notificações do navegador',
    settings_desc_notifications: 'Mostrar notificação quando resposta completar com app em background.',
    settings_desc_token_usage: 'Exibe contagem de tokens abaixo de cada resposta. Também com /usage.',
    settings_sidebar_density_compact: 'Compacto',
    settings_sidebar_density_detailed: 'Detalhado',
    settings_desc_sidebar_density: 'Controla quanto metadado a lista de sessões mostra na sidebar.',
    settings_label_auto_title_refresh: 'Atualização adaptativa de título',
    settings_auto_title_refresh_off: 'Desligado',
    settings_auto_title_refresh_5: 'A cada 5 trocas',
    settings_auto_title_refresh_10: 'A cada 10 trocas',
    settings_auto_title_refresh_20: 'A cada 20 trocas',
    settings_desc_auto_title_refresh: 'Re-gera título da sessão baseado na última troca.',
    settings_desc_external_sessions: 'Mostrar conversas de CLI, Telegram, Discord, Slack e outros canais na lista de sessões. Clique para importar e continuar.',
    settings_desc_previous_messaging_sessions: 'Mostrar sessões antigas de Discord, Telegram, Slack e Weixin substituídas por reset ou compressão.',
    settings_desc_sync_insights: 'Espelha uso de tokens para state.db.',
    settings_desc_check_updates: 'Mostrar banner quando versões mais novas estiverem disponíveis.',
    settings_desc_whats_new_summary: "Changes the What's New action from opening the raw diff first to generating a short, human-readable summary. The regular diff comparison stays available after the summary.",
    settings_desc_bot_name: 'Usado apenas para o perfil padrão. Outros perfis usam seus próprios nomes.',
    settings_desc_password: 'Digite nova senha para definir ou trocar. Deixe em branco para manter.',
    password_placeholder: 'Digite nova senha…',
    password_env_var_locked: 'A variável de ambiente HERMES_WEBUI_PASSWORD está definida e tem prioridade. Remova-a e reinicie o servidor para gerenciar a senha aqui.',
    password_env_var_locked_placeholder: 'Bloqueado: variável HERMES_WEBUI_PASSWORD está definida',
    disable_auth: 'Desativar Auth',
    sign_out: 'Sair',
    // Providers panel
    providers_tab_title: 'Provedores',
    providers_section_title: 'Provedores',
    providers_section_meta: 'Gerenciar API keys. Mudanças fazem efeito imediatamente.',
    providers_status_configured: 'API key configurada',
    providers_status_not_configured: 'Sem API key',
    providers_status_oauth: 'OAuth',
    providers_status_api_key: 'API key',
    providers_status_not_configured_label: 'Não configurado',
    providers_oauth_hint: 'Autenticado via OAuth. Sem API key necessária.',
    providers_oauth_config_yaml_hint: 'Token configurado via config.yaml. Para atualizar, edite config.yaml ou rode hermes auth.',
    providers_oauth_not_configured_hint: 'Não autenticado. Rode hermes auth no terminal.',
    providers_save: 'Salvar',
    providers_remove: 'Remover',
    providers_saving: 'Salvando…',
    providers_removing: 'Removendo…',
    providers_enter_key: 'Por favor digite uma API key',
    providers_empty: 'Nenhum provedor configurável encontrado.',
    providers_key_updated: 'API key salva',
    providers_key_removed: 'API key removida',
    providers_key_placeholder_new: 'sk-...',
    providers_key_placeholder_replace: 'Digite nova key para substituir…',
    provider_quota_title: 'Cota do provedor ativo',
    provider_quota_active_provider: 'Provedor ativo',
    provider_quota_last_checked_after_refresh: 'Última verificação após atualizar',
    provider_quota_last_checked: 'Última verificação {0}',
    provider_quota_refresh_usage: 'Atualizar uso',
    provider_quota_refreshing: 'Atualizando...',
    provider_quota_refresh_title: 'Atualizar agora os limites de uso do provedor',
    provider_quota_refresh_succeeded: 'Uso do provedor atualizado',
    provider_quota_refresh_failed: 'Falha ao atualizar uso do provedor',
    provider_quota_session_limit: 'Limite de 5 horas',
    provider_quota_weekly_limit: 'Limite semanal',
    provider_quota_window_fallback: 'Janela',
    provider_quota_metric_remaining: 'Restante',
    provider_quota_metric_used: 'Usado',
    provider_quota_metric_limit: 'Limite',
    provider_quota_status_available: 'disponível',
    provider_quota_status_exhausted: 'esgotado',
    provider_quota_status_unavailable: 'indisponível',
    provider_quota_status_failed: 'falhou',
    provider_quota_status_checked: 'verificado',
    provider_quota_status_no_key: 'sem chave',
    provider_quota_status_invalid_key: 'chave inválida',
    provider_quota_status_unsupported: 'não compatível',
    provider_quota_used_meta: '{0} usado',
    provider_quota_resets_meta: 'reinicia {0}',
    provider_quota_credential_pool: 'Pool de credenciais',
    provider_quota_credential_label: 'Credencial {0}',
    provider_quota_pool_plans: 'Planos: {0}',
    provider_quota_pool_no_windows: 'Nenhuma janela de limite da conta informada.',
    provider_quota_account_limits_loaded: 'Limites da conta carregados.',
    provider_quota_unavailable: 'Status da cota indisponível',
    provider_quota_retry_after: 'Tente novamente após {0}',
    provider_quota_pool_summary_available: '{0}/{1} disponíveis',
    provider_quota_pool_summary_exhausted: '{0} esgotadas',
    provider_quota_pool_summary_failed: '{0} com falha',
    provider_quota_pool_summary_checked: '{0} verificadas',
    cancel: 'Cancelar',
    create_job: 'Criar tarefa',
    save_skill: 'Salvar skill',
    editing: 'Editando',
    // Empty state
    empty_title: 'Como posso ajudar?',
    empty_subtitle: 'Pergunte qualquer coisa, rode comandos, explore arquivos ou gerencie tarefas.',
    suggest_files: 'Quais arquivos estão neste workspace?',
    suggest_schedule: 'O que tenho na agenda hoje?',
    suggest_plan: 'Me ajude a planejar um pequeno projeto.',
    // onboarding
    onboarding_badge: 'PRIMEIRO ACESSO',
    onboarding_title: 'Bem-vindo ao Hermes Web UI',
    onboarding_lead: 'Uma configuração rápida vai verificar Hermes, salvar provedor, escolher workspace e modelo, e opcionalmente proteger com senha.',
    onboarding_back: 'Voltar',
    onboarding_continue: 'Continuar',
    onboarding_skip: 'Pular configuração',
    onboarding_skipped: 'Configuração pulada — usando config existente.',
    onboarding_open: 'Abrir Hermes',
    onboarding_step_system_title: 'Verificação do sistema',
    onboarding_step_system_desc: 'Verificar Hermes Agent e visibilidade da config.',
    onboarding_step_setup_title: 'Configuração do provedor',
    onboarding_step_setup_desc: 'Salvar config mínima do provedor Hermes.',
    onboarding_step_workspace_title: 'Workspace + modelo',
    onboarding_step_workspace_desc: 'Escolher padrões para novas sessões e chat.',
    onboarding_step_password_title: 'Senha opcional',
    onboarding_step_password_desc: 'Proteger Web UI antes de compartilhar.',
    onboarding_step_finish_title: 'Finalizar',
    onboarding_step_finish_desc: 'Revisar e entrar no app.',
    onboarding_notice_system_ready: 'Hermes Agent parece acessível pela Web UI.',
    onboarding_notice_system_unavailable: 'Hermes Agent não está totalmente disponível. Bootstrap pode instalar, mas setup do provedor pode requerer terminal.',
    onboarding_check_agent: 'Hermes Agent',
    onboarding_check_agent_ready: 'Detectado e importável',
    onboarding_check_agent_missing: 'Ausente ou parcialmente importável',
    onboarding_check_password: 'Senha',
    onboarding_check_password_enabled: 'Já ativada',
    onboarding_check_password_disabled: 'Não ativada ainda',
    onboarding_check_provider: 'Config do provedor',
    onboarding_check_provider_ready: 'Pronto para conversar',
    onboarding_check_provider_partial: 'Salvo mas incompleto',
    onboarding_check_provider_pending: 'Precisa verificação',
    onboarding_config_file: 'Arquivo de config:',
    onboarding_env_file: 'Arquivo .env:',
    onboarding_unknown: 'Desconhecido',
    onboarding_current_provider: 'Config atual:',
    onboarding_missing_imports: 'Imports ausentes:',
    onboarding_notice_setup_required: 'Escolha caminho simples de provedor aqui. OAuth avançado ainda pertence ao Hermes CLI.',
    onboarding_notice_setup_already_ready: 'Setup de provedor Hermes já detectado. Pode manter ou substituir.',
    onboarding_oauth_provider_ready_title: 'Provedor já autenticado',
    onboarding_oauth_provider_ready_body: 'Esta instância usa provedor OAuth (<strong>{provider}</strong>) configurado via CLI. Sem API key necessária.',
    onboarding_oauth_provider_not_ready_title: 'Provedor OAuth não autenticado',
    onboarding_oauth_provider_not_ready_body: 'Esta instância usa <strong>{provider}</strong> com OAuth. Rode `hermes auth` no terminal.',
    onboarding_oauth_switch_hint: 'Ou escolha provedor diferente abaixo para trocar para API-key:',
    onboarding_notice_workspace: 'Estes valores reusam as mesmas APIs de settings do app normal.',
    onboarding_workspace_label: 'Workspace',
    onboarding_workspace_or_path: 'Ou digite path do workspace',
    onboarding_workspace_placeholder: '/home/voce/workspace',
    onboarding_provider_label: 'Modo de setup',
    onboarding_quick_setup_badge: 'setup rápido',
    provider_category_easy_start: 'Início fácil',
    provider_category_self_hosted: 'Open / self-hosted',
    provider_category_specialized: 'Especializado',
    onboarding_api_key_label: 'API key',
    oauth_login_codex: 'Login with Codex (ChatGPT)', // TODO: translate
    oauth_codex_step1: 'Step 1: Visit this URL and enter the code', // TODO: translate
    oauth_codex_step2: 'Step 2: Enter this code on the page', // TODO: translate
    oauth_codex_polling: 'Waiting for authorization...', // TODO: translate
    oauth_codex_success: 'Codex OAuth login successful!', // TODO: translate
    oauth_codex_error: 'OAuth login failed', // TODO: translate
    oauth_codex_expired: 'Code expired, please try again', // TODO: translate
    onboarding_api_key_placeholder: 'Deixe em branco para manter key existente',
    onboarding_api_key_label_optional: 'API key (optional)', // TODO: translate
    onboarding_api_key_placeholder_optional: 'Leave blank for keyless servers', // TODO: translate
    onboarding_api_key_help_keyless: 'Most LM Studio / Ollama / vLLM installs run keyless — leave this blank if your server doesn\'t require authentication. Use the Test connection button to verify.', // TODO: translate
    onboarding_api_key_help_prefix: 'Salvo como segredo no .env do Hermes usando',
    onboarding_base_url_label: 'Base URL',
    onboarding_base_url_placeholder: 'https://seu-endpoint.exemplo/v1',
    onboarding_base_url_help: 'Use para endpoints OpenAI-compatible, self-hosted, LiteLLM, Ollama, LM Studio, vLLM.',
    onboarding_model_label: 'Modelo padrão',
    onboarding_workspace_help: 'Escolha modelo que Hermes deve usar para novos chats.',
    onboarding_custom_model_placeholder: 'nome-do-seu-modelo',
    onboarding_custom_model_help: 'Para endpoints customizados, digite ID exato que seu servidor espera.',
    onboarding_notice_password_enabled: 'Senha já configurada. Digite nova apenas se quiser substituir.',
    onboarding_notice_password_recommended: 'Opcional mas recomendado se expor UI além de localhost.',
    onboarding_password_label: 'Senha (opcional)',
    onboarding_password_placeholder: 'Deixe em branco para pular',
    onboarding_password_help: 'Senhas são salvas via settings API e hasheadas no servidor.',
    onboarding_notice_finish: 'Pode reabrir Configurações depois para mudar qualquer coisa.',
    onboarding_not_set: 'Não definido',
    onboarding_password_will_enable: 'Será ativada',
    onboarding_password_will_replace: 'Será substituída',
    onboarding_password_keep_existing: 'Manter senha atual',
    onboarding_password_remains_disabled: 'Permanecerá desativada',
    onboarding_password_skipped: 'Pulado por enquanto',
    onboarding_finish_help: 'Finalizar guarda <code>onboarding_completed</code> em settings e leva ao app normal.',
    onboarding_error_choose_workspace: 'Escolha workspace antes de continuar.',
    onboarding_error_choose_model: 'Escolha modelo antes de continuar.',
    onboarding_error_provider_required: 'Escolha modo de setup antes de continuar.',
    onboarding_error_base_url_required: 'Base URL é necessária para endpoints customizados.',
    onboarding_probe_test_button: 'Test connection', // TODO: translate
    onboarding_probe_probing: 'Testing connection…', // TODO: translate
    onboarding_probe_ok: 'Connected. {n} model(s) available.', // TODO: translate
    onboarding_probe_error_generic: 'Could not reach the configured base URL.', // TODO: translate
    onboarding_probe_error_invalid_url: 'Base URL must start with http:// or https://.', // TODO: translate
    onboarding_probe_error_dns: 'Could not resolve the host. Check the URL or use the host\'s IP address.', // TODO: translate
    onboarding_probe_error_connect_refused: 'Connection refused — the server may not be running on that address. From inside Docker, try the host IP instead of localhost.', // TODO: translate
    onboarding_probe_error_timeout: 'The endpoint did not respond in time. Check that the server is running and the URL is correct.', // TODO: translate
    onboarding_probe_error_http_4xx: 'The endpoint returned a client error. Check authentication and the URL path (typically ends in /v1).', // TODO: translate
    onboarding_probe_error_http_5xx: 'The endpoint returned a server error. Check the LM Studio / Ollama server logs.', // TODO: translate
    onboarding_probe_error_parse: 'The endpoint did not return a model list in the expected shape. Verify the URL points to the OpenAI-compatible API root.', // TODO: translate
    onboarding_probe_error_unreachable: 'Could not reach the configured base URL.', // TODO: translate
    onboarding_error_probe_failed: 'Could not validate the configured base URL.', // TODO: translate
    onboarding_error_workspace_required: 'Workspace é necessário.',
    onboarding_error_model_required: 'Modelo é necessário.',
    onboarding_complete: 'Configuração completa',

    // panel/runtime i18n
    error_prefix: 'Erro: ',
    not_available: 'N/D',
    never: 'nunca',
    add: 'Adicionar',
    add_failed: 'Falha ao adicionar: ',
    remove_failed: 'Falha ao remover: ',
    switch_failed: 'Falha ao trocar: ',
    name_required: 'Nome é necessário',
    content_required: 'Conteúdo é necessário',
    view: 'Ver',
    dismiss: 'Dispensar',
    disable: 'Desativar',
    cron_no_jobs: 'Nenhuma tarefa agendada encontrada.',
    cron_status_off: 'desligado',
    cron_status_paused: 'pausado',
    cron_status_error: 'erro',
    cron_status_active: 'ativo',
    cron_status_running: 'rodando…',
    cron_status_needs_attention: 'precisa atenção',
    cron_attention_desc: 'Esta tarefa não tem próxima execução. Scheduler pode não ter calculado.',
    cron_attention_croniter_hint: 'Gateway pode não ter pacote croniter. Reinicie com cron support.',
    cron_attention_resume: 'Retomar e recalcular',
    cron_jobs_project: 'Tarefas Agendadas',
    cron_attention_run_once: 'Rodar uma vez agora',
    cron_attention_copy_diagnostics: 'Copiar diagnóstico',
    cron_diagnostics_copied: 'Diagnóstico copiado',
    cron_next: 'Próxima',
    cron_last: 'Última',
    cron_run_now: 'Rodar agora',
    cron_pause: 'Pausar',
    cron_resume: 'Retomar',
    cron_job_name_placeholder: 'Nome da tarefa',
    cron_schedule_placeholder: 'Agendamento',
    cron_prompt_placeholder: 'Prompt',
    cron_last_output: 'Último output',
    cron_expand_prompt: 'Expandir prompt',
    cron_collapse_prompt: 'Contraer prompt',
    cron_expand_output: 'Expandir saída',
    cron_collapse_output: 'Contraer saída',
    cron_all_runs: 'Todas execuções',
    cron_hide_runs: 'Esconder execuções',
    cron_no_runs_yet: '(sem execuções ainda)',
    cron_schedule_required_example: 'Agendamento necessário (ex: "0 9 * * *" ou "every 1h")',
    cron_schedule_required: 'Agendamento é necessário',
    cron_prompt_required: 'Prompt é necessário',
    cron_job_created: 'Tarefa criada',
    cron_job_triggered: 'Tarefa acionada',
    cron_job_paused: 'Tarefa pausada',
    cron_job_resumed: 'Tarefa retomada',
    cron_job_updated: 'Tarefa atualizada',
    cron_delete_confirm_title: 'Excluir tarefa cron',
    cron_delete_confirm_message: 'Isso não pode ser desfeito.',
    cron_job_deleted: 'Tarefa excluída',
    cron_completion_status: (name, status) => `Cron "${name}" ${status}`,
    status_failed: 'falhou',
    status_completed: 'completou',
    todos_no_active: 'Nenhuma lista de tarefas ativa nesta sessão.',
    clear_conversation_title: 'Limpar conversa',
    clear_conversation_message: 'Limpar todas mensagens? Isso não pode ser desfeito.',
    clear_failed: 'Falha ao limpar: ',
    skills_no_match: 'Nenhuma skill corresponde.',
    linked_files: 'Arquivos vinculados',
    skill_load_failed: 'Não foi possível carregar skill: ',
    skill_file_load_failed: 'Não foi possível carregar arquivo: ',
    skills_empty_title: 'Selecione uma skill',
    skills_empty_sub: 'Escolha skill da sidebar para ver conteúdo, ou crie nova.',
    skills_edit: 'Editar',
    skills_delete: 'Excluir',
    skills_back_to: 'Voltar para {0}',
    tasks_empty_title: 'Selecione tarefa agendada',
    tasks_empty_sub: 'Escolha tarefa da sidebar para ver detalhes e execuções.',
    workspaces_empty_title: 'Selecione um space',
    workspaces_empty_sub: 'Escolha space da sidebar para ver arquivos e settings.',
    profiles_empty_title: 'Selecione um perfil',
    profiles_empty_sub: 'Escolha perfil da sidebar para ver e editar settings.',
    memory_notes_label: 'memória (notas)',
    memory_saved: 'Memória salva',
    my_notes: 'Minhas Notas',
    user_profile: 'Perfil do Usuário',
    no_notes_yet: 'Nenhuma nota ainda.',
    no_profile_yet: 'Nenhum perfil definido.',
    agent_soul: 'Alma do Agente',
    no_soul_yet: 'Nenhuma alma definida.',
    // skill form
    skill_name: 'Nome',
    skill_category: 'Categoria',
    skill_category_placeholder: 'Opcional, ex: devops',
    skill_content: 'Conteúdo SKILL.md',
    skill_content_placeholder: 'YAML frontmatter + markdown body',
    skill_rename_not_supported: 'Renomear skill não suportado. Crie nova e exclua antiga.',
    skill_metadata: 'Metadados',
    // cron form
    cron_name_label: 'Nome',
    cron_name_placeholder: 'Opcional',
    cron_schedule_label: 'Agendamento',
    cron_schedule_hint: "Use 'every 1h' ou uma expressão Cron para tarefas recorrentes. Durações como '30m' rodam uma vez.",
    cron_schedule_once_warning: "Durações como '30m' rodam uma vez e são removidas após executar. Use 'every 30m' para manter uma tarefa recorrente.",
    cron_prompt_label: 'Prompt',
    cron_deliver_label: 'Entregar output para',
    cron_deliver_local: 'Local (salvar output apenas)',
    cron_profile_label: 'Perfil',
    cron_profile_server_default: 'padrão do servidor',
    cron_profile_server_default_hint: 'Usa o perfil padrão do servidor WebUI no momento da execução. Tarefas existentes sem perfil mantêm esse comportamento legado.',
    cron_toast_notifications_label: 'Toasts de conclusão',
    cron_toast_notifications_hint: 'Mostra um toast quando este cron termina. O emblema de Tarefas e o marcador de nova execução ainda são atualizados quando desligado.',
    cron_toast_notifications_enabled: 'Ativado',
    cron_toast_notifications_disabled: 'Desativado',
    cron_deliver_origin: 'Origem (mesmo chat)',
    cron_deliver_telegram: 'Telegram',
    cron_deliver_discord: 'Discord',
    cron_skills_label: 'Skills',
    cron_skills_placeholder: 'Adicionar skills (opcional)…',
    cron_skills_edit_hint: 'Lista de skills não editável após criação.',
    // workspace form
    workspace_name_label: 'Nome',
    workspace_name_placeholder: 'Nome amigável opcional',
    workspace_path_label: 'Path',
    workspace_path_required: 'Path é necessário',
    workspace_path_readonly: 'Path não pode mudar. Apenas renomear.',
    workspace_new_title: 'Novo space',
    workspace_rename_title: 'Renomear space',
    // profile form
    profile_name_label: 'Nome',
    profile_name_required: 'Nome é necessário',
    profile_name_placeholder: 'ex: Trabalho, Pessoal',
    profile_provider_label: 'Provedor',
    profile_model_label: 'Modelo',
    profile_model_hint: 'Escolha provedores e modelos configurados para este novo perfil.',
    profile_model_use_default: 'Usar o padrão do perfil ativo',
    profile_model_required: 'Modelo é necessário',
    profile_base_url_label: 'Base URL',
    profile_base_url_placeholder: 'Opcional, ex: http://localhost:11434',
    profile_api_key_label: 'API key',
    profile_api_key_placeholder: 'Opcional',
    manage_profiles: 'Gerenciar perfis',
    profiles_load_failed: 'Falha ao carregar perfis',
    profile_switched_new_conversation: (name) => `Trocado para perfil: ${name} — nova conversa iniciada`,
    profile_switched: (name) => `Trocado para perfil: ${name}`,
    profile_delete_confirm: (name) => `Excluir perfil "${name}"?`,
    profile_deleted: 'Perfil excluído',
    profile_delete_failed: 'Falha ao excluir perfil: ',
    profile_create_failed: 'Falha ao criar perfil: ',
    profile_update_failed: 'Falha ao atualizar perfil: ',
    profile_already_exists: 'Perfil já existe',
    // workspace switch dialog
    workspace_switch_prompt_title: 'Trocar workspace',
    workspace_switch_prompt_message: 'Digite path absoluto do workspace para adicionar e trocar.',
    workspace_switch_prompt_confirm: 'Trocar',
    workspace_switch_prompt_placeholder: '/Users/voce/projeto',
    workspace_not_added: 'Workspace não adicionado',
    workspace_already_saved: 'Workspace já salvo — escolha da lista',
    workspace_busy_switch: 'Não pode trocar workspace com agente rodando',
    discard_file_edits_title: 'Descartar edições de arquivo?',
    discard_file_edits_message: 'Trocar workspace descarta edições não salvas no preview.',
    workspace_switched_to: (name) => `Trocado para ${name}`,
    workspace_use: 'Usar',
    workspace_use_title: 'Usar nesta conversa',
    workspace_add_title: 'Adicionar workspace',
    // Approval card
    approval_skip: 'Pular',
    approval_skip_title: 'Pular este prompt de aprovação',
    approval_skip_all: 'Pular todos',
    approval_skip_all_title: 'Pular todos prompts de aprovação nesta sessão',
    // TTS (#499)
    tts_listen: 'Ouvir',
    tts_not_supported: 'Síntese de voz não disponível',
    settings_label_tts: 'Texto para voz nas respostas',
    settings_desc_tts: 'Mostrar botão de alto-falante nas mensagens do assistente',
    settings_label_tts_auto_read: 'Ler respostas automaticamente',
    settings_desc_tts_auto_read: 'Ler automaticamente as respostas do assistente',
    // Composer voice-mode pref (#1488)
    settings_label_voice_mode: 'Hands-free voice mode button',  // TODO: translate
    settings_desc_voice_mode: 'Show the voice-mode button (audio waveform) next to the dictation mic. Lets you speak naturally — Hermes auto-sends after a pause and reads replies aloud. Requires a browser that supports both speech recognition and TTS.',  // TODO: translate
    settings_label_tts_voice: 'Voz',
    settings_desc_tts_voice: 'Selecionar voz para síntese de voz',
    settings_label_tts_rate: 'Velocidade da fala',
    settings_label_tts_pitch: 'Tom da fala',
    checkpoint_date: 'Date',  // TODO: translate
    checkpoint_diff_files_changed: (n) => `${n} file${n === 1 ? '' : 's'} changed`,  // TODO: translate
    checkpoint_diff_no_changes: 'No differences found between this checkpoint and the current workspace.',  // TODO: translate
    checkpoint_diff_title: 'Changes in checkpoint',  // TODO: translate
    checkpoint_empty: 'No checkpoints found for this workspace.',  // TODO: translate
    checkpoint_error: 'Failed to load checkpoints',  // TODO: translate
    checkpoint_files: 'Files',  // TODO: translate
    checkpoint_loading: 'Loading checkpoints…',  // TODO: translate
    checkpoint_message: 'Message',  // TODO: translate
    checkpoint_restore: 'Restore',  // TODO: translate
    checkpoint_restore_confirm_message: (ckpt) => `Restore workspace to checkpoint "${ckpt}"? This will overwrite files with the saved versions. Files added after this checkpoint will not be deleted.`,  // TODO: translate
    checkpoint_restore_confirm_title: 'Restore checkpoint?',  // TODO: translate
    checkpoint_restored: 'Checkpoint restored',  // TODO: translate
    checkpoint_title: 'Checkpoints',  // TODO: translate
    checkpoint_view_diff: 'View diff',  // TODO: translate
    insights_activity_by_day: 'Activity by Day',  // TODO: translate
    insights_activity_by_hour: 'Activity by Hour',  // TODO: translate
    insights_cost: 'Estimated Cost',  // TODO: translate
    insights_footer: 'Showing data from the last {days} days',  // TODO: translate
    insights_input_tokens: 'Input',  // TODO: translate
    insights_messages: 'Messages',  // TODO: translate
    insights_models: 'Models',  // TODO: translate
    insights_no_cost: 'N/A',  // TODO: translate
    insights_output_tokens: 'Output',  // TODO: translate
    insights_peak_hour: 'Peak: {hour}',  // TODO: translate
    insights_sessions: 'Sessions',  // TODO: translate
    insights_title: 'Usage Analytics',  // TODO: translate
    insights_token_breakdown: 'Token Breakdown',  // TODO: translate
    insights_tokens: 'Tokens',  // TODO: translate
    insights_total: 'Total',  // TODO: translate
    settings_desc_api_redact: 'Self-hosted users can disable for transparency (not recommended for shared instances).',  // TODO: translate
    settings_label_api_redact: 'Redact sensitive data in API responses',  // TODO: translate
    voice_error: 'Voice not supported in this browser',  // TODO: translate
    voice_listening: 'Listening…',  // TODO: translate
    voice_mode_active: 'Voice mode on',  // TODO: translate
    voice_mode_off: 'Voice mode off',  // TODO: translate
    voice_speaking: 'Speaking…',  // TODO: translate
    voice_thinking: 'Thinking…',  // TODO: translate
    // Composer voice buttons (#1488)
    voice_dictate: 'Dictate',  // TODO: translate
    voice_dictate_active: 'Stop dictation',  // TODO: translate
    voice_mode_toggle: 'Voice mode',  // TODO: translate
    voice_mode_toggle_active: 'Exit voice mode',  // TODO: translate
    subagent_children: 'Subagent sessions',  // TODO: translate
    // login-flow keys (issue #1442)
    sign_out_failed: 'Falha ao sair: ',
    auth_disabled: 'Autenticação desativada — proteção por senha removida',
    disable_auth_confirm_title: 'Desativar proteção por senha',
  },
  ko: {
    offline_title: '연결이 끊겼습니다',
    offline_browser_detail: '브라우저가 이 장치가 오프라인이라고 보고합니다.',
    offline_network_detail: '현재 이 브라우저에서 Hermes에 연결할 수 없습니다.',
    offline_autorefresh: 'Hermes에 다시 연결되면 이 페이지를 자동으로 새로고침합니다.',
    offline_check_now: '지금 확인',
    offline_checking: '확인 중…',
    offline_stream_waiting: '연결이 끊겼습니다. 새로고침을 기다리는 중…',
    _lang: 'ko',
    _label: '한국어',
    _speech: 'ko-KR',
    // boot.js
    cancelling: '취소 중\u2026',
    cancel_failed: '취소 실패: ',
    mic_denied: '마이크 접근이 거부되었습니다. 브라우저 권한을 확인하세요.',
    mic_no_speech: '음성이 감지되지 않았습니다. 다시 시도하세요.',
    mic_network: '음성 인식을 사용할 수 없습니다.',
    mic_error: '음성 입력 오류: ',
    session_imported: '세션을 가져왔습니다',
    import_failed: '가져오기 실패: ',
    import_invalid_json: '잘못된 JSON입니다',
    image_pasted: '붙여넣은 이미지: ',
    // messages.js
    edit_message: '메시지 편집',
    regenerate: '응답 다시 생성',
    copy: '복사',
    copied: '복사됨!',
    copy_failed: '복사 실패',
    selected_text_reply: '선택 항목으로 답장',
    selected_text_reply_title: '선택한 채팅 텍스트를 인용 컨텍스트로 추가',
    selected_text_reply_appended: '선택한 텍스트가 입력창에 추가되었습니다',

    diff_loading: 'diff 불러오는 중',
    diff_error: '패치 파일을 로드할 수 없습니다',
    diff_too_large: '패치 파일이 너무 커서 인라인으로 표시할 수 없습니다',
    tree_view: 'Tree',
    raw_view: 'Raw',
    parse_failed_note: 'parse failed',
    you: '나',
    mcp_servers_title: 'MCP Servers',
    mcp_servers_desc: 'Manage Model Context Protocol servers configured in config.yaml.',
    mcp_no_servers: 'No MCP servers configured.',
    mcp_add_server: '+ Add Server',
    mcp_field_name: 'Server Name',
    mcp_transport_label: 'Transport Type',
    mcp_field_command: 'Command',
    mcp_field_args: 'Arguments (comma-separated)',
    mcp_field_url: 'URL',
    mcp_field_timeout: 'Timeout (seconds)',
    mcp_save: 'Save',
    mcp_cancel: 'Cancel',
    mcp_name_required: 'Server name is required.',
    mcp_url_required: 'URL is required for HTTP transport.',
    mcp_command_required: 'Command is required for stdio transport.',
    mcp_saved: 'MCP server saved.',
    mcp_save_failed: 'Failed to save MCP server.',
    mcp_delete_confirm_title: 'Delete MCP Server',
    mcp_delete_confirm_message: 'Delete MCP server "{0}"? This cannot be undone.',
    mcp_deleted: 'MCP server deleted.',
    mcp_delete_failed: 'Failed to delete MCP server.',
    mcp_load_failed: 'Failed to load MCP servers.',
    mcp_restart_hint: 'Server changes are read-only here for now. Edit config.yaml and restart Hermes for changes to take effect.',
    mcp_toggle_followup: 'Enable/disable controls are intentionally deferred until MCP reload semantics are explicit.',
    mcp_status_active: 'Active',
    mcp_status_configured: 'Configured',
    mcp_status_disabled: 'Disabled',
    mcp_status_invalid_config: 'Invalid config',
    mcp_status_unknown: 'Unknown',
    mcp_tool_count: '{0} tools',
    mcp_enabled_yes: 'Enabled',
    mcp_enabled_no: 'Disabled',
    mcp_tools_title: 'MCP Tools',
    mcp_tools_desc: 'Search known tools across active MCP servers.',
    mcp_tools_search_placeholder: 'Search tools by name, server, or description…',
    mcp_tools_no_tools: 'No MCP tools are available from the active runtime inventory.',
    mcp_tools_no_matches: 'No MCP tools match your search.',
    mcp_tools_load_failed: 'Failed to load MCP tools.',
    mcp_tools_schema_empty: 'No schema parameters.',
    mcp_tools_runtime_note: 'Tool inventory only uses already-known active MCP runtime data; the WebUI does not start or probe servers.',
    mcp_tools_summary_no_matches: (query,total) => `No MCP tools matching “${query}” (${total} total MCP tools).`,
    mcp_tools_summary_none: 'No MCP tools to show.',
    mcp_tools_summary_matching: (query) => ` matching “${query}”`,
    mcp_tools_summary_total_note: (total) => ` (${total} total MCP tools)`,
    mcp_tools_summary_showing: (start,end,filtered,searchNote,totalNote,page,pages) => `Showing ${start}-${end} of ${filtered} MCP tools${searchNote}${totalNote}. Page ${page} of ${pages}.`,
    mcp_tools_page_size_prefix: 'Show',
    mcp_tools_page_size_suffix: 'per page',
    mcp_tools_per_page_aria: 'MCP tools per page',
    mcp_tools_inactive_configured_servers: (servers) => `Configured but inactive in this WebUI runtime: ${servers}.`,
    mcp_tools_pagination_label: 'MCP tools pagination',
    mcp_tools_previous_page: '‹ Prev',
    mcp_tools_previous_page_aria: 'Previous MCP tools page',
    mcp_tools_next_page: 'Next ›',
    mcp_tools_next_page_aria: 'Next MCP tools page',
    thinking: '생각 중',
    expand_all: '모두 펼치기',
    collapse_all: '모두 접기',
    edit_failed: 'Edit failed: ',
    regen_failed: 'Regenerate failed: ',
    reconnect_active: 'A response is still being generated. Reload when ready?',
    reconnect_finished: 'A response was in progress when you last left. Messages may have updated.',
    // approval card
    approval_heading: '승인 필요',
    approval_desc_prefix: '위험한 명령이 감지되었습니다',
    approval_btn_once: '한 번 허용',
    approval_btn_once_title: '이 명령만 허용(Enter)',
    approval_btn_session: '세션 허용',
    approval_btn_session_title: '이 대화 세션 동안 허용',
    approval_btn_always: '항상 허용',
    approval_btn_always_title: '이 명령 패턴을 항상 허용',
    approval_btn_deny: '거부',
    approval_btn_deny_title: '거부 — 이 명령을 실행하지 않음',
    approval_responding: '응답 중\u2026',
    clarify_heading: '확인 필요',
    clarify_hint: '선택지를 고르거나 아래에 직접 입력하세요.',
    clarify_other: '기타',
    clarify_send: '보내기',
    clarify_input_placeholder: '응답을 입력하세요…',
    clarify_responding: '응답 중\u2026',
    untitled: '제목 없음',
    n_messages: (n) => `${n}개 메시지`,
    load_older_messages: '↑ 위로 스크롤하거나 클릭하여 이전 메시지 불러오기',
    session_jump_start: '시작',
    session_jump_start_label: '세션 시작으로 이동',
    session_jump_end: '끝',
    session_jump_end_label: '세션 끝으로 이동',
    jump_to_question: '질문으로',
    jump_to_question_label: '이 응답의 질문으로 이동',
    queued_label: 'Sends after response',
    queued_count: (n) => n === 1 ? '1 queued' : `${n} queued`,
    queued_cancel: 'Cancel queued message',
    model_unavailable: ' (unavailable)',
    model_unavailable_title: 'This model is no longer in your current provider list',
    provider_mismatch_warning: (m,p)=>`"${m}" may not work with your configured provider (${p}). Send anyway, or run \`hermes model\` in your terminal to switch.`,
    provider_mismatch_label: 'Provider mismatch',
    model_not_found_label: 'Model not found',
    model_custom_label: 'Custom model ID',
    model_custom_placeholder: 'e.g. openai/gpt-5.4',
    model_search_placeholder: 'Search models…',
    session_toolsets: 'Session Toolsets', // TODO: translate
    session_toolsets_desc: 'Restrict available tools for this session (blank = use global config)', // TODO: translate
    session_toolsets_global: 'Global (default)', // TODO: translate
    session_toolsets_custom: 'Custom', // TODO: translate
    session_toolsets_placeholder: 'tool1, tool2, \u2026', // TODO: translate
    session_toolsets_apply: 'Apply', // TODO: translate
    session_toolsets_clear: 'Clear (use global)', // TODO: translate
    session_toolsets_applied: 'Toolsets updated', // TODO: translate
    session_toolsets_cleared: 'Toolsets cleared — using global config', // TODO: translate
    session_toolsets_failed: 'Failed to update toolsets: ', // TODO: translate
    model_search_no_results: 'No models found',
    model_group_configured: '구성됨',
    ws_search_placeholder: '워크스페이스 검색…',
    ws_no_results: '워크스페이스를 찾을 수 없습니다',
    workspace_new_worktree_conversation: 'worktree에서 새 대화',
    workspace_new_worktree_conversation_meta: '이 워크스페이스용 격리된 git worktree를 만듭니다.',
    workspace_worktree_created: 'worktree 대화가 생성되었습니다',
    workspace_worktree_failed: 'worktree 생성 실패: ',
    session_worktree_badge: 'Worktree',
    model_scope_advisory: '다음 메시지부터 이 대화에 적용됩니다.',
    model_scope_toast: '다음 메시지부터 이 대화에 적용됩니다.',
    // commands.js
    cmd_clear: '대화 메시지 지우기',
    cmd_compress: 'Manually compress conversation context (usage: /compress [focus topic])',
    ctx_compress_hint: '\ucee8\ud14d\uc2a4\ud2b8 \uc555\ucd95\ud558\uba70 \uacf5\uac04 \ud655\ubcf4 →',
    ctx_compress_action: '\u26a0 \uc9c0\uae08 \uc555\ucd95\ud558\uba70 \ucee8\ud14d\uc2a4\ud2b8 \ud655\ubcf4',
    cmd_compact_alias: 'Legacy alias for /compress',
    cmd_model: '모델 전환(예: /model gpt-4o)',
    cmd_workspace: '이름으로 워크스페이스 전환',
    cmd_terminal: '워크스페이스 터미널 열기',
    cmd_new: '새 채팅 세션 시작',
    cmd_usage: '토큰 사용량 표시 켜기/끄기',
    cmd_theme: 'Switch appearance (theme: system/dark/light, skin: default/ares/mono/slate/poseidon/sisyphus/charizard/sienna/catppuccin/nous/geist-contrast)',
    cmd_personality: 'Switch agent personality',
    cmd_skills: 'List available Hermes skills',
    available_commands: '사용 가능한 명령:',
    type_slash: '/ 를 입력해 명령 보기',
    conversation_cleared: '대화를 지웠습니다',
    command_label: '명령',
    context_compaction_label: 'Context compaction',
    retrieval_context_label: 'Indexed context',
    retrieval_context_preview: 'Earlier messages are stored and retrievable with context tools',
    preserved_task_list_label: '보존된 작업 목록',
    reference_only_label: 'Reference only',
    model_usage: 'Usage: /model <name>',
    no_model_match: 'No model matching "',
    switched_to: 'Switched to ',
    workspace_usage: 'Usage: /workspace <name>',
    no_workspace_match: 'No workspace matching "',
    switched_workspace: 'Switched to workspace: ',
    workspace_switch_failed: 'Workspace switch failed: ',
    new_session: '새 세션을 만들었습니다',
    new_session_creating: '새 대화를 만드는 중…',
    compressing: 'Requesting context compression...',
    compress_running_label: 'Compressing',
    compress_complete_label: 'Compression complete',
    auto_compress_label: '자동 압축',
    compress_failed_label: 'Compression failed',
    focus_label: 'Focus',
    token_usage_on: 'Token usage on',
    token_usage_off: 'Token usage off',
    usage_cache_hit_detail: '캐시: {0}% 적중({1} 읽기 / {2} 쓰기)',
    usage_cached_percent: '{0}% 캐시됨',
    theme_usage: 'Usage: /theme ',
    theme_set: 'Theme: ',
    no_active_session: '활성 세션 없음',
    cmd_queue: 'Queue a message for the next turn',
    cmd_goal: '지속 목표를 설정하거나 확인',
    goal_evaluating_progress: 'Evaluating goal progress…',
    goal_working_toward: 'Working toward goal…',
    goal_continuing_toast: 'Continuing toward goal…',
    goal_status_none: 'No active goal. Set one with /goal <text>.',
    goal_status_active: (turns, max_turns, goal) => `⊙ Goal (active, ${turns}/${max_turns} turns): ${goal}`,
    goal_status_paused: (turns, max_turns, reason, goal) => `⏸ Goal (paused, ${turns}/${max_turns}${reason ? `, ${reason}` : ''}): ${goal}`,
    goal_status_done: (turns, max_turns, goal) => `✓ Goal done (${turns}/${max_turns}): ${goal}`,
    goal_set: (turns, goal) => `⊙ Goal set (${turns}-turn budget): ${goal}`,
    goal_paused: (goal) => `⏸ Goal paused: ${goal}`,
    goal_resumed: (goal) => `▶ Goal resumed: ${goal}`,
    goal_cleared: 'Goal cleared.',
    goal_no_goal: 'No active goal.',
    goal_achieved: (reason) => `✓ Goal achieved: ${reason}`,
    goal_paused_budget_exhausted: (turns, max_turns) => `⏸ Goal paused — ${turns}/${max_turns} turns used. Use /goal resume to keep going, or /goal clear to stop.`,
    goal_continuing: (turns, max_turns, reason) => `↻ Continuing toward goal (${turns}/${max_turns}): ${reason}`,
    cmd_interrupt: 'Cancel current turn and send a new message',
    cmd_steer: 'Inject a mid-turn correction without interrupting the agent',
    cmd_queue_no_msg: 'Usage: /queue <message>',
    cmd_queue_not_busy: 'No active task — just send normally',
    cmd_queue_confirm: 'Message queued',
    cmd_interrupt_no_msg: 'Usage: /interrupt <message>',
    cmd_interrupt_confirm: 'Interrupted — sending new message',
    cmd_steer_no_msg: 'Usage: /steer <message>',
    cmd_steer_fallback: 'Steer unavailable — queued for next turn instead',
    cmd_steer_delivered: 'Steer delivered — agent will see it on its next tool result',
    steer_leftover_queued: 'Steer queued for next turn',
    busy_steer_fallback: 'Steer unavailable — queued for next turn',
    busy_interrupt_confirm: 'Interrupted — sending new message',
    settings_label_busy_input_mode: '작업 중 입력 방식',
    settings_desc_busy_input_mode: '에이전트가 실행 중일 때 메시지를 보내면 어떻게 처리할지 제어합니다. 대기는 다음 차례까지 기다리고, 중단은 현재 작업을 취소하고 새로 시작하며, 조정은 현재 작업을 중단하지 않고 중간 수정 사항을 전달합니다(에이전트 또는 스트림을 사용할 수 없으면 대기로 전환).',
    settings_label_fade_text_effect: '텍스트 페이드 효과',
    settings_desc_fade_text_effect: '어시스턴트가 응답하는 동안 새로 스트리밍되는 단어를 부드럽게 표시합니다. OpenWebUI와 비슷하며, 최대 성능을 위해 기본값은 꺼짐입니다.',
    settings_busy_input_mode_queue: '후속 메시지 대기',
    settings_busy_input_mode_interrupt: '현재 작업 중단',
    settings_busy_input_mode_steer: '조정(중간 수정)',

    slash_skill_badge: '스킬',
    slash_skill_desc: '이 스킬 실행',
    cmd_stop: '현재 응답 중지',
    cmd_title: '세션 제목 보기 또는 설정',
    cmd_retry: '마지막 메시지 다시 보내기',
    cmd_undo: '마지막 교환 제거',
    cmd_btw: '곁질문하기(임시)',
    cmd_btw_usage: '/btw <질문> — 세션 맥락을 사용해 곁질문하기',
    cmd_background: '백그라운드에서 프롬프트 실행',
    cmd_background_usage: '/background <프롬프트> — 차단하지 않고 병렬 실행',
    btw_asking: '곁질문 중...',
    btw_label: '곁질문 — 기록에 저장되지 않음',
    btw_done: '곁질문 답변 완료',
    btw_no_answer: '답변을 받지 못했습니다.',
    btw_failed: '곁질문 실패: ',
    bg_running: '백그라운드에서 실행 중...',
    bg_complete: '백그라운드 작업 완료',
    bg_label: '백그라운드 결과:',
    bg_no_answer: '(답변 없음)',
    bg_failed: '백그라운드 작업 실패: ',
    undo_exchange: '마지막 교환 실행 취소',
    cmd_status: '세션 정보 표시',
    cmd_voice: '마이크 입력 전환',
    stream_stopped: '응답이 중지되었습니다.',
    no_active_task: '중지할 활성 작업이 없습니다.',
    cancel_unavailable: '취소를 사용할 수 없습니다.',
    retry_failed: '재시도 실패: ',
    undo_failed: '실행 취소 실패: ',
    undid_n_messages: '제거됨',
    undid_messages_suffix: '개 메시지.',
    status_heading: '세션 상태',
    status_session_id: '세션 ID',
    status_title: '제목',
    status_model: '모델',
    status_provider: '제공자',
    status_workspace: '워크스페이스',
    status_personality: '페르소나',
    status_messages: '메시지',
    status_agent_running: '에이전트 실행 중',
    status_profile: '프로필',
    status_hermes_home: 'Hermes 홈',
    status_started: '시작 시간',
    status_tokens: '토큰',
    status_updated: '업데이트됨',
    status_ephemeral: '임시 스냅샷 — 대화 기록에 저장되지 않습니다.',
    status_no_tokens: '사용된 토큰 없음',
    status_unknown: '알 수 없음',
    status_yes: '예',
    status_no: '아니요',
    status_load_failed: '상태를 불러오지 못했습니다: ',
    title_current: '현재 제목',
    title_change_hint: '`/title <새 이름>`으로 이름을 변경하세요.',
    title_set: '제목 설정됨:',
    cmd_webui_only_session: '이 명령은 CLI에서 가져온 세션에서 사용할 수 없습니다.',
    cmd_voice_use_mic: '작성창의 마이크 버튼을 클릭하세요.',
    usage_heading: '토큰 사용량',
    usage_default_model: '기본값',
    usage_unknown: '알 수 없음',
    usage_input_tokens: '입력 토큰',
    usage_output_tokens: '출력 토큰',
    usage_total: '총 토큰',
    usage_estimated_cost: '예상 비용',
    usage_settings_tip: '참고: 비용 추정치는 대략적인 값입니다.',
    usage_load_failed: '사용량을 불러오지 못했습니다: ',
    usage_personality_none: '없음',
    no_personalities: 'No personalities found (add them to ~/.hermes/personalities/)',
    available_personalities: 'Available personalities:',
    personality_switch_hint: '\n\nUse `/personality <name>` to switch, or `/personality none` to clear.',
    personalities_load_failed: 'Failed to load personalities',
    personality_cleared: 'Personality cleared',
    personality_set: 'Personality: ',
    failed_colon: 'Failed: ',
    // ui.js
    no_workspace: 'No workspace',
    terminal_open_title: '워크스페이스 터미널 열기',
    terminal_no_workspace_title: '터미널을 열 워크스페이스를 선택하세요',
    terminal_title: '터미널',
    terminal_clear: '지우기',
    terminal_copy_output: '출력 복사',
    terminal_restart: '다시 시작',
    terminal_collapse: '접기',
    terminal_expand: '펼치기',
    terminal_close: '닫기',
    terminal_input_placeholder: '명령 입력...',
    terminal_start_failed: '터미널 시작 실패: ',
    terminal_input_failed: '터미널 입력 실패: ',
    terminal_copy_failed: '복사 실패: ',
    terminal_error: '터미널 오류',
    workspace_empty_no_path: 'No workspace selected. Set a workspace in Settings \u2192 Workspace to browse files.',
    workspace_empty_dir: 'This workspace is empty.',
    workspace_show_hidden_files: '숨김 파일 표시',
    workspace_show_hidden_files_desc: 'Include .DS_Store, .git, node_modules, and other hidden / system files in the file tree.',
    workspace_hidden_files_visible: 'hidden visible',
    workspace_hidden_files_visible_title: 'Hidden files are visible — click for options',
    workspace_options: 'Workspace options',
    dialog_confirm_title: 'Confirm action',
    dialog_prompt_title: 'Enter a value',
    dialog_confirm_btn: 'Confirm',
    // workspace.js
    unsaved_confirm: 'You have unsaved changes in the preview. Discard and navigate?',
    discard: '버리기',
    save: '저장',
    edit: '편집',
    clear: '지우기',
    create: '만들기',
    remove: '제거',
    save_title: 'Save changes',
    edit_title: 'Edit this file',
    saved: '저장됨',
    save_failed: '저장 실패: ',
    image_load_failed: 'Could not load image',
    file_open_failed: 'Could not open file',
    downloading: (name) => `Downloading ${name}\u2026`,
    double_click_rename: 'Double-click to rename',
    renamed_to: 'Renamed to ',
    rename_failed: 'Rename failed: ',
    delete_title: '삭제',
    delete_confirm: (name) => `${name}을(를) 삭제할까요?`,
    delete_dir_confirm: (name) => `"${name}" 폴더와 모든 내용을 삭제할까요?`,
    rename_title: '이름 바꾸기',
    rename_prompt: '새 이름:',
    deleted: '삭제됨: ',
    delete_failed: '삭제 실패: ',
    reveal_in_finder: '파일 관리자에서 열기',
    reveal_failed: '표시 실패: ',
    copy_file_path: '파일 경로 복사',
    download_folder: 'Download Folder', // TODO: translate
    path_copied: '파일 경로가 클립보드에 복사되었습니다',
    path_copy_failed: '경로 복사 실패: ',
    session_rename: '대화 이름 변경',
    session_rename_desc: '이 대화의 제목 편집',
    new_file_prompt: 'New file name (e.g. notes.md):',
    project_name_prompt: 'Project name:',
    created: '생성됨: ',
    create_failed: '생성 실패: ',
    new_folder_prompt: 'New folder name:',
    folder_created: 'Created folder ',
    folder_create_failed: 'Create folder failed: ',
    workspace_auto_create_folder: '폴더가 없으면 생성',
    folder_add_as_space_btn: '스페이스로 추가',
    folder_add_as_space_msg: '이 폴더를 워크스페이스 목록의 새 스페이스로 추가할까요?',
    archive_extracted: (n, c) => `${c}개 압축 파일에서 ${n}개 파일 압축 해제됨`,
    folder_add_as_space_title: '스페이스로 추가할까요?',
    remove_title: 'Remove',
    empty_dir: '(비어 있음)',
    upload_failed: 'Upload failed: ',
    upload_too_large: (maxMb, fileMb) => `File is too large (${fileMb} MB). Maximum upload size is ${maxMb} MB.`,
    all_uploads_failed: (n) => `All ${n} upload(s) failed`,
    session_pin: 'Pin conversation',
    session_unpin: 'Unpin conversation',
    session_pin_desc: 'Keep this conversation at the top',
    session_unpin_desc: 'Remove from pinned',
    session_pin_failed: 'Pin failed: ',
    session_move_project: 'Move to project',
    session_move_project_desc_has: 'Change the project for this conversation',
    session_move_project_desc_none: 'Assign a project to this conversation',
    session_archive: 'Archive conversation',
    session_hide_external: '목록에서 숨기기',
    session_restore: 'Restore conversation',
    session_archive_desc: 'Hide this conversation until archived is shown',
    session_archive_worktree_desc: '이 대화를 숨기고 worktree는 디스크에 유지합니다',
    session_hide_external_desc: '원본 기록은 삭제하지 않고 WebUI 목록에서만 숨깁니다.',
    session_restore_desc: 'Bring this conversation back into the main list',
    session_archived: 'Session archived',
    session_archived_worktree: '세션이 보관되었습니다. Worktree는 디스크에 남아 있습니다.',
    session_hidden: '목록에서 숨겼습니다',
    session_restored: 'Session restored',
    session_archive_failed: 'Archive failed: ',
    session_duplicate: 'Duplicate conversation',
    session_duplicate_desc: 'Create a copy with the same workspace and model',
    session_duplicated: 'Session duplicated',
    session_duplicate_failed: 'Duplicate failed: ',
    session_stop_response: 'Stop response',
    session_stop_response_desc: 'Cancel the running response for this conversation',
    session_delete: 'Delete conversation',
    session_delete_desc: 'Permanently remove this conversation',
    session_delete_confirm: '이 대화를 삭제하시겠습니까?',
    session_delete_worktree_desc: 'WebUI 대화만 삭제하고 worktree는 디스크에 유지합니다',
    session_delete_worktree_confirm: (path) => `이 대화를 삭제하시겠습니까? ${path}의 worktree는 디스크에 남아 있습니다.`,
    session_deleted: '대화가 삭제되었습니다',
    session_deleted_worktree: '대화가 삭제되었습니다. Worktree는 디스크에 남아 있습니다.',
    session_worktree_remove: '워크트리 삭제',
    session_worktree_remove_desc: (path) => `${path}의 git worktree를 디스크에서 삭제합니다`,
    session_worktree_remove_confirm: (path) => `git worktree를 디스크에서 삭제하시겠습니까?\n\n경로: ${path}\n\n전체 worktree 디렉토리가 삭제됩니다. 세션 데이터는 WebUI에 보존됩니다.`,
    session_worktree_remove_not_exists: (path) => `${path}의 worktree가 디스크에 더 이상 존재하지 않습니다.`,
    session_worktree_remove_confirm_label: '삭제',
    session_worktree_removed: '워크트리가 삭제되었습니다.',
    session_worktree_remove_failed: '워크트리 삭제 실패: ',
    session_worktree_remove_status_failed: '워크트리 상태 읽기 실패: ',
    session_worktree_remove_locked_by_stream: '삭제할 수 없습니다 — 활성 스트리밍 세션이 이 worktree를 사용 중입니다.',
    session_worktree_remove_locked_by_terminal: '삭제할 수 없습니다 — 활성 터미널 세션이 이 worktree를 사용 중입니다.',
    session_worktree_remove_unsafe_blocked: '이 worktree를 삭제하기 전에 로컬 변경 사항이나 푸시되지 않은 커밋을 정리하세요.',
    session_worktree_remove_dirty_warning: '경고: 이 worktree에는 커밋되지 않은 변경 사항이 있으며 손실됩니다.',
    session_worktree_remove_untracked_warning: (count) => `${count}개의 추적되지 않은 파일이 영구적으로 삭제됩니다.`,
    session_worktree_remove_ahead_warning: (ahead) => `${ahead}개의 푸시되지 않은 커밋이 손실됩니다.`,
    session_select_mode: '선택',
    session_select_mode_desc: '일괄 관리할 대화를 선택하세요',
    session_select_all: '전체 선택',
    session_deselect_all: '전체 해제',
    session_selected_count: '{0}개 선택됨',
    session_batch_archive: '보관',
    session_batch_delete: '삭제',
    session_batch_move: '프로젝트로 이동',
    session_batch_delete_confirm: '{0}개의 대화를 삭제하시겠습니까?',
    session_batch_archive_confirm: '{0}개의 대화를 보관하시겠습니까?',
    session_batch_delete_worktree_confirm: '{0}개의 대화를 삭제하시겠습니까? worktree가 있는 대화 {1}개는 worktree 디렉터리를 디스크에 남깁니다.',
    session_batch_archive_worktree_confirm: '{0}개의 대화를 보관하시겠습니까? worktree가 있는 대화 {1}개는 worktree 디렉터리를 디스크에 유지합니다.',
    session_no_selection: '선택된 대화가 없습니다',
    // settings panel
    settings_heading_title: '제어 센터',
    settings_heading_subtitle: '환경설정, 대화 도구, 시스템 제어.',
    settings_section_conversation_title: '대화',
    settings_section_appearance_title: '외형',
    settings_section_appearance_meta: '테마, 강조 색상, 시각 스타일.',
    settings_section_preferences_title: '환경설정',
    settings_section_preferences_meta: 'Hermes Web UI의 기본값과 UI 동작.',
    settings_section_system_title: '시스템',
    settings_section_system_meta: '인스턴스 버전과 접근 제어.',
    settings_check_now: '지금 확인',
    settings_checking: '확인 중\u2026',
    settings_up_to_date: '최신 상태 \u2713',
    settings_updates_available: '{count} update(s) available',
    settings_updates_disabled: 'Update checks disabled',
    settings_update_check_failed: 'Update check failed',
    settings_label_workspace_panel_open: '기본으로 워크스페이스 패널 열기',
    settings_desc_workspace_panel_open: '활성화하면 새 세션마다 워크스페이스/파일 브라우저 패널이 자동으로 열립니다. 언제든지 수동으로 닫을 수 있습니다.',
    settings_label_session_jump_buttons: '세션 이동 버튼 표시',
    settings_desc_session_jump_buttons: '긴 세션 기록을 읽을 때 떠 있는 시작 및 끝 버튼을 표시합니다.',

    settings_label_session_endless_scroll: '위로 스크롤할 때 이전 메시지 불러오기',

    settings_desc_session_endless_scroll: '활성화하면 위로 스크롤할 때 이전 메시지를 자동으로 불러옵니다. 비활성화하면 이전 메시지 버튼을 사용합니다.',

    settings_label_tab_visibility: '사이드바 탭',
    settings_desc_tab_visibility: '사이드바와 레일에 표시할 탭을 선택하세요. 채팅과 설정은 항상 표시됩니다.',
    open_in_browser: '브라우저에서 열기',
    settings_dropdown_conversation: '대화',
    settings_dropdown_appearance: '외형',
    settings_dropdown_preferences: '환경설정',
    settings_dropdown_providers: 'Providers',
    settings_dropdown_system: '시스템',
    settings_tab_conversation: '대화',
    settings_tab_appearance: '외형',
    settings_tab_preferences: '환경설정',
    settings_tab_plugins: '플러그인',
    settings_plugins_title: 'Plugins',  // TODO: translate
    settings_plugins_meta: 'View installed Hermes plugins and the lifecycle hooks they register. This panel is read-only.',  // TODO: translate
    settings_plugins_empty: 'No Hermes plugins are currently visible. Install or enable plugins from the Hermes CLI/config to see them here.',  // TODO: translate
    plugins_unnamed: 'Unnamed plugin',  // TODO: translate
    plugins_no_description: 'No description provided.',  // TODO: translate
    plugins_no_hooks: 'No registered lifecycle hooks',  // TODO: translate
    plugins_registered_hooks: 'Registered hooks',  // TODO: translate
    plugins_enabled: 'Enabled',  // TODO: translate
    plugins_disabled: 'Disabled',  // TODO: translate
    plugins_active_provider: 'Active (provider)',  // TODO: translate
    plugins_provider_no_hooks: 'Provider plugin — no agent-visibility hooks',  // TODO: translate
    plugins_load_failed: 'Failed to load plugins: ',  // TODO: translate
    settings_tab_system: '시스템',
    settings_title: '설정',
    settings_save_btn: '설정 저장',
    settings_label_model: '기본 모델',
    settings_desc_model: '새 대화에 사용됩니다. 기존 대화는 선택된 모델을 유지합니다.',
    settings_label_send_key: '전송 키',
    settings_label_theme: '테마',
    settings_label_skin: '스킨',
    settings_label_font_size: '글꼴 크기',
    font_size_small: '작게',
    font_size_default: '기본',
    font_size_large: '크게',
    font_size_xlarge: '매우 크게',
    settings_autosave_saving: '저장 중…',
    settings_autosave_saved: '저장됨',
    settings_autosave_failed: '저장 실패',
    settings_autosave_retry: '다시 시도',
    settings_label_language: '언어',
    settings_label_quota_chip: '작성기에 공급자 할당량 칩 표시',
    settings_desc_quota_chip: '작성기 푸터에 남은 할당량 표시기(예: OpenRouter 크레딧 잔액)를 표시합니다. 기본값은 끔. 활성화 시 노트북과 표준 데스크톱에서 작성기가 복잡해지지 않도록 와이드 디스플레이(≥1400px)에서만 표시됩니다.',
    settings_label_hide_suggestions: 'Hide new-chat suggestions',
    settings_desc_hide_suggestions: 'Hide the three default suggestion buttons on the empty new-chat screen to avoid accidental taps.',
    settings_label_token_usage: '토큰 사용량 표시',
    settings_label_sidebar_density: '사이드바 밀도',
    cmd_reasoning: 'Toggle thinking visibility (show/hide), set effort level, or check current status',
    settings_label_external_sessions: '외부 세션 표시',
    settings_label_previous_messaging_sessions: '이전 메시징 세션 표시',
    settings_label_sync_insights: 'Insights에 동기화',
    settings_label_check_updates: '업데이트 확인',
    settings_label_whats_new_summary: "Summarize What's New with AI",
    settings_label_bot_name: '기본 Assistant 이름',
    settings_label_password: '접근 비밀번호',
    settings_saved: '설정 저장됨',
    settings_save_failed: '설정 저장 실패: ',
    settings_load_failed: '설정 로드 실패: ',
    settings_saved_pw: '설정이 저장되었습니다 — 비밀번호 보호가 활성화되었으며 이 브라우저는 로그인 상태로 유지됩니다',
    settings_saved_pw_updated: '설정이 저장되었습니다 — 비밀번호가 업데이트되었습니다',
    // login page (used server-side via /api/i18n/login endpoint)
    login_title: '로그인',
    login_subtitle: '계속하려면 비밀번호를 입력하세요.',
    login_placeholder: '비밀번호',
    login_btn: '로그인',
    login_invalid_pw: '비밀번호가 올바르지 않습니다',
    login_conn_failed: '연결 실패',
    // Sidebar & Tabs
    tab_chat: '채팅',
    tab_tasks: '작업',
    tab_skills: '스킬',
    tab_memory: '메모리',
    tab_workspaces: '공간',
    tab_profiles: 'Agent 프로필',
    tab_kanban: 'Kanban',
    kanban_board: 'Board',
    kanban_visible_tasks: '{0} visible tasks',
    kanban_search_tasks: 'Search tasks',
    kanban_all_assignees: 'All assignees',
    kanban_all_tenants: 'All tenants',
    kanban_include_archived: 'Include archived',
    kanban_no_matching_tasks: 'No matching tasks',
    kanban_no_data: 'No Kanban data',
    kanban_work_queue_hint: 'This is the Hermes Agent work queue. Create or triage a task, assign it, move it to Ready, then let the dispatcher claim it.',
    kanban_unavailable: 'Kanban unavailable',
    kanban_read_only: 'Read-only view',
    kanban_empty: 'Empty',
    kanban_task: 'Task',
    kanban_no_description: 'No description',
    kanban_refresh: 'Refresh',
    kanban_status_triage: 'Triage',
    kanban_status_todo: 'Todo',
    kanban_status_ready: 'Ready',
    kanban_status_running: 'Running',
    kanban_status_blocked: 'Blocked',
    kanban_status_done: 'Done',
    kanban_status_original_hint: 'Actual status: {0}. This dialog only supports Triage/Todo/Ready edits.',
    kanban_comments_count: 'Comments ({0})',
    kanban_events_count: 'Events ({0})',
    kanban_links: 'Links',
    kanban_parents: 'Parents',
    kanban_children: 'Children',
    kanban_runs_count: 'Runs ({0})',
    kanban_no_comments: 'No comments',
    kanban_no_events: 'No events',
    kanban_no_runs: 'No runs',
    kanban_title: '제목',
    kanban_description: '설명',
    kanban_description_placeholder: '선택 — 해야 할 일, 수락 기준, 링크',
    kanban_status: '상태',
    kanban_assignee: '담당자',
    kanban_assignee_placeholder: '선택 — 비워두면 누구나 가능',
    kanban_tenant: '테넌트',
    kanban_tenant_placeholder: '선택 — 프로젝트 또는 팀 슬러그',
    kanban_priority: '우선순위',
    kanban_priority_hint: '높은 숫자가 먼저 실행됩니다. 기본값: 0.',
    kanban_title_required: '제목은 필수입니다.',
    kanban_edit_task: '작업 편집',
    kanban_run_dispatcher: '디스패처 실행',
    kanban_run_dispatcher_confirm: '이 보드의 Ready 작업을 클레임하고 워커 서브프로세스를 생성합니다(클릭당 최대 8개). 계속할까요?',
    kanban_assignee_profiles_label: 'Hermes 프로필',
    kanban_assignee_other_label: '기타 (CLI 레인 / 삭제된 프로필)',
    kanban_assignee_unassigned: '— 미할당 (자동 실행되지 않음) —',
    kanban_ready_needs_assignee: '«미할당» + «Ready»를 선택했습니다. 디스패처는 이 작업을 건너뜁니다. 확인하려면 다시 제출하거나 프로필을 선택하세요.',
    kanban_dispatch_preview_prefix: '미리보기:',
    kanban_dispatch_run_prefix: '디스패치됨:',
    kanban_dispatch_spawned: '생성됨',
    kanban_dispatch_promoted: '승격됨',
    kanban_dispatch_reclaimed: '재요청됨',
    kanban_dispatch_skipped_unassigned: '건너뜀 (담당자 없음)',
    kanban_dispatch_skipped_nonspawnable: '건너뜀 (알 수 없는 프로필)',
    kanban_dispatch_auto_blocked: '자동 차단',
    kanban_dispatch_timed_out: '시간 초과',
    kanban_dispatch_crashed: '충돌',
    kanban_new_task: 'New task',
    kanban_add_comment: 'Add comment',
      kanban_only_mine: 'Only mine',
      kanban_bulk_action: 'Bulk action',
      kanban_nudge_dispatcher: 'Preview dispatcher',
      kanban_stats: 'Stats',
      kanban_worker_log: 'Worker log',
      kanban_block: 'Block',
      kanban_unblock: 'Unblock',
      kanban_back_to_board: 'Back to board',
      kanban_lanes_by_profile: 'Lanes by profile',
      kanban_new_board: 'New board…',
      kanban_rename_board: 'Rename current board…',
      kanban_archive_board: 'Archive current board…',
      kanban_archive_board_confirm: 'Archive board "{name}"? Tasks remain on disk and the board can be restored from kanban/boards/_archived/.',
      kanban_board_archived: 'Board archived',
      kanban_board_name: 'Name',
      kanban_board_slug: 'Slug (lowercase, hyphens)',
      kanban_board_description: 'Description (optional)',
      kanban_board_icon: 'Icon (emoji, optional)',
      kanban_board_color: 'Color (optional)',
      kanban_board_name_required: 'Name is required',
      kanban_board_slug_required: 'Slug is required',
      kanban_card_complete: 'complete',
      kanban_card_archive: 'archive',
      kanban_unassigned: 'unassigned',
    kanban_status_archived: 'Archived',
    tab_todos: 'Todos',
    tab_insights: '통계',
    tab_dashboard: 'Hermes 대시보드',
    dashboard_loopback_warning: '대시보드는 서버에서 loopback 전용입니다. 서버 자체에서 접속하거나 --host 0.0.0.0(안전하지 않음)으로 다시 시작하세요.',
    tab_logs: 'Logs',
    tab_settings: '설정',

    logs_title: 'Logs',  // TODO: translate
    logs_file: 'File',  // TODO: translate
    logs_tail: 'Tail',  // TODO: translate
    logs_auto_refresh: 'Auto-refresh (5s)',  // TODO: translate
    logs_wrap: 'Wrap lines',  // TODO: translate
    logs_copy_all: 'Copy all',  // TODO: translate
    logs_empty: 'No log lines yet.',  // TODO: translate
    logs_loading: 'Loading logs…',  // TODO: translate
    logs_load_failed: 'Logs failed to load',  // TODO: translate
    logs_status_idle: 'Choose a log file to view recent lines.',  // TODO: translate
    logs_no_mtime: 'not written yet',  // TODO: translate
    logs_truncated_hint: 'Showing the tail of a large log file; older bytes were skipped to keep memory bounded.',  // TODO: translate
    logs_copied: 'Logs copied',  // TODO: translate
    logs_severity: '심각도',
    logs_severity_all: '전체',
    logs_severity_errors: '오류',
    logs_severity_warnings: '경고+',
    logs_filter_active: '표시됨(필터 활성)',
    new_conversation: '새 대화',
    filter_conversations: '대화 필터…',
    session_time_unknown: 'Unknown',
    session_time_minutes_ago: (n) => `${n}m`,
    session_time_hours_ago: (n) => `${n}h`,
    session_time_days_ago: (n) => `${n}d`,
    session_time_last_week: '1w',
    session_time_bucket_today: 'Today',
    session_time_bucket_yesterday: 'Yesterday',
    session_time_bucket_this_week: 'This week',
    session_time_bucket_last_week: 'Last week',
    session_time_bucket_older: 'Older',
    scheduled_jobs: '예약 작업',
    new_job: '새 작업',
    loading: '로딩 중...',
    search_skills: 'Search skills...',
    new_skill: 'New skill',
    personal_memory: '개인 메모리',
    current_task_list: '현재 작업 목록',
    workspace_desc: '세션용 워크스페이스를 추가하고 전환합니다.',
    session_meta_messages: (n) => `${n} msg${n === 1 ? '' : 's'}`,
    session_meta_children: (n) => `${n} child${n === 1 ? '' : 'ren'}`,
    session_meta_segments: (n) => `${n} segment${n === 1 ? '' : 's'}`,
    session_lineage_segment_untitled: '제목 없는 세그먼트',
    session_lineage_segment_open: '계보 세그먼트 열기',
    new_profile: 'New profile',
    transcript: '대화 기록',
    download_transcript: 'Download as Markdown',
    import: '가져오기',
    export_session_json: 'JSON',
    export_session_json_tooltip: '전체 세션을 JSON으로 내보내기',
    import_session_json_tooltip: 'JSON에서 세션 가져오기',
    clear_conversation_btn_tooltip: '이 대화의 모든 메시지 지우기',
    // Settings detail
    settings_label_rtl: '오른쪽에서 왼쪽 채팅 레이아웃',
    settings_desc_rtl: '아랍어나 히브리어 같은 언어를 위해 채팅 메시지와 작성 입력의 정렬을 뒤집습니다. 채팅 영역에만 영향을 주며, 사이드바와 다른 패널은 왼쪽에서 오른쪽으로 유지됩니다.',
    settings_label_sound: '알림음',
    settings_desc_sound: 'Assistant 응답이 끝나면 소리를 재생합니다.',
    settings_label_notifications: '브라우저 알림',
    settings_desc_notifications: '앱이 백그라운드에 있을 때 응답이 완료되면 시스템 알림을 표시합니다.',
    settings_desc_token_usage: '각 Assistant 응답 아래에 입력/출력 토큰 수를 표시합니다. /usage로도 전환할 수 있습니다.',
    settings_sidebar_density_compact: '간결',
    settings_sidebar_density_detailed: '자세히',
    settings_desc_sidebar_density: '왼쪽 사이드바의 세션 목록에 표시할 메타데이터 양을 제어합니다.',
    settings_label_auto_title_refresh: '적응형 제목 새로고침',
    settings_auto_title_refresh_off: '꺼짐',
    settings_auto_title_refresh_5: 'Every 5 exchanges',
    settings_auto_title_refresh_10: 'Every 10 exchanges',
    settings_auto_title_refresh_20: 'Every 20 exchanges',
    settings_desc_auto_title_refresh: '최신 대화를 바탕으로 세션 제목을 자동으로 다시 생성해 대화가 진행되어도 제목을 관련 있게 유지합니다. LLM 제목 생성 모델 설정이 필요합니다.',
    settings_desc_external_sessions: 'CLI, Telegram, Discord, Slack 및 기타 채널의 대화를 세션 목록에 표시합니다. 클릭하여 가져오고 계속하세요.',
    settings_desc_previous_messaging_sessions: 'reset 또는 compression으로 교체된 이전 Discord, Telegram, Slack, Weixin 세션을 표시합니다.',
    settings_desc_sync_insights: 'WebUI 토큰 사용량을 state.db에 반영하여 hermes /insights에 브라우저 세션 데이터가 포함되도록 합니다. 기본값은 꺼짐입니다.',
    settings_desc_check_updates: 'WebUI 또는 Agent의 새 버전이 있으면 배너를 표시합니다. 백그라운드에서 주기적으로 git fetch를 실행합니다.',
    settings_desc_whats_new_summary: "Changes the What's New action from opening the raw diff first to generating a short, human-readable summary. The regular diff comparison stays available after the summary.",
    settings_desc_bot_name: '기본 프로필에만 사용됩니다. 다른 프로필은 각 프로필 이름을 사용합니다.',
    settings_desc_password: '새 비밀번호를 설정하거나 변경하려면 입력하세요. 현재 설정을 유지하려면 비워 두세요.',
    password_placeholder: '새 비밀번호 입력…',
    password_env_var_locked: '현재 HERMES_WEBUI_PASSWORD 환경 변수가 설정되어 있어 우선 적용됩니다. 변수를 해제하고 서버를 재시작해야 여기에서 비밀번호를 관리할 수 있습니다.',
    password_env_var_locked_placeholder: '잠금: HERMES_WEBUI_PASSWORD 환경 변수가 설정되어 있습니다',
    disable_auth: '인증 비활성화',
    sign_out: '로그아웃',
    // Providers panel
    providers_tab_title: 'Providers',
    providers_section_title: 'Providers',
    providers_section_meta: 'Manage API keys for AI providers. Changes take effect immediately.',
    providers_status_configured: 'API key configured',
    providers_status_not_configured: 'No API key',
    providers_status_oauth: 'OAuth',
    providers_status_api_key: 'API key',
    providers_status_not_configured_label: 'Not configured',
    providers_oauth_hint: 'Authenticated via OAuth. No API key needed.',
    providers_oauth_config_yaml_hint: 'Token configured via config.yaml. To update, edit the providers section in your config.yaml or run hermes auth.',
    providers_oauth_not_configured_hint: 'Not authenticated. Run hermes auth in the terminal to configure this provider.',
    providers_save: 'Save',
    providers_remove: 'Remove',
    providers_saving: 'Saving…',
    providers_removing: 'Removing…',
    providers_enter_key: 'Please enter an API key',
    providers_empty: 'No configurable providers found.',
    providers_key_updated: 'API key saved',
    providers_key_removed: 'API key removed',
    providers_key_placeholder_new: 'sk-...',
    providers_key_placeholder_replace: 'Enter new key to replace…',
    provider_quota_title: '활성 제공자 할당량',
    provider_quota_active_provider: '활성 제공자',
    provider_quota_last_checked_after_refresh: '새로고침 후 마지막 확인',
    provider_quota_last_checked: '마지막 확인 {0}',
    provider_quota_refresh_usage: '사용량 새로고침',
    provider_quota_refreshing: '새로고침 중...',
    provider_quota_refresh_title: '제공자 사용 제한을 지금 새로고침',
    provider_quota_refresh_succeeded: '제공자 사용량을 새로고침했습니다',
    provider_quota_refresh_failed: '제공자 사용량 새로고침 실패',
    provider_quota_session_limit: '5시간 제한',
    provider_quota_weekly_limit: '주간 제한',
    provider_quota_window_fallback: '기간',
    provider_quota_metric_remaining: '남음',
    provider_quota_metric_used: '사용됨',
    provider_quota_metric_limit: '제한',
    provider_quota_status_available: '사용 가능',
    provider_quota_status_exhausted: '소진됨',
    provider_quota_status_unavailable: '사용 불가',
    provider_quota_status_failed: '실패',
    provider_quota_status_checked: '확인됨',
    provider_quota_status_no_key: '키 없음',
    provider_quota_status_invalid_key: '잘못된 키',
    provider_quota_status_unsupported: '지원되지 않음',
    provider_quota_used_meta: '{0} 사용됨',
    provider_quota_resets_meta: '{0}에 재설정',
    provider_quota_credential_pool: '자격 증명 풀',
    provider_quota_credential_label: '자격 증명 {0}',
    provider_quota_pool_plans: '플랜: {0}',
    provider_quota_pool_no_windows: '보고된 계정 제한 기간이 없습니다.',
    provider_quota_account_limits_loaded: '계정 제한을 불러왔습니다.',
    provider_quota_unavailable: '할당량 상태를 사용할 수 없습니다',
    provider_quota_retry_after: '{0} 후 다시 시도',
    provider_quota_pool_summary_available: '{0}/{1} 사용 가능',
    provider_quota_pool_summary_exhausted: '{0}개 소진됨',
    provider_quota_pool_summary_failed: '{0}개 실패',
    provider_quota_pool_summary_checked: '{0}개 확인됨',
    cancel: '취소',
    create_job: 'Create job',
    save_skill: 'Save skill',
    editing: 'Editing',
    // Empty state
    empty_title: '무엇을 도와드릴까요?',
    empty_subtitle: '질문하고, 명령을 실행하고, 파일을 탐색하거나 예약 작업을 관리하세요.',
    suggest_files: '이 워크스페이스에는 어떤 파일이 있나요?',
    suggest_schedule: '오늘 일정에는 무엇이 있나요?',
    suggest_plan: '작은 프로젝트 계획을 도와주세요.',
    // onboarding
    onboarding_badge: '첫 실행',
    onboarding_title: 'Hermes Web UI에 오신 것을 환영합니다',
    onboarding_lead: '간단한 안내 설정으로 Hermes 설치를 확인하고, 워크스페이스와 모델을 선택하며, 필요하면 비밀번호로 앱을 보호합니다.',
    onboarding_back: '뒤로',
    onboarding_continue: '계속',
    onboarding_skip: '설정 건너뛰기',
    onboarding_skipped: 'Setup skipped — using existing config.',
    onboarding_open: 'Open Hermes',
    onboarding_step_system_title: 'System check',
    onboarding_step_system_desc: 'Verify Hermes Agent and config visibility.',
    onboarding_step_setup_title: 'Provider setup',
    onboarding_step_setup_desc: 'Save the minimum Hermes provider config.',
    onboarding_step_workspace_title: 'Workspace + model',
    onboarding_step_workspace_desc: 'Pick defaults for new sessions and chat.',
    onboarding_step_password_title: 'Optional password',
    onboarding_step_password_desc: 'Protect the Web UI before sharing it.',
    onboarding_step_finish_title: 'Finish',
    onboarding_step_finish_desc: 'Review and enter the app.',
    onboarding_notice_system_ready: 'Hermes Agent looks reachable from the Web UI.',
    onboarding_notice_system_unavailable: 'Hermes Agent is not fully available yet. Bootstrap can install it, but provider setup may still require a terminal.',
    onboarding_check_agent: 'Hermes Agent',
    onboarding_check_agent_ready: 'Detected and importable',
    onboarding_check_agent_missing: 'Missing or partially importable',
    onboarding_check_password: 'Password',
    onboarding_check_password_enabled: 'Already enabled',
    onboarding_check_password_disabled: 'Not enabled yet',
    onboarding_check_provider: 'Provider config',
    onboarding_check_provider_ready: 'Ready to chat',
    onboarding_check_provider_partial: 'Saved but incomplete',
    onboarding_check_provider_pending: 'Needs verification',
    onboarding_config_file: 'Config file:',
    onboarding_env_file: '.env file:',
    onboarding_unknown: 'Unknown',
    onboarding_current_provider: 'Current setup:',
    onboarding_missing_imports: 'Missing imports:',
    onboarding_notice_setup_required: 'Choose a simple provider path here. Advanced OAuth flows still belong in the Hermes CLI for now.',
    onboarding_notice_setup_already_ready: 'A working Hermes provider setup is already detected. You can keep it or replace it here.',
    onboarding_oauth_provider_ready_title: 'Provider already authenticated',
    onboarding_oauth_provider_ready_body: 'This instance is configured to use an OAuth provider (<strong>{provider}</strong>) that was set up via the Hermes CLI. No API key is needed here — click Continue to finish setup.',
    onboarding_oauth_provider_not_ready_title: 'OAuth provider not yet authenticated',
    onboarding_oauth_provider_not_ready_body: 'This instance is configured to use <strong>{provider}</strong>, which uses OAuth rather than an API key. Run <code>hermes auth</code> or <code>hermes model</code> in a terminal to authenticate, then reload the Web UI.',
    onboarding_oauth_switch_hint: 'Or choose a different provider below to switch to an API-key setup:',
    onboarding_notice_workspace: 'These values reuse the same settings APIs as the normal app.',
    onboarding_workspace_label: 'Workspace',
    onboarding_workspace_or_path: 'Or enter a workspace path',
    onboarding_workspace_placeholder: '/home/you/workspace',
    onboarding_provider_label: 'Setup mode',
    onboarding_quick_setup_badge: 'quick setup',
    provider_category_easy_start: 'Easy start',
    provider_category_self_hosted: 'Open / self-hosted',
    provider_category_specialized: 'Specialized',
    onboarding_api_key_label: 'API key',
    oauth_login_codex: 'Login with Codex (ChatGPT)', // TODO: translate
    oauth_codex_step1: 'Step 1: Visit this URL and enter the code', // TODO: translate
    oauth_codex_step2: 'Step 2: Enter this code on the page', // TODO: translate
    oauth_codex_polling: 'Waiting for authorization...', // TODO: translate
    oauth_codex_success: 'Codex OAuth login successful!', // TODO: translate
    oauth_codex_error: 'OAuth login failed', // TODO: translate
    oauth_codex_expired: 'Code expired, please try again', // TODO: translate
    onboarding_api_key_placeholder: 'Leave blank to keep an existing saved key',
    onboarding_api_key_label_optional: 'API key (optional)', // TODO: translate
    onboarding_api_key_placeholder_optional: 'Leave blank for keyless servers', // TODO: translate
    onboarding_api_key_help_keyless: 'Most LM Studio / Ollama / vLLM installs run keyless — leave this blank if your server doesn\'t require authentication. Use the Test connection button to verify.', // TODO: translate
    onboarding_api_key_help_prefix: 'Saved as a secret in your Hermes .env file using',
    onboarding_base_url_label: 'Base URL',
    onboarding_base_url_placeholder: 'https://your-endpoint.example/v1',
    onboarding_base_url_help: 'Use this for OpenAI-compatible routers, self-hosted servers, LiteLLM, Ollama, LM Studio, vLLM, or similar endpoints.',
    onboarding_model_label: 'Default model',
    onboarding_workspace_help: 'Pick the model Hermes should use for new chats after setup completes.',
    onboarding_custom_model_placeholder: 'your-model-name',
    onboarding_custom_model_help: 'For custom endpoints, enter the exact model ID your server expects.',
    onboarding_notice_password_enabled: 'A password is already configured. Enter a new one only if you want to replace it.',
    onboarding_notice_password_recommended: 'Optional but recommended if you will expose the UI beyond localhost.',
    onboarding_password_label: 'Password (optional)',
    onboarding_password_placeholder: 'Leave blank to skip',
    onboarding_password_help: 'Passwords are stored through the existing settings API and hashed server-side.',
    onboarding_notice_finish: 'You can reopen Settings later to change any of this.',
    onboarding_not_set: 'Not set',
    onboarding_password_will_enable: 'Will be enabled',
    onboarding_password_will_replace: 'Will be replaced',
    onboarding_password_keep_existing: 'Keep current password',
    onboarding_password_remains_disabled: 'Will remain disabled',
    onboarding_password_skipped: 'Skipped for now',
    onboarding_finish_help: 'Finishing stores <code>onboarding_completed</code> in settings and drops you into the normal app.',
    onboarding_error_choose_workspace: 'Choose a workspace before continuing.',
    onboarding_error_choose_model: 'Choose a model before continuing.',
    onboarding_error_provider_required: 'Choose a setup mode before continuing.',
    onboarding_error_base_url_required: 'Base URL is required for custom endpoints.',
    onboarding_probe_test_button: 'Test connection', // TODO: translate
    onboarding_probe_probing: 'Testing connection…', // TODO: translate
    onboarding_probe_ok: 'Connected. {n} model(s) available.', // TODO: translate
    onboarding_probe_error_generic: 'Could not reach the configured base URL.', // TODO: translate
    onboarding_probe_error_invalid_url: 'Base URL must start with http:// or https://.', // TODO: translate
    onboarding_probe_error_dns: 'Could not resolve the host. Check the URL or use the host\'s IP address.', // TODO: translate
    onboarding_probe_error_connect_refused: 'Connection refused — the server may not be running on that address. From inside Docker, try the host IP instead of localhost.', // TODO: translate
    onboarding_probe_error_timeout: 'The endpoint did not respond in time. Check that the server is running and the URL is correct.', // TODO: translate
    onboarding_probe_error_http_4xx: 'The endpoint returned a client error. Check authentication and the URL path (typically ends in /v1).', // TODO: translate
    onboarding_probe_error_http_5xx: 'The endpoint returned a server error. Check the LM Studio / Ollama server logs.', // TODO: translate
    onboarding_probe_error_parse: 'The endpoint did not return a model list in the expected shape. Verify the URL points to the OpenAI-compatible API root.', // TODO: translate
    onboarding_probe_error_unreachable: 'Could not reach the configured base URL.', // TODO: translate
    onboarding_error_probe_failed: 'Could not validate the configured base URL.', // TODO: translate
    onboarding_error_workspace_required: 'Workspace is required.',
    onboarding_error_model_required: 'Model is required.',
    onboarding_complete: '설정 완료',

    // panel/runtime i18n
    error_prefix: 'Error: ',
    not_available: 'N/A',
    never: 'never',
    add: 'Add',
    add_failed: 'Add failed: ',
    remove_failed: 'Remove failed: ',
    switch_failed: 'Switch failed: ',
    name_required: 'Name is required',
    content_required: 'Content is required',
    view: 'View',
    dismiss: 'Dismiss',
    disable: 'Disable',
    cron_no_jobs: 'No scheduled jobs found.',
    cron_status_off: 'off',
    cron_status_paused: 'paused',
    cron_status_error: 'error',
    cron_status_active: 'active',
    cron_status_running: '\uc2e4\ud589 \uc911\u2026',
    cron_status_needs_attention: '주의 필요',
    cron_attention_desc: '이 반복 작업에 다음 실행 시간이 없습니다. 스케줄러가 다음 실행을 계산하지 못했을 수 있습니다.',
    cron_attention_croniter_hint: 'Gateway 런타임에 croniter 패키지가 없을 수 있습니다. cron 지원이 포함된 환경으로 Gateway를 재시작한 후 이 작업을 재개하세요.',
    cron_attention_resume: '재개 및 재계산',
    cron_jobs_project: '예약 작업',
    cron_attention_run_once: '지금 한 번 실행',
    cron_attention_copy_diagnostics: '진단 정보 복사',
    cron_diagnostics_copied: '크론 진단 정보가 복사되었습니다',
    cron_next: 'Next',
    cron_last: 'Last',
    cron_run_now: 'Run now',
    cron_pause: 'Pause',
    cron_resume: 'Resume',
    cron_job_name_placeholder: 'Job name',
    cron_schedule_placeholder: 'Schedule',
    cron_prompt_placeholder: 'Prompt',
    cron_last_output: 'Last output',
    cron_expand_prompt: 'Expand prompt',
    cron_collapse_prompt: 'Collapse prompt',
    cron_expand_output: 'Expand output',
    cron_collapse_output: 'Collapse output',
    cron_all_runs: 'All runs',
    cron_hide_runs: 'Hide runs',
    cron_no_runs_yet: '(no runs yet)',
    cron_schedule_required_example: 'Schedule is required (e.g. "0 9 * * *" or "every 1h")',
    cron_schedule_required: 'Schedule is required',
    cron_prompt_required: 'Prompt is required',
    cron_job_created: 'Job created',
    cron_duplicate: 'Duplicate',
    cron_duplicated: 'Job duplicated (paused)',
    cron_job_triggered: 'Job triggered',
    cron_job_paused: 'Job paused',
    cron_job_resumed: 'Job resumed',
    cron_job_updated: 'Job updated',
    cron_delete_confirm_title: 'Delete cron job',
    cron_delete_confirm_message: 'This cannot be undone.',
    cron_job_deleted: 'Job deleted',
    cron_completion_status: (name, status) => `Cron "${name}" ${status}`,
    status_failed: 'failed',
    status_completed: 'completed',
    todos_no_active: 'No active task list in this session.',
    clear_conversation_title: 'Clear conversation',
    clear_conversation_message: 'Clear all messages? This cannot be undone.',
    clear_failed: 'Clear failed: ',
    skills_no_match: 'No skills match.',
    linked_files: 'Linked Files',
    skill_load_failed: 'Could not load skill: ',
    skill_file_load_failed: 'Could not load file: ',
    skill_name_required: 'Skill name is required',
    skill_updated: 'Skill updated',
    skill_created: 'Skill created',
    skill_deleted: 'Skill deleted',
    skill_delete_confirm: 'Delete skill "{0}"?',
    skills_empty_title: 'Select a skill',
    skills_empty_sub: 'Pick a skill from the sidebar to view its contents, or create a new one.',
    skills_edit: 'Edit',
    skills_delete: 'Delete',
    skills_back_to: 'Back to {0}',
    tasks_empty_title: 'Select a scheduled job',
    tasks_empty_sub: 'Pick a job from the sidebar to view its details and runs, or create a new one.',
    workspaces_empty_title: 'Select a space',
    workspaces_empty_sub: 'Pick a space from the sidebar to view its files and settings, or add a new one.',
    profiles_empty_title: 'Select a profile',
    profiles_empty_sub: 'Pick an agent profile from the sidebar to view and edit its settings, or create a new one.',
    memory_notes_label: 'memory (notes)',
    memory_saved: 'Memory saved',
    my_notes: 'My Notes',
    user_profile: 'User Profile',
    no_notes_yet: 'No notes yet.',
    no_profile_yet: 'No profile yet.',
    agent_soul: 'Agent Soul',
    no_soul_yet: 'No soul defined yet.',
    workspace_choose_path: 'Choose workspace path',
    workspace_choose_path_meta: 'Add a validated path and switch this conversation',
    workspace_manage: 'Manage workspaces',
    workspace_manage_meta: 'Open the Spaces panel',
    workspace_use_title: 'Use in current session',
    workspace_use: 'Use',
    workspace_add_path_placeholder: 'Add workspace path (e.g. /home/user/my-project)',
    workspace_paths_validated_hint: 'Paths are validated as existing directories before saving.',

    workspace_drag_hint: '드래그하여 순서 변경',
    workspace_reorder_failed: '순서 변경 실패',
    workspace_added: 'Workspace added',
    workspace_renamed: 'Workspace renamed',
    workspace_remove_confirm_title: 'Remove workspace',
    workspace_remove_confirm_message: (path) => `Remove "${path}"?`,
    workspace_removed: 'Workspace removed',
    workspace_switch_prompt_title: 'Switch workspace',
    workspace_switch_prompt_message: 'Enter an absolute workspace path to add and switch this conversation to.',
    workspace_switch_prompt_confirm: 'Switch',
    workspace_switch_prompt_placeholder: '/Users/you/project',
    workspace_not_added: 'Workspace was not added',
    workspace_already_saved: 'Workspace already saved — choose it from the list',
    workspace_busy_switch: 'Cannot switch workspace while agent is running',
    discard_file_edits_title: 'Discard file edits?',
    discard_file_edits_message: 'Switching workspaces will discard unsaved file edits in the preview.',
    workspace_switched_to: (name) => `Switched to ${name}`,
    profiles_no_profiles: 'No profiles found.',
    profile_api_keys_configured: 'API keys configured',
    profile_gateway_running: 'Gateway running',
    profile_gateway_stopped: 'Gateway stopped',
    profile_active: 'ACTIVE',
    profile_no_configuration: 'No configuration',
    profile_skill_count: (count) => `${count} skill${count === 1 ? '' : 's'}`,
    profile_use: 'Use',
    profile_switch_title: 'Switch to this profile',
    profile_delete_title: 'Delete this profile',
    profile_default_label: '(default)',
    profile_name_placeholder: 'Profile name (lowercase, a-z 0-9 hyphens)',
    profile_clone_label: 'Clone config from active profile',
    profile_model_label: 'Model / provider',
    profile_model_hint: 'Choose from configured providers and models for this new profile.',
    profile_model_use_default: 'Use active profile default',
    profile_base_url_placeholder: 'Base URL (optional, e.g. http://localhost:11434)',
    profile_api_key_placeholder: 'API key (optional)',
    manage_profiles: 'Manage profiles',
    profiles_load_failed: 'Failed to load profiles',
    profile_switched_new_conversation: (name) => `Switched to profile: ${name} — new conversation started`,
    profile_switched: (name) => `Switched to profile: ${name}`,
    profile_name_rule: 'Lowercase letters, numbers, hyphens, underscores only',
    profile_base_url_rule: 'Base URL must start with http:// or https://',
    profile_created: (name) => `Profile created: ${name}`,
    profile_delete_confirm_title: (name) => `Delete profile "${name}"?`,
    profile_delete_confirm_message: 'All sessions, config, skills, and memory for this profile will be permanently deleted. This cannot be undone.',
    profile_deleted: (name) => `Profile deleted: ${name}`,
    active_conversation_none: 'No active conversation selected.',
    active_conversation_meta: (title, count) => `${title} · ${count} message${count === 1 ? '' : 's'}`,
    settings_unsaved_changes: 'You have unsaved changes.',
    sign_out_failed: '로그아웃 실패: ',
    disable_auth_confirm_title: '비밀번호 보호 비활성화',
    disable_auth_confirm_message: 'Anyone will be able to access this instance.',
    auth_disabled: '인증 비활성화 — 비밀번호 보호가 제거되었습니다',
    disable_auth_failed: 'Failed to disable auth: ',
    bg_error_single: (title) => `"${title}" has encountered an error`,
    bg_error_multi: (count) => `${count} sessions have encountered an error`,
    // skill form
    skill_name: 'Name',
    skill_category: 'Category',
    skill_category_placeholder: 'Optional, e.g. devops',
    skill_content: 'SKILL.md content',
    skill_content_placeholder: 'YAML frontmatter + markdown body',
    skill_rename_not_supported: 'Renaming a skill is not supported. Create a new skill and delete the old one to rename.',
    skill_metadata: 'Metadata',
    // cron form
    cron_name_label: 'Name',
    cron_name_placeholder: 'Optional',
    cron_schedule_label: 'Schedule',
    cron_schedule_hint: "Use 'every 1h' or a cron expression for recurring jobs. Bare durations like '30m' run once.",
    cron_schedule_once_warning: "Duration forms like '30m' run once and are removed after running. Use 'every 30m' to keep a recurring job.",
    cron_prompt_label: 'Prompt',
    cron_deliver_label: 'Deliver output to',
    cron_deliver_local: 'Local (save output only)',
    cron_profile_label: 'Profile',
    cron_profile_server_default: 'server default',
    cron_profile_server_default_hint: 'Uses the WebUI server default profile at run time. Existing jobs without a profile keep this legacy behavior.',
    cron_toast_notifications_label: '완료 토스트',
    cron_toast_notifications_hint: '이 Cron이 완료되면 토스트를 표시합니다. 꺼져 있어도 Tasks 배지와 새 실행 표시는 계속 업데이트됩니다.',
    cron_toast_notifications_enabled: '사용',
    cron_toast_notifications_disabled: '사용 안 함',
    cron_skills_label: 'Skills',
    cron_skills_placeholder: 'Add skills (optional)…',
    cron_skills_edit_hint: 'Skill list is not editable after creation.',
    // workspace form
    workspace_name_label: 'Name',
    workspace_name_placeholder: 'Optional friendly name',
    workspace_path_label: 'Path',
    workspace_path_required: 'Path is required',
    workspace_path_readonly: 'Path cannot be changed. Rename only.',
    workspace_new_title: 'New space',
    // profile form
    profile_name_label: 'Name',
    profile_base_url_label: 'Base URL',
    profile_api_key_label: 'API key',
    cmd_yolo: 'YOLO 모드 전환',
    cmd_branch: 'Fork this conversation into a new session',
    cmd_branch_usage: '/branch [name] — fork conversation (optionally with a name)',
    branch_forked: 'Forked into new session',
    branch_failed: 'Fork failed: ',
    fork_from_here: 'Fork from here',
    forked_from: 'Forked from',
    yolo_no_session: '활성 세션 없음',
    yolo_enabled: '⚡ YOLO 모드 켜짐 — 이 세션에서 승인 건너뜀',
    yolo_disabled: 'YOLO 모드 꺼짐',
    yolo_pill_label: 'YOLO',
    yolo_pill_title_active: 'YOLO 모드 활성 — 클릭하여 비활성화',
    approval_skip_all: '⚡ 이 세션에서 모두 건너뛰기',
    approval_skip_all_title: '이 세션의 모든 승인 요청 건너뛰기',
    // composer action tooltips
    composer_send: '메시지 보내기',
    composer_queue: '메시지 대기열에 추가',
    composer_interrupt: '중단하고 전송',
    composer_steer: '현재 응답 유도',
    composer_stop: '생성 중지',
    composer_disabled_clarify: '위의 명확화 요청에 응답하세요',
    composer_disabled_compression: '압축 완료 대기 중',
    composer_disabled_empty: '메시지를 입력하세요',
    composer_mobile_workspace: '워크스페이스',
    composer_mobile_model: '모델',
    composer_mobile_reasoning: '추론',
    composer_mobile_context: '컨텍스트',

    pdf_loading: 'PDF {0} 로드 중…',
    pdf_too_large: 'PDF가 인라인 미리보기에 너무 큼',
    pdf_no_pages: 'PDF 미리보기를 렌더링할 수 없음',
    pdf_error: 'PDF 로드 실패',
    pdf_download: 'PDF 다운로드',
    html_loading: 'HTML 미리보기 로드 중…',
    html_too_large: 'HTML이 인라인 미리보기에 너무 큼',
    html_error: 'HTML 미리보기 로드 실패',
    html_open_full: '전체 페이지 열기',
    html_sandbox_label: 'HTML 미리보기',
    media_audio_label: '오디오',
    media_svg_label: '다이어그램',
    media_video_label: '비디오',
    csv_loading: 'CSV 로딩 중',
    csv_too_large: 'CSV 파일이 너무 커서 인라인 렌더링할 수 없습니다',
    csv_no_data: 'CSV 파일에 표시할 데이터가 부족합니다',
    csv_error: 'CSV 파일을 로드하지 못했습니다',
    csv_header_note: '첫 번째 행이 테이블 헤더로 표시됩니다',
    excalidraw_loading: '다이어그램 로딩 중',
    excalidraw_too_large: 'Excalidraw 파일이 너무 커서 인라인 렌더링할 수 없습니다',
    excalidraw_invalid: '잘못된 Excalidraw 파일 형식',
    excalidraw_error: 'Excalidraw 파일을 로드하지 못했습니다',
    excalidraw_label: '다이어그램',
    excalidraw_download: '다운로드',
    excalidraw_empty: '빈 다이어그램',
    excalidraw_render_error: '다이어그램 렌더링 실패',
    excalidraw_simplified: '단순화된 SVG 미리보기 — Excalidraw 캔버스와 픽셀 동일하지 않음',
    // TTS (#499)
    tts_listen: '듣기',
    tts_not_supported: '음성 합성을 사용할 수 없습니다',
    settings_label_tts: '답변 음성 합성',
    settings_desc_tts: '도움말 메시지에 스피커 버튼 표시',
    settings_label_tts_auto_read: '답변 자동 읽기',
    settings_desc_tts_auto_read: '도움말 답변을 자동으로 읽어줌',
    // Composer voice-mode pref (#1488)
    settings_label_voice_mode: 'Hands-free voice mode button',  // TODO: translate
    settings_desc_voice_mode: 'Show the voice-mode button (audio waveform) next to the dictation mic. Lets you speak naturally — Hermes auto-sends after a pause and reads replies aloud. Requires a browser that supports both speech recognition and TTS.',  // TODO: translate
    settings_label_tts_voice: '음성',
    settings_desc_tts_voice: '음성 합성 음성 선택',
    settings_label_tts_rate: '말 속도',
    settings_label_tts_pitch: '말 톤',
    checkpoint_date: 'Date',  // TODO: translate
    checkpoint_diff_files_changed: (n) => `${n} file${n === 1 ? '' : 's'} changed`,  // TODO: translate
    checkpoint_diff_no_changes: 'No differences found between this checkpoint and the current workspace.',  // TODO: translate
    checkpoint_diff_title: 'Changes in checkpoint',  // TODO: translate
    checkpoint_empty: 'No checkpoints found for this workspace.',  // TODO: translate
    checkpoint_error: 'Failed to load checkpoints',  // TODO: translate
    checkpoint_files: 'Files',  // TODO: translate
    checkpoint_loading: 'Loading checkpoints…',  // TODO: translate
    checkpoint_message: 'Message',  // TODO: translate
    checkpoint_restore: 'Restore',  // TODO: translate
    checkpoint_restore_confirm_message: (ckpt) => `Restore workspace to checkpoint "${ckpt}"? This will overwrite files with the saved versions. Files added after this checkpoint will not be deleted.`,  // TODO: translate
    checkpoint_restore_confirm_title: 'Restore checkpoint?',  // TODO: translate
    checkpoint_restored: 'Checkpoint restored',  // TODO: translate
    checkpoint_title: 'Checkpoints',  // TODO: translate
    checkpoint_view_diff: 'View diff',  // TODO: translate
    insights_activity_by_day: 'Activity by Day',  // TODO: translate
    insights_activity_by_hour: 'Activity by Hour',  // TODO: translate
    insights_cost: 'Estimated Cost',  // TODO: translate
    insights_daily_tokens: '일별 토큰',
    insights_model_name: '모델',
    insights_model_sessions: '세션',
    insights_model_tokens: '토큰',
    insights_model_cost: '비용',
    insights_model_share: '비율',
    insights_no_usage_data: '아직 사용 데이터가 없습니다',
    insights_footer: 'Showing data from the last {days} days',  // TODO: translate
    insights_input_tokens: 'Input',  // TODO: translate
    insights_messages: 'Messages',  // TODO: translate
    insights_models: 'Models',  // TODO: translate
    insights_no_cost: 'N/A',  // TODO: translate
    insights_output_tokens: 'Output',  // TODO: translate
    insights_peak_hour: 'Peak: {hour}',  // TODO: translate
    insights_sessions: 'Sessions',  // TODO: translate
    insights_title: 'Usage Analytics',  // TODO: translate
    insights_token_breakdown: 'Token Breakdown',  // TODO: translate
    insights_tokens: 'Tokens',  // TODO: translate
    insights_total: 'Total',  // TODO: translate
    settings_desc_api_redact: 'Self-hosted users can disable for transparency (not recommended for shared instances).',  // TODO: translate
    settings_label_api_redact: 'Redact sensitive data in API responses',  // TODO: translate
    voice_error: 'Voice not supported in this browser',  // TODO: translate
    voice_listening: 'Listening…',  // TODO: translate
    voice_mode_active: 'Voice mode on',  // TODO: translate
    voice_mode_off: 'Voice mode off',  // TODO: translate
    voice_speaking: 'Speaking…',  // TODO: translate
    voice_thinking: 'Thinking…',  // TODO: translate
    // Composer voice buttons (#1488)
    voice_dictate: 'Dictate',  // TODO: translate
    voice_dictate_active: 'Stop dictation',  // TODO: translate
    voice_mode_toggle: 'Voice mode',  // TODO: translate
    voice_mode_toggle_active: 'Exit voice mode',  // TODO: translate
    subagent_children: 'Subagent sessions',  // TODO: translate
  },

  fr: {
    offline_title: 'Connexion perdue',
    offline_browser_detail: 'Votre navigateur signale que cet appareil est hors ligne.',
    offline_network_detail: 'Hermes est actuellement inaccessible depuis ce navigateur.',
    offline_autorefresh: 'J\'actualiserai automatiquement cette page lorsqu\'Hermès sera à nouveau joignable.',
    offline_check_now: 'Vérifiez maintenant',
    offline_checking: 'Vérification…',
    offline_stream_waiting: 'Connexion perdue. En attendant de rafraîchir…',
    _lang: 'fr',
    _label: 'Français',
    _speech: 'fr-FR',
    cancelling: 'Annulation\u2026',
    cancel_failed: 'Échec de l\'annulation :',
    mic_denied: 'Accès au microphone refusé. Vérifiez les autorisations du navigateur.',
    mic_no_speech: 'Aucune parole détectée. Essayer à nouveau.',
    mic_network: 'Reconnaissance vocale indisponible.',
    mic_error: 'Erreur de saisie vocale :',
    voice_dictate: 'Dicter',
    voice_dictate_active: 'Arrêter la dictée',
    voice_mode_toggle: 'Mode vocal',
    voice_mode_toggle_active: 'Quitter le mode vocal',
    voice_listening: 'Écoute…',
    voice_speaking: 'Parlant…',
    voice_thinking: 'Pensée…',
    voice_error: 'Voix non prise en charge dans ce navigateur',
    voice_mode_active: 'Mode vocal activé',
    voice_mode_off: 'Mode vocal désactivé',
    session_imported: 'Session importée',
    import_failed: 'Échec de l\'importation :',
    import_invalid_json: 'JSON invalide',
    image_pasted: 'Image collée :',
    edit_message: 'Modifier le message',
    regenerate: 'Régénérer la réponse',
    copy: 'Copie',
    copied: 'Copié!',
    copy_failed: 'Échec de la copie',
    selected_text_reply: 'Répondre avec la sélection',
    selected_text_reply_title: 'Ajouter le texte sélectionné du chat comme contexte cité',
    selected_text_reply_appended: 'Texte sélectionné ajouté au compositeur',
    diff_loading: 'Chargement des différences',
    diff_error: 'Impossible de charger le fichier de correctif',
    diff_too_large: 'Fichier de correctif trop volumineux pour être affiché en ligne',
    tree_view: 'Arbre',
    raw_view: 'Brut',
    parse_failed_note: 'l\'analyse a échoué',
    you: 'Toi',
    mcp_servers_title: 'Serveurs MCP',
    mcp_servers_desc: 'Affichez les serveurs MCP configurés dans config.yaml.',
    mcp_no_servers: 'Aucun serveur MCP configuré.',
    mcp_add_server: '+ Ajouter un serveur',
    mcp_field_name: 'Nom du serveur',
    mcp_transport_label: 'Type de transport',
    mcp_field_command: 'Commande',
    mcp_field_args: 'Arguments (séparés par des virgules)',
    mcp_field_url: 'URL',
    mcp_field_timeout: 'Délai d\'expiration (secondes)',
    mcp_save: 'Sauvegarder',
    mcp_cancel: 'Annuler',
    mcp_name_required: 'Le nom du serveur est requis.',
    mcp_url_required: 'L\'URL est requise pour le transport HTTP.',
    mcp_command_required: 'La commande est requise pour le transport stdio.',
    mcp_saved: 'Serveur MCP enregistré.',
    mcp_save_failed: 'Échec de l\'enregistrement du serveur MCP.',
    mcp_delete_confirm_title: 'Supprimer le serveur MCP',
    mcp_delete_confirm_message: 'Supprimer le serveur MCP "{0}" ? Cette action ne peut pas être annulée.',
    mcp_deleted: 'Serveur MCP supprimé.',
    mcp_delete_failed: 'Échec de la suppression du serveur MCP.',
    mcp_load_failed: 'Échec du chargement des serveurs MCP.',
    mcp_restart_hint: 'Les modifications apportées au serveur sont en lecture seule ici pour le moment. Modifiez config.yaml et redémarrez Hermes pour que les modifications prennent effet.',
    mcp_toggle_followup: 'Les contrôles d\'activation/désactivation sont intentionnellement différés jusqu\'à ce que la sémantique de rechargement MCP soit explicite.',
    mcp_status_active: 'Actif',
    mcp_status_configured: 'Configuré',
    mcp_status_disabled: 'Désactivé',
    mcp_status_invalid_config: 'Configuration invalide',
    mcp_status_unknown: 'Inconnu',
    mcp_tool_count: '{0} outils',
    mcp_enabled_yes: 'Activé',
    mcp_enabled_no: 'Désactivé',
    mcp_tools_title: 'Outils MCP',
    mcp_tools_desc: 'Recherchez des outils connus sur les serveurs MCP actifs.',
    mcp_tools_search_placeholder: 'Outils de recherche par nom, serveur ou description…',
    mcp_tools_no_tools: 'Aucun outil MCP n\'est disponible dans l\'inventaire d\'exécution actif.',
    mcp_tools_no_matches: 'Aucun outil MCP ne correspond à votre recherche.',
    mcp_tools_load_failed: 'Échec du chargement des outils MCP.',
    mcp_tools_schema_empty: 'Aucun paramètre de schéma.',
    mcp_tools_runtime_note: 'L\'inventaire des outils utilise uniquement les données d\'exécution MCP actives déjà connues ; le WebUI ne démarre pas et ne sonde pas les serveurs.',
    mcp_tools_summary_no_matches: (query,total) => `No MCP tools matching “${query}” (${total} total MCP tools).`,
    mcp_tools_summary_none: 'No MCP tools to show.',
    mcp_tools_summary_matching: (query) => ` matching “${query}”`,
    mcp_tools_summary_total_note: (total) => ` (${total} total MCP tools)`,
    mcp_tools_summary_showing: (start,end,filtered,searchNote,totalNote,page,pages) => `Showing ${start}-${end} of ${filtered} MCP tools${searchNote}${totalNote}. Page ${page} of ${pages}.`,
    mcp_tools_page_size_prefix: 'Show',
    mcp_tools_page_size_suffix: 'per page',
    mcp_tools_per_page_aria: 'MCP tools per page',
    mcp_tools_inactive_configured_servers: (servers) => `Configured but inactive in this WebUI runtime: ${servers}.`,
    mcp_tools_pagination_label: 'MCP tools pagination',
    mcp_tools_previous_page: '‹ Prev',
    mcp_tools_previous_page_aria: 'Previous MCP tools page',
    mcp_tools_next_page: 'Next ›',
    mcp_tools_next_page_aria: 'Next MCP tools page',
    pdf_loading: 'Chargement du PDF {0}…',
    pdf_too_large: 'PDF trop volumineux pour un aperçu en ligne',
    pdf_no_pages: 'Le PDF n\'a pas de pages',
    pdf_error: 'Échec de l\'affichage de l\'aperçu PDF',
    pdf_download: 'Télécharger le PDF',
    html_loading: 'Chargement de l\'aperçu HTML…',
    html_too_large: 'HTML trop volumineux pour l\'aperçu en ligne',
    html_error: 'Échec de l\'affichage de l\'aperçu HTML',
    html_open_full: 'Ouvrir la page entière',
    html_sandbox_label: 'Aperçu HTML (en bac à sable)',
    thinking: 'Pensée',
    expand_all: 'Tout développer',
    collapse_all: 'Tout réduire',
    edit_failed: 'Échec de la modification :',
    regen_failed: 'Échec de la régénération :',
    reconnect_active: 'Une réponse est toujours en cours de génération. Recharger quand vous êtes prêt ?',
    reconnect_finished: 'Une réponse était en cours lors de votre dernier départ. Les messages ont peut-être été mis à jour.',
    approval_heading: 'Approbation requise',
    approval_desc_prefix: 'Commande dangereuse détectée',
    approval_btn_once: 'Autoriser une fois',
    approval_btn_once_title: 'Autoriser cette commande (Entrée)',
    approval_btn_session: 'Autoriser la session',
    approval_btn_session_title: 'Autoriser cette session de conversation',
    approval_btn_always: 'Toujours autoriser',
    approval_btn_always_title: 'Toujours autoriser ce modèle de commande',
    approval_btn_deny: 'Refuser',
    approval_btn_deny_title: 'Refuser - n\'exécutez pas cette commande',
    approval_responding: 'Répondre\u2026',
    clarify_heading: 'Des éclaircissements sont nécessaires',
    clarify_hint: 'Choisissez un choix ou saisissez votre propre réponse ci-dessous.',
    clarify_other: 'Autre',
    clarify_send: 'Envoyer',
    clarify_input_placeholder: 'Tapez votre réponse…',
    clarify_responding: 'Répondre\u2026',
    untitled: 'Sans titre',
    load_older_messages: '↑ Faites défiler vers le haut ou cliquez pour charger les anciens messages',
    session_jump_start: 'Commencer',
    session_jump_start_label: 'Aller au début de la session',
    session_jump_end: 'Fin',
    session_jump_end_label: 'Aller à la fin de la session',
    jump_to_question: 'à la question',
    jump_to_question_label: 'Aller à la question de cette réponse',
    queued_label: 'Envoie après réponse',
    queued_cancel: 'Annuler le message en file d\'attente',
    model_unavailable: '(indisponible)',
    model_unavailable_title: 'Ce modèle ne figure plus dans votre liste de fournisseurs actuelle',
    provider_mismatch_label: 'Inadéquation des fournisseurs',
    model_not_found_label: 'Modèle introuvable',
    model_custom_label: 'ID de modèle personnalisé',
    model_custom_placeholder: 'par ex. openai/gpt-5.4',
    model_search_placeholder: 'Rechercher des modèles…',
    model_search_no_results: 'Aucun modèle trouvé',
    model_group_configured: 'Configuré',
    ws_search_placeholder: 'Rechercher des espaces de travail…',
    ws_no_results: 'Aucun espace de travail trouvé',
    workspace_new_worktree_conversation: 'Nouvelle conversation dans l\'arbre de travail',
    workspace_new_worktree_conversation_meta: 'Créez un arbre de travail git isolé pour cet espace de travail.',
    workspace_worktree_created: 'Conversation Worktree créée',
    workspace_worktree_failed: 'La création de l\'arbre de travail a échoué :',
    session_worktree_badge: 'Arbre de travail',
    model_scope_advisory: 'S\'applique à cette conversation à partir de votre prochain message.',
    model_scope_toast: 'S\'applique à cette conversation à partir de votre prochain message.',
    cmd_clear: 'Messages de conversation clairs',
    cmd_compress: 'Compresser manuellement le contexte de conversation (utilisation : /compress [thème principal])',
    ctx_compress_hint: 'Compresser le contexte pour libérer de l\'espace →',
    ctx_compress_action: '⚠ Compressez maintenant pour libérer le contexte',
    cmd_compact_alias: 'Alias ​​hérité pour /compress',
    cmd_model: 'Changer de modèle (par exemple /model gpt-4o)',
    cmd_workspace: 'Changer d\'espace de travail par nom',
    cmd_terminal: 'Ouvrez le terminal de l\'espace de travail',
    cmd_new: 'Démarrer une nouvelle session de discussion',
    cmd_usage: 'Activer/désactiver l\'affichage de l\'utilisation du jeton',
    cmd_theme: 'Changer d\'apparence (thème : system/dark/light, skin : default/ares/mono/slate/poseidon/sisyphus/charizard/sienna/catppuccin/nous/geist-contrast)',
    cmd_personality: 'Personnalité de l\'agent de commutation',
    cmd_skills: 'Lister les compétences Hermès disponibles',
    available_commands: 'Commandes disponibles :',
    type_slash: 'Tapez / pour voir les commandes',
    conversation_cleared: 'Conversation effacée',
    command_label: 'Commande',
    context_compaction_label: 'Compactage du contexte',
    preserved_task_list_label: 'Liste de tâches préservée',
    reference_only_label: 'Référence seulement',
    model_usage: 'Utilisation : /model <nom>',
    no_model_match: 'Aucun modèle correspondant "',
    switched_to: 'Passé à',
    workspace_usage: 'Utilisation : /espace de travail <nom>',
    no_workspace_match: 'Aucun espace de travail correspondant "',
    switched_workspace: 'Passé à l\'espace de travail :',
    workspace_switch_failed: 'Échec du changement d\'espace de travail :',
    new_session: 'Nouvelle session créée',
    new_session_creating: 'Création d’une nouvelle conversation…',
    compressing: 'Demande de compression de contexte...',
    compress_running_label: 'Compression',
    compress_complete_label: 'Compression terminée',
    auto_compress_label: 'Compression automatique',
    compress_failed_label: 'Échec de la compression',
    focus_label: 'Se concentrer',
    token_usage_on: 'Utilisation du jeton sur',
    token_usage_off: 'Utilisation des jetons désactivée',
    usage_cache_hit_detail: 'Cache : {0}% de réussite ({1} lecture / {2} écriture)',
    usage_cached_percent: '{0}% en cache',
    theme_usage: 'Utilisation : /theme ',
    theme_set: 'Thème:',
    no_active_session: 'Aucune session active',
    cmd_queue: 'Mettre un message en file d\'attente pour le prochain tour',
    cmd_goal: 'Définir ou inspecter un objectif persistant',
    goal_evaluating_progress: 'Évaluer la progression des objectifs…',
    goal_working_toward: 'Travailler vers l’objectif…',
    goal_continuing_toast: 'Continuer vers l’objectif…',
    goal_status_none: 'Aucun objectif actif. Définissez-en un avec /goal <text>.',
    goal_cleared: 'But dégagé.',
    goal_no_goal: 'Aucun objectif actif.',
    cmd_interrupt: 'Annuler le tour en cours et envoyer un nouveau message',
    cmd_steer: 'Injecter une correction à mi-tour sans interrompre l\'agent',
    cmd_queue_no_msg: 'Utilisation : /queue <message>',
    cmd_queue_not_busy: 'Aucune tâche active - envoyez simplement normalement',
    cmd_queue_confirm: 'Message en file d\'attente',
    cmd_interrupt_no_msg: 'Utilisation : /interruption <message>',
    cmd_interrupt_confirm: 'Interrompu — envoi d\'un nouveau message',
    cmd_steer_no_msg: 'Utilisation : /steer <message>',
    cmd_steer_fallback: 'Steer indisponible – mis en file d’attente pour le prochain tour à la place',
    cmd_steer_delivered: 'Steer livré - l\'agent le verra sur son prochain résultat d\'outil',
    steer_leftover_queued: 'Bœuf en attente pour le prochain tour',
    busy_steer_fallback: 'Steer indisponible – en file d’attente pour le prochain tour',
    busy_interrupt_confirm: 'Interrompu — envoi d\'un nouveau message',
    settings_label_busy_input_mode: 'Mode de saisie occupé',
    settings_desc_busy_input_mode: 'Contrôle ce qui se passe lorsque vous envoyez un message pendant l\'exécution de l\'agent. La file d\'attente attend ; L\'interruption s\'annule et recommence ; Steer injecte une correction à mi-tour sans interrompre (revient en file d\'attente lorsque l\'agent ou le flux est indisponible).',
    settings_label_fade_text_effect: 'Effet de fondu du texte',
    settings_desc_fade_text_effect: 'Affiche progressivement les nouveaux mots diffusés pendant que l’assistant répond. Similaire à OpenWebUI ; désactivé par défaut pour des performances maximales.',
    settings_busy_input_mode_queue: 'Suivi de file d\'attente',
    settings_busy_input_mode_interrupt: 'Interrompre le tour en cours',
    settings_busy_input_mode_steer: 'Direction (correction à mi-virage)',
    status_profile: 'Profil',
    status_hermes_home: 'Maison Hermès',
    status_started: 'Commencé',
    status_updated: 'Mis à jour',
    status_tokens: 'Jetons',
    status_ephemeral: 'Instantané éphémère – non enregistré dans l’historique des transcriptions.',
    status_no_tokens: 'Aucun jeton utilisé',
    status_unknown: 'Inconnu',
    usage_personality_none: 'aucun',
    session_toolsets: 'Ensembles d\'outils de session',
    session_toolsets_desc: 'Restreindre les outils disponibles pour cette session (vide = utiliser la configuration globale)',
    session_toolsets_global: 'Global (par défaut)',
    session_toolsets_custom: 'Coutume',
    session_toolsets_placeholder: 'outil1, outil2, …',
    session_toolsets_apply: 'Appliquer',
    session_toolsets_clear: 'Effacer (utiliser global)',
    session_toolsets_applied: 'Ensembles d\'outils mis à jour',
    session_toolsets_cleared: 'Ensembles d\'outils effacés - à l\'aide de la configuration globale',
    session_toolsets_failed: 'Échec de la mise à jour des ensembles d\'outils :',
    no_personalities: 'Aucune personnalité trouvée (ajoutez-les à ~/.hermes/personalities/)',
    available_personalities: 'Personnalités disponibles :',
    personality_switch_hint: '\\n\\nUtilisez `/personality <name>` pour changer, ou `/personality none` pour effacer.',
    personalities_load_failed: 'Échec du chargement des personnalités',
    personality_cleared: 'Personnalité effacée',
    personality_set: 'Personnalité:',
    failed_colon: 'Échoué:',
    no_workspace: 'Pas d\'espace de travail',
    terminal_open_title: 'Terminal d\'espace de travail ouvert',
    terminal_no_workspace_title: 'Sélectionnez un espace de travail pour ouvrir le terminal',
    terminal_title: 'Terminal',
    terminal_clear: 'Clair',
    terminal_copy_output: 'Copier la sortie',
    terminal_restart: 'Redémarrage',
    terminal_collapse: 'Effondrement',
    terminal_expand: 'Développer',
    terminal_close: 'Fermer',
    terminal_input_placeholder: 'Exécutez une commande...',
    terminal_start_failed: 'Échec du démarrage du terminal :',
    terminal_input_failed: 'L\'entrée du terminal a échoué :',
    terminal_copy_failed: 'Échec de la copie :',
    terminal_error: 'Erreur de terminal',
    workspace_empty_no_path: 'Aucun espace de travail sélectionné. Définissez un espace de travail dans Paramètres \u2192 Espace de travail pour parcourir les fichiers.',
    workspace_empty_dir: 'Cet espace de travail est vide.',
    workspace_show_hidden_files: 'Afficher les fichiers cachés',
    workspace_show_hidden_files_desc: 'Incluez .DS_Store, .git, node_modules et d\'autres fichiers cachés/système dans l\'arborescence des fichiers.',
    workspace_hidden_files_visible: 'caché visible',
    workspace_hidden_files_visible_title: 'Les fichiers cachés sont visibles – cliquez pour les options',
    workspace_options: 'Options de l\'espace de travail',
    dialog_confirm_title: 'Confirmer l\'action',
    dialog_prompt_title: 'Entrez une valeur',
    dialog_confirm_btn: 'Confirmer',
    unsaved_confirm: 'Vous avez des modifications non enregistrées dans l\'aperçu. Supprimer et naviguer ?',
    discard: 'Jeter',
    save: 'Sauvegarder',
    edit: 'Modifier',
    clear: 'Clair',
    create: 'Créer',
    remove: 'Retirer',
    save_title: 'Enregistrer les modifications',
    edit_title: 'Modifier ce fichier',
    saved: 'Enregistré',
    save_failed: 'Échec de l\'enregistrement :',
    image_load_failed: 'Impossible de charger l\'image',
    file_open_failed: 'Impossible d\'ouvrir le fichier',
    double_click_rename: 'Double-cliquez pour renommer',
    renamed_to: 'Renommé en',
    rename_failed: 'Échec du changement de nom :',
    delete_title: 'Supprimer',
    rename_title: 'Rebaptiser',
    rename_prompt: 'Nouveau nom :',
    deleted: 'Supprimé',
    delete_failed: 'Échec de la suppression :',
    reveal_in_finder: 'Révéler dans le gestionnaire de fichiers',
    reveal_failed: 'Échec de la révélation :',
    copy_file_path: 'Copier le chemin du fichier',
    download_folder: 'Download Folder', // TODO: translate
    path_copied: 'Chemin du fichier copié dans le presse-papiers',
    path_copy_failed: 'Échec de la copie du chemin :',
    session_rename: 'Renommer la conversation',
    session_rename_desc: 'Modifier le titre de cette conversation',
    new_file_prompt: 'Nouveau nom de fichier (par exemple notes.md) :',
    project_name_prompt: 'Nom du projet :',
    created: 'Créé',
    create_failed: 'Échec de la création :',
    new_folder_prompt: 'Nouveau nom de dossier :',
    folder_created: 'Dossier créé',
    folder_create_failed: 'Échec de la création du dossier :',
    remove_title: 'Retirer',
    empty_dir: '(vide)',
    upload_failed: 'Échec du téléchargement :',
    session_pin: 'Épingler la conversation',
    session_unpin: 'Désépingler la conversation',
    session_pin_desc: 'Gardez cette conversation en haut',
    session_unpin_desc: 'Supprimer de l\'épinglé',
    session_pin_failed: 'Échec de la broche :',
    session_move_project: 'Passer au projet',
    session_move_project_desc_has: 'Changer le projet pour cette conversation',
    session_move_project_desc_none: 'Attribuer un projet à cette conversation',
    session_archive: 'Archiver une conversation',
    session_hide_external: 'Masquer de la liste',
    session_restore: 'Restaurer la conversation',
    session_archive_desc: 'Masquer cette conversation jusqu\'à ce que l\'archive soit affichée',
    session_archive_worktree_desc: 'Cachez cette conversation ; garder son arbre de travail sur le disque',
    session_hide_external_desc: 'Masquer cette session importée du WebUI sans supprimer l\'historique d\'origine.',
    session_restore_desc: 'Ramenez cette conversation dans la liste principale',
    session_archived: 'Séance archivée',
    session_archived_worktree: 'Séance archivée. Worktree reste sur le disque.',
    session_hidden: 'Session masquée de la liste',
    session_restored: 'Session restaurée',
    session_archive_failed: 'Échec de l\'archivage :',
    session_duplicate: 'Conversation en double',
    session_duplicate_desc: 'Créer une copie avec le même espace de travail et le même modèle',
    session_duplicated: 'Session dupliquée',
    session_duplicate_failed: 'Échec de la duplication :',
    session_stop_response: 'Arrêter la réponse',
    session_stop_response_desc: 'Annuler la réponse en cours pour cette conversation',
    session_delete: 'Supprimer la conversation',
    session_delete_desc: 'Supprimer définitivement cette conversation',
    session_delete_confirm: 'Supprimer cette conversation ?',
    session_delete_worktree_desc: 'Supprimez uniquement la conversation WebUI ; garder l\'arbre de travail sur le disque',
    session_deleted: 'Conversation supprimée',
    session_deleted_worktree: 'Conversation supprimée. Worktree reste sur le disque.',
    session_worktree_remove: 'Supprimer le worktree',
    session_worktree_remove_desc: (path) => `Supprimer le git worktree à ${path} du disque`,
    session_worktree_remove_confirm: (path) => `Supprimer le git worktree du disque ?\n\nChemin : ${path}\n\nTout le répertoire worktree sera supprimé. Les données de session restent dans WebUI.`,
    session_worktree_remove_not_exists: (path) => `Le worktree à ${path} n'existe plus sur le disque.`,
    session_worktree_remove_confirm_label: 'Supprimer',
    session_worktree_removed: 'Worktree supprimé.',
    session_worktree_remove_failed: 'Échec de la suppression du worktree : ',
    session_worktree_remove_status_failed: 'Échec de la lecture du statut du worktree : ',
    session_worktree_remove_locked_by_stream: 'Impossible de supprimer — une session de streaming active utilise ce worktree.',
    session_worktree_remove_locked_by_terminal: 'Impossible de supprimer — une session de terminal active utilise ce worktree.',
    session_worktree_remove_unsafe_blocked: 'Résolvez les modifications locales ou les commits non poussés avant de supprimer ce worktree.',
    session_worktree_remove_dirty_warning: 'ATTENTION : Ce worktree a des modifications non validées qui seront perdues.',
    session_worktree_remove_untracked_warning: (count) => `${count} fichier(s) non suivi(s) seront définitivement supprimés.`,
    session_worktree_remove_ahead_warning: (ahead) => `${ahead} commit(s) non poussé(s) seront perdus.`,
    session_select_mode: 'Sélectionner',
    session_select_mode_desc: 'Sélectionnez les conversations à gérer par lots',
    session_select_all: 'Tout sélectionner',
    session_deselect_all: 'Tout désélectionner',
    session_selected_count: '{0} sélectionné',
    session_batch_archive: 'Archive',
    session_batch_delete: 'Supprimer',
    session_batch_move: 'Passer au projet',
    session_batch_delete_confirm: 'Supprimer {0} conversations ?',
    session_batch_archive_confirm: 'Archiver {0} conversations ?',
    session_batch_delete_worktree_confirm: 'Supprimer {0} conversations ? {1} conversations basées sur Worktree laisseront leurs répertoires Worktree sur le disque.',
    session_batch_archive_worktree_confirm: 'Archiver {0} conversations ? {1} conversations basées sur un arbre de travail conserveront leurs répertoires d\'arbre de travail sur le disque.',
    session_no_selection: 'Aucune conversation sélectionnée',
    settings_heading_title: 'Centre de contrôle',
    settings_heading_subtitle: 'Préférences, outils de conversation et contrôles système.',
    settings_section_conversation_title: 'Conversation',
    settings_section_appearance_title: 'Apparence',
    settings_section_appearance_meta: 'Thème, couleurs d\'accent et style visuel.',
    settings_section_preferences_title: 'Préférences',
    settings_section_preferences_meta: 'Paramètres par défaut et comportement de l\'interface utilisateur pour Hermes Web UI.',
    settings_section_system_title: 'Système',
    settings_section_system_meta: 'Version de l\'instance et contrôles d\'accès.',
    settings_check_now: 'Vérifiez maintenant',
    settings_checking: 'Vérification\u2026',
    settings_up_to_date: 'À jour \u2713',
    settings_updates_available: '{count} mises à jour disponibles',
    settings_updates_disabled: 'Vérifications de mise à jour désactivées',
    settings_update_check_failed: 'La vérification de la mise à jour a échoué',
    settings_label_workspace_panel_open: 'Garder le panneau de l\'espace de travail ouvert par défaut',
    settings_desc_workspace_panel_open: 'Lorsqu\'il est activé, le panneau de l\'espace de travail/navigateur de fichiers s\'ouvre automatiquement à chaque nouvelle session. Vous pouvez toujours le fermer manuellement à tout moment.',
    settings_label_session_jump_buttons: 'Afficher les boutons de saut de session',
    settings_desc_session_jump_buttons: 'Affichez les boutons flottants de début et de fin lors de la lecture de longs historiques de session.',
    settings_label_session_endless_scroll: 'Charger les anciens messages en faisant défiler vers le haut',
    settings_desc_session_endless_scroll: 'Lorsqu\'ils sont activés, les anciens messages se chargent automatiquement lorsque vous faites défiler vers le haut. Lorsqu\'il est désactivé, utilisez le bouton des messages plus anciens.',

    settings_label_tab_visibility: 'Onglets de la barre latérale',
    settings_desc_tab_visibility: 'Choisissez quels onglets apparaissent dans la barre latérale et le rail. Chat et Paramètres sont toujours visibles.',
    open_in_browser: 'Ouvrir dans le navigateur',
    settings_dropdown_conversation: 'Conversation',
    settings_dropdown_appearance: 'Apparence',
    settings_dropdown_preferences: 'Préférences',
    settings_dropdown_providers: 'Fournisseurs',
    settings_dropdown_system: 'Système',
    settings_tab_conversation: 'Conversation',
    settings_tab_appearance: 'Apparence',
    settings_tab_preferences: 'Préférences',
    settings_tab_plugins: 'Plugins',
    settings_plugins_title: 'Plugins',  // TODO: translate
    settings_plugins_meta: 'View installed Hermes plugins and the lifecycle hooks they register. This panel is read-only.',  // TODO: translate
    settings_plugins_empty: 'No Hermes plugins are currently visible. Install or enable plugins from the Hermes CLI/config to see them here.',  // TODO: translate
    plugins_unnamed: 'Unnamed plugin',  // TODO: translate
    plugins_no_description: 'No description provided.',  // TODO: translate
    plugins_no_hooks: 'No registered lifecycle hooks',  // TODO: translate
    plugins_registered_hooks: 'Registered hooks',  // TODO: translate
    plugins_enabled: 'Enabled',  // TODO: translate
    plugins_disabled: 'Disabled',  // TODO: translate
    plugins_active_provider: 'Active (provider)',  // TODO: translate
    plugins_provider_no_hooks: 'Provider plugin — no agent-visibility hooks',  // TODO: translate
    plugins_load_failed: 'Failed to load plugins: ',  // TODO: translate
    settings_tab_system: 'Système',
    settings_title: 'Paramètres',
    settings_save_btn: 'Enregistrer les paramètres',
    settings_label_model: 'Modèle par défaut',
    settings_desc_model: 'Utilisé pour les nouvelles conversations. Les conversations existantes conservent leur modèle sélectionné.',
    settings_label_send_key: 'Envoyer la clé',
    settings_label_theme: 'Thème',
    settings_label_skin: 'Peau',
    settings_label_font_size: 'Taille de la police',
    font_size_small: 'Petit',
    font_size_default: 'Défaut',
    font_size_large: 'Grand',
    font_size_xlarge: 'Très grand',
    settings_autosave_saving: 'Économie…',
    settings_autosave_saved: 'Enregistré',
    settings_autosave_failed: 'Échec de l\'enregistrement',
    settings_autosave_retry: 'Réessayer',
    settings_label_language: 'Langue',
    settings_label_quota_chip: 'Afficher la pastille de quota du fournisseur dans le compositeur',
    settings_desc_quota_chip: "Affiche un indicateur ambiant de quota restant (par ex. solde de crédit OpenRouter) dans le pied du compositeur. Désactivé par défaut. Visible uniquement sur les écrans larges (≥1400px) lorsqu'activé, pour garder le compositeur dégagé sur les ordinateurs portables et les bureaux standard.",
    settings_label_hide_suggestions: 'Hide new-chat suggestions',
    settings_desc_hide_suggestions: 'Hide the three default suggestion buttons on the empty new-chat screen to avoid accidental taps.',
    settings_label_token_usage: 'Afficher l\'utilisation du jeton',
    settings_label_sidebar_density: 'Densité de la barre latérale',
    cmd_reasoning: 'Basculez la visibilité de la réflexion (afficher/masquer), définir le niveau d\'effort ou vérifier l\'état actuel',
    settings_label_external_sessions: 'Afficher les sessions non-WebUI',
    settings_label_previous_messaging_sessions: 'Afficher les sessions de messagerie précédentes',
    settings_label_sync_insights: 'Synchroniser avec les insights',
    settings_label_check_updates: 'Vérifier les mises à jour',
    settings_label_whats_new_summary: "Summarize What's New with AI",
    settings_label_bot_name: 'Nom par défaut de l\'assistant',
    settings_label_password: 'Mot de passe d\'accès',
    settings_saved: 'Paramètres enregistrés',
    settings_save_failed: 'Échec de l\'enregistrement :',
    settings_load_failed: 'Échec du chargement des paramètres :',
    settings_saved_pw: 'Paramètres enregistrés : protection par mot de passe activée et ce navigateur reste connecté',
    settings_saved_pw_updated: 'Paramètres enregistrés – mot de passe mis à jour',
    login_title: 'Se connecter',
    login_subtitle: 'Entrez votre mot de passe pour continuer',
    login_placeholder: 'Mot de passe',
    login_btn: 'Se connecter',
    login_invalid_pw: 'Mot de passe invalide',
    login_conn_failed: 'La connexion a échoué',
    dialog_confirm_title: 'Confirmer l\'action',
    dialog_prompt_title: 'Entrez une valeur',
    dialog_confirm_btn: 'Confirmer',
    discard: 'Jeter',
    clear: 'Clair',
    create: 'Créer',
    remove: 'Retirer',
    project_name_prompt: 'Nom du projet :',
    tab_chat: 'Chat',
    tab_tasks: 'Tâches',
    tab_skills: 'Compétences',
    tab_memory: 'Mémoire',
    tab_workspaces: 'Espaces',
    tab_profiles: 'Profils',
    tab_kanban: 'Kanban',
    kanban_board: 'Conseil',
    kanban_visible_tasks: '{0} tâches visibles',
    kanban_search_tasks: 'Tâches de recherche',
    kanban_all_assignees: 'Tous les assignés',
    kanban_all_tenants: 'Tous les locataires',
    kanban_include_archived: 'Inclure archivé',
    kanban_no_matching_tasks: 'Aucune tâche correspondante',
    kanban_no_data: 'Aucune donnée Kanban',
    kanban_work_queue_hint: 'Il s\'agit de la file d\'attente de travail de l\'agent Hermes. Créez ou triez une tâche, attribuez-la, déplacez-la vers Prêt, puis laissez le répartiteur la réclamer.',
    kanban_unavailable: 'Kanban indisponible',
    kanban_read_only: 'Vue en lecture seule',
    kanban_empty: 'Vide',
    kanban_task: 'Tâche',
    kanban_no_description: 'Pas de description',
    kanban_refresh: 'Rafraîchir',
    kanban_status_triage: 'Triage',
    kanban_status_todo: 'Faire',
    kanban_status_ready: 'Prêt',
    kanban_status_running: 'En cours d\'exécution',
    kanban_status_blocked: 'Bloqué',
    kanban_status_done: 'Fait',
    kanban_comments_count: 'Commentaires ({0})',
    kanban_events_count: 'Événements ({0})',
    kanban_links: 'Links',
    kanban_parents: 'Parents',
    kanban_children: 'Enfants',
    kanban_runs_count: 'Exécutions ({0})',
    kanban_no_comments: 'Sans commentaires',
    kanban_no_events: 'Aucun événement',
    kanban_no_runs: 'Aucune course',
    kanban_title: 'Titre',
    kanban_description: 'Description',
    kanban_description_placeholder: 'Facultatif : ce qui doit se passer, les critères d\'acceptation, les liens',
    kanban_status: 'Statut',
    kanban_assignee: 'Cessionnaire',
    kanban_assignee_placeholder: 'Facultatif – laisser vide pour tout travailleur',
    kanban_tenant: 'Locataire',
    kanban_tenant_placeholder: 'Facultatif – slug de projet ou d\'équipe',
    kanban_priority: 'Priorité',
    kanban_priority_hint: 'Les nombres plus élevés sont exécutés en premier. Par défaut 0.',
    kanban_title_required: 'Le titre est requis.',
    kanban_new_task: 'Nouvelle tâche',
    kanban_edit_task: 'Modifier la tâche',
    kanban_status_original_hint: 'Statut actuel : {0}. Cette boîte de dialogue prend uniquement en charge les modifications Triage/Todo/Ready.',
    kanban_run_dispatcher: 'Exécuter le répartiteur',
    kanban_run_dispatcher_confirm: 'Cela réclamera des tâches prêtes sur ce tableau et générera des sous-processus de travail (un par tâche, jusqu\'à 8 par clic). Continuer?',
    kanban_assignee_profiles_label: 'Profils Hermès',
    kanban_assignee_other_label: 'Autre (voies CLI / profils supprimés)',
    kanban_assignee_unassigned: '— Non attribué (ne s\'exécutera pas automatiquement) —',
    kanban_ready_needs_assignee: 'Vous avez sélectionné Non attribué + Prêt. Le répartiteur ignorera cette tâche. Soumettez à nouveau pour confirmer ou choisissez un profil.',
    kanban_dispatch_preview_prefix: 'Aperçu :',
    kanban_dispatch_run_prefix: 'Expédié :',
    kanban_dispatch_spawned: 'engendré',
    kanban_dispatch_promoted: 'promu',
    kanban_dispatch_reclaimed: 'récupéré',
    kanban_dispatch_skipped_unassigned: 'ignoré (pas de destinataire)',
    kanban_dispatch_skipped_nonspawnable: 'ignoré (profil inconnu)',
    kanban_dispatch_auto_blocked: 'auto-bloqué',
    kanban_dispatch_timed_out: 'expiré',
    kanban_dispatch_crashed: 's\'est écrasé',
    kanban_add_comment: 'Ajouter un commentaire',
    kanban_status_archived: 'Archivé',
    tab_todos: 'Toutes les tâches',
    tab_insights: 'Connaissances',
    tab_dashboard: 'Tableau de bord Hermès',
    dashboard_loopback_warning: 'Le tableau de bord est en boucle uniquement sur le serveur. Naviguez depuis le serveur lui-même ou redémarrez-le avec --host 0.0.0.0 (non sécurisé).',
    tab_logs: 'Journaux',
    tab_settings: 'Paramètres',
    new_conversation: 'Nouvelle conversation',
    filter_conversations: 'Filtrer les conversations...',
    session_time_unknown: 'Inconnu',
    session_time_last_week: '1w',
    session_time_bucket_today: 'Aujourd\'hui',
    session_time_bucket_yesterday: 'Hier',
    session_time_bucket_this_week: 'Cette semaine',
    session_time_bucket_last_week: 'La semaine dernière',
    session_time_bucket_older: 'Plus vieux',
    scheduled_jobs: 'Travaux planifiés',
    new_job: 'Nouvel emploi',
    loading: 'Chargement...',
    search_skills: 'Compétences de recherche...',
    new_skill: 'Nouvelle compétence',
    personal_memory: 'Mémoire personnelle',
    current_task_list: 'Liste de tâches actuelle',
    logs_title: 'Journaux',
    logs_file: 'Déposer',
    logs_tail: 'Queue',
    logs_auto_refresh: 'Actualisation automatique (5s)',
    logs_wrap: 'Enrouler les lignes',
    logs_copy_all: 'Copier tout',
    logs_empty: 'Aucune ligne de journal pour l\'instant.',
    logs_loading: 'Chargement des journaux…',
    logs_load_failed: 'Les journaux n\'ont pas pu être chargés',
    logs_status_idle: 'Choisissez un fichier journal pour afficher les lignes récentes.',
    logs_no_mtime: 'pas encore écrit',
    logs_truncated_hint: 'Afficher la fin d\'un gros fichier journal ; les octets plus anciens ont été ignorés pour limiter la mémoire.',
    logs_copied: 'Journaux copiés',
    logs_severity: 'Gravité',
    logs_severity_all: 'Tous',
    logs_severity_errors: 'Erreurs',
    logs_severity_warnings: 'Avertissements+',
    logs_filter_active: 'affiché (filtre actif)',
    insights_title: 'Analyse d\'utilisation',
    insights_sessions: 'Séances',
    insights_messages: 'Messages',
    insights_tokens: 'Jetons',
    insights_cost: 'Coût estimé',
    insights_no_cost: 'N / A',
    insights_models: 'Modèles',
    insights_activity_by_day: 'Activité par jour',
    insights_activity_by_hour: 'Activité par heure',
    insights_peak_hour: 'Pic : {heure}',
    insights_token_breakdown: 'Répartition des jetons',
    insights_input_tokens: 'Saisir',
    insights_output_tokens: 'Sortir',
    insights_total: 'Total',
    insights_daily_tokens: 'Jetons quotidiens',
    insights_model_name: 'Modèle',
    insights_model_sessions: 'Séances',
    insights_model_tokens: 'Jetons',
    insights_model_cost: 'Coût',
    insights_model_share: 'Partager',
    insights_no_usage_data: 'Aucune donnée d\'utilisation pour l\'instant',
    insights_footer: 'Affichage des données des {days} derniers jours',
    workspace_desc: 'Ajoutez et changez d\'espace de travail pour vos sessions.',
    session_lineage_segment_untitled: 'Segment sans titre',
    session_lineage_segment_open: 'Segment de lignée ouverte',
    new_profile: 'Nouveau profil',
    transcript: 'Transcription',
    download_transcript: 'Télécharger en Markdown',
    import: 'Importer',
    export_session_json: 'JSON',
    export_session_json_tooltip: 'Exporter la session complète en JSON',
    import_session_json_tooltip: 'Importer une session depuis JSON',
    clear_conversation_btn_tooltip: 'Effacer tous les messages de cette conversation',
    settings_label_rtl: 'Mise en page du chat de droite à gauche',
    settings_desc_rtl: "Inverse l'alignement des messages du chat et de la saisie du compositeur pour des langues comme l'arabe ou l'hébreu. N'affecte que la zone de chat — la barre latérale et les autres panneaux restent de gauche à droite.",
    settings_label_sound: 'Son de notification',
    settings_desc_sound: 'Jouez un son lorsque l\'assistant termine une réponse.',
    tts_listen: 'Écouter',
    tts_not_supported: 'La synthèse vocale n\'est pas prise en charge dans ce navigateur.',
    settings_label_tts: 'Text-to-Speech pour les réponses',
    settings_desc_tts: 'Affichez un bouton haut-parleur sur chaque message de l\'assistant pour le lire à haute voix à l\'aide de la synthèse vocale de votre navigateur.',
    settings_label_tts_auto_read: 'Lecture automatique des réponses à haute voix',
    settings_desc_tts_auto_read: 'Prononcez automatiquement chaque nouvelle réponse de l\'assistant lorsqu\'elle est terminée. S\'arrête lorsque vous commencez à taper.',
    settings_label_voice_mode: 'Bouton du mode vocal mains libres',
    settings_desc_voice_mode: 'Affichez le bouton du mode vocal (forme d\'onde audio) à côté du micro de dictée. Vous permet de parler naturellement : Hermes envoie automatiquement après une pause et lit les réponses à haute voix. Nécessite un navigateur prenant en charge à la fois la reconnaissance vocale et TTS.',
    settings_label_tts_voice: 'Voix',
    settings_desc_tts_voice: 'Voix préférée. Rempli à partir des voix disponibles dans votre navigateur.',
    settings_label_tts_rate: 'Taux de parole',
    settings_label_tts_pitch: 'Emplacement du discours',
    settings_label_notifications: 'Notifications du navigateur',
    settings_desc_notifications: 'Afficher une notification système lorsqu\'une réponse est terminée alors que l\'application est en arrière-plan.',
    settings_desc_token_usage: 'Affiche le nombre de jetons d’entrée/sortie sous chaque réponse de l’assistant. Également basculé avec /usage.',
    settings_label_api_redact: 'Expurger les données sensibles dans les réponses API',
    settings_desc_api_redact: 'Les utilisateurs auto-hébergés peuvent désactiver pour des raisons de transparence (non recommandé pour les instances partagées).',
    settings_sidebar_density_compact: 'Compact',
    settings_sidebar_density_detailed: 'Détaillé',
    settings_desc_sidebar_density: 'Contrôle la quantité de métadonnées que la liste des sessions affiche dans la barre latérale gauche.',
    settings_label_auto_title_refresh: 'Actualisation adaptative du titre',
    settings_auto_title_refresh_off: 'Désactivé',
    settings_auto_title_refresh_5: 'Tous les 5 échanges',
    settings_auto_title_refresh_10: 'Tous les 10 échanges',
    settings_auto_title_refresh_20: 'Tous les 20 échanges',
    settings_desc_auto_title_refresh: 'Régénère automatiquement le titre de la session en fonction du dernier échange, le gardant ainsi pertinent à mesure que la conversation évolue. Nécessite la configuration d’un modèle de génération de titres LLM.',
    settings_desc_external_sessions: 'Affichez les conversations de CLI, Telegram, Discord, Slack et d\'autres chaînes dans la liste des sessions. Cliquez pour importer et continuer.',
    settings_desc_previous_messaging_sessions: 'Affichez les anciennes sessions Discord, Telegram, Slack et Weixin remplacées par reset ou compression.',
    settings_desc_sync_insights: 'Met en miroir l\'utilisation du jeton WebUI dans state.db afin que Hermes /insights inclut les données de session du navigateur. Désactivé par défaut.',
    settings_desc_check_updates: 'Afficher une bannière lorsque des versions plus récentes de WebUI ou de l\'agent sont disponibles. Exécute périodiquement une récupération git en arrière-plan.',
    settings_desc_whats_new_summary: "Changes the What's New action from opening the raw diff first to generating a short, human-readable summary. The regular diff comparison stays available after the summary.",
    settings_desc_bot_name: 'Utilisé uniquement pour le profil par défaut. Les autres profils utilisent leurs propres noms.',
    settings_desc_password: 'Saisissez un nouveau mot de passe pour le définir ou le modifier. Laissez vide pour conserver le paramètre actuel.',
    password_placeholder: 'Entrez le nouveau mot de passe…',
    password_env_var_locked: 'La variable d\'environnement HERMES_WEBUI_PASSWORD est actuellement définie et est prioritaire. Désactivez-le et redémarrez le serveur pour gérer le mot de passe à partir d\'ici.',
    password_env_var_locked_placeholder: 'Verrouillé : la variable d\'environnement HERMES_WEBUI_PASSWORD est définie',
    disable_auth: 'Désactiver l\'authentification',
    sign_out: 'Se déconnecter',
    providers_tab_title: 'Fournisseurs',
    providers_section_title: 'Fournisseurs',
    providers_section_meta: 'Gérez les clés API pour les fournisseurs d\'IA. Les modifications prennent effet immédiatement.',
    providers_status_configured: 'Clé API configurée',
    providers_status_not_configured: 'Aucune clé API',
    providers_status_oauth: 'OAuth',
    providers_status_api_key: 'Clé API',
    providers_status_not_configured_label: 'Non configuré',
    providers_oauth_hint: 'Authentifié via OAuth. Aucune clé API nécessaire.',
    providers_oauth_config_yaml_hint: 'Jeton configuré via config.yaml. Pour mettre à jour, modifiez la section des fournisseurs dans votre config.yaml ou exécutez Hermes Auth.',
    providers_oauth_not_configured_hint: 'Non authentifié. Exécutez Hermes Auth dans le terminal pour configurer ce fournisseur.',
    providers_save: 'Sauvegarder',
    providers_remove: 'Retirer',
    providers_saving: 'Économie…',
    providers_removing: 'Suppression…',
    providers_enter_key: 'Veuillez saisir une clé API',
    providers_empty: 'Aucun fournisseur configurable trouvé.',
    providers_key_updated: 'Clé API enregistrée',
    providers_key_removed: 'Clé API supprimée',
    providers_key_placeholder_new: 'sk-...',
    providers_key_placeholder_replace: 'Entrez une nouvelle clé à remplacer…',
    provider_quota_title: 'Quota du fournisseur actif',
    provider_quota_active_provider: 'Fournisseur actif',
    provider_quota_last_checked_after_refresh: 'Dernière vérification après actualisation',
    provider_quota_last_checked: 'Dernière vérification {0}',
    provider_quota_refresh_usage: 'Actualiser l’utilisation',
    provider_quota_refreshing: 'Actualisation...',
    provider_quota_refresh_title: 'Actualiser maintenant les limites d’utilisation du fournisseur',
    provider_quota_refresh_succeeded: 'Utilisation du fournisseur actualisée',
    provider_quota_refresh_failed: 'Échec de l’actualisation de l’utilisation du fournisseur',
    provider_quota_session_limit: 'Limite de 5 heures',
    provider_quota_weekly_limit: 'Limite hebdomadaire',
    provider_quota_window_fallback: 'Fenêtre',
    provider_quota_metric_remaining: 'Restant',
    provider_quota_metric_used: 'Utilisé',
    provider_quota_metric_limit: 'Limite',
    provider_quota_status_available: 'disponible',
    provider_quota_status_exhausted: 'épuisé',
    provider_quota_status_unavailable: 'indisponible',
    provider_quota_status_failed: 'échec',
    provider_quota_status_checked: 'vérifié',
    provider_quota_status_no_key: 'aucune clé',
    provider_quota_status_invalid_key: 'clé non valide',
    provider_quota_status_unsupported: 'non pris en charge',
    provider_quota_used_meta: '{0} utilisé',
    provider_quota_resets_meta: 'réinitialisation {0}',
    provider_quota_credential_pool: 'Pool d’identifiants',
    provider_quota_credential_label: 'Identifiant {0}',
    provider_quota_pool_plans: 'Plans : {0}',
    provider_quota_pool_no_windows: 'Aucune fenêtre de limite de compte signalée.',
    provider_quota_account_limits_loaded: 'Limites de compte chargées.',
    provider_quota_unavailable: 'Statut du quota indisponible',
    provider_quota_retry_after: 'Réessayer après {0}',
    provider_quota_pool_summary_available: '{0}/{1} disponibles',
    provider_quota_pool_summary_exhausted: '{0} épuisés',
    provider_quota_pool_summary_failed: '{0} en échec',
    provider_quota_pool_summary_checked: '{0} vérifiés',
    cancel: 'Annuler',
    create_job: 'Créer un emploi',
    save_skill: 'Enregistrer la compétence',
    editing: 'Édition',
    empty_title: 'En quoi puis-je aider ?',
    empty_subtitle: 'Demandez n\'importe quoi, exécutez des commandes, explorez des fichiers ou gérez vos tâches planifiées.',
    suggest_files: 'Quels fichiers se trouvent dans cet espace de travail ?',
    suggest_schedule: 'Quel est mon programme aujourd\'hui ?',
    suggest_plan: 'Aide-moi à planifier un petit projet.',
    onboarding_badge: 'PREMIÈRE EXÉCUTION',
    onboarding_title: 'Bienvenue dans l\'interface utilisateur Web Hermès',
    onboarding_lead: 'Une configuration guidée rapide vérifiera Hermes, enregistrera une configuration réelle du fournisseur, choisira un espace de travail et un modèle et protégera éventuellement l\'application avec un mot de passe.',
    onboarding_back: 'Dos',
    onboarding_continue: 'Continuer',
    onboarding_skip: 'Ignorer la configuration',
    onboarding_skipped: 'Configuration ignorée – en utilisant la configuration existante.',
    onboarding_open: 'Hermès ouvert',
    onboarding_step_system_title: 'Vérification du système',
    onboarding_step_system_desc: 'Vérifiez la visibilité de l\'agent Hermes et de la configuration.',
    onboarding_step_setup_title: 'Configuration du fournisseur',
    onboarding_step_setup_desc: 'Enregistrez la configuration minimale du fournisseur Hermes.',
    onboarding_step_workspace_title: 'Espace de travail + modèle',
    onboarding_step_workspace_desc: 'Choisissez les valeurs par défaut pour les nouvelles sessions et le chat.',
    onboarding_step_password_title: 'Mot de passe facultatif',
    onboarding_step_password_desc: 'Protégez l’interface utilisateur Web avant de la partager.',
    onboarding_step_finish_title: 'Finition',
    onboarding_step_finish_desc: 'Vérifiez et entrez dans l\'application.',
    onboarding_notice_system_ready: 'L\'agent Hermes semble accessible depuis l\'interface utilisateur Web.',
    onboarding_notice_system_unavailable: 'Hermes Agent n’est pas encore entièrement disponible. Bootstrap peut l\'installer, mais la configuration du fournisseur peut toujours nécessiter un terminal.',
    onboarding_check_agent: 'Agent Hermès',
    onboarding_check_agent_ready: 'Détecté et importable',
    onboarding_check_agent_missing: 'Manquant ou partiellement importable',
    onboarding_check_password: 'Mot de passe',
    onboarding_check_password_enabled: 'Déjà activé',
    onboarding_check_password_disabled: 'Pas encore activé',
    onboarding_check_provider: 'Configuration du fournisseur',
    onboarding_check_provider_ready: 'Prêt à discuter',
    onboarding_check_provider_partial: 'Enregistré mais incomplet',
    onboarding_check_provider_pending: 'Vérification nécessaire',
    onboarding_config_file: 'Fichier de configuration :',
    onboarding_env_file: 'Fichier .env :',
    onboarding_unknown: 'Inconnu',
    onboarding_current_provider: 'Configuration actuelle :',
    onboarding_missing_imports: 'Importations manquantes :',
    onboarding_notice_setup_required: 'Choisissez ici un chemin de fournisseur simple. Les flux OAuth avancés appartiennent toujours à la CLI Hermes pour le moment.',
    onboarding_notice_setup_already_ready: 'Une configuration de fournisseur Hermes fonctionnelle est déjà détectée. Vous pouvez le conserver ou le remplacer ici.',
    onboarding_oauth_provider_ready_title: 'Fournisseur déjà authentifié',
    onboarding_oauth_provider_ready_body: 'Cette instance est configurée pour utiliser un fournisseur OAuth (<strong>{provider}</strong>) configuré via la CLI Hermes. Aucune clé API n\'est nécessaire ici - cliquez sur Continuer pour terminer la configuration.',
    onboarding_oauth_provider_not_ready_title: 'Fournisseur OAuth pas encore authentifié',
    onboarding_oauth_provider_not_ready_body: 'Cette instance est configurée pour utiliser <strong>{provider}</strong>, qui utilise OAuth plutôt qu\'une clé API. Exécutez <code>hermes auth</code> ou <code>hermes model</code> dans un terminal pour vous authentifier, puis rechargez l\'interface utilisateur Web.',
    onboarding_oauth_switch_hint: 'Ou choisissez un autre fournisseur ci-dessous pour passer à une configuration par clé API :',
    oauth_login_codex: 'Connectez-vous avec Codex (ChatGPT)',
    oauth_codex_step1: 'Étape 1 : Visitez cette URL et entrez le code',
    oauth_codex_step2: 'Étape 2 : Saisissez ce code sur la page',
    oauth_codex_polling: 'En attente d\'autorisation...',
    oauth_codex_success: 'Connexion au Codex OAuth réussie !',
    oauth_codex_error: 'Échec de la connexion OAuth',
    oauth_codex_expired: 'Code expiré, veuillez réessayer',
    onboarding_notice_workspace: 'Ces valeurs réutilisent les mêmes API de paramètres que l\'application normale.',
    onboarding_workspace_label: 'Espace de travail',
    onboarding_workspace_or_path: 'Ou entrez un chemin d\'espace de travail',
    onboarding_workspace_placeholder: '/accueil/vous/espace de travail',
    onboarding_provider_label: 'Mode configuration',
    onboarding_quick_setup_badge: 'configuration rapide',
    provider_category_easy_start: 'Démarrage facile',
    provider_category_self_hosted: 'Ouvert / auto-hébergé',
    provider_category_specialized: 'Spécialisé',
    onboarding_api_key_label: 'Clé API',
    onboarding_api_key_placeholder: 'Laisser vide pour conserver une clé enregistrée existante',
    onboarding_api_key_label_optional: 'Clé API (facultatif)',
    onboarding_api_key_placeholder_optional: 'Laisser vide pour les serveurs sans clé',
    onboarding_api_key_help_keyless: 'La plupart des installations LM Studio / Ollama / vLLM s\'exécutent sans clé — laissez ce champ vide si votre serveur ne nécessite pas d\'authentification. Utilisez le bouton Tester la connexion pour vérifier.',
    onboarding_api_key_help_prefix: 'Enregistré comme secret dans votre fichier Hermes .env en utilisant',
    onboarding_base_url_label: 'URL de base',
    onboarding_base_url_placeholder: 'https://votre-endpoint.example/v1',
    onboarding_base_url_help: 'Utilisez-le pour les routeurs compatibles OpenAI, les serveurs auto-hébergés, LiteLLM, Ollama, LM Studio, vLLM ou des points de terminaison similaires.',
    onboarding_model_label: 'Modèle par défaut',
    onboarding_workspace_help: 'Choisissez le modèle qu\'Hermes doit utiliser pour les nouvelles discussions une fois la configuration terminée.',
    onboarding_custom_model_placeholder: 'votre-nom-de-modèle',
    onboarding_custom_model_help: 'Pour les points de terminaison personnalisés, entrez l’ID de modèle exact attendu par votre serveur.',
    onboarding_notice_password_enabled: 'Un mot de passe est déjà configuré. Saisissez-en un nouveau uniquement si vous souhaitez le remplacer.',
    onboarding_notice_password_recommended: 'Facultatif mais recommandé si vous exposez l\'interface utilisateur au-delà de localhost.',
    onboarding_password_label: 'Mot de passe (facultatif)',
    onboarding_password_placeholder: 'Laisser vide pour sauter',
    onboarding_password_help: 'Les mots de passe sont stockés via l\'API des paramètres existants et hachés côté serveur.',
    onboarding_notice_finish: 'Vous pouvez rouvrir les paramètres plus tard pour modifier tout cela.',
    onboarding_not_set: 'Non défini',
    onboarding_password_will_enable: 'Sera activé',
    onboarding_password_will_replace: 'Sera remplacé',
    onboarding_password_keep_existing: 'Conserver le mot de passe actuel',
    onboarding_password_remains_disabled: 'Restera invalide',
    onboarding_password_skipped: 'Ignoré pour l\'instant',
    onboarding_finish_help: 'La finition stocke <code>onboarding_completed</code> dans les paramètres et vous amène dans l\'application normale.',
    onboarding_error_choose_workspace: 'Choisissez un espace de travail avant de continuer.',
    onboarding_error_choose_model: 'Choisissez un modèle avant de continuer.',
    onboarding_error_provider_required: 'Choisissez un mode de configuration avant de continuer.',
    onboarding_error_base_url_required: 'L\'URL de base est requise pour les points de terminaison personnalisés.',
    onboarding_probe_test_button: 'Tester la connexion',
    onboarding_probe_probing: 'Test de connexion…',
    onboarding_probe_ok: 'Connecté. {n} modèle(s) disponible(s).',
    onboarding_probe_error_generic: 'Impossible d\'atteindre l\'URL de base configurée.',
    onboarding_probe_error_invalid_url: 'L\'URL de base doit commencer par http:// ou https://.',
    onboarding_probe_error_dns: 'Impossible de résoudre l\'hôte. Vérifiez l\'URL ou utilisez l\'adresse IP de l\'hôte.',
    onboarding_probe_error_connect_refused: 'Connexion refusée : le serveur ne fonctionne peut-être pas à cette adresse. Depuis Docker, essayez l’adresse IP de l’hôte au lieu de localhost.',
    onboarding_probe_error_timeout: 'Le point final n’a pas répondu à temps. Vérifiez que le serveur est en cours d\'exécution et que l\'URL est correcte.',
    onboarding_probe_error_http_4xx: 'Le point de terminaison a renvoyé une erreur client. Vérifiez l\'authentification et le chemin de l\'URL (se termine généralement par /v1).',
    onboarding_probe_error_http_5xx: 'Le point de terminaison a renvoyé une erreur de serveur. Vérifiez les journaux du serveur LM Studio / Ollama.',
    onboarding_probe_error_parse: 'Le point de terminaison n’a pas renvoyé une liste de modèles sous la forme attendue. Vérifiez que l\'URL pointe vers la racine de l\'API compatible OpenAI.',
    onboarding_probe_error_unreachable: 'Impossible d\'atteindre l\'URL de base configurée.',
    onboarding_error_probe_failed: 'Impossible de valider l\'URL de base configurée.',
    onboarding_error_workspace_required: 'Un espace de travail est requis.',
    onboarding_error_model_required: 'Un modèle est requis.',
    onboarding_complete: 'Intégration terminée',
    error_prefix: 'Erreur:',
    not_available: 'N / A',
    never: 'jamais',
    add: 'Ajouter',
    add_failed: 'Échec de l\'ajout :',
    remove_failed: 'Échec de la suppression :',
    switch_failed: 'Échec du changement :',
    name_required: 'Le nom est requis',
    content_required: 'Le contenu est requis',
    view: 'Voir',
    dismiss: 'Rejeter',
    disable: 'Désactiver',
    cron_no_jobs: 'Aucune tâche planifiée trouvée.',
    cron_status_off: 'désactivé',
    cron_status_paused: 'en pause',
    cron_status_error: 'erreur',
    cron_status_active: 'actif',
    cron_status_running: 'courir\u2026',
    cron_status_needs_attention: 'a besoin d\'attention',
    cron_attention_desc: 'Cette tâche récurrente n\'a pas de prochaine exécution. Le planificateur n\'a peut-être pas réussi à calculer sa prochaine exécution.',
    cron_attention_croniter_hint: 'Il se peut que le package croniter soit manquant dans le runtime Gateway. Redémarrez la passerelle avec la prise en charge de cron, puis reprenez ce travail.',
    cron_attention_resume: 'Reprendre et recalculer',
    cron_jobs_project: 'Emplois Cron',
    cron_attention_run_once: 'Cours une fois maintenant',
    cron_attention_copy_diagnostics: 'Copier les diagnostics',
    cron_diagnostics_copied: 'Diagnostics Cron copiés',
    cron_next: 'Suivant',
    cron_last: 'Dernier',
    cron_run_now: 'Courez maintenant',
    cron_pause: 'Pause',
    cron_resume: 'CV',
    cron_job_name_placeholder: 'Nom du travail',
    cron_schedule_placeholder: 'Calendrier',
    cron_prompt_placeholder: 'Rapide',
    cron_last_output: 'Dernière sortie',
    cron_expand_prompt: 'Développer le prompt',
    cron_collapse_prompt: 'Réduire le prompt',
    cron_expand_output: 'Développer la sortie',
    cron_collapse_output: 'Réduire la sortie',
    cron_all_runs: 'Toutes les courses',
    cron_hide_runs: 'Masquer les courses',
    cron_no_runs_yet: '(pas encore de courses)',
    cron_schedule_required_example: 'Un horaire est requis (par exemple "0 9 * * *" ou "toutes les 1h")',
    cron_schedule_required: 'Un horaire est requis',
    cron_prompt_required: 'Une invite est requise',
    cron_job_created: 'Emploi créé',
    cron_duplicate: 'Double',
    cron_duplicated: 'Tâche dupliquée (en pause)',
    cron_job_triggered: 'Tâche déclenchée',
    cron_job_paused: 'Tâche suspendue',
    cron_job_resumed: 'Travail repris',
    cron_job_updated: 'Emploi mis à jour',
    cron_delete_confirm_title: 'Supprimer la tâche cron',
    cron_delete_confirm_message: 'Cela ne peut pas être annulé.',
    cron_job_deleted: 'Travail supprimé',
    status_failed: 'échoué',
    status_completed: 'complété',
    todos_no_active: 'Aucune liste de tâches active dans cette session.',
    clear_conversation_title: 'Conversation claire',
    clear_conversation_message: 'Effacer tous les messages ? Cela ne peut pas être annulé.',
    clear_failed: 'Échec de la suppression :',
    skills_no_match: 'Aucune compétence ne correspond.',
    linked_files: 'Fichiers liés',
    skill_load_failed: 'Impossible de charger la compétence :',
    skill_file_load_failed: 'Impossible de charger le fichier :',
    skill_name_required: 'Le nom de la compétence est requis',
    skill_updated: 'Compétence mise à jour',
    skill_created: 'Compétence créée',
    skill_deleted: 'Compétence supprimée',
    skill_delete_confirm: 'Supprimer la compétence "{0}" ?',
    skills_empty_title: 'Sélectionnez une compétence',
    skills_empty_sub: 'Choisissez une compétence dans la barre latérale pour afficher son contenu ou créez-en une nouvelle.',
    skills_edit: 'Modifier',
    skills_delete: 'Supprimer',
    skills_back_to: 'Retour à {0}',
    tasks_empty_title: 'Sélectionnez une tâche planifiée',
    tasks_empty_sub: 'Choisissez une tâche dans la barre latérale pour afficher ses détails et ses exécutions, ou créez-en une nouvelle.',
    workspaces_empty_title: 'Sélectionnez un espace',
    workspaces_empty_sub: 'Choisissez un espace dans la barre latérale pour afficher ses fichiers et paramètres, ou ajoutez-en un nouveau.',
    profiles_empty_title: 'Sélectionnez un profil',
    profiles_empty_sub: 'Choisissez un profil d\'agent dans la barre latérale pour afficher et modifier ses paramètres, ou créez-en un nouveau.',
    memory_notes_label: 'mémoire (notes)',
    memory_saved: 'Mémoire sauvegardée',
    my_notes: 'Mes notes',
    user_profile: 'Profil utilisateur',
    no_notes_yet: 'Aucune note pour l\'instant.',
    no_profile_yet: 'Pas encore de profil.',
    agent_soul: 'Âme de l\'agent',
    no_soul_yet: 'Pas encore d\'âme définie.',
    workspace_choose_path: 'Choisir le chemin de l\'espace de travail',
    workspace_choose_path_meta: 'Ajoutez un chemin validé et changez cette conversation',
    workspace_manage: 'Gérer les espaces de travail',
    workspace_manage_meta: 'Ouvrez le panneau Espaces',
    workspace_use_title: 'Utiliser dans la session en cours',
    workspace_use: 'Utiliser',
    workspace_add_path_placeholder: 'Ajouter un chemin d\'accès à l\'espace de travail (par exemple /home/user/my-project)',
    workspace_paths_validated_hint: 'Les chemins sont validés en tant que répertoires existants avant d\'être enregistrés.',
    workspace_drag_hint: 'Faites glisser pour réorganiser',
    workspace_reorder_failed: 'Échec de la réorganisation',
    workspace_added: 'Espace de travail ajouté',
    workspace_renamed: 'Espace de travail renommé',
    workspace_remove_confirm_title: 'Supprimer l\'espace de travail',
    workspace_removed: 'Espace de travail supprimé',
    workspace_switch_prompt_title: 'Changer d\'espace de travail',
    workspace_switch_prompt_message: 'Entrez un chemin d’accès absolu à l’espace de travail vers lequel ajouter et basculer cette conversation.',
    workspace_switch_prompt_confirm: 'Changer',
    workspace_switch_prompt_placeholder: '/Utilisateurs/vous/projet',
    workspace_not_added: 'L\'espace de travail n\'a pas été ajouté',
    workspace_already_saved: 'Espace de travail déjà enregistré : choisissez-le dans la liste',
    workspace_busy_switch: 'Impossible de changer d\'espace de travail pendant que l\'agent est en cours d\'exécution',
    discard_file_edits_title: 'Supprimer les modifications du fichier ?',
    discard_file_edits_message: 'Changer d’espace de travail supprimera les modifications de fichiers non enregistrées dans l’aperçu.',
    profiles_no_profiles: 'Aucun profil trouvé.',
    profile_api_keys_configured: 'Clés API configurées',
    profile_gateway_running: 'Passerelle en cours d\'exécution',
    profile_gateway_stopped: 'Passerelle arrêtée',
    profile_active: 'ACTIF',
    profile_no_configuration: 'Aucune configuration',
    profile_use: 'Utiliser',
    profile_switch_title: 'Passer à ce profil',
    profile_delete_title: 'Supprimer ce profil',
    profile_default_label: '(défaut)',
    profile_name_placeholder: 'Nom du profil (minuscules, a-z 0-9 tirets)',
    profile_clone_label: 'Cloner la configuration du profil actif',
    profile_model_label: 'Modèle / fournisseur',
    profile_model_hint: 'Choisissez parmi les fournisseurs et modèles configurés pour ce nouveau profil.',
    profile_model_use_default: 'Utiliser la valeur par défaut du profil actif',
    profile_base_url_placeholder: 'URL de base (facultatif, par exemple http://localhost:11434)',
    profile_api_key_placeholder: 'Clé API (facultatif)',
    manage_profiles: 'Gérer les profils',
    profiles_load_failed: 'Échec du chargement des profils',
    profile_name_rule: 'Lettres minuscules, chiffres, traits d\'union et traits de soulignement uniquement',
    profile_base_url_rule: 'L\'URL de base doit commencer par http:// ou https://',
    profile_delete_confirm_message: 'Toutes les sessions, configurations, compétences et mémoire de ce profil seront définitivement supprimées. Cela ne peut pas être annulé.',
    active_conversation_none: 'Aucune conversation active sélectionnée.',
    settings_unsaved_changes: 'Vous avez des modifications non enregistrées.',
    sign_out_failed: 'Échec de la déconnexion :',
    disable_auth_confirm_title: 'Désactiver la protection par mot de passe',
    disable_auth_confirm_message: 'Tout le monde pourra accéder à cette instance.',
    auth_disabled: 'Authentification désactivée – protection par mot de passe supprimée',
    disable_auth_failed: 'Échec de la désactivation de l\'authentification :',
    skill_name: 'Nom',
    skill_category: 'Catégorie',
    skill_category_placeholder: 'Facultatif, par ex. développeurs',
    skill_content: 'Contenu SKILL.md',
    skill_content_placeholder: 'Frontmatter YAML + corps de démarque',
    skill_rename_not_supported: 'Renommer une compétence n\'est pas pris en charge. Créez une nouvelle compétence et supprimez l\'ancienne pour la renommer.',
    skill_metadata: 'Métadonnées',
    cron_name_label: 'Nom',
    cron_name_placeholder: 'Facultatif',
    cron_schedule_label: 'Calendrier',
    cron_schedule_hint: 'Utilisez « toutes les heures » ou une expression cron pour les tâches récurrentes. Les durées nues comme « 30 m » s\'exécutent une fois.',
    cron_schedule_once_warning: 'Les formulaires de durée tels que « 30 m » s\'exécutent une fois et sont supprimés après l\'exécution. Utilisez « tous les 30 mois » pour conserver une tâche récurrente.',
    cron_prompt_label: 'Rapide',
    cron_deliver_label: 'Livrer la sortie à',
    cron_deliver_local: 'Local (enregistrer la sortie uniquement)',
    cron_profile_label: 'Profil',
    cron_profile_server_default: 'serveur par défaut',
    cron_profile_server_default_hint: 'Utilise le profil par défaut du serveur WebUI au moment de l\'exécution. Les tâches existantes sans profil conservent ce comportement hérité.',
    cron_toast_notifications_label: 'Toasts d’achèvement',
    cron_toast_notifications_hint: 'Montrez un toast lorsque ce cron se termine. Le badge Tâches et le marqueur de nouvelle exécution sont toujours mis à jour lorsque cette option est désactivée.',
    cron_toast_notifications_enabled: 'Activé',
    cron_toast_notifications_disabled: 'Désactivé',
    cron_skills_label: 'Compétences',
    cron_skills_placeholder: 'Ajouter des compétences (facultatif)…',
    cron_skills_edit_hint: 'La liste de compétences n\'est pas modifiable après la création.',
    workspace_name_label: 'Nom',
    workspace_name_placeholder: 'Nom convivial facultatif',
    workspace_path_label: 'Chemin',
    workspace_path_required: 'Le chemin est obligatoire',
    workspace_path_readonly: 'Le chemin ne peut pas être modifié. Renommer uniquement.',
    workspace_new_title: 'Nouvel espace',
    profile_name_label: 'Nom',
    profile_base_url_label: 'URL de base',
    profile_api_key_label: 'Clé API',
    cmd_yolo: 'Basculer le mode YOLO (ignorer les approbations)',
    yolo_no_session: 'Aucune session active',
    yolo_enabled: '⚡ Mode YOLO activé – les approbations ont ignoré cette session',
    yolo_disabled: 'Mode YOLO désactivé',
    yolo_pill_label: 'YOLO',
    yolo_pill_title_active: 'Mode YOLO actif — cliquez pour désactiver',
    approval_skip_all: '⚡ Passer toute cette session',
    approval_skip_all_title: 'Ignorer toutes les invites d\'approbation pour cette session',
    composer_send: 'Envoyer un message',
    composer_queue: 'Message de file d\'attente',
    composer_interrupt: 'Interrompre et envoyer',
    composer_steer: 'Piloter la réponse actuelle',
    composer_stop: 'Arrêter la génération',
    composer_disabled_clarify: 'Répondre à la demande de précisions',
    composer_disabled_compression: 'En attendant la fin de la compression',
    composer_disabled_empty: 'Tapez un message à envoyer',
    composer_mobile_workspace: 'Espace de travail',
    composer_mobile_model: 'Modèle',
    composer_mobile_reasoning: 'Raisonnement',
    composer_mobile_context: 'Contexte',
    media_audio_label: 'Audio',
    media_svg_label: 'Diagramme',
    media_video_label: 'Vidéo',
    csv_loading: 'Chargement du fichier CSV',
    csv_too_large: 'Fichier CSV trop volumineux pour le rendu en ligne',
    csv_no_data: 'Le fichier CSV ne contient pas suffisamment de données pour être affiché sous forme de tableau',
    csv_error: 'Échec du chargement du fichier CSV',
    csv_header_note: 'Première ligne affichée comme en-tête du tableau',
    excalidraw_loading: 'Diagramme de chargement',
    excalidraw_too_large: 'Fichier Excalidraw trop volumineux pour le rendu en ligne',
    excalidraw_invalid: 'Format de fichier Excalidraw invalide',
    excalidraw_error: 'Échec du chargement du fichier Excalidraw',
    excalidraw_label: 'Diagramme',
    excalidraw_download: 'Télécharger',
    excalidraw_empty: 'Diagramme vide',
    excalidraw_render_error: 'Échec du rendu du diagramme',
    excalidraw_simplified: 'Aperçu SVG simplifié — pas identique au pixel au canevas Excalidraw',
    checkpoint_title: 'Points de contrôle',
    checkpoint_empty: 'Aucun point de contrôle trouvé pour cet espace de travail.',
    checkpoint_loading: 'Chargement des points de contrôle…',
    checkpoint_error: 'Échec du chargement des points de contrôle',
    checkpoint_date: 'Date',
    checkpoint_message: 'Message',
    checkpoint_files: 'Fichiers',
    checkpoint_view_diff: 'Voir la différence',
    checkpoint_restore: 'Restaurer',
    checkpoint_restore_confirm_title: 'Restaurer le point de contrôle ?',
    checkpoint_restored: 'Point de contrôle restauré',
    checkpoint_diff_title: 'Changements au point de contrôle',
    checkpoint_diff_no_changes: 'Aucune différence trouvée entre ce point de contrôle et l\'espace de travail actuel.',

    // === Missing keys (FR translation completion) ===
    bg_complete: 'Tâche en arrière-plan terminée',
    bg_failed: 'Échec de la tâche en arrière-plan : ',
    bg_label: 'Résultat en arrière-plan :',
    bg_no_answer: '(aucune réponse)',
    bg_running: 'Exécution en arrière-plan…',
    branch_failed: 'Échec du fork : ',
    branch_forked: 'Conversation forkée dans une nouvelle session',
    btw_asking: 'Question annexe en cours…',
    btw_done: 'Question annexe répondue',
    btw_failed: 'Échec de la question annexe : ',
    btw_label: 'Question annexe — hors historique',
    btw_no_answer: 'Aucune réponse reçue.',
    cancel_unavailable: 'Annulation indisponible.',
    cmd_background: 'Exécuter une commande en arrière-plan',
    cmd_background_usage: '/background <prompt> — exécute en parallèle sans bloquer',
    cmd_branch: 'Forker cette conversation dans une nouvelle session',
    cmd_branch_usage: '/branch [nom] — forke la conversation (avec un nom optionnel)',
    cmd_btw: 'Poser une question annexe (éphémère)',
    cmd_btw_usage: '/btw <question> — pose une question annexe en utilisant le contexte de la session',
    cmd_retry: 'Renvoyer le dernier message',
    cmd_status: 'Afficher les infos de la session',
    cmd_stop: 'Arrêter la réponse en cours',
    cmd_title: 'Obtenir ou définir le titre de la session',
    cmd_undo: 'Supprimer le dernier échange',
    cmd_voice: 'Activer/désactiver le micro',
    cmd_voice_use_mic: 'Cliquez sur le bouton micro dans le composeur.',
    cmd_webui_only_session: 'Cette commande n\'est pas disponible pour les sessions importées en CLI.',
    folder_add_as_space_btn: 'Ajouter comme espace',
    folder_add_as_space_msg: 'Ajouter ce dossier comme nouvel espace dans votre liste ?',
    folder_add_as_space_title: 'Ajouter comme espace ?',
    fork_from_here: 'Forker à partir d\'ici',
    forked_from: 'Forké depuis',
    kanban_archive_board: 'Archiver le tableau courant…',
    kanban_archive_board_confirm: 'Archiver le tableau « {name} » ? Les tâches restent sur disque et le tableau peut être restauré depuis kanban/boards/_archived/.',
    kanban_back_to_board: 'Retour au tableau',
    kanban_block: 'Bloquer',
    kanban_board_archived: 'Tableau archivé',
    kanban_board_color: 'Couleur (optionnel)',
    kanban_board_description: 'Description (optionnel)',
    kanban_board_icon: 'Icône (emoji, optionnel)',
    kanban_board_name: 'Nom',
    kanban_board_name_required: 'Le nom est requis',
    kanban_board_slug: 'Slug (minuscules, tirets)',
    kanban_board_slug_required: 'Le slug est requis',
    kanban_bulk_action: 'Action groupée',
    kanban_card_archive: 'archiver',
    kanban_card_complete: 'terminer',
    kanban_lanes_by_profile: 'Colonnes par profil',
    kanban_new_board: 'Nouveau tableau…',
    kanban_nudge_dispatcher: 'Aperçu du dispatcher',
    kanban_only_mine: 'Seulement les miennes',
    kanban_rename_board: 'Renommer le tableau courant…',
    kanban_stats: 'Statistiques',
    kanban_unassigned: 'non assigné',
    kanban_unblock: 'Débloquer',
    kanban_worker_log: 'Journal du worker',
    no_active_task: 'Aucune tâche active à arrêter.',
    retrieval_context_label: 'Contexte indexé',
    retrieval_context_preview: 'Les messages plus anciens sont stockés et récupérables via les outils de contexte',
    retry_failed: 'Échec de la nouvelle tentative : ',
    slash_skill_badge: 'Skill',
    slash_skill_desc: 'Invoquer cette skill',
    status_agent_running: 'Agent en cours d\'exécution',
    status_heading: 'État de la session',
    status_load_failed: 'Échec du chargement de l\'état : ',
    status_messages: 'Messages',
    status_model: 'Modèle',
    status_no: 'Non',
    status_personality: 'Personnalité',
    status_provider: 'Fournisseur',
    status_session_id: 'ID de session',
    status_title: 'Titre',
    status_workspace: 'Espace de travail',
    status_yes: 'Oui',
    stream_stopped: 'Réponse arrêtée.',
    subagent_children: 'Sous-sessions de sous-agents',
    title_change_hint: 'Utilisez `/title <nouveau nom>` pour renommer.',
    title_current: 'Titre actuel',
    title_set: 'Titre défini sur',
    undid_messages_suffix: 'message(s).',
    undid_n_messages: 'Supprimé',
    undo_exchange: 'Annuler le dernier échange',
    undo_failed: 'Échec de l\'annulation : ',
    usage_default_model: 'par défaut',
    usage_estimated_cost: 'Coût estimé',
    usage_heading: 'Consommation de tokens',
    usage_input_tokens: 'Tokens d\'entrée',
    usage_load_failed: 'Échec du chargement de la consommation : ',
    usage_output_tokens: 'Tokens de sortie',
    usage_settings_tip: 'Note : les estimations de coût sont approximatives.',
    usage_total: 'Total de tokens',
    usage_unknown: 'inconnu',
    workspace_auto_create_folder: 'Créer le dossier s\'il n\'existe pas',
  }
};

// Active locale — defaults to English; overridden by loadLocale() at boot.
let _locale = LOCALES.en;

/**
 * Resolve an incoming locale tag to a known LOCALES key.
 * Supports exact keys, case-insensitive matches, and a few common aliases
 * (e.g. zh-CN -> zh, zh-TW -> zh-Hant). Returns null when unresolved.
 * @param {string} lang
 * @returns {string|null}
 */
function resolveLocale(lang) {
  if (typeof lang !== 'string') return null;
  const raw = lang.trim();
  if (!raw) return null;
  if (LOCALES[raw]) return raw;

  const lower = raw.toLowerCase().replace(/_/g, '-');

  // Case-insensitive direct match first.
  const direct = Object.keys(LOCALES).find((k) => k.toLowerCase() === lower);
  if (direct) return direct;

  // Common Chinese variants.
  if (lower === 'zh' || lower.startsWith('zh-cn') || lower.startsWith('zh-sg') || lower.startsWith('zh-hans')) {
    return LOCALES.zh ? 'zh' : null;
  }
  if (lower.startsWith('zh-tw') || lower.startsWith('zh-hk') || lower.startsWith('zh-mo') || lower.startsWith('zh-hant')) {
    return LOCALES['zh-Hant'] ? 'zh-Hant' : null;
  }

  // Fallback to base language subtag (e.g. en-US -> en).
  const base = lower.split('-')[0];
  const baseMatch = Object.keys(LOCALES).find((k) => k.toLowerCase() === base);
  return baseMatch || null;
}

/**
 * Resolve locale with precedence:
 * 1) primary (typically server setting)
 * 2) fallback (typically localStorage)
 * 3) English
 * @param {string} primary
 * @param {string} fallback
 * @returns {string}
 */
function resolvePreferredLocale(primary, fallback) {
  return resolveLocale(primary) || resolveLocale(fallback) || 'en';
}

/**
 * Translate a key. Falls back to English if the key is missing in the active locale.
 * Supports function values (for interpolated strings): call t('key', arg).
 * @param {string} key
 * @param {...*} args - forwarded to function-valued translations
 * @returns {string}
 */
function t(key, ...args) {
  const val = _locale[key] ?? LOCALES.en[key];
  if (val === undefined) return key;  // final fallback: return key itself
  if (typeof val === 'function') return val(...args);
  if (args.length) {
    // Locale strings can use numbered placeholders like {0} and {1}.
    return String(val).replace(/\{(\d+)\}/g, (match, idx) => (
      Object.prototype.hasOwnProperty.call(args, idx) ? String(args[idx]) : match
    ));
  }
  return val;
}

/**
 * Switch locale by language code (e.g. 'en', 'zh').
 * Persists to localStorage and updates the <html lang> attribute.
 * @param {string} lang
 */
function setLocale(lang) {
  const resolved = resolveLocale(lang) || 'en';
  _locale = LOCALES[resolved];
  localStorage.setItem('hermes-lang', resolved);
  document.documentElement.lang = _locale._speech || resolved;
}

/**
 * Load locale from localStorage (called once at boot, before DOMContentLoaded).
 * Server-persisted preference is applied later in loadSettingsPanel().
 */
function loadLocale() {
  setLocale(resolvePreferredLocale(null, localStorage.getItem('hermes-lang')));
}

/**
 * Re-stamp all [data-i18n] elements in the DOM with the current locale.
 * Safe to call at any time — missing keys fall back to English.
 * Call after setLocale() to make static HTML text update without a reload.
 */
function applyLocaleToDOM() {
  document.querySelectorAll('[data-i18n]').forEach(el => {
    const key = el.getAttribute('data-i18n');
    const val = t(key);
    if (val && val !== key) el.textContent = val;
  });
  document.querySelectorAll('[data-i18n-title]').forEach(el => {
    const key = el.getAttribute('data-i18n-title');
    const val = t(key);
    if (!val || val === key) return;
    if (el.hasAttribute('data-tooltip')) {
      // Custom CSS tooltip is in use (#1775) — sync it and explicitly clear
      // the native `title` attribute so the slow ~1.5s browser tooltip never
      // co-fires alongside the fast custom tooltip.
      el.setAttribute('data-tooltip', val);
      if (el.hasAttribute('title')) el.removeAttribute('title');
    } else {
      // Element opted out of custom tooltips — fall back to the native title.
      el.title = val;
    }
  });
  document.querySelectorAll('[data-i18n-placeholder]').forEach(el => {
    const key = el.getAttribute('data-i18n-placeholder');
    const val = t(key);
    if (val && val !== key) el.placeholder = val;
  });
  document.querySelectorAll('[data-i18n-aria-label]').forEach(el => {
    const key = el.getAttribute('data-i18n-aria-label');
    const val = t(key);
    if (val && val !== key) el.setAttribute('aria-label', val);
  });
  if (typeof syncAppTitlebar === 'function') syncAppTitlebar();
}

// Apply saved locale immediately so there's no flash of English on reload.
loadLocale();
