/* ===========================================================================
   ALVI · HOME — hero y bloque de servicios

   AQUÍ NO HAY NI UN COLOR ESCRITO. Todos salen de theme.css como var(--...).
   =========================================================================== */


/* ===========================================================================
   HERO

   Foto a sangre y, encima, una PLACA VERDE OPACA que desborda la foto por
   abajo y se apoya en el fondo crema.

   La placa es opaca a propósito. El hero de gradiente con el texto flotando
   sobre la foto es el hero por defecto de cualquier web de servicios, y encima
   juega el contraste a los dados: si el cliente manda una foto clara, el
   titular deja de leerse. Aquí NINGÚN texto va sobre la imagen, así que el
   contraste está garantizado pase lo que pase con la fotografía.
   =========================================================================== */

/*
  PROPORCIÓN DEL HERO

  La placa se apoya MAYORITARIAMENTE sobre la foto y desborda solo lo justo
  para pisar el crema. Al revés —una placa grande con una tira de imagen
  encima— no se lee como una placa sobre una fotografía, se lee como una caja
  verde coronada por una franja.

  Y el solape existe en los tres anchos. Es el recurso central del hero: si
  solo aparece en escritorio, en el móvil (que es por donde entra la mayoría
  de este público) el hero deja de ser el hero.
*/
.hero {
  padding-bottom: var(--sp-6);
}

/* La sección que va justo detrás del hero respira menos por arriba: así, en
   una pantalla de 1080 asoma el titular de servicios y no solo un palmo de
   crema. Ese asomo es lo que dice "esta página sigue". */
.seccion--tras-hero {
  padding-top: var(--sp-10);
}

/* El contenedor de la placa crea contexto de formato propio.
   Sin esto, el margen negativo de la placa COLAPSA con el del contenedor y el
   solape real sale 45px menor que el que se pide: se movía el contenedor
   entero en vez de solo la placa. Con flow-root el margen hace exactamente lo
   que dice. */
.hero__cuerpo {
  display: flow-root;
}

/* La foto rompe el contenedor y va de lado a lado. */
.hero__foto {
  width: 100%;
}

.hero__hueco {
  /* Altura directa, sin proporción: combinar "aspect-ratio" con un tope de
     altura hace que el navegador encoja también la anchura, y la foto deja de
     ir a sangre. Aquí se controla el alto y el ancho es siempre el 100 %. */
  aspect-ratio: auto;
  /* La foto es CONTEXTO, no protagonista: cada píxel que ocupa aquí empuja el
     teléfono hacia abajo, y el escenario que manda es el agricultor en la
     finca con el móvil.

     El tope sube de 15rem (270px) a 19rem (342px) porque la cabecera pegajosa
     de una fila devolvió 72px sobre el pliegue: medido, sobraban 182px de
     margen bajo los botones a 360x780 y la foto se había quedado corta.
     Por debajo de 480px no manda esta regla: allí la foto va en 16:9,
     debajo de la placa y pegada a ella. */
  height: clamp(11rem, 55.5vw, 19rem);
  border-inline: 0;
  border-radius: 0;

  /* EL ENCUADRE DEL HERO.

     Medido sobre una rejilla de porcentajes puesta encima del original: el
     rótulo "ALVI SERVICIOS Y MANTENIMIENTOS S.L." ocupa del 29,8 % al 37,8 %
     del alto, y del 23 % al 100 % del ancho. Llega justo al borde derecho.

     De ahí salen las dos reglas de las que depende todo lo demás:

       1. LA CAJA NUNCA PUEDE SER MÁS ALTA QUE LA FOTO (1,78:1 tras el recorte
          de origen que hace generar-imagenes.py). Si lo es, "cover" recorta
          por los lados en vez de por arriba y abajo, y lo primero que se
          pierde es el final del rótulo. Es lo que pasaba a 360px con la caja
          en 4:5: se veía "ALVI SERVICIOS Y MANTENI".
       2. Con el recorte de origen ya hecho, la banda visible es casi la foto
          entera, así que el encuadre vertical apenas tiene que corregir nada
          por debajo de 60rem. Donde sí importa es en escritorio, que es donde
          la caja se estrecha de verdad. */
  --foto-encuadre: 50% 50%;
}

