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
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
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
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
table:
match: Partido
status: Estado
ingest: Ingest
disconnects: Desconexiones
link: Enlace
detail: Detalle
regia: Regie
show:
title: "Sesión %{id}"
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
ingest_node: "Nodo ingest:"
rtmp_ingest: "Ingesta RTMP:"
events_title: Eventos
table:
type: Tipo
when: Cuándo
meta: Meta
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: "—"
role:
home: Home-lab
lab: Lab
cloud: Hetzner
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