/* =========================================================================
   CEA100 — Componentes de página
   Se carga en todas las páginas, después de estilos.css.
   ========================================================================= */

/* ---------- Presentación (hero) ---------------------------------------- */

.hero {
  position: relative;
  padding-block: clamp(3rem, 2rem + 6vw, 7rem) clamp(3rem, 2rem + 5vw, 6rem);
  overflow: hidden;
}

.hero-rejilla {
  display: grid;
  gap: calc(var(--paso) * 1.5);
  align-items: center;
}

@media (min-width: 62em) {
  .hero-rejilla { grid-template-columns: 1.15fr 0.85fr; }
}

.hero h1 { margin-block: 0.4em 0.5em; }

.hero-acciones {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: calc(var(--paso) * 1.2);
}

/* ---- El sol de la escuela de verano ---------------------------------------
   Un sol asomando por la esquina superior izquierda del hero, con el abanico
   de rayos girando muy despacio.

   Son dos gradientes y una máscara: ni una imagen que descargar ni una línea
   de JavaScript. Lo único que se mueve es «transform» y «opacity», que el
   navegador resuelve en la capa de composición sin recalcular estilos ni
   maquetación, así que puede estar girando toda la visita sin coste real.

   El hero recorta lo que se sale (overflow: hidden), por eso el sol puede
   sobresalir por la esquina sin provocar barra de desplazamiento. */
.hero-sol {
  position: absolute;
  top:  -9rem;
  left: -9rem;
  width: clamp(19rem, 34vw, 34rem);
  aspect-ratio: 1;
  z-index: 0;              /* por encima de .hero-fondo, por debajo del texto */
  pointer-events: none;

  /* Ámbar cálido contra el turquesa de la temporada. Con la opacidad tan baja
     no se lee como una mancha naranja, sino como luz. */
  --sol-nucleo: rgba(255, 200,  96, 0.62);
  --sol-halo:   rgba(255, 143,  74, 0.20);
  --sol-rayo:   rgba(255, 156,  66, 0.16);
}

.hero-sol::before,
.hero-sol::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
}

/* Los rayos: 24 cuñas repetidas alrededor del centro.
   Cada cuña va de transparente a color y vuelta a transparente en lugar de
   ser un bloque macizo. Con el canto duro parecían un sol de imprenta; así
   se difuminan por los lados y parecen luz.
   La máscara los deja huecos por dentro —ahí va el disco— y los desvanece
   antes del borde, para que no se vea dónde termina el círculo. */