/* Por debajo de 480px la foto va debajo de la placa, en 16:9. Como el recorte
   de origen ya deja la fotografía casi en esa misma proporción, aquí se ve
   entera de lado a lado y el encuadre vertical no tiene nada que corregir. */
@media (max-width: 30rem) {
  .hero__hueco {
    --foto-encuadre: 50% 38%;
  }
}

@media (min-width: 48rem) {
  /* El 62vw de antes daba una caja de 0,62 de alto por 1 de ancho: más alta
     que la foto, o sea recorte horizontal y rótulo cortado otra vez. 55vw la
     deja siempre por debajo de 1,78:1. */
  .hero__hueco {
    height: min(clamp(22rem, 55vw, 26rem), 72vh);
  }
}

@media (min-width: 60rem) {
  /* LA ALTURA DEL HERO ES UN REPARTO, no un gusto.

     Cada píxel de alto de la foto empuja el teléfono hacia abajo, y el
     teléfono es el motivo de la página. Pero si la foto se queda corta, la
     placa tapa el rótulo de la nave y la foto deja de decir nada.

     Probé primero con min(56.25vw, 78vh). Medido: el rótulo entraba, sí, pero
     a 1440x900 el teléfono se iba 8px por debajo del pliegue y los botones
     86px. Eso es peor que la foto pequeña.

     42vw con tope de 72vh es el punto donde las dos cosas entran a la vez en
     las pantallas reales. Y hay una razón por la que el tope de 72vh no
     estropea el encuadre: en cualquier pantalla 16:9 manda el 72vh y la caja
     sale 0,405 de alto; en cualquier 16:10 manda el 42vw y sale 0,42. Son
     casi la misma proporción, así que un único encuadre vale para todas.

     El tope es 70vh y no 72vh por 15px: con 72vh el teléfono se quedaba
     clavado en el pliegue a 1366x768 —margen medido: 0px— y un margen de
     cero no es un margen. */
  .hero__hueco {
    height: min(clamp(26rem, 42vw, 56rem), 70vh);

    /* 62 % deja a la vista, medido, del 26 % al 79 % de la fotografía
       original: el tejado con las placas solares, el rótulo en el tercio alto
       y las furgonetas. Ni el cielo liso de arriba ni el asfalto de abajo. */
    --foto-encuadre: 50% 62%;
  }
}

/* Pantallas ultrapanorámicas (21:9 y ventanas muy bajas y anchas). Aquí la
   banda visible se estrecha de golpe, y con el 62 % el recorte empezaría por
   debajo del rótulo y le cortaría la parte de arriba. Único sitio del hero
   con un encuadre distinto, y está medido, no supuesto. */
/* DE 1280px PARA ARRIBA LA BARRA FLOTA SOBRE LA FOTO.
   La foto crece exactamente lo que mide la barra, así que la placa y todo lo
   que hay debajo se quedan donde estaban; lo que gana la página es que la
   fotografía empieza en el píxel 0 en vez de debajo de un cajón oscuro.

   Y el encuadre baja al 0 %: con la caja más alta, el rótulo se iba justo
   detrás de la barra —medido, entre 6 y 38px por debajo de ella según el
   ancho—. Con el encuadre arriba del todo, el rótulo sale por debajo de la
   barra en las doce medidas.

   El tope de 55vw impide que la suma deje la caja más alta que la foto. */
@media (min-width: 80rem) {
  .hero__hueco {
    height: min(calc(min(clamp(26rem, 42vw, 56rem), 70vh) + var(--alto-cabecera)), 55vw);
    --foto-encuadre: 50% 0%;
  }
}

