@import url('https://fonts.googleapis.com/css2?family=Sora:wght@600;700;800&family=DM+Sans:opsz,wght@9..40,400;9..40,500;9..40,700&display=swap');

:root {
  --color-bg: #f5f6f8;
  --color-surface: #ffffff;
  --color-border: #e1e4e8;
  --color-text: #1a1d21;
  --color-text-muted: #6b7280;
  --color-marca-navy: #14275a;
  --color-marca-navy-oscuro: #0c1a3d;
  --color-marca-naranja: #f5811e;
  /* Ajuste de contraste (2026-08-30): el naranja de marca (#f5811e) da
     solo 2.61:1 contra blanco — falla WCAG AA incluso para texto grande
     (mínimo 3:1), y peor para texto chico (mínimo 4.5:1). Esta variable
     ya existía pero no se usaba en ningún lado; se le puso un valor real
     -- mismo matiz/saturación que --color-marca-naranja (H=27.6°,
     S=91.5%), solo más oscuro (L=35% en vez de 54%) -- calculado para
     5.29:1 contra blanco, con margen sobre el mínimo de 4.5:1. Es el
     naranja a usar en cualquier lugar donde el naranja pinte una
     superficie grande con texto blanco encima (tarjetas de indicador,
     títulos de sección) — --color-marca-naranja (el claro) queda para
     acentos chicos donde no hay texto blanco encima (badges con fondo
     claro y texto naranja, por ejemplo). */
  --color-marca-naranja-oscuro: #ab5308;
  /* Paleta corporativa: azul marino como color primario (encabezados,
     navegación, botones principales), naranja como acento (badges de
     alerta). Alias sobre los colores de marca para que sean un solo
     origen de verdad. */
  --color-primary: var(--color-marca-navy);
  --color-primary-hover: var(--color-marca-navy-oscuro);
  /* Acento de marca por academia (Fase 10) -- distinto de --color-warning
     a propósito: --color-warning tiene significado semántico (alertas,
     vencidos) en toda la app y no debe cambiar por academia. Este acento
     es puramente decorativo (carnet, insignias) y cae al naranja de
     EasySports por defecto, igual que --color-primary cae al navy. */
  --color-acento-marca: var(--color-marca-naranja);
  --color-danger: #dc2626;
  --color-warning: var(--color-marca-naranja);
  /* Colores de tipo de evento del calendario (2026-08-23): entrenamiento y
     campeonato reusan navy/naranja (actividad regular / evento que
     resalta). Viaje necesita un tercer color categórico que no exista
     todavía — no reusa el verde de éxito ni el rojo de peligro para no
     prestarse a confusión con esos significados ya establecidos. */
  --color-evento-entrenamiento: var(--color-marca-navy);
  --color-evento-campeonato: var(--color-marca-naranja);
  --color-evento-viaje: #7c3aed;
  /* .estado-pill.activo/.pagado usaban un verde hardcodeado sin variable
     -- era el único color de badge sin tokenizar (naranja/rojo ya tenían
     --color-warning/--color-danger). Formalizado en el rediseño visual
     (2026-08-29, piloteado primero en admin/dashboard.html). */
  --color-success: #15803d;
  --color-success-bg: #dcfce7;
  /* Rediseño visual (2026-08-29): la escala de radio que ya existía era
     inconsistente (6/8/10/12px según componente) sin ser un desacuerdo de
     diseño, solo nunca se formalizó. --radio-base es el valor "generoso"
     para tarjetas/tablas/botones; --radio-chico es para elementos chicos
     donde --radio-base se vería desproporcionado (botones de acción
     inline en tablas). */
  --radio-base: 14px;
  --radio-chico: 10px;
  /* Sombra de dos capas (una pegada + una difusa) -- mismo tono neutro que
     ya usaba .tarjeta-login/.panel-notificaciones, no el registro
     dramático con tinte navy que usa la landing (rgba(20,39,90,0.1-0.3)),
     que es para vender, no para uso diario. */
  --sombra-tarjeta: 0 1px 2px rgba(16, 24, 40, 0.04), 0 4px 12px rgba(16, 24, 40, 0.06);
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
}

html {
  scroll-behavior: smooth;
  /* Ver el comentario en body: en iOS Safari en particular, hace falta
     en los dos (html Y body) para que de verdad no quede scroll
     horizontal ni "rebote" lateral. */
  overflow-x: hidden;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text);
  /* Red de seguridad (2026-09-15, bug de celular reportado por el
     usuario en el portal de representante): sin esto, un solo elemento
     que se desborde por accidente (una tarjeta de grid, una tabla, un
     texto largo) arrastra TODA la página a scroll horizontal en vez de
     quedar contenido -- el usuario terminaba teniendo que "correr la
     navegación a la derecha" para ver el resto. Los elementos que sí
     necesitan su propio scroll horizontal (tablas, nav de celular) ya
     lo declaran en su propio contenedor, así que esto no les afecta. */
  overflow-x: hidden;
}

a {
  color: var(--color-primary);
}

/* ---------- Login ---------- */

.pantalla-centrada {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
}

.tarjeta-login {
  width: 100%;
  max-width: 360px;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radio-base);
  padding: 2rem;
  box-shadow: var(--sombra-tarjeta);
}

.tarjeta-login h1 {
  font-size: 1.25rem;
  margin: 0 0 1.5rem;
  color: var(--color-primary);
}

.campo {
  margin-bottom: 1rem;
}

.campo label {
  display: block;
  font-size: 0.875rem;
  font-weight: 600;
  margin-bottom: 0.375rem;
}

.campo input {
  width: 100%;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--color-border);
  border-radius: 8px;
  font-size: 1rem;
}

.campo input:focus {
  outline: 2px solid var(--color-primary);
  outline-offset: 1px;
}

/* `.campo input` de arriba (pensada para inputs de texto) estiraba
   cualquier checkbox/radio a 100% de ancho -- 2026-09-09, a pedido del
   usuario tras ver el resultado en Invitar entrenador. Un checkbox/radio
   nunca debe heredar ese ancho, esté donde esté. */
.campo input[type="checkbox"],
.campo input[type="radio"] {
  width: auto;
}

/* input[type=color] con el mismo width:100% + padding de un input de texto
   se ve, en Chrome, como una línea delgada en vez de un cuadro de color
   reconocible -- el swatch interno se aplasta contra el padding. Se le da
   tamaño y relleno propios, como cualquier selector de color. */
.campo input[type="color"] {
  width: 72px;
  height: 48px;
  padding: 4px;
  cursor: pointer;
}

/* Un checkbox/radio suelto con su propio texto (ej. "Cobrar matrícula
   anual" en configuracion.html, o "Todos los jugadores activos" en
   cobros.html) -- antes era un <label> a secas dentro de .campo, que por
   `.campo label { display: block }` (arriba) quedaba con el cuadradito
   solo en su propia línea, arriba del texto. Agregar esta clase a ese
   <label> lo pone en fila: cuadradito a la izquierda, texto a la
   derecha, como cualquier checkbox del sistema operativo. */
.campo label.campo-checkbox {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 400;
  cursor: pointer;
}

/* select/textarea nunca tuvieron su propia regla — quedaban con la
   apariencia nativa del sistema operativo, chica e inconsistente. */
.campo select,
.campo textarea {
  width: 100%;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--color-border);
  border-radius: 8px;
  font-size: 1rem;
  font-family: inherit;
}

.campo select:focus,
.campo textarea:focus {
  outline: 2px solid var(--color-primary);
  outline-offset: 1px;
}

button {
  font: inherit;
  cursor: pointer;
}

.boton-primario {
  width: 100%;
  padding: 0.7rem;
  background: var(--color-primary);
  color: #fff;
  border: none;
  border-radius: var(--radio-base);
  font-weight: 600;
}

.boton-primario:hover {
  background: var(--color-primary-hover);
}

.boton-primario:disabled {
  opacity: 0.6;
  cursor: default;
}

.mensaje-error {
  margin-top: 1rem;
  padding: 0.6rem 0.75rem;
  background: #fef2f2;
  color: var(--color-danger);
  border: 1px solid #fecaca;
  border-radius: 8px;
  font-size: 0.875rem;
}

/* ---------- Layout general de pantallas internas ---------- */

/* Aviso de "modo demo" (montado por auth.js vía modo-demo.js) para las 3
   cuentas fijas de solo lectura -- franja completa arriba de todo, antes
   de .barra-superior, en las 3 pantallas donde aparece (nunca en
   super_admin: es_demo siempre es false ahí). */
.barra-modo-demo {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  padding: 0.75rem 1.5rem;
  background: var(--color-marca-navy);
  color: #fbfaf8;
  text-align: center;
}

.barra-modo-demo-texto {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.9rem;
}

.barra-modo-demo-icono {
  display: inline-flex;
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  color: var(--color-marca-naranja);
}

.barra-modo-demo-icono svg {
  width: 100%;
  height: 100%;
}

.barra-modo-demo-boton {
  padding: 0.4rem 1rem;
  border-radius: 999px;
  border: 1.5px solid rgba(251, 250, 248, 0.4);
  background: transparent;
  color: #fbfaf8;
  font-family: inherit;
  font-weight: 600;
  font-size: 0.85rem;
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.2s ease, border-color 0.2s ease;
}

.barra-modo-demo-boton:hover {
  background: rgba(251, 250, 248, 0.12);
  border-color: rgba(251, 250, 248, 0.7);
}

.barra-superior {
  display: flex;
  align-items: center;
  justify-content: space-between;
  /* Con justify-content:space-between, el espacio entre el bloque
     izquierdo (logo/título/nav) y el derecho (campanita/logout) depende
     de cuánto ancho sobre -- con el nav de admin_academia (hasta 10
     enlaces) eso podía llegar a 0px en pantallas no ultra-anchas, la
     campanita quedaba pegada al último enlace. `gap` acá funciona como
     piso mínimo garantizado sin importar cuánto espacio sobre. */
  gap: 1.5rem;
  /* flex-wrap agregado en el rediseño visual (2026-08-29) -- con nav
     largos (admin_academia llega a 11 enlaces) + nombre de academia
     largo, si no entra todo en una fila el bloque derecho (campanita +
     cerrar sesión) baja a su propia fila en vez de exprimir el nombre
     letra por letra. Antes de Fase 10 acá también vivía la marca "Con
     tecnología de EasySports" -- se movió al pie de página (siempre
     oculta en el header ahora), así que esto rara vez llega a activarse
     salvo con un nombre de academia realmente largo. */
  flex-wrap: wrap;
  row-gap: 0.5rem;
  padding: 1rem 1.5rem;
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
}

/* Marca EasySports (rediseño visual, 2026-08-29; movida al pie en
   Fase 10 a pedido del usuario) -- insertada por montarNotificaciones()
   (web/assets/notificaciones.js) en .barra-superior-derecha (versión
   header, hoy siempre oculta) y al final de <body> (versión pie, hoy
   siempre visible), mismo único lugar que arma las dos para los 22
   roles/pantallas que las usan. Antes de esto, la marca desaparecía por
   completo de toda pantalla autenticada apenas cargaba la academia
   (mostrarAcademiaEnEncabezado() reemplaza el texto "EasySports" del
   <h1>) -- el logo.png real solo se usa en la landing pública.
   La versión de header competía por espacio con el menú (especialmente
   el de admin_academia, agrupado con íconos) y partía la barra superior
   en dos líneas en anchos de laptop comunes -- el usuario prefirió
   sacarla del todo del header y dejarla siempre como cierre de página,
   en vez de aparecer/desaparecer según el ancho de pantalla. */
.marca-easysports-header {
  display: none;
}

.marca-easysports-footer {
  display: block;
  text-align: center;
  padding: 1.25rem 1rem;
  font-size: 0.75rem;
  color: var(--color-text-muted);
}

.marca-easysports-footer strong {
  color: var(--color-primary);
  font-weight: 700;
}

.barra-superior h1 {
  font-size: 1.1rem;
  margin: 0;
  color: var(--color-primary);
}

.barra-superior-izquierda {
  display: flex;
  align-items: center;
  gap: 1.5rem;
}

/* Botón de hamburguesa (Fase 10, a pedido del usuario) -- insertado por
   montarNotificaciones() (web/assets/notificaciones.js) como primer hijo
   de .barra-superior-izquierda, en las mismas 22+ pantallas que ya
   arman ahí la marca/campanita. Invisible en escritorio (el nav ya se ve
   completo ahí); en celular abre/cierra el nav como panel desplegable
   -- ver el breakpoint de celular más abajo. */
.boton-menu-movil {
  display: none;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  padding: 0;
  flex-shrink: 0;
  /* Relleno con el color de marca de la academia y líneas blancas (no
     solo un ícono de contorno) -- a pedido del usuario, "para que se
     note más". Mismo var(--color-primary) que ya tiñe el resto de
     acentos de marca, aplicado por aplicarColorDeMarca() en academia.js. */
  background: var(--color-primary);
  border: none;
  border-radius: var(--radio-chico);
  color: #fff;
  cursor: pointer;
}

.boton-menu-movil svg {
  width: 20px;
  height: 20px;
}

/* Contenedor del lado derecho de la barra superior (campanita de
   notificaciones + botón de cerrar sesión) — necesario porque
   .barra-superior usa justify-content: space-between con solo 2 hijos
   directos; agregar la campanita como un tercer hijo suelto rompería ese
   layout. web/assets/notificaciones.js arma este contenedor por JS. */
.barra-superior-derecha {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.logo-academia-header {
  /* 32px -> 58px (2026-09-09): el usuario pidió que el logo de la
     academia se vea con mucha más importancia, al menos 80% más grande,
     siempre en el mismo lugar (esquina superior izquierda de
     .barra-superior-izquierda, antes del nombre) en las 22 pantallas que
     lo muestran -- ya estaban 100% consistentes en HTML, así que este es
     el único cambio necesario. */
  height: 58px;
  width: auto;
  display: block;
}

/* ---------- Centro de notificaciones (Fase 8b) ---------- */

.campanita-notificaciones {
  position: relative;
}

.boton-campanita {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 0;
  background: transparent;
  border: 1px solid var(--color-border);
  border-radius: 8px;
  color: var(--color-text);
  cursor: pointer;
}

.boton-campanita:hover {
  background: var(--color-bg);
}

.boton-campanita svg {
  width: 20px;
  height: 20px;
}

.badge-notificaciones {
  position: absolute;
  top: -4px;
  right: -4px;
  min-width: 18px;
  height: 18px;
  padding: 0 4px;
  border-radius: 999px;
  background: var(--color-danger);
  color: #fff;
  font-size: 0.7rem;
  font-weight: 700;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* .badge-notificaciones { display: flex } tiene la misma especificidad
   que la regla [hidden] { display: none } del navegador -- sin esto, el
   atributo hidden queda sin efecto y el badge nunca se oculta cuando el
   conteo llega a 0. */
.badge-notificaciones[hidden] {
  display: none;
}

.panel-notificaciones {
  position: absolute;
  top: calc(100% + 0.5rem);
  right: 0;
  width: 340px;
  max-width: calc(100vw - 2rem);
  max-height: 420px;
  display: flex;
  flex-direction: column;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radio-base);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
  z-index: 50;
  overflow: hidden;
}

/* Mismo motivo que .badge-notificaciones[hidden] arriba: display: flex
   con la misma especificidad que [hidden] { display: none } lo anula. */
.panel-notificaciones[hidden] {
  display: none;
}

.panel-notificaciones-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.85rem 1rem;
  border-bottom: 1px solid var(--color-border);
}

