/* ==========================================================================
   Tokens del rediseño. Fichero nuevo a propósito: la carpeta scss/ no la
   compila nadie y style.css son 1495 lineas mantenidas a mano. Esto se carga
   despues, gana en cascada, y se puede revisar y revertir por separado.
   ========================================================================== */

/* La fuente de la portada, ahora disponible en TODO el sitio.
   Estaba declarada solo en landing.css, que unicamente carga la pagina de
   bienvenida; el resto del sitio no la tenia. Son 9 KB, asi que el coste de
   servirla en todas partes es despreciable.
   `font-display: swap` evita que el texto quede invisible mientras descarga. */
/* Cheri-ES.ttf es Cheri con los caracteres del español añadidos.
   La original solo trae los 95 ASCII imprimibles: ni una vocal acentuada, ni la
   ñ, ni ¿ ni ¡. Cada carácter que faltaba caía a otra tipografía, así que en
   español los títulos salían con las tildes de otra letra —y de una distinta en
   cada móvil, porque el repuesto era `cursive`, o sea «la cursiva del sistema».

   Los 16 caracteres nuevos NO están dibujados a mano: son glifos COMPUESTOS que
   referencian a los propios trazos de Cheri. La á es la a de Cheri con su
   apóstrofo encima; la ñ usa la virgulilla ~; la ü, las comillas "; y ¿ ¡ son
   ? ! girados 180°. Mismo trazo, mismo grosor, mismo diseño.
   La í va sobre una «i sin punto» fabricada quitándole el contorno del punto,
   para que el acento lo sustituya en vez de sumarse.

   Se conserva el nombre de familia 'Cheri': así el resto del CSS no cambia.
   La genera _docs/completar-cheri.py a partir de _docs/fuentes/Cheri.ttf. */
@font-face {
  font-family: 'Cheri';
  src: url('../assets/fonts/Cheri-ES.ttf') format('truetype');
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}

/* Los colores de marca NO valen para texto:
   #03a9c9 da 2,79:1 sobre blanco y #8ec784 da 1,97:1 — ambos fallan WCAG AA.
   Son superficie. El texto usa --text (#555555, 7,5:1) o
   --text-strong (#16A34A, 3,30:1, solo para titulares grandes: a partir de
   18,66px en negrita o 24px normal). */
/* ==========================================================================
   EL TEMA OSCURO DEL MÓVIL
   Android Chrome trae una opción, «tema oscuro automático para el contenido
   web», que INVIERTE los colores de cualquier página que no declare los suyos.
   El resultado es lo que veía el cliente: la web entera apagada y desvaída,
   con los azules y verdes convertidos en grises sucios.

   `color-scheme: light` es la forma estándar de decirle al navegador «esta
   página ya tiene su diseño de color, no lo toques». No obliga a nadie a usar
   el modo claro en su móvil: solo evita que el navegador reinterprete ESTA
   página. Chrome respeta esta declaración y desactiva el oscurecido forzado.

   Va aquí y no en cada hoja porque afecta al documento entero. */
:root {
  color-scheme: light;
}

:root {
  /* TEXTO PRINCIPAL: azul marino de marca, no gris neutro.
     Venía de la propuesta de paleta del cliente. Era #555555, un gris de
     plantilla que da 7,46:1 sobre blanco. Este navy da 11,65:1 sobre el crema
     de abajo: se lee mejor Y pertenece a la marca, en vez de ser el gris que
     trae cualquier tema. Medido, no estimado. */
  --text: #163A59;

  /* Texto secundario: pies de foto, fechas, etiquetas. Mismo origen.
     5,12:1 sobre el crema — cumple AA sin competir con el texto principal. */
  --text-suave: #587083;

  /* EL VERDE DE LA PALETA, en su versión legible.
     Se queda: es color de marca y da aire a una página que si no sería toda
     azul. Pero como TEXTO hay que oscurecerlo, y bastante:
       #16A34A            3,30:1 — no llega
       #56A52C (PDF)      3,05:1 — no llega
       #68B52A (PDF)      2,52:1 — no llega
       #0B9A39 (PDF)      3,65:1 — no llega
     Los verdes vivos de la paleta valen para adornos y fondos, no para letras.
     #15803D sí cumplía, pero se quedaba en 4,52 sobre --accent-soft: dos
     centésimas por encima del mínimo, sin margen para nada.
     Este da 5,73 sobre el crema, 5,22 sobre #e6f6fa y 5,28 sobre #eef7ec.
     A ojo es el mismo verde, solo un punto más profundo. */
  --text-strong: #147536;

  /* FONDO DE PÁGINA: blanco cálido, no blanco puro.
     Quita el frío del #ffffff sin llegar a parecer amarillento, y hace que las
     tarjetas —que siguen en blanco puro, ver --surface— se despeguen del fondo
     sin necesidad de sombras. La diferencia con el blanco es de 0,12 puntos de
     contraste: no compromete ningún texto, y se comprobó midiendo el sitio
     entero después del cambio. */
  --fondo: #fffef8;

  /* Superficie de TARJETA, distinta del fondo de página a propósito. */
  --surface: #ffffff;

  /* VALORES POR DEFECTO, NO DECORACION. Una declaracion con un var() sin
     definir es invalida en tiempo de valor calculado: la propiedad cae a su
     valor INICIAL (transparent), no al que declarase una hoja anterior. Sin
     esto, cualquier plantilla que olvide data-branch deja .navbar
     transparente y su menu blanco sobre blanco. Paso de verdad en
     _layouts/post.html y dejo seis paginas sin navegacion visible.
     Aqui el acento de Revere hace de red: nunca queda sin definir. */
  --accent: #03a9c9;
  --accent-soft: #e6f6fa;
  --accent-deep: #00808f;

  /* EL ACENTO CUANDO HACE DE TEXTO, no de fondo.
     --accent-deep se eligió para llevar texto BLANCO encima: en esa pareja da
     4,68:1 y cumple de sobra. Pero usado al revés —como color de letra— solo
     cumple sobre blanco puro. Sobre los fondos claros de la web (--accent-soft
     #e6f6fa y el #e0eaf0 del pie) se queda en 3,8:1, por debajo del mínimo.
     Medido en el navegador, no estimado.
     Este tono da 5,73:1 sobre blanco, 5,17 sobre #e6f6fa y 4,81 sobre #e0eaf0,
     así que sirve para las tres. Un color no es accesible o inaccesible por sí
     mismo: lo es la PAREJA color-fondo, y al invertirla hay que volver a medir. */
  --accent-texto: #006b78;

  /* LA BARRA DE NAVEGACIÓN, aparte de los acentos.
     El cliente la quería clara y pastel. Con letras BLANCAS era imposible: el
     tono oscuro (#00808f) ya daba 4,68:1 y el mínimo es 4,5 — cualquier aclarado
     lo rompía. Con letras OSCURAS se puede llegar mucho más lejos.
     #8fd8e8 con #0b3d46 da 7,43:1.
     No se aclara más porque a partir de aquí la barra empieza a confundirse con
     el fondo pálido de las entradillas (--accent-soft): a #a3dfeb ya solo hay
     1,32 de diferencia entre los dos. */
  /* LA BARRA. Celeste suave, elegido sobre ocho opciones comparadas en pantalla.
     Sale del PDF de paleta de Everett.

     Se decidió mirando DOS cosas, no una:
       1. Que el menú se lea: #15548d sobre este celeste da 6,40:1.
       2. Que el botón de «Lista de espera» —que tiene color propio, #00808f—
          siga destacando contra la barra: aquí da 3,83.

     El segundo criterio es el que descartó los fondos oscuros. «Velvet Elvis»
     (#4a91b4) cumplía de sobra el primero (4,64:1 con texto casi tinta), pero
     hundía el botón: 1,34 de diferencia con la barra, o sea que la píldora se
     perdía dentro del fondo. Con el acero profundo bajaba a 1,20 y con el verde
     azulado a 1,00 —invisible del todo—. Un color puede pasar la auditoría de
     accesibilidad y aun así romper la jerarquía visual: son preguntas distintas.

     Además así la cabecera desciende ordenada: franja azul marino arriba, barra
     celeste, página crema. Con una barra oscura, franja y barra se fundían en un
     solo bloque pesado. */
  --nav-bg: #cdeef7;
  --nav-text: #15548d;

  /* TÍTULOS Y PIE, como tokens.
     Estos dos colores estaban escritos a fuego en cinco sitios distintos, y eso
     impedía que una sede pudiera tener su propia paleta sin duplicar selectores.
     Los valores de aquí son los de Revere; Everett los sobreescribe más abajo. */
  --titulo: #15548d;
  --pie-bg: #e0eaf0;
}

/* DOS acentos por sede, y la diferencia importa:
   --accent      color de marca. Solo adornos: bordes, subrayados, circulos.
                 NUNCA lleva texto encima (blanco sobre el da 2,79:1 y 1,97:1).
   --accent-deep el mismo color oscurecido hasta cumplir WCAG AA con texto
                 blanco: 4,68:1 en Revere y 4,82:1 en Everett. Medidos.
   --accent-soft fondo palido. Lleva texto oscuro, nunca blanco. */
[data-branch="revere"] {
  --accent: #03a9c9;
  --accent-soft: #e6f6fa;
  --accent-deep: #00808f;
}

/* EVERETT VA EN VERDE. Revere se queda en azul.
   (Sustituye a la unificación anterior, en la que las dos compartían el azul.)

   Cada verde tiene la MISMA luminancia relativa que el azul al que sustituye.
   Eso no es un capricho: el contraste depende solo de la luminancia, así que
   igualándola, TODOS los ratios ya medidos del sitio se conservan sin volver a
   auditar color por color. Comprobado: menú 6,40 → 6,38, botón 4,68 → 4,67.

     azul       →  verde      luminancia   para qué
     #03a9c9    →  #60ad2f    0,3261       adornos, bordes, subrayados
     #e6f6fa    →  #eaf7e2    0,8964       fondos pálidos de sección
     #00808f    →  #488223    0,1742       botones con texto blanco
     #cdeef7    →  #d6f0c6    0,8084       fondo de la barra
     #15548d    →  #335c19    0,0842       texto del menú, títulos, franja
     #006b78    →  #3d6d1e    0,1187       enlaces sobre fondo claro

   El tono sale del verde del logo (#5aa12c), variando solo la luminosidad. */
[data-branch="everett"] {
  --accent: #60ad2f;
  --accent-soft: #eaf7e2;
  --accent-deep: #488223;
  --accent-texto: #3d6d1e;
  --nav-bg: #d6f0c6;
  --nav-text: #335c19;
  --titulo: #335c19;
  --pie-bg: #e4efdc;
}

/* El claymorphism de este sitio usa transiciones con rebote. Hay niños y
   adultos sensibles al movimiento: si el sistema lo pide, se quitan. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ==========================================================================
   Bilingüe. Ambos idiomas van en el HTML para que Google indexe los dos;
   se muestra uno y se oculta el otro con CSS. Cambio instantaneo, sin
   peticion y sin parpadeo.
   Por defecto ingles: asi la pagina se lee aunque el JavaScript no cargue.
   ========================================================================== */
.i18n[lang="es"] {
  display: none;
}

[data-lang="es"] .i18n[lang="en"] {
  display: none;
}

[data-lang="es"] .i18n[lang="es"] {
  display: inline;
}

/* ==========================================================================
   LA CABECERA TOMA EL COLOR DE SU SEDE
   style.css fija #03a9c9 a fuego en .navbar (linea 1392) y en su zig-zag
   (.navbar:before, linea 1468). Aqui se sustituye por el token, que
   [data-branch] del body resuelve a cian en Revere y verde en Everett.
   ========================================================================== */
.navbar {
  background: var(--nav-bg);
}

/* style.css pinta de BLANCO todo lo que hay dentro de la barra, en seis reglas
   distintas. Sobre el azul claro el blanco desaparece, así que hay que cubrirlas
   todas: si se olvida una, ese elemento queda invisible y no se nota hasta que
   alguien lo busca. */
/* OJO A LA ESPECIFICIDAD. La barra lleva la clase `navbar-dark`, y Bootstrap
   tiene `.navbar-dark .navbar-nav .nav-link` (0,3,0). Un selector como
   `.navbar .nav-item a` (0,1,2) NO gana, por mucho que cargue después: la
   especificidad manda sobre el orden. Por eso aquí se usa
   `.navbar.navbar-dark .navbar-nav ...` (0,4,x). */
.navbar .brand-name,
.navbar.navbar-dark .navbar-nav .nav-item a,
.navbar.navbar-dark .navbar-nav .nav-item a i,
.navbar.navbar-dark .navbar-nav .nav-item a span,
.navbar.navbar-dark .navbar-nav .nav-item.active a,
.navbar.navbar-dark .navbar-nav .nav-item.active a span {
  color: var(--nav-text);
}

/* El hover era blanco al 50%: sobre fondo claro no se veía nada. Ahora aclara
   el propio color oscuro, que sí se percibe. */
.navbar.navbar-dark .navbar-nav .nav-item a:hover,
.navbar.navbar-dark .navbar-nav .nav-item a:hover i,
.navbar.navbar-dark .navbar-nav .nav-item a:hover span {
  color: var(--accent-deep);
}

/* El subrayado de la página activa y el del hover también eran blancos. */
.navbar .nav-item a::after,
.navbar .nav-item.active a::after {
  border-bottom-color: var(--nav-text);
}

/* El contorno de foco en blanco desaparecía sobre el azul claro. */
.navbar .nav-item a:focus-visible {
  outline-color: var(--nav-text);
}

/* El botón de menú en móvil: su borde era blanco translúcido. */
.navbar .navbar-toggler {
  border-color: var(--nav-text);
}

