/* ============================================================
   _componentes.css — FNN Plataforma
   Componentes reutilizables inferidos del Figma "Nadar es vida".
   Depende de los tokens definidos en _tema.css (cargar SIEMPRE
   _tema.css antes que este fichero). No define ningún color,
   tamaño o radio directamente: todo viene de var(--...).
   ============================================================ */

/* --- Reinicio base --- */
* {
    box-sizing: border-box;
}

html {
    scroll-behavior: smooth;
}

body {
    margin: 0;
    background: var(--color-fondo);
    color: var(--color-texto);
    font-family: var(--fuente-principal);
    font-size: var(--tamano-base);
    line-height: var(--altura-linea);
}

a {
    color: inherit;
}

h1, h2, h3, h4, p, dl, dd {
    margin: 0;
}

button, input, select, textarea {
    font-family: inherit;
}

a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
.pastilla:focus-visible {
    outline: 3px solid var(--color-primario-oscuro);
    outline-offset: 2px;
}

/* Texto solo para lector de pantalla (Evaluación, 2026-07-14): el marcador
   completo/incompleta del alumno y otros indicadores puramente visuales
   necesitan un equivalente textual que NO dependa de aria-hidden en el
   propio elemento decorativo. */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* --- Layout / rejilla --- */
.contenedor {
    width: min(var(--ancho-contenido), 100%);
    margin: 0 auto;
    padding: 0 clamp(1rem, 4vw, 2rem);
}

.contenedor--ancho {
    width: min(var(--ancho-contenido-lg), 100%);
    margin: 0 auto;
    padding: 0 clamp(1rem, 4vw, 2rem);
}

.seccion {
    padding-block: var(--espaciado-xl);
}

.pila > * + * {
    margin-top: var(--espaciado-md);
}

.pila-ajustada > * + * {
    margin-top: var(--espaciado-sm);
}

/* --- Cabecera de sitio (.site-header) ---
   Portada literalmente de FNN.Public/_componentes.css (2026-07-04, al
   migrar Auth/Login.cshtml — ver docs/I18N.md y docs/DESIGN_SYSTEM.md).
   Sustituye a .cabecera-sitio/.selector-idioma, que eran un boceto previo
   sin confirmar contra el PDF y sin ninguna vista que los consumiera
   todavía (verificado con grep antes de quitarlos: cero usos en
   FNN.Monitor/Views). .site-header SÍ está confirmado contra las 13
   páginas de "Nadar es vida.pdf": "Home" a la izquierda, marca (icono +
   nombre federación) centrada, selector CAS/EUS a la derecha. */
.site-header {
    position: sticky;
    top: 0;
    z-index: 20;
    display: grid;
    /* Mobile-first: los extremos ("Home" / CAS-EUS) se ajustan a su
       contenido y la marca central ocupa el resto (puede encogerse y
       envolver texto) para no forzar overflow horizontal. En pantallas
       con más aire (ver media query) pasa a 1fr auto 1fr para un
       centrado visual exacto. */
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: var(--espaciado-sm);
    padding: var(--espaciado-md) clamp(1rem, 4vw, 4rem);
    background: var(--color-fondo-translucido);
    border-bottom: 1px solid var(--color-borde);
    backdrop-filter: blur(12px);
}

@media (min-width: 700px) {
    .site-header {
        grid-template-columns: 1fr auto 1fr;
    }
}

.site-header__inicio {
    justify-self: start;
    min-width: 0;
    color: var(--color-texto);
    /* Confirmado en el PDF: "Home" va en peso normal y a un tamaño
       notablemente mayor que el resto de la cabecera. */
    font-weight: var(--peso-normal);
    font-size: var(--tamano-xl);
    text-decoration: none;
    white-space: nowrap;
    transition: color var(--transicion-rapida);
}

.site-header__inicio:hover {
    text-decoration: underline;
}

.site-header__marca {
    display: inline-flex;
    align-items: center;
    justify-self: center;
    min-width: 0;
    gap: var(--espaciado-sm);
    color: var(--color-texto);
    text-decoration: none;
    text-align: center;
}

/* Logo oficial de cabecera (asset SVG en wwwroot/img/logo-cabecera.svg,
   copiado de FNN.Public — ver decisión 4). Solo se controla el tamaño
   por CSS (max-height/max-width); width/height "auto" mantiene la
   proporción real (626:83) sin deformarla. */
.site-header__marca-imagen {
    display: block;
    width: auto;
    height: auto;
    /* 56px (antes 40px): corrección de composición del Login pedida por
       Fermín 2026-07-04 tras comparar contra la pág. 4 del PDF ("el logo
       se ve demasiado pequeño"). Solo tamaño, la estructura de .site-header
       no se toca; la fila de grid se expande sola para acomodar el logo
       más alto, sin recortar nada. */
    max-height: 56px;
    max-width: 100%;
}

/* Confirmado en el PDF: mismo tamaño y peso (normal, no negrita) que
   "Home"; el idioma activo se distingue solo con subrayado + color. */
.site-header__idioma {
    display: flex;
    align-items: center;
    justify-self: end;
    gap: 0.15rem;
    font-size: var(--tamano-xl);
    font-weight: var(--peso-normal);
    white-space: nowrap;
}

.site-header__idioma a {
    color: var(--color-texto-suave);
    text-decoration: none;
    transition: color var(--transicion-rapida);
}

.site-header__idioma a:hover {
    color: var(--color-texto);
}

.site-header__idioma a[aria-current="true"] {
    color: var(--color-texto);
    text-decoration: underline;
    text-underline-offset: 3px;
}