.panel-notificaciones-header h3 {
  margin: 0;
  font-size: 0.95rem;
  color: var(--color-primary);
}

.boton-marcar-todas {
  background: none;
  border: none;
  color: var(--color-primary);
  font-size: 0.8rem;
  cursor: pointer;
  padding: 0;
  font-family: inherit;
}

.boton-marcar-todas:hover {
  text-decoration: underline;
}

.boton-marcar-todas:disabled {
  color: var(--color-text-muted);
  cursor: default;
  text-decoration: none;
}

.panel-notificaciones-lista {
  overflow-y: auto;
}

.notificacion-fila {
  display: block;
  width: 100%;
  text-align: left;
  padding: 0.75rem 1rem;
  border: none;
  border-bottom: 1px solid var(--color-border);
  background: var(--color-surface);
  cursor: pointer;
  font-family: inherit;
}

.notificacion-fila:last-child {
  border-bottom: none;
}

.notificacion-fila:hover {
  background: var(--color-bg);
}

.notificacion-fila.no-leida {
  background: #eef2ff;
}

.notificacion-fila.no-leida:hover {
  background: #e0e7ff;
}

.notificacion-titulo {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-weight: 600;
  font-size: 0.875rem;
  color: var(--color-text);
}

.notificacion-punto {
  width: 8px;
  height: 8px;
  border-radius: 999px;
  background: var(--color-primary);
  flex-shrink: 0;
}

.notificacion-mensaje {
  margin: 0.2rem 0 0;
  font-size: 0.8rem;
  color: var(--color-text-muted);
}

.notificacion-fecha {
  margin: 0.3rem 0 0;
  font-size: 0.7rem;
  color: var(--color-text-muted);
}

.panel-notificaciones-vacio {
  padding: 2rem 1rem;
  text-align: center;
  color: var(--color-text-muted);
  font-size: 0.875rem;
}

.preview-logo-academia {
  max-height: 96px;
  max-width: 100%;
  display: block;
}

/* Galería de la página pública de la academia (Fase "página pública",
   2026-10-05) -- grilla de miniaturas con botón de eliminar superpuesto,
   usada en admin/configuracion.html para "Nuestras instalaciones" y
   "Nuestros estudiantes". */
.galeria-admin-academia {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
  gap: 0.75rem;
  margin: 0.75rem 0;
}

.galeria-admin-academia-item {
  position: relative;
  aspect-ratio: 1;
  border-radius: var(--radio-base);
  overflow: hidden;
  background: var(--color-bg);
}

.galeria-admin-academia-item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.galeria-admin-academia-eliminar {
  position: absolute;
  top: 0.3rem;
  right: 0.3rem;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: none;
  background: rgba(20, 39, 90, 0.72);
  color: #fff;
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}

.galeria-admin-academia-eliminar:hover {
  background: var(--color-danger);
}

/* ---------- Perfil de la academia (dashboard) ---------- */

.perfil-academia {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radio-base);
  box-shadow: var(--sombra-tarjeta);
  border-top: 3px solid var(--color-primary);
  padding: 1.5rem;
}

.perfil-academia-encabezado {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 0.5rem;
}

.perfil-logo-academia {
  height: 72px;
  width: auto;
  display: block;
  border-radius: 999px;
  border: 3px solid var(--color-surface);
  outline: 2px solid var(--color-border);
  box-shadow: var(--sombra-tarjeta);
}

.perfil-academia-encabezado h3 {
  margin: 0;
  font-size: 1.4rem;
}

.perfil-academia > .texto-muted {
  margin: 0 0 1.25rem;
}

.perfil-academia-grilla {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 1.5rem;
}

.perfil-academia-grilla h4 {
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--color-text-muted);
  margin: 0 0 0.5rem;
}

.lista-sedes {
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: 0.9rem;
}

.lista-sedes li {
  margin-bottom: 0.35rem;
}

.nav-secundaria {
  display: flex;
  gap: 1rem;
}

.nav-secundaria a {
  font-size: 0.875rem;
  color: var(--color-text-muted);
  text-decoration: none;
}

.nav-secundaria a:hover,
.nav-secundaria a.activo {
  color: var(--color-primary);
}

/* Nav inferior móvil -- representante y entrenador (2026-09-29,
   rediseño visual). Generado por web/assets/nav-inferior.js, no es
   HTML estático. Oculto en escritorio (ver media query abajo). */
.nav-inferior {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 40;
  height: 62px;
  background: var(--color-surface);
  border-top: 1px solid var(--color-border);
  display: flex;
  align-items: stretch;
  padding-bottom: env(safe-area-inset-bottom, 0);
}

.nav-inferior-item {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  position: relative;
  color: var(--color-text-muted);
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
}

.nav-inferior-item svg {
  width: 19px;
  height: 19px;
}

.nav-inferior-item span {
  font-size: 0.6rem;
  font-weight: 600;
}

.nav-inferior-item.activo {
  color: var(--color-primary);
}

.nav-inferior-item-punto {
  position: absolute;
  top: 6px;
  right: calc(50% - 14px);
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--color-marca-naranja);
  border: 1.5px solid var(--color-surface);
}

.con-nav-inferior {
  padding-bottom: 4.5rem;
}

@media (min-width: 900px) {
  .nav-inferior {
    display: none;
  }
  .con-nav-inferior {
    padding-bottom: 0;
  }
}

/* Menú agrupado de admin_academia (2026-09-06) — generado por
   web/assets/nav-admin.js, no es HTML estático. Reemplaza el
   <nav class="nav-secundaria"> de 12 enlaces sueltos por 6 opciones, 3
   con submenú. .nav-secundaria se mantiene sin cambios para
   entrenador/representante/super_admin. */
.nav-admin {
  display: flex;
  align-items: center;
  gap: 26px;
}
.nav-admin-link,
.nav-admin-grupo-trigger {
  font-size: 0.875rem;
  color: var(--color-text-muted);
  text-decoration: none;
  background: none;
  border: none;
  padding: 0;
  font-family: inherit;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 5px;
  white-space: nowrap;
}
.nav-admin-link:hover,
.nav-admin-grupo-trigger:hover {
  color: var(--color-primary);
}
.nav-admin-link.activo {
  color: var(--color-primary);
  padding-bottom: 4px;
  border-bottom: 2px solid var(--color-primary);
}
.nav-admin-grupo-trigger.activo {
  color: var(--color-primary);
}
.nav-admin-grupo-trigger svg {
  width: 12px;
  height: 12px;
  transition: transform 0.15s ease;
}
.nav-admin-link .nav-admin-icono,
.nav-admin-grupo-trigger .nav-admin-icono {
  width: 15px;
  height: 15px;
  flex-shrink: 0;
}
.nav-admin-grupo-trigger.abierto {
  color: var(--color-primary);
  background: rgba(20, 39, 90, 0.07);
  border-radius: var(--radio-chico);
  padding: 6px 10px;
  margin: -6px -10px;
}
.nav-admin-grupo-trigger.abierto svg {
  transform: rotate(180deg);
}
.nav-admin-grupo {
  position: relative;
  display: flex;
  align-items: center;
}
.nav-admin-desplegable {
  /* position: fixed (no absolute) + top/left puestos por JS al abrirlo
     (ver nav-admin.js) -- así el panel no vive dentro de la caja de
     .nav-admin, que en el celular necesita overflow-x: auto para
     deslizarse y recortaba (dejaba invisible) cualquier desplegable
     que se saliera de su alto. */
  position: fixed;
  width: 220px;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radio-base);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
  padding: 8px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  z-index: 50;
}
/* Mismo motivo que .badge-notificaciones[hidden]/.panel-notificaciones[hidden]
   más arriba: display: flex con la misma especificidad que
   [hidden] { display: none } del navegador lo anula -- sin esto, el
   desplegable queda siempre visible y el toggle por JS no tiene efecto. */
.nav-admin-desplegable[hidden] {
  display: none;
}
.nav-admin-desplegable a {
  display: block;
  padding: 10px 12px;
  border-radius: var(--radio-chico);
  font-size: 0.875rem;
  color: var(--color-text);
  text-decoration: none;
  white-space: nowrap;
}
.nav-admin-desplegable a:hover {
  background: var(--color-bg);
}
.nav-admin-desplegable a.activo {
  color: var(--color-primary);
  background: rgba(20, 39, 90, 0.06);
}

.boton-secundario {
  padding: 0.45rem 0.9rem;
  background: transparent;
  border: 1px solid var(--color-border);
  border-radius: var(--radio-base);
  font-size: 0.875rem;
  color: var(--color-text);
}

.boton-secundario:hover {
  background: var(--color-bg);
}

/* ---------- Barra de pestañas genérica (nacida en cobros.html, ---------- */
/* reusada desde 2026-09-09 en cualquier pantalla de "lista + formulario"
   -- ej. Jugadores/Nuevo jugador, Categorías/Nueva categoría -- para no
   tener que bajar hasta el final de una lista larga a buscar el
   formulario. Mismo espíritu que .nav-admin-link/.nav-admin-desplegable
   a.activo: fondo tenue + texto en --color-primary para marcar la opción
   activa, sin inventar un patrón visual nuevo. */
.barra-pestanas {
  display: flex;
  gap: 0.5rem;
  margin-bottom: 1.5rem;
  flex-wrap: wrap;
}

.boton-pestana {
  padding: 0.5rem 1.1rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 999px;
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--color-text-muted);
  cursor: pointer;
}

.boton-pestana:hover {
  color: var(--color-marca-navy);
  border-color: var(--color-marca-navy);
}

.boton-pestana.activa {
  background: var(--color-marca-navy);
  border-color: var(--color-marca-navy);
  color: #fff;
}

.boton-pestana.activa:hover {
  color: #fff;
}

main {
  max-width: 1100px;
  margin: 0 auto;
  padding: 1.5rem;
}

/* ---------- Tarjetas de indicadores ---------- */

.grilla-indicadores {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 1rem;
  margin-bottom: 2rem;
}

/* Relleno naranja sólido + texto blanco (2026-08-30, ajuste al rediseño
   visual del 2026-08-29 -- antes era fondo blanco con acento navy). Usa
   --color-marca-naranja-oscuro, no --color-marca-naranja -- ver el
   comentario de esa variable en :root, es el que da 5.29:1 contra blanco
   (WCAG AA). Sin border-left ya no hace falta, el naranja sólido ya es
   la señal de "esto es un indicador". */
.tarjeta-indicador {
  background: var(--color-marca-naranja-oscuro);
  border: none;
  border-radius: var(--radio-base);
  box-shadow: var(--sombra-tarjeta);
  padding: 1rem 1.25rem;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.tarjeta-indicador:hover {
  transform: translateY(-2px);
  box-shadow: 0 2px 4px rgba(16, 24, 40, 0.05), 0 8px 20px rgba(16, 24, 40, 0.09);
}

.tarjeta-indicador .etiqueta {
  font-size: 0.8rem;
  /* Blanco casi sólido, no un blanco atenuado -- a 0.85 de opacidad el
     contraste contra el naranja baja a 4.29:1, por debajo del mínimo de
     4.5:1 para texto chico (WCAG AA). La jerarquía etiqueta/valor la da
     el tamaño y el peso de fuente, no la opacidad del color. */
  color: rgba(255, 255, 255, 0.95);
  margin-bottom: 0.4rem;
}

.tarjeta-indicador .valor {
  font-size: 1.6rem;
  font-weight: 700;
  color: #fff;
}

.tarjeta-indicador .valor.cargando {
  color: rgba(255, 255, 255, 0.95);
  font-weight: 400;
  font-size: 1rem;
}

/* ---------- Tabla de cobros pendientes ---------- */

/* Solo dentro de <main> (pantallas de la app) — la landing pública
   (web/index.html) no usa <main>, así que sus h2 en fondos de color
   (franja-cierre, franja-foto-superpuesta) no se ven afectados por esta regla. */
/* Ajuste de marca (2026-08-30): los títulos de sección pasan de navy a
   naranja en las 22 pantallas -- decisión de marca del usuario, a
   sabiendas de que reduce el contraste que hacía destacar
   .seccion-alertas (que ya usaba naranja en sus badges de "pendiente" --
   ver el ajuste de esos badges más abajo, que intenta compensar esto).
   Usa --color-marca-naranja-oscuro (WCAG-seguro), no
   --color-marca-naranja -- ver el comentario de esa variable en :root. */
main h2 {
  font-size: 1rem;
  color: var(--color-marca-naranja-oscuro);
  position: relative;
  margin-bottom: 1rem;
  padding-bottom: 0.6rem;
}

main h2::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0;
  width: 2.5rem;
  height: 3px;
  border-radius: 999px;
  background: var(--color-marca-naranja-oscuro);
}

.tabla-cobros {
  width: 100%;
  border-collapse: collapse;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radio-base);
  box-shadow: var(--sombra-tarjeta);
  overflow: hidden;
}

.tabla-cobros th,
.tabla-cobros td {
  text-align: left;
  padding: 0.85rem 1.1rem;
  border-bottom: 1px solid var(--color-border);
  font-size: 0.9rem;
}

.tabla-cobros tbody tr {
  transition: background 0.12s ease;
}

.tabla-cobros tbody tr:hover {
  background: rgba(20, 39, 90, 0.025);
}

.tabla-cobros th {
  background: var(--color-bg);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--color-text-muted);
}

.tabla-cobros tbody tr:last-child td {
  border-bottom: none;
}

/* Inputs/selects que se crean sueltos dentro de una celda (edición inline
   de sedes/categorías) tampoco tenían regla propia. */
.tabla-cobros input,
.tabla-cobros select {
  padding: 0.4rem 0.5rem;
  border: 1px solid var(--color-border);
  border-radius: 6px;
  font-size: 0.9rem;
  font-family: inherit;
}