.navbar .navbar-toggler-icon {
  /* El icono de Bootstrap es una imagen SVG con las rayas en blanco, metida en
     la propia hoja. Se sustituye por la misma forma en oscuro. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3E%3Cpath stroke='%230b3d46' stroke-width='2.4' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E");
}

/* Sobre barra clara, un botón blanco se confundiría con el fondo: se rellena
   con el acento profundo, que además es la acción principal del menú. */
.navbar.navbar-dark .navbar-nav .nav-item-cta a.nav-link,
.navbar.navbar-dark .navbar-nav .nav-item-cta a.nav-link span,
.navbar.navbar-dark .navbar-nav .nav-item-cta a.nav-link i,
.navbar.navbar-dark .navbar-nav .nav-item-cta a.nav-link:hover,
.navbar.navbar-dark .navbar-nav .nav-item-cta a.nav-link:hover span,
.navbar.navbar-dark .navbar-nav .nav-item-cta a.nav-link:hover i {
  background: var(--accent-deep);
  color: #ffffff;
}

/* background-IMAGE, no la forma abreviada background: la abreviada reinicia
   background-size, que style.css declara aparte (1.25rem 2.5rem) y es lo que
   convierte los dos degradados en dientes de sierra. Con la abreviada el
   tamano cae a `auto` y la tira se deforma. */
/* ONDA en vez de dientes de sierra.
   El troquelado de picos era lo que más delataba la edad de la plantilla. Una
   onda conserva el aire infantil —que aquí tiene sentido— sin parecer recortable
   de manualidades.
   Se dibuja con una MÁSCARA, no con un degradado de color: así el tono sale de
   `background-color` y sigue al token de la sede. Con degradados habría que
   repetir el color dentro de la forma, que es lo que hacía el original. */
.navbar:before {
  height: 2.25rem;
  bottom: -2.2rem;
  background-image: none;
  background-color: var(--nav-bg);
  /* UNA sola curva que recorre todo el ancho, no una onda repetida.
     `preserveAspectRatio='none'` deja que el dibujo se estire, y el tamaño
     `100% 100%` sin repetir hace que haya exactamente una curva, mida lo que
     mida la pantalla. */
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 60' preserveAspectRatio='none'%3E%3Cpath d='M0 0 H1440 V16 Q720 60 0 16 Z' fill='%23000'/%3E%3C/svg%3E") no-repeat top center / 100% 100%;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 60' preserveAspectRatio='none'%3E%3Cpath d='M0 0 H1440 V16 Q720 60 0 16 Z' fill='%23000'/%3E%3C/svg%3E") no-repeat top center / 100% 100%;
}

/* El borde bajo la foto del carrusel. Era el TERCER sitio con troquelado y se
   me había escapado: no estaba en `.zig-zag` ni en `.navbar`, sino en
   `.slider:after`. Misma curva única, en blanco, porque lo que hay debajo es
   el cuerpo de la página. */
.slider:after {
  height: 2.25rem;
  background-image: none;
  background-color: #ffffff;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 60' preserveAspectRatio='none'%3E%3Cpath d='M0 44 Q720 0 1440 44 V60 H0 Z' fill='%23000'/%3E%3C/svg%3E") no-repeat bottom center / 100% 100%;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 60' preserveAspectRatio='none'%3E%3Cpath d='M0 44 Q720 0 1440 44 V60 H0 Z' fill='%23000'/%3E%3C/svg%3E") no-repeat bottom center / 100% 100%;
}

/* ==========================================================================
   SEPARADORES ENTRE SECCIONES
   Eran cuatro tiras de dientes de sierra de 2,5rem con 5rem de margen arriba y
   abajo: mucho ruido para separar dos bloques. Se sustituyen por la misma onda,
   más baja y discreta.
   ========================================================================== */
.zig-zag.section-separator {
  height: 2.25rem;
  margin-top: 2.5rem;
  margin-bottom: 2.5rem;
  /* La sombra seguía el contorno de los picos y los remarcaba. */
  filter: none;
  background-image: none;
  background-color: var(--accent-soft);
  /* La curva va al revés que la de la cabecera —sube en el centro en vez de
     bajar— para que las dos se respondan en lugar de repetirse. */
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 60' preserveAspectRatio='none'%3E%3Cpath d='M0 44 Q720 0 1440 44 V60 H0 Z' fill='%23000'/%3E%3C/svg%3E") no-repeat bottom center / 100% 100%;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 60' preserveAspectRatio='none'%3E%3Cpath d='M0 44 Q720 0 1440 44 V60 H0 Z' fill='%23000'/%3E%3C/svg%3E") no-repeat bottom center / 100% 100%;
}

/* Las cuatro variantes de style.css (.first … .fourth) traen el degradado de
   picos en la forma ABREVIADA `background:`, con especificidad 0,3,0. La regla
   de arriba es 0,2,0 y NO las gana: hay que apagar el degradado en cada una.
   Tercera vez en el proyecto que la especificidad manda sobre el orden. */
.zig-zag.section-separator.first,
.zig-zag.section-separator.second,
.zig-zag.section-separator.third {
  background-image: none;
  background-color: var(--accent-soft);
}

/* El último separador es la transición al pie, que tiene su propio color. */
.zig-zag.section-separator.fourth {
  margin: 0;
  height: 2.25rem;
  background-image: none;
  background-color: var(--pie-bg);
}

/* El nombre va en tres lineas (FCC / The Little / Future). Centradas ENTRE SI,
   no en la pagina: la marca sigue a la izquierda, solo se equilibran las lineas
   unas sobre otras.
   La tipografia es la misma de la portada: la cabecera y la pagina de entrada
   dejan de parecer dos sitios distintos. */
.navbar .brand-name {
  text-align: center;
  font-family: 'Cheri', 'Baloo 2', cursive;
  font-weight: 400;
  letter-spacing: 0.5px;
}

/* Cheri es una tipografia de rotulo: en los enlaces del menu, a 19px, se lee
   peor que la del cuerpo. Se usa con un poco mas de tamano y espaciado para
   compensar. */
.navbar.navbar-dark .navbar-nav .nav-item a {
  font-family: 'Cheri', 'Baloo 2', cursive;
  font-weight: 400;
  font-size: 1.3em;
  letter-spacing: 0.3px;
}

/* El logo medía 50px contra un bloque de nombre de 99: se perdia. Se sube a la
   altura del nombre para que se vea el dibujo, sin que la barra crezca (el
   enlace de marca ya ocupa 107px). */
.navbar .navbar-brand img {
  height: 5.75rem;
  width: auto;
  margin-right: 0.35rem;
  /* style.css le pone border-radius:50%, que recorta la imagen a un circulo.
     El logo NO es circular: es cuadrado, con «Family Child Care» en arco arriba
     y la ciudad abajo. A 50px apenas se notaba; a 92px el recorte se comia el
     texto («amily Child Car»). */
  border-radius: 0;
}

/* Con el menu colapsado la barra es mas baja y el nombre cabe en menos lineas:
   un logo de 92px ahi la estiraria sin motivo. */
@media (max-width: 991.98px) {
  .navbar .navbar-brand img {
    height: 4rem;
  }
}

/* ==========================================================================
   BOTONES DE IDIOMA, como los de la portada
   La franja superior ya es #15548d, el mismo azul que la portada usa para el
   estado activo. Copiarlo tal cual dejaria el boton activo INVISIBLE sobre su
   propio fondo, asi que se invierte: activo = blanco solido con texto azul.
   ========================================================================== */
.lang-toggle-header .lang-btn {
  font-family: 'Cheri', 'Baloo 2', cursive;
  font-weight: 400;
  font-size: 0.95rem;
  letter-spacing: 0.3px;
  background: rgba(255, 255, 255, 0.2);
  border: 1px solid rgba(255, 255, 255, 0.55);
  color: #ffffff;
  padding: 3px 12px;
  border-radius: 6px;
  cursor: pointer;
  transition: background 0.2s, color 0.2s;
}

.lang-toggle-header .lang-btn.active,
.lang-toggle-header .lang-btn:hover {
  background: #ffffff;
  border-color: #ffffff;
  color: var(--titulo);
}

.lang-toggle-header .lang-btn:focus-visible {
  outline: 2px solid #ffffff;
  outline-offset: 2px;
}

/* El boton de cambiar sede vive en la misma franja: se iguala para que los
   tres se lean como un grupo y no como piezas de distinta epoca. */
.branch-switcher .branch-btn {
  font-family: 'Cheri', 'Baloo 2', cursive;
  font-size: 0.95rem;
  letter-spacing: 0.3px;
  color: #ffffff;
  border-color: rgba(255, 255, 255, 0.55);
  border-radius: 6px;
}

/* ==========================================================================
   PAGINA NOSOTROS
   Movil primero. Una columna por defecto; las rejillas se abren con
   auto-fit, sin puntos de ruptura que mantener.
   ========================================================================== */
.branch-about {
  color: var(--text);
}

.branch-about .container {
  max-width: 1100px;
}

.branch-about section {
  padding-block: 3rem;
}

/* Titulo de seccion, con un subrayado corto del color de la sede.

   Esto era una LISTA de contenedores (.branch-about, .branch-home…) y falló dos
   veces por el mismo motivo: cada plantilla nueva salia sin estilo —en gris,
   con la fuente por defecto y alineada a la izquierda— hasta que alguien se
   acordaba de añadirla a la lista. La primera vez fueron la portada y
   Programas; la segunda, «Para las familias».

   Ahora cuelga de `main`, que es el envoltorio de TODAS las plantillas de
   pagina. Asi una plantilla nueva hereda el estilo sin tocar el CSS.
   Las variantes con selector propio (.program-col, .contacto-datos) siguen
   ganando: son 0,2,0 contra el 0,1,1 de esta. */
main .section-title {
  font-family: 'Cheri', 'Baloo 2', cursive;
  font-weight: 400;
  font-size: clamp(1.6rem, 4vw, 2.2rem);
  /* Azul de la portada, NO el verde: los titulos de seccion pasan a hablar el
     mismo idioma que la cabecera y la pagina de entrada. */
  color: var(--titulo);
  text-align: center;
  margin-bottom: 2rem;
  letter-spacing: 0.4px;
  /* SIN contorno blanco: estos van sobre fondo blanco, y ahi el halo no se ve
     pero si adelgaza las letras. El contorno se reserva para los titulos que
     van sobre fondo de color. */
}

main .section-title::after {
  content: "";
  display: block;
  width: 3.5rem;
  height: 4px;
  border-radius: 2px;
  background: var(--accent);
  margin: 0.6rem auto 0;
}

/* --- Entradilla --- */
.about-hero {
  background: var(--accent-soft);
  text-align: center;
}

/* El titulo grande de cada pagina, con la tipografia y el tratamiento de la
   portada: azul con contorno blanco. El contorno funciona aqui porque el fondo
   es el azul palido de la entradilla, no blanco puro: el halo se ve y separa
   las letras del fondo en vez de comerselas. */
.about-title {
  font-family: 'Cheri', 'Baloo 2', cursive;
  font-weight: 400;
  font-size: clamp(2.1rem, 6vw, 3.2rem);
  color: var(--titulo);
  margin-bottom: 1rem;
  letter-spacing: 0.5px;
  -webkit-text-stroke: 2.5px #ffffff;
  paint-order: stroke fill;
}

.about-lead {
  font-size: clamp(1.05rem, 2.5vw, 1.25rem);
  line-height: 1.7;
  max-width: 46ch;
  margin: 0 auto 1.25rem;
}

/* Sede, ciudad y franja de edad. Aqui el acento SI vale para texto porque
   --text-strong es el verde accesible, no el color de marca. */
.about-where {
  font-weight: 600;
  color: var(--text-strong);
  margin: 0;
}

/* --- Mision, vision, objetivo --- */
.purpose-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
  gap: 1.5rem;
}

/* Claymorphism suave, el lenguaje visual del sitio: bordes muy redondeados
   y sombra baja en vez de linea. */
.purpose-card {
  background: var(--surface);
  border-radius: 20px;
  border-top: 5px solid var(--accent);
  padding: 1.75rem;
  box-shadow: 0 6px 22px rgba(0, 0, 0, 0.07);
}

.purpose-card h2 {
  font-family: 'Baloo 2', cursive;
  font-size: 1.3rem;
  color: var(--text-strong);
  margin-bottom: 0.75rem;
}

.purpose-card p {
  line-height: 1.7;
  margin: 0;
}

/* --- Horario en la entradilla --- */
.about-hours {
  font-size: 0.95rem;
  margin: 0.35rem 0 0;
}

/* --- Compromiso y trayectoria (brochure) --- */
.about-commitment {
  text-align: center;
}

.commitment-text {
  font-size: clamp(1.05rem, 2.2vw, 1.2rem);
  line-height: 1.75;
  max-width: 60ch;
  margin: 0 auto 1.25rem;
}

/* La trayectoria se destaca sin gritar: un filete del color de la sede
   a la izquierda, que es mas sobrio que una caja entera. */
.commitment-years {
  max-width: 60ch;
  margin: 0 auto;
  padding: 0.9rem 1.25rem;
  text-align: left;
  background: var(--accent-soft);
  border-left: 4px solid var(--accent);
  border-radius: 0 12px 12px 0;
  font-weight: 600;
  line-height: 1.6;
}

/* --- Propuesta pedagogica --- */
.about-pedagogy {
  text-align: center;
}

.pedagogy-intro,
.pedagogy-closing {
  max-width: 62ch;
  margin: 0 auto;
  line-height: 1.7;
}

.pedagogy-closing {
  margin-top: 1.75rem;
  font-style: italic;
}

/* Los centros de aprendizaje son etiquetas, no parrafos: se leen de un vistazo
   y se reordenan solas segun el ancho. */
.center-grid {
  list-style: none;
  padding: 0;
  margin: 1.75rem auto 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.6rem;
}

.center-chip {
  background: var(--accent-soft);
  border: 2px solid var(--accent);
  border-radius: 999px;
  padding: 0.5rem 1.1rem;
  font-weight: 600;
  font-size: 0.95rem;
  line-height: 1.3;
}

/* --- Que incluye y como trabajamos --- */
.about-program {
  background: var(--accent-soft);
}

.program-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));
  gap: 2rem;
}

.program-col .section-title {
  text-align: left;
}

.program-col .section-title::after {
  margin-left: 0;
}

.service-list,
.work-list {
  list-style: none;
  padding: 0;
  margin: 0;
}

.service-list li,
.work-list li {
  position: relative;
  padding-left: 1.9rem;
  margin-bottom: 0.85rem;
  line-height: 1.6;
}

/* Punto solido para lo que incluye: es un inventario. */
.service-list li::before {
  content: "";
  position: absolute;
  left: 0.35rem;
  top: 0.55em;
  width: 0.6rem;
  height: 0.6rem;
  border-radius: 50%;
  background-color: var(--accent-deep);
}

/* Flecha para como trabajamos: son acciones, no cosas. */
.work-list li::before {
  content: "";
  position: absolute;
  left: 0.2rem;
  top: 0.3em;
  width: 1rem;
  height: 1rem;
  background-color: var(--accent-deep);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14M13 6l6 6-6 6'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14M13 6l6 6-6 6'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* --- Valores --- */
.about-values {
  text-align: center;
}

.values-intro {
  max-width: 55ch;
  margin: 0 auto 1.75rem;
  line-height: 1.7;
}

.values-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
  gap: 1rem;
  text-align: left;
}

/* Corazon en vez de marca: los valores no son requisitos que se cumplen,
   y el icono no se anuncia porque es una mascara, no un caracter. */
.values-list li {
  position: relative;
  padding: 1rem 1rem 1rem 3rem;
  background: var(--surface);
  border-radius: 14px;
  line-height: 1.55;
  box-shadow: 0 3px 12px rgba(0, 0, 0, 0.05);
}

.values-list li::before {
  content: "";
  position: absolute;
  left: 1rem;
  top: 1.05rem;
  width: 1.25rem;
  height: 1.25rem;
  background-color: var(--accent-deep);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 21s-8-5.2-8-10.4A4.6 4.6 0 0 1 12 7a4.6 4.6 0 0 1 8 3.6C20 15.8 12 21 12 21z'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 21s-8-5.2-8-10.4A4.6 4.6 0 0 1 12 7a4.6 4.6 0 0 1 8 3.6C20 15.8 12 21 12 21z'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* --- Lema del brochure, sobre el CTA --- */
.cta-tagline {
  font-family: 'Baloo 2', cursive;
  font-size: 1.1rem;
  letter-spacing: 0.03em;
  margin-bottom: 0.35rem;
  opacity: 0.95;
}

/* --- Por que confian en nosotros --- */
.about-trust {
  background: var(--accent-soft);
}

.trust-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
  gap: 1rem;
}

.trust-list li {
  background: var(--surface);
  border-radius: 14px;
  padding: 1rem 1rem 1rem 3rem;
  position: relative;
  font-weight: 600;
  line-height: 1.5;
  box-shadow: 0 3px 12px rgba(0, 0, 0, 0.05);
}

/* La marca es un DIBUJO, no un caracter. Poner "✓" en ::before no lo oculta:
   NVDA, JAWS y VoiceOver anuncian el contenido generado, asi que leerian
   "marca de verificacion" antes de cada punto. Un SVG de fondo no se anuncia. */
.trust-list li::before {
  content: "";
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6L9 17l-5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 0.85rem 0.85rem;
  position: absolute;
  left: 1rem;
  top: 50%;
  transform: translateY(-50%);
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 50%;
  /* background-COLOR, no la abreviada: la abreviada borraria el background-image
     de arriba, que es el dibujo de la marca. */
  background-color: var(--accent-deep);
}

/* --- Equipo --- */
.team-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
  gap: 1.5rem;
  justify-content: center;
}