@media (min-width: 60rem) and (max-width: 79.99rem) and (min-aspect-ratio: 2 / 1) {
  /* Sin barra flotante: la caja es la de siempre y el encuadre, el de siempre. */
  .hero__hueco {
    --foto-encuadre: 50% 43%;
  }
}

/* Ventanas muy anchas y bajas CON la barra flotando. Aquí la banda visible se
   estrecha y el rótulo se acerca a la placa por abajo en vez de a la barra por
   arriba: a 1920x800 con el encuadre a 0 se metía 79px dentro de la placa.
   El 22 % es el punto donde las dos cosas entran, y entran justas. */
@media (min-width: 80rem) and (min-aspect-ratio: 2 / 1) {
  .hero__hueco {
    --foto-encuadre: 50% 22%;
  }
}

/* ===========================================================================
   LAS DOS PUERTAS

   Debajo del hero, en el sitio donde el ojo va después del teléfono. Son las
   dos cosas a las que viene la gente, dichas como se dicen por teléfono.

   El bloque entero es el enlace, no un botón dentro de un cajón: en un móvil
   con guantes, un área táctil de media pantalla no falla.

   Los dos fondos son distintos a propósito. Una es una compra y la otra es un
   apuro; si las dos gritan igual, no se distingue cuál es cuál. El lima lleva
   TINTA encima —el blanco sobre este verde da 3,30:1 y no llega a AA—.
   =========================================================================== */

.puertas__reja {
  display: grid;
  gap: var(--sp-2);
  padding-block: var(--sp-2) 0;
}

@media (min-width: 48rem) {
  .puertas__reja {
    grid-template-columns: 1fr 1fr;
  }
}

.puerta {
  position: relative;
  isolation: isolate;

  display: grid;
  align-content: start;
  gap: var(--sp-2);
  padding: var(--sp-6);
  min-height: 11rem;

  text-decoration: none;

  /* El desplazamiento de 1px al pulsar. Físico y sin sombra: la pieza baja,
     no flota. */
  transition: transform 90ms var(--ease);
}

.puerta:active {
  transform: translateY(1px);
}

@media (prefers-reduced-motion: reduce) {
  .puerta {
    transition: none;
  }
}

.puerta--pieza {
  background: var(--bg-accent);
  color: var(--text-on-accent);
  --surco: var(--surco-sobre-lima);
}

.puerta--averia {
  background: var(--bg-inverse);
  color: var(--text-on-inverse);
  --surco: var(--surco-sobre-oscuro);
}

/* La referencia, arriba. Es el mismo motivo que el código de sección: la
   página está organizada como el almacén. */
/* SIN OPACIDAD, y esto lo cazó contraste.py, no el ojo.
   Con opacity: 0.72 el código quedaba en 4,15:1 sobre el lima: por debajo del
   mínimo AA de 4,5. La jerarquía la dan el cuerpo pequeño y el espaciado de
   letra, que no cuestan contraste. Sobre el gris oscuro va en el gris claro
   de secundario, que es el mismo que usa el pie de página. */
.puerta__codigo {
  font-size: var(--fs-meta);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.12em;
}

.puerta--averia .puerta__codigo {
  color: var(--text-on-inverse-muted);
}

.puerta__titulo {
  font-family: var(--font-title);
  font-size: var(--fs-h3);
  font-weight: 700;
  line-height: 1.15;
}

.puerta__texto {
  max-width: 34ch;
}

/* El pie hace de "y ahora qué": el icono y adónde lleva. Va subrayado solo al
   pasar por encima, porque el bloque entero ya se ve que es un enlace. */
.puerta__pie {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin-top: var(--sp-2);
  font-size: var(--fs-meta);
  font-weight: 600;
}

.puerta:hover .puerta__pie,
.puerta:focus-visible .puerta__pie {
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
}

.puerta__pie svg {
  width: 1.15em;
  height: 1.15em;
  flex: 0 0 auto;
}