/* Envoltorio del extremo derecho de la cabecera cuando hay más de un
   elemento (selector CAS/EUS + cerrar sesión): mantiene el mismo
   justify-self:end que .site-header__idioma tenía cuando era hijo directo
   de la rejilla, pero ahora aplicado al envoltorio — .site-header__idioma
   sigue funcionando igual como hijo único en Login (Login.cshtml no se
   toca). Primer consumidor: Home/Index.cshtml (única pantalla de Monitor
   con sesión iniciada que ya no usa el navbar de Bootstrap). */
/* Mobile-first en columna: el ancho "auto" que la rejilla de .site-header
   le reserva a esta celda se calcula por max-content, que ignora los
   saltos de línea de flex-wrap (por eso una fila con "CAS/EUS" + botón
   podía forzar ese ancho a la suma de ambos y dejar la columna central del
   logo a 0px — bug real detectado en verificación, no solo estético). En
   columna, el ancho máximo de contenido es el del hijo más ancho, no la
   suma, así que no puede desbordar. Pasa a fila horizontal solo a partir
   de 700px, con la cabecera entera (mismo punto de corte que el resto de
   .site-header). */
.site-header__acciones {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    justify-self: end;
    gap: var(--espaciado-xs);
}

.site-header__acciones .boton {
    width: auto;
    min-height: auto;
    padding: 0.35rem 0.75rem;
    font-size: var(--tamano-sm);
    white-space: nowrap;
}

@media (min-width: 700px) {
    .site-header__acciones {
        flex-direction: row;
        align-items: center;
        gap: var(--espaciado-md);
    }
}

/* --- Pie mínimo de sitio (.pie-sitio) ---
   Ya existía en este fichero, sin usar todavía por ninguna vista
   (verificado con grep). Encaja exactamente con la decisión 8 (pie
   mínimo para Login: copyright centrado, sin las 3 columnas ricas del
   .site-footer de Public) — se reutiliza tal cual en vez de crear un
   componente nuevo duplicado. Primer consumidor: Auth/Login.cshtml. */
.pie-sitio {
    padding: var(--espaciado-lg);
    text-align: center;
    color: var(--color-texto-suave);
    font-size: var(--tamano-sm);
}

/* --- Migas de pan ---
   "Adultos > Pasar lista", "Inicio > Inscripción Adultos > Completa
   tus datos". Título grande, sin decoración de enlace agresiva. */
.migas {
    font-size: var(--tamano-titulo);
    font-weight: var(--peso-normal);
}

.migas a {
    text-decoration: none;
}

.migas a:hover {
    text-decoration: underline;
}

/* --- Grupo de filtro: etiqueta + pastillas --- */
.grupo-filtro {
    display: grid;
    gap: var(--espaciado-sm);
}

.grupo-filtro__etiqueta {
    font-size: var(--tamano-sm);
    font-weight: var(--peso-bold);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--color-texto);
}

.grupo-filtro__opciones {
    display: flex;
    flex-wrap: wrap;
    gap: var(--espaciado-sm);
}

.filtros {
    display: grid;
    gap: var(--espaciado-lg);
    grid-template-columns: 1fr;
    align-items: start;
}

@media (min-width: 900px) {
    .filtros--dos-columnas {
        grid-template-columns: 1fr 1fr;
        column-gap: var(--espaciado-xxl);
    }

    /* Variante asimétrica (Asistencia/Elegir, 2026-07-13: PISCINA suele
       tener más opciones que NIVEL, ver docs/I18N.md). Selector compuesto
       .filtros.filtros--asimetrica para ganar siempre a la regla genérica
       ".filtros { grid-template-columns: repeat(2,1fr) }" de más abajo
       (Sistema responsive), sin depender del orden en el fichero. */
    .filtros.filtros--asimetrica {
        grid-template-columns: 3fr 2fr;
        column-gap: var(--espaciado-xxl);
    }
}

/* --- Pastilla (filtro por piscina / nivel / día / colegio / curso) ---
   Modificadores de estado: .pastilla--seleccionada / :disabled.
   Modificadores de color: .pastilla--piscina-{slug} y
   .pastilla--categoria-{slug}; aplican solo el FONDO, el resto del
   estilo (borde, tipografía) es común. */
.pastilla {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: var(--alto-minimo-touch);
    padding: 0.5rem 1rem;
    border: 1px solid var(--color-borde);
    border-radius: var(--radio-pastilla);
    background: var(--color-superficie);
    color: var(--color-texto);
    font-size: var(--tamano-sm);
    font-weight: var(--peso-normal);
    letter-spacing: 0.02em;
    text-transform: uppercase;
    text-decoration: none;
    cursor: pointer;
    transition: background var(--transicion-rapida), border-color var(--transicion-rapida);
}

.pastilla:disabled,
.pastilla[aria-disabled="true"] {
    opacity: 0.45;
    cursor: not-allowed;
}

.pastilla--seleccionada {
    border-width: 2px;
    font-weight: var(--peso-bold);
}

/* Piscinas: color fijo por instalación (ver huecos: hoy se mapea por
   nombre; migrar a Piscina.Color en cuanto exista en el modelo). */
.pastilla--piscina-color-azul     { background: var(--color-piscina-azul); }
.pastilla--piscina-color-verde    { background: var(--color-piscina-verde); }
.pastilla--piscina-color-naranja  { background: var(--color-piscina-naranja); }
.pastilla--piscina-color-amarillo { background: var(--color-piscina-amarillo); }
.pastilla--piscina-color-rosa     { background: var(--color-piscina-rosa); }
.pastilla--piscina-color-violeta  { background: var(--color-piscina-violeta); }
.pastilla--piscina-color-turquesa { background: var(--color-piscina-turquesa); }
.pastilla--piscina-color-celeste  { background: var(--color-piscina-celeste); }
.pastilla--piscina-color-salmon   { background: var(--color-piscina-salmon); }
.pastilla--piscina-color-lima     { background: var(--color-piscina-lima); }