.team-card {
  background: var(--surface);
  border-radius: 20px;
  padding: 1.75rem;
  text-align: center;
  box-shadow: 0 6px 22px rgba(0, 0, 0, 0.07);
}

.team-photo {
  width: 7.5rem;
  height: 7.5rem;
  border-radius: 50%;
  margin: 0 auto 1rem;
  background-size: cover;
  background-position: center;
  border: 4px solid var(--accent);
}

/* Sin foto todavia: un circulo del color suave de la sede, no un hueco roto. */
.team-photo-empty {
  background: var(--accent-soft);
}

.team-name {
  font-family: 'Baloo 2', cursive;
  font-size: 1.25rem;
  color: var(--text-strong);
  margin-bottom: 0.25rem;
}

.team-role {
  font-weight: 600;
  margin-bottom: 0.75rem;
}

/* El mismo ancho que la presentación de Darling (40rem). Cuando la tarjeta
   ocupa toda la fila, una biografía de cuatro frases salía en líneas de ~130
   caracteres, el doble de lo que se lee cómodo. */
.team-bio {
  line-height: 1.6;
  margin: 0 auto;
  max-width: 40rem;
  text-wrap: pretty;
}

/* --- Llamada a la accion --- */
.about-cta {
  background: var(--accent-deep);
  color: #ffffff;
  text-align: center;
}

/* La llamada a la accion va sobre fondo de color: aqui el titulo es blanco y
   el contorno sobra. La tipografia si se unifica. */
.about-cta h2 {
  font-family: 'Cheri', 'Baloo 2', cursive;
  font-weight: 400;
  font-size: clamp(1.7rem, 4.5vw, 2.4rem);
  color: #ffffff;
  margin-bottom: 0.5rem;
  letter-spacing: 0.5px;
}

.about-cta p {
  margin-bottom: 1.5rem;
  opacity: 0.95;
}

/* Boton blanco sobre el acento: maximo contraste en ambas sedes. */
.cta-button {
  display: inline-block;
  background: #ffffff;
  color: var(--text-strong);
  font-family: 'Baloo 2', cursive;
  font-weight: 700;
  font-size: 1.05rem;
  padding: 0.8rem 2.2rem;
  border-radius: 999px;
  text-decoration: none;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.15);
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}

.cta-button:hover,
.cta-button:focus {
  color: var(--text-strong);
  text-decoration: none;
  transform: translateY(-2px);
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.2);
}

/* El foco debe verse sobre fondo de color: blanco no serviria. */
.cta-button:focus-visible {
  outline: 3px solid #ffffff;
  outline-offset: 3px;
}

/* Dos acciones en la llamada final: apuntarse pesa mas que preguntar, asi que
   la secundaria va en version contorno. */
.cta-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  justify-content: center;
}

.cta-button-ghost {
  background: transparent;
  color: #ffffff;
  border: 2px solid #ffffff;
  box-shadow: none;
}

.cta-button-ghost:hover,
.cta-button-ghost:focus {
  background: #ffffff;
  color: var(--text-strong);
}

/* La lista de espera es la accion principal del menu, asi que va como boton
   y no como un enlace mas. `nowrap` evita que "Waiting List" parta en dos
   lineas y descuadre la barra. */
.navbar .nav-item-cta a.nav-link {
  white-space: nowrap;
  background: #ffffff;
  border-radius: 999px;
  padding: 0.35rem 1rem;
  margin-left: 0.4rem;
}

/* El color va tambien en los descendientes: style.css pinta de blanco el span y
   el icono de dentro de cada enlace del menu, y sobre la pastilla blanca eso
   dejaba el boton vacio. Se vio al mirar la pagina, no al leer el CSS. */
.navbar .nav-item-cta a.nav-link,
.navbar .nav-item-cta a.nav-link span,
.navbar .nav-item-cta a.nav-link i {
  color: var(--accent-deep);
}

.navbar .nav-item-cta a.nav-link:hover,
.navbar .nav-item-cta a.nav-link:hover span,
.navbar .nav-item-cta a.nav-link:hover i {
  color: var(--accent-deep);
}

.navbar .nav-item-cta a.nav-link:hover {
  filter: brightness(0.95);
}

/* El subrayado animado de los demas enlaces sobraria dentro del boton. */
.navbar .nav-item-cta a.nav-link::after,
.navbar .nav-item-cta.active a.nav-link::after {
  display: none;
}

.navbar .nav-item-cta a.nav-link:focus-visible {
  outline: 3px solid #ffffff;
  outline-offset: 2px;
}

/* Con el menu desplegado en movil, el boton ocupa su propia fila entera. */
@media (max-width: 991.98px) {
  .navbar .nav-item-cta a.nav-link {
    display: inline-block;
    margin: 0.5rem 0 0;
  }
}

/* ==========================================================================
   LISTA DE ESPERA
   ========================================================================== */

/* El iframe al que Google responde. No se puede usar display:none en algunos
   navegadores sin que el envio falle, asi que se saca de pantalla. */
.visually-hidden-frame {
  position: absolute;
  width: 1px;
  height: 1px;
  border: 0;
  clip-path: inset(50%);
  overflow: hidden;
}

.waitlist-form-section .container {
  max-width: 720px;
}

/* --- Aviso de formulario sin conectar --- */
.form-offline {
  background: var(--accent-soft);
  border-left: 5px solid var(--accent-deep);
  border-radius: 0 16px 16px 0;
  padding: 1.75rem;
  text-align: center;
}

.form-offline h2 {
  font-family: 'Baloo 2', cursive;
  font-size: 1.35rem;
  color: var(--text-strong);
  margin-bottom: 0.5rem;
}

.form-offline-contact {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  justify-content: center;
  margin: 1.25rem 0 0;
}

/* Fuera del CTA de color, el boton necesita relleno propio para verse. */
.form-offline-contact .cta-button,
.wl-submit {
  background: var(--accent-deep);
  color: #ffffff;
}

.form-offline-contact .cta-button:hover,
.form-offline-contact .cta-button:focus,
.wl-submit:hover,
.wl-submit:focus {
  color: #ffffff;
}

.wl-submit:focus-visible {
  outline: 3px solid var(--accent-deep);
  outline-offset: 3px;
}

/* --- El formulario --- */
.wl-form fieldset {
  border: 0;
  padding: 0;
  margin: 0 0 2rem;
}

.wl-form legend {
  font-family: 'Baloo 2', cursive;
  font-size: 1.3rem;
  color: var(--text-strong);
  padding: 0;
  margin-bottom: 1rem;
  width: 100%;
  border-bottom: 2px solid var(--accent);
  padding-bottom: 0.4rem;
}

.wl-field {
  margin-bottom: 1.25rem;
}

/* Dos columnas en pantalla ancha, una sola en movil, sin punto de ruptura. */
.wl-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
  gap: 0 1.25rem;
}

.wl-field label,
.wl-label {
  display: block;
  font-weight: 600;
  margin-bottom: 0.35rem;
}

/* El asterisco es decorativo: el campo ya lleva `required`, que es lo que
   anuncia el lector de pantalla. */
.req {
  color: var(--text-strong);
}

.wl-field input[type="text"],
.wl-field input[type="email"],
.wl-field input[type="tel"],
.wl-field input[type="date"],
.wl-field textarea {
  width: 100%;
  padding: 0.7rem 0.9rem;
  font: inherit;
  color: var(--text);
  background: var(--surface);
  border: 2px solid #cfd8dd;
  border-radius: 12px;
}

.wl-field input:focus,
.wl-field textarea:focus {
  outline: none;
  border-color: var(--accent-deep);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

/* El foco NO puede depender solo del color: se marca tambien con el contorno
   del navegador para quien no distinga el cambio de borde. */
.wl-field input:focus-visible,
.wl-field textarea:focus-visible {
  outline: 2px solid var(--accent-deep);
  outline-offset: 1px;
}

.wl-field textarea {
  resize: vertical;
}

.wl-help {
  font-size: 0.875rem;
  margin: 0.4rem 0 0;
}

.wl-choices {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

/* Toda la etiqueta es zona de clic, no solo el circulito. */
.wl-choice {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  margin: 0;
  padding: 0.55rem 1rem;
  font-weight: 500;
  background: var(--surface);
  border: 2px solid #cfd8dd;
  border-radius: 999px;
  cursor: pointer;
}

.wl-choice:focus-within {
  border-color: var(--accent-deep);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.wl-choice input {
  accent-color: var(--accent-deep);
  margin: 0;
}

.wl-privacy {
  font-size: 0.9rem;
  background: var(--accent-soft);
  border-radius: 12px;
  padding: 0.9rem 1.1rem;
  margin-bottom: 1.5rem;
}

.wl-submit {
  display: block;
  width: 100%;
  border: 0;
  cursor: pointer;
}

.wl-submit:disabled {
  opacity: 0.65;
  cursor: progress;
}

/* --- Confirmacion --- */
.wl-success {
  text-align: center;
  background: var(--accent-soft);
  border-radius: 20px;
  padding: 2.5rem 1.5rem;
}

.wl-success:focus {
  outline: none;
}

.wl-success h2 {
  font-family: 'Baloo 2', cursive;
  font-size: clamp(1.5rem, 4vw, 2rem);
  color: var(--text-strong);
  margin-bottom: 0.6rem;
}

.wl-success-contact {
  margin: 1rem 0 0;
  font-weight: 600;
}

/* ==========================================================================
   FORMULARIO DE CONTACTO
   Reutiliza los estilos de campo de la lista de espera; solo cambia la rejilla.
   ========================================================================== */
.cf-form {
  margin-top: 1.5rem;
}

.cf-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
  gap: 0 1.25rem;
}

.cf-field {
  margin-bottom: 1.25rem;
}

.cf-field label {
  display: block;
  font-weight: 600;
  margin-bottom: 0.35rem;
}

.cf-field input,
.cf-field textarea {
  width: 100%;
  padding: 0.7rem 0.9rem;
  font: inherit;
  color: var(--text);
  background: var(--surface);
  border: 2px solid #cfd8dd;
  border-radius: 12px;
}

.cf-field textarea {
  resize: vertical;
}

.cf-field input:focus,
.cf-field textarea:focus {
  outline: none;
  border-color: var(--accent-deep);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.cf-field input:focus-visible,
.cf-field textarea:focus-visible {
  outline: 2px solid var(--accent-deep);
  outline-offset: 1px;
}

/* Trampa para robots. Se saca de pantalla en vez de usar display:none porque
   algunos bots detectan display:none y se saltan el campo; asi pican mas.
   Una persona nunca lo ve ni lo alcanza con el tabulador. */
.gform-trampa-caja {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* Si el envío falla de verdad, se ve. El rojo es el unico sitio del sitio donde
   se usa: significa "esto no ha salido", no decoración. */
.cf-error {
  margin-top: 1.25rem;
  padding: 1rem 1.15rem;
  background: #fdecec;
  border-left: 5px solid #b3261e;
  border-radius: 0 12px 12px 0;
  color: #8c1d18;
  font-weight: 600;
  line-height: 1.6;
}

.cf-error a {
  color: inherit;
  text-decoration: underline;
}

/* ==========================================================================
   CONTACTO
   ========================================================================== */

.branch-contacto .container {
  max-width: 1100px;
}

.contacto-seccion {
  padding-block: 3rem;
}

.contacto-grid {
  display: grid;
  gap: 2.5rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));
}

.contacto-datos .section-title,
.contacto-formulario .section-title {
  text-align: left;
}

.contacto-datos .section-title::after,
.contacto-formulario .section-title::after {
  margin-left: 0;
}

.dato-lista {
  list-style: none;
  padding: 0;
  margin: 0 0 2rem;
}

.dato-lista li {
  display: flex;
  gap: 0.9rem;
  align-items: flex-start;
  padding: 0.9rem 0;
  border-bottom: 1px solid #e3eaee;
  line-height: 1.55;
}

.dato-lista li:last-child {
  border-bottom: 0;
}

/* Los iconos toman el color de la sede. Antes eran una mezcla de imagenes PNG
   y FontAwesome, con un morado #7C6BC4 escrito a fuego en las dos sedes. */
.dato-icono {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent-deep);
}

.dato-lista strong {
  display: block;
  color: var(--text-strong);
  font-size: 0.9rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  margin-bottom: 0.1rem;
}

.dato-lista a {
  color: var(--text);
  text-decoration: underline;
}

.contacto-mapa {
  border-radius: 16px;
  overflow: hidden;
  box-shadow: 0 6px 22px rgba(0, 0, 0, 0.07);
  /* aspect-ratio en vez de altura fija: el mapa se adapta al ancho sin dejar
     franjas vacias ni recortarse en movil. */
  aspect-ratio: 4 / 3;
  max-width: 100%;
}

.contacto-mapa iframe {
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}

/* ==========================================================================
   PORTADA DE SEDE
   ========================================================================== */

.branch-home .container {
  max-width: 1100px;
}

.branch-home section {
  padding-block: 3rem;
}

.home-intro {
  background: var(--accent-soft);
  text-align: center;
}

.home-cta {
  margin-top: 1.5rem;
}

/* Fuera de la franja de color, el boton secundario necesita su propio borde:
   el de contorno blanco desapareceria sobre fondo claro. */
.cta-button-hueco {
  background: transparent;
  color: var(--text-strong);
  border: 2px solid var(--accent-deep);
  box-shadow: none;
}

.cta-button-hueco:hover,
.cta-button-hueco:focus {
  background: var(--accent-deep);
  color: #ffffff;
}

/* --- Las cuatro cifras --- */
.datos-grid {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
  text-align: center;
}

.datos-grid li {
  padding: 1.25rem 1rem;
  background: var(--surface);
  border-radius: 16px;
  box-shadow: 0 3px 12px rgba(0, 0, 0, 0.05);
}

.datos-grid strong {
  display: block;
  font-family: 'Baloo 2', cursive;
  font-size: 1.2rem;
  color: var(--text-strong);
  line-height: 1.25;
  margin-bottom: 0.25rem;
}

.datos-grid span {
  display: block;
  font-size: 0.9rem;
}

/* --- Qué ofrecemos --- */
/* Flex y no grid, a proposito.
   Con `grid-template-columns: repeat(auto-fit, ...)` las cinco tarjetas caian
   4 + 1: la ultima se quedaba sola en su fila, alineada a la izquierda, y
   parecia un error de maquetacion mas que una tarjeta mas.
   Con flex y `justify-content: center`, la fila incompleta se CENTRA: 3 + 2
   se lee como una decision, no como un sobrante. */
.oferta-grid {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 1.5rem;
}

.oferta-grid > li {
  flex: 1 1 15rem;
  max-width: 22rem;
}

/* A partir de tablet se fijan tres por fila. Sin esto, flex encaja cuatro en
   pantallas anchas y vuelve el mismo problema del huerfano. */
@media (min-width: 56rem) {
  .oferta-grid > li {
    flex: 0 1 calc(33.333% - 1rem);
    max-width: none;
  }
}

.oferta-card {
  background: var(--surface);
  border-radius: 20px;
  border-top: 5px solid var(--accent);
  padding: 1.75rem;
  text-align: center;
  box-shadow: 0 6px 22px rgba(0, 0, 0, 0.07);
}

.oferta-icono {
  display: grid;
  place-items: center;
  width: 3.5rem;
  height: 3.5rem;
  margin: 0 auto 1rem;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent-deep);
  font-size: 1.35rem;
}

.oferta-card h3 {
  font-family: 'Baloo 2', cursive;
  font-size: 1.15rem;
  color: var(--text-strong);
  margin-bottom: 0.5rem;
}

.oferta-card p {
  margin: 0;
  line-height: 1.6;
}

/* --- Avance de programas --- */
.home-programas {
  background: var(--accent-soft);
  text-align: center;
}

.avance-grid {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.6rem;
}