.hero__placa {
  background: var(--bg-inverse);
  color: var(--text-on-inverse);
  padding: var(--sp-6);

  /* LA PLACA TIENE QUE PINTARSE POR ENCIMA DE LA FOTO, Y NO BASTA CON EL ORDEN
     DEL DOCUMENTO.

     El orden de pintado del CSS no es "lo que va después tapa a lo que va
     antes". Primero se pintan los FONDOS de todos los bloques, y después el
     contenido en línea y los elementos reemplazados —entre ellos, las <img>—.
     Así que una imagen que está ANTES en el documento se pinta ENCIMA del
     fondo de un bloque que está después.

     Mientras el hero llevaba el hueco compuesto no se notaba: el hueco es un
     fondo, y se pintaba en la misma fase. En cuanto entró una fotografía de
     verdad, el titular se quedó sobre la foto y dejó de leerse.

     Con position + z-index la placa crea su propio contexto de apilamiento y
     se pinta encima de todo lo anterior. La regla de la casa —el titular NUNCA
     va sobre la fotografía— se sostiene aquí. */
  position: relative;
  z-index: 1;

  /* El solape empieza aquí: la placa sube sobre la foto. Este valor gobierna
     la banda estrecha; de 48rem para arriba lo sustituyen las reglas de más
     abajo. */
  margin-top: -8.9rem;
}

/* ---------------------------------------------------------------------------
   HERO EN MÓVIL: OTRA ESTRUCTURA, NO LA MISMA ENCOGIDA

   Por debajo de 480px la placa NO se monta sobre la foto. Va pegada a la
   cabecera, a ancho completo, y la fotografía baja debajo, en 16:9, PEGADA
   a la placa, haciendo de transición hacia los servicios.

   El motivo: con el solape que hacía falta para que los botones cupieran por
   encima del pliegue, de la foto quedaban 54px. Eso no es una fotografía, es
   una franja de textura, y con la imagen real puesta quedaría peor, no mejor.
   El recurso de la placa sobre la imagen es de tablet y escritorio.

   De 481px en adelante no cambia nada.
   --------------------------------------------------------------------------- */

@media (max-width: 30rem) {
  .hero {
    display: flex;
    flex-direction: column;
  }

  /* LA FOTO VUELVE A SER FONDO, TAMBIÉN EN MÓVIL.

     Iba debajo de la placa y eran tres cajas apiladas sin relación: cajón
     oscuro, tira de foto, tarjeta verde. La foto no era fondo de nada.

     Ahora es el mismo recurso que en escritorio: la fotografía arriba y a
     sangre, y la placa montada encima desbordando hacia el crema.

     Se pudo recuperar porque la cabecera bajó de 144px a 72: esos 72px son
     justo el margen que hacía falta. */
  .hero__foto {
    order: 0;
    margin-top: 0;
  }

  .hero__cuerpo {
    order: 1;
  }

  .hero__placa {
    /* EL SOLAPE, y de dónde sale el número.

       Tira de dos sitios a la vez y en direcciones opuestas:

         · MÁS solape tapa el rótulo de la nave. Dentro de la caja 16:9 el
           rótulo va del 20,4 % al 31,9 % del alto, así que por encima de la
           placa tienen que quedar al menos 0,319 x 56,25vw más un poco de aire.
         · MENOS solape empuja los botones bajo el pliegue, porque la foto ya
           no está debajo de la placa sino encima, y todo lo que se ve de ella
           baja el resto.

       28vw es la mitad de la altura de la foto: deja a la vista la otra mitad,
       con el rótulo entero y aire por los dos lados. Las medidas de cada
       tamaño están en el informe.

       LA PLACA SIGUE OPACA. El titular no va sobre la fotografía; lo que hace
       la placa es taparla, no dejarla translucir. */
    margin-top: calc(-1 * 28vw);
  }

  /* A 320px la cuenta no sale con el 28vw: la placa mide 54px más que a 360
     —el titular y la línea de horario parten en más líneas— y los botones se
     iban 25px por debajo del pliegue.

     36vw sube el solape al 64 % de la foto y los devuelve dentro. Es el único
     tamaño donde los dos márgenes quedan finos: 8px de aire bajo el rótulo y
     el pliegue justo. Está medido y dicho; por debajo de esto no da más de
     sí. */
  @media (max-width: 22rem) {
    .hero__placa {
      margin-top: calc(-1 * 36vw);
    }
  }

  /* El aire interior de la placa se aprieta en el bloque de 47,99rem, más
     abajo en este mismo archivo. Se ajusta ALLÍ y no aquí: dos bloques con la
     misma especificidad para lo mismo es la forma de que gane el que no
     querías, y en este proyecto ya ha pasado tres veces. */

  .hero__hueco {
    /* 16:9 Y NO 4:5, y no es una preferencia estética.
       En 4:5 la caja (1,25) es más alta que la foto (1,78), así que el
       recorte pasa a ser horizontal: medido, solo se veía del 18 % al 82 %
       del ancho del original. El rótulo va del 23 % al 100 %, o sea que se
       perdía un tercio de él. En la captura se leía "ALVI SERVICIOS Y
       MANTENI".
       De paso, 16:9 es una de las dos únicas proporciones del sitio. */
    aspect-ratio: 16 / 9;
    height: auto;
    max-height: none;
  }
}