.estado-pill {
  display: inline-block;
  padding: 0.3rem 0.8rem;
  border-radius: 999px;
  border: 1px solid transparent;
  font-size: 0.75rem;
  font-weight: 600;
}

/* PROPUESTA no confirmada (2026-08-30) -- ver CLAUDE.md/el reporte de la
   sesión. Con el naranja ahora en títulos de sección + tarjetas de
   indicador, "pendiente" (que ya usaba naranja) se mezcla con el resto de
   la pantalla y deja de leerse como alerta. Acá se lo pasa a un tono
   neutro (mismo tratamiento que .estado-pill.inactivo, no colisiona en la
   práctica porque nunca aparecen en la misma lista) y "vencido" pasa a
   relleno sólido en vez de tinte claro, para que sea el único badge que
   de verdad "grita". Si no gusta, revertir es solo estas dos reglas.*/
.estado-pill.pendiente {
  background: #f1f2f4;
  color: var(--color-text-muted);
  border-color: var(--color-border);
}

.estado-pill.vencido {
  background: var(--color-danger);
  color: #fff;
  border-color: transparent;
}

.estado-pill.activo,
.estado-pill.pagado {
  background: var(--color-success-bg);
  color: var(--color-success);
  border-color: rgba(21, 128, 61, 0.25);
}

.estado-pill.inactivo {
  background: #f1f2f4;
  color: var(--color-text-muted);
}

/* Suspensión de usuarios/representantes individuales (2026-09-09) --
   mismo tratamiento sólido que .estado-pill.vencido: es una acción activa
   del super_admin/admin_academia, no un estado neutro como "sin acceso"
   o "inactivo", así que necesita leerse como alerta igual que "vencido". */
.estado-pill.suspendido {
  background: var(--color-danger);
  color: #fff;
  border-color: transparent;
}

.boton-recordatorio {
  padding: 0.35rem 0.75rem;
  background: transparent;
  border: 1px solid var(--color-primary);
  color: var(--color-primary);
  border-radius: var(--radio-chico);
  font-size: 0.8rem;
}

.boton-recordatorio:hover {
  background: #eff6ff;
}

/* Grupo de botones de acción dentro de una celda de tabla (Editar/Eliminar,
   Guardar/Cancelar, etc.) — mismo patrón flex+gap que ya usa
   .calendario-acciones-detalle, en vez de márgenes sueltos entre botones.
   flex-wrap para que en celular, si la celda queda angosta, los botones
   bajen a una segunda línea con el mismo espaciado en vez de recortarse o
   apretarse. */
.celda-acciones-tabla {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.texto-muted {
  color: var(--color-text-muted);
  font-size: 0.9rem;
}

/* ---------- Formularios internos (invitar entrenador, etc.) ---------- */

.tarjeta-formulario {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radio-base);
  box-shadow: var(--sombra-tarjeta);
  padding: 1.25rem;
  max-width: 480px;
}

/* Lista de checkboxes/radios (categorías, sedes, jugadores, audiencia de
   comunicados) -- rediseñada 2026-09-09 a pedido del usuario: antes era
   una fila de "chips" en flex-wrap que se veía desordenada (y en la
   práctica se rompía -- ver el comentario sobre `.campo input` más
   arriba), ahora es una lista vertical simple, cuadradito a la
   izquierda y texto a la derecha, como cualquier lista de opciones.
   Selectores con dos clases (`.checkboxes-categorias .checkbox-categoria`)
   a propósito -- le ganan por especificidad a `.campo label` sin
   necesitar !important, que este archivo no usa en ningún otro lado. */
.checkboxes-categorias {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  margin-bottom: 1rem;
  max-height: 220px;
  overflow-y: auto;
  padding: 0.35rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radio-chico);
}

.checkboxes-categorias .checkbox-categoria {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.9rem;
  font-weight: 400;
  padding: 0.4rem 0.5rem;
  border-radius: var(--radio-chico);
  cursor: pointer;
}

.checkboxes-categorias .checkbox-categoria:hover {
  background: var(--color-bg);
}

.checkboxes-categorias input[type="checkbox"],
.checkboxes-categorias input[type="radio"] {
  width: auto;
  flex-shrink: 0;
  margin: 0;
}

.banner-exito {
  margin-bottom: 1rem;
  padding: 0.75rem 1rem;
  background: #ecfdf5;
  border: 1px solid #a7f3d0;
  border-radius: 8px;
  color: #065f46;
  font-size: 0.9rem;
  max-width: 480px;
}

.banner-exito p {
  margin: 0.25rem 0;
}

section {
  margin-bottom: 2rem;
}

/* ---------- Toma de asistencia (entrenador) ---------- */

.grupo-estado-asistencia {
  display: flex;
  gap: 0.4rem;
}

/* Variante circular con una sola letra (rediseño 2026-09-29, pantalla de
   tomar asistencia de entrenador) -- clase modificadora aparte para no
   afectar las otras 4 pantallas que reusan .boton-estado con la palabra
   completa (admin/entrenamientos, admin/torneos, admin/cursos-vacacionales,
   entrenador/torneos). La palabra completa se conserva en title/aria-label
   de cada botón. */
.grupo-estado-asistencia-compacta {
  gap: 0.35rem;
}

.grupo-estado-asistencia-compacta .boton-estado {
  width: 30px;
  height: 30px;
  padding: 0;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
}

.boton-estado {
  padding: 0.3rem 0.65rem;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  border-radius: 6px;
  font-size: 0.8rem;
  color: var(--color-text-muted);
}

.boton-estado.activo.presente {
  background: #dcfce7;
  border-color: #86efac;
  color: #15803d;
}

.boton-estado.activo.ausente {
  background: #fee2e2;
  border-color: #fca5a5;
  color: var(--color-danger);
}

.boton-estado.activo.atraso {
  background: #fdead9;
  border-color: #f7b98a;
  color: var(--color-warning);
}

.boton-estado.activo.justificado {
  background: #dbeafe;
  border-color: #93c5fd;
  color: var(--color-primary);
}

/* ---------- Escáner de QR de asistencia (entrenador) ---------- */
.modal-escaner-qr {
  position: fixed;
  inset: 0;
  background: rgba(12, 18, 32, 0.75);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  z-index: 1000;
}

/* Misma clase de bug ya documentada dos veces en este archivo
   (.badge-notificaciones/.panel-notificaciones, .nav-admin-desplegable):
   [hidden] del navegador y este display: flex tienen la misma
   especificidad -- sin esta regla, el atributo hidden no ocultaría nada. */
.modal-escaner-qr[hidden] {
  display: none;
}

.modal-escaner-qr-contenido {
  background: var(--color-surface);
  border-radius: var(--radio-base);
  box-shadow: var(--sombra-tarjeta);
  padding: 1.25rem;
  max-width: 420px;
  width: 100%;
}

.modal-escaner-qr-encabezado {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.75rem;
}

.modal-escaner-qr-encabezado h3 {
  margin: 0;
  font-size: 1rem;
}

#video-escaner-qr {
  width: 100%;
  border-radius: var(--radio-chico);
  background: #000;
  aspect-ratio: 1 / 1;
  object-fit: cover;
}

.mensaje-error-escaner {
  color: var(--color-danger);
}

.feed-escaneo-qr-item {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.35rem 0;
  font-size: 0.875rem;
}

.form-pago-inline {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex-wrap: wrap;
}

/* Una fila por jugador en el selector de tallas de uniforme (Generar
   cobros) — reusa .form-pago-inline como base y solo agrega separación
   entre jugadores cuando hay varios en la lista. */
.fila-talla-jugador {
  justify-content: space-between;
  padding: 0.4rem 0;
  border-bottom: 1px solid var(--color-border);
}

.fila-talla-jugador:last-child {
  border-bottom: none;
}

.form-pago-inline input,
.form-pago-inline select {
  padding: 0.3rem 0.5rem;
  border: 1px solid var(--color-border);
  border-radius: 6px;
  font-size: 0.8rem;
}

.input-justificacion {
  margin-top: 0.4rem;
  padding: 0.35rem 0.6rem;
  border: 1px solid var(--color-border);
  border-radius: 6px;
  font-size: 0.8rem;
  width: 100%;
  max-width: 220px;
}

/* ---------- Portal de representantes ---------- */

.grilla-hijos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
  gap: 1.25rem;
}

.tarjeta-hijo {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radio-base);
  box-shadow: var(--sombra-tarjeta);
  border-left: 4px solid var(--color-primary);
  padding: 1.25rem;
  /* Corrección 2026-09-15 (bug reportado por el usuario en celular: el
     portal se veía descuadrado, con scroll horizontal para ver el nav) --
     por defecto, un hijo de grid no se achica por debajo del ancho
     mínimo de su contenido ("min-width: auto" implícito), así que un
     párrafo largo (la descripción del carnet) o el propio carnet podían
     forzar la tarjeta -- y con ella toda la página -- a desbordar hacia
     la derecha en vez de ajustarse al ancho de la columna 1fr que ya le
     da .grilla-hijos en el breakpoint de celular. min-width: 0 vuelve a
     dejar que se achique de verdad y el contenido de adentro envuelva
     normalmente. Mismo patrón ya usado en .barra-superior-izquierda. */
  min-width: 0;
}

.tarjeta-hijo-encabezado {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 1rem;
}

.tarjeta-hijo-encabezado h3 {
  margin: 0;
  font-size: 1.05rem;
}

.tarjeta-hijo-encabezado p {
  margin: 0.15rem 0 0;
}

/* Cada sección del perfil del hijo es un <details> colapsable
   (2026-09-22, a pedido del usuario: el perfil se volvía un scroll muy
   largo con todo desplegado a la vez) -- solo el carnet empieza abierto
   (ver crearTarjetaHijo() en portal.html), el resto arranca cerrado y
   se expande al tocar su título. */
.tarjeta-hijo-seccion {
  margin-top: 0.75rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--color-border);
}

.tarjeta-hijo-seccion summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  cursor: pointer;
  list-style: none;
  -webkit-tap-highlight-color: transparent;
  /* área de toque cómoda en celular sin agrandar visualmente el texto */
  padding: 0.25rem 0;
  margin: -0.25rem 0;
}

.tarjeta-hijo-seccion summary::-webkit-details-marker {
  display: none;
}

.tarjeta-hijo-seccion summary::after {
  content: '';
  flex-shrink: 0;
  width: 0.45rem;
  height: 0.45rem;
  border-right: 2px solid var(--color-text-muted);
  border-bottom: 2px solid var(--color-text-muted);
  transform: rotate(45deg);
  transition: transform 0.15s ease;
}

.tarjeta-hijo-seccion[open] summary::after {
  transform: rotate(-135deg);
}

.tarjeta-hijo-seccion h4 {
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--color-text);
  margin: 0;
}

.tarjeta-hijo-seccion-cabecera {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  min-width: 0;
}

.tarjeta-hijo-seccion-icono {
  flex-shrink: 0;
  width: 30px;
  height: 30px;
  border-radius: 9px;
  background: #e8ebf5;
  color: var(--color-primary);
  display: flex;
  align-items: center;
  justify-content: center;
}

.tarjeta-hijo-seccion-icono svg {
  width: 15px;
  height: 15px;
}

.tarjeta-hijo-seccion[open] summary {
  margin-bottom: 0.5rem;
}

.tarjeta-hijo-seccion .tabla-cobros {
  font-size: 0.85rem;
}

/* Skeleton loader -- reemplaza los textos "Cargando..." (2026-09-29,
   rediseño visual del portal de representante). */
.skeleton-linea {
  height: 10px;
  border-radius: 6px;
  background: linear-gradient(90deg, #e5e7eb 25%, #eef0f3 37%, #e5e7eb 63%);
  background-size: 400% 100%;
  animation: skeleton-brillo 1.4s ease infinite;
}

@keyframes skeleton-brillo {
  0% { background-position: 100% 50%; }
  100% { background-position: 0% 50%; }
}

@media (prefers-reduced-motion: reduce) {
  .skeleton-linea {
    animation: none;
    background: #e5e7eb;
  }
}

/* Ficha completa del estudiante, de solo lectura, en el dashboard de
   representantes (2026-09-15, a pedido del usuario) -- la información
   adicional ya cargada en el perfil del jugador se ve siempre, sin
   tener que abrir el formulario de edición. */
.ficha-perfil-jugador {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 0.7rem 1rem;
  margin: 0 0 0.85rem;
  min-width: 0;
}

.ficha-perfil-jugador .ficha-dato {
  min-width: 0;
}

.ficha-perfil-jugador .ficha-dato-ancho {
  grid-column: 1 / -1;
}

.ficha-perfil-jugador .ficha-dato-etiqueta {
  margin: 0 0 0.15rem;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--color-text-muted);
}

.ficha-perfil-jugador .ficha-dato-valor {
  margin: 0;
  font-size: 0.9rem;
  overflow-wrap: break-word;
}

.valor-asistencia {
  font-size: 1.4rem;
  font-weight: 700;
  margin: 0;
}