.avance-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  background: var(--surface);
  border: 2px solid var(--accent);
  border-radius: 999px;
  padding: 0.55rem 1.15rem;
  font-weight: 600;
  font-size: 0.95rem;
}

.avance-chip i {
  color: var(--accent-deep);
}

.avance-mas {
  margin: 1.75rem 0 0;
  font-weight: 700;
}

.avance-mas a {
  color: var(--text-strong);
  text-decoration: underline;
}

/* --- Testimonios --- */
.testimonio-grid {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 1.5rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr));
}

.testimonio-card {
  background: var(--surface);
  border-radius: 20px;
  padding: 1.75rem;
  box-shadow: 0 6px 22px rgba(0, 0, 0, 0.07);
  display: flex;
  flex-direction: column;
}

.testimonio-card blockquote {
  margin: 0 0 1.25rem;
  padding: 0;
  border: 0;
  /* Empuja al autor al fondo: las tarjetas lo alinean aunque las citas
     tengan distinto largo. */
  flex: 1;
}

.testimonio-card blockquote p {
  margin: 0;
  line-height: 1.7;
  font-style: italic;
}

/* La comilla es decorativa y va en ::before, para que el lector de pantalla
   no la anuncie como parte de la cita. */
.testimonio-card blockquote::before {
  content: "\201C";
  display: block;
  font-family: 'Baloo 2', cursive;
  font-size: 2.5rem;
  line-height: 1;
  color: var(--accent);
}

.testimonio-autor {
  display: flex;
  align-items: center;
  gap: 0.85rem;
}

.testimonio-autor img,
.testimonio-inicial {
  flex: 0 0 auto;
  width: 3rem;
  height: 3rem;
  border-radius: 50%;
  object-fit: cover;
}

/* Sin foto: la inicial sobre el color de la sede. Mas honesto que una imagen
   de banco de una persona que no es esa familia. */
.testimonio-inicial {
  display: grid;
  place-items: center;
  background: var(--accent-deep);
  color: #ffffff;
  font-family: 'Baloo 2', cursive;
  font-size: 1.3rem;
}

.testimonio-autor strong {
  display: block;
  color: var(--text-strong);
}

.testimonio-rol {
  display: block;
  font-size: 0.9rem;
}

/* ==========================================================================
   PÁGINA DE PROGRAMAS / ACTIVIDADES
   ========================================================================== */

.branch-programas .container {
  max-width: 1100px;
}

.programas-lista {
  padding-block: 3rem;
}

/* --- Revere: actividades (sin pagina propia) --- */
.actividad-grid,
.programa-grid {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 1.5rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
}

/* --- Everett: programas con pagina propia --- */
.programa-card {
  background: var(--surface);
  border-radius: 20px;
  overflow: hidden;
  box-shadow: 0 6px 22px rgba(0, 0, 0, 0.07);
}

/* Toda la tarjeta es el enlace, no solo el titulo: mas facil de acertar en
   movil y no obliga a apuntar a un texto pequeno. */
.programa-card > a {
  display: flex;
  flex-direction: column;
  height: 100%;
  color: var(--text);
  text-decoration: none;
}

.programa-card > a:hover,
.programa-card > a:focus {
  color: var(--text);
  text-decoration: none;
}

/* LA PROPORCION DE LA TARJETA, por sede.
   No es un capricho: las fotos de cada sede vienen en formatos distintos y la
   misma proporcion no puede servir a las dos.

   Everett son fotos APAISADAS -> 3:2 les va bien, apenas se recortan.
   Revere son fotos VERTICALES del movil -> con 3:2 se conservaba el 50 % de la
   imagen, y se notaba: caras a medias y encuadres apretados. En CUADRADO se
   conserva el 75 %, que con el 4:5 en que se guardan deja la foto casi entera.

   El icono lleva la MISMA proporcion que la foto. Antes la imagen era 3:2 y el
   icono 4:3, asi que la ficha sin foto quedaba de otra altura y desalineaba la
   fila. */
.programa-card img {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  display: block;
}

[data-branch="revere"] .programa-card img,
[data-branch="revere"] .programa-icono {
  aspect-ratio: 1;
}

.programa-texto {
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: 1.4rem;
}

.programa-card h2 {
  font-family: 'Baloo 2', cursive;
  font-size: 1.25rem;
  color: var(--text-strong);
  margin-bottom: 0.5rem;
}

.programa-info {
  display: block;
  line-height: 1.6;
  /* Empuja "Leer mas" al fondo: todas las tarjetas lo alinean aunque los
     textos tengan distinto largo. */
  flex: 1;
  margin-bottom: 0.9rem;
}

.programa-mas {
  display: block;
  font-weight: 700;
  color: var(--text-strong);
}

.programa-card > a:hover .programa-mas {
  text-decoration: underline;
}

.programa-card > a:focus-visible {
  outline: 3px solid var(--accent-deep);
  outline-offset: 3px;
}

/* ==========================================================================
   PÁGINA DE UNA CLASE
   ========================================================================== */

/* El contenido del programa, ahora desde datos y en los dos idiomas. */
.prog-intro {
  font-family: 'Baloo 2', cursive;
  font-size: 1.5rem;
  color: var(--text-strong);
  margin-bottom: 1.5rem;
}

.prog-bloque {
  margin-bottom: 1.75rem;
}

.prog-bloque h3 {
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--text);
  margin-bottom: 0.6rem;
  padding-bottom: 0.4rem;
  border-bottom: 2px solid var(--accent-soft);
}

.prog-bloque ul {
  margin: 0;
  padding-left: 1.3rem;
}

.prog-bloque li {
  margin-bottom: 0.45rem;
  line-height: 1.6;
}

.prog-cierre {
  line-height: 1.75;
  margin-bottom: 1rem;
}

/* La accion principal de la barra lateral: apuntarse. Antes ahi habia un precio
   roto ("$ Included.00") y una valoracion de cinco estrellas inventada. */
.clase-cta {
  margin: 1.5rem 0;
  padding: 1.5rem;
  background: var(--accent-soft);
  border-radius: 16px;
  text-align: center;
}

.clase-cta p {
  margin-bottom: 1rem;
  line-height: 1.6;
}

.clase-cta .cta-button {
  background: var(--accent-deep);
  color: #ffffff;
}

.clase-cta .cta-button:hover,
.clase-cta .cta-button:focus {
  color: #ffffff;
}

.clase-otras-titulo {
  font-family: 'Baloo 2', cursive;
  font-size: 1.3rem;
  color: var(--text-strong);
  margin-bottom: 0.75rem;
}

.clase-otras {
  list-style: none;
  padding: 0;
  margin: 0;
}

/* Toda la fila es enlace, no solo el nombre: mas facil de acertar en movil. */
.clase-otra {
  display: flex;
  gap: 0.85rem;
  align-items: flex-start;
  padding: 0.85rem 0;
  color: var(--text);
  text-decoration: none;
}

.clase-otra:hover,
.clase-otra:focus {
  color: var(--text);
  text-decoration: none;
}

.clase-otra:hover strong {
  text-decoration: underline;
}

.clase-otra img {
  flex: 0 0 auto;
  width: 4.5rem;
  height: 4.5rem;
  object-fit: cover;
  border-radius: 12px;
}

.clase-otra strong {
  display: block;
  color: var(--text-strong);
  font-size: 1.02rem;
  margin-bottom: 0.2rem;
}

.clase-otra-info {
  display: block;
  font-size: 0.9rem;
  line-height: 1.45;
}

.clase-otra:focus-visible {
  outline: 3px solid var(--accent-deep);
  outline-offset: 3px;
  border-radius: 12px;
}

/* --- Avisos de campo sin responder --- */

/* El error NO se marca solo con color: lleva tambien un icono y el borde del
   campo cambia de grosor. Quien no distingue el rojo tiene que enterarse
   igual (WCAG 1.4.1). */
.campo-error {
  display: flex;
  align-items: flex-start;
  gap: 0.4rem;
  margin: 0.4rem 0 0;
  color: #8c1d18;
  font-size: 0.9rem;
  font-weight: 600;
  line-height: 1.45;
}

.campo-error::before {
  content: "";
  flex: 0 0 auto;
  width: 1.05rem;
  height: 1.05rem;
  margin-top: 0.1rem;
  background-color: #b3261e;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2 1 21h22L12 2zm0 6v7m0 3v1' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2 1 21h22L12 2zm0 6v7m0 3v1' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round'/%3E%3C/svg%3E") center / contain no-repeat;
}

.campo-invalido input,
.campo-invalido textarea {
  border-color: #b3261e;
  border-width: 3px;
}

.campo-invalido .wl-choice {
  border-color: #b3261e;
}

/* Resumen al pie del formulario: dice cuántas faltan antes de que la persona
   se ponga a buscarlas. */
.form-resumen-error {
  margin-bottom: 1.25rem;
  padding: 1rem 1.15rem;
  background: #fdecec;
  border-left: 5px solid #b3261e;
  border-radius: 0 12px 12px 0;
  color: #8c1d18;
  font-weight: 600;
  line-height: 1.6;
}

.form-resumen-error:focus {
  outline: 3px solid #b3261e;
  outline-offset: 2px;
}

/* ==========================================================================
   PIE: telefono y correo ahora son enlaces
   Sin esto heredan el azul por defecto de Bootstrap (#007bff), que sobre el
   fondo del pie da 3,26:1 y no llega a AA. El texto vecino usa #555 (6,11:1),
   asi que se igualan a el.
   El subrayado se queda: el color por si solo no puede ser la unica senal de
   que algo es un enlace (WCAG 1.4.1).
   ========================================================================== */
footer .address a {
  color: inherit;
  text-decoration: underline;
}

footer .address a:hover,
footer .address a:focus {
  color: inherit;
  text-decoration: none;
}

/* ==========================================================================
   PARA LAS FAMILIAS — noticias, avisos y boletín
   ========================================================================== */

/* El conmutador de idioma en versión BLOQUE.
   El `.i18n` de arriba es `display: inline`, que vale para una frase suelta
   dentro de un párrafo. El cuerpo de una noticia son varios párrafos, y con
   `inline` se apelotonarían todos en una sola línea corrida. Aquí se repite la
   misma lógica de tres reglas pero conmutando a `block`.
   Las tres reglas son necesarias: el idioma vive en `data-lang` del <body>, y
   hay que cubrir el estado por defecto (sin atributo) y los dos explícitos. */
.i18n-bloque[lang="es"] {
  display: none;
}

[data-lang="es"] .i18n-bloque[lang="en"] {
  display: none;
}

[data-lang="es"] .i18n-bloque[lang="es"] {
  display: block;
}

/* --- La lista de noticias --- */
.news-lista {
  padding: 1rem 0 3rem;
}

.news-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 1.75rem;
}

.news-card {
  display: grid;
  grid-template-columns: minmax(0, 15rem) minmax(0, 1fr);
  gap: 1.5rem;
  align-items: start;
  background-color: var(--surface);
  border: 1px solid rgba(0, 0, 0, 0.07);
  border-radius: 1.25rem;
  padding: 1.25rem;
}

/* Sin foto, el texto ocupa las dos columnas en vez de dejar un hueco. */
.news-card:not(:has(.news-foto)) {
  grid-template-columns: minmax(0, 1fr);
}

.news-foto {
  display: block;
  border-radius: 0.9rem;
  overflow: hidden;
}

.news-foto img {
  width: 100%;
  /* Relación fija: las fotos que suba el centro vendrán de tamaños dispares y
     sin esto cada tarjeta tendría una altura distinta. */
  aspect-ratio: 4 / 3;
  object-fit: cover;
  display: block;
}

.news-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
  margin-bottom: 0.4rem;
  font-size: 0.9rem;
  /* Tono secundario: la fecha acompaña al titular, no compite con él. */
  color: var(--text-suave);
}

.news-titulo {
  font-family: 'Cheri', 'Baloo 2', cursive;
  font-size: 1.6rem;
  margin: 0 0 0.5rem;
  line-height: 1.2;
}

/* Azul, NO el verde de --text-strong. Ese token es anterior a la unificación de
   las dos sedes en azul, y un titular verde en una página donde todo lo demás
   —cabecera, título de sección, título de página— es azul canta como un error. */
.news-titulo a {
  color: var(--titulo);
  text-decoration: none;
}

.news-titulo a:hover,
.news-titulo a:focus-visible {
  text-decoration: underline;
}

.news-resumen {
  margin: 0 0 0.6rem;
}

.news-mas a {
  color: var(--accent-texto);
  font-weight: 600;
  text-decoration: none;
}

.news-mas a:hover,
.news-mas a:focus-visible {
  text-decoration: underline;
}

.news-vacio {
  text-align: center;
  max-width: 40rem;
  margin: 0 auto;
  padding: 2rem 0;
}

/* --- Una noticia suelta --- */
.news-detalle {
  padding: 2.5rem 0 1rem;
}

.news-detalle > .container {
  max-width: 44rem;
}

.news-detalle-foto {
  width: 100%;
  border-radius: 1.25rem;
  margin-bottom: 1.5rem;
}

/* Los dos bloques de idioma comparten el mismo ritmo de lectura. */
.news-detalle-cuerpo p {
  margin-bottom: 1rem;
}

.news-detalle-cuerpo h2,
.news-detalle-cuerpo h3 {
  font-family: 'Cheri', 'Baloo 2', cursive;
  margin: 1.75rem 0 0.75rem;
}

.news-volver {
  margin-top: 1.75rem;
}

.news-volver a {
  color: var(--accent-texto);
  font-weight: 600;
}

/* --- Instagram: un enlace, no un muro incrustado --- */
.news-redes {
  background-color: var(--accent-soft);
  padding: 2.5rem 0;
  text-align: center;
}

.news-redes-texto {
  max-width: 34rem;
  margin: 0 auto 1.25rem;
}

.news-redes-boton i {
  margin-right: 0.5rem;
}

/* --- El boletín --- */
.news-boletin {
  padding: 2.5rem 0 3rem;
  text-align: center;
}

.boletin-texto {
  margin-bottom: 1rem;
}

.boletin-seccion .boletin-texto {
  max-width: 36rem;
  margin-left: auto;
  margin-right: auto;
}

.boletin-form {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  justify-content: center;
}

.boletin-pie .boletin-form {
  justify-content: flex-start;
}

.boletin-input {
  flex: 1 1 14rem;
  min-width: 0;
  padding: 0.7rem 1rem;
  border: 1px solid rgba(0, 0, 0, 0.18);
  border-radius: 999px;
  font: inherit;
}

.boletin-input:focus-visible {
  outline: 3px solid var(--accent-deep);
  outline-offset: 2px;
}

.boletin-boton {
  background-color: var(--accent-deep);
  color: #ffffff;
  border: none;
  border-radius: 999px;
  padding: 0.7rem 1.6rem;
  font-weight: 600;
  cursor: pointer;
}

.boletin-boton:hover,
.boletin-boton:focus-visible {
  filter: brightness(1.08);
}

/* La nota de la baja: obligatoria por ley y deliberadamente discreta.
   No se baja de 0.8rem ni se aclara más: tiene que poder leerse. */
.boletin-letra-pequena {
  flex-basis: 100%;
  margin: 0.5rem 0 0;
  font-size: 0.8rem;
}

.boletin-alternativa a {
  color: var(--accent-texto);
  font-weight: 600;
}

.footer-mas-noticias {
  margin-top: 0.9rem;
}

/* El color se fija aquí a propósito. Heredado del pie salía en 3,26:1 sobre el
   #e0eaf0 del fondo, por debajo del 4,5 exigido. */
.footer-mas-noticias a {
  font-weight: 600;
  color: var(--accent-texto);
}

/* En pantalla estrecha la tarjeta pasa a una columna: la foto arriba y el
   texto debajo, que es como se lee un aviso en el móvil. */