/* Categoría: acento de la sección activa (Adultos = naranja,
   Campaña escolar = amarillo...). Se aplica a NIVEL / DÍAS / COLEGIO
   / CURSO, no a PISCINA. */
.pastilla--categoria-adultos.pastilla--seleccionada   { background: var(--color-categoria-adultos); }
.pastilla--categoria-adultos:not(.pastilla--seleccionada)   { background: var(--color-categoria-adultos-suave); border-color: var(--color-categoria-adultos-suave); color: var(--color-texto-suave); }
.pastilla--categoria-escolar.pastilla--seleccionada   { background: var(--color-categoria-escolar); }
.pastilla--categoria-escolar:not(.pastilla--seleccionada)   { background: var(--color-categoria-escolar-suave); border-color: var(--color-categoria-escolar-suave); color: var(--color-texto-suave); }
.pastilla--categoria-infantiles.pastilla--seleccionada   { background: var(--color-categoria-infantiles); }
.pastilla--categoria-infantiles:not(.pastilla--seleccionada)   { background: var(--color-categoria-infantiles-suave); border-color: var(--color-categoria-infantiles-suave); color: var(--color-texto-suave); }

/* Pastilla "pendiente" — portado de FNN.Public/_componentes.css
   (2026-07-05, Pasar lista): opción que el diseño ya muestra (pág. 7-8:
   PISCINA/NIVEL/DÍAS de contexto, Descargar) pero cuyo filtrado o
   funcionalidad real todavía no existe. Se pinta EXACTAMENTE como la
   pastilla normal (nada de atenuarla) pero sin cursor de acción, para no
   prometer una interacción que no responde. */
.pastilla--pendiente {
    cursor: default;
}

/* --- Botones ---
   .boton--categoria-* se usa para el CTA principal de cada sección
   (ENVIAR en Pasar lista/Evaluación); .boton--primario para acciones
   globales (INSCRIPCIÓN, INICIAR SESIÓN). */
.boton {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: var(--alto-minimo-touch);
    width: 100%;
    border: 1px solid transparent;
    border-radius: var(--radio-boton);
    padding: 0.85rem 1.5rem;
    font-size: var(--tamano-lg);
    font-weight: var(--peso-bold);
    text-transform: uppercase;
    letter-spacing: 0.03em;
    text-decoration: none;
    cursor: pointer;
    transition: filter var(--transicion-rapida);
}

.boton:hover {
    filter: brightness(0.96);
}

.boton:disabled {
    cursor: not-allowed;
    opacity: 0.55;
}

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

.boton--categoria-adultos { background: var(--color-categoria-adultos); color: var(--color-sobre-primario); }
.boton--categoria-escolar { background: var(--color-categoria-escolar); color: var(--color-sobre-primario); }
.boton--categoria-infantiles { background: var(--color-categoria-infantiles); color: var(--color-sobre-primario); }

.boton--secundario {
    background: var(--color-superficie);
    border-color: var(--color-borde);
    color: var(--color-texto);
}

.boton--ancho-auto {
    width: auto;
}

/* --- Tarjetas de inicio (Home: Adultos / Infantiles / Escuela...) --- */
.rejilla-inicio {
    display: grid;
    gap: var(--espaciado-md);
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
}

.tarjeta-inicio {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--color-borde);
    border-radius: var(--radio-card);
    overflow: hidden;
    background: var(--color-superficie);
    text-decoration: none;
    color: var(--color-texto);
}

.tarjeta-inicio__titulo {
    padding: var(--espaciado-md);
    font-size: var(--tamano-xl);
}

.tarjeta-inicio__imagen {
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
}

.tarjeta-inicio--activa {
    background: var(--color-primario);
}

/* Variante en acordeón (misma tarjeta, pero expandible con sub-enlaces
   Pasar lista / Evaluación / Calendario). */
.acordeon-inicio {
    border: 1px solid var(--color-borde);
    border-radius: var(--radio-card);
    overflow: hidden;
}

.acordeon-inicio__cabecera {
    display: flex;
    align-items: center;
    gap: var(--espaciado-md);
    padding: var(--espaciado-md);
    cursor: pointer;
    list-style: none;
}

.acordeon-inicio__cabecera::-webkit-details-marker {
    display: none;
}

.acordeon-inicio__miniatura {
    width: 56px;
    height: 56px;
    border-radius: var(--radio-md);
    object-fit: cover;
    flex-shrink: 0;
}

.acordeon-inicio__titulo {
    flex: 1;
    font-size: var(--tamano-xl);
}

/* Indicador + / − de despliegue para el acordeón de categorías */
.acordeon-inicio__cabecera::after {
    content: "+";
    flex: none;
    font-size: var(--tamano-xl);
    font-weight: var(--peso-bold);
    line-height: 1;
    color: var(--color-texto);
    margin-left: auto;
}

.acordeon-inicio[open] > .acordeon-inicio__cabecera::after {
    content: "\2212"; /* signo menos unicode */
}

.acordeon-inicio--activo,
.acordeon-inicio--activo .acordeon-inicio__cabecera {
    background: var(--color-primario);
}

/* Confirmado por Fermín (2026-07-04): el resaltado celeste de "Adultos" en
   el PDF es el estado :hover de la cabecera (afordancia de que la fila es
   clicable), no un dato persistente — no hay ninguna regla de negocio
   "categoría activa" que aplicar. .acordeon-inicio--activo (arriba) se deja
   tal cual, sin usar, por si en el futuro hiciera falta un estado
   persistente real; esto es solo feedback de interacción. */
.acordeon-inicio__cabecera:hover {
    background: var(--color-primario);
}