.hero-sol::before {
  background: repeating-conic-gradient(from 0deg,
    transparent        0deg,
    var(--sol-rayo)  1.6deg,
    transparent      3.2deg,
    transparent       15deg);
  -webkit-mask-image: radial-gradient(closest-side, transparent 30%, #000 46%, transparent 82%);
          mask-image: radial-gradient(closest-side, transparent 30%, #000 46%, transparent 82%);
  animation: cea-sol-gira 140s linear infinite;
}

/* El disco. */
.hero-sol::after {
  background: radial-gradient(closest-side,
    var(--sol-nucleo)  0%,
    var(--sol-halo)   40%,
    transparent       72%);
  animation: cea-sol-late 9s cubic-bezier(0.45, 0, 0.55, 1) infinite;
}

/* Aquí «linear» no es pereza: en una rotación continua cualquier curva de
   aceleración se nota como un tirón en cada vuelta. */
@keyframes cea-sol-gira {
  to { transform: rotate(1turn); }
}

@keyframes cea-sol-late {
  0%, 100% { transform: scale(1);    opacity: 0.85; }
  50%      { transform: scale(1.06); opacity: 1; }
}

/* En el móvil el sol se queda, pero quieto. A ese tamaño el giro no se
   aprecia y no compensa mantener una capa de composición despierta. */
@media (max-width: 61.999em) {
  .hero-sol { top: -7rem; left: -7rem; }
  .hero-sol::before,
  .hero-sol::after { animation: none; }
}

@media (prefers-reduced-motion: reduce) {
  .hero-sol::before,
  .hero-sol::after { animation: none; }
}


/* ---- Los goterones de cera de la escuela de Semana Santa ------------------
   La cera de los cirios resbalando desde el borde de arriba, con su bola al
   final: lo que los niños van recogiendo del suelo durante las procesiones.

   Cuelgan del borde superior a propósito. Es la franja que se ve nada más
   abrir la página, y al colgar de arriba no le quitan sitio al titular, que
   empieza más abajo.

   No crecen al cargar: la cera lleva ahí un rato y ya está puesta. Lo único
   que se mueve es una gota que se desprende de vez en cuando, y solo de tres
   de los siete goterones. */
.hero-cera {
  position: absolute;
  /* La cabecera es pegajosa y translúcida, y se SOLAPA con el hero: las dos
     empiezan en cero. Colgando los goterones del borde del hero, los cortos
     quedaban enteros por detrás de la cabecera y solo asomaban los tres que
     la superaban en largo.
     Los 4,2rem son algo menos que el alto de la cabecera, a propósito: así el
     arranque se mete un poco por debajo de la barra. Si sobrase, se vería un
     hueco entre la barra y el goterón, que canta mucho más que el solape. */
  top: 4.2rem;
  left: 0;
  right: 0;
  height: 0;               /* solo hace de percha; los goterones se salen */
  z-index: 0;              /* por encima de .hero-fondo, por debajo del texto */
  pointer-events: none;
}

.hero-cera i {
  position: absolute;
  top: 0;
  width: 0.85rem;
  border-radius: 0 0 0.45rem 0.45rem;
  /* El degradado en horizontal es lo que le da volumen de cilindro: luz a la
     izquierda y sombra a la derecha. Plano parecería una pegatina. */
  background: linear-gradient(90deg, #fbf6e9 0%, #efe3c6 40%, #d3ba88 100%);
  box-shadow: 0 3px 9px rgb(92 62 20 / 0.13);
}

/* La bola del final, que es lo que hace que se lea como cera y no como una
   barra: la gota se acumula abajo hasta que pesa. */
.hero-cera i::before {
  content: '';
  position: absolute;
  left: -0.21rem;
  bottom: -0.66rem;
  width: 1.27rem;
  height: 1.27rem;
  border-radius: 50%;
  background: radial-gradient(circle at 34% 28%, #fdfaf1, #e3d0a2 58%, #c9ae78);
  box-shadow: 0 3px 9px rgb(92 62 20 / 0.15);
}

/* La gota que se desprende. Nace en la bola, se estira al caer y se apaga. */
.hero-cera i::after {
  content: '';
  position: absolute;
  left: 0.07rem;
  bottom: -0.55rem;
  width: 0.71rem;
  height: 0.95rem;
  border-radius: 50% 50% 50% 50% / 64% 64% 36% 36%;
  background: radial-gradient(circle at 36% 30%, #fdfaf1, #ddc899);
  opacity: 0;
}

/* Largos, anchos y posiciones dispares. Repartidos hacia la izquierda porque
   en escritorio el cartel ocupa la derecha y allí quedarían tapados.
   Los anchos varían aunque sea poco: siete columnas idénticas se leen como
   una plantilla, y la cera no cae dos veces igual. */
.hero-cera i:nth-child(1) { left:  4%; height: 3.1rem; width: 0.78rem; }
.hero-cera i:nth-child(2) { left: 12%; height: 6.6rem; width: 0.95rem; }
.hero-cera i:nth-child(3) { left: 21%; height: 2.1rem; width: 0.72rem; }
.hero-cera i:nth-child(4) { left: 31%; height: 4.9rem; width: 0.88rem; }
.hero-cera i:nth-child(5) { left: 43%; height: 3.4rem; width: 0.8rem;  }
.hero-cera i:nth-child(6) { left: 52%; height: 6.8rem; width: 1rem;    }
.hero-cera i:nth-child(7) { left: 58%; height: 2.6rem; width: 0.75rem; }

/* Dos de otro color. No es capricho: las bolas de cera que recogen los niños
   salen de varios tonos porque se mezcla la de distintas hermandades. Uno en
   el morado de la temporada y otro en rojo cardenal, y el resto en marfil
   para que no parezcan ceras de colorear. */
.hero-cera i:nth-child(4) {
  background: linear-gradient(90deg, #a67cc9 0%, #8d5cb4 40%, #63398b 100%);
}
.hero-cera i:nth-child(4)::before {
  background: radial-gradient(circle at 34% 28%, #c9a9e0, #8d5cb4 58%, #5d3484);
}
.hero-cera i:nth-child(7) {
  background: linear-gradient(90deg, #d98a86 0%, #c56761 40%, #9b4038 100%);
}
.hero-cera i:nth-child(7)::before {
  background: radial-gradient(circle at 34% 28%, #e8b0ac, #c56761 58%, #973d35);
}

/* Ciclos largos y desfasados: la gracia es que caiga una de vez en cuando y
   te pille de sorpresa, no que llueva cera. */
.hero-cera i:nth-child(2)::after { animation: cea-cera-gota 14s ease-in  3s infinite; }
.hero-cera i:nth-child(4)::after { animation: cea-cera-gota 19s ease-in 11s infinite; }
.hero-cera i:nth-child(6)::after { animation: cea-cera-gota 23s ease-in 17s infinite; }

@keyframes cea-cera-gota {
  0%,  2% { transform: translateY(0) scale(0.45);          opacity: 0; }
      7%  { transform: translateY(0) scale(1);             opacity: 1; }
     13%  { transform: translateY(0.35rem) scale(1);       opacity: 1; }
     30%  { transform: translateY(15rem) scale(0.9, 1.45); opacity: 0; }
    100%  { transform: translateY(15rem) scale(0.9, 1.45); opacity: 0; }
}

/* En móvil no hay cartel a la derecha, así que se reparten por todo el ancho,
   y se acortan porque la pantalla es más estrecha.

   Además el hero necesita aire por arriba. En escritorio la rejilla centra el
   texto contra la altura del cartel y eso deja un buen hueco bajo la
   cabecera; al apilarse en móvil ese hueco desaparece y el titular sube hasta
   pegarse a la barra, con los goterones cayéndole encima. El aire se le da
   solo a la página que lleva cera, que es la única que lo necesita. */
@media (max-width: 61.999em) {
  .hero-con-cera { padding-top: 9rem; }

  .hero-cera i { width: 0.7rem; }
  .hero-cera i::before { left: -0.19rem; bottom: -0.55rem; width: 1.08rem; height: 1.08rem; }
  .hero-cera i:nth-child(1) { left:  5%; height: 1.6rem; }
  .hero-cera i:nth-child(2) { left: 18%; height: 2.8rem; }
  .hero-cera i:nth-child(3) { left: 30%; height: 1.1rem; }
  .hero-cera i:nth-child(4) { left: 45%; height: 2.4rem; }
  .hero-cera i:nth-child(5) { left: 60%; height: 1.8rem; }
  .hero-cera i:nth-child(6) { left: 74%; height: 3.2rem; }
  .hero-cera i:nth-child(7) { left: 88%; height: 1.4rem; }
}

/* Sin gotas cayendo: en móvil por lo de siempre, y con movimiento reducido
   porque una gota que cae sola es justo lo que molesta a quien lo activa.
   Los goterones se quedan; son lo que se ve, y no se mueven. */
@media (max-width: 61.999em), (prefers-reduced-motion: reduce) {
  .hero-cera i::after { display: none; }
}

/* Fondo suave con degradado animado. Solo color: no mueve la maquetación. */
.hero-fondo {
  position: absolute;
  inset: -30% -10% auto -10%;
  height: 80%;
  z-index: -1;
  background:
    radial-gradient(38% 55% at 22% 30%, color-mix(in oklab, var(--temporada) 16%, transparent), transparent 70%),
    radial-gradient(42% 50% at 82% 18%, color-mix(in oklab, var(--temporada-acento, var(--acento)) 13%, transparent), transparent 70%);
  filter: blur(10px);
  animation: respirar 18s ease-in-out infinite alternate;
}

@keyframes respirar {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(0, 2%, 0) scale(1.08); }
}

/* ---------- Marca grande del hero -------------------------------------- */

.hero-marca {
  display: grid;
  place-items: center;
  padding: var(--paso);
}

.hero-marca svg {
  width: min(100%, 20rem);
  color: var(--temporada);
  filter: drop-shadow(0 18px 40px rgb(49 41 132 / 0.18));
}

/* ---------- Tarjetas ---------------------------------------------------- */

.tarjeta {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding: calc(var(--paso) * 1.1);
  background: var(--papel);
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  text-decoration: none;
  color: inherit;
  transition: transform 220ms cubic-bezier(0.2, 0.8, 0.2, 1),
              border-color 220ms ease,
              box-shadow 220ms ease;
}

a.tarjeta:hover {
  transform: translateY(-4px);
  border-color: var(--temporada);
  box-shadow: var(--sombra-md);
  color: inherit;
}

.tarjeta h3 { font-size: var(--titulo-sm); }

.tarjeta p { font-size: var(--texto-sm); color: var(--tinta-suave); max-width: none; }

.tarjeta-pie {
  margin-top: auto;
  padding-top: 0.5rem;
  font-size: var(--texto-sm);
  font-weight: 600;
  color: var(--temporada);
}

a.tarjeta:hover .tarjeta-pie::after { transform: translateX(4px); }

.tarjeta-pie::after {
  content: '→';
  display: inline-block;
  margin-left: 0.35em;
  transition: transform 220ms cubic-bezier(0.2, 0.8, 0.2, 1);
}

/* Tarjeta de temporada: hereda el color de su tema. */
.tarjeta-temporada { border-top: 4px solid var(--temporada); }
.tarjeta-temporada.tema-verano       { --temporada: #0e9e86; }
.tarjeta-temporada.tema-navidad      { --temporada: #0d6480; }
.tarjeta-temporada.tema-semana-santa { --temporada: #6d3f9e; }

/* ---------- Cabecera de sección ----------------------------------------- */

.seccion-cabecera {
  max-width: 60ch;
  margin-bottom: calc(var(--paso) * 1.6);
}

.seccion-cabecera h2 { margin-block: 0.25em 0.4em; }

.seccion-cabecera p { color: var(--tinta-suave); font-size: var(--texto-lg); }

.seccion-niebla { background: var(--niebla); }

.seccion-temporada { background: var(--temporada-suave); }

/* ---------- Cifras ------------------------------------------------------ */

.cifras {
  display: grid;
  gap: var(--paso);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 11rem), 1fr));
  list-style: none;
  padding: 0;
}

.cifras li { text-align: center; }

.cifras .cifra {
  display: block;
  font-family: var(--familia-titulos);
  font-size: var(--titulo-lg);
  font-weight: 600;
  line-height: 1;
  color: var(--temporada);
}

.cifras .cifra-texto {
  display: block;
  margin-top: 0.4rem;
  font-size: var(--texto-sm);
  color: var(--tinta-suave);
}

/* ---------- Carteles ---------------------------------------------------- */

.carteles {
  display: grid;
  gap: var(--paso);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
  list-style: none;
  padding: 0;
}

.cartel img {
  width: 100%;
  border-radius: var(--radio);
  box-shadow: var(--sombra-sm);
  transition: transform 260ms cubic-bezier(0.2, 0.8, 0.2, 1), box-shadow 260ms ease;
}

.cartel a:hover img {
  transform: translateY(-5px) scale(1.015);
  box-shadow: var(--sombra-md);
}

/* Un solo cartel destacado, a lo ancho */
.carteles-destacado { grid-template-columns: 1fr; max-width: 46rem; margin-inline: auto; }

/* ---------- Cartel en el hero de temporada ------------------------------ */
/* El cartel publicitario que el centro imprime y reparte por la ciudad. Va
   arriba del todo, junto al titular: es lo primero que ve quien entra. */

.hero-temporada {
  display: grid;
  gap: calc(var(--paso) * 1.6);
  align-items: center;
}

@media (min-width: 62em) {
  /* El cartel es vertical (A3 o A4), así que se lleva menos ancho que el
     texto pero gana altura. */
  .hero-temporada { grid-template-columns: 1.25fr 0.75fr; }
}

.hero-cartel { display: grid; gap: 0.6rem; }

.carteles-hero { grid-template-columns: 1fr; gap: 0.75rem; }

.carteles-hero .cartel img {
  border-radius: var(--radio);
  box-shadow: 0 8px 20px rgb(20 18 43 / 0.10), 0 30px 60px rgb(20 18 43 / 0.14);
  /* Un marco claro despega el cartel del fondo cuando ambos comparten el
     color de la temporada. */
  border: 3px solid var(--papel);
}

.hero-cartel-pie {
  font-size: var(--texto-xs);
  color: var(--tinta-suave);
  text-align: center;
  max-width: none;
}

/* En móvil el cartel va debajo del texto y con ancho acotado: quien entra
   desde el teléfono busca el precio y a quién llamar, no un póster a pantalla
   completa que le obligue a hacer scroll para llegar al dato. */
@media (max-width: 61.999em) {
  .carteles-hero { max-width: 21rem; margin-inline: auto; }
}

/* ---------- Listas de contenido ----------------------------------------- */

.lista-marcada {
  list-style: none;
  padding: 0;
  display: grid;
  gap: 0.7rem;
  max-width: var(--ancho-texto);
}

.lista-marcada li {
  position: relative;
  padding-left: 1.9rem;
}

.lista-marcada li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 0.7rem;
  height: 0.7rem;
  border-radius: 3px;
  background: var(--temporada);
}

/* ---------- Bloques de actividades -------------------------------------- */

.actividades { margin: 0; max-width: var(--ancho-texto); }

.actividades dt {
  font-size: var(--texto-xs);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--temporada);
  margin-top: 1.2rem;
}

.actividades dt:first-child { margin-top: 0; }

.actividades dd { margin: 0.2rem 0 0; }

/* ---------- Bloque de datos prácticos ----------------------------------- */

.datos-practicos {
  display: grid;
  gap: var(--paso);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
  padding: calc(var(--paso) * 1.2);
  background: var(--papel);
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  margin: 0;
}

.datos-practicos dt {
  font-size: var(--texto-xs);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--tinta-suave);
  margin-bottom: 0.3rem;
}

.datos-practicos dd {
  margin: 0;
  font-size: var(--texto-lg);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* ---------- La nota del descuento por hermanos --------------------------- */
/* Una nota amarilla pegada con celo sobre la esquina del recuadro de datos
   prácticos. Amarillo porque es el color que todo el mundo lee como «papelito
   pegado» sin tener que explicarlo, y porque contrasta con las tres paletas de
   temporada, que van de turquesa a morado. */

.pegatina-percha { position: relative; }

.pegatina {
  position: absolute;
  top: -1.9rem;
  right: -0.4rem;
  z-index: 2;
  width: 10.5rem;
  display: block;
  padding: 1.15rem 0.8rem 0.85rem;
  text-align: center;
  text-decoration: none;
  color: #3a3210;
  background: linear-gradient(163deg, #ffe98f 0%, #ffd93d 58%, #f6c500 100%);
  border-radius: 2px 2px 4px 4px;
  /* Torcida: una nota pegada a mano nunca queda recta, y ese par de grados es
     lo que la separa de una caja de aviso más. */
  transform: rotate(-4deg);
  box-shadow: 0 1px 1px rgb(60 45 0 / 0.16),
              0 11px 20px -7px rgb(70 50 0 / 0.38);
  transition: transform 260ms cubic-bezier(0.2, 0.8, 0.2, 1),
              box-shadow 260ms ease;
}

/* La sombra que se acumula abajo insinúa que el papel se despega por ese
   canto. Sin ella la nota parece impresa sobre el fondo. */
.pegatina::after {
  content: '';
  position: absolute;
  inset: auto 0 0 0;
  height: 1.5rem;
  border-radius: 0 0 4px 4px;
  background: linear-gradient(to top, rgb(90 65 0 / 0.10), transparent);
  pointer-events: none;
}

/* El celo. */
.pegatina-cinta {
  position: absolute;
  top: -0.6rem;
  left: 50%;
  width: 4.8rem;
  height: 1.45rem;
  transform: translateX(-50%) rotate(2.5deg);
  background: rgb(255 255 255 / 0.5);
  border-inline: 1px dashed rgb(255 255 255 / 0.85);
  box-shadow: 0 1px 2px rgb(60 45 0 / 0.12);
}

.pegatina-cifra {
  display: block;
  font-family: var(--familia-titulos);
  font-size: 2.5rem;
  font-weight: 700;
  line-height: 0.92;
  /* El color de la temporada: la nota es la misma en las tres páginas, pero el
     número se tiñe del tema. Los tres tonos son oscuros, así que el contraste
     contra el amarillo está garantizado en todas. */
  color: var(--temporada-fuerte, #3a3210);
}

.pegatina-texto {
  display: block;
  margin-top: 0.25rem;
  font-size: var(--texto-sm);
  line-height: 1.25;
}

.pegatina-texto strong { font-weight: 700; }

.pegatina-nota {
  display: block;
  margin-top: 0.4rem;
  font-size: var(--texto-xs);
  /* Un marrón más apagado se leía mejor de estilo, pero contra la parte oscura
     del amarillo se quedaba en 4,17:1 y el mínimo exigido es 4,5. */
  color: #4e4210;
}

.pegatina-pie {
  display: block;
  margin-top: 0.55rem;
  padding-top: 0.45rem;
  border-top: 1px dashed rgb(90 70 0 / 0.3);
  font-size: var(--texto-xs);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.pegatina-pie::after {
  content: ' →';
  display: inline-block;
  transition: transform 220ms cubic-bezier(0.2, 0.8, 0.2, 1);
}

/* Al pasar por encima se endereza y se levanta, como si fueras a despegarla.
   Vale igual con el teclado: es un enlace, no un adorno con ratón. */
.pegatina:hover,
.pegatina:focus-visible {
  transform: rotate(0deg) translateY(-5px) scale(1.04);
  box-shadow: 0 2px 3px rgb(60 45 0 / 0.18),
              0 22px 32px -9px rgb(70 50 0 / 0.45);
  color: #3a3210;
}

.pegatina:hover .pegatina-pie::after,
.pegatina:focus-visible .pegatina-pie::after { transform: translateX(4px); }

/* La nota no puede taparle el sitio a un dato: el precio quedaba debajo. Se le
   reserva hueco en el recuadro —a la derecha si hay columnas, arriba si no— y
   así se apoya sobre espacio vacío en lugar de sobre texto. */
@media (min-width: 48em) {
  .pegatina-percha .datos-practicos { padding-right: 11.5rem; }
}

@media (max-width: 47.99em) {
  .pegatina {
    width: 9rem;
    top: -1.2rem;
    right: 0.5rem;
    padding: 1rem 0.7rem 0.75rem;
  }
  .pegatina-cifra { font-size: 2.1rem; }
  .pegatina-percha .datos-practicos { padding-top: 8.4rem; }
}

@media (prefers-reduced-motion: reduce) {
  .pegatina { transition: box-shadow 260ms ease; }
  .pegatina:hover,
  .pegatina:focus-visible { transform: rotate(-4deg); }
}

/* ---------- Tabla de tarifas -------------------------------------------- */

.tabla-tarifas {
  width: 100%;
  max-width: 34rem;
  border-collapse: collapse;
  background: var(--papel);
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  overflow: hidden;
}

.tabla-tarifas th,
.tabla-tarifas td {
  padding: 0.85rem 1.1rem;
  text-align: left;
  border-bottom: 1px solid var(--borde);
}

.tabla-tarifas tr:last-child th,
.tabla-tarifas tr:last-child td { border-bottom: 0; }

.tabla-tarifas th { font-weight: 500; }

.tabla-tarifas td {
  text-align: right;
  font-weight: 700;
  color: var(--temporada);
  /* Cifras de ancho fijo: así los precios quedan alineados en columna. */
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ---------- Preguntas frecuentes ---------------------------------------- */

.faq { max-width: 52rem; }

.faq details {
  border-bottom: 1px solid var(--borde);
  padding-block: 0.4rem;
}

.faq summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding-block: 0.9rem;
  font-family: var(--familia-titulos);
  font-size: var(--titulo-sm);
  font-weight: 600;
  cursor: pointer;
  list-style: none;
}

.faq summary::-webkit-details-marker { display: none; }

.faq summary::after {
  content: '+';
  flex: none;
  font-family: var(--familia-texto);
  font-size: 1.5rem;
  line-height: 1;
  color: var(--temporada);
  transition: transform 220ms cubic-bezier(0.2, 0.8, 0.2, 1);
}

.faq details[open] summary::after { transform: rotate(45deg); }

.faq details > p, .faq details > ul { padding-bottom: 1rem; }

/* ---------- Aviso de dato pendiente ------------------------------------- */

.aviso-pendiente {
  display: flex;
  gap: 0.75rem;
  padding: 1rem 1.25rem;
  background: #fff8e1;
  border-left: 4px solid #b45309;
  border-radius: var(--radio-sm);
  font-size: var(--texto-sm);
  max-width: var(--ancho-texto);
}

/* ---------- Formulario --------------------------------------------------- */

.formulario {
  display: grid;
  gap: var(--paso);
  max-width: 40rem;
}

/* 'align-content: start' no es cosmética. Dos campos emparejados forman una
   fila de la misma altura, y si uno lleva texto de ayuda o un error debajo y
   el otro no, el que va corto estira su input para rellenar el hueco: los dos
   recuadros acaban de distinto alto y la línea se ve torcida. Empaquetando
   las filas arriba, cada input conserva su altura y quedan alineados. */
.campo { display: grid; gap: 0.35rem; align-content: start; }

.campo-ayuda { font-size: var(--texto-xs); color: var(--tinta-suave); }

/* Pista corta dentro de la propia etiqueta. Existe para no gastar una línea
   debajo del campo: en una pareja, esa línea de más descuadra la fila. */
.etiqueta-pista {
  font-weight: 400;
  font-size: var(--texto-xs);
  color: var(--tinta-suave);
}

.campo-error { font-size: var(--texto-sm); color: #b3261e; font-weight: 600; }

/* ---------- Formulario de solicitud de plaza ----------------------------
   Es el formulario más largo de la web: once bloques seguidos. A 44rem
   pegado a la izquierda quedaba una columna estrecha y larguísima con medio
   contenedor vacío al lado. Se resuelve con lo que el propio formulario ya
   tenía: sus dos grupos, «quién viene» y «quién lo apunta», que son
   independientes y se pueden leer uno al lado del otro sin partir ninguna
   secuencia por la mitad. */

.formulario-temporada {
  max-width: 62rem;
  margin-inline: auto;
  padding: clamp(1.25rem, 0.6rem + 2.4vw, 2.5rem);
  background: var(--papel);
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  box-shadow: var(--sombra-sm);
}

/* La cabecera y los avisos de esta sección se alinean con el formulario, no
   con el borde del contenedor. El formulario es un panel centrado de 62rem,
   y todo lo de arriba se quedaba pegado a la izquierda, descuadrado
   respecto a él. */
.bloque-reserva {
  max-width: 62rem;
  margin-inline: auto;
}

.seccion-cabecera.bloque-reserva { text-align: center; }

/* El párrafo se queda justificado aunque el bloque vaya centrado: la regla
   directa sobre 'p' gana a la alineación que se hereda del padre. Lo que
   hace falta es centrar su caja, porque si no la mancha de texto justificado
   se pega al borde izquierdo del bloque y vuelve el descuadre. */
.seccion-cabecera.bloque-reserva p { margin-inline: auto; }

/* El sobretítulo también es un <p>, así que le caía encima el justificado
   general. Una sola línea justificada se pinta pegada a la izquierda, y se
   quedaba descolgado bajo un titular centrado. */
.seccion-cabecera.bloque-reserva .sobretitulo { text-align: center; }

/* Cada grupo mide su propio ancho. Las parejas de campos de dentro se
   deciden por esa medida y no por la de la ventana: en pantalla ancha el
   formulario va a dos columnas, y media columna no da para dos campos por
   mucho que la ventana sea grande. */
.formulario-temporada .grupo { container-type: inline-size; }

/* Por defecto, uno debajo de otro. La regla general de .campos-par mira la
   ventana, y aquí eso no sirve. */
.formulario-temporada .campos-par { grid-template-columns: 1fr; }

@container (min-width: 26rem) {
  .formulario-temporada .campos-par { grid-template-columns: 1fr 1fr; }

  /* Un nombre con dos apellidos necesita sitio; una edad son dos cifras. Pero
     no tan desigual como para que «Edad (3–12) *» se parta en dos líneas: si
     la etiqueta pasa a dos renglones, la fila vuelve a crecer y reaparece el
     descuadre que se estaba arreglando. */
  .formulario-temporada .campos-par-desigual { grid-template-columns: 1.9fr 1fr; }
}

/* Semana Santa no pinta «cuándo empieza». Sin esto, «cuánto tiempo» se
   quedaría a media línea, cojo, con un hueco al lado. */
.formulario-temporada .campo-solo { display: grid; }

@media (min-width: 62em) {
  .formulario-temporada > fieldset {
    grid-template-columns: 1fr 1fr;
    align-items: start;
    column-gap: calc(var(--paso) * 1.7);
  }

  /* El botón cruza las dos columnas: es el final del formulario entero, no
     el de la columna derecha. */
  .formulario-temporada > fieldset > .formulario-envio {
    grid-column: 1 / -1;
    border-top: 1px solid var(--borde);
    padding-top: var(--paso);
  }
}

/* Los grupos de campos van en fieldset por lo que significan, no por cómo se
   ven: un lector de pantalla anuncia la leyenda al entrar en el grupo, y el
   fieldset de fuera permite apagar el formulario entero con una palabra.
   El borde y el hueco que traen por defecto sobran. */
.formulario fieldset {
  display: grid;
  gap: var(--paso);
  border: 0;
  padding: 0;
  margin: 0;
  min-width: 0;            /* si no, el fieldset se niega a encoger */
}

.formulario legend {
  padding: 0;
  font-family: var(--familia-titulos);
  font-size: var(--titulo-sm);
  font-weight: 600;
}

/* Campos cortos de dos en dos, pero solo cuando hay sitio. */
.campos-par { display: grid; gap: var(--paso); }

@media (min-width: 40em) {
  .campos-par { grid-template-columns: 1fr 1fr; }
}

.campo-casilla {
  display: flex;
  gap: 0.65rem;
  align-items: flex-start;
  font-weight: 400;
  font-size: var(--texto-sm);
}

/* La regla general pone los campos al 100% del ancho. A una casilla eso la
   deja del tamaño de un botón. */
.campo-casilla input[type="checkbox"] {
  width: 1.1rem;
  height: 1.1rem;
  flex: none;
  margin-top: 0.15rem;
  accent-color: var(--temporada, var(--indigo-600));
}

.campo-casilla .campo-ayuda { display: block; }

/* Mientras el formulario está apagado se ve, pero se ve apagado: así nadie
   empieza a rellenarlo creyendo que va a llegar a alguna parte. */
.formulario fieldset[disabled] { opacity: 0.62; }

.formulario fieldset[disabled] .boton { cursor: not-allowed; }

/* Campo trampa: invisible para personas, apetecible para robots. */
.trampa {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.mensaje {
  padding: 1rem 1.25rem;
  border-radius: var(--radio-sm);
  max-width: 40rem;
}

.mensaje-bien { background: #e7f6ec; border-left: 4px solid #14713f; }
.mensaje-mal  { background: #fdecea; border-left: 4px solid #b3261e; }

/* ---------- Canales de contacto ------------------------------------------ */
/* Sustituyen al formulario mientras está desactivado. */

.canales { display: grid; gap: 0.9rem; margin-top: var(--paso); }

.canal {
  display: grid;
  gap: 0.15rem;
  padding: calc(var(--paso) * 0.9) calc(var(--paso) * 1.1);
  background: var(--papel);
  border: 1px solid var(--borde);
  border-left: 4px solid var(--indigo-600);
  border-radius: var(--radio);
  text-decoration: none;
  color: inherit;
  transition: transform 200ms cubic-bezier(0.2, 0.8, 0.2, 1),
              box-shadow 200ms ease, border-color 200ms ease;
}

.canal:hover {
  transform: translateX(4px);
  box-shadow: var(--sombra-md);
  border-color: var(--acento);
  color: inherit;
}

.canal-etiqueta {
  font-size: var(--texto-xs);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--tinta-suave);
}

.canal-valor {
  font-family: var(--familia-titulos);
  font-size: var(--titulo-sm);
  font-weight: 600;
  color: var(--indigo-700);
  font-variant-numeric: tabular-nums;
}

.canal-nota { font-size: var(--texto-sm); color: var(--tinta-suave); }

/* ---------- Contacto ----------------------------------------------------- */

.contacto-rejilla {
  display: grid;
  gap: calc(var(--paso) * 1.5);
}

@media (min-width: 62em) {
  .contacto-rejilla { grid-template-columns: 1.1fr 0.9fr; }
}

.mapa {
  display: block;
  border-radius: var(--radio);
  overflow: hidden;
  border: 1px solid var(--borde);
}

/* ---------- Partículas de temporada -------------------------------------- */

.particulas {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  /* El ancho y el alto explícitos NO sobran. Un canvas es un elemento
     reemplazado, como una imagen: con inset:0 pero sin medidas, se queda en
     su tamaño intrínseco de 300x150 y las partículas se dibujan en un
     recuadro de la esquina en lugar de sobre toda la sección. */
  width: 100%;
  height: 100%;
}

.hero > .contenedor { position: relative; z-index: 1; }

/* ---------- Llamada final ------------------------------------------------ */

.llamada {
  text-align: center;
  padding: calc(var(--seccion) * 0.8) var(--paso);
  background: var(--temporada);
  border-radius: var(--radio);
  color: #fff;
}

.llamada h2 { color: #fff; }
.llamada p  { color: rgb(255 255 255 / 0.9); margin-inline: auto; }
.llamada .boton-principal { background: #fff; color: var(--temporada-fuerte); margin-top: var(--paso); }
.llamada .boton-principal:hover { background: #fff; color: var(--temporada-fuerte); }