@media (max-width: 40rem) {
  .news-card {
    grid-template-columns: minmax(0, 1fr);
  }

  .news-titulo {
    font-size: 1.35rem;
  }
}

/* EL MENÚ EN PANTALLAS MEDIANAS.
   Al añadir «Familias» el menú pasó de seis elementos a siete, y en español
   —donde las etiquetas son más largas que en inglés: «Horarios», «Nosotros»,
   «Contacto»— dejó de caber: el botón de lista de espera se salía 18px por la
   derecha y aparecía cortado. Medido a 1280px, que es la anchura de portátil
   más común.

   Van dos cambios. Uno: la barra pasa de `navbar-expand-lg` a
   `navbar-expand-xl`, o sea que el menú se pliega en hamburguesa por debajo de
   1200px en vez de 992px. Con seis elementos cabía; con siete, entre 992 y
   1150px el botón se salía casi 90px.
   Y dos: en la franja de 1200 a 1400, donde el menú sí se despliega pero va
   justo, se encoge un poco la letra. Por encima de 1400 sobra sitio y se deja
   el tamaño original. */
@media (min-width: 75em) and (max-width: 87.49em) {
  .navbar.navbar-dark .navbar-nav .nav-item a {
    font-size: 1.12em;
    letter-spacing: 0.2px;
  }

  .navbar .navbar-nav .nav-item a {
    padding-left: 0.4rem;
    padding-right: 0.4rem;
  }
}

/* ==========================================================================
   FONDO Y TEXTO DE LA PÁGINA
   ========================================================================== */

/* style.css fija `color: #555555` directamente en `body` (línea 197) y no
   declara fondo, así que el navegador ponía blanco puro. Aquí se sustituyen
   las dos cosas por los tokens. Misma especificidad que style.css, pero esta
   hoja carga después, así que gana. */
body {
  background-color: var(--fondo);
  color: var(--text);
}

/* La curva bajo el carrusel se dibuja con el color de LO QUE HAY DEBAJO, que
   es el cuerpo de la página. Estaba en blanco puro: al pasar el fondo a crema
   habría dejado una costura blanca justo bajo la foto. */
.slider:after {
  background-color: var(--fondo);
}

/* EL BOTÓN PRINCIPAL DEL CARRUSEL.
   Es la llamada a la acción más visible de la portada, y fallaba en sus DOS
   estados por la misma razón: usaba la pareja blanco / #03a9c9, que da 2,79:1
   mirando por cualquiera de los dos lados —el contraste es simétrico—. El
   propio redesign.css ya avisa arriba de que #03a9c9 «no vale para texto: es
   superficie». Este botón se quedó sin migrar.

   Reposo: blanco sobre --accent-deep (#00808f) = 4,68:1.
   Hover:  --accent-texto (#006b78) sobre blanco = 5,73:1.
   La especificidad iguala la de style.css (0,3,0) y esta hoja carga después. */
.slider .carousel-caption .btn-cta-primary {
  background: var(--accent-deep);
  color: #ffffff;
}

.slider .carousel-caption .btn-cta-primary:hover,
.slider .carousel-caption .btn-cta-primary:focus-visible {
  background: #ffffff;
  color: var(--accent-texto);
}

/* ==========================================================================
   ICONO EN LUGAR DE FOTO
   Las nueve actividades de Revere nacen sin fotografía: las del proyecto son de
   niños de 5 a 8 años y esta sede atiende de 3 meses a 3 años. Un icono grande
   sobre el color de la sede informa peor que una buena foto, pero MUCHO mejor
   que una foto de la edad equivocada. En cuanto haya fotos reales, basta con
   rellenar `image` en _data/activities.yml y estas reglas dejan de aplicarse.
   ========================================================================== */

/* En la tarjeta de la rejilla: ocupa el mismo hueco que la <img> para que las
   tarjetas con foto y sin foto queden alineadas en la misma fila. */
.programa-icono {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 3 / 2;
  background-color: var(--accent-soft);
  color: var(--accent-texto);
  font-size: 3.5rem;
}

/* En la ficha completa, arriba del todo, donde Everett pone su fotografía. */
.clase-icono-grande {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 16 / 7;
  background-color: var(--accent-soft);
  color: var(--accent-texto);
  font-size: 5.5rem;
  border-radius: 1rem;
  margin-bottom: 1.5rem;
}

/* En la lista lateral de «otras actividades»: mismo tamaño que la miniatura. */
.clase-otra-icono {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 4rem;
  height: 4rem;
  flex: 0 0 4rem;
  border-radius: 0.6rem;
  background-color: var(--accent-soft);
  color: var(--accent-texto);
  font-size: 1.5rem;
}

@media (max-width: 40rem) {
  .clase-icono-grande {
    aspect-ratio: 16 / 9;
    font-size: 4rem;
  }
}

/* LOS BLOQUES DE CONTENIDO NO FLOTAN.
   style.css tiene `.classes-details section { float:left; width:63%; margin:0 1.5% }`
   (línea 1230) pensado para LA COLUMNA principal. Pero los bloques de contenido
   también son <section>, y ese selector no distingue entre la sección que hace de
   columna y las que van dentro: cada bloque se ponía a flotar al 63%, y el párrafo
   de cierre se envolvía a su lado en vez de ir debajo. Se veía en las dos sedes.

   La especificidad de aquella regla es 0,2,0, así que `.prog-bloque` a secas (0,1,0)
   no la gana: hay que subir a 0,2,0 y aprovechar que esta hoja carga después.
   Cuarta vez en el proyecto que la especificidad manda sobre el orden. */
.classes-details .prog-bloque {
  float: none;
  width: auto;
  margin: 0 0 1.75rem;
}

/* El cierre tiene que empezar por debajo de todo lo anterior, no al lado. */
.classes-details .prog-cierre {
  clear: both;
}

/* ==========================================================================
   LOS DOS COLORES QUE VIVEN EN style.css
   El pie y la franja superior llevan su azul escrito a fuego allí, así que no
   basta con cambiar un token: hay que sobreescribir la regla. Se usa el token
   para que cada sede ponga el suyo.
   ========================================================================== */

footer {
  background-color: var(--pie-bg);
}

/* La franja de «cambiar ubicación». Lleva texto BLANCO, así que su color es el
   oscuro de la sede, no el claro: #15548d en Revere (7,82:1 con blanco) y
   #335c19 en Everett (7,82:1 también — misma luminancia, mismo contraste). */
.branch-switcher {
  background-color: var(--titulo);
}

/* ==========================================================================
   TABLA DE DÍAS DE CIERRE
   Sale dentro de un artículo de noticias. Toma el color de la sede, así que la
   misma tabla se ve azul en Revere y verde en Everett.
   ========================================================================== */
.cierres-tabla-envoltorio {
  /* La tabla es lo único que puede pedir más ancho que el móvil: se le da su
     propio desplazamiento lateral en vez de dejar que empuje a la página. */
  overflow-x: auto;
  margin: 1.5rem 0 2rem;
  border-radius: 1rem;
  border: 1px solid rgba(0, 0, 0, 0.08);
}

.cierres-tabla {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.95rem;
}

.cierres-tabla thead th {
  background-color: var(--accent-soft);
  color: var(--titulo);
  text-align: left;
  padding: 0.75rem 1rem;
  font-weight: 700;
  white-space: nowrap;
}

.cierres-tabla tbody th,
.cierres-tabla tbody td {
  padding: 0.7rem 1rem;
  border-top: 1px solid rgba(0, 0, 0, 0.07);
  text-align: left;
  vertical-align: top;
}

/* El nombre del día va en <th scope="row">: para un lector de pantalla, cada
   fecha queda asociada a su motivo en vez de leerse como una lista suelta. */
.cierres-tabla tbody th {
  font-weight: 600;
  color: var(--text);
}

.cierres-tabla tbody td {
  white-space: nowrap;
}

/* Los cierres de varios días se destacan: son los que hay que planificar. */
.cierres-tabla .cierre-vacaciones {
  background-color: var(--accent-soft);
}

.cierres-tabla .cierre-vacaciones th,
.cierres-tabla .cierre-vacaciones td {
  font-weight: 700;
}

.cierre-etiqueta {
  display: inline-block;
  margin-left: 0.5rem;
  padding: 0.1rem 0.55rem;
  border-radius: 999px;
  background-color: var(--accent-soft);
  color: var(--accent-texto);
  font-size: 0.75rem;
  font-weight: 700;
  white-space: nowrap;
}

/* Dentro de una fila que ya es del color de acento, la etiqueta se invierte
   para no desaparecer sobre su propio fondo. */
.cierre-vacaciones .cierre-etiqueta-larga {
  background-color: var(--surface);
}

@media (max-width: 36rem) {
  .cierres-tabla {
    font-size: 0.88rem;
  }

  .cierres-tabla thead th,
  .cierres-tabla tbody th,
  .cierres-tabla tbody td {
    padding: 0.6rem 0.7rem;
  }

  /* En móvil la etiqueta baja a su propia línea: al lado del nombre obligaba a
     desplazar la tabla de lado para leer la fecha. */
  .cierre-etiqueta {
    display: block;
    margin: 0.3rem 0 0;
    width: fit-content;
  }
}

/* ==========================================================================
   MENÚ SEMANAL
   Una tarjeta por día, no una tabla. La lámina original es 4 comidas × 5 días,
   que en pantalla son seis columnas y obligan a desplazar de lado en el móvil
   para llegar al viernes. Por día se lee igual de bien en cualquier pantalla, y
   responde a la pregunta real: «¿qué come mi hijo el martes?».
   ========================================================================== */
.menu-seccion {
  background-color: var(--accent-soft);
  padding-block: 3rem;
}

.menu-intro {
  max-width: 44rem;
  margin: 0 auto 2rem;
  text-align: center;
}

.menu-semana {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 1.25rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
}

/* Las columnas se fijan por tramos en vez de dejarlo a `auto-fit`.
   Con auto-fit solo, la semana caía 4 + 1 tanto a 1100px como a 900: el viernes
   se quedaba solo abajo. Una semana partida en 4 + 1 se lee peor que una semana
   entera o que una partida 3 + 2, porque el lector espera cinco días seguidos.

   Tramo medio (tablet): 3 columnas -> 3 + 2, que se lee como dos mitades.
   Tramo ancho: las 5 de una fila. */
@media (min-width: 42rem) {
  .menu-semana {
    grid-template-columns: repeat(3, 1fr);
  }
}

@media (min-width: 66rem) {
  .menu-semana {
    grid-template-columns: repeat(5, 1fr);
  }
}

.menu-dia {
  background-color: var(--surface);
  border-radius: 1rem;
  overflow: hidden;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.07);
  display: flex;
  flex-direction: column;
}

.menu-dia-titulo {
  margin: 0;
  padding: 0.7rem 1rem;
  background-color: var(--accent-deep);
  color: #ffffff;
  font-family: 'Cheri', 'Baloo 2', cursive;
  font-size: 1.25rem;
  font-weight: 400;
  text-align: center;
  letter-spacing: 0.3px;
}

.menu-comidas {
  margin: 0;
  padding: 0.4rem 1rem 1rem;
  flex: 1;
}

.menu-comida + .menu-comida {
  border-top: 1px solid rgba(0, 0, 0, 0.07);
  margin-top: 0.7rem;
  padding-top: 0.7rem;
}

.menu-comida dt {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.78rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: var(--accent-texto);
  margin-bottom: 0.25rem;
}

.menu-icono {
  font-size: 0.85rem;
}

.menu-comida dd {
  margin: 0;
  font-size: 0.95rem;
  line-height: 1.5;
}

/* La bebida se repite en casi todas las casillas: va en su propia línea y más
   discreta, para que no compita con el plato. */
.menu-bebida {
  display: block;
  margin-top: 0.2rem;
  font-size: 0.85rem;
  color: var(--text-suave);
}

.menu-alergias {
  display: flex;
  align-items: flex-start;
  gap: 0.7rem;
  max-width: 46rem;
  margin: 1.8rem auto 0;
  padding: 1rem 1.2rem;
  background-color: var(--surface);
  border-radius: 0.9rem;
  font-size: 0.95rem;
  line-height: 1.6;
}

.menu-alergias-icono {
  flex: 0 0 auto;
  color: var(--accent-texto);
  font-size: 1.1rem;
  margin-top: 0.15rem;
}

/* ==========================================================================
   PULIDO DE INTERACCIÓN  ·  2026-09-21
   ==========================================================================

   Va al final a propósito: estas reglas AJUSTAN lo que ya existe más arriba y
   necesitan ganar por orden de carga sin subir la especificidad a la fuerza.

   Qué se arregló, medido en el navegador antes de tocar nada:

   · CERO estados `:active` en todo el sitio. Pulsar un botón no devolvía
     ninguna señal: en un móvil, donde no hay cursor ni hover, eso deja a la
     persona sin saber si el toque entró.
   · Cuatro controles por debajo del mínimo de 44 px de alto —«Cambiar sede» 33,
     los de idioma 31, el menú 38, los del carrusel 38—.
   · El carrusel avanzaba solo cada 5 s sin forma de pararlo.

   Lo que NO se tocó: la paleta, los tonos de cada sede y los contrastes, que ya
   estaban validados contra WCAG AA. Esto es pulido de interacción, no rediseño.
   ========================================================================== */

/* --- Suavizado de fuente -------------------------------------------------
   La Cheri es una tipografía de trazo fino; en macOS sin esto se ve más
   gruesa y sucia de lo que debería. */
html {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* --- Titulares que no se rompen mal --------------------------------------
   `balance` reparte las palabras entre líneas en vez de dejar una suelta
   colgando. Solo en titulares y textos cortos: en prosa larga el navegador
   deja de aplicarlo y además no aporta. */
h1, h2, h3,
.section-title,
.programa-card h2,
.news-titulo,
.landing-title {
  text-wrap: balance;
}

.about-lead,
.programa-info,
.news-resumen,
.menu-intro {
  text-wrap: pretty;
}

/* --- Cifras que no bailan ------------------------------------------------
   En la tabla de días de cierre las fechas van en columna: con cifras de
   ancho variable los números no alinean y la columna parece torcida. */
.cierres-tabla td,
.menu-dia-hora,
.timetable td {
  font-variant-numeric: tabular-nums;
}

/* ==========================================================================
   BOTONES: respuesta al pulsar
   ==========================================================================
   `scale(0.96)` es el gesto táctil estándar: el botón se hunde bajo el dedo y
   vuelve al soltar. Se combina con bajar la sombra, porque un objeto que se
   hunde proyecta menos sombra — así el movimiento se lee como físico y no como
   un parpadeo.

   Las transiciones declaran SUS propiedades. `transition: all` haría que el
   navegador vigile cada propiedad que cambie, incluidas las que provocan
   recálculo de maquetación. */

.cta-button {
  transition-property: transform, box-shadow, background-color, color;
  transition-duration: 180ms;
  transition-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
}

.cta-button:active {
  transform: translateY(0) scale(0.96);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.16);
  /* Sin transición al bajar: el hundido tiene que sentirse inmediato. El
     rebote de vuelta sí se anima, con la regla de arriba. */
  transition-duration: 60ms;
}

/* Los botones de la barra superior y del menú */
.branch-switcher .branch-btn,
.lang-toggle-header .lang-btn,
.navbar .nav-link,
.btn {
  transition-property: transform, background-color, border-color, color, box-shadow;
  transition-duration: 160ms;
  transition-timing-function: ease-out;
}

.branch-switcher .branch-btn:active,
.lang-toggle-header .lang-btn:active,
.navbar .nav-link:active,
.btn:active {
  transform: scale(0.96);
  transition-duration: 60ms;
}