/* Fermín (2026-07-05): pasar el ratón por un submenú (Pasar lista/
   Evaluación/Calendario) también debe activar el hover de la cabecera de
   su categoría, no solo el del propio submenú — refuerza que son parte del
   mismo grupo. :hover en el <details> completo se dispara igual al pasar
   por cualquier descendiente (cabecera u opciones), así que basta con
   apuntar el fondo a la cabecera desde aquí; no hace falta JS. */
.acordeon-inicio:hover .acordeon-inicio__cabecera {
    background: var(--color-primario);
}

.acordeon-inicio__opciones a,
.acordeon-inicio__opciones .acordeon-inicio__opcion-pendiente {
    display: block;
    padding: var(--espaciado-md);
    border-top: 1px solid var(--color-borde);
    text-decoration: none;
    color: var(--color-texto);
}

/* Sub-enlace sin pantalla propia todavía (p. ej. Calendario) — visible,
   pero no navegable, para no dejar enlaces rotos (ver docs/I18N.md). */
.acordeon-inicio__opcion-pendiente {
    color: var(--color-texto-suave);
    cursor: default;
}

/* Hover también en los sub-elementos (Fermín, 2026-07-04): misma
   afordancia que la cabecera (.acordeon-inicio__cabecera:hover), aplicada
   tanto a los enlaces reales futuros como a los placeholders actuales —
   el cursor:default de arriba ya deja claro que estos últimos no navegan
   todavía, el hover es solo continuidad visual del mismo patrón. */
.acordeon-inicio__opciones a:hover,
.acordeon-inicio__opciones .acordeon-inicio__opcion-pendiente:hover {
    background: var(--color-primario);
}

/* --- Tarjeta de curso (catálogo público) --- */
.tarjeta-curso {
    display: flex;
    flex-direction: column;
    gap: var(--espaciado-sm);
    padding: var(--espaciado-lg);
    border: 1px solid var(--color-borde);
    border-radius: var(--radio-card);
    background: var(--color-superficie);
}

.tarjeta-curso__lista {
    display: flex;
    flex-wrap: wrap;
    gap: var(--espaciado-md) var(--espaciado-lg);
    color: var(--color-texto);
}

.tarjeta-curso__dato::before {
    content: "■ ";
}

/* Título de tarjeta-curso (mismo nombre que FNN.Public/_CursoCard.cshtml,
   sin estilo propio allí — aquí sí lo necesita porque Evaluación la usa
   como <a> clicable de una lista, no como ficha informativa). */
.tarjeta-curso__titulo {
    font-size: var(--tamano-lg);
    font-weight: var(--peso-bold);
}

/* Variante clicable de .tarjeta-curso (Evaluación: selección de curso,
   2026-07-14) — mismo bloque visual que el catálogo público, pero como
   <a> en vez de <article> para navegar directo a Evaluacion/Curso/{Id}.
   El acento de hover usa --color-categoria-actual (puente ya fijado en
   <main>, ver Views/Evaluacion/Index.cshtml), igual que .horario--seleccionado. */
.tarjeta-curso--enlace {
    text-decoration: none;
    color: inherit;
    cursor: pointer;
    transition: border-color var(--transicion-rapida), box-shadow var(--transicion-rapida);
}

.tarjeta-curso--enlace:hover {
    border-color: var(--color-categoria-actual, var(--color-primario));
    box-shadow: inset 0 0 0 1px var(--color-categoria-actual, var(--color-primario));
}

/* --- Panel resumen de selección (wizard de inscripción) --- */
.panel-resumen {
    padding: var(--espaciado-lg);
    border: 1px solid var(--color-borde);
    border-radius: var(--radio-card);
}

.panel-resumen__titulo {
    font-size: var(--tamano-xl);
    margin-bottom: var(--espaciado-md);
}

/* --- Formularios ---
   Etiquetas en mayúsculas con asterisco para obligatorios, campo con
   placeholder tenue, borde fino oscuro. */
.campo {
    display: grid;
    gap: var(--espaciado-xs);
}

.campo__etiqueta {
    font-size: var(--tamano-sm);
    font-weight: var(--peso-bold);
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.campo__etiqueta--requerido::after {
    content: "*";
    margin-left: 0.15em;
}

.campo input,
.campo select,
.campo textarea {
    min-height: var(--alto-minimo-touch);
    padding: 0.65rem 0.85rem;
    border: 1px solid var(--color-borde);
    border-radius: var(--radio-md);
    background: var(--color-superficie);
    color: var(--color-texto);
    font-size: var(--tamano-base);
}

/* Comentario de evaluación (2026-07-14): ancho completo explícito, no
   depender solo del stretch por defecto de .campo (grid). */
.campo textarea {
    width: 100%;
    resize: vertical;
}

.campo input::placeholder {
    color: var(--color-texto-muy-suave);
}

.formulario-rejilla {
    display: grid;
    gap: var(--espaciado-md);
    grid-template-columns: 1fr;
}

@media (min-width: 900px) {
    .formulario-rejilla--3 {
        grid-template-columns: repeat(3, 1fr);
    }

    .formulario-rejilla--2 {
        grid-template-columns: repeat(2, 1fr);
    }
}

/* Sí/No como pastillas de dos estados (¿Abonado?, ítems de evaluación) */
.toggle-si-no {
    display: inline-flex;
    gap: var(--espaciado-xs);
}

.toggle-si-no button {
    min-width: 64px;
    min-height: var(--alto-minimo-touch);
    border: 1px solid var(--color-borde);
    border-radius: var(--radio-md);
    background: var(--color-superficie);
    font-weight: var(--peso-bold);
    cursor: pointer;
}

.toggle-si-no button[aria-pressed="true"].toggle-si-no__si {
    background: var(--color-exito);
    color: #fff;
    border-color: var(--color-exito);
}

.toggle-si-no button[aria-pressed="true"].toggle-si-no__no {
    background: var(--color-peligro);
    color: #fff;
    border-color: var(--color-peligro);
}

/* Variante sobre <input type="radio"> real + <label> (Evaluación,
   2026-07-13): mismo componente visual que los botones de arriba, pero sin
   JS para marcar/desmarcar Sí/No — el estado lo lleva el propio radio (name
   compartido = grupo, comportamiento de formulario nativo). El radio se
   oculta visualmente (no display:none, para que siga siendo enfocable por
   teclado) y es el <label for="..."> el que recibe el estilo de botón; el
   texto es contenido HTML normal del label (recurso traducible), no CSS
   generado — evita depender de ::before sobre un elemento reemplazado
   (soporte inconsistente entre navegadores). Ver Evaluacion/Curso.cshtml. */
.toggle-si-no input[type="radio"] {
    position: absolute;
    opacity: 0;
    width: 1px;
    height: 1px;
}

.toggle-si-no label {
    display: grid;
    place-items: center;
    min-width: 64px;
    min-height: var(--alto-minimo-touch);
    border: 1px solid var(--color-borde);
    border-radius: var(--radio-md);
    background: var(--color-superficie);
    font-weight: var(--peso-bold);
    cursor: pointer;
}

.toggle-si-no input[type="radio"]:focus-visible + label {
    outline: 2px solid var(--color-primario);
    outline-offset: 2px;
}

.toggle-si-no input.toggle-si-no__si:checked + label {
    background: var(--color-exito);
    color: #fff;
    border-color: var(--color-exito);
}

.toggle-si-no input.toggle-si-no__no:checked + label {
    background: var(--color-peligro);
    color: #fff;
    border-color: var(--color-peligro);
}

/* --- Calendario compacto (Pasar lista) --- */
.calendario {
    display: grid;
    gap: var(--espaciado-sm);
}

.calendario__cabecera {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--espaciado-md);
    font-weight: var(--peso-bold);
}