/* Entre 480 y 768 la placa sí se monta, pero la franja de foto que queda
   arriba es estrecha y el rótulo del hueco se colaría por detrás. */
@media (min-width: 30.01rem) and (max-width: 47.99rem) {
  .hero__hueco .hueco__rotulo {
    display: none;
  }
}



/* --- Ritmo interno de la placa -------------------------------------------
   Todo lo de aquí abajo está apretado a propósito para bajar la placa de 823px
   a poco más de 560. No desaparece ningún elemento: se recorta el aire. */

.hero__titular {
  font-size: var(--fs-display);
  line-height: 1;
  font-weight: 700;
  margin: 0 0 var(--sp-3);

  /* "pretty" y NO "balance". Balance reparte el texto en líneas de longitud
     parecida, y eso mantenía el titular en CUATRO líneas cuando cabía en tres:
     81px de placa de más, que es justo lo que había que recortar. Pretty llena
     las líneas y solo evita que la última quede huérfana. */
  text-wrap: pretty;
}

.hero__frase {
  font-size: var(--fs-lead);
  line-height: 1.45;
  color: var(--text-muted);
  margin: 0 0 var(--sp-3);
  max-width: 34ch;
}

.hero__regla {
  border: 0;
  border-top: 1px solid var(--border-on-inverse);
  margin: 0 0 var(--sp-3);
}

/* Etiqueta, número y horario van juntos: son una sola cosa. */
.hero__llamada {
  margin-bottom: var(--sp-5);
}

.hero__rotulo {
  display: block;
  font-size: var(--fs-meta);
  color: var(--text-muted);
  margin-bottom: var(--sp-1);
}

.hero__llamada .horario-aviso {
  margin-top: var(--sp-1);
}

.hero__acciones {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
}

.hero__acciones .boton {
  flex: 1 1 auto;
}

@media (min-width: 30rem) {
  .hero__acciones .boton {
    flex: 0 0 auto;
  }
}


/* --- Palanca 4: ritmo interno de la placa, solo en móvil ------------------
   Escritorio queda intacto: está aprobado y no se toca. Aquí solo se recorta
   aire, ni un elemento desaparece y no se baja el cuerpo de nada. */