/* ==========================================================================
   ÁREAS DE PULSACIÓN
   ==========================================================================
   Mínimo 44 px de alto. Se consigue con `min-height` más centrado por flex, y
   NO subiendo el `padding`: el padding empujaría el texto y descuadraría la
   barra, que va justa de alto.

   El texto se queda del mismo tamaño; lo que crece es la zona que responde al
   dedo. En un móvil esa diferencia es la que separa «no funciona» de «funciona
   a la primera». */
.branch-switcher .branch-btn,
.lang-toggle-header .lang-btn {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* El menú solo en móvil: en escritorio hay cursor, y estirar el menú ahí
   separaría las secciones sin motivo. */
@media (max-width: 1199.98px) {
  .navbar .nav-link {
    min-height: 44px;
    display: flex;
    align-items: center;
  }
}

/* ==========================================================================
   CARRUSEL
   ==========================================================================
   Los controles de Bootstrap ocupan el 15 % del ancho y TODO el alto: medidos,
   190 x 382 px de zona invisible sobre la propia diapositiva. Quien intenta
   tocar el centro de la foto acaba pasando de diapositiva sin querer.

   Se convierten en botones redondos de tamaño honesto: lo que se ve es lo que
   responde. */
.carousel-control-prev,
.carousel-control-next {
  width: 3.25rem;
  height: 3.25rem;
  top: 50%;
  bottom: auto;
  transform: translateY(-50%);
  border-radius: 50%;
  background-color: rgba(255, 255, 255, 0.82);
  backdrop-filter: blur(4px);
  opacity: 1;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.18);
  transition-property: background-color, transform, box-shadow;
  transition-duration: 160ms;
  transition-timing-function: ease-out;
}

.carousel-control-prev { left: 1rem; }
.carousel-control-next { right: 1rem; }

.carousel-control-prev:hover,
.carousel-control-next:hover,
.carousel-control-prev:focus,
.carousel-control-next:focus {
  background-color: #ffffff;
  transform: translateY(-50%) scale(1.06);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.24);
  opacity: 1;
}

.carousel-control-prev:active,
.carousel-control-next:active {
  transform: translateY(-50%) scale(0.94);
  transition-duration: 60ms;
}

.carousel-control-prev:focus-visible,
.carousel-control-next:focus-visible,
.carousel-pausa:focus-visible {
  outline: 3px solid var(--titulo);
  outline-offset: 3px;
}

/* Las flechas de Bootstrap son blancas; sobre un botón claro no se verían. */
.carousel-control-prev-icon,
.carousel-control-next-icon {
  width: 1.25rem;
  height: 1.25rem;
  filter: invert(1);
}

/* --- Botón de pausa ------------------------------------------------------
   Contenido que se mueve solo necesita poder pararse. No es un adorno: quien
   lee despacio, quien usa lector de pantalla o quien simplemente estaba
   mirando una foto pierde la diapositiva a media frase. */
.carousel-pausa {
  position: absolute;
  right: 1rem;
  bottom: 1rem;
  z-index: 5;
  width: 2.75rem;
  height: 2.75rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 50%;
  background-color: rgba(255, 255, 255, 0.82);
  backdrop-filter: blur(4px);
  color: var(--titulo);
  font-size: 0.95rem;
  cursor: pointer;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.18);
  transition-property: background-color, transform, box-shadow;
  transition-duration: 160ms;
  transition-timing-function: ease-out;
}

.carousel-pausa:hover {
  background-color: #ffffff;
  transform: scale(1.06);
}

.carousel-pausa:active {
  transform: scale(0.94);
  transition-duration: 60ms;
}

/* El icono cambia según el estado, y el estado lo anuncia `aria-pressed` para
   quien no ve el icono. */
.carousel-pausa .icono-pausa { display: inline; }
.carousel-pausa .icono-play  { display: none; }
.carousel-pausa[aria-pressed="true"] .icono-pausa { display: none; }
.carousel-pausa[aria-pressed="true"] .icono-play  { display: inline; }

/* ==========================================================================
   TRANSICIÓN ENTRE PÁGINAS
   ==========================================================================
   Con la API de View Transitions el propio navegador funde una página con la
   siguiente. Dos cosas la hacen la opción correcta aquí:

   · Es NATIVA. La alternativa clásica —interceptar los clics con JavaScript y
     animar a mano— rompe el botón Atrás, el abrir en pestaña nueva y la
     navegación por teclado. Esto no toca ninguno.
   · Es mejora progresiva pura. El navegador que no la soporta ignora la regla
     y navega como siempre. No hay respaldo que mantener ni nada que se rompa.

   La animación es deliberadamente corta y sin desplazamiento lateral: es la web
   de una guardería, no una presentación. Un fundido de 220 ms basta para que el
   cambio se sienta continuo en vez de un parpadeo. */
@view-transition {
  navigation: auto;
}

::view-transition-old(root) {
  animation: tlf-salida 140ms cubic-bezier(0.4, 0, 1, 1) both;
}

::view-transition-new(root) {
  animation: tlf-entrada 220ms cubic-bezier(0, 0, 0.2, 1) both;
}

/* La salida es más corta que la entrada: lo que se va no merece tanta atención
   como lo que llega, y alargarla solo retrasa la lectura. */
@keyframes tlf-salida {
  to { opacity: 0; }
}

@keyframes tlf-entrada {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* La cabecera NO se funde: se queda quieta mientras el cuerpo cambia. Así la
   navegación se siente como un panel que cambia, no como recargar todo. */
header.fixed-top {
  view-transition-name: tlf-cabecera;
}

/* ==========================================================================
   MOVIMIENTO REDUCIDO
   ==========================================================================
   El bloque general de más arriba ya reduce animaciones y transiciones a
   0,01 ms para todo. Aquí se apaga lo que ese bloque NO alcanza:

   · las transiciones entre páginas viven fuera del árbol normal, así que el
     selector `*` no las toca;
   · el carrusel lo mueve JavaScript con un temporizador, y ninguna regla CSS
     puede parar un temporizador. De eso se encarga scripts.html, que lee la
     misma preferencia del sistema. */
@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root),
  ::view-transition-new(root) {
    animation: none !important;
  }

  .cta-button:active,
  .branch-switcher .branch-btn:active,
  .lang-toggle-header .lang-btn:active,
  .navbar .nav-link:active,
  .btn:active,
  .carousel-control-prev:active,
  .carousel-control-next:active,
  .carousel-pausa:active {
    transform: none;
  }
}

/* ==========================================================================
   EL PANEL DEL CARRUSEL: contraste
   ==========================================================================
   `style.css` le daba `rgba(0, 0, 0, 0.2)`. Medido sobre la foto más clara del
   carrusel, el texto blanco encima quedaba en **2,55:1**. WCAG AA pide 4,5:1
   para el texto normal y 3:1 para el titular grande: no cumplía ninguno de los
   dos, y no era sutil — en la foto de los libros el subtítulo casi desaparece.

   El 0,52 no es un tanteo. Despejando la fórmula de contraste para texto blanco
   sobre esa foto, el alfa mínimo que alcanza 4,5:1 es **0,467** —con el azul
   oscuro (15,23,32) que se usa, no con negro puro, que necesitaría menos—. Se
   sube a 0,52 para tener margen sobre fotos algo más claras que la medida.
   Primera versión a 0,46: daba 4,43:1 y se quedó a siete centésimas.

   Se resuelve con degradado en vez de un color plano por dos motivos:
   · un rectángulo gris uniforme al 48 % tapa la foto y se ve pesado;
   · el degradado carga más abajo, que es donde va el texto pequeño —el que más
     contraste necesita— y aligera arriba, donde está el titular grande, que con
     3:1 tiene de sobra.

   El desenfoque de fondo hace el resto del trabajo: al difuminar la foto que hay
   detrás, quita los bordes de alto contraste que compiten con las letras. Es lo
   que separa un panel legible de uno que solo está oscurecido.
   ========================================================================== */
.slider .carousel-caption {
  background: linear-gradient(
    to bottom,
    rgba(15, 23, 32, 0.52) 0%,
    rgba(15, 23, 32, 0.64) 100%
  );
  backdrop-filter: blur(7px) saturate(1.05);
  -webkit-backdrop-filter: blur(7px) saturate(1.05);
  /* Un borde muy tenue separa el panel de la foto sin dibujar una caja. */
  border: 1px solid rgba(255, 255, 255, 0.16);
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.22);
}

/* La sombra del texto deja de hacer falta cuando el fondo ya cumple, y sumarla
   sobre un panel oscuro solo emborrona los bordes de las letras. */
.slider .carousel-caption h2,
.slider .carousel-caption p {
  text-shadow: none;
}

/* Si el navegador no soporta `backdrop-filter` no hay desenfoque, y el panel se
   queda solo con el degradado. Se compensa subiéndolo para que el contraste no
   dependa de una función opcional. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .slider .carousel-caption {
    background: linear-gradient(
      to bottom,
      rgba(15, 23, 32, 0.62) 0%,
      rgba(15, 23, 32, 0.74) 100%
    );
  }
}

/* ==========================================================================
   PULSO EN LOS BOTONES DE LISTA DE ESPERA
   ==========================================================================
   Son los cuatro botones que convierten una visita en una familia interesada, y
   ahora todos laten: un aro que sale del borde, crece y se desvanece, con un
   compás de descanso antes del siguiente. Es el gesto de «púlsame» que usan las
   aplicaciones, y se ve desde el otro lado de la pantalla.

   POR QUÉ EL MOVIMIENTO VA EN UN PSEUDOELEMENTO Y NO EN EL BOTÓN
   El botón ya usa `transform` para dos cosas: subir 2 px al pasar el ratón y
   hundirse al pulsar. Una animación en marcha GANA siempre sobre una
   transición de la misma propiedad, así que animar el `transform` del botón
   habría dejado los dos gestos muertos: el botón dejaría de responder al tacto.
   Por eso late el aro, no el botón.

   POR QUÉ EL COLOR ES UNA VARIABLE
   Los cuatro botones viven sobre fondos distintos:

     · la pastilla de la cabecera ....... sobre --nav-bg, pastel claro
     · el del carrusel ................. sobre una foto
     · el de «home-intro» .............. sobre --accent-soft, claro
     · el de «about-cta» ............... sobre --accent-deep, oscuro

   Un color fijo sería invisible en la mitad. El valor por defecto es el oscuro
   de la sede, que funciona sobre los fondos claros, y se cambia a blanco donde
   el fondo es oscuro.

   Sustituye al anillo de luz giratorio del intento anterior: aquel efecto era
   demasiado sutil y solo estaba en el botón de la cabecera.
   ========================================================================== */

.cta-button,
.slider .carousel-caption .btn-cta-primary,
.navbar .nav-item-cta a.nav-link {
  /* Por defecto, el tono oscuro de la sede: se ve sobre los fondos claros. */
  --color-pulso: var(--accent-deep);
  position: relative;
}

/* Donde el fondo es oscuro, el aro se vuelve blanco. */
.about-cta .cta-button,
.slider .carousel-caption .btn-cta-primary {
  --color-pulso: #ffffff;
}

.cta-button::before,
.slider .carousel-caption .btn-cta-primary::before,
.navbar .nav-item-cta a.nav-link::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  border: 3px solid var(--color-pulso);
  /* Decoración: no debe robarle el clic al botón. */
  pointer-events: none;
  /* Parte invisible: el primer fotograma del latido ya lo enciende. */
  opacity: 0;
  animation: tlf-latido 2.4s cubic-bezier(0.16, 1, 0.3, 1) infinite;
}

/* El aro crece y se apaga en poco más de la mitad del ciclo; el resto es
   silencio. Ese descanso es lo que lo convierte en un latido en vez de un
   parpadeo continuo, que cansaría al minuto de estar en la página. */
@keyframes tlf-latido {
  0% {
    opacity: 0.85;
    transform: scale(1);
  }
  60% {
    opacity: 0;
    transform: scale(1.22);
  }
  100% {
    opacity: 0;
    transform: scale(1.22);
  }
}

/* EL ARO NO PUEDE ABRIR UN DESPLAZAMIENTO LATERAL.
   `scale(1.22)` es un porcentaje: en un botón estrecho son unos píxeles, pero
   el de enviar ocupa todo el ancho en pantallas estrechas (≈350 px) y el 22 %
   son 38 px que se salían por los lados. Medido el 2026-09-23 en los contactos
   y las listas de espera, a 390 px: en una ventana estrecha normal, la rueda o
   el trackpad movían la página 25 px de lado; con esta regla, 0. (En la
   emulación de móvil de Chrome no llegaba a desplazarse ni sin ella.)

   `clip` y no `hidden`: recorta igual, pero no convierte la raíz en un
   contenedor de scroll, así que no interfiere con lo fijo ni con lo pegajoso.
   Es seguro porque ninguna página necesita desplazarse de lado: las 70
   capturas a 390 px miden exactamente 390. Lo que tenga que desplazarse de
   lado (una tabla ancha) lo hace dentro de su propia caja. */
html {
  overflow-x: clip;
}

/* Al pasar el ratón o al enfocar con el teclado el latido se acelera: el botón
   confirma que está vivo antes incluso de pulsarlo. */
.cta-button:hover::before,
.cta-button:focus-visible::before,
.slider .carousel-caption .btn-cta-primary:hover::before,
.slider .carousel-caption .btn-cta-primary:focus-visible::before,
.navbar .nav-item-cta a.nav-link:hover::before,
.navbar .nav-item-cta a.nav-link:focus-visible::before {
  animation-duration: 1.2s;
}

/* Los cuatro laten a la vez si no se hace nada, y eso se lee como un error de
   pintado. Se desfasan: en una misma página, el de arriba late antes que el de
   abajo, y el conjunto parece vivo en vez de sincronizado por accidente. */
.navbar .nav-item-cta a.nav-link::before { animation-delay: 0s; }
.slider .carousel-caption .btn-cta-primary::before { animation-delay: 0.5s; }
.home-intro .cta-button::before { animation-delay: 0.9s; }
.about-cta .cta-button::before { animation-delay: 1.3s; }

/* --- La cabecera no puede recortar el aro --------------------------------
   El aro sobresale un 22 % del botón. Si algún contenedor de la barra tiene
   `overflow: hidden`, lo corta por la mitad y se ve un cuadrado. */
.navbar .nav-item-cta,
.navbar .navbar-nav {
  overflow: visible;
}

/* --- Movimiento reducido -------------------------------------------------
   El bloque general de más arriba deja las animaciones en 0,01 ms, y eso
   congelaría el aro en su primer fotograma: un borde grueso y fijo alrededor
   del botón, que parece un error. Aquí se retira entero. */
@media (prefers-reduced-motion: reduce) {
  .cta-button::before,
  .slider .carousel-caption .btn-cta-primary::before,
  .navbar .nav-item-cta a.nav-link::before {
    display: none;
  }
}

/* ==========================================================================
   MOVIMIENTO AL PASAR EL RATÓN: los que faltaban
   ==========================================================================
   Auditados los `:hover` de todo el sitio, cinco controles cambiaban de color
   pero no se movían. El más visible era la pastilla de «Lista de espera» de la
   cabecera: tenía el latido del aro, pero el botón en sí se quedaba quieto, y
   eso hace que el aro parezca pegado encima en vez de salir de él.

   (Las variantes `-ghost` y `-hueco` sí se movían: llevan también la clase base
   `.cta-button`, así que heredan su `translateY`. Parecían no moverse al leer
   el CSS y sí lo hacían al mirar el HTML.)

   CUÁNTO SE MUEVE CADA UNO
   No todos lo mismo. Los de la barra superior viven en una franja estrecha:
   un salto de 2 px ahí se ve suelto, como si el botón se despegara. Se quedan
   en 1 px, que se nota sin descolocar la fila. La pastilla principal sí sube
   2 px, igual que los botones grandes de llamada a la acción, porque es el
   mismo gesto y conviene que sea el mismo en toda la web.

   ⚠️ EL ORDEN DE ESTE BLOQUE IMPORTA
   Las reglas `:active` van AL FINAL, después de las de `:hover`. Con un ratón
   siempre estás en hover mientras pulsas: si el hover se declarara después,
   ganaría, y el botón no se hundiría nunca. Es el mismo motivo por el que el
   .htaccess de `api/` lleva su aviso de orden.
   ========================================================================== */

