{ "app": { "name": "EverShelf", "loading": "Cargando..." }, "nav": { "title": "EverShelf", "home": "Inicio", "inventory": "Despensa", "recipes": "Recetas", "shopping": "Compras", "log": "Registro", "settings": "Ajustes" }, "btn": { "back": "← Volver", "save": "💾 Guardar", "cancel": "✕ Cancelar", "close": "Cerrar", "add": "✅ Añadir", "delete": "Eliminar", "edit": "✏️ Editar", "use": "Usar", "edit_item": "Editar", "search": "🔍 Buscar", "go": "✅ Ir", "toggle_password": "👁️ Mostrar/Ocultar", "load_more": "Cargar más...", "save_config": "💾 Guardar configuración", "save_product": "💾 Guardar producto", "restart": "↺ Reiniciar", "reset_default": "↺ Restablecer valores por defecto", "save_info": "💾 Guardar información", "retry": "🔄 Reintentar", "yes_short": "Sí", "no_short": "No" }, "form": { "select_placeholder": "-- Seleccionar --" }, "locations": { "dispensa": "Despensa", "frigo": "Nevera", "freezer": "Congelador", "altro": "Otro" }, "categories": { "latticini": "Lácteos", "carne": "Carne", "pesce": "Pescado", "frutta": "Fruta", "verdura": "Verduras", "pasta": "Pasta y Arroz", "pane": "Pan y Panadería", "surgelati": "Congelados", "bevande": "Bebidas", "condimenti": "Condimentos", "snack": "Snacks y Dulces", "conserve": "Conservas", "cereali": "Cereales y Legumbres", "igiene": "Higiene", "pulizia": "Limpieza", "altro": "Otro", "select": "-- Seleccionar --" }, "units": { "pz": "uds", "conf": "paq", "g": "g", "ml": "ml", "pieces": "Unidades", "grams": "Gramos", "box": "Paquete", "boxes": "Paquetes", "millilitres": "Mililitros", "from": "de" }, "shopping_sections": { "frutta_verdura": "Frutas y Verduras", "carne_pesce": "Carne y Pescado", "latticini": "Lácteos y Frescos", "pane_dolci": "Pan y Dulces", "pasta": "Pasta y Cereales", "conserve": "Conservas y Salsas", "surgelati": "Congelados", "bevande": "Bebidas", "pulizia_igiene": "Limpieza e Higiene", "altro": "Otro" }, "dashboard": { "expired_title": "🚫 Caducado", "expiring_title": "⏰ Caduca pronto", "stats_period": "📊 Últimos 30 días", "opened_title": "📦 Productos abiertos", "review_title": "🔍 Por revisar", "review_hint": "Cantidades inusuales. Confirma si son correctas o modifícalas.", "quick_recipe": "Receta rápida con productos que caducan", "banner_review_title": "Cantidad anormal", "banner_review_action_ok": "Es correcto", "banner_review_action_finish": "🗑️ Todo terminado", "banner_review_action_edit": "Corregir", "banner_review_action_weigh": "Pesar", "banner_review_dismiss": "Ignorar", "banner_prediction_title": "Consumo por revisar", "banner_prediction_hint": "La estimación de consumo se adapta a los datos recientes: confirma solo si la cantidad actual es correcta.", "banner_prediction_action_confirm": "Confirmar {qty} {unit}", "banner_prediction_action_weigh": "Pesar ahora", "banner_prediction_action_edit": "Actualizar cantidad", "banner_expired_title": "Producto caducado", "banner_expired_today": "Caducado hoy", "banner_expired_days": "Caducado hace {days} días", "banner_expired_action_use": "Usar de todas formas", "banner_expired_action_finished": "¡Ya lo terminé!", "banner_expired_action_throw": "Lo tiré", "banner_expired_action_edit": "Corregir fecha", "banner_anomaly_action_edit": "Corregir inventario", "banner_anomaly_action_dismiss": "La cantidad es correcta", "banner_no_expiry_title": "Caducidad faltante: {name}", "banner_no_expiry_detail": "Este producto no tiene fecha de caducidad. ¿Quieres añadir una o confirmar que no caduca?", "banner_no_expiry_action_set": "Establecer fecha de caducidad", "banner_no_expiry_action_dismiss": "No caduca ✓", "banner_no_expiry_toast_dismissed": "Marcado como «sin fecha de caducidad»", "banner_expiring_title": "Caduca pronto", "banner_expiring_today": "¡Caduca hoy!", "banner_expiring_tomorrow": "Caduca mañana", "banner_expiring_days": "Caduca en {days} días", "banner_expiring_action_use": "Usar ahora", "banner_finished_title": "¿terminado?", "banner_finished_detail": "Registré que {name} llegó a cero de stock. ¿Realmente se acabó o todavía tienes algo?", "banner_finished_action_yes": "Sí, se acabó", "banner_finished_action_no": "No, todavía tengo", "banner_review_unusual_pkg_title": "Tamaño de paquete inusual", "banner_review_unusual_pkg_detail": "Configuraste un paquete de {qty} {unit} — el tamaño parece muy grande. Comprueba si es correcto o edita.", "banner_review_low_qty_title": "Cantidad muy baja", "banner_review_low_qty_detail": "Solo tienes {qty} en stock — parece muy poco, puede ser un error de escritura. Confirma si es correcto.", "banner_review_high_qty_title": "Cantidad inusualmente alta", "banner_review_high_qty_detail": "Tienes {qty} en stock — la cifra parece muy alta. Confirma si es correcto o edita.", "banner_prediction_rate_day": "Media ~{n} {unit}/día", "banner_prediction_rate_week": "Media ~{n} {unit}/semana", "banner_prediction_days_ago": "Hace {n} días reabasteciste", "banner_prediction_more": "estimación anterior: {expected} {unit}{time}; cantidad actual: {actual} {unit}.", "banner_prediction_less": "estimación: {expected} {unit}{time}; cantidad actual: {actual} {unit}. Si tu ritmo de uso cambió, la previsión se actualiza automáticamente.", "banner_finished_zero": "El inventario muestra cero, pero los movimientos registrados sugieren que no debería estar vacío.", "banner_finished_expected": "Según los registros deberías tener todavía {qty} {unit}.", "banner_finished_check": "¿Puedes comprobarlo?", "banner_anomaly_phantom_title": "tienes más stock del esperado", "banner_anomaly_phantom_detail": "El inventario indica {inv_qty} {unit}, pero según los registros solo deberías tener {expected_qty} {unit}. ¿Añadiste stock sin registrarlo?", "banner_anomaly_untracked_title": "stock no registrado como entrada", "banner_anomaly_untracked_detail": "Tienes {inv_qty} {unit} en inventario, pero las salidas registradas superan las entradas — el stock inicial probablemente nunca se añadió como transacción «entrada». Puedes corregir la cantidad o registrar las entradas faltantes.", "banner_anomaly_ghost_title": "tienes menos stock del esperado", "banner_anomaly_ghost_detail": "Según las operaciones registradas deberías tener {expected_qty} {unit} de {name}, pero el inventario solo muestra {inv_qty} {unit}. ¿Tomaste stock sin registrarlo?", "banner_dup_loss_title": "Control de doble salida: {name}", "banner_dup_loss_detail": "Posible registro duplicado en {location}: dos salidas seguidas ({qty_pair}) en ~{seconds}s. Revisa y corrige si hace falta.", "banner_dup_loss_action_fix": "Corregir cantidad", "banner_dup_loss_action_open": "Abrir ficha del producto", "banner_dup_loss_action_done": "Ya revisado", "banner_dup_loss_toast_done": "Control marcado como revisado", "consumed": "Consumido: {n} ({pct}%)", "wasted": "Desperdiciado: {n} ({pct}%)", "more_opened": "y {n} más abiertos...", "banner_expired_detail": "{when} · aún tienes {qty}.", "banner_opened_detail": "{when} en {location} · aún tienes {qty}.", "banner_explain_title": "Pedir explicación a Gemini", "banner_explain_btn": "Explicar", "banner_analyzing": "🤖 Analizando…" }, "inventory": { "title": "Despensa", "filter_all": "Todo", "search_placeholder": "🔍 Buscar producto...", "recent_title": "🕐 Usados recientemente", "popular_title": "⭐ Más usados", "empty": "No hay productos aquí.\n¡Escanea un producto para añadirlo!", "no_items_found": "No se encontraron artículos", "qty_remainder_suffix": "restante", "vacuum_badge": "🫙 Al vacío", "opened_badge": "📭 Abierto", "label_expiry": "📅 Caducidad", "label_storage": "🫙 Almacenamiento", "label_status": "📭 Estado", "opened_since": "Abierto desde el {date}", "label_position": "📍 Ubicación", "label_quantity": "📦 Cantidad", "label_added": "📅 Añadido", "empty_text": "No hay productos aquí.
¡Escanea un producto para añadirlo!", "empty_db": "No hay productos en la base de datos.
¡Escanea un producto para empezar!", "qty_trace": "< 1" }, "scan": { "title": "Escáner", "mode_shopping": "🛒 Modo compras", "mode_shopping_end": "✅ Finalizar compras", "spesa_btn": "🛒 Compras", "zoom": "Zoom", "tab_barcode": "Código de barras", "tab_name": "Nombre", "tab_ai": "IA", "recents_label": "Recientes", "torch_hint": "Linterna", "torch_on": "Linterna encendida", "torch_off": "Linterna apagada", "torch_unavailable": "Linterna no disponible en este dispositivo", "flip_hint": "Cambiar cámara", "flip_front": "Cámara frontal", "flip_back": "Cámara trasera", "num_ocr_btn": "🔢 Leer números con IA", "num_ocr_searching": "Buscando código de barras con IA...", "num_ocr_found": "Código encontrado: {code}", "num_ocr_not_found": "No se encontró código de barras en la imagen", "barcode_placeholder": "Introduce el código de barras...", "quick_name_divider": "o escribe el nombre", "quick_name_placeholder": "Ej.: Manzanas, Calabacín, Pan...", "manual_entry": "✏️ Entrada manual", "ai_identify": "🤖 Identificar con IA", "hint": "Escanea el código de barras, escribe el nombre del producto o usa la IA para identificarlo", "debug_toggle": "🐛 Registro de depuración", "barcode_acquired": "🔖 Código de barras escaneado: {code}", "scan_barcode": "🔖 Escanear código de barras", "create_named": "Crear {name}", "new_without_barcode": "Nuevo producto sin código de barras", "status_ready": "Apunta la cámara al código de barras", "status_scanning": "Escaneando...", "status_partial": "Detectado: {code} — verificando...", "status_invalid": "Inválido: {code} — reintentando", "status_confirmed": "Confirmado!", "status_parallel": "Escaneo combinado activo...", "status_ocr_searching": "Estoy leyendo los números del código de barras...", "status_ai_visual_searching": "Ahora intento reconocer el producto...", "method_ai_ocr": "Gemini OCR", "method_ai_vision": "Gemini Vision", "ai_fallback_searching": "Identificación de IA en curso...", "ai_fallback_found": "Producto identificado por IA", "ai_fallback_not_found": "IA: producto no reconocido", "ai_fallback_exhausted": "IA: producto no reconocido — prueba a escanear el código", "ai_overlay_msg": "Gemini Vision está analizando el producto...", "ai_retry_btn": "Reintentar con IA", "ai_match_title": "Producto reconocido por IA", "ai_match_subtitle": "Elige un producto ya en despensa o agrega el detectado.", "ai_match_existing": "Posibles coincidencias en despensa", "ai_match_none": "No se encontraron productos similares en despensa.", "ai_match_use_btn": "Usar este", "ai_match_add_btn": "Agregar \"{name}\"", "ai_detected_label": "IA detecto" }, "action": { "title": "¿Qué quieres hacer?", "add_btn": "📥 AÑADIR", "add_sub": "a la despensa/nevera", "use_btn": "📤 USAR / CONSUMIR", "use_sub": "de la despensa/nevera", "have_title": "📦 ¡Ya en stock!", "add_more_sub": "añadir más", "use_qty_sub": "cuánto usaste", "throw_btn": "🗑️ DESECHAR", "throw_sub": "tirar", "edit_sub": "caducidad, ubicación…", "create_recipe_btn": "Receta" }, "add": { "title": "Añadir a la despensa", "location_label": "📍 ¿Dónde lo guardas?", "quantity_label": "📦 Cantidad", "conf_size_label": "📦 Cada paquete contiene:", "conf_size_placeholder": "ej. 300", "vacuum_label": "🫙 Al vacío", "vacuum_hint": "La fecha de caducidad se ampliará automáticamente", "submit": "✅ Añadir", "purchase_type_label": "🛒 Este producto es...", "new_btn": "🆕 Recién comprado", "existing_btn": "📦 Ya lo tenía", "remaining_label": "📦 Cantidad restante", "remaining_hint": "¿Aproximadamente cuánto queda?", "remaining_full": "🟢 Lleno", "remaining_half": "🟠 Por la mitad", "estimated_expiry": "Caducidad estimada:", "suffix_freezer": "(congelador)", "suffix_vacuum": "(al vacío)", "hint_modify": "📝 Puedes cambiar la fecha o escanearla con la cámara", "scan_expiry_title": "📷 Escanear fecha de caducidad", "product_added": "✅ ¡{name} añadido!{qty}", "suffix_freezer_vacuum": "(congelador + al vacío)", "history_badge_tip": "Media de {n} entradas anteriores", "vacuum_question": "¿Al vacío?", "vacuum_saved": "🔒 ¡Al vacío!" }, "use": { "title": "Usar / Consumir", "location_label": "📍 ¿De dónde?", "quantity_label": "¿Cuánto usaste?", "change": "cambiar", "partial_hint": "O especifica la cantidad usada:", "partial_piece_hint": "¿Usaste solo una parte?", "piece": "unidad", "one_whole": "1 entero", "use_all": "🗑️ Todo usado / Terminado", "submit": "📤 Usar esta cantidad", "available": "📦 Disponible:", "opened_badge": "ABIERTO", "not_in_inventory": "⚠️ Producto no en inventario.", "expiry_warning": "⚠️ ¡Usa primero el{loc} que caduca el {date} — {when}!", "expiry_warning_opened": "⚠️ El{loc} lleva abierto {when} — ¡úsalo primero!", "throw_title": "🗑️ Desechar producto", "throw_all": "🗑️ Desechar TODO ({qty})", "throw_qty_label": "¿Cuánto desechar?", "throw_qty_hint": "o introduce una cantidad:", "throw_partial_btn": "🗑️ Desechar esta cantidad", "when_expired": "caducado hace {n} días", "when_today": "caduca hoy", "when_tomorrow": "caduca mañana", "when_days": "caduca en {n} días", "toast_used": "📤 {qty} de {name} usado", "toast_bring": "🛒 Producto terminado → añadido a Bring!", "toast_opened_finished": "🔓 ¡Paquete abierto de {name} terminado!", "disambiguation_hint": "¿Qué quieres decir con «todo terminado»?", "disambiguation_all": "🗑️ Terminar TODO ({qty})", "error_exceeds_stock": "⚠️ ¡No puedes usar más de lo que tienes disponible!", "use_all_confirm_title": "✅ Terminar todo", "use_all_confirm_msg": "Confirma que has terminado el producto:", "use_all_confirm_btn": "✅ Sí, terminado", "throw_all_confirm_title": "🗑️ Desechar todo", "throw_all_confirm_msg": "¿Realmente quieres tirar todo el producto?", "throw_all_confirm_btn": "🗑️ Sí, desechar" }, "product": { "title_new": "Nuevo producto", "title_edit": "Editar producto", "ai_fill": "📷 Sacar foto e identificar con IA", "ai_fill_hint": "La IA rellenará automáticamente los campos del producto", "name_label": "🏷️ Nombre del producto *", "name_placeholder": "Ej.: Leche entera, Pasta penne...", "brand_label": "🏢 Marca", "brand_placeholder": "Ej.: Barilla, Danone, Heinz...", "category_label": "📂 Categoría", "unit_label": "📏 Unidad de medida", "default_qty_label": "🔢 Cantidad por defecto", "conf_size_label": "📦 Cada paquete contiene:", "conf_size_placeholder": "ej. 300", "notes_label": "📝 Notas", "notes_placeholder": "Ej.: sin lactosa, ecológico, guardar en nevera tras abrir...", "barcode_label": "🔖 Código de barras", "barcode_placeholder": "Código de barras (si disponible)", "barcode_hint": "⚠️ ¡Añade el código de barras para la próxima vez solo tendrás que escanear!", "submit": "💾 Guardar producto", "name_required": "Introduce el nombre del producto", "conf_size_required": "Especifica el contenido del paquete", "expiry_estimated": "Caducidad estimada:", "scan_expiry": "Escanear fecha de caducidad", "expiry_hint": "📝 Puedes editar la fecha o escanearla con la cámara", "add_batch": "📦 + Lote con fecha diferente", "package_info": "📦 Paquete: {info}", "edit_catalog": "⚙️ Editar información del producto (nombre, marca, categoría…)", "not_recognized": "⚠️ Producto no reconocido", "edit_info": "✏️ Editar información", "modify_details": "EDITAR\ncaducidad, ubicación…", "already_in_pantry": "📋 Ya en la despensa", "no_barcode": "Sin código de barras", "unknown_product": "Producto no reconocido", "edit_name_brand": "Editar nombre/marca", "weight_label": "Peso", "origin_label": "Origen", "labels_label": "Etiquetas", "select_variant": "Selecciona la variante exacta o usa los datos de IA:" }, "products": { "title": "📦 Todos los productos", "search_placeholder": "🔍 Buscar producto...", "empty": "No hay productos en la base de datos.\n¡Escanea un producto para empezar!", "no_category": "No hay productos en esta categoría" }, "recipes": { "title": "🍳 Recetas", "generate": "✨ Generar nueva receta", "archive_empty": "No hay recetas guardadas. ¡Genera tu primera receta!", "dialog_title": "🍳 Receta", "dialog_desc": "Generaré una receta saludable usando ingredientes de la despensa, priorizando los productos que caducan.", "meal_label": "🕐 ¿Qué comida?", "persons_label": "👥 ¿Para cuántas personas?", "meal_type_label": "🎯 Tipo de comida", "opt_fast": "⚡ Comida rápida", "opt_light": "🥗 Apetito ligero", "opt_expiry": "⏰ Priorizar productos que caducan", "opt_healthy": "💚 Extra saludable", "opt_opened": "📦 Priorizar productos abiertos", "opt_zero_waste": "♻️ Cero desperdicio", "generate_btn": "✨ Generar receta", "loading_msg": "Preparando tu receta...", "start_cooking": "👨‍🍳 Modo cocina", "regenerate": "🔄 Generar otra", "regen_choice_title": "¿Qué quieres hacer con esta receta?", "regen_replace": "🔄 Generar otra (descartar esta)", "regen_save_new": "💾 Guardar en el archivo y generar una nueva", "close_btn": "✅ Cerrar", "ingredients_title": "🧾 Ingredientes", "tools_title": "Equipo necesario", "steps_title": "👨‍🍳 Pasos", "no_steps": "No hay pasos disponibles", "generate_error": "Error de generación", "persons_short": "com.", "use_ingredient_title": "Usar ingrediente", "recipe_qty_label": "Receta", "from_where_label": "¿De dónde?", "amount_label": "Cuánto", "use_amount_btn": "Usar esta cantidad", "use_all_btn": "Usar TODO / Terminado", "packs_label": "Paquetes", "quantity_in_total": "Cantidad en {unit} (total: {total})", "packs_of_have": "Paquetes de {size} (tienes {count} paquetes)", "scale_wait_stable": "Espera 10s de peso estable para el relleno automático…", "ingredient_scaled_toast": "📦 ¡Ingrediente deducido de la despensa!", "finished_added_bring_toast": "🛒 Producto terminado → ¡añadido a Bring!", "load_error": "Error de carga", "favorite": "Añadir a favoritos", "unfavorite": "Quitar de favoritos", "adjust_persons": "Personas" }, "shopping": { "title": "🛒 Lista de la compra", "bring_loading": "Conectando a Bring!...", "bring_not_configured": "Bring! no está configurado. Añade tu email y contraseña en los ajustes.", "tab_to_buy": "🛍️ Por comprar", "tab_forecast": "🧠 Previsión", "total_label": "💰 Total estimado", "section_to_buy": "🛍️ Por comprar", "suggestions_title": "💡 Sugerencias IA", "suggestions_add": "✅ Añadir selección a Bring!", "search_prices": "🔍 Buscar todos los precios", "suggest_btn": "Sugerir qué comprar", "smart_title": "🧠 Predicciones inteligentes", "smart_empty": "No hay predicciones disponibles.
Añade productos a tu despensa para recibir predicciones inteligentes.", "smart_filter_all": "Todo", "smart_filter_critical": "🔴 Urgente", "smart_filter_high": "🟠 Pronto", "smart_filter_medium": "🟡 Planificar", "smart_filter_low": "🟢 Previsión", "smart_add": "🛒 Añadir selección a Bring!", "empty": "¡Lista de la compra vacía!\nUsa el botón de abajo para generar sugerencias.", "already_in_list": "🛒 \"{name}\" ya está en la lista de la compra", "already_in_list_short": "ℹ️ Ya en la lista de la compra", "add_prompt": "¿Quieres añadirlo a la lista de la compra?", "smart_already": "📊 Las predicciones de compra ya predicen {name}", "all_searched": "Todos los productos ya han sido buscados. Usa 🔄 para buscar individualmente.", "search_complete": "Búsqueda completada: {count} productos", "removed_sufficient": "🧹 {removed} producto(s) con stock suficiente eliminado(s) de la lista", "suggest_buy": "🛒 Comprar: {qty} {unit}", "suggest_buy_approx": "🛒 Al menos: {qty} {unit}", "suggest_buy_tip": "Cantidad sugerida basada en tus últimos 14 días de consumo", "suggest_buy_approx_tip": "Estimación mínima basada en el consumo (compra el tamaño de paquete más cercano)", "bring_badge": "🛒 Ya en Bring!", "add_urgent_toast": "🔴 {n} producto(s) urgente(s) añadido(s) automáticamente a Bring!", "migration_done": "✅ {migrated} actualizado(s), {skipped} ya estaban ok", "added_to_bring": "🛒 {n} productos añadidos a Bring!", "added_to_bring_skip": "{n} ya presentes", "all_on_bring": "¡Todos los productos ya estaban en Bring!", "freq_high": "📈 Frecuente", "freq_regular": "📊 Regular", "freq_occasional": "📉 Ocasional", "out_of_stock": "Sin stock", "scan_toast": "📷 Escanear: {name}", "empty_category": "No hay productos en esta categoría", "session_empty": "🛒 Sin productos aún", "urgency_critical": "Urgente", "urgency_high": "Pronto", "urgency_medium": "Planificar", "urgency_low": "Previsión", "urgency_medium_short": "Medio", "urgency_low_short": "Ok", "tag_urgent": "🔴 Urgente", "tag_priority": "⭐ Prioridad", "tag_check": "✅ Comprobar", "smart_already_predicted": "📊 Las predicciones inteligentes ya predicen {name}{urgency}.", "item_removed": "✅ ¡{name} eliminado de la lista!", "urgency_spec_critical": "⚡ Urgente", "urgency_spec_high": "🟠 Pronto", "bring_add_n": "Añadir {n} a Bring!", "bring_add_selected": "Añadir selección a Bring!", "bring_adding": "Añadiendo...", "bring_added_one": "1 producto añadido a Bring!", "bring_added_many": "{n} productos añadidos a Bring!", "bring_skipped": "({n} ya en la lista)", "force_sync": "Forzar sincronización de Bring!", "scan_target_label": "Estás buscando", "scan_target_found": "¡Encontrado! Eliminar de la lista", "bring_add_one": "Añadir 1 producto a Bring!", "bring_add_many": "Añadir {n} productos a Bring!", "syncing": "Sincronizando…", "sync_done": "Sincronización completada", "price_searching": "Buscando...", "search_action": "Buscar", "open_action": "Abrir", "not_found": "No encontrado", "search_price": "Buscar precio", "tap_to_scan": "Toca para escanear", "tag_title": "Etiqueta", "remove_title": "Eliminar", "found_count": "{found}/{total} productos encontrados", "savings_offers": "· 🏷️ Ahorras {amount}€ con ofertas", "searching_progress": "Buscando {current}/{total}...", "remove_error": "Error al eliminar", "btn_fetch_prices": "Buscar precios", "price_total_label": "💰 Total estimado:", "price_loading": "Buscando precios…", "price_not_found": "precio n/d", "suggest_loading": "Analizando...", "suggest_error": "Error al generar sugerencias", "priority_high": "Alta", "priority_medium": "Media", "priority_low": "Baja", "smart_last_update": "Actualizado {time}", "names_already_updated": "Todos los nombres ya están actualizados" }, "ai": { "title": "🤖 Identificación IA", "capture": "📸 Sacar foto", "retake": "🔄 Repetir", "hint": "Saca una foto del producto y la IA intentará identificarlo", "identifying": "🤖 Identificando producto...", "no_api_key": "⚠️ Clave API de Gemini no configurada.\nAñade GEMINI_API_KEY al archivo .env en el servidor.", "fields_filled": "✅ Campos rellenados por IA", "use_data": "✅ Usar datos de IA", "use_data_no_barcode": "✅ Usar datos de IA (sin código de barras)" }, "log": { "title": "📒 Registro de operaciones", "type_added": "Añadido", "type_waste": "Desechado", "type_used": "Usado", "type_bring": "Añadido a Bring!", "undone_badge": "Deshecho", "undo_title": "Deshacer esta operación", "load_error": "Error al cargar el registro", "empty": "No hay operaciones registradas.", "undo_action_remove": "eliminación de", "undo_action_restore": "reabastecimiento de", "undo_confirm": "¿Deshacer esta operación?\n→ {action} {name}", "undo_success": "↩ Operación deshecha para {name}", "already_undone": "Operación ya deshecha", "too_old": "No se pueden deshacer operaciones de más de 24 horas", "undo_error": "Error al deshacer", "recipe_prefix": "Receta" }, "chat": { "title": "Chef Gemini", "welcome": "¡Hola! Soy tu asistente de cocina", "welcome_desc": "¡Pídeme que te prepare un zumo, un snack, un plato rápido… Conozco tu despensa, tus electrodomésticos y tus preferencias!", "suggestion_snack": "🍿 Snack rápido", "suggestion_juice": "🥤 Zumo/Batido", "suggestion_light": "🥗 Algo ligero", "suggestion_expiry": "⏰ Usar productos que caducan", "clear": "Nueva conversación", "placeholder": "Pregunta algo...", "cleared": "Chat borrado", "suggestion_snack_text": "¿Qué puedo preparar como snack rápido?", "suggestion_juice_text": "Hazme un zumo o batido con lo que tengo", "suggestion_light_text": "Tengo hambre pero quiero algo ligero", "suggestion_expiry_text": "¿Qué está a punto de caducar y cómo puedo usarlo?", "transfer_to_recipes": "Transferir a recetas", "transferring": "Transfiriendo...", "transferred": "¡Añadido a recetas!", "open_recipe": "Abrir receta", "quick_recipe_prompt": "¡Sugiere una receta rápida PARA UNA PERSONA usando los productos que caducan primero! Ignora el congelador, céntrate en la nevera y la despensa." }, "cooking": { "close": "Cerrar", "tts_btn": "Leer en voz alta", "restart": "↺ Reiniciar", "replay": "🔊 Repetir", "timer": "⏱️ {time} · Temporizador", "prev": "◀ Anterior", "next": "Siguiente ▶", "ingredient_used": "✔️ Deducido", "ingredient_use_btn": "📦 Usar", "ingredient_deduct_title": "Deducir de la despensa", "timer_expired_tts": "¡Temporizador {label} finalizado!", "timer_warning_tts": "¡Atención! {label}: ¡10 segundos restantes!", "recipe_done_tts": "¡Receta completada! ¡Buen provecho!", "expires_chip": "cad. {date}", "finish": "✅ Finalizar", "step_fallback": "Paso {n}", "zerowaste_label": "♻️ Desperdicio", "zerowaste_tip_title": "Consejo sin desperdicios" }, "settings": { "title": "⚙️ Ajustes", "tab_api": "Claves API", "tab_bring": "Bring!", "tab_recipe": "Recetas", "tab_mealplan": "Plan semanal", "tab_appliances": "Electrodomésticos", "tab_spesa": "Compra online", "tab_camera": "Cámara", "tab_security": "Seguridad", "tab_tts": "Voz (TTS)", "tab_language": "Idioma", "tab_scale": "Báscula inteligente", "gemini": { "title": "🤖 Google Gemini IA", "hint": "Clave API para identificación de productos, fechas de caducidad y recetas.", "key_label": "Clave API Gemini" }, "bring": { "title": "🛒 Lista de la compra Bring!", "hint": "Credenciales para la integración con la lista de la compra Bring!", "email_label": "📧 Email Bring!", "password_label": "🔒 Contraseña Bring!" }, "price": { "title": "💰 Estimación de precios (IA)", "hint": "Mostrar el coste estimado por producto en la lista de la compra usando IA.", "enabled_label": "Activar estimación de precios", "country_label": "🌍 País de referencia", "currency_label": "💱 Moneda", "update_label": "🔄 Actualizar precios cada", "update_suffix": "meses" }, "recipe": { "title": "🍳 Preferencias de recetas", "hint": "Configura las opciones predeterminadas para la generación de recetas.", "persons_label": "👥 Raciones por defecto", "options_label": "🎯 Opciones de receta por defecto", "fast": "⚡ Comida rápida", "light": "🥗 Comida ligera", "expiry": "⏰ Prioridad caducidad", "healthy": "💚 Extra saludable", "opened": "📦 Prioridad productos abiertos", "zerowaste": "♻️ Cero desperdicio", "dietary_label": "🚫 Intolerancias / Restricciones", "dietary_placeholder": "Ej.: sin gluten, sin lactosa, vegetariano..." }, "mealplan": { "title": "📅 Plan de comidas semanal", "hint": "Establece el tipo de comida para cada día. Se usará como guía en la generación de recetas.", "enabled": "✅ Activar plan semanal", "legend": "🌤️ = Almuerzo  ·  🌙 = Cena  ·  Toca un badge para cambiarlo.", "types_title": "📋 Tipos disponibles", "reset_btn": "↺ Restaurar valores por defecto" }, "appliances": { "title": "🔌 Electrodomésticos disponibles", "hint": "Indica los electrodomésticos que tienes. Se tendrán en cuenta en la generación de recetas.", "new_placeholder": "Ej.: Panificadora, Thermomix, Freidora de aire...", "quick_title": "Añadir rápido:", "oven": "🔥 Horno", "microwave": "📡 Microondas", "air_fryer": "🍟 Freidora de aire", "bread_maker": "🍞 Panificadora", "bimby": "🤖 Thermomix/Cookeo", "mixer": "🌀 Robot de cocina", "steamer": "♨️ Vaporera", "pressure_cooker": "🫕 Olla a presión", "toaster": "🍞 Tostadora", "blender": "🍹 Batidora", "empty": "No hay electrodomésticos añadidos" }, "spesa": { "title": "🛍️ Compra online", "hint": "Configura el proveedor de compra online.", "provider_label": "🏪 Proveedor", "email_label": "📧 Email", "password_label": "🔒 Contraseña", "login_btn": "🔐 Iniciar sesión", "ai_prompt_label": "🤖 Prompt IA de selección de producto", "ai_prompt_placeholder": "Instrucciones para la IA al elegir entre varios productos...", "ai_prompt_hint": "La IA usa este prompt para elegir el producto más apropiado de los resultados. Deja vacío para el comportamiento por defecto.", "configure_first": "Configura primero la compra online en ajustes", "missing_credentials": "Introduce email y contraseña", "login_in_progress": "Iniciando sesión...", "login_error_prefix": "Error:", "login_network_error_prefix": "Error de red:", "login_success_default": "¡Inicio de sesión exitoso!", "result_name_label": "Nombre", "result_card_label": "Tarjeta", "result_pickup_label": "Punto de recogida", "result_points_label": "Puntos de fidelidad", "connected_relogin": "✅ Conectado — Iniciar sesión de nuevo", "connected_as": "Conectado como {name}" }, "camera": { "title": "📷 Cámara", "hint": "Elige qué cámara usar para el escaneo de códigos de barras e identificación IA.", "device_label": "📸 Cámara por defecto", "back": "📱 Trasera (por defecto)", "front": "🤳 Frontal", "devices_hint": "Si tienes varias cámaras, puedes seleccionar una específica de la lista de arriba tras conceder los permisos.", "detect_btn": "🔄 Detectar cámaras", "ai_fallback_label": "Identificación visual IA (repuesto 5s)", "ai_fallback_hint": "Si no se lee ningún código de barras en 5 segundos, se envía automáticamente un fotograma a la IA para identificar el producto visualmente. Requiere Gemini configurado." }, "security": { "title": "🔒 Certificado HTTPS", "hint": "Si el navegador muestra el error «Tu conexión no es privada» (ERR_CERT_AUTHORITY_INVALID), necesitas instalar el certificado CA en el dispositivo.", "download_btn": "📥 Descargar certificado CA", "token_title": "🔑 Token de ajustes", "token_label": "Token de acceso", "token_hint": "Si `SETTINGS_TOKEN` está configurado en el `.env` del servidor, introduce el token aquí antes de guardar los ajustes. Deja vacío si no está configurado.", "token_placeholder": "(vacío = sin protección)", "token_required_hint": "🔒 Este servidor requiere un token para guardar los ajustes.", "cert_instructions": "Instrucciones para Chrome (Android):
1. Descarga el certificado de arriba
2. Ve a Ajustes → Seguridad y privacidad → Más ajustes de seguridad → Instalar desde almacenamiento
3. Selecciona el archivo EverShelf_CA.crt descargado
4. Elige «CA» y confirma
5. Reinicia Chrome

Instrucciones para Chrome (PC):
1. Descarga el certificado de arriba
2. Ve a chrome://settings/certificates
3. Pestaña «Autoridades» → Importar → selecciona el archivo
4. Marca «Confiar en este certificado para identificar sitios web»
5. Reinicia Chrome" }, "tts": { "title": "🔊 Voz & TTS", "hint": "Configura la síntesis de voz mediante cualquier API REST externa. Los pasos de la receta y los temporizadores expirados se enviarán al endpoint configurado.", "enabled": "✅ Activar TTS", "engine_label": "⚙️ Motor TTS", "engine_browser": "🔇 Navegador (sin conexión, sin configuración requerida)", "engine_server": "🌐 Servidor externo (Home Assistant, API REST...)", "voice_label": "🗣️ Voz", "rate_label": "⚡ Velocidad", "pitch_label": "🎵 Tono", "url_label": "🌐 URL del endpoint", "method_label": "📡 Método HTTP", "auth_label": "🔐 Autenticación", "auth_bearer": "Bearer Token", "auth_custom": "Cabecera personalizada", "auth_none": "Ninguna", "token_label": "🔑 Bearer Token", "custom_header_name": "📋 Nombre de cabecera", "custom_header_value": "📋 Valor de cabecera", "content_type_label": "📄 Content-Type", "payload_key_label": "🗝️ Campo de texto en el payload", "payload_key_hint": "Nombre del campo JSON que contendrá el texto a leer (ej.: message, text).", "extra_fields_label": "➕ Campos adicionales (JSON)", "extra_fields_placeholder": "{\"entity_id\": \"media_player.salon\"}", "extra_fields_hint": "Campos adicionales a incluir en el payload, en formato JSON. Deja vacío si no es necesario.", "test_btn": "🔊 Enviar voz de prueba", "voices_loading": "Cargando voces…", "voice_not_supported": "Voz no compatible con este navegador", "voices_none": "No hay voces disponibles en este dispositivo", "voices_hint": "Las voces disponibles dependen del SO y el navegador. Pulsa ↺ si la lista no carga.", "url_missing": "⚠️ URL del endpoint faltante.", "test_sending": "⏳ Enviando…", "test_ok": "✅ Respuesta {code} — comprueba que el altavoz haya hablado.", "heard_question": "¿Has escuchado la voz?", "heard_yes": "Sí, la escuché", "heard_no": "No, no escuché nada", "test_ok_kiosk": "TTS funcionando.", "test_fail_steps": "Comprueba: 1) el volumen del multimedia no es 0; 2) Google Text-to-Speech está instalado y actualizado; 3) el paquete de voz español está descargado en la configuración TTS de Android." }, "language": { "title": "🌐 Idioma", "hint": "Selecciona el idioma de la interfaz.", "label": "🌐 Idioma", "restart_notice": "La página se recargará para aplicar el nuevo idioma." }, "screensaver": { "label": "Activar protector de pantalla", "card_title": "🌙 Protector de pantalla", "card_hint": "Muestra un reloj con información útil después de 5 minutos de inactividad. Desactivado por defecto.", "timeout_1": "1 minuto", "timeout_2": "2 minutos", "timeout_5": "5 minutos", "timeout_10": "10 minutos", "timeout_15": "15 minutos", "timeout_30": "30 minutos", "timeout_60": "1 hora", "start_after": "⏱️ Iniciar tras" }, "scale": { "title": "⚖️ Báscula inteligente", "hint": "Conecta una báscula Bluetooth mediante la pasarela Android para leer el peso automáticamente.", "tab": "Báscula inteligente", "enabled": "✅ Activar báscula inteligente", "url_label": "🌐 URL de la pasarela WebSocket", "url_placeholder": "ws://192.168.1.x:8765", "url_hint": "URL mostrada por la app Android (misma red Wi-Fi). Ej.:", "test_btn": "🔗 Probar conexión", "download_btn": "📥 Descargar pasarela Android (APK)", "download_hint": "App Android que conecta tu báscula BLE con EverShelf.", "download_sub": "Fuente: evershelf-scale-gateway/ en la raíz del proyecto", "live_weight": "peso en tiempo real", "auto_reconnect": "🔁 Reconexión: automática", "kiosk_title": "📡 Báscula BLE integrada en el kiosco", "kiosk_hint": "La báscula está gestionada directamente por la pasarela BLE interna del kiosco. Para vincular un nuevo dispositivo, usa el asistente de configuración.", "kiosk_reconfigure": "🔄 Reconfigurar báscula BLE", "ble_protocols": "

🔌 Protocolos BLE soportados:

" }, "kiosk": { "hint": "Convierte una tableta Android en un panel EverShelf permanente con pasarela BLE integrada.", "download_btn": "📥 Descargar EverShelf Kiosk (APK)", "download_sub": "Modo kiosco a pantalla completa + pasarela de báscula integrada. Fuente: evershelf-kiosk/", "native_title": "Configuración del kiosco", "native_hint": "URL del servidor, báscula BLE, protector de pantalla y asistente de configuración.", "native_btn": "Abrir configuración del kiosco", "native_tap_hint": "Toca el botón de engranaje en la parte superior derecha", "native_update_hint": "Actualiza la app del kiosco para usar esta función", "update_title": "Actualización del kiosco", "check_updates_btn": "🔍 Buscar actualizaciones", "needs_update": "⚠️ El kiosco instalado no admite esta función. Actualiza la app del kiosco para activarla." }, "saved": "✅ ¡Configuración guardada!", "saved_local": "✅ Configuración guardada localmente", "saved_local_error": "⚠️ Guardado localmente, error del servidor: {error}", "theme": { "title": "🌙 Apariencia", "hint": "Elige el tema de la interfaz.", "label": "🌙 Tema", "off": "☀️ Claro", "on": "🌙 Oscuro", "auto": "🔄 Automático (sistema)" }, "zerowaste": { "card_title": "♻️ Consejos sin desperdicios", "card_hint": "Durante la cocción, muestra consejos sobre cómo reutilizar los restos generados en cada paso (peladuras, agua de cocción, etc.). Desactivado por defecto.", "label": "Mostrar consejos durante la cocción" }, "backup": { "tab": "Copia de seguridad", "local_title": "Copia local", "local_hint": "Instantánea diaria de la base de datos. Configura cuántos días de copias de seguridad conservar.", "enabled": "Activar copia de seguridad diaria automática", "retention_days": "Retención (días)", "retention_info": "Las copias se conservan durante", "backup_now": "Hacer copia ahora", "backing_up": "Haciendo copia…", "backed_up": "Copia completada", "backup_error": "Error en la copia", "last_backup": "Última copia", "no_backup_yet": "Aún no se ha creado ninguna copia", "list_empty": "No hay copias disponibles", "restore_btn": "Restaurar", "restore_confirm": "Restaurar la copia", "delete_btn": "Eliminar", "delete_confirm": "Eliminar la copia", "gdrive_title": "Google Drive", "gdrive_hint": "Copias de seguridad automáticas en Google Drive via OAuth 2.0. No se requieren bibliotecas externas.", "gdrive_enabled": "Activar copia en Google Drive", "gdrive_folder_id": "ID de carpeta de Drive", "gdrive_folder_id_hint": "Copia el ID desde la URL de la carpeta de Drive: …/folders/ID", "gdrive_retention_days": "Retención en Drive (días, 0=mantener todo)", "gdrive_test": "Probar conexión", "gdrive_ok": "Conexión exitosa!", "gdrive_error": "Conexión fallida", "gdrive_push_now": "Subir a Drive ahora", "gdrive_pushing": "Subiendo…", "gdrive_pushed": "Subido a Drive", "gdrive_wizard_hint": "Opcional: copia de seguridad diaria automática en Google Drive via OAuth 2.0.", "gdrive_skip": "Omitir — configurar después en Ajustes", "gdrive_client_id": "Client ID", "gdrive_client_secret": "Client Secret", "gdrive_redirect_uri_hint": "Agrega http://localhost como URI de redireccionamiento autorizado en Google Cloud Console. Funciona en cualquier servidor, incluso sin dominio público.", "gdrive_code_title": "Pegar la URL o el código de autorización", "gdrive_code_hint": "Tras autorizar, el navegador abrirá http://localhost y puede mostrar un error de conexión — es normal. Copia la URL de la barra de direcciones (ej. http://localhost/?code=4%2F0A...) y pégala aquí.", "gdrive_code_submit": "Confirmar", "gdrive_code_empty": "Pega primero la URL o el código de autorización", "gdrive_redirect_uri_label": "URI de redirección (agregar en Google Cloud Console):", "gdrive_oauth_authorize": "Autorizar con Google", "gdrive_oauth_authorized": "Autorizado", "gdrive_oauth_not_authorized": "Aún no autorizado", "gdrive_oauth_window_opened": "Ventana abierta — autoriza y regresa aquí", "gdrive_oauth_how_to": "Cómo configurar OAuth 2.0 (paso a paso)", "gdrive_oauth_steps": "
  • Ve a console.cloud.google.com y selecciona tu proyecto
  • Habilita la API de Google Drive: API y servicios → Habilitar API → Google Drive API
  • Ve a API y servicios → Credenciales → Crear credenciales → ID de cliente OAuth
  • Tipo de aplicación: Aplicación web; agrega la URL mostrada abajo como URI de redirección autorizado
  • Copia el Client ID y el Client Secret en los campos de arriba y guarda
  • Haz clic en Autorizar con Google: inicia sesión en tu cuenta de Google y concede acceso
  • La ventana se cierra automáticamente al finalizar y las copias de seguridad están listas
  • " }, "shopping": { "tab": "Lista de la compra", "title": "Lista de la compra", "hint": "Configura la lista de la compra integrada o conecta Bring!.", "enable_label": "Activar lista de la compra", "mode_label": "Proveedor", "mode_internal": "Integrado (sin Bring!)", "mode_bring": "Bring! (app externa)", "bring_section_title": "Configuración de Bring!", "ai_section_title": "Asistencia IA", "smart_suggestions_label": "Sugerencias IA", "forecast_label": "Previsión de productos por agotar", "auto_add_label": "Añadir automáticamente cuando", "auto_add_suffix": "restante en stock (0 = solo cuando se agota)" }, "ha": { "tab": "Home Assistant", "title": "Home Assistant", "hint": "Conecta EverShelf a Home Assistant para automatizaciones, notificaciones push y sensores REST.", "enabled": "Activar integración con Home Assistant", "connection_title": "Conexión", "url_label": "URL de Home Assistant", "url_placeholder": "http://192.168.1.50:8123", "url_hint": "URL base de tu instancia de Home Assistant.", "token_label": "Token de acceso de larga duración", "token_hint": "Genera desde Perfil HA → Seguridad → Tokens de acceso de larga duración.", "token_placeholder": "eyJhbGci...", "token_saved": "Token guardado (oculto por seguridad)", "test_btn": "Probar conexión", "test_ok": "Conectado a {version}", "test_fail": "Conexión fallida: {error}", "test_bad_token": "HA accesible pero el token no es válido", "testing": "Probando…", "error_no_url": "Por favor, introduce primero la URL de Home Assistant.", "tts_title": "TTS en altavoz inteligente", "tts_hint": "Lee los pasos de la receta en un reproductor de medios de Home Assistant.", "tts_entity_label": "Entity ID del reproductor multimedia", "tts_entity_placeholder": "media_player.salon", "tts_entity_hint": "ID de entidad del reproductor multimedia HA. Encuéntralo en HA: Herramientas para desarrolladores → Estados.", "tts_platform_label": "Plataforma TTS", "tts_platform_speak": "tts.speak (recomendado)", "tts_platform_notify": "notify.* (servicio de notificaciones)", "tts_apply_btn": "Aplicar preset HA a la pestaña TTS", "tts_apply_hint": "Pre-rellena la pestaña TTS con la URL y el token de Home Assistant.", "tts_preset_applied": "Preset HA aplicado a la pestaña TTS.", "webhook_title": "Automatizaciones Webhook", "webhook_hint": "Envía datos a Home Assistant cuando ocurren eventos en la despensa.", "webhook_id_label": "ID de Webhook", "webhook_id_placeholder": "evershelf_webhook_abc123", "webhook_id_hint": "ID del webhook creado en HA. Copia desde: HA → Ajustes → Automatizaciones → Crear → Disparador Webhook.", "webhook_events_label": "Notificar en estos eventos", "event_expiry": "Productos próximos a caducar (diario)", "event_shopping": "Artículo añadido a la lista de compras", "event_stock": "Nivel de stock actualizado", "expiry_days_label": "Antelación de caducidad (días)", "expiry_days_hint": "Enviar alerta de caducidad N días antes de la fecha.", "webhook_help": "En HA: Ajustes → Automatizaciones → Crear automatización → Disparador: Webhook → copia el ID generado.", "notify_title": "Notificaciones push", "notify_hint": "Envía notificaciones push a tu teléfono mediante un servicio notify de Home Assistant.", "notify_service_label": "Servicio notify", "notify_service_placeholder": "notify.mobile_app_mi_telefono", "notify_service_hint": "Nombre del servicio notify de HA. Déjalo vacío para desactivar.", "sensor_title": "Sensores REST", "sensor_hint": "Añade a configuration.yaml para crear sensores de EverShelf en Home Assistant.", "sensor_copy_btn": "Copiar YAML", "sensor_copied": "¡YAML copiado al portapapeles!", "save_btn": "Guardar ajustes HA", "ha_hint": "Si usas Home Assistant, utiliza la pestaña Home Assistant para configurar TTS, webhooks y sensores." } }, "expiry": { "today": "HOY", "tomorrow": "Mañana", "days": "{days} días", "expired_days": "hace {days}d", "expired_yesterday": "Ayer", "expired_today": "Hoy", "badge_today": "⚠️ ¡Caduca hoy!", "badge_tomorrow": "⏰ Mañana", "badge_tomorrow_long": "⏰ Caduca mañana", "badge_days": "⏰ {n} días", "badge_expired_ago": "⚠️ Caducado hace {n}d", "badge_expired": "⛔ ¡Caducado!", "badge_stable": "✅ Estable", "badge_expiring_short": "⏰ Cad. en {n}d", "badge_ok_still": "✅ Aún {n}d", "badge_expires_red": "🔴 Cad. en {n}d", "badge_expires_yellow": "🟡 Cad. en {n}d", "badge_expired_bare": "⚠️ Caducado", "badge_expires_warn": "⚠️ Cad. en {n}d", "badge_days_left": "⏳ ~{n}d restantes", "days_approx": "~{n} días", "weeks_approx": "~{n} semanas", "months_approx": "~{n} meses", "years_approx": "~{n} años", "expired_today_long": "Caducado hoy", "expired_ago_long": "Caducado hace {n} días", "expired_suffix": "— ¡Caducado!", "expired_suffix_ok": "— Caducado (aún ok)", "expired_suffix_warning": "— Caducado (comprobar primero)", "opened_ago_long": "Abierto hace {n} días", "opened_today_long": "Abierto hoy", "opened_suffix": "— ¡Abierto demasiado tiempo!", "opened_suffix_ok": "— Abierto (aún ok)", "opened_suffix_warning": "— Abierto (comprobar primero)", "days_compact": "{n}d", "badge_check_soon": "Comprobar pronto" }, "status": { "ok": "OK", "check": "Comprobar", "discard": "Desechar", "tip_freezer_ok": "En congelador: aún seguro (~{n}d de margen)", "tip_freezer_check": "En el congelador mucho tiempo, puede haber perdido calidad. Consumir pronto", "tip_freezer_danger": "En el congelador demasiado tiempo, riesgo de quemadura por congelación y degradación", "tip_highRisk_check": "Caducado recientemente, comprueba el olor y el aspecto antes de consumir", "tip_highRisk_danger": "Producto perecedero caducado: desechar por seguridad", "tip_medRisk_check1": "Comprueba el aspecto y el olor antes de consumir", "tip_medRisk_check2": "Caducado hace tiempo, comprueba cuidadosamente antes de usar", "tip_medRisk_danger": "Demasiado tiempo desde la caducidad, mejor desechar", "tip_lowRisk_ok": "Producto de larga duración, aún seguro para consumir", "tip_lowRisk_check": "Caducado hace más de un mes, comprueba la integridad del envase", "tip_lowRisk_danger": "Caducado hace demasiado tiempo, mejor no arriesgarse" }, "toast": { "product_saved": "¡Producto guardado!", "product_created": "¡Producto creado!", "product_updated": "✅ ¡Producto actualizado!", "product_removed": "Producto eliminado", "updated": "¡Actualizado!", "quantity_confirmed": "✓ Cantidad confirmada", "added_to_inventory": "✅ ¡{name} añadido!", "removed_from_list": "✅ ¡{name} eliminado de la lista!", "removed_from_list_short": "Eliminado de la lista", "added_to_shopping": "🛒 ¡Añadido a la lista de la compra!", "removed_from_shopping": "🛒 Eliminado de la lista de la compra", "finished_to_bring": "🛒 Producto terminado → ¡añadido a Bring!", "thrown_away": "🗑️ ¡{name} tirado!", "thrown_away_partial": "🗑️ {qty} {unit} de {name} tirado(s)", "finished_all": "📤 ¡{name} terminado!", "product_finished_confirmed": "✅ Eliminado — añádelo de nuevo cuando reabastezcas", "appliance_added": "Electrodoméstico añadido", "item_added": "{name} añadido" }, "antiwaste": { "title": "🌱 Informe anti-desperdicio", "grade_label": "Nota", "you": "Tú", "avg_label": "Media", "better": "🎉 ¡Desperdicias un {diff}% menos que la media {country}!", "worse": "⚠️ Desperdicias más que la media {country}. ¡Hay margen de mejora!", "on_par": "→ Estás en la media {country}. ¡Puedes hacerlo mejor!", "saved_money": "~{amount}/mes ahorrado", "saved_meals": "~{n} comidas salvadas", "saved_co2": "{n} kg CO₂ evitados", "trend_title": "Tendencia (últimos 3 meses)", "months_ago_2": "-60 días", "months_ago_1": "-30 días", "this_month": "Ahora", "country_it": "Media italiana", "country_de": "Media alemana", "country_en": "Media estadounidense", "source": "Fuentes: REDUCE, Eurostat, USDA 2021", "live_on": "Datos en vivo", "live_off": "Sin conexión", "meals": "comidas", "annual_info": "📅 Tú ~{you} kg/año · media ~{avg} kg/año", "badge_rate": "tasa de pérdida", "badge_saved_money": "ahorrado vs media", "badge_wasted": "artículos perdidos", "badge_better": "menos que la media" }, "error": { "generic": "Error", "network": "Error de red", "no_api_key": "Configura la clave API en los ajustes", "loading": "Error al cargar el producto", "not_found": "Producto no encontrado", "not_found_manual": "Producto no encontrado. Introdúcelo manualmente.", "search": "Error de búsqueda. Inténtalo de nuevo.", "search_short": "Error de búsqueda", "save": "Error al guardar", "connection": "Error de conexión", "camera": "No se puede acceder a la cámara", "bring_add": "Error al añadir a Bring!", "bring_connection": "Error de conexión con Bring!", "identification": "Error de identificación", "ai_quota": "Cuota de IA agotada. Inténtalo de nuevo en unos minutos.", "barcode_empty": "Introduce un código de barras", "barcode_format": "El código de barras solo puede contener números (4-14 dígitos)", "barcode_checksum": "Suma de comprobación EAN inválida — verifica los dígitos del código", "min_chars": "Escribe al menos 2 caracteres", "not_in_inventory": "Producto no en inventario", "appliance_exists": "El electrodoméstico ya existe", "already_exists": "Ya existe", "network_retry": "Error de conexión. Inténtalo de nuevo.", "select_items": "Selecciona al menos un producto", "server_offline": "Conexión con el servidor perdida", "server_restored": "Conexión con el servidor restaurada", "server_retry": "Reintentar", "unknown": "Error desconocido", "prefix": "Error", "no_inventory_entry": "No se encontró ninguna entrada de inventario", "offline_title": "Sin conexión", "offline_subtitle": "La app no puede conectar con el servidor. Verifica tu conexión Wi-Fi.", "offline_checking": "Verificando conexión…", "offline_restored": "¡Conexión restaurada!", "offline_continue": "Continuar en modo sin conexión", "offline_reading_cache": "Leyendo desde caché local", "offline_ops_pending": "{n} operaciones pendientes", "offline_synced": "{n} operaciones sincronizadas", "offline_ai_disabled": "No disponible sin conexión", "offline_cache_ready": "Offline — {n} productos en caché" }, "confirm_placeholder_search": null, "confirm": { "remove_item": "¿Realmente quieres eliminar este producto del inventario?", "kiosk_exit": "¿Salir del modo kiosco?", "cancel": "Cancelar", "proceed": "Confirmar", "discard_one": "Tirar 1 unidad" }, "location": { "dispensa": "Despensa", "frigo": "Nevera", "freezer": "Congelador" }, "edit": { "title": "Editar {name}", "unknown_hint": "Introduce el nombre del producto y la información", "label_name": "🏷️ Nombre del producto", "choose_location_title": "¿Qué ubicación?", "choose_location_hint": "Elige la ubicación a editar:", "confirm_large_qty": "Estás configurando la cantidad a {qty} {unit}. Esto parece inusualmente alto. ¿Confirmar?" }, "screensaver": { "recipe_btn": "Recetas", "scan_btn": "Escanear producto" }, "days": { "mon": "Lunes", "tue": "Martes", "wed": "Miércoles", "thu": "Jueves", "fri": "Viernes", "sat": "Sábado", "sun": "Domingo", "mon_short": "Lun", "tue_short": "Mar", "wed_short": "Mié", "thu_short": "Jue", "fri_short": "Vie", "sat_short": "Sáb", "sun_short": "Dom" }, "meal_types": { "lunch": "Almuerzo", "dinner": "Cena", "colazione": "Desayuno", "merenda": "Merienda", "dolce": "Postre", "succo": "Zumo de fruta", "pranzo": "Almuerzo", "cena": "Cena" }, "scale": { "status_connected": "Báscula conectada", "status_searching": "Pasarela conectada, esperando báscula…", "status_disconnected": "Pasarela de báscula inaccesible", "status_error": "Error de conexión con la pasarela", "not_connected": "Pasarela de báscula no conectada", "read_btn": "⚖️ Leer desde báscula", "reading_title": "Lectura de báscula", "place_on_scale": "Coloca el producto en la báscula…", "waiting_stable": "El peso se capturará automáticamente cuando la lectura sea estable.", "no_url": "Introduce la URL de la pasarela", "testing": "⏳ Probando conexión…", "connected_ok": "¡Conexión con la pasarela exitosa!", "timeout": "Tiempo de espera agotado: sin respuesta de la pasarela", "error_connect": "No se puede conectar a la pasarela", "tab": "Báscula inteligente", "low_weight": "Peso < 10 g · introduce manualmente\n(la lectura automática requiere al menos 10 g)", "density_hint": "(densidad {density} g/ml)", "ml_hint": "(se convertirá a ml)", "weight_detected": "Peso detectado — espera 10s de estabilidad…", "weight_too_low": "Peso demasiado bajo — esperando…", "stable": "✓ Estable", "auto_confirm": "✅ {val} {unit} — confirmación automática en 5s (toca para cancelar)", "cancelled_replace": "Cancelado — vuelve a colocar el ingrediente en la báscula para continuar" }, "prediction": { "expected_qty": "Esperado: {expected} {unit}", "actual_qty": "Actual: {actual} {unit}", "check_suggestion": "Comprueba o pesa la cantidad restante" }, "date": { "today": "📅 Hoy", "yesterday": "📅 Ayer" }, "scanner": { "title_barcode": "🔖 Escanear código de barras", "barcode_hint": "Encuadra el código de barras del producto", "barcode_manual_placeholder": "O introduce manualmente...", "barcode_use_btn": "✅ Usar este código", "ai_identifying": "🤖 Identificando producto...", "ai_analyzing": "🤖 Análisis IA en curso...", "product_label_hint": "Encuadra la etiqueta del producto", "expiry_label_hint": "Encuadra la fecha de caducidad impresa en el producto", "capture_btn": "📸 Capturar", "capture_photo_btn": "📸 Sacar foto", "retake_btn": "🔄 Repetir", "camera_error_hint": "Asegúrate de usar HTTPS y haber concedido los permisos de cámara.
    Puedes introducir el código de barras manualmente o usar la identificación IA.", "no_barcode": "Sin código de barras", "save_new_btn": "🆕 Ninguno de estos — guardar como nuevo" }, "lowstock": { "title": "⚠️ ¡Stock bajo!", "message": "{name} se está agotando — solo quedan {qty}.", "question": "¿Quieres añadirlo a la lista de la compra?", "yes": "🛒 Sí, añadir a Bring!", "no": "No, por ahora estoy bien" }, "move": { "title": "📦 ¿Mover el resto?", "question": "¿Quieres mover {thing} de {name} a otra ubicación?", "question_short": "¿Quieres mover {thing} a otra ubicación?", "thing_opened": "el paquete abierto", "thing_rest": "el resto", "stay_btn": "No, quedarse en {location}", "moved_toast": "📦 Paquete abierto movido a {location}", "vacuum_restore": "🫙 Restaurar al vacío", "vacuum_seal_rest": "🔒 Sellar el resto al vacío" }, "nova": { "1": "Sin procesar", "2": "Ingrediente culinario", "3": "Procesado", "4": "Ultraprocesado" }, "meal_plan_types": { "pasta": "Pasta", "riso": "Arroz", "carne": "Carne", "pesce": "Pescado", "legumi": "Legumbres", "uova": "Huevos", "formaggio": "Queso", "pizza": "Pizza", "affettati": "Fiambres", "verdure": "Verduras", "zuppa": "Sopa", "insalata": "Ensalada", "pane": "Pan/Bocadillo", "dolce": "Postre", "libero": "Libre" }, "meal_sub": { "dolce_torta": "Tarta", "dolce_crema": "Crema / Pudín", "dolce_crumble": "Crumble / Tarta", "dolce_biscotti": "Galletas / Pastelería", "dolce_frutta": "Postre de fruta", "succo_dolce": "Dulce / Afrutado", "succo_energizzante": "Energizante", "succo_detox": "Detox / Verde", "succo_rinfrescante": "Refrescante", "succo_vitaminico": "Vitamínico / Cítricos" }, "meal_plan": { "reset_success": "Plan semanal restablecido", "not_available": "no disponible en la despensa", "suggested_by": "sugerido por el plan semanal" }, "nutrition": { "title": "🥗 Análisis alimentario", "score_excellent": "😄 Excelente", "score_good": "🙂 Bien", "score_improve": "😬 Mejorable", "label_health": "🌿 Salud", "label_variety": "🎨 Variedad", "label_fresh": "❄️ Fresco", "source": "Basado en {n} productos en tu despensa · EverShelf", "products_count": "productos", "today_title": "🥗 Tu despensa hoy", "products_n": "{n} productos", "macros_title": "Macronutrientes estimados", "macros_proteins": "Proteínas", "macros_carbs": "Carbohidratos", "macros_fat": "Grasas", "macros_fiber": "Fibra", "macros_source": "Estimación basada en {n} productos en despensa" }, "facts": { "greeting_morning": "Buenos días", "greeting_afternoon": "Buenas tardes", "greeting_evening": "Buenas noches", "pantry_waiting": "¡{greeting}! Tu despensa te espera.", "expired_one": "Tienes 1 producto caducado en tu despensa. ¡Compruébalo!", "expired_many": "Tienes {n} productos caducados en tu despensa. ¡Compruébalos!", "expired_list": "Productos caducados: {names}", "expired_list_more": "y {n} más", "freezer_expired_ok": "{name} está caducado, pero al estar en el congelador puede estar bien. ¡Compruébalo!", "freezer_expired_old": "{name} en el congelador lleva demasiado tiempo caducado. Mejor tirarlo.", "fridge_expired_one": "¡Tienes 1 producto caducado en la nevera!", "fridge_expired_many": "¡Tienes {n} productos caducados en la nevera!", "expiring_today": "¡{name} caduca hoy! Úsalo enseguida.", "expiring_tomorrow": "{name} caduca mañana. ¡Planifica!", "expiring_days": "{name} caduca en {days} días.", "expiring_many": "Tienes {n} productos que caducan pronto.", "expiring_this_week": "¡{n} productos caducan esta semana. Planifica tus comidas en consecuencia!", "expiring_item_loc": "{name} ({loc}) caduca en {days} {dayslabel}.", "expiring_this_month": "{n} productos caducarán este mes.", "shopping_add": "Añadir a la lista: {names} 🛒", "shopping_more": "y {n} más", "shopping_empty": "¡Lista de la compra vacía. Todo en stock! ✅", "in_fridge": "En la nevera: {name}.", "in_freezer": "En el congelador: {name}. ¡No lo olvides!", "top_category": "La categoría principal es {icon} {cat} con {n} productos.", "cat_meat": "Tienes {n} productos cárnicos. 🥩", "cat_dairy": "Tienes {n} productos lácteos en casa. 🥛", "cat_veggies": "Tienes {n} tipos de verduras. ¡Genial para la salud! 🥬", "cat_fruit": "Tienes {n} tipos de fruta. 🍎", "cat_drinks": "Tienes {n} bebidas disponibles. 🥤", "cat_frozen": "Tienes {n} artículos congelados. ❄️", "cat_pasta": "Tienes {n} tipos de pasta. 🍝 ¿Y si hacemos una carbonara?", "cat_canned": "Tienes {n} conservas en la despensa. 🥫", "cat_snacks": "Tienes {n} snacks. ¡Resiste la tentación! 🍪", "cat_condiments": "Tienes {n} condimentos disponibles. 🧂", "item_random": "¿Sabías que tienes {name} en {loc}?", "item_qty": "{name}: tienes {qty}.", "no_expiry_count": "{n} productos no tienen fecha de caducidad.", "furthest_expiry": "El producto con la fecha de caducidad más lejana es {name}: {months} meses.", "high_qty": "¡Tienes un buen stock de {name}: {qty}!", "low_qty_item": "{name} se está agotando. ¿Añadirlo a tu lista de la compra?", "low_qty_count": "{n} productos están casi agotados.", "morning_bread": "¡Buenos días! Tienes pan para el desayuno. 🍞", "morning_milk": "¿Hay leche en la nevera para un café con leche? ☕🥛", "morning_fruit": "¡Buenos días! Algo de fruta fresca es un gran comienzo. 🍎", "noon_pasta": "Es hora de comer… ¿Y si preparamos un buen plato de pasta? 🍝", "noon_salad": "¿Una ensalada fresca para comer? ¡Tienes {n} verduras! 🥗", "evening_meat": "Para cenar podrías usar la carne que tienes. 🥩", "evening_fish": "¿Qué tal pescado para cenar? 🐟", "evening_expiring": "Tienes {n} productos que caducan esta semana — ¡úsalos esta noche!", "night_reminder": "¡Buenas noches! Recuerda usar mañana: {names}.", "weekly_balance": "Balance semanal: +{in} añadidos, −{out} consumidos.", "weekly_added": "Has añadido {n} productos esta semana.", "weekly_consumed": "Has consumido {n} productos esta semana. ¡Bien hecho!", "tip_freezer": "💡 Los productos congelados duran mucho más que la fecha de caducidad.", "tip_bread": "💡 El pan congelado conserva su frescura durante semanas.", "tip_fifo": "💡 Para evitar desperdicios, usa primero los productos más cercanos a la caducidad (FIFO).", "tip_meat": "💡 La carne en el congelador puede durar hasta 6 meses con seguridad.", "tip_no_refreeze": "💡 Nunca vuelvas a congelar un producto descongelado. ¡Cocínalo enseguida!", "tip_fridge": "💡 Una nevera ordenada te ahorra tiempo y dinero.", "tip_canned": "💡 Las conservas abiertas deben ir a la nevera y consumirse en pocos días.", "top_brand": "La marca más común en tu despensa es {brand} con {n} productos.", "combo_pasta": "Tienes pasta y condimentos: ¡listo para un primer plato! 🍝", "combo_sandwich": "Pan y carne: ¡un sándwich rápido siempre es buena idea! 🥪", "combo_balanced": "Verduras y carne: ¡tienes todo para una comida equilibrada! 🥗🥩", "pantry_empty": "¡La despensa está vacía! Es hora de ir al supermercado. 🛒", "pantry_empty_scan": "No hay productos registrados. ¡Escanea algo para empezar!", "location_distribution": "Distribución: {parts}", "day": "día", "days": "días" }, "kiosk_session": { "first_item": "¡Primer artículo: {name}!", "items_two_four": "{n} artículos — arrancando 🚀", "items_five_nine": "{n} artículos — ¡buen ritmo! 💪", "items_ten_twenty": "{n} artículos — casi un récord 🏆", "items_twenty_plus": "{n} artículos — ¡compra épica! 🛒🔥", "duplicates_one": "1 duplicado (mismo artículo dos veces)", "duplicates_many": "{n} duplicados (cogido varias veces)", "top_category": "Categoría principal: {cat} ({count}×)", "items_fallback": "{n} artículo{plural} añadido{plural}" }, "kiosk": { "check_btn": "🔍 Buscar actualizaciones", "checking": "⏳ Comprobando…", "error_check": "Error durante la comprobación de actualizaciones", "error_start_install": "Error al iniciar la instalación", "version_installed": "Instalado: {v}", "update_available": "⬆️ Nueva versión disponible: {latest} (instalada: {current})", "up_to_date": "✅ Estás actualizado — versión {v}", "too_old": "⚠️ El kiosco instalado es demasiado antiguo para la comprobación automática de actualizaciones.
    Pulsa el botón de abajo para descargar e instalar la nueva versión directamente.", "manual_install": "⚠️ Este kiosco no admite instalación automática.
    Procedimiento manual:
    1. Sal del kiosco (botón ✕ arriba a la izquierda)
    2. Desinstala la app EverShelf Kiosk
    3. Descarga e instala el nuevo APK desde GitHub:", "starting_download": "⏳ Iniciando descarga…", "install_btn": "⬇️ Instalar actualización", "exit_title": "Salir del kiosco", "refresh_title": "Actualizar página" }, "update": { "new_version": "Nueva versión", "btn": "Actualizar" }, "gemini": { "chat_title": "Chat con Gemini", "not_configured": "🤖 Gemini no configurado — establece GEMINI_API_KEY en los ajustes" }, "appliances": { "empty": "No hay electrodomésticos añadidos" }, "about": { "title": "Acerca de", "version": "Versión", "report_bug": "Reportar un error", "report_bug_hint": "¿Algo no funciona? Envíanos un informe directamente desde la app.", "report_bug_modal_title": "Reportar un error", "report_type_bug": "Error", "report_type_feature": "Función", "report_type_question": "Pregunta", "report_field_title": "Título", "report_field_title_ph": "Breve descripción del problema", "report_field_desc": "Descripción", "report_field_desc_ph": "Describe el problema en detalle…", "report_field_steps": "Pasos para reproducir (opcional)", "report_field_steps_ph": "1. Ir a…\n2. Tocar…\n3. Ver el error…", "report_auto_info": "Adjuntado automáticamente: versión {version}, idioma {lang}.", "report_send_btn": "Enviar informe", "report_bug_sending": "Enviando…", "report_bug_sent": "¡Informe enviado — gracias!", "report_bug_error": "No se pudo enviar el informe. Comprueba tu conexión.", "changelog": "Registro de cambios", "github": "Repositorio GitHub" }, "export": { "title": "Exportar inventario", "hint": "Descarga el inventario actual en CSV o abre la versión imprimible (PDF).", "btn_csv": "Descargar CSV", "btn_pdf": "PDF / Imprimir", "btn_title": "Exportar" }, "startup": { "connecting": "Conectando al servidor...", "check_php_memory": "Memoria PHP", "check_php_timeout": "Tiempo de espera PHP", "check_php_upload": "Upload PHP", "check_data_dir": "Carpeta de datos", "check_rate_limits": "Dir. rate limits", "check_backups": "Dir. copias de seguridad", "check_write_test": "Prueba escritura disco", "check_disk_space": "Espacio en disco", "check_db_connect": "Conexión base de datos", "check_db_tables": "Tablas de la BD", "check_db_integrity": "Integridad BD", "check_db_wal": "Modo WAL", "check_db_size": "Tamaño de la BD", "check_db_rows": "Datos del inventario", "check_env": "Archivo .env", "check_gemini": "Clave Gemini AI", "check_bring_creds": "Credenciales Bring!", "check_bring_token": "Token de Bring!", "check_curl_ssl": "cURL SSL", "check_internet": "Conexión a internet", "fresh_install": "instalación nueva", "warnings_found": "avisos detectados", "all_ok": "Sistema OK", "critical_error_short": "Error crítico", "critical_error": "Error crítico: la aplicación no puede iniciarse. Revisa los registros del servidor.", "error_network": "No se puede contactar con el servidor. Comprueba tu conexión de red.", "retry": "Reintentar", "syncing_local": "Sincronizando datos locales...", "sync_done": "Datos locales sincronizados" }, "stats_monthly": { "title": "Estadísticas Mensuales", "consumed": "productos usados", "trend_up": "+{pct}% vs {prev}", "trend_down": "-{pct}% vs {prev}", "trend_same": "mismo ritmo que el mes pasado", "added": "añadidos", "wasted": "desperdiciados", "top_used": "más usado", "top_cats": "Categorías principales", "source": "Historial de transacciones · mes actual" } }