.calendario__cabecera button,
.calendario__cabecera a {
    border: none;
    background: none;
    font-size: var(--tamano-lg);
    text-decoration: none;
    color: inherit;
    cursor: pointer;
}

.calendario__rejilla {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: var(--espaciado-xs);
    text-align: center;
}

.calendario__dia {
    display: grid;
    place-items: center;
    aspect-ratio: 1;
    border-radius: 50%;
    text-decoration: none;
    color: inherit;
    cursor: pointer;
}

/* --color-categoria-actual: variable puente que cada pantalla fija según
   la categoría real del curso (ver Asistencia/Sesion.cshtml), en vez de
   hardcodear el acento de "Adultos" aquí — este componente es compartido
   por las 3 categorías (Adultos/Infantiles/Campaña escolar). Fallback a
   adultos si nadie la define, para no romper usos anteriores. */
.calendario__dia--seleccionado {
    background: var(--color-categoria-actual, var(--color-categoria-adultos));
    font-weight: var(--peso-bold);
}

.lista-horarios {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
    gap: var(--espaciado-sm);
}

.horario {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.2rem;
    text-align: center;
    text-decoration: none;
    color: inherit;
    min-height: var(--alto-minimo-touch);
    padding: 0.4rem;
    border: 1px solid var(--color-borde);
    border-radius: var(--radio-md);
    background: var(--color-superficie-fondo);
    font-size: var(--tamano-sm);
    cursor: pointer;
}

/* Como .horario ahora puede ser un <a> con varias líneas (Asistencia/Elegir,
   2026-07-13: hora + piscina + estado), en vez de solo texto de hora
   (Asistencia/Sesion, contexto estático) — mismo bloque visual, un solo
   hijo cuando es texto plano, varios cuando hay más info. */
.horario small {
    font-size: 0.7em;
    color: var(--color-texto-suave);
}

/* Igual que .calendario__dia--seleccionado: color de categoría real,
   confirmado contra la pág. 7 del PDF (la franja horaria seleccionada usa
   el mismo acento que PISCINA/NIVEL, no el celeste de --color-primario). */
.horario--seleccionado {
    background: var(--color-categoria-actual, var(--color-categoria-adultos));
    border-width: 2px;
}

/* --- Casilla circular (checkbox redondo) ---
   Confirmado contra la pág. 7-8 del PDF: el checkbox de asistencia y los
   de "Seleccionar todo"/"Descargar" son círculos, no cuadrados nativos.
   appearance:none + border-radius:50% sobre un <input type="checkbox">
   real (mismo name=/value=, mismo comportamiento de formulario: solo
   cambia el pintado). */
.casilla-circular {
    appearance: none;
    -webkit-appearance: none;
    width: 1.25rem;
    height: 1.25rem;
    min-width: 1.25rem;
    margin: 0;
    border: 1px solid var(--color-borde);
    border-radius: 50%;
    cursor: pointer;
    flex-shrink: 0;
}

.casilla-circular:checked {
    background: var(--color-categoria-actual, var(--color-primario));
}

/* Sesión Cerrada (2026-07-05): las casillas de asistencia se bloquean de
   verdad (disabled, no solo atenuadas) — hay que reabrir la sesión antes
   de poder tocar nada, ver Asistencia/Sesion.cshtml y ServicioAsistencia
   .GuardarPaseListaAsync (el guardián del servidor rechaza igualmente el
   guardado aunque llegase un POST manual). */
.casilla-circular:disabled {
    cursor: not-allowed;
    opacity: 0.5;
}

/* --- Estado de la sesión (Abierta/Cerrada), pastilla junto a las migas de
   Pasar lista. No existe en el PDF (pág. 7-8 no muestra ningún estado):
   es funcionalidad real necesaria para el cierre explícito de sesión, ver
   docs/I18N.md "Cerrar/Reabrir sesión". */