@media (max-width: 47.99rem) {
  /* De sp-5 a sp-4 y de sp-2 a sp-1: 27px menos de alto de placa. Es lo que
     hace que, con la foto ahora ENCIMA de la placa, los botones sigan cabiendo
     en las pantallas de 780. No se toca ni un cuerpo de letra ni un área
     táctil: solo huecos. */
  .hero__placa {
    padding: var(--sp-4);
  }

  .hero__titular,
  .hero__frase,
  .hero__regla {
    margin-bottom: var(--sp-1);
  }

  .hero__frase {
    line-height: 1.3;
  }

  /* Ya está en sp-3, no en el sp-5 de la regla base. Se intentó "recuperar"
     esos 9px añadiendo esta misma declaración más arriba, en este mismo
     bloque, y el resultado fue idéntico al píxel: la regla ya existía aquí
     abajo. Antes de recortar aire hay que mirar si ya está recortado. */
  .hero__llamada {
    margin-bottom: var(--sp-3);
  }

  /* Los dos botones en una fila, pero NO al 50/50: con el mismo ancho el rojo
     y el de contorno pesan igual y se rompe la regla de una sola acción
     principal por pantalla. 58/42 a favor de "Pedir cita", con el hueco
     descontado de cada parte para que el reparto sea exacto.

     Al 42 % de 279px son 117px de ancho por 54 de alto: por encima de los
     48x48 de área táctil mínima. */
  .hero__acciones {
    flex-wrap: nowrap;
    gap: var(--sp-2);
  }

  .hero__acciones .boton--principal {
    flex: 0 0 calc(58% - (var(--sp-2) / 2));
  }

  .hero__acciones .boton--secundario {
    flex: 0 0 calc(42% - (var(--sp-2) / 2));
  }

  .hero__acciones .boton {
    padding-inline: var(--sp-3);
    font-size: var(--fs-meta);
  }

  .hero__acciones .boton svg {
    width: 1.15em;
    height: 1.15em;
  }
}

/* --- 320px: los últimos 9px --------------------------------------------------

   VA AQUÍ ABAJO, DESPUÉS DEL BLOQUE DE 47,99rem, y no arriba con el resto de
   lo de 22rem. A 320 casan las dos condiciones, misma especificidad, y gana la
   última: puesto arriba, el `padding: var(--sp-4)` de más abajo lo pisaría y
   esto sería código muerto. Ha pasado ya cuatro veces en este archivo.

   Solo se toca el aire de arriba y abajo de la placa —de 18 a 13,5— y se deja
   el de los lados. Los lados se ven; el de arriba y abajo, a 320, es lo único
   que separa los botones del borde inferior de la pantalla. Ni un cuerpo de
   letra ni un área táctil cambian. */
@media (max-width: 22rem) {
  .hero__placa {
    padding-block: var(--sp-3);
  }
}

@media (min-width: 48rem) {
  .hero__placa {
    max-width: 46rem;

    /* MENOS SOLAPE QUE EN ESCRITORIO, y aquí sí hay un motivo medido.
       En esta banda la foto no puede pasar de 55vw sin recortar el rótulo por
       los lados (ver .hero__hueco), así que la franja que queda por encima de
       la placa es corta. Con el solape de escritorio la placa se comía el
       rótulo: a 768px, el rótulo acaba en el píxel 133 de la foto y la placa
       empezaba en el 98. */
    margin-top: calc(-1 * clamp(12rem, 24vw, 20rem));
    padding: var(--sp-6);
  }
}

/* --- El solape de escritorio ----------------------------------------------

   ESTE BLOQUE TIENE QUE IR DESPUÉS DEL DE 48rem, y por eso está aquí abajo y
   no arriba con los demás.

   Estuvo arriba y era CÓDIGO MUERTO: misma especificidad, gana el último, y el
   `margin-top: -15rem` fijo del bloque de 48rem lo pisaba entero. El resultado
   es que el solape llevaba tiempo clavado en 270px —el 50 % de la placa—
   cuando el acuerdo era 65-75 % y en su día medía 71 %. El cálculo escalado
   estaba escrito y no se ejecutaba nunca.

   Es el mismo tipo de fallo que el de la regla del botón flotante: una
   media query correcta puesta antes que la que la anula. Se ve midiendo, no
   leyendo.

   El solape escala con el ancho en vez de ser fijo. Con un valor fijo, a
   1024px la placa tapaba casi toda la foto y no quedaba imagen que ver. */