.lista-horarios {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.lista-horarios li {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  background: var(--color-bg);
  border-radius: var(--radio-chico);
  padding: 0.5rem 0.65rem;
  font-size: 0.85rem;
}

.lista-horarios-icono {
  flex-shrink: 0;
  width: 28px;
  height: 28px;
  border-radius: 8px;
  background: #e8ebf5;
  color: var(--color-primary);
  display: flex;
  align-items: center;
  justify-content: center;
}

.lista-horarios-icono svg {
  width: 14px;
  height: 14px;
}

/* Home rediseñada del portal de representante (2026-09-29, mockup
   aprobado por el usuario) -- saludo, carnet promovido a "hero",
   tarjetas "Próximo" (entrenamiento + pago pendiente) y grilla de
   accesos "Tu academia". Ver crearTarjetaHijo() en portal.html. */
.saludo-portal {
  margin-bottom: 1.1rem;
}

.saludo-portal h2 {
  font-family: 'Sora', sans-serif;
  font-size: 1.3rem;
  font-weight: 700;
  color: var(--color-marca-navy);
  margin: 0;
}

.saludo-portal-subtitulo {
  margin: 0.15rem 0 0;
  color: var(--color-text-muted);
  font-size: 0.92rem;
}

.carnet-hero-envoltorio {
  margin: 0 0 1.4rem;
}

.carnet-hero-envoltorio canvas {
  width: 100%;
  height: auto;
}

.carnet-hero-acciones {
  margin-top: 0.6rem;
}

.carnet-hero-nota {
  margin: 0.4rem 0 0;
  font-size: 0.78rem;
  color: var(--color-text-muted);
}

.bloque-portal-home {
  margin: 0 0 1.4rem;
}

.titulo-subseccion-portal {
  font-family: 'Sora', sans-serif;
  font-size: 1rem;
  font-weight: 700;
  color: var(--color-marca-navy);
  margin: 0 0 0.6rem;
}

.lista-proximo {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.tarjeta-proximo-item {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  width: 100%;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radio-base);
  padding: 0.7rem 0.9rem;
  box-shadow: var(--sombra-tarjeta);
  cursor: pointer;
  font: inherit;
  text-align: left;
  color: inherit;
  -webkit-tap-highlight-color: transparent;
}

.tarjeta-proximo-item-icono {
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  border-radius: 10px;
  background: #e8ebf5;
  color: var(--color-primary);
  display: flex;
  align-items: center;
  justify-content: center;
}

.tarjeta-proximo-item-icono svg {
  width: 18px;
  height: 18px;
}

.tarjeta-proximo-item-texto {
  flex-grow: 1;
  min-width: 0;
}

.tarjeta-proximo-item-etiqueta {
  margin: 0;
  font-size: 0.78rem;
  color: var(--color-text-muted);
}

.tarjeta-proximo-item-valor {
  margin: 0.1rem 0 0;
  font-size: 0.92rem;
  font-weight: 700;
  color: var(--color-marca-navy);
}

.tarjeta-proximo-item-chevron {
  flex-shrink: 0;
  color: #9ca3af;
  display: flex;
}

.tarjeta-proximo-item.alerta {
  background: #fff4e8;
  border-color: #fadbb2;
}

.tarjeta-proximo-item.alerta .tarjeta-proximo-item-icono {
  background: #ffe4c2;
  color: var(--color-marca-naranja-oscuro);
}

.tarjeta-proximo-item.alerta .tarjeta-proximo-item-valor {
  color: var(--color-marca-naranja-oscuro);
}

.grilla-academia {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75rem;
}

.grilla-academia-item {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.6rem;
  width: 100%;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radio-base);
  padding: 0.85rem;
  box-shadow: var(--sombra-tarjeta);
  cursor: pointer;
  font: inherit;
  text-align: left;
  color: inherit;
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
}

/* Tarjeta de entrenamiento "de hoy" (dashboard de entrenador,
   rediseño 2026-09-29) -- mismo tipo de tarjeta que .evento-tarjeta del
   calendario, con el agregado de un botón grande de acción abajo. */