.estado-sesion {
    display: inline-block;
    margin-left: var(--espaciado-sm);
    padding: 0.15rem 0.6rem;
    border-radius: var(--radio-pastilla);
    font-size: var(--tamano-sm);
    font-weight: var(--peso-bold);
    vertical-align: middle;
}

.estado-sesion--abierta {
    background: var(--color-exito-fondo);
    color: var(--color-exito);
}

.estado-sesion--cerrada {
    background: var(--color-neutro-fondo);
    color: var(--color-texto-suave);
}

/* --- Marcador de evaluación completa/incompleta (Evaluación, pág. 9-10 del
   PDF) --- círculo relleno/vacío en la fila colapsada del alumno, DISTINTO
   del "+"/"−" de .alumno__marcador (ese es solo expandir/contraer). Completa
   = todos los ítems de fase visibles hoy tienen resultado — ver
   InscripcionEvalViewModel.EvaluacionCompleta (2026-07-13). No interactivo:
   es un <span>, no un checkbox. */
.marcador-evaluacion {
    display: inline-block;
    width: 0.8rem;
    height: 0.8rem;
    min-width: 0.8rem;
    border: 1px solid var(--color-borde);
    border-radius: 50%;
    flex-shrink: 0;
}

/* Negro relleno, no verde (Evaluación, 2026-07-14): el color de éxito ya
   se usa para "Conseguido" en los ítems Sí/No — reutilizarlo aquí
   confundía "completa" con "todo conseguido", cuando son cosas distintas
   (completa = todo TIENE respuesta, sea Sí o No). var(--color-borde) es el
   negro de referencia del Design System (ver .casilla-circular). */
.marcador-evaluacion--completa {
    background: var(--color-borde);
    border-color: var(--color-borde);
}

/* --- Lista de alumnado (acordeón simple con contacto) --- */
.lista-alumnado {
    border-top: 1px solid var(--color-borde-suave);
}

.alumno {
    display: flex;
    align-items: center;
    gap: var(--espaciado-sm);
    padding: var(--espaciado-md) 0;
    border-bottom: 1px solid var(--color-borde-suave);
    cursor: pointer;
}

/* Fila de acción (Seleccionar todo / Descargar), mismo lenguaje visual
   que .alumno (círculo + texto) pero sin la separación inferior de la
   lista de alumnado propiamente dicha. */
.alumno--accion {
    border-bottom: none;
    padding-block: var(--espaciado-sm);
}

.alumno--pendiente {
    cursor: default;
    color: var(--color-texto-suave);
}

/* Envoltorio <details> de cada fila de alumno: oculta el marcador nativo
   (como .acordeon-inicio__cabecera) y dibuja "+"/"−" con CSS puro sobre
   [open], sin JS. */
.fila-alumno > summary {
    list-style: none;
}

.fila-alumno > summary::-webkit-details-marker {
    display: none;
}

.alumno__marcador::before {
    content: "+";
    font-size: var(--tamano-lg);
    line-height: 1;
}

.fila-alumno[open] > summary .alumno__marcador::before {
    content: "\2212"; /* signo menos, no guion */
}

.alumno__nombre {
    flex: 1;
    font-size: var(--tamano-lg);
}

.alumno__detalle {
    display: grid;
    gap: var(--espaciado-lg);
    padding: 0 0 var(--espaciado-md) calc(var(--espaciado-md) + 24px);
    color: var(--color-texto-suave);
    font-size: var(--tamano-sm);
}

/* --- Rúbrica 1-10 (Aptitud técnica, Evaluación 2026-07-14) ---
   <fieldset>/<legend> real (un criterio = un grupo de radios con su propio
   label) en vez del <select> anterior. Mismo patrón de "radio oculto +
   label como botón" que .toggle-si-no (input[type=radio] posicionado fuera
   de vista sin display:none, para que siga siendo enfocable/anunciado por
   lector de pantalla; el label recibe el estilo visual). "Sin valorar" es
   una opción más del grupo (value="", primer radio), no la ausencia de
   selección — así el estado "no valorado todavía" es explícito y
   seleccionable, no solo "ningún botón pulsado". */
.rubrica {
    display: grid;
    gap: var(--espaciado-xs);
    border: none;
    margin: 0;
    padding: 0;
}

.rubrica__titulo {
    display: block;
    width: 100%;
    margin: 0;
    padding: 0;
    font-weight: var(--peso-bold);
}

.rubrica__opciones {
    display: flex;
    flex-wrap: wrap;
    gap: var(--espaciado-xs);
}

.rubrica__radio {
    position: absolute;
    opacity: 0;
    width: 1px;
    height: 1px;
}

.rubrica__etiqueta {
    display: grid;
    place-items: center;
    min-width: var(--alto-minimo-touch);
    min-height: var(--alto-minimo-touch);
    padding: 0 0.25rem;
    border: 2px solid var(--color-borde);
    border-radius: var(--radio-sm);
    background: var(--color-superficie);
    font-weight: var(--peso-bold);
    cursor: pointer;
}

.rubrica__radio:focus-visible + .rubrica__etiqueta {
    outline: 3px solid var(--color-primario-oscuro);
    outline-offset: 2px;
}

/* Estado seleccionado: no solo cambia el color de fondo — también engorda
   el borde y añade una marca "✓" (2026-07-14, ronda de accesibilidad), para
   que quien no perciba bien el color siga viendo cuál está marcado. */
.rubrica__radio:checked + .rubrica__etiqueta {
    position: relative;
    background: var(--color-primario);
    border-color: var(--color-borde);
    border-width: 3px;
}

.rubrica__radio:checked + .rubrica__etiqueta::after {
    content: "\2713";
    position: absolute;
    top: -0.5rem;
    right: -0.5rem;
    display: grid;
    place-items: center;
    width: 1.1rem;
    height: 1.1rem;
    border-radius: 50%;
    background: var(--color-borde);
    color: var(--color-superficie);
    font-size: 0.7rem;
}