@media (min-width: 60rem) {
  .hero__placa {
    /* 44rem y no 38rem: con la placa un poco más ancha el titular entra en
       tres líneas en vez de cuatro. Es ritmo interno, no contenido menos. */
    max-width: 44rem;
    margin-top: calc(-1 * clamp(19rem, 31vw, 24rem));
    padding: var(--sp-6) var(--sp-8);
  }
}


/* ---------------------------------------------------------------------------
   EL ÚNICO MOMENTO ORQUESTADO DE TODO EL SITIO

   La placa entra desde abajo y el teléfono aparece 120 ms después. Nada más
   se mueve solo en toda la web: ni tarjetas que suben al pasar el ratón, ni
   secciones que aparecen al hacer scroll. Eso marea, y a este público más.

   La animación se declara DENTRO de "prefers-reduced-motion: no-preference",
   así que quien tenga puesto el ajuste de movimiento reducido no es que vea
   una animación más corta: es que no hay animación que ver.
   --------------------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
  .hero__placa {
    animation: alvi-placa-entra 520ms var(--ease) both;
  }

  .hero__llamada {
    animation: alvi-aparece 360ms var(--ease) 120ms both;
  }
}

/* La placa NO se desvanece: solo se desliza.
   Con opacidad, durante medio segundo la placa es translúcida, el titular se
   queda encima de la foto y deja de leerse. Todo el sentido de la placa opaca
   es que el contraste no dependa nunca de la fotografía, y una animación no
   puede saltarse eso ni por 500 ms. */
@keyframes alvi-placa-entra {
  from {
    transform: translateY(2.5rem);
  }
  to {
    transform: none;
  }
}

@keyframes alvi-aparece {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}


/* ===========================================================================
   ALVI EN UNA FRASE
   Franja verde de lado a lado. Dos líneas grandes y nada más: es una
   afirmación, no una llamada, y por eso no lleva botón.
   =========================================================================== */

.frase-marca {
  margin: 0;
  max-width: 30ch;
  font-family: var(--font-title);
  font-size: var(--fs-h2);
  font-weight: 600;
  line-height: 1.25;
  text-wrap: pretty;
}

@media (min-width: 60rem) {
  .frase-marca {
    max-width: 46ch;
  }
}


/* ===========================================================================
   FAMILIAS DE RECAMBIO
   Atajos a las familias que más se piden, más el enlace al catálogo entero.
   =========================================================================== */

.familias {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  list-style: none;
  margin: var(--sp-6) 0 0;
  padding: 0;
}

.familias__enlace {
  display: inline-flex;
  align-items: center;
  min-height: var(--touch);
  padding-inline: var(--sp-5);

  background: var(--bg-paper);
  color: var(--text-body);
  border: 2px solid var(--border-strong);
  border-radius: var(--r-md);
  font-weight: 600;
  text-decoration: none;
}

/* AL PASAR POR ENCIMA SE RELLENA, no se limita a cambiar de borde. Antes solo
   se movía el color del trazo y no se notaba; ahora la píldora se enciende
   entera. Tinta sobre lima, jamás blanco. */
.familias__enlace:hover,
.familias__enlace:focus-visible {
  background: var(--bg-accent);
  border-color: var(--bg-accent);
  color: var(--text-on-accent);
}

.familias__enlace:active {
  transform: translateY(1px);
}

@media (prefers-reduced-motion: reduce) {
  .familias__enlace:active {
    transform: none;
  }
}

.familias__enlace--todo {
  border-style: dashed;
}


/* ===========================================================================
   MARCAS
   Huecos de logotipo con el nombre escrito debajo. Los logotipos los aporta
   el cliente: son material con derechos y no se inventan ni se descargan.
   =========================================================================== */