.lista-entrenamientos-hoy {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.tarjeta-entrenamiento-hoy {
  background: var(--color-surface);
  border-radius: var(--radio-base);
  box-shadow: var(--sombra-tarjeta);
  padding: 0.85rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.tarjeta-entrenamiento-hoy-fila {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.tarjeta-entrenamiento-hoy-icono {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  border-radius: var(--radio-chico);
  background: #e8ebf5;
  color: var(--color-marca-navy);
}

.tarjeta-entrenamiento-hoy-icono svg {
  width: 18px;
  height: 18px;
}

.tarjeta-entrenamiento-hoy-texto {
  flex-grow: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
}

.tarjeta-entrenamiento-hoy-texto strong {
  font-size: 0.9rem;
}

.tarjeta-entrenamiento-hoy-texto .texto-muted {
  font-size: 0.78rem;
}

.boton-pasar-asistencia {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 42px;
  background: var(--color-marca-naranja-oscuro);
  color: #fff;
  border-radius: var(--radio-chico);
  font-weight: 700;
  font-size: 0.85rem;
  text-decoration: none;
}

.boton-pasar-asistencia:hover {
  background: var(--color-marca-navy);
  color: #fff;
}

.grilla-academia-item-icono {
  width: 34px;
  height: 34px;
  border-radius: 10px;
  background: #e8ebf5;
  color: var(--color-primary);
  display: flex;
  align-items: center;
  justify-content: center;
}

.grilla-academia-item-icono svg {
  width: 17px;
  height: 17px;
}

.grilla-academia-item span:last-child {
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--color-text);
}

.grilla-academia-item[data-tono='violeta'] .grilla-academia-item-icono {
  background: #ede9fe;
  color: #7c3aed;
}

.grilla-academia-item[data-tono='verde'] .grilla-academia-item-icono {
  background: var(--color-success-bg);
  color: var(--color-success);
}

/* Con un solo hijo vinculado (el caso más común) se oculta el
   avatar/nombre/estado repetido de cada tarjeta -- el carnet, justo
   debajo, ya identifica al hijo. Con más de uno, se deja como estaba
   (separador necesario entre tarjetas). Ver cargarHijos() en
   portal.html. */
.grilla-hijos-un-hijo .tarjeta-hijo-encabezado {
  display: none;
}

.lista-comunicados {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

/* Lista de mensajes en formato "chat" -- representante/mensajes.html
   (rediseño visual, 2026-09-29). Reemplaza la tabla de mensajes por
   filas tocables completas, mismo patrón visual que .lista-comunicados
   pero con avatar circular en vez de acento lateral. */
.lista-mensajes {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}

.lista-mensajes li {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.75rem 0;
  border-bottom: 1px solid var(--color-border);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.lista-mensajes li:last-child {
  border-bottom: none;
}

.lista-mensajes li:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
  border-radius: var(--radio-chico);
}

.lista-mensajes-texto {
  flex-grow: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.lista-mensajes-fila-superior {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}

.lista-mensajes-asunto {
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--color-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.lista-mensajes-fecha {
  font-size: 0.7rem;
  color: var(--color-text-muted);
  flex-shrink: 0;
}

.lista-mensajes-previsualizacion {
  font-size: 0.78rem;
  color: var(--color-text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.lista-mensajes-punto {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--color-marca-naranja);
  flex-shrink: 0;
}

/* Mensajes ya respondidos/leídos: baja de intensidad, mismo criterio que
   el mockup aprobado -- solo lo pendiente de mi respuesta se ve "vivo". */
.lista-mensajes-leido .avatar-iniciales {
  background: #9ca3af;
}

.lista-mensajes-leido .lista-mensajes-asunto {
  color: var(--color-text-muted);
  font-weight: 700;
}

/* Avatar circular con iniciales (Fase 10) -- crearAvatarIniciales() en
   academia.js. Usa --color-primary, así que ya sale con el color de
   marca de cada academia sin nada extra acá. */
.avatar-iniciales {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  background: var(--color-primary);
  color: #fff;
  font-weight: 700;
  flex-shrink: 0;
  line-height: 1;
}

/* Avatar circular con foto del jugador (Fase 11, 2026-10-03) --
   crearAvatar() en academia.js cae a .avatar-iniciales de arriba cuando
   no hay foto, así que ambas clases comparten el mismo tamaño circular
   para que no haya salto de layout al pasar de una a otra. */
.avatar-foto {
  border-radius: 999px;
  object-fit: cover;
  flex-shrink: 0;
  display: block;
}

/* Widget de subir/quitar foto del jugador (Fase 11, 2026-10-03) -- usado
   en representante/portal.html (por hijo) y admin/jugadores.html (en
   nombre del representante). Los botones reusan .boton-secundario /
   .boton-recordatorio de siempre, acá solo se acomoda el layout. */
.foto-jugador-widget {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin: 0.75rem 0;
}

.foto-jugador-widget-acciones {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.foto-jugador-widget-quitar {
  background: none;
  border: none;
  color: var(--color-error, #dc2626);
  font-size: 0.85rem;
  font-weight: 700;
  cursor: pointer;
  padding: 0.4rem 0.2rem;
}

.foto-jugador-widget-quitar:hover {
  text-decoration: underline;
}

.foto-jugador-widget-nota {
  flex-basis: 100%;
  margin: 0;
}

.lista-comunicados li {
  border: 1px solid var(--color-border);
  /* Acento de marca (Fase 9): franja izquierda con --color-primary, la
     misma variable que ya pinta el color configurado por cada academia
     (ver aplicarColorDeMarca() en academia.js) -- para que un comunicado
     se identifique de un vistazo como de esta academia, sin tocar nada
     de JS acá, ya que la variable se actualiza sola por academia. */
  border-left: 4px solid var(--color-primary);
  border-radius: 8px;
  padding: 0.6rem 0.75rem;
}

.lista-comunicados-encabezado {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  font-size: 0.85rem;
}

.lista-comunicados p {
  margin: 0.35rem 0 0;
  font-size: 0.9rem;
}

/* ---------- Página pública (index.html) ----------
   Traducción literal del diseño exportado desde Claude Design
   (web/assets/landing nueva/) a HTML/CSS plano: misma estructura, mismos
   tamaños, mismas animaciones — sin el framework de componentes del
   export (incompatible con "sin build step"). Los colores de marca
   (navy/naranja) siempre salen de las variables de :root; las variantes
   de opacidad se escriben como rgba(20, 39, 90, X) / rgba(245, 129, 30, X)
   porque son exactamente los valores RGB de --color-marca-navy /
   --color-marca-naranja (CSS no permite variar la opacidad de una
   variable sin color-mix()/relative color syntax, todavía poco fiable en
   todos los navegadores) — no es un segundo origen de verdad de color,
   son el mismo azul/naranja con transparencia. */

body.pagina-landing {
  font-family: 'DM Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  background: #fbfaf8;
}

.pagina-landing h1,
.pagina-landing h2,
.pagina-landing h3,
.pagina-landing h4 {
  font-family: 'Sora', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  margin: 0;
  letter-spacing: -0.02em;
}

.landing-ancho {
  max-width: 1440px;
  margin: 0 auto;
  overflow-x: clip;
}

@keyframes es-flotar {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-14px); }
}

@keyframes es-flotar-suave {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-7px); }
}

@keyframes es-pulso {
  0%, 100% { transform: scale(1); opacity: 1; }
  50% { transform: scale(1.35); opacity: 0.35; }
}

@keyframes es-marquee {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}

/* Resalta temporalmente una fila/tarjeta cuando se llega por deep-link
   desde una notificación (2026-09-14) -- mismo mecanismo compartido para
   cualquier pantalla sin panel de detalle propio (cobros, entrenamientos
   del entrenador, cursos vacacionales, comunicados, solicitudes de
   pre-registro, tarjetas de hijo en el portal): un parpadeo breve de
   fondo con el naranja de marca, para que la fila se note sin necesidad
   de un estado permanente que limpiar después. */
@keyframes es-resaltado-notificacion {
  0%, 100% { background-color: transparent; }
  25%, 75% { background-color: rgba(245, 129, 30, 0.25); }
}
.fila-destacada-notificacion {
  animation: es-resaltado-notificacion 2.5s ease-in-out 1;
}

/* Pantalla de bienvenida con disolvencia del logo (2026-09-15) -- se
   muestra una sola vez por pestaña, tanto en la página pública como al
   entrar al panel ya logueado (ver web/assets/splash.js). Fondo con el
   navy de marca para que el logo se note mientras aparece. */
.pantalla-bienvenida-easysports {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #ffffff;
  opacity: 1;
  transition: opacity 1.1s ease;
}
.pantalla-bienvenida-easysports.pantalla-bienvenida-saliendo {
  opacity: 0;
}
.pantalla-bienvenida-logo {
  max-width: 275px;
  width: 50vw;
  opacity: 0;
  transform: scale(0.96);
  transition: opacity 1.4s ease, transform 1.4s ease;
}
.pantalla-bienvenida-logo.pantalla-bienvenida-logo-lista {
  opacity: 1;
  transform: scale(1);
}

@keyframes es-blob {
  0%, 100% { border-radius: 58% 42% 46% 54% / 52% 48% 52% 48%; }
  33% { border-radius: 44% 56% 60% 40% / 46% 58% 42% 54%; }
  66% { border-radius: 52% 48% 40% 60% / 60% 40% 56% 44%; }
}

@media (prefers-reduced-motion: reduce) {
  .pagina-landing * {
    animation: none !important;
  }
}

/* ---------- Header ---------- */

.nav-publica {
  position: sticky;
  top: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
  padding: 1rem 2.5rem;
  background: rgba(251, 250, 248, 0.82);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid rgba(20, 39, 90, 0.08);
}

.logo-publico {
  display: inline-block;
  height: 56px;
  overflow: hidden;
  border-radius: 4px;
  flex: none;
}

.logo-publico img {
  height: 78px;
  width: auto;
  display: block;
  object-fit: cover;
  object-position: top;
}

.nav-publica-enlaces {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  font-size: 0.9375rem;
  font-weight: 500;
  white-space: nowrap;
}

.nav-publica-enlaces a {
  color: var(--color-marca-navy);
  text-decoration: none;
}

.nav-publica-enlaces a:hover {
  color: var(--color-marca-naranja);
}

.boton-nav-login {
  padding: 0.6875rem 1.25rem;
  border-radius: 999px;
  background: var(--color-marca-navy);
  color: #fbfaf8;
  text-decoration: none;
  font-size: 0.8125rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  display: inline-block;
  transition: transform 0.25s ease, background 0.25s ease;
}

.boton-nav-login:hover {
  background: var(--color-marca-naranja);
  color: #fff;
  transform: translateY(-2px);
}

/* Dos accesos en el header público (2026-09-09, texto ajustado 2026-09-10):
   "Ingreso academia o club" / "Ingreso equipo" llevan al mismo
   /login.html (el login es uno solo, el rol decide el destino),
   separados solo para que cada audiencia vea de entrada que hay una
   puerta pensada para ella. El segundo texto dice "equipo" en vez de
   "club" a propósito -- una academia real también se llama "club"
   coloquialmente en Ecuador, así que "club" solo del lado de academia
   evita que un dueño de academia piense que la otra puerta es la suya. */
.nav-publica-acciones {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  flex: none;
}

.boton-nav-login-contorno {
  background: transparent;
  color: var(--color-marca-navy);
  border: 1.5px solid var(--color-marca-navy);
}

.boton-nav-login-contorno:hover {
  background: var(--color-marca-navy);
  color: #fbfaf8;
}

#funcionalidades,
#roles,
#precios,
#faq,
#deportes {
  scroll-margin-top: 90px;
}

/* ---------- Hero ---------- */

.hero-publico {
  position: relative;
  padding: 6rem 2.5rem 2.5rem;
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  gap: 3.5rem;
  align-items: center;
}

.hero-publico-fondo {
  position: absolute;
  top: -5rem;
  left: -8.75rem;
  width: 28.75rem;
  height: 28.75rem;
  background: radial-gradient(circle, rgba(245, 129, 30, 0.16), transparent 68%);
  animation: es-flotar 12s ease-in-out infinite;
  pointer-events: none;
}

.hero-publico-texto {
  position: relative;
  max-width: 35rem;
}

.insignia-hero {
  display: inline-flex;
  align-items: center;
  gap: 0.5625rem;
  padding: 0.4375rem 0.9375rem;
  border-radius: 999px;
  border: 1px solid rgba(20, 39, 90, 0.14);
  font-family: 'IBM Plex Mono', monospace;
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin-bottom: 1.625rem;
  color: var(--color-marca-navy);
}

.punto-pulso {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--color-marca-naranja);
  animation: es-pulso 2.4s ease-in-out infinite;
  flex: none;
}

.hero-publico h1 {
  font-size: clamp(2.4rem, 4.6vw, 4.25rem);
  line-height: 1.02;
  font-weight: 700;
  margin-bottom: 1.625rem;
  color: var(--color-marca-navy);
}

.hero-publico h1 .resaltado {
  background: linear-gradient(100deg, var(--color-marca-naranja), color-mix(in srgb, var(--color-marca-naranja) 55%, white));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.hero-publico p {
  font-size: 1.25rem;
  line-height: 1.55;
  color: rgba(20, 39, 90, 0.72);
  max-width: 35rem;
  margin: 0 0 2.25rem;
}

.hero-publico-botones {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  gap: 0.875rem;
}

.hero-publico-imagen {
  position: relative;
}

.hero-publico-imagen-fondo {
  position: absolute;
  inset: -1.625rem;
  background: radial-gradient(circle at 60% 40%, rgba(20, 39, 90, 0.14), transparent 70%);
  animation: es-blob 14s ease-in-out infinite;
  pointer-events: none;
}

.hero-publico-imagen img {
  position: relative;
  width: 100%;
  height: 35rem;
  object-fit: cover;
  display: block;
  border-radius: 60% 40% 46% 54% / 52% 48% 52% 48%;
  animation: es-blob 16s ease-in-out infinite, es-flotar-suave 9s ease-in-out infinite;
  box-shadow: 0 24px 48px rgba(20, 39, 90, 0.3);
}

.hero-publico-chip {
  position: absolute;
  bottom: 1.625rem;
  left: -1.125rem;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  padding: 1rem 1.25rem;
  border-radius: 20px;
  background: #fbfaf8;
  box-shadow: 0 18px 40px rgba(20, 39, 90, 0.16);
  animation: es-flotar-suave 7s ease-in-out infinite;
  max-width: 220px;
}

.hero-publico-chip-etiqueta {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  color: rgba(20, 39, 90, 0.55);
  text-transform: uppercase;
}

.hero-publico-chip-valor {
  font-family: 'Sora', sans-serif;
  font-size: 0.9375rem;
  font-weight: 700;
  color: var(--color-marca-naranja);
}

/* ---------- Carrusel de deportes ---------- */

.marquee-deportes {
  overflow: hidden;
  padding: 1.75rem 0 4.5rem;
  mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}

.marquee-deportes-pista {
  display: flex;
  width: max-content;
  gap: 3.5rem;
  animation: es-marquee 26s linear infinite;
  font-family: 'Sora', sans-serif;
  font-size: 1.375rem;
  font-weight: 500;
  color: rgba(20, 39, 90, 0.34);
  white-space: nowrap;
}

/* ---------- Animación de aparición al hacer scroll ---------- */

.por-revelar {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity 0.7s cubic-bezier(0.2, 0.8, 0.2, 1), transform 0.7s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.por-revelar.revelado {
  opacity: 1;
  transform: none;
}

/* ---------- Botones CTA ---------- */

.boton-cta-naranja,
.boton-cta-contorno,
.boton-cta-navy,
.boton-cta-contorno-navy {
  padding: 1rem 1.875rem;
  border-radius: 999px;
  font-weight: 600;
  text-decoration: none;
  font-size: 1rem;
  display: inline-block;
  text-align: center;
  transition: transform 0.28s cubic-bezier(0.2, 0.8, 0.2, 1), box-shadow 0.28s ease, background 0.25s ease, border-color 0.25s ease, color 0.25s ease;
}

.boton-cta-naranja {
  background: var(--color-marca-naranja);
  color: #fff;
  box-shadow: 0 14px 34px rgba(245, 129, 30, 0.32);
}

.boton-cta-naranja:hover {
  transform: translateY(-3px) scale(1.02);
  box-shadow: 0 22px 44px rgba(245, 129, 30, 0.4);
  color: #fff;
}

.boton-cta-contorno {
  border: 1.5px solid rgba(20, 39, 90, 0.2);
  color: var(--color-marca-navy);
}

.boton-cta-contorno:hover {
  transform: translateY(-3px);
  border-color: var(--color-marca-navy);
}

.boton-cta-navy {
  background: var(--color-marca-navy);
  color: #fff;
}

.boton-cta-navy:hover {
  background: var(--color-marca-navy-oscuro);
  transform: translateY(-3px);
  color: #fff;
}

.boton-cta-contorno-navy {
  border: 1.5px solid rgba(20, 39, 90, 0.2);
  color: var(--color-marca-navy);
  background: transparent;
}

.boton-cta-contorno-navy:hover {
  border-color: var(--color-marca-navy);
  transform: translateY(-2px);
}

/* ---------- Comparación: "Sin sistema" vs. "Con EasySports" ---------- */

.seccion-comparacion {
  max-width: 1100px;
  margin: 0 auto;
  padding: 0 2.5rem 6.875rem;
}

.seccion-comparacion h2,
.seccion-funcionalidades h2,
.seccion-roles h2,
.seccion-precios h2,
.seccion-equipo h2,
.seccion-faq h2 {
  font-size: 2.75rem;
  line-height: 1.1;
  margin-bottom: 1.125rem;
  color: var(--color-marca-navy);
}

.seccion-comparacion h2,
.seccion-funcionalidades h2 {
  max-width: 47.5rem;
}

/* Sección "Plantel Amateur": a diferencia de los planes de academia (donde
   predomina el navy), acá el naranja es el color protagonista -- refuerza
   con color que es un servicio aparte, no un cuarto plan de academia. */
.seccion-equipo h2 {
  color: var(--color-marca-naranja);
}

.seccion-subtitulo-izq {
  font-size: 1.1875rem;
  color: rgba(20, 39, 90, 0.68);
  max-width: 40rem;
  margin: 0 0 3rem;
}

.comparacion-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.5rem;
}

.columna-comparacion {
  border-radius: 28px;
  padding: 2.125rem;
}

.columna-comparacion h3 {
  font-size: 1.375rem;
  margin-bottom: 1.375rem;
}

.columna-comparacion ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.875rem;
}

.columna-comparacion li {
  display: flex;
  align-items: flex-start;
  gap: 0.8125rem;
  font-size: 1.03125rem;
  line-height: 1.5;
}

.viñeta-rombo {
  flex: none;
  width: 9px;
  height: 9px;
  margin-top: 0.5rem;
  background: rgba(20, 39, 90, 0.3);
  transform: rotate(45deg);
}

.viñeta-punto {
  flex: none;
  width: 10px;
  height: 10px;
  margin-top: 0.4375rem;
  border-radius: 50%;
  background: var(--color-marca-naranja);
}

.columna-problema {
  background: rgba(20, 39, 90, 0.03);
  border: 1.5px dashed rgba(20, 39, 90, 0.22);
}

.columna-problema h3 {
  color: rgba(20, 39, 90, 0.6);
}

.columna-problema li {
  color: rgba(20, 39, 90, 0.66);
}

.columna-solucion {
  position: relative;
  background: var(--color-marca-navy);
  color: #fbfaf8;
  overflow: hidden;
  box-shadow: 0 24px 60px rgba(20, 39, 90, 0.28);
}

.columna-solucion-fondo {
  position: absolute;
  top: -4.375rem;
  right: -4.375rem;
  width: 13.75rem;
  height: 13.75rem;
  background: radial-gradient(circle, rgba(245, 129, 30, 0.55), transparent 65%);
  animation: es-flotar 10s ease-in-out infinite;
  pointer-events: none;
}

.columna-solucion h3 {
  position: relative;
  color: #fbfaf8;
}

.columna-solucion li {
  position: relative;
  color: rgba(251, 250, 248, 0.86);
}

/* ---------- Funcionalidades ---------- */

.seccion-funcionalidades {
  max-width: 1100px;
  margin: 0 auto;
  padding: 0 2.5rem 2.5rem;
}

.grilla-funcionalidades {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.375rem;
}

.tarjeta-funcionalidad {
  padding: 1.875rem;
  border-radius: 26px;
  background: #fff;
  border: 1px solid rgba(20, 39, 90, 0.08);
  transition: transform 0.35s cubic-bezier(0.2, 0.8, 0.2, 1), box-shadow 0.35s ease, border-color 0.35s ease;
}

.tarjeta-funcionalidad:hover {
  transform: translateY(-6px);
  box-shadow: 0 22px 48px rgba(20, 39, 90, 0.12);
  border-color: rgba(245, 129, 30, 0.4);
}

.icono-funcionalidad {
  width: 44px;
  height: 44px;
  margin-bottom: 1.25rem;
  display: grid;
  place-items: center;
  border-radius: 14px;
  background: rgba(245, 129, 30, 0.12);
}

.icono-funcionalidad svg {
  width: 24px;
  height: 24px;
  color: var(--color-marca-naranja);
}

.tarjeta-funcionalidad h3 {
  font-size: 1.1875rem;
  margin-bottom: 0.625rem;
  color: var(--color-marca-navy);
}

.tarjeta-funcionalidad p {
  margin: 0;
  font-size: 1rem;
  line-height: 1.55;
  color: rgba(20, 39, 90, 0.68);
}

/* ---------- Fotos con degradado y contenido superpuesto
   (Próximamente / Deportes) ---------- */

.franja-foto-superpuesta {
  position: relative;
  margin: 5.625rem 0 6.875rem;
  padding: 0 2.5rem;
}

.foto-superpuesta {
  position: relative;
  border-radius: 36px;
  overflow: hidden;
}

.foto-superpuesta img {
  width: 100%;
  height: 32.5rem;
  object-fit: cover;
  display: block;
}

.foto-superpuesta-navy {
  background: var(--color-marca-navy);
}

.foto-superpuesta-navy img {
  opacity: 0.55;
}

.foto-superpuesta-degradado {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.foto-superpuesta-degradado-diagonal {
  background: linear-gradient(95deg, var(--color-marca-navy) 6%, rgba(20, 39, 90, 0.86) 42%, rgba(20, 39, 90, 0) 82%);
}

.foto-superpuesta-degradado-mascara {
  background: linear-gradient(180deg, transparent 0%, var(--color-marca-navy) 96%);
  mix-blend-mode: multiply;
}

.foto-superpuesta-contenido {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  gap: 1.625rem;
  padding: 3.5rem;
  color: #fbfaf8;
}

.foto-superpuesta-contenido-centrado {
  justify-content: center;
  max-width: 41.25rem;
}

.foto-superpuesta-contenido-abajo {
  justify-content: flex-end;
}

.foto-superpuesta-contenido h2,
.foto-superpuesta-contenido h3 {
  color: #fbfaf8;
}

.foto-superpuesta-contenido-centrado h3 {
  font-size: 2.25rem;
  line-height: 1.12;
}

.foto-superpuesta-contenido-abajo h2 {
  font-size: 3.25rem;
  line-height: 1.06;
  max-width: 45rem;
}

.pildoras-proximamente {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
}

.pildora-proximamente {
  display: flex;
  align-items: center;
  gap: 0.6875rem;
  padding: 0.8125rem 1.25rem;
  border-radius: 999px;
  border: 1px solid rgba(251, 250, 248, 0.28);
  background: rgba(251, 250, 248, 0.08);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  font-size: 1rem;
  font-weight: 500;
  transition: transform 0.3s ease, background 0.3s ease;
}

.pildora-proximamente:hover {
  transform: translateY(-3px);
  background: rgba(245, 129, 30, 0.22);
}

.pildora-proximamente-etiqueta {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 0.6875rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(251, 250, 248, 0.6);
}

.pildoras-deportes {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
}

.pildora-deporte {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  padding: 0.875rem 1.5rem;
  border-radius: 999px;
  background: rgba(251, 250, 248, 0.1);
  border: 1px solid rgba(251, 250, 248, 0.25);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  color: #fbfaf8;
  font-family: 'Sora', sans-serif;
  font-size: 1.0625rem;
  font-weight: 500;
  transition: transform 0.3s cubic-bezier(0.2, 0.8, 0.2, 1), background 0.3s ease;
}

.pildora-deporte:hover {
  transform: translateY(-4px) scale(1.04);
  background: var(--color-marca-naranja);
}

.anillo-deporte {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  border: 2px solid var(--color-marca-naranja);
  animation: es-flotar-suave 6s ease-in-out infinite;
  flex: none;
}

/* ---------- Roles ---------- */

.seccion-roles {
  max-width: 1100px;
  margin: 0 auto;
  padding: 0 2.5rem 6.875rem;
}

.grilla-roles {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.375rem;
}

.tarjeta-rol {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  padding: 2.125rem;
  border-radius: 28px;
  background: #fff;
  border: 1px solid rgba(20, 39, 90, 0.08);
  transition: transform 0.35s cubic-bezier(0.2, 0.8, 0.2, 1), box-shadow 0.35s ease;
}

.tarjeta-rol:hover {
  transform: translateY(-6px);
  box-shadow: 0 24px 52px rgba(20, 39, 90, 0.12);
}

.numero-rol {
  display: block;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 0.75rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-marca-naranja);
}

.tarjeta-rol h3 {
  font-size: 1.5rem;
  line-height: 1.15;
  color: var(--color-marca-navy);
}

.tarjeta-rol ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  font-size: 1rem;
  line-height: 1.5;
  color: rgba(20, 39, 90, 0.7);
}

.tarjeta-rol li {
  display: flex;
  gap: 0.75rem;
}

.tarjeta-rol li::before {
  content: "";
  flex: none;
  width: 18px;
  height: 1px;
  margin-top: 0.75rem;
  background: var(--color-marca-naranja);
}

/* ---------- Precios ---------- */

.seccion-precios {
  max-width: 1100px;
  margin: 0 auto;
  padding: 0 2.5rem 6.875rem;
}

.seccion-precios .seccion-subtitulo-izq {
  margin-bottom: 2rem;
}

.toggle-facturacion {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 0.375rem;
  padding: 0.375rem;
  border-radius: 999px;
  background: rgba(20, 39, 90, 0.06);
  margin-bottom: 2.5rem;
}

.boton-toggle {
  border: none;
  cursor: pointer;
  background: transparent;
  padding: 0.6875rem 1.25rem;
  border-radius: 999px;
  font-family: 'DM Sans', sans-serif;
  font-size: 0.9375rem;
  font-weight: 600;
  color: rgba(20, 39, 90, 0.65);
  display: flex;
  align-items: center;
  gap: 0.4rem;
  white-space: nowrap;
  transition: background 0.3s ease, color 0.3s ease;
}

.boton-toggle.activo {
  background: var(--color-marca-navy);
  color: #fbfaf8;
}

.etiqueta-descuento {
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--color-marca-naranja);
}