/* "Sin valorar" es una pastilla más ancha y con borde discontinuo — se
   distingue de las puntuaciones incluso sin leer el texto. */
.rubrica__etiqueta--sin-valorar {
    min-width: auto;
    padding: 0 0.85rem;
    border-style: dashed;
    font-weight: var(--peso-normal);
    text-transform: none;
    color: var(--color-texto-suave);
}

.rubrica__radio--sin-valorar:checked + .rubrica__etiqueta--sin-valorar {
    background: var(--color-neutro-fondo);
    border-style: dashed;
    color: var(--color-texto);
}

.rubrica__radio--sin-valorar:checked + .rubrica__etiqueta--sin-valorar::after {
    background: var(--color-texto-suave);
}

/* --- Aptitud técnica: cabecera del bloque (Evaluación, 2026-07-14) ---
   Ya no reutiliza .fase__cabecera (esa queda solo para las 7 fases con
   color propio): título simple, mismo lenguaje tipográfico que
   .campo__etiqueta, sin banda de color — evita el problema de contraste de
   antes (texto blanco de .color-sobre-fase sobre fondo blanco cuando no
   había data-fase). */
.bloque-aptitud-tecnica {
    display: grid;
    gap: var(--espaciado-md);
}

.bloque-aptitud-tecnica__titulo {
    margin: 0;
    font-size: var(--tamano-base);
    font-weight: var(--peso-bold);
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--color-texto);
}

/* --- Actitud y convivencia: acordeón propio y neutro (Evaluación,
   2026-07-14) --- Antes reutilizaba .fase/.fase__cabecera (banda de color
   de fase, "Sí a todo" en la cabecera). Ahora es un <details> propio:
   colapsado por defecto, cabecera neutra (fondo --color-neutro-fondo, texto
   --color-texto, no un color de fase) con "+"/"−" igual que .fila-alumno, y
   "Sí a todo" al final del cuerpo, no en la cabecera. */
.bloque-actitud {
    border: 1px solid var(--color-borde-suave);
    border-radius: var(--radio-md);
    overflow: hidden;
}

.bloque-actitud__cabecera {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--espaciado-md);
    padding: var(--espaciado-sm) var(--espaciado-md);
    background: var(--color-neutro-fondo);
    color: var(--color-texto);
    font-weight: var(--peso-bold);
    cursor: pointer;
    list-style: none;
}

.bloque-actitud__cabecera::-webkit-details-marker {
    display: none;
}

.bloque-actitud__marcador::before {
    content: "+";
    font-size: var(--tamano-lg);
    line-height: 1;
}

.bloque-actitud[open] > .bloque-actitud__cabecera .bloque-actitud__marcador::before {
    content: "\2212";
}

.bloque-actitud__cuerpo {
    display: grid;
    padding: var(--espaciado-sm) var(--espaciado-md) var(--espaciado-md);
    gap: var(--espaciado-xs);
}

.bloque-actitud__pie {
    display: flex;
    justify-content: flex-end;
    padding-top: var(--espaciado-sm);
}

/* --- ITEMS: encabezado general + lista de fases (Evaluación, 2026-07-14) --- */
.bloque-items {
    display: grid;
    gap: var(--espaciado-sm);
}

.bloque-items__titulo {
    margin: 0;
    font-size: var(--tamano-base);
    font-weight: var(--peso-bold);
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--color-texto);
}

/* --- Banner de fase de evaluación ---
   Cabecera de color de fase + lista de ítems Sí/No. El color viene
   de --color-fase-{orden}-{slug} vía atributo data-fase="1".."7".
   Desde 2026-07-14 .fase es un <details>: una fase abierta por defecto,
   el resto colapsadas (ver faseAAbrir en Curso.cshtml), con .fase__cabecera
   como <summary> — número de fase en círculo + nombre en mayúsculas, y
   "Sí a todo" ya NO vive aquí (ver .fase__pie), para que la cabecera sea
   pura navegación de acordeón. */
.fase {
    border-radius: var(--radio-md);
    overflow: hidden;
}

.fase__cabecera {
    display: flex;
    align-items: center;
    gap: var(--espaciado-sm);
    padding: var(--espaciado-sm) var(--espaciado-md);
    color: var(--color-sobre-fase);
    font-weight: var(--peso-bold);
    text-transform: uppercase;
    cursor: pointer;
    list-style: none;
}

.fase__cabecera::-webkit-details-marker {
    display: none;
}

/* Indicador +/- de expandir/colapsar, mismo lenguaje que .fila-alumno y
   .bloque-actitud — se añade a la derecha vía margin-left:auto para no
   depender del orden de los spans en el HTML. */
.fase__cabecera::after {
    content: "+";
    margin-left: auto;
    font-size: var(--tamano-lg);
    line-height: 1;
}

.fase[open] > .fase__cabecera::after {
    content: "\2212";
}

.fase__numero {
    display: grid;
    place-items: center;
    width: 1.75rem;
    height: 1.75rem;
    flex-shrink: 0;
    border: 1px solid rgba(255, 255, 255, 0.6);
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.25);
    font-size: var(--tamano-sm);
}

.fase[data-fase="1"] .fase__cabecera { background: var(--color-fase-1-adaptacion); }
.fase[data-fase="2"] .fase__cabecera { background: var(--color-fase-2-descubrimiento); }
.fase[data-fase="3"] .fase__cabecera { background: var(--color-fase-3-confianza); }
.fase[data-fase="4"] .fase__cabecera { background: var(--color-fase-4-autonomia); }
.fase[data-fase="5"] .fase__cabecera { background: var(--color-fase-5-dominio); }
.fase[data-fase="6"] .fase__cabecera { background: var(--color-fase-6-tecnica); }
.fase[data-fase="7"] .fase__cabecera { background: var(--color-fase-7-competicion); }