/* --- La pastilla de «Lista de espera» de la cabecera ---------------------- */
.navbar .nav-item-cta a.nav-link:hover,
.navbar .nav-item-cta a.nav-link:focus-visible {
  transform: translateY(-2px);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.18);
}

/* --- La barra superior: cambiar sede e idioma ----------------------------- */
.branch-switcher .branch-btn:hover,
.branch-switcher .branch-btn:focus-visible,
.lang-toggle-header .lang-btn:hover,
.lang-toggle-header .lang-btn:focus-visible {
  transform: translateY(-1px);
}

/* --- Las secciones del menú ----------------------------------------------
   Ya tenían su subrayado animado, que es su respuesta propia. Se les suma un
   desplazamiento mínimo para que el menú entero responda igual al tacto. */
.navbar .navbar-nav .nav-item:not(.nav-item-cta) a.nav-link:hover,
.navbar .navbar-nav .nav-item:not(.nav-item-cta) a.nav-link:focus-visible {
  transform: translateY(-1px);
}

/* --- El botón de menú en móvil ------------------------------------------- */
.navbar-toggler {
  transition-property: transform, box-shadow, background-color;
  transition-duration: 160ms;
  transition-timing-function: ease-out;
}

.navbar-toggler:hover,
.navbar-toggler:focus-visible {
  transform: scale(1.06);
}

/* ==========================================================================
   Y AHORA SÍ, EL HUNDIDO AL PULSAR
   ==========================================================================
   Va después de todos los `:hover` de arriba a propósito. Repite lo que ya
   estaba declarado en el bloque de pulido, porque aquellas reglas quedaron por
   encima en el archivo y el hover nuevo las habría tapado.

   `translateY(0)` es necesario en cada una: sin él, el `scale` se sumaría al
   `translateY` del hover y el botón se hundiría estando 2 px más arriba, que
   se lee como un temblor en vez de como una pulsación. */
.cta-button:active,
.navbar .nav-item-cta a.nav-link:active,
.branch-switcher .branch-btn:active,
.lang-toggle-header .lang-btn:active,
.navbar .navbar-nav .nav-item:not(.nav-item-cta) a.nav-link:active,
.slider .carousel-caption .btn-cta-primary:active,
.btn:active {
  transform: translateY(0) scale(0.96);
  transition-duration: 60ms;
}

.navbar-toggler:active {
  transform: scale(0.94);
  transition-duration: 60ms;
}

/* --- Movimiento reducido ------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .navbar .nav-item-cta a.nav-link:hover,
  .navbar .nav-item-cta a.nav-link:focus-visible,
  .branch-switcher .branch-btn:hover,
  .branch-switcher .branch-btn:focus-visible,
  .lang-toggle-header .lang-btn:hover,
  .lang-toggle-header .lang-btn:focus-visible,
  .navbar .navbar-nav .nav-item:not(.nav-item-cta) a.nav-link:hover,
  .navbar .navbar-nav .nav-item:not(.nav-item-cta) a.nav-link:focus-visible,
  .navbar-toggler:hover,
  .navbar-toggler:focus-visible,
  .cta-button:active,
  .navbar .nav-item-cta a.nav-link:active,
  .branch-switcher .branch-btn:active,
  .lang-toggle-header .lang-btn:active,
  .btn:active,
  .navbar-toggler:active {
    transform: none;
  }
}

/* --- «Cuando se hace» ----------------------------------------------------
   Etiqueta con el dia y la hora de una actividad, en la tarjeta y en la ficha.
   El dato se calcula del horario (ver _includes/cuando-actividad.html), asi que
   aqui solo se le da forma.

   Va como pastilla y no como una linea mas de texto: es un dato de otra
   naturaleza que la descripcion —cuando, no que— y mezclarlos en el mismo
   parrafo obligaria a leerlo entero para encontrarlo. */
.cuando-actividad {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.5rem;
  padding: 0.25rem 0.7rem;
  border-radius: 999px;
  background-color: var(--accent-soft);
  color: var(--accent-texto);
  font-size: 0.82rem;
  line-height: 1.4;
  font-variant-numeric: tabular-nums;
}

.cuando-actividad i {
  font-size: 0.85em;
  opacity: 0.85;
}

/* En la ficha de detalle va dentro de una columna estrecha de la barra lateral,
   asi que ahi se deja fluir en vez de forzar una sola linea. */
.list-group-item .cuando-actividad {
  margin-top: 0;
  padding: 0.2rem 0.6rem;
  font-size: 0.8rem;
}

/* ==========================================================================
   LA JORNADA: cuatro bloques, selector de día y marca de «ahora mismo»
   ==========================================================================
   El día no es una lista de veinte horas sueltas: es llegada, juego, comida y
   descanso, y tarde. Se agrupa por ahí, que es como lo vive una familia, y lo
   único que cambia de un día a otro —la actividad— se resuelve con el selector
   en vez de repetir las veinte líneas cinco veces.

   CUARTA VERSIÓN DE ESTA SECCIÓN
   Tabla heredada de la plantilla · línea de tiempo · una tarjeta por día · esta.
   Cada versión RETIRÓ el CSS de la anterior antes de escribir el suyo. No es
   manía: en este mismo archivo dos bloques compitiendo por el mismo componente
   ya provocaron un fallo de especificidad que costó una tarde. Si algún día se
   cambia otra vez, bórrese este bloque entero primero.

   CONTRASTE COMPROBADO PAREJA POR PAREJA (no en abstracto)
   Blanco sobre --accent-deep  4,68:1 (Revere) · 4,67:1 (Everett)
   --accent-texto sobre --accent-soft  5,61 · 5,55
   --text-suave sobre --accent-soft    4,66 · 4,66   ← el más justo de todos
   --accent-deep sobre --accent-soft   4,22 · 4,21   (el punto del aviso)
   El punto del aviso empezó siendo --accent y daba 2,52:1: el color de marca
   luce sobre blanco y desaparece sobre su propio tono pálido. El contraste es
   una propiedad de LA PAREJA, nunca del color solo.
   ========================================================================== */

.branch-horario .container {
  max-width: 1180px;
}

.horario-seccion {
  padding-block: 2.5rem 3.5rem;
}

/* --- El selector de día --------------------------------------------------
   Nace con `hidden` desde la plantilla y lo destapa el JavaScript. Un botón
   que no hace nada es peor que no tener botón: sin script se ven los cinco
   días en lista y el selector no llega a aparecer. */
/* La etiqueta del selector va a la vista en lugar de en un aria-label: el
   porqué está en la plantilla, y se resume en que t.html devuelve dos <span>
   y eso dentro de un atributo rompe el HTML. */
.dia-selector-titulo {
  margin: 0 0 0.5rem;
  text-align: center;
  font-size: 0.85rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-suave);
}

.dia-selector-titulo[hidden] {
  display: none;
}

.dia-selector {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem;
  margin-bottom: 1.1rem;
}

.dia-selector[hidden] {
  display: none;
}

.dia-chip {
  /* 44 px de alto real: es el mínimo para un dedo, y aquí hay cinco seguidos. */
  min-height: 44px;
  padding: 0.45rem 1.05rem;
  border: 1px solid var(--accent-soft);
  border-radius: 999px;
  background-color: var(--surface);
  color: var(--accent-texto);
  font-family: 'Cheri', 'Baloo 2', cursive;
  font-size: 1rem;
  line-height: 1.2;
  cursor: pointer;
  transition-property: background-color, border-color, color, transform, box-shadow;
  transition-duration: 160ms;
  transition-timing-function: ease-out;
}

.dia-chip:hover {
  border-color: var(--accent-deep);
  transform: translateY(-2px);
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.09);
}

.dia-chip:focus-visible {
  outline: 2px solid var(--accent-deep);
  outline-offset: 2px;
}

/* El pulsado no se marca solo con color: `aria-pressed` es lo que oye un lector
   de pantalla, y aquí es además lo que dispara el estilo. Un único origen. */
.dia-chip[aria-pressed='true'] {
  background-color: var(--accent-deep);
  border-color: var(--accent-deep);
  color: #ffffff;
  box-shadow: 0 3px 9px rgba(0, 0, 0, 0.16);
}

.dia-chip:active {
  transform: scale(0.95);
  transition-duration: 60ms;
}

/* --- El aviso de «ahora mismo» -------------------------------------------
   Lo rellena el navegador, no el servidor: una página estática se genera una
   vez, así que una hora calculada al construir se quedaría congelada para
   siempre en el momento de publicar. */
.ahora-aviso {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  width: fit-content;
  margin: 0 auto 1.6rem;
  padding: 0.4rem 1rem;
  border-radius: 999px;
  background-color: var(--accent-soft);
  color: var(--accent-texto);
  font-size: 0.92rem;
  line-height: 1.3;
  font-variant-numeric: tabular-nums;
}

.ahora-aviso[hidden] {
  display: none;
}

.ahora-punto {
  flex: none;
  width: 0.6rem;
  height: 0.6rem;
  border-radius: 50%;
  /* --accent-deep, no --accent: ver la nota de contraste de la cabecera. */
  background-color: var(--accent-deep);
  animation: tlf-latir-punto 2s ease-in-out infinite;
}

@keyframes tlf-latir-punto {
  0%, 100% { opacity: 1;    transform: scale(1); }
  50%      { opacity: 0.45; transform: scale(0.72); }
}

/* --- La rejilla de bloques ----------------------------------------------- */
.jornada {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  /* Cuatro en fila cuando caben, y baja a dos y a una sin puntos de ruptura
     que mantener a mano. */
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
  gap: 1.15rem;
  /* Cada tarjeta termina donde termina su contenido. Estirándolas todas a la
     misma altura, la de la tarde quedaba con 300 px de blanco debajo, y un
     hueco así se lee como «aquí falta algo». Los cuatro bloques duran cosas
     distintas de verdad —la mañana tiene siete momentos y la tarde tres—, así
     que la altura desigual no es un defecto: es el dato. */
  align-items: start;
}

.jornada-bloque {
  display: flex;
  flex-direction: column;
  background-color: var(--surface);
  border-radius: 1.1rem;
  overflow: hidden;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05), 0 6px 18px rgba(0, 0, 0, 0.07);

  /* La entrada escalonada cuenta el orden del día: primero se posa la llegada,
     luego el juego, luego la comida, luego la tarde. Se anima `translate` —la
     propiedad independiente— y no `transform`, para que nada de lo que venga
     después tenga que pelearse con ella: una animación en curso gana siempre
     a una transición sobre la misma propiedad, y eso ya rompió el botón de
     lista de espera en este proyecto. */
  opacity: 0;
  translate: 0 14px;
  animation: tlf-bloque-entra 480ms cubic-bezier(0.16, 1, 0.3, 1) forwards;
}

.jornada-bloque:nth-child(1) { animation-delay:  60ms; }
.jornada-bloque:nth-child(2) { animation-delay: 140ms; }
.jornada-bloque:nth-child(3) { animation-delay: 220ms; }
.jornada-bloque:nth-child(4) { animation-delay: 300ms; }

@keyframes tlf-bloque-entra {
  to { opacity: 1; translate: 0 0; }
}

/* --- La cabecera de cada bloque ------------------------------------------ */
.jornada-cabecera {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: 0.15rem 0.7rem;
  padding: 0.95rem 1rem;
  /* Dos títulos caben en una línea y dos en dos, así que sin esto las cuatro
     cabeceras medían distinto (95, 73, 73, 95 px) y los cuerpos de las tarjetas
     arrancaban a alturas diferentes. Con el alto mínimo de dos líneas, las
     cuatro cabeceras se alinean aunque el título sea corto. */
  min-height: 5.9rem;
  align-content: center;
  /* El degradado solo OSCURECE. Añade profundidad sin tocar el contraste
     medido: si aclarase, el blanco de encima bajaría de 4,68:1 y dejaría de
     cumplir. Oscurecer nunca puede empeorar texto blanco. */
  background-image: linear-gradient(155deg, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.12));
  background-color: var(--accent-deep);
}

.jornada-icono {
  grid-row: span 2;
  display: grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
  background-color: rgba(255, 255, 255, 0.18);
  color: #ffffff;
  font-size: 1.05rem;
}

.jornada-titulo {
  margin: 0;
  font-family: 'Cheri', 'Baloo 2', cursive;
  font-size: 1.2rem;
  font-weight: 400;
  line-height: 1.15;
  /* Blanco puro. Sobre --accent-deep ya va justo (4,68:1) y no queda margen
     para rebajarlo con transparencia: la jerarquía la hace el tamaño. */
  color: #ffffff;
  text-wrap: balance;
}

.jornada-tramo {
  font-size: 0.85rem;
  line-height: 1.3;
  color: #ffffff;
  font-variant-numeric: tabular-nums;
}

/* --- Los momentos -------------------------------------------------------- */
.jornada-lista {
  list-style: none;
  margin: 0;
  padding: 0.3rem 0;
  flex: 1;
}

.jornada-momento {
  display: grid;
  grid-template-columns: 4.6rem 1fr;
  gap: 0 0.6rem;
  padding: 0.5rem 1rem;
  /* La barra de «ahora» vive aquí en transparente para que al encenderse no
     mueva el texto ni un píxel. */
  border-left: 3px solid transparent;
  transition-property: background-color, border-left-color;
  transition-duration: 220ms;
  transition-timing-function: ease-out;
}

.jornada-momento + .jornada-momento {
  border-top: 1px solid rgba(0, 0, 0, 0.06);
}

.jornada-hora {
  font-family: 'Cheri', 'Baloo 2', cursive;
  font-size: 0.82rem;
  line-height: 1.4;
  color: var(--titulo);
  /* Cifras de ancho fijo: sin esto las horas bailan de fila en fila. */
  font-variant-numeric: tabular-nums;
}

.jornada-momento-titulo {
  display: block;
  font-size: 0.93rem;
  line-height: 1.4;
  color: var(--text);
  text-wrap: pretty;
}

.jornada-detalle {
  display: block;
  margin-top: 0.2rem;
  font-size: 0.79rem;
  line-height: 1.5;
  color: var(--text-suave);
  text-wrap: pretty;
}

/* --- El momento que está pasando ahora ----------------------------------- */
.jornada-ahora {
  background-color: var(--accent-soft);
  border-left-color: var(--accent-deep);
}

.jornada-ahora .jornada-hora {
  font-weight: 600;
}

/* --- La actividad del día, con sus cinco días ---------------------------- */
.jornada-semana {
  list-style: none;
  margin: 0.45rem 0 0;
  padding: 0;
}

.jornada-semana > li[hidden] {
  display: none;
}

/* El nombre del día solo hace falta cuando se ven los cinco a la vez, es decir
   cuando no hay JavaScript. Con el selector puesto, el día ya lo dice el chip
   pulsado y repetirlo aquí sería decir dos veces lo mismo. */
.jornada-dia {
  display: block;
  font-size: 0.75rem;
  line-height: 1.3;
  color: var(--text-suave);
}

.dia-selector:not([hidden]) ~ .jornada .jornada-dia {
  display: none;
}

.jornada-programa {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.25rem;
  padding: 0.3rem 0.7rem;
  border-radius: 999px;
  background-color: var(--accent-soft);
  color: var(--accent-texto);
  font-size: 0.85rem;
  line-height: 1.35;
  text-decoration: none;
  transition-property: background-color, transform, box-shadow;
  transition-duration: 160ms;
  transition-timing-function: ease-out;
}