.boton-toggle.activo .etiqueta-descuento {
  color: #ffd9a8;
}

.grilla-precios {
  display: grid;
  /* 4 tramos de precio fijo desde 2026-09-22 (Premium salió de esta
     grilla -- ahora es un bloque .tarjeta-precio-banner aparte, junto
     con el de implementación). repeat(4, 1fr) los reparte parejos en
     el ancho de .seccion-precios (1100px); en mobile pasan a 1fr. */
  /* minmax(0, 1fr) en vez de 1fr a secas: sin el 0 cada columna hereda
     min-width:auto y compite por su min-content (el número de precio en
     Estándar, con fuente grande y "MÁS POPULAR", es el que más pide) --
     eso dejaba a esa tarjeta angosta y el texto envuelto palabra por
     palabra. Con minmax(0, 1fr) las 4 columnas se reparten el ancho
     parejo de verdad. */
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1.375rem;
  /* stretch (no start): las 4 tarjetas deben quedar a la misma altura --
     Estándar es más alta por la etiqueta "MÁS POPULAR" y su lista más
     larga. Con stretch todas igualan la altura de la fila, y .precio-lista
     (flex-grow: 1, ver más abajo) absorbe el espacio extra empujando el
     botón de cada tarjeta al mismo nivel abajo. */
  align-items: stretch;
  margin-bottom: 1.625rem;
}

.tarjeta-precio {
  display: flex;
  flex-direction: column;
  gap: 1.125rem;
  padding: 2.125rem;
  border-radius: 28px;
  background: #fff;
  border: 1px solid rgba(20, 39, 90, 0.08);
  position: relative;
  min-width: 0;
  transition: transform 0.35s ease, box-shadow 0.35s ease;
}

.tarjeta-precio:not(.tarjeta-precio-popular):hover {
  transform: translateY(-5px);
  box-shadow: 0 22px 48px rgba(20, 39, 90, 0.1);
}

.tarjeta-precio h3 {
  font-size: 1.5rem;
  color: var(--color-marca-navy);
}

.precio-rango {
  margin: 0;
  font-size: 0.96875rem;
  color: rgba(20, 39, 90, 0.6);
}

.precio-valor {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.25rem;
  min-width: 0;
}

.precio-monto {
  font-family: 'Sora', sans-serif;
  font-size: 2.875rem;
  font-weight: 700;
  color: var(--color-text);
}

.precio-periodo {
  font-size: 1rem;
  color: rgba(20, 39, 90, 0.6);
}

.precio-nota-facturacion {
  margin: 0;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 0.75rem;
  color: rgba(20, 39, 90, 0.5);
}

.precio-lista {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.6875rem;
  flex-grow: 1;
}

.precio-lista li {
  font-size: 1rem;
  color: rgba(20, 39, 90, 0.72);
  padding-left: 1.3rem;
  position: relative;
  line-height: 1.4;
}

.precio-lista li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.5em;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--color-marca-naranja);
}

.precio-lista li.precio-lista-heredado {
  font-style: italic;
  color: rgba(20, 39, 90, 0.55);
  padding-left: 0;
}

.precio-lista li.precio-lista-heredado::before {
  display: none;
}

.boton-precio-cta {
  margin-top: 0.5rem;
}

.tarjeta-precio-popular {
  padding: 2.5rem 2.125rem;
  background: var(--color-marca-navy);
  color: #fbfaf8;
  overflow: hidden;
  box-shadow: 0 28px 64px rgba(20, 39, 90, 0.3);
  transition: transform 0.35s ease;
}

.tarjeta-precio-popular-fondo {
  position: absolute;
  bottom: -5.625rem;
  left: -3.75rem;
  width: 16.25rem;
  height: 16.25rem;
  background: radial-gradient(circle, rgba(245, 129, 30, 0.45), transparent 66%);
  animation: es-flotar 11s ease-in-out infinite;
  pointer-events: none;
}

.tarjeta-precio-popular h3,
.tarjeta-precio-popular .precio-monto {
  position: relative;
  color: #fbfaf8;
}

.tarjeta-precio-popular .precio-rango,
.tarjeta-precio-popular .precio-periodo {
  position: relative;
  color: rgba(251, 250, 248, 0.7);
}

.tarjeta-precio-popular .precio-nota-facturacion {
  position: relative;
  color: rgba(251, 250, 248, 0.55);
}

.tarjeta-precio-popular .precio-lista {
  position: relative;
  color: rgba(251, 250, 248, 0.85);
}

.tarjeta-precio-popular .precio-lista li {
  color: rgba(251, 250, 248, 0.85);
}

.tarjeta-precio-popular .precio-lista li.precio-lista-heredado {
  color: rgba(251, 250, 248, 0.6);
}

.etiqueta-popular {
  position: relative;
  align-self: flex-start;
  padding: 0.375rem 0.875rem;
  border-radius: 999px;
  background: var(--color-marca-naranja);
  color: #fff;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin: 0;
  display: inline-block;
}

.nota-precios {
  margin: 1.625rem 0 0;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 0.75rem;
  color: rgba(20, 39, 90, 0.5);
}

/* Bloques largos debajo de la grilla de 4 -- plan Premium ("a convenir")
   y la asistencia de implementación (pago único). No encajan en tarjetas
   verticales angostas porque su contenido es una sola oferta, no una
   lista de features por nivel; van en formato horizontal de ancho
   completo, apilados en mobile. */
.tarjeta-precio-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
  padding: 2.125rem 2.5rem;
  border-radius: 28px;
  background: #fff;
  border: 1px solid rgba(20, 39, 90, 0.08);
  margin-bottom: 1.125rem;
  transition: transform 0.35s ease, box-shadow 0.35s ease;
}

.tarjeta-precio-banner:hover {
  transform: translateY(-3px);
  box-shadow: 0 22px 48px rgba(20, 39, 90, 0.1);
}

.tarjeta-precio-banner:last-of-type {
  margin-bottom: 1.625rem;
}

.tarjeta-precio-banner-info {
  flex: 1 1 60%;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.tarjeta-precio-banner-info h3 {
  margin: 0;
  font-size: 1.5rem;
  color: var(--color-marca-navy);
}

.tarjeta-precio-banner-cta {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.375rem;
  flex: 0 0 auto;
  text-align: right;
}

.tarjeta-precio-banner-cta .precio-valor {
  justify-content: flex-end;
}

.tarjeta-precio-banner-cta .boton-precio-cta {
  margin-top: 0.375rem;
}

/* Variante liviana: la asistencia de implementación es un cobro único y
   secundario frente al plan Premium -- no debe competir en peso visual,
   así que baja padding, tipografía y sombra frente a .tarjeta-precio-banner
   a secas. */
.tarjeta-precio-banner-secundaria {
  padding: 1.375rem 2rem;
  background: rgba(20, 39, 90, 0.025);
  border: 1px dashed rgba(20, 39, 90, 0.15);
  box-shadow: none;
}

.tarjeta-precio-banner-secundaria:hover {
  transform: none;
  box-shadow: none;
}

.tarjeta-precio-banner-secundaria .tarjeta-precio-banner-info h3 {
  font-size: 1.125rem;
}

.tarjeta-precio-banner-secundaria .precio-rango {
  font-size: 0.875rem;
}

.tarjeta-precio-banner-secundaria .precio-monto {
  font-size: 1.75rem;
}

/* ---------- Club Amateur (equipo) ---------- */

.seccion-equipo {
  max-width: 1100px;
  margin: 0 auto;
  padding: 0 2.5rem 6.875rem;
}

.seccion-equipo .seccion-subtitulo-izq {
  margin-bottom: 2.5rem;
}

.grilla-equipo {
  display: grid;
  grid-template-columns: 1.15fr 0.85fr;
  gap: 2.5rem;
  align-items: center;
}

.lista-equipo {
  gap: 1.125rem;
}

.lista-equipo li {
  font-size: 1.0625rem;
}

/* Mismo molde de .tarjeta-precio (fondo blanco, no un cuarto plan de
   academia con fondo navy sólido como .tarjeta-precio-popular) -- el
   naranja es el acento: borde, título y botón, no el fondo entero. */
.tarjeta-precio-equipo {
  border: 1.5px solid var(--color-marca-naranja);
  box-shadow: 0 22px 48px rgba(245, 129, 30, 0.14);
}

.tarjeta-precio-equipo h3 {
  color: var(--color-marca-naranja);
}

/* Roadmap propio de la sección club (2026-09-09) -- mismo componente
   .pildora-proximamente de la franja general "Próximamente en la
   plataforma", pero esa franja vive sobre una foto oscura (texto blanco,
   fondo translúcido claro) y acá el fondo de la sección es blanco -- sin
   este override las píldoras quedarían casi invisibles (blanco sobre
   blanco). Mismo criterio de "no reproducir código, solo adaptar color"
   que el resto del proyecto. */
.proximamente-club {
  margin-top: 3rem;
  padding-top: 2.5rem;
  border-top: 1px solid var(--color-border);
}

.proximamente-club-titulo {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 0.8125rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin: 0 0 1rem;
}

.proximamente-club .pildora-proximamente {
  border: 1px solid var(--color-border);
  background: #f1f2f4;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  color: var(--color-marca-navy);
}

.proximamente-club .pildora-proximamente:hover {
  background: rgba(245, 129, 30, 0.12);
}

.proximamente-club .pildora-proximamente-etiqueta {
  color: var(--color-text-muted);
}

/* ---------- FAQ ---------- */

.seccion-faq {
  max-width: 1100px;
  margin: 0 auto;
  padding: 0 2.5rem 6.875rem;
  display: grid;
  grid-template-columns: 0.8fr 1.2fr;
  gap: 3.5rem;
  align-items: start;
}

.lista-faq {
  display: flex;
  flex-direction: column;
  gap: 0.875rem;
}

.item-faq {
  border-radius: 22px;
  background: #fff;
  border: 1px solid rgba(20, 39, 90, 0.09);
  transition: border-color 0.3s ease, box-shadow 0.3s ease;
}

.item-faq.abierto {
  border-color: rgba(245, 129, 30, 0.45);
  box-shadow: 0 18px 40px rgba(20, 39, 90, 0.1);
}

.item-faq-pregunta {
  width: 100%;
  cursor: pointer;
  border: none;
  background: transparent;
  padding: 1.625rem 1.75rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1.5rem;
  text-align: left;
  font: inherit;
}

.item-faq-pregunta h3 {
  font-size: 1.1875rem;
  line-height: 1.3;
  color: var(--color-text);
}

.item-faq-icono {
  flex: none;
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: rgba(20, 39, 90, 0.07);
  color: var(--color-marca-navy);
  font-size: 1.125rem;
  line-height: 1;
  transition: transform 0.35s cubic-bezier(0.2, 0.8, 0.2, 1), background 0.3s ease, color 0.3s ease;
}

.item-faq.abierto .item-faq-icono {
  background: var(--color-marca-naranja);
  color: #fff;
  transform: rotate(135deg);
}

.item-faq-respuesta {
  overflow: hidden;
  max-height: 0;
  opacity: 0;
  margin-top: 0;
  transition: max-height 0.45s cubic-bezier(0.2, 0.8, 0.2, 1), opacity 0.35s ease, margin-top 0.35s ease;
  padding: 0 1.75rem;
}

.item-faq.abierto .item-faq-respuesta {
  max-height: 220px;
  opacity: 1;
  margin-top: -0.5rem;
  padding-bottom: 1.625rem;
}

.item-faq-respuesta p {
  margin: 0;
  font-size: 1.03125rem;
  line-height: 1.55;
  color: rgba(20, 39, 90, 0.7);
}

/* ---------- Cierre ---------- */

.franja-cierre {
  padding: 0 2.5rem 7.5rem;
}

.franja-cierre-tarjeta {
  position: relative;
  overflow: hidden;
  padding: 5.25rem 3.75rem;
  border-radius: 40px;
  background: linear-gradient(120deg, var(--color-marca-navy), var(--color-marca-navy-oscuro));
  color: #fbfaf8;
  text-align: center;
}

.franja-cierre-fondo {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(circle at 12% -20%, rgba(245, 129, 30, 0.4), transparent 40%),
    radial-gradient(circle at 92% 120%, rgba(245, 129, 30, 0.28), transparent 42%);
}

.franja-cierre-tarjeta h2,
.franja-cierre-tarjeta a {
  position: relative;
}

.franja-cierre-tarjeta h2 {
  font-size: 3.125rem;
  line-height: 1.08;
  max-width: 51.25rem;
  margin: 0 auto 1.875rem;
  color: #fbfaf8;
}

/* ---------- Pie de página ---------- */

.pie-landing {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1.5rem;
  padding: 1.875rem 2.5rem 2.75rem;
  border-top: 1px solid rgba(20, 39, 90, 0.1);
  font-size: 0.90625rem;
  color: rgba(20, 39, 90, 0.6);
}

.pie-landing img {
  height: 2.75rem;
  width: auto;
  display: block;
}

.pie-landing-enlaces {
  display: flex;
  gap: 1.25rem;
}

.pie-landing-enlaces a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 0.15rem;
}
/* ---------- Calendario (admin/entrenador/representante) ----------
   Motor compartido en web/assets/calendario.js, montado dentro de un
   contenedor vacío por cada pantalla. En desktop se ve el grid mensual; en
   celular (breakpoint de abajo) se oculta el grid y se muestra en su lugar
   una agenda cronológica — un grid de 7 columnas es ilegible en una
   pantalla angosta, mismo motivo por el que Google Calendar también
   cambia a lista en mobile. Ambas vistas se arman en cada render a partir
   de los mismos eventos ya cargados, no hay una segunda consulta. */

.calendario-encabezado {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 1rem;
}