.fase__item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--espaciado-md);
    padding: var(--espaciado-sm) var(--espaciado-md);
    background: var(--color-superficie);
    border-bottom: 1px solid var(--color-borde-suave);
}

.fase__item-descripcion {
    white-space: pre-line;
    font-size: var(--tamano-sm);
}

/* Pie de fase / bloque de actitud: aquí vive "Sí a todo" ahora que ya no
   está en la cabecera de color — fondo de superficie normal, así que el
   .boton estándar (con .boton--secundario) contrasta bien sin overrides
   específicos. */
.fase__pie {
    display: flex;
    justify-content: flex-end;
    padding: var(--espaciado-sm) var(--espaciado-md);
    background: var(--color-superficie);
}

/* --- Stepper / wizard --- */
.stepper {
    display: flex;
    gap: var(--espaciado-sm);
    flex-wrap: wrap;
}

.stepper__paso {
    border: 1px solid var(--color-borde);
    border-radius: 999px;
    padding: 0.35rem 0.85rem;
    color: var(--color-texto-suave);
    font-weight: var(--peso-bold);
}

.stepper__paso--activo,
.stepper__paso--hecho {
    background: var(--color-primario);
    border-color: var(--color-primario);
    color: var(--color-sobre-primario);
}

/* --- Tarjeta de acceso (login) --- */
/* Corrección de composición 2026-07-04 (Fermín, comparando contra la pág. 4
   del PDF): el formulario era demasiado pequeño y quedaba pegado arriba.
   max-width sube de 480 a 560px, el gap entre campos crece, y el
   posicionamiento vertical ya no lo decide el margin de este componente —
   lo centra `main` en Auth/Login.cshtml (ver .pagina-login en site.css) para
   que quede en la zona media real de la pantalla, no a un margen fijo desde
   la cabecera. Los overrides de input/botón de aquí son deliberadamente
   ESPECÍFICOS de `.tarjeta-acceso` (no se toca `.campo input`/`.boton` base,
   que son componentes compartidos por el resto del Design System, todavía
   sin usar en ninguna otra pantalla de Monitor). */
.tarjeta-acceso {
    display: grid;
    gap: var(--espaciado-lg);
    max-width: 560px;
    margin: 0 auto;
}

/* El <form> no debe romper el grid de .tarjeta-acceso (si no, el `gap`
   solo separaría el resumen de validación del <form> como bloque único,
   sin aire entre los propios campos y el botón de dentro). display:contents
   promueve los hijos del form al grid del padre sin cambiar nada de
   comportamiento ni de accesibilidad. */
.tarjeta-acceso form {
    display: contents;
}

.tarjeta-acceso .campo input {
    min-height: 3.75rem;
    padding: 1rem 1.25rem;
    border: 1px solid var(--color-borde);
    border-radius: var(--radio-md);
    font-size: var(--tamano-lg);
}

.tarjeta-acceso .boton {
    min-height: 3.75rem;
    font-size: var(--tamano-xl);
    padding-block: 1rem;
}

.tarjeta-acceso__olvido {
    text-align: center;
    color: var(--color-texto-suave);
    text-decoration: none;
}

/* --- Estado vacío / avisos --- */
.aviso {
    border: 1px dashed var(--color-borde-suave);
    border-radius: var(--radio-md);
    padding: var(--espaciado-lg);
    color: var(--color-texto-suave);
}

/* Variantes para TempData["Mensaje"]/["Error"] (antes las pintaba el
   navbar de Bootstrap de _Layout.cshtml; Asistencia/Sesion.cshtml ya no
   usa ese layout — mismo criterio que Login/Home). */
.aviso--exito {
    border-style: solid;
    border-color: var(--color-exito);
    color: var(--color-exito);
}

.aviso--error {
    border-style: solid;
    border-color: var(--color-peligro);
    color: var(--color-peligro);
}

/* --- Utilidades de acciones al pie del formulario --- */
.acciones-formulario {
    display: flex;
    flex-wrap: wrap;
    gap: var(--espaciado-md);
    align-items: center;
}

.acciones-formulario--reparto {
    justify-content: space-between;
}

/* Fila principal de envío (ENVIAR / Finalizar pase de lista): algo más
   de aire por encima respecto a la fila de Seleccionar todo/Descargar
   inmediata anterior (corrección de composición 2026-07-13, ver
   docs/I18N.md — Asistencia/Sesion.cshtml). */
.acciones-formulario--principal {
    margin-top: var(--espaciado-lg);
}

/* ============================================================
   Sistema responsive
   Mobile-first: las reglas base sirven para <600px. A partir de ahí
   se añaden columnas / rejillas más anchas. Estos dos puntos de
   corte son los únicos que deben usarse en todo el proyecto (ver
   documentación de --ancho-contenido en _tema.css).
   ============================================================ */
@media (min-width: 600px) {
    .formulario-rejilla {
        grid-template-columns: 1fr 1fr;
    }

    .grupo-filtro__opciones {
        row-gap: var(--espaciado-md);
    }
}

@media (min-width: 900px) {
    .filtros {
        grid-template-columns: repeat(2, 1fr);
    }

    .boton {
        width: auto;
    }
}

@media (max-width: 599px) {
    .cabecera-sitio {
        flex-wrap: wrap;
    }

    .acciones-formulario {
        flex-direction: column;
        align-items: stretch;
    }

    /* "Sí a todo" a ancho completo en móvil, igual que el resto de acciones
       apiladas (Evaluación, 2026-07-14) — .boton--ancho-auto solo aplica a
       partir de 600px. */
    .fase__pie .boton,
    .bloque-actitud__pie .boton {
        width: 100%;
    }

    .lista-horarios {
        grid-template-columns: repeat(2, 1fr);
    }
}
