es: admin: layout: title: "Match Live TV — Admin" nav: dashboard: Panel ops: Ops announcements: Avisos clubs: Clubes y equipos billing: Facturación youtube: YouTube sessions: Sesiones analytics: Analytics costs: Costes stream_nodes: Nodos stream password: Contraseña logout: Salir flash: login_required: Inicia sesión para continuar login_success: Sesión iniciada correctamente invalid_credentials: Usuario o contraseña no válidos logout_success: Sesión cerrada password_current_incorrect: La contraseña actual no es correcta password_too_short: La nueva contraseña debe tener al menos 8 caracteres password_too_long: La nueva contraseña no puede superar los 72 caracteres password_too_weak: "La nueva contraseña debe incluir al menos 3 entre: minúsculas, mayúsculas, números y símbolos" password_same_as_current: La nueva contraseña debe ser distinta de la actual password_mismatch: Las contraseñas no coinciden password_updated: Contraseña actualizada ops_acknowledged: Incidencia asumida ops_resolved: Incidencia resuelta ops_muted: Notificaciones silenciadas durante 24 horas stream_node_created: "Nodo lab %{slug} provisionado." stream_node_destroyed: "Nodo %{slug} eliminado." stream_node_draining: "Nodo %{slug} en drain." autoscale_kill_on: "Kill-switch del autoscaler activado. Sin scale-out automático." autoscale_kill_off: "Kill-switch del autoscaler desactivado (hace falta STREAM_AUTOSCALE_ENABLED=1)." comped_granted: "Suscripción de cortesía %{plan} activada para %{club}." comped_revoked: "Suscripción de cortesía revocada para %{club}." session_already_terminated: "La sesión ya ha finalizado (%{status})." session_stopped: Sesión finalizada. session_stop_error: "Error al cerrar la sesión: %{error}" session_terminated_no_regia: "Sesión finalizada: no se puede generar el enlace de regie." session_regia_generated: Enlace de regie generado. invoice_upload_hint: Sube el PDF desde la lista «Pagos por facturar». invoice_draft_created: Borrador creado. Sube el PDF desde la página de Facturación o aquí abajo. invoice_issued: "Factura %{number} emitida y enviada a %{email}." invoice_updated: "Factura %{number} actualizada." invoice_uploaded: "Factura subida y enviada a %{email}." youtube_not_configured: Configura YOUTUBE_CLIENT_ID y YOUTUBE_CLIENT_SECRET en .env announcement_created: Aviso guardado announcement_updated: Aviso actualizado announcement_destroyed: Aviso eliminado cost_entry_created: Partida de coste guardada. cost_entry_updated: Partida de coste actualizada. cost_entry_destroyed: Partida de coste eliminada. common: free_plan: Free yes: "Sí" no: "No" dash: "—" live_page: Página en directo auth: new: title: Acceso admin username_label: Usuario password_label: Contraseña submit: Acceder initial_credentials_html: "Credenciales iniciales: admin / AdminPass123. Cambia la contraseña después del primer acceso." passwords: edit: title: Cambiar contraseña current_password_label: Contraseña actual new_password_label: "Nueva contraseña (mín. 8, al menos 3 tipos de caracteres)" confirm_password_label: Confirma la nueva contraseña submit: Guardar contraseña cancel: Cancelar dashboard: kpi: active_sessions: Sesiones activas active_sessions_sub: en directo ahora today: Emitidas hoy today_sub: "%{duration} de emisión" month: Emitidas este mes month_sub: "%{duration} en total" teams: Equipos teams_sub: "%{count} usuarios" cpu: CPU cpu_sub: "carga %{one} / %{five} / %{fifteen}" ram: RAM ram_sub: "%{used} / %{total}" network: Ancho de banda (total) network_sub: "↑ %{tx} · ↓ %{rx}" recordings: Repeticiones archivadas recordings_sub: "%{count} grabaciones" charts: cpu: CPU (%) ram: RAM (%) ops_panel: title: Estado de la plataforma (Ops) critical: "%{count} incidencia(s) crítica(s) abierta(s)" view_dashboard: Ver panel de Ops warnings: "%{count} aviso(s)" dashboard_link: Panel de Ops none_html: "No hay incidencias abiertas. %{link}" disk: system_title: Disco del sistema free_label: "Libre: %{free} (%{percent}% usado)" not_available: Métricas de disco no disponibles recordings_title: Archivo de grabaciones recordings_content: "Contenido de las grabaciones: %{size}" recordings_not_mounted: "Ruta %{path} no montada" sessions: title: Sesiones activas table: match: Partido status: Estado client: Cliente ingest: Ingest start: Inicio link: Enlace none: No hay ninguna sesión activa en este momento. detail: Detalle stop: Finalizar stop_confirm: "¿Finalizar esta sesión?" regia: Regie teams: title: Equipos matches_count: "%{count} partidos" view_all: "Ver clubes (%{count} equipos)" stream_nodes: title: Nodos streaming providers: "Cloud: %{cloud} · DNS: %{dns}" actions_title: Acciones table_title: Nodos registrados empty: No hay nodos registrados. free_slots: one: "%{count} libre" other: "%{count} libres" kpi: autoscaler: Autoscaler kill_switch: KILL kind: "modo %{kind}" free_slots: Slots libres soft_slots: "umbral soft ≤ %{soft}" spare: Spare warm_spare: warm spares listos overflow: Overflow overflow_nodes: nodos cloud/lab budget: Presupuesto estimado budget_of: "de €%{budget}/mes (%{ok})" autoscale: "Autoscaler %{enabled} · free_slots=%{free} (soft≤%{soft}) · spare=%{spare}/%{warm} · overflow=%{overflow}/%{max} · kind=%{kind}" autoscale_budget: "presupuesto €%{eur}/€%{budget} (%{ok})" kill_switch_active: "KILL-SWITCH ACTIVO" engage_kill_switch: "Kill-switch ON" clear_kill_switch: "Kill-switch OFF" kill_switch_confirm: "¿Bloquear el autoscaler inmediatamente?" provision_lab: Provisionar lab provision_cloud: Provisionar Hetzner provision_cloud_confirm: "¿Crear un servidor Hetzner Cloud + DNS en mltv-stream.net?" hetzner_token_missing: "Configura HCLOUD_TOKEN para habilitar el provisioning Cloud." drain: Drain destroy: Eliminar destroy_confirm: "¿Eliminar el nodo %{slug}?" hosts_title: DNS lab (/etc/hosts) col: slug: Slug role: Rol status: Estado slots: Slots hostname: Hostname provider: Provider ops: kpi: critical: Críticas abiertas warning: Avisos abiertos total: Total abiertas open: title: Incidencias abiertas table: severity: Gravedad kind: Tipo title: Título occurrences: N.º last_seen: Última vez none: No hay incidencias abiertas. La plataforma parece estar sana. actions: acknowledge: Asumida resolve: Resolver mute: Silenciar 24h resolved: title: Resueltas (últimos 30 días) table: resolved_at: Resuelta none: No se han resuelto incidencias recientemente. clubs: index: title: Clubes y equipos subtitle_html: "Suscripciones de cortesía (patrocinadores / promociones) y estado de YouTube por equipo. Pagos de Stripe: %{billing_link}." billing_link: Facturación table: club: Club plan: Plan teams: Equipos comped: Cortesía stripe: Stripe manage: Gestionar invoices: Facturas show: back: "← Clubes y equipos" sport_label: "Deporte: %{sport}" recordings_archive: Archivo de repeticiones billing_link: Pagos y facturas youtube_platform_link: Canal de YouTube de la plataforma youtube_club_label: "YouTube del club:" youtube_connected: (conectado) youtube_premium_full_not_connected: Premium Full — canal del club no conectado (usa Match Live TV) no_channel_hint_html: "Sin un canal conectado, la app usa el canal de Match Live TV. %{link}." link_channel: Conectar canal (página del club) teams_title: Equipos no_teams: No hay equipos registrados. table: team: Equipo sport: Deporte matches_and_details: Partidos y detalles replay: Repeticiones comped: title: Suscripción de cortesía description: "Patrocinador o promoción: concede Premium Light/Full sin pago en Stripe. Revocable en cualquier momento." active_label: "Activa:" since_label_html: "Desde el %{date}" by_admin: "· admin %{username}" stripe_note: "Nota: también existe una suscripción de Stripe vinculada; la cortesía tiene prioridad sobre el plan." revoke_button: Revocar cortesía (volver a Free o restaurar Stripe) revoke_confirm: "¿Revocar la suscripción de cortesía para %{club}?" current_plan: "Plan actual: %{plan}" stripe_active: "· pago de Stripe activo" plan_label: Plan reason_label: "Motivo (p. ej. patrocinador 2026)" reason_placeholder: "Patrocinador, promoción…" grant_button: Conceder cortesía teams: show: back: "← %{club}" sport_label: "Deporte: %{sport}" club_label_html: "Club: %{club} · %{replay_link} · %{billing_link}" replay_link: Repeticiones del equipo billing_link: Pagos y facturas youtube_label: "YouTube:" youtube_platform_default_no_oauth: ", predeterminado sin OAuth del club" youtube_platform_channel: "(canal de la plataforma%{suffix})" youtube_club_channel: (canal del club) youtube_not_ready: no está listo no_channel_hint_html: "Sin un canal conectado, la app usa el canal de Match Live TV. %{link}." link_channel: Conectar canal (página del club) matches_title: Partidos sessions: index: title: Sesiones de emisión lead: Busca por club, equipo, rival o sede. Filtra por estado, plataforma, nodo y periodo. results: "Mostrando %{shown} de %{total}" none: Ninguna sesión coincide con estos filtros. filters: q: Buscar q_placeholder: Club, equipo, rival… status: Estado platform: Plataforma club: Club node: Nodo ingest from: Desde to: Hasta any: Todos apply: Filtrar reset: Restablecer table: club: Club match: Partido status: Estado started: Inicio ended: Fin duration: Duración ingest: Ingest disconnects: Desconexiones client: Cliente link: Enlace detail: Detalle regia: Regie show: title: "Sesión %{id}" heading: Detalle de sesión back: "← Volver a sesiones" club_label: "Club:" summary_title: Resumen timing_title: Tiempos ingest_title: Ingest y medios devices_title: Dispositivos events_title: Eventos events_none: No hay eventos registrados. status_label: "Estado:" stop_button: Finalizar sesión stop_confirm: "¿Finalizar la emisión? La ruta RTMP se eliminará y el estado pasará a finalizada." match_label: "Partido: %{team} vs %{opponent}" youtube_studio: YouTube Studio broadcast: Emisión open_replays: Abrir replays del club audio_muted: Audio silenciado audio_on: Audio activo ingest_node: "Nodo ingest:" rtmp_ingest: "Ingesta RTMP:" fields: id: ID club: Club team: Equipo opponent: Rival operator: Operador platform: Plataforma client_os: Sistema app_version: Versión app device: Dispositivo os_version: Versión OS carrier: Operador móvil privacy: Privacidad quality: Calidad min_quality: Calidad mínima audio: Audio created: Creada started: Inicio ended: Fin duration: Duración disconnects: Desconexiones scheduled: Partido programado location: Sede node: Nodo rtmp: Ingesta RTMP hls: HLS recording: Replay devices: role: Rol network: Red battery: Batería bitrate: Bitrate fps: FPS last_seen: Último contacto table: type: Tipo when: Cuándo meta: Detalles links: watch_title: Enlace en directo none: No hay ningún enlace de vídeo disponible para esta sesión. regia_title: Enlace de regie terminated: Sesión finalizada — enlace de regie no disponible. regia_label: Regie valid_until: "Válido hasta %{date}" active_exists: Ya existe un enlace de regie activo (la URL no se puede recuperar). Genera uno nuevo si necesitas compartirlo de nuevo. none_active: No hay ningún enlace de regie activo. Genera un enlace para compartir con quien gestione el marcador. generate_button: Generar enlace de regie ingest: none: "—" decommissioned: "(nodo eliminado)" role: home: Home-lab lab: Lab cloud: Hetzner analytics: missing_path: Selecciona una página. filters: from: Desde to: Hasta device: Dispositivo any: Todos apply: Filtrar reset: Restablecer layer: Capa layer_move: Movimientos del ratón layer_click: Clics devices: mobile: Móvil tablet: Tablet desktop: Escritorio index: title: Analytics del sitio lead: Heatmaps de movimientos/clics y scroll agregados (first-party), solo con consentimiento estadístico. Sin datos personales. none: No hay datos en el periodo seleccionado. heatmap: Heatmap table: path: Página pageviews: Pageviews moves: Movimientos clicks: Clics avg_scroll: Scroll medio max_scroll: Scroll máx show: title: Heatmap de página back: "← Volver a Analytics" summary: Resumen scroll_depth: Profundidad de scroll scroll_hint: "Media %{avg}% · máximo %{max}%" heatmap_moves: Mapa de movimientos heatmap_clicks: Mapa de clics heatmap_hint: Superposición de color sobre la captura %{device}. Verde = poco, rojo = mucho. Los datos no se mezclan entre dispositivos. device_tabs_label: Dispositivo preview_title: Captura de página preview_unavailable: Vista previa no disponible para rutas con placeholder (p. ej. /clubs/:id). snapshot_missing: Aún no hay captura para %{device}. Visita la página con ese dispositivo y consentimiento analytics, y vuelve a intentarlo. snapshot_meta: "Captura %{device} · %{at}" no_points: No hay puntos agregados para esta capa en el periodo. heatmap_title: Mapa de clics no_clicks: No hay clics agregados para esta página en el periodo. preview: title: Vista previa sin seguimiento lead: Navega el sitio público sin registrar pageviews, clics, movimientos ni capturas heatmap. Útil para pruebas en producción. active: Vista previa staff activa en este navegador (7 días o hasta desactivar). enable: Activar vista previa staff disable: Desactivar vista previa open_site: Abrir sitio enabled: Vista previa staff activada. Este navegador no registrará analytics. disabled: Vista previa staff desactivada. billing: index: title: Pagos por facturar description: Pagos de Stripe cobrados sin PDF de factura. Genera el PDF en tus sistemas y súbelo aquí; se asociará al pago y se enviará por email al cliente. filter_label: "Filtrar clubes:" filter_all: Todos incomplete_profile_warning: Datos de facturación incompletos no_billing_data: No hay datos de facturación — el cliente debe completar su perfil. pdf_label: PDF de la factura upload_button: Subir PDF y enviar al cliente none_pending: "No hay pagos pendientes de facturar%{club}." none_pending_for_club: " para %{club}" uploaded_title: Facturas ya subidas table: date: Fecha club: Club description: Descripción amount: Importe invoice: Factura status: Estado back_dashboard: "← Panel" billing_invoices: index: title: "Facturación — %{club}" back_dashboard: "← Panel" new_invoice: Nueva factura (sin pago) payments_title: Pagos table: date: Fecha description: Descripción amount: Importe invoice: Factura pdf_suffix: " (PDF)" edit_send_pdf: Editar / enviar PDF create_invoice: Crear factura no_payments: No hay pagos registrados para este club. all_invoices_title: Todas las facturas table2: number: Número date: Fecha amount: Importe status: Estado payment: Pago edit: Editar no_invoices: No hay facturas. new: title: "Nueva factura — %{club}" linked_payment: "Vinculada al pago del %{date} (%{amount})." number_label: Número de factura issued_on_label: Fecha de emisión amount_label: "Importe (€)" notes_label: Notas internas (opcional) hint: Guarda el borrador y luego sube el PDF y envíalo al cliente desde la siguiente pantalla. submit: Crear borrador de factura back: "← Pagos y facturas" edit: title: "Factura %{number} — %{club}" status_label: "Estado:" sent_at: "· Enviada el %{date}" number_label: Número de factura issued_on_label: Fecha de emisión amount_label: "Importe (€)" payment_info: "Pago: %{description} — %{amount}" pdf_label: PDF de la factura pdf_already: "PDF ya subido: %{filename}" notes_label: Notas internas save_draft: Guardar borrador issue_send: Emitir y enviar por email issue_confirm: "¿Enviar la factura a %{email}?" back: "← Pagos y facturas" youtube: platform_token: title: Token del canal de Match Live TV page_title: "Token de YouTube — Match Live TV" channel_label: "Canal: %{title}" success: "Conexión correcta. Copia esta línea ahora mismo:" env_hint_html: "Añade en /opt/matchlivetv/infra/.env:" not_shown_again_html: "No se volverá a mostrar. Luego: docker compose -f docker-compose.prod.yml restart rails sidekiq" no_refresh_token_html: "Google no ha devuelto un refresh token. En tu cuenta de Google → acceso de apps, revoca «Match Live TV» y repite el proceso desde /admin/youtube/platform." back_dashboard: "← Panel admin" club_recordings: index: title: "Repeticiones — %{club}" announcements: index: title: Avisos lead: Mensajes hacia las apps, el sitio público y el área privada — mantenimiento, actualizaciones o comunicados. new: Nuevo aviso table_title: Avisos none: Todavía no hay avisos. Crea uno para notificar a las apps y al sitio. new: title: Nuevo aviso edit: title: Editar aviso table: status: Estado kind: Tipo title: Mensaje channels: Destinos window: Ventana actions: edit: Editar delete: Eliminar delete_confirm: ¿Eliminar este aviso? Ya no se verá en los destinos elegidos. kind: info: Información maintenance: Mantenimiento update: Actualización severity: info: Info warning: Atención critical: Crítico status: draft: Borrador published: Publicado archived: Archivado channels: android: App Android ios: App iOS web_public: Sitio público web_private: Área privada window: always: Siempre (mientras esté publicado) from: "Desde %{time}" until: "Hasta %{time}" form: kind: Tipo severity: Gravedad status: Estado channels: Dónde mostrarlo channels_hint: "Elige uno o más destinos. Android e iOS son independientes: si el texto debe ser distinto, crea dos avisos. El área privada se ve tras iniciar sesión (club, equipos, cuenta)." title: Título body: Texto starts_at: Visible desde ends_at: Visible hasta window_hint: Déjalo vacío para mostrarlo de inmediato mientras esté publicado. action_url: Enlace (opcional) action_url_hint: En actualizaciones, una URL vacía abre la tienda de esa plataforma (Play Store en Android, App Store en iOS). action_label: Texto del botón locales_legend: Texto por idioma locales_hint: Completa todos los idiomas de la app (italiano, inglés, francés, alemán, español). El italiano es obligatorio; si falta un idioma, se usa inglés y luego italiano. locale_required: obligatorio dismissible: El usuario puede cerrar el aviso dismissible_hint: Quita la marca para avisos de mantenimiento que deben permanecer visibles. submit_create: Guardar aviso submit_update: Actualizar aviso cancel: Cancelar