.calendario-nav {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.calendario-nav h3 {
  margin: 0;
  min-width: 160px;
  text-align: center;
  color: var(--color-primary);
  text-transform: capitalize;
}

.calendario-acciones {
  display: flex;
  gap: 0.5rem;
}

.leyenda-calendario {
  display: flex;
  gap: 1.25rem;
  flex-wrap: wrap;
  margin-bottom: 1rem;
  font-size: 0.85rem;
  color: var(--color-text-muted);
}

.leyenda-item {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}

.punto-evento {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
}

.punto-evento.entrenamiento,
.pill-evento.entrenamiento {
  background: var(--color-evento-entrenamiento);
}

.punto-evento.campeonato,
.pill-evento.campeonato {
  background: var(--color-evento-campeonato);
}

.punto-evento.viaje,
.pill-evento.viaje {
  background: var(--color-evento-viaje);
}

.grid-calendario {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 1px;
  background: var(--color-border);
  border: 1px solid var(--color-border);
  border-radius: 10px;
  overflow: hidden;
}

.celda-dia-nombre {
  background: var(--color-bg);
  padding: 0.5rem;
  text-align: center;
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--color-text-muted);
}

.celda-dia {
  background: var(--color-surface);
  min-height: 92px;
  padding: 0.4rem;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  cursor: pointer;
}

.celda-dia.fuera-de-mes {
  background: var(--color-bg);
}

.celda-dia.fuera-de-mes .celda-dia-numero {
  color: var(--color-text-muted);
}

.celda-dia.hoy .celda-dia-numero {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--color-primary);
  color: #fff;
}

.celda-dia-numero {
  font-size: 0.8rem;
  font-weight: 600;
}

.pill-evento {
  border: none;
  border-radius: 6px;
  padding: 0.15rem 0.4rem;
  font-size: 0.7rem;
  color: #fff;
  text-align: left;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}

.lista-agenda-calendario {
  display: none;
}

.agenda-dia {
  padding: 0.75rem 0;
  border-bottom: 1px solid var(--color-border);
}

.agenda-dia:last-child {
  border-bottom: none;
}

.agenda-dia.hoy .agenda-dia-fecha {
  color: var(--color-primary);
}

.agenda-dia-fecha {
  margin: 0 0 0.5rem;
  font-size: 0.85rem;
  font-weight: 700;
  text-transform: capitalize;
}

.pill-evento-agenda {
  display: block;
  margin-bottom: 0.35rem;
  font-size: 0.85rem;
  padding: 0.35rem 0.6rem;
  white-space: normal;
}

/* Tarjetas de la agenda (rediseño 2026-09-29): icono + texto + chevron,
   mismo lenguaje que "Próximo" y "Tu academia" en el portal. */
.lista-eventos-agenda {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.evento-tarjeta {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  width: 100%;
  border: 1px solid transparent;
  background: var(--color-surface);
  border-radius: var(--radio-base);
  padding: 0.7rem 0.85rem;
  box-shadow: var(--sombra-tarjeta);
  cursor: pointer;
  text-align: left;
  color: inherit;
  text-decoration: none;
  font-family: inherit;
}

.evento-tarjeta-icono {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  border-radius: var(--radio-chico);
  background: #e8ebf5;
  color: var(--color-marca-navy);
}

.evento-tarjeta-icono svg {
  width: 18px;
  height: 18px;
}

.evento-tarjeta-texto {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  flex-grow: 1;
  min-width: 0;
}

.evento-tarjeta-titulo {
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--color-marca-navy);
}

.evento-tarjeta-subtitulo {
  font-size: 0.75rem;
  color: var(--color-text-muted);
}

.evento-tarjeta-chevron {
  flex-shrink: 0;
  display: flex;
  color: #9ca3af;
}

.evento-tarjeta-campeonato {
  border-color: #ede9fe;
}

.evento-tarjeta-campeonato .evento-tarjeta-icono {
  background: #ede9fe;
  color: #7c3aed;
}

.evento-tarjeta-viaje .evento-tarjeta-icono {
  background: #dcfce7;
  color: var(--color-success);
}

/* Panel de alertas del dashboard de admin (rediseño 2026-09-29): mismo
   tipo de tarjeta que el calendario, con un tono por severidad. */
.lista-tarjetas-alerta {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.tarjeta-alerta-vencido {
  border-color: #fee2e2;
}

.tarjeta-alerta-vencido .evento-tarjeta-icono {
  background: #fee2e2;
  color: var(--color-danger);
}

.tarjeta-alerta-pendiente .evento-tarjeta-icono {
  background: #fdead9;
  color: var(--color-marca-naranja-oscuro);
}

.panel-calendario {
  margin-top: 1.25rem;
  max-width: 480px;
}

.panel-calendario-encabezado {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0.75rem;
}

.panel-calendario-encabezado h3 {
  margin: 0;
}

.calendario-acciones-detalle {
  display: flex;
  gap: 0.5rem;
  margin-top: 1rem;
}

/* ---------- Responsive (celular) ----------
   Un solo breakpoint a 640px ("modo celular"): cubre cualquier teléfono en
   vertical y la mayoría en horizontal, sin entrar en el rango de tablets/
   ventanas de escritorio angostas. Todo vive acá, compartido — ninguna
   página tiene su propio CSS. La marca EasySports (header oculto / pie
   visible) ya no depende de este breakpoint -- ver la regla base más
   arriba, Fase 10. */

@media (max-width: 640px) {
  /* Tablas: el propio <table> pasa a ser el contenedor de scroll (no hace
     falta envolverlo en un div por página) — thead/tbody/tr/td conservan
     su display de tabla por dentro, así que las columnas del header siguen
     alineadas con las del body mientras se desliza. */
  .tabla-cobros {
    display: block;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    max-width: 100%;
  }

  /* Cuadrículas de tarjetas: una sola columna. */
  .grilla-indicadores,
  .perfil-academia-grilla,
  .grilla-hijos,
  .comparacion-grid,
  .grilla-funcionalidades,
  .grilla-roles,
  .grilla-precios,
  .grilla-equipo,
  .seccion-faq {
    grid-template-columns: 1fr;
  }

  /* La tarjeta "Más popular" se agranda con transform:scale en desktop —
     en una sola columna angosta eso solo la hace ver desalineada. */
  .tarjeta-precio-popular {
    transform: none;
  }

  /* Bloques largos (Premium, implementación): en desktop son una fila
     horizontal info + cta alineada a la derecha; en una columna angosta
     eso se ve apretado, así que se apilan y el cta se alinea a la
     izquierda igual que el resto del texto. */
  .tarjeta-precio-banner {
    flex-direction: column;
    align-items: flex-start;
    padding: 1.75rem 1.5rem;
    gap: 1.25rem;
  }

  .tarjeta-precio-banner-cta {
    align-items: flex-start;
    text-align: left;
    width: 100%;
  }

  .tarjeta-precio-banner-cta .precio-valor {
    justify-content: flex-start;
  }

  /* Calendario: el grid de 7 columnas es ilegible en una pantalla angosta
     (cada celda quedaría de ~45px) — se oculta y se muestra la agenda
     cronológica en su lugar, mismos eventos ya cargados. */
  .grid-calendario {
    display: none;
  }

  .lista-agenda-calendario {
    display: block;
  }

  .calendario-nav h3 {
    min-width: 0;
  }

  /* Landing pública: el nav de enlaces y el hero de dos columnas no caben
     en una pantalla de celular — el hero se apila y queda centrado, y las
     fotos con contenido superpuesto (Próximamente/Deportes) reducen su
     texto para no verse gigante en una pantalla angosta. */
  .nav-publica {
    padding: 0.75rem 1.25rem;
    flex-wrap: wrap;
    justify-content: center;
    row-gap: 0.625rem;
  }

  /* Logo 40% más grande y centrado en móvil (antes quedaba pegado a la
     izquierda porque, al apilarse en su propia línea con justify-content:
     space-between y un solo elemento en esa línea, el space-between no
     tiene nada "entre qué" repartir y lo deja al inicio). */
  .logo-publico {
    height: 78px;
  }

  .logo-publico img {
    height: 109px;
  }

  .nav-publica-enlaces {
    display: none;
  }

  /* Los dos accesos (academia/club) no caben junto al logo en una pantalla
     angosta -- en vez de recortarse contra el borde (bug real reportado
     por el usuario el 2026-09-10, capturas de pantalla en iPhone), pasan
     a ocupar toda la fila propia y se apilan en columna, uno debajo del
     otro, cada uno a ancho completo. */
  .nav-publica-acciones {
    flex-direction: column;
    align-items: stretch;
    width: 100%;
    gap: 0.5rem;
  }

  .nav-publica-acciones .boton-nav-login {
    padding: 0.625rem 0.875rem;
    font-size: 0.875rem;
    text-align: center;
    box-sizing: border-box;
  }

  .hero-publico {
    grid-template-columns: 1fr;
    padding: 3.5rem 1.25rem 1.5rem;
    text-align: center;
  }

  .hero-publico-texto {
    max-width: 100%;
  }

  .insignia-hero {
    margin-left: auto;
    margin-right: auto;
  }

  .hero-publico p {
    margin-left: auto;
    margin-right: auto;
  }

  .hero-publico-botones {
    justify-content: center;
  }

  .hero-publico-imagen img {
    height: 20rem;
  }

  .hero-publico-chip {
    left: 0;
  }

  .seccion-comparacion,
  .seccion-funcionalidades,
  .seccion-roles,
  .seccion-precios,
  .seccion-equipo,
  .seccion-faq {
    padding-left: 1.25rem;
    padding-right: 1.25rem;
  }

  .franja-foto-superpuesta {
    padding: 0 1.25rem;
  }

  .foto-superpuesta-contenido {
    padding: 1.75rem;
  }

  .foto-superpuesta-contenido-centrado h3 {
    font-size: 1.5rem;
  }

  .foto-superpuesta-contenido-abajo h2 {
    font-size: 2rem;
  }

  .franja-cierre {
    padding: 0 1.25rem 4rem;
  }

  .franja-cierre-tarjeta {
    padding: 3rem 1.5rem;
  }

  .franja-cierre-tarjeta h2 {
    font-size: 1.9rem;
  }

  .pie-landing {
    flex-direction: column;
    text-align: center;
    padding: 1.5rem 1.25rem 2rem;
  }

  /* Nav superior (Fase 10, rediseño a pedido del usuario): la versión
     anterior dejaba el nav completo visible pero deslizable
     horizontalmente ("hay que desplazarse a la derecha y se ve
     confuso"), con la campanita y "Cerrar sesión" solos en una segunda
     fila. Ahora el nav (nav-secundaria o nav-admin, según el rol) se
     oculta por completo y se abre como panel desplegable con el botón
     de hamburguesa de .boton-menu-movil (insertado por
     notificaciones.js). "Cerrar sesión" se traslada al final de ese
     mismo panel (ver más abajo) -- la fila superior queda solo con
     hamburguesa + logo + nombre a la izquierda y la campanita a la
     derecha, sin quiebre de línea. */
  .barra-superior {
    position: relative;
    flex-wrap: nowrap;
  }

  /* El nombre de la academia puede ser largo (p. ej. "[TEST] Academia QA
     EasySports") -- antes rompía a una segunda línea y eso empujaba a la
     campanita a su propia fila. Ahora se trunca con "…" en vez de
     envolver, y el logo se reduce un poco, para que hamburguesa + logo +
     nombre + campanita entren siempre en una sola fila. */
  .barra-superior-izquierda {
    flex: 1;
    min-width: 0;
  }

  .barra-superior h1 {
    flex: 1;
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .logo-academia-header {
    height: 36px;
  }

  .barra-superior-derecha {
    flex-shrink: 0;
  }

  .boton-menu-movil {
    display: inline-flex;
  }

  .nav-secundaria,
  .nav-admin {
    display: none;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    position: absolute;
    top: 100%;
    left: -1rem;
    right: -1rem;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 0 0 var(--radio-base) var(--radio-base);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
    padding: 0.5rem;
    max-height: calc(100vh - 70px);
    overflow-y: auto;
    z-index: 45;
  }

  .nav-secundaria.nav-movil-abierta,
  .nav-admin.nav-movil-abierta {
    display: flex;
  }

  /* Tipografía e iconos del panel de nav, +40% sobre el tamaño de
     escritorio (0.875rem -> 1.25rem, íconos 15px -> 22px) a pedido del
     usuario -- en celular se leen de cerca y de un vistazo, así que el
     tamaño de escritorio (pensado para cuando comparten fila con otros
     6-11 enlaces) se queda corto. Títulos en negrita, también pedido. */
  .nav-secundaria a {
    padding: 0.85rem 0.6rem;
    white-space: normal;
    border-radius: var(--radio-chico);
    font-size: 1.25rem;
    font-weight: 700;
  }

  .nav-secundaria a:hover,
  .nav-secundaria a.activo {
    background: var(--color-bg);
  }

  /* Grupos de nav-admin ("Plantel", "Actividad", "Comunicación"): en
     escritorio son un trigger + un desplegable flotante (posicionado en
     JS, ver nav-admin.js); en celular, adentro del panel ya vertical, el
     trigger ocupa todo el ancho como cualquier otro enlace. Su propio
     desplegable (position: fixed, calculado en JS a partir de la
     posición del trigger) sigue funcionando igual, sin cambios. */
  .nav-admin-grupo,
  .nav-admin-link,
  .nav-admin-grupo-trigger {
    width: 100%;
  }

  .nav-admin-link,
  .nav-admin-grupo-trigger {
    padding: 0.85rem 0.6rem;
    border-radius: var(--radio-chico);
    font-size: 1.25rem;
    font-weight: 700;
  }

  .nav-admin-link .nav-admin-icono,
  .nav-admin-grupo-trigger .nav-admin-icono {
    width: 22px;
    height: 22px;
  }

  .nav-admin-grupo-trigger svg:not(.nav-admin-icono) {
    width: 18px;
    height: 18px;
  }

  .nav-admin-grupo-trigger.abierto {
    margin: 0;
  }

  /* El enlace activo en escritorio se marca con una raya inferior de 2px
     -- en el panel apilado de celular, un enlace de ancho completo, esa
     raya se ve como una línea suelta que cruza toda la pantalla. Un
     fondo tenue (mismo tono que ya usa nav-admin-grupo-trigger.abierto)
     marca el enlace activo sin ese efecto. */
  .nav-admin-link.activo {
    padding-bottom: 0.85rem;
    border-bottom: none;
    background: rgba(20, 39, 90, 0.07);
  }

  /* "Cerrar sesión" se traslada al final del panel en celular (ver
     notificaciones.js) -- separado del resto de las opciones con un
     espacio doble, a pedido del usuario. align-items: stretch (arriba)
     ya lo estira al ancho completo del panel, como cualquier otro ítem. */
  .nav-secundaria #boton-logout,
  .nav-admin #boton-logout {
    margin-top: 2rem;
  }

  /* Botones y campos: alto mínimo ~44px (tamaño de toque cómodo). 16px de
     fuente en inputs/selects evita que iOS haga zoom automático al
     enfocarlos. */
  .boton-primario,
  .boton-secundario,
  .boton-recordatorio,
  .boton-estado,
  .boton-nav-login,
  .boton-cta-naranja,
  .boton-cta-contorno,
  .boton-cta-navy,
  .boton-cta-contorno-navy,
  .boton-toggle {
    min-height: 44px;
    font-size: 1rem;
  }

  .campo input,
  .campo select,
  .campo textarea,
  .tabla-cobros input,
  .tabla-cobros select,
  .form-pago-inline input,
  .form-pago-inline select,
  .input-justificacion {
    min-height: 44px;
    font-size: 1rem;
  }

  .checkbox-categoria input[type="checkbox"] {
    width: 1.25rem;
    height: 1.25rem;
  }

  /* El panel de notificaciones se ancla con right:0 relativo a la
     campanita, que en celular queda cerca del borde izquierdo de la
     pantalla — con el mismo ancho que en escritorio, el panel se sale
     por la izquierda. En vez de anclarlo a la campanita, pasa a fixed y
     ocupa casi todo el ancho de la pantalla, como una hoja. */
  .panel-notificaciones {
    position: fixed;
    top: 4.5rem;
    left: 1rem;
    right: 1rem;
    width: auto;
    max-width: none;
  }

  /* Desplegables de grupo (Plantel/Actividad/Comunicación) en cascada
     (Fase 10, tercera vuelta, a pedido del usuario: "que se vean que
     simplemente están unidos y caen como cascada") -- nav-admin.js los
     reubica como hijos de .nav-admin-grupo en vez de <body> cuando el
     ancho es de celular, así que acá solo hace falta que dejen de verse
     como una tarjeta flotante (position: fixed, sombra, borde propio) y
     pasen a fluir apilados debajo de su trigger, indentados para que se
     note que le pertenecen. */
  .nav-admin-grupo {
    flex-direction: column;
    align-items: stretch;
  }

  .nav-admin-grupo .nav-admin-desplegable {
    position: static;
    width: auto;
    background: transparent;
    border: none;
    box-shadow: none;
    border-radius: 0;
    padding: 0 0 0 2.4rem;
    gap: 0;
  }

  .nav-admin-grupo .nav-admin-desplegable a {
    font-size: 1.1rem;
    font-weight: 600;
    padding: 0.6rem;
    white-space: normal;
  }
}

/* ===========================================================
   Refresco visual (2026-09-10) -- tipografía, iconografía y
   matices de color aplicados a toda la app. Nació como piloto
   en el dashboard de admin (dashboard-piloto.css, ya fundido y
   borrado); tras la aprobación del usuario se extendió a las 26
   pantallas restantes. Ver conversación: "quiero que el naranja
   y el azul tengan más participación en el diseño" + pedido de
   animaciones/hover suaves. */

body {
  font-family: 'DM Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
}

main h1,
main h3,
main h4 {
  font-family: 'Sora', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  letter-spacing: -0.01em;
}

/* Encabezados de sección: ícono en una placa navy/naranja chica + texto
   en Sora, en vez del texto naranja + raya inferior. */
main h2 {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  font-family: 'Sora', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--color-text);
  padding-bottom: 0;
}