.jornada-programa:hover,
.jornada-programa:focus-visible {
  color: var(--accent-texto);
  text-decoration: none;
  transform: translateY(-2px);
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
}

.jornada-programa:focus-visible {
  outline: 2px solid var(--accent-deep);
  outline-offset: 2px;
}

.jornada-programa:active {
  transform: scale(0.96);
  transition-duration: 60ms;
}

.jornada-programa i {
  font-size: 0.9em;
  opacity: 0.85;
}

/* Dentro del momento resaltado, la píldora se queda en blanco para no
   desaparecer sobre un fondo de su mismo tono. */
.jornada-ahora .jornada-programa {
  background-color: var(--surface);
}

/* Con el dedo, la píldora de 28 px de alto se queda corta: el mínimo cómodo
   son 44. No se agranda siempre, porque con ratón 28 px ya se acierta de sobra
   y engordarla en el escritorio la volvería un botón que no es. Se toca el alto
   mínimo y no el tamaño de letra: así crece el área de pulsación sin que la
   píldora cambie de aspecto. */
@media (pointer: coarse) {
  .jornada-programa {
    min-height: 44px;
    padding-block: 0.5rem;
  }
}

.jornada-nota {
  margin: 1.9rem auto 0;
  max-width: 46rem;
  font-size: 0.9rem;
  line-height: 1.6;
  color: var(--text-suave);
  text-align: center;
  text-wrap: pretty;
}

/* --- Móvil ---------------------------------------------------------------
   Con una sola columna sobra ancho, así que la hora se queda al lado del texto
   y solo se estrecha el margen interior. */
@media (max-width: 30rem) {
  .jornada-momento {
    grid-template-columns: 4.2rem 1fr;
    padding-inline: 0.75rem;
  }

  .dia-chip {
    padding-inline: 0.85rem;
  }
}

/* --- Menos movimiento ----------------------------------------------------
   Si el sistema pide menos movimiento, el estado final aparece directo: las
   tarjetas ya visibles, el punto quieto. No se «acorta» la animación, se
   entrega el resultado. */
@media (prefers-reduced-motion: reduce) {
  .jornada-bloque {
    opacity: 1;
    translate: none;
    animation: none;
  }

  .ahora-punto {
    animation: none;
  }

  .dia-chip,
  .jornada-momento,
  .jornada-programa {
    transition-duration: 1ms;
  }

  .dia-chip:hover,
  .jornada-programa:hover,
  .jornada-programa:focus-visible {
    transform: none;
  }

  .dia-chip:active,
  .jornada-programa:active {
    transform: none;
  }
}

/* ==========================================================================
   LAS IMÁGENES RESERVAN SU SITIO SIN QUEDAR ESTIRADAS
   ==========================================================================
   Al poner `width` y `height` en las etiquetas <img> para que la página deje el
   hueco desde el principio y no salte al cargar, se rompió el carrusel: la
   diapositiva pasó de 382 px de alto a 514.

   EL PORQUÉ, QUE NO ES EVIDENTE
   Esos atributos solo sirven de PROPORCIÓN mientras el alto en CSS sea `auto`.
   El carrusel trae `.w-100` de Bootstrap, que fija `width: 100%`, y no fijaba
   ningún alto: en cuanto existe el atributo `height`, ese número pasa a ser el
   alto de verdad, en píxeles, y deja de escalarse con el ancho.

   Con `height: auto` el navegador vuelve a calcular el alto a partir del ancho,
   y sigue usando los atributos para reservar el hueco. Se conservan las dos
   cosas: sin salto y sin deformar.

   Misma especificidad que la regla de style.css (0,2,1), y esta hoja carga
   después. Si alguna vez se sube la de allí, esta deja de aplicarse.
   ========================================================================== */

.slider .carousel-item img {
  height: auto;
}

/* AQUÍ HABÍA UN `#site-logo { height: auto }` Y FUE UN ERROR.
   El logo ya lo dimensiona `.navbar .navbar-brand img` con `height: 5.75rem;
   width: auto`, que es lo correcto. Pero un selector de ID (1,0,0) gana a dos
   clases más un elemento (0,2,1) da igual el orden de carga, así que aquel
   `height: auto` anulaba la altura del encabezado y el logo se pintaba a 192 px
   en vez de a 92. La regla del carrusel de arriba sí hace falta porque allí no
   había ninguna altura en CSS; aquí sí la hay. */

/* ==========================================================================
   BOTONES FLOTANTES: WHATSAPP E INSTAGRAM
   ==========================================================================
   DOS DECISIONES DE COLOR DISTINTAS, Y A PROPÓSITO

   WhatsApp mantiene su verde oficial #25D366 aunque el icono blanco encima dé
   1,98:1, por debajo del 3:1 que pide WCAG para un gráfico. Se acepta porque
   WCAG exime expresamente a los logotipos, y porque en cualquier otro verde el
   botón deja de leerse como «WhatsApp», que es su única función.

   Instagram NO necesita esa excepción. Su degradado oficial empieza en amarillo
   (#FEDA75, 1,35:1) y naranja (#FA7E1E, 2,60:1), que fallan; pero el tramo
   rosa→morado→azul (4,73 · 6,08 · 5,54) cumple de sobra y sigue siendo
   inconfundiblemente Instagram. Aquí sí se puede cumplir sin perder nada, así
   que se cumple. Una excepción solo vale cuando no hay alternativa.

   Lo que se corrige en los DOS es el borde contra el fondo, que no está exento:
   ambos llevan sombra propia. Un botón cuyo límite no se distingue del fondo es
   un problema de verdad.

   «FOCUS NOT OBSCURED» (WCAG 2.2 AA)
   El criterio menciona por su nombre los botones de chat flotantes: no pueden
   tapar el elemento que tiene el foco del teclado. Por eso van pequeños, en una
   esquina, con z-index por debajo de la cabecera, y el bloque está al final del
   documento para que el tabulador llegue a ellos el último.

   NO PARPADEAN NI REBOTAN
   Entran una vez al cargar, escalonados, y se quedan quietos. Un botón que late
   sin parar no comunica nada: compite con el contenido por la atención, y aquí
   la familia está leyendo horarios y menús.
   ========================================================================== */

.botones-flotantes {
  position: fixed;
  /* Las variables de área segura mantienen los botones fuera de la barra de
     gestos del iPhone. En lo demás valen 0, así que no hay que condicionarlas. */
  right: calc(1rem + env(safe-area-inset-right, 0px));
  bottom: calc(1rem + env(safe-area-inset-bottom, 0px));
  /* Por debajo de la cabecera (1030) y del selector de sede (1031), por encima
     de todo el contenido, que no pasa de 10. */
  z-index: 1020;

  display: flex;
  flex-direction: column;
  /* 0,75rem = 12 px entre objetivos: por encima de los 8 px mínimos, para que
     un pulgar no acierte el de al lado. */
  gap: 0.75rem;
}

.boton-flotante {
  display: grid;
  place-items: center;
  width: 3.5rem;    /* 56 px: holgado sobre el mínimo de 44 */
  height: 3.5rem;
  border-radius: 50%;
  color: #ffffff;
  font-size: 1.8rem;
  line-height: 1;
  text-decoration: none;

  /* La sombra no es adorno: es lo que separa el botón del fondo. */
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.26), 0 1px 3px rgba(0, 0, 0, 0.18);

  transition-property: transform, box-shadow, filter;
  transition-duration: 180ms;
  transition-timing-function: ease-out;

  /* Entran una vez y se acabó. Se anima `translate` y no `transform` para que
     el hover de abajo no tenga que pelearse con la animación: una animación en
     curso gana siempre a una transición sobre la misma propiedad, y eso ya
     rompió el botón de lista de espera en este proyecto. */
  opacity: 0;
  translate: 0 12px;
  animation: tlf-flotante-entra 420ms cubic-bezier(0.16, 1, 0.3, 1) forwards;
}

/* El de abajo entra primero: es el principal, y el orden cuenta cuál importa. */
.boton-whatsapp  { animation-delay: 600ms; }
.boton-instagram { animation-delay: 760ms; }

@keyframes tlf-flotante-entra {
  to { opacity: 1; translate: 0 0; }
}

.boton-whatsapp {
  background-color: #25d366;
}

.boton-instagram {
  /* Sin el tramo cálido del degradado oficial: ver la nota de la cabecera. */
  background-image: linear-gradient(135deg, #d62976 0%, #962fbf 55%, #4f5bd5 100%);
}

.boton-flotante:hover,
.boton-flotante:focus-visible {
  color: #ffffff;
  text-decoration: none;
  transform: translateY(-3px);
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3), 0 2px 5px rgba(0, 0, 0, 0.2);
  /* Se aclara con un filtro en vez de cambiar el color: así vale igual para el
     verde plano y para el degradado, sin repetir cada fondo dos veces. */
  filter: brightness(1.08);
}

/* El aro de foco va oscuro: sobre estos fondos, uno blanco no se vería. */
.boton-flotante:focus-visible {
  outline: 3px solid #14213d;
  outline-offset: 3px;
}

.boton-flotante:active {
  transform: scale(0.94);
  transition-duration: 70ms;
}

/* En móvil se acercan a la esquina: ahí el ancho es oro y el pulgar llega igual. */
@media (max-width: 30rem) {
  .botones-flotantes {
    right: calc(0.75rem + env(safe-area-inset-right, 0px));
    bottom: calc(0.75rem + env(safe-area-inset-bottom, 0px));
  }
}

/* Al imprimir no pintan nada: son botones, y en papel no se pulsan. */
@media print {
  .botones-flotantes {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .boton-flotante {
    opacity: 1;
    translate: none;
    animation: none;
    transition-duration: 1ms;
  }

  .boton-flotante:hover,
  .boton-flotante:focus-visible,
  .boton-flotante:active {
    transform: none;
  }
}

/* ==========================================================================
   EL CARRUSEL EN EL MÓVIL, Y EL PANEL MÁS A LA IZQUIERDA
   ==========================================================================
   1. EN EL MÓVIL SE VE ENTERO, SOLO QUE MÁS PEQUEÑO

   `style.css` lo escondía por debajo de 640 px con `display: none`. Eso tenía
   dos problemas: en el teléfono no se veía NINGUNA foto del centro —y son las
   suyas, no de banco—, y la primera se descargaba igual, porque una <img> se
   pide aunque su contenedor esté oculto. Eran 244 kB por visita para nada.

   Ahora se muestra REDUCIDA, no recortada: la foto entera, a escala. Lo que lo
   hace posible es el `height: auto` de más arriba —sin él, el atributo
   `height="640"` se tomaría como altura fija en píxeles y el `object-fit: cover`
   recortaría—. Con el alto en automático, el navegador calcula la altura desde
   el ancho y entra la imagen completa.

   A 390 px de ancho sale una franja de unos 130 px de alto. Es poco, sí: es lo
   que mide una foto de proporción 3:1 en una pantalla estrecha. La alternativa
   era recortarla, y entonces no se vería entera.

   El rótulo no aparece en el móvil (lleva `d-none d-md-block` de Bootstrap), así
   que ahí no tapa nada: se ve solo la fotografía.

   2. EL PANEL, MÁS A LA IZQUIERDA

   Estaba en `left: 21%` y, con su ancho, llegaba casi al centro de la foto. Al
   moverlo al 4 % queda libre bastante más de la mitad derecha de la imagen, que
   es donde suele estar lo que se quiere ver. Se le pone además un ancho máximo
   para que en pantallas muy anchas no se estire y vuelva a comerse la foto.

   La especificidad iguala la de style.css (0,3,0) y esta hoja carga después.
   ========================================================================== */

/* El `max()` no es adorno: con `left: 4%` a secas, en una pantalla de 1280 el
   panel empezaba en 51 px y la ZONA PULSABLE de la flecha anterior termina en
   68. Se pisaban, y como el panel va encima, un clic en la flecha caía en el
   panel y no pasaba de diapositiva. El suelo de 5rem (80 px) garantiza que
   queden separados por poco que sea la pantalla; en pantallas anchas manda el
   4 %, que es lo que se pidió. */
.slider .carousel-caption {
  left: max(5rem, 4%);
  max-width: min(34rem, 46%);
}

/* En pantallas medianas se deja un poco más de margen: con el panel pegado al
   borde en un portátil, el texto queda incómodo de leer. */
@media (max-width: 1200px) {
  .slider .carousel-caption {
    left: max(5rem, 5%);
    max-width: min(30rem, 52%);
  }
}

@media screen and (max-width: 640px) {
  /* Anula el `display: none` de style.css. */
  .slider {
    display: block;
  }

  /* SIN FLECHAS EN EL MÓVIL, Y NO ES POR ESTÉTICA.
     Sobre una franja de 130 px, las dos flechas más el botón de pausa ocupaban
     el 23 % de la foto, y medido: la flecha derecha y la pausa se pisaban una a
     otra —mismo sitio, 21 px de solape—, así que pulsar una podía activar la
     otra.

     Se van las flechas porque su función ya está cubierta: el carrusel de
     Bootstrap responde al deslizar del dedo, que es como se pasa una foto en un
     teléfono. La pausa se queda porque su función NO está cubierta por nada
     más, y además es obligatoria: un contenido que se mueve solo tiene que
     poder pararse (WCAG 2.2.2). */
  .slider .carousel-control-prev,
  .slider .carousel-control-next {
    display: none;
  }
}

/* El hueco de la cabecera fija lo mide assets/js/alto-cabecera.js y lo deja en
   `--alto-cabecera`. El 10.2rem de respaldo es el valor que tenía style.css: si
   el script no carga, la página queda exactamente como estaba.

   Hacía falta porque el número fijo se quedaba corto —60 px en un móvil de 390,
   16 en una tableta de 745— y lo que cayera en esa franja quedaba debajo de la
   cabecera. Con el carrusel oculto en el móvil no se notaba; al mostrarlo, la
   cabecera tapaba casi la mitad de la foto. */
body {
  padding-top: var(--alto-cabecera, 10.2rem);
}

/* ==========================================================================
   LA PRESENTACIÓN DE LA EDUCADORA, DENTRO DE SU TARJETA
   ==========================================================================
   Va bajo el nombre, en la misma tarjeta. Primero estuvo como sección aparte
   debajo y no funcionaba: la foto quedaba arriba en su recuadro y el texto
   suelto más abajo, sin que se leyera que hablaba la misma persona.

   LA TARJETA ESTÁ CENTRADA Y EL TEXTO NO.
   `.team-card` lleva `text-align: center`, que está bien para un nombre y dos
   líneas de cargo. Con seis párrafos seguidos, el texto centrado obliga a
   buscar el principio de cada renglón. Aquí se alinea a la izquierda.

   ANCHO LIMITADO A 40rem.
   Con una sola educadora la tarjeta ocupa todo el ancho, y una línea de 1.100
   píxeles pierde el salto de renglón. Se centra la columna de texto dentro de
   la tarjeta, que es distinto de centrar el texto.
   ========================================================================== */

.team-presentacion {
  max-width: 40rem;
  margin: 1rem auto 0;
  text-align: left;
  text-wrap: pretty;
}

.team-presentacion p {
  margin: 0 0 1rem;
  font-size: 1rem;
  line-height: 1.7;
  color: var(--text);
}

.team-presentacion p:last-child {
  margin-bottom: 0;
}

/* El nombre y el primer párrafo se separan un poco más: el nombre es el título
   de lo que viene debajo, no una línea más del texto. */
.team-card .team-name {
  margin-bottom: 0.5rem;
}

@media (max-width: 30rem) {
  .team-presentacion p {
    font-size: 0.95rem;
    line-height: 1.65;
  }
}
