/**
 * Dashboard Internationalization Module
 *
 * Single source of truth for all translatable UI strings.
 * Namespaced flat keys: "nav.messages", "common.save", "settings.language_label"
 * Supported languages: English (en), Spanish (es)
 *
 * Usage:
 *   import { t, tJs, SUPPORTED_LANGS } from "./i18n.js";
 *   t("nav.messages", "es")       // → "Mensajes"  (for HTML contexts)
 *   tJs("notif.no_notifications", "es")  // → JS-safe escaped string (for JS string contexts)
 */

export const translations = {
  // ─── Nav & Layout ───
  "nav.logout": { en: "Logout", es: "Cerrar sesión" },
  "nav.toggleMenu": { en: "Toggle menu", es: "Alternar menú" },
  "nav.toggleTheme": { en: "Toggle theme", es: "Cambiar tema" },
  // Panel nav names (keyed by panel id)
  "nav.nest": { en: "Crow's Nest", es: "Nido del Cuervo" },
  "nav.messages": { en: "Messages", es: "Mensajes" },
  "nav.memory": { en: "Memory", es: "Memoria" },
  "nav.blog": { en: "Blog", es: "Blog" },
  "nav.files": { en: "Files", es: "Archivos" },
  "nav.extensions": { en: "Extensions", es: "Extensiones" },
  "nav.skills": { en: "Skills", es: "Habilidades" },
  "nav.settings": { en: "Settings", es: "Ajustes" },
  "nav.contacts": { en: "Contacts", es: "Contactos" },
  "nav.projects": { en: "Projects", es: "Proyectos" },
  // Nav group headers — spine-aligned (W3-6)
  "nav.group.home": { en: "Home", es: "Inicio" },
  "nav.group.agents": { en: "Agents", es: "Agentes" },
  "nav.group.connections": { en: "Connections", es: "Conexiones" },
  "nav.group.workspace": { en: "Workspace", es: "Espacio de trabajo" },
  "nav.group.system": { en: "System", es: "Sistema" },
  // Legacy group header keys (kept so old customized configs that still reference
  // these group ids render translated names rather than bare ids)
  "nav.group.core": { en: "Core", es: "Principal" },
  "nav.group.content": { en: "Content", es: "Contenido" },
  "nav.group.media": { en: "Media", es: "Medios" },
  "nav.group.education": { en: "Education", es: "Educación" },
  "nav.group.tools": { en: "Tools", es: "Herramientas" },

  // ─── Login ───
  "login.title": { en: "Login", es: "Iniciar sesión" },
  "login.setupTitle": { en: "Setup", es: "Configuración" },
  "login.subtitle": { en: "Crow's Nest Login", es: "Inicio de sesión" },
  "login.setupSubtitle": { en: "Set your Crow's Nest password", es: "Establece tu contraseña" },
  "login.passwordPlaceholder": { en: "Password", es: "Contraseña" },
  "login.choosePasswordPlaceholder": { en: "Choose a password (12+ characters)", es: "Elige una contraseña (12+ caracteres)" },
  "login.confirmPlaceholder": { en: "Confirm password", es: "Confirmar contraseña" },
  "login.loginButton": { en: "Login", es: "Iniciar sesión" },
  "login.setPasswordButton": { en: "Set Password", es: "Establecer contraseña" },
  "login.setupTokenError": { en: "Use the link you were sent to set up your password.", es: "Usa el enlace que te enviaron para establecer tu contraseña." },
  "login.2faTitle": { en: "Two-Factor Authentication", es: "Autenticación de dos factores" },
  "login.2faSubtitle": { en: "Enter the code from your authenticator app", es: "Ingresa el código de tu aplicación autenticadora" },
  "login.2faPlaceholder": { en: "000000", es: "000000" },
  "login.2faVerifyButton": { en: "Verify", es: "Verificar" },
  "login.2faTrustDevice": { en: "Trust this device for 30 days", es: "Confiar en este dispositivo por 30 días" },
  "login.2faUseRecovery": { en: "Use a recovery code instead", es: "Usar un código de recuperación" },
  "login.2faRecoveryTitle": { en: "Recovery Code", es: "Código de recuperación" },
  "login.2faRecoverySubtitle": { en: "Enter one of your recovery codes", es: "Ingresa uno de tus códigos de recuperación" },
  "login.2faRecoveryButton": { en: "Submit", es: "Enviar" },
  "login.backToLogin": { en: "Back to login", es: "Volver al inicio de sesión" },
  "login.2faSetupTitle": { en: "Set Up Two-Factor Authentication", es: "Configurar autenticación de dos factores" },
  "login.2faSetupSubtitle": { en: "Scan this QR code with your authenticator app", es: "Escanea este código QR con tu aplicación autenticadora" },
  "login.2faManualKey": { en: "Manual key", es: "Clave manual" },
  "login.2faRecoveryCodes": { en: "Recovery Codes", es: "Códigos de recuperación" },
  "login.2faSaveCodesWarning": { en: "Save these codes — they will not be shown again.", es: "Guarda estos códigos — no se mostrarán de nuevo." },
  "login.2faSetupVerifyButton": { en: "Verify & Enable 2FA", es: "Verificar y activar 2FA" },
  "login.2faInvalidCode": { en: "Invalid code. Please try again.", es: "Código inválido. Inténtalo de nuevo." },
  "login.2faSessionExpired": { en: "Session expired. Please log in again.", es: "Sesión expirada. Inicia sesión de nuevo." },
  "login.2faRequired": { en: "Two-factor authentication is required. Please set it up to continue.", es: "La autenticación de dos factores es obligatoria. Configúrala para continuar." },
  "login.forgotPassword": { en: "Forgot password?", es: "¿Olvidaste tu contraseña?" },
  "login.resetTitle": { en: "Reset Password", es: "Restablecer contraseña" },
  "login.resetSubtitle": { en: "Reset your Crow's Nest password", es: "Restablece tu contraseña de Crow's Nest" },
  "login.resetSendButton": { en: "Send Reset Email", es: "Enviar correo de restablecimiento" },
  "login.resetSelfHosted": { en: "Run this command on your server to reset your password:", es: "Ejecuta este comando en tu servidor para restablecer tu contraseña:" },
  "login.resetEmailSent": { en: "If an email is on file, a reset link has been sent. Check your inbox.", es: "Si hay un correo registrado, se envió un enlace de restablecimiento. Revisa tu bandeja." },
  "login.resetNewPassword": { en: "Choose a new password", es: "Elige una nueva contraseña" },
  "login.resetPasswordButton": { en: "Reset Password", es: "Restablecer contraseña" },
  "login.resetSuccess": { en: "Password reset successfully. You can now log in.", es: "Contraseña restablecida exitosamente. Ya puedes iniciar sesión." },
  "login.resetInvalidToken": { en: "Invalid or expired reset link. Please request a new one.", es: "Enlace de restablecimiento inválido o expirado. Solicita uno nuevo." },
  "login.resetNotAvailable": { en: "Password reset is not available for this instance.", es: "El restablecimiento de contraseña no está disponible para esta instancia." },
  "login.lockoutSupport": { en: "Need help? Contact support", es: "¿Necesitas ayuda? Contacta soporte" },
  "login.lockoutSelfHosted": { en: "You can reset your password from the command line:", es: "Puedes restablecer tu contraseña desde la línea de comandos:" },

  // ─── Common ───
  "common.save": { en: "Save", es: "Guardar" },
  "common.cancel": { en: "Cancel", es: "Cancelar" },
  "common.delete": { en: "Delete", es: "Eliminar" },
  "common.edit": { en: "Edit", es: "Editar" },
  "common.remove": { en: "Remove", es: "Eliminar" },
  "common.back": { en: "Back", es: "Atrás" },
  "common.search": { en: "Search", es: "Buscar" },
  "common.clear": { en: "Clear", es: "Limpiar" },
  "common.previous": { en: "Previous", es: "Anterior" },
  "common.next": { en: "Next", es: "Siguiente" },
  "common.loading": { en: "Loading...", es: "Cargando..." },
  "common.error": { en: "Error", es: "Error" },
  "common.close": { en: "Close", es: "Cerrar" },

  // ─── Time formatting ───
  "time.justNow": { en: "just now", es: "ahora mismo" },
  "time.mAgo": { en: "m ago", es: "m atrás" },
  "time.hAgo": { en: "h ago", es: "h atrás" },
  "time.dAgo": { en: "d ago", es: "d atrás" },

  // ─── Kiosk Mode ───
  "kiosk.toggle": { en: "Companion", es: "Compañero" },
  "kiosk.exit": { en: "Exit Companion", es: "Salir del compañero" },
  "kiosk.unavailable": { en: "AI Companion is not running", es: "El compañero de IA no está activo" },

  // ─── Notifications ───
  "notif.systemHealth": { en: "System Health", es: "Estado del sistema" },
  "notif.notifications": { en: "Notifications", es: "Notificaciones" },
  "notif.clearAll": { en: "Clear all", es: "Limpiar todo" },
  "notif.noNotifications": { en: "No notifications", es: "Sin notificaciones" },
  "notif.errorLoading": { en: "Error loading", es: "Error al cargar" },
  "notif.failedToLoad": { en: "Failed to load", es: "Error al cargar" },
  "notif.dismiss": { en: "Dismiss", es: "Descartar" },
  "notif.status": { en: "Status", es: "Estado" },
  "notif.ram": { en: "RAM", es: "RAM" },
  "notif.cpus": { en: "CPUs", es: "CPUs" },
  "notif.uptime": { en: "Uptime", es: "Tiempo activo" },

  // ─── Player ───
  "player.previous": { en: "Previous", es: "Anterior" },
  "player.playPause": { en: "Play/Pause", es: "Reproducir/Pausar" },
  "player.next": { en: "Next", es: "Siguiente" },
  "player.close": { en: "Close", es: "Cerrar" },
  "player.playing": { en: "Playing...", es: "Reproduciendo..." },
  "player.paused": { en: "Paused", es: "Pausado" },

  // ─── Health / Nest Panel ───
  "health.pageTitle": { en: "Crow's Nest", es: "Nido del Cuervo" },
  "health.welcome": { en: "Welcome to the Crow's Nest", es: "Bienvenido al Nido del Cuervo" },
  "health.subtitle": { en: "System health at a glance", es: "Estado del sistema de un vistazo" },
  "health.cpu": { en: "CPU", es: "CPU" },
  "health.ram": { en: "RAM", es: "RAM" },
  "health.disk": { en: "Disk", es: "Disco" },
  "health.uptime": { en: "Uptime", es: "Tiempo activo" },
  "health.cpuUsage": { en: "CPU Usage", es: "Uso de CPU" },
  "health.memory": { en: "Memory", es: "Memoria" },
  "health.systemUptime": { en: "System Uptime", es: "Tiempo activo del sistema" },
  "health.systemResources": { en: "System Resources", es: "Recursos del sistema" },
  "health.docker": { en: "Docker", es: "Docker" },
  "health.database": { en: "Database", es: "Base de datos" },
  "health.dockerNotAvailable": { en: "Docker is not available or not running.", es: "Docker no está disponible o no se está ejecutando." },
  "health.containersTotal": { en: "containers total", es: "contenedores en total" },
  "health.running": { en: "running", es: "en ejecución" },
  "health.stopped": { en: "stopped", es: "detenidos" },
  "health.databaseSize": { en: "database size", es: "tamaño de la base de datos" },
  "health.memories": { en: "memories", es: "memorias" },
  "health.projects": { en: "projects", es: "proyectos" },
  "health.sources": { en: "sources", es: "fuentes" },
  "health.posts": { en: "posts", es: "publicaciones" },
  "health.contacts": { en: "contacts", es: "contactos" },
  "health.refreshHint": { en: "Reload the page to refresh stats.", es: "Recarga la página para actualizar las estadísticas." },
  "health.yourApps": { en: "Your Apps", es: "Tus aplicaciones" },
  "health.open": { en: "Open", es: "Abrir" },
  "health.runningStatus": { en: "Running", es: "En ejecución" },
  "health.stoppedStatus": { en: "Stopped", es: "Detenido" },

  // ─── Nest Panel ───
  "nest.pinned": { en: "Pinned", es: "Fijados" },
  "nest.instances": { en: "Instances", es: "Instancias" },
  "nest.openInstance": { en: "Open", es: "Abrir" },
  "nest.offlineSince": { en: "Offline since", es: "Sin conexión desde" },
  "nest.retry": { en: "Retry", es: "Reintentar" },

  // ─── Health strip (W3-3) ───
  "health.allgood": { en: "Everything looks good", es: "Todo funciona bien" },
  "health.statusDetails": { en: "Status details", es: "Detalles de estado" },
  "health.runBackupNow": { en: "Run backup now", es: "Hacer copia ahora" },
  "health.backupDone": { en: "Backup complete", es: "Copia completada" },
  "health.backupFailed": { en: "Backup failed", es: "Copia fallida" },
  "health.stripLabel": { en: "System status", es: "Estado del sistema" },

  // ─── Onboarding first-success (W3-3) ───
  "onboarding.firstMemory.title": { en: "Store a memory", es: "Guarda un recuerdo" },
  "onboarding.firstMemory.body": {
    en: "Ask your AI to remember something, or browse the Memory panel.",
    es: "Pídele a tu IA que recuerde algo, o explora el panel de Memoria.",
  },
  "onboarding.firstMemory.action": { en: "Open Memory", es: "Abrir Memoria" },
  "onboarding.firstAgent.title": { en: "Create an agent", es: "Crea un agente" },
  "onboarding.firstAgent.body": {
    en: "Set up a bot to run on Gmail, Discord, or other channels.",
    es: "Configura un bot para ejecutarse en Gmail, Discord u otros canales.",
  },
  "onboarding.firstAgent.action": { en: "Open Bot Builder", es: "Abrir Bot Builder" },
  "onboarding.firstConnect.title": { en: "Connect an AI client", es: "Conecta un cliente de IA" },
  "onboarding.firstConnect.body": {
    en: "Use Crow's memory and tools from Claude Code, Cursor, and others.",
    es: "Usa la memoria y herramientas de Crow desde Claude Code, Cursor y otros.",
  },
  "onboarding.firstConnect.action": { en: "Connect a client", es: "Conectar cliente" },
  "onboarding.celebration": { en: "You're all set up", es: "Todo está listo" },

  // ─── Messages Panel ───
  "messages.pageTitle": { en: "Messages", es: "Mensajes" },
  "messages.noChats": { en: "No chats", es: "Sin chats" },
  "messages.newConversation": { en: "New conversation or contact", es: "Nueva conversación o contacto" },
  "messages.newAiChat": { en: "New AI Chat", es: "Nuevo chat de IA" },
  "messages.aiChatDesc": { en: "Start a conversation with your AI provider", es: "Inicia una conversación con tu proveedor de IA" },
  "messages.generateInvite": { en: "Generate Invite", es: "Generar invitación" },
  "messages.generateInviteDesc": { en: "Create code to share with a friend", es: "Crea un código para compartir con un amigo" },
  "messages.acceptInvite": { en: "Accept Invite", es: "Aceptar invitación" },
  "messages.acceptInviteDesc": { en: "Paste an invite code from a contact", es: "Pega un código de invitación de un contacto" },
  "messages.generateInviteCode": { en: "Generate Invite Code", es: "Generar código de invitación" },
  "messages.acceptInviteButton": { en: "Accept Invite", es: "Aceptar invitación" },
  "messages.pasteInvitePlaceholder": { en: "Paste invite code...", es: "Pega el código de invitación..." },
  "messages.inviteGenerated": { en: "Invite generated:", es: "Invitación generada:" },
  "messages.inviteError": { en: "Invite error:", es: "Error de invitación:" },
  "messages.dismiss": { en: "Dismiss", es: "Descartar" },
  "messages.emptyTitle": { en: "Messages", es: "Mensajes" },
  "messages.emptyDesc": { en: "Select a conversation or click + to start.", es: "Selecciona una conversación o haz clic en + para comenzar." },
  "messages.typeMessage": { en: "Type a message...", es: "Escribe un mensaje..." },
  "messages.send": { en: "Send", es: "Enviar" },
  "messages.info": { en: "Info", es: "Info" },
  "messages.deleteConversation": { en: "Delete", es: "Eliminar" },
  "messages.deleteConfirm": { en: "Delete this conversation?", es: "¿Eliminar esta conversación?" },
  "messages.thinking": { en: "Thinking...", es: "Pensando..." },
  "messages.using": { en: "Using", es: "Usando" },
  "messages.error": { en: "Error:", es: "Error:" },
  "messages.unknown": { en: "Unknown", es: "Desconocido" },
  "messages.connectionError": { en: "Connection error:", es: "Error de conexión:" },
  "messages.contactNotFound": { en: "Contact not found", es: "Contacto no encontrado" },
  "messages.reply": { en: "Reply", es: "Responder" },
  "messages.replyingTo": { en: "Replying to", es: "Respondiendo a" },
  "messages.you": { en: "You", es: "Tú" },
  "messages.them": { en: "Them", es: "Ellos" },
  "messages.attachFile": { en: "Attach file", es: "Adjuntar archivo" },
  "messages.aiNotConfigured": { en: "AI provider not configured. Set one up in Settings first.", es: "Proveedor de IA no configurado. Configura uno en Ajustes primero." },
  "messages.newConversationTitle": { en: "New conversation", es: "Nueva conversación" },
  "messages.createChat": { en: "Create Chat", es: "Crear chat" },
  "messages.details": { en: "Details", es: "Detalles" },
  "messages.created": { en: "Created:", es: "Creado:" },
  "messages.tokens": { en: "Tokens:", es: "Tokens:" },
  "messages.deleteConversationAction": { en: "Delete Conversation", es: "Eliminar conversación" },
  "messages.status": { en: "Status", es: "Estado" },
  "messages.onlineStatus": { en: "Online", es: "En línea" },
  "messages.lastSeen": { en: "Last seen", es: "Visto por última vez" },
  "messages.security": { en: "Security", es: "Seguridad" },
  "messages.e2eEncrypted": { en: "End-to-end encrypted", es: "Cifrado de extremo a extremo" },
  "messages.blockContact": { en: "Block Contact", es: "Bloquear contacto" },
  "messages.unblockContact": { en: "Unblock Contact", es: "Desbloquear contacto" },
  "messages.blockConfirm": { en: "Block this contact? They won't be able to message you.", es: "¿Bloquear este contacto? No podrá enviarte mensajes." },
  "messages.clickToCopy": { en: "Click to copy", es: "Haz clic para copiar" },
  "messages.copied": { en: "Copied!", es: "¡Copiado!" },
  "messages.file": { en: "File", es: "Archivo" },

  // ─── Blog Panel ───
  "blog.pageTitle": { en: "Blog", es: "Blog" },
  "blog.total": { en: "Total", es: "Total" },
  "blog.published": { en: "Published", es: "Publicados" },
  "blog.drafts": { en: "Drafts", es: "Borradores" },
  "blog.liveBlog": { en: "Live Blog", es: "Blog en vivo" },
  "blog.rss": { en: "RSS", es: "RSS" },
  "blog.atom": { en: "Atom", es: "Atom" },
  "blog.postsSection": { en: "Posts", es: "Publicaciones" },
  "blog.noPostsYet": { en: "No posts yet", es: "Aún no hay publicaciones" },
  "blog.createFirstPost": { en: "Create your first post below.", es: "Crea tu primera publicación abajo." },
  "blog.newPost": { en: "New Post", es: "Nueva publicación" },
  "blog.editPrefix": { en: "Edit:", es: "Editar:" },
  "blog.titleAndContentRequired": { en: "Title and content are required.", es: "El título y el contenido son obligatorios." },
  "blog.tableTitle": { en: "Title", es: "Título" },
  "blog.tableStatus": { en: "Status", es: "Estado" },
  "blog.tableSlug": { en: "Slug", es: "Slug" },
  "blog.tableDate": { en: "Date", es: "Fecha" },
  "blog.tableActions": { en: "Actions", es: "Acciones" },
  "blog.publish": { en: "Publish", es: "Publicar" },
  "blog.unpublish": { en: "Unpublish", es: "Despublicar" },
  "blog.edit": { en: "Edit", es: "Editar" },
  "blog.delete": { en: "Delete", es: "Eliminar" },
  "blog.deleteConfirm": { en: "Delete this post?", es: "¿Eliminar esta publicación?" },
  "blog.titleLabel": { en: "Title", es: "Título" },
  "blog.titlePlaceholder": { en: "Post title", es: "Título de la publicación" },
  "blog.contentLabel": { en: "Content", es: "Contenido" },
  "blog.contentPlaceholder": { en: "Write in Markdown...", es: "Escribe en Markdown..." },
  "blog.togglePreview": { en: "Toggle Preview", es: "Alternar vista previa" },
  "blog.previewLabel": { en: "Preview:", es: "Vista previa:" },
  "blog.startTypingPreview": { en: "Start typing to see preview...", es: "Empieza a escribir para ver la vista previa..." },
  "blog.previewFailed": { en: "Preview failed", es: "Error en la vista previa" },
  "blog.tagsLabel": { en: "Tags", es: "Etiquetas" },
  "blog.tagsPlaceholder": { en: "tag1, tag2, tag3", es: "etiqueta1, etiqueta2, etiqueta3" },
  "blog.visibilityLabel": { en: "Visibility", es: "Visibilidad" },
  "blog.visibilityPrivate": { en: "Private", es: "Privado" },
  "blog.visibilityPublic": { en: "Public", es: "Público" },
  "blog.visibilityPeers": { en: "Peers Only", es: "Solo pares" },
  "blog.coverImage": { en: "Cover Image", es: "Imagen de portada" },
  "blog.saveChanges": { en: "Save Changes", es: "Guardar cambios" },
  "blog.createDraft": { en: "Create Draft", es: "Crear borrador" },
  "blog.boldTitle": { en: "Bold", es: "Negrita" },
  "blog.italicTitle": { en: "Italic", es: "Cursiva" },
  "blog.heading2Title": { en: "Heading 2", es: "Encabezado 2" },
  "blog.heading3Title": { en: "Heading 3", es: "Encabezado 3" },
  "blog.linkTitle": { en: "Link", es: "Enlace" },
  "blog.imageTitle": { en: "Image", es: "Imagen" },
  "blog.bulletListTitle": { en: "Bullet List", es: "Lista con viñetas" },
  "blog.numberedListTitle": { en: "Numbered List", es: "Lista numerada" },
  "blog.quoteTitle": { en: "Quote", es: "Cita" },
  "blog.inlineCodeTitle": { en: "Inline Code", es: "Código en línea" },
  "blog.codeBlockTitle": { en: "Code Block", es: "Bloque de código" },
  "blog.horizontalRuleTitle": { en: "Horizontal Rule", es: "Línea horizontal" },
  // W3-4: alert() → crowToast replacements (blog panel)
  "blog.uploadFailed": { en: "Image upload failed", es: "Error al subir la imagen" },
  "blog.uploadError": { en: "Upload error", es: "Error de carga" },

  // ─── Memory Panel ───
  "memory.pageTitle": { en: "Memory", es: "Memoria" },
  "memory.editPageTitle": { en: "Edit Memory", es: "Editar memoria" },
  "memory.viewPageTitle": { en: "View Memory", es: "Ver memoria" },
  "memory.totalMemories": { en: "Total Memories", es: "Total de memorias" },
  "memory.searchPlaceholder": { en: "Search memories...", es: "Buscar memorias..." },
  "memory.search": { en: "Search", es: "Buscar" },
  "memory.clear": { en: "Clear", es: "Limpiar" },
  "memory.searchResults": { en: "Search Results", es: "Resultados de búsqueda" },
  "memory.recentMemories": { en: "Recent Memories", es: "Memorias recientes" },
  "memory.noMemoriesYet": { en: "No memories yet", es: "Aún no hay memorias" },
  "memory.askAiToRemember": { en: "Ask your AI to remember something to get started.", es: "Pídele a tu IA que recuerde algo para comenzar." },
  "memory.categoryLabel": { en: "Category", es: "Categoría" },
  "memory.allCategories": { en: "All categories", es: "Todas las categorías" },
  "memory.importanceLabel": { en: "Importance", es: "Importancia" },
  "memory.contentLabel": { en: "Content", es: "Contenido" },
  "memory.updatedLabel": { en: "Updated", es: "Actualizado" },
  "memory.actionsLabel": { en: "Actions", es: "Acciones" },
  "memory.save": { en: "Save", es: "Guardar" },
  "memory.cancel": { en: "Cancel", es: "Cancelar" },
  "memory.edit": { en: "Edit", es: "Editar" },
  "memory.delete": { en: "Delete", es: "Eliminar" },
  "memory.deleteConfirm": { en: "Delete this memory?", es: "¿Eliminar esta memoria?" },
  "memory.previous": { en: "Previous", es: "Anterior" },
  "memory.next": { en: "Next", es: "Siguiente" },
  "memory.matches": { en: "matches", es: "coincidencias" },
  "memory.memoriesCount": { en: "memories", es: "memorias" },

  // ─── Files Panel ───
  "files.pageTitle": { en: "Files", es: "Archivos" },
  "files.filesCount": { en: "Files", es: "Archivos" },
  "files.images": { en: "Images", es: "Imágenes" },
  "files.used": { en: "Used", es: "Usado" },
  "files.quota": { en: "Quota", es: "Cuota" },
  "files.storage": { en: "Storage", es: "Almacenamiento" },
  "files.online": { en: "Online", es: "En línea" },
  "files.offline": { en: "Offline", es: "Sin conexión" },
  "files.storageQuota": { en: "Storage Quota", es: "Cuota de almacenamiento" },
  "files.storageCriticallyFull": { en: "Storage critically full — free space or increase quota", es: "Almacenamiento críticamente lleno — libera espacio o aumenta la cuota" },
  "files.storageUsageHigh": { en: "Storage usage is high — consider freeing space", es: "El uso de almacenamiento es alto — considera liberar espacio" },
  "files.upload": { en: "Upload", es: "Subir" },
  "files.dropFilesHere": { en: "Drop files here", es: "Suelta archivos aquí" },
  "files.orClickBrowse": { en: "or click to browse", es: "o haz clic para explorar" },
  "files.general": { en: "General", es: "General" },
  "files.blogMedia": { en: "Blog Media", es: "Medios del blog" },
  "files.sharedFile": { en: "Shared File", es: "Archivo compartido" },
  "files.all": { en: "All", es: "Todos" },
  "files.documents": { en: "Documents", es: "Documentos" },
  "files.other": { en: "Other", es: "Otros" },
  "files.noFilesYet": { en: "No files yet", es: "Aún no hay archivos" },
  "files.uploadHint": { en: "Upload files by dragging them into the zone above, or ask your AI to upload something.", es: "Sube archivos arrastrándolos a la zona de arriba, o pídele a tu IA que suba algo." },
  "files.storageNotConfigured": { en: "Storage not configured", es: "Almacenamiento no configurado" },
  "files.copyUrl": { en: "Copy URL", es: "Copiar URL" },
  "files.copied": { en: "Copied!", es: "¡Copiado!" },
  "files.deleteFile": { en: "Delete", es: "Eliminar" },
  "files.blogBadge": { en: "Blog", es: "Blog" },
  "files.sharedBadge": { en: "Shared", es: "Compartido" },
  "files.imageCategory": { en: "Image", es: "Imagen" },
  "files.docCategory": { en: "Doc", es: "Doc" },
  "files.fileCategory": { en: "File", es: "Archivo" },
  "files.filesSection": { en: "Files", es: "Archivos" },

  // ─── Extensions Panel ───
  "extensions.pageTitle": { en: "Extensions", es: "Extensiones" },
  "extensions.installed": { en: "Installed", es: "Instalados" },
  "extensions.runningLabel": { en: "Running", es: "En ejecución" },
  "extensions.available": { en: "Available", es: "Disponibles" },
  "extensions.installedSection": { en: "Installed", es: "Instalados" },
  "extensions.availableSection": { en: "Available Add-ons", es: "Complementos disponibles" },
  "extensions.noAddonsInstalled": { en: "No add-ons installed", es: "No hay complementos instalados" },
  "extensions.browseBelow": { en: "Browse available add-ons below to get started.", es: "Explora los complementos disponibles abajo para comenzar." },
  "extensions.registryUnavailable": { en: "Registry unavailable", es: "Registro no disponible" },
  "extensions.registryUnavailableDesc": { en: "Could not reach the add-on registry. Check your internet connection.", es: "No se pudo acceder al registro de complementos. Verifica tu conexión a internet." },
  "extensions.stoppedBadge": { en: "Stopped", es: "Detenido" },
  "extensions.runningBadge": { en: "Running", es: "En ejecución" },
  "extensions.mcpServer": { en: "MCP Server", es: "Servidor MCP" },
  "extensions.stop": { en: "Stop", es: "Detener" },
  "extensions.restart": { en: "Restart", es: "Reiniciar" },
  "extensions.start": { en: "Start", es: "Iniciar" },
  "extensions.remove": { en: "Remove", es: "Eliminar" },
  "extensions.install": { en: "Install", es: "Instalar" },
  "extensions.installedBadge": { en: "Installed", es: "Instalado" },
  "extensions.official": { en: "Official", es: "Oficial" },
  "extensions.community": { en: "Community", es: "Comunidad" },
  "extensions.communityNotVerified": { en: "Not verified by Crow", es: "No verificado por Crow" },
  "extensions.mcpServers": { en: "MCP Servers", es: "Servidores MCP" },
  "extensions.bundles": { en: "Bundles", es: "Paquetes" },
  "extensions.localRegistry": { en: "Showing local registry (remote unavailable)", es: "Mostrando registro local (remoto no disponible)" },
  "extensions.communityStores": { en: "Community Stores", es: "Tiendas de la comunidad" },
  "extensions.noStoresConfigured": { en: "No community stores configured.", es: "No hay tiendas de la comunidad configuradas." },
  "extensions.addStore": { en: "Add Store", es: "Agregar tienda" },
  "extensions.askAi": { en: "Or ask your AI:", es: "O pídele a tu IA:" },
  "extensions.devGuide": { en: "developer guide", es: "guía de desarrollo" },
  "extensions.toCreateOwn": { en: "To create your own, see the", es: "Para crear el tuyo, consulta la" },
  "extensions.installTitle": { en: "Install", es: "Instalar" },
  "extensions.communityWarningTitle": { en: "Community add-on — not verified by Crow", es: "Complemento de la comunidad — no verificado por Crow" },
  "extensions.communityWarningDesc": { en: "This add-on comes from a community store. Review its source before installing.", es: "Este complemento proviene de una tienda de la comunidad. Revisa su código antes de instalar." },
  "extensions.installDesc": { en: "This will download and configure the add-on. You can update settings later.", es: "Esto descargará y configurará el complemento. Puedes actualizar la configuración después." },
  "extensions.configuration": { en: "Configuration", es: "Configuración" },
  "extensions.installing": { en: "Installing...", es: "Instalando..." },
  "extensions.copyingFiles": { en: "Copying files and pulling images...", es: "Copiando archivos y descargando imágenes..." },
  "extensions.installFailed": { en: "Install failed", es: "Error en la instalación" },
  "extensions.retry": { en: "Retry", es: "Reintentar" },
  "extensions.networkError": { en: "Network error", es: "Error de red" },
  "extensions.cannotBeUndone": { en: "This action cannot be undone", es: "Esta acción no se puede deshacer" },
  "extensions.deleteStoredData": { en: "Delete all stored data", es: "Eliminar todos los datos almacenados" },
  "extensions.removing": { en: "Removing...", es: "Eliminando..." },
  "extensions.stoppingAndRemoving": { en: "Stopping and removing...", es: "Deteniendo y eliminando..." },
  "extensions.removalFailed": { en: "Removal failed", es: "Error al eliminar" },
  "extensions.starting": { en: "Starting...", es: "Iniciando..." },
  "extensions.stopping": { en: "Stopping...", es: "Deteniendo..." },
  "extensions.done": { en: "Done!", es: "¡Listo!" },
  "extensions.working": { en: "Working...", es: "Trabajando..." },
  "extensions.failed": { en: "Failed:", es: "Error:" },
  "extensions.unknownError": { en: "Unknown error", es: "Error desconocido" },
  "extensions.gatewayRestarting": { en: "Gateway restarting to apply configuration...", es: "La puerta de enlace se está reiniciando para aplicar la configuración..." },
  "extensions.uninstallDockerDesc": { en: "This will stop all containers and remove the add-on. The gateway will restart to apply changes.", es: "Esto detendrá todos los contenedores y eliminará el complemento. La puerta de enlace se reiniciará para aplicar los cambios." },
  "extensions.uninstallDesc": { en: "This will remove the add-on and its configuration.", es: "Esto eliminará el complemento y su configuración." },
  "extensions.dataDeleteHint": { en: "Optionally delete all files stored by this service. Leave unchecked to keep data for a future reinstall.", es: "Opcionalmente elimina todos los archivos almacenados por este servicio. Deja sin marcar para conservar los datos para una futura reinstalación." },
  "extensions.restartingGatewayChanges": { en: "Restarting gateway...", es: "Reiniciando la puerta de enlace..." },
  "extensions.installedDate": { en: "installed", es: "instalado" },
  "extensions.needsRam": { en: "This add-on needs ~", es: "Este complemento necesita ~" },
  "extensions.ramFree": { en: "MB RAM. Your server has", es: "MB RAM. Tu servidor tiene" },
  "extensions.mbFree": { en: "MB free.", es: "MB libres." },
  "extensions.needsDisk": { en: "This add-on needs ~", es: "Este complemento necesita ~" },
  "extensions.diskFree": { en: "MB disk. Your server has", es: "MB disco. Tu servidor tiene" },
  "extensions.installMayCauseInstability": { en: "Installing may cause instability.", es: "La instalación puede causar inestabilidad." },
  "extensions.tags": { en: "Tags", es: "Etiquetas" },
  "extensions.requirements": { en: "Requirements", es: "Requisitos" },
  "extensions.ports": { en: "Ports", es: "Puertos" },
  "extensions.webInterface": { en: "Web Interface", es: "Interfaz web" },
  "extensions.notes": { en: "Notes", es: "Notas" },
  "extensions.gpuRequired": { en: "GPU Required", es: "GPU requerida" },
  "extensions.close": { en: "Close", es: "Cerrar" },
  "extensions.searchPlaceholder": { en: "Search add-ons...", es: "Buscar complementos..." },
  "extensions.categoryAll": { en: "All", es: "Todos" },
  "extensions.categoryAi": { en: "AI", es: "IA" },
  "extensions.categoryMedia": { en: "Media", es: "Multimedia" },
  "extensions.categoryProductivity": { en: "Productivity", es: "Productividad" },
  "extensions.categoryStorage": { en: "Storage", es: "Almacenamiento" },
  "extensions.categorySmartHome": { en: "Smart Home", es: "Casa inteligente" },
  "extensions.categoryNetworking": { en: "Networking", es: "Redes" },
  "extensions.categoryGaming": { en: "Gaming", es: "Juegos" },
  "extensions.categoryData": { en: "Data", es: "Datos" },
  "extensions.categorySocial": { en: "Social", es: "Social" },
  "extensions.categoryFinance": { en: "Finance", es: "Finanzas" },
  "extensions.categoryInfrastructure": { en: "Infrastructure", es: "Infraestructura" },
  "extensions.categoryAutomation": { en: "Automation", es: "Automatizaci\u00f3n" },
  "extensions.categoryEducation": { en: "Education", es: "Educaci\u00f3n" },
  "extensions.categoryFederatedSocial": { en: "Federated (Social)", es: "Federado (Social)" },
  "extensions.categoryFederatedMedia": { en: "Federated (Media)", es: "Federado (Medios)" },
  "extensions.categoryFederatedComms": { en: "Federated (Chat)", es: "Federado (Chat)" },
  "extensions.categoryCameras": { en: "Cameras", es: "Cámaras" },
  "extensions.categoryOther": { en: "Other", es: "Otros" },
  "extensions.incompatibleGpuArch": { en: "Incompatible GPU arch.", es: "Arquitectura GPU incompatible." },
  "extensions.insufficientVram": { en: "insufficient VRAM", es: "VRAM insuficiente" },
  "extensions.incompatibleHost": { en: "incompatible host", es: "host incompatible" },
  "extensions.webUiFallback": { en: "Web UI", es: "Interfaz web" },

  // ─── Skills Panel ───
  "skills.pageTitle": { en: "Skills", es: "Habilidades" },
  "skills.totalSkills": { en: "Total Skills", es: "Total de habilidades" },
  "skills.builtIn": { en: "Built-in", es: "Integradas" },
  "skills.custom": { en: "Custom", es: "Personalizadas" },
  "skills.wantMoreSkills": { en: "Want more skills?", es: "¿Quieres más habilidades?" },
  "skills.browseSkillBundles": { en: "Browse and install skill bundles from the add-on marketplace.", es: "Explora e instala paquetes de habilidades desde el mercado de complementos." },
  "skills.extensionsLink": { en: "Extensions", es: "Extensiones" },
  "skills.allSkills": { en: "All Skills", es: "Todas las habilidades" },
  "skills.createNewSkill": { en: "Create New Skill", es: "Crear nueva habilidad" },
  "skills.tableName": { en: "Name", es: "Nombre" },
  "skills.tableFile": { en: "File", es: "Archivo" },
  "skills.tableSource": { en: "Source", es: "Fuente" },
  "skills.tableActions": { en: "Actions", es: "Acciones" },
  "skills.view": { en: "View", es: "Ver" },
  "skills.edit": { en: "Edit", es: "Editar" },
  "skills.delete": { en: "Delete", es: "Eliminar" },
  "skills.deleteConfirm": { en: "Delete this skill?", es: "¿Eliminar esta habilidad?" },
  "skills.save": { en: "Save", es: "Guardar" },
  "skills.cancel": { en: "Cancel", es: "Cancelar" },
  "skills.back": { en: "Back", es: "Atrás" },
  "skills.overrideButton": { en: "Override with Custom Copy", es: "Sobrescribir con copia personalizada" },
  "skills.userSkillEditable": { en: "User Skill (editable)", es: "Habilidad de usuario (editable)" },
  "skills.builtInReadOnly": { en: "Built-in Skill (read-only)", es: "Habilidad integrada (solo lectura)" },
  "skills.overridden": { en: "overridden", es: "sobrescrita" },
  "skills.customBadge": { en: "custom", es: "personalizada" },
  "skills.builtInBadge": { en: "built-in", es: "integrada" },
  "skills.noSkillsFound": { en: "No skills found", es: "No se encontraron habilidades" },
  "skills.skillsDirectory": { en: "Skills should be in the skills/ directory.", es: "Las habilidades deben estar en el directorio skills/." },
  "skills.filenameLabel": { en: "Filename", es: "Nombre de archivo" },
  "skills.filenamePlaceholder": { en: "my-skill.md", es: "mi-habilidad.md" },
  "skills.contentLabel": { en: "Content", es: "Contenido" },
  "skills.createSkill": { en: "Create Skill", es: "Crear habilidad" },
  "skills.skillPrefix": { en: "Skill:", es: "Habilidad:" },
  "skills.overrideConfirm": { en: "This will copy the built-in skill to your user skills directory (~/.crow/skills/) where you can customize it. The user version will take precedence over the built-in one. Continue?", es: "Esto copiará la habilidad integrada a tu directorio de habilidades de usuario (~/.crow/skills/) donde puedes personalizarla. La versión de usuario tendrá prioridad sobre la integrada. ¿Continuar?" },
  "skills.deleteUserSkillConfirm": { en: "Delete this user skill? The built-in version (if one exists) will be used instead.", es: "¿Eliminar esta habilidad de usuario? Se usará la versión integrada (si existe) en su lugar." },

  // ─── Bot Builder Panel (W3-4 + W4-3 C5 i18n sweep) ───
  // JS-context keys (tJs) — pre-existing
  "botbuilder.confirmApproveSkill": { en: "Approve and promote \"{name}\" into ~/.crow/skills and attach it to this bot?", es: "¿Aprobar y promover \"{name}\" en ~/.crow/skills y asociarlo a este bot?" },
  "botbuilder.confirmRejectSkill": { en: "Discard the proposed skill \"{name}\"? This deletes the staged file.", es: "¿Descartar la habilidad propuesta \"{name}\"? Esto elimina el archivo en espera." },
  "botbuilder.confirmStopSession": { en: "Stop this session?", es: "¿Detener esta sesión?" },
  "botbuilder.stopSessionFailed": { en: "Couldn't stop session — try again", es: "No se pudo detener la sesión — intenta de nuevo" },
  // Tab labels (HTML-context) — TABS[i][0] ids are frozen; only display labels are translated
  "botbuilder.tabAi": { en: "AI / Models", es: "IA / Modelos" },
  "botbuilder.tabTools": { en: "Tools & Extensions", es: "Herramientas y extensiones" },
  "botbuilder.tabGateways": { en: "Gateways", es: "Puertas de enlace" },
  "botbuilder.tabTracker": { en: "Project / Tracker", es: "Proyecto / Rastreador" },
  "botbuilder.tabSkills": { en: "Skills & Prompt", es: "Habilidades y prompt" },
  "botbuilder.tabPermissions": { en: "Permissions / Safety", es: "Permisos / Seguridad" },
  "botbuilder.tabTriggers": { en: "Triggers", es: "Disparadores" },
  "botbuilder.tabSessions": { en: "Sessions", es: "Sesiones" },
  "botbuilder.tabReview": { en: "Review / Deploy", es: "Revisar / Desplegar" },
  // Button labels
  "botbuilder.btnSaveAi": { en: "Save AI", es: "Guardar IA" },
  "botbuilder.btnSaveTools": { en: "Save Tools", es: "Guardar herramientas" },
  "botbuilder.btnSaveGateways": { en: "Save Gateways", es: "Guardar puertas de enlace" },
  "botbuilder.btnSaveTrackerConfig": { en: "Save Tracker Config", es: "Guardar configuración del rastreador" },
  "botbuilder.btnSaveSkillsPrompt": { en: "Save Skills &amp; Prompt", es: "Guardar habilidades y prompt" },
  "botbuilder.btnSavePermissions": { en: "Save Permissions", es: "Guardar permisos" },
  "botbuilder.btnSaveTriggers": { en: "Save Triggers", es: "Guardar disparadores" },
  "botbuilder.btnRegenMcp": { en: "Regenerate &lt;session_dir&gt;/.mcp.json", es: "Regenerar &lt;session_dir&gt;/.mcp.json" },
  "botbuilder.btnDisableBot": { en: "Disable bot", es: "Desactivar bot" },
  "botbuilder.btnEnableBot": { en: "Enable bot", es: "Activar bot" },
  // Form/section labels
  "botbuilder.labelDefaultModel": { en: "Default model", es: "Modelo predeterminado" },
  "botbuilder.labelEscalationModel": { en: "Escalation model (optional, cloud)", es: "Modelo de escalada (opcional, nube)" },
  "botbuilder.labelFastVoiceModel": { en: "Fast voice model (glasses)", es: "Modelo de voz rápido (gafas)" },
  "botbuilder.labelVoiceProfiles": { en: "Voice profiles (reference, read-only)", es: "Perfiles de voz (referencia, solo lectura)" },
  "botbuilder.labelPiBuiltin": { en: "pi builtin", es: "pi incorporado" },
  "botbuilder.labelCrowMcpTools": { en: "Crow MCP tools", es: "Herramientas MCP de Crow" },
  "botbuilder.labelPiExtensions": { en: "pi extensions", es: "extensiones pi" },
  "botbuilder.labelGatewayType": { en: "Gateway type", es: "Tipo de puerta de enlace" },
  "botbuilder.labelLinkedProject": { en: "Linked project", es: "Proyecto vinculado" },
  "botbuilder.labelTrackerType": { en: "Tracker type", es: "Tipo de rastreador" },
  "botbuilder.labelTrackerSlug": { en: "Tracker slug", es: "Slug del rastreador" },
  "botbuilder.labelContextFields": { en: "Context fields (comma-separated keys for prompt)", es: "Campos de contexto (claves separadas por comas para el prompt)" },
  "botbuilder.labelQueueFilter": { en: "Queue filter (key=value for dispatch queue)", es: "Filtro de cola (clave=valor para la cola de despacho)" },
  "botbuilder.labelSystemPrompt": { en: "System prompt", es: "Prompt del sistema" },
  "botbuilder.labelProposedSkills": { en: "Proposed skills (pending review)", es: "Habilidades propuestas (pendientes de revisión)" },
  "botbuilder.labelSelfLearningHistory": { en: "Self-learning history (last 25)", es: "Historial de autoaprendizaje (últimas 25)" },
  "botbuilder.labelBash": { en: "bash", es: "bash" },
  "botbuilder.labelBashAllowPrefixes": { en: "bash_allow prefixes (one per line; allowlist mode)", es: "Prefijos bash_allow (uno por línea; modo lista permitida)" },
  "botbuilder.labelWritePaths": { en: "write_paths (one per line)", es: "write_paths (uno por línea)" },
  "botbuilder.labelExternalSend": { en: "external_send", es: "external_send" },
  "botbuilder.labelConfirmTools": { en: "confirm tools (one per line; blocked unattended)", es: "Herramientas de confirmación (una por línea; bloqueadas sin supervisión)" },
  "botbuilder.labelSelfLearning": { en: "Self-learning — post-turn skill review", es: "Autoaprendizaje — revisión de habilidades post-turno" },
  "botbuilder.labelGatewayTriggered": { en: "Gateway-triggered (Gmail inbound via the bridge tick)", es: "Disparado por puerta de enlace (Gmail entrante mediante el tick del puente)" },
  "botbuilder.labelCron": { en: "Cron (bridge's own timer; optional)", es: "Cron (temporizador propio del puente; opcional)" },
  // Sessions table headers
  "botbuilder.thId": { en: "ID", es: "ID" },
  "botbuilder.thStatus": { en: "Status", es: "Estado" },
  "botbuilder.thModel": { en: "Model", es: "Modelo" },
  "botbuilder.thThread": { en: "Thread", es: "Hilo" },
  "botbuilder.thUpdated": { en: "Updated", es: "Actualizado" },
  "botbuilder.thActions": { en: "Actions", es: "Acciones" },
  // Notices
  "botbuilder.noticeUnknownBot": { en: "Unknown bot.", es: "Bot desconocido." },
  "botbuilder.noticeAllBots": { en: "all bots", es: "todos los bots" },
  "botbuilder.noticeNoSessions": { en: "No sessions for this bot.", es: "No hay sesiones para este bot." },
  "botbuilder.noticeNoProposedSkills": { en: "No proposed skills awaiting review.", es: "No hay habilidades propuestas pendientes de revisión." },
  "botbuilder.noticeNoSelfLearning": { en: "No self-learning activity yet (enable it on the <strong>Permissions</strong> tab).", es: "Aún no hay actividad de autoaprendizaje (actívalo en la pestaña <strong>Permisos</strong>)." },
  // Gateway sub-labels
  "botbuilder.gwLabelBotTokenDiscord": { en: "Bot token", es: "Token del bot" },
  "botbuilder.gwLabelChannelIds": { en: "Channel IDs (one per line, optional — blank = any channel)", es: "IDs de canal (uno por línea, opcional — vacío = cualquier canal)" },
  "botbuilder.gwLabelAllowlistDiscord": { en: "Allowlist — Discord user IDs (one per line)", es: "Lista permitida — IDs de usuario de Discord (uno por línea)" },
  "botbuilder.gwLabelBotTokenTelegram": { en: "Bot token (from @BotFather)", es: "Token del bot (de @BotFather)" },
  "botbuilder.gwLabelAllowlistTelegram": { en: "Allowlist — Telegram user IDs (one per line, blank = anyone)", es: "Lista permitida — IDs de usuario de Telegram (uno por línea, vacío = cualquiera)" },
  "botbuilder.gwLabelChatIds": { en: "Restrict to chat IDs (one per line, optional)", es: "Restringir a IDs de chat (uno por línea, opcional)" },
  "botbuilder.gwLabelBotTokenSlack": { en: "Bot token (xoxb-…)", es: "Token del bot (xoxb-…)" },
  "botbuilder.gwLabelAppToken": { en: "App-level token (xapp-…, connections:write)", es: "Token de nivel de app (xapp-…, connections:write)" },
  "botbuilder.gwLabelAllowlistSlack": { en: "Allowlist — Slack user IDs (one per line, blank = anyone)", es: "Lista permitida — IDs de usuario de Slack (uno por línea, vacío = cualquiera)" },
  "botbuilder.gwLabelChannelIdsSlack": { en: "Restrict to channel IDs (one per line, optional)", es: "Restringir a IDs de canal (uno por línea, opcional)" },
  "botbuilder.gwLabelPairedDevice": { en: "Paired device", es: "Dispositivo vinculado" },
  "botbuilder.gwLabelFastVoiceModel": { en: "Fast voice model (overrides the AI tab for this binding)", es: "Modelo de voz rápido (reemplaza la pestaña IA para este enlace)" },
  "botbuilder.gwLabelVoicePlumbing": { en: "Voice plumbing (bound to the device)", es: "Plomería de voz (enlazado al dispositivo)" },
  "botbuilder.gwLabelPairedKiosk": { en: "Paired kiosk device", es: "Dispositivo kiosk vinculado" },
  "botbuilder.gwLabelAvatarModel": { en: "Avatar (Live2D model name, blank = bot/default)", es: "Avatar (nombre del modelo Live2D, vacío = bot/predeterminado)" },
  "botbuilder.gwLabelHearingStyle": { en: "Hearing style", es: "Estilo de escucha" },
  "botbuilder.gwLabelVoiceIdleTimeout": { en: "Voice idle timeout (seconds before pet/idle)", es: "Tiempo de espera de voz inactiva (segundos antes de pet/idle)" },
  "botbuilder.gwHintDiscord": { en: "Discord runs via the long-lived <code>pibot-discord.service</code> (discord_gateway.mjs holds a WebSocket per bot). The <code>MessageContent</code> privileged intent must be enabled in the Discord Developer Portal. After changing token/guild/channel config, restart the service: <code>sudo systemctl restart pibot-discord</code>.", es: "Discord se ejecuta a través del servicio de larga duración <code>pibot-discord.service</code> (discord_gateway.mjs mantiene un WebSocket por bot). El intent privilegiado <code>MessageContent</code> debe estar habilitado en el Portal de Desarrolladores de Discord. Tras cambiar token/guild/canal, reinicia el servicio: <code>sudo systemctl restart pibot-discord</code>." },
  "botbuilder.gwHintTelegram": { en: "Telegram runs via the long-lived <code>pibot-gateways.service</code> (gateways/telegram.mjs, long-poll — dials out, no inbound port). After changing config, restart: <code>sudo systemctl restart pibot-gateways</code>.", es: "Telegram se ejecuta a través del servicio de larga duración <code>pibot-gateways.service</code> (gateways/telegram.mjs, long-poll — saliente, sin puerto entrante). Tras cambiar la configuración, reinicia: <code>sudo systemctl restart pibot-gateways</code>." },
  "botbuilder.gwHintSlack": { en: "Slack runs via the long-lived <code>pibot-gateways.service</code> (gateways/slack.mjs, Socket Mode — dials out, no inbound port). Needs Socket Mode enabled + an app-level token with <code>connections:write</code>. After changing config, restart: <code>sudo systemctl restart pibot-gateways</code>.", es: "Slack se ejecuta a través del servicio de larga duración <code>pibot-gateways.service</code> (gateways/slack.mjs, Socket Mode — saliente, sin puerto entrante). Necesita Socket Mode habilitado + un token de nivel de app con <code>connections:write</code>. Tras cambiar la configuración, reinicia: <code>sudo systemctl restart pibot-gateways</code>." },
  "botbuilder.gwHintGlasses": { en: "Saving binds the device (<code>bound_bot_id</code>) so the meta-glasses fast voice turn runs THIS bot's persona, skills, scoped tools, and permissions. One bot &harr; one device; re-binding unbinds the prior device. No gateway restart needed — the voice turn reads the binding live (30s cache).", es: "Guardar enlaza el dispositivo (<code>bound_bot_id</code>) para que el turno de voz rápida de las gafas ejecute la persona, habilidades, herramientas y permisos de ESTE bot. Un bot &harr; un dispositivo; volver a enlazar desvincula el dispositivo anterior. No se necesita reiniciar el gateway — el turno de voz lee el enlace en vivo (caché de 30s)." },
  "botbuilder.gwHintCompanion": { en: "Saving binds the device (<code>bound_bot_id</code>, <code>device_kind:companion</code>) so this kiosk shows THIS bot's persona/avatar and the feature toggles above. The fast&rarr;escalate model pair is global to the companion container (the model proxy). Changing avatar/persona takes effect on the next kiosk session; toggles apply live. See <code>docs/guide/kiosk-mode.md</code>.", es: "Guardar enlaza el dispositivo (<code>bound_bot_id</code>, <code>device_kind:companion</code>) para que este kiosk muestre la persona/avatar y los toggles de ESTE bot. El par de modelos fast&rarr;escalate es global al contenedor companion (el proxy de modelos). Los cambios de avatar/persona tienen efecto en la próxima sesión del kiosk; los toggles se aplican en vivo. Ver <code>docs/guide/kiosk-mode.md</code>." },
  "botbuilder.gwHintNone": { en: "No gateway — this bot is driven only by direct injection / cards, not inbound messages.", es: "Sin gateway — este bot solo es impulsado por inyección directa / tarjetas, no por mensajes entrantes." },
  "botbuilder.gwHintGmail": { en: "Gmail polls <code>to:&lt;+alias&gt;@maestro.press</code> via bridge_tick.mjs (pibot-bridge.timer, ~1 min).", es: "Gmail sondea <code>to:&lt;+alias&gt;@maestro.press</code> a través de bridge_tick.mjs (pibot-bridge.timer, ~1 min)." },
  // Tracker definition editor labels
  "botbuilder.tdefLabelDisplayName": { en: "Display name", es: "Nombre para mostrar" },
  "botbuilder.tdefLabelStatusColumns": { en: "Status columns (comma-separated, in display order)", es: "Columnas de estado (separadas por comas, en orden de visualización)" },
  "botbuilder.tdefLabelDataFields": { en: "Data fields (columns_json)", es: "Campos de datos (columns_json)" },
  // Skills tab labels
  "botbuilder.skillsGroupGeneral": { en: "General", es: "General" },
  "botbuilder.skillsHintProposals": { en: "Drafted by this bot into <code>&lt;session_dir&gt;/proposed-skills/</code>. Review and edit (sanitize any &#9888; flagged phrasing), then Approve to copy into <code>~/.crow/skills</code> and attach, or Reject to discard. Inert until approved.", es: "Borradores de este bot en <code>&lt;session_dir&gt;/proposed-skills/</code>. Revisa y edita (sanea cualquier frase marcada con &#9888;), luego Aprueba para copiar en <code>~/.crow/skills</code> y adjuntar, o Rechaza para descartar. Inerte hasta aprobado." },
  // Permissions tab hints
  "botbuilder.hintMultiAgent": { en: "Multi-agent is gated by pi-lab/permission-gating.ts (Phase 3.1): <code>subagent</code> is allowed only when this is on AND the bot's resolved model is MULTI_AGENT_CAPABLE; recursion is depth-capped. Off by default.", es: "El multi-agente está controlado por pi-lab/permission-gating.ts (Fase 3.1): <code>subagent</code> solo se permite cuando esto está activado Y el modelo resuelto del bot es MULTI_AGENT_CAPABLE; la recursión tiene un límite de profundidad. Desactivado por defecto." },
  "botbuilder.hintSelfAuthoring": { en: "When on, the bot may DRAFT a skill file into its confined staging dir (<code>&lt;session_dir&gt;/proposed-skills/</code>). Proposals are <strong>inert</strong> — they never load and never reach <code>~/.crow/skills</code> until you approve them on the <strong>Skills &amp; Prompt</strong> tab. Skills are pure prompt text; approving one can never grant a tool or change this policy. Off by default.", es: "Cuando está activado, el bot puede REDACTAR un archivo de habilidad en su directorio de preparación confinado (<code>&lt;session_dir&gt;/proposed-skills/</code>). Las propuestas son <strong>inertes</strong> — nunca se cargan ni llegan a <code>~/.crow/skills</code> hasta que las apruebes en la pestaña <strong>Habilidades y prompt</strong>. Las habilidades son texto de prompt puro; aprobar una nunca puede otorgar una herramienta ni cambiar esta política. Desactivado por defecto." },
  "botbuilder.hintSelfLearningDetail": { en: "After each turn, an idle-only, cheap-model review decides whether to write or improve a skill (Hermes-style). <strong>propose</strong> drafts into the staging dir for your approval (same flow as self-authoring, but auto-triggered). <strong>auto</strong> writes/patches directly, behind guardrails: guardrail-phrase drafts are blocked to a proposal; high-blast-radius bots (open <code>external_send</code>, non-<code>deny</code> bash, or multi-agent) silently degrade to propose; a bot may only patch skills it itself auto-authored, never operator- or repo-authored ones. Runs ONLY when no pi turn is live, so it never starves real turns. Off by default. Auto-written skills appear under <strong>Skills &amp; Prompt</strong>.", es: "Tras cada turno, una revisión inactiva y de modelo económico decide si escribir o mejorar una habilidad (estilo Hermes). <strong>propose</strong> redacta en el directorio de preparación para tu aprobación (mismo flujo que self-authoring, pero activado automáticamente). <strong>auto</strong> escribe/parchea directamente, con salvaguardas: los borradores con frases de salvaguarda se bloquean como propuesta; los bots de alto radio de explosión (<code>external_send</code> abierto, bash no-<code>deny</code>, o multi-agente) degradan silenciosamente a propose; un bot solo puede parchear habilidades que él mismo autoeditó, nunca las del operador o del repositorio. Se ejecuta SOLO cuando no hay turno pi activo, por lo que nunca muere de hambre los turnos reales. Desactivado por defecto. Las habilidades auto-escritas aparecen bajo <strong>Habilidades y prompt</strong>." },
  "botbuilder.hintPermEnforced": { en: "Enforced by pi-lab/permission-gating.ts via PI_BOT_PERMISSION_POLICY (Phase 2.2). Default-deny for safety.", es: "Aplicado por pi-lab/permission-gating.ts vía PI_BOT_PERMISSION_POLICY (Fase 2.2). Denegación por defecto para seguridad." },
  // Sessions tab label
  "botbuilder.sessionSendLabelPrefix": { en: "Send message to session (thread: ", es: "Enviar mensaje a sesión (hilo: " },
  // Review tab
  "botbuilder.reviewEffectiveDecision": { en: "Effective runtime decision", es: "Decisión de ejecución efectiva" },
  "botbuilder.reviewHintSaving": { en: "Saving a bot writes pi_bot_defs only. The bridge spawn-per-turn picks up changes on the next inbound; no gateway restart needed.", es: "Guardar un bot solo escribe pi_bot_defs. El bridge por turno recoge los cambios en el siguiente mensaje entrante; no se necesita reiniciar el gateway." },

  // ─── Bot Board Panel (W3-4 + W4-3 i18n sweep) ───
  // Status label keys — display counterparts to the frozen CARD_STATUSES data values
  "botboard.statusPending": { en: "Pending", es: "Pendiente" },
  "botboard.statusInProgress": { en: "In Progress", es: "En progreso" },
  "botboard.statusDone": { en: "Done", es: "Hecho" },
  "botboard.statusCancelled": { en: "Cancelled", es: "Cancelada" },
  // HTML-context strings (html.js)
  "botboard.titlePriorityPrefix": { en: "priority", es: "prioridad" },
  "botboard.cardWorking": { en: "a bot is working this card — read-only", es: "un bot está trabajando esta tarjeta — solo lectura" },
  "botboard.cardWorkingBadge": { en: "🔒 bot working", es: "🔒 bot trabajando" },
  "botboard.moveTo": { en: "move to ", es: "mover a " },
  "botboard.itemProcessing": { en: "a bot is processing this item — read-only", es: "un bot está procesando este ítem — solo lectura" },
  "botboard.itemProcessingBadge": { en: "🔒 processing", es: "🔒 procesando" },
  "botboard.collapseColumn": { en: "collapse column", es: "contraer columna" },
  "botboard.collapseColumnAria": { en: "Collapse {col} column", es: "Contraer columna {col}" },
  "botboard.trackerNotFound": { en: "Tracker definition <code>{slug}</code> not found.", es: "Definición de rastreador <code>{slug}</code> no encontrada." },
  // JS-context strings (client.js)
  "botboard.jsCardPrefix": { en: "Card #", es: "Tarjeta #" },
  // jsCardLocked / jsItemLocked: emoji prefix (🔒) and em-dash (—) are hardcoded
  // in the template as \uXXXX escapes to preserve EN byte-identity; these keys
  // cover only the text after the emoji prefix (split at the em-dash boundary).
  // DO NOT merge Pre/Post into one key — combining would embed the emoji/dash
  // as UTF-8 bytes instead of \uXXXX escapes and change the rendered EN bytes.
  "botboard.jsCardLockedPre": { en: "A bot is working this card ", es: "Un bot está trabajando esta tarjeta " },
  "botboard.jsCardLockedPost": { en: "fields & plan are read-only.", es: "los campos y el plan son de solo lectura." },
  "botboard.jsItemPrefix": { en: "Item #", es: "Ítem #" },
  "botboard.jsItemLockedPre": { en: "A bot is processing this item ", es: "Un bot está procesando este ítem " },
  "botboard.jsItemLockedPost": { en: "read-only.", es: "solo lectura." },
  "botboard.jsItemLoadFailed": { en: "Failed to load item.", es: "No se pudo cargar el ítem." },
  "botboard.jsSectionDataFields": { en: "Data Fields", es: "Campos de datos" },
  "botboard.jsSectionHistory": { en: "History", es: "Historial" },
  "botboard.jsSectionRelated": { en: "Related", es: "Relacionado" },
  "botboard.jsUpdatedPrefix": { en: "Updated: ", es: "Actualizado: " },
  "botboard.jsCreatedPrefix": { en: "Created: ", es: "Creado: " },
  "botboard.jsLeasePrefix": { en: "Lease: ", es: "Lease: " },
  "botboard.jsSaved": { en: "Saved.", es: "Guardado." },
  "botboard.jsProjectUpdated": { en: "Project updated.", es: "Proyecto actualizado." },
  "botboard.jsCancelled": { en: "Cancelled.", es: "Cancelada." },
  "botboard.jsForceUnlocked": { en: "Force-unlocked.", es: "Desbloqueo forzado." },
  "botboard.jsToggleEdit": { en: "Edit", es: "Editar" },
  "botboard.jsTogglePreview": { en: "Preview", es: "Vista previa" },
  "botboard.jsPlanSaved": { en: "Plan saved.", es: "Plan guardado." },
  "botboard.jsLeaseCleared": { en: "Lease cleared.", es: "Lease limpiado." },
  "botboard.jsNameRequired": { en: "Name required.", es: "El nombre es obligatorio." },
  "botboard.jsTitleRequired": { en: "Title required.", es: "El título es obligatorio." },
  "botboard.jsNoUnlinkedCards": { en: "No unlinked cards.", es: "No hay tarjetas sin enlazar." },
  "botboard.jsSelectAtLeastOne": { en: "Select at least one card.", es: "Selecciona al menos una tarjeta." },
  "botboard.jsMaxPerAssign": { en: "Max 200 per assign.", es: "Máx. 200 por asignación." },
  "botboard.confirmCancelCard": { en: "Cancel card #{id}?", es: "¿Cancelar tarjeta #{id}?" },
  "botboard.confirmForceUnlock": { en: "Force-unlock card #{id}? Only if the bot/pi is confirmed dead.", es: "¿Forzar desbloqueo de tarjeta #{id}? Solo si el bot/pi está confirmado como inactivo." },
  "botboard.confirmClearLease": { en: "Force-clear lease on item #{id}?", es: "¿Forzar limpieza del lease en ítem #{id}?" },
  "botboard.trackerItemLocked": { en: "🔒 Item #{id} is being processed by a bot.", es: "🔒 El ítem #{id} está siendo procesado por un bot." },
  "botboard.cardLocked": { en: "🔒 Card #{id} is being worked by a bot.", es: "🔒 La tarjeta #{id} está siendo trabajada por un bot." },
  "botboard.moveFailed": { en: "Move failed — try again", es: "Error al mover — intenta de nuevo" },
  "botboard.moveItemFailed": { en: "Couldn't move item — try again", es: "No se pudo mover el ítem — intenta de nuevo" },
  "botboard.loadFailed": { en: "Couldn't load — try again", es: "No se pudo cargar — intenta de nuevo" },
  // Error/notice messages
  "botboard.errLocked": { en: "⚠️ That item is being worked by a bot — read-only.", es: "⚠️ Ese ítem está siendo trabajado por un bot — solo lectura." },
  "botboard.errBadMove": { en: "⚠️ Invalid status move.", es: "⚠️ Movimiento de estado inválido." },
  "botboard.errMoveFailed": { en: "⚠️ Move failed.", es: "⚠️ El movimiento falló." },
  "botboard.runtimeNotActive": { en: "Bot runtime is not active on this instance — board reflects definitions only.", es: "El tiempo de ejecución del bot no está activo en esta instancia — el tablero solo refleja definiciones." },
  "botboard.peerBotUpdated": { en: "✅ Peer bot updated.", es: "✅ Bot par actualizado." },
  "botboard.peerBotUpdateFailed": { en: "⚠️ Peer bot update failed: ", es: "⚠️ Error al actualizar bot par: " },
  "botboard.peerBotsSection": { en: "Bots on other instances", es: "Bots en otras instancias" },
  "botboard.peerBotsHelp": { en: "Manageable bots can be enabled/disabled from here. Others are read-only — open that instance's dashboard to edit or run them.", es: "Los bots gestionables se pueden activar/desactivar desde aquí. Los demás son de solo lectura — abre el panel de esa instancia para editarlos o ejecutarlos." },
  "botboard.noBots": { en: "No enabled bots found. Create a bot in Bot Builder to start a board.", es: "No se encontraron bots activos. Crea un bot en Bot Builder para empezar un tablero." },
  "botboard.noTracker": { en: "This bot has no tracker.", es: "Este bot no tiene rastreador." },
  "botboard.noBotsOption": { en: "-- no bots --", es: "-- sin bots --" },
  "botboard.labelBotSwitcher": { en: "Bot", es: "Bot" },
  "botboard.editBotLink": { en: "Edit bot", es: "Editar bot" },
  "botboard.botNotFound": { en: "not found or disabled.", es: "no encontrado o desactivado." },
  "botboard.colBot": { en: "Bot", es: "Bot" },
  "botboard.colInstance": { en: "Instance", es: "Instancia" },
  "botboard.colModel": { en: "Model", es: "Modelo" },
  "botboard.colStatus": { en: "Status", es: "Estado" },
  "botboard.botEnabled": { en: "enabled", es: "activo" },
  "botboard.botDisabled": { en: "disabled", es: "inactivo" },
  "botboard.btnDisable": { en: "Disable", es: "Desactivar" },
  "botboard.btnEnable": { en: "Enable", es: "Activar" },
  "botboard.btnEdit": { en: "Edit", es: "Editar" },
  "botboard.peerReadOnly": { en: "read-only — open on owner", es: "solo lectura — abre en el propietario" },
  "botboard.notInitTitle": { en: "Bot Board", es: "Tablero de bots" },
  // Drawer labels
  "botboard.drawerCardTitle": { en: "Card", es: "Tarjeta" },
  "botboard.labelTitle": { en: "Title", es: "Título" },
  "botboard.labelStatus": { en: "Status", es: "Estado" },
  "botboard.labelPriority": { en: "Priority", es: "Prioridad" },
  "botboard.labelDueDate": { en: "Due date", es: "Fecha límite" },
  "botboard.labelOwner": { en: "Owner", es: "Responsable" },
  "botboard.labelTags": { en: "Tags (comma-separated)", es: "Etiquetas (separadas por coma)" },
  "botboard.labelDescription": { en: "Description", es: "Descripción" },
  "botboard.labelProject": { en: "Project", es: "Proyecto" },
  "botboard.btnSaveCard": { en: "Save card", es: "Guardar tarjeta" },
  "botboard.btnCancelCard": { en: "Cancel card", es: "Cancelar tarjeta" },
  "botboard.btnForceUnlock": { en: "Force-unlock", es: "Forzar desbloqueo" },
  "botboard.planFileHeading": { en: "Plan file", es: "Archivo de plan" },
  "botboard.btnSavePlan": { en: "Save plan", es: "Guardar plan" },
  "botboard.btnPreview": { en: "Preview", es: "Vista previa" },
  "botboard.drawerNewProject": { en: "New project", es: "Nuevo proyecto" },
  "botboard.labelName": { en: "Name", es: "Nombre" },
  "botboard.btnCreateProject": { en: "Create project", es: "Crear proyecto" },
  "botboard.drawerNewCard": { en: "New card", es: "Nueva tarjeta" },
  "botboard.newCardHelp": { en: "Created in the current project, status <b>pending</b>.", es: "Creada en el proyecto actual, estado <b>pendiente</b>." },
  "botboard.btnCreateCard": { en: "Create card", es: "Crear tarjeta" },
  "botboard.drawerBulkTitle": { en: "Add unlinked cards", es: "Agregar tarjetas sin enlazar" },
  "botboard.bulkHelp": { en: "Cards with no project (max 200 per assign).", es: "Tarjetas sin proyecto (máx. 200 por asignación)." },
  "botboard.btnAssign": { en: "Assign selected", es: "Asignar seleccionadas" },
  "botboard.drawerTrackerItem": { en: "Item", es: "Ítem" },
  "botboard.labelLabel": { en: "Label", es: "Etiqueta" },
  "botboard.labelActionNeeded": { en: "Action needed", es: "Acción requerida" },
  "botboard.btnSaveItem": { en: "Save item", es: "Guardar ítem" },
  "botboard.btnForceClearLease": { en: "Force-clear lease", es: "Forzar limpieza de lease" },
  "botboard.drawerNewTrackerItem": { en: "New tracker item", es: "Nuevo ítem de rastreador" },
  "botboard.labelLabelTitle": { en: "Label (title)", es: "Etiqueta (título)" },
  "botboard.btnCreateItem": { en: "Create item", es: "Crear ítem" },
  // Kanban board messages
  "botboard.noProjectLinked": { en: "This bot has no project linked. Assign a project_id in Bot Builder.", es: "Este bot no tiene proyecto vinculado. Asigna un project_id en Bot Builder." },
  "botboard.cardNotFound": { en: "Card not found", es: "Tarjeta no encontrada" },
  "botboard.backToBoard": { en: "← back to board", es: "← volver al tablero" },
  "botboard.planNoBot": { en: "No bot is linked to this project, so there is no plan file path.", es: "No hay bot vinculado a este proyecto, por lo que no hay ruta de archivo de plan." },
  "botboard.planLocked": { en: "🔒 A bot is working this card — the plan file is read-only.", es: "🔒 Un bot está trabajando esta tarjeta — el archivo de plan es de solo lectura." },
  "botboard.planJsHint": { en: "Open this board with JavaScript enabled to edit the plan file in the card drawer.", es: "Abre este tablero con JavaScript activado para editar el archivo de plan en el cajón de tarjeta." },
  "botboard.moveLabel": { en: "Move: ", es: "Mover: " },
  "botboard.planFilePlaceholder": { en: "(no plan yet)", es: "(sin plan aún)" },
  "botboard.fieldPriority": { en: "Priority", es: "Prioridad" },
  "botboard.fieldDue": { en: "Due", es: "Fecha límite" },
  "botboard.fieldOwner": { en: "Owner", es: "Responsable" },
  "botboard.fieldTags": { en: "Tags", es: "Etiquetas" },
  "botboard.fieldParent": { en: "Parent", es: "Padre" },
  "botboard.fieldUpdated": { en: "Updated", es: "Actualizado" },
  // Tracker board messages
  "botboard.noTrackerSlug": { en: "Custom tracker type but no tracker_slug configured.", es: "Tipo de rastreador personalizado pero sin tracker_slug configurado." },
  "botboard.filterActionNeeded": { en: "action needed", es: "acción requerida" },
  "botboard.viewColumns": { en: "Columns", es: "Columnas" },
  "botboard.viewList": { en: "List", es: "Lista" },

  // ─── Projects Panel (W3-4) ───
  "projects.confirmRevoke": { en: "Revoke {who}?", es: "¿Revocar a {who}?" },

  // ─── Orchestrator Panel (W3-4) ───
  "orchestrator.confirmResetRefcounts": { en: "Reset all lifecycle refcounts? This reconciles against live provider health.", es: "¿Restablecer todos los contadores de referencia? Esto concilia con el estado de los proveedores activos." },

  // ─── Extensions Panel (W3-4) ───
  "extensions.serviceUnavailable": { en: "Extensions service unavailable", es: "Servicio de extensiones no disponible" },
  "extensions.serviceUnavailableDesc": { en: "Could not load the add-on registry. Check your connection and try again.", es: "No se pudo cargar el registro de complementos. Verifica tu conexión e intenta de nuevo." },

  // ─── Settings Panel ───
  "settings.pageTitle": { en: "Settings", es: "Ajustes" },
  "settings.searchPlaceholder": { en: "Search settings", es: "Buscar ajustes" },
  "settings.searchNoResults": { en: "No settings match your search.", es: "Ningún ajuste coincide con tu búsqueda." },
  "settings.passwordUpdated": { en: "Password updated.", es: "Contraseña actualizada." },
  "settings.passwordTooShort": { en: "Password must be at least 12 characters.", es: "La contraseña debe tener al menos 12 caracteres." },
  "settings.passwordMismatch": { en: "Passwords don't match.", es: "Las contraseñas no coinciden." },
  "settings.currentPassword": { en: "Current Password", es: "Contraseña actual" },
  "settings.currentPasswordPlaceholder": { en: "Enter current password", es: "Ingresa la contraseña actual" },
  "settings.currentPasswordWrong": { en: "Current password is incorrect.", es: "La contraseña actual es incorrecta." },
  "settings.memories": { en: "Memories", es: "Memorias" },
  "settings.sourcesLabel": { en: "Sources", es: "Fuentes" },
  "settings.contactsLabel": { en: "Contacts", es: "Contactos" },
  "settings.postsLabel": { en: "Posts", es: "Publicaciones" },
  "settings.productivity": { en: "Productivity", es: "Productividad" },
  "settings.communication": { en: "Communication", es: "Comunicación" },
  "settings.development": { en: "Development", es: "Desarrollo" },
  "settings.connected": { en: "Connected", es: "Conectado" },
  "settings.tools": { en: "tools", es: "herramientas" },
  "settings.notSet": { en: "Not set", es: "No configurado" },
  "settings.noConfigNeeded": { en: "No configuration needed — works out of the box.", es: "No se necesita configuración — funciona de inmediato." },
  "settings.requires": { en: "Requires", es: "Requiere" },
  "settings.getApiKey": { en: "Get API Key", es: "Obtener clave API" },
  "settings.docs": { en: "Docs", es: "Documentación" },
  "settings.save": { en: "Save", es: "Guardar" },
  "settings.removeIntegration": { en: "Remove", es: "Eliminar" },
  "settings.saving": { en: "Saving...", es: "Guardando..." },
  "settings.savedRestarting": { en: "Saved. Gateway restarting...", es: "Guardado. Reiniciando la puerta de enlace..." },
  "settings.savedRestartNeeded": { en: "Saved. Restart gateway to activate.", es: "Guardado. Reinicia la puerta de enlace para activar." },
  "settings.saveFailed": { en: "Save failed.", es: "Error al guardar." },
  "settings.removing": { en: "Removing...", es: "Eliminando..." },
  "settings.removeConfirm": { en: "Remove this integration? Its API keys will be commented out in .env.", es: "¿Eliminar esta integración? Sus claves API serán comentadas en .env." },
  "settings.integrationsSection": { en: "Integrations", es: "Integraciones" },
  "settings.identitySection": { en: "Identity", es: "Identidad" },
  "settings.crowId": { en: "Crow ID:", es: "ID de Crow:" },
  "settings.ed25519": { en: "Ed25519:", es: "Ed25519:" },
  "settings.identityNotAvailable": { en: "Identity not available.", es: "Identidad no disponible." },
  "settings.blogSettingsSection": { en: "Blog Settings", es: "Ajustes del blog" },
  "settings.blogTitle": { en: "Blog Title", es: "Título del blog" },
  "settings.tagline": { en: "Tagline", es: "Eslogan" },
  "settings.taglinePlaceholder": { en: "A short description", es: "Una descripción corta" },
  "settings.defaultAuthor": { en: "Default Author", es: "Autor predeterminado" },
  "settings.themeLabel": { en: "Theme", es: "Tema" },
  "settings.darkDefault": { en: "Dark (default)", es: "Oscuro (predeterminado)" },
  "settings.light": { en: "Light", es: "Claro" },
  "settings.serif": { en: "Serif", es: "Serif" },
  "settings.blogDiscovery": { en: "Blog Discovery", es: "Descubrimiento del blog" },
  "settings.notListed": { en: "Not listed", es: "No listado" },
  "settings.listedInRegistry": { en: "Listed in Crow Blog Registry", es: "Listado en el Registro de Blogs de Crow" },
  "settings.saveBlogSettings": { en: "Save Blog Settings", es: "Guardar ajustes del blog" },
  "settings.contactDiscoverySection": { en: "Contact Discovery", es: "Descubrimiento de contactos" },
  "settings.contactDiscoveryLabel": { en: "Contact Discovery", es: "Descubrimiento de contactos" },
  "settings.disabled": { en: "Disabled", es: "Desactivado" },
  "settings.enabled": { en: "Enabled — findable by other Crow users", es: "Activado — visible para otros usuarios de Crow" },
  "settings.displayName": { en: "Display Name", es: "Nombre para mostrar" },
  "settings.displayNamePlaceholder": { en: "Name shown to other Crow users", es: "Nombre visible para otros usuarios de Crow" },
  "settings.saveDiscoverySettings": { en: "Save Discovery Settings", es: "Guardar ajustes de descubrimiento" },
  "settings.changePasswordSection": { en: "Change Password", es: "Cambiar contraseña" },
  "settings.newPassword": { en: "New Password", es: "Nueva contraseña" },
  "settings.newPasswordPlaceholder": { en: "At least 12 characters", es: "Al menos 12 caracteres" },
  "settings.confirmPassword": { en: "Confirm Password", es: "Confirmar contraseña" },
  "settings.changePasswordButton": { en: "Change Password", es: "Cambiar contraseña" },
  "settings.languageSection": { en: "Language", es: "Idioma" },
  "settings.languageLabel": { en: "Language", es: "Idioma" },
  "settings.saveLanguage": { en: "Save Language", es: "Guardar idioma" },
  "settings.connectionUrls": { en: "Connection URLs", es: "URLs de conexión" },
  "settings.local": { en: "Local", es: "Local" },
  "settings.tailnetLan": { en: "Tailnet / LAN", es: "Tailnet / LAN" },
  "settings.publicBlogOnly": { en: "Public (blog only)", es: "Público (solo blog)" },
  "settings.context": { en: "Context", es: "Contexto" },
  "settings.url": { en: "URL", es: "URL" },
  "settings.statusColumn": { en: "Status", es: "Estado" },
  "settings.always": { en: "always", es: "siempre" },
  "settings.active": { en: "active", es: "activo" },
  "settings.live": { en: "live", es: "en vivo" },
  "settings.mcpEndpoints": { en: "MCP Endpoints (for AI clients)", es: "Endpoints MCP (para clientes de IA)" },
  "settings.server": { en: "Server", es: "Servidor" },
  "settings.endpointUrl": { en: "Endpoint URL", es: "URL del endpoint" },
  "settings.scope": { en: "Scope", es: "Alcance" },
  "settings.routerRecommended": { en: "Router (recommended)", es: "Router (recomendado)" },
  "settings.categoryTools": { en: "7 category tools", es: "7 herramientas por categoría" },
  "settings.allMemoryTools": { en: "All memory tools", es: "Todas las herramientas de memoria" },
  "settings.allResearchTools": { en: "All research tools", es: "Todas las herramientas de investigación" },
  "settings.allSharingTools": { en: "All sharing tools", es: "Todas las herramientas de compartir" },
  "settings.aiProviderSection": { en: "AI Provider", es: "Proveedor de IA" },
  "settings.provider": { en: "Provider", es: "Proveedor" },
  "settings.notConfigured": { en: "— Not configured —", es: "— No configurado —" },
  "settings.apiKey": { en: "API Key", es: "Clave API" },
  "settings.model": { en: "Model", es: "Modelo" },
  "settings.modelOptional": { en: "optional — uses provider default if blank", es: "opcional — usa el predeterminado del proveedor si está vacío" },
  "settings.baseUrl": { en: "Base URL", es: "URL base" },
  "settings.baseUrlHint": { en: "Ollama, OpenRouter, or custom endpoint", es: "Ollama, OpenRouter o endpoint personalizado" },
  "settings.testConnection": { en: "Test Connection", es: "Probar conexión" },
  "settings.testingConnection": { en: "Testing connection...", es: "Probando conexión..." },
  "settings.connectionSuccessful": { en: "Connection successful! Provider:", es: "¡Conexión exitosa! Proveedor:" },
  "settings.testFailed": { en: "Failed:", es: "Falló:" },
  "settings.removeAiConfirm": { en: "Remove AI provider configuration?", es: "¿Eliminar la configuración del proveedor de IA?" },
  "settings.savedAiReady": { en: "Saved. AI Chat is ready.", es: "Guardado. El chat de IA está listo." },
  "settings.openChat": { en: "Open Chat", es: "Abrir chat" },
  "settings.aiProfilesSection": { en: "AI Profiles", es: "Perfiles de IA" },
  "settings.addProfile": { en: "+ Add Profile", es: "+ Agregar perfil" },
  "settings.profileName": { en: "Profile Name", es: "Nombre del perfil" },
  "settings.profileNamePlaceholder": { en: "e.g. DashScope, Z.AI", es: "ej. DashScope, Z.AI" },
  "settings.apiKeyLabel": { en: "API Key", es: "Clave API" },
  "settings.leaveBlankKeep": { en: "Leave blank to keep existing", es: "Deja vacío para mantener el existente" },
  "settings.baseUrlLabel": { en: "Base URL", es: "URL base" },
  "settings.modelsLabel": { en: "Models", es: "Modelos" },
  "settings.commaSeparated": { en: "comma-separated", es: "separados por comas" },
  "settings.defaultModel": { en: "Default Model", es: "Modelo predeterminado" },
  "settings.saveProfile": { en: "Save Profile", es: "Guardar perfil" },
  "settings.editProfile": { en: "Edit", es: "Editar" },
  "settings.testProfile": { en: "Test", es: "Probar" },
  "settings.deleteProfile": { en: "Delete", es: "Eliminar" },
  "settings.deleteProfileConfirm": { en: "Delete this AI profile?", es: "¿Eliminar este perfil de IA?" },
  "settings.connectedStatus": { en: "Connected!", es: "¡Conectado!" },
  "settings.failedStatus": { en: "Failed", es: "Falló" },
  "settings.testing": { en: "Testing...", es: "Probando..." },
  "settings.savedReloading": { en: "Saved! Reloading...", es: "¡Guardado! Recargando..." },
  "settings.models": { en: "models", es: "modelos" },
  "settings.key": { en: "Key:", es: "Clave:" },
  "settings.deviceContextSection": { en: "Device Context", es: "Contexto del dispositivo" },
  "settings.deviceId": { en: "Device ID:", es: "ID del dispositivo:" },
  "settings.notSetDevice": { en: "Not set", es: "No establecido" },
  "settings.sectionColumn": { en: "Section", es: "Sección" },
  "settings.keyColumn": { en: "Key", es: "Clave" },
  "settings.overriddenBadge": { en: "overridden", es: "sobrescrito" },
  "settings.activeBadge": { en: "active", es: "activo" },
  "settings.disabledBadge": { en: "disabled", es: "desactivado" },
  "settings.updatesSection": { en: "Updates", es: "Actualizaciones" },
  "settings.currentVersion": { en: "Current Version", es: "Versión actual" },
  "settings.lastChecked": { en: "Last Checked", es: "Última verificación" },
  "settings.never": { en: "Never", es: "Nunca" },
  "settings.statusLabel": { en: "Status", es: "Estado" },
  "settings.waitingFirstCheck": { en: "Waiting for first check", es: "Esperando la primera verificación" },
  "settings.autoUpdate": { en: "Auto-Update", es: "Actualización automática" },
  "settings.enabledOption": { en: "Enabled", es: "Activado" },
  "settings.disabledOption": { en: "Disabled", es: "Desactivado" },
  "settings.checkInterval": { en: "Check Interval", es: "Intervalo de verificación" },
  "settings.everyHour": { en: "Every hour", es: "Cada hora" },
  "settings.every6Hours": { en: "Every 6 hours", es: "Cada 6 horas" },
  "settings.every12Hours": { en: "Every 12 hours", es: "Cada 12 horas" },
  "settings.daily": { en: "Daily", es: "Diariamente" },
  "settings.checkNow": { en: "Check Now", es: "Verificar ahora" },
  "settings.checking": { en: "Checking...", es: "Verificando..." },
  "settings.alreadyUpToDate": { en: "Already up to date.", es: "Ya está actualizado." },
  "settings.helpSetupSection": { en: "Help & Setup", es: "Ayuda y configuración" },
  "settings.notifications": { en: "Notifications", es: "Notificaciones" },
  "settings.notifTypes": { en: "Enabled notification types", es: "Tipos de notificación habilitados" },
  "settings.notifReminder": { en: "Reminders", es: "Recordatorios" },
  "settings.notifMedia": { en: "Media", es: "Medios" },
  "settings.notifPeer": { en: "Peer Messages", es: "Mensajes de pares" },
  "settings.notifSystem": { en: "System", es: "Sistema" },

  // ─── Settings Groups ───
  "settings.group.general": { en: "General", es: "General" },
  "settings.group.ai": { en: "AI & Models", es: "IA y Modelos" },
  "settings.group.connections": { en: "Connections", es: "Conexiones" },
  "settings.group.content": { en: "Content", es: "Contenido" },
  "settings.group.multiInstance": { en: "Multi-Instance", es: "Multi-instancia" },
  "settings.group.system": { en: "System", es: "Sistema" },
  "settings.group.account": { en: "Account", es: "Cuenta" },

  // ─── Settings Section Labels ───
  "settings.section.theme": { en: "Theme", es: "Tema" },
  "settings.section.language": { en: "Language", es: "Idioma" },
  "settings.section.notifications": { en: "Notifications", es: "Notificaciones" },
  "settings.section.ports": { en: "Ports", es: "Puertos" },
  "settings.section.remoteExposure": { en: "Remote Tool Exposure", es: "Exposición de herramientas remotas" },
  "settings.section.remoteInvocation": { en: "Remote Tool Invocation", es: "Invocación de herramientas remotas" },
  "settings.section.remoteBotManagement": { en: "Remote Bot Management", es: "Gestión remota de bots" },
  "settings.section.botRuntime": { en: "Bot Runtime", es: "Ejecución de bots" },
  "settings.ports.description": { en: "Host ports used by installed bundles and core services, with live status. Read-only.", es: "Puertos del host usados por los paquetes instalados y los servicios principales, con estado en vivo. Solo lectura." },
  "settings.section.llm": { en: "LLM Orchestrator", es: "Orquestador LLM" },
  "settings.section.connections": { en: "Connection URLs", es: "URLs de conexión" },
  "settings.section.helpSetup": { en: "Help & Setup", es: "Ayuda y configuración" },
  "settings.section.integrations": { en: "Integrations", es: "Integraciones" },
  "settings.section.blog": { en: "Blog Settings", es: "Ajustes del blog" },
  "settings.section.discovery": { en: "Contact Discovery", es: "Descubrimiento de contactos" },
  "settings.section.updates": { en: "Updates", es: "Actualizaciones" },
  "settings.section.deviceContext": { en: "Device Context", es: "Contexto del dispositivo" },
  "settings.section.identity": { en: "Identity", es: "Identidad" },
  "settings.section.password": { en: "Change Password", es: "Cambiar contraseña" },
  "settings.section.navGroups": { en: "Navigation", es: "Navegación" },
  // Multi-Instance group
  "settings.section.pairedInstances": { en: "Paired Instances", es: "Instancias emparejadas" },
  "settings.section.syncConflicts": { en: "Sync Conflicts", es: "Conflictos de sincronización" },
  "settings.section.syncProfiles": { en: "Sync Profiles", es: "Perfiles de sincronización" },
  "settings.section.auditLog": { en: "Cross-Host Audit", es: "Auditoría entre hosts" },
  "settings.section.sharedContext": { en: "Shared Context (crow.md)", es: "Contexto compartido (crow.md)" },
  "settings.section.tts": { en: "Text-to-Speech", es: "Texto a voz" },
  "settings.ttsSearchVoices": { en: "Search voices...", es: "Buscar voces..." },
  "settings.ttsAllGenders": { en: "All voices", es: "Todas las voces" },
  "settings.ttsFemale": { en: "Female", es: "Femenina" },
  "settings.ttsMale": { en: "Male", es: "Masculina" },
  "settings.ttsCurrentVoice": { en: "Current voice", es: "Voz actual" },
  "settings.section.companionVoice": { en: "Companion Voice", es: "Voz del compañero" },
  "settings.section.companion": { en: "Companion", es: "Compañero" },
  "settings.section.twoFactor": { en: "Two-Factor Auth", es: "Autenticación 2FA" },
  "settings.2faEnabled": { en: "Two-factor authentication enabled.", es: "Autenticación de dos factores activada." },
  "settings.2faDisabled": { en: "Two-factor authentication disabled.", es: "Autenticación de dos factores desactivada." },
  "settings.2faCodesRegenerated": { en: "Recovery codes regenerated.", es: "Códigos de recuperación regenerados." },
  "settings.2faDevicesRevoked": { en: "All trusted devices revoked.", es: "Todos los dispositivos de confianza revocados." },
  "settings.2faStatus": { en: "Status", es: "Estado" },
  "settings.2faStatusEnabled": { en: "Enabled", es: "Activada" },
  "settings.2faRecoveryRemaining": { en: "Recovery codes remaining", es: "Códigos de recuperación restantes" },
  "settings.2faRegenerateCodes": { en: "Regenerate Recovery Codes", es: "Regenerar códigos de recuperación" },
  "settings.2faRevokeDevices": { en: "Revoke All Trusted Devices", es: "Revocar todos los dispositivos de confianza" },
  "settings.2faDisableButton": { en: "Disable Two-Factor Auth", es: "Desactivar autenticación 2FA" },
  "settings.2faDisableConfirm": { en: "Are you sure you want to disable two-factor authentication?", es: "¿Estás seguro de desactivar la autenticación de dos factores?" },
  "settings.2faMandatory": { en: "Two-factor authentication is required for managed hosting and cannot be disabled.", es: "La autenticación de dos factores es obligatoria para hosting administrado y no puede desactivarse." },
  "settings.2faSetupInstructions": { en: "Scan the QR code with your authenticator app (Google Authenticator, Authy, etc.), then enter the code to verify.", es: "Escanea el código QR con tu aplicación autenticadora (Google Authenticator, Authy, etc.), luego ingresa el código para verificar." },

  // ─── Settings Navigation ───
  "settings.backToSettings": { en: "Settings", es: "Ajustes" },

  // ─── Sync Conflicts Section (W4-1) ───
  "syncConflicts.description": {
    en: "When two instances edit the same item at the same time, the newer version is kept and the other is saved here for review. Unresolved conflicts are shown first.",
    es: "Cuando dos instancias editan el mismo elemento al mismo tiempo, se guarda la versión más reciente y la otra se almacena aquí para revisión. Los conflictos sin resolver se muestran primero.",
  },
  "syncConflicts.unresolvedHeading": { en: "Unresolved conflicts", es: "Conflictos sin resolver" },
  "syncConflicts.resolvedHeading": { en: "Recently resolved", es: "Resueltos recientemente" },
  "syncConflicts.none": { en: "No unresolved conflicts — everything is in sync.", es: "Sin conflictos sin resolver — todo está sincronizado." },
  "syncConflicts.noneResolved": { en: "No resolved conflicts.", es: "Sin conflictos resueltos." },
  "syncConflicts.colTable": { en: "Table", es: "Tabla" },
  "syncConflicts.colRowId": { en: "Row", es: "Fila" },
  "syncConflicts.colWhen": { en: "When", es: "Cuándo" },
  "syncConflicts.colOp": { en: "Op", es: "Op" },
  "syncConflicts.colData": { en: "Data", es: "Datos" },
  "syncConflicts.colActions": { en: "Actions", es: "Acciones" },
  "syncConflicts.resolvedLabel": { en: "Resolved", es: "Resuelto" },
  "syncConflicts.showData": { en: "View data", es: "Ver datos" },
  "syncConflicts.winningData": { en: "Kept version (current)", es: "Versión guardada (actual)" },
  "syncConflicts.losingDataFields": { en: "Fields in the other version", es: "Campos de la otra versión" },
  "syncConflicts.losingDataDelete": { en: "Deleted version (other side)", es: "Versión eliminada (otro lado)" },
  "syncConflicts.keepCurrent": { en: "Keep current", es: "Mantener actual" },
  "syncConflicts.restoreOther": { en: "Restore other version", es: "Restaurar otra versión" },
  "syncConflicts.insertRestoreDisabled": {
    en: "Auto-restore not available (id collision — review data above and resolve manually).",
    es: "Restauración automática no disponible (colisión de id — revisa los datos arriba y resuélvelo manualmente).",
  },
  "syncConflicts.compositeRestoreDisabled": {
    en: "Auto-restore not available (composite key — use crow_update_context_section to apply the values shown).",
    es: "Restauración automática no disponible (clave compuesta — usa crow_update_context_section para aplicar los valores mostrados).",
  },
  "syncConflicts.resolveAll": { en: "Resolve all (keep current versions)", es: "Resolver todos (mantener versiones actuales)" },
  "syncConflicts.resolveAllConfirm": {
    en: "Mark all unresolved conflicts as resolved? The current (winning) version of each item will be kept.",
    es: "¿Marcar todos los conflictos sin resolver como resueltos? Se mantendrá la versión actual (ganadora) de cada elemento.",
  },
  "syncConflicts.loadError": { en: "Failed to load conflicts", es: "Error al cargar conflictos" },
  "syncConflicts.msgApplied": { en: "The other version was restored.", es: "La otra versión fue restaurada." },
  "syncConflicts.msgStale": { en: "This item has changed since the conflict was recorded — please review the current version and confirm again.", es: "Este elemento ha cambiado desde que se registró el conflicto — revisa la versión actual y confirma de nuevo." },
  "syncConflicts.msgRefused": { en: "This version can't be restored automatically; its data remains visible below.", es: "Esta versión no se puede restaurar automáticamente; sus datos siguen visibles abajo." },
  "syncConflicts.msgFailed": { en: "Restore failed — the conflict stays open and its data remains visible below.", es: "La restauración falló — el conflicto sigue abierto y sus datos siguen visibles abajo." },

  // ─── Nav Groups Settings ───
  "navGroups.description": { en: "Organize your sidebar by creating groups and moving panels between them.", es: "Organiza tu barra lateral creando grupos y moviendo paneles entre ellos." },
  "navGroups.noGroups": { en: "No navigation groups configured. Create one to get started.", es: "No hay grupos de navegación configurados. Crea uno para comenzar." },
  "navGroups.newGroupName": { en: "New group name", es: "Nombre del nuevo grupo" },
  "navGroups.createGroup": { en: "Create Group", es: "Crear grupo" },
  "navGroups.rename": { en: "Rename", es: "Renombrar" },
  "navGroups.noPanels": { en: "No panels in this group", es: "No hay paneles en este grupo" },
  "navGroups.collapsed": { en: "collapsed", es: "colapsado" },

  // ─── Contacts Panel ───
  "contacts.tabAll": { en: "All Contacts", es: "Todos los contactos" },
  "contacts.tabGroups": { en: "Groups", es: "Grupos" },
  "contacts.tabProfile": { en: "My Profile", es: "Mi perfil" },
  "contacts.searchPlaceholder": { en: "Search contacts...", es: "Buscar contactos..." },
  "contacts.typeAll": { en: "All Types", es: "Todos los tipos" },
  "contacts.typeCrow": { en: "Crow Peers", es: "Pares Crow" },
  "contacts.typeManual": { en: "Manual", es: "Manual" },
  "contacts.allGroups": { en: "All Groups", es: "Todos los grupos" },
  "contacts.import": { en: "Import", es: "Importar" },
  "contacts.export": { en: "Export vCard", es: "Exportar vCard" },
  "contacts.addManual": { en: "Add manual contact", es: "Agregar contacto manual" },
  "contacts.addContact": { en: "Add Contact", es: "Agregar contacto" },
  "contacts.fieldName": { en: "Name", es: "Nombre" },
  "contacts.fieldEmail": { en: "Email", es: "Correo" },
  "contacts.fieldPhone": { en: "Phone", es: "Telefono" },
  "contacts.fieldNotes": { en: "Notes", es: "Notas" },
  "contacts.fieldAvatar": { en: "Avatar URL", es: "URL de avatar" },
  "contacts.namePlaceholder": { en: "Full name", es: "Nombre completo" },
  "contacts.noContacts": { en: "No contacts yet", es: "Sin contactos" },
  "contacts.noContactsHint": { en: "Add a manual contact above, or ask your AI to generate an invite code.", es: "Agrega un contacto manual arriba, o pide a tu IA que genere un codigo de invitacion." },
  "contacts.blocked": { en: "Blocked", es: "Bloqueado" },
  "contacts.manual": { en: "Manual", es: "Manual" },
  "contacts.crow": { en: "Crow Peer", es: "Par Crow" },
  "contacts.notFound": { en: "Contact not found.", es: "Contacto no encontrado." },
  "contacts.lastSeen": { en: "Last Seen", es: "Visto por ultima vez" },
  "contacts.joined": { en: "Added", es: "Agregado" },
  "contacts.details": { en: "Details", es: "Detalles" },
  "contacts.activity": { en: "Recent Activity", es: "Actividad reciente" },
  "contacts.editContact": { en: "Edit contact", es: "Editar contacto" },
  "contacts.block": { en: "Block", es: "Bloquear" },
  "contacts.unblock": { en: "Unblock", es: "Desbloquear" },
  "contacts.blockConfirm": { en: "Block this contact? They won\\'t be able to message or share with you.", es: "Bloquear este contacto? No podra enviarte mensajes ni compartir contigo." },
  "contacts.deleteConfirm": { en: "Delete this contact? This cannot be undone.", es: "Eliminar este contacto? No se puede deshacer." },
  "contacts.addToGroup": { en: "Add to Group", es: "Agregar al grupo" },
  "contacts.noGroups": { en: "No groups created yet. Go to the Groups tab to create one.", es: "No hay grupos creados. Ve a la pestana Grupos para crear uno." },
  "contacts.groupName": { en: "Group Name", es: "Nombre del grupo" },
  "contacts.groupNamePlaceholder": { en: "e.g. Family, Work, Friends", es: "ej. Familia, Trabajo, Amigos" },
  "contacts.groupColor": { en: "Color", es: "Color" },
  "contacts.createGroup": { en: "Create Group", es: "Crear grupo" },
  "contacts.noGroupsYet": { en: "No groups yet. Create one above.", es: "Sin grupos. Crea uno arriba." },
  "contacts.noMembers": { en: "No members", es: "Sin miembros" },
  "contacts.deleteGroupConfirm": { en: "Delete this group? Contacts will not be deleted.", es: "Eliminar este grupo? Los contactos no se eliminaran." },
  "contacts.profileName": { en: "Display Name", es: "Nombre para mostrar" },
  "contacts.profileNamePlaceholder": { en: "How others see you", es: "Como te ven los demas" },
  "contacts.profileBio": { en: "Bio", es: "Biografia" },
  "contacts.profileBioPlaceholder": { en: "A short bio about yourself", es: "Una breve biografia sobre ti" },
  "contacts.profileNotSet": { en: "Not set", es: "No configurado" },
  "contacts.importTitle": { en: "Import Contacts", es: "Importar contactos" },
  "contacts.importFormat": { en: "Format", es: "Formato" },
  "contacts.importFile": { en: "Choose File", es: "Elegir archivo" },
  "contacts.importPaste": { en: "Or paste content", es: "O pegar contenido" },
  "contacts.importPastePlaceholder": { en: "Paste vCard or CSV content here...", es: "Pega el contenido vCard o CSV aqui..." },
  "contacts.importButton": { en: "Import", es: "Importar" },

  // ─── Onboarding (first-run guided tour) ───
  "onboarding.title": { en: "Welcome to Crow", es: "Bienvenido a Crow" },
  "onboarding.welcome.title": { en: "Welcome", es: "Bienvenido" },
  "onboarding.welcome.body": {
    en: "Crow is your persistent memory and research assistant. It remembers what matters and works across the AI clients you already use. This short tour points you to the few things worth setting up.",
    es: "Crow es tu asistente de memoria persistente e investigación. Recuerda lo importante y funciona con los clientes de IA que ya usas. Este breve recorrido te muestra las pocas cosas que vale la pena configurar.",
  },
  "onboarding.integrations.title": { en: "Connect your tools", es: "Conecta tus herramientas" },
  "onboarding.integrations.body": {
    en: "Link services like Google, Slack, and GitHub so Crow can act on them for you. You add API keys in Settings, where each integration explains what it needs.",
    es: "Conecta servicios como Google, Slack y GitHub para que Crow pueda actuar en ellos por ti. Agrega las claves API en Ajustes, donde cada integración explica lo que necesita.",
  },
  "onboarding.integrationsNote": {
    en: "Some integrations need a gateway restart to take effect after you add their keys.",
    es: "Algunas integraciones requieren reiniciar el gateway para activarse después de agregar sus claves.",
  },
  "onboarding.openIntegrations": { en: "Open Integrations", es: "Abrir Integraciones" },
  "onboarding.bot.title": { en: "Set up an agent", es: "Configura un agente" },
  "onboarding.bot.body": {
    en: "Crow can run agents on channels like Gmail and Discord, each with its own persona, skills, and tools. Create one in the Bot Builder.",
    es: "Crow puede ejecutar agentes en canales como Gmail y Discord, cada uno con su propia personalidad, habilidades y herramientas. Crea uno en el Bot Builder.",
  },
  "onboarding.openBotBuilder": { en: "Open Bot Builder", es: "Abrir Bot Builder" },
  "onboarding.connect.title": { en: "Connect an AI client", es: "Conecta un cliente de IA" },
  "onboarding.connect.body": {
    en: "Use Crow's memory and tools from Claude Code, claude.ai, and other clients over MCP.",
    es: "Usa la memoria y herramientas de Crow desde Claude Code, claude.ai y otros clientes mediante MCP.",
  },
  "onboarding.connectNote": {
    en: "Open the guided connect wizard to set up Claude Code, Cursor, Gemini CLI, and other clients with copy-paste config.",
    es: "Abre el asistente de conexión guiado para configurar Claude Code, Cursor, Gemini CLI y otros clientes con configuración lista para copiar.",
  },
  "onboarding.openConnections": { en: "Open the connect wizard", es: "Abrir el asistente de conexión" },
  "onboarding.done.title": { en: "You're all set", es: "Todo listo" },
  "onboarding.done.body": {
    en: "That's the tour. Explore the dashboard at your own pace. Everything here is available from the sidebar.",
    es: "Eso es todo. Explora el panel a tu ritmo. Todo está disponible en la barra lateral.",
  },
  "onboarding.doneNote": {
    en: "You can replay this guide anytime from Settings, Help and Setup.",
    es: "Puedes repetir esta guía cuando quieras desde Ajustes, Ayuda y configuración.",
  },
  "onboarding.btnNext": { en: "Next", es: "Siguiente" },
  "onboarding.btnBack": { en: "Back", es: "Atrás" },
  "onboarding.btnSkip": { en: "Skip to dashboard", es: "Ir al panel" },
  "onboarding.btnGoDashboard": { en: "Go to the dashboard", es: "Ir al panel" },
  "onboarding.replayLink": { en: "Replay setup guide", es: "Repetir guía de configuración" },

  // F6c-1 connect wizard
  "connect.title": { en: "Connect a client", es: "Conecta un cliente" },
  "connect.intro": {
    en: "Connect an MCP client to use Crow's memory and tools. Local clients (Claude Code, Cursor, and others on this machine or your Tailnet) connect directly. Pick your client below for copy-paste setup.",
    es: "Conecta un cliente MCP para usar la memoria y las herramientas de Crow. Los clientes locales (Claude Code, Cursor y otros en esta máquina o tu Tailnet) se conectan directamente. Elige tu cliente abajo para una configuración lista para copiar.",
  },
  "connect.localStdioHeading": { en: "Local (stdio)", es: "Local (stdio)" },
  "connect.remoteHttpHeading": { en: "Remote (HTTP)", es: "Remoto (HTTP)" },
  "connect.stdioNote": {
    en: "Local stdio needs the Crow repository checked out on this machine.",
    es: "El stdio local necesita el repositorio de Crow descargado en esta máquina.",
  },
  "connect.oauthNote": {
    en: "On first use the client opens a browser to authorize access. No token is needed.",
    es: "En el primer uso el cliente abre un navegador para autorizar el acceso. No se necesita ningún token.",
  },
  "connect.cc.stdioLead": {
    en: "In your Crow repo, run the config generator, then restart Claude Code:",
    es: "En tu repo de Crow, ejecuta el generador de configuración y luego reinicia Claude Code:",
  },
  "connect.cc.remoteLead": {
    en: "Or connect over HTTP from any Tailnet machine. Add this to ~/.claude/mcp.json (or .mcp.json in a project):",
    es: "O conéctate por HTTP desde cualquier máquina del Tailnet. Agrega esto a ~/.claude/mcp.json (o a .mcp.json en un proyecto):",
  },
  "connect.cursor.lead": {
    en: "Add this to .cursor/mcp.json, then reload Cursor:",
    es: "Agrega esto a .cursor/mcp.json y luego recarga Cursor:",
  },
  "connect.cline.lead": {
    en: "In VS Code, open Cline's MCP settings, add a remote (streamable HTTP) server, and paste this URL:",
    es: "En VS Code, abre los ajustes MCP de Cline, agrega un servidor remoto (streamable HTTP) y pega esta URL:",
  },
  "connect.gemini.lead": {
    en: "Add this MCP endpoint URL to your Gemini CLI settings (~/.gemini/settings.json), then restart Gemini CLI:",
    es: "Agrega esta URL de endpoint MCP a tus ajustes de Gemini CLI (~/.gemini/settings.json) y luego reinicia Gemini CLI:",
  },
  "connect.desktop.lead": {
    en: "Claude Desktop connects over local stdio. In your Crow repo, run the config generator, then restart Claude Desktop:",
    es: "Claude Desktop se conecta por stdio local. En tu repo de Crow, ejecuta el generador de configuración y luego reinicia Claude Desktop:",
  },
  "connect.cloud.warning": {
    en: "Cloud web clients (claude.ai, ChatGPT) cannot reach a private Crow. This instance is reachable on your Tailnet only, and exposing the MCP endpoints publicly is intentionally blocked. Use a local client instead.",
    es: "Los clientes web en la nube (claude.ai, ChatGPT) no pueden alcanzar un Crow privado. Esta instancia es accesible solo en tu Tailnet, y exponer los endpoints MCP públicamente está bloqueado a propósito. Usa un cliente local en su lugar.",
  },
  "connect.moreHeading": { en: "More", es: "Más" },
  "connect.openConnections": { en: "View raw connection URLs", es: "Ver URLs de conexión sin formato" },
  "connect.openWizard": { en: "Open the connect wizard", es: "Abrir el asistente de conexión" },
  "connect.settingsPointer": {
    en: "Need step-by-step setup for a specific client? Open the guided connect wizard.",
    es: "¿Necesitas configuración paso a paso para un cliente específico? Abre el asistente de conexión guiado.",
  },
  "connect.token.heading": { en: "Headless / no browser (token)", es: "Sin navegador (token)" },
  "connect.token.intro": {
    en: "For a client that has no browser to complete the OAuth sign-in, generate a token and paste it into the client config below. The token grants full access to this Crow, so treat it like a password.",
    es: "Para un cliente que no tiene navegador para completar el inicio de sesión OAuth, genera un token y pégalo en la configuración del cliente. El token otorga acceso completo a este Crow, así que trátalo como una contraseña.",
  },
  "connect.token.generate": { en: "Generate token", es: "Generar token" },
  "connect.token.rotate": { en: "Rotate token", es: "Rotar token" },
  "connect.token.revoke": { en: "Revoke token", es: "Revocar token" },
  "connect.token.activeSince": { en: "A token is active. Created:", es: "Hay un token activo. Creado:" },
  "connect.token.revealHeading": { en: "Your new token", es: "Tu nuevo token" },
  "connect.token.revealWarning": {
    en: "Copy this token now. For your security it will not be shown again. If you lose it, rotate to get a new one.",
    es: "Copia este token ahora. Por tu seguridad no se mostrará de nuevo. Si lo pierdes, rótalo para obtener uno nuevo.",
  },
  "connect.token.configLead": {
    en: "Paste this into a client that supports an Authorization header (for example Claude Code):",
    es: "Pega esto en un cliente que admita un encabezado de autorización (por ejemplo Claude Code):",
  },
  "connect.token.placeholderNote": {
    en: "The token is stored hashed and cannot be shown again. The config below uses a placeholder. Rotate to issue a fresh token you can copy.",
    es: "El token se guarda cifrado y no se puede volver a mostrar. La configuración de abajo usa un marcador. Rota para emitir un token nuevo que puedas copiar.",
  },
  "connect.token.connectionsPointer": {
    en: "Generate a headless access token in the connect wizard.",
    es: "Genera un token de acceso sin navegador en el asistente de conexión.",
  },
  "connect.token.actionError": {
    en: "Something went wrong with that action. Refresh the page and try again.",
    es: "Algo salió mal con esa acción. Actualiza la página e inténtalo de nuevo.",
  },
};

export const SUPPORTED_LANGS = ["en", "es"];

/**
 * Translate a key to the given language.
 * Fallback: requested lang → en → raw key.
 * @param {string} key - Dot-separated translation key (e.g. "nav.messages")
 * @param {string} [lang="en"] - Language code
 * @returns {string}
 */
export function t(key, lang = "en") {
  const entry = translations[key];
  if (!entry) return key;
  return entry[lang] || entry.en || key;
}

/**
 * JS-safe version of t() for embedding in template literal JS strings.
 * Escapes single quotes, backslashes, backticks, and ${} sequences.
 * Use this instead of t() when the result will be inside a JS string literal.
 * @param {string} key
 * @param {string} [lang="en"]
 * @returns {string}
 */
export function tJs(key, lang = "en") {
  const val = t(key, lang);
  return val
    .replace(/\\/g, "\\\\")
    .replace(/'/g, "\\'")
    .replace(/`/g, "\\`")
    .replace(/\$\{/g, "\\${");
}