main h2::after {
  display: none;
}

.icono-seccion {
  width: 34px;
  height: 34px;
  border-radius: 10px;
  background: rgba(20, 39, 90, 0.08);
  color: var(--color-marca-navy);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: transform 0.2s ease, filter 0.2s ease;
}

.icono-seccion[data-tono='naranja'] {
  background: rgba(245, 129, 30, 0.14);
  color: var(--color-marca-naranja-oscuro);
}

.icono-seccion svg {
  width: 18px;
  height: 18px;
}

main > section:hover .icono-seccion,
.perfil-academia:hover .icono-seccion {
  transform: scale(1.08);
  filter: brightness(1.12);
}

/* ---------- Tarjetas de indicador: de bloque naranja sólido repetido a
   tarjeta clara + placa de color por métrica (navy/naranja/verde/violeta
   -- los 4 ya existen como variables de marca, no son colores nuevos). */
.tarjeta-indicador {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-top: 3px solid var(--color-border);
  display: flex;
  align-items: center;
  gap: 0.9rem;
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}

.tarjeta-indicador:hover {
  transform: translateY(-3px);
  box-shadow: 0 2px 4px rgba(16, 24, 40, 0.05), 0 10px 22px rgba(16, 24, 40, 0.1);
}

.tarjeta-indicador-icono {
  width: 42px;
  height: 42px;
  border-radius: 999px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: transform 0.2s ease, filter 0.2s ease;
}

.tarjeta-indicador-icono svg {
  width: 21px;
  height: 21px;
}

.tarjeta-indicador:hover .tarjeta-indicador-icono {
  transform: scale(1.1);
  filter: brightness(1.12);
}

.tarjeta-indicador[data-tono='navy'] {
  border-top-color: var(--color-marca-navy);
}
.tarjeta-indicador[data-tono='navy'] .tarjeta-indicador-icono {
  background: var(--color-marca-navy);
  color: #fff;
}
.tarjeta-indicador[data-tono='navy'] .valor {
  color: var(--color-marca-navy);
}

.tarjeta-indicador[data-tono='naranja'] {
  border-top-color: var(--color-marca-naranja-oscuro);
}
.tarjeta-indicador[data-tono='naranja'] .tarjeta-indicador-icono {
  background: var(--color-marca-naranja-oscuro);
  color: #fff;
}
.tarjeta-indicador[data-tono='naranja'] .valor {
  color: var(--color-marca-naranja-oscuro);
}

.tarjeta-indicador[data-tono='verde'] {
  border-top-color: var(--color-success);
}
.tarjeta-indicador[data-tono='verde'] .tarjeta-indicador-icono {
  background: var(--color-success);
  color: #fff;
}
.tarjeta-indicador[data-tono='verde'] .valor {
  color: var(--color-success);
}

.tarjeta-indicador[data-tono='violeta'] {
  border-top-color: var(--color-evento-viaje);
}
.tarjeta-indicador[data-tono='violeta'] .tarjeta-indicador-icono {
  background: var(--color-evento-viaje);
  color: #fff;
}
.tarjeta-indicador[data-tono='violeta'] .valor {
  color: var(--color-evento-viaje);
}

.tarjeta-indicador .etiqueta {
  color: var(--color-text-muted);
  margin-bottom: 0.2rem;
}

.tarjeta-indicador .valor.cargando {
  color: var(--color-text-muted);
}

/* ---------- Tarjetas contenedoras: leve elevación al pasar el mouse. */
.perfil-academia,
main > section {
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}

.perfil-academia:hover,
main > section:hover {
  transform: translateY(-2px);
  box-shadow: 0 2px 4px rgba(16, 24, 40, 0.05), 0 10px 24px rgba(16, 24, 40, 0.08);
}

/* ---------- Alertas: ícono por tipo en vez de solo la pill de texto. */
.lista-comunicados-encabezado {
  gap: 0.6rem;
}

.icono-alerta {
  width: 26px;
  height: 26px;
  border-radius: 999px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.icono-alerta svg {
  width: 14px;
  height: 14px;
}

.icono-alerta.vencido {
  background: rgba(220, 38, 38, 0.12);
  color: var(--color-danger);
}

.icono-alerta.pendiente {
  background: #eef0f3;
  color: var(--color-text-muted);
}

.lista-comunicados li {
  border-radius: var(--radio-chico);
  transition: background 0.15s ease;
}

.lista-comunicados li:hover {
  background: var(--color-bg);
}

/* ---------- Estado vacío: ícono chico + texto, en vez de solo una línea
   de texto gris. */
.estado-vacio {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  color: var(--color-text-muted);
}

.estado-vacio svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  color: var(--color-text-muted);
}

/* ---------- Encabezados de tabla con tinte navy y línea de marca sobre
   la barra superior, para sumar color corporativo sin perder el gris de
   fondo dominante. */
.tabla-cobros th {
  background: rgba(20, 39, 90, 0.05);
  color: var(--color-marca-navy);
}

.barra-superior {
  border-bottom: 3px solid transparent;
  border-image: linear-gradient(90deg, var(--color-marca-navy), var(--color-marca-naranja-oscuro)) 1;
}

/* ===========================================================
   Animaciones en botones, enlaces, pestañas y campos (2026-09-10,
   segunda vuelta) -- el usuario notó que el refresco visual anterior
   dejó afuera lo más interactivo de la app (botones, enlaces, pestañas)
   y que la mejora se sentía sobre todo en los 2 dashboards (más
   "lienzo": tarjetas de indicador, íconos de sección) y poco en las
   pantallas de tabla/formulario. Esto es intencionalmente compartido
   -- .boton-primario/.boton-secundario/.boton-pestana/a/.campo input
   los usan las 27 pantallas de la app, así que no hace falta tocar
   cada archivo de nuevo. */

a {
  transition: color 0.15s ease;
}

a:hover {
  color: var(--color-marca-naranja-oscuro);
}

.boton-primario {
  transition: background 0.2s ease, transform 0.15s ease, box-shadow 0.2s ease;
}

.boton-primario:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 16px rgba(20, 39, 90, 0.28);
}

.boton-primario:active {
  transform: translateY(0);
  box-shadow: none;
}

.boton-secundario {
  transition: background 0.2s ease, border-color 0.2s ease, color 0.2s ease, transform 0.15s ease;
}

.boton-secundario:hover {
  border-color: var(--color-marca-navy);
  color: var(--color-marca-navy);
  transform: translateY(-2px);
}

.boton-secundario:active {
  transform: translateY(0);
}

.boton-recordatorio {
  transition: background 0.2s ease, border-color 0.2s ease, transform 0.15s ease;
}

.boton-recordatorio:hover {
  transform: translateY(-2px);
  border-color: var(--color-marca-navy-oscuro);
}

.boton-estado {
  transition: background 0.2s ease, border-color 0.2s ease, color 0.2s ease, transform 0.15s ease;
}

.boton-estado:hover {
  transform: translateY(-2px);
  border-color: var(--color-marca-navy);
  color: var(--color-marca-navy);
}

.boton-pestana {
  transition: color 0.2s ease, border-color 0.25s ease, transform 0.15s ease;
}

.boton-pestana:hover {
  color: var(--color-marca-navy);
  transform: translateY(-1px);
}

.boton-pestana.activa {
  transition: color 0.2s ease, border-color 0.25s ease;
}

/* Campos: el foco pasa de un outline seco a un halo navy suave,
   consistente con el resto del refresco de color. */
.campo input,
.campo select,
.campo textarea {
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

.campo input:focus,
.campo select:focus,
.campo textarea:focus {
  outline: none;
  border-color: var(--color-marca-navy);
  box-shadow: 0 0 0 3px rgba(20, 39, 90, 0.14);
}

/* Ícono del menú superior: mismo espíritu que los íconos de sección
   (escala + brillo al pasar el mouse), quedaba afuera de la ronda
   anterior de animaciones. */
.nav-admin-icono {
  transition: transform 0.18s ease;
}

.nav-admin-link:hover .nav-admin-icono,
.nav-admin-grupo-trigger:hover .nav-admin-icono {
  transform: scale(1.15);
}

.nav-admin-desplegable a {
  transition: background 0.15s ease, color 0.15s ease, padding-left 0.15s ease;
}

.nav-admin-desplegable a:hover {
  padding-left: 16px;
}

/* Adjuntos (PDF o imagen) en mensajes de soporte, 2026-09-14 -- enlace
   con ícono de clip que arma web/assets/adjuntos-mensajes.js, tanto en
   la fila de "envío" (mensaje original) como en la de "respuesta". */
.enlace-adjunto-mensaje {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  margin-top: 0.5rem;
  font-size: 0.875rem;
  color: var(--color-primary);
  text-decoration: none;
}

.enlace-adjunto-mensaje:hover {
  text-decoration: underline;
}

/* Texto de ayuda bajo el input de archivo en los formularios de mensajes
   (límite de tamaño/tipos permitidos) -- mismo tono que .texto-muted,
   pero sin heredar su margen de párrafo. */
.ayuda-campo-archivo {
  display: block;
  margin-top: 0.3rem;
  color: var(--color-text-muted);
  font-size: 0.8rem;
}

/* Botón "Quitar archivo" junto al input[type=file] -- ver
   montarBotonQuitarAdjunto() en adjuntos-mensajes.js, 2026-09-21. */
.boton-quitar-adjunto {
  margin-left: 0.6rem;
  padding: 0;
  background: transparent;
  border: none;
  color: var(--color-danger);
  font-size: 0.8rem;
  text-decoration: underline;
  cursor: pointer;
}

.boton-quitar-adjunto:hover {
  color: var(--color-danger-oscuro, var(--color-danger));
}

/* Sistema de publicidad (2026-09-25) -- ver web/assets/anuncios.js y
   claude/plan-implementacion-publicidad-easysports.md. Dos piezas: el
   banner fijo dentro del flujo normal de una pantalla, y el pop-up de
   apertura a pantalla completa. La etiqueta "Publicidad" es obligatoria
   en los dos -- un anuncio siempre debe ser distinguible del contenido
   real, exigencia pareja de Google Play y App Store. */
.anuncio-banner-enlace {
  position: relative;
  display: block;
  border-radius: var(--radio-base);
  overflow: hidden;
  margin: 1.5rem 0;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
}
.anuncio-banner-media {
  display: block;
  width: 100%;
  max-height: 220px;
  object-fit: cover;
}
@media (min-width: 900px) {
  .anuncio-banner-media {
    max-height: 160px;
  }
}
.anuncio-etiqueta {
  position: absolute;
  top: 0.5rem;
  left: 0.5rem;
  padding: 0.15rem 0.6rem;
  border-radius: 999px;
  background: rgba(26, 29, 33, 0.65);
  color: #ffffff;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.anuncio-apertura-fondo {
  position: fixed;
  inset: 0;
  z-index: 2000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  background: rgba(12, 26, 61, 0.72);
}
.anuncio-apertura-tarjeta {
  position: relative;
  max-width: 420px;
  width: 100%;
  border-radius: var(--radio-base);
  overflow: hidden;
  background: var(--color-surface);
  box-shadow: 0 20px 45px rgba(12, 26, 61, 0.35);
}
.anuncio-apertura-media {
  display: block;
  width: 100%;
  max-height: 70vh;
  object-fit: cover;
}
.anuncio-apertura-cerrar {
  position: absolute;
  top: 0.6rem;
  right: 0.6rem;
  z-index: 1;
  width: 2rem;
  height: 2rem;
  border: none;
  border-radius: 999px;
  background: rgba(26, 29, 33, 0.65);
  color: #ffffff;
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
}
.anuncio-apertura-cerrar:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