.marcas {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: var(--sp-6);
  list-style: none;
  margin: 0;
  padding: 0;
}

.marcas__item {
  min-width: 0;
  text-align: center;
}

.marcas__hueco {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 3 / 2;
  margin-bottom: var(--sp-3);

  background: var(--slot-bg);
  color: var(--slot-text);
  border: 2px dashed var(--slot-border);
  border-radius: var(--r-md);
  opacity: 0.55;
}

.marcas__nombre {
  margin: 0;
  font-family: var(--font-title);
  font-size: var(--fs-h3);
  font-weight: 600;
}

.marcas__tipo {
  margin: var(--sp-1) 0 0;
  font-size: var(--fs-meta);
  color: var(--text-muted);
  max-width: none;
}


/* ===========================================================================
   PUEBLOS DE LA ZONA DE ACTUACIÓN
   =========================================================================== */

.pueblos {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-5);
  list-style: none;
  margin: var(--sp-6) 0;
  padding: 0;
  font-weight: 600;
}

.pueblos li {
  position: relative;
  padding-left: var(--sp-5);
}

.pueblos li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.7em;
  width: var(--sp-3);
  height: 2px;
  background: var(--bullet-marca);
}

/* ===========================================================================
   RESEÑAS

   Filas con regla, no tarjetas con comillas gigantes. Es el mismo lenguaje
   que los servicios y que el albarán: aquí lo que importa es leer lo que
   pone.

   Las estrellas salen de los tokens de la casa, no de un amarillo de
   pictograma. Y van acompañadas del número escrito para el lector de
   pantalla: contar estrellas por el color no es una opción para todo el
   mundo.
   =========================================================================== */

.valoracion {
  display: flex;
  align-items: baseline;
  gap: var(--sp-3);
  margin-bottom: var(--sp-8);
}

.valoracion__media {
  font-family: var(--font-title);
  font-size: var(--fs-h1);
  font-weight: 700;
  line-height: 1;
  margin: 0;
  color: var(--text-body);
}

.valoracion__sobre {
  font-size: var(--fs-body);
  font-weight: 400;
  color: var(--text-muted);
}

.valoracion__cuenta {
  margin: 0;
  color: var(--text-muted);
}

.resenas {
  list-style: none;
  margin: 0;
  padding: 0;
}

.resena {
  padding-block: var(--sp-6);
  border-top: 1px solid var(--border-hairline);
}

.resena:last-child {
  border-bottom: 1px solid var(--border-hairline);
}

/* Las estrellas van en el verde de ESCRIBIR (--text-accent, que apunta a
   --c-accent-800), no en el verde de marca: ese da 3,1:1 sobre crema y no se
   leería. Este da 6,3:1. Es uno de los pocos sitios donde el acento aparece
   sin ser un botón, y aquí se lo ha ganado: una valoración pide color. */
.resena__estrellas {
  margin: 0 0 var(--sp-2);
  font-size: var(--fs-lead);
  line-height: 1;
  color: var(--text-accent);
  letter-spacing: 0.1em;
}

.resena__texto {
  margin: 0;
  border: 0;
  padding: 0;
}

.resena__texto p {
  margin: 0;
  font-size: var(--fs-lead);
  line-height: var(--lh-body);
  max-width: var(--w-prose);
}

.resena__firma {
  margin: var(--sp-3) 0 0;
  font-size: var(--fs-meta);
  color: var(--text-muted);
  display: flex;
  flex-wrap: wrap;
  gap: 0 var(--sp-2);
}

/* El nombre de quien la escribió va con más peso que la procedencia: es la
   atribución, y una reseña sin autor no es una reseña. */
.resena__autor {
  font-weight: 600;
  color: var(--text-body);
}

/* "Reseña en Google · 2026". El año y no una fecha relativa: "2020" se lee
   como trayectoria, "hace seis años" envejece solo. */
.resena__fuente::before {
  content: "· ";
}

.resenas__enlace {
  margin-top: var(--sp-8);
